diff --git a/.gitattributes b/.gitattributes index dfe0770424..0269fab9cb 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,2 +1,3 @@ # Auto detect text files and perform LF normalization * text=auto +*.sol linguist-language=Solidity diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 79c7a53014..0a09baef7d 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,12 +1,32 @@ # Lines starting with '#' are comments. # Each line is a file pattern followed by one or more owners. -accounts/usbwallet @karalabe -consensus @karalabe -core/ @karalabe @holiman -eth/ @karalabe -les/ @zsfelfoldi -light/ @zsfelfoldi -mobile/ @karalabe -p2p/ @fjl @zsfelfoldi -whisper/ @gballet @gluk256 +accounts/usbwallet @karalabe +consensus @karalabe +core/ @karalabe @holiman +eth/ @karalabe +les/ @zsfelfoldi +light/ @zsfelfoldi +mobile/ @karalabe +p2p/ @fjl @zsfelfoldi +swarm/bmt @zelig +swarm/dev @lmars +swarm/fuse @jmozah @holisticode +swarm/grafana_dashboards @nonsense +swarm/metrics @nonsense @holisticode +swarm/multihash @nolash +swarm/network/bitvector @zelig @janos @gbalint +swarm/network/priorityqueue @zelig @janos @gbalint +swarm/network/simulations @zelig +swarm/network/stream @janos @zelig @gbalint @holisticode @justelad +swarm/network/stream/intervals @janos +swarm/network/stream/testing @zelig +swarm/pot @zelig +swarm/pss @nolash @zelig @nonsense +swarm/services @zelig +swarm/state @justelad +swarm/storage/encryption @gbalint @zelig @nagydani +swarm/storage/mock @janos +swarm/storage/mru @nolash +swarm/testutil @lmars +whisper/ @gballet @gluk256 diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000000..afa9ab503f --- /dev/null +++ b/.travis.yml @@ -0,0 +1,208 @@ +language: go +go_import_path: github.com/ethereum/go-ethereum +sudo: false +matrix: + include: + - os: linux + dist: trusty + sudo: required + go: 1.9.x + script: + - sudo modprobe fuse + - sudo chmod 666 /dev/fuse + - sudo chown root:$USER /etc/fuse.conf + - go run build/ci.go install + - go run build/ci.go test -coverage $TEST_PACKAGES + + # These are the latest Go versions. + - os: linux + dist: trusty + sudo: required + go: 1.10.x + script: + - sudo modprobe fuse + - sudo chmod 666 /dev/fuse + - sudo chown root:$USER /etc/fuse.conf + - go run build/ci.go install + - go run build/ci.go test -coverage $TEST_PACKAGES + + - os: osx + go: 1.10.x + script: + - unset -f cd # workaround for https://github.com/travis-ci/travis-ci/issues/8703 + - brew update + - brew cask install osxfuse + - go run build/ci.go install + - go run build/ci.go test -coverage $TEST_PACKAGES + + # This builder only tests code linters on latest version of Go + - os: linux + dist: trusty + go: 1.10.x + env: + - lint + git: + submodules: false # avoid cloning ethereum/tests + script: + - go run build/ci.go lint + + # This builder does the Ubuntu PPA upload + - os: linux + dist: trusty + go: 1.10.x + env: + - ubuntu-ppa + git: + submodules: false # avoid cloning ethereum/tests + addons: + apt: + packages: + - devscripts + - debhelper + - dput + - fakeroot + script: + - go run build/ci.go debsrc -signer "Go Ethereum Linux Builder " -upload ppa:ethereum/ethereum + + # This builder does the Linux Azure uploads + - os: linux + dist: trusty + sudo: required + go: 1.10.x + env: + - azure-linux + git: + submodules: false # avoid cloning ethereum/tests + addons: + apt: + packages: + - gcc-multilib + script: + # Build for the primary platforms that Trusty can manage + - go run build/ci.go install + - go run build/ci.go archive -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds + - go run build/ci.go install -arch 386 + - go run build/ci.go archive -arch 386 -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds + + # Switch over GCC to cross compilation (breaks 386, hence why do it here only) + - sudo -E 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 + - sudo ln -s /usr/include/asm-generic /usr/include/asm + + - GOARM=5 go run build/ci.go install -arch arm -cc arm-linux-gnueabi-gcc + - GOARM=5 go run build/ci.go archive -arch arm -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds + - GOARM=6 go run build/ci.go install -arch arm -cc arm-linux-gnueabi-gcc + - GOARM=6 go run build/ci.go archive -arch arm -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds + - GOARM=7 go run build/ci.go install -arch arm -cc arm-linux-gnueabihf-gcc + - GOARM=7 go run build/ci.go archive -arch arm -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds + - go run build/ci.go install -arch arm64 -cc aarch64-linux-gnu-gcc + - go run build/ci.go archive -arch arm64 -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds + + # This builder does the Linux Azure MIPS xgo uploads + - os: linux + dist: trusty + services: + - docker + go: 1.10.x + env: + - azure-linux-mips + git: + submodules: false # avoid cloning ethereum/tests + script: + - go run build/ci.go xgo --alltools -- --targets=linux/mips --ldflags '-extldflags "-static"' -v + - for bin in build/bin/*-linux-mips; do mv -f "${bin}" "${bin/-linux-mips/}"; done + - go run build/ci.go archive -arch mips -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds + + - go run build/ci.go xgo --alltools -- --targets=linux/mipsle --ldflags '-extldflags "-static"' -v + - for bin in build/bin/*-linux-mipsle; do mv -f "${bin}" "${bin/-linux-mipsle/}"; done + - go run build/ci.go archive -arch mipsle -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds + + - go run build/ci.go xgo --alltools -- --targets=linux/mips64 --ldflags '-extldflags "-static"' -v + - for bin in build/bin/*-linux-mips64; do mv -f "${bin}" "${bin/-linux-mips64/}"; done + - go run build/ci.go archive -arch mips64 -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds + + - go run build/ci.go xgo --alltools -- --targets=linux/mips64le --ldflags '-extldflags "-static"' -v + - for bin in build/bin/*-linux-mips64le; do mv -f "${bin}" "${bin/-linux-mips64le/}"; done + - go run build/ci.go archive -arch mips64le -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds + + # This builder does the Android Maven and Azure uploads + - os: linux + dist: trusty + addons: + apt: + packages: + - oracle-java8-installer + - oracle-java8-set-default + language: android + android: + components: + - platform-tools + - tools + - android-15 + - android-19 + - android-24 + env: + - azure-android + - maven-android + git: + submodules: false # avoid cloning ethereum/tests + before_install: + - curl https://storage.googleapis.com/golang/go1.10.3.linux-amd64.tar.gz | tar -xz + - export PATH=`pwd`/go/bin:$PATH + - export GOROOT=`pwd`/go + - export GOPATH=$HOME/go + script: + # Build the Android archive and upload it to Maven Central and Azure + - curl https://dl.google.com/android/repository/android-ndk-r17b-linux-x86_64.zip -o android-ndk-r17b.zip + - unzip -q android-ndk-r17b.zip && rm android-ndk-r17b.zip + - mv android-ndk-r17b $HOME + - export ANDROID_NDK=$HOME/android-ndk-r17b + + - mkdir -p $GOPATH/src/github.com/ethereum + - ln -s `pwd` $GOPATH/src/github.com/ethereum + - go run build/ci.go aar -signer ANDROID_SIGNING_KEY -deploy https://oss.sonatype.org -upload gethstore/builds + + # This builder does the OSX Azure, iOS CocoaPods and iOS Azure uploads + - os: osx + go: 1.10.x + env: + - azure-osx + - azure-ios + - cocoapods-ios + git: + submodules: false # avoid cloning ethereum/tests + script: + - go run build/ci.go install + - go run build/ci.go archive -type tar -signer OSX_SIGNING_KEY -upload gethstore/builds + + # Build the iOS framework and upload it to CocoaPods and Azure + - gem uninstall cocoapods -a -x + - gem install cocoapods + + - mv ~/.cocoapods/repos/master ~/.cocoapods/repos/master.bak + - sed -i '.bak' 's/repo.join/!repo.join/g' $(dirname `gem which cocoapods`)/cocoapods/sources_manager.rb + - if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then git clone --depth=1 https://github.com/CocoaPods/Specs.git ~/.cocoapods/repos/master && pod setup --verbose; fi + + - xctool -version + - xcrun simctl list + + # Workaround for https://github.com/golang/go/issues/23749 + - export CGO_CFLAGS_ALLOW='-fmodules|-fblocks|-fobjc-arc' + - go run build/ci.go xcode -signer IOS_SIGNING_KEY -deploy trunk -upload gethstore/builds + + # This builder does the Azure archive purges to avoid accumulating junk + - os: linux + dist: trusty + go: 1.10.x + env: + - azure-purge + git: + submodules: false # avoid cloning ethereum/tests + script: + - go run build/ci.go purge -store gethstore/builds -days 14 + +notifications: + webhooks: + urls: + - https://webhooks.gitter.im/e/e09ccdce1048c5e03445 + on_success: change + on_failure: always diff --git a/AUTHORS b/AUTHORS index bd44a3de55..609dc48c72 100644 --- a/AUTHORS +++ b/AUTHORS @@ -171,3 +171,4 @@ xiekeyang yoza ΞTHΞЯSPHΞЯΞ <{viktor.tron,nagydani,zsfelfoldi}@gmail.com> Максим Чусовлянов +Ralph Caraveo diff --git a/Dockerfile b/Dockerfile index ce9b9c7a2a..4aed7c7a49 100644 --- a/Dockerfile +++ b/Dockerfile @@ -9,15 +9,5 @@ FROM alpine:latest LABEL maintainer="anil@xinfin.org" -WORKDIR /XDCchain - -COPY --from=builder /XDCchain/build/bin/XDC /usr/local/bin/XDC - -RUN chmod +x /usr/local/bin/XDC - -EXPOSE 8545 -EXPOSE 30303 - -ENTRYPOINT ["/usr/local/bin/XDC"] - -CMD ["--help"] +EXPOSE 8545 8546 30303 30303/udp +ENTRYPOINT ["XDC"] diff --git a/Dockerfile.alltools b/Dockerfile.alltools new file mode 100644 index 0000000000..e54e107bf3 --- /dev/null +++ b/Dockerfile.alltools @@ -0,0 +1,15 @@ +# Build Geth in a stock Go builder container +FROM golang:1.10-alpine as builder + +RUN apk add --no-cache make gcc musl-dev linux-headers + +ADD . /go-ethereum +RUN cd /go-ethereum && make all + +# Pull all binaries into a second stage deploy alpine container +FROM alpine:latest + +RUN apk add --no-cache ca-certificates +COPY --from=builder /go-ethereum/build/bin/* /usr/local/bin/ + +EXPOSE 8545 8546 30303 30303/udp diff --git a/Makefile b/Makefile index 17097b2ff3..98a7750a83 100644 --- a/Makefile +++ b/Makefile @@ -15,11 +15,6 @@ XDC: @echo "Done building." @echo "Run \"$(GOBIN)/XDC\" to launch XDC." -gc: - build/env.sh go run build/ci.go install ./cmd/gc - @echo "Done building." - @echo "Run \"$(GOBIN)/gc\" to launch gc." - bootnode: build/env.sh go run build/ci.go install ./cmd/bootnode @echo "Done building." @@ -36,7 +31,11 @@ all: test: all build/env.sh go run build/ci.go test +lint: ## Run linters. + build/env.sh go run build/ci.go lint + clean: + ./build/clean_go_build_cache.sh rm -fr build/_workspace/pkg/ $(GOBIN)/* # Cross Compilation Targets (xgo) diff --git a/README.md b/README.md index 7466c21f3f..94b8253d02 100644 --- a/README.md +++ b/README.md @@ -6,4 +6,300 @@ Website Resource : https://xinFin.org XinFin Mainet URL: http://XinFin.network/ -XinFin TestNet/Apothem URL: http://apothem.network/ +## Building the source + +For prerequisites and detailed build instructions please read the +[Installation Instructions](https://github.com/ethereum/go-ethereum/wiki/Building-Ethereum) +on the wiki. + +Building geth requires both a Go (version 1.7 or later) and a C compiler. +You can install them using your favourite package manager. +Once the dependencies are installed, run + + make geth + +or, to build the full suite of utilities: + + make all + +## Executables + +The go-ethereum project comes with several wrappers/executables found in the `cmd` directory. + +| Command | Description | +|:----------:|-------------| +| **`geth`** | Our main Ethereum CLI client. It is the entry point into the Ethereum network (main-, test- or private net), capable of running as a full node (default) archive node (retaining all historical state) or a light node (retrieving data live). It can be used by other processes as a gateway into the Ethereum network via JSON RPC endpoints exposed on top of HTTP, WebSocket and/or IPC transports. `geth --help` and the [CLI Wiki page](https://github.com/ethereum/go-ethereum/wiki/Command-Line-Options) for command line options. | +| `abigen` | Source code generator to convert Ethereum contract definitions into easy to use, compile-time type-safe Go packages. It operates on plain [Ethereum contract ABIs](https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI) with expanded functionality if the contract bytecode is also available. However it also accepts Solidity source files, making development much more streamlined. Please see our [Native DApps](https://github.com/ethereum/go-ethereum/wiki/Native-DApps:-Go-bindings-to-Ethereum-contracts) wiki page for details. | +| `bootnode` | Stripped down version of our Ethereum client implementation that only takes part in the network node discovery protocol, but does not run any of the higher level application protocols. It can be used as a lightweight bootstrap node to aid in finding peers in private networks. | +| `evm` | Developer utility version of the EVM (Ethereum Virtual Machine) that is capable of running bytecode snippets within a configurable environment and execution mode. Its purpose is to allow isolated, fine-grained debugging of EVM opcodes (e.g. `evm --code 60ff60ff --debug`). | +| `gethrpctest` | Developer utility tool to support our [ethereum/rpc-test](https://github.com/ethereum/rpc-tests) test suite which validates baseline conformity to the [Ethereum JSON RPC](https://github.com/ethereum/wiki/wiki/JSON-RPC) specs. Please see the [test suite's readme](https://github.com/ethereum/rpc-tests/blob/master/README.md) for details. | +| `rlpdump` | Developer utility tool to convert binary RLP ([Recursive Length Prefix](https://github.com/ethereum/wiki/wiki/RLP)) dumps (data encoding used by the Ethereum protocol both network as well as consensus wise) to user friendlier hierarchical representation (e.g. `rlpdump --hex CE0183FFFFFFC4C304050583616263`). | +| `swarm` | Swarm daemon and tools. This is the entrypoint for the Swarm network. `swarm --help` for command line options and subcommands. See [Swarm README](https://github.com/ethereum/go-ethereum/tree/master/swarm) for more information. | +| `puppeth` | a CLI wizard that aids in creating a new Ethereum network. | + +## Running geth + +Going through all the possible command line flags is out of scope here (please consult our +[CLI Wiki page](https://github.com/ethereum/go-ethereum/wiki/Command-Line-Options)), but we've +enumerated a few common parameter combos to get you up to speed quickly on how you can run your +own Geth instance. + +### Full node on the main Ethereum network + +By far the most common scenario is people wanting to simply interact with the Ethereum network: +create accounts; transfer funds; deploy and interact with contracts. For this particular use-case +the user doesn't care about years-old historical data, so we can fast-sync quickly to the current +state of the network. To do so: + +``` +$ geth console +``` + +This command will: + + * Start geth in fast sync mode (default, can be changed with the `--syncmode` flag), causing it to + download more data in exchange for avoiding processing the entire history of the Ethereum network, + which is very CPU intensive. + * Start up Geth's built-in interactive [JavaScript console](https://github.com/ethereum/go-ethereum/wiki/JavaScript-Console), + (via the trailing `console` subcommand) through which you can invoke all official [`web3` methods](https://github.com/ethereum/wiki/wiki/JavaScript-API) + as well as Geth's own [management APIs](https://github.com/ethereum/go-ethereum/wiki/Management-APIs). + This too is optional and if you leave it out you can always attach to an already running Geth instance + with `geth attach`. + +### Full node on the Ethereum test network + +Transitioning towards developers, if you'd like to play around with creating Ethereum contracts, you +almost certainly would like to do that without any real money involved until you get the hang of the +entire system. In other words, instead of attaching to the main network, you want to join the **test** +network with your node, which is fully equivalent to the main network, but with play-Ether only. + +``` +$ geth --testnet console +``` + +The `console` subcommand have the exact same meaning as above and they are equally useful on the +testnet too. Please see above for their explanations if you've skipped to here. + +Specifying the `--testnet` flag however will reconfigure your Geth instance a bit: + + * Instead of using the default data directory (`~/.ethereum` on Linux for example), Geth will nest + itself one level deeper into a `testnet` subfolder (`~/.ethereum/testnet` on Linux). Note, on OSX + and Linux this also means that attaching to a running testnet node requires the use of a custom + endpoint since `geth attach` will try to attach to a production node endpoint by default. E.g. + `geth attach /testnet/geth.ipc`. Windows users are not affected by this. + * Instead of connecting the main Ethereum network, the client will connect to the test network, + which uses different P2P bootnodes, different network IDs and genesis states. + +*Note: Although there are some internal protective measures to prevent transactions from crossing +over between the main network and test network, you should make sure to always use separate accounts +for play-money and real-money. Unless you manually move accounts, Geth will by default correctly +separate the two networks and will not make any accounts available between them.* + +### Full node on the Rinkeby test network + +The above test network is a cross client one based on the ethash proof-of-work consensus algorithm. As such, it has certain extra overhead and is more susceptible to reorganization attacks due to the network's low difficulty / security. Go Ethereum also supports connecting to a proof-of-authority based test network called [*Rinkeby*](https://www.rinkeby.io) (operated by members of the community). This network is lighter, more secure, but is only supported by go-ethereum. + +``` +$ geth --rinkeby console +``` + +### Configuration + +As an alternative to passing the numerous flags to the `geth` binary, you can also pass a configuration file via: + +``` +$ geth --config /path/to/your_config.toml +``` + +To get an idea how the file should look like you can use the `dumpconfig` subcommand to 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 Docker: + +``` +docker run -d --name ethereum-node -v /Users/alice/ethereum:/root \ + -p 8545:8545 -p 30303:30303 \ + ethereum/client-go +``` + +This will start geth in fast-sync mode with a DB memory allowance of 1GB just as the above command does. It will also create a persistent volume in your home directory for saving your blockchain as well as map the default ports. There is also an `alpine` tag available for a slim version of the image. + +Do not forget `--rpcaddr 0.0.0.0`, if you want to access RPC from other containers and/or hosts. By default, `geth` binds to the local interface and RPC endpoints is not accessible from the outside. + +### Programatically interfacing Geth nodes + +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://github.com/ethereum/wiki/wiki/JSON-RPC) and +[Geth specific APIs](https://github.com/ethereum/go-ethereum/wiki/Management-APIs)). These can be +exposed via HTTP, WebSockets and IPC (unix sockets on unix based platforms, and named pipes on Windows). + +The IPC interface is enabled by default and exposes all the APIs supported by Geth, whereas the HTTP +and WS interfaces need to manually be enabled and only expose a subset of APIs due to security reasons. +These can be turned on/off and configured as you'd expect. + +HTTP based JSON-RPC API options: + + * `--rpc` Enable the HTTP-RPC server + * `--rpcaddr` HTTP-RPC server listening interface (default: "localhost") + * `--rpcport` HTTP-RPC server listening port (default: 8545) + * `--rpcapi` API's offered over the HTTP-RPC interface (default: "eth,net,web3") + * `--rpccorsdomain` Comma separated list of domains from which to accept cross origin requests (browser enforced) + * `--ws` Enable the WS-RPC server + * `--wsaddr` WS-RPC server listening interface (default: "localhost") + * `--wsport` WS-RPC server listening port (default: 8546) + * `--wsapi` API's offered over the WS-RPC interface (default: "eth,net,web3") + * `--wsorigins` Origins from which to accept websockets requests + * `--ipcdisable` Disable the IPC-RPC server + * `--ipcapi` API's offered over the IPC-RPC interface (default: "admin,debug,eth,miner,net,personal,shh,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 connect +via HTTP, WS or IPC to a Geth node configured with the above flags and you'll need to speak [JSON-RPC](http://www.jsonrpc.org/specification) +on all transports. You can reuse the same connection for multiple requests! + +**Note: Please understand the security implications of opening up an HTTP/WS based transport before +doing so! Hackers on the internet are actively trying to subvert Ethereum nodes with exposed APIs! +Further, all browser tabs can access locally running webservers, so malicious webpages could try to +subvert locally available APIs!** + +### Operating a private network + +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 + +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`): + +```json +{ + "config": { + "chainId": 0, + "homesteadBlock": 0, + "eip155Block": 0, + "eip158Block": 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, you can populate the `alloc` field with account +configs: + +```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: + +``` +$ 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: + +``` +$ bootnode --genkey=boot.key +$ bootnode --nodekey=boot.key +``` + +With the bootnode online, it will display an [`enode` URL](https://github.com/ethereum/wiki/wiki/enode-url-format) +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 also use a full fledged Geth node as a bootnode, but it's the less recommended way.* + +#### 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. + +``` +$ 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 + +Mining on the public Ethereum network is a complex task as it's only feasible using GPUs, requiring +an OpenCL or CUDA enabled `ethminer` instance. For information on such a setup, please consult the +[EtherMining subreddit](https://www.reddit.com/r/EtherMining/) and the [Genoil miner](https://github.com/Genoil/cpp-ethereum) +repository. + +In a private network setting however, 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: + +``` +$ geth --mine --minerthreads=1 --etherbase=0x0000000000000000000000000000000000000000 +``` + +Which will start mining blocks and transactions on a single CPU thread, crediting all proceedings to +the account specified by `--etherbase`. You can further tune the mining by changing the default gas +limit blocks converge to (`--targetgaslimit`) and the price transactions are accepted at (`--gasprice`). + +## Contribution + +Thank you for considering to help out with the source code! We welcome contributions from +anyone on the internet, and are grateful for even the smallest of fixes! + +If you'd like to contribute to go-ethereum, please fork, fix, commit and send a pull request +for the maintainers to review and merge into the main code base. If you wish to submit more +complex changes though, please check up with the core devs first on [our gitter channel](https://gitter.im/ethereum/go-ethereum) +to ensure those changes are in line with the general philosophy of the project and/or get some +early feedback which can make both your efforts much lighter as well as our review and merge +procedures quick and simple. + +Please make sure your contributions adhere to our coding guidelines: + + * Code must adhere to the official Go [formatting](https://golang.org/doc/effective_go.html#formatting) guidelines (i.e. uses [gofmt](https://golang.org/cmd/gofmt/)). + * Code must be documented adhering to the official Go [commentary](https://golang.org/doc/effective_go.html#commentary) guidelines. + * Pull requests need to be based on and opened against the `master` branch. + * Commit messages should be prefixed with the package(s) they modify. + * E.g. "eth, rpc: make trace configs optional" + +Please see the [Developers' Guide](https://github.com/ethereum/go-ethereum/wiki/Developers'-Guide) +for more details on configuring your environment, managing project dependencies and testing procedures. + +## License + +The go-ethereum library (i.e. all code outside of the `cmd` directory) is licensed under the +[GNU Lesser General Public License v3.0](https://www.gnu.org/licenses/lgpl-3.0.en.html), also +included in our repository in the `COPYING.LESSER` file. + +The go-ethereum binaries (i.e. all code inside of the `cmd` directory) is licensed under the +[GNU General Public License v3.0](https://www.gnu.org/licenses/gpl-3.0.en.html), also included +in our repository in the `COPYING` file. diff --git a/VERSION b/VERSION deleted file mode 100644 index 17e51c385e..0000000000 --- a/VERSION +++ /dev/null @@ -1 +0,0 @@ -0.1.1 diff --git a/accounts/abi/argument.go b/accounts/abi/argument.go index 512d8fdfa7..93b513c346 100644 --- a/accounts/abi/argument.go +++ b/accounts/abi/argument.go @@ -111,9 +111,14 @@ func (arguments Arguments) unpackTuple(v interface{}, marshalledValues []interfa if err := requireUnpackKind(value, typ, kind, arguments); err != nil { return err } - // If the output interface is a struct, make sure names don't collide + + // If the interface is a struct, get of abi->struct_field mapping + + var abi2struct map[string]string if kind == reflect.Struct { - if err := requireUniqueStructFieldNames(arguments); err != nil { + var err error + abi2struct, err = mapAbiToStructFields(arguments, value) + if err != nil { return err } } @@ -123,9 +128,10 @@ func (arguments Arguments) unpackTuple(v interface{}, marshalledValues []interfa switch kind { case reflect.Struct: - err := unpackStruct(value, reflectValue, arg) - if err != nil { - return err + if structField, ok := abi2struct[arg.Name]; ok { + if err := set(value.FieldByName(structField), reflectValue, arg); err != nil { + return err + } } case reflect.Slice, reflect.Array: if value.Len() < i { @@ -151,17 +157,22 @@ func (arguments Arguments) unpackAtomic(v interface{}, marshalledValues []interf if len(marshalledValues) != 1 { return fmt.Errorf("abi: wrong length, expected single value, got %d", len(marshalledValues)) } + elem := reflect.ValueOf(v).Elem() kind := elem.Kind() reflectValue := reflect.ValueOf(marshalledValues[0]) + var abi2struct map[string]string if kind == reflect.Struct { - //make sure names don't collide - if err := requireUniqueStructFieldNames(arguments); err != nil { + var err error + if abi2struct, err = mapAbiToStructFields(arguments, elem); err != nil { return err } - - return unpackStruct(elem, reflectValue, arguments[0]) + arg := arguments.NonIndexed()[0] + if structField, ok := abi2struct[arg.Name]; ok { + return set(elem.FieldByName(structField), reflectValue, arg) + } + return nil } return set(elem, reflectValue, arguments.NonIndexed()[0]) @@ -277,18 +288,3 @@ func capitalise(input string) string { } return strings.ToUpper(input[:1]) + input[1:] } - -//unpackStruct extracts each argument into its corresponding struct field -func unpackStruct(value, reflectValue reflect.Value, arg Argument) error { - name := capitalise(arg.Name) - typ := value.Type() - for j := 0; j < typ.NumField(); j++ { - // TODO read tags: `abi:"fieldName"` - if typ.Field(j).Name == name { - if err := set(value.Field(j), reflectValue, arg); err != nil { - return err - } - } - } - return nil -} diff --git a/accounts/abi/bind/backends/simulated.go b/accounts/abi/bind/backends/simulated.go index 10e16d5ec9..ae56347cbe 100644 --- a/accounts/abi/bind/backends/simulated.go +++ b/accounts/abi/bind/backends/simulated.go @@ -31,6 +31,7 @@ import ( "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/rawdb" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" @@ -65,7 +66,7 @@ type SimulatedBackend struct { // NewSimulatedBackend creates a new binding backend using a simulated blockchain // for testing purposes. func NewSimulatedBackend(alloc core.GenesisAlloc) *SimulatedBackend { - database, _ := ethdb.NewMemDatabase() + database := ethdb.NewMemDatabase() genesis := core.Genesis{Config: params.AllEthashProtocolChanges, Alloc: alloc} genesis.MustCommit(database) blockchain, _ := core.NewBlockChain(database, nil, genesis.Config, ethash.NewFaker(), vm.Config{}) @@ -172,7 +173,7 @@ func (b *SimulatedBackend) ForEachStorageAt(ctx context.Context, contract common // TransactionReceipt returns the receipt of a transaction. func (b *SimulatedBackend) TransactionReceipt(ctx context.Context, txHash common.Hash) (*types.Receipt, error) { - receipt, _, _, _ := core.GetReceipt(b.database, txHash) + receipt, _, _, _ := rawdb.ReadReceipt(b.database, txHash) return receipt, nil } @@ -336,18 +337,24 @@ func (b *SimulatedBackend) SendTransaction(ctx context.Context, tx *types.Transa // // TODO(karalabe): Deprecate when the subscription one can return past data too. func (b *SimulatedBackend) FilterLogs(ctx context.Context, query ethereum.FilterQuery) ([]types.Log, error) { - // Initialize unset filter boundaried to run from genesis to chain head - from := int64(0) - if query.FromBlock != nil { - from = query.FromBlock.Int64() + var filter *filters.Filter + if query.BlockHash != nil { + // Block filter requested, construct a single-shot filter + filter = filters.NewBlockFilter(&filterBackend{b.database, b.blockchain}, *query.BlockHash, query.Addresses, query.Topics) + } else { + // Initialize unset filter boundaried to run from genesis to chain head + from := int64(0) + if query.FromBlock != nil { + from = query.FromBlock.Int64() + } + to := int64(-1) + if query.ToBlock != nil { + to = query.ToBlock.Int64() + } + // Construct the range filter + filter = filters.NewRangeFilter(&filterBackend{b.database, b.blockchain}, from, to, query.Addresses, query.Topics) } - to := int64(-1) - if query.ToBlock != nil { - to = query.ToBlock.Int64() - } - // Construct and execute the filter - filter := filters.New(&filterBackend{b.database, b.blockchain}, from, to, query.Addresses, query.Topics) - + // Run the filter and return all the logs logs, err := filter.Logs(ctx) if err != nil { return nil, err @@ -442,12 +449,24 @@ func (fb *filterBackend) HeaderByNumber(ctx context.Context, block rpc.BlockNumb return fb.bc.GetHeaderByNumber(uint64(block.Int64())), nil } +func (fb *filterBackend) HeaderByHash(ctx context.Context, hash common.Hash) (*types.Header, error) { + return fb.bc.GetHeaderByHash(hash), nil +} + func (fb *filterBackend) GetReceipts(ctx context.Context, hash common.Hash) (types.Receipts, error) { - return core.GetBlockReceipts(fb.db, hash, core.GetBlockNumber(fb.db, hash)), nil + number := rawdb.ReadHeaderNumber(fb.db, hash) + if number == nil { + return nil, nil + } + return rawdb.ReadReceipts(fb.db, hash, *number), nil } func (fb *filterBackend) GetLogs(ctx context.Context, hash common.Hash) ([][]*types.Log, error) { - receipts := core.GetBlockReceipts(fb.db, hash, core.GetBlockNumber(fb.db, hash)) + number := rawdb.ReadHeaderNumber(fb.db, hash) + if number == nil { + return nil, nil + } + receipts := rawdb.ReadReceipts(fb.db, hash, *number) if receipts == nil { return nil, nil } @@ -458,7 +477,7 @@ func (fb *filterBackend) GetLogs(ctx context.Context, hash common.Hash) ([][]*ty return logs, nil } -func (fb *filterBackend) SubscribeTxPreEvent(ch chan<- core.TxPreEvent) event.Subscription { +func (fb *filterBackend) SubscribeNewTxsEvent(ch chan<- core.NewTxsEvent) event.Subscription { return event.NewSubscription(func(quit <-chan struct{}) error { <-quit return nil diff --git a/accounts/abi/event.go b/accounts/abi/event.go index 595f169f3a..a3f6be9732 100644 --- a/accounts/abi/event.go +++ b/accounts/abi/event.go @@ -33,15 +33,15 @@ type Event struct { Inputs Arguments } -func (event Event) String() string { - inputs := make([]string, len(event.Inputs)) - for i, input := range event.Inputs { +func (e Event) String() string { + inputs := make([]string, len(e.Inputs)) + for i, input := range e.Inputs { inputs[i] = fmt.Sprintf("%v %v", input.Name, input.Type) if input.Indexed { inputs[i] = fmt.Sprintf("%v indexed %v", input.Name, input.Type) } } - return fmt.Sprintf("event %v(%v)", event.Name, strings.Join(inputs, ", ")) + return fmt.Sprintf("e %v(%v)", e.Name, strings.Join(inputs, ", ")) } // Id returns the canonical representation of the event's signature used by the diff --git a/accounts/abi/event_test.go b/accounts/abi/event_test.go index cca61e433d..3bfdd7c0ab 100644 --- a/accounts/abi/event_test.go +++ b/accounts/abi/event_test.go @@ -58,12 +58,28 @@ var jsonEventPledge = []byte(`{ "type": "event" }`) +var jsonEventMixedCase = []byte(`{ + "anonymous": false, + "inputs": [{ + "indexed": false, "name": "value", "type": "uint256" + }, { + "indexed": false, "name": "_value", "type": "uint256" + }, { + "indexed": false, "name": "Value", "type": "uint256" + }], + "name": "MixedCase", + "type": "event" + }`) + // 1000000 var transferData1 = "00000000000000000000000000000000000000000000000000000000000f4240" // "0x00Ce0d46d924CC8437c806721496599FC3FFA268", 2218516807680, "usd" var pledgeData1 = "00000000000000000000000000ce0d46d924cc8437c806721496599fc3ffa2680000000000000000000000000000000000000000000000000000020489e800007573640000000000000000000000000000000000000000000000000000000000" +// 1000000,2218516807680,1000001 +var mixedCaseData1 = "00000000000000000000000000000000000000000000000000000000000f42400000000000000000000000000000000000000000000000000000020489e8000000000000000000000000000000000000000000000000000000000000000f4241" + func TestEventId(t *testing.T) { var table = []struct { definition string @@ -121,6 +137,27 @@ func TestEventTupleUnpack(t *testing.T) { Value *big.Int } + type EventTransferWithTag struct { + // this is valid because `value` is not exportable, + // so value is only unmarshalled into `Value1`. + value *big.Int + Value1 *big.Int `abi:"value"` + } + + type BadEventTransferWithSameFieldAndTag struct { + Value *big.Int + Value1 *big.Int `abi:"value"` + } + + type BadEventTransferWithDuplicatedTag struct { + Value1 *big.Int `abi:"value"` + Value2 *big.Int `abi:"value"` + } + + type BadEventTransferWithEmptyTag struct { + Value *big.Int `abi:""` + } + type EventPledge struct { Who common.Address Wad *big.Int @@ -133,9 +170,16 @@ func TestEventTupleUnpack(t *testing.T) { Currency [3]byte } + type EventMixedCase struct { + Value1 *big.Int `abi:"value"` + Value2 *big.Int `abi:"_value"` + Value3 *big.Int `abi:"Value"` + } + bigint := new(big.Int) bigintExpected := big.NewInt(1000000) bigintExpected2 := big.NewInt(2218516807680) + bigintExpected3 := big.NewInt(1000001) addr := common.HexToAddress("0x00Ce0d46d924CC8437c806721496599FC3FFA268") var testCases = []struct { data string @@ -158,6 +202,34 @@ func TestEventTupleUnpack(t *testing.T) { jsonEventTransfer, "", "Can unpack ERC20 Transfer event into slice", + }, { + transferData1, + &EventTransferWithTag{}, + &EventTransferWithTag{Value1: bigintExpected}, + jsonEventTransfer, + "", + "Can unpack ERC20 Transfer event into structure with abi: tag", + }, { + transferData1, + &BadEventTransferWithDuplicatedTag{}, + &BadEventTransferWithDuplicatedTag{}, + jsonEventTransfer, + "struct: abi tag in 'Value2' already mapped", + "Can not unpack ERC20 Transfer event with duplicated abi tag", + }, { + transferData1, + &BadEventTransferWithSameFieldAndTag{}, + &BadEventTransferWithSameFieldAndTag{}, + jsonEventTransfer, + "abi: multiple variables maps to the same abi field 'value'", + "Can not unpack ERC20 Transfer event with a field and a tag mapping to the same abi variable", + }, { + transferData1, + &BadEventTransferWithEmptyTag{}, + &BadEventTransferWithEmptyTag{}, + jsonEventTransfer, + "struct: abi tag in 'Value' is empty", + "Can not unpack ERC20 Transfer event with an empty tag", }, { pledgeData1, &EventPledge{}, @@ -216,6 +288,13 @@ func TestEventTupleUnpack(t *testing.T) { jsonEventPledge, "abi: cannot unmarshal tuple into map[string]interface {}", "Can not unpack Pledge event into map", + }, { + mixedCaseData1, + &EventMixedCase{}, + &EventMixedCase{Value1: bigintExpected, Value2: bigintExpected2, Value3: bigintExpected3}, + jsonEventMixedCase, + "", + "Can unpack abi variables with mixed case", }} for _, tc := range testCases { @@ -227,7 +306,7 @@ func TestEventTupleUnpack(t *testing.T) { assert.Nil(err, "Should be able to unpack event data.") assert.Equal(tc.expected, tc.dest, tc.name) } else { - assert.EqualError(err, tc.error) + assert.EqualError(err, tc.error, tc.name) } }) } diff --git a/accounts/abi/method.go b/accounts/abi/method.go index f434ffdbef..5831057652 100644 --- a/accounts/abi/method.go +++ b/accounts/abi/method.go @@ -47,10 +47,8 @@ type Method struct { // Please note that "int" is substitute for its canonical representation "int256" func (method Method) Sig() string { types := make([]string, len(method.Inputs)) - i := 0 - for _, input := range method.Inputs { + for i, input := range method.Inputs { types[i] = input.Type.String() - i++ } return fmt.Sprintf("%v(%v)", method.Name, strings.Join(types, ",")) } diff --git a/accounts/abi/numbers.go b/accounts/abi/numbers.go index 9ad99f90d2..4d706846da 100644 --- a/accounts/abi/numbers.go +++ b/accounts/abi/numbers.go @@ -25,35 +25,20 @@ import ( ) var ( - big_t = reflect.TypeOf(&big.Int{}) - derefbig_t = reflect.TypeOf(big.Int{}) - uint8_t = reflect.TypeOf(uint8(0)) - uint16_t = reflect.TypeOf(uint16(0)) - uint32_t = reflect.TypeOf(uint32(0)) - uint64_t = reflect.TypeOf(uint64(0)) - int_t = reflect.TypeOf(int(0)) - int8_t = reflect.TypeOf(int8(0)) - int16_t = reflect.TypeOf(int16(0)) - int32_t = reflect.TypeOf(int32(0)) - int64_t = reflect.TypeOf(int64(0)) - address_t = reflect.TypeOf(common.Address{}) - int_ts = reflect.TypeOf([]int(nil)) - int8_ts = reflect.TypeOf([]int8(nil)) - int16_ts = reflect.TypeOf([]int16(nil)) - int32_ts = reflect.TypeOf([]int32(nil)) - int64_ts = reflect.TypeOf([]int64(nil)) + bigT = reflect.TypeOf(&big.Int{}) + derefbigT = reflect.TypeOf(big.Int{}) + uint8T = reflect.TypeOf(uint8(0)) + uint16T = reflect.TypeOf(uint16(0)) + uint32T = reflect.TypeOf(uint32(0)) + uint64T = reflect.TypeOf(uint64(0)) + int8T = reflect.TypeOf(int8(0)) + int16T = reflect.TypeOf(int16(0)) + int32T = reflect.TypeOf(int32(0)) + int64T = reflect.TypeOf(int64(0)) + addressT = reflect.TypeOf(common.Address{}) ) // U256 converts a big Int into a 256bit EVM number. func U256(n *big.Int) []byte { return math.PaddedBigBytes(math.U256(n), 32) } - -// checks whether the given reflect value is signed. This also works for slices with a number type -func isSigned(v reflect.Value) bool { - switch v.Type() { - case int_ts, int8_ts, int16_ts, int32_ts, int64_ts, int_t, int8_t, int16_t, int32_t, int64_t: - return true - } - return false -} diff --git a/accounts/abi/numbers_test.go b/accounts/abi/numbers_test.go index b9ff5aef17..d25a5abcb5 100644 --- a/accounts/abi/numbers_test.go +++ b/accounts/abi/numbers_test.go @@ -19,7 +19,6 @@ package abi import ( "bytes" "math/big" - "reflect" "testing" ) @@ -32,13 +31,3 @@ func TestNumberTypes(t *testing.T) { t.Errorf("expected %x got %x", ubytes, unsigned) } } - -func TestSigned(t *testing.T) { - if isSigned(reflect.ValueOf(uint(10))) { - t.Error("signed") - } - - if !isSigned(reflect.ValueOf(int(10))) { - t.Error("not signed") - } -} diff --git a/accounts/abi/reflect.go b/accounts/abi/reflect.go index 2e6bf7098f..0193517a42 100644 --- a/accounts/abi/reflect.go +++ b/accounts/abi/reflect.go @@ -19,12 +19,13 @@ package abi import ( "fmt" "reflect" + "strings" ) // indirect recursively dereferences the value until it either gets the value // or finds a big.Int func indirect(v reflect.Value) reflect.Value { - if v.Kind() == reflect.Ptr && v.Elem().Type() != derefbig_t { + if v.Kind() == reflect.Ptr && v.Elem().Type() != derefbigT { return indirect(v.Elem()) } return v @@ -36,26 +37,26 @@ func reflectIntKindAndType(unsigned bool, size int) (reflect.Kind, reflect.Type) switch size { case 8: if unsigned { - return reflect.Uint8, uint8_t + return reflect.Uint8, uint8T } - return reflect.Int8, int8_t + return reflect.Int8, int8T case 16: if unsigned { - return reflect.Uint16, uint16_t + return reflect.Uint16, uint16T } - return reflect.Int16, int16_t + return reflect.Int16, int16T case 32: if unsigned { - return reflect.Uint32, uint32_t + return reflect.Uint32, uint32T } - return reflect.Int32, int32_t + return reflect.Int32, int32T case 64: if unsigned { - return reflect.Uint64, uint64_t + return reflect.Uint64, uint64T } - return reflect.Int64, int64_t + return reflect.Int64, int64T } - return reflect.Ptr, big_t + return reflect.Ptr, bigT } // mustArrayToBytesSlice creates a new byte slice with the exact same size as value @@ -111,18 +112,101 @@ func requireUnpackKind(v reflect.Value, t reflect.Type, k reflect.Kind, return nil } -// requireUniqueStructFieldNames makes sure field names don't collide -func requireUniqueStructFieldNames(args Arguments) error { - exists := make(map[string]bool) - for _, arg := range args { - field := capitalise(arg.Name) - if field == "" { - return fmt.Errorf("abi: purely underscored output cannot unpack to struct") +// mapAbiToStringField maps abi to struct fields. +// first round: for each Exportable field that contains a `abi:""` tag +// and this field name exists in the arguments, pair them together. +// second round: for each argument field that has not been already linked, +// find what variable is expected to be mapped into, if it exists and has not been +// used, pair them. +func mapAbiToStructFields(args Arguments, value reflect.Value) (map[string]string, error) { + + typ := value.Type() + + abi2struct := make(map[string]string) + struct2abi := make(map[string]string) + + // first round ~~~ + for i := 0; i < typ.NumField(); i++ { + structFieldName := typ.Field(i).Name + + // skip private struct fields. + if structFieldName[:1] != strings.ToUpper(structFieldName[:1]) { + continue } - if exists[field] { - return fmt.Errorf("abi: multiple outputs mapping to the same struct field '%s'", field) + + // skip fields that have no abi:"" tag. + var ok bool + var tagName string + if tagName, ok = typ.Field(i).Tag.Lookup("abi"); !ok { + continue } - exists[field] = true + + // check if tag is empty. + if tagName == "" { + return nil, fmt.Errorf("struct: abi tag in '%s' is empty", structFieldName) + } + + // check which argument field matches with the abi tag. + found := false + for _, abiField := range args.NonIndexed() { + if abiField.Name == tagName { + if abi2struct[abiField.Name] != "" { + return nil, fmt.Errorf("struct: abi tag in '%s' already mapped", structFieldName) + } + // pair them + abi2struct[abiField.Name] = structFieldName + struct2abi[structFieldName] = abiField.Name + found = true + } + } + + // check if this tag has been mapped. + if !found { + return nil, fmt.Errorf("struct: abi tag '%s' defined but not found in abi", tagName) + } + } - return nil + + // second round ~~~ + for _, arg := range args { + + abiFieldName := arg.Name + structFieldName := capitalise(abiFieldName) + + if structFieldName == "" { + return nil, fmt.Errorf("abi: purely underscored output cannot unpack to struct") + } + + // this abi has already been paired, skip it... unless there exists another, yet unassigned + // struct field with the same field name. If so, raise an error: + // abi: [ { "name": "value" } ] + // struct { Value *big.Int , Value1 *big.Int `abi:"value"`} + if abi2struct[abiFieldName] != "" { + if abi2struct[abiFieldName] != structFieldName && + struct2abi[structFieldName] == "" && + value.FieldByName(structFieldName).IsValid() { + return nil, fmt.Errorf("abi: multiple variables maps to the same abi field '%s'", abiFieldName) + } + continue + } + + // return an error if this struct field has already been paired. + if struct2abi[structFieldName] != "" { + return nil, fmt.Errorf("abi: multiple outputs mapping to the same struct field '%s'", structFieldName) + } + + if value.FieldByName(structFieldName).IsValid() { + // pair them + abi2struct[abiFieldName] = structFieldName + struct2abi[structFieldName] = abiFieldName + } else { + // not paired, but annotate as used, to detect cases like + // abi : [ { "name": "value" }, { "name": "_value" } ] + // struct { Value *big.Int } + struct2abi[structFieldName] = abiFieldName + } + + } + + return abi2struct, nil } diff --git a/accounts/abi/type.go b/accounts/abi/type.go index a1f13ffa29..9de36daffb 100644 --- a/accounts/abi/type.go +++ b/accounts/abi/type.go @@ -135,7 +135,7 @@ func NewType(t string) (typ Type, err error) { typ.Type = reflect.TypeOf(bool(false)) case "address": typ.Kind = reflect.Array - typ.Type = address_t + typ.Type = addressT typ.Size = 20 typ.T = AddressTy case "string": diff --git a/accounts/abi/type_test.go b/accounts/abi/type_test.go index e55af12939..f6b36f18fd 100644 --- a/accounts/abi/type_test.go +++ b/accounts/abi/type_test.go @@ -46,36 +46,36 @@ func TestTypeRegexp(t *testing.T) { {"bool[2][2][2]", Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2][2][2]bool{}), Elem: &Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2][2]bool{}), Elem: &Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]bool{}), Elem: &Type{Kind: reflect.Bool, T: BoolTy, Type: reflect.TypeOf(bool(false)), stringKind: "bool"}, stringKind: "bool[2]"}, stringKind: "bool[2][2]"}, stringKind: "bool[2][2][2]"}}, {"bool[][][]", Type{T: SliceTy, Kind: reflect.Slice, Type: reflect.TypeOf([][][]bool{}), Elem: &Type{T: SliceTy, Kind: reflect.Slice, Type: reflect.TypeOf([][]bool{}), Elem: &Type{T: SliceTy, Kind: reflect.Slice, Type: reflect.TypeOf([]bool{}), Elem: &Type{Kind: reflect.Bool, T: BoolTy, Type: reflect.TypeOf(bool(false)), stringKind: "bool"}, stringKind: "bool[]"}, stringKind: "bool[][]"}, stringKind: "bool[][][]"}}, {"bool[][2][]", Type{T: SliceTy, Kind: reflect.Slice, Type: reflect.TypeOf([][2][]bool{}), Elem: &Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2][]bool{}), Elem: &Type{T: SliceTy, Kind: reflect.Slice, Type: reflect.TypeOf([]bool{}), Elem: &Type{Kind: reflect.Bool, T: BoolTy, Type: reflect.TypeOf(bool(false)), stringKind: "bool"}, stringKind: "bool[]"}, stringKind: "bool[][2]"}, stringKind: "bool[][2][]"}}, - {"int8", Type{Kind: reflect.Int8, Type: int8_t, Size: 8, T: IntTy, stringKind: "int8"}}, - {"int16", Type{Kind: reflect.Int16, Type: int16_t, Size: 16, T: IntTy, stringKind: "int16"}}, - {"int32", Type{Kind: reflect.Int32, Type: int32_t, Size: 32, T: IntTy, stringKind: "int32"}}, - {"int64", Type{Kind: reflect.Int64, Type: int64_t, Size: 64, T: IntTy, stringKind: "int64"}}, - {"int256", Type{Kind: reflect.Ptr, Type: big_t, Size: 256, T: IntTy, stringKind: "int256"}}, - {"int8[]", Type{Kind: reflect.Slice, T: SliceTy, Type: reflect.TypeOf([]int8{}), Elem: &Type{Kind: reflect.Int8, Type: int8_t, Size: 8, T: IntTy, stringKind: "int8"}, stringKind: "int8[]"}}, - {"int8[2]", Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]int8{}), Elem: &Type{Kind: reflect.Int8, Type: int8_t, Size: 8, T: IntTy, stringKind: "int8"}, stringKind: "int8[2]"}}, - {"int16[]", Type{Kind: reflect.Slice, T: SliceTy, Type: reflect.TypeOf([]int16{}), Elem: &Type{Kind: reflect.Int16, Type: int16_t, Size: 16, T: IntTy, stringKind: "int16"}, stringKind: "int16[]"}}, - {"int16[2]", Type{Size: 2, Kind: reflect.Array, T: ArrayTy, Type: reflect.TypeOf([2]int16{}), Elem: &Type{Kind: reflect.Int16, Type: int16_t, Size: 16, T: IntTy, stringKind: "int16"}, stringKind: "int16[2]"}}, - {"int32[]", Type{Kind: reflect.Slice, T: SliceTy, Type: reflect.TypeOf([]int32{}), Elem: &Type{Kind: reflect.Int32, Type: int32_t, Size: 32, T: IntTy, stringKind: "int32"}, stringKind: "int32[]"}}, - {"int32[2]", Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]int32{}), Elem: &Type{Kind: reflect.Int32, Type: int32_t, Size: 32, T: IntTy, stringKind: "int32"}, stringKind: "int32[2]"}}, - {"int64[]", Type{Kind: reflect.Slice, T: SliceTy, Type: reflect.TypeOf([]int64{}), Elem: &Type{Kind: reflect.Int64, Type: int64_t, Size: 64, T: IntTy, stringKind: "int64"}, stringKind: "int64[]"}}, - {"int64[2]", Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]int64{}), Elem: &Type{Kind: reflect.Int64, Type: int64_t, Size: 64, T: IntTy, stringKind: "int64"}, stringKind: "int64[2]"}}, - {"int256[]", Type{Kind: reflect.Slice, T: SliceTy, Type: reflect.TypeOf([]*big.Int{}), Elem: &Type{Kind: reflect.Ptr, Type: big_t, Size: 256, T: IntTy, stringKind: "int256"}, stringKind: "int256[]"}}, - {"int256[2]", Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]*big.Int{}), Elem: &Type{Kind: reflect.Ptr, Type: big_t, Size: 256, T: IntTy, stringKind: "int256"}, stringKind: "int256[2]"}}, - {"uint8", Type{Kind: reflect.Uint8, Type: uint8_t, Size: 8, T: UintTy, stringKind: "uint8"}}, - {"uint16", Type{Kind: reflect.Uint16, Type: uint16_t, Size: 16, T: UintTy, stringKind: "uint16"}}, - {"uint32", Type{Kind: reflect.Uint32, Type: uint32_t, Size: 32, T: UintTy, stringKind: "uint32"}}, - {"uint64", Type{Kind: reflect.Uint64, Type: uint64_t, Size: 64, T: UintTy, stringKind: "uint64"}}, - {"uint256", Type{Kind: reflect.Ptr, Type: big_t, Size: 256, T: UintTy, stringKind: "uint256"}}, - {"uint8[]", Type{Kind: reflect.Slice, T: SliceTy, Type: reflect.TypeOf([]uint8{}), Elem: &Type{Kind: reflect.Uint8, Type: uint8_t, Size: 8, T: UintTy, stringKind: "uint8"}, stringKind: "uint8[]"}}, - {"uint8[2]", Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]uint8{}), Elem: &Type{Kind: reflect.Uint8, Type: uint8_t, Size: 8, T: UintTy, stringKind: "uint8"}, stringKind: "uint8[2]"}}, - {"uint16[]", Type{T: SliceTy, Kind: reflect.Slice, Type: reflect.TypeOf([]uint16{}), Elem: &Type{Kind: reflect.Uint16, Type: uint16_t, Size: 16, T: UintTy, stringKind: "uint16"}, stringKind: "uint16[]"}}, - {"uint16[2]", Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]uint16{}), Elem: &Type{Kind: reflect.Uint16, Type: uint16_t, Size: 16, T: UintTy, stringKind: "uint16"}, stringKind: "uint16[2]"}}, - {"uint32[]", Type{T: SliceTy, Kind: reflect.Slice, Type: reflect.TypeOf([]uint32{}), Elem: &Type{Kind: reflect.Uint32, Type: uint32_t, Size: 32, T: UintTy, stringKind: "uint32"}, stringKind: "uint32[]"}}, - {"uint32[2]", Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]uint32{}), Elem: &Type{Kind: reflect.Uint32, Type: uint32_t, Size: 32, T: UintTy, stringKind: "uint32"}, stringKind: "uint32[2]"}}, - {"uint64[]", Type{T: SliceTy, Kind: reflect.Slice, Type: reflect.TypeOf([]uint64{}), Elem: &Type{Kind: reflect.Uint64, Type: uint64_t, Size: 64, T: UintTy, stringKind: "uint64"}, stringKind: "uint64[]"}}, - {"uint64[2]", Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]uint64{}), Elem: &Type{Kind: reflect.Uint64, Type: uint64_t, Size: 64, T: UintTy, stringKind: "uint64"}, stringKind: "uint64[2]"}}, - {"uint256[]", Type{T: SliceTy, Kind: reflect.Slice, Type: reflect.TypeOf([]*big.Int{}), Elem: &Type{Kind: reflect.Ptr, Type: big_t, Size: 256, T: UintTy, stringKind: "uint256"}, stringKind: "uint256[]"}}, - {"uint256[2]", Type{Kind: reflect.Array, T: ArrayTy, Type: reflect.TypeOf([2]*big.Int{}), Size: 2, Elem: &Type{Kind: reflect.Ptr, Type: big_t, Size: 256, T: UintTy, stringKind: "uint256"}, stringKind: "uint256[2]"}}, + {"int8", Type{Kind: reflect.Int8, Type: int8T, Size: 8, T: IntTy, stringKind: "int8"}}, + {"int16", Type{Kind: reflect.Int16, Type: int16T, Size: 16, T: IntTy, stringKind: "int16"}}, + {"int32", Type{Kind: reflect.Int32, Type: int32T, Size: 32, T: IntTy, stringKind: "int32"}}, + {"int64", Type{Kind: reflect.Int64, Type: int64T, Size: 64, T: IntTy, stringKind: "int64"}}, + {"int256", Type{Kind: reflect.Ptr, Type: bigT, Size: 256, T: IntTy, stringKind: "int256"}}, + {"int8[]", Type{Kind: reflect.Slice, T: SliceTy, Type: reflect.TypeOf([]int8{}), Elem: &Type{Kind: reflect.Int8, Type: int8T, Size: 8, T: IntTy, stringKind: "int8"}, stringKind: "int8[]"}}, + {"int8[2]", Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]int8{}), Elem: &Type{Kind: reflect.Int8, Type: int8T, Size: 8, T: IntTy, stringKind: "int8"}, stringKind: "int8[2]"}}, + {"int16[]", Type{Kind: reflect.Slice, T: SliceTy, Type: reflect.TypeOf([]int16{}), Elem: &Type{Kind: reflect.Int16, Type: int16T, Size: 16, T: IntTy, stringKind: "int16"}, stringKind: "int16[]"}}, + {"int16[2]", Type{Size: 2, Kind: reflect.Array, T: ArrayTy, Type: reflect.TypeOf([2]int16{}), Elem: &Type{Kind: reflect.Int16, Type: int16T, Size: 16, T: IntTy, stringKind: "int16"}, stringKind: "int16[2]"}}, + {"int32[]", Type{Kind: reflect.Slice, T: SliceTy, Type: reflect.TypeOf([]int32{}), Elem: &Type{Kind: reflect.Int32, Type: int32T, Size: 32, T: IntTy, stringKind: "int32"}, stringKind: "int32[]"}}, + {"int32[2]", Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]int32{}), Elem: &Type{Kind: reflect.Int32, Type: int32T, Size: 32, T: IntTy, stringKind: "int32"}, stringKind: "int32[2]"}}, + {"int64[]", Type{Kind: reflect.Slice, T: SliceTy, Type: reflect.TypeOf([]int64{}), Elem: &Type{Kind: reflect.Int64, Type: int64T, Size: 64, T: IntTy, stringKind: "int64"}, stringKind: "int64[]"}}, + {"int64[2]", Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]int64{}), Elem: &Type{Kind: reflect.Int64, Type: int64T, Size: 64, T: IntTy, stringKind: "int64"}, stringKind: "int64[2]"}}, + {"int256[]", Type{Kind: reflect.Slice, T: SliceTy, Type: reflect.TypeOf([]*big.Int{}), Elem: &Type{Kind: reflect.Ptr, Type: bigT, Size: 256, T: IntTy, stringKind: "int256"}, stringKind: "int256[]"}}, + {"int256[2]", Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]*big.Int{}), Elem: &Type{Kind: reflect.Ptr, Type: bigT, Size: 256, T: IntTy, stringKind: "int256"}, stringKind: "int256[2]"}}, + {"uint8", Type{Kind: reflect.Uint8, Type: uint8T, Size: 8, T: UintTy, stringKind: "uint8"}}, + {"uint16", Type{Kind: reflect.Uint16, Type: uint16T, Size: 16, T: UintTy, stringKind: "uint16"}}, + {"uint32", Type{Kind: reflect.Uint32, Type: uint32T, Size: 32, T: UintTy, stringKind: "uint32"}}, + {"uint64", Type{Kind: reflect.Uint64, Type: uint64T, Size: 64, T: UintTy, stringKind: "uint64"}}, + {"uint256", Type{Kind: reflect.Ptr, Type: bigT, Size: 256, T: UintTy, stringKind: "uint256"}}, + {"uint8[]", Type{Kind: reflect.Slice, T: SliceTy, Type: reflect.TypeOf([]uint8{}), Elem: &Type{Kind: reflect.Uint8, Type: uint8T, Size: 8, T: UintTy, stringKind: "uint8"}, stringKind: "uint8[]"}}, + {"uint8[2]", Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]uint8{}), Elem: &Type{Kind: reflect.Uint8, Type: uint8T, Size: 8, T: UintTy, stringKind: "uint8"}, stringKind: "uint8[2]"}}, + {"uint16[]", Type{T: SliceTy, Kind: reflect.Slice, Type: reflect.TypeOf([]uint16{}), Elem: &Type{Kind: reflect.Uint16, Type: uint16T, Size: 16, T: UintTy, stringKind: "uint16"}, stringKind: "uint16[]"}}, + {"uint16[2]", Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]uint16{}), Elem: &Type{Kind: reflect.Uint16, Type: uint16T, Size: 16, T: UintTy, stringKind: "uint16"}, stringKind: "uint16[2]"}}, + {"uint32[]", Type{T: SliceTy, Kind: reflect.Slice, Type: reflect.TypeOf([]uint32{}), Elem: &Type{Kind: reflect.Uint32, Type: uint32T, Size: 32, T: UintTy, stringKind: "uint32"}, stringKind: "uint32[]"}}, + {"uint32[2]", Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]uint32{}), Elem: &Type{Kind: reflect.Uint32, Type: uint32T, Size: 32, T: UintTy, stringKind: "uint32"}, stringKind: "uint32[2]"}}, + {"uint64[]", Type{T: SliceTy, Kind: reflect.Slice, Type: reflect.TypeOf([]uint64{}), Elem: &Type{Kind: reflect.Uint64, Type: uint64T, Size: 64, T: UintTy, stringKind: "uint64"}, stringKind: "uint64[]"}}, + {"uint64[2]", Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]uint64{}), Elem: &Type{Kind: reflect.Uint64, Type: uint64T, Size: 64, T: UintTy, stringKind: "uint64"}, stringKind: "uint64[2]"}}, + {"uint256[]", Type{T: SliceTy, Kind: reflect.Slice, Type: reflect.TypeOf([]*big.Int{}), Elem: &Type{Kind: reflect.Ptr, Type: bigT, Size: 256, T: UintTy, stringKind: "uint256"}, stringKind: "uint256[]"}}, + {"uint256[2]", Type{Kind: reflect.Array, T: ArrayTy, Type: reflect.TypeOf([2]*big.Int{}), Size: 2, Elem: &Type{Kind: reflect.Ptr, Type: bigT, Size: 256, T: UintTy, stringKind: "uint256"}, stringKind: "uint256[2]"}}, {"bytes32", Type{Kind: reflect.Array, T: FixedBytesTy, Size: 32, Type: reflect.TypeOf([32]byte{}), stringKind: "bytes32"}}, {"bytes[]", Type{T: SliceTy, Kind: reflect.Slice, Type: reflect.TypeOf([][]byte{}), Elem: &Type{Kind: reflect.Slice, Type: reflect.TypeOf([]byte{}), T: BytesTy, stringKind: "bytes"}, stringKind: "bytes[]"}}, {"bytes[2]", Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2][]byte{}), Elem: &Type{T: BytesTy, Type: reflect.TypeOf([]byte{}), Kind: reflect.Slice, stringKind: "bytes"}, stringKind: "bytes[2]"}}, @@ -84,9 +84,9 @@ func TestTypeRegexp(t *testing.T) { {"string", Type{Kind: reflect.String, T: StringTy, Type: reflect.TypeOf(""), stringKind: "string"}}, {"string[]", Type{T: SliceTy, Kind: reflect.Slice, Type: reflect.TypeOf([]string{}), Elem: &Type{Kind: reflect.String, Type: reflect.TypeOf(""), T: StringTy, stringKind: "string"}, stringKind: "string[]"}}, {"string[2]", Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]string{}), Elem: &Type{Kind: reflect.String, T: StringTy, Type: reflect.TypeOf(""), stringKind: "string"}, stringKind: "string[2]"}}, - {"address", Type{Kind: reflect.Array, Type: address_t, Size: 20, T: AddressTy, stringKind: "address"}}, - {"address[]", Type{T: SliceTy, Kind: reflect.Slice, Type: reflect.TypeOf([]common.Address{}), Elem: &Type{Kind: reflect.Array, Type: address_t, Size: 20, T: AddressTy, stringKind: "address"}, stringKind: "address[]"}}, - {"address[2]", Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]common.Address{}), Elem: &Type{Kind: reflect.Array, Type: address_t, Size: 20, T: AddressTy, stringKind: "address"}, stringKind: "address[2]"}}, + {"address", Type{Kind: reflect.Array, Type: addressT, Size: 20, T: AddressTy, stringKind: "address"}}, + {"address[]", Type{T: SliceTy, Kind: reflect.Slice, Type: reflect.TypeOf([]common.Address{}), Elem: &Type{Kind: reflect.Array, Type: addressT, Size: 20, T: AddressTy, stringKind: "address"}, stringKind: "address[]"}}, + {"address[2]", Type{Kind: reflect.Array, T: ArrayTy, Size: 2, Type: reflect.TypeOf([2]common.Address{}), Elem: &Type{Kind: reflect.Array, Type: addressT, Size: 20, T: AddressTy, stringKind: "address"}, stringKind: "address[2]"}}, // TODO when fixed types are implemented properly // {"fixed", Type{}}, // {"fixed128x128", Type{}}, @@ -252,6 +252,9 @@ func TestTypeCheck(t *testing.T) { {"bytes20", common.Address{}, ""}, {"address", [20]byte{}, ""}, {"address", common.Address{}, ""}, + {"bytes32[]]", "", "invalid arg type in abi"}, + {"invalidType", "", "unsupported arg type: invalidType"}, + {"invalidSlice[]", "", "unsupported arg type: invalidSlice"}, } { typ, err := NewType(test.typ) if err != nil && len(test.err) == 0 { diff --git a/accounts/abi/unpack_test.go b/accounts/abi/unpack_test.go index ee62567094..bdbab10b4f 100644 --- a/accounts/abi/unpack_test.go +++ b/accounts/abi/unpack_test.go @@ -56,6 +56,23 @@ var unpackTests = []unpackTest{ enc: "0000000000000000000000000000000000000000000000000000000000000001", want: true, }, + { + def: `[{ "type": "bool" }]`, + enc: "0000000000000000000000000000000000000000000000000000000000000000", + want: false, + }, + { + def: `[{ "type": "bool" }]`, + enc: "0000000000000000000000000000000000000000000000000001000000000001", + want: false, + err: "abi: improperly encoded boolean value", + }, + { + def: `[{ "type": "bool" }]`, + enc: "0000000000000000000000000000000000000000000000000000000000000003", + want: false, + err: "abi: improperly encoded boolean value", + }, { def: `[{"type": "uint32"}]`, enc: "0000000000000000000000000000000000000000000000000000000000000001", diff --git a/accounts/keystore/account_cache.go b/accounts/keystore/account_cache.go index 71f698ece7..da3a46eb80 100644 --- a/accounts/keystore/account_cache.go +++ b/accounts/keystore/account_cache.go @@ -27,10 +27,10 @@ import ( "sync" "time" + mapset "github.com/deckarep/golang-set" "github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/log" - "gopkg.in/fatih/set.v0" ) // Minimum amount of time between cache reloads. This limit applies if the platform does @@ -79,7 +79,7 @@ func newAccountCache(keydir string) (*accountCache, chan struct{}) { keydir: keydir, byAddr: make(map[common.Address][]accounts.Account), notify: make(chan struct{}, 1), - fileC: fileCache{all: set.NewNonTS()}, + fileC: fileCache{all: mapset.NewThreadUnsafeSet()}, } ac.watcher = newWatcher(ac) return ac, ac.notify @@ -237,7 +237,7 @@ func (ac *accountCache) scanAccounts() error { log.Debug("Failed to reload keystore contents", "err", err) return err } - if creates.Size() == 0 && deletes.Size() == 0 && updates.Size() == 0 { + if creates.Cardinality() == 0 && deletes.Cardinality() == 0 && updates.Cardinality() == 0 { return nil } // Create a helper method to scan the contents of the key files @@ -272,15 +272,15 @@ func (ac *accountCache) scanAccounts() error { // Process all the file diffs start := time.Now() - for _, p := range creates.List() { + for _, p := range creates.ToSlice() { if a := readAccount(p.(string)); a != nil { ac.add(*a) } } - for _, p := range deletes.List() { + for _, p := range deletes.ToSlice() { ac.deleteByFile(p.(string)) } - for _, p := range updates.List() { + for _, p := range updates.ToSlice() { path := p.(string) ac.deleteByFile(path) if a := readAccount(path); a != nil { diff --git a/accounts/keystore/file_cache.go b/accounts/keystore/file_cache.go index c91b7b7b61..26da34dcfd 100644 --- a/accounts/keystore/file_cache.go +++ b/accounts/keystore/file_cache.go @@ -24,20 +24,20 @@ import ( "sync" "time" + mapset "github.com/deckarep/golang-set" "github.com/ethereum/go-ethereum/log" - set "gopkg.in/fatih/set.v0" ) // fileCache is a cache of files seen during scan of keystore. type fileCache struct { - all *set.SetNonTS // Set of all files from the keystore folder - lastMod time.Time // Last time instance when a file was modified + all mapset.Set // Set of all files from the keystore folder + lastMod time.Time // Last time instance when a file was modified mu sync.RWMutex } // scan performs a new scan on the given directory, compares against the already // cached filenames, and returns file sets: creates, deletes, updates. -func (fc *fileCache) scan(keyDir string) (set.Interface, set.Interface, set.Interface, error) { +func (fc *fileCache) scan(keyDir string) (mapset.Set, mapset.Set, mapset.Set, error) { t0 := time.Now() // List all the failes from the keystore folder @@ -51,8 +51,8 @@ func (fc *fileCache) scan(keyDir string) (set.Interface, set.Interface, set.Inte defer fc.mu.Unlock() // Iterate all the files and gather their metadata - all := set.NewNonTS() - mods := set.NewNonTS() + all := mapset.NewThreadUnsafeSet() + mods := mapset.NewThreadUnsafeSet() var newLastMod time.Time for _, fi := range files { @@ -76,9 +76,9 @@ func (fc *fileCache) scan(keyDir string) (set.Interface, set.Interface, set.Inte t2 := time.Now() // Update the tracked files and return the three sets - deletes := set.Difference(fc.all, all) // Deletes = previous - current - creates := set.Difference(all, fc.all) // Creates = current - previous - updates := set.Difference(mods, creates) // Updates = modified - creates + deletes := fc.all.Difference(all) // Deletes = previous - current + creates := all.Difference(fc.all) // Creates = current - previous + updates := mods.Difference(creates) // Updates = modified - creates fc.all, fc.lastMod = all, newLastMod t3 := time.Now() diff --git a/accounts/keystore/keystore.go b/accounts/keystore/keystore.go index 80ccd37419..6b04acd05f 100644 --- a/accounts/keystore/keystore.go +++ b/accounts/keystore/keystore.go @@ -50,7 +50,7 @@ var ( var KeyStoreType = reflect.TypeOf(&KeyStore{}) // KeyStoreScheme is the protocol scheme prefixing account and wallet URLs. -var KeyStoreScheme = "keystore" +const KeyStoreScheme = "keystore" // Maximum time between wallet refreshes (if filesystem notifications don't work). const walletRefreshCycle = 3 * time.Second diff --git a/accounts/keystore/keystore_passphrase.go b/accounts/keystore/keystore_passphrase.go index 02b7a417c9..0f7642a62a 100644 --- a/accounts/keystore/keystore_passphrase.go +++ b/accounts/keystore/keystore_passphrase.go @@ -28,18 +28,18 @@ package keystore import ( "bytes" "crypto/aes" - crand "crypto/rand" + "crypto/rand" "crypto/sha256" "encoding/hex" "encoding/json" "fmt" + "io" "io/ioutil" "path/filepath" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/math" "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/crypto/randentropy" "github.com/pborman/uuid" "golang.org/x/crypto/pbkdf2" "golang.org/x/crypto/scrypt" @@ -93,7 +93,7 @@ func (ks keyStorePassphrase) GetKey(addr common.Address, filename, auth string) // StoreKey generates a key, encrypts with 'auth' and stores in the given directory func StoreKey(dir, auth string, scryptN, scryptP int) (common.Address, error) { - _, a, err := storeNewKey(&keyStorePassphrase{dir, scryptN, scryptP}, crand.Reader, auth) + _, a, err := storeNewKey(&keyStorePassphrase{dir, scryptN, scryptP}, rand.Reader, auth) return a.Address, err } @@ -108,16 +108,19 @@ func (ks keyStorePassphrase) StoreKey(filename string, key *Key, auth string) er func (ks keyStorePassphrase) JoinPath(filename string) string { if filepath.IsAbs(filename) { return filename - } else { - return filepath.Join(ks.keysDirPath, filename) } + return filepath.Join(ks.keysDirPath, filename) } // EncryptKey encrypts a key using the specified scrypt parameters into a json // blob that can be decrypted later on. func EncryptKey(key *Key, auth string, scryptN, scryptP int) ([]byte, error) { authArray := []byte(auth) - salt := randentropy.GetEntropyCSPRNG(32) + + salt := make([]byte, 32) + if _, err := io.ReadFull(rand.Reader, salt); err != nil { + panic("reading from crypto/rand failed: " + err.Error()) + } derivedKey, err := scrypt.Key(authArray, salt, scryptN, scryptR, scryptP, scryptDKLen) if err != nil { return nil, err @@ -125,7 +128,10 @@ func EncryptKey(key *Key, auth string, scryptN, scryptP int) ([]byte, error) { encryptKey := derivedKey[:16] keyBytes := math.PaddedBigBytes(key.PrivateKey.D, 32) - iv := randentropy.GetEntropyCSPRNG(aes.BlockSize) // 16 + iv := make([]byte, aes.BlockSize) // 16 + if _, err := io.ReadFull(rand.Reader, iv); err != nil { + panic("reading from crypto/rand failed: " + err.Error()) + } cipherText, err := aesCTRXOR(encryptKey, keyBytes, iv) if err != nil { return nil, err diff --git a/accounts/keystore/keystore_plain.go b/accounts/keystore/keystore_plain.go index b490ca72b8..f62a133ce1 100644 --- a/accounts/keystore/keystore_plain.go +++ b/accounts/keystore/keystore_plain.go @@ -56,7 +56,6 @@ func (ks keyStorePlain) StoreKey(filename string, key *Key, auth string) error { func (ks keyStorePlain) JoinPath(filename string) string { if filepath.IsAbs(filename) { return filename - } else { - return filepath.Join(ks.keysDirPath, filename) } + return filepath.Join(ks.keysDirPath, filename) } diff --git a/accounts/url.go b/accounts/url.go index 47f9d8ee4b..a5add10216 100644 --- a/accounts/url.go +++ b/accounts/url.go @@ -74,6 +74,22 @@ func (u URL) MarshalJSON() ([]byte, error) { return json.Marshal(u.String()) } +// UnmarshalJSON parses url. +func (u *URL) UnmarshalJSON(input []byte) error { + var textURL string + err := json.Unmarshal(input, &textURL) + if err != nil { + return err + } + url, err := parseURL(textURL) + if err != nil { + return err + } + u.Scheme = url.Scheme + u.Path = url.Path + return nil +} + // Cmp compares x and y and returns: // // -1 if x < y diff --git a/accounts/url_test.go b/accounts/url_test.go new file mode 100644 index 0000000000..8027728719 --- /dev/null +++ b/accounts/url_test.go @@ -0,0 +1,96 @@ +// 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 accounts + +import ( + "testing" +) + +func TestURLParsing(t *testing.T) { + url, err := parseURL("https://ethereum.org") + if err != nil { + t.Errorf("unexpected error: %v", err) + } + if url.Scheme != "https" { + t.Errorf("expected: %v, got: %v", "https", url.Scheme) + } + if url.Path != "ethereum.org" { + t.Errorf("expected: %v, got: %v", "ethereum.org", url.Path) + } + + _, err = parseURL("ethereum.org") + if err == nil { + t.Error("expected err, got: nil") + } +} + +func TestURLString(t *testing.T) { + url := URL{Scheme: "https", Path: "ethereum.org"} + if url.String() != "https://ethereum.org" { + t.Errorf("expected: %v, got: %v", "https://ethereum.org", url.String()) + } + + url = URL{Scheme: "", Path: "ethereum.org"} + if url.String() != "ethereum.org" { + t.Errorf("expected: %v, got: %v", "ethereum.org", url.String()) + } +} + +func TestURLMarshalJSON(t *testing.T) { + url := URL{Scheme: "https", Path: "ethereum.org"} + json, err := url.MarshalJSON() + if err != nil { + t.Errorf("unexpcted error: %v", err) + } + if string(json) != "\"https://ethereum.org\"" { + t.Errorf("expected: %v, got: %v", "\"https://ethereum.org\"", string(json)) + } +} + +func TestURLUnmarshalJSON(t *testing.T) { + url := &URL{} + err := url.UnmarshalJSON([]byte("\"https://ethereum.org\"")) + if err != nil { + t.Errorf("unexpcted error: %v", err) + } + if url.Scheme != "https" { + t.Errorf("expected: %v, got: %v", "https", url.Scheme) + } + if url.Path != "ethereum.org" { + t.Errorf("expected: %v, got: %v", "https", url.Path) + } +} + +func TestURLComparison(t *testing.T) { + tests := []struct { + urlA URL + urlB URL + expect int + }{ + {URL{"https", "ethereum.org"}, URL{"https", "ethereum.org"}, 0}, + {URL{"http", "ethereum.org"}, URL{"https", "ethereum.org"}, -1}, + {URL{"https", "ethereum.org/a"}, URL{"https", "ethereum.org"}, 1}, + {URL{"https", "abc.org"}, URL{"https", "ethereum.org"}, -1}, + } + + for i, tt := range tests { + result := tt.urlA.Cmp(tt.urlB) + if result != tt.expect { + t.Errorf("test %d: cmp mismatch: expected: %d, got: %d", i, tt.expect, result) + } + } +} diff --git a/accounts/usbwallet/hub.go b/accounts/usbwallet/hub.go index 61fc98ccc8..640320bc91 100644 --- a/accounts/usbwallet/hub.go +++ b/accounts/usbwallet/hub.go @@ -127,7 +127,7 @@ func (hub *Hub) refreshWallets() { // breaking the Ledger protocol if that is waiting for user confirmation. This // is a bug acknowledged at Ledger, but it won't be fixed on old devices so we // need to prevent concurrent comms ourselves. The more elegant solution would - // be to ditch enumeration in favor of hutplug events, but that don't work yet + // be to ditch enumeration in favor of hotplug events, but that don't work yet // on Windows so if we need to hack it anyway, this is more elegant for now. hub.commsLock.Lock() if hub.commsPend > 0 { // A confirmation is pending, don't refresh diff --git a/accounts/usbwallet/internal/trezor/trezor.go b/accounts/usbwallet/internal/trezor/trezor.go index 8ae9e726e4..80cc75efc4 100644 --- a/accounts/usbwallet/internal/trezor/trezor.go +++ b/accounts/usbwallet/internal/trezor/trezor.go @@ -36,7 +36,7 @@ func Type(msg proto.Message) uint16 { } // Name returns the friendly message type name of a specific protocol buffer -// type numbers. +// type number. func Name(kind uint16) string { name := MessageType_name[int32(kind)] if len(name) < 12 { diff --git a/accounts/usbwallet/ledger.go b/accounts/usbwallet/ledger.go index f5def61d23..2583fbc4da 100644 --- a/accounts/usbwallet/ledger.go +++ b/accounts/usbwallet/ledger.go @@ -53,11 +53,9 @@ const ( ledgerOpGetConfiguration ledgerOpcode = 0x06 // Returns specific wallet application configuration ledgerP1DirectlyFetchAddress ledgerParam1 = 0x00 // Return address directly from the wallet - ledgerP1ConfirmFetchAddress ledgerParam1 = 0x01 // Require a user confirmation before returning the address ledgerP1InitTransactionData ledgerParam1 = 0x00 // First transaction data block for signing ledgerP1ContTransactionData ledgerParam1 = 0x80 // Subsequent transaction data block for signing ledgerP2DiscardAddressChainCode ledgerParam2 = 0x00 // Do not return the chain code along with the address - ledgerP2ReturnAddressChainCode ledgerParam2 = 0x01 // Require a user confirmation before returning the address ) // errLedgerReplyInvalidHeader is the error message returned by a Ledger data exchange @@ -304,7 +302,7 @@ func (w *ledgerDriver) ledgerSign(derivationPath []uint32, tx *types.Transaction for i, component := range derivationPath { binary.BigEndian.PutUint32(path[1+4*i:], component) } - // Create the transaction RLP based on whether legacy or EIP155 signing was requeste + // Create the transaction RLP based on whether legacy or EIP155 signing was requested var ( txrlp []byte err error diff --git a/accounts/usbwallet/wallet.go b/accounts/usbwallet/wallet.go index 8b3b5a5224..6cef6e0fb0 100644 --- a/accounts/usbwallet/wallet.go +++ b/accounts/usbwallet/wallet.go @@ -99,7 +99,7 @@ type wallet struct { // // As such, a hardware wallet needs two locks to function correctly. A state // lock can be used to protect the wallet's software-side internal state, which - // must not be held exlusively during hardware communication. A communication + // must not be held exclusively during hardware communication. A communication // lock can be used to achieve exclusive access to the device itself, this one // however should allow "skipping" waiting for operations that might want to // use the device, but can live without too (e.g. account self-derivation). diff --git a/appveyor.yml b/appveyor.yml index 45475d1669..05ff92cf36 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -23,8 +23,8 @@ environment: install: - git submodule update --init - rmdir C:\go /s /q - - appveyor DownloadFile https://storage.googleapis.com/golang/go1.10.windows-%GETH_ARCH%.zip - - 7z x go1.10.windows-%GETH_ARCH%.zip -y -oC:\ > NUL + - appveyor DownloadFile https://storage.googleapis.com/golang/go1.10.3.windows-%GETH_ARCH%.zip + - 7z x go1.10.3.windows-%GETH_ARCH%.zip -y -oC:\ > NUL - go version - gcc --version diff --git a/bmt/bmt.go b/bmt/bmt.go deleted file mode 100644 index 4b65b1d94a..0000000000 --- a/bmt/bmt.go +++ /dev/null @@ -1,561 +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 bmt provides a binary merkle tree implementation -package bmt - -import ( - "fmt" - "hash" - "io" - "strings" - "sync" - "sync/atomic" -) - -/* -Binary Merkle Tree Hash is a hash function over arbitrary datachunks of limited size -It is defined as the root hash of the binary merkle tree built over fixed size segments -of the underlying chunk using any base hash function (e.g keccak 256 SHA3) - -It is used as the chunk hash function in swarm which in turn is the basis for the -128 branching swarm hash http://swarm-guide.readthedocs.io/en/latest/architecture.html#swarm-hash - -The BMT is optimal for providing compact inclusion proofs, i.e. prove that a -segment is a substring of a chunk starting at a particular offset -The size of the underlying segments is fixed at 32 bytes (called the resolution -of the BMT hash), the EVM word size to optimize for on-chain BMT verification -as well as the hash size optimal for inclusion proofs in the merkle tree of the swarm hash. - -Two implementations are provided: - -* RefHasher is optimized for code simplicity and meant as a reference implementation -* Hasher is optimized for speed taking advantage of concurrency with minimalistic - control structure to coordinate the concurrent routines - It implements the ChunkHash interface as well as the go standard hash.Hash interface - -*/ - -const ( - // DefaultSegmentCount is the maximum number of segments of the underlying chunk - DefaultSegmentCount = 128 // Should be equal to storage.DefaultBranches - // DefaultPoolSize is the maximum number of bmt trees used by the hashers, i.e, - // the maximum number of concurrent BMT hashing operations performed by the same hasher - DefaultPoolSize = 8 -) - -// BaseHasher is a hash.Hash constructor function used for the base hash of the BMT. -type BaseHasher func() hash.Hash - -// Hasher a reusable hasher for fixed maximum size chunks representing a BMT -// implements the hash.Hash interface -// reuse pool of Tree-s for amortised memory allocation and resource control -// supports order-agnostic concurrent segment writes -// as well as sequential read and write -// can not be called concurrently on more than one chunk -// can be further appended after Sum -// Reset gives back the Tree to the pool and guaranteed to leave -// the tree and itself in a state reusable for hashing a new chunk -type Hasher struct { - pool *TreePool // BMT resource pool - bmt *Tree // prebuilt BMT resource for flowcontrol and proofs - blocksize int // segment size (size of hash) also for hash.Hash - count int // segment count - size int // for hash.Hash same as hashsize - cur int // cursor position for righmost currently open chunk - segment []byte // the rightmost open segment (not complete) - depth int // index of last level - result chan []byte // result channel - hash []byte // to record the result - max int32 // max segments for SegmentWriter interface - blockLength []byte // The block length that needes to be added in Sum -} - -// New creates a reusable Hasher -// implements the hash.Hash interface -// pulls a new Tree from a resource pool for hashing each chunk -func New(p *TreePool) *Hasher { - return &Hasher{ - pool: p, - depth: depth(p.SegmentCount), - size: p.SegmentSize, - blocksize: p.SegmentSize, - count: p.SegmentCount, - result: make(chan []byte), - } -} - -// Node is a reuseable segment hasher representing a node in a BMT -// it allows for continued writes after a Sum -// and is left in completely reusable state after Reset -type Node struct { - level, index int // position of node for information/logging only - initial bool // first and last node - root bool // whether the node is root to a smaller BMT - isLeft bool // whether it is left side of the parent double segment - unbalanced bool // indicates if a node has only the left segment - parent *Node // BMT connections - state int32 // atomic increment impl concurrent boolean toggle - left, right []byte -} - -// NewNode constructor for segment hasher nodes in the BMT -func NewNode(level, index int, parent *Node) *Node { - return &Node{ - parent: parent, - level: level, - index: index, - initial: index == 0, - isLeft: index%2 == 0, - } -} - -// TreePool provides a pool of Trees used as resources by Hasher -// a Tree popped from the pool is guaranteed to have clean state -// for hashing a new chunk -// Hasher Reset releases the Tree to the pool -type TreePool struct { - lock sync.Mutex - c chan *Tree - hasher BaseHasher - SegmentSize int - SegmentCount int - Capacity int - count int -} - -// NewTreePool creates a Tree pool with hasher, segment size, segment count and capacity -// on GetTree it reuses free Trees or creates a new one if size is not reached -func NewTreePool(hasher BaseHasher, segmentCount, capacity int) *TreePool { - return &TreePool{ - c: make(chan *Tree, capacity), - hasher: hasher, - SegmentSize: hasher().Size(), - SegmentCount: segmentCount, - Capacity: capacity, - } -} - -// Drain drains the pool uptil it has no more than n resources -func (self *TreePool) Drain(n int) { - self.lock.Lock() - defer self.lock.Unlock() - for len(self.c) > n { - <-self.c - self.count-- - } -} - -// Reserve is blocking until it returns an available Tree -// it reuses free Trees or creates a new one if size is not reached -func (self *TreePool) Reserve() *Tree { - self.lock.Lock() - defer self.lock.Unlock() - var t *Tree - if self.count == self.Capacity { - return <-self.c - } - select { - case t = <-self.c: - default: - t = NewTree(self.hasher, self.SegmentSize, self.SegmentCount) - self.count++ - } - return t -} - -// Release gives back a Tree to the pool. -// This Tree is guaranteed to be in reusable state -// does not need locking -func (self *TreePool) Release(t *Tree) { - self.c <- t // can never fail but... -} - -// Tree is a reusable control structure representing a BMT -// organised in a binary tree -// Hasher uses a TreePool to pick one for each chunk hash -// the Tree is 'locked' while not in the pool -type Tree struct { - leaves []*Node -} - -// Draw draws the BMT (badly) -func (self *Tree) Draw(hash []byte, d int) string { - var left, right []string - var anc []*Node - for i, n := range self.leaves { - left = append(left, fmt.Sprintf("%v", hashstr(n.left))) - if i%2 == 0 { - anc = append(anc, n.parent) - } - right = append(right, fmt.Sprintf("%v", hashstr(n.right))) - } - anc = self.leaves - var hashes [][]string - for l := 0; len(anc) > 0; l++ { - var nodes []*Node - hash := []string{""} - for i, n := range anc { - hash = append(hash, fmt.Sprintf("%v|%v", hashstr(n.left), hashstr(n.right))) - if i%2 == 0 && n.parent != nil { - nodes = append(nodes, n.parent) - } - } - hash = append(hash, "") - hashes = append(hashes, hash) - anc = nodes - } - hashes = append(hashes, []string{"", fmt.Sprintf("%v", hashstr(hash)), ""}) - total := 60 - del := " " - var rows []string - for i := len(hashes) - 1; i >= 0; i-- { - var textlen int - hash := hashes[i] - for _, s := range hash { - textlen += len(s) - } - if total < textlen { - total = textlen + len(hash) - } - delsize := (total - textlen) / (len(hash) - 1) - if delsize > len(del) { - delsize = len(del) - } - row := fmt.Sprintf("%v: %v", len(hashes)-i-1, strings.Join(hash, del[:delsize])) - rows = append(rows, row) - - } - rows = append(rows, strings.Join(left, " ")) - rows = append(rows, strings.Join(right, " ")) - return strings.Join(rows, "\n") + "\n" -} - -// NewTree initialises the Tree by building up the nodes of a BMT -// segment size is stipulated to be the size of the hash -// segmentCount needs to be positive integer and does not need to be -// a power of two and can even be an odd number -// segmentSize * segmentCount determines the maximum chunk size -// hashed using the tree -func NewTree(hasher BaseHasher, segmentSize, segmentCount int) *Tree { - n := NewNode(0, 0, nil) - n.root = true - prevlevel := []*Node{n} - // iterate over levels and creates 2^level nodes - level := 1 - count := 2 - for d := 1; d <= depth(segmentCount); d++ { - nodes := make([]*Node, count) - for i := 0; i < len(nodes); i++ { - parent := prevlevel[i/2] - t := NewNode(level, i, parent) - nodes[i] = t - } - prevlevel = nodes - level++ - count *= 2 - } - // the datanode level is the nodes on the last level where - return &Tree{ - leaves: prevlevel, - } -} - -// methods needed by hash.Hash - -// Size returns the size -func (self *Hasher) Size() int { - return self.size -} - -// BlockSize returns the block size -func (self *Hasher) BlockSize() int { - return self.blocksize -} - -// Sum returns the hash of the buffer -// hash.Hash interface Sum method appends the byte slice to the underlying -// data before it calculates and returns the hash of the chunk -func (self *Hasher) Sum(b []byte) (r []byte) { - t := self.bmt - i := self.cur - n := t.leaves[i] - j := i - // must run strictly before all nodes calculate - // datanodes are guaranteed to have a parent - if len(self.segment) > self.size && i > 0 && n.parent != nil { - n = n.parent - } else { - i *= 2 - } - d := self.finalise(n, i) - self.writeSegment(j, self.segment, d) - c := <-self.result - self.releaseTree() - - // sha3(length + BMT(pure_chunk)) - if self.blockLength == nil { - return c - } - res := self.pool.hasher() - res.Reset() - res.Write(self.blockLength) - res.Write(c) - return res.Sum(nil) -} - -// Hasher implements the SwarmHash interface - -// Hash waits for the hasher result and returns it -// caller must call this on a BMT Hasher being written to -func (self *Hasher) Hash() []byte { - return <-self.result -} - -// Hasher implements the io.Writer interface - -// Write fills the buffer to hash -// with every full segment complete launches a hasher go routine -// that shoots up the BMT -func (self *Hasher) Write(b []byte) (int, error) { - l := len(b) - if l <= 0 { - return 0, nil - } - s := self.segment - i := self.cur - count := (self.count + 1) / 2 - need := self.count*self.size - self.cur*2*self.size - size := self.size - if need > size { - size *= 2 - } - if l < need { - need = l - } - // calculate missing bit to complete current open segment - rest := size - len(s) - if need < rest { - rest = need - } - s = append(s, b[:rest]...) - need -= rest - // read full segments and the last possibly partial segment - for need > 0 && i < count-1 { - // push all finished chunks we read - self.writeSegment(i, s, self.depth) - need -= size - if need < 0 { - size += need - } - s = b[rest : rest+size] - rest += size - i++ - } - self.segment = s - self.cur = i - // otherwise, we can assume len(s) == 0, so all buffer is read and chunk is not yet full - return l, nil -} - -// Hasher implements the io.ReaderFrom interface - -// ReadFrom reads from io.Reader and appends to the data to hash using Write -// it reads so that chunk to hash is maximum length or reader reaches EOF -// caller must Reset the hasher prior to call -func (self *Hasher) ReadFrom(r io.Reader) (m int64, err error) { - bufsize := self.size*self.count - self.size*self.cur - len(self.segment) - buf := make([]byte, bufsize) - var read int - for { - var n int - n, err = r.Read(buf) - read += n - if err == io.EOF || read == len(buf) { - hash := self.Sum(buf[:n]) - if read == len(buf) { - err = NewEOC(hash) - } - break - } - if err != nil { - break - } - n, err = self.Write(buf[:n]) - if err != nil { - break - } - } - return int64(read), err -} - -// Reset needs to be called before writing to the hasher -func (self *Hasher) Reset() { - self.getTree() - self.blockLength = nil -} - -// Hasher implements the SwarmHash interface - -// ResetWithLength needs to be called before writing to the hasher -// the argument is supposed to be the byte slice binary representation of -// the legth of the data subsumed under the hash -func (self *Hasher) ResetWithLength(l []byte) { - self.Reset() - self.blockLength = l - -} - -// Release gives back the Tree to the pool whereby it unlocks -// it resets tree, segment and index -func (self *Hasher) releaseTree() { - if self.bmt != nil { - n := self.bmt.leaves[self.cur] - for ; n != nil; n = n.parent { - n.unbalanced = false - if n.parent != nil { - n.root = false - } - } - self.pool.Release(self.bmt) - self.bmt = nil - - } - self.cur = 0 - self.segment = nil -} - -func (self *Hasher) writeSegment(i int, s []byte, d int) { - h := self.pool.hasher() - n := self.bmt.leaves[i] - - if len(s) > self.size && n.parent != nil { - go func() { - h.Reset() - h.Write(s) - s = h.Sum(nil) - - if n.root { - self.result <- s - return - } - self.run(n.parent, h, d, n.index, s) - }() - return - } - go self.run(n, h, d, i*2, s) -} - -func (self *Hasher) run(n *Node, h hash.Hash, d int, i int, s []byte) { - isLeft := i%2 == 0 - for { - if isLeft { - n.left = s - } else { - n.right = s - } - if !n.unbalanced && n.toggle() { - return - } - if !n.unbalanced || !isLeft || i == 0 && d == 0 { - h.Reset() - h.Write(n.left) - h.Write(n.right) - s = h.Sum(nil) - - } else { - s = append(n.left, n.right...) - } - - self.hash = s - if n.root { - self.result <- s - return - } - - isLeft = n.isLeft - n = n.parent - i++ - } -} - -// getTree obtains a BMT resource by reserving one from the pool -func (self *Hasher) getTree() *Tree { - if self.bmt != nil { - return self.bmt - } - t := self.pool.Reserve() - self.bmt = t - return t -} - -// atomic bool toggle implementing a concurrent reusable 2-state object -// atomic addint with %2 implements atomic bool toggle -// it returns true if the toggler just put it in the active/waiting state -func (self *Node) toggle() bool { - return atomic.AddInt32(&self.state, 1)%2 == 1 -} - -func hashstr(b []byte) string { - end := len(b) - if end > 4 { - end = 4 - } - return fmt.Sprintf("%x", b[:end]) -} - -func depth(n int) (d int) { - for l := (n - 1) / 2; l > 0; l /= 2 { - d++ - } - return d -} - -// finalise is following the zigzags on the tree belonging -// to the final datasegment -func (self *Hasher) finalise(n *Node, i int) (d int) { - isLeft := i%2 == 0 - for { - // when the final segment's path is going via left segments - // the incoming data is pushed to the parent upon pulling the left - // we do not need toogle the state since this condition is - // detectable - n.unbalanced = isLeft - n.right = nil - if n.initial { - n.root = true - return d - } - isLeft = n.isLeft - n = n.parent - d++ - } -} - -// EOC (end of chunk) implements the error interface -type EOC struct { - Hash []byte // read the hash of the chunk off the error -} - -// Error returns the error string -func (self *EOC) Error() string { - return fmt.Sprintf("hasher limit reached, chunk hash: %x", self.Hash) -} - -// NewEOC creates new end of chunk error with the hash -func NewEOC(hash []byte) *EOC { - return &EOC{hash} -} diff --git a/bmt/bmt_r.go b/bmt/bmt_r.go deleted file mode 100644 index 649093ee3a..0000000000 --- a/bmt/bmt_r.go +++ /dev/null @@ -1,85 +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 . - -// simple nonconcurrent reference implementation for hashsize segment based -// Binary Merkle tree hash on arbitrary but fixed maximum chunksize -// -// This implementation does not take advantage of any paralellisms and uses -// far more memory than necessary, but it is easy to see that it is correct. -// It can be used for generating test cases for optimized implementations. -// see testBMTHasherCorrectness function in bmt_test.go -package bmt - -import ( - "hash" -) - -// RefHasher is the non-optimized easy to read reference implementation of BMT -type RefHasher struct { - span int - section int - cap int - h hash.Hash -} - -// NewRefHasher returns a new RefHasher -func NewRefHasher(hasher BaseHasher, count int) *RefHasher { - h := hasher() - hashsize := h.Size() - maxsize := hashsize * count - c := 2 - for ; c < count; c *= 2 { - } - if c > 2 { - c /= 2 - } - return &RefHasher{ - section: 2 * hashsize, - span: c * hashsize, - cap: maxsize, - h: h, - } -} - -// Hash returns the BMT hash of the byte slice -// implements the SwarmHash interface -func (rh *RefHasher) Hash(d []byte) []byte { - if len(d) > rh.cap { - d = d[:rh.cap] - } - - return rh.hash(d, rh.span) -} - -func (rh *RefHasher) hash(d []byte, s int) []byte { - l := len(d) - left := d - var right []byte - if l > rh.section { - for ; s >= l; s /= 2 { - } - left = rh.hash(d[:s], s) - right = d[s:] - if l-s > rh.section/2 { - right = rh.hash(right, s) - } - } - defer rh.h.Reset() - rh.h.Write(left) - rh.h.Write(right) - h := rh.h.Sum(nil) - return h -} diff --git a/bmt/bmt_test.go b/bmt/bmt_test.go deleted file mode 100644 index 57df83060a..0000000000 --- a/bmt/bmt_test.go +++ /dev/null @@ -1,481 +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 bmt - -import ( - "bytes" - crand "crypto/rand" - "fmt" - "hash" - "io" - "math/rand" - "sync" - "sync/atomic" - "testing" - "time" - - "github.com/ethereum/go-ethereum/crypto/sha3" -) - -const ( - maxproccnt = 8 -) - -// TestRefHasher tests that the RefHasher computes the expected BMT hash for -// all data lengths between 0 and 256 bytes -func TestRefHasher(t *testing.T) { - hashFunc := sha3.NewKeccak256 - - sha3 := func(data ...[]byte) []byte { - h := hashFunc() - for _, v := range data { - h.Write(v) - } - return h.Sum(nil) - } - - // the test struct is used to specify the expected BMT hash for data - // lengths between "from" and "to" - type test struct { - from int64 - to int64 - expected func([]byte) []byte - } - - var tests []*test - - // all lengths in [0,64] should be: - // - // sha3(data) - // - tests = append(tests, &test{ - from: 0, - to: 64, - expected: func(data []byte) []byte { - return sha3(data) - }, - }) - - // all lengths in [65,96] should be: - // - // sha3( - // sha3(data[:64]) - // data[64:] - // ) - // - tests = append(tests, &test{ - from: 65, - to: 96, - expected: func(data []byte) []byte { - return sha3(sha3(data[:64]), data[64:]) - }, - }) - - // all lengths in [97,128] should be: - // - // sha3( - // sha3(data[:64]) - // sha3(data[64:]) - // ) - // - tests = append(tests, &test{ - from: 97, - to: 128, - expected: func(data []byte) []byte { - return sha3(sha3(data[:64]), sha3(data[64:])) - }, - }) - - // all lengths in [129,160] should be: - // - // sha3( - // sha3( - // sha3(data[:64]) - // sha3(data[64:128]) - // ) - // data[128:] - // ) - // - tests = append(tests, &test{ - from: 129, - to: 160, - expected: func(data []byte) []byte { - return sha3(sha3(sha3(data[:64]), sha3(data[64:128])), data[128:]) - }, - }) - - // all lengths in [161,192] should be: - // - // sha3( - // sha3( - // sha3(data[:64]) - // sha3(data[64:128]) - // ) - // sha3(data[128:]) - // ) - // - tests = append(tests, &test{ - from: 161, - to: 192, - expected: func(data []byte) []byte { - return sha3(sha3(sha3(data[:64]), sha3(data[64:128])), sha3(data[128:])) - }, - }) - - // all lengths in [193,224] should be: - // - // sha3( - // sha3( - // sha3(data[:64]) - // sha3(data[64:128]) - // ) - // sha3( - // sha3(data[128:192]) - // data[192:] - // ) - // ) - // - tests = append(tests, &test{ - from: 193, - to: 224, - expected: func(data []byte) []byte { - return sha3(sha3(sha3(data[:64]), sha3(data[64:128])), sha3(sha3(data[128:192]), data[192:])) - }, - }) - - // all lengths in [225,256] should be: - // - // sha3( - // sha3( - // sha3(data[:64]) - // sha3(data[64:128]) - // ) - // sha3( - // sha3(data[128:192]) - // sha3(data[192:]) - // ) - // ) - // - tests = append(tests, &test{ - from: 225, - to: 256, - expected: func(data []byte) []byte { - return sha3(sha3(sha3(data[:64]), sha3(data[64:128])), sha3(sha3(data[128:192]), sha3(data[192:]))) - }, - }) - - // run the tests - for _, x := range tests { - for length := x.from; length <= x.to; length++ { - t.Run(fmt.Sprintf("%d_bytes", length), func(t *testing.T) { - data := make([]byte, length) - if _, err := io.ReadFull(crand.Reader, data); err != nil && err != io.EOF { - t.Fatal(err) - } - expected := x.expected(data) - actual := NewRefHasher(hashFunc, 128).Hash(data) - if !bytes.Equal(actual, expected) { - t.Fatalf("expected %x, got %x", expected, actual) - } - }) - } - } -} - -func testDataReader(l int) (r io.Reader) { - return io.LimitReader(crand.Reader, int64(l)) -} - -func TestHasherCorrectness(t *testing.T) { - err := testHasher(testBaseHasher) - if err != nil { - t.Fatal(err) - } -} - -func testHasher(f func(BaseHasher, []byte, int, int) error) error { - tdata := testDataReader(4128) - data := make([]byte, 4128) - tdata.Read(data) - hasher := sha3.NewKeccak256 - size := hasher().Size() - counts := []int{1, 2, 3, 4, 5, 8, 16, 32, 64, 128} - - var err error - for _, count := range counts { - max := count * size - incr := 1 - for n := 0; n <= max+incr; n += incr { - err = f(hasher, data, n, count) - if err != nil { - return err - } - } - } - return nil -} - -func TestHasherReuseWithoutRelease(t *testing.T) { - testHasherReuse(1, t) -} - -func TestHasherReuseWithRelease(t *testing.T) { - testHasherReuse(maxproccnt, t) -} - -func testHasherReuse(i int, t *testing.T) { - hasher := sha3.NewKeccak256 - pool := NewTreePool(hasher, 128, i) - defer pool.Drain(0) - bmt := New(pool) - - for i := 0; i < 500; i++ { - n := rand.Intn(4096) - tdata := testDataReader(n) - data := make([]byte, n) - tdata.Read(data) - - err := testHasherCorrectness(bmt, hasher, data, n, 128) - if err != nil { - t.Fatal(err) - } - } -} - -func TestHasherConcurrency(t *testing.T) { - hasher := sha3.NewKeccak256 - pool := NewTreePool(hasher, 128, maxproccnt) - defer pool.Drain(0) - wg := sync.WaitGroup{} - cycles := 100 - wg.Add(maxproccnt * cycles) - errc := make(chan error) - - for p := 0; p < maxproccnt; p++ { - for i := 0; i < cycles; i++ { - go func() { - bmt := New(pool) - n := rand.Intn(4096) - tdata := testDataReader(n) - data := make([]byte, n) - tdata.Read(data) - err := testHasherCorrectness(bmt, hasher, data, n, 128) - wg.Done() - if err != nil { - errc <- err - } - }() - } - } - go func() { - wg.Wait() - close(errc) - }() - var err error - select { - case <-time.NewTimer(5 * time.Second).C: - err = fmt.Errorf("timed out") - case err = <-errc: - } - if err != nil { - t.Fatal(err) - } -} - -func testBaseHasher(hasher BaseHasher, d []byte, n, count int) error { - pool := NewTreePool(hasher, count, 1) - defer pool.Drain(0) - bmt := New(pool) - return testHasherCorrectness(bmt, hasher, d, n, count) -} - -func testHasherCorrectness(bmt hash.Hash, hasher BaseHasher, d []byte, n, count int) (err error) { - data := d[:n] - rbmt := NewRefHasher(hasher, count) - exp := rbmt.Hash(data) - timeout := time.NewTimer(time.Second) - c := make(chan error) - - go func() { - bmt.Reset() - bmt.Write(data) - got := bmt.Sum(nil) - if !bytes.Equal(got, exp) { - c <- fmt.Errorf("wrong hash: expected %x, got %x", exp, got) - } - close(c) - }() - select { - case <-timeout.C: - err = fmt.Errorf("BMT hash calculation timed out") - case err = <-c: - } - return err -} - -func BenchmarkSHA3_4k(t *testing.B) { benchmarkSHA3(4096, t) } -func BenchmarkSHA3_2k(t *testing.B) { benchmarkSHA3(4096/2, t) } -func BenchmarkSHA3_1k(t *testing.B) { benchmarkSHA3(4096/4, t) } -func BenchmarkSHA3_512b(t *testing.B) { benchmarkSHA3(4096/8, t) } -func BenchmarkSHA3_256b(t *testing.B) { benchmarkSHA3(4096/16, t) } -func BenchmarkSHA3_128b(t *testing.B) { benchmarkSHA3(4096/32, t) } - -func BenchmarkBMTBaseline_4k(t *testing.B) { benchmarkBMTBaseline(4096, t) } -func BenchmarkBMTBaseline_2k(t *testing.B) { benchmarkBMTBaseline(4096/2, t) } -func BenchmarkBMTBaseline_1k(t *testing.B) { benchmarkBMTBaseline(4096/4, t) } -func BenchmarkBMTBaseline_512b(t *testing.B) { benchmarkBMTBaseline(4096/8, t) } -func BenchmarkBMTBaseline_256b(t *testing.B) { benchmarkBMTBaseline(4096/16, t) } -func BenchmarkBMTBaseline_128b(t *testing.B) { benchmarkBMTBaseline(4096/32, t) } - -func BenchmarkRefHasher_4k(t *testing.B) { benchmarkRefHasher(4096, t) } -func BenchmarkRefHasher_2k(t *testing.B) { benchmarkRefHasher(4096/2, t) } -func BenchmarkRefHasher_1k(t *testing.B) { benchmarkRefHasher(4096/4, t) } -func BenchmarkRefHasher_512b(t *testing.B) { benchmarkRefHasher(4096/8, t) } -func BenchmarkRefHasher_256b(t *testing.B) { benchmarkRefHasher(4096/16, t) } -func BenchmarkRefHasher_128b(t *testing.B) { benchmarkRefHasher(4096/32, t) } - -func BenchmarkHasher_4k(t *testing.B) { benchmarkHasher(4096, t) } -func BenchmarkHasher_2k(t *testing.B) { benchmarkHasher(4096/2, t) } -func BenchmarkHasher_1k(t *testing.B) { benchmarkHasher(4096/4, t) } -func BenchmarkHasher_512b(t *testing.B) { benchmarkHasher(4096/8, t) } -func BenchmarkHasher_256b(t *testing.B) { benchmarkHasher(4096/16, t) } -func BenchmarkHasher_128b(t *testing.B) { benchmarkHasher(4096/32, t) } - -func BenchmarkHasherNoReuse_4k(t *testing.B) { benchmarkHasherReuse(1, 4096, t) } -func BenchmarkHasherNoReuse_2k(t *testing.B) { benchmarkHasherReuse(1, 4096/2, t) } -func BenchmarkHasherNoReuse_1k(t *testing.B) { benchmarkHasherReuse(1, 4096/4, t) } -func BenchmarkHasherNoReuse_512b(t *testing.B) { benchmarkHasherReuse(1, 4096/8, t) } -func BenchmarkHasherNoReuse_256b(t *testing.B) { benchmarkHasherReuse(1, 4096/16, t) } -func BenchmarkHasherNoReuse_128b(t *testing.B) { benchmarkHasherReuse(1, 4096/32, t) } - -func BenchmarkHasherReuse_4k(t *testing.B) { benchmarkHasherReuse(16, 4096, t) } -func BenchmarkHasherReuse_2k(t *testing.B) { benchmarkHasherReuse(16, 4096/2, t) } -func BenchmarkHasherReuse_1k(t *testing.B) { benchmarkHasherReuse(16, 4096/4, t) } -func BenchmarkHasherReuse_512b(t *testing.B) { benchmarkHasherReuse(16, 4096/8, t) } -func BenchmarkHasherReuse_256b(t *testing.B) { benchmarkHasherReuse(16, 4096/16, t) } -func BenchmarkHasherReuse_128b(t *testing.B) { benchmarkHasherReuse(16, 4096/32, t) } - -// benchmarks the minimum hashing time for a balanced (for simplicity) BMT -// by doing count/segmentsize parallel hashings of 2*segmentsize bytes -// doing it on n maxproccnt each reusing the base hasher -// the premise is that this is the minimum computation needed for a BMT -// therefore this serves as a theoretical optimum for concurrent implementations -func benchmarkBMTBaseline(n int, t *testing.B) { - tdata := testDataReader(64) - data := make([]byte, 64) - tdata.Read(data) - hasher := sha3.NewKeccak256 - - t.ReportAllocs() - t.ResetTimer() - for i := 0; i < t.N; i++ { - count := int32((n-1)/hasher().Size() + 1) - wg := sync.WaitGroup{} - wg.Add(maxproccnt) - var i int32 - for j := 0; j < maxproccnt; j++ { - go func() { - defer wg.Done() - h := hasher() - for atomic.AddInt32(&i, 1) < count { - h.Reset() - h.Write(data) - h.Sum(nil) - } - }() - } - wg.Wait() - } -} - -func benchmarkHasher(n int, t *testing.B) { - tdata := testDataReader(n) - data := make([]byte, n) - tdata.Read(data) - - size := 1 - hasher := sha3.NewKeccak256 - segmentCount := 128 - pool := NewTreePool(hasher, segmentCount, size) - bmt := New(pool) - - t.ReportAllocs() - t.ResetTimer() - for i := 0; i < t.N; i++ { - bmt.Reset() - bmt.Write(data) - bmt.Sum(nil) - } -} - -func benchmarkHasherReuse(poolsize, n int, t *testing.B) { - tdata := testDataReader(n) - data := make([]byte, n) - tdata.Read(data) - - hasher := sha3.NewKeccak256 - segmentCount := 128 - pool := NewTreePool(hasher, segmentCount, poolsize) - cycles := 200 - - t.ReportAllocs() - t.ResetTimer() - for i := 0; i < t.N; i++ { - wg := sync.WaitGroup{} - wg.Add(cycles) - for j := 0; j < cycles; j++ { - bmt := New(pool) - go func() { - defer wg.Done() - bmt.Reset() - bmt.Write(data) - bmt.Sum(nil) - }() - } - wg.Wait() - } -} - -func benchmarkSHA3(n int, t *testing.B) { - data := make([]byte, n) - tdata := testDataReader(n) - tdata.Read(data) - hasher := sha3.NewKeccak256 - h := hasher() - - t.ReportAllocs() - t.ResetTimer() - for i := 0; i < t.N; i++ { - h.Reset() - h.Write(data) - h.Sum(nil) - } -} - -func benchmarkRefHasher(n int, t *testing.B) { - data := make([]byte, n) - tdata := testDataReader(n) - tdata.Read(data) - hasher := sha3.NewKeccak256 - rbmt := NewRefHasher(hasher, 128) - - t.ReportAllocs() - t.ResetTimer() - for i := 0; i < t.N; i++ { - rbmt.Hash(data) - } -} diff --git a/build/ci.go b/build/ci.go index 2998cfe18e..e542e011a4 100644 --- a/build/ci.go +++ b/build/ci.go @@ -26,8 +26,14 @@ Available commands are: install [ -arch architecture ] [ -cc compiler ] [ packages... ] -- builds packages and executables test [ -coverage ] [ packages... ] -- runs the tests lint -- runs certain pre-selected linters + archive [ -arch architecture ] [ -type zip|tar ] [ -signer key-envvar ] [ -upload dest ] -- archives build artifacts importkeys -- imports signing keys from env + debsrc [ -signer key-id ] [ -upload dest ] -- creates a debian source package + nsis -- creates a Windows NSIS installer + aar [ -local ] [ -sign key-id ] [-deploy repo] [ -upload dest ] -- creates an Android archive + xcode [ -local ] [ -sign key-id ] [-deploy repo] [ -upload dest ] -- creates an iOS XCode framework xgo [ -alltools ] [ options ] -- cross builds according to options + purge [ -store blobstore ] [ -days threshold ] -- purges old archives from the blobstore For all commands, -n prevents execution of external programs (dry run mode). @@ -35,6 +41,9 @@ For all commands, -n prevents execution of external programs (dry run mode). package main import ( + "bufio" + "bytes" + "encoding/base64" "flag" "fmt" "go/parser" @@ -44,25 +53,107 @@ import ( "os" "os/exec" "path/filepath" + "regexp" "runtime" "strings" + "time" "github.com/ethereum/go-ethereum/internal/build" + "github.com/ethereum/go-ethereum/params" + sv "github.com/ethereum/go-ethereum/swarm/version" ) var ( - // Files that end up in the geth-alltools*.zip archive. + // Files that end up in the XDC*.zip archive. + XDCArchiveFiles = []string{ + "COPYING", + executablePath("XDC"), + } + + // Files that end up in the XDC-alltools*.zip archive. allToolsArchiveFiles = []string{ "COPYING", executablePath("abigen"), executablePath("bootnode"), executablePath("evm"), - executablePath("geth"), + executablePath("XDC"), executablePath("puppeth"), executablePath("rlpdump"), - executablePath("swarm"), executablePath("wnode"), } + + // Files that end up in the swarm*.zip archive. + swarmArchiveFiles = []string{ + "COPYING", + executablePath("swarm"), + } + + // A debian package is created for all executables listed here. + debExecutables = []debExecutable{ + { + BinaryName: "abigen", + Description: "Source code generator to convert Ethereum contract definitions into easy to use, compile-time type-safe Go packages.", + }, + { + BinaryName: "bootnode", + Description: "Ethereum bootnode.", + }, + { + BinaryName: "evm", + Description: "Developer utility version of the EVM (Ethereum Virtual Machine) that is capable of running bytecode snippets within a configurable environment and execution mode.", + }, + { + BinaryName: "XDC", + Description: "Ethereum CLI client.", + }, + { + BinaryName: "puppeth", + Description: "Ethereum private network manager.", + }, + { + BinaryName: "rlpdump", + Description: "Developer utility tool that prints RLP structures.", + }, + { + BinaryName: "wnode", + Description: "Ethereum Whisper diagnostic tool", + }, + } + + // A debian package is created for all executables listed here. + debSwarmExecutables = []debExecutable{ + { + BinaryName: "swarm", + PackageName: "ethereum-swarm", + Description: "Ethereum Swarm daemon and tools", + }, + } + + debEthereum = debPackage{ + Name: "ethereum", + Version: params.Version, + Executables: debExecutables, + } + + debSwarm = debPackage{ + Name: "ethereum-swarm", + Version: sv.Version, + Executables: debSwarmExecutables, + } + + // Debian meta packages to build and push to Ubuntu PPA + debPackages = []debPackage{ + debSwarm, + debEthereum, + } + + // Distros for which packages are created. + // Note: vivid is unsupported because there is no golang-1.6 package for it. + // Note: wily is unsupported because it was officially deprecated on lanchpad. + // Note: yakkety is unsupported because it was officially deprecated on lanchpad. + // Note: zesty is unsupported because it was officially deprecated on lanchpad. + // Note: artful is unsupported because it was officially deprecated on lanchpad. + debDistros = []string{"trusty", "xenial", "bionic", "cosmic"} ) var GOBIN, _ = filepath.Abs(filepath.Join("build", "bin")) @@ -90,8 +181,20 @@ func main() { doTest(os.Args[2:]) case "lint": doLint(os.Args[2:]) + case "archive": + doArchive(os.Args[2:]) + case "debsrc": + doDebianSource(os.Args[2:]) + case "nsis": + doWindowsInstaller(os.Args[2:]) + case "aar": + doAndroidArchive(os.Args[2:]) + case "xcode": + doXCodeFramework(os.Args[2:]) case "xgo": doXgo(os.Args[2:]) + case "purge": + doPurge(os.Args[2:]) default: log.Fatal("unknown command ", os.Args[1]) } @@ -116,7 +219,7 @@ func doInstall(cmdline []string) { if minor < 9 { log.Println("You have Go version", runtime.Version()) - log.Println("XDC requires at least Go version 1.9 and cannot") + log.Println("go-ethereum requires at least Go version 1.9 and cannot") log.Println("be compiled with an earlier version. Please upgrade your Go installation.") os.Exit(1) } @@ -254,10 +357,14 @@ func doLint(cmdline []string) { build.MustRun(goTool("get", "gopkg.in/alecthomas/gometalinter.v2")) build.MustRunCommand(filepath.Join(GOBIN, "gometalinter.v2"), "--install") - // Run fast linters batched together + // Run fast linters batched toXDCer configs := []string{ "--vendor", + "--tests", + "--deadline=2m", "--disable-all", + "--enable=goimports", + "--enable=varcheck", "--enable=vet", "--enable=gofmt", "--enable=misspell", @@ -268,11 +375,622 @@ func doLint(cmdline []string) { // Run slow linters one by one for _, linter := range []string{"unconvert", "gosimple"} { - configs = []string{"--vendor", "--deadline=10m", "--disable-all", "--enable=" + linter} + configs = []string{"--vendor", "--tests", "--deadline=10m", "--disable-all", "--enable=" + linter} build.MustRunCommand(filepath.Join(GOBIN, "gometalinter.v2"), append(configs, packages...)...) } } +// Release Packaging +func doArchive(cmdline []string) { + var ( + arch = flag.String("arch", runtime.GOARCH, "Architecture cross packaging") + atype = flag.String("type", "zip", "Type of archive to write (zip|tar)") + signer = flag.String("signer", "", `Environment variable holding the signing key (e.g. LINUX_SIGNING_KEY)`) + upload = flag.String("upload", "", `Destination to upload the archives (usually "XDCstore/builds")`) + ext string + ) + flag.CommandLine.Parse(cmdline) + switch *atype { + case "zip": + ext = ".zip" + case "tar": + ext = ".tar.gz" + default: + log.Fatal("unknown archive type: ", atype) + } + + var ( + env = build.Env() + + baseXDC = archiveBasename(*arch, params.ArchiveVersion(env.Commit)) + XDC = "XDC-" + baseXDC + ext + alltools = "XDC-alltools-" + baseXDC + ext + + baseswarm = archiveBasename(*arch, sv.ArchiveVersion(env.Commit)) + swarm = "swarm-" + baseswarm + ext + ) + maybeSkipArchive(env) + if err := build.WriteArchive(XDC, XDCArchiveFiles); err != nil { + log.Fatal(err) + } + if err := build.WriteArchive(alltools, allToolsArchiveFiles); err != nil { + log.Fatal(err) + } + if err := build.WriteArchive(swarm, swarmArchiveFiles); err != nil { + log.Fatal(err) + } + for _, archive := range []string{XDC, alltools, swarm} { + if err := archiveUpload(archive, *upload, *signer); err != nil { + log.Fatal(err) + } + } +} + +func archiveBasename(arch string, archiveVersion string) string { + platform := runtime.GOOS + "-" + arch + if arch == "arm" { + platform += os.Getenv("GOARM") + } + if arch == "android" { + platform = "android-all" + } + if arch == "ios" { + platform = "ios-all" + } + return platform + "-" + archiveVersion +} + +func archiveUpload(archive string, blobstore string, signer string) error { + // If signing was requested, generate the signature files + if signer != "" { + pgpkey, err := base64.StdEncoding.DecodeString(os.Getenv(signer)) + if err != nil { + return fmt.Errorf("invalid base64 %s", signer) + } + if err := build.PGPSignFile(archive, archive+".asc", string(pgpkey)); err != nil { + return err + } + } + // If uploading to Azure was requested, push the archive possibly with its signature + if blobstore != "" { + auth := build.AzureBlobstoreConfig{ + Account: strings.Split(blobstore, "/")[0], + Token: os.Getenv("AZURE_BLOBSTORE_TOKEN"), + Container: strings.SplitN(blobstore, "/", 2)[1], + } + if err := build.AzureBlobstoreUpload(archive, filepath.Base(archive), auth); err != nil { + return err + } + if signer != "" { + if err := build.AzureBlobstoreUpload(archive+".asc", filepath.Base(archive+".asc"), auth); err != nil { + return err + } + } + } + return nil +} + +// skips archiving for some build configurations. +func maybeSkipArchive(env build.Environment) { + if env.IsPullRequest { + log.Printf("skipping because this is a PR build") + os.Exit(0) + } + if env.IsCronJob { + log.Printf("skipping because this is a cron job") + os.Exit(0) + } + if env.Branch != "master" && !strings.HasPrefix(env.Tag, "v1.") { + log.Printf("skipping because branch %q, tag %q is not on the whitelist", env.Branch, env.Tag) + os.Exit(0) + } +} + +// Debian Packaging +func doDebianSource(cmdline []string) { + var ( + signer = flag.String("signer", "", `Signing key name, also used as package author`) + upload = flag.String("upload", "", `Where to upload the source package (usually "ppa:ethereum/ethereum")`) + workdir = flag.String("workdir", "", `Output directory for packages (uses temp dir if unset)`) + now = time.Now() + ) + flag.CommandLine.Parse(cmdline) + *workdir = makeWorkdir(*workdir) + env := build.Env() + maybeSkipArchive(env) + + // Import the signing key. + if b64key := os.Getenv("PPA_SIGNING_KEY"); b64key != "" { + key, err := base64.StdEncoding.DecodeString(b64key) + if err != nil { + log.Fatal("invalid base64 PPA_SIGNING_KEY") + } + gpg := exec.Command("gpg", "--import") + gpg.Stdin = bytes.NewReader(key) + build.MustRun(gpg) + } + + // Create Debian packages and upload them + for _, pkg := range debPackages { + for _, distro := range debDistros { + meta := newDebMetadata(distro, *signer, env, now, pkg.Name, pkg.Version, pkg.Executables) + pkgdir := stageDebianSource(*workdir, meta) + debuild := exec.Command("debuild", "-S", "-sa", "-us", "-uc") + debuild.Dir = pkgdir + build.MustRun(debuild) + + changes := fmt.Sprintf("%s_%s_source.changes", meta.Name(), meta.VersionString()) + changes = filepath.Join(*workdir, changes) + if *signer != "" { + build.MustRunCommand("debsign", changes) + } + if *upload != "" { + build.MustRunCommand("dput", *upload, changes) + } + } + } +} + +func makeWorkdir(wdflag string) string { + var err error + if wdflag != "" { + err = os.MkdirAll(wdflag, 0744) + } else { + wdflag, err = ioutil.TempDir("", "XDC-build-") + } + if err != nil { + log.Fatal(err) + } + return wdflag +} + +func isUnstableBuild(env build.Environment) bool { + if env.Tag != "" { + return false + } + return true +} + +type debPackage struct { + Name string // the name of the Debian package to produce, e.g. "ethereum", or "ethereum-swarm" + Version string // the clean version of the debPackage, e.g. 1.8.12 or 0.3.0, without any metadata + Executables []debExecutable // executables to be included in the package +} + +type debMetadata struct { + Env build.Environment + + PackageName string + + // go-ethereum version being built. Note that this + // is not the debian package version. The package version + // is constructed by VersionString. + Version string + + Author string // "name ", also selects signing key + Distro, Time string + Executables []debExecutable +} + +type debExecutable struct { + PackageName string + BinaryName string + Description string +} + +// Package returns the name of the package if present, or +// fallbacks to BinaryName +func (d debExecutable) Package() string { + if d.PackageName != "" { + return d.PackageName + } + return d.BinaryName +} + +func newDebMetadata(distro, author string, env build.Environment, t time.Time, name string, version string, exes []debExecutable) debMetadata { + if author == "" { + // No signing key, use default author. + author = "Ethereum Builds " + } + return debMetadata{ + PackageName: name, + Env: env, + Author: author, + Distro: distro, + Version: version, + Time: t.Format(time.RFC1123Z), + Executables: exes, + } +} + +// Name returns the name of the metapackage that depends +// on all executable packages. +func (meta debMetadata) Name() string { + if isUnstableBuild(meta.Env) { + return meta.PackageName + "-unstable" + } + return meta.PackageName +} + +// VersionString returns the debian version of the packages. +func (meta debMetadata) VersionString() string { + vsn := meta.Version + if meta.Env.Buildnum != "" { + vsn += "+build" + meta.Env.Buildnum + } + if meta.Distro != "" { + vsn += "+" + meta.Distro + } + return vsn +} + +// ExeList returns the list of all executable packages. +func (meta debMetadata) ExeList() string { + names := make([]string, len(meta.Executables)) + for i, e := range meta.Executables { + names[i] = meta.ExeName(e) + } + return strings.Join(names, ", ") +} + +// ExeName returns the package name of an executable package. +func (meta debMetadata) ExeName(exe debExecutable) string { + if isUnstableBuild(meta.Env) { + return exe.Package() + "-unstable" + } + return exe.Package() +} + +// EthereumSwarmPackageName returns the name of the swarm package based on +// environment, e.g. "ethereum-swarm-unstable", or "ethereum-swarm". +// This is needed so that we make sure that "ethereum" package, +// depends on and installs "ethereum-swarm" +func (meta debMetadata) EthereumSwarmPackageName() string { + if isUnstableBuild(meta.Env) { + return debSwarm.Name + "-unstable" + } + return debSwarm.Name +} + +// ExeConflicts returns the content of the Conflicts field +// for executable packages. +func (meta debMetadata) ExeConflicts(exe debExecutable) string { + if isUnstableBuild(meta.Env) { + // Set up the conflicts list so that the *-unstable packages + // cannot be installed alongside the regular version. + // + // https://www.debian.org/doc/debian-policy/ch-relationships.html + // is very explicit about Conflicts: and says that Breaks: should + // be preferred and the conflicting files should be handled via + // alternates. We might do this eventually but using a conflict is + // easier now. + return "ethereum, " + exe.Package() + } + return "" +} + +func stageDebianSource(tmpdir string, meta debMetadata) (pkgdir string) { + pkg := meta.Name() + "-" + meta.VersionString() + pkgdir = filepath.Join(tmpdir, pkg) + if err := os.Mkdir(pkgdir, 0755); err != nil { + log.Fatal(err) + } + + // Copy the source code. + build.MustRunCommand("git", "checkout-index", "-a", "--prefix", pkgdir+string(filepath.Separator)) + + // Put the debian build files in place. + debian := filepath.Join(pkgdir, "debian") + build.Render("build/deb/"+meta.PackageName+"/deb.rules", filepath.Join(debian, "rules"), 0755, meta) + build.Render("build/deb/"+meta.PackageName+"/deb.changelog", filepath.Join(debian, "changelog"), 0644, meta) + build.Render("build/deb/"+meta.PackageName+"/deb.control", filepath.Join(debian, "control"), 0644, meta) + build.Render("build/deb/"+meta.PackageName+"/deb.copyright", filepath.Join(debian, "copyright"), 0644, meta) + build.RenderString("8\n", filepath.Join(debian, "compat"), 0644, meta) + build.RenderString("3.0 (native)\n", filepath.Join(debian, "source/format"), 0644, meta) + for _, exe := range meta.Executables { + install := filepath.Join(debian, meta.ExeName(exe)+".install") + docs := filepath.Join(debian, meta.ExeName(exe)+".docs") + build.Render("build/deb/"+meta.PackageName+"/deb.install", install, 0644, exe) + build.Render("build/deb/"+meta.PackageName+"/deb.docs", docs, 0644, exe) + } + + return pkgdir +} + +// Windows installer +func doWindowsInstaller(cmdline []string) { + // Parse the flags and make skip installer generation on PRs + var ( + arch = flag.String("arch", runtime.GOARCH, "Architecture for cross build packaging") + signer = flag.String("signer", "", `Environment variable holding the signing key (e.g. WINDOWS_SIGNING_KEY)`) + upload = flag.String("upload", "", `Destination to upload the archives (usually "XDCstore/builds")`) + workdir = flag.String("workdir", "", `Output directory for packages (uses temp dir if unset)`) + ) + flag.CommandLine.Parse(cmdline) + *workdir = makeWorkdir(*workdir) + env := build.Env() + maybeSkipArchive(env) + + // Aggregate binaries that are included in the installer + var ( + devTools []string + allTools []string + XDCTool string + ) + for _, file := range allToolsArchiveFiles { + if file == "COPYING" { // license, copied later + continue + } + allTools = append(allTools, filepath.Base(file)) + if filepath.Base(file) == "XDC.exe" { + XDCTool = file + } else { + devTools = append(devTools, file) + } + } + + // Render NSIS scripts: Installer NSIS contains two installer sections, + // first section contains the XDC binary, second section holds the dev tools. + templateData := map[string]interface{}{ + "License": "COPYING", + "XDC": XDCTool, + "DevTools": devTools, + } + build.Render("build/nsis.XDC.nsi", filepath.Join(*workdir, "XDC.nsi"), 0644, nil) + build.Render("build/nsis.install.nsh", filepath.Join(*workdir, "install.nsh"), 0644, templateData) + build.Render("build/nsis.uninstall.nsh", filepath.Join(*workdir, "uninstall.nsh"), 0644, allTools) + build.Render("build/nsis.pathupdate.nsh", filepath.Join(*workdir, "PathUpdate.nsh"), 0644, nil) + build.Render("build/nsis.envvarupdate.nsh", filepath.Join(*workdir, "EnvVarUpdate.nsh"), 0644, nil) + build.CopyFile(filepath.Join(*workdir, "SimpleFC.dll"), "build/nsis.simplefc.dll", 0755) + build.CopyFile(filepath.Join(*workdir, "COPYING"), "COPYING", 0755) + + // Build the installer. This assumes that all the needed files have been previously + // built (don't mix building and packaging to keep cross compilation complexity to a + // minimum). + version := strings.Split(params.Version, ".") + if env.Commit != "" { + version[2] += "-" + env.Commit[:8] + } + installer, _ := filepath.Abs("XDC-" + archiveBasename(*arch, params.ArchiveVersion(env.Commit)) + ".exe") + build.MustRunCommand("makensis.exe", + "/DOUTPUTFILE="+installer, + "/DMAJORVERSION="+version[0], + "/DMINORVERSION="+version[1], + "/DBUILDVERSION="+version[2], + "/DARCH="+*arch, + filepath.Join(*workdir, "XDC.nsi"), + ) + + // Sign and publish installer. + if err := archiveUpload(installer, *upload, *signer); err != nil { + log.Fatal(err) + } +} + +// Android archives + +func doAndroidArchive(cmdline []string) { + var ( + local = flag.Bool("local", false, `Flag whether we're only doing a local build (skip Maven artifacts)`) + signer = flag.String("signer", "", `Environment variable holding the signing key (e.g. ANDROID_SIGNING_KEY)`) + deploy = flag.String("deploy", "", `Destination to deploy the archive (usually "https://oss.sonatype.org")`) + upload = flag.String("upload", "", `Destination to upload the archive (usually "XDCstore/builds")`) + ) + flag.CommandLine.Parse(cmdline) + env := build.Env() + + // Sanity check that the SDK and NDK are installed and set + if os.Getenv("ANDROID_HOME") == "" { + log.Fatal("Please ensure ANDROID_HOME points to your Android SDK") + } + if os.Getenv("ANDROID_NDK") == "" { + log.Fatal("Please ensure ANDROID_NDK points to your Android NDK") + } + // Build the Android archive and Maven resources + build.MustRun(goTool("get", "golang.org/x/mobile/cmd/gomobile", "golang.org/x/mobile/cmd/gobind")) + build.MustRun(gomobileTool("init", "--ndk", os.Getenv("ANDROID_NDK"))) + build.MustRun(gomobileTool("bind", "-ldflags", "-s -w", "--target", "android", "--javapkg", "org.ethereum", "-v", "github.com/ethereum/go-ethereum/mobile")) + + if *local { + // If we're building locally, copy bundle to build dir and skip Maven + os.Rename("XDC.aar", filepath.Join(GOBIN, "XDC.aar")) + return + } + meta := newMavenMetadata(env) + build.Render("build/mvn.pom", meta.Package+".pom", 0755, meta) + + // Skip Maven deploy and Azure upload for PR builds + maybeSkipArchive(env) + + // Sign and upload the archive to Azure + archive := "XDC-" + archiveBasename("android", params.ArchiveVersion(env.Commit)) + ".aar" + os.Rename("XDC.aar", archive) + + if err := archiveUpload(archive, *upload, *signer); err != nil { + log.Fatal(err) + } + // Sign and upload all the artifacts to Maven Central + os.Rename(archive, meta.Package+".aar") + if *signer != "" && *deploy != "" { + // Import the signing key into the local GPG instance + b64key := os.Getenv(*signer) + key, err := base64.StdEncoding.DecodeString(b64key) + if err != nil { + log.Fatalf("invalid base64 %s", *signer) + } + gpg := exec.Command("gpg", "--import") + gpg.Stdin = bytes.NewReader(key) + build.MustRun(gpg) + + keyID, err := build.PGPKeyID(string(key)) + if err != nil { + log.Fatal(err) + } + // Upload the artifacts to Sonatype and/or Maven Central + repo := *deploy + "/service/local/staging/deploy/maven2" + if meta.Develop { + repo = *deploy + "/content/repositories/snapshots" + } + build.MustRunCommand("mvn", "gpg:sign-and-deploy-file", "-e", "-X", + "-settings=build/mvn.settings", "-Durl="+repo, "-DrepositoryId=ossrh", + "-Dgpg.keyname="+keyID, + "-DpomFile="+meta.Package+".pom", "-Dfile="+meta.Package+".aar") + } +} + +func gomobileTool(subcmd string, args ...string) *exec.Cmd { + cmd := exec.Command(filepath.Join(GOBIN, "gomobile"), subcmd) + cmd.Args = append(cmd.Args, args...) + cmd.Env = []string{ + "GOPATH=" + build.GOPATH(), + "PATH=" + GOBIN + string(os.PathListSeparator) + os.Getenv("PATH"), + } + for _, e := range os.Environ() { + if strings.HasPrefix(e, "GOPATH=") || strings.HasPrefix(e, "PATH=") { + continue + } + cmd.Env = append(cmd.Env, e) + } + return cmd +} + +type mavenMetadata struct { + Version string + Package string + Develop bool + Contributors []mavenContributor +} + +type mavenContributor struct { + Name string + Email string +} + +func newMavenMetadata(env build.Environment) mavenMetadata { + // Collect the list of authors from the repo root + contribs := []mavenContributor{} + if authors, err := os.Open("AUTHORS"); err == nil { + defer authors.Close() + + scanner := bufio.NewScanner(authors) + for scanner.Scan() { + // Skip any whitespace from the authors list + line := strings.TrimSpace(scanner.Text()) + if line == "" || line[0] == '#' { + continue + } + // Split the author and insert as a contributor + re := regexp.MustCompile("([^<]+) <(.+)>") + parts := re.FindStringSubmatch(line) + if len(parts) == 3 { + contribs = append(contribs, mavenContributor{Name: parts[1], Email: parts[2]}) + } + } + } + // Render the version and package strings + version := params.Version + if isUnstableBuild(env) { + version += "-SNAPSHOT" + } + return mavenMetadata{ + Version: version, + Package: "XDC-" + version, + Develop: isUnstableBuild(env), + Contributors: contribs, + } +} + +// XCode frameworks + +func doXCodeFramework(cmdline []string) { + var ( + local = flag.Bool("local", false, `Flag whether we're only doing a local build (skip Maven artifacts)`) + signer = flag.String("signer", "", `Environment variable holding the signing key (e.g. IOS_SIGNING_KEY)`) + deploy = flag.String("deploy", "", `Destination to deploy the archive (usually "trunk")`) + upload = flag.String("upload", "", `Destination to upload the archives (usually "XDCstore/builds")`) + ) + flag.CommandLine.Parse(cmdline) + env := build.Env() + + // Build the iOS XCode framework + build.MustRun(goTool("get", "golang.org/x/mobile/cmd/gomobile", "golang.org/x/mobile/cmd/gobind")) + build.MustRun(gomobileTool("init")) + bind := gomobileTool("bind", "-ldflags", "-s -w", "--target", "ios", "--tags", "ios", "-v", "github.com/ethereum/go-ethereum/mobile") + + if *local { + // If we're building locally, use the build folder and stop afterwards + bind.Dir, _ = filepath.Abs(GOBIN) + build.MustRun(bind) + return + } + archive := "XDC-" + archiveBasename("ios", params.ArchiveVersion(env.Commit)) + if err := os.Mkdir(archive, os.ModePerm); err != nil { + log.Fatal(err) + } + bind.Dir, _ = filepath.Abs(archive) + build.MustRun(bind) + build.MustRunCommand("tar", "-zcvf", archive+".tar.gz", archive) + + // Skip CocoaPods deploy and Azure upload for PR builds + maybeSkipArchive(env) + + // Sign and upload the framework to Azure + if err := archiveUpload(archive+".tar.gz", *upload, *signer); err != nil { + log.Fatal(err) + } + // Prepare and upload a PodSpec to CocoaPods + if *deploy != "" { + meta := newPodMetadata(env, archive) + build.Render("build/pod.podspec", "XDC.podspec", 0755, meta) + build.MustRunCommand("pod", *deploy, "push", "XDC.podspec", "--allow-warnings", "--verbose") + } +} + +type podMetadata struct { + Version string + Commit string + Archive string + Contributors []podContributor +} + +type podContributor struct { + Name string + Email string +} + +func newPodMetadata(env build.Environment, archive string) podMetadata { + // Collect the list of authors from the repo root + contribs := []podContributor{} + if authors, err := os.Open("AUTHORS"); err == nil { + defer authors.Close() + + scanner := bufio.NewScanner(authors) + for scanner.Scan() { + // Skip any whitespace from the authors list + line := strings.TrimSpace(scanner.Text()) + if line == "" || line[0] == '#' { + continue + } + // Split the author and insert as a contributor + re := regexp.MustCompile("([^<]+) <(.+)>") + parts := re.FindStringSubmatch(line) + if len(parts) == 3 { + contribs = append(contribs, podContributor{Name: parts[1], Email: parts[2]}) + } + } + } + version := params.Version + if isUnstableBuild(env) { + version += "-unstable." + env.Buildnum + } + return podMetadata{ + Archive: archive, + Version: version, + Commit: env.Commit, + Contributors: contribs, + } +} + // Cross compilation func doXgo(cmdline []string) { @@ -324,3 +1042,53 @@ func xgoTool(args []string) *exec.Cmd { } return cmd } + +// Binary distribution cleanups + +func doPurge(cmdline []string) { + var ( + store = flag.String("store", "", `Destination from where to purge archives (usually "XDCstore/builds")`) + limit = flag.Int("days", 30, `Age threshold above which to delete unstalbe archives`) + ) + flag.CommandLine.Parse(cmdline) + + if env := build.Env(); !env.IsCronJob { + log.Printf("skipping because not a cron job") + os.Exit(0) + } + // Create the azure authentication and list the current archives + auth := build.AzureBlobstoreConfig{ + Account: strings.Split(*store, "/")[0], + Token: os.Getenv("AZURE_BLOBSTORE_TOKEN"), + Container: strings.SplitN(*store, "/", 2)[1], + } + blobs, err := build.AzureBlobstoreList(auth) + if err != nil { + log.Fatal(err) + } + // Iterate over the blobs, collect and sort all unstable builds + for i := 0; i < len(blobs); i++ { + if !strings.Contains(blobs[i].Name, "unstable") { + blobs = append(blobs[:i], blobs[i+1:]...) + i-- + } + } + for i := 0; i < len(blobs); i++ { + for j := i + 1; j < len(blobs); j++ { + if blobs[i].Properties.LastModified.After(blobs[j].Properties.LastModified) { + blobs[i], blobs[j] = blobs[j], blobs[i] + } + } + } + // Filter out all archives more recent that the given threshold + for i, blob := range blobs { + if time.Since(blob.Properties.LastModified) < time.Duration(*limit)*24*time.Hour { + blobs = blobs[:i] + break + } + } + // Delete all marked as such and return + if err := build.AzureBlobstoreDelete(auth, blobs); err != nil { + log.Fatal(err) + } +} diff --git a/build/clean_go_build_cache.sh b/build/clean_go_build_cache.sh new file mode 100755 index 0000000000..1666381d98 --- /dev/null +++ b/build/clean_go_build_cache.sh @@ -0,0 +1,19 @@ +#!/bin/sh + +# Cleaning the Go cache only makes sense if we actually have Go installed... or +# if Go is actually callable. This does not hold true during deb packaging, so +# we need an explicit check to avoid build failures. +if ! command -v go > /dev/null; then + exit +fi + +version_gt() { + test "$(printf '%s\n' "$@" | sort -V | head -n 1)" != "$1" +} + +golang_version=$(go version |cut -d' ' -f3 |sed 's/go//') + +# Clean go build cache when go version is greater than or equal to 1.10 +if !(version_gt 1.10 $golang_version); then + go clean -cache +fi diff --git a/build/deb/ethereum-swarm/deb.changelog b/build/deb/ethereum-swarm/deb.changelog new file mode 100644 index 0000000000..83f804a833 --- /dev/null +++ b/build/deb/ethereum-swarm/deb.changelog @@ -0,0 +1,5 @@ +{{.Name}} ({{.VersionString}}) {{.Distro}}; urgency=low + + * git build of {{.Env.Commit}} + + -- {{.Author}} {{.Time}} diff --git a/build/deb/ethereum-swarm/deb.control b/build/deb/ethereum-swarm/deb.control new file mode 100644 index 0000000000..8cd325bf55 --- /dev/null +++ b/build/deb/ethereum-swarm/deb.control @@ -0,0 +1,19 @@ +Source: {{.Name}} +Section: science +Priority: extra +Maintainer: {{.Author}} +Build-Depends: debhelper (>= 8.0.0), golang-1.10 +Standards-Version: 3.9.5 +Homepage: https://ethereum.org +Vcs-Git: git://github.com/ethereum/go-ethereum.git +Vcs-Browser: https://github.com/ethereum/go-ethereum + +{{range .Executables}} +Package: {{$.ExeName .}} +Conflicts: {{$.ExeConflicts .}} +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends} +Built-Using: ${misc:Built-Using} +Description: {{.Description}} + {{.Description}} +{{end}} diff --git a/build/deb/ethereum-swarm/deb.copyright b/build/deb/ethereum-swarm/deb.copyright new file mode 100644 index 0000000000..fe6e36ad9d --- /dev/null +++ b/build/deb/ethereum-swarm/deb.copyright @@ -0,0 +1,14 @@ +Copyright 2018 The go-ethereum Authors + +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 . diff --git a/build/deb/ethereum-swarm/deb.docs b/build/deb/ethereum-swarm/deb.docs new file mode 100644 index 0000000000..62deb04972 --- /dev/null +++ b/build/deb/ethereum-swarm/deb.docs @@ -0,0 +1 @@ +AUTHORS diff --git a/build/deb/ethereum-swarm/deb.install b/build/deb/ethereum-swarm/deb.install new file mode 100644 index 0000000000..e7666ce5fb --- /dev/null +++ b/build/deb/ethereum-swarm/deb.install @@ -0,0 +1 @@ +build/bin/{{.BinaryName}} usr/bin diff --git a/build/deb/ethereum-swarm/deb.rules b/build/deb/ethereum-swarm/deb.rules new file mode 100644 index 0000000000..7f286569ea --- /dev/null +++ b/build/deb/ethereum-swarm/deb.rules @@ -0,0 +1,13 @@ +#!/usr/bin/make -f +# -*- makefile -*- + +# Uncomment this to turn on verbose mode. +#export DH_VERBOSE=1 + +override_dh_auto_build: + build/env.sh /usr/lib/go-1.10/bin/go run build/ci.go install -git-commit={{.Env.Commit}} -git-branch={{.Env.Branch}} -git-tag={{.Env.Tag}} -buildnum={{.Env.Buildnum}} -pull-request={{.Env.IsPullRequest}} + +override_dh_auto_test: + +%: + dh $@ diff --git a/build/deb/ethereum/deb.changelog b/build/deb/ethereum/deb.changelog new file mode 100644 index 0000000000..83f804a833 --- /dev/null +++ b/build/deb/ethereum/deb.changelog @@ -0,0 +1,5 @@ +{{.Name}} ({{.VersionString}}) {{.Distro}}; urgency=low + + * git build of {{.Env.Commit}} + + -- {{.Author}} {{.Time}} diff --git a/build/deb/ethereum/deb.control b/build/deb/ethereum/deb.control new file mode 100644 index 0000000000..e693d1d046 --- /dev/null +++ b/build/deb/ethereum/deb.control @@ -0,0 +1,25 @@ +Source: {{.Name}} +Section: science +Priority: extra +Maintainer: {{.Author}} +Build-Depends: debhelper (>= 8.0.0), golang-1.10 +Standards-Version: 3.9.5 +Homepage: https://ethereum.org +Vcs-Git: git://github.com/ethereum/go-ethereum.git +Vcs-Browser: https://github.com/ethereum/go-ethereum + +Package: {{.Name}} +Architecture: any +Depends: ${misc:Depends}, {{.EthereumSwarmPackageName}}, {{.ExeList}} +Description: Meta-package to install geth, swarm, and other tools + Meta-package to install geth, swarm and other tools + +{{range .Executables}} +Package: {{$.ExeName .}} +Conflicts: {{$.ExeConflicts .}} +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends} +Built-Using: ${misc:Built-Using} +Description: {{.Description}} + {{.Description}} +{{end}} diff --git a/build/deb/ethereum/deb.copyright b/build/deb/ethereum/deb.copyright new file mode 100644 index 0000000000..fe6e36ad9d --- /dev/null +++ b/build/deb/ethereum/deb.copyright @@ -0,0 +1,14 @@ +Copyright 2018 The go-ethereum Authors + +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 . diff --git a/build/deb/ethereum/deb.docs b/build/deb/ethereum/deb.docs new file mode 100644 index 0000000000..62deb04972 --- /dev/null +++ b/build/deb/ethereum/deb.docs @@ -0,0 +1 @@ +AUTHORS diff --git a/build/deb/ethereum/deb.install b/build/deb/ethereum/deb.install new file mode 100644 index 0000000000..e7666ce5fb --- /dev/null +++ b/build/deb/ethereum/deb.install @@ -0,0 +1 @@ +build/bin/{{.BinaryName}} usr/bin diff --git a/build/deb/ethereum/deb.rules b/build/deb/ethereum/deb.rules new file mode 100644 index 0000000000..7f286569ea --- /dev/null +++ b/build/deb/ethereum/deb.rules @@ -0,0 +1,13 @@ +#!/usr/bin/make -f +# -*- makefile -*- + +# Uncomment this to turn on verbose mode. +#export DH_VERBOSE=1 + +override_dh_auto_build: + build/env.sh /usr/lib/go-1.10/bin/go run build/ci.go install -git-commit={{.Env.Commit}} -git-branch={{.Env.Branch}} -git-tag={{.Env.Tag}} -buildnum={{.Env.Buildnum}} -pull-request={{.Env.IsPullRequest}} + +override_dh_auto_test: + +%: + dh $@ diff --git a/build/goimports.sh b/build/goimports.sh new file mode 100755 index 0000000000..1fcace6a4b --- /dev/null +++ b/build/goimports.sh @@ -0,0 +1,18 @@ +#!/bin/sh + +find_files() { + find . ! \( \ + \( \ + -path '.github' \ + -o -path './build/_workspace' \ + -o -path './build/bin' \ + -o -path './crypto/bn256' \ + -o -path '*/vendor/*' \ + \) -prune \ + \) -name '*.go' +} + +GOFMT="gofmt -s -w" +GOIMPORTS="goimports -w" +find_files | xargs $GOFMT +find_files | xargs $GOIMPORTS diff --git a/build/mvn.pom b/build/mvn.pom new file mode 100644 index 0000000000..7670246ba9 --- /dev/null +++ b/build/mvn.pom @@ -0,0 +1,57 @@ + + 4.0.0 + + org.ethereum + geth + {{.Version}} + aar + + Android Ethereum Client + Android port of the go-ethereum libraries and node + https://github.com/ethereum/go-ethereum + 2015 + + + + GNU Lesser General Public License, Version 3.0 + https://www.gnu.org/licenses/lgpl-3.0.en.html + repo + + + + + Ethereum + https://ethereum.org + + + + + karalabe + Péter Szilágyi + peterke@gmail.com + https://github.com/karalabe + + https://www.gravatar.com/avatar/2ecbf0f5b4b79eebf8c193e5d324357f?s=256 + + + + + {{range .Contributors}} + + {{.Name}} + {{.Email}} + {{end}} + + + + GitHub Issues + https://github.com/ethereum/go-ethereum/issues/ + + + + https://github.com/ethereum/go-ethereum + + diff --git a/build/mvn.settings b/build/mvn.settings new file mode 100644 index 0000000000..406b409b9b --- /dev/null +++ b/build/mvn.settings @@ -0,0 +1,24 @@ + + + + ossrh + ${env.ANDROID_SONATYPE_USERNAME} + ${env.ANDROID_SONATYPE_PASSWORD} + + + + + ossrh + + true + + + gpg + + + + + diff --git a/build/nsis.envvarupdate.nsh b/build/nsis.envvarupdate.nsh new file mode 100644 index 0000000000..9c3ecbe337 --- /dev/null +++ b/build/nsis.envvarupdate.nsh @@ -0,0 +1,327 @@ +/** + * EnvVarUpdate.nsh + * : Environmental Variables: append, prepend, and remove entries + * + * WARNING: If you use StrFunc.nsh header then include it before this file + * with all required definitions. This is to avoid conflicts + * + * Usage: + * ${EnvVarUpdate} "ResultVar" "EnvVarName" "Action" "RegLoc" "PathString" + * + * Credits: + * Version 1.0 + * * Cal Turney (turnec2) + * * Amir Szekely (KiCHiK) and e-circ for developing the forerunners of this + * function: AddToPath, un.RemoveFromPath, AddToEnvVar, un.RemoveFromEnvVar, + * WriteEnvStr, and un.DeleteEnvStr + * * Diego Pedroso (deguix) for StrTok + * * Kevin English (kenglish_hi) for StrContains + * * Hendri Adriaens (Smile2Me), Diego Pedroso (deguix), and Dan Fuhry + * (dandaman32) for StrReplace + * + * Version 1.1 (compatibility with StrFunc.nsh) + * * techtonik + * + * http://nsis.sourceforge.net/Environmental_Variables:_append%2C_prepend%2C_and_remove_entries + * + */ + + +!ifndef ENVVARUPDATE_FUNCTION +!define ENVVARUPDATE_FUNCTION +!verbose push +!verbose 3 +!include "LogicLib.nsh" +!include "WinMessages.NSH" +!include "StrFunc.nsh" + +; ---- Fix for conflict if StrFunc.nsh is already includes in main file ----------------------- +!macro _IncludeStrFunction StrFuncName + !ifndef ${StrFuncName}_INCLUDED + ${${StrFuncName}} + !endif + !ifndef Un${StrFuncName}_INCLUDED + ${Un${StrFuncName}} + !endif + !define un.${StrFuncName} "${Un${StrFuncName}}" +!macroend + +!insertmacro _IncludeStrFunction StrTok +!insertmacro _IncludeStrFunction StrStr +!insertmacro _IncludeStrFunction StrRep + +; ---------------------------------- Macro Definitions ---------------------------------------- +!macro _EnvVarUpdateConstructor ResultVar EnvVarName Action Regloc PathString + Push "${EnvVarName}" + Push "${Action}" + Push "${RegLoc}" + Push "${PathString}" + Call EnvVarUpdate + Pop "${ResultVar}" +!macroend +!define EnvVarUpdate '!insertmacro "_EnvVarUpdateConstructor"' + +!macro _unEnvVarUpdateConstructor ResultVar EnvVarName Action Regloc PathString + Push "${EnvVarName}" + Push "${Action}" + Push "${RegLoc}" + Push "${PathString}" + Call un.EnvVarUpdate + Pop "${ResultVar}" +!macroend +!define un.EnvVarUpdate '!insertmacro "_unEnvVarUpdateConstructor"' +; ---------------------------------- Macro Definitions end------------------------------------- + +;----------------------------------- EnvVarUpdate start---------------------------------------- +!define hklm_all_users 'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"' +!define hkcu_current_user 'HKCU "Environment"' + +!macro EnvVarUpdate UN + +Function ${UN}EnvVarUpdate + + Push $0 + Exch 4 + Exch $1 + Exch 3 + Exch $2 + Exch 2 + Exch $3 + Exch + Exch $4 + Push $5 + Push $6 + Push $7 + Push $8 + Push $9 + Push $R0 + + /* After this point: + ------------------------- + $0 = ResultVar (returned) + $1 = EnvVarName (input) + $2 = Action (input) + $3 = RegLoc (input) + $4 = PathString (input) + $5 = Orig EnvVar (read from registry) + $6 = Len of $0 (temp) + $7 = tempstr1 (temp) + $8 = Entry counter (temp) + $9 = tempstr2 (temp) + $R0 = tempChar (temp) */ + + ; Step 1: Read contents of EnvVarName from RegLoc + ; + ; Check for empty EnvVarName + ${If} $1 == "" + SetErrors + DetailPrint "ERROR: EnvVarName is blank" + Goto EnvVarUpdate_Restore_Vars + ${EndIf} + + ; Check for valid Action + ${If} $2 != "A" + ${AndIf} $2 != "P" + ${AndIf} $2 != "R" + SetErrors + DetailPrint "ERROR: Invalid Action - must be A, P, or R" + Goto EnvVarUpdate_Restore_Vars + ${EndIf} + + ${If} $3 == HKLM + ReadRegStr $5 ${hklm_all_users} $1 ; Get EnvVarName from all users into $5 + ${ElseIf} $3 == HKCU + ReadRegStr $5 ${hkcu_current_user} $1 ; Read EnvVarName from current user into $5 + ${Else} + SetErrors + DetailPrint 'ERROR: Action is [$3] but must be "HKLM" or HKCU"' + Goto EnvVarUpdate_Restore_Vars + ${EndIf} + + ; Check for empty PathString + ${If} $4 == "" + SetErrors + DetailPrint "ERROR: PathString is blank" + Goto EnvVarUpdate_Restore_Vars + ${EndIf} + + ; Make sure we've got some work to do + ${If} $5 == "" + ${AndIf} $2 == "R" + SetErrors + DetailPrint "$1 is empty - Nothing to remove" + Goto EnvVarUpdate_Restore_Vars + ${EndIf} + + ; Step 2: Scrub EnvVar + ; + StrCpy $0 $5 ; Copy the contents to $0 + ; Remove spaces around semicolons (NOTE: spaces before the 1st entry or + ; after the last one are not removed here but instead in Step 3) + ${If} $0 != "" ; If EnvVar is not empty ... + ${Do} + ${${UN}StrStr} $7 $0 " ;" + ${If} $7 == "" + ${ExitDo} + ${EndIf} + ${${UN}StrRep} $0 $0 " ;" ";" ; Remove ';' + ${Loop} + ${Do} + ${${UN}StrStr} $7 $0 "; " + ${If} $7 == "" + ${ExitDo} + ${EndIf} + ${${UN}StrRep} $0 $0 "; " ";" ; Remove ';' + ${Loop} + ${Do} + ${${UN}StrStr} $7 $0 ";;" + ${If} $7 == "" + ${ExitDo} + ${EndIf} + ${${UN}StrRep} $0 $0 ";;" ";" + ${Loop} + + ; Remove a leading or trailing semicolon from EnvVar + StrCpy $7 $0 1 0 + ${If} $7 == ";" + StrCpy $0 $0 "" 1 ; Change ';' to '' + ${EndIf} + StrLen $6 $0 + IntOp $6 $6 - 1 + StrCpy $7 $0 1 $6 + ${If} $7 == ";" + StrCpy $0 $0 $6 ; Change ';' to '' + ${EndIf} + ; DetailPrint "Scrubbed $1: [$0]" ; Uncomment to debug + ${EndIf} + + /* Step 3. Remove all instances of the target path/string (even if "A" or "P") + $6 = bool flag (1 = found and removed PathString) + $7 = a string (e.g. path) delimited by semicolon(s) + $8 = entry counter starting at 0 + $9 = copy of $0 + $R0 = tempChar */ + + ${If} $5 != "" ; If EnvVar is not empty ... + StrCpy $9 $0 + StrCpy $0 "" + StrCpy $8 0 + StrCpy $6 0 + + ${Do} + ${${UN}StrTok} $7 $9 ";" $8 "0" ; $7 = next entry, $8 = entry counter + + ${If} $7 == "" ; If we've run out of entries, + ${ExitDo} ; were done + ${EndIf} ; + + ; Remove leading and trailing spaces from this entry (critical step for Action=Remove) + ${Do} + StrCpy $R0 $7 1 + ${If} $R0 != " " + ${ExitDo} + ${EndIf} + StrCpy $7 $7 "" 1 ; Remove leading space + ${Loop} + ${Do} + StrCpy $R0 $7 1 -1 + ${If} $R0 != " " + ${ExitDo} + ${EndIf} + StrCpy $7 $7 -1 ; Remove trailing space + ${Loop} + ${If} $7 == $4 ; If string matches, remove it by not appending it + StrCpy $6 1 ; Set 'found' flag + ${ElseIf} $7 != $4 ; If string does NOT match + ${AndIf} $0 == "" ; and the 1st string being added to $0, + StrCpy $0 $7 ; copy it to $0 without a prepended semicolon + ${ElseIf} $7 != $4 ; If string does NOT match + ${AndIf} $0 != "" ; and this is NOT the 1st string to be added to $0, + StrCpy $0 $0;$7 ; append path to $0 with a prepended semicolon + ${EndIf} ; + + IntOp $8 $8 + 1 ; Bump counter + ${Loop} ; Check for duplicates until we run out of paths + ${EndIf} + + ; Step 4: Perform the requested Action + ; + ${If} $2 != "R" ; If Append or Prepend + ${If} $6 == 1 ; And if we found the target + DetailPrint "Target is already present in $1. It will be removed and" + ${EndIf} + ${If} $0 == "" ; If EnvVar is (now) empty + StrCpy $0 $4 ; just copy PathString to EnvVar + ${If} $6 == 0 ; If found flag is either 0 + ${OrIf} $6 == "" ; or blank (if EnvVarName is empty) + DetailPrint "$1 was empty and has been updated with the target" + ${EndIf} + ${ElseIf} $2 == "A" ; If Append (and EnvVar is not empty), + StrCpy $0 $0;$4 ; append PathString + ${If} $6 == 1 + DetailPrint "appended to $1" + ${Else} + DetailPrint "Target was appended to $1" + ${EndIf} + ${Else} ; If Prepend (and EnvVar is not empty), + StrCpy $0 $4;$0 ; prepend PathString + ${If} $6 == 1 + DetailPrint "prepended to $1" + ${Else} + DetailPrint "Target was prepended to $1" + ${EndIf} + ${EndIf} + ${Else} ; If Action = Remove + ${If} $6 == 1 ; and we found the target + DetailPrint "Target was found and removed from $1" + ${Else} + DetailPrint "Target was NOT found in $1 (nothing to remove)" + ${EndIf} + ${If} $0 == "" + DetailPrint "$1 is now empty" + ${EndIf} + ${EndIf} + + ; Step 5: Update the registry at RegLoc with the updated EnvVar and announce the change + ; + ClearErrors + ${If} $3 == HKLM + WriteRegExpandStr ${hklm_all_users} $1 $0 ; Write it in all users section + ${ElseIf} $3 == HKCU + WriteRegExpandStr ${hkcu_current_user} $1 $0 ; Write it to current user section + ${EndIf} + + IfErrors 0 +4 + MessageBox MB_OK|MB_ICONEXCLAMATION "Could not write updated $1 to $3" + DetailPrint "Could not write updated $1 to $3" + Goto EnvVarUpdate_Restore_Vars + + ; "Export" our change + SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000 + + EnvVarUpdate_Restore_Vars: + ; + ; Restore the user's variables and return ResultVar + Pop $R0 + Pop $9 + Pop $8 + Pop $7 + Pop $6 + Pop $5 + Pop $4 + Pop $3 + Pop $2 + Pop $1 + Push $0 ; Push my $0 (ResultVar) + Exch + Pop $0 ; Restore his $0 + +FunctionEnd + +!macroend ; EnvVarUpdate UN +!insertmacro EnvVarUpdate "" +!insertmacro EnvVarUpdate "un." +;----------------------------------- EnvVarUpdate end---------------------------------------- + +!verbose pop +!endif \ No newline at end of file diff --git a/build/nsis.geth.nsi b/build/nsis.geth.nsi new file mode 100644 index 0000000000..1034f30235 --- /dev/null +++ b/build/nsis.geth.nsi @@ -0,0 +1,70 @@ +# Builds a Windows installer with NSIS. +# It expects the following command line arguments: +# - OUTPUTFILE, filename of the installer (without extension) +# - MAJORVERSION, major build version +# - MINORVERSION, minor build version +# - BUILDVERSION, build id version +# +# The created installer executes the following steps: +# 1. install geth for all users +# 2. install optional development tools such as abigen +# 3. create an uninstaller +# 4. configures the Windows firewall for geth +# 5. create geth, attach and uninstall start menu entries +# 6. configures the registry that allows Windows to manage the package through its platform tools +# 7. adds the environment system wide variable ETHEREUM_SOCKET +# 8. adds the install directory to %PATH% +# +# Requirements: +# - NSIS, http://nsis.sourceforge.net/Main_Page +# - NSIS Large Strings build, http://nsis.sourceforge.net/Special_Builds +# - SFP, http://nsis.sourceforge.net/NSIS_Simple_Firewall_Plugin (put dll in NSIS\Plugins\x86-ansi) +# +# After intalling NSIS extra the NSIS Large Strings build zip and replace the makensis.exe and the +# files found in Stub. +# +# based on: http://nsis.sourceforge.net/A_simple_installer_with_start_menu_shortcut_and_uninstaller +# +# TODO: +# - sign installer +CRCCheck on + +!define GROUPNAME "Ethereum" +!define APPNAME "Geth" +!define DESCRIPTION "Official Go implementation of the Ethereum protocol" +!addplugindir .\ + +# Require admin rights on NT6+ (When UAC is turned on) +RequestExecutionLevel admin + +# Use LZMA compression +SetCompressor /SOLID lzma + +!include LogicLib.nsh +!include PathUpdate.nsh +!include EnvVarUpdate.nsh + +!macro VerifyUserIsAdmin +UserInfo::GetAccountType +pop $0 +${If} $0 != "admin" # Require admin rights on NT4+ + messageBox mb_iconstop "Administrator rights required!" + setErrorLevel 740 # ERROR_ELEVATION_REQUIRED + quit +${EndIf} +!macroend + +function .onInit + # make vars are global for all users since geth is installed global + setShellVarContext all + !insertmacro VerifyUserIsAdmin + + ${If} ${ARCH} == "amd64" + StrCpy $InstDir "$PROGRAMFILES64\${APPNAME}" + ${Else} + StrCpy $InstDir "$PROGRAMFILES32\${APPNAME}" + ${Endif} +functionEnd + +!include install.nsh +!include uninstall.nsh diff --git a/build/nsis.install.nsh b/build/nsis.install.nsh new file mode 100644 index 0000000000..57ef5a37c6 --- /dev/null +++ b/build/nsis.install.nsh @@ -0,0 +1,103 @@ +Name "geth ${MAJORVERSION}.${MINORVERSION}.${BUILDVERSION}" # VERSION variables set through command line arguments +InstallDir "$InstDir" +OutFile "${OUTPUTFILE}" # set through command line arguments + +# Links for "Add/Remove Programs" +!define HELPURL "https://github.com/ethereum/go-ethereum/issues" +!define UPDATEURL "https://github.com/ethereum/go-ethereum/releases" +!define ABOUTURL "https://github.com/ethereum/go-ethereum#ethereum-go" +!define /date NOW "%Y%m%d" + +PageEx license + LicenseData {{.License}} +PageExEnd + +# Install geth binary +Section "Geth" GETH_IDX + SetOutPath $INSTDIR + file {{.Geth}} + + # Create start menu launcher + createDirectory "$SMPROGRAMS\${APPNAME}" + createShortCut "$SMPROGRAMS\${APPNAME}\${APPNAME}.lnk" "$INSTDIR\geth.exe" "--fast" "--cache=512" + createShortCut "$SMPROGRAMS\${APPNAME}\Attach.lnk" "$INSTDIR\geth.exe" "attach" "" "" + createShortCut "$SMPROGRAMS\${APPNAME}\Uninstall.lnk" "$INSTDIR\uninstall.exe" "" "" "" + + # Firewall - remove rules (if exists) + SimpleFC::AdvRemoveRule "Geth incoming peers (TCP:30303)" + SimpleFC::AdvRemoveRule "Geth outgoing peers (TCP:30303)" + SimpleFC::AdvRemoveRule "Geth UDP discovery (UDP:30303)" + + # Firewall - add rules + SimpleFC::AdvAddRule "Geth incoming peers (TCP:30303)" "" 6 1 1 2147483647 1 "$INSTDIR\geth.exe" "" "" "Ethereum" 30303 "" "" "" + SimpleFC::AdvAddRule "Geth outgoing peers (TCP:30303)" "" 6 2 1 2147483647 1 "$INSTDIR\geth.exe" "" "" "Ethereum" "" 30303 "" "" + SimpleFC::AdvAddRule "Geth UDP discovery (UDP:30303)" "" 17 2 1 2147483647 1 "$INSTDIR\geth.exe" "" "" "Ethereum" "" 30303 "" "" + + # Set default IPC endpoint (https://github.com/ethereum/EIPs/issues/147) + ${EnvVarUpdate} $0 "ETHEREUM_SOCKET" "R" "HKLM" "\\.\pipe\geth.ipc" + ${EnvVarUpdate} $0 "ETHEREUM_SOCKET" "A" "HKLM" "\\.\pipe\geth.ipc" + + # Add instdir to PATH + Push "$INSTDIR" + Call AddToPath +SectionEnd + +# Install optional develop tools. +Section /o "Development tools" DEV_TOOLS_IDX + SetOutPath $INSTDIR + {{range .DevTools}}file {{.}} + {{end}} +SectionEnd + +# Return on top of stack the total size (as DWORD) of the selected/installed sections. +Var GetInstalledSize.total +Function GetInstalledSize + StrCpy $GetInstalledSize.total 0 + + ${if} ${SectionIsSelected} ${GETH_IDX} + SectionGetSize ${GETH_IDX} $0 + IntOp $GetInstalledSize.total $GetInstalledSize.total + $0 + ${endif} + + ${if} ${SectionIsSelected} ${DEV_TOOLS_IDX} + SectionGetSize ${DEV_TOOLS_IDX} $0 + IntOp $GetInstalledSize.total $GetInstalledSize.total + $0 + ${endif} + + IntFmt $GetInstalledSize.total "0x%08X" $GetInstalledSize.total + Push $GetInstalledSize.total +FunctionEnd + +# Write registry, Windows uses these values in various tools such as add/remove program. +# PowerShell: Get-ItemProperty HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* | Select-Object DisplayName, InstallLocation, InstallDate | Format-Table –AutoSize +function .onInstSuccess + # Save information in registry in HKEY_LOCAL_MACHINE branch, Windows add/remove functionality depends on this + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${GROUPNAME} ${APPNAME}" "DisplayName" "${GROUPNAME} - ${APPNAME} - ${DESCRIPTION}" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${GROUPNAME} ${APPNAME}" "UninstallString" "$\"$INSTDIR\uninstall.exe$\"" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${GROUPNAME} ${APPNAME}" "QuietUninstallString" "$\"$INSTDIR\uninstall.exe$\" /S" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${GROUPNAME} ${APPNAME}" "InstallLocation" "$INSTDIR" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${GROUPNAME} ${APPNAME}" "InstallDate" "${NOW}" + # Wait for Alex + #WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${GROUPNAME} ${APPNAME}" "DisplayIcon" "$\"$INSTDIR\logo.ico$\"" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${GROUPNAME} ${APPNAME}" "Publisher" "${GROUPNAME}" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${GROUPNAME} ${APPNAME}" "HelpLink" "${HELPURL}" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${GROUPNAME} ${APPNAME}" "URLUpdateInfo" "${UPDATEURL}" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${GROUPNAME} ${APPNAME}" "URLInfoAbout" "${ABOUTURL}" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${GROUPNAME} ${APPNAME}" "DisplayVersion" "${MAJORVERSION}.${MINORVERSION}.${BUILDVERSION}" + WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${GROUPNAME} ${APPNAME}" "VersionMajor" ${MAJORVERSION} + WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${GROUPNAME} ${APPNAME}" "VersionMinor" ${MINORVERSION} + # There is no option for modifying or repairing the install + WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${GROUPNAME} ${APPNAME}" "NoModify" 1 + WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${GROUPNAME} ${APPNAME}" "NoRepair" 1 + + Call GetInstalledSize + Pop $0 + WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${GROUPNAME} ${APPNAME}" "EstimatedSize" "$0" + + # Create uninstaller + writeUninstaller "$INSTDIR\uninstall.exe" +functionEnd + +Page components +Page directory +Page instfiles diff --git a/build/nsis.pathupdate.nsh b/build/nsis.pathupdate.nsh new file mode 100644 index 0000000000..f54b7e3e13 --- /dev/null +++ b/build/nsis.pathupdate.nsh @@ -0,0 +1,153 @@ +!include "WinMessages.nsh" + +; see https://support.microsoft.com/en-us/kb/104011 +!define Environ 'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"' +; HKEY_LOCAL_MACHINE = 0x80000002 + +; AddToPath - Appends dir to PATH +; (does not work on Win9x/ME) +; +; Usage: +; Push "dir" +; Call AddToPath +Function AddToPath + Exch $0 + Push $1 + Push $2 + Push $3 + Push $4 + + ; NSIS ReadRegStr returns empty string on string overflow + ; Native calls are used here to check actual length of PATH + ; $4 = RegOpenKey(HKEY_LOCAL_MACHINE, "SYSTEM\CurrentControlSet\Control\Session Manager\Environment", &$3) + System::Call "advapi32::RegOpenKey(i 0x80000002, t'SYSTEM\CurrentControlSet\Control\Session Manager\Environment', *i.r3) i.r4" + IntCmp $4 0 0 done done + + ; $4 = RegQueryValueEx($3, "PATH", (DWORD*)0, (DWORD*)0, &$1, ($2=NSIS_MAX_STRLEN, &$2)) + ; RegCloseKey($3) + System::Call "advapi32::RegQueryValueEx(i $3, t'PATH', i 0, i 0, t.r1, *i ${NSIS_MAX_STRLEN} r2) i.r4" + System::Call "advapi32::RegCloseKey(i $3)" + + IntCmp $4 234 0 +4 +4 ; $4 == ERROR_MORE_DATA + DetailPrint "AddToPath: original length $2 > ${NSIS_MAX_STRLEN}" + MessageBox MB_OK "PATH not updated, original length $2 > ${NSIS_MAX_STRLEN}" + Goto done + + IntCmp $4 0 +5 ; $4 != NO_ERROR + IntCmp $4 2 +3 ; $4 != ERROR_FILE_NOT_FOUND + DetailPrint "AddToPath: unexpected error code $4" + Goto done + StrCpy $1 "" + + ; Check if already in PATH + Push "$1;" + Push "$0;" + Call StrStr + Pop $2 + StrCmp $2 "" 0 done + Push "$1;" + Push "$0\;" + Call StrStr + Pop $2 + StrCmp $2 "" 0 done + + ; Prevent NSIS string overflow + StrLen $2 $0 + StrLen $3 $1 + IntOp $2 $2 + $3 + IntOp $2 $2 + 2 ; $2 = strlen(dir) + strlen(PATH) + sizeof(";") + IntCmp $2 ${NSIS_MAX_STRLEN} +4 +4 0 + DetailPrint "AddToPath: new length $2 > ${NSIS_MAX_STRLEN}" + MessageBox MB_OK "PATH not updated, new length $2 > ${NSIS_MAX_STRLEN}." + Goto done + + ; Append dir to PATH + DetailPrint "Add to PATH: $0" + StrCpy $2 $1 1 -1 + StrCmp $2 ";" 0 +2 + StrCpy $1 $1 -1 ; remove trailing ';' + StrCmp $1 "" +2 ; no leading ';' + StrCpy $0 "$1;$0" + + WriteRegExpandStr ${Environ} "PATH" $0 + SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000 + +done: + Pop $4 + Pop $3 + Pop $2 + Pop $1 + Pop $0 +FunctionEnd + + +; RemoveFromPath - Removes dir from PATH +; +; Usage: +; Push "dir" +; Call RemoveFromPath +Function un.RemoveFromPath + Exch $0 + Push $1 + Push $2 + Push $3 + Push $4 + Push $5 + Push $6 + + ; NSIS ReadRegStr returns empty string on string overflow + ; Native calls are used here to check actual length of PATH + ; $4 = RegOpenKey(HKEY_LOCAL_MACHINE, "SYSTEM\CurrentControlSet\Control\Session Manager\Environment", &$3) + System::Call "advapi32::RegOpenKey(i 0x80000002, t'SYSTEM\CurrentControlSet\Control\Session Manager\Environment', *i.r3) i.r4" + IntCmp $4 0 0 done done + + ; $4 = RegQueryValueEx($3, "PATH", (DWORD*)0, (DWORD*)0, &$1, ($2=NSIS_MAX_STRLEN, &$2)) + ; RegCloseKey($3) + System::Call "advapi32::RegQueryValueEx(i $3, t'PATH', i 0, i 0, t.r1, *i ${NSIS_MAX_STRLEN} r2) i.r4" + System::Call "advapi32::RegCloseKey(i $3)" + + IntCmp $4 234 0 +4 +4 ; $4 == ERROR_MORE_DATA + DetailPrint "RemoveFromPath: original length $2 > ${NSIS_MAX_STRLEN}" + MessageBox MB_OK "PATH not updated, original length $2 > ${NSIS_MAX_STRLEN}" + Goto done + + IntCmp $4 0 +5 ; $4 != NO_ERROR + IntCmp $4 2 +3 ; $4 != ERROR_FILE_NOT_FOUND + DetailPrint "RemoveFromPath: unexpected error code $4" + Goto done + StrCpy $1 "" + + ; length < ${NSIS_MAX_STRLEN} -> ReadRegStr can be used + ReadRegStr $1 ${Environ} "PATH" + StrCpy $5 $1 1 -1 + StrCmp $5 ";" +2 + StrCpy $1 "$1;" ; ensure trailing ';' + Push $1 + Push "$0;" + Call un.StrStr + Pop $2 ; pos of our dir + StrCmp $2 "" done + + DetailPrint "Remove from PATH: $0" + StrLen $3 "$0;" + StrLen $4 $2 + StrCpy $5 $1 -$4 ; $5 is now the part before the path to remove + StrCpy $6 $2 "" $3 ; $6 is now the part after the path to remove + StrCpy $3 "$5$6" + StrCpy $5 $3 1 -1 + StrCmp $5 ";" 0 +2 + StrCpy $3 $3 -1 ; remove trailing ';' + WriteRegExpandStr ${Environ} "PATH" $3 + SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000 + +done: + Pop $6 + Pop $5 + Pop $4 + Pop $3 + Pop $2 + Pop $1 + Pop $0 +FunctionEnd + + diff --git a/build/nsis.simplefc.dll b/build/nsis.simplefc.dll new file mode 100644 index 0000000000..73b7d9634d Binary files /dev/null and b/build/nsis.simplefc.dll differ diff --git a/build/nsis.simplefc.source.zip b/build/nsis.simplefc.source.zip new file mode 100644 index 0000000000..d7476022ad Binary files /dev/null and b/build/nsis.simplefc.source.zip differ diff --git a/build/nsis.uninstall.nsh b/build/nsis.uninstall.nsh new file mode 100644 index 0000000000..6358faa74e --- /dev/null +++ b/build/nsis.uninstall.nsh @@ -0,0 +1,33 @@ +Section "Uninstall" + # uninstall for all users + setShellVarContext all + + # Delete (optionally) installed files + {{range $}}Delete $INSTDIR\{{.}} + {{end}} + Delete $INSTDIR\uninstall.exe + + # Delete install directory + rmDir $INSTDIR + + # Delete start menu launcher + Delete "$SMPROGRAMS\${APPNAME}\${APPNAME}.lnk" + Delete "$SMPROGRAMS\${APPNAME}\Attach.lnk" + Delete "$SMPROGRAMS\${APPNAME}\Uninstall.lnk" + rmDir "$SMPROGRAMS\${APPNAME}" + + # Firewall - remove rules if exists + SimpleFC::AdvRemoveRule "Geth incoming peers (TCP:30303)" + SimpleFC::AdvRemoveRule "Geth outgoing peers (TCP:30303)" + SimpleFC::AdvRemoveRule "Geth UDP discovery (UDP:30303)" + + # Remove IPC endpoint (https://github.com/ethereum/EIPs/issues/147) + ${un.EnvVarUpdate} $0 "ETHEREUM_SOCKET" "R" "HKLM" "\\.\pipe\geth.ipc" + + # Remove install directory from PATH + Push "$INSTDIR" + Call un.RemoveFromPath + + # Cleanup registry (deletes all sub keys) + DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${GROUPNAME} ${APPNAME}" +SectionEnd diff --git a/build/pod.podspec b/build/pod.podspec new file mode 100644 index 0000000000..2c14c280c7 --- /dev/null +++ b/build/pod.podspec @@ -0,0 +1,22 @@ +Pod::Spec.new do |spec| + spec.name = 'Geth' + spec.version = '{{.Version}}' + spec.license = { :type => 'GNU Lesser General Public License, Version 3.0' } + spec.homepage = 'https://github.com/ethereum/go-ethereum' + spec.authors = { {{range .Contributors}} + '{{.Name}}' => '{{.Email}}',{{end}} + } + spec.summary = 'iOS Ethereum Client' + spec.source = { :git => 'https://github.com/ethereum/go-ethereum.git', :commit => '{{.Commit}}' } + + spec.platform = :ios + spec.ios.deployment_target = '9.0' + spec.ios.vendored_frameworks = 'Frameworks/Geth.framework' + + spec.prepare_command = <<-CMD + curl https://gethstore.blob.core.windows.net/builds/{{.Archive}}.tar.gz | tar -xvz + mkdir Frameworks + mv {{.Archive}}/Geth.framework Frameworks + rm -rf {{.Archive}} + CMD +end diff --git a/build/update-license.go b/build/update-license.go new file mode 100644 index 0000000000..22e4033428 --- /dev/null +++ b/build/update-license.go @@ -0,0 +1,395 @@ +// +build none + +/* +This command generates GPL license headers on top of all source files. +You can run it once per month, before cutting a release or just +whenever you feel like it. + + go run update-license.go + +All authors (people who have contributed code) are listed in the +AUTHORS file. The author names are mapped and deduplicated using the +.mailmap file. You can use .mailmap to set the canonical name and +address for each author. See git-shortlog(1) for an explanation of the +.mailmap format. + +Please review the resulting diff to check whether the correct +copyright assignments are performed. +*/ + +package main + +import ( + "bufio" + "bytes" + "fmt" + "io/ioutil" + "log" + "os" + "os/exec" + "path/filepath" + "regexp" + "runtime" + "sort" + "strconv" + "strings" + "sync" + "text/template" + "time" +) + +var ( + // only files with these extensions will be considered + extensions = []string{".go", ".js", ".qml"} + + // paths with any of these prefixes will be skipped + skipPrefixes = []string{ + // boring stuff + "vendor/", "tests/testdata/", "build/", + // don't relicense vendored sources + "cmd/internal/browser", + "consensus/ethash/xor.go", + "crypto/bn256/", + "crypto/ecies/", + "crypto/secp256k1/curve.go", + "crypto/sha3/", + "internal/jsre/deps", + "log/", + "common/bitutil/bitutil", + // don't license generated files + "contracts/chequebook/contract/code.go", + } + + // paths with this prefix are licensed as GPL. all other files are LGPL. + gplPrefixes = []string{"cmd/"} + + // this regexp must match the entire license comment at the + // beginning of each file. + licenseCommentRE = regexp.MustCompile(`^//\s*(Copyright|This file is part of).*?\n(?://.*?\n)*\n*`) + + // this text appears at the start of AUTHORS + authorsFileHeader = "# This is the official list of go-ethereum authors for copyright purposes.\n\n" +) + +// this template generates the license comment. +// its input is an info structure. +var licenseT = template.Must(template.New("").Parse(` +// Copyright {{.Year}} The go-ethereum Authors +// This file is part of {{.Whole false}}. +// +// {{.Whole true}} is free software: you can redistribute it and/or modify +// it under the terms of the GNU {{.License}} as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// {{.Whole true}} 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 {{.License}} for more details. +// +// You should have received a copy of the GNU {{.License}} +// along with {{.Whole false}}. If not, see . + +`[1:])) + +type info struct { + file string + Year int64 +} + +func (i info) License() string { + if i.gpl() { + return "General Public License" + } + return "Lesser General Public License" +} + +func (i info) ShortLicense() string { + if i.gpl() { + return "GPL" + } + return "LGPL" +} + +func (i info) Whole(startOfSentence bool) string { + if i.gpl() { + return "go-ethereum" + } + if startOfSentence { + return "The go-ethereum library" + } + return "the go-ethereum library" +} + +func (i info) gpl() bool { + for _, p := range gplPrefixes { + if strings.HasPrefix(i.file, p) { + return true + } + } + return false +} + +func main() { + var ( + files = getFiles() + filec = make(chan string) + infoc = make(chan *info, 20) + wg sync.WaitGroup + ) + + writeAuthors(files) + + go func() { + for _, f := range files { + filec <- f + } + close(filec) + }() + for i := runtime.NumCPU(); i >= 0; i-- { + // getting file info is slow and needs to be parallel. + // it traverses git history for each file. + wg.Add(1) + go getInfo(filec, infoc, &wg) + } + go func() { + wg.Wait() + close(infoc) + }() + writeLicenses(infoc) +} + +func skipFile(path string) bool { + if strings.Contains(path, "/testdata/") { + return true + } + for _, p := range skipPrefixes { + if strings.HasPrefix(path, p) { + return true + } + } + return false +} + +func getFiles() []string { + cmd := exec.Command("git", "ls-tree", "-r", "--name-only", "HEAD") + var files []string + err := doLines(cmd, func(line string) { + if skipFile(line) { + return + } + ext := filepath.Ext(line) + for _, wantExt := range extensions { + if ext == wantExt { + goto keep + } + } + return + keep: + files = append(files, line) + }) + if err != nil { + log.Fatal("error getting files:", err) + } + return files +} + +var authorRegexp = regexp.MustCompile(`\s*[0-9]+\s*(.*)`) + +func gitAuthors(files []string) []string { + cmds := []string{"shortlog", "-s", "-n", "-e", "HEAD", "--"} + cmds = append(cmds, files...) + cmd := exec.Command("git", cmds...) + var authors []string + err := doLines(cmd, func(line string) { + m := authorRegexp.FindStringSubmatch(line) + if len(m) > 1 { + authors = append(authors, m[1]) + } + }) + if err != nil { + log.Fatalln("error getting authors:", err) + } + return authors +} + +func readAuthors() []string { + content, err := ioutil.ReadFile("AUTHORS") + if err != nil && !os.IsNotExist(err) { + log.Fatalln("error reading AUTHORS:", err) + } + var authors []string + for _, a := range bytes.Split(content, []byte("\n")) { + if len(a) > 0 && a[0] != '#' { + authors = append(authors, string(a)) + } + } + // Retranslate existing authors through .mailmap. + // This should catch email address changes. + authors = mailmapLookup(authors) + return authors +} + +func mailmapLookup(authors []string) []string { + if len(authors) == 0 { + return nil + } + cmds := []string{"check-mailmap", "--"} + cmds = append(cmds, authors...) + cmd := exec.Command("git", cmds...) + var translated []string + err := doLines(cmd, func(line string) { + translated = append(translated, line) + }) + if err != nil { + log.Fatalln("error translating authors:", err) + } + return translated +} + +func writeAuthors(files []string) { + merge := make(map[string]bool) + // Add authors that Git reports as contributorxs. + // This is the primary source of author information. + for _, a := range gitAuthors(files) { + merge[a] = true + } + // Add existing authors from the file. This should ensure that we + // never lose authors, even if Git stops listing them. We can also + // add authors manually this way. + for _, a := range readAuthors() { + merge[a] = true + } + // Write sorted list of authors back to the file. + var result []string + for a := range merge { + result = append(result, a) + } + sort.Strings(result) + content := new(bytes.Buffer) + content.WriteString(authorsFileHeader) + for _, a := range result { + content.WriteString(a) + content.WriteString("\n") + } + fmt.Println("writing AUTHORS") + if err := ioutil.WriteFile("AUTHORS", content.Bytes(), 0644); err != nil { + log.Fatalln(err) + } +} + +func getInfo(files <-chan string, out chan<- *info, wg *sync.WaitGroup) { + for file := range files { + stat, err := os.Lstat(file) + if err != nil { + fmt.Printf("ERROR %s: %v\n", file, err) + continue + } + if !stat.Mode().IsRegular() { + continue + } + if isGenerated(file) { + continue + } + info, err := fileInfo(file) + if err != nil { + fmt.Printf("ERROR %s: %v\n", file, err) + continue + } + out <- info + } + wg.Done() +} + +func isGenerated(file string) bool { + fd, err := os.Open(file) + if err != nil { + return false + } + defer fd.Close() + buf := make([]byte, 2048) + n, _ := fd.Read(buf) + buf = buf[:n] + for _, l := range bytes.Split(buf, []byte("\n")) { + if bytes.HasPrefix(l, []byte("// Code generated")) { + return true + } + } + return false +} + +// fileInfo finds the lowest year in which the given file was committed. +func fileInfo(file string) (*info, error) { + info := &info{file: file, Year: int64(time.Now().Year())} + cmd := exec.Command("git", "log", "--follow", "--find-renames=80", "--find-copies=80", "--pretty=format:%ai", "--", file) + err := doLines(cmd, func(line string) { + y, err := strconv.ParseInt(line[:4], 10, 64) + if err != nil { + fmt.Printf("cannot parse year: %q", line[:4]) + } + if y < info.Year { + info.Year = y + } + }) + return info, err +} + +func writeLicenses(infos <-chan *info) { + for i := range infos { + writeLicense(i) + } +} + +func writeLicense(info *info) { + fi, err := os.Stat(info.file) + if os.IsNotExist(err) { + fmt.Println("skipping (does not exist)", info.file) + return + } + if err != nil { + log.Fatalf("error stat'ing %s: %v\n", info.file, err) + } + content, err := ioutil.ReadFile(info.file) + if err != nil { + log.Fatalf("error reading %s: %v\n", info.file, err) + } + // Construct new file content. + buf := new(bytes.Buffer) + licenseT.Execute(buf, info) + if m := licenseCommentRE.FindIndex(content); m != nil && m[0] == 0 { + buf.Write(content[:m[0]]) + buf.Write(content[m[1]:]) + } else { + buf.Write(content) + } + // Write it to the file. + if bytes.Equal(content, buf.Bytes()) { + fmt.Println("skipping (no changes)", info.file) + return + } + fmt.Println("writing", info.ShortLicense(), info.file) + if err := ioutil.WriteFile(info.file, buf.Bytes(), fi.Mode()); err != nil { + log.Fatalf("error writing %s: %v", info.file, err) + } +} + +func doLines(cmd *exec.Cmd, f func(string)) error { + stdout, err := cmd.StdoutPipe() + if err != nil { + return err + } + if err := cmd.Start(); err != nil { + return err + } + s := bufio.NewScanner(stdout) + for s.Scan() { + f(s.Text()) + } + if s.Err() != nil { + return s.Err() + } + if err := cmd.Wait(); err != nil { + return fmt.Errorf("%v (for %s)", err, strings.Join(cmd.Args, " ")) + } + return nil +} diff --git a/cmd/XDC/accountcmd.go b/cmd/XDC/accountcmd.go index 2a33018dcf..5ff5e544f1 100644 --- a/cmd/XDC/accountcmd.go +++ b/cmd/XDC/accountcmd.go @@ -340,7 +340,7 @@ func importWallet(ctx *cli.Context) error { if len(keyfile) == 0 { utils.Fatalf("keyfile must be given as argument") } - keyJson, err := ioutil.ReadFile(keyfile) + keyJSON, err := ioutil.ReadFile(keyfile) if err != nil { utils.Fatalf("Could not read wallet file: %v", err) } @@ -349,7 +349,7 @@ func importWallet(ctx *cli.Context) error { passphrase := getPassPhrase("", false, 0, utils.MakePasswordList(ctx)) ks := stack.AccountManager().Backends(keystore.KeyStoreType)[0].(*keystore.KeyStore) - acct, err := ks.ImportPreSaleKey(keyJson, passphrase) + acct, err := ks.ImportPreSaleKey(keyJSON, passphrase) if err != nil { utils.Fatalf("%v", err) } diff --git a/cmd/XDC/bugcmd.go b/cmd/XDC/bugcmd.go index 3c0eb846b3..6e7fc0c734 100644 --- a/cmd/XDC/bugcmd.go +++ b/cmd/XDC/bugcmd.go @@ -41,7 +41,7 @@ var bugCommand = cli.Command{ Category: "MISCELLANEOUS COMMANDS", } -const issueUrl = "https://github.com/ethereum/go-ethereum/issues/new" +const issueURL = "https://github.com/ethereum/go-ethereum/issues/new" // reportBug reports a bug by opening a new URL to the go-ethereum GH issue // tracker and setting default values as the issue body. @@ -49,15 +49,17 @@ func reportBug(ctx *cli.Context) error { // execute template and write contents to buff var buff bytes.Buffer - fmt.Fprintln(&buff, header) - fmt.Fprintln(&buff, "Version:", params.Version) + fmt.Fprintln(&buff, "#### System information") + fmt.Fprintln(&buff) + fmt.Fprintln(&buff, "Version:", params.VersionWithMeta) fmt.Fprintln(&buff, "Go Version:", runtime.Version()) fmt.Fprintln(&buff, "OS:", runtime.GOOS) printOSDetails(&buff) + fmt.Fprintln(&buff, header) // open a new GH issue - if !browser.Open(issueUrl + "?body=" + url.QueryEscape(buff.String())) { - fmt.Printf("Please file a new issue at %s using this template:\n%s", issueUrl, buff.String()) + if !browser.Open(issueURL + "?body=" + url.QueryEscape(buff.String())) { + fmt.Printf("Please file a new issue at %s using this template:\n\n%s", issueURL, buff.String()) } return nil } @@ -97,13 +99,15 @@ func printCmdOut(w io.Writer, prefix, path string, args ...string) { fmt.Fprintf(w, "%s%s\n", prefix, bytes.TrimSpace(out)) } -const header = `Please answer these questions before submitting your issue. Thanks! +const header = ` +#### Expected behaviour -#### What did you do? - -#### What did you expect to see? - -#### What did you see instead? - -#### System details + +#### Actual behaviour + + +#### Steps to reproduce the behaviour + + +#### Backtrace ` diff --git a/cmd/XDC/chaincmd.go b/cmd/XDC/chaincmd.go index fc3be707f0..c2663b98a9 100644 --- a/cmd/XDC/chaincmd.go +++ b/cmd/XDC/chaincmd.go @@ -94,7 +94,8 @@ processing will proceed even if an individual RLP-file import failure occurs.`, Requires a first argument of the file to write to. Optional second and third arguments control the first and last block to write. In this mode, the file will be appended -if already existing.`, +if already existing. If the file ends with .gz, the output will +be gzipped.`, } importPreimagesCommand = cli.Command{ Action: utils.MigrateFlags(importPreimages), diff --git a/cmd/XDC/config.go b/cmd/XDC/config.go index 39645322c7..6d92be4822 100644 --- a/cmd/XDC/config.go +++ b/cmd/XDC/config.go @@ -145,7 +145,8 @@ func makeConfigNode(ctx *cli.Context) (*node.Node, XDCConfig) { cfg.StakeEnable = ctx.GlobalBool(utils.StakingEnabledFlag.Name) } if !ctx.GlobalIsSet(debug.VerbosityFlag.Name) { - debug.Glogger.Verbosity(log.Lvl(cfg.Verbosity)) + glogger := log.NewGlogHandler(log.StreamHandler(os.Stderr, log.TerminalFormat(false))) + glogger.Verbosity(log.Lvl(cfg.Verbosity)) } if !ctx.GlobalIsSet(utils.NATFlag.Name) && cfg.NAT != "" { diff --git a/cmd/XDC/consolecmd_test.go b/cmd/XDC/consolecmd_test.go index f189db1741..88824c4c3c 100644 --- a/cmd/XDC/consolecmd_test.go +++ b/cmd/XDC/consolecmd_test.go @@ -50,7 +50,7 @@ func TestConsoleWelcome(t *testing.T) { XDC.SetTemplateFunc("goos", func() string { return runtime.GOOS }) XDC.SetTemplateFunc("goarch", func() string { return runtime.GOARCH }) XDC.SetTemplateFunc("gover", runtime.Version) - XDC.SetTemplateFunc("XDCver", func() string { return params.Version }) + XDC.SetTemplateFunc("XDCver", func() string { return params.VersionWithMeta }) XDC.SetTemplateFunc("niltime", func() string { return time.Unix(0, 0).Format(time.RFC1123) }) XDC.SetTemplateFunc("apis", func() string { return ipcAPIs }) @@ -131,7 +131,7 @@ func testAttachWelcome(t *testing.T, XDC *testXDC, endpoint, apis string) { attach.SetTemplateFunc("goos", func() string { return runtime.GOOS }) attach.SetTemplateFunc("goarch", func() string { return runtime.GOARCH }) attach.SetTemplateFunc("gover", runtime.Version) - attach.SetTemplateFunc("XDCver", func() string { return params.Version }) + attach.SetTemplateFunc("XDCver", func() string { return params.VersionWithMeta }) attach.SetTemplateFunc("etherbase", func() string { return XDC.Etherbase }) attach.SetTemplateFunc("niltime", func() string { return time.Unix(0, 0).Format(time.RFC1123) }) attach.SetTemplateFunc("ipc", func() bool { return strings.HasPrefix(endpoint, "ipc") }) diff --git a/cmd/XDC/dao_test.go b/cmd/XDC/dao_test.go index 13052ed19e..bc6af719ed 100644 --- a/cmd/XDC/dao_test.go +++ b/cmd/XDC/dao_test.go @@ -24,7 +24,7 @@ import ( "testing" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/params" ) @@ -131,8 +131,8 @@ func testDAOForkBlockNewChain(t *testing.T, test int, genesis string, expectBloc if genesis != "" { genesisHash = daoGenesisHash } - config, err := core.GetChainConfig(db, genesisHash) - if err != nil { + config := rawdb.ReadChainConfig(db, genesisHash) + if config == nil { t.Errorf("test %d: failed to retrieve chain config: %v", test, err) return // we want to return here, the other checks can't make it past this point (nil panic). } diff --git a/cmd/XDC/genesis_test.go b/cmd/XDC/genesis_test.go new file mode 100644 index 0000000000..e75b542cbb --- /dev/null +++ b/cmd/XDC/genesis_test.go @@ -0,0 +1,110 @@ +// Copyright 2016 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 ( + "io/ioutil" + "os" + "path/filepath" + "testing" +) + +var customGenesisTests = []struct { + genesis string + query string + result string +}{ + // Plain genesis file without anything extra + { + genesis: `{ + "alloc" : {}, + "coinbase" : "0x0000000000000000000000000000000000000000", + "difficulty" : "0x20000", + "extraData" : "", + "gasLimit" : "0x2fefd8", + "nonce" : "0x0000000000000042", + "mixhash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "timestamp" : "0x00" + }`, + query: "eth.getBlock(0).nonce", + result: "0x0000000000000042", + }, + // Genesis file with an empty chain configuration (ensure missing fields work) + { + genesis: `{ + "alloc" : {}, + "coinbase" : "0x0000000000000000000000000000000000000000", + "difficulty" : "0x20000", + "extraData" : "", + "gasLimit" : "0x2fefd8", + "nonce" : "0x0000000000000042", + "mixhash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "timestamp" : "0x00", + "config" : {} + }`, + query: "eth.getBlock(0).nonce", + result: "0x0000000000000042", + }, + // Genesis file with specific chain configurations + { + genesis: `{ + "alloc" : {}, + "coinbase" : "0x0000000000000000000000000000000000000000", + "difficulty" : "0x20000", + "extraData" : "", + "gasLimit" : "0x2fefd8", + "nonce" : "0x0000000000000042", + "mixhash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "timestamp" : "0x00", + "config" : { + "homesteadBlock" : 314, + "daoForkBlock" : 141, + "daoForkSupport" : true + } + }`, + query: "eth.getBlock(0).nonce", + result: "0x0000000000000042", + }, +} + +// Tests that initializing Geth with a custom genesis block and chain definitions +// work properly. +func TestCustomGenesis(t *testing.T) { + for i, tt := range customGenesisTests { + // Create a temporary data directory to use and inspect later + datadir := tmpdir(t) + defer os.RemoveAll(datadir) + + // Initialize the data directory with the custom genesis block + json := filepath.Join(datadir, "genesis.json") + if err := ioutil.WriteFile(json, []byte(tt.genesis), 0600); err != nil { + t.Fatalf("test %d: failed to write genesis file: %v", i, err) + } + runGeth(t, "--datadir", datadir, "init", json).WaitExit() + + // Query the custom genesis block + geth := runGeth(t, + "--datadir", datadir, "--maxpeers", "0", "--port", "0", + "--nodiscover", "--nat", "none", "--ipcdisable", + "--exec", tt.query, "console") + geth.ExpectRegexp(tt.result) + geth.ExpectExit() + } +} diff --git a/cmd/XDC/main.go b/cmd/XDC/main.go index 0d531da427..1d7b3be068 100644 --- a/cmd/XDC/main.go +++ b/cmd/XDC/main.go @@ -18,12 +18,16 @@ package main import ( "fmt" + "math" "os" "runtime" + godebug "runtime/debug" "sort" + "strconv" "strings" "time" + "github.com/elastic/gosigar" "github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/accounts/keystore" "github.com/ethereum/go-ethereum/cmd/utils" @@ -146,13 +150,22 @@ var ( utils.WhisperMaxMessageSizeFlag, utils.WhisperMinPOWFlag, } + + metricsFlags = []cli.Flag{ + utils.MetricsEnableInfluxDBFlag, + utils.MetricsInfluxDBEndpointFlag, + utils.MetricsInfluxDBDatabaseFlag, + utils.MetricsInfluxDBUsernameFlag, + utils.MetricsInfluxDBPasswordFlag, + utils.MetricsInfluxDBHostTagFlag, + } ) func init() { // Initialize the CLI app and start XDC app.Action = XDC app.HideVersion = true // we have a command to print the version - app.Copyright = "Copyright (c) 2018 XDCchain" + app.Copyright = "Copyright 2017-2020 The XDC.Network Authors" app.Commands = []cli.Command{ // See chaincmd.go: initCommand, @@ -178,13 +191,38 @@ func init() { app.Flags = append(app.Flags, rpcFlags...) app.Flags = append(app.Flags, consoleFlags...) app.Flags = append(app.Flags, debug.Flags...) - //app.Flags = append(app.Flags, whisperFlags...) + app.Flags = append(app.Flags, whisperFlags...) + app.Flags = append(app.Flags, metricsFlags...) app.Before = func(ctx *cli.Context) error { runtime.GOMAXPROCS(runtime.NumCPU()) - if err := debug.Setup(ctx); err != nil { + + logdir := "" + if ctx.GlobalBool(utils.DashboardEnabledFlag.Name) { + logdir = (&node.Config{DataDir: utils.MakeDataDir(ctx)}).ResolvePath("logs") + } + if err := debug.Setup(ctx, logdir); err != nil { return err } + // Cap the cache allowance and tune the garbage collector + var mem gosigar.Mem + if err := mem.Get(); err == nil { + allowance := int(mem.Total / 1024 / 1024 / 3) + if cache := ctx.GlobalInt(utils.CacheFlag.Name); cache > allowance { + log.Warn("Sanitizing cache to Go's GC limits", "provided", cache, "updated", allowance) + ctx.GlobalSet(utils.CacheFlag.Name, strconv.Itoa(allowance)) + } + } + // Ensure Go's GC ignores the database cache for trigger percentage + cache := ctx.GlobalInt(utils.CacheFlag.Name) + gogc := math.Max(20, math.Min(100, 100/(float64(cache)/1024))) + + log.Debug("Sanitizing Go's GC trigger", "percent", int(gogc)) + godebug.SetGCPercent(int(gogc)) + + // Start metrics export if enabled + utils.SetupMetrics(ctx) + // Start system runtime metrics collection go metrics.CollectProcessMetrics(3 * time.Second) @@ -210,16 +248,31 @@ func main() { // It creates a default node based on the command line arguments and runs it in // blocking mode, waiting for it to be shut down. func XDC(ctx *cli.Context) error { + if args := ctx.Args(); len(args) > 0 { + return fmt.Errorf("invalid command: %q", args[0]) + } node, cfg := makeFullNode(ctx) startNode(ctx, node, cfg) node.Wait() return nil } +// func XDC(ctx *cli.Context) error { +// node, cfg := makeFullNode(ctx) +// startNode(ctx, node) +// node.Wait() +// return nil +// } // startNode boots up the system node and all registered protocols, after which // it unlocks any requested accounts, and starts the RPC/IPC interfaces and the // miner. + +// TODO : check later +// func startNode(ctx *cli.Context, stack *node.Node) { +// debug.Memsize.Add("node", stack) func startNode(ctx *cli.Context, stack *node.Node, cfg XDCConfig) { + + // Start up the node itself utils.StartNode(stack) @@ -244,7 +297,7 @@ func startNode(ctx *cli.Context, stack *node.Node, cfg XDCConfig) { stack.AccountManager().Subscribe(events) go func() { - // Create an chain state reader for self-derivation + // Create a chain state reader for self-derivation rpcClient, err := stack.Attach() if err != nil { utils.Fatalf("Failed to attach to self: %v", err) @@ -268,11 +321,11 @@ func startNode(ctx *cli.Context, stack *node.Node, cfg XDCConfig) { status, _ := event.Wallet.Status() log.Info("New wallet appeared", "url", event.Wallet.URL(), "status", status) + derivationPath := accounts.DefaultBaseDerivationPath if event.Wallet.URL().Scheme == "ledger" { - event.Wallet.SelfDerive(accounts.DefaultLedgerBaseDerivationPath, stateReader) - } else { - event.Wallet.SelfDerive(accounts.DefaultBaseDerivationPath, stateReader) + derivationPath = accounts.DefaultLedgerBaseDerivationPath } + event.Wallet.SelfDerive(derivationPath, stateReader) case accounts.WalletDropped: log.Info("Old wallet dropped", "url", event.Wallet.URL()) diff --git a/cmd/XDC/misccmd.go b/cmd/XDC/misccmd.go index ef822a0176..4f88d0928e 100644 --- a/cmd/XDC/misccmd.go +++ b/cmd/XDC/misccmd.go @@ -108,7 +108,7 @@ func makedag(ctx *cli.Context) error { func version(ctx *cli.Context) error { fmt.Println(strings.Title(clientIdentifier)) - fmt.Println("Version:", params.Version) + fmt.Println("Version:", params.VersionWithMeta) if gitCommit != "" { fmt.Println("Git Commit:", gitCommit) } diff --git a/cmd/XDC/monitorcmd.go b/cmd/XDC/monitorcmd.go index 4940589b76..1410742671 100644 --- a/cmd/XDC/monitorcmd.go +++ b/cmd/XDC/monitorcmd.go @@ -185,12 +185,12 @@ func resolveMetric(metrics map[string]interface{}, pattern string, path string) parts := strings.SplitN(pattern, "/", 2) if len(parts) > 1 { for _, variation := range strings.Split(parts[0], ",") { - if submetrics, ok := metrics[variation].(map[string]interface{}); !ok { + submetrics, ok := metrics[variation].(map[string]interface{}) + if !ok { utils.Fatalf("Failed to retrieve system metrics: %s", path+variation) return nil - } else { - results = append(results, resolveMetric(submetrics, parts[1], path+variation+"/")...) } + results = append(results, resolveMetric(submetrics, parts[1], path+variation+"/")...) } return results } diff --git a/cmd/XDC/usage.go b/cmd/XDC/usage.go index 61ac98ecaa..a2e9e9b26a 100644 --- a/cmd/XDC/usage.go +++ b/cmd/XDC/usage.go @@ -33,7 +33,7 @@ import ( var AppHelpTemplate = `NAME: {{.App.Name}} - {{.App.Usage}} - Copyright (c) 2018 XDCchain + Copyright 2017-2020 The XDC.Network Authors USAGE: {{.App.HelpName}} [options]{{if .App.Commands}} command [command options]{{end}} {{if .App.ArgsUsage}}{{.App.ArgsUsage}}{{else}}[arguments...]{{end}} @@ -78,9 +78,27 @@ var AppHelpFlagGroups = []flagGroup{ utils.GCModeFlag, utils.EthStatsURLFlag, utils.IdentityFlag, - //utils.LightServFlag, - //utils.LightPeersFlag, - //utils.LightKDFFlag, + utils.LightServFlag, + utils.LightPeersFlag, + utils.LightKDFFlag, + }, + }, + { + Name: "DEVELOPER CHAIN", + Flags: []cli.Flag{ + utils.DeveloperFlag, + utils.DeveloperPeriodFlag, + }, + }, + { + Name: "ETHASH", + Flags: []cli.Flag{ + utils.EthashCacheDirFlag, + utils.EthashCachesInMemoryFlag, + utils.EthashCachesOnDiskFlag, + utils.EthashDatasetDirFlag, + utils.EthashDatasetsInMemoryFlag, + utils.EthashDatasetsOnDiskFlag, }, }, //{Name: "DEVELOPER CHAIN", @@ -206,15 +224,26 @@ var AppHelpFlagGroups = []flagGroup{ { Name: "LOGGING AND DEBUGGING", Flags: append([]cli.Flag{ - utils.MetricsEnabledFlag, - //utils.FakePoWFlag, - //utils.NoCompactionFlag, + utils.FakePoWFlag, + utils.NoCompactionFlag, }, debug.Flags...), }, - //{ - // Name: "WHISPER (EXPERIMENTAL)", - // Flags: whisperFlags, - //}, + { + Name: "METRICS AND STATS", + Flags: []cli.Flag{ + utils.MetricsEnabledFlag, + utils.MetricsEnableInfluxDBFlag, + utils.MetricsInfluxDBEndpointFlag, + utils.MetricsInfluxDBDatabaseFlag, + utils.MetricsInfluxDBUsernameFlag, + utils.MetricsInfluxDBPasswordFlag, + utils.MetricsInfluxDBHostTagFlag, + }, + }, + { + Name: "WHISPER (EXPERIMENTAL)", + Flags: whisperFlags, + }, { Name: "DEPRECATED", Flags: []cli.Flag{ diff --git a/cmd/abigen/main.go b/cmd/abigen/main.go index 3a1ae6f4c3..3ac37ba7ad 100644 --- a/cmd/abigen/main.go +++ b/cmd/abigen/main.go @@ -29,7 +29,7 @@ import ( ) var ( - abiFlag = flag.String("abi", "", "Path to the Ethereum contract ABI json to bind") + abiFlag = flag.String("abi", "", "Path to the Ethereum contract ABI json to bind, - for STDIN") binFlag = flag.String("bin", "", "Path to the Ethereum contract bytecode (generate deploy method)") typFlag = flag.String("type", "", "Struct name for the binding (default = package name)") @@ -75,16 +75,27 @@ func main() { bins []string types []string ) - if *solFlag != "" { + if *solFlag != "" || *abiFlag == "-" { // Generate the list of types to exclude from binding exclude := make(map[string]bool) for _, kind := range strings.Split(*excFlag, ",") { exclude[strings.ToLower(kind)] = true } - contracts, err := compiler.CompileSolidity(*solcFlag, *solFlag) - if err != nil { - fmt.Printf("Failed to build Solidity contract: %v\n", err) - os.Exit(-1) + + var contracts map[string]*compiler.Contract + var err error + if *solFlag != "" { + contracts, err = compiler.CompileSolidity(*solcFlag, *solFlag) + if err != nil { + fmt.Printf("Failed to build Solidity contract: %v\n", err) + os.Exit(-1) + } + } else { + contracts, err = contractsFromStdin() + if err != nil { + fmt.Printf("Failed to read input ABIs from STDIN: %v\n", err) + os.Exit(-1) + } } // Gather all non-excluded contract for binding for name, contract := range contracts { @@ -138,3 +149,12 @@ func main() { os.Exit(-1) } } + +func contractsFromStdin() (map[string]*compiler.Contract, error) { + bytes, err := ioutil.ReadAll(os.Stdin) + if err != nil { + return nil, err + } + + return compiler.ParseCombinedJSON(bytes, "", "", "", "") +} diff --git a/cmd/clef/4byte.json b/cmd/clef/4byte.json new file mode 100644 index 0000000000..5603d5931d --- /dev/null +++ b/cmd/clef/4byte.json @@ -0,0 +1 @@ +{"0x22ec1244": "shaBid(bytes32,address,uint256,bytes32)", "0xcae9ca51": "approveAndCall(address,uint256,bytes)", "0x4fb2e45d": "transferOwner(address)", "0x7741b4ec": "RandomNumberFromSeed(uint256)", "0x267127ec": "getTokenSettings()", "0xb7213bd4": "readLog(uint256)", "0x3018205f": "getController()", "0xc8edf65e": "GetAndReduceFeesByFraction(uint256)", "0xeec2b628": "beforeExecute(address)", "0xfc0c546a": "token()", "0x40a3d246": "toggle()", "0x70983e91": "startBoardProposal(uint256,address)", "0x6b5caec4": "setBot(address)", "0x78524b2e": "halveMinQuorum()", "0x2c60a055": "MapTest()", "0xc2fb8f36": "TinyHuman(address,address,address)", "0x6822abae": "getMinimumCallCost(uint256)", "0x6f9fb98a": "getContractBalance()", "0x5c17f9f4": "approve(address,uint256,bytes)", "0x504ac982": "transfer(string,string)", "0x06e53f47": "whichChainIsThis()", "0xf359671c": "withdrawWithReference(address,uint256,string)", "0xf97d0591": "parseTimestamp(uint256)", "0xd3c0715b": "vote(uint256,bool,string)", "0x6b069710": "scheduleCall(address,bytes,uint256,uint256,uint8)", "0x37ae43a3": "BetOnHashV81()", "0xab519020": "calcShare(uint256,uint256)", "0x6572ae13": "calculateWinner(uint256,uint256)", "0x6aaba012": "ErrorGenerator()", "0xfe05e8b1": "assertFact(uint256,string)", "0x6e940a29": "changeHost(address)", "0x669ee827": "RegisterDevice()", "0x6f4dd69c": "testSetBalanceUpdatesSupply()", "0x4401a6e4": "safeSend(address)", "0x27dc297e": "__callback(bytes32,string)", "0xe4dedc7f": "DeleteContract()", "0x7fef036e": "totalEntries()", "0x64325ddb": "currentClaimPrice()", "0x2fc0aad3": "isNumericString(string)", "0xbc45d789": "setConfigUint(int256,bytes32,uint256)", "0xee95feaf": "isSeller(address)", "0x358d5dc2": "getIsCashed(uint256,uint256)", "0x1397fdbd": "getShares(address,bytes,int256[])", "0x2d8c1c35": "level_up()", "0x24600fc3": "withdrawFunds()", "0x05f8b6f5": "_rewireIdentities(bytes32[],uint256,uint256,uint32)", "0x1840f0ca": "countVotes(uint256)", "0xd44aadf7": "initROS()", "0xca1d209d": "fund(uint256)", "0x5fa513d5": "findPtr(uint256,uint256,uint256,uint256)", "0x3c314a91": "playerGetPendingTxByAddress(address)", "0xd5582205": "getCertifiedStudentAtIndex(uint256)", "0xe45ebe93": "checkVoteStatus()", "0xcd9380d5": "testSetBalanceSetsSupplyCumulatively()", "0x637e86eb": "totBOTs()", "0x5bb47808": "setFactory(address)", "0x674cc1f5": "getMarketHashes(bytes32[])", "0x648bf774": "recover(address,address)", "0x0221038a": "payOut(address,uint256)", "0x4016535a": "parseBlock(bytes,uint256)", "0xa3908e1b": "convert(uint256)", "0xd9e7ee1c": "new_game(uint256,uint256)", "0x929e626e": "getShareDistribution(bytes32)", "0xa20495d3": "Managed()", "0xd409ddda": "EtherizationUtils()", "0xcb2b9031": "addressToBytes(address,address)", "0xfff3c457": "readMessages(uint256)", "0x043753ba": "makeDecision(uint256,bool)", "0x85b4bb53": "getSettings()", "0x60726abb": "copy()", "0xe50d0473": "SetRank(uint8,address,uint16)", "0x54ae8492": "CustodialForward()", "0xd6d02c51": "whois(string)", "0xcb712535": "_transferFrom(address,address,uint256)", "0xb152f19e": "getFirstSchedulableBlock()", "0x9334ab61": "Infos()", "0x88a49164": "testErrorUnauthorizedTransfer()", "0x17db59a4": "dEthereumlotteryNet(address,address,address)", "0xf85aefba": "testBitsSetFailIndexOOB()", "0xae99847b": "daylimit(uint256)", "0xd93e7573": "disown(bytes32)", "0xa5468081": "Pyramid(address)", "0x00e7d289": "registerListening(address)", "0x57ee24af": "getNum(bytes32,uint256)", "0xdaea85c5": "approve(address)", "0x36ffa905": "getMyProposals()", "0x7143059f": "getParticipant(address)", "0x55ff440a": "castStringToUInt(string)", "0x6a4a6b6e": "_myAddressHelper()", "0xb67fabdf": "scheduleTransaction(address,uint256,uint256,bytes)", "0xbcca1fd3": "changeVotingRules(uint256,uint256,int256)", "0x1d3390a1": "carefulSendWithFixedGas(address,uint256,uint256)", "0x45104b16": "EXECUTION_GAS_OVERHEAD()", "0xa26759cb": "addFunds()", "0x232523e8": "forceDivestOfAllInvestors()", "0x7e904a48": "getNumContents(uint256)", "0xb69c0896": "BaseScheduler(address,address,uint256)", "0xc6ed8e1b": "getApprovedProxys()", "0x4d1f8c31": "owner(uint64)", "0x17c65aa7": "getMaxLossAfterTrade(address,uint256,int256,int256)", "0x2c02d622": "precalculate()", "0xa035b1fe": "price()", "0x43b0e8df": "set(uint256,uint256,uint256)", "0x9b5fde7d": "payOut(uint256,string)", "0x89fcd099": "getApproval(address,address)", "0x4c0eceb5": "plusOnePonzi()", "0x880cdc31": "updateOwner(address)", "0xdab80d6f": "addSponsor(address)", "0x0fcda174": "getAccountTokenBalance(address,address)", "0xa55cab95": "getName(uint8,uint8)", "0x934db458": "Big()", "0xeb782d8c": "ContentSeries(address)", "0xdbfef710": "getDefaultRequiredGas()", "0x4f09eba7": "proxyApprove(address,uint256,bytes32)", "0xf4c5ab7c": "validateCallGas(uint256,uint256)", "0x376fe102": "userId(address)", "0x922dd59a": "icapTransfer(bytes,address,bytes,uint256)", "0x7318b453": "setVotetUntil(uint8)", "0xb8c86aa6": "getArraySettingResult()", "0x37bdc99b": "release(uint256)", "0x7cbcc254": "__reset__()", "0x37664643": "retractLatestRevision(bytes32)", "0x4b031d0f": "shortSellShares(bytes,uint8,uint256,uint256)", "0xad8d5f48": "exec(address,bytes,uint256)", "0x2f95b833": "requiredStackDepth()", "0xe3848e5b": "thing(string,string,string)", "0xaa272d4b": "getNodeIndexId(bytes)", "0xd7f746ce": "tickingBomb()", "0x3b84edbd": "setRNG(address)", "0x1fb2f2a0": "testUpdateLatestRevision()", "0xb7fba4d3": "getProxy(address)", "0x4b8e1ba8": "isMinter(int256,address)", "0xba4c206e": "removeCertificationDocumentInternal(address,bytes32)", "0x884b5dc2": "fill(uint256[])", "0x88017e05": "setContribution(uint256)", "0x1ff517ff": "totalDebt(address)", "0xd0315658": "getShareDistributionWithTimestamp(bytes)", "0x7d03f5f3": "newGame()", "0xb7538f3e": "ChangeClient(address)", "0xbf4d89b5": "parseInt(string,uint256)", "0x7b55c8b5": "scheduleCall(address,bytes4,bytes,uint8,uint256[4])", "0x350d141e": "getWasApprovedBeforeDeadline()", "0x27960c5f": "validateEndowment(uint256,uint256,uint256,uint256,uint256,uint256,uint256)", "0xb774d3d7": "BankOwner_GetDonationsBalance()", "0x267b6922": "entries(bytes32)", "0x08b7c13b": "getExists(bytes20)", "0x7e7a2fbf": "contribute_toTheGame()", "0x5b86914d": "bet_value()", "0x0e1087c3": "getMarketMakerFunds()", "0xf7149220": "RNG()", "0x345006b6": "getGenerationForCall(address)", "0xc4b14e0b": "getSignature(bytes32)", "0x419945f8": "ExpiringMarket(uint256)", "0x41868769": "CallAborted(address,bytes)", "0x29092d0e": "remove(address)", "0x746c9171": "m_required()", "0x5020dcf4": "convertToEach(uint256,string,uint256)", "0xa06db7dc": "gracePeriod()", "0xbf8fc670": "sendToAggregation(uint256)", "0xf14fcbc8": "commit(bytes32)", "0xa538d287": "getMinMax()", "0xcae523c1": "testOwnedTryAuthUnauthorized()", "0x04d10f1c": "isValidChainyJson(string)", "0x9ba5b4e9": "getEventHashes(bytes32[])", "0xfedfd535": "Config()", "0x42ce0f30": "testThrowUpdateLatestRevisionNotOwner()", "0x31be6985": "testBitXorSuccess()", "0x173cb7de": "getNumReleasesForNameHash(bytes32)", "0xd90a88cd": "getContentReplies(uint256,uint256)", "0x92eefe9b": "setController(address)", "0x052b81c7": "releaseBadges()", "0xb2855b4f": "setFeeAddr(address)", "0x19a9c2f1": "generateId(string)", "0xfa9acb05": "addressInArray(address,address)", "0x3da5c3ce": "puzzle(address,bytes32)", "0x7a427d98": "forceReturn()", "0x70e71ea3": "etherandomSeedWithGasLimit(uint256)", "0xd7a58658": "changeHouseedge(uint8)", "0x72b75585": "getOriginalClient()", "0xf802075f": "requiredEndowment()", "0x7997b997": "doMelt(uint256,uint256)", "0x6d5433e6": "max(uint256,uint256)", "0xb651cbaf": "add_level(address,bytes)", "0xb4d6d4c7": "getPackageData(bytes32)", "0x90e3c278": "getShares(uint256[128])", "0x179b73da": "killBoardProposal(uint256,address)", "0xc944a38e": "CharlyLifeLog(string,int256)", "0xe1c66292": "Create(uint32,address)", "0x69c8b344": "ownedToken(address)", "0xabcf1328": "InterestBank()", "0x532e7e6a": "calcEarningsSelling(bytes,uint256,uint256[],uint8,uint256)", "0x43d24a5e": "addUpdater(address)", "0xd1feca67": "addSpendingRequest(address)", "0x2d34ba79": "setup(address,address)", "0xcb14d93b": "getHash(bytes,address,uint256)", "0x309424fe": "get_all_names()", "0x96c52fc3": "____forward(address,uint256,uint256,bytes)", "0xde39acea": "get32(bytes,uint256)", "0xf3dd3d8a": "newCurrency(string,string,uint8)", "0x2432eb23": "testThrowRetractLatestRevisionNotUpdatable()", "0x7fcf3a2f": "throwFooBar()", "0xabe9f569": "oraclize_getPrice(string,uint256)", "0x41ee903e": "clear(uint256,uint256)", "0xd249a52e": "update(bytes,uint256[],uint256[])", "0xc3d014d6": "setContent(bytes32,bytes32)", "0x3ac5cb73": "GeometricPonzi()", "0x4a1aa767": "claim_victory(uint256,uint8,uint8,uint8)", "0xce592586": "setThresold(uint256,uint256)", "0x63deb2c5": "changeMemberAddress(address)", "0x2e6e504a": "trusteeWithdraw()", "0xcfed9199": "timePassed(uint256)", "0xb782fc9b": "getFirstActiveDuel2()", "0x35b28153": "addAuthorization(address)", "0x46f7a883": "BuyTicket(uint8,uint8,uint8)", "0x83c51a38": "thesimplegame()", "0xfa28ba0d": "validateReleaseLockfileURI(string)", "0xa7b2d4cb": "remove(int256,address)", "0x010731c0": "sendCryptedHand(bytes32)", "0xe9e99d81": "getChannelFeed(address,uint256,uint256,uint256)", "0x4e30a66c": "safeToAdd(uint256,uint256)", "0x2c4e591b": "totalGames()", "0xa3221c8e": "step8()", "0x783ce458": "expmod(uint256,uint256,uint256)", "0xe417291b": "undelegateDAOTokens(uint256)", "0x8e5d97a2": "releasePendingTransfer(uint256)", "0xbc5ff5e1": "oraclize_query(string,string[4],uint256)", "0x38f77d69": "getDistributeProfitsInfo()", "0xbb510a77": "createChannel(address,uint256)", "0x650955d4": "HashToken()", "0xa8484938": "doApprove(address,uint256)", "0x64ed31fe": "authVotes(address)", "0xf7ae9421": "checkInvestorBalance(address)", "0xba904eed": "removeRegistrar(address)", "0xdce4a447": "at(address)", "0xdb4cacec": "Other()", "0x3647b87a": "buildFactory()", "0xa51aea2d": "changeMaxMultiplier(uint256)", "0x4974bc27": "download()", "0xf8a8fd6d": "test()", "0xd8c90762": "addTrustedIssuer(address,string)", "0xdf6c13c3": "getMinFunding()", "0x867904b4": "issue(address,uint256)", "0x1531c267": "fipsRegisterMulti(uint256,address,bytes)", "0x40a49a96": "searchSmallestInvestor()", "0x61bffe01": "addIdentities(bytes32[],bytes32[])", "0xf77a0923": "BitcoinProcessor(address)", "0xd02528e6": "GetGameIndexesToProcess()", "0x9f927be7": "getNextCall(uint256)", "0xd8162db7": "lockedUntilBlock()", "0x36dfe260": "payOneTimeReward()", "0xc5b1a53c": "deposit(bytes16[],uint64)", "0xc2b6b58c": "isClosed()", "0xc88cc6ac": "getCertification(address)", "0x77ac3da5": "oraclize_query(uint256,string,string[1],uint256)", "0x70ab8ba8": "creditUpdate()", "0xd3ea3322": "testBuildTokenSystemCost()", "0x72388610": "paybackAll()", "0xca6d56dc": "addMember(address)", "0x0994a0a0": "DSTokenTest()", "0xe53e04a5": "refillGas()", "0xc1d5e84f": "addNewUser(address)", "0x89ed0b30": "setOraclizeGas(uint32)", "0x02ba8742": "sendCoins(address,uint256)", "0xb0de1cb7": "publish(uint64,bytes,uint64)", "0x0e13b9af": "getValue(uint8,uint8)", "0xb3dfcdc3": "Contribution(uint256)", "0xa9b35240": "packageExists(bytes32)", "0xd1d3bb92": "testSetPkg()", "0x97297467": "checkAndVerify(bytes)", "0xe31bfa00": "next_id()", "0x9948e493": "calcMarketFee(bytes,uint256)", "0xd148288f": "setHoldingPeriod(uint256)", "0xc032dc30": "execute(uint256,address)", "0xdad99989": "burnCoins(address)", "0xb1999937": "leapYearsBefore(uint256)", "0xa6cbcdd5": "numSignatures(bytes4)", "0xaca66aec": "DVIP()", "0x20bf0c52": "Derived(uint256)", "0x693ec85e": "get(string)", "0x0411bca8": "getChallengeAnswerResult(uint256)", "0x61584936": "sealedBids(bytes32)", "0x2f1927cb": "prepareRoll(uint256,uint256,uint256)", "0xeaa1f9fe": "reqisterListening(address)", "0xb623f5e5": "checkSetCosignerAddress(address)", "0xa88c5ef7": "NextPayout()", "0x66ad484c": "newfirst_player(address)", "0xb4022950": "collectFeesInEther(uint256)", "0xbff0fbb8": "calculateMeat(uint256)", "0xd62b255b": "setOwner(address,string)", "0x2fd6d40b": "getBetValueByGamble(uint8)", "0x3b0506f7": "getVoteByAddress(address,uint256)", "0xbddd3a6b": "step7()", "0x67fbd289": "destroyTokens(uint256)", "0x9844347b": "createCertificate(bytes,bytes,uint256,bytes)", "0x5e68ac2c": "Kingdom(string,address,address,address,uint256,uint256,uint256,uint256,uint256)", "0x8ba9f354": "testClearBitSuccess()", "0x48027610": "transferPaidOut(address,address,uint256)", "0x912de8de": "fixBalance()", "0x04509918": "scheduleCall(address)", "0x7cf0ffcb": "forceDivestAll()", "0x3b3b57de": "addr(bytes32)", "0xeb7c6f72": "step6()", "0xfe6f0d82": "testConstructorEvent()", "0x55b62dcf": "getThresold(uint256)", "0xfbae5e7d": "Investors(uint256)", "0x29e206bd": "forceDivestAll(bool)", "0x6a226a49": "addMessage(string)", "0x8e2a6470": "allocateShares(address,uint256)", "0xe6e7237f": "claim_time_victory(uint256)", "0x17a601b5": "MAX_STACK_DEPTH_REQUIREMENT()", "0x87fd0421": "TheEthereumLottery()", "0xc17e6817": "sendSafe(address,uint256)", "0xa5dfee67": "testThrowsCreateNewRevisionNotUpdatable()", "0xb35893f3": "setExporter()", "0x1ceea715": "GetMyInvestFee()", "0xb78bd4a5": "breakCookie(string)", "0x05215b2f": "createStandardToken(uint256)", "0x2632bf20": "unblockMe()", "0x5292af1f": "sendBalance(address)", "0xc2e9fab3": "SubUser()", "0x6493d7fc": "CircuitBreaker(address,address,uint256,uint256)", "0x4f896d4f": "resolve(uint256)", "0x16870257": "getTileDescription(uint8,uint8)", "0x3ef87414": "getRevisionCount(bytes20)", "0x747586b8": "setInt(int256)", "0x5714f6a1": "getTotalAvailableRelays()", "0x99154b49": "ARK()", "0x1efb17ee": "changeHouseAddress(address)", "0x354d7e40": "Payout()", "0x2da0d1ea": "etherSold()", "0xea46193e": "getEtherBalance()", "0x11fe773d": "memcpy(uint256,uint256,uint256)", "0x1e701780": "MICRODAO(address,uint256,uint256,uint256,address)", "0x1c31f710": "setBeneficiary(address)", "0x0a4caed0": "getChannelByRank(address,uint256)", "0xf3125a1f": "deposit(address,uint256,bytes,uint256)", "0x00e46700": "setMinimumPassPercentage(uint8)", "0x92d282c1": "Send()", "0x89d59ee5": "createPersonalDepositAddress()", "0xbe1c766b": "getLength()", "0x70a08231": "balanceOf(address)", "0xae0a6b28": "signature(string,bytes32)", "0xb3485dca": "UpdatePrice(uint8,uint32)", "0xf8ec4bf2": "setAllowTransactions(bool)", "0x53d97e65": "setPrizes(uint32[])", "0xd1b1a22b": "set(string,uint256[],uint256[],uint256[],bool[],uint256[])", "0x96286cc9": "isTokenOwner(address)", "0x154af6b1": "sendShares(uint256,uint8,uint256,address)", "0xbe2430fe": "sendValues()", "0x57a373a1": "uintInArray(uint256,uint256,int256,uint256[],uint256)", "0x8fd28bcf": "testFailAuthorityAuth()", "0x89ef40e7": "numberOfHealthyGenerations()", "0x23e9c216": "setBounty(address,string,uint256)", "0x71dd99fe": "BigRisk()", "0x1e9fcc77": "activateAllowance(address,address)", "0x561e91a1": "makeBet()", "0x32d2fb9f": "getRefRemainingTime(uint256)", "0x992c870d": "transferName(bytes,address)", "0x6b3fdc5a": "oraclize_setNetwork(uint8)", "0x2ea459b8": "claimThrone(bytes)", "0x33a99e04": "selectWinner()", "0x3b49a77b": "hasConfirmed(bytes,address)", "0xa352f1a8": "calcSHA3(bytes)", "0x4bb4b260": "cashAllOut()", "0xb89a73cb": "isShareholder(address)", "0xba5a2d33": "exitPool(address)", "0xddd41ef6": "transferDirector(address)", "0xa06cab79": "Registrar(address,bytes32)", "0x871113c3": "oraclize_query(string,string[1],uint256)", "0x1f0f711f": "discontinue()", "0x632f0ba6": "descriptionHashes(bytes)", "0x980e8c81": "FutureBlockCall(address,uint256,uint8,address,bytes,uint256,uint256,uint256)", "0x4ae8c55f": "getWwLength()", "0x82fc49b8": "setCosignerAddress(address)", "0xc4bd8ebc": "num_monsters()", "0x0381cb3b": "setRowcol(uint256,uint256[2])", "0x124eaee6": "Identity()", "0x3f4be889": "callContractAddress()", "0xef3a6031": "testBaseToken()", "0x954ab4b2": "say()", "0x1b855044": "getHash(uint256,uint256)", "0xd9d73887": "Diana()", "0x5103a5a3": "certify(address,bytes32)", "0x51560da9": "topDogInfo()", "0xf3ee6305": "removeCertificationDocument(address,bytes32)", "0x049ae734": "scheduleCall(address,bytes4,uint256,uint256,uint8)", "0xd8a8e03a": "move(uint256,address)", "0xc3c5a547": "isRegistered(address)", "0x06005754": "nameRegAddress()", "0xbe592488": "validateName(bytes)", "0x0eecae21": "draw()", "0xac3e7d24": "addChainyData(string)", "0xfd83f3e3": "QueueUserMayBeDeliveryDroneCotnrol()", "0x7772a380": "isInGeneration(address,uint256)", "0xeb1ff845": "changeId(uint256,uint256,uint256)", "0x9cc9299e": "killSwap()", "0x1e2ca0f3": "updateLeftLottery(address)", "0x998446a8": "acceptRequest(uint256,bytes)", "0x8e1ffb19": "testThrowsRetractLatestRevisionEnforceRevisions()", "0x9935935f": "setResolveHandler(bytes,address)", "0xcd4b6914": "getRandom(uint256)", "0xc08dd1dc": "IOU(string,string,uint8)", "0xbe4054b9": "commitReading(address,uint256,uint256,string)", "0xbc21ce9d": "Aggregation()", "0x6e173a7f": "storeBlockHeader(bytes,bytes)", "0x114d69b2": "setCRLaddr(address)", "0x3fa4f245": "value()", "0x69573648": "remove(bytes,bytes)", "0x7fee4ecb": "GAS_PER_DEPTH()", "0x591c515f": "append(string,string)", "0x727b1cd6": "next_draw(bytes32,uint256,uint256,uint256,uint256,uint256)", "0xc60ce271": "findNextMinute(uint256,bytes)", "0xd337616e": "resetLottery()", "0xdacaeb07": "pledge(bool,uint256)", "0xb29c2493": "token(uint256,string,uint8,string)", "0x61047ff4": "fibonacci(uint256)", "0x8f367001": "numTokensAbleToPurchase()", "0x12cc08f2": "getPackageReleaseHashes(string,uint256,uint256)", "0x67a59d91": "scheduleCall(address,bytes,bytes,uint256,uint256,uint8)", "0xe6c3b4ab": "testBalanceAuth()", "0xd526b9bd": "_allow()", "0x29de91db": "setMsg(address,uint256)", "0xd1cf113e": "multiAccessSetRecipient(address)", "0xc2412676": "Token()", "0x391f2e96": "InvestCancel()", "0xc0ae6a3a": "ultimateOutcomes(bytes)", "0x202d6eaf": "addInvestorsValue(uint256)", "0x30b9af98": "withdrawFunding()", "0xe80bd3e5": "addCertificationDocumentToSelf(bytes32)", "0xf4e36afd": "findThroneByNameHash(uint256)", "0x30677b83": "multiplierFactor()", "0x590528a9": "sellShares(uint256,uint8,uint256,uint256)", "0x01cceb38": "setExpiry(uint256)", "0x779beca0": "getNumOfSalesWithSameId(bytes)", "0xac940823": "betOnLowHigh(bool)", "0x06961560": "DAO(address,uint256,uint256,uint256,address)", "0xd42bf301": "doTriggerTryAuth()", "0xfa566ddd": "doAllowance(address,address)", "0x6677febe": "get_all_accepted()", "0xaa67c919": "depositFor(address)", "0xf28386bf": "Nexium()", "0x77e4fb04": "testFailNotEnoughValue()", "0x12b58349": "getTotalBalance()", "0xc0d2834b": "DataSource()", "0x3e82055a": "addSignature(uint256,bytes16,bytes)", "0xcff2fa42": "_returnFee(address,uint256)", "0xa056469a": "extractFeeLength()", "0xc98031be": "hintURL(int256,bytes32,string)", "0x6ebbe863": "updatePublishContract(address)", "0x08216c0f": "createHumanStandardToken(uint256,string,uint8,string)", "0xc36af460": "getLatest()", "0xdb5b4183": "oracleOutcomes(bytes,address)", "0x0b5ab3d5": "destroyDeed()", "0xe1c7392a": "init()", "0x4ca1fad8": "addRequest(uint256)", "0x305b73d9": "configure(address,address,uint256,uint8,bytes32,bytes32)", "0x9077dcfd": "submitCoding(string,uint256)", "0x38fff2d0": "getPoolId()", "0x07bc6fad": "withdraw(address,uint256,bytes32,uint256)", "0xfbf58b3e": "transfer(string,address)", "0x1d8b70da": "order_received(string)", "0x0b3ed536": "claimDonations(uint256)", "0x6f374a12": "setBool()", "0x0ca35682": "recover(uint256)", "0x3ae7cdfa": "fipsLegacyRegister(bytes20[],address)", "0xe6c1beb4": "prepend(address)", "0x776d62f6": "costs()", "0xe4690a0b": "popRequest()", "0x74eb9b68": "isAccountLocked(address)", "0x7d32e7bd": "transfer(address,bytes32)", "0xdf2f0a4a": "getDecisionBlockNumber(uint256,uint256)", "0xc494f71a": "LedgerFund(uint32,uint32,uint64,uint64)", "0x446d5aa4": "getAttributes(address)", "0x4cdc6a73": "Marriage()", "0x677cee54": "SafeConditionalHFTransfer()", "0x7b48ba20": "testThrowDisownNotOwner()", "0x1288c42a": "Prism()", "0xe8b13c44": "getChainyTimestamp(string)", "0xe4c2db06": "getPreviousFile(bytes)", "0xf0586f0d": "doThrow(bool)", "0xc1b06513": "registerEvent(bytes32[])", "0x521eb273": "wallet()", "0x32254992": "getPrevHash(int256)", "0x1fd96b69": "ManagedAccount(address,bool)", "0xabf74a93": "pitFee()", "0xa480ca79": "collectFees(address)", "0xa0bde7e8": "getShareDistributionWithTimestamp(bytes32)", "0xff27c476": "shiftBitsRight(bytes,uint256)", "0x172d8a30": "setDirectorLock(uint256,uint256)", "0xf262de8c": "add_staircase(uint16)", "0x990f3f53": "computeResponseSecondHalf(uint256,uint16)", "0x26745909": "PRNG_Challenge()", "0xcacc24eb": "transferFromViaProxy(address,address,address,uint256)", "0x94f3f81d": "removeAuthorization(address)", "0x3f0ec70b": "RequestFactory(address)", "0xa2a8336f": "claimEtherSigner(uint256)", "0xaa5d4719": "getTransferable(bytes20)", "0x23cd7cd5": "Model()", "0x3fb0b2c9": "CancelRoundAndRefundAll()", "0xd5fa2b00": "setAddr(bytes32,address)", "0xa0f61310": "FakeRelay(bytes)", "0x4ea66c38": "buyinInternal(address,uint256)", "0xbe040fb0": "redeem()", "0xb845c9a2": "WEI()", "0x26a7985a": "getMaximumCallGas()", "0x06661abd": "count()", "0xc89f8f08": "testGetController()", "0x81baf820": "BlockScheduler(address)", "0x9801cb8e": "ProofOfExistence()", "0xeb7492d1": "testTotalSupply()", "0x3dfb4843": "renewDeed(bytes32)", "0xc3fa5f93": "BlockScheduler(address,address)", "0x7958533a": "meta(uint256,bytes32)", "0xa1a66e56": "deductFunds(uint256)", "0xaf92a693": "addRegistrar(address)", "0xb2aac51f": "lookupUser(string)", "0xd70cf105": "moveBalance(address,address,uint256)", "0x2afb21bc": "InvestWithdraw()", "0x6d09e2ec": "commitCurrency(address,uint256,uint256)", "0x7b1a4909": "transferETH(address,uint256)", "0x96c824a8": "createAccountFundContract()", "0xe0a70811": "restart(bytes20,bytes)", "0x22057bc7": "getAllRevisionBlockNumbers(bytes20)", "0x6af2da2f": "testKeyedHash()", "0x7f6d8955": "RegisterOne(uint32,address,address)", "0x65f27bea": "testSubBalanceFailsBelowZero()", "0xa2f16d80": "dexWithdrawCollectedFees()", "0xc179520c": "ManageAccount()", "0x2672b3e2": "SplitterEtcToEth()", "0xe839e65e": "query2(string,string,string)", "0x39f64b52": "calcTokenPrice()", "0x4ef5710a": "WatchNumberOfPlayerInCurrentRound()", "0x3017fe24": "callAPIVersion()", "0x2977b1b1": "testAllowanceStartsAtZero()", "0x531c1b33": "getOperatingBudget()", "0xb7f2f33c": "transferRightIfApproved(address,bytes)", "0x00873367": "comparisonchr(string)", "0x2a0d79ef": "totalSupply(bytes)", "0xa715ff59": "EtherandomProxy()", "0xd6ca8ccb": "disown(bytes20)", "0x6ad2a0b3": "buildContract(address)", "0x45596e2e": "setFeeRate(uint256)", "0x0e97cfdf": "placeOrder(uint256,uint256,uint256)", "0x9549355e": "oracalizeReading(uint256)", "0x8d7af473": "numberOfProposals()", "0x728af7ec": "getInterest(uint256,uint256)", "0x11b9fee8": "ForkChecker(uint256,bytes32)", "0xd850288b": "etherlist_top()", "0xf4dc2d21": "Deed(uint256)", "0xf8b11853": "getGenerationStartAt(uint256)", "0x7c7a52bf": "newChallenge(uint256,address)", "0xd2d4bd72": "getCrossRate(bytes,bytes)", "0xe9b93569": "OwnerGetFee()", "0xfb72d24e": "shift_right(uint64,uint256)", "0x112e39a8": "scheduleCall(uint256)", "0x6c494843": "multiAccessChangeOwnerD(address,address,address)", "0x313ce567": "decimals()", "0x9bac8602": "testFailAddBalanceAboveOverflow()", "0xa70a9ad7": "switchDeity(address)", "0x6a61e5fc": "setTokenPrice(uint256)", "0x990c8f79": "returnValue()", "0xa4136862": "setGreeting(string)", "0x0af4626d": "testRetract()", "0x5e11544b": "newPeriod()", "0xdc206e5f": "oraclize_query(uint256,string,string[])", "0xcaa648b4": "getTotalValue()", "0x20bfec70": "WatchFees()", "0x62a0b56b": "testUnset()", "0x42f6e389": "isModule(address)", "0x769796fe": "resetAction(uint256)", "0x402e6230": "getTotalGambles()", "0xe8a1c08f": "nibbleToChar(uint256)", "0x1aa3a008": "register()", "0x96d02099": "rsplit()", "0x83324e8c": "numGroups()", "0x72c7c85a": "minority()", "0xb8d94b95": "buildDSNullMap()", "0xe039e4a1": "getOwner(uint8,uint8)", "0x625cc465": "baseDonation()", "0x77372213": "setName(bytes32,string)", "0xa7dfc874": "unregister(bytes,address,uint256,bytes)", "0x37f4c00e": "anchorGasPrice()", "0xb2bfd948": "checkNumbers(uint8[3])", "0x512f1e64": "orderBookLength()", "0xafed762b": "toSlice(string)", "0xbb6a1427": "testThrowRestartEnforceRevisions()", "0x734d8287": "unclaimedFees()", "0xf295206f": "_unsafeSend(address,uint256)", "0x69d01268": "concatUInt(uint256)", "0x0494630f": "oraclize_query(uint256,string,string[4],uint256)", "0x13fc6ac2": "getEventData(bytes32)", "0xbff974e8": "getContentReplies(uint256)", "0x18921de4": "addSignature(string,uint256[],uint256[],uint256[],bool[],uint256[])", "0xa87e7552": "isValid(bytes,bytes)", "0xb8d3bfe3": "MeatGrindersAssociation(address,address,uint256,uint256,uint256,address)", "0x61461954": "execute()", "0xecb0256b": "relayTx(bytes,int256,int256[],int256,int256,bytes,int256,int256[],int256,int256)", "0x7cdbae63": "addRegistryIntoTagsIndex(address)", "0x1f4e996b": "challenge(bool)", "0x0eb0afa6": "createDebt(address,address,uint256)", "0x5f6a1301": "clearPending()", "0x305a762a": "getTicketsCountByBuyer(uint256,address)", "0x724ae9d0": "getMinInvestment()", "0x1e39499d": "scheduleCall(address,bytes,uint256)", "0x4f197ee7": "transferPackageOwner(string,address)", "0x7e3faec1": "GoldTxFeePool(address,address,bytes)", "0x8d68cf59": "sendFunds()", "0x83eed3d5": "queryN(uint256,string,bytes)", "0x15c91115": "pbkdf2(bytes,bytes,uint256)", "0xeb121e2f": "update(uint256,uint256[101][])", "0x5e44daf3": "vote(uint256,int256)", "0xac562666": "freezeCoin()", "0xb0166b04": "testTransferringMkr()", "0x631de4d6": "replace(address,address)", "0x4bd70ea3": "testFailGetUnset()", "0xf738e5ca": "ownerTakeProfit()", "0xc6236a5c": "scheduleCall(bytes,uint256,uint256,uint8,uint256)", "0x119aa5c8": "checkForward(bytes)", "0x541aea0f": "put(uint256,uint256)", "0x6386c1c7": "getUserInfo(address)", "0x4e209678": "testFailBreach()", "0xe9fe799e": "registrantRemove(address)", "0x2aee19c7": "testCreateWithNonce()", "0xa0ec4e09": "getUltimateOutcomes(bytes32[])", "0x4d9e4e22": "Etheria()", "0xa6b513ee": "finalPrice()", "0x82f0d875": "makeHash()", "0x78ae88d1": "newDeal(uint256,uint256,uint256,uint256,uint256)", "0x177766e6": "getOptionChain(uint256)", "0xf1173928": "RemovedFromGeneration(address,uint256)", "0xea2ea847": "testChallengeFinalize()", "0xbd35d570": "GAS_TO_COMPLETE_EXECUTION()", "0x364ea9e7": "set(uint256,uint256,bool[],uint256[])", "0x17ff0caa": "WeatherBet(uint256,address,address,address)", "0x4e23a144": "fundUser(address,uint256)", "0x144267e0": "refundSecurity(address,uint256,uint256)", "0x31c6c4cf": "transferFromWithReference(address,address,uint256,bytes32,string)", "0x2eb5c61f": "testThrowsUpdateLatestRevisionEnforceRevisions()", "0xde640e19": "Investment(uint256)", "0x9cb8a26a": "selfDestruct()", "0x9c43d950": "registration(uint256,uint256,uint256)", "0xe2fdcc17": "escrow()", "0xc618d15f": "ConvertNumbers(bytes5)", "0x8c98117c": "getBill(uint256,uint256)", "0x2d7788db": "rejectRequest(uint256)", "0xfaab9d39": "setRegistrar(address)", "0xa289673b": "fipsChangeOwner(bytes20,address,address)", "0x54d9d6f8": "findNextDay(uint256,bytes)", "0x008a745d": "claimDividendShare(uint256)", "0x6f4812e2": "testFailControllerInsufficientFundsTransfer()", "0x5e983d08": "setPrices()", "0x798974dd": "getNumProposals()", "0x4ca168cf": "register(bytes,uint256,address,string,uint256)", "0xa1e4d3c2": "MembershipRoster()", "0xd4065763": "returnRemainingMoney()", "0x0c4326a0": "getMajorMinorPatch(bytes32)", "0xeece1e1f": "scheduleShuffling()", "0x226685ee": "Visit()", "0x323082d7": "Vote(string)", "0x0b15650b": "randInt(uint256,uint256)", "0xc9cfac55": "refundCurrency(address,uint256,uint256)", "0xfe4a3ac9": "setExecPrice(uint256)", "0x6a0e605f": "MyToken(uint256,string,uint8,string,address)", "0xb549793d": "scheduleCall(bytes4,bytes,uint256,uint256,uint8,uint256)", "0x85e68531": "revokeAccess(address)", "0x01991313": "scheduleCall(address,bytes4,uint256)", "0x0a6be0e7": "BalancedPonzi()", "0xf463edd1": "createDocument(uint256)", "0xa20c404f": "ModifySettings(uint256,uint256,uint256,uint256,uint256,uint256,uint256)", "0x560bb612": "SignatureValidator(address)", "0xf7654176": "split()", "0x48f05187": "scheduleCall(address,bytes4,bytes,uint256)", "0xf2b904c3": "checkBetColumn(uint8,address,bytes32,bytes32)", "0x7bc0ff20": "setupExportFee(address,uint256)", "0xeb06e65e": "allowanceFromProxy(address,address,address)", "0xfe757fb5": "lastClaimPrice()", "0xa5d0bab1": "buyPartial(uint256,uint256)", "0xda7d0082": "isCertification(address,bytes32)", "0xe570be18": "DVIPBackend(address,address)", "0x54738157": "OwnerCloseContract()", "0xc1e5304a": "CreateNewDraw(uint256,bytes)", "0x0c26e42e": "getReleaseHashForNameHash(bytes32,uint256)", "0x0f7d6673": "Channel()", "0x54ea4000": "identify(address[])", "0x69307c80": "rotateBits(bytes,int256)", "0x78f0161a": "setGreyGreenPrice(uint8)", "0x23b872dd": "transferFrom(address,address,uint256)", "0x578bcc20": "reduceDebt(address,address,uint256)", "0x59e148fc": "getLastOfferId()", "0xb5299ca6": "giveMeat()", "0xae30d35d": "ARK_TROGLOg_1_00()", "0x2d2c44f2": "Vault()", "0xce19419b": "testThrowsSetNotUpdatableNotOwner()", "0xffcf21a9": "eventOracles(bytes,uint256)", "0xf46c50dc": "doFail()", "0x73b55eaf": "registerData(address,int256,bytes32,address)", "0x53770f9a": "isStateless()", "0x4d47feaa": "ShareholderDB(uint256)", "0x40b31937": "pledgeDecline(uint256)", "0x01cb3b20": "checkGoalReached()", "0x62e05175": "setMotionDB(address)", "0xf362d78f": "testBitNotEqualSuccess()", "0xd2531590": "CANCEL_EXTRA_GAS()", "0x9a92b7e7": "EthVenturesFinal()", "0x79b0797c": "AmIPlayer1()", "0x6241bfd1": "Token(uint256)", "0x94a1710d": "testNonOwnerCantBreach()", "0xb466b76f": "fresh()", "0x4a5dddd2": "proxyPurchase(address)", "0xc0a1a949": "x15()", "0xc3b8bfe5": "transferIfNoHF(address)", "0x4a7e049e": "getFullCompany(address,uint256)", "0x481b659d": "permitPermanentApproval(address)", "0x16ce8a69": "setBuilding(uint256,uint256)", "0x1593a8c7": "endLottery()", "0x078c3fa4": "_transferToICAPWithReference(bytes32,uint256,string)", "0xfa3f1e99": "testBlobStoreRegistered()", "0x0b9e9817": "CanaryV7FastTestnet()", "0x6663bbec": "orderMatch(uint256,uint256,int256,uint256,uint256,address,uint8,bytes,bytes,int256)", "0x273bc3c9": "numberOfThrones()", "0x3c84f868": "set(int256,address,uint256)", "0x1ac61e8c": "testBlobCreate()", "0x5ccc3eaa": "roundMoneyUpToWholeFinney(uint256)", "0x0ccec396": "getNumReleases()", "0x6ac6205c": "addDataPoint(int256,uint256,bool,string)", "0x1d124fe4": "setUtils2(address)", "0x4c471cde": "scheduleCall(address,bytes4,bytes,uint256,uint256,uint8,uint256)", "0x52a554a1": "voteBoardProposal(uint256,address,bool)", "0x745a8be2": "flip32(bytes)", "0xbac1e2e0": "testBitsAndSuccess()", "0x25fda176": "notify(address,uint256)", "0x3b8e6f2e": "balanceAt(address,uint256)", "0x60585358": "getByte()", "0xc853c03d": "newDraw(uint256,uint8[3],uint256,uint256,uint256,uint256)", "0x741273d6": "testThrowRegisterContractAgain()", "0x8f2c44a2": "UnicornMilker()", "0x59d96db5": "terminate(uint256,string)", "0x483ba09e": "setBitcoinBridge(address)", "0x74fbbc86": "rate(uint256,uint256,string)", "0x83ea0620": "packageExists(string)", "0xd917deb5": "Donate()", "0x3fc6bc94": "payDAO()", "0x6558488a": "scheduleSetBool(address,uint256,bool)", "0x83e78b31": "bet(uint8,bool,uint8)", "0xeccb15bc": "SatPosition(int256,int256)", "0x7daa10ce": "getMyInfo()", "0x3e4565d2": "testErrorUnauthorizedNameRegister2()", "0x2143da91": "GameOfThrones()", "0xb29f0835": "doIt()", "0xdcc0ccf3": "Dao(address)", "0x70d53be5": "find()", "0x9a828a71": "oracalizeReading(uint256,string)", "0x6a6d31db": "externalEnter()", "0xf8b71c64": "rewardTo(address,uint256)", "0x0399c357": "assignFreeReadings(address,uint8)", "0x81ade307": "query(string,string)", "0xdb83694c": "getSaleInfo()", "0xa6bf3df0": "oraclize_query(string,string[2],uint256)", "0x29605e77": "transferOperator(address)", "0xf29d2f28": "setTokenHolder(address)", "0xa96f8668": "releaseTokens()", "0x8a3bc2bc": "iPropose(bytes,uint256,bool)", "0xd18611d6": "reactivate()", "0x7620a65b": "Publisher()", "0xa268b332": "testBitXorFailIndexOOB()", "0x6b1781b6": "Emergency()", "0x1003e2d2": "add(uint256)", "0x1209b1f6": "ticketPrice()", "0xe5a27038": "Pluton(uint256,string,uint8,string)", "0x22bc3b8e": "getArgument(uint256)", "0x47bdb7f4": "transferDisable(bytes20)", "0x13137731": "testThrowsUpdateLatestRevisionNotUpdatable()", "0x3f3935d1": "confirmReverse(string)", "0xecb4136e": "NotAnotherPonzi()", "0x49e347ae": "getContents(uint256[],uint256)", "0x669dafe8": "toWei(uint256)", "0xc233e870": "isLatestPatchTree(bytes32,bytes32)", "0x7b789b3d": "agreement(bytes,bytes,bytes)", "0x682d3bb0": "pdfCertificateProof(bytes)", "0x42346c5e": "parseInt(string)", "0x3177029f": "approveAndCall(address,uint256)", "0x71ffcb16": "changeFeeAccount(address)", "0xc971442c": "getDBs()", "0x362e2565": "returnDeposits()", "0xe10e274a": "CrazyEarning()", "0x6d705ebb": "register(address,uint256)", "0xbe9a6555": "start()", "0x1ce624d6": "Crypted_RPS()", "0x2c4cb4be": "removeRegistryFromNameIndex(address)", "0x68742da6": "withdrawFunds(address)", "0x18f3fae1": "setOversight(address)", "0x061ea8cc": "countByOwner(address)", "0xd6d22fa4": "MetaCoin()", "0x85654c9c": "setMembershipRoster(address)", "0x8aa33776": "setMsgPrice(uint256)", "0x4dd850fb": "UfoPonzi()", "0x07e00bcb": "kissBTCCallback(uint256,uint256)", "0xa1b7ae62": "setdirectorName(string)", "0xb4d9cc3a": "profitDisperser()", "0x0f24f5c8": "doTransfer(address,uint256)", "0x8d72a473": "deductFunds(address,uint256)", "0x28f03554": "ProcessDividend()", "0x98391c94": "muteMe(bool)", "0x346cabbc": "scheduleCall(address,bytes4,uint256,bytes,uint256)", "0xa42e36c6": "scheduleTransaction(address,bytes,uint8,uint256[5],uint256)", "0x21b36a08": "setFee(uint64,uint256)", "0xd94073d4": "PT()", "0xe8580dd4": "Survey(address,uint256,string,bytes32[])", "0x1f0c1e0c": "getEventTokenAddress(bytes32,uint256)", "0xce8b7151": "isHF()", "0x9bee757b": "requestExecution(bytes,uint256)", "0x775dec49": "keccak()", "0x6673ce2b": "Results_of_the_last_round()", "0x9f87acd0": "exec(bytes32,bytes32,uint256)", "0x02394872": "getLastBlockHeight()", "0x615664ba": "Market()", "0x0d7af726": "addGame(address,string,string)", "0xf4aa1291": "withdrawFundsAdvanced(address,uint256,uint256)", "0x8ed67a44": "setPrice(uint16)", "0x84ebde52": "Under_the_Hood()", "0x5a28340a": "accessOperatingBudget(uint256)", "0x9a89ad65": "within6Confirms(int256,int256)", "0xdfce8ac3": "fipsLegacyRegister(bytes20,address,bytes)", "0x73f310df": "multiAccessRemoveOwner(address)", "0x4cbee813": "logout(string)", "0xd992bd5b": "testResultNotZero()", "0x05b34410": "creationDate()", "0xfed4614b": "funeral(bytes,int256)", "0x58cb7323": "MainnetETCSurvey()", "0xbb504317": "divest(address,uint256)", "0x82381c96": "WatchCurrentMultiplier()", "0xcce81927": "EtherDice(address,address)", "0x70961774": "getBlockCreatedOn()", "0x84a7b223": "Canary(address)", "0x9378a9e2": "setUInt(uint256)", "0xe4360fc8": "getFileListElement(bytes)", "0xe597f402": "create(bytes1,bytes32,bytes)", "0x95d5a1be": "SignatureReg()", "0x33ce7787": "transferInvestorAccount(address,address)", "0x46c52b1a": "blockHexCoordsValid(int8,int8)", "0x3092afd5": "removeMinter(address)", "0x30945443": "update(address,string,string)", "0xc37ff3d9": "sha(uint256,uint256)", "0x29a6f31b": "oraclize_query(uint256,string,string[2],uint256)", "0x227f9633": "addOption(string,address,uint256)", "0x38eaf913": "setDirectorNode(string)", "0xab67aa58": "transferFrom(address,address,uint256,bytes)", "0x0ce3151c": "personUpdateRelation(uint256,string)", "0x216ef940": "proxyUpgrade(address,address,bytes)", "0x76bc21d9": "fireEventLog2Anonym()", "0xf004073a": "performAction(uint256)", "0xdba7ef7d": "Bookie(address,address)", "0xa0469b02": "inputToDigit(uint256)", "0x1d007f5f": "changeDAO(address)", "0x9dcb5c65": "resultsWeightedByEther()", "0x14ab9038": "setTTL(bytes32,uint64)", "0xf4d94699": "EndowmentRetriever()", "0xe74b9d11": "safeToSubtract(uint256,uint256)", "0xd7504385": "validateToAddress(address)", "0x57e2880d": "scheduleTransaction(uint256,uint256)", "0xe73a914c": "setDAO(address)", "0xc47bc007": "add_funds()", "0x37881810": "setCallbackAddress(address)", "0x686f2c90": "collectAllFees()", "0x278b8c0e": "cancelOrder(address,uint256,address,uint256,uint256,uint256,uint8,bytes32,bytes32)", "0xfac34ff6": "throwFoo()", "0x6d98e9fc": "totalWei()", "0xb0bcc610": "scheduleTransaction(address)", "0x665bcc32": "ProcessGames(uint256[],bool)", "0x3fd1f232": "LookAtAllTheseTastyFees()", "0xdd727ea6": "runJackpot()", "0x0acc4382": "getMinDailyWithdrawLimit()", "0x46b207b8": "checkExpiry()", "0xde5d953a": "logSingleIndex(bytes,bytes,uint256)", "0xf504e0da": "load_level(uint16)", "0x4b63e601": "scheduleCall(address,uint256,bytes)", "0x4a71d469": "collectRev()", "0x80db79d9": "StructAndFor()", "0x090637a1": "GetPart(bytes,uint256)", "0xc003b082": "getMyPlayerID()", "0x00a7d6b3": "checkTransferFromToICAP(address,bytes32,uint256)", "0xdcf8113e": "campaignEndedSuccessfully()", "0xd1af8a5a": "LinkerExample()", "0x01fd89a4": "getFlags(bytes20)", "0xa39a45b7": "replaceOwner(address)", "0x0a3b1cd2": "setHotwallet(address)", "0x075fe877": "scheduleCall(address,bytes,uint256,uint256)", "0x3e5fd9b5": "dEthereumlotteryNet(address,address,bool,address)", "0xa6403636": "resolve(uint8,bytes32,bytes32,bytes32)", "0x0b2acb3f": "add(address,bytes)", "0x6d522b19": "multiAccessChangeRequirementD(uint256,address)", "0x4311de8f": "ownerWithdraw()", "0xa99e7e29": "register(bytes,address)", "0x1ed6f423": "changeDescription(address,string)", "0xcd50d44f": "CheckRepresentment()", "0x4c0e207a": "__outputCallback(uint256)", "0xea8a1af0": "cancel()", "0x67387d6b": "testThrowCreateWithNonceExistingNonce()", "0xdc583801": "doubleyour5()", "0xb8077e28": "getTxOrigin()", "0xbfbc793c": "computeNameFuzzyHash(string)", "0x79baa8a9": "BasicIncome_CoFund()", "0xf4dbeb9d": "getCredRanksByContents(address,uint256[])", "0x227185d6": "Send1Get2()", "0x75c4aaa6": "addUnderDog(uint256)", "0xa7abc124": "activate(bool,bool)", "0x8df554b3": "Dividend()", "0x092b25e9": "setOwner(string,address)", "0x67af26fb": "transferOtherFrom(address,address,address,uint256)", "0x4bb278f3": "finalize()", "0xd1e15045": "sendBack()", "0xa4699cad": "resetWithdrawls()", "0xb61d27f6": "execute(address,uint256,bytes)", "0x9772c982": "scheduleCall(address,bytes4,bytes,uint256,uint256)", "0x1b3a8e6f": "directionCount(int256,int256,int256,int256)", "0xd499555b": "getFirstActiveDuel()", "0xb738169c": "betOnOddEven(bool,bool)", "0x411c4e72": "ModifyFeeFraction(uint256)", "0x06f36cc9": "helpBlue()", "0x9e65c7e5": "updateLatestRevision(bytes20,bytes)", "0xb47fa7e0": "DepositLimit(uint256)", "0xf1736d86": "m_dailyLimit()", "0x62ea82db": "bids(address)", "0x4166c1fd": "getElevation(uint8,uint8)", "0x8702735c": "setCapitol(uint256,uint256)", "0x3cc7790a": "GSI()", "0x83f6d9a4": "validateNameInternal(string)", "0x8d99b2eb": "endPoll()", "0x8bbda7e3": "setContent(string,bytes)", "0x52efea6e": "clear()", "0x2581c674": "testBitsOrFailIndexOOB()", "0x05d87fe2": "issueLetterOfCredit(uint256,uint256,uint256)", "0xcbf0b0c0": "kill(address)", "0xf83d96c1": "InsuranceAgent()", "0x8dd5e298": "canEnterPool(address)", "0x2d580ef6": "add(address,bytes32)", "0xeeda149c": "Register(address)", "0xcc25decd": "SampleOffer(address,bytes,uint256,uint256,uint256,uint256,uint256)", "0x428d64bd": "getShares(address,bytes32[])", "0x3c9a4baa": "requestOutput(bytes)", "0x8cae1374": "editBlock(uint8,uint8,uint256,int8[5])", "0x419db07b": "generousFee()", "0x202e3924": "getOperation(uint256)", "0x5ee345e4": "computeEndowment(uint256,uint256,uint256,uint256,uint256,uint256)", "0x7df23b6a": "ReleaseOracle(address[])", "0x9b2ea4bd": "setAddress(string,address)", "0x65093661": "newCommunity(address)", "0x33637d5a": "getPendingBlock(uint256)", "0x7910085d": "fipsIsRegistered(bytes20)", "0x730720b8": "testControllerValidTransfers()", "0xb0c80972": "setBalance(uint256,bool)", "0xdcf537b1": "multiply7(int256)", "0xdf5cc291": "get4(bytes,uint256)", "0x9ae4e388": "ChangeClientTokenAccount(address,bool)", "0x3121369d": "validateRequiredStackDepth(uint256)", "0x1747dfd4": "ContractPlay()", "0x598647f8": "bid(uint256,uint256)", "0xc368109c": "monster_hp(uint256)", "0x7fa22001": "assertEq0(bytes,bytes,bytes)", "0x8e280dce": "findNextYear(uint256,bytes)", "0x39d1f908": "actualBalance()", "0x8143f8a8": "totalGas(bytes)", "0xfe55932a": "setName(uint256,string)", "0x0fbf7151": "startsWith()", "0x4f20f35a": "payExpenses(address,uint256)", "0x705eeb90": "MultipleConstructorTest(bool)", "0x2df8e00d": "becomeMortal(uint256)", "0x645dce72": "updateRelease(uint32,uint32,uint32,bytes20,bool)", "0x1f6e5117": "getCallbackAddress()", "0xf51cbc72": "Level()", "0x64edfbf0": "purchase()", "0x35930e13": "setMinimalRewardedBalance(uint256)", "0x015e4f3a": "getConfigUint(int256,bytes)", "0x2c329e99": "Last_block_number_and_bloctime_used()", "0x6f3a7561": "SimpleAuction(address)", "0x6de00927": "GetUserRank(uint8,address)", "0xbe600276": "move(uint16)", "0x27d6c032": "unregister(bytes)", "0x4188d79c": "releaseExists(string,uint32,uint32,uint32,string,string)", "0x7ba38916": "changeAdminFromBoard(address)", "0x3369dace": "flipTheCoinAndWin()", "0xfa8dc33a": "checkRecordExists(bytes)", "0xebaf7f2f": "returnReward(uint256)", "0xc88961da": "createKingdom(string,address,address,address)", "0x21970c0c": "pay_royalty()", "0xb4a5ef58": "updateDefaultTimeoutPeriod(uint256)", "0x57bcccb6": "revokePermanentApproval(address)", "0xd1d1c8ae": "ConvertNumbers(bytes)", "0xc1c0e9c4": "exec()", "0xcc131be1": "CreateNewDraw(uint256)", "0x75f96ead": "Guess(uint256)", "0x8a5fb3ca": "currentFeePercentage()", "0x550bcd8d": "testThrowUpdateLatestRevisionEnforceRevisions()", "0xa6780857": "fireEventLog0Anonym()", "0x2d0104a5": "updateFirstDuel1(uint256)", "0xcbf1304d": "balances(address,uint256)", "0xdda9939c": "Store(address[])", "0xf41bfa9e": "mint(int256,uint256,string)", "0x044215c6": "token(uint256)", "0x1f903037": "getBytes32()", "0xa6f9dae1": "changeOwner(address)", "0xf9391d24": "AllPayAuction()", "0xabebb7f3": "MarketsContract()", "0x9e1e6528": "uncertify(address)", "0x81788e2b": "addAllowedAddress(address)", "0x4f44728d": "ownerChangeOwner(address)", "0x3da0ac79": "compare()", "0x96e438a1": "reclaimDeposit(uint256)", "0x5fe22c8b": "testFailTransferWithoutApproval()", "0x6835f32c": "build(bytes)", "0x5cac8b27": "amazing()", "0xad605729": "getParticipantCount()", "0xb6294bde": "AdminGetFee()", "0xec81e22e": "returnmoneycreator(uint8,uint256)", "0xc535165f": "revealAndPayout(bytes,bytes)", "0x6e0bd282": "destroy(bytes32)", "0xdda44b10": "buyRecipient(address,uint8,bytes32,bytes32)", "0xd4859dbc": "UniversalFunctionSecure(uint8,bytes32,bytes32,bytes32,bytes32,bytes32)", "0xd2602930": "RockPaperScissors()", "0xa08b3367": "EC()", "0x92d66313": "getYear(uint256)", "0xe49dcee9": "fixTokens()", "0x36555b85": "add(string,uint256)", "0x25010816": "get_length(uint256,uint256)", "0x610d5de8": "validateEndowment(uint256,uint256,uint256,uint256,uint256)", "0x79ce9fac": "transfer(bytes32,address)", "0x3ced516c": "descriptionHashes(bytes32)", "0xcf69df28": "getDataRequestLength()", "0x706dfe54": "getIssueState(uint256,bytes32)", "0x5af77fff": "Contract()", "0x66e5cb50": "stopTransfer(uint256)", "0x5f72f450": "check(uint256)", "0xf3b50c04": "rescind()", "0x57aee888": "_eraseNodeHierarchy(uint256,bytes32[],bytes32)", "0xaacc5a17": "getRandom()", "0x40275f85": "getPersonalDepositAddress(address)", "0x75700437": "query1_withGasLimit(uint256,string,string,uint256)", "0x6eb7b4c2": "underdogInfo(uint256)", "0x0f3eb785": "add(string,uint256,uint256,uint256)", "0xdc19266f": "Total_of_Players()", "0x9743dfc1": "jesterAutomaticCollectFee()", "0x6618b008": "cancelSellOrder(address)", "0x65538c73": "fireEventLog0()", "0xa4502cb8": "setExportFee(address,uint256)", "0x97bb2a63": "newvow(uint256,address)", "0xb400d149": "betOnNumber(uint8)", "0x030d406b": "entryPayout(uint256)", "0x1d71a1cd": "newIncome(string)", "0x85dd2148": "getSaleDate(bytes16)", "0x29917954": "exitPool()", "0xa25057de": "_transferToICAP(bytes32,uint256)", "0x24fc65ed": "getId(uint256,uint256)", "0x938199a5": "getDateOfLastPayment()", "0x04bb754c": "TradeFinancing()", "0xe37aa618": "distributeValue()", "0x547916ea": "finishRound()", "0xed01bf29": "budget()", "0x95ee1221": "isCancelled()", "0xfe777bcd": "etherForSale()", "0xffe302d1": "setPlz(string)", "0x891de9ed": "fromTLA(string)", "0x84734476": "copyBytes(bytes,uint256,uint256,bytes,uint256)", "0xfb114f57": "oraclize_query(uint256,string,string[3],uint256)", "0xceebe28d": "repoInterfaceVersion()", "0xb0ad38c4": "buildCity(string,uint256[2],uint256[2])", "0xefa7e56b": "GameEnds()", "0xcc3471af": "maxClaimBlock()", "0xa7c5052e": "buildDSTokenRegistry()", "0x6831c169": "totalPayedOut()", "0x98f3b81a": "getShares(address,bytes32[],int256[])", "0x2d077ad0": "Latch()", "0x0ac28725": "requestTradeDeal(uint256,uint256,string)", "0xb311ee0c": "refundClaimDeposit()", "0xadd82871": "strEqual(string,string)", "0x7879e19e": "CollectAllFees()", "0x5bd74490": "regProxy(address,address)", "0xd2b0d554": "getDisclaimer()", "0x0b74edc6": "testFinalHash()", "0x6cf761d4": "getMinConfirmationsByAddr(address)", "0x4cedf74e": "get_party1()", "0x4adcbd19": "isThisHardforkedVersion()", "0xefdecd9b": "check_withdrawdao()", "0x996a8046": "__callback(bytes32,string,bool)", "0x7c9cd7df": "changeDeveloper_only_Dev(address)", "0x3f77b560": "newDocument(bytes)", "0x06b5f02d": "calcWinnings(uint256,uint256)", "0x0a2282ae": "JackPot()", "0x378a2178": "tallyVotes()", "0xd8915fc5": "DCAssetBackend(bytes32,bytes32)", "0x0f590c36": "emergencyFixGameResult(uint64,uint256)", "0xea4af029": "ConferenceCertification()", "0x769dc523": "GetCategoryNumber(bytes4)", "0xd5df7559": "removeDocument(uint256)", "0x749aa2d9": "endRound()", "0xd8e5ae6a": "Etheramid()", "0xc0576b73": "monsters(uint256)", "0x32fefb4c": "add_account(address,address)", "0x7d619d9b": "holdCoin(address,address)", "0x5b067cce": "testCreateCostMain()", "0x384b1393": "follow(uint256)", "0x4162169f": "dao()", "0x5d8227e6": "FactoryBase(string,string,string)", "0x6bf52ffa": "Vote()", "0xeb5904c0": "setProfitDistributionContract(address)", "0x366a68dc": "setBlockLock(uint256)", "0x80d9eaa6": "refCount()", "0x89b8b492": "read(uint64)", "0x46b5e202": "set_num_levels(uint256,uint256)", "0xd96de4ce": "AdminDrawError()", "0x47b47102": "bakeCookie(string)", "0x1d7b5baf": "setUint(int256,bytes32,string,uint256)", "0x0699d07d": "updateMaxVal()", "0xfa544161": "getOwner(address)", "0x638560cf": "registerBool(address,bool)", "0x7c25f260": "Government()", "0x24a852c6": "unset(bytes)", "0xa32f0f41": "testFailControllerUnapprovedTransferFrom()", "0x0968f264": "withdraw(bytes)", "0x5f52e9fd": "WithdrawCashForHardwareReturn(uint256)", "0xc0f68859": "getMinimumGracePeriod()", "0x1bf6c21b": "USD()", "0x0fe234ed": "testSetController()", "0x05a17fc6": "getAccountFeed(address,uint256,uint256,uint256)", "0x673448dd": "isApproved(address)", "0x59dac714": "hashTo256(bytes)", "0x5a09f2f4": "setHouseFee(uint256)", "0x013cf08b": "proposals(uint256)", "0xeebf9808": "PiggyBank()", "0xadd43c59": "EtherTopDog()", "0xf909d60d": "getMinimumGasLimit()", "0xeb045789": "ChannelSeries(address)", "0x66d38203": "setup(address)", "0xe8641652": "strCompare(string,string)", "0x1959a002": "userInfo(address)", "0x737c8ea1": "_getRevisionBlockNumber(bytes32,uint256)", "0x127714c7": "getBudget()", "0x97daa043": "register(bytes,address,address,uint256,bytes)", "0xb5784f6f": "testMultiplePackages()", "0x0ce46c43": "scheduleCall(address,bytes4,bytes,uint16,uint8,uint256[5])", "0xe5782fd5": "setFeeStructure(uint256,uint256,uint256)", "0xa9f6def0": "HonestDice()", "0xeb7cdb56": "rankDown(uint256,uint256)", "0xb17b94c1": "testSystem()", "0xdd36e18b": "ContractStatus()", "0xee0dc478": "testSetEnforceRevisions()", "0x918359c6": "needsBirth()", "0xa5b1e13d": "settle(address,address,uint256,uint256)", "0x6b76484e": "swap(address,address)", "0x68402460": "scheduleCall(address,bytes4,uint256,uint256,uint8,uint256)", "0x733480b7": "transferToICAP(bytes32,uint256)", "0x567dbf18": "__forward(address,uint256,uint256,bytes)", "0x73e1743a": "buildDSBasicAuthority()", "0x482961e1": "updateReading(uint256,uint256)", "0x4e6ba0a9": "testCreateCostMultisig()", "0x8d7108e5": "isValidLocation(uint8,uint8,int8[5],int8[24])", "0x10142785": "assign(bytes,uint256,bytes1)", "0xfe97ee88": "hasPhone(address)", "0xe2861c8d": "cashOutProfit()", "0x0fa9ced4": "emergencyFuneral()", "0x8389f353": "setNumCities(uint256)", "0xdba1ac3d": "getEnforceRevisions(bytes20)", "0x1b4fa6ab": "getDefaultStackCheck()", "0x79be02af": "Read(address)", "0x70844f7a": "sendBadge(address,uint256)", "0x7bfaad96": "addNode(bytes,address)", "0x4d782cbc": "executeSellOrder()", "0xbe71248a": "payWinner()", "0x41304fac": "log(string)", "0x4f059a43": "getClaimAmountForBlock()", "0x6d2cb794": "airaTransfer(address,address,uint256)", "0x5a5383ac": "canExitPool()", "0xcabd27de": "Motion(address)", "0x433d4aab": "resolve(uint8,uint8)", "0x7d89ae63": "__findRef(string)", "0x4e1053cc": "RobinHoodPonzi()", "0x0220a5b4": "terminate(string)", "0x419ffa03": "fipsRegister(address)", "0x77a7e6be": "getRefTotal(uint256)", "0xed64bea4": "JamCoin()", "0x3cf885c4": "isBitSet(uint256,uint8)", "0xf2da67db": "setMany(uint256,int256,uint256,bytes20,address,bytes)", "0xe26c8434": "AdminStartDraw(string,bytes)", "0x13df7091": "mintAll(int256)", "0x8a46bf6d": "testFallback()", "0x29bed3bf": "EthereumRoulette()", "0xf869b11a": "declareVictor(uint256,uint256)", "0x45c41478": "getMarkets(bytes,address)", "0x90cf581c": "voteYes()", "0x9ec35352": "returnRandom()", "0x5025b9ae": "expire(uint256,uint256,uint8,bytes,bytes,bytes)", "0x338a1379": "_setPackedBlockNumber(bytes20,uint256)", "0xdb641ab4": "Game_balance_in_Ethers()", "0xbc0e7adb": "testThrowsDisownNotOwner()", "0x302d350e": "firstChainedCallback(uint256)", "0x5af73f3f": "getMinimalBalance(uint256,address)", "0x4c488dac": "getChannelValidUntil(bytes)", "0xa1616429": "testBitOrSuccess()", "0xaa64c43b": "transferPool(address,address,uint256)", "0x78e97925": "startTime()", "0xa0355f4e": "decline(uint256)", "0x02556de3": "updateMajorTree(bytes32)", "0x01984892": "name(address)", "0xfad4b99a": "updateChannelMinimum(address,uint256)", "0x4f39ca59": "drop(bytes32)", "0x61591a7c": "personUpdateDOB(uint256,int256)", "0x17b3a34b": "_addIdentities(uint256,bytes32[])", "0x91d8b14e": "BuyTickets()", "0x1aadcc34": "convertGreyGreen(uint8,uint8)", "0x9a863892": "NewProposal(uint256)", "0xc5487661": "proxyTransferToICAPWithReference(bytes32,uint256,string)", "0x85f8c16d": "claimHours(int256)", "0xa71f94c8": "scheduleSetUInt(address,uint256,uint256)", "0x7ef09476": "transfer(uint64,address)", "0x94bcdb4c": "Example2()", "0x37930615": "extend(bytes16[],uint64)", "0xfb09b1ac": "testBalanceOfReflectsTransfer()", "0x19a278b9": "getBAddress()", "0xc0a239e3": "valuePerShare()", "0xa039e3c7": "testSetNotTransferable()", "0x22593300": "Small(address)", "0xe21608be": "ReserveToken()", "0xc2985578": "foo()", "0xb463bcde": "testThrowsSetNotTransferableNotOwner()", "0x88d695b2": "batchTransfer(address[],uint256[])", "0x37b0574a": "isClassic()", "0x1da6822c": "testThrowsTransferEnableNotTransferable()", "0xdcfa9cc0": "testProxyCall()", "0x478aa69e": "unauthorizeUser(address)", "0x102accc1": "fireEventLog2()", "0xed62cf1f": "setCanCall(address,address,bytes,bool)", "0x15f73331": "invalidateName(string)", "0x73e30e49": "majorEventFunc(uint256,bytes,bytes)", "0x00c721ab": "setHand(uint256)", "0xf9e27106": "investmentEntryCost()", "0x4c7f74df": "EtherDelta(address,address,address,uint256,uint256,uint256)", "0xb74e452b": "today()", "0xd3118a5a": "addDoc(string,string)", "0xc204f9f1": "_transferFromToICAP(address,bytes32,uint256)", "0xf50d3914": "resetFoundationtList()", "0xe67cdfb7": "moveOldUser(uint256)", "0x98eaca94": "inKissBTC(uint256)", "0xc633084f": "sendGreeting(address,string)", "0xde10f04b": "eraseNode(bytes32[])", "0xd50495f4": "addTransaction(bytes)", "0x96cff3df": "getMinimumCallCost(uint256,uint256)", "0xce373b95": "heroOfThePit()", "0x39e525f9": "resolveCallback(uint256)", "0x942b90d3": "getRewardTable()", "0xedca914c": "buyTicket()", "0x5fcb568c": "release(string,uint32,uint32,uint32,string,string,string)", "0x6c9c2faf": "getSupply()", "0xf1448e10": "requestExecution(bytes)", "0x0c08bf88": "terminate()", "0x08aba5aa": "setAccountBalance(uint256)", "0x2c46d8d5": "EndRound(uint256)", "0x3d5db1c2": "incrUserOnholdBal(address,uint256,bool)", "0xf2f254c7": "getLatestMinorTree(bytes32,uint32)", "0x373a1bc3": "scheduleCall(address,bytes4)", "0x3a96fdd7": "compare(string,string)", "0x738ddabe": "getContentIndexedAccountCred(uint256,address,address)", "0x5acce36b": "getEndowmentBalance()", "0x1ca60aeb": "setMeltingContract(address)", "0x52375093": "m_lastDay()", "0x565a2e2c": "getBeneficiary()", "0x9d5c6061": "getMsgGas()", "0x41d31feb": "get_read_only_keys()", "0x796b89b9": "getBlockTimestamp()", "0x4a41e045": "getUint8(int8)", "0x38e48f06": "save(string)", "0x1cda37f2": "eraseRecords(bytes32)", "0xae978f08": "getLatestTweet()", "0x20909fa0": "communityCurrency()", "0xafbec8df": "TheGrid()", "0x1c14179a": "GavCoin()", "0x0b6142fc": "breach()", "0x3ab1e703": "roundMoneyDown3SF(uint256)", "0x414ceac0": "investorAddFee(uint256)", "0x82a62137": "activateAccount(address)", "0x4ca7fbd0": "updateTokenPriceWeekTwo()", "0x2551858e": "getFlags(bytes32)", "0x4ad07b0e": "oracleOutcomes(bytes32,address)", "0x60b431a4": "testGetSig()", "0xa5f8cdbb": "buyTicket(address)", "0x64aabe92": "tryExec(address,bytes,uint256)", "0xa6c01cfd": "isInGeneration(uint256)", "0x149c5066": "ChanceOfWinning(uint256)", "0xc068eae0": "player_collect_winnings(uint256)", "0x8129fc1c": "initialize()", "0xcf832ce2": "ownerRefundPlayer(bytes32,address,uint256,uint256)", "0x3517a740": "getNodeParent(bytes)", "0xec6afc22": "oraclize_query(uint256,string,string[3])", "0x50944a8f": "setMembership(address)", "0x85b1423e": "returnAll()", "0xd95a2d42": "lendGovernmentMoney(address)", "0x347632e8": "getShareholderAdressByID(uint256)", "0xbb39a960": "trade(address,uint256,address,uint256)", "0x8abadb6b": "setAccountLevel(address,uint256)", "0xa502aae8": "getNextGenerationId()", "0xb5bfdd73": "addDSource(string,bytes1,uint256)", "0x28d3ad3f": "getPot(uint256)", "0x08933d11": "getJoinBlock(address)", "0x8383bfc8": "EscrowFoundry()", "0x2ca15122": "sign()", "0xf340fa01": "deposit(address)", "0x9ed93318": "create(address)", "0xa1c0539d": "scheduleCall(address,bytes4,bytes)", "0xced92670": "changeMultiplier(uint256)", "0xb2c652f3": "getMarkets(uint256[128])", "0x69b144eb": "testThrowsCreateNewRevisionNotOwner()", "0x16c72721": "forked()", "0x712ca0f8": "getOrder(string)", "0x0cf45ba5": "updateFirstDuel2(uint256)", "0x4173b181": "setWeiPrice(uint256)", "0x689b3e2d": "Moonraker(address,address)", "0x8691162a": "TlcCoin()", "0x432ced04": "reserve(bytes32)", "0x38178fbe": "addString(string,string)", "0x8f1327c0": "getRound(uint256)", "0xa9eed530": "reduceOrderQty(uint256,uint256)", "0x408938d0": "testUpdatePackageDb()", "0x56105a08": "DgxSwap()", "0xc43d0575": "scheduleCall(bytes4,uint256)", "0xdba21657": "askForEther(uint256)", "0xca3b5c91": "hasRelation(bytes,bytes,address)", "0xc71cbcf3": "recoverAccount(address,address)", "0xb010d94a": "canExitPool(address)", "0x0a16697a": "targetBlock()", "0xff1f7046": "requiresAuction(string)", "0x0b811cb6": "executeProposal(uint256,bytes32)", "0xbb8be064": "HardwareToken()", "0xe2b05077": "getSaleDate(bytes,uint256)", "0x1e9a6950": "redeem(address,uint256)", "0xd21b84ac": "createNewDAO(address)", "0xd644e356": "index(uint256,address,uint256,uint256)", "0xea27a881": "getMinimumEndowment(uint256,uint256,uint256,uint256)", "0x99a88ec4": "upgrade(address,address)", "0xc8e4acef": "playerByAddress(address)", "0x0b7abf77": "TOTAL_TOKENS()", "0xfb5d7376": "step4()", "0xc0aa18e7": "History()", "0xe2233ada": "smartDoor(address[])", "0xd6006e88": "send(address[],uint256[],uint256)", "0x95671958": "getFileListTail()", "0x16bac350": "overthrow(string)", "0x5cb18a6d": "fipsLegacyRegisterMulti(bytes20[],address,bytes)", "0x60116397": "Registrar(address,bytes32,uint256)", "0x60fe47b1": "set(uint256)", "0x5f8f0483": "buyBankerAgreementFromImporterBank()", "0x4c8cc20b": "toContentID(address,string,string,address,uint256)", "0x45ca25ed": "changeName(address,string)", "0xb21bce4c": "vote(bytes,bool)", "0x334dc700": "CanaryV7Testnet()", "0xc31d0031": "CrowdFundDAO(string,uint8,string)", "0xf3d91708": "isEligibleForUpgrade(address)", "0x0ee07836": "adjustDifficulty(uint256)", "0xf6232556": "Security_GetNumberOfAttemptsToConnectBankAccountToANewOwnerAddress()", "0xb2d37e95": "remove_order(uint32)", "0x691d58e7": "_applyRefund(uint256)", "0x1c2353e1": "isCertifier(address)", "0xcf158fe9": "scheduleTransaction(uint256,uint256,uint256)", "0x5d96ec65": "setAdministrator(address,string,bool)", "0x0651844e": "activateBalance(address)", "0x217311ac": "getWords(uint64)", "0xc127c247": "addMember(address,string)", "0x40c0bcb9": "checkBetNumber(uint8,address,bytes32,bytes32)", "0xb633620c": "getTimestamp(uint256)", "0x5b764811": "_jMul(uint256,uint256,uint256,uint256)", "0xfe029156": "swap(address,address,uint256,uint256)", "0x31db4b95": "doTriggerAuth()", "0x203c03fa": "Coinflip()", "0x209a5b8a": "moneySumAtSettlement(address,uint256,int256,uint256)", "0xf10ae2ab": "__dig_then_proxy(uint256,address,bytes)", "0xd532e481": "activateFrozenAccount(address)", "0xe9a9c1b4": "get_party1_balance()", "0x8fcc9cfb": "setMinDeposit(uint256)", "0xe5c7e509": "testThrowTransferDisableNotEnabled()", "0x4e077f2a": "addGasEther()", "0xb7c93330": "ResourcePoolTester()", "0x82661dc4": "splitDAO(uint256,address)", "0x0e554bd8": "scheduleCall(bytes,uint256,uint256,uint8)", "0x49041903": "getGame(uint64)", "0x0e1da6c3": "claimTimeout()", "0xc53ad76f": "Kardashian()", "0x8b7bcc86": "numWinners()", "0x1043dcdf": "LastIsMe(uint256,uint256)", "0x6cd22eaf": "updateAuthority(address,bool)", "0xb796a339": "addRegistryIntoOwnerIndex(address,address)", "0x308d6613": "getSignData(uint256,uint8)", "0xed88c68e": "donate()", "0xb719d1d0": "getRegInfo(address)", "0xac8d6030": "removeRequest(address)", "0x46f0975a": "signers()", "0x434cb64c": "startNextGeneration()", "0x6cb3d30a": "triggerTryAuth()", "0x3c067945": "fundBalance()", "0x26c7edaa": "flip4(bytes)", "0xf76f950e": "uint2str(uint256)", "0x860e9960": "BetPriceLimit()", "0xb0ecca8f": "LookAtLastTimePerZone(uint256)", "0xa35cfa22": "make_move(uint256,uint8,uint8,uint8,uint8)", "0x3f74fecb": "DSTrueFallbackTest()", "0xdd2ad311": "scheduleCall(bytes,uint256)", "0x0ae5e739": "grantAccess(address)", "0x7d5fec5a": "setOwner(uint8,uint8,address)", "0x6a4b6aa5": "untrustedChildWithdraw()", "0x332f93a9": "nextPayoutGoal()", "0xc5ae6e0e": "Kernal()", "0x75438e49": "fillGas()", "0x51404cbe": "forceDivestOfOneInvestor(address)", "0xeacfc0ae": "Authorized()", "0xe59d843a": "Replicator(bytes,uint256,uint256,address)", "0xf00e8651": "createRequest(address[2],address,uint256[11],uint256,bytes)", "0x02acdb44": "setAnyoneCanCall(address,bytes4,bool)", "0x2a24f46c": "auctionEnd()", "0x7ef1925b": "getShareRange(uint256,uint8)", "0x2fac1a54": "newOrder(bool,uint256,uint256,uint256,uint256)", "0x56b8c724": "transfer(address,uint256,string)", "0x33fd066d": "doBalanceFor(address)", "0xf29617da": "registrationDeposit(address)", "0x2b297f9e": "registerDao(address)", "0x79cce1c5": "getReleaseHashes(uint256,uint256)", "0xbed1b8b9": "convertToInt(string)", "0xef5daf01": "_dumpToCompany()", "0x23dc42e7": "query1(uint256,string,string)", "0xa53b1c1e": "setInt256(int256)", "0xb8cf14e7": "updateStatusPlayer()", "0x61aa8d93": "processFee()", "0x10f41715": "updateMintingData(uint256,uint256)", "0x048e2e94": "getAccountSize(address,uint256)", "0x7c47965e": "isInCurrentGeneration()", "0x420a8ac8": "NanoPyramid()", "0xe56556a9": "getPlayerID(address)", "0x5cd2f4d3": "approve(address,bytes32)", "0x8da4d776": "newCommune(address)", "0x4d30b6be": "balanceOf(address,bytes32)", "0x4a606c53": "_db()", "0x4956eaf0": "deploy(address,uint256)", "0xf1fe42b8": "TransactionRequest(address[3],address,uint256[11],uint256,bytes)", "0x63e38ff3": "id_for_nym(uint256)", "0x0e757a2e": "testSetAndGet()", "0x3facd57c": "registerBill(uint256,address,address,uint256,uint256,uint256)", "0xe548cf13": "betOnColumn(bool,bool,bool)", "0x2f1e4968": "makeNewProposal(string,uint256)", "0x0b467b9b": "revoke(bytes)", "0x74bfb965": "addNewProxy(address)", "0x02de2cf3": "isLatestPreReleaseTree(bytes32,bytes32)", "0xfc1f7652": "_isBoardMember(address)", "0xefef39a1": "purchase(uint256)", "0x3ae9b510": "getLatestMajorTree(bytes32)", "0xc24924d6": "setQueryFee(uint256)", "0x839930ba": "getMinimumBet()", "0x8f5e9ca7": "acceptTOS(address,bool)", "0xd1100691": "BookCafe()", "0x839849c0": "changeBaseMultiplier(uint256)", "0x758971e8": "ownerTakeProfit(bool)", "0x2b785960": "testBitAndSuccess()", "0xd96a094a": "buy(uint256)", "0x379607f5": "claim(uint256)", "0x88e072b2": "checkTransfer(address,uint256)", "0x05fefda7": "setPrices(uint256,uint256)", "0xfc63d4fb": "order(bool,uint32,uint128)", "0x5718b994": "checkEvent(address,bytes,bytes,uint256)", "0x0c0662a8": "getLastWithdrawal()", "0xeb947f19": "ExampleResourcePool()", "0xb51c4f96": "getCodeSize(address)", "0x702fc7da": "ReviewModel()", "0xc6cb7a96": "orderMatchTest(uint256,uint256,int256,uint256,uint256,address,address,uint256,int256)", "0xb7760c8f": "transfer(uint256,address)", "0x32b12eac": "setFallback(address)", "0x0a4d564c": "TieUpLooseEnds()", "0xc3ad5ecb": "getTweet(uint256)", "0xe86afde0": "description(uint64)", "0xd0549602": "scheduleTransaction(address,uint256,uint256,uint256)", "0xbf2e694f": "getPreviousRequest(address,address)", "0x2525f5c1": "cancelBid(address,bytes32)", "0x19f02ceb": "set(address,address,uint256)", "0xf00acc47": "prepareRoll(uint256,uint256)", "0x29d28aad": "Broker(address)", "0x041d0c0b": "MyTokenLoad(uint256,string,uint8,string,address)", "0xd81ab0c1": "invoke(uint256,address,address,bytes)", "0xab09ee80": "respond(uint256,uint256,uint256,uint256)", "0xd985f122": "RelayToolsTest()", "0xbe0638e4": "WealthShare()", "0x5263ba87": "getLatestPatchTree(bytes32,uint32,uint32)", "0xb7bae9b7": "exists(bytes,bytes)", "0x0b80f8d3": "invmod(uint256,uint256)", "0xbb4d7cd1": "tag(uint256,string)", "0xadf54e0c": "betOnLowHigh(bool,bool)", "0xed54746e": "lastAuction()", "0xf158458c": "getMinimumEndowment(uint256,uint256)", "0x5fcc2edb": "IndividualityTokenRoot(address)", "0x7cc48875": "Slots()", "0x2885b593": "extractMasterKeyIndexLength()", "0x8940aebe": "publicKey(uint256)", "0x0aece23c": "getFeeAmount(int256)", "0x72c3015c": "mint(int256,address,string)", "0xd6a619e3": "transferIfPuritanical(address)", "0xe30443bc": "setBalance(address,uint256)", "0x1277e24f": "payOneTimeFee()", "0xb958a5e1": "getPhoneByAddress(address)", "0x4e71d92d": "claim()", "0x3e0d4f4a": "ApproveContractorProposal()", "0x18160ddd": "totalSupply()", "0x150ad2a8": "owner_transfer_ownership(address)", "0xa2b5591c": "oraclize_query(uint256,string,string[],uint256)", "0x8d227fc0": "getPeriodInfo()", "0x1c0b6367": "processTransaction(bytes,uint256)", "0xf245b9e4": "DVIP(address)", "0x392327b5": "owner_set_fraction(uint256)", "0xadaccd74": "getNickname(address)", "0x2e0ef395": "voteOnNewEntryFees_only_VIP(uint8)", "0x89c19ddb": "concat(string,string)", "0xcef8d343": "buyShare(uint256,bool)", "0xd224118f": "PrepareDraw()", "0x4269d8ef": "_safeSend(address,uint256)", "0xda1441cd": "KudosBank(uint256)", "0x7ccfd45a": "removeSubUser(address)", "0xcc70bb1a": "publish(string,string,string,address)", "0x708f29a6": "getTotalPayments()", "0x05459f42": "WeeklyLotteryB(address)", "0x452d44dc": "checkBothNotNull()", "0x659fb968": "getOracleOutcomes(bytes32[],address[])", "0x3570c2ee": "PosRewards()", "0xbca86986": "testSetup()", "0xff49b26e": "createEvent(uint256,uint256,uint8,uint32,address,uint256,uint8)", "0x541d920c": "commit(bytes,string)", "0xa6a20ff6": "DSEasyMultisig(uint256,uint256,uint256,uint256)", "0x0f5381f1": "testUserCanIncreaseVersionNumber()", "0xf8f46b5f": "getCurrentMinerAddress()", "0xfcfff16f": "open()", "0x5a9b0b89": "getInfo()", "0xb8017221": "get_party2_balance()", "0x514dcfe3": "seller_accept()", "0x2004dff6": "Basics()", "0x0b6d8d52": "createDAO(address,uint256,uint256)", "0xf18d20be": "adminWithdraw()", "0x8f9df278": "newEntry(int256,bool,uint256,int256,string,bytes32,address,uint256[])", "0x75949c13": "sendHalf(address)", "0x64ac2c4a": "WavesPresale()", "0x8946d33f": "SplitterEthToEtc()", "0x11400d8e": "priv_fastGetBlockHash__(int256,int256)", "0x7266f4a4": "X3()", "0xb189ad2a": "testErrorUnauthorizedAfterTransfer()", "0x31c2bd0b": "propose(address,bytes,uint256)", "0x100c8ada": "setCAmodulus(bytes)", "0x296ed88f": "testFailControllerInsufficientFundsTransferFrom()", "0xd5dbb1ad": "solveBet(address,uint8,bool,uint8,bytes32,bytes32)", "0x8a9ffb90": "transfer(string,string,bool)", "0x968908a3": "createMarketMaker(uint256,uint16,uint256)", "0x7b02b2c9": "sendMsg(address,string)", "0xa33dd801": "setTreasuryBalance(uint256)", "0x2f553d31": "isCreated(bytes32)", "0xf712d7ff": "testFailControllerTransferFromWithoutApproval()", "0xe51ff1fc": "iterateOverThings()", "0x60fd902c": "gnosisToken()", "0x2ef875fb": "div10(uint256,uint8)", "0x640f244b": "findSuitableGen()", "0x16cb9a01": "assertFalse(bool,bytes)", "0xe671f510": "onEtherandomExec(bytes32,bytes32,uint256)", "0x758b5172": "setPlayersPerRound(uint256)", "0x6423db34": "Reset()", "0x21958a50": "AddressSeries(address)", "0xfb87d5ea": "TransactionRequest(address[4],address,uint256[11],uint256,bytes)", "0xfb279ef3": "tip(uint256,address,uint256)", "0x338cdca1": "request()", "0x4e7ad367": "fireEventLog1Anonym()", "0xbd9335c0": "scheduleHangouts()", "0x4cb85356": "BranchSender(uint256,bytes32)", "0x1d7e1f68": "getContentRank(address,uint256)", "0x1a1df394": "Play(bool)", "0x468129a5": "setUnit(uint256,uint256,uint256)", "0xecb70fb7": "hasEnded()", "0x2d49ffcd": "getLocked()", "0x2e06c756": "post(string,string,string,uint256,uint256,address)", "0x73f93a48": "getAccountContentTip(address,uint256)", "0xf6a3d24e": "exists(address)", "0x5fbddcf3": "isLivingMonarch()", "0x6d568c43": "weiToCents(uint256)", "0xacf4280c": "buildDSApprovalDB()", "0xf3541901": "execute(address,bytes,uint256,uint256)", "0x88eb7af7": "_isHuman()", "0x48a490fb": "transferFromTreasury(address,uint256)", "0x5e03d393": "setAccountFrozenStatus(address,bool)", "0xfc687311": "betOn(int8)", "0x5bbfe9b6": "_myGroupHelper()", "0x5629c6d9": "doExecution(address)", "0xe3a9b508": "EnableDisableTokenProxy()", "0x9229c504": "new_mainPlayer(address)", "0x6f6c0244": "generateShortLink()", "0x33613cbe": "getBondBalance(address)", "0x4229616d": "collectPercentOfFees(uint256)", "0x4ed3885e": "set(string)", "0x043bb5e7": "getIdentities(address[])", "0xad2fea7c": "removeMinter(int256,address)", "0x0b7e9c44": "payout(address)", "0x17f5de95": "MAX_TOKENS_SOLD()", "0x50ea1932": "lookupISO3116_1_alpha_2(bytes)", "0x96f7807a": "getDuel2(uint256)", "0xa97ffd5e": "safeToSell(uint256)", "0x2f4ee5d4": "registerThrone(bytes,uint256,address,uint256,uint256)", "0x4c0bcfe5": "getTransferableBalance(address)", "0x0d17bc2e": "_disallow()", "0x0ca7395f": "returnFund(address,uint256)", "0x69fe0e2d": "setFee(uint256)", "0xfaf27bca": "greeter(string)", "0x0c7de59d": "edit(address,bytes,bool)", "0x16e27349": "getFeeRecipient(int256,int256)", "0x37751b35": "doTransfer(address,address,uint256)", "0x67fc1c6a": "validateProposedMonarchName(string)", "0xf59f99ee": "createNextGeneration()", "0x6be505f5": "selectWinner(bytes32)", "0xf6bd5893": "getGas(uint256)", "0x35b09a6e": "someFunction()", "0xb3aaa277": "validate(address[4],address,uint256[11],uint256,bytes,uint256)", "0x4f052648": "XaurumDataContract()", "0x117b4705": "retract(bytes32)", "0x2145e36c": "testBitSetFailIndexOOB()", "0x3d750b28": "found()", "0x1334a5e2": "eventCallback(uint8,address,address,uint256)", "0x3c2c21a0": "scheduleCall(address,uint256,bytes4)", "0x82996d9f": "rent()", "0xaf640d0f": "id()", "0xdaf22f4d": "identify(bytes32)", "0xfe4667e9": "getMaxLossAfterTrade(address,uint256,uint256,int256,int256)", "0xfc108f70": "GamblerPerAddress(address)", "0x89f4ed7a": "getLastTag(uint256)", "0xfcc11241": "addOrder(uint256,uint256,uint256,uint256,uint256,uint8)", "0x43243797": "fundsOf(address)", "0x892c0214": "NumberOfCurrentBlockMiners()", "0xb5a6c525": "extractFrozenAccountLength()", "0x1acb2719": "getNextRequest(address,address)", "0xa89a4f09": "creatorBalanceChecker()", "0x1e83409a": "claim(address)", "0x5e1d7ae4": "changeFeeRebate(uint256)", "0xb7482509": "deposit(address,string)", "0xfb47a067": "_getRevisionBlockNumber(bytes20,uint256)", "0x5dcdddd1": "testSafeToAddFix()", "0x9aa26f06": "registerBytes32(address,bytes)", "0xd085e66e": "GetPart(bytes32,uint256)", "0x2cd78450": "activateExportFeeChargeRecord(address)", "0x35d129f6": "untag(string)", "0x1a7a98e2": "getDomain(uint256)", "0x877653f0": "_storeBalanceRecord(address)", "0x446fbcd1": "CredSign()", "0xfae8f9a2": "setInitialParent(int256,int256,int256,int256,int256,int256)", "0xc1b056b0": "getNodeLeftChild(bytes)", "0x71f297cc": "XaurumToken(address)", "0xe3ffc9a3": "sendEtherToOwner()", "0xeccf1b29": "CrystalDoubler()", "0x57f4d5ec": "processDividends(address,uint256)", "0x75c589a0": "getMinimumCallCost()", "0x66772438": "computeResponse(uint16)", "0x7fefde53": "WillRegistry()", "0x8f4fb958": "calculateRandomNumberByBlockhash(uint256,address)", "0xed498fa8": "userTokens(address)", "0x5601eaea": "execute(uint256,uint256)", "0x8dd8596c": "sendDonation()", "0x15a0df43": "testThrowCreateNewRevisionNotOwner()", "0x0382c254": "CheckHash(uint8,uint8,uint8,uint8,bytes32)", "0x157f8f51": "feePaid(int256,int256,int256,int256)", "0xf00aac7f": "ArrayRR()", "0x7b7d7225": "_approve(address,uint256)", "0x54ed7b6e": "addHash(bytes)", "0x235c002d": "transferOther(address,address,uint256)", "0x7057c20d": "CFD(address)", "0xd5563f31": "createAuction(uint256)", "0x46c3166f": "testThrowRetractLatestRevisionNotOwner()", "0x4420e486": "register(address)", "0x9a969768": "distributeProfits(uint256)", "0x464f37c9": "trustedChildRefund()", "0x5d495aea": "pickWinner()", "0xdf55b41a": "owner(string)", "0x10e6e06c": "vote(bool,uint256)", "0xe7faecec": "testFailInsufficientFundsTransfers()", "0xea98e540": "proxyTransferFromToICAPWithReference(address,bytes32,uint256,string)", "0xfff78f9c": "doThrow()", "0x9bb01b5f": "ElcoinDb(address)", "0xdc6dd152": "playerRollDice(uint256)", "0x5d0be9de": "softWithdrawRevenueFor(address)", "0xcd591822": "CanaryV7Fast()", "0x36e6b92e": "taskProcessedWithCosting(uint256,uint256)", "0x7bb6a4c6": "uno(uint256)", "0x03427656": "getDefaultSoftResolutionBlocks()", "0xc1fd4339": "createMarket(bytes32,uint256,uint256,address)", "0xeb95b7d5": "Bounty(address,address)", "0x4dd49ab4": "get(bytes,uint256)", "0xfa6d373c": "LeaderHash()", "0x8c8d98a0": "toTimestamp(uint16,uint8,uint8)", "0x9a79f4a8": "testFailHeaderInsufficientFee()", "0xdd90c403": "getAccountFeed(address,uint256,uint256)", "0x58e59c32": "get_entry(uint256,uint256,uint256)", "0xfd747c0b": "rsaVerify(bytes,bytes,uint256,bytes)", "0x0f4cf692": "numMessages()", "0x18433bb7": "DrawPrepare()", "0x1dea0c57": "getRealBet(uint256)", "0x7d60e343": "getFileListSize()", "0xd24ddcfe": "buyKissBTC()", "0xa055fe64": "_projectCommitNew(address)", "0x5f17114e": "TimeDeposit()", "0x85fe0448": "testThrowRestartNotUpdatable()", "0x901717d1": "one()", "0x528fd7b0": "manualPayExpiredDuel()", "0x85952454": "newOwner(address)", "0xf34c7010": "commitSecurity(address,uint256,uint256)", "0x3bf2313d": "__transferToICAPWithReference(bytes32,uint256,string)", "0x67b830ad": "fillOrder(uint256)", "0x73fac6f0": "confirmReceived()", "0xf1b3f968": "getRaceEndBlock()", "0xf99fc046": "dEthereumlotteryNet()", "0xb409da05": "logDoubleIndex(bytes,bytes,bytes,uint256)", "0x9e920587": "testOwnedAuth()", "0x8e7cb6e1": "getIndex(uint256)", "0xe2f8a017": "payInstallment(uint256)", "0xac3e6b2f": "testSetNotRetractable()", "0x8fbc3ecd": "BUFFER()", "0x4b729aff": "buyNumber(uint256)", "0x166c4b85": "len(bytes32)", "0x6299f8cf": "stop(uint256)", "0xd767aee0": "bbb()", "0x29090202": "Resolver(address)", "0xcc2c2bcf": "MotionFactory(string,string,string)", "0xfd260dfc": "getCertificationDbStatus(address)", "0x30aceb89": "validateRequestParams(address[3],address,uint256[11],uint256,bytes,uint256)", "0xd11f13df": "numberOfParticipantsWaitingForPayout()", "0xd05c78da": "safeMul(uint256,uint256)", "0x69953501": "setUtils(address)", "0xff7f5f2a": "EtherizationUtils2()", "0xde4b3262": "setBasePrice(uint256)", "0x6cf9cc58": "registerResource(bytes,uint256,bytes,string)", "0x7ac37d58": "ownerTransferEther(address,uint256)", "0x0121b93f": "vote(uint256)", "0x07b6f631": "testTestHarnessAuth()", "0x869b3f6a": "testThrowsRetractNotOwner()", "0x18253234": "ticketsAvailable()", "0x5581004d": "createThrone(bytes,uint256,uint256,uint256,uint256)", "0x7102c138": "Standard_Token(uint256)", "0xce5566c5": "cash(uint256,uint256)", "0x16a25cbd": "ttl(bytes32)", "0x0c9fcec9": "setApproval(address,address,uint256)", "0xe6d95eb8": "DSAuthorized()", "0x34c0d654": "setPackageDb(address)", "0x0ee79fb3": "closeReferendums()", "0xe2cdd42a": "vote(uint256,address,bool)", "0xd3f297d6": "claimLiquidityReward()", "0xf37b437b": "scheduleCall(address,bytes,uint256,uint256,uint8,uint256,uint256)", "0x2090cf8b": "consultBalance(address)", "0xc9296d14": "scheduleTransaction(address,uint256,uint256,uint256,bytes)", "0x7993e5c2": "Devcon2TokenForTesting()", "0x268bb78e": "propose(address,bytes,uint256,uint256)", "0x2b16b56a": "setIndex(uint256,uint256)", "0x6d15f208": "reject(string,uint256,uint16,address,uint256)", "0xc4ff3614": "Wallet(address[],uint256,uint256)", "0xb47d89ad": "Details()", "0x0ae08793": "confirmAndCheck(bytes32)", "0x061e494f": "getBet(uint256)", "0x314e99a2": "abdicate()", "0xe487eb58": "getOwner(bytes20)", "0x7ee65635": "LookAtDepositsToPlay()", "0x9e9d3aa4": "FirstBloodToken(address,address,uint256,uint256)", "0x4dfd1b02": "setUint8(int8,uint8)", "0x82fbdc9c": "register(bytes)", "0xa8b60b93": "ackMsg(uint256,string)", "0x081e806d": "PayOut(uint256)", "0x8bab8791": "testPkgUpdate()", "0xc262df45": "isKnownRequest(address,address)", "0x4123cb6b": "m_numOwners()", "0x62be3172": "Message(address,address,address,string)", "0x0d368fee": "deverify(address)", "0x5f1231ea": "getMemberInfo(address)", "0xa07daa65": "newRequest(uint256)", "0xa4406bcd": "placeSellOrder(uint256,uint256)", "0x5b7d47a9": "betOnColor(bool,bool)", "0x9c6034a7": "sendIfNotForked()", "0x26a4861c": "CROWDFUNDING_PERIOD()", "0xbaac5300": "createTokenProxy(address)", "0xfc72c1ef": "ERC20Base(uint256)", "0x316b08a0": "scheduleTransaction(address,bytes,uint256[7],uint256)", "0x0b590c6b": "SingularDTVToken()", "0x750e443a": "voteAgainst(uint256)", "0xfc7b9c18": "totalDebt()", "0x7ff9b596": "tokenPrice()", "0xd67cbec9": "release(uint32,uint32,uint32,bytes20)", "0x553cc48d": "Player(string)", "0x579cdf17": "getAdminName(address)", "0x7e1c4205": "query2(uint256,string,string,string,uint256)", "0x54107401": "declareLove(string,string)", "0xea4ba8eb": "getOutcome(bytes)", "0x9b5adea2": "setMinter()", "0x185061da": "undoIt()", "0x90c3a370": "AuctionMaster()", "0xbd02e4f6": "calcRandomNumberAndGetPreliminaryGameResult(uint256,uint64)", "0xbc126ba1": "totalCents()", "0xa3747fef": "register(bytes,bytes)", "0x805210b7": "AmIPlayer2()", "0x4e05ded6": "ClassicCheck()", "0xec2ac54e": "deposit(address,uint256,bytes32,uint256)", "0x49c15bd9": "Purchase()", "0x87bb7ae0": "getTicketPrice()", "0xf2f03877": "commit(uint256,bytes32)", "0x167d3e9c": "SetOwner(address)", "0x5c634241": "CanaryV6()", "0xba15e52e": "getInfo(bytes20)", "0x06c1df7b": "checkBetColumn(uint8)", "0xf7bc39bf": "owns(address)", "0x27b752b8": "sha3HexAddress(address)", "0x5ac801fe": "setName(bytes32)", "0x1ae460e5": "isInPool()", "0x85c7a953": "WithdrawFullBalanceFromBankAccount()", "0x755b5b75": "setNumUnits(uint256,uint256)", "0xaefc8c72": "unsealBid(bytes32,address,uint256,bytes32)", "0xfab43cb1": "getPongAddress()", "0x9e997121": "getConfigAddress(bytes)", "0xda2b7416": "testBitsAndFailIndexOOB()", "0xd0e30db0": "deposit()", "0x4a0d89ba": "getSwap(uint256)", "0x63a9c3d7": "verify(address)", "0x337b1cf9": "setIpfsHash(bytes)", "0xbaf00f76": "removeAllSubUsers()", "0x1b370abb": "getPreviousNode(bytes)", "0x741e2345": "registerMany(address,uint256,int256,uint256,bytes20,address,bytes)", "0xb3760c80": "orderMatch(uint256,uint256,uint256,int256,uint256,uint256,address,uint8,bytes,bytes,int256)", "0x73ffd969": "setMap(uint256,uint256,uint256)", "0x50b44712": "tickets(uint256)", "0x6a9d2afd": "playToWinTest(uint256)", "0x644998ae": "maintain(int256,uint256,uint256)", "0x2203ab56": "ABI(bytes32,uint256)", "0x9c67f06f": "registryStarted()", "0x93423e9c": "getAccountBalance(address)", "0x524e4e61": "testDistribution()", "0xa17042cc": "getMsgValue()", "0x4f9d719e": "testEvent()", "0xcbcaacab": "checkTransferWithReference(address,uint256,string)", "0x1bcf5758": "getOccupies(uint8)", "0x1d4b0796": "updateTxStats()", "0xd173707d": "hasPhysicalAddress(address)", "0xa54a2b8b": "testBlockHashFetch()", "0xc51bf934": "CEILING()", "0x0e54b872": "registerUser(string,address)", "0xba51a6df": "changeRequirement(uint256)", "0x6bd92f7c": "activateAllowanceRecord(address,address)", "0x90daaf67": "getMinimalDeposit()", "0x85d5c971": "logTransfer(address,address,bytes32)", "0x8b9e5385": "MeterSlock(uint256,uint256,address)", "0x7bcd7fad": "getRecordAtIndex(uint256)", "0x8e035ac1": "BetOnHashV82()", "0x5dbe47e8": "contains(address)", "0x21bb79fe": "luckyDogInfo()", "0xdd467064": "lock(uint256)", "0xa4beffa7": "increaseInvestment()", "0x8400c307": "isRecipientAllowed(address)", "0x0965bf7d": "processProposals()", "0x4b5dc8cb": "roundMoneyDown3SFExt(uint256)", "0x777feff5": "getCertificationDbAtIndex(uint256)", "0x9462eae5": "ChangeContractor(address)", "0x4c6d1d9e": "checkOutTag(string)", "0x09a399a7": "personAdd(string,int256,int256,string)", "0x31380c89": "TokenSale()", "0xd0bff051": "testSetBalanceDb()", "0x4c738909": "getMyBalance()", "0xb2310cc5": "payRequstedSum(uint256,uint256)", "0xda3c300d": "currentFee()", "0x6ed7c013": "move_monsters()", "0x4f073130": "takeOrder(bool,uint256,uint256)", "0x6860fd58": "Fees(uint256)", "0x214c9d50": "WritedrawStatus()", "0xf314bf46": "setReleaseDb(address)", "0x561a4873": "buyAd(string,string,string,uint256,uint8,address)", "0xf249cf19": "get_all_challenges()", "0xbbed7177": "getContentTimestamp(uint256)", "0xc864e760": "recordCommissionEarned(uint256)", "0x1896f70a": "setResolver(bytes32,address)", "0xfd35e71b": "entryPayoutDue(uint256)", "0x5a58cd4c": "deleteContract()", "0xb29b5366": "setRentable(bool)", "0xad5c613d": "purchase(bytes)", "0x6949a058": "sendOwnerEther()", "0xc03e382f": "calculateShare()", "0xf5bade66": "setDeposit(uint256)", "0x384e5018": "etherandomCallbackAddress()", "0xf06186c7": "testReality()", "0x677342ce": "sqrt(uint256)", "0x10e89b22": "remove_deal(uint32)", "0xf2b445ad": "rowround(uint256,uint256)", "0xd7ed7453": "redeemWinnings(uint256)", "0x92b4bb50": "rps()", "0x089327de": "MyToken()", "0x87ebd76c": "initContract(string,string,uint256,uint256)", "0xdbc45228": "newProposal(address,uint256,bytes,bytes)", "0x6b1feeeb": "get_my_sig()", "0x6837ff1e": "newContract(address)", "0x9f181b5e": "tokenCount()", "0x92ba4ba6": "GridMember(string,uint256,bool,address,address)", "0x45755dd6": "returnFunds(uint256)", "0xb4b9d1f1": "lookup(uint256,uint256)", "0x98024f18": "testThrowsTransferDisableNotEnabled()", "0x9e7b8d61": "giveRightToVote(address)", "0x8112821f": "EthVentures()", "0xe65d6b49": "getCommission()", "0x068c966b": "DrawDetails(uint256)", "0x9bb5239a": "CheckPrize(address,uint256)", "0xff08d2b0": "PayMiners()", "0x9be1fcee": "BankOwner_DisableConnectBankAccountToNewOwnerAddress()", "0x5f972df8": "_jDiv(uint256,uint256,uint256,uint256)", "0xfe8b6642": "setEnforceRevisions(bytes32)", "0xe4cc1161": "seedWithGasLimit(uint256)", "0x5fd4b08a": "getName(address)", "0xaa51793c": "isLosingBet(uint256)", "0x31757f2e": "collisionCount()", "0xe1f5ebc5": "_projectAddNew(address,uint256)", "0x64228857": "getRevisionCount(bytes32)", "0x5ca3400c": "WithBeneficiary(address)", "0x39f4debc": "fillOrderAuto()", "0xcc2c5453": "add_sword(uint16)", "0x0a19b14a": "trade(address,uint256,address,uint256,uint256,uint256,address,uint8,bytes32,bytes32,uint256)", "0x4d207d9a": "identify(address)", "0x3e83fe36": "getMyShares()", "0x8bb0faee": "setRef(string,string)", "0x38bbfa50": "__callback(bytes32,string,bytes)", "0xcee6f93c": "getResultOfLastFlip()", "0xbbba3333": "safer_ecrecover(bytes32,uint8,bytes32,bytes32)", "0x8e19899e": "withdraw(bytes32)", "0xd8389dc5": "hash(bytes32)", "0x8a4068dd": "transfer()", "0xea9e107a": "acceptRegistrarTransfer(bytes32,address,uint256)", "0x8f4ffcb1": "receiveApproval(address,uint256,address,bytes)", "0xf67abd87": "entryDetails(uint256)", "0x67acd805": "lowerMinWager(uint256)", "0xec035393": "_getAllRevisionBlockNumbers(bytes20)", "0xbd858288": "orderMatch(uint256,uint256,int256,uint256,uint256,address,uint8,bytes32,bytes32,int256)", "0x112c7075": "ManualDeposit()", "0xd81a91e9": "get_party2()", "0xc52bd836": "setDappOwner(bytes32,address)", "0xf84f420b": "getRandomNumber(address,uint256)", "0xcfe9a7b8": "getPackageName(uint256)", "0xe97dcb62": "enter()", "0x48db5f89": "player()", "0x6bdbf8e6": "concat()", "0x3c959aca": "CheckTickets()", "0x3aa5f4f7": "changeTokenSettings(uint16,uint256,uint256)", "0xac20902e": "NormalizeMoney()", "0x2fac1d36": "isReadyFor(address)", "0xdcaa5620": "findNextWeekday(uint256,bytes)", "0xf9909915": "bulkStoreHeader(bytes,int256,bytes,int256)", "0xcd2cdd5b": "claimOwnershi()", "0xcfae3217": "greet()", "0xf5c8d71b": "forceMove(address,address,uint256)", "0x9718b524": "newTreasury(address)", "0xd0679d34": "send(address,uint256)", "0x1301ee02": "transferringETC(address)", "0x60eb2826": "Badge()", "0x0d0c2008": "TwoAndAHalfPonzi()", "0x17e1bfb7": "addInstitution(address,string)", "0x06394c9b": "changeOperator(address)", "0x80c951bf": "currentClaimPriceInFinney()", "0xd063f55f": "toLittleEndian(uint64)", "0x53f818d6": "checkBetValue()", "0x9205fbc2": "testAuthorityAuth()", "0x3e4c0c82": "player_1(uint256)", "0xe571c35e": "ReverseRegistrar(address,bytes32)", "0x24804cef": "Deed()", "0x622e88cb": "testBitsXorSuccess()", "0xdfca2f53": "LookAtPrizes()", "0xafa293d4": "getSource()", "0x755f99c2": "AddNewSmallContract(address)", "0x7137ed47": "setProxyContract(address)", "0x835b42fc": "testThrowUpdateLatestRevisionNotUpdatable()", "0xdd34e129": "PriceTest()", "0xedb27f4e": "switchWizard(address)", "0x1c5d9faa": "setNickname(string)", "0x4746cef8": "_confirmAndCheck(address,bytes32)", "0x189c94ae": "testFallbackStaticSig()", "0x0cb749b6": "FutureBlockCall(address,uint256,uint8,address,bytes,bytes,uint256,uint256,uint16,uint256,uint256)", "0x2b25a7e4": "giveKudos(address,uint256)", "0x294f3d4d": "setUpLimit(uint256)", "0x2cce81aa": "getBlockHash(int256)", "0x4cd11943": "NewManualInvestor(address,uint256)", "0x7eaef50c": "over()", "0x8ac4e1d8": "TemperatureOracle()", "0xf108a7d2": "withdraw(uint256,address,string)", "0x00a676f9": "getExists(bytes32)", "0xb8d4efb5": "validate_percent(uint8)", "0xc7489441": "closeMarketMaker(uint256)", "0x3def449b": "FipsNotary()", "0x5687f2b8": "emitApproval(address,address,uint256)", "0xa9f8ec6c": "AlarmClockTipFaucet()", "0xd8e5c048": "scheduleCall(address,uint256,uint256)", "0x135217e7": "requires_depth()", "0x0aa46c12": "testClearBitFailIndexOOB()", "0x77d32e94": "ecrecovery(bytes32,bytes)", "0xace523c4": "createReferendum(string,string,uint256,uint256)", "0x5ca8bc52": "returnIt()", "0xdb318833": "_ecAdd(uint256,uint256,uint256,uint256,uint256,uint256)", "0x623195b0": "setABI(bytes32,uint256,bytes)", "0xd7bb99ba": "contribute()", "0x2880ebe7": "underdogPayoutMarkup()", "0x4ce01d86": "totalBetValue()", "0x837a7ba5": "testThrowTransferDisabled()", "0x386fcda8": "testCreateCostToken()", "0x0e850239": "scheduleCall(bytes4,bytes)", "0x163aba3c": "getQueryFee()", "0x9941e3d0": "setCallAddress(address)", "0x23637e60": "votePrice(uint256,bool)", "0xde78e78a": "tokenLaunched()", "0xe3579ea5": "publish(string,string,address,uint256)", "0x59a547b0": "recordCommission(uint256)", "0x1aa86370": "updateXIPFSPublicKey(string)", "0x97fcb54e": "transfer_eth(address,uint256)", "0x05d2f92a": "check_depth(address,uint256)", "0xdfcbb794": "TrustFund(address,uint256,address)", "0xb7dd1d17": "getAllRevisionBlockNumbers(bytes32)", "0x75862df4": "TokenWithEStop(address)", "0xd22057a9": "register(bytes32,address)", "0x29d017b5": "TestWithConstructor(address,uint256[])", "0xd216d55d": "etherandomExec(bytes32,bytes32,uint256)", "0xfba06849": "fipsPublishDataMulti(bytes20[],bytes)", "0xa37fd390": "setHomeAdv(uint256,string)", "0xcf2e3efc": "GetBankAccountBalance()", "0x423e7e79": "_dispatchEarnings()", "0x74087040": "testBitsNotEqualSuccess()", "0x61d585da": "state(bytes32)", "0xcfb3a493": "getMyBounty(uint256)", "0x5afeb106": "Sqrt()", "0xf9e84395": "unexempt(address)", "0x5669c94f": "issueToken(address,string)", "0x19b05f49": "accept(uint256)", "0x3ae01f84": "USDOracle()", "0x8c172fa2": "getEvent(bytes32)", "0x4671e65e": "proposeEmergencyWithdrawal(address)", "0xc27d7721": "create(uint256[101][])", "0x5c52e51e": "processPayout()", "0xf7a0fa0a": "getShareDistribution(bytes)", "0x31a3a506": "closeFunding()", "0x465e759b": "testRestart()", "0xb60d4288": "fund()", "0x52200a13": "getNumHolders(uint256)", "0xf2c298be": "register(string)", "0x7bc25372": "UserCheckBalance(address)", "0x104d5fdd": "getPriceProxy()", "0x447cd682": "scheduleTransaction(address,uint256)", "0xa045fdff": "scheduleCall(address,bytes)", "0x4757f1d2": "redeemAllOutcomes(uint256,uint256)", "0x5e855f14": "Dice(uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)", "0x5d3c1d4c": "_getRequest(uint256)", "0x416c8701": "beyond()", "0x63aea3e0": "PlayerInfo(uint256)", "0xa163a624": "Test()", "0xedede601": "testBalance()", "0x13651124": "WithdrawAmountFromBankAccount(uint256)", "0x893d20e8": "getOwner()", "0x90b5561d": "insert(uint256)", "0xf9983a12": "GetMyInvestmentBalance()", "0xb71c47a2": "surrender()", "0xf2a75fe4": "empty()", "0x804ba97a": "tryGet(bytes)", "0x6506b623": "rotateBitsLeft(bytes,uint256)", "0x3ef8ec78": "announce_numbers(uint8,uint8,uint8,uint8,uint32,bytes32)", "0x73abecbb": "kill1()", "0xd5171523": "euroteambet()", "0x8e52cb51": "getRecordKey(bytes,bytes,bytes)", "0x7adbf973": "setOracle(address)", "0x4aa16737": "enter(uint8)", "0xf0cb556c": "updateLatestRevision(bytes32,bytes)", "0xbc8fbbf8": "nuke()", "0xc8e55708": "oraclize_query(string,string[1])", "0x7332b520": "getRewardsCount(uint256)", "0xf7c2b38c": "seconds_left()", "0xba344743": "_rawTransfer(address,address,uint256)", "0xcab5c0f1": "_incrementState()", "0xe044c2de": "newLoan(bytes,address,uint256,uint256,uint256,uint256,uint256,uint256)", "0x76abc03b": "getShareDistribution(uint256)", "0xf0da84f8": "getTransferable(bytes32)", "0xcde99727": "calculateROI()", "0x155dd5ee": "withdrawFunds(uint256)", "0x8b543b80": "maximumCredit(address)", "0x340ddda6": "MeatConversionCalculator(uint256,uint256)", "0x524f3889": "getPrice(string)", "0x84054d3d": "cashout()", "0x856f3080": "WhatWasMyHash(bytes32)", "0x0386a016": "closeProposal(uint256)", "0xcebce72d": "token(uint64)", "0x7f480f9d": "processDividends(address)", "0x11d12402": "testEasyPropose()", "0x2f695053": "getCertifierAtIndex(uint256)", "0xd9fcb31f": "comm_channel()", "0x141c4e60": "challenge(uint256,address)", "0x4ff13571": "x2()", "0xa01bc729": "monster_attack(uint256)", "0x2fe9541f": "addIssueBounty(string,uint256)", "0x5503a659": "smallponzi()", "0xdfc765dc": "getMatchers_by_index(uint256)", "0x0b7623ba": "abs(int8)", "0xcde0a4f8": "setRegulator(address)", "0xf95b5a58": "getInitialAnswer(uint256)", "0x66b42dcb": "register(address,string,uint256,string)", "0x9f2ce678": "vote(bytes32,bool)", "0xb3559460": "getGenerationSize(uint256)", "0x5ddae283": "transferRegistrars(bytes32)", "0x59dc735c": "getClient()", "0xc258ff74": "List()", "0x4fb4bcec": "step5()", "0xed684cc6": "trigger(uint256)", "0x09405164": "getOpenCandidates()", "0x5c5d625e": "getProof()", "0x9f5f7c7f": "tokenSplit(address,address,address,uint256)", "0x0e38901a": "unvault(uint256)", "0x75160a20": "pay_royalties()", "0x15398afe": "compareNumericStrings(string,string)", "0xbbd8b602": "getOracleOutcomes(bytes,address[])", "0xebae35a6": "DAOTokenCreationProxyTransferer(address,address)", "0x15abc160": "createValidatedRequest(address[3],address,uint256[11],uint256,bytes)", "0x830953ab": "claimAmount()", "0x26b916b4": "Set_Interest_Rate(uint256)", "0x1fb291cb": "registerInt(address,int256)", "0x505fb46c": "add(uint256,uint256,uint256)", "0xf00d4b5d": "changeOwner(address,address)", "0x034187fd": "setEthToCents(uint256)", "0x94d9cf8f": "CreateProxyWithControllerAndRecovery(address,address[],uint256,uint256)", "0xacbf98a7": "endsWith()", "0xfc2c3e08": "getIteration()", "0x6d7da0b1": "MyContract()", "0x1558ae4d": "Etheroll()", "0x42cbb15c": "getBlockNumber()", "0x29cd62ea": "setPubkey(bytes32,bytes32,bytes32)", "0x2030f721": "num_objects()", "0xbc08afd9": "WebOfTrustToken(address,uint256)", "0x8cdfb1e6": "transferIfHF(address)", "0xa0bd3c0f": "scheduleCall(address,bytes,bytes,uint256)", "0x4e71e0c8": "claimOwnership()", "0xc1cc0775": "calculateFeeDynamic(uint256,uint256)", "0x50c42921": "replicate()", "0x25495998": "getMinimumConsumerDeposit()", "0x3d8e2947": "getFileAddress(bytes)", "0x1f794436": "getBlockHeader(int256)", "0x7d380265": "addOptionChain(uint256,string,uint256,uint256,bytes32,address,int256[])", "0xec0b4153": "getMoneyness(int256,uint256,uint256)", "0x01775f23": "_closeBooks()", "0x9d063ed8": "FIFSRegistrar(address,bytes32)", "0x083b2732": "callback()", "0xa1920586": "offer(uint256,uint256)", "0x19c47214": "getBlockVersion(bytes)", "0xa293d1e8": "safeSub(uint256,uint256)", "0xfe73e3ec": "preliminaryGameResult(uint64)", "0xf004b12b": "CrowdFund(uint256,uint256,address)", "0x54d03b5c": "changeFeeMake(uint256)", "0x9dbc4f9b": "participantDetails(uint256)", "0xd002462b": "setDeploymentFee(uint256)", "0xed2b8e0b": "getPoolRotationDelay()", "0xf697a0ed": "ppb(uint256,uint256)", "0x964c836c": "receiveExecutionNotification()", "0x5e0e2957": "dumpOut()", "0x33232609": "blake2b(uint64[],uint64[],uint64)", "0x88f53db1": "getDataRequest(uint256)", "0x0caf9d39": "testFailTooManyMembers()", "0x1f2e886c": "testControllerTransferTriggersEvent()", "0x586a69fa": "getMaximumStackCheck()", "0xf64fca2e": "getNodeId(bytes)", "0x8b95ec0c": "testAddBalance()", "0x32e7c5bf": "B()", "0x57e6c2f4": "isAuthorized()", "0xb2f2588b": "sortNumbers(uint8[3])", "0xe95bee59": "checkFormat(string)", "0xcef887b0": "storeBlockWithFee(bytes,int256)", "0xbe26733c": "Kill()", "0xe82f7dd4": "testThrowsRetractLatestRevisionNotUpdatable()", "0xfd7ac203": "TestToken()", "0x6d052f56": "testBitsSetSuccess()", "0xf65c4d42": "Participate(uint256)", "0x432c685f": "trustClient(address)", "0xb0171fa4": "getCurrentGenerationId()", "0x03251a08": "setMin(uint256,uint256)", "0x58d3b617": "Notifier(string)", "0x15dacbea": "transferFrom(address,address,address,uint256)", "0x83f7b8e1": "getNumberOfPhotos()", "0xf1076703": "getVerificationId(address,bytes,bytes)", "0x752a3df6": "transferIfHardForked(address)", "0xaf93afdd": "Shipment(bytes,bytes,bytes,bytes,string,bytes,uint256,uint256,bytes,bytes,uint256,uint256,string,bytes,bytes,bytes)", "0x7fcf532c": "Withdrawal(address,uint256)", "0x72ea4b8c": "getNumInvestors()", "0x7df52ba8": "Arbitrate(uint32,uint32,bool)", "0xea25f24a": "TokenCreation(uint256,uint256,address)", "0xf74100e3": "getBits(bytes)", "0x63bfe3d8": "SkillBeatsLuck()", "0x80599e4b": "remove(string)", "0x6c050eae": "look()", "0xf9a794ad": "EtherLovers()", "0x501e8428": "getPart(bytes,uint256)", "0xf446c1d0": "A()", "0x2d67bb91": "World()", "0xeef547d7": "deal_details(uint32)", "0xa6cb9e64": "scheduleCall(address,bytes,bytes)", "0x659010e7": "m_spentToday()", "0x9b0b9c07": "acceptBankDraft()", "0x315e2f1b": "setTestString(string)", "0x69bcdb7d": "getCommitment(uint256)", "0xe1376da2": "updateFirstActiveGamble(uint256)", "0xc70d169d": "answerRequest(uint256,bytes)", "0xa094a031": "isReady()", "0x74e60a48": "cancelOrder(address,uint256,address,uint256,uint256,uint256,address,uint8,bytes32,bytes32)", "0x1b5ee6ae": "mintToken(int256,address,uint256)", "0x7f791833": "toTimestamp(uint16,uint8,uint8,uint8)", "0x5e6ad49d": "_setCosignerAddress(address)", "0xb2e85b67": "getPlayerStatus(address,uint256)", "0x30a24abd": "create(bytes4,bytes)", "0x9f0e3107": "get_timestamp(bytes32)", "0x33397816": "withdrawAccountBalance(address)", "0x0da3e613": "EthFactory()", "0xa5f3c23b": "add(int256,int256)", "0xc1829a14": "testFailTooFewConfirms()", "0x5322f0c5": "getChannelOwner(bytes)", "0x0fd1f94e": "firstClaimBlock()", "0x639d57f2": "testGetBitSuccess()", "0xd3aa22c7": "transferTLA(string,address)", "0x86314af9": "BetOnHashV84()", "0x3059ac30": "Escrow(address,address)", "0x0efafd01": "getPlayerGainLossOnLastFlip()", "0x49bf66d3": "addRegistryIntoNameIndex(address)", "0x3af39c21": "undefined()", "0xb660d77c": "switchMPO(address,address)", "0x0fdb468f": "fee(uint64)", "0x72479140": "CreateTicket(address,uint8,uint8,uint8)", "0xe79a198f": "unregister()", "0x688dcfd7": "setProofType(bytes1)", "0xfb9a4595": "GitHubBounty()", "0xd02a9889": "getDateOfFirstPayment()", "0xca35271c": "numDebtors(address)", "0x08714bfa": "TestContract()", "0x16d960b5": "createThing(bytes32[],bytes32[],uint88)", "0x17961d0f": "ord()", "0x62ba9687": "toTimestamp(uint16,uint8,uint8,uint8,uint8)", "0xbba91ea7": "getHomeadvIndex(uint256)", "0xb45105b2": "post(string,address,string)", "0xa7e25683": "testShortOutput()", "0xa068e8d3": "convict(uint256,uint256,uint256,uint256)", "0x09a69f57": "getRewardAmount()", "0xe7334156": "processNextDeposit(address)", "0x62ee6d29": "changeHashtoLowOrHigh(uint256)", "0xa80d4e9a": "EtherAuction(uint256)", "0x18489f50": "thingExist(bytes32[])", "0x5323c6cf": "calcCostsBuying(bytes,uint256,uint256[],uint8,uint256)", "0x9a777d5d": "buyCoins()", "0x36344022": "testAuthorizedTransfer()", "0x8b863095": "setContractorProposal(uint256,bytes)", "0xd10e99fe": "mint(int256,bytes32)", "0x12c82bcc": "sendRobust(address,uint256)", "0x0bf75567": "voteSuperQuorum(uint256,bool)", "0xf5f6ea26": "EthOne()", "0x14918f5e": "performInitialWithdrawal()", "0xdf32754b": "owned()", "0x1632070c": "setRewardDivisor(uint256)", "0xe50a3bb1": "oraclize_query(string,string[],uint256)", "0x9b619d3b": "_deleteAllPackedRevisionBlockNumbers(bytes32)", "0x3b751f7f": "claimThroneRP(string)", "0xd55ec697": "upgrade()", "0x43703b0e": "getEventData(bytes)", "0xd1bf9aba": "nextRune()", "0x76849376": "addNode(bytes32,address)", "0xfd958695": "isAlphaNumeric(bytes1)", "0x9fa5e5d5": "setARKowner(address)", "0x6e2cde85": "drawPot(string,string)", "0x4d5b080c": "scheduleTransaction(uint256,address,uint256)", "0xf1e4a540": "unsetCoordinator()", "0x364f4896": "emission(address,address,uint256,uint16,uint16)", "0x9183fd01": "getSeedPrice()", "0x9832ee65": "resultsWeightedByTokens()", "0xdd5244b4": "testTryProxyCallWithValue()", "0xec2ec781": "testFailGetUnsetToken()", "0x7db9743b": "Registry()", "0x1adf2d1a": "Offer(address,address,bytes,uint256,uint256,uint128,uint256)", "0x1ba326c4": "calcShare(uint256,uint256,uint256)", "0x3ced842b": "make_offer()", "0xea295ec2": "calcRevenue(address)", "0x3c894475": "scheduleTransaction(address,bytes,uint8,uint256[6],uint256)", "0x477bddaa": "setContractAddress(address)", "0xed180443": "getUint256(int256)", "0xee725d44": "toChannelID(string)", "0xa4898fd5": "deployContract(address)", "0x75ee85bd": "salsa20_8(uint256,uint256)", "0xbe7c29c1": "getNewDAOAddress(uint256)", "0xfe01f1ff": "TokenTester()", "0x6103d915": "Winners(uint256)", "0xa30b5c69": "AttributeModel()", "0x81064e2d": "getCreditorAmounts()", "0x23584a21": "initStats(string,address,uint256)", "0xe2894a8a": "OwnerAnnounce(string)", "0xa84c5330": "createNewRevision(bytes20,bytes)", "0xb742398b": "trade(address,uint256,bytes,address,uint256,bytes)", "0x3211bb90": "OwnerAddFunds()", "0xa0befa94": "getStake(uint256,uint256)", "0x6dc3edcf": "executeExecutable(uint256,uint256)", "0x17e875e3": "Transparancy()", "0x6939864b": "lotteryState()", "0x3b107682": "DualIndex()", "0x51b3d7b9": "_transferWithReference(address,uint256,string)", "0xdf7cec28": "cancelBid(bytes32)", "0x1e74a2d3": "getMinimumEndowment()", "0x39b333d9": "Play(uint8,uint8,uint8,uint8)", "0xcbd08c8c": "config(uint256,uint256,uint256,uint256)", "0xca6ad1e4": "setCustomGasPrice(uint256)", "0x510f44cb": "TestFactoryUser()", "0xcee6ee38": "aEthereumlotteryNet()", "0x11610c25": "bet()", "0xb73405a9": "roundMoneyDownNicely(uint256)", "0xb8851fea": "endDateStart()", "0xa4325485": "getCreatorBalance()", "0x2c181929": "getChainWork()", "0xffb4c857": "_confirmAndCheck(bytes32)", "0x9e66cd38": "free(uint64)", "0x44e43cb8": "depositRevenue()", "0xa553a597": "configure(uint256,uint256,uint8,address)", "0xc47f0027": "setName(string)", "0x565a2ecf": "classicTransfer(address)", "0x1da0fb1b": "updateSettings(uint256,uint256,uint256,uint256,uint256,bool)", "0xa5ebf389": "getMoneyTotals()", "0x7f445c24": "subRegistrar(string)", "0x9ad4f98e": "BlocksureInfo()", "0xd6b4ec12": "getDailyWithdrawalLimit()", "0xe0886f90": "at(uint256)", "0x5dc77e26": "andThen(string,address)", "0xe7d50e5c": "FarmShare()", "0x3f2965f0": "registerSeller(address)", "0x85b73d3c": "testCreateNewRevision()", "0x49437210": "getUpdatable(bytes32)", "0xe1a9109d": "setSeedPrice(uint256)", "0x95978868": "strConcat(string,string,string,string,string)", "0x511b1df9": "addr(string)", "0xc5b1d9aa": "newRound()", "0xecf6eb22": "setConfigAddress(bytes,address)", "0x9a9c9c53": "DepositToBankAccount()", "0x27ea6f2b": "setLimit(uint256)", "0xd2dc0869": "add(string,uint256,string,string,address)", "0xc86a90fe": "sendCoin(uint256,address)", "0x5dfc2e4a": "noop()", "0xd81e8423": "get(address,address)", "0x4cad42d3": "testWager()", "0xd120a284": "getBytesFromNumbers(uint8[3])", "0x991ffd4e": "scheduleCall(address,bytes,bytes,uint256,uint256,uint8,uint256)", "0x60c311fd": "doBurnFromContract(address,uint256)", "0xbb6a0853": "GreedPit()", "0xc27b2c2d": "collectEarnings()", "0x446294ad": "multiAccessGetOwners()", "0x5bec9e67": "infinite()", "0x47e7ef24": "deposit(address,uint256)", "0x8d216186": "roll(uint256,bytes32)", "0xdf300b46": "getThing(bytes32[])", "0x5a6c787e": "updateWithMPO()", "0x1f2dc5ef": "divisor()", "0x421aeda6": "Set_your_game_number(string)", "0xba1162d7": "getFmLength()", "0x853255cc": "sum()", "0x20768ee8": "getProposalID()", "0xf5c57382": "nameOf(address)", "0x4e417a98": "callData()", "0xc90d080a": "registerEvent(bytes)", "0x0b1e400a": "_transferFromToICAPWithReference(address,bytes32,uint256,string)", "0xe420264a": "g(uint256)", "0x8a00a82f": "withdrawRewardFor(address)", "0x06638e92": "GetNumbersFromHash(bytes32)", "0xf63da25b": "Emailer()", "0xc01706dd": "getContentByRank(address,uint256,uint256)", "0xe1108706": "rfind()", "0xffd10e07": "enterPool(address)", "0xc4254c7b": "CoreWallet()", "0x30e0789e": "_transfer(address,address,uint256)", "0x992ae976": "isSafePunctuation(bytes1)", "0x4afce471": "test_requires_depth(uint16)", "0xda7fc24f": "setBackend(address)", "0xeb7402f5": "multiAccessHasConfirmed(bytes32,address)", "0x6c1a5b8c": "TOKEN_TARGET()", "0xb3a2a999": "nextWithdrawal(bytes16)", "0x4a420138": "scheduleHeartbeat()", "0xb1233451": "setTerm(uint256,string)", "0x266710ca": "manualUpdateBalances_only_Dev()", "0x98866c1a": "personUpdateDOD(uint256,int256)", "0xaa6be303": "debtors(address)", "0xda5c0a7c": "testDisown()", "0x8757a2cd": "test_depth(uint256,uint256)", "0xe1bedf2a": "AlarmTester(address)", "0x5dcbac7a": "registerBytes(address,bytes)", "0xa587da29": "setPackage(bytes,uint8,uint8,uint8,bytes)", "0xc3da42b8": "c()", "0x4b8772c1": "buyUnit(uint256,uint256)", "0x67f12ecf": "validate(address,uint256,uint256[101][])", "0x0bd089ab": "MyAdvancedToken(uint256,string,uint8,string,address)", "0x32829a23": "OpenBankAccount()", "0xdea06188": "NumberOfBlockAlreadyMined()", "0x61e539da": "testFailWrongAccountTransfers()", "0x8a3e44d4": "assetMoveInformation(address,address)", "0x1327d3d8": "setValidator(address)", "0x207c64fb": "validate(address)", "0x80acaafb": "profitDistribution()", "0x90b98a11": "sendCoin(address,uint256)", "0x8b147245": "update(bytes32)", "0x920c94df": "BuyTicketForOther(address,uint8,uint8,uint8)", "0x6f698fb5": "setMinimumQuorum(uint256)", "0xac5e81a9": "historyPayout(address)", "0x70d084c0": "SingularDTVCrowdfunding()", "0x67ce940d": "getOverhead()", "0x7a791524": "setNextFeePercentage(uint8)", "0xd6d902c4": "claimThroneFor(bytes,address)", "0xc71e48d6": "setOutcome(bytes32,bytes32[])", "0xef41e06f": "testThrowSetEnforceRevisionsNotOwner()", "0x70be4ffa": "testErrorUnauthorizedSetPackage()", "0x6d12301c": "getBetValue(bytes32,uint8)", "0x4e69d560": "getStatus()", "0x55234ec0": "remaining()", "0x5cfd8c24": "ResetPonzi()", "0xe29fb547": "scheduleCall(bytes4,uint256,uint256,uint8,uint256)", "0xbd119967": "add_rating(uint256,uint256)", "0x966acb38": "testThrowTransferNotTransferable()", "0x5c665f89": "getFunds(address,bool)", "0xa59d6986": "recoverLostFunds()", "0x403abbc7": "updateFirstActiveGamble()", "0x0230a07c": "releaseDeed(bytes32)", "0x2d116186": "deityBalance()", "0x602acca1": "InchainICO(address[],uint256)", "0xd393c871": "register(string,address,uint256)", "0xe0fe075e": "payoutReady()", "0xf3e3c629": "testBalanceOfStartsAtZero()", "0x48cd4cb1": "startBlock()", "0x669459a7": "removeRegistryFromOwnerIndex(address)", "0x74d89c47": "testUpdateNameDb()", "0x182db370": "getWhatHappened()", "0xf363441f": "getCreatorDotBalance()", "0x6896fabf": "getAccountBalance()", "0xb29a0308": "logAnonymous(bytes,bytes,bytes,uint256)", "0x3023d0c4": "Ethstick()", "0x1077f06c": "makeClaim(uint256)", "0x8a519fb9": "BlockChainEnterprise()", "0xbffbe61c": "node(address)", "0xe20bbd8d": "RecoveryWithTenant()", "0x03bda14e": "raiseMaxNumBets(uint256)", "0xe1041d86": "__throw()", "0x3d79d1c8": "bal()", "0xbd3f0965": "AiraEtherFunds(string,string)", "0xc388cca6": "testBitAndFailIndexOOB()", "0x921f98bb": "resolveFailVote()", "0x4bbb216c": "_target(address)", "0x10922cc1": "testTransferCost()", "0xeceb2945": "checkProposalCode(uint256,address,uint256,bytes)", "0x3df4ddf4": "first()", "0x21a49ec2": "LCoin()", "0x6d1f00a6": "ThroneMaker(uint256)", "0xcaed4f9f": "DataService()", "0x5cff876b": "carrotsCaught()", "0x3a7fb796": "mintGreen(int256,address,uint256)", "0x370b6939": "AdminSetDrawer(address)", "0x2d9a37d3": "getMaxPayout()", "0x739f888c": "setNewEstimate(int256,int256)", "0x04dd69fa": "getGenerationIdForCall(address)", "0xb764e273": "failSend()", "0xd4dfadbf": "getMarket(address)", "0xa0e67e2b": "getOwners()", "0x2d592a34": "sellKissBTC(uint256)", "0x8a341c83": "testErrorRootAuthorityChangeUnownedPackage()", "0xfcc6b5d5": "fillTheirOrder(address)", "0x61649472": "getPoolFreezePeriod()", "0x3dd297da": "safeMultiply(uint256,uint256)", "0x5d3278f0": "LooneyFifty()", "0x7399646a": "theRun()", "0x3e450fff": "adminDeleteAccount()", "0x93cc9162": "taskRejected(uint256,uint256)", "0xbc5d0f65": "beginExecution()", "0x1934d55a": "isPermanentlyApproved(address,address)", "0xf1cff4b5": "testBitsNotSetSuccess()", "0xf240f7c3": "dispute()", "0xf6d5959b": "getActionStatus(uint256)", "0x0f23cbaa": "recycle()", "0x74f8d96e": "getRevisionBlockNumber(bytes20,uint256)", "0x0bad342a": "EscrowContract(address,address,address,address,uint256,uint256,uint256,uint256)", "0xa6afd5fd": "getBets()", "0x84ad6ff3": "ReversibleDemo()", "0x62b3b833": "createCoupon(string)", "0x523ccfa8": "isKnownCall(address)", "0xacc8cb18": "pushTerm(string)", "0xa753d6f2": "CreateProposal(string,string,string,string,string,string,uint32,uint32)", "0xc5699d68": "_compare(int256,bytes,int256)", "0xe2faf044": "createDAO(address,uint256,uint256,uint256)", "0xa15afb48": "Replicator()", "0x352d2790": "UUID4()", "0x7dee2cad": "CancelMyInvestment()", "0xbeabacc8": "transfer(address,address,uint256)", "0x674f220f": "previousOwner()", "0x4b3b6168": "SetNewBigContract(address)", "0x54ba7daa": "enter(bytes,bytes)", "0x06fdde03": "name()", "0x5944427b": "getRequestResult(uint256)", "0x983ef725": "getDifficulty(uint256)", "0x9287c877": "getNavLength()", "0xa987d654": "restoreItem(uint256)", "0x05433a26": "GetNumbersFromHash(bytes)", "0xd04bfc9c": "buyer_pay()", "0x4a9b3f95": "personUpdateName(uint256,string)", "0xe6b972f5": "userName(address)", "0x88782386": "UnicornMilk()", "0x74580e2f": "changeCreator(address)", "0x1785f53c": "removeAdmin(address)", "0xad544dcb": "testSetNotUpdatable()", "0xafd09bab": "quadrupler()", "0x77bc222c": "_eraseSingleNode(bytes32)", "0x09957e69": "newSale(bytes,uint256,uint256)", "0xa21931ea": "CreateProposal(string,string,string,uint32,string,string,string,uint32,uint32)", "0xbb6b4619": "SendETC(address)", "0x3aa94b1d": "getCoinStats(uint256)", "0x9e2262f5": "testCreateCostData()", "0x2bf4e53d": "getCurrentShareholders()", "0x6111dd02": "calcCostsSelling(uint256,uint8,uint8,uint256)", "0x6b9b1006": "TransactionRecorder()", "0x83b23b40": "cEthereumlotteryNet()", "0x770c6cbb": "WithDrawPreForkChildDAO()", "0x67080f6e": "testThrowsSetEnforceRevisionsNotOwner()", "0xa10bee85": "_transferFromWithReference(address,address,uint256,string)", "0x49cc954b": "twoYearsPassed()", "0x88c3ba85": "ParallelGambling()", "0x03985426": "getMode(bytes32)", "0xad8ed335": "__proxy(address)", "0x306387a4": "dealStatus(uint256)", "0x0343dfa0": "checkInvariants()", "0x23df9df5": "_refund(uint256)", "0x837e7cc6": "rollDice()", "0x98b1e06a": "deposit(bytes)", "0xa0440426": "purchaseProduct(uint256,uint256)", "0x4cb71b9b": "getAllReleaseHashes()", "0x3a7d280c": "login(string)", "0xb9a904f9": "testUnauthorizedSetBetaPackage()", "0xe94a4db1": "isSuitableGen(uint256,uint256)", "0x60f8af90": "refundRound()", "0x43bf718e": "getHashOfTheProposalDocument()", "0x4a30f976": "censorship(uint256,bool,bool)", "0x47e46806": "toString()", "0x8d59cc02": "register(address,string,string)", "0xb3fb14ad": "getGameResult()", "0x4a23dc52": "FileStore()", "0x8da5cb5b": "owner()", "0x3cc8daf7": "setNameOwner(bytes,address)", "0x14cbdb54": "EspCoin()", "0xc47cf5de": "getAddress(bytes)", "0x71e11354": "updateRegistration(string,string)", "0x8b2e6dcf": "publish(bytes32)", "0x12d00c2e": "soloWithdraw(uint256)", "0xd68199dc": "gameStats()", "0xf0f967e8": "canCall(address,address,bytes)", "0xe0c7c117": "Randao()", "0xddeae033": "claimFor(address)", "0xcec7260b": "move_monster(uint16,uint16)", "0xe51ace16": "record(string)", "0x4f76cb02": "testGetBitFailIndexOOB()", "0x942385eb": "getPayroll()", "0x46d667db": "setBytes32(bytes)", "0x35a063b4": "abort()", "0xb1d51d31": "pay(uint64,address)", "0x7140bdf3": "get_all_best_offers()", "0x0380e2f3": "getHashOfTheSignedDocument()", "0x2feda2fa": "POI()", "0x3c0870ae": "challenge(uint256,uint256,uint256,bool)", "0x27a5c7c6": "voteDecline(uint256)", "0xafd8c8c4": "GasProxy(address,address)", "0x8de93222": "purchase(address,uint256)", "0x087e055a": "getConfigBool(bytes)", "0xbaccc92b": "RegulatorIfc(address)", "0x8c546f81": "GNT()", "0x57cb2fc4": "getInt8()", "0xe3083fb5": "removeFromContribution(uint256)", "0x1a092541": "getDescription()", "0x7486a8e3": "get_publisher(bytes32)", "0x089e0ad0": "buildDSMap()", "0x29161820": "Base(uint256)", "0xe2f8feb2": "internal_tester(int256)", "0x1d2dbb22": "CancelMyInvest()", "0x726ab4ef": "getParentHash(bytes)", "0x83d8a90f": "theDonkeyKing()", "0x9babdad6": "removeShareholder(address)", "0xdeb931a2": "getOwner(bytes32)", "0x90cb04e1": "buy(string,uint256,uint16)", "0x2ff92323": "oraclize_query(uint256,string,string[4])", "0xf91a792e": "decryptHand(string,uint256,uint256,uint256)", "0xebf6e91d": "hit(uint256)", "0xb085b9a5": "Example()", "0x07b2779f": "BasicRegulator(address,uint256,uint256)", "0xe10e5dce": "_build(bytes)", "0x3e239e1a": "getHour(uint256)", "0xacc5a0dc": "GetPrize()", "0xa79deb4f": "acceptTradeDeal()", "0xd7c26adb": "oraclize_setProof(bytes1)", "0xc6a17d2b": "pow10(uint256,uint8)", "0xa87d942c": "getCount()", "0xe706918c": "testToggleBitSuccess()", "0xc1812b15": "reorganizeOwners()", "0x7c7c7695": "getAccountID(address)", "0x1a26ed1c": "validateReservedWindowSize(uint256,uint256)", "0x87393bc6": "verifyFirstHalf(uint256[4],uint256[4])", "0x2e52d606": "n()", "0x2037fcbf": "withdrawInvestment(uint256)", "0x77228659": "query2(uint256,string,string,string)", "0xf67a1d37": "BlockChainChallenge()", "0xc67146a5": "check_bet(uint256,address,uint8)", "0xc89f2ce4": "funds()", "0x58e29e17": "initiateProof()", "0xf0e10c0d": "play(address,uint256)", "0x480b70bd": "scheduleCall(address,bytes4,uint256,uint256)", "0x5294157f": "sendWithAllOurGasExceptExt(address,uint256,uint256)", "0xad447a19": "getBalanceDB()", "0x41095b60": "voteForUltimateOutcome(bytes,uint16)", "0x5521d17b": "betOnColor(bool)", "0xc8f8d75d": "Config(uint8,address)", "0x10ae4ce2": "setReleaseValidator(address)", "0x9fd4f7d1": "replaceWizard(address)", "0x77c78df9": "getCurrentLevel()", "0x1dda5c7d": "testFailSubBalanceBelowZero()", "0x21e5383a": "addBalance(address,uint256)", "0xb0414a2d": "setMinimumGasLimit(uint256)", "0x919840ad": "check()", "0xf651bf44": "move_to(uint16)", "0x0b97bc86": "startDate()", "0x29f1bff4": "withdrawFromChildDAO(uint256)", "0x7a02dc06": "getInfo(bytes32)", "0xe5bf93b9": "balanceEther(uint256)", "0x288c6ed2": "getSeedCost(uint256)", "0x4db3da83": "scheduleCall(bytes4)", "0x270cfee1": "getTokenAccount()", "0xb5d03751": "YoutubeViews()", "0x27e056a5": "addMinter(int256,address)", "0xfa7d68f1": "getAccountInfo(uint256,uint256)", "0x09fc8f6d": "isTokenUpgraded(bytes32)", "0xa5b9e922": "getContentTimetamp(uint256)", "0x1f8947c1": "extractUint(int256,bytes,uint256,uint256)", "0xbcc941b6": "totalWinners()", "0x1db71ffb": "doLoops(uint256)", "0x35ae41c9": "godAutomaticCollectFee()", "0x42cf0e72": "searchByOwner(address)", "0x69f18967": "testSetBitFailIndexOOB()", "0x57b07cd9": "getReleaseHash(uint256)", "0x2baf4f22": "_safeFalse()", "0x3133f2a7": "outstandingBalance()", "0x773c84ee": "exec(address,bytes,uint256,uint256)", "0x9070b18d": "_getAllRevisionBlockNumbers(bytes32)", "0x476e04c7": "NewMessage(string)", "0x3b91ceef": "setMax(uint256,uint256)", "0xe6cb9013": "safeAdd(uint256,uint256)", "0xc2038560": "setOutcome(bytes,bytes)", "0xbed34bba": "compareStrings(string,string)", "0xba8661a2": "TimestampScheduler(address)", "0x4c4aea87": "getReleaseData(bytes32)", "0x1177892f": "getBalanceByAdress(address)", "0x126a710e": "dnsrr(bytes32)", "0x60913244": "botOnSale(uint256,uint256)", "0x5731f357": "oraclize_query(uint256,string,string,string)", "0x3e58c58c": "send(address)", "0x2187a833": "setGreenToken()", "0x5f09952e": "voteAllowTransactions(bool)", "0xf2b26d8f": "nextEtherForSale()", "0x1f201e39": "etherandomExecWithGasLimit(bytes32,bytes32,uint256,uint256)", "0x43d726d6": "close()", "0x6cdf4c90": "ownerSetMinBet(uint256)", "0xe6e8c692": "computeResponseFirstHalf(uint256,uint16)", "0xd1d80fdf": "setAddr(address)", "0x6da1833c": "getInstitutionByName(string)", "0x7682e6ff": "getTrustSetting(address)", "0x8f6f988c": "setUltimateOutcome(bytes)", "0xe299beb3": "SimpleIndex()", "0xa2bb5d48": "get_username(address)", "0x780900dc": "create(uint256)", "0x78710d37": "seven()", "0x2b20e397": "registrar()", "0x4094ef5e": "addDataRequest(string)", "0xc630f92b": "canEnterPool()", "0xdd114c22": "publish(address,uint256,address,uint256)", "0x57006864": "checkBetParity(uint8)", "0x45788ce2": "prev(address)", "0xee8ff562": "setMaxProfit()", "0xdc63a62c": "getFileListHead()", "0x9447fd0a": "until()", "0xb303dcbd": "Owned()", "0x0ecaea73": "create(address,uint256)", "0x20339891": "addGridMember(address)", "0xc8c01a55": "request(address,uint256)", "0x76f10ad0": "getSnapshot(uint256)", "0xc06c4474": "get_burned(bytes32)", "0x67cb61b6": "getChoice()", "0xca708230": "funnel()", "0x08b7fa31": "PriceFeed()", "0xac6bc853": "startSpin()", "0xf4bbfd6a": "scheduleCall(bytes,bytes)", "0xab73e316": "next(address)", "0xba0179b5": "confirm(uint256)", "0x1e62be25": "Bytes32Passer()", "0xb950556a": "setThingValid(bytes32[],bool)", "0xb61c0503": "fireEventLog1()", "0x79a85e6c": "getProductInfo(uint256)", "0x959ac484": "push(uint256)", "0x78e80b39": "UserGetPrize()", "0xff74927b": "strConcat(string,string)", "0xd207e757": "ownerSetOraclizeSafeGas(uint32)", "0x5819dde2": "getNumbersFromBytes(bytes3)", "0xf34ed4e6": "RanDAOPlus(address)", "0x3943807b": "insert(bytes,bytes,int256)", "0x38cc4831": "getAddress()", "0x12a7b914": "getBool()", "0xa4fd6f56": "isEnded()", "0x6c86888b": "testTrade(address,uint256,address,uint256,uint256,uint256,address,uint8,bytes32,bytes32,uint256,address)", "0x0bebd0f9": "addAddressToGeneration(address,uint256)", "0x003074ff": "getFrontend()", "0x2776a859": "computeResponseSecondHalf(uint16)", "0xadfe6b80": "InvestAdd()", "0x6981b5f4": "getLength(string)", "0x4a994eef": "setDelegate(address,bool)", "0xbac1e9f6": "getChannelSize(address,uint256)", "0xbdfdb519": "accept(string,uint256,uint16)", "0x68f5aa0f": "setShareholderDB(address)", "0xafb95eed": "logApproval(address,address,bytes32)", "0xae152cf4": "oraclize_query(string,string,uint256)", "0xe3b26a8c": "SocialNetwork()", "0x54204ad4": "triple()", "0xbc8f3bcb": "ZeroDollarHomePage()", "0xf0350c04": "transfer_ownership(address)", "0xfde9ba41": "transfer(bytes,address,uint256)", "0xfa2acd87": "G(uint64[16],uint256,uint256,uint256,uint256,uint64,uint64)", "0x3a76abff": "_eraseNode(uint256,bytes32[],bytes32)", "0x0acf473b": "AdminCloseContract()", "0x299e7318": "resolveVoting()", "0xb414d4b6": "frozenAccount(address)", "0x8d375da2": "testMakeItFail()", "0x6e8dad74": "retrieveAccountBalance(bytes,bytes)", "0xd3aa831f": "testOwnedTryAuth()", "0x13220305": "doTransferOther(address,address,address,uint256)", "0xb0c7f709": "kingAutomaticCollectFee()", "0x2dabbeed": "reclaim(uint256)", "0x5c19a95c": "delegate(address)", "0xbc2a4dd6": "doBalanceOf(address)", "0x8e7ea5b2": "getWinner()", "0xdb37e42f": "multisetProofType(uint256[],address[])", "0xa6b197aa": "Order(address,uint256)", "0x8cf4dbfb": "collectBalance()", "0xd0821b0e": "bet(uint8)", "0xa02b161e": "unregister(uint256)", "0x09dd0e81": "getBlockchainHead()", "0x8a0807b7": "indexOf(string,string)", "0xe3914699": "dEthereumlotteryNetWinners(address)", "0x44d75fa9": "updateMinorTree(bytes32)", "0x3c21db0a": "theGames(uint256)", "0xf0e959f9": "TokenSales(address)", "0x696bda86": "submitProposal(uint256,bytes)", "0x3b343a13": "getNodeAddress(bytes)", "0x2812f8b8": "FutureCall(address,uint256,uint16,address,bytes4,bytes,uint256,uint256,uint256)", "0xbf32bf97": "FailGuyTax()", "0x89ced196": "setNotUpdatable(bytes32)", "0xb94e962a": "allocateTickets(uint256)", "0x7a479160": "getRequestArgs(uint256)", "0x5a825cbb": "getPayment(uint256,uint256)", "0x4ca8b0d0": "registerExistingThrone(bytes,address,uint256,uint256)", "0x82afd23b": "isActive(uint256)", "0x6ebf10fe": "storeHeader(bytes,address)", "0x1437f9a3": "Set_your_game_number(uint16)", "0xd98d011d": "getCandidateKey(bytes,bytes,bytes,bytes)", "0x8b676ae8": "scheduleCall(address,bytes4,uint256,uint256,uint8,uint256,uint256)", "0x90fd53ec": "farmTile(uint8,uint8,int8)", "0x46e44f63": "getCheckRecordTS(bytes)", "0x1de38038": "makercoin(uint256)", "0xc038a38e": "totals()", "0xfa80918b": "computeNodeId(bytes,bytes)", "0xc76a4bfb": "relayReceiveApproval(address,address,uint256,bytes)", "0x2406cedb": "setPackageOwner(bytes32,address)", "0xb7297cf3": "gameSettings()", "0xe94acf0e": "TinyRouter(address)", "0x4a2b0c38": "DividendProfit()", "0x0e3f732a": "TheGame()", "0xd62457f6": "callValue()", "0x4961b40c": "getReleaseValidator()", "0x540cafe0": "storeHeaderWithFee(bytes,int256,address)", "0x7ff729fc": "fillUpProject(uint256,uint256)", "0x253459e3": "feesSeperateFromBalanceApproximately()", "0x930a80b4": "testAuthorizedSetPackage()", "0xb3cb8885": "nextUnderdogPayout()", "0x62c7855b": "getConfigBytes(bytes32)", "0x4f28af6a": "handleBet(uint256)", "0x103f9251": "transferFrom(address,address)", "0x9b19251a": "whitelist(address)", "0x9928811b": "testBroken()", "0xb33a8a11": "setTokenReference(address)", "0x27f06fff": "requestFillUp(uint256)", "0x2f570a23": "test(bytes)", "0x96ef7aa0": "cash_transfered(string)", "0x3983d5c4": "calcBaseFee(uint256)", "0xec0f1025": "testBitsOrSuccess()", "0xd35f4a99": "mint(int256,address,uint256)", "0x09dfdc71": "currentPyramidBalanceApproximately()", "0xac4e73f9": "proposeReverse(string,address)", "0xac4bd53a": "currentLeader()", "0x5a2ee019": "m()", "0xeba36dbd": "setAddr(uint256,address)", "0x0358d965": "addPayout(uint256)", "0xd7206124": "setInvestorLock(bool)", "0xe916d0f0": "doBalance(address)", "0x67c2a360": "authorizeUser(address)", "0x828d671c": "dyn_sig()", "0xaf6fe8e2": "testGetToken()", "0x283a4576": "Tomeka()", "0x8ac0ca36": "buyViaJohan()", "0xcc872b66": "issue(uint256)", "0xd826f88f": "reset()", "0x2aa3177a": "self_store()", "0x53b7b2e9": "cEthereumlotteryNet(bytes)", "0xce88b145": "getAccount(uint256)", "0x1fa03a2b": "isApprovedFor(address,address)", "0xe42d5be0": "getPaymentOf(address)", "0xb722a9ef": "getPreviousShareholder(address)", "0xfadf87b1": "testGetBitsSuccess()", "0xd26c8a8a": "coinBalance()", "0x30ccebb5": "getStatus(address)", "0x47799da8": "last()", "0x4a5db3b5": "authorizeAddress(address)", "0x22686250": "index(int256,uint256)", "0x07ef99a0": "demintTokens(int256,address,uint8)", "0xea2d4cf8": "__DeployerFunctions(address,address,uint256)", "0x092a2e37": "multiAccessAddOwnerD(address,address)", "0x671fa0a0": "Inscription(string)", "0xa10edc55": "GeneralPurposeProfitSplitter()", "0xd9c67404": "getMerkleRoot(bytes)", "0xdc419fd8": "cancelOrder(bool,uint256)", "0xc9734ebd": "WatchLastPayout()", "0xc7d6faf1": "easyPropose(address,uint256)", "0xfe63300a": "registerExternalBill(uint256,address,address,uint256,uint256,uint256)", "0xd3437fe0": "assertFact(uint256,bytes)", "0x5fb3e119": "Auction()", "0x665beae7": "ExecutableBase(bytes)", "0xc8bb73ef": "testGetBitsFailIndexOOB()", "0xc1d4f708": "getMwLength()", "0x22b0f6ee": "getStatusOfPayout(uint256)", "0x21520c5f": "calculatePayout(uint8,bool,uint256)", "0x66e98c31": "createCoin(string,uint256,uint256,string,string,address)", "0x7b352962": "isFinished()", "0x48d9614d": "GetFee()", "0xfe0d94c1": "execute(uint256)", "0xe4547f98": "documentExists(bytes)", "0x4e10c3ee": "transferWithoutReward(address,uint256)", "0x58ae8bcf": "voteInMasterKey(address)", "0x1dcb304b": "fipsGenerate()", "0xb595181f": "ShapeshiftBot()", "0xe02426c1": "getSignatureHash(bytes4,uint256)", "0x67546967": "EthBtcEscrow()", "0x85b31d7b": "myInfo()", "0xaa677354": "register(address,address)", "0x1d2e2cc4": "ENS()", "0x1097e579": "Enter()", "0x13a396d8": "getRequiredDeposit(bytes)", "0x6df3edef": "getSavedBytes()", "0x09b30ed5": "afterExecute(address)", "0x718e6302": "play(string)", "0x8e46fbb2": "testBitsXorFailIndexOOB()", "0x0d87a7c0": "WLBDrawsDB()", "0xbbe42771": "closeDeed(uint256)", "0xedfbf7b6": "setVotingDeadline(uint256)", "0x299e6b07": "Wallet(address)", "0x5cbc85d0": "returnBounty(uint256)", "0xe5225381": "collect()", "0x94f60a63": "getKudosLeft(address)", "0xd6960697": "confirmPurchase()", "0x4a1f0bf6": "inheritToNextGeneration(address)", "0x244ded7a": "ChangeOwnership(address)", "0x39b35753": "authCancel(address)", "0x75cb2672": "configure(address)", "0x938ae4cc": "testThrowDisownNotTransferable()", "0x04fc11d5": "getActual()", "0xacab021c": "getTOS(address)", "0x812cddf2": "getSavedString()", "0x8ae475a9": "notorize(string)", "0xb1d05422": "SendEmail(string,string)", "0x0fffbb54": "changeRankingSize(uint256)", "0xb6ed9f15": "PFOffer(address,address,bytes,uint256,uint256,uint128)", "0xda333ca6": "payOut(uint256)", "0x652f1f16": "addSignature(string)", "0x983b2d56": "addMinter(address)", "0x5e1936d4": "testThrowSetNotTransferableNotOwner()", "0x4ac1ad78": "getWeekday(uint256)", "0x6ba0b4f2": "isKnownSelector(bytes4)", "0x7c4c27c8": "isThisPuritanicalVersion()", "0x7ae2b5c7": "min(uint256,uint256)", "0x63bd1d4a": "payout()", "0x3fd94686": "changeEligibleDonkeys(uint256)", "0x7fe0518a": "asyncSend(address,uint256)", "0x5a8dd79f": "getDesignatedCaller(address,uint256)", "0x2635f4de": "registerLibrary(bytes,address)", "0x1335ff36": "createEventAndMarketMaker(uint256,uint256,uint8,uint32,address,uint256,uint8,uint16,uint256)", "0x181be00d": "getValue(uint8)", "0x9c1500f0": "registerMany(address,uint256,int256,uint256,bytes,address,bytes)", "0x16f9ce49": "_slotCommitNew(address)", "0x8ca4eef6": "getBuild(bytes32)", "0x8ee21b8e": "get_default_keys()", "0xa66f7ad6": "signRelease(uint256)", "0x414053be": "best_adjustment_for(bool,uint128)", "0x83a51ad0": "oraclize_setConfig(bytes32)", "0x262c0b72": "getPayoutFreezePeriod()", "0x499af77c": "current_spin_number()", "0x4209fff1": "isUser(address)", "0x6e1b6bcc": "checkMyBet(address)", "0xb46300ec": "send()", "0x6b1cb549": "orderMatch(uint256,uint256,uint256,int256,uint256,uint256,address,uint8,bytes32,bytes32,int256)", "0x58d9fa04": "addUser(uint256,address)", "0x24c93343": "error(string)", "0xa95d017d": "getRevisionBlockNumber(bytes32,uint256)", "0x46af23f5": "InstantLottery(address,address,bool,address)", "0x29ef56b1": "getAskOrderBookStats()", "0xe97db66e": "setJackpot()", "0x4b59e880": "puzzle(address,bytes32,bytes32)", "0xc7f86c37": "withdrawFundsRP()", "0x57d4021b": "nextPayoutWhenPyramidBalanceTotalsApproximately()", "0xf1c760ae": "fixBalanceInternal(address)", "0x0908178f": "NoFeePonzi()", "0x22ebb3ac": "DieselPricePeg()", "0xb39a64cd": "getNumCalled()", "0x1c02708d": "killContract()", "0x65228934": "setOperationsCallGas(uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)", "0x3397ca17": "numBalanceRecords(address)", "0xe436bdf3": "Draws(uint256)", "0xaf55bba0": "removeRegistryFromTagsIndex(address)", "0x11103599": "Token_Offer(address,address,uint16)", "0xb3a2a6c0": "setOfficialWebsite(string)", "0xb06eb03f": "DSEasyMultisig(uint256,uint256,uint256)", "0x775c300c": "deploy()", "0xb1c6517a": "LookAtNumberOfPlayers()", "0xc19d93fb": "state()", "0xac9873c7": "CanaryV7()", "0x750cae6a": "enableBetting_only_Dev()", "0xdf3c8620": "num_challenges()", "0xbb00fc55": "bookEarnings()", "0x0bd2ae1c": "ERW()", "0x580bdf3c": "disableBetting_only_Dev()", "0x5c3f9765": "endDateClose()", "0xc4128b6d": "upgradeCount()", "0x140b4465": "executeSpendingRequests()", "0xfaa1a8ff": "getOwnedBot(address,uint256)", "0x40e58ee5": "cancel(uint256)", "0xf4ea95b9": "validateReleaseVersion(uint32[3])", "0x2ba0b09f": "AddNewCategory(bytes4,uint8,uint8,address)", "0x55db4092": "setTOS(address,bool)", "0xf9cc0605": "getAvailable()", "0x3f2f46b4": "revealRock(string)", "0x2af7ceff": "testPrice(uint256)", "0xcaaf2dd7": "getInitialAnswerResult(uint256)", "0x6f36ce79": "insert_deal(address,address,uint64,uint128,uint32)", "0xa18c751e": "set(bytes,bytes)", "0x4d536fe3": "doit()", "0x3197cbb6": "endTime()", "0xb83069c5": "getStemPrice()", "0x3f15457f": "ens()", "0x81ebdeea": "testThrowCreateWithNonceRetracted()", "0x249b4d0b": "removeTrustedIssuer(address,bytes)", "0xe7b48f74": "get(int256,address)", "0x089d5c4a": "repr()", "0x3a9e7433": "scheduleCall(bytes4,uint256,uint256,uint8)", "0x504f1671": "getSize(address)", "0xf3a44fe1": "withdrawForWorkshop()", "0x7a837213": "setAllowedAccount(address)", "0x4551b1d7": "ProxyPayment(address,address)", "0x5dac1601": "SimpleStablecoin()", "0x87914c6f": "prolongateContract()", "0xe3ceb06d": "YesNo(bytes32,address,string,address,uint256)", "0x42a745cb": "testBitEqualSuccess()", "0xaa8dea8c": "fipsAddToLedger(bytes20,address,bytes)", "0x986dcd4d": "setCycleLimit(uint256)", "0x1e44c112": "find_strike(uint64,uint32,uint32)", "0x1ecfe64d": "_jSub(uint256,uint256,uint256,uint256)", "0x4ae85627": "grindUnicorns(uint256)", "0x200ebe34": "addTokensToGive(address)", "0x7b632c41": "TimestampScheduler(address,address)", "0x979b6f6f": "RoundInfo()", "0xb3ea3924": "PointlessCoin(int256,uint256,string,uint8,string,address)", "0x1d834a1b": "insert(uint256,uint256)", "0x931df75f": "validateProposedThroneName(bytes)", "0x6189be15": "columnround(uint256,uint256)", "0xdf5dd1a5": "addOracle(address)", "0x22d8cf5b": "CheckUserVote(uint8,uint8)", "0xdd62ed3e": "allowance(address,address)", "0xc0eb2325": "scheduleTransaction(address,bytes,uint256)", "0x038461ea": "getCertifiedStudentsCount()", "0x9ee035c9": "lookupCanonicalFormat(bytes)", "0x0ab58ead": "SingularDTVFund()", "0x550ed1f0": "getMaxBetAmount()", "0x6e63015c": "getCertifiersCount()", "0xbbd4f854": "buyShares(bytes32,uint8,uint256,uint256)", "0x306b031d": "getGenerationEndAt(uint256)", "0x1bd9c46e": "setImporter()", "0xc80c28a2": "getNumberOfParticipants()", "0xcb553ac9": "sweepWizardCommission(uint256)", "0x6389654e": "changeDailyWithdrawalLimit(uint256)", "0xc0a963c9": "notifyWinner(address,uint256)", "0x3c335b0e": "getRetractable(bytes20)", "0x017972af": "getNumbersFromHash(bytes32)", "0x07da68f5": "stop()", "0x1e8c72b4": "incrUserAvailBal(address,uint256,bool)", "0x0df71602": "setWinner(uint256)", "0x85e5bb3a": "Security_AddPasswordSha3HashToBankAccount(bytes32)", "0x2ade6c36": "getNodeAddress(bytes32)", "0xb33926cb": "owner_withdraw(uint256)", "0x57764094": "getRate(uint256)", "0x13827950": "getShareholderDB()", "0x26826bf8": "setImage(bytes)", "0x76d438b0": "sendReward(uint256,uint256)", "0x51d6e547": "getNonce(bytes)", "0x4f24186a": "newProposal(string)", "0x1a695230": "transfer(address)", "0xe820a32f": "vetoPayout(uint256,uint256)", "0xfb3a1fb2": "getReleaseDb()", "0x6bae05cf": "preRegister(address)", "0xae2df7b3": "setImporterBank()", "0x56d73ad1": "getCertifierDb()", "0x8396392d": "add(string,string,string,address)", "0xeb08b304": "changeMeatProvider(address)", "0xb60e72cc": "log(string,uint256)", "0x76999896": "KingOfTheEtherThrone()", "0xea851885": "buyStake(bool)", "0xa5982885": "assertFalse(bool)", "0xfbf1f78a": "unapprove(address)", "0xc2ba5b40": "getPackageData(string)", "0x83d51a38": "concatString(string)", "0x68af4971": "registerListening()", "0x14ba5c09": "getDay()", "0xe4849b32": "sell(uint256)", "0x44dd4b3b": "lookupGeneration(uint256)", "0x3fda1281": "get_keys()", "0x09241200": "wasSuccessful()", "0xbc9147a4": "Foundation()", "0xe33734fd": "changeProposalDeposit(uint256)", "0x2cce4abe": "_finishNoCallback()", "0x45e965cd": "strConcat(string,string,string,string)", "0xd4245e5b": "transferringETH(address)", "0x10082bff": "getActorBillXdetail(address,uint256,bool)", "0xc831391d": "getPoolOverlapSize()", "0x15e33901": "digest(bytes,uint256)", "0x5f0edfb8": "create(bytes,bytes32,bytes1)", "0xadd4c784": "getResult(bytes32)", "0x3233c686": "claimerDeposit()", "0x187a62d5": "voteEmergencyWithdrawal(bool)", "0x5404bbf7": "getEntropy()", "0x3f5b7675": "periodTwo()", "0x7ec0f30d": "ack(string)", "0xd30a512e": "betOnColumnOrDozen(bool,bool,bool)", "0x9fcbc738": "setIntermediate(address)", "0x539e2bfb": "secondChainedCallback(uint256)", "0xe724529c": "freezeAccount(address,bool)", "0x5aa97eeb": "getMarkets(bytes32[],address)", "0xc51be90f": "query_withGasLimit(uint256,string,string,uint256)", "0x531b97d7": "oneCentOfWei()", "0xeace4827": "player_make_bet(uint8)", "0x9c851ebc": "new_entry()", "0x98c9cdf4": "getMinimumCallGas()", "0xd8f012c6": "StatelessFactory(string,string,string)", "0xceeafd9d": "withdrawFundsAdvancedRP(address,uint256,uint256)", "0xd6d7d525": "get(bytes)", "0xbf55486b": "Tanya()", "0xd35ada32": "addParticipant(address,address)", "0xa8239d0b": "getPrice(string,address)", "0x12514bba": "transfer(uint256)", "0xb00140aa": "getHash(bytes)", "0x36f66528": "EtherDelta(address,uint256,uint256)", "0x279e0912": "getDownloadPrice()", "0x8173b813": "setNumCities(uint256,uint256)", "0xb98fdc36": "IconomiToken(uint256,string,uint8,string,uint256)", "0x3c7a3aff": "commit()", "0xcac77df7": "__transferFromToICAPWithReference(address,bytes32,uint256,string)", "0xfbeaebc6": "murder()", "0x2fa7cbfb": "getExecCost(uint256)", "0xe44d3084": "testFailure()", "0xede8acdb": "startAuction(bytes32)", "0xd5544f94": "getFundsAndAvailable(address)", "0x3824d8ee": "buy100DaoFor1Eth()", "0xbe3945e4": "getFee(address,address,uint256)", "0x1917ab5c": "activate(string)", "0x23509e69": "donkeysEligibleForFees()", "0xf460590b": "updateSigner(address,bool)", "0xc55c1cb6": "queryN_withGasLimit(uint256,string,bytes,uint256)", "0xd96d7ea2": "PRE_EXECUTION_GAS()", "0x1f7b6d32": "length()", "0xacf8bf2a": "channelCount()", "0x18968a03": "finalize(uint256,address,address)", "0x5674a3ed": "runLottery()", "0xe3280126": "addOrder(string,bool)", "0x32afa2f9": "claimEtherOwner(uint256)", "0x355474d2": "commitReading(address)", "0x00601d6c": "board(uint256,uint8,uint8)", "0x2667f407": "__proxy(address,bytes)", "0x79716e43": "confirmTransaction(bytes32)", "0x272cda88": "EternalDB()", "0x76ca0c77": "scheduleCall(address,bytes,uint256,bytes,uint256)", "0x338b5dea": "depositToken(address,uint256)", "0xfa93f883": "getMinute(uint256)", "0xafc4a982": "PathCost(uint16,uint32)", "0xf7d97577": "setPrice(uint256,uint256)", "0x842bc37b": "GetSmallCotractIndex(address)", "0x75f40f40": "underdogPayoutFund()", "0x23a1c271": "setPongval(int8)", "0x02571be3": "owner(bytes32)", "0xf79b22e0": "betOnATeam(uint256)", "0x10cf5d47": "awaitingPayout()", "0x1b00fe51": "testHypothesis()", "0xd449ce7c": "Administered()", "0x455259cb": "getGasPrice()", "0x975057e7": "store()", "0xdfdb5f17": "doBurn(address,uint256)", "0xaa497b9d": "scheduleCall(address,uint256,bytes,uint256,uint256,uint8)", "0xcabfb934": "replace(address)", "0x1f1f5e76": "addValueToContribution(uint256)", "0xa0eda9f2": "_transferFee(address,uint256,string)", "0xa8d95fb2": "claim(address,string)", "0x03ee8f08": "getCoeff(uint16)", "0x9872a20a": "registerUInt(address,uint256)", "0xb20d30a9": "setDailyLimit(uint256)", "0xe116b17e": "getKudosLeftForProject(address,address)", "0xf7c9f74a": "insert_contribution(address,uint256)", "0xc7a1865b": "play(bytes32)", "0x356594ab": "EtherTransfer()", "0xe22b0c46": "verify(uint256,uint256,uint8,bytes,bytes)", "0x2fea7b81": "getIdentity(address)", "0x6fa8de90": "changeMeatParameters(uint256,uint256)", "0x37c390e3": "allow_move(uint16)", "0xd22c391a": "validateProposedThroneRules(uint256,uint256,uint256,uint256,uint256)", "0xf6d339e4": "setAddress(bytes32,string,address)", "0xd7cc8362": "isLatestMajorTree(bytes32,bytes32)", "0xdd012a15": "setIt(uint256)", "0x254c91b3": "testBitNotSetSuccess()", "0x47e40553": "nextRound()", "0xa6b206bf": "doSomething(uint256)", "0xac996e7e": "resolvePledging()", "0x71e2d919": "lol()", "0x07d5b826": "buyAllOutcomes(bytes32,uint256)", "0x5f68804e": "SimpleLotto()", "0xa510f776": "setCompany()", "0x0d48e8d0": "doBalance()", "0xd21d7950": "changeGasLimitOfSafeSend(uint256)", "0x3358d2d3": "buildDSTokenFrontend()", "0xec93cfae": "FountainOfWealth()", "0x65b1fdf4": "scheduleIssuePOIs()", "0xdc3080f2": "spentAllowance(address,address)", "0xd1f0bb2d": "populateAllowedFreeExchanges()", "0xd591221f": "testTransfer()", "0xf24b5779": "removeTrustedIssuer(address,string)", "0xed4b1d0d": "scheduleTransaction(uint256)", "0xa83627de": "updatePeriod()", "0xf597a499": "UserDatabase(uint256)", "0x21f8a721": "getAddress(bytes32)", "0x5548c837": "Deposit(address,address,uint256)", "0x55b775ea": "setFeed(address)", "0x01b869f1": "release(uint32,uint32,uint32,bytes)", "0x609ff1bd": "winningProposal()", "0xdf98ef33": "getResource(bytes,uint256,bytes)", "0xd39eb301": "getStatus(uint8,uint8)", "0x2cc0b254": "init(address,bytes32)", "0x4228974c": "Videos()", "0xc431f885": "addToContribution()", "0x00e43ee9": "setMigrationStatus(uint256,address)", "0xd9f8a4e2": "calcCurrentTokenPrice()", "0xb9e6f1d9": "get_amount()", "0x6b3a87d2": "WatchWinningPot()", "0xef4592fb": "getResult(bytes)", "0x41b9dc2b": "has(bytes32,bytes32)", "0x3b9901cc": "getChannelsByRanks(address,uint256,uint256)", "0x83876bc9": "newProposalInWei(address,uint256,string,bytes)", "0x50a3bd39": "enterPool()", "0xc976bbbb": "_compare(int256,bytes2,int256)", "0x0e47c76f": "rotate(uint64,uint256)", "0x6f85c7e4": "WAITING_PERIOD()", "0x7075b1d8": "latestMonarchInternal()", "0x9209b3c0": "getCrtDetails(bytes)", "0x305075db": "NormalizeRanks()", "0xb6b55f25": "deposit(uint256)", "0xf09ea2a6": "offer(uint256,address,uint256,address)", "0xf1320af2": "exempt(address)", "0xc813c30e": "testThrowSomething()", "0x4faa2d54": "getTimeElapsed()", "0x22017c5f": "DSTokenBase(uint256)", "0x6637b882": "setDao(address)", "0xd0b52156": "getIpfsHash(address,address)", "0x13bd4e2c": "_prepareAndSendReward()", "0xdb7ca38a": "XaurmProxyContract()", "0x1bad1d2e": "monitorWallet(address)", "0x691f3431": "name(bytes32)", "0x3169ff3e": "LooneyLottery()", "0x446a7974": "Fokitol()", "0xdc3ab866": "checkEarnings(address)", "0xfad9bf9e": "storeBlockWithFeeAndRecipient(bytes,int256,int256,bytes,int256,int256)", "0xaf408d89": "setStatus(bytes)", "0xd02bf162": "spinTheWheel()", "0x9a36f932": "feeDivisor()", "0xca77ab8a": "getNextFile(bytes)", "0xc8e49707": "activateExportFee(address)", "0x502414e4": "marketMaker(string)", "0x78ec81a0": "sendEarnings(address)", "0x14167bf0": "oraclize_query(string,string[])", "0xba13a572": "lottery()", "0x299ed37a": "emergencyCall()", "0x6ec3af26": "addTrustedIssuer(address,bytes)", "0x3d69b403": "isOutcomeSet(bytes)", "0x9a19a953": "setInt8(int8)", "0x7817a60f": "acceptMember(address,string)", "0x1e223143": "getFirst()", "0x5437b39b": "hasUnprocessedDividends(address)", "0x8f0c724c": "setOperationsCallGas(uint256)", "0x3c925f16": "getAccountHolder()", "0x477801b1": "getLastRoundResults_by_index(uint256)", "0x3d21aa42": "sendApproval(address,uint256,address)", "0xd2b8035a": "draw(uint256,uint256)", "0x19c32e0b": "hmacsha256(bytes,bytes)", "0x28f90e4b": "Etheramid2()", "0xe87df70e": "fivetimes()", "0xc028df06": "offer()", "0xacb6c69b": "setTrustedClient(address)", "0xac7ffae3": "updt(uint256,string,uint256,uint256,string,string,address)", "0x0e5ffb3c": "hashVersion(uint32,uint32,uint32,string,string)", "0x4ac6b2be": "getCheckRecordCreator(bytes)", "0x93dafba2": "getSubpot(uint256)", "0x592685d5": "getWindowStart(address,address)", "0xc24a0f8b": "endDate()", "0x3f9b250a": "getDocument(uint256)", "0xd845a4b3": "request(uint256)", "0xa5bfa9a9": "claimToken(bytes32)", "0x8e3957d9": "RandomNumber()", "0x62fb09b2": "getRefDescr(uint256)", "0x9f35d3b2": "start(string,string,uint256,uint256,uint256,uint256)", "0xea1bf386": "getNextSellerBOTdata(uint256)", "0xe27fe50f": "startAuctions(bytes32[])", "0x031d973e": "closeMarket(bytes32)", "0x754dea40": "setBackendOwner(address)", "0xd83a8d11": "testProposing()", "0xf24a534e": "Oracle()", "0xd08275f1": "WolframAlpha()", "0x932db761": "profitsFromBitnationDebitCard()", "0xd96aee49": "MultipleConstructorTest()", "0x4594d06a": "delMinter(int256,address)", "0xb9f256cd": "newProposalInEther(address,uint256,string,bytes)", "0x1d2bca17": "MyToken(uint256,string,uint8,string)", "0x6edbd134": "hasHash()", "0x847f8a10": "Refund(uint32)", "0xb0604a26": "schedule()", "0x6676871d": "reserved_funds()", "0x05888fcd": "tradeBalances(address,uint256,address,uint256,address,uint256)", "0xe771066f": "marriageProof(bytes)", "0x7e32a592": "repairTheCastle()", "0xbab2f552": "currentCycle()", "0x45a3b0bf": "resolveFailPledge()", "0x070a888f": "updateRewardDuration(uint256)", "0x20d9822e": "setAnyoneCanCall(address,string,bool)", "0x224993c2": "setTimeBlock(uint256)", "0x01bd4051": "disown(string)", "0x4bc2a657": "setVoter(address)", "0x522103fa": "changeUnicorn(uint256,address)", "0xc988d70f": "getDailyWithdrawLimit()", "0x2f7f3ecf": "findNextHour(uint256,bytes)", "0x1b769e74": "testThrowsRestartNotUpdatable()", "0x4d561721": "etherandomSetNetwork()", "0x92a781d8": "changeBaseValue(uint256)", "0xf0a78538": "scheduleTransaction(uint256,bytes)", "0x64ef212e": "proxyTransferWithReference(address,uint256,bytes32,string)", "0x97c3ccd8": "ban(address)", "0xdeb6930c": "PriceTicker()", "0x6cc5fdaa": "setBytes32(bytes,bytes)", "0x92c8eb96": "DSFalseFallbackTest()", "0x6534b4e2": "IsPayoutReady__InfoFunction(bytes32)", "0x15e812ad": "getBaseFee()", "0xf5b53e17": "getInt256()", "0x081bf263": "isOOB(uint8,uint8)", "0xd2fb8787": "recordExists(bytes)", "0x86c57fcc": "b32ToBytes(bytes)", "0xe3a199d6": "testThrowCreateNewRevisionNotUpdatable()", "0x57cfeeee": "transfer(address,uint256,bytes32)", "0xb72e717d": "fromAddress(address)", "0x61b20d8c": "retrieveFunds()", "0xf4b103d4": "SimpleStorage(uint256)", "0xe2056c46": "ExtraBalToken()", "0xc3ee6311": "lockAndCall(string)", "0x136af582": "next(bytes,bytes,bytes,bytes,bytes,bytes,bytes)", "0xc5d5997c": "changeSubUser(address,address)", "0xf8018a79": "prepend(address,address)", "0xf6b4dfb4": "contractAddress()", "0x9450b1c8": "addCharityFundation(string,string,string)", "0xd1a8d447": "get_all_bet_values()", "0x66d8c463": "reveal(bytes32,string)", "0xbb963c8a": "transferLibOwnership(bytes,address)", "0xd56b2889": "finish()", "0x9fb25d9e": "LeaderMessage()", "0x6ad50ed4": "investmentEntryInfos()", "0xa4d575ce": "_forward(address,bytes)", "0xa3ec5616": "next(bytes,bytes,bytes,bytes,bytes,bytes,bytes,uint256)", "0x0db73c72": "noevent()", "0xf449619e": "collectPrize(uint256)", "0x1afccfa5": "Proposal(address,address,address,bytes,bool)", "0x4788cabf": "getContractId()", "0x4112987c": "strConcat(string,string,string)", "0x928a00d2": "deleteCoin(uint256)", "0xd9ec0508": "testThrowTransferNotEnabled()", "0x9aaf442c": "applyCensorship(uint256)", "0x49407a44": "claimEther(uint256)", "0x4fcf8210": "eraseRecord(bytes32)", "0x5ed84aa6": "getNymCenterAPIURL()", "0xa3c2c462": "totalReceived()", "0x5938748e": "changeVotingRules(address,address,uint256,uint256,uint256)", "0x6fc9d5e4": "changeCompareTo(uint256)", "0xe2ee9941": "tap(bytes20)", "0x0ff4f160": "oraclize_query(uint256,string,string[1])", "0x43ec3f38": "toSliceB32(bytes32)", "0x3288eb0b": "ChineseCookies()", "0x373c98a2": "authCall(address,bytes32)", "0x6ea056a9": "sweep(address,uint256)", "0x8dc45377": "getDuel1(uint256)", "0xd4625a3a": "equals()", "0x616fca9b": "adopt(address)", "0x32cea83e": "birth(bytes)", "0x002a5cc9": "getTicketHolders(uint256)", "0x31119b4d": "changeDeveloper(address)", "0x69569a51": "setFrontend(address)", "0xb7e24979": "addThing(bytes)", "0x164e68de": "withdrawFees(address)", "0x42bf4431": "orderMatchTest(uint256,uint256,uint256,int256,uint256,uint256,address,address,int256)", "0x5dd672ec": "latestBid()", "0x45fe6e2a": "Scheduler()", "0x55cc4e57": "setIssuer(address)", "0x1df5e755": "Etherandom()", "0x8f70009d": "id_for_address(address,address)", "0x39b50688": "cancelSellOrder()", "0x40953102": "scheduleCall(address,uint256,bytes,uint256,uint256,uint8,uint256)", "0x677913e9": "setAmount(int32)", "0x66671c71": "BaseScheduler(address,address)", "0xfe71aec5": "LittleCactus()", "0x879d46fd": "DAOTrust(address,address,bytes,uint256,uint256,uint128)", "0x3b143184": "Congress(uint256,uint256,int256,address)", "0x7370a38d": "getNumPackages()", "0xfee35ff8": "newInvest(uint256,address,uint256)", "0x57dc9760": "DaoChallenge()", "0x8ac78c80": "Docsign()", "0x76d66f5d": "_Transfer(address,address,bytes32)", "0x9dc2c8f5": "fireEventLog4Anonym()", "0x43114842": "acceptChallenge(uint256,uint256,uint256)", "0x2043285d": "getMarketMakers()", "0xfb32f4f5": "ARK_FLAGGER_1_00()", "0x69431ab6": "TokenCreation(uint256,uint256,address,string,string,uint8)", "0x045c6ce0": "voteForProposal(uint256)", "0xa140e79c": "setMinimumDebatePeriod(uint256)", "0x331a72d1": "getRetractable(bytes32)", "0x87cc1e1c": "setExporterBank()", "0x7183616c": "notarize(string)", "0xce79add1": "givableBalanceOf(address)", "0x6f0cfab6": "DNSResolver()", "0x1c2f38ff": "paid(uint64)", "0xb7de47d3": "getIndex(uint256,uint256)", "0x04a2b2c2": "testOwnerCanBreach()", "0x65a4dfb3": "oraclize_query(uint256,string,string,string,uint256)", "0xf2ddc772": "confirm(bytes)", "0xa00ce377": "getIsContractValid()", "0xfe9fbb80": "isAuthorized(address)", "0xbbd39ac0": "coinBalanceOf(address)", "0xa4fde8bc": "player_declare_taking_too_long()", "0xd052fbf6": "getHistory(string,uint256)", "0xd205ad7d": "proposeDissolve(bytes)", "0x5a3b7e42": "standard()", "0xf27197ab": "getIsAvailable()", "0x00a94b6e": "oraclize_query(uint256,string,string[5],uint256)", "0x971c803f": "getMinimumStackCheck()", "0x5168afa4": "getPackageHash(bytes,uint8,uint8,uint8)", "0xaef99eef": "Game()", "0x7f924c4e": "testDeposit()", "0xb1adc241": "BalanceDB()", "0x6a704d7b": "AddedToGeneration(address,uint256)", "0xb9f37c86": "Registrar()", "0xc631b292": "closeVoting()", "0x19350aea": "nameFor(address)", "0x85dee34c": "query2_withGasLimit(uint256,string,string,string,uint256)", "0xbf187478": "shift_left(uint64,uint256)", "0x5b6b431d": "Withdraw(uint256)", "0xe5dd90a5": "HumanStandardToken(uint256,string,uint8,string)", "0xbf8c50ff": "scheduleTransaction()", "0x013d64bd": "setCanCall(address,address,string,bool)", "0xb870ecbb": "testNormalWhitelistAdd()", "0xbcd3d8ca": "Collector(address,address,uint256)", "0x4401ff5c": "sellShares(bytes,uint8,uint256,uint256)", "0x3e0dfbdf": "getInvestorByAddress(address)", "0xcb3e64fd": "unhalt()", "0xafc24e3d": "getChallengeAnswer(uint256)", "0xa36c8ec2": "UpdateContractorAddress(address)", "0xd5a4a3c6": "findRecentBet(address)", "0xb028ee13": "s2b(string)", "0x692ad3a9": "round(uint256,uint256,uint256,uint256)", "0x0a7493b4": "Etheropt(uint256,string,uint256,uint256,bytes,address,int256[])", "0x60689557": "Rock()", "0x717fedf0": "getFirstActiveDuel1()", "0xe837ab59": "getParticipantByAddress(address)", "0x32d5fe98": "revealCampaign(uint256,uint256)", "0x0178b8bf": "resolver(bytes32)", "0x44faa139": "Withdraw(uint32)", "0x418cf199": "setEstimateCost(uint256,uint256)", "0xae45850b": "schedulerAddress()", "0xd4871517": "BTCLotto(address,uint256)", "0xfbffb355": "testBitsEqualFailIndexOOB()", "0x2be6d43c": "ARKTagger_1_00()", "0x1df47aad": "ReplayProtection()", "0xb36a0b15": "getSignDetails(uint256,uint8)", "0x9c4baf27": "Skywalker(address,address)", "0xfb34fc6f": "WatchNextBlockReward()", "0xceba30b5": "scheduleTransaction(address,bytes,uint256[4],uint256)", "0xfc94dd18": "verifyHumanStandardToken(address)", "0x1ff13086": "size(int256)", "0xce92dced": "newBid(bytes32)", "0x231944e2": "moveUnits(uint256,uint256,uint256[])", "0x784813e0": "lookupBet(uint256,uint256)", "0xe0e3ba5a": "getLosesShare(address)", "0x5c1b3ca1": "getConfigUint(int256,bytes32)", "0x91060168": "fetchString(address,bytes4,bytes32)", "0x354b2735": "testDeploy()", "0xb88eef53": "registryCreated()", "0x8e3d4e5e": "Fibonacci(bytes)", "0x64bd87d6": "scheduleCall(address,bytes,bytes,uint256,uint256)", "0x5c3d005d": "demote(address)", "0xb6509c12": "Ethereum_twelve_bagger()", "0xe87508be": "investorDeposit()", "0xcb96012e": "hashTo256(bytes32)", "0x314e0fb6": "scheduleTransaction(address,bytes,uint256[3],uint256)", "0x5b6a54bc": "adjustTransactionFee(uint256)", "0x5f515226": "checkBalance(address)", "0x76cd7cbc": "sign(bytes)", "0xce220ecf": "testAddBalanceFailsAboveOverflow()", "0x922fc84b": "taskProcessedNoCosting(uint256)", "0xf8b2cb4f": "getBalance(address)", "0x7a29332d": "buyAllOutcomes(uint256,uint256)", "0x04106c8b": "startGeneration()", "0x8eaa1e29": "getContentByData(address,uint256,string,string)", "0x5a7a8850": "rollWithSeed(bytes32)", "0x2facc4e8": "depositGovernance(uint256,address)", "0xf2561a43": "voteSuicide(address)", "0xee1b4828": "closeBooks()", "0x18f303a1": "SetInternalValues(uint8,uint256)", "0xce60f78d": "createMarriage(bytes,bytes,uint256,bytes,bytes)", "0x18b749c4": "payEther(uint256)", "0xbbc6eb1f": "getDefaultDonation()", "0x0b1ca49a": "removeMember(address)", "0xccf4f413": "setSubRegistrar(string,address)", "0x4616caa9": "pushCoin(uint256,address,string)", "0xd69450d5": "setUUID4Bytes(bytes)", "0xc98165b6": "createTarget()", "0x8c79a24d": "refName(uint256)", "0x56d88e27": "len()", "0xbfc3d84b": "CT()", "0xc7f2e6af": "Contribute(bytes20)", "0xd7e11e9d": "AddTicket(bytes)", "0x2d06177a": "addManager(address)", "0xd588acc4": "claimMiningReward()", "0x2ffb9e64": "updateGasForXaurData(uint256,uint256)", "0xf896503a": "getConfigAddress(bytes32)", "0x9af8c4ba": "respond(uint256,address,bytes)", "0x82a5285d": "getMinBetAmount()", "0x3ead67b5": "changeContractOwner(address)", "0xb29d7914": "getRefResults(uint256)", "0x135128c2": "CounterPartyDeposit()", "0x795b9a6f": "scheduleCall(address,bytes4,uint256,bytes)", "0x83197ef0": "destroy()", "0x433836dc": "scheduleTransaction(address,bytes,uint8,uint256[3],uint256)", "0xf009347d": "KudosProxy(address)", "0xf2fde38b": "transferOwnership(address)", "0x62c99e84": "_Approval(address,address,bytes32)", "0x1b83b823": "notifyPlayer(uint256)", "0xe56c8552": "spinTheWheel(address)", "0x93eec1fb": "setName(uint8,uint8,string)", "0x11af3c68": "divest(address)", "0x8279c7db": "setReceiverAddress(address)", "0x44691f7e": "hasStarted()", "0x349501b7": "checkDepth(uint256)", "0xe8beef5b": "fireEventLog3Anonym()", "0x0870607b": "addSubUser(address)", "0x063925c8": "scheduleCall(bytes,uint256,uint256)", "0xa23744f0": "tryCreateCheckRecord(bytes)", "0x35d79fad": "CertificationDb(address,uint256,address)", "0x44691f2b": "Dispute()", "0xd7ccc2c3": "getLastPayment()", "0x152583de": "getAttributes()", "0x1a9360dd": "checkDate()", "0x420ef2b3": "TargetHash()", "0xf0caea2b": "SmartRoulette()", "0x5d268629": "Refund()", "0x23385089": "emitApprove(address,address,uint256)", "0x7648c929": "returnRemainingEther()", "0x5d5bc4cb": "BetOnRed()", "0xde8fa431": "getSize()", "0xda6b31b9": "testErrorTransferToNullAuthority()", "0x444dd6f3": "Elcoin()", "0xe1fa8e84": "register(bytes32)", "0x3e0a322d": "setStartTime(uint256)", "0x21bacf28": "getDefaultFee()", "0xb1662d58": "setModule(address,bool)", "0x5b0fc9c3": "setOwner(bytes32,address)", "0x40193d17": "getPongvalConstant()", "0xfb95adeb": "testFailBlockhashInsuffiecientFee()", "0x8ecc0950": "returnToOwner()", "0x34b7ac9b": "END_MINTING()", "0xeaa37394": "create(bytes,bytes32,bool,bool,bool,bool,bool)", "0xd7bc23af": "newParameters(int256,uint256,uint256,uint256)", "0x97709cde": "ARK_VOTER_1_00(uint256,uint256,uint256,uint256,uint256,uint256)", "0xcf4a1612": "scheduleTransaction(uint256,address,bytes,uint256)", "0x40695625": "testRetractLatestRevision()", "0x90c3f38f": "setDescription(string)", "0x5fdf05d7": "two()", "0xaaac50bd": "transferDisable(bytes32)", "0x206a44f3": "getNum(bytes,uint256)", "0x7ac26aeb": "getTag(string,uint256)", "0xdc3f65d3": "createdByMe()", "0xe99543aa": "Trash(uint256)", "0x1bcad37a": "getTotalCost()", "0xa7f43779": "remove()", "0x3416f9d4": "subtractSafely(uint256,uint256)", "0x3bcf7d22": "newBribedCitizen(address)", "0x918f1bb5": "ProjectKudos()", "0xcf09e6e1": "SetBigContract(address)", "0x23add736": "claim(uint256,uint256,uint8,bytes,bytes)", "0x8ac6a869": "isObsolete()", "0x2324c67c": "getAllSignatureHashes(bytes4)", "0x981a60f5": "extractNameFromData(bytes)", "0xc018d0e6": "getFeeAmount(int256,int256)", "0x50e06b57": "Etherization()", "0x49e65440": "setSymbol(bytes32)", "0xfaee13b9": "set(int8)", "0x01ffc9a7": "supportsInterface(bytes4)", "0xc0b92612": "changePig(address)", "0x3f9f5b68": "setPreviousID(uint256,int256)", "0x2e9c5e77": "doStackExtension(uint256)", "0xc83be888": "single_move(uint256,uint8,uint8)", "0xef19c332": "_checkSigned(bytes32,uint256,uint8,bytes32,bytes32)", "0x2f30c6f6": "set(uint256,address)", "0x62986e27": "Canary(address,uint16)", "0x44dfdce0": "getNameOwner(bytes)", "0x4b7fcee7": "ownerPausePayouts(bool)", "0x84dac46e": "Fucksign()", "0x0878bc51": "getAttachesto(uint8)", "0x42d16748": "getMinDailyWithdrawalLimit()", "0x4ecd73e2": "DistributeDividends(uint256)", "0x03750d94": "serverSeed(address,bytes32)", "0xea0a5237": "announce(string)", "0x611daa7e": "EmergencyBalanceReset(uint256)", "0x2ae87a70": "getNumContents(address,uint256)", "0x5ec01e4d": "random()", "0xfd735602": "executeN()", "0xfebefd61": "startAuctionsAndBid(bytes32[],bytes32)", "0x8b64d70e": "owner_set_time_limit(uint256)", "0x2839e928": "ackermann(uint256,uint256)", "0xaf29e720": "remainingGasFund(uint256)", "0x9eee85fe": "bookEarnings(address,uint256)", "0x3733ffca": "convertTo(uint256,string,string)", "0xdbde1988": "transferFromWithoutReward(address,address,uint256)", "0xd3edcb5b": "getCreditorAddresses()", "0x77fcb91d": "forward(address,bool)", "0xf062e26b": "check_darkdao()", "0xdef2489b": "convert(address)", "0xccbda1af": "getChannelByName(string)", "0x267c8507": "authorizeManager(address)", "0xf1c30ec0": "reclaim(bytes)", "0xe6470fbe": "updateDefaultPayment()", "0x8fe58eb9": "Triger()", "0xd6b44859": "scheduleUndoIt(uint256)", "0x0eb8ed07": "transferEnable(bytes32)", "0xfc1f2a70": "Add(uint256,string,string)", "0x058026d0": "checkTransferToICAPWithReference(bytes32,uint256,string)", "0xaf27c7b3": "Security_HasPasswordSha3HashBeenAddedToBankAccount()", "0x5b151fd2": "fifty_fifty()", "0x531d1974": "testThrowRetractLatestRevisionEnforceRevisions()", "0x60213b88": "getInitialWithdrawal()", "0x29e94503": "VersionedBlob()", "0x9c5d7030": "reimburseGas(uint256,address,uint256,uint256)", "0xcd9a3c98": "any(bool[7])", "0xb484e532": "getMyMsg()", "0xd1f59db9": "isLatestMinorTree(bytes32,bytes32)", "0xe0c6190d": "checkTime()", "0xaf5610dd": "isThisPreforkVersion()", "0xfa968eea": "minBetAmount()", "0x003538c5": "TestRegistrar(address,bytes32)", "0x71c59097": "MainnetSurvey(uint256,string,bytes32[])", "0xc82aac47": "searchByTag(bytes32)", "0xeca5c793": "testErrorUnauthorizedNameRegister()", "0xdc75f2db": "multiowned(address[],uint256)", "0x4c9ed763": "requestTokensBack()", "0xbd9a5673": "oraclize_query(string,string[5])", "0xb11e3b82": "createEvent(bytes32,bool,int256,int256,uint8,address,address,bytes32[])", "0x86e4e178": "CheckTickets(address,uint256,uint256)", "0x53c84526": "setSmartAffiliateContract(address)", "0x89029d8c": "get_all(uint256,uint256)", "0xc25e6908": "ultimateOutcomes(bytes32)", "0x6b1e564a": "challengeWinningOutcome(bytes32,uint16)", "0x1c895915": "getNumberOfPayments(uint256)", "0x244fcd03": "removeRelease(bytes32,string)", "0x2ca6d2c0": "getAccountSize(address)", "0xfe67a54b": "endAuction()", "0x756fb8c9": "getOptionChain()", "0x88102583": "safeCastSigned(uint256)", "0x60063887": "transferDebt(address,address,address,uint256)", "0x16216f39": "return13()", "0x8089d001": "getHashOfBlock(uint256)", "0x27bc39c0": "submitCanonicalCandidate(bytes,bytes,bytes,bytes)", "0xb29ae23f": "getDateOfSignature()", "0xdd729530": "add_shield(uint16)", "0x38557648": "executeSellOrder(address)", "0xe2a71f12": "accountDelete()", "0xce869a64": "fails()", "0x69bdfd3a": "toContractDie(bytes,bytes,uint256)", "0x99aeade3": "iterateTable(uint256,uint256)", "0x46bdca9a": "equal(string,string)", "0x5e07f240": "shiftBitsLeft(bytes,uint256)", "0x76285b5b": "_is360thDay()", "0x594151e0": "Dice()", "0x4dc43eaf": "setTreasury(uint256,uint256)", "0xec727000": "getApprovalDB()", "0xb144adfb": "balance_of(address)", "0x63052d82": "getOwnersIndex(address)", "0x833b4596": "testApproveSetsAllowance()", "0xc67d376d": "getClosedCandidates()", "0xcf03f5f4": "activateMasterKey(address)", "0x7ca55e00": "etherandomVerify(bytes32,bytes32,bytes32,uint256,uint256)", "0xd92ebe46": "createDAO(address,uint256,uint256,uint256,string,string,uint8)", "0x3773930e": "ConfigureFunction(address,uint256,uint16,uint16,uint16)", "0xfee6d28c": "addSnapshot(string)", "0xe71264fa": "addNewTokens(uint256)", "0xc4d9102f": "setNextID(uint256,int256)", "0xa6f0e577": "isLeapYear(uint16)", "0xc7102df7": "__stopBlock()", "0xfa93019c": "getBlocks(uint8,uint8)", "0xe9794dc1": "CreateHash(uint8,string)", "0x5460ef10": "sendWithExtraGas(address,uint256,uint256)", "0x2f62a6ff": "fipsRegister(uint256,address,bytes)", "0xd630bd53": "pledgeApprove(uint256)", "0x3448c7d6": "createHistory(bytes,address,address)", "0xdda3342b": "ReplicatorFactory()", "0x0cd865ec": "recover(address)", "0xb9f28076": "historyIdx(address)", "0x4dda1764": "CafeMaker()", "0x883ba26b": "getIsSettled()", "0x3f5e268f": "convictInitial(uint256,uint256)", "0x4a3b0eec": "authorizeOpen(uint256,bool,string)", "0xee6d2641": "sendWithExtraGasExt(address,uint256,uint256)", "0xde14bbf7": "randomGen(uint256,uint256)", "0x7f3bd56e": "disburse(address,uint256)", "0x20d8741f": "Feed()", "0x60c6b3a5": "claim(bytes,address,uint256,uint8,bytes,bytes)", "0xda4b5e29": "contains()", "0xb3c25835": "addUser(address,string,string,uint256)", "0xee2af3fb": "set_factory(address)", "0xb821f815": "pay_winner(uint256)", "0x138cc941": "testErrorTransferToRejectAuthority()", "0xc0b6f0c2": "NextRoundAndEvents()", "0xc7e67360": "GAS_BUFFER()", "0x058d7433": "setAlliesContract(address)", "0xd810f298": "computeSettlementAmount()", "0xa24d23eb": "ProcessGame(uint256,uint256)", "0x7ac91cc2": "testFailOwnedAuth()", "0x79c3ddc1": "isPackageOwner(string,address,address)", "0x478ae93c": "playToWin(uint256)", "0x6632a507": "testSetupPrecondition()", "0xb6013cef": "finalize(uint256,uint256)", "0x37b7bf11": "Tile(int256,int256)", "0xecfc7ecc": "placeBid()", "0x70b1d9d4": "requestCanonicalFormat(bytes)", "0x315fdea3": "TreasureChest()", "0xc5575ef0": "checkTransferFrom(address,address,uint256)", "0x65c72840": "getDay(uint256)", "0xd6eafd08": "scheduleCall(address,bytes,bytes,uint8,uint256[4])", "0x350fbe2e": "calcNextDrawTime()", "0x8af784dc": "expectEventsExact(address)", "0x2db89533": "Auth(uint8,address)", "0x9f203255": "setAuditor(address)", "0x2526d960": "clawback()", "0x3fbd40fd": "ProcessDraw()", "0xface030b": "SpinTheWheel(address)", "0x648621ec": "xnotify(string)", "0x22dc36e2": "processed(uint64)", "0x6f52167d": "payDuel(address,string,address,string)", "0x8f70bfa0": "processDeposit()", "0x25ea269e": "Scissors()", "0x93feb13b": "ForceSendHelper(address)", "0xb688a363": "join()", "0x89859b50": "updateLatestTree(bytes32)", "0xf83d08ba": "lock()", "0x7d287697": "testTryGetUnset()", "0x98d5fdca": "getPrice()", "0xfe72e717": "toDie(bytes)", "0xb3c06f50": "transferFrom(address,address,bytes32)", "0x1465aa97": "testingContract()", "0x069d6d1c": "closeOrder(uint256)", "0xa79f26dc": "force()", "0xf2371fb3": "grantGiveableKudos(address,uint256)", "0xaa7dcd84": "testUpdateAuthorityEvent()", "0x0d8b5fa2": "testControllerValidTransferFrom()", "0x0e0f55d0": "RewardOrder(uint256,uint256)", "0x9ea1b79d": "getContentChannel(uint256)", "0x4a67fa7d": "setLotteryFee(uint256)", "0xdb006a75": "redeem(uint256)", "0x8f4ed333": "step2()", "0x1a10cfc3": "delete_entry(uint256,uint256,uint256)", "0xd422e4e0": "takeFee(address,uint256,string)", "0x61a00f6d": "Ballot(bytes32[])", "0x9c30936f": "removeCertificationDocumentFromSelf(bytes32)", "0xa5f4af33": "playerWithdrawPendingTransactions()", "0x07ad9ecb": "safeSend(address,uint256)", "0x8f99ea43": "setDividendDB(address)", "0x1df473bc": "newContract(bytes)", "0xea5ea470": "payFunding(uint256)", "0x743e0c9b": "receiveTokens(uint256)", "0x21835af6": "__dig(uint256)", "0x47448e8a": "set(bytes32,string,bytes32)", "0x9b1ad792": "destroyToken(address,uint256)", "0xf765088f": "UpdateClientAddress(address)", "0xddbbc35c": "searchByName(string)", "0x5ed7ca5b": "halt()", "0x97950740": "roomForBirth()", "0xfc01abbe": "stringToBytes32(string,string)", "0xea3d508a": "selector()", "0x8c88752a": "ContributorList(uint256)", "0x5837e083": "move_history(uint256)", "0xf7c3ee7a": "immortality()", "0x1b9f9647": "accessMyWallet(address)", "0xc8691b2a": "getHistory(uint256)", "0x91e8d3dc": "testBitOrFailIndexOOB()", "0x5c89c10d": "setBannedCycles(uint256[])", "0x4500054f": "isCancellable()", "0x334ef224": "testThrowsUpdateLatestRevisionNotOwner()", "0x763a738c": "allNames()", "0x45590ec8": "addTag(uint256,string)", "0xe7740cf9": "revealPaper(string)", "0xd9d2d058": "Splitter()", "0xb412d4d6": "CafeDelivered()", "0x8365172c": "num_levels()", "0x41c0e1b5": "kill()", "0x3106fea0": "voteOnProposal(uint256,bool,uint256)", "0x82ab890a": "update(uint256)", "0x4636a159": "newPhoneToAddr(address,uint256)", "0x2f29d8c5": "elapsed()", "0x1bf20668": "testAdminTransfer()", "0xf709dd51": "getTrademark()", "0x8b859409": "setRelease(bytes32,bytes32,string)", "0x03959bb7": "setDataContract(address)", "0x4247f52d": "DoRoll()", "0x31ab4066": "testAuthorityTryAuth()", "0xac4b2bae": "newParameters(int256,uint256,int256,uint256)", "0x57eaeddf": "_isContract()", "0x4a3a87e2": "CreateProxyWithControllerAndRecoveryKey(address,address,uint256,uint256)", "0xd116c8c4": "releasePayment()", "0x6615dd83": "setSeedSourceB(address)", "0xb8aca90b": "CurrentGame()", "0xc124e2ea": "checkBetDozen(uint8)", "0x4b0bbf84": "addEntropy()", "0x452fbc41": "USN(address,address,bytes,uint256,uint256,uint128)", "0xcdb6753b": "setNav(uint32)", "0xbb5d40eb": "isValid()", "0xd6f42038": "PhoneToAddress()", "0x6bc3e0f0": "verifySecondHalf(uint256[4],uint256[4],uint256[4])", "0x33893071": "checkMyWithdraw(address)", "0xfb46d4c5": "tweet(string)", "0x248582b0": "receivePaymentForGoodsSoldEarly()", "0x766a3f2e": "Security_ConnectBankAccountToNewOwnerAddress(uint32,string)", "0x1c8d5d38": "allowance(address,address,bytes32)", "0x6b256f57": "DAOSecurity(address,address,bytes,uint256,uint256,uint128)", "0xe8d1e961": "lockAccount(uint256)", "0x152fb125": "SimpleMixer()", "0xf72457af": "CertifierDb()", "0xe8a5282d": "setConfig(bytes32)", "0xbeb92f55": "setCaller(address)", "0x9a571d9f": "isAlphaLower(bytes1)", "0x46a2679a": "getSubpotsCount(uint256)", "0xd62d3115": "testCreate()", "0xb6ed0632": "cancelOrder(uint256,uint256)", "0xc95e81cb": "MyBet(uint8,address)", "0x1d5a9f3f": "object_types(uint256)", "0xa49d53a1": "SmartRevshare()", "0x5b65b9ab": "setFee(uint256,uint256,uint256)", "0x116c6eab": "getProfitShare(address)", "0x8e46afa9": "getDefaultGracePeriod()", "0xdabc706e": "getProposalCost()", "0x3fbb539d": "scheduleCall(address,bytes,uint256,bytes)", "0x86269a88": "checkBetNumber(uint8)", "0xb6ac24df": "updatePatchTree(bytes32)", "0x4637d827": "trust(address)", "0x1c1b8772": "update(address)", "0x5a9f2def": "scheduleCall(bytes4,bytes,uint256,uint256)", "0x81a60c0d": "getResults(uint256)", "0xd1b4ff7e": "multiAccessRevokeD(bytes32,address)", "0x92b7d5b9": "getCurrentGaslimit()", "0x77ceded8": "mintGrey(int256,address,uint256)", "0x2a095fbe": "unlinkEID(bytes,bytes,address)", "0xa6e16ba2": "testThrowsRetractLatestRevisionNotOwner()", "0x4579268a": "getOffer(uint256)", "0xcabb3a3a": "isAlphaNumeric(string)", "0xfadc51cf": "isAlpha(bytes1)", "0xf2022905": "toldYouItWouldWork()", "0x686e8aaa": "GetMoney()", "0x07718a3b": "BankOwner_WithdrawDonations()", "0xc58343ef": "getRequest(uint256)", "0x7b1a547c": "registerAs(address,string,uint256,string,address)", "0x213b9eb8": "setAddr(string,address)", "0x75090ebf": "changeDomain(uint256,uint256,uint256,address)", "0xdbbdf083": "register(uint256,address)", "0xfa4e5e5a": "notify(uint8,string,string)", "0x86a5ff97": "changeStatus(string)", "0xb8f71f26": "scheduleTransaction(uint256,address)", "0xa2ec191a": "addDSource(string,uint256)", "0x18b31f94": "registerLengthFunction(string,string,address)", "0x7b395487": "voteForUltimateOutcome(bytes32,uint16)", "0x39246d75": "VersionModel()", "0xd500dd6a": "challengeTimeout(uint256,bool,address)", "0xd1da09ee": "extractImportFeeChargeLength()", "0xc74e907b": "commit(address,uint256,uint256)", "0x4b09ebb2": "e_exp(uint256)", "0xec3af4a9": "getProjectKudos(address)", "0x714064f3": "BreakableBond(address,address,uint256)", "0xc4bc5da5": "resumeContract()", "0xf7888aec": "balanceOf(address,address)", "0x2f597e71": "testLongInput()", "0x7212b67e": "add_potion(uint16)", "0x9a15f4f3": "getBlockHeader(int256,int256)", "0x6eacd48a": "ownerPauseGame(bool)", "0xf739ed4c": "id_for_user_version(uint256,uint256)", "0xfaf0952b": "testThrowRestartNotOwner()", "0x88a1e895": "test2Fails()", "0x237e9492": "executeProposal(uint256,bytes)", "0x7cb97b2b": "set_owner(address)", "0x2bb685bc": "kill2()", "0xdc52696f": "tokenSupplyChanged()", "0x83d852d9": "shutdownTransactions()", "0x525b25b1": "getDeploymentReward()", "0xeac116c4": "createKingdom(string,address,address,address,address)", "0x014e5fde": "ARKController_1_00()", "0xc6ae3b57": "dEthereumlotteryNet(address,address)", "0xcddbe729": "game(uint256)", "0x8823a9c0": "changeFeeTake(uint256)", "0x021991e7": "getBetsLocked()", "0x3015394c": "cancelRequest(uint256)", "0x9d118770": "destroy(uint256)", "0xe854dfb4": "Order(address,uint256,uint256)", "0x8435be4b": "getLastFarm(uint8,uint8)", "0x27fbcac5": "getChannelFeed(address,uint256,uint256)", "0xc1be4031": "XaurumProxyERC20()", "0x8e25071a": "setProxyCurrator(address)", "0x4f139314": "compensateLatestMonarch(uint256)", "0x85c78fac": "retryOraclizeRequest(uint256)", "0x478e25bf": "resetAction(bytes32)", "0xc74c251f": "addSafely(uint256,uint256)", "0x058aace1": "divest()", "0x6d1da953": "createWithNonce(bytes32,bytes)", "0x30c0f8d6": "scheduleTransaction(address,bytes)", "0x69a5e902": "multiAccessCall(address,uint256,bytes)", "0x6f8b44b0": "setMaxSupply(uint256)", "0x919edc7c": "getChainySender(string)", "0x0b7ad54c": "getContent(uint256)", "0x5bfdc700": "registerData(address,int256,bytes,address)", "0x0d1fce42": "getBankroll()", "0x739b47ca": "recordWin(address)", "0xa5ea11da": "getParameters()", "0xf8af9e6f": "setAdv(uint256,string,string)", "0xe32e9f22": "setDeploymentReward(uint256)", "0x0baaaed9": "setConfigBytes(bytes,bytes)", "0x99f4b251": "mine()", "0x362af076": "createRequest(address[3],address,uint256[11],uint256,bytes)", "0x7fd238ba": "doCoinage(address[],uint256[],uint256,uint256,uint256)", "0x3adb2de7": "bet_this_spin()", "0xa311dd70": "setArray(uint8[10])", "0xc5bf339c": "getLastNonPublished()", "0x9d1bbd7e": "CancelRoundAndRefundAll(uint256)", "0x89790192": "WithFee(address,uint256)", "0x1c879c47": "getMarketHashes(bytes)", "0xbb84d362": "splitProfitVIP_only_Dev()", "0xffb1a6cb": "getWins(address)", "0x3b355af6": "baseData()", "0xb181a8fc": "resetContract()", "0x7d3d6522": "goalReached()", "0xd4c2b6b1": "scheduleTransaction(address,bytes,uint256[5],uint256)", "0xd65ab5f2": "startGame()", "0x4c4766e8": "KittenRegistry()", "0x77e5bf84": "getTxGasprice()", "0xff981099": "getVotes(uint256)", "0x4a7b26ec": "join_game(uint256)", "0xcccf7a8e": "has(uint256)", "0xa525f42c": "transferFromToICAP(address,bytes32,uint256)", "0xeef8e35f": "setChainyURL(string)", "0x557ed1ba": "getTime()", "0x595da94d": "has_owners(uint256)", "0x12511c14": "transferEnable(bytes20)", "0x2b291eb6": "UserAddTicket(bytes)", "0x50baa622": "withdrawToken(uint256)", "0xc01a8c84": "confirmTransaction(uint256)", "0x671dacdc": "CalculateSqrt(uint256)", "0xe74ffbd5": "getPart(bytes32,uint256)", "0xdd54a62f": "content(string)", "0x4025b293": "redeemAllOutcomes(bytes32,uint256)", "0xa8659216": "setInitialLockinDays(uint256)", "0x00b5b223": "computeResponse(uint256,uint16)", "0x2ef761d3": "buyTile(uint8,uint8)", "0x0a874df6": "lookup(uint256)", "0x42c69566": "get_address(address,string)", "0x02dc2e1d": "queuePayment(bytes)", "0x86bb7121": "getBlocksPerRound()", "0xacfdfd1c": "deploy(uint256,string,string,address)", "0x7d298ee3": "beforeExecute(address,uint256)", "0x5023d124": "TestFactory()", "0x827ef325": "_parseMsgData(bytes)", "0xd35b9d83": "codeAt(address)", "0x26161670": "donkeyRanking(uint256)", "0xe0834ea4": "WatchBalanceInEther()", "0xd44f2d3d": "getInitialWithdrawalDone()", "0x4f223fe3": "StatefulFactory(string,string,string)", "0x91cd242d": "setMeta(bytes32,bytes32,bytes32)", "0x9a97043b": "depositIdx(address)", "0x85db2dda": "PayoutQueueSize()", "0x423e1298": "setDoNotAutoRefundTo(bool)", "0xb7a97a2b": "isValidChannel(uint256)", "0xc1441172": "setBlackFlagRequest(uint256,uint256)", "0x53d9d910": "create(address[],uint256,uint256)", "0x64d905c0": "awaitingParticipants()", "0x718bd6dd": "setRequestUntil(uint8)", "0x5a353193": "KrakenPriceTicker()", "0xfb099c84": "newInvestor()", "0xd264e05e": "forward()", "0xcd9f05b8": "balanceEtherAddress(address)", "0xa1da2fb9": "retrieveDAOReward(bool)", "0x60708ae3": "issueAndCommit(address,address,uint256,uint256)", "0x109df68e": "rotateBitsRight(bytes,uint256)", "0x793cd71e": "cashOut()", "0xd3017193": "addUser(address,uint256)", "0xaacf5328": "setVideoID(string,uint256)", "0xb56e1bca": "setExchangeToken()", "0x9341231c": "sendOrThrow(address,uint256)", "0xaed8f3da": "partsPerBillion(uint256,uint256)", "0xdcff5581": "NewFeeAddress(address)", "0xbbe4fd50": "getNow()", "0x3df16377": "make_move_and_claim_victory(uint256,uint8,uint8,uint8,uint8,uint8,uint8,uint8)", "0x5ae5df8f": "deleteRef(string)", "0x6d853ab6": "isSubUser(address)", "0x28472c6c": "claimComputation(bytes,bytes)", "0x2c215998": "updateStatus(string)", "0x7eff1465": "setAccountAllowance(address,address,uint256)", "0xd5089396": "Token(string,string,uint8,uint256)", "0xd1f7a4e4": "createCertificate(bytes)", "0x8c0e2a31": "regProxy(address)", "0xa819819b": "sweepDeityCommission(uint256)", "0x2b861629": "storeBlockHeader(bytes)", "0x25d4bdeb": "LookAtCollectedFees()", "0x5dddea66": "updateState(uint256,uint8,uint256)", "0x3ccfd60b": "withdraw()", "0x6795dbcd": "getAddress(bytes32,string)", "0x9b9ba572": "oraclize_query(string,string[3])", "0xa925d85e": "Exchange(address,address)", "0xbfe8c107": "betOnDozen(bool,bool,bool)", "0x1af716ba": "transferFrom(address,address,uint256,string)", "0x67eae672": "sendCoinFrom(address,uint256,address)", "0x311d5a2a": "recordBalance(address)", "0x7ca823d5": "getAverageChainWork()", "0x19483cd1": "checkHash()", "0xd366fbab": "startLottery(bytes32,uint256,uint256,uint256,uint256,bool)", "0x4d70d1d7": "generateId(uint256)", "0xe13dc28b": "testValidTransfers()", "0x12065fe0": "getBalance()", "0xdd67a360": "OrderLifeCycle()", "0xd7c23572": "historyTimesPlayed(address)", "0x2675c123": "CloseContract()", "0x1381e400": "cancel(uint32)", "0xa48a663c": "transferFromToICAPWithReference(address,bytes32,uint256,string)", "0xb03260be": "scheduleTransaction(uint256,address,bytes)", "0xb37217a4": "getRandomNumber(uint256)", "0x5c54305e": "InsufficientFunds(address,uint256,uint256)", "0x17e1b09b": "minimumDeposit(uint256)", "0x10c4e8b0": "all()", "0xa31d5580": "Registrar(address,bytes32,address)", "0xbe6307c8": "getDraw(uint256)", "0xc985c221": "get_all_levels()", "0x91b7f5ed": "setPrice(uint256)", "0xe42def21": "CryptoHill()", "0x738486bd": "BeerCoin(uint256)", "0xe422ebe9": "getBot()", "0x67dd74ca": "buyTicket(uint256)", "0x276b94e1": "copypaste()", "0x39aaba25": "get_status()", "0x7ed19af9": "multiAccessRevoke(bytes32)", "0x4c1b2446": "transmitInteger(address,bytes,bytes,uint256,uint16)", "0xd014c01f": "enter(address)", "0x1d49e081": "EXECUTE_EXTRA_GAS()", "0x9dafbc13": "initBlock(uint256)", "0xc7e22ac4": "setOracleGas(uint256)", "0xa3053236": "SafeInvestments()", "0xf42ac1de": "minQuorum(uint256)", "0x04d91c6a": "testFail()", "0x0e662cf0": "buyTokens(uint16)", "0x1ef0625b": "player_2(uint256)", "0xcec1365a": "ShortLimit(uint256)", "0x340f5e4e": "get_all_num_levels()", "0x3e2729bf": "isRevocated(bytes)", "0x5a1cc358": "getChannelRank(address,uint256)", "0x4d366398": "runPeerBalance()", "0xaf9a3f9b": "hashName(string)", "0x33298e25": "invoke(uint256,uint256)", "0x63def590": "untrustClient(address)", "0x836d6d66": "WeeklyLotteryB(address,uint256)", "0x7f497550": "scheduleTransfer(address,uint256,uint256)", "0xf9e05ed9": "sha(uint128)", "0xf6458c6a": "toZ1(uint256[3],uint256)", "0xf41017fc": "finalize(uint24)", "0xeeb57139": "CollectMoney(uint256)", "0xfdacd576": "setCompleted(uint256)", "0xb7266456": "StandardToken()", "0x6a8c2437": "totalRescues()", "0x1fdf6e0c": "protectKingdom()", "0xcf31e9fe": "getOutputHash()", "0xc8117b5b": "extractBalanceOfLength()", "0x0674763c": "assert(bool)", "0x87def081": "getFeeRecipient(int256)", "0xc63ff8dd": "claim(bytes)", "0x329bfc33": "getCurrentWinner()", "0x3d6a3664": "setNewOracle(address)", "0xdaa21e0e": "testBitSetSuccess()", "0xbf8783e0": "callAndGetReturn(address,bytes,uint256)", "0xb06df18e": "transfer(bytes20,address)", "0x00100a18": "NewPoll(string,string,uint256,uint256)", "0x2ffb8631": "getReleaseLockfileURI(bytes32)", "0x6716a692": "setDVIP(address)", "0xe8223468": "sha3clone(bytes)", "0x0aeacb5e": "getTotalRecords()", "0x29e30910": "testThrowCreateExistingNonce()", "0x240ecad5": "transferViaProxy(address,address,uint256)", "0xa33d4968": "Tripler()", "0x8caaaae6": "totalWeiPrice()", "0xf28a7912": "quick2()", "0xcbe9ef39": "BasicCoin(uint256,address)", "0xea3d2827": "selectWinner(string)", "0x92e9fd5e": "ColdWallet(address,address)", "0xcd5e3c5d": "roll()", "0x4a82534b": "create(address,address,address,uint256,uint8,uint8,uint256)", "0x5ccd2f9b": "_deleteAllPackedRevisionBlockNumbers(bytes20)", "0x9380b8e7": "testFailAddingMembers()", "0x31b0795c": "registerAddress(address,address)", "0xb76e4890": "Tester()", "0x29c08ba2": "payPremium()", "0xd7f31eb9": "forward(address,uint256,bytes)", "0xd7ef1356": "best_adjustment(bool)", "0x48d9a374": "blockTransfer(address,uint256)", "0x88b9e10e": "seizeTokens(address,uint256)", "0x8736fd16": "getRefStatus(uint256)", "0x2b30d2b8": "invoke(uint256)", "0xd4e78272": "Draw()", "0x0257c48c": "meta(bytes32,bytes32)", "0xc1246d39": "simulatePathwayFromBeneficiary()", "0x699b328a": "randomize()", "0xa200dc73": "getNextShareholder(address)", "0x9a7a7c11": "makeRoll(uint256)", "0x2bf1f9da": "restart(bytes32,bytes)", "0x943a32bc": "Relay(address)", "0x93503337": "isAllowed(bytes32,uint256)", "0xe97b2190": "add_wall(uint16)", "0x0448f79f": "addOptionChain(uint256,string,uint256,uint256,bytes,address,int256[])", "0xc0df77d0": "getRefName(uint256)", "0x27121069": "verify(bytes,uint8,bytes,bytes)", "0xb7009613": "canCall(address,address,bytes4)", "0x0295d71b": "currentDepositLimit()", "0x35ee2783": "Alarm()", "0x71b6663e": "play1(address,uint256)", "0x0178fe3f": "getData(uint256)", "0x489306eb": "oraclize_query(string,string)", "0xfce59d0c": "MangoRepo()", "0x8efc777f": "isBeta(bytes)", "0x1f7b8622": "getVotingDeadline()", "0x76da5667": "admin_kill()", "0x152cf9db": "getDataPoint(int256,uint256,uint256)", "0xd09de08a": "increment()", "0x64ee49fe": "scheduleCall(address,uint256,bytes4,uint256,uint256,uint8)", "0xd9fe60f3": "DTHPool(address,address,uint256,string,string,string)", "0x6b4dd158": "getPrice(bytes)", "0x0a80ef45": "getIsClosed()", "0x51fdaf92": "checkExpiredfunds()", "0x694e0d5b": "StringPasser(uint8[])", "0x0e1d88fc": "addTender(uint256,uint256,address,uint256)", "0x53850db3": "getParticipantById(uint256)", "0xb6cb405b": "getContractor()", "0x4c6b25b1": "results(bytes32)", "0x1c4e6cd0": "NameReg()", "0x53aab434": "buyIn()", "0x1ebe5c0f": "sendWithAllOurGasExcept(address,uint256,uint256)", "0xd98b9bb5": "placeBid(address,uint256)", "0x02e8d8c0": "scheduleTransaction(address,uint256,uint256)", "0x8a120dc9": "testBitEqualFailIndexOOB()", "0x33f707d1": "ownerWithdraw(uint256)", "0x98e00e54": "getCallWindowSize()", "0x4da74ee6": "setVoteIntention(uint256,bool,bool,string)", "0x6617e11a": "NiceGuyTax()", "0xfe13a823": "computeResponseFirstHalf(uint16)", "0xf7bd2361": "LookAtBalance()", "0xb09bc3bf": "try_to_get()", "0x0cee22e9": "testSetBalanceSetsSupply()", "0xae404996": "oraclize_query(string,string[3],uint256)", "0x2ad95786": "winner(address)", "0xe5fe4f31": "buy(uint8,bytes32,bytes32)", "0xe23941bc": "testDepositWithdraw()", "0xfc89aff6": "submitVerifiedUsers(address[])", "0xddf187b0": "dogFight()", "0xb5f5962a": "CALL_GAS_CEILING(uint256)", "0x92093dd6": "getLastResult()", "0xbfad16f4": "new_offer(uint256,uint256)", "0x01df7f30": "validateProposedThroneConfig(uint256,uint256,uint256,uint256)", "0x4054f5de": "EthVentures3()", "0x244c23ee": "Token(uint256,string,uint8,string)", "0xc3daab96": "withdrawBond(uint256)", "0x5fa21f1f": "enableBetting()", "0x3b591ea7": "AmountToForgeTheNextBlock()", "0x8c3c4b34": "getSaleStatus()", "0x7429f1eb": "multiAccessSetRecipientD(address,address)", "0xf99ff4df": "paged(uint256,uint256)", "0x2a64fb63": "getSaleDate(bytes)", "0x749f9889": "changeAllowedRecipients(address,bool)", "0x053c351b": "oraclize_getPrice(string)", "0x19663f7f": "TransferAmountFromBankAccountToAddress(uint256,address)", "0x5292c1a9": "testThrowsRestartEnforceRevisions()", "0x68f2ab8e": "Currency(string,string)", "0xd6e0bf29": "OwnerDeposit()", "0x94c3fa2e": "getLastBlockHashUsed()", "0x45362978": "query1(string,string)", "0xaff21c65": "getMinimumEndowment(uint256)", "0xe33c7ae2": "scheduleTransaction(uint256,uint256,bytes)", "0x9eb9dd3b": "getBetsProcessed()", "0x3807ba1b": "poi()", "0x7281854d": "GetCategoryValue(uint8)", "0x45ee49b9": "getUltimateOutcomes(bytes)", "0x0109f22e": "CrowdSale()", "0x98596726": "note(uint224)", "0x06900c41": "ZeroPonzi()", "0x3df76482": "fipsPublishData(bytes20,bytes)", "0xe0429b6c": "ShinySquirrels()", "0xa4a7cf5c": "redeemWinnings(bytes32)", "0x2e898ddc": "validateTemporalUnit(uint256)", "0x3af75ee1": "storeBlockWithFee(bytes,int256,bytes,int256)", "0x43e6125d": "Badge(address)", "0x75a6a332": "testThrowRetractNotRetractable()", "0xbed411a0": "CheckPrize(address)", "0x16f3cb5e": "__kill()", "0xe8efc1a0": "updatedValue(bytes32)", "0x9c7264d7": "fillOrder(address,uint256)", "0x9a0af2ec": "getStLength()", "0xf62cce34": "_clearRecordHierarchy(uint256,bytes32[],bytes32)", "0x940f851c": "Ballot(uint8)", "0xd96e5565": "testThrowsRetractNotRetractable()", "0x3a314b24": "SendETH(address)", "0xbd8c1d33": "checkTransferFromToICAPWithReference(address,bytes32,uint256,string)", "0x01da73ff": "isValidChannel(bytes)", "0x8f8bde82": "MicroDAO()", "0x2973e372": "isAlphaUpper(bytes1)", "0x1d2b7155": "activateImportFeeChargeRecord(address)", "0x06ab5923": "setSubnodeOwner(bytes32,bytes32,address)", "0x9d7d6667": "multipliers()", "0x8af49ab7": "maintain(uint256,uint256)", "0x1f3a3a53": "mint(int256,uint256)", "0x74389991": "breakit()", "0x64371977": "set(uint256,string)", "0x3fa6497f": "AdminAddFunds()", "0xba7dc45f": "_removeOperation(bytes32)", "0xf81d087d": "prepareLottery()", "0xd239ea8b": "getSchemasLenght()", "0xa2f3ede2": "computeNameHash(bytes)", "0xa28ecf0b": "sendCryptedHand(bytes)", "0x003b9d88": "setLowerFeePercentage(uint8)", "0x98ea5fca": "depositEther()", "0xb9a0a708": "testChargesAmountApproved()", "0x55291dbd": "claimEther()", "0x2d2800f1": "react()", "0xa9d2293d": "lastClaimBlock()", "0xc45aa04c": "queryShareholders(bytes,uint256)", "0x67af1c81": "getRoundIndex()", "0x50b7b7a2": "setRating(bytes32,uint256)", "0x0aa7881a": "MintableToken(int256,uint256)", "0x0eb3f5a0": "sweepCommission(uint256)", "0x97d47a60": "registerAccountant(bytes,address)", "0xe2c61114": "setImportFee(address,uint256)", "0x6dbe31eb": "testSubBalance()", "0xf5c98aff": "GreeterB(bytes)", "0x79216f5f": "add_monster(uint16,uint16,uint16)", "0x023c23db": "getSize(uint256)", "0x0e1ca8a5": "Oraclize()", "0xa05e822a": "howManyOwners()", "0x313b7b19": "finance()", "0x51a5f2f2": "ConsultingHalf(address,address)", "0x1fb6e99d": "paymentNeeded(uint64)", "0x2bffc7ed": "add(string,address)", "0x5c52c2f5": "resetSpentToday()", "0x39cdde32": "ecverify(bytes32,bytes,address)", "0x64e24f4b": "UpdateClientTokenAccount(address)", "0x0d2560ee": "addMe()", "0xd8589be3": "CoinFlipper()", "0x3b46a7df": "ivote(bool)", "0xa6823189": "parseAddr(string)", "0xd0c24e93": "setNotUpdatable(bytes20)", "0x1f13de92": "inEther(uint256)", "0xb6ce5581": "oraclize_query(string,string[5],uint256)", "0x31ae0019": "KissBTC()", "0xdabf7dc8": "PayoutDividendEarly(uint256,bool)", "0xe3da41b5": "sortWinningNumbers(uint8[5])", "0x8ea98117": "setCoordinator(address)", "0xeff6be2f": "changeBaseFee(uint256)", "0x483a83df": "setKYC(address)", "0xf98a4eca": "executeVote(uint256)", "0x776d1a01": "unvest(uint256,uint256,uint256,uint256,uint256,bool)", "0x1cf52f2b": "isActiveRegistrant(address)", "0x24c9bf5e": "Prizes()", "0xb3822da8": "getContents(uint256[])", "0x999a9965": "setMany(uint256,int256,uint256,bytes,address,bytes)", "0xbade6033": "propose(bytes,uint256)", "0xd38159b8": "testPass()", "0xdabf7ec4": "helper(uint256)", "0xf4993bbd": "executeEmergencyWithdrawal()", "0x46ddb7db": "setAccountBalance(address,uint256)", "0xc12af1ce": "fipsRegister(uint256,bytes)", "0x8f420866": "DEFAULT_SEND_GAS()", "0x62770252": "needsFuneral(uint256)", "0x32921690": "checkDepth(address,uint256)", "0xb3c1a588": "parseMsgData(bytes)", "0x29cd5777": "_tryEraseSingleNode(bytes32)", "0xc6e0c908": "checkTransferFromWithReference(address,address,uint256,string)", "0x9bd99195": "multiAccessChangeOwner(address,address)", "0xa360b26f": "Migrations()", "0x6c6f1d93": "getContractCreationValue()", "0x5445e38c": "_isCycleValid(uint256)", "0x2c85f8e0": "oraclize_query(string,string,string,uint256)", "0xcdda62ad": "FutureBlockCall(address,uint256,uint8,address,bytes4,bytes,uint256,uint256,uint16,uint256,uint256)", "0xc8fdc891": "numberOfMonarchs()", "0xf578fd85": "assertEq0(bytes,bytes)", "0xda311588": "getCoin(uint256)", "0x9a35f886": "__dig_then_proxy(uint256)", "0xfa14df6b": "getChangeRecipientFee()", "0x95f0684b": "getPackageNameHash(uint256)", "0x42909a9e": "create_game()", "0x51582ef3": "sendProxyTransaction(address,uint256,uint256,bytes)", "0xc4e41b22": "getTotalSupply()", "0x110df916": "getChannelID(uint256)", "0x4dc3141b": "CalcAll()", "0xb88a802f": "claimReward()", "0x82b2e257": "getTokenBalance()", "0x9bb0e4df": "getUint(int256,bytes32,string)", "0xc1ae4044": "checkBetColor(uint8)", "0x4a8b5389": "allocateBountyAndEcosystemTokens()", "0xdf06f906": "numBets()", "0xdeb80111": "transfer_asset(address,uint256)", "0x5216aeec": "totalInvested()", "0xe2deaa81": "set_reference(uint256,uint256,uint256)", "0x2ffda1e0": "setBlackflag(uint256,bool)", "0xba45b0b8": "transfer(address,address)", "0x7d7c2a1c": "rebalance()", "0xf32efd3c": "recoverUser(address,address,uint256,uint8,bytes32,bytes32)", "0x4571d4c4": "FutureCall(address,uint256,uint16,address,bytes,bytes,uint256,uint256,uint256)", "0x5fc5d48b": "burnUnsoldCoins(address)", "0x4da47ba0": "TokenSale(address,uint256)", "0x3d9ce89b": "scheduleCall(bytes4,bytes,uint256)", "0x6662e4be": "isWinningBet(uint256)", "0xa501e88d": "Content()", "0x4b70cec4": "getTime(address)", "0x12253a6c": "stopContract()", "0x173825d9": "removeOwner(address)", "0x26121ff0": "f()", "0x7b647652": "LittleEthereumDoubler()", "0x0c5c2ca3": "getIndexName(bytes)", "0x90f2c86d": "convertToWei(uint256,string)", "0x83f95f13": "openClaim(string)", "0xe8b5e51f": "invest()", "0xfdc4b338": "authorizeExtension(uint256,bool,string)", "0x4e116eb8": "unRegisterCertificationDb(address)", "0x5c8a1053": "extend(string)", "0xa932ed0d": "whitelistRemove(address)", "0xa1188e56": "getCurrentDifficulty()", "0xbf1fe420": "setGasPrice(uint256)", "0xead710c4": "greet(string)", "0x144fa6d7": "setToken(address)", "0x42402c2c": "fipsTransferMulti(bytes20[],address)", "0x93e84cd9": "play()", "0x741b3c39": "depositBond()", "0x23306ed6": "getMinimumBond()", "0x5f2e686d": "Ethereum_eight_bagger()", "0x9890220b": "drain()", "0x233120aa": "getChainyURL()", "0xe9dc0614": "vote(bytes)", "0x4df53a0f": "testSetApprovalDb()", "0x5fe27ab0": "createHKG(address)", "0xb56b2627": "add_owner(uint256,address)", "0x6f9a023c": "theultimatepyramid()", "0xc8796572": "collectFees()", "0xea3ebae6": "getConfigBool(bytes32)", "0x213ac932": "addUser(address,uint256,uint8,bytes32,bytes32)", "0xfae9d06d": "calculateTxFee(uint256,address)", "0x45d27edf": "forward_method(bytes,address,uint256,bytes)", "0x8e9ccd04": "computeIndexId(address,bytes)", "0x2f6ae467": "transferDocument(bytes,address)", "0x6e353a1d": "emergencyWithdrawal(address)", "0x7dd56411": "ownerOf(bytes32)", "0x9dc35799": "updateReading(uint256)", "0x246c02e6": "check_depth(uint16)", "0x03d22885": "scheduleCall(address,uint256,bytes4,uint256,uint256,uint8,uint256)", "0x881be8f7": "undo()", "0x953307d8": "revealScissors(string)", "0x7af30442": "testToggleBitFailIndexOOB()", "0x1e0c7ed4": "setConfigBool(bytes32,bool)", "0x2e3be78d": "setPrecisionDirect(uint8)", "0x95a078e8": "hasAccess(address)", "0x245a03ec": "scheduleSetIt(uint256,uint256)", "0xb863bd37": "random(uint256)", "0xa5e62f02": "fallbackRP()", "0x618fa9ce": "getBotBillingIndex(uint256,uint256)", "0x06909f69": "cancel(string,uint256)", "0x2b198366": "addCertifier(address)", "0x57e871e7": "blockNumber()", "0x2b98222e": "getInstitutionByAddress(address)", "0x89eedf00": "setPdfHash(bytes,bytes)", "0x7ac4b05e": "returnMyMoney(uint256)", "0x7fc90182": "Pool(uint256)", "0x291e6777": "sendVote(uint256,uint256)", "0x579badf6": "UniversalFunction(uint8,bytes32,bytes32,bytes32,bytes32,bytes32)", "0xe1f21c67": "approve(address,address,uint256)", "0xa1b9af31": "unlockBets()", "0x92d0d153": "t()", "0x095ea7b3": "approve(address,uint256)", "0x9cb31079": "setLowLimit(uint256)", "0xb971b4e5": "setNotTransferable(bytes20)", "0x2a745971": "BlockKing()", "0x582ca57b": "get_associations()", "0xa0d605c6": "addCertificationDocumentInternal(address,bytes32)", "0x85233869": "NumberOfMiners()", "0xb0349184": "clearRecords(bytes32[])", "0x3e8f5b90": "setConfig(string,uint256)", "0x7c73f846": "getMinimumEndowment(uint256,uint256,uint256)", "0xcc9ae3f6": "getMyReward()", "0xac900c2d": "unregisterSeller(address)", "0x306df22d": "GPSDestination(int256,int256,uint256)", "0x5e968a49": "ownerSetMaxProfitAsPercentOfHouse(uint256)", "0x80dcaf27": "getRefNumber()", "0x4245b0f7": "Lottery()", "0xe46164c5": "waitingForPayout()", "0xa8c3ec48": "oraclize_query(uint256,string,string[2])", "0x58ea80e5": "setThroneCreationPrice(uint256)", "0x8a4fb16a": "getWithdrawal(uint256)", "0x4464aec7": "testTryGet()", "0xf3c37bd5": "Verifier(address,uint256,uint8)", "0xb4c4e005": "testTransferToAcceptAuthority()", "0x346b306a": "oraclize_query(string,string,string)", "0x24032866": "checkExecutionAuthorization(address,uint256)", "0x509f8633": "create_account()", "0x26da8e17": "ownerUpdateCostToCallOraclize(uint256)", "0x74a93e6c": "setTokenHolder(address,address)", "0x1baaeb91": "getSignature(bytes4,uint256)", "0x337c1e28": "getIndexRoot(bytes)", "0xac92fdb5": "getSaleDate(bytes16,uint256)", "0x13b2663b": "cash_received(string)", "0x68e4bd99": "testSetBitSuccess()", "0x20620f37": "onAuctionEnd(string)", "0x85528394": "currentClaimPriceWei()", "0x1995333b": "burnFunds(uint256)", "0x5184ffc9": "setAmbiAddress(address,bytes)", "0x269975d0": "GameDetails(uint256)", "0x29274fe1": "buyBOTx(uint256,string,string,address,uint256)", "0x720c4798": "workshop()", "0x6f9a5eab": "createTx(uint256,address,uint256)", "0xb66a323c": "claimThrone(string)", "0x14cabddb": "joinProof(uint256)", "0x76e4ca0d": "voteQuorum(uint256,bool)", "0xbcb3b5d2": "getGamblesList(uint256)", "0xf2080ba6": "Pong(int8)", "0xab470f05": "getCaller()", "0xe0b1cccb": "updateBalance(address,uint256)", "0x4889ca88": "receiveApproval(address,uint256,address)", "0xbc4b3365": "addFunds(address,uint256)", "0x5d1a3b82": "getOutcome(bytes32)", "0x8204ecdd": "getFee(bytes)", "0x49aa4ee2": "removeVote()", "0x9131d803": "testSetFrontend()", "0x72929b56": "getKudosPerProject(address)", "0x287418e7": "query(uint256,uint16)", "0xbb7859b5": "periodThree()", "0x7dc5cd32": "_patternToNumber(bytes)", "0xf7ea7a3d": "setTotalSupply(uint256)", "0xb3f98adc": "vote(uint8)", "0x655388be": "walkTowardsBlock()", "0x856deacf": "findTag(string)", "0xcaab0acc": "testThrowCreateRetracted()", "0xede8ebf3": "checkApprove(address,uint256)", "0x4296a9cb": "getNodeRightChild(bytes)", "0x03cf4fd6": "expire(uint256,uint256,uint8,bytes32,bytes32,bytes32)", "0x87045369": "setCanCall(address,address,bytes4,bool)", "0x0ed21029": "getIssueAssignee(uint256,bytes32)", "0xc5958bda": "removeFile(bytes)", "0xa8026912": "setSource(address)", "0x05a5b8c6": "verifyTx(bytes,int256,int256[],int256,bytes,int256,int256[],int256)", "0xed3058e0": "transferRight(address,bytes)", "0xba487e62": "newCampaign(uint32,uint96,uint16,uint16)", "0xd6c19fe0": "build(bytes,uint256,uint256,address)", "0xebb741cb": "getChannelSize(uint256)", "0x3b996f40": "quarter(uint32,uint32,uint32,uint32)", "0x0b7373d6": "giveAllBack()", "0x3f887fad": "buyShares(uint256,uint8,uint256,uint256)", "0xb5deeca7": "BaseRegistry()", "0x6dd6e87b": "checkOut(int256)", "0x90a85119": "checkBetResult(uint8)", "0x724121ae": "contentExists(uint256)", "0x67bd69a6": "getLastDuel2()", "0x821e9169": "testFailControllerChargeMoreThanApproved()", "0x083ae1fe": "setPackage(string)", "0x8eaa6ac0": "get(bytes32)", "0xf42aa287": "getBlobStore(bytes12)", "0x32a2c5d0": "getContractAddress()", "0x69d89575": "releaseFunds()", "0x984ac378": "lotteryTitle()", "0x3baf4e1e": "newPayment(uint256,uint256)", "0x938c4307": "scheduleCall(bytes4,bytes,uint16,uint8,uint256,uint256,uint256,uint256,uint256)", "0x47372325": "getChannelSize(address)", "0xcb10e0c5": "getLastDuel1()", "0x1a0919dc": "unregister(bytes32)", "0x6a3c1198": "_projectCancelNew()", "0x976b01c0": "setNotRetractable(bytes20)", "0x44d03ac6": "BlockhashFetch(address)", "0xb0fd935b": "registerCertificationDb(address)", "0x2c7c4549": "PurchasableToken(uint256)", "0x3e0a51b4": "TweetAccount()", "0xc5f310c0": "register(bytes12)", "0xc10dd4c6": "getEvents(bytes32[],address)", "0x37a6b9f8": "recordCallback(address,uint256,bytes,bytes)", "0x1b9265b8": "pay()", "0xc91d7e9c": "getFee(bytes32[])", "0xf6c5c80d": "cleanUp()", "0x590e1ae3": "refund()", "0x9c709343": "split(bool,address)", "0xe68d3ae3": "escrow(uint256,string,address,uint256)", "0xa1cb31b7": "_state()", "0xfbac3951": "isBlocked(address)", "0x29dfdded": "addNewDonkey(address)", "0x7bc49a95": "play(uint256,uint256)", "0x5329c681": "checkTimeout(uint256)", "0x7c05caf3": "testCreateCostAuth()", "0x8606f905": "balanceOf(address,bytes)", "0xbe45fd62": "transfer(address,uint256,bytes)", "0xd7130651": "getCity(uint256)", "0xb2353d69": "updateRightLottery(address)", "0x01bb85a4": "__startBlock(string)", "0x4316abbb": "newJester(address)", "0x5c3e426c": "adminRetrieveDonations(address)", "0x293ffca3": "AddressReg()", "0x4156fdb7": "createSwap(uint256)", "0x2852b71c": "accept()", "0x027a5e3f": "getLastVersion(bytes)", "0x3d90d44d": "addPowerSource(address,uint256,uint256)", "0x1ab06ee5": "set(uint256,uint256)", "0x50f07cf9": "setReadingDelay(uint256)", "0x669e48aa": "get(uint256,uint256)", "0xdea9c72b": "getLatestPreReleaseTree(bytes32,uint32,uint32,uint32)", "0x60f66701": "useCoupon(string)", "0x2431f164": "process_payment()", "0x17623e5b": "unauthorizeManager(address)", "0x367bbd78": "strlen(string)", "0xbab86ea8": "test(string,string)", "0x25f3da52": "GetBankAccountNumber()", "0xebb045fa": "PublicResolver(address)", "0xdd57d5c5": "setTrust(address)", "0x22e803c2": "transferBounty()", "0x12c8052f": "won()", "0x3535cd52": "setDailyCosts(uint256)", "0x92d8c8cf": "setupImportFee(address,uint256)", "0x53caf582": "testThrowSetNotUpdatableNotOwner()", "0xb3ade772": "shipProducts(string,string)", "0x61472fd4": "CSGOBets()", "0x5c7c9aa4": "checkAccountState(address)", "0x6560a307": "suggestedGas()", "0xd0d552dd": "setAsset(address)", "0xc02f081a": "shiftBits(bytes,int256)", "0x9348cef7": "reveal(uint256,uint256)", "0x5ca1c5a0": "getNodeValue(bytes)", "0x34c1b4ba": "sha(bytes)", "0xe0117441": "setRegistrationPrice(uint256)", "0x92698814": "reserved(bytes32)", "0xaa1e84de": "hash(bytes)", "0x2125b65b": "transfer(uint32,address,uint224)", "0x9f9eac67": "ChangeName(string)", "0x7eb69ba1": "hint(int256,bytes32,string,bytes20)", "0xc6888fa1": "multiply(uint256)", "0xa9059cbb": "transfer(address,uint256)", "0x84c344fe": "_register(bytes4,string)", "0x744d8b4f": "recordWin(uint256,uint256)", "0xad1ef61e": "donkeyInvested(address)", "0xb4787dc5": "linkEID(bytes,bytes)", "0x7b1cbb13": "getChannelValue(bytes)", "0xd0febe4c": "buyTokens()", "0x74f519db": "setLastTimestamp(uint256,uint256)", "0xe30081a0": "setAddress(address)", "0x6fd902e1": "getCurrentBlockNumber()", "0x25d8dcf2": "betAndFlip()", "0xc062f578": "updateStage()", "0xe0cfc05c": "testThrowsRetractLatestRevisionDoesntHaveAdditionalRevisions()", "0x854f4817": "buyKissBTCWithCallback(address,uint256)", "0x58b1f29c": "refundBounty(uint256)", "0x0645b5d5": "getMyShareholderID()", "0xe9c63b9c": "requestPeerBalance()", "0x1b03316f": "getSecond()", "0xbcc6092a": "MyEtherBank()", "0x1cf43b63": "extractExportFeeChargeLength()", "0x5e58f141": "shares(address,bytes,int256)", "0x6103d70b": "withdrawPayments()", "0x3e0663e0": "AdminDrawProcess()", "0xa0f029fc": "ContractorInterface(address,address,address)", "0xe604cf9f": "get_all_squares()", "0xd13d1ace": "scheduleCall(bytes,bytes,uint16,uint8,uint256,uint256,uint256,uint256,uint256)", "0xb74bc710": "LuckyDoubler()", "0x611f69de": "__proxy_motion(address,uint256,uint256,bytes)", "0xbb814e9e": "versionExists(bytes32)", "0x545e7c61": "deploy(address,address)", "0x1b437d0c": "compareLastCalldata(bytes)", "0x845051d3": "testContractsNotNull()", "0x23de6651": "emitTransfer(address,address,uint256)", "0xd78c20ff": "voteApprove(uint256)", "0x6f13e01b": "EthVenturePlugin()", "0x1f6b0a9d": "getReleaseLockfileURI(string,uint32,uint32,uint32,string,string)", "0x13d4bc24": "buyTokenProxy(address)", "0xd509b16c": "testWithdraw()", "0x2f54bf6e": "isOwner(address)", "0xf60381a1": "stra2cbor(string[])", "0x34dbe44d": "getLastBlockNumberUsed()", "0x28dcfdac": "getSignsCount(uint256)", "0x2888f9d0": "updateMaxBet()", "0xc3b2556d": "lookup(bytes)", "0x6fbaaa1e": "currentMultiplier()", "0xe241c1d9": "deriveKey(uint256,uint256,uint256)", "0x5b37e150": "create(bytes32,bytes)", "0xa1c95ac2": "GSIToken(uint256,string,uint8,string,address)", "0xfc9e53df": "setNextRegistrar(address)", "0x34e8980f": "bootUpHangouts()", "0x457dd8b3": "setMasterKey(address)", "0xdb833e3a": "sellShares(bytes32,uint8,uint256,uint256)", "0x1e5330ca": "checkBetResult(uint8,address,bytes32,bytes32)", "0x4a00a522": "homebase(int256,int256)", "0xb938bf42": "sendBounty(bytes32)", "0x46be96c3": "amountFilled(address,uint256,address,uint256,uint256,uint256,address,uint8,bytes32,bytes32)", "0x2fa00e58": "fipsTransfer(bytes20,address)", "0x95669952": "debtor(address,uint256)", "0x3f19d043": "getContributions(address)", "0xeb455dc6": "sendBitcoin(string,uint256)", "0x034cb28e": "addressOf(address,bytes)", "0x1e26fd33": "setBool(bool)", "0x1b55ba3a": "Start()", "0x6f3fe404": "updateBalances()", "0xc45b415e": "createRequest(address[4],address,uint256[11],uint256,bytes)", "0x180aadb7": "underLimit(uint256)", "0xb44bd51d": "getConfig(string)", "0x93d79105": "hashRelease(bytes32,bytes32)", "0x9f8a13d7": "isActive(address)", "0x257bcd6a": "placeBet(uint256,bytes32,bytes32)", "0xdd10d97e": "getPlayerWaiting()", "0x6d16f79c": "__transferWithReference(address,uint256,string)", "0x6ce1417e": "Fund()", "0x67beaccb": "scheduleCall(bytes)", "0x4b0697e4": "Manager(address)", "0x6a7fc8b7": "setDailyWithdrawLimit(uint128)", "0x7a6e9df7": "getTimestamp(bytes)", "0x797af627": "confirm(bytes32)", "0x81183633": "setStandard(bytes32)", "0x6a1db1bf": "changeFee(uint256)", "0x4e6ab570": "insert_order(address,bool,uint32,uint128)", "0xa4e2d634": "isLocked()", "0x7c79ebce": "expired(uint64)", "0x20965255": "getValue()", "0xfd408767": "fireEventLog4()", "0xcf6b3822": "WatchCollectedFeesInSzabo()", "0x8f7fe231": "ValidetherOracle()", "0xbf12165e": "fillUpSlot(uint256,uint256)", "0xdabdc1f2": "ChangeActiveDigger(address)", "0xe9e7a667": "get_stake(bytes32)", "0x0ad95b44": "bribery()", "0xdb6fcf01": "is_destroyed(uint256)", "0x4378a6e3": "getAttributes(uint256)", "0x71589d6b": "newponzi()", "0x47274dbe": "disableUser(address,address)", "0xb40a5627": "bidCount()", "0xf1eae25c": "mortal()", "0x13af4035": "setOwner(address)", "0xaf030d2c": "setResult(uint256,uint256,bytes32)", "0x098ab6a1": "snapshotCount()", "0x27cca148": "lastClaimedBlock()", "0x940c154b": "lockBet(uint256)", "0x378c0605": "buyTickets(address)", "0xbcfcb03e": "allocateFounderTokens()", "0x0138e31b": "_jAdd(uint256,uint256,uint256,uint256)", "0x0a7f4239": "getAccountFundContract(address)", "0xc96593a0": "The10ETHPyramid()", "0x22beb9b9": "scheduleDoIt(uint256)", "0xdb0e127a": "openDoor()", "0x3dc02266": "fipsRegister(uint256)", "0x7d242ae5": "setBasePrice(uint256,bytes)", "0xe82b7cb2": "proxySetCosignerAddress(address,bytes32)", "0xa60bbcd3": "ModelCoordinator()", "0xc26aa3c9": "lockUnicorn(uint256)", "0x96ff7e97": "requestIdentity()", "0x99753de7": "clear_level()", "0x69d79ad5": "moneySumAtSettlement(address,uint256,uint256,int256,uint256,uint256)", "0xda359dc8": "setBytes(bytes)", "0x6edb4cf6": "testThrowRetractLatestRevisionDoesntHaveAdditionalRevisions()", "0x9d170c5d": "getRef(string)", "0x11cd98ed": "convertToAllTable(uint256,string)", "0x67f809e9": "DynamicPyramid()", "0xd5f37f95": "sign(uint256,uint256,address)", "0xf5562753": "getClaimAmountForBlock(uint256)", "0xc9bbc8c0": "donkeyName(address)", "0x5858ef10": "testErrorNonOwnerCantBreach()", "0x74388347": "checkBetDozen(uint8,address,bytes32,bytes32)", "0xee564544": "_slotCancelNew()", "0xf3bb9741": "commitmentCampaign(uint256,bytes32)", "0x2b68b9c6": "destruct()", "0xa9b8f7b8": "ProtectTheCastle()", "0x16181bb7": "shortSellShares(bytes32,uint8,uint256,uint256)", "0xb524abcf": "totalSupply(bytes32)", "0x8006745b": "getPayout(address)", "0x137c638b": "getExtraGas()", "0x824d5603": "getIndex(uint16,uint16)", "0x245a6f74": "isProxyLegit(address)", "0x9eded57a": "paybackLast()", "0x7b1aa45f": "ownerDeposit()", "0x974654f4": "requiredGas()", "0x76d690bb": "BountyList()", "0xf4b2dfea": "Matching_Finneys()", "0xbd66528a": "claim(bytes32)", "0x85eac05f": "changeOwnerAddress(address)", "0xa69df4b5": "unlock()", "0xe6d9bb0f": "secondsUntilEnd()", "0xcd57a448": "SwapContract(address,uint256)", "0xb245fc92": "findNextMonth(uint256,bytes)", "0x7620f4bb": "fipsNotaryLegacy68b4()", "0x61886014": "combineDice(uint8,uint8)", "0xdf4ec249": "step3()", "0x2262cd94": "wroom()", "0x1099d3ec": "scheduleTransaction(uint256,uint256,uint256,bytes)", "0xd8c34127": "isKnownSignature(string)", "0x8afa08bd": "setDrawDate(uint256)", "0xdb18c972": "play4(address,uint256)", "0x2f30283e": "testSomething()", "0x8ca17995": "divest(uint256)", "0x1ef3755d": "restart()", "0x99bb875c": "funeralAndBirth(bytes,int256,bytes)", "0x157ad5a1": "canWithdrawBond(address,uint256)", "0xfd8055d2": "updateBOTBillingInfo(uint256,string,address,string,string,uint256)", "0xa10889fa": "setVersion(uint32,uint32,uint32,string,string)", "0x51cff8d9": "withdraw(address)", "0xbe999705": "addFunds(uint256)", "0x2e5d1042": "requestPayout(uint256,uint256,bytes32,uint256,uint256)", "0xb50954b6": "cancelWaitingForOpponent()", "0xc42cd8cf": "etherSplit(address,address)", "0x42ce1488": "upload(string)", "0xad04592e": "owner_deposit()", "0xc2cf7326": "hasConfirmed(bytes32,address)", "0x1dbf3bc7": "spend(uint256)", "0x36b81feb": "Deed(address)", "0xf47289e1": "_ecDouble(uint256,uint256,uint256)", "0x026993e0": "Midas(address,address)", "0x5e404de3": "setMaximumCredit(uint256)", "0x0194db8e": "sum(uint256[])", "0xa04a0908": "execute(address,bytes,uint256)", "0x2b4a3b31": "doTransferFrom(address,address,uint256)", "0x96ed10a4": "issuePOIs()", "0xb75c7dc6": "revoke(bytes32)", "0x6056969b": "announce(bytes32)", "0xd63547e6": "GetFreeCnt()", "0x788e26e7": "sponsorDeposit()", "0x550dd006": "calcCostsBuying(uint256,uint8,uint8,uint256)", "0xd4b1d19f": "testThrowsTransferDisabled()", "0x04706fdf": "giveContributionsBackProfitBugged()", "0x5d5483b3": "WatchAppliedFeePercentage()", "0x6bf8f85a": "forceFinish()", "0x3edd90e7": "NewOwner(address)", "0x7c69b5d1": "NewDeposit(uint256)", "0x866f6736": "trustedChildWithdraw()", "0xcdcb7c8f": "chase()", "0x60dccd89": "getContentAccount(uint256)", "0xbff1f9e1": "totalUsers()", "0x1aca00fd": "variable(uint256)", "0x6e658fbe": "myFundsExpireIn(uint256)", "0xddb1bdc8": "credit(address,uint256,uint256)", "0x934bc29d": "exampleFunction(uint256)", "0x113e6b66": "fipsAddToLedger(bytes20,address)", "0x1a88bc66": "slot()", "0xec97cff7": "addCertificationDocument(address,bytes32)", "0x0790e880": "setBlockappsAddr(address)", "0xe0ad411d": "assets(bytes)", "0x791b51f1": "Consulting(address,address)", "0xa26dbf26": "totalParticipants()", "0xb78b52df": "allocate(address,uint256)", "0xdb29fe12": "addShareholder(address)", "0x06459119": "testThrowsTransferNotTransferable()", "0xbadbaa3c": "setCallData()", "0x2c6b2c92": "checkProfitLossSinceInvestorChange()", "0x8aa6f1b1": "setUltimateOutcome(bytes32)", "0xecb98714": "random_damage(uint256)", "0x506e106c": "setToS(string)", "0xf0d474f9": "underdogCount()", "0x2212dbc3": "get_timestamp()", "0xd504ea1d": "getArray()", "0x9b29cb23": "getDailyPayment()", "0x9d3e069c": "StartDraw()", "0x12494160": "isHolder()", "0xbbd4e8c9": "numDeposits()", "0xfea2920e": "createNewDraw()", "0xff556ecb": "releaseUnicorn(uint256)", "0x3bed33ce": "withdrawEther(uint256)", "0xaa9669c1": "roll(uint256,bytes)", "0xa00aede9": "scheduleCall(uint256,address)", "0xc0819961": "Invest()", "0x1ed24195": "getPeriod()", "0x5babb758": "testSetUp()", "0xaaf9d13e": "buyTopDog(uint256,uint256)", "0x7c45ef6c": "stringToSig(string,string)", "0x7353f62b": "testGetApprovalDb()", "0xef7507c8": "testWinner(uint256)", "0x7ef95c6f": "extractAccountAllowanceRecordLength(address)", "0x66099706": "getChannelCred(address,uint256)", "0x5c242c59": "query1(uint256,string,string,uint256)", "0x299a7bcc": "setOwner(address,address)", "0xe1152343": "payout(uint256)", "0xd40a71fb": "step1()", "0xda9c6a46": "getReplyCount(uint256)", "0xffb7bfba": "watchProposal(uint256)", "0x2e1a7d4d": "withdraw(uint256)", "0x03da8902": "transfearDBOwner(address)", "0xc9bd2893": "fines()", "0xfdd3a879": "quick()", "0xda0774ad": "getCallFeeScalar(uint256,uint256)", "0x0f2c9329": "split(address,address)", "0xa3912ec8": "receiveEther()", "0xfd6f5430": "setContent(string,bytes32)", "0x99e0021f": "mergencyCall()", "0xb7aec6a5": "scheduleCall(address,bytes,uint256,uint256,uint8,uint256)", "0x23145ca0": "forceCheck()", "0xc7cf28fe": "canClaimTimeout()", "0x26db7648": "proposedVersion()", "0x60a60fd8": "testProxyCallWithValue()", "0x044d0b06": "oraclize_query(string,string[2])", "0x4f013184": "investInTheSystem()", "0x0c9fd581": "assertTrue(bool)", "0x09574810": "getOperationsNumber()", "0x6e2edf30": "ETCSurvey(address)", "0x3cc86b80": "GetMoney(uint256,address)", "0xf7b89a3e": "getTotalCosts()", "0xb18c6847": "manualUpdateBalances()", "0x8a65d874": "userStats(address)", "0xf80b3cfa": "checkBetLowhigh(uint8)", "0xc2def3b9": "getOrganizer()", "0x2dae9878": "BankOwner_EnableConnectBankAccountToNewOwnerAddress()", "0x1998aeef": "bid()", "0xc64e8bc0": "executeN(uint256)", "0xd4088e33": "setPrice(uint256,uint256,uint64)", "0xd263b7eb": "ownerkill()", "0xc478fc37": "EtherWheel(uint256,uint256,uint8)", "0x05b765ea": "getCertifierStatus(address)", "0x93c32e06": "changeFounder(address)", "0xf207564e": "register(uint256)", "0xae6c0b03": "canWithdrawBond(uint256)", "0x2b1071c9": "testTransferToNullAuthority()", "0xd9feeeb6": "fillMyOrder(uint256)", "0x9fb755d7": "setHotWallet(address)", "0x7f98444f": "randomEnd()", "0xf3fef3a3": "withdraw(address,uint256)", "0x48a0d754": "available()", "0x3af94817": "getPongvalRemote()", "0xec21a913": "setUint256(int256,uint256)", "0x6099af40": "setConfigBool(bytes,bool)", "0xf0cbe059": "proxyTransferFromWithReference(address,address,uint256,bytes32,string)", "0xf93589ce": "didWin(bytes)", "0x1eb5ea2e": "returnFunds()", "0xa6027d53": "IconomiTokenTest(uint256,string,uint8,string,uint256)", "0x8a323b38": "Contract(uint256,string,uint8,string)", "0xb0f07e44": "registerData()", "0xc9d27afe": "vote(uint256,bool)", "0x64265b1a": "share_transfered(string)", "0x78205f67": "testThrowTransferEnableNotTransferable()", "0x081780f4": "clearRecord(bytes32)", "0xdd137b5d": "toBase58(uint256,uint8)", "0x9483e91a": "withdraw(address,uint256,bytes,uint256)", "0xc6502da8": "basePayment()", "0xe17e1274": "testTransferToRejectAuthority()", "0x9af605cb": "__proxy(address,bytes,uint256)", "0x7a8df1b9": "getAffiliateInfo(address)", "0x46b305d6": "lockBetsForWithdraw()", "0x7d4cf602": "buildDSBalanceDB()", "0xce87f626": "replaceWizardRP(address)", "0x125b8f06": "isInNextGeneration()", "0xd0068f80": "getClient(uint256)", "0x7f0899f2": "AddTicket(bytes5[])", "0xb15dcc25": "query(address,bytes2,uint256)", "0x07a9574a": "changeLeaderMessage(string)", "0x16e55626": "getDogName(address)", "0xbc058968": "updateThingData(bytes32[],bytes32[],uint88)", "0x02aa274b": "setForward(bytes4,address)", "0x08f235ec": "getDefaultPayment()", "0x1dd4914b": "withdrawEtherOrThrow(uint256)", "0x7ca31724": "tokenId(address)", "0x0c4f65bd": "getOwnerAddress()", "0xeec3cb41": "placeBet(bool[],uint256,uint256)", "0x9054bdec": "toTimestamp(uint16,uint8,uint8,uint8,uint8,uint8)", "0x468f02d2": "getUnderlyingPrice()", "0x74331be7": "sete(address)", "0xb05e390a": "TokenEther(string,string)", "0x89cc5ea8": "bid(string,address,uint256)", "0xa8893a6e": "getNumOfSalesWithSameId(bytes16)", "0x3defb962": "heartbeat()", "0x15a03930": "TossMyCoin()", "0x1d8ae626": "Security(string,string)", "0xf1bca7a4": "doCall(uint256)", "0xae6215d8": "getBlockHeight(bytes)", "0x8124bb0f": "continueExecution()", "0xc1cbbca7": "contribute(uint256)", "0xa48566ba": "serverSeed(address,bytes)", "0xc0f5a9cb": "deleteThing(bytes32[])", "0x4136aa35": "isAlive()", "0x6fe665e9": "SlotMachine()", "0xfaff50a8": "rootNode()", "0xaf769eff": "Paper()", "0x77863b61": "CrossWhitehatWithdraw(uint256,address)", "0x2bed55b0": "buildDSEasyMultisig(uint256,uint256,uint256)", "0xd2ef7398": "challenge()", "0x96e4ee3d": "convert(uint256,uint256)", "0x2dff6941": "content(bytes32)", "0x4d536f9f": "validateNameExt(bytes)", "0xd4d5d32a": "collectFee()", "0x6620a935": "sendToOwner()", "0x5084da18": "fipsOwner(bytes20)", "0xe419f189": "multiAccessIsOwner(address)", "0xa9fbc614": "lookupTicketHolder(uint256)", "0x11f72496": "testT()", "0x7365870b": "bet(uint256)", "0x09861b81": "flooredSub(uint256,uint256)", "0xe28fed1e": "userRescues(address)", "0x28cc413a": "getProof(uint256,uint256,uint256)", "0x9a8f09bd": "newKing(address)", "0x5d068051": "sendFees(address)", "0x49cbe338": "tryRead(uint64)", "0x691bfc89": "goods(uint16,uint256)", "0xfc36e15b": "vote(string)", "0x48107843": "getNextCallSibling(address)", "0x6461fe39": "transferFromWithReference(address,address,uint256,string)", "0x804e11dc": "testThrowsDisownNotTransferable()", "0x76f30ca1": "toContentID(address,uint256,string,bytes)", "0xa77b2e37": "Coin()", "0x3f2f1596": "setupTreasury(address,uint256)", "0x3de9e4c6": "__transferFromWithReference(address,address,uint256,string)", "0x612e45a3": "newProposal(address,uint256,string,bytes,uint256,bool)", "0x4cdb48e4": "isValidNym(address)", "0x5afa5036": "isCertified(address)", "0x9a1b420b": "OraclizeAddrResolver()", "0xec5c9036": "Crowdsale(address,uint256,uint256)", "0x01095962": "oraclize_setCustomGasPrice(uint256)", "0xe7e2aa0e": "buyer_cancel()", "0x2da8f764": "submitVideo(string,string)", "0x3395dc70": "acceptTransfer(address,address,uint256)", "0xdf143fb7": "HackerGold(address)", "0x63334c58": "transferETC(address)", "0x6a5da6e5": "followCampaign(uint256)", "0x49fb2dc5": "add_to_association(uint256,uint256,uint256)", "0x953aa435": "GetPrice(uint8)", "0xc1257bad": "testPassingAProposal()", "0x3bc5de30": "getData()", "0x4abb9d39": "depletable()", "0x129484b6": "changeFeeRecipient(int256,int256,int256,int256,int256,int256)", "0x902e64e5": "Oath()", "0x8c4dd5cd": "Democracy()", "0xbea124a6": "query(bytes,bytes,int256)", "0x69347990": "ownerWithdrawl()", "0x606deecd": "requestData()", "0x6720ceb1": "sendPayment()", "0xb1050da5": "newProposal(address,uint256,string,bytes)", "0xfeaa29d8": "insertProfitHere()", "0x36f9f49c": "etherandomSeed()", "0xae815843": "query(uint256,string,string,uint256)", "0x752d349c": "depthCheck(int256,int256)", "0xa24835d1": "destroy(address,uint256)", "0x26070774": "Token(address)", "0x6e0d98fe": "setProbabilities(uint32[])", "0x0761a004": "step(uint256,bytes)", "0xad82dcac": "testBlockhashCorrectFee()", "0x0900f010": "upgrade(address)", "0xa288fb1f": "setConfigUint(int256,bytes,uint256)", "0xe88b8ac6": "confirmAndCheck(bytes)", "0xf1a00a53": "unregisterListening(address)", "0xb17acdcd": "collectFees(uint256)", "0xb5d0f16e": "getGasScalar(uint256,uint256)", "0xae999ece": "reserve(string)", "0x95ceb4b3": "winningProtocal()", "0x1a93fa4b": "reorganizeSubUsers()", "0x9243e088": "setEnforceRevisions(bytes20)", "0x342454c7": "isDigit(bytes1)", "0x8e2c6f4d": "initiateVerification(address,bytes,bytes)", "0xddb5b3ac": "SellTokens()", "0xd18dfdc9": "parrot(uint256)", "0xd3732642": "FastRealisticPyramid()", "0x37ab8f20": "notifyPlayer(uint256,uint256,uint256,uint256)", "0xfb6e155f": "availableVolume(address,uint256,address,uint256,uint256,uint256,address,uint8,bytes32,bytes32)", "0x50ab6f7f": "getMsgs()", "0x6b6a53fa": "testThrowsRestartNotOwner()", "0x4dc7cc55": "terminateAlt()", "0x8b9726c1": "multiAccessCallD(address,uint256,bytes,address)", "0x5a74dee5": "multiAccessRemoveOwnerD(address,address)", "0xfd339d18": "testAuthorityTryAuthUnauthorized()", "0xd3d6a975": "testThrowsTransferNotEnabled()", "0x8aa001fc": "getSecond(uint256)", "0x2ec2c246": "unregister(address)", "0xbbdb31cb": "challenge(uint256,address,bool)", "0x635cfda2": "Incrementer()", "0x704b6c02": "setAdmin(address)", "0xc1c723f4": "validateProposedMonarchName(bytes)", "0xadf5e565": "verify(bytes,address,uint256,uint8,bytes,bytes)", "0xbe7cddf8": "TwoD()", "0xc71b583b": "closeRequest()", "0x9cbf9e36": "createToken()", "0x69c4113d": "setNewBudget(uint256,uint256,uint256,uint256)", "0xd4649fde": "expire(uint256,uint8,bytes32,bytes32,bytes32)", "0xf9a7a2ef": "named(bytes)", "0xdbf45aa3": "EthBank()", "0xbb3ce7fe": "DepositHolder()", "0xfb5d5729": "getPongvalTransactional()", "0x2f0b15f6": "testGetUnset()", "0x62891b5d": "multiAccessChangeRequirement(uint256)", "0x538e0759": "refill()", "0x24c65f35": "updateRefundGas()", "0x62b24189": "DepositToBankAccountFromDifferentAddress(uint32)", "0xd81f53fd": "EtherId()", "0xcea943ee": "getSaleConfig()", "0x23647398": "testThrowRetractNotOwner()", "0xcdcd77c0": "baz(uint32,bool)", "0xa677fbd9": "example2Func()", "0xa02b9aac": "getPaymentDataByAddress(address)", "0x268eb055": "setDescription(uint64,bytes)", "0x09d2d0b9": "setServiceAccount(address,bool)", "0x5f70d9ac": "getBot(uint256)", "0x63f80de3": "issueCoin(address,uint256,uint256)", "0x8570153e": "publish(string,string,bytes,address[])", "0x7975c56e": "oraclize_query(uint256,string,string)", "0x7c3064f1": "refundStake()", "0xef4ffee2": "Honestgamble()", "0xfdc193a4": "test3Fails()", "0x0eb495c2": "pushCity()", "0x6a357465": "payHours(address,uint256)", "0x93f0bb51": "order(address,uint256,address,uint256,uint256,uint256,uint8,bytes32,bytes32)", "0x0a9254e4": "setUp()", "0xc490a266": "toUInt(bytes)", "0xf666323e": "UUIDProvider()", "0x857d4c07": "throwScraps(uint256)", "0x7fd8ee68": "computeNameHashExt(bytes)", "0x7bd703e8": "getBalanceInEth(address)", "0x68f65f02": "ChangeShownDenomination(bool,bool,bool,bool)", "0xc7f758a8": "getProposal(uint256)", "0x824dbc9a": "changeMembership(address,uint256,bool,string)", "0x2a228fc2": "processWithdrawals()", "0xe0457884": "betResolution(uint8,uint8,uint8,bool)", "0x550538f6": "getOneTimeCosts()", "0xf3e84cf3": "createNewRevision(bytes32,bytes)", "0x77fe38a4": "transferToICAPWithReference(bytes32,uint256,string)", "0xcc189d00": "Vault(address,uint256)", "0x9e281a98": "withdrawToken(address,uint256)", "0x7b12df39": "userProfits()", "0xa843c97f": "attack(uint256,uint256,uint256[])", "0x9da680f3": "adjustRegistrationFee(uint256)", "0x3ea3f6c5": "activateRegistrar()", "0xb36df681": "ExecutableBase()", "0x0f3a1412": "getArrlist(uint256,uint256)", "0x8b7f0ddd": "register(address,address,string,string,bytes32[],uint256,string)", "0xb5d3a379": "CanaryTestnet()", "0x9894221a": "SendCashForHardwareReturn()", "0xc2b12a73": "setBytes32(bytes32)", "0xff1b4341": "easyPropose(address,uint256,uint256)", "0x927ed13a": "newClient(uint256,address)", "0x9b9d0364": "_setFeeStructure(uint256,uint256,uint256)", "0x01518d76": "sendQuery(uint256)", "0x4112b7f1": "tryGetNameOwner(bytes)", "0xb759f954": "approve(uint256)", "0x810a882f": "setConfigBytes(bytes32,bytes32)", "0xea7a7184": "testGetBalanceDb()", "0xb0c8f9dc": "add(string)", "0xe59f611f": "InputLimit(uint256)", "0xdce293a7": "minLength(uint256)", "0xf509b627": "confirm(address,uint224,uint32,address)", "0xd48bfca7": "addToken(address)", "0x044f9ac8": "findThroneCalled(bytes)", "0x1d57bcf7": "ProofLibInterface()", "0x75830463": "checkBetLowhigh(uint8,address,bytes32,bytes32)", "0x2a45a39a": "Post(address)", "0x29cbdc86": "buyin(address,uint256)", "0x3cbfed74": "getBondBalance()", "0x80a23ddf": "mintBadge(int256,address,uint256)", "0x96b76c23": "stand(uint256)", "0xc392f5a0": "getAllPackageReleaseHashes(string)", "0x4847a79c": "_transfer(address,uint256)", "0x905e6e42": "JSON_Test()", "0x9f489e4e": "getDeposit(uint256,address)", "0x4f8e624e": "Greeter(string)", "0x96013c9c": "testLatestPkgGetter()", "0xe4fc6b6d": "distribute()", "0x423d4ef2": "createChannel()", "0x24d7806c": "isAdmin(address)", "0x691fb8ea": "jumpIn()", "0xd50f6bf0": "transferETH(address)", "0xd0e0813a": "promote(address)", "0x528eedcb": "sendSafe(address,address,uint256)", "0x00faf4dd": "getTokenDivisor()", "0x46a1d95f": "closeMarket(bytes)", "0x318a3fee": "relayTx(bytes,int256,int256[],int256,int256)", "0x49d55d9d": "receiveTransfer(uint256)", "0x4fa99dd0": "Matching_Ethers()", "0x99a5d747": "calculateFee(uint256)", "0x3c67c51e": "testLogs()", "0x12ab7242": "setupStackDepthLib(address)", "0xad9ec17e": "setGreyToken()", "0xc37e8cb2": "testExportAuthorized()", "0x43046844": "placeBet(uint8)", "0xc6e1c178": "TheLuckyOne(bytes)", "0x13d1aa2e": "f(uint256,uint256)", "0x64a4a5d7": "testBitsEqualSuccess()", "0xfb1669ca": "setBalance(uint256)", "0x40fdef80": "administration(uint256,string,uint256,uint256,address)", "0xcf7315c6": "retract(bytes20)", "0x76196c88": "setDnsrr(bytes32,bytes)", "0x08bf2d0d": "getOrderBook(uint256,uint256)", "0x021c309a": "solveBet(address,uint8,bool,uint8)", "0x4de162e4": "extractAccountLength()", "0x56fa47f0": "split(address)", "0xb3a0b1ef": "basicInfoGetter()", "0x26066ad5": "offer(uint256,bytes,uint256,bytes)", "0x99c724ef": "skipInLine(uint256,uint256)", "0x838445e8": "EtherAds(address,address,address)", "0xe06174e4": "settings()", "0xfac5bb92": "getPreRelease(bytes32)", "0x93c94acb": "calculateRewards(uint256[3][3])", "0xd7fa1007": "setHash(bytes32,bytes32)", "0x2a714078": "triggerAuth()", "0x4cd995da": "registerCompany(address,string)", "0xf6469342": "_setPackedBlockNumber(bytes32,uint256)", "0x8e7fd292": "trySetSubnodeOwner(bytes32,address)", "0x4f573cb2": "withdrawRevenue()", "0x924c28c1": "ContractInterface(address,address,address)", "0x4fc9c91a": "identityOf(bytes32)", "0x19901f1d": "TokenSale(uint256,uint256)", "0xaf8b7525": "CollectAndReduceFees(uint256)", "0x3ccb7dc9": "CrowdFund(uint256,uint256)", "0xaeeb96af": "Highlander()", "0xa126c5df": "GAS_TO_AUTHORIZE_EXECUTION()", "0x13c89a8f": "getAllowedTime(bytes32)", "0xf38b0600": "fireEventLog3()", "0xc7144269": "changeSettings_only_Dev(uint256,uint256,uint256,uint256,uint16,uint256,uint256,uint256,uint8,uint8)", "0xefc81a8c": "create()", "0x7429c086": "repeat()", "0x9c0a4bbc": "AlwaysFail()", "0xc3d23e10": "checkBet()", "0x28a45038": "testTryProxyCall()", "0xa668d7c9": "NiceGuyPonzi()", "0x06fe1fd7": "getPackageName(bytes32)", "0x29f27577": "InvestorList(uint256)", "0x57e25a79": "PullPaymentCapable()", "0x6d1669e1": "approveAndCall(address,address,uint256,bytes)", "0xa7e93e87": "retractLatestRevision(bytes20)", "0x9c7e8a03": "addParticipant(address,address,uint256)", "0xc6ab4514": "sendRobust(address,uint256,uint256)", "0xe8f6bc2e": "changeAccountLevelsAddr(address)", "0xb5d1990d": "numRecords()", "0x3e853128": "getGasForXau(address)", "0xa1add510": "hasRelation(bytes32,bytes32,address)", "0x31e3e2fe": "WithDraw()", "0x86723215": "createMarket(bytes,uint256,uint256,address)", "0xce845d1d": "currentBalance()", "0xc3a2c0c3": "scheduleCall()", "0xcf8eeb7e": "subBalance(address,uint256)", "0xaeb4f0d3": "RegisterTwo(address,address)", "0x3c716e08": "updateAuthority(address)", "0x9919b1cc": "getContentsByRanks(address,uint256,uint256,uint256)", "0x0f06670a": "didWin(bytes32)", "0x74e4435f": "getUserAddress(uint256,bytes32)", "0x4664b235": "bytes32_to_bytes(bytes,bytes,bytes)", "0x2ac9bf09": "bid(uint256,uint256,uint256)", "0xf11c4482": "approveFromProxy(address,address,uint256)", "0xfe992c98": "balanceOfAll(address)", "0x43e332c5": "Last_block_number_and_blockhash_used()", "0x0066753e": "removeCertifier(address)", "0xd299dac0": "blake2b(bytes,bytes,uint64)", "0x41395efa": "dgxBalance()", "0xac1b14ff": "proxyCall(uint256)", "0x7a6ce2e1": "getMsgSender()", "0x3855dcd6": "getContrarians_by_index(uint256)", "0xe6febc9b": "investorWithdraw(uint256)", "0xe6e91cfc": "voidFailedPayment(uint256)", "0x547eeac1": "acceptTransfer()", "0x9824425a": "takeOrder(uint256,uint256,uint256,uint256)", "0xdf25ee23": "getIndexId(address,bytes)", "0x0f3d7c3e": "release(string,uint32[3],string,string,string)", "0x15cff546": "isOperationBlocked()", "0x0b927666": "order(address,uint256,address,uint256,uint256,uint256)", "0x00ce2057": "triggerPayment()", "0x9a9c29f6": "settle(uint256,uint256)", "0x0f096163": "Chainy()", "0x2f5a5c5b": "timegame()", "0x900d85fa": "updatePreReleaseTree(bytes32)", "0x1cbd0519": "accountLevel(address)", "0x29a065bd": "getLOg(uint256)", "0xcec95aa1": "getReleaseHashForPackage(string,uint256)", "0x41524433": "sellKissBTCWithCallback(uint256,address,uint256)", "0x5e431709": "sealedBids(address,bytes32)", "0xf55b23c0": "externalLeave()", "0x31375242": "ownerSetTreasury(address)", "0x51b42b00": "deactivate()", "0x5af36e3e": "refund(uint256,uint256)", "0xc5096a69": "feeFor(address,address,uint256)", "0x059a500c": "makeDeposit(uint256)", "0x3c2e7d54": "priv_inMainChain__(int256,int256)", "0x9431f5f0": "withdrawFees(bytes)", "0x91b4a0e7": "Difficulty()", "0x268d50fe": "ownerSetHouseEdge(uint256)", "0x9644fcbd": "changeMembership(address,bool,string)", "0x66aa6f26": "payFee(bytes)", "0x353928d8": "helpRed()", "0x9c1193ea": "GreeterA(bytes)", "0xdd79e33e": "splitIdentifiers(string)", "0x4d268ddd": "payImporterBankForGoodsBought()", "0x656d2f63": "ManagedAccount(address)", "0x1216e771": "expiration(uint64)", "0x36f7cd70": "setPricePerStake(uint256)", "0x7842a3a4": "payReward()", "0x0ae50a39": "GetOwner()", "0xc81caae7": "acceptMember(address,string,string)", "0xe50dce71": "testControllerApproveSetsAllowance()", "0x4b64e492": "execute(address)", "0xd9e947f3": "kickOutMember(address)", "0x35cc59a9": "createSchema(bytes)", "0x2530c905": "rand(uint256)", "0x4894e37f": "__callback(bytes,string,bytes)", "0x70480275": "addAdmin(address)", "0x969cb7c3": "getPublisher(uint256)", "0x4ed4831a": "all(bool[7])", "0x2ef3accc": "getPrice(string,uint256)", "0x67854643": "getGenerationMemberLength(uint256)", "0xe6690fb1": "nextAuction(uint256)", "0x5829d310": "entries(int256)", "0x7fe1dc7e": "getToken(bytes)", "0xe7329e71": "scheduleCall(bytes,bytes,uint256,uint256,uint8,uint256)", "0x41c12a70": "voteNo()", "0x6a28db13": "getQrLength()", "0xdd93890b": "setMeta(uint256,bytes32,bytes32)", "0xa48bdb7c": "results()", "0x9d888e86": "currentVersion()", "0xff81fb91": "unhint(int256,bytes32)", "0x9ec32d45": "challengeWinningOutcome(bytes,uint16)", "0xa0a2f629": "setReferralId(uint256,address)", "0x76577eae": "distributeEarnings()", "0x3e5cee05": "issueIOU(string,uint256,address)", "0xf3c7d275": "prenup(string,string,string,string,string,address,address)", "0x7154ae61": "CheckNumbers(uint8[5])", "0x05de4f07": "getContentParent(uint256)", "0xb81e43fc": "getEventName()", "0xa7eeea37": "NewContributor(uint256)", "0xe816a515": "takeFlight()", "0x05b2b03a": "CertificationCentre(address)", "0x74d4ab27": "fipsRegister()", "0x65fa2f7f": "getLastPrice(uint256)", "0xcc8b34ab": "CrowdCoin()", "0xe2b178a0": "getAuthority()", "0x5fb64fd6": "checkMembership(address)", "0x7948f523": "setAmbiAddress(address,bytes32)", "0xebb71194": "withdrawFees(bytes32)", "0x6545bed3": "Dice(uint256,uint256,uint256,uint256,uint256,uint256,uint256)", "0x7065cb48": "addOwner(address)", "0x913f424c": "_ecMul(uint256,uint256,uint256,uint256)", "0xdbecc372": "Example(uint256)", "0x9f7f760c": "SimpleDice()", "0xca94692d": "abiSignature()", "0x61ba3377": "WatchLastTime()", "0x20e647e1": "checkBetColor(uint8,address,bytes32,bytes32)", "0x0a3b0a4f": "add(address)", "0xc51cf179": "calcBaseFeeForShares(uint256)", "0x8baced64": "isInPool(address)", "0x4dc415de": "reject()", "0x1555e337": "ConferenceCertificate()", "0x9555a942": "withdrawFrom(address,address,uint256)", "0xe1efda6d": "airaSend(address,address,uint256)", "0x8bfc2f33": "delegateDAOTokens(uint256)", "0xb964608d": "get_return_by_level(uint256)", "0x0c1fad51": "setSeedSourceA(address)", "0x98688a95": "Ai()", "0xd930a90b": "testFailMoveBalanceDueToInsufficientFunds()", "0x337b5988": "testSimpleNameRegister()", "0xf06d335e": "_recoverAccount(address,address)", "0x025bbbe5": "newSale(bytes16,uint256,uint256)", "0x984413b8": "_eraseNode(bytes32)", "0x5ea187c9": "BuildByteArray(bytes)", "0xc2a95cc9": "updateTrustSettings(address,uint256)", "0xde0ff7c5": "getEther()", "0x4ac7becf": "SimpleSign()", "0x252786e4": "WatchBlockSizeInEther()", "0xf2016a4f": "updateMinEthPerNotification(uint256)", "0xd743ca38": "newWinner(uint256,address,uint256,uint256,uint256)", "0x9eab5253": "getMembers()", "0x51d38d5f": "addDeveloper(address,string)", "0x930ed251": "getSavedVar()", "0x715ef4ff": "resendFailedPayment(uint256)", "0xb1418cf4": "payHouse()", "0xe1569f6b": "testThrowsSetNotRetractableNotOwner()", "0x4ae9af61": "getBotStats(uint256,uint256)", "0xbf8ecf9c": "authProposals()", "0xc00ca383": "getByOwner(address,uint256)", "0xc8e7ca2e": "getMsgData()", "0x711953ef": "setGameAddress(address)", "0x63a8dac2": "changeSettings(uint256,uint256,uint256,uint8,uint256,uint256,uint8,uint8)", "0x72c87075": "testBlockHeaderFetch()", "0x4c7a2254": "checkMyWithdraw()", "0xab91c7b0": "queueLength()", "0x25209260": "PrepareRoll(uint256)", "0x58150c8b": "GameRegistry()", "0x75608264": "get_hash(uint8,bytes32)", "0x6510ef4d": "oraclize_query(uint256,string,string[5])", "0xd57a12f5": "testCheckSigs()", "0x3f415772": "releaseExists(bytes32)", "0xda25c0cd": "ThisExternalAssembly()", "0xf239e528": "sendOneEtherHome()", "0xc4321adb": "investInTheSystem(uint256)", "0x4fab2ca4": "testGetFrontend()", "0x05261aea": "finalize(uint256)", "0x576eac66": "setFundingGoal(uint256)", "0xe75528cc": "buyBuilding(uint256,uint256)", "0x6ed43eb0": "getInvestorList(uint256)", "0xb38415f3": "getConfigBytes(bytes)", "0x771ad635": "getContentCred(address,uint256)", "0x93c166ec": "computeEndowment(uint256,uint256,uint256,uint256)", "0xac35caee": "transferWithReference(address,uint256,string)", "0xc6803622": "wasCalled()", "0x8cfd8901": "_incBlock()", "0xfcf0f55b": "eventOracles(bytes32,uint256)", "0x505ff574": "register(address,uint256,bool)", "0xf824384a": "addInvestorAtID(uint256)", "0x6b9f96ea": "flush()", "0xc3d0a564": "getAccountBalance(bytes)", "0x30fd300f": "registerBytes32(address,bytes32)", "0xc3169ef2": "respond(uint256,uint256[4])", "0xcf1cd249": "secureSend(address)", "0x62c335c1": "checkCallback(address,uint256,bytes,bytes)", "0xb599afc8": "totalBetCount()", "0x69433e12": "setExchange(uint256)", "0x899942b8": "Devcon2Token()", "0x4c2d71b3": "setConfigAddress(bytes32,address)", "0xb974b0a3": "allData()", "0x27e8c2d8": "burnUnicornShares()", "0xf639365d": "testSetGet()", "0x2f5d3916": "testControllerApproveTriggersEvent()", "0x938b5f32": "origin()", "0xd60dcb5d": "Switch()", "0xde629235": "getCertificationDocumentAtIndex(address,uint256)", "0x329ce29e": "buyTile(uint256)", "0x59e2d30e": "testThrowBlobStoreNotRegistered()", "0xa005b87b": "NullMapTest()", "0xc13afa91": "object_locations(uint256)", "0x4848b1a5": "setData(uint256,uint256)", "0x80ede329": "getDocumentDetails(uint256)", "0x35d13969": "SendAllMoney()", "0x8040cac4": "testOverflow()", "0x9507d39a": "get(uint256)", "0xc040e6b8": "stage()", "0x18178358": "poke()", "0xfd782de5": "Proxy()", "0xfd68a422": "returnmoneycreator(uint8,uint128)", "0x86a50535": "voteFor(uint256)", "0x44602a7d": "testFallbackReturn()", "0xa230c524": "isMember(address)", "0x3ffbd47f": "register(string,string)", "0x8cecf66e": "_inverse(uint256)", "0x51017702": "isOutcomeSet(bytes32)", "0xd408746a": "GetContractAddr()", "0x20130753": "testThrowSetNotRetractableNotOwner()", "0xa0e2abf7": "getFirstActiveGamble()", "0x7c582304": "updateInvestmentTotal(address,uint256)", "0x95d89b41": "symbol()", "0x1768b436": "ETCSurvey()", "0x6d4ce63c": "get()", "0xc41a360a": "getOwner(uint256)", "0x49942ccb": "scheduleCall(bytes,bytes,uint256,uint256)", "0x6b64c769": "startAuction()", "0x084d72f4": "getWinningOutcome(uint256)", "0xd379be23": "claimer()", "0x41fa4876": "multiBlockRandomGen(uint256,uint256)", "0x5bc7e259": "updateRelease(uint32,uint32,uint32,bytes,bool)", "0x47f3d794": "configure(uint256,uint8,uint256,uint256,uint256,uint256)", "0xe2bbb158": "deposit(uint256,uint256)", "0x953a7fab": "testMoveBalance()", "0xeacc5b3b": "safeSend(address,uint256,uint256)", "0x96f0aa8f": "findNextSecond(uint256,bytes)", "0xc8690233": "pubkey(bytes32)", "0x459f93f7": "getBuyers(uint256,address)", "0xf714de9c": "MultiAccess()", "0xf4a81d08": "getKudosGiven(address)", "0x5aa94a68": "computeResultVoteExtraInvestFeesRate()", "0xdb2a0cb7": "HumanStandardTokenFactory()", "0xdf3a6b10": "testMemberAddedEvent()", "0xce8d054e": "_setupNoCallback()", "0x8ea822d8": "createThings(bytes32[],uint16[],bytes32[],uint16[],uint88)", "0x24fb563f": "PlayerTickets(address,uint256,uint256)", "0x8c0e156d": "scheduleCall(bytes4,uint256,uint256)", "0xef04fdb7": "buyShares(bytes,uint8,uint256,uint256)", "0xa0afd731": "dividendBalance(address)", "0xc3c95c7b": "getMarket(bytes32)", "0x94ed9b77": "append(address,address)", "0xc87b36ed": "disableBetting()", "0x566735d8": "PreVNK(uint256,string,string,uint8)", "0x400aae08": "isInCurrentGeneration(address)", "0x44dd4b5e": "scheduleTransaction(address,uint256,bytes)", "0x48c54b9d": "claimTokens()", "0xe8930efd": "Investors(address)", "0xa6f2ae3a": "buy()", "0x12819817": "setXauForGasCurrator(address)", "0x056e1059": "oraclize_query(uint256,string,string,uint256)", "0x7824407f": "tokenSupply()", "0x7f0c949c": "setJurisdication(string)", "0x2e817963": "set_sdl(address)", "0xaee84f6b": "setTime(address,uint256)", "0x3c0dde1c": "_addPools(address,address)", "0xf8bd526e": "setCoinageContract(address)", "0x04b07a5e": "removeUpdater(address)", "0x11149ada": "getProof(uint256)", "0x4306cc3f": "queryEarnings(address)", "0x55241077": "setValue(uint256)", "0x492b67ea": "Etherdoc()", "0xadf59f99": "query(uint256,string,string)", "0x951b01c5": "setCertifierDb(address)", "0x8ae986cf": "registrantApprove(address)", "0xfa68b4ce": "lookupISO3116_1_alpha_3(bytes)", "0x7fdc8290": "isUnderscore(bytes1)", "0x89495172": "convictFinal(uint256,uint256)", "0x93e02d13": "FallenLeaders()", "0x3e476053": "moveFunds(address,uint256)", "0x8894dd2b": "addEther()", "0x8f03850b": "numContributors()", "0xbfc3cd2f": "testFailChargeMoreThanApproved()", "0x1d82e9c7": "EXTRA_GAS()", "0x278ecde1": "refund(uint256)", "0x0f825673": "deleteCoupon(string)", "0xa324ad24": "getMonth(uint256)", "0xd628e0a6": "WatchBalance()", "0xb238ad0e": "getDaysInMonth(uint8,uint16)", "0xd6febde8": "buy(uint256,uint256)", "0x370ec1c5": "_fillOrder(address,uint256)", "0x4c33fe94": "cancel(address)", "0xcdd13701": "getEventHashes(uint256[256])", "0xe1bc3003": "reveal(bytes,string)", "0xa2e62045": "update()", "0x75f45878": "scheduleCall(bytes,bytes,uint256)", "0xd2756e11": "finalizeNumber(uint256)", "0x48519189": "MonedaAlcala(string,string)", "0x009b9369": "getVoteNumber(uint256)", "0xdaa283c8": "__callback(bytes,string)", "0xfcce2622": "challengeAnswer(uint256,bytes)", "0xac18de43": "removeManager(address)", "0x16d9356f": "oraclize_query(string,string[4])", "0xd1734eac": "isInNextGeneration(address)", "0x524fa7b9": "whitelistAdd(address)", "0xa5eb7a4e": "operated()", "0xb0aab296": "getNextNode(bytes)", "0x1982ed58": "ChangeReuseCashInHarware(bool,uint16,uint16)", "0xdf811d7d": "numberOfPlayersInCurrentRound()", "0xca7dc5b1": "getNumberOfTweets()", "0x488b3538": "shares(address,bytes32,int256)", "0xebd83378": "get_blocks_for(uint256)", "0x399fdb86": "testFailNormalWhitelistReset()", "0xca0c1e62": "computeMerkle(int256,int256,int256[],int256,int256,int256[])", "0x8963dab4": "getNodeId(bytes,bytes)", "0x7d94792a": "seed()", "0xbcf175c8": "oraclize_cbAddress()", "0x38eee93e": "scheduleCall(address,bytes,bytes,uint16,uint8,uint256[5])", "0xa08d3f83": "Etheropt(uint256,string,uint256,uint256,bytes32,address,int256[])", "0xae47a290": "changeMaxBet(uint256)", "0xd12c1e28": "badgesOf(address)", "0x001f8d11": "removePackage(bytes32,string)", "0x54fd4d50": "version()", "0x89abeb19": "ProcessGameExt(uint256)", "0x3dd7c1b9": "newProduct(string,string,uint256,uint256)", "0xa396541e": "getPongvalTxRetrievalAttempted()", "0xcc8af0fe": "bytesToUInt(bytes,bytes)", "0x983b94fb": "finalizeAuction(bytes32)", "0x3df91162": "getUpdatable(bytes20)", "0x045236b4": "getChainyData(string)", "0x9c172f87": "EthVentures4()", "0x996a4be3": "uintToBytes(uint256,uint256)", "0x775a8f5e": "toBytes(uint256)", "0xb6db75a0": "isAdmin()", "0x0b6fcdb0": "getEnforceRevisions(bytes32)", "0x29d6f899": "BetOnBlue()", "0xe6cbcba9": "PlusOnePonzi()", "0xc9030ea0": "addMember(address,bool)", "0x8f283970": "changeAdmin(address)", "0x670c884e": "setup(address,uint256,uint256,uint256,address)", "0x808ab1d6": "getCertificationDbCount()", "0x018f5472": "isAUser(address)", "0x59c87d70": "request(bytes32)", "0x407cfe5e": "get_all_players()", "0x33f472b9": "MPO()", "0x662dbe96": "getNodeHeight(bytes)", "0x60b1e173": "getProof(uint256,address,address)", "0xf25eb5c1": "removeReverse()", "0x1d065dde": "_transferWithReward(address,address,uint256)", "0x65343fcb": "TrustEth()", "0xaa237e21": "set(bool,uint256)", "0x60e519c0": "computeMarginAmount()", "0xd9597016": "multisetCustomGasPrice(uint256[],address[])", "0x4f10acc1": "updateGoldFeeData(uint256)", "0x1e9ea66a": "balanceEther10000000(uint256)", "0xffe34512": "getNumChannels(address)", "0x71dd8862": "IndexOf()", "0xdd9dd688": "calcStopPrice()", "0x934354e7": "finishSpin()", "0x26881518": "setupFee(address)", "0x5eb3f639": "assertTrue(bool,bytes)", "0xe9540395": "getRewardDivisor()", "0x8e4afa51": "checkTransferToICAP(bytes32,uint256)", "0xb5b33eda": "scheduleCall(address,uint256)", "0x3d6a32bd": "createTradeContract(address,uint256,uint256,uint256,bool,bool)", "0x5fd9dff6": "allowance(address,address,bytes)", "0x0d244d68": "setNotRetractable(bytes32)", "0xe63697c8": "withdraw(uint256,address,uint256)", "0x3e5087cc": "testBasicThing()", "0xee77fe86": "scheduleCall(address,bytes4,bytes,uint256,uint256,uint8)", "0xb1cc4348": "placeWager()", "0xb95594e5": "lineOfPlayers(uint256)", "0xa9cc4718": "fail()", "0x54385526": "setStatus(uint8,uint8,string)", "0xb45c48dc": "Security_AddPasswordSha3HashToBankAccount(bytes)", "0xace51abc": "helperVerifyHash__(uint256,int256,int256[],int256,uint256,int256,int256[],int256)", "0x1f5d0b4c": "address(address,address,uint256)", "0x7acbfb65": "setOwner(uint256,uint256)", "0x3462f32d": "execWithGasLimit(bytes32,bytes32,uint256,uint256)", "0xac04f5a7": "append(address)", "0x2fcb6628": "_stringGas(string,string)", "0xe977992d": "Doubler()", "0xc57a050e": "fairandeasy()", "0x412664ae": "sendToken(address,uint256)", "0x0afa9fb9": "contains(int256,address)", "0xb69ef8a8": "balance()", "0x264c8e9a": "whatWasTheVal()", "0x255016c8": "checkIfExploded()", "0xd716222c": "is_owner(uint256,address)", "0xc398f030": "expire(uint256,uint8,bytes,bytes,bytes)", "0xb7d454a4": "setNotTransferable(bytes32)", "0x4789aaef": "EthereumDice()", "0xc0171112": "timestamp(uint64)", "0x4f60f334": "multiAccessAddOwner(address)", "0x80aed05f": "LooneyDice()", "0x55ba343f": "getMarket(bytes)", "0x943b0747": "RewardOffer(address,address,bytes,uint256,uint256,uint128,uint256)", "0xa27c672a": "owner_reveal_and_commit(uint8,bytes32,bytes32)", "0x8f731077": "extractAllowanceRecordLength(address)", "0xc3d345c4": "getHangoutAddress()", "0xa8978434": "softResolveAnswer(uint256)", "0x7cef6047": "getNavHistory(uint256)", "0xfae14192": "changeFeePercentage(uint256)", "0x2ddbc04a": "play2(address,uint256)", "0x3fb27b85": "seal()", "0xe8038e25": "TokenSale(uint256,uint256,address)", "0x8d92fdf3": "withdrawAsset(uint256)", "0x8579cbde": "getPrice(string,uint256,address)", "0x0d61b519": "executeProposal(uint256)", "0x63a599a4": "emergencyStop()", "0x661e3605": "ConstructorContract(uint256)", "0xfd7c460d": "ciberLottery()", "0x1f83f440": "getPaymentByAddress(address)", "0xdcf73856": "generateGroups()", "0x3c6e03d7": "thewhalegame()", "0x271cd760": "getPackageDb()", "0x53fefd7d": "changeMaxDeposit(uint256)", "0xae169a50": "claimReward(uint256)", "0x6da84ec0": "calcMarketFee(bytes32,uint256)", "0xb16562fe": "fipsRegister(address,bytes)", "0x041fe13d": "onEtherandomSeed(bytes32,bytes32)", "0x4a617faa": "shaBid(bytes32,uint256,bytes32)", "0x052b2aa7": "getRegistrants()", "0x0ff0a4df": "reFund()", "0xe56b9dce": "GetPrize(uint256)", "0x8eec99c8": "setNewAdmin(address)", "0xffcce369": "changeIPFSHash(string)", "0x40fdf515": "issuetender(address,uint256,uint256)", "0xef4bdfdd": "Set_your_game_number_between_1_15(string)", "0xa991cb0e": "respond(uint256)", "0x617fba04": "getRecord(address)", "0x475a9fa9": "issueTokens(address,uint256)", "0xd30fbd0d": "safeSubtract(uint256,uint256)", "0xe54d4051": "receiveInteger(bytes,uint256,uint16)", "0x8023ffbd": "getOverallSize()", "0x8390b02a": "rfindPtr(uint256,uint256,uint256,uint256)", "0x11e99c22": "arrival()", "0x10c1952f": "setLocked()", "0x039a21b8": "tryExecute(address,bytes,uint256)", "0x201dcd7a": "newChallenge(uint256,uint256)", "0x5aebfd14": "createFile(bytes)", "0xa6b1caa3": "gasScalar(uint256)", "0x200538c6": "DTE()", "0xd1738b72": "wroomWroom()", "0x22f607f6": "Escrow()", "0x7e81b6aa": "KingdomFactory()", "0x901d7775": "voteOutMasterKey(address)", "0xd6af9411": "Rouleth()", "0x7b0383b2": "initializeDispute(uint256)", "0x70c9edb7": "BTCRelayTools(address)", "0xe9c31315": "checkBetParity(uint8,address,bytes32,bytes32)", "0xee82ac5e": "getBlockHash(uint256)", "0x727089f1": "extractAllowanceLength()", "0x8bbb5af7": "test1Fails()", "0x47872b42": "unsealBid(bytes32,uint256,bytes32)", "0x46b04e53": "PlayerInfoPerZone(uint256,uint256)", "0x752bacce": "getExecPrice()", "0x89d8ca67": "drawPot(bytes32,bytes32)", "0xc23697a8": "check(address)", "0x0af658ca": "personUpdateActivity(uint256,bool)", "0x24d4e90a": "ln(uint256)", "0x09d33f1d": "addRequest(address,uint256)", "0xc913b552": "getVersions(bytes)", "0xbb3b8dca": "getCertificateHash(bytes)", "0x3809c0bf": "doInfinite()", "0x853552d7": "_slotAddNew(address)", "0xccf1ab9b": "usurpation()", "0xe7dafdb6": "transfer_token(address,address,uint256)", "0x0c77a697": "claimFounders()", "0xda82a035": "sweepCommission()"} \ No newline at end of file diff --git a/cmd/clef/README.md b/cmd/clef/README.md new file mode 100644 index 0000000000..027c22c98f --- /dev/null +++ b/cmd/clef/README.md @@ -0,0 +1,877 @@ +Clef +---- +Clef can be used to sign transactions and data and is meant as a replacement for geth's account management. +This allows DApps not to depend on geth's account management. When a DApp wants to sign data it can send the data to +the signer, the signer will then provide the user with context and asks the user for permission to sign the data. If +the users grants the signing request the signer 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 a remote node because a local Ethereum node is not available, not +synchronised with the chain or a particular Ethereum node that has no built-in (or limited) account management. + +Clef can run as a daemon on the same machine, or off a usb-stick like [usb armory](https://inversepath.com/usbarmory), +or a separate VM in a [QubesOS](https://www.qubes-os.org/) type os setup. + +Check out + +* the [tutorial](tutorial.md) for some concrete examples on how the signer works. +* the [setup docs](docs/setup.md) for some information on how to configure it to work on QubesOS or USBArmory. + + +## Command line flags +Clef accepts the following command line options: +``` +COMMANDS: + init Initialize the signer, generate secret storage + attest Attest that a js-file is to be used + addpw Store a credential for a keystore file + help Shows a list of commands or help for one command + +GLOBAL OPTIONS: + --loglevel value log level to emit to the screen (default: 4) + --keystore value Directory for the keystore (default: "$HOME/.ethereum/keystore") + --configdir value Directory for clef configuration (default: "$HOME/.clef") + --networkid value Network identifier (integer, 1=Frontier, 2=Morden (disused), 3=Ropsten, 4=Rinkeby) (default: 1) + --lightkdf Reduce key-derivation RAM & CPU usage at some expense of KDF strength + --nousb Disables monitoring for and managing USB hardware wallets + --rpcaddr value HTTP-RPC server listening interface (default: "localhost") + --rpcport value HTTP-RPC server listening port (default: 8550) + --signersecret value A file containing the password used to encrypt signer credentials, e.g. keystore credentials and ruleset hash + --4bytedb value File containing 4byte-identifiers (default: "./4byte.json") + --4bytedb-custom value File used for writing new 4byte-identifiers submitted via API (default: "./4byte-custom.json") + --auditlog value File used to emit audit logs. Set to "" to disable (default: "audit.log") + --rules value Enable rule-engine (default: "rules.json") + --stdio-ui Use STDIN/STDOUT as a channel for an external UI. This means that an STDIN/STDOUT is used for RPC-communication with a e.g. a graphical user interface, and can be used when the signer is started by an external process. + --stdio-ui-test Mechanism to test interface between signer and UI. Requires 'stdio-ui'. + --help, -h show help + --version, -v print the version + +``` + + +Example: +``` +signer -keystore /my/keystore -chainid 4 +``` + + +## Security model + +The security model of the signer is as follows: + +* One critical component (the signer binary / daemon) is responsible for handling cryptographic operations: signing, private keys, encryption/decryption of keystore files. +* The signer binary has a well-defined 'external' API. +* The 'external' API is considered UNTRUSTED. +* The signer binary also communicates with whatever process that invoked the binary, via stdin/stdout. + * This channel is considered 'trusted'. Over this channel, approvals and passwords are communicated. + +The general flow for signing a transaction using e.g. geth is as follows: +![image](sign_flow.png) + +In this case, `geth` would be started with `--externalsigner=http://localhost:8550` and would relay requests to `eth.sendTransaction`. + +## TODOs + +Some snags and todos + +* [ ] The signer should take a startup param "--no-change", for UIs that do not contain the capability + to perform changes to things, only approve/deny. Such a UI should be able to start the signer in + a more secure mode by telling it that it only wants approve/deny capabilities. + +* [x] It would be nice if the signer could collect new 4byte-id:s/method selectors, and have a +secondary database for those (`4byte_custom.json`). Users could then (optionally) submit their collections for +inclusion upstream. + +* It should be possible to configure the signer to check if an account is indeed known to it, before +passing on to the UI. The reason it currently does not, is that it would make it possible to enumerate +accounts if it immediately returned "unknown account". +* [x] It should be possible to configure the signer to auto-allow listing (certain) accounts, instead of asking every time. +* [x] Done Upon startup, the signer should spit out some info to the caller (particularly important when executed in `stdio-ui`-mode), +invoking methods with the following info: + * [x] Version info about the signer + * [x] Address of API (http/ipc) + * [ ] List of known accounts +* [ ] Have a default timeout on signing operations, so that if the user has not answered withing e.g. 60 seconds, the request is rejected. +* [ ] `account_signRawTransaction` +* [ ] `account_bulkSignTransactions([] transactions)` should + * only exist if enabled via config/flag + * only allow non-data-sending transactions + * all txs must use the same `from`-account + * let the user confirm, showing + * the total amount + * the number of unique recipients + +* Geth todos + - The signer should pass the `Origin` header as call-info to the UI. As of right now, the way that info about the request is +put together is a bit of a hack into the http server. This could probably be greatly improved + - Relay: Geth should be started in `geth --external_signer localhost:8550`. + - Currently, the Geth APIs use `common.Address` in the arguments to transaction submission (e.g `to` field). This + type is 20 `bytes`, and is incapable of carrying checksum information. The signer uses `common.MixedcaseAddress`, which + retains the original input. + - The Geth api should switch to use the same type, and relay `to`-account verbatim to the external api. + +* [x] Storage + * [x] An encrypted key-value storage should be implemented + * See [rules.md](rules.md) for more info about this. + +* Another potential thing to introduce is pairing. + * To prevent spurious requests which users just accept, implement a way to "pair" the caller with the signer (external API). + * Thus geth/mist/cpp would cryptographically handshake and afterwards the caller would be allowed to make signing requests. + * This feature would make the addition of rules less dangerous. + +* Wallets / accounts. Add API methods for wallets. + +## Communication + +### External API + +The signer listens to HTTP requests on `rpcaddr`:`rpcport`, with the same JSONRPC standard as Geth. The messages are +expected to be JSON [jsonrpc 2.0 standard](http://www.jsonrpc.org/specification). + +Some of these call can require user interaction. Clients must be aware that responses +may be delayed significanlty or may never be received if a users decides to ignore the confirmation request. + +The External API is **untrusted** : it does not accept credentials over this api, nor does it expect +that requests have any authority. + +### UI API + +The signer 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 the +`stdin`/`stdout` for the UI-api. + +An example (insecure) proof-of-concept of has been implemented in `pythonsigner.py`. + +The model is as follows: + +* The user starts the UI app (`pythonsigner.py`). +* The UI app starts the `signer` with `--stdio-ui`, and listens to the +process output for confirmation-requests. +* The `signer` opens the external http api. +* When the `signer` receives requests, it sends a `jsonrpc` request via `stdout`. +* The UI app prompts the user accordingly, and responds to the `signer` +* The `signer` signs (or not), and responds to the original request. + +## External API + +See the [external api changelog](extapi_changelog.md) for information about changes to this API. + +### Encoding +- number: positive integers that are hex encoded +- data: hex encoded data +- string: ASCII string + +All hex encoded values must be prefixed with `0x`. + +## Methods + +### account_new + +#### Create new password protected account + +The signer will generate a new private key, encrypts it according to [web3 keystore spec](https://github.com/ethereum/wiki/wiki/Web3-Secret-Storage-Definition) and stores it in the keystore directory. +The client is responsible for creating a backup of the keystore. If the keystore is lost there is no method of retrieving lost accounts. + +#### Arguments + +None + +#### Result + - address [string]: account address that is derived from the generated key + - url [string]: location of the keyfile + +#### Sample call +```json +{ + "id": 0, + "jsonrpc": "2.0", + "method": "account_new", + "params": [] +} + +{ + "id": 0, + "jsonrpc": "2.0", + "result": { + "address": "0xbea9183f8f4f03d427f6bcea17388bdff1cab133", + "url": "keystore:///my/keystore/UTC--2017-08-24T08-40-15.419655028Z--bea9183f8f4f03d427f6bcea17388bdff1cab133" + } +} +``` + +### account_list + +#### List available accounts + List all accounts that this signer currently manages + +#### Arguments + +None + +#### Result + - array with account records: + - account.address [string]: account address that is derived from the generated key + - account.type [string]: type of the + - account.url [string]: location of the account + +#### Sample call +```json +{ + "id": 1, + "jsonrpc": "2.0", + "method": "account_list" +} + +{ + "id": 1, + "jsonrpc": "2.0", + "result": [ + { + "address": "0xafb2f771f58513609765698f65d3f2f0224a956f", + "type": "account", + "url": "keystore:///tmp/keystore/UTC--2017-08-24T07-26-47.162109726Z--afb2f771f58513609765698f65d3f2f0224a956f" + }, + { + "address": "0xbea9183f8f4f03d427f6bcea17388bdff1cab133", + "type": "account", + "url": "keystore:///tmp/keystore/UTC--2017-08-24T08-40-15.419655028Z--bea9183f8f4f03d427f6bcea17388bdff1cab133" + } + ] +} +``` + +### account_signTransaction + +#### Sign transactions + Signs a transactions and responds with the signed transaction in RLP encoded form. + +#### Arguments + 2. transaction object: + - `from` [address]: account to send the transaction from + - `to` [address]: receiver account. If omitted or `0x`, will cause contract creation. + - `gas` [number]: maximum amount of gas to burn + - `gasPrice` [number]: gas price + - `value` [number:optional]: amount of Wei to send with the transaction + - `data` [data:optional]: input data + - `nonce` [number]: account nonce + 3. method signature [string:optional] + - The method signature, if present, is to aid decoding the calldata. Should consist of `methodname(paramtype,...)`, e.g. `transfer(uint256,address)`. The signer may use this data to parse the supplied calldata, and show the user. The data, however, is considered totally untrusted, and reliability is not expected. + + +#### Result + - signed transaction in RLP encoded form [data] + +#### Sample call +```json +{ + "id": 2, + "jsonrpc": "2.0", + "method": "account_signTransaction", + "params": [ + { + "from": "0x1923f626bb8dc025849e00f99c25fe2b2f7fb0db", + "gas": "0x55555", + "gasPrice": "0x1234", + "input": "0xabcd", + "nonce": "0x0", + "to": "0x07a565b7ed7d7a678680a4c162885bedbb695fe0", + "value": "0x1234" + } + ] +} +``` +Response + +```json +{ + "jsonrpc": "2.0", + "id": 67, + "error": { + "code": -32000, + "message": "Request denied" + } +} +``` +#### Sample call with ABI-data + + +```json +{ + "jsonrpc": "2.0", + "method": "account_signTransaction", + "params": [ + { + "from": "0x694267f14675d7e1b9494fd8d72fefe1755710fa", + "gas": "0x333", + "gasPrice": "0x1", + "nonce": "0x0", + "to": "0x07a565b7ed7d7a678680a4c162885bedbb695fe0", + "value": "0x0", + "data": "0x4401a6e40000000000000000000000000000000000000000000000000000000000000012" + }, + "safeSend(address)" + ], + "id": 67 +} +``` +Response + +```json +{ + "jsonrpc": "2.0", + "id": 67, + "result": { + "raw": "0xf88380018203339407a565b7ed7d7a678680a4c162885bedbb695fe080a44401a6e4000000000000000000000000000000000000000000000000000000000000001226a0223a7c9bcf5531c99be5ea7082183816eb20cfe0bbc322e97cc5c7f71ab8b20ea02aadee6b34b45bb15bc42d9c09de4a6754e7000908da72d48cc7704971491663", + "tx": { + "nonce": "0x0", + "gasPrice": "0x1", + "gas": "0x333", + "to": "0x07a565b7ed7d7a678680a4c162885bedbb695fe0", + "value": "0x0", + "input": "0x4401a6e40000000000000000000000000000000000000000000000000000000000000012", + "v": "0x26", + "r": "0x223a7c9bcf5531c99be5ea7082183816eb20cfe0bbc322e97cc5c7f71ab8b20e", + "s": "0x2aadee6b34b45bb15bc42d9c09de4a6754e7000908da72d48cc7704971491663", + "hash": "0xeba2df809e7a612a0a0d444ccfa5c839624bdc00dd29e3340d46df3870f8a30e" + } + } +} +``` + +Bash example: +```bash +#curl -H "Content-Type: application/json" -X POST --data '{"jsonrpc":"2.0","method":"account_signTransaction","params":[{"from":"0x694267f14675d7e1b9494fd8d72fefe1755710fa","gas":"0x333","gasPrice":"0x1","nonce":"0x0","to":"0x07a565b7ed7d7a678680a4c162885bedbb695fe0", "value":"0x0", "data":"0x4401a6e40000000000000000000000000000000000000000000000000000000000000012"},"safeSend(address)"],"id":67}' http://localhost:8550/ + +{"jsonrpc":"2.0","id":67,"result":{"raw":"0xf88380018203339407a565b7ed7d7a678680a4c162885bedbb695fe080a44401a6e4000000000000000000000000000000000000000000000000000000000000001226a0223a7c9bcf5531c99be5ea7082183816eb20cfe0bbc322e97cc5c7f71ab8b20ea02aadee6b34b45bb15bc42d9c09de4a6754e7000908da72d48cc7704971491663","tx":{"nonce":"0x0","gasPrice":"0x1","gas":"0x333","to":"0x07a565b7ed7d7a678680a4c162885bedbb695fe0","value":"0x0","input":"0x4401a6e40000000000000000000000000000000000000000000000000000000000000012","v":"0x26","r":"0x223a7c9bcf5531c99be5ea7082183816eb20cfe0bbc322e97cc5c7f71ab8b20e","s":"0x2aadee6b34b45bb15bc42d9c09de4a6754e7000908da72d48cc7704971491663","hash":"0xeba2df809e7a612a0a0d444ccfa5c839624bdc00dd29e3340d46df3870f8a30e"}}} +``` + + +### account_sign + +#### Sign data + Signs a chunk of data and returns the calculated signature. + +#### Arguments + - account [address]: account to sign with + - data [data]: data to sign + +#### Result + - calculated signature [data] + +#### Sample call +```json +{ + "id": 3, + "jsonrpc": "2.0", + "method": "account_sign", + "params": [ + "0x1923f626bb8dc025849e00f99c25fe2b2f7fb0db", + "0xaabbccdd" + ] +} +``` +Response + +```json +{ + "id": 3, + "jsonrpc": "2.0", + "result": "0x5b6693f153b48ec1c706ba4169960386dbaa6903e249cc79a8e6ddc434451d417e1e57327872c7f538beeb323c300afa9999a3d4a5de6caf3be0d5ef832b67ef1c" +} +``` + +### account_ecRecover + +#### Recover address + Derive the address from the account that was used to sign data from the data and signature. + +#### Arguments + - data [data]: data that was signed + - signature [data]: the signature to verify + +#### Result + - derived account [address] + +#### Sample call +```json +{ + "id": 4, + "jsonrpc": "2.0", + "method": "account_ecRecover", + "params": [ + "0xaabbccdd", + "0x5b6693f153b48ec1c706ba4169960386dbaa6903e249cc79a8e6ddc434451d417e1e57327872c7f538beeb323c300afa9999a3d4a5de6caf3be0d5ef832b67ef1c" + ] +} +``` +Response + +```json +{ + "id": 4, + "jsonrpc": "2.0", + "result": "0x1923f626bb8dc025849e00f99c25fe2b2f7fb0db" +} + +``` + +### account_import + +#### Import account + Import a private key into the keystore. The imported key is expected to be encrypted according to the web3 keystore + format. + +#### Arguments + - account [object]: key in [web3 keystore format](https://github.com/ethereum/wiki/wiki/Web3-Secret-Storage-Definition) (retrieved with account_export) + +#### Result + - imported key [object]: + - key.address [address]: address of the imported key + - key.type [string]: type of the account + - key.url [string]: key URL + +#### Sample call +```json +{ + "id": 6, + "jsonrpc": "2.0", + "method": "account_import", + "params": [ + { + "address": "c7412fc59930fd90099c917a50e5f11d0934b2f5", + "crypto": { + "cipher": "aes-128-ctr", + "cipherparams": { + "iv": "401c39a7c7af0388491c3d3ecb39f532" + }, + "ciphertext": "eb045260b18dd35cd0e6d99ead52f8fa1e63a6b0af2d52a8de198e59ad783204", + "kdf": "scrypt", + "kdfparams": { + "dklen": 32, + "n": 262144, + "p": 1, + "r": 8, + "salt": "9a657e3618527c9b5580ded60c12092e5038922667b7b76b906496f021bb841a" + }, + "mac": "880dc10bc06e9cec78eb9830aeb1e7a4a26b4c2c19615c94acb632992b952806" + }, + "id": "09bccb61-b8d3-4e93-bf4f-205a8194f0b9", + "version": 3 + }, + ] +} +``` +Response + +```json +{ + "id": 6, + "jsonrpc": "2.0", + "result": { + "address": "0xc7412fc59930fd90099c917a50e5f11d0934b2f5", + "type": "account", + "url": "keystore:///tmp/keystore/UTC--2017-08-24T11-00-42.032024108Z--c7412fc59930fd90099c917a50e5f11d0934b2f5" + } +} +``` + +### account_export + +#### Export account from keystore + Export a private key from the keystore. The exported private key is encrypted with the original passphrase. When the + key is imported later this passphrase is required. + +#### Arguments + - account [address]: export private key that is associated with this account + +#### Result + - exported key, see [web3 keystore format](https://github.com/ethereum/wiki/wiki/Web3-Secret-Storage-Definition) for + more information + +#### Sample call +```json +{ + "id": 5, + "jsonrpc": "2.0", + "method": "account_export", + "params": [ + "0xc7412fc59930fd90099c917a50e5f11d0934b2f5" + ] +} +``` +Response + +```json +{ + "id": 5, + "jsonrpc": "2.0", + "result": { + "address": "c7412fc59930fd90099c917a50e5f11d0934b2f5", + "crypto": { + "cipher": "aes-128-ctr", + "cipherparams": { + "iv": "401c39a7c7af0388491c3d3ecb39f532" + }, + "ciphertext": "eb045260b18dd35cd0e6d99ead52f8fa1e63a6b0af2d52a8de198e59ad783204", + "kdf": "scrypt", + "kdfparams": { + "dklen": 32, + "n": 262144, + "p": 1, + "r": 8, + "salt": "9a657e3618527c9b5580ded60c12092e5038922667b7b76b906496f021bb841a" + }, + "mac": "880dc10bc06e9cec78eb9830aeb1e7a4a26b4c2c19615c94acb632992b952806" + }, + "id": "09bccb61-b8d3-4e93-bf4f-205a8194f0b9", + "version": 3 + } +} +``` + + + +## UI API + +These methods needs to be implemented by a UI listener. + +By starting the signer with the switch `--stdio-ui-test`, the signer will invoke all known methods, and expect the UI to respond with +denials. This can be used during development to ensure that the API is (at least somewhat) correctly implemented. +See `pythonsigner`, which can be invoked via `python3 pythonsigner.py test` to perform the 'denial-handshake-test'. + +All methods in this API uses object-based parameters, so that there can be no mixups of parameters: each piece of data is accessed by key. + +See the [ui api changelog](intapi_changelog.md) for information about changes to this API. + +OBS! A slight deviation from `json` standard is in place: every request and response should be confined to a single line. +Whereas the `json` specification allows for linebreaks, linebreaks __should not__ be used in this communication channel, to make +things simpler for both parties. + +### ApproveTx + +Invoked when there's a transaction for approval. + + +#### Sample call + +Here's a method invocation: +```bash + +curl -i -H "Content-Type: application/json" -X POST --data '{"jsonrpc":"2.0","method":"account_signTransaction","params":[{"from":"0x694267f14675d7e1b9494fd8d72fefe1755710fa","gas":"0x333","gasPrice":"0x1","nonce":"0x0","to":"0x07a565b7ed7d7a678680a4c162885bedbb695fe0", "value":"0x0", "data":"0x4401a6e40000000000000000000000000000000000000000000000000000000000000012"},"safeSend(address)"],"id":67}' http://localhost:8550/ +``` + +```json + +{ + "jsonrpc": "2.0", + "id": 1, + "method": "ApproveTx", + "params": [ + { + "transaction": { + "from": "0x0x694267f14675d7e1b9494fd8d72fefe1755710fa", + "to": "0x0x07a565b7ed7d7a678680a4c162885bedbb695fe0", + "gas": "0x333", + "gasPrice": "0x1", + "value": "0x0", + "nonce": "0x0", + "data": "0x4401a6e40000000000000000000000000000000000000000000000000000000000000012", + "input": null + }, + "call_info": [ + { + "type": "WARNING", + "message": "Invalid checksum on to-address" + }, + { + "type": "Info", + "message": "safeSend(address: 0x0000000000000000000000000000000000000012)" + } + ], + "meta": { + "remote": "127.0.0.1:48486", + "local": "localhost:8550", + "scheme": "HTTP/1.1" + } + } + ] +} + +``` + +The same method invocation, but with invalid data: +```bash + +curl -i -H "Content-Type: application/json" -X POST --data '{"jsonrpc":"2.0","method":"account_signTransaction","params":[{"from":"0x694267f14675d7e1b9494fd8d72fefe1755710fa","gas":"0x333","gasPrice":"0x1","nonce":"0x0","to":"0x07a565b7ed7d7a678680a4c162885bedbb695fe0", "value":"0x0", "data":"0x4401a6e40000000000000002000000000000000000000000000000000000000000000012"},"safeSend(address)"],"id":67}' http://localhost:8550/ +``` + +```json + +{ + "jsonrpc": "2.0", + "id": 1, + "method": "ApproveTx", + "params": [ + { + "transaction": { + "from": "0x0x694267f14675d7e1b9494fd8d72fefe1755710fa", + "to": "0x0x07a565b7ed7d7a678680a4c162885bedbb695fe0", + "gas": "0x333", + "gasPrice": "0x1", + "value": "0x0", + "nonce": "0x0", + "data": "0x4401a6e40000000000000002000000000000000000000000000000000000000000000012", + "input": null + }, + "call_info": [ + { + "type": "WARNING", + "message": "Invalid checksum on to-address" + }, + { + "type": "WARNING", + "message": "Transaction data did not match ABI-interface: WARNING: Supplied data is stuffed with extra data. \nWant 0000000000000002000000000000000000000000000000000000000000000012\nHave 0000000000000000000000000000000000000000000000000000000000000012\nfor method safeSend(address)" + } + ], + "meta": { + "remote": "127.0.0.1:48492", + "local": "localhost:8550", + "scheme": "HTTP/1.1" + } + } + ] +} + + +``` + +One which has missing `to`, but with no `data`: + + +```json + +{ + "jsonrpc": "2.0", + "id": 3, + "method": "ApproveTx", + "params": [ + { + "transaction": { + "from": "", + "to": null, + "gas": "0x0", + "gasPrice": "0x0", + "value": "0x0", + "nonce": "0x0", + "data": null, + "input": null + }, + "call_info": [ + { + "type": "CRITICAL", + "message": "Tx will create contract with empty code!" + } + ], + "meta": { + "remote": "signer binary", + "local": "main", + "scheme": "in-proc" + } + } + ] +} +``` + +### ApproveExport + +Invoked when a request to export an account has been made. + +#### Sample call + +```json + +{ + "jsonrpc": "2.0", + "id": 7, + "method": "ApproveExport", + "params": [ + { + "address": "0x0000000000000000000000000000000000000000", + "meta": { + "remote": "signer binary", + "local": "main", + "scheme": "in-proc" + } + } + ] +} + +``` + +### ApproveListing + +Invoked when a request for account listing has been made. + +#### Sample call + +```json + +{ + "jsonrpc": "2.0", + "id": 5, + "method": "ApproveListing", + "params": [ + { + "accounts": [ + { + "type": "Account", + "url": "keystore:///home/bazonk/.ethereum/keystore/UTC--2017-11-20T14-44-54.089682944Z--123409812340981234098123409812deadbeef42", + "address": "0x123409812340981234098123409812deadbeef42" + }, + { + "type": "Account", + "url": "keystore:///home/bazonk/.ethereum/keystore/UTC--2017-11-23T21-59-03.199240693Z--cafebabedeadbeef34098123409812deadbeef42", + "address": "0xcafebabedeadbeef34098123409812deadbeef42" + } + ], + "meta": { + "remote": "signer binary", + "local": "main", + "scheme": "in-proc" + } + } + ] +} + +``` + + +### ApproveSignData + +#### Sample call + +```json +{ + "jsonrpc": "2.0", + "id": 4, + "method": "ApproveSignData", + "params": [ + { + "address": "0x123409812340981234098123409812deadbeef42", + "raw_data": "0x01020304", + "message": "\u0019Ethereum Signed Message:\n4\u0001\u0002\u0003\u0004", + "hash": "0x7e3a4e7a9d1744bc5c675c25e1234ca8ed9162bd17f78b9085e48047c15ac310", + "meta": { + "remote": "signer binary", + "local": "main", + "scheme": "in-proc" + } + } + ] +} + +``` + +### ShowInfo + +The UI should show the info to the user. Does not expect response. + +#### Sample call + +```json +{ + "jsonrpc": "2.0", + "id": 9, + "method": "ShowInfo", + "params": [ + { + "text": "Tests completed" + } + ] +} + +``` + +### ShowError + +The UI should show the info to the user. Does not expect response. + +```json + +{ + "jsonrpc": "2.0", + "id": 2, + "method": "ShowError", + "params": [ + { + "text": "Testing 'ShowError'" + } + ] +} + +``` + +### OnApproved + +`OnApprovedTx` is called when a transaction has been approved and signed. The call contains the return value that will be sent to the external caller. The return value from this method is ignored - the reason for having this callback is to allow the ruleset to keep track of approved transactions. + +When implementing rate-limited rules, this callback should be used. + +TLDR; Use this method to keep track of signed transactions, instead of using the data in `ApproveTx`. + +### OnSignerStartup + +This method provide the UI with information about what API version the signer uses (both internal and external) aswell as build-info and external api, +in k/v-form. + +Example call: +```json + +{ + "jsonrpc": "2.0", + "id": 1, + "method": "OnSignerStartup", + "params": [ + { + "info": { + "extapi_http": "http://localhost:8550", + "extapi_ipc": null, + "extapi_version": "2.0.0", + "intapi_version": "1.2.0" + } + } + ] +} + +``` + + +### Rules for UI apis + +A UI should conform to the following rules. + +* A UI MUST NOT load any external resources that were not embedded/part of the UI package. + * For example, not load icons, stylesheets from the internet + * Not load files from the filesystem, unless they reside in the same local directory (e.g. config files) +* A Graphical UI MUST show the blocky-identicon for ethereum addresses. +* A UI MUST warn display approproate warning if the destination-account is formatted with invalid checksum. +* A UI MUST NOT open any ports or services + * The signer opens the public port +* A UI SHOULD verify the permissions on the signer binary, and refuse to execute or warn if permissions allow non-user write. +* A UI SHOULD inform the user about the `SHA256` or `MD5` hash of the binary being executed +* A UI SHOULD NOT maintain a secondary storage of data, e.g. list of accounts + * The signer provides accounts +* A UI SHOULD, to the best extent possible, use static linking / bundling, so that requried libraries are bundled +along with the UI. + + +### UI Implementations + +There are a couple of implementation for a UI. We'll try to keep this list up to date. + +| Name | Repo | UI type| No external resources| Blocky support| Verifies permissions | Hash information | No secondary storage | Statically linked| Can modify parameters| +| ---- | ---- | -------| ---- | ---- | ---- |---- | ---- | ---- | ---- | +| QtSigner| https://github.com/holiman/qtsigner/| Python3/QT-based| :+1:| :+1:| :+1:| :+1:| :+1:| :x: | :+1: (partially)| +| GtkSigner| https://github.com/holiman/gtksigner| Python3/GTK-based| :+1:| :x:| :x:| :+1:| :+1:| :x: | :x: | +| Frame | https://github.com/floating/frame/commits/go-signer| Electron-based| :x:| :x:| :x:| :x:| ?| :x: | :x: | diff --git a/cmd/clef/docs/qubes/clef_qubes_http.png b/cmd/clef/docs/qubes/clef_qubes_http.png new file mode 100644 index 0000000000..a641e1987f Binary files /dev/null and b/cmd/clef/docs/qubes/clef_qubes_http.png differ diff --git a/cmd/clef/docs/qubes/clef_qubes_qrexec.png b/cmd/clef/docs/qubes/clef_qubes_qrexec.png new file mode 100644 index 0000000000..f57fc8933e Binary files /dev/null and b/cmd/clef/docs/qubes/clef_qubes_qrexec.png differ diff --git a/cmd/clef/docs/qubes/qrexec-example.png b/cmd/clef/docs/qubes/qrexec-example.png new file mode 100644 index 0000000000..0d86fde19d Binary files /dev/null and b/cmd/clef/docs/qubes/qrexec-example.png differ diff --git a/cmd/clef/docs/qubes/qubes-client.py b/cmd/clef/docs/qubes/qubes-client.py new file mode 100644 index 0000000000..93a74b899b --- /dev/null +++ b/cmd/clef/docs/qubes/qubes-client.py @@ -0,0 +1,23 @@ +""" +This implements a dispatcher which listens to localhost:8550, and proxies +requests via qrexec to the service qubes.EthSign on a target domain +""" + +import http.server +import socketserver,subprocess + +PORT=8550 +TARGET_DOMAIN= 'debian-work' + +class Dispatcher(http.server.BaseHTTPRequestHandler): + def do_POST(self): + post_data = self.rfile.read(int(self.headers['Content-Length'])) + p = subprocess.Popen(['/usr/bin/qrexec-client-vm',TARGET_DOMAIN,'qubes.Clefsign'],stdin=subprocess.PIPE, stdout=subprocess.PIPE) + output = p.communicate(post_data)[0] + self.wfile.write(output) + + +with socketserver.TCPServer(("",PORT), Dispatcher) as httpd: + print("Serving at port", PORT) + httpd.serve_forever() + diff --git a/cmd/clef/docs/qubes/qubes.Clefsign b/cmd/clef/docs/qubes/qubes.Clefsign new file mode 100644 index 0000000000..9b5af7b4fe --- /dev/null +++ b/cmd/clef/docs/qubes/qubes.Clefsign @@ -0,0 +1,16 @@ +#!/bin/bash + +SIGNER_BIN="/home/user/tools/clef/clef" +SIGNER_CMD="/home/user/tools/gtksigner/gtkui.py -s $SIGNER_BIN" + +# Start clef if not already started +if [ ! -S /home/user/.clef/clef.ipc ]; then + $SIGNER_CMD & + sleep 1 +fi + +# Should be started by now +if [ -S /home/user/.clef/clef.ipc ]; then + # Post incoming request to HTTP channel + curl -H "Content-Type: application/json" -X POST -d @- http://localhost:8550 2>/dev/null +fi diff --git a/cmd/clef/docs/qubes/qubes_newaccount-1.png b/cmd/clef/docs/qubes/qubes_newaccount-1.png new file mode 100644 index 0000000000..598dbbee7a Binary files /dev/null and b/cmd/clef/docs/qubes/qubes_newaccount-1.png differ diff --git a/cmd/clef/docs/qubes/qubes_newaccount-2.png b/cmd/clef/docs/qubes/qubes_newaccount-2.png new file mode 100644 index 0000000000..cd762a1934 Binary files /dev/null and b/cmd/clef/docs/qubes/qubes_newaccount-2.png differ diff --git a/cmd/clef/docs/setup.md b/cmd/clef/docs/setup.md new file mode 100644 index 0000000000..33d2b0381f --- /dev/null +++ b/cmd/clef/docs/setup.md @@ -0,0 +1,198 @@ +# Setting up Clef + +This document describes how Clef can be used in a more secure manner than executing it from your everyday laptop, +in order to ensure that the keys remain safe in the event that your computer should get compromised. + +## Qubes OS + + +### Background + +The Qubes operating system is based around virtual machines (qubes), where a set of virtual machines are configured, typically for +different purposes such as: + +- personal + - Your personal email, browsing etc +- work + - Work email etc +- vault + - a VM without network access, where gpg-keys and/or keepass credentials are stored. + +A couple of dedicated virtual machines handle externalities: + +- sys-net provides networking to all other (network-enabled) machines +- sys-firewall handles firewall rules +- sys-usb handles USB devices, and can map usb-devices to certain qubes. + +The goal of this document is to describe how we can set up clef to provide secure transaction +signing from a `vault` vm, to another networked qube which runs Dapps. + +### Setup + +There are two ways that this can be achieved: integrated via Qubes or integrated via networking. + + +#### 1. Qubes Integrated + +Qubes provdes a facility for inter-qubes communication via `qrexec`. A qube can request to make a cross-qube RPC request +to another qube. The OS then asks the user if the call is permitted. + +![Example](qubes/qrexec-example.png) + +A policy-file can be created to allow such interaction. On the `target` domain, a service is invoked which can read the +`stdin` from the `client` qube. + +This is how [Split GPG](https://www.qubes-os.org/doc/split-gpg/) is implemented. We can set up Clef the same way: + +##### Server + +![Clef via qrexec](qubes/clef_qubes_qrexec.png) + +On the `target` qubes, we need to define the rpc service. + +[qubes.Clefsign](qubes/qubes.Clefsign): + +```bash +#!/bin/bash + +SIGNER_BIN="/home/user/tools/clef/clef" +SIGNER_CMD="/home/user/tools/gtksigner/gtkui.py -s $SIGNER_BIN" + +# Start clef if not already started +if [ ! -S /home/user/.clef/clef.ipc ]; then + $SIGNER_CMD & + sleep 1 +fi + +# Should be started by now +if [ -S /home/user/.clef/clef.ipc ]; then + # Post incoming request to HTTP channel + curl -H "Content-Type: application/json" -X POST -d @- http://localhost:8550 2>/dev/null +fi + +``` +This RPC service is not complete (see notes about HTTP headers below), but works as a proof-of-concept. +It will forward the data received on `stdin` (forwarded by the OS) to Clef's HTTP channel. + +It would have been possible to send data directly to the `/home/user/.clef/.clef.ipc` +socket via e.g `nc -U /home/user/.clef/clef.ipc`, but the reason for sending the request +data over `HTTP` instead of `IPC` is that we want the ability to forward `HTTP` headers. + +To enable the service: + +``` bash +sudo cp qubes.Clefsign /etc/qubes-rpc/ +sudo chmod +x /etc/qubes-rpc/ qubes.Clefsign +``` + +This setup uses [gtksigner](https://github.com/holiman/gtksigner), which is a very minimal GTK-based UI that works well +with minimal requirements. + +##### Client + + +On the `client` qube, we need to create a listener which will receive the request from the Dapp, and proxy it. + + +[qubes-client.py](qubes/client/qubes-client.py): + +```python + +""" +This implements a dispatcher which listens to localhost:8550, and proxies +requests via qrexec to the service qubes.EthSign on a target domain +""" + +import http.server +import socketserver,subprocess + +PORT=8550 +TARGET_DOMAIN= 'debian-work' + +class Dispatcher(http.server.BaseHTTPRequestHandler): + def do_POST(self): + post_data = self.rfile.read(int(self.headers['Content-Length'])) + p = subprocess.Popen(['/usr/bin/qrexec-client-vm',TARGET_DOMAIN,'qubes.Clefsign'],stdin=subprocess.PIPE, stdout=subprocess.PIPE) + output = p.communicate(post_data)[0] + self.wfile.write(output) + + +with socketserver.TCPServer(("",PORT), Dispatcher) as httpd: + print("Serving at port", PORT) + httpd.serve_forever() + + +``` + +#### Testing + +To test the flow, if we have set up `debian-work` as the `target`, we can do + +```bash +$ cat newaccnt.json +{ "id": 0, "jsonrpc": "2.0","method": "account_new","params": []} + +$ cat newaccnt.json| qrexec-client-vm debian-work qubes.Clefsign +``` + +This should pop up first a dialog to allow the IPC call: + +![one](qubes/qubes_newaccount-1.png) + +Followed by a GTK-dialog to approve the operation + +![two](qubes/qubes_newaccount-2.png) + +To test the full flow, we use the client wrapper. Start it on the `client` qube: +``` +[user@work qubes]$ python3 qubes-client.py +``` + +Make the request over http (`client` qube): +``` +[user@work clef]$ cat newaccnt.json | curl -X POST -d @- http://localhost:8550 +``` +And it should show the same popups again. + +##### Pros and cons + +The benefits of this setup are: + +- This is the qubes-os intended model for inter-qube communication, +- and thus benefits from qubes-os dialogs and policies for user approval + +However, it comes with a couple of drawbacks: + +- The `qubes-gpg-client` must forward the http request via RPC to the `target` qube. When doing so, the proxy + will either drop important headers, or replace them. + - The `Host` header is most likely `localhost` + - The `Origin` header must be forwarded + - Information about the remote ip must be added as a `X-Forwarded-For`. However, Clef cannot always trust an `XFF` header, + since malicious clients may lie about `XFF` in order to fool the http server into believing it comes from another address. +- Even with a policy in place to allow rpc-calls between `caller` and `target`, there will be several popups: + - One qubes-specific where the user specifies the `target` vm + - One clef-specific to approve the transaction + + +#### 2. Network integrated + +The second way to set up Clef on a qubes system is to allow networking, and have Clef listen to a port which is accessible +form other qubes. + +![Clef via http](qubes/clef_qubes_http.png) + + + + +## USBArmory + +The [USB armory](https://inversepath.com/usbarmory) is an open source hardware design with an 800 Mhz ARM processor. It is a pocket-size +computer. When inserted into a laptop, it identifies itself as a USB network interface, basically adding another network +to your computer. Over this new network interface, you can SSH into the device. + +Running Clef off a USB armory means that you can use the armory as a very versatile offline computer, which only +ever connects to a local network between your computer and the device itself. + +Needless to say, the while this model should be fairly secure against remote attacks, an attacker with physical access +to the USB Armory would trivially be able to extract the contents of the device filesystem. + diff --git a/cmd/clef/extapi_changelog.md b/cmd/clef/extapi_changelog.md new file mode 100644 index 0000000000..2014e90ae4 --- /dev/null +++ b/cmd/clef/extapi_changelog.md @@ -0,0 +1,25 @@ +### Changelog for external API + + + +#### 2.0.0 + +* Commit `73abaf04b1372fa4c43201fb1b8019fe6b0a6f8d`, move `from` into `transaction` object in `signTransaction`. This +makes the `accounts_signTransaction` identical to the old `eth_signTransaction`. + + +#### 1.0.0 + +Initial release. + +### Versioning + +The API uses [semantic versioning](https://semver.org/). + +TLDR; Given a version number MAJOR.MINOR.PATCH, increment the: + +* MAJOR version when you make incompatible API changes, +* MINOR version when you add functionality in a backwards-compatible manner, and +* PATCH version when you make backwards-compatible bug fixes. + +Additional labels for pre-release and build metadata are available as extensions to the MAJOR.MINOR.PATCH format. diff --git a/cmd/clef/intapi_changelog.md b/cmd/clef/intapi_changelog.md new file mode 100644 index 0000000000..7d2a897ea2 --- /dev/null +++ b/cmd/clef/intapi_changelog.md @@ -0,0 +1,86 @@ +### Changelog for internal API (ui-api) + +### 2.0.0 + +* Modify how `call_info` on a transaction is conveyed. New format: + +``` +{ + "jsonrpc": "2.0", + "id": 2, + "method": "ApproveTx", + "params": [ + { + "transaction": { + "from": "0x82A2A876D39022B3019932D30Cd9c97ad5616813", + "to": "0x07a565b7ed7d7a678680a4c162885bedbb695fe0", + "gas": "0x333", + "gasPrice": "0x123", + "value": "0x10", + "nonce": "0x0", + "data": "0x4401a6e40000000000000000000000000000000000000000000000000000000000000012", + "input": null + }, + "call_info": [ + { + "type": "WARNING", + "message": "Invalid checksum on to-address" + }, + { + "type": "WARNING", + "message": "Tx contains data, but provided ABI signature could not be matched: Did not match: test (0 matches)" + } + ], + "meta": { + "remote": "127.0.0.1:54286", + "local": "localhost:8550", + "scheme": "HTTP/1.1" + } + } + ] +} +``` + +#### 1.2.0 + +* Add `OnStartup` method, to provide the UI with information about what API version +the signer uses (both internal and external) aswell as build-info and external api. + +Example call: +```json +{ + "jsonrpc": "2.0", + "id": 1, + "method": "OnSignerStartup", + "params": [ + { + "info": { + "extapi_http": "http://localhost:8550", + "extapi_ipc": null, + "extapi_version": "2.0.0", + "intapi_version": "1.2.0" + } + } + ] +} +``` + +#### 1.1.0 + +* Add `OnApproved` method + +#### 1.0.0 + +Initial release. + +### Versioning + +The API uses [semantic versioning](https://semver.org/). + +TLDR; Given a version number MAJOR.MINOR.PATCH, increment the: + +* MAJOR version when you make incompatible API changes, +* MINOR version when you add functionality in a backwards-compatible manner, and +* PATCH version when you make backwards-compatible bug fixes. + +Additional labels for pre-release and build metadata are available as extensions to the MAJOR.MINOR.PATCH format. diff --git a/cmd/clef/main.go b/cmd/clef/main.go new file mode 100644 index 0000000000..85704754de --- /dev/null +++ b/cmd/clef/main.go @@ -0,0 +1,640 @@ +// Copyright 2018 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 . + +// signer is a utility that can be used so sign transactions and +// arbitrary data. +package main + +import ( + "bufio" + "context" + "crypto/rand" + "crypto/sha256" + "encoding/hex" + "encoding/json" + "fmt" + "io" + "io/ioutil" + "os" + "os/signal" + "os/user" + "path/filepath" + "runtime" + "strings" + + "github.com/ethereum/go-ethereum/cmd/utils" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/node" + "github.com/ethereum/go-ethereum/rpc" + "github.com/ethereum/go-ethereum/signer/core" + "github.com/ethereum/go-ethereum/signer/rules" + "github.com/ethereum/go-ethereum/signer/storage" + "gopkg.in/urfave/cli.v1" +) + +// ExternalAPIVersion -- see extapi_changelog.md +const ExternalAPIVersion = "2.0.0" + +// InternalAPIVersion -- see intapi_changelog.md +const InternalAPIVersion = "2.0.0" + +const legalWarning = ` +WARNING! + +Clef is alpha software, and not yet publically released. This software has _not_ been audited, and there +are no guarantees about the workings of this software. It may contain severe flaws. You should not use this software +unless you agree to take full responsibility for doing so, and know what you are doing. + +TLDR; THIS IS NOT PRODUCTION-READY SOFTWARE! + +` + +var ( + logLevelFlag = cli.IntFlag{ + Name: "loglevel", + Value: 4, + Usage: "log level to emit to the screen", + } + keystoreFlag = cli.StringFlag{ + Name: "keystore", + Value: filepath.Join(node.DefaultDataDir(), "keystore"), + Usage: "Directory for the keystore", + } + configdirFlag = cli.StringFlag{ + Name: "configdir", + Value: DefaultConfigDir(), + Usage: "Directory for Clef configuration", + } + rpcPortFlag = cli.IntFlag{ + Name: "rpcport", + Usage: "HTTP-RPC server listening port", + Value: node.DefaultHTTPPort + 5, + } + signerSecretFlag = cli.StringFlag{ + Name: "signersecret", + Usage: "A file containing the password used to encrypt Clef credentials, e.g. keystore credentials and ruleset hash", + } + dBFlag = cli.StringFlag{ + Name: "4bytedb", + Usage: "File containing 4byte-identifiers", + Value: "./4byte.json", + } + customDBFlag = cli.StringFlag{ + Name: "4bytedb-custom", + Usage: "File used for writing new 4byte-identifiers submitted via API", + Value: "./4byte-custom.json", + } + auditLogFlag = cli.StringFlag{ + Name: "auditlog", + Usage: "File used to emit audit logs. Set to \"\" to disable", + Value: "audit.log", + } + ruleFlag = cli.StringFlag{ + Name: "rules", + Usage: "Enable rule-engine", + Value: "rules.json", + } + stdiouiFlag = cli.BoolFlag{ + Name: "stdio-ui", + Usage: "Use STDIN/STDOUT as a channel for an external UI. " + + "This means that an STDIN/STDOUT is used for RPC-communication with a e.g. a graphical user " + + "interface, and can be used when Clef is started by an external process.", + } + testFlag = cli.BoolFlag{ + Name: "stdio-ui-test", + Usage: "Mechanism to test interface between Clef and UI. Requires 'stdio-ui'.", + } + app = cli.NewApp() + initCommand = cli.Command{ + Action: utils.MigrateFlags(initializeSecrets), + Name: "init", + Usage: "Initialize the signer, generate secret storage", + ArgsUsage: "", + Flags: []cli.Flag{ + logLevelFlag, + configdirFlag, + }, + Description: ` +The init command generates a master seed which Clef can use to store credentials and data needed for +the rule-engine to work.`, + } + attestCommand = cli.Command{ + Action: utils.MigrateFlags(attestFile), + Name: "attest", + Usage: "Attest that a js-file is to be used", + ArgsUsage: "", + Flags: []cli.Flag{ + logLevelFlag, + configdirFlag, + signerSecretFlag, + }, + Description: ` +The attest command stores the sha256 of the rule.js-file that you want to use for automatic processing of +incoming requests. + +Whenever you make an edit to the rule file, you need to use attestation to tell +Clef that the file is 'safe' to execute.`, + } + + addCredentialCommand = cli.Command{ + Action: utils.MigrateFlags(addCredential), + Name: "addpw", + Usage: "Store a credential for a keystore file", + ArgsUsage: "
", + Flags: []cli.Flag{ + logLevelFlag, + configdirFlag, + signerSecretFlag, + }, + Description: ` +The addpw command stores a password for a given address (keyfile). If you invoke it with only one parameter, it will +remove any stored credential for that address (keyfile) +`, + } +) + +func init() { + app.Name = "Clef" + app.Usage = "Manage Ethereum account operations" + app.Flags = []cli.Flag{ + logLevelFlag, + keystoreFlag, + configdirFlag, + utils.NetworkIdFlag, + utils.LightKDFFlag, + utils.NoUSBFlag, + utils.RPCListenAddrFlag, + utils.RPCVirtualHostsFlag, + utils.IPCDisabledFlag, + utils.IPCPathFlag, + utils.RPCEnabledFlag, + rpcPortFlag, + signerSecretFlag, + dBFlag, + customDBFlag, + auditLogFlag, + ruleFlag, + stdiouiFlag, + testFlag, + } + app.Action = signer + app.Commands = []cli.Command{initCommand, attestCommand, addCredentialCommand} + +} +func main() { + if err := app.Run(os.Args); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } +} + +func initializeSecrets(c *cli.Context) error { + if err := initialize(c); err != nil { + return err + } + configDir := c.String(configdirFlag.Name) + + masterSeed := make([]byte, 256) + n, err := io.ReadFull(rand.Reader, masterSeed) + if err != nil { + return err + } + if n != len(masterSeed) { + return fmt.Errorf("failed to read enough random") + } + err = os.Mkdir(configDir, 0700) + if err != nil && !os.IsExist(err) { + return err + } + location := filepath.Join(configDir, "secrets.dat") + if _, err := os.Stat(location); err == nil { + return fmt.Errorf("file %v already exists, will not overwrite", location) + } + err = ioutil.WriteFile(location, masterSeed, 0700) + if err != nil { + return err + } + fmt.Printf("A master seed has been generated into %s\n", location) + fmt.Printf(` +This is required to be able to store credentials, such as : +* Passwords for keystores (used by rule engine) +* Storage for javascript rules +* Hash of rule-file + +You should treat that file with utmost secrecy, and make a backup of it. +NOTE: This file does not contain your accounts. Those need to be backed up separately! + +`) + return nil +} +func attestFile(ctx *cli.Context) error { + if len(ctx.Args()) < 1 { + utils.Fatalf("This command requires an argument.") + } + if err := initialize(ctx); err != nil { + return err + } + + stretchedKey, err := readMasterKey(ctx) + if err != nil { + utils.Fatalf(err.Error()) + } + configDir := ctx.String(configdirFlag.Name) + vaultLocation := filepath.Join(configDir, common.Bytes2Hex(crypto.Keccak256([]byte("vault"), stretchedKey)[:10])) + confKey := crypto.Keccak256([]byte("config"), stretchedKey) + + // Initialize the encrypted storages + configStorage := storage.NewAESEncryptedStorage(filepath.Join(vaultLocation, "config.json"), confKey) + val := ctx.Args().First() + configStorage.Put("ruleset_sha256", val) + log.Info("Ruleset attestation updated", "sha256", val) + return nil +} + +func addCredential(ctx *cli.Context) error { + if len(ctx.Args()) < 1 { + utils.Fatalf("This command requires at leaste one argument.") + } + if err := initialize(ctx); err != nil { + return err + } + + stretchedKey, err := readMasterKey(ctx) + if err != nil { + utils.Fatalf(err.Error()) + } + configDir := ctx.String(configdirFlag.Name) + vaultLocation := filepath.Join(configDir, common.Bytes2Hex(crypto.Keccak256([]byte("vault"), stretchedKey)[:10])) + pwkey := crypto.Keccak256([]byte("credentials"), stretchedKey) + + // Initialize the encrypted storages + pwStorage := storage.NewAESEncryptedStorage(filepath.Join(vaultLocation, "credentials.json"), pwkey) + key := ctx.Args().First() + value := "" + if len(ctx.Args()) > 1 { + value = ctx.Args().Get(1) + } + pwStorage.Put(key, value) + log.Info("Credential store updated", "key", key) + return nil +} + +func initialize(c *cli.Context) error { + // Set up the logger to print everything + logOutput := os.Stdout + if c.Bool(stdiouiFlag.Name) { + logOutput = os.Stderr + // If using the stdioui, we can't do the 'confirm'-flow + fmt.Fprintf(logOutput, legalWarning) + } else { + if !confirm(legalWarning) { + return fmt.Errorf("aborted by user") + } + } + + log.Root().SetHandler(log.LvlFilterHandler(log.Lvl(c.Int(logLevelFlag.Name)), log.StreamHandler(logOutput, log.TerminalFormat(true)))) + return nil +} + +func signer(c *cli.Context) error { + if err := initialize(c); err != nil { + return err + } + var ( + ui core.SignerUI + ) + if c.Bool(stdiouiFlag.Name) { + log.Info("Using stdin/stdout as UI-channel") + ui = core.NewStdIOUI() + } else { + log.Info("Using CLI as UI-channel") + ui = core.NewCommandlineUI() + } + db, err := core.NewAbiDBFromFiles(c.String(dBFlag.Name), c.String(customDBFlag.Name)) + if err != nil { + utils.Fatalf(err.Error()) + } + log.Info("Loaded 4byte db", "signatures", db.Size(), "file", c.String("4bytedb")) + + var ( + api core.ExternalAPI + ) + + configDir := c.String(configdirFlag.Name) + if stretchedKey, err := readMasterKey(c); err != nil { + log.Info("No master seed provided, rules disabled") + } else { + + if err != nil { + utils.Fatalf(err.Error()) + } + vaultLocation := filepath.Join(configDir, common.Bytes2Hex(crypto.Keccak256([]byte("vault"), stretchedKey)[:10])) + + // Generate domain specific keys + pwkey := crypto.Keccak256([]byte("credentials"), stretchedKey) + jskey := crypto.Keccak256([]byte("jsstorage"), stretchedKey) + confkey := crypto.Keccak256([]byte("config"), stretchedKey) + + // Initialize the encrypted storages + pwStorage := storage.NewAESEncryptedStorage(filepath.Join(vaultLocation, "credentials.json"), pwkey) + jsStorage := storage.NewAESEncryptedStorage(filepath.Join(vaultLocation, "jsstorage.json"), jskey) + configStorage := storage.NewAESEncryptedStorage(filepath.Join(vaultLocation, "config.json"), confkey) + + //Do we have a rule-file? + ruleJS, err := ioutil.ReadFile(c.String(ruleFlag.Name)) + if err != nil { + log.Info("Could not load rulefile, rules not enabled", "file", "rulefile") + } else { + hasher := sha256.New() + hasher.Write(ruleJS) + shasum := hasher.Sum(nil) + storedShasum := configStorage.Get("ruleset_sha256") + if storedShasum != hex.EncodeToString(shasum) { + log.Info("Could not validate ruleset hash, rules not enabled", "got", hex.EncodeToString(shasum), "expected", storedShasum) + } else { + // Initialize rules + ruleEngine, err := rules.NewRuleEvaluator(ui, jsStorage, pwStorage) + if err != nil { + utils.Fatalf(err.Error()) + } + ruleEngine.Init(string(ruleJS)) + ui = ruleEngine + log.Info("Rule engine configured", "file", c.String(ruleFlag.Name)) + } + } + } + + apiImpl := core.NewSignerAPI( + c.Int64(utils.NetworkIdFlag.Name), + c.String(keystoreFlag.Name), + c.Bool(utils.NoUSBFlag.Name), + ui, db, + c.Bool(utils.LightKDFFlag.Name)) + + api = apiImpl + + // Audit logging + if logfile := c.String(auditLogFlag.Name); logfile != "" { + api, err = core.NewAuditLogger(logfile, api) + if err != nil { + utils.Fatalf(err.Error()) + } + log.Info("Audit logs configured", "file", logfile) + } + // register signer API with server + var ( + extapiURL = "n/a" + ipcapiURL = "n/a" + ) + rpcAPI := []rpc.API{ + { + Namespace: "account", + Public: true, + Service: api, + Version: "1.0"}, + } + if c.Bool(utils.RPCEnabledFlag.Name) { + + vhosts := splitAndTrim(c.GlobalString(utils.RPCVirtualHostsFlag.Name)) + cors := splitAndTrim(c.GlobalString(utils.RPCCORSDomainFlag.Name)) + + // start http server + httpEndpoint := fmt.Sprintf("%s:%d", c.String(utils.RPCListenAddrFlag.Name), c.Int(rpcPortFlag.Name)) + listener, _, err := rpc.StartHTTPEndpoint(httpEndpoint, rpcAPI, []string{"account"}, cors, vhosts, rpc.DefaultHTTPTimeouts) + if err != nil { + utils.Fatalf("Could not start RPC api: %v", err) + } + extapiURL = fmt.Sprintf("http://%s", httpEndpoint) + log.Info("HTTP endpoint opened", "url", extapiURL) + + defer func() { + listener.Close() + log.Info("HTTP endpoint closed", "url", httpEndpoint) + }() + + } + if !c.Bool(utils.IPCDisabledFlag.Name) { + if c.IsSet(utils.IPCPathFlag.Name) { + ipcapiURL = c.String(utils.IPCPathFlag.Name) + } else { + ipcapiURL = filepath.Join(configDir, "clef.ipc") + } + + listener, _, err := rpc.StartIPCEndpoint(ipcapiURL, rpcAPI) + if err != nil { + utils.Fatalf("Could not start IPC api: %v", err) + } + log.Info("IPC endpoint opened", "url", ipcapiURL) + defer func() { + listener.Close() + log.Info("IPC endpoint closed", "url", ipcapiURL) + }() + + } + + if c.Bool(testFlag.Name) { + log.Info("Performing UI test") + go testExternalUI(apiImpl) + } + ui.OnSignerStartup(core.StartupInfo{ + Info: map[string]interface{}{ + "extapi_version": ExternalAPIVersion, + "intapi_version": InternalAPIVersion, + "extapi_http": extapiURL, + "extapi_ipc": ipcapiURL, + }, + }) + + abortChan := make(chan os.Signal) + signal.Notify(abortChan, os.Interrupt) + + sig := <-abortChan + log.Info("Exiting...", "signal", sig) + + return nil +} + +// splitAndTrim splits input separated by a comma +// and trims excessive white space from the substrings. +func splitAndTrim(input string) []string { + result := strings.Split(input, ",") + for i, r := range result { + result[i] = strings.TrimSpace(r) + } + return result +} + +// DefaultConfigDir is the default config directory to use for the vaults and other +// persistence requirements. +func DefaultConfigDir() string { + // Try to place the data folder in the user's home dir + home := homeDir() + if home != "" { + if runtime.GOOS == "darwin" { + return filepath.Join(home, "Library", "Signer") + } else if runtime.GOOS == "windows" { + return filepath.Join(home, "AppData", "Roaming", "Signer") + } else { + return filepath.Join(home, ".clef") + } + } + // As we cannot guess a stable location, return empty and handle later + return "" +} + +func homeDir() string { + if home := os.Getenv("HOME"); home != "" { + return home + } + if usr, err := user.Current(); err == nil { + return usr.HomeDir + } + return "" +} +func readMasterKey(ctx *cli.Context) ([]byte, error) { + var ( + file string + configDir = ctx.String(configdirFlag.Name) + ) + if ctx.IsSet(signerSecretFlag.Name) { + file = ctx.String(signerSecretFlag.Name) + } else { + file = filepath.Join(configDir, "secrets.dat") + } + if err := checkFile(file); err != nil { + return nil, err + } + masterKey, err := ioutil.ReadFile(file) + if err != nil { + return nil, err + } + if len(masterKey) < 256 { + return nil, fmt.Errorf("master key of insufficient length, expected >255 bytes, got %d", len(masterKey)) + } + // Create vault location + vaultLocation := filepath.Join(configDir, common.Bytes2Hex(crypto.Keccak256([]byte("vault"), masterKey)[:10])) + err = os.Mkdir(vaultLocation, 0700) + if err != nil && !os.IsExist(err) { + return nil, err + } + //!TODO, use KDF to stretch the master key + // stretched_key := stretch_key(master_key) + + return masterKey, nil +} + +// checkFile is a convenience function to check if a file +// * exists +// * is mode 0600 +func checkFile(filename string) error { + info, err := os.Stat(filename) + if err != nil { + return fmt.Errorf("failed stat on %s: %v", filename, err) + } + // Check the unix permission bits + if info.Mode().Perm()&077 != 0 { + return fmt.Errorf("file (%v) has insecure file permissions (%v)", filename, info.Mode().String()) + } + return nil +} + +// confirm displays a text and asks for user confirmation +func confirm(text string) bool { + fmt.Printf(text) + fmt.Printf("\nEnter 'ok' to proceed:\n>") + + text, err := bufio.NewReader(os.Stdin).ReadString('\n') + if err != nil { + log.Crit("Failed to read user input", "err", err) + } + + if text := strings.TrimSpace(text); text == "ok" { + return true + } + return false +} + +func testExternalUI(api *core.SignerAPI) { + + ctx := context.WithValue(context.Background(), "remote", "clef binary") + ctx = context.WithValue(ctx, "scheme", "in-proc") + ctx = context.WithValue(ctx, "local", "main") + + errs := make([]string, 0) + + api.UI.ShowInfo("Testing 'ShowInfo'") + api.UI.ShowError("Testing 'ShowError'") + + checkErr := func(method string, err error) { + if err != nil && err != core.ErrRequestDenied { + errs = append(errs, fmt.Sprintf("%v: %v", method, err.Error())) + } + } + var err error + + _, err = api.SignTransaction(ctx, core.SendTxArgs{From: common.MixedcaseAddress{}}, nil) + checkErr("SignTransaction", err) + _, err = api.Sign(ctx, common.MixedcaseAddress{}, common.Hex2Bytes("01020304")) + checkErr("Sign", err) + _, err = api.List(ctx) + checkErr("List", err) + _, err = api.New(ctx) + checkErr("New", err) + _, err = api.Export(ctx, common.Address{}) + checkErr("Export", err) + _, err = api.Import(ctx, json.RawMessage{}) + checkErr("Import", err) + + api.UI.ShowInfo("Tests completed") + + if len(errs) > 0 { + log.Error("Got errors") + for _, e := range errs { + log.Error(e) + } + } else { + log.Info("No errors") + } + +} + +/** +//Create Account + +curl -H "Content-Type: application/json" -X POST --data '{"jsonrpc":"2.0","method":"account_new","params":["test"],"id":67}' localhost:8550 + +// List accounts + +curl -i -H "Content-Type: application/json" -X POST --data '{"jsonrpc":"2.0","method":"account_list","params":[""],"id":67}' http://localhost:8550/ + +// Make Transaction +// safeSend(0x12) +// 4401a6e40000000000000000000000000000000000000000000000000000000000000012 + +// supplied abi +curl -i -H "Content-Type: application/json" -X POST --data '{"jsonrpc":"2.0","method":"account_signTransaction","params":[{"from":"0x82A2A876D39022B3019932D30Cd9c97ad5616813","gas":"0x333","gasPrice":"0x123","nonce":"0x0","to":"0x07a565b7ed7d7a678680a4c162885bedbb695fe0", "value":"0x10", "data":"0x4401a6e40000000000000000000000000000000000000000000000000000000000000012"},"test"],"id":67}' http://localhost:8550/ + +// Not supplied +curl -i -H "Content-Type: application/json" -X POST --data '{"jsonrpc":"2.0","method":"account_signTransaction","params":[{"from":"0x82A2A876D39022B3019932D30Cd9c97ad5616813","gas":"0x333","gasPrice":"0x123","nonce":"0x0","to":"0x07a565b7ed7d7a678680a4c162885bedbb695fe0", "value":"0x10", "data":"0x4401a6e40000000000000000000000000000000000000000000000000000000000000012"}],"id":67}' http://localhost:8550/ + +// Sign data + +curl -i -H "Content-Type: application/json" -X POST --data '{"jsonrpc":"2.0","method":"account_sign","params":["0x694267f14675d7e1b9494fd8d72fefe1755710fa","bazonk gaz baz"],"id":67}' http://localhost:8550/ + + +**/ diff --git a/cmd/clef/pythonsigner.py b/cmd/clef/pythonsigner.py new file mode 100644 index 0000000000..46fa23bd8c --- /dev/null +++ b/cmd/clef/pythonsigner.py @@ -0,0 +1,179 @@ +import os,sys, subprocess +from tinyrpc.transports import ServerTransport +from tinyrpc.protocols.jsonrpc import JSONRPCProtocol +from tinyrpc.dispatch import public,RPCDispatcher +from tinyrpc.server import RPCServer + +""" This is a POC example of how to write a custom UI for Clef. The UI starts the +clef process with the '--stdio-ui' option, and communicates with clef using standard input / output. + +The standard input/output is a relatively secure way to communicate, as it does not require opening any ports +or IPC files. Needless to say, it does not protect against memory inspection mechanisms where an attacker +can access process memory.""" + +try: + import urllib.parse as urlparse +except ImportError: + import urllib as urlparse + +class StdIOTransport(ServerTransport): + """ Uses std input/output for RPC """ + def receive_message(self): + return None, urlparse.unquote(sys.stdin.readline()) + + def send_reply(self, context, reply): + print(reply) + +class PipeTransport(ServerTransport): + """ Uses std a pipe for RPC """ + + def __init__(self,input, output): + self.input = input + self.output = output + + def receive_message(self): + data = self.input.readline() + print(">> {}".format( data)) + return None, urlparse.unquote(data) + + def send_reply(self, context, reply): + print("<< {}".format( reply)) + self.output.write(reply) + self.output.write("\n") + +class StdIOHandler(): + + def __init__(self): + pass + + @public + def ApproveTx(self,req): + """ + Example request: + { + "jsonrpc": "2.0", + "method": "ApproveTx", + "params": [{ + "transaction": { + "to": "0xae967917c465db8578ca9024c205720b1a3651A9", + "gas": "0x333", + "gasPrice": "0x123", + "value": "0x10", + "data": "0xd7a5865800000000000000000000000000000000000000000000000000000000000000ff", + "nonce": "0x0" + }, + "from": "0xAe967917c465db8578ca9024c205720b1a3651A9", + "call_info": "Warning! Could not validate ABI-data against calldata\nSupplied ABI spec does not contain method signature in data: 0xd7a58658", + "meta": { + "remote": "127.0.0.1:34572", + "local": "localhost:8550", + "scheme": "HTTP/1.1" + } + }], + "id": 1 + } + + :param transaction: transaction info + :param call_info: info abou the call, e.g. if ABI info could not be + :param meta: metadata about the request, e.g. where the call comes from + :return: + """ + transaction = req.get('transaction') + _from = req.get('from') + call_info = req.get('call_info') + meta = req.get('meta') + + return { + "approved" : False, + #"transaction" : transaction, + # "from" : _from, +# "password" : None, + } + + @public + def ApproveSignData(self, req): + """ Example request + + """ + return {"approved": False, "password" : None} + + @public + def ApproveExport(self, req): + """ Example request + + """ + return {"approved" : False} + + @public + def ApproveImport(self, req): + """ Example request + + """ + return { "approved" : False, "old_password": "", "new_password": ""} + + @public + def ApproveListing(self, req): + """ Example request + + """ + return {'accounts': []} + + @public + def ApproveNewAccount(self, req): + """ + Example request + + :return: + """ + return {"approved": False, + #"password": "" + } + + @public + def ShowError(self,message = {}): + """ + Example request: + + {"jsonrpc":"2.0","method":"ShowInfo","params":{"message":"Testing 'ShowError'"},"id":1} + + :param message: to show + :return: nothing + """ + if 'text' in message.keys(): + sys.stderr.write("Error: {}\n".format( message['text'])) + return + + @public + def ShowInfo(self,message = {}): + """ + Example request + {"jsonrpc":"2.0","method":"ShowInfo","params":{"message":"Testing 'ShowInfo'"},"id":0} + + :param message: to display + :return:nothing + """ + + if 'text' in message.keys(): + sys.stdout.write("Error: {}\n".format( message['text'])) + return + +def main(args): + + cmd = ["./clef", "--stdio-ui"] + if len(args) > 0 and args[0] == "test": + cmd.extend(["--stdio-ui-test"]) + print("cmd: {}".format(" ".join(cmd))) + dispatcher = RPCDispatcher() + dispatcher.register_instance(StdIOHandler(), '') + # line buffered + p = subprocess.Popen(cmd, bufsize=1, universal_newlines=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE) + + rpc_server = RPCServer( + PipeTransport(p.stdout, p.stdin), + JSONRPCProtocol(), + dispatcher + ) + rpc_server.serve_forever() + +if __name__ == '__main__': + main(sys.argv[1:]) diff --git a/cmd/clef/rules.md b/cmd/clef/rules.md new file mode 100644 index 0000000000..327ba765c5 --- /dev/null +++ b/cmd/clef/rules.md @@ -0,0 +1,236 @@ +# Rules + +The `signer` binary contains a ruleset engine, implemented with [OttoVM](https://github.com/robertkrimen/otto) + +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; + +1. Rule Implementation: how to create, manage and interpret rules in a flexible but secure manner +2. Credential managements and credentials; how to provide auto-unlock without exposing keys unnecessarily. + +The section below deals with both of them + +## Rule Implementation + +A ruleset file is implemented as a `js` file. Under the hood, the ruleset-engine is a `SignerUI`, implementing the same methods as the `json-rpc` methods +defined in the UI protocol. Example: + +```javascript + +function asBig(str){ + if(str.slice(0,2) == "0x"){ return new BigNumber(str.slice(2),16)} + return new BigNumber(str) +} + +// Approve transactions to a certain contract if value is below a certain limit +function ApproveTx(req){ + + var limit = big.Newint("0xb1a2bc2ec50000") + var value = asBig(req.transaction.value); + + if(req.transaction.to.toLowerCase()=="0xae967917c465db8578ca9024c205720b1a3651a9") + && value.lt(limit) ){ + return "Approve" + } + // If we return "Reject", it will be rejected. + // By not returning anything, it will be passed to the next UI, for manual processing +} + +//Approve listings if request made from IPC +function ApproveListing(req){ + if (req.metadata.scheme == "ipc"){ return "Approve"} +} + +``` + +Whenever the external API is called (and the ruleset is enabled), the `signer` calls the UI, which is an instance of a ruleset-engine. The ruleset-engine +invokes the corresponding method. In doing so, there are three possible outcomes: + +1. JS returns "Approve" + * Auto-approve request +2. JS returns "Reject" + * Auto-reject request +3. Error occurs, or something else is returned + * Pass on to `next` ui: the regular UI channel. + +A more advanced example can be found below, "Example 1: ruleset for a rate-limited window", using `storage` to `Put` and `Get` `string`s by key. + +* At the time of writing, storage only exists as an ephemeral unencrypted implementation, to be used during testing. + +### Things to note + +The Otto vm has a few [caveats](https://github.com/robertkrimen/otto): + +* "use strict" will parse, but does nothing. +* The regular expression engine (re2/regexp) is not fully compatible with the ECMA5 specification. +* Otto targets ES5. ES6 features (eg: Typed Arrays) are not supported. + +Additionally, a few more have been added + +* The rule execution cannot load external javascript files. +* The only preloaded libary is [`bignumber.js`](https://github.com/MikeMcl/bignumber.js) version `2.0.3`. This one is fairly old, and is not aligned with the documentation at the github repository. +* Each invocation is made in a fresh virtual machine. This means that you cannot store data in global variables between invocations. This is a deliberate choice -- if you want to store data, use the disk-backed `storage`, since rules should not rely on ephemeral data. +* Javascript API parameters are _always_ an object. This is also a design choice, to ensure that parameters are accessed by _key_ and not by order. This is to prevent mistakes due to missing parameters or parameter changes. +* The JS engine has access to `storage` and `console`. + +#### Security considerations + +##### Security of ruleset + +Some security precautions can be made, such as: + +* Never load `ruleset.js` unless the file is `readonly` (`r-??-??-?`). If the user wishes to modify the ruleset, he must make it writeable and then set back to readonly. + * This is to prevent attacks where files are dropped on the users disk. +* Since we're going to have to have some form of secure storage (not defined in this section), we could also store the `sha3` of the `ruleset.js` file in there. + * If the user wishes to modify the ruleset, he'd then have to perform e.g. `signer --attest /path/to/ruleset --credential ` + +##### Security of implementation + +The drawbacks of this very flexible solution is that the `signer` needs to contain a javascript engine. This is pretty simple to implement, since it's already +implemented for `geth`. There are no known security vulnerabilities in, nor have we had any security-problems with it so far. + +The javascript engine would be an added attack surface; but if the validation of `rulesets` is made good (with hash-based attestation), the actual javascript cannot be considered +an attack surface -- if an attacker can control the ruleset, a much simpler attack would be to implement an "always-approve" rule instead of exploiting the js vm. The only benefit +to be gained from attacking the actual `signer` process from the `js` side would be if it could somehow extract cryptographic keys from memory. + +##### Security in usability + +Javascript is flexible, but also easy to get wrong, especially when users assume that `js` can handle large integers natively. Typical errors +include trying to multiply `gasCost` with `gas` without using `bigint`:s. + +It's unclear whether any other DSL could be more secure; since there's always the possibility of erroneously implementing a rule. + + +## Credential management + +The ability to auto-approve transaction means that the signer needs to have necessary credentials to decrypt keyfiles. These passwords are hereafter called `ksp` (keystore pass). + +### Example implementation + +Upon startup of the signer, the signer is given a switch: `--seed ` +The `seed` contains a blob of bytes, which is the master seed for the `signer`. + +The `signer` uses the `seed` to: + +* Generate the `path` where the settings are stored. + * `./settings/1df094eb-c2b1-4689-90dd-790046d38025/vault.dat` + * `./settings/1df094eb-c2b1-4689-90dd-790046d38025/rules.js` +* Generate the encryption password for `vault.dat`. + +The `vault.dat` would be an encrypted container storing the following information: + +* `ksp` entries +* `sha256` hash of `rules.js` +* Information about pair:ed callers (not yet specified) + +### Security considerations + +This would leave it up to the user to ensure that the `path/to/masterseed` is handled in a secure way. It's difficult to get around this, although one could +imagine leveraging OS-level keychains where supported. The setup is however in general similar to how ssh-keys are stored in `.ssh/`. + + +# Implementation status + +This is now implemented (with ephemeral non-encrypted storage for now, so not yet enabled). + +## Example 1: ruleset for a rate-limited window + + +```javascript + + function big(str){ + if(str.slice(0,2) == "0x"){ return new BigNumber(str.slice(2),16)} + return new BigNumber(str) + } + + // Time window: 1 week + var window = 1000* 3600*24*7; + + // Limit : 1 ether + var limit = new BigNumber("1e18"); + + function isLimitOk(transaction){ + var value = big(transaction.value) + // Start of our window function + var windowstart = new Date().getTime() - window; + + var txs = []; + var stored = storage.Get('txs'); + + if(stored != ""){ + txs = JSON.parse(stored) + } + // First, remove all that have passed out of the time-window + var newtxs = txs.filter(function(tx){return tx.tstamp > windowstart}); + console.log(txs, newtxs.length); + + // Secondly, aggregate the current sum + sum = new BigNumber(0) + + sum = newtxs.reduce(function(agg, tx){ return big(tx.value).plus(agg)}, sum); + console.log("ApproveTx > Sum so far", sum); + console.log("ApproveTx > Requested", value.toNumber()); + + // Would we exceed weekly limit ? + return sum.plus(value).lt(limit) + + } + function ApproveTx(r){ + if (isLimitOk(r.transaction)){ + return "Approve" + } + return "Nope" + } + + /** + * OnApprovedTx(str) is called when a transaction has been approved and signed. The parameter + * 'response_str' contains the return value that will be sent to the external caller. + * The return value from this method is ignore - the reason for having this callback is to allow the + * ruleset to keep track of approved transactions. + * + * When implementing rate-limited rules, this callback should be used. + * If a rule responds with neither 'Approve' nor 'Reject' - the tx goes to manual processing. If the user + * then accepts the transaction, this method will be called. + * + * TLDR; Use this method to keep track of signed transactions, instead of using the data in ApproveTx. + */ + function OnApprovedTx(resp){ + var value = big(resp.tx.value) + var txs = [] + // Load stored transactions + var stored = storage.Get('txs'); + if(stored != ""){ + txs = JSON.parse(stored) + } + // Add this to the storage + txs.push({tstamp: new Date().getTime(), value: value}); + storage.Put("txs", JSON.stringify(txs)); + } + +``` + +## Example 2: allow destination + +```javascript + + function ApproveTx(r){ + if(r.transaction.from.toLowerCase()=="0x0000000000000000000000000000000000001337"){ return "Approve"} + if(r.transaction.from.toLowerCase()=="0x000000000000000000000000000000000000dead"){ return "Reject"} + // Otherwise goes to manual processing + } + +``` + +## Example 3: Allow listing + +```javascript + + function ApproveListing(){ + return "Approve" + } + +``` \ No newline at end of file diff --git a/cmd/clef/sign_flow.png b/cmd/clef/sign_flow.png new file mode 100644 index 0000000000..9c0f3cc5d5 Binary files /dev/null and b/cmd/clef/sign_flow.png differ diff --git a/cmd/clef/tutorial.md b/cmd/clef/tutorial.md new file mode 100644 index 0000000000..d59e08ac7a --- /dev/null +++ b/cmd/clef/tutorial.md @@ -0,0 +1,198 @@ +## Initializing the signer + +First, initialize the master seed. + +```text +#./signer init + +WARNING! + +The signer is alpha software, and not yet publically released. This software has _not_ been audited, and there +are no guarantees about the workings of this software. It may contain severe flaws. You should not use this software +unless you agree to take full responsibility for doing so, and know what you are doing. + +TLDR; THIS IS NOT PRODUCTION-READY SOFTWARE! + + +Enter 'ok' to proceed: +>ok +A master seed has been generated into /home/martin/.signer/secrets.dat + +This is required to be able to store credentials, such as : +* Passwords for keystores (used by rule engine) +* Storage for javascript rules +* Hash of rule-file + +You should treat that file with utmost secrecy, and make a backup of it. +NOTE: This file does not contain your accounts. Those need to be backed up separately! +``` + +(for readability purposes, we'll remove the WARNING printout in the rest of this document) + +## Creating rules + +Now, you can create a rule-file. + +```javascript +function ApproveListing(){ + return "Approve" +} +``` +Get the `sha256` hash.... +```text +#sha256sum rules.js +6c21d1737429d6d4f2e55146da0797782f3c0a0355227f19d702df377c165d72 rules.js +``` +...And then `attest` the file: +```text +#./signer attest 6c21d1737429d6d4f2e55146da0797782f3c0a0355227f19d702df377c165d72 + +INFO [02-21|12:14:38] Ruleset attestation updated sha256=6c21d1737429d6d4f2e55146da0797782f3c0a0355227f19d702df377c165d72 +``` +At this point, we then start the signer with the rule-file: + +```text +#./signer --rules rules.json + +INFO [02-21|12:15:18] Using CLI as UI-channel +INFO [02-21|12:15:18] Loaded 4byte db signatures=5509 file=./4byte.json +INFO [02-21|12:15:18] Could not load rulefile, rules not enabled file=rulefile +DEBUG[02-21|12:15:18] FS scan times list=35.335µs set=5.536µs diff=5.073µs +DEBUG[02-21|12:15:18] Ledger support enabled +DEBUG[02-21|12:15:18] Trezor support enabled +INFO [02-21|12:15:18] Audit logs configured file=audit.log +INFO [02-21|12:15:18] HTTP endpoint opened url=http://localhost:8550 +------- Signer info ------- +* extapi_http : http://localhost:8550 +* extapi_ipc : +* extapi_version : 2.0.0 +* intapi_version : 1.2.0 + +``` + +Any list-requests will now be auto-approved by our rule-file. + +## Under the hood + +While doing the operations above, these files have been created: + +```text +#ls -laR ~/.signer/ +/home/martin/.signer/: +total 16 +drwx------ 3 martin martin 4096 feb 21 12:14 . +drwxr-xr-x 71 martin martin 4096 feb 21 12:12 .. +drwx------ 2 martin martin 4096 feb 21 12:14 43f73718397aa54d1b22 +-rwx------ 1 martin martin 256 feb 21 12:12 secrets.dat + +/home/martin/.signer/43f73718397aa54d1b22: +total 12 +drwx------ 2 martin martin 4096 feb 21 12:14 . +drwx------ 3 martin martin 4096 feb 21 12:14 .. +-rw------- 1 martin martin 159 feb 21 12:14 config.json + +#cat /home/martin/.signer/43f73718397aa54d1b22/config.json +{"ruleset_sha256":{"iv":"6v4W4tfJxj3zZFbl","c":"6dt5RTDiTq93yh1qDEjpsat/tsKG7cb+vr3sza26IPL2fvsQ6ZoqFx++CPUa8yy6fD9Bbq41L01ehkKHTG3pOAeqTW6zc/+t0wv3AB6xPmU="}} + +``` + +In `~/.signer`, the `secrets.dat` file was created, containing the `master_seed`. +The `master_seed` was then used to derive a few other things: + +- `vault_location` : in this case `43f73718397aa54d1b22` . + - Thus, if you use a different `master_seed`, another `vault_location` will be used that does not conflict with each other. + - Example: `signer --signersecret /path/to/afile ...` +- `config.json` which is the encrypted key/value storage for configuration data, containing the key `ruleset_sha256`. + + +## Adding credentials + +In order to make more useful rules; sign transactions, the signer needs access to the passwords needed to unlock keystores. + +```text +#./signer addpw 0x694267f14675d7e1b9494fd8d72fefe1755710fa test + +INFO [02-21|13:43:21] Credential store updated key=0x694267f14675d7e1b9494fd8d72fefe1755710fa +``` +## More advanced rules + +Now let's update the rules to make use of credentials + +```javascript +function ApproveListing(){ + return "Approve" +} +function ApproveSignData(r){ + if( r.address.toLowerCase() == "0x694267f14675d7e1b9494fd8d72fefe1755710fa") + { + if(r.message.indexOf("bazonk") >= 0){ + return "Approve" + } + return "Reject" + } + // Otherwise goes to manual processing +} + +``` +In this example, +* any requests to sign data with the account `0x694...` will be + * auto-approved if the message contains with `bazonk`, + * and auto-rejected if it does not. + * Any other signing-requests will be passed along for manual approve/reject. + +..attest the new file +```text +#sha256sum rules.js +2a0cb661dacfc804b6e95d935d813fd17c0997a7170e4092ffbc34ca976acd9f rules.js + +#./signer attest 2a0cb661dacfc804b6e95d935d813fd17c0997a7170e4092ffbc34ca976acd9f + +INFO [02-21|14:36:30] Ruleset attestation updated sha256=2a0cb661dacfc804b6e95d935d813fd17c0997a7170e4092ffbc34ca976acd9f +``` + +And start the signer: + +``` +#./signer --rules rules.js + +INFO [02-21|14:41:56] Using CLI as UI-channel +INFO [02-21|14:41:56] Loaded 4byte db signatures=5509 file=./4byte.json +INFO [02-21|14:41:56] Rule engine configured file=rules.js +DEBUG[02-21|14:41:56] FS scan times list=34.607µs set=4.509µs diff=4.87µs +DEBUG[02-21|14:41:56] Ledger support enabled +DEBUG[02-21|14:41:56] Trezor support enabled +INFO [02-21|14:41:56] Audit logs configured file=audit.log +INFO [02-21|14:41:56] HTTP endpoint opened url=http://localhost:8550 +------- Signer info ------- +* extapi_version : 2.0.0 +* intapi_version : 1.2.0 +* extapi_http : http://localhost:8550 +* extapi_ipc : +INFO [02-21|14:41:56] error occurred during execution error="ReferenceError: 'OnSignerStartup' is not defined" +``` +And then test signing, once with `bazonk` and once without: + +``` +#curl -H "Content-Type: application/json" -X POST --data "{\"jsonrpc\":\"2.0\",\"method\":\"account_sign\",\"params\":[\"0x694267f14675d7e1b9494fd8d72fefe1755710fa\",\"0x$(xxd -pu <<< ' bazonk baz gaz')\"],\"id\":67}" http://localhost:8550/ +{"jsonrpc":"2.0","id":67,"result":"0x93e6161840c3ae1efc26dc68dedab6e8fc233bb3fefa1b4645dbf6609b93dace160572ea4ab33240256bb6d3dadb60dcd9c515d6374d3cf614ee897408d41d541c"} + +#curl -H "Content-Type: application/json" -X POST --data "{\"jsonrpc\":\"2.0\",\"method\":\"account_sign\",\"params\":[\"0x694267f14675d7e1b9494fd8d72fefe1755710fa\",\"0x$(xxd -pu <<< ' bonk baz gaz')\"],\"id\":67}" http://localhost:8550/ +{"jsonrpc":"2.0","id":67,"error":{"code":-32000,"message":"Request denied"}} + +``` + +Meanwhile, in the signer output: +```text +INFO [02-21|14:42:41] Op approved +INFO [02-21|14:42:56] Op rejected +``` + +The signer also stores all traffic over the external API in a log file. The last 4 lines shows the two requests and their responses: + +```text +#tail audit.log -n 4 +t=2018-02-21T14:42:41+0100 lvl=info msg=Sign api=signer type=request metadata="{\"remote\":\"127.0.0.1:49706\",\"local\":\"localhost:8550\",\"scheme\":\"HTTP/1.1\"}" addr="0x694267f14675d7e1b9494fd8d72fefe1755710fa [chksum INVALID]" data=202062617a6f6e6b2062617a2067617a0a +t=2018-02-21T14:42:42+0100 lvl=info msg=Sign api=signer type=response data=93e6161840c3ae1efc26dc68dedab6e8fc233bb3fefa1b4645dbf6609b93dace160572ea4ab33240256bb6d3dadb60dcd9c515d6374d3cf614ee897408d41d541c error=nil +t=2018-02-21T14:42:56+0100 lvl=info msg=Sign api=signer type=request metadata="{\"remote\":\"127.0.0.1:49708\",\"local\":\"localhost:8550\",\"scheme\":\"HTTP/1.1\"}" addr="0x694267f14675d7e1b9494fd8d72fefe1755710fa [chksum INVALID]" data=2020626f6e6b2062617a2067617a0a +t=2018-02-21T14:42:56+0100 lvl=info msg=Sign api=signer type=response data= error="Request denied" +``` diff --git a/cmd/ethkey/changepassphrase.go b/cmd/ethkey/changepassphrase.go new file mode 100644 index 0000000000..d1ae2ae0d8 --- /dev/null +++ b/cmd/ethkey/changepassphrase.go @@ -0,0 +1,72 @@ +package main + +import ( + "fmt" + "io/ioutil" + "strings" + + "github.com/ethereum/go-ethereum/accounts/keystore" + "github.com/ethereum/go-ethereum/cmd/utils" + "gopkg.in/urfave/cli.v1" +) + +var newPassphraseFlag = cli.StringFlag{ + Name: "newpasswordfile", + Usage: "the file that contains the new passphrase for the keyfile", +} + +var commandChangePassphrase = cli.Command{ + Name: "changepassphrase", + Usage: "change the passphrase on a keyfile", + ArgsUsage: "", + Description: ` +Change the passphrase of a keyfile.`, + Flags: []cli.Flag{ + passphraseFlag, + newPassphraseFlag, + }, + Action: func(ctx *cli.Context) error { + keyfilepath := ctx.Args().First() + + // Read key from file. + keyjson, err := ioutil.ReadFile(keyfilepath) + if err != nil { + utils.Fatalf("Failed to read the keyfile at '%s': %v", keyfilepath, err) + } + + // Decrypt key with passphrase. + passphrase := getPassphrase(ctx) + key, err := keystore.DecryptKey(keyjson, passphrase) + if err != nil { + utils.Fatalf("Error decrypting key: %v", err) + } + + // Get a new passphrase. + fmt.Println("Please provide a new passphrase") + var newPhrase string + if passFile := ctx.String(newPassphraseFlag.Name); passFile != "" { + content, err := ioutil.ReadFile(passFile) + if err != nil { + utils.Fatalf("Failed to read new passphrase file '%s': %v", passFile, err) + } + newPhrase = strings.TrimRight(string(content), "\r\n") + } else { + newPhrase = promptPassphrase(true) + } + + // Encrypt the key with the new passphrase. + newJson, err := keystore.EncryptKey(key, newPhrase, keystore.StandardScryptN, keystore.StandardScryptP) + if err != nil { + utils.Fatalf("Error encrypting with new passphrase: %v", err) + } + + // Then write the new keyfile in place of the old one. + if err := ioutil.WriteFile(keyfilepath, newJson, 600); err != nil { + utils.Fatalf("Error writing new keyfile to disk: %v", err) + } + + // Don't print anything. Just return successfully, + // producing a positive exit code. + return nil + }, +} diff --git a/cmd/ethkey/generate.go b/cmd/ethkey/generate.go index 6d57d17fb4..fe9a0c1519 100644 --- a/cmd/ethkey/generate.go +++ b/cmd/ethkey/generate.go @@ -90,7 +90,7 @@ If you want to encrypt an existing private key, it can be specified by setting } // Encrypt key with passphrase. - passphrase := getPassPhrase(ctx, true) + passphrase := promptPassphrase(true) keyjson, err := keystore.EncryptKey(key, passphrase, keystore.StandardScryptN, keystore.StandardScryptP) if err != nil { utils.Fatalf("Error encrypting key: %v", err) diff --git a/cmd/ethkey/inspect.go b/cmd/ethkey/inspect.go index dbf5afc0ce..ba03d4d936 100644 --- a/cmd/ethkey/inspect.go +++ b/cmd/ethkey/inspect.go @@ -60,7 +60,7 @@ make sure to use this feature with great caution!`, } // Decrypt key with passphrase. - passphrase := getPassPhrase(ctx, false) + passphrase := getPassphrase(ctx) key, err := keystore.DecryptKey(keyjson, passphrase) if err != nil { utils.Fatalf("Error decrypting key: %v", err) diff --git a/cmd/ethkey/main.go b/cmd/ethkey/main.go index 2a9e5ee483..c434da0c05 100644 --- a/cmd/ethkey/main.go +++ b/cmd/ethkey/main.go @@ -38,6 +38,7 @@ func init() { app.Commands = []cli.Command{ commandGenerate, commandInspect, + commandChangePassphrase, commandSignMessage, commandVerifyMessage, } @@ -53,10 +54,6 @@ var ( Name: "json", Usage: "output JSON instead of human-readable format", } - messageFlag = cli.StringFlag{ - Name: "message", - Usage: "the file that contains the message to sign/verify", - } ) func main() { diff --git a/cmd/ethkey/message.go b/cmd/ethkey/message.go index 531a931c82..5caea69ff6 100644 --- a/cmd/ethkey/message.go +++ b/cmd/ethkey/message.go @@ -62,7 +62,7 @@ To sign a message contained in a file, use the --msgfile flag. } // Decrypt key with passphrase. - passphrase := getPassPhrase(ctx, false) + passphrase := getPassphrase(ctx) key, err := keystore.DecryptKey(keyjson, passphrase) if err != nil { utils.Fatalf("Error decrypting key: %v", err) diff --git a/cmd/ethkey/utils.go b/cmd/ethkey/utils.go index 0e563bf922..6f60ebaf1b 100644 --- a/cmd/ethkey/utils.go +++ b/cmd/ethkey/utils.go @@ -28,11 +28,32 @@ import ( "gopkg.in/urfave/cli.v1" ) -// getPassPhrase obtains a passphrase given by the user. It first checks the -// --passphrase command line flag and ultimately prompts the user for a +// promptPassphrase prompts the user for a passphrase. Set confirmation to true +// to require the user to confirm the passphrase. +func promptPassphrase(confirmation bool) string { + passphrase, err := console.Stdin.PromptPassword("Passphrase: ") + if err != nil { + utils.Fatalf("Failed to read passphrase: %v", err) + } + + if confirmation { + confirm, err := console.Stdin.PromptPassword("Repeat passphrase: ") + if err != nil { + utils.Fatalf("Failed to read passphrase confirmation: %v", err) + } + if passphrase != confirm { + utils.Fatalf("Passphrases do not match") + } + } + + return passphrase +} + +// getPassphrase obtains a passphrase given by the user. It first checks the +// --passfile command line flag and ultimately prompts the user for a // passphrase. -func getPassPhrase(ctx *cli.Context, confirmation bool) string { - // Look for the --passphrase flag. +func getPassphrase(ctx *cli.Context) string { + // Look for the --passwordfile flag. passphraseFile := ctx.String(passphraseFlag.Name) if passphraseFile != "" { content, err := ioutil.ReadFile(passphraseFile) @@ -44,20 +65,7 @@ func getPassPhrase(ctx *cli.Context, confirmation bool) string { } // Otherwise prompt the user for the passphrase. - passphrase, err := console.Stdin.PromptPassword("Passphrase: ") - if err != nil { - utils.Fatalf("Failed to read passphrase: %v", err) - } - if confirmation { - confirm, err := console.Stdin.PromptPassword("Repeat passphrase: ") - if err != nil { - utils.Fatalf("Failed to read passphrase confirmation: %v", err) - } - if passphrase != confirm { - utils.Fatalf("Passphrases do not match") - } - } - return passphrase + return promptPassphrase(false) } // signHash is a helper function that calculates a hash for the given message diff --git a/cmd/evm/compiler.go b/cmd/evm/compiler.go index c019a2fe70..f8aef2074c 100644 --- a/cmd/evm/compiler.go +++ b/cmd/evm/compiler.go @@ -50,6 +50,6 @@ func compileCmd(ctx *cli.Context) error { if err != nil { return err } - fmt.Println(bin) + fmt.Fprintln(ctx.App.Writer, bin) return nil } diff --git a/cmd/evm/disasm.go b/cmd/evm/disasm.go index 4a442cf784..0f3491818d 100644 --- a/cmd/evm/disasm.go +++ b/cmd/evm/disasm.go @@ -45,6 +45,6 @@ func disasmCmd(ctx *cli.Context) error { } code := strings.TrimSpace(string(in[:])) - fmt.Printf("%v\n", code) + fmt.Fprintf(ctx.App.Writer, "%v\n", code) return asm.PrintDisassembled(code) } diff --git a/cmd/evm/internal/compiler/compiler.go b/cmd/evm/internal/compiler/compiler.go index 753ca62264..a2abc8f7da 100644 --- a/cmd/evm/internal/compiler/compiler.go +++ b/cmd/evm/internal/compiler/compiler.go @@ -30,10 +30,11 @@ func Compile(fn string, src []byte, debug bool) (string, error) { bin, compileErrors := compiler.Compile() if len(compileErrors) > 0 { // report errors + errs := "" for _, err := range compileErrors { - fmt.Printf("%s:%v\n", fn, err) + errs += fmt.Sprintf("%s:%v\n", fn, err) } - return "", errors.New("compiling failed") + return "", errors.New(errs + "compiling failed\n") } return bin, nil } diff --git a/cmd/evm/json_logger.go b/cmd/evm/json_logger.go index 0e7a911896..f16424fbe6 100644 --- a/cmd/evm/json_logger.go +++ b/cmd/evm/json_logger.go @@ -32,6 +32,8 @@ type JSONLogger struct { cfg *vm.LogConfig } +// NewJSONLogger creates a new EVM tracer that prints execution steps as JSON objects +// into the provided stream. func NewJSONLogger(cfg *vm.LogConfig, writer io.Writer) *JSONLogger { return &JSONLogger{json.NewEncoder(writer), cfg} } diff --git a/cmd/evm/runner.go b/cmd/evm/runner.go index 8a7399840c..fed41f53a1 100644 --- a/cmd/evm/runner.go +++ b/cmd/evm/runner.go @@ -21,12 +21,12 @@ import ( "encoding/json" "fmt" "io/ioutil" + "math/big" "os" + goruntime "runtime" "runtime/pprof" "time" - goruntime "runtime" - "github.com/ethereum/go-ethereum/cmd/evm/internal/compiler" "github.com/ethereum/go-ethereum/cmd/utils" "github.com/ethereum/go-ethereum/common" @@ -76,6 +76,7 @@ func runCmd(ctx *cli.Context) error { logconfig := &vm.LogConfig{ DisableMemory: ctx.GlobalBool(DisableMemoryFlag.Name), DisableStack: ctx.GlobalBool(DisableStackFlag.Name), + Debug: ctx.GlobalBool(DebugFlag.Name), } var ( @@ -83,8 +84,9 @@ func runCmd(ctx *cli.Context) error { debugLogger *vm.StructLogger statedb *state.StateDB chainConfig *params.ChainConfig - sender = common.StringToAddress("sender") - receiver = common.StringToAddress("receiver") + sender = common.BytesToAddress([]byte("sender")) + receiver = common.BytesToAddress([]byte("receiver")) + blockNumber uint64 ) if ctx.GlobalBool(MachineFlag.Name) { tracer = NewJSONLogger(logconfig, os.Stdout) @@ -96,13 +98,13 @@ func runCmd(ctx *cli.Context) error { } if ctx.GlobalString(GenesisFlag.Name) != "" { gen := readGenesis(ctx.GlobalString(GenesisFlag.Name)) - db, _ := ethdb.NewMemDatabase() + db := ethdb.NewMemDatabase() genesis := gen.ToBlock(db) statedb, _ = state.New(genesis.Root(), state.NewDatabase(db)) chainConfig = gen.Config + blockNumber = gen.Number } else { - db, _ := ethdb.NewMemDatabase() - statedb, _ = state.New(common.Hash{}, state.NewDatabase(db)) + statedb, _ = state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) } if ctx.GlobalString(SenderFlag.Name) != "" { sender = common.HexToAddress(ctx.GlobalString(SenderFlag.Name)) @@ -126,13 +128,13 @@ func runCmd(ctx *cli.Context) error { if ctx.GlobalString(CodeFileFlag.Name) == "-" { //Try reading from stdin if hexcode, err = ioutil.ReadAll(os.Stdin); err != nil { - fmt.Printf("Could not load code from stdin: %v\n", err) + fmt.Fprintf(ctx.App.ErrWriter, "Could not load code from stdin: %v\n", err) os.Exit(1) } } else { // Codefile with hex assembly if hexcode, err = ioutil.ReadFile(ctx.GlobalString(CodeFileFlag.Name)); err != nil { - fmt.Printf("Could not load code from file: %v\n", err) + fmt.Fprintf(ctx.App.ErrWriter, "Could not load code from file: %v\n", err) os.Exit(1) } } @@ -155,11 +157,12 @@ func runCmd(ctx *cli.Context) error { initialGas := ctx.GlobalUint64(GasFlag.Name) runtimeConfig := runtime.Config{ - Origin: sender, - State: statedb, - GasLimit: initialGas, - GasPrice: utils.GlobalBig(ctx, PriceFlag.Name), - Value: utils.GlobalBig(ctx, ValueFlag.Name), + Origin: sender, + State: statedb, + GasLimit: initialGas, + GasPrice: utils.GlobalBig(ctx, PriceFlag.Name), + Value: utils.GlobalBig(ctx, ValueFlag.Name), + BlockNumber: new(big.Int).SetUint64(blockNumber), EVMConfig: vm.Config{ Tracer: tracer, Debug: ctx.GlobalBool(DebugFlag.Name) || ctx.GlobalBool(MachineFlag.Name), @@ -169,11 +172,11 @@ func runCmd(ctx *cli.Context) error { if cpuProfilePath := ctx.GlobalString(CPUProfileFlag.Name); cpuProfilePath != "" { f, err := os.Create(cpuProfilePath) if err != nil { - fmt.Println("could not create CPU profile: ", err) + fmt.Fprintf(ctx.App.ErrWriter, "could not create CPU profile: %v\n", err) os.Exit(1) } if err := pprof.StartCPUProfile(f); err != nil { - fmt.Println("could not start CPU profile: ", err) + fmt.Fprintf(ctx.App.ErrWriter, "could not start CPU profile: %v\n", err) os.Exit(1) } defer pprof.StopCPUProfile() @@ -197,17 +200,17 @@ func runCmd(ctx *cli.Context) error { if ctx.GlobalBool(DumpFlag.Name) { statedb.IntermediateRoot(true) - fmt.Println(string(statedb.Dump())) + fmt.Fprintln(ctx.App.Writer, string(statedb.Dump())) } if memProfilePath := ctx.GlobalString(MemProfileFlag.Name); memProfilePath != "" { f, err := os.Create(memProfilePath) if err != nil { - fmt.Println("could not create memory profile: ", err) + fmt.Fprintf(ctx.App.ErrWriter, "could not create memory profile: %v\n", err) os.Exit(1) } if err := pprof.WriteHeapProfile(f); err != nil { - fmt.Println("could not write memory profile: ", err) + fmt.Fprintf(ctx.App.ErrWriter, "could not create memory profile: %v\n", err) os.Exit(1) } f.Close() @@ -215,17 +218,17 @@ func runCmd(ctx *cli.Context) error { if ctx.GlobalBool(DebugFlag.Name) { if debugLogger != nil { - fmt.Fprintln(os.Stderr, "#### TRACE ####") - vm.WriteTrace(os.Stderr, debugLogger.StructLogs()) + fmt.Fprintln(ctx.App.ErrWriter, "#### TRACE ####") + vm.WriteTrace(ctx.App.ErrWriter, debugLogger.StructLogs()) } - fmt.Fprintln(os.Stderr, "#### LOGS ####") - vm.WriteLogs(os.Stderr, statedb.Logs()) + fmt.Fprintln(ctx.App.ErrWriter, "#### LOGS ####") + vm.WriteLogs(ctx.App.ErrWriter, statedb.Logs()) } if ctx.GlobalBool(StatDumpFlag.Name) { var mem goruntime.MemStats goruntime.ReadMemStats(&mem) - fmt.Fprintf(os.Stderr, `evm execution time: %v + fmt.Fprintf(ctx.App.ErrWriter, `evm execution time: %v heap objects: %d allocations: %d total allocations: %d @@ -234,12 +237,10 @@ Gas used: %d `, execTime, mem.HeapObjects, mem.Alloc, mem.TotalAlloc, mem.NumGC, initialGas-leftOverGas) } - if tracer != nil { - tracer.CaptureEnd(ret, initialGas-leftOverGas, execTime, err) - } else { - fmt.Printf("0x%x\n", ret) + if tracer == nil { + fmt.Fprintf(ctx.App.Writer, "0x%x\n", ret) if err != nil { - fmt.Printf(" error: %v\n", err) + fmt.Fprintf(ctx.App.ErrWriter, " error: %v\n", err) } } diff --git a/cmd/evm/staterunner.go b/cmd/evm/staterunner.go index 071ea94ad0..bee1b34dcc 100644 --- a/cmd/evm/staterunner.go +++ b/cmd/evm/staterunner.go @@ -38,6 +38,8 @@ var stateTestCommand = cli.Command{ ArgsUsage: "", } +// StatetestResult contains the execution status after running a state test, any +// error that might have occurred and a dump of the final state if requested. type StatetestResult struct { Name string `json:"name"` Pass bool `json:"pass"` @@ -105,7 +107,7 @@ func stateTestCmd(ctx *cli.Context) error { } // print state root for evmlab tracing (already committed above, so no need to delete objects again if ctx.GlobalBool(MachineFlag.Name) && state != nil { - fmt.Fprintf(os.Stderr, "{\"stateRoot\": \"%x\"}\n", state.IntermediateRoot(false)) + fmt.Fprintf(ctx.App.ErrWriter, "{\"stateRoot\": \"%x\"}\n", state.IntermediateRoot(false)) } results = append(results, *result) @@ -113,13 +115,13 @@ func stateTestCmd(ctx *cli.Context) error { // Print any structured logs collected if ctx.GlobalBool(DebugFlag.Name) { if debugger != nil { - fmt.Fprintln(os.Stderr, "#### TRACE ####") - vm.WriteTrace(os.Stderr, debugger.StructLogs()) + fmt.Fprintln(ctx.App.ErrWriter, "#### TRACE ####") + vm.WriteTrace(ctx.App.ErrWriter, debugger.StructLogs()) } } } } out, _ := json.MarshalIndent(results, "", " ") - fmt.Println(string(out)) + fmt.Fprintln(ctx.App.Writer, string(out)) return nil } diff --git a/cmd/faucet/faucet.go b/cmd/faucet/faucet.go index 503e80c0b5..894e6d915a 100644 --- a/cmd/faucet/faucet.go +++ b/cmd/faucet/faucet.go @@ -77,9 +77,6 @@ var ( accJSONFlag = flag.String("account.json", "", "Key json file to fund user requests with") accPassFlag = flag.String("account.pass", "", "Decryption password to access faucet funds") - githubUser = flag.String("github.user", "", "GitHub user to authenticate with for Gist access") - githubToken = flag.String("github.token", "", "GitHub personal token to access Gists with") - captchaToken = flag.String("captcha.token", "", "Recaptcha site key to authenticate client side") captchaSecret = flag.String("captcha.secret", "", "Recaptcha secret key to authenticate server side") @@ -216,7 +213,7 @@ func newFaucet(genesis *core.Genesis, port int, enodes []*discv5.Node, network u // Assemble the raw devp2p protocol stack stack, err := node.New(&node.Config{ Name: "XDC", - Version: params.Version, + Version: params.VersionWithMeta, DataDir: filepath.Join(os.Getenv("HOME"), ".faucet"), P2P: p2p.Config{ NAT: nat.Any(), @@ -474,7 +471,7 @@ func (f *faucet) apiHandler(conn *websocket.Conn) { amount = new(big.Int).Div(amount, new(big.Int).Exp(big.NewInt(2), big.NewInt(int64(msg.Tier)), nil)) tx := types.NewTransaction(f.nonce+uint64(len(f.reqs)), address, amount, 21000, f.price, nil) - signed, err := f.keystore.SignTx(f.account, tx, f.config.ChainId) + signed, err := f.keystore.SignTx(f.account, tx, f.config.ChainID) if err != nil { f.lock.Unlock() if err = sendError(conn, err); err != nil { @@ -638,59 +635,6 @@ func sendSuccess(conn *websocket.Conn, msg string) error { return send(conn, map[string]string{"success": msg}, time.Second) } -// authGitHub tries to authenticate a faucet request using GitHub gists, returning -// the username, avatar URL and Ethereum address to fund on success. -func authGitHub(url string) (string, string, common.Address, error) { - // Retrieve the gist from the GitHub Gist APIs - parts := strings.Split(url, "/") - req, _ := http.NewRequest("GET", "https://api.github.com/gists/"+parts[len(parts)-1], nil) - if *githubUser != "" { - req.SetBasicAuth(*githubUser, *githubToken) - } - res, err := http.DefaultClient.Do(req) - if err != nil { - return "", "", common.Address{}, err - } - var gist struct { - Owner struct { - Login string `json:"login"` - } `json:"owner"` - Files map[string]struct { - Content string `json:"content"` - } `json:"files"` - } - err = json.NewDecoder(res.Body).Decode(&gist) - res.Body.Close() - if err != nil { - return "", "", common.Address{}, err - } - if gist.Owner.Login == "" { - return "", "", common.Address{}, errors.New("Anonymous Gists not allowed") - } - // Iterate over all the files and look for Ethereum addresses - var address common.Address - for _, file := range gist.Files { - content := strings.TrimSpace(file.Content) - if len(content) == 2+common.AddressLength*2 { - address = common.HexToAddress(content) - } - } - if address == (common.Address{}) { - return "", "", common.Address{}, errors.New("No Ethereum address found to fund") - } - // Validate the user's existence since the API is unhelpful here - if res, err = http.Head("https://github.com/" + gist.Owner.Login); err != nil { - return "", "", common.Address{}, err - } - res.Body.Close() - - if res.StatusCode != 200 { - return "", "", common.Address{}, errors.New("Invalid user... boom!") - } - // Everything passed validation, return the gathered infos - return gist.Owner.Login + "@github", fmt.Sprintf("https://github.com/%s.png?size=64", gist.Owner.Login), address, nil -} - // authTwitter tries to authenticate a faucet request using Twitter posts, returning // the username, avatar URL and Ethereum address to fund on success. func authTwitter(url string) (string, string, common.Address, error) { diff --git a/cmd/gc/main.go b/cmd/gc/main.go deleted file mode 100644 index 6fdc25d87f..0000000000 --- a/cmd/gc/main.go +++ /dev/null @@ -1,270 +0,0 @@ -package main - -import ( - "flag" - "fmt" - "os" - "os/signal" - "runtime" - "sync" - "sync/atomic" - "time" - - "github.com/ethereum/go-ethereum/cmd/utils" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core" - "github.com/ethereum/go-ethereum/core/state" - "github.com/ethereum/go-ethereum/eth" - "github.com/ethereum/go-ethereum/ethdb" - "github.com/ethereum/go-ethereum/rlp" - "github.com/ethereum/go-ethereum/trie" - "github.com/hashicorp/golang-lru" - "github.com/syndtr/goleveldb/leveldb" - "github.com/syndtr/goleveldb/leveldb/util" -) - -var ( - dir = flag.String("dir", "", "directory to XDCChain chaindata") - cacheSize = flag.Int("size", 1000000, "LRU cache size") - sercureKey = []byte("secure-key-") - nWorker = runtime.NumCPU() / 2 - cleanAddress = []common.Address{common.HexToAddress(common.BlockSigners)} - cache *lru.Cache - finish = int32(0) - running = true - stateRoots = make(chan TrieRoot) -) - -type TrieRoot struct { - trie *trie.SecureTrie - number uint64 -} -type StateNode struct { - node trie.Node - path []byte -} -type ResultProcessNode struct { - index int - number int - newNodes [17]*StateNode - keys [17]*[]byte -} - -func main() { - flag.Parse() - lddb, _ := ethdb.NewLDBDatabase(*dir, eth.DefaultConfig.DatabaseCache, utils.MakeDatabaseHandles()) - head := core.GetHeadBlockHash(lddb) - currentHeader := core.GetHeader(lddb, head, core.GetBlockNumber(lddb, head)) - tridb := trie.NewDatabase(lddb) - catchEventInterupt(lddb.LDB()) - cache, _ = lru.New(*cacheSize) - go func() { - for i := uint64(1); i <= currentHeader.Number.Uint64(); i++ { - hash := core.GetCanonicalHash(lddb, i) - root := core.GetHeader(lddb, hash, i).Root - trieRoot, err := trie.NewSecure(root, tridb, 0) - if err != nil { - continue - } - if running { - stateRoots <- TrieRoot{trieRoot, i} - } else { - break - } - } - if running { - close(stateRoots) - } - }() - for trieRoot := range stateRoots { - atomic.StoreInt32(&finish, 1) - if running { - for _, address := range cleanAddress { - enc := trieRoot.trie.Get(address.Bytes()) - var data state.Account - rlp.DecodeBytes(enc, &data) - fmt.Println(time.Now().Format(time.RFC3339), "Start clean state address ", address.Hex(), " at block ", trieRoot.number) - signerRoot, err := resolveHash(data.Root[:], lddb.LDB()) - if err != nil { - fmt.Println(time.Now().Format(time.RFC3339), "Not found clean state address ", address.Hex(), " at block ", trieRoot.number) - continue - } - batch := new(leveldb.Batch) - count := 1 - list := []*StateNode{{node: signerRoot}} - for len(list) > 0 { - newList, total := findNewNodes(list, lddb.LDB(), batch) - count = count + 17*len(newList) - list = removeNodesNil(newList, total) - } - fmt.Println(time.Now().Format(time.RFC3339), "Finish clean state address ", address.Hex(), " at block ", trieRoot.number, " keys ", count) - err = lddb.LDB().Write(batch, nil) - if err != nil { - fmt.Println(time.Now().Format(time.RFC3339), "Write batch leveldb error", err) - os.Exit(1) - } - } - } else { - break - } - atomic.StoreInt32(&finish, 0) - } - fmt.Println(time.Now(), "compact") - lddb.LDB().CompactRange(util.Range{}) - lddb.Close() - fmt.Println(time.Now(), "end") -} - -func removeNodesNil(list [][17]*StateNode, length int) []*StateNode { - results := make([]*StateNode, length) - index := 0 - for _, nodes := range list { - for _, node := range nodes { - if node != nil { - results[index] = node - index++ - } - } - } - return results -} -func catchEventInterupt(db *leveldb.DB) { - c := make(chan os.Signal, 1) - signal.Notify(c, os.Interrupt) - go func() { - for sig := range c { - fmt.Println("catch event interrupt ", sig, running, finish) - running = false - if atomic.LoadInt32(&finish) == 0 { - close(stateRoots) - db.Close() - os.Exit(1) - } - } - }() -} -func resolveHash(n trie.HashNode, db *leveldb.DB) (trie.Node, error) { - if cache.Contains(common.BytesToHash(n)) { - return nil, &trie.MissingNodeError{} - } - enc, err := db.Get(n, nil) - if err != nil || enc == nil { - return nil, &trie.MissingNodeError{} - } - return trie.MustDecodeNode(n, enc, 0), nil -} - -func getAllChilds(n StateNode, db *leveldb.DB) ([17]*StateNode, error) { - childs := [17]*StateNode{} - switch node := n.node.(type) { - case *trie.FullNode: - // Full Node, move to the first non-nil child. - for i := 0; i < len(node.Children); i++ { - child := node.Children[i] - if child != nil { - childNode := child - var err error = nil - if _, ok := child.(trie.HashNode); ok { - childNode, err = resolveHash(child.(trie.HashNode), db) - } - if err == nil { - childs[i] = &StateNode{node: childNode, path: append(n.path, byte(i))} - } else if err != nil { - _, ok := err.(*trie.MissingNodeError) - if !ok { - return childs, err - } - } - } - } - case *trie.ShortNode: - // Short Node, return the pointer singleton child - childNode := node.Val - var err error = nil - if _, ok := node.Val.(trie.HashNode); ok { - childNode, err = resolveHash(node.Val.(trie.HashNode), db) - } - if err == nil { - childs[0] = &StateNode{node: childNode, path: append(n.path, node.Key...)} - } else if err != nil { - _, ok := err.(*trie.MissingNodeError) - if !ok { - return childs, err - } - } - } - return childs, nil -} -func processNodes(node StateNode, db *leveldb.DB) ([17]*StateNode, [17]*[]byte, int) { - hash, _ := node.node.Cache() - commonHash := common.BytesToHash(hash) - newNodes := [17]*StateNode{} - keys := [17]*[]byte{} - number := 0 - if !cache.Contains(commonHash) { - childNodes, err := getAllChilds(node, db) - if err != nil { - fmt.Println("Error when get all childs node : ", common.Bytes2Hex(node.path), err) - os.Exit(1) - } - for i, child := range childNodes { - if child != nil { - if _, ok := child.node.(trie.ValueNode); ok { - buf := append(sercureKey, child.path...) - keys[i] = &buf - } else { - hash, _ := child.node.Cache() - var bytes []byte = hash - keys[i] = &bytes - newNodes[i] = child - number++ - } - } - } - cache.Add(commonHash, true) - } - return newNodes, keys, number -} - -func findNewNodes(nodes []*StateNode, db *leveldb.DB, batchlvdb *leveldb.Batch) ([][17]*StateNode, int) { - length := len(nodes) - chunkSize := length / nWorker - if len(nodes)%nWorker != 0 { - chunkSize++ - } - childNodes := make([][17]*StateNode, length) - results := make(chan ResultProcessNode) - wg := sync.WaitGroup{} - wg.Add(length) - for i := 0; i < nWorker; i++ { - from := i * chunkSize - to := from + chunkSize - if to > length { - to = length - } - go func(from int, to int) { - for j := from; j < to; j++ { - childs, keys, number := processNodes(*nodes[j], db) - go func(result ResultProcessNode) { - results <- result - }(ResultProcessNode{j, number, childs, keys}) - } - }(from, to) - } - total := 0 - go func() { - for result := range results { - childNodes[result.index] = result.newNodes - total = total + result.number - for _, key := range result.keys { - if key != nil { - batchlvdb.Delete(*key) - } - } - wg.Done() - } - }() - wg.Wait() - close(results) - return childNodes, total -} diff --git a/cmd/p2psim/main.go b/cmd/p2psim/main.go index 0c8ed038d5..6604b671fc 100644 --- a/cmd/p2psim/main.go +++ b/cmd/p2psim/main.go @@ -180,7 +180,10 @@ func main() { }, }, } - app.Run(os.Args) + if err := app.Run(os.Args); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } } func showNetwork(ctx *cli.Context) error { @@ -275,9 +278,8 @@ func createNode(ctx *cli.Context) error { if len(ctx.Args()) != 0 { return cli.ShowCommandHelp(ctx, ctx.Command.Name) } - config := &adapters.NodeConfig{ - Name: ctx.String("name"), - } + config := adapters.RandomNodeConfig() + config.Name = ctx.String("name") if key := ctx.String("key"); key != "" { privKey, err := crypto.HexToECDSA(key) if err != nil { diff --git a/cmd/puppeth/genesis.go b/cmd/puppeth/genesis.go index 1974a94aa2..5f39a889d1 100644 --- a/cmd/puppeth/genesis.go +++ b/cmd/puppeth/genesis.go @@ -103,8 +103,8 @@ func newCppEthereumGenesisSpec(network string, genesis *core.Genesis) (*cppEther spec.Params.ByzantiumForkBlock = (hexutil.Uint64)(genesis.Config.ByzantiumBlock.Uint64()) spec.Params.ConstantinopleForkBlock = (hexutil.Uint64)(math.MaxUint64) - spec.Params.NetworkID = (hexutil.Uint64)(genesis.Config.ChainId.Uint64()) - spec.Params.ChainID = (hexutil.Uint64)(genesis.Config.ChainId.Uint64()) + spec.Params.NetworkID = (hexutil.Uint64)(genesis.Config.ChainID.Uint64()) + spec.Params.ChainID = (hexutil.Uint64)(genesis.Config.ChainID.Uint64()) spec.Params.MaximumExtraDataSize = (hexutil.Uint64)(params.MaximumExtraDataSize) spec.Params.MinGasLimit = (hexutil.Uint64)(params.MinGasLimit) @@ -284,7 +284,7 @@ func newParityChainSpec(network string, genesis *core.Genesis, bootnodes []strin spec.Params.MaximumExtraDataSize = (hexutil.Uint64)(params.MaximumExtraDataSize) spec.Params.MinGasLimit = (hexutil.Uint64)(params.MinGasLimit) spec.Params.GasLimitBoundDivisor = (hexutil.Uint64)(params.GasLimitBoundDivisor) - spec.Params.NetworkID = (hexutil.Uint64)(genesis.Config.ChainId.Uint64()) + spec.Params.NetworkID = (hexutil.Uint64)(genesis.Config.ChainID.Uint64()) spec.Params.MaxCodeSize = params.MaxCodeSize spec.Params.EIP155Transition = genesis.Config.EIP155Block.Uint64() spec.Params.EIP98Transition = math.MaxUint64 diff --git a/cmd/puppeth/module_dashboard.go b/cmd/puppeth/module_dashboard.go index 3832b247f8..a517623381 100644 --- a/cmd/puppeth/module_dashboard.go +++ b/cmd/puppeth/module_dashboard.go @@ -609,7 +609,7 @@ func deployDashboard(client *sshClient, network string, conf *config, config *da } template.Must(template.New("").Parse(dashboardContent)).Execute(indexfile, map[string]interface{}{ "Network": network, - "NetworkID": conf.Genesis.Config.ChainId, + "NetworkID": conf.Genesis.Config.ChainID, "NetworkTitle": strings.Title(network), "EthstatsPage": config.ethstats, "ExplorerPage": config.explorer, @@ -683,7 +683,7 @@ func deployDashboard(client *sshClient, network string, conf *config, config *da return nil, client.Stream(fmt.Sprintf("cd %s && docker-compose -p %s up -d --build --force-recreate", workdir, network)) } -// dashboardInfos is returned from an dashboard status check to allow reporting +// dashboardInfos is returned from a dashboard status check to allow reporting // various configuration parameters. type dashboardInfos struct { host string diff --git a/cmd/puppeth/module_ethstats.go b/cmd/puppeth/module_ethstats.go index 20b7afe236..1a7b484267 100644 --- a/cmd/puppeth/module_ethstats.go +++ b/cmd/puppeth/module_ethstats.go @@ -122,7 +122,7 @@ func (info *ethstatsInfos) Report() map[string]string { "Website address": info.host, "Website listener port": strconv.Itoa(info.port), "Login secret": info.secret, - "Banned addresses": fmt.Sprintf("%v", info.banned), + "Banned addresses": strings.Join(info.banned, "\n"), } } diff --git a/cmd/puppeth/module_explorer.go b/cmd/puppeth/module_explorer.go index 427134153b..bb43e5fe4e 100644 --- a/cmd/puppeth/module_explorer.go +++ b/cmd/puppeth/module_explorer.go @@ -168,7 +168,7 @@ func (info *explorerInfos) Report() map[string]string { return report } -// checkExplorer does a health-check against an block explorer server to verify +// checkExplorer does a health-check against a block explorer server to verify // whether it's running, and if yes, whether it's responsive. func checkExplorer(client *sshClient, network string) (*explorerInfos, error) { // Inspect a possible block explorer container on the host diff --git a/cmd/puppeth/module_faucet.go b/cmd/puppeth/module_faucet.go index 976bf04d00..8365bf47d0 100644 --- a/cmd/puppeth/module_faucet.go +++ b/cmd/puppeth/module_faucet.go @@ -30,7 +30,7 @@ import ( "github.com/ethereum/go-ethereum/log" ) -// faucetDockerfile is the Dockerfile required to build an faucet container to +// faucetDockerfile is the Dockerfile required to build a faucet container to // grant crypto tokens based on GitHub authentications. var faucetDockerfile = ` FROM ethereum/client-go:alltools-latest @@ -138,7 +138,7 @@ func deployFaucet(client *sshClient, network string, bootnodes []string, config return nil, client.Stream(fmt.Sprintf("cd %s && docker-compose -p %s up -d --build --force-recreate", workdir, network)) } -// faucetInfos is returned from an faucet status check to allow reporting various +// faucetInfos is returned from a faucet status check to allow reporting various // configuration parameters. type faucetInfos struct { node *nodeInfos @@ -181,7 +181,7 @@ func (info *faucetInfos) Report() map[string]string { return report } -// checkFaucet does a health-check against an faucet server to verify whether +// checkFaucet does a health-check against a faucet server to verify whether // it's running, and if yes, gathering a collection of useful infos about it. func checkFaucet(client *sshClient, network string) (*faucetInfos, error) { // Inspect a possible faucet container on the host diff --git a/cmd/puppeth/module_node.go b/cmd/puppeth/module_node.go index 54e7e7a43d..4006cf8e85 100644 --- a/cmd/puppeth/module_node.go +++ b/cmd/puppeth/module_node.go @@ -198,7 +198,7 @@ func (info *nodeInfos) Report() map[string]string { return report } -// checkNode does a health-check against an boot or seal node server to verify +// checkNode does a health-check against a boot or seal node server to verify // whether it's running, and if yes, whether it's responsive. func checkNode(client *sshClient, network string, boot bool) (*nodeInfos, error) { kind := "bootnode" @@ -221,7 +221,7 @@ func checkNode(client *sshClient, network string, boot bool) (*nodeInfos, error) // Container available, retrieve its node ID and its genesis json var out []byte - if out, err = client.Run(fmt.Sprintf("docker exec %s_%s_1 XDC --exec admin.nodeInfo.id attach", network, kind)); err != nil { + if out, err = client.Run(fmt.Sprintf("docker exec %s_%s_1 XDC --exec admin.nodeInfo.id --cache=16 attach", network, kind)); err != nil { return nil, ErrServiceUnreachable } id := bytes.Trim(bytes.TrimSpace(out), "\"") diff --git a/cmd/puppeth/wizard_faucet.go b/cmd/puppeth/wizard_faucet.go index 9a429bc96d..6f08408947 100644 --- a/cmd/puppeth/wizard_faucet.go +++ b/cmd/puppeth/wizard_faucet.go @@ -49,7 +49,7 @@ func (w *wizard) deployFaucet() { existed := err == nil infos.node.genesis, _ = json.MarshalIndent(w.conf.Genesis, "", " ") - infos.node.network = w.conf.Genesis.Config.ChainId.Int64() + infos.node.network = w.conf.Genesis.Config.ChainID.Int64() // Figure out which port to listen on fmt.Println() diff --git a/cmd/puppeth/wizard_genesis.go b/cmd/puppeth/wizard_genesis.go index 713dd7a03d..fa58ff9f4e 100644 --- a/cmd/puppeth/wizard_genesis.go +++ b/cmd/puppeth/wizard_genesis.go @@ -344,7 +344,7 @@ func (w *wizard) makeGenesis() { // Query the user for some custom extras fmt.Println() fmt.Println("Specify your chain/network ID if you want an explicit one (default = random)") - genesis.Config.ChainId = new(big.Int).SetUint64(uint64(w.readDefaultInt(rand.Intn(65536)))) + genesis.Config.ChainID = new(big.Int).SetUint64(uint64(w.readDefaultInt(rand.Intn(65536)))) // All done, store the genesis and flush to disk log.Info("Configured new genesis block") diff --git a/cmd/puppeth/wizard_netstats.go b/cmd/puppeth/wizard_netstats.go index 90bf7ae3c8..89b38e262b 100644 --- a/cmd/puppeth/wizard_netstats.go +++ b/cmd/puppeth/wizard_netstats.go @@ -203,7 +203,7 @@ func (stats serverStats) render() { table.SetHeader([]string{"Server", "Address", "Service", "Config", "Value"}) table.SetAlignment(tablewriter.ALIGN_LEFT) - table.SetColWidth(100) + table.SetColWidth(40) // Find the longest lines for all columns for the hacked separator separator := make([]string, 5) @@ -222,8 +222,10 @@ func (stats serverStats) render() { if len(config) > len(separator[3]) { separator[3] = strings.Repeat("-", len(config)) } - if len(value) > len(separator[4]) { - separator[4] = strings.Repeat("-", len(value)) + for _, val := range strings.Split(value, "\n") { + if len(val) > len(separator[4]) { + separator[4] = strings.Repeat("-", len(val)) + } } } } @@ -263,26 +265,20 @@ func (stats serverStats) render() { sort.Strings(configs) for k, config := range configs { - switch { - case j == 0 && k == 0: - table.Append([]string{server, stats[server].address, service, config, stats[server].services[service][config]}) - case k == 0: - table.Append([]string{"", "", service, config, stats[server].services[service][config]}) - default: - table.Append([]string{"", "", "", config, stats[server].services[service][config]}) + for l, value := range strings.Split(stats[server].services[service][config], "\n") { + switch { + case j == 0 && k == 0 && l == 0: + table.Append([]string{server, stats[server].address, service, config, value}) + case k == 0 && l == 0: + table.Append([]string{"", "", service, config, value}) + case l == 0: + table.Append([]string{"", "", "", config, value}) + default: + table.Append([]string{"", "", "", "", value}) + } } } } } table.Render() } - -// protips contains a collection of network infos to report pro-tips -// based on. -type protips struct { - genesis string - network int64 - bootFull []string - bootLight []string - ethstats string -} diff --git a/cmd/puppeth/wizard_node.go b/cmd/puppeth/wizard_node.go index d766ab2cf3..98edb93634 100644 --- a/cmd/puppeth/wizard_node.go +++ b/cmd/puppeth/wizard_node.go @@ -56,7 +56,7 @@ func (w *wizard) deployNode(boot bool) { existed := err == nil infos.genesis, _ = json.MarshalIndent(w.conf.Genesis, "", " ") - infos.network = w.conf.Genesis.Config.ChainId.Int64() + infos.network = w.conf.Genesis.Config.ChainID.Int64() // Figure out where the user wants to store the persistent data fmt.Println() @@ -107,7 +107,7 @@ func (w *wizard) deployNode(boot bool) { // Ethash based miners only need an etherbase to mine against fmt.Println() if infos.etherbase == "" { - fmt.Printf("What address should the miner user?\n") + fmt.Printf("What address should the miner use?\n") for { if address := w.readAddress(); address != nil { infos.etherbase = address.Hex() @@ -115,7 +115,7 @@ func (w *wizard) deployNode(boot bool) { } } } else { - fmt.Printf("What address should the miner user? (default = %s)\n", infos.etherbase) + fmt.Printf("What address should the miner use? (default = %s)\n", infos.etherbase) infos.etherbase = w.readDefaultAddress(common.HexToAddress(infos.etherbase)).Hex() } } else if w.conf.Genesis.Config.XDPoS != nil { diff --git a/cmd/puppeth/wizard_wallet.go b/cmd/puppeth/wizard_wallet.go index 933cd9ae59..7624d11e20 100644 --- a/cmd/puppeth/wizard_wallet.go +++ b/cmd/puppeth/wizard_wallet.go @@ -52,7 +52,7 @@ func (w *wizard) deployWallet() { existed := err == nil infos.genesis, _ = json.MarshalIndent(w.conf.Genesis, "", " ") - infos.network = w.conf.Genesis.Config.ChainId.Int64() + infos.network = w.conf.Genesis.Config.ChainID.Int64() // Figure out which port to listen on fmt.Println() diff --git a/cmd/swarm/config.go b/cmd/swarm/config.go index a13ff875ba..779c484ebf 100644 --- a/cmd/swarm/config.go +++ b/cmd/swarm/config.go @@ -24,6 +24,7 @@ import ( "reflect" "strconv" "strings" + "time" "unicode" cli "gopkg.in/urfave/cli.v1" @@ -58,19 +59,25 @@ var ( //constants for environment variables const ( - SWARM_ENV_CHEQUEBOOK_ADDR = "SWARM_CHEQUEBOOK_ADDR" - SWARM_ENV_ACCOUNT = "SWARM_ACCOUNT" - SWARM_ENV_LISTEN_ADDR = "SWARM_LISTEN_ADDR" - SWARM_ENV_PORT = "SWARM_PORT" - SWARM_ENV_NETWORK_ID = "SWARM_NETWORK_ID" - SWARM_ENV_SWAP_ENABLE = "SWARM_SWAP_ENABLE" - SWARM_ENV_SWAP_API = "SWARM_SWAP_API" - SWARM_ENV_SYNC_ENABLE = "SWARM_SYNC_ENABLE" - SWARM_ENV_ENS_API = "SWARM_ENS_API" - SWARM_ENV_ENS_ADDR = "SWARM_ENS_ADDR" - SWARM_ENV_CORS = "SWARM_CORS" - SWARM_ENV_BOOTNODES = "SWARM_BOOTNODES" - XDC_ENV_DATADIR = "XDC_DATADIR" + SWARM_ENV_CHEQUEBOOK_ADDR = "SWARM_CHEQUEBOOK_ADDR" + SWARM_ENV_ACCOUNT = "SWARM_ACCOUNT" + SWARM_ENV_LISTEN_ADDR = "SWARM_LISTEN_ADDR" + SWARM_ENV_PORT = "SWARM_PORT" + SWARM_ENV_NETWORK_ID = "SWARM_NETWORK_ID" + SWARM_ENV_SWAP_ENABLE = "SWARM_SWAP_ENABLE" + SWARM_ENV_SWAP_API = "SWARM_SWAP_API" + SWARM_ENV_SYNC_DISABLE = "SWARM_SYNC_DISABLE" + SWARM_ENV_SYNC_UPDATE_DELAY = "SWARM_ENV_SYNC_UPDATE_DELAY" + SWARM_ENV_DELIVERY_SKIP_CHECK = "SWARM_DELIVERY_SKIP_CHECK" + SWARM_ENV_ENS_API = "SWARM_ENS_API" + SWARM_ENV_ENS_ADDR = "SWARM_ENS_ADDR" + SWARM_ENV_CORS = "SWARM_CORS" + SWARM_ENV_BOOTNODES = "SWARM_BOOTNODES" + SWARM_ENV_PSS_ENABLE = "SWARM_PSS_ENABLE" + SWARM_ENV_STORE_PATH = "SWARM_STORE_PATH" + SWARM_ENV_STORE_CAPACITY = "SWARM_STORE_CAPACITY" + SWARM_ENV_STORE_CACHE_CAPACITY = "SWARM_STORE_CACHE_CAPACITY" + XDC_ENV_DATADIR = "XDC_DATADIR" ) // These settings ensure that TOML keys use the same names as Go struct fields. @@ -92,10 +99,8 @@ var tomlSettings = toml.Config{ //before booting the swarm node, build the configuration func buildConfig(ctx *cli.Context) (config *bzzapi.Config, err error) { - //check for deprecated flags - checkDeprecated(ctx) //start by creating a default config - config = bzzapi.NewDefaultConfig() + config = bzzapi.NewConfig() //first load settings from config file (if provided) config, err = configFileOverride(config, ctx) if err != nil { @@ -168,7 +173,7 @@ func cmdLineOverride(currentConfig *bzzapi.Config, ctx *cli.Context) *bzzapi.Con if networkid := ctx.GlobalString(SwarmNetworkIdFlag.Name); networkid != "" { if id, _ := strconv.Atoi(networkid); id != 0 { - currentConfig.NetworkId = uint64(id) + currentConfig.NetworkID = uint64(id) } } @@ -191,12 +196,20 @@ func cmdLineOverride(currentConfig *bzzapi.Config, ctx *cli.Context) *bzzapi.Con currentConfig.SwapEnabled = true } - if ctx.GlobalIsSet(SwarmSyncEnabledFlag.Name) { - currentConfig.SyncEnabled = true + if ctx.GlobalIsSet(SwarmSyncDisabledFlag.Name) { + currentConfig.SyncEnabled = false } - currentConfig.SwapApi = ctx.GlobalString(SwarmSwapAPIFlag.Name) - if currentConfig.SwapEnabled && currentConfig.SwapApi == "" { + if d := ctx.GlobalDuration(SwarmSyncUpdateDelay.Name); d > 0 { + currentConfig.SyncUpdateDelay = d + } + + if ctx.GlobalIsSet(SwarmDeliverySkipCheckFlag.Name) { + currentConfig.DeliverySkipCheck = true + } + + currentConfig.SwapAPI = ctx.GlobalString(SwarmSwapAPIFlag.Name) + if currentConfig.SwapEnabled && currentConfig.SwapAPI == "" { utils.Fatalf(SWARM_ERR_SWAP_SET_NO_API) } @@ -209,10 +222,6 @@ func cmdLineOverride(currentConfig *bzzapi.Config, ctx *cli.Context) *bzzapi.Con currentConfig.EnsAPIs = ensAPIs } - if ensaddr := ctx.GlobalString(DeprecatedEnsAddrFlag.Name); ensaddr != "" { - currentConfig.EnsRoot = common.HexToAddress(ensaddr) - } - if cors := ctx.GlobalString(CorsStringFlag.Name); cors != "" { currentConfig.Cors = cors } @@ -221,6 +230,18 @@ func cmdLineOverride(currentConfig *bzzapi.Config, ctx *cli.Context) *bzzapi.Con currentConfig.BootNodes = ctx.GlobalString(utils.BootnodesFlag.Name) } + if storePath := ctx.GlobalString(SwarmStorePath.Name); storePath != "" { + currentConfig.LocalStoreParams.ChunkDbPath = storePath + } + + if storeCapacity := ctx.GlobalUint64(SwarmStoreCapacity.Name); storeCapacity != 0 { + currentConfig.LocalStoreParams.DbCapacity = storeCapacity + } + + if storeCacheCapacity := ctx.GlobalUint(SwarmStoreCacheCapacity.Name); storeCacheCapacity != 0 { + currentConfig.LocalStoreParams.CacheCapacity = storeCacheCapacity + } + return currentConfig } @@ -239,7 +260,7 @@ func envVarsOverride(currentConfig *bzzapi.Config) (config *bzzapi.Config) { if networkid := os.Getenv(SWARM_ENV_NETWORK_ID); networkid != "" { if id, _ := strconv.Atoi(networkid); id != 0 { - currentConfig.NetworkId = uint64(id) + currentConfig.NetworkID = uint64(id) } } @@ -262,17 +283,29 @@ func envVarsOverride(currentConfig *bzzapi.Config) (config *bzzapi.Config) { } } - if syncenable := os.Getenv(SWARM_ENV_SYNC_ENABLE); syncenable != "" { - if sync, err := strconv.ParseBool(syncenable); err != nil { - currentConfig.SyncEnabled = sync + if syncdisable := os.Getenv(SWARM_ENV_SYNC_DISABLE); syncdisable != "" { + if sync, err := strconv.ParseBool(syncdisable); err != nil { + currentConfig.SyncEnabled = !sync + } + } + + if v := os.Getenv(SWARM_ENV_DELIVERY_SKIP_CHECK); v != "" { + if skipCheck, err := strconv.ParseBool(v); err != nil { + currentConfig.DeliverySkipCheck = skipCheck + } + } + + if v := os.Getenv(SWARM_ENV_SYNC_UPDATE_DELAY); v != "" { + if d, err := time.ParseDuration(v); err != nil { + currentConfig.SyncUpdateDelay = d } } if swapapi := os.Getenv(SWARM_ENV_SWAP_API); swapapi != "" { - currentConfig.SwapApi = swapapi + currentConfig.SwapAPI = swapapi } - if currentConfig.SwapEnabled && currentConfig.SwapApi == "" { + if currentConfig.SwapEnabled && currentConfig.SwapAPI == "" { utils.Fatalf(SWARM_ERR_SWAP_SET_NO_API) } @@ -312,18 +345,6 @@ func dumpConfig(ctx *cli.Context) error { return nil } -//deprecated flags checked here -func checkDeprecated(ctx *cli.Context) { - // exit if the deprecated --ethapi flag is set - if ctx.GlobalString(DeprecatedEthAPIFlag.Name) != "" { - utils.Fatalf("--ethapi is no longer a valid command line flag, please use --ens-api and/or --swap-api.") - } - // warn if --ens-api flag is set - if ctx.GlobalString(DeprecatedEnsAddrFlag.Name) != "" { - log.Warn("--ens-addr is no longer a valid command line flag, please use --ens-api to specify contract address.") - } -} - //validate configuration parameters func validateConfig(cfg *bzzapi.Config) (err error) { for _, ensAPI := range cfg.EnsAPIs { diff --git a/cmd/swarm/config_test.go b/cmd/swarm/config_test.go index 9bf584f50c..d5011e3a70 100644 --- a/cmd/swarm/config_test.go +++ b/cmd/swarm/config_test.go @@ -34,7 +34,7 @@ import ( func TestDumpConfig(t *testing.T) { swarm := runSwarm(t, "dumpconfig") - defaultConf := api.NewDefaultConfig() + defaultConf := api.NewConfig() out, err := tomlSettings.Marshal(&defaultConf) if err != nil { t.Fatal(err) @@ -43,7 +43,7 @@ func TestDumpConfig(t *testing.T) { swarm.ExpectExit() } -func TestFailsSwapEnabledNoSwapApi(t *testing.T) { +func TestConfigFailsSwapEnabledNoSwapApi(t *testing.T) { flags := []string{ fmt.Sprintf("--%s", SwarmNetworkIdFlag.Name), "42", fmt.Sprintf("--%s", SwarmPortFlag.Name), "54545", @@ -55,7 +55,7 @@ func TestFailsSwapEnabledNoSwapApi(t *testing.T) { swarm.ExpectExit() } -func TestFailsNoBzzAccount(t *testing.T) { +func TestConfigFailsNoBzzAccount(t *testing.T) { flags := []string{ fmt.Sprintf("--%s", SwarmNetworkIdFlag.Name), "42", fmt.Sprintf("--%s", SwarmPortFlag.Name), "54545", @@ -66,7 +66,7 @@ func TestFailsNoBzzAccount(t *testing.T) { swarm.ExpectExit() } -func TestCmdLineOverrides(t *testing.T) { +func TestConfigCmdLineOverrides(t *testing.T) { dir, err := ioutil.TempDir("", "bzztest") if err != nil { t.Fatal(err) @@ -85,9 +85,10 @@ func TestCmdLineOverrides(t *testing.T) { flags := []string{ fmt.Sprintf("--%s", SwarmNetworkIdFlag.Name), "42", fmt.Sprintf("--%s", SwarmPortFlag.Name), httpPort, - fmt.Sprintf("--%s", SwarmSyncEnabledFlag.Name), + fmt.Sprintf("--%s", SwarmSyncDisabledFlag.Name), fmt.Sprintf("--%s", CorsStringFlag.Name), "*", fmt.Sprintf("--%s", SwarmAccountFlag.Name), account.Address.String(), + fmt.Sprintf("--%s", SwarmDeliverySkipCheckFlag.Name), fmt.Sprintf("--%s", EnsAPIFlag.Name), "", "--datadir", dir, "--ipcpath", conf.IPCPath, @@ -120,12 +121,16 @@ func TestCmdLineOverrides(t *testing.T) { t.Fatalf("Expected port to be %s, got %s", httpPort, info.Port) } - if info.NetworkId != 42 { - t.Fatalf("Expected network ID to be %d, got %d", 42, info.NetworkId) + if info.NetworkID != 42 { + t.Fatalf("Expected network ID to be %d, got %d", 42, info.NetworkID) } - if !info.SyncEnabled { - t.Fatal("Expected Sync to be enabled, but is false") + if info.SyncEnabled { + t.Fatal("Expected Sync to be disabled, but is true") + } + + if !info.DeliverySkipCheck { + t.Fatal("Expected DeliverySkipCheck to be enabled, but it is not") } if info.Cors != "*" { @@ -135,7 +140,7 @@ func TestCmdLineOverrides(t *testing.T) { node.Shutdown() } -func TestFileOverrides(t *testing.T) { +func TestConfigFileOverrides(t *testing.T) { // assign ports httpPort, err := assignTCPPort() @@ -145,16 +150,16 @@ func TestFileOverrides(t *testing.T) { //create a config file //first, create a default conf - defaultConf := api.NewDefaultConfig() + defaultConf := api.NewConfig() //change some values in order to test if they have been loaded - defaultConf.SyncEnabled = true - defaultConf.NetworkId = 54 + defaultConf.SyncEnabled = false + defaultConf.DeliverySkipCheck = true + defaultConf.NetworkID = 54 defaultConf.Port = httpPort - defaultConf.StoreParams.DbCapacity = 9000000 - defaultConf.ChunkerParams.Branches = 64 - defaultConf.HiveParams.CallInterval = 6000000000 + defaultConf.DbCapacity = 9000000 + defaultConf.HiveParams.KeepAliveInterval = 6000000000 defaultConf.Swap.Params.Strategy.AutoCashInterval = 600 * time.Second - defaultConf.SyncParams.KeyBufferSize = 512 + //defaultConf.SyncParams.KeyBufferSize = 512 //create a TOML string out, err := tomlSettings.Marshal(&defaultConf) if err != nil { @@ -215,38 +220,38 @@ func TestFileOverrides(t *testing.T) { t.Fatalf("Expected port to be %s, got %s", httpPort, info.Port) } - if info.NetworkId != 54 { - t.Fatalf("Expected network ID to be %d, got %d", 54, info.NetworkId) + if info.NetworkID != 54 { + t.Fatalf("Expected network ID to be %d, got %d", 54, info.NetworkID) } - if !info.SyncEnabled { - t.Fatal("Expected Sync to be enabled, but is false") + if info.SyncEnabled { + t.Fatal("Expected Sync to be disabled, but is true") } - if info.StoreParams.DbCapacity != 9000000 { - t.Fatalf("Expected network ID to be %d, got %d", 54, info.NetworkId) + if !info.DeliverySkipCheck { + t.Fatal("Expected DeliverySkipCheck to be enabled, but it is not") } - if info.ChunkerParams.Branches != 64 { - t.Fatalf("Expected chunker params branches to be %d, got %d", 64, info.ChunkerParams.Branches) + if info.DbCapacity != 9000000 { + t.Fatalf("Expected network ID to be %d, got %d", 54, info.NetworkID) } - if info.HiveParams.CallInterval != 6000000000 { - t.Fatalf("Expected HiveParams CallInterval to be %d, got %d", uint64(6000000000), uint64(info.HiveParams.CallInterval)) + if info.HiveParams.KeepAliveInterval != 6000000000 { + t.Fatalf("Expected HiveParams KeepAliveInterval to be %d, got %d", uint64(6000000000), uint64(info.HiveParams.KeepAliveInterval)) } if info.Swap.Params.Strategy.AutoCashInterval != 600*time.Second { t.Fatalf("Expected SwapParams AutoCashInterval to be %ds, got %d", 600, info.Swap.Params.Strategy.AutoCashInterval) } - if info.SyncParams.KeyBufferSize != 512 { - t.Fatalf("Expected info.SyncParams.KeyBufferSize to be %d, got %d", 512, info.SyncParams.KeyBufferSize) - } + // if info.SyncParams.KeyBufferSize != 512 { + // t.Fatalf("Expected info.SyncParams.KeyBufferSize to be %d, got %d", 512, info.SyncParams.KeyBufferSize) + // } node.Shutdown() } -func TestEnvVars(t *testing.T) { +func TestConfigEnvVars(t *testing.T) { // assign ports httpPort, err := assignTCPPort() if err != nil { @@ -257,7 +262,8 @@ func TestEnvVars(t *testing.T) { envVars = append(envVars, fmt.Sprintf("%s=%s", SwarmPortFlag.EnvVar, httpPort)) envVars = append(envVars, fmt.Sprintf("%s=%s", SwarmNetworkIdFlag.EnvVar, "999")) envVars = append(envVars, fmt.Sprintf("%s=%s", CorsStringFlag.EnvVar, "*")) - envVars = append(envVars, fmt.Sprintf("%s=%s", SwarmSyncEnabledFlag.EnvVar, "true")) + envVars = append(envVars, fmt.Sprintf("%s=%s", SwarmSyncDisabledFlag.EnvVar, "true")) + envVars = append(envVars, fmt.Sprintf("%s=%s", SwarmDeliverySkipCheckFlag.EnvVar, "true")) dir, err := ioutil.TempDir("", "bzztest") if err != nil { @@ -326,23 +332,27 @@ func TestEnvVars(t *testing.T) { t.Fatalf("Expected port to be %s, got %s", httpPort, info.Port) } - if info.NetworkId != 999 { - t.Fatalf("Expected network ID to be %d, got %d", 999, info.NetworkId) + if info.NetworkID != 999 { + t.Fatalf("Expected network ID to be %d, got %d", 999, info.NetworkID) } if info.Cors != "*" { t.Fatalf("Expected Cors flag to be set to %s, got %s", "*", info.Cors) } - if !info.SyncEnabled { - t.Fatal("Expected Sync to be enabled, but is false") + if info.SyncEnabled { + t.Fatal("Expected Sync to be disabled, but is true") + } + + if !info.DeliverySkipCheck { + t.Fatal("Expected DeliverySkipCheck to be enabled, but it is not") } node.Shutdown() cmd.Process.Kill() } -func TestCmdLineOverridesFile(t *testing.T) { +func TestConfigCmdLineOverridesFile(t *testing.T) { // assign ports httpPort, err := assignTCPPort() @@ -352,26 +362,27 @@ func TestCmdLineOverridesFile(t *testing.T) { //create a config file //first, create a default conf - defaultConf := api.NewDefaultConfig() + defaultConf := api.NewConfig() //change some values in order to test if they have been loaded - defaultConf.SyncEnabled = false - defaultConf.NetworkId = 54 + defaultConf.SyncEnabled = true + defaultConf.NetworkID = 54 defaultConf.Port = "8588" - defaultConf.StoreParams.DbCapacity = 9000000 - defaultConf.ChunkerParams.Branches = 64 - defaultConf.HiveParams.CallInterval = 6000000000 + defaultConf.DbCapacity = 9000000 + defaultConf.HiveParams.KeepAliveInterval = 6000000000 defaultConf.Swap.Params.Strategy.AutoCashInterval = 600 * time.Second - defaultConf.SyncParams.KeyBufferSize = 512 + //defaultConf.SyncParams.KeyBufferSize = 512 //create a TOML file out, err := tomlSettings.Marshal(&defaultConf) if err != nil { t.Fatalf("Error creating TOML file in TestFileOverride: %v", err) } //write file - f, err := ioutil.TempFile("", "testconfig.toml") + fname := "testconfig.toml" + f, err := ioutil.TempFile("", fname) if err != nil { t.Fatalf("Error writing TOML file in TestFileOverride: %v", err) } + defer os.Remove(fname) //write file _, err = f.WriteString(string(out)) if err != nil { @@ -392,7 +403,7 @@ func TestCmdLineOverridesFile(t *testing.T) { flags := []string{ fmt.Sprintf("--%s", SwarmNetworkIdFlag.Name), "77", fmt.Sprintf("--%s", SwarmPortFlag.Name), httpPort, - fmt.Sprintf("--%s", SwarmSyncEnabledFlag.Name), + fmt.Sprintf("--%s", SwarmSyncDisabledFlag.Name), fmt.Sprintf("--%s", SwarmTomlConfigPathFlag.Name), f.Name(), fmt.Sprintf("--%s", SwarmAccountFlag.Name), account.Address.String(), "--ens-api", "", @@ -427,33 +438,29 @@ func TestCmdLineOverridesFile(t *testing.T) { t.Fatalf("Expected port to be %s, got %s", httpPort, info.Port) } - if info.NetworkId != expectNetworkId { - t.Fatalf("Expected network ID to be %d, got %d", expectNetworkId, info.NetworkId) + if info.NetworkID != expectNetworkId { + t.Fatalf("Expected network ID to be %d, got %d", expectNetworkId, info.NetworkID) } - if !info.SyncEnabled { - t.Fatal("Expected Sync to be enabled, but is false") + if info.SyncEnabled { + t.Fatal("Expected Sync to be disabled, but is true") } - if info.StoreParams.DbCapacity != 9000000 { - t.Fatalf("Expected network ID to be %d, got %d", 54, info.NetworkId) + if info.LocalStoreParams.DbCapacity != 9000000 { + t.Fatalf("Expected Capacity to be %d, got %d", 9000000, info.LocalStoreParams.DbCapacity) } - if info.ChunkerParams.Branches != 64 { - t.Fatalf("Expected chunker params branches to be %d, got %d", 64, info.ChunkerParams.Branches) - } - - if info.HiveParams.CallInterval != 6000000000 { - t.Fatalf("Expected HiveParams CallInterval to be %d, got %d", uint64(6000000000), uint64(info.HiveParams.CallInterval)) + if info.HiveParams.KeepAliveInterval != 6000000000 { + t.Fatalf("Expected HiveParams KeepAliveInterval to be %d, got %d", uint64(6000000000), uint64(info.HiveParams.KeepAliveInterval)) } if info.Swap.Params.Strategy.AutoCashInterval != 600*time.Second { t.Fatalf("Expected SwapParams AutoCashInterval to be %ds, got %d", 600, info.Swap.Params.Strategy.AutoCashInterval) } - if info.SyncParams.KeyBufferSize != 512 { - t.Fatalf("Expected info.SyncParams.KeyBufferSize to be %d, got %d", 512, info.SyncParams.KeyBufferSize) - } + // if info.SyncParams.KeyBufferSize != 512 { + // t.Fatalf("Expected info.SyncParams.KeyBufferSize to be %d, got %d", 512, info.SyncParams.KeyBufferSize) + // } node.Shutdown() } diff --git a/cmd/swarm/db.go b/cmd/swarm/db.go index dfd2d069b9..fe03f2d160 100644 --- a/cmd/swarm/db.go +++ b/cmd/swarm/db.go @@ -23,6 +23,7 @@ import ( "path/filepath" "github.com/ethereum/go-ethereum/cmd/utils" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/swarm/storage" "gopkg.in/urfave/cli.v1" @@ -30,11 +31,11 @@ import ( func dbExport(ctx *cli.Context) { args := ctx.Args() - if len(args) != 2 { - utils.Fatalf("invalid arguments, please specify both (path to a local chunk database) and (path to write the tar archive to, - for stdout)") + if len(args) != 3 { + utils.Fatalf("invalid arguments, please specify both (path to a local chunk database), (path to write the tar archive to, - for stdout) and the base key") } - store, err := openDbStore(args[0]) + store, err := openLDBStore(args[0], common.Hex2Bytes(args[2])) if err != nil { utils.Fatalf("error opening local chunk database: %s", err) } @@ -62,11 +63,11 @@ func dbExport(ctx *cli.Context) { func dbImport(ctx *cli.Context) { args := ctx.Args() - if len(args) != 2 { - utils.Fatalf("invalid arguments, please specify both (path to a local chunk database) and (path to read the tar archive from, - for stdin)") + if len(args) != 3 { + utils.Fatalf("invalid arguments, please specify both (path to a local chunk database), (path to read the tar archive from, - for stdin) and the base key") } - store, err := openDbStore(args[0]) + store, err := openLDBStore(args[0], common.Hex2Bytes(args[2])) if err != nil { utils.Fatalf("error opening local chunk database: %s", err) } @@ -94,11 +95,11 @@ func dbImport(ctx *cli.Context) { func dbClean(ctx *cli.Context) { args := ctx.Args() - if len(args) != 1 { - utils.Fatalf("invalid arguments, please specify (path to a local chunk database)") + if len(args) != 2 { + utils.Fatalf("invalid arguments, please specify (path to a local chunk database) and the base key") } - store, err := openDbStore(args[0]) + store, err := openLDBStore(args[0], common.Hex2Bytes(args[1])) if err != nil { utils.Fatalf("error opening local chunk database: %s", err) } @@ -107,10 +108,13 @@ func dbClean(ctx *cli.Context) { store.Cleanup() } -func openDbStore(path string) (*storage.DbStore, error) { +func openLDBStore(path string, basekey []byte) (*storage.LDBStore, error) { if _, err := os.Stat(filepath.Join(path, "CURRENT")); err != nil { return nil, fmt.Errorf("invalid chunkdb path: %s", err) } - hash := storage.MakeHashFunc("SHA3") - return storage.NewDbStore(path, hash, 10000000, 0) + + storeparams := storage.NewDefaultStoreParams() + ldbparams := storage.NewLDBStoreParams(storeparams, path) + ldbparams.BaseKey = basekey + return storage.NewLDBStore(ldbparams) } diff --git a/cmd/swarm/download.go b/cmd/swarm/download.go new file mode 100644 index 0000000000..c2418f744c --- /dev/null +++ b/cmd/swarm/download.go @@ -0,0 +1,85 @@ +// Copyright 2018 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" + "path/filepath" + "strings" + + "github.com/ethereum/go-ethereum/cmd/utils" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/swarm/api" + swarm "github.com/ethereum/go-ethereum/swarm/api/client" + "gopkg.in/urfave/cli.v1" +) + +func download(ctx *cli.Context) { + log.Debug("downloading content using swarm down") + args := ctx.Args() + dest := "." + + switch len(args) { + case 0: + utils.Fatalf("Usage: swarm down [options] []") + case 1: + log.Trace(fmt.Sprintf("swarm down: no destination path - assuming working dir")) + default: + log.Trace(fmt.Sprintf("destination path arg: %s", args[1])) + if absDest, err := filepath.Abs(args[1]); err == nil { + dest = absDest + } else { + utils.Fatalf("could not get download path: %v", err) + } + } + + var ( + bzzapi = strings.TrimRight(ctx.GlobalString(SwarmApiFlag.Name), "/") + isRecursive = ctx.Bool(SwarmRecursiveFlag.Name) + client = swarm.NewClient(bzzapi) + ) + + if fi, err := os.Stat(dest); err == nil { + if isRecursive && !fi.Mode().IsDir() { + utils.Fatalf("destination path is not a directory!") + } + } else { + if !os.IsNotExist(err) { + utils.Fatalf("could not stat path: %v", err) + } + } + + uri, err := api.Parse(args[0]) + if err != nil { + utils.Fatalf("could not parse uri argument: %v", err) + } + + // assume behaviour according to --recursive switch + if isRecursive { + if err := client.DownloadDirectory(uri.Addr, uri.Path, dest); err != nil { + utils.Fatalf("encoutered an error while downloading directory: %v", err) + } + } else { + // we are downloading a file + log.Debug(fmt.Sprintf("downloading file/path from a manifest. hash: %s, path:%s", uri.Addr, uri.Path)) + + err := client.DownloadFile(uri.Addr, uri.Path, dest) + if err != nil { + utils.Fatalf("could not download %s from given address: %s. error: %v", uri.Path, uri.Addr, err) + } + } +} diff --git a/cmd/swarm/export_test.go b/cmd/swarm/export_test.go new file mode 100644 index 0000000000..525538ad75 --- /dev/null +++ b/cmd/swarm/export_test.go @@ -0,0 +1,139 @@ +// Copyright 2018 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 ( + "bytes" + "crypto/md5" + "crypto/rand" + "io" + "io/ioutil" + "net/http" + "os" + "strings" + "testing" + + "github.com/ethereum/go-ethereum/swarm" +) + +// TestCLISwarmExportImport perform the following test: +// 1. runs swarm node +// 2. uploads a random file +// 3. runs an export of the local datastore +// 4. runs a second swarm node +// 5. imports the exported datastore +// 6. fetches the uploaded random file from the second node +func TestCLISwarmExportImport(t *testing.T) { + cluster := newTestCluster(t, 1) + + // generate random 10mb file + f, cleanup := generateRandomFile(t, 10000000) + defer cleanup() + + // upload the file with 'swarm up' and expect a hash + up := runSwarm(t, "--bzzapi", cluster.Nodes[0].URL, "up", f.Name()) + _, matches := up.ExpectRegexp(`[a-f\d]{64}`) + up.ExpectExit() + hash := matches[0] + + var info swarm.Info + if err := cluster.Nodes[0].Client.Call(&info, "bzz_info"); err != nil { + t.Fatal(err) + } + + cluster.Stop() + defer cluster.Cleanup() + + // generate an export.tar + exportCmd := runSwarm(t, "db", "export", info.Path+"/chunks", info.Path+"/export.tar", strings.TrimPrefix(info.BzzKey, "0x")) + exportCmd.ExpectExit() + + // start second cluster + cluster2 := newTestCluster(t, 1) + + var info2 swarm.Info + if err := cluster2.Nodes[0].Client.Call(&info2, "bzz_info"); err != nil { + t.Fatal(err) + } + + // stop second cluster, so that we close LevelDB + cluster2.Stop() + defer cluster2.Cleanup() + + // import the export.tar + importCmd := runSwarm(t, "db", "import", info2.Path+"/chunks", info.Path+"/export.tar", strings.TrimPrefix(info2.BzzKey, "0x")) + importCmd.ExpectExit() + + // spin second cluster back up + cluster2.StartExistingNodes(t, 1, strings.TrimPrefix(info2.BzzAccount, "0x")) + + // try to fetch imported file + res, err := http.Get(cluster2.Nodes[0].URL + "/bzz:/" + hash) + if err != nil { + t.Fatal(err) + } + + if res.StatusCode != 200 { + t.Fatalf("expected HTTP status %d, got %s", 200, res.Status) + } + + // compare downloaded file with the generated random file + mustEqualFiles(t, f, res.Body) +} + +func mustEqualFiles(t *testing.T, up io.Reader, down io.Reader) { + h := md5.New() + upLen, err := io.Copy(h, up) + if err != nil { + t.Fatal(err) + } + upHash := h.Sum(nil) + h.Reset() + downLen, err := io.Copy(h, down) + if err != nil { + t.Fatal(err) + } + downHash := h.Sum(nil) + + if !bytes.Equal(upHash, downHash) || upLen != downLen { + t.Fatalf("downloaded imported file md5=%x (length %v) is not the same as the generated one mp5=%x (length %v)", downHash, downLen, upHash, upLen) + } +} + +func generateRandomFile(t *testing.T, size int) (f *os.File, teardown func()) { + // create a tmp file + tmp, err := ioutil.TempFile("", "swarm-test") + if err != nil { + t.Fatal(err) + } + + // callback for tmp file cleanup + teardown = func() { + tmp.Close() + os.Remove(tmp.Name()) + } + + // write 10mb random data to file + buf := make([]byte, 10000000) + _, err = rand.Read(buf) + if err != nil { + t.Fatal(err) + } + ioutil.WriteFile(tmp.Name(), buf, 0755) + + return tmp, teardown +} diff --git a/cmd/swarm/fs.go b/cmd/swarm/fs.go new file mode 100644 index 0000000000..0124586cfe --- /dev/null +++ b/cmd/swarm/fs.go @@ -0,0 +1,127 @@ +// Copyright 2018 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" + "fmt" + "path/filepath" + "strings" + "time" + + "github.com/ethereum/go-ethereum/cmd/utils" + "github.com/ethereum/go-ethereum/node" + "github.com/ethereum/go-ethereum/rpc" + "github.com/ethereum/go-ethereum/swarm/fuse" + "gopkg.in/urfave/cli.v1" +) + +func mount(cliContext *cli.Context) { + args := cliContext.Args() + if len(args) < 2 { + utils.Fatalf("Usage: swarm fs mount --ipcpath ") + } + + client, err := dialRPC(cliContext) + if err != nil { + utils.Fatalf("had an error dailing to RPC endpoint: %v", err) + } + defer client.Close() + + ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) + defer cancel() + + mf := &fuse.MountInfo{} + mountPoint, err := filepath.Abs(filepath.Clean(args[1])) + if err != nil { + utils.Fatalf("error expanding path for mount point: %v", err) + } + err = client.CallContext(ctx, mf, "swarmfs_mount", args[0], mountPoint) + if err != nil { + utils.Fatalf("had an error calling the RPC endpoint while mounting: %v", err) + } +} + +func unmount(cliContext *cli.Context) { + args := cliContext.Args() + + if len(args) < 1 { + utils.Fatalf("Usage: swarm fs unmount --ipcpath ") + } + client, err := dialRPC(cliContext) + if err != nil { + utils.Fatalf("had an error dailing to RPC endpoint: %v", err) + } + defer client.Close() + + ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) + defer cancel() + + mf := fuse.MountInfo{} + err = client.CallContext(ctx, &mf, "swarmfs_unmount", args[0]) + if err != nil { + utils.Fatalf("encountered an error calling the RPC endpoint while unmounting: %v", err) + } + fmt.Printf("%s\n", mf.LatestManifest) //print the latest manifest hash for user reference +} + +func listMounts(cliContext *cli.Context) { + client, err := dialRPC(cliContext) + if err != nil { + utils.Fatalf("had an error dailing to RPC endpoint: %v", err) + } + defer client.Close() + + ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) + defer cancel() + + mf := []fuse.MountInfo{} + err = client.CallContext(ctx, &mf, "swarmfs_listmounts") + if err != nil { + utils.Fatalf("encountered an error calling the RPC endpoint while unmounting: %v", err) + } + if len(mf) == 0 { + fmt.Print("Could not found any swarmfs mounts. Please make sure you've specified the correct RPC endpoint\n") + } else { + fmt.Printf("Found %d swarmfs mount(s):\n", len(mf)) + for i, mountInfo := range mf { + fmt.Printf("%d:\n", i) + fmt.Printf("\tMount point: %s\n", mountInfo.MountPoint) + fmt.Printf("\tLatest Manifest: %s\n", mountInfo.LatestManifest) + fmt.Printf("\tStart Manifest: %s\n", mountInfo.StartManifest) + } + } +} + +func dialRPC(ctx *cli.Context) (*rpc.Client, error) { + var endpoint string + + if ctx.IsSet(utils.IPCPathFlag.Name) { + endpoint = ctx.String(utils.IPCPathFlag.Name) + } else { + utils.Fatalf("swarm ipc endpoint not specified") + } + + if endpoint == "" { + endpoint = node.DefaultIPCEndpoint(clientIdentifier) + } else if strings.HasPrefix(endpoint, "rpc:") || strings.HasPrefix(endpoint, "ipc:") { + // Backwards compatibility with geth < 1.5 which required + // these prefixes. + endpoint = endpoint[4:] + } + return rpc.Dial(endpoint) +} diff --git a/cmd/swarm/fs_test.go b/cmd/swarm/fs_test.go new file mode 100644 index 0000000000..0cbf0eb137 --- /dev/null +++ b/cmd/swarm/fs_test.go @@ -0,0 +1,236 @@ +// Copyright 2018 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 . + +// +build linux darwin freebsd + +package main + +import ( + "bytes" + "io" + "io/ioutil" + "os" + "path/filepath" + "strings" + "testing" + "time" + + "github.com/ethereum/go-ethereum/log" + colorable "github.com/mattn/go-colorable" +) + +func init() { + log.PrintOrigins(true) + log.Root().SetHandler(log.LvlFilterHandler(log.Lvl(*loglevel), log.StreamHandler(colorable.NewColorableStderr(), log.TerminalFormat(true)))) +} + +type testFile struct { + filePath string + content string +} + +// TestCLISwarmFs is a high-level test of swarmfs +func TestCLISwarmFs(t *testing.T) { + cluster := newTestCluster(t, 3) + defer cluster.Shutdown() + + // create a tmp dir + mountPoint, err := ioutil.TempDir("", "swarm-test") + log.Debug("swarmfs cli test", "1st mount", mountPoint) + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(mountPoint) + + handlingNode := cluster.Nodes[0] + mhash := doUploadEmptyDir(t, handlingNode) + log.Debug("swarmfs cli test: mounting first run", "ipc path", filepath.Join(handlingNode.Dir, handlingNode.IpcPath)) + + mount := runSwarm(t, []string{ + "fs", + "mount", + "--ipcpath", filepath.Join(handlingNode.Dir, handlingNode.IpcPath), + mhash, + mountPoint, + }...) + mount.ExpectExit() + + filesToAssert := []*testFile{} + + dirPath, err := createDirInDir(mountPoint, "testSubDir") + if err != nil { + t.Fatal(err) + } + dirPath2, err := createDirInDir(dirPath, "AnotherTestSubDir") + + dummyContent := "somerandomtestcontentthatshouldbeasserted" + dirs := []string{ + mountPoint, + dirPath, + dirPath2, + } + files := []string{"f1.tmp", "f2.tmp"} + for _, d := range dirs { + for _, entry := range files { + tFile, err := createTestFileInPath(d, entry, dummyContent) + if err != nil { + t.Fatal(err) + } + filesToAssert = append(filesToAssert, tFile) + } + } + if len(filesToAssert) != len(dirs)*len(files) { + t.Fatalf("should have %d files to assert now, got %d", len(dirs)*len(files), len(filesToAssert)) + } + hashRegexp := `[a-f\d]{64}` + log.Debug("swarmfs cli test: unmounting first run...", "ipc path", filepath.Join(handlingNode.Dir, handlingNode.IpcPath)) + + unmount := runSwarm(t, []string{ + "fs", + "unmount", + "--ipcpath", filepath.Join(handlingNode.Dir, handlingNode.IpcPath), + mountPoint, + }...) + _, matches := unmount.ExpectRegexp(hashRegexp) + unmount.ExpectExit() + + hash := matches[0] + if hash == mhash { + t.Fatal("this should not be equal") + } + log.Debug("swarmfs cli test: asserting no files in mount point") + + //check that there's nothing in the mount folder + filesInDir, err := ioutil.ReadDir(mountPoint) + if err != nil { + t.Fatalf("had an error reading the directory: %v", err) + } + + if len(filesInDir) != 0 { + t.Fatal("there shouldn't be anything here") + } + + secondMountPoint, err := ioutil.TempDir("", "swarm-test") + log.Debug("swarmfs cli test", "2nd mount point at", secondMountPoint) + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(secondMountPoint) + + log.Debug("swarmfs cli test: remounting at second mount point", "ipc path", filepath.Join(handlingNode.Dir, handlingNode.IpcPath)) + + //remount, check files + newMount := runSwarm(t, []string{ + "fs", + "mount", + "--ipcpath", filepath.Join(handlingNode.Dir, handlingNode.IpcPath), + hash, // the latest hash + secondMountPoint, + }...) + + newMount.ExpectExit() + time.Sleep(1 * time.Second) + + filesInDir, err = ioutil.ReadDir(secondMountPoint) + if err != nil { + t.Fatal(err) + } + + if len(filesInDir) == 0 { + t.Fatal("there should be something here") + } + + log.Debug("swarmfs cli test: traversing file tree to see it matches previous mount") + + for _, file := range filesToAssert { + file.filePath = strings.Replace(file.filePath, mountPoint, secondMountPoint, -1) + fileBytes, err := ioutil.ReadFile(file.filePath) + + if err != nil { + t.Fatal(err) + } + if !bytes.Equal(fileBytes, bytes.NewBufferString(file.content).Bytes()) { + t.Fatal("this should be equal") + } + } + + log.Debug("swarmfs cli test: unmounting second run", "ipc path", filepath.Join(handlingNode.Dir, handlingNode.IpcPath)) + + unmountSec := runSwarm(t, []string{ + "fs", + "unmount", + "--ipcpath", filepath.Join(handlingNode.Dir, handlingNode.IpcPath), + secondMountPoint, + }...) + + _, matches = unmountSec.ExpectRegexp(hashRegexp) + unmountSec.ExpectExit() + + if matches[0] != hash { + t.Fatal("these should be equal - no changes made") + } +} + +func doUploadEmptyDir(t *testing.T, node *testNode) string { + // create a tmp dir + tmpDir, err := ioutil.TempDir("", "swarm-test") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(tmpDir) + + hashRegexp := `[a-f\d]{64}` + + flags := []string{ + "--bzzapi", node.URL, + "--recursive", + "up", + tmpDir} + + log.Info("swarmfs cli test: uploading dir with 'swarm up'") + up := runSwarm(t, flags...) + _, matches := up.ExpectRegexp(hashRegexp) + up.ExpectExit() + hash := matches[0] + log.Info("swarmfs cli test: dir uploaded", "hash", hash) + return hash +} + +func createDirInDir(createInDir string, dirToCreate string) (string, error) { + fullpath := filepath.Join(createInDir, dirToCreate) + err := os.MkdirAll(fullpath, 0777) + if err != nil { + return "", err + } + return fullpath, nil +} + +func createTestFileInPath(dir, filename, content string) (*testFile, error) { + tFile := &testFile{} + filePath := filepath.Join(dir, filename) + if file, err := os.Create(filePath); err == nil { + tFile.content = content + tFile.filePath = filePath + + _, err = io.WriteString(file, content) + if err != nil { + return nil, err + } + file.Close() + } + + return tFile, nil +} diff --git a/cmd/swarm/hash.go b/cmd/swarm/hash.go index 792e8d0d7a..bca4955b15 100644 --- a/cmd/swarm/hash.go +++ b/cmd/swarm/hash.go @@ -18,6 +18,7 @@ package main import ( + "context" "fmt" "os" @@ -38,11 +39,11 @@ func hash(ctx *cli.Context) { defer f.Close() stat, _ := f.Stat() - chunker := storage.NewTreeChunker(storage.NewChunkerParams()) - key, err := chunker.Split(f, stat.Size(), nil, nil, nil) + fileStore := storage.NewFileStore(storage.NewMapChunkStore(), storage.NewFileStoreParams()) + addr, _, err := fileStore.Store(context.TODO(), f, stat.Size(), false) if err != nil { utils.Fatalf("%v\n", err) } else { - fmt.Printf("%v\n", key) + fmt.Printf("%v\n", addr) } } diff --git a/cmd/swarm/main.go b/cmd/swarm/main.go index a136885012..d53b040502 100644 --- a/cmd/swarm/main.go +++ b/cmd/swarm/main.go @@ -34,21 +34,37 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/console" "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/ethclient" "github.com/ethereum/go-ethereum/internal/debug" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/node" "github.com/ethereum/go-ethereum/p2p" "github.com/ethereum/go-ethereum/p2p/discover" - "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/swarm" bzzapi "github.com/ethereum/go-ethereum/swarm/api" swarmmetrics "github.com/ethereum/go-ethereum/swarm/metrics" + "github.com/ethereum/go-ethereum/swarm/tracing" + sv "github.com/ethereum/go-ethereum/swarm/version" "gopkg.in/urfave/cli.v1" ) const clientIdentifier = "swarm" +const helpTemplate = `NAME: +{{.HelpName}} - {{.Usage}} + +USAGE: +{{if .UsageText}}{{.UsageText}}{{else}}{{.HelpName}}{{if .VisibleFlags}} [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}}{{if .Category}} + +CATEGORY: +{{.Category}}{{end}}{{if .Description}} + +DESCRIPTION: +{{.Description}}{{end}}{{if .VisibleFlags}} + +OPTIONS: +{{range .VisibleFlags}}{{.}} +{{end}}{{end}} +` var ( gitCommit string // Git SHA1 commit hash of the release (set via linker flags) @@ -87,10 +103,6 @@ var ( Usage: "Network identifier (integer, default 3=swarm testnet)", EnvVar: SWARM_ENV_NETWORK_ID, } - SwarmConfigPathFlag = cli.StringFlag{ - Name: "bzzconfig", - Usage: "DEPRECATED: please use --config path/to/TOML-file", - } SwarmSwapEnabledFlag = cli.BoolFlag{ Name: "swap", Usage: "Swarm SWAP enabled (default false)", @@ -101,10 +113,20 @@ var ( Usage: "URL of the Ethereum API provider to use to settle SWAP payments", EnvVar: SWARM_ENV_SWAP_API, } - SwarmSyncEnabledFlag = cli.BoolTFlag{ - Name: "sync", - Usage: "Swarm Syncing enabled (default true)", - EnvVar: SWARM_ENV_SYNC_ENABLE, + SwarmSyncDisabledFlag = cli.BoolTFlag{ + Name: "nosync", + Usage: "Disable swarm syncing", + EnvVar: SWARM_ENV_SYNC_DISABLE, + } + SwarmSyncUpdateDelay = cli.DurationFlag{ + Name: "sync-update-delay", + Usage: "Duration for sync subscriptions update after no new peers are added (default 15s)", + EnvVar: SWARM_ENV_SYNC_UPDATE_DELAY, + } + SwarmDeliverySkipCheckFlag = cli.BoolFlag{ + Name: "delivery-skip-check", + Usage: "Skip chunk delivery check (default false)", + EnvVar: SWARM_ENV_DELIVERY_SKIP_CHECK, } EnsAPIFlag = cli.StringSliceFlag{ Name: "ens-api", @@ -116,13 +138,13 @@ var ( Usage: "Swarm HTTP endpoint", Value: "http://127.0.0.1:8500", } - SwarmRecursiveUploadFlag = cli.BoolFlag{ + SwarmRecursiveFlag = cli.BoolFlag{ Name: "recursive", Usage: "Upload directories recursively", } SwarmWantManifestFlag = cli.BoolTFlag{ Name: "manifest", - Usage: "Automatic manifest upload", + Usage: "Automatic manifest upload (default true)", } SwarmUploadDefaultPath = cli.StringFlag{ Name: "defaultpath", @@ -134,22 +156,43 @@ var ( } SwarmUploadMimeType = cli.StringFlag{ Name: "mime", - Usage: "force mime type", + Usage: "Manually specify MIME type", + } + SwarmEncryptedFlag = cli.BoolFlag{ + Name: "encrypt", + Usage: "use encrypted upload", } CorsStringFlag = cli.StringFlag{ Name: "corsdomain", Usage: "Domain on which to send Access-Control-Allow-Origin header (multiple domains can be supplied separated by a ',')", EnvVar: SWARM_ENV_CORS, } - - // the following flags are deprecated and should be removed in the future - DeprecatedEthAPIFlag = cli.StringFlag{ - Name: "ethapi", - Usage: "DEPRECATED: please use --ens-api and --swap-api", + SwarmStorePath = cli.StringFlag{ + Name: "store.path", + Usage: "Path to leveldb chunk DB (default <$GETH_ENV_DIR>/swarm/bzz-<$BZZ_KEY>/chunks)", + EnvVar: SWARM_ENV_STORE_PATH, } - DeprecatedEnsAddrFlag = cli.StringFlag{ - Name: "ens-addr", - Usage: "DEPRECATED: ENS contract address, please use --ens-api with contract address according to its format", + SwarmStoreCapacity = cli.Uint64Flag{ + Name: "store.size", + Usage: "Number of chunks (5M is roughly 20-25GB) (default 5000000)", + EnvVar: SWARM_ENV_STORE_CAPACITY, + } + SwarmStoreCacheCapacity = cli.UintFlag{ + Name: "store.cache.size", + Usage: "Number of recent chunks cached in memory (default 5000)", + EnvVar: SWARM_ENV_STORE_CACHE_CAPACITY, + } + SwarmResourceMultihashFlag = cli.BoolFlag{ + Name: "multihash", + Usage: "Determines how to interpret data for a resource update. If not present, data will be interpreted as raw, literal data that will be included in the resource", + } + SwarmResourceNameFlag = cli.StringFlag{ + Name: "name", + Usage: "User-defined name for the new resource", + } + SwarmResourceDataOnCreateFlag = cli.StringFlag{ + Name: "data", + Usage: "Initializes the resource with the given hex-encoded data. Data must be prefixed by 0x", } ) @@ -159,12 +202,21 @@ var ( SWARM_ERR_SWAP_SET_NO_API = "SWAP is enabled but --swap-api is not set" ) +// this help command gets added to any subcommand that does not define it explicitly +var defaultSubcommandHelp = cli.Command{ + Action: func(ctx *cli.Context) { cli.ShowCommandHelpAndExit(ctx, "", 1) }, + CustomHelpTemplate: helpTemplate, + Name: "help", + Usage: "shows this help", + Hidden: true, +} + var defaultNodeConfig = node.DefaultConfig // This init function sets defaults so cmd/swarm can run alongside geth. func init() { defaultNodeConfig.Name = clientIdentifier - defaultNodeConfig.Version = params.VersionWithCommit(gitCommit) + defaultNodeConfig.Version = sv.VersionWithCommit(gitCommit) defaultNodeConfig.P2P.ListenAddr = ":30399" defaultNodeConfig.IPCPath = "bzzd.ipc" // Set flag defaults for --help display. @@ -180,91 +232,165 @@ func init() { app.Copyright = "Copyright 2013-2016 The go-ethereum Authors" app.Commands = []cli.Command{ { - Action: version, - Name: "version", - Usage: "Print version numbers", - ArgsUsage: " ", - Description: ` -The output of this command is supposed to be machine-readable. -`, + Action: version, + CustomHelpTemplate: helpTemplate, + Name: "version", + Usage: "Print version numbers", + Description: "The output of this command is supposed to be machine-readable", }, { - Action: upload, - Name: "up", - Usage: "upload a file or directory to swarm using the HTTP API", - ArgsUsage: " ", - Description: ` -"upload a file or directory to swarm using the HTTP API and prints the root hash", -`, + Action: upload, + CustomHelpTemplate: helpTemplate, + Name: "up", + Usage: "uploads a file or directory to swarm using the HTTP API", + ArgsUsage: "", + Flags: []cli.Flag{SwarmEncryptedFlag}, + Description: "uploads a file or directory to swarm using the HTTP API and prints the root hash", }, { - Action: list, - Name: "ls", - Usage: "list files and directories contained in a manifest", - ArgsUsage: " []", - Description: ` -Lists files and directories contained in a manifest. -`, - }, - { - Action: hash, - Name: "hash", - Usage: "print the swarm hash of a file or directory", - ArgsUsage: " ", - Description: ` -Prints the swarm hash of file or directory. -`, - }, - { - Name: "manifest", - Usage: "update a MANIFEST", - ArgsUsage: "manifest COMMAND", - Description: ` -Updates a MANIFEST by adding/removing/updating the hash of a path. -`, + CustomHelpTemplate: helpTemplate, + Name: "resource", + Usage: "(Advanced) Create and update Mutable Resources", + ArgsUsage: "", + Description: "Works with Mutable Resource Updates", Subcommands: []cli.Command{ { - Action: add, - Name: "add", - Usage: "add a new path to the manifest", - ArgsUsage: " []", - Description: ` -Adds a new path to the manifest -`, + Action: resourceCreate, + CustomHelpTemplate: helpTemplate, + Name: "create", + Usage: "creates a new Mutable Resource", + ArgsUsage: "", + Description: "creates a new Mutable Resource", + Flags: []cli.Flag{SwarmResourceNameFlag, SwarmResourceDataOnCreateFlag, SwarmResourceMultihashFlag}, }, { - Action: update, - Name: "update", - Usage: "update the hash for an already existing path in the manifest", - ArgsUsage: " []", - Description: ` -Update the hash for an already existing path in the manifest -`, + Action: resourceUpdate, + CustomHelpTemplate: helpTemplate, + Name: "update", + Usage: "updates the content of an existing Mutable Resource", + ArgsUsage: " <0x Hex data>", + Description: "updates the content of an existing Mutable Resource", + Flags: []cli.Flag{SwarmResourceMultihashFlag}, }, { - Action: remove, - Name: "remove", - Usage: "removes a path from the manifest", - ArgsUsage: " ", - Description: ` -Removes a path from the manifest -`, + Action: resourceInfo, + CustomHelpTemplate: helpTemplate, + Name: "info", + Usage: "obtains information about an existing Mutable Resource", + ArgsUsage: "", + Description: "obtains information about an existing Mutable Resource", }, }, }, { - Name: "db", - Usage: "manage the local chunk database", - ArgsUsage: "db COMMAND", + Action: list, + CustomHelpTemplate: helpTemplate, + Name: "ls", + Usage: "list files and directories contained in a manifest", + ArgsUsage: " []", + Description: "Lists files and directories contained in a manifest", + }, + { + Action: hash, + CustomHelpTemplate: helpTemplate, + Name: "hash", + Usage: "print the swarm hash of a file or directory", + ArgsUsage: "", + Description: "Prints the swarm hash of file or directory", + }, + { + Action: download, + Name: "down", + Flags: []cli.Flag{SwarmRecursiveFlag}, + Usage: "downloads a swarm manifest or a file inside a manifest", + ArgsUsage: " []", Description: ` -Manage the local chunk database. +Downloads a swarm bzz uri to the given dir. When no dir is provided, working directory is assumed. --recursive flag is expected when downloading a manifest with multiple entries. `, + }, + + { + Name: "manifest", + CustomHelpTemplate: helpTemplate, + Usage: "perform operations on swarm manifests", + ArgsUsage: "COMMAND", + Description: "Updates a MANIFEST by adding/removing/updating the hash of a path.\nCOMMAND could be: add, update, remove", Subcommands: []cli.Command{ { - Action: dbExport, - Name: "export", - Usage: "export a local chunk database as a tar archive (use - to send to stdout)", - ArgsUsage: " ", + Action: add, + CustomHelpTemplate: helpTemplate, + Name: "add", + Usage: "add a new path to the manifest", + ArgsUsage: " []", + Description: "Adds a new path to the manifest", + }, + { + Action: update, + CustomHelpTemplate: helpTemplate, + Name: "update", + Usage: "update the hash for an already existing path in the manifest", + ArgsUsage: " []", + Description: "Update the hash for an already existing path in the manifest", + }, + { + Action: remove, + CustomHelpTemplate: helpTemplate, + Name: "remove", + Usage: "removes a path from the manifest", + ArgsUsage: " ", + Description: "Removes a path from the manifest", + }, + }, + }, + { + Name: "fs", + CustomHelpTemplate: helpTemplate, + Usage: "perform FUSE operations", + ArgsUsage: "fs COMMAND", + Description: "Performs FUSE operations by mounting/unmounting/listing mount points. This assumes you already have a Swarm node running locally. For all operation you must reference the correct path to bzzd.ipc in order to communicate with the node", + Subcommands: []cli.Command{ + { + Action: mount, + CustomHelpTemplate: helpTemplate, + Name: "mount", + Flags: []cli.Flag{utils.IPCPathFlag}, + Usage: "mount a swarm hash to a mount point", + ArgsUsage: "swarm fs mount --ipcpath ", + Description: "Mounts a Swarm manifest hash to a given mount point. This assumes you already have a Swarm node running locally. You must reference the correct path to your bzzd.ipc file", + }, + { + Action: unmount, + CustomHelpTemplate: helpTemplate, + Name: "unmount", + Flags: []cli.Flag{utils.IPCPathFlag}, + Usage: "unmount a swarmfs mount", + ArgsUsage: "swarm fs unmount --ipcpath ", + Description: "Unmounts a swarmfs mount residing at . This assumes you already have a Swarm node running locally. You must reference the correct path to your bzzd.ipc file", + }, + { + Action: listMounts, + CustomHelpTemplate: helpTemplate, + Name: "list", + Flags: []cli.Flag{utils.IPCPathFlag}, + Usage: "list swarmfs mounts", + ArgsUsage: "swarm fs list --ipcpath ", + Description: "Lists all mounted swarmfs volumes. This assumes you already have a Swarm node running locally. You must reference the correct path to your bzzd.ipc file", + }, + }, + }, + { + Name: "db", + CustomHelpTemplate: helpTemplate, + Usage: "manage the local chunk database", + ArgsUsage: "db COMMAND", + Description: "Manage the local chunk database", + Subcommands: []cli.Command{ + { + Action: dbExport, + CustomHelpTemplate: helpTemplate, + Name: "export", + Usage: "export a local chunk database as a tar archive (use - to send to stdout)", + ArgsUsage: " ", Description: ` Export a local chunk database as a tar archive (use - to send to stdout). @@ -277,10 +403,11 @@ pv(1) tool to get a progress bar: `, }, { - Action: dbImport, - Name: "import", - Usage: "import chunks from a tar archive into a local chunk database (use - to read from stdin)", - ArgsUsage: " ", + Action: dbImport, + CustomHelpTemplate: helpTemplate, + Name: "import", + Usage: "import chunks from a tar archive into a local chunk database (use - to read from stdin)", + ArgsUsage: " ", Description: ` Import chunks from a tar archive into a local chunk database (use - to read from stdin). @@ -293,30 +420,24 @@ pv(1) tool to get a progress bar: `, }, { - Action: dbClean, - Name: "clean", - Usage: "remove corrupt entries from a local chunk database", - ArgsUsage: "", - Description: ` -Remove corrupt entries from a local chunk database. -`, + Action: dbClean, + CustomHelpTemplate: helpTemplate, + Name: "clean", + Usage: "remove corrupt entries from a local chunk database", + ArgsUsage: "", + Description: "Remove corrupt entries from a local chunk database", }, }, }, - { - Action: func(ctx *cli.Context) { - utils.Fatalf("ERROR: 'swarm cleandb' has been removed, please use 'swarm db clean'.") - }, - Name: "cleandb", - Usage: "DEPRECATED: use 'swarm db clean'", - ArgsUsage: " ", - Description: ` -DEPRECATED: use 'swarm db clean'. -`, - }, + // See config.go DumpConfigCommand, } + + // append a hidden help subcommand to all commands that have subcommands + // if a help command was already defined above, that one will take precedence. + addDefaultHelpSubcommands(app.Commands) + sort.Sort(cli.CommandsByName(app.Commands)) app.Flags = []cli.Flag{ @@ -339,10 +460,11 @@ DEPRECATED: use 'swarm db clean'. CorsStringFlag, EnsAPIFlag, SwarmTomlConfigPathFlag, - SwarmConfigPathFlag, SwarmSwapEnabledFlag, SwarmSwapAPIFlag, - SwarmSyncEnabledFlag, + SwarmSyncDisabledFlag, + SwarmSyncUpdateDelay, + SwarmDeliverySkipCheckFlag, SwarmListenAddrFlag, SwarmPortFlag, SwarmAccountFlag, @@ -350,23 +472,34 @@ DEPRECATED: use 'swarm db clean'. ChequebookAddrFlag, // upload flags SwarmApiFlag, - SwarmRecursiveUploadFlag, + SwarmRecursiveFlag, SwarmWantManifestFlag, SwarmUploadDefaultPath, SwarmUpFromStdinFlag, SwarmUploadMimeType, - //deprecated flags - DeprecatedEthAPIFlag, - DeprecatedEnsAddrFlag, + // storage flags + SwarmStorePath, + SwarmStoreCapacity, + SwarmStoreCacheCapacity, } + rpcFlags := []cli.Flag{ + utils.WSEnabledFlag, + utils.WSListenAddrFlag, + utils.WSPortFlag, + utils.WSApiFlag, + utils.WSAllowedOriginsFlag, + } + app.Flags = append(app.Flags, rpcFlags...) app.Flags = append(app.Flags, debug.Flags...) app.Flags = append(app.Flags, swarmmetrics.Flags...) + app.Flags = append(app.Flags, tracing.Flags...) app.Before = func(ctx *cli.Context) error { runtime.GOMAXPROCS(runtime.NumCPU()) - if err := debug.Setup(ctx); err != nil { + if err := debug.Setup(ctx, ""); err != nil { return err } swarmmetrics.Setup(ctx) + tracing.Setup(ctx) return nil } app.After = func(ctx *cli.Context) error { @@ -384,15 +517,12 @@ func main() { func version(ctx *cli.Context) error { fmt.Println(strings.Title(clientIdentifier)) - fmt.Println("Version:", params.Version) + fmt.Println("Version:", sv.VersionWithMeta) if gitCommit != "" { fmt.Println("Git Commit:", gitCommit) } - fmt.Println("Network Id:", ctx.GlobalInt(utils.NetworkIdFlag.Name)) fmt.Println("Go Version:", runtime.Version()) fmt.Println("OS:", runtime.GOOS) - fmt.Printf("GOPATH=%s\n", os.Getenv("GOPATH")) - fmt.Printf("GOROOT=%s\n", runtime.GOROOT()) return nil } @@ -405,7 +535,11 @@ func bzzd(ctx *cli.Context) error { } cfg := defaultNodeConfig - //XDC only supports --datadir via command line + + //pss operates on ws + cfg.WSModules = append(cfg.WSModules, "pss") + + //geth only supports --datadir via command line //in order to be consistent within swarm, if we pass --datadir via environment variable //or via config file, we get the same directory for XDC and swarm if _, err := os.Stat(bzzconfig.Path); err == nil { @@ -421,7 +555,7 @@ func bzzd(ctx *cli.Context) error { //due to overriding behavior initSwarmNode(bzzconfig, stack, ctx) //register BZZ as node.Service in the ethereum node - registerBzzService(bzzconfig, ctx, stack) + registerBzzService(bzzconfig, stack) //start the node utils.StartNode(stack) @@ -439,7 +573,7 @@ func bzzd(ctx *cli.Context) error { bootnodes := strings.Split(bzzconfig.BootNodes, ",") injectBootnodes(stack.Server(), bootnodes) } else { - if bzzconfig.NetworkId == 3 { + if bzzconfig.NetworkID == 3 { injectBootnodes(stack.Server(), testbetBootNodes) } } @@ -448,21 +582,11 @@ func bzzd(ctx *cli.Context) error { return nil } -func registerBzzService(bzzconfig *bzzapi.Config, ctx *cli.Context, stack *node.Node) { - +func registerBzzService(bzzconfig *bzzapi.Config, stack *node.Node) { //define the swarm service boot function - boot := func(ctx *node.ServiceContext) (node.Service, error) { - var swapClient *ethclient.Client - var err error - if bzzconfig.SwapApi != "" { - log.Info("connecting to SWAP API", "url", bzzconfig.SwapApi) - swapClient, err = ethclient.Dial(bzzconfig.SwapApi) - if err != nil { - return nil, fmt.Errorf("error connecting to SWAP API %s: %s", bzzconfig.SwapApi, err) - } - } - - return swarm.NewSwarm(ctx, swapClient, bzzconfig) + boot := func(_ *node.ServiceContext) (node.Service, error) { + // In production, mockStore must be always nil. + return swarm.NewSwarm(bzzconfig, nil) } //register within the ethereum node if err := stack.Register(boot); err != nil { @@ -487,6 +611,26 @@ func getAccount(bzzaccount string, ctx *cli.Context, stack *node.Node) *ecdsa.Pr return decryptStoreAccount(ks, bzzaccount, utils.MakePasswordList(ctx)) } +// getPrivKey returns the private key of the specified bzzaccount +// Used only by client commands, such as `resource` +func getPrivKey(ctx *cli.Context) *ecdsa.PrivateKey { + // booting up the swarm node just as we do in bzzd action + bzzconfig, err := buildConfig(ctx) + if err != nil { + utils.Fatalf("unable to configure swarm: %v", err) + } + cfg := defaultNodeConfig + if _, err := os.Stat(bzzconfig.Path); err == nil { + cfg.DataDir = bzzconfig.Path + } + utils.SetNodeConfig(ctx, &cfg) + stack, err := node.New(&cfg) + if err != nil { + utils.Fatalf("can't create node: %v", err) + } + return getAccount(bzzconfig.BzzAccount, ctx, stack) +} + func decryptStoreAccount(ks *keystore.KeyStore, account string, passwords []string) *ecdsa.PrivateKey { var a accounts.Account var err error @@ -551,3 +695,16 @@ func injectBootnodes(srv *p2p.Server, nodes []string) { srv.AddPeer(n) } } + +// addDefaultHelpSubcommand scans through defined CLI commands and adds +// a basic help subcommand to each +// if a help command is already defined, it will take precedence over the default. +func addDefaultHelpSubcommands(commands []cli.Command) { + for i := range commands { + cmd := &commands[i] + if cmd.Subcommands != nil { + cmd.Subcommands = append(cmd.Subcommands, defaultSubcommandHelp) + addDefaultHelpSubcommands(cmd.Subcommands) + } + } +} diff --git a/cmd/swarm/manifest.go b/cmd/swarm/manifest.go index 41a69a5d05..82166edf6c 100644 --- a/cmd/swarm/manifest.go +++ b/cmd/swarm/manifest.go @@ -131,13 +131,13 @@ func addEntryToManifest(ctx *cli.Context, mhash, path, hash, ctype string) strin longestPathEntry = api.ManifestEntry{} ) - mroot, err := client.DownloadManifest(mhash) + mroot, isEncrypted, err := client.DownloadManifest(mhash) if err != nil { utils.Fatalf("Manifest download failed: %v", err) } //TODO: check if the "hash" to add is valid and present in swarm - _, err = client.DownloadManifest(hash) + _, _, err = client.DownloadManifest(hash) if err != nil { utils.Fatalf("Hash to add is not present: %v", err) } @@ -180,7 +180,7 @@ func addEntryToManifest(ctx *cli.Context, mhash, path, hash, ctype string) strin mroot.Entries = append(mroot.Entries, newEntry) } - newManifestHash, err := client.UploadManifest(mroot) + newManifestHash, err := client.UploadManifest(mroot, isEncrypted) if err != nil { utils.Fatalf("Manifest upload failed: %v", err) } @@ -197,7 +197,7 @@ func updateEntryInManifest(ctx *cli.Context, mhash, path, hash, ctype string) st longestPathEntry = api.ManifestEntry{} ) - mroot, err := client.DownloadManifest(mhash) + mroot, isEncrypted, err := client.DownloadManifest(mhash) if err != nil { utils.Fatalf("Manifest download failed: %v", err) } @@ -257,7 +257,7 @@ func updateEntryInManifest(ctx *cli.Context, mhash, path, hash, ctype string) st mroot = newMRoot } - newManifestHash, err := client.UploadManifest(mroot) + newManifestHash, err := client.UploadManifest(mroot, isEncrypted) if err != nil { utils.Fatalf("Manifest upload failed: %v", err) } @@ -273,7 +273,7 @@ func removeEntryFromManifest(ctx *cli.Context, mhash, path string) string { longestPathEntry = api.ManifestEntry{} ) - mroot, err := client.DownloadManifest(mhash) + mroot, isEncrypted, err := client.DownloadManifest(mhash) if err != nil { utils.Fatalf("Manifest download failed: %v", err) } @@ -323,7 +323,7 @@ func removeEntryFromManifest(ctx *cli.Context, mhash, path string) string { mroot = newMRoot } - newManifestHash, err := client.UploadManifest(mroot) + newManifestHash, err := client.UploadManifest(mroot, isEncrypted) if err != nil { utils.Fatalf("Manifest upload failed: %v", err) } diff --git a/cmd/swarm/mru.go b/cmd/swarm/mru.go new file mode 100644 index 0000000000..6176b6d6c8 --- /dev/null +++ b/cmd/swarm/mru.go @@ -0,0 +1,169 @@ +// Copyright 2016 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 . + +// Command resource allows the user to create and update signed mutable resource updates +package main + +import ( + "fmt" + "strconv" + "strings" + + "github.com/ethereum/go-ethereum/common/hexutil" + + "github.com/ethereum/go-ethereum/cmd/utils" + swarm "github.com/ethereum/go-ethereum/swarm/api/client" + "github.com/ethereum/go-ethereum/swarm/storage/mru" + "gopkg.in/urfave/cli.v1" +) + +func NewGenericSigner(ctx *cli.Context) mru.Signer { + return mru.NewGenericSigner(getPrivKey(ctx)) +} + +// swarm resource create [--name ] [--data <0x Hexdata> [--multihash=false]] +// swarm resource update <0x Hexdata> [--multihash=false] +// swarm resource info + +func resourceCreate(ctx *cli.Context) { + args := ctx.Args() + + var ( + bzzapi = strings.TrimRight(ctx.GlobalString(SwarmApiFlag.Name), "/") + client = swarm.NewClient(bzzapi) + multihash = ctx.Bool(SwarmResourceMultihashFlag.Name) + initialData = ctx.String(SwarmResourceDataOnCreateFlag.Name) + name = ctx.String(SwarmResourceNameFlag.Name) + ) + + if len(args) < 1 { + fmt.Println("Incorrect number of arguments") + cli.ShowCommandHelpAndExit(ctx, "create", 1) + return + } + signer := NewGenericSigner(ctx) + frequency, err := strconv.ParseUint(args[0], 10, 64) + if err != nil { + fmt.Printf("Frequency formatting error: %s\n", err.Error()) + cli.ShowCommandHelpAndExit(ctx, "create", 1) + return + } + + metadata := mru.ResourceMetadata{ + Name: name, + Frequency: frequency, + Owner: signer.Address(), + } + + var newResourceRequest *mru.Request + if initialData != "" { + initialDataBytes, err := hexutil.Decode(initialData) + if err != nil { + fmt.Printf("Error parsing data: %s\n", err.Error()) + cli.ShowCommandHelpAndExit(ctx, "create", 1) + return + } + newResourceRequest, err = mru.NewCreateUpdateRequest(&metadata) + if err != nil { + utils.Fatalf("Error creating new resource request: %s", err) + } + newResourceRequest.SetData(initialDataBytes, multihash) + if err = newResourceRequest.Sign(signer); err != nil { + utils.Fatalf("Error signing resource update: %s", err.Error()) + } + } else { + newResourceRequest, err = mru.NewCreateRequest(&metadata) + if err != nil { + utils.Fatalf("Error creating new resource request: %s", err) + } + } + + manifestAddress, err := client.CreateResource(newResourceRequest) + if err != nil { + utils.Fatalf("Error creating resource: %s", err.Error()) + return + } + fmt.Println(manifestAddress) // output manifest address to the user in a single line (useful for other commands to pick up) + +} + +func resourceUpdate(ctx *cli.Context) { + args := ctx.Args() + + var ( + bzzapi = strings.TrimRight(ctx.GlobalString(SwarmApiFlag.Name), "/") + client = swarm.NewClient(bzzapi) + multihash = ctx.Bool(SwarmResourceMultihashFlag.Name) + ) + + if len(args) < 2 { + fmt.Println("Incorrect number of arguments") + cli.ShowCommandHelpAndExit(ctx, "update", 1) + return + } + signer := NewGenericSigner(ctx) + manifestAddressOrDomain := args[0] + data, err := hexutil.Decode(args[1]) + if err != nil { + utils.Fatalf("Error parsing data: %s", err.Error()) + return + } + + // Retrieve resource status and metadata out of the manifest + updateRequest, err := client.GetResourceMetadata(manifestAddressOrDomain) + if err != nil { + utils.Fatalf("Error retrieving resource status: %s", err.Error()) + } + + // set the new data + updateRequest.SetData(data, multihash) + + // sign update + if err = updateRequest.Sign(signer); err != nil { + utils.Fatalf("Error signing resource update: %s", err.Error()) + } + + // post update + err = client.UpdateResource(updateRequest) + if err != nil { + utils.Fatalf("Error updating resource: %s", err.Error()) + return + } +} + +func resourceInfo(ctx *cli.Context) { + var ( + bzzapi = strings.TrimRight(ctx.GlobalString(SwarmApiFlag.Name), "/") + client = swarm.NewClient(bzzapi) + ) + args := ctx.Args() + if len(args) < 1 { + fmt.Println("Incorrect number of arguments.") + cli.ShowCommandHelpAndExit(ctx, "info", 1) + return + } + manifestAddressOrDomain := args[0] + metadata, err := client.GetResourceMetadata(manifestAddressOrDomain) + if err != nil { + utils.Fatalf("Error retrieving resource metadata: %s", err.Error()) + return + } + encodedMetadata, err := metadata.MarshalJSON() + if err != nil { + utils.Fatalf("Error encoding metadata to JSON for display:%s", err) + } + fmt.Println(string(encodedMetadata)) +} diff --git a/cmd/swarm/run_test.go b/cmd/swarm/run_test.go index 594cfa55cb..a70c4686dd 100644 --- a/cmd/swarm/run_test.go +++ b/cmd/swarm/run_test.go @@ -81,6 +81,7 @@ type testCluster struct { // // When starting more than one node, they are connected together using the // admin SetPeer RPC method. + func newTestCluster(t *testing.T, size int) *testCluster { cluster := &testCluster{} defer func() { @@ -96,18 +97,7 @@ func newTestCluster(t *testing.T, size int) *testCluster { cluster.TmpDir = tmpdir // start the nodes - cluster.Nodes = make([]*testNode, 0, size) - for i := 0; i < size; i++ { - dir := filepath.Join(cluster.TmpDir, fmt.Sprintf("swarm%02d", i)) - if err := os.Mkdir(dir, 0700); err != nil { - t.Fatal(err) - } - - node := newTestNode(t, dir) - node.Name = fmt.Sprintf("swarm%02d", i) - - cluster.Nodes = append(cluster.Nodes, node) - } + cluster.StartNewNodes(t, size) if size == 1 { return cluster @@ -145,14 +135,51 @@ func (c *testCluster) Shutdown() { os.RemoveAll(c.TmpDir) } +func (c *testCluster) Stop() { + for _, node := range c.Nodes { + node.Shutdown() + } +} + +func (c *testCluster) StartNewNodes(t *testing.T, size int) { + c.Nodes = make([]*testNode, 0, size) + for i := 0; i < size; i++ { + dir := filepath.Join(c.TmpDir, fmt.Sprintf("swarm%02d", i)) + if err := os.Mkdir(dir, 0700); err != nil { + t.Fatal(err) + } + + node := newTestNode(t, dir) + node.Name = fmt.Sprintf("swarm%02d", i) + + c.Nodes = append(c.Nodes, node) + } +} + +func (c *testCluster) StartExistingNodes(t *testing.T, size int, bzzaccount string) { + c.Nodes = make([]*testNode, 0, size) + for i := 0; i < size; i++ { + dir := filepath.Join(c.TmpDir, fmt.Sprintf("swarm%02d", i)) + node := existingTestNode(t, dir, bzzaccount) + node.Name = fmt.Sprintf("swarm%02d", i) + + c.Nodes = append(c.Nodes, node) + } +} + +func (c *testCluster) Cleanup() { + os.RemoveAll(c.TmpDir) +} + type testNode struct { - Name string - Addr string - URL string - Enode string - Dir string - Client *rpc.Client - Cmd *cmdtest.TestCmd + Name string + Addr string + URL string + Enode string + Dir string + IpcPath string + Client *rpc.Client + Cmd *cmdtest.TestCmd } const testPassphrase = "swarm-test-passphrase" @@ -181,6 +208,72 @@ func getTestAccount(t *testing.T, dir string) (conf *node.Config, account accoun return conf, account } +func existingTestNode(t *testing.T, dir string, bzzaccount string) *testNode { + conf, _ := getTestAccount(t, dir) + node := &testNode{Dir: dir} + + // use a unique IPCPath when running tests on Windows + if runtime.GOOS == "windows" { + conf.IPCPath = fmt.Sprintf("bzzd-%s.ipc", bzzaccount) + } + + // assign ports + httpPort, err := assignTCPPort() + if err != nil { + t.Fatal(err) + } + p2pPort, err := assignTCPPort() + if err != nil { + t.Fatal(err) + } + + // start the node + node.Cmd = runSwarm(t, + "--port", p2pPort, + "--nodiscover", + "--datadir", dir, + "--ipcpath", conf.IPCPath, + "--ens-api", "", + "--bzzaccount", bzzaccount, + "--bzznetworkid", "321", + "--bzzport", httpPort, + "--verbosity", "6", + ) + node.Cmd.InputLine(testPassphrase) + defer func() { + if t.Failed() { + node.Shutdown() + } + }() + + // wait for the node to start + for start := time.Now(); time.Since(start) < 10*time.Second; time.Sleep(50 * time.Millisecond) { + node.Client, err = rpc.Dial(conf.IPCEndpoint()) + if err == nil { + break + } + } + if node.Client == nil { + t.Fatal(err) + } + + // load info + var info swarm.Info + if err := node.Client.Call(&info, "bzz_info"); err != nil { + t.Fatal(err) + } + node.Addr = net.JoinHostPort("127.0.0.1", info.Port) + node.URL = "http://" + node.Addr + + var nodeInfo p2p.NodeInfo + if err := node.Client.Call(&nodeInfo, "admin_nodeInfo"); err != nil { + t.Fatal(err) + } + node.Enode = fmt.Sprintf("enode://%s@127.0.0.1:%s", nodeInfo.ID, p2pPort) + + return node +} + func newTestNode(t *testing.T, dir string) *testNode { conf, account := getTestAccount(t, dir) @@ -239,6 +332,7 @@ func newTestNode(t *testing.T, dir string) *testNode { t.Fatal(err) } node.Enode = fmt.Sprintf("enode://%s@127.0.0.1:%s", nodeInfo.ID, p2pPort) + node.IpcPath = conf.IPCPath return node } diff --git a/cmd/swarm/swarm-smoke/main.go b/cmd/swarm/swarm-smoke/main.go new file mode 100644 index 0000000000..87bc39816d --- /dev/null +++ b/cmd/swarm/swarm-smoke/main.go @@ -0,0 +1,101 @@ +// Copyright 2018 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 ( + "os" + "sort" + + "github.com/ethereum/go-ethereum/log" + colorable "github.com/mattn/go-colorable" + + cli "gopkg.in/urfave/cli.v1" +) + +var ( + endpoints []string + includeLocalhost bool + cluster string + scheme string + filesize int + from int + to int +) + +func main() { + log.PrintOrigins(true) + log.Root().SetHandler(log.LvlFilterHandler(log.LvlTrace, log.StreamHandler(colorable.NewColorableStderr(), log.TerminalFormat(true)))) + + app := cli.NewApp() + app.Name = "smoke-test" + app.Usage = "" + + app.Flags = []cli.Flag{ + cli.StringFlag{ + Name: "cluster-endpoint", + Value: "testing", + Usage: "cluster to point to (open, or testing)", + Destination: &cluster, + }, + cli.IntFlag{ + Name: "cluster-from", + Value: 8501, + Usage: "swarm node (from)", + Destination: &from, + }, + cli.IntFlag{ + Name: "cluster-to", + Value: 8512, + Usage: "swarm node (to)", + Destination: &to, + }, + cli.StringFlag{ + Name: "cluster-scheme", + Value: "http", + Usage: "http or https", + Destination: &scheme, + }, + cli.BoolFlag{ + Name: "include-localhost", + Usage: "whether to include localhost:8500 as an endpoint", + Destination: &includeLocalhost, + }, + cli.IntFlag{ + Name: "filesize", + Value: 1, + Usage: "file size for generated random file in MB", + Destination: &filesize, + }, + } + + app.Commands = []cli.Command{ + { + Name: "upload_and_sync", + Aliases: []string{"c"}, + Usage: "upload and sync", + Action: cliUploadAndSync, + }, + } + + sort.Sort(cli.FlagsByName(app.Flags)) + sort.Sort(cli.CommandsByName(app.Commands)) + + err := app.Run(os.Args) + if err != nil { + log.Error(err.Error()) + } +} diff --git a/cmd/swarm/swarm-smoke/upload_and_sync.go b/cmd/swarm/swarm-smoke/upload_and_sync.go new file mode 100644 index 0000000000..d5300b63d9 --- /dev/null +++ b/cmd/swarm/swarm-smoke/upload_and_sync.go @@ -0,0 +1,191 @@ +// Copyright 2018 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 ( + "bytes" + "crypto/md5" + "crypto/rand" + "fmt" + "io" + "io/ioutil" + "net/http" + "os" + "os/exec" + "strings" + "sync" + "time" + + "github.com/ethereum/go-ethereum/log" + "github.com/pborman/uuid" + + cli "gopkg.in/urfave/cli.v1" +) + +func generateEndpoints(scheme string, cluster string, from int, to int) { + if cluster == "prod" { + cluster = "" + } else { + cluster = cluster + "." + } + + for port := from; port <= to; port++ { + endpoints = append(endpoints, fmt.Sprintf("%s://%v.%sswarm-gateways.net", scheme, port, cluster)) + } + + if includeLocalhost { + endpoints = append(endpoints, "http://localhost:8500") + } +} + +func cliUploadAndSync(c *cli.Context) error { + defer func(now time.Time) { log.Info("total time", "time", time.Since(now), "size", filesize) }(time.Now()) + + generateEndpoints(scheme, cluster, from, to) + + log.Info("uploading to " + endpoints[0] + " and syncing") + + f, cleanup := generateRandomFile(filesize * 1000000) + defer cleanup() + + hash, err := upload(f, endpoints[0]) + if err != nil { + log.Error(err.Error()) + return err + } + + fhash, err := digest(f) + if err != nil { + log.Error(err.Error()) + return err + } + + log.Info("uploaded successfully", "hash", hash, "digest", fmt.Sprintf("%x", fhash)) + + if filesize < 10 { + time.Sleep(35 * time.Second) + } else { + time.Sleep(15 * time.Second) + time.Sleep(2 * time.Duration(filesize) * time.Second) + } + + wg := sync.WaitGroup{} + for _, endpoint := range endpoints { + endpoint := endpoint + ruid := uuid.New()[:8] + wg.Add(1) + go func(endpoint string, ruid string) { + for { + err := fetch(hash, endpoint, fhash, ruid) + if err != nil { + continue + } + + wg.Done() + return + } + }(endpoint, ruid) + } + wg.Wait() + log.Info("all endpoints synced random file successfully") + + return nil +} + +// fetch is getting the requested `hash` from the `endpoint` and compares it with the `original` file +func fetch(hash string, endpoint string, original []byte, ruid string) error { + log.Trace("sleeping", "ruid", ruid) + time.Sleep(5 * time.Second) + + log.Trace("http get request", "ruid", ruid, "api", endpoint, "hash", hash) + res, err := http.Get(endpoint + "/bzz:/" + hash + "/") + if err != nil { + log.Warn(err.Error(), "ruid", ruid) + return err + } + log.Trace("http get response", "ruid", ruid, "api", endpoint, "hash", hash, "code", res.StatusCode, "len", res.ContentLength) + + if res.StatusCode != 200 { + err := fmt.Errorf("expected status code %d, got %v", 200, res.StatusCode) + log.Warn(err.Error(), "ruid", ruid) + return err + } + + defer res.Body.Close() + + rdigest, err := digest(res.Body) + if err != nil { + log.Warn(err.Error(), "ruid", ruid) + return err + } + + if !bytes.Equal(rdigest, original) { + err := fmt.Errorf("downloaded imported file md5=%x is not the same as the generated one=%x", rdigest, original) + log.Warn(err.Error(), "ruid", ruid) + return err + } + + log.Trace("downloaded file matches random file", "ruid", ruid, "len", res.ContentLength) + + return nil +} + +// upload is uploading a file `f` to `endpoint` via the `swarm up` cmd +func upload(f *os.File, endpoint string) (string, error) { + var out bytes.Buffer + cmd := exec.Command("swarm", "--bzzapi", endpoint, "up", f.Name()) + cmd.Stdout = &out + err := cmd.Run() + if err != nil { + return "", err + } + hash := strings.TrimRight(out.String(), "\r\n") + return hash, nil +} + +func digest(r io.Reader) ([]byte, error) { + h := md5.New() + _, err := io.Copy(h, r) + if err != nil { + return nil, err + } + return h.Sum(nil), nil +} + +// generateRandomFile is creating a temporary file with the requested byte size +func generateRandomFile(size int) (f *os.File, teardown func()) { + // create a tmp file + tmp, err := ioutil.TempFile("", "swarm-test") + if err != nil { + panic(err) + } + + // callback for tmp file cleanup + teardown = func() { + tmp.Close() + os.Remove(tmp.Name()) + } + + buf := make([]byte, size) + _, err = rand.Read(buf) + if err != nil { + panic(err) + } + ioutil.WriteFile(tmp.Name(), buf, 0755) + + return tmp, teardown +} diff --git a/cmd/swarm/upload.go b/cmd/swarm/upload.go index 9f4c525bb9..8ba0e7c5f0 100644 --- a/cmd/swarm/upload.go +++ b/cmd/swarm/upload.go @@ -40,12 +40,13 @@ func upload(ctx *cli.Context) { args := ctx.Args() var ( bzzapi = strings.TrimRight(ctx.GlobalString(SwarmApiFlag.Name), "/") - recursive = ctx.GlobalBool(SwarmRecursiveUploadFlag.Name) + recursive = ctx.GlobalBool(SwarmRecursiveFlag.Name) wantManifest = ctx.GlobalBoolT(SwarmWantManifestFlag.Name) defaultPath = ctx.GlobalString(SwarmUploadDefaultPath.Name) fromStdin = ctx.GlobalBool(SwarmUpFromStdinFlag.Name) mimeType = ctx.GlobalString(SwarmUploadMimeType.Name) client = swarm.NewClient(bzzapi) + toEncrypt = ctx.Bool(SwarmEncryptedFlag.Name) file string ) @@ -76,7 +77,7 @@ func upload(ctx *cli.Context) { utils.Fatalf("Error opening file: %s", err) } defer f.Close() - hash, err := client.UploadRaw(f, f.Size) + hash, err := client.UploadRaw(f, f.Size, toEncrypt) if err != nil { utils.Fatalf("Upload failed: %s", err) } @@ -97,7 +98,7 @@ func upload(ctx *cli.Context) { if !recursive { return "", errors.New("Argument is a directory and recursive upload is disabled") } - return client.UploadDirectory(file, defaultPath, "") + return client.UploadDirectory(file, defaultPath, "", toEncrypt) } } else { doUpload = func() (string, error) { @@ -110,7 +111,7 @@ func upload(ctx *cli.Context) { mimeType = detectMimeType(file) } f.ContentType = mimeType - return client.Upload(f, "") + return client.Upload(f, "", toEncrypt) } } hash, err := doUpload() diff --git a/cmd/swarm/upload_test.go b/cmd/swarm/upload_test.go index df7fc216af..2afc9b3a11 100644 --- a/cmd/swarm/upload_test.go +++ b/cmd/swarm/upload_test.go @@ -17,60 +17,259 @@ package main import ( + "bytes" + "flag" + "fmt" "io" "io/ioutil" "net/http" "os" + "path" + "path/filepath" + "strings" "testing" + "time" + + "github.com/ethereum/go-ethereum/log" + swarm "github.com/ethereum/go-ethereum/swarm/api/client" + colorable "github.com/mattn/go-colorable" ) +var loglevel = flag.Int("loglevel", 3, "verbosity of logs") + +func init() { + log.PrintOrigins(true) + log.Root().SetHandler(log.LvlFilterHandler(log.Lvl(*loglevel), log.StreamHandler(colorable.NewColorableStderr(), log.TerminalFormat(true)))) +} + // TestCLISwarmUp tests that running 'swarm up' makes the resulting file // available from all nodes via the HTTP API func TestCLISwarmUp(t *testing.T) { - // start 3 node cluster - t.Log("starting 3 node cluster") + testCLISwarmUp(false, t) +} +func TestCLISwarmUpRecursive(t *testing.T) { + testCLISwarmUpRecursive(false, t) +} + +// TestCLISwarmUpEncrypted tests that running 'swarm encrypted-up' makes the resulting file +// available from all nodes via the HTTP API +func TestCLISwarmUpEncrypted(t *testing.T) { + testCLISwarmUp(true, t) +} +func TestCLISwarmUpEncryptedRecursive(t *testing.T) { + testCLISwarmUpRecursive(true, t) +} + +func testCLISwarmUp(toEncrypt bool, t *testing.T) { + log.Info("starting 3 node cluster") cluster := newTestCluster(t, 3) defer cluster.Shutdown() // create a tmp file tmp, err := ioutil.TempFile("", "swarm-test") - assertNil(t, err) - defer tmp.Close() - defer os.Remove(tmp.Name()) - _, err = io.WriteString(tmp, "data") - assertNil(t, err) - - // upload the file with 'swarm up' and expect a hash - t.Log("uploading file with 'swarm up'") - up := runSwarm(t, "--bzzapi", cluster.Nodes[0].URL, "up", tmp.Name()) - _, matches := up.ExpectRegexp(`[a-f\d]{64}`) - up.ExpectExit() - hash := matches[0] - t.Logf("file uploaded with hash %s", hash) - - // get the file from the HTTP API of each node - for _, node := range cluster.Nodes { - t.Logf("getting file from %s", node.Name) - res, err := http.Get(node.URL + "/bzz:/" + hash) - assertNil(t, err) - assertHTTPResponse(t, res, http.StatusOK, "data") - } -} - -func assertNil(t *testing.T, err error) { if err != nil { t.Fatal(err) } + defer tmp.Close() + defer os.Remove(tmp.Name()) + + // write data to file + data := "notsorandomdata" + _, err = io.WriteString(tmp, data) + if err != nil { + t.Fatal(err) + } + + hashRegexp := `[a-f\d]{64}` + flags := []string{ + "--bzzapi", cluster.Nodes[0].URL, + "up", + tmp.Name()} + if toEncrypt { + hashRegexp = `[a-f\d]{128}` + flags = []string{ + "--bzzapi", cluster.Nodes[0].URL, + "up", + "--encrypt", + tmp.Name()} + } + // upload the file with 'swarm up' and expect a hash + log.Info(fmt.Sprintf("uploading file with 'swarm up'")) + up := runSwarm(t, flags...) + _, matches := up.ExpectRegexp(hashRegexp) + up.ExpectExit() + hash := matches[0] + log.Info("file uploaded", "hash", hash) + + // get the file from the HTTP API of each node + for _, node := range cluster.Nodes { + log.Info("getting file from node", "node", node.Name) + + res, err := http.Get(node.URL + "/bzz:/" + hash) + if err != nil { + t.Fatal(err) + } + defer res.Body.Close() + + reply, err := ioutil.ReadAll(res.Body) + if err != nil { + t.Fatal(err) + } + if res.StatusCode != 200 { + t.Fatalf("expected HTTP status 200, got %s", res.Status) + } + if string(reply) != data { + t.Fatalf("expected HTTP body %q, got %q", data, reply) + } + log.Debug("verifying uploaded file using `swarm down`") + //try to get the content with `swarm down` + tmpDownload, err := ioutil.TempDir("", "swarm-test") + tmpDownload = path.Join(tmpDownload, "tmpfile.tmp") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(tmpDownload) + + bzzLocator := "bzz:/" + hash + flags = []string{ + "--bzzapi", cluster.Nodes[0].URL, + "down", + bzzLocator, + tmpDownload, + } + + down := runSwarm(t, flags...) + down.ExpectExit() + + fi, err := os.Stat(tmpDownload) + if err != nil { + t.Fatalf("could not stat path: %v", err) + } + + switch mode := fi.Mode(); { + case mode.IsRegular(): + downloadedBytes, err := ioutil.ReadFile(tmpDownload) + if err != nil { + t.Fatalf("had an error reading the downloaded file: %v", err) + } + if !bytes.Equal(downloadedBytes, bytes.NewBufferString(data).Bytes()) { + t.Fatalf("retrieved data and posted data not equal!") + } + + default: + t.Fatalf("expected to download regular file, got %s", fi.Mode()) + } + } + + timeout := time.Duration(2 * time.Second) + httpClient := http.Client{ + Timeout: timeout, + } + + // try to squeeze a timeout by getting an non-existent hash from each node + for _, node := range cluster.Nodes { + _, err := httpClient.Get(node.URL + "/bzz:/1023e8bae0f70be7d7b5f74343088ba408a218254391490c85ae16278e230340") + // we're speeding up the timeout here since netstore has a 60 seconds timeout on a request + if err != nil && !strings.Contains(err.Error(), "Client.Timeout exceeded while awaiting headers") { + t.Fatal(err) + } + // this is disabled since it takes 60s due to netstore timeout + // if res.StatusCode != 404 { + // t.Fatalf("expected HTTP status 404, got %s", res.Status) + // } + } } -func assertHTTPResponse(t *testing.T, res *http.Response, expectedStatus int, expectedBody string) { - defer res.Body.Close() - if res.StatusCode != expectedStatus { - t.Fatalf("expected HTTP status %d, got %s", expectedStatus, res.Status) +func testCLISwarmUpRecursive(toEncrypt bool, t *testing.T) { + fmt.Println("starting 3 node cluster") + cluster := newTestCluster(t, 3) + defer cluster.Shutdown() + + tmpUploadDir, err := ioutil.TempDir("", "swarm-test") + if err != nil { + t.Fatal(err) } - data, err := ioutil.ReadAll(res.Body) - assertNil(t, err) - if string(data) != expectedBody { - t.Fatalf("expected HTTP body %q, got %q", expectedBody, data) + defer os.RemoveAll(tmpUploadDir) + // create tmp files + data := "notsorandomdata" + for _, path := range []string{"tmp1", "tmp2"} { + if err := ioutil.WriteFile(filepath.Join(tmpUploadDir, path), bytes.NewBufferString(data).Bytes(), 0644); err != nil { + t.Fatal(err) + } + } + + hashRegexp := `[a-f\d]{64}` + flags := []string{ + "--bzzapi", cluster.Nodes[0].URL, + "--recursive", + "up", + tmpUploadDir} + if toEncrypt { + hashRegexp = `[a-f\d]{128}` + flags = []string{ + "--bzzapi", cluster.Nodes[0].URL, + "--recursive", + "up", + "--encrypt", + tmpUploadDir} + } + // upload the file with 'swarm up' and expect a hash + log.Info(fmt.Sprintf("uploading file with 'swarm up'")) + up := runSwarm(t, flags...) + _, matches := up.ExpectRegexp(hashRegexp) + up.ExpectExit() + hash := matches[0] + log.Info("dir uploaded", "hash", hash) + + // get the file from the HTTP API of each node + for _, node := range cluster.Nodes { + log.Info("getting file from node", "node", node.Name) + //try to get the content with `swarm down` + tmpDownload, err := ioutil.TempDir("", "swarm-test") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(tmpDownload) + bzzLocator := "bzz:/" + hash + flagss := []string{} + flagss = []string{ + "--bzzapi", cluster.Nodes[0].URL, + "down", + "--recursive", + bzzLocator, + tmpDownload, + } + + fmt.Println("downloading from swarm with recursive") + down := runSwarm(t, flagss...) + down.ExpectExit() + + files, err := ioutil.ReadDir(tmpDownload) + for _, v := range files { + fi, err := os.Stat(path.Join(tmpDownload, v.Name())) + if err != nil { + t.Fatalf("got an error: %v", err) + } + + switch mode := fi.Mode(); { + case mode.IsRegular(): + if file, err := swarm.Open(path.Join(tmpDownload, v.Name())); err != nil { + t.Fatalf("encountered an error opening the file returned from the CLI: %v", err) + } else { + ff := make([]byte, len(data)) + io.ReadFull(file, ff) + buf := bytes.NewBufferString(data) + + if !bytes.Equal(ff, buf.Bytes()) { + t.Fatalf("retrieved data and posted data not equal!") + } + } + default: + t.Fatalf("this shouldnt happen") + } + } + if err != nil { + t.Fatalf("could not list files at: %v", files) + } } } diff --git a/cmd/utils/cmd.go b/cmd/utils/cmd.go index c0af4c13e7..58d72f32ba 100644 --- a/cmd/utils/cmd.go +++ b/cmd/utils/cmd.go @@ -29,6 +29,7 @@ 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/types" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethdb" @@ -271,15 +272,13 @@ func ImportPreimages(db *ethdb.LDBDatabase, fn string) error { // Accumulate the preimages and flush when enough ws gathered preimages[crypto.Keccak256Hash(blob)] = common.CopyBytes(blob) if len(preimages) > 1024 { - if err := core.WritePreimages(db, 0, preimages); err != nil { - return err - } + rawdb.WritePreimages(db, 0, preimages) preimages = make(map[common.Hash][]byte) } } // Flush the last batch preimage data if len(preimages) > 0 { - return core.WritePreimages(db, 0, preimages) + rawdb.WritePreimages(db, 0, preimages) } return nil } diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 8d40b9f0c5..73d4ab30cb 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -27,6 +27,7 @@ import ( "runtime" "strconv" "strings" + "time" "github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/accounts/keystore" @@ -48,6 +49,7 @@ import ( "github.com/ethereum/go-ethereum/les" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/metrics" + "github.com/ethereum/go-ethereum/metrics/influxdb" "github.com/ethereum/go-ethereum/node" "github.com/ethereum/go-ethereum/p2p" "github.com/ethereum/go-ethereum/p2p/discover" @@ -64,7 +66,7 @@ var ( {{if .cmd.Description}}{{.cmd.Description}} {{end}}{{if .cmd.Subcommands}} SUBCOMMANDS: - {{range .cmd.Subcommands}}{{.cmd.Name}}{{with .cmd.ShortName}}, {{.cmd}}{{end}}{{ "\t" }}{{.cmd.Usage}} + {{range .cmd.Subcommands}}{{.Name}}{{with .ShortName}}, {{.}}{{end}}{{ "\t" }}{{.Usage}} {{end}}{{end}}{{if .categorizedFlags}} {{range $idx, $categorized := .categorizedFlags}}{{$categorized.Name}} OPTIONS: {{range $categorized.Flags}}{{"\t"}}{{.}} @@ -96,7 +98,7 @@ func NewApp(gitCommit, usage string) *cli.App { app.Author = "" //app.Authors = nil app.Email = "" - app.Version = params.Version + app.Version = params.VersionWithMeta if len(gitCommit) >= 8 { app.Version += "-" + gitCommit[:8] } @@ -176,11 +178,11 @@ var ( } FastSyncFlag = cli.BoolFlag{ Name: "fast", - Usage: "Enable fast syncing through state downloads", + Usage: "Enable fast syncing through state downloads (replaced by --syncmode)", } LightModeFlag = cli.BoolFlag{ Name: "light", - Usage: "Enable light client mode", + Usage: "Enable light client mode (replaced by --syncmode)", } defaultSyncMode = eth.DefaultConfig.SyncMode SyncModeFlag = TextMarshalerFlag{ @@ -209,7 +211,7 @@ var ( } // Dashboard settings DashboardEnabledFlag = cli.BoolFlag{ - Name: "dashboard", + Name: metrics.DashboardEnabledFlag, Usage: "Enable the dashboard", } DashboardAddrFlag = cli.StringFlag{ @@ -378,10 +380,6 @@ var ( Name: "ethstats", Usage: "Reporting URL of a ethstats service (nodename:secret@host:port)", } - MetricsEnabledFlag = cli.BoolFlag{ - Name: metrics.MetricsEnabledFlag, - Usage: "Enable metrics collection and reporting", - } FakePoWFlag = cli.BoolFlag{ Name: "fakepow", Usage: "Disables proof-of-work verification", @@ -550,6 +548,45 @@ var ( Usage: "Minimum POW accepted", Value: whisper.DefaultMinimumPoW, } + + // Metrics flags + MetricsEnabledFlag = cli.BoolFlag{ + Name: metrics.MetricsEnabledFlag, + Usage: "Enable metrics collection and reporting", + } + MetricsEnableInfluxDBFlag = cli.BoolFlag{ + Name: "metrics.influxdb", + Usage: "Enable metrics export/push to an external InfluxDB database", + } + MetricsInfluxDBEndpointFlag = cli.StringFlag{ + Name: "metrics.influxdb.endpoint", + Usage: "InfluxDB API endpoint to report metrics to", + Value: "http://localhost:8086", + } + MetricsInfluxDBDatabaseFlag = cli.StringFlag{ + Name: "metrics.influxdb.database", + Usage: "InfluxDB database name to push reported metrics to", + Value: "geth", + } + MetricsInfluxDBUsernameFlag = cli.StringFlag{ + Name: "metrics.influxdb.username", + Usage: "Username to authorize access to the database", + Value: "test", + } + MetricsInfluxDBPasswordFlag = cli.StringFlag{ + Name: "metrics.influxdb.password", + Usage: "Password to authorize access to the database", + Value: "test", + } + // The `host` tag is part of every measurement sent to InfluxDB. Queries on tags are faster in InfluxDB. + // It is used so that we can group all nodes and average a measurement across all of them, but also so + // that we can select a specific node and inspect its measurements. + // https://docs.influxdata.com/influxdb/v1.4/concepts/key_concepts/#tag-key + MetricsInfluxDBHostTagFlag = cli.StringFlag{ + Name: "metrics.influxdb.host.tag", + Usage: "InfluxDB `host` tag attached to all measurements", + Value: "localhost", + } ) // MakeDataDir retrieves the currently requested data directory, terminating @@ -625,8 +662,7 @@ func setBootstrapNodes(ctx *cli.Context, cfg *p2p.Config) { for _, url := range urls { node, err := discover.ParseNode(url) if err != nil { - log.Error("Bootstrap URL invalid", "enode", url, "err", err) - continue + log.Crit("Bootstrap URL invalid", "enode", url, "err", err) } cfg.BootstrapNodes = append(cfg.BootstrapNodes, node) } @@ -983,7 +1019,7 @@ func setEthash(ctx *cli.Context, cfg *eth.Config) { } } -// checkExclusive verifies that only a single isntance of the provided flags was +// 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{}) { @@ -1111,6 +1147,9 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *eth.Config) { } cfg.Genesis = core.DefaultRinkebyGenesisBlock() case ctx.GlobalBool(DeveloperFlag.Name): + if !ctx.GlobalIsSet(NetworkIdFlag.Name) { + cfg.NetworkId = 1337 + } // Create new developer account or reuse existing one var ( developer accounts.Account @@ -1172,7 +1211,7 @@ func RegisterEthService(stack *node.Node, cfg *eth.Config) { // RegisterDashboardService adds a dashboard to the stack. func RegisterDashboardService(stack *node.Node, cfg *dashboard.Config, commit string) { stack.Register(func(ctx *node.ServiceContext) (node.Service, error) { - return dashboard.New(cfg, commit) + return dashboard.New(cfg, commit, ctx.ResolvePath("logs")), nil }) } @@ -1186,7 +1225,7 @@ func RegisterShhService(stack *node.Node, cfg *whisper.Config) { } // RegisterEthStatsService configures the Ethereum Stats daemon and adds it to -// th egiven node. +// the given node. func RegisterEthStatsService(stack *node.Node, url string) { if err := stack.Register(func(ctx *node.ServiceContext) (node.Service, error) { // Retrieve both eth and les services @@ -1208,6 +1247,27 @@ func SetupNetwork(ctx *cli.Context) { params.TargetGasLimit = ctx.GlobalUint64(TargetGasLimitFlag.Name) } +func SetupMetrics(ctx *cli.Context) { + if metrics.Enabled { + log.Info("Enabling metrics collection") + var ( + enableExport = ctx.GlobalBool(MetricsEnableInfluxDBFlag.Name) + endpoint = ctx.GlobalString(MetricsInfluxDBEndpointFlag.Name) + database = ctx.GlobalString(MetricsInfluxDBDatabaseFlag.Name) + username = ctx.GlobalString(MetricsInfluxDBUsernameFlag.Name) + password = ctx.GlobalString(MetricsInfluxDBPasswordFlag.Name) + hosttag = ctx.GlobalString(MetricsInfluxDBHostTagFlag.Name) + ) + + if enableExport { + log.Info("Enabling metrics export to InfluxDB") + go influxdb.InfluxDBWithTags(metrics.DefaultRegistry, 10*time.Second, endpoint, database, username, password, "geth.", map[string]string{ + "host": hosttag, + }) + } + } +} + // MakeChainDatabase open an LevelDB using the flags passed to the client and will hard crash if it fails. func MakeChainDatabase(ctx *cli.Context, stack *node.Node) ethdb.Database { var ( diff --git a/cmd/wnode/main.go b/cmd/wnode/main.go index 988c50ce3d..31b65c1da9 100644 --- a/cmd/wnode/main.go +++ b/cmd/wnode/main.go @@ -140,8 +140,8 @@ func processArgs() { } if *asymmetricMode && len(*argPub) > 0 { - pub = crypto.ToECDSAPub(common.FromHex(*argPub)) - if !isKeyValid(pub) { + var err error + if pub, err = crypto.UnmarshalPubkey(common.FromHex(*argPub)); err != nil { utils.Fatalf("invalid public key") } } @@ -271,7 +271,9 @@ func initialize() { if *mailServerMode { shh.RegisterServer(&mailServer) - mailServer.Init(shh, *argDBPath, msPassword, *argServerPoW) + if err := mailServer.Init(shh, *argDBPath, msPassword, *argServerPoW); err != nil { + utils.Fatalf("Failed to init MailServer: %s", err) + } } server = &p2p.Server{ @@ -319,10 +321,6 @@ func startServer() error { return nil } -func isKeyValid(k *ecdsa.PublicKey) bool { - return k.X != nil && k.Y != nil -} - func configureNode() { var err error var p2pAccept bool @@ -338,9 +336,8 @@ func configureNode() { if b == nil { utils.Fatalf("Error: can not convert hexadecimal string") } - pub = crypto.ToECDSAPub(b) - if !isKeyValid(pub) { - utils.Fatalf("Error: invalid public key") + if pub, err = crypto.UnmarshalPubkey(b); err != nil { + utils.Fatalf("Error: invalid peer public key") } } } diff --git a/common/bytes.go b/common/bytes.go index f143f150d8..03bcdbc88e 100644 --- a/common/bytes.go +++ b/common/bytes.go @@ -19,9 +19,12 @@ package common import "encoding/hex" +// ToHex returns the hex representation of b, prefixed with '0x'. +// For empty slices, the return value is "0x0". +// +// Deprecated: use hexutil.Encode instead. func ToHex(b []byte) string { hex := Bytes2Hex(b) - // Prefer output of "0x0" instead of "0x" if len(hex) == 0 { hex = "0" } @@ -45,9 +48,7 @@ func FromHex(s string) []byte { return Hex2Bytes(s) } -// Copy bytes -// -// Returns an exact copy of the provided bytes +// CopyBytes returns an exact copy of the provided bytes. func CopyBytes(b []byte) (copiedBytes []byte) { if b == nil { return nil @@ -66,10 +67,12 @@ func hasHexPrefix(str string) bool { return len(str) >= 2 && str[0] == '0' && (str[1] == 'x' || str[1] == 'X') } +// isHexCharacter returns bool of c being a valid hexadecimal. func isHexCharacter(c byte) bool { return ('0' <= c && c <= '9') || ('a' <= c && c <= 'f') || ('A' <= c && c <= 'F') } +// isHex validates whether each byte is valid hexadecimal string. func isHex(str string) bool { if len(str)%2 != 0 { return false @@ -82,31 +85,32 @@ func isHex(str string) bool { return true } +// Bytes2Hex returns the hexadecimal encoding of d. func Bytes2Hex(d []byte) string { return hex.EncodeToString(d) } +// Hex2Bytes returns the bytes represented by the hexadecimal string str. func Hex2Bytes(str string) []byte { h, _ := hex.DecodeString(str) - return h } +// Hex2BytesFixed returns bytes of a specified fixed length flen. func Hex2BytesFixed(str string, flen int) []byte { h, _ := hex.DecodeString(str) if len(h) == flen { return h - } else { - if len(h) > flen { - return h[len(h)-flen:] - } else { - hh := make([]byte, flen) - copy(hh[flen-len(h):flen], h[:]) - return hh - } } + if len(h) > flen { + return h[len(h)-flen:] + } + hh := make([]byte, flen) + copy(hh[flen-len(h):flen], h[:]) + return hh } +// RightPadBytes zero-pads slice to the right up to length l. func RightPadBytes(slice []byte, l int) []byte { if l <= len(slice) { return slice @@ -118,6 +122,7 @@ func RightPadBytes(slice []byte, l int) []byte { return padded } +// LeftPadBytes zero-pads slice to the left up to length l. func LeftPadBytes(slice []byte, l int) []byte { if l <= len(slice) { return slice diff --git a/common/compiler/solidity.go b/common/compiler/solidity.go index 234714a2b9..f6e8d2e42a 100644 --- a/common/compiler/solidity.go +++ b/common/compiler/solidity.go @@ -31,11 +31,17 @@ import ( var versionRegexp = regexp.MustCompile(`([0-9]+)\.([0-9]+)\.([0-9]+)`) +// Contract contains information about a compiled contract, alongside its code. type Contract struct { Code string `json:"code"` Info ContractInfo `json:"info"` } +// ContractInfo contains information about a compiled contract, including access +// to the ABI definition, user and developer docs, and metadata. +// +// Depending on the source, language version, compiler version, and compiler +// options will provide information about how the contract was compiled. type ContractInfo struct { Source string `json:"source"` Language string `json:"language"` @@ -142,8 +148,22 @@ func (s *Solidity) run(cmd *exec.Cmd, source string) (map[string]*Contract, erro if err := cmd.Run(); err != nil { return nil, fmt.Errorf("solc: %v\n%s", err, stderr.Bytes()) } + + return ParseCombinedJSON(stdout.Bytes(), source, s.Version, s.Version, strings.Join(s.makeArgs(), " ")) +} + +// ParseCombinedJSON takes the direct output of a solc --combined-output run and +// parses it into a map of string contract name to Contract structs. The +// provided source, language and compiler version, and compiler options are all +// passed through into the Contract structs. +// +// The solc output is expected to contain ABI, user docs, and dev docs. +// +// Returns an error if the JSON is malformed or missing data, or if the JSON +// embedded within the JSON is malformed. +func ParseCombinedJSON(combinedJSON []byte, source string, languageVersion string, compilerVersion string, compilerOptions string) (map[string]*Contract, error) { var output solcOutput - if err := json.Unmarshal(stdout.Bytes(), &output); err != nil { + if err := json.Unmarshal(combinedJSON, &output); err != nil { return nil, err } @@ -168,9 +188,9 @@ func (s *Solidity) run(cmd *exec.Cmd, source string) (map[string]*Contract, erro Info: ContractInfo{ Source: source, Language: "Solidity", - LanguageVersion: s.Version, - CompilerVersion: s.Version, - CompilerOptions: strings.Join(s.makeArgs(), " "), + LanguageVersion: languageVersion, + CompilerVersion: compilerVersion, + CompilerOptions: compilerOptions, AbiDefinition: abi, UserDoc: userdoc, DeveloperDoc: devdoc, diff --git a/common/hexutil/hexutil.go b/common/hexutil/hexutil.go index 02c488a3f1..46223a2815 100644 --- a/common/hexutil/hexutil.go +++ b/common/hexutil/hexutil.go @@ -39,6 +39,7 @@ import ( const uintBits = 32 << (uint64(^uint(0)) >> 63) +// Errors var ( ErrEmptyString = &decError{"empty hex string"} ErrSyntax = &decError{"invalid hex string"} diff --git a/common/math/big.go b/common/math/big.go index 7872786503..9d2e7946d1 100644 --- a/common/math/big.go +++ b/common/math/big.go @@ -22,12 +22,13 @@ import ( "math/big" ) +// Various big integer limit values. var ( tt255 = BigPow(2, 255) tt256 = BigPow(2, 256) tt256m1 = new(big.Int).Sub(tt256, big.NewInt(1)) - MaxBig256 = new(big.Int).Set(tt256m1) tt63 = BigPow(2, 63) + MaxBig256 = new(big.Int).Set(tt256m1) MaxBig63 = new(big.Int).Sub(tt63, big.NewInt(1)) ) @@ -78,7 +79,7 @@ func ParseBig256(s string) (*big.Int, bool) { return bigint, ok } -// MustParseBig parses s as a 256 bit big integer and panics if the string is invalid. +// MustParseBig256 parses s as a 256 bit big integer and panics if the string is invalid. func MustParseBig256(s string) *big.Int { v, ok := ParseBig256(s) if !ok { @@ -186,9 +187,8 @@ func U256(x *big.Int) *big.Int { func S256(x *big.Int) *big.Int { if x.Cmp(tt255) < 0 { return x - } else { - return new(big.Int).Sub(x, tt256) } + return new(big.Int).Sub(x, tt256) } // Exp implements exponentiation by squaring. diff --git a/common/math/integer.go b/common/math/integer.go index 7eff4d3b00..93b1d036dd 100644 --- a/common/math/integer.go +++ b/common/math/integer.go @@ -21,8 +21,8 @@ import ( "strconv" ) +// Integer limit values. const ( - // Integer limit values. MaxInt8 = 1<<7 - 1 MinInt8 = -1 << 7 MaxInt16 = 1<<15 - 1 diff --git a/common/mclock/mclock.go b/common/mclock/mclock.go index 92005252eb..02608d17b0 100644 --- a/common/mclock/mclock.go +++ b/common/mclock/mclock.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 mclock is a wrapper for a monotonic clock source +// Package mclock is a wrapper for a monotonic clock source package mclock import ( @@ -23,8 +23,10 @@ import ( "github.com/aristanetworks/goarista/monotime" ) -type AbsTime time.Duration // absolute monotonic time +// AbsTime represents absolute monotonic time. +type AbsTime time.Duration +// Now returns the current absolute monotonic time. func Now() AbsTime { return AbsTime(monotime.Now()) } diff --git a/common/number/int.go b/common/number/int.go deleted file mode 100644 index 6dab2436de..0000000000 --- a/common/number/int.go +++ /dev/null @@ -1,197 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package number - -import ( - "math/big" - - "github.com/ethereum/go-ethereum/common" -) - -var tt256 = new(big.Int).Lsh(big.NewInt(1), 256) -var tt256m1 = new(big.Int).Sub(new(big.Int).Lsh(big.NewInt(1), 256), big.NewInt(1)) -var tt255 = new(big.Int).Lsh(big.NewInt(1), 255) - -func limitUnsigned256(x *Number) *Number { - x.num.And(x.num, tt256m1) - return x -} - -func limitSigned256(x *Number) *Number { - if x.num.Cmp(tt255) < 0 { - return x - } else { - x.num.Sub(x.num, tt256) - return x - } -} - -// Number function -type Initialiser func(n int64) *Number - -// A Number represents a generic integer with a bounding function limiter. Limit is called after each operations -// to give "fake" bounded integers. New types of Number can be created through NewInitialiser returning a lambda -// with the new Initialiser. -type Number struct { - num *big.Int - limit func(n *Number) *Number -} - -// Returns a new initialiser for a new *Number without having to expose certain fields -func NewInitialiser(limiter func(*Number) *Number) Initialiser { - return func(n int64) *Number { - return &Number{big.NewInt(n), limiter} - } -} - -// Return a Number with a UNSIGNED limiter up to 256 bits -func Uint256(n int64) *Number { - return &Number{big.NewInt(n), limitUnsigned256} -} - -// Return a Number with a SIGNED limiter up to 256 bits -func Int256(n int64) *Number { - return &Number{big.NewInt(n), limitSigned256} -} - -// Returns a Number with a SIGNED unlimited size -func Big(n int64) *Number { - return &Number{big.NewInt(n), func(x *Number) *Number { return x }} -} - -// Sets i to sum of x+y -func (i *Number) Add(x, y *Number) *Number { - i.num.Add(x.num, y.num) - return i.limit(i) -} - -// Sets i to difference of x-y -func (i *Number) Sub(x, y *Number) *Number { - i.num.Sub(x.num, y.num) - return i.limit(i) -} - -// Sets i to product of x*y -func (i *Number) Mul(x, y *Number) *Number { - i.num.Mul(x.num, y.num) - return i.limit(i) -} - -// Sets i to the quotient prodject of x/y -func (i *Number) Div(x, y *Number) *Number { - i.num.Div(x.num, y.num) - return i.limit(i) -} - -// Sets i to x % y -func (i *Number) Mod(x, y *Number) *Number { - i.num.Mod(x.num, y.num) - return i.limit(i) -} - -// Sets i to x << s -func (i *Number) Lsh(x *Number, s uint) *Number { - i.num.Lsh(x.num, s) - return i.limit(i) -} - -// Sets i to x^y -func (i *Number) Pow(x, y *Number) *Number { - i.num.Exp(x.num, y.num, big.NewInt(0)) - return i.limit(i) -} - -// Setters - -// Set x to i -func (i *Number) Set(x *Number) *Number { - i.num.Set(x.num) - return i.limit(i) -} - -// Set x bytes to i -func (i *Number) SetBytes(x []byte) *Number { - i.num.SetBytes(x) - return i.limit(i) -} - -// Cmp compares x and y and returns: -// -// -1 if x < y -// 0 if x == y -// +1 if x > y -func (i *Number) Cmp(x *Number) int { - return i.num.Cmp(x.num) -} - -// Getters - -// Returns the string representation of i -func (i *Number) String() string { - return i.num.String() -} - -// Returns the byte representation of i -func (i *Number) Bytes() []byte { - return i.num.Bytes() -} - -// Uint64 returns the Uint64 representation of x. If x cannot be represented in an int64, the result is undefined. -func (i *Number) Uint64() uint64 { - return i.num.Uint64() -} - -// Int64 returns the int64 representation of x. If x cannot be represented in an int64, the result is undefined. -func (i *Number) Int64() int64 { - return i.num.Int64() -} - -// Returns the signed version of i -func (i *Number) Int256() *Number { - return Int(0).Set(i) -} - -// Returns the unsigned version of i -func (i *Number) Uint256() *Number { - return Uint(0).Set(i) -} - -// Returns the index of the first bit that's set to 1 -func (i *Number) FirstBitSet() int { - for j := 0; j < i.num.BitLen(); j++ { - if i.num.Bit(j) > 0 { - return j - } - } - - return i.num.BitLen() -} - -// Variables - -var ( - Zero = Uint(0) - One = Uint(1) - Two = Uint(2) - MaxUint256 = Uint(0).SetBytes(common.Hex2Bytes("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")) - - MinOne = Int(-1) - - // "typedefs" - Uint = Uint256 - Int = Int256 -) diff --git a/common/number/uint_test.go b/common/number/uint_test.go deleted file mode 100644 index 3ab9e4c344..0000000000 --- a/common/number/uint_test.go +++ /dev/null @@ -1,108 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package number - -import ( - "math/big" - "testing" - - "github.com/ethereum/go-ethereum/common" -) - -func TestSet(t *testing.T) { - a := Uint(0) - b := Uint(10) - a.Set(b) - if a.num.Cmp(b.num) != 0 { - t.Error("didn't compare", a, b) - } - - c := Uint(0).SetBytes(common.Hex2Bytes("0a")) - if c.num.Cmp(big.NewInt(10)) != 0 { - t.Error("c set bytes failed.") - } -} - -func TestInitialiser(t *testing.T) { - check := false - init := NewInitialiser(func(x *Number) *Number { - check = true - return x - }) - a := init(0).Add(init(1), init(2)) - if a.Cmp(init(3)) != 0 { - t.Error("expected 3. got", a) - } - if !check { - t.Error("expected limiter to be called") - } -} - -func TestGet(t *testing.T) { - a := Uint(10) - if a.Uint64() != 10 { - t.Error("expected to get 10. got", a.Uint64()) - } - - a = Uint(10) - if a.Int64() != 10 { - t.Error("expected to get 10. got", a.Int64()) - } -} - -func TestCmp(t *testing.T) { - a := Uint(10) - b := Uint(10) - c := Uint(11) - - if a.Cmp(b) != 0 { - t.Error("a b == 0 failed", a, b) - } - - if a.Cmp(c) >= 0 { - t.Error("a c < 0 failed", a, c) - } - - if c.Cmp(b) <= 0 { - t.Error("c b > 0 failed", c, b) - } -} - -func TestMaxArith(t *testing.T) { - a := Uint(0).Add(MaxUint256, One) - if a.Cmp(Zero) != 0 { - t.Error("expected max256 + 1 = 0 got", a) - } - - a = Uint(0).Sub(Uint(0), One) - if a.Cmp(MaxUint256) != 0 { - t.Error("expected 0 - 1 = max256 got", a) - } - - a = Int(0).Sub(Int(0), One) - if a.Cmp(MinOne) != 0 { - t.Error("expected 0 - 1 = -1 got", a) - } -} - -func TestConversion(t *testing.T) { - a := Int(-1) - b := a.Uint256() - if b.Cmp(MaxUint256) != 0 { - t.Error("expected -1 => unsigned to return max. got", b) - } -} diff --git a/common/path.go b/common/path.go index bd8da86e74..69820cfe5d 100644 --- a/common/path.go +++ b/common/path.go @@ -30,6 +30,7 @@ func MakeName(name, version string) string { return fmt.Sprintf("%s/v%s/%s/%s", name, version, runtime.GOOS, runtime.Version()) } +// FileExist checks if a file exists at filePath. func FileExist(filePath string) bool { _, err := os.Stat(filePath) if err != nil && os.IsNotExist(err) { @@ -39,9 +40,10 @@ func FileExist(filePath string) bool { return true } -func AbsolutePath(Datadir string, filename string) string { +// AbsolutePath returns datadir + filename, or filename if it is absolute. +func AbsolutePath(datadir string, filename string) string { if filepath.IsAbs(filename) { return filename } - return filepath.Join(Datadir, filename) + return filepath.Join(datadir, filename) } diff --git a/common/types.go b/common/types.go index 785b123618..616ec3be98 100644 --- a/common/types.go +++ b/common/types.go @@ -17,16 +17,20 @@ package common import ( + "database/sql/driver" "encoding/hex" + "encoding/json" "fmt" "math/big" "math/rand" "reflect" + "strings" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/crypto/sha3" ) +// Lengths of hashes and addresses in bytes. const ( HashLength = 32 AddressLength = 20 @@ -50,20 +54,32 @@ var ( // Hash represents the 32 byte Keccak256 hash of arbitrary data. type Hash [HashLength]byte +// BytesToHash sets b to hash. +// If b is larger than len(h), b will be cropped from the left. func BytesToHash(b []byte) Hash { var h Hash h.SetBytes(b) return h } func StringToHash(s string) Hash { return BytesToHash([]byte(s)) } -func BigToHash(b *big.Int) Hash { return BytesToHash(b.Bytes()) } -func HexToHash(s string) Hash { return BytesToHash(FromHex(s)) } -// Get the string representation of the underlying hash -func (h Hash) Str() string { return string(h[:]) } + +// BigToHash sets byte representation of b to hash. +// If b is larger than len(h), b will be cropped from the left. +func BigToHash(b *big.Int) Hash { return BytesToHash(b.Bytes()) } + +// HexToHash sets byte representation of s to hash. +// If b is larger than len(h), b will be cropped from the left. +func HexToHash(s string) Hash { return BytesToHash(FromHex(s)) } + +// Bytes gets the byte representation of the underlying hash. func (h Hash) Bytes() []byte { return h[:] } + +// Big converts a hash to a big integer. func (h Hash) Big() *big.Int { return new(big.Int).SetBytes(h[:]) } -func (h Hash) Hex() string { return hexutil.Encode(h[:]) } + +// Hex converts a hash to a hex string. +func (h Hash) Hex() string { return hexutil.Encode(h[:]) } // TerminalString implements log.TerminalStringer, formatting a string for console // output during logging. @@ -98,7 +114,8 @@ func (h Hash) MarshalText() ([]byte, error) { return hexutil.Bytes(h[:]).MarshalText() } -// Sets the hash to the value of b. If b is larger than len(h), 'b' will be cropped (from the left). +// SetBytes sets the hash to the value of b. +// If b is larger than len(h), b will be cropped from the left. func (h *Hash) SetBytes(b []byte) { if len(b) > len(h) { b = b[len(b)-HashLength:] @@ -107,16 +124,6 @@ func (h *Hash) SetBytes(b []byte) { copy(h[HashLength-len(b):], b) } -// Set string `s` to h. If s is larger than len(h) s will be cropped (from left) to fit. -func (h *Hash) SetString(s string) { h.SetBytes([]byte(s)) } - -// Sets h to other -func (h *Hash) Set(other Hash) { - for i, v := range other { - h[i] = v - } -} - // Generate implements testing/quick.Generator. func (h Hash) Generate(rand *rand.Rand, size int) reflect.Value { m := rand.Intn(len(h)) @@ -126,8 +133,22 @@ func (h Hash) Generate(rand *rand.Rand, size int) reflect.Value { return reflect.ValueOf(h) } -func EmptyHash(h Hash) bool { - return h == Hash{} +// Scan implements Scanner for database/sql. +func (h *Hash) Scan(src interface{}) error { + srcB, ok := src.([]byte) + if !ok { + return fmt.Errorf("can't scan %T into Hash", src) + } + if len(srcB) != HashLength { + return fmt.Errorf("can't scan []byte of len %d into Hash, want %d", len(srcB), HashLength) + } + copy(h[:], srcB) + return nil +} + +// Value implements valuer for database/sql. +func (h Hash) Value() (driver.Value, error) { + return h[:], nil } // UnprefixedHash allows marshaling a Hash without 0x prefix. @@ -148,14 +169,22 @@ func (h UnprefixedHash) MarshalText() ([]byte, error) { // Address represents the 20 byte address of an Ethereum account. type Address [AddressLength]byte +// BytesToAddress returns Address with value b. +// If b is larger than len(h), b will be cropped from the left. func BytesToAddress(b []byte) Address { var a Address a.SetBytes(b) return a } func StringToAddress(s string) Address { return BytesToAddress([]byte(s)) } -func BigToAddress(b *big.Int) Address { return BytesToAddress(b.Bytes()) } -func HexToAddress(s string) Address { return BytesToAddress(FromHex(s)) } + +// BigToAddress returns Address with byte values of b. +// If b is larger than len(h), b will be cropped from the left. +func BigToAddress(b *big.Int) Address { return BytesToAddress(b.Bytes()) } + +// HexToAddress returns Address with byte values of s. +// If s is larger than len(h), s will be cropped from the left. +func HexToAddress(s string) Address { return BytesToAddress(FromHex(s)) } // IsHexAddress verifies whether a string can represent a valid hex-encoded // Ethereum address or not. @@ -169,11 +198,14 @@ func IsHexAddress(s string) bool { return len(s) == 2*AddressLength && isHex(s) } -// Get the string representation of the underlying address -func (a Address) Str() string { return string(a[:]) } +// Bytes gets the string representation of the underlying address. func (a Address) Bytes() []byte { return a[:] } + +// Big converts an address to a big integer. func (a Address) Big() *big.Int { return new(big.Int).SetBytes(a[:]) } -func (a Address) Hash() Hash { return BytesToHash(a[:]) } + +// Hash converts an address to a hash by left-padding it with zeros. +func (a Address) Hash() Hash { return BytesToHash(a[:]) } // Hex returns an EIP55-compliant hex string representation of the address. func (a Address) Hex() string { @@ -197,7 +229,7 @@ func (a Address) Hex() string { return "xdc" + string(result) } -// String implements the stringer interface and is used also by the logger. +// String implements fmt.Stringer. func (a Address) String() string { return a.Hex() } @@ -208,7 +240,8 @@ func (a Address) Format(s fmt.State, c rune) { fmt.Fprintf(s, "%"+string(c), a[:]) } -// Sets the address to the value of b. If b is larger than len(a) it will panic +// SetBytes sets the address to the value of b. +// If b is larger than len(a) it will panic. func (a *Address) SetBytes(b []byte) { if len(b) > len(a) { b = b[len(b)-AddressLength:] @@ -216,16 +249,6 @@ func (a *Address) SetBytes(b []byte) { copy(a[AddressLength-len(b):], b) } -// Set string `s` to a. If s is larger than len(a) it will panic -func (a *Address) SetString(s string) { a.SetBytes([]byte(s)) } - -// Sets a to other -func (a *Address) Set(other Address) { - for i, v := range other { - a[i] = v - } -} - // MarshalText returns the hex representation of a. func (a Address) MarshalText() ([]byte, error) { return hexutil.Bytes(a[:]).MarshalXDCText() @@ -241,7 +264,25 @@ func (a *Address) UnmarshalJSON(input []byte) error { return hexutil.UnmarshalFixedJSON(addressT, input, a[:]) } -// UnprefixedHash allows marshaling an Address without 0x prefix. +// Scan implements Scanner for database/sql. +func (a *Address) Scan(src interface{}) error { + srcB, ok := src.([]byte) + if !ok { + return fmt.Errorf("can't scan %T into Address", src) + } + if len(srcB) != AddressLength { + return fmt.Errorf("can't scan []byte of len %d into Address, want %d", len(srcB), AddressLength) + } + copy(a[:], srcB) + return nil +} + +// Value implements valuer for database/sql. +func (a Address) Value() (driver.Value, error) { + return a[:], nil +} + +// UnprefixedAddress allows marshaling an Address without 0x prefix. type UnprefixedAddress Address // UnmarshalText decodes the address from hex. The 0x prefix is optional. @@ -290,3 +331,64 @@ func ExtractAddressFromBytes(bytePenalties []byte) []Address { } return penalties } + + +// MixedcaseAddress retains the original string, which may or may not be +// correctly checksummed +type MixedcaseAddress struct { + addr Address + original string +} + +// NewMixedcaseAddress constructor (mainly for testing) +func NewMixedcaseAddress(addr Address) MixedcaseAddress { + return MixedcaseAddress{addr: addr, original: addr.Hex()} +} + +// NewMixedcaseAddressFromString is mainly meant for unit-testing +func NewMixedcaseAddressFromString(hexaddr string) (*MixedcaseAddress, error) { + if !IsHexAddress(hexaddr) { + return nil, fmt.Errorf("Invalid address") + } + a := FromHex(hexaddr) + return &MixedcaseAddress{addr: BytesToAddress(a), original: hexaddr}, nil +} + +// UnmarshalJSON parses MixedcaseAddress +func (ma *MixedcaseAddress) UnmarshalJSON(input []byte) error { + if err := hexutil.UnmarshalFixedJSON(addressT, input, ma.addr[:]); err != nil { + return err + } + return json.Unmarshal(input, &ma.original) +} + +// MarshalJSON marshals the original value +func (ma *MixedcaseAddress) MarshalJSON() ([]byte, error) { + if strings.HasPrefix(ma.original, "0x") || strings.HasPrefix(ma.original, "0X") { + return json.Marshal(fmt.Sprintf("0x%s", ma.original[2:])) + } + return json.Marshal(fmt.Sprintf("0x%s", ma.original)) +} + +// Address returns the address +func (ma *MixedcaseAddress) Address() Address { + return ma.addr +} + +// String implements fmt.Stringer +func (ma *MixedcaseAddress) String() string { + if ma.ValidChecksum() { + return fmt.Sprintf("%s [chksum ok]", ma.original) + } + return fmt.Sprintf("%s [chksum INVALID]", ma.original) +} + +// ValidChecksum returns true if the address has valid checksum +func (ma *MixedcaseAddress) ValidChecksum() bool { + return ma.original == ma.addr.Hex() +} + +// Original returns the mixed-case input string +func (ma *MixedcaseAddress) Original() string { + return ma.original +} diff --git a/common/types_template.go b/common/types_template.go deleted file mode 100644 index 9a8f29977b..0000000000 --- a/common/types_template.go +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -// +build none -//sed -e 's/_N_/Hash/g' -e 's/_S_/32/g' -e '1d' types_template.go | gofmt -w hash.go - -package common - -import "math/big" - -type _N_ [_S_]byte - -func BytesTo_N_(b []byte) _N_ { - var h _N_ - h.SetBytes(b) - return h -} -func StringTo_N_(s string) _N_ { return BytesTo_N_([]byte(s)) } -func BigTo_N_(b *big.Int) _N_ { return BytesTo_N_(b.Bytes()) } -func HexTo_N_(s string) _N_ { return BytesTo_N_(FromHex(s)) } - -// Don't use the default 'String' method in case we want to overwrite - -// Get the string representation of the underlying hash -func (h _N_) Str() string { return string(h[:]) } -func (h _N_) Bytes() []byte { return h[:] } -func (h _N_) Big() *big.Int { return new(big.Int).SetBytes(h[:]) } -func (h _N_) Hex() string { return "0x" + Bytes2Hex(h[:]) } - -// Sets the hash to the value of b. If b is larger than len(h) it will panic -func (h *_N_) SetBytes(b []byte) { - // Use the right most bytes - if len(b) > len(h) { - b = b[len(b)-_S_:] - } - - // Reverse the loop - for i := len(b) - 1; i >= 0; i-- { - h[_S_-len(b)+i] = b[i] - } -} - -// Set string `s` to h. If s is larger than len(h) it will panic -func (h *_N_) SetString(s string) { h.SetBytes([]byte(s)) } - -// Sets h to other -func (h *_N_) Set(other _N_) { - for i, v := range other { - h[i] = v - } -} diff --git a/common/types_test.go b/common/types_test.go index 0c47b79e54..ca8ba6c366 100644 --- a/common/types_test.go +++ b/common/types_test.go @@ -17,8 +17,10 @@ package common import ( + "database/sql/driver" "encoding/json" "math/big" + "reflect" "strings" "testing" ) @@ -155,11 +157,222 @@ func BenchmarkAddressHex(b *testing.B) { } } -func TestRemoveItemInArray(t *testing.T) { - array := []Address{HexToAddress("0x0000003"), HexToAddress("0x0000001"), HexToAddress("0x0000002"), HexToAddress("0x0000003")} - remove := []Address{HexToAddress("0x0000002"), HexToAddress("0x0000004"), HexToAddress("0x0000003")} - array = RemoveItemFromArray(array, remove) - if len(array) != 1 { - t.Error("fail remove item from array address") +func TestMixedcaseAccount_Address(t *testing.T) { + + // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-55.md + // Note: 0X{checksum_addr} is not valid according to spec above + + var res []struct { + A MixedcaseAddress + Valid bool + } + if err := json.Unmarshal([]byte(`[ + {"A" : "0xae967917c465db8578ca9024c205720b1a3651A9", "Valid": false}, + {"A" : "0xAe967917c465db8578ca9024c205720b1a3651A9", "Valid": true}, + {"A" : "0XAe967917c465db8578ca9024c205720b1a3651A9", "Valid": false}, + {"A" : "0x1111111111111111111112222222222223333323", "Valid": true} + ]`), &res); err != nil { + t.Fatal(err) + } + + for _, r := range res { + if got := r.A.ValidChecksum(); got != r.Valid { + t.Errorf("Expected checksum %v, got checksum %v, input %v", r.Valid, got, r.A.String()) + } + } + + //These should throw exceptions: + var r2 []MixedcaseAddress + for _, r := range []string{ + `["0x11111111111111111111122222222222233333"]`, // Too short + `["0x111111111111111111111222222222222333332"]`, // Too short + `["0x11111111111111111111122222222222233333234"]`, // Too long + `["0x111111111111111111111222222222222333332344"]`, // Too long + `["1111111111111111111112222222222223333323"]`, // Missing 0x + `["x1111111111111111111112222222222223333323"]`, // Missing 0 + `["0xG111111111111111111112222222222223333323"]`, //Non-hex + } { + if err := json.Unmarshal([]byte(r), &r2); err == nil { + t.Errorf("Expected failure, input %v", r) + } + + } + +} + +func TestHash_Scan(t *testing.T) { + type args struct { + src interface{} + } + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "working scan", + args: args{src: []byte{ + 0xb2, 0x6f, 0x2b, 0x34, 0x2a, 0xab, 0x24, 0xbc, 0xf6, 0x3e, + 0xa2, 0x18, 0xc6, 0xa9, 0x27, 0x4d, 0x30, 0xab, 0x9a, 0x15, + 0xa2, 0x18, 0xc6, 0xa9, 0x27, 0x4d, 0x30, 0xab, 0x9a, 0x15, + 0x10, 0x00, + }}, + wantErr: false, + }, + { + name: "non working scan", + args: args{src: int64(1234567890)}, + wantErr: true, + }, + { + name: "invalid length scan", + args: args{src: []byte{ + 0xb2, 0x6f, 0x2b, 0x34, 0x2a, 0xab, 0x24, 0xbc, 0xf6, 0x3e, + 0xa2, 0x18, 0xc6, 0xa9, 0x27, 0x4d, 0x30, 0xab, 0x9a, 0x15, + 0xa2, 0x18, 0xc6, 0xa9, 0x27, 0x4d, 0x30, 0xab, 0x9a, 0x15, + }}, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + h := &Hash{} + if err := h.Scan(tt.args.src); (err != nil) != tt.wantErr { + t.Errorf("Hash.Scan() error = %v, wantErr %v", err, tt.wantErr) + } + + if !tt.wantErr { + for i := range h { + if h[i] != tt.args.src.([]byte)[i] { + t.Errorf( + "Hash.Scan() didn't scan the %d src correctly (have %X, want %X)", + i, h[i], tt.args.src.([]byte)[i], + ) + } + } + } + }) + } +} + +func TestHash_Value(t *testing.T) { + b := []byte{ + 0xb2, 0x6f, 0x2b, 0x34, 0x2a, 0xab, 0x24, 0xbc, 0xf6, 0x3e, + 0xa2, 0x18, 0xc6, 0xa9, 0x27, 0x4d, 0x30, 0xab, 0x9a, 0x15, + 0xa2, 0x18, 0xc6, 0xa9, 0x27, 0x4d, 0x30, 0xab, 0x9a, 0x15, + 0x10, 0x00, + } + var usedH Hash + usedH.SetBytes(b) + tests := []struct { + name string + h Hash + want driver.Value + wantErr bool + }{ + { + name: "Working value", + h: usedH, + want: b, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := tt.h.Value() + if (err != nil) != tt.wantErr { + t.Errorf("Hash.Value() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("Hash.Value() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestAddress_Scan(t *testing.T) { + type args struct { + src interface{} + } + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "working scan", + args: args{src: []byte{ + 0xb2, 0x6f, 0x2b, 0x34, 0x2a, 0xab, 0x24, 0xbc, 0xf6, 0x3e, + 0xa2, 0x18, 0xc6, 0xa9, 0x27, 0x4d, 0x30, 0xab, 0x9a, 0x15, + }}, + wantErr: false, + }, + { + name: "non working scan", + args: args{src: int64(1234567890)}, + wantErr: true, + }, + { + name: "invalid length scan", + args: args{src: []byte{ + 0xb2, 0x6f, 0x2b, 0x34, 0x2a, 0xab, 0x24, 0xbc, 0xf6, 0x3e, + 0xa2, 0x18, 0xc6, 0xa9, 0x27, 0x4d, 0x30, 0xab, 0x9a, + }}, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + a := &Address{} + if err := a.Scan(tt.args.src); (err != nil) != tt.wantErr { + t.Errorf("Address.Scan() error = %v, wantErr %v", err, tt.wantErr) + } + + if !tt.wantErr { + for i := range a { + if a[i] != tt.args.src.([]byte)[i] { + t.Errorf( + "Address.Scan() didn't scan the %d src correctly (have %X, want %X)", + i, a[i], tt.args.src.([]byte)[i], + ) + } + } + } + }) + } +} + +func TestAddress_Value(t *testing.T) { + b := []byte{ + 0xb2, 0x6f, 0x2b, 0x34, 0x2a, 0xab, 0x24, 0xbc, 0xf6, 0x3e, + 0xa2, 0x18, 0xc6, 0xa9, 0x27, 0x4d, 0x30, 0xab, 0x9a, 0x15, + } + var usedA Address + usedA.SetBytes(b) + tests := []struct { + name string + a Address + want driver.Value + wantErr bool + }{ + { + name: "Working value", + a: usedA, + want: b, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := tt.a.Value() + if (err != nil) != tt.wantErr { + t.Errorf("Address.Value() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("Address.Value() = %v, want %v", got, tt.want) + } + }) } } diff --git a/compression/rle/read_write.go b/compression/rle/read_write.go deleted file mode 100644 index 0e7ad90aec..0000000000 --- a/compression/rle/read_write.go +++ /dev/null @@ -1,101 +0,0 @@ -// 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 -// 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 rle implements the run-length encoding used for Ethereum data. -package rle - -import ( - "bytes" - "errors" - - "github.com/ethereum/go-ethereum/crypto" -) - -const ( - token byte = 0xfe - emptyShaToken = 0xfd - emptyListShaToken = 0xfe - tokenToken = 0xff -) - -var empty = crypto.Keccak256([]byte("")) -var emptyList = crypto.Keccak256([]byte{0x80}) - -func Decompress(dat []byte) ([]byte, error) { - buf := new(bytes.Buffer) - - for i := 0; i < len(dat); i++ { - if dat[i] == token { - if i+1 < len(dat) { - switch dat[i+1] { - case emptyShaToken: - buf.Write(empty) - case emptyListShaToken: - buf.Write(emptyList) - case tokenToken: - buf.WriteByte(token) - default: - buf.Write(make([]byte, int(dat[i+1]-2))) - } - i++ - } else { - return nil, errors.New("error reading bytes. token encountered without proceeding bytes") - } - } else { - buf.WriteByte(dat[i]) - } - } - - return buf.Bytes(), nil -} - -func compressChunk(dat []byte) (ret []byte, n int) { - switch { - case dat[0] == token: - return []byte{token, tokenToken}, 1 - case len(dat) > 1 && dat[0] == 0x0 && dat[1] == 0x0: - j := 0 - for j <= 254 && j < len(dat) { - if dat[j] != 0 { - break - } - j++ - } - return []byte{token, byte(j + 2)}, j - case len(dat) >= 32: - if dat[0] == empty[0] && bytes.Equal(dat[:32], empty) { - return []byte{token, emptyShaToken}, 32 - } else if dat[0] == emptyList[0] && bytes.Equal(dat[:32], emptyList) { - return []byte{token, emptyListShaToken}, 32 - } - fallthrough - default: - return dat[:1], 1 - } -} - -func Compress(dat []byte) []byte { - buf := new(bytes.Buffer) - - i := 0 - for i < len(dat) { - b, n := compressChunk(dat[i:]) - buf.Write(b) - i += n - } - - return buf.Bytes() -} diff --git a/compression/rle/read_write_test.go b/compression/rle/read_write_test.go deleted file mode 100644 index b36f7907bc..0000000000 --- a/compression/rle/read_write_test.go +++ /dev/null @@ -1,50 +0,0 @@ -// 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 -// 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 rle - -import ( - "testing" - - checker "gopkg.in/check.v1" -) - -func Test(t *testing.T) { checker.TestingT(t) } - -type CompressionRleSuite struct{} - -var _ = checker.Suite(&CompressionRleSuite{}) - -func (s *CompressionRleSuite) TestDecompressSimple(c *checker.C) { - exp := []byte{0xc5, 0xd2, 0x46, 0x1, 0x86, 0xf7, 0x23, 0x3c, 0x92, 0x7e, 0x7d, 0xb2, 0xdc, 0xc7, 0x3, 0xc0, 0xe5, 0x0, 0xb6, 0x53, 0xca, 0x82, 0x27, 0x3b, 0x7b, 0xfa, 0xd8, 0x4, 0x5d, 0x85, 0xa4, 0x70} - res, err := Decompress([]byte{token, 0xfd}) - c.Assert(err, checker.IsNil) - c.Assert(res, checker.DeepEquals, exp) - - exp = []byte{0x56, 0xe8, 0x1f, 0x17, 0x1b, 0xcc, 0x55, 0xa6, 0xff, 0x83, 0x45, 0xe6, 0x92, 0xc0, 0xf8, 0x6e, 0x5b, 0x48, 0xe0, 0x1b, 0x99, 0x6c, 0xad, 0xc0, 0x1, 0x62, 0x2f, 0xb5, 0xe3, 0x63, 0xb4, 0x21} - res, err = Decompress([]byte{token, 0xfe}) - c.Assert(err, checker.IsNil) - c.Assert(res, checker.DeepEquals, exp) - - res, err = Decompress([]byte{token, 0xff}) - c.Assert(err, checker.IsNil) - c.Assert(res, checker.DeepEquals, []byte{token}) - - res, err = Decompress([]byte{token, 12}) - c.Assert(err, checker.IsNil) - c.Assert(res, checker.DeepEquals, make([]byte, 10)) - -} diff --git a/consensus/XDPoS/XDPoS.go b/consensus/XDPoS/XDPoS.go index 9924c82104..480435e78e 100644 --- a/consensus/XDPoS/XDPoS.go +++ b/consensus/XDPoS/XDPoS.go @@ -1077,7 +1077,7 @@ func (c *XDPoS) CacheData(header *types.Header, txs []*types.Transaction, receip signTxs := []*types.Transaction{} for _, tx := range txs { if tx.IsSigningTransaction() { - var b uint + var b uint64 for _, r := range receipts { if r.TxHash == tx.Hash() { if len(r.PostState) > 0 { diff --git a/consensus/clique/api.go b/consensus/clique/api.go index b875eef012..6bcf987af5 100644 --- a/consensus/clique/api.go +++ b/consensus/clique/api.go @@ -75,7 +75,7 @@ func (api *API) GetSigners(number *rpc.BlockNumber) ([]common.Address, error) { return snap.signers(), nil } -// GetSignersAtHash retrieves the state snapshot at a given block. +// 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 { diff --git a/consensus/clique/clique.go b/consensus/clique/clique.go index c2405ae297..df6c4b2dd4 100644 --- a/consensus/clique/clique.go +++ b/consensus/clique/clique.go @@ -53,7 +53,6 @@ const ( // Clique proof-of-authority protocol constants. var ( epochLength = uint64(30000) // Default number of blocks after which to checkpoint and reset the pending votes - blockPeriod = uint64(15) // Default minimum difference between two consecutive block's timestamps extraVanity = 32 // Fixed number of extra-data prefix bytes reserved for signer vanity extraSeal = 65 // Fixed number of extra-data suffix bytes reserved for signer seal @@ -383,7 +382,7 @@ func (c *Clique) snapshot(chain consensus.ChainReader, number uint64, hash commo // If an on-disk checkpoint snapshot can be found, use that if number%checkpointInterval == 0 { if s, err := loadSnapshot(c.config, c.signatures, c.db, hash); err == nil { - log.Trace("Loaded voting snapshot form disk", "number", number, "hash", hash) + log.Trace("Loaded voting snapshot from disk", "number", number, "hash", hash) snap = s break } diff --git a/consensus/clique/snapshot.go b/consensus/clique/snapshot.go index 9ebdb8df15..2333d69247 100644 --- a/consensus/clique/snapshot.go +++ b/consensus/clique/snapshot.go @@ -19,6 +19,7 @@ package clique import ( "bytes" "encoding/json" + "sort" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" @@ -56,6 +57,13 @@ type Snapshot struct { Tally map[common.Address]Tally `json:"tally"` // Current vote tally to avoid recalculating } +// signers implements the sort interface to allow sorting a list of addresses +type signers []common.Address + +func (s signers) Len() int { return len(s) } +func (s signers) Less(i, j int) bool { return bytes.Compare(s[i][:], s[j][:]) < 0 } +func (s signers) Swap(i, j int) { s[i], s[j] = s[j], s[i] } + // newSnapshot creates a new snapshot with the specified startup parameters. This // method does not initialize the set of recent signers, so only ever use if for // the genesis block. @@ -286,18 +294,12 @@ func (s *Snapshot) apply(headers []*types.Header) (*Snapshot, error) { // signers retrieves the list of authorized signers in ascending order. func (s *Snapshot) signers() []common.Address { - signers := make([]common.Address, 0, len(s.Signers)) - for signer := range s.Signers { - signers = append(signers, signer) + sigs := make([]common.Address, 0, len(s.Signers)) + for sig := range s.Signers { + sigs = append(sigs, sig) } - for i := 0; i < len(signers); i++ { - for j := i + 1; j < len(signers); j++ { - if bytes.Compare(signers[i][:], signers[j][:]) > 0 { - signers[i], signers[j] = signers[j], signers[i] - } - } - } - return signers + sort.Sort(signers(sigs)) + return sigs } // inturn returns if a signer at a given block height is in-turn or not. diff --git a/consensus/clique/snapshot_test.go b/consensus/clique/snapshot_test.go new file mode 100644 index 0000000000..5ac730c9e7 --- /dev/null +++ b/consensus/clique/snapshot_test.go @@ -0,0 +1,406 @@ +// 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 ( + "bytes" + "crypto/ecdsa" + "math/big" + "testing" + + "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/types" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/params" +) + +type testerVote struct { + signer string + voted string + auth bool +} + +// testerAccountPool is a pool to maintain currently active tester accounts, +// mapped from textual names used in the tests below to actual Ethereum private +// keys capable of signing transactions. +type testerAccountPool struct { + accounts map[string]*ecdsa.PrivateKey +} + +func newTesterAccountPool() *testerAccountPool { + return &testerAccountPool{ + accounts: make(map[string]*ecdsa.PrivateKey), + } +} + +func (ap *testerAccountPool) sign(header *types.Header, signer string) { + // Ensure we have a persistent key for the signer + if ap.accounts[signer] == nil { + ap.accounts[signer], _ = crypto.GenerateKey() + } + // Sign the header and embed the signature in extra data + sig, _ := crypto.Sign(sigHash(header).Bytes(), ap.accounts[signer]) + copy(header.Extra[len(header.Extra)-65:], sig) +} + +func (ap *testerAccountPool) address(account string) common.Address { + // Ensure we have a persistent key for the account + if ap.accounts[account] == nil { + ap.accounts[account], _ = crypto.GenerateKey() + } + // Resolve and return the Ethereum address + return crypto.PubkeyToAddress(ap.accounts[account].PublicKey) +} + +// testerChainReader implements consensus.ChainReader to access the genesis +// block. All other methods and requests will panic. +type testerChainReader struct { + db ethdb.Database +} + +func (r *testerChainReader) Config() *params.ChainConfig { return params.AllCliqueProtocolChanges } +func (r *testerChainReader) CurrentHeader() *types.Header { panic("not supported") } +func (r *testerChainReader) GetHeader(common.Hash, uint64) *types.Header { panic("not supported") } +func (r *testerChainReader) GetBlock(common.Hash, uint64) *types.Block { panic("not supported") } +func (r *testerChainReader) GetHeaderByHash(common.Hash) *types.Header { panic("not supported") } +func (r *testerChainReader) GetHeaderByNumber(number uint64) *types.Header { + if number == 0 { + return rawdb.ReadHeader(r.db, rawdb.ReadCanonicalHash(r.db, 0), 0) + } + panic("not supported") +} + +// Tests that voting is evaluated correctly for various simple and complex scenarios. +func TestVoting(t *testing.T) { + // Define the various voting scenarios to test + tests := []struct { + epoch uint64 + signers []string + votes []testerVote + results []string + }{ + { + // Single signer, no votes cast + signers: []string{"A"}, + votes: []testerVote{{signer: "A"}}, + results: []string{"A"}, + }, { + // Single signer, voting to add two others (only accept first, second needs 2 votes) + signers: []string{"A"}, + votes: []testerVote{ + {signer: "A", voted: "B", auth: true}, + {signer: "B"}, + {signer: "A", voted: "C", auth: true}, + }, + results: []string{"A", "B"}, + }, { + // Two signers, voting to add three others (only accept first two, third needs 3 votes already) + signers: []string{"A", "B"}, + votes: []testerVote{ + {signer: "A", voted: "C", auth: true}, + {signer: "B", voted: "C", auth: true}, + {signer: "A", voted: "D", auth: true}, + {signer: "B", voted: "D", auth: true}, + {signer: "C"}, + {signer: "A", voted: "E", auth: true}, + {signer: "B", voted: "E", auth: true}, + }, + results: []string{"A", "B", "C", "D"}, + }, { + // Single signer, dropping itself (weird, but one less cornercase by explicitly allowing this) + signers: []string{"A"}, + votes: []testerVote{ + {signer: "A", voted: "A", auth: false}, + }, + results: []string{}, + }, { + // Two signers, actually needing mutual consent to drop either of them (not fulfilled) + signers: []string{"A", "B"}, + votes: []testerVote{ + {signer: "A", voted: "B", auth: false}, + }, + results: []string{"A", "B"}, + }, { + // Two signers, actually needing mutual consent to drop either of them (fulfilled) + signers: []string{"A", "B"}, + votes: []testerVote{ + {signer: "A", voted: "B", auth: false}, + {signer: "B", voted: "B", auth: false}, + }, + results: []string{"A"}, + }, { + // Three signers, two of them deciding to drop the third + signers: []string{"A", "B", "C"}, + votes: []testerVote{ + {signer: "A", voted: "C", auth: false}, + {signer: "B", voted: "C", auth: false}, + }, + results: []string{"A", "B"}, + }, { + // Four signers, consensus of two not being enough to drop anyone + signers: []string{"A", "B", "C", "D"}, + votes: []testerVote{ + {signer: "A", voted: "C", auth: false}, + {signer: "B", voted: "C", auth: false}, + }, + results: []string{"A", "B", "C", "D"}, + }, { + // Four signers, consensus of three already being enough to drop someone + signers: []string{"A", "B", "C", "D"}, + votes: []testerVote{ + {signer: "A", voted: "D", auth: false}, + {signer: "B", voted: "D", auth: false}, + {signer: "C", voted: "D", auth: false}, + }, + results: []string{"A", "B", "C"}, + }, { + // Authorizations are counted once per signer per target + signers: []string{"A", "B"}, + votes: []testerVote{ + {signer: "A", voted: "C", auth: true}, + {signer: "B"}, + {signer: "A", voted: "C", auth: true}, + {signer: "B"}, + {signer: "A", voted: "C", auth: true}, + }, + results: []string{"A", "B"}, + }, { + // Authorizing multiple accounts concurrently is permitted + signers: []string{"A", "B"}, + votes: []testerVote{ + {signer: "A", voted: "C", auth: true}, + {signer: "B"}, + {signer: "A", voted: "D", auth: true}, + {signer: "B"}, + {signer: "A"}, + {signer: "B", voted: "D", auth: true}, + {signer: "A"}, + {signer: "B", voted: "C", auth: true}, + }, + results: []string{"A", "B", "C", "D"}, + }, { + // Deauthorizations are counted once per signer per target + signers: []string{"A", "B"}, + votes: []testerVote{ + {signer: "A", voted: "B", auth: false}, + {signer: "B"}, + {signer: "A", voted: "B", auth: false}, + {signer: "B"}, + {signer: "A", voted: "B", auth: false}, + }, + results: []string{"A", "B"}, + }, { + // Deauthorizing multiple accounts concurrently is permitted + signers: []string{"A", "B", "C", "D"}, + votes: []testerVote{ + {signer: "A", voted: "C", auth: false}, + {signer: "B"}, + {signer: "C"}, + {signer: "A", voted: "D", auth: false}, + {signer: "B"}, + {signer: "C"}, + {signer: "A"}, + {signer: "B", voted: "D", auth: false}, + {signer: "C", voted: "D", auth: false}, + {signer: "A"}, + {signer: "B", voted: "C", auth: false}, + }, + results: []string{"A", "B"}, + }, { + // Votes from deauthorized signers are discarded immediately (deauth votes) + signers: []string{"A", "B", "C"}, + votes: []testerVote{ + {signer: "C", voted: "B", auth: false}, + {signer: "A", voted: "C", auth: false}, + {signer: "B", voted: "C", auth: false}, + {signer: "A", voted: "B", auth: false}, + }, + results: []string{"A", "B"}, + }, { + // Votes from deauthorized signers are discarded immediately (auth votes) + signers: []string{"A", "B", "C"}, + votes: []testerVote{ + {signer: "C", voted: "B", auth: false}, + {signer: "A", voted: "C", auth: false}, + {signer: "B", voted: "C", auth: false}, + {signer: "A", voted: "B", auth: false}, + }, + results: []string{"A", "B"}, + }, { + // Cascading changes are not allowed, only the account being voted on may change + signers: []string{"A", "B", "C", "D"}, + votes: []testerVote{ + {signer: "A", voted: "C", auth: false}, + {signer: "B"}, + {signer: "C"}, + {signer: "A", voted: "D", auth: false}, + {signer: "B", voted: "C", auth: false}, + {signer: "C"}, + {signer: "A"}, + {signer: "B", voted: "D", auth: false}, + {signer: "C", voted: "D", auth: false}, + }, + results: []string{"A", "B", "C"}, + }, { + // Changes reaching consensus out of bounds (via a deauth) execute on touch + signers: []string{"A", "B", "C", "D"}, + votes: []testerVote{ + {signer: "A", voted: "C", auth: false}, + {signer: "B"}, + {signer: "C"}, + {signer: "A", voted: "D", auth: false}, + {signer: "B", voted: "C", auth: false}, + {signer: "C"}, + {signer: "A"}, + {signer: "B", voted: "D", auth: false}, + {signer: "C", voted: "D", auth: false}, + {signer: "A"}, + {signer: "C", voted: "C", auth: true}, + }, + results: []string{"A", "B"}, + }, { + // Changes reaching consensus out of bounds (via a deauth) may go out of consensus on first touch + signers: []string{"A", "B", "C", "D"}, + votes: []testerVote{ + {signer: "A", voted: "C", auth: false}, + {signer: "B"}, + {signer: "C"}, + {signer: "A", voted: "D", auth: false}, + {signer: "B", voted: "C", auth: false}, + {signer: "C"}, + {signer: "A"}, + {signer: "B", voted: "D", auth: false}, + {signer: "C", voted: "D", auth: false}, + {signer: "A"}, + {signer: "B", voted: "C", auth: true}, + }, + results: []string{"A", "B", "C"}, + }, { + // Ensure that pending votes don't survive authorization status changes. This + // corner case can only appear if a signer is quickly added, removed and then + // readded (or the inverse), while one of the original voters dropped. If a + // past vote is left cached in the system somewhere, this will interfere with + // the final signer outcome. + signers: []string{"A", "B", "C", "D", "E"}, + votes: []testerVote{ + {signer: "A", voted: "F", auth: true}, // Authorize F, 3 votes needed + {signer: "B", voted: "F", auth: true}, + {signer: "C", voted: "F", auth: true}, + {signer: "D", voted: "F", auth: false}, // Deauthorize F, 4 votes needed (leave A's previous vote "unchanged") + {signer: "E", voted: "F", auth: false}, + {signer: "B", voted: "F", auth: false}, + {signer: "C", voted: "F", auth: false}, + {signer: "D", voted: "F", auth: true}, // Almost authorize F, 2/3 votes needed + {signer: "E", voted: "F", auth: true}, + {signer: "B", voted: "A", auth: false}, // Deauthorize A, 3 votes needed + {signer: "C", voted: "A", auth: false}, + {signer: "D", voted: "A", auth: false}, + {signer: "B", voted: "F", auth: true}, // Finish authorizing F, 3/3 votes needed + }, + results: []string{"B", "C", "D", "E", "F"}, + }, { + // Epoch transitions reset all votes to allow chain checkpointing + epoch: 3, + signers: []string{"A", "B"}, + votes: []testerVote{ + {signer: "A", voted: "C", auth: true}, + {signer: "B"}, + {signer: "A"}, // Checkpoint block, (don't vote here, it's validated outside of snapshots) + {signer: "B", voted: "C", auth: true}, + }, + results: []string{"A", "B"}, + }, + } + // Run through the scenarios and test them + for i, tt := range tests { + // Create the account pool and generate the initial set of signers + accounts := newTesterAccountPool() + + signers := make([]common.Address, len(tt.signers)) + for j, signer := range tt.signers { + signers[j] = accounts.address(signer) + } + for j := 0; j < len(signers); j++ { + for k := j + 1; k < len(signers); k++ { + if bytes.Compare(signers[j][:], signers[k][:]) > 0 { + signers[j], signers[k] = signers[k], signers[j] + } + } + } + // Create the genesis block with the initial set of signers + genesis := &core.Genesis{ + ExtraData: make([]byte, extraVanity+common.AddressLength*len(signers)+extraSeal), + } + for j, signer := range signers { + copy(genesis.ExtraData[extraVanity+j*common.AddressLength:], signer[:]) + } + // Create a pristine blockchain with the genesis injected + db := ethdb.NewMemDatabase() + genesis.Commit(db) + + // Assemble a chain of headers from the cast votes + headers := make([]*types.Header, len(tt.votes)) + for j, vote := range tt.votes { + headers[j] = &types.Header{ + Number: big.NewInt(int64(j) + 1), + Time: big.NewInt(int64(j) * 15), + Coinbase: accounts.address(vote.voted), + Extra: make([]byte, extraVanity+extraSeal), + } + if j > 0 { + headers[j].ParentHash = headers[j-1].Hash() + } + if vote.auth { + copy(headers[j].Nonce[:], nonceAuthVote) + } + accounts.sign(headers[j], vote.signer) + } + // Pass all the headers through clique and ensure tallying succeeds + head := headers[len(headers)-1] + + snap, err := New(¶ms.CliqueConfig{Epoch: tt.epoch}, db).snapshot(&testerChainReader{db: db}, head.Number.Uint64(), head.Hash(), headers) + if err != nil { + t.Errorf("test %d: failed to create voting snapshot: %v", i, err) + continue + } + // Verify the final list of signers against the expected ones + signers = make([]common.Address, len(tt.results)) + for j, signer := range tt.results { + signers[j] = accounts.address(signer) + } + for j := 0; j < len(signers); j++ { + for k := j + 1; k < len(signers); k++ { + if bytes.Compare(signers[j][:], signers[k][:]) > 0 { + signers[j], signers[k] = signers[k], signers[j] + } + } + } + result := snap.signers() + if len(result) != len(signers) { + t.Errorf("test %d: signers mismatch: have %x, want %x", i, result, signers) + continue + } + for j := 0; j < len(result); j++ { + if !bytes.Equal(result[j][:], signers[j][:]) { + t.Errorf("test %d, signer %d: signer mismatch: have %x, want %x", i, j, result[j], signers[j]) + } + } + } +} diff --git a/consensus/consensus.go b/consensus/consensus.go index b02afa63c4..a8984b9a7e 100644 --- a/consensus/consensus.go +++ b/consensus/consensus.go @@ -18,12 +18,13 @@ package consensus import ( + "math/big" + "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/params" "github.com/ethereum/go-ethereum/rpc" - "math/big" ) // ChainReader defines a small collection of methods needed to access the local diff --git a/consensus/ethash/algorithm.go b/consensus/ethash/algorithm.go index 905a7b1ea7..f252a7f3a3 100644 --- a/consensus/ethash/algorithm.go +++ b/consensus/ethash/algorithm.go @@ -94,14 +94,25 @@ func calcDatasetSize(epoch int) uint64 { // reused between hash runs instead of requiring new ones to be created. type hasher func(dest []byte, data []byte) -// makeHasher creates a repetitive hasher, allowing the same hash data structures -// to be reused between hash runs instead of requiring new ones to be created. -// The returned function is not thread safe! +// makeHasher creates a repetitive hasher, allowing the same hash data structures to +// be reused between hash runs instead of requiring new ones to be created. The returned +// function is not thread safe! func makeHasher(h hash.Hash) hasher { + // sha3.state supports Read to get the sum, use it to avoid the overhead of Sum. + // Read alters the state but we reset the hash before every operation. + type readerHash interface { + hash.Hash + Read([]byte) (int, error) + } + rh, ok := h.(readerHash) + if !ok { + panic("can't find Read method on hash") + } + outputLen := rh.Size() return func(dest []byte, data []byte) { - h.Write(data) - h.Sum(dest[:0]) - h.Reset() + rh.Reset() + rh.Write(data) + rh.Read(dest[:outputLen]) } } @@ -203,15 +214,6 @@ func swap(buffer []byte) { } } -// prepare converts an ethash cache or dataset from a byte stream into the internal -// int representation. All ethash methods work with ints to avoid constant byte to -// int conversions as well as to handle both little and big endian systems. -func prepare(dest []uint32, src []byte) { - for i := 0; i < len(dest); i++ { - dest[i] = binary.LittleEndian.Uint32(src[i*4:]) - } -} - // fnv is an algorithm inspired by the FNV hash, which in some cases is used as // a non-associative substitute for XOR. Note that we multiply the prime with // the full 32-bit input, in contrast with the FNV-1 spec which multiplies the diff --git a/consensus/ethash/algorithm_test.go b/consensus/ethash/algorithm_test.go index 841e39233f..f0c6465fdb 100644 --- a/consensus/ethash/algorithm_test.go +++ b/consensus/ethash/algorithm_test.go @@ -18,6 +18,7 @@ package ethash import ( "bytes" + "encoding/binary" "io/ioutil" "math/big" "os" @@ -30,6 +31,15 @@ import ( "github.com/ethereum/go-ethereum/core/types" ) +// prepare converts an ethash cache or dataset from a byte stream into the internal +// int representation. All ethash methods work with ints to avoid constant byte to +// int conversions as well as to handle both little and big endian systems. +func prepare(dest []uint32, src []byte) { + for i := 0; i < len(dest); i++ { + dest[i] = binary.LittleEndian.Uint32(src[i*4:]) + } +} + // Tests whether the dataset size calculator works correctly by cross checking the // hard coded lookup table with the value generated by it. func TestSizeCalculations(t *testing.T) { diff --git a/consensus/ethash/consensus.go b/consensus/ethash/consensus.go index 99eec82211..eb0f73d98b 100644 --- a/consensus/ethash/consensus.go +++ b/consensus/ethash/consensus.go @@ -24,6 +24,7 @@ import ( "runtime" "time" + mapset "github.com/deckarep/golang-set" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/math" "github.com/ethereum/go-ethereum/consensus" @@ -31,7 +32,6 @@ import ( "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/params" - set "gopkg.in/fatih/set.v0" ) // Ethash proof-of-work protocol constants. @@ -177,7 +177,7 @@ func (ethash *Ethash) VerifyUncles(chain consensus.ChainReader, block *types.Blo return errTooManyUncles } // Gather the set of past uncles and ancestors - uncles, ancestors := set.New(), make(map[common.Hash]*types.Header) + uncles, ancestors := mapset.NewSet(), make(map[common.Hash]*types.Header) number, parent := block.NumberU64()-1, block.ParentHash() for i := 0; i < 7; i++ { @@ -198,7 +198,7 @@ func (ethash *Ethash) VerifyUncles(chain consensus.ChainReader, block *types.Blo for _, uncle := range block.Uncles() { // Make sure every uncle is rewarded only once hash := uncle.Hash() - if uncles.Has(hash) { + if uncles.Contains(hash) { return errDuplicateUncle } uncles.Add(hash) @@ -356,8 +356,8 @@ func calcDifficultyByzantium(time uint64, parent *types.Header) *big.Int { x.Set(params.MinimumDifficulty) } // calculate a fake block number for the ice-age delay: - // https://github.com/ethereum/EIPs/pull/669 - // fake_block_number = min(0, block.number - 3_000_000 + // https://github.com/ethereum/EIPs/pull/669 + // fake_block_number = max(0, block.number - 3_000_000) fakeBlockNumber := new(big.Int) if parent.Number.Cmp(big2999999) >= 0 { fakeBlockNumber = fakeBlockNumber.Sub(parent.Number, big2999999) // Note, parent is 1 less than the actual block number diff --git a/consensus/ethash/ethash.go b/consensus/ethash/ethash.go index 1b3dcee302..f79dd6c36b 100644 --- a/consensus/ethash/ethash.go +++ b/consensus/ethash/ethash.go @@ -156,7 +156,7 @@ type lru struct { futureItem interface{} } -// newlru create a new least-recently-used cache for ither the verification caches +// newlru create a new least-recently-used cache for either the verification caches // or the mining datasets. func newlru(what string, maxItems int, new func(epoch uint64) interface{}) *lru { if maxItems <= 0 { @@ -389,7 +389,7 @@ type Config struct { PowMode Mode } -// Ethash is a consensus engine based on proot-of-work implementing the ethash +// Ethash is a consensus engine based on proof-of-work implementing the ethash // algorithm. type Ethash struct { config Config diff --git a/console/bridge.go b/console/bridge.go index b28cc438e2..b0b4d37985 100644 --- a/console/bridge.go +++ b/console/bridge.go @@ -87,7 +87,7 @@ func (b *bridge) NewAccount(call otto.FunctionCall) (response otto.Value) { // OpenWallet is a wrapper around personal.openWallet which can interpret and // react to certain error messages, such as the Trezor PIN matrix request. func (b *bridge) OpenWallet(call otto.FunctionCall) (response otto.Value) { - // Make sure we have an wallet specified to open + // Make sure we have a wallet specified to open if !call.Argument(0).IsString() { throwJSException("first argument must be the wallet URL to open") } @@ -271,7 +271,7 @@ func (b *bridge) SleepBlocks(call otto.FunctionCall) (response otto.Value) { } type jsonrpcCall struct { - Id int64 + ID int64 Method string Params []interface{} } @@ -304,7 +304,7 @@ func (b *bridge) Send(call otto.FunctionCall) (response otto.Value) { resps, _ := call.Otto.Object("new Array()") for _, req := range reqs { resp, _ := call.Otto.Object(`({"jsonrpc":"2.0"})`) - resp.Set("id", req.Id) + resp.Set("id", req.ID) var result json.RawMessage err = b.client.Call(&result, req.Method, req.Params...) switch err := err.(type) { diff --git a/console/console.go b/console/console.go index d843044ffc..0edcb93107 100644 --- a/console/console.go +++ b/console/console.go @@ -60,7 +60,7 @@ type Config struct { Preload []string // Absolute paths to JavaScript files to preload } -// Console is a JavaScript interpreted runtime environment. It is a fully fleged +// Console is a JavaScript interpreted runtime environment. It is a fully fledged // JavaScript console attached to a running node via an external or in-process RPC // client. type Console struct { @@ -73,6 +73,8 @@ type Console struct { printer io.Writer // Output writer to serialize any display strings to } +// New initializes a JavaScript interpreted runtime environment and sets defaults +// with the config struct. func New(config Config) (*Console, error) { // Handle unset config values gracefully if config.Prompter == nil { diff --git a/contracts/ens/ens.go b/contracts/ens/ens.go index 06045a5cd8..75d9d0e4b1 100644 --- a/contracts/ens/ens.go +++ b/contracts/ens/ens.go @@ -95,7 +95,7 @@ func ensParentNode(name string) (common.Hash, common.Hash) { } } -func ensNode(name string) common.Hash { +func EnsNode(name string) common.Hash { parentNode, parentLabel := ensParentNode(name) return crypto.Keccak256Hash(parentNode[:], parentLabel[:]) } @@ -136,7 +136,7 @@ func (self *ENS) getRegistrar(node [32]byte) (*contract.FIFSRegistrarSession, er // Resolve is a non-transactional call that returns the content hash associated with a name. func (self *ENS) Resolve(name string) (common.Hash, error) { - node := ensNode(name) + node := EnsNode(name) resolver, err := self.getResolver(node) if err != nil { @@ -165,7 +165,7 @@ func (self *ENS) Register(name string) (*types.Transaction, error) { // SetContentHash sets the content hash associated with a name. Only works if the caller // owns the name, and the associated resolver implements a `setContent` function. func (self *ENS) SetContentHash(name string, hash common.Hash) (*types.Transaction, error) { - node := ensNode(name) + node := EnsNode(name) resolver, err := self.getResolver(node) if err != nil { diff --git a/contracts/ens/ens_test.go b/contracts/ens/ens_test.go index 0016f47dbf..6ad8447082 100644 --- a/contracts/ens/ens_test.go +++ b/contracts/ens/ens_test.go @@ -55,7 +55,7 @@ func TestENS(t *testing.T) { if err != nil { t.Fatalf("can't deploy resolver: %v", err) } - if _, err := ens.SetResolver(ensNode(name), resolverAddr); err != nil { + if _, err := ens.SetResolver(EnsNode(name), resolverAddr); err != nil { t.Fatalf("can't set resolver: %v", err) } contractBackend.Commit() diff --git a/contracts/utils.go b/contracts/utils.go index 27570e8230..182e2111e6 100644 --- a/contracts/utils.go +++ b/contracts/utils.go @@ -32,6 +32,7 @@ import ( "github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/consensus" @@ -76,7 +77,7 @@ func CreateTransactionSign(chainConfig *params.ChainConfig, pool *core.TxPool, m // Create and send tx to smart contract for sign validate block. nonce := pool.State().GetNonce(account.Address) tx := CreateTxSign(block.Number(), block.Hash(), nonce, common.HexToAddress(common.BlockSigners)) - txSigned, err := wallet.SignTx(account, tx, chainConfig.ChainId) + txSigned, err := wallet.SignTx(account, tx, chainConfig.ChainID) if err != nil { log.Error("Fail to create tx sign", "error", err) return err @@ -105,7 +106,7 @@ func CreateTransactionSign(chainConfig *params.ChainConfig, pool *core.TxPool, m log.Error("Fail to get tx opening for randomize", "error", err) return err } - txSigned, err := wallet.SignTx(account, tx, chainConfig.ChainId) + txSigned, err := wallet.SignTx(account, tx, chainConfig.ChainID) if err != nil { log.Error("Fail to create tx secret", "error", err) return err @@ -134,7 +135,7 @@ func CreateTransactionSign(chainConfig *params.ChainConfig, pool *core.TxPool, m log.Error("Fail to get tx opening for randomize", "error", err) return err } - txSigned, err := wallet.SignTx(account, tx, chainConfig.ChainId) + txSigned, err := wallet.SignTx(account, tx, chainConfig.ChainID) if err != nil { log.Error("Fail to create tx opening", "error", err) return err @@ -326,8 +327,10 @@ func GetRewardForCheckpoint(c *XDPoS.XDPoS, chain consensus.ChainReader, header block := chain.GetBlock(header.Hash(), i) txs := block.Transactions() if !chain.Config().IsTIPSigning(header.Number) { - receipts := core.GetBlockReceipts(c.GetDb(), header.Hash(), i) + receipts := rawdb.ReadReceipts(c.GetDb(), header.Hash(), i) signData = c.CacheData(header, txs, receipts) + // receipts := core.GetBlockReceipts(c.GetDb(), header.Hash(), i) + // signData = c.CacheData(header, txs, receipts) } else { signData = c.CacheSigner(header.Hash(), txs) } diff --git a/core/asm/compiler.go b/core/asm/compiler.go index 18dc0877ff..c7a5440701 100644 --- a/core/asm/compiler.go +++ b/core/asm/compiler.go @@ -17,7 +17,6 @@ package asm import ( - "errors" "fmt" "math/big" "os" @@ -52,7 +51,7 @@ func NewCompiler(debug bool) *Compiler { // the compiler. // // feed is the first pass in the compile stage as it -// collect the used labels in the program and keeps a +// 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 @@ -121,7 +120,7 @@ func (c *Compiler) next() token { return token } -// compile line compiles a single line instruction e.g. +// compileLine compiles a single line instruction e.g. // "push 1", "jump @label". func (c *Compiler) compileLine() error { n := c.next() @@ -237,19 +236,16 @@ func (c *Compiler) pushBin(v interface{}) { // isPush returns whether the string op is either any of // push(N). func isPush(op string) bool { - return op == "push" + return strings.ToUpper(op) == "PUSH" } // isJump returns whether the string op is jump(i) func isJump(op string) bool { - return op == "jumpi" || op == "jump" + return strings.ToUpper(op) == "JUMPI" || strings.ToUpper(op) == "JUMP" } // toBinary converts text to a vm.OpCode func toBinary(text string) vm.OpCode { - if isPush(text) { - text = "push1" - } return vm.StringToOp(strings.ToUpper(text)) } @@ -264,11 +260,6 @@ func (err compileError) Error() string { return fmt.Sprintf("%d syntax error: unexpected %v, expected %v", err.lineno, err.got, err.want) } -var ( - errExpBol = errors.New("expected beginning of line") - errExpElementOrLabel = errors.New("expected beginning of line") -) - func compileErr(c token, got, want string) error { return compileError{ got: got, diff --git a/core/asm/lexer.go b/core/asm/lexer.go index 4d62159e55..91caeb27bc 100644 --- a/core/asm/lexer.go +++ b/core/asm/lexer.go @@ -242,7 +242,7 @@ func lexLabel(l *lexer) stateFn { } // lexInsideString lexes the inside of a string until -// until the state function finds the closing quote. +// the state function finds the closing quote. // It returns the lex text state function. func lexInsideString(l *lexer) stateFn { if l.acceptRunUntil('"') { diff --git a/core/bench_test.go b/core/bench_test.go index e23f0d19d1..748aebe407 100644 --- a/core/bench_test.go +++ b/core/bench_test.go @@ -26,6 +26,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/math" "github.com/ethereum/go-ethereum/consensus/ethash" + "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/crypto" @@ -148,7 +149,7 @@ func benchInsertChain(b *testing.B, disk bool, gen func(int, *BlockGen)) { // Create the database in memory or in a temporary directory. var db ethdb.Database if !disk { - db, _ = ethdb.NewMemDatabase() + db = ethdb.NewMemDatabase() } else { dir, err := ioutil.TempDir("", "eth-core-bench") if err != nil { @@ -234,13 +235,15 @@ func makeChainForBench(db ethdb.Database, full bool, count uint64) { ReceiptHash: types.EmptyRootHash, } hash = header.Hash() - WriteHeader(db, header) - WriteCanonicalHash(db, hash, n) - WriteTd(db, hash, n, big.NewInt(int64(n+1))) + + rawdb.WriteHeader(db, header) + rawdb.WriteCanonicalHash(db, hash, n) + rawdb.WriteTd(db, hash, n, big.NewInt(int64(n+1))) + if full || n == 0 { block := types.NewBlockWithHeader(header) - WriteBody(db, hash, n, block.Body()) - WriteBlockReceipts(db, hash, n, nil) + rawdb.WriteBody(db, hash, n, block.Body()) + rawdb.WriteReceipts(db, hash, n, nil) } } } @@ -292,11 +295,10 @@ func benchReadChain(b *testing.B, full bool, count uint64) { header := chain.GetHeaderByNumber(n) if full { hash := header.Hash() - GetBody(db, hash, n) - GetBlockReceipts(db, hash, n) + rawdb.ReadBody(db, hash, n) + rawdb.ReadReceipts(db, hash, n) } } - chain.Stop() db.Close() } diff --git a/core/block_validator_test.go b/core/block_validator_test.go index c44def0148..3441b96506 100644 --- a/core/block_validator_test.go +++ b/core/block_validator_test.go @@ -32,7 +32,7 @@ import ( func TestHeaderVerification(t *testing.T) { // Create a simple chain to verify var ( - testdb, _ = ethdb.NewMemDatabase() + testdb = ethdb.NewMemDatabase() gspec = &Genesis{Config: params.TestChainConfig} genesis = gspec.MustCommit(testdb) blocks, _ = GenerateChain(params.TestChainConfig, genesis, ethash.NewFaker(), testdb, 8, nil) @@ -83,7 +83,7 @@ func TestHeaderConcurrentVerification32(t *testing.T) { testHeaderConcurrentVeri func testHeaderConcurrentVerification(t *testing.T, threads int) { // Create a simple chain to verify var ( - testdb, _ = ethdb.NewMemDatabase() + testdb = ethdb.NewMemDatabase() gspec = &Genesis{Config: params.TestChainConfig} genesis = gspec.MustCommit(testdb) blocks, _ = GenerateChain(params.TestChainConfig, genesis, ethash.NewFaker(), testdb, 8, nil) @@ -154,7 +154,7 @@ func TestHeaderConcurrentAbortion32(t *testing.T) { testHeaderConcurrentAbortion func testHeaderConcurrentAbortion(t *testing.T, threads int) { // Create a simple chain to verify var ( - testdb, _ = ethdb.NewMemDatabase() + testdb = ethdb.NewMemDatabase() gspec = &Genesis{Config: params.TestChainConfig} genesis = gspec.MustCommit(testdb) blocks, _ = GenerateChain(params.TestChainConfig, genesis, ethash.NewFaker(), testdb, 1024, nil) diff --git a/core/blockchain.go b/core/blockchain.go index 99f561998e..1c5cf543ed 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -32,6 +32,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/mclock" "github.com/ethereum/go-ethereum/consensus" + "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/consensus/XDPoS" contractValidator "github.com/ethereum/go-ethereum/contracts/validator/contract" "github.com/ethereum/go-ethereum/core/state" @@ -223,7 +224,7 @@ func (bc *BlockChain) getProcInterrupt() bool { // assumes that the chain manager mutex is held. func (bc *BlockChain) loadLastState() error { // Restore the last known head block - head := GetHeadBlockHash(bc.db) + head := rawdb.ReadHeadBlockHash(bc.db) if head == (common.Hash{}) { // Corrupt or empty database, init from scratch log.Warn("Empty database, resetting chain") @@ -249,7 +250,7 @@ func (bc *BlockChain) loadLastState() error { // Restore the last known head header currentHeader := currentBlock.Header() - if head := GetHeadHeaderHash(bc.db); head != (common.Hash{}) { + if head := rawdb.ReadHeadHeaderHash(bc.db); head != (common.Hash{}) { if header := bc.GetHeaderByHash(head); header != nil { currentHeader = header } @@ -258,7 +259,7 @@ func (bc *BlockChain) loadLastState() error { // Restore the last known head fast block bc.currentFastBlock.Store(currentBlock) - if head := GetHeadFastBlockHash(bc.db); head != (common.Hash{}) { + if head := rawdb.ReadHeadFastBlockHash(bc.db); head != (common.Hash{}) { if block := bc.GetBlockByHash(head); block != nil { bc.currentFastBlock.Store(block) } @@ -289,8 +290,8 @@ func (bc *BlockChain) SetHead(head uint64) error { defer bc.mu.Unlock() // Rewind the header chain, deleting all block bodies until then - delFn := func(hash common.Hash, num uint64) { - DeleteBody(bc.db, hash, num) + delFn := func(db rawdb.DatabaseDeleter, hash common.Hash, num uint64) { + rawdb.DeleteBody(db, hash, num) } bc.hc.SetHead(head, delFn) currentHeader := bc.hc.CurrentHeader() @@ -324,12 +325,10 @@ func (bc *BlockChain) SetHead(head uint64) error { } currentBlock := bc.CurrentBlock() currentFastBlock := bc.CurrentFastBlock() - if err := WriteHeadBlockHash(bc.db, currentBlock.Hash()); err != nil { - log.Crit("Failed to reset head full block", "err", err) - } - if err := WriteHeadFastBlockHash(bc.db, currentFastBlock.Hash()); err != nil { - log.Crit("Failed to reset head fast block", "err", err) - } + + rawdb.WriteHeadBlockHash(bc.db, currentBlock.Hash()) + rawdb.WriteHeadFastBlockHash(bc.db, currentFastBlock.Hash()) + return bc.loadLastState() } @@ -427,9 +426,8 @@ func (bc *BlockChain) ResetWithGenesisBlock(genesis *types.Block) error { if err := bc.hc.WriteTd(genesis.Hash(), genesis.NumberU64(), genesis.Difficulty()); err != nil { log.Crit("Failed to write genesis block TD", "err", err) } - if err := WriteBlock(bc.db, genesis); err != nil { - log.Crit("Failed to write genesis block", "err", err) - } + rawdb.WriteBlock(bc.db, genesis) + bc.genesisBlock = genesis bc.insert(bc.genesisBlock) bc.currentBlock.Store(bc.genesisBlock) @@ -473,15 +471,19 @@ func (bc *BlockChain) ExportN(w io.Writer, first uint64, last uint64) error { } log.Info("Exporting batch of blocks", "count", last-first+1) + start, reported := time.Now(), time.Now() for nr := first; nr <= last; nr++ { block := bc.GetBlockByNumber(nr) if block == nil { return fmt.Errorf("export failed on #%d: not found", nr) } - if err := block.EncodeRLP(w); err != nil { return err } + if time.Since(reported) >= statsReportLimit { + log.Info("Exporting blocks", "exported", block.NumberU64()-first, "elapsed", common.PrettyDuration(time.Since(start))) + reported = time.Now() + } } return nil @@ -495,15 +497,12 @@ func (bc *BlockChain) ExportN(w io.Writer, first uint64, last uint64) error { // Note, this function assumes that the `mu` mutex is held! func (bc *BlockChain) insert(block *types.Block) { // If the block is on a side chain or an unknown one, force other heads onto it too - updateHeads := GetCanonicalHash(bc.db, block.NumberU64()) != block.Hash() + updateHeads := rawdb.ReadCanonicalHash(bc.db, block.NumberU64()) != block.Hash() // Add the block to the canonical chain number scheme and mark as the head - if err := WriteCanonicalHash(bc.db, block.Hash(), block.NumberU64()); err != nil { - log.Crit("Failed to insert block number", "err", err) - } - if err := WriteHeadBlockHash(bc.db, block.Hash()); err != nil { - log.Crit("Failed to insert head block hash", "err", err) - } + rawdb.WriteCanonicalHash(bc.db, block.Hash(), block.NumberU64()) + rawdb.WriteHeadBlockHash(bc.db, block.Hash()) + bc.currentBlock.Store(block) // save cache BlockSigners @@ -515,10 +514,8 @@ func (bc *BlockChain) insert(block *types.Block) { // If the block is better than our head or is on a different chain, force update heads if updateHeads { bc.hc.SetCurrentHeader(block.Header()) + rawdb.WriteHeadFastBlockHash(bc.db, block.Hash()) - if err := WriteHeadFastBlockHash(bc.db, block.Hash()); err != nil { - log.Crit("Failed to insert head fast block hash", "err", err) - } bc.currentFastBlock.Store(block) } } @@ -536,7 +533,11 @@ func (bc *BlockChain) GetBody(hash common.Hash) *types.Body { body := cached.(*types.Body) return body } - body := GetBody(bc.db, hash, bc.hc.GetBlockNumber(hash)) + number := bc.hc.GetBlockNumber(hash) + if number == nil { + return nil + } + body := rawdb.ReadBody(bc.db, hash, *number) if body == nil { return nil } @@ -552,7 +553,11 @@ func (bc *BlockChain) GetBodyRLP(hash common.Hash) rlp.RawValue { if cached, ok := bc.bodyRLPCache.Get(hash); ok { return cached.(rlp.RawValue) } - body := GetBodyRLP(bc.db, hash, bc.hc.GetBlockNumber(hash)) + number := bc.hc.GetBlockNumber(hash) + if number == nil { + return nil + } + body := rawdb.ReadBodyRLP(bc.db, hash, *number) if len(body) == 0 { return nil } @@ -566,8 +571,7 @@ func (bc *BlockChain) HasBlock(hash common.Hash, number uint64) bool { if bc.blockCache.Contains(hash) { return true } - ok, _ := bc.db.Has(blockBodyKey(hash, number)) - return ok + return rawdb.HasBody(bc.db, hash, number) } // HasState checks if state trie is fully present in the database or not. @@ -594,7 +598,7 @@ func (bc *BlockChain) GetBlock(hash common.Hash, number uint64) *types.Block { if block, ok := bc.blockCache.Get(hash); ok { return block.(*types.Block) } - block := GetBlock(bc.db, hash, number) + block := rawdb.ReadBlock(bc.db, hash, number) if block == nil { return nil } @@ -605,13 +609,17 @@ func (bc *BlockChain) GetBlock(hash common.Hash, number uint64) *types.Block { // GetBlockByHash retrieves a block from the database by hash, caching it if found. func (bc *BlockChain) GetBlockByHash(hash common.Hash) *types.Block { - return bc.GetBlock(hash, bc.hc.GetBlockNumber(hash)) + number := bc.hc.GetBlockNumber(hash) + if number == nil { + return nil + } + return bc.GetBlock(hash, *number) } // GetBlockByNumber retrieves a block from the database by number, caching it // (associated with its hash) if found. func (bc *BlockChain) GetBlockByNumber(number uint64) *types.Block { - hash := GetCanonicalHash(bc.db, number) + hash := rawdb.ReadCanonicalHash(bc.db, number) if hash == (common.Hash{}) { return nil } @@ -620,21 +628,28 @@ func (bc *BlockChain) GetBlockByNumber(number uint64) *types.Block { // GetReceiptsByHash retrieves the receipts for all transactions in a given block. func (bc *BlockChain) GetReceiptsByHash(hash common.Hash) types.Receipts { - return GetBlockReceipts(bc.db, hash, GetBlockNumber(bc.db, hash)) + number := rawdb.ReadHeaderNumber(bc.db, hash) + if number == nil { + return nil + } + return rawdb.ReadReceipts(bc.db, hash, *number) } // GetBlocksFromHash returns the block corresponding to hash and up to n-1 ancestors. // [deprecated by eth/62] func (bc *BlockChain) GetBlocksFromHash(hash common.Hash, n int) (blocks []*types.Block) { number := bc.hc.GetBlockNumber(hash) + if number == nil { + return nil + } for i := 0; i < n; i++ { - block := bc.GetBlock(hash, number) + block := bc.GetBlock(hash, *number) if block == nil { break } blocks = append(blocks, block) hash = block.ParentHash() - number-- + *number-- } return } @@ -688,9 +703,9 @@ func (bc *BlockChain) Stop() { } } for !bc.triegc.Empty() { - triedb.Dereference(bc.triegc.PopItem().(common.Hash), common.Hash{}) + triedb.Dereference(bc.triegc.PopItem().(common.Hash)) } - if size := triedb.Size(); size != 0 { + if size, _ := triedb.Size(); size != 0 { log.Error("Dangling trie nodes after full cleanup") } } @@ -739,12 +754,12 @@ func (bc *BlockChain) Rollback(chain []common.Hash) { if currentFastBlock := bc.CurrentFastBlock(); currentFastBlock.Hash() == hash { newFastBlock := bc.GetBlock(currentFastBlock.ParentHash(), currentFastBlock.NumberU64()-1) bc.currentFastBlock.Store(newFastBlock) - WriteHeadFastBlockHash(bc.db, newFastBlock.Hash()) + rawdb.WriteHeadFastBlockHash(bc.db, newFastBlock.Hash()) } if currentBlock := bc.CurrentBlock(); currentBlock.Hash() == hash { newBlock := bc.GetBlock(currentBlock.ParentHash(), currentBlock.NumberU64()-1) bc.currentBlock.Store(newBlock) - WriteHeadBlockHash(bc.db, newBlock.Hash()) + rawdb.WriteHeadBlockHash(bc.db, newBlock.Hash()) } } } @@ -829,15 +844,10 @@ func (bc *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain [ return i, fmt.Errorf("failed to set receipts data: %v", err) } // Write all the data out into the database - if err := WriteBody(batch, block.Hash(), block.NumberU64(), block.Body()); err != nil { - return i, fmt.Errorf("failed to write block body: %v", err) - } - if err := WriteBlockReceipts(batch, block.Hash(), block.NumberU64(), receipts); err != nil { - return i, fmt.Errorf("failed to write block receipts: %v", err) - } - if err := WriteTxLookupEntries(batch, block); err != nil { - return i, fmt.Errorf("failed to write lookup metadata: %v", err) - } + rawdb.WriteBody(batch, block.Hash(), block.NumberU64(), block.Body()) + rawdb.WriteReceipts(batch, block.Hash(), block.NumberU64(), receipts) + rawdb.WriteTxLookupEntries(batch, block) + stats.processed++ if batch.ValueSize() >= ethdb.IdealBatchSize { @@ -861,9 +871,7 @@ func (bc *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain [ if td := bc.GetTd(head.Hash(), head.NumberU64()); td != nil { // Rewind may have occurred, skip in that case currentFastBlock := bc.CurrentFastBlock() if bc.GetTd(currentFastBlock.Hash(), currentFastBlock.NumberU64()).Cmp(td) < 0 { - if err := WriteHeadFastBlockHash(bc.db, head.Hash()); err != nil { - log.Crit("Failed to update head fast block hash", "err", err) - } + rawdb.WriteHeadFastBlockHash(bc.db, head.Hash()) bc.currentFastBlock.Store(head) } } @@ -891,9 +899,8 @@ func (bc *BlockChain) WriteBlockWithoutState(block *types.Block, td *big.Int) (e if err := bc.hc.WriteTd(block.Hash(), block.NumberU64(), td); err != nil { return err } - if err := WriteBlock(bc.db, block); err != nil { - return err - } + rawdb.WriteBlock(bc.db, block) + return nil } @@ -921,9 +928,8 @@ func (bc *BlockChain) WriteBlockWithState(block *types.Block, receipts []*types. } // Write other block data using a batch. batch := bc.db.NewBatch() - if err := WriteBlock(batch, block); err != nil { - return NonStatTy, err - } + rawdb.WriteBlock(batch, block) + root, err := state.Commit(bc.chainConfig.IsEIP158(block.Number())) if err != nil { return NonStatTy, err @@ -941,33 +947,29 @@ func (bc *BlockChain) WriteBlockWithState(block *types.Block, receipts []*types. bc.triegc.Push(root, -float32(block.NumberU64())) if current := block.NumberU64(); current > triesInMemory { + // If we exceeded our memory allowance, flush matured singleton nodes to disk + var ( + nodes, imgs = triedb.Size() + limit = common.StorageSize(bc.cacheConfig.TrieNodeLimit) * 1024 * 1024 + ) + if nodes > limit || imgs > 4*1024*1024 { + triedb.Cap(limit - ethdb.IdealBatchSize) + } // Find the next state trie we need to commit header := bc.GetHeaderByNumber(current - triesInMemory) chosen := header.Number.Uint64() - // Only write to disk if we exceeded our memory allowance *and* also have at - // least a given number of tries gapped. - var ( - size = triedb.Size() - limit = common.StorageSize(bc.cacheConfig.TrieNodeLimit) * 1024 * 1024 - ) - if size > limit || bc.gcproc > bc.cacheConfig.TrieTimeLimit { + // If we exceeded out time allowance, flush an entire trie to disk + if bc.gcproc > bc.cacheConfig.TrieTimeLimit { // If we're exceeding limits but haven't reached a large enough memory gap, // warn the user that the system is becoming unstable. - if chosen < lastWrite+triesInMemory { - switch { - case size >= 2*limit: - log.Warn("State memory usage too high, committing", "size", size, "limit", limit, "optimum", float64(chosen-lastWrite)/triesInMemory) - case bc.gcproc >= 2*bc.cacheConfig.TrieTimeLimit: - log.Info("State in memory for too long, committing", "time", bc.gcproc, "allowance", bc.cacheConfig.TrieTimeLimit, "optimum", float64(chosen-lastWrite)/triesInMemory) - } - } - // If optimum or critical limits reached, write to disk - if chosen >= lastWrite+triesInMemory || size >= 2*limit || bc.gcproc >= 2*bc.cacheConfig.TrieTimeLimit { - triedb.Commit(header.Root, true) - lastWrite = chosen - bc.gcproc = 0 + if chosen < lastWrite+triesInMemory && bc.gcproc >= 2*bc.cacheConfig.TrieTimeLimit { + log.Info("State in memory for too long, committing", "time", bc.gcproc, "allowance", bc.cacheConfig.TrieTimeLimit, "optimum", float64(chosen-lastWrite)/triesInMemory) } + // Flush an entire trie and restart the counters + triedb.Commit(header.Root, true) + lastWrite = chosen + bc.gcproc = 0 } // Garbage collect anything below our required write retention for !bc.triegc.Empty() { @@ -976,13 +978,12 @@ func (bc *BlockChain) WriteBlockWithState(block *types.Block, receipts []*types. bc.triegc.Push(root, number) break } - triedb.Dereference(root.(common.Hash), common.Hash{}) + triedb.Dereference(root.(common.Hash)) } } } - if err := WriteBlockReceipts(batch, block.Hash(), block.NumberU64(), receipts); err != nil { - return NonStatTy, err - } + rawdb.WriteReceipts(batch, block.Hash(), block.NumberU64(), receipts) + // If the total difficulty is higher than our known, add it to the canonical chain // Second clause in the if statement reduces the vulnerability to selfish mining. // Please refer to http://www.cs.cornell.edu/~ie53/publications/btcProcFC.pdf @@ -999,14 +1000,10 @@ func (bc *BlockChain) WriteBlockWithState(block *types.Block, receipts []*types. return NonStatTy, err } } - // Write the positional metadata for transaction and receipt lookups - if err := WriteTxLookupEntries(batch, block); err != nil { - return NonStatTy, err - } - // Write hash preimages - if err := WritePreimages(bc.db, block.NumberU64(), state.Preimages()); err != nil { - return NonStatTy, err - } + // Write the positional metadata for transaction/receipt lookups and preimages + rawdb.WriteTxLookupEntries(batch, block) + rawdb.WritePreimages(batch, block.NumberU64(), state.Preimages()) + status = CanonStatTy } else { status = SideStatTy @@ -1044,10 +1041,14 @@ func (bc *BlockChain) InsertChain(chain types.Blocks) (int, error) { // only reason this method exists as a separate one is to make locking cleaner // with deferred statements. func (bc *BlockChain) insertChain(chain types.Blocks) (int, []interface{}, []*types.Log, error) { + // Sanity check that we have something meaningful to import + if len(chain) == 0 { + return 0, nil, nil, nil + } // Do a sanity check that the provided chain is actually ordered and linked for i := 1; i < len(chain); i++ { if chain[i].NumberU64() != chain[i-1].NumberU64()+1 || chain[i].ParentHash() != chain[i-1].Hash() { - // Chain broke ancestry, log a messge (programming error) and skip insertion + // Chain broke ancestry, log a message (programming error) and skip insertion log.Error("Non contiguous block insert", "number", chain[i].Number(), "hash", chain[i].Hash(), "parent", chain[i].ParentHash(), "prevnumber", chain[i-1].Number(), "prevhash", chain[i-1].Hash()) @@ -1083,6 +1084,9 @@ func (bc *BlockChain) insertChain(chain types.Blocks) (int, []interface{}, []*ty abort, results := bc.engine.VerifyHeaders(bc, headers, seals) defer close(abort) + // Start a parallel signature recovery (signer will fluke on fork transition, minimal perf loss) + senderCacher.recoverFromBlocks(types.MakeSigner(bc.chainConfig, chain[0].Number()), chain) + // Iterate over the blocks and insert when the verifier permits for i, block := range chain { // If the chain is terminating, stop processing blocks @@ -1218,7 +1222,9 @@ func (bc *BlockChain) insertChain(chain types.Blocks) (int, []interface{}, []*ty } stats.processed++ stats.usedGas += usedGas - stats.report(chain, i, bc.stateCache.TrieDB().Size()) + // stats.report(chain, i, bc.stateCache.TrieDB().Size()) + cache1, _ := bc.stateCache.TrieDB().Size() + stats.report(chain, i, cache1) if status == CanonStatTy && bc.chainConfig.XDPoS != nil { // epoch block if (chain[i].NumberU64() % bc.chainConfig.XDPoS.Epoch) == 0 { @@ -1232,6 +1238,9 @@ func (bc *BlockChain) insertChain(chain types.Blocks) (int, []interface{}, []*ty } } } + + cache, _ := bc.stateCache.TrieDB().Size() + stats.report(chain, i, cache) } // Append a single chain head event if we've progressed the chain if lastCanon != nil && bc.CurrentBlock().Hash() == lastCanon.Hash() { @@ -1418,7 +1427,9 @@ func (bc *BlockChain) insertBlock(block *types.Block) ([]interface{}, []*types.L } stats.processed++ stats.usedGas += result.usedGas - stats.report(types.Blocks{block}, 0, bc.stateCache.TrieDB().Size()) + // stats.report(types.Blocks{block}, 0, bc.stateCache.TrieDB().Size()) + cache, _ := bc.stateCache.TrieDB().Size() + stats.report(types.Blocks{block}, 0, cache) if status == CanonStatTy && bc.chainConfig.XDPoS != nil { // epoch block if (block.NumberU64() % bc.chainConfig.XDPoS.Epoch) == 0 { @@ -1449,8 +1460,8 @@ type insertStats struct { startTime mclock.AbsTime } -// statsReportLimit is the time limit during import after which we always print -// out progress. This avoids the user wondering what's going on. +// statsReportLimit is the time limit during import and export after which we +// always print out progress. This avoids the user wondering what's going on. const statsReportLimit = 8 * time.Second // report prints statistics if some number of blocks have been processed @@ -1503,9 +1514,13 @@ func (bc *BlockChain) reorg(oldBlock, newBlock *types.Block) error { // collectLogs collects the logs that were generated during the // processing of the block that corresponds with the given hash. // These logs are later announced as deleted. - collectLogs = func(h common.Hash) { + collectLogs = func(hash common.Hash) { // Coalesce logs and set 'Removed'. - receipts := GetBlockReceipts(bc.db, h, bc.hc.GetBlockNumber(h)) + number := bc.hc.GetBlockNumber(hash) + if number == nil { + return + } + receipts := rawdb.ReadReceipts(bc.db, hash, *number) for _, receipt := range receipts { for _, log := range receipt.Logs { del := *log @@ -1574,18 +1589,19 @@ func (bc *BlockChain) reorg(oldBlock, newBlock *types.Block) error { // insert the block in the canonical way, re-writing history bc.insert(newChain[i]) // write lookup entries for hash based transaction/receipt searches - if err := WriteTxLookupEntries(bc.db, newChain[i]); err != nil { - return err - } + rawdb.WriteTxLookupEntries(bc.db, newChain[i]) addedTxs = append(addedTxs, newChain[i].Transactions()...) } // calculate the difference between deleted and added transactions diff := types.TxDifference(deletedTxs, addedTxs) // When transactions get deleted from the database that means the // receipts that were created in the fork must also be deleted + batch := bc.db.NewBatch() for _, tx := range diff { - DeleteTxLookupEntry(bc.db, tx.Hash()) + rawdb.DeleteTxLookupEntry(batch, tx.Hash()) } + batch.Write() + if len(deletedLogs) > 0 { go bc.rmLogsFeed.Send(RemovedLogsEvent{deletedLogs}) } @@ -1635,27 +1651,21 @@ func (bc *BlockChain) update() { } } -// BadBlockArgs represents the entries in the list returned when bad blocks are queried. -type BadBlockArgs struct { - Hash common.Hash `json:"hash"` - Header *types.Header `json:"header"` -} - // BadBlocks returns a list of the last 'bad blocks' that the client has seen on the network -func (bc *BlockChain) BadBlocks() ([]BadBlockArgs, error) { - headers := make([]BadBlockArgs, 0, bc.badBlocks.Len()) +func (bc *BlockChain) BadBlocks() []*types.Block { + blocks := make([]*types.Block, 0, bc.badBlocks.Len()) for _, hash := range bc.badBlocks.Keys() { - if hdr, exist := bc.badBlocks.Peek(hash); exist { - header := hdr.(*types.Header) - headers = append(headers, BadBlockArgs{header.Hash(), header}) + if blk, exist := bc.badBlocks.Peek(hash); exist { + block := blk.(*types.Block) + blocks = append(blocks, block) } } - return headers, nil + return blocks } // addBadBlock adds a bad block to the bad-block LRU cache func (bc *BlockChain) addBadBlock(block *types.Block) { - bc.badBlocks.Add(block.Header().Hash(), block.Header()) + bc.badBlocks.Add(block.Hash(), block) } // reportBlock logs a bad block error. @@ -1773,6 +1783,18 @@ func (bc *BlockChain) GetBlockHashesFromHash(hash common.Hash, max uint64) []com return bc.hc.GetBlockHashesFromHash(hash, max) } +// GetAncestor retrieves the Nth ancestor of a given block. It assumes that either the given block or +// a close ancestor of it is canonical. maxNonCanonical points to a downwards counter limiting the +// number of blocks to be individually checked before we reach the canonical chain. +// +// Note: ancestor == 0 returns the same block, 1 returns its parent and so on. +func (bc *BlockChain) GetAncestor(hash common.Hash, number, ancestor uint64, maxNonCanonical *uint64) (common.Hash, uint64) { + bc.chainmu.Lock() + defer bc.chainmu.Unlock() + + return bc.hc.GetAncestor(hash, number, ancestor, maxNonCanonical) +} + // GetHeaderByNumber retrieves a block header from the database by number, // caching it (associated with its hash) if found. func (bc *BlockChain) GetHeaderByNumber(number uint64) *types.Header { diff --git a/core/blockchain_test.go b/core/blockchain_test.go index 8ec3c3df39..14fd67eafd 100644 --- a/core/blockchain_test.go +++ b/core/blockchain_test.go @@ -25,7 +25,9 @@ import ( "time" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/consensus" "github.com/ethereum/go-ethereum/consensus/ethash" + "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" @@ -34,6 +36,39 @@ import ( "github.com/ethereum/go-ethereum/params" ) +// So we can deterministically seed different blockchains +var ( + canonicalSeed = 1 + forkSeed = 2 +) + +// newCanonical creates a chain database, and injects a deterministic canonical +// chain. Depending on the full flag, if creates either a full block chain or a +// header only chain. +func newCanonical(engine consensus.Engine, n int, full bool) (ethdb.Database, *BlockChain, error) { + var ( + db = ethdb.NewMemDatabase() + genesis = new(Genesis).MustCommit(db) + ) + + // Initialize a fresh chain with only a genesis block + blockchain, _ := NewBlockChain(db, nil, params.AllEthashProtocolChanges, engine, vm.Config{}) + // Create and inject the requested chain + if n == 0 { + return db, blockchain, nil + } + if full { + // Full block-chain requested + blocks := makeBlockChain(genesis, n, engine, db, canonicalSeed) + _, err := blockchain.InsertChain(blocks) + return db, blockchain, err + } + // Header-only chain requested + headers := makeHeaderChain(genesis.Header(), n, engine, db, canonicalSeed) + _, err := blockchain.InsertHeaderChain(headers, 1) + return db, blockchain, err +} + // 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)) { // Copy old chain up to #i into a new db @@ -128,8 +163,8 @@ func testBlockChainImport(chain types.Blocks, blockchain *BlockChain) error { return err } blockchain.mu.Lock() - WriteTd(blockchain.db, block.Hash(), block.NumberU64(), new(big.Int).Add(block.Difficulty(), blockchain.GetTdByHash(block.ParentHash()))) - WriteBlock(blockchain.db, block) + rawdb.WriteTd(blockchain.db, block.Hash(), block.NumberU64(), new(big.Int).Add(block.Difficulty(), blockchain.GetTdByHash(block.ParentHash()))) + rawdb.WriteBlock(blockchain.db, block) statedb.Commit(false) blockchain.mu.Unlock() } @@ -146,8 +181,8 @@ func testHeaderChainImport(chain []*types.Header, blockchain *BlockChain) error } // Manually insert the header into the database, but don't reorganise (allows subsequent testing) blockchain.mu.Lock() - WriteTd(blockchain.db, header.Hash(), header.Number.Uint64(), new(big.Int).Add(header.Difficulty, blockchain.GetTdByHash(header.ParentHash))) - WriteHeader(blockchain.db, header) + rawdb.WriteTd(blockchain.db, header.Hash(), header.Number.Uint64(), new(big.Int).Add(header.Difficulty, blockchain.GetTdByHash(header.ParentHash))) + rawdb.WriteHeader(blockchain.db, header) blockchain.mu.Unlock() } return nil @@ -173,7 +208,7 @@ func TestLastBlock(t *testing.T) { if _, err := blockchain.InsertChain(blocks); err != nil { t.Fatalf("Failed to insert block: %v", err) } - if blocks[len(blocks)-1].Hash() != GetHeadBlockHash(blockchain.db) { + if blocks[len(blocks)-1].Hash() != rawdb.ReadHeadBlockHash(blockchain.db) { t.Fatalf("Write/Get HeadBlockHash failed") } } @@ -551,16 +586,16 @@ func testInsertNonceError(t *testing.T, full bool) { func TestFastVsFullChains(t *testing.T) { // Configure and generate a sample block chain var ( - gendb, _ = ethdb.NewMemDatabase() - key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") - address = crypto.PubkeyToAddress(key.PublicKey) - funds = big.NewInt(1000000000) - gspec = &Genesis{ + gendb = ethdb.NewMemDatabase() + key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") + address = crypto.PubkeyToAddress(key.PublicKey) + funds = big.NewInt(1000000000) + gspec = &Genesis{ Config: params.TestChainConfig, Alloc: GenesisAlloc{address: {Balance: funds}}, } genesis = gspec.MustCommit(gendb) - signer = types.NewEIP155Signer(gspec.Config.ChainId) + signer = types.NewEIP155Signer(gspec.Config.ChainID) ) blocks, receipts := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), gendb, 1024, func(i int, block *BlockGen) { block.SetCoinbase(common.Address{0x00}) @@ -581,7 +616,7 @@ func TestFastVsFullChains(t *testing.T) { } }) // Import the chain as an archive node for the comparison baseline - archiveDb, _ := ethdb.NewMemDatabase() + archiveDb := ethdb.NewMemDatabase() gspec.MustCommit(archiveDb) archive, _ := NewBlockChain(archiveDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}) defer archive.Stop() @@ -590,7 +625,7 @@ func TestFastVsFullChains(t *testing.T) { t.Fatalf("failed to process block %d: %v", n, err) } // Fast import the chain as a non-archive node to test - fastDb, _ := ethdb.NewMemDatabase() + fastDb := ethdb.NewMemDatabase() gspec.MustCommit(fastDb) fast, _ := NewBlockChain(fastDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}) defer fast.Stop() @@ -622,13 +657,13 @@ func TestFastVsFullChains(t *testing.T) { } else if types.CalcUncleHash(fblock.Uncles()) != types.CalcUncleHash(ablock.Uncles()) { t.Errorf("block #%d [%x]: uncles mismatch: have %v, want %v", num, hash, fblock.Uncles(), ablock.Uncles()) } - if freceipts, areceipts := GetBlockReceipts(fastDb, hash, GetBlockNumber(fastDb, hash)), GetBlockReceipts(archiveDb, hash, GetBlockNumber(archiveDb, hash)); types.DeriveSha(freceipts) != types.DeriveSha(areceipts) { + if freceipts, areceipts := rawdb.ReadReceipts(fastDb, hash, *rawdb.ReadHeaderNumber(fastDb, hash)), rawdb.ReadReceipts(archiveDb, hash, *rawdb.ReadHeaderNumber(archiveDb, hash)); types.DeriveSha(freceipts) != types.DeriveSha(areceipts) { t.Errorf("block #%d [%x]: receipts mismatch: have %v, want %v", num, hash, freceipts, areceipts) } } // Check that the canonical chains are the same between the databases for i := 0; i < len(blocks)+1; i++ { - if fhash, ahash := GetCanonicalHash(fastDb, uint64(i)), GetCanonicalHash(archiveDb, uint64(i)); fhash != ahash { + if fhash, ahash := rawdb.ReadCanonicalHash(fastDb, uint64(i)), rawdb.ReadCanonicalHash(archiveDb, uint64(i)); fhash != ahash { t.Errorf("block #%d: canonical hash mismatch: have %v, want %v", i, fhash, ahash) } } @@ -639,12 +674,12 @@ func TestFastVsFullChains(t *testing.T) { func TestLightVsFastVsFullChainHeads(t *testing.T) { // Configure and generate a sample block chain var ( - gendb, _ = ethdb.NewMemDatabase() - key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") - address = crypto.PubkeyToAddress(key.PublicKey) - funds = big.NewInt(1000000000) - gspec = &Genesis{Config: params.TestChainConfig, Alloc: GenesisAlloc{address: {Balance: funds}}} - genesis = gspec.MustCommit(gendb) + gendb = ethdb.NewMemDatabase() + key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") + address = crypto.PubkeyToAddress(key.PublicKey) + funds = big.NewInt(1000000000) + gspec = &Genesis{Config: params.TestChainConfig, Alloc: GenesisAlloc{address: {Balance: funds}}} + genesis = gspec.MustCommit(gendb) ) height := uint64(1024) blocks, receipts := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), gendb, int(height), nil) @@ -667,7 +702,7 @@ func TestLightVsFastVsFullChainHeads(t *testing.T) { } } // Import the chain as an archive node and ensure all pointers are updated - archiveDb, _ := ethdb.NewMemDatabase() + archiveDb := ethdb.NewMemDatabase() gspec.MustCommit(archiveDb) archive, _ := NewBlockChain(archiveDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}) @@ -681,7 +716,7 @@ func TestLightVsFastVsFullChainHeads(t *testing.T) { assert(t, "archive", archive, height/2, height/2, height/2) // Import the chain as a non-archive node and ensure all pointers are updated - fastDb, _ := ethdb.NewMemDatabase() + fastDb := ethdb.NewMemDatabase() gspec.MustCommit(fastDb) fast, _ := NewBlockChain(fastDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}) defer fast.Stop() @@ -701,7 +736,7 @@ func TestLightVsFastVsFullChainHeads(t *testing.T) { assert(t, "fast", fast, height/2, height/2, 0) // Import the chain as a light node and ensure all pointers are updated - lightDb, _ := ethdb.NewMemDatabase() + lightDb := ethdb.NewMemDatabase() gspec.MustCommit(lightDb) light, _ := NewBlockChain(lightDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}) @@ -724,7 +759,7 @@ func TestChainTxReorgs(t *testing.T) { addr1 = crypto.PubkeyToAddress(key1.PublicKey) addr2 = crypto.PubkeyToAddress(key2.PublicKey) addr3 = crypto.PubkeyToAddress(key3.PublicKey) - db, _ = ethdb.NewMemDatabase() + db = ethdb.NewMemDatabase() gspec = &Genesis{ Config: params.TestChainConfig, GasLimit: 3141592, @@ -735,7 +770,7 @@ func TestChainTxReorgs(t *testing.T) { }, } genesis = gspec.MustCommit(db) - signer = types.NewEIP155Signer(gspec.Config.ChainId) + signer = types.NewEIP155Signer(gspec.Config.ChainID) ) // Create two transactions shared between the chains: @@ -804,28 +839,28 @@ func TestChainTxReorgs(t *testing.T) { // removed tx for i, tx := range (types.Transactions{pastDrop, freshDrop}) { - if txn, _, _, _ := GetTransaction(db, tx.Hash()); txn != nil { + if txn, _, _, _ := rawdb.ReadTransaction(db, tx.Hash()); txn != nil { t.Errorf("drop %d: tx %v found while shouldn't have been", i, txn) } - if rcpt, _, _, _ := GetReceipt(db, tx.Hash()); rcpt != nil { + if rcpt, _, _, _ := rawdb.ReadReceipt(db, tx.Hash()); rcpt != nil { t.Errorf("drop %d: receipt %v found while shouldn't have been", i, rcpt) } } // added tx for i, tx := range (types.Transactions{pastAdd, freshAdd, futureAdd}) { - if txn, _, _, _ := GetTransaction(db, tx.Hash()); txn == nil { + if txn, _, _, _ := rawdb.ReadTransaction(db, tx.Hash()); txn == nil { t.Errorf("add %d: expected tx to be found", i) } - if rcpt, _, _, _ := GetReceipt(db, tx.Hash()); rcpt == nil { + if rcpt, _, _, _ := rawdb.ReadReceipt(db, tx.Hash()); rcpt == nil { t.Errorf("add %d: expected receipt to be found", i) } } // shared tx for i, tx := range (types.Transactions{postponed, swapped}) { - if txn, _, _, _ := GetTransaction(db, tx.Hash()); txn == nil { + if txn, _, _, _ := rawdb.ReadTransaction(db, tx.Hash()); txn == nil { t.Errorf("share %d: expected tx to be found", i) } - if rcpt, _, _, _ := GetReceipt(db, tx.Hash()); rcpt == nil { + if rcpt, _, _, _ := rawdb.ReadReceipt(db, tx.Hash()); rcpt == nil { t.Errorf("share %d: expected receipt to be found", i) } } @@ -836,12 +871,12 @@ func TestLogReorgs(t *testing.T) { var ( key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") addr1 = crypto.PubkeyToAddress(key1.PublicKey) - db, _ = ethdb.NewMemDatabase() + db = ethdb.NewMemDatabase() // this code generates a log code = common.Hex2Bytes("60606040525b7f24ec1d3ff24c2f6ff210738839dbc339cd45a5294d85c79361016243157aae7b60405180905060405180910390a15b600a8060416000396000f360606040526008565b00") gspec = &Genesis{Config: params.TestChainConfig, Alloc: GenesisAlloc{addr1: {Balance: big.NewInt(10000000000000)}}} genesis = gspec.MustCommit(db) - signer = types.NewEIP155Signer(gspec.Config.ChainId) + signer = types.NewEIP155Signer(gspec.Config.ChainID) ) blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}) @@ -878,88 +913,88 @@ func TestLogReorgs(t *testing.T) { } } -//func TestReorgSideEvent(t *testing.T) { -// var ( -// db, _ = ethdb.NewMemDatabase() -// key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") -// addr1 = crypto.PubkeyToAddress(key1.PublicKey) -// gspec = &Genesis{ -// Config: params.TestChainConfig, -// Alloc: GenesisAlloc{addr1: {Balance: big.NewInt(10000000000000)}}, -// } -// genesis = gspec.MustCommit(db) -// signer = types.NewEIP155Signer(gspec.Config.ChainId) -// ) -// -// blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}) -// defer blockchain.Stop() -// -// chain, _ := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 3, func(i int, gen *BlockGen) {}) -// if _, err := blockchain.InsertChain(chain); err != nil { -// t.Fatalf("failed to insert chain: %v", err) -// } -// -// replacementBlocks, _ := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 4, func(i int, gen *BlockGen) { -// tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), 1000000, new(big.Int), nil), signer, key1) -// if i == 2 { -// gen.OffsetTime(-9) -// } -// if err != nil { -// t.Fatalf("failed to create tx: %v", err) -// } -// gen.AddTx(tx) -// }) -// chainSideCh := make(chan ChainSideEvent, 64) -// blockchain.SubscribeChainSideEvent(chainSideCh) -// if _, err := blockchain.InsertChain(replacementBlocks); err != nil { -// t.Fatalf("failed to insert chain: %v", err) -// } -// -// // first two block of the secondary chain are for a brief moment considered -// // side chains because up to that point the first one is considered the -// // heavier chain. -// expectedSideHashes := map[common.Hash]bool{ -// replacementBlocks[0].Hash(): true, -// replacementBlocks[1].Hash(): true, -// chain[0].Hash(): true, -// chain[1].Hash(): true, -// chain[2].Hash(): true, -// } -// -// i := 0 -// -// const timeoutDura = 10 * time.Second -// timeout := time.NewTimer(timeoutDura) -//done: -// for { -// select { -// case ev := <-chainSideCh: -// block := ev.Block -// if _, ok := expectedSideHashes[block.Hash()]; !ok { -// t.Errorf("%d: didn't expect %x to be in side chain", i, block.Hash()) -// } -// i++ -// -// if i == len(expectedSideHashes) { -// timeout.Stop() -// -// break done -// } -// timeout.Reset(timeoutDura) -// -// case <-timeout.C: -// t.Fatal("Timeout. Possibly not all blocks were triggered for sideevent") -// } -// } -// -// // make sure no more events are fired -// select { -// case e := <-chainSideCh: -// t.Errorf("unexpected event fired: %v", e) -// case <-time.After(250 * time.Millisecond): -// } -// -//} +func TestReorgSideEvent(t *testing.T) { + var ( + db = ethdb.NewMemDatabase() + key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") + addr1 = crypto.PubkeyToAddress(key1.PublicKey) + gspec = &Genesis{ + Config: params.TestChainConfig, + Alloc: GenesisAlloc{addr1: {Balance: big.NewInt(10000000000000)}}, + } + genesis = gspec.MustCommit(db) + signer = types.NewEIP155Signer(gspec.Config.ChainID) + ) + + blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}) + defer blockchain.Stop() + + chain, _ := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 3, func(i int, gen *BlockGen) {}) + if _, err := blockchain.InsertChain(chain); err != nil { + t.Fatalf("failed to insert chain: %v", err) + } + + replacementBlocks, _ := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 4, func(i int, gen *BlockGen) { + tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), 1000000, new(big.Int), nil), signer, key1) + if i == 2 { + gen.OffsetTime(-9) + } + if err != nil { + t.Fatalf("failed to create tx: %v", err) + } + gen.AddTx(tx) + }) + chainSideCh := make(chan ChainSideEvent, 64) + blockchain.SubscribeChainSideEvent(chainSideCh) + if _, err := blockchain.InsertChain(replacementBlocks); err != nil { + t.Fatalf("failed to insert chain: %v", err) + } + + // first two block of the secondary chain are for a brief moment considered + // side chains because up to that point the first one is considered the + // heavier chain. + expectedSideHashes := map[common.Hash]bool{ + replacementBlocks[0].Hash(): true, + replacementBlocks[1].Hash(): true, + chain[0].Hash(): true, + chain[1].Hash(): true, + chain[2].Hash(): true, + } + + i := 0 + + const timeoutDura = 10 * time.Second + timeout := time.NewTimer(timeoutDura) +done: + for { + select { + case ev := <-chainSideCh: + block := ev.Block + if _, ok := expectedSideHashes[block.Hash()]; !ok { + t.Errorf("%d: didn't expect %x to be in side chain", i, block.Hash()) + } + i++ + + if i == len(expectedSideHashes) { + timeout.Stop() + + break done + } + timeout.Reset(timeoutDura) + + case <-timeout.C: + t.Fatal("Timeout. Possibly not all blocks were triggered for sideevent") + } + } + + // make sure no more events are fired + select { + case e := <-chainSideCh: + t.Errorf("unexpected event fired: %v", e) + case <-time.After(250 * time.Millisecond): + } + +} // Tests if the canonical block can be fetched from the database during chain insertion. func TestCanonicalBlockRetrieval(t *testing.T) { @@ -980,14 +1015,14 @@ func TestCanonicalBlockRetrieval(t *testing.T) { // try to retrieve a block by its canonical hash and see if the block data can be retrieved. for { - ch := GetCanonicalHash(blockchain.db, block.NumberU64()) + ch := rawdb.ReadCanonicalHash(blockchain.db, block.NumberU64()) if ch == (common.Hash{}) { continue // busy wait for canonical hash to be written } if ch != block.Hash() { t.Fatalf("unknown canonical hash, want %s, got %s", block.Hash().Hex(), ch.Hex()) } - fb := GetBlock(blockchain.db, ch, block.NumberU64()) + fb := rawdb.ReadBlock(blockchain.db, ch, block.NumberU64()) if fb == nil { t.Fatalf("unable to retrieve block %d for canonical hash: %s", block.NumberU64(), ch.Hex()) } @@ -1008,13 +1043,13 @@ func TestCanonicalBlockRetrieval(t *testing.T) { func TestEIP155Transition(t *testing.T) { // Configure and generate a sample block chain var ( - db, _ = ethdb.NewMemDatabase() + db = ethdb.NewMemDatabase() key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") address = crypto.PubkeyToAddress(key.PublicKey) funds = big.NewInt(1000000000) deleteAddr = common.Address{1} gspec = &Genesis{ - Config: ¶ms.ChainConfig{ChainId: big.NewInt(1), EIP155Block: big.NewInt(2), HomesteadBlock: new(big.Int)}, + Config: ¶ms.ChainConfig{ChainID: big.NewInt(1), EIP155Block: big.NewInt(2), HomesteadBlock: new(big.Int)}, Alloc: GenesisAlloc{address: {Balance: funds}, deleteAddr: {Balance: new(big.Int)}}, } genesis = gspec.MustCommit(db) @@ -1045,7 +1080,7 @@ func TestEIP155Transition(t *testing.T) { } block.AddTx(tx) - tx, err = basicTx(types.NewEIP155Signer(gspec.Config.ChainId)) + tx, err = basicTx(types.NewEIP155Signer(gspec.Config.ChainID)) if err != nil { t.Fatal(err) } @@ -1057,7 +1092,7 @@ func TestEIP155Transition(t *testing.T) { } block.AddTx(tx) - tx, err = basicTx(types.NewEIP155Signer(gspec.Config.ChainId)) + tx, err = basicTx(types.NewEIP155Signer(gspec.Config.ChainID)) if err != nil { t.Fatal(err) } @@ -1085,7 +1120,7 @@ func TestEIP155Transition(t *testing.T) { } // generate an invalid chain id transaction - config := ¶ms.ChainConfig{ChainId: big.NewInt(2), EIP155Block: big.NewInt(2), HomesteadBlock: new(big.Int)} + config := ¶ms.ChainConfig{ChainID: big.NewInt(2), EIP155Block: big.NewInt(2), HomesteadBlock: new(big.Int)} blocks, _ = GenerateChain(config, blocks[len(blocks)-1], ethash.NewFaker(), db, 4, func(i int, block *BlockGen) { var ( tx *types.Transaction @@ -1094,8 +1129,7 @@ func TestEIP155Transition(t *testing.T) { return types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{}, new(big.Int), 21000, new(big.Int), nil), signer, key) } ) - switch i { - case 0: + if i == 0 { tx, err = basicTx(types.NewEIP155Signer(big.NewInt(2))) if err != nil { t.Fatal(err) @@ -1112,14 +1146,14 @@ func TestEIP155Transition(t *testing.T) { func TestEIP161AccountRemoval(t *testing.T) { // Configure and generate a sample block chain var ( - db, _ = ethdb.NewMemDatabase() + db = ethdb.NewMemDatabase() key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") address = crypto.PubkeyToAddress(key.PublicKey) funds = big.NewInt(1000000000) theAddr = common.Address{1} gspec = &Genesis{ Config: ¶ms.ChainConfig{ - ChainId: big.NewInt(1), + ChainID: big.NewInt(1), HomesteadBlock: new(big.Int), EIP155Block: new(big.Int), EIP158Block: big.NewInt(2), @@ -1135,7 +1169,7 @@ func TestEIP161AccountRemoval(t *testing.T) { var ( tx *types.Transaction err error - signer = types.NewEIP155Signer(gspec.Config.ChainId) + signer = types.NewEIP155Signer(gspec.Config.ChainID) ) switch i { case 0: @@ -1184,7 +1218,7 @@ func TestBlockchainHeaderchainReorgConsistency(t *testing.T) { // Generate a canonical chain to act as the main dataset engine := ethash.NewFaker() - db, _ := ethdb.NewMemDatabase() + db := ethdb.NewMemDatabase() genesis := new(Genesis).MustCommit(db) blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 64, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) }) @@ -1200,7 +1234,7 @@ func TestBlockchainHeaderchainReorgConsistency(t *testing.T) { } // Import the canonical and fork chain side by side, verifying the current block // and current header consistency - diskdb, _ := ethdb.NewMemDatabase() + diskdb := ethdb.NewMemDatabase() new(Genesis).MustCommit(diskdb) chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}) @@ -1229,7 +1263,7 @@ func TestTrieForkGC(t *testing.T) { // Generate a canonical chain to act as the main dataset engine := ethash.NewFaker() - db, _ := ethdb.NewMemDatabase() + db := ethdb.NewMemDatabase() genesis := new(Genesis).MustCommit(db) blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 2*triesInMemory, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) }) @@ -1244,7 +1278,7 @@ func TestTrieForkGC(t *testing.T) { forks[i] = fork[0] } // Import the canonical and fork chain side by side, forcing the trie cache to cache both - diskdb, _ := ethdb.NewMemDatabase() + diskdb := ethdb.NewMemDatabase() new(Genesis).MustCommit(diskdb) chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}) @@ -1261,8 +1295,8 @@ func TestTrieForkGC(t *testing.T) { } // Dereference all the recent tries and ensure no past trie is left in for i := 0; i < triesInMemory; i++ { - chain.stateCache.TrieDB().Dereference(blocks[len(blocks)-1-i].Root(), common.Hash{}) - chain.stateCache.TrieDB().Dereference(forks[len(blocks)-1-i].Root(), common.Hash{}) + chain.stateCache.TrieDB().Dereference(blocks[len(blocks)-1-i].Root()) + chain.stateCache.TrieDB().Dereference(forks[len(blocks)-1-i].Root()) } if len(chain.stateCache.TrieDB().Nodes()) > 0 { t.Fatalf("stale tries still alive after garbase collection") @@ -1275,7 +1309,7 @@ func TestLargeReorgTrieGC(t *testing.T) { // Generate the original common chain segment and the two competing forks engine := ethash.NewFaker() - db, _ := ethdb.NewMemDatabase() + db := ethdb.NewMemDatabase() genesis := new(Genesis).MustCommit(db) shared, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 64, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) }) @@ -1283,7 +1317,7 @@ func TestLargeReorgTrieGC(t *testing.T) { competitor, _ := GenerateChain(params.TestChainConfig, shared[len(shared)-1], engine, db, 2*triesInMemory+1, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{3}) }) // Import the shared chain and the original canonical one - diskdb, _ := ethdb.NewMemDatabase() + diskdb := ethdb.NewMemDatabase() new(Genesis).MustCommit(diskdb) chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}) @@ -1321,3 +1355,114 @@ func TestLargeReorgTrieGC(t *testing.T) { } } } + +// 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) { + var ( + signer = types.HomesteadSigner{} + testBankKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") + testBankAddress = crypto.PubkeyToAddress(testBankKey.PublicKey) + bankFunds = big.NewInt(100000000000000000) + gspec = Genesis{ + Config: params.TestChainConfig, + Alloc: GenesisAlloc{ + testBankAddress: {Balance: bankFunds}, + common.HexToAddress("0xc0de"): { + Code: []byte{0x60, 0x01, 0x50}, + Balance: big.NewInt(0), + }, // push 1, pop + }, + GasLimit: 100e6, // 100 M + } + ) + // Generate the original common chain segment and the two competing forks + engine := ethash.NewFaker() + db := ethdb.NewMemDatabase() + genesis := gspec.MustCommit(db) + + blockGenerator := func(i int, block *BlockGen) { + block.SetCoinbase(common.Address{1}) + for txi := 0; txi < numTxs; txi++ { + uniq := uint64(i*numTxs + txi) + recipient := recipientFn(uniq) + //recipient := common.BigToAddress(big.NewInt(0).SetUint64(1337 + uniq)) + tx, err := types.SignTx(types.NewTransaction(uniq, recipient, big.NewInt(1), params.TxGas, big.NewInt(1), nil), signer, testBankKey) + if err != nil { + b.Error(err) + } + block.AddTx(tx) + } + } + + shared, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, numBlocks, blockGenerator) + b.StopTimer() + b.ResetTimer() + for i := 0; i < b.N; i++ { + // Import the shared chain and the original canonical one + diskdb := ethdb.NewMemDatabase() + gspec.MustCommit(diskdb) + + chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}) + if err != nil { + b.Fatalf("failed to create tester chain: %v", err) + } + b.StartTimer() + if _, err := chain.InsertChain(shared); err != nil { + b.Fatalf("failed to insert shared chain: %v", err) + } + b.StopTimer() + if got := chain.CurrentBlock().Transactions().Len(); got != numTxs*numBlocks { + b.Fatalf("Transactions were not included, expected %d, got %d", (numTxs * numBlocks), got) + + } + } +} +func BenchmarkBlockChain_1x1000ValueTransferToNonexisting(b *testing.B) { + var ( + numTxs = 1000 + numBlocks = 1 + ) + + recipientFn := func(nonce uint64) common.Address { + return common.BigToAddress(big.NewInt(0).SetUint64(1337 + nonce)) + } + dataFn := func(nonce uint64) []byte { + return nil + } + + benchmarkLargeNumberOfValueToNonexisting(b, numTxs, numBlocks, recipientFn, dataFn) +} +func BenchmarkBlockChain_1x1000ValueTransferToExisting(b *testing.B) { + var ( + numTxs = 1000 + numBlocks = 1 + ) + b.StopTimer() + b.ResetTimer() + + recipientFn := func(nonce uint64) common.Address { + return common.BigToAddress(big.NewInt(0).SetUint64(1337)) + } + dataFn := func(nonce uint64) []byte { + return nil + } + + benchmarkLargeNumberOfValueToNonexisting(b, numTxs, numBlocks, recipientFn, dataFn) +} +func BenchmarkBlockChain_1x1000Executions(b *testing.B) { + var ( + numTxs = 1000 + numBlocks = 1 + ) + b.StopTimer() + b.ResetTimer() + + recipientFn := func(nonce uint64) common.Address { + return common.BigToAddress(big.NewInt(0).SetUint64(0xc0de)) + } + dataFn := func(nonce uint64) []byte { + return nil + } + + benchmarkLargeNumberOfValueToNonexisting(b, numTxs, numBlocks, recipientFn, dataFn) +} diff --git a/core/bloombits/generator.go b/core/bloombits/generator.go index 540085450d..ae07481ada 100644 --- a/core/bloombits/generator.go +++ b/core/bloombits/generator.go @@ -22,16 +22,22 @@ import ( "github.com/ethereum/go-ethereum/core/types" ) -// 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, -var errSectionOutOfBounds = errors.New("section out of bounds") +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 - nextBit uint // Next bit to set when adding a bloom + nextSec uint // Next section to set when adding a bloom } // NewGenerator creates a rotated bloom generator that can iteratively fill a @@ -51,15 +57,15 @@ func NewGenerator(sections uint) (*Generator, error) { // 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.nextBit >= b.sections { + if b.nextSec >= b.sections { return errSectionOutOfBounds } - if b.nextBit != index { + if b.nextSec != index { return errors.New("bloom filter with unexpected index") } // Rotate the bloom and insert into our collection - byteIndex := b.nextBit / 8 - bitMask := byte(1) << byte(7-b.nextBit%8) + byteIndex := b.nextSec / 8 + bitMask := byte(1) << byte(7-b.nextSec%8) for i := 0; i < types.BloomBitLength; i++ { bloomByteIndex := types.BloomByteLength - 1 - i/8 @@ -69,7 +75,7 @@ func (b *Generator) AddBloom(index uint, bloom types.Bloom) error { b.blooms[i][byteIndex] |= bitMask } } - b.nextBit++ + b.nextSec++ return nil } @@ -77,11 +83,11 @@ func (b *Generator) AddBloom(index uint, bloom types.Bloom) error { // 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.nextBit != b.sections { + if b.nextSec != b.sections { return nil, errors.New("bloom not fully generated yet") } - if idx >= b.sections { - return nil, errSectionOutOfBounds + if idx >= types.BloomBitLength { + return nil, errBloomBitOutOfBounds } return b.blooms[idx], nil } diff --git a/core/bloombits/matcher.go b/core/bloombits/matcher.go index ce3031702f..3ec0d5ae94 100644 --- a/core/bloombits/matcher.go +++ b/core/bloombits/matcher.go @@ -59,7 +59,7 @@ type partialMatches struct { // It can also have the actual results set to be used as a delivery data struct. // // The contest and error fields are used by the light client to terminate matching -// early if an error is enountered on some path of the pipeline. +// early if an error is encountered on some path of the pipeline. type Retrieval struct { Bit uint Sections []uint64 @@ -218,7 +218,7 @@ func (m *Matcher) Start(ctx context.Context, begin, end uint64, results chan uin // run creates a daisy-chain of sub-matchers, one for the address set and one // for each topic set, each sub-matcher receiving a section only if the previous // ones have all found a potential match in one of the blocks of the section, -// then binary AND-ing its own matches and forwaring the result to the next one. +// then binary AND-ing its own matches and forwarding the result to the next one. // // The method starts feeding the section indexes into the first sub-matcher on a // new goroutine and returns a sink channel receiving the results. @@ -392,7 +392,7 @@ func (m *Matcher) distributor(dist chan *request, session *MatcherSession) { shutdown = session.quit // Shutdown request channel, will gracefully wait for pending requests ) - // assign is a helper method fo try to assign a pending bit an an actively + // assign is a helper method fo try to assign a pending bit an actively // listening servicer, or schedule it up for later when one arrives. assign := func(bit uint) { select { @@ -543,7 +543,7 @@ func (s *MatcherSession) Error() error { } // AllocateRetrieval assigns a bloom bit index to a client process that can either -// immediately reuest and fetch the section contents assigned to this bit or wait +// 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) @@ -599,8 +599,8 @@ func (s *MatcherSession) DeliverSections(bit uint, sections []uint64, bitsets [] } } -// Multiplex polls the matcher session for rerieval tasks and multiplexes it into -// the reuested retrieval queue to be serviced together with other sessions. +// 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 diff --git a/core/bloombits/matcher_test.go b/core/bloombits/matcher_test.go index 7a5f78ef3a..91143e525e 100644 --- a/core/bloombits/matcher_test.go +++ b/core/bloombits/matcher_test.go @@ -156,7 +156,7 @@ func testMatcher(t *testing.T, filter [][]bloomIndexes, start, blocks uint64, in // Track the number of retrieval requests made var requested uint32 - // Start the matching session for the filter and the retriver goroutines + // Start the matching session for the filter and the retriever goroutines quit := make(chan struct{}) matches := make(chan uint64, 16) diff --git a/core/chain_indexer.go b/core/chain_indexer.go index 158ed83245..0b927116d0 100644 --- a/core/chain_indexer.go +++ b/core/chain_indexer.go @@ -24,6 +24,7 @@ import ( "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" @@ -206,7 +207,7 @@ func (c *ChainIndexer) eventLoop(currentHeader *types.Header, events chan ChainE // TODO(karalabe): This operation is expensive and might block, causing the event system to // potentially also lock up. We need to do with on a different thread somehow. - if h := FindCommonAncestor(c.chainDb, prevHeader, header); h != nil { + if h := rawdb.FindCommonAncestor(c.chainDb, prevHeader, header); h != nil { c.newHead(h.Number.Uint64(), true) } } @@ -349,11 +350,11 @@ func (c *ChainIndexer) processSection(section uint64, lastHead common.Hash) (com } for number := section * c.sectionSize; number < (section+1)*c.sectionSize; number++ { - hash := GetCanonicalHash(c.chainDb, number) + hash := rawdb.ReadCanonicalHash(c.chainDb, number) if hash == (common.Hash{}) { return common.Hash{}, fmt.Errorf("canonical block #%d unknown", number) } - header := GetHeader(c.chainDb, hash, 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 { diff --git a/core/chain_indexer_test.go b/core/chain_indexer_test.go index 9fc09eda51..550caf5567 100644 --- a/core/chain_indexer_test.go +++ b/core/chain_indexer_test.go @@ -24,6 +24,7 @@ import ( "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" ) @@ -47,7 +48,7 @@ func TestChainIndexerWithChildren(t *testing.T) { // multiple backends. The section size and required confirmation count parameters // are randomized. func testChainIndexer(t *testing.T, count int) { - db, _ := ethdb.NewMemDatabase() + db := ethdb.NewMemDatabase() defer db.Close() // Create a chain of indexers and ensure they all report empty @@ -92,10 +93,10 @@ func testChainIndexer(t *testing.T, count int) { inject := func(number uint64) { header := &types.Header{Number: big.NewInt(int64(number)), Extra: big.NewInt(rand.Int63()).Bytes()} if number > 0 { - header.ParentHash = GetCanonicalHash(db, number-1) + header.ParentHash = rawdb.ReadCanonicalHash(db, number-1) } - WriteHeader(db, header) - WriteCanonicalHash(db, header.Hash(), number) + rawdb.WriteHeader(db, header) + rawdb.WriteCanonicalHash(db, header.Hash(), number) } // Start indexer with an already existing chain for i := uint64(0); i <= 100; i++ { diff --git a/core/chain_makers.go b/core/chain_makers.go index 369e6b01ec..5286e9ddcc 100644 --- a/core/chain_makers.go +++ b/core/chain_makers.go @@ -30,12 +30,6 @@ import ( "github.com/ethereum/go-ethereum/params" ) -// So we can deterministically seed different blockchains -var ( - canonicalSeed = 1 - forkSeed = 2 -) - // BlockGen creates blocks for testing. // See GenerateChain for a detailed explanation. type BlockGen struct { @@ -252,32 +246,6 @@ func makeHeader(chain consensus.ChainReader, parent *types.Block, state *state.S } } -// newCanonical creates a chain database, and injects a deterministic canonical -// chain. Depending on the full flag, if creates either a full block chain or a -// header only chain. -func newCanonical(engine consensus.Engine, n int, full bool) (ethdb.Database, *BlockChain, error) { - // Initialize a fresh chain with only a genesis block - gspec := new(Genesis) - db, _ := ethdb.NewMemDatabase() - genesis := gspec.MustCommit(db) - - blockchain, _ := NewBlockChain(db, nil, params.AllEthashProtocolChanges, engine, vm.Config{}) - // Create and inject the requested chain - if n == 0 { - return db, blockchain, nil - } - if full { - // Full block-chain requested - blocks := makeBlockChain(genesis, n, engine, db, canonicalSeed) - _, err := blockchain.InsertChain(blocks) - return db, blockchain, err - } - // Header-only chain requested - headers := makeHeaderChain(genesis.Header(), n, engine, db, canonicalSeed) - _, err := blockchain.InsertHeaderChain(headers, 1) - return db, blockchain, err -} - // makeHeaderChain creates a deterministic chain of headers rooted at parent. func makeHeaderChain(parent *types.Header, n int, engine consensus.Engine, db ethdb.Database, seed int) []*types.Header { blocks := makeBlockChain(types.NewBlockWithHeader(parent), n, engine, db, seed) diff --git a/core/chain_makers_test.go b/core/chain_makers_test.go index 93be43ddce..5015d1f48e 100644 --- a/core/chain_makers_test.go +++ b/core/chain_makers_test.go @@ -36,7 +36,7 @@ func ExampleGenerateChain() { addr1 = crypto.PubkeyToAddress(key1.PublicKey) addr2 = crypto.PubkeyToAddress(key2.PublicKey) addr3 = crypto.PubkeyToAddress(key3.PublicKey) - db, _ = ethdb.NewMemDatabase() + db = ethdb.NewMemDatabase() ) // Ensure that key1 has some funds in the genesis block. diff --git a/core/dao_test.go b/core/dao_test.go index e0a3e3ff37..284b1d98bd 100644 --- a/core/dao_test.go +++ b/core/dao_test.go @@ -32,13 +32,13 @@ func TestDAOForkRangeExtradata(t *testing.T) { forkBlock := big.NewInt(32) // Generate a common prefix for both pro-forkers and non-forkers - db, _ := ethdb.NewMemDatabase() + db := ethdb.NewMemDatabase() gspec := new(Genesis) genesis := gspec.MustCommit(db) prefix, _ := GenerateChain(params.TestChainConfig, genesis, ethash.NewFaker(), db, int(forkBlock.Int64()-1), func(i int, gen *BlockGen) {}) // Create the concurrent, conflicting two nodes - proDb, _ := ethdb.NewMemDatabase() + proDb := ethdb.NewMemDatabase() gspec.MustCommit(proDb) proConf := *params.TestChainConfig @@ -48,7 +48,7 @@ func TestDAOForkRangeExtradata(t *testing.T) { proBc, _ := NewBlockChain(proDb, nil, &proConf, ethash.NewFaker(), vm.Config{}) defer proBc.Stop() - conDb, _ := ethdb.NewMemDatabase() + conDb := ethdb.NewMemDatabase() gspec.MustCommit(conDb) conConf := *params.TestChainConfig @@ -67,7 +67,7 @@ func TestDAOForkRangeExtradata(t *testing.T) { // Try to expand both pro-fork and non-fork chains iteratively with other camp's blocks for i := int64(0); i < params.DAOForkExtraRange.Int64(); i++ { // Create a pro-fork block, and try to feed into the no-fork chain - db, _ = ethdb.NewMemDatabase() + db = ethdb.NewMemDatabase() gspec.MustCommit(db) bc, _ := NewBlockChain(db, nil, &conConf, ethash.NewFaker(), vm.Config{}) defer bc.Stop() @@ -92,7 +92,7 @@ func TestDAOForkRangeExtradata(t *testing.T) { t.Fatalf("contra-fork chain didn't accepted no-fork block: %v", err) } // Create a no-fork block, and try to feed into the pro-fork chain - db, _ = ethdb.NewMemDatabase() + db = ethdb.NewMemDatabase() gspec.MustCommit(db) bc, _ = NewBlockChain(db, nil, &proConf, ethash.NewFaker(), vm.Config{}) defer bc.Stop() @@ -118,7 +118,7 @@ func TestDAOForkRangeExtradata(t *testing.T) { } } // Verify that contra-forkers accept pro-fork extra-datas after forking finishes - db, _ = ethdb.NewMemDatabase() + db = ethdb.NewMemDatabase() gspec.MustCommit(db) bc, _ := NewBlockChain(db, nil, &conConf, ethash.NewFaker(), vm.Config{}) defer bc.Stop() @@ -138,7 +138,7 @@ func TestDAOForkRangeExtradata(t *testing.T) { t.Fatalf("contra-fork chain didn't accept pro-fork block post-fork: %v", err) } // Verify that pro-forkers accept contra-fork extra-datas after forking finishes - db, _ = ethdb.NewMemDatabase() + db = ethdb.NewMemDatabase() gspec.MustCommit(db) bc, _ = NewBlockChain(db, nil, &proConf, ethash.NewFaker(), vm.Config{}) defer bc.Stop() diff --git a/core/database_util.go b/core/database_util.go deleted file mode 100644 index 8c46989854..0000000000 --- a/core/database_util.go +++ /dev/null @@ -1,652 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package core - -import ( - "bytes" - "encoding/binary" - "encoding/json" - "errors" - "fmt" - "math/big" - - "github.com/ethereum/go-ethereum/common" - "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" - "github.com/ethereum/go-ethereum/params" - "github.com/ethereum/go-ethereum/rlp" -) - -// DatabaseReader wraps the Get method of a backing data store. -type DatabaseReader interface { - Get(key []byte) (value []byte, err error) -} - -// DatabaseDeleter wraps the Delete method of a backing data store. -type DatabaseDeleter interface { - Delete(key []byte) error -} - -var ( - headHeaderKey = []byte("LastHeader") - headBlockKey = []byte("LastBlock") - headFastKey = []byte("LastFast") - trieSyncKey = []byte("TrieSync") - - // Data item prefixes (use single byte to avoid mixing data types, avoid `i`). - headerPrefix = []byte("h") // headerPrefix + num (uint64 big endian) + hash -> header - tdSuffix = []byte("t") // headerPrefix + num (uint64 big endian) + hash + tdSuffix -> td - numSuffix = []byte("n") // headerPrefix + num (uint64 big endian) + numSuffix -> hash - blockHashPrefix = []byte("H") // blockHashPrefix + hash -> num (uint64 big endian) - bodyPrefix = []byte("b") // bodyPrefix + num (uint64 big endian) + hash -> block body - blockReceiptsPrefix = []byte("r") // blockReceiptsPrefix + num (uint64 big endian) + hash -> block receipts - lookupPrefix = []byte("l") // lookupPrefix + hash -> transaction/receipt lookup metadata - bloomBitsPrefix = []byte("B") // bloomBitsPrefix + bit (uint16 big endian) + section (uint64 big endian) + hash -> bloom bits - - preimagePrefix = "secure-key-" // preimagePrefix + hash -> preimage - configPrefix = []byte("ethereum-config-") // config prefix for the db - - // Chain index prefixes (use `i` + single byte to avoid mixing data types). - BloomBitsIndexPrefix = []byte("iB") // BloomBitsIndexPrefix is the data table of a chain indexer to track its progress - - // used by old db, now only used for conversion - oldReceiptsPrefix = []byte("receipts-") - oldTxMetaSuffix = []byte{0x01} - - ErrChainConfigNotFound = errors.New("ChainConfig not found") // general config not found error - - preimageCounter = metrics.NewRegisteredCounter("db/preimage/total", nil) - preimageHitCounter = metrics.NewRegisteredCounter("db/preimage/hits", nil) -) - -// TxLookupEntry is a positional metadata to help looking up the data content of -// a transaction or receipt given only its hash. -type TxLookupEntry struct { - BlockHash common.Hash - BlockIndex uint64 - Index uint64 -} - -// encodeBlockNumber encodes a block number as big endian uint64 -func encodeBlockNumber(number uint64) []byte { - enc := make([]byte, 8) - binary.BigEndian.PutUint64(enc, number) - return enc -} - -// GetCanonicalHash retrieves a hash assigned to a canonical block number. -func GetCanonicalHash(db DatabaseReader, number uint64) common.Hash { - data, _ := db.Get(append(append(headerPrefix, encodeBlockNumber(number)...), numSuffix...)) - if len(data) == 0 { - return common.Hash{} - } - return common.BytesToHash(data) -} - -// missingNumber is returned by GetBlockNumber if no header with the -// given block hash has been stored in the database -const missingNumber = uint64(0xffffffffffffffff) - -// GetBlockNumber returns the block number assigned to a block hash -// if the corresponding header is present in the database -func GetBlockNumber(db DatabaseReader, hash common.Hash) uint64 { - data, _ := db.Get(append(blockHashPrefix, hash.Bytes()...)) - if len(data) != 8 { - return missingNumber - } - return binary.BigEndian.Uint64(data) -} - -// GetHeadHeaderHash retrieves the hash of the current canonical head block's -// header. The difference between this and GetHeadBlockHash is that whereas the -// last block hash is only updated upon a full block import, the last header -// hash is updated already at header import, allowing head tracking for the -// light synchronization mechanism. -func GetHeadHeaderHash(db DatabaseReader) common.Hash { - data, _ := db.Get(headHeaderKey) - if len(data) == 0 { - return common.Hash{} - } - return common.BytesToHash(data) -} - -// GetHeadBlockHash retrieves the hash of the current canonical head block. -func GetHeadBlockHash(db DatabaseReader) common.Hash { - data, _ := db.Get(headBlockKey) - if len(data) == 0 { - return common.Hash{} - } - return common.BytesToHash(data) -} - -// GetHeadFastBlockHash retrieves the hash of the current canonical head block during -// fast synchronization. The difference between this and GetHeadBlockHash is that -// whereas the last block hash is only updated upon a full block import, the last -// fast hash is updated when importing pre-processed blocks. -func GetHeadFastBlockHash(db DatabaseReader) common.Hash { - data, _ := db.Get(headFastKey) - if len(data) == 0 { - return common.Hash{} - } - return common.BytesToHash(data) -} - -// GetTrieSyncProgress retrieves the number of tries nodes fast synced to allow -// reportinc correct numbers across restarts. -func GetTrieSyncProgress(db DatabaseReader) uint64 { - data, _ := db.Get(trieSyncKey) - if len(data) == 0 { - return 0 - } - return new(big.Int).SetBytes(data).Uint64() -} - -// GetHeaderRLP retrieves a block header in its raw RLP database encoding, or nil -// if the header's not found. -func GetHeaderRLP(db DatabaseReader, hash common.Hash, number uint64) rlp.RawValue { - data, _ := db.Get(headerKey(hash, number)) - return data -} - -// GetHeader retrieves the block header corresponding to the hash, nil if none -// found. -func GetHeader(db DatabaseReader, hash common.Hash, number uint64) *types.Header { - data := GetHeaderRLP(db, hash, number) - if len(data) == 0 { - return nil - } - header := new(types.Header) - if err := rlp.Decode(bytes.NewReader(data), header); err != nil { - log.Error("Invalid block header RLP", "hash", hash, "err", err) - return nil - } - return header -} - -// GetBodyRLP retrieves the block body (transactions and uncles) in RLP encoding. -func GetBodyRLP(db DatabaseReader, hash common.Hash, number uint64) rlp.RawValue { - data, _ := db.Get(blockBodyKey(hash, number)) - return data -} - -func headerKey(hash common.Hash, number uint64) []byte { - return append(append(headerPrefix, encodeBlockNumber(number)...), hash.Bytes()...) -} - -func blockBodyKey(hash common.Hash, number uint64) []byte { - return append(append(bodyPrefix, encodeBlockNumber(number)...), hash.Bytes()...) -} - -// GetBody retrieves the block body (transactons, uncles) corresponding to the -// hash, nil if none found. -func GetBody(db DatabaseReader, hash common.Hash, number uint64) *types.Body { - data := GetBodyRLP(db, hash, number) - if len(data) == 0 { - return nil - } - body := new(types.Body) - if err := rlp.Decode(bytes.NewReader(data), body); err != nil { - log.Error("Invalid block body RLP", "hash", hash, "err", err) - return nil - } - return body -} - -// GetTd retrieves a block's total difficulty corresponding to the hash, nil if -// none found. -func GetTd(db DatabaseReader, hash common.Hash, number uint64) *big.Int { - data, _ := db.Get(append(append(append(headerPrefix, encodeBlockNumber(number)...), hash[:]...), tdSuffix...)) - if len(data) == 0 { - return nil - } - td := new(big.Int) - if err := rlp.Decode(bytes.NewReader(data), td); err != nil { - log.Error("Invalid block total difficulty RLP", "hash", hash, "err", err) - return nil - } - return td -} - -// GetBlock retrieves an entire block corresponding to the hash, assembling it -// back from the stored header and body. If either the header or body could not -// be retrieved nil is returned. -// -// Note, due to concurrent download of header and block body the header and thus -// canonical hash can be stored in the database but the body data not (yet). -func GetBlock(db DatabaseReader, hash common.Hash, number uint64) *types.Block { - // Retrieve the block header and body contents - header := GetHeader(db, hash, number) - if header == nil { - return nil - } - body := GetBody(db, hash, number) - if body == nil { - return nil - } - // Reassemble the block and return - return types.NewBlockWithHeader(header).WithBody(body.Transactions, body.Uncles) -} - -// GetBlockReceipts retrieves the receipts generated by the transactions included -// in a block given by its hash. -func GetBlockReceipts(db DatabaseReader, hash common.Hash, number uint64) types.Receipts { - data, _ := db.Get(append(append(blockReceiptsPrefix, encodeBlockNumber(number)...), hash[:]...)) - if len(data) == 0 { - return nil - } - storageReceipts := []*types.ReceiptForStorage{} - if err := rlp.DecodeBytes(data, &storageReceipts); err != nil { - log.Error("Invalid receipt array RLP", "hash", hash, "err", err) - return nil - } - receipts := make(types.Receipts, len(storageReceipts)) - for i, receipt := range storageReceipts { - receipts[i] = (*types.Receipt)(receipt) - } - return receipts -} - -// GetTxLookupEntry retrieves the positional metadata associated with a transaction -// hash to allow retrieving the transaction or receipt by hash. -func GetTxLookupEntry(db DatabaseReader, hash common.Hash) (common.Hash, uint64, uint64) { - // Load the positional metadata from disk and bail if it fails - data, _ := db.Get(append(lookupPrefix, hash.Bytes()...)) - if len(data) == 0 { - return common.Hash{}, 0, 0 - } - // Parse and return the contents of the lookup entry - var entry TxLookupEntry - if err := rlp.DecodeBytes(data, &entry); err != nil { - log.Error("Invalid lookup entry RLP", "hash", hash, "err", err) - return common.Hash{}, 0, 0 - } - return entry.BlockHash, entry.BlockIndex, entry.Index -} - -// GetTransaction retrieves a specific transaction from the database, along with -// its added positional metadata. -func GetTransaction(db DatabaseReader, hash common.Hash) (*types.Transaction, common.Hash, uint64, uint64) { - // Retrieve the lookup metadata and resolve the transaction from the body - blockHash, blockNumber, txIndex := GetTxLookupEntry(db, hash) - - if blockHash != (common.Hash{}) { - body := GetBody(db, blockHash, blockNumber) - if body == nil || len(body.Transactions) <= int(txIndex) { - log.Error("Transaction referenced missing", "number", blockNumber, "hash", blockHash, "index", txIndex) - return nil, common.Hash{}, 0, 0 - } - return body.Transactions[txIndex], blockHash, blockNumber, txIndex - } - // Old transaction representation, load the transaction and it's metadata separately - data, _ := db.Get(hash.Bytes()) - if len(data) == 0 { - return nil, common.Hash{}, 0, 0 - } - var tx types.Transaction - if err := rlp.DecodeBytes(data, &tx); err != nil { - return nil, common.Hash{}, 0, 0 - } - // Retrieve the blockchain positional metadata - data, _ = db.Get(append(hash.Bytes(), oldTxMetaSuffix...)) - if len(data) == 0 { - return nil, common.Hash{}, 0, 0 - } - var entry TxLookupEntry - if err := rlp.DecodeBytes(data, &entry); err != nil { - return nil, common.Hash{}, 0, 0 - } - return &tx, entry.BlockHash, entry.BlockIndex, entry.Index -} - -// GetReceipt retrieves a specific transaction receipt from the database, along with -// its added positional metadata. -func GetReceipt(db DatabaseReader, hash common.Hash) (*types.Receipt, common.Hash, uint64, uint64) { - // Retrieve the lookup metadata and resolve the receipt from the receipts - blockHash, blockNumber, receiptIndex := GetTxLookupEntry(db, hash) - - if blockHash != (common.Hash{}) { - receipts := GetBlockReceipts(db, blockHash, blockNumber) - if len(receipts) <= int(receiptIndex) { - log.Error("Receipt refereced missing", "number", blockNumber, "hash", blockHash, "index", receiptIndex) - return nil, common.Hash{}, 0, 0 - } - return receipts[receiptIndex], blockHash, blockNumber, receiptIndex - } - // Old receipt representation, load the receipt and set an unknown metadata - data, _ := db.Get(append(oldReceiptsPrefix, hash[:]...)) - if len(data) == 0 { - return nil, common.Hash{}, 0, 0 - } - var receipt types.ReceiptForStorage - err := rlp.DecodeBytes(data, &receipt) - if err != nil { - log.Error("Invalid receipt RLP", "hash", hash, "err", err) - } - return (*types.Receipt)(&receipt), common.Hash{}, 0, 0 -} - -// GetBloomBits retrieves the compressed bloom bit vector belonging to the given -// section and bit index from the. -func GetBloomBits(db DatabaseReader, bit uint, section uint64, head common.Hash) ([]byte, error) { - key := append(append(bloomBitsPrefix, make([]byte, 10)...), head.Bytes()...) - - binary.BigEndian.PutUint16(key[1:], uint16(bit)) - binary.BigEndian.PutUint64(key[3:], section) - - return db.Get(key) -} - -// WriteCanonicalHash stores the canonical hash for the given block number. -func WriteCanonicalHash(db ethdb.Putter, hash common.Hash, number uint64) error { - key := append(append(headerPrefix, encodeBlockNumber(number)...), numSuffix...) - if err := db.Put(key, hash.Bytes()); err != nil { - log.Crit("Failed to store number to hash mapping", "err", err) - } - return nil -} - -// WriteHeadHeaderHash stores the head header's hash. -func WriteHeadHeaderHash(db ethdb.Putter, hash common.Hash) error { - if err := db.Put(headHeaderKey, hash.Bytes()); err != nil { - log.Crit("Failed to store last header's hash", "err", err) - } - return nil -} - -// WriteHeadBlockHash stores the head block's hash. -func WriteHeadBlockHash(db ethdb.Putter, hash common.Hash) error { - if err := db.Put(headBlockKey, hash.Bytes()); err != nil { - log.Crit("Failed to store last block's hash", "err", err) - } - return nil -} - -// WriteHeadFastBlockHash stores the fast head block's hash. -func WriteHeadFastBlockHash(db ethdb.Putter, hash common.Hash) error { - if err := db.Put(headFastKey, hash.Bytes()); err != nil { - log.Crit("Failed to store last fast block's hash", "err", err) - } - return nil -} - -// WriteTrieSyncProgress stores the fast sync trie process counter to support -// retrieving it across restarts. -func WriteTrieSyncProgress(db ethdb.Putter, count uint64) error { - if err := db.Put(trieSyncKey, new(big.Int).SetUint64(count).Bytes()); err != nil { - log.Crit("Failed to store fast sync trie progress", "err", err) - } - return nil -} - -// WriteHeader serializes a block header into the database. -func WriteHeader(db ethdb.Putter, header *types.Header) error { - data, err := rlp.EncodeToBytes(header) - if err != nil { - return err - } - hash := header.Hash().Bytes() - num := header.Number.Uint64() - encNum := encodeBlockNumber(num) - key := append(blockHashPrefix, hash...) - if err := db.Put(key, encNum); err != nil { - log.Crit("Failed to store hash to number mapping", "err", err) - } - key = append(append(headerPrefix, encNum...), hash...) - if err := db.Put(key, data); err != nil { - log.Crit("Failed to store header", "err", err) - } - return nil -} - -// WriteBody serializes the body of a block into the database. -func WriteBody(db ethdb.Putter, hash common.Hash, number uint64, body *types.Body) error { - data, err := rlp.EncodeToBytes(body) - if err != nil { - return err - } - return WriteBodyRLP(db, hash, number, data) -} - -// WriteBodyRLP writes a serialized body of a block into the database. -func WriteBodyRLP(db ethdb.Putter, hash common.Hash, number uint64, rlp rlp.RawValue) error { - key := append(append(bodyPrefix, encodeBlockNumber(number)...), hash.Bytes()...) - if err := db.Put(key, rlp); err != nil { - log.Crit("Failed to store block body", "err", err) - } - return nil -} - -// WriteTd serializes the total difficulty of a block into the database. -func WriteTd(db ethdb.Putter, hash common.Hash, number uint64, td *big.Int) error { - data, err := rlp.EncodeToBytes(td) - if err != nil { - return err - } - key := append(append(append(headerPrefix, encodeBlockNumber(number)...), hash.Bytes()...), tdSuffix...) - if err := db.Put(key, data); err != nil { - log.Crit("Failed to store block total difficulty", "err", err) - } - return nil -} - -// WriteBlock serializes a block into the database, header and body separately. -func WriteBlock(db ethdb.Putter, block *types.Block) error { - // Store the body first to retain database consistency - if err := WriteBody(db, block.Hash(), block.NumberU64(), block.Body()); err != nil { - return err - } - // Store the header too, signaling full block ownership - if err := WriteHeader(db, block.Header()); err != nil { - return err - } - return nil -} - -// WriteBlockReceipts stores all the transaction receipts belonging to a block -// as a single receipt slice. This is used during chain reorganisations for -// rescheduling dropped transactions. -func WriteBlockReceipts(db ethdb.Putter, hash common.Hash, number uint64, receipts types.Receipts) error { - // Convert the receipts into their storage form and serialize them - storageReceipts := make([]*types.ReceiptForStorage, len(receipts)) - for i, receipt := range receipts { - storageReceipts[i] = (*types.ReceiptForStorage)(receipt) - } - bytes, err := rlp.EncodeToBytes(storageReceipts) - if err != nil { - return err - } - // Store the flattened receipt slice - key := append(append(blockReceiptsPrefix, encodeBlockNumber(number)...), hash.Bytes()...) - if err := db.Put(key, bytes); err != nil { - log.Crit("Failed to store block receipts", "err", err) - } - return nil -} - -// WriteTxLookupEntries stores a positional metadata for every transaction from -// a block, enabling hash based transaction and receipt lookups. -func WriteTxLookupEntries(db ethdb.Putter, block *types.Block) error { - // Iterate over each transaction and encode its metadata - for i, tx := range block.Transactions() { - entry := TxLookupEntry{ - BlockHash: block.Hash(), - BlockIndex: block.NumberU64(), - Index: uint64(i), - } - data, err := rlp.EncodeToBytes(entry) - if err != nil { - return err - } - if err := db.Put(append(lookupPrefix, tx.Hash().Bytes()...), data); err != nil { - return err - } - } - return nil -} - -// WriteBloomBits writes the compressed bloom bits vector belonging to the given -// section and bit index. -func WriteBloomBits(db ethdb.Putter, bit uint, section uint64, head common.Hash, bits []byte) { - key := append(append(bloomBitsPrefix, make([]byte, 10)...), head.Bytes()...) - - binary.BigEndian.PutUint16(key[1:], uint16(bit)) - binary.BigEndian.PutUint64(key[3:], section) - - if err := db.Put(key, bits); err != nil { - log.Crit("Failed to store bloom bits", "err", err) - } -} - -// DeleteCanonicalHash removes the number to hash canonical mapping. -func DeleteCanonicalHash(db DatabaseDeleter, number uint64) { - db.Delete(append(append(headerPrefix, encodeBlockNumber(number)...), numSuffix...)) -} - -// DeleteHeader removes all block header data associated with a hash. -func DeleteHeader(db DatabaseDeleter, hash common.Hash, number uint64) { - db.Delete(append(blockHashPrefix, hash.Bytes()...)) - db.Delete(append(append(headerPrefix, encodeBlockNumber(number)...), hash.Bytes()...)) -} - -// DeleteBody removes all block body data associated with a hash. -func DeleteBody(db DatabaseDeleter, hash common.Hash, number uint64) { - db.Delete(append(append(bodyPrefix, encodeBlockNumber(number)...), hash.Bytes()...)) -} - -// DeleteTd removes all block total difficulty data associated with a hash. -func DeleteTd(db DatabaseDeleter, hash common.Hash, number uint64) { - db.Delete(append(append(append(headerPrefix, encodeBlockNumber(number)...), hash.Bytes()...), tdSuffix...)) -} - -// DeleteBlock removes all block data associated with a hash. -func DeleteBlock(db DatabaseDeleter, hash common.Hash, number uint64) { - DeleteBlockReceipts(db, hash, number) - DeleteHeader(db, hash, number) - DeleteBody(db, hash, number) - DeleteTd(db, hash, number) -} - -// DeleteBlockReceipts removes all receipt data associated with a block hash. -func DeleteBlockReceipts(db DatabaseDeleter, hash common.Hash, number uint64) { - db.Delete(append(append(blockReceiptsPrefix, encodeBlockNumber(number)...), hash.Bytes()...)) -} - -// DeleteTxLookupEntry removes all transaction data associated with a hash. -func DeleteTxLookupEntry(db DatabaseDeleter, hash common.Hash) { - db.Delete(append(lookupPrefix, hash.Bytes()...)) -} - -// PreimageTable returns a Database instance with the key prefix for preimage entries. -func PreimageTable(db ethdb.Database) ethdb.Database { - return ethdb.NewTable(db, preimagePrefix) -} - -// WritePreimages writes the provided set of preimages to the database. `number` is the -// current block number, and is used for debug messages only. -func WritePreimages(db ethdb.Database, number uint64, preimages map[common.Hash][]byte) error { - table := PreimageTable(db) - batch := table.NewBatch() - hitCount := 0 - for hash, preimage := range preimages { - if _, err := table.Get(hash.Bytes()); err != nil { - batch.Put(hash.Bytes(), preimage) - hitCount++ - } - } - preimageCounter.Inc(int64(len(preimages))) - preimageHitCounter.Inc(int64(hitCount)) - if hitCount > 0 { - if err := batch.Write(); err != nil { - return fmt.Errorf("preimage write fail for block %d: %v", number, err) - } - } - return nil -} - -// GetBlockChainVersion reads the version number from db. -func GetBlockChainVersion(db DatabaseReader) int { - var vsn uint - enc, _ := db.Get([]byte("BlockchainVersion")) - rlp.DecodeBytes(enc, &vsn) - return int(vsn) -} - -// WriteBlockChainVersion writes vsn as the version number to db. -func WriteBlockChainVersion(db ethdb.Putter, vsn int) { - enc, _ := rlp.EncodeToBytes(uint(vsn)) - db.Put([]byte("BlockchainVersion"), enc) -} - -// WriteChainConfig writes the chain config settings to the database. -func WriteChainConfig(db ethdb.Putter, hash common.Hash, cfg *params.ChainConfig) error { - // short circuit and ignore if nil config. GetChainConfig - // will return a default. - if cfg == nil { - return nil - } - - jsonChainConfig, err := json.Marshal(cfg) - if err != nil { - return err - } - - return db.Put(append(configPrefix, hash[:]...), jsonChainConfig) -} - -// GetChainConfig will fetch the network settings based on the given hash. -func GetChainConfig(db DatabaseReader, hash common.Hash) (*params.ChainConfig, error) { - jsonChainConfig, _ := db.Get(append(configPrefix, hash[:]...)) - if len(jsonChainConfig) == 0 { - return nil, ErrChainConfigNotFound - } - - var config params.ChainConfig - if err := json.Unmarshal(jsonChainConfig, &config); err != nil { - return nil, err - } - - return &config, nil -} - -// FindCommonAncestor returns the last common ancestor of two block headers -func FindCommonAncestor(db DatabaseReader, a, b *types.Header) *types.Header { - for bn := b.Number.Uint64(); a.Number.Uint64() > bn; { - a = GetHeader(db, a.ParentHash, a.Number.Uint64()-1) - if a == nil { - return nil - } - } - for an := a.Number.Uint64(); an < b.Number.Uint64(); { - b = GetHeader(db, b.ParentHash, b.Number.Uint64()-1) - if b == nil { - return nil - } - } - for a.Hash() != b.Hash() { - a = GetHeader(db, a.ParentHash, a.Number.Uint64()-1) - if a == nil { - return nil - } - b = GetHeader(db, b.ParentHash, b.Number.Uint64()-1) - if b == nil { - return nil - } - } - return a -} diff --git a/core/events.go b/core/events.go index 6f404f612b..8d200f2a29 100644 --- a/core/events.go +++ b/core/events.go @@ -21,8 +21,8 @@ import ( "github.com/ethereum/go-ethereum/core/types" ) -// TxPreEvent is posted when a transaction enters the transaction pool. -type TxPreEvent struct{ Tx *types.Transaction } +// NewTxsEvent is posted when a batch of transactions enter the transaction pool. +type NewTxsEvent struct{ Txs []*types.Transaction } // PendingLogsEvent is posted pre mining and notifies of pending logs. type PendingLogsEvent struct { @@ -35,9 +35,6 @@ type PendingStateEvent struct{} // NewMinedBlockEvent is posted when a block has been imported. type NewMinedBlockEvent struct{ Block *types.Block } -// RemovedTransactionEvent is posted when a reorg happens -type RemovedTransactionEvent struct{ Txs types.Transactions } - // RemovedLogsEvent is posted when a reorg happens type RemovedLogsEvent struct{ Logs []*types.Log } diff --git a/core/evm.go b/core/evm.go index 596ea95fb7..d303c40a40 100644 --- a/core/evm.go +++ b/core/evm.go @@ -84,7 +84,7 @@ func GetHashFn(ref *types.Header, chain ChainContext) func(n uint64) common.Hash } } -// CanTransfer checks wether there are enough funds in the address' account to make a transfer. +// CanTransfer checks whether there are enough funds in the address' account to make a transfer. // This does not take the necessary gas in to account to make the transfer valid. func CanTransfer(db vm.StateDB, addr common.Address, amount *big.Int) bool { return db.GetBalance(addr).Cmp(amount) >= 0 diff --git a/core/genesis.go b/core/genesis.go index 8fab2684de..bf3bf90395 100644 --- a/core/genesis.go +++ b/core/genesis.go @@ -28,6 +28,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/common/math" + "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/ethdb" @@ -155,7 +156,7 @@ func SetupGenesisBlock(db ethdb.Database, genesis *Genesis) (*params.ChainConfig } // Just commit the new block if there is no stored genesis block. - stored := GetCanonicalHash(db, 0) + stored := rawdb.ReadCanonicalHash(db, 0) if (stored == common.Hash{}) { if genesis == nil { log.Info("Writing default main-net genesis block") @@ -177,14 +178,11 @@ func SetupGenesisBlock(db ethdb.Database, genesis *Genesis) (*params.ChainConfig // Get the existing chain configuration. newcfg := genesis.configOrDefault(stored) - storedcfg, err := GetChainConfig(db, stored) - if err != nil { - if err == ErrChainConfigNotFound { - // This case happens if a genesis write was interrupted. - log.Warn("Found genesis block without chain config") - err = WriteChainConfig(db, stored, newcfg) - } - return newcfg, stored, 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 } // Special case: don't change the existing config of a non-mainnet chain if no new // config is supplied. These chains would get AllProtocolChanges (and a compat error) @@ -195,15 +193,16 @@ func SetupGenesisBlock(db ethdb.Database, genesis *Genesis) (*params.ChainConfig // Check config compatibility and write the config. Compatibility errors // are returned to the caller unless we're already at block zero. - height := GetBlockNumber(db, GetHeadHeaderHash(db)) - if height == missingNumber { + height := rawdb.ReadHeaderNumber(db, rawdb.ReadHeadHeaderHash(db)) + if height == nil { return newcfg, stored, fmt.Errorf("missing block number for head header hash") } - compatErr := storedcfg.CheckCompatible(newcfg, height) - if compatErr != nil && height != 0 && compatErr.RewindTo != 0 { + compatErr := storedcfg.CheckCompatible(newcfg, *height) + if compatErr != nil && *height != 0 && compatErr.RewindTo != 0 { return newcfg, stored, compatErr } - return newcfg, stored, WriteChainConfig(db, stored, newcfg) + rawdb.WriteChainConfig(db, stored, newcfg) + return newcfg, stored, nil } func (g *Genesis) configOrDefault(ghash common.Hash) *params.ChainConfig { @@ -223,7 +222,7 @@ func (g *Genesis) configOrDefault(ghash common.Hash) *params.ChainConfig { // to the given database (or discards it if nil). func (g *Genesis) ToBlock(db ethdb.Database) *types.Block { if db == nil { - db, _ = ethdb.NewMemDatabase() + db = ethdb.NewMemDatabase() } statedb, _ := state.New(common.Hash{}, state.NewDatabase(db)) for addr, account := range g.Alloc { @@ -267,29 +266,19 @@ func (g *Genesis) Commit(db ethdb.Database) (*types.Block, error) { if block.Number().Sign() != 0 { return nil, fmt.Errorf("can't commit genesis block with number > 0") } - if err := WriteTd(db, block.Hash(), block.NumberU64(), g.Difficulty); err != nil { - return nil, err - } - if err := WriteBlock(db, block); err != nil { - return nil, err - } - if err := WriteBlockReceipts(db, block.Hash(), block.NumberU64(), nil); err != nil { - return nil, err - } - if err := WriteCanonicalHash(db, block.Hash(), block.NumberU64()); err != nil { - return nil, err - } - if err := WriteHeadBlockHash(db, block.Hash()); err != nil { - return nil, err - } - if err := WriteHeadHeaderHash(db, block.Hash()); err != nil { - return nil, err - } + rawdb.WriteTd(db, block.Hash(), block.NumberU64(), g.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.WriteHeadHeaderHash(db, block.Hash()) + config := g.Config if config == nil { config = params.AllEthashProtocolChanges } - return block, WriteChainConfig(db, block.Hash(), config) + rawdb.WriteChainConfig(db, block.Hash(), config) + return block, nil } // MustCommit writes the genesis block and state to db, panicking on error. diff --git a/core/genesis_test.go b/core/genesis_test.go index 47788984b3..31901fee6a 100644 --- a/core/genesis_test.go +++ b/core/genesis_test.go @@ -24,6 +24,7 @@ import ( "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/rawdb" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/params" @@ -140,7 +141,7 @@ func TestSetupGenesis(t *testing.T) { } for _, test := range tests { - db, _ := ethdb.NewMemDatabase() + db := ethdb.NewMemDatabase() config, hash, err := test.fn(db) // Check the return values. if !reflect.DeepEqual(err, test.wantErr) { @@ -154,7 +155,7 @@ func TestSetupGenesis(t *testing.T) { t.Errorf("%s: returned hash %s, want %s", test.name, hash.Hex(), test.wantHash.Hex()) } else if err == nil { // Check database content. - stored := GetBlock(db, test.wantHash, 0) + stored := rawdb.ReadBlock(db, test.wantHash, 0) if stored.Hash() != test.wantHash { t.Errorf("%s: block in DB has hash %s, want %s", test.name, stored.Hash(), test.wantHash) } diff --git a/core/headerchain.go b/core/headerchain.go index 2d1b0a2a18..2bbec28bf3 100644 --- a/core/headerchain.go +++ b/core/headerchain.go @@ -28,6 +28,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/consensus" + "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" @@ -97,7 +98,7 @@ func NewHeaderChain(chainDb ethdb.Database, config *params.ChainConfig, engine c } hc.currentHeader.Store(hc.genesisHeader) - if head := GetHeadBlockHash(chainDb); head != (common.Hash{}) { + if head := rawdb.ReadHeadBlockHash(chainDb); head != (common.Hash{}) { if chead := hc.GetHeaderByHash(head); chead != nil { hc.currentHeader.Store(chead) } @@ -109,13 +110,14 @@ func NewHeaderChain(chainDb ethdb.Database, config *params.ChainConfig, engine c // GetBlockNumber retrieves the block number belonging to the given hash // from the cache or database -func (hc *HeaderChain) GetBlockNumber(hash common.Hash) uint64 { +func (hc *HeaderChain) GetBlockNumber(hash common.Hash) *uint64 { if cached, ok := hc.numberCache.Get(hash); ok { - return cached.(uint64) + number := cached.(uint64) + return &number } - number := GetBlockNumber(hc.chainDb, hash) - if number != missingNumber { - hc.numberCache.Add(hash, number) + number := rawdb.ReadHeaderNumber(hc.chainDb, hash) + if number != nil { + hc.numberCache.Add(hash, *number) } return number } @@ -147,41 +149,40 @@ func (hc *HeaderChain) WriteHeader(header *types.Header) (status WriteStatus, er if err := hc.WriteTd(hash, number, externTd); err != nil { log.Crit("Failed to write header total difficulty", "err", err) } - if err := WriteHeader(hc.chainDb, header); err != nil { - log.Crit("Failed to write header content", "err", err) - } + rawdb.WriteHeader(hc.chainDb, header) + // If the total difficulty is higher than our known, add it to the canonical chain // Second clause in the if statement reduces the vulnerability to selfish mining. // Please refer to http://www.cs.cornell.edu/~ie53/publications/btcProcFC.pdf if externTd.Cmp(localTd) > 0 || (externTd.Cmp(localTd) == 0 && mrand.Float64() < 0.5) { // Delete any canonical number assignments above the new head + batch := hc.chainDb.NewBatch() for i := number + 1; ; i++ { - hash := GetCanonicalHash(hc.chainDb, i) + hash := rawdb.ReadCanonicalHash(hc.chainDb, i) if hash == (common.Hash{}) { break } - DeleteCanonicalHash(hc.chainDb, i) + rawdb.DeleteCanonicalHash(batch, i) } + batch.Write() + // Overwrite any stale canonical number assignments var ( headHash = header.ParentHash headNumber = header.Number.Uint64() - 1 headHeader = hc.GetHeader(headHash, headNumber) ) - for GetCanonicalHash(hc.chainDb, headNumber) != headHash { - WriteCanonicalHash(hc.chainDb, headHash, headNumber) + for rawdb.ReadCanonicalHash(hc.chainDb, headNumber) != headHash { + rawdb.WriteCanonicalHash(hc.chainDb, headHash, headNumber) headHash = headHeader.ParentHash headNumber = headHeader.Number.Uint64() - 1 headHeader = hc.GetHeader(headHash, headNumber) } // Extend the canonical chain with the new header - if err := WriteCanonicalHash(hc.chainDb, hash, number); err != nil { - log.Crit("Failed to insert header number", "err", err) - } - if err := WriteHeadHeaderHash(hc.chainDb, hash); err != nil { - log.Crit("Failed to insert head header hash", "err", err) - } + rawdb.WriteCanonicalHash(hc.chainDb, hash, number) + rawdb.WriteHeadHeaderHash(hc.chainDb, hash) + hc.currentHeaderHash = hash hc.currentHeader.Store(types.CopyHeader(header)) @@ -207,7 +208,7 @@ func (hc *HeaderChain) ValidateHeaderChain(chain []*types.Header, checkFreq int) // 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 || chain[i].ParentHash != chain[i-1].Hash() { - // Chain broke ancestry, log a messge (programming error) and skip insertion + // Chain broke ancestry, log a message (programming error) and skip insertion log.Error("Non contiguous header insert", "number", chain[i].Number, "hash", chain[i].Hash(), "parent", chain[i].ParentHash, "prevnumber", chain[i-1].Number, "prevhash", chain[i-1].Hash()) @@ -309,6 +310,43 @@ func (hc *HeaderChain) GetBlockHashesFromHash(hash common.Hash, max uint64) []co return chain } +// GetAncestor retrieves the Nth ancestor of a given block. It assumes that either the given block or +// a close ancestor of it is canonical. maxNonCanonical points to a downwards counter limiting the +// number of blocks to be individually checked before we reach the canonical chain. +// +// Note: ancestor == 0 returns the same block, 1 returns its parent and so on. +func (hc *HeaderChain) GetAncestor(hash common.Hash, number, ancestor uint64, maxNonCanonical *uint64) (common.Hash, uint64) { + if ancestor > number { + return common.Hash{}, 0 + } + if ancestor == 1 { + // in this case it is cheaper to just read the header + if header := hc.GetHeader(hash, number); header != nil { + return header.ParentHash, number - 1 + } else { + return common.Hash{}, 0 + } + } + for ancestor != 0 { + if rawdb.ReadCanonicalHash(hc.chainDb, number) == hash { + number -= ancestor + return rawdb.ReadCanonicalHash(hc.chainDb, number), number + } + if *maxNonCanonical == 0 { + return common.Hash{}, 0 + } + *maxNonCanonical-- + ancestor-- + header := hc.GetHeader(hash, number) + if header == nil { + return common.Hash{}, 0 + } + hash = header.ParentHash + number-- + } + 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 { @@ -316,7 +354,7 @@ func (hc *HeaderChain) GetTd(hash common.Hash, number uint64) *big.Int { if cached, ok := hc.tdCache.Get(hash); ok { return cached.(*big.Int) } - td := GetTd(hc.chainDb, hash, number) + td := rawdb.ReadTd(hc.chainDb, hash, number) if td == nil { return nil } @@ -328,15 +366,17 @@ func (hc *HeaderChain) GetTd(hash common.Hash, number uint64) *big.Int { // GetTdByHash retrieves a block's total difficulty in the canonical chain from the // database by hash, caching it if found. func (hc *HeaderChain) GetTdByHash(hash common.Hash) *big.Int { - return hc.GetTd(hash, hc.GetBlockNumber(hash)) + number := hc.GetBlockNumber(hash) + if number == nil { + return nil + } + return hc.GetTd(hash, *number) } // WriteTd stores a block's total difficulty into the database, also caching it // along the way. func (hc *HeaderChain) WriteTd(hash common.Hash, number uint64, td *big.Int) error { - if err := WriteTd(hc.chainDb, hash, number, td); err != nil { - return err - } + rawdb.WriteTd(hc.chainDb, hash, number, td) hc.tdCache.Add(hash, new(big.Int).Set(td)) return nil } @@ -348,7 +388,7 @@ func (hc *HeaderChain) GetHeader(hash common.Hash, number uint64) *types.Header if header, ok := hc.headerCache.Get(hash); ok { return header.(*types.Header) } - header := GetHeader(hc.chainDb, hash, number) + header := rawdb.ReadHeader(hc.chainDb, hash, number) if header == nil { return nil } @@ -360,7 +400,11 @@ func (hc *HeaderChain) GetHeader(hash common.Hash, number uint64) *types.Header // GetHeaderByHash retrieves a block header from the database by hash, caching it if // found. func (hc *HeaderChain) GetHeaderByHash(hash common.Hash) *types.Header { - return hc.GetHeader(hash, hc.GetBlockNumber(hash)) + number := hc.GetBlockNumber(hash) + if number == nil { + return nil + } + return hc.GetHeader(hash, *number) } // HasHeader checks if a block header is present in the database or not. @@ -368,14 +412,13 @@ func (hc *HeaderChain) HasHeader(hash common.Hash, number uint64) bool { if hc.numberCache.Contains(hash) || hc.headerCache.Contains(hash) { return true } - ok, _ := hc.chainDb.Has(headerKey(hash, number)) - return ok + return rawdb.HasHeader(hc.chainDb, hash, number) } // GetHeaderByNumber retrieves a block header from the database by number, // caching it (associated with its hash) if found. func (hc *HeaderChain) GetHeaderByNumber(number uint64) *types.Header { - hash := GetCanonicalHash(hc.chainDb, number) + hash := rawdb.ReadCanonicalHash(hc.chainDb, number) if hash == (common.Hash{}) { return nil } @@ -390,16 +433,15 @@ func (hc *HeaderChain) CurrentHeader() *types.Header { // SetCurrentHeader sets the current head header of the canonical chain. func (hc *HeaderChain) SetCurrentHeader(head *types.Header) { - if err := WriteHeadHeaderHash(hc.chainDb, head.Hash()); err != nil { - log.Crit("Failed to insert head header hash", "err", err) - } + rawdb.WriteHeadHeaderHash(hc.chainDb, head.Hash()) + hc.currentHeader.Store(head) hc.currentHeaderHash = head.Hash() } // DeleteCallback is a callback function that is called by SetHead before // each header is deleted. -type DeleteCallback func(common.Hash, uint64) +type DeleteCallback func(rawdb.DatabaseDeleter, common.Hash, uint64) // SetHead rewinds the local chain to a new head. Everything above the new head // will be deleted and the new one set. @@ -409,21 +451,24 @@ func (hc *HeaderChain) SetHead(head uint64, delFn DeleteCallback) { if hdr := hc.CurrentHeader(); hdr != nil { height = hdr.Number.Uint64() } - + batch := hc.chainDb.NewBatch() for hdr := hc.CurrentHeader(); hdr != nil && hdr.Number.Uint64() > head; hdr = hc.CurrentHeader() { hash := hdr.Hash() num := hdr.Number.Uint64() if delFn != nil { - delFn(hash, num) + delFn(batch, hash, num) } - DeleteHeader(hc.chainDb, hash, num) - DeleteTd(hc.chainDb, hash, num) + rawdb.DeleteHeader(batch, hash, num) + rawdb.DeleteTd(batch, hash, num) + hc.currentHeader.Store(hc.GetHeader(hdr.ParentHash, hdr.Number.Uint64()-1)) } // Roll back the canonical chain numbering for i := height; i > head; i-- { - DeleteCanonicalHash(hc.chainDb, i) + rawdb.DeleteCanonicalHash(batch, i) } + batch.Write() + // Clear out any stale content from the caches hc.headerCache.Purge() hc.tdCache.Purge() @@ -434,9 +479,7 @@ func (hc *HeaderChain) SetHead(head uint64, delFn DeleteCallback) { } hc.currentHeaderHash = hc.CurrentHeader().Hash() - if err := WriteHeadHeaderHash(hc.chainDb, hc.currentHeaderHash); err != nil { - log.Crit("Failed to reset head header hash", "err", err) - } + rawdb.WriteHeadHeaderHash(hc.chainDb, hc.currentHeaderHash) } // SetGenesis sets a new genesis block header for the chain diff --git a/core/helper_test.go b/core/helper_test.go index 698a2924cb..051384d854 100644 --- a/core/helper_test.go +++ b/core/helper_test.go @@ -18,7 +18,6 @@ package core import ( "container/list" - "fmt" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/ethdb" @@ -77,18 +76,11 @@ func (tm *TestManager) Db() ethdb.Database { } func NewTestManager() *TestManager { - db, err := ethdb.NewMemDatabase() - if err != nil { - fmt.Println("Could not create mem-db, failing") - return nil - } - testManager := &TestManager{} testManager.eventMux = new(event.TypeMux) - testManager.db = db + testManager.db = ethdb.NewMemDatabase() // testManager.txPool = NewTxPool(testManager) // testManager.blockChain = NewBlockChain(testManager) // testManager.stateManager = NewStateManager(testManager) - return testManager } diff --git a/core/rawdb/accessors_chain.go b/core/rawdb/accessors_chain.go new file mode 100644 index 0000000000..da54328326 --- /dev/null +++ b/core/rawdb/accessors_chain.go @@ -0,0 +1,375 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package rawdb + +import ( + "bytes" + "encoding/binary" + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/rlp" +) + +// ReadCanonicalHash retrieves the hash assigned to a canonical block number. +func ReadCanonicalHash(db DatabaseReader, number uint64) common.Hash { + data, _ := db.Get(headerHashKey(number)) + if len(data) == 0 { + return common.Hash{} + } + return common.BytesToHash(data) +} + +// WriteCanonicalHash stores the hash assigned to a canonical block number. +func WriteCanonicalHash(db DatabaseWriter, hash common.Hash, number uint64) { + if err := db.Put(headerHashKey(number), hash.Bytes()); err != nil { + log.Crit("Failed to store number to hash mapping", "err", err) + } +} + +// DeleteCanonicalHash removes the number to hash canonical mapping. +func DeleteCanonicalHash(db DatabaseDeleter, number uint64) { + if err := db.Delete(headerHashKey(number)); err != nil { + log.Crit("Failed to delete number to hash mapping", "err", err) + } +} + +// ReadHeaderNumber returns the header number assigned to a hash. +func ReadHeaderNumber(db DatabaseReader, hash common.Hash) *uint64 { + data, _ := db.Get(headerNumberKey(hash)) + if len(data) != 8 { + return nil + } + number := binary.BigEndian.Uint64(data) + return &number +} + +// ReadHeadHeaderHash retrieves the hash of the current canonical head header. +func ReadHeadHeaderHash(db DatabaseReader) common.Hash { + data, _ := db.Get(headHeaderKey) + if len(data) == 0 { + return common.Hash{} + } + return common.BytesToHash(data) +} + +// WriteHeadHeaderHash stores the hash of the current canonical head header. +func WriteHeadHeaderHash(db DatabaseWriter, hash common.Hash) { + if err := db.Put(headHeaderKey, hash.Bytes()); err != nil { + log.Crit("Failed to store last header's hash", "err", err) + } +} + +// ReadHeadBlockHash retrieves the hash of the current canonical head block. +func ReadHeadBlockHash(db DatabaseReader) common.Hash { + data, _ := db.Get(headBlockKey) + if len(data) == 0 { + return common.Hash{} + } + return common.BytesToHash(data) +} + +// WriteHeadBlockHash stores the head block's hash. +func WriteHeadBlockHash(db DatabaseWriter, hash common.Hash) { + if err := db.Put(headBlockKey, hash.Bytes()); err != nil { + log.Crit("Failed to store last block's hash", "err", err) + } +} + +// ReadHeadFastBlockHash retrieves the hash of the current fast-sync head block. +func ReadHeadFastBlockHash(db DatabaseReader) common.Hash { + data, _ := db.Get(headFastBlockKey) + if len(data) == 0 { + return common.Hash{} + } + return common.BytesToHash(data) +} + +// WriteHeadFastBlockHash stores the hash of the current fast-sync head block. +func WriteHeadFastBlockHash(db DatabaseWriter, hash common.Hash) { + if err := db.Put(headFastBlockKey, hash.Bytes()); err != nil { + log.Crit("Failed to store last fast block's hash", "err", err) + } +} + +// ReadFastTrieProgress retrieves the number of tries nodes fast synced to allow +// reporting correct numbers across restarts. +func ReadFastTrieProgress(db DatabaseReader) uint64 { + data, _ := db.Get(fastTrieProgressKey) + if len(data) == 0 { + return 0 + } + return new(big.Int).SetBytes(data).Uint64() +} + +// WriteFastTrieProgress stores the fast sync trie process counter to support +// retrieving it across restarts. +func WriteFastTrieProgress(db DatabaseWriter, count uint64) { + if err := db.Put(fastTrieProgressKey, new(big.Int).SetUint64(count).Bytes()); err != nil { + log.Crit("Failed to store fast sync trie progress", "err", err) + } +} + +// ReadHeaderRLP retrieves a block header in its raw RLP database encoding. +func ReadHeaderRLP(db DatabaseReader, hash common.Hash, number uint64) rlp.RawValue { + data, _ := db.Get(headerKey(number, hash)) + return data +} + +// HasHeader verifies the existence of a block header corresponding to the hash. +func HasHeader(db DatabaseReader, hash common.Hash, number uint64) bool { + if has, err := db.Has(headerKey(number, hash)); !has || err != nil { + return false + } + return true +} + +// ReadHeader retrieves the block header corresponding to the hash. +func ReadHeader(db DatabaseReader, hash common.Hash, number uint64) *types.Header { + data := ReadHeaderRLP(db, hash, number) + if len(data) == 0 { + return nil + } + header := new(types.Header) + if err := rlp.Decode(bytes.NewReader(data), header); err != nil { + log.Error("Invalid block header RLP", "hash", hash, "err", err) + return nil + } + return header +} + +// WriteHeader stores a block header into the database and also stores the hash- +// to-number mapping. +func WriteHeader(db DatabaseWriter, header *types.Header) { + // Write the hash -> number mapping + var ( + hash = header.Hash() + number = header.Number.Uint64() + encoded = encodeBlockNumber(number) + ) + key := headerNumberKey(hash) + if err := db.Put(key, encoded); err != nil { + log.Crit("Failed to store hash to number mapping", "err", err) + } + // Write the encoded header + data, err := rlp.EncodeToBytes(header) + if err != nil { + log.Crit("Failed to RLP encode header", "err", err) + } + key = headerKey(number, hash) + if err := db.Put(key, data); err != nil { + log.Crit("Failed to store header", "err", err) + } +} + +// DeleteHeader removes all block header data associated with a hash. +func DeleteHeader(db DatabaseDeleter, hash common.Hash, number uint64) { + if err := db.Delete(headerKey(number, hash)); err != nil { + log.Crit("Failed to delete header", "err", err) + } + if err := db.Delete(headerNumberKey(hash)); err != nil { + log.Crit("Failed to delete hash to number mapping", "err", err) + } +} + +// ReadBodyRLP retrieves the block body (transactions and uncles) in RLP encoding. +func ReadBodyRLP(db DatabaseReader, hash common.Hash, number uint64) rlp.RawValue { + data, _ := db.Get(blockBodyKey(number, hash)) + return data +} + +// WriteBodyRLP stores an RLP encoded block body into the database. +func WriteBodyRLP(db DatabaseWriter, hash common.Hash, number uint64, rlp rlp.RawValue) { + if err := db.Put(blockBodyKey(number, hash), rlp); err != nil { + log.Crit("Failed to store block body", "err", err) + } +} + +// HasBody verifies the existence of a block body corresponding to the hash. +func HasBody(db DatabaseReader, hash common.Hash, number uint64) bool { + if has, err := db.Has(blockBodyKey(number, hash)); !has || err != nil { + return false + } + return true +} + +// ReadBody retrieves the block body corresponding to the hash. +func ReadBody(db DatabaseReader, hash common.Hash, number uint64) *types.Body { + data := ReadBodyRLP(db, hash, number) + if len(data) == 0 { + return nil + } + body := new(types.Body) + if err := rlp.Decode(bytes.NewReader(data), body); err != nil { + log.Error("Invalid block body RLP", "hash", hash, "err", err) + return nil + } + return body +} + +// WriteBody storea a block body into the database. +func WriteBody(db DatabaseWriter, hash common.Hash, number uint64, body *types.Body) { + data, err := rlp.EncodeToBytes(body) + if err != nil { + log.Crit("Failed to RLP encode body", "err", err) + } + WriteBodyRLP(db, hash, number, data) +} + +// DeleteBody removes all block body data associated with a hash. +func DeleteBody(db DatabaseDeleter, hash common.Hash, number uint64) { + if err := db.Delete(blockBodyKey(number, hash)); err != nil { + log.Crit("Failed to delete block body", "err", err) + } +} + +// ReadTd retrieves a block's total difficulty corresponding to the hash. +func ReadTd(db DatabaseReader, hash common.Hash, number uint64) *big.Int { + data, _ := db.Get(headerTDKey(number, hash)) + if len(data) == 0 { + return nil + } + td := new(big.Int) + if err := rlp.Decode(bytes.NewReader(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 DatabaseWriter, 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 DatabaseDeleter, hash common.Hash, number uint64) { + if err := db.Delete(headerTDKey(number, hash)); err != nil { + log.Crit("Failed to delete block total difficulty", "err", err) + } +} + +// ReadReceipts retrieves all the transaction receipts belonging to a block. +func ReadReceipts(db DatabaseReader, hash common.Hash, number uint64) types.Receipts { + // Retrieve the flattened receipt slice + data, _ := db.Get(blockReceiptsKey(number, hash)) + if len(data) == 0 { + return nil + } + // Convert the revceipts from their storage form to their internal representation + storageReceipts := []*types.ReceiptForStorage{} + if err := rlp.DecodeBytes(data, &storageReceipts); err != nil { + log.Error("Invalid receipt array RLP", "hash", hash, "err", err) + return nil + } + receipts := make(types.Receipts, len(storageReceipts)) + for i, receipt := range storageReceipts { + receipts[i] = (*types.Receipt)(receipt) + } + return receipts +} + +// WriteReceipts stores all the transaction receipts belonging to a block. +func WriteReceipts(db DatabaseWriter, hash common.Hash, number uint64, receipts types.Receipts) { + // Convert the receipts into their storage form and serialize them + storageReceipts := make([]*types.ReceiptForStorage, len(receipts)) + for i, receipt := range receipts { + storageReceipts[i] = (*types.ReceiptForStorage)(receipt) + } + bytes, err := rlp.EncodeToBytes(storageReceipts) + if err != nil { + log.Crit("Failed to encode block receipts", "err", err) + } + // Store the flattened receipt slice + if err := db.Put(blockReceiptsKey(number, hash), bytes); err != nil { + log.Crit("Failed to store block receipts", "err", err) + } +} + +// DeleteReceipts removes all receipt data associated with a block hash. +func DeleteReceipts(db DatabaseDeleter, hash common.Hash, number uint64) { + if err := db.Delete(blockReceiptsKey(number, hash)); err != nil { + log.Crit("Failed to delete block receipts", "err", err) + } +} + +// ReadBlock retrieves an entire block corresponding to the hash, assembling it +// back from the stored header and body. If either the header or body could not +// be retrieved nil is returned. +// +// Note, due to concurrent download of header and block body the header and thus +// canonical hash can be stored in the database but the body data not (yet). +func ReadBlock(db DatabaseReader, hash common.Hash, number uint64) *types.Block { + header := ReadHeader(db, hash, number) + if header == nil { + return nil + } + body := ReadBody(db, hash, number) + if body == nil { + return nil + } + return types.NewBlockWithHeader(header).WithBody(body.Transactions, body.Uncles) +} + +// WriteBlock serializes a block into the database, header and body separately. +func WriteBlock(db DatabaseWriter, block *types.Block) { + WriteBody(db, block.Hash(), block.NumberU64(), block.Body()) + WriteHeader(db, block.Header()) +} + +// DeleteBlock removes all block data associated with a hash. +func DeleteBlock(db DatabaseDeleter, hash common.Hash, number uint64) { + DeleteReceipts(db, hash, number) + DeleteHeader(db, hash, number) + DeleteBody(db, hash, number) + DeleteTd(db, hash, number) +} + +// FindCommonAncestor returns the last common ancestor of two block headers +func FindCommonAncestor(db DatabaseReader, a, b *types.Header) *types.Header { + for bn := b.Number.Uint64(); a.Number.Uint64() > bn; { + a = ReadHeader(db, a.ParentHash, a.Number.Uint64()-1) + if a == nil { + return nil + } + } + for an := a.Number.Uint64(); an < b.Number.Uint64(); { + b = ReadHeader(db, b.ParentHash, b.Number.Uint64()-1) + if b == nil { + return nil + } + } + for a.Hash() != b.Hash() { + a = ReadHeader(db, a.ParentHash, a.Number.Uint64()-1) + if a == nil { + return nil + } + b = ReadHeader(db, b.ParentHash, b.Number.Uint64()-1) + if b == nil { + return nil + } + } + return a +} diff --git a/core/database_util_test.go b/core/rawdb/accessors_chain_test.go similarity index 59% rename from core/database_util_test.go rename to core/rawdb/accessors_chain_test.go index ab4e45a478..9ddae6e2b5 100644 --- a/core/database_util_test.go +++ b/core/rawdb/accessors_chain_test.go @@ -1,4 +1,4 @@ -// Copyright 2015 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 @@ -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 core +package rawdb import ( "bytes" @@ -30,23 +30,21 @@ import ( // Tests block header storage and retrieval operations. func TestHeaderStorage(t *testing.T) { - db, _ := ethdb.NewMemDatabase() + db := ethdb.NewMemDatabase() // Create a test header to move around the database and make sure it's really new header := &types.Header{Number: big.NewInt(42), Extra: []byte("test header")} - if entry := GetHeader(db, header.Hash(), header.Number.Uint64()); entry != nil { + if entry := ReadHeader(db, header.Hash(), header.Number.Uint64()); entry != nil { t.Fatalf("Non existent header returned: %v", entry) } // Write and verify the header in the database - if err := WriteHeader(db, header); err != nil { - t.Fatalf("Failed to write header into database: %v", err) - } - if entry := GetHeader(db, header.Hash(), header.Number.Uint64()); entry == nil { + WriteHeader(db, header) + if entry := ReadHeader(db, header.Hash(), header.Number.Uint64()); entry == nil { t.Fatalf("Stored header not found") } else if entry.Hash() != header.Hash() { t.Fatalf("Retrieved header mismatch: have %v, want %v", entry, header) } - if entry := GetHeaderRLP(db, header.Hash(), header.Number.Uint64()); entry == nil { + if entry := ReadHeaderRLP(db, header.Hash(), header.Number.Uint64()); entry == nil { t.Fatalf("Stored header RLP not found") } else { hasher := sha3.NewKeccak256() @@ -58,14 +56,14 @@ func TestHeaderStorage(t *testing.T) { } // Delete the header and verify the execution DeleteHeader(db, header.Hash(), header.Number.Uint64()) - if entry := GetHeader(db, header.Hash(), header.Number.Uint64()); entry != nil { + if entry := ReadHeader(db, header.Hash(), header.Number.Uint64()); entry != nil { t.Fatalf("Deleted header returned: %v", entry) } } // Tests block body storage and retrieval operations. func TestBodyStorage(t *testing.T) { - db, _ := ethdb.NewMemDatabase() + db := ethdb.NewMemDatabase() // Create a test body to move around the database and make sure it's really new body := &types.Body{Uncles: []*types.Header{{Extra: []byte("test header")}}} @@ -74,19 +72,17 @@ func TestBodyStorage(t *testing.T) { rlp.Encode(hasher, body) hash := common.BytesToHash(hasher.Sum(nil)) - if entry := GetBody(db, hash, 0); entry != nil { + if entry := ReadBody(db, hash, 0); entry != nil { t.Fatalf("Non existent body returned: %v", entry) } // Write and verify the body in the database - if err := WriteBody(db, hash, 0, body); err != nil { - t.Fatalf("Failed to write body into database: %v", err) - } - if entry := GetBody(db, hash, 0); entry == nil { + WriteBody(db, hash, 0, body) + if entry := ReadBody(db, hash, 0); entry == nil { t.Fatalf("Stored body not found") } else if types.DeriveSha(types.Transactions(entry.Transactions)) != types.DeriveSha(types.Transactions(body.Transactions)) || types.CalcUncleHash(entry.Uncles) != types.CalcUncleHash(body.Uncles) { t.Fatalf("Retrieved body mismatch: have %v, want %v", entry, body) } - if entry := GetBodyRLP(db, hash, 0); entry == nil { + if entry := ReadBodyRLP(db, hash, 0); entry == nil { t.Fatalf("Stored body RLP not found") } else { hasher := sha3.NewKeccak256() @@ -98,14 +94,14 @@ func TestBodyStorage(t *testing.T) { } // Delete the body and verify the execution DeleteBody(db, hash, 0) - if entry := GetBody(db, hash, 0); entry != nil { + if entry := ReadBody(db, hash, 0); entry != nil { t.Fatalf("Deleted body returned: %v", entry) } } // Tests block storage and retrieval operations. func TestBlockStorage(t *testing.T) { - db, _ := ethdb.NewMemDatabase() + db := ethdb.NewMemDatabase() // Create a test block to move around the database and make sure it's really new block := types.NewBlockWithHeader(&types.Header{ @@ -114,50 +110,48 @@ func TestBlockStorage(t *testing.T) { TxHash: types.EmptyRootHash, ReceiptHash: types.EmptyRootHash, }) - if entry := GetBlock(db, block.Hash(), block.NumberU64()); entry != nil { + if entry := ReadBlock(db, block.Hash(), block.NumberU64()); entry != nil { t.Fatalf("Non existent block returned: %v", entry) } - if entry := GetHeader(db, block.Hash(), block.NumberU64()); entry != nil { + if entry := ReadHeader(db, block.Hash(), block.NumberU64()); entry != nil { t.Fatalf("Non existent header returned: %v", entry) } - if entry := GetBody(db, block.Hash(), block.NumberU64()); entry != nil { + if entry := ReadBody(db, block.Hash(), block.NumberU64()); entry != nil { t.Fatalf("Non existent body returned: %v", entry) } // Write and verify the block in the database - if err := WriteBlock(db, block); err != nil { - t.Fatalf("Failed to write block into database: %v", err) - } - if entry := GetBlock(db, block.Hash(), block.NumberU64()); entry == nil { + WriteBlock(db, block) + if entry := ReadBlock(db, block.Hash(), block.NumberU64()); entry == nil { t.Fatalf("Stored block not found") } else if entry.Hash() != block.Hash() { t.Fatalf("Retrieved block mismatch: have %v, want %v", entry, block) } - if entry := GetHeader(db, block.Hash(), block.NumberU64()); entry == nil { + if entry := ReadHeader(db, block.Hash(), block.NumberU64()); entry == nil { t.Fatalf("Stored header not found") } else if entry.Hash() != block.Header().Hash() { t.Fatalf("Retrieved header mismatch: have %v, want %v", entry, block.Header()) } - if entry := GetBody(db, block.Hash(), block.NumberU64()); entry == nil { + if entry := ReadBody(db, block.Hash(), block.NumberU64()); entry == nil { t.Fatalf("Stored body not found") } else if types.DeriveSha(types.Transactions(entry.Transactions)) != types.DeriveSha(block.Transactions()) || types.CalcUncleHash(entry.Uncles) != types.CalcUncleHash(block.Uncles()) { t.Fatalf("Retrieved body mismatch: have %v, want %v", entry, block.Body()) } // Delete the block and verify the execution DeleteBlock(db, block.Hash(), block.NumberU64()) - if entry := GetBlock(db, block.Hash(), block.NumberU64()); entry != nil { + if entry := ReadBlock(db, block.Hash(), block.NumberU64()); entry != nil { t.Fatalf("Deleted block returned: %v", entry) } - if entry := GetHeader(db, block.Hash(), block.NumberU64()); entry != nil { + if entry := ReadHeader(db, block.Hash(), block.NumberU64()); entry != nil { t.Fatalf("Deleted header returned: %v", entry) } - if entry := GetBody(db, block.Hash(), block.NumberU64()); entry != nil { + if entry := ReadBody(db, block.Hash(), block.NumberU64()); entry != nil { t.Fatalf("Deleted body returned: %v", entry) } } // Tests that partial block contents don't get reassembled into full blocks. func TestPartialBlockStorage(t *testing.T) { - db, _ := ethdb.NewMemDatabase() + db := ethdb.NewMemDatabase() block := types.NewBlockWithHeader(&types.Header{ Extra: []byte("test block"), UncleHash: types.EmptyUncleHash, @@ -165,31 +159,24 @@ func TestPartialBlockStorage(t *testing.T) { ReceiptHash: types.EmptyRootHash, }) // Store a header and check that it's not recognized as a block - if err := WriteHeader(db, block.Header()); err != nil { - t.Fatalf("Failed to write header into database: %v", err) - } - if entry := GetBlock(db, block.Hash(), block.NumberU64()); entry != nil { + WriteHeader(db, block.Header()) + if entry := ReadBlock(db, block.Hash(), block.NumberU64()); entry != nil { t.Fatalf("Non existent block returned: %v", entry) } DeleteHeader(db, block.Hash(), block.NumberU64()) // Store a body and check that it's not recognized as a block - if err := WriteBody(db, block.Hash(), block.NumberU64(), block.Body()); err != nil { - t.Fatalf("Failed to write body into database: %v", err) - } - if entry := GetBlock(db, block.Hash(), block.NumberU64()); entry != nil { + WriteBody(db, block.Hash(), block.NumberU64(), block.Body()) + if entry := ReadBlock(db, block.Hash(), block.NumberU64()); entry != nil { t.Fatalf("Non existent block returned: %v", entry) } DeleteBody(db, block.Hash(), block.NumberU64()) // Store a header and a body separately and check reassembly - if err := WriteHeader(db, block.Header()); err != nil { - t.Fatalf("Failed to write header into database: %v", err) - } - if err := WriteBody(db, block.Hash(), block.NumberU64(), block.Body()); err != nil { - t.Fatalf("Failed to write body into database: %v", err) - } - if entry := GetBlock(db, block.Hash(), block.NumberU64()); entry == nil { + WriteHeader(db, block.Header()) + WriteBody(db, block.Hash(), block.NumberU64(), block.Body()) + + if entry := ReadBlock(db, block.Hash(), block.NumberU64()); entry == nil { t.Fatalf("Stored block not found") } else if entry.Hash() != block.Hash() { t.Fatalf("Retrieved block mismatch: have %v, want %v", entry, block) @@ -198,142 +185,88 @@ func TestPartialBlockStorage(t *testing.T) { // Tests block total difficulty storage and retrieval operations. func TestTdStorage(t *testing.T) { - db, _ := ethdb.NewMemDatabase() + db := ethdb.NewMemDatabase() // 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 := GetTd(db, hash, 0); entry != nil { + if entry := ReadTd(db, hash, 0); entry != nil { t.Fatalf("Non existent TD returned: %v", entry) } // Write and verify the TD in the database - if err := WriteTd(db, hash, 0, td); err != nil { - t.Fatalf("Failed to write TD into database: %v", err) - } - if entry := GetTd(db, hash, 0); entry == nil { + 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 := GetTd(db, hash, 0); entry != nil { + 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, _ := ethdb.NewMemDatabase() + db := ethdb.NewMemDatabase() // Create a test canonical number and assinged hash to move around hash, number := common.Hash{0: 0xff}, uint64(314) - if entry := GetCanonicalHash(db, number); entry != (common.Hash{}) { + if entry := ReadCanonicalHash(db, number); entry != (common.Hash{}) { t.Fatalf("Non existent canonical mapping returned: %v", entry) } // Write and verify the TD in the database - if err := WriteCanonicalHash(db, hash, number); err != nil { - t.Fatalf("Failed to write canonical mapping into database: %v", err) - } - if entry := GetCanonicalHash(db, number); entry == (common.Hash{}) { + WriteCanonicalHash(db, hash, number) + if entry := ReadCanonicalHash(db, number); entry == (common.Hash{}) { t.Fatalf("Stored canonical mapping not found") } else if entry != hash { t.Fatalf("Retrieved canonical mapping mismatch: have %v, want %v", entry, hash) } // Delete the TD and verify the execution DeleteCanonicalHash(db, number) - if entry := GetCanonicalHash(db, number); entry != (common.Hash{}) { + if entry := ReadCanonicalHash(db, number); entry != (common.Hash{}) { t.Fatalf("Deleted canonical mapping returned: %v", entry) } } // Tests that head headers and head blocks can be assigned, individually. func TestHeadStorage(t *testing.T) { - db, _ := ethdb.NewMemDatabase() + db := ethdb.NewMemDatabase() blockHead := types.NewBlockWithHeader(&types.Header{Extra: []byte("test block header")}) blockFull := types.NewBlockWithHeader(&types.Header{Extra: []byte("test block full")}) blockFast := types.NewBlockWithHeader(&types.Header{Extra: []byte("test block fast")}) // Check that no head entries are in a pristine database - if entry := GetHeadHeaderHash(db); entry != (common.Hash{}) { + if entry := ReadHeadHeaderHash(db); entry != (common.Hash{}) { t.Fatalf("Non head header entry returned: %v", entry) } - if entry := GetHeadBlockHash(db); entry != (common.Hash{}) { + if entry := ReadHeadBlockHash(db); entry != (common.Hash{}) { t.Fatalf("Non head block entry returned: %v", entry) } - if entry := GetHeadFastBlockHash(db); entry != (common.Hash{}) { + if entry := ReadHeadFastBlockHash(db); entry != (common.Hash{}) { t.Fatalf("Non fast head block entry returned: %v", entry) } // Assign separate entries for the head header and block - if err := WriteHeadHeaderHash(db, blockHead.Hash()); err != nil { - t.Fatalf("Failed to write head header hash: %v", err) - } - if err := WriteHeadBlockHash(db, blockFull.Hash()); err != nil { - t.Fatalf("Failed to write head block hash: %v", err) - } - if err := WriteHeadFastBlockHash(db, blockFast.Hash()); err != nil { - t.Fatalf("Failed to write fast head block hash: %v", err) - } + WriteHeadHeaderHash(db, blockHead.Hash()) + WriteHeadBlockHash(db, blockFull.Hash()) + WriteHeadFastBlockHash(db, blockFast.Hash()) + // Check that both heads are present, and different (i.e. two heads maintained) - if entry := GetHeadHeaderHash(db); entry != blockHead.Hash() { + if entry := ReadHeadHeaderHash(db); entry != blockHead.Hash() { t.Fatalf("Head header hash mismatch: have %v, want %v", entry, blockHead.Hash()) } - if entry := GetHeadBlockHash(db); entry != blockFull.Hash() { + if entry := ReadHeadBlockHash(db); entry != blockFull.Hash() { t.Fatalf("Head block hash mismatch: have %v, want %v", entry, blockFull.Hash()) } - if entry := GetHeadFastBlockHash(db); entry != blockFast.Hash() { + if entry := ReadHeadFastBlockHash(db); entry != blockFast.Hash() { t.Fatalf("Fast head block hash mismatch: have %v, want %v", entry, blockFast.Hash()) } } -// Tests that positional lookup metadata can be stored and retrieved. -func TestLookupStorage(t *testing.T) { - db, _ := ethdb.NewMemDatabase() - - tx1 := types.NewTransaction(1, common.BytesToAddress([]byte{0x11}), big.NewInt(111), 1111, big.NewInt(11111), []byte{0x11, 0x11, 0x11}) - tx2 := types.NewTransaction(2, common.BytesToAddress([]byte{0x22}), big.NewInt(222), 2222, big.NewInt(22222), []byte{0x22, 0x22, 0x22}) - tx3 := types.NewTransaction(3, common.BytesToAddress([]byte{0x33}), big.NewInt(333), 3333, big.NewInt(33333), []byte{0x33, 0x33, 0x33}) - txs := []*types.Transaction{tx1, tx2, tx3} - - block := types.NewBlock(&types.Header{Number: big.NewInt(314)}, txs, nil, nil) - - // Check that no transactions entries are in a pristine database - for i, tx := range txs { - if txn, _, _, _ := GetTransaction(db, tx.Hash()); txn != nil { - t.Fatalf("tx #%d [%x]: non existent transaction returned: %v", i, tx.Hash(), txn) - } - } - // Insert all the transactions into the database, and verify contents - if err := WriteBlock(db, block); err != nil { - t.Fatalf("failed to write block contents: %v", err) - } - if err := WriteTxLookupEntries(db, block); err != nil { - t.Fatalf("failed to write transactions: %v", err) - } - for i, tx := range txs { - if txn, hash, number, index := GetTransaction(db, tx.Hash()); txn == nil { - t.Fatalf("tx #%d [%x]: transaction not found", i, tx.Hash()) - } else { - if hash != block.Hash() || number != block.NumberU64() || index != uint64(i) { - t.Fatalf("tx #%d [%x]: positional metadata mismatch: have %x/%d/%d, want %x/%v/%v", i, tx.Hash(), hash, number, index, block.Hash(), block.NumberU64(), i) - } - if tx.String() != txn.String() { - t.Fatalf("tx #%d [%x]: transaction mismatch: have %v, want %v", i, tx.Hash(), txn, tx) - } - } - } - // Delete the transactions and check purge - for i, tx := range txs { - DeleteTxLookupEntry(db, tx.Hash()) - if txn, _, _, _ := GetTransaction(db, tx.Hash()); txn != nil { - t.Fatalf("tx #%d [%x]: deleted transaction returned: %v", i, tx.Hash(), txn) - } - } -} - // Tests that receipts associated with a single block can be stored and retrieved. func TestBlockReceiptStorage(t *testing.T) { - db, _ := ethdb.NewMemDatabase() + db := ethdb.NewMemDatabase() receipt1 := &types.Receipt{ Status: types.ReceiptStatusFailed, @@ -361,14 +294,12 @@ func TestBlockReceiptStorage(t *testing.T) { // Check that no receipt entries are in a pristine database hash := common.BytesToHash([]byte{0x03, 0x14}) - if rs := GetBlockReceipts(db, hash, 0); len(rs) != 0 { + if rs := ReadReceipts(db, hash, 0); len(rs) != 0 { t.Fatalf("non existent receipts returned: %v", rs) } // Insert the receipt slice into the database and check presence - if err := WriteBlockReceipts(db, hash, 0, receipts); err != nil { - t.Fatalf("failed to write block receipts: %v", err) - } - if rs := GetBlockReceipts(db, hash, 0); len(rs) == 0 { + WriteReceipts(db, hash, 0, receipts) + if rs := ReadReceipts(db, hash, 0); len(rs) == 0 { t.Fatalf("no receipts returned") } else { for i := 0; i < len(receipts); i++ { @@ -381,8 +312,8 @@ func TestBlockReceiptStorage(t *testing.T) { } } // Delete the receipt slice and check purge - DeleteBlockReceipts(db, hash, 0) - if rs := GetBlockReceipts(db, hash, 0); len(rs) != 0 { + DeleteReceipts(db, hash, 0) + if rs := ReadReceipts(db, hash, 0); len(rs) != 0 { t.Fatalf("deleted receipts returned: %v", rs) } } diff --git a/core/rawdb/accessors_indexes.go b/core/rawdb/accessors_indexes.go new file mode 100644 index 0000000000..4ff7e5bd35 --- /dev/null +++ b/core/rawdb/accessors_indexes.go @@ -0,0 +1,107 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package rawdb + +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/rlp" +) + +// ReadTxLookupEntry retrieves the positional metadata associated with a transaction +// hash to allow retrieving the transaction or receipt by hash. +func ReadTxLookupEntry(db DatabaseReader, hash common.Hash) (common.Hash, uint64, uint64) { + data, _ := db.Get(txLookupKey(hash)) + if len(data) == 0 { + return common.Hash{}, 0, 0 + } + var entry TxLookupEntry + if err := rlp.DecodeBytes(data, &entry); err != nil { + log.Error("Invalid transaction lookup entry RLP", "hash", hash, "err", err) + return common.Hash{}, 0, 0 + } + return entry.BlockHash, entry.BlockIndex, entry.Index +} + +// WriteTxLookupEntries stores a positional metadata for every transaction from +// a block, enabling hash based transaction and receipt lookups. +func WriteTxLookupEntries(db DatabaseWriter, block *types.Block) { + for i, tx := range block.Transactions() { + entry := TxLookupEntry{ + BlockHash: block.Hash(), + BlockIndex: block.NumberU64(), + Index: uint64(i), + } + data, err := rlp.EncodeToBytes(entry) + if err != nil { + log.Crit("Failed to encode transaction lookup entry", "err", err) + } + if err := db.Put(txLookupKey(tx.Hash()), data); err != nil { + log.Crit("Failed to store transaction lookup entry", "err", err) + } + } +} + +// DeleteTxLookupEntry removes all transaction data associated with a hash. +func DeleteTxLookupEntry(db DatabaseDeleter, hash common.Hash) { + db.Delete(txLookupKey(hash)) +} + +// ReadTransaction retrieves a specific transaction from the database, along with +// its added positional metadata. +func ReadTransaction(db DatabaseReader, hash common.Hash) (*types.Transaction, common.Hash, uint64, uint64) { + blockHash, blockNumber, txIndex := ReadTxLookupEntry(db, hash) + if blockHash == (common.Hash{}) { + return nil, common.Hash{}, 0, 0 + } + body := ReadBody(db, blockHash, blockNumber) + if body == nil || len(body.Transactions) <= int(txIndex) { + log.Error("Transaction referenced missing", "number", blockNumber, "hash", blockHash, "index", txIndex) + return nil, common.Hash{}, 0, 0 + } + return body.Transactions[txIndex], blockHash, blockNumber, txIndex +} + +// ReadReceipt retrieves a specific transaction receipt from the database, along with +// its added positional metadata. +func ReadReceipt(db DatabaseReader, hash common.Hash) (*types.Receipt, common.Hash, uint64, uint64) { + blockHash, blockNumber, receiptIndex := ReadTxLookupEntry(db, hash) + if blockHash == (common.Hash{}) { + return nil, common.Hash{}, 0, 0 + } + receipts := ReadReceipts(db, blockHash, blockNumber) + if len(receipts) <= int(receiptIndex) { + log.Error("Receipt refereced missing", "number", blockNumber, "hash", blockHash, "index", receiptIndex) + return nil, common.Hash{}, 0, 0 + } + return receipts[receiptIndex], blockHash, blockNumber, receiptIndex +} + +// ReadBloomBits retrieves the compressed bloom bit vector belonging to the given +// section and bit index from the. +func ReadBloomBits(db DatabaseReader, bit uint, section uint64, head common.Hash) ([]byte, error) { + return db.Get(bloomBitsKey(bit, section, head)) +} + +// WriteBloomBits stores the compressed bloom bits vector belonging to the given +// section and bit index. +func WriteBloomBits(db DatabaseWriter, bit uint, section uint64, head common.Hash, bits []byte) { + if err := db.Put(bloomBitsKey(bit, section, head), bits); err != nil { + log.Crit("Failed to store bloom bits", "err", err) + } +} diff --git a/core/rawdb/accessors_indexes_test.go b/core/rawdb/accessors_indexes_test.go new file mode 100644 index 0000000000..d9c10e1490 --- /dev/null +++ b/core/rawdb/accessors_indexes_test.go @@ -0,0 +1,68 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package rawdb + +import ( + "math/big" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/ethdb" +) + +// Tests that positional lookup metadata can be stored and retrieved. +func TestLookupStorage(t *testing.T) { + db := ethdb.NewMemDatabase() + + tx1 := types.NewTransaction(1, common.BytesToAddress([]byte{0x11}), big.NewInt(111), 1111, big.NewInt(11111), []byte{0x11, 0x11, 0x11}) + tx2 := types.NewTransaction(2, common.BytesToAddress([]byte{0x22}), big.NewInt(222), 2222, big.NewInt(22222), []byte{0x22, 0x22, 0x22}) + tx3 := types.NewTransaction(3, common.BytesToAddress([]byte{0x33}), big.NewInt(333), 3333, big.NewInt(33333), []byte{0x33, 0x33, 0x33}) + txs := []*types.Transaction{tx1, tx2, tx3} + + block := types.NewBlock(&types.Header{Number: big.NewInt(314)}, txs, nil, nil) + + // Check that no transactions entries are in a pristine database + for i, tx := range txs { + if txn, _, _, _ := ReadTransaction(db, tx.Hash()); txn != nil { + t.Fatalf("tx #%d [%x]: non existent transaction returned: %v", i, tx.Hash(), txn) + } + } + // Insert all the transactions into the database, and verify contents + WriteBlock(db, block) + WriteTxLookupEntries(db, block) + + for i, tx := range txs { + if txn, hash, number, index := ReadTransaction(db, tx.Hash()); txn == nil { + t.Fatalf("tx #%d [%x]: transaction not found", i, tx.Hash()) + } else { + if hash != block.Hash() || number != block.NumberU64() || index != uint64(i) { + t.Fatalf("tx #%d [%x]: positional metadata mismatch: have %x/%d/%d, want %x/%v/%v", i, tx.Hash(), hash, number, index, block.Hash(), block.NumberU64(), i) + } + if tx.Hash() != txn.Hash() { + t.Fatalf("tx #%d [%x]: transaction mismatch: have %v, want %v", i, tx.Hash(), txn, tx) + } + } + } + // Delete the transactions and check purge + for i, tx := range txs { + DeleteTxLookupEntry(db, tx.Hash()) + if txn, _, _, _ := ReadTransaction(db, tx.Hash()); txn != nil { + t.Fatalf("tx #%d [%x]: deleted transaction returned: %v", i, tx.Hash(), txn) + } + } +} diff --git a/core/rawdb/accessors_metadata.go b/core/rawdb/accessors_metadata.go new file mode 100644 index 0000000000..514328e87b --- /dev/null +++ b/core/rawdb/accessors_metadata.go @@ -0,0 +1,90 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package rawdb + +import ( + "encoding/json" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/rlp" +) + +// ReadDatabaseVersion retrieves the version number of the database. +func ReadDatabaseVersion(db DatabaseReader) int { + var version int + + enc, _ := db.Get(databaseVerisionKey) + rlp.DecodeBytes(enc, &version) + + return version +} + +// WriteDatabaseVersion stores the version number of the database +func WriteDatabaseVersion(db DatabaseWriter, version int) { + enc, _ := rlp.EncodeToBytes(version) + if err := db.Put(databaseVerisionKey, enc); err != nil { + log.Crit("Failed to store the database version", "err", err) + } +} + +// ReadChainConfig retrieves the consensus settings based on the given genesis hash. +func ReadChainConfig(db DatabaseReader, hash common.Hash) *params.ChainConfig { + data, _ := db.Get(configKey(hash)) + if len(data) == 0 { + return nil + } + var config params.ChainConfig + if err := json.Unmarshal(data, &config); err != nil { + log.Error("Invalid chain config JSON", "hash", hash, "err", err) + return nil + } + return &config +} + +// WriteChainConfig writes the chain config settings to the database. +func WriteChainConfig(db DatabaseWriter, hash common.Hash, cfg *params.ChainConfig) { + if cfg == nil { + return + } + data, err := json.Marshal(cfg) + if err != nil { + log.Crit("Failed to JSON encode chain config", "err", err) + } + if err := db.Put(configKey(hash), data); err != nil { + log.Crit("Failed to store chain config", "err", err) + } +} + +// ReadPreimage retrieves a single preimage of the provided hash. +func ReadPreimage(db DatabaseReader, hash common.Hash) []byte { + data, _ := db.Get(preimageKey(hash)) + return data +} + +// WritePreimages writes the provided set of preimages to the database. `number` is the +// current block number, and is used for debug messages only. +func WritePreimages(db DatabaseWriter, number uint64, preimages map[common.Hash][]byte) { + for hash, preimage := range preimages { + if err := db.Put(preimageKey(hash), preimage); err != nil { + log.Crit("Failed to store trie preimage", "err", err) + } + } + preimageCounter.Inc(int64(len(preimages))) + preimageHitCounter.Inc(int64(len(preimages))) +} diff --git a/core/rawdb/interfaces.go b/core/rawdb/interfaces.go new file mode 100644 index 0000000000..3bdf55124a --- /dev/null +++ b/core/rawdb/interfaces.go @@ -0,0 +1,33 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package rawdb + +// DatabaseReader wraps the Has and Get method of a backing data store. +type DatabaseReader interface { + Has(key []byte) (bool, error) + Get(key []byte) ([]byte, error) +} + +// DatabaseWriter wraps the Put method of a backing data store. +type DatabaseWriter interface { + Put(key []byte, value []byte) error +} + +// DatabaseDeleter wraps the Delete method of a backing data store. +type DatabaseDeleter interface { + Delete(key []byte) error +} diff --git a/core/rawdb/schema.go b/core/rawdb/schema.go new file mode 100644 index 0000000000..ef597ef309 --- /dev/null +++ b/core/rawdb/schema.go @@ -0,0 +1,134 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +// Package rawdb contains a collection of low level database accessors. +package rawdb + +import ( + "encoding/binary" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/metrics" +) + +// The fields below define the low level database schema prefixing. +var ( + // databaseVerisionKey tracks the current database version. + databaseVerisionKey = []byte("DatabaseVersion") + + // headHeaderKey tracks the latest know header's hash. + headHeaderKey = []byte("LastHeader") + + // headBlockKey tracks the latest know full block's hash. + headBlockKey = []byte("LastBlock") + + // headFastBlockKey tracks the latest known incomplete block's hash duirng fast sync. + headFastBlockKey = []byte("LastFast") + + // fastTrieProgressKey tracks the number of trie entries imported during fast sync. + fastTrieProgressKey = []byte("TrieSync") + + // 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 + headerHashSuffix = []byte("n") // headerPrefix + num (uint64 big endian) + headerHashSuffix -> hash + headerNumberPrefix = []byte("H") // headerNumberPrefix + hash -> num (uint64 big endian) + + blockBodyPrefix = []byte("b") // blockBodyPrefix + num (uint64 big endian) + hash -> block body + blockReceiptsPrefix = []byte("r") // blockReceiptsPrefix + num (uint64 big endian) + hash -> block receipts + + txLookupPrefix = []byte("l") // txLookupPrefix + hash -> transaction/receipt lookup metadata + bloomBitsPrefix = []byte("B") // bloomBitsPrefix + bit (uint16 big endian) + section (uint64 big endian) + hash -> bloom bits + + preimagePrefix = []byte("secure-key-") // preimagePrefix + hash -> preimage + configPrefix = []byte("ethereum-config-") // config prefix for the db + + // Chain index prefixes (use `i` + single byte to avoid mixing data types). + BloomBitsIndexPrefix = []byte("iB") // BloomBitsIndexPrefix is the data table of a chain indexer to track its progress + + preimageCounter = metrics.NewRegisteredCounter("db/preimage/total", nil) + preimageHitCounter = metrics.NewRegisteredCounter("db/preimage/hits", nil) +) + +// TxLookupEntry is a positional metadata to help looking up the data content of +// a transaction or receipt given only its hash. +type TxLookupEntry struct { + BlockHash common.Hash + BlockIndex uint64 + Index uint64 +} + +// encodeBlockNumber encodes a block number as big endian uint64 +func encodeBlockNumber(number uint64) []byte { + enc := make([]byte, 8) + binary.BigEndian.PutUint64(enc, number) + return enc +} + +// headerKey = headerPrefix + num (uint64 big endian) + hash +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...) +} + +// headerNumberKey = headerNumberPrefix + hash +func headerNumberKey(hash common.Hash) []byte { + return append(headerNumberPrefix, hash.Bytes()...) +} + +// blockBodyKey = blockBodyPrefix + num (uint64 big endian) + hash +func blockBodyKey(number uint64, hash common.Hash) []byte { + return append(append(blockBodyPrefix, encodeBlockNumber(number)...), hash.Bytes()...) +} + +// blockReceiptsKey = blockReceiptsPrefix + num (uint64 big endian) + hash +func blockReceiptsKey(number uint64, hash common.Hash) []byte { + return append(append(blockReceiptsPrefix, encodeBlockNumber(number)...), hash.Bytes()...) +} + +// txLookupKey = txLookupPrefix + hash +func txLookupKey(hash common.Hash) []byte { + return append(txLookupPrefix, hash.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 +} + +// preimageKey = preimagePrefix + hash +func preimageKey(hash common.Hash) []byte { + return append(preimagePrefix, hash.Bytes()...) +} + +// configKey = configPrefix + hash +func configKey(hash common.Hash) []byte { + return append(configPrefix, hash.Bytes()...) +} diff --git a/core/state/database.go b/core/state/database.go index 36926ec69d..c1b630991c 100644 --- a/core/state/database.go +++ b/core/state/database.go @@ -26,7 +26,7 @@ import ( lru "github.com/hashicorp/golang-lru" ) -// Trie cache generation limit after which to evic trie nodes from memory. +// Trie cache generation limit after which to evict trie nodes from memory. var MaxTrieCacheGen = uint16(120) const ( @@ -151,9 +151,6 @@ func (db *cachingDB) ContractCodeSize(addrHash, codeHash common.Hash) (int, erro return cached.(int), nil } code, err := db.ContractCode(addrHash, codeHash) - if err == nil { - db.codeSizeCache.Add(codeHash, len(code)) - } return len(code), err } diff --git a/core/state/dump.go b/core/state/dump.go index 46e612850a..072dbbf053 100644 --- a/core/state/dump.go +++ b/core/state/dump.go @@ -53,7 +53,7 @@ func (self *StateDB) RawDump() Dump { panic(err) } - obj := newObject(nil, common.BytesToAddress(addr), data, nil) + obj := newObject(nil, common.BytesToAddress(addr), data) account := DumpAccount{ Balance: data.Balance.String(), Nonce: data.Nonce, diff --git a/core/state/journal.go b/core/state/journal.go index a89bb3d13a..a03ca57dbc 100644 --- a/core/state/journal.go +++ b/core/state/journal.go @@ -22,11 +22,67 @@ import ( "github.com/ethereum/go-ethereum/common" ) +// journalEntry is a modification entry in the state change journal that can be +// reverted on demand. type journalEntry interface { - undo(*StateDB) + // revert undoes the changes introduced by this journal entry. + revert(*StateDB) + + // dirtied returns the Ethereum address modified by this journal entry. + dirtied() *common.Address } -type journal []journalEntry +// journal contains the list of state modifications applied since the last state +// commit. These are tracked to be able to be reverted in case of an execution +// exception or revertal request. +type journal struct { + entries []journalEntry // Current changes tracked by the journal + dirties map[common.Address]int // Dirty accounts and the number of changes +} + +// newJournal create a new initialized journal. +func newJournal() *journal { + return &journal{ + dirties: make(map[common.Address]int), + } +} + +// append inserts a new modification entry to the end of the change journal. +func (j *journal) append(entry journalEntry) { + j.entries = append(j.entries, entry) + if addr := entry.dirtied(); addr != nil { + j.dirties[*addr]++ + } +} + +// revert undoes a batch of journalled modifications along with any reverted +// dirty handling too. +func (j *journal) revert(statedb *StateDB, snapshot int) { + for i := len(j.entries) - 1; i >= snapshot; i-- { + // Undo the changes made by the operation + j.entries[i].revert(statedb) + + // Drop any dirty tracking induced by the change + if addr := j.entries[i].dirtied(); addr != nil { + if j.dirties[*addr]--; j.dirties[*addr] == 0 { + delete(j.dirties, *addr) + } + } + } + j.entries = j.entries[:snapshot] +} + +// dirty explicitly sets an address to dirty, even if the change entries would +// otherwise suggest it as clean. This method is an ugly hack to handle the RIPEMD +// precompile consensus exception. +func (j *journal) dirty(addr common.Address) { + j.dirties[addr]++ +} + +// length returns the current number of entries in the journal. +func (j *journal) length() int { + return len(j.entries) +} type ( // Changes to the account trie. @@ -77,16 +133,24 @@ type ( } ) -func (ch createObjectChange) undo(s *StateDB) { +func (ch createObjectChange) revert(s *StateDB) { delete(s.stateObjects, *ch.account) delete(s.stateObjectsDirty, *ch.account) } -func (ch resetObjectChange) undo(s *StateDB) { +func (ch createObjectChange) dirtied() *common.Address { + return ch.account +} + +func (ch resetObjectChange) revert(s *StateDB) { s.setStateObject(ch.prev) } -func (ch suicideChange) undo(s *StateDB) { +func (ch resetObjectChange) dirtied() *common.Address { + return nil +} + +func (ch suicideChange) revert(s *StateDB) { obj := s.getStateObject(*ch.account) if obj != nil { obj.suicided = ch.prev @@ -94,38 +158,60 @@ func (ch suicideChange) undo(s *StateDB) { } } -var ripemd = common.HexToAddress("0000000000000000000000000000000000000003") - -func (ch touchChange) undo(s *StateDB) { - if !ch.prev && *ch.account != ripemd { - s.getStateObject(*ch.account).touched = ch.prev - if !ch.prevDirty { - delete(s.stateObjectsDirty, *ch.account) - } - } +func (ch suicideChange) dirtied() *common.Address { + return ch.account } -func (ch balanceChange) undo(s *StateDB) { +var ripemd = common.HexToAddress("0000000000000000000000000000000000000003") + +func (ch touchChange) revert(s *StateDB) { +} + +func (ch touchChange) dirtied() *common.Address { + return ch.account +} + +func (ch balanceChange) revert(s *StateDB) { s.getStateObject(*ch.account).setBalance(ch.prev) } -func (ch nonceChange) undo(s *StateDB) { +func (ch balanceChange) dirtied() *common.Address { + return ch.account +} + +func (ch nonceChange) revert(s *StateDB) { s.getStateObject(*ch.account).setNonce(ch.prev) } -func (ch codeChange) undo(s *StateDB) { +func (ch nonceChange) dirtied() *common.Address { + return ch.account +} + +func (ch codeChange) revert(s *StateDB) { s.getStateObject(*ch.account).setCode(common.BytesToHash(ch.prevhash), ch.prevcode) } -func (ch storageChange) undo(s *StateDB) { +func (ch codeChange) dirtied() *common.Address { + return ch.account +} + +func (ch storageChange) revert(s *StateDB) { s.getStateObject(*ch.account).setState(ch.key, ch.prevalue) } -func (ch refundChange) undo(s *StateDB) { +func (ch storageChange) dirtied() *common.Address { + return ch.account +} + +func (ch refundChange) revert(s *StateDB) { s.refund = ch.prev } -func (ch addLogChange) undo(s *StateDB) { +func (ch refundChange) dirtied() *common.Address { + return nil +} + +func (ch addLogChange) revert(s *StateDB) { logs := s.logs[ch.txhash] if len(logs) == 1 { delete(s.logs, ch.txhash) @@ -135,6 +221,14 @@ func (ch addLogChange) undo(s *StateDB) { s.logSize-- } -func (ch addPreimageChange) undo(s *StateDB) { +func (ch addLogChange) dirtied() *common.Address { + return nil +} + +func (ch addPreimageChange) revert(s *StateDB) { delete(s.preimages, ch.hash) } + +func (ch addPreimageChange) dirtied() *common.Address { + return nil +} diff --git a/core/state/managed_state_test.go b/core/state/managed_state_test.go index 1cfdd3a890..3d9c4e8676 100644 --- a/core/state/managed_state_test.go +++ b/core/state/managed_state_test.go @@ -26,8 +26,7 @@ import ( var addr = common.BytesToAddress([]byte("test")) func create() (*ManagedState, *account) { - db, _ := ethdb.NewMemDatabase() - statedb, _ := New(common.Hash{}, NewDatabase(db)) + statedb, _ := New(common.Hash{}, NewDatabase(ethdb.NewMemDatabase())) ms := ManageState(statedb) ms.StateDB.SetNonce(addr, 100) ms.accounts[addr] = newAccount(ms.StateDB.getStateObject(addr)) diff --git a/core/state/state_object.go b/core/state/state_object.go index b2112bfaec..091d24184a 100644 --- a/core/state/state_object.go +++ b/core/state/state_object.go @@ -85,9 +85,7 @@ type stateObject struct { // during the "update" phase of the state transition. dirtyCode bool // true if the code was updated suicided bool - touched bool deleted bool - onDirty func(addr common.Address) // Callback method to mark a state object newly dirty } // empty returns whether the account is considered empty. @@ -105,7 +103,7 @@ type Account struct { } // newObject creates a state object. -func newObject(db *StateDB, address common.Address, data Account, onDirty func(addr common.Address)) *stateObject { +func newObject(db *StateDB, address common.Address, data Account) *stateObject { if data.Balance == nil { data.Balance = new(big.Int) } @@ -119,7 +117,6 @@ func newObject(db *StateDB, address common.Address, data Account, onDirty func(a data: data, cachedStorage: make(Storage), dirtyStorage: make(Storage), - onDirty: onDirty, } } @@ -137,23 +134,17 @@ func (self *stateObject) setError(err error) { func (self *stateObject) markSuicided() { self.suicided = true - if self.onDirty != nil { - self.onDirty(self.Address()) - self.onDirty = nil - } } func (c *stateObject) touch() { - c.db.journal = append(c.db.journal, touchChange{ - account: &c.address, - prev: c.touched, - prevDirty: c.onDirty == nil, + c.db.journal.append(touchChange{ + account: &c.address, }) - if c.onDirty != nil { - c.onDirty(c.Address()) - c.onDirty = nil + if c.address == ripemd { + // Explicitly put it in the dirty-cache, which is otherwise generated from + // flattened journals. + c.db.journal.dirty(c.address) } - c.touched = true } func (c *stateObject) getTrie(db Database) Trie { @@ -187,15 +178,13 @@ func (self *stateObject) GetState(db Database, key common.Hash) common.Hash { } value.SetBytes(content) } - if (value != common.Hash{}) { - self.cachedStorage[key] = value - } + self.cachedStorage[key] = value return value } // SetState updates a value in account storage. func (self *stateObject) SetState(db Database, key, value common.Hash) { - self.db.journal = append(self.db.journal, storageChange{ + self.db.journal.append(storageChange{ account: &self.address, key: key, prevalue: self.GetState(db, key), @@ -206,11 +195,6 @@ func (self *stateObject) SetState(db Database, key, value common.Hash) { func (self *stateObject) setState(key, value common.Hash) { self.cachedStorage[key] = value self.dirtyStorage[key] = value - - if self.onDirty != nil { - self.onDirty(self.Address()) - self.onDirty = nil - } } // updateTrie writes cached storage modifications into the object's storage trie. @@ -235,7 +219,7 @@ func (self *stateObject) updateRoot(db Database) { self.data.Root = self.trie.Hash() } -// CommitTrie the storage trie of the object to dwb. +// CommitTrie the storage trie of the object to db. // This updates the trie root. func (self *stateObject) CommitTrie(db Database) error { self.updateTrie(db) @@ -274,7 +258,7 @@ func (c *stateObject) SubBalance(amount *big.Int) { } func (self *stateObject) SetBalance(amount *big.Int) { - self.db.journal = append(self.db.journal, balanceChange{ + self.db.journal.append(balanceChange{ account: &self.address, prev: new(big.Int).Set(self.data.Balance), }) @@ -283,17 +267,13 @@ func (self *stateObject) SetBalance(amount *big.Int) { func (self *stateObject) setBalance(amount *big.Int) { self.data.Balance = amount - if self.onDirty != nil { - self.onDirty(self.Address()) - self.onDirty = nil - } } // Return the gas back to the origin. Used by the Virtual machine or Closures func (c *stateObject) ReturnGas(gas *big.Int) {} -func (self *stateObject) deepCopy(db *StateDB, onDirty func(addr common.Address)) *stateObject { - stateObject := newObject(db, self.address, self.data, onDirty) +func (self *stateObject) deepCopy(db *StateDB) *stateObject { + stateObject := newObject(db, self.address, self.data) if self.trie != nil { stateObject.trie = db.db.CopyTrie(self.trie) } @@ -333,7 +313,7 @@ func (self *stateObject) Code(db Database) []byte { func (self *stateObject) SetCode(codeHash common.Hash, code []byte) { prevcode := self.Code(self.db.db) - self.db.journal = append(self.db.journal, codeChange{ + self.db.journal.append(codeChange{ account: &self.address, prevhash: self.CodeHash(), prevcode: prevcode, @@ -345,14 +325,10 @@ func (self *stateObject) setCode(codeHash common.Hash, code []byte) { self.code = code self.data.CodeHash = codeHash[:] self.dirtyCode = true - if self.onDirty != nil { - self.onDirty(self.Address()) - self.onDirty = nil - } } func (self *stateObject) SetNonce(nonce uint64) { - self.db.journal = append(self.db.journal, nonceChange{ + self.db.journal.append(nonceChange{ account: &self.address, prev: self.data.Nonce, }) @@ -361,10 +337,6 @@ func (self *stateObject) SetNonce(nonce uint64) { func (self *stateObject) setNonce(nonce uint64) { self.data.Nonce = nonce - if self.onDirty != nil { - self.onDirty(self.Address()) - self.onDirty = nil - } } func (self *stateObject) CodeHash() []byte { diff --git a/core/state/state_test.go b/core/state/state_test.go index 6d42d63d82..123559ea9b 100644 --- a/core/state/state_test.go +++ b/core/state/state_test.go @@ -87,7 +87,7 @@ func (s *StateSuite) TestDump(c *checker.C) { } func (s *StateSuite) SetUpTest(c *checker.C) { - s.db, _ = ethdb.NewMemDatabase() + s.db = ethdb.NewMemDatabase() s.state, _ = New(common.Hash{}, NewDatabase(s.db)) } @@ -99,7 +99,7 @@ func (s *StateSuite) TestNull(c *checker.C) { s.state.SetState(address, common.Hash{}, value) s.state.Commit(false) value = s.state.GetState(address, common.Hash{}) - if !common.EmptyHash(value) { + if value != (common.Hash{}) { c.Errorf("expected empty hash. got %x", value) } } @@ -133,8 +133,7 @@ func (s *StateSuite) TestSnapshotEmpty(c *checker.C) { // use testing instead of checker because checker does not support // printing/logging in tests (-check.vv does not work) func TestSnapshot2(t *testing.T) { - db, _ := ethdb.NewMemDatabase() - state, _ := New(common.Hash{}, NewDatabase(db)) + state, _ := New(common.Hash{}, NewDatabase(ethdb.NewMemDatabase())) stateobjaddr0 := toAddr([]byte("so0")) stateobjaddr1 := toAddr([]byte("so1")) diff --git a/core/state/statedb.go b/core/state/statedb.go index 2ae700cd67..dc9d30a1dc 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -76,7 +76,7 @@ type StateDB struct { // Journal of state modifications. This is the backbone of // Snapshot and RevertToSnapshot. - journal journal + journal *journal validRevisions []revision nextRevisionId int @@ -96,6 +96,7 @@ func New(root common.Hash, db Database) (*StateDB, error) { stateObjectsDirty: make(map[common.Address]struct{}), logs: make(map[common.Hash][]*types.Log), preimages: make(map[common.Hash][]byte), + journal: newJournal(), }, nil } @@ -131,7 +132,7 @@ func (self *StateDB) Reset(root common.Hash) error { } func (self *StateDB) AddLog(log *types.Log) { - self.journal = append(self.journal, addLogChange{txhash: self.thash}) + self.journal.append(addLogChange{txhash: self.thash}) log.TxHash = self.thash log.BlockHash = self.bhash @@ -156,7 +157,7 @@ func (self *StateDB) Logs() []*types.Log { // AddPreimage records a SHA3 preimage seen by the VM. func (self *StateDB) AddPreimage(hash common.Hash, preimage []byte) { if _, ok := self.preimages[hash]; !ok { - self.journal = append(self.journal, addPreimageChange{hash: hash}) + self.journal.append(addPreimageChange{hash: hash}) pi := make([]byte, len(preimage)) copy(pi, preimage) self.preimages[hash] = pi @@ -169,7 +170,7 @@ func (self *StateDB) Preimages() map[common.Hash][]byte { } func (self *StateDB) AddRefund(gas uint64) { - self.journal = append(self.journal, refundChange{prev: self.refund}) + self.journal.append(refundChange{prev: self.refund}) self.refund += gas } @@ -255,7 +256,7 @@ func (self *StateDB) StorageTrie(addr common.Address) Trie { if stateObject == nil { return nil } - cpy := stateObject.deepCopy(self, nil) + cpy := stateObject.deepCopy(self) return cpy.updateTrie(self.db) } @@ -325,7 +326,7 @@ func (self *StateDB) Suicide(addr common.Address) bool { if stateObject == nil { return false } - self.journal = append(self.journal, suicideChange{ + self.journal.append(suicideChange{ account: &addr, prev: stateObject.suicided, prevbalance: new(big.Int).Set(stateObject.Balance()), @@ -387,7 +388,7 @@ func (self *StateDB) getStateObject(addr common.Address) (stateObject *stateObje return nil } // Insert into the live set. - obj := newObject(self, addr, data, self.MarkStateObjectDirty) + obj := newObject(self, addr, data) self.setStateObject(obj) return obj } @@ -405,22 +406,16 @@ func (self *StateDB) GetOrNewStateObject(addr common.Address) *stateObject { return stateObject } -// MarkStateObjectDirty adds the specified object to the dirty map to avoid costly -// state object cache iteration to find a handful of modified ones. -func (self *StateDB) MarkStateObjectDirty(addr common.Address) { - self.stateObjectsDirty[addr] = struct{}{} -} - // createObject creates a new state object. If there is an existing account with // the given address, it is overwritten and returned as the second return value. func (self *StateDB) createObject(addr common.Address) (newobj, prev *stateObject) { prev = self.getStateObject(addr) - newobj = newObject(self, addr, Account{}, self.MarkStateObjectDirty) + newobj = newObject(self, addr, Account{}) newobj.setNonce(0) // sets the object to dirty if prev == nil { - self.journal = append(self.journal, createObjectChange{account: &addr}) + self.journal.append(createObjectChange{account: &addr}) } else { - self.journal = append(self.journal, resetObjectChange{prev: prev}) + self.journal.append(resetObjectChange{prev: prev}) } self.setStateObject(newobj) return newobj, prev @@ -474,18 +469,35 @@ func (self *StateDB) Copy() *StateDB { state := &StateDB{ db: self.db, trie: self.db.CopyTrie(self.trie), - stateObjects: make(map[common.Address]*stateObject, len(self.stateObjectsDirty)), - stateObjectsDirty: make(map[common.Address]struct{}, len(self.stateObjectsDirty)), + stateObjects: make(map[common.Address]*stateObject, len(self.journal.dirties)), + stateObjectsDirty: make(map[common.Address]struct{}, len(self.journal.dirties)), refund: self.refund, logs: make(map[common.Hash][]*types.Log, len(self.logs)), logSize: self.logSize, preimages: make(map[common.Hash][]byte), + journal: newJournal(), } // Copy the dirty states, logs, and preimages - for addr := range self.stateObjectsDirty { - state.stateObjects[addr] = self.stateObjects[addr].deepCopy(state, state.MarkStateObjectDirty) - state.stateObjectsDirty[addr] = struct{}{} + for addr := range self.journal.dirties { + // As documented [here](https://github.com/ethereum/go-ethereum/pull/16485#issuecomment-380438527), + // and in the Finalise-method, there is a case where an object is in the journal but not + // in the stateObjects: OOG after touch on ripeMD prior to Byzantium. Thus, we need to check for + // nil + if object, exist := self.stateObjects[addr]; exist { + state.stateObjects[addr] = object.deepCopy(state) + state.stateObjectsDirty[addr] = struct{}{} + } } + // Above, we don't copy the actual journal. This means that if the copy is copied, the + // loop above will be a no-op, since the copy's journal is empty. + // Thus, here we iterate over stateObjects, to enable copies of copies + for addr := range self.stateObjectsDirty { + if _, exist := state.stateObjects[addr]; !exist { + state.stateObjects[addr] = self.stateObjects[addr].deepCopy(state) + state.stateObjectsDirty[addr] = struct{}{} + } + } + for hash, logs := range self.logs { state.logs[hash] = make([]*types.Log, len(logs)) copy(state.logs[hash], logs) @@ -500,7 +512,7 @@ func (self *StateDB) Copy() *StateDB { func (self *StateDB) Snapshot() int { id := self.nextRevisionId self.nextRevisionId++ - self.validRevisions = append(self.validRevisions, revision{id, len(self.journal)}) + self.validRevisions = append(self.validRevisions, revision{id, self.journal.length()}) return id } @@ -515,13 +527,8 @@ func (self *StateDB) RevertToSnapshot(revid int) { } snapshot := self.validRevisions[idx].journalIndex - // Replay the journal to undo changes. - for i := len(self.journal) - 1; i >= snapshot; i-- { - self.journal[i].undo(self) - } - self.journal = self.journal[:snapshot] - - // Remove invalidated snapshots from the stack. + // Replay the journal to undo changes and remove invalidated snapshots + self.journal.revert(self, snapshot) self.validRevisions = self.validRevisions[:idx] } @@ -533,14 +540,25 @@ func (self *StateDB) GetRefund() uint64 { // Finalise finalises the state by removing the self destructed objects // and clears the journal as well as the refunds. func (s *StateDB) Finalise(deleteEmptyObjects bool) { - for addr := range s.stateObjectsDirty { - stateObject := s.stateObjects[addr] + for addr := range s.journal.dirties { + stateObject, exist := s.stateObjects[addr] + if !exist { + // ripeMD is 'touched' at block 1714175, in tx 0x1237f737031e40bcde4a8b7e717b2d15e3ecadfe49bb1bbc71ee9deb09c6fcf2 + // That tx goes out of gas, and although the notion of 'touched' does not exist there, the + // touch-event will still be recorded in the journal. Since ripeMD is a special snowflake, + // it will persist in the journal even though the journal is reverted. In this special circumstance, + // it may exist in `s.journal.dirties` but not in `s.stateObjects`. + // Thus, we can safely ignore it here + continue + } + if stateObject.suicided || (deleteEmptyObjects && stateObject.empty()) { s.deleteStateObject(stateObject) } else { stateObject.updateRoot(s.db) s.updateStateObject(stateObject) } + s.stateObjectsDirty[addr] = struct{}{} } // Invalidate journal because reverting across transactions is not allowed. s.clearJournalAndRefund() @@ -562,29 +580,8 @@ func (self *StateDB) Prepare(thash, bhash common.Hash, ti int) { self.txIndex = ti } -// DeleteSuicides flags the suicided objects for deletion so that it -// won't be referenced again when called / queried up on. -// -// DeleteSuicides should not be used for consensus related updates -// under any circumstances. -func (s *StateDB) DeleteSuicides() { - // Reset refund so that any used-gas calculations can use this method. - s.clearJournalAndRefund() - - for addr := range s.stateObjectsDirty { - stateObject := s.stateObjects[addr] - - // If the object has been removed by a suicide - // flag the object as deleted. - if stateObject.suicided { - stateObject.deleted = true - } - delete(s.stateObjectsDirty, addr) - } -} - func (s *StateDB) clearJournalAndRefund() { - s.journal = nil + s.journal = newJournal() s.validRevisions = s.validRevisions[:0] s.refund = 0 } @@ -593,6 +590,9 @@ func (s *StateDB) clearJournalAndRefund() { func (s *StateDB) Commit(deleteEmptyObjects bool) (root common.Hash, err error) { defer s.clearJournalAndRefund() + for addr := range s.journal.dirties { + s.stateObjectsDirty[addr] = struct{}{} + } // Commit objects to the trie. for addr, stateObject := range s.stateObjects { _, isDirty := s.stateObjectsDirty[addr] @@ -604,7 +604,7 @@ func (s *StateDB) Commit(deleteEmptyObjects bool) (root common.Hash, err error) case isDirty: // Write any contract code associated with the state object if stateObject.code != nil && stateObject.dirtyCode { - s.db.TrieDB().Insert(common.BytesToHash(stateObject.CodeHash()), stateObject.code) + s.db.TrieDB().InsertBlob(common.BytesToHash(stateObject.CodeHash()), stateObject.code) stateObject.dirtyCode = false } // Write any storage changes in the state object to its storage trie. diff --git a/core/state/statedb_test.go b/core/state/statedb_test.go index d9e3d9b797..e2b349de86 100644 --- a/core/state/statedb_test.go +++ b/core/state/statedb_test.go @@ -39,7 +39,7 @@ import ( // actually committing the state. func TestUpdateLeaks(t *testing.T) { // Create an empty state database - db, _ := ethdb.NewMemDatabase() + db := ethdb.NewMemDatabase() state, _ := New(common.Hash{}, NewDatabase(db)) // Update it with some accounts @@ -66,8 +66,8 @@ func TestUpdateLeaks(t *testing.T) { // only the one right before the commit. func TestIntermediateLeaks(t *testing.T) { // Create two state databases, one transitioning to the final state, the other final from the beginning - transDb, _ := ethdb.NewMemDatabase() - finalDb, _ := ethdb.NewMemDatabase() + transDb := ethdb.NewMemDatabase() + finalDb := ethdb.NewMemDatabase() transState, _ := New(common.Hash{}, NewDatabase(transDb)) finalState, _ := New(common.Hash{}, NewDatabase(finalDb)) @@ -122,8 +122,7 @@ func TestIntermediateLeaks(t *testing.T) { // https://github.com/ethereum/go-ethereum/pull/15549. func TestCopy(t *testing.T) { // Create a random state test to copy and modify "independently" - db, _ := ethdb.NewMemDatabase() - orig, _ := New(common.Hash{}, NewDatabase(db)) + orig, _ := New(common.Hash{}, NewDatabase(ethdb.NewMemDatabase())) for i := byte(0); i < 255; i++ { obj := orig.GetOrNewStateObject(common.BytesToAddress([]byte{i})) @@ -334,8 +333,7 @@ func (test *snapshotTest) String() string { func (test *snapshotTest) run() bool { // Run all actions and create snapshots. var ( - db, _ = ethdb.NewMemDatabase() - state, _ = New(common.Hash{}, NewDatabase(db)) + state, _ = New(common.Hash{}, NewDatabase(ethdb.NewMemDatabase())) snapshotRevs = make([]int, len(test.snapshots)) sindex = 0 ) @@ -413,11 +411,27 @@ func (s *StateSuite) TestTouchDelete(c *check.C) { snapshot := s.state.Snapshot() s.state.AddBalance(common.Address{}, new(big.Int)) - if len(s.state.stateObjectsDirty) != 1 { + + if len(s.state.journal.dirties) != 1 { c.Fatal("expected one dirty state object") } s.state.RevertToSnapshot(snapshot) - if len(s.state.stateObjectsDirty) != 0 { + if len(s.state.journal.dirties) != 0 { c.Fatal("expected no dirty state object") } } + +// TestCopyOfCopy tests that modified objects are carried over to the copy, and the copy of the copy. +// See https://github.com/ethereum/go-ethereum/pull/15225#issuecomment-380191512 +func TestCopyOfCopy(t *testing.T) { + sdb, _ := New(common.Hash{}, NewDatabase(ethdb.NewMemDatabase())) + addr := common.HexToAddress("aaaa") + sdb.SetBalance(addr, big.NewInt(42)) + + if got := sdb.Copy().GetBalance(addr).Uint64(); got != 42 { + t.Fatalf("1st copy fail, expected 42, got %v", got) + } + if got := sdb.Copy().Copy().GetBalance(addr).Uint64(); got != 42 { + t.Fatalf("2nd copy fail, expected 42, got %v", got) + } +} diff --git a/core/state/sync.go b/core/state/sync.go index 28fcf6ae05..c566e79073 100644 --- a/core/state/sync.go +++ b/core/state/sync.go @@ -25,8 +25,8 @@ import ( ) // NewStateSync create a new state trie download scheduler. -func NewStateSync(root common.Hash, database trie.DatabaseReader) *trie.TrieSync { - var syncer *trie.TrieSync +func NewStateSync(root common.Hash, database trie.DatabaseReader) *trie.Sync { + var syncer *trie.Sync callback := func(leaf []byte, parent common.Hash) error { var obj Account if err := rlp.Decode(bytes.NewReader(leaf), &obj); err != nil { @@ -36,6 +36,6 @@ func NewStateSync(root common.Hash, database trie.DatabaseReader) *trie.TrieSync syncer.AddRawEntry(common.BytesToHash(obj.CodeHash), 64, parent) return nil } - syncer = trie.NewTrieSync(root, database, callback) + syncer = trie.NewSync(root, database, callback) return syncer } diff --git a/core/state/sync_test.go b/core/state/sync_test.go index 8f14a44e7a..3177401608 100644 --- a/core/state/sync_test.go +++ b/core/state/sync_test.go @@ -38,8 +38,7 @@ type testAccount struct { // makeTestState create a sample test state to test node-wise reconstruction. func makeTestState() (Database, common.Hash, []*testAccount) { // Create an empty state - diskdb, _ := ethdb.NewMemDatabase() - db := NewDatabase(diskdb) + db := NewDatabase(ethdb.NewMemDatabase()) state, _ := New(common.Hash{}, db) // Fill it with some arbitrary data @@ -125,8 +124,7 @@ func checkStateConsistency(db ethdb.Database, root common.Hash) error { // Tests that an empty state is not scheduled for syncing. func TestEmptyStateSync(t *testing.T) { empty := common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421") - db, _ := ethdb.NewMemDatabase() - if req := NewStateSync(empty, db).Missing(1); len(req) != 0 { + if req := NewStateSync(empty, ethdb.NewMemDatabase()).Missing(1); len(req) != 0 { t.Errorf("content requested for empty state: %v", req) } } @@ -141,7 +139,7 @@ func testIterativeStateSync(t *testing.T, batch int) { srcDb, srcRoot, srcAccounts := makeTestState() // Create a destination state and sync with the scheduler - dstDb, _ := ethdb.NewMemDatabase() + dstDb := ethdb.NewMemDatabase() sched := NewStateSync(srcRoot, dstDb) queue := append([]common.Hash{}, sched.Missing(batch)...) @@ -173,7 +171,7 @@ func TestIterativeDelayedStateSync(t *testing.T) { srcDb, srcRoot, srcAccounts := makeTestState() // Create a destination state and sync with the scheduler - dstDb, _ := ethdb.NewMemDatabase() + dstDb := ethdb.NewMemDatabase() sched := NewStateSync(srcRoot, dstDb) queue := append([]common.Hash{}, sched.Missing(0)...) @@ -210,7 +208,7 @@ func testIterativeRandomStateSync(t *testing.T, batch int) { srcDb, srcRoot, srcAccounts := makeTestState() // Create a destination state and sync with the scheduler - dstDb, _ := ethdb.NewMemDatabase() + dstDb := ethdb.NewMemDatabase() sched := NewStateSync(srcRoot, dstDb) queue := make(map[common.Hash]struct{}) @@ -250,7 +248,7 @@ func TestIterativeRandomDelayedStateSync(t *testing.T) { srcDb, srcRoot, srcAccounts := makeTestState() // Create a destination state and sync with the scheduler - dstDb, _ := ethdb.NewMemDatabase() + dstDb := ethdb.NewMemDatabase() sched := NewStateSync(srcRoot, dstDb) queue := make(map[common.Hash]struct{}) @@ -297,7 +295,7 @@ func TestIncompleteStateSync(t *testing.T) { checkTrieConsistency(srcDb.TrieDB().DiskDB().(ethdb.Database), srcRoot) // Create a destination state and sync with the scheduler - dstDb, _ := ethdb.NewMemDatabase() + dstDb := ethdb.NewMemDatabase() sched := NewStateSync(srcRoot, dstDb) added := []common.Hash{} diff --git a/core/state_processor.go b/core/state_processor.go index c2df09f994..b803481399 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -137,7 +137,7 @@ func (p *StateProcessor) ProcessBlockNoValidator(cBlock *CalculatedBlock, stated // and uses the input parameters for its environment. It returns the receipt // for the transaction, gas used and an error if the transaction failed, // indicating the block was invalid. -func ApplyTransaction(config *params.ChainConfig, bc *BlockChain, author *common.Address, gp *GasPool, statedb *state.StateDB, header *types.Header, tx *types.Transaction, usedGas *uint64, cfg vm.Config) (*types.Receipt, uint64, error) { +func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *common.Address, gp *GasPool, statedb *state.StateDB, header *types.Header, tx *types.Transaction, usedGas *uint64, cfg vm.Config) (*types.Receipt, uint64, error) { if tx.To() != nil && tx.To().String() == common.BlockSigners && config.IsTIPSigning(header.Number) { return ApplySignTransaction(config, statedb, header, tx, usedGas) } diff --git a/core/state_transition.go b/core/state_transition.go index 23ab89190d..a188ed7d43 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -35,7 +35,7 @@ var ( The State Transitioning Model A state transition is a change made when a transaction is applied to the current world state -The state transitioning model does all all the necessary work to work out a valid new state root. +The state transitioning model does all the necessary work to work out a valid new state root. 1) Nonce handling 2) Pre pay gas @@ -131,7 +131,6 @@ func NewStateTransition(evm *vm.EVM, msg Message, gp *GasPool) *StateTransition func ApplyMessage(evm *vm.EVM, msg Message, gp *GasPool) ([]byte, uint64, bool, error) { return NewStateTransition(evm, msg, gp).TransitionDb() } - func (st *StateTransition) from() vm.AccountRef { f := st.msg.From() if !st.state.Exist(f) { @@ -140,20 +139,23 @@ func (st *StateTransition) from() vm.AccountRef { return vm.AccountRef(f) } -func (st *StateTransition) to() vm.AccountRef { - if st.msg == nil { - return vm.AccountRef{} +// to returns the recipient of the message. +func (st *StateTransition) to() common.Address { + if st.msg == nil || st.msg.To() == nil /* contract creation */ { + return common.Address{} } + // return *st.msg.To() to := st.msg.To() if to == nil { - return vm.AccountRef{} // contract creation + return common.Address{} // contract creation } - reference := vm.AccountRef(*to) + reference := common.Address(*to) if !st.state.Exist(*to) { st.state.CreateAccount(*to) } return reference + } func (st *StateTransition) useGas(amount uint64) error { @@ -166,12 +168,8 @@ func (st *StateTransition) useGas(amount uint64) error { } func (st *StateTransition) buyGas() error { - var ( - state = st.state - sender = st.from() - ) mgval := new(big.Int).Mul(new(big.Int).SetUint64(st.msg.Gas()), st.gasPrice) - if state.GetBalance(sender.Address()).Cmp(mgval) < 0 { + if st.state.GetBalance(st.msg.From()).Cmp(mgval) < 0 { return errInsufficientBalanceForGas } if err := st.gp.SubGas(st.msg.Gas()); err != nil { @@ -180,20 +178,17 @@ func (st *StateTransition) buyGas() error { st.gas += st.msg.Gas() st.initialGas = st.msg.Gas() - state.SubBalance(sender.Address(), mgval) + st.state.SubBalance(st.msg.From(), mgval) return nil } func (st *StateTransition) preCheck() error { - msg := st.msg - sender := st.from() - - // Make sure this transaction's nonce is correct - if msg.CheckNonce() { - nonce := st.state.GetNonce(sender.Address()) - if nonce < msg.Nonce() { + // Make sure this transaction's nonce is correct. + if st.msg.CheckNonce() { + nonce := st.state.GetNonce(st.msg.From()) + if nonce < st.msg.Nonce() { return ErrNonceTooHigh - } else if nonce > msg.Nonce() { + } else if nonce > st.msg.Nonce() { return ErrNonceTooLow } } @@ -201,15 +196,14 @@ func (st *StateTransition) preCheck() error { } // TransitionDb will transition the state by applying the current message and -// returning the result including the the used gas. It returns an error if it -// failed. An error indicates a consensus issue. +// returning the result including the used gas. It returns an error if failed. +// An error indicates a consensus issue. func (st *StateTransition) TransitionDb() (ret []byte, usedGas uint64, failed bool, err error) { if err = st.preCheck(); err != nil { return } msg := st.msg - sender := st.from() // err checked in preCheck - + sender := vm.AccountRef(msg.From()) homestead := st.evm.ChainConfig().IsHomestead(st.evm.BlockNumber) contractCreation := msg.To() == nil @@ -238,13 +232,11 @@ func (st *StateTransition) TransitionDb() (ret []byte, usedGas uint64, failed bo contractAction = "contract creation" } else { // Increment the nonce for the next transaction - nonce = st.state.GetNonce(sender.Address()) + 1 - st.state.SetNonce(sender.Address(), nonce) - ret, st.gas, vmerr = evm.Call(sender, st.to().Address(), st.data, st.gas, st.value) - contractAction = "contract call" + st.state.SetNonce(msg.From(), st.state.GetNonce(sender.Address())+1) + ret, st.gas, vmerr = evm.Call(sender, st.to(), st.data, st.gas, st.value) } if vmerr != nil { - log.Debug("VM returned with error", "action", contractAction, "contract address", st.to().Address(), "gas", st.gas, "gasPrice", st.gasPrice, "nonce", nonce, "err", vmerr) + log.Debug("VM returned with error", "action", contractAction, "contract address", "gas", st.gas, "gasPrice", st.gasPrice, "nonce", nonce, "err", vmerr) // The only possible consensus-error would be if there wasn't // sufficient balance to make the transfer happen. The first // balance transfer may never fail. @@ -267,10 +259,8 @@ func (st *StateTransition) refundGas() { st.gas += refund // Return ETH for remaining gas, exchanged at the original rate. - sender := st.from() - remaining := new(big.Int).Mul(new(big.Int).SetUint64(st.gas), st.gasPrice) - st.state.AddBalance(sender.Address(), remaining) + st.state.AddBalance(st.msg.From(), remaining) // Also return remaining gas to the block gas counter so it is // available for the next transaction. diff --git a/core/tx_cacher.go b/core/tx_cacher.go new file mode 100644 index 0000000000..6d989c83d9 --- /dev/null +++ b/core/tx_cacher.go @@ -0,0 +1,105 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package core + +import ( + "runtime" + + "github.com/ethereum/go-ethereum/core/types" +) + +// senderCacher is a concurrent tranaction sender recoverer anc cacher. +var senderCacher = newTxSenderCacher(runtime.NumCPU()) + +// txSenderCacherRequest is a request for recovering transaction senders with a +// specific signature scheme and caching it into the transactions themselves. +// +// The inc field defines the number of transactions to skip after each recovery, +// which is used to feed the same underlying input array to different threads but +// ensure they process the early transactions fast. +type txSenderCacherRequest struct { + signer types.Signer + txs []*types.Transaction + inc int +} + +// txSenderCacher is a helper structure to concurrently ecrecover transaction +// senders from digital signatures on background threads. +type txSenderCacher struct { + threads int + tasks chan *txSenderCacherRequest +} + +// newTxSenderCacher creates a new transaction sender background cacher and starts +// as many procesing goroutines as allowed by the GOMAXPROCS on construction. +func newTxSenderCacher(threads int) *txSenderCacher { + cacher := &txSenderCacher{ + tasks: make(chan *txSenderCacherRequest, threads), + threads: threads, + } + for i := 0; i < threads; i++ { + go cacher.cache() + } + return cacher +} + +// cache is an infinite loop, caching transaction senders from various forms of +// data structures. +func (cacher *txSenderCacher) cache() { + for task := range cacher.tasks { + for i := 0; i < len(task.txs); i += task.inc { + types.Sender(task.signer, task.txs[i]) + } + } +} + +// recover recovers the senders from a batch of transactions and caches them +// back into the same data structures. There is no validation being done, nor +// any reaction to invalid signatures. That is up to calling code later. +func (cacher *txSenderCacher) recover(signer types.Signer, txs []*types.Transaction) { + // If there's nothing to recover, abort + if len(txs) == 0 { + return + } + // Ensure we have meaningful task sizes and schedule the recoveries + tasks := cacher.threads + if len(txs) < tasks*4 { + tasks = (len(txs) + 3) / 4 + } + for i := 0; i < tasks; i++ { + cacher.tasks <- &txSenderCacherRequest{ + signer: signer, + txs: txs[i:], + inc: tasks, + } + } +} + +// recoverFromBlocks recovers the senders from a batch of blocks and caches them +// back into the same data structures. There is no validation being done, nor +// any reaction to invalid signatures. That is up to calling code later. +func (cacher *txSenderCacher) recoverFromBlocks(signer types.Signer, blocks []*types.Block) { + count := 0 + for _, block := range blocks { + count += len(block.Transactions()) + } + txs := make([]*types.Transaction, 0, count) + for _, block := range blocks { + txs = append(txs, block.Transactions()...) + } + cacher.recover(signer, txs) +} diff --git a/core/tx_journal.go b/core/tx_journal.go index e872d7b530..1397e9fd34 100644 --- a/core/tx_journal.go +++ b/core/tx_journal.go @@ -56,7 +56,7 @@ func newTxJournal(path string) *txJournal { // load parses a transaction journal dump from disk, loading its contents into // the specified pool. -func (journal *txJournal) load(add func(*types.Transaction) error) error { +func (journal *txJournal) load(add func([]*types.Transaction) []error) error { // Skip the parsing if the journal file doens't exist at all if _, err := os.Stat(journal.path); os.IsNotExist(err) { return nil @@ -76,7 +76,21 @@ func (journal *txJournal) load(add func(*types.Transaction) error) error { stream := rlp.NewStream(input, 0) total, dropped := 0, 0 - var failure error + // Create a method to load a limited batch of transactions and bump the + // appropriate progress counters. Then use this method to load all the + // journalled transactions in small-ish batches. + loadBatch := func(txs types.Transactions) { + for _, err := range add(txs) { + if err != nil { + log.Debug("Failed to add journaled transaction", "err", err) + dropped++ + } + } + } + var ( + failure error + batch types.Transactions + ) for { // Parse the next transaction and terminate on error tx := new(types.Transaction) @@ -84,14 +98,17 @@ func (journal *txJournal) load(add func(*types.Transaction) error) error { if err != io.EOF { failure = err } + if batch.Len() > 0 { + loadBatch(batch) + } break } - // Import the transaction and bump the appropriate progress counters + // New transaction parsed, queue up for later, import if threnshold is reached total++ - if err = add(tx); err != nil { - log.Debug("Failed to add journaled transaction", "err", err) - dropped++ - continue + + if batch = append(batch, tx); batch.Len() > 1024 { + loadBatch(batch) + batch = batch[:0] } } log.Info("Loaded local transaction journal", "transactions", total, "dropped", dropped) diff --git a/core/tx_list.go b/core/tx_list.go index 80bee54825..631a25a0a4 100644 --- a/core/tx_list.go +++ b/core/tx_list.go @@ -370,9 +370,20 @@ func (l *txList) Flatten() types.Transactions { // price-sorted transactions to discard when the pool fills up. type priceHeap []*types.Transaction -func (h priceHeap) Len() int { return len(h) } -func (h priceHeap) Less(i, j int) bool { return h[i].GasPrice().Cmp(h[j].GasPrice()) < 0 } -func (h priceHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] } +func (h priceHeap) Len() int { return len(h) } +func (h priceHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] } + +func (h priceHeap) Less(i, j int) bool { + // Sort primarily by price, returning the cheaper one + switch h[i].GasPrice().Cmp(h[j].GasPrice()) { + case -1: + return true + case 1: + return false + } + // If the prices match, stabilize via nonces (high nonce is worse) + return h[i].Nonce() > h[j].Nonce() +} func (h *priceHeap) Push(x interface{}) { *h = append(*h, x.(*types.Transaction)) @@ -389,13 +400,13 @@ func (h *priceHeap) Pop() interface{} { // txPricedList is a price-sorted heap to allow operating on transactions pool // contents in a price-incrementing way. type txPricedList struct { - all *map[common.Hash]*types.Transaction // Pointer to the map of all transactions - items *priceHeap // Heap of prices of all the stored transactions - stales int // Number of stale price points to (re-heap trigger) + all *txLookup // Pointer to the map of all transactions + items *priceHeap // Heap of prices of all the stored transactions + stales int // Number of stale price points to (re-heap trigger) } // newTxPricedList creates a new price-sorted transaction heap. -func newTxPricedList(all *map[common.Hash]*types.Transaction) *txPricedList { +func newTxPricedList(all *txLookup) *txPricedList { return &txPricedList{ all: all, items: new(priceHeap), @@ -417,17 +428,18 @@ func (l *txPricedList) Removed() { return } // Seems we've reached a critical number of stale transactions, reheap - reheap := make(priceHeap, 0, len(*l.all)) + reheap := make(priceHeap, 0, l.all.Count()) l.stales, l.items = 0, &reheap - for _, tx := range *l.all { + l.all.Range(func(hash common.Hash, tx *types.Transaction) bool { *l.items = append(*l.items, tx) - } + return true + }) heap.Init(l.items) } // Cap finds all the transactions below the given price threshold, drops them -// from the priced list and returs them for further removal from the entire pool. +// from the priced list and returns them for further removal from the entire pool. func (l *txPricedList) Cap(threshold *big.Int, local *accountSet) types.Transactions { drop := make(types.Transactions, 0, 128) // Remote underpriced transactions to drop save := make(types.Transactions, 0, 64) // Local underpriced transactions to keep @@ -435,7 +447,7 @@ func (l *txPricedList) Cap(threshold *big.Int, local *accountSet) types.Transact for len(*l.items) > 0 { // Discard stale transactions if found during cleanup tx := heap.Pop(l.items).(*types.Transaction) - if _, ok := (*l.all)[tx.Hash()]; !ok { + if l.all.Get(tx.Hash()) == nil { l.stales-- continue } @@ -467,7 +479,7 @@ func (l *txPricedList) Underpriced(tx *types.Transaction, local *accountSet) boo // Discard stale price points if found at the heap start for len(*l.items) > 0 { head := []*types.Transaction(*l.items)[0] - if _, ok := (*l.all)[head.Hash()]; !ok { + if l.all.Get(head.Hash()) == nil { l.stales-- heap.Pop(l.items) continue @@ -492,7 +504,7 @@ func (l *txPricedList) Discard(count int, local *accountSet) types.Transactions for len(*l.items) > 0 && count > 0 { // Discard stale transactions if found during cleanup tx := heap.Pop(l.items).(*types.Transaction) - if _, ok := (*l.all)[tx.Hash()]; !ok { + if l.all.Get(tx.Hash()) == nil { l.stales-- continue } diff --git a/core/tx_pool.go b/core/tx_pool.go index 2a66d9c2a1..0f6b5a1cb4 100644 --- a/core/tx_pool.go +++ b/core/tx_pool.go @@ -38,8 +38,6 @@ import ( const ( // chainHeadChanSize is the size of channel listening to ChainHeadEvent. chainHeadChanSize = 10 - // rmTxChanSize is the size of channel listening to RemovedTransactionEvent. - rmTxChanSize = 10 ) var ( @@ -140,7 +138,7 @@ type TxPoolConfig struct { PriceLimit uint64 // Minimum gas price to enforce for acceptance into the pool PriceBump uint64 // Minimum price bump percentage to replace an already existing transaction (nonce) - AccountSlots uint64 // Minimum number of executable transaction slots guaranteed per account + AccountSlots uint64 // Number of executable transaction slots guaranteed per account GlobalSlots uint64 // Maximum number of executable transaction slots for all accounts AccountQueue uint64 // Maximum number of non-executable transaction slots permitted per account GlobalQueue uint64 // Maximum number of non-executable transaction slots for all accounts @@ -210,11 +208,11 @@ type TxPool struct { locals *accountSet // Set of local transaction to exempt from eviction rules journal *txJournal // Journal of local transaction to back up to disk - pending map[common.Address]*txList // All currently processable transactions - queue map[common.Address]*txList // Queued but non-processable transactions - beats map[common.Address]time.Time // Last heartbeat from each known account - all map[common.Hash]*types.Transaction // All transactions to allow lookups - priced *txPricedList // All transactions sorted by price + pending map[common.Address]*txList // All currently processable transactions + queue map[common.Address]*txList // Queued but non-processable transactions + beats map[common.Address]time.Time // Last heartbeat from each known account + all *txLookup // All transactions to allow lookups + priced *txPricedList // All transactions sorted by price wg sync.WaitGroup // for shutdown sync @@ -233,23 +231,23 @@ func NewTxPool(config TxPoolConfig, chainconfig *params.ChainConfig, chain block config: config, chainconfig: chainconfig, chain: chain, - signer: types.NewEIP155Signer(chainconfig.ChainId), + signer: types.NewEIP155Signer(chainconfig.ChainID), pending: make(map[common.Address]*txList), queue: make(map[common.Address]*txList), beats: make(map[common.Address]time.Time), - all: make(map[common.Hash]*types.Transaction), + all: newTxLookup(), chainHeadCh: make(chan ChainHeadEvent, chainHeadChanSize), gasPrice: new(big.Int).SetUint64(config.PriceLimit), } pool.locals = newAccountSet(pool.signer) - pool.priced = newTxPricedList(&pool.all) + pool.priced = newTxPricedList(pool.all) pool.reset(nil, chain.CurrentBlock().Header()) // If local transactions and journaling is enabled, load from disk if !config.NoLocals && config.Journal != "" { pool.journal = newTxJournal(config.Journal) - if err := pool.journal.load(pool.AddLocal); err != 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 { @@ -329,7 +327,7 @@ func (pool *TxPool) loop() { // Any non-locals old enough should be removed if time.Since(pool.beats[addr]) > pool.config.Lifetime { for _, tx := range pool.queue[addr].Flatten() { - pool.removeTx(tx.Hash()) + pool.removeTx(tx.Hash(), true) } } } @@ -422,6 +420,7 @@ func (pool *TxPool) reset(oldHead, newHead *types.Header) { // Inject any transactions discarded due to reorgs log.Debug("Reinjecting stale transactions", "count", len(reinject)) + senderCacher.recover(pool.signer, reinject) pool.addTxsLocked(reinject, false) // validate the pool of pending transactions, this will remove @@ -455,9 +454,9 @@ func (pool *TxPool) Stop() { log.Info("Transaction pool stopped") } -// SubscribeTxPreEvent registers a subscription of TxPreEvent and +// SubscribeNewTxsEvent registers a subscription of NewTxsEvent and // starts sending event to the given channel. -func (pool *TxPool) SubscribeTxPreEvent(ch chan<- TxPreEvent) event.Subscription { +func (pool *TxPool) SubscribeNewTxsEvent(ch chan<- NewTxsEvent) event.Subscription { return pool.scope.Track(pool.txFeed.Subscribe(ch)) } @@ -477,7 +476,7 @@ func (pool *TxPool) SetGasPrice(price *big.Int) { pool.gasPrice = price for _, tx := range pool.priced.Cap(price, pool.locals) { - pool.removeTx(tx.Hash()) + pool.removeTx(tx.Hash(), false) } log.Info("Transaction pool price threshold updated", "price", price) } @@ -649,7 +648,7 @@ func (pool *TxPool) validateTx(tx *types.Transaction, local bool) error { func (pool *TxPool) add(tx *types.Transaction, local bool) (bool, error) { // If the transaction is already known, discard it hash := tx.Hash() - if pool.all[hash] != nil { + if pool.all.Get(hash) != nil { log.Trace("Discarding already known transaction", "hash", hash) return false, fmt.Errorf("known transaction: %x", hash) } @@ -665,20 +664,19 @@ func (pool *TxPool) add(tx *types.Transaction, local bool) (bool, error) { return pool.promoteSpecialTx(from, tx) } // If the transaction pool is full, discard underpriced transactions - if uint64(len(pool.all)) >= pool.config.GlobalSlots+pool.config.GlobalQueue { - log.Debug("Add transaction to pool full", "hash", hash, "nonce", tx.Nonce()) + if uint64(pool.all.Count()) >= pool.config.GlobalSlots+pool.config.GlobalQueue { // If the new transaction is underpriced, don't accept it - if pool.priced.Underpriced(tx, pool.locals) { + if !local && pool.priced.Underpriced(tx, pool.locals) { log.Trace("Discarding underpriced transaction", "hash", hash, "price", tx.GasPrice()) underpricedTxCounter.Inc(1) return false, ErrUnderpriced } // New transaction is better than our worse ones, make room for it - drop := pool.priced.Discard(len(pool.all)-int(pool.config.GlobalSlots+pool.config.GlobalQueue-1), pool.locals) + drop := pool.priced.Discard(pool.all.Count()-int(pool.config.GlobalSlots+pool.config.GlobalQueue-1), pool.locals) for _, tx := range drop { log.Trace("Discarding freshly underpriced transaction", "hash", tx.Hash(), "price", tx.GasPrice()) underpricedTxCounter.Inc(1) - pool.removeTx(tx.Hash()) + pool.removeTx(tx.Hash(), false) } } // If the transaction is replacing an already pending one, do directly @@ -691,18 +689,18 @@ func (pool *TxPool) add(tx *types.Transaction, local bool) (bool, error) { } // New transaction is better, replace old one if old != nil { - delete(pool.all, old.Hash()) + pool.all.Remove(old.Hash()) pool.priced.Removed() pendingReplaceCounter.Inc(1) } - pool.all[tx.Hash()] = tx + pool.all.Add(tx) pool.priced.Put(tx) pool.journalTx(from, tx) log.Trace("Pooled new executable transaction", "hash", hash, "from", from, "to", tx.To()) // We've directly injected a replacement transaction, notify subsystems - go pool.txFeed.Send(TxPreEvent{tx}) + go pool.txFeed.Send(NewTxsEvent{types.Transactions{tx}}) return old != nil, nil } @@ -738,12 +736,14 @@ func (pool *TxPool) enqueueTx(hash common.Hash, tx *types.Transaction) (bool, er } // Discard any previous transaction and mark this if old != nil { - delete(pool.all, old.Hash()) + pool.all.Remove(old.Hash()) pool.priced.Removed() queuedReplaceCounter.Inc(1) } - pool.all[hash] = tx - pool.priced.Put(tx) + if pool.all.Get(hash) == nil { + pool.all.Add(tx) + pool.priced.Put(tx) + } return old != nil, nil } @@ -759,10 +759,11 @@ func (pool *TxPool) journalTx(from common.Address, tx *types.Transaction) { } } -// promoteTx adds a transaction to the pending (processable) list of transactions. +// promoteTx adds a transaction to the pending (processable) list of transactions +// and returns whether it was inserted or an older was better. // // Note, this method assumes the pool lock is held! -func (pool *TxPool) promoteTx(addr common.Address, hash common.Hash, tx *types.Transaction) { +func (pool *TxPool) promoteTx(addr common.Address, hash common.Hash, tx *types.Transaction) bool { // Try to insert the transaction into the pending queue if pool.pending[addr] == nil { pool.pending[addr] = newTxList(true) @@ -772,29 +773,29 @@ func (pool *TxPool) promoteTx(addr common.Address, hash common.Hash, tx *types.T inserted, old := list.Add(tx, pool.config.PriceBump) if !inserted { // An older transaction was better, discard this - delete(pool.all, hash) + pool.all.Remove(hash) pool.priced.Removed() pendingDiscardCounter.Inc(1) - return + return false } // Otherwise discard any previous transaction and mark this if old != nil { - delete(pool.all, old.Hash()) + pool.all.Remove(old.Hash()) pool.priced.Removed() pendingReplaceCounter.Inc(1) } // Failsafe to work around direct pending inserts (tests) - if pool.all[hash] == nil { - pool.all[hash] = tx + if pool.all.Get(hash) == nil { + pool.all.Add(tx) pool.priced.Put(tx) } // Set the potentially new pending nonce and notify any subsystems of the new tx pool.beats[addr] = time.Now() pool.pendingState.SetNonce(addr, tx.Nonce()+1) - go pool.txFeed.Send(TxPreEvent{tx}) + return true } func (pool *TxPool) promoteSpecialTx(addr common.Address, tx *types.Transaction) (bool, error) { @@ -809,7 +810,7 @@ func (pool *TxPool) promoteSpecialTx(addr common.Address, tx *types.Transaction) } // Otherwise discard any previous transaction and mark this if old != nil { - delete(pool.all, old.Hash()) + pool.all.Remove(old.Hash()) pool.priced.Removed() pendingReplaceCounter.Inc(1) } @@ -821,13 +822,15 @@ func (pool *TxPool) promoteSpecialTx(addr common.Address, tx *types.Transaction) list.gascap = gas } // Failsafe to work around direct pending inserts (tests) - if pool.all[tx.Hash()] == nil { - pool.all[tx.Hash()] = tx + // if pool.all[tx.Hash()] == nil { + // pool.all[tx.Hash()] = tx + if pool.all.Get(tx.Hash()) == nil { + pool.all.Add(tx) } // Set the potentially new pending nonce and notify any subsystems of the new tx pool.beats[addr] = time.Now() pool.pendingState.SetNonce(addr, tx.Nonce()+1) - go pool.txFeed.Send(TxPreEvent{tx}) + go pool.txFeed.Send(NewTxsEvent{types.Transactions{tx}}) return true, nil } @@ -896,11 +899,9 @@ func (pool *TxPool) addTxsLocked(txs []*types.Transaction, local bool) []error { for i, tx := range txs { var replace bool - if replace, errs[i] = pool.add(tx, local); errs[i] == nil { - if !replace { - from, _ := types.Sender(pool.signer, tx) // already validated - dirty[from] = struct{}{} - } + if replace, errs[i] = pool.add(tx, local); errs[i] == nil && !replace { + from, _ := types.Sender(pool.signer, tx) // already validated + dirty[from] = struct{}{} } } // Only reprocess the internal state if something was actually added @@ -922,7 +923,7 @@ func (pool *TxPool) Status(hashes []common.Hash) []TxStatus { status := make([]TxStatus, len(hashes)) for i, hash := range hashes { - if tx := pool.all[hash]; tx != nil { + if tx := pool.all.Get(hash); tx != nil { from, _ := types.Sender(pool.signer, tx) // already validated if pool.pending[from] != nil && pool.pending[from].txs.items[tx.Nonce()] != nil { status[i] = TxStatusPending @@ -937,26 +938,24 @@ func (pool *TxPool) Status(hashes []common.Hash) []TxStatus { // Get returns a transaction if it is contained in the pool // and nil otherwise. func (pool *TxPool) Get(hash common.Hash) *types.Transaction { - pool.mu.RLock() - defer pool.mu.RUnlock() - - return pool.all[hash] + return pool.all.Get(hash) } // removeTx removes a single transaction from the queue, moving all subsequent // transactions back to the future queue. -func (pool *TxPool) removeTx(hash common.Hash) { +func (pool *TxPool) removeTx(hash common.Hash, outofbound bool) { // Fetch the transaction we wish to delete - tx, ok := pool.all[hash] - if !ok { + tx := pool.all.Get(hash) + if tx == nil { return } addr, _ := types.Sender(pool.signer, tx) // already validated during insertion // Remove it from the list of known transactions - delete(pool.all, hash) - pool.priced.Removed() - + pool.all.Remove(hash) + if outofbound { + pool.priced.Removed() + } // 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 { @@ -989,6 +988,9 @@ func (pool *TxPool) removeTx(hash common.Hash) { // future queue to the set of pending transactions. During this process, all // invalidated transactions (low nonce, low balance) are deleted. func (pool *TxPool) promoteExecutables(accounts []common.Address) { + // Track the promoted transactions to broadcast them at once + var promoted []*types.Transaction + // Gather all the accounts potentially needing updates if accounts == nil { accounts = make([]common.Address, 0, len(pool.queue)) @@ -1006,7 +1008,7 @@ func (pool *TxPool) promoteExecutables(accounts []common.Address) { for _, tx := range list.Forward(pool.currentState.GetNonce(addr)) { hash := tx.Hash() log.Trace("Removed old queued transaction", "hash", hash) - delete(pool.all, hash) + pool.all.Remove(hash) pool.priced.Removed() } // Drop all transactions that are too costly (low balance or out of gas) @@ -1014,21 +1016,23 @@ func (pool *TxPool) promoteExecutables(accounts []common.Address) { for _, tx := range drops { hash := tx.Hash() log.Trace("Removed unpayable queued transaction", "hash", hash) - delete(pool.all, hash) + pool.all.Remove(hash) pool.priced.Removed() queuedNofundsCounter.Inc(1) } // Gather all executable transactions and promote them for _, tx := range list.Ready(pool.pendingState.GetNonce(addr)) { hash := tx.Hash() - log.Trace("Promoting queued transaction", "hash", hash) - pool.promoteTx(addr, hash, tx) + if pool.promoteTx(addr, hash, tx) { + log.Trace("Promoting queued transaction", "hash", hash) + promoted = append(promoted, tx) + } } // Drop all transactions over the allowed limit if !pool.locals.contains(addr) { for _, tx := range list.Cap(int(pool.config.AccountQueue)) { hash := tx.Hash() - delete(pool.all, hash) + pool.all.Remove(hash) pool.priced.Removed() queuedRateLimitCounter.Inc(1) log.Trace("Removed cap-exceeding queued transaction", "hash", hash) @@ -1039,6 +1043,10 @@ func (pool *TxPool) promoteExecutables(accounts []common.Address) { delete(pool.queue, addr) } } + // Notify subsystem for new promoted transactions. + if len(promoted) > 0 { + go pool.txFeed.Send(NewTxsEvent{promoted}) + } // If the pending limit is overflown, start equalizing allowances pending := uint64(0) for _, list := range pool.pending { @@ -1073,7 +1081,7 @@ func (pool *TxPool) promoteExecutables(accounts []common.Address) { for _, tx := range list.Cap(list.Len() - 1) { // Drop the transaction from the global pools too hash := tx.Hash() - delete(pool.all, hash) + pool.all.Remove(hash) pool.priced.Removed() // Update the account nonce to the dropped transaction @@ -1095,7 +1103,7 @@ func (pool *TxPool) promoteExecutables(accounts []common.Address) { for _, tx := range list.Cap(list.Len() - 1) { // Drop the transaction from the global pools too hash := tx.Hash() - delete(pool.all, hash) + pool.all.Remove(hash) pool.priced.Removed() // Update the account nonce to the dropped transaction @@ -1117,7 +1125,7 @@ func (pool *TxPool) promoteExecutables(accounts []common.Address) { } if queued > pool.config.GlobalQueue { // Sort all accounts with queued transactions by heartbeat - addresses := make(addresssByHeartbeat, 0, len(pool.queue)) + 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]}) @@ -1135,7 +1143,7 @@ func (pool *TxPool) promoteExecutables(accounts []common.Address) { // Drop all transactions if they are less than the overflow if size := uint64(list.Len()); size <= drop { for _, tx := range list.Flatten() { - pool.removeTx(tx.Hash()) + pool.removeTx(tx.Hash(), true) } drop -= size queuedRateLimitCounter.Inc(int64(size)) @@ -1144,7 +1152,7 @@ func (pool *TxPool) promoteExecutables(accounts []common.Address) { // Otherwise drop only last few transactions txs := list.Flatten() for i := len(txs) - 1; i >= 0 && drop > 0; i-- { - pool.removeTx(txs[i].Hash()) + pool.removeTx(txs[i].Hash(), true) drop-- queuedRateLimitCounter.Inc(1) } @@ -1164,7 +1172,7 @@ func (pool *TxPool) demoteUnexecutables() { for _, tx := range list.Forward(nonce) { hash := tx.Hash() log.Trace("Removed old pending transaction", "hash", hash) - delete(pool.all, hash) + pool.all.Remove(hash) pool.priced.Removed() } // Drop all transactions that are too costly (low balance or out of gas), and queue any invalids back for later @@ -1172,7 +1180,7 @@ func (pool *TxPool) demoteUnexecutables() { for _, tx := range drops { hash := tx.Hash() log.Trace("Removed unpayable pending transaction", "hash", hash) - delete(pool.all, hash) + pool.all.Remove(hash) pool.priced.Removed() pendingNofundsCounter.Inc(1) } @@ -1181,7 +1189,7 @@ func (pool *TxPool) demoteUnexecutables() { log.Trace("Demoting pending transaction", "hash", hash) pool.enqueueTx(hash, tx) } - // If there's a gap in front, warn (should never happen) and postpone all transactions + // If there's a gap in front, alert (should never happen) and postpone all transactions if list.Len() > 0 && list.txs.Get(nonce) == nil { for _, tx := range list.Cap(0) { hash := tx.Hash() @@ -1203,11 +1211,11 @@ type addressByHeartbeat struct { heartbeat time.Time } -type addresssByHeartbeat []addressByHeartbeat +type addressesByHeartbeat []addressByHeartbeat -func (a addresssByHeartbeat) Len() int { return len(a) } -func (a addresssByHeartbeat) Less(i, j int) bool { return a[i].heartbeat.Before(a[j].heartbeat) } -func (a addresssByHeartbeat) Swap(i, j int) { a[i], a[j] = a[j], a[i] } +func (a addressesByHeartbeat) Len() int { return len(a) } +func (a addressesByHeartbeat) Less(i, j int) bool { return a[i].heartbeat.Before(a[j].heartbeat) } +func (a addressesByHeartbeat) Swap(i, j int) { a[i], a[j] = a[j], a[i] } // accountSet is simply a set of addresses to check for existence, and a signer // capable of deriving addresses from transactions. @@ -1244,3 +1252,68 @@ func (as *accountSet) containsTx(tx *types.Transaction) bool { func (as *accountSet) add(addr common.Address) { as.accounts[addr] = struct{}{} } + +// txLookup is used internally by TxPool to track transactions while allowing lookup without +// mutex contention. +// +// Note, although this type is properly protected against concurrent access, it +// is **not** a type that should ever be mutated or even exposed outside of the +// transaction pool, since its internal state is tightly coupled with the pools +// internal mechanisms. The sole purpose of the type is to permit out-of-bound +// peeking into the pool in TxPool.Get without having to acquire the widely scoped +// TxPool.mu mutex. +type txLookup struct { + all map[common.Hash]*types.Transaction + lock sync.RWMutex +} + +// newTxLookup returns a new txLookup structure. +func newTxLookup() *txLookup { + return &txLookup{ + all: make(map[common.Hash]*types.Transaction), + } +} + +// Range calls f on each key and value present in the map. +func (t *txLookup) Range(f func(hash common.Hash, tx *types.Transaction) bool) { + t.lock.RLock() + defer t.lock.RUnlock() + + for key, value := range t.all { + if !f(key, value) { + break + } + } +} + +// Get returns a transaction if it exists in the lookup, or nil if not found. +func (t *txLookup) Get(hash common.Hash) *types.Transaction { + t.lock.RLock() + defer t.lock.RUnlock() + + return t.all[hash] +} + +// Count returns the current number of items in the lookup. +func (t *txLookup) Count() int { + t.lock.RLock() + defer t.lock.RUnlock() + + return len(t.all) +} + +// Add adds a transaction to the lookup. +func (t *txLookup) Add(tx *types.Transaction) { + t.lock.Lock() + defer t.lock.Unlock() + + t.all[tx.Hash()] = tx +} + +// Remove removes a transaction from the lookup. +func (t *txLookup) Remove(hash common.Hash) { + t.lock.Lock() + defer t.lock.Unlock() + + delete(t.all, hash) +} diff --git a/core/tx_pool_test.go b/core/tx_pool_test.go index a4bd7ba83e..bf88b1a448 100644 --- a/core/tx_pool_test.go +++ b/core/tx_pool_test.go @@ -78,8 +78,7 @@ func pricedTransaction(nonce uint64, gaslimit uint64, gasprice *big.Int, key *ec } func setupTxPool() (*TxPool, *ecdsa.PrivateKey) { - diskdb, _ := ethdb.NewMemDatabase() - statedb, _ := state.New(common.Hash{}, state.NewDatabase(diskdb)) + statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} key, _ := crypto.GenerateKey() @@ -95,7 +94,7 @@ func validateTxPoolInternals(pool *TxPool) error { // Ensure the total transaction set is consistent with pending + queued pending, queued := pool.stats() - if total := len(pool.all); total != pending+queued { + if total := pool.all.Count(); total != pending+queued { return fmt.Errorf("total transaction count %d != %d pending + %d queued", total, pending, queued) } if priced := pool.priced.items.Len() - pool.priced.stales; priced != pending+queued { @@ -119,21 +118,27 @@ func validateTxPoolInternals(pool *TxPool) error { // validateEvents checks that the correct number of transaction addition events // were fired on the pool's event feed. -func validateEvents(events chan TxPreEvent, count int) error { - for i := 0; i < count; i++ { +func validateEvents(events chan NewTxsEvent, count int) error { + var received []*types.Transaction + + for len(received) < count { select { - case <-events: + case ev := <-events: + received = append(received, ev.Txs...) case <-time.After(time.Second): - return fmt.Errorf("event #%d not fired", i) + return fmt.Errorf("event #%d not fired", received) } } + if len(received) > count { + return fmt.Errorf("more than %d events fired: %v", count, received[count:]) + } select { - case tx := <-events: - return fmt.Errorf("more than %d events fired: %v", count, tx.Tx) + case ev := <-events: + return fmt.Errorf("more than %d events fired: %v", count, ev.Txs) case <-time.After(50 * time.Millisecond): // This branch should be "default", but it's a data race between goroutines, - // reading the event channel and pushng into it, so better wait a bit ensuring + // reading the event channel and pushing into it, so better wait a bit ensuring // really nothing gets injected. } return nil @@ -158,8 +163,7 @@ func (c *testChain) State() (*state.StateDB, error) { // a state change between those fetches. stdb := c.statedb if *c.trigger { - db, _ := ethdb.NewMemDatabase() - c.statedb, _ = state.New(common.Hash{}, state.NewDatabase(db)) + c.statedb, _ = state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) // simulate that the new head block included tx0 and tx1 c.statedb.SetNonce(c.address, 2) c.statedb.SetBalance(c.address, new(big.Int).SetUint64(params.Ether)) @@ -175,10 +179,9 @@ func TestStateChangeDuringTransactionPoolReset(t *testing.T) { t.Parallel() var ( - db, _ = ethdb.NewMemDatabase() key, _ = crypto.GenerateKey() address = crypto.PubkeyToAddress(key.PublicKey) - statedb, _ = state.New(common.Hash{}, state.NewDatabase(db)) + statedb, _ = state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) trigger = false ) @@ -209,15 +212,10 @@ func TestStateChangeDuringTransactionPoolReset(t *testing.T) { pool.lockedReset(nil, nil) - pendingTx, err := pool.Pending() + _, err := pool.Pending() if err != nil { t.Fatalf("Could not fetch pending transactions: %v", err) } - - for addr, txs := range pendingTx { - t.Logf("%0x: %d\n", addr, len(txs)) - } - nonce = pool.State().GetNonce(address) if nonce != 2 { t.Fatalf("Invalid nonce, want 2, got %d", nonce) @@ -337,8 +335,7 @@ func TestTransactionChainFork(t *testing.T) { addr := crypto.PubkeyToAddress(key.PublicKey) resetState := func() { - db, _ := ethdb.NewMemDatabase() - statedb, _ := state.New(common.Hash{}, state.NewDatabase(db)) + statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) statedb.AddBalance(addr, big.NewInt(100000000000000)) pool.chain = &testBlockChain{statedb, 1000000, new(event.Feed)} @@ -350,7 +347,7 @@ func TestTransactionChainFork(t *testing.T) { if _, err := pool.add(tx, false); err != nil { t.Error("didn't expect error", err) } - pool.removeTx(tx.Hash()) + pool.removeTx(tx.Hash(), true) // reset the pool's internal state resetState() @@ -367,8 +364,7 @@ func TestTransactionDoubleNonce(t *testing.T) { addr := crypto.PubkeyToAddress(key.PublicKey) resetState := func() { - db, _ := ethdb.NewMemDatabase() - statedb, _ := state.New(common.Hash{}, state.NewDatabase(db)) + statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) statedb.AddBalance(addr, big.NewInt(100000000000000)) pool.chain = &testBlockChain{statedb, 1000000, new(event.Feed)} @@ -405,8 +401,8 @@ func TestTransactionDoubleNonce(t *testing.T) { t.Errorf("transaction mismatch: have %x, want %x", tx.Hash(), tx2.Hash()) } // Ensure the total transaction count is correct - if len(pool.all) != 1 { - t.Error("expected 1 total transactions, got", len(pool.all)) + if pool.all.Count() != 1 { + t.Error("expected 1 total transactions, got", pool.all.Count()) } } @@ -428,8 +424,8 @@ func TestTransactionMissingNonce(t *testing.T) { if pool.queue[addr].Len() != 1 { t.Error("expected 1 queued transaction, got", pool.queue[addr].Len()) } - if len(pool.all) != 1 { - t.Error("expected 1 total transactions, got", len(pool.all)) + if pool.all.Count() != 1 { + t.Error("expected 1 total transactions, got", pool.all.Count()) } } @@ -492,8 +488,8 @@ func TestTransactionDropping(t *testing.T) { if pool.queue[account].Len() != 3 { t.Errorf("queued transaction mismatch: have %d, want %d", pool.queue[account].Len(), 3) } - if len(pool.all) != 6 { - t.Errorf("total transaction mismatch: have %d, want %d", len(pool.all), 6) + if pool.all.Count() != 6 { + t.Errorf("total transaction mismatch: have %d, want %d", pool.all.Count(), 6) } pool.lockedReset(nil, nil) if pool.pending[account].Len() != 3 { @@ -502,8 +498,8 @@ func TestTransactionDropping(t *testing.T) { if pool.queue[account].Len() != 3 { t.Errorf("queued transaction mismatch: have %d, want %d", pool.queue[account].Len(), 3) } - if len(pool.all) != 6 { - t.Errorf("total transaction mismatch: have %d, want %d", len(pool.all), 6) + if pool.all.Count() != 6 { + t.Errorf("total transaction mismatch: have %d, want %d", pool.all.Count(), 6) } // Reduce the balance of the account, and check that invalidated transactions are dropped pool.currentState.AddBalance(account, big.NewInt(-650)) @@ -527,8 +523,8 @@ func TestTransactionDropping(t *testing.T) { if _, ok := pool.queue[account].txs.items[tx12.Nonce()]; ok { t.Errorf("out-of-fund queued transaction present: %v", tx11) } - if len(pool.all) != 4 { - t.Errorf("total transaction mismatch: have %d, want %d", len(pool.all), 4) + if pool.all.Count() != 4 { + t.Errorf("total transaction mismatch: have %d, want %d", pool.all.Count(), 4) } // Reduce the block gas limit, check that invalidated transactions are dropped pool.chain.(*testBlockChain).gasLimit = 100 @@ -546,8 +542,8 @@ func TestTransactionDropping(t *testing.T) { if _, ok := pool.queue[account].txs.items[tx11.Nonce()]; ok { t.Errorf("over-gased queued transaction present: %v", tx11) } - if len(pool.all) != 2 { - t.Errorf("total transaction mismatch: have %d, want %d", len(pool.all), 2) + if pool.all.Count() != 2 { + t.Errorf("total transaction mismatch: have %d, want %d", pool.all.Count(), 2) } } @@ -558,8 +554,7 @@ func TestTransactionPostponing(t *testing.T) { t.Parallel() // Create the pool to test the postponing with - db, _ := ethdb.NewMemDatabase() - statedb, _ := state.New(common.Hash{}, state.NewDatabase(db)) + statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain) @@ -601,8 +596,8 @@ func TestTransactionPostponing(t *testing.T) { if len(pool.queue) != 0 { t.Errorf("queued accounts mismatch: have %d, want %d", len(pool.queue), 0) } - if len(pool.all) != len(txs) { - t.Errorf("total transaction mismatch: have %d, want %d", len(pool.all), len(txs)) + if pool.all.Count() != len(txs) { + t.Errorf("total transaction mismatch: have %d, want %d", pool.all.Count(), len(txs)) } pool.lockedReset(nil, nil) if pending := pool.pending[accs[0]].Len() + pool.pending[accs[1]].Len(); pending != len(txs) { @@ -611,8 +606,8 @@ func TestTransactionPostponing(t *testing.T) { if len(pool.queue) != 0 { t.Errorf("queued accounts mismatch: have %d, want %d", len(pool.queue), 0) } - if len(pool.all) != len(txs) { - t.Errorf("total transaction mismatch: have %d, want %d", len(pool.all), len(txs)) + if pool.all.Count() != len(txs) { + t.Errorf("total transaction mismatch: have %d, want %d", pool.all.Count(), len(txs)) } // Reduce the balance of the account, and check that transactions are reorganised for _, addr := range accs { @@ -661,8 +656,8 @@ func TestTransactionPostponing(t *testing.T) { } } } - if len(pool.all) != len(txs)/2 { - t.Errorf("total transaction mismatch: have %d, want %d", len(pool.all), len(txs)/2) + if pool.all.Count() != len(txs)/2 { + t.Errorf("total transaction mismatch: have %d, want %d", pool.all.Count(), len(txs)/2) } } @@ -680,7 +675,7 @@ func TestTransactionGapFilling(t *testing.T) { pool.currentState.AddBalance(account, big.NewInt(1000000)) // Keep track of transaction events to ensure all executables get announced - events := make(chan TxPreEvent, testTxPoolConfig.AccountQueue+5) + events := make(chan NewTxsEvent, testTxPoolConfig.AccountQueue+5) sub := pool.txFeed.Subscribe(events) defer sub.Unsubscribe() @@ -753,8 +748,8 @@ func TestTransactionQueueAccountLimiting(t *testing.T) { } } } - if len(pool.all) != int(testTxPoolConfig.AccountQueue) { - t.Errorf("total transaction mismatch: have %d, want %d", len(pool.all), testTxPoolConfig.AccountQueue) + if pool.all.Count() != int(testTxPoolConfig.AccountQueue) { + t.Errorf("total transaction mismatch: have %d, want %d", pool.all.Count(), testTxPoolConfig.AccountQueue) } } @@ -774,8 +769,7 @@ func testTransactionQueueGlobalLimiting(t *testing.T, nolocals bool) { t.Parallel() // Create the pool to test the limit enforcement with - db, _ := ethdb.NewMemDatabase() - statedb, _ := state.New(common.Hash{}, state.NewDatabase(db)) + statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} config := testTxPoolConfig @@ -864,8 +858,7 @@ func testTransactionQueueTimeLimiting(t *testing.T, nolocals bool) { evictionInterval = time.Second // Create the pool to test the non-expiration enforcement - db, _ := ethdb.NewMemDatabase() - statedb, _ := state.New(common.Hash{}, state.NewDatabase(db)) + statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} config := testTxPoolConfig @@ -934,7 +927,7 @@ func TestTransactionPendingLimiting(t *testing.T) { pool.currentState.AddBalance(account, big.NewInt(1000000)) testTxPoolConfig.AccountQueue = 10 // Keep track of transaction events to ensure all executables get announced - events := make(chan TxPreEvent, testTxPoolConfig.AccountQueue) + events := make(chan NewTxsEvent, testTxPoolConfig.AccountQueue+5) sub := pool.txFeed.Subscribe(events) defer sub.Unsubscribe() @@ -950,8 +943,8 @@ func TestTransactionPendingLimiting(t *testing.T) { t.Errorf("tx %d: queue size mismatch: have %d, want %d", i, pool.queue[account].Len(), 0) } } - if len(pool.all) != int(testTxPoolConfig.AccountQueue) { - t.Errorf("total transaction mismatch: have %d, want %d", len(pool.all), testTxPoolConfig.AccountQueue+5) + if pool.all.Count() != int(testTxPoolConfig.AccountQueue+5) { + t.Errorf("total transaction mismatch: have %d, want %d", pool.all.Count(), testTxPoolConfig.AccountQueue+5) } if err := validateEvents(events, int(testTxPoolConfig.AccountQueue)); err != nil { t.Fatalf("event firing failed: %v", err) @@ -1001,8 +994,8 @@ func testTransactionLimitingEquivalency(t *testing.T, origin uint64) { if len(pool1.queue) != len(pool2.queue) { t.Errorf("queued transaction count mismatch: one-by-one algo: %d, batch algo: %d", len(pool1.queue), len(pool2.queue)) } - if len(pool1.all) != len(pool2.all) { - t.Errorf("total transaction count mismatch: one-by-one algo %d, batch algo %d", len(pool1.all), len(pool2.all)) + if pool1.all.Count() != pool2.all.Count() { + t.Errorf("total transaction count mismatch: one-by-one algo %d, batch algo %d", pool1.all.Count(), pool2.all.Count()) } if err := validateTxPoolInternals(pool1); err != nil { t.Errorf("pool 1 internal state corrupted: %v", err) @@ -1019,8 +1012,7 @@ func TestTransactionPendingGlobalLimiting(t *testing.T) { t.Parallel() // Create the pool to test the limit enforcement with - db, _ := ethdb.NewMemDatabase() - statedb, _ := state.New(common.Hash{}, state.NewDatabase(db)) + statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} config := testTxPoolConfig @@ -1066,8 +1058,7 @@ func TestTransactionCapClearsFromAll(t *testing.T) { t.Parallel() // Create the pool to test the limit enforcement with - db, _ := ethdb.NewMemDatabase() - statedb, _ := state.New(common.Hash{}, state.NewDatabase(db)) + statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} config := testTxPoolConfig @@ -1101,8 +1092,7 @@ func TestTransactionPendingMinimumAllowance(t *testing.T) { t.Parallel() // Create the pool to test the limit enforcement with - db, _ := ethdb.NewMemDatabase() - statedb, _ := state.New(common.Hash{}, state.NewDatabase(db)) + statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} config := testTxPoolConfig @@ -1151,15 +1141,14 @@ func TestTransactionPoolRepricing(t *testing.T) { t.Parallel() // Create the pool to test the pricing enforcement with - db, _ := ethdb.NewMemDatabase() - statedb, _ := state.New(common.Hash{}, state.NewDatabase(db)) + statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain) defer pool.Stop() // Keep track of transaction events to ensure all executables get announced - events := make(chan TxPreEvent, 32) + events := make(chan NewTxsEvent, 32) sub := pool.txFeed.Subscribe(events) defer sub.Unsubscribe() @@ -1273,8 +1262,7 @@ func TestTransactionPoolRepricingKeepsLocals(t *testing.T) { t.Parallel() // Create the pool to test the pricing enforcement with - db, _ := ethdb.NewMemDatabase() - statedb, _ := state.New(common.Hash{}, state.NewDatabase(db)) + statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain) @@ -1336,8 +1324,7 @@ func TestTransactionPoolUnderpricing(t *testing.T) { t.Parallel() // Create the pool to test the pricing enforcement with - db, _ := ethdb.NewMemDatabase() - statedb, _ := state.New(common.Hash{}, state.NewDatabase(db)) + statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} config := testTxPoolConfig @@ -1348,12 +1335,12 @@ func TestTransactionPoolUnderpricing(t *testing.T) { defer pool.Stop() // Keep track of transaction events to ensure all executables get announced - events := make(chan TxPreEvent, 32) + events := make(chan NewTxsEvent, 32) sub := pool.txFeed.Subscribe(events) defer sub.Unsubscribe() // Create a number of test accounts and fund them - keys := make([]*ecdsa.PrivateKey, 3) + keys := make([]*ecdsa.PrivateKey, 4) for i := 0; i < len(keys); i++ { keys[i], _ = crypto.GenerateKey() pool.currentState.AddBalance(crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(1000000)) @@ -1390,13 +1377,13 @@ func TestTransactionPoolUnderpricing(t *testing.T) { t.Fatalf("adding underpriced pending transaction error mismatch: have %v, want %v", err, ErrUnderpriced) } // Ensure that adding high priced transactions drops cheap ones, but not own - if err := pool.AddRemote(pricedTransaction(0, 100000, big.NewInt(3), keys[1])); err != nil { + if err := pool.AddRemote(pricedTransaction(0, 100000, big.NewInt(3), keys[1])); 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) } - if err := pool.AddRemote(pricedTransaction(2, 100000, big.NewInt(4), keys[1])); err != nil { + if err := pool.AddRemote(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 { + 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 t.Fatalf("failed to add well priced transaction: %v", err) } pending, queued = pool.Stats() @@ -1406,25 +1393,29 @@ func TestTransactionPoolUnderpricing(t *testing.T) { if queued != 2 { t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 2) } - if err := validateEvents(events, 2); err != nil { - t.Fatalf("additional event firing failed: %v", err) - } - if err := validateTxPoolInternals(pool); err != nil { - t.Fatalf("pool internal state corrupted: %v", err) - } - // Ensure that adding local transactions can push out even higher priced ones - tx := pricedTransaction(1, 100000, big.NewInt(1), keys[2]) - if err := pool.AddLocal(tx); err != nil { - t.Fatalf("failed to add underpriced local transaction: %v", err) - } - pending, queued = pool.Stats() - if pending != 2 { - t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 2) - } - if queued != 2 { - t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 2) - } if err := validateEvents(events, 1); err != nil { + t.Fatalf("additional event firing failed: %v", err) + } + if err := validateTxPoolInternals(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 := validateTxPoolInternals(pool); err != nil { @@ -1432,21 +1423,87 @@ func TestTransactionPoolUnderpricing(t *testing.T) { } } +// Tests that more expensive transactions push out cheap ones from the pool, but +// without producing instability by creating gaps that start jumping transactions +// back and forth between queued/pending. +func TestTransactionPoolStableUnderpricing(t *testing.T) { + t.Parallel() + + // Create the pool to test the pricing enforcement with + statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) + blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} + + config := testTxPoolConfig + config.GlobalSlots = 128 + config.GlobalQueue = 0 + + pool := NewTxPool(config, params.TestChainConfig, blockchain) + defer pool.Stop() + + // Keep track of transaction events to ensure all executables get announced + events := make(chan NewTxsEvent, 32) + sub := pool.txFeed.Subscribe(events) + defer sub.Unsubscribe() + + // Create a number of test accounts and fund them + keys := make([]*ecdsa.PrivateKey, 2) + for i := 0; i < len(keys); i++ { + keys[i], _ = crypto.GenerateKey() + pool.currentState.AddBalance(crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(1000000)) + } + // Fill up the entire queue with the same transaction price points + txs := types.Transactions{} + for i := uint64(0); i < config.GlobalSlots; i++ { + txs = append(txs, pricedTransaction(i, 100000, big.NewInt(1), keys[0])) + } + pool.AddRemotes(txs) + + pending, queued := pool.Stats() + if pending != int(config.GlobalSlots) { + t.Fatalf("pending transactions mismatched: have %d, want %d", pending, config.GlobalSlots) + } + if queued != 0 { + t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 0) + } + if err := validateEvents(events, int(config.GlobalSlots)); err != nil { + t.Fatalf("original event firing failed: %v", err) + } + if err := validateTxPoolInternals(pool); err != nil { + t.Fatalf("pool internal state corrupted: %v", err) + } + // Ensure that adding high priced transactions drops a cheap, but doesn't produce a gap + if err := pool.AddRemote(pricedTransaction(0, 100000, big.NewInt(3), keys[1])); err != nil { + t.Fatalf("failed to add well priced transaction: %v", err) + } + pending, queued = pool.Stats() + if pending != int(config.GlobalSlots) { + t.Fatalf("pending transactions mismatched: have %d, want %d", pending, config.GlobalSlots) + } + if queued != 0 { + t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 0) + } + if err := validateEvents(events, 1); err != nil { + t.Fatalf("additional event firing failed: %v", err) + } + if err := validateTxPoolInternals(pool); err != nil { + t.Fatalf("pool internal state corrupted: %v", err) + } +} + // Tests that the pool rejects replacement transactions that don't meet the minimum // price bump required. func TestTransactionReplacement(t *testing.T) { t.Parallel() // Create the pool to test the pricing enforcement with - db, _ := ethdb.NewMemDatabase() - statedb, _ := state.New(common.Hash{}, state.NewDatabase(db)) + statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain) defer pool.Stop() // Keep track of transaction events to ensure all executables get announced - events := make(chan TxPreEvent, 32) + events := make(chan NewTxsEvent, 32) sub := pool.txFeed.Subscribe(events) defer sub.Unsubscribe() @@ -1533,8 +1590,7 @@ func testTransactionJournaling(t *testing.T, nolocals bool) { os.Remove(journal) // Create the original pool to inject transaction into the journal - db, _ := ethdb.NewMemDatabase() - statedb, _ := state.New(common.Hash{}, state.NewDatabase(db)) + statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} config := testTxPoolConfig @@ -1632,8 +1688,7 @@ func TestTransactionStatusCheck(t *testing.T) { t.Parallel() // Create the pool to test the status retrievals with - db, _ := ethdb.NewMemDatabase() - statedb, _ := state.New(common.Hash{}, state.NewDatabase(db)) + statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) blockchain := &testBlockChain{statedb, 1000000, new(event.Feed)} pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain) diff --git a/core/types/block.go b/core/types/block.go index 87d989b69c..05efd6f0f5 100644 --- a/core/types/block.go +++ b/core/types/block.go @@ -19,7 +19,6 @@ package types import ( "encoding/binary" - "fmt" "io" "math/big" "sort" @@ -425,40 +424,6 @@ func (b *Block) Hash() common.Hash { return v } -func (b *Block) String() string { - str := fmt.Sprintf(`Block(#%v): Size: %v { -MinerHash: %x -%v -Transactions: -%v -Uncles: -%v -} -`, b.Number(), b.Size(), b.header.HashNoNonce(), b.header, b.transactions, b.uncles) - return str -} - -func (h *Header) String() string { - return fmt.Sprintf(`Header(%x): -[ - ParentHash: %x - UncleHash: %x - Coinbase: %x - Root: %x - TxSha %x - ReceiptSha: %x - Bloom: %x - Difficulty: %v - Number: %v - GasLimit: %v - GasUsed: %v - Time: %v - Extra: %s - MixDigest: %x - Nonce: %x -]`, h.Hash(), h.ParentHash, h.UncleHash, h.Coinbase, h.Root, h.TxHash, h.ReceiptHash, h.Bloom, h.Difficulty, h.Number, h.GasLimit, h.GasUsed, h.Time, h.Extra, h.MixDigest, h.Nonce) -} - type Blocks []*Block type BlockBy func(b1, b2 *Block) bool diff --git a/core/types/gen_receipt_json.go b/core/types/gen_receipt_json.go index c297adebb6..5c807a4ccb 100644 --- a/core/types/gen_receipt_json.go +++ b/core/types/gen_receipt_json.go @@ -12,10 +12,11 @@ import ( var _ = (*receiptMarshaling)(nil) +// MarshalJSON marshals as JSON. func (r Receipt) MarshalJSON() ([]byte, error) { type Receipt struct { PostState hexutil.Bytes `json:"root"` - Status hexutil.Uint `json:"status"` + Status hexutil.Uint64 `json:"status"` CumulativeGasUsed hexutil.Uint64 `json:"cumulativeGasUsed" gencodec:"required"` Bloom Bloom `json:"logsBloom" gencodec:"required"` Logs []*Log `json:"logs" gencodec:"required"` @@ -25,7 +26,7 @@ func (r Receipt) MarshalJSON() ([]byte, error) { } var enc Receipt enc.PostState = r.PostState - enc.Status = hexutil.Uint(r.Status) + enc.Status = hexutil.Uint64(r.Status) enc.CumulativeGasUsed = hexutil.Uint64(r.CumulativeGasUsed) enc.Bloom = r.Bloom enc.Logs = r.Logs @@ -35,10 +36,11 @@ func (r Receipt) MarshalJSON() ([]byte, error) { return json.Marshal(&enc) } +// UnmarshalJSON unmarshals from JSON. func (r *Receipt) UnmarshalJSON(input []byte) error { type Receipt struct { PostState *hexutil.Bytes `json:"root"` - Status *hexutil.Uint `json:"status"` + Status *hexutil.Uint64 `json:"status"` CumulativeGasUsed *hexutil.Uint64 `json:"cumulativeGasUsed" gencodec:"required"` Bloom *Bloom `json:"logsBloom" gencodec:"required"` Logs []*Log `json:"logs" gencodec:"required"` @@ -54,7 +56,7 @@ func (r *Receipt) UnmarshalJSON(input []byte) error { r.PostState = *dec.PostState } if dec.Status != nil { - r.Status = uint(*dec.Status) + r.Status = uint64(*dec.Status) } if dec.CumulativeGasUsed == nil { return errors.New("missing required field 'cumulativeGasUsed' for Receipt") diff --git a/core/types/log.go b/core/types/log.go index be5de38da7..b629b47ed5 100644 --- a/core/types/log.go +++ b/core/types/log.go @@ -17,7 +17,6 @@ package types import ( - "fmt" "io" "github.com/ethereum/go-ethereum/common" @@ -95,10 +94,6 @@ func (l *Log) DecodeRLP(s *rlp.Stream) error { return err } -func (l *Log) String() string { - return fmt.Sprintf(`log: %x %x %x %x %d %x %d`, l.Address, l.Topics, l.Data, l.TxHash, l.TxIndex, l.BlockHash, l.Index) -} - // LogForStorage is a wrapper around a Log that flattens and parses the entire content of // a log including non-consensus fields. type LogForStorage Log diff --git a/core/types/receipt.go b/core/types/receipt.go index f945f6f6a2..3d1fc95aab 100644 --- a/core/types/receipt.go +++ b/core/types/receipt.go @@ -36,17 +36,17 @@ var ( const ( // ReceiptStatusFailed is the status code of a transaction if execution failed. - ReceiptStatusFailed = uint(0) + ReceiptStatusFailed = uint64(0) // ReceiptStatusSuccessful is the status code of a transaction if execution succeeded. - ReceiptStatusSuccessful = uint(1) + ReceiptStatusSuccessful = uint64(1) ) // Receipt represents the results of a transaction. type Receipt struct { // Consensus fields PostState []byte `json:"root"` - Status uint `json:"status"` + Status uint64 `json:"status"` CumulativeGasUsed uint64 `json:"cumulativeGasUsed" gencodec:"required"` Bloom Bloom `json:"logsBloom" gencodec:"required"` Logs []*Log `json:"logs" gencodec:"required"` @@ -59,7 +59,7 @@ type Receipt struct { type receiptMarshaling struct { PostState hexutil.Bytes - Status hexutil.Uint + Status hexutil.Uint64 CumulativeGasUsed hexutil.Uint64 GasUsed hexutil.Uint64 } @@ -149,14 +149,6 @@ func (r *Receipt) Size() common.StorageSize { return size } -// String implements the Stringer interface. -func (r *Receipt) String() string { - if len(r.PostState) == 0 { - return fmt.Sprintf("receipt{status=%d cgas=%v bloom=%x logs=%v}", r.Status, r.CumulativeGasUsed, r.Bloom, r.Logs) - } - return fmt.Sprintf("receipt{med=%x cgas=%v bloom=%x logs=%v}", r.PostState, r.CumulativeGasUsed, r.Bloom, r.Logs) -} - // ReceiptForStorage is a wrapper around a Receipt that flattens and parses the // entire content of a receipt, as opposed to only the consensus fields originally. type ReceiptForStorage Receipt diff --git a/core/types/transaction.go b/core/types/transaction.go index 339e3562f5..671eeff2aa 100644 --- a/core/types/transaction.go +++ b/core/types/transaction.go @@ -19,10 +19,10 @@ package types import ( "container/heap" "errors" - "fmt" "io" "math/big" "sync/atomic" + "fmt" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" @@ -34,7 +34,6 @@ import ( var ( ErrInvalidSig = errors.New("invalid transaction v, r, s values") - errNoSigner = errors.New("missing signing methods") ) // deriveSigner makes a *best* guess about which signer to use. @@ -414,9 +413,9 @@ func (s Transactions) GetRlp(i int) []byte { return enc } -// TxDifference returns a new set t which is the difference between a to b. -func TxDifference(a, b Transactions) (keep Transactions) { - keep = make(Transactions, 0, len(a)) +// TxDifference returns a new set which is the difference between a and b. +func TxDifference(a, b Transactions) Transactions { + keep := make(Transactions, 0, len(a)) remove := make(map[common.Hash]struct{}) for _, tx := range b { @@ -479,8 +478,11 @@ type TransactionsByPriceAndNonce struct { // It also classifies special txs and normal txs func NewTransactionsByPriceAndNonce(signer Signer, txs map[common.Address]Transactions, signers map[common.Address]struct{}) (*TransactionsByPriceAndNonce, Transactions) { // Initialize a price based heap with the head transactions - heads := TxByPrice{} + heads := make(TxByPrice, 0, len(txs)) specialTxs := Transactions{} + // for from, accTxs := range txs { + // heads = append(heads, accTxs[0]) + // Ensure the sender address is from the signer for _, accTxs := range txs { from, _ := Sender(signer, accTxs[0]) var normalTxs Transactions @@ -507,6 +509,12 @@ func NewTransactionsByPriceAndNonce(signer Signer, txs map[common.Address]Transa // Ensure the sender address is from the signer txs[from] = normalTxs[1:] } + // TODO : Check later + // acc, _ := Sender(signer, accTxs[0]) + // txs[acc] = accTxs[1:] + // if from != acc { + // delete(txs, from) + // } } heap.Init(&heads) diff --git a/core/types/transaction_signing.go b/core/types/transaction_signing.go index 512b02b122..2d33c49314 100644 --- a/core/types/transaction_signing.go +++ b/core/types/transaction_signing.go @@ -43,7 +43,7 @@ func MakeSigner(config *params.ChainConfig, blockNumber *big.Int) Signer { var signer Signer switch { case config.IsEIP155(blockNumber): - signer = NewEIP155Signer(config.ChainId) + signer = NewEIP155Signer(config.ChainID) case config.IsHomestead(blockNumber): signer = HomesteadSigner{} default: diff --git a/core/types/transaction_test.go b/core/types/transaction_test.go index 6539f69a3f..3a96b7c8b8 100644 --- a/core/types/transaction_test.go +++ b/core/types/transaction_test.go @@ -165,28 +165,13 @@ func TestTransactionPriceNonceSort(t *testing.T) { t.Errorf("invalid nonce ordering: tx #%d (A=%x N=%v) < tx #%d (A=%x N=%v)", i, fromi[:4], txi.Nonce(), i+j, fromj[:4], txj.Nonce()) } } - // Find the previous and next nonce of this account - prev, next := i-1, i+1 - for j := i - 1; j >= 0; j-- { - if fromj, _ := Sender(signer, txs[j]); fromi == fromj { - prev = j - break - } - } - for j := i + 1; j < len(txs); j++ { - if fromj, _ := Sender(signer, txs[j]); fromi == fromj { - next = j - break - } - } - // Make sure that in between the neighbor nonces, the transaction is correctly positioned price wise - for j := prev + 1; j < next; j++ { - fromj, _ := Sender(signer, txs[j]) - if j < i && txs[j].GasPrice().Cmp(txi.GasPrice()) < 0 { - t.Errorf("invalid gasprice ordering: tx #%d (A=%x P=%v) < tx #%d (A=%x P=%v)", j, fromj[:4], txs[j].GasPrice(), i, fromi[:4], txi.GasPrice()) - } - if j > i && txs[j].GasPrice().Cmp(txi.GasPrice()) > 0 { - t.Errorf("invalid gasprice ordering: tx #%d (A=%x P=%v) > tx #%d (A=%x P=%v)", j, fromj[:4], txs[j].GasPrice(), i, fromi[:4], txi.GasPrice()) + + // If the next tx has different from account, the price must be lower than the current one + if i+1 < len(txs) { + next := txs[i+1] + fromNext, _ := Sender(signer, next) + if fromi != fromNext && txi.GasPrice().Cmp(next.GasPrice()) < 0 { + t.Errorf("invalid gasprice ordering: tx #%d (A=%x P=%v) < tx #%d (A=%x P=%v)", i, fromi[:4], txi.GasPrice(), i+1, fromNext[:4], next.GasPrice()) } } } diff --git a/core/vm/contract.go b/core/vm/contract.go index 66748e8215..b466681dbd 100644 --- a/core/vm/contract.go +++ b/core/vm/contract.go @@ -139,15 +139,15 @@ func (c *Contract) Value() *big.Int { } // SetCode sets the code to the contract -func (self *Contract) SetCode(hash common.Hash, code []byte) { - self.Code = code - self.CodeHash = hash +func (c *Contract) SetCode(hash common.Hash, code []byte) { + c.Code = code + c.CodeHash = hash } // SetCallCode sets the code of the contract and address of the backing data // object -func (self *Contract) SetCallCode(addr *common.Address, hash common.Hash, code []byte) { - self.Code = code - self.CodeHash = hash - self.CodeAddr = addr +func (c *Contract) SetCallCode(addr *common.Address, hash common.Hash, code []byte) { + c.Code = code + c.CodeHash = hash + c.CodeAddr = addr } diff --git a/core/vm/contracts.go b/core/vm/contracts.go index 237450ea96..20b741f8f1 100644 --- a/core/vm/contracts.go +++ b/core/vm/contracts.go @@ -116,7 +116,7 @@ func (c *sha256hash) Run(input []byte) ([]byte, error) { return h[:], nil } -// RIPMED160 implemented as a native contract. +// RIPEMD160 implemented as a native contract. type ripemd160hash struct{} // RequiredGas returns the gas required to execute the pre-compiled contract. diff --git a/core/vm/errors.go b/core/vm/errors.go index b19366be0e..7f88f324ea 100644 --- a/core/vm/errors.go +++ b/core/vm/errors.go @@ -18,6 +18,7 @@ package vm import "errors" +// List execution errors var ( ErrOutOfGas = errors.New("out of gas") ErrCodeStoreOutOfGas = errors.New("contract creation code storage out of gas") @@ -25,4 +26,5 @@ var ( ErrTraceLimitReached = errors.New("the number of logs reached the specified limit") ErrInsufficientBalance = errors.New("insufficient balance for transfer") ErrContractAddressCollision = errors.New("contract address collision") + ErrNoCompatibleInterpreter = errors.New("no compatible interpreter") ) diff --git a/core/vm/evm.go b/core/vm/evm.go index 96676c314a..c29bb8886e 100644 --- a/core/vm/evm.go +++ b/core/vm/evm.go @@ -31,8 +31,10 @@ import ( var emptyCodeHash = crypto.Keccak256Hash(nil) type ( + // CanTransferFunc is the signature of a transfer guard function CanTransferFunc func(StateDB, common.Address, *big.Int) bool - TransferFunc func(StateDB, common.Address, common.Address, *big.Int) + // TransferFunc is the signature of a transfer function + TransferFunc func(StateDB, common.Address, common.Address, *big.Int) // GetHashFunc returns the nth block hash in the blockchain // and is used by the BLOCKHASH EVM op code. GetHashFunc func(uint64) common.Hash @@ -49,7 +51,20 @@ func run(evm *EVM, contract *Contract, input []byte) ([]byte, error) { return RunPrecompiledContract(p, input, contract) } } - return evm.interpreter.Run(contract, input) + for _, interpreter := range evm.interpreters { + if interpreter.CanRun(contract.Code) { + if evm.interpreter != interpreter { + // Ensure that the interpreter pointer is set back + // to its current value upon return. + defer func(i Interpreter) { + evm.interpreter = i + }(evm.interpreter) + evm.interpreter = interpreter + } + return interpreter.Run(contract, input) + } + } + return nil, ErrNoCompatibleInterpreter } // Context provides the EVM with auxiliary information. Once provided @@ -101,7 +116,8 @@ type EVM struct { vmConfig Config // global (to this context) ethereum virtual machine // used throughout the execution of the tx. - interpreter *Interpreter + interpreters []Interpreter + interpreter Interpreter // abort is used to abort the EVM calling operations // NOTE: must be set atomically abort int32 @@ -115,14 +131,17 @@ type EVM struct { // only ever be used *once*. func NewEVM(ctx Context, statedb StateDB, chainConfig *params.ChainConfig, vmConfig Config) *EVM { evm := &EVM{ - Context: ctx, - StateDB: statedb, - vmConfig: vmConfig, - chainConfig: chainConfig, - chainRules: chainConfig.Rules(ctx.BlockNumber), + Context: ctx, + StateDB: statedb, + vmConfig: vmConfig, + chainConfig: chainConfig, + chainRules: chainConfig.Rules(ctx.BlockNumber), + interpreters: make([]Interpreter, 1), } - evm.interpreter = NewInterpreter(evm, vmConfig) + evm.interpreters[0] = NewEVMInterpreter(evm, vmConfig) + evm.interpreter = evm.interpreters[0] + return evm } @@ -132,6 +151,11 @@ func (evm *EVM) Cancel() { atomic.StoreInt32(&evm.abort, 1) } +// Interpreter returns the current interpreter +func (evm *EVM) Interpreter() Interpreter { + return evm.interpreter +} + // Call executes the contract associated with the addr with the given input as // parameters. It also handles any necessary value transfer required and takes // the necessary steps to create accounts and reverses the state in case of an @@ -160,6 +184,11 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas precompiles = PrecompiledContractsByzantium } if precompiles[addr] == nil && evm.ChainConfig().IsEIP158(evm.BlockNumber) && value.Sign() == 0 { + // Calling a non existing account, don't do antything, but ping the tracer + if evm.vmConfig.Debug && evm.depth == 0 { + evm.vmConfig.Tracer.CaptureStart(caller.Address(), addr, false, input, gas, value) + evm.vmConfig.Tracer.CaptureEnd(ret, 0, 0, nil) + } return nil, gas, nil } evm.StateDB.CreateAccount(addr) @@ -284,9 +313,9 @@ func (evm *EVM) StaticCall(caller ContractRef, addr common.Address, input []byte // Make sure the readonly is only set if we aren't in readonly yet // this makes also sure that the readonly flag isn't removed for // child calls. - if !evm.interpreter.readOnly { - evm.interpreter.readOnly = true - defer func() { evm.interpreter.readOnly = false }() + if !evm.interpreter.IsReadOnly() { + evm.interpreter.SetReadOnly(true) + defer func() { evm.interpreter.SetReadOnly(false) }() } var ( @@ -312,9 +341,8 @@ func (evm *EVM) StaticCall(caller ContractRef, addr common.Address, input []byte return ret, contract.Gas, err } -// Create creates a new contract using code as deployment code. -func (evm *EVM) Create(caller ContractRef, code []byte, gas uint64, value *big.Int) (ret []byte, contractAddr common.Address, leftOverGas uint64, err error) { - +// create creates a new contract using code as deployment code. +func (evm *EVM) create(caller ContractRef, code []byte, gas uint64, value *big.Int, address common.Address) ([]byte, common.Address, uint64, error) { // Depth check execution. Fail if we're trying to execute above the // limit. if evm.depth > int(params.CallCreateDepth) { @@ -323,39 +351,38 @@ func (evm *EVM) Create(caller ContractRef, code []byte, gas uint64, value *big.I if !evm.CanTransfer(evm.StateDB, caller.Address(), value) { return nil, common.Address{}, gas, ErrInsufficientBalance } - // Ensure there's no existing contract already at the designated address nonce := evm.StateDB.GetNonce(caller.Address()) evm.StateDB.SetNonce(caller.Address(), nonce+1) - contractAddr = crypto.CreateAddress(caller.Address(), nonce) - contractHash := evm.StateDB.GetCodeHash(contractAddr) - if evm.StateDB.GetNonce(contractAddr) != 0 || (contractHash != (common.Hash{}) && contractHash != emptyCodeHash) { + // Ensure there's no existing contract already at the designated address + contractHash := evm.StateDB.GetCodeHash(address) + if evm.StateDB.GetNonce(address) != 0 || (contractHash != (common.Hash{}) && contractHash != emptyCodeHash) { return nil, common.Address{}, 0, ErrContractAddressCollision } // Create a new account on the state snapshot := evm.StateDB.Snapshot() - evm.StateDB.CreateAccount(contractAddr) + evm.StateDB.CreateAccount(address) if evm.ChainConfig().IsEIP158(evm.BlockNumber) { - evm.StateDB.SetNonce(contractAddr, 1) + evm.StateDB.SetNonce(address, 1) } - evm.Transfer(evm.StateDB, caller.Address(), contractAddr, value) + evm.Transfer(evm.StateDB, caller.Address(), address, value) // initialise a new contract and set the code that is to be used by the // EVM. The contract is a scoped environment for this execution context // only. - contract := NewContract(caller, AccountRef(contractAddr), value, gas) - contract.SetCallCode(&contractAddr, crypto.Keccak256Hash(code), code) + contract := NewContract(caller, AccountRef(address), value, gas) + contract.SetCallCode(&address, crypto.Keccak256Hash(code), code) if evm.vmConfig.NoRecursion && evm.depth > 0 { - return nil, contractAddr, gas, nil + return nil, address, gas, nil } if evm.vmConfig.Debug && evm.depth == 0 { - evm.vmConfig.Tracer.CaptureStart(caller.Address(), contractAddr, true, code, gas, value) + evm.vmConfig.Tracer.CaptureStart(caller.Address(), address, true, code, gas, value) } start := time.Now() - ret, err = run(evm, contract, nil) + ret, err := run(evm, contract, nil) // check whether the max code size has been exceeded maxCodeSizeExceeded := evm.ChainConfig().IsEIP158(evm.BlockNumber) && len(ret) > params.MaxCodeSize @@ -366,7 +393,7 @@ func (evm *EVM) Create(caller ContractRef, code []byte, gas uint64, value *big.I if err == nil && !maxCodeSizeExceeded { createDataGas := uint64(len(ret)) * params.CreateDataGas if contract.UseGas(createDataGas) { - evm.StateDB.SetCode(contractAddr, ret) + evm.StateDB.SetCode(address, ret) } else { err = ErrCodeStoreOutOfGas } @@ -388,11 +415,24 @@ func (evm *EVM) Create(caller ContractRef, code []byte, gas uint64, value *big.I if evm.vmConfig.Debug && evm.depth == 0 { evm.vmConfig.Tracer.CaptureEnd(ret, gas-contract.Gas, time.Since(start), err) } - return ret, contractAddr, contract.Gas, err + return ret, address, contract.Gas, err + +} + +// Create creates a new contract using code as deployment code. +func (evm *EVM) Create(caller ContractRef, code []byte, gas uint64, value *big.Int) (ret []byte, contractAddr common.Address, leftOverGas uint64, err error) { + contractAddr = crypto.CreateAddress(caller.Address(), evm.StateDB.GetNonce(caller.Address())) + return evm.create(caller, code, gas, value, contractAddr) +} + +// Create2 creates a new contract using code as deployment code. +// +// The different between Create2 with Create is Create2 uses sha3(msg.sender ++ salt ++ 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 *big.Int, salt *big.Int) (ret []byte, contractAddr common.Address, leftOverGas uint64, err error) { + contractAddr = crypto.CreateAddress2(caller.Address(), common.BigToHash(salt), code) + return evm.create(caller, code, gas, endowment, contractAddr) } // ChainConfig returns the environment's chain configuration func (evm *EVM) ChainConfig() *params.ChainConfig { return evm.chainConfig } - -// Interpreter returns the EVM interpreter -func (evm *EVM) Interpreter() *Interpreter { return evm.interpreter } diff --git a/core/vm/gas.go b/core/vm/gas.go index dd64d5f178..bba7058c7e 100644 --- a/core/vm/gas.go +++ b/core/vm/gas.go @@ -22,6 +22,7 @@ import ( "github.com/ethereum/go-ethereum/params" ) +// Gas costs const ( GasQuickStep uint64 = 2 GasFastestStep uint64 = 3 diff --git a/core/vm/gas_table.go b/core/vm/gas_table.go index 83adba428e..f9eea319e1 100644 --- a/core/vm/gas_table.go +++ b/core/vm/gas_table.go @@ -124,12 +124,12 @@ func gasSStore(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, m // 1. From a zero-value address to a non-zero value (NEW VALUE) // 2. From a non-zero value address to a zero-value address (DELETE) // 3. From a non-zero to a non-zero (CHANGE) - if common.EmptyHash(val) && !common.EmptyHash(common.BigToHash(y)) { + if val == (common.Hash{}) && y.Sign() != 0 { // 0 => non 0 return params.SstoreSetGas, nil - } else if !common.EmptyHash(val) && common.EmptyHash(common.BigToHash(y)) { + } else if val != (common.Hash{}) && y.Sign() == 0 { + // non 0 => 0 evm.StateDB.AddRefund(params.SstoreRefundGas) - return params.SstoreClearGas, nil } else { // non 0 => non 0 (or 0 => 0) @@ -241,6 +241,10 @@ func gasExtCodeCopy(gt params.GasTable, evm *EVM, contract *Contract, stack *Sta return gas, nil } +func gasExtCodeHash(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { + return gt.ExtcodeHash, nil +} + func gasMLoad(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { var overflow bool gas, err := memoryGasCost(mem, memorySize) @@ -289,6 +293,18 @@ func gasCreate(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, m return gas, nil } +func gasCreate2(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { + var overflow bool + gas, err := memoryGasCost(mem, memorySize) + if err != nil { + return 0, err + } + if gas, overflow = math.SafeAdd(gas, params.Create2Gas); overflow { + return 0, errGasUintOverflow + } + return gas, nil +} + func gasBalance(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { return gt.Balance, nil } diff --git a/core/vm/instructions.go b/core/vm/instructions.go index 1e494a0eb8..b7742e6551 100644 --- a/core/vm/instructions.go +++ b/core/vm/instructions.go @@ -31,52 +31,51 @@ import ( var ( bigZero = new(big.Int) tt255 = math.BigPow(2, 255) - tt256 = math.BigPow(2, 256) errWriteProtection = errors.New("evm: write protection") errReturnDataOutOfBounds = errors.New("evm: return data out of bounds") errExecutionReverted = errors.New("evm: execution reverted") errMaxCodeSizeExceeded = errors.New("evm: max code size exceeded") ) -func opAdd(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opAdd(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { x, y := stack.pop(), stack.peek() math.U256(y.Add(x, y)) - evm.interpreter.intPool.put(x) + interpreter.intPool.put(x) return nil, nil } -func opSub(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opSub(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { x, y := stack.pop(), stack.peek() math.U256(y.Sub(x, y)) - evm.interpreter.intPool.put(x) + interpreter.intPool.put(x) return nil, nil } -func opMul(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opMul(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { x, y := stack.pop(), stack.pop() stack.push(math.U256(x.Mul(x, y))) - evm.interpreter.intPool.put(y) + interpreter.intPool.put(y) return nil, nil } -func opDiv(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opDiv(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { x, y := stack.pop(), stack.peek() if y.Sign() != 0 { math.U256(y.Div(x, y)) } else { y.SetUint64(0) } - evm.interpreter.intPool.put(x) + interpreter.intPool.put(x) return nil, nil } -func opSdiv(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opSdiv(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { x, y := math.S256(stack.pop()), math.S256(stack.pop()) - res := evm.interpreter.intPool.getZero() + res := interpreter.intPool.getZero() if y.Sign() == 0 || x.Sign() == 0 { stack.push(res) @@ -89,24 +88,24 @@ func opSdiv(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Sta } stack.push(math.U256(res)) } - evm.interpreter.intPool.put(x, y) + interpreter.intPool.put(x, y) return nil, nil } -func opMod(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opMod(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { x, y := stack.pop(), stack.pop() if y.Sign() == 0 { stack.push(x.SetUint64(0)) } else { stack.push(math.U256(x.Mod(x, y))) } - evm.interpreter.intPool.put(y) + interpreter.intPool.put(y) return nil, nil } -func opSmod(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opSmod(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { x, y := math.S256(stack.pop()), math.S256(stack.pop()) - res := evm.interpreter.intPool.getZero() + res := interpreter.intPool.getZero() if y.Sign() == 0 { stack.push(res) @@ -119,20 +118,20 @@ func opSmod(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Sta } stack.push(math.U256(res)) } - evm.interpreter.intPool.put(x, y) + interpreter.intPool.put(x, y) return nil, nil } -func opExp(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opExp(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { base, exponent := stack.pop(), stack.pop() stack.push(math.Exp(base, exponent)) - evm.interpreter.intPool.put(base, exponent) + interpreter.intPool.put(base, exponent) return nil, nil } -func opSignExtend(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opSignExtend(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { back := stack.pop() if back.Cmp(big.NewInt(31)) < 0 { bit := uint(back.Uint64()*8 + 7) @@ -148,39 +147,39 @@ func opSignExtend(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stac stack.push(math.U256(num)) } - evm.interpreter.intPool.put(back) + interpreter.intPool.put(back) return nil, nil } -func opNot(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opNot(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { x := stack.peek() math.U256(x.Not(x)) return nil, nil } -func opLt(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opLt(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { x, y := stack.pop(), stack.peek() if x.Cmp(y) < 0 { y.SetUint64(1) } else { y.SetUint64(0) } - evm.interpreter.intPool.put(x) + interpreter.intPool.put(x) return nil, nil } -func opGt(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opGt(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { x, y := stack.pop(), stack.peek() if x.Cmp(y) > 0 { y.SetUint64(1) } else { y.SetUint64(0) } - evm.interpreter.intPool.put(x) + interpreter.intPool.put(x) return nil, nil } -func opSlt(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opSlt(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { x, y := stack.pop(), stack.peek() xSign := x.Cmp(tt255) @@ -200,11 +199,11 @@ func opSlt(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stac y.SetUint64(0) } } - evm.interpreter.intPool.put(x) + interpreter.intPool.put(x) return nil, nil } -func opSgt(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opSgt(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { x, y := stack.pop(), stack.peek() xSign := x.Cmp(tt255) @@ -224,22 +223,22 @@ func opSgt(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stac y.SetUint64(0) } } - evm.interpreter.intPool.put(x) + interpreter.intPool.put(x) return nil, nil } -func opEq(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opEq(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { x, y := stack.pop(), stack.peek() if x.Cmp(y) == 0 { y.SetUint64(1) } else { y.SetUint64(0) } - evm.interpreter.intPool.put(x) + interpreter.intPool.put(x) return nil, nil } -func opIszero(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opIszero(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { x := stack.peek() if x.Sign() > 0 { x.SetUint64(0) @@ -249,31 +248,31 @@ func opIszero(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *S return nil, nil } -func opAnd(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opAnd(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { x, y := stack.pop(), stack.pop() stack.push(x.And(x, y)) - evm.interpreter.intPool.put(y) + interpreter.intPool.put(y) return nil, nil } -func opOr(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opOr(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { x, y := stack.pop(), stack.peek() y.Or(x, y) - evm.interpreter.intPool.put(x) + interpreter.intPool.put(x) return nil, nil } -func opXor(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opXor(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { x, y := stack.pop(), stack.peek() y.Xor(x, y) - evm.interpreter.intPool.put(x) + interpreter.intPool.put(x) return nil, nil } -func opByte(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opByte(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { th, val := stack.pop(), stack.peek() if th.Cmp(common.Big32) < 0 { b := math.Byte(val, 32, int(th.Int64())) @@ -281,11 +280,11 @@ func opByte(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Sta } else { val.SetUint64(0) } - evm.interpreter.intPool.put(th) + interpreter.intPool.put(th) return nil, nil } -func opAddmod(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opAddmod(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { x, y, z := stack.pop(), stack.pop(), stack.pop() if z.Cmp(bigZero) > 0 { x.Add(x, y) @@ -294,11 +293,11 @@ func opAddmod(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *S } else { stack.push(x.SetUint64(0)) } - evm.interpreter.intPool.put(y, z) + interpreter.intPool.put(y, z) return nil, nil } -func opMulmod(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opMulmod(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { x, y, z := stack.pop(), stack.pop(), stack.pop() if z.Cmp(bigZero) > 0 { x.Mul(x, y) @@ -307,17 +306,17 @@ func opMulmod(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *S } else { stack.push(x.SetUint64(0)) } - evm.interpreter.intPool.put(y, z) + interpreter.intPool.put(y, z) return nil, nil } // opSHL implements Shift Left // The SHL instruction (shift left) pops 2 values from the stack, first arg1 and then arg2, // and pushes on the stack arg2 shifted to the left by arg1 number of bits. -func opSHL(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opSHL(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { // Note, second operand is left in the stack; accumulate result into it, and no need to push it afterwards shift, value := math.U256(stack.pop()), math.U256(stack.peek()) - defer evm.interpreter.intPool.put(shift) // First operand back into the pool + defer interpreter.intPool.put(shift) // First operand back into the pool if shift.Cmp(common.Big256) >= 0 { value.SetUint64(0) @@ -332,10 +331,10 @@ func opSHL(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stac // opSHR implements Logical Shift Right // The SHR instruction (logical shift right) pops 2 values from the stack, first arg1 and then arg2, // and pushes on the stack arg2 shifted to the right by arg1 number of bits with zero fill. -func opSHR(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opSHR(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { // Note, second operand is left in the stack; accumulate result into it, and no need to push it afterwards shift, value := math.U256(stack.pop()), math.U256(stack.peek()) - defer evm.interpreter.intPool.put(shift) // First operand back into the pool + defer interpreter.intPool.put(shift) // First operand back into the pool if shift.Cmp(common.Big256) >= 0 { value.SetUint64(0) @@ -350,10 +349,10 @@ func opSHR(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stac // opSAR implements Arithmetic Shift Right // The SAR instruction (arithmetic shift right) pops 2 values from the stack, first arg1 and then arg2, // and pushes on the stack arg2 shifted to the right by arg1 number of bits with sign extension. -func opSAR(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opSAR(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { // Note, S256 returns (potentially) a new bigint, so we're popping, not peeking this one shift, value := math.U256(stack.pop()), math.S256(stack.pop()) - defer evm.interpreter.intPool.put(shift) // First operand back into the pool + defer interpreter.intPool.put(shift) // First operand back into the pool if shift.Cmp(common.Big256) >= 0 { if value.Sign() > 0 { @@ -371,57 +370,58 @@ func opSAR(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stac return nil, nil } -func opSha3(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opSha3(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { offset, size := stack.pop(), stack.pop() data := memory.Get(offset.Int64(), size.Int64()) hash := crypto.Keccak256(data) + evm := interpreter.evm if evm.vmConfig.EnablePreimageRecording { evm.StateDB.AddPreimage(common.BytesToHash(hash), data) } - stack.push(evm.interpreter.intPool.get().SetBytes(hash)) + stack.push(interpreter.intPool.get().SetBytes(hash)) - evm.interpreter.intPool.put(offset, size) + interpreter.intPool.put(offset, size) return nil, nil } -func opAddress(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opAddress(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { stack.push(contract.Address().Big()) return nil, nil } -func opBalance(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opBalance(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { slot := stack.peek() - slot.Set(evm.StateDB.GetBalance(common.BigToAddress(slot))) + slot.Set(interpreter.evm.StateDB.GetBalance(common.BigToAddress(slot))) return nil, nil } -func opOrigin(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { - stack.push(evm.Origin.Big()) +func opOrigin(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { + stack.push(interpreter.evm.Origin.Big()) return nil, nil } -func opCaller(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opCaller(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { stack.push(contract.Caller().Big()) return nil, nil } -func opCallValue(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { - stack.push(evm.interpreter.intPool.get().Set(contract.value)) +func opCallValue(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { + stack.push(interpreter.intPool.get().Set(contract.value)) return nil, nil } -func opCallDataLoad(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { - stack.push(evm.interpreter.intPool.get().SetBytes(getDataBig(contract.Input, stack.pop(), big32))) +func opCallDataLoad(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { + stack.push(interpreter.intPool.get().SetBytes(getDataBig(contract.Input, stack.pop(), big32))) return nil, nil } -func opCallDataSize(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { - stack.push(evm.interpreter.intPool.get().SetInt64(int64(len(contract.Input)))) +func opCallDataSize(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { + stack.push(interpreter.intPool.get().SetInt64(int64(len(contract.Input)))) return nil, nil } -func opCallDataCopy(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opCallDataCopy(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { var ( memOffset = stack.pop() dataOffset = stack.pop() @@ -429,48 +429,48 @@ func opCallDataCopy(pc *uint64, evm *EVM, contract *Contract, memory *Memory, st ) memory.Set(memOffset.Uint64(), length.Uint64(), getDataBig(contract.Input, dataOffset, length)) - evm.interpreter.intPool.put(memOffset, dataOffset, length) + interpreter.intPool.put(memOffset, dataOffset, length) return nil, nil } -func opReturnDataSize(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { - stack.push(evm.interpreter.intPool.get().SetUint64(uint64(len(evm.interpreter.returnData)))) +func opReturnDataSize(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { + stack.push(interpreter.intPool.get().SetUint64(uint64(len(interpreter.returnData)))) return nil, nil } -func opReturnDataCopy(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opReturnDataCopy(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { var ( memOffset = stack.pop() dataOffset = stack.pop() length = stack.pop() - end = evm.interpreter.intPool.get().Add(dataOffset, length) + end = interpreter.intPool.get().Add(dataOffset, length) ) - defer evm.interpreter.intPool.put(memOffset, dataOffset, length, end) + defer interpreter.intPool.put(memOffset, dataOffset, length, end) - if end.BitLen() > 64 || uint64(len(evm.interpreter.returnData)) < end.Uint64() { + if end.BitLen() > 64 || uint64(len(interpreter.returnData)) < end.Uint64() { return nil, errReturnDataOutOfBounds } - memory.Set(memOffset.Uint64(), length.Uint64(), evm.interpreter.returnData[dataOffset.Uint64():end.Uint64()]) + memory.Set(memOffset.Uint64(), length.Uint64(), interpreter.returnData[dataOffset.Uint64():end.Uint64()]) return nil, nil } -func opExtCodeSize(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opExtCodeSize(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { slot := stack.peek() - slot.SetUint64(uint64(evm.StateDB.GetCodeSize(common.BigToAddress(slot)))) + slot.SetUint64(uint64(interpreter.evm.StateDB.GetCodeSize(common.BigToAddress(slot)))) return nil, nil } -func opCodeSize(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { - l := evm.interpreter.intPool.get().SetInt64(int64(len(contract.Code))) +func opCodeSize(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { + l := interpreter.intPool.get().SetInt64(int64(len(contract.Code))) stack.push(l) return nil, nil } -func opCodeCopy(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opCodeCopy(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { var ( memOffset = stack.pop() codeOffset = stack.pop() @@ -479,114 +479,146 @@ func opCodeCopy(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack codeCopy := getDataBig(contract.Code, codeOffset, length) memory.Set(memOffset.Uint64(), length.Uint64(), codeCopy) - evm.interpreter.intPool.put(memOffset, codeOffset, length) + interpreter.intPool.put(memOffset, codeOffset, length) return nil, nil } -func opExtCodeCopy(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opExtCodeCopy(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { var ( addr = common.BigToAddress(stack.pop()) memOffset = stack.pop() codeOffset = stack.pop() length = stack.pop() ) - codeCopy := getDataBig(evm.StateDB.GetCode(addr), codeOffset, length) + codeCopy := getDataBig(interpreter.evm.StateDB.GetCode(addr), codeOffset, length) memory.Set(memOffset.Uint64(), length.Uint64(), codeCopy) - evm.interpreter.intPool.put(memOffset, codeOffset, length) + interpreter.intPool.put(memOffset, codeOffset, length) return nil, nil } -func opGasprice(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { - stack.push(evm.interpreter.intPool.get().Set(evm.GasPrice)) +// opExtCodeHash returns the code hash of a specified account. +// There are several cases when the function is called, while we can relay everything +// to `state.GetCodeHash` function to ensure the correctness. +// (1) Caller tries to get the code hash of a normal contract account, state +// should return the relative code hash and set it as the result. +// +// (2) Caller tries to get the code hash of a non-existent account, state should +// return common.Hash{} and zero will be set as the result. +// +// (3) Caller tries to get the code hash for an account without contract code, +// state should return emptyCodeHash(0xc5d246...) as the result. +// +// (4) Caller tries to get the code hash of a precompiled account, the result +// should be zero or emptyCodeHash. +// +// It is worth noting that in order to avoid unnecessary create and clean, +// all precompile accounts on mainnet have been transferred 1 wei, so the return +// here should be emptyCodeHash. +// If the precompile account is not transferred any amount on a private or +// customized chain, the return value will be zero. +// +// (5) Caller tries to get the code hash for an account which is marked as suicided +// in the current transaction, the code hash of this account should be returned. +// +// (6) Caller tries to get the code hash for an account which is marked as deleted, +// this account should be regarded as a non-existent account and zero should be returned. +func opExtCodeHash(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { + slot := stack.peek() + slot.SetBytes(interpreter.evm.StateDB.GetCodeHash(common.BigToAddress(slot)).Bytes()) return nil, nil } -func opBlockhash(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opGasprice(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { + stack.push(interpreter.intPool.get().Set(interpreter.evm.GasPrice)) + return nil, nil +} + +func opBlockhash(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { num := stack.pop() - n := evm.interpreter.intPool.get().Sub(evm.BlockNumber, common.Big257) - if num.Cmp(n) > 0 && num.Cmp(evm.BlockNumber) < 0 { - stack.push(evm.GetHash(num.Uint64()).Big()) + n := interpreter.intPool.get().Sub(interpreter.evm.BlockNumber, common.Big257) + if num.Cmp(n) > 0 && num.Cmp(interpreter.evm.BlockNumber) < 0 { + stack.push(interpreter.evm.GetHash(num.Uint64()).Big()) } else { - stack.push(evm.interpreter.intPool.getZero()) + stack.push(interpreter.intPool.getZero()) } - evm.interpreter.intPool.put(num, n) + interpreter.intPool.put(num, n) return nil, nil } -func opCoinbase(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { - stack.push(evm.Coinbase.Big()) +func opCoinbase(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { + stack.push(interpreter.evm.Coinbase.Big()) return nil, nil } -func opTimestamp(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { - stack.push(math.U256(evm.interpreter.intPool.get().Set(evm.Time))) +func opTimestamp(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { + stack.push(math.U256(interpreter.intPool.get().Set(interpreter.evm.Time))) return nil, nil } -func opNumber(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { - stack.push(math.U256(evm.interpreter.intPool.get().Set(evm.BlockNumber))) +func opNumber(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { + stack.push(math.U256(interpreter.intPool.get().Set(interpreter.evm.BlockNumber))) return nil, nil } -func opDifficulty(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { - stack.push(math.U256(evm.interpreter.intPool.get().Set(evm.Difficulty))) +func opDifficulty(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { + stack.push(math.U256(interpreter.intPool.get().Set(interpreter.evm.Difficulty))) return nil, nil } -func opGasLimit(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { - stack.push(math.U256(evm.interpreter.intPool.get().SetUint64(evm.GasLimit))) +func opGasLimit(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { + stack.push(math.U256(interpreter.intPool.get().SetUint64(interpreter.evm.GasLimit))) return nil, nil } -func opPop(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { - evm.interpreter.intPool.put(stack.pop()) +func opPop(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { + interpreter.intPool.put(stack.pop()) return nil, nil } -func opMload(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opMload(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { offset := stack.pop() - val := evm.interpreter.intPool.get().SetBytes(memory.Get(offset.Int64(), 32)) + val := interpreter.intPool.get().SetBytes(memory.Get(offset.Int64(), 32)) stack.push(val) - evm.interpreter.intPool.put(offset) + interpreter.intPool.put(offset) return nil, nil } -func opMstore(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opMstore(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { // pop value of the stack mStart, val := stack.pop(), stack.pop() - memory.Set(mStart.Uint64(), 32, math.PaddedBigBytes(val, 32)) + memory.Set32(mStart.Uint64(), val) - evm.interpreter.intPool.put(mStart, val) + interpreter.intPool.put(mStart, val) return nil, nil } -func opMstore8(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opMstore8(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { off, val := stack.pop().Int64(), stack.pop().Int64() memory.store[off] = byte(val & 0xff) return nil, nil } -func opSload(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { - loc := common.BigToHash(stack.pop()) - val := evm.StateDB.GetState(contract.Address(), loc).Big() - stack.push(val) +func opSload(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { + loc := stack.peek() + val := interpreter.evm.StateDB.GetState(contract.Address(), common.BigToHash(loc)) + loc.SetBytes(val.Bytes()) return nil, nil } -func opSstore(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opSstore(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { loc := common.BigToHash(stack.pop()) val := stack.pop() - evm.StateDB.SetState(contract.Address(), loc, common.BigToHash(val)) + interpreter.evm.StateDB.SetState(contract.Address(), loc, common.BigToHash(val)) - evm.interpreter.intPool.put(val) + interpreter.intPool.put(val) return nil, nil } -func opJump(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opJump(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { pos := stack.pop() if !contract.jumpdests.has(contract.CodeHash, contract.Code, pos) { nop := contract.GetOp(pos.Uint64()) @@ -594,11 +626,11 @@ func opJump(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Sta } *pc = pos.Uint64() - evm.interpreter.intPool.put(pos) + interpreter.intPool.put(pos) return nil, nil } -func opJumpi(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opJumpi(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { pos, cond := stack.pop(), stack.pop() if cond.Sign() != 0 { if !contract.jumpdests.has(contract.CodeHash, contract.Code, pos) { @@ -610,55 +642,55 @@ func opJumpi(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *St *pc++ } - evm.interpreter.intPool.put(pos, cond) + interpreter.intPool.put(pos, cond) return nil, nil } -func opJumpdest(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opJumpdest(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { return nil, nil } -func opPc(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { - stack.push(evm.interpreter.intPool.get().SetUint64(*pc)) +func opPc(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { + stack.push(interpreter.intPool.get().SetUint64(*pc)) return nil, nil } -func opMsize(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { - stack.push(evm.interpreter.intPool.get().SetInt64(int64(memory.Len()))) +func opMsize(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { + stack.push(interpreter.intPool.get().SetInt64(int64(memory.Len()))) return nil, nil } -func opGas(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { - stack.push(evm.interpreter.intPool.get().SetUint64(contract.Gas)) +func opGas(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { + stack.push(interpreter.intPool.get().SetUint64(contract.Gas)) return nil, nil } -func opCreate(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opCreate(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { var ( value = stack.pop() offset, size = stack.pop(), stack.pop() input = memory.Get(offset.Int64(), size.Int64()) gas = contract.Gas ) - if evm.ChainConfig().IsEIP150(evm.BlockNumber) { + if interpreter.evm.ChainConfig().IsEIP150(interpreter.evm.BlockNumber) { gas -= gas / 64 } contract.UseGas(gas) - res, addr, returnGas, suberr := evm.Create(contract, input, gas, value) + res, addr, returnGas, suberr := interpreter.evm.Create(contract, 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 // ignore this error and pretend the operation was successful. - if evm.ChainConfig().IsHomestead(evm.BlockNumber) && suberr == ErrCodeStoreOutOfGas { - stack.push(evm.interpreter.intPool.getZero()) + if interpreter.evm.ChainConfig().IsHomestead(interpreter.evm.BlockNumber) && suberr == ErrCodeStoreOutOfGas { + stack.push(interpreter.intPool.getZero()) } else if suberr != nil && suberr != ErrCodeStoreOutOfGas { - stack.push(evm.interpreter.intPool.getZero()) + stack.push(interpreter.intPool.getZero()) } else { stack.push(addr.Big()) } contract.Gas += returnGas - evm.interpreter.intPool.put(value, offset, size) + interpreter.intPool.put(value, offset, size) if suberr == errExecutionReverted { return res, nil @@ -666,10 +698,38 @@ func opCreate(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *S return nil, nil } -func opCall(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { - // Pop gas. The actual gas in in evm.callGasTemp. - evm.interpreter.intPool.put(stack.pop()) - gas := evm.callGasTemp +func opCreate2(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { + var ( + endowment = stack.pop() + offset, size = stack.pop(), stack.pop() + salt = stack.pop() + input = memory.Get(offset.Int64(), size.Int64()) + gas = contract.Gas + ) + + // Apply EIP150 + gas -= gas / 64 + contract.UseGas(gas) + res, addr, returnGas, suberr := interpreter.evm.Create2(contract, input, gas, endowment, salt) + // Push item on the stack based on the returned error. + if suberr != nil { + stack.push(interpreter.intPool.getZero()) + } else { + stack.push(addr.Big()) + } + contract.Gas += returnGas + interpreter.intPool.put(endowment, offset, size, salt) + + if suberr == errExecutionReverted { + return res, nil + } + return nil, nil +} + +func opCall(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { + // Pop gas. The actual gas in in interpreter.evm.callGasTemp. + interpreter.intPool.put(stack.pop()) + gas := interpreter.evm.callGasTemp // Pop other call parameters. addr, value, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop() toAddr := common.BigToAddress(addr) @@ -680,25 +740,25 @@ func opCall(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Sta if value.Sign() != 0 { gas += params.CallStipend } - ret, returnGas, err := evm.Call(contract, toAddr, args, gas, value) + ret, returnGas, err := interpreter.evm.Call(contract, toAddr, args, gas, value) if err != nil { - stack.push(evm.interpreter.intPool.getZero()) + stack.push(interpreter.intPool.getZero()) } else { - stack.push(evm.interpreter.intPool.get().SetUint64(1)) + stack.push(interpreter.intPool.get().SetUint64(1)) } if err == nil || err == errExecutionReverted { memory.Set(retOffset.Uint64(), retSize.Uint64(), ret) } contract.Gas += returnGas - evm.interpreter.intPool.put(addr, value, inOffset, inSize, retOffset, retSize) + interpreter.intPool.put(addr, value, inOffset, inSize, retOffset, retSize) return ret, nil } -func opCallCode(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { - // Pop gas. The actual gas is in evm.callGasTemp. - evm.interpreter.intPool.put(stack.pop()) - gas := evm.callGasTemp +func opCallCode(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { + // Pop gas. The actual gas is in interpreter.evm.callGasTemp. + interpreter.intPool.put(stack.pop()) + gas := interpreter.evm.callGasTemp // Pop other call parameters. addr, value, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop() toAddr := common.BigToAddress(addr) @@ -709,96 +769,96 @@ func opCallCode(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack if value.Sign() != 0 { gas += params.CallStipend } - ret, returnGas, err := evm.CallCode(contract, toAddr, args, gas, value) + ret, returnGas, err := interpreter.evm.CallCode(contract, toAddr, args, gas, value) if err != nil { - stack.push(evm.interpreter.intPool.getZero()) + stack.push(interpreter.intPool.getZero()) } else { - stack.push(evm.interpreter.intPool.get().SetUint64(1)) + stack.push(interpreter.intPool.get().SetUint64(1)) } if err == nil || err == errExecutionReverted { memory.Set(retOffset.Uint64(), retSize.Uint64(), ret) } contract.Gas += returnGas - evm.interpreter.intPool.put(addr, value, inOffset, inSize, retOffset, retSize) + interpreter.intPool.put(addr, value, inOffset, inSize, retOffset, retSize) return ret, nil } -func opDelegateCall(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { - // Pop gas. The actual gas is in evm.callGasTemp. - evm.interpreter.intPool.put(stack.pop()) - gas := evm.callGasTemp +func opDelegateCall(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { + // Pop gas. The actual gas is in interpreter.evm.callGasTemp. + interpreter.intPool.put(stack.pop()) + gas := interpreter.evm.callGasTemp // Pop other call parameters. addr, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop() toAddr := common.BigToAddress(addr) // Get arguments from the memory. args := memory.Get(inOffset.Int64(), inSize.Int64()) - ret, returnGas, err := evm.DelegateCall(contract, toAddr, args, gas) + ret, returnGas, err := interpreter.evm.DelegateCall(contract, toAddr, args, gas) if err != nil { - stack.push(evm.interpreter.intPool.getZero()) + stack.push(interpreter.intPool.getZero()) } else { - stack.push(evm.interpreter.intPool.get().SetUint64(1)) + stack.push(interpreter.intPool.get().SetUint64(1)) } if err == nil || err == errExecutionReverted { memory.Set(retOffset.Uint64(), retSize.Uint64(), ret) } contract.Gas += returnGas - evm.interpreter.intPool.put(addr, inOffset, inSize, retOffset, retSize) + interpreter.intPool.put(addr, inOffset, inSize, retOffset, retSize) return ret, nil } -func opStaticCall(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { - // Pop gas. The actual gas is in evm.callGasTemp. - evm.interpreter.intPool.put(stack.pop()) - gas := evm.callGasTemp +func opStaticCall(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { + // Pop gas. The actual gas is in interpreter.evm.callGasTemp. + interpreter.intPool.put(stack.pop()) + gas := interpreter.evm.callGasTemp // Pop other call parameters. addr, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop() toAddr := common.BigToAddress(addr) // Get arguments from the memory. args := memory.Get(inOffset.Int64(), inSize.Int64()) - ret, returnGas, err := evm.StaticCall(contract, toAddr, args, gas) + ret, returnGas, err := interpreter.evm.StaticCall(contract, toAddr, args, gas) if err != nil { - stack.push(evm.interpreter.intPool.getZero()) + stack.push(interpreter.intPool.getZero()) } else { - stack.push(evm.interpreter.intPool.get().SetUint64(1)) + stack.push(interpreter.intPool.get().SetUint64(1)) } if err == nil || err == errExecutionReverted { memory.Set(retOffset.Uint64(), retSize.Uint64(), ret) } contract.Gas += returnGas - evm.interpreter.intPool.put(addr, inOffset, inSize, retOffset, retSize) + interpreter.intPool.put(addr, inOffset, inSize, retOffset, retSize) return ret, nil } -func opReturn(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opReturn(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { offset, size := stack.pop(), stack.pop() ret := memory.GetPtr(offset.Int64(), size.Int64()) - evm.interpreter.intPool.put(offset, size) + interpreter.intPool.put(offset, size) return ret, nil } -func opRevert(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opRevert(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { offset, size := stack.pop(), stack.pop() ret := memory.GetPtr(offset.Int64(), size.Int64()) - evm.interpreter.intPool.put(offset, size) + interpreter.intPool.put(offset, size) return ret, nil } -func opStop(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { +func opStop(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { return nil, nil } -func opSuicide(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { - balance := evm.StateDB.GetBalance(contract.Address()) - evm.StateDB.AddBalance(common.BigToAddress(stack.pop()), balance) +func opSuicide(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { + balance := interpreter.evm.StateDB.GetBalance(contract.Address()) + interpreter.evm.StateDB.AddBalance(common.BigToAddress(stack.pop()), balance) - evm.StateDB.Suicide(contract.Address()) + interpreter.evm.StateDB.Suicide(contract.Address()) return nil, nil } @@ -806,7 +866,7 @@ func opSuicide(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack * // make log instruction function func makeLog(size int) executionFunc { - return func(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { + return func(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { topics := make([]common.Hash, size) mStart, mSize := stack.pop(), stack.pop() for i := 0; i < size; i++ { @@ -814,23 +874,23 @@ func makeLog(size int) executionFunc { } d := memory.Get(mStart.Int64(), mSize.Int64()) - evm.StateDB.AddLog(&types.Log{ + interpreter.evm.StateDB.AddLog(&types.Log{ Address: contract.Address(), Topics: topics, Data: d, // This is a non-consensus field, but assigned here because // core/state doesn't know the current block number. - BlockNumber: evm.BlockNumber.Uint64(), + BlockNumber: interpreter.evm.BlockNumber.Uint64(), }) - evm.interpreter.intPool.put(mStart, mSize) + interpreter.intPool.put(mStart, mSize) return nil, nil } } // make push instruction function func makePush(size uint64, pushByteSize int) executionFunc { - return func(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { + return func(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { codeLen := len(contract.Code) startMin := codeLen @@ -843,7 +903,7 @@ func makePush(size uint64, pushByteSize int) executionFunc { endMin = startMin + pushByteSize } - integer := evm.interpreter.intPool.get() + integer := interpreter.intPool.get() stack.push(integer.SetBytes(common.RightPadBytes(contract.Code[startMin:endMin], pushByteSize))) *pc += size @@ -851,10 +911,10 @@ func makePush(size uint64, pushByteSize int) executionFunc { } } -// make push instruction function +// make dup instruction function func makeDup(size int64) executionFunc { - return func(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { - stack.dup(evm.interpreter.intPool, int(size)) + return func(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { + stack.dup(interpreter.intPool, int(size)) return nil, nil } } @@ -862,8 +922,8 @@ func makeDup(size int64) executionFunc { // make swap instruction function func makeSwap(size int64) executionFunc { // switch n + 1 otherwise n would be swapped with n - size += 1 - return func(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { + size++ + return func(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { stack.swap(int(size)) return nil, nil } diff --git a/core/vm/instructions_test.go b/core/vm/instructions_test.go index 0de558612c..ec5de94eda 100644 --- a/core/vm/instructions_test.go +++ b/core/vm/instructions_test.go @@ -30,19 +30,23 @@ type twoOperandTest struct { expected string } -func testTwoOperandOp(t *testing.T, tests []twoOperandTest, opFn func(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error)) { +func testTwoOperandOp(t *testing.T, tests []twoOperandTest, opFn func(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error)) { var ( - env = NewEVM(Context{}, nil, params.TestChainConfig, Config{}) - stack = newstack() - pc = uint64(0) + env = NewEVM(Context{}, nil, params.TestChainConfig, Config{}) + stack = newstack() + pc = uint64(0) + evmInterpreter = NewEVMInterpreter(env, env.vmConfig) ) + + env.interpreter = evmInterpreter + evmInterpreter.intPool = poolOfIntPools.get() for i, test := range tests { x := new(big.Int).SetBytes(common.Hex2Bytes(test.x)) shift := new(big.Int).SetBytes(common.Hex2Bytes(test.y)) expected := new(big.Int).SetBytes(common.Hex2Bytes(test.expected)) stack.push(x) stack.push(shift) - opFn(&pc, env, nil, nil, stack) + opFn(&pc, evmInterpreter, nil, nil, stack) actual := stack.pop() if actual.Cmp(expected) != 0 { t.Errorf("Testcase %d, expected %v, got %v", i, expected, actual) @@ -50,13 +54,13 @@ func testTwoOperandOp(t *testing.T, tests []twoOperandTest, opFn func(pc *uint64 // Check pool usage // 1.pool is not allowed to contain anything on the stack // 2.pool is not allowed to contain the same pointers twice - if env.interpreter.intPool.pool.len() > 0 { + if evmInterpreter.intPool.pool.len() > 0 { poolvals := make(map[*big.Int]struct{}) poolvals[actual] = struct{}{} - for env.interpreter.intPool.pool.len() > 0 { - key := env.interpreter.intPool.get() + for evmInterpreter.intPool.pool.len() > 0 { + key := evmInterpreter.intPool.get() if _, exist := poolvals[key]; exist { t.Errorf("Testcase %d, pool contains double-entry", i) } @@ -64,13 +68,18 @@ func testTwoOperandOp(t *testing.T, tests []twoOperandTest, opFn func(pc *uint64 } } } + poolOfIntPools.put(evmInterpreter.intPool) } func TestByteOp(t *testing.T) { var ( - env = NewEVM(Context{}, nil, params.TestChainConfig, Config{}) - stack = newstack() + env = NewEVM(Context{}, nil, params.TestChainConfig, Config{}) + stack = newstack() + evmInterpreter = NewEVMInterpreter(env, env.vmConfig) ) + + env.interpreter = evmInterpreter + evmInterpreter.intPool = poolOfIntPools.get() tests := []struct { v string th uint64 @@ -91,12 +100,13 @@ func TestByteOp(t *testing.T) { th := new(big.Int).SetUint64(test.th) stack.push(val) stack.push(th) - opByte(&pc, env, nil, nil, stack) + opByte(&pc, evmInterpreter, nil, nil, stack) actual := stack.pop() if actual.Cmp(test.expected) != 0 { t.Fatalf("Expected [%v] %v:th byte to be %v, was %v.", test.v, test.th, test.expected, actual) } } + poolOfIntPools.put(evmInterpreter.intPool) } func TestSHL(t *testing.T) { @@ -196,11 +206,14 @@ func TestSLT(t *testing.T) { testTwoOperandOp(t, tests, opSlt) } -func opBenchmark(bench *testing.B, op func(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error), args ...string) { +func opBenchmark(bench *testing.B, op func(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error), args ...string) { var ( - env = NewEVM(Context{}, nil, params.TestChainConfig, Config{}) - stack = newstack() + env = NewEVM(Context{}, nil, params.TestChainConfig, Config{}) + stack = newstack() + evmInterpreter = NewEVMInterpreter(env, env.vmConfig) ) + + env.interpreter = evmInterpreter // convert args byteArgs := make([][]byte, len(args)) for i, arg := range args { @@ -213,7 +226,7 @@ func opBenchmark(bench *testing.B, op func(pc *uint64, evm *EVM, contract *Contr a := new(big.Int).SetBytes(arg) stack.push(a) } - op(&pc, env, nil, nil, stack) + op(&pc, evmInterpreter, nil, nil, stack) stack.pop() } } @@ -425,3 +438,50 @@ func BenchmarkOpIsZero(b *testing.B) { x := "FBCDEF090807060504030201ffffffffFBCDEF090807060504030201ffffffff" opBenchmark(b, opIszero, x) } + +func TestOpMstore(t *testing.T) { + var ( + env = NewEVM(Context{}, nil, params.TestChainConfig, Config{}) + stack = newstack() + mem = NewMemory() + evmInterpreter = NewEVMInterpreter(env, env.vmConfig) + ) + + env.interpreter = evmInterpreter + evmInterpreter.intPool = poolOfIntPools.get() + mem.Resize(64) + pc := uint64(0) + v := "abcdef00000000000000abba000000000deaf000000c0de00100000000133700" + stack.pushN(new(big.Int).SetBytes(common.Hex2Bytes(v)), big.NewInt(0)) + opMstore(&pc, evmInterpreter, nil, mem, stack) + if got := common.Bytes2Hex(mem.Get(0, 32)); got != v { + t.Fatalf("Mstore fail, got %v, expected %v", got, v) + } + stack.pushN(big.NewInt(0x1), big.NewInt(0)) + opMstore(&pc, evmInterpreter, nil, mem, stack) + if common.Bytes2Hex(mem.Get(0, 32)) != "0000000000000000000000000000000000000000000000000000000000000001" { + t.Fatalf("Mstore failed to overwrite previous value") + } + poolOfIntPools.put(evmInterpreter.intPool) +} + +func BenchmarkOpMstore(bench *testing.B) { + var ( + env = NewEVM(Context{}, nil, params.TestChainConfig, Config{}) + stack = newstack() + mem = NewMemory() + evmInterpreter = NewEVMInterpreter(env, env.vmConfig) + ) + + env.interpreter = evmInterpreter + mem.Resize(64) + pc := uint64(0) + memStart := big.NewInt(0) + value := big.NewInt(0x1337) + + bench.ResetTimer() + for i := 0; i < bench.N; i++ { + stack.pushN(value, memStart) + opMstore(&pc, evmInterpreter, nil, mem, stack) + } +} diff --git a/core/vm/interpreter.go b/core/vm/interpreter.go index 7090e0261f..1e9202424a 100644 --- a/core/vm/interpreter.go +++ b/core/vm/interpreter.go @@ -45,7 +45,30 @@ type Config struct { // passed environment to query external sources for state information. // The Interpreter will run the byte code VM based on the passed // configuration. -type Interpreter struct { +type Interpreter interface { + // Run loops and evaluates the contract's code with the given input data and returns + // the return byte-slice and an error if one occurred. + Run(contract *Contract, input []byte) ([]byte, error) + // CanRun tells if the contract, passed as an argument, can be + // run by the current interpreter. This is meant so that the + // caller can do something like: + // + // ```golang + // for _, interpreter := range interpreters { + // if interpreter.CanRun(contract.code) { + // interpreter.Run(contract.code, input) + // } + // } + // ``` + CanRun([]byte) bool + // IsReadOnly reports if the interpreter is in read only mode. + IsReadOnly() bool + // SetReadOnly sets (or unsets) read only mode in the interpreter. + SetReadOnly(bool) +} + +// EVMInterpreter represents an EVM interpreter +type EVMInterpreter struct { evm *EVM cfg Config gasTable params.GasTable @@ -55,8 +78,8 @@ type Interpreter struct { returnData []byte // Last CALL's return data for subsequent reuse } -// NewInterpreter returns a new instance of the Interpreter. -func NewInterpreter(evm *EVM, cfg Config) *Interpreter { +// NewEVMInterpreter returns a new instance of the Interpreter. +func NewEVMInterpreter(evm *EVM, cfg Config) *EVMInterpreter { // We use the STOP instruction whether to see // the jump table was initialised. If it was not // we'll set the default jump table. @@ -73,15 +96,14 @@ func NewInterpreter(evm *EVM, cfg Config) *Interpreter { } } - return &Interpreter{ + return &EVMInterpreter{ evm: evm, cfg: cfg, gasTable: evm.ChainConfig().GasTable(evm.BlockNumber), - intPool: newIntPool(), } } -func (in *Interpreter) enforceRestrictions(op OpCode, operation operation, stack *Stack) error { +func (in *EVMInterpreter) enforceRestrictions(op OpCode, operation operation, stack *Stack) error { if in.evm.chainRules.IsByzantium { if in.readOnly { // If the interpreter is operating in readonly mode, make sure no @@ -103,7 +125,15 @@ func (in *Interpreter) enforceRestrictions(op OpCode, operation operation, stack // It's important to note that any errors returned by the interpreter should be // considered a revert-and-consume-all-gas operation except for // errExecutionReverted which means revert-and-keep-gas-left. -func (in *Interpreter) Run(contract *Contract, input []byte) (ret []byte, err error) { +func (in *EVMInterpreter) Run(contract *Contract, input []byte) (ret []byte, err error) { + if in.intPool == nil { + in.intPool = poolOfIntPools.get() + defer func() { + poolOfIntPools.put(in.intPool) + in.intPool = nil + }() + } + // Increment the call depth which is restricted to 1024 in.evm.depth++ defer func() { in.evm.depth-- }() @@ -133,6 +163,9 @@ func (in *Interpreter) Run(contract *Contract, input []byte) (ret []byte, err er ) contract.Input = input + // Reclaim the stack as an int pool when the execution stops + defer func() { in.intPool.put(stack.data...) }() + if in.cfg.Debug { defer func() { if err != nil { @@ -199,7 +232,7 @@ func (in *Interpreter) Run(contract *Contract, input []byte) (ret []byte, err er } // execute the operation - res, err := operation.execute(&pc, in.evm, contract, mem, stack) + res, err := operation.execute(&pc, in, contract, mem, stack) // verifyPool is a build flag. Pool verification makes sure the integrity // of the integer pool by comparing values to a default value. if verifyPool { @@ -224,3 +257,19 @@ func (in *Interpreter) Run(contract *Contract, input []byte) (ret []byte, err er } return nil, nil } + +// CanRun tells if the contract, passed as an argument, can be +// run by the current interpreter. +func (in *EVMInterpreter) CanRun(code []byte) bool { + return true +} + +// IsReadOnly reports if the interpreter is in read only mode. +func (in *EVMInterpreter) IsReadOnly() bool { + return in.readOnly +} + +// SetReadOnly sets (or unsets) read only mode in the interpreter. +func (in *EVMInterpreter) SetReadOnly(ro bool) { + in.readOnly = ro +} diff --git a/core/vm/intpool.go b/core/vm/intpool.go index 5dbda18eee..917a78d560 100644 --- a/core/vm/intpool.go +++ b/core/vm/intpool.go @@ -16,7 +16,10 @@ package vm -import "math/big" +import ( + "math/big" + "sync" +) var checkVal = big.NewInt(-42) @@ -65,3 +68,39 @@ func (p *intPool) put(is ...*big.Int) { p.pool.push(i) } } + +// The intPool pool's default capacity +const poolDefaultCap = 25 + +// intPoolPool manages a pool of intPools. +type intPoolPool struct { + pools []*intPool + lock sync.Mutex +} + +var poolOfIntPools = &intPoolPool{ + pools: make([]*intPool, 0, poolDefaultCap), +} + +// get is looking for an available pool to return. +func (ipp *intPoolPool) get() *intPool { + ipp.lock.Lock() + defer ipp.lock.Unlock() + + if len(poolOfIntPools.pools) > 0 { + ip := ipp.pools[len(ipp.pools)-1] + ipp.pools = ipp.pools[:len(ipp.pools)-1] + return ip + } + return newIntPool() +} + +// put a pool that has been allocated with get. +func (ipp *intPoolPool) put(ip *intPool) { + ipp.lock.Lock() + defer ipp.lock.Unlock() + + if len(ipp.pools) < cap(ipp.pools) { + ipp.pools = append(ipp.pools, ip) + } +} diff --git a/core/vm/intpool_test.go b/core/vm/intpool_test.go new file mode 100644 index 0000000000..6c0d00f3ce --- /dev/null +++ b/core/vm/intpool_test.go @@ -0,0 +1,55 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package vm + +import ( + "testing" +) + +func TestIntPoolPoolGet(t *testing.T) { + poolOfIntPools.pools = make([]*intPool, 0, poolDefaultCap) + + nip := poolOfIntPools.get() + if nip == nil { + t.Fatalf("Invalid pool allocation") + } +} + +func TestIntPoolPoolPut(t *testing.T) { + poolOfIntPools.pools = make([]*intPool, 0, poolDefaultCap) + + nip := poolOfIntPools.get() + if len(poolOfIntPools.pools) != 0 { + t.Fatalf("Pool got added to list when none should have been") + } + + poolOfIntPools.put(nip) + if len(poolOfIntPools.pools) == 0 { + t.Fatalf("Pool did not get added to list when one should have been") + } +} + +func TestIntPoolPoolReUse(t *testing.T) { + poolOfIntPools.pools = make([]*intPool, 0, poolDefaultCap) + nip := poolOfIntPools.get() + poolOfIntPools.put(nip) + poolOfIntPools.get() + + if len(poolOfIntPools.pools) != 0 { + t.Fatalf("Invalid number of pools. Got %d, expected %d", len(poolOfIntPools.pools), 0) + } +} diff --git a/core/vm/jump_table.go b/core/vm/jump_table.go index 3389941353..deedf70cdb 100644 --- a/core/vm/jump_table.go +++ b/core/vm/jump_table.go @@ -24,7 +24,7 @@ import ( ) type ( - executionFunc func(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) + executionFunc func(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) gasFunc func(params.GasTable, *EVM, *Contract, *Stack, *Memory, uint64) (uint64, error) // last parameter is the requested memory size as a uint64 stackValidationFunc func(*Stack) error memorySizeFunc func(*Stack) *big.Int @@ -33,7 +33,7 @@ type ( var errGasUintOverflow = errors.New("gas uint64 overflow") type operation struct { - // op is the operation function + // execute is the operation function execute executionFunc // gasCost is the gas function and returns the gas required for execution gasCost gasFunc @@ -51,17 +51,17 @@ type operation struct { } var ( - frontierInstructionSet = NewFrontierInstructionSet() - homesteadInstructionSet = NewHomesteadInstructionSet() - byzantiumInstructionSet = NewByzantiumInstructionSet() - constantinopleInstructionSet = NewConstantinopleInstructionSet() + frontierInstructionSet = newFrontierInstructionSet() + homesteadInstructionSet = newHomesteadInstructionSet() + byzantiumInstructionSet = newByzantiumInstructionSet() + constantinopleInstructionSet = newConstantinopleInstructionSet() ) // NewConstantinopleInstructionSet returns the frontier, homestead // byzantium and contantinople instructions. -func NewConstantinopleInstructionSet() [256]operation { +func newConstantinopleInstructionSet() [256]operation { // instructions that can be executed during the byzantium phase. - instructionSet := NewByzantiumInstructionSet() + instructionSet := newByzantiumInstructionSet() instructionSet[SHL] = operation{ execute: opSHL, gasCost: constGasFunc(GasFastestStep), @@ -80,14 +80,29 @@ func NewConstantinopleInstructionSet() [256]operation { validateStack: makeStackFunc(2, 1), valid: true, } + instructionSet[EXTCODEHASH] = operation{ + execute: opExtCodeHash, + gasCost: gasExtCodeHash, + validateStack: makeStackFunc(1, 1), + valid: true, + } + instructionSet[CREATE2] = operation{ + execute: opCreate2, + gasCost: gasCreate2, + validateStack: makeStackFunc(4, 1), + memorySize: memoryCreate2, + valid: true, + writes: true, + returns: true, + } return instructionSet } // NewByzantiumInstructionSet returns the frontier, homestead and // byzantium instructions. -func NewByzantiumInstructionSet() [256]operation { +func newByzantiumInstructionSet() [256]operation { // instructions that can be executed during the homestead phase. - instructionSet := NewHomesteadInstructionSet() + instructionSet := newHomesteadInstructionSet() instructionSet[STATICCALL] = operation{ execute: opStaticCall, gasCost: gasStaticCall, @@ -123,8 +138,8 @@ func NewByzantiumInstructionSet() [256]operation { // NewHomesteadInstructionSet returns the frontier and homestead // instructions that can be executed during the homestead phase. -func NewHomesteadInstructionSet() [256]operation { - instructionSet := NewFrontierInstructionSet() +func newHomesteadInstructionSet() [256]operation { + instructionSet := newFrontierInstructionSet() instructionSet[DELEGATECALL] = operation{ execute: opDelegateCall, gasCost: gasDelegateCall, @@ -138,7 +153,7 @@ func NewHomesteadInstructionSet() [256]operation { // NewFrontierInstructionSet returns the frontier instructions // that can be executed during the frontier phase. -func NewFrontierInstructionSet() [256]operation { +func newFrontierInstructionSet() [256]operation { return [256]operation{ STOP: { execute: opStop, diff --git a/core/vm/logger.go b/core/vm/logger.go index 4c820d8b53..85acb8d6d3 100644 --- a/core/vm/logger.go +++ b/core/vm/logger.go @@ -29,11 +29,13 @@ import ( "github.com/ethereum/go-ethereum/core/types" ) +// Storage represents a contract's storage. type Storage map[common.Hash]common.Hash -func (self Storage) Copy() Storage { +// Copy duplicates the current storage. +func (s Storage) Copy() Storage { cpy := make(Storage) - for key, value := range self { + for key, value := range s { cpy[key] = value } @@ -45,6 +47,7 @@ type LogConfig struct { DisableMemory bool // disable memory capture DisableStack bool // disable stack capture DisableStorage bool // disable storage capture + Debug bool // print output during capture end Limit int // maximum length of output, but zero means unlimited } @@ -75,10 +78,12 @@ type structLogMarshaling struct { ErrorString string `json:"error"` // adds call to ErrorString() in MarshalJSON } +// OpName formats the operand name in a human-readable format. func (s *StructLog) OpName() string { return s.Op.String() } +// ErrorString formats the log's error as a string. func (s *StructLog) ErrorString() string { if s.Err != nil { return s.Err.Error() @@ -123,6 +128,7 @@ func NewStructLogger(cfg *LogConfig) *StructLogger { return logger } +// CaptureStart implements the Tracer interface to initialize the tracing operation. func (l *StructLogger) CaptureStart(from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) error { return nil } @@ -177,13 +183,22 @@ func (l *StructLogger) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost ui return nil } +// CaptureFault implements the Tracer interface to trace an execution fault +// while running an opcode. func (l *StructLogger) CaptureFault(env *EVM, pc uint64, op OpCode, gas, cost uint64, memory *Memory, stack *Stack, contract *Contract, depth int, err error) error { return nil } +// CaptureEnd is called after the call finishes to finalize the tracing. func (l *StructLogger) CaptureEnd(output []byte, gasUsed uint64, t time.Duration, err error) error { l.output = output l.err = err + if l.cfg.Debug { + fmt.Printf("0x%x\n", output) + if err != nil { + fmt.Printf(" error: %v\n", err) + } + } return nil } diff --git a/core/vm/memory.go b/core/vm/memory.go index 99a84d2271..722862b1de 100644 --- a/core/vm/memory.go +++ b/core/vm/memory.go @@ -16,7 +16,12 @@ package vm -import "fmt" +import ( + "fmt" + "math/big" + + "github.com/ethereum/go-ethereum/common/math" +) // Memory implements a simple memory model for the ethereum virtual machine. type Memory struct { @@ -24,25 +29,39 @@ type Memory struct { lastGasCost uint64 } +// NewMemory returns a new memory memory model. func NewMemory() *Memory { return &Memory{} } // Set sets offset + size to value func (m *Memory) Set(offset, size uint64, value []byte) { - // length of store may never be less than offset + size. - // The store should be resized PRIOR to setting the memory - if size > uint64(len(m.store)) { - panic("INVALID memory: store empty") - } - // It's possible the offset is greater than 0 and size equals 0. This is because // the calcMemSize (common.go) could potentially return 0 when size is zero (NO-OP) if size > 0 { + // length of store may never be less than offset + size. + // The store should be resized PRIOR to setting the memory + if offset+size > uint64(len(m.store)) { + panic("invalid memory: store empty") + } copy(m.store[offset:offset+size], value) } } +// Set32 sets the 32 bytes starting at offset to the value of val, left-padded with zeroes to +// 32 bytes. +func (m *Memory) Set32(offset uint64, val *big.Int) { + // length of store may never be less than offset + size. + // The store should be resized PRIOR to setting the memory + if offset+32 > uint64(len(m.store)) { + panic("invalid memory: store empty") + } + // Zero the memory area + copy(m.store[offset:offset+32], []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}) + // Fill in relevant bits + math.ReadBits(val, m.store[offset:offset+32]) +} + // Resize resizes the memory to size func (m *Memory) Resize(size uint64) { if uint64(m.Len()) < size { @@ -51,14 +70,14 @@ func (m *Memory) Resize(size uint64) { } // Get returns offset + size as a new slice -func (self *Memory) Get(offset, size int64) (cpy []byte) { +func (m *Memory) Get(offset, size int64) (cpy []byte) { if size == 0 { return nil } - if len(self.store) > int(offset) { + if len(m.store) > int(offset) { cpy = make([]byte, size) - copy(cpy, self.store[offset:offset+size]) + copy(cpy, m.store[offset:offset+size]) return } @@ -67,13 +86,13 @@ func (self *Memory) Get(offset, size int64) (cpy []byte) { } // GetPtr returns the offset + size -func (self *Memory) GetPtr(offset, size int64) []byte { +func (m *Memory) GetPtr(offset, size int64) []byte { if size == 0 { return nil } - if len(self.store) > int(offset) { - return self.store[offset : offset+size] + if len(m.store) > int(offset) { + return m.store[offset : offset+size] } return nil @@ -89,6 +108,7 @@ func (m *Memory) Data() []byte { return m.store } +// Print dumps the content of the memory. func (m *Memory) Print() { fmt.Printf("### mem %d bytes ###\n", len(m.store)) if len(m.store) > 0 { diff --git a/core/vm/memory_table.go b/core/vm/memory_table.go index bec0235bcc..8fa6c90ca7 100644 --- a/core/vm/memory_table.go +++ b/core/vm/memory_table.go @@ -58,6 +58,10 @@ func memoryCreate(stack *Stack) *big.Int { return calcMemSize(stack.Back(1), stack.Back(2)) } +func memoryCreate2(stack *Stack) *big.Int { + return calcMemSize(stack.Back(1), stack.Back(2)) +} + func memoryCall(stack *Stack) *big.Int { x := calcMemSize(stack.Back(5), stack.Back(6)) y := calcMemSize(stack.Back(3), stack.Back(4)) @@ -65,12 +69,6 @@ func memoryCall(stack *Stack) *big.Int { return math.BigMax(x, y) } -func memoryCallCode(stack *Stack) *big.Int { - x := calcMemSize(stack.Back(5), stack.Back(6)) - y := calcMemSize(stack.Back(3), stack.Back(4)) - - return math.BigMax(x, y) -} func memoryDelegateCall(stack *Stack) *big.Int { x := calcMemSize(stack.Back(4), stack.Back(5)) y := calcMemSize(stack.Back(2), stack.Back(3)) diff --git a/core/vm/opcodes.go b/core/vm/opcodes.go index 7fe55b72f6..4349ffd295 100644 --- a/core/vm/opcodes.go +++ b/core/vm/opcodes.go @@ -23,6 +23,7 @@ import ( // OpCode is an EVM opcode type OpCode byte +// IsPush specifies if an opcode is a PUSH opcode. func (op OpCode) IsPush() bool { switch op { case PUSH1, PUSH2, PUSH3, PUSH4, PUSH5, PUSH6, PUSH7, PUSH8, PUSH9, PUSH10, PUSH11, PUSH12, PUSH13, PUSH14, PUSH15, PUSH16, PUSH17, PUSH18, PUSH19, PUSH20, PUSH21, PUSH22, PUSH23, PUSH24, PUSH25, PUSH26, PUSH27, PUSH28, PUSH29, PUSH30, PUSH31, PUSH32: @@ -31,12 +32,13 @@ func (op OpCode) IsPush() bool { return false } +// IsStaticJump specifies if an opcode is JUMP. func (op OpCode) IsStaticJump() bool { return op == JUMP } +// 0x0 range - arithmetic ops. const ( - // 0x0 range - arithmetic ops STOP OpCode = iota ADD MUL @@ -51,6 +53,7 @@ const ( SIGNEXTEND ) +// 0x10 range - comparison ops. const ( LT OpCode = iota + 0x10 GT @@ -70,8 +73,8 @@ const ( SHA3 = 0x20 ) +// 0x30 range - closure state. const ( - // 0x30 range - closure state ADDRESS OpCode = 0x30 + iota BALANCE ORIGIN @@ -87,10 +90,11 @@ const ( EXTCODECOPY RETURNDATASIZE RETURNDATACOPY + EXTCODEHASH ) +// 0x40 range - block operations. const ( - // 0x40 range - block operations BLOCKHASH OpCode = 0x40 + iota COINBASE TIMESTAMP @@ -99,8 +103,8 @@ const ( GASLIMIT ) +// 0x50 range - 'storage' and execution. const ( - // 0x50 range - 'storage' and execution POP OpCode = 0x50 + iota MLOAD MSTORE @@ -115,8 +119,8 @@ const ( JUMPDEST ) +// 0x60 range. const ( - // 0x60 range PUSH1 OpCode = 0x60 + iota PUSH2 PUSH3 @@ -183,6 +187,7 @@ const ( SWAP16 ) +// 0xa0 range - logging ops. const ( LOG0 OpCode = 0xa0 + iota LOG1 @@ -191,29 +196,30 @@ const ( LOG4 ) -// unofficial opcodes used for parsing +// unofficial opcodes used for parsing. const ( PUSH OpCode = 0xb0 + iota DUP SWAP ) +// 0xf0 range - closures. const ( - // 0xf0 range - closures CREATE OpCode = 0xf0 + iota CALL CALLCODE RETURN DELEGATECALL + CREATE2 STATICCALL = 0xfa REVERT = 0xfd SELFDESTRUCT = 0xff ) -// Since the opcodes aren't all in order we can't use a regular slice +// Since the opcodes aren't all in order we can't use a regular slice. var opCodeToString = map[OpCode]string{ - // 0x0 range - arithmetic ops + // 0x0 range - arithmetic ops. STOP: "STOP", ADD: "ADD", MUL: "MUL", @@ -232,7 +238,7 @@ var opCodeToString = map[OpCode]string{ ISZERO: "ISZERO", SIGNEXTEND: "SIGNEXTEND", - // 0x10 range - bit ops + // 0x10 range - bit ops. AND: "AND", OR: "OR", XOR: "XOR", @@ -243,10 +249,10 @@ var opCodeToString = map[OpCode]string{ ADDMOD: "ADDMOD", MULMOD: "MULMOD", - // 0x20 range - crypto + // 0x20 range - crypto. SHA3: "SHA3", - // 0x30 range - closure state + // 0x30 range - closure state. ADDRESS: "ADDRESS", BALANCE: "BALANCE", ORIGIN: "ORIGIN", @@ -262,8 +268,9 @@ var opCodeToString = map[OpCode]string{ EXTCODECOPY: "EXTCODECOPY", RETURNDATASIZE: "RETURNDATASIZE", RETURNDATACOPY: "RETURNDATACOPY", + EXTCODEHASH: "EXTCODEHASH", - // 0x40 range - block operations + // 0x40 range - block operations. BLOCKHASH: "BLOCKHASH", COINBASE: "COINBASE", TIMESTAMP: "TIMESTAMP", @@ -271,7 +278,7 @@ var opCodeToString = map[OpCode]string{ DIFFICULTY: "DIFFICULTY", GASLIMIT: "GASLIMIT", - // 0x50 range - 'storage' and execution + // 0x50 range - 'storage' and execution. POP: "POP", //DUP: "DUP", //SWAP: "SWAP", @@ -287,7 +294,7 @@ var opCodeToString = map[OpCode]string{ GAS: "GAS", JUMPDEST: "JUMPDEST", - // 0x60 range - push + // 0x60 range - push. PUSH1: "PUSH1", PUSH2: "PUSH2", PUSH3: "PUSH3", @@ -360,12 +367,13 @@ var opCodeToString = map[OpCode]string{ LOG3: "LOG3", LOG4: "LOG4", - // 0xf0 range + // 0xf0 range. CREATE: "CREATE", CALL: "CALL", RETURN: "RETURN", CALLCODE: "CALLCODE", DELEGATECALL: "DELEGATECALL", + CREATE2: "CREATE2", STATICCALL: "STATICCALL", REVERT: "REVERT", SELFDESTRUCT: "SELFDESTRUCT", @@ -375,10 +383,10 @@ var opCodeToString = map[OpCode]string{ SWAP: "SWAP", } -func (o OpCode) String() string { - str := opCodeToString[o] +func (op OpCode) String() string { + str := opCodeToString[op] if len(str) == 0 { - return fmt.Sprintf("Missing opcode 0x%x", int(o)) + return fmt.Sprintf("Missing opcode 0x%x", int(op)) } return str @@ -429,6 +437,7 @@ var stringToOp = map[string]OpCode{ "EXTCODECOPY": EXTCODECOPY, "RETURNDATASIZE": RETURNDATASIZE, "RETURNDATACOPY": RETURNDATACOPY, + "EXTCODEHASH": EXTCODEHASH, "BLOCKHASH": BLOCKHASH, "COINBASE": COINBASE, "TIMESTAMP": TIMESTAMP, @@ -517,6 +526,7 @@ var stringToOp = map[string]OpCode{ "LOG3": LOG3, "LOG4": LOG4, "CREATE": CREATE, + "CREATE2": CREATE2, "CALL": CALL, "RETURN": RETURN, "CALLCODE": CALLCODE, @@ -524,6 +534,7 @@ var stringToOp = map[string]OpCode{ "SELFDESTRUCT": SELFDESTRUCT, } +// StringToOp finds the opcode whose name is stored in `str`. func StringToOp(str string) OpCode { return stringToOp[str] } diff --git a/core/vm/runtime/runtime.go b/core/vm/runtime/runtime.go index 1e9ed7ae2d..cda49a34b4 100644 --- a/core/vm/runtime/runtime.go +++ b/core/vm/runtime/runtime.go @@ -52,7 +52,7 @@ type Config struct { func setDefaults(cfg *Config) { if cfg.ChainConfig == nil { cfg.ChainConfig = ¶ms.ChainConfig{ - ChainId: big.NewInt(1), + ChainID: big.NewInt(1), HomesteadBlock: new(big.Int), DAOForkBlock: new(big.Int), DAOForkSupport: false, @@ -99,11 +99,10 @@ func Execute(code, input []byte, cfg *Config) ([]byte, *state.StateDB, error) { setDefaults(cfg) if cfg.State == nil { - db, _ := ethdb.NewMemDatabase() - cfg.State, _ = state.New(common.Hash{}, state.NewDatabase(db)) + cfg.State, _ = state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) } var ( - address = common.StringToAddress("contract") + address = common.BytesToAddress([]byte("contract")) vmenv = NewEnv(cfg) sender = vm.AccountRef(cfg.Origin) ) @@ -113,7 +112,7 @@ func Execute(code, input []byte, cfg *Config) ([]byte, *state.StateDB, error) { // Call the code with the given configuration. ret, _, err := vmenv.Call( sender, - common.StringToAddress("contract"), + common.BytesToAddress([]byte("contract")), input, cfg.GasLimit, cfg.Value, @@ -130,8 +129,7 @@ func Create(input []byte, cfg *Config) ([]byte, common.Address, uint64, error) { setDefaults(cfg) if cfg.State == nil { - db, _ := ethdb.NewMemDatabase() - cfg.State, _ = state.New(common.Hash{}, state.NewDatabase(db)) + cfg.State, _ = state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) } var ( vmenv = NewEnv(cfg) diff --git a/core/vm/runtime/runtime_test.go b/core/vm/runtime/runtime_test.go index 2c4dc50265..ef664bda30 100644 --- a/core/vm/runtime/runtime_test.go +++ b/core/vm/runtime/runtime_test.go @@ -94,8 +94,7 @@ func TestExecute(t *testing.T) { } func TestCall(t *testing.T) { - db, _ := ethdb.NewMemDatabase() - state, _ := state.New(common.Hash{}, state.NewDatabase(db)) + state, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) address := common.HexToAddress("0x0a") state.SetCode(address, []byte{ byte(vm.PUSH1), 10, diff --git a/core/vm/stack.go b/core/vm/stack.go index 9c10d50ad1..4c1b9e8037 100644 --- a/core/vm/stack.go +++ b/core/vm/stack.go @@ -21,7 +21,7 @@ import ( "math/big" ) -// stack is an object for basic stack operations. Items popped to the stack are +// Stack is an object for basic stack operations. Items popped to the stack are // expected to be changed and modified. stack does not take care of adding newly // initialised objects. type Stack struct { @@ -32,6 +32,7 @@ func newstack() *Stack { return &Stack{data: make([]*big.Int, 0, 1024)} } +// Data returns the underlying big.Int array. func (st *Stack) Data() []*big.Int { return st.data } @@ -80,6 +81,7 @@ func (st *Stack) require(n int) error { return nil } +// Print dumps the content of the stack func (st *Stack) Print() { fmt.Println("### stack ###") if len(st.data) > 0 { diff --git a/crypto/bn256/cloudflare/example_test.go b/crypto/bn256/cloudflare/example_test.go index b2d19807a2..6c285995cb 100644 --- a/crypto/bn256/cloudflare/example_test.go +++ b/crypto/bn256/cloudflare/example_test.go @@ -6,9 +6,12 @@ package bn256 import ( "crypto/rand" + "testing" + + "github.com/stretchr/testify/require" ) -func ExamplePair() { +func TestExamplePair(t *testing.T) { // This implements the tripartite Diffie-Hellman algorithm from "A One // Round Protocol for Tripartite Diffie-Hellman", A. Joux. // http://www.springerlink.com/content/cddc57yyva0hburb/fulltext.pdf @@ -40,4 +43,9 @@ func ExamplePair() { k3.ScalarMult(k3, c) // k1, k2 and k3 will all be equal. + + require.Equal(t, k1, k2) + require.Equal(t, k1, k3) + + require.Equal(t, len(np), 4) //Avoid gometalinter varcheck err on np } diff --git a/crypto/crypto.go b/crypto/crypto.go index 1c4d5a2e02..dec6e3c19e 100644 --- a/crypto/crypto.go +++ b/crypto/crypto.go @@ -35,10 +35,12 @@ import ( ) var ( - secp256k1_N, _ = new(big.Int).SetString("fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141", 16) - secp256k1_halfN = new(big.Int).Div(secp256k1_N, big.NewInt(2)) + secp256k1N, _ = new(big.Int).SetString("fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141", 16) + secp256k1halfN = new(big.Int).Div(secp256k1N, big.NewInt(2)) ) +var errInvalidPubkey = errors.New("invalid secp256k1 public key") + // Keccak256 calculates and returns the Keccak256 hash of the input data. func Keccak256(data ...[]byte) []byte { d := sha3.NewKeccak256() @@ -68,12 +70,18 @@ func Keccak512(data ...[]byte) []byte { return d.Sum(nil) } -// Creates an ethereum address given the bytes and the nonce +// CreateAddress creates an ethereum address given the bytes and the nonce func CreateAddress(b common.Address, nonce uint64) common.Address { data, _ := rlp.EncodeToBytes([]interface{}{b, nonce}) return common.BytesToAddress(Keccak256(data)[12:]) } +// CreateAddress2 creates an ethereum address given the address bytes, initial +// contract code and a salt. +func CreateAddress2(b common.Address, salt common.Hash, code []byte) common.Address { + return common.BytesToAddress(Keccak256([]byte{0xff}, b.Bytes(), salt.Bytes(), code)[12:]) +} + // ToECDSA creates a private key with the given D value. func ToECDSA(d []byte) (*ecdsa.PrivateKey, error) { return toECDSA(d, true) @@ -99,7 +107,7 @@ func toECDSA(d []byte, strict bool) (*ecdsa.PrivateKey, error) { priv.D = new(big.Int).SetBytes(d) // The priv.D must < N - if priv.D.Cmp(secp256k1_N) >= 0 { + if priv.D.Cmp(secp256k1N) >= 0 { return nil, fmt.Errorf("invalid private key, >=N") } // The priv.D must not be zero or negative. @@ -122,12 +130,13 @@ func FromECDSA(priv *ecdsa.PrivateKey) []byte { return math.PaddedBigBytes(priv.D, priv.Params().BitSize/8) } -func ToECDSAPub(pub []byte) *ecdsa.PublicKey { - if len(pub) == 0 { - return nil - } +// UnmarshalPubkey converts bytes to a secp256k1 public key. +func UnmarshalPubkey(pub []byte) (*ecdsa.PublicKey, error) { x, y := elliptic.Unmarshal(S256(), pub) - return &ecdsa.PublicKey{Curve: S256(), X: x, Y: y} + if x == nil { + return nil, errInvalidPubkey + } + return &ecdsa.PublicKey{Curve: S256(), X: x, Y: y}, nil } func FromECDSAPub(pub *ecdsa.PublicKey) []byte { @@ -184,11 +193,11 @@ func ValidateSignatureValues(v byte, r, s *big.Int, homestead bool) bool { } // reject upper range of s values (ECDSA malleability) // see discussion in secp256k1/libsecp256k1/include/secp256k1.h - if homestead && s.Cmp(secp256k1_halfN) > 0 { + if homestead && s.Cmp(secp256k1halfN) > 0 { return false } // Frontier: allow s to be in full N range - return r.Cmp(secp256k1_N) < 0 && s.Cmp(secp256k1_N) < 0 && (v == 0 || v == 1) + return r.Cmp(secp256k1N) < 0 && s.Cmp(secp256k1N) < 0 && (v == 0 || v == 1) } func PubkeyToAddress(p ecdsa.PublicKey) common.Address { diff --git a/crypto/crypto_test.go b/crypto/crypto_test.go index 8350354623..177c19c0cf 100644 --- a/crypto/crypto_test.go +++ b/crypto/crypto_test.go @@ -23,9 +23,11 @@ import ( "io/ioutil" "math/big" "os" + "reflect" "testing" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" ) var testAddrHex = "970e8128ab834e8eac17ab8e3812f010678cf791" @@ -56,6 +58,33 @@ func BenchmarkSha3(b *testing.B) { } } +func TestUnmarshalPubkey(t *testing.T) { + key, err := UnmarshalPubkey(nil) + if err != errInvalidPubkey || key != nil { + t.Fatalf("expected error, got %v, %v", err, key) + } + key, err = UnmarshalPubkey([]byte{1, 2, 3}) + if err != errInvalidPubkey || key != nil { + t.Fatalf("expected error, got %v, %v", err, key) + } + + var ( + enc, _ = hex.DecodeString("04760c4460e5336ac9bbd87952a3c7ec4363fc0a97bd31c86430806e287b437fd1b01abc6e1db640cf3106b520344af1d58b00b57823db3e1407cbc433e1b6d04d") + dec = &ecdsa.PublicKey{ + Curve: S256(), + X: hexutil.MustDecodeBig("0x760c4460e5336ac9bbd87952a3c7ec4363fc0a97bd31c86430806e287b437fd1"), + Y: hexutil.MustDecodeBig("0xb01abc6e1db640cf3106b520344af1d58b00b57823db3e1407cbc433e1b6d04d"), + } + ) + key, err = UnmarshalPubkey(enc) + if err != nil { + t.Fatalf("expected no error, got %v", err) + } + if !reflect.DeepEqual(key, dec) { + t.Fatal("wrong result") + } +} + func TestSign(t *testing.T) { key, _ := HexToECDSA(testPrivHex) addr := common.HexToAddress(testAddrHex) @@ -69,7 +98,7 @@ func TestSign(t *testing.T) { if err != nil { t.Errorf("ECRecover error: %s", err) } - pubKey := ToECDSAPub(recoveredPub) + pubKey, _ := UnmarshalPubkey(recoveredPub) recoveredAddr := PubkeyToAddress(*pubKey) if addr != recoveredAddr { t.Errorf("Address mismatch: want: %x have: %x", addr, recoveredAddr) @@ -154,7 +183,7 @@ func TestValidateSignatureValues(t *testing.T) { minusOne := big.NewInt(-1) one := common.Big1 zero := common.Big0 - secp256k1nMinus1 := new(big.Int).Sub(secp256k1_N, common.Big1) + secp256k1nMinus1 := new(big.Int).Sub(secp256k1N, common.Big1) // correct v,r,s check(true, 0, one, one) @@ -181,9 +210,9 @@ func TestValidateSignatureValues(t *testing.T) { // correct sig with max r,s check(true, 0, secp256k1nMinus1, secp256k1nMinus1) // correct v, combinations of incorrect r,s at upper limit - check(false, 0, secp256k1_N, secp256k1nMinus1) - check(false, 0, secp256k1nMinus1, secp256k1_N) - check(false, 0, secp256k1_N, secp256k1_N) + check(false, 0, secp256k1N, secp256k1nMinus1) + check(false, 0, secp256k1nMinus1, secp256k1N) + check(false, 0, secp256k1N, secp256k1N) // current callers ensures r,s cannot be negative, but let's test for that too // as crypto package could be used stand-alone diff --git a/crypto/secp256k1/LICENSE b/crypto/secp256k1/LICENSE new file mode 100644 index 0000000000..f9090e1423 --- /dev/null +++ b/crypto/secp256k1/LICENSE @@ -0,0 +1,31 @@ +Copyright (c) 2010 The Go Authors. All rights reserved. +Copyright (c) 2011 ThePiachu. All rights reserved. +Copyright (c) 2015 Jeffrey Wilcke. All rights reserved. +Copyright (c) 2015 Felix Lange. All rights reserved. +Copyright (c) 2015 Gustav Simonsson. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of the copyright holder. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/crypto/secp256k1/curve.go b/crypto/secp256k1/curve.go index df80481857..56be235b36 100644 --- a/crypto/secp256k1/curve.go +++ b/crypto/secp256k1/curve.go @@ -1,5 +1,6 @@ // Copyright 2010 The Go Authors. All rights reserved. // Copyright 2011 ThePiachu. All rights reserved. +// Copyright 2015 Jeffrey Wilcke, Felix Lange, Gustav Simonsson. All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are @@ -35,8 +36,6 @@ import ( "crypto/elliptic" "math/big" "unsafe" - - "github.com/ethereum/go-ethereum/common/math" ) /* @@ -45,6 +44,27 @@ extern int secp256k1_ext_scalar_mul(const secp256k1_context* ctx, const unsigned */ import "C" +const ( + // number of bits in a big.Word + wordBits = 32 << (uint64(^big.Word(0)) >> 63) + // number of bytes in a big.Word + wordBytes = wordBits / 8 +) + +// readBits encodes the absolute value of bigint as big-endian bytes. Callers +// must ensure that buf has enough space. If buf is too short the result will +// be incomplete. +func readBits(bigint *big.Int, buf []byte) { + i := len(buf) + for _, d := range bigint.Bits() { + for j := 0; j < wordBytes && i > 0; j++ { + i-- + buf[i] = byte(d) + d >>= 8 + } + } +} + // This code is from https://github.com/ThePiachu/GoBit and implements // several Koblitz elliptic curves over prime fields. // @@ -77,7 +97,7 @@ func (BitCurve *BitCurve) Params() *elliptic.CurveParams { } } -// IsOnBitCurve returns true if the given (x,y) lies on the BitCurve. +// IsOnCurve returns true if the given (x,y) lies on the BitCurve. func (BitCurve *BitCurve) IsOnCurve(x, y *big.Int) bool { // y² = x³ + b y2 := new(big.Int).Mul(y, y) //y² @@ -231,8 +251,9 @@ func (BitCurve *BitCurve) ScalarMult(Bx, By *big.Int, scalar []byte) (*big.Int, // Do the multiplication in C, updating point. point := make([]byte, 64) - math.ReadBits(Bx, point[:32]) - math.ReadBits(By, point[32:]) + readBits(Bx, point[:32]) + readBits(By, point[32:]) + pointPtr := (*C.uchar)(unsafe.Pointer(&point[0])) scalarPtr := (*C.uchar)(unsafe.Pointer(&scalar[0])) res := C.secp256k1_ext_scalar_mul(context, pointPtr, scalarPtr) @@ -264,8 +285,8 @@ func (BitCurve *BitCurve) Marshal(x, y *big.Int) []byte { byteLen := (BitCurve.BitSize + 7) >> 3 ret := make([]byte, 1+2*byteLen) ret[0] = 4 // uncompressed point flag - math.ReadBits(x, ret[1:1+byteLen]) - math.ReadBits(y, ret[1+byteLen:]) + readBits(x, ret[1:1+byteLen]) + readBits(y, ret[1+byteLen:]) return ret } @@ -290,11 +311,11 @@ func init() { // See SEC 2 section 2.7.1 // curve parameters taken from: // http://www.secg.org/collateral/sec2_final.pdf - theCurve.P, _ = new(big.Int).SetString("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", 16) - theCurve.N, _ = new(big.Int).SetString("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", 16) - theCurve.B, _ = new(big.Int).SetString("0000000000000000000000000000000000000000000000000000000000000007", 16) - theCurve.Gx, _ = new(big.Int).SetString("79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", 16) - theCurve.Gy, _ = new(big.Int).SetString("483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8", 16) + theCurve.P, _ = new(big.Int).SetString("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", 0) + theCurve.N, _ = new(big.Int).SetString("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", 0) + theCurve.B, _ = new(big.Int).SetString("0x0000000000000000000000000000000000000000000000000000000000000007", 0) + theCurve.Gx, _ = new(big.Int).SetString("0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", 0) + theCurve.Gy, _ = new(big.Int).SetString("0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8", 0) theCurve.BitSize = 256 } diff --git a/crypto/secp256k1/ext.h b/crypto/secp256k1/ext.h index 9b043c724e..e422fe4b49 100644 --- a/crypto/secp256k1/ext.h +++ b/crypto/secp256k1/ext.h @@ -1,18 +1,6 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . +// Copyright 2015 Jeffrey Wilcke, Felix Lange, Gustav Simonsson. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be found in +// the LICENSE file. // secp256k1_context_create_sign_verify creates a context for signing and signature verification. static secp256k1_context* secp256k1_context_create_sign_verify() { diff --git a/crypto/secp256k1/panic_cb.go b/crypto/secp256k1/panic_cb.go index e0e9034ee0..6d59a1d247 100644 --- a/crypto/secp256k1/panic_cb.go +++ b/crypto/secp256k1/panic_cb.go @@ -1,18 +1,6 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . +// Copyright 2015 Jeffrey Wilcke, Felix Lange, Gustav Simonsson. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be found in +// the LICENSE file. package secp256k1 diff --git a/crypto/secp256k1/secp256.go b/crypto/secp256k1/secp256.go index eefbb99ee4..843fb12525 100644 --- a/crypto/secp256k1/secp256.go +++ b/crypto/secp256k1/secp256.go @@ -1,18 +1,6 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . +// Copyright 2015 Jeffrey Wilcke, Felix Lange, Gustav Simonsson. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be found in +// the LICENSE file. // Package secp256k1 wraps the bitcoin secp256k1 C library. package secp256k1 diff --git a/crypto/secp256k1/secp256_test.go b/crypto/secp256k1/secp256_test.go index f6582ecd54..ef2a3a3790 100644 --- a/crypto/secp256k1/secp256_test.go +++ b/crypto/secp256k1/secp256_test.go @@ -1,18 +1,6 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . +// Copyright 2015 Jeffrey Wilcke, Felix Lange, Gustav Simonsson. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be found in +// the LICENSE file. package secp256k1 @@ -22,10 +10,8 @@ import ( "crypto/elliptic" "crypto/rand" "encoding/hex" + "io" "testing" - - "github.com/ethereum/go-ethereum/common/math" - "github.com/ethereum/go-ethereum/crypto/randentropy" ) const TestCount = 1000 @@ -36,11 +22,24 @@ func generateKeyPair() (pubkey, privkey []byte) { panic(err) } pubkey = elliptic.Marshal(S256(), key.X, key.Y) - return pubkey, math.PaddedBigBytes(key.D, 32) + + privkey = make([]byte, 32) + blob := key.D.Bytes() + copy(privkey[32-len(blob):], blob) + + return pubkey, privkey +} + +func csprngEntropy(n int) []byte { + buf := make([]byte, n) + if _, err := io.ReadFull(rand.Reader, buf); err != nil { + panic("reading from crypto/rand failed: " + err.Error()) + } + return buf } func randSig() []byte { - sig := randentropy.GetEntropyCSPRNG(65) + sig := csprngEntropy(65) sig[32] &= 0x70 sig[64] %= 4 return sig @@ -49,7 +48,7 @@ func randSig() []byte { // tests for malleability // highest bit of signature ECDSA s value must be 0, in the 33th byte func compactSigCheck(t *testing.T, sig []byte) { - var b int = int(sig[32]) + var b = int(sig[32]) if b < 0 { t.Errorf("highest bit is negative: %d", b) } @@ -63,7 +62,7 @@ func compactSigCheck(t *testing.T, sig []byte) { func TestSignatureValidity(t *testing.T) { pubkey, seckey := generateKeyPair() - msg := randentropy.GetEntropyCSPRNG(32) + msg := csprngEntropy(32) sig, err := Sign(msg, seckey) if err != nil { t.Errorf("signature error: %s", err) @@ -86,7 +85,7 @@ func TestSignatureValidity(t *testing.T) { func TestInvalidRecoveryID(t *testing.T) { _, seckey := generateKeyPair() - msg := randentropy.GetEntropyCSPRNG(32) + msg := csprngEntropy(32) sig, _ := Sign(msg, seckey) sig[64] = 99 _, err := RecoverPubkey(msg, sig) @@ -97,7 +96,7 @@ func TestInvalidRecoveryID(t *testing.T) { func TestSignAndRecover(t *testing.T) { pubkey1, seckey := generateKeyPair() - msg := randentropy.GetEntropyCSPRNG(32) + msg := csprngEntropy(32) sig, err := Sign(msg, seckey) if err != nil { t.Errorf("signature error: %s", err) @@ -148,7 +147,7 @@ func TestRandomMessagesWithRandomKeys(t *testing.T) { func signAndRecoverWithRandomMessages(t *testing.T, keys func() ([]byte, []byte)) { for i := 0; i < TestCount; i++ { pubkey1, seckey := keys() - msg := randentropy.GetEntropyCSPRNG(32) + msg := csprngEntropy(32) sig, err := Sign(msg, seckey) if err != nil { t.Fatalf("signature error: %s", err) @@ -176,7 +175,7 @@ func signAndRecoverWithRandomMessages(t *testing.T, keys func() ([]byte, []byte) func TestRecoveryOfRandomSignature(t *testing.T) { pubkey1, _ := generateKeyPair() - msg := randentropy.GetEntropyCSPRNG(32) + msg := csprngEntropy(32) for i := 0; i < TestCount; i++ { // recovery can sometimes work, but if so should always give wrong pubkey @@ -189,11 +188,11 @@ func TestRecoveryOfRandomSignature(t *testing.T) { func TestRandomMessagesAgainstValidSig(t *testing.T) { pubkey1, seckey := generateKeyPair() - msg := randentropy.GetEntropyCSPRNG(32) + msg := csprngEntropy(32) sig, _ := Sign(msg, seckey) for i := 0; i < TestCount; i++ { - msg = randentropy.GetEntropyCSPRNG(32) + msg = csprngEntropy(32) pubkey2, _ := RecoverPubkey(msg, sig) // recovery can sometimes work, but if so should always give wrong pubkey if bytes.Equal(pubkey1, pubkey2) { @@ -219,7 +218,7 @@ func TestRecoverSanity(t *testing.T) { func BenchmarkSign(b *testing.B) { _, seckey := generateKeyPair() - msg := randentropy.GetEntropyCSPRNG(32) + msg := csprngEntropy(32) b.ResetTimer() for i := 0; i < b.N; i++ { @@ -228,7 +227,7 @@ func BenchmarkSign(b *testing.B) { } func BenchmarkRecover(b *testing.B) { - msg := randentropy.GetEntropyCSPRNG(32) + msg := csprngEntropy(32) _, seckey := generateKeyPair() sig, _ := Sign(msg, seckey) b.ResetTimer() diff --git a/crypto/signature_nocgo.go b/crypto/signature_nocgo.go index f636b23772..e8fa18ed47 100644 --- a/crypto/signature_nocgo.go +++ b/crypto/signature_nocgo.go @@ -88,7 +88,7 @@ func VerifySignature(pubkey, hash, signature []byte) bool { return false } // Reject malleable signatures. libsecp256k1 does this check but btcec doesn't. - if sig.S.Cmp(secp256k1_halfN) > 0 { + if sig.S.Cmp(secp256k1halfN) > 0 { return false } return sig.Verify(hash, key) diff --git a/dashboard/assets.go b/dashboard/assets.go index 1304a3dba1..f3e7cf9815 100644 --- a/dashboard/assets.go +++ b/dashboard/assets.go @@ -64,6 +64,9 @@ var _indexHtml = []byte(` ::-webkit-scrollbar-thumb { background: #212121; } + ::-webkit-scrollbar-corner { + background: transparent; + } @@ -84,7 +87,7 @@ func indexHtml() (*asset, error) { } info := bindataFileInfo{name: "index.html", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)} - a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x6b, 0xd9, 0xa6, 0xeb, 0x32, 0x49, 0x9b, 0xe5, 0x3a, 0xcb, 0x99, 0xd3, 0xb6, 0x69, 0x7f, 0xde, 0x35, 0x9d, 0x5, 0x96, 0x84, 0xc0, 0x14, 0xef, 0xbe, 0x58, 0x10, 0x5e, 0x40, 0xf2, 0x12, 0x97}} + a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x22, 0xc8, 0x3d, 0x86, 0x2f, 0xb4, 0x6a, 0x1f, 0xda, 0xd, 0x54, 0x14, 0xa3, 0x6e, 0x80, 0x56, 0x28, 0xea, 0x44, 0xcf, 0xf5, 0xf2, 0xe, 0xad, 0x19, 0xf5, 0x93, 0xd6, 0x8d, 0x6d, 0x2f, 0x35}} return a, nil } @@ -116,11 +119,11 @@ var _bundleJs = []byte((((((((((`!function(modules) { return __webpack_require__.d(getter, "a", getter), getter; }, __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); - }, __webpack_require__.p = "", __webpack_require__(__webpack_require__.s = 336); + }, __webpack_require__.p = "", __webpack_require__(__webpack_require__.s = 375); }([ function(module, exports, __webpack_require__) { "use strict"; (function(process) { - "production" === process.env.NODE_ENV ? module.exports = __webpack_require__(337) : module.exports = __webpack_require__(338); + "production" === process.env.NODE_ENV ? module.exports = __webpack_require__(376) : module.exports = __webpack_require__(377); }).call(exports, __webpack_require__(2)); }, function(module, exports, __webpack_require__) { (function(process) { @@ -128,8 +131,8 @@ var _bundleJs = []byte((((((((((`!function(modules) { var REACT_ELEMENT_TYPE = "function" == typeof Symbol && Symbol.for && Symbol.for("react.element") || 60103, isValidElement = function(object) { return "object" == typeof object && null !== object && object.$$typeof === REACT_ELEMENT_TYPE; }; - module.exports = __webpack_require__(379)(isValidElement, !0); - } else module.exports = __webpack_require__(380)(); + module.exports = __webpack_require__(418)(isValidElement, !0); + } else module.exports = __webpack_require__(419)(); }).call(exports, __webpack_require__(2)); }, function(module, exports) { function defaultSetTimout() { @@ -289,7 +292,7 @@ var _bundleJs = []byte((((((((((`!function(modules) { }), __webpack_require__.d(__webpack_exports__, "o", function() { return parseChildIndex; }); - var __WEBPACK_IMPORTED_MODULE_0_lodash_isNil__ = __webpack_require__(20), __WEBPACK_IMPORTED_MODULE_0_lodash_isNil___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_lodash_isNil__), __WEBPACK_IMPORTED_MODULE_1_lodash_isString__ = __webpack_require__(163), __WEBPACK_IMPORTED_MODULE_1_lodash_isString___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_lodash_isString__), __WEBPACK_IMPORTED_MODULE_2_lodash_isObject__ = __webpack_require__(31), __WEBPACK_IMPORTED_MODULE_2_lodash_isObject___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_2_lodash_isObject__), __WEBPACK_IMPORTED_MODULE_3_lodash_isFunction__ = __webpack_require__(8), __WEBPACK_IMPORTED_MODULE_3_lodash_isFunction___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_3_lodash_isFunction__), __WEBPACK_IMPORTED_MODULE_4_lodash_isArray__ = __webpack_require__(11), __WEBPACK_IMPORTED_MODULE_4_lodash_isArray___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_4_lodash_isArray__), __WEBPACK_IMPORTED_MODULE_5_react__ = __webpack_require__(0), __WEBPACK_IMPORTED_MODULE_5_react___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_5_react__), __WEBPACK_IMPORTED_MODULE_6_prop_types__ = __webpack_require__(1), __WEBPACK_IMPORTED_MODULE_6_prop_types___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_6_prop_types__), __WEBPACK_IMPORTED_MODULE_7__DataUtils__ = __webpack_require__(9), __WEBPACK_IMPORTED_MODULE_8__PureRender__ = __webpack_require__(5), PRESENTATION_ATTRIBUTES = { + var __WEBPACK_IMPORTED_MODULE_0_lodash_isNil__ = __webpack_require__(20), __WEBPACK_IMPORTED_MODULE_0_lodash_isNil___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_lodash_isNil__), __WEBPACK_IMPORTED_MODULE_1_lodash_isString__ = __webpack_require__(173), __WEBPACK_IMPORTED_MODULE_1_lodash_isString___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_lodash_isString__), __WEBPACK_IMPORTED_MODULE_2_lodash_isObject__ = __webpack_require__(32), __WEBPACK_IMPORTED_MODULE_2_lodash_isObject___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_2_lodash_isObject__), __WEBPACK_IMPORTED_MODULE_3_lodash_isFunction__ = __webpack_require__(8), __WEBPACK_IMPORTED_MODULE_3_lodash_isFunction___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_3_lodash_isFunction__), __WEBPACK_IMPORTED_MODULE_4_lodash_isArray__ = __webpack_require__(13), __WEBPACK_IMPORTED_MODULE_4_lodash_isArray___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_4_lodash_isArray__), __WEBPACK_IMPORTED_MODULE_5_react__ = __webpack_require__(0), __WEBPACK_IMPORTED_MODULE_5_react___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_5_react__), __WEBPACK_IMPORTED_MODULE_6_prop_types__ = __webpack_require__(1), __WEBPACK_IMPORTED_MODULE_6_prop_types___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_6_prop_types__), __WEBPACK_IMPORTED_MODULE_7__DataUtils__ = __webpack_require__(9), __WEBPACK_IMPORTED_MODULE_8__PureRender__ = __webpack_require__(5), PRESENTATION_ATTRIBUTES = { alignmentBaseline: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.string, angle: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.number, baselineShift: __WEBPACK_IMPORTED_MODULE_6_prop_types___default.a.string, @@ -502,7 +505,7 @@ var _bundleJs = []byte((((((((((`!function(modules) { }, function(module, exports, __webpack_require__) { "use strict"; exports.__esModule = !0; - var _assign = __webpack_require__(204), _assign2 = function(obj) { + var _assign = __webpack_require__(222), _assign2 = function(obj) { return obj && obj.__esModule ? obj : { default: obj }; @@ -527,7 +530,7 @@ var _bundleJs = []byte((((((((((`!function(modules) { var tag = baseGetTag(value); return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag; } - var baseGetTag = __webpack_require__(41), isObject = __webpack_require__(31), asyncTag = "[object AsyncFunction]", funcTag = "[object Function]", genTag = "[object GeneratorFunction]", proxyTag = "[object Proxy]"; + var baseGetTag = __webpack_require__(41), isObject = __webpack_require__(32), asyncTag = "[object AsyncFunction]", funcTag = "[object Function]", genTag = "[object GeneratorFunction]", proxyTag = "[object Proxy]"; module.exports = isFunction; }, function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -554,7 +557,7 @@ var _bundleJs = []byte((((((((((`!function(modules) { }), __webpack_require__.d(__webpack_exports__, "c", function() { return getLinearRegression; }); - var __WEBPACK_IMPORTED_MODULE_0_lodash_get__ = __webpack_require__(164), __WEBPACK_IMPORTED_MODULE_0_lodash_get___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_lodash_get__), __WEBPACK_IMPORTED_MODULE_1_lodash_isArray__ = __webpack_require__(11), __WEBPACK_IMPORTED_MODULE_1_lodash_isArray___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_lodash_isArray__), __WEBPACK_IMPORTED_MODULE_2_lodash_isNaN__ = __webpack_require__(116), __WEBPACK_IMPORTED_MODULE_2_lodash_isNaN___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_2_lodash_isNaN__), __WEBPACK_IMPORTED_MODULE_3_lodash_isNumber__ = __webpack_require__(169), __WEBPACK_IMPORTED_MODULE_3_lodash_isNumber___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_3_lodash_isNumber__), __WEBPACK_IMPORTED_MODULE_4_lodash_isString__ = __webpack_require__(163), __WEBPACK_IMPORTED_MODULE_4_lodash_isString___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_4_lodash_isString__), mathSign = function(value) { + var __WEBPACK_IMPORTED_MODULE_0_lodash_get__ = __webpack_require__(174), __WEBPACK_IMPORTED_MODULE_0_lodash_get___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_lodash_get__), __WEBPACK_IMPORTED_MODULE_1_lodash_isArray__ = __webpack_require__(13), __WEBPACK_IMPORTED_MODULE_1_lodash_isArray___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_lodash_isArray__), __WEBPACK_IMPORTED_MODULE_2_lodash_isNaN__ = __webpack_require__(120), __WEBPACK_IMPORTED_MODULE_2_lodash_isNaN___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_2_lodash_isNaN__), __WEBPACK_IMPORTED_MODULE_3_lodash_isNumber__ = __webpack_require__(272), __WEBPACK_IMPORTED_MODULE_3_lodash_isNumber___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_3_lodash_isNumber__), __WEBPACK_IMPORTED_MODULE_4_lodash_isString__ = __webpack_require__(173), __WEBPACK_IMPORTED_MODULE_4_lodash_isString___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_4_lodash_isString__), mathSign = function(value) { return 0 === value ? 0 : value > 0 ? 1 : -1; }, isPercent = function(value) { return __WEBPACK_IMPORTED_MODULE_4_lodash_isString___default()(value) && value.indexOf("%") === value.length - 1; @@ -623,12 +626,12 @@ var _bundleJs = []byte((((((((((`!function(modules) { Object.defineProperty(exports, "__esModule", { value: !0 }), exports.sheetsManager = void 0; - var _keys = __webpack_require__(50), _keys2 = _interopRequireDefault(_keys), _extends2 = __webpack_require__(6), _extends3 = _interopRequireDefault(_extends2), _getPrototypeOf = __webpack_require__(26), _getPrototypeOf2 = _interopRequireDefault(_getPrototypeOf), _classCallCheck2 = __webpack_require__(27), _classCallCheck3 = _interopRequireDefault(_classCallCheck2), _createClass2 = __webpack_require__(28), _createClass3 = _interopRequireDefault(_createClass2), _possibleConstructorReturn2 = __webpack_require__(29), _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2), _inherits2 = __webpack_require__(30), _inherits3 = _interopRequireDefault(_inherits2), _objectWithoutProperties2 = __webpack_require__(7), _objectWithoutProperties3 = _interopRequireDefault(_objectWithoutProperties2), _map = __webpack_require__(401), _map2 = _interopRequireDefault(_map), _minSafeInteger = __webpack_require__(417), _minSafeInteger2 = _interopRequireDefault(_minSafeInteger), _react = __webpack_require__(0), _react2 = _interopRequireDefault(_react), _propTypes = __webpack_require__(1), _propTypes2 = _interopRequireDefault(_propTypes), _warning = __webpack_require__(12), _warning2 = _interopRequireDefault(_warning), _hoistNonReactStatics = __webpack_require__(151), _hoistNonReactStatics2 = _interopRequireDefault(_hoistNonReactStatics), _getDisplayName = __webpack_require__(226), _getDisplayName2 = _interopRequireDefault(_getDisplayName), _wrapDisplayName = __webpack_require__(75), _wrapDisplayName2 = _interopRequireDefault(_wrapDisplayName), _contextTypes = __webpack_require__(420), _contextTypes2 = _interopRequireDefault(_contextTypes), _jss = __webpack_require__(228), _ns = __webpack_require__(227), ns = function(obj) { + var _keys = __webpack_require__(55), _keys2 = _interopRequireDefault(_keys), _extends2 = __webpack_require__(6), _extends3 = _interopRequireDefault(_extends2), _getPrototypeOf = __webpack_require__(26), _getPrototypeOf2 = _interopRequireDefault(_getPrototypeOf), _classCallCheck2 = __webpack_require__(27), _classCallCheck3 = _interopRequireDefault(_classCallCheck2), _createClass2 = __webpack_require__(28), _createClass3 = _interopRequireDefault(_createClass2), _possibleConstructorReturn2 = __webpack_require__(29), _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2), _inherits2 = __webpack_require__(30), _inherits3 = _interopRequireDefault(_inherits2), _objectWithoutProperties2 = __webpack_require__(7), _objectWithoutProperties3 = _interopRequireDefault(_objectWithoutProperties2), _map = __webpack_require__(440), _map2 = _interopRequireDefault(_map), _minSafeInteger = __webpack_require__(456), _minSafeInteger2 = _interopRequireDefault(_minSafeInteger), _react = __webpack_require__(0), _react2 = _interopRequireDefault(_react), _propTypes = __webpack_require__(1), _propTypes2 = _interopRequireDefault(_propTypes), _warning = __webpack_require__(11), _warning2 = _interopRequireDefault(_warning), _hoistNonReactStatics = __webpack_require__(162), _hoistNonReactStatics2 = _interopRequireDefault(_hoistNonReactStatics), _getDisplayName = __webpack_require__(244), _getDisplayName2 = _interopRequireDefault(_getDisplayName), _wrapDisplayName = __webpack_require__(79), _wrapDisplayName2 = _interopRequireDefault(_wrapDisplayName), _contextTypes = __webpack_require__(459), _contextTypes2 = _interopRequireDefault(_contextTypes), _jss = __webpack_require__(246), _ns = __webpack_require__(245), ns = function(obj) { if (obj && obj.__esModule) return obj; var newObj = {}; if (null != obj) for (var key in obj) Object.prototype.hasOwnProperty.call(obj, key) && (newObj[key] = obj[key]); return newObj.default = obj, newObj; - }(_ns), _jssPreset = __webpack_require__(442), _jssPreset2 = _interopRequireDefault(_jssPreset), _createMuiTheme = __webpack_require__(150), _createMuiTheme2 = _interopRequireDefault(_createMuiTheme), _themeListener = __webpack_require__(149), _themeListener2 = _interopRequireDefault(_themeListener), _createGenerateClassName = __webpack_require__(455), _createGenerateClassName2 = _interopRequireDefault(_createGenerateClassName), _getStylesCreator = __webpack_require__(456), _getStylesCreator2 = _interopRequireDefault(_getStylesCreator), jss = (0, + }(_ns), _jssPreset = __webpack_require__(481), _jssPreset2 = _interopRequireDefault(_jssPreset), _createMuiTheme = __webpack_require__(161), _createMuiTheme2 = _interopRequireDefault(_createMuiTheme), _themeListener = __webpack_require__(160), _themeListener2 = _interopRequireDefault(_themeListener), _createGenerateClassName = __webpack_require__(494), _createGenerateClassName2 = _interopRequireDefault(_createGenerateClassName), _getStylesCreator = __webpack_require__(495), _getStylesCreator2 = _interopRequireDefault(_getStylesCreator), jss = (0, _jss.create)((0, _jssPreset2.default)()), generateClassName = (0, _createGenerateClassName2.default)(), indexCounter = _minSafeInteger2.default, sheetsManager = exports.sheetsManager = new _map2.default(), noopTheme = {}, defaultTheme = void 0, withStyles = function(stylesOrCreator) { var options = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {}; return function(Component) { @@ -730,10 +733,10 @@ var _bundleJs = []byte((((((((((`!function(modules) { renderedClasses = sheetsManagerTheme.sheet.classes; } classes = classesProp ? (0, _extends3.default)({}, renderedClasses, (0, _keys2.default)(classesProp).reduce(function(accumulator, key) { - return "production" !== process.env.NODE_ENV && (0, _warning2.default)(renderedClasses[key] || _this3.disableStylesGeneration, [ "Material-UI: the key ` + "`") + (`" + key + "` + ("`" + ` provided to the classes property is not implemented in " + (0, + return "production" !== process.env.NODE_ENV && (0, _warning2.default)(renderedClasses[key] || _this3.disableStylesGeneration, [ "Material-UI: the key ` + ("`" + `" + key + "`)) + ("`" + (` provided to the classes property is not implemented in " + (0, _getDisplayName2.default)(Component) + ".", "You can only override one of the following: " + (0, _keys2.default)(renderedClasses).join(",") ].join("\n")), "production" !== process.env.NODE_ENV && (0, - _warning2.default)(!classesProp[key] || "string" == typeof classesProp[key], [ "Material-UI: the key `))) + (("`" + (`" + key + "` + "`")) + (` provided to the classes property is not valid for " + (0, + _warning2.default)(!classesProp[key] || "string" == typeof classesProp[key], [ "Material-UI: the key ` + "`"))) + ((`" + key + "` + ("`" + ` provided to the classes property is not valid for " + (0, _getDisplayName2.default)(Component) + ".", "You need to provide a non empty string instead of: " + classesProp[key] + "." ].join("\n")), classesProp[key] && (accumulator[key] = renderedClasses[key] + " " + classesProp[key]), accumulator; @@ -761,9 +764,6 @@ var _bundleJs = []byte((((((((((`!function(modules) { }; exports.default = withStyles; }).call(exports, __webpack_require__(2)); -}, function(module, exports) { - var isArray = Array.isArray; - module.exports = isArray; }, function(module, exports, __webpack_require__) { "use strict"; (function(process) { @@ -772,7 +772,7 @@ var _bundleJs = []byte((((((((((`!function(modules) { var len = arguments.length; args = new Array(len > 2 ? len - 2 : 0); for (var key = 2; key < len; key++) args[key - 2] = arguments[key]; - if (void 0 === format) throw new Error("` + ("`" + `warning(condition, format, ...args)`)))) + ((("`" + (` requires a warning message argument"); + if (void 0 === format) throw new Error("`)) + ("`" + (`warning(condition, format, ...args)` + "`")))) + (((` requires a warning message argument"); if (format.length < 10 || /^[s\W]*$/.test(format)) throw new Error("The warning format should be able to uniquely identify this warning. Please, use a more descriptive format than: " + format); if (!condition) { var argIndex = 0, message = "Warning: " + format.replace(/%s/g, function() { @@ -788,7 +788,7 @@ var _bundleJs = []byte((((((((((`!function(modules) { }, function(module, exports, __webpack_require__) { "use strict"; exports.__esModule = !0; - var _defineProperty = __webpack_require__(142), _defineProperty2 = function(obj) { + var _defineProperty = __webpack_require__(154), _defineProperty2 = function(obj) { return obj && obj.__esModule ? obj : { default: obj }; @@ -801,6 +801,9 @@ var _bundleJs = []byte((((((((((`!function(modules) { writable: !0 }) : obj[key] = value, obj; }; +}, function(module, exports) { + var isArray = Array.isArray; + module.exports = isArray; }, function(module, __webpack_exports__, __webpack_require__) { "use strict"; function _objectWithoutProperties(obj, keys) { @@ -826,7 +829,7 @@ var _bundleJs = []byte((((((((((`!function(modules) { }; Layer.propTypes = propTypes, __webpack_exports__.a = Layer; }, function(module, exports, __webpack_require__) { - var global = __webpack_require__(157), core = __webpack_require__(158), hide = __webpack_require__(245), redefine = __webpack_require__(536), ctx = __webpack_require__(539), $export = function(type, name, source) { + var global = __webpack_require__(167), core = __webpack_require__(168), hide = __webpack_require__(266), redefine = __webpack_require__(581), ctx = __webpack_require__(584), $export = function(type, name, source) { var key, own, out, exp, IS_FORCED = type & $export.F, IS_GLOBAL = type & $export.G, IS_STATIC = type & $export.S, IS_PROTO = type & $export.P, IS_BIND = type & $export.B, target = IS_GLOBAL ? global : IS_STATIC ? global[name] || (global[name] = {}) : (global[name] || {}).prototype, exports = IS_GLOBAL ? core : core[name] || (core[name] = {}), expProto = exports.prototype || (exports.prototype = {}); IS_GLOBAL && (source = name); for (key in source) own = !IS_FORCED && target && void 0 !== target[key], out = (own ? target : source)[key], @@ -914,8 +917,8 @@ var _bundleJs = []byte((((((((((`!function(modules) { }), __webpack_require__.d(__webpack_exports__, "y", function() { return parseDomainOfCategoryAxis; }); - var __WEBPACK_IMPORTED_MODULE_0_lodash_isEqual__ = __webpack_require__(34), __WEBPACK_IMPORTED_MODULE_0_lodash_isEqual___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_lodash_isEqual__), __WEBPACK_IMPORTED_MODULE_1_lodash_sortBy__ = __webpack_require__(284), __WEBPACK_IMPORTED_MODULE_1_lodash_sortBy___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_lodash_sortBy__), __WEBPACK_IMPORTED_MODULE_2_lodash_isNaN__ = __webpack_require__(116), __WEBPACK_IMPORTED_MODULE_2_lodash_isNaN___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_2_lodash_isNaN__), __WEBPACK_IMPORTED_MODULE_3_lodash_isString__ = __webpack_require__(163), __WEBPACK_IMPORTED_MODULE_3_lodash_isString___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_3_lodash_isString__), __WEBPACK_IMPORTED_MODULE_4_lodash_max__ = __webpack_require__(700), __WEBPACK_IMPORTED_MODULE_4_lodash_max___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_4_lodash_max__), __WEBPACK_IMPORTED_MODULE_5_lodash_min__ = __webpack_require__(289), __WEBPACK_IMPORTED_MODULE_5_lodash_min___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_5_lodash_min__), __WEBPACK_IMPORTED_MODULE_6_lodash_isArray__ = __webpack_require__(11), __WEBPACK_IMPORTED_MODULE_6_lodash_isArray___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_6_lodash_isArray__), __WEBPACK_IMPORTED_MODULE_7_lodash_flatMap__ = __webpack_require__(701), __WEBPACK_IMPORTED_MODULE_7_lodash_flatMap___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_7_lodash_flatMap__), __WEBPACK_IMPORTED_MODULE_8_lodash_isFunction__ = __webpack_require__(8), __WEBPACK_IMPORTED_MODULE_8_lodash_isFunction___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_8_lodash_isFunction__), __WEBPACK_IMPORTED_MODULE_9_lodash_get__ = __webpack_require__(164), __WEBPACK_IMPORTED_MODULE_9_lodash_get___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_9_lodash_get__), __WEBPACK_IMPORTED_MODULE_10_lodash_isNil__ = __webpack_require__(20), __WEBPACK_IMPORTED_MODULE_10_lodash_isNil___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_10_lodash_isNil__), __WEBPACK_IMPORTED_MODULE_11_recharts_scale__ = __webpack_require__(703), __WEBPACK_IMPORTED_MODULE_12_d3_scale__ = (__webpack_require__.n(__WEBPACK_IMPORTED_MODULE_11_recharts_scale__), - __webpack_require__(292)), __WEBPACK_IMPORTED_MODULE_13_d3_shape__ = __webpack_require__(172), __WEBPACK_IMPORTED_MODULE_14__DataUtils__ = __webpack_require__(9), __WEBPACK_IMPORTED_MODULE_15__cartesian_ReferenceDot__ = __webpack_require__(325), __WEBPACK_IMPORTED_MODULE_16__cartesian_ReferenceLine__ = __webpack_require__(326), __WEBPACK_IMPORTED_MODULE_17__cartesian_ReferenceArea__ = __webpack_require__(327), __WEBPACK_IMPORTED_MODULE_18__cartesian_ErrorBar__ = __webpack_require__(92), __WEBPACK_IMPORTED_MODULE_19__component_Legend__ = __webpack_require__(170), __WEBPACK_IMPORTED_MODULE_20__ReactUtils__ = __webpack_require__(4), _extends = Object.assign || function(target) { + var __WEBPACK_IMPORTED_MODULE_0_lodash_isEqual__ = __webpack_require__(45), __WEBPACK_IMPORTED_MODULE_0_lodash_isEqual___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_lodash_isEqual__), __WEBPACK_IMPORTED_MODULE_1_lodash_sortBy__ = __webpack_require__(321), __WEBPACK_IMPORTED_MODULE_1_lodash_sortBy___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_lodash_sortBy__), __WEBPACK_IMPORTED_MODULE_2_lodash_isNaN__ = __webpack_require__(120), __WEBPACK_IMPORTED_MODULE_2_lodash_isNaN___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_2_lodash_isNaN__), __WEBPACK_IMPORTED_MODULE_3_lodash_isString__ = __webpack_require__(173), __WEBPACK_IMPORTED_MODULE_3_lodash_isString___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_3_lodash_isString__), __WEBPACK_IMPORTED_MODULE_4_lodash_max__ = __webpack_require__(841), __WEBPACK_IMPORTED_MODULE_4_lodash_max___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_4_lodash_max__), __WEBPACK_IMPORTED_MODULE_5_lodash_min__ = __webpack_require__(328), __WEBPACK_IMPORTED_MODULE_5_lodash_min___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_5_lodash_min__), __WEBPACK_IMPORTED_MODULE_6_lodash_isArray__ = __webpack_require__(13), __WEBPACK_IMPORTED_MODULE_6_lodash_isArray___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_6_lodash_isArray__), __WEBPACK_IMPORTED_MODULE_7_lodash_flatMap__ = __webpack_require__(842), __WEBPACK_IMPORTED_MODULE_7_lodash_flatMap___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_7_lodash_flatMap__), __WEBPACK_IMPORTED_MODULE_8_lodash_isFunction__ = __webpack_require__(8), __WEBPACK_IMPORTED_MODULE_8_lodash_isFunction___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_8_lodash_isFunction__), __WEBPACK_IMPORTED_MODULE_9_lodash_get__ = __webpack_require__(174), __WEBPACK_IMPORTED_MODULE_9_lodash_get___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_9_lodash_get__), __WEBPACK_IMPORTED_MODULE_10_lodash_isNil__ = __webpack_require__(20), __WEBPACK_IMPORTED_MODULE_10_lodash_isNil___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_10_lodash_isNil__), __WEBPACK_IMPORTED_MODULE_11_recharts_scale__ = __webpack_require__(844), __WEBPACK_IMPORTED_MODULE_12_d3_scale__ = (__webpack_require__.n(__WEBPACK_IMPORTED_MODULE_11_recharts_scale__), + __webpack_require__(331)), __WEBPACK_IMPORTED_MODULE_13_d3_shape__ = __webpack_require__(182), __WEBPACK_IMPORTED_MODULE_14__DataUtils__ = __webpack_require__(9), __WEBPACK_IMPORTED_MODULE_15__cartesian_ReferenceDot__ = __webpack_require__(364), __WEBPACK_IMPORTED_MODULE_16__cartesian_ReferenceLine__ = __webpack_require__(365), __WEBPACK_IMPORTED_MODULE_17__cartesian_ReferenceArea__ = __webpack_require__(366), __WEBPACK_IMPORTED_MODULE_18__cartesian_ErrorBar__ = __webpack_require__(95), __WEBPACK_IMPORTED_MODULE_19__component_Legend__ = __webpack_require__(180), __WEBPACK_IMPORTED_MODULE_20__ReactUtils__ = __webpack_require__(4), _extends = Object.assign || function(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) Object.prototype.hasOwnProperty.call(source, key) && (target[key] = source[key]); @@ -1406,7 +1409,7 @@ var _bundleJs = []byte((((((((((`!function(modules) { }; }, function(module, exports) { var core = module.exports = { - version: "2.5.3" + version: "2.5.7" }; "number" == typeof __e && (__e = core); }, function(module, __webpack_exports__, __webpack_require__) { @@ -1449,10 +1452,10 @@ var _bundleJs = []byte((((((((((`!function(modules) { __webpack_exports__.a = newInterval; var t0 = new Date(), t1 = new Date(); }, function(module, exports, __webpack_require__) { - var global = __webpack_require__(24), core = __webpack_require__(17), ctx = __webpack_require__(46), hide = __webpack_require__(40), $export = function(type, name, source) { + var global = __webpack_require__(24), core = __webpack_require__(17), ctx = __webpack_require__(51), hide = __webpack_require__(39), has = __webpack_require__(54), $export = function(type, name, source) { var key, own, out, IS_FORCED = type & $export.F, IS_GLOBAL = type & $export.G, IS_STATIC = type & $export.S, IS_PROTO = type & $export.P, IS_BIND = type & $export.B, IS_WRAP = type & $export.W, exports = IS_GLOBAL ? core : core[name] || (core[name] = {}), expProto = exports.prototype, target = IS_GLOBAL ? global : IS_STATIC ? global[name] : (global[name] || {}).prototype; IS_GLOBAL && (source = name); - for (key in source) (own = !IS_FORCED && target && void 0 !== target[key]) && key in exports || (out = own ? target[key] : source[key], + for (key in source) (own = !IS_FORCED && target && void 0 !== target[key]) && has(exports, key) || (out = own ? target[key] : source[key], exports[key] = IS_GLOBAL && "function" != typeof target[key] ? source[key] : IS_BIND && own ? ctx(out, global) : IS_WRAP && target[key] == out ? function(C) { var F = function(a, b, c) { if (this instanceof C) { @@ -1482,12 +1485,12 @@ var _bundleJs = []byte((((((((((`!function(modules) { } module.exports = isNil; }, function(module, exports, __webpack_require__) { - var store = __webpack_require__(139)("wks"), uid = __webpack_require__(99), Symbol = __webpack_require__(24).Symbol, USE_SYMBOL = "function" == typeof Symbol; + var store = __webpack_require__(151)("wks"), uid = __webpack_require__(103), Symbol = __webpack_require__(24).Symbol, USE_SYMBOL = "function" == typeof Symbol; (module.exports = function(name) { return store[name] || (store[name] = USE_SYMBOL && Symbol[name] || (USE_SYMBOL ? Symbol : uid)("Symbol." + name)); }).store = store; }, function(module, exports, __webpack_require__) { - var anObject = __webpack_require__(47), IE8_DOM_DEFINE = __webpack_require__(206), toPrimitive = __webpack_require__(133), dP = Object.defineProperty; + var anObject = __webpack_require__(52), IE8_DOM_DEFINE = __webpack_require__(224), toPrimitive = __webpack_require__(145), dP = Object.defineProperty; exports.f = __webpack_require__(25) ? Object.defineProperty : function(O, P, Attributes) { if (anObject(O), P = toPrimitive(P, !0), anObject(Attributes), IE8_DOM_DEFINE) try { return dP(O, P, Attributes); @@ -1617,7 +1620,7 @@ var _bundleJs = []byte((((((((((`!function(modules) { var global = module.exports = "undefined" != typeof window && window.Math == Math ? window : "undefined" != typeof self && self.Math == Math ? self : Function("return this")(); "number" == typeof __g && (__g = global); }, function(module, exports, __webpack_require__) { - module.exports = !__webpack_require__(48)(function() { + module.exports = !__webpack_require__(53)(function() { return 7 != Object.defineProperty({}, "a", { get: function() { return 7; @@ -1626,7 +1629,7 @@ var _bundleJs = []byte((((((((((`!function(modules) { }); }, function(module, exports, __webpack_require__) { module.exports = { - default: __webpack_require__(355), + default: __webpack_require__(394), __esModule: !0 }; }, function(module, exports, __webpack_require__) { @@ -1637,7 +1640,7 @@ var _bundleJs = []byte((((((((((`!function(modules) { }, function(module, exports, __webpack_require__) { "use strict"; exports.__esModule = !0; - var _defineProperty = __webpack_require__(142), _defineProperty2 = function(obj) { + var _defineProperty = __webpack_require__(154), _defineProperty2 = function(obj) { return obj && obj.__esModule ? obj : { default: obj }; @@ -1658,7 +1661,7 @@ var _bundleJs = []byte((((((((((`!function(modules) { }, function(module, exports, __webpack_require__) { "use strict"; exports.__esModule = !0; - var _typeof2 = __webpack_require__(101), _typeof3 = function(obj) { + var _typeof2 = __webpack_require__(105), _typeof3 = function(obj) { return obj && obj.__esModule ? obj : { default: obj }; @@ -1675,7 +1678,7 @@ var _bundleJs = []byte((((((((((`!function(modules) { }; } exports.__esModule = !0; - var _setPrototypeOf = __webpack_require__(372), _setPrototypeOf2 = _interopRequireDefault(_setPrototypeOf), _create = __webpack_require__(376), _create2 = _interopRequireDefault(_create), _typeof2 = __webpack_require__(101), _typeof3 = _interopRequireDefault(_typeof2); + var _setPrototypeOf = __webpack_require__(411), _setPrototypeOf2 = _interopRequireDefault(_setPrototypeOf), _create = __webpack_require__(415), _create2 = _interopRequireDefault(_create), _typeof2 = __webpack_require__(105), _typeof3 = _interopRequireDefault(_typeof2); exports.default = function(subClass, superClass) { if ("function" != typeof superClass && null !== superClass) throw new TypeError("Super expression must either be null or a function, not " + (void 0 === superClass ? "undefined" : (0, _typeof3.default)(superClass))); @@ -1688,15 +1691,15 @@ var _bundleJs = []byte((((((((((`!function(modules) { } }), superClass && (_setPrototypeOf2.default ? (0, _setPrototypeOf2.default)(subClass, superClass) : subClass.__proto__ = superClass); }; +}, function(module, exports, __webpack_require__) { + var freeGlobal = __webpack_require__(268), freeSelf = "object" == typeof self && self && self.Object === Object && self, root = freeGlobal || freeSelf || Function("return this")(); + module.exports = root; }, function(module, exports) { function isObject(value) { var type = typeof value; return null != value && ("object" == type || "function" == type); } module.exports = isObject; -}, function(module, exports, __webpack_require__) { - var freeGlobal = __webpack_require__(243), freeSelf = "object" == typeof self && self && self.Object === Object && self, root = freeGlobal || freeSelf || Function("return this")(); - module.exports = root; }, function(module, exports, __webpack_require__) { "use strict"; function _interopRequireDefault(obj) { @@ -1707,53 +1710,48 @@ var _bundleJs = []byte((((((((((`!function(modules) { Object.defineProperty(exports, "__esModule", { value: !0 }), exports.translateStyle = exports.AnimateGroup = exports.configBezier = exports.configSpring = void 0; - var _Animate = __webpack_require__(264), _Animate2 = _interopRequireDefault(_Animate), _easing = __webpack_require__(277), _util = __webpack_require__(122), _AnimateGroup = __webpack_require__(681), _AnimateGroup2 = _interopRequireDefault(_AnimateGroup); + var _Animate = __webpack_require__(287), _Animate2 = _interopRequireDefault(_Animate), _easing = __webpack_require__(305), _util = __webpack_require__(132), _AnimateGroup = __webpack_require__(762), _AnimateGroup2 = _interopRequireDefault(_AnimateGroup); exports.configSpring = _easing.configSpring, exports.configBezier = _easing.configBezier, exports.AnimateGroup = _AnimateGroup2.default, exports.translateStyle = _util.translateStyle, exports.default = _Animate2.default; -}, function(module, exports, __webpack_require__) { - function isEqual(value, other) { - return baseIsEqual(value, other); - } - var baseIsEqual = __webpack_require__(177); - module.exports = isEqual; +}, function(module, exports) { + var isArray = Array.isArray; + module.exports = isArray; }, function(module, exports) { module.exports = function(it) { return "object" == typeof it ? null !== it : "function" == typeof it; }; -}, function(module, exports) { - function isObjectLike(value) { - return null != value && "object" == typeof value; - } - module.exports = isObjectLike; +}, function(module, exports, __webpack_require__) { + var freeGlobal = __webpack_require__(292), freeSelf = "object" == typeof self && self && self.Object === Object && self, root = freeGlobal || freeSelf || Function("return this")(); + module.exports = root; }, function(module, __webpack_exports__, __webpack_require__) { "use strict"; - var __WEBPACK_IMPORTED_MODULE_0__src_bisect__ = __webpack_require__(293); + var __WEBPACK_IMPORTED_MODULE_0__src_bisect__ = __webpack_require__(332); __webpack_require__.d(__webpack_exports__, "b", function() { return __WEBPACK_IMPORTED_MODULE_0__src_bisect__.a; }); - var __WEBPACK_IMPORTED_MODULE_1__src_ascending__ = __webpack_require__(64); + var __WEBPACK_IMPORTED_MODULE_1__src_ascending__ = __webpack_require__(69); __webpack_require__.d(__webpack_exports__, "a", function() { return __WEBPACK_IMPORTED_MODULE_1__src_ascending__.a; }); - var __WEBPACK_IMPORTED_MODULE_2__src_bisector__ = __webpack_require__(294); + var __WEBPACK_IMPORTED_MODULE_2__src_bisector__ = __webpack_require__(333); __webpack_require__.d(__webpack_exports__, "c", function() { return __WEBPACK_IMPORTED_MODULE_2__src_bisector__.a; }); - var __WEBPACK_IMPORTED_MODULE_18__src_quantile__ = (__webpack_require__(707), __webpack_require__(708), - __webpack_require__(296), __webpack_require__(298), __webpack_require__(709), __webpack_require__(712), - __webpack_require__(713), __webpack_require__(302), __webpack_require__(714), __webpack_require__(715), - __webpack_require__(716), __webpack_require__(717), __webpack_require__(303), __webpack_require__(295), - __webpack_require__(718), __webpack_require__(184)); + var __WEBPACK_IMPORTED_MODULE_18__src_quantile__ = (__webpack_require__(848), __webpack_require__(849), + __webpack_require__(335), __webpack_require__(337), __webpack_require__(850), __webpack_require__(853), + __webpack_require__(854), __webpack_require__(341), __webpack_require__(855), __webpack_require__(856), + __webpack_require__(857), __webpack_require__(858), __webpack_require__(342), __webpack_require__(334), + __webpack_require__(859), __webpack_require__(204)); __webpack_require__.d(__webpack_exports__, "d", function() { return __WEBPACK_IMPORTED_MODULE_18__src_quantile__.a; }); - var __WEBPACK_IMPORTED_MODULE_19__src_range__ = __webpack_require__(300); + var __WEBPACK_IMPORTED_MODULE_19__src_range__ = __webpack_require__(339); __webpack_require__.d(__webpack_exports__, "e", function() { return __WEBPACK_IMPORTED_MODULE_19__src_range__.a; }); - var __WEBPACK_IMPORTED_MODULE_23__src_ticks__ = (__webpack_require__(719), __webpack_require__(720), - __webpack_require__(721), __webpack_require__(301)); + var __WEBPACK_IMPORTED_MODULE_23__src_ticks__ = (__webpack_require__(860), __webpack_require__(861), + __webpack_require__(862), __webpack_require__(340)); __webpack_require__.d(__webpack_exports__, "h", function() { return __WEBPACK_IMPORTED_MODULE_23__src_ticks__.a; }), __webpack_require__.d(__webpack_exports__, "f", function() { @@ -1761,7 +1759,7 @@ var _bundleJs = []byte((((((((((`!function(modules) { }), __webpack_require__.d(__webpack_exports__, "g", function() { return __WEBPACK_IMPORTED_MODULE_23__src_ticks__.c; }); - __webpack_require__(304), __webpack_require__(297), __webpack_require__(722); + __webpack_require__(343), __webpack_require__(336), __webpack_require__(863); }, function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.d(__webpack_exports__, "d", function() { @@ -1777,33 +1775,39 @@ var _bundleJs = []byte((((((((((`!function(modules) { }); var durationSecond = 1e3, durationMinute = 6e4, durationHour = 36e5, durationDay = 864e5, durationWeek = 6048e5; }, function(module, exports, __webpack_require__) { - "use strict"; - function makeEmptyFunction(arg) { - return function() { - return arg; - }; - } - var emptyFunction = function() {}; - emptyFunction.thatReturns = makeEmptyFunction, emptyFunction.thatReturnsFalse = makeEmptyFunction(!1), - emptyFunction.thatReturnsTrue = makeEmptyFunction(!0), emptyFunction.thatReturnsNull = makeEmptyFunction(null), - emptyFunction.thatReturnsThis = function() { - return this; - }, emptyFunction.thatReturnsArgument = function(arg) { - return arg; - }, module.exports = emptyFunction; -}, function(module, exports, __webpack_require__) { - var dP = __webpack_require__(22), createDesc = __webpack_require__(71); + var dP = __webpack_require__(22), createDesc = __webpack_require__(75); module.exports = __webpack_require__(25) ? function(object, key, value) { return dP.f(object, key, createDesc(1, value)); } : function(object, key, value) { return object[key] = value, object; }; +}, function(module, exports) { + var g; + g = function() { + return this; + }(); + try { + g = g || Function("return this")() || (0, eval)("this"); + } catch (e) { + "object" == typeof window && (g = window); + } + module.exports = g; }, function(module, exports, __webpack_require__) { function baseGetTag(value) { return null == value ? void 0 === value ? undefinedTag : nullTag : symToStringTag && symToStringTag in Object(value) ? getRawTag(value) : objectToString(value); } - var Symbol = __webpack_require__(78), getRawTag = __webpack_require__(522), objectToString = __webpack_require__(523), nullTag = "[object Null]", undefinedTag = "[object Undefined]", symToStringTag = Symbol ? Symbol.toStringTag : void 0; + var Symbol = __webpack_require__(83), getRawTag = __webpack_require__(603), objectToString = __webpack_require__(604), nullTag = "[object Null]", undefinedTag = "[object Undefined]", symToStringTag = Symbol ? Symbol.toStringTag : void 0; module.exports = baseGetTag; +}, function(module, exports) { + function isObjectLike(value) { + return null != value && "object" == typeof value; + } + module.exports = isObjectLike; +}, function(module, exports) { + function isObjectLike(value) { + return null != value && "object" == typeof value; + } + module.exports = isObjectLike; }, function(module, __webpack_exports__, __webpack_require__) { "use strict"; function _toConsumableArray(arr) { @@ -1828,7 +1832,7 @@ var _bundleJs = []byte((((((((((`!function(modules) { className: __WEBPACK_IMPORTED_MODULE_5_classnames___default()("recharts-label", className) }, attrs, positionAttrs), label); } - var __WEBPACK_IMPORTED_MODULE_0_lodash_isObject__ = __webpack_require__(31), __WEBPACK_IMPORTED_MODULE_0_lodash_isObject___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_lodash_isObject__), __WEBPACK_IMPORTED_MODULE_1_lodash_isFunction__ = __webpack_require__(8), __WEBPACK_IMPORTED_MODULE_1_lodash_isFunction___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_lodash_isFunction__), __WEBPACK_IMPORTED_MODULE_2_lodash_isNil__ = __webpack_require__(20), __WEBPACK_IMPORTED_MODULE_2_lodash_isNil___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_2_lodash_isNil__), __WEBPACK_IMPORTED_MODULE_3_react__ = __webpack_require__(0), __WEBPACK_IMPORTED_MODULE_3_react___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_3_react__), __WEBPACK_IMPORTED_MODULE_4_prop_types__ = __webpack_require__(1), __WEBPACK_IMPORTED_MODULE_4_prop_types___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_4_prop_types__), __WEBPACK_IMPORTED_MODULE_5_classnames__ = __webpack_require__(3), __WEBPACK_IMPORTED_MODULE_5_classnames___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_5_classnames__), __WEBPACK_IMPORTED_MODULE_6__Text__ = __webpack_require__(54), __WEBPACK_IMPORTED_MODULE_7__util_ReactUtils__ = __webpack_require__(4), __WEBPACK_IMPORTED_MODULE_8__util_DataUtils__ = __webpack_require__(9), __WEBPACK_IMPORTED_MODULE_9__util_PolarUtils__ = __webpack_require__(23), _extends = Object.assign || function(target) { + var __WEBPACK_IMPORTED_MODULE_0_lodash_isObject__ = __webpack_require__(32), __WEBPACK_IMPORTED_MODULE_0_lodash_isObject___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_lodash_isObject__), __WEBPACK_IMPORTED_MODULE_1_lodash_isFunction__ = __webpack_require__(8), __WEBPACK_IMPORTED_MODULE_1_lodash_isFunction___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_lodash_isFunction__), __WEBPACK_IMPORTED_MODULE_2_lodash_isNil__ = __webpack_require__(20), __WEBPACK_IMPORTED_MODULE_2_lodash_isNil___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_2_lodash_isNil__), __WEBPACK_IMPORTED_MODULE_3_react__ = __webpack_require__(0), __WEBPACK_IMPORTED_MODULE_3_react___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_3_react__), __WEBPACK_IMPORTED_MODULE_4_prop_types__ = __webpack_require__(1), __WEBPACK_IMPORTED_MODULE_4_prop_types___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_4_prop_types__), __WEBPACK_IMPORTED_MODULE_5_classnames__ = __webpack_require__(3), __WEBPACK_IMPORTED_MODULE_5_classnames___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_5_classnames__), __WEBPACK_IMPORTED_MODULE_6__Text__ = __webpack_require__(61), __WEBPACK_IMPORTED_MODULE_7__util_ReactUtils__ = __webpack_require__(4), __WEBPACK_IMPORTED_MODULE_8__util_DataUtils__ = __webpack_require__(9), __WEBPACK_IMPORTED_MODULE_9__util_PolarUtils__ = __webpack_require__(23), _extends = Object.assign || function(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) Object.prototype.hasOwnProperty.call(source, key) && (target[key] = source[key]); @@ -2038,9 +2042,15 @@ var _bundleJs = []byte((((((((((`!function(modules) { }; Label.parseViewBox = parseViewBox, Label.renderCallByParent = renderCallByParent, __webpack_exports__.a = Label; +}, function(module, exports, __webpack_require__) { + function isEqual(value, other) { + return baseIsEqual(value, other); + } + var baseIsEqual = __webpack_require__(199); + module.exports = isEqual; }, function(module, __webpack_exports__, __webpack_require__) { "use strict"; - var __WEBPACK_IMPORTED_MODULE_0__src_color__ = __webpack_require__(187); + var __WEBPACK_IMPORTED_MODULE_0__src_color__ = __webpack_require__(207); __webpack_require__.d(__webpack_exports__, "a", function() { return __WEBPACK_IMPORTED_MODULE_0__src_color__.e; }), __webpack_require__.d(__webpack_exports__, "f", function() { @@ -2048,13 +2058,13 @@ var _bundleJs = []byte((((((((((`!function(modules) { }), __webpack_require__.d(__webpack_exports__, "d", function() { return __WEBPACK_IMPORTED_MODULE_0__src_color__.f; }); - var __WEBPACK_IMPORTED_MODULE_1__src_lab__ = __webpack_require__(730); + var __WEBPACK_IMPORTED_MODULE_1__src_lab__ = __webpack_require__(871); __webpack_require__.d(__webpack_exports__, "e", function() { return __WEBPACK_IMPORTED_MODULE_1__src_lab__.a; }), __webpack_require__.d(__webpack_exports__, "c", function() { return __WEBPACK_IMPORTED_MODULE_1__src_lab__.b; }); - var __WEBPACK_IMPORTED_MODULE_2__src_cubehelix__ = __webpack_require__(731); + var __WEBPACK_IMPORTED_MODULE_2__src_cubehelix__ = __webpack_require__(872); __webpack_require__.d(__webpack_exports__, "b", function() { return __WEBPACK_IMPORTED_MODULE_2__src_cubehelix__.a; }); @@ -2090,7 +2100,7 @@ var _bundleJs = []byte((((((((((`!function(modules) { })); })) : null; } - var __WEBPACK_IMPORTED_MODULE_0_lodash_isObject__ = __webpack_require__(31), __WEBPACK_IMPORTED_MODULE_0_lodash_isObject___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_lodash_isObject__), __WEBPACK_IMPORTED_MODULE_1_lodash_isFunction__ = __webpack_require__(8), __WEBPACK_IMPORTED_MODULE_1_lodash_isFunction___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_lodash_isFunction__), __WEBPACK_IMPORTED_MODULE_2_lodash_isNil__ = __webpack_require__(20), __WEBPACK_IMPORTED_MODULE_2_lodash_isNil___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_2_lodash_isNil__), __WEBPACK_IMPORTED_MODULE_3_lodash_last__ = __webpack_require__(781), __WEBPACK_IMPORTED_MODULE_3_lodash_last___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_3_lodash_last__), __WEBPACK_IMPORTED_MODULE_4_lodash_isArray__ = __webpack_require__(11), __WEBPACK_IMPORTED_MODULE_4_lodash_isArray___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_4_lodash_isArray__), __WEBPACK_IMPORTED_MODULE_5_react__ = __webpack_require__(0), __WEBPACK_IMPORTED_MODULE_5_react___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_5_react__), __WEBPACK_IMPORTED_MODULE_6_prop_types__ = __webpack_require__(1), __WEBPACK_IMPORTED_MODULE_6_prop_types___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_6_prop_types__), __WEBPACK_IMPORTED_MODULE_7__Label__ = __webpack_require__(42), __WEBPACK_IMPORTED_MODULE_8__container_Layer__ = __webpack_require__(14), __WEBPACK_IMPORTED_MODULE_9__util_ReactUtils__ = __webpack_require__(4), __WEBPACK_IMPORTED_MODULE_10__util_ChartUtils__ = __webpack_require__(16), _extends = Object.assign || function(target) { + var __WEBPACK_IMPORTED_MODULE_0_lodash_isObject__ = __webpack_require__(32), __WEBPACK_IMPORTED_MODULE_0_lodash_isObject___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_lodash_isObject__), __WEBPACK_IMPORTED_MODULE_1_lodash_isFunction__ = __webpack_require__(8), __WEBPACK_IMPORTED_MODULE_1_lodash_isFunction___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_lodash_isFunction__), __WEBPACK_IMPORTED_MODULE_2_lodash_isNil__ = __webpack_require__(20), __WEBPACK_IMPORTED_MODULE_2_lodash_isNil___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_2_lodash_isNil__), __WEBPACK_IMPORTED_MODULE_3_lodash_last__ = __webpack_require__(922), __WEBPACK_IMPORTED_MODULE_3_lodash_last___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_3_lodash_last__), __WEBPACK_IMPORTED_MODULE_4_lodash_isArray__ = __webpack_require__(13), __WEBPACK_IMPORTED_MODULE_4_lodash_isArray___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_4_lodash_isArray__), __WEBPACK_IMPORTED_MODULE_5_react__ = __webpack_require__(0), __WEBPACK_IMPORTED_MODULE_5_react___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_5_react__), __WEBPACK_IMPORTED_MODULE_6_prop_types__ = __webpack_require__(1), __WEBPACK_IMPORTED_MODULE_6_prop_types___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_6_prop_types__), __WEBPACK_IMPORTED_MODULE_7__Label__ = __webpack_require__(44), __WEBPACK_IMPORTED_MODULE_8__container_Layer__ = __webpack_require__(14), __WEBPACK_IMPORTED_MODULE_9__util_ReactUtils__ = __webpack_require__(4), __WEBPACK_IMPORTED_MODULE_10__util_ChartUtils__ = __webpack_require__(16), _extends = Object.assign || function(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) Object.prototype.hasOwnProperty.call(source, key) && (target[key] = source[key]); @@ -2174,7 +2184,7 @@ var _bundleJs = []byte((((((((((`!function(modules) { } }), superClass && (Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass); } - var __WEBPACK_IMPORTED_MODULE_0_lodash_sortBy__ = __webpack_require__(284), __WEBPACK_IMPORTED_MODULE_0_lodash_sortBy___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_lodash_sortBy__), __WEBPACK_IMPORTED_MODULE_1_lodash_isFunction__ = __webpack_require__(8), __WEBPACK_IMPORTED_MODULE_1_lodash_isFunction___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_lodash_isFunction__), __WEBPACK_IMPORTED_MODULE_2_lodash_range__ = __webpack_require__(334), __WEBPACK_IMPORTED_MODULE_2_lodash_range___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_2_lodash_range__), __WEBPACK_IMPORTED_MODULE_3_lodash_throttle__ = __webpack_require__(790), __WEBPACK_IMPORTED_MODULE_3_lodash_throttle___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_3_lodash_throttle__), __WEBPACK_IMPORTED_MODULE_4_lodash_isNil__ = __webpack_require__(20), __WEBPACK_IMPORTED_MODULE_4_lodash_isNil___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_4_lodash_isNil__), __WEBPACK_IMPORTED_MODULE_5_react__ = __webpack_require__(0), __WEBPACK_IMPORTED_MODULE_5_react___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_5_react__), __WEBPACK_IMPORTED_MODULE_6_prop_types__ = __webpack_require__(1), __WEBPACK_IMPORTED_MODULE_6_prop_types___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_6_prop_types__), __WEBPACK_IMPORTED_MODULE_7_classnames__ = __webpack_require__(3), __WEBPACK_IMPORTED_MODULE_7_classnames___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_7_classnames__), __WEBPACK_IMPORTED_MODULE_8__container_Surface__ = __webpack_require__(79), __WEBPACK_IMPORTED_MODULE_9__container_Layer__ = __webpack_require__(14), __WEBPACK_IMPORTED_MODULE_10__component_Tooltip__ = __webpack_require__(121), __WEBPACK_IMPORTED_MODULE_11__component_Legend__ = __webpack_require__(170), __WEBPACK_IMPORTED_MODULE_12__shape_Curve__ = __webpack_require__(66), __WEBPACK_IMPORTED_MODULE_13__shape_Cross__ = __webpack_require__(328), __WEBPACK_IMPORTED_MODULE_14__shape_Sector__ = __webpack_require__(127), __WEBPACK_IMPORTED_MODULE_15__shape_Dot__ = __webpack_require__(56), __WEBPACK_IMPORTED_MODULE_16__shape_Rectangle__ = __webpack_require__(65), __WEBPACK_IMPORTED_MODULE_17__util_ReactUtils__ = __webpack_require__(4), __WEBPACK_IMPORTED_MODULE_18__cartesian_CartesianAxis__ = __webpack_require__(335), __WEBPACK_IMPORTED_MODULE_19__cartesian_Brush__ = __webpack_require__(333), __WEBPACK_IMPORTED_MODULE_20__util_DOMUtils__ = __webpack_require__(183), __WEBPACK_IMPORTED_MODULE_21__util_DataUtils__ = __webpack_require__(9), __WEBPACK_IMPORTED_MODULE_22__util_ChartUtils__ = __webpack_require__(16), __WEBPACK_IMPORTED_MODULE_23__util_PolarUtils__ = __webpack_require__(23), __WEBPACK_IMPORTED_MODULE_24__util_PureRender__ = __webpack_require__(5), __WEBPACK_IMPORTED_MODULE_25__util_Events__ = __webpack_require__(791), _extends = Object.assign || function(target) { + var __WEBPACK_IMPORTED_MODULE_0_lodash_sortBy__ = __webpack_require__(321), __WEBPACK_IMPORTED_MODULE_0_lodash_sortBy___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_lodash_sortBy__), __WEBPACK_IMPORTED_MODULE_1_lodash_isFunction__ = __webpack_require__(8), __WEBPACK_IMPORTED_MODULE_1_lodash_isFunction___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_lodash_isFunction__), __WEBPACK_IMPORTED_MODULE_2_lodash_range__ = __webpack_require__(373), __WEBPACK_IMPORTED_MODULE_2_lodash_range___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_2_lodash_range__), __WEBPACK_IMPORTED_MODULE_3_lodash_throttle__ = __webpack_require__(933), __WEBPACK_IMPORTED_MODULE_3_lodash_throttle___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_3_lodash_throttle__), __WEBPACK_IMPORTED_MODULE_4_lodash_isNil__ = __webpack_require__(20), __WEBPACK_IMPORTED_MODULE_4_lodash_isNil___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_4_lodash_isNil__), __WEBPACK_IMPORTED_MODULE_5_react__ = __webpack_require__(0), __WEBPACK_IMPORTED_MODULE_5_react___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_5_react__), __WEBPACK_IMPORTED_MODULE_6_prop_types__ = __webpack_require__(1), __WEBPACK_IMPORTED_MODULE_6_prop_types___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_6_prop_types__), __WEBPACK_IMPORTED_MODULE_7_classnames__ = __webpack_require__(3), __WEBPACK_IMPORTED_MODULE_7_classnames___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_7_classnames__), __WEBPACK_IMPORTED_MODULE_8__container_Surface__ = __webpack_require__(82), __WEBPACK_IMPORTED_MODULE_9__container_Layer__ = __webpack_require__(14), __WEBPACK_IMPORTED_MODULE_10__component_Tooltip__ = __webpack_require__(125), __WEBPACK_IMPORTED_MODULE_11__component_Legend__ = __webpack_require__(180), __WEBPACK_IMPORTED_MODULE_12__shape_Curve__ = __webpack_require__(71), __WEBPACK_IMPORTED_MODULE_13__shape_Cross__ = __webpack_require__(367), __WEBPACK_IMPORTED_MODULE_14__shape_Sector__ = __webpack_require__(139), __WEBPACK_IMPORTED_MODULE_15__shape_Dot__ = __webpack_require__(63), __WEBPACK_IMPORTED_MODULE_16__shape_Rectangle__ = __webpack_require__(70), __WEBPACK_IMPORTED_MODULE_17__util_ReactUtils__ = __webpack_require__(4), __WEBPACK_IMPORTED_MODULE_18__cartesian_CartesianAxis__ = __webpack_require__(374), __WEBPACK_IMPORTED_MODULE_19__cartesian_Brush__ = __webpack_require__(372), __WEBPACK_IMPORTED_MODULE_20__util_DOMUtils__ = __webpack_require__(198), __WEBPACK_IMPORTED_MODULE_21__util_DataUtils__ = __webpack_require__(9), __WEBPACK_IMPORTED_MODULE_22__util_ChartUtils__ = __webpack_require__(16), __WEBPACK_IMPORTED_MODULE_23__util_PolarUtils__ = __webpack_require__(23), __WEBPACK_IMPORTED_MODULE_24__util_PureRender__ = __webpack_require__(5), __WEBPACK_IMPORTED_MODULE_25__util_Events__ = __webpack_require__(934), _extends = Object.assign || function(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) Object.prototype.hasOwnProperty.call(source, key) && (target[key] = source[key]); @@ -3194,7 +3204,42 @@ var _bundleJs = []byte((((((((((`!function(modules) { }; __webpack_exports__.a = generateCategoricalChart; }, function(module, exports, __webpack_require__) { - var aFunction = __webpack_require__(205); + "use strict"; + (function(process) { + function invariant(condition, format, a, b, c, d, e, f) { + if (validateFormat(format), !condition) { + var error; + if (void 0 === format) error = new Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings."); else { + var args = [ a, b, c, d, e, f ], argIndex = 0; + error = new Error(format.replace(/%s/g, function() { + return args[argIndex++]; + })), error.name = "Invariant Violation"; + } + throw error.framesToPop = 1, error; + } + } + var validateFormat = function(format) {}; + "production" !== process.env.NODE_ENV && (validateFormat = function(format) { + if (void 0 === format) throw new Error("invariant requires an error message argument"); + }), module.exports = invariant; + }).call(exports, __webpack_require__(2)); +}, function(module, exports, __webpack_require__) { + "use strict"; + function makeEmptyFunction(arg) { + return function() { + return arg; + }; + } + var emptyFunction = function() {}; + emptyFunction.thatReturns = makeEmptyFunction, emptyFunction.thatReturnsFalse = makeEmptyFunction(!1), + emptyFunction.thatReturnsTrue = makeEmptyFunction(!0), emptyFunction.thatReturnsNull = makeEmptyFunction(null), + emptyFunction.thatReturnsThis = function() { + return this; + }, emptyFunction.thatReturnsArgument = function(arg) { + return arg; + }, module.exports = emptyFunction; +}, function(module, exports, __webpack_require__) { + var aFunction = __webpack_require__(223); module.exports = function(fn, that, length) { if (aFunction(fn), void 0 === that) return fn; switch (length) { @@ -3238,7 +3283,7 @@ var _bundleJs = []byte((((((((((`!function(modules) { }; }, function(module, exports, __webpack_require__) { module.exports = { - default: __webpack_require__(382), + default: __webpack_require__(421), __esModule: !0 }; }, function(module, exports, __webpack_require__) { @@ -3285,17 +3330,17 @@ var _bundleJs = []byte((((((((((`!function(modules) { Object.defineProperty(exports, "__esModule", { value: !0 }); - var _typeof2 = __webpack_require__(101), _typeof3 = _interopRequireDefault(_typeof2), _keys = __webpack_require__(50), _keys2 = _interopRequireDefault(_keys); + var _typeof2 = __webpack_require__(105), _typeof3 = _interopRequireDefault(_typeof2), _keys = __webpack_require__(55), _keys2 = _interopRequireDefault(_keys); exports.capitalize = capitalize, exports.contains = contains, exports.findIndex = findIndex, exports.find = find, exports.createChainedFunction = createChainedFunction; - var _warning = __webpack_require__(12), _warning2 = _interopRequireDefault(_warning); + var _warning = __webpack_require__(11), _warning2 = _interopRequireDefault(_warning); }).call(exports, __webpack_require__(2)); }, function(module, exports, __webpack_require__) { function getNative(object, key) { var value = getValue(object, key); return baseIsNative(value) ? value : void 0; } - var baseIsNative = __webpack_require__(564), getValue = __webpack_require__(567); + var baseIsNative = __webpack_require__(611), getValue = __webpack_require__(614); module.exports = getNative; }, function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -3304,6 +3349,19 @@ var _bundleJs = []byte((((((((((`!function(modules) { return x; }; }; +}, function(module, exports, __webpack_require__) { + function getNative(object, key) { + var value = getValue(object, key); + return baseIsNative(value) ? value : void 0; + } + var baseIsNative = __webpack_require__(668), getValue = __webpack_require__(673); + module.exports = getNative; +}, function(module, exports, __webpack_require__) { + function baseGetTag(value) { + return null == value ? void 0 === value ? undefinedTag : nullTag : symToStringTag && symToStringTag in Object(value) ? getRawTag(value) : objectToString(value); + } + var Symbol = __webpack_require__(128), getRawTag = __webpack_require__(669), objectToString = __webpack_require__(670), nullTag = "[object Null]", undefinedTag = "[object Undefined]", symToStringTag = Symbol ? Symbol.toStringTag : void 0; + module.exports = baseGetTag; }, function(module, __webpack_exports__, __webpack_require__) { "use strict"; function _objectWithoutProperties(obj, keys) { @@ -3329,7 +3387,7 @@ var _bundleJs = []byte((((((((((`!function(modules) { } }), superClass && (Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass); } - var _class, _temp2, __WEBPACK_IMPORTED_MODULE_0_lodash_isNil__ = __webpack_require__(20), __WEBPACK_IMPORTED_MODULE_0_lodash_isNil___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_lodash_isNil__), __WEBPACK_IMPORTED_MODULE_1_react__ = __webpack_require__(0), __WEBPACK_IMPORTED_MODULE_1_react___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_react__), __WEBPACK_IMPORTED_MODULE_2_prop_types__ = __webpack_require__(1), __WEBPACK_IMPORTED_MODULE_2_prop_types___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_2_prop_types__), __WEBPACK_IMPORTED_MODULE_3_reduce_css_calc__ = __webpack_require__(688), __WEBPACK_IMPORTED_MODULE_3_reduce_css_calc___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_3_reduce_css_calc__), __WEBPACK_IMPORTED_MODULE_4_classnames__ = __webpack_require__(3), __WEBPACK_IMPORTED_MODULE_4_classnames___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_4_classnames__), __WEBPACK_IMPORTED_MODULE_5__util_DataUtils__ = __webpack_require__(9), __WEBPACK_IMPORTED_MODULE_6__util_ReactUtils__ = __webpack_require__(4), __WEBPACK_IMPORTED_MODULE_7__util_DOMUtils__ = __webpack_require__(183), _extends = Object.assign || function(target) { + var _class, _temp2, __WEBPACK_IMPORTED_MODULE_0_lodash_isNil__ = __webpack_require__(20), __WEBPACK_IMPORTED_MODULE_0_lodash_isNil___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_lodash_isNil__), __WEBPACK_IMPORTED_MODULE_1_react__ = __webpack_require__(0), __WEBPACK_IMPORTED_MODULE_1_react___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_react__), __WEBPACK_IMPORTED_MODULE_2_prop_types__ = __webpack_require__(1), __WEBPACK_IMPORTED_MODULE_2_prop_types___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_2_prop_types__), __WEBPACK_IMPORTED_MODULE_3_reduce_css_calc__ = __webpack_require__(771), __WEBPACK_IMPORTED_MODULE_3_reduce_css_calc___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_3_reduce_css_calc__), __WEBPACK_IMPORTED_MODULE_4_classnames__ = __webpack_require__(3), __WEBPACK_IMPORTED_MODULE_4_classnames___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_4_classnames__), __WEBPACK_IMPORTED_MODULE_5__util_DataUtils__ = __webpack_require__(9), __WEBPACK_IMPORTED_MODULE_6__util_ReactUtils__ = __webpack_require__(4), __WEBPACK_IMPORTED_MODULE_7__util_DOMUtils__ = __webpack_require__(198), _extends = Object.assign || function(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) Object.prototype.hasOwnProperty.call(source, key) && (target[key] = source[key]); @@ -3549,12 +3607,12 @@ var _bundleJs = []byte((((((((((`!function(modules) { }, _class = _temp)) || _class; __webpack_exports__.a = Dot; }, function(module, exports, __webpack_require__) { - var IObject = __webpack_require__(134), defined = __webpack_require__(136); + var IObject = __webpack_require__(146), defined = __webpack_require__(148); module.exports = function(it) { return IObject(defined(it)); }; }, function(module, exports, __webpack_require__) { - var defined = __webpack_require__(136); + var defined = __webpack_require__(148); module.exports = function(it) { return Object(defined(it)); }; @@ -3593,7 +3651,7 @@ var _bundleJs = []byte((((((((((`!function(modules) { return protoProps && defineProperties(Constructor.prototype, protoProps), staticProps && defineProperties(Constructor, staticProps), Constructor; }; - }(), _warning = __webpack_require__(12), _warning2 = _interopRequireDefault(_warning), _toCss = __webpack_require__(152), _toCss2 = _interopRequireDefault(_toCss), _toCssValue = __webpack_require__(106), _toCssValue2 = _interopRequireDefault(_toCssValue), StyleRule = function() { + }(), _warning = __webpack_require__(11), _warning2 = _interopRequireDefault(_warning), _toCss = __webpack_require__(163), _toCss2 = _interopRequireDefault(_toCss), _toCssValue = __webpack_require__(110), _toCssValue2 = _interopRequireDefault(_toCssValue), StyleRule = function() { function StyleRule(key, style, options) { _classCallCheck(this, StyleRule), this.type = "style", this.isProcessed = !1; var sheet = options.sheet, Renderer = options.Renderer, selector = options.selector; @@ -3657,34 +3715,17 @@ var _bundleJs = []byte((((((((((`!function(modules) { } ]), StyleRule; }(); exports.default = StyleRule; -}, function(module, exports) { - var g; - g = function() { - return this; - }(); - try { - g = g || Function("return this")() || (0, eval)("this"); - } catch (e) { - "object" == typeof window && (g = window); - } - module.exports = g; }, function(module, exports, __webpack_require__) { function isSymbol(value) { return "symbol" == typeof value || isObjectLike(value) && baseGetTag(value) == symbolTag; } - var baseGetTag = __webpack_require__(41), isObjectLike = __webpack_require__(36), symbolTag = "[object Symbol]"; + var baseGetTag = __webpack_require__(41), isObjectLike = __webpack_require__(42), symbolTag = "[object Symbol]"; module.exports = isSymbol; }, function(module, exports) { function identity(value) { return value; } module.exports = identity; -}, function(module, exports, __webpack_require__) { - function baseIteratee(value) { - return "function" == typeof value ? value : null == value ? identity : "object" == typeof value ? isArray(value) ? baseMatchesProperty(value[0], value[1]) : baseMatches(value) : property(value); - } - var baseMatches = __webpack_require__(671), baseMatchesProperty = __webpack_require__(674), identity = __webpack_require__(62), isArray = __webpack_require__(11), property = __webpack_require__(678); - module.exports = baseIteratee; }, function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_exports__.a = function(a, b) { @@ -3855,7 +3896,7 @@ var _bundleJs = []byte((((((((((`!function(modules) { } }), superClass && (Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass); } - var _class, _class2, _temp, __WEBPACK_IMPORTED_MODULE_0_lodash_isArray__ = __webpack_require__(11), __WEBPACK_IMPORTED_MODULE_0_lodash_isArray___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_lodash_isArray__), __WEBPACK_IMPORTED_MODULE_1_lodash_isFunction__ = __webpack_require__(8), __WEBPACK_IMPORTED_MODULE_1_lodash_isFunction___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_lodash_isFunction__), __WEBPACK_IMPORTED_MODULE_2_react__ = __webpack_require__(0), __WEBPACK_IMPORTED_MODULE_2_react___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_2_react__), __WEBPACK_IMPORTED_MODULE_3_prop_types__ = __webpack_require__(1), __WEBPACK_IMPORTED_MODULE_3_prop_types___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_3_prop_types__), __WEBPACK_IMPORTED_MODULE_4_d3_shape__ = __webpack_require__(172), __WEBPACK_IMPORTED_MODULE_5_classnames__ = __webpack_require__(3), __WEBPACK_IMPORTED_MODULE_5_classnames___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_5_classnames__), __WEBPACK_IMPORTED_MODULE_6__util_PureRender__ = __webpack_require__(5), __WEBPACK_IMPORTED_MODULE_7__util_ReactUtils__ = __webpack_require__(4), __WEBPACK_IMPORTED_MODULE_8__util_DataUtils__ = __webpack_require__(9), _extends = Object.assign || function(target) { + var _class, _class2, _temp, __WEBPACK_IMPORTED_MODULE_0_lodash_isArray__ = __webpack_require__(13), __WEBPACK_IMPORTED_MODULE_0_lodash_isArray___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_lodash_isArray__), __WEBPACK_IMPORTED_MODULE_1_lodash_isFunction__ = __webpack_require__(8), __WEBPACK_IMPORTED_MODULE_1_lodash_isFunction___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_lodash_isFunction__), __WEBPACK_IMPORTED_MODULE_2_react__ = __webpack_require__(0), __WEBPACK_IMPORTED_MODULE_2_react___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_2_react__), __WEBPACK_IMPORTED_MODULE_3_prop_types__ = __webpack_require__(1), __WEBPACK_IMPORTED_MODULE_3_prop_types___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_3_prop_types__), __WEBPACK_IMPORTED_MODULE_4_d3_shape__ = __webpack_require__(182), __WEBPACK_IMPORTED_MODULE_5_classnames__ = __webpack_require__(3), __WEBPACK_IMPORTED_MODULE_5_classnames___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_5_classnames__), __WEBPACK_IMPORTED_MODULE_6__util_PureRender__ = __webpack_require__(5), __WEBPACK_IMPORTED_MODULE_7__util_ReactUtils__ = __webpack_require__(4), __WEBPACK_IMPORTED_MODULE_8__util_DataUtils__ = __webpack_require__(9), _extends = Object.assign || function(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) Object.prototype.hasOwnProperty.call(source, key) && (target[key] = source[key]); @@ -4173,26 +4214,6 @@ var _bundleJs = []byte((((((((((`!function(modules) { } return to; }; -}, function(module, exports, __webpack_require__) { - "use strict"; - (function(process) { - function invariant(condition, format, a, b, c, d, e, f) { - if (validateFormat(format), !condition) { - var error; - if (void 0 === format) error = new Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings."); else { - var args = [ a, b, c, d, e, f ], argIndex = 0; - error = new Error(format.replace(/%s/g, function() { - return args[argIndex++]; - })), error.name = "Invariant Violation"; - } - throw error.framesToPop = 1, error; - } - } - var validateFormat = function(format) {}; - "production" !== process.env.NODE_ENV && (validateFormat = function(format) { - if (void 0 === format) throw new Error("invariant requires an error message argument"); - }), module.exports = invariant; - }).call(exports, __webpack_require__(2)); }, function(module, exports) { module.exports = function(bitmap, value) { return { @@ -4203,7 +4224,7 @@ var _bundleJs = []byte((((((((((`!function(modules) { }; }; }, function(module, exports, __webpack_require__) { - var $keys = __webpack_require__(208), enumBugKeys = __webpack_require__(140); + var $keys = __webpack_require__(226), enumBugKeys = __webpack_require__(152); module.exports = Object.keys || function(O) { return $keys(O, enumBugKeys); }; @@ -4261,7 +4282,7 @@ var _bundleJs = []byte((((((((((`!function(modules) { }, function(module, exports, __webpack_require__) { "use strict"; exports.__esModule = !0; - var _getDisplayName = __webpack_require__(226), _getDisplayName2 = function(obj) { + var _getDisplayName = __webpack_require__(244), _getDisplayName2 = function(obj) { return obj && obj.__esModule ? obj : { default: obj }; @@ -4300,7 +4321,7 @@ var _bundleJs = []byte((((((((((`!function(modules) { return protoProps && defineProperties(Constructor.prototype, protoProps), staticProps && defineProperties(Constructor, staticProps), Constructor; }; - }(), _createRule = __webpack_require__(107), _createRule2 = _interopRequireDefault(_createRule), _linkRule = __webpack_require__(231), _linkRule2 = _interopRequireDefault(_linkRule), _StyleRule = __webpack_require__(59), _StyleRule2 = _interopRequireDefault(_StyleRule), _escape = __webpack_require__(428), _escape2 = _interopRequireDefault(_escape), RuleList = function() { + }(), _createRule = __webpack_require__(111), _createRule2 = _interopRequireDefault(_createRule), _linkRule = __webpack_require__(249), _linkRule2 = _interopRequireDefault(_linkRule), _StyleRule = __webpack_require__(66), _StyleRule2 = _interopRequireDefault(_StyleRule), _escape = __webpack_require__(467), _escape2 = _interopRequireDefault(_escape), RuleList = function() { function RuleList(options) { _classCallCheck(this, RuleList), this.map = {}, this.raw = {}, this.index = [], this.options = options, this.classes = options.classes; @@ -4444,9 +4465,6 @@ var _bundleJs = []byte((((((((((`!function(modules) { color: "rgba(255, 255, 255, 0.54)" } }; -}, function(module, exports, __webpack_require__) { - var root = __webpack_require__(32), Symbol = root.Symbol; - module.exports = Symbol; }, function(module, __webpack_exports__, __webpack_require__) { "use strict"; function _objectWithoutProperties(obj, keys) { @@ -4490,15 +4508,12 @@ var _bundleJs = []byte((((((((((`!function(modules) { children: __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.oneOfType([ __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.arrayOf(__WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.node), __WEBPACK_IMPORTED_MODULE_1_prop_types___default.a.node ]) }; Surface.propTypes = propTypes, __webpack_exports__.a = Surface; -}, function(module, exports) { - function arrayMap(array, iteratee) { - for (var index = -1, length = null == array ? 0 : array.length, result = Array(length); ++index < length; ) result[index] = iteratee(array[index], index, array); - return result; - } - module.exports = arrayMap; +}, function(module, exports, __webpack_require__) { + var root = __webpack_require__(31), Symbol = root.Symbol; + module.exports = Symbol; }, function(module, __webpack_exports__, __webpack_require__) { "use strict"; - var __WEBPACK_IMPORTED_MODULE_0__src_path__ = __webpack_require__(586); + var __WEBPACK_IMPORTED_MODULE_0__src_path__ = __webpack_require__(633); __webpack_require__.d(__webpack_exports__, "a", function() { return __WEBPACK_IMPORTED_MODULE_0__src_path__.a; }); @@ -4546,12 +4561,6 @@ var _bundleJs = []byte((((((((((`!function(modules) { for (var n = series.length, o = new Array(n); --n >= 0; ) o[n] = n; return o; }; -}, function(module, exports, __webpack_require__) { - function isArrayLike(value) { - return null != value && isLength(value.length) && !isFunction(value); - } - var isFunction = __webpack_require__(8), isLength = __webpack_require__(181); - module.exports = isArrayLike; }, function(module, __webpack_exports__, __webpack_require__) { "use strict"; function Cell() { @@ -4567,6 +4576,12 @@ var _bundleJs = []byte((((((((((`!function(modules) { }; Cell.propTypes = _extends({}, __WEBPACK_IMPORTED_MODULE_1__util_ReactUtils__.c), Cell.displayName = "Cell", __webpack_exports__.a = Cell; +}, function(module, exports, __webpack_require__) { + function baseIteratee(value) { + return "function" == typeof value ? value : null == value ? identity : "object" == typeof value ? isArray(value) ? baseMatchesProperty(value[0], value[1]) : baseMatches(value) : property(value); + } + var baseMatches = __webpack_require__(815), baseMatchesProperty = __webpack_require__(818), identity = __webpack_require__(68), isArray = __webpack_require__(13), property = __webpack_require__(822); + module.exports = baseIteratee; }, function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_exports__.a = function(x) { @@ -4601,29 +4616,29 @@ var _bundleJs = []byte((((((((((`!function(modules) { }, linearish(scale); } __webpack_exports__.b = linearish, __webpack_exports__.a = linear; - var __WEBPACK_IMPORTED_MODULE_0_d3_array__ = __webpack_require__(37), __WEBPACK_IMPORTED_MODULE_1_d3_interpolate__ = __webpack_require__(89), __WEBPACK_IMPORTED_MODULE_2__continuous__ = __webpack_require__(125), __WEBPACK_IMPORTED_MODULE_3__tickFormat__ = __webpack_require__(742); + var __WEBPACK_IMPORTED_MODULE_0_d3_array__ = __webpack_require__(37), __WEBPACK_IMPORTED_MODULE_1_d3_interpolate__ = __webpack_require__(92), __WEBPACK_IMPORTED_MODULE_2__continuous__ = __webpack_require__(137), __WEBPACK_IMPORTED_MODULE_3__tickFormat__ = __webpack_require__(883); }, function(module, __webpack_exports__, __webpack_require__) { "use strict"; - var __WEBPACK_IMPORTED_MODULE_0__src_value__ = __webpack_require__(186); + var __WEBPACK_IMPORTED_MODULE_0__src_value__ = __webpack_require__(206); __webpack_require__.d(__webpack_exports__, "a", function() { return __WEBPACK_IMPORTED_MODULE_0__src_value__.a; }); - var __WEBPACK_IMPORTED_MODULE_5__src_number__ = (__webpack_require__(310), __webpack_require__(189), - __webpack_require__(308), __webpack_require__(311), __webpack_require__(124)); + var __WEBPACK_IMPORTED_MODULE_5__src_number__ = (__webpack_require__(349), __webpack_require__(209), + __webpack_require__(347), __webpack_require__(350), __webpack_require__(136)); __webpack_require__.d(__webpack_exports__, "c", function() { return __WEBPACK_IMPORTED_MODULE_5__src_number__.a; }); - var __WEBPACK_IMPORTED_MODULE_7__src_round__ = (__webpack_require__(312), __webpack_require__(732)); + var __WEBPACK_IMPORTED_MODULE_7__src_round__ = (__webpack_require__(351), __webpack_require__(873)); __webpack_require__.d(__webpack_exports__, "d", function() { return __WEBPACK_IMPORTED_MODULE_7__src_round__.a; }); - var __WEBPACK_IMPORTED_MODULE_15__src_cubehelix__ = (__webpack_require__(313), __webpack_require__(733), - __webpack_require__(736), __webpack_require__(307), __webpack_require__(737), __webpack_require__(738), - __webpack_require__(739), __webpack_require__(740)); + var __WEBPACK_IMPORTED_MODULE_15__src_cubehelix__ = (__webpack_require__(352), __webpack_require__(874), + __webpack_require__(877), __webpack_require__(346), __webpack_require__(878), __webpack_require__(879), + __webpack_require__(880), __webpack_require__(881)); __webpack_require__.d(__webpack_exports__, "b", function() { return __WEBPACK_IMPORTED_MODULE_15__src_cubehelix__.a; }); - __webpack_require__(741); + __webpack_require__(882); }, function(module, __webpack_exports__, __webpack_require__) { "use strict"; function linear(a, d) { @@ -4650,7 +4665,7 @@ var _bundleJs = []byte((((((((((`!function(modules) { return d ? linear(a, d) : Object(__WEBPACK_IMPORTED_MODULE_0__constant__.a)(isNaN(a) ? b : a); } __webpack_exports__.c = hue, __webpack_exports__.b = gamma, __webpack_exports__.a = nogamma; - var __WEBPACK_IMPORTED_MODULE_0__constant__ = __webpack_require__(309); + var __WEBPACK_IMPORTED_MODULE_0__constant__ = __webpack_require__(348); }, function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_exports__.a = function(s) { @@ -4845,7 +4860,7 @@ var _bundleJs = []byte((((((((((`!function(modules) { }, function(module, exports, __webpack_require__) { "use strict"; (function(process) { - var emptyFunction = __webpack_require__(39), warning = emptyFunction; + var emptyFunction = __webpack_require__(50), warning = emptyFunction; if ("production" !== process.env.NODE_ENV) { var printWarning = function(format) { for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) args[_key - 1] = arguments[_key]; @@ -4858,7 +4873,7 @@ var _bundleJs = []byte((((((((((`!function(modules) { } catch (x) {} }; warning = function(condition, format) { - if (void 0 === format) throw new Error("` + "`")) + (`warning(condition, format, ...args)` + ("`" + ` requires a warning message argument"); + if (void 0 === format) throw new Error("` + ("`" + `warning(condition, format, ...args)`)) + ("`" + (` requires a warning message argument"); if (0 !== format.indexOf("Failed Composite propType: ") && !condition) { for (var _len2 = arguments.length, args = Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) args[_key2 - 2] = arguments[_key2]; printWarning.apply(void 0, [ format ].concat(args)); @@ -4880,7 +4895,7 @@ var _bundleJs = []byte((((((((((`!function(modules) { } } } - "production" === process.env.NODE_ENV ? (checkDCE(), module.exports = __webpack_require__(339)) : module.exports = __webpack_require__(342); + "production" === process.env.NODE_ENV ? (checkDCE(), module.exports = __webpack_require__(378)) : module.exports = __webpack_require__(381); }).call(exports, __webpack_require__(2)); }, function(module, exports, __webpack_require__) { "use strict"; @@ -4898,10 +4913,12 @@ var _bundleJs = []byte((((((((((`!function(modules) { var hasOwnProperty = Object.prototype.hasOwnProperty; module.exports = shallowEqual; }, function(module, exports, __webpack_require__) { - var toInteger = __webpack_require__(137), min = Math.min; + var toInteger = __webpack_require__(149), min = Math.min; module.exports = function(it) { return it > 0 ? min(toInteger(it), 9007199254740991) : 0; }; +}, function(module, exports) { + module.exports = !0; }, function(module, exports) { var id = 0, px = Math.random(); module.exports = function(key) { @@ -4917,7 +4934,7 @@ var _bundleJs = []byte((((((((((`!function(modules) { }; } exports.__esModule = !0; - var _iterator = __webpack_require__(357), _iterator2 = _interopRequireDefault(_iterator), _symbol = __webpack_require__(365), _symbol2 = _interopRequireDefault(_symbol), _typeof = "function" == typeof _symbol2.default && "symbol" == typeof _iterator2.default ? function(obj) { + var _iterator = __webpack_require__(396), _iterator2 = _interopRequireDefault(_iterator), _symbol = __webpack_require__(404), _symbol2 = _interopRequireDefault(_symbol), _typeof = "function" == typeof _symbol2.default && "symbol" == typeof _iterator2.default ? function(obj) { return typeof obj; } : function(obj) { return obj && "function" == typeof _symbol2.default && obj.constructor === _symbol2.default && obj !== _symbol2.default.prototype ? "symbol" : typeof obj; @@ -4928,9 +4945,9 @@ var _bundleJs = []byte((((((((((`!function(modules) { return obj && "function" == typeof _symbol2.default && obj.constructor === _symbol2.default && obj !== _symbol2.default.prototype ? "symbol" : void 0 === obj ? "undefined" : _typeof(obj); }; }, function(module, exports, __webpack_require__) { - var anObject = __webpack_require__(47), dPs = __webpack_require__(361), enumBugKeys = __webpack_require__(140), IE_PROTO = __webpack_require__(138)("IE_PROTO"), Empty = function() {}, createDict = function() { - var iframeDocument, iframe = __webpack_require__(207)("iframe"), i = enumBugKeys.length; - for (iframe.style.display = "none", __webpack_require__(362).appendChild(iframe), + var anObject = __webpack_require__(52), dPs = __webpack_require__(400), enumBugKeys = __webpack_require__(152), IE_PROTO = __webpack_require__(150)("IE_PROTO"), Empty = function() {}, createDict = function() { + var iframeDocument, iframe = __webpack_require__(225)("iframe"), i = enumBugKeys.length; + for (iframe.style.display = "none", __webpack_require__(401).appendChild(iframe), iframe.src = "javascript:", iframeDocument = iframe.contentWindow.document, iframeDocument.open(), iframeDocument.write(" + -
-
- -
-
-

Welcome to Swarm

-
-
- - - - -

Enter the hash or ENS of a Swarm-hosted file below:

- - - -
-
-

- Swarm: Serverless Hosting Incentivised Peer-To-Peer Storage And Content Distribution
- Swarm -

-
- +

Enter the hash or ENS of a Swarm-hosted file below:

+
+ + +
+
+ +
+

+ Swarm: Serverless Hosting Incentivised peer-to-peer Storage and Content Distribution +

+
+ `[1:])) diff --git a/swarm/api/manifest.go b/swarm/api/manifest.go index 685a300fca..198ca22ce0 100644 --- a/swarm/api/manifest.go +++ b/swarm/api/manifest.go @@ -18,22 +18,25 @@ package api import ( "bytes" + "context" "encoding/json" "errors" "fmt" "io" "net/http" "strings" - "sync" "time" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/swarm/log" "github.com/ethereum/go-ethereum/swarm/storage" ) const ( - ManifestType = "application/bzz-manifest+json" + ManifestType = "application/bzz-manifest+json" + ResourceContentType = "application/bzz-resource" + + manifestSizeLimit = 5 * 1024 * 1024 ) // Manifest represents a swarm manifest @@ -59,38 +62,57 @@ type ManifestList struct { } // NewManifest creates and stores a new, empty manifest -func (a *Api) NewManifest() (storage.Key, error) { +func (a *API) NewManifest(ctx context.Context, toEncrypt bool) (storage.Address, error) { var manifest Manifest data, err := json.Marshal(&manifest) if err != nil { return nil, err } - return a.Store(bytes.NewReader(data), int64(len(data)), &sync.WaitGroup{}) + key, wait, err := a.Store(ctx, bytes.NewReader(data), int64(len(data)), toEncrypt) + wait(ctx) + return key, err +} + +// Manifest hack for supporting Mutable Resource Updates from the bzz: scheme +// see swarm/api/api.go:API.Get() for more information +func (a *API) NewResourceManifest(ctx context.Context, resourceAddr string) (storage.Address, error) { + var manifest Manifest + entry := ManifestEntry{ + Hash: resourceAddr, + ContentType: ResourceContentType, + } + manifest.Entries = append(manifest.Entries, entry) + data, err := json.Marshal(&manifest) + if err != nil { + return nil, err + } + key, _, err := a.Store(ctx, bytes.NewReader(data), int64(len(data)), false) + return key, err } // ManifestWriter is used to add and remove entries from an underlying manifest type ManifestWriter struct { - api *Api + api *API trie *manifestTrie quitC chan bool } -func (a *Api) NewManifestWriter(key storage.Key, quitC chan bool) (*ManifestWriter, error) { - trie, err := loadManifest(a.dpa, key, quitC) +func (a *API) NewManifestWriter(ctx context.Context, addr storage.Address, quitC chan bool) (*ManifestWriter, error) { + trie, err := loadManifest(ctx, a.fileStore, addr, quitC) if err != nil { - return nil, fmt.Errorf("error loading manifest %s: %s", key, err) + return nil, fmt.Errorf("error loading manifest %s: %s", addr, err) } return &ManifestWriter{a, trie, quitC}, nil } // AddEntry stores the given data and adds the resulting key to the manifest -func (m *ManifestWriter) AddEntry(data io.Reader, e *ManifestEntry) (storage.Key, error) { - key, err := m.api.Store(data, e.Size, nil) +func (m *ManifestWriter) AddEntry(ctx context.Context, data io.Reader, e *ManifestEntry) (storage.Address, error) { + key, _, err := m.api.Store(ctx, data, e.Size, m.trie.encrypted) if err != nil { return nil, err } entry := newManifestTrieEntry(e, nil) - entry.Hash = key.String() + entry.Hash = key.Hex() m.trie.addEntry(entry, m.quitC) return key, nil } @@ -102,29 +124,29 @@ func (m *ManifestWriter) RemoveEntry(path string) error { } // Store stores the manifest, returning the resulting storage key -func (m *ManifestWriter) Store() (storage.Key, error) { - return m.trie.hash, m.trie.recalcAndStore() +func (m *ManifestWriter) Store() (storage.Address, error) { + return m.trie.ref, m.trie.recalcAndStore() } // ManifestWalker is used to recursively walk the entries in the manifest and // all of its submanifests type ManifestWalker struct { - api *Api + api *API trie *manifestTrie quitC chan bool } -func (a *Api) NewManifestWalker(key storage.Key, quitC chan bool) (*ManifestWalker, error) { - trie, err := loadManifest(a.dpa, key, quitC) +func (a *API) NewManifestWalker(ctx context.Context, addr storage.Address, quitC chan bool) (*ManifestWalker, error) { + trie, err := loadManifest(ctx, a.fileStore, addr, quitC) if err != nil { - return nil, fmt.Errorf("error loading manifest %s: %s", key, err) + return nil, fmt.Errorf("error loading manifest %s: %s", addr, err) } return &ManifestWalker{a, trie, quitC}, nil } -// SkipManifest is used as a return value from WalkFn to indicate that the +// ErrSkipManifest is used as a return value from WalkFn to indicate that the // manifest should be skipped -var SkipManifest = errors.New("skip this manifest") +var ErrSkipManifest = errors.New("skip this manifest") // WalkFn is the type of function called for each entry visited by a recursive // manifest walk @@ -144,7 +166,7 @@ func (m *ManifestWalker) walk(trie *manifestTrie, prefix string, walkFn WalkFn) entry.Path = prefix + entry.Path err := walkFn(&entry.ManifestEntry) if err != nil { - if entry.ContentType == ManifestType && err == SkipManifest { + if entry.ContentType == ManifestType && err == ErrSkipManifest { continue } return err @@ -163,9 +185,10 @@ func (m *ManifestWalker) walk(trie *manifestTrie, prefix string, walkFn WalkFn) } type manifestTrie struct { - dpa *storage.DPA - entries [257]*manifestTrieEntry // indexed by first character of basePath, entries[256] is the empty basePath entry - hash storage.Key // if hash != nil, it is stored + fileStore *storage.FileStore + entries [257]*manifestTrieEntry // indexed by first character of basePath, entries[256] is the empty basePath entry + ref storage.Address // if ref != nil, it is stored + encrypted bool } func newManifestTrieEntry(entry *ManifestEntry, subtrie *manifestTrie) *manifestTrieEntry { @@ -181,48 +204,55 @@ type manifestTrieEntry struct { subtrie *manifestTrie } -func loadManifest(dpa *storage.DPA, hash storage.Key, quitC chan bool) (trie *manifestTrie, err error) { // non-recursive, subtrees are downloaded on-demand - - log.Trace(fmt.Sprintf("manifest lookup key: '%v'.", hash.Log())) - // retrieve manifest via DPA - manifestReader := dpa.Retrieve(hash) - return readManifest(manifestReader, hash, dpa, quitC) +func loadManifest(ctx context.Context, fileStore *storage.FileStore, hash storage.Address, quitC chan bool) (trie *manifestTrie, err error) { // non-recursive, subtrees are downloaded on-demand + log.Trace("manifest lookup", "key", hash) + // retrieve manifest via FileStore + manifestReader, isEncrypted := fileStore.Retrieve(ctx, hash) + log.Trace("reader retrieved", "key", hash) + return readManifest(manifestReader, hash, fileStore, isEncrypted, quitC) } -func readManifest(manifestReader storage.LazySectionReader, hash storage.Key, dpa *storage.DPA, quitC chan bool) (trie *manifestTrie, err error) { // non-recursive, subtrees are downloaded on-demand +func readManifest(mr storage.LazySectionReader, hash storage.Address, fileStore *storage.FileStore, isEncrypted bool, quitC chan bool) (trie *manifestTrie, err error) { // non-recursive, subtrees are downloaded on-demand // TODO check size for oversized manifests - size, err := manifestReader.Size(quitC) + size, err := mr.Size(mr.Context(), quitC) if err != nil { // size == 0 // can't determine size means we don't have the root chunk + log.Trace("manifest not found", "key", hash) err = fmt.Errorf("Manifest not Found") return } + if size > manifestSizeLimit { + log.Warn("manifest exceeds size limit", "key", hash, "size", size, "limit", manifestSizeLimit) + err = fmt.Errorf("Manifest size of %v bytes exceeds the %v byte limit", size, manifestSizeLimit) + return + } manifestData := make([]byte, size) - read, err := manifestReader.Read(manifestData) + read, err := mr.Read(manifestData) if int64(read) < size { - log.Trace(fmt.Sprintf("Manifest %v not found.", hash.Log())) + log.Trace("manifest not found", "key", hash) if err == nil { err = fmt.Errorf("Manifest retrieval cut short: read %v, expect %v", read, size) } return } - log.Trace(fmt.Sprintf("Manifest %v retrieved", hash.Log())) + log.Debug("manifest retrieved", "key", hash) var man struct { Entries []*manifestTrieEntry `json:"entries"` } err = json.Unmarshal(manifestData, &man) if err != nil { err = fmt.Errorf("Manifest %v is malformed: %v", hash.Log(), err) - log.Trace(fmt.Sprintf("%v", err)) + log.Trace("malformed manifest", "key", hash) return } - log.Trace(fmt.Sprintf("Manifest %v has %d entries.", hash.Log(), len(man.Entries))) + log.Trace("manifest entries", "key", hash, "len", len(man.Entries)) trie = &manifestTrie{ - dpa: dpa, + fileStore: fileStore, + encrypted: isEncrypted, } for _, entry := range man.Entries { trie.addEntry(entry, quitC) @@ -230,18 +260,18 @@ func readManifest(manifestReader storage.LazySectionReader, hash storage.Key, dp return } -func (self *manifestTrie) addEntry(entry *manifestTrieEntry, quitC chan bool) { - self.hash = nil // trie modified, hash needs to be re-calculated on demand +func (mt *manifestTrie) addEntry(entry *manifestTrieEntry, quitC chan bool) { + mt.ref = nil // trie modified, hash needs to be re-calculated on demand if len(entry.Path) == 0 { - self.entries[256] = entry + mt.entries[256] = entry return } b := entry.Path[0] - oldentry := self.entries[b] + oldentry := mt.entries[b] if (oldentry == nil) || (oldentry.Path == entry.Path && oldentry.ContentType != ManifestType) { - self.entries[b] = entry + mt.entries[b] = entry return } @@ -251,7 +281,7 @@ func (self *manifestTrie) addEntry(entry *manifestTrieEntry, quitC chan bool) { } if (oldentry.ContentType == ManifestType) && (cpl == len(oldentry.Path)) { - if self.loadSubTrie(oldentry, quitC) != nil { + if mt.loadSubTrie(oldentry, quitC) != nil { return } entry.Path = entry.Path[cpl:] @@ -263,21 +293,22 @@ func (self *manifestTrie) addEntry(entry *manifestTrieEntry, quitC chan bool) { commonPrefix := entry.Path[:cpl] subtrie := &manifestTrie{ - dpa: self.dpa, + fileStore: mt.fileStore, + encrypted: mt.encrypted, } entry.Path = entry.Path[cpl:] oldentry.Path = oldentry.Path[cpl:] subtrie.addEntry(entry, quitC) subtrie.addEntry(oldentry, quitC) - self.entries[b] = newManifestTrieEntry(&ManifestEntry{ + mt.entries[b] = newManifestTrieEntry(&ManifestEntry{ Path: commonPrefix, ContentType: ManifestType, }, subtrie) } -func (self *manifestTrie) getCountLast() (cnt int, entry *manifestTrieEntry) { - for _, e := range self.entries { +func (mt *manifestTrie) getCountLast() (cnt int, entry *manifestTrieEntry) { + for _, e := range mt.entries { if e != nil { cnt++ entry = e @@ -286,27 +317,27 @@ func (self *manifestTrie) getCountLast() (cnt int, entry *manifestTrieEntry) { return } -func (self *manifestTrie) deleteEntry(path string, quitC chan bool) { - self.hash = nil // trie modified, hash needs to be re-calculated on demand +func (mt *manifestTrie) deleteEntry(path string, quitC chan bool) { + mt.ref = nil // trie modified, hash needs to be re-calculated on demand if len(path) == 0 { - self.entries[256] = nil + mt.entries[256] = nil return } b := path[0] - entry := self.entries[b] + entry := mt.entries[b] if entry == nil { return } if entry.Path == path { - self.entries[b] = nil + mt.entries[b] = nil return } epl := len(entry.Path) if (entry.ContentType == ManifestType) && (len(path) >= epl) && (path[:epl] == entry.Path) { - if self.loadSubTrie(entry, quitC) != nil { + if mt.loadSubTrie(entry, quitC) != nil { return } entry.subtrie.deleteEntry(path[epl:], quitC) @@ -317,13 +348,13 @@ func (self *manifestTrie) deleteEntry(path string, quitC chan bool) { if lastentry != nil { lastentry.Path = entry.Path + lastentry.Path } - self.entries[b] = lastentry + mt.entries[b] = lastentry } } } -func (self *manifestTrie) recalcAndStore() error { - if self.hash != nil { +func (mt *manifestTrie) recalcAndStore() error { + if mt.ref != nil { return nil } @@ -331,14 +362,14 @@ func (self *manifestTrie) recalcAndStore() error { buffer.WriteString(`{"entries":[`) list := &Manifest{} - for _, entry := range self.entries { + for _, entry := range mt.entries { if entry != nil { if entry.Hash == "" { // TODO: paralellize err := entry.subtrie.recalcAndStore() if err != nil { return err } - entry.Hash = entry.subtrie.hash.String() + entry.Hash = entry.subtrie.ref.Hex() } list.Entries = append(list.Entries, entry.ManifestEntry) } @@ -351,23 +382,26 @@ func (self *manifestTrie) recalcAndStore() error { } sr := bytes.NewReader(manifest) - wg := &sync.WaitGroup{} - key, err2 := self.dpa.Store(sr, int64(len(manifest)), wg, nil) - wg.Wait() - self.hash = key + ctx := context.TODO() + key, wait, err2 := mt.fileStore.Store(ctx, sr, int64(len(manifest)), mt.encrypted) + if err2 != nil { + return err2 + } + err2 = wait(ctx) + mt.ref = key return err2 } -func (self *manifestTrie) loadSubTrie(entry *manifestTrieEntry, quitC chan bool) (err error) { +func (mt *manifestTrie) loadSubTrie(entry *manifestTrieEntry, quitC chan bool) (err error) { if entry.subtrie == nil { hash := common.Hex2Bytes(entry.Hash) - entry.subtrie, err = loadManifest(self.dpa, hash, quitC) + entry.subtrie, err = loadManifest(context.TODO(), mt.fileStore, hash, quitC) entry.Hash = "" // might not match, should be recalculated } return } -func (self *manifestTrie) listWithPrefixInt(prefix, rp string, quitC chan bool, cb func(entry *manifestTrieEntry, suffix string)) error { +func (mt *manifestTrie) listWithPrefixInt(prefix, rp string, quitC chan bool, cb func(entry *manifestTrieEntry, suffix string)) error { plen := len(prefix) var start, stop int if plen == 0 { @@ -384,7 +418,7 @@ func (self *manifestTrie) listWithPrefixInt(prefix, rp string, quitC chan bool, return fmt.Errorf("aborted") default: } - entry := self.entries[i] + entry := mt.entries[i] if entry != nil { epl := len(entry.Path) if entry.ContentType == ManifestType { @@ -393,7 +427,7 @@ func (self *manifestTrie) listWithPrefixInt(prefix, rp string, quitC chan bool, l = epl } if prefix[:l] == entry.Path[:l] { - err := self.loadSubTrie(entry, quitC) + err := mt.loadSubTrie(entry, quitC) if err != nil { return err } @@ -412,23 +446,22 @@ func (self *manifestTrie) listWithPrefixInt(prefix, rp string, quitC chan bool, return nil } -func (self *manifestTrie) listWithPrefix(prefix string, quitC chan bool, cb func(entry *manifestTrieEntry, suffix string)) (err error) { - return self.listWithPrefixInt(prefix, "", quitC, cb) +func (mt *manifestTrie) listWithPrefix(prefix string, quitC chan bool, cb func(entry *manifestTrieEntry, suffix string)) (err error) { + return mt.listWithPrefixInt(prefix, "", quitC, cb) } -func (self *manifestTrie) findPrefixOf(path string, quitC chan bool) (entry *manifestTrieEntry, pos int) { - +func (mt *manifestTrie) findPrefixOf(path string, quitC chan bool) (entry *manifestTrieEntry, pos int) { log.Trace(fmt.Sprintf("findPrefixOf(%s)", path)) if len(path) == 0 { - return self.entries[256], 0 + return mt.entries[256], 0 } //see if first char is in manifest entries b := path[0] - entry = self.entries[b] + entry = mt.entries[b] if entry == nil { - return self.entries[256], 0 + return mt.entries[256], 0 } epl := len(entry.Path) @@ -436,7 +469,7 @@ func (self *manifestTrie) findPrefixOf(path string, quitC chan bool) (entry *man if len(path) <= epl { if entry.Path[:len(path)] == path { if entry.ContentType == ManifestType { - err := self.loadSubTrie(entry, quitC) + err := mt.loadSubTrie(entry, quitC) if err == nil && entry.subtrie != nil { subentries := entry.subtrie.entries for i := 0; i < len(subentries); i++ { @@ -457,7 +490,7 @@ func (self *manifestTrie) findPrefixOf(path string, quitC chan bool) (entry *man log.Trace(fmt.Sprintf("entry.ContentType = %v", entry.ContentType)) //the subentry is a manifest, load subtrie if entry.ContentType == ManifestType && (strings.Contains(entry.Path, path) || strings.Contains(path, entry.Path)) { - err := self.loadSubTrie(entry, quitC) + err := mt.loadSubTrie(entry, quitC) if err != nil { return nil, 0 } @@ -478,7 +511,7 @@ func (self *manifestTrie) findPrefixOf(path string, quitC chan bool) (entry *man pos = epl } } - return + return nil, 0 } // file system manifest always contains regularized paths @@ -495,10 +528,10 @@ func RegularSlashes(path string) (res string) { return } -func (self *manifestTrie) getEntry(spath string) (entry *manifestTrieEntry, fullpath string) { +func (mt *manifestTrie) getEntry(spath string) (entry *manifestTrieEntry, fullpath string) { path := RegularSlashes(spath) var pos int quitC := make(chan bool) - entry, pos = self.findPrefixOf(path, quitC) + entry, pos = mt.findPrefixOf(path, quitC) return entry, path[:pos] } diff --git a/swarm/api/manifest_test.go b/swarm/api/manifest_test.go index 7098ca16fd..d65f023f85 100644 --- a/swarm/api/manifest_test.go +++ b/swarm/api/manifest_test.go @@ -42,7 +42,9 @@ func manifest(paths ...string) (manifestReader storage.LazySectionReader) { func testGetEntry(t *testing.T, path, match string, multiple bool, paths ...string) *manifestTrie { quitC := make(chan bool) - trie, err := readManifest(manifest(paths...), nil, nil, quitC) + fileStore := storage.NewFileStore(nil, storage.NewFileStoreParams()) + ref := make([]byte, fileStore.HashSize()) + trie, err := readManifest(manifest(paths...), ref, fileStore, false, quitC) if err != nil { t.Errorf("unexpected error making manifest: %v", err) } @@ -97,7 +99,9 @@ func TestGetEntry(t *testing.T) { func TestExactMatch(t *testing.T) { quitC := make(chan bool) mf := manifest("shouldBeExactMatch.css", "shouldBeExactMatch.css.map") - trie, err := readManifest(mf, nil, nil, quitC) + fileStore := storage.NewFileStore(nil, storage.NewFileStoreParams()) + ref := make([]byte, fileStore.HashSize()) + trie, err := readManifest(mf, ref, fileStore, false, quitC) if err != nil { t.Errorf("unexpected error making manifest: %v", err) } @@ -128,7 +132,9 @@ func TestAddFileWithManifestPath(t *testing.T) { reader := &storage.LazyTestSectionReader{ SectionReader: io.NewSectionReader(bytes.NewReader(manifest), 0, int64(len(manifest))), } - trie, err := readManifest(reader, nil, nil, nil) + fileStore := storage.NewFileStore(nil, storage.NewFileStoreParams()) + ref := make([]byte, fileStore.HashSize()) + trie, err := readManifest(reader, ref, fileStore, false, nil) if err != nil { t.Fatal(err) } @@ -144,3 +150,26 @@ func TestAddFileWithManifestPath(t *testing.T) { checkEntry(t, "ac", "ac", false, trie) checkEntry(t, "a", "a", false, trie) } + +// TestReadManifestOverSizeLimit creates a manifest reader with data longer then +// manifestSizeLimit and checks if readManifest function will return the exact error +// message. +// The manifest data is not in json-encoded format, preventing possbile +// successful parsing attempts if limit check fails. +func TestReadManifestOverSizeLimit(t *testing.T) { + manifest := make([]byte, manifestSizeLimit+1) + reader := &storage.LazyTestSectionReader{ + SectionReader: io.NewSectionReader(bytes.NewReader(manifest), 0, int64(len(manifest))), + } + _, err := readManifest(reader, storage.Address{}, nil, false, nil) + if err == nil { + t.Fatal("got no error from readManifest") + } + // Error message is part of the http response body + // which justifies exact string validation. + got := err.Error() + want := fmt.Sprintf("Manifest size of %v bytes exceeds the %v byte limit", len(manifest), manifestSizeLimit) + if got != want { + t.Fatalf("got error mesage %q, expected %q", got, want) + } +} diff --git a/swarm/api/storage.go b/swarm/api/storage.go index 0e3abecfe4..3b52301a01 100644 --- a/swarm/api/storage.go +++ b/swarm/api/storage.go @@ -16,7 +16,12 @@ package api -import "path" +import ( + "context" + "path" + + "github.com/ethereum/go-ethereum/swarm/storage" +) type Response struct { MimeType string @@ -30,10 +35,10 @@ type Response struct { // // DEPRECATED: Use the HTTP API instead type Storage struct { - api *Api + api *API } -func NewStorage(api *Api) *Storage { +func NewStorage(api *API) *Storage { return &Storage{api} } @@ -41,12 +46,8 @@ func NewStorage(api *Api) *Storage { // its content type // // DEPRECATED: Use the HTTP API instead -func (self *Storage) Put(content, contentType string) (string, error) { - key, err := self.api.Put(content, contentType) - if err != nil { - return "", err - } - return key.String(), err +func (s *Storage) Put(ctx context.Context, content string, contentType string, toEncrypt bool) (storage.Address, func(context.Context) error, error) { + return s.api.Put(ctx, content, contentType, toEncrypt) } // Get retrieves the content from bzzpath and reads the response in full @@ -57,21 +58,21 @@ func (self *Storage) Put(content, contentType string) (string, error) { // size is resp.Size // // DEPRECATED: Use the HTTP API instead -func (self *Storage) Get(bzzpath string) (*Response, error) { +func (s *Storage) Get(ctx context.Context, bzzpath string) (*Response, error) { uri, err := Parse(path.Join("bzz:/", bzzpath)) if err != nil { return nil, err } - key, err := self.api.Resolve(uri) + addr, err := s.api.Resolve(ctx, uri) if err != nil { return nil, err } - reader, mimeType, status, err := self.api.Get(key, uri.Path) + reader, mimeType, status, _, err := s.api.Get(ctx, addr, uri.Path) if err != nil { return nil, err } quitC := make(chan bool) - expsize, err := reader.Size(quitC) + expsize, err := reader.Size(ctx, quitC) if err != nil { return nil, err } @@ -87,18 +88,18 @@ func (self *Storage) Get(bzzpath string) (*Response, error) { // and merge on to it. creating an entry w conentType (mime) // // DEPRECATED: Use the HTTP API instead -func (self *Storage) Modify(rootHash, path, contentHash, contentType string) (newRootHash string, err error) { +func (s *Storage) Modify(ctx context.Context, rootHash, path, contentHash, contentType string) (newRootHash string, err error) { uri, err := Parse("bzz:/" + rootHash) if err != nil { return "", err } - key, err := self.api.Resolve(uri) + addr, err := s.api.Resolve(ctx, uri) if err != nil { return "", err } - key, err = self.api.Modify(key, path, contentHash, contentType) + addr, err = s.api.Modify(ctx, addr, path, contentHash, contentType) if err != nil { return "", err } - return key.String(), nil + return addr.Hex(), nil } diff --git a/swarm/api/storage_test.go b/swarm/api/storage_test.go index d260dd61d8..ef96972b68 100644 --- a/swarm/api/storage_test.go +++ b/swarm/api/storage_test.go @@ -17,30 +17,37 @@ package api import ( + "context" "testing" ) -func testStorage(t *testing.T, f func(*Storage)) { - testApi(t, func(api *Api) { - f(NewStorage(api)) +func testStorage(t *testing.T, f func(*Storage, bool)) { + testAPI(t, func(api *API, toEncrypt bool) { + f(NewStorage(api), toEncrypt) }) } func TestStoragePutGet(t *testing.T) { - testStorage(t, func(api *Storage) { + testStorage(t, func(api *Storage, toEncrypt bool) { content := "hello" exp := expResponse(content, "text/plain", 0) // exp := expResponse([]byte(content), "text/plain", 0) - bzzhash, err := api.Put(content, exp.MimeType) + ctx := context.TODO() + bzzkey, wait, err := api.Put(ctx, content, exp.MimeType, toEncrypt) if err != nil { t.Fatalf("unexpected error: %v", err) } - // to check put against the Api#Get + err = wait(ctx) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + bzzhash := bzzkey.Hex() + // to check put against the API#Get resp0 := testGet(t, api.api, bzzhash, "") checkResponse(t, resp0, exp) // check storage#Get - resp, err := api.Get(bzzhash) + resp, err := api.Get(context.TODO(), bzzhash) if err != nil { t.Fatalf("unexpected error: %v", err) } diff --git a/swarm/api/testapi.go b/swarm/api/testapi.go index 6631196c17..4c7d0982ba 100644 --- a/swarm/api/testapi.go +++ b/swarm/api/testapi.go @@ -21,26 +21,26 @@ import ( ) type Control struct { - api *Api + api *API hive *network.Hive } -func NewControl(api *Api, hive *network.Hive) *Control { +func NewControl(api *API, hive *network.Hive) *Control { return &Control{api, hive} } -func (self *Control) BlockNetworkRead(on bool) { - self.hive.BlockNetworkRead(on) -} - -func (self *Control) SyncEnabled(on bool) { - self.hive.SyncEnabled(on) -} - -func (self *Control) SwapEnabled(on bool) { - self.hive.SwapEnabled(on) -} - -func (self *Control) Hive() string { - return self.hive.String() +//func (self *Control) BlockNetworkRead(on bool) { +// self.hive.BlockNetworkRead(on) +//} +// +//func (self *Control) SyncEnabled(on bool) { +// self.hive.SyncEnabled(on) +//} +// +//func (self *Control) SwapEnabled(on bool) { +// self.hive.SwapEnabled(on) +//} +// +func (c *Control) Hive() string { + return c.hive.String() } diff --git a/swarm/api/uri.go b/swarm/api/uri.go index d8aafedf41..14965e0d93 100644 --- a/swarm/api/uri.go +++ b/swarm/api/uri.go @@ -19,9 +19,17 @@ package api import ( "fmt" "net/url" + "regexp" "strings" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/swarm/storage" ) +//matches hex swarm hashes +// TODO: this is bad, it should not be hardcoded how long is a hash +var hashMatcher = regexp.MustCompile("^([0-9A-Fa-f]{64})([0-9A-Fa-f]{64})?$") + // URI is a reference to content stored in swarm. type URI struct { // Scheme has one of the following values: @@ -32,18 +40,15 @@ type URI struct { // (address is not resolved) // * bzz-list - list of all files contained in a swarm manifest // - // Deprecated Schemes: - // * bzzr - raw swarm content - // * bzzi - immutable URI of an entry in a swarm manifest - // (address is not resolved) - // * bzz-hash - hash of swarm content - // Scheme string - // Addr is either a hexadecimal storage key or it an address which - // resolves to a storage key + // Addr is either a hexadecimal storage address or it an address which + // resolves to a storage address Addr string + // addr stores the parsed storage address + addr storage.Address + // Path is the path to the content within a swarm manifest Path string } @@ -59,7 +64,6 @@ type URI struct { // * :/// // // with scheme one of bzz, bzz-raw, bzz-immutable, bzz-list or bzz-hash -// or deprecated ones bzzr and bzzi func Parse(rawuri string) (*URI, error) { u, err := url.Parse(rawuri) if err != nil { @@ -69,7 +73,7 @@ func Parse(rawuri string) (*URI, error) { // check the scheme is valid switch uri.Scheme { - case "bzz", "bzz-raw", "bzz-immutable", "bzz-list", "bzz-hash", "bzzr", "bzzi": + case "bzz", "bzz-raw", "bzz-immutable", "bzz-list", "bzz-hash", "bzz-resource": default: return nil, fmt.Errorf("unknown scheme %q", u.Scheme) } @@ -91,6 +95,9 @@ func Parse(rawuri string) (*URI, error) { } return uri, nil } +func (u *URI) Resource() bool { + return u.Scheme == "bzz-resource" +} func (u *URI) Raw() bool { return u.Scheme == "bzz-raw" @@ -104,14 +111,6 @@ func (u *URI) List() bool { return u.Scheme == "bzz-list" } -func (u *URI) DeprecatedRaw() bool { - return u.Scheme == "bzzr" -} - -func (u *URI) DeprecatedImmutable() bool { - return u.Scheme == "bzzi" -} - func (u *URI) Hash() bool { return u.Scheme == "bzz-hash" } @@ -119,3 +118,14 @@ func (u *URI) Hash() bool { func (u *URI) String() string { return u.Scheme + ":/" + u.Addr + "/" + u.Path } + +func (u *URI) Address() storage.Address { + if u.addr != nil { + return u.addr + } + if hashMatcher.MatchString(u.Addr) { + u.addr = common.Hex2Bytes(u.Addr) + return u.addr + } + return nil +} diff --git a/swarm/api/uri_test.go b/swarm/api/uri_test.go index 137b4505d4..ea649e273c 100644 --- a/swarm/api/uri_test.go +++ b/swarm/api/uri_test.go @@ -17,8 +17,11 @@ package api import ( + "bytes" "reflect" "testing" + + "github.com/ethereum/go-ethereum/swarm/storage" ) func TestParseURI(t *testing.T) { @@ -32,6 +35,8 @@ func TestParseURI(t *testing.T) { expectHash bool expectDeprecatedRaw bool expectDeprecatedImmutable bool + expectValidKey bool + expectAddr storage.Address } tests := []test{ { @@ -120,24 +125,17 @@ func TestParseURI(t *testing.T) { expectList: true, }, { - uri: "bzzr:", - expectURI: &URI{Scheme: "bzzr"}, - expectDeprecatedRaw: true, - }, - { - uri: "bzzr:/", - expectURI: &URI{Scheme: "bzzr"}, - expectDeprecatedRaw: true, - }, - { - uri: "bzzi:", - expectURI: &URI{Scheme: "bzzi"}, - expectDeprecatedImmutable: true, - }, - { - uri: "bzzi:/", - expectURI: &URI{Scheme: "bzzi"}, - expectDeprecatedImmutable: true, + uri: "bzz-raw://4378d19c26590f1a818ed7d6a62c3809e149b0999cab5ce5f26233b3b423bf8c", + expectURI: &URI{Scheme: "bzz-raw", + Addr: "4378d19c26590f1a818ed7d6a62c3809e149b0999cab5ce5f26233b3b423bf8c", + }, + expectValidKey: true, + expectRaw: true, + expectAddr: storage.Address{67, 120, 209, 156, 38, 89, 15, 26, + 129, 142, 215, 214, 166, 44, 56, 9, + 225, 73, 176, 153, 156, 171, 92, 229, + 242, 98, 51, 179, 180, 35, 191, 140, + }, }, } for _, x := range tests { @@ -166,11 +164,14 @@ func TestParseURI(t *testing.T) { if actual.Hash() != x.expectHash { t.Fatalf("expected %s hash to be %t, got %t", x.uri, x.expectHash, actual.Hash()) } - if actual.DeprecatedRaw() != x.expectDeprecatedRaw { - t.Fatalf("expected %s deprecated raw to be %t, got %t", x.uri, x.expectDeprecatedRaw, actual.DeprecatedRaw()) - } - if actual.DeprecatedImmutable() != x.expectDeprecatedImmutable { - t.Fatalf("expected %s deprecated immutable to be %t, got %t", x.uri, x.expectDeprecatedImmutable, actual.DeprecatedImmutable()) + if x.expectValidKey { + if actual.Address() == nil { + t.Fatalf("expected %s to return a valid key, got nil", x.uri) + } else { + if !bytes.Equal(x.expectAddr, actual.Address()) { + t.Fatalf("expected %s to be decoded to %v", x.expectURI.Addr, x.expectAddr) + } + } } } } diff --git a/swarm/bmt/bmt.go b/swarm/bmt/bmt.go new file mode 100644 index 0000000000..1a141047ae --- /dev/null +++ b/swarm/bmt/bmt.go @@ -0,0 +1,693 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +// Package bmt provides a binary merkle tree implementation used for swarm chunk hash +package bmt + +import ( + "fmt" + "hash" + "strings" + "sync" + "sync/atomic" +) + +/* +Binary Merkle Tree Hash is a hash function over arbitrary datachunks of limited size. +It is defined as the root hash of the binary merkle tree built over fixed size segments +of the underlying chunk using any base hash function (e.g., keccak 256 SHA3). +Chunks with data shorter than the fixed size are hashed as if they had zero padding. + +BMT hash is used as the chunk hash function in swarm which in turn is the basis for the +128 branching swarm hash http://swarm-guide.readthedocs.io/en/latest/architecture.html#swarm-hash + +The BMT is optimal for providing compact inclusion proofs, i.e. prove that a +segment is a substring of a chunk starting at a particular offset. +The size of the underlying segments is fixed to the size of the base hash (called the resolution +of the BMT hash), Using Keccak256 SHA3 hash is 32 bytes, the EVM word size to optimize for on-chain BMT verification +as well as the hash size optimal for inclusion proofs in the merkle tree of the swarm hash. + +Two implementations are provided: + +* RefHasher is optimized for code simplicity and meant as a reference implementation + that is simple to understand +* Hasher is optimized for speed taking advantage of concurrency with minimalistic + control structure to coordinate the concurrent routines + + BMT Hasher implements the following interfaces + * standard golang hash.Hash - synchronous, reusable + * SwarmHash - SumWithSpan provided + * io.Writer - synchronous left-to-right datawriter + * AsyncWriter - concurrent section writes and asynchronous Sum call +*/ + +const ( + // SegmentCount is the maximum number of segments of the underlying chunk + // Should be equal to max-chunk-data-size / hash-size + SegmentCount = 128 + // PoolSize is the maximum number of bmt trees used by the hashers, i.e, + // the maximum number of concurrent BMT hashing operations performed by the same hasher + PoolSize = 8 +) + +// BaseHasherFunc is a hash.Hash constructor function used for the base hash of the BMT. +// implemented by Keccak256 SHA3 sha3.NewKeccak256 +type BaseHasherFunc func() hash.Hash + +// Hasher a reusable hasher for fixed maximum size chunks representing a BMT +// - implements the hash.Hash interface +// - reuses a pool of trees for amortised memory allocation and resource control +// - supports order-agnostic concurrent segment writes and section (double segment) writes +// as well as sequential read and write +// - the same hasher instance must not be called concurrently on more than one chunk +// - the same hasher instance is synchronously reuseable +// - Sum gives back the tree to the pool and guaranteed to leave +// the tree and itself in a state reusable for hashing a new chunk +// - generates and verifies segment inclusion proofs (TODO:) +type Hasher struct { + pool *TreePool // BMT resource pool + bmt *tree // prebuilt BMT resource for flowcontrol and proofs +} + +// New creates a reusable BMT Hasher that +// pulls a new tree from a resource pool for hashing each chunk +func New(p *TreePool) *Hasher { + return &Hasher{ + pool: p, + } +} + +// TreePool provides a pool of trees used as resources by the BMT Hasher. +// A tree popped from the pool is guaranteed to have a clean state ready +// for hashing a new chunk. +type TreePool struct { + lock sync.Mutex + c chan *tree // the channel to obtain a resource from the pool + hasher BaseHasherFunc // base hasher to use for the BMT levels + SegmentSize int // size of leaf segments, stipulated to be = hash size + SegmentCount int // the number of segments on the base level of the BMT + Capacity int // pool capacity, controls concurrency + Depth int // depth of the bmt trees = int(log2(segmentCount))+1 + Size int // the total length of the data (count * size) + count int // current count of (ever) allocated resources + zerohashes [][]byte // lookup table for predictable padding subtrees for all levels +} + +// NewTreePool creates a tree pool with hasher, segment size, segment count and capacity +// on Hasher.getTree it reuses free trees or creates a new one if capacity is not reached +func NewTreePool(hasher BaseHasherFunc, segmentCount, capacity int) *TreePool { + // initialises the zerohashes lookup table + depth := calculateDepthFor(segmentCount) + segmentSize := hasher().Size() + zerohashes := make([][]byte, depth+1) + zeros := make([]byte, segmentSize) + zerohashes[0] = zeros + h := hasher() + for i := 1; i < depth+1; i++ { + zeros = doSum(h, nil, zeros, zeros) + zerohashes[i] = zeros + } + return &TreePool{ + c: make(chan *tree, capacity), + hasher: hasher, + SegmentSize: segmentSize, + SegmentCount: segmentCount, + Capacity: capacity, + Size: segmentCount * segmentSize, + Depth: depth, + zerohashes: zerohashes, + } +} + +// Drain drains the pool until it has no more than n resources +func (p *TreePool) Drain(n int) { + p.lock.Lock() + defer p.lock.Unlock() + for len(p.c) > n { + <-p.c + p.count-- + } +} + +// Reserve is blocking until it returns an available tree +// it reuses free trees or creates a new one if size is not reached +// TODO: should use a context here +func (p *TreePool) reserve() *tree { + p.lock.Lock() + defer p.lock.Unlock() + var t *tree + if p.count == p.Capacity { + return <-p.c + } + select { + case t = <-p.c: + default: + t = newTree(p.SegmentSize, p.Depth, p.hasher) + p.count++ + } + return t +} + +// release gives back a tree to the pool. +// this tree is guaranteed to be in reusable state +func (p *TreePool) release(t *tree) { + p.c <- t // can never fail ... +} + +// tree is a reusable control structure representing a BMT +// organised in a binary tree +// Hasher uses a TreePool to obtain a tree for each chunk hash +// the tree is 'locked' while not in the pool +type tree struct { + leaves []*node // leaf nodes of the tree, other nodes accessible via parent links + cursor int // index of rightmost currently open segment + offset int // offset (cursor position) within currently open segment + section []byte // the rightmost open section (double segment) + result chan []byte // result channel + span []byte // The span of the data subsumed under the chunk +} + +// node is a reuseable segment hasher representing a node in a BMT +type node struct { + isLeft bool // whether it is left side of the parent double segment + parent *node // pointer to parent node in the BMT + state int32 // atomic increment impl concurrent boolean toggle + left, right []byte // this is where the two children sections are written + hasher hash.Hash // preconstructed hasher on nodes +} + +// newNode constructs a segment hasher node in the BMT (used by newTree) +func newNode(index int, parent *node, hasher hash.Hash) *node { + return &node{ + parent: parent, + isLeft: index%2 == 0, + hasher: hasher, + } +} + +// Draw draws the BMT (badly) +func (t *tree) draw(hash []byte) string { + var left, right []string + var anc []*node + for i, n := range t.leaves { + left = append(left, fmt.Sprintf("%v", hashstr(n.left))) + if i%2 == 0 { + anc = append(anc, n.parent) + } + right = append(right, fmt.Sprintf("%v", hashstr(n.right))) + } + anc = t.leaves + var hashes [][]string + for l := 0; len(anc) > 0; l++ { + var nodes []*node + hash := []string{""} + for i, n := range anc { + hash = append(hash, fmt.Sprintf("%v|%v", hashstr(n.left), hashstr(n.right))) + if i%2 == 0 && n.parent != nil { + nodes = append(nodes, n.parent) + } + } + hash = append(hash, "") + hashes = append(hashes, hash) + anc = nodes + } + hashes = append(hashes, []string{"", fmt.Sprintf("%v", hashstr(hash)), ""}) + total := 60 + del := " " + var rows []string + for i := len(hashes) - 1; i >= 0; i-- { + var textlen int + hash := hashes[i] + for _, s := range hash { + textlen += len(s) + } + if total < textlen { + total = textlen + len(hash) + } + delsize := (total - textlen) / (len(hash) - 1) + if delsize > len(del) { + delsize = len(del) + } + row := fmt.Sprintf("%v: %v", len(hashes)-i-1, strings.Join(hash, del[:delsize])) + rows = append(rows, row) + + } + rows = append(rows, strings.Join(left, " ")) + rows = append(rows, strings.Join(right, " ")) + return strings.Join(rows, "\n") + "\n" +} + +// newTree initialises a tree by building up the nodes of a BMT +// - segment size is stipulated to be the size of the hash +func newTree(segmentSize, depth int, hashfunc func() hash.Hash) *tree { + n := newNode(0, nil, hashfunc()) + prevlevel := []*node{n} + // iterate over levels and creates 2^(depth-level) nodes + // the 0 level is on double segment sections so we start at depth - 2 since + count := 2 + for level := depth - 2; level >= 0; level-- { + nodes := make([]*node, count) + for i := 0; i < count; i++ { + parent := prevlevel[i/2] + var hasher hash.Hash + if level == 0 { + hasher = hashfunc() + } + nodes[i] = newNode(i, parent, hasher) + } + prevlevel = nodes + count *= 2 + } + // the datanode level is the nodes on the last level + return &tree{ + leaves: prevlevel, + result: make(chan []byte), + section: make([]byte, 2*segmentSize), + } +} + +// methods needed to implement hash.Hash + +// Size returns the size +func (h *Hasher) Size() int { + return h.pool.SegmentSize +} + +// BlockSize returns the block size +func (h *Hasher) BlockSize() int { + return 2 * h.pool.SegmentSize +} + +// Sum returns the BMT root hash of the buffer +// using Sum presupposes sequential synchronous writes (io.Writer interface) +// hash.Hash interface Sum method appends the byte slice to the underlying +// data before it calculates and returns the hash of the chunk +// caller must make sure Sum is not called concurrently with Write, writeSection +func (h *Hasher) Sum(b []byte) (s []byte) { + t := h.getTree() + // write the last section with final flag set to true + go h.writeSection(t.cursor, t.section, true, true) + // wait for the result + s = <-t.result + span := t.span + // release the tree resource back to the pool + h.releaseTree() + // b + sha3(span + BMT(pure_chunk)) + if len(span) == 0 { + return append(b, s...) + } + return doSum(h.pool.hasher(), b, span, s) +} + +// methods needed to implement the SwarmHash and the io.Writer interfaces + +// Write calls sequentially add to the buffer to be hashed, +// with every full segment calls writeSection in a go routine +func (h *Hasher) Write(b []byte) (int, error) { + l := len(b) + if l == 0 { + return 0, nil + } + t := h.getTree() + secsize := 2 * h.pool.SegmentSize + // calculate length of missing bit to complete current open section + smax := secsize - t.offset + // if at the beginning of chunk or middle of the section + if t.offset < secsize { + // fill up current segment from buffer + copy(t.section[t.offset:], b) + // if input buffer consumed and open section not complete, then + // advance offset and return + if smax == 0 { + smax = secsize + } + if l <= smax { + t.offset += l + return l, nil + } + } else { + // if end of a section + if t.cursor == h.pool.SegmentCount*2 { + return 0, nil + } + } + // read full sections and the last possibly partial section from the input buffer + for smax < l { + // section complete; push to tree asynchronously + go h.writeSection(t.cursor, t.section, true, false) + // reset section + t.section = make([]byte, secsize) + // copy from input buffer at smax to right half of section + copy(t.section, b[smax:]) + // advance cursor + t.cursor++ + // smax here represents successive offsets in the input buffer + smax += secsize + } + t.offset = l - smax + secsize + return l, nil +} + +// Reset needs to be called before writing to the hasher +func (h *Hasher) Reset() { + h.releaseTree() +} + +// methods needed to implement the SwarmHash interface + +// ResetWithLength needs to be called before writing to the hasher +// the argument is supposed to be the byte slice binary representation of +// the length of the data subsumed under the hash, i.e., span +func (h *Hasher) ResetWithLength(span []byte) { + h.Reset() + h.getTree().span = span +} + +// releaseTree gives back the Tree to the pool whereby it unlocks +// it resets tree, segment and index +func (h *Hasher) releaseTree() { + t := h.bmt + if t == nil { + return + } + h.bmt = nil + go func() { + t.cursor = 0 + t.offset = 0 + t.span = nil + t.section = make([]byte, h.pool.SegmentSize*2) + select { + case <-t.result: + default: + } + h.pool.release(t) + }() +} + +// NewAsyncWriter extends Hasher with an interface for concurrent segment/section writes +func (h *Hasher) NewAsyncWriter(double bool) *AsyncHasher { + secsize := h.pool.SegmentSize + if double { + secsize *= 2 + } + write := func(i int, section []byte, final bool) { + h.writeSection(i, section, double, final) + } + return &AsyncHasher{ + Hasher: h, + double: double, + secsize: secsize, + write: write, + } +} + +// SectionWriter is an asynchronous segment/section writer interface +type SectionWriter interface { + Reset() // standard init to be called before reuse + Write(index int, data []byte) // write into section of index + Sum(b []byte, length int, span []byte) []byte // returns the hash of the buffer + SectionSize() int // size of the async section unit to use +} + +// AsyncHasher extends BMT Hasher with an asynchronous segment/section writer interface +// AsyncHasher is unsafe and does not check indexes and section data lengths +// it must be used with the right indexes and length and the right number of sections +// +// behaviour is undefined if +// * non-final sections are shorter or longer than secsize +// * if final section does not match length +// * write a section with index that is higher than length/secsize +// * set length in Sum call when length/secsize < maxsec +// +// * if Sum() is not called on a Hasher that is fully written +// a process will block, can be terminated with Reset +// * it will not leak processes if not all sections are written but it blocks +// and keeps the resource which can be released calling Reset() +type AsyncHasher struct { + *Hasher // extends the Hasher + mtx sync.Mutex // to lock the cursor access + double bool // whether to use double segments (call Hasher.writeSection) + secsize int // size of base section (size of hash or double) + write func(i int, section []byte, final bool) +} + +// methods needed to implement AsyncWriter + +// SectionSize returns the size of async section unit to use +func (sw *AsyncHasher) SectionSize() int { + return sw.secsize +} + +// Write writes the i-th section of the BMT base +// this function can and is meant to be called concurrently +// it sets max segment threadsafely +func (sw *AsyncHasher) Write(i int, section []byte) { + sw.mtx.Lock() + defer sw.mtx.Unlock() + t := sw.getTree() + // cursor keeps track of the rightmost section written so far + // if index is lower than cursor then just write non-final section as is + if i < t.cursor { + // if index is not the rightmost, safe to write section + go sw.write(i, section, false) + return + } + // if there is a previous rightmost section safe to write section + if t.offset > 0 { + if i == t.cursor { + // i==cursor implies cursor was set by Hash call so we can write section as final one + // since it can be shorter, first we copy it to the padded buffer + t.section = make([]byte, sw.secsize) + copy(t.section, section) + go sw.write(i, t.section, true) + return + } + // the rightmost section just changed, so we write the previous one as non-final + go sw.write(t.cursor, t.section, false) + } + // set i as the index of the righmost section written so far + // set t.offset to cursor*secsize+1 + t.cursor = i + t.offset = i*sw.secsize + 1 + t.section = make([]byte, sw.secsize) + copy(t.section, section) +} + +// Sum can be called any time once the length and the span is known +// potentially even before all segments have been written +// in such cases Sum will block until all segments are present and +// the hash for the length can be calculated. +// +// b: digest is appended to b +// length: known length of the input (unsafe; undefined if out of range) +// meta: metadata to hash together with BMT root for the final digest +// e.g., span for protection against existential forgery +func (sw *AsyncHasher) Sum(b []byte, length int, meta []byte) (s []byte) { + sw.mtx.Lock() + t := sw.getTree() + if length == 0 { + sw.mtx.Unlock() + s = sw.pool.zerohashes[sw.pool.Depth] + } else { + // for non-zero input the rightmost section is written to the tree asynchronously + // if the actual last section has been written (t.cursor == length/t.secsize) + maxsec := (length - 1) / sw.secsize + if t.offset > 0 { + go sw.write(t.cursor, t.section, maxsec == t.cursor) + } + // set cursor to maxsec so final section is written when it arrives + t.cursor = maxsec + t.offset = length + result := t.result + sw.mtx.Unlock() + // wait for the result or reset + s = <-result + } + // relesase the tree back to the pool + sw.releaseTree() + // if no meta is given just append digest to b + if len(meta) == 0 { + return append(b, s...) + } + // hash together meta and BMT root hash using the pools + return doSum(sw.pool.hasher(), b, meta, s) +} + +// writeSection writes the hash of i-th section into level 1 node of the BMT tree +func (h *Hasher) writeSection(i int, section []byte, double bool, final bool) { + // select the leaf node for the section + var n *node + var isLeft bool + var hasher hash.Hash + var level int + t := h.getTree() + if double { + level++ + n = t.leaves[i] + hasher = n.hasher + isLeft = n.isLeft + n = n.parent + // hash the section + section = doSum(hasher, nil, section) + } else { + n = t.leaves[i/2] + hasher = n.hasher + isLeft = i%2 == 0 + } + // write hash into parent node + if final { + // for the last segment use writeFinalNode + h.writeFinalNode(level, n, hasher, isLeft, section) + } else { + h.writeNode(n, hasher, isLeft, section) + } +} + +// writeNode pushes the data to the node +// if it is the first of 2 sisters written, the routine terminates +// if it is the second, it calculates the hash and writes it +// to the parent node recursively +// since hashing the parent is synchronous the same hasher can be used +func (h *Hasher) writeNode(n *node, bh hash.Hash, isLeft bool, s []byte) { + level := 1 + for { + // at the root of the bmt just write the result to the result channel + if n == nil { + h.getTree().result <- s + return + } + // otherwise assign child hash to left or right segment + if isLeft { + n.left = s + } else { + n.right = s + } + // the child-thread first arriving will terminate + if n.toggle() { + return + } + // the thread coming second now can be sure both left and right children are written + // so it calculates the hash of left|right and pushes it to the parent + s = doSum(bh, nil, n.left, n.right) + isLeft = n.isLeft + n = n.parent + level++ + } +} + +// writeFinalNode is following the path starting from the final datasegment to the +// BMT root via parents +// for unbalanced trees it fills in the missing right sister nodes using +// the pool's lookup table for BMT subtree root hashes for all-zero sections +// otherwise behaves like `writeNode` +func (h *Hasher) writeFinalNode(level int, n *node, bh hash.Hash, isLeft bool, s []byte) { + + for { + // at the root of the bmt just write the result to the result channel + if n == nil { + if s != nil { + h.getTree().result <- s + } + return + } + var noHash bool + if isLeft { + // coming from left sister branch + // when the final section's path is going via left child node + // we include an all-zero subtree hash for the right level and toggle the node. + n.right = h.pool.zerohashes[level] + if s != nil { + n.left = s + // if a left final node carries a hash, it must be the first (and only thread) + // so the toggle is already in passive state no need no call + // yet thread needs to carry on pushing hash to parent + noHash = false + } else { + // if again first thread then propagate nil and calculate no hash + noHash = n.toggle() + } + } else { + // right sister branch + if s != nil { + // if hash was pushed from right child node, write right segment change state + n.right = s + // if toggle is true, we arrived first so no hashing just push nil to parent + noHash = n.toggle() + + } else { + // if s is nil, then thread arrived first at previous node and here there will be two, + // so no need to do anything and keep s = nil for parent + noHash = true + } + } + // the child-thread first arriving will just continue resetting s to nil + // the second thread now can be sure both left and right children are written + // it calculates the hash of left|right and pushes it to the parent + if noHash { + s = nil + } else { + s = doSum(bh, nil, n.left, n.right) + } + // iterate to parent + isLeft = n.isLeft + n = n.parent + level++ + } +} + +// getTree obtains a BMT resource by reserving one from the pool and assigns it to the bmt field +func (h *Hasher) getTree() *tree { + if h.bmt != nil { + return h.bmt + } + t := h.pool.reserve() + h.bmt = t + return t +} + +// atomic bool toggle implementing a concurrent reusable 2-state object +// atomic addint with %2 implements atomic bool toggle +// it returns true if the toggler just put it in the active/waiting state +func (n *node) toggle() bool { + return atomic.AddInt32(&n.state, 1)%2 == 1 +} + +// calculates the hash of the data using hash.Hash +func doSum(h hash.Hash, b []byte, data ...[]byte) []byte { + h.Reset() + for _, v := range data { + h.Write(v) + } + return h.Sum(b) +} + +// hashstr is a pretty printer for bytes used in tree.draw +func hashstr(b []byte) string { + end := len(b) + if end > 4 { + end = 4 + } + return fmt.Sprintf("%x", b[:end]) +} + +// calculateDepthFor calculates the depth (number of levels) in the BMT tree +func calculateDepthFor(n int) (d int) { + c := 2 + for ; c < n; c *= 2 { + d++ + } + return d + 1 +} diff --git a/swarm/bmt/bmt_r.go b/swarm/bmt/bmt_r.go new file mode 100644 index 0000000000..0cb6c146f5 --- /dev/null +++ b/swarm/bmt/bmt_r.go @@ -0,0 +1,84 @@ +// 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 bmt is a simple nonconcurrent reference implementation for hashsize segment based +// Binary Merkle tree hash on arbitrary but fixed maximum chunksize +// +// This implementation does not take advantage of any paralellisms and uses +// far more memory than necessary, but it is easy to see that it is correct. +// It can be used for generating test cases for optimized implementations. +// There is extra check on reference hasher correctness in bmt_test.go +// * TestRefHasher +// * testBMTHasherCorrectness function +package bmt + +import ( + "hash" +) + +// RefHasher is the non-optimized easy-to-read reference implementation of BMT +type RefHasher struct { + maxDataLength int // c * hashSize, where c = 2 ^ ceil(log2(count)), where count = ceil(length / hashSize) + sectionLength int // 2 * hashSize + hasher hash.Hash // base hash func (Keccak256 SHA3) +} + +// NewRefHasher returns a new RefHasher +func NewRefHasher(hasher BaseHasherFunc, count int) *RefHasher { + h := hasher() + hashsize := h.Size() + c := 2 + for ; c < count; c *= 2 { + } + return &RefHasher{ + sectionLength: 2 * hashsize, + maxDataLength: c * hashsize, + hasher: h, + } +} + +// Hash returns the BMT hash of the byte slice +// implements the SwarmHash interface +func (rh *RefHasher) Hash(data []byte) []byte { + // if data is shorter than the base length (maxDataLength), we provide padding with zeros + d := make([]byte, rh.maxDataLength) + length := len(data) + if length > rh.maxDataLength { + length = rh.maxDataLength + } + copy(d, data[:length]) + return rh.hash(d, rh.maxDataLength) +} + +// data has length maxDataLength = segmentSize * 2^k +// hash calls itself recursively on both halves of the given slice +// concatenates the results, and returns the hash of that +// if the length of d is 2 * segmentSize then just returns the hash of that section +func (rh *RefHasher) hash(data []byte, length int) []byte { + var section []byte + if length == rh.sectionLength { + // section contains two data segments (d) + section = data + } else { + // section contains hashes of left and right BMT subtreea + // to be calculated by calling hash recursively on left and right half of d + length /= 2 + section = append(rh.hash(data[:length], length), rh.hash(data[length:], length)...) + } + rh.hasher.Reset() + rh.hasher.Write(section) + return rh.hasher.Sum(nil) +} diff --git a/swarm/bmt/bmt_test.go b/swarm/bmt/bmt_test.go new file mode 100644 index 0000000000..891d8cbb29 --- /dev/null +++ b/swarm/bmt/bmt_test.go @@ -0,0 +1,615 @@ +// 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 bmt + +import ( + "bytes" + crand "crypto/rand" + "encoding/binary" + "fmt" + "io" + "math/rand" + "sync" + "sync/atomic" + "testing" + "time" + + "github.com/ethereum/go-ethereum/crypto/sha3" +) + +// the actual data length generated (could be longer than max datalength of the BMT) +const BufferSize = 4128 + +var counts = []int{1, 2, 3, 4, 5, 8, 9, 15, 16, 17, 32, 37, 42, 53, 63, 64, 65, 111, 127, 128} + +// calculates the Keccak256 SHA3 hash of the data +func sha3hash(data ...[]byte) []byte { + h := sha3.NewKeccak256() + return doSum(h, nil, data...) +} + +// TestRefHasher tests that the RefHasher computes the expected BMT hash for +// some small data lengths +func TestRefHasher(t *testing.T) { + // the test struct is used to specify the expected BMT hash for + // segment counts between from and to and lengths from 1 to datalength + type test struct { + from int + to int + expected func([]byte) []byte + } + + var tests []*test + // all lengths in [0,64] should be: + // + // sha3hash(data) + // + tests = append(tests, &test{ + from: 1, + to: 2, + expected: func(d []byte) []byte { + data := make([]byte, 64) + copy(data, d) + return sha3hash(data) + }, + }) + + // all lengths in [3,4] should be: + // + // sha3hash( + // sha3hash(data[:64]) + // sha3hash(data[64:]) + // ) + // + tests = append(tests, &test{ + from: 3, + to: 4, + expected: func(d []byte) []byte { + data := make([]byte, 128) + copy(data, d) + return sha3hash(sha3hash(data[:64]), sha3hash(data[64:])) + }, + }) + + // all segmentCounts in [5,8] should be: + // + // sha3hash( + // sha3hash( + // sha3hash(data[:64]) + // sha3hash(data[64:128]) + // ) + // sha3hash( + // sha3hash(data[128:192]) + // sha3hash(data[192:]) + // ) + // ) + // + tests = append(tests, &test{ + from: 5, + to: 8, + expected: func(d []byte) []byte { + data := make([]byte, 256) + copy(data, d) + return sha3hash(sha3hash(sha3hash(data[:64]), sha3hash(data[64:128])), sha3hash(sha3hash(data[128:192]), sha3hash(data[192:]))) + }, + }) + + // run the tests + for _, x := range tests { + for segmentCount := x.from; segmentCount <= x.to; segmentCount++ { + for length := 1; length <= segmentCount*32; length++ { + t.Run(fmt.Sprintf("%d_segments_%d_bytes", segmentCount, length), func(t *testing.T) { + data := make([]byte, length) + if _, err := io.ReadFull(crand.Reader, data); err != nil && err != io.EOF { + t.Fatal(err) + } + expected := x.expected(data) + actual := NewRefHasher(sha3.NewKeccak256, segmentCount).Hash(data) + if !bytes.Equal(actual, expected) { + t.Fatalf("expected %x, got %x", expected, actual) + } + }) + } + } + } +} + +// tests if hasher responds with correct hash comparing the reference implementation return value +func TestHasherEmptyData(t *testing.T) { + hasher := sha3.NewKeccak256 + var data []byte + for _, count := range counts { + t.Run(fmt.Sprintf("%d_segments", count), func(t *testing.T) { + pool := NewTreePool(hasher, count, PoolSize) + defer pool.Drain(0) + bmt := New(pool) + rbmt := NewRefHasher(hasher, count) + refHash := rbmt.Hash(data) + expHash := syncHash(bmt, nil, data) + if !bytes.Equal(expHash, refHash) { + t.Fatalf("hash mismatch with reference. expected %x, got %x", refHash, expHash) + } + }) + } +} + +// tests sequential write with entire max size written in one go +func TestSyncHasherCorrectness(t *testing.T) { + data := newData(BufferSize) + hasher := sha3.NewKeccak256 + size := hasher().Size() + + var err error + for _, count := range counts { + t.Run(fmt.Sprintf("segments_%v", count), func(t *testing.T) { + max := count * size + var incr int + capacity := 1 + pool := NewTreePool(hasher, count, capacity) + defer pool.Drain(0) + for n := 0; n <= max; n += incr { + incr = 1 + rand.Intn(5) + bmt := New(pool) + err = testHasherCorrectness(bmt, hasher, data, n, count) + if err != nil { + t.Fatal(err) + } + } + }) + } +} + +// tests order-neutral concurrent writes with entire max size written in one go +func TestAsyncCorrectness(t *testing.T) { + data := newData(BufferSize) + hasher := sha3.NewKeccak256 + size := hasher().Size() + whs := []whenHash{first, last, random} + + for _, double := range []bool{false, true} { + for _, wh := range whs { + for _, count := range counts { + t.Run(fmt.Sprintf("double_%v_hash_when_%v_segments_%v", double, wh, count), func(t *testing.T) { + max := count * size + var incr int + capacity := 1 + pool := NewTreePool(hasher, count, capacity) + defer pool.Drain(0) + for n := 1; n <= max; n += incr { + incr = 1 + rand.Intn(5) + bmt := New(pool) + d := data[:n] + rbmt := NewRefHasher(hasher, count) + exp := rbmt.Hash(d) + got := syncHash(bmt, nil, d) + if !bytes.Equal(got, exp) { + t.Fatalf("wrong sync hash for datalength %v: expected %x (ref), got %x", n, exp, got) + } + sw := bmt.NewAsyncWriter(double) + got = asyncHashRandom(sw, nil, d, wh) + if !bytes.Equal(got, exp) { + t.Fatalf("wrong async hash for datalength %v: expected %x, got %x", n, exp, got) + } + } + }) + } + } + } +} + +// Tests that the BMT hasher can be synchronously reused with poolsizes 1 and PoolSize +func TestHasherReuse(t *testing.T) { + t.Run(fmt.Sprintf("poolsize_%d", 1), func(t *testing.T) { + testHasherReuse(1, t) + }) + t.Run(fmt.Sprintf("poolsize_%d", PoolSize), func(t *testing.T) { + testHasherReuse(PoolSize, t) + }) +} + +// tests if bmt reuse is not corrupting result +func testHasherReuse(poolsize int, t *testing.T) { + hasher := sha3.NewKeccak256 + pool := NewTreePool(hasher, SegmentCount, poolsize) + defer pool.Drain(0) + bmt := New(pool) + + for i := 0; i < 100; i++ { + data := newData(BufferSize) + n := rand.Intn(bmt.Size()) + err := testHasherCorrectness(bmt, hasher, data, n, SegmentCount) + if err != nil { + t.Fatal(err) + } + } +} + +// Tests if pool can be cleanly reused even in concurrent use by several hasher +func TestBMTConcurrentUse(t *testing.T) { + hasher := sha3.NewKeccak256 + pool := NewTreePool(hasher, SegmentCount, PoolSize) + defer pool.Drain(0) + cycles := 100 + errc := make(chan error) + + for i := 0; i < cycles; i++ { + go func() { + bmt := New(pool) + data := newData(BufferSize) + n := rand.Intn(bmt.Size()) + errc <- testHasherCorrectness(bmt, hasher, data, n, 128) + }() + } +LOOP: + for { + select { + case <-time.NewTimer(5 * time.Second).C: + t.Fatal("timed out") + case err := <-errc: + if err != nil { + t.Fatal(err) + } + cycles-- + if cycles == 0 { + break LOOP + } + } + } +} + +// Tests BMT Hasher io.Writer interface is working correctly +// even multiple short random write buffers +func TestBMTWriterBuffers(t *testing.T) { + hasher := sha3.NewKeccak256 + + for _, count := range counts { + t.Run(fmt.Sprintf("%d_segments", count), func(t *testing.T) { + errc := make(chan error) + pool := NewTreePool(hasher, count, PoolSize) + defer pool.Drain(0) + n := count * 32 + bmt := New(pool) + data := newData(n) + rbmt := NewRefHasher(hasher, count) + refHash := rbmt.Hash(data) + expHash := syncHash(bmt, nil, data) + if !bytes.Equal(expHash, refHash) { + t.Fatalf("hash mismatch with reference. expected %x, got %x", refHash, expHash) + } + attempts := 10 + f := func() error { + bmt := New(pool) + bmt.Reset() + var buflen int + for offset := 0; offset < n; offset += buflen { + buflen = rand.Intn(n-offset) + 1 + read, err := bmt.Write(data[offset : offset+buflen]) + if err != nil { + return err + } + if read != buflen { + return fmt.Errorf("incorrect read. expected %v bytes, got %v", buflen, read) + } + } + hash := bmt.Sum(nil) + if !bytes.Equal(hash, expHash) { + return fmt.Errorf("hash mismatch. expected %x, got %x", hash, expHash) + } + return nil + } + + for j := 0; j < attempts; j++ { + go func() { + errc <- f() + }() + } + timeout := time.NewTimer(2 * time.Second) + for { + select { + case err := <-errc: + if err != nil { + t.Fatal(err) + } + attempts-- + if attempts == 0 { + return + } + case <-timeout.C: + t.Fatalf("timeout") + } + } + }) + } +} + +// helper function that compares reference and optimised implementations on +// correctness +func testHasherCorrectness(bmt *Hasher, hasher BaseHasherFunc, d []byte, n, count int) (err error) { + span := make([]byte, 8) + if len(d) < n { + n = len(d) + } + binary.BigEndian.PutUint64(span, uint64(n)) + data := d[:n] + rbmt := NewRefHasher(hasher, count) + exp := sha3hash(span, rbmt.Hash(data)) + got := syncHash(bmt, span, data) + if !bytes.Equal(got, exp) { + return fmt.Errorf("wrong hash: expected %x, got %x", exp, got) + } + return err +} + +// +func BenchmarkBMT(t *testing.B) { + for size := 4096; size >= 128; size /= 2 { + t.Run(fmt.Sprintf("%v_size_%v", "SHA3", size), func(t *testing.B) { + benchmarkSHA3(t, size) + }) + t.Run(fmt.Sprintf("%v_size_%v", "Baseline", size), func(t *testing.B) { + benchmarkBMTBaseline(t, size) + }) + t.Run(fmt.Sprintf("%v_size_%v", "REF", size), func(t *testing.B) { + benchmarkRefHasher(t, size) + }) + t.Run(fmt.Sprintf("%v_size_%v", "BMT", size), func(t *testing.B) { + benchmarkBMT(t, size) + }) + } +} + +type whenHash = int + +const ( + first whenHash = iota + last + random +) + +func BenchmarkBMTAsync(t *testing.B) { + whs := []whenHash{first, last, random} + for size := 4096; size >= 128; size /= 2 { + for _, wh := range whs { + for _, double := range []bool{false, true} { + t.Run(fmt.Sprintf("double_%v_hash_when_%v_size_%v", double, wh, size), func(t *testing.B) { + benchmarkBMTAsync(t, size, wh, double) + }) + } + } + } +} + +func BenchmarkPool(t *testing.B) { + caps := []int{1, PoolSize} + for size := 4096; size >= 128; size /= 2 { + for _, c := range caps { + t.Run(fmt.Sprintf("poolsize_%v_size_%v", c, size), func(t *testing.B) { + benchmarkPool(t, c, size) + }) + } + } +} + +// benchmarks simple sha3 hash on chunks +func benchmarkSHA3(t *testing.B, n int) { + data := newData(n) + hasher := sha3.NewKeccak256 + h := hasher() + + t.ReportAllocs() + t.ResetTimer() + for i := 0; i < t.N; i++ { + doSum(h, nil, data) + } +} + +// benchmarks the minimum hashing time for a balanced (for simplicity) BMT +// by doing count/segmentsize parallel hashings of 2*segmentsize bytes +// doing it on n PoolSize each reusing the base hasher +// the premise is that this is the minimum computation needed for a BMT +// therefore this serves as a theoretical optimum for concurrent implementations +func benchmarkBMTBaseline(t *testing.B, n int) { + hasher := sha3.NewKeccak256 + hashSize := hasher().Size() + data := newData(hashSize) + + t.ReportAllocs() + t.ResetTimer() + for i := 0; i < t.N; i++ { + count := int32((n-1)/hashSize + 1) + wg := sync.WaitGroup{} + wg.Add(PoolSize) + var i int32 + for j := 0; j < PoolSize; j++ { + go func() { + defer wg.Done() + h := hasher() + for atomic.AddInt32(&i, 1) < count { + doSum(h, nil, data) + } + }() + } + wg.Wait() + } +} + +// benchmarks BMT Hasher +func benchmarkBMT(t *testing.B, n int) { + data := newData(n) + hasher := sha3.NewKeccak256 + pool := NewTreePool(hasher, SegmentCount, PoolSize) + bmt := New(pool) + + t.ReportAllocs() + t.ResetTimer() + for i := 0; i < t.N; i++ { + syncHash(bmt, nil, data) + } +} + +// benchmarks BMT hasher with asynchronous concurrent segment/section writes +func benchmarkBMTAsync(t *testing.B, n int, wh whenHash, double bool) { + data := newData(n) + hasher := sha3.NewKeccak256 + pool := NewTreePool(hasher, SegmentCount, PoolSize) + bmt := New(pool).NewAsyncWriter(double) + idxs, segments := splitAndShuffle(bmt.SectionSize(), data) + shuffle(len(idxs), func(i int, j int) { + idxs[i], idxs[j] = idxs[j], idxs[i] + }) + + t.ReportAllocs() + t.ResetTimer() + for i := 0; i < t.N; i++ { + asyncHash(bmt, nil, n, wh, idxs, segments) + } +} + +// benchmarks 100 concurrent bmt hashes with pool capacity +func benchmarkPool(t *testing.B, poolsize, n int) { + data := newData(n) + hasher := sha3.NewKeccak256 + pool := NewTreePool(hasher, SegmentCount, poolsize) + cycles := 100 + + t.ReportAllocs() + t.ResetTimer() + wg := sync.WaitGroup{} + for i := 0; i < t.N; i++ { + wg.Add(cycles) + for j := 0; j < cycles; j++ { + go func() { + defer wg.Done() + bmt := New(pool) + syncHash(bmt, nil, data) + }() + } + wg.Wait() + } +} + +// benchmarks the reference hasher +func benchmarkRefHasher(t *testing.B, n int) { + data := newData(n) + hasher := sha3.NewKeccak256 + rbmt := NewRefHasher(hasher, 128) + + t.ReportAllocs() + t.ResetTimer() + for i := 0; i < t.N; i++ { + rbmt.Hash(data) + } +} + +func newData(bufferSize int) []byte { + data := make([]byte, bufferSize) + _, err := io.ReadFull(crand.Reader, data) + if err != nil { + panic(err.Error()) + } + return data +} + +// Hash hashes the data and the span using the bmt hasher +func syncHash(h *Hasher, span, data []byte) []byte { + h.ResetWithLength(span) + h.Write(data) + return h.Sum(nil) +} + +func splitAndShuffle(secsize int, data []byte) (idxs []int, segments [][]byte) { + l := len(data) + n := l / secsize + if l%secsize > 0 { + n++ + } + for i := 0; i < n; i++ { + idxs = append(idxs, i) + end := (i + 1) * secsize + if end > l { + end = l + } + section := data[i*secsize : end] + segments = append(segments, section) + } + shuffle(n, func(i int, j int) { + idxs[i], idxs[j] = idxs[j], idxs[i] + }) + return idxs, segments +} + +// splits the input data performs a random shuffle to mock async section writes +func asyncHashRandom(bmt SectionWriter, span []byte, data []byte, wh whenHash) (s []byte) { + idxs, segments := splitAndShuffle(bmt.SectionSize(), data) + return asyncHash(bmt, span, len(data), wh, idxs, segments) +} + +// mock for async section writes for BMT SectionWriter +// requires a permutation (a random shuffle) of list of all indexes of segments +// and writes them in order to the appropriate section +// the Sum function is called according to the wh parameter (first, last, random [relative to segment writes]) +func asyncHash(bmt SectionWriter, span []byte, l int, wh whenHash, idxs []int, segments [][]byte) (s []byte) { + bmt.Reset() + if l == 0 { + return bmt.Sum(nil, l, span) + } + c := make(chan []byte, 1) + hashf := func() { + c <- bmt.Sum(nil, l, span) + } + maxsize := len(idxs) + var r int + if wh == random { + r = rand.Intn(maxsize) + } + for i, idx := range idxs { + bmt.Write(idx, segments[idx]) + if (wh == first || wh == random) && i == r { + go hashf() + } + } + if wh == last { + return bmt.Sum(nil, l, span) + } + return <-c +} + +// this is also in swarm/network_test.go +// shuffle pseudo-randomizes the order of elements. +// n is the number of elements. Shuffle panics if n < 0. +// swap swaps the elements with indexes i and j. +func shuffle(n int, swap func(i, j int)) { + if n < 0 { + panic("invalid argument to Shuffle") + } + + // Fisher-Yates shuffle: https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle + // Shuffle really ought not be called with n that doesn't fit in 32 bits. + // Not only will it take a very long time, but with 2³¹! possible permutations, + // there's no way that any PRNG can have a big enough internal state to + // generate even a minuscule percentage of the possible permutations. + // Nevertheless, the right API signature accepts an int n, so handle it as best we can. + i := n - 1 + for ; i > 1<<31-1-1; i-- { + j := int(rand.Int63n(int64(i + 1))) + swap(i, j) + } + for ; i > 0; i-- { + j := int(rand.Int31n(int32(i + 1))) + swap(i, j) + } +} diff --git a/swarm/fuse/fuse_dir.go b/swarm/fuse/fuse_dir.go index 91b236ae8a..7f66451f10 100644 --- a/swarm/fuse/fuse_dir.go +++ b/swarm/fuse/fuse_dir.go @@ -19,12 +19,14 @@ package fuse import ( - "bazil.org/fuse" - "bazil.org/fuse/fs" - "golang.org/x/net/context" "os" "path/filepath" "sync" + + "bazil.org/fuse" + "bazil.org/fuse/fs" + "github.com/ethereum/go-ethereum/swarm/log" + "golang.org/x/net/context" ) var ( @@ -48,6 +50,7 @@ type SwarmDir struct { } func NewSwarmDir(fullpath string, minfo *MountInfo) *SwarmDir { + log.Debug("swarmfs", "NewSwarmDir", fullpath) newdir := &SwarmDir{ inode: NewInode(), name: filepath.Base(fullpath), @@ -61,6 +64,8 @@ func NewSwarmDir(fullpath string, minfo *MountInfo) *SwarmDir { } func (sd *SwarmDir) Attr(ctx context.Context, a *fuse.Attr) error { + sd.lock.RLock() + defer sd.lock.RUnlock() a.Inode = sd.inode a.Mode = os.ModeDir | 0700 a.Uid = uint32(os.Getuid()) @@ -69,7 +74,7 @@ func (sd *SwarmDir) Attr(ctx context.Context, a *fuse.Attr) error { } func (sd *SwarmDir) Lookup(ctx context.Context, req *fuse.LookupRequest, resp *fuse.LookupResponse) (fs.Node, error) { - + log.Debug("swarmfs", "Lookup", req.Name) for _, n := range sd.files { if n.name == req.Name { return n, nil @@ -84,6 +89,7 @@ func (sd *SwarmDir) Lookup(ctx context.Context, req *fuse.LookupRequest, resp *f } func (sd *SwarmDir) ReadDirAll(ctx context.Context) ([]fuse.Dirent, error) { + log.Debug("swarmfs ReadDirAll") var children []fuse.Dirent for _, file := range sd.files { children = append(children, fuse.Dirent{Inode: file.inode, Type: fuse.DT_File, Name: file.name}) @@ -95,6 +101,7 @@ func (sd *SwarmDir) ReadDirAll(ctx context.Context) ([]fuse.Dirent, error) { } func (sd *SwarmDir) Create(ctx context.Context, req *fuse.CreateRequest, resp *fuse.CreateResponse) (fs.Node, fs.Handle, error) { + log.Debug("swarmfs Create", "path", sd.path, "req.Name", req.Name) newFile := NewSwarmFile(sd.path, req.Name, sd.mountInfo) newFile.fileSize = 0 // 0 means, file is not in swarm yet and it is just created @@ -107,6 +114,7 @@ func (sd *SwarmDir) Create(ctx context.Context, req *fuse.CreateRequest, resp *f } func (sd *SwarmDir) Remove(ctx context.Context, req *fuse.RemoveRequest) error { + log.Debug("swarmfs Remove", "path", sd.path, "req.Name", req.Name) if req.Dir && sd.directories != nil { newDirs := []*SwarmDir{} @@ -143,13 +151,11 @@ func (sd *SwarmDir) Remove(ctx context.Context, req *fuse.RemoveRequest) error { } func (sd *SwarmDir) Mkdir(ctx context.Context, req *fuse.MkdirRequest) (fs.Node, error) { - - newDir := NewSwarmDir(req.Name, sd.mountInfo) - + log.Debug("swarmfs Mkdir", "path", sd.path, "req.Name", req.Name) + newDir := NewSwarmDir(filepath.Join(sd.path, req.Name), sd.mountInfo) sd.lock.Lock() defer sd.lock.Unlock() sd.directories = append(sd.directories, newDir) return newDir, nil - } diff --git a/swarm/fuse/fuse_file.go b/swarm/fuse/fuse_file.go index c94a0773f5..ca04f737e2 100644 --- a/swarm/fuse/fuse_file.go +++ b/swarm/fuse/fuse_file.go @@ -26,7 +26,7 @@ import ( "bazil.org/fuse" "bazil.org/fuse/fs" - "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/swarm/log" "github.com/ethereum/go-ethereum/swarm/storage" "golang.org/x/net/context" ) @@ -50,7 +50,7 @@ type SwarmFile struct { inode uint64 name string path string - key storage.Key + addr storage.Address fileSize int64 reader storage.LazySectionReader @@ -63,7 +63,7 @@ func NewSwarmFile(path, fname string, minfo *MountInfo) *SwarmFile { inode: NewInode(), name: fname, path: path, - key: nil, + addr: nil, fileSize: -1, // -1 means , file already exists in swarm and you need to just get the size from swarm reader: nil, @@ -73,33 +73,38 @@ func NewSwarmFile(path, fname string, minfo *MountInfo) *SwarmFile { return newFile } -func (file *SwarmFile) Attr(ctx context.Context, a *fuse.Attr) error { - - a.Inode = file.inode +func (sf *SwarmFile) Attr(ctx context.Context, a *fuse.Attr) error { + log.Debug("swarmfs Attr", "path", sf.path) + sf.lock.Lock() + defer sf.lock.Unlock() + a.Inode = sf.inode //TODO: need to get permission as argument a.Mode = 0700 a.Uid = uint32(os.Getuid()) a.Gid = uint32(os.Getegid()) - if file.fileSize == -1 { - reader := file.mountInfo.swarmApi.Retrieve(file.key) + if sf.fileSize == -1 { + reader, _ := sf.mountInfo.swarmApi.Retrieve(ctx, sf.addr) quitC := make(chan bool) - size, err := reader.Size(quitC) + size, err := reader.Size(ctx, quitC) if err != nil { - log.Warn("Couldnt get size of file %s : %v", file.path, err) + log.Error("Couldnt get size of file %s : %v", sf.path, err) + return err } - file.fileSize = size + sf.fileSize = size + log.Trace("swarmfs Attr", "size", size) + close(quitC) } - a.Size = uint64(file.fileSize) + a.Size = uint64(sf.fileSize) return nil } func (sf *SwarmFile) Read(ctx context.Context, req *fuse.ReadRequest, resp *fuse.ReadResponse) error { - + log.Debug("swarmfs Read", "path", sf.path, "req.String", req.String()) sf.lock.RLock() defer sf.lock.RUnlock() if sf.reader == nil { - sf.reader = sf.mountInfo.swarmApi.Retrieve(sf.key) + sf.reader, _ = sf.mountInfo.swarmApi.Retrieve(ctx, sf.addr) } buf := make([]byte, req.Size) n, err := sf.reader.ReadAt(buf, req.Offset) @@ -108,26 +113,23 @@ func (sf *SwarmFile) Read(ctx context.Context, req *fuse.ReadRequest, resp *fuse } resp.Data = buf[:n] sf.reader = nil - return err + return err } func (sf *SwarmFile) Write(ctx context.Context, req *fuse.WriteRequest, resp *fuse.WriteResponse) error { - + log.Debug("swarmfs Write", "path", sf.path, "req.String", req.String()) if sf.fileSize == 0 && req.Offset == 0 { - // A new file is created err := addFileToSwarm(sf, req.Data, len(req.Data)) if err != nil { return err } resp.Size = len(req.Data) - } else if req.Offset <= sf.fileSize { - totalSize := sf.fileSize + int64(len(req.Data)) if totalSize > MaxAppendFileSize { - log.Warn("Append file size reached (%v) : (%v)", sf.fileSize, len(req.Data)) + log.Warn("swarmfs Append file size reached (%v) : (%v)", sf.fileSize, len(req.Data)) return errFileSizeMaxLimixReached } @@ -137,9 +139,8 @@ func (sf *SwarmFile) Write(ctx context.Context, req *fuse.WriteRequest, resp *fu } resp.Size = len(req.Data) } else { - log.Warn("Invalid write request size(%v) : off(%v)", sf.fileSize, req.Offset) + log.Warn("swarmfs Invalid write request size(%v) : off(%v)", sf.fileSize, req.Offset) return errInvalidOffset } - return nil } diff --git a/swarm/fuse/swarmfs.go b/swarm/fuse/swarmfs.go index 2493bdab19..c7aa983b7d 100644 --- a/swarm/fuse/swarmfs.go +++ b/swarm/fuse/swarmfs.go @@ -17,9 +17,10 @@ package fuse import ( - "github.com/ethereum/go-ethereum/swarm/api" "sync" "time" + + "github.com/ethereum/go-ethereum/swarm/api" ) const ( @@ -38,12 +39,12 @@ var ( ) type SwarmFS struct { - swarmApi *api.Api + swarmApi *api.API activeMounts map[string]*MountInfo swarmFsLock *sync.RWMutex } -func NewSwarmFS(api *api.Api) *SwarmFS { +func NewSwarmFS(api *api.API) *SwarmFS { swarmfsLock.Do(func() { swarmfs = &SwarmFS{ swarmApi: api, diff --git a/swarm/fuse/swarmfs_test.go b/swarm/fuse/swarmfs_test.go index 42af36345f..d579d15a02 100644 --- a/swarm/fuse/swarmfs_test.go +++ b/swarm/fuse/swarmfs_test.go @@ -1,4 +1,4 @@ -// Copyright 2017 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 @@ -20,7 +20,10 @@ package fuse import ( "bytes" + "context" "crypto/rand" + "flag" + "fmt" "io" "io/ioutil" "os" @@ -29,8 +32,24 @@ import ( "github.com/ethereum/go-ethereum/swarm/api" "github.com/ethereum/go-ethereum/swarm/storage" + + "github.com/ethereum/go-ethereum/log" + + colorable "github.com/mattn/go-colorable" ) +var ( + loglevel = flag.Int("loglevel", 4, "verbosity of logs") + rawlog = flag.Bool("rawlog", false, "turn off terminal formatting in logs") + longrunning = flag.Bool("longrunning", false, "do run long-running tests") +) + +func init() { + flag.Parse() + log.PrintOrigins(true) + log.Root().SetHandler(log.LvlFilterHandler(log.Lvl(*loglevel), log.StreamHandler(colorable.NewColorableStderr(), log.TerminalFormat(!*rawlog)))) +} + type fileInfo struct { perm uint64 uid int @@ -38,41 +57,70 @@ type fileInfo struct { contents []byte } -func createTestFilesAndUploadToSwarm(t *testing.T, api *api.Api, files map[string]fileInfo, uploadDir string) string { - os.RemoveAll(uploadDir) +//create files from the map of name and content provided and upload them to swarm via api +func createTestFilesAndUploadToSwarm(t *testing.T, api *api.API, files map[string]fileInfo, uploadDir string, toEncrypt bool) string { + //iterate the map for fname, finfo := range files { actualPath := filepath.Join(uploadDir, fname) filePath := filepath.Dir(actualPath) + //create directory err := os.MkdirAll(filePath, 0777) if err != nil { t.Fatalf("Error creating directory '%v' : %v", filePath, err) } + //create file fd, err1 := os.OpenFile(actualPath, os.O_RDWR|os.O_CREATE, os.FileMode(finfo.perm)) if err1 != nil { t.Fatalf("Error creating file %v: %v", actualPath, err1) } - fd.Write(finfo.contents) - fd.Chown(finfo.uid, finfo.gid) - fd.Chmod(os.FileMode(finfo.perm)) - fd.Sync() - fd.Close() + //write content to file + _, err = fd.Write(finfo.contents) + if err != nil { + t.Fatalf("Error writing to file '%v' : %v", filePath, err) + } + /* + Note @holisticode: It's not clear why the Chown command was added to the test suite. + Some files are initialized with different permissions in the individual test, + resulting in errors on Chown which were not checked. + After adding the checks tests would fail. + + What's then the reason to have this check in the first place? + Disabling for now + + err = fd.Chown(finfo.uid, finfo.gid) + if err != nil { + t.Fatalf("Error chown file '%v' : %v", filePath, err) + } + */ + err = fd.Chmod(os.FileMode(finfo.perm)) + if err != nil { + t.Fatalf("Error chmod file '%v' : %v", filePath, err) + } + err = fd.Sync() + if err != nil { + t.Fatalf("Error sync file '%v' : %v", filePath, err) + } + err = fd.Close() + if err != nil { + t.Fatalf("Error closing file '%v' : %v", filePath, err) + } } - bzzhash, err := api.Upload(uploadDir, "") + //upload directory to swarm and return hash + bzzhash, err := api.Upload(context.TODO(), uploadDir, "", toEncrypt) if err != nil { - t.Fatalf("Error uploading directory %v: %v", uploadDir, err) + t.Fatalf("Error uploading directory %v: %vm encryption: %v", uploadDir, err, toEncrypt) } return bzzhash } -func mountDir(t *testing.T, api *api.Api, files map[string]fileInfo, bzzHash string, mountDir string) *SwarmFS { - os.RemoveAll(mountDir) - os.MkdirAll(mountDir, 0777) +//mount a swarm hash as a directory on files system via FUSE +func mountDir(t *testing.T, api *api.API, files map[string]fileInfo, bzzHash string, mountDir string) *SwarmFS { swarmfs := NewSwarmFS(api) _, err := swarmfs.Mount(bzzHash, mountDir) if isFUSEUnsupportedError(err) { @@ -81,17 +129,21 @@ func mountDir(t *testing.T, api *api.Api, files map[string]fileInfo, bzzHash str t.Fatalf("Error mounting hash %v: %v", bzzHash, err) } + //check directory is mounted found := false mi := swarmfs.Listmounts() for _, minfo := range mi { + minfo.lock.RLock() if minfo.MountPoint == mountDir { if minfo.StartManifest != bzzHash || minfo.LatestManifest != bzzHash || minfo.fuseConnection == nil { + minfo.lock.RUnlock() t.Fatalf("Error mounting: exp(%s): act(%s)", bzzHash, minfo.StartManifest) } found = true } + minfo.lock.RUnlock() } // Test listMounts @@ -105,6 +157,7 @@ func mountDir(t *testing.T, api *api.Api, files map[string]fileInfo, bzzHash str return swarmfs } +// Check if file and their attributes are as expected func compareGeneratedFileWithFileInMount(t *testing.T, files map[string]fileInfo, mountDir string) { err := filepath.Walk(mountDir, func(path string, f os.FileInfo, err error) error { if f.IsDir() { @@ -142,12 +195,12 @@ func compareGeneratedFileWithFileInMount(t *testing.T, files map[string]fileInfo } if !bytes.Equal(fileContents, finfo.contents) { t.Fatalf("File %v contents mismatch: %v , %v", fname, fileContents, finfo.contents) - } // TODO: check uid and gid } } +//check mounted file with provided content func checkFile(t *testing.T, testMountDir, fname string, contents []byte) { destinationFile := filepath.Join(testMountDir, fname) dfinfo, err1 := os.Stat(destinationFile) @@ -163,15 +216,21 @@ func checkFile(t *testing.T, testMountDir, fname string, contents []byte) { t.Fatalf("Could not open file %v", destinationFile) } newcontent := make([]byte, len(contents)) - fd.Read(newcontent) - fd.Close() + _, err := fd.Read(newcontent) + if err != nil { + t.Fatalf("Could not read from file %v", err) + } + err = fd.Close() + if err != nil { + t.Fatalf("Could not close file %v", err) + } if !bytes.Equal(contents, newcontent) { t.Fatalf("File content mismatch expected (%v): received (%v) ", contents, newcontent) } } -func getRandomBtes(size int) []byte { +func getRandomBytes(size int) []byte { contents := make([]byte, size) rand.Read(contents) return contents @@ -190,647 +249,1449 @@ func isDirEmpty(name string) bool { } type testAPI struct { - api *api.Api + api *api.API } -func (ta *testAPI) mountListAndUnmount(t *testing.T) { - files := make(map[string]fileInfo) - testUploadDir, _ := ioutil.TempDir(os.TempDir(), "fuse-source") - testMountDir, _ := ioutil.TempDir(os.TempDir(), "fuse-dest") +type testData struct { + testDir string + testUploadDir string + testMountDir string + bzzHash string + files map[string]fileInfo + toEncrypt bool + swarmfs *SwarmFS +} - files["1.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} - files["2.txt"] = fileInfo{0711, 333, 444, getRandomBtes(10)} - files["3.txt"] = fileInfo{0622, 333, 444, getRandomBtes(100)} - files["4.txt"] = fileInfo{0533, 333, 444, getRandomBtes(1024)} - files["5.txt"] = fileInfo{0544, 333, 444, getRandomBtes(10)} - files["6.txt"] = fileInfo{0555, 333, 444, getRandomBtes(10)} - files["7.txt"] = fileInfo{0666, 333, 444, getRandomBtes(10)} - files["8.txt"] = fileInfo{0777, 333, 333, getRandomBtes(10)} - files["11.txt"] = fileInfo{0777, 333, 444, getRandomBtes(10)} - files["111.txt"] = fileInfo{0777, 333, 444, getRandomBtes(10)} - files["two/2.txt"] = fileInfo{0777, 333, 444, getRandomBtes(10)} - files["two/2/2.txt"] = fileInfo{0777, 333, 444, getRandomBtes(10)} - files["two/2./2.txt"] = fileInfo{0777, 444, 444, getRandomBtes(10)} - files["twice/2.txt"] = fileInfo{0777, 444, 333, getRandomBtes(200)} - files["one/two/three/four/five/six/seven/eight/nine/10.txt"] = fileInfo{0777, 333, 444, getRandomBtes(10240)} - files["one/two/three/four/five/six/six"] = fileInfo{0777, 333, 444, getRandomBtes(10)} - bzzHash := createTestFilesAndUploadToSwarm(t, ta.api, files, testUploadDir) - - swarmfs := mountDir(t, ta.api, files, bzzHash, testMountDir) - defer swarmfs.Stop() - - // Check unmount - _, err := swarmfs.Unmount(testMountDir) +//create the root dir of a test +func (ta *testAPI) initSubtest(name string) (*testData, error) { + var err error + d := &testData{} + d.testDir, err = ioutil.TempDir(os.TempDir(), name) if err != nil { - t.Fatalf("could not unmount %v", bzzHash) + return nil, fmt.Errorf("Couldn't create test dir: %v", err) } - if !isDirEmpty(testMountDir) { - t.Fatalf("unmount didnt work for %v", testMountDir) - } - + return d, nil } -func (ta *testAPI) maxMounts(t *testing.T) { - files := make(map[string]fileInfo) - files["1.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} - uploadDir1, _ := ioutil.TempDir(os.TempDir(), "max-upload1") - bzzHash1 := createTestFilesAndUploadToSwarm(t, ta.api, files, uploadDir1) - mount1, _ := ioutil.TempDir(os.TempDir(), "max-mount1") - swarmfs1 := mountDir(t, ta.api, files, bzzHash1, mount1) - defer swarmfs1.Stop() +//upload data and mount directory +func (ta *testAPI) uploadAndMount(dat *testData, t *testing.T) (*testData, error) { + //create upload dir + err := os.MkdirAll(dat.testUploadDir, 0777) + if err != nil { + return nil, fmt.Errorf("Couldn't create upload dir: %v", err) + } + //create mount dir + err = os.MkdirAll(dat.testMountDir, 0777) + if err != nil { + return nil, fmt.Errorf("Couldn't create mount dir: %v", err) + } + //upload the file + dat.bzzHash = createTestFilesAndUploadToSwarm(t, ta.api, dat.files, dat.testUploadDir, dat.toEncrypt) + log.Debug("Created test files and uploaded to Swarm") + //mount the directory + dat.swarmfs = mountDir(t, ta.api, dat.files, dat.bzzHash, dat.testMountDir) + log.Debug("Mounted swarm fs") + return dat, nil +} - files["2.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} - uploadDir2, _ := ioutil.TempDir(os.TempDir(), "max-upload2") - bzzHash2 := createTestFilesAndUploadToSwarm(t, ta.api, files, uploadDir2) - mount2, _ := ioutil.TempDir(os.TempDir(), "max-mount2") - swarmfs2 := mountDir(t, ta.api, files, bzzHash2, mount2) - defer swarmfs2.Stop() +//add a directory to the test directory tree +func addDir(root string, name string) (string, error) { + d := filepath.Join(root, name) + err := os.MkdirAll(d, 0777) + if err != nil { + return "", fmt.Errorf("Couldn't create dir inside test dir: %v", err) + } + return d, nil +} - files["3.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} - uploadDir3, _ := ioutil.TempDir(os.TempDir(), "max-upload3") - bzzHash3 := createTestFilesAndUploadToSwarm(t, ta.api, files, uploadDir3) - mount3, _ := ioutil.TempDir(os.TempDir(), "max-mount3") - swarmfs3 := mountDir(t, ta.api, files, bzzHash3, mount3) - defer swarmfs3.Stop() +func (ta *testAPI) mountListAndUnmountEncrypted(t *testing.T) { + log.Debug("Starting mountListAndUnmountEncrypted test") + ta.mountListAndUnmount(t, true) + log.Debug("Test mountListAndUnmountEncrypted terminated") +} - files["4.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} - uploadDir4, _ := ioutil.TempDir(os.TempDir(), "max-upload4") - bzzHash4 := createTestFilesAndUploadToSwarm(t, ta.api, files, uploadDir4) - mount4, _ := ioutil.TempDir(os.TempDir(), "max-mount4") - swarmfs4 := mountDir(t, ta.api, files, bzzHash4, mount4) - defer swarmfs4.Stop() +func (ta *testAPI) mountListAndUnmountNonEncrypted(t *testing.T) { + log.Debug("Starting mountListAndUnmountNonEncrypted test") + ta.mountListAndUnmount(t, false) + log.Debug("Test mountListAndUnmountNonEncrypted terminated") +} - files["5.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} - uploadDir5, _ := ioutil.TempDir(os.TempDir(), "max-upload5") - bzzHash5 := createTestFilesAndUploadToSwarm(t, ta.api, files, uploadDir5) - mount5, _ := ioutil.TempDir(os.TempDir(), "max-mount5") - swarmfs5 := mountDir(t, ta.api, files, bzzHash5, mount5) - defer swarmfs5.Stop() +//mount a directory unmount and check the directory is empty afterwards +func (ta *testAPI) mountListAndUnmount(t *testing.T, toEncrypt bool) { + dat, err := ta.initSubtest("mountListAndUnmount") + if err != nil { + t.Fatalf("Couldn't initialize subtest dirs: %v", err) + } + defer os.RemoveAll(dat.testDir) - files["6.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} - uploadDir6, _ := ioutil.TempDir(os.TempDir(), "max-upload6") - bzzHash6 := createTestFilesAndUploadToSwarm(t, ta.api, files, uploadDir6) - mount6, _ := ioutil.TempDir(os.TempDir(), "max-mount6") + dat.toEncrypt = toEncrypt + dat.testUploadDir = filepath.Join(dat.testDir, "testUploadDir") + dat.testMountDir = filepath.Join(dat.testDir, "testMountDir") + dat.files = make(map[string]fileInfo) - os.RemoveAll(mount6) - os.MkdirAll(mount6, 0777) - _, err := swarmfs.Mount(bzzHash6, mount6) + dat.files["1.txt"] = fileInfo{0700, 333, 444, getRandomBytes(10)} + dat.files["2.txt"] = fileInfo{0711, 333, 444, getRandomBytes(10)} + dat.files["3.txt"] = fileInfo{0622, 333, 444, getRandomBytes(100)} + dat.files["4.txt"] = fileInfo{0533, 333, 444, getRandomBytes(1024)} + dat.files["5.txt"] = fileInfo{0544, 333, 444, getRandomBytes(10)} + dat.files["6.txt"] = fileInfo{0555, 333, 444, getRandomBytes(10)} + dat.files["7.txt"] = fileInfo{0666, 333, 444, getRandomBytes(10)} + dat.files["8.txt"] = fileInfo{0777, 333, 333, getRandomBytes(10)} + dat.files["11.txt"] = fileInfo{0777, 333, 444, getRandomBytes(10)} + dat.files["111.txt"] = fileInfo{0777, 333, 444, getRandomBytes(10)} + dat.files["two/2.txt"] = fileInfo{0777, 333, 444, getRandomBytes(10)} + dat.files["two/2/2.txt"] = fileInfo{0777, 333, 444, getRandomBytes(10)} + dat.files["two/2./2.txt"] = fileInfo{0777, 444, 444, getRandomBytes(10)} + dat.files["twice/2.txt"] = fileInfo{0777, 444, 333, getRandomBytes(200)} + dat.files["one/two/three/four/five/six/seven/eight/nine/10.txt"] = fileInfo{0777, 333, 444, getRandomBytes(10240)} + dat.files["one/two/three/four/five/six/six"] = fileInfo{0777, 333, 444, getRandomBytes(10)} + + dat, err = ta.uploadAndMount(dat, t) + if err != nil { + t.Fatalf("Error during upload of files to swarm / mount of swarm dir: %v", err) + } + defer dat.swarmfs.Stop() + // Check unmount + _, err = dat.swarmfs.Unmount(dat.testMountDir) + if err != nil { + t.Fatalf("could not unmount %v", dat.bzzHash) + } + log.Debug("Unmount successful") + if !isDirEmpty(dat.testMountDir) { + t.Fatalf("unmount didnt work for %v", dat.testMountDir) + } + log.Debug("subtest terminated") +} + +func (ta *testAPI) maxMountsEncrypted(t *testing.T) { + log.Debug("Starting maxMountsEncrypted test") + ta.runMaxMounts(t, true) + log.Debug("Test maxMountsEncrypted terminated") +} + +func (ta *testAPI) maxMountsNonEncrypted(t *testing.T) { + log.Debug("Starting maxMountsNonEncrypted test") + ta.runMaxMounts(t, false) + log.Debug("Test maxMountsNonEncrypted terminated") +} + +//mount several different directories until the maximum has been reached +func (ta *testAPI) runMaxMounts(t *testing.T, toEncrypt bool) { + dat, err := ta.initSubtest("runMaxMounts") + if err != nil { + t.Fatalf("Couldn't initialize subtest dirs: %v", err) + } + defer os.RemoveAll(dat.testDir) + + dat.toEncrypt = toEncrypt + dat.testUploadDir = filepath.Join(dat.testDir, "max-upload1") + dat.testMountDir = filepath.Join(dat.testDir, "max-mount1") + dat.files = make(map[string]fileInfo) + dat.files["1.txt"] = fileInfo{0700, 333, 444, getRandomBytes(10)} + + dat, err = ta.uploadAndMount(dat, t) + if err != nil { + t.Fatalf("Error during upload of files to swarm / mount of swarm dir: %v", err) + } + defer dat.swarmfs.Stop() + + dat.testUploadDir = filepath.Join(dat.testDir, "max-upload2") + dat.testMountDir = filepath.Join(dat.testDir, "max-mount2") + dat.files["2.txt"] = fileInfo{0700, 333, 444, getRandomBytes(10)} + + dat, err = ta.uploadAndMount(dat, t) + if err != nil { + t.Fatalf("Error during upload of files to swarm / mount of swarm dir: %v", err) + } + + dat.testUploadDir = filepath.Join(dat.testDir, "max-upload3") + dat.testMountDir = filepath.Join(dat.testDir, "max-mount3") + dat.files["3.txt"] = fileInfo{0700, 333, 444, getRandomBytes(10)} + + dat, err = ta.uploadAndMount(dat, t) + if err != nil { + t.Fatalf("Error during upload of files to swarm / mount of swarm dir: %v", err) + } + + dat.testUploadDir = filepath.Join(dat.testDir, "max-upload4") + dat.testMountDir = filepath.Join(dat.testDir, "max-mount4") + dat.files["4.txt"] = fileInfo{0700, 333, 444, getRandomBytes(10)} + + dat, err = ta.uploadAndMount(dat, t) + if err != nil { + t.Fatalf("Error during upload of files to swarm / mount of swarm dir: %v", err) + } + + dat.testUploadDir = filepath.Join(dat.testDir, "max-upload5") + dat.testMountDir = filepath.Join(dat.testDir, "max-mount5") + dat.files["5.txt"] = fileInfo{0700, 333, 444, getRandomBytes(10)} + + dat, err = ta.uploadAndMount(dat, t) + if err != nil { + t.Fatalf("Error during upload of files to swarm / mount of swarm dir: %v", err) + } + + //now try an additional mount, should fail due to max mounts reached + testUploadDir6 := filepath.Join(dat.testDir, "max-upload6") + err = os.MkdirAll(testUploadDir6, 0777) + if err != nil { + t.Fatalf("Couldn't create upload dir 6: %v", err) + } + dat.files["6.txt"] = fileInfo{0700, 333, 444, getRandomBytes(10)} + testMountDir6 := filepath.Join(dat.testDir, "max-mount6") + err = os.MkdirAll(testMountDir6, 0777) + if err != nil { + t.Fatalf("Couldn't create mount dir 5: %v", err) + } + bzzHash6 := createTestFilesAndUploadToSwarm(t, ta.api, dat.files, testUploadDir6, toEncrypt) + log.Debug("Created test files and uploaded to swarm with uploadDir6") + _, err = dat.swarmfs.Mount(bzzHash6, testMountDir6) if err == nil { - t.Fatalf("Error: Going beyond max mounts %v", bzzHash6) + t.Fatalf("Expected this mount to fail due to exceeding max number of allowed mounts, but succeeded. %v", bzzHash6) } - + log.Debug("Maximum mount reached, additional mount failed. Correct.") } -func (ta *testAPI) remount(t *testing.T) { - files := make(map[string]fileInfo) - files["1.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} - uploadDir1, _ := ioutil.TempDir(os.TempDir(), "re-upload1") - bzzHash1 := createTestFilesAndUploadToSwarm(t, ta.api, files, uploadDir1) - testMountDir1, _ := ioutil.TempDir(os.TempDir(), "re-mount1") - swarmfs := mountDir(t, ta.api, files, bzzHash1, testMountDir1) - defer swarmfs.Stop() +func (ta *testAPI) remountEncrypted(t *testing.T) { + log.Debug("Starting remountEncrypted test") + ta.remount(t, true) + log.Debug("Test remountEncrypted terminated") +} +func (ta *testAPI) remountNonEncrypted(t *testing.T) { + log.Debug("Starting remountNonEncrypted test") + ta.remount(t, false) + log.Debug("Test remountNonEncrypted terminated") +} - uploadDir2, _ := ioutil.TempDir(os.TempDir(), "re-upload2") - bzzHash2 := createTestFilesAndUploadToSwarm(t, ta.api, files, uploadDir2) - testMountDir2, _ := ioutil.TempDir(os.TempDir(), "re-mount2") +//test remounting same hash second time and different hash in already mounted point +func (ta *testAPI) remount(t *testing.T, toEncrypt bool) { + dat, err := ta.initSubtest("remount") + if err != nil { + t.Fatalf("Couldn't initialize subtest dirs: %v", err) + } + defer os.RemoveAll(dat.testDir) + + dat.toEncrypt = toEncrypt + dat.testUploadDir = filepath.Join(dat.testDir, "remount-upload1") + dat.testMountDir = filepath.Join(dat.testDir, "remount-mount1") + dat.files = make(map[string]fileInfo) + + dat.files["1.txt"] = fileInfo{0700, 333, 444, getRandomBytes(10)} + + dat, err = ta.uploadAndMount(dat, t) + if err != nil { + t.Fatalf("Error during upload of files to swarm / mount of swarm dir: %v", err) + } + defer dat.swarmfs.Stop() // try mounting the same hash second time - os.RemoveAll(testMountDir2) - os.MkdirAll(testMountDir2, 0777) - _, err := swarmfs.Mount(bzzHash1, testMountDir2) - if err != nil { - t.Fatalf("Error mounting hash %v", bzzHash1) + testMountDir2, err2 := addDir(dat.testDir, "remount-mount2") + if err2 != nil { + t.Fatalf("Error creating second mount dir: %v", err2) + } + _, err2 = dat.swarmfs.Mount(dat.bzzHash, testMountDir2) + if err2 != nil { + t.Fatalf("Error mounting hash second time on different dir %v", dat.bzzHash) } // mount a different hash in already mounted point - _, err = swarmfs.Mount(bzzHash2, testMountDir1) + dat.files["2.txt"] = fileInfo{0700, 333, 444, getRandomBytes(10)} + testUploadDir2, err3 := addDir(dat.testDir, "remount-upload2") + if err3 != nil { + t.Fatalf("Error creating second upload dir: %v", err3) + } + bzzHash2 := createTestFilesAndUploadToSwarm(t, ta.api, dat.files, testUploadDir2, toEncrypt) + _, err = swarmfs.Mount(bzzHash2, dat.testMountDir) if err == nil { t.Fatalf("Error mounting hash %v", bzzHash2) } + log.Debug("Mount on existing mount point failed. Correct.") // mount nonexistent hash - _, err = swarmfs.Mount("0xfea11223344", testMountDir1) + failDir, err3 := addDir(dat.testDir, "remount-fail") + if err3 != nil { + t.Fatalf("Error creating remount dir: %v", bzzHash2) + } + failHash := "0xfea11223344" + _, err = swarmfs.Mount(failHash, failDir) if err == nil { - t.Fatalf("Error mounting hash %v", bzzHash2) + t.Fatalf("Expected this mount to fail due to non existing hash. But succeeded %v", failHash) } + log.Debug("Nonexistent hash hasn't been mounted. Correct.") } -func (ta *testAPI) unmount(t *testing.T) { - files := make(map[string]fileInfo) - uploadDir, _ := ioutil.TempDir(os.TempDir(), "ex-upload") - testMountDir, _ := ioutil.TempDir(os.TempDir(), "ex-mount") - - files["1.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} - bzzHash := createTestFilesAndUploadToSwarm(t, ta.api, files, uploadDir) - - swarmfs := mountDir(t, ta.api, files, bzzHash, testMountDir) - defer swarmfs.Stop() - - swarmfs.Unmount(testMountDir) - - mi := swarmfs.Listmounts() - for _, minfo := range mi { - if minfo.MountPoint == testMountDir { - t.Fatalf("mount state not cleaned up in unmount case %v", testMountDir) - } - } +func (ta *testAPI) unmountEncrypted(t *testing.T) { + log.Debug("Starting unmountEncrypted test") + ta.unmount(t, true) + log.Debug("Test unmountEncrypted terminated") } -func (ta *testAPI) unmountWhenResourceBusy(t *testing.T) { - files := make(map[string]fileInfo) - testUploadDir, _ := ioutil.TempDir(os.TempDir(), "ex-upload") - testMountDir, _ := ioutil.TempDir(os.TempDir(), "ex-mount") +func (ta *testAPI) unmountNonEncrypted(t *testing.T) { + log.Debug("Starting unmountNonEncrypted test") + ta.unmount(t, false) + log.Debug("Test unmountNonEncrypted terminated") +} - files["1.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} - bzzHash := createTestFilesAndUploadToSwarm(t, ta.api, files, testUploadDir) - - swarmfs := mountDir(t, ta.api, files, bzzHash, testMountDir) - defer swarmfs.Stop() - - actualPath := filepath.Join(testMountDir, "2.txt") - d, err := os.OpenFile(actualPath, os.O_RDWR, os.FileMode(0700)) - d.Write(getRandomBtes(10)) - - _, err = swarmfs.Unmount(testMountDir) +//mount then unmount and check that it has been unmounted +func (ta *testAPI) unmount(t *testing.T, toEncrypt bool) { + dat, err := ta.initSubtest("unmount") if err != nil { - t.Fatalf("could not unmount %v", bzzHash) + t.Fatalf("Couldn't initialize subtest dirs: %v", err) } - d.Close() + defer os.RemoveAll(dat.testDir) + + dat.toEncrypt = toEncrypt + dat.testUploadDir = filepath.Join(dat.testDir, "ex-upload1") + dat.testMountDir = filepath.Join(dat.testDir, "ex-mount1") + dat.files = make(map[string]fileInfo) + dat.files["1.txt"] = fileInfo{0700, 333, 444, getRandomBytes(10)} + + dat, err = ta.uploadAndMount(dat, t) + if err != nil { + t.Fatalf("Error during upload of files to swarm / mount of swarm dir: %v", err) + } + defer dat.swarmfs.Stop() + + _, err = dat.swarmfs.Unmount(dat.testMountDir) + if err != nil { + t.Fatalf("could not unmount %v", dat.bzzHash) + } + log.Debug("Unmounted Dir") mi := swarmfs.Listmounts() + log.Debug("Going to list mounts") for _, minfo := range mi { - if minfo.MountPoint == testMountDir { - t.Fatalf("mount state not cleaned up in unmount case %v", testMountDir) + log.Debug("Mount point in list: ", "point", minfo.MountPoint) + if minfo.MountPoint == dat.testMountDir { + t.Fatalf("mount state not cleaned up in unmount case %v", dat.testMountDir) } } + log.Debug("subtest terminated") } -func (ta *testAPI) seekInMultiChunkFile(t *testing.T) { - files := make(map[string]fileInfo) - testUploadDir, _ := ioutil.TempDir(os.TempDir(), "seek-upload") - testMountDir, _ := ioutil.TempDir(os.TempDir(), "seek-mount") +func (ta *testAPI) unmountWhenResourceBusyEncrypted(t *testing.T) { + log.Debug("Starting unmountWhenResourceBusyEncrypted test") + ta.unmountWhenResourceBusy(t, true) + log.Debug("Test unmountWhenResourceBusyEncrypted terminated") +} +func (ta *testAPI) unmountWhenResourceBusyNonEncrypted(t *testing.T) { + log.Debug("Starting unmountWhenResourceBusyNonEncrypted test") + ta.unmountWhenResourceBusy(t, false) + log.Debug("Test unmountWhenResourceBusyNonEncrypted terminated") +} - files["1.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10240)} - bzzHash := createTestFilesAndUploadToSwarm(t, ta.api, files, testUploadDir) +//unmount while a resource is busy; should fail +func (ta *testAPI) unmountWhenResourceBusy(t *testing.T, toEncrypt bool) { + dat, err := ta.initSubtest("unmountWhenResourceBusy") + if err != nil { + t.Fatalf("Couldn't initialize subtest dirs: %v", err) + } + defer os.RemoveAll(dat.testDir) - swarmfs := mountDir(t, ta.api, files, bzzHash, testMountDir) - defer swarmfs.Stop() + dat.toEncrypt = toEncrypt + dat.testUploadDir = filepath.Join(dat.testDir, "ex-upload1") + dat.testMountDir = filepath.Join(dat.testDir, "ex-mount1") + dat.files = make(map[string]fileInfo) + dat.files["1.txt"] = fileInfo{0700, 333, 444, getRandomBytes(10)} - // Create a new file seek the second chunk - actualPath := filepath.Join(testMountDir, "1.txt") - d, _ := os.OpenFile(actualPath, os.O_RDONLY, os.FileMode(0700)) + dat, err = ta.uploadAndMount(dat, t) + if err != nil { + t.Fatalf("Error during upload of files to swarm / mount of swarm dir: %v", err) + } + defer dat.swarmfs.Stop() - d.Seek(5000, 0) + //create a file in the mounted directory, then try to unmount - should fail + actualPath := filepath.Join(dat.testMountDir, "2.txt") + //d, err := os.OpenFile(actualPath, os.O_RDWR, os.FileMode(0700)) + d, err := os.Create(actualPath) + if err != nil { + t.Fatalf("Couldn't create new file: %v", err) + } + //we need to manually close the file before mount for this test + //but let's defer too in case of errors + defer d.Close() + _, err = d.Write(getRandomBytes(10)) + if err != nil { + t.Fatalf("Couldn't write to file: %v", err) + } + log.Debug("Bytes written") + + _, err = dat.swarmfs.Unmount(dat.testMountDir) + if err == nil { + t.Fatalf("Expected mount to fail due to resource busy, but it succeeded...") + } + //free resources + err = d.Close() + if err != nil { + t.Fatalf("Couldn't close file! %v", dat.bzzHash) + } + log.Debug("File closed") + + //now unmount after explicitly closed file + _, err = dat.swarmfs.Unmount(dat.testMountDir) + if err != nil { + t.Fatalf("Expected mount to succeed after freeing resource, but it failed: %v", err) + } + //check if the dir is still mounted + mi := dat.swarmfs.Listmounts() + log.Debug("Going to list mounts") + for _, minfo := range mi { + log.Debug("Mount point in list: ", "point", minfo.MountPoint) + if minfo.MountPoint == dat.testMountDir { + t.Fatalf("mount state not cleaned up in unmount case %v", dat.testMountDir) + } + } + log.Debug("subtest terminated") +} + +func (ta *testAPI) seekInMultiChunkFileEncrypted(t *testing.T) { + log.Debug("Starting seekInMultiChunkFileEncrypted test") + ta.seekInMultiChunkFile(t, true) + log.Debug("Test seekInMultiChunkFileEncrypted terminated") +} + +func (ta *testAPI) seekInMultiChunkFileNonEncrypted(t *testing.T) { + log.Debug("Starting seekInMultiChunkFileNonEncrypted test") + ta.seekInMultiChunkFile(t, false) + log.Debug("Test seekInMultiChunkFileNonEncrypted terminated") +} + +//open a file in a mounted dir and go to a certain position +func (ta *testAPI) seekInMultiChunkFile(t *testing.T, toEncrypt bool) { + dat, err := ta.initSubtest("seekInMultiChunkFile") + if err != nil { + t.Fatalf("Couldn't initialize subtest dirs: %v", err) + } + defer os.RemoveAll(dat.testDir) + + dat.toEncrypt = toEncrypt + dat.testUploadDir = filepath.Join(dat.testDir, "seek-upload1") + dat.testMountDir = filepath.Join(dat.testDir, "seek-mount") + dat.files = make(map[string]fileInfo) + dat.files["1.txt"] = fileInfo{0700, 333, 444, getRandomBytes(10240)} + + dat, err = ta.uploadAndMount(dat, t) + if err != nil { + t.Fatalf("Error during upload of files to swarm / mount of swarm dir: %v", err) + } + defer dat.swarmfs.Stop() + + // Open the file in the mounted dir and seek the second chunk + actualPath := filepath.Join(dat.testMountDir, "1.txt") + d, err := os.OpenFile(actualPath, os.O_RDONLY, os.FileMode(0700)) + if err != nil { + t.Fatalf("Couldn't open file: %v", err) + } + log.Debug("Opened file") + defer func() { + err := d.Close() + if err != nil { + t.Fatalf("Error closing file! %v", err) + } + }() + + _, err = d.Seek(5000, 0) + if err != nil { + t.Fatalf("Error seeking in file: %v", err) + } contents := make([]byte, 1024) - d.Read(contents) - finfo := files["1.txt"] + _, err = d.Read(contents) + if err != nil { + t.Fatalf("Error reading file: %v", err) + } + log.Debug("Read contents") + finfo := dat.files["1.txt"] if !bytes.Equal(finfo.contents[:6024][5000:], contents) { t.Fatalf("File seek contents mismatch") } - d.Close() + log.Debug("subtest terminated") } -func (ta *testAPI) createNewFile(t *testing.T) { - files := make(map[string]fileInfo) - testUploadDir, _ := ioutil.TempDir(os.TempDir(), "create-upload") - testMountDir, _ := ioutil.TempDir(os.TempDir(), "create-mount") +func (ta *testAPI) createNewFileEncrypted(t *testing.T) { + log.Debug("Starting createNewFileEncrypted test") + ta.createNewFile(t, true) + log.Debug("Test createNewFileEncrypted terminated") +} - files["1.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} - files["five.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} - files["six.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} - bzzHash := createTestFilesAndUploadToSwarm(t, ta.api, files, testUploadDir) +func (ta *testAPI) createNewFileNonEncrypted(t *testing.T) { + log.Debug("Starting createNewFileNonEncrypted test") + ta.createNewFile(t, false) + log.Debug("Test createNewFileNonEncrypted terminated") +} - swarmfs1 := mountDir(t, ta.api, files, bzzHash, testMountDir) - defer swarmfs1.Stop() +//create a new file in a mounted swarm directory, +//unmount the fuse dir and then remount to see if new file is still there +func (ta *testAPI) createNewFile(t *testing.T, toEncrypt bool) { + dat, err := ta.initSubtest("createNewFile") + if err != nil { + t.Fatalf("Couldn't initialize subtest dirs: %v", err) + } + defer os.RemoveAll(dat.testDir) + + dat.toEncrypt = toEncrypt + dat.testUploadDir = filepath.Join(dat.testDir, "create-upload1") + dat.testMountDir = filepath.Join(dat.testDir, "create-mount") + dat.files = make(map[string]fileInfo) + dat.files["1.txt"] = fileInfo{0700, 333, 444, getRandomBytes(10)} + dat.files["five.txt"] = fileInfo{0700, 333, 444, getRandomBytes(10)} + dat.files["six.txt"] = fileInfo{0700, 333, 444, getRandomBytes(10)} + + dat, err = ta.uploadAndMount(dat, t) + if err != nil { + t.Fatalf("Error during upload of files to swarm / mount of swarm dir: %v", err) + } + defer dat.swarmfs.Stop() // Create a new file in the root dir and check - actualPath := filepath.Join(testMountDir, "2.txt") + actualPath := filepath.Join(dat.testMountDir, "2.txt") d, err1 := os.OpenFile(actualPath, os.O_RDWR|os.O_CREATE, os.FileMode(0665)) if err1 != nil { - t.Fatalf("Could not create file %s : %v", actualPath, err1) + t.Fatalf("Could not open file %s : %v", actualPath, err1) } + defer d.Close() + log.Debug("Opened file") contents := make([]byte, 11) - rand.Read(contents) - d.Write(contents) - d.Close() + _, err = rand.Read(contents) + if err != nil { + t.Fatalf("Could not rand read contents %v", err) + } + log.Debug("content read") + _, err = d.Write(contents) + if err != nil { + t.Fatalf("Couldn't write contents: %v", err) + } + log.Debug("content written") + err = d.Close() + if err != nil { + t.Fatalf("Couldn't close file: %v", err) + } + log.Debug("file closed") - mi, err2 := swarmfs1.Unmount(testMountDir) + mi, err2 := dat.swarmfs.Unmount(dat.testMountDir) if err2 != nil { t.Fatalf("Could not unmount %v", err2) } + log.Debug("Directory unmounted") - // mount again and see if things are okay - files["2.txt"] = fileInfo{0700, 333, 444, contents} - swarmfs2 := mountDir(t, ta.api, files, mi.LatestManifest, testMountDir) - defer swarmfs2.Stop() - - checkFile(t, testMountDir, "2.txt", contents) -} - -func (ta *testAPI) createNewFileInsideDirectory(t *testing.T) { - files := make(map[string]fileInfo) - testUploadDir, _ := ioutil.TempDir(os.TempDir(), "createinsidedir-upload") - testMountDir, _ := ioutil.TempDir(os.TempDir(), "createinsidedir-mount") - - files["one/1.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} - bzzHash := createTestFilesAndUploadToSwarm(t, ta.api, files, testUploadDir) - - swarmfs1 := mountDir(t, ta.api, files, bzzHash, testMountDir) - defer swarmfs1.Stop() - - // Create a new file inside a existing dir and check - dirToCreate := filepath.Join(testMountDir, "one") - actualPath := filepath.Join(dirToCreate, "2.txt") - d, err1 := os.OpenFile(actualPath, os.O_RDWR|os.O_CREATE, os.FileMode(0665)) - if err1 != nil { - t.Fatalf("Could not create file %s : %v", actualPath, err1) - } - contents := make([]byte, 11) - rand.Read(contents) - d.Write(contents) - d.Close() - - mi, err2 := swarmfs1.Unmount(testMountDir) - if err2 != nil { - t.Fatalf("Could not unmount %v", err2) - } - - // mount again and see if things are okay - files["one/2.txt"] = fileInfo{0700, 333, 444, contents} - swarmfs2 := mountDir(t, ta.api, files, mi.LatestManifest, testMountDir) - defer swarmfs2.Stop() - - checkFile(t, testMountDir, "one/2.txt", contents) -} - -func (ta *testAPI) createNewFileInsideNewDirectory(t *testing.T) { - files := make(map[string]fileInfo) - testUploadDir, _ := ioutil.TempDir(os.TempDir(), "createinsidenewdir-upload") - testMountDir, _ := ioutil.TempDir(os.TempDir(), "createinsidenewdir-mount") - - files["1.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} - bzzHash := createTestFilesAndUploadToSwarm(t, ta.api, files, testUploadDir) - - swarmfs1 := mountDir(t, ta.api, files, bzzHash, testMountDir) - defer swarmfs1.Stop() - - // Create a new file inside a existing dir and check - dirToCreate := filepath.Join(testMountDir, "one") - os.MkdirAll(dirToCreate, 0777) - actualPath := filepath.Join(dirToCreate, "2.txt") - d, err1 := os.OpenFile(actualPath, os.O_RDWR|os.O_CREATE, os.FileMode(0665)) - if err1 != nil { - t.Fatalf("Could not create file %s : %v", actualPath, err1) - } - contents := make([]byte, 11) - rand.Read(contents) - d.Write(contents) - d.Close() - - mi, err2 := swarmfs1.Unmount(testMountDir) - if err2 != nil { - t.Fatalf("Could not unmount %v", err2) - } - - // mount again and see if things are okay - files["one/2.txt"] = fileInfo{0700, 333, 444, contents} - swarmfs2 := mountDir(t, ta.api, files, mi.LatestManifest, testMountDir) - defer swarmfs2.Stop() - - checkFile(t, testMountDir, "one/2.txt", contents) -} - -func (ta *testAPI) removeExistingFile(t *testing.T) { - files := make(map[string]fileInfo) - testUploadDir, _ := ioutil.TempDir(os.TempDir(), "remove-upload") - testMountDir, _ := ioutil.TempDir(os.TempDir(), "remove-mount") - - files["1.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} - files["five.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} - files["six.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} - bzzHash := createTestFilesAndUploadToSwarm(t, ta.api, files, testUploadDir) - - swarmfs1 := mountDir(t, ta.api, files, bzzHash, testMountDir) - defer swarmfs1.Stop() - - // Remove a file in the root dir and check - actualPath := filepath.Join(testMountDir, "five.txt") - os.Remove(actualPath) - - mi, err2 := swarmfs1.Unmount(testMountDir) - if err2 != nil { - t.Fatalf("Could not unmount %v", err2) - } - - // mount again and see if things are okay - delete(files, "five.txt") - swarmfs2 := mountDir(t, ta.api, files, mi.LatestManifest, testMountDir) - defer swarmfs2.Stop() -} - -func (ta *testAPI) removeExistingFileInsideDir(t *testing.T) { - files := make(map[string]fileInfo) - testUploadDir, _ := ioutil.TempDir(os.TempDir(), "remove-upload") - testMountDir, _ := ioutil.TempDir(os.TempDir(), "remove-mount") - - files["1.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} - files["one/five.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} - files["one/six.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} - bzzHash := createTestFilesAndUploadToSwarm(t, ta.api, files, testUploadDir) - - swarmfs1 := mountDir(t, ta.api, files, bzzHash, testMountDir) - defer swarmfs1.Stop() - - // Remove a file in the root dir and check - actualPath := filepath.Join(testMountDir, "one/five.txt") - os.Remove(actualPath) - - mi, err2 := swarmfs1.Unmount(testMountDir) - if err2 != nil { - t.Fatalf("Could not unmount %v", err2) - } - - // mount again and see if things are okay - delete(files, "one/five.txt") - swarmfs2 := mountDir(t, ta.api, files, mi.LatestManifest, testMountDir) - defer swarmfs2.Stop() -} - -func (ta *testAPI) removeNewlyAddedFile(t *testing.T) { - - files := make(map[string]fileInfo) - testUploadDir, _ := ioutil.TempDir(os.TempDir(), "removenew-upload") - testMountDir, _ := ioutil.TempDir(os.TempDir(), "removenew-mount") - - files["1.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} - files["five.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} - files["six.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} - bzzHash := createTestFilesAndUploadToSwarm(t, ta.api, files, testUploadDir) - - swarmfs1 := mountDir(t, ta.api, files, bzzHash, testMountDir) - defer swarmfs1.Stop() - - // Adda a new file and remove it - dirToCreate := filepath.Join(testMountDir, "one") - os.MkdirAll(dirToCreate, os.FileMode(0665)) - actualPath := filepath.Join(dirToCreate, "2.txt") - d, err1 := os.OpenFile(actualPath, os.O_RDWR|os.O_CREATE, os.FileMode(0665)) - if err1 != nil { - t.Fatalf("Could not create file %s : %v", actualPath, err1) - } - contents := make([]byte, 11) - rand.Read(contents) - d.Write(contents) - d.Close() - - checkFile(t, testMountDir, "one/2.txt", contents) - - os.Remove(actualPath) - - mi, err2 := swarmfs1.Unmount(testMountDir) - if err2 != nil { - t.Fatalf("Could not unmount %v", err2) - } - - // mount again and see if things are okay - swarmfs2 := mountDir(t, ta.api, files, mi.LatestManifest, testMountDir) - defer swarmfs2.Stop() - - if bzzHash != mi.LatestManifest { - t.Fatalf("same contents different hash orig(%v): new(%v)", bzzHash, mi.LatestManifest) - } -} - -func (ta *testAPI) addNewFileAndModifyContents(t *testing.T) { - files := make(map[string]fileInfo) - testUploadDir, _ := ioutil.TempDir(os.TempDir(), "modifyfile-upload") - testMountDir, _ := ioutil.TempDir(os.TempDir(), "modifyfile-mount") - - files["1.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} - files["five.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} - files["six.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} - bzzHash := createTestFilesAndUploadToSwarm(t, ta.api, files, testUploadDir) - - swarmfs1 := mountDir(t, ta.api, files, bzzHash, testMountDir) - defer swarmfs1.Stop() - - // Create a new file in the root dir and check - actualPath := filepath.Join(testMountDir, "2.txt") - d, err1 := os.OpenFile(actualPath, os.O_RDWR|os.O_CREATE, os.FileMode(0665)) - if err1 != nil { - t.Fatalf("Could not create file %s : %v", actualPath, err1) - } - line1 := []byte("Line 1") - rand.Read(line1) - d.Write(line1) - d.Close() - - mi1, err2 := swarmfs1.Unmount(testMountDir) - if err2 != nil { - t.Fatalf("Could not unmount %v", err2) - } - - // mount again and see if things are okay - files["2.txt"] = fileInfo{0700, 333, 444, line1} - swarmfs2 := mountDir(t, ta.api, files, mi1.LatestManifest, testMountDir) - defer swarmfs2.Stop() - - checkFile(t, testMountDir, "2.txt", line1) - - mi2, err3 := swarmfs2.Unmount(testMountDir) + testMountDir2, err3 := addDir(dat.testDir, "create-mount2") if err3 != nil { - t.Fatalf("Could not unmount %v", err3) + t.Fatalf("Error creating mount dir2: %v", err3) } + // mount again and see if things are okay + dat.files["2.txt"] = fileInfo{0700, 333, 444, contents} + _ = mountDir(t, ta.api, dat.files, mi.LatestManifest, testMountDir2) + log.Debug("Directory mounted again") - // mount again and modify - swarmfs3 := mountDir(t, ta.api, files, mi2.LatestManifest, testMountDir) - defer swarmfs3.Stop() - - fd, err4 := os.OpenFile(actualPath, os.O_RDWR|os.O_APPEND, os.FileMode(0665)) - if err4 != nil { - t.Fatalf("Could not create file %s : %v", actualPath, err4) + checkFile(t, testMountDir2, "2.txt", contents) + _, err2 = dat.swarmfs.Unmount(testMountDir2) + if err2 != nil { + t.Fatalf("Could not unmount %v", err2) } - line2 := []byte("Line 2") - rand.Read(line2) - fd.Seek(int64(len(line1)), 0) - fd.Write(line2) - fd.Close() + log.Debug("subtest terminated") +} - mi3, err5 := swarmfs3.Unmount(testMountDir) - if err5 != nil { - t.Fatalf("Could not unmount %v", err5) +func (ta *testAPI) createNewFileInsideDirectoryEncrypted(t *testing.T) { + log.Debug("Starting createNewFileInsideDirectoryEncrypted test") + ta.createNewFileInsideDirectory(t, true) + log.Debug("Test createNewFileInsideDirectoryEncrypted terminated") +} + +func (ta *testAPI) createNewFileInsideDirectoryNonEncrypted(t *testing.T) { + log.Debug("Starting createNewFileInsideDirectoryNonEncrypted test") + ta.createNewFileInsideDirectory(t, false) + log.Debug("Test createNewFileInsideDirectoryNonEncrypted terminated") +} + +//create a new file inside a directory inside the mount +func (ta *testAPI) createNewFileInsideDirectory(t *testing.T, toEncrypt bool) { + dat, err := ta.initSubtest("createNewFileInsideDirectory") + if err != nil { + t.Fatalf("Couldn't initialize subtest dirs: %v", err) } + defer os.RemoveAll(dat.testDir) + + dat.toEncrypt = toEncrypt + dat.testUploadDir = filepath.Join(dat.testDir, "createinsidedir-upload") + dat.testMountDir = filepath.Join(dat.testDir, "createinsidedir-mount") + dat.files = make(map[string]fileInfo) + dat.files["one/1.txt"] = fileInfo{0700, 333, 444, getRandomBytes(10)} + + dat, err = ta.uploadAndMount(dat, t) + if err != nil { + t.Fatalf("Error during upload of files to swarm / mount of swarm dir: %v", err) + } + defer dat.swarmfs.Stop() + + // Create a new file inside a existing dir and check + dirToCreate := filepath.Join(dat.testMountDir, "one") + actualPath := filepath.Join(dirToCreate, "2.txt") + d, err1 := os.OpenFile(actualPath, os.O_RDWR|os.O_CREATE, os.FileMode(0665)) + if err1 != nil { + t.Fatalf("Could not create file %s : %v", actualPath, err1) + } + defer d.Close() + log.Debug("File opened") + contents := make([]byte, 11) + _, err = rand.Read(contents) + if err != nil { + t.Fatalf("Error filling random bytes into byte array %v", err) + } + log.Debug("Content read") + _, err = d.Write(contents) + if err != nil { + t.Fatalf("Error writing random bytes into file %v", err) + } + log.Debug("Content written") + err = d.Close() + if err != nil { + t.Fatalf("Error closing file %v", err) + } + log.Debug("File closed") + + mi, err2 := dat.swarmfs.Unmount(dat.testMountDir) + if err2 != nil { + t.Fatalf("Could not unmount %v", err2) + } + log.Debug("Directory unmounted") + + testMountDir2, err3 := addDir(dat.testDir, "createinsidedir-mount2") + if err3 != nil { + t.Fatalf("Error creating mount dir2: %v", err3) + } + // mount again and see if things are okay + dat.files["one/2.txt"] = fileInfo{0700, 333, 444, contents} + _ = mountDir(t, ta.api, dat.files, mi.LatestManifest, testMountDir2) + log.Debug("Directory mounted again") + + checkFile(t, testMountDir2, "one/2.txt", contents) + _, err = dat.swarmfs.Unmount(testMountDir2) + if err != nil { + t.Fatalf("could not unmount %v", dat.bzzHash) + } + log.Debug("subtest terminated") +} + +func (ta *testAPI) createNewFileInsideNewDirectoryEncrypted(t *testing.T) { + log.Debug("Starting createNewFileInsideNewDirectoryEncrypted test") + ta.createNewFileInsideNewDirectory(t, true) + log.Debug("Test createNewFileInsideNewDirectoryEncrypted terminated") +} + +func (ta *testAPI) createNewFileInsideNewDirectoryNonEncrypted(t *testing.T) { + log.Debug("Starting createNewFileInsideNewDirectoryNonEncrypted test") + ta.createNewFileInsideNewDirectory(t, false) + log.Debug("Test createNewFileInsideNewDirectoryNonEncrypted terminated") +} + +//create a new directory in mount and a new file +func (ta *testAPI) createNewFileInsideNewDirectory(t *testing.T, toEncrypt bool) { + dat, err := ta.initSubtest("createNewFileInsideNewDirectory") + if err != nil { + t.Fatalf("Couldn't initialize subtest dirs: %v", err) + } + defer os.RemoveAll(dat.testDir) + + dat.toEncrypt = toEncrypt + dat.testUploadDir = filepath.Join(dat.testDir, "createinsidenewdir-upload") + dat.testMountDir = filepath.Join(dat.testDir, "createinsidenewdir-mount") + dat.files = make(map[string]fileInfo) + dat.files["1.txt"] = fileInfo{0700, 333, 444, getRandomBytes(10)} + + dat, err = ta.uploadAndMount(dat, t) + if err != nil { + t.Fatalf("Error during upload of files to swarm / mount of swarm dir: %v", err) + } + defer dat.swarmfs.Stop() + + // Create a new file inside a existing dir and check + dirToCreate, err2 := addDir(dat.testMountDir, "one") + if err2 != nil { + t.Fatalf("Error creating mount dir2: %v", err2) + } + actualPath := filepath.Join(dirToCreate, "2.txt") + d, err1 := os.OpenFile(actualPath, os.O_RDWR|os.O_CREATE, os.FileMode(0665)) + if err1 != nil { + t.Fatalf("Could not create file %s : %v", actualPath, err1) + } + defer d.Close() + log.Debug("File opened") + contents := make([]byte, 11) + _, err = rand.Read(contents) + if err != nil { + t.Fatalf("Error writing random bytes to byte array: %v", err) + } + log.Debug("content read") + _, err = d.Write(contents) + if err != nil { + t.Fatalf("Error writing to file: %v", err) + } + log.Debug("content written") + err = d.Close() + if err != nil { + t.Fatalf("Error closing file: %v", err) + } + log.Debug("File closed") + + mi, err2 := dat.swarmfs.Unmount(dat.testMountDir) + if err2 != nil { + t.Fatalf("Could not unmount %v", err2) + } + log.Debug("Directory unmounted") // mount again and see if things are okay + dat.files["one/2.txt"] = fileInfo{0700, 333, 444, contents} + _ = mountDir(t, ta.api, dat.files, mi.LatestManifest, dat.testMountDir) + log.Debug("Directory mounted again") + + checkFile(t, dat.testMountDir, "one/2.txt", contents) + _, err2 = dat.swarmfs.Unmount(dat.testMountDir) + if err2 != nil { + t.Fatalf("Could not unmount %v", err2) + } + log.Debug("subtest terminated") +} + +func (ta *testAPI) removeExistingFileEncrypted(t *testing.T) { + log.Debug("Starting removeExistingFileEncrypted test") + ta.removeExistingFile(t, true) + log.Debug("Test removeExistingFileEncrypted terminated") +} + +func (ta *testAPI) removeExistingFileNonEncrypted(t *testing.T) { + log.Debug("Starting removeExistingFileNonEncrypted test") + ta.removeExistingFile(t, false) + log.Debug("Test removeExistingFileNonEncrypted terminated") +} + +//remove existing file in mount +func (ta *testAPI) removeExistingFile(t *testing.T, toEncrypt bool) { + dat, err := ta.initSubtest("removeExistingFile") + if err != nil { + t.Fatalf("Couldn't initialize subtest dirs: %v", err) + } + defer os.RemoveAll(dat.testDir) + + dat.toEncrypt = toEncrypt + dat.testUploadDir = filepath.Join(dat.testDir, "remove-upload") + dat.testMountDir = filepath.Join(dat.testDir, "remove-mount") + dat.files = make(map[string]fileInfo) + dat.files["1.txt"] = fileInfo{0700, 333, 444, getRandomBytes(10)} + dat.files["five.txt"] = fileInfo{0700, 333, 444, getRandomBytes(10)} + dat.files["six.txt"] = fileInfo{0700, 333, 444, getRandomBytes(10)} + + dat, err = ta.uploadAndMount(dat, t) + if err != nil { + t.Fatalf("Error during upload of files to swarm / mount of swarm dir: %v", err) + } + defer dat.swarmfs.Stop() + + // Remove a file in the root dir and check + actualPath := filepath.Join(dat.testMountDir, "five.txt") + err = os.Remove(actualPath) + if err != nil { + t.Fatalf("Error removing file! %v", err) + } + mi, err2 := dat.swarmfs.Unmount(dat.testMountDir) + if err2 != nil { + t.Fatalf("Could not unmount %v", err2) + } + log.Debug("Directory unmounted") + + // mount again and see if things are okay + delete(dat.files, "five.txt") + _ = mountDir(t, ta.api, dat.files, mi.LatestManifest, dat.testMountDir) + _, err = os.Stat(actualPath) + if err == nil { + t.Fatal("Expected file to not be present in re-mount after removal, but it is there") + } + _, err2 = dat.swarmfs.Unmount(dat.testMountDir) + if err2 != nil { + t.Fatalf("Could not unmount %v", err2) + } + log.Debug("subtest terminated") +} + +func (ta *testAPI) removeExistingFileInsideDirEncrypted(t *testing.T) { + log.Debug("Starting removeExistingFileInsideDirEncrypted test") + ta.removeExistingFileInsideDir(t, true) + log.Debug("Test removeExistingFileInsideDirEncrypted terminated") +} + +func (ta *testAPI) removeExistingFileInsideDirNonEncrypted(t *testing.T) { + log.Debug("Starting removeExistingFileInsideDirNonEncrypted test") + ta.removeExistingFileInsideDir(t, false) + log.Debug("Test removeExistingFileInsideDirNonEncrypted terminated") +} + +//remove a file inside a directory inside a mount +func (ta *testAPI) removeExistingFileInsideDir(t *testing.T, toEncrypt bool) { + dat, err := ta.initSubtest("removeExistingFileInsideDir") + if err != nil { + t.Fatalf("Couldn't initialize subtest dirs: %v", err) + } + defer os.RemoveAll(dat.testDir) + + dat.toEncrypt = toEncrypt + dat.testUploadDir = filepath.Join(dat.testDir, "remove-upload") + dat.testMountDir = filepath.Join(dat.testDir, "remove-mount") + dat.files = make(map[string]fileInfo) + dat.files["1.txt"] = fileInfo{0700, 333, 444, getRandomBytes(10)} + dat.files["one/five.txt"] = fileInfo{0700, 333, 444, getRandomBytes(10)} + dat.files["one/six.txt"] = fileInfo{0700, 333, 444, getRandomBytes(10)} + + dat, err = ta.uploadAndMount(dat, t) + if err != nil { + t.Fatalf("Error during upload of files to swarm / mount of swarm dir: %v", err) + } + defer dat.swarmfs.Stop() + + // Remove a file in the root dir and check + actualPath := filepath.Join(dat.testMountDir, "one") + actualPath = filepath.Join(actualPath, "five.txt") + err = os.Remove(actualPath) + if err != nil { + t.Fatalf("Error removing file! %v", err) + } + mi, err2 := dat.swarmfs.Unmount(dat.testMountDir) + if err2 != nil { + t.Fatalf("Could not unmount %v", err2) + } + log.Debug("Directory unmounted") + + // mount again and see if things are okay + delete(dat.files, "one/five.txt") + _ = mountDir(t, ta.api, dat.files, mi.LatestManifest, dat.testMountDir) + _, err = os.Stat(actualPath) + if err == nil { + t.Fatal("Expected file to not be present in re-mount after removal, but it is there") + } + + okPath := filepath.Join(dat.testMountDir, "one") + okPath = filepath.Join(okPath, "six.txt") + _, err = os.Stat(okPath) + if err != nil { + t.Fatal("Expected file to be present in re-mount after removal, but it is not there") + } + _, err2 = dat.swarmfs.Unmount(dat.testMountDir) + if err2 != nil { + t.Fatalf("Could not unmount %v", err2) + } + log.Debug("subtest terminated") +} + +func (ta *testAPI) removeNewlyAddedFileEncrypted(t *testing.T) { + log.Debug("Starting removeNewlyAddedFileEncrypted test") + ta.removeNewlyAddedFile(t, true) + log.Debug("Test removeNewlyAddedFileEncrypted terminated") +} + +func (ta *testAPI) removeNewlyAddedFileNonEncrypted(t *testing.T) { + log.Debug("Starting removeNewlyAddedFileNonEncrypted test") + ta.removeNewlyAddedFile(t, false) + log.Debug("Test removeNewlyAddedFileNonEncrypted terminated") +} + +//add a file in mount and then remove it; on remount file should not be there +func (ta *testAPI) removeNewlyAddedFile(t *testing.T, toEncrypt bool) { + dat, err := ta.initSubtest("removeNewlyAddedFile") + if err != nil { + t.Fatalf("Couldn't initialize subtest dirs: %v", err) + } + defer os.RemoveAll(dat.testDir) + + dat.toEncrypt = toEncrypt + dat.testUploadDir = filepath.Join(dat.testDir, "removenew-upload") + dat.testMountDir = filepath.Join(dat.testDir, "removenew-mount") + dat.files = make(map[string]fileInfo) + dat.files["1.txt"] = fileInfo{0700, 333, 444, getRandomBytes(10)} + dat.files["five.txt"] = fileInfo{0700, 333, 444, getRandomBytes(10)} + dat.files["six.txt"] = fileInfo{0700, 333, 444, getRandomBytes(10)} + + dat, err = ta.uploadAndMount(dat, t) + if err != nil { + t.Fatalf("Error during upload of files to swarm / mount of swarm dir: %v", err) + } + defer dat.swarmfs.Stop() + + // Add a a new file and remove it + dirToCreate := filepath.Join(dat.testMountDir, "one") + err = os.MkdirAll(dirToCreate, os.FileMode(0665)) + if err != nil { + t.Fatalf("Error creating dir in mounted dir: %v", err) + } + actualPath := filepath.Join(dirToCreate, "2.txt") + d, err1 := os.OpenFile(actualPath, os.O_RDWR|os.O_CREATE, os.FileMode(0665)) + if err1 != nil { + t.Fatalf("Could not create file %s : %v", actualPath, err1) + } + defer d.Close() + log.Debug("file opened") + contents := make([]byte, 11) + _, err = rand.Read(contents) + if err != nil { + t.Fatalf("Error writing random bytes to byte array: %v", err) + } + log.Debug("content read") + _, err = d.Write(contents) + if err != nil { + t.Fatalf("Error writing random bytes to file: %v", err) + } + log.Debug("content written") + err = d.Close() + if err != nil { + t.Fatalf("Error closing file: %v", err) + } + log.Debug("file closed") + + checkFile(t, dat.testMountDir, "one/2.txt", contents) + log.Debug("file checked") + + err = os.Remove(actualPath) + if err != nil { + t.Fatalf("Error removing file: %v", err) + } + log.Debug("file removed") + + mi, err2 := dat.swarmfs.Unmount(dat.testMountDir) + if err2 != nil { + t.Fatalf("Could not unmount %v", err2) + } + log.Debug("Directory unmounted") + + testMountDir2, err3 := addDir(dat.testDir, "removenew-mount2") + if err3 != nil { + t.Fatalf("Error creating mount dir2: %v", err3) + } + // mount again and see if things are okay + _ = mountDir(t, ta.api, dat.files, mi.LatestManifest, testMountDir2) + log.Debug("Directory mounted again") + + if dat.bzzHash != mi.LatestManifest { + t.Fatalf("same contents different hash orig(%v): new(%v)", dat.bzzHash, mi.LatestManifest) + } + _, err2 = dat.swarmfs.Unmount(testMountDir2) + if err2 != nil { + t.Fatalf("Could not unmount %v", err2) + } + log.Debug("subtest terminated") +} + +func (ta *testAPI) addNewFileAndModifyContentsEncrypted(t *testing.T) { + log.Debug("Starting addNewFileAndModifyContentsEncrypted test") + ta.addNewFileAndModifyContents(t, true) + log.Debug("Test addNewFileAndModifyContentsEncrypted terminated") +} + +func (ta *testAPI) addNewFileAndModifyContentsNonEncrypted(t *testing.T) { + log.Debug("Starting addNewFileAndModifyContentsNonEncrypted test") + ta.addNewFileAndModifyContents(t, false) + log.Debug("Test addNewFileAndModifyContentsNonEncrypted terminated") +} + +//add a new file and modify content; remount and check the modified file is intact +func (ta *testAPI) addNewFileAndModifyContents(t *testing.T, toEncrypt bool) { + dat, err := ta.initSubtest("addNewFileAndModifyContents") + if err != nil { + t.Fatalf("Couldn't initialize subtest dirs: %v", err) + } + defer os.RemoveAll(dat.testDir) + + dat.toEncrypt = toEncrypt + dat.testUploadDir = filepath.Join(dat.testDir, "modifyfile-upload") + dat.testMountDir = filepath.Join(dat.testDir, "modifyfile-mount") + dat.files = make(map[string]fileInfo) + dat.files["1.txt"] = fileInfo{0700, 333, 444, getRandomBytes(10)} + dat.files["five.txt"] = fileInfo{0700, 333, 444, getRandomBytes(10)} + dat.files["six.txt"] = fileInfo{0700, 333, 444, getRandomBytes(10)} + + dat, err = ta.uploadAndMount(dat, t) + if err != nil { + t.Fatalf("Error during upload of files to swarm / mount of swarm dir: %v", err) + } + defer dat.swarmfs.Stop() + + // Create a new file in the root dir + actualPath := filepath.Join(dat.testMountDir, "2.txt") + d, err1 := os.OpenFile(actualPath, os.O_RDWR|os.O_CREATE, os.FileMode(0665)) + if err1 != nil { + t.Fatalf("Could not create file %s : %v", actualPath, err1) + } + defer d.Close() + //write some random data into the file + log.Debug("file opened") + line1 := []byte("Line 1") + _, err = rand.Read(line1) + if err != nil { + t.Fatalf("Error writing random bytes to byte array: %v", err) + } + log.Debug("line read") + _, err = d.Write(line1) + if err != nil { + t.Fatalf("Error writing random bytes to file: %v", err) + } + log.Debug("line written") + err = d.Close() + if err != nil { + t.Fatalf("Error closing file: %v", err) + } + log.Debug("file closed") + + //unmount the hash on the mounted dir + mi1, err2 := dat.swarmfs.Unmount(dat.testMountDir) + if err2 != nil { + t.Fatalf("Could not unmount %v", err2) + } + log.Debug("Directory unmounted") + + //mount on a different dir to see if modified file is correct + testMountDir2, err3 := addDir(dat.testDir, "modifyfile-mount2") + if err3 != nil { + t.Fatalf("Error creating mount dir2: %v", err3) + } + dat.files["2.txt"] = fileInfo{0700, 333, 444, line1} + _ = mountDir(t, ta.api, dat.files, mi1.LatestManifest, testMountDir2) + log.Debug("Directory mounted again") + + checkFile(t, testMountDir2, "2.txt", line1) + log.Debug("file checked") + + //unmount second dir + mi2, err4 := dat.swarmfs.Unmount(testMountDir2) + if err4 != nil { + t.Fatalf("Could not unmount %v", err4) + } + log.Debug("Directory unmounted again") + + //mount again on original dir and modify the file + //let's clean up the mounted dir first: remove... + err = os.RemoveAll(dat.testMountDir) + if err != nil { + t.Fatalf("Error cleaning up mount dir: %v", err) + } + //...and re-create + err = os.MkdirAll(dat.testMountDir, 0777) + if err != nil { + t.Fatalf("Error re-creating mount dir: %v", err) + } + //now remount + _ = mountDir(t, ta.api, dat.files, mi2.LatestManifest, dat.testMountDir) + log.Debug("Directory mounted yet again") + + //open the file.... + fd, err5 := os.OpenFile(actualPath, os.O_RDWR|os.O_APPEND, os.FileMode(0665)) + if err5 != nil { + t.Fatalf("Could not create file %s : %v", actualPath, err5) + } + defer fd.Close() + log.Debug("file opened") + //...and modify something + line2 := []byte("Line 2") + _, err = rand.Read(line2) + if err != nil { + t.Fatalf("Error modifying random bytes to byte array: %v", err) + } + log.Debug("line read") + _, err = fd.Seek(int64(len(line1)), 0) + if err != nil { + t.Fatalf("Error seeking position for modification: %v", err) + } + _, err = fd.Write(line2) + if err != nil { + t.Fatalf("Error modifying file: %v", err) + } + log.Debug("line written") + err = fd.Close() + if err != nil { + t.Fatalf("Error closing modified file; %v", err) + } + log.Debug("file closed") + + //unmount the modified directory + mi3, err6 := dat.swarmfs.Unmount(dat.testMountDir) + if err6 != nil { + t.Fatalf("Could not unmount %v", err6) + } + log.Debug("Directory unmounted yet again") + + //now remount on a different dir and check that the modified file is ok + testMountDir4, err7 := addDir(dat.testDir, "modifyfile-mount4") + if err7 != nil { + t.Fatalf("Could not unmount %v", err7) + } b := [][]byte{line1, line2} line1and2 := bytes.Join(b, []byte("")) - files["2.txt"] = fileInfo{0700, 333, 444, line1and2} - swarmfs4 := mountDir(t, ta.api, files, mi3.LatestManifest, testMountDir) - defer swarmfs4.Stop() + dat.files["2.txt"] = fileInfo{0700, 333, 444, line1and2} + _ = mountDir(t, ta.api, dat.files, mi3.LatestManifest, testMountDir4) + log.Debug("Directory mounted final time") - checkFile(t, testMountDir, "2.txt", line1and2) + checkFile(t, testMountDir4, "2.txt", line1and2) + _, err = dat.swarmfs.Unmount(testMountDir4) + if err != nil { + t.Fatalf("Could not unmount %v", err) + } + log.Debug("subtest terminated") } -func (ta *testAPI) removeEmptyDir(t *testing.T) { - files := make(map[string]fileInfo) - testUploadDir, _ := ioutil.TempDir(os.TempDir(), "rmdir-upload") - testMountDir, _ := ioutil.TempDir(os.TempDir(), "rmdir-mount") +func (ta *testAPI) removeEmptyDirEncrypted(t *testing.T) { + log.Debug("Starting removeEmptyDirEncrypted test") + ta.removeEmptyDir(t, true) + log.Debug("Test removeEmptyDirEncrypted terminated") +} - files["1.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} - files["five.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} - files["six.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} - bzzHash := createTestFilesAndUploadToSwarm(t, ta.api, files, testUploadDir) +func (ta *testAPI) removeEmptyDirNonEncrypted(t *testing.T) { + log.Debug("Starting removeEmptyDirNonEncrypted test") + ta.removeEmptyDir(t, false) + log.Debug("Test removeEmptyDirNonEncrypted terminated") +} - swarmfs1 := mountDir(t, ta.api, files, bzzHash, testMountDir) - defer swarmfs1.Stop() +//remove an empty dir inside mount +func (ta *testAPI) removeEmptyDir(t *testing.T, toEncrypt bool) { + dat, err := ta.initSubtest("removeEmptyDir") + if err != nil { + t.Fatalf("Couldn't initialize subtest dirs: %v", err) + } + defer os.RemoveAll(dat.testDir) - os.MkdirAll(filepath.Join(testMountDir, "newdir"), 0777) + dat.toEncrypt = toEncrypt + dat.testUploadDir = filepath.Join(dat.testDir, "rmdir-upload") + dat.testMountDir = filepath.Join(dat.testDir, "rmdir-mount") + dat.files = make(map[string]fileInfo) + dat.files["1.txt"] = fileInfo{0700, 333, 444, getRandomBytes(10)} + dat.files["five.txt"] = fileInfo{0700, 333, 444, getRandomBytes(10)} + dat.files["six.txt"] = fileInfo{0700, 333, 444, getRandomBytes(10)} - mi, err3 := swarmfs1.Unmount(testMountDir) + dat, err = ta.uploadAndMount(dat, t) + if err != nil { + t.Fatalf("Error during upload of files to swarm / mount of swarm dir: %v", err) + } + defer dat.swarmfs.Stop() + + _, err2 := addDir(dat.testMountDir, "newdir") + if err2 != nil { + t.Fatalf("Could not unmount %v", err2) + } + mi, err := dat.swarmfs.Unmount(dat.testMountDir) + if err != nil { + t.Fatalf("Could not unmount %v", err) + } + log.Debug("Directory unmounted") + //by just adding an empty dir, the hash doesn't change; test this + if dat.bzzHash != mi.LatestManifest { + t.Fatalf("same contents different hash orig(%v): new(%v)", dat.bzzHash, mi.LatestManifest) + } + log.Debug("subtest terminated") +} + +func (ta *testAPI) removeDirWhichHasFilesEncrypted(t *testing.T) { + log.Debug("Starting removeDirWhichHasFilesEncrypted test") + ta.removeDirWhichHasFiles(t, true) + log.Debug("Test removeDirWhichHasFilesEncrypted terminated") +} +func (ta *testAPI) removeDirWhichHasFilesNonEncrypted(t *testing.T) { + log.Debug("Starting removeDirWhichHasFilesNonEncrypted test") + ta.removeDirWhichHasFiles(t, false) + log.Debug("Test removeDirWhichHasFilesNonEncrypted terminated") +} + +//remove a directory with a file; check on remount file isn't there +func (ta *testAPI) removeDirWhichHasFiles(t *testing.T, toEncrypt bool) { + dat, err := ta.initSubtest("removeDirWhichHasFiles") + if err != nil { + t.Fatalf("Couldn't initialize subtest dirs: %v", err) + } + defer os.RemoveAll(dat.testDir) + + dat.toEncrypt = toEncrypt + dat.testUploadDir = filepath.Join(dat.testDir, "rmdir-upload") + dat.testMountDir = filepath.Join(dat.testDir, "rmdir-mount") + dat.files = make(map[string]fileInfo) + dat.files["one/1.txt"] = fileInfo{0700, 333, 444, getRandomBytes(10)} + dat.files["two/five.txt"] = fileInfo{0700, 333, 444, getRandomBytes(10)} + dat.files["two/six.txt"] = fileInfo{0700, 333, 444, getRandomBytes(10)} + + dat, err = ta.uploadAndMount(dat, t) + if err != nil { + t.Fatalf("Error during upload of files to swarm / mount of swarm dir: %v", err) + } + defer dat.swarmfs.Stop() + + //delete a directory inside the mounted dir with all its files + dirPath := filepath.Join(dat.testMountDir, "two") + err = os.RemoveAll(dirPath) + if err != nil { + t.Fatalf("Error removing directory in mounted dir: %v", err) + } + + mi, err2 := dat.swarmfs.Unmount(dat.testMountDir) + if err2 != nil { + t.Fatalf("Could not unmount %v ", err2) + } + log.Debug("Directory unmounted") + + //we deleted files in the OS, so let's delete them also in the files map + delete(dat.files, "two/five.txt") + delete(dat.files, "two/six.txt") + + // mount again and see if deleted files have been deleted indeed + testMountDir2, err3 := addDir(dat.testDir, "remount-mount2") if err3 != nil { t.Fatalf("Could not unmount %v", err3) } - if bzzHash != mi.LatestManifest { - t.Fatalf("same contents different hash orig(%v): new(%v)", bzzHash, mi.LatestManifest) + _ = mountDir(t, ta.api, dat.files, mi.LatestManifest, testMountDir2) + log.Debug("Directory mounted") + actualPath := filepath.Join(dirPath, "five.txt") + _, err = os.Stat(actualPath) + if err == nil { + t.Fatal("Expected file to not be present in re-mount after removal, but it is there") } + _, err = os.Stat(dirPath) + if err == nil { + t.Fatal("Expected file to not be present in re-mount after removal, but it is there") + } + _, err = dat.swarmfs.Unmount(testMountDir2) + if err != nil { + t.Fatalf("Could not unmount %v", err) + } + log.Debug("subtest terminated") } -func (ta *testAPI) removeDirWhichHasFiles(t *testing.T) { - files := make(map[string]fileInfo) - testUploadDir, _ := ioutil.TempDir(os.TempDir(), "rmdir-upload") - testMountDir, _ := ioutil.TempDir(os.TempDir(), "rmdir-mount") +func (ta *testAPI) removeDirWhichHasSubDirsEncrypted(t *testing.T) { + log.Debug("Starting removeDirWhichHasSubDirsEncrypted test") + ta.removeDirWhichHasSubDirs(t, true) + log.Debug("Test removeDirWhichHasSubDirsEncrypted terminated") +} - files["one/1.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} - files["two/five.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} - files["two/six.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} - bzzHash := createTestFilesAndUploadToSwarm(t, ta.api, files, testUploadDir) +func (ta *testAPI) removeDirWhichHasSubDirsNonEncrypted(t *testing.T) { + log.Debug("Starting removeDirWhichHasSubDirsNonEncrypted test") + ta.removeDirWhichHasSubDirs(t, false) + log.Debug("Test removeDirWhichHasSubDirsNonEncrypted terminated") +} - swarmfs1 := mountDir(t, ta.api, files, bzzHash, testMountDir) - defer swarmfs1.Stop() +//remove a directory with subdirectories inside mount; on remount check they are not there +func (ta *testAPI) removeDirWhichHasSubDirs(t *testing.T, toEncrypt bool) { + dat, err := ta.initSubtest("removeDirWhichHasSubDirs") + if err != nil { + t.Fatalf("Couldn't initialize subtest dirs: %v", err) + } + defer os.RemoveAll(dat.testDir) - dirPath := filepath.Join(testMountDir, "two") - os.RemoveAll(dirPath) + dat.toEncrypt = toEncrypt + dat.testUploadDir = filepath.Join(dat.testDir, "rmsubdir-upload") + dat.testMountDir = filepath.Join(dat.testDir, "rmsubdir-mount") + dat.files = make(map[string]fileInfo) + dat.files["one/1.txt"] = fileInfo{0700, 333, 444, getRandomBytes(10)} + dat.files["two/three/2.txt"] = fileInfo{0700, 333, 444, getRandomBytes(10)} + dat.files["two/three/3.txt"] = fileInfo{0700, 333, 444, getRandomBytes(10)} + dat.files["two/four/5.txt"] = fileInfo{0700, 333, 444, getRandomBytes(10)} + dat.files["two/four/6.txt"] = fileInfo{0700, 333, 444, getRandomBytes(10)} + dat.files["two/four/six/7.txt"] = fileInfo{0700, 333, 444, getRandomBytes(10)} - mi, err2 := swarmfs1.Unmount(testMountDir) + dat, err = ta.uploadAndMount(dat, t) + if err != nil { + t.Fatalf("Error during upload of files to swarm / mount of swarm dir: %v", err) + } + defer dat.swarmfs.Stop() + + dirPath := filepath.Join(dat.testMountDir, "two") + err = os.RemoveAll(dirPath) + if err != nil { + t.Fatalf("Error removing directory in mounted dir: %v", err) + } + + //delete a directory inside the mounted dir with all its files + mi, err2 := dat.swarmfs.Unmount(dat.testMountDir) if err2 != nil { t.Fatalf("Could not unmount %v ", err2) } + log.Debug("Directory unmounted") + + //we deleted files in the OS, so let's delete them also in the files map + delete(dat.files, "two/three/2.txt") + delete(dat.files, "two/three/3.txt") + delete(dat.files, "two/four/5.txt") + delete(dat.files, "two/four/6.txt") + delete(dat.files, "two/four/six/7.txt") // mount again and see if things are okay - delete(files, "two/five.txt") - delete(files, "two/six.txt") - - swarmfs2 := mountDir(t, ta.api, files, mi.LatestManifest, testMountDir) - defer swarmfs2.Stop() -} - -func (ta *testAPI) removeDirWhichHasSubDirs(t *testing.T) { - files := make(map[string]fileInfo) - testUploadDir, _ := ioutil.TempDir(os.TempDir(), "rmsubdir-upload") - testMountDir, _ := ioutil.TempDir(os.TempDir(), "rmsubdir-mount") - - files["one/1.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} - files["two/three/2.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} - files["two/three/3.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} - files["two/four/5.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} - files["two/four/6.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} - files["two/four/six/7.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)} - - bzzHash := createTestFilesAndUploadToSwarm(t, ta.api, files, testUploadDir) - - swarmfs1 := mountDir(t, ta.api, files, bzzHash, testMountDir) - defer swarmfs1.Stop() - - dirPath := filepath.Join(testMountDir, "two") - os.RemoveAll(dirPath) - - mi, err2 := swarmfs1.Unmount(testMountDir) - if err2 != nil { - t.Fatalf("Could not unmount %v ", err2) + testMountDir2, err3 := addDir(dat.testDir, "remount-mount2") + if err3 != nil { + t.Fatalf("Could not unmount %v", err3) } - - // mount again and see if things are okay - delete(files, "two/three/2.txt") - delete(files, "two/three/3.txt") - delete(files, "two/four/5.txt") - delete(files, "two/four/6.txt") - delete(files, "two/four/six/7.txt") - - swarmfs2 := mountDir(t, ta.api, files, mi.LatestManifest, testMountDir) - defer swarmfs2.Stop() + _ = mountDir(t, ta.api, dat.files, mi.LatestManifest, testMountDir2) + log.Debug("Directory mounted again") + actualPath := filepath.Join(dirPath, "three") + actualPath = filepath.Join(actualPath, "2.txt") + _, err = os.Stat(actualPath) + if err == nil { + t.Fatal("Expected file to not be present in re-mount after removal, but it is there") + } + actualPath = filepath.Join(dirPath, "four") + _, err = os.Stat(actualPath) + if err == nil { + t.Fatal("Expected file to not be present in re-mount after removal, but it is there") + } + _, err = os.Stat(dirPath) + if err == nil { + t.Fatal("Expected file to not be present in re-mount after removal, but it is there") + } + _, err = dat.swarmfs.Unmount(testMountDir2) + if err != nil { + t.Fatalf("Could not unmount %v", err) + } + log.Debug("subtest terminated") } -func (ta *testAPI) appendFileContentsToEnd(t *testing.T) { - files := make(map[string]fileInfo) - testUploadDir, _ := ioutil.TempDir(os.TempDir(), "appendlargefile-upload") - testMountDir, _ := ioutil.TempDir(os.TempDir(), "appendlargefile-mount") +func (ta *testAPI) appendFileContentsToEndEncrypted(t *testing.T) { + log.Debug("Starting appendFileContentsToEndEncrypted test") + ta.appendFileContentsToEnd(t, true) + log.Debug("Test appendFileContentsToEndEncrypted terminated") +} + +func (ta *testAPI) appendFileContentsToEndNonEncrypted(t *testing.T) { + log.Debug("Starting appendFileContentsToEndNonEncrypted test") + ta.appendFileContentsToEnd(t, false) + log.Debug("Test appendFileContentsToEndNonEncrypted terminated") +} + +//append contents to the end of a file; remount and check it's intact +func (ta *testAPI) appendFileContentsToEnd(t *testing.T, toEncrypt bool) { + dat, err := ta.initSubtest("appendFileContentsToEnd") + if err != nil { + t.Fatalf("Couldn't initialize subtest dirs: %v", err) + } + defer os.RemoveAll(dat.testDir) + + dat.toEncrypt = toEncrypt + dat.testUploadDir = filepath.Join(dat.testDir, "appendlargefile-upload") + dat.testMountDir = filepath.Join(dat.testDir, "appendlargefile-mount") + dat.files = make(map[string]fileInfo) line1 := make([]byte, 10) - rand.Read(line1) - files["1.txt"] = fileInfo{0700, 333, 444, line1} - bzzHash := createTestFilesAndUploadToSwarm(t, ta.api, files, testUploadDir) + _, err = rand.Read(line1) + if err != nil { + t.Fatalf("Error writing random bytes to byte array: %v", err) + } - swarmfs1 := mountDir(t, ta.api, files, bzzHash, testMountDir) - defer swarmfs1.Stop() + dat.files["1.txt"] = fileInfo{0700, 333, 444, line1} - actualPath := filepath.Join(testMountDir, "1.txt") + dat, err = ta.uploadAndMount(dat, t) + if err != nil { + t.Fatalf("Error during upload of files to swarm / mount of swarm dir: %v", err) + } + defer dat.swarmfs.Stop() + + actualPath := filepath.Join(dat.testMountDir, "1.txt") fd, err4 := os.OpenFile(actualPath, os.O_RDWR|os.O_APPEND, os.FileMode(0665)) if err4 != nil { t.Fatalf("Could not create file %s : %v", actualPath, err4) } + defer fd.Close() + log.Debug("file opened") line2 := make([]byte, 5) - rand.Read(line2) - fd.Seek(int64(len(line1)), 0) - fd.Write(line2) - fd.Close() + _, err = rand.Read(line2) + if err != nil { + t.Fatalf("Error writing random bytes to byte array: %v", err) + } + log.Debug("line read") + _, err = fd.Seek(int64(len(line1)), 0) + if err != nil { + t.Fatalf("Error searching for position to append: %v", err) + } + _, err = fd.Write(line2) + if err != nil { + t.Fatalf("Error appending: %v", err) + } + log.Debug("line written") + err = fd.Close() + if err != nil { + t.Fatalf("Error closing file: %v", err) + } + log.Debug("file closed") - mi1, err5 := swarmfs1.Unmount(testMountDir) + mi1, err5 := dat.swarmfs.Unmount(dat.testMountDir) if err5 != nil { t.Fatalf("Could not unmount %v ", err5) } + log.Debug("Directory unmounted") - // mount again and see if things are okay + // mount again and see if appended file is correct b := [][]byte{line1, line2} line1and2 := bytes.Join(b, []byte("")) - files["1.txt"] = fileInfo{0700, 333, 444, line1and2} - swarmfs2 := mountDir(t, ta.api, files, mi1.LatestManifest, testMountDir) - defer swarmfs2.Stop() + dat.files["1.txt"] = fileInfo{0700, 333, 444, line1and2} + testMountDir2, err6 := addDir(dat.testDir, "remount-mount2") + if err6 != nil { + t.Fatalf("Could not unmount %v", err6) + } + _ = mountDir(t, ta.api, dat.files, mi1.LatestManifest, testMountDir2) + log.Debug("Directory mounted") - checkFile(t, testMountDir, "1.txt", line1and2) + checkFile(t, testMountDir2, "1.txt", line1and2) + + _, err = dat.swarmfs.Unmount(testMountDir2) + if err != nil { + t.Fatalf("Could not unmount %v", err) + } + log.Debug("subtest terminated") } +//run all the tests func TestFUSE(t *testing.T) { + t.Skip("disable fuse tests until they are stable") + //create a data directory for swarm datadir, err := ioutil.TempDir("", "fuse") if err != nil { t.Fatalf("unable to create temp dir: %v", err) } - os.RemoveAll(datadir) + defer os.RemoveAll(datadir) - dpa, err := storage.NewLocalDPA(datadir) + fileStore, err := storage.NewLocalFileStore(datadir, make([]byte, 32)) if err != nil { t.Fatal(err) } - ta := &testAPI{api: api.NewApi(dpa, nil)} - dpa.Start() - defer dpa.Stop() + ta := &testAPI{api: api.NewAPI(fileStore, nil, nil)} - t.Run("mountListAndUmount", ta.mountListAndUnmount) - t.Run("maxMounts", ta.maxMounts) - t.Run("remount", ta.remount) - t.Run("unmount", ta.unmount) - t.Run("unmountWhenResourceBusy", ta.unmountWhenResourceBusy) - t.Run("seekInMultiChunkFile", ta.seekInMultiChunkFile) - t.Run("createNewFile", ta.createNewFile) - t.Run("createNewFileInsideDirectory", ta.createNewFileInsideDirectory) - t.Run("createNewFileInsideNewDirectory", ta.createNewFileInsideNewDirectory) - t.Run("removeExistingFile", ta.removeExistingFile) - t.Run("removeExistingFileInsideDir", ta.removeExistingFileInsideDir) - t.Run("removeNewlyAddedFile", ta.removeNewlyAddedFile) - t.Run("addNewFileAndModifyContents", ta.addNewFileAndModifyContents) - t.Run("removeEmptyDir", ta.removeEmptyDir) - t.Run("removeDirWhichHasFiles", ta.removeDirWhichHasFiles) - t.Run("removeDirWhichHasSubDirs", ta.removeDirWhichHasSubDirs) - t.Run("appendFileContentsToEnd", ta.appendFileContentsToEnd) + //run a short suite of tests + //approx time: 28s + t.Run("mountListAndUnmountEncrypted", ta.mountListAndUnmountEncrypted) + t.Run("remountEncrypted", ta.remountEncrypted) + t.Run("unmountWhenResourceBusyNonEncrypted", ta.unmountWhenResourceBusyNonEncrypted) + t.Run("removeExistingFileEncrypted", ta.removeExistingFileEncrypted) + t.Run("addNewFileAndModifyContentsNonEncrypted", ta.addNewFileAndModifyContentsNonEncrypted) + t.Run("removeDirWhichHasFilesNonEncrypted", ta.removeDirWhichHasFilesNonEncrypted) + t.Run("appendFileContentsToEndEncrypted", ta.appendFileContentsToEndEncrypted) + + //provide longrunning flag to execute all tests + //approx time with longrunning: 140s + if *longrunning { + t.Run("mountListAndUnmountNonEncrypted", ta.mountListAndUnmountNonEncrypted) + t.Run("maxMountsEncrypted", ta.maxMountsEncrypted) + t.Run("maxMountsNonEncrypted", ta.maxMountsNonEncrypted) + t.Run("remountNonEncrypted", ta.remountNonEncrypted) + t.Run("unmountEncrypted", ta.unmountEncrypted) + t.Run("unmountNonEncrypted", ta.unmountNonEncrypted) + t.Run("unmountWhenResourceBusyEncrypted", ta.unmountWhenResourceBusyEncrypted) + t.Run("unmountWhenResourceBusyNonEncrypted", ta.unmountWhenResourceBusyNonEncrypted) + t.Run("seekInMultiChunkFileEncrypted", ta.seekInMultiChunkFileEncrypted) + t.Run("seekInMultiChunkFileNonEncrypted", ta.seekInMultiChunkFileNonEncrypted) + t.Run("createNewFileEncrypted", ta.createNewFileEncrypted) + t.Run("createNewFileNonEncrypted", ta.createNewFileNonEncrypted) + t.Run("createNewFileInsideDirectoryEncrypted", ta.createNewFileInsideDirectoryEncrypted) + t.Run("createNewFileInsideDirectoryNonEncrypted", ta.createNewFileInsideDirectoryNonEncrypted) + t.Run("createNewFileInsideNewDirectoryEncrypted", ta.createNewFileInsideNewDirectoryEncrypted) + t.Run("createNewFileInsideNewDirectoryNonEncrypted", ta.createNewFileInsideNewDirectoryNonEncrypted) + t.Run("removeExistingFileNonEncrypted", ta.removeExistingFileNonEncrypted) + t.Run("removeExistingFileInsideDirEncrypted", ta.removeExistingFileInsideDirEncrypted) + t.Run("removeExistingFileInsideDirNonEncrypted", ta.removeExistingFileInsideDirNonEncrypted) + t.Run("removeNewlyAddedFileEncrypted", ta.removeNewlyAddedFileEncrypted) + t.Run("removeNewlyAddedFileNonEncrypted", ta.removeNewlyAddedFileNonEncrypted) + t.Run("addNewFileAndModifyContentsEncrypted", ta.addNewFileAndModifyContentsEncrypted) + t.Run("removeEmptyDirEncrypted", ta.removeEmptyDirEncrypted) + t.Run("removeEmptyDirNonEncrypted", ta.removeEmptyDirNonEncrypted) + t.Run("removeDirWhichHasFilesEncrypted", ta.removeDirWhichHasFilesEncrypted) + t.Run("removeDirWhichHasSubDirsEncrypted", ta.removeDirWhichHasSubDirsEncrypted) + t.Run("removeDirWhichHasSubDirsNonEncrypted", ta.removeDirWhichHasSubDirsNonEncrypted) + t.Run("appendFileContentsToEndNonEncrypted", ta.appendFileContentsToEndNonEncrypted) + } } diff --git a/swarm/fuse/swarmfs_unix.go b/swarm/fuse/swarmfs_unix.go index 75742845a2..9ff55cc324 100644 --- a/swarm/fuse/swarmfs_unix.go +++ b/swarm/fuse/swarmfs_unix.go @@ -19,6 +19,7 @@ package fuse import ( + "context" "errors" "fmt" "os" @@ -30,15 +31,16 @@ import ( "bazil.org/fuse" "bazil.org/fuse/fs" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/swarm/api" + "github.com/ethereum/go-ethereum/swarm/log" ) var ( - errEmptyMountPoint = errors.New("need non-empty mount point") - errMaxMountCount = errors.New("max FUSE mount count reached") - errMountTimeout = errors.New("mount timeout") - errAlreadyMounted = errors.New("mount point is already serving") + errEmptyMountPoint = errors.New("need non-empty mount point") + errNoRelativeMountPoint = errors.New("invalid path for mount point (need absolute path)") + errMaxMountCount = errors.New("max FUSE mount count reached") + errMountTimeout = errors.New("mount timeout") + errAlreadyMounted = errors.New("mount point is already serving") ) func isFUSEUnsupportedError(err error) bool { @@ -48,18 +50,20 @@ func isFUSEUnsupportedError(err error) bool { return err == fuse.ErrOSXFUSENotFound } -// information about every active mount +// MountInfo contains information about every active mount type MountInfo struct { MountPoint string StartManifest string LatestManifest string rootDir *SwarmDir fuseConnection *fuse.Conn - swarmApi *api.Api + swarmApi *api.API lock *sync.RWMutex + serveClose chan struct{} } -func NewMountInfo(mhash, mpoint string, sapi *api.Api) *MountInfo { +func NewMountInfo(mhash, mpoint string, sapi *api.API) *MountInfo { + log.Debug("swarmfs NewMountInfo", "hash", mhash, "mount point", mpoint) newMountInfo := &MountInfo{ MountPoint: mpoint, StartManifest: mhash, @@ -68,50 +72,61 @@ func NewMountInfo(mhash, mpoint string, sapi *api.Api) *MountInfo { fuseConnection: nil, swarmApi: sapi, lock: &sync.RWMutex{}, + serveClose: make(chan struct{}), } return newMountInfo } -func (self *SwarmFS) Mount(mhash, mountpoint string) (*MountInfo, error) { - +func (swarmfs *SwarmFS) Mount(mhash, mountpoint string) (*MountInfo, error) { + log.Info("swarmfs", "mounting hash", mhash, "mount point", mountpoint) if mountpoint == "" { return nil, errEmptyMountPoint } + if !strings.HasPrefix(mountpoint, "/") { + return nil, errNoRelativeMountPoint + } cleanedMountPoint, err := filepath.Abs(filepath.Clean(mountpoint)) if err != nil { return nil, err } + log.Trace("swarmfs mount", "cleanedMountPoint", cleanedMountPoint) - self.swarmFsLock.Lock() - defer self.swarmFsLock.Unlock() + swarmfs.swarmFsLock.Lock() + defer swarmfs.swarmFsLock.Unlock() - noOfActiveMounts := len(self.activeMounts) + noOfActiveMounts := len(swarmfs.activeMounts) + log.Debug("swarmfs mount", "# active mounts", noOfActiveMounts) if noOfActiveMounts >= maxFuseMounts { return nil, errMaxMountCount } - if _, ok := self.activeMounts[cleanedMountPoint]; ok { + if _, ok := swarmfs.activeMounts[cleanedMountPoint]; ok { return nil, errAlreadyMounted } - log.Info(fmt.Sprintf("Attempting to mount %s ", cleanedMountPoint)) - _, manifestEntryMap, err := self.swarmApi.BuildDirectoryTree(mhash, true) + log.Trace("swarmfs mount: getting manifest tree") + _, manifestEntryMap, err := swarmfs.swarmApi.BuildDirectoryTree(context.TODO(), mhash, true) if err != nil { return nil, err } - mi := NewMountInfo(mhash, cleanedMountPoint, self.swarmApi) + log.Trace("swarmfs mount: building mount info") + mi := NewMountInfo(mhash, cleanedMountPoint, swarmfs.swarmApi) dirTree := map[string]*SwarmDir{} rootDir := NewSwarmDir("/", mi) - dirTree["/"] = rootDir + log.Trace("swarmfs mount", "rootDir", rootDir) mi.rootDir = rootDir + log.Trace("swarmfs mount: traversing manifest map") for suffix, entry := range manifestEntryMap { - key := common.Hex2Bytes(entry.Hash) + if suffix == "" { //empty suffix means that the file has no name - i.e. this is the default entry in a manifest. Since we cannot have files without a name, let us ignore this entry + log.Warn("Manifest has an empty-path (default) entry which will be ignored in FUSE mount.") + continue + } + addr := common.Hex2Bytes(entry.Hash) fullpath := "/" + suffix basepath := filepath.Dir(fullpath) - parentDir := rootDir dirUntilNow := "" paths := strings.Split(basepath, "/") @@ -128,105 +143,143 @@ func (self *SwarmFS) Mount(mhash, mountpoint string) (*MountInfo, error) { } else { parentDir = dirTree[dirUntilNow] } - } } thisFile := NewSwarmFile(basepath, filepath.Base(fullpath), mi) - thisFile.key = key + thisFile.addr = addr parentDir.files = append(parentDir.files, thisFile) } fconn, err := fuse.Mount(cleanedMountPoint, fuse.FSName("swarmfs"), fuse.VolumeName(mhash)) if isFUSEUnsupportedError(err) { - log.Warn("Fuse not installed", "mountpoint", cleanedMountPoint, "err", err) + log.Error("swarmfs error - FUSE not installed", "mountpoint", cleanedMountPoint, "err", err) return nil, err } else if err != nil { fuse.Unmount(cleanedMountPoint) - log.Warn("Error mounting swarm manifest", "mountpoint", cleanedMountPoint, "err", err) + log.Error("swarmfs error mounting swarm manifest", "mountpoint", cleanedMountPoint, "err", err) return nil, err } mi.fuseConnection = fconn serverr := make(chan error, 1) go func() { - log.Info(fmt.Sprintf("Serving %s at %s", mhash, cleanedMountPoint)) + log.Info("swarmfs", "serving hash", mhash, "at", cleanedMountPoint) filesys := &SwarmRoot{root: rootDir} + //start serving the actual file system; see note below if err := fs.Serve(fconn, filesys); err != nil { - log.Warn(fmt.Sprintf("Could not Serve SwarmFileSystem error: %v", err)) + log.Warn("swarmfs could not serve the requested hash", "error", err) serverr <- err } - + mi.serveClose <- struct{}{} }() + /* + IMPORTANT NOTE: the fs.Serve function is blocking; + Serve builds up the actual fuse file system by calling the + Attr functions on each SwarmFile, creating the file inodes; + specifically calling the swarm's LazySectionReader.Size() to set the file size. + + This can take some time, and it appears that if we access the fuse file system + too early, we can bring the tests to deadlock. The assumption so far is that + at this point, the fuse driver didn't finish to initialize the file system. + + Accessing files too early not only deadlocks the tests, but locks the access + of the fuse file completely, resulting in blocked resources at OS system level. + Even a simple `ls /tmp/testDir/testMountDir` could deadlock in a shell. + + Workaround so far is to wait some time to give the OS enough time to initialize + the fuse file system. During tests, this seemed to address the issue. + + HOWEVER IT SHOULD BE NOTED THAT THIS MAY ONLY BE AN EFFECT, + AND THE DEADLOCK CAUSED BY SOMETHING ELSE BLOCKING ACCESS DUE TO SOME RACE CONDITION + (caused in the bazil.org library and/or the SwarmRoot, SwarmDir and SwarmFile implementations) + */ + time.Sleep(2 * time.Second) + + timer := time.NewTimer(mountTimeout) + defer timer.Stop() // Check if the mount process has an error to report. select { - case <-time.After(mountTimeout): - fuse.Unmount(cleanedMountPoint) + case <-timer.C: + log.Warn("swarmfs timed out mounting over FUSE", "mountpoint", cleanedMountPoint, "err", err) + err := fuse.Unmount(cleanedMountPoint) + if err != nil { + return nil, err + } return nil, errMountTimeout - case err := <-serverr: - fuse.Unmount(cleanedMountPoint) - log.Warn("Error serving swarm FUSE FS", "mountpoint", cleanedMountPoint, "err", err) + log.Warn("swarmfs error serving over FUSE", "mountpoint", cleanedMountPoint, "err", err) + err = fuse.Unmount(cleanedMountPoint) return nil, err case <-fconn.Ready: - log.Info("Now serving swarm FUSE FS", "manifest", mhash, "mountpoint", cleanedMountPoint) + //this signals that the actual mount point from the fuse.Mount call is ready; + //it does not signal though that the file system from fs.Serve is actually fully built up + if err := fconn.MountError; err != nil { + log.Error("Mounting error from fuse driver: ", "err", err) + return nil, err + } + log.Info("swarmfs now served over FUSE", "manifest", mhash, "mountpoint", cleanedMountPoint) } - self.activeMounts[cleanedMountPoint] = mi + timer.Stop() + swarmfs.activeMounts[cleanedMountPoint] = mi return mi, nil } -func (self *SwarmFS) Unmount(mountpoint string) (*MountInfo, error) { - - self.swarmFsLock.Lock() - defer self.swarmFsLock.Unlock() +func (swarmfs *SwarmFS) Unmount(mountpoint string) (*MountInfo, error) { + swarmfs.swarmFsLock.Lock() + defer swarmfs.swarmFsLock.Unlock() cleanedMountPoint, err := filepath.Abs(filepath.Clean(mountpoint)) if err != nil { return nil, err } - mountInfo := self.activeMounts[cleanedMountPoint] + mountInfo := swarmfs.activeMounts[cleanedMountPoint] if mountInfo == nil || mountInfo.MountPoint != cleanedMountPoint { - return nil, fmt.Errorf("%s is not mounted", cleanedMountPoint) + return nil, fmt.Errorf("swarmfs %s is not mounted", cleanedMountPoint) } err = fuse.Unmount(cleanedMountPoint) if err != nil { err1 := externalUnmount(cleanedMountPoint) if err1 != nil { - errStr := fmt.Sprintf("UnMount error: %v", err) + errStr := fmt.Sprintf("swarmfs unmount error: %v", err) log.Warn(errStr) return nil, err1 } } - mountInfo.fuseConnection.Close() - delete(self.activeMounts, cleanedMountPoint) + err = mountInfo.fuseConnection.Close() + if err != nil { + return nil, err + } + delete(swarmfs.activeMounts, cleanedMountPoint) - succString := fmt.Sprintf("UnMounting %v succeeded", cleanedMountPoint) + <-mountInfo.serveClose + + succString := fmt.Sprintf("swarmfs unmounting %v succeeded", cleanedMountPoint) log.Info(succString) return mountInfo, nil } -func (self *SwarmFS) Listmounts() []*MountInfo { - self.swarmFsLock.RLock() - defer self.swarmFsLock.RUnlock() - - rows := make([]*MountInfo, 0, len(self.activeMounts)) - for _, mi := range self.activeMounts { +func (swarmfs *SwarmFS) Listmounts() []*MountInfo { + swarmfs.swarmFsLock.RLock() + defer swarmfs.swarmFsLock.RUnlock() + rows := make([]*MountInfo, 0, len(swarmfs.activeMounts)) + for _, mi := range swarmfs.activeMounts { rows = append(rows, mi) } return rows } -func (self *SwarmFS) Stop() bool { - for mp := range self.activeMounts { - mountInfo := self.activeMounts[mp] - self.Unmount(mountInfo.MountPoint) +func (swarmfs *SwarmFS) Stop() bool { + for mp := range swarmfs.activeMounts { + mountInfo := swarmfs.activeMounts[mp] + swarmfs.Unmount(mountInfo.MountPoint) } return true } diff --git a/swarm/fuse/swarmfs_util.go b/swarm/fuse/swarmfs_util.go index 169b674876..4f2e1416b6 100644 --- a/swarm/fuse/swarmfs_util.go +++ b/swarm/fuse/swarmfs_util.go @@ -24,7 +24,7 @@ import ( "os/exec" "runtime" - "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/swarm/log" ) func externalUnmount(mountPoint string) error { @@ -38,35 +38,35 @@ func externalUnmount(mountPoint string) error { // Try FUSE-specific commands if umount didn't work. switch runtime.GOOS { case "darwin": - return exec.CommandContext(ctx, "diskutil", "umount", "force", mountPoint).Run() + return exec.CommandContext(ctx, "diskutil", "umount", mountPoint).Run() case "linux": return exec.CommandContext(ctx, "fusermount", "-u", mountPoint).Run() default: - return fmt.Errorf("unmount: unimplemented") + return fmt.Errorf("swarmfs unmount: unimplemented") } } func addFileToSwarm(sf *SwarmFile, content []byte, size int) error { - fkey, mhash, err := sf.mountInfo.swarmApi.AddFile(sf.mountInfo.LatestManifest, sf.path, sf.name, content, true) + fkey, mhash, err := sf.mountInfo.swarmApi.AddFile(context.TODO(), sf.mountInfo.LatestManifest, sf.path, sf.name, content, true) if err != nil { return err } sf.lock.Lock() defer sf.lock.Unlock() - sf.key = fkey + sf.addr = fkey sf.fileSize = int64(size) sf.mountInfo.lock.Lock() defer sf.mountInfo.lock.Unlock() sf.mountInfo.LatestManifest = mhash - log.Info("Added new file:", "fname", sf.name, "New Manifest hash", mhash) + log.Info("swarmfs added new file:", "fname", sf.name, "new Manifest hash", mhash) return nil } func removeFileFromSwarm(sf *SwarmFile) error { - mkey, err := sf.mountInfo.swarmApi.RemoveFile(sf.mountInfo.LatestManifest, sf.path, sf.name, true) + mkey, err := sf.mountInfo.swarmApi.RemoveFile(context.TODO(), sf.mountInfo.LatestManifest, sf.path, sf.name, true) if err != nil { return err } @@ -75,7 +75,7 @@ func removeFileFromSwarm(sf *SwarmFile) error { defer sf.mountInfo.lock.Unlock() sf.mountInfo.LatestManifest = mkey - log.Info("Removed file:", "fname", sf.name, "New Manifest hash", mkey) + log.Info("swarmfs removed file:", "fname", sf.name, "new Manifest hash", mkey) return nil } @@ -102,20 +102,20 @@ func removeDirectoryFromSwarm(sd *SwarmDir) error { } func appendToExistingFileInSwarm(sf *SwarmFile, content []byte, offset int64, length int64) error { - fkey, mhash, err := sf.mountInfo.swarmApi.AppendFile(sf.mountInfo.LatestManifest, sf.path, sf.name, sf.fileSize, content, sf.key, offset, length, true) + fkey, mhash, err := sf.mountInfo.swarmApi.AppendFile(context.TODO(), sf.mountInfo.LatestManifest, sf.path, sf.name, sf.fileSize, content, sf.addr, offset, length, true) if err != nil { return err } sf.lock.Lock() defer sf.lock.Unlock() - sf.key = fkey + sf.addr = fkey sf.fileSize = sf.fileSize + int64(len(content)) sf.mountInfo.lock.Lock() defer sf.mountInfo.lock.Unlock() sf.mountInfo.LatestManifest = mhash - log.Info("Appended file:", "fname", sf.name, "New Manifest hash", mhash) + log.Info("swarmfs appended file:", "fname", sf.name, "new Manifest hash", mhash) return nil } diff --git a/swarm/grafana_dashboards/ldbstore.json b/swarm/grafana_dashboards/ldbstore.json new file mode 100644 index 0000000000..2d64380ba8 --- /dev/null +++ b/swarm/grafana_dashboards/ldbstore.json @@ -0,0 +1,2278 @@ +{ + "annotations": { + "list": [ + { + "$$hashKey": "object:325", + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 1, + "id": 5, + "iteration": 1527598894689, + "links": [], + "panels": [ + { + "collapsed": true, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 40, + "panels": [ + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "metrics", + "fill": 1, + "gridPos": { + "h": 6, + "w": 12, + "x": 0, + "y": 1 + }, + "id": 42, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "alias": "$tag_host", + "groupBy": [ + { + "params": [ + "$myinterval" + ], + "type": "time" + }, + { + "params": [ + "host" + ], + "type": "tag" + }, + { + "params": [ + "0" + ], + "type": "fill" + } + ], + "measurement": "swarm.localstore.get.cachehit.count", + "orderByTime": "ASC", + "policy": "default", + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "field" + }, + { + "params": [], + "type": "sum" + } + ] + ], + "tags": [ + { + "key": "host", + "operator": "=~", + "value": "/^$host$/" + } + ] + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "LocalStore get cachehit", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "metrics", + "fill": 1, + "gridPos": { + "h": 6, + "w": 12, + "x": 12, + "y": 1 + }, + "id": 43, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "alias": "$tag_host", + "groupBy": [ + { + "params": [ + "$myinterval" + ], + "type": "time" + }, + { + "params": [ + "host" + ], + "type": "tag" + }, + { + "params": [ + "0" + ], + "type": "fill" + } + ], + "measurement": "swarm.localstore.get.cachemiss.count", + "orderByTime": "ASC", + "policy": "default", + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "field" + }, + { + "params": [], + "type": "sum" + } + ] + ], + "tags": [ + { + "key": "host", + "operator": "=~", + "value": "/^$host$/" + } + ] + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "LocalStore get cachemiss", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "metrics", + "fill": 1, + "gridPos": { + "h": 6, + "w": 12, + "x": 0, + "y": 7 + }, + "id": 44, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "alias": "$tag_host", + "groupBy": [ + { + "params": [ + "$myinterval" + ], + "type": "time" + }, + { + "params": [ + "host" + ], + "type": "tag" + }, + { + "params": [ + "0" + ], + "type": "fill" + } + ], + "measurement": "swarm.localstore.getorcreaterequest.count", + "orderByTime": "ASC", + "policy": "default", + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "field" + }, + { + "params": [], + "type": "sum" + } + ] + ], + "tags": [ + { + "key": "host", + "operator": "=~", + "value": "/^$host$/" + } + ] + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Total LocalStore.GetOrCreateRequest", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "metrics", + "fill": 1, + "gridPos": { + "h": 6, + "w": 12, + "x": 12, + "y": 7 + }, + "id": 47, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "alias": "$tag_host", + "groupBy": [ + { + "params": [ + "$myinterval" + ], + "type": "time" + }, + { + "params": [ + "host" + ], + "type": "tag" + }, + { + "params": [ + "0" + ], + "type": "fill" + } + ], + "measurement": "swarm.localstore.getorcreaterequest.errfetching.count", + "orderByTime": "ASC", + "policy": "default", + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "field" + }, + { + "params": [], + "type": "sum" + } + ] + ], + "tags": [ + { + "key": "host", + "operator": "=~", + "value": "/^$host$/" + } + ] + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "LocalStore GetOrCreateRequest ErrFetching", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "metrics", + "fill": 1, + "gridPos": { + "h": 6, + "w": 12, + "x": 0, + "y": 13 + }, + "id": 45, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "alias": "$tag_host", + "groupBy": [ + { + "params": [ + "$myinterval" + ], + "type": "time" + }, + { + "params": [ + "host" + ], + "type": "tag" + }, + { + "params": [ + "0" + ], + "type": "fill" + } + ], + "measurement": "swarm.localstore.getorcreaterequest.hit.count", + "orderByTime": "ASC", + "policy": "default", + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "field" + }, + { + "params": [], + "type": "sum" + } + ] + ], + "tags": [ + { + "key": "host", + "operator": "=~", + "value": "/^$host$/" + } + ] + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "LocalStore.GetOrCreateRequest hit", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "metrics", + "fill": 1, + "gridPos": { + "h": 6, + "w": 12, + "x": 12, + "y": 13 + }, + "id": 49, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "alias": "$tag_host", + "groupBy": [ + { + "params": [ + "$myinterval" + ], + "type": "time" + }, + { + "params": [ + "host" + ], + "type": "tag" + }, + { + "params": [ + "0" + ], + "type": "fill" + } + ], + "measurement": "swarm.localstore.getorcreaterequest.miss.count", + "orderByTime": "ASC", + "policy": "default", + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "field" + }, + { + "params": [], + "type": "sum" + } + ] + ], + "tags": [ + { + "key": "host", + "operator": "=~", + "value": "/^$host$/" + } + ] + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "LocalStore GetOrCreateRequest miss", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "metrics", + "fill": 1, + "gridPos": { + "h": 6, + "w": 12, + "x": 0, + "y": 19 + }, + "id": 48, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "alias": "$tag_host", + "groupBy": [ + { + "params": [ + "$myinterval" + ], + "type": "time" + }, + { + "params": [ + "host" + ], + "type": "tag" + }, + { + "params": [ + "0" + ], + "type": "fill" + } + ], + "measurement": "swarm.localstore.get.error.count", + "orderByTime": "ASC", + "policy": "default", + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "field" + }, + { + "params": [], + "type": "sum" + } + ] + ], + "tags": [ + { + "key": "host", + "operator": "=~", + "value": "/^$host$/" + } + ] + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "LocalStore get error", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "metrics", + "fill": 1, + "gridPos": { + "h": 6, + "w": 12, + "x": 12, + "y": 19 + }, + "id": 46, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "alias": "$tag_host", + "groupBy": [ + { + "params": [ + "$myinterval" + ], + "type": "time" + }, + { + "params": [ + "host" + ], + "type": "tag" + }, + { + "params": [ + "0" + ], + "type": "fill" + } + ], + "measurement": "swarm.localstore.get.errfetching.count", + "orderByTime": "ASC", + "policy": "default", + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "field" + }, + { + "params": [], + "type": "sum" + } + ] + ], + "tags": [ + { + "key": "host", + "operator": "=~", + "value": "/^$host$/" + } + ] + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "LocalStore get ErrFetching", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + } + ], + "title": "LocalStore", + "type": "row" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 1 + }, + "id": 27, + "panels": [], + "title": "LDBStore", + "type": "row" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "metrics", + "fill": 1, + "gridPos": { + "h": 6, + "w": 12, + "x": 0, + "y": 2 + }, + "id": 29, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "alias": "$tag_host", + "groupBy": [ + { + "params": [ + "$myinterval" + ], + "type": "time" + }, + { + "params": [ + "host" + ], + "type": "tag" + }, + { + "params": [ + "0" + ], + "type": "fill" + } + ], + "measurement": "swarm.ldbstore.get.count", + "orderByTime": "ASC", + "policy": "default", + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "field" + }, + { + "params": [], + "type": "sum" + } + ] + ], + "tags": [ + { + "key": "host", + "operator": "=~", + "value": "/^$host$/" + } + ] + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "LDBStore get", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "none", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "metrics", + "fill": 1, + "gridPos": { + "h": 6, + "w": 12, + "x": 12, + "y": 2 + }, + "id": 30, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "alias": "$tag_host", + "groupBy": [ + { + "params": [ + "$myinterval" + ], + "type": "time" + }, + { + "params": [ + "host" + ], + "type": "tag" + }, + { + "params": [ + "0" + ], + "type": "fill" + } + ], + "measurement": "swarm.ldbstore.put.count", + "orderByTime": "ASC", + "policy": "default", + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "field" + }, + { + "params": [], + "type": "sum" + } + ] + ], + "tags": [ + { + "key": "host", + "operator": "=~", + "value": "/^$host$/" + } + ] + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "LDBStore put", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "none", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "metrics", + "fill": 1, + "gridPos": { + "h": 6, + "w": 12, + "x": 0, + "y": 8 + }, + "id": 31, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "alias": "$tag_host", + "groupBy": [ + { + "params": [ + "$myinterval" + ], + "type": "time" + }, + { + "params": [ + "host" + ], + "type": "tag" + }, + { + "params": [ + "0" + ], + "type": "fill" + } + ], + "measurement": "swarm.ldbstore.synciterator.count", + "orderByTime": "ASC", + "policy": "default", + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "field" + }, + { + "params": [], + "type": "sum" + } + ] + ], + "tags": [ + { + "key": "host", + "operator": "=~", + "value": "/^$host$/" + } + ] + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "LDBStore SyncIterator", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "none", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "metrics", + "fill": 1, + "gridPos": { + "h": 6, + "w": 12, + "x": 12, + "y": 8 + }, + "id": 32, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "alias": "$tag_host", + "groupBy": [ + { + "params": [ + "$myinterval" + ], + "type": "time" + }, + { + "params": [ + "host" + ], + "type": "tag" + }, + { + "params": [ + "0" + ], + "type": "fill" + } + ], + "measurement": "swarm.ldbstore.synciterator.seek.count", + "orderByTime": "ASC", + "policy": "default", + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "field" + }, + { + "params": [], + "type": "sum" + } + ] + ], + "tags": [ + { + "key": "host", + "operator": "=~", + "value": "/^$host$/" + } + ] + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "LDBStore SyncIterator Seek/Next", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "none", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "metrics", + "fill": 1, + "gridPos": { + "h": 6, + "w": 12, + "x": 0, + "y": 14 + }, + "id": 50, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "alias": "$tag_host", + "groupBy": [ + { + "params": [ + "$myinterval" + ], + "type": "time" + }, + { + "params": [ + "host" + ], + "type": "tag" + }, + { + "params": [ + "0" + ], + "type": "fill" + } + ], + "measurement": "swarm.ldbstore.collectgarbage.count", + "orderByTime": "ASC", + "policy": "default", + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "field" + }, + { + "params": [], + "type": "sum" + } + ] + ], + "tags": [ + { + "key": "host", + "operator": "=~", + "value": "/^$host$/" + } + ] + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "LDBStore Collect Garbage", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "none", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "metrics", + "fill": 1, + "gridPos": { + "h": 6, + "w": 12, + "x": 12, + "y": 14 + }, + "id": 51, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "alias": "$tag_host", + "groupBy": [ + { + "params": [ + "$myinterval" + ], + "type": "time" + }, + { + "params": [ + "host" + ], + "type": "tag" + }, + { + "params": [ + "0" + ], + "type": "fill" + } + ], + "measurement": "swarm.ldbstore.collectgarbage.delete.count", + "orderByTime": "ASC", + "policy": "default", + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "field" + }, + { + "params": [], + "type": "sum" + } + ] + ], + "tags": [ + { + "key": "host", + "operator": "=~", + "value": "/^$host$/" + } + ] + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "LDBStore Collect Garbage - Actual Deletes", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "none", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "collapsed": true, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 20 + }, + "id": 34, + "panels": [ + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "metrics", + "fill": 1, + "gridPos": { + "h": 6, + "w": 12, + "x": 0, + "y": 39 + }, + "id": 36, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "alias": "$tag_host", + "groupBy": [ + { + "params": [ + "$myinterval" + ], + "type": "time" + }, + { + "params": [ + "host" + ], + "type": "tag" + }, + { + "params": [ + "0" + ], + "type": "fill" + } + ], + "measurement": "swarm.ldbdatabase.get.count", + "orderByTime": "ASC", + "policy": "default", + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "field" + }, + { + "params": [], + "type": "sum" + } + ] + ], + "tags": [ + { + "key": "host", + "operator": "=~", + "value": "/^$host$/" + } + ] + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "LDBDatabase get", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "none", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "metrics", + "fill": 1, + "gridPos": { + "h": 6, + "w": 12, + "x": 12, + "y": 39 + }, + "id": 37, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "alias": "$tag_host", + "groupBy": [ + { + "params": [ + "$myinterval" + ], + "type": "time" + }, + { + "params": [ + "host" + ], + "type": "tag" + }, + { + "params": [ + "0" + ], + "type": "fill" + } + ], + "measurement": "swarm.ldbdatabase.write.count", + "orderByTime": "ASC", + "policy": "default", + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "field" + }, + { + "params": [], + "type": "sum" + } + ] + ], + "tags": [ + { + "key": "host", + "operator": "=~", + "value": "/^$host$/" + } + ] + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "LDBDatabase write", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "none", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "metrics", + "fill": 1, + "gridPos": { + "h": 6, + "w": 12, + "x": 0, + "y": 45 + }, + "id": 38, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "alias": "$tag_host", + "groupBy": [ + { + "params": [ + "$myinterval" + ], + "type": "time" + }, + { + "params": [ + "host" + ], + "type": "tag" + }, + { + "params": [ + "0" + ], + "type": "fill" + } + ], + "measurement": "swarm.ldbdatabase.newiterator.count", + "orderByTime": "ASC", + "policy": "default", + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "field" + }, + { + "params": [], + "type": "sum" + } + ] + ], + "tags": [ + { + "key": "host", + "operator": "=~", + "value": "/^$host$/" + } + ] + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "LDBDatabase NewIterator", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "none", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + } + ], + "title": "LDBDatabase", + "type": "row" + } + ], + "refresh": "10s", + "schemaVersion": 16, + "style": "dark", + "tags": [], + "templating": { + "list": [ + { + "auto": false, + "auto_count": 30, + "auto_min": "10s", + "current": { + "text": "10s", + "value": "10s" + }, + "hide": 0, + "label": "resolution", + "name": "myinterval", + "options": [ + { + "selected": false, + "text": "5s", + "value": "5s" + }, + { + "selected": true, + "text": "10s", + "value": "10s" + }, + { + "selected": false, + "text": "30s", + "value": "30s" + }, + { + "selected": false, + "text": "100s", + "value": "100s" + } + ], + "query": "5s,10s,30s,100s", + "refresh": 2, + "type": "interval" + }, + { + "allValue": null, + "current": { + "text": "swarm_30399 + swarm_30400 + swarm_30401", + "value": [ + "swarm_30399", + "swarm_30400", + "swarm_30401" + ] + }, + "datasource": "metrics", + "hide": 0, + "includeAll": true, + "label": null, + "multi": true, + "name": "host", + "options": [], + "query": "SHOW TAG VALUES WITH KEY = \"host\"", + "refresh": 1, + "regex": "", + "sort": 1, + "tagValuesQuery": "", + "tags": [], + "tagsQuery": "swarm.http.request.GET.time.span", + "type": "query", + "useTags": false + } + ] + }, + "time": { + "from": "now-15m", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "time_options": [ + "5m", + "15m", + "1h", + "6h", + "12h", + "24h", + "2d", + "7d", + "30d" + ] + }, + "timezone": "", + "title": "LDBStore and LDBDatabase", + "uid": "zS6beG7iz", + "version": 28 +} diff --git a/swarm/grafana_dashboards/swarm.json b/swarm/grafana_dashboards/swarm.json new file mode 100644 index 0000000000..3ee244d154 --- /dev/null +++ b/swarm/grafana_dashboards/swarm.json @@ -0,0 +1,3198 @@ +{ + "annotations": { + "list": [ + { + "$$hashKey": "object:147", + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 1, + "id": 2, + "iteration": 1527598859072, + "links": [], + "panels": [ + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 34, + "panels": [], + "title": "P2P", + "type": "row" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "metrics", + "fill": 1, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 1 + }, + "id": 36, + "legend": { + "alignAsTable": true, + "avg": false, + "current": true, + "max": true, + "min": false, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "alias": "$tag_host", + "groupBy": [ + { + "params": [ + "$__interval" + ], + "type": "time" + }, + { + "params": [ + "host" + ], + "type": "tag" + }, + { + "params": [ + "none" + ], + "type": "fill" + } + ], + "measurement": "swarm.peer.send.count", + "orderByTime": "ASC", + "policy": "default", + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "field" + }, + { + "params": [], + "type": "sum" + } + ] + ], + "tags": [] + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "P2P Send() - messages sent", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "metrics", + "fill": 1, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 1 + }, + "id": 37, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "alias": "p95($tag_host)", + "groupBy": [ + { + "params": [ + "$__interval" + ], + "type": "time" + }, + { + "params": [ + "host" + ], + "type": "tag" + }, + { + "params": [ + "none" + ], + "type": "fill" + } + ], + "measurement": "swarm.peer.send_t.span", + "orderByTime": "ASC", + "policy": "default", + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "p95" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + } + ] + ], + "tags": [] + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "P2P Send() timer - 95%ile", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "ns", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "metrics", + "fill": 1, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 10 + }, + "id": 38, + "legend": { + "alignAsTable": true, + "avg": false, + "current": true, + "max": true, + "min": false, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "alias": "1 $tag_host", + "groupBy": [ + { + "params": [ + "$__interval" + ], + "type": "time" + }, + { + "params": [ + "host" + ], + "type": "tag" + }, + { + "params": [ + "none" + ], + "type": "fill" + } + ], + "measurement": "swarm.peer.sendpriority.1.count", + "orderByTime": "ASC", + "policy": "default", + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "field" + }, + { + "params": [], + "type": "sum" + } + ] + ], + "tags": [] + }, + { + "alias": "2 $tag_host", + "groupBy": [ + { + "params": [ + "$__interval" + ], + "type": "time" + }, + { + "params": [ + "host" + ], + "type": "tag" + }, + { + "params": [ + "none" + ], + "type": "fill" + } + ], + "measurement": "swarm.peer.sendpriority.2.count", + "orderByTime": "ASC", + "policy": "default", + "refId": "B", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "field" + }, + { + "params": [], + "type": "sum" + } + ] + ], + "tags": [] + }, + { + "alias": "3 $tag_host", + "groupBy": [ + { + "params": [ + "$__interval" + ], + "type": "time" + }, + { + "params": [ + "host" + ], + "type": "tag" + }, + { + "params": [ + "none" + ], + "type": "fill" + } + ], + "measurement": "swarm.peer.sendpriority.3.count", + "orderByTime": "ASC", + "policy": "default", + "refId": "C", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "field" + }, + { + "params": [], + "type": "sum" + } + ] + ], + "tags": [] + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "P2P SendPriority() - messages sent", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "metrics", + "fill": 1, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 10 + }, + "id": 39, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": true, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "alias": "1 $tag_host", + "groupBy": [ + { + "params": [ + "$__interval" + ], + "type": "time" + }, + { + "params": [ + "host" + ], + "type": "tag" + }, + { + "params": [ + "none" + ], + "type": "fill" + } + ], + "measurement": "swarm.peer.sendpriority_t.1.span", + "orderByTime": "ASC", + "policy": "default", + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "p95" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + } + ] + ], + "tags": [] + }, + { + "alias": "2 $tag_host", + "groupBy": [ + { + "params": [ + "$__interval" + ], + "type": "time" + }, + { + "params": [ + "host" + ], + "type": "tag" + }, + { + "params": [ + "none" + ], + "type": "fill" + } + ], + "measurement": "swarm.peer.sendpriority_t.2.span", + "orderByTime": "ASC", + "policy": "default", + "refId": "B", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "p95" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + } + ] + ], + "tags": [] + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "P2P SendPriority() timer - 95%ile", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "ns", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "metrics", + "fill": 1, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 19 + }, + "id": 40, + "legend": { + "alignAsTable": true, + "avg": false, + "current": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "alias": "$tag_host", + "groupBy": [ + { + "params": [ + "$__interval" + ], + "type": "time" + }, + { + "params": [ + "host" + ], + "type": "tag" + }, + { + "params": [ + "none" + ], + "type": "fill" + } + ], + "measurement": "swarm.registry.peers.gauge", + "orderByTime": "ASC", + "policy": "default", + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "field" + }, + { + "params": [], + "type": "last" + } + ] + ], + "tags": [] + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Registry Peers", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "collapsed": true, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 28 + }, + "id": 32, + "panels": [ + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "metrics", + "fill": 1, + "gridPos": { + "h": 6, + "w": 12, + "x": 0, + "y": 2 + }, + "id": 14, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "alias": "$tag_host", + "groupBy": [ + { + "params": [ + "$myinterval" + ], + "type": "time" + }, + { + "params": [ + "host" + ], + "type": "tag" + }, + { + "params": [ + "0" + ], + "type": "fill" + } + ], + "measurement": "swarm.stack.uptime.gauge", + "orderByTime": "ASC", + "policy": "default", + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + } + ] + ], + "tags": [ + { + "key": "host", + "operator": "=~", + "value": "/^$host$/" + } + ] + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Uptime", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "ns", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + } + ], + "title": "Uptime", + "type": "row" + }, + { + "collapsed": true, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 29 + }, + "id": 28, + "panels": [ + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "metrics", + "fill": 1, + "gridPos": { + "h": 6, + "w": 12, + "x": 0, + "y": 7 + }, + "id": 2, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": true, + "min": false, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "alias": "GET", + "dsType": "influxdb", + "groupBy": [ + { + "params": [ + "$myinterval" + ], + "type": "time" + }, + { + "params": [ + "null" + ], + "type": "fill" + } + ], + "measurement": "swarm.http.request.GET.count", + "orderByTime": "ASC", + "policy": "default", + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "field" + }, + { + "params": [], + "type": "sum" + } + ] + ], + "tags": [ + { + "key": "host", + "operator": "=~", + "value": "/^$host$/" + } + ] + }, + { + "alias": "POST", + "dsType": "influxdb", + "groupBy": [ + { + "params": [ + "$myinterval" + ], + "type": "time" + }, + { + "params": [ + "null" + ], + "type": "fill" + } + ], + "measurement": "swarm.http.request.POST.count", + "orderByTime": "ASC", + "policy": "default", + "refId": "B", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "field" + }, + { + "params": [], + "type": "sum" + } + ] + ], + "tags": [ + { + "key": "host", + "operator": "=~", + "value": "/^$host$/" + } + ] + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Total HTTP Requests", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "metrics", + "fill": 1, + "gridPos": { + "h": 6, + "w": 12, + "x": 12, + "y": 7 + }, + "id": 26, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "alias": "$tag_host", + "groupBy": [ + { + "params": [ + "$myinterval" + ], + "type": "time" + }, + { + "params": [ + "host" + ], + "type": "tag" + }, + { + "params": [ + "0" + ], + "type": "fill" + } + ], + "measurement": "swarm.http.request.GET.time.span", + "orderByTime": "ASC", + "policy": "default", + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "p95" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + } + ] + ], + "tags": [ + { + "key": "host", + "operator": "=~", + "value": "/^$host$/" + } + ] + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "HTTP GET requests 95% timer", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "ns", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "metrics", + "fill": 1, + "gridPos": { + "h": 6, + "w": 12, + "x": 0, + "y": 13 + }, + "id": 15, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "alias": "$tag_host", + "groupBy": [ + { + "params": [ + "$myinterval" + ], + "type": "time" + }, + { + "params": [ + "host" + ], + "type": "tag" + }, + { + "params": [ + "0" + ], + "type": "fill" + } + ], + "measurement": "swarm.http.request.GET.time.span", + "orderByTime": "ASC", + "policy": "default", + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "p50" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + } + ] + ], + "tags": [ + { + "key": "host", + "operator": "=~", + "value": "/^$host$/" + } + ] + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "HTTP GET requests 50% timer", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "ns", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "metrics", + "fill": 1, + "gridPos": { + "h": 6, + "w": 12, + "x": 12, + "y": 13 + }, + "id": 8, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": true, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "alias": "POST", + "groupBy": [ + { + "params": [ + "$myinterval" + ], + "type": "time" + }, + { + "params": [ + "host" + ], + "type": "tag" + }, + { + "params": [ + "0" + ], + "type": "fill" + } + ], + "measurement": "swarm.http.request.POST.time.span", + "orderByTime": "ASC", + "policy": "default", + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "p95" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + } + ] + ], + "tags": [ + { + "key": "host", + "operator": "=~", + "value": "/^$host$/" + } + ] + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "HTTP POST requests 95% timer", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "ns", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + } + ], + "title": "HTTP", + "type": "row" + }, + { + "collapsed": true, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 30 + }, + "id": 30, + "panels": [ + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "metrics", + "fill": 1, + "gridPos": { + "h": 5, + "w": 12, + "x": 0, + "y": 8 + }, + "id": 16, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": true, + "min": false, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "alias": "$tag_host", + "dsType": "influxdb", + "groupBy": [ + { + "params": [ + "$myinterval" + ], + "type": "time" + }, + { + "params": [ + "host" + ], + "type": "tag" + }, + { + "params": [ + "0" + ], + "type": "fill" + } + ], + "measurement": "swarm.lazychunkreader.read.count", + "orderByTime": "ASC", + "policy": "default", + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "field" + }, + { + "params": [], + "type": "sum" + } + ] + ], + "tags": [ + { + "key": "host", + "operator": "=~", + "value": "/^$host$/" + } + ] + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "LazyChunkReader read() calls", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "metrics", + "fill": 1, + "gridPos": { + "h": 5, + "w": 12, + "x": 12, + "y": 8 + }, + "id": 18, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": true, + "min": false, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "alias": "$tag_host", + "dsType": "influxdb", + "groupBy": [ + { + "params": [ + "$myinterval" + ], + "type": "time" + }, + { + "params": [ + "host" + ], + "type": "tag" + }, + { + "params": [ + "0" + ], + "type": "fill" + } + ], + "measurement": "swarm.lazychunkreader.read.err.count", + "orderByTime": "ASC", + "policy": "default", + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "field" + }, + { + "params": [], + "type": "sum" + } + ] + ], + "tags": [ + { + "key": "host", + "operator": "=~", + "value": "/^$host$/" + } + ] + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "LazyChunkReader read errors", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "none", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "metrics", + "fill": 1, + "gridPos": { + "h": 5, + "w": 12, + "x": 0, + "y": 13 + }, + "id": 17, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": true, + "min": false, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "alias": "$tag_host", + "dsType": "influxdb", + "groupBy": [ + { + "params": [ + "$myinterval" + ], + "type": "time" + }, + { + "params": [ + "host" + ], + "type": "tag" + }, + { + "params": [ + "0" + ], + "type": "fill" + } + ], + "measurement": "swarm.lazychunkreader.read.bytes.count", + "orderByTime": "ASC", + "policy": "default", + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "field" + }, + { + "params": [], + "type": "sum" + } + ] + ], + "tags": [ + { + "key": "host", + "operator": "=~", + "value": "/^$host$/" + } + ] + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "LazyChunkReader bytes read", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "decbytes", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + } + ], + "title": "LazyChunkReader", + "type": "row" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 31 + }, + "id": 25, + "panels": [], + "title": "All measurements", + "type": "row" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "metrics", + "fill": 1, + "gridPos": { + "h": 6, + "w": 12, + "x": 0, + "y": 32 + }, + "id": 3, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": true, + "min": false, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "alias": "$tag_host", + "dsType": "influxdb", + "groupBy": [ + { + "params": [ + "$myinterval" + ], + "type": "time" + }, + { + "params": [ + "host" + ], + "type": "tag" + }, + { + "params": [ + "0" + ], + "type": "fill" + } + ], + "measurement": "swarm.api.get.count.count", + "orderByTime": "ASC", + "policy": "default", + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "field" + }, + { + "params": [], + "type": "sum" + } + ] + ], + "tags": [ + { + "key": "host", + "operator": "=~", + "value": "/^$host$/" + } + ] + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "API Get (BZZ)", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "metrics", + "fill": 1, + "gridPos": { + "h": 6, + "w": 12, + "x": 12, + "y": 32 + }, + "id": 13, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": true, + "min": false, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "alias": "$tag_host", + "groupBy": [ + { + "params": [ + "$myinterval" + ], + "type": "time" + }, + { + "params": [ + "host" + ], + "type": "tag" + }, + { + "params": [ + "0" + ], + "type": "fill" + } + ], + "measurement": "swarm.network.stream.request_from_peers.count.count", + "orderByTime": "ASC", + "policy": "default", + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "field" + }, + { + "params": [], + "type": "sum" + } + ] + ], + "tags": [ + { + "key": "host", + "operator": "=~", + "value": "/^$host$/" + } + ] + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Request from peers", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "metrics", + "fill": 1, + "gridPos": { + "h": 6, + "w": 12, + "x": 0, + "y": 38 + }, + "id": 11, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": true, + "min": false, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "alias": "$tag_host", + "groupBy": [ + { + "params": [ + "$myinterval" + ], + "type": "time" + }, + { + "params": [ + "host" + ], + "type": "tag" + }, + { + "params": [ + "0" + ], + "type": "fill" + } + ], + "measurement": "swarm.network.stream.received_chunks.count.count", + "orderByTime": "ASC", + "policy": "default", + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "field" + }, + { + "params": [], + "type": "sum" + } + ] + ], + "tags": [ + { + "key": "host", + "operator": "=~", + "value": "/^$host$/" + } + ] + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Received chunks", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "metrics", + "fill": 1, + "gridPos": { + "h": 6, + "w": 12, + "x": 12, + "y": 38 + }, + "id": 12, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": true, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "alias": "$tag_host", + "dsType": "influxdb", + "groupBy": [ + { + "params": [ + "$myinterval" + ], + "type": "time" + }, + { + "params": [ + "host" + ], + "type": "tag" + }, + { + "params": [ + "0" + ], + "type": "fill" + } + ], + "measurement": "swarm.storage.cache.requests.size.gauge", + "orderByTime": "ASC", + "policy": "default", + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "field" + }, + { + "params": [], + "type": "max" + } + ] + ], + "tags": [ + { + "key": "host", + "operator": "=~", + "value": "/^$host$/" + } + ] + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Requests cache entries", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "metrics", + "fill": 1, + "gridPos": { + "h": 6, + "w": 12, + "x": 0, + "y": 44 + }, + "id": 9, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": true, + "min": false, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "alias": "$tag_host", + "groupBy": [ + { + "params": [ + "$myinterval" + ], + "type": "time" + }, + { + "params": [ + "host" + ], + "type": "tag" + }, + { + "params": [ + "0" + ], + "type": "fill" + } + ], + "measurement": "swarm.network.stream.handle_retrieve_request_msg.count.count", + "orderByTime": "ASC", + "policy": "default", + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "field" + }, + { + "params": [], + "type": "sum" + } + ] + ], + "tags": [ + { + "key": "host", + "operator": "=~", + "value": "/^$host$/" + } + ] + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Handle retrieve request msg", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "metrics", + "fill": 1, + "gridPos": { + "h": 6, + "w": 12, + "x": 12, + "y": 44 + }, + "id": 20, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": true, + "min": false, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "alias": "$tag_host", + "dsType": "influxdb", + "groupBy": [ + { + "params": [ + "$myinterval" + ], + "type": "time" + }, + { + "params": [ + "host" + ], + "type": "tag" + }, + { + "params": [ + "0" + ], + "type": "fill" + } + ], + "measurement": "swarm.syncer.setnextbatch.iterator.count", + "orderByTime": "ASC", + "policy": "default", + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "field" + }, + { + "params": [], + "type": "sum" + } + ] + ], + "tags": [ + { + "key": "host", + "operator": "=~", + "value": "/^$host$/" + } + ] + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "syncer setnextbatch iterator calls", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "none", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "metrics", + "fill": 1, + "gridPos": { + "h": 6, + "w": 12, + "x": 0, + "y": 50 + }, + "id": 21, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": true, + "min": false, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "alias": "$tag_host", + "dsType": "influxdb", + "groupBy": [ + { + "params": [ + "$myinterval" + ], + "type": "time" + }, + { + "params": [ + "host" + ], + "type": "tag" + }, + { + "params": [ + "0" + ], + "type": "fill" + } + ], + "measurement": "swarm.peer.handlewantedhashesmsg.count", + "orderByTime": "ASC", + "policy": "default", + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "field" + }, + { + "params": [], + "type": "sum" + } + ] + ], + "tags": [ + { + "key": "host", + "operator": "=~", + "value": "/^$host$/" + } + ] + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "peer HandleWantedHashesMsg", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "none", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "metrics", + "fill": 1, + "gridPos": { + "h": 6, + "w": 12, + "x": 12, + "y": 50 + }, + "id": 22, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": true, + "min": false, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "alias": "$tag_host", + "dsType": "influxdb", + "groupBy": [ + { + "params": [ + "$myinterval" + ], + "type": "time" + }, + { + "params": [ + "host" + ], + "type": "tag" + }, + { + "params": [ + "0" + ], + "type": "fill" + } + ], + "measurement": "swarm.peer.handlesubscribemsg.count", + "orderByTime": "ASC", + "policy": "default", + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "field" + }, + { + "params": [], + "type": "sum" + } + ] + ], + "tags": [ + { + "key": "host", + "operator": "=~", + "value": "/^$host$/" + } + ] + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "peer HandleSubscribeMsg", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "none", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "metrics", + "fill": 1, + "gridPos": { + "h": 6, + "w": 12, + "x": 0, + "y": 56 + }, + "id": 23, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": true, + "min": false, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "alias": "$tag_host", + "dsType": "influxdb", + "groupBy": [ + { + "params": [ + "$myinterval" + ], + "type": "time" + }, + { + "params": [ + "host" + ], + "type": "tag" + }, + { + "params": [ + "0" + ], + "type": "fill" + } + ], + "measurement": "swarm.peer.handlewantedhashesmsg.actualget.count", + "orderByTime": "ASC", + "policy": "default", + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "field" + }, + { + "params": [], + "type": "sum" + } + ] + ], + "tags": [ + { + "key": "host", + "operator": "=~", + "value": "/^$host$/" + } + ] + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "peer HandleWantedHashesMsg actual get", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "none", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "metrics", + "fill": 1, + "gridPos": { + "h": 6, + "w": 12, + "x": 12, + "y": 56 + }, + "id": 19, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": true, + "min": false, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "alias": "$tag_host", + "dsType": "influxdb", + "groupBy": [ + { + "params": [ + "$myinterval" + ], + "type": "time" + }, + { + "params": [ + "host" + ], + "type": "tag" + }, + { + "params": [ + "0" + ], + "type": "fill" + } + ], + "measurement": "swarm.peer.handleofferedhashes.count", + "orderByTime": "ASC", + "policy": "default", + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "field" + }, + { + "params": [], + "type": "sum" + } + ] + ], + "tags": [ + { + "key": "host", + "operator": "=~", + "value": "/^$host$/" + } + ] + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "peer OfferedHashesMsg", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "none", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + } + ], + "refresh": "30s", + "schemaVersion": 16, + "style": "dark", + "tags": [], + "templating": { + "list": [ + { + "auto": false, + "auto_count": 30, + "auto_min": "10s", + "current": { + "text": "10s", + "value": "10s" + }, + "hide": 0, + "label": "resolution", + "name": "myinterval", + "options": [ + { + "selected": false, + "text": "5s", + "value": "5s" + }, + { + "selected": true, + "text": "10s", + "value": "10s" + }, + { + "selected": false, + "text": "30s", + "value": "30s" + }, + { + "selected": false, + "text": "100s", + "value": "100s" + } + ], + "query": "5s,10s,30s,100s", + "refresh": 2, + "type": "interval" + }, + { + "allValue": null, + "current": { + "text": "swarm_30399 + swarm_30400 + swarm_30401 + swarm_30402", + "value": [ + "swarm_30399", + "swarm_30400", + "swarm_30401", + "swarm_30402" + ] + }, + "datasource": "metrics", + "hide": 0, + "includeAll": true, + "label": null, + "multi": true, + "name": "host", + "options": [], + "query": "SHOW TAG VALUES WITH KEY = \"host\"", + "refresh": 1, + "regex": "", + "sort": 1, + "tagValuesQuery": "", + "tags": [], + "tagsQuery": "swarm.http.request.GET.time.span", + "type": "query", + "useTags": false + } + ] + }, + "time": { + "from": "now-15m", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "time_options": [ + "5m", + "15m", + "1h", + "6h", + "12h", + "24h", + "2d", + "7d", + "30d" + ] + }, + "timezone": "", + "title": "Swarm", + "uid": "vmEtxxgmz", + "version": 138 +} diff --git a/swarm/log/log.go b/swarm/log/log.go new file mode 100644 index 0000000000..ce372632e8 --- /dev/null +++ b/swarm/log/log.go @@ -0,0 +1,48 @@ +package log + +import ( + l "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/metrics" +) + +const ( + // CallDepth is set to 1 in order to influence to reported line number of + // the log message with 1 skipped stack frame of calling l.Output() + CallDepth = 1 +) + +// Warn is a convenient alias for log.Warn with stats +func Warn(msg string, ctx ...interface{}) { + metrics.GetOrRegisterCounter("warn", nil).Inc(1) + l.Output(msg, l.LvlWarn, CallDepth, ctx...) +} + +// Error is a convenient alias for log.Error with stats +func Error(msg string, ctx ...interface{}) { + metrics.GetOrRegisterCounter("error", nil).Inc(1) + l.Output(msg, l.LvlError, CallDepth, ctx...) +} + +// Crit is a convenient alias for log.Crit with stats +func Crit(msg string, ctx ...interface{}) { + metrics.GetOrRegisterCounter("crit", nil).Inc(1) + l.Output(msg, l.LvlCrit, CallDepth, ctx...) +} + +// Info is a convenient alias for log.Info with stats +func Info(msg string, ctx ...interface{}) { + metrics.GetOrRegisterCounter("info", nil).Inc(1) + l.Output(msg, l.LvlInfo, CallDepth, ctx...) +} + +// Debug is a convenient alias for log.Debug with stats +func Debug(msg string, ctx ...interface{}) { + metrics.GetOrRegisterCounter("debug", nil).Inc(1) + l.Output(msg, l.LvlDebug, CallDepth, ctx...) +} + +// Trace is a convenient alias for log.Trace with stats +func Trace(msg string, ctx ...interface{}) { + metrics.GetOrRegisterCounter("trace", nil).Inc(1) + l.Output(msg, l.LvlTrace, CallDepth, ctx...) +} diff --git a/swarm/metrics/flags.go b/swarm/metrics/flags.go index 48b231b219..79490fd360 100644 --- a/swarm/metrics/flags.go +++ b/swarm/metrics/flags.go @@ -20,9 +20,9 @@ import ( "time" "github.com/ethereum/go-ethereum/cmd/utils" - "github.com/ethereum/go-ethereum/log" gethmetrics "github.com/ethereum/go-ethereum/metrics" "github.com/ethereum/go-ethereum/metrics/influxdb" + "github.com/ethereum/go-ethereum/swarm/log" "gopkg.in/urfave/cli.v1" ) @@ -81,6 +81,9 @@ func Setup(ctx *cli.Context) { hosttag = ctx.GlobalString(metricsInfluxDBHostTagFlag.Name) ) + // Start system runtime metrics collection + go gethmetrics.CollectProcessMetrics(2 * time.Second) + if enableExport { log.Info("Enabling swarm metrics export to InfluxDB") go influxdb.InfluxDBWithTags(gethmetrics.DefaultRegistry, 10*time.Second, endpoint, database, username, password, "swarm.", map[string]string{ diff --git a/swarm/multihash/multihash.go b/swarm/multihash/multihash.go new file mode 100644 index 0000000000..3306e3a6dc --- /dev/null +++ b/swarm/multihash/multihash.go @@ -0,0 +1,92 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package multihash + +import ( + "bytes" + "encoding/binary" + "errors" + "fmt" +) + +const ( + defaultMultihashLength = 32 + defaultMultihashTypeCode = 0x1b +) + +var ( + multihashTypeCode uint8 + MultihashLength = defaultMultihashLength +) + +func init() { + multihashTypeCode = defaultMultihashTypeCode + MultihashLength = defaultMultihashLength +} + +// check if valid swarm multihash +func isSwarmMultihashType(code uint8) bool { + return code == multihashTypeCode +} + +// GetMultihashLength returns the digest length of the provided multihash +// It will fail if the multihash is not a valid swarm mulithash +func GetMultihashLength(data []byte) (int, int, error) { + cursor := 0 + typ, c := binary.Uvarint(data) + if c <= 0 { + return 0, 0, errors.New("unreadable hashtype field") + } + if !isSwarmMultihashType(uint8(typ)) { + return 0, 0, fmt.Errorf("hash code %x is not a swarm hashtype", typ) + } + cursor += c + hashlength, c := binary.Uvarint(data[cursor:]) + if c <= 0 { + return 0, 0, errors.New("unreadable length field") + } + cursor += c + + // we cheekily assume hashlength < maxint + inthashlength := int(hashlength) + if len(data[c:]) < inthashlength { + return 0, 0, errors.New("length mismatch") + } + return inthashlength, cursor, nil +} + +// FromMulithash returns the digest portion of the multihash +// It will fail if the multihash is not a valid swarm multihash +func FromMultihash(data []byte) ([]byte, error) { + hashLength, _, err := GetMultihashLength(data) + if err != nil { + return nil, err + } + return data[len(data)-hashLength:], nil +} + +// ToMulithash wraps the provided digest data with a swarm mulithash header +func ToMultihash(hashData []byte) []byte { + buf := bytes.NewBuffer(nil) + b := make([]byte, 8) + c := binary.PutUvarint(b, uint64(multihashTypeCode)) + buf.Write(b[:c]) + c = binary.PutUvarint(b, uint64(len(hashData))) + buf.Write(b[:c]) + buf.Write(hashData) + return buf.Bytes() +} diff --git a/swarm/multihash/multihash_test.go b/swarm/multihash/multihash_test.go new file mode 100644 index 0000000000..85df741dda --- /dev/null +++ b/swarm/multihash/multihash_test.go @@ -0,0 +1,53 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package multihash + +import ( + "bytes" + "math/rand" + "testing" +) + +// parse multihash, and check that invalid multihashes fail +func TestCheckMultihash(t *testing.T) { + hashbytes := make([]byte, 32) + c, err := rand.Read(hashbytes) + if err != nil { + t.Fatal(err) + } else if c < 32 { + t.Fatal("short read") + } + + expected := ToMultihash(hashbytes) + + l, hl, _ := GetMultihashLength(expected) + if l != 32 { + t.Fatalf("expected length %d, got %d", 32, l) + } else if hl != 2 { + t.Fatalf("expected header length %d, got %d", 2, hl) + } + if _, _, err := GetMultihashLength(expected[1:]); err == nil { + t.Fatal("expected failure on corrupt header") + } + if _, _, err := GetMultihashLength(expected[:len(expected)-2]); err == nil { + t.Fatal("expected failure on short content") + } + dh, _ := FromMultihash(expected) + if !bytes.Equal(dh, hashbytes) { + t.Fatalf("expected content hash %x, got %x", hashbytes, dh) + } +} diff --git a/swarm/network/README.md b/swarm/network/README.md new file mode 100644 index 0000000000..ad429b38be --- /dev/null +++ b/swarm/network/README.md @@ -0,0 +1,152 @@ +## Streaming + +Streaming is a new protocol of the swarm bzz bundle of protocols. +This protocol provides the basic logic for chunk-based data flow. +It implements simple retrieve requests and delivery using priority queue. +A data exchange stream is a directional flow of chunks between peers. +The source of datachunks is the upstream, the receiver is called the +downstream peer. Each streaming protocol defines an outgoing streamer +and an incoming streamer, the former installing on the upstream, +the latter on the downstream peer. + +Subscribe on StreamerPeer launches an incoming streamer that sends +a subscribe msg upstream. The streamer on the upstream peer +handles the subscribe msg by installing the relevant outgoing streamer +. The modules now engage in a process of upstream sending a sequence of hashes of +chunks downstream (OfferedHashesMsg). The downstream peer evaluates which hashes are needed +and get it delivered by sending back a msg (WantedHashesMsg). + +Historical syncing is supported - currently not the right abstraction -- +state kept across sessions by saving a series of intervals after their last +batch actually arrived. + +Live streaming is also supported, by starting session from the first item +after the subscription. + +Provable data exchange. In case a stream represents a swarm document's data layer +or higher level chunks, streaming up to a certain index is always provable. It saves on +sending intermediate chunks. + +Using the streamer logic, various stream types are easy to implement: + +* light node requests: + * url lookup with offset + * document download + * document upload +* syncing + * live session syncing + * historical syncing +* simple retrieve requests and deliveries +* mutable resource updates streams +* receipting for finger pointing + +## Syncing + +Syncing is the process that makes sure storer nodes end up storing all and only the chunks that are requested from them. + +### Requirements + +- eventual consistency: so each chunk historical should be syncable +- since the same chunk can and will arrive from many peers, (network traffic should be +optimised, only one transfer of data per chunk) +- explicit request deliveries should be prioritised higher than recent chunks received +during the ongoing session which in turn should be higher than historical chunks. +- insured chunks should get receipted for finger pointing litigation, the receipts storage +should be organised efficiently, upstream peer should also be able to find these +receipts for a deleted chunk easily to refute their challenge. +- syncing should be resilient to cut connections, metadata should be persisted that +keep track of syncing state across sessions, historical syncing state should survive restart +- extra data structures to support syncing should be kept at minimum +- syncing is organized separately for chunk types (resource update v content chunk) +- various types of streams should have common logic abstracted + +Syncing is now entirely mediated by the localstore, ie., no processes or memory leaks due to network contention. +When a new chunk is stored, its chunk hash is index by proximity bin + +peers syncronise by getting the chunks closer to the downstream peer than to the upstream one. +Consequently peers just sync all stored items for the kad bin the receiving peer falls into. +The special case of nearest neighbour sets is handled by the downstream peer +indicating they want to sync all kademlia bins with proximity equal to or higher +than their depth. + +This sync state represents the initial state of a sync connection session. +Retrieval is dictated by downstream peers simply using a special streamer protocol. + +Syncing chunks created during the session by the upstream peer is called live session syncing +while syncing of earlier chunks is historical syncing. + +Once the relevant chunk is retrieved, downstream peer looks up all hash segments in its localstore +and sends to the upstream peer a message with a a bitvector to indicate +missing chunks (e.g., for chunk `k`, hash with chunk internal index which case ) +new items. In turn upstream peer sends the relevant chunk data alongside their index. + +On sending chunks there is a priority queue system. If during looking up hashes in its localstore, +downstream peer hits on an open request then a retrieve request is sent immediately to the upstream peer indicating +that no extra round of checks is needed. If another peers syncer hits the same open request, it is slightly unsafe to not ask +that peer too: if the first one disconnects before delivering or fails to deliver and therefore gets +disconnected, we should still be able to continue with the other. The minimum redundant traffic coming from such simultaneous +eventualities should be sufficiently rare not to warrant more complex treatment. + +Session syncing involves downstream peer to request a new state on a bin from upstream. +using the new state, the range (of chunks) between the previous state and the new one are retrieved +and chunks are requested identical to the historical case. After receiving all the missing chunks +from the new hashes, downstream peer will request a new range. If this happens before upstream peer updates a new state, +we say that session syncing is live or the two peers are in sync. In general the time interval passed since downstream peer request up to the current session cursor is a good indication of a permanent (probably increasing) lag. + +If there is no historical backlog, and downstream peer has an acceptable 'last synced' tag, then it is said to be fully synced with the upstream peer. +If a peer is fully synced with all its storer peers, it can advertise itself as globally fully synced. + +The downstream peer persists the record of the last synced offset. When the two peers disconnect and +reconnect syncing can start from there. +This situation however can also happen while historical syncing is not yet complete. +Effectively this means that the peer needs to persist a record of an arbitrary array of offset ranges covered. + +### Delivery requests + +once the appropriate ranges of the hashstream are retrieved and buffered, downstream peer just scans the hashes, looks them up in localstore, if not found, create a request entry. +The range is referenced by the chunk index. Alongside the name (indicating the stream, e.g., content chunks for bin 6) and the range +downstream peer sends a 128 long bitvector indicating which chunks are needed. +Newly created requests are satisfied bound together in a waitgroup which when done, will promptt sending the next one. +to be able to do check and storage concurrently, we keep a buffer of one, we start with two batches of hashes. +If there is nothing to give, upstream peers SetNextBatch is blocking. Subscription ends with an unsubscribe. which removes the syncer from the map. + +Canceling requests (for instance the late chunks of an erasure batch) should be a chan closed +on the request + +Simple request is also a subscribe +different streaming protocols are different p2p protocols with same message types. +the constructor is the Run function itself. which takes a streamerpeer as argument + + +### provable streams + +The swarm hash over the hash stream has many advantages. It implements a provable data transfer +and provide efficient storage for receipts in the form of inclusion proofs useable for finger pointing litigation. +When challenged on a missing chunk, upstream peer will provide an inclusion proof of a chunk hash against the state of the +sync stream. In order to be able to generate such an inclusion proof, upstream peer needs to store the hash index (counting consecutive hash-size segments) alongside the chunk data and preserve it even when the chunk data is deleted until the chunk is no longer insured. +if there is no valid insurance on the files the entry may be deleted. +As long as the chunk is preserved, no takeover proof will be needed since the node can respond to any challenge. +However, once the node needs to delete an insured chunk for capacity reasons, a receipt should be available to +refute the challenge by finger pointing to a downstream peer. +As part of the deletion protocol then, hashes of insured chunks to be removed are pushed to an infinite stream for every bin. + +Downstream peer on the other hand needs to make sure that they can only be finger pointed about a chunk they did receive and store. +For this the check of a state should be exhaustive. If historical syncing finishes on one state, all hashes before are covered, no +surprises. In other words historical syncing this process is self verifying. With session syncing however, it is not enough to check going back covering the range from old offset to new. Continuity (i.e., that the new state is extension of the old) needs to be verified: after downstream peer reads the range into a buffer, it appends the buffer the last known state at the last known offset and verifies the resulting hash matches +the latest state. Past intervals of historical syncing are checked via the the session root. +Upstream peer signs the states, downstream peers can use as handover proofs. +Downstream peers sign off on a state together with an initial offset. + +Once historical syncing is complete and the session does not lag, downstream peer only preserves the latest upstream state and store the signed version. + +Upstream peer needs to keep the latest takeover states: each deleted chunk's hash should be covered by takeover proof of at least one peer. If historical syncing is complete, upstream peer typically will store only the latest takeover proof from downstream peer. +Crucially, the structure is totally independent of the number of peers in the bin, so it scales extremely well. + +## implementation + +The simplest protocol just involves upstream peer to prefix the key with the kademlia proximity order (say 0-15 or 0-31) +and simply iterate on index per bin when syncing with a peer. + +priority queues are used for sending chunks so that user triggered requests should be responded to first, session syncing second, and historical with lower priority. +The request on chunks remains implemented as a dataless entry in the memory store. +The lifecycle of this object should be more carefully thought through, ie., when it fails to retrieve it should be removed. diff --git a/swarm/network/bitvector/bitvector.go b/swarm/network/bitvector/bitvector.go new file mode 100644 index 0000000000..edc7c50cb7 --- /dev/null +++ b/swarm/network/bitvector/bitvector.go @@ -0,0 +1,66 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package bitvector + +import ( + "errors" +) + +var errInvalidLength = errors.New("invalid length") + +type BitVector struct { + len int + b []byte +} + +func New(l int) (bv *BitVector, err error) { + return NewFromBytes(make([]byte, l/8+1), l) +} + +func NewFromBytes(b []byte, l int) (bv *BitVector, err error) { + if l <= 0 { + return nil, errInvalidLength + } + if len(b)*8 < l { + return nil, errInvalidLength + } + return &BitVector{ + len: l, + b: b, + }, nil +} + +func (bv *BitVector) Get(i int) bool { + bi := i / 8 + return bv.b[bi]&(0x1<. + +package bitvector + +import "testing" + +func TestBitvectorNew(t *testing.T) { + _, err := New(0) + if err != errInvalidLength { + t.Errorf("expected err %v, got %v", errInvalidLength, err) + } + + _, err = NewFromBytes(nil, 0) + if err != errInvalidLength { + t.Errorf("expected err %v, got %v", errInvalidLength, err) + } + + _, err = NewFromBytes([]byte{0}, 9) + if err != errInvalidLength { + t.Errorf("expected err %v, got %v", errInvalidLength, err) + } + + _, err = NewFromBytes(make([]byte, 8), 8) + if err != nil { + t.Error(err) + } +} + +func TestBitvectorGetSet(t *testing.T) { + for _, length := range []int{ + 1, + 2, + 4, + 8, + 9, + 15, + 16, + } { + bv, err := New(length) + if err != nil { + t.Errorf("error for length %v: %v", length, err) + } + + for i := 0; i < length; i++ { + if bv.Get(i) { + t.Errorf("expected false for element on index %v", i) + } + } + + func() { + defer func() { + if err := recover(); err == nil { + t.Errorf("expecting panic") + } + }() + bv.Get(length + 8) + }() + + for i := 0; i < length; i++ { + bv.Set(i, true) + for j := 0; j < length; j++ { + if j == i { + if !bv.Get(j) { + t.Errorf("element on index %v is not set to true", i) + } + } else { + if bv.Get(j) { + t.Errorf("element on index %v is not false", i) + } + } + } + + bv.Set(i, false) + + if bv.Get(i) { + t.Errorf("element on index %v is not set to false", i) + } + } + } +} + +func TestBitvectorNewFromBytesGet(t *testing.T) { + bv, err := NewFromBytes([]byte{8}, 8) + if err != nil { + t.Error(err) + } + if !bv.Get(3) { + t.Fatalf("element 3 is not set to true: state %08b", bv.b[0]) + } +} diff --git a/swarm/network/common.go b/swarm/network/common.go new file mode 100644 index 0000000000..15b2e20604 --- /dev/null +++ b/swarm/network/common.go @@ -0,0 +1,30 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package network + +import ( + "fmt" + "strings" +) + +func LogAddrs(nns [][]byte) string { + var nnsa []string + for _, nn := range nns { + nnsa = append(nnsa, fmt.Sprintf("%08x", nn[:4])) + } + return strings.Join(nnsa, ", ") +} diff --git a/swarm/network/depo.go b/swarm/network/depo.go deleted file mode 100644 index 5ffbf8be11..0000000000 --- a/swarm/network/depo.go +++ /dev/null @@ -1,232 +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 network - -import ( - "bytes" - "encoding/binary" - "fmt" - "time" - - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/metrics" - "github.com/ethereum/go-ethereum/swarm/storage" -) - -//metrics variables -var ( - syncReceiveCount = metrics.NewRegisteredCounter("network.sync.recv.count", nil) - syncReceiveIgnore = metrics.NewRegisteredCounter("network.sync.recv.ignore", nil) - syncSendCount = metrics.NewRegisteredCounter("network.sync.send.count", nil) - syncSendRefused = metrics.NewRegisteredCounter("network.sync.send.refused", nil) - syncSendNotFound = metrics.NewRegisteredCounter("network.sync.send.notfound", nil) -) - -// Handler for storage/retrieval related protocol requests -// implements the StorageHandler interface used by the bzz protocol -type Depo struct { - hashfunc storage.SwarmHasher - localStore storage.ChunkStore - netStore storage.ChunkStore -} - -func NewDepo(hash storage.SwarmHasher, localStore, remoteStore storage.ChunkStore) *Depo { - return &Depo{ - hashfunc: hash, - localStore: localStore, - netStore: remoteStore, // entrypoint internal - } -} - -// Handles UnsyncedKeysMsg after msg decoding - unsynced hashes upto sync state -// * the remote sync state is just stored and handled in protocol -// * filters through the new syncRequests and send the ones missing -// * back immediately as a deliveryRequest message -// * empty message just pings back for more (is this needed?) -// * strict signed sync states may be needed. -func (self *Depo) HandleUnsyncedKeysMsg(req *unsyncedKeysMsgData, p *peer) error { - unsynced := req.Unsynced - var missing []*syncRequest - var chunk *storage.Chunk - var err error - for _, req := range unsynced { - // skip keys that are found, - chunk, err = self.localStore.Get(req.Key[:]) - if err != nil || chunk.SData == nil { - missing = append(missing, req) - } - } - log.Debug(fmt.Sprintf("Depo.HandleUnsyncedKeysMsg: received %v unsynced keys: %v missing. new state: %v", len(unsynced), len(missing), req.State)) - log.Trace(fmt.Sprintf("Depo.HandleUnsyncedKeysMsg: received %v", unsynced)) - // send delivery request with missing keys - err = p.deliveryRequest(missing) - if err != nil { - return err - } - // set peers state to persist - p.syncState = req.State - return nil -} - -// Handles deliveryRequestMsg -// * serves actual chunks asked by the remote peer -// by pushing to the delivery queue (sync db) of the correct priority -// (remote peer is free to reprioritize) -// * the message implies remote peer wants more, so trigger for -// * new outgoing unsynced keys message is fired -func (self *Depo) HandleDeliveryRequestMsg(req *deliveryRequestMsgData, p *peer) error { - deliver := req.Deliver - // queue the actual delivery of a chunk () - log.Trace(fmt.Sprintf("Depo.HandleDeliveryRequestMsg: received %v delivery requests: %v", len(deliver), deliver)) - for _, sreq := range deliver { - // TODO: look up in cache here or in deliveries - // priorities are taken from the message so the remote party can - // reprioritise to at their leisure - // r = self.pullCached(sreq.Key) // pulls and deletes from cache - Push(p, sreq.Key, sreq.Priority) - } - - // sends it out as unsyncedKeysMsg - p.syncer.sendUnsyncedKeys() - return nil -} - -// the entrypoint for store requests coming from the bzz wire protocol -// if key found locally, return. otherwise -// remote is untrusted, so hash is verified and chunk passed on to NetStore -func (self *Depo) HandleStoreRequestMsg(req *storeRequestMsgData, p *peer) { - var islocal bool - req.from = p - chunk, err := self.localStore.Get(req.Key) - switch { - case err != nil: - log.Trace(fmt.Sprintf("Depo.handleStoreRequest: %v not found locally. create new chunk/request", req.Key)) - // not found in memory cache, ie., a genuine store request - // create chunk - syncReceiveCount.Inc(1) - chunk = storage.NewChunk(req.Key, nil) - - case chunk.SData == nil: - // found chunk in memory store, needs the data, validate now - log.Trace(fmt.Sprintf("Depo.HandleStoreRequest: %v. request entry found", req)) - - default: - // data is found, store request ignored - // this should update access count? - syncReceiveIgnore.Inc(1) - log.Trace(fmt.Sprintf("Depo.HandleStoreRequest: %v found locally. ignore.", req)) - islocal = true - //return - } - - hasher := self.hashfunc() - hasher.Write(req.SData) - if !bytes.Equal(hasher.Sum(nil), req.Key) { - // data does not validate, ignore - // TODO: peer should be penalised/dropped? - log.Warn(fmt.Sprintf("Depo.HandleStoreRequest: chunk invalid. store request ignored: %v", req)) - return - } - - if islocal { - return - } - // update chunk with size and data - chunk.SData = req.SData // protocol validates that SData is minimum 9 bytes long (int64 size + at least one byte of data) - chunk.Size = int64(binary.LittleEndian.Uint64(req.SData[0:8])) - log.Trace(fmt.Sprintf("delivery of %v from %v", chunk, p)) - chunk.Source = p - self.netStore.Put(chunk) -} - -// entrypoint for retrieve requests coming from the bzz wire protocol -// checks swap balance - return if peer has no credit -func (self *Depo) HandleRetrieveRequestMsg(req *retrieveRequestMsgData, p *peer) { - req.from = p - // swap - record credit for 1 request - // note that only charge actual reqsearches - var err error - if p.swap != nil { - err = p.swap.Add(1) - } - if err != nil { - log.Warn(fmt.Sprintf("Depo.HandleRetrieveRequest: %v - cannot process request: %v", req.Key.Log(), err)) - return - } - - // call storage.NetStore#Get which - // blocks until local retrieval finished - // launches cloud retrieval - chunk, _ := self.netStore.Get(req.Key) - req = self.strategyUpdateRequest(chunk.Req, req) - // check if we can immediately deliver - if chunk.SData != nil { - log.Trace(fmt.Sprintf("Depo.HandleRetrieveRequest: %v - content found, delivering...", req.Key.Log())) - - if req.MaxSize == 0 || int64(req.MaxSize) >= chunk.Size { - sreq := &storeRequestMsgData{ - Id: req.Id, - Key: chunk.Key, - SData: chunk.SData, - requestTimeout: req.timeout, // - } - syncSendCount.Inc(1) - p.syncer.addRequest(sreq, DeliverReq) - } else { - syncSendRefused.Inc(1) - log.Trace(fmt.Sprintf("Depo.HandleRetrieveRequest: %v - content found, not wanted", req.Key.Log())) - } - } else { - syncSendNotFound.Inc(1) - log.Trace(fmt.Sprintf("Depo.HandleRetrieveRequest: %v - content not found locally. asked swarm for help. will get back", req.Key.Log())) - } -} - -// add peer request the chunk and decides the timeout for the response if still searching -func (self *Depo) strategyUpdateRequest(rs *storage.RequestStatus, origReq *retrieveRequestMsgData) (req *retrieveRequestMsgData) { - log.Trace(fmt.Sprintf("Depo.strategyUpdateRequest: key %v", origReq.Key.Log())) - // we do not create an alternative one - req = origReq - if rs != nil { - self.addRequester(rs, req) - req.setTimeout(self.searchTimeout(rs, req)) - } - return -} - -// decides the timeout promise sent with the immediate peers response to a retrieve request -// if timeout is explicitly set and expired -func (self *Depo) searchTimeout(rs *storage.RequestStatus, req *retrieveRequestMsgData) (timeout *time.Time) { - reqt := req.getTimeout() - t := time.Now().Add(searchTimeout) - if reqt != nil && reqt.Before(t) { - return reqt - } else { - return &t - } -} - -/* -adds a new peer to an existing open request -only add if less than requesterCount peers forwarded the same request id so far -note this is done irrespective of status (searching or found) -*/ -func (self *Depo) addRequester(rs *storage.RequestStatus, req *retrieveRequestMsgData) { - log.Trace(fmt.Sprintf("Depo.addRequester: key %v - add peer to req.Id %v", req.Key.Log(), req.Id)) - list := rs.Requesters[req.Id] - rs.Requesters[req.Id] = append(list, req) -} diff --git a/swarm/network/discovery.go b/swarm/network/discovery.go new file mode 100644 index 0000000000..55bf7c0332 --- /dev/null +++ b/swarm/network/discovery.go @@ -0,0 +1,211 @@ +// 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 network + +import ( + "context" + "fmt" + "sync" + + "github.com/ethereum/go-ethereum/swarm/pot" +) + +// discovery bzz extension for requesting and relaying node address records + +// discPeer wraps BzzPeer and embeds an Overlay connectivity driver +type discPeer struct { + *BzzPeer + overlay Overlay + sentPeers bool // whether we already sent peer closer to this address + mtx sync.RWMutex + peers map[string]bool // tracks node records sent to the peer + depth uint8 // the proximity order advertised by remote as depth of saturation +} + +// NewDiscovery constructs a discovery peer +func newDiscovery(p *BzzPeer, o Overlay) *discPeer { + d := &discPeer{ + overlay: o, + BzzPeer: p, + peers: make(map[string]bool), + } + // record remote as seen so we never send a peer its own record + d.seen(d) + return d +} + +// HandleMsg is the message handler that delegates incoming messages +func (d *discPeer) HandleMsg(ctx context.Context, msg interface{}) error { + switch msg := msg.(type) { + + case *peersMsg: + return d.handlePeersMsg(msg) + + case *subPeersMsg: + return d.handleSubPeersMsg(msg) + + default: + return fmt.Errorf("unknown message type: %T", msg) + } +} + +// NotifyDepth sends a message to all connections if depth of saturation is changed +func NotifyDepth(depth uint8, h Overlay) { + f := func(val OverlayConn, po int, _ bool) bool { + dp, ok := val.(*discPeer) + if ok { + dp.NotifyDepth(depth) + } + return true + } + h.EachConn(nil, 255, f) +} + +// NotifyPeer informs all peers about a newly added node +func NotifyPeer(p OverlayAddr, k Overlay) { + f := func(val OverlayConn, po int, _ bool) bool { + dp, ok := val.(*discPeer) + if ok { + dp.NotifyPeer(p, uint8(po)) + } + return true + } + k.EachConn(p.Address(), 255, f) +} + +// NotifyPeer notifies the remote node (recipient) about a peer if +// the peer's PO is within the recipients advertised depth +// OR the peer is closer to the recipient than self +// unless already notified during the connection session +func (d *discPeer) NotifyPeer(a OverlayAddr, po uint8) { + // immediately return + if (po < d.getDepth() && pot.ProxCmp(d.localAddr, d, a) != 1) || d.seen(a) { + return + } + // log.Trace(fmt.Sprintf("%08x peer %08x notified of peer %08x", d.localAddr.Over()[:4], d.Address()[:4], a.Address()[:4])) + resp := &peersMsg{ + Peers: []*BzzAddr{ToAddr(a)}, + } + go d.Send(context.TODO(), resp) +} + +// NotifyDepth sends a subPeers Msg to the receiver notifying them about +// a change in the depth of saturation +func (d *discPeer) NotifyDepth(po uint8) { + // log.Trace(fmt.Sprintf("%08x peer %08x notified of new depth %v", d.localAddr.Over()[:4], d.Address()[:4], po)) + go d.Send(context.TODO(), &subPeersMsg{Depth: po}) +} + +/* +peersMsg is the message to pass peer information +It is always a response to a peersRequestMsg + +The encoding of a peer address is identical the devp2p base protocol peers +messages: [IP, Port, NodeID], +Note that a node's FileStore address is not the NodeID but the hash of the NodeID. + +TODO: +To mitigate against spurious peers messages, requests should be remembered +and correctness of responses should be checked + +If the proxBin of peers in the response is incorrect the sender should be +disconnected +*/ + +// peersMsg encapsulates an array of peer addresses +// used for communicating about known peers +// relevant for bootstrapping connectivity and updating peersets +type peersMsg struct { + Peers []*BzzAddr +} + +// String pretty prints a peersMsg +func (msg peersMsg) String() string { + return fmt.Sprintf("%T: %v", msg, msg.Peers) +} + +// handlePeersMsg called by the protocol when receiving peerset (for target address) +// list of nodes ([]PeerAddr in peersMsg) is added to the overlay db using the +// Register interface method +func (d *discPeer) handlePeersMsg(msg *peersMsg) error { + // register all addresses + if len(msg.Peers) == 0 { + return nil + } + + for _, a := range msg.Peers { + d.seen(a) + NotifyPeer(a, d.overlay) + } + return d.overlay.Register(toOverlayAddrs(msg.Peers...)) +} + +// subPeers msg is communicating the depth/sharpness/focus of the overlay table of a peer +type subPeersMsg struct { + Depth uint8 +} + +// String returns the pretty printer +func (msg subPeersMsg) String() string { + return fmt.Sprintf("%T: request peers > PO%02d. ", msg, msg.Depth) +} + +func (d *discPeer) handleSubPeersMsg(msg *subPeersMsg) error { + if !d.sentPeers { + d.setDepth(msg.Depth) + var peers []*BzzAddr + d.overlay.EachConn(d.Over(), 255, func(p OverlayConn, po int, isproxbin bool) bool { + if pob, _ := pof(d, d.localAddr, 0); pob > po { + return false + } + if !d.seen(p) { + peers = append(peers, ToAddr(p.Off())) + } + return true + }) + if len(peers) > 0 { + // log.Debug(fmt.Sprintf("%08x: %v peers sent to %v", d.overlay.BaseAddr(), len(peers), d)) + go d.Send(context.TODO(), &peersMsg{Peers: peers}) + } + } + d.sentPeers = true + return nil +} + +// seen takes an Overlay peer and checks if it was sent to a peer already +// if not, marks the peer as sent +func (d *discPeer) seen(p OverlayPeer) bool { + d.mtx.Lock() + defer d.mtx.Unlock() + k := string(p.Address()) + if d.peers[k] { + return true + } + d.peers[k] = true + return false +} + +func (d *discPeer) getDepth() uint8 { + d.mtx.RLock() + defer d.mtx.RUnlock() + return d.depth +} +func (d *discPeer) setDepth(depth uint8) { + d.mtx.Lock() + defer d.mtx.Unlock() + d.depth = depth +} diff --git a/swarm/network/discovery_test.go b/swarm/network/discovery_test.go new file mode 100644 index 0000000000..0427d81cad --- /dev/null +++ b/swarm/network/discovery_test.go @@ -0,0 +1,57 @@ +// 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 network + +import ( + "testing" + + p2ptest "github.com/ethereum/go-ethereum/p2p/testing" +) + +/*** + * + * - after connect, that outgoing subpeersmsg is sent + * + */ +func TestDiscovery(t *testing.T) { + params := NewHiveParams() + s, pp := newHiveTester(t, params, 1, nil) + + id := s.IDs[0] + raddr := NewAddrFromNodeID(id) + pp.Register([]OverlayAddr{OverlayAddr(raddr)}) + + // start the hive and wait for the connection + pp.Start(s.Server) + defer pp.Stop() + + // send subPeersMsg to the peer + err := s.TestExchanges(p2ptest.Exchange{ + Label: "outgoing subPeersMsg", + Expects: []p2ptest.Expect{ + { + Code: 1, + Msg: &subPeersMsg{Depth: 0}, + Peer: id, + }, + }, + }) + + if err != nil { + t.Fatal(err) + } +} diff --git a/swarm/network/forwarding.go b/swarm/network/forwarding.go deleted file mode 100644 index 88a82a678c..0000000000 --- a/swarm/network/forwarding.go +++ /dev/null @@ -1,150 +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 network - -import ( - "fmt" - "math/rand" - "time" - - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/swarm/storage" -) - -const requesterCount = 3 - -/* -forwarder implements the CloudStore interface (use by storage.NetStore) -and serves as the cloud store backend orchestrating storage/retrieval/delivery -via the native bzz protocol -which uses an MSB logarithmic distance-based semi-permanent Kademlia table for -* recursive forwarding style routing for retrieval -* smart syncronisation -*/ - -type forwarder struct { - hive *Hive -} - -func NewForwarder(hive *Hive) *forwarder { - return &forwarder{hive: hive} -} - -// generate a unique id uint64 -func generateId() uint64 { - r := rand.New(rand.NewSource(time.Now().UnixNano())) - return uint64(r.Int63()) -} - -var searchTimeout = 3 * time.Second - -// forwarding logic -// logic propagating retrieve requests to peers given by the kademlia hive -func (self *forwarder) Retrieve(chunk *storage.Chunk) { - peers := self.hive.getPeers(chunk.Key, 0) - log.Trace(fmt.Sprintf("forwarder.Retrieve: %v - received %d peers from KΛÐΞMLIΛ...", chunk.Key.Log(), len(peers))) -OUT: - for _, p := range peers { - log.Trace(fmt.Sprintf("forwarder.Retrieve: sending retrieveRequest %v to peer [%v]", chunk.Key.Log(), p)) - for _, recipients := range chunk.Req.Requesters { - for _, recipient := range recipients { - req := recipient.(*retrieveRequestMsgData) - if req.from.Addr() == p.Addr() { - continue OUT - } - } - } - req := &retrieveRequestMsgData{ - Key: chunk.Key, - Id: generateId(), - } - var err error - if p.swap != nil { - err = p.swap.Add(-1) - } - if err == nil { - p.retrieve(req) - break OUT - } - log.Warn(fmt.Sprintf("forwarder.Retrieve: unable to send retrieveRequest to peer [%v]: %v", chunk.Key.Log(), err)) - } -} - -// requests to specific peers given by the kademlia hive -// except for peers that the store request came from (if any) -// delivery queueing taken care of by syncer -func (self *forwarder) Store(chunk *storage.Chunk) { - var n int - msg := &storeRequestMsgData{ - Key: chunk.Key, - SData: chunk.SData, - } - var source *peer - if chunk.Source != nil { - source = chunk.Source.(*peer) - } - for _, p := range self.hive.getPeers(chunk.Key, 0) { - log.Trace(fmt.Sprintf("forwarder.Store: %v %v", p, chunk)) - - if p.syncer != nil && (source == nil || p.Addr() != source.Addr()) { - n++ - Deliver(p, msg, PropagateReq) - } - } - log.Trace(fmt.Sprintf("forwarder.Store: sent to %v peers (chunk = %v)", n, chunk)) -} - -// once a chunk is found deliver it to its requesters unless timed out -func (self *forwarder) Deliver(chunk *storage.Chunk) { - // iterate over request entries - for id, requesters := range chunk.Req.Requesters { - counter := requesterCount - msg := &storeRequestMsgData{ - Key: chunk.Key, - SData: chunk.SData, - } - var n int - var req *retrieveRequestMsgData - // iterate over requesters with the same id - for id, r := range requesters { - req = r.(*retrieveRequestMsgData) - if req.timeout == nil || req.timeout.After(time.Now()) { - log.Trace(fmt.Sprintf("forwarder.Deliver: %v -> %v", req.Id, req.from)) - msg.Id = uint64(id) - Deliver(req.from, msg, DeliverReq) - n++ - counter-- - if counter <= 0 { - break - } - } - } - log.Trace(fmt.Sprintf("forwarder.Deliver: submit chunk %v (request id %v) for delivery to %v peers", chunk.Key.Log(), id, n)) - } -} - -// initiate delivery of a chunk to a particular peer via syncer#addRequest -// depending on syncer mode and priority settings and sync request type -// this either goes via confirmation roundtrip or queued or pushed directly -func Deliver(p *peer, req interface{}, ty int) { - p.syncer.addRequest(req, ty) -} - -// push chunk over to peer -func Push(p *peer, key storage.Key, priority uint) { - p.syncer.doDelivery(key, priority, p.syncer.quit) -} diff --git a/swarm/network/hive.go b/swarm/network/hive.go index 8404ffcc2a..a54a17d29d 100644 --- a/swarm/network/hive.go +++ b/swarm/network/hive.go @@ -18,386 +18,244 @@ package network import ( "fmt" - "math/rand" - "path/filepath" + "sync" "time" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/metrics" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/p2p" "github.com/ethereum/go-ethereum/p2p/discover" - "github.com/ethereum/go-ethereum/p2p/netutil" - "github.com/ethereum/go-ethereum/swarm/network/kademlia" - "github.com/ethereum/go-ethereum/swarm/storage" + "github.com/ethereum/go-ethereum/swarm/log" + "github.com/ethereum/go-ethereum/swarm/state" ) -// Hive is the logistic manager of the swarm -// it uses a generic kademlia nodetable to find best peer list -// for any target -// this is used by the netstore to search for content in the swarm -// the bzz protocol peersMsgData exchange is relayed to Kademlia -// for db storage and filtering -// connections and disconnections are reported and relayed -// to keep the nodetable uptodate +/* +Hive is the logistic manager of the swarm -var ( - peersNumGauge = metrics.NewRegisteredGauge("network.peers.num", nil) - addPeerCounter = metrics.NewRegisteredCounter("network.addpeer.count", nil) - removePeerCounter = metrics.NewRegisteredCounter("network.removepeer.count", nil) -) +When the hive is started, a forever loop is launched that +asks the Overlay Topology driver (e.g., generic kademlia nodetable) +to suggest peers to bootstrap connectivity +*/ -type Hive struct { - listenAddr func() string - callInterval uint64 - id discover.NodeID - addr kademlia.Address - kad *kademlia.Kademlia - path string - quit chan bool - toggle chan bool - more chan bool - - // for testing only - swapEnabled bool - syncEnabled bool - blockRead bool - blockWrite bool +// Overlay is the interface for kademlia (or other topology drivers) +type Overlay interface { + // suggest peers to connect to + SuggestPeer() (OverlayAddr, int, bool) + // register and deregister peer connections + On(OverlayConn) (depth uint8, changed bool) + Off(OverlayConn) + // register peer addresses + Register([]OverlayAddr) error + // iterate over connected peers + EachConn([]byte, int, func(OverlayConn, int, bool) bool) + // iterate over known peers (address records) + EachAddr([]byte, int, func(OverlayAddr, int, bool) bool) + // pretty print the connectivity + String() string + // base Overlay address of the node itself + BaseAddr() []byte + // connectivity health check used for testing + Healthy(*PeerPot) *Health } -const ( - callInterval = 3000000000 - // bucketSize = 3 - // maxProx = 8 - // proxBinSize = 4 -) - +// HiveParams holds the config options to hive type HiveParams struct { - CallInterval uint64 - KadDbPath string - *kademlia.KadParams + Discovery bool // if want discovery of not + PeersBroadcastSetSize uint8 // how many peers to use when relaying + MaxPeersPerRequest uint8 // max size for peer address batches + KeepAliveInterval time.Duration } -//create default params -func NewDefaultHiveParams() *HiveParams { - kad := kademlia.NewDefaultKadParams() - // kad.BucketSize = bucketSize - // kad.MaxProx = maxProx - // kad.ProxBinSize = proxBinSize - +// NewHiveParams returns hive config with only the +func NewHiveParams() *HiveParams { return &HiveParams{ - CallInterval: callInterval, - KadParams: kad, + Discovery: true, + PeersBroadcastSetSize: 3, + MaxPeersPerRequest: 5, + KeepAliveInterval: 500 * time.Millisecond, } } -//this can only finally be set after all config options (file, cmd line, env vars) -//have been evaluated -func (self *HiveParams) Init(path string) { - self.KadDbPath = filepath.Join(path, "bzz-peers.json") +// Hive manages network connections of the swarm node +type Hive struct { + *HiveParams // settings + Overlay // the overlay connectiviy driver + Store state.Store // storage interface to save peers across sessions + addPeer func(*discover.Node) // server callback to connect to a peer + // bookkeeping + lock sync.Mutex + ticker *time.Ticker } -func NewHive(addr common.Hash, params *HiveParams, swapEnabled, syncEnabled bool) *Hive { - kad := kademlia.New(kademlia.Address(addr), params.KadParams) +// NewHive constructs a new hive +// HiveParams: config parameters +// Overlay: connectivity driver using a network topology +// StateStore: to save peers across sessions +func NewHive(params *HiveParams, overlay Overlay, store state.Store) *Hive { return &Hive{ - callInterval: params.CallInterval, - kad: kad, - addr: kad.Addr(), - path: params.KadDbPath, - swapEnabled: swapEnabled, - syncEnabled: syncEnabled, + HiveParams: params, + Overlay: overlay, + Store: store, } } -func (self *Hive) SyncEnabled(on bool) { - self.syncEnabled = on -} - -func (self *Hive) SwapEnabled(on bool) { - self.swapEnabled = on -} - -func (self *Hive) BlockNetworkRead(on bool) { - self.blockRead = on -} - -func (self *Hive) BlockNetworkWrite(on bool) { - self.blockWrite = on -} - -// public accessor to the hive base address -func (self *Hive) Addr() kademlia.Address { - return self.addr -} - -// Start receives network info only at startup -// listedAddr is a function to retrieve listening address to advertise to peers -// connectPeer is a function to connect to a peer based on its NodeID or enode URL -// there are called on the p2p.Server which runs on the node -func (self *Hive) Start(id discover.NodeID, listenAddr func() string, connectPeer func(string) error) (err error) { - self.toggle = make(chan bool) - self.more = make(chan bool) - self.quit = make(chan bool) - self.id = id - self.listenAddr = listenAddr - err = self.kad.Load(self.path, nil) - if err != nil { - log.Warn(fmt.Sprintf("Warning: error reading kaddb '%s' (skipping): %v", self.path, err)) - err = nil +// Start stars the hive, receives p2p.Server only at startup +// server is used to connect to a peer based on its NodeID or enode URL +// these are called on the p2p.Server which runs on the node +func (h *Hive) Start(server *p2p.Server) error { + log.Info(fmt.Sprintf("%08x hive starting", h.BaseAddr()[:4])) + // if state store is specified, load peers to prepopulate the overlay address book + if h.Store != nil { + log.Info("detected an existing store. trying to load peers") + if err := h.loadPeers(); err != nil { + log.Error(fmt.Sprintf("%08x hive encoutered an error trying to load peers", h.BaseAddr()[:4])) + return err + } } + // assigns the p2p.Server#AddPeer function to connect to peers + h.addPeer = server.AddPeer + // ticker to keep the hive alive + h.ticker = time.NewTicker(h.KeepAliveInterval) // this loop is doing bootstrapping and maintains a healthy table - go self.keepAlive() - go func() { - // whenever toggled ask kademlia about most preferred peer - for alive := range self.more { - if !alive { - // receiving false closes the loop while allowing parallel routines - // to attempt to write to more (remove Peer when shutting down) - return - } - node, need, proxLimit := self.kad.Suggest() - - if node != nil && len(node.Url) > 0 { - log.Trace(fmt.Sprintf("call known bee %v", node.Url)) - // enode or any lower level connection address is unnecessary in future - // discovery table is used to look it up. - connectPeer(node.Url) - } - if need { - // a random peer is taken from the table - peers := self.kad.FindClosest(kademlia.RandomAddressAt(self.addr, rand.Intn(self.kad.MaxProx)), 1) - if len(peers) > 0 { - // a random address at prox bin 0 is sent for lookup - randAddr := kademlia.RandomAddressAt(self.addr, proxLimit) - req := &retrieveRequestMsgData{ - Key: storage.Key(randAddr[:]), - } - log.Trace(fmt.Sprintf("call any bee near %v (PO%03d) - messenger bee: %v", randAddr, proxLimit, peers[0])) - peers[0].(*peer).retrieve(req) - } else { - log.Warn(fmt.Sprintf("no peer")) - } - log.Trace(fmt.Sprintf("buzz kept alive")) - } else { - log.Info(fmt.Sprintf("no need for more bees")) - } - select { - case self.toggle <- need: - case <-self.quit: - return - } - log.Debug(fmt.Sprintf("queen's address: %v, population: %d (%d)", self.addr, self.kad.Count(), self.kad.DBCount())) - } - }() - return -} - -// keepAlive is a forever loop -// in its awake state it periodically triggers connection attempts -// by writing to self.more until Kademlia Table is saturated -// wake state is toggled by writing to self.toggle -// it restarts if the table becomes non-full again due to disconnections -func (self *Hive) keepAlive() { - alarm := time.NewTicker(time.Duration(self.callInterval)).C - for { - peersNumGauge.Update(int64(self.kad.Count())) - select { - case <-alarm: - if self.kad.DBCount() > 0 { - select { - case self.more <- true: - log.Debug(fmt.Sprintf("buzz wakeup")) - default: - } - } - case need := <-self.toggle: - if alarm == nil && need { - alarm = time.NewTicker(time.Duration(self.callInterval)).C - } - if alarm != nil && !need { - alarm = nil - - } - case <-self.quit: - return - } - } -} - -func (self *Hive) Stop() error { - // closing toggle channel quits the updateloop - close(self.quit) - return self.kad.Save(self.path, saveSync) -} - -// called at the end of a successful protocol handshake -func (self *Hive) addPeer(p *peer) error { - addPeerCounter.Inc(1) - defer func() { - select { - case self.more <- true: - default: - } - }() - log.Trace(fmt.Sprintf("hi new bee %v", p)) - err := self.kad.On(p, loadSync) - if err != nil { - return err - } - // self lookup (can be encoded as nil/zero key since peers addr known) + no id () - // the most common way of saying hi in bzz is initiation of gossip - // let me know about anyone new from my hood , here is the storageradius - // to send the 6 byte self lookup - // we do not record as request or forward it, just reply with peers - p.retrieve(&retrieveRequestMsgData{}) - log.Trace(fmt.Sprintf("'whatsup wheresdaparty' sent to %v", p)) - + go h.connect() return nil } -// called after peer disconnected -func (self *Hive) removePeer(p *peer) { - removePeerCounter.Inc(1) - log.Debug(fmt.Sprintf("bee %v removed", p)) - self.kad.Off(p, saveSync) - select { - case self.more <- true: - default: +// Stop terminates the updateloop and saves the peers +func (h *Hive) Stop() error { + log.Info(fmt.Sprintf("%08x hive stopping, saving peers", h.BaseAddr()[:4])) + h.ticker.Stop() + if h.Store != nil { + if err := h.savePeers(); err != nil { + return fmt.Errorf("could not save peers to persistence store: %v", err) + } + if err := h.Store.Close(); err != nil { + return fmt.Errorf("could not close file handle to persistence store: %v", err) + } } - if self.kad.Count() == 0 { - log.Debug(fmt.Sprintf("empty, all bees gone")) + log.Info(fmt.Sprintf("%08x hive stopped, dropping peers", h.BaseAddr()[:4])) + h.EachConn(nil, 255, func(p OverlayConn, _ int, _ bool) bool { + log.Info(fmt.Sprintf("%08x dropping peer %08x", h.BaseAddr()[:4], p.Address()[:4])) + p.Drop(nil) + return true + }) + + log.Info(fmt.Sprintf("%08x all peers dropped", h.BaseAddr()[:4])) + return nil +} + +// connect is a forever loop +// at each iteration, ask the overlay driver to suggest the most preferred peer to connect to +// as well as advertises saturation depth if needed +func (h *Hive) connect() { + for range h.ticker.C { + + addr, depth, changed := h.SuggestPeer() + if h.Discovery && changed { + NotifyDepth(uint8(depth), h) + } + if addr == nil { + continue + } + + log.Trace(fmt.Sprintf("%08x hive connect() suggested %08x", h.BaseAddr()[:4], addr.Address()[:4])) + under, err := discover.ParseNode(string(addr.(Addr).Under())) + if err != nil { + log.Warn(fmt.Sprintf("%08x unable to connect to bee %08x: invalid node URL: %v", h.BaseAddr()[:4], addr.Address()[:4], err)) + continue + } + log.Trace(fmt.Sprintf("%08x attempt to connect to bee %08x", h.BaseAddr()[:4], addr.Address()[:4])) + h.addPeer(under) } } -// Retrieve a list of live peers that are closer to target than us -func (self *Hive) getPeers(target storage.Key, max int) (peers []*peer) { - var addr kademlia.Address - copy(addr[:], target[:]) - for _, node := range self.kad.FindClosest(addr, max) { - peers = append(peers, node.(*peer)) +// Run protocol run function +func (h *Hive) Run(p *BzzPeer) error { + dp := newDiscovery(p, h) + depth, changed := h.On(dp) + // if we want discovery, advertise change of depth + if h.Discovery { + if changed { + // if depth changed, send to all peers + NotifyDepth(depth, h) + } else { + // otherwise just send depth to new peer + dp.NotifyDepth(depth) + } + } + NotifyPeer(p.Off(), h) + defer h.Off(dp) + return dp.Run(dp.HandleMsg) +} + +// NodeInfo function is used by the p2p.server RPC interface to display +// protocol specific node information +func (h *Hive) NodeInfo() interface{} { + return h.String() +} + +// PeerInfo function is used by the p2p.server RPC interface to display +// protocol specific information any connected peer referred to by their NodeID +func (h *Hive) PeerInfo(id discover.NodeID) interface{} { + addr := NewAddrFromNodeID(id) + return struct { + OAddr hexutil.Bytes + UAddr hexutil.Bytes + }{ + OAddr: addr.OAddr, + UAddr: addr.UAddr, + } +} + +// ToAddr returns the serialisable version of u +func ToAddr(pa OverlayPeer) *BzzAddr { + if addr, ok := pa.(*BzzAddr); ok { + return addr + } + if p, ok := pa.(*discPeer); ok { + return p.BzzAddr + } + return pa.(*BzzPeer).BzzAddr +} + +// loadPeers, savePeer implement persistence callback/ +func (h *Hive) loadPeers() error { + var as []*BzzAddr + err := h.Store.Get("peers", &as) + if err != nil { + if err == state.ErrNotFound { + log.Info(fmt.Sprintf("hive %08x: no persisted peers found", h.BaseAddr()[:4])) + return nil + } + return err + } + log.Info(fmt.Sprintf("hive %08x: peers loaded", h.BaseAddr()[:4])) + + return h.Register(toOverlayAddrs(as...)) +} + +// toOverlayAddrs transforms an array of BzzAddr to OverlayAddr +func toOverlayAddrs(as ...*BzzAddr) (oas []OverlayAddr) { + for _, a := range as { + oas = append(oas, OverlayAddr(a)) } return } -// disconnects all the peers -func (self *Hive) DropAll() { - log.Info(fmt.Sprintf("dropping all bees")) - for _, node := range self.kad.FindClosest(kademlia.Address{}, 0) { - node.Drop() - } -} - -// contructor for kademlia.NodeRecord based on peer address alone -// TODO: should go away and only addr passed to kademlia -func newNodeRecord(addr *peerAddr) *kademlia.NodeRecord { - now := time.Now() - return &kademlia.NodeRecord{ - Addr: addr.Addr, - Url: addr.String(), - Seen: now, - After: now, - } -} - -// called by the protocol when receiving peerset (for target address) -// peersMsgData is converted to a slice of NodeRecords for Kademlia -// this is to store all thats needed -func (self *Hive) HandlePeersMsg(req *peersMsgData, from *peer) { - var nrs []*kademlia.NodeRecord - for _, p := range req.Peers { - if err := netutil.CheckRelayIP(from.remoteAddr.IP, p.IP); err != nil { - log.Trace(fmt.Sprintf("invalid peer IP %v from %v: %v", from.remoteAddr.IP, p.IP, err)) - continue +// savePeers, savePeer implement persistence callback/ +func (h *Hive) savePeers() error { + var peers []*BzzAddr + h.Overlay.EachAddr(nil, 256, func(pa OverlayAddr, i int, _ bool) bool { + if pa == nil { + log.Warn(fmt.Sprintf("empty addr: %v", i)) + return true } - nrs = append(nrs, newNodeRecord(p)) + apa := ToAddr(pa) + log.Trace("saving peer", "peer", apa) + peers = append(peers, apa) + return true + }) + if err := h.Store.Put("peers", peers); err != nil { + return fmt.Errorf("could not save peers: %v", err) } - self.kad.Add(nrs) -} - -// peer wraps the protocol instance to represent a connected peer -// it implements kademlia.Node interface -type peer struct { - *bzz // protocol instance running on peer connection -} - -// protocol instance implements kademlia.Node interface (embedded peer) -func (self *peer) Addr() kademlia.Address { - return self.remoteAddr.Addr -} - -func (self *peer) Url() string { - return self.remoteAddr.String() -} - -// TODO take into account traffic -func (self *peer) LastActive() time.Time { - return self.lastActive -} - -// reads the serialised form of sync state persisted as the 'Meta' attribute -// and sets the decoded syncState on the online node -func loadSync(record *kademlia.NodeRecord, node kademlia.Node) error { - p, ok := node.(*peer) - if !ok { - return fmt.Errorf("invalid type") - } - if record.Meta == nil { - log.Debug(fmt.Sprintf("no sync state for node record %v setting default", record)) - p.syncState = &syncState{DbSyncState: &storage.DbSyncState{}} - return nil - } - state, err := decodeSync(record.Meta) - if err != nil { - return fmt.Errorf("error decoding kddb record meta info into a sync state: %v", err) - } - log.Trace(fmt.Sprintf("sync state for node record %v read from Meta: %s", record, string(*(record.Meta)))) - p.syncState = state - return err -} - -// callback when saving a sync state -func saveSync(record *kademlia.NodeRecord, node kademlia.Node) { - if p, ok := node.(*peer); ok { - meta, err := encodeSync(p.syncState) - if err != nil { - log.Warn(fmt.Sprintf("error saving sync state for %v: %v", node, err)) - return - } - log.Trace(fmt.Sprintf("saved sync state for %v: %s", node, string(*meta))) - record.Meta = meta - } -} - -// the immediate response to a retrieve request, -// sends relevant peer data given by the kademlia hive to the requester -// TODO: remember peers sent for duration of the session, only new peers sent -func (self *Hive) peers(req *retrieveRequestMsgData) { - if req != nil { - var addrs []*peerAddr - if req.timeout == nil || time.Now().Before(*(req.timeout)) { - key := req.Key - // self lookup from remote peer - if storage.IsZeroKey(key) { - addr := req.from.Addr() - key = storage.Key(addr[:]) - req.Key = nil - } - // get peer addresses from hive - for _, peer := range self.getPeers(key, int(req.MaxPeers)) { - addrs = append(addrs, peer.remoteAddr) - } - log.Debug(fmt.Sprintf("Hive sending %d peer addresses to %v. req.Id: %v, req.Key: %v", len(addrs), req.from, req.Id, req.Key.Log())) - - peersData := &peersMsgData{ - Peers: addrs, - Key: req.Key, - Id: req.Id, - } - peersData.setTimeout(req.timeout) - req.from.peers(peersData) - } - } -} - -func (self *Hive) String() string { - return self.kad.String() + return nil } diff --git a/swarm/network/hive_test.go b/swarm/network/hive_test.go new file mode 100644 index 0000000000..c2abfb2aad --- /dev/null +++ b/swarm/network/hive_test.go @@ -0,0 +1,108 @@ +// 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 network + +import ( + "io/ioutil" + "log" + "os" + "testing" + + p2ptest "github.com/ethereum/go-ethereum/p2p/testing" + "github.com/ethereum/go-ethereum/swarm/state" +) + +func newHiveTester(t *testing.T, params *HiveParams, n int, store state.Store) (*bzzTester, *Hive) { + // setup + addr := RandomAddr() // tested peers peer address + to := NewKademlia(addr.OAddr, NewKadParams()) + pp := NewHive(params, to, store) // hive + + return newBzzBaseTester(t, n, addr, DiscoverySpec, pp.Run), pp +} + +func TestRegisterAndConnect(t *testing.T) { + params := NewHiveParams() + s, pp := newHiveTester(t, params, 1, nil) + + id := s.IDs[0] + raddr := NewAddrFromNodeID(id) + pp.Register([]OverlayAddr{OverlayAddr(raddr)}) + + // start the hive and wait for the connection + err := pp.Start(s.Server) + if err != nil { + t.Fatal(err) + } + defer pp.Stop() + // retrieve and broadcast + err = s.TestDisconnected(&p2ptest.Disconnect{ + Peer: s.IDs[0], + Error: nil, + }) + + if err == nil || err.Error() != "timed out waiting for peers to disconnect" { + t.Fatalf("expected peer to connect") + } +} + +func TestHiveStatePersistance(t *testing.T) { + log.SetOutput(os.Stdout) + + dir, err := ioutil.TempDir("", "hive_test_store") + if err != nil { + panic(err) + } + defer os.RemoveAll(dir) + + store, err := state.NewDBStore(dir) //start the hive with an empty dbstore + + params := NewHiveParams() + s, pp := newHiveTester(t, params, 5, store) + + peers := make(map[string]bool) + for _, id := range s.IDs { + raddr := NewAddrFromNodeID(id) + pp.Register([]OverlayAddr{OverlayAddr(raddr)}) + peers[raddr.String()] = true + } + + // start the hive and wait for the connection + err = pp.Start(s.Server) + if err != nil { + t.Fatal(err) + } + pp.Stop() + store.Close() + + persistedStore, err := state.NewDBStore(dir) //start the hive with an empty dbstore + + s1, pp := newHiveTester(t, params, 1, persistedStore) + + //start the hive and wait for the connection + + pp.Start(s1.Server) + i := 0 + pp.Overlay.EachAddr(nil, 256, func(addr OverlayAddr, po int, nn bool) bool { + delete(peers, addr.(*BzzAddr).String()) + i++ + return true + }) + if len(peers) != 0 || i != 5 { + t.Fatalf("invalid peers loaded") + } +} diff --git a/swarm/network/kademlia.go b/swarm/network/kademlia.go new file mode 100644 index 0000000000..0177d449c4 --- /dev/null +++ b/swarm/network/kademlia.go @@ -0,0 +1,765 @@ +// 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 network + +import ( + "bytes" + "fmt" + "math/rand" + "strings" + "sync" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/swarm/log" + "github.com/ethereum/go-ethereum/swarm/pot" +) + +/* + +Taking the proximity order relative to a fix point x classifies the points in +the space (n byte long byte sequences) into bins. Items in each are at +most half as distant from x as items in the previous bin. Given a sample of +uniformly distributed items (a hash function over arbitrary sequence) the +proximity scale maps onto series of subsets with cardinalities on a negative +exponential scale. + +It also has the property that any two item belonging to the same bin are at +most half as distant from each other as they are from x. + +If we think of random sample of items in the bins as connections in a network of +interconnected nodes then relative proximity can serve as the basis for local +decisions for graph traversal where the task is to find a route between two +points. Since in every hop, the finite distance halves, there is +a guaranteed constant maximum limit on the number of hops needed to reach one +node from the other. +*/ + +var pof = pot.DefaultPof(256) + +// KadParams holds the config params for Kademlia +type KadParams struct { + // adjustable parameters + MaxProxDisplay int // number of rows the table shows + MinProxBinSize int // nearest neighbour core minimum cardinality + MinBinSize int // minimum number of peers in a row + MaxBinSize int // maximum number of peers in a row before pruning + RetryInterval int64 // initial interval before a peer is first redialed + RetryExponent int // exponent to multiply retry intervals with + MaxRetries int // maximum number of redial attempts + // function to sanction or prevent suggesting a peer + Reachable func(OverlayAddr) bool +} + +// NewKadParams returns a params struct with default values +func NewKadParams() *KadParams { + return &KadParams{ + MaxProxDisplay: 16, + MinProxBinSize: 2, + MinBinSize: 2, + MaxBinSize: 4, + RetryInterval: 4200000000, // 4.2 sec + MaxRetries: 42, + RetryExponent: 2, + } +} + +// Kademlia is a table of live peers and a db of known peers (node records) +type Kademlia struct { + lock sync.RWMutex + *KadParams // Kademlia configuration parameters + base []byte // immutable baseaddress of the table + addrs *pot.Pot // pots container for known peer addresses + conns *pot.Pot // pots container for live peer connections + depth uint8 // stores the last current depth of saturation + nDepth int // stores the last neighbourhood depth + nDepthC chan int // returned by DepthC function to signal neighbourhood depth change + addrCountC chan int // returned by AddrCountC function to signal peer count change +} + +// NewKademlia creates a Kademlia table for base address addr +// with parameters as in params +// if params is nil, it uses default values +func NewKademlia(addr []byte, params *KadParams) *Kademlia { + if params == nil { + params = NewKadParams() + } + return &Kademlia{ + base: addr, + KadParams: params, + addrs: pot.NewPot(nil, 0), + conns: pot.NewPot(nil, 0), + } +} + +// OverlayPeer interface captures the common aspect of view of a peer from the Overlay +// topology driver +type OverlayPeer interface { + Address() []byte +} + +// OverlayConn represents a connected peer +type OverlayConn interface { + OverlayPeer + Drop(error) // call to indicate a peer should be expunged + Off() OverlayAddr // call to return a persitent OverlayAddr +} + +// OverlayAddr represents a kademlia peer record +type OverlayAddr interface { + OverlayPeer + Update(OverlayAddr) OverlayAddr // returns the updated version of the original +} + +// entry represents a Kademlia table entry (an extension of OverlayPeer) +type entry struct { + OverlayPeer + seenAt time.Time + retries int +} + +// newEntry creates a kademlia peer from an OverlayPeer interface +func newEntry(p OverlayPeer) *entry { + return &entry{ + OverlayPeer: p, + seenAt: time.Now(), + } +} + +// Bin is the binary (bitvector) serialisation of the entry address +func (e *entry) Bin() string { + return pot.ToBin(e.addr().Address()) +} + +// Label is a short tag for the entry for debug +func Label(e *entry) string { + return fmt.Sprintf("%s (%d)", e.Hex()[:4], e.retries) +} + +// Hex is the hexadecimal serialisation of the entry address +func (e *entry) Hex() string { + return fmt.Sprintf("%x", e.addr().Address()) +} + +// String is the short tag for the entry +func (e *entry) String() string { + return fmt.Sprintf("%s (%d)", e.Hex()[:8], e.retries) +} + +// addr returns the kad peer record (OverlayAddr) corresponding to the entry +func (e *entry) addr() OverlayAddr { + a, _ := e.OverlayPeer.(OverlayAddr) + return a +} + +// conn returns the connected peer (OverlayPeer) corresponding to the entry +func (e *entry) conn() OverlayConn { + c, _ := e.OverlayPeer.(OverlayConn) + return c +} + +// Register enters each OverlayAddr as kademlia peer record into the +// database of known peer addresses +func (k *Kademlia) Register(peers []OverlayAddr) error { + k.lock.Lock() + defer k.lock.Unlock() + var known, size int + for _, p := range peers { + // error if self received, peer should know better + // and should be punished for this + if bytes.Equal(p.Address(), k.base) { + return fmt.Errorf("add peers: %x is self", k.base) + } + var found bool + k.addrs, _, found, _ = pot.Swap(k.addrs, p, pof, func(v pot.Val) pot.Val { + // if not found + if v == nil { + // insert new offline peer into conns + return newEntry(p) + } + // found among known peers, do nothing + return v + }) + if found { + known++ + } + size++ + } + // send new address count value only if there are new addresses + if k.addrCountC != nil && size-known > 0 { + k.addrCountC <- k.addrs.Size() + } + // log.Trace(fmt.Sprintf("%x registered %v peers, %v known, total: %v", k.BaseAddr()[:4], size, known, k.addrs.Size())) + + k.sendNeighbourhoodDepthChange() + return nil +} + +// SuggestPeer returns a known peer for the lowest proximity bin for the +// lowest bincount below depth +// naturally if there is an empty row it returns a peer for that +func (k *Kademlia) SuggestPeer() (a OverlayAddr, o int, want bool) { + k.lock.Lock() + defer k.lock.Unlock() + minsize := k.MinBinSize + depth := k.neighbourhoodDepth() + // if there is a callable neighbour within the current proxBin, connect + // this makes sure nearest neighbour set is fully connected + var ppo int + k.addrs.EachNeighbour(k.base, pof, func(val pot.Val, po int) bool { + if po < depth { + return false + } + a = k.callable(val) + ppo = po + return a == nil + }) + if a != nil { + log.Trace(fmt.Sprintf("%08x candidate nearest neighbour found: %v (%v)", k.BaseAddr()[:4], a, ppo)) + return a, 0, false + } + // log.Trace(fmt.Sprintf("%08x no candidate nearest neighbours to connect to (Depth: %v, minProxSize: %v) %#v", k.BaseAddr()[:4], depth, k.MinProxBinSize, a)) + + var bpo []int + prev := -1 + k.conns.EachBin(k.base, pof, 0, func(po, size int, f func(func(val pot.Val, i int) bool) bool) bool { + prev++ + for ; prev < po; prev++ { + bpo = append(bpo, prev) + minsize = 0 + } + if size < minsize { + bpo = append(bpo, po) + minsize = size + } + return size > 0 && po < depth + }) + // all buckets are full, ie., minsize == k.MinBinSize + if len(bpo) == 0 { + // log.Debug(fmt.Sprintf("%08x: all bins saturated", k.BaseAddr()[:4])) + return nil, 0, false + } + // as long as we got candidate peers to connect to + // dont ask for new peers (want = false) + // try to select a candidate peer + // find the first callable peer + nxt := bpo[0] + k.addrs.EachBin(k.base, pof, nxt, func(po, _ int, f func(func(pot.Val, int) bool) bool) bool { + // for each bin (up until depth) we find callable candidate peers + if po >= depth { + return false + } + return f(func(val pot.Val, _ int) bool { + a = k.callable(val) + return a == nil + }) + }) + // found a candidate + if a != nil { + return a, 0, false + } + // no candidate peer found, request for the short bin + var changed bool + if uint8(nxt) < k.depth { + k.depth = uint8(nxt) + changed = true + } + return a, nxt, changed +} + +// On inserts the peer as a kademlia peer into the live peers +func (k *Kademlia) On(p OverlayConn) (uint8, bool) { + k.lock.Lock() + defer k.lock.Unlock() + e := newEntry(p) + var ins bool + k.conns, _, _, _ = pot.Swap(k.conns, p, pof, func(v pot.Val) pot.Val { + // if not found live + if v == nil { + ins = true + // insert new online peer into conns + return e + } + // found among live peers, do nothing + return v + }) + if ins { + // insert new online peer into addrs + k.addrs, _, _, _ = pot.Swap(k.addrs, p, pof, func(v pot.Val) pot.Val { + return e + }) + // send new address count value only if the peer is inserted + if k.addrCountC != nil { + k.addrCountC <- k.addrs.Size() + } + } + log.Trace(k.string()) + // calculate if depth of saturation changed + depth := uint8(k.saturation(k.MinBinSize)) + var changed bool + if depth != k.depth { + changed = true + k.depth = depth + } + k.sendNeighbourhoodDepthChange() + return k.depth, changed +} + +// NeighbourhoodDepthC returns the channel that sends a new kademlia +// neighbourhood depth on each change. +// Not receiving from the returned channel will block On function +// when the neighbourhood depth is changed. +func (k *Kademlia) NeighbourhoodDepthC() <-chan int { + if k.nDepthC == nil { + k.nDepthC = make(chan int) + } + return k.nDepthC +} + +// sendNeighbourhoodDepthChange sends new neighbourhood depth to k.nDepth channel +// if it is initialized. +func (k *Kademlia) sendNeighbourhoodDepthChange() { + // nDepthC is initialized when NeighbourhoodDepthC is called and returned by it. + // It provides signaling of neighbourhood depth change. + // This part of the code is sending new neighbourhood depth to nDepthC if that condition is met. + if k.nDepthC != nil { + nDepth := k.neighbourhoodDepth() + if nDepth != k.nDepth { + k.nDepth = nDepth + k.nDepthC <- nDepth + } + } +} + +// AddrCountC returns the channel that sends a new +// address count value on each change. +// Not receiving from the returned channel will block Register function +// when address count value changes. +func (k *Kademlia) AddrCountC() <-chan int { + if k.addrCountC == nil { + k.addrCountC = make(chan int) + } + return k.addrCountC +} + +// Off removes a peer from among live peers +func (k *Kademlia) Off(p OverlayConn) { + k.lock.Lock() + defer k.lock.Unlock() + var del bool + k.addrs, _, _, _ = pot.Swap(k.addrs, p, pof, func(v pot.Val) pot.Val { + // v cannot be nil, must check otherwise we overwrite entry + if v == nil { + panic(fmt.Sprintf("connected peer not found %v", p)) + } + del = true + return newEntry(p.Off()) + }) + + if del { + k.conns, _, _, _ = pot.Swap(k.conns, p, pof, func(_ pot.Val) pot.Val { + // v cannot be nil, but no need to check + return nil + }) + // send new address count value only if the peer is deleted + if k.addrCountC != nil { + k.addrCountC <- k.addrs.Size() + } + k.sendNeighbourhoodDepthChange() + } +} + +func (k *Kademlia) EachBin(base []byte, pof pot.Pof, o int, eachBinFunc func(conn OverlayConn, po int) bool) { + k.lock.RLock() + defer k.lock.RUnlock() + + var startPo int + var endPo int + kadDepth := k.neighbourhoodDepth() + + k.conns.EachBin(base, pof, o, func(po, size int, f func(func(val pot.Val, i int) bool) bool) bool { + if startPo > 0 && endPo != k.MaxProxDisplay { + startPo = endPo + 1 + } + if po < kadDepth { + endPo = po + } else { + endPo = k.MaxProxDisplay + } + + for bin := startPo; bin <= endPo; bin++ { + f(func(val pot.Val, _ int) bool { + return eachBinFunc(val.(*entry).conn(), bin) + }) + } + return true + }) +} + +// EachConn is an iterator with args (base, po, f) applies f to each live peer +// that has proximity order po or less as measured from the base +// if base is nil, kademlia base address is used +func (k *Kademlia) EachConn(base []byte, o int, f func(OverlayConn, int, bool) bool) { + k.lock.RLock() + defer k.lock.RUnlock() + k.eachConn(base, o, f) +} + +func (k *Kademlia) eachConn(base []byte, o int, f func(OverlayConn, int, bool) bool) { + if len(base) == 0 { + base = k.base + } + depth := k.neighbourhoodDepth() + k.conns.EachNeighbour(base, pof, func(val pot.Val, po int) bool { + if po > o { + return true + } + return f(val.(*entry).conn(), po, po >= depth) + }) +} + +// EachAddr called with (base, po, f) is an iterator applying f to each known peer +// that has proximity order po or less as measured from the base +// if base is nil, kademlia base address is used +func (k *Kademlia) EachAddr(base []byte, o int, f func(OverlayAddr, int, bool) bool) { + k.lock.RLock() + defer k.lock.RUnlock() + k.eachAddr(base, o, f) +} + +func (k *Kademlia) eachAddr(base []byte, o int, f func(OverlayAddr, int, bool) bool) { + if len(base) == 0 { + base = k.base + } + depth := k.neighbourhoodDepth() + k.addrs.EachNeighbour(base, pof, func(val pot.Val, po int) bool { + if po > o { + return true + } + return f(val.(*entry).addr(), po, po >= depth) + }) +} + +// neighbourhoodDepth returns the proximity order that defines the distance of +// the nearest neighbour set with cardinality >= MinProxBinSize +// if there is altogether less than MinProxBinSize peers it returns 0 +// caller must hold the lock +func (k *Kademlia) neighbourhoodDepth() (depth int) { + if k.conns.Size() < k.MinProxBinSize { + return 0 + } + var size int + f := func(v pot.Val, i int) bool { + size++ + depth = i + return size < k.MinProxBinSize + } + k.conns.EachNeighbour(k.base, pof, f) + return depth +} + +// callable when called with val, +func (k *Kademlia) callable(val pot.Val) OverlayAddr { + e := val.(*entry) + // not callable if peer is live or exceeded maxRetries + if e.conn() != nil || e.retries > k.MaxRetries { + return nil + } + // calculate the allowed number of retries based on time lapsed since last seen + timeAgo := int64(time.Since(e.seenAt)) + div := int64(k.RetryExponent) + div += (150000 - rand.Int63n(300000)) * div / 1000000 + var retries int + for delta := timeAgo; delta > k.RetryInterval; delta /= div { + retries++ + } + // this is never called concurrently, so safe to increment + // peer can be retried again + if retries < e.retries { + log.Trace(fmt.Sprintf("%08x: %v long time since last try (at %v) needed before retry %v, wait only warrants %v", k.BaseAddr()[:4], e, timeAgo, e.retries, retries)) + return nil + } + // function to sanction or prevent suggesting a peer + if k.Reachable != nil && !k.Reachable(e.addr()) { + log.Trace(fmt.Sprintf("%08x: peer %v is temporarily not callable", k.BaseAddr()[:4], e)) + return nil + } + e.retries++ + log.Trace(fmt.Sprintf("%08x: peer %v is callable", k.BaseAddr()[:4], e)) + + return e.addr() +} + +// BaseAddr return the kademlia base address +func (k *Kademlia) BaseAddr() []byte { + return k.base +} + +// String returns kademlia table + kaddb table displayed with ascii +func (k *Kademlia) String() string { + k.lock.RLock() + defer k.lock.RUnlock() + return k.string() +} + +// String returns kademlia table + kaddb table displayed with ascii +func (k *Kademlia) string() string { + wsrow := " " + var rows []string + + rows = append(rows, "=========================================================================") + rows = append(rows, fmt.Sprintf("%v KΛÐΞMLIΛ hive: queen's address: %x", time.Now().UTC().Format(time.UnixDate), k.BaseAddr()[:3])) + rows = append(rows, fmt.Sprintf("population: %d (%d), MinProxBinSize: %d, MinBinSize: %d, MaxBinSize: %d", k.conns.Size(), k.addrs.Size(), k.MinProxBinSize, k.MinBinSize, k.MaxBinSize)) + + liverows := make([]string, k.MaxProxDisplay) + peersrows := make([]string, k.MaxProxDisplay) + + depth := k.neighbourhoodDepth() + rest := k.conns.Size() + k.conns.EachBin(k.base, pof, 0, func(po, size int, f func(func(val pot.Val, i int) bool) bool) bool { + var rowlen int + if po >= k.MaxProxDisplay { + po = k.MaxProxDisplay - 1 + } + row := []string{fmt.Sprintf("%2d", size)} + rest -= size + f(func(val pot.Val, vpo int) bool { + e := val.(*entry) + row = append(row, fmt.Sprintf("%x", e.Address()[:2])) + rowlen++ + return rowlen < 4 + }) + r := strings.Join(row, " ") + r = r + wsrow + liverows[po] = r[:31] + return true + }) + + k.addrs.EachBin(k.base, pof, 0, func(po, size int, f func(func(val pot.Val, i int) bool) bool) bool { + var rowlen int + if po >= k.MaxProxDisplay { + po = k.MaxProxDisplay - 1 + } + if size < 0 { + panic("wtf") + } + row := []string{fmt.Sprintf("%2d", size)} + // we are displaying live peers too + f(func(val pot.Val, vpo int) bool { + e := val.(*entry) + row = append(row, Label(e)) + rowlen++ + return rowlen < 4 + }) + peersrows[po] = strings.Join(row, " ") + return true + }) + + for i := 0; i < k.MaxProxDisplay; i++ { + if i == depth { + rows = append(rows, fmt.Sprintf("============ DEPTH: %d ==========================================", i)) + } + left := liverows[i] + right := peersrows[i] + if len(left) == 0 { + left = " 0 " + } + if len(right) == 0 { + right = " 0" + } + rows = append(rows, fmt.Sprintf("%03d %v | %v", i, left, right)) + } + rows = append(rows, "=========================================================================") + return "\n" + strings.Join(rows, "\n") +} + +// PeerPot keeps info about expected nearest neighbours and empty bins +// used for testing only +type PeerPot struct { + NNSet [][]byte + EmptyBins []int +} + +// NewPeerPotMap creates a map of pot record of OverlayAddr with keys +// as hexadecimal representations of the address. +func NewPeerPotMap(kadMinProxSize int, addrs [][]byte) map[string]*PeerPot { + // create a table of all nodes for health check + np := pot.NewPot(nil, 0) + for _, addr := range addrs { + np, _, _ = pot.Add(np, addr, pof) + } + ppmap := make(map[string]*PeerPot) + + for i, a := range addrs { + pl := 256 + prev := 256 + var emptyBins []int + var nns [][]byte + np.EachNeighbour(addrs[i], pof, func(val pot.Val, po int) bool { + a := val.([]byte) + if po == 256 { + return true + } + if pl == 256 || pl == po { + nns = append(nns, a) + } + if pl == 256 && len(nns) >= kadMinProxSize { + pl = po + prev = po + } + if prev < pl { + for j := prev; j > po; j-- { + emptyBins = append(emptyBins, j) + } + } + prev = po - 1 + return true + }) + for j := prev; j >= 0; j-- { + emptyBins = append(emptyBins, j) + } + log.Trace(fmt.Sprintf("%x NNS: %s", addrs[i][:4], LogAddrs(nns))) + ppmap[common.Bytes2Hex(a)] = &PeerPot{nns, emptyBins} + } + return ppmap +} + +// saturation returns the lowest proximity order that the bin for that order +// has less than n peers +func (k *Kademlia) saturation(n int) int { + prev := -1 + k.addrs.EachBin(k.base, pof, 0, func(po, size int, f func(func(val pot.Val, i int) bool) bool) bool { + prev++ + return prev == po && size >= n + }) + depth := k.neighbourhoodDepth() + if depth < prev { + return depth + } + return prev +} + +// full returns true if all required bins have connected peers. +// It is used in Healthy function. +func (k *Kademlia) full(emptyBins []int) (full bool) { + prev := 0 + e := len(emptyBins) + ok := true + depth := k.neighbourhoodDepth() + k.conns.EachBin(k.base, pof, 0, func(po, _ int, _ func(func(val pot.Val, i int) bool) bool) bool { + if prev == depth+1 { + return true + } + for i := prev; i < po; i++ { + e-- + if e < 0 { + ok = false + return false + } + if emptyBins[e] != i { + log.Trace(fmt.Sprintf("%08x po: %d, i: %d, e: %d, emptybins: %v", k.BaseAddr()[:4], po, i, e, logEmptyBins(emptyBins))) + if emptyBins[e] < i { + panic("incorrect peerpot") + } + ok = false + return false + } + } + prev = po + 1 + return true + }) + if !ok { + return false + } + return e == 0 +} + +func (k *Kademlia) knowNearestNeighbours(peers [][]byte) bool { + pm := make(map[string]bool) + + k.eachAddr(nil, 255, func(p OverlayAddr, po int, nn bool) bool { + if !nn { + return false + } + pk := fmt.Sprintf("%x", p.Address()) + pm[pk] = true + return true + }) + for _, p := range peers { + pk := fmt.Sprintf("%x", p) + if !pm[pk] { + log.Trace(fmt.Sprintf("%08x: known nearest neighbour %s not found", k.BaseAddr()[:4], pk[:8])) + return false + } + } + return true +} + +func (k *Kademlia) gotNearestNeighbours(peers [][]byte) (got bool, n int, missing [][]byte) { + pm := make(map[string]bool) + + k.eachConn(nil, 255, func(p OverlayConn, po int, nn bool) bool { + if !nn { + return false + } + pk := fmt.Sprintf("%x", p.Address()) + pm[pk] = true + return true + }) + var gots int + var culprits [][]byte + for _, p := range peers { + pk := fmt.Sprintf("%x", p) + if pm[pk] { + gots++ + } else { + log.Trace(fmt.Sprintf("%08x: ExpNN: %s not found", k.BaseAddr()[:4], pk[:8])) + culprits = append(culprits, p) + } + } + return gots == len(peers), gots, culprits +} + +// Health state of the Kademlia +type Health struct { + KnowNN bool // whether node knows all its nearest neighbours + GotNN bool // whether node is connected to all its nearest neighbours + CountNN int // amount of nearest neighbors connected to + CulpritsNN [][]byte // which known NNs are missing + Full bool // whether node has a peer in each kademlia bin (where there is such a peer) + Hive string +} + +// Healthy reports the health state of the kademlia connectivity +// returns a Health struct +func (k *Kademlia) Healthy(pp *PeerPot) *Health { + k.lock.RLock() + defer k.lock.RUnlock() + gotnn, countnn, culpritsnn := k.gotNearestNeighbours(pp.NNSet) + knownn := k.knowNearestNeighbours(pp.NNSet) + full := k.full(pp.EmptyBins) + log.Trace(fmt.Sprintf("%08x: healthy: knowNNs: %v, gotNNs: %v, full: %v\n", k.BaseAddr()[:4], knownn, gotnn, full)) + return &Health{knownn, gotnn, countnn, culpritsnn, full, k.string()} +} + +func logEmptyBins(ebs []int) string { + var ebss []string + for _, eb := range ebs { + ebss = append(ebss, fmt.Sprintf("%d", eb)) + } + return strings.Join(ebss, ", ") +} diff --git a/swarm/network/kademlia/address.go b/swarm/network/kademlia/address.go deleted file mode 100644 index 4c38a846f9..0000000000 --- a/swarm/network/kademlia/address.go +++ /dev/null @@ -1,173 +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 kademlia - -import ( - "fmt" - "math/rand" - "strings" - - "github.com/ethereum/go-ethereum/common" -) - -type Address common.Hash - -func (a Address) String() string { - return fmt.Sprintf("%x", a[:]) -} - -func (a *Address) MarshalJSON() (out []byte, err error) { - return []byte(`"` + a.String() + `"`), nil -} - -func (a *Address) UnmarshalJSON(value []byte) error { - *a = Address(common.HexToHash(string(value[1 : len(value)-1]))) - return nil -} - -// the string form of the binary representation of an address (only first 8 bits) -func (a Address) Bin() string { - var bs []string - for _, b := range a[:] { - bs = append(bs, fmt.Sprintf("%08b", b)) - } - return strings.Join(bs, "") -} - -/* -Proximity(x, y) returns the proximity order of the MSB distance between x and y - -The distance metric MSB(x, y) of two equal length byte sequences x an y is the -value of the binary integer cast of the x^y, ie., x and y bitwise xor-ed. -the binary cast is big endian: most significant bit first (=MSB). - -Proximity(x, y) is a discrete logarithmic scaling of the MSB distance. -It is defined as the reverse rank of the integer part of the base 2 -logarithm of the distance. -It is calculated by counting the number of common leading zeros in the (MSB) -binary representation of the x^y. - -(0 farthest, 255 closest, 256 self) -*/ -func proximity(one, other Address) (ret int) { - for i := 0; i < len(one); i++ { - oxo := one[i] ^ other[i] - for j := 0; j < 8; j++ { - if (oxo>>uint8(7-j))&0x01 != 0 { - return i*8 + j - } - } - } - return len(one) * 8 -} - -// Address.ProxCmp compares the distances a->target and b->target. -// Returns -1 if a is closer to target, 1 if b is closer to target -// and 0 if they are equal. -func (target Address) ProxCmp(a, b Address) int { - for i := range target { - da := a[i] ^ target[i] - db := b[i] ^ target[i] - if da > db { - return 1 - } else if da < db { - return -1 - } - } - return 0 -} - -// randomAddressAt(address, prox) generates a random address -// at proximity order prox relative to address -// if prox is negative a random address is generated -func RandomAddressAt(self Address, prox int) (addr Address) { - addr = self - var pos int - if prox >= 0 { - pos = prox / 8 - trans := prox % 8 - transbytea := byte(0) - for j := 0; j <= trans; j++ { - transbytea |= 1 << uint8(7-j) - } - flipbyte := byte(1 << uint8(7-trans)) - transbyteb := transbytea ^ byte(255) - randbyte := byte(rand.Intn(255)) - addr[pos] = ((addr[pos] & transbytea) ^ flipbyte) | randbyte&transbyteb - } - for i := pos + 1; i < len(addr); i++ { - addr[i] = byte(rand.Intn(255)) - } - - return -} - -// KeyRange(a0, a1, proxLimit) returns the address inclusive address -// range that contain addresses closer to one than other -func KeyRange(one, other Address, proxLimit int) (start, stop Address) { - prox := proximity(one, other) - if prox >= proxLimit { - prox = proxLimit - } - start = CommonBitsAddrByte(one, other, byte(0x00), prox) - stop = CommonBitsAddrByte(one, other, byte(0xff), prox) - return -} - -func CommonBitsAddrF(self, other Address, f func() byte, p int) (addr Address) { - prox := proximity(self, other) - var pos int - if p <= prox { - prox = p - } - pos = prox / 8 - addr = self - trans := byte(prox % 8) - var transbytea byte - if p > prox { - transbytea = byte(0x7f) - } else { - transbytea = byte(0xff) - } - transbytea >>= trans - transbyteb := transbytea ^ byte(0xff) - addrpos := addr[pos] - addrpos &= transbyteb - if p > prox { - addrpos ^= byte(0x80 >> trans) - } - addrpos |= transbytea & f() - addr[pos] = addrpos - for i := pos + 1; i < len(addr); i++ { - addr[i] = f() - } - - return -} - -func CommonBitsAddr(self, other Address, prox int) (addr Address) { - return CommonBitsAddrF(self, other, func() byte { return byte(rand.Intn(255)) }, prox) -} - -func CommonBitsAddrByte(self, other Address, b byte, prox int) (addr Address) { - return CommonBitsAddrF(self, other, func() byte { return b }, prox) -} - -// randomAddressAt() generates a random address -func RandomAddress() Address { - return RandomAddressAt(Address{}, -1) -} diff --git a/swarm/network/kademlia/address_test.go b/swarm/network/kademlia/address_test.go deleted file mode 100644 index c062c8eafb..0000000000 --- a/swarm/network/kademlia/address_test.go +++ /dev/null @@ -1,96 +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 kademlia - -import ( - "math/rand" - "reflect" - "testing" - - "github.com/ethereum/go-ethereum/common" -) - -func (Address) Generate(rand *rand.Rand, size int) reflect.Value { - var id Address - for i := 0; i < len(id); i++ { - id[i] = byte(uint8(rand.Intn(255))) - } - return reflect.ValueOf(id) -} - -func TestCommonBitsAddrF(t *testing.T) { - a := Address(common.HexToHash("0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef")) - b := Address(common.HexToHash("0x8123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef")) - c := Address(common.HexToHash("0x4123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef")) - d := Address(common.HexToHash("0x0023456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef")) - e := Address(common.HexToHash("0x01A3456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef")) - ab := CommonBitsAddrF(a, b, func() byte { return byte(0x00) }, 10) - expab := Address(common.HexToHash("0x8000000000000000000000000000000000000000000000000000000000000000")) - - if ab != expab { - t.Fatalf("%v != %v", ab, expab) - } - ac := CommonBitsAddrF(a, c, func() byte { return byte(0x00) }, 10) - expac := Address(common.HexToHash("0x4000000000000000000000000000000000000000000000000000000000000000")) - - if ac != expac { - t.Fatalf("%v != %v", ac, expac) - } - ad := CommonBitsAddrF(a, d, func() byte { return byte(0x00) }, 10) - expad := Address(common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000")) - - if ad != expad { - t.Fatalf("%v != %v", ad, expad) - } - ae := CommonBitsAddrF(a, e, func() byte { return byte(0x00) }, 10) - expae := Address(common.HexToHash("0x0180000000000000000000000000000000000000000000000000000000000000")) - - if ae != expae { - t.Fatalf("%v != %v", ae, expae) - } - acf := CommonBitsAddrF(a, c, func() byte { return byte(0xff) }, 10) - expacf := Address(common.HexToHash("0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")) - - if acf != expacf { - t.Fatalf("%v != %v", acf, expacf) - } - aeo := CommonBitsAddrF(a, e, func() byte { return byte(0x00) }, 2) - expaeo := Address(common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000")) - - if aeo != expaeo { - t.Fatalf("%v != %v", aeo, expaeo) - } - aep := CommonBitsAddrF(a, e, func() byte { return byte(0xff) }, 2) - expaep := Address(common.HexToHash("0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")) - - if aep != expaep { - t.Fatalf("%v != %v", aep, expaep) - } - -} - -func TestRandomAddressAt(t *testing.T) { - var a Address - for i := 0; i < 100; i++ { - a = RandomAddress() - prox := rand.Intn(255) - b := RandomAddressAt(a, prox) - if proximity(a, b) != prox { - t.Fatalf("incorrect address prox(%v, %v) == %v (expected %v)", a, b, proximity(a, b), prox) - } - } -} diff --git a/swarm/network/kademlia/kaddb.go b/swarm/network/kademlia/kaddb.go deleted file mode 100644 index b37ced5ba0..0000000000 --- a/swarm/network/kademlia/kaddb.go +++ /dev/null @@ -1,350 +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 kademlia - -import ( - "encoding/json" - "fmt" - "io/ioutil" - "os" - "sync" - "time" - - "github.com/ethereum/go-ethereum/log" -) - -type NodeData interface { - json.Marshaler - json.Unmarshaler -} - -// allow inactive peers under -type NodeRecord struct { - Addr Address // address of node - Url string // Url, used to connect to node - After time.Time // next call after time - Seen time.Time // last connected at time - Meta *json.RawMessage // arbitrary metadata saved for a peer - - node Node -} - -func (self *NodeRecord) setSeen() { - t := time.Now() - self.Seen = t - self.After = t -} - -func (self *NodeRecord) String() string { - return fmt.Sprintf("<%v>", self.Addr) -} - -// persisted node record database () -type KadDb struct { - Address Address - Nodes [][]*NodeRecord - index map[Address]*NodeRecord - cursors []int - lock sync.RWMutex - purgeInterval time.Duration - initialRetryInterval time.Duration - connRetryExp int -} - -func newKadDb(addr Address, params *KadParams) *KadDb { - return &KadDb{ - Address: addr, - Nodes: make([][]*NodeRecord, params.MaxProx+1), // overwritten by load - cursors: make([]int, params.MaxProx+1), - index: make(map[Address]*NodeRecord), - purgeInterval: params.PurgeInterval, - initialRetryInterval: params.InitialRetryInterval, - connRetryExp: params.ConnRetryExp, - } -} - -func (self *KadDb) findOrCreate(index int, a Address, url string) *NodeRecord { - defer self.lock.Unlock() - self.lock.Lock() - - record, found := self.index[a] - if !found { - record = &NodeRecord{ - Addr: a, - Url: url, - } - log.Info(fmt.Sprintf("add new record %v to kaddb", record)) - // insert in kaddb - self.index[a] = record - self.Nodes[index] = append(self.Nodes[index], record) - } else { - log.Info(fmt.Sprintf("found record %v in kaddb", record)) - } - // update last seen time - record.setSeen() - // update with url in case IP/port changes - record.Url = url - return record -} - -// add adds node records to kaddb (persisted node record db) -func (self *KadDb) add(nrs []*NodeRecord, proximityBin func(Address) int) { - defer self.lock.Unlock() - self.lock.Lock() - var n int - var nodes []*NodeRecord - for _, node := range nrs { - _, found := self.index[node.Addr] - if !found && node.Addr != self.Address { - node.setSeen() - self.index[node.Addr] = node - index := proximityBin(node.Addr) - dbcursor := self.cursors[index] - nodes = self.Nodes[index] - // this is inefficient for allocation, need to just append then shift - newnodes := make([]*NodeRecord, len(nodes)+1) - copy(newnodes[:], nodes[:dbcursor]) - newnodes[dbcursor] = node - copy(newnodes[dbcursor+1:], nodes[dbcursor:]) - log.Trace(fmt.Sprintf("new nodes: %v, nodes: %v", newnodes, nodes)) - self.Nodes[index] = newnodes - n++ - } - } - if n > 0 { - log.Debug(fmt.Sprintf("%d/%d node records (new/known)", n, len(nrs))) - } -} - -/* -next return one node record with the highest priority for desired -connection. -This is used to pick candidates for live nodes that are most wanted for -a higly connected low centrality network structure for Swarm which best suits -for a Kademlia-style routing. - -* Starting as naive node with empty db, this implements Kademlia bootstrapping -* As a mature node, it fills short lines. All on demand. - -The candidate is chosen using the following strategy: -We check for missing online nodes in the buckets for 1 upto Max BucketSize rounds. -On each round we proceed from the low to high proximity order buckets. -If the number of active nodes (=connected peers) is < rounds, then start looking -for a known candidate. To determine if there is a candidate to recommend the -kaddb node record database row corresponding to the bucket is checked. - -If the row cursor is on position i, the ith element in the row is chosen. -If the record is scheduled not to be retried before NOW, the next element is taken. -If the record is scheduled to be retried, it is set as checked, scheduled for -checking and is returned. The time of the next check is in X (duration) such that -X = ConnRetryExp * delta where delta is the time past since the last check and -ConnRetryExp is constant obsoletion factor. (Note that when node records are added -from peer messages, they are marked as checked and placed at the cursor, ie. -given priority over older entries). Entries which were checked more than -purgeInterval ago are deleted from the kaddb row. If no candidate is found after -a full round of checking the next bucket up is considered. If no candidate is -found when we reach the maximum-proximity bucket, the next round starts. - -node record a is more favoured to b a > b iff a is a passive node (record of -offline past peer) -|proxBin(a)| < |proxBin(b)| -|| (proxBin(a) < proxBin(b) && |proxBin(a)| == |proxBin(b)|) -|| (proxBin(a) == proxBin(b) && lastChecked(a) < lastChecked(b)) - - -The second argument returned names the first missing slot found -*/ -func (self *KadDb) findBest(maxBinSize int, binSize func(int) int) (node *NodeRecord, need bool, proxLimit int) { - // return nil, proxLimit indicates that all buckets are filled - defer self.lock.Unlock() - self.lock.Lock() - - var interval time.Duration - var found bool - var purge []bool - var delta time.Duration - var cursor int - var count int - var after time.Time - - // iterate over columns maximum bucketsize times - for rounds := 1; rounds <= maxBinSize; rounds++ { - ROUND: - // iterate over rows from PO 0 upto MaxProx - for po, dbrow := range self.Nodes { - // if row has rounds connected peers, then take the next - if binSize(po) >= rounds { - continue ROUND - } - if !need { - // set proxlimit to the PO where the first missing slot is found - proxLimit = po - need = true - } - purge = make([]bool, len(dbrow)) - - // there is a missing slot - finding a node to connect to - // select a node record from the relavant kaddb row (of identical prox order) - ROW: - for cursor = self.cursors[po]; !found && count < len(dbrow); cursor = (cursor + 1) % len(dbrow) { - count++ - node = dbrow[cursor] - - // skip already connected nodes - if node.node != nil { - log.Debug(fmt.Sprintf("kaddb record %v (PO%03d:%d/%d) already connected", node.Addr, po, cursor, len(dbrow))) - continue ROW - } - - // if node is scheduled to connect - if node.After.After(time.Now()) { - log.Debug(fmt.Sprintf("kaddb record %v (PO%03d:%d) skipped. seen at %v (%v ago), scheduled at %v", node.Addr, po, cursor, node.Seen, delta, node.After)) - continue ROW - } - - delta = time.Since(node.Seen) - if delta < self.initialRetryInterval { - delta = self.initialRetryInterval - } - if delta > self.purgeInterval { - // remove node - purge[cursor] = true - log.Debug(fmt.Sprintf("kaddb record %v (PO%03d:%d) unreachable since %v. Removed", node.Addr, po, cursor, node.Seen)) - continue ROW - } - - log.Debug(fmt.Sprintf("kaddb record %v (PO%03d:%d) ready to be tried. seen at %v (%v ago), scheduled at %v", node.Addr, po, cursor, node.Seen, delta, node.After)) - - // scheduling next check - interval = delta * time.Duration(self.connRetryExp) - after = time.Now().Add(interval) - - log.Debug(fmt.Sprintf("kaddb record %v (PO%03d:%d) selected as candidate connection %v. seen at %v (%v ago), selectable since %v, retry after %v (in %v)", node.Addr, po, cursor, rounds, node.Seen, delta, node.After, after, interval)) - node.After = after - found = true - } // ROW - self.cursors[po] = cursor - self.delete(po, purge) - if found { - return node, need, proxLimit - } - } // ROUND - } // ROUNDS - - return nil, need, proxLimit -} - -// deletes the noderecords of a kaddb row corresponding to the indexes -// caller must hold the dblock -// the call is unsafe, no index checks -func (self *KadDb) delete(row int, purge []bool) { - var nodes []*NodeRecord - dbrow := self.Nodes[row] - for i, del := range purge { - if i == self.cursors[row] { - //reset cursor - self.cursors[row] = len(nodes) - } - // delete the entry to be purged - if del { - delete(self.index, dbrow[i].Addr) - continue - } - // otherwise append to new list - nodes = append(nodes, dbrow[i]) - } - self.Nodes[row] = nodes -} - -// save persists kaddb on disk (written to file on path in json format. -func (self *KadDb) save(path string, cb func(*NodeRecord, Node)) error { - defer self.lock.Unlock() - self.lock.Lock() - - var n int - - for _, b := range self.Nodes { - for _, node := range b { - n++ - node.After = time.Now() - node.Seen = time.Now() - if cb != nil { - cb(node, node.node) - } - } - } - - data, err := json.MarshalIndent(self, "", " ") - if err != nil { - return err - } - err = ioutil.WriteFile(path, data, os.ModePerm) - if err != nil { - log.Warn(fmt.Sprintf("unable to save kaddb with %v nodes to %v: %v", n, path, err)) - } else { - log.Info(fmt.Sprintf("saved kaddb with %v nodes to %v", n, path)) - } - return err -} - -// Load(path) loads the node record database (kaddb) from file on path. -func (self *KadDb) load(path string, cb func(*NodeRecord, Node) error) (err error) { - defer self.lock.Unlock() - self.lock.Lock() - - var data []byte - data, err = ioutil.ReadFile(path) - if err != nil { - return - } - - err = json.Unmarshal(data, self) - if err != nil { - return - } - var n int - var purge []bool - for po, b := range self.Nodes { - purge = make([]bool, len(b)) - ROW: - for i, node := range b { - if cb != nil { - err = cb(node, node.node) - if err != nil { - purge[i] = true - continue ROW - } - } - n++ - if node.After.IsZero() { - node.After = time.Now() - } - self.index[node.Addr] = node - } - self.delete(po, purge) - } - log.Info(fmt.Sprintf("loaded kaddb with %v nodes from %v", n, path)) - - return -} - -// accessor for KAD offline db count -func (self *KadDb) count() int { - defer self.lock.Unlock() - self.lock.Lock() - return len(self.index) -} diff --git a/swarm/network/kademlia/kademlia.go b/swarm/network/kademlia/kademlia.go deleted file mode 100644 index b5999b52d4..0000000000 --- a/swarm/network/kademlia/kademlia.go +++ /dev/null @@ -1,454 +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 kademlia - -import ( - "fmt" - "sort" - "strings" - "sync" - "time" - - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/metrics" -) - -//metrics variables -//For metrics, we want to count how many times peers are added/removed -//at a certain index. Thus we do that with an array of counters with -//entry for each index -var ( - bucketAddIndexCount []metrics.Counter - bucketRmIndexCount []metrics.Counter -) - -const ( - bucketSize = 4 - proxBinSize = 2 - maxProx = 8 - connRetryExp = 2 - maxPeers = 100 -) - -var ( - purgeInterval = 42 * time.Hour - initialRetryInterval = 42 * time.Millisecond - maxIdleInterval = 42 * 1000 * time.Millisecond - // maxIdleInterval = 42 * 10 0 * time.Millisecond -) - -type KadParams struct { - // adjustable parameters - MaxProx int - ProxBinSize int - BucketSize int - PurgeInterval time.Duration - InitialRetryInterval time.Duration - MaxIdleInterval time.Duration - ConnRetryExp int -} - -func NewDefaultKadParams() *KadParams { - return &KadParams{ - MaxProx: maxProx, - ProxBinSize: proxBinSize, - BucketSize: bucketSize, - PurgeInterval: purgeInterval, - InitialRetryInterval: initialRetryInterval, - MaxIdleInterval: maxIdleInterval, - ConnRetryExp: connRetryExp, - } -} - -// Kademlia is a table of active nodes -type Kademlia struct { - addr Address // immutable baseaddress of the table - *KadParams // Kademlia configuration parameters - proxLimit int // state, the PO of the first row of the most proximate bin - proxSize int // state, the number of peers in the most proximate bin - count int // number of active peers (w live connection) - buckets [][]Node // the actual bins - db *KadDb // kaddb, node record database - lock sync.RWMutex // mutex to access buckets -} - -type Node interface { - Addr() Address - Url() string - LastActive() time.Time - Drop() -} - -// public constructor -// add is the base address of the table -// params is KadParams configuration -func New(addr Address, params *KadParams) *Kademlia { - buckets := make([][]Node, params.MaxProx+1) - kad := &Kademlia{ - addr: addr, - KadParams: params, - buckets: buckets, - db: newKadDb(addr, params), - } - kad.initMetricsVariables() - return kad -} - -// accessor for KAD base address -func (self *Kademlia) Addr() Address { - return self.addr -} - -// accessor for KAD active node count -func (self *Kademlia) Count() int { - defer self.lock.Unlock() - self.lock.Lock() - return self.count -} - -// accessor for KAD active node count -func (self *Kademlia) DBCount() int { - return self.db.count() -} - -// On is the entry point called when a new nodes is added -// unsafe in that node is not checked to be already active node (to be called once) -func (self *Kademlia) On(node Node, cb func(*NodeRecord, Node) error) (err error) { - log.Debug(fmt.Sprintf("%v", self)) - defer self.lock.Unlock() - self.lock.Lock() - - index := self.proximityBin(node.Addr()) - record := self.db.findOrCreate(index, node.Addr(), node.Url()) - - if cb != nil { - err = cb(record, node) - log.Trace(fmt.Sprintf("cb(%v, %v) ->%v", record, node, err)) - if err != nil { - return fmt.Errorf("unable to add node %v, callback error: %v", node.Addr(), err) - } - log.Debug(fmt.Sprintf("add node record %v with node %v", record, node)) - } - - // insert in kademlia table of active nodes - bucket := self.buckets[index] - // if bucket is full insertion replaces the worst node - // TODO: give priority to peers with active traffic - if len(bucket) < self.BucketSize { // >= allows us to add peers beyond the bucketsize limitation - self.buckets[index] = append(bucket, node) - bucketAddIndexCount[index].Inc(1) - log.Debug(fmt.Sprintf("add node %v to table", node)) - self.setProxLimit(index, true) - record.node = node - self.count++ - return nil - } - - // always rotate peers - idle := self.MaxIdleInterval - var pos int - var replaced Node - for i, p := range bucket { - idleInt := time.Since(p.LastActive()) - if idleInt > idle { - idle = idleInt - pos = i - replaced = p - } - } - if replaced == nil { - log.Debug(fmt.Sprintf("all peers wanted, PO%03d bucket full", index)) - return fmt.Errorf("bucket full") - } - log.Debug(fmt.Sprintf("node %v replaced by %v (idle for %v > %v)", replaced, node, idle, self.MaxIdleInterval)) - replaced.Drop() - // actually replace in the row. When off(node) is called, the peer is no longer in the row - bucket[pos] = node - // there is no change in bucket cardinalities so no prox limit adjustment is needed - record.node = node - self.count++ - return nil - -} - -// Off is the called when a node is taken offline (from the protocol main loop exit) -func (self *Kademlia) Off(node Node, cb func(*NodeRecord, Node)) (err error) { - self.lock.Lock() - defer self.lock.Unlock() - - index := self.proximityBin(node.Addr()) - bucketRmIndexCount[index].Inc(1) - bucket := self.buckets[index] - for i := 0; i < len(bucket); i++ { - if node.Addr() == bucket[i].Addr() { - self.buckets[index] = append(bucket[:i], bucket[(i+1):]...) - self.setProxLimit(index, false) - break - } - } - - record := self.db.index[node.Addr()] - // callback on remove - if cb != nil { - cb(record, record.node) - } - record.node = nil - self.count-- - log.Debug(fmt.Sprintf("remove node %v from table, population now is %v", node, self.count)) - - return -} - -// proxLimit is dynamically adjusted so that -// 1) there is no empty buckets in bin < proxLimit and -// 2) the sum of all items are the minimum possible but higher than ProxBinSize -// adjust Prox (proxLimit and proxSize after an insertion/removal of nodes) -// caller holds the lock -func (self *Kademlia) setProxLimit(r int, on bool) { - // if the change is outside the core (PO lower) - // and the change does not leave a bucket empty then - // no adjustment needed - if r < self.proxLimit && len(self.buckets[r]) > 0 { - return - } - // if on=a node was added, then r must be within prox limit so increment cardinality - if on { - self.proxSize++ - curr := len(self.buckets[self.proxLimit]) - // if now core is big enough without the furthest bucket, then contract - // this can result in more than one bucket change - for self.proxSize >= self.ProxBinSize+curr && curr > 0 { - self.proxSize -= curr - self.proxLimit++ - curr = len(self.buckets[self.proxLimit]) - - log.Trace(fmt.Sprintf("proxbin contraction (size: %v, limit: %v, bin: %v)", self.proxSize, self.proxLimit, r)) - } - return - } - // otherwise - if r >= self.proxLimit { - self.proxSize-- - } - // expand core by lowering prox limit until hit zero or cover the empty bucket or reached target cardinality - for (self.proxSize < self.ProxBinSize || r < self.proxLimit) && - self.proxLimit > 0 { - // - self.proxLimit-- - self.proxSize += len(self.buckets[self.proxLimit]) - log.Trace(fmt.Sprintf("proxbin expansion (size: %v, limit: %v, bin: %v)", self.proxSize, self.proxLimit, r)) - } -} - -/* -returns the list of nodes belonging to the same proximity bin -as the target. The most proximate bin will be the union of the bins between -proxLimit and MaxProx. -*/ -func (self *Kademlia) FindClosest(target Address, max int) []Node { - self.lock.Lock() - defer self.lock.Unlock() - - r := nodesByDistance{ - target: target, - } - - po := self.proximityBin(target) - index := po - step := 1 - log.Trace(fmt.Sprintf("serving %v nodes at %v (PO%02d)", max, index, po)) - - // if max is set to 0, just want a full bucket, dynamic number - min := max - // set limit to max - limit := max - if max == 0 { - min = 1 - limit = maxPeers - } - - var n int - for index >= 0 { - // add entire bucket - for _, p := range self.buckets[index] { - r.push(p, limit) - n++ - } - // terminate if index reached the bottom or enough peers > min - log.Trace(fmt.Sprintf("add %v -> %v (PO%02d, PO%03d)", len(self.buckets[index]), n, index, po)) - if n >= min && (step < 0 || max == 0) { - break - } - // reach top most non-empty PO bucket, turn around - if index == self.MaxProx { - index = po - step = -1 - } - index += step - } - log.Trace(fmt.Sprintf("serve %d (<=%d) nodes for target lookup %v (PO%03d)", n, max, target, po)) - return r.nodes -} - -func (self *Kademlia) Suggest() (*NodeRecord, bool, int) { - defer self.lock.RUnlock() - self.lock.RLock() - return self.db.findBest(self.BucketSize, func(i int) int { return len(self.buckets[i]) }) -} - -// adds node records to kaddb (persisted node record db) -func (self *Kademlia) Add(nrs []*NodeRecord) { - self.db.add(nrs, self.proximityBin) -} - -// nodesByDistance is a list of nodes, ordered by distance to target. -type nodesByDistance struct { - nodes []Node - target Address -} - -func sortedByDistanceTo(target Address, slice []Node) bool { - var last Address - for i, node := range slice { - if i > 0 { - if target.ProxCmp(node.Addr(), last) < 0 { - return false - } - } - last = node.Addr() - } - return true -} - -// push(node, max) adds the given node to the list, keeping the total size -// below max elements. -func (h *nodesByDistance) push(node Node, max int) { - // returns the firt index ix such that func(i) returns true - ix := sort.Search(len(h.nodes), func(i int) bool { - return h.target.ProxCmp(h.nodes[i].Addr(), node.Addr()) >= 0 - }) - - if len(h.nodes) < max { - h.nodes = append(h.nodes, node) - } - if ix < len(h.nodes) { - copy(h.nodes[ix+1:], h.nodes[ix:]) - h.nodes[ix] = node - } -} - -/* -Taking the proximity order relative to a fix point x classifies the points in -the space (n byte long byte sequences) into bins. Items in each are at -most half as distant from x as items in the previous bin. Given a sample of -uniformly distributed items (a hash function over arbitrary sequence) the -proximity scale maps onto series of subsets with cardinalities on a negative -exponential scale. - -It also has the property that any two item belonging to the same bin are at -most half as distant from each other as they are from x. - -If we think of random sample of items in the bins as connections in a network of interconnected nodes than relative proximity can serve as the basis for local -decisions for graph traversal where the task is to find a route between two -points. Since in every hop, the finite distance halves, there is -a guaranteed constant maximum limit on the number of hops needed to reach one -node from the other. -*/ - -func (self *Kademlia) proximityBin(other Address) (ret int) { - ret = proximity(self.addr, other) - if ret > self.MaxProx { - ret = self.MaxProx - } - return -} - -// provides keyrange for chunk db iteration -func (self *Kademlia) KeyRange(other Address) (start, stop Address) { - defer self.lock.RUnlock() - self.lock.RLock() - return KeyRange(self.addr, other, self.proxLimit) -} - -// save persists kaddb on disk (written to file on path in json format. -func (self *Kademlia) Save(path string, cb func(*NodeRecord, Node)) error { - return self.db.save(path, cb) -} - -// Load(path) loads the node record database (kaddb) from file on path. -func (self *Kademlia) Load(path string, cb func(*NodeRecord, Node) error) (err error) { - return self.db.load(path, cb) -} - -// kademlia table + kaddb table displayed with ascii -func (self *Kademlia) String() string { - defer self.lock.RUnlock() - self.lock.RLock() - defer self.db.lock.RUnlock() - self.db.lock.RLock() - - var rows []string - rows = append(rows, "=========================================================================") - rows = append(rows, fmt.Sprintf("%v KΛÐΞMLIΛ hive: queen's address: %v", time.Now().UTC().Format(time.UnixDate), self.addr.String()[:6])) - rows = append(rows, fmt.Sprintf("population: %d (%d), proxLimit: %d, proxSize: %d", self.count, len(self.db.index), self.proxLimit, self.proxSize)) - rows = append(rows, fmt.Sprintf("MaxProx: %d, ProxBinSize: %d, BucketSize: %d", self.MaxProx, self.ProxBinSize, self.BucketSize)) - - for i, bucket := range self.buckets { - - if i == self.proxLimit { - rows = append(rows, fmt.Sprintf("============ PROX LIMIT: %d ==========================================", i)) - } - row := []string{fmt.Sprintf("%03d", i), fmt.Sprintf("%2d", len(bucket))} - var k int - c := self.db.cursors[i] - for ; k < len(bucket); k++ { - p := bucket[(c+k)%len(bucket)] - row = append(row, p.Addr().String()[:6]) - if k == 4 { - break - } - } - for ; k < 4; k++ { - row = append(row, " ") - } - row = append(row, fmt.Sprintf("| %2d %2d", len(self.db.Nodes[i]), self.db.cursors[i])) - - for j, p := range self.db.Nodes[i] { - row = append(row, p.Addr.String()[:6]) - if j == 3 { - break - } - } - rows = append(rows, strings.Join(row, " ")) - if i == self.MaxProx { - } - } - rows = append(rows, "=========================================================================") - return strings.Join(rows, "\n") -} - -//We have to build up the array of counters for each index -func (self *Kademlia) initMetricsVariables() { - //create the arrays - bucketAddIndexCount = make([]metrics.Counter, self.MaxProx+1) - bucketRmIndexCount = make([]metrics.Counter, self.MaxProx+1) - //at each index create a metrics counter - for i := 0; i < (self.KadParams.MaxProx + 1); i++ { - bucketAddIndexCount[i] = metrics.NewRegisteredCounter(fmt.Sprintf("network.kademlia.bucket.add.%d.index", i), nil) - bucketRmIndexCount[i] = metrics.NewRegisteredCounter(fmt.Sprintf("network.kademlia.bucket.rm.%d.index", i), nil) - } -} diff --git a/swarm/network/kademlia/kademlia_test.go b/swarm/network/kademlia/kademlia_test.go deleted file mode 100644 index 88858908a4..0000000000 --- a/swarm/network/kademlia/kademlia_test.go +++ /dev/null @@ -1,392 +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 kademlia - -import ( - "fmt" - "math" - "math/rand" - "os" - "path/filepath" - "reflect" - "testing" - "testing/quick" - "time" -) - -var ( - quickrand = rand.New(rand.NewSource(time.Now().Unix())) - quickcfgFindClosest = &quick.Config{MaxCount: 50, Rand: quickrand} - quickcfgBootStrap = &quick.Config{MaxCount: 100, Rand: quickrand} -) - -type testNode struct { - addr Address -} - -func (n *testNode) String() string { - return fmt.Sprintf("%x", n.addr[:]) -} - -func (n *testNode) Addr() Address { - return n.addr -} - -func (n *testNode) Drop() { -} - -func (n *testNode) Url() string { - return "" -} - -func (n *testNode) LastActive() time.Time { - return time.Now() -} - -func TestOn(t *testing.T) { - addr, ok1 := gen(Address{}, quickrand).(Address) - other, ok2 := gen(Address{}, quickrand).(Address) - if !ok1 || !ok2 { - t.Errorf("oops") - } - kad := New(addr, NewDefaultKadParams()) - err := kad.On(&testNode{addr: other}, nil) - _ = err -} - -func TestBootstrap(t *testing.T) { - - test := func(test *bootstrapTest) bool { - // for any node kad.le, Target and N - params := NewDefaultKadParams() - params.MaxProx = test.MaxProx - params.BucketSize = test.BucketSize - params.ProxBinSize = test.BucketSize - kad := New(test.Self, params) - var err error - - for p := 0; p < 9; p++ { - var nrs []*NodeRecord - n := math.Pow(float64(2), float64(7-p)) - for i := 0; i < int(n); i++ { - addr := RandomAddressAt(test.Self, p) - nrs = append(nrs, &NodeRecord{ - Addr: addr, - }) - } - kad.Add(nrs) - } - - node := &testNode{test.Self} - - n := 0 - for n < 100 { - err = kad.On(node, nil) - if err != nil { - t.Fatalf("backend not accepting node: %v", err) - } - - record, need, _ := kad.Suggest() - if !need { - break - } - n++ - if record == nil { - continue - } - node = &testNode{record.Addr} - } - exp := test.BucketSize * (test.MaxProx + 1) - if kad.Count() != exp { - t.Errorf("incorrect number of peers, expected %d, got %d\n%v", exp, kad.Count(), kad) - return false - } - return true - } - if err := quick.Check(test, quickcfgBootStrap); err != nil { - t.Error(err) - } - -} - -func TestFindClosest(t *testing.T) { - - test := func(test *FindClosestTest) bool { - // for any node kad.le, Target and N - params := NewDefaultKadParams() - params.MaxProx = 7 - kad := New(test.Self, params) - var err error - for _, node := range test.All { - err = kad.On(node, nil) - if err != nil && err.Error() != "bucket full" { - t.Fatalf("backend not accepting node: %v", err) - } - } - - if len(test.All) == 0 || test.N == 0 { - return true - } - nodes := kad.FindClosest(test.Target, test.N) - - // check that the number of results is min(N, kad.len) - wantN := test.N - if tlen := kad.Count(); tlen < test.N { - wantN = tlen - } - - if len(nodes) != wantN { - t.Errorf("wrong number of nodes: got %d, want %d", len(nodes), wantN) - return false - } - - if hasDuplicates(nodes) { - t.Errorf("result contains duplicates") - return false - } - - if !sortedByDistanceTo(test.Target, nodes) { - t.Errorf("result is not sorted by distance to target") - return false - } - - // check that the result nodes have minimum distance to target. - farthestResult := nodes[len(nodes)-1].Addr() - for i, b := range kad.buckets { - for j, n := range b { - if contains(nodes, n.Addr()) { - continue // don't run the check below for nodes in result - } - if test.Target.ProxCmp(n.Addr(), farthestResult) < 0 { - _ = i * j - t.Errorf("kad.le contains node that is closer to target but it's not in result") - return false - } - } - } - return true - } - if err := quick.Check(test, quickcfgFindClosest); err != nil { - t.Error(err) - } -} - -type proxTest struct { - add bool - index int - addr Address -} - -var ( - addresses []Address -) - -func TestProxAdjust(t *testing.T) { - r := rand.New(rand.NewSource(time.Now().UnixNano())) - self := gen(Address{}, r).(Address) - params := NewDefaultKadParams() - params.MaxProx = 7 - kad := New(self, params) - - var err error - for i := 0; i < 100; i++ { - a := gen(Address{}, r).(Address) - addresses = append(addresses, a) - err = kad.On(&testNode{addr: a}, nil) - if err != nil && err.Error() != "bucket full" { - t.Fatalf("backend not accepting node: %v", err) - } - if !kad.proxCheck(t) { - return - } - } - test := func(test *proxTest) bool { - node := &testNode{test.addr} - if test.add { - kad.On(node, nil) - } else { - kad.Off(node, nil) - } - return kad.proxCheck(t) - } - if err := quick.Check(test, quickcfgFindClosest); err != nil { - t.Error(err) - } -} - -func TestSaveLoad(t *testing.T) { - r := rand.New(rand.NewSource(time.Now().UnixNano())) - addresses := gen([]Address{}, r).([]Address) - self := RandomAddress() - params := NewDefaultKadParams() - params.MaxProx = 7 - kad := New(self, params) - - var err error - - for _, a := range addresses { - err = kad.On(&testNode{addr: a}, nil) - if err != nil && err.Error() != "bucket full" { - t.Fatalf("backend not accepting node: %v", err) - } - } - nodes := kad.FindClosest(self, 100) - - path := filepath.Join(os.TempDir(), "bzz-kad-test-save-load.peers") - err = kad.Save(path, nil) - if err != nil && err.Error() != "bucket full" { - t.Fatalf("unepected error saving kaddb: %v", err) - } - kad = New(self, params) - err = kad.Load(path, nil) - if err != nil && err.Error() != "bucket full" { - t.Fatalf("unepected error loading kaddb: %v", err) - } - for _, b := range kad.db.Nodes { - for _, node := range b { - err = kad.On(&testNode{node.Addr}, nil) - if err != nil && err.Error() != "bucket full" { - t.Fatalf("backend not accepting node: %v", err) - } - } - } - loadednodes := kad.FindClosest(self, 100) - for i, node := range loadednodes { - if nodes[i].Addr() != node.Addr() { - t.Errorf("node mismatch at %d/%d: %v != %v", i, len(nodes), nodes[i].Addr(), node.Addr()) - } - } -} - -func (self *Kademlia) proxCheck(t *testing.T) bool { - var sum int - for i, b := range self.buckets { - l := len(b) - // if we are in the high prox multibucket - if i >= self.proxLimit { - sum += l - } else if l == 0 { - t.Errorf("bucket %d empty, yet proxLimit is %d\n%v", len(b), self.proxLimit, self) - return false - } - } - // check if merged high prox bucket does not exceed size - if sum > 0 { - if sum != self.proxSize { - t.Errorf("proxSize incorrect, expected %v, got %v", sum, self.proxSize) - return false - } - last := len(self.buckets[self.proxLimit]) - if last > 0 && sum >= self.ProxBinSize+last { - t.Errorf("proxLimit %v incorrect, redundant non-empty bucket %d added to proxBin with %v (target %v)\n%v", self.proxLimit, last, sum-last, self.ProxBinSize, self) - return false - } - if self.proxLimit > 0 && sum < self.ProxBinSize { - t.Errorf("proxLimit %v incorrect. proxSize %v is less than target %v, yet there is more peers", self.proxLimit, sum, self.ProxBinSize) - return false - } - } - return true -} - -type bootstrapTest struct { - MaxProx int - BucketSize int - Self Address -} - -func (*bootstrapTest) Generate(rand *rand.Rand, size int) reflect.Value { - t := &bootstrapTest{ - Self: gen(Address{}, rand).(Address), - MaxProx: 5 + rand.Intn(2), - BucketSize: rand.Intn(3) + 1, - } - return reflect.ValueOf(t) -} - -type FindClosestTest struct { - Self Address - Target Address - All []Node - N int -} - -func (c FindClosestTest) String() string { - return fmt.Sprintf("A: %064x\nT: %064x\n(%d)\n", c.Self[:], c.Target[:], c.N) -} - -func (*FindClosestTest) Generate(rand *rand.Rand, size int) reflect.Value { - t := &FindClosestTest{ - Self: gen(Address{}, rand).(Address), - Target: gen(Address{}, rand).(Address), - N: rand.Intn(bucketSize), - } - for _, a := range gen([]Address{}, rand).([]Address) { - t.All = append(t.All, &testNode{addr: a}) - } - return reflect.ValueOf(t) -} - -func (*proxTest) Generate(rand *rand.Rand, size int) reflect.Value { - var add bool - if rand.Intn(1) == 0 { - add = true - } - var t *proxTest - if add { - t = &proxTest{ - addr: gen(Address{}, rand).(Address), - add: add, - } - } else { - t = &proxTest{ - index: rand.Intn(len(addresses)), - add: add, - } - } - return reflect.ValueOf(t) -} - -func hasDuplicates(slice []Node) bool { - seen := make(map[Address]bool) - for _, node := range slice { - if seen[node.Addr()] { - return true - } - seen[node.Addr()] = true - } - return false -} - -func contains(nodes []Node, addr Address) bool { - for _, n := range nodes { - if n.Addr() == addr { - return true - } - } - return false -} - -// gen wraps quick.Value so it's easier to use. -// it generates a random value of the given value's type. -func gen(typ interface{}, rand *rand.Rand) interface{} { - v, ok := quick.Value(reflect.TypeOf(typ), rand) - if !ok { - panic(fmt.Sprintf("couldn't generate random value of type %T", typ)) - } - return v.Interface() -} diff --git a/swarm/network/kademlia_test.go b/swarm/network/kademlia_test.go new file mode 100644 index 0000000000..b60e1e9a39 --- /dev/null +++ b/swarm/network/kademlia_test.go @@ -0,0 +1,623 @@ +// 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 network + +import ( + "bytes" + "fmt" + "os" + "testing" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/swarm/pot" +) + +func init() { + h := log.LvlFilterHandler(log.LvlWarn, log.StreamHandler(os.Stderr, log.TerminalFormat(true))) + log.Root().SetHandler(h) +} + +func testKadPeerAddr(s string) *BzzAddr { + a := pot.NewAddressFromString(s) + return &BzzAddr{OAddr: a, UAddr: a} +} + +type testDropPeer struct { + Peer + dropc chan error +} + +type dropError struct { + error + addr string +} + +func (d *testDropPeer) Drop(err error) { + err2 := &dropError{err, binStr(d)} + d.dropc <- err2 +} + +type testKademlia struct { + *Kademlia + Discovery bool + dropc chan error +} + +func newTestKademlia(b string) *testKademlia { + params := NewKadParams() + params.MinBinSize = 1 + params.MinProxBinSize = 2 + base := pot.NewAddressFromString(b) + return &testKademlia{ + NewKademlia(base, params), + false, + make(chan error), + } +} + +func (k *testKademlia) newTestKadPeer(s string) Peer { + return &testDropPeer{&BzzPeer{BzzAddr: testKadPeerAddr(s)}, k.dropc} +} + +func (k *testKademlia) On(ons ...string) *testKademlia { + for _, s := range ons { + k.Kademlia.On(k.newTestKadPeer(s).(OverlayConn)) + } + return k +} + +func (k *testKademlia) Off(offs ...string) *testKademlia { + for _, s := range offs { + k.Kademlia.Off(k.newTestKadPeer(s).(OverlayConn)) + } + + return k +} + +func (k *testKademlia) Register(regs ...string) *testKademlia { + var as []OverlayAddr + for _, s := range regs { + as = append(as, testKadPeerAddr(s)) + } + err := k.Kademlia.Register(as) + if err != nil { + panic(err.Error()) + } + return k +} + +func testSuggestPeer(t *testing.T, k *testKademlia, expAddr string, expPo int, expWant bool) error { + addr, o, want := k.SuggestPeer() + if binStr(addr) != expAddr { + return fmt.Errorf("incorrect peer address suggested. expected %v, got %v", expAddr, binStr(addr)) + } + if o != expPo { + return fmt.Errorf("incorrect prox order suggested. expected %v, got %v", expPo, o) + } + if want != expWant { + return fmt.Errorf("expected SuggestPeer to want peers: %v", expWant) + } + return nil +} + +func binStr(a OverlayPeer) string { + if a == nil { + return "" + } + return pot.ToBin(a.Address())[:8] +} + +func TestSuggestPeerBug(t *testing.T) { + // 2 row gap, unsaturated proxbin, no callables -> want PO 0 + k := newTestKademlia("00000000").On( + "10000000", "11000000", + "01000000", + + "00010000", "00011000", + ).Off( + "01000000", + ) + err := testSuggestPeer(t, k, "01000000", 0, false) + if err != nil { + t.Fatal(err.Error()) + } +} + +func TestSuggestPeerFindPeers(t *testing.T) { + // 2 row gap, unsaturated proxbin, no callables -> want PO 0 + k := newTestKademlia("00000000").On("00100000") + err := testSuggestPeer(t, k, "", 0, false) + if err != nil { + t.Fatal(err.Error()) + } + + // 2 row gap, saturated proxbin, no callables -> want PO 0 + k.On("00010000") + err = testSuggestPeer(t, k, "", 0, false) + if err != nil { + t.Fatal(err.Error()) + } + + // 1 row gap (1 less), saturated proxbin, no callables -> want PO 1 + k.On("10000000") + err = testSuggestPeer(t, k, "", 1, false) + if err != nil { + t.Fatal(err.Error()) + } + + // no gap (1 less), saturated proxbin, no callables -> do not want more + k.On("01000000", "00100001") + err = testSuggestPeer(t, k, "", 0, false) + if err != nil { + t.Fatal(err.Error()) + } + + // oversaturated proxbin, > do not want more + k.On("00100001") + err = testSuggestPeer(t, k, "", 0, false) + if err != nil { + t.Fatal(err.Error()) + } + + // reintroduce gap, disconnected peer callable + // log.Info(k.String()) + k.Off("01000000") + err = testSuggestPeer(t, k, "01000000", 0, false) + if err != nil { + t.Fatal(err.Error()) + } + + // second time disconnected peer not callable + // with reasonably set Interval + err = testSuggestPeer(t, k, "", 1, true) + if err != nil { + t.Fatal(err.Error()) + } + + // on and off again, peer callable again + k.On("01000000") + k.Off("01000000") + err = testSuggestPeer(t, k, "01000000", 0, false) + if err != nil { + t.Fatal(err.Error()) + } + + k.On("01000000") + // new closer peer appears, it is immediately wanted + k.Register("00010001") + err = testSuggestPeer(t, k, "00010001", 0, false) + if err != nil { + t.Fatal(err.Error()) + } + + // PO1 disconnects + k.On("00010001") + log.Info(k.String()) + k.Off("01000000") + log.Info(k.String()) + // second time, gap filling + err = testSuggestPeer(t, k, "01000000", 0, false) + if err != nil { + t.Fatal(err.Error()) + } + + k.On("01000000") + err = testSuggestPeer(t, k, "", 0, false) + if err != nil { + t.Fatal(err.Error()) + } + + k.MinBinSize = 2 + err = testSuggestPeer(t, k, "", 0, true) + if err != nil { + t.Fatal(err.Error()) + } + + k.Register("01000001") + err = testSuggestPeer(t, k, "01000001", 0, false) + if err != nil { + t.Fatal(err.Error()) + } + + k.On("10000001") + log.Trace(fmt.Sprintf("Kad:\n%v", k.String())) + err = testSuggestPeer(t, k, "", 1, true) + if err != nil { + t.Fatal(err.Error()) + } + + k.On("01000001") + err = testSuggestPeer(t, k, "", 0, false) + if err != nil { + t.Fatal(err.Error()) + } + + k.MinBinSize = 3 + k.Register("10000010") + err = testSuggestPeer(t, k, "10000010", 0, false) + if err != nil { + t.Fatal(err.Error()) + } + + k.On("10000010") + err = testSuggestPeer(t, k, "", 1, false) + if err != nil { + t.Fatal(err.Error()) + } + + k.On("01000010") + err = testSuggestPeer(t, k, "", 2, false) + if err != nil { + t.Fatal(err.Error()) + } + + k.On("00100010") + err = testSuggestPeer(t, k, "", 3, false) + if err != nil { + t.Fatal(err.Error()) + } + + k.On("00010010") + err = testSuggestPeer(t, k, "", 0, false) + if err != nil { + t.Fatal(err.Error()) + } + +} + +func TestSuggestPeerRetries(t *testing.T) { + t.Skip("Test is disabled, because it is flaky. It fails with kademlia_test.go:346: incorrect peer address suggested. expected , got 01000000") + // 2 row gap, unsaturated proxbin, no callables -> want PO 0 + k := newTestKademlia("00000000") + k.RetryInterval = int64(100 * time.Millisecond) // cycle + k.MaxRetries = 50 + k.RetryExponent = 2 + sleep := func(n int) { + ts := k.RetryInterval + for i := 1; i < n; i++ { + ts *= int64(k.RetryExponent) + } + time.Sleep(time.Duration(ts)) + } + + k.Register("01000000") + k.On("00000001", "00000010") + err := testSuggestPeer(t, k, "01000000", 0, false) + if err != nil { + t.Fatal(err.Error()) + } + + err = testSuggestPeer(t, k, "", 0, false) + if err != nil { + t.Fatal(err.Error()) + } + + sleep(1) + err = testSuggestPeer(t, k, "01000000", 0, false) + if err != nil { + t.Fatal(err.Error()) + } + + err = testSuggestPeer(t, k, "", 0, false) + if err != nil { + t.Fatal(err.Error()) + } + + sleep(1) + err = testSuggestPeer(t, k, "01000000", 0, false) + if err != nil { + t.Fatal(err.Error()) + } + + err = testSuggestPeer(t, k, "", 0, false) + if err != nil { + t.Fatal(err.Error()) + } + + sleep(2) + err = testSuggestPeer(t, k, "01000000", 0, false) + if err != nil { + t.Fatal(err.Error()) + } + + err = testSuggestPeer(t, k, "", 0, false) + if err != nil { + t.Fatal(err.Error()) + } + + sleep(2) + err = testSuggestPeer(t, k, "", 0, false) + if err != nil { + t.Fatal(err.Error()) + } + +} + +func TestKademliaHiveString(t *testing.T) { + k := newTestKademlia("00000000").On("01000000", "00100000").Register("10000000", "10000001") + k.MaxProxDisplay = 8 + h := k.String() + expH := "\n=========================================================================\nMon Feb 27 12:10:28 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 000000\npopulation: 2 (4), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 4\n000 0 | 2 8100 (0) 8000 (0)\n============ DEPTH: 1 ==========================================\n001 1 4000 | 1 4000 (0)\n002 1 2000 | 1 2000 (0)\n003 0 | 0\n004 0 | 0\n005 0 | 0\n006 0 | 0\n007 0 | 0\n=========================================================================" + if expH[104:] != h[104:] { + t.Fatalf("incorrect hive output. expected %v, got %v", expH, h) + } +} + +// testKademliaCase constructs the kademlia and PeerPot map to validate +// the SuggestPeer and Healthy methods for provided hex-encoded addresses. +// Argument pivotAddr is the address of the kademlia. +func testKademliaCase(t *testing.T, pivotAddr string, addrs ...string) { + addr := common.FromHex(pivotAddr) + addrs = append(addrs, pivotAddr) + + k := NewKademlia(addr, NewKadParams()) + + as := make([][]byte, len(addrs)) + for i, a := range addrs { + as[i] = common.FromHex(a) + } + + for _, a := range as { + if bytes.Equal(a, addr) { + continue + } + p := &BzzAddr{OAddr: a, UAddr: a} + if err := k.Register([]OverlayAddr{p}); err != nil { + t.Fatal(err) + } + } + + ppmap := NewPeerPotMap(2, as) + + pp := ppmap[pivotAddr] + + for { + a, _, _ := k.SuggestPeer() + if a == nil { + break + } + k.On(&BzzPeer{BzzAddr: a.(*BzzAddr)}) + } + + h := k.Healthy(pp) + if !(h.GotNN && h.KnowNN && h.Full) { + t.Error("not healthy") + } +} + +/* +The regression test for the following invalid kademlia edge case. + +Addresses used in this test are discovered as part of the simulation network +in higher level tests for streaming. They were generated randomly. + +========================================================================= +Mon Apr 9 12:18:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 7efef1 +population: 9 (49), MinProxBinSize: 2, MinBinSize: 2, MaxBinSize: 4 +000 2 d7e5 ec56 | 18 ec56 (0) d7e5 (0) d9e0 (0) c735 (0) +001 2 18f1 3176 | 14 18f1 (0) 10bb (0) 10d1 (0) 0421 (0) +002 2 52aa 47cd | 11 52aa (0) 51d9 (0) 5161 (0) 5130 (0) +003 1 646e | 1 646e (0) +004 0 | 3 769c (0) 76d1 (0) 7656 (0) +============ DEPTH: 5 ========================================== +005 1 7a48 | 1 7a48 (0) +006 1 7cbd | 1 7cbd (0) +007 0 | 0 +008 0 | 0 +009 0 | 0 +010 0 | 0 +011 0 | 0 +012 0 | 0 +013 0 | 0 +014 0 | 0 +015 0 | 0 +========================================================================= +*/ +func TestKademliaCase1(t *testing.T) { + testKademliaCase(t, + "7efef1c41d77f843ad167be95f6660567eb8a4a59f39240000cce2e0d65baf8e", + "ec560e6a4806aa37f147ee83687f3cf044d9953e61eedb8c34b6d50d9e2c5623", + "646e9540c84f6a2f9cf6585d45a4c219573b4fd1b64a3c9a1386fc5cf98c0d4d", + "18f13c5fba653781019025ab10e8d2fdc916d6448729268afe9e928ffcdbb8e8", + "317617acf99b4ffddda8a736f8fc6c6ede0bf690bc23d834123823e6d03e2f69", + "d7e52d9647a5d1c27a68c3ee65d543be3947ae4b68537b236d71ef9cb15fb9ab", + "7a48f75f8ca60487ae42d6f92b785581b40b91f2da551ae73d5eae46640e02e8", + "7cbd42350bde8e18ae5b955b5450f8e2cef3419f92fbf5598160c60fd78619f0", + "52aa3ddec61f4d48dd505a2385403c634f6ad06ee1d99c5c90a5ba6006f9af9c", + "47cdb6fa93eeb8bc91a417ff4e3b14a9c2ea85137462e2f575fae97f0c4be60d", + "5161943eb42e2a03e715fe8afa1009ff5200060c870ead6ab103f63f26cb107f", + "a38eaa1255f76bf883ca0830c86e8c4bb7eed259a8348aae9b03f21f90105bee", + "b2522bdf1ab26f324e75424fdf6e493b47e8a27687fe76347607b344fc010075", + "5bd7213964efb2580b91d02ac31ef126838abeba342f5dbdbe8d4d03562671a2", + "0b531adb82744768b694d7f94f73d4f0c9de591266108daeb8c74066bfc9c9ca", + "28501f59f70e888d399570145ed884353e017443c675aa12731ada7c87ea14f7", + "4a45f1fc63e1a9cb9dfa44c98da2f3d20c2923e5d75ff60b2db9d1bdb0c54d51", + "b193431ee35cd32de95805e7c1c749450c47486595aae7195ea6b6019a64fd61", + "baebf36a1e35a7ed834e1c72faf44ba16c159fa47d3289ceb3ca35fefa8739b5", + "a3659bd32e05fa36c8d20dbaaed8362bf1a8a7bd116aed62d8a43a2efbdf513f", + "10d1b50881a4770ebebdd0a75589dabb931e6716747b0f65fd6b080b88c4fdb6", + "3c76b8ca5c7ce6a03320646826213f59229626bf5b9d25da0c3ec0662dcb8ff3", + "4d72a04ddeb851a68cd197ef9a92a3e2ff01fbbff638e64929dd1a9c2e150112", + "c7353d320987956075b5bc1668571c7a36c800d5598fdc4832ec6569561e15d1", + "d9e0c7c90878c20ab7639d5954756f54775404b3483407fe1b483635182734f6", + "8fca67216b7939c0824fb06c5279901a94da41da9482b000f56df9906736ee75", + "460719d7f7aa7d7438f0eaf30333484fa3bd0f233632c10ba89e6e46dd3604be", + "0421d92c8a1c79ed5d01305a3d25aaf22a8f5f9e3d4bc80da47ee16ce20465fe", + "3441d9d9c0f05820a1bb6459fc7d8ef266a1bd929e7db939a10f544efe8261ea", + "ab198a66c293586746758468c610e5d3914d4ce629147eff6dd55a31f863ff8f", + "3a1c8c16b0763f3d2c35269f454ff779d1255e954d2deaf6c040fb3f0bcdc945", + "5561c0ea3b203e173b11e6aa9d0e621a4e10b1d8b178b8fe375220806557b823", + "7656caccdc79cd8d7ce66d415cc96a718e8271c62fb35746bfc2b49faf3eebf3", + "5130594fd54c1652cf2debde2c4204573ed76555d1e26757fe345b409af1544a", + "76d1e83c71ca246d042e37ff1db181f2776265fbcfdc890ce230bfa617c9c2f0", + "89580231962624c53968c1b0095b4a2732b2a2640a19fdd7d21fd064fcc0a5ef", + "3d10d001fff44680c7417dd66ecf2e984f0baa20a9bbcea348583ba5ff210c4f", + "43754e323f0f3a1155b1852bd6edd55da86b8c4cfe3df8b33733fca50fc202b8", + "a9e7b1bb763ae6452ddcacd174993f82977d81a85206bb2ae3c842e2d8e19b4c", + "10bb07da7bc7c7757f74149eff167d528a94a253cdc694a863f4d50054c00b6d", + "28f0bc1b44658548d6e05dd16d4c2fe77f1da5d48b6774bc4263b045725d0c19", + "835fbbf1d16ba7347b6e2fc552d6e982148d29c624ea20383850df3c810fa8fc", + "8e236c56a77d7f46e41e80f7092b1a68cd8e92f6156365f41813ad1ca2c6b6f3", + "51d9c857e9238c49186e37b4eccf17a82de3d5739f026f6043798ab531456e73", + "bbddf7db6a682225301f36a9fd5b0d0121d2951753e1681295f3465352ad511f", + "2690a910c33ee37b91eb6c4e0731d1d345e2dc3b46d308503a6e85bbc242c69e", + "769ce86aa90b518b7ed382f9fdacfbed93574e18dc98fe6c342e4f9f409c2d5a", + "ba3bebec689ce51d3e12776c45f80d25164fdfb694a8122d908081aaa2e7122c", + "3a51f4146ea90a815d0d283d1ceb20b928d8b4d45875e892696986a3c0d8fb9b", + "81968a2d8fb39114342ee1da85254ec51e0608d7f0f6997c2a8354c260a71009", + ) +} + +/* +The regression test for the following invalid kademlia edge case. + +Addresses used in this test are discovered as part of the simulation network +in higher level tests for streaming. They were generated randomly. + +========================================================================= +Mon Apr 9 18:43:48 UTC 2018 KΛÐΞMLIΛ hive: queen's address: bc7f3b +population: 9 (49), MinProxBinSize: 2, MinBinSize: 2, MaxBinSize: 4 +000 2 0f49 67ff | 28 0f49 (0) 0211 (0) 07b2 (0) 0703 (0) +001 2 e84b f3a4 | 13 f3a4 (0) e84b (0) e58b (0) e60b (0) +002 1 8dba | 1 8dba (0) +003 2 a008 ad72 | 2 ad72 (0) a008 (0) +004 0 | 3 b61f (0) b27f (0) b027 (0) +============ DEPTH: 5 ========================================== +005 1 ba19 | 1 ba19 (0) +006 0 | 0 +007 1 bdd6 | 1 bdd6 (0) +008 0 | 0 +009 0 | 0 +010 0 | 0 +011 0 | 0 +012 0 | 0 +013 0 | 0 +014 0 | 0 +015 0 | 0 +========================================================================= +*/ +func TestKademliaCase2(t *testing.T) { + testKademliaCase(t, + "bc7f3b6a4a7e3c91b100ca6680b6c06ff407972b88956324ca853295893e0237", "67ffb61d3aa27449d277016188f35f19e2321fbda5008c68cf6303faa080534f", "600cd54c842eadac1729c04abfc369bc244572ca76117105b9dd910283b82730", "d955a05409650de151218557425105a8aa2867bb6a0e0462fa1cf90abcf87ad6", "7a6b726de45abdf7bb3e5fd9fb0dc8932270ca4dedef92238c80c05bcdb570e3", "263e99424ebfdb652adb4e3dcd27d59e11bb7ae1c057b3ef6f390d0228006254", "ba195d1a53aafde68e661c64d39db8c2a73505bf336125c15c3560de3b48b7ed", "3458c762169937115f67cabc35a6c384ed70293a8aec37b077a6c1b8e02d510e", "4ef4dc2e28ac6efdba57e134ac24dd4e0be68b9d54f7006515eb9509105f700c", "2a8782b79b0c24b9714dfd2c8ff1932bebc08aa6520b4eaeaa59ff781238890c", "625d02e960506f4524e9cdeac85b33faf3ea437fceadbd478b62b78720cf24fc", "e051a36a8c8637f520ba259c9ed3fadaf740dadc6a04c3f0e21778ebd4cd6ac4", "e34bc014fa2504f707bb3d904872b56c2fa250bee3cb19a147a0418541f1bd90", "28036dc79add95799916893890add5d8972f3b95325a509d6ded3d448f4dc652", "1b013c407794fa2e4c955d8f51cbc6bd78588a174b6548246b291281304b5409", "34f71b68698e1534095ff23ee9c35bf64c7f12b8463e7c6f6b19c25cf03928b4", "c712c6e9bbb7076832972a95890e340b94ed735935c3c0bb788e61f011b59479", "a008d5becdcda4b9dbfdaafc3cec586cf61dcf2d4b713b6168fff02e3b9f0b08", "29de15555cdbebaab214009e416ee92f947dcec5dab9894129f50f1b17138f34", "5df9449f700bd4b5a23688b68b293f2e92fa6ca524c93bc6bb9936efba9d9ada", "3ab0168a5f87fedc6a39b53c628256ac87a98670d8691bbdaaecec22418d13a2", "1ee299b2d2a74a568494130e6869e66d57982d345c482a0e0eeb285ac219ae3b", "e0e0e3b860cea9b7a74cf1b0675cc632dc64e80a02f20bbc5e96e2e8bb670606", "dc1ba6f169b0fcdcca021dcebaf39fe5d4875e7e69b854fad65687c1d7719ec0", "d321f73e42fcfb1d3a303eddf018ca5dffdcfd5567cd5ec1212f045f6a07e47d", "070320c3da7b542e5ca8aaf6a0a53d2bb5113ed264ab1db2dceee17c729edcb1", "17d314d65fdd136b50d182d2c8f5edf16e7838c2be8cf2c00abe4b406dbcd1d8", "e60b99e0a06f7d2d99d84085f67cdf8cc22a9ae22c339365d80f90289834a2b4", "02115771e18932e1f67a45f11f5bf743c5dae97fbc477d34d35c996012420eac", "3102a40eb2e5060353dd19bf61eeec8782dd1bebfcb57f4c796912252b591827", "8dbaf231062f2dc7ddaba5f9c7761b0c21292be51bf8c2ef503f31d4a2f63f79", "b02787b713c83a9f9183216310f04251994e04c2763a9024731562e8978e7cc4", "b27fe6cd33989e10909ce794c4b0b88feae286b614a59d49a3444c1a7b51ea82", "07b2d2c94fdc6fd148fe23be2ed9eff54f5e12548f29ed8416e6860fc894466f", "e58bf9f451ef62ac44ff0a9bb0610ec0fd14d423235954f0d3695e83017cbfc4", "bdd600b91bb79d1ee0053b854de308cfaa7e2abce575ea6815a0a7b3449609c2", "0f49c93c1edc7999920b21977cedd51a763940dac32e319feb9c1df2da0f3071", "7cbf0297cd41acf655cd6f960d7aaf61479edb4189d5c001cbc730861f0deb41", "79265193778d87ad626a5f59397bc075872d7302a12634ce2451a767d0a82da2", "2fe7d705f7c370b9243dbaafe007d555ff58d218822fca49d347b12a0282457c", "e84bc0c83d05e55a0080eed41dda5a795da4b9313a4da697142e69a65834cbb3", "cc4d278bd9aa0e9fb3cd8d2e0d68fb791aab5de4b120b845c409effbed47a180", "1a2317a8646cd4b6d3c4aa4cc25f676533abb689cf180787db216880a1239ad8", "cbafd6568cf8e99076208e6b6843f5808a7087897c67aad0c54694669398f889", "7b7c8357255fc37b4dae0e1af61589035fd39ff627e0938c6b3da8b4e4ec5d23", "2b8d782c1f5bac46c922cf439f6aa79f91e9ba5ffc0020d58455188a2075b334", "b61f45af2306705740742e76197a119235584ced01ef3f7cf3d4370f6c557cd1", "2775612e7cdae2780bf494c370bdcbe69c55e4a1363b1dc79ea0135e61221cce", "f3a49bb22f40885e961299abfa697a7df690a79f067bf3a4847a3ad48d826c9f", "ad724ac218dc133c0aadf4618eae21fdd0c2f3787af279846b49e2b4f97ff167", + ) +} + +/* +The regression test for the following invalid kademlia edge case. + +Addresses used in this test are discovered as part of the simulation network +in higher level tests for streaming. They were generated randomly. + +========================================================================= +Mon Apr 9 19:04:35 UTC 2018 KΛÐΞMLIΛ hive: queen's address: b4822e +population: 8 (49), MinProxBinSize: 2, MinBinSize: 2, MaxBinSize: 4 +000 2 786c 774b | 29 774b (0) 786c (0) 7a79 (0) 7d2f (0) +001 2 d9de cf19 | 10 cf19 (0) d9de (0) d2ff (0) d2a2 (0) +002 2 8ca1 8d74 | 5 8d74 (0) 8ca1 (0) 9793 (0) 9f51 (0) +003 0 | 0 +004 0 | 3 bfac (0) bcbb (0) bde9 (0) +005 0 | 0 +============ DEPTH: 6 ========================================== +006 1 b660 | 1 b660 (0) +007 0 | 0 +008 1 b450 | 1 b450 (0) +009 0 | 0 +010 0 | 0 +011 0 | 0 +012 0 | 0 +013 0 | 0 +014 0 | 0 +015 0 | 0 +========================================================================= +*/ +func TestKademliaCase3(t *testing.T) { + testKademliaCase(t, + "b4822e874a01b94ac3a35c821e6db131e785c2fcbb3556e84b36102caf09b091", "2ecf54ea38d58f9cfc3862e54e5854a7c506fbc640e0b38e46d7d45a19794999", "442374092be50fc7392e8dd3f6fab3158ff7f14f26ff98060aed9b2eecf0b97d", "b450a4a67fcfa3b976cf023d8f1f15052b727f712198ce901630efe2f95db191", "9a7291638eb1c989a6dd6661a42c735b23ac6605b5d3e428aa5ffe650e892c85", "67f62eeab9804cfcac02b25ebeab9113d1b9d03dd5200b1c5a324cc0163e722f", "2e4a0e4b53bca4a9d7e2734150e9f579f29a255ade18a268461b20d026c9ee90", "30dd79c5fcdaa1b106f6960c45c9fde7c046aa3d931088d98c52ab759d0b2ac4", "97936fb5a581e59753c54fa5feec493714f2218245f61f97a62eafd4699433e4", "3a2899b6e129e3e193f6e2aefb82589c948c246d2ec1d4272af32ef3b2660f44", "f0e2a8aa88e67269e9952431ef12e5b29b7f41a1871fbfc38567fad95655d607", "7fa12b3f3c5f8383bfc644b958f72a486969733fa097d8952b3eb4f7b4f73192", "360c167aad5fc992656d6010ec45fdce5bcd492ad9608bc515e2be70d4e430c1", "fe21bc969b3d8e5a64a6484a829c1e04208f26f3cd4de6afcbc172a5bd17f1f1", "b660a1f40141d7ccd282fe5bd9838744119bd1cb3780498b5173578cc5ad308f", "44dcb3370e76680e2fba8cd986ad45ff0b77ca45680ee8d950e47922c4af6226", "8ca126923d17fccb689647307b89f38aa14e2a7b9ebcf3c1e31ccf3d2291a3bc", "f0ae19ae9ce6329327cbf42baf090e084c196b0877d8c7b69997e0123be23ef8", "d2a2a217385158e3e1e348883a14bc423e57daa12077e8c49797d16121ea0810", "f5467ccd85bb4ebe768527db520a210459969a5f1fae6e07b43f519799f0b224", "68be5fd9f9d142a5099e3609011fe3bab7bb992c595999e31e0b3d1668dfb3cf", "4d49a8a476e4934afc6b5c36db9bece3ed1804f20b952da5a21b2b0de766aa73", "ea7155745ef3fb2d099513887a2ba279333ced65c65facbd890ce58bd3fce772", "cf19f51f4e848053d289ac95a9138cdd23fc3077ae913cd58cda8cc7a521b2e1", "590b1cd41c7e6144e76b5cd515a3a4d0a4317624620a3f1685f43ae68bdcd890", "d2ffe0626b5f94a7e00fa0b506e7455a3d9399c15800db108d5e715ef5f6e346", "69630878c50a91f6c2edd23a706bfa0b50bd5661672a37d67bab38e6bca3b698", "445e9067079899bb5faafaca915ae6c0f6b1b730a5a628835dd827636f7feb1e", "6461c77491f1c4825958949f23c153e6e1759a5be53abbcee17c9da3867f3141", "23a235f4083771ccc207771daceda700b525a59ab586788d4f6892e69e34a6e2", "bde99f79ef41a81607ddcf92b9f95dcbc6c3537e91e8bf740e193dc73b19485e", "177957c0e5f0fbd12b88022a91768095d193830986caec8d888097d3ff4310b8", "bcbbdbaa4cdf8352422072f332e05111b732354a35c4d7c617ce1fc3b8b42a5a", "774b6717fdfb0d1629fb9d4c04a9ca40079ae2955d7f82e897477055ed017abb", "16443bf625be6d39ecaa6f114e5d2c1d47a64bfd3c13808d94b55b6b6acef2ee", "8d7495d9008066505ed00ce8198af82bfa5a6b4c08768b4c9fb3aa4eb0b0cca2", "15800849a53349508cb382959527f6c3cf1a46158ff1e6e2316b7dea7967e35f", "7a792f0f4a2b731781d1b244b2a57947f1a2e32900a1c0793449f9f7ae18a7b7", "5e517c2832c9deaa7df77c7bad4d20fd6eda2b7815e155e68bc48238fac1416f", "9f51a14f0019c72bd1d472706d8c80a18c1873c6a0663e754b60eae8094483d7", "7d2fabb565122521d22ba99fed9e5be6a458fbc93156d54db27d97a00b8c3a97", "786c9e412a7db4ec278891fa534caa9a1d1a028c631c6f3aeb9c4d96ad895c36", "3bd6341d40641c2632a5a0cd7a63553a04e251efd7195897a1d27e02a7a8bfde", "31efd1f5fb57b8cff0318d77a1a9e8d67e1d1c8d18ce90f99c3a240dff48cdc8", "d9de3e1156ce1380150948acbcfecd99c96e7f4b0bc97745f4681593d017f74f", "427a2201e09f9583cd990c03b81b58148c297d474a3b50f498d83b1c7a9414cd", "bfaca11596d3dec406a9fcf5d97536516dfe7f0e3b12078428a7e1700e25218a", "351c4770a097248a650008152d0cab5825d048bef770da7f3364f59d1e721bc0", "ee00f205d1486b2be7381d962bd2867263758e880529e4e2bfedfa613bbc0e71", "6aa3b6418d89e3348e4859c823ef4d6d7cd46aa7f7e77aba586c4214d760d8f8", + ) +} + +/* +The regression test for the following invalid kademlia edge case. + +Addresses used in this test are discovered as part of the simulation network +in higher level tests for streaming. They were generated randomly. + +========================================================================= +Mon Apr 9 19:16:25 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 9a90fe +population: 8 (49), MinProxBinSize: 2, MinBinSize: 2, MaxBinSize: 4 +000 2 72ef 4e6c | 24 0b1e (0) 0d66 (0) 17f5 (0) 17e8 (0) +001 2 fc2b fa47 | 13 fa47 (0) fc2b (0) fffd (0) ecef (0) +002 2 b847 afa8 | 6 afa8 (0) ad77 (0) bb7c (0) b847 (0) +003 0 | 0 +004 0 | 4 91fc (0) 957d (0) 9482 (0) 949a (0) +============ DEPTH: 5 ========================================== +005 1 9ccf | 1 9ccf (0) +006 0 | 0 +007 1 9bb2 | 1 9bb2 (0) +008 0 | 0 +009 0 | 0 +010 0 | 0 +011 0 | 0 +012 0 | 0 +013 0 | 0 +014 0 | 0 +015 0 | 0 +========================================================================= +*/ +func TestKademliaCase4(t *testing.T) { + testKademliaCase(t, + "9a90fe3506277244549064b8c3276abb06284a199d9063a97331947f2b7da7f4", + "c19359eddef24b7be1a833b4475f212cd944263627a53f9ef4837d106c247730", "fc2b6fef99ef947f7e57c3df376891769e2a2fd83d2b8e634e0fc1e91eaa080c", "ecefc0e1a8ea7bb4b48c469e077401fce175dd75294255b96c4e54f6a2950a55", "bb7ce598efc056bba343cc2614aa3f67a575557561290b44c73a63f8f433f9f7", "55fbee6ca52dfd7f0be0db969ee8e524b654ab4f0cce7c05d83887d7d2a15460", "afa852b6b319998c6a283cc0c82d2f5b8e9410075d7700f3012761f1cfbd0f76", "36c370cfb63f2087971ba6e58d7585b04e16b8f0da335efb91554c2dd8fe191c", "6be41e029985edebc901fb77fc4fb65516b6d85086e2a98bfa3159c99391e585", "dd3cfc72ea553e7d2b28f0037a65646b30955b929d29ba4c40f4a2a811248e77", "da3a8f18e09c7b0ca235c4e33e1441a5188f1df023138bf207753ee63e768f7d", "de9e3ab4dc572d54a2d4b878329fd832bb51a149f4ce167316eeb177b61e7e01", "4e6c1ecde6ed917706257fe020a1d02d2e9d87fca4c85f0f7b132491008c5032", "72ef04b77a070e13463b3529dd312bcacfb7a12d20dc597f5ec3de0501e9b834", "3fef57186675d524ab8bb1f54ba8cb68610babca1247c0c46dbb60aed003c69d", "1d8e6b71f7a052865d6558d4ba44ad5fab7b908cc1badf5766822e1c20d0d823", "6be2f2b4ffa173014d4ec7df157d289744a2bda54bb876b264ccfa898a0da315", "b0ba3fff8643f9985c744327b0c4c869763509fd5da2de9a80a4a0a082021255", "9ccf40b9406ba2e6567101fb9b4e5334a9ec74263eff47267da266ba45e6c158", "d7347f02c180a448e60f73931845062ce00048750b584790278e9c93ef31ad81", "b68c6359a22b3bee6fecb8804311cfd816648ea31d530c9fb48e477e029d707a", "0d668a18ad7c2820214df6df95a6c855ce19fb1cb765f8ca620e45db76686d37", "3fbd2663bff65533246f1fabb9f38086854c6218aeb3dc9ac6ac73d4f0988f91", "949aa5719ca846052bfaa1b38c97b6eca3df3e24c0e0630042c6bccafbb4cdb5", "77b8a2b917bef5d54f3792183b014cca7798f713ff14fe0b2ac79b4c9f6f996d", "17e853cbd8dc00cba3cd9ffeb36f26a9f41a0eb92f80b62c2cda16771c935388", "5f682ed7a8cf2f98387c3def7c97f9f05ae39e39d393eeca3cf621268d6347f8", "ad77487eaf11fd8084ba4517a51766eb0e5b77dd3492dfa79aa3a2802fb29d20", "d247cfcacf9a8200ebaddf639f8c926ab0a001abe682f40df3785e80ed124e91", "195589442e11907eede1ee6524157f1125f68399f3170c835ff81c603b069f6c", "5b5ca0a67f3c54e7d3a6a862ef56168ec9ed1f4945e6c24de6d336b2be2e6f8c", "56430e4caa253015f1f998dce4a48a88af1953f68e94eca14f53074ae9c3e467", "0b1eed6a5bf612d1d8e08f5c546f3d12e838568fd3aa43ed4c537f10c65545d6", "7058db19a56dfff01988ac4a62e1310597f9c8d7ebde6890dadabf047d722d39", "b847380d6888ff7cd11402d086b19eccc40950b52c9d67e73cb4f8462f5df078", "df6c048419a2290ab546d527e9eeba349e7f7e1759bafe4adac507ce60ef9670", "91fc5b4b24fc3fbfea7f9a3d0f0437cb5733c0c2345d8bdffd7048d6e3b8a37b", "957d8ea51b37523952b6f5ae95462fcd4aed1483ef32cc80b69580aaeee03606", "efa82e4e91ad9ab781977400e9ac0bb9de7389aaedebdae979b73d1d3b8d72b0", "7400c9f3f3fc0cc6fe8cc37ab24b9771f44e9f78be913f73cd35fc4be030d6bd", "9bb28f4122d61f7bb56fe27ef706159fb802fef0f5de9dfa32c9c5b3183235f1", "40a8de6e98953498b806614532ea4abf8b99ad7f9719fb68203a6eae2efa5b2a", "412de0b218b8f7dcacc9205cd16ffb4eca5b838f46a2f4f9f534026061a47308", "17f56ecad51075080680ad9faa0fd8946b824d3296ddb20be07f9809fe8d1c5a", "fffd4e7ae885a41948a342b6647955a7ec8a8039039f510cff467ef597675457", "35e78e11b5ac46a29dd04ab0043136c3291f4ca56cb949ace33111ed56395463", "94824fc80230af82077c83bfc01dc9675b1f9d3d538b1e5f41c21ac753598691", "fa470ae314ca3fce493f21b423eef2a49522e09126f6f2326fa3c9cac0b344f7", "7078860b5b621b21ac7b95f9fc4739c8235ce5066a8b9bd7d938146a34fa88ec", "eea53560f0428bfd2eca4f86a5ce9dec5ff1309129a975d73465c1c9e9da71d1", + ) +} + +/* +The regression test for the following invalid kademlia edge case. + +Addresses used in this test are discovered as part of the simulation network +in higher level tests for streaming. They were generated randomly. + +========================================================================= +Mon Apr 9 19:25:18 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 5dd5c7 +population: 13 (49), MinProxBinSize: 2, MinBinSize: 2, MaxBinSize: 4 +000 2 e528 fad0 | 22 fad0 (0) e528 (0) e3bb (0) ed13 (0) +001 3 3f30 18e0 1dd3 | 7 3f30 (0) 23db (0) 10b6 (0) 18e0 (0) +002 4 7c54 7804 61e4 60f9 | 10 61e4 (0) 60f9 (0) 636c (0) 7186 (0) +003 2 40ae 4bae | 5 4bae (0) 4d5c (0) 403a (0) 40ae (0) +004 0 | 0 +005 0 | 3 5808 (0) 5a0e (0) 5bdb (0) +============ DEPTH: 6 ========================================== +006 2 5f14 5f61 | 2 5f14 (0) 5f61 (0) +007 0 | 0 +008 0 | 0 +009 0 | 0 +010 0 | 0 +011 0 | 0 +012 0 | 0 +013 0 | 0 +014 0 | 0 +015 0 | 0 +========================================================================= +*/ +func TestKademliaCase5(t *testing.T) { + testKademliaCase(t, + "5dd5c77dd9006a800478fcebb02d48d4036389e7d3c8f6a83b97dbad13f4c0a9", + "78fafa0809929a1279ece089a51d12457c2d8416dff859aeb2ccc24bb50df5ec", "1dd39b1257e745f147cbbc3cadd609ccd6207c41056dbc4254bba5d2527d3ee5", "5f61dd66d4d94aec8fcc3ce0e7885c7edf30c43143fa730e2841c5d28e3cd081", "8aa8b0472cb351d967e575ad05c4b9f393e76c4b01ef4b3a54aac5283b78abc9", "4502f385152a915b438a6726ce3ea9342e7a6db91a23c2f6bee83a885ed7eb82", "718677a504249db47525e959ef1784bed167e1c46f1e0275b9c7b588e28a3758", "7c54c6ed1f8376323896ed3a4e048866410de189e9599dd89bf312ca4adb96b5", "18e03bd3378126c09e799a497150da5c24c895aedc84b6f0dbae41fc4bac081a", "23db76ac9e6e58d9f5395ca78252513a7b4118b4155f8462d3d5eec62486cadc", "40ae0e8f065e96c7adb7fa39505136401f01780481e678d718b7f6dbb2c906ec", "c1539998b8bae19d339d6bbb691f4e9daeb0e86847545229e80fe0dffe716e92", "ed139d73a2699e205574c08722ca9f030ad2d866c662f1112a276b91421c3cb9", "5bdb19584b7a36d09ca689422ef7e6bb681b8f2558a6b2177a8f7c812f631022", "636c9de7fe234ffc15d67a504c69702c719f626c17461d3f2918e924cd9d69e2", "de4455413ff9335c440d52458c6544191bd58a16d85f700c1de53b62773064ea", "de1963310849527acabc7885b6e345a56406a8f23e35e436b6d9725e69a79a83", "a80a50a467f561210a114cba6c7fb1489ed43a14d61a9edd70e2eb15c31f074d", "7804f12b8d8e6e4b375b242058242068a3809385e05df0e64973cde805cf729c", "60f9aa320c02c6f2e6370aa740cf7cea38083fa95fca8c99552cda52935c1520", "d8da963602390f6c002c00ce62a84b514edfce9ebde035b277a957264bb54d21", "8463d93256e026fe436abad44697152b9a56ac8e06a0583d318e9571b83d073c", "9a3f78fcefb9a05e40a23de55f6153d7a8b9d973ede43a380bf46bb3b3847de1", "e3bb576f4b3760b9ca6bff59326f4ebfc4a669d263fb7d67ab9797adea54ed13", "4d5cdbd6dcca5bdf819a0fe8d175dc55cc96f088d37462acd5ea14bc6296bdbe", "5a0ed28de7b5258c727cb85447071c74c00a5fbba9e6bc0393bc51944d04ab2a", "61e4ddb479c283c638f4edec24353b6cc7a3a13b930824aad016b0996ca93c47", "7e3610868acf714836cafaaa7b8c009a9ac6e3a6d443e5586cf661530a204ee2", "d74b244d4345d2c86e30a097105e4fb133d53c578320285132a952cdaa64416e", "cfeed57d0f935bfab89e3f630a7c97e0b1605f0724d85a008bbfb92cb47863a8", "580837af95055670e20d494978f60c7f1458dc4b9e389fc7aa4982b2aca3bce3", "df55c0c49e6c8a83d82dfa1c307d3bf6a20e18721c80d8ec4f1f68dc0a137ced", "5f149c51ce581ba32a285439a806c063ced01ccd4211cd024e6a615b8f216f95", "1eb76b00aeb127b10dd1b7cd4c3edeb4d812b5a658f0feb13e85c4d2b7c6fe06", "7a56ba7c3fb7cbfb5561a46a75d95d7722096b45771ec16e6fa7bbfab0b35dfe", "4bae85ad88c28470f0015246d530adc0cd1778bdd5145c3c6b538ee50c4e04bd", "afd1892e2a7145c99ec0ebe9ded0d3fec21089b277a68d47f45961ec5e39e7e0", "953138885d7b36b0ef79e46030f8e61fd7037fbe5ce9e0a94d728e8c8d7eab86", "de761613ef305e4f628cb6bf97d7b7dc69a9d513dc233630792de97bcda777a6", "3f3087280063d09504c084bbf7fdf984347a72b50d097fd5b086ffabb5b3fb4c", "7d18a94bb1ebfdef4d3e454d2db8cb772f30ca57920dd1e402184a9e598581a0", "a7d6fbdc9126d9f10d10617f49fb9f5474ffe1b229f76b7dd27cebba30eccb5d", "fad0246303618353d1387ec10c09ee991eb6180697ed3470ed9a6b377695203d", "1cf66e09ea51ee5c23df26615a9e7420be2ac8063f28f60a3bc86020e94fe6f3", "8269cdaa153da7c358b0b940791af74d7c651cd4d3f5ed13acfe6d0f2c539e7f", "90d52eaaa60e74bf1c79106113f2599471a902d7b1c39ac1f55b20604f453c09", "9788fd0c09190a3f3d0541f68073a2f44c2fcc45bb97558a7c319f36c25a75b3", "10b68fc44157ecfdae238ee6c1ce0333f906ad04d1a4cb1505c8e35c3c87fbb0", "e5284117fdf3757920475c786e0004cb00ba0932163659a89b36651a01e57394", "403ad51d911e113dcd5f9ff58c94f6d278886a2a4da64c3ceca2083282c92de3", + ) +} diff --git a/swarm/network/messages.go b/swarm/network/messages.go deleted file mode 100644 index d920def959..0000000000 --- a/swarm/network/messages.go +++ /dev/null @@ -1,308 +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 network - -import ( - "fmt" - "net" - "time" - - "github.com/ethereum/go-ethereum/contracts/chequebook" - "github.com/ethereum/go-ethereum/p2p/discover" - "github.com/ethereum/go-ethereum/swarm/network/kademlia" - "github.com/ethereum/go-ethereum/swarm/services/swap" - "github.com/ethereum/go-ethereum/swarm/storage" -) - -/* -BZZ protocol Message Types and Message Data Types -*/ - -// bzz protocol message codes -const ( - statusMsg = iota // 0x01 - storeRequestMsg // 0x02 - retrieveRequestMsg // 0x03 - peersMsg // 0x04 - syncRequestMsg // 0x05 - deliveryRequestMsg // 0x06 - unsyncedKeysMsg // 0x07 - paymentMsg // 0x08 -) - -/* - Handshake - -* Version: 8 byte integer version of the protocol -* ID: arbitrary byte sequence client identifier human readable -* Addr: the address advertised by the node, format similar to DEVp2p wire protocol -* Swap: info for the swarm accounting protocol -* NetworkID: 8 byte integer network identifier -* Caps: swarm-specific capabilities, format identical to devp2p -* SyncState: syncronisation state (db iterator key and address space etc) persisted about the peer - -*/ -type statusMsgData struct { - Version uint64 - ID string - Addr *peerAddr - Swap *swap.SwapProfile - NetworkId uint64 -} - -func (self *statusMsgData) String() string { - return fmt.Sprintf("Status: Version: %v, ID: %v, Addr: %v, Swap: %v, NetworkId: %v", self.Version, self.ID, self.Addr, self.Swap, self.NetworkId) -} - -/* - store requests are forwarded to the peers in their kademlia proximity bin - if they are distant - if they are within our storage radius or have any incentive to store it - then attach your nodeID to the metadata - if the storage request is sufficiently close (within our proxLimit, i. e., the - last row of the routing table) -*/ -type storeRequestMsgData struct { - Key storage.Key // hash of datasize | data - SData []byte // the actual chunk Data - // optional - Id uint64 // request ID. if delivery, the ID is retrieve request ID - requestTimeout *time.Time // expiry for forwarding - [not serialised][not currently used] - storageTimeout *time.Time // expiry of content - [not serialised][not currently used] - from *peer // [not serialised] protocol registers the requester -} - -func (self storeRequestMsgData) String() string { - var from string - if self.from == nil { - from = "self" - } else { - from = self.from.Addr().String() - } - end := len(self.SData) - if len(self.SData) > 10 { - end = 10 - } - return fmt.Sprintf("from: %v, Key: %v; ID: %v, requestTimeout: %v, storageTimeout: %v, SData %x", from, self.Key, self.Id, self.requestTimeout, self.storageTimeout, self.SData[:end]) -} - -/* -Retrieve request - -Timeout in milliseconds. Note that zero timeout retrieval requests do not request forwarding, but prompt for a peers message response. therefore they serve also -as messages to retrieve peers. - -MaxSize specifies the maximum size that the peer will accept. This is useful in -particular if we allow storage and delivery of multichunk payload representing -the entire or partial subtree unfolding from the requested root key. -So when only interested in limited part of a stream (infinite trees) or only -testing chunk availability etc etc, we can indicate it by limiting the size here. - -Request ID can be newly generated or kept from the request originator. -If request ID Is missing or zero, the request is handled as a lookup only -prompting a peers response but not launching a search. Lookup requests are meant -to be used to bootstrap kademlia tables. - -In the special case that the key is the zero value as well, the remote peer's -address is assumed (the message is to be handled as a self lookup request). -The response is a PeersMsg with the peers in the kademlia proximity bin -corresponding to the address. -*/ - -type retrieveRequestMsgData struct { - Key storage.Key // target Key address of chunk to be retrieved - Id uint64 // request id, request is a lookup if missing or zero - MaxSize uint64 // maximum size of delivery accepted - MaxPeers uint64 // maximum number of peers returned - Timeout uint64 // the longest time we are expecting a response - timeout *time.Time // [not serialied] - from *peer // -} - -func (self *retrieveRequestMsgData) String() string { - var from string - if self.from == nil { - from = "ourselves" - } else { - from = self.from.Addr().String() - } - var target []byte - if len(self.Key) > 3 { - target = self.Key[:4] - } - return fmt.Sprintf("from: %v, Key: %x; ID: %v, MaxSize: %v, MaxPeers: %d", from, target, self.Id, self.MaxSize, self.MaxPeers) -} - -// lookups are encoded by missing request ID -func (self *retrieveRequestMsgData) isLookup() bool { - return self.Id == 0 -} - -// sets timeout fields -func (self *retrieveRequestMsgData) setTimeout(t *time.Time) { - self.timeout = t - if t != nil { - self.Timeout = uint64(t.UnixNano()) - } else { - self.Timeout = 0 - } -} - -func (self *retrieveRequestMsgData) getTimeout() (t *time.Time) { - if self.Timeout > 0 && self.timeout == nil { - timeout := time.Unix(int64(self.Timeout), 0) - t = &timeout - self.timeout = t - } - return -} - -// peerAddr is sent in StatusMsg as part of the handshake -type peerAddr struct { - IP net.IP - Port uint16 - ID []byte // the 64 byte NodeID (ECDSA Public Key) - Addr kademlia.Address -} - -// peerAddr pretty prints as enode -func (self *peerAddr) String() string { - var nodeid discover.NodeID - copy(nodeid[:], self.ID) - return discover.NewNode(nodeid, self.IP, 0, self.Port).String() -} - -/* -peers Msg is one response to retrieval; it is always encouraged after a retrieval -request to respond with a list of peers in the same kademlia proximity bin. -The encoding of a peer is identical to that in the devp2p base protocol peers -messages: [IP, Port, NodeID] -note that a node's DPA address is not the NodeID but the hash of the NodeID. - -Timeout serves to indicate whether the responder is forwarding the query within -the timeout or not. - -NodeID serves as the owner of payment contracts and signer of proofs of transfer. - -The Key is the target (if response to a retrieval request) or missing (zero value) -peers address (hash of NodeID) if retrieval request was a self lookup. - -Peers message is requested by retrieval requests with a missing or zero value request ID -*/ -type peersMsgData struct { - Peers []*peerAddr // - Timeout uint64 // - timeout *time.Time // indicate whether responder is expected to deliver content - Key storage.Key // present if a response to a retrieval request - Id uint64 // present if a response to a retrieval request - from *peer -} - -// peers msg pretty printer -func (self *peersMsgData) String() string { - var from string - if self.from == nil { - from = "ourselves" - } else { - from = self.from.Addr().String() - } - var target []byte - if len(self.Key) > 3 { - target = self.Key[:4] - } - return fmt.Sprintf("from: %v, Key: %x; ID: %v, Peers: %v", from, target, self.Id, self.Peers) -} - -func (self *peersMsgData) setTimeout(t *time.Time) { - self.timeout = t - if t != nil { - self.Timeout = uint64(t.UnixNano()) - } else { - self.Timeout = 0 - } -} - -/* -syncRequest - -is sent after the handshake to initiate syncing -the syncState of the remote node is persisted in kaddb and set on the -peer/protocol instance when the node is registered by hive as online{ -*/ - -type syncRequestMsgData struct { - SyncState *syncState `rlp:"nil"` -} - -func (self *syncRequestMsgData) String() string { - return fmt.Sprintf("%v", self.SyncState) -} - -/* -deliveryRequest - -is sent once a batch of sync keys is filtered. The ones not found are -sent as a list of syncReuest (hash, priority) in the Deliver field. -When the source receives the sync request it continues to iterate -and fetch at most N items as yet unsynced. -At the same time responds with deliveries of the items. -*/ -type deliveryRequestMsgData struct { - Deliver []*syncRequest -} - -func (self *deliveryRequestMsgData) String() string { - return fmt.Sprintf("sync request for new chunks\ndelivery request for %v chunks", len(self.Deliver)) -} - -/* -unsyncedKeys - -is sent first after the handshake if SyncState iterator brings up hundreds, thousands? -and subsequently sent as a response to deliveryRequestMsgData. - -Syncing is the iterative process of exchanging unsyncedKeys and deliveryRequestMsgs -both ways. - -State contains the sync state sent by the source. When the source receives the -sync state it continues to iterate and fetch at most N items as yet unsynced. -At the same time responds with deliveries of the items. -*/ -type unsyncedKeysMsgData struct { - Unsynced []*syncRequest - State *syncState -} - -func (self *unsyncedKeysMsgData) String() string { - return fmt.Sprintf("sync: keys of %d new chunks (state %v) => synced: %v", len(self.Unsynced), self.State, self.State.Synced) -} - -/* -payment - -is sent when the swap balance is tilted in favour of the remote peer -and in absolute units exceeds the PayAt parameter in the remote peer's profile -*/ - -type paymentMsgData struct { - Units uint // units actually paid for (checked against amount by swap) - Promise *chequebook.Cheque // payment with cheque -} - -func (self *paymentMsgData) String() string { - return fmt.Sprintf("payment for %d units: %v", self.Units, self.Promise) -} diff --git a/swarm/network/networkid_test.go b/swarm/network/networkid_test.go new file mode 100644 index 0000000000..05134b083b --- /dev/null +++ b/swarm/network/networkid_test.go @@ -0,0 +1,266 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package network + +import ( + "bytes" + "context" + "flag" + "fmt" + "math/rand" + "strings" + "testing" + "time" + + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/node" + "github.com/ethereum/go-ethereum/p2p" + "github.com/ethereum/go-ethereum/p2p/discover" + "github.com/ethereum/go-ethereum/p2p/simulations" + "github.com/ethereum/go-ethereum/p2p/simulations/adapters" + "github.com/ethereum/go-ethereum/rpc" +) + +var ( + currentNetworkID int + cnt int + nodeMap map[int][]discover.NodeID + kademlias map[discover.NodeID]*Kademlia +) + +const ( + NumberOfNets = 4 + MaxTimeout = 6 +) + +func init() { + flag.Parse() + rand.Seed(time.Now().Unix()) +} + +/* +Run the network ID test. +The test creates one simulations.Network instance, +a number of nodes, then connects nodes with each other in this network. + +Each node gets a network ID assigned according to the number of networks. +Having more network IDs is just arbitrary in order to exclude +false positives. + +Nodes should only connect with other nodes with the same network ID. +After the setup phase, the test checks on each node if it has the +expected node connections (excluding those not sharing the network ID). +*/ +func TestNetworkID(t *testing.T) { + log.Debug("Start test") + //arbitrarily set the number of nodes. It could be any number + numNodes := 24 + //the nodeMap maps all nodes (slice value) with the same network ID (key) + nodeMap = make(map[int][]discover.NodeID) + //set up the network and connect nodes + net, err := setupNetwork(numNodes) + if err != nil { + t.Fatalf("Error setting up network: %v", err) + } + defer func() { + //shutdown the snapshot network + log.Trace("Shutting down network") + net.Shutdown() + }() + //let's sleep to ensure all nodes are connected + time.Sleep(1 * time.Second) + //for each group sharing the same network ID... + for _, netIDGroup := range nodeMap { + log.Trace("netIDGroup size", "size", len(netIDGroup)) + //...check that their size of the kademlia is of the expected size + //the assumption is that it should be the size of the group minus 1 (the node itself) + for _, node := range netIDGroup { + if kademlias[node].addrs.Size() != len(netIDGroup)-1 { + t.Fatalf("Kademlia size has not expected peer size. Kademlia size: %d, expected size: %d", kademlias[node].addrs.Size(), len(netIDGroup)-1) + } + kademlias[node].EachAddr(nil, 0, func(addr OverlayAddr, _ int, _ bool) bool { + found := false + for _, nd := range netIDGroup { + p := ToOverlayAddr(nd.Bytes()) + if bytes.Equal(p, addr.Address()) { + found = true + } + } + if !found { + t.Fatalf("Expected node not found for node %s", node.String()) + } + return true + }) + } + } + log.Info("Test terminated successfully") +} + +// setup simulated network with bzz/discovery and pss services. +// connects nodes in a circle +// if allowRaw is set, omission of builtin pss encryption is enabled (see PssParams) +func setupNetwork(numnodes int) (net *simulations.Network, err error) { + log.Debug("Setting up network") + quitC := make(chan struct{}) + errc := make(chan error) + nodes := make([]*simulations.Node, numnodes) + if numnodes < 16 { + return nil, fmt.Errorf("Minimum sixteen nodes in network") + } + adapter := adapters.NewSimAdapter(newServices()) + //create the network + net = simulations.NewNetwork(adapter, &simulations.NetworkConfig{ + ID: "NetworkIdTestNet", + DefaultService: "bzz", + }) + log.Debug("Creating networks and nodes") + + var connCount int + + //create nodes and connect them to each other + for i := 0; i < numnodes; i++ { + log.Trace("iteration: ", "i", i) + nodeconf := adapters.RandomNodeConfig() + nodes[i], err = net.NewNodeWithConfig(nodeconf) + if err != nil { + return nil, fmt.Errorf("error creating node %d: %v", i, err) + } + err = net.Start(nodes[i].ID()) + if err != nil { + return nil, fmt.Errorf("error starting node %d: %v", i, err) + } + client, err := nodes[i].Client() + if err != nil { + return nil, fmt.Errorf("create node %d rpc client fail: %v", i, err) + } + //now setup and start event watching in order to know when we can upload + ctx, watchCancel := context.WithTimeout(context.Background(), MaxTimeout*time.Second) + defer watchCancel() + watchSubscriptionEvents(ctx, nodes[i].ID(), client, errc, quitC) + //on every iteration we connect to all previous ones + for k := i - 1; k >= 0; k-- { + connCount++ + log.Debug(fmt.Sprintf("Connecting node %d with node %d; connection count is %d", i, k, connCount)) + err = net.Connect(nodes[i].ID(), nodes[k].ID()) + if err != nil { + if !strings.Contains(err.Error(), "already connected") { + return nil, fmt.Errorf("error connecting nodes: %v", err) + } + } + } + } + //now wait until the number of expected subscriptions has been finished + //`watchSubscriptionEvents` will write with a `nil` value to errc + for err := range errc { + if err != nil { + return nil, err + } + //`nil` received, decrement count + connCount-- + log.Trace("count down", "cnt", connCount) + //all subscriptions received + if connCount == 0 { + close(quitC) + break + } + } + log.Debug("Network setup phase terminated") + return net, nil +} + +func newServices() adapters.Services { + kademlias = make(map[discover.NodeID]*Kademlia) + kademlia := func(id discover.NodeID) *Kademlia { + if k, ok := kademlias[id]; ok { + return k + } + addr := NewAddrFromNodeID(id) + params := NewKadParams() + params.MinProxBinSize = 2 + params.MaxBinSize = 3 + params.MinBinSize = 1 + params.MaxRetries = 1000 + params.RetryExponent = 2 + params.RetryInterval = 1000000 + kademlias[id] = NewKademlia(addr.Over(), params) + return kademlias[id] + } + return adapters.Services{ + "bzz": func(ctx *adapters.ServiceContext) (node.Service, error) { + addr := NewAddrFromNodeID(ctx.Config.ID) + hp := NewHiveParams() + hp.Discovery = false + cnt++ + //assign the network ID + currentNetworkID = cnt % NumberOfNets + if ok := nodeMap[currentNetworkID]; ok == nil { + nodeMap[currentNetworkID] = make([]discover.NodeID, 0) + } + //add this node to the group sharing the same network ID + nodeMap[currentNetworkID] = append(nodeMap[currentNetworkID], ctx.Config.ID) + log.Debug("current network ID:", "id", currentNetworkID) + config := &BzzConfig{ + OverlayAddr: addr.Over(), + UnderlayAddr: addr.Under(), + HiveParams: hp, + NetworkID: uint64(currentNetworkID), + } + return NewBzz(config, kademlia(ctx.Config.ID), nil, nil, nil), nil + }, + } +} + +func watchSubscriptionEvents(ctx context.Context, id discover.NodeID, client *rpc.Client, errc chan error, quitC chan struct{}) { + events := make(chan *p2p.PeerEvent) + sub, err := client.Subscribe(context.Background(), "admin", events, "peerEvents") + if err != nil { + log.Error(err.Error()) + errc <- fmt.Errorf("error getting peer events for node %v: %s", id, err) + return + } + go func() { + defer func() { + sub.Unsubscribe() + log.Trace("watch subscription events: unsubscribe", "id", id) + }() + + for { + select { + case <-quitC: + return + case <-ctx.Done(): + select { + case errc <- ctx.Err(): + case <-quitC: + } + return + case e := <-events: + if e.Type == p2p.PeerEventTypeAdd { + errc <- nil + } + case err := <-sub.Err(): + if err != nil { + select { + case errc <- fmt.Errorf("error getting peer events for node %v: %v", id, err): + case <-quitC: + } + return + } + } + } + }() +} diff --git a/swarm/network/priorityqueue/priorityqueue.go b/swarm/network/priorityqueue/priorityqueue.go new file mode 100644 index 0000000000..fab638c9e2 --- /dev/null +++ b/swarm/network/priorityqueue/priorityqueue.go @@ -0,0 +1,111 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +// package priority_queue implement a channel based priority queue +// over arbitrary types. It provides an +// an autopop loop applying a function to the items always respecting +// their priority. The structure is only quasi consistent ie., if a lower +// priority item is autopopped, it is guaranteed that there was a point +// when no higher priority item was present, ie. it is not guaranteed +// that there was any point where the lower priority item was present +// but the higher was not + +package priorityqueue + +import ( + "context" + "errors" +) + +var ( + errContention = errors.New("queue contention") + errBadPriority = errors.New("bad priority") + + wakey = struct{}{} +) + +// PriorityQueue is the basic structure +type PriorityQueue struct { + queues []chan interface{} + wakeup chan struct{} +} + +// New is the constructor for PriorityQueue +func New(n int, l int) *PriorityQueue { + var queues = make([]chan interface{}, n) + for i := range queues { + queues[i] = make(chan interface{}, l) + } + return &PriorityQueue{ + queues: queues, + wakeup: make(chan struct{}, 1), + } +} + +// Run is a forever loop popping items from the queues +func (pq *PriorityQueue) Run(ctx context.Context, f func(interface{})) { + top := len(pq.queues) - 1 + p := top +READ: + for { + q := pq.queues[p] + select { + case <-ctx.Done(): + return + case x := <-q: + f(x) + p = top + default: + if p > 0 { + p-- + continue READ + } + p = top + select { + case <-ctx.Done(): + return + case <-pq.wakeup: + } + } + } +} + +// Push pushes an item to the appropriate queue specified in the priority argument +// if context is given it waits until either the item is pushed or the Context aborts +// otherwise returns errContention if the queue is full +func (pq *PriorityQueue) Push(ctx context.Context, x interface{}, p int) error { + if p < 0 || p >= len(pq.queues) { + return errBadPriority + } + if ctx == nil { + select { + case pq.queues[p] <- x: + default: + return errContention + } + } else { + select { + case pq.queues[p] <- x: + case <-ctx.Done(): + return ctx.Err() + } + } + select { + case pq.wakeup <- wakey: + default: + } + return nil +} diff --git a/swarm/network/priorityqueue/priorityqueue_test.go b/swarm/network/priorityqueue/priorityqueue_test.go new file mode 100644 index 0000000000..cd54250f8e --- /dev/null +++ b/swarm/network/priorityqueue/priorityqueue_test.go @@ -0,0 +1,97 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . +package priorityqueue + +import ( + "context" + "sync" + "testing" +) + +func TestPriorityQueue(t *testing.T) { + var results []string + wg := sync.WaitGroup{} + pq := New(3, 2) + wg.Add(1) + go pq.Run(context.Background(), func(v interface{}) { + results = append(results, v.(string)) + wg.Done() + }) + pq.Push(context.Background(), "2.0", 2) + wg.Wait() + if results[0] != "2.0" { + t.Errorf("expected first result %q, got %q", "2.0", results[0]) + } + +Loop: + for i, tc := range []struct { + priorities []int + values []string + results []string + errors []error + }{ + { + priorities: []int{0}, + values: []string{""}, + results: []string{""}, + }, + { + priorities: []int{0, 1}, + values: []string{"0.0", "1.0"}, + results: []string{"1.0", "0.0"}, + }, + { + priorities: []int{1, 0}, + values: []string{"1.0", "0.0"}, + results: []string{"1.0", "0.0"}, + }, + { + priorities: []int{0, 1, 1}, + values: []string{"0.0", "1.0", "1.1"}, + results: []string{"1.0", "1.1", "0.0"}, + }, + { + priorities: []int{0, 0, 0}, + values: []string{"0.0", "0.0", "0.1"}, + errors: []error{nil, nil, errContention}, + }, + } { + var results []string + wg := sync.WaitGroup{} + pq := New(3, 2) + wg.Add(len(tc.values)) + for j, value := range tc.values { + err := pq.Push(nil, value, tc.priorities[j]) + if tc.errors != nil && err != tc.errors[j] { + t.Errorf("expected push error %v, got %v", tc.errors[j], err) + continue Loop + } + if err != nil { + continue Loop + } + } + go pq.Run(context.Background(), func(v interface{}) { + results = append(results, v.(string)) + wg.Done() + }) + wg.Wait() + for k, result := range tc.results { + if results[k] != result { + t.Errorf("test case %v: expected %v element %q, got %q", i, k, result, results[k]) + } + } + } +} diff --git a/swarm/network/protocol.go b/swarm/network/protocol.go index 1cbe00a973..49ae5a15bf 100644 --- a/swarm/network/protocol.go +++ b/swarm/network/protocol.go @@ -16,519 +16,414 @@ package network -/* -bzz implements the swarm wire protocol [bzz] (sister of eth and shh) -the protocol instance is launched on each peer by the network layer if the -bzz protocol handler is registered on the p2p server. - -The bzz protocol component speaks the bzz protocol -* handle the protocol handshake -* register peers in the KΛÐΞMLIΛ table via the hive logistic manager -* dispatch to hive for handling the DHT logic -* encode and decode requests for storage and retrieval -* handle sync protocol messages via the syncer -* talks the SWAP payment protocol (swap accounting is done within NetStore) -*/ - import ( + "context" "errors" "fmt" "net" - "strconv" + "sync" "time" - "github.com/ethereum/go-ethereum/contracts/chequebook" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/metrics" + "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/p2p" - bzzswap "github.com/ethereum/go-ethereum/swarm/services/swap" - "github.com/ethereum/go-ethereum/swarm/services/swap/swap" - "github.com/ethereum/go-ethereum/swarm/storage" -) - -//metrics variables -var ( - storeRequestMsgCounter = metrics.NewRegisteredCounter("network.protocol.msg.storerequest.count", nil) - retrieveRequestMsgCounter = metrics.NewRegisteredCounter("network.protocol.msg.retrieverequest.count", nil) - peersMsgCounter = metrics.NewRegisteredCounter("network.protocol.msg.peers.count", nil) - syncRequestMsgCounter = metrics.NewRegisteredCounter("network.protocol.msg.syncrequest.count", nil) - unsyncedKeysMsgCounter = metrics.NewRegisteredCounter("network.protocol.msg.unsyncedkeys.count", nil) - deliverRequestMsgCounter = metrics.NewRegisteredCounter("network.protocol.msg.deliverrequest.count", nil) - paymentMsgCounter = metrics.NewRegisteredCounter("network.protocol.msg.payment.count", nil) - invalidMsgCounter = metrics.NewRegisteredCounter("network.protocol.msg.invalid.count", nil) - handleStatusMsgCounter = metrics.NewRegisteredCounter("network.protocol.msg.handlestatus.count", nil) + "github.com/ethereum/go-ethereum/p2p/discover" + "github.com/ethereum/go-ethereum/p2p/protocols" + "github.com/ethereum/go-ethereum/rpc" + "github.com/ethereum/go-ethereum/swarm/log" + "github.com/ethereum/go-ethereum/swarm/state" ) const ( - Version = 0 - ProtocolLength = uint64(8) + DefaultNetworkID = 3 + // ProtocolMaxMsgSize maximum allowed message size ProtocolMaxMsgSize = 10 * 1024 * 1024 - NetworkId = 3 + // timeout for waiting + bzzHandshakeTimeout = 3000 * time.Millisecond ) -// bzz represents the swarm wire protocol -// an instance is running on each peer -type bzz struct { - storage StorageHandler // handler storage/retrieval related requests coming via the bzz wire protocol - hive *Hive // the logistic manager, peerPool, routing service and peer handler - dbAccess *DbAccess // access to db storage counter and iterator for syncing - requestDb *storage.LDBDatabase // db to persist backlog of deliveries to aid syncing - remoteAddr *peerAddr // remote peers address - peer *p2p.Peer // the p2p peer object - rw p2p.MsgReadWriter // messageReadWriter to send messages to - backend chequebook.Backend - lastActive time.Time - NetworkId uint64 - - swap *swap.Swap // swap instance for the peer connection - swapParams *bzzswap.SwapParams // swap settings both local and remote - swapEnabled bool // flag to enable SWAP (will be set via Caps in handshake) - syncEnabled bool // flag to enable SYNC (will be set via Caps in handshake) - syncer *syncer // syncer instance for the peer connection - syncParams *SyncParams // syncer params - syncState *syncState // outgoing syncronisation state (contains reference to remote peers db counter) +// BzzSpec is the spec of the generic swarm handshake +var BzzSpec = &protocols.Spec{ + Name: "bzz", + Version: 5, + MaxMsgSize: 10 * 1024 * 1024, + Messages: []interface{}{ + HandshakeMsg{}, + }, } -// interface type for handler of storage/retrieval related requests coming -// via the bzz wire protocol -// messages: UnsyncedKeys, DeliveryRequest, StoreRequest, RetrieveRequest -type StorageHandler interface { - HandleUnsyncedKeysMsg(req *unsyncedKeysMsgData, p *peer) error - HandleDeliveryRequestMsg(req *deliveryRequestMsgData, p *peer) error - HandleStoreRequestMsg(req *storeRequestMsgData, p *peer) - HandleRetrieveRequestMsg(req *retrieveRequestMsgData, p *peer) +// DiscoverySpec is the spec for the bzz discovery subprotocols +var DiscoverySpec = &protocols.Spec{ + Name: "hive", + Version: 5, + MaxMsgSize: 10 * 1024 * 1024, + Messages: []interface{}{ + peersMsg{}, + subPeersMsg{}, + }, } -/* -main entrypoint, wrappers starting a server that will run the bzz protocol -use this constructor to attach the protocol ("class") to server caps -This is done by node.Node#Register(func(node.ServiceContext) (Service, error)) -Service implements Protocols() which is an array of protocol constructors -at node startup the protocols are initialised -the Dev p2p layer then calls Run(p *p2p.Peer, rw p2p.MsgReadWriter) error -on each peer connection -The Run function of the Bzz protocol class creates a bzz instance -which will represent the peer for the swarm hive and all peer-aware components -*/ -func Bzz(cloud StorageHandler, backend chequebook.Backend, hive *Hive, dbaccess *DbAccess, sp *bzzswap.SwapParams, sy *SyncParams, networkId uint64) (p2p.Protocol, error) { +// Addr interface that peerPool needs +type Addr interface { + OverlayPeer + Over() []byte + Under() []byte + String() string + Update(OverlayAddr) OverlayAddr +} - // a single global request db is created for all peer connections - // this is to persist delivery backlog and aid syncronisation - requestDb, err := storage.NewLDBDatabase(sy.RequestDbPath) - if err != nil { - return p2p.Protocol{}, fmt.Errorf("error setting up request db: %v", err) +// Peer interface represents an live peer connection +type Peer interface { + Addr // the address of a peer + Conn // the live connection (protocols.Peer) + LastActive() time.Time // last time active +} + +// Conn interface represents an live peer connection +type Conn interface { + ID() discover.NodeID // the key that uniquely identifies the Node for the peerPool + Handshake(context.Context, interface{}, func(interface{}) error) (interface{}, error) // can send messages + Send(context.Context, interface{}) error // can send messages + Drop(error) // disconnect this peer + Run(func(context.Context, interface{}) error) error // the run function to run a protocol + Off() OverlayAddr +} + +// BzzConfig captures the config params used by the hive +type BzzConfig struct { + OverlayAddr []byte // base address of the overlay network + UnderlayAddr []byte // node's underlay address + HiveParams *HiveParams + NetworkID uint64 +} + +// Bzz is the swarm protocol bundle +type Bzz struct { + *Hive + NetworkID uint64 + localAddr *BzzAddr + mtx sync.Mutex + handshakes map[discover.NodeID]*HandshakeMsg + streamerSpec *protocols.Spec + streamerRun func(*BzzPeer) error +} + +// NewBzz is the swarm protocol constructor +// arguments +// * bzz config +// * overlay driver +// * peer store +func NewBzz(config *BzzConfig, kad Overlay, store state.Store, streamerSpec *protocols.Spec, streamerRun func(*BzzPeer) error) *Bzz { + return &Bzz{ + Hive: NewHive(config.HiveParams, kad, store), + NetworkID: config.NetworkID, + localAddr: &BzzAddr{config.OverlayAddr, config.UnderlayAddr}, + handshakes: make(map[discover.NodeID]*HandshakeMsg), + streamerRun: streamerRun, + streamerSpec: streamerSpec, } - if networkId == 0 { - networkId = NetworkId - } - return p2p.Protocol{ - Name: "bzz", - Version: Version, - Length: ProtocolLength, - Run: func(p *p2p.Peer, rw p2p.MsgReadWriter) error { - return run(requestDb, cloud, backend, hive, dbaccess, sp, sy, networkId, p, rw) +} + +// UpdateLocalAddr updates underlayaddress of the running node +func (b *Bzz) UpdateLocalAddr(byteaddr []byte) *BzzAddr { + b.localAddr = b.localAddr.Update(&BzzAddr{ + UAddr: byteaddr, + OAddr: b.localAddr.OAddr, + }).(*BzzAddr) + return b.localAddr +} + +// NodeInfo returns the node's overlay address +func (b *Bzz) NodeInfo() interface{} { + return b.localAddr.Address() +} + +// Protocols return the protocols swarm offers +// Bzz implements the node.Service interface +// * handshake/hive +// * discovery +func (b *Bzz) Protocols() []p2p.Protocol { + protocol := []p2p.Protocol{ + { + Name: BzzSpec.Name, + Version: BzzSpec.Version, + Length: BzzSpec.Length(), + Run: b.runBzz, + NodeInfo: b.NodeInfo, }, - }, nil + { + Name: DiscoverySpec.Name, + Version: DiscoverySpec.Version, + Length: DiscoverySpec.Length(), + Run: b.RunProtocol(DiscoverySpec, b.Hive.Run), + NodeInfo: b.Hive.NodeInfo, + PeerInfo: b.Hive.PeerInfo, + }, + } + if b.streamerSpec != nil && b.streamerRun != nil { + protocol = append(protocol, p2p.Protocol{ + Name: b.streamerSpec.Name, + Version: b.streamerSpec.Version, + Length: b.streamerSpec.Length(), + Run: b.RunProtocol(b.streamerSpec, b.streamerRun), + }) + } + return protocol } -/* -the main protocol loop that - * does the handshake by exchanging statusMsg - * if peer is valid and accepted, registers with the hive - * then enters into a forever loop handling incoming messages - * storage and retrieval related queries coming via bzz are dispatched to StorageHandler - * peer-related messages are dispatched to the hive - * payment related messages are relayed to SWAP service - * on disconnect, unregister the peer in the hive (note RemovePeer in the post-disconnect hook) - * whenever the loop terminates, the peer will disconnect with Subprotocol error - * whenever handlers return an error the loop terminates -*/ -func run(requestDb *storage.LDBDatabase, depo StorageHandler, backend chequebook.Backend, hive *Hive, dbaccess *DbAccess, sp *bzzswap.SwapParams, sy *SyncParams, networkId uint64, p *p2p.Peer, rw p2p.MsgReadWriter) (err error) { +// APIs returns the APIs offered by bzz +// * hive +// Bzz implements the node.Service interface +func (b *Bzz) APIs() []rpc.API { + return []rpc.API{{ + Namespace: "hive", + Version: "3.0", + Service: b.Hive, + }} +} - self := &bzz{ - storage: depo, - backend: backend, - hive: hive, - dbAccess: dbaccess, - requestDb: requestDb, - peer: p, - rw: rw, - swapParams: sp, - syncParams: sy, - swapEnabled: hive.swapEnabled, - syncEnabled: true, - NetworkId: networkId, +// RunProtocol is a wrapper for swarm subprotocols +// returns a p2p protocol run function that can be assigned to p2p.Protocol#Run field +// arguments: +// * p2p protocol spec +// * run function taking BzzPeer as argument +// this run function is meant to block for the duration of the protocol session +// on return the session is terminated and the peer is disconnected +// the protocol waits for the bzz handshake is negotiated +// the overlay address on the BzzPeer is set from the remote handshake +func (b *Bzz) RunProtocol(spec *protocols.Spec, run func(*BzzPeer) error) func(*p2p.Peer, p2p.MsgReadWriter) error { + return func(p *p2p.Peer, rw p2p.MsgReadWriter) error { + // wait for the bzz protocol to perform the handshake + handshake, _ := b.GetHandshake(p.ID()) + defer b.removeHandshake(p.ID()) + select { + case <-handshake.done: + case <-time.After(bzzHandshakeTimeout): + return fmt.Errorf("%08x: %s protocol timeout waiting for handshake on %08x", b.BaseAddr()[:4], spec.Name, p.ID().Bytes()[:4]) + } + if handshake.err != nil { + return fmt.Errorf("%08x: %s protocol closed: %v", b.BaseAddr()[:4], spec.Name, handshake.err) + } + // the handshake has succeeded so construct the BzzPeer and run the protocol + peer := &BzzPeer{ + Peer: protocols.NewPeer(p, rw, spec), + localAddr: b.localAddr, + BzzAddr: handshake.peerAddr, + lastActive: time.Now(), + } + return run(peer) } +} - // handle handshake - err = self.handleStatus() - if err != nil { - return err - } +// performHandshake implements the negotiation of the bzz handshake +// shared among swarm subprotocols +func (b *Bzz) performHandshake(p *protocols.Peer, handshake *HandshakeMsg) error { + ctx, cancel := context.WithTimeout(context.Background(), bzzHandshakeTimeout) defer func() { - // if the handler loop exits, the peer is disconnecting - // deregister the peer in the hive - self.hive.removePeer(&peer{bzz: self}) - if self.syncer != nil { - self.syncer.stop() // quits request db and delivery loops, save requests - } - if self.swap != nil { - self.swap.Stop() // quits chequebox autocash etc - } + close(handshake.done) + cancel() }() - - // the main forever loop that handles incoming requests - for { - if self.hive.blockRead { - log.Warn(fmt.Sprintf("Cannot read network")) - time.Sleep(100 * time.Millisecond) - continue - } - err = self.handle() - if err != nil { - return - } + rsh, err := p.Handshake(ctx, handshake, b.checkHandshake) + if err != nil { + handshake.err = err + return err } + handshake.peerAddr = rsh.(*HandshakeMsg).Addr + return nil } -// TODO: may need to implement protocol drop only? don't want to kick off the peer -// if they are useful for other protocols -func (self *bzz) Drop() { - self.peer.Disconnect(p2p.DiscSubprotocolError) -} +// runBzz is the p2p protocol run function for the bzz base protocol +// that negotiates the bzz handshake +func (b *Bzz) runBzz(p *p2p.Peer, rw p2p.MsgReadWriter) error { + handshake, _ := b.GetHandshake(p.ID()) + if !<-handshake.init { + return fmt.Errorf("%08x: bzz already started on peer %08x", b.localAddr.Over()[:4], ToOverlayAddr(p.ID().Bytes())[:4]) + } + close(handshake.init) + defer b.removeHandshake(p.ID()) + peer := protocols.NewPeer(p, rw, BzzSpec) + err := b.performHandshake(peer, handshake) + if err != nil { + log.Warn(fmt.Sprintf("%08x: handshake failed with remote peer %08x: %v", b.localAddr.Over()[:4], ToOverlayAddr(p.ID().Bytes())[:4], err)) -// one cycle of the main forever loop that handles and dispatches incoming messages -func (self *bzz) handle() error { - msg, err := self.rw.ReadMsg() - log.Debug(fmt.Sprintf("<- %v", msg)) + return err + } + // fail if we get another handshake + msg, err := rw.ReadMsg() if err != nil { return err } - if msg.Size > ProtocolMaxMsgSize { - return fmt.Errorf("message too long: %v > %v", msg.Size, ProtocolMaxMsgSize) + msg.Discard() + return errors.New("received multiple handshakes") +} + +// BzzPeer is the bzz protocol view of a protocols.Peer (itself an extension of p2p.Peer) +// implements the Peer interface and all interfaces Peer implements: Addr, OverlayPeer +type BzzPeer struct { + *protocols.Peer // represents the connection for online peers + localAddr *BzzAddr // local Peers address + *BzzAddr // remote address -> implements Addr interface = protocols.Peer + lastActive time.Time // time is updated whenever mutexes are releasing +} + +func NewBzzTestPeer(p *protocols.Peer, addr *BzzAddr) *BzzPeer { + return &BzzPeer{ + Peer: p, + localAddr: addr, + BzzAddr: NewAddrFromNodeID(p.ID()), } - // make sure that the payload has been fully consumed - defer msg.Discard() +} - switch msg.Code { +// Off returns the overlay peer record for offline persistence +func (p *BzzPeer) Off() OverlayAddr { + return p.BzzAddr +} - case statusMsg: - // no extra status message allowed. The one needed already handled by - // handleStatus - log.Debug(fmt.Sprintf("Status message: %v", msg)) - return errors.New("extra status message") +// LastActive returns the time the peer was last active +func (p *BzzPeer) LastActive() time.Time { + return p.lastActive +} - case storeRequestMsg: - // store requests are dispatched to netStore - storeRequestMsgCounter.Inc(1) - var req storeRequestMsgData - if err := msg.Decode(&req); err != nil { - return fmt.Errorf("<- %v: %v", msg, err) - } - if n := len(req.SData); n < 9 { - return fmt.Errorf("<- %v: Data too short (%v)", msg, n) - } - // last Active time is set only when receiving chunks - self.lastActive = time.Now() - log.Trace(fmt.Sprintf("incoming store request: %s", req.String())) - // swap accounting is done within forwarding - self.storage.HandleStoreRequestMsg(&req, &peer{bzz: self}) +/* + Handshake - case retrieveRequestMsg: - // retrieve Requests are dispatched to netStore - retrieveRequestMsgCounter.Inc(1) - var req retrieveRequestMsgData - if err := msg.Decode(&req); err != nil { - return fmt.Errorf("<- %v: %v", msg, err) - } - req.from = &peer{bzz: self} - // if request is lookup and not to be delivered - if req.isLookup() { - log.Trace(fmt.Sprintf("self lookup for %v: responding with peers only...", req.from)) - } else if req.Key == nil { - return fmt.Errorf("protocol handler: req.Key == nil || req.Timeout == nil") - } else { - // swap accounting is done within netStore - self.storage.HandleRetrieveRequestMsg(&req, &peer{bzz: self}) - } - // direct response with peers, TODO: sort this out - self.hive.peers(&req) +* Version: 8 byte integer version of the protocol +* NetworkID: 8 byte integer network identifier +* Addr: the address advertised by the node including underlay and overlay connecctions +*/ +type HandshakeMsg struct { + Version uint64 + NetworkID uint64 + Addr *BzzAddr - case peersMsg: - // response to lookups and immediate response to retrieve requests - // dispatches new peer data to the hive that adds them to KADDB - peersMsgCounter.Inc(1) - var req peersMsgData - if err := msg.Decode(&req); err != nil { - return fmt.Errorf("<- %v: %v", msg, err) - } - req.from = &peer{bzz: self} - log.Trace(fmt.Sprintf("<- peer addresses: %v", req)) - self.hive.HandlePeersMsg(&req, &peer{bzz: self}) + // peerAddr is the address received in the peer handshake + peerAddr *BzzAddr - case syncRequestMsg: - syncRequestMsgCounter.Inc(1) - var req syncRequestMsgData - if err := msg.Decode(&req); err != nil { - return fmt.Errorf("<- %v: %v", msg, err) - } - log.Debug(fmt.Sprintf("<- sync request: %v", req)) - self.lastActive = time.Now() - self.sync(req.SyncState) + init chan bool + done chan struct{} + err error +} - case unsyncedKeysMsg: - // coming from parent node offering - unsyncedKeysMsgCounter.Inc(1) - var req unsyncedKeysMsgData - if err := msg.Decode(&req); err != nil { - return fmt.Errorf("<- %v: %v", msg, err) - } - log.Debug(fmt.Sprintf("<- unsynced keys : %s", req.String())) - err := self.storage.HandleUnsyncedKeysMsg(&req, &peer{bzz: self}) - self.lastActive = time.Now() - if err != nil { - return fmt.Errorf("<- %v: %v", msg, err) - } +// String pretty prints the handshake +func (bh *HandshakeMsg) String() string { + return fmt.Sprintf("Handshake: Version: %v, NetworkID: %v, Addr: %v", bh.Version, bh.NetworkID, bh.Addr) +} - case deliveryRequestMsg: - // response to syncKeysMsg hashes filtered not existing in db - // also relays the last synced state to the source - deliverRequestMsgCounter.Inc(1) - var req deliveryRequestMsgData - if err := msg.Decode(&req); err != nil { - return fmt.Errorf("<-msg %v: %v", msg, err) - } - log.Debug(fmt.Sprintf("<- delivery request: %s", req.String())) - err := self.storage.HandleDeliveryRequestMsg(&req, &peer{bzz: self}) - self.lastActive = time.Now() - if err != nil { - return fmt.Errorf("<- %v: %v", msg, err) - } - - case paymentMsg: - // swap protocol message for payment, Units paid for, Cheque paid with - paymentMsgCounter.Inc(1) - if self.swapEnabled { - var req paymentMsgData - if err := msg.Decode(&req); err != nil { - return fmt.Errorf("<- %v: %v", msg, err) - } - log.Debug(fmt.Sprintf("<- payment: %s", req.String())) - self.swap.Receive(int(req.Units), req.Promise) - } - - default: - // no other message is allowed - invalidMsgCounter.Inc(1) - return fmt.Errorf("invalid message code: %v", msg.Code) +// Perform initiates the handshake and validates the remote handshake message +func (b *Bzz) checkHandshake(hs interface{}) error { + rhs := hs.(*HandshakeMsg) + if rhs.NetworkID != b.NetworkID { + return fmt.Errorf("network id mismatch %d (!= %d)", rhs.NetworkID, b.NetworkID) + } + if rhs.Version != uint64(BzzSpec.Version) { + return fmt.Errorf("version mismatch %d (!= %d)", rhs.Version, BzzSpec.Version) } return nil } -func (self *bzz) handleStatus() (err error) { +// removeHandshake removes handshake for peer with peerID +// from the bzz handshake store +func (b *Bzz) removeHandshake(peerID discover.NodeID) { + b.mtx.Lock() + defer b.mtx.Unlock() + delete(b.handshakes, peerID) +} - handshake := &statusMsgData{ - Version: uint64(Version), - ID: "honey", - Addr: self.selfAddr(), - NetworkId: self.NetworkId, - Swap: &bzzswap.SwapProfile{ - Profile: self.swapParams.Profile, - PayProfile: self.swapParams.PayProfile, - }, - } - - err = p2p.Send(self.rw, statusMsg, handshake) - if err != nil { - return err - } - - // read and handle remote status - var msg p2p.Msg - msg, err = self.rw.ReadMsg() - if err != nil { - return err - } - - if msg.Code != statusMsg { - return fmt.Errorf("first msg has code %x (!= %x)", msg.Code, statusMsg) - } - - handleStatusMsgCounter.Inc(1) - - if msg.Size > ProtocolMaxMsgSize { - return fmt.Errorf("message too long: %v > %v", msg.Size, ProtocolMaxMsgSize) - } - - var status statusMsgData - if err := msg.Decode(&status); err != nil { - return fmt.Errorf("<- %v: %v", msg, err) - } - - if status.NetworkId != self.NetworkId { - return fmt.Errorf("network id mismatch: %d (!= %d)", status.NetworkId, self.NetworkId) - } - - if Version != status.Version { - return fmt.Errorf("protocol version mismatch: %d (!= %d)", status.Version, Version) - } - - self.remoteAddr = self.peerAddr(status.Addr) - log.Trace(fmt.Sprintf("self: advertised IP: %v, peer advertised: %v, local address: %v\npeer: advertised IP: %v, remote address: %v\n", self.selfAddr(), self.remoteAddr, self.peer.LocalAddr(), status.Addr.IP, self.peer.RemoteAddr())) - - if self.swapEnabled { - // set remote profile for accounting - self.swap, err = bzzswap.NewSwap(self.swapParams, status.Swap, self.backend, self) - if err != nil { - return err +// GetHandshake returns the bzz handhake that the remote peer with peerID sent +func (b *Bzz) GetHandshake(peerID discover.NodeID) (*HandshakeMsg, bool) { + b.mtx.Lock() + defer b.mtx.Unlock() + handshake, found := b.handshakes[peerID] + if !found { + handshake = &HandshakeMsg{ + Version: uint64(BzzSpec.Version), + NetworkID: b.NetworkID, + Addr: b.localAddr, + init: make(chan bool, 1), + done: make(chan struct{}), } + // when handhsake is first created for a remote peer + // it is initialised with the init + handshake.init <- true + b.handshakes[peerID] = handshake } - log.Info(fmt.Sprintf("Peer %08x is capable (%d/%d)", self.remoteAddr.Addr[:4], status.Version, status.NetworkId)) - err = self.hive.addPeer(&peer{bzz: self}) + return handshake, found +} + +// BzzAddr implements the PeerAddr interface +type BzzAddr struct { + OAddr []byte + UAddr []byte +} + +// Address implements OverlayPeer interface to be used in Overlay +func (a *BzzAddr) Address() []byte { + return a.OAddr +} + +// Over returns the overlay address +func (a *BzzAddr) Over() []byte { + return a.OAddr +} + +// Under returns the underlay address +func (a *BzzAddr) Under() []byte { + return a.UAddr +} + +// ID returns the nodeID from the underlay enode address +func (a *BzzAddr) ID() discover.NodeID { + return discover.MustParseNode(string(a.UAddr)).ID +} + +// Update updates the underlay address of a peer record +func (a *BzzAddr) Update(na OverlayAddr) OverlayAddr { + return &BzzAddr{a.OAddr, na.(Addr).Under()} +} + +// String pretty prints the address +func (a *BzzAddr) String() string { + return fmt.Sprintf("%x <%s>", a.OAddr, a.UAddr) +} + +// RandomAddr is a utility method generating an address from a public key +func RandomAddr() *BzzAddr { + key, err := crypto.GenerateKey() if err != nil { - return err + panic("unable to generate key") } - - // hive sets syncstate so sync should start after node added - log.Info(fmt.Sprintf("syncronisation request sent with %v", self.syncState)) - self.syncRequest() - - return nil + pubkey := crypto.FromECDSAPub(&key.PublicKey) + var id discover.NodeID + copy(id[:], pubkey[1:]) + return NewAddrFromNodeID(id) } -func (self *bzz) sync(state *syncState) error { - // syncer setup - if self.syncer != nil { - return errors.New("sync request can only be sent once") +// NewNodeIDFromAddr transforms the underlay address to an adapters.NodeID +func NewNodeIDFromAddr(addr Addr) discover.NodeID { + log.Info(fmt.Sprintf("uaddr=%s", string(addr.Under()))) + node := discover.MustParseNode(string(addr.Under())) + return node.ID +} + +// NewAddrFromNodeID constucts a BzzAddr from a discover.NodeID +// the overlay address is derived as the hash of the nodeID +func NewAddrFromNodeID(id discover.NodeID) *BzzAddr { + return &BzzAddr{ + OAddr: ToOverlayAddr(id.Bytes()), + UAddr: []byte(discover.NewNode(id, net.IP{127, 0, 0, 1}, 30303, 30303).String()), } +} - cnt := self.dbAccess.counter() - remoteaddr := self.remoteAddr.Addr - start, stop := self.hive.kad.KeyRange(remoteaddr) - - // an explicitly received nil syncstate disables syncronisation - if state == nil { - self.syncEnabled = false - log.Warn(fmt.Sprintf("syncronisation disabled for peer %v", self)) - state = &syncState{DbSyncState: &storage.DbSyncState{}, Synced: true} - } else { - state.synced = make(chan bool) - state.SessionAt = cnt - if storage.IsZeroKey(state.Stop) && state.Synced { - state.Start = storage.Key(start[:]) - state.Stop = storage.Key(stop[:]) - } - log.Debug(fmt.Sprintf("syncronisation requested by peer %v at state %v", self, state)) +// NewAddrFromNodeIDAndPort constucts a BzzAddr from a discover.NodeID and port uint16 +// the overlay address is derived as the hash of the nodeID +func NewAddrFromNodeIDAndPort(id discover.NodeID, host net.IP, port uint16) *BzzAddr { + return &BzzAddr{ + OAddr: ToOverlayAddr(id.Bytes()), + UAddr: []byte(discover.NewNode(id, host, port, port).String()), } - var err error - self.syncer, err = newSyncer( - self.requestDb, - storage.Key(remoteaddr[:]), - self.dbAccess, - self.unsyncedKeys, self.store, - self.syncParams, state, func() bool { return self.syncEnabled }, - ) - if err != nil { - return nil - } - log.Trace(fmt.Sprintf("syncer set for peer %v", self)) - return nil } -func (self *bzz) String() string { - return self.remoteAddr.String() -} - -// repair reported address if IP missing -func (self *bzz) peerAddr(base *peerAddr) *peerAddr { - if base.IP.IsUnspecified() { - host, _, _ := net.SplitHostPort(self.peer.RemoteAddr().String()) - base.IP = net.ParseIP(host) - } - return base -} - -// returns self advertised node connection info (listening address w enodes) -// IP will get repaired on the other end if missing -// or resolved via ID by discovery at dialout -func (self *bzz) selfAddr() *peerAddr { - id := self.hive.id - host, port, _ := net.SplitHostPort(self.hive.listenAddr()) - intport, _ := strconv.Atoi(port) - addr := &peerAddr{ - Addr: self.hive.addr, - ID: id[:], - IP: net.ParseIP(host), - Port: uint16(intport), - } - return addr -} - -// outgoing messages -// send retrieveRequestMsg -func (self *bzz) retrieve(req *retrieveRequestMsgData) error { - return self.send(retrieveRequestMsg, req) -} - -// send storeRequestMsg -func (self *bzz) store(req *storeRequestMsgData) error { - return self.send(storeRequestMsg, req) -} - -func (self *bzz) syncRequest() error { - req := &syncRequestMsgData{} - if self.hive.syncEnabled { - log.Debug(fmt.Sprintf("syncronisation request to peer %v at state %v", self, self.syncState)) - req.SyncState = self.syncState - } - if self.syncState == nil { - log.Warn(fmt.Sprintf("syncronisation disabled for peer %v at state %v", self, self.syncState)) - } - return self.send(syncRequestMsg, req) -} - -// queue storeRequestMsg in request db -func (self *bzz) deliveryRequest(reqs []*syncRequest) error { - req := &deliveryRequestMsgData{ - Deliver: reqs, - } - return self.send(deliveryRequestMsg, req) -} - -// batch of syncRequests to send off -func (self *bzz) unsyncedKeys(reqs []*syncRequest, state *syncState) error { - req := &unsyncedKeysMsgData{ - Unsynced: reqs, - State: state, - } - return self.send(unsyncedKeysMsg, req) -} - -// send paymentMsg -func (self *bzz) Pay(units int, promise swap.Promise) { - req := &paymentMsgData{uint(units), promise.(*chequebook.Cheque)} - self.payment(req) -} - -// send paymentMsg -func (self *bzz) payment(req *paymentMsgData) error { - return self.send(paymentMsg, req) -} - -// sends peersMsg -func (self *bzz) peers(req *peersMsgData) error { - return self.send(peersMsg, req) -} - -func (self *bzz) send(msg uint64, data interface{}) error { - if self.hive.blockWrite { - return fmt.Errorf("network write blocked") - } - log.Trace(fmt.Sprintf("-> %v: %v (%T) to %v", msg, data, data, self)) - err := p2p.Send(self.rw, msg, data) - if err != nil { - self.Drop() - } - return err +// ToOverlayAddr creates an overlayaddress from a byte slice +func ToOverlayAddr(id []byte) []byte { + return crypto.Keccak256(id) } diff --git a/swarm/network/protocol_test.go b/swarm/network/protocol_test.go index 988d0ac923..63faf31088 100644 --- a/swarm/network/protocol_test.go +++ b/swarm/network/protocol_test.go @@ -1,4 +1,4 @@ -// Copyright 2014 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 @@ -15,3 +15,226 @@ // along with the go-ethereum library. If not, see . package network + +import ( + "flag" + "fmt" + "os" + "sync" + "testing" + + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/p2p" + "github.com/ethereum/go-ethereum/p2p/discover" + "github.com/ethereum/go-ethereum/p2p/protocols" + p2ptest "github.com/ethereum/go-ethereum/p2p/testing" +) + +var ( + loglevel = flag.Int("loglevel", 2, "verbosity of logs") +) + +func init() { + flag.Parse() + log.Root().SetHandler(log.LvlFilterHandler(log.Lvl(*loglevel), log.StreamHandler(os.Stderr, log.TerminalFormat(true)))) +} + +type testStore struct { + sync.Mutex + + values map[string][]byte +} + +func newTestStore() *testStore { + return &testStore{values: make(map[string][]byte)} +} + +func (t *testStore) Load(key string) ([]byte, error) { + t.Lock() + defer t.Unlock() + v, ok := t.values[key] + if !ok { + return nil, fmt.Errorf("key not found: %s", key) + } + return v, nil +} + +func (t *testStore) Save(key string, v []byte) error { + t.Lock() + defer t.Unlock() + t.values[key] = v + return nil +} + +func HandshakeMsgExchange(lhs, rhs *HandshakeMsg, id discover.NodeID) []p2ptest.Exchange { + + return []p2ptest.Exchange{ + { + Expects: []p2ptest.Expect{ + { + Code: 0, + Msg: lhs, + Peer: id, + }, + }, + }, + { + Triggers: []p2ptest.Trigger{ + { + Code: 0, + Msg: rhs, + Peer: id, + }, + }, + }, + } +} + +func newBzzBaseTester(t *testing.T, n int, addr *BzzAddr, spec *protocols.Spec, run func(*BzzPeer) error) *bzzTester { + cs := make(map[string]chan bool) + + srv := func(p *BzzPeer) error { + defer func() { + if cs[p.ID().String()] != nil { + close(cs[p.ID().String()]) + } + }() + return run(p) + } + + protocol := func(p *p2p.Peer, rw p2p.MsgReadWriter) error { + return srv(&BzzPeer{ + Peer: protocols.NewPeer(p, rw, spec), + localAddr: addr, + BzzAddr: NewAddrFromNodeID(p.ID()), + }) + } + + s := p2ptest.NewProtocolTester(t, NewNodeIDFromAddr(addr), n, protocol) + + for _, id := range s.IDs { + cs[id.String()] = make(chan bool) + } + + return &bzzTester{ + addr: addr, + ProtocolTester: s, + cs: cs, + } +} + +type bzzTester struct { + *p2ptest.ProtocolTester + addr *BzzAddr + cs map[string]chan bool +} + +func newBzzHandshakeTester(t *testing.T, n int, addr *BzzAddr) *bzzTester { + config := &BzzConfig{ + OverlayAddr: addr.Over(), + UnderlayAddr: addr.Under(), + HiveParams: NewHiveParams(), + NetworkID: DefaultNetworkID, + } + kad := NewKademlia(addr.OAddr, NewKadParams()) + bzz := NewBzz(config, kad, nil, nil, nil) + + s := p2ptest.NewProtocolTester(t, NewNodeIDFromAddr(addr), 1, bzz.runBzz) + + return &bzzTester{ + addr: addr, + ProtocolTester: s, + } +} + +// should test handshakes in one exchange? parallelisation +func (s *bzzTester) testHandshake(lhs, rhs *HandshakeMsg, disconnects ...*p2ptest.Disconnect) error { + var peers []discover.NodeID + id := NewNodeIDFromAddr(rhs.Addr) + if len(disconnects) > 0 { + for _, d := range disconnects { + peers = append(peers, d.Peer) + } + } else { + peers = []discover.NodeID{id} + } + + if err := s.TestExchanges(HandshakeMsgExchange(lhs, rhs, id)...); err != nil { + return err + } + + if len(disconnects) > 0 { + return s.TestDisconnected(disconnects...) + } + + // If we don't expect disconnect, ensure peers remain connected + err := s.TestDisconnected(&p2ptest.Disconnect{ + Peer: s.IDs[0], + Error: nil, + }) + + if err == nil { + return fmt.Errorf("Unexpected peer disconnect") + } + + if err.Error() != "timed out waiting for peers to disconnect" { + return err + } + + return nil +} + +func correctBzzHandshake(addr *BzzAddr) *HandshakeMsg { + return &HandshakeMsg{ + Version: 5, + NetworkID: DefaultNetworkID, + Addr: addr, + } +} + +func TestBzzHandshakeNetworkIDMismatch(t *testing.T) { + addr := RandomAddr() + s := newBzzHandshakeTester(t, 1, addr) + id := s.IDs[0] + + err := s.testHandshake( + correctBzzHandshake(addr), + &HandshakeMsg{Version: 5, NetworkID: 321, Addr: NewAddrFromNodeID(id)}, + &p2ptest.Disconnect{Peer: id, Error: fmt.Errorf("Handshake error: Message handler error: (msg code 0): network id mismatch 321 (!= 3)")}, + ) + + if err != nil { + t.Fatal(err) + } +} + +func TestBzzHandshakeVersionMismatch(t *testing.T) { + addr := RandomAddr() + s := newBzzHandshakeTester(t, 1, addr) + id := s.IDs[0] + + err := s.testHandshake( + correctBzzHandshake(addr), + &HandshakeMsg{Version: 0, NetworkID: 3, Addr: NewAddrFromNodeID(id)}, + &p2ptest.Disconnect{Peer: id, Error: fmt.Errorf("Handshake error: Message handler error: (msg code 0): version mismatch 0 (!= 5)")}, + ) + + if err != nil { + t.Fatal(err) + } +} + +func TestBzzHandshakeSuccess(t *testing.T) { + addr := RandomAddr() + s := newBzzHandshakeTester(t, 1, addr) + id := s.IDs[0] + + err := s.testHandshake( + correctBzzHandshake(addr), + &HandshakeMsg{Version: 5, NetworkID: 3, Addr: NewAddrFromNodeID(id)}, + ) + + if err != nil { + t.Fatal(err) + } +} diff --git a/swarm/network/simulation/bucket.go b/swarm/network/simulation/bucket.go new file mode 100644 index 0000000000..ddbedb5210 --- /dev/null +++ b/swarm/network/simulation/bucket.go @@ -0,0 +1,81 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package simulation + +import ( + "github.com/ethereum/go-ethereum/p2p/discover" +) + +// BucketKey is the type that should be used for keys in simulation buckets. +type BucketKey string + +// NodeItem returns an item set in ServiceFunc function for a particualar node. +func (s *Simulation) NodeItem(id discover.NodeID, key interface{}) (value interface{}, ok bool) { + s.mu.Lock() + defer s.mu.Unlock() + + if _, ok := s.buckets[id]; !ok { + return nil, false + } + return s.buckets[id].Load(key) +} + +// SetNodeItem sets a new item associated with the node with provided NodeID. +// Buckets should be used to avoid managing separate simulation global state. +func (s *Simulation) SetNodeItem(id discover.NodeID, key interface{}, value interface{}) { + s.mu.Lock() + defer s.mu.Unlock() + + s.buckets[id].Store(key, value) +} + +// NodesItems returns a map of items from all nodes that are all set under the +// same BucketKey. +func (s *Simulation) NodesItems(key interface{}) (values map[discover.NodeID]interface{}) { + s.mu.RLock() + defer s.mu.RUnlock() + + ids := s.NodeIDs() + values = make(map[discover.NodeID]interface{}, len(ids)) + for _, id := range ids { + if _, ok := s.buckets[id]; !ok { + continue + } + if v, ok := s.buckets[id].Load(key); ok { + values[id] = v + } + } + return values +} + +// UpNodesItems returns a map of items with the same BucketKey from all nodes that are up. +func (s *Simulation) UpNodesItems(key interface{}) (values map[discover.NodeID]interface{}) { + s.mu.RLock() + defer s.mu.RUnlock() + + ids := s.UpNodeIDs() + values = make(map[discover.NodeID]interface{}) + for _, id := range ids { + if _, ok := s.buckets[id]; !ok { + continue + } + if v, ok := s.buckets[id].Load(key); ok { + values[id] = v + } + } + return values +} diff --git a/swarm/network/simulation/bucket_test.go b/swarm/network/simulation/bucket_test.go new file mode 100644 index 0000000000..461d99825c --- /dev/null +++ b/swarm/network/simulation/bucket_test.go @@ -0,0 +1,155 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package simulation + +import ( + "sync" + "testing" + + "github.com/ethereum/go-ethereum/node" + "github.com/ethereum/go-ethereum/p2p/simulations/adapters" +) + +// TestServiceBucket tests all bucket functionalities using subtests. +// It constructs a simulation of two nodes by adding items to their buckets +// in ServiceFunc constructor, then by SetNodeItem. Testing UpNodesItems +// is done by stopping one node and validating availability of its items. +func TestServiceBucket(t *testing.T) { + testKey := "Key" + testValue := "Value" + + sim := New(map[string]ServiceFunc{ + "noop": func(ctx *adapters.ServiceContext, b *sync.Map) (node.Service, func(), error) { + b.Store(testKey, testValue+ctx.Config.ID.String()) + return newNoopService(), nil, nil + }, + }) + defer sim.Close() + + id1, err := sim.AddNode() + if err != nil { + t.Fatal(err) + } + + id2, err := sim.AddNode() + if err != nil { + t.Fatal(err) + } + + t.Run("ServiceFunc bucket Store", func(t *testing.T) { + v, ok := sim.NodeItem(id1, testKey) + if !ok { + t.Fatal("bucket item not found") + } + s, ok := v.(string) + if !ok { + t.Fatal("bucket item value is not string") + } + if s != testValue+id1.String() { + t.Fatalf("expected %q, got %q", testValue+id1.String(), s) + } + + v, ok = sim.NodeItem(id2, testKey) + if !ok { + t.Fatal("bucket item not found") + } + s, ok = v.(string) + if !ok { + t.Fatal("bucket item value is not string") + } + if s != testValue+id2.String() { + t.Fatalf("expected %q, got %q", testValue+id2.String(), s) + } + }) + + customKey := "anotherKey" + customValue := "anotherValue" + + t.Run("SetNodeItem", func(t *testing.T) { + sim.SetNodeItem(id1, customKey, customValue) + + v, ok := sim.NodeItem(id1, customKey) + if !ok { + t.Fatal("bucket item not found") + } + s, ok := v.(string) + if !ok { + t.Fatal("bucket item value is not string") + } + if s != customValue { + t.Fatalf("expected %q, got %q", customValue, s) + } + + v, ok = sim.NodeItem(id2, customKey) + if ok { + t.Fatal("bucket item should not be found") + } + }) + + if err := sim.StopNode(id2); err != nil { + t.Fatal(err) + } + + t.Run("UpNodesItems", func(t *testing.T) { + items := sim.UpNodesItems(testKey) + + v, ok := items[id1] + if !ok { + t.Errorf("node 1 item not found") + } + s, ok := v.(string) + if !ok { + t.Fatal("node 1 item value is not string") + } + if s != testValue+id1.String() { + t.Fatalf("expected %q, got %q", testValue+id1.String(), s) + } + + v, ok = items[id2] + if ok { + t.Errorf("node 2 item should not be found") + } + }) + + t.Run("NodeItems", func(t *testing.T) { + items := sim.NodesItems(testKey) + + v, ok := items[id1] + if !ok { + t.Errorf("node 1 item not found") + } + s, ok := v.(string) + if !ok { + t.Fatal("node 1 item value is not string") + } + if s != testValue+id1.String() { + t.Fatalf("expected %q, got %q", testValue+id1.String(), s) + } + + v, ok = items[id2] + if !ok { + t.Errorf("node 2 item not found") + } + s, ok = v.(string) + if !ok { + t.Fatal("node 1 item value is not string") + } + if s != testValue+id2.String() { + t.Fatalf("expected %q, got %q", testValue+id2.String(), s) + } + }) +} diff --git a/swarm/network/simulation/connect.go b/swarm/network/simulation/connect.go new file mode 100644 index 0000000000..3d0f6cb3fc --- /dev/null +++ b/swarm/network/simulation/connect.go @@ -0,0 +1,159 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package simulation + +import ( + "strings" + + "github.com/ethereum/go-ethereum/p2p/discover" +) + +// ConnectToPivotNode connects the node with provided NodeID +// to the pivot node, already set by Simulation.SetPivotNode method. +// It is useful when constructing a star network topology +// when simulation adds and removes nodes dynamically. +func (s *Simulation) ConnectToPivotNode(id discover.NodeID) (err error) { + pid := s.PivotNodeID() + if pid == nil { + return ErrNoPivotNode + } + return s.connect(*pid, id) +} + +// ConnectToLastNode connects the node with provided NodeID +// to the last node that is up, and avoiding connection to self. +// It is useful when constructing a chain network topology +// when simulation adds and removes nodes dynamically. +func (s *Simulation) ConnectToLastNode(id discover.NodeID) (err error) { + ids := s.UpNodeIDs() + l := len(ids) + if l < 2 { + return nil + } + lid := ids[l-1] + if lid == id { + lid = ids[l-2] + } + return s.connect(lid, id) +} + +// ConnectToRandomNode connects the node with provieded NodeID +// to a random node that is up. +func (s *Simulation) ConnectToRandomNode(id discover.NodeID) (err error) { + n := s.RandomUpNode(id) + if n == nil { + return ErrNodeNotFound + } + return s.connect(n.ID, id) +} + +// ConnectNodesFull connects all nodes one to another. +// It provides a complete connectivity in the network +// which should be rarely needed. +func (s *Simulation) ConnectNodesFull(ids []discover.NodeID) (err error) { + if ids == nil { + ids = s.UpNodeIDs() + } + l := len(ids) + for i := 0; i < l; i++ { + for j := i + 1; j < l; j++ { + err = s.connect(ids[i], ids[j]) + if err != nil { + return err + } + } + } + return nil +} + +// ConnectNodesChain connects all nodes in a chain topology. +// If ids argument is nil, all nodes that are up will be connected. +func (s *Simulation) ConnectNodesChain(ids []discover.NodeID) (err error) { + if ids == nil { + ids = s.UpNodeIDs() + } + l := len(ids) + for i := 0; i < l-1; i++ { + err = s.connect(ids[i], ids[i+1]) + if err != nil { + return err + } + } + return nil +} + +// ConnectNodesRing connects all nodes in a ring topology. +// If ids argument is nil, all nodes that are up will be connected. +func (s *Simulation) ConnectNodesRing(ids []discover.NodeID) (err error) { + if ids == nil { + ids = s.UpNodeIDs() + } + l := len(ids) + if l < 2 { + return nil + } + for i := 0; i < l-1; i++ { + err = s.connect(ids[i], ids[i+1]) + if err != nil { + return err + } + } + return s.connect(ids[l-1], ids[0]) +} + +// ConnectNodesStar connects all nodes in a star topology +// with the center at provided NodeID. +// If ids argument is nil, all nodes that are up will be connected. +func (s *Simulation) ConnectNodesStar(id discover.NodeID, ids []discover.NodeID) (err error) { + if ids == nil { + ids = s.UpNodeIDs() + } + l := len(ids) + for i := 0; i < l; i++ { + if id == ids[i] { + continue + } + err = s.connect(id, ids[i]) + if err != nil { + return err + } + } + return nil +} + +// ConnectNodesStarPivot connects all nodes in a star topology +// with the center at already set pivot node. +// If ids argument is nil, all nodes that are up will be connected. +func (s *Simulation) ConnectNodesStarPivot(ids []discover.NodeID) (err error) { + id := s.PivotNodeID() + if id == nil { + return ErrNoPivotNode + } + return s.ConnectNodesStar(*id, ids) +} + +// connect connects two nodes but ignores already connected error. +func (s *Simulation) connect(oneID, otherID discover.NodeID) error { + return ignoreAlreadyConnectedErr(s.Net.Connect(oneID, otherID)) +} + +func ignoreAlreadyConnectedErr(err error) error { + if err == nil || strings.Contains(err.Error(), "already connected") { + return nil + } + return err +} diff --git a/swarm/network/simulation/connect_test.go b/swarm/network/simulation/connect_test.go new file mode 100644 index 0000000000..10d73e4a1c --- /dev/null +++ b/swarm/network/simulation/connect_test.go @@ -0,0 +1,306 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package simulation + +import ( + "testing" + + "github.com/ethereum/go-ethereum/p2p/discover" +) + +func TestConnectToPivotNode(t *testing.T) { + sim := New(noopServiceFuncMap) + defer sim.Close() + + pid, err := sim.AddNode() + if err != nil { + t.Fatal(err) + } + + sim.SetPivotNode(pid) + + id, err := sim.AddNode() + if err != nil { + t.Fatal(err) + } + + if len(sim.Net.Conns) > 0 { + t.Fatal("no connections should exist after just adding nodes") + } + + err = sim.ConnectToPivotNode(id) + if err != nil { + t.Fatal(err) + } + + if sim.Net.GetConn(id, pid) == nil { + t.Error("node did not connect to pivot node") + } +} + +func TestConnectToLastNode(t *testing.T) { + sim := New(noopServiceFuncMap) + defer sim.Close() + + n := 10 + + ids, err := sim.AddNodes(n) + if err != nil { + t.Fatal(err) + } + + id, err := sim.AddNode() + if err != nil { + t.Fatal(err) + } + + if len(sim.Net.Conns) > 0 { + t.Fatal("no connections should exist after just adding nodes") + } + + err = sim.ConnectToLastNode(id) + if err != nil { + t.Fatal(err) + } + + for _, i := range ids[:n-2] { + if sim.Net.GetConn(id, i) != nil { + t.Error("node connected to the node that is not the last") + } + } + + if sim.Net.GetConn(id, ids[n-1]) == nil { + t.Error("node did not connect to the last node") + } +} + +func TestConnectToRandomNode(t *testing.T) { + sim := New(noopServiceFuncMap) + defer sim.Close() + + n := 10 + + ids, err := sim.AddNodes(n) + if err != nil { + t.Fatal(err) + } + + if len(sim.Net.Conns) > 0 { + t.Fatal("no connections should exist after just adding nodes") + } + + err = sim.ConnectToRandomNode(ids[0]) + if err != nil { + t.Fatal(err) + } + + var cc int + for i := 0; i < n; i++ { + for j := i + 1; j < n; j++ { + if sim.Net.GetConn(ids[i], ids[j]) != nil { + cc++ + } + } + } + + if cc != 1 { + t.Errorf("expected one connection, got %v", cc) + } +} + +func TestConnectNodesFull(t *testing.T) { + sim := New(noopServiceFuncMap) + defer sim.Close() + + ids, err := sim.AddNodes(12) + if err != nil { + t.Fatal(err) + } + + if len(sim.Net.Conns) > 0 { + t.Fatal("no connections should exist after just adding nodes") + } + + err = sim.ConnectNodesFull(ids) + if err != nil { + t.Fatal(err) + } + + testFull(t, sim, ids) +} + +func testFull(t *testing.T, sim *Simulation, ids []discover.NodeID) { + n := len(ids) + var cc int + for i := 0; i < n; i++ { + for j := i + 1; j < n; j++ { + if sim.Net.GetConn(ids[i], ids[j]) != nil { + cc++ + } + } + } + + want := n * (n - 1) / 2 + + if cc != want { + t.Errorf("expected %v connection, got %v", want, cc) + } +} + +func TestConnectNodesChain(t *testing.T) { + sim := New(noopServiceFuncMap) + defer sim.Close() + + ids, err := sim.AddNodes(10) + if err != nil { + t.Fatal(err) + } + + if len(sim.Net.Conns) > 0 { + t.Fatal("no connections should exist after just adding nodes") + } + + err = sim.ConnectNodesChain(ids) + if err != nil { + t.Fatal(err) + } + + testChain(t, sim, ids) +} + +func testChain(t *testing.T, sim *Simulation, ids []discover.NodeID) { + n := len(ids) + for i := 0; i < n; i++ { + for j := i + 1; j < n; j++ { + c := sim.Net.GetConn(ids[i], ids[j]) + if i == j-1 { + if c == nil { + t.Errorf("nodes %v and %v are not connected, but they should be", i, j) + } + } else { + if c != nil { + t.Errorf("nodes %v and %v are connected, but they should not be", i, j) + } + } + } + } +} + +func TestConnectNodesRing(t *testing.T) { + sim := New(noopServiceFuncMap) + defer sim.Close() + + ids, err := sim.AddNodes(10) + if err != nil { + t.Fatal(err) + } + + if len(sim.Net.Conns) > 0 { + t.Fatal("no connections should exist after just adding nodes") + } + + err = sim.ConnectNodesRing(ids) + if err != nil { + t.Fatal(err) + } + + testRing(t, sim, ids) +} + +func testRing(t *testing.T, sim *Simulation, ids []discover.NodeID) { + n := len(ids) + for i := 0; i < n; i++ { + for j := i + 1; j < n; j++ { + c := sim.Net.GetConn(ids[i], ids[j]) + if i == j-1 || (i == 0 && j == n-1) { + if c == nil { + t.Errorf("nodes %v and %v are not connected, but they should be", i, j) + } + } else { + if c != nil { + t.Errorf("nodes %v and %v are connected, but they should not be", i, j) + } + } + } + } +} + +func TestConnectToNodesStar(t *testing.T) { + sim := New(noopServiceFuncMap) + defer sim.Close() + + ids, err := sim.AddNodes(10) + if err != nil { + t.Fatal(err) + } + + if len(sim.Net.Conns) > 0 { + t.Fatal("no connections should exist after just adding nodes") + } + + centerIndex := 2 + + err = sim.ConnectNodesStar(ids[centerIndex], ids) + if err != nil { + t.Fatal(err) + } + + testStar(t, sim, ids, centerIndex) +} + +func testStar(t *testing.T, sim *Simulation, ids []discover.NodeID, centerIndex int) { + n := len(ids) + for i := 0; i < n; i++ { + for j := i + 1; j < n; j++ { + c := sim.Net.GetConn(ids[i], ids[j]) + if i == centerIndex || j == centerIndex { + if c == nil { + t.Errorf("nodes %v and %v are not connected, but they should be", i, j) + } + } else { + if c != nil { + t.Errorf("nodes %v and %v are connected, but they should not be", i, j) + } + } + } + } +} + +func TestConnectToNodesStarPivot(t *testing.T) { + sim := New(noopServiceFuncMap) + defer sim.Close() + + ids, err := sim.AddNodes(10) + if err != nil { + t.Fatal(err) + } + + if len(sim.Net.Conns) > 0 { + t.Fatal("no connections should exist after just adding nodes") + } + + pivotIndex := 4 + + sim.SetPivotNode(ids[pivotIndex]) + + err = sim.ConnectNodesStarPivot(ids) + if err != nil { + t.Fatal(err) + } + + testStar(t, sim, ids, pivotIndex) +} diff --git a/swarm/network/simulation/events.go b/swarm/network/simulation/events.go new file mode 100644 index 0000000000..980a9a7564 --- /dev/null +++ b/swarm/network/simulation/events.go @@ -0,0 +1,168 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package simulation + +import ( + "context" + "sync" + + "github.com/ethereum/go-ethereum/p2p/discover" + + "github.com/ethereum/go-ethereum/p2p" +) + +// PeerEvent is the type of the channel returned by Simulation.PeerEvents. +type PeerEvent struct { + // NodeID is the ID of node that the event is caught on. + NodeID discover.NodeID + // Event is the event that is caught. + Event *p2p.PeerEvent + // Error is the error that may have happened during event watching. + Error error +} + +// PeerEventsFilter defines a filter on PeerEvents to exclude messages with +// defined properties. Use PeerEventsFilter methods to set required options. +type PeerEventsFilter struct { + t *p2p.PeerEventType + protocol *string + msgCode *uint64 +} + +// NewPeerEventsFilter returns a new PeerEventsFilter instance. +func NewPeerEventsFilter() *PeerEventsFilter { + return &PeerEventsFilter{} +} + +// Type sets the filter to only one peer event type. +func (f *PeerEventsFilter) Type(t p2p.PeerEventType) *PeerEventsFilter { + f.t = &t + return f +} + +// Protocol sets the filter to only one message protocol. +func (f *PeerEventsFilter) Protocol(p string) *PeerEventsFilter { + f.protocol = &p + return f +} + +// MsgCode sets the filter to only one msg code. +func (f *PeerEventsFilter) MsgCode(c uint64) *PeerEventsFilter { + f.msgCode = &c + return f +} + +// PeerEvents returns a channel of events that are captured by admin peerEvents +// subscription nodes with provided NodeIDs. Additional filters can be set to ignore +// events that are not relevant. +func (s *Simulation) PeerEvents(ctx context.Context, ids []discover.NodeID, filters ...*PeerEventsFilter) <-chan PeerEvent { + eventC := make(chan PeerEvent) + + // wait group to make sure all subscriptions to admin peerEvents are established + // before this function returns. + var subsWG sync.WaitGroup + for _, id := range ids { + s.shutdownWG.Add(1) + subsWG.Add(1) + go func(id discover.NodeID) { + defer s.shutdownWG.Done() + + client, err := s.Net.GetNode(id).Client() + if err != nil { + subsWG.Done() + eventC <- PeerEvent{NodeID: id, Error: err} + return + } + events := make(chan *p2p.PeerEvent) + sub, err := client.Subscribe(ctx, "admin", events, "peerEvents") + if err != nil { + subsWG.Done() + eventC <- PeerEvent{NodeID: id, Error: err} + return + } + defer sub.Unsubscribe() + + subsWG.Done() + + for { + select { + case <-ctx.Done(): + if err := ctx.Err(); err != nil { + select { + case eventC <- PeerEvent{NodeID: id, Error: err}: + case <-s.Done(): + } + } + return + case <-s.Done(): + return + case e := <-events: + match := len(filters) == 0 // if there are no filters match all events + for _, f := range filters { + if f.t != nil && *f.t != e.Type { + continue + } + if f.protocol != nil && *f.protocol != e.Protocol { + continue + } + if f.msgCode != nil && e.MsgCode != nil && *f.msgCode != *e.MsgCode { + continue + } + // all filter parameters matched, break the loop + match = true + break + } + if match { + select { + case eventC <- PeerEvent{NodeID: id, Event: e}: + case <-ctx.Done(): + if err := ctx.Err(); err != nil { + select { + case eventC <- PeerEvent{NodeID: id, Error: err}: + case <-s.Done(): + } + } + return + case <-s.Done(): + return + } + } + case err := <-sub.Err(): + if err != nil { + select { + case eventC <- PeerEvent{NodeID: id, Error: err}: + case <-ctx.Done(): + if err := ctx.Err(); err != nil { + select { + case eventC <- PeerEvent{NodeID: id, Error: err}: + case <-s.Done(): + } + } + return + case <-s.Done(): + return + } + } + } + } + }(id) + } + + // wait all subscriptions + subsWG.Wait() + return eventC +} diff --git a/swarm/network/simulation/events_test.go b/swarm/network/simulation/events_test.go new file mode 100644 index 0000000000..0c185d9774 --- /dev/null +++ b/swarm/network/simulation/events_test.go @@ -0,0 +1,104 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package simulation + +import ( + "context" + "sync" + "testing" + "time" +) + +// TestPeerEvents creates simulation, adds two nodes, +// register for peer events, connects nodes in a chain +// and waits for the number of connection events to +// be received. +func TestPeerEvents(t *testing.T) { + sim := New(noopServiceFuncMap) + defer sim.Close() + + _, err := sim.AddNodes(2) + if err != nil { + t.Fatal(err) + } + + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + events := sim.PeerEvents(ctx, sim.NodeIDs()) + + // two nodes -> two connection events + expectedEventCount := 2 + + var wg sync.WaitGroup + wg.Add(expectedEventCount) + + go func() { + for e := range events { + if e.Error != nil { + if e.Error == context.Canceled { + return + } + t.Error(e.Error) + continue + } + wg.Done() + } + }() + + err = sim.ConnectNodesChain(sim.NodeIDs()) + if err != nil { + t.Fatal(err) + } + + wg.Wait() +} + +func TestPeerEventsTimeout(t *testing.T) { + sim := New(noopServiceFuncMap) + defer sim.Close() + + _, err := sim.AddNodes(2) + if err != nil { + t.Fatal(err) + } + + ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond) + defer cancel() + events := sim.PeerEvents(ctx, sim.NodeIDs()) + + done := make(chan struct{}) + go func() { + for e := range events { + if e.Error == context.Canceled { + return + } + if e.Error == context.DeadlineExceeded { + close(done) + return + } else { + t.Fatal(e.Error) + } + } + }() + + select { + case <-time.After(time.Second): + t.Error("no context deadline received") + case <-done: + // all good, context deadline detected + } +} diff --git a/swarm/network/simulation/example_test.go b/swarm/network/simulation/example_test.go new file mode 100644 index 0000000000..2a8116921a --- /dev/null +++ b/swarm/network/simulation/example_test.go @@ -0,0 +1,140 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package simulation_test + +import ( + "context" + "fmt" + "sync" + "time" + + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/node" + "github.com/ethereum/go-ethereum/p2p" + "github.com/ethereum/go-ethereum/p2p/simulations/adapters" + "github.com/ethereum/go-ethereum/swarm/network" + "github.com/ethereum/go-ethereum/swarm/network/simulation" +) + +// Every node can have a Kademlia associated using the node bucket under +// BucketKeyKademlia key. This allows to use WaitTillHealthy to block until +// all nodes have the their Kadmlias healthy. +func ExampleSimulation_WaitTillHealthy() { + sim := simulation.New(map[string]simulation.ServiceFunc{ + "bzz": func(ctx *adapters.ServiceContext, b *sync.Map) (node.Service, func(), error) { + addr := network.NewAddrFromNodeID(ctx.Config.ID) + hp := network.NewHiveParams() + hp.Discovery = false + config := &network.BzzConfig{ + OverlayAddr: addr.Over(), + UnderlayAddr: addr.Under(), + HiveParams: hp, + } + kad := network.NewKademlia(addr.Over(), network.NewKadParams()) + // store kademlia in node's bucket under BucketKeyKademlia + // so that it can be found by WaitTillHealthy method. + b.Store(simulation.BucketKeyKademlia, kad) + return network.NewBzz(config, kad, nil, nil, nil), nil, nil + }, + }) + defer sim.Close() + + _, err := sim.AddNodesAndConnectRing(10) + if err != nil { + // handle error properly... + panic(err) + } + + ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second) + defer cancel() + ill, err := sim.WaitTillHealthy(ctx, 2) + if err != nil { + // inspect the latest detected not healthy kademlias + for id, kad := range ill { + fmt.Println("Node", id) + fmt.Println(kad.String()) + } + // handle error... + } + + // continue with the test +} + +// Watch all peer events in the simulation network, buy receiving from a channel. +func ExampleSimulation_PeerEvents() { + sim := simulation.New(nil) + defer sim.Close() + + events := sim.PeerEvents(context.Background(), sim.NodeIDs()) + + go func() { + for e := range events { + if e.Error != nil { + log.Error("peer event", "err", e.Error) + continue + } + log.Info("peer event", "node", e.NodeID, "peer", e.Event.Peer, "msgcode", e.Event.MsgCode) + } + }() +} + +// Detect when a nodes drop a peer. +func ExampleSimulation_PeerEvents_disconnections() { + sim := simulation.New(nil) + defer sim.Close() + + disconnections := sim.PeerEvents( + context.Background(), + sim.NodeIDs(), + simulation.NewPeerEventsFilter().Type(p2p.PeerEventTypeDrop), + ) + + go func() { + for d := range disconnections { + if d.Error != nil { + log.Error("peer drop", "err", d.Error) + continue + } + log.Warn("peer drop", "node", d.NodeID, "peer", d.Event.Peer) + } + }() +} + +// Watch multiple types of events or messages. In this case, they differ only +// by MsgCode, but filters can be set for different types or protocols, too. +func ExampleSimulation_PeerEvents_multipleFilters() { + sim := simulation.New(nil) + defer sim.Close() + + msgs := sim.PeerEvents( + context.Background(), + sim.NodeIDs(), + // Watch when bzz messages 1 and 4 are received. + simulation.NewPeerEventsFilter().Type(p2p.PeerEventTypeMsgRecv).Protocol("bzz").MsgCode(1), + simulation.NewPeerEventsFilter().Type(p2p.PeerEventTypeMsgRecv).Protocol("bzz").MsgCode(4), + ) + + go func() { + for m := range msgs { + if m.Error != nil { + log.Error("bzz message", "err", m.Error) + continue + } + log.Info("bzz message", "node", m.NodeID, "peer", m.Event.Peer) + } + }() +} diff --git a/swarm/network/simulation/http.go b/swarm/network/simulation/http.go new file mode 100644 index 0000000000..69ae3baec2 --- /dev/null +++ b/swarm/network/simulation/http.go @@ -0,0 +1,68 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package simulation + +import ( + "fmt" + "net/http" + + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/p2p/simulations" +) + +// Package defaults. +var ( + DefaultHTTPSimAddr = ":8888" +) + +//WithServer implements the builder pattern constructor for Simulation to +//start with a HTTP server +func (s *Simulation) WithServer(addr string) *Simulation { + //assign default addr if nothing provided + if addr == "" { + addr = DefaultHTTPSimAddr + } + log.Info(fmt.Sprintf("Initializing simulation server on %s...", addr)) + //initialize the HTTP server + s.handler = simulations.NewServer(s.Net) + s.runC = make(chan struct{}) + //add swarm specific routes to the HTTP server + s.addSimulationRoutes() + s.httpSrv = &http.Server{ + Addr: addr, + Handler: s.handler, + } + go func() { + err := s.httpSrv.ListenAndServe() + if err != nil { + log.Error("Error starting the HTTP server", "error", err) + } + }() + return s +} + +//register additional HTTP routes +func (s *Simulation) addSimulationRoutes() { + s.handler.POST("/runsim", s.RunSimulation) +} + +// RunSimulation is the actual POST endpoint runner +func (s *Simulation) RunSimulation(w http.ResponseWriter, req *http.Request) { + log.Debug("RunSimulation endpoint running") + s.runC <- struct{}{} + w.WriteHeader(http.StatusOK) +} diff --git a/swarm/network/simulation/http_test.go b/swarm/network/simulation/http_test.go new file mode 100644 index 0000000000..775cf92190 --- /dev/null +++ b/swarm/network/simulation/http_test.go @@ -0,0 +1,109 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package simulation + +import ( + "context" + "fmt" + "net/http" + "sync" + "testing" + "time" + + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/node" + "github.com/ethereum/go-ethereum/p2p/simulations/adapters" +) + +func TestSimulationWithHTTPServer(t *testing.T) { + log.Debug("Init simulation") + + ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second) + defer cancel() + + sim := New( + map[string]ServiceFunc{ + "noop": func(_ *adapters.ServiceContext, b *sync.Map) (node.Service, func(), error) { + return newNoopService(), nil, nil + }, + }).WithServer(DefaultHTTPSimAddr) + defer sim.Close() + log.Debug("Done.") + + _, err := sim.AddNode() + if err != nil { + t.Fatal(err) + } + + log.Debug("Starting sim round and let it time out...") + //first test that running without sending to the channel will actually + //block the simulation, so let it time out + result := sim.Run(ctx, func(ctx context.Context, sim *Simulation) error { + log.Debug("Just start the sim without any action and wait for the timeout") + //ensure with a Sleep that simulation doesn't terminate before the timeout + time.Sleep(2 * time.Second) + return nil + }) + + if result.Error != nil { + if result.Error.Error() == "context deadline exceeded" { + log.Debug("Expected timeout error received") + } else { + t.Fatal(result.Error) + } + } + + //now run it again and send the expected signal on the waiting channel, + //then close the simulation + log.Debug("Starting sim round and wait for frontend signal...") + //this time the timeout should be long enough so that it doesn't kick in too early + ctx, cancel2 := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel2() + go sendRunSignal(t) + result = sim.Run(ctx, func(ctx context.Context, sim *Simulation) error { + log.Debug("This run waits for the run signal from `frontend`...") + //ensure with a Sleep that simulation doesn't terminate before the signal is received + time.Sleep(2 * time.Second) + return nil + }) + if result.Error != nil { + t.Fatal(result.Error) + } + log.Debug("Test terminated successfully") +} + +func sendRunSignal(t *testing.T) { + //We need to first wait for the sim HTTP server to start running... + time.Sleep(2 * time.Second) + //then we can send the signal + + log.Debug("Sending run signal to simulation: POST /runsim...") + resp, err := http.Post(fmt.Sprintf("http://localhost%s/runsim", DefaultHTTPSimAddr), "application/json", nil) + if err != nil { + t.Fatalf("Request failed: %v", err) + } + defer func() { + err := resp.Body.Close() + if err != nil { + log.Error("Error closing response body", "err", err) + } + }() + log.Debug("Signal sent") + if resp.StatusCode != http.StatusOK { + t.Fatalf("err %s", resp.Status) + } +} diff --git a/swarm/network/simulation/kademlia.go b/swarm/network/simulation/kademlia.go new file mode 100644 index 0000000000..3e45cb0ce1 --- /dev/null +++ b/swarm/network/simulation/kademlia.go @@ -0,0 +1,96 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package simulation + +import ( + "context" + "encoding/hex" + "time" + + "github.com/ethereum/go-ethereum/p2p/discover" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/swarm/network" +) + +// BucketKeyKademlia is the key to be used for storing the kademlia +// instance for particuar node, usually inside the ServiceFunc function. +var BucketKeyKademlia BucketKey = "kademlia" + +// WaitTillHealthy is blocking until the health of all kademlias is true. +// If error is not nil, a map of kademlia that was found not healthy is returned. +func (s *Simulation) WaitTillHealthy(ctx context.Context, kadMinProxSize int) (ill map[discover.NodeID]*network.Kademlia, err error) { + // Prepare PeerPot map for checking Kademlia health + var ppmap map[string]*network.PeerPot + kademlias := s.kademlias() + addrs := make([][]byte, 0, len(kademlias)) + for _, k := range kademlias { + addrs = append(addrs, k.BaseAddr()) + } + ppmap = network.NewPeerPotMap(kadMinProxSize, addrs) + + // Wait for healthy Kademlia on every node before checking files + ticker := time.NewTicker(200 * time.Millisecond) + defer ticker.Stop() + + ill = make(map[discover.NodeID]*network.Kademlia) + for { + select { + case <-ctx.Done(): + return ill, ctx.Err() + case <-ticker.C: + for k := range ill { + delete(ill, k) + } + log.Debug("kademlia health check", "addr count", len(addrs)) + for id, k := range kademlias { + //PeerPot for this node + addr := common.Bytes2Hex(k.BaseAddr()) + pp := ppmap[addr] + //call Healthy RPC + h := k.Healthy(pp) + //print info + log.Debug(k.String()) + log.Debug("kademlia", "empty bins", pp.EmptyBins, "gotNN", h.GotNN, "knowNN", h.KnowNN, "full", h.Full) + log.Debug("kademlia", "health", h.GotNN && h.KnowNN && h.Full, "addr", hex.EncodeToString(k.BaseAddr()), "node", id) + log.Debug("kademlia", "ill condition", !h.GotNN || !h.Full, "addr", hex.EncodeToString(k.BaseAddr()), "node", id) + if !h.GotNN || !h.Full { + ill[id] = k + } + } + if len(ill) == 0 { + return nil, nil + } + } + } +} + +// kademlias returns all Kademlia instances that are set +// in simulation bucket. +func (s *Simulation) kademlias() (ks map[discover.NodeID]*network.Kademlia) { + items := s.UpNodesItems(BucketKeyKademlia) + ks = make(map[discover.NodeID]*network.Kademlia, len(items)) + for id, v := range items { + k, ok := v.(*network.Kademlia) + if !ok { + continue + } + ks[id] = k + } + return ks +} diff --git a/swarm/network/simulation/kademlia_test.go b/swarm/network/simulation/kademlia_test.go new file mode 100644 index 0000000000..d11fe7e41f --- /dev/null +++ b/swarm/network/simulation/kademlia_test.go @@ -0,0 +1,67 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package simulation + +import ( + "context" + "sync" + "testing" + "time" + + "github.com/ethereum/go-ethereum/node" + "github.com/ethereum/go-ethereum/p2p/simulations/adapters" + "github.com/ethereum/go-ethereum/swarm/network" +) + +func TestWaitTillHealthy(t *testing.T) { + sim := New(map[string]ServiceFunc{ + "bzz": func(ctx *adapters.ServiceContext, b *sync.Map) (node.Service, func(), error) { + addr := network.NewAddrFromNodeID(ctx.Config.ID) + hp := network.NewHiveParams() + hp.Discovery = false + config := &network.BzzConfig{ + OverlayAddr: addr.Over(), + UnderlayAddr: addr.Under(), + HiveParams: hp, + } + kad := network.NewKademlia(addr.Over(), network.NewKadParams()) + // store kademlia in node's bucket under BucketKeyKademlia + // so that it can be found by WaitTillHealthy method. + b.Store(BucketKeyKademlia, kad) + return network.NewBzz(config, kad, nil, nil, nil), nil, nil + }, + }) + defer sim.Close() + + _, err := sim.AddNodesAndConnectRing(10) + if err != nil { + t.Fatal(err) + } + + ctx, cancel := context.WithTimeout(context.Background(), 120*time.Second) + defer cancel() + ill, err := sim.WaitTillHealthy(ctx, 2) + if err != nil { + for id, kad := range ill { + t.Log("Node", id) + t.Log(kad.String()) + } + if err != nil { + t.Fatal(err) + } + } +} diff --git a/swarm/network/simulation/node.go b/swarm/network/simulation/node.go new file mode 100644 index 0000000000..784588fa6e --- /dev/null +++ b/swarm/network/simulation/node.go @@ -0,0 +1,362 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package simulation + +import ( + "encoding/json" + "errors" + "io/ioutil" + "math/rand" + "os" + "time" + + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/p2p/discover" + "github.com/ethereum/go-ethereum/p2p/simulations" + "github.com/ethereum/go-ethereum/p2p/simulations/adapters" +) + +// NodeIDs returns NodeIDs for all nodes in the network. +func (s *Simulation) NodeIDs() (ids []discover.NodeID) { + nodes := s.Net.GetNodes() + ids = make([]discover.NodeID, len(nodes)) + for i, node := range nodes { + ids[i] = node.ID() + } + return ids +} + +// UpNodeIDs returns NodeIDs for nodes that are up in the network. +func (s *Simulation) UpNodeIDs() (ids []discover.NodeID) { + nodes := s.Net.GetNodes() + for _, node := range nodes { + if node.Up { + ids = append(ids, node.ID()) + } + } + return ids +} + +// DownNodeIDs returns NodeIDs for nodes that are stopped in the network. +func (s *Simulation) DownNodeIDs() (ids []discover.NodeID) { + nodes := s.Net.GetNodes() + for _, node := range nodes { + if !node.Up { + ids = append(ids, node.ID()) + } + } + return ids +} + +// AddNodeOption defines the option that can be passed +// to Simulation.AddNode method. +type AddNodeOption func(*adapters.NodeConfig) + +// AddNodeWithMsgEvents sets the EnableMsgEvents option +// to NodeConfig. +func AddNodeWithMsgEvents(enable bool) AddNodeOption { + return func(o *adapters.NodeConfig) { + o.EnableMsgEvents = enable + } +} + +// AddNodeWithService specifies a service that should be +// started on a node. This option can be repeated as variadic +// argument toe AddNode and other add node related methods. +// If AddNodeWithService is not specified, all services will be started. +func AddNodeWithService(serviceName string) AddNodeOption { + return func(o *adapters.NodeConfig) { + o.Services = append(o.Services, serviceName) + } +} + +// AddNode creates a new node with random configuration, +// applies provided options to the config and adds the node to network. +// By default all services will be started on a node. If one or more +// AddNodeWithService option are provided, only specified services will be started. +func (s *Simulation) AddNode(opts ...AddNodeOption) (id discover.NodeID, err error) { + conf := adapters.RandomNodeConfig() + for _, o := range opts { + o(conf) + } + if len(conf.Services) == 0 { + conf.Services = s.serviceNames + } + node, err := s.Net.NewNodeWithConfig(conf) + if err != nil { + return id, err + } + return node.ID(), s.Net.Start(node.ID()) +} + +// AddNodes creates new nodes with random configurations, +// applies provided options to the config and adds nodes to network. +func (s *Simulation) AddNodes(count int, opts ...AddNodeOption) (ids []discover.NodeID, err error) { + ids = make([]discover.NodeID, 0, count) + for i := 0; i < count; i++ { + id, err := s.AddNode(opts...) + if err != nil { + return nil, err + } + ids = append(ids, id) + } + return ids, nil +} + +// AddNodesAndConnectFull is a helpper method that combines +// AddNodes and ConnectNodesFull. Only new nodes will be connected. +func (s *Simulation) AddNodesAndConnectFull(count int, opts ...AddNodeOption) (ids []discover.NodeID, err error) { + if count < 2 { + return nil, errors.New("count of nodes must be at least 2") + } + ids, err = s.AddNodes(count, opts...) + if err != nil { + return nil, err + } + err = s.ConnectNodesFull(ids) + if err != nil { + return nil, err + } + return ids, nil +} + +// AddNodesAndConnectChain is a helpper method that combines +// AddNodes and ConnectNodesChain. The chain will be continued from the last +// added node, if there is one in simulation using ConnectToLastNode method. +func (s *Simulation) AddNodesAndConnectChain(count int, opts ...AddNodeOption) (ids []discover.NodeID, err error) { + if count < 2 { + return nil, errors.New("count of nodes must be at least 2") + } + id, err := s.AddNode(opts...) + if err != nil { + return nil, err + } + err = s.ConnectToLastNode(id) + if err != nil { + return nil, err + } + ids, err = s.AddNodes(count-1, opts...) + if err != nil { + return nil, err + } + ids = append([]discover.NodeID{id}, ids...) + err = s.ConnectNodesChain(ids) + if err != nil { + return nil, err + } + return ids, nil +} + +// AddNodesAndConnectRing is a helpper method that combines +// AddNodes and ConnectNodesRing. +func (s *Simulation) AddNodesAndConnectRing(count int, opts ...AddNodeOption) (ids []discover.NodeID, err error) { + if count < 2 { + return nil, errors.New("count of nodes must be at least 2") + } + ids, err = s.AddNodes(count, opts...) + if err != nil { + return nil, err + } + err = s.ConnectNodesRing(ids) + if err != nil { + return nil, err + } + return ids, nil +} + +// AddNodesAndConnectStar is a helpper method that combines +// AddNodes and ConnectNodesStar. +func (s *Simulation) AddNodesAndConnectStar(count int, opts ...AddNodeOption) (ids []discover.NodeID, err error) { + if count < 2 { + return nil, errors.New("count of nodes must be at least 2") + } + ids, err = s.AddNodes(count, opts...) + if err != nil { + return nil, err + } + err = s.ConnectNodesStar(ids[0], ids[1:]) + if err != nil { + return nil, err + } + return ids, nil +} + +//UploadSnapshot uploads a snapshot to the simulation +//This method tries to open the json file provided, applies the config to all nodes +//and then loads the snapshot into the Simulation network +func (s *Simulation) UploadSnapshot(snapshotFile string, opts ...AddNodeOption) error { + f, err := os.Open(snapshotFile) + if err != nil { + return err + } + defer func() { + err := f.Close() + if err != nil { + log.Error("Error closing snapshot file", "err", err) + } + }() + jsonbyte, err := ioutil.ReadAll(f) + if err != nil { + return err + } + var snap simulations.Snapshot + err = json.Unmarshal(jsonbyte, &snap) + if err != nil { + return err + } + + //the snapshot probably has the property EnableMsgEvents not set + //just in case, set it to true! + //(we need this to wait for messages before uploading) + for _, n := range snap.Nodes { + n.Node.Config.EnableMsgEvents = true + n.Node.Config.Services = s.serviceNames + for _, o := range opts { + o(n.Node.Config) + } + } + + log.Info("Waiting for p2p connections to be established...") + + //now we can load the snapshot + err = s.Net.Load(&snap) + if err != nil { + return err + } + log.Info("Snapshot loaded") + return nil +} + +// SetPivotNode sets the NodeID of the network's pivot node. +// Pivot node is just a specific node that should be treated +// differently then other nodes in test. SetPivotNode and +// PivotNodeID are just a convenient functions to set and +// retrieve it. +func (s *Simulation) SetPivotNode(id discover.NodeID) { + s.mu.Lock() + defer s.mu.Unlock() + s.pivotNodeID = &id +} + +// PivotNodeID returns NodeID of the pivot node set by +// Simulation.SetPivotNode method. +func (s *Simulation) PivotNodeID() (id *discover.NodeID) { + s.mu.Lock() + defer s.mu.Unlock() + return s.pivotNodeID +} + +// StartNode starts a node by NodeID. +func (s *Simulation) StartNode(id discover.NodeID) (err error) { + return s.Net.Start(id) +} + +// StartRandomNode starts a random node. +func (s *Simulation) StartRandomNode() (id discover.NodeID, err error) { + n := s.randomDownNode() + if n == nil { + return id, ErrNodeNotFound + } + return n.ID, s.Net.Start(n.ID) +} + +// StartRandomNodes starts random nodes. +func (s *Simulation) StartRandomNodes(count int) (ids []discover.NodeID, err error) { + ids = make([]discover.NodeID, 0, count) + downIDs := s.DownNodeIDs() + for i := 0; i < count; i++ { + n := s.randomNode(downIDs, ids...) + if n == nil { + return nil, ErrNodeNotFound + } + err = s.Net.Start(n.ID) + if err != nil { + return nil, err + } + ids = append(ids, n.ID) + } + return ids, nil +} + +// StopNode stops a node by NodeID. +func (s *Simulation) StopNode(id discover.NodeID) (err error) { + return s.Net.Stop(id) +} + +// StopRandomNode stops a random node. +func (s *Simulation) StopRandomNode() (id discover.NodeID, err error) { + n := s.RandomUpNode() + if n == nil { + return id, ErrNodeNotFound + } + return n.ID, s.Net.Stop(n.ID) +} + +// StopRandomNodes stops random nodes. +func (s *Simulation) StopRandomNodes(count int) (ids []discover.NodeID, err error) { + ids = make([]discover.NodeID, 0, count) + upIDs := s.UpNodeIDs() + for i := 0; i < count; i++ { + n := s.randomNode(upIDs, ids...) + if n == nil { + return nil, ErrNodeNotFound + } + err = s.Net.Stop(n.ID) + if err != nil { + return nil, err + } + ids = append(ids, n.ID) + } + return ids, nil +} + +// seed the random generator for Simulation.randomNode. +func init() { + rand.Seed(time.Now().UnixNano()) +} + +// RandomUpNode returns a random SimNode that is up. +// Arguments are NodeIDs for nodes that should not be returned. +func (s *Simulation) RandomUpNode(exclude ...discover.NodeID) *adapters.SimNode { + return s.randomNode(s.UpNodeIDs(), exclude...) +} + +// randomDownNode returns a random SimNode that is not up. +func (s *Simulation) randomDownNode(exclude ...discover.NodeID) *adapters.SimNode { + return s.randomNode(s.DownNodeIDs(), exclude...) +} + +// randomNode returns a random SimNode from the slice of NodeIDs. +func (s *Simulation) randomNode(ids []discover.NodeID, exclude ...discover.NodeID) *adapters.SimNode { + for _, e := range exclude { + var i int + for _, id := range ids { + if id == e { + ids = append(ids[:i], ids[i+1:]...) + } else { + i++ + } + } + } + l := len(ids) + if l == 0 { + return nil + } + n := s.Net.GetNode(ids[rand.Intn(l)]) + node, _ := n.Node.(*adapters.SimNode) + return node +} diff --git a/swarm/network/simulation/node_test.go b/swarm/network/simulation/node_test.go new file mode 100644 index 0000000000..94f0b4fac0 --- /dev/null +++ b/swarm/network/simulation/node_test.go @@ -0,0 +1,462 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package simulation + +import ( + "context" + "fmt" + "sync" + "testing" + "time" + + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/node" + "github.com/ethereum/go-ethereum/p2p/discover" + "github.com/ethereum/go-ethereum/p2p/simulations/adapters" + "github.com/ethereum/go-ethereum/swarm/network" +) + +func TestUpDownNodeIDs(t *testing.T) { + sim := New(noopServiceFuncMap) + defer sim.Close() + + ids, err := sim.AddNodes(10) + if err != nil { + t.Fatal(err) + } + + gotIDs := sim.NodeIDs() + + if !equalNodeIDs(ids, gotIDs) { + t.Error("returned nodes are not equal to added ones") + } + + stoppedIDs, err := sim.StopRandomNodes(3) + if err != nil { + t.Fatal(err) + } + + gotIDs = sim.UpNodeIDs() + + for _, id := range gotIDs { + if !sim.Net.GetNode(id).Up { + t.Errorf("node %s should not be down", id) + } + } + + if !equalNodeIDs(ids, append(gotIDs, stoppedIDs...)) { + t.Error("returned nodes are not equal to added ones") + } + + gotIDs = sim.DownNodeIDs() + + for _, id := range gotIDs { + if sim.Net.GetNode(id).Up { + t.Errorf("node %s should not be up", id) + } + } + + if !equalNodeIDs(stoppedIDs, gotIDs) { + t.Error("returned nodes are not equal to the stopped ones") + } +} + +func equalNodeIDs(one, other []discover.NodeID) bool { + if len(one) != len(other) { + return false + } + var count int + for _, a := range one { + var found bool + for _, b := range other { + if a == b { + found = true + break + } + } + if found { + count++ + } else { + return false + } + } + return count == len(one) +} + +func TestAddNode(t *testing.T) { + sim := New(noopServiceFuncMap) + defer sim.Close() + + id, err := sim.AddNode() + if err != nil { + t.Fatal(err) + } + + n := sim.Net.GetNode(id) + if n == nil { + t.Fatal("node not found") + } + + if !n.Up { + t.Error("node not started") + } +} + +func TestAddNodeWithMsgEvents(t *testing.T) { + sim := New(noopServiceFuncMap) + defer sim.Close() + + id, err := sim.AddNode(AddNodeWithMsgEvents(true)) + if err != nil { + t.Fatal(err) + } + + if !sim.Net.GetNode(id).Config.EnableMsgEvents { + t.Error("EnableMsgEvents is false") + } + + id, err = sim.AddNode(AddNodeWithMsgEvents(false)) + if err != nil { + t.Fatal(err) + } + + if sim.Net.GetNode(id).Config.EnableMsgEvents { + t.Error("EnableMsgEvents is true") + } +} + +func TestAddNodeWithService(t *testing.T) { + sim := New(map[string]ServiceFunc{ + "noop1": noopServiceFunc, + "noop2": noopServiceFunc, + }) + defer sim.Close() + + id, err := sim.AddNode(AddNodeWithService("noop1")) + if err != nil { + t.Fatal(err) + } + + n := sim.Net.GetNode(id).Node.(*adapters.SimNode) + if n.Service("noop1") == nil { + t.Error("service noop1 not found on node") + } + if n.Service("noop2") != nil { + t.Error("service noop2 should not be found on node") + } +} + +func TestAddNodes(t *testing.T) { + sim := New(noopServiceFuncMap) + defer sim.Close() + + nodesCount := 12 + + ids, err := sim.AddNodes(nodesCount) + if err != nil { + t.Fatal(err) + } + + count := len(ids) + if count != nodesCount { + t.Errorf("expected %v nodes, got %v", nodesCount, count) + } + + count = len(sim.Net.GetNodes()) + if count != nodesCount { + t.Errorf("expected %v nodes, got %v", nodesCount, count) + } +} + +func TestAddNodesAndConnectFull(t *testing.T) { + sim := New(noopServiceFuncMap) + defer sim.Close() + + n := 12 + + ids, err := sim.AddNodesAndConnectFull(n) + if err != nil { + t.Fatal(err) + } + + testFull(t, sim, ids) +} + +func TestAddNodesAndConnectChain(t *testing.T) { + sim := New(noopServiceFuncMap) + defer sim.Close() + + _, err := sim.AddNodesAndConnectChain(12) + if err != nil { + t.Fatal(err) + } + + // add another set of nodes to test + // if two chains are connected + _, err = sim.AddNodesAndConnectChain(7) + if err != nil { + t.Fatal(err) + } + + testChain(t, sim, sim.UpNodeIDs()) +} + +func TestAddNodesAndConnectRing(t *testing.T) { + sim := New(noopServiceFuncMap) + defer sim.Close() + + ids, err := sim.AddNodesAndConnectRing(12) + if err != nil { + t.Fatal(err) + } + + testRing(t, sim, ids) +} + +func TestAddNodesAndConnectStar(t *testing.T) { + sim := New(noopServiceFuncMap) + defer sim.Close() + + ids, err := sim.AddNodesAndConnectStar(12) + if err != nil { + t.Fatal(err) + } + + testStar(t, sim, ids, 0) +} + +//To test that uploading a snapshot works +func TestUploadSnapshot(t *testing.T) { + log.Debug("Creating simulation") + s := New(map[string]ServiceFunc{ + "bzz": func(ctx *adapters.ServiceContext, b *sync.Map) (node.Service, func(), error) { + addr := network.NewAddrFromNodeID(ctx.Config.ID) + hp := network.NewHiveParams() + hp.Discovery = false + config := &network.BzzConfig{ + OverlayAddr: addr.Over(), + UnderlayAddr: addr.Under(), + HiveParams: hp, + } + kad := network.NewKademlia(addr.Over(), network.NewKadParams()) + return network.NewBzz(config, kad, nil, nil, nil), nil, nil + }, + }) + defer s.Close() + + nodeCount := 16 + log.Debug("Uploading snapshot") + err := s.UploadSnapshot(fmt.Sprintf("../stream/testing/snapshot_%d.json", nodeCount)) + if err != nil { + t.Fatalf("Error uploading snapshot to simulation network: %v", err) + } + + ctx := context.Background() + log.Debug("Starting simulation...") + s.Run(ctx, func(ctx context.Context, sim *Simulation) error { + log.Debug("Checking") + nodes := sim.UpNodeIDs() + if len(nodes) != nodeCount { + t.Fatal("Simulation network node number doesn't match snapshot node number") + } + return nil + }) + log.Debug("Done.") +} + +func TestPivotNode(t *testing.T) { + sim := New(noopServiceFuncMap) + defer sim.Close() + + id, err := sim.AddNode() + if err != nil { + t.Fatal(err) + } + + id2, err := sim.AddNode() + if err != nil { + t.Fatal(err) + } + + if sim.PivotNodeID() != nil { + t.Error("expected no pivot node") + } + + sim.SetPivotNode(id) + + pid := sim.PivotNodeID() + + if pid == nil { + t.Error("pivot node not set") + } else if *pid != id { + t.Errorf("expected pivot node %s, got %s", id, *pid) + } + + sim.SetPivotNode(id2) + + pid = sim.PivotNodeID() + + if pid == nil { + t.Error("pivot node not set") + } else if *pid != id2 { + t.Errorf("expected pivot node %s, got %s", id2, *pid) + } +} + +func TestStartStopNode(t *testing.T) { + sim := New(noopServiceFuncMap) + defer sim.Close() + + id, err := sim.AddNode() + if err != nil { + t.Fatal(err) + } + + n := sim.Net.GetNode(id) + if n == nil { + t.Fatal("node not found") + } + if !n.Up { + t.Error("node not started") + } + + err = sim.StopNode(id) + if err != nil { + t.Fatal(err) + } + if n.Up { + t.Error("node not stopped") + } + + // Sleep here to ensure that Network.watchPeerEvents defer function + // has set the `node.Up = false` before we start the node again. + // p2p/simulations/network.go:215 + // + // The same node is stopped and started again, and upon start + // watchPeerEvents is started in a goroutine. If the node is stopped + // and then very quickly started, that goroutine may be scheduled later + // then start and force `node.Up = false` in its defer function. + // This will make this test unreliable. + time.Sleep(time.Second) + + err = sim.StartNode(id) + if err != nil { + t.Fatal(err) + } + if !n.Up { + t.Error("node not started") + } +} + +func TestStartStopRandomNode(t *testing.T) { + sim := New(noopServiceFuncMap) + defer sim.Close() + + _, err := sim.AddNodes(3) + if err != nil { + t.Fatal(err) + } + + id, err := sim.StopRandomNode() + if err != nil { + t.Fatal(err) + } + + n := sim.Net.GetNode(id) + if n == nil { + t.Fatal("node not found") + } + if n.Up { + t.Error("node not stopped") + } + + id2, err := sim.StopRandomNode() + if err != nil { + t.Fatal(err) + } + + // Sleep here to ensure that Network.watchPeerEvents defer function + // has set the `node.Up = false` before we start the node again. + // p2p/simulations/network.go:215 + // + // The same node is stopped and started again, and upon start + // watchPeerEvents is started in a goroutine. If the node is stopped + // and then very quickly started, that goroutine may be scheduled later + // then start and force `node.Up = false` in its defer function. + // This will make this test unreliable. + time.Sleep(time.Second) + + idStarted, err := sim.StartRandomNode() + if err != nil { + t.Fatal(err) + } + + if idStarted != id && idStarted != id2 { + t.Error("unexpected started node ID") + } +} + +func TestStartStopRandomNodes(t *testing.T) { + sim := New(noopServiceFuncMap) + defer sim.Close() + + _, err := sim.AddNodes(10) + if err != nil { + t.Fatal(err) + } + + ids, err := sim.StopRandomNodes(3) + if err != nil { + t.Fatal(err) + } + + for _, id := range ids { + n := sim.Net.GetNode(id) + if n == nil { + t.Fatal("node not found") + } + if n.Up { + t.Error("node not stopped") + } + } + + // Sleep here to ensure that Network.watchPeerEvents defer function + // has set the `node.Up = false` before we start the node again. + // p2p/simulations/network.go:215 + // + // The same node is stopped and started again, and upon start + // watchPeerEvents is started in a goroutine. If the node is stopped + // and then very quickly started, that goroutine may be scheduled later + // then start and force `node.Up = false` in its defer function. + // This will make this test unreliable. + time.Sleep(time.Second) + + ids, err = sim.StartRandomNodes(2) + if err != nil { + t.Fatal(err) + } + + for _, id := range ids { + n := sim.Net.GetNode(id) + if n == nil { + t.Fatal("node not found") + } + if !n.Up { + t.Error("node not started") + } + } +} diff --git a/swarm/network/simulation/service.go b/swarm/network/simulation/service.go new file mode 100644 index 0000000000..02e7ad0cc9 --- /dev/null +++ b/swarm/network/simulation/service.go @@ -0,0 +1,65 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package simulation + +import ( + "github.com/ethereum/go-ethereum/node" + "github.com/ethereum/go-ethereum/p2p/discover" + "github.com/ethereum/go-ethereum/p2p/simulations/adapters" +) + +// Service returns a single Service by name on a particular node +// with provided id. +func (s *Simulation) Service(name string, id discover.NodeID) node.Service { + simNode, ok := s.Net.GetNode(id).Node.(*adapters.SimNode) + if !ok { + return nil + } + services := simNode.ServiceMap() + if len(services) == 0 { + return nil + } + return services[name] +} + +// RandomService returns a single Service by name on a +// randomly chosen node that is up. +func (s *Simulation) RandomService(name string) node.Service { + n := s.RandomUpNode() + if n == nil { + return nil + } + return n.Service(name) +} + +// Services returns all services with a provided name +// from nodes that are up. +func (s *Simulation) Services(name string) (services map[discover.NodeID]node.Service) { + nodes := s.Net.GetNodes() + services = make(map[discover.NodeID]node.Service) + for _, node := range nodes { + if !node.Up { + continue + } + simNode, ok := node.Node.(*adapters.SimNode) + if !ok { + continue + } + services[node.ID()] = simNode.Service(name) + } + return services +} diff --git a/swarm/network/simulation/service_test.go b/swarm/network/simulation/service_test.go new file mode 100644 index 0000000000..23b0d86f24 --- /dev/null +++ b/swarm/network/simulation/service_test.go @@ -0,0 +1,46 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package simulation + +import ( + "testing" +) + +func TestService(t *testing.T) { + sim := New(noopServiceFuncMap) + defer sim.Close() + + id, err := sim.AddNode() + if err != nil { + t.Fatal(err) + } + + _, ok := sim.Service("noop", id).(*noopService) + if !ok { + t.Fatalf("service is not of %T type", &noopService{}) + } + + _, ok = sim.RandomService("noop").(*noopService) + if !ok { + t.Fatalf("service is not of %T type", &noopService{}) + } + + _, ok = sim.Services("noop")[id].(*noopService) + if !ok { + t.Fatalf("service is not of %T type", &noopService{}) + } +} diff --git a/swarm/network/simulation/simulation.go b/swarm/network/simulation/simulation.go new file mode 100644 index 0000000000..2241dfca21 --- /dev/null +++ b/swarm/network/simulation/simulation.go @@ -0,0 +1,201 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package simulation + +import ( + "context" + "errors" + "net/http" + "sync" + "time" + + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/node" + "github.com/ethereum/go-ethereum/p2p/discover" + "github.com/ethereum/go-ethereum/p2p/simulations" + "github.com/ethereum/go-ethereum/p2p/simulations/adapters" +) + +// Common errors that are returned by functions in this package. +var ( + ErrNodeNotFound = errors.New("node not found") + ErrNoPivotNode = errors.New("no pivot node set") +) + +// Simulation provides methods on network, nodes and services +// to manage them. +type Simulation struct { + // Net is exposed as a way to access lower level functionalities + // of p2p/simulations.Network. + Net *simulations.Network + + serviceNames []string + cleanupFuncs []func() + buckets map[discover.NodeID]*sync.Map + pivotNodeID *discover.NodeID + shutdownWG sync.WaitGroup + done chan struct{} + mu sync.RWMutex + + httpSrv *http.Server //attach a HTTP server via SimulationOptions + handler *simulations.Server //HTTP handler for the server + runC chan struct{} //channel where frontend signals it is ready +} + +// ServiceFunc is used in New to declare new service constructor. +// The first argument provides ServiceContext from the adapters package +// giving for example the access to NodeID. Second argument is the sync.Map +// where all "global" state related to the service should be kept. +// All cleanups needed for constructed service and any other constructed +// objects should ne provided in a single returned cleanup function. +type ServiceFunc func(ctx *adapters.ServiceContext, bucket *sync.Map) (s node.Service, cleanup func(), err error) + +// New creates a new Simulation instance with new +// simulations.Network initialized with provided services. +func New(services map[string]ServiceFunc) (s *Simulation) { + s = &Simulation{ + buckets: make(map[discover.NodeID]*sync.Map), + done: make(chan struct{}), + } + + adapterServices := make(map[string]adapters.ServiceFunc, len(services)) + for name, serviceFunc := range services { + s.serviceNames = append(s.serviceNames, name) + adapterServices[name] = func(ctx *adapters.ServiceContext) (node.Service, error) { + b := new(sync.Map) + service, cleanup, err := serviceFunc(ctx, b) + if err != nil { + return nil, err + } + s.mu.Lock() + defer s.mu.Unlock() + if cleanup != nil { + s.cleanupFuncs = append(s.cleanupFuncs, cleanup) + } + s.buckets[ctx.Config.ID] = b + return service, nil + } + } + + s.Net = simulations.NewNetwork( + adapters.NewSimAdapter(adapterServices), + &simulations.NetworkConfig{ID: "0"}, + ) + + return s +} + +// RunFunc is the function that will be called +// on Simulation.Run method call. +type RunFunc func(context.Context, *Simulation) error + +// Result is the returned value of Simulation.Run method. +type Result struct { + Duration time.Duration + Error error +} + +// Run calls the RunFunc function while taking care of +// cancelation provided through the Context. +func (s *Simulation) Run(ctx context.Context, f RunFunc) (r Result) { + //if the option is set to run a HTTP server with the simulation, + //init the server and start it + start := time.Now() + if s.httpSrv != nil { + log.Info("Waiting for frontend to be ready...(send POST /runsim to HTTP server)") + //wait for the frontend to connect + select { + case <-s.runC: + case <-ctx.Done(): + return Result{ + Duration: time.Since(start), + Error: ctx.Err(), + } + } + log.Info("Received signal from frontend - starting simulation run.") + } + errc := make(chan error) + quit := make(chan struct{}) + defer close(quit) + go func() { + select { + case errc <- f(ctx, s): + case <-quit: + } + }() + var err error + select { + case <-ctx.Done(): + err = ctx.Err() + case err = <-errc: + } + return Result{ + Duration: time.Since(start), + Error: err, + } +} + +// Maximal number of parallel calls to cleanup functions on +// Simulation.Close. +var maxParallelCleanups = 10 + +// Close calls all cleanup functions that are returned by +// ServiceFunc, waits for all of them to finish and other +// functions that explicitly block shutdownWG +// (like Simulation.PeerEvents) and shuts down the network +// at the end. It is used to clean all resources from the +// simulation. +func (s *Simulation) Close() { + close(s.done) + sem := make(chan struct{}, maxParallelCleanups) + s.mu.RLock() + cleanupFuncs := make([]func(), len(s.cleanupFuncs)) + for i, f := range s.cleanupFuncs { + if f != nil { + cleanupFuncs[i] = f + } + } + s.mu.RUnlock() + for _, cleanup := range cleanupFuncs { + s.shutdownWG.Add(1) + sem <- struct{}{} + go func(cleanup func()) { + defer s.shutdownWG.Done() + defer func() { <-sem }() + + cleanup() + }(cleanup) + } + if s.httpSrv != nil { + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) + defer cancel() + err := s.httpSrv.Shutdown(ctx) + if err != nil { + log.Error("Error shutting down HTTP server!", "err", err) + } + close(s.runC) + } + s.shutdownWG.Wait() + s.Net.Shutdown() +} + +// Done returns a channel that is closed when the simulation +// is closed by Close method. It is useful for signaling termination +// of all possible goroutines that are created within the test. +func (s *Simulation) Done() <-chan struct{} { + return s.done +} diff --git a/swarm/network/simulation/simulation_test.go b/swarm/network/simulation/simulation_test.go new file mode 100644 index 0000000000..803e0499a2 --- /dev/null +++ b/swarm/network/simulation/simulation_test.go @@ -0,0 +1,207 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package simulation + +import ( + "context" + "errors" + "flag" + "sync" + "testing" + "time" + + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/node" + "github.com/ethereum/go-ethereum/p2p" + "github.com/ethereum/go-ethereum/p2p/simulations/adapters" + "github.com/ethereum/go-ethereum/rpc" + colorable "github.com/mattn/go-colorable" +) + +var ( + loglevel = flag.Int("loglevel", 2, "verbosity of logs") +) + +func init() { + flag.Parse() + log.PrintOrigins(true) + log.Root().SetHandler(log.LvlFilterHandler(log.Lvl(*loglevel), log.StreamHandler(colorable.NewColorableStderr(), log.TerminalFormat(true)))) +} + +// TestRun tests if Run method calls RunFunc and if it handles context properly. +func TestRun(t *testing.T) { + sim := New(noopServiceFuncMap) + defer sim.Close() + + t.Run("call", func(t *testing.T) { + expect := "something" + var got string + r := sim.Run(context.Background(), func(ctx context.Context, sim *Simulation) error { + got = expect + return nil + }) + + if r.Error != nil { + t.Errorf("unexpected error: %v", r.Error) + } + if got != expect { + t.Errorf("expected %q, got %q", expect, got) + } + }) + + t.Run("cancelation", func(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), 50*time.Millisecond) + defer cancel() + + r := sim.Run(ctx, func(ctx context.Context, sim *Simulation) error { + time.Sleep(100 * time.Millisecond) + return nil + }) + + if r.Error != context.DeadlineExceeded { + t.Errorf("unexpected error: %v", r.Error) + } + }) + + t.Run("context value and duration", func(t *testing.T) { + ctx := context.WithValue(context.Background(), "hey", "there") + sleep := 50 * time.Millisecond + + r := sim.Run(ctx, func(ctx context.Context, sim *Simulation) error { + if ctx.Value("hey") != "there" { + return errors.New("expected context value not passed") + } + time.Sleep(sleep) + return nil + }) + + if r.Error != nil { + t.Errorf("unexpected error: %v", r.Error) + } + if r.Duration < sleep { + t.Errorf("reported run duration less then expected: %s", r.Duration) + } + }) +} + +// TestClose tests are Close method triggers all close functions and are all nodes not up anymore. +func TestClose(t *testing.T) { + var mu sync.Mutex + var cleanupCount int + + sleep := 50 * time.Millisecond + + sim := New(map[string]ServiceFunc{ + "noop": func(ctx *adapters.ServiceContext, b *sync.Map) (node.Service, func(), error) { + return newNoopService(), func() { + time.Sleep(sleep) + mu.Lock() + defer mu.Unlock() + cleanupCount++ + }, nil + }, + }) + + nodeCount := 30 + + _, err := sim.AddNodes(nodeCount) + if err != nil { + t.Fatal(err) + } + + var upNodeCount int + for _, n := range sim.Net.GetNodes() { + if n.Up { + upNodeCount++ + } + } + if upNodeCount != nodeCount { + t.Errorf("all nodes should be up, insted only %v are up", upNodeCount) + } + + sim.Close() + + if cleanupCount != nodeCount { + t.Errorf("number of cleanups expected %v, got %v", nodeCount, cleanupCount) + } + + upNodeCount = 0 + for _, n := range sim.Net.GetNodes() { + if n.Up { + upNodeCount++ + } + } + if upNodeCount != 0 { + t.Errorf("all nodes should be down, insted %v are up", upNodeCount) + } +} + +// TestDone checks if Close method triggers the closing of done channel. +func TestDone(t *testing.T) { + sim := New(noopServiceFuncMap) + sleep := 50 * time.Millisecond + timeout := 2 * time.Second + + start := time.Now() + go func() { + time.Sleep(sleep) + sim.Close() + }() + + select { + case <-time.After(timeout): + t.Error("done channel closing timmed out") + case <-sim.Done(): + if d := time.Since(start); d < sleep { + t.Errorf("done channel closed sooner then expected: %s", d) + } + } +} + +// a helper map for usual services that do not do anyting +var noopServiceFuncMap = map[string]ServiceFunc{ + "noop": noopServiceFunc, +} + +// a helper function for most basic noop service +func noopServiceFunc(ctx *adapters.ServiceContext, b *sync.Map) (node.Service, func(), error) { + return newNoopService(), nil, nil +} + +// noopService is the service that does not do anything +// but implements node.Service interface. +type noopService struct{} + +func newNoopService() node.Service { + return &noopService{} +} + +func (t *noopService) Protocols() []p2p.Protocol { + return []p2p.Protocol{} +} + +func (t *noopService) APIs() []rpc.API { + return []rpc.API{} +} + +func (t *noopService) Start(server *p2p.Server) error { + return nil +} + +func (t *noopService) Stop() error { + return nil +} diff --git a/swarm/network/simulations/discovery/discovery.go b/swarm/network/simulations/discovery/discovery.go new file mode 100644 index 0000000000..a6ff5fd45e --- /dev/null +++ b/swarm/network/simulations/discovery/discovery.go @@ -0,0 +1,17 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package discovery diff --git a/swarm/network/simulations/discovery/discovery_test.go b/swarm/network/simulations/discovery/discovery_test.go new file mode 100644 index 0000000000..acf3479e52 --- /dev/null +++ b/swarm/network/simulations/discovery/discovery_test.go @@ -0,0 +1,586 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package discovery + +import ( + "context" + "encoding/json" + "errors" + "flag" + "fmt" + "io/ioutil" + "math/rand" + "os" + "path" + "strings" + "sync" + "testing" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/node" + "github.com/ethereum/go-ethereum/p2p" + "github.com/ethereum/go-ethereum/p2p/discover" + "github.com/ethereum/go-ethereum/p2p/simulations" + "github.com/ethereum/go-ethereum/p2p/simulations/adapters" + "github.com/ethereum/go-ethereum/swarm/network" + "github.com/ethereum/go-ethereum/swarm/state" + colorable "github.com/mattn/go-colorable" +) + +// serviceName is used with the exec adapter so the exec'd binary knows which +// service to execute +const serviceName = "discovery" +const testMinProxBinSize = 2 +const discoveryPersistenceDatadir = "discovery_persistence_test_store" + +var discoveryPersistencePath = path.Join(os.TempDir(), discoveryPersistenceDatadir) +var discoveryEnabled = true +var persistenceEnabled = false + +var services = adapters.Services{ + serviceName: newService, +} + +func cleanDbStores() error { + entries, err := ioutil.ReadDir(os.TempDir()) + if err != nil { + return err + } + + for _, f := range entries { + if strings.HasPrefix(f.Name(), discoveryPersistenceDatadir) { + os.RemoveAll(path.Join(os.TempDir(), f.Name())) + } + } + return nil + +} + +func getDbStore(nodeID string) (*state.DBStore, error) { + if _, err := os.Stat(discoveryPersistencePath + "_" + nodeID); os.IsNotExist(err) { + log.Info(fmt.Sprintf("directory for nodeID %s does not exist. creating...", nodeID)) + ioutil.TempDir("", discoveryPersistencePath+"_"+nodeID) + } + log.Info(fmt.Sprintf("opening storage directory for nodeID %s", nodeID)) + store, err := state.NewDBStore(discoveryPersistencePath + "_" + nodeID) + if err != nil { + return nil, err + } + return store, nil +} + +var ( + nodeCount = flag.Int("nodes", 10, "number of nodes to create (default 10)") + initCount = flag.Int("conns", 1, "number of originally connected peers (default 1)") + snapshotFile = flag.String("snapshot", "", "create snapshot") + loglevel = flag.Int("loglevel", 3, "verbosity of logs") + rawlog = flag.Bool("rawlog", false, "remove terminal formatting from logs") +) + +func init() { + flag.Parse() + // register the discovery service which will run as a devp2p + // protocol when using the exec adapter + adapters.RegisterServices(services) + + log.PrintOrigins(true) + log.Root().SetHandler(log.LvlFilterHandler(log.Lvl(*loglevel), log.StreamHandler(colorable.NewColorableStderr(), log.TerminalFormat(!*rawlog)))) +} + +// Benchmarks to test the average time it takes for an N-node ring +// to full a healthy kademlia topology +func BenchmarkDiscovery_8_1(b *testing.B) { benchmarkDiscovery(b, 8, 1) } +func BenchmarkDiscovery_16_1(b *testing.B) { benchmarkDiscovery(b, 16, 1) } +func BenchmarkDiscovery_32_1(b *testing.B) { benchmarkDiscovery(b, 32, 1) } +func BenchmarkDiscovery_64_1(b *testing.B) { benchmarkDiscovery(b, 64, 1) } +func BenchmarkDiscovery_128_1(b *testing.B) { benchmarkDiscovery(b, 128, 1) } +func BenchmarkDiscovery_256_1(b *testing.B) { benchmarkDiscovery(b, 256, 1) } + +func BenchmarkDiscovery_8_2(b *testing.B) { benchmarkDiscovery(b, 8, 2) } +func BenchmarkDiscovery_16_2(b *testing.B) { benchmarkDiscovery(b, 16, 2) } +func BenchmarkDiscovery_32_2(b *testing.B) { benchmarkDiscovery(b, 32, 2) } +func BenchmarkDiscovery_64_2(b *testing.B) { benchmarkDiscovery(b, 64, 2) } +func BenchmarkDiscovery_128_2(b *testing.B) { benchmarkDiscovery(b, 128, 2) } +func BenchmarkDiscovery_256_2(b *testing.B) { benchmarkDiscovery(b, 256, 2) } + +func BenchmarkDiscovery_8_4(b *testing.B) { benchmarkDiscovery(b, 8, 4) } +func BenchmarkDiscovery_16_4(b *testing.B) { benchmarkDiscovery(b, 16, 4) } +func BenchmarkDiscovery_32_4(b *testing.B) { benchmarkDiscovery(b, 32, 4) } +func BenchmarkDiscovery_64_4(b *testing.B) { benchmarkDiscovery(b, 64, 4) } +func BenchmarkDiscovery_128_4(b *testing.B) { benchmarkDiscovery(b, 128, 4) } +func BenchmarkDiscovery_256_4(b *testing.B) { benchmarkDiscovery(b, 256, 4) } + +func TestDiscoverySimulationDockerAdapter(t *testing.T) { + testDiscoverySimulationDockerAdapter(t, *nodeCount, *initCount) +} + +func testDiscoverySimulationDockerAdapter(t *testing.T, nodes, conns int) { + adapter, err := adapters.NewDockerAdapter() + if err != nil { + if err == adapters.ErrLinuxOnly { + t.Skip(err) + } else { + t.Fatal(err) + } + } + testDiscoverySimulation(t, nodes, conns, adapter) +} + +func TestDiscoverySimulationExecAdapter(t *testing.T) { + testDiscoverySimulationExecAdapter(t, *nodeCount, *initCount) +} + +func testDiscoverySimulationExecAdapter(t *testing.T, nodes, conns int) { + baseDir, err := ioutil.TempDir("", "swarm-test") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(baseDir) + testDiscoverySimulation(t, nodes, conns, adapters.NewExecAdapter(baseDir)) +} + +func TestDiscoverySimulationSimAdapter(t *testing.T) { + testDiscoverySimulationSimAdapter(t, *nodeCount, *initCount) +} + +func TestDiscoveryPersistenceSimulationSimAdapter(t *testing.T) { + testDiscoveryPersistenceSimulationSimAdapter(t, *nodeCount, *initCount) +} + +func testDiscoveryPersistenceSimulationSimAdapter(t *testing.T, nodes, conns int) { + testDiscoveryPersistenceSimulation(t, nodes, conns, adapters.NewSimAdapter(services)) +} + +func testDiscoverySimulationSimAdapter(t *testing.T, nodes, conns int) { + testDiscoverySimulation(t, nodes, conns, adapters.NewSimAdapter(services)) +} + +func testDiscoverySimulation(t *testing.T, nodes, conns int, adapter adapters.NodeAdapter) { + startedAt := time.Now() + result, err := discoverySimulation(nodes, conns, adapter) + if err != nil { + t.Fatalf("Setting up simulation failed: %v", err) + } + if result.Error != nil { + t.Fatalf("Simulation failed: %s", result.Error) + } + t.Logf("Simulation with %d nodes passed in %s", nodes, result.FinishedAt.Sub(result.StartedAt)) + var min, max time.Duration + var sum int + for _, pass := range result.Passes { + duration := pass.Sub(result.StartedAt) + if sum == 0 || duration < min { + min = duration + } + if duration > max { + max = duration + } + sum += int(duration.Nanoseconds()) + } + t.Logf("Min: %s, Max: %s, Average: %s", min, max, time.Duration(sum/len(result.Passes))*time.Nanosecond) + finishedAt := time.Now() + t.Logf("Setup: %s, shutdown: %s", result.StartedAt.Sub(startedAt), finishedAt.Sub(result.FinishedAt)) +} + +func testDiscoveryPersistenceSimulation(t *testing.T, nodes, conns int, adapter adapters.NodeAdapter) map[int][]byte { + persistenceEnabled = true + discoveryEnabled = true + + result, err := discoveryPersistenceSimulation(nodes, conns, adapter) + + if err != nil { + t.Fatalf("Setting up simulation failed: %v", err) + } + if result.Error != nil { + t.Fatalf("Simulation failed: %s", result.Error) + } + t.Logf("Simulation with %d nodes passed in %s", nodes, result.FinishedAt.Sub(result.StartedAt)) + // set the discovery and persistence flags again to default so other + // tests will not be affected + discoveryEnabled = true + persistenceEnabled = false + return nil +} + +func benchmarkDiscovery(b *testing.B, nodes, conns int) { + for i := 0; i < b.N; i++ { + result, err := discoverySimulation(nodes, conns, adapters.NewSimAdapter(services)) + if err != nil { + b.Fatalf("setting up simulation failed: %v", err) + } + if result.Error != nil { + b.Logf("simulation failed: %s", result.Error) + } + } +} + +func discoverySimulation(nodes, conns int, adapter adapters.NodeAdapter) (*simulations.StepResult, error) { + // create network + net := simulations.NewNetwork(adapter, &simulations.NetworkConfig{ + ID: "0", + DefaultService: serviceName, + }) + defer net.Shutdown() + trigger := make(chan discover.NodeID) + ids := make([]discover.NodeID, nodes) + for i := 0; i < nodes; i++ { + conf := adapters.RandomNodeConfig() + node, err := net.NewNodeWithConfig(conf) + if err != nil { + return nil, fmt.Errorf("error starting node: %s", err) + } + if err := net.Start(node.ID()); err != nil { + return nil, fmt.Errorf("error starting node %s: %s", node.ID().TerminalString(), err) + } + if err := triggerChecks(trigger, net, node.ID()); err != nil { + return nil, fmt.Errorf("error triggering checks for node %s: %s", node.ID().TerminalString(), err) + } + ids[i] = node.ID() + } + + // run a simulation which connects the 10 nodes in a ring and waits + // for full peer discovery + var addrs [][]byte + action := func(ctx context.Context) error { + return nil + } + wg := sync.WaitGroup{} + for i := range ids { + // collect the overlay addresses, to + addrs = append(addrs, network.ToOverlayAddr(ids[i].Bytes())) + for j := 0; j < conns; j++ { + var k int + if j == 0 { + k = (i + 1) % len(ids) + } else { + k = rand.Intn(len(ids)) + } + wg.Add(1) + go func(i, k int) { + defer wg.Done() + net.Connect(ids[i], ids[k]) + }(i, k) + } + } + wg.Wait() + log.Debug(fmt.Sprintf("nodes: %v", len(addrs))) + // construct the peer pot, so that kademlia health can be checked + ppmap := network.NewPeerPotMap(testMinProxBinSize, addrs) + check := func(ctx context.Context, id discover.NodeID) (bool, error) { + select { + case <-ctx.Done(): + return false, ctx.Err() + default: + } + + node := net.GetNode(id) + if node == nil { + return false, fmt.Errorf("unknown node: %s", id) + } + client, err := node.Client() + if err != nil { + return false, fmt.Errorf("error getting node client: %s", err) + } + healthy := &network.Health{} + addr := common.Bytes2Hex(network.ToOverlayAddr(id.Bytes())) + if err := client.Call(&healthy, "hive_healthy", ppmap[addr]); err != nil { + return false, fmt.Errorf("error getting node health: %s", err) + } + log.Debug(fmt.Sprintf("node %4s healthy: got nearest neighbours: %v, know nearest neighbours: %v, saturated: %v\n%v", id, healthy.GotNN, healthy.KnowNN, healthy.Full, healthy.Hive)) + return healthy.KnowNN && healthy.GotNN && healthy.Full, nil + } + + // 64 nodes ~ 1min + // 128 nodes ~ + timeout := 300 * time.Second + ctx, cancel := context.WithTimeout(context.Background(), timeout) + defer cancel() + result := simulations.NewSimulation(net).Run(ctx, &simulations.Step{ + Action: action, + Trigger: trigger, + Expect: &simulations.Expectation{ + Nodes: ids, + Check: check, + }, + }) + if result.Error != nil { + return result, nil + } + + if *snapshotFile != "" { + snap, err := net.Snapshot() + if err != nil { + return nil, errors.New("no shapshot dude") + } + jsonsnapshot, err := json.Marshal(snap) + if err != nil { + return nil, fmt.Errorf("corrupt json snapshot: %v", err) + } + log.Info("writing snapshot", "file", *snapshotFile) + err = ioutil.WriteFile(*snapshotFile, jsonsnapshot, 0755) + if err != nil { + return nil, err + } + } + return result, nil +} + +func discoveryPersistenceSimulation(nodes, conns int, adapter adapters.NodeAdapter) (*simulations.StepResult, error) { + cleanDbStores() + defer cleanDbStores() + + // create network + net := simulations.NewNetwork(adapter, &simulations.NetworkConfig{ + ID: "0", + DefaultService: serviceName, + }) + defer net.Shutdown() + trigger := make(chan discover.NodeID) + ids := make([]discover.NodeID, nodes) + var addrs [][]byte + + for i := 0; i < nodes; i++ { + conf := adapters.RandomNodeConfig() + node, err := net.NewNodeWithConfig(conf) + if err != nil { + panic(err) + } + if err != nil { + return nil, fmt.Errorf("error starting node: %s", err) + } + if err := net.Start(node.ID()); err != nil { + return nil, fmt.Errorf("error starting node %s: %s", node.ID().TerminalString(), err) + } + if err := triggerChecks(trigger, net, node.ID()); err != nil { + return nil, fmt.Errorf("error triggering checks for node %s: %s", node.ID().TerminalString(), err) + } + ids[i] = node.ID() + a := network.ToOverlayAddr(ids[i].Bytes()) + + addrs = append(addrs, a) + } + + // run a simulation which connects the 10 nodes in a ring and waits + // for full peer discovery + ppmap := network.NewPeerPotMap(testMinProxBinSize, addrs) + + var restartTime time.Time + + action := func(ctx context.Context) error { + ticker := time.NewTicker(500 * time.Millisecond) + + for range ticker.C { + isHealthy := true + for _, id := range ids { + //call Healthy RPC + node := net.GetNode(id) + if node == nil { + return fmt.Errorf("unknown node: %s", id) + } + client, err := node.Client() + if err != nil { + return fmt.Errorf("error getting node client: %s", err) + } + healthy := &network.Health{} + addr := common.Bytes2Hex(network.ToOverlayAddr(id.Bytes())) + if err := client.Call(&healthy, "hive_healthy", ppmap[addr]); err != nil { + return fmt.Errorf("error getting node health: %s", err) + } + + log.Info(fmt.Sprintf("NODE: %s, IS HEALTHY: %t", id.String(), healthy.GotNN && healthy.KnowNN && healthy.Full)) + if !healthy.GotNN || !healthy.Full { + isHealthy = false + break + } + } + if isHealthy { + break + } + } + ticker.Stop() + + log.Info("reached healthy kademlia. starting to shutdown nodes.") + shutdownStarted := time.Now() + // stop all ids, then start them again + for _, id := range ids { + node := net.GetNode(id) + + if err := net.Stop(node.ID()); err != nil { + return fmt.Errorf("error stopping node %s: %s", node.ID().TerminalString(), err) + } + } + log.Info(fmt.Sprintf("shutting down nodes took: %s", time.Since(shutdownStarted))) + persistenceEnabled = true + discoveryEnabled = false + restartTime = time.Now() + for _, id := range ids { + node := net.GetNode(id) + if err := net.Start(node.ID()); err != nil { + return fmt.Errorf("error starting node %s: %s", node.ID().TerminalString(), err) + } + if err := triggerChecks(trigger, net, node.ID()); err != nil { + return fmt.Errorf("error triggering checks for node %s: %s", node.ID().TerminalString(), err) + } + } + + log.Info(fmt.Sprintf("restarting nodes took: %s", time.Since(restartTime))) + + return nil + } + //connects in a chain + wg := sync.WaitGroup{} + //connects in a ring + for i := range ids { + for j := 1; j <= conns; j++ { + k := (i + j) % len(ids) + if k == i { + k = (k + 1) % len(ids) + } + wg.Add(1) + go func(i, k int) { + defer wg.Done() + net.Connect(ids[i], ids[k]) + }(i, k) + } + } + wg.Wait() + log.Debug(fmt.Sprintf("nodes: %v", len(addrs))) + // construct the peer pot, so that kademlia health can be checked + check := func(ctx context.Context, id discover.NodeID) (bool, error) { + select { + case <-ctx.Done(): + return false, ctx.Err() + default: + } + + node := net.GetNode(id) + if node == nil { + return false, fmt.Errorf("unknown node: %s", id) + } + client, err := node.Client() + if err != nil { + return false, fmt.Errorf("error getting node client: %s", err) + } + healthy := &network.Health{} + addr := common.Bytes2Hex(network.ToOverlayAddr(id.Bytes())) + if err := client.Call(&healthy, "hive_healthy", ppmap[addr]); err != nil { + return false, fmt.Errorf("error getting node health: %s", err) + } + log.Info(fmt.Sprintf("node %4s healthy: got nearest neighbours: %v, know nearest neighbours: %v, saturated: %v", id, healthy.GotNN, healthy.KnowNN, healthy.Full)) + + return healthy.KnowNN && healthy.GotNN && healthy.Full, nil + } + + // 64 nodes ~ 1min + // 128 nodes ~ + timeout := 300 * time.Second + ctx, cancel := context.WithTimeout(context.Background(), timeout) + defer cancel() + result := simulations.NewSimulation(net).Run(ctx, &simulations.Step{ + Action: action, + Trigger: trigger, + Expect: &simulations.Expectation{ + Nodes: ids, + Check: check, + }, + }) + if result.Error != nil { + return result, nil + } + + return result, nil +} + +// triggerChecks triggers a simulation step check whenever a peer is added or +// removed from the given node, and also every second to avoid a race between +// peer events and kademlia becoming healthy +func triggerChecks(trigger chan discover.NodeID, net *simulations.Network, id discover.NodeID) error { + node := net.GetNode(id) + if node == nil { + return fmt.Errorf("unknown node: %s", id) + } + client, err := node.Client() + if err != nil { + return err + } + events := make(chan *p2p.PeerEvent) + sub, err := client.Subscribe(context.Background(), "admin", events, "peerEvents") + if err != nil { + return fmt.Errorf("error getting peer events for node %v: %s", id, err) + } + go func() { + defer sub.Unsubscribe() + + tick := time.NewTicker(time.Second) + defer tick.Stop() + + for { + select { + case <-events: + trigger <- id + case <-tick.C: + trigger <- id + case err := <-sub.Err(): + if err != nil { + log.Error(fmt.Sprintf("error getting peer events for node %v", id), "err", err) + } + return + } + } + }() + return nil +} + +func newService(ctx *adapters.ServiceContext) (node.Service, error) { + host := adapters.ExternalIP() + + addr := network.NewAddrFromNodeIDAndPort(ctx.Config.ID, host, ctx.Config.Port) + + kp := network.NewKadParams() + kp.MinProxBinSize = testMinProxBinSize + + if ctx.Config.Reachable != nil { + kp.Reachable = func(o network.OverlayAddr) bool { + return ctx.Config.Reachable(o.(*network.BzzAddr).ID()) + } + } + kad := network.NewKademlia(addr.Over(), kp) + hp := network.NewHiveParams() + hp.KeepAliveInterval = time.Duration(200) * time.Millisecond + hp.Discovery = discoveryEnabled + + log.Info(fmt.Sprintf("discovery for nodeID %s is %t", ctx.Config.ID.String(), hp.Discovery)) + + config := &network.BzzConfig{ + OverlayAddr: addr.Over(), + UnderlayAddr: addr.Under(), + HiveParams: hp, + } + + if persistenceEnabled { + log.Info(fmt.Sprintf("persistence enabled for nodeID %s", ctx.Config.ID.String())) + store, err := getDbStore(ctx.Config.ID.String()) + if err != nil { + return nil, err + } + return network.NewBzz(config, kad, store, nil, nil), nil + } + + return network.NewBzz(config, kad, nil, nil, nil), nil +} diff --git a/swarm/network/simulations/discovery/jsonsnapshot.txt b/swarm/network/simulations/discovery/jsonsnapshot.txt new file mode 100755 index 0000000000..51d319dbc9 --- /dev/null +++ b/swarm/network/simulations/discovery/jsonsnapshot.txt @@ -0,0 +1 @@ +{"nodes":[{"config":{"id":"b3bdd767da3baf548169c34731204e18c2661fdd6f99859aad09c0e3a575cebbdbff3ad2fce53b3af9226e421a0ef5b7c0d934b382054b1aab0dd37586bda390","private_key":"0fe997f31d91d569cd9283232c7b44ea29fbdd25b3ba351d0676d12f36236fce","name":"node01","services":["discovery"]},"up":true},{"config":{"id":"b6dbb137efcd90412472b7015a5c94800be2ae4d9a2bb5a93e6edd56358c170031dba7552bda187ef60bf84cdafc0f7f800d70a06e75359c13bab53ae1df2849","private_key":"710b57c14e04a6800c26ed2effe1d76ae25f7e113410c30f4065cdf7639aea30","name":"node02","services":["discovery"]},"up":true},{"config":{"id":"5a9a437cf250d662b6c13ae07b3713db497d84f16e98dc4dc849a91ebc4e4a4056c4911150b03633ff9a12af5b59036242325967944a5354be936e101900051e","private_key":"370728241e71b18ecfe4979cbeeeb968f30943e8022ae1f41965ffb1959f50f6","name":"node03","services":["discovery"]},"up":true},{"config":{"id":"110cedce4adb25a6cb0ff756e28cde22421e825c1110f7472b52a8d4de604a9ffe7d01f5e71aff483ec0a3fa8bfe8e2cb53eb85b8944f839331351628f1b209d","private_key":"2dd7bf0eca70d3b78a01600abc6665b1abd27cee96f42a4c0aea58ebc3e0f1c0","name":"node04","services":["discovery"]},"up":true},{"config":{"id":"3ed77f18fe4fcfe40621e525c8c329bd066c477d01ff1d237458d66d0d3646961c0f943ae773a3ab78b07579dc0ee28eae5a89936c11ccaf43e12b86fc3f63ea","private_key":"f9e67ff0212a3ddf9085385e825bf63e1619938ba8332f970b28e4241a78ec50","name":"node05","services":["discovery"]},"up":true},{"config":{"id":"62481ad258b8d3ddd9262adcdccec70288e879db1e74565599cf4aa277d7f03c333d2ef0d9a06699c779f9d274a2b84a32506009afe5ee5c4e9574302c04a2bb","private_key":"9e6291b175d334e057dd7a902b42675f6ba4735378351ce22b742f835be1082d","name":"node06","services":["discovery"]},"up":true},{"config":{"id":"f4718b84450d7f5444394533f5312f0196f2c2c7d867fb3ddd82fbafdc21f3c478555c96401357aa8c68582f39ad4e752aa61ff19e781ca5c4525fc258853eec","private_key":"ebff8542458c73a3ee77b58a6e7c12ef2132f2fe1623eb47e67751ca277be79a","name":"node07","services":["discovery"]},"up":true},{"config":{"id":"5019a6b7ab464e4c443a1fb74a94fbf4fe2754999ad2b08a6585cc44e0cf53a0a964d5e2cf5069b5a5660b0346a4fd9f6d998b8843be6b4be8858431c813bd23","private_key":"5725444d69bdd3e6740ebf2f7aa9126d9f00297a0a83eea6e5cbeb81a7fe56f7","name":"node08","services":["discovery"]},"up":true},{"config":{"id":"17917299fdc3a358f7b7336157e927c22e3e0c661fb0e630df3821f238fff46e2e6387cfaf2a6fdb33cf5bb005a6248bea664645133c28f068578c0fb362d132","private_key":"56b698d576cb9b1758ad09ca53a61b297b59dd2e6f5aeb1828ca22beb5be2ea7","name":"node09","services":["discovery"]},"up":true},{"config":{"id":"b212f4df8ee646c3a6cd566a6544ec4534ebcc3be9ab697010225014136ab9cdeaca96b8119ca07e3ff69f7f097e162793d8262aaee2a79367a298a77ae2cfeb","private_key":"99488b9451a47aa37013cc8934ecc51614a8f23f3b1fa29b6537c01e7da55530","name":"node10","services":["discovery"]},"up":true}],"conns":[{"one":"b3bdd767da3baf548169c34731204e18c2661fdd6f99859aad09c0e3a575cebbdbff3ad2fce53b3af9226e421a0ef5b7c0d934b382054b1aab0dd37586bda390","other":"b212f4df8ee646c3a6cd566a6544ec4534ebcc3be9ab697010225014136ab9cdeaca96b8119ca07e3ff69f7f097e162793d8262aaee2a79367a298a77ae2cfeb","up":true,"reverse":false,"distance":79},{"one":"b6dbb137efcd90412472b7015a5c94800be2ae4d9a2bb5a93e6edd56358c170031dba7552bda187ef60bf84cdafc0f7f800d70a06e75359c13bab53ae1df2849","other":"b3bdd767da3baf548169c34731204e18c2661fdd6f99859aad09c0e3a575cebbdbff3ad2fce53b3af9226e421a0ef5b7c0d934b382054b1aab0dd37586bda390","up":true,"reverse":false,"distance":77},{"one":"5a9a437cf250d662b6c13ae07b3713db497d84f16e98dc4dc849a91ebc4e4a4056c4911150b03633ff9a12af5b59036242325967944a5354be936e101900051e","other":"b6dbb137efcd90412472b7015a5c94800be2ae4d9a2bb5a93e6edd56358c170031dba7552bda187ef60bf84cdafc0f7f800d70a06e75359c13bab53ae1df2849","up":true,"reverse":false,"distance":65},{"one":"110cedce4adb25a6cb0ff756e28cde22421e825c1110f7472b52a8d4de604a9ffe7d01f5e71aff483ec0a3fa8bfe8e2cb53eb85b8944f839331351628f1b209d","other":"5a9a437cf250d662b6c13ae07b3713db497d84f16e98dc4dc849a91ebc4e4a4056c4911150b03633ff9a12af5b59036242325967944a5354be936e101900051e","up":true,"reverse":true,"distance":69},{"one":"3ed77f18fe4fcfe40621e525c8c329bd066c477d01ff1d237458d66d0d3646961c0f943ae773a3ab78b07579dc0ee28eae5a89936c11ccaf43e12b86fc3f63ea","other":"110cedce4adb25a6cb0ff756e28cde22421e825c1110f7472b52a8d4de604a9ffe7d01f5e71aff483ec0a3fa8bfe8e2cb53eb85b8944f839331351628f1b209d","up":true,"reverse":false,"distance":70},{"one":"62481ad258b8d3ddd9262adcdccec70288e879db1e74565599cf4aa277d7f03c333d2ef0d9a06699c779f9d274a2b84a32506009afe5ee5c4e9574302c04a2bb","other":"3ed77f18fe4fcfe40621e525c8c329bd066c477d01ff1d237458d66d0d3646961c0f943ae773a3ab78b07579dc0ee28eae5a89936c11ccaf43e12b86fc3f63ea","up":true,"reverse":false,"distance":69},{"one":"f4718b84450d7f5444394533f5312f0196f2c2c7d867fb3ddd82fbafdc21f3c478555c96401357aa8c68582f39ad4e752aa61ff19e781ca5c4525fc258853eec","other":"62481ad258b8d3ddd9262adcdccec70288e879db1e74565599cf4aa277d7f03c333d2ef0d9a06699c779f9d274a2b84a32506009afe5ee5c4e9574302c04a2bb","up":true,"reverse":false,"distance":65},{"one":"5019a6b7ab464e4c443a1fb74a94fbf4fe2754999ad2b08a6585cc44e0cf53a0a964d5e2cf5069b5a5660b0346a4fd9f6d998b8843be6b4be8858431c813bd23","other":"f4718b84450d7f5444394533f5312f0196f2c2c7d867fb3ddd82fbafdc21f3c478555c96401357aa8c68582f39ad4e752aa61ff19e781ca5c4525fc258853eec","up":true,"reverse":false,"distance":65},{"one":"17917299fdc3a358f7b7336157e927c22e3e0c661fb0e630df3821f238fff46e2e6387cfaf2a6fdb33cf5bb005a6248bea664645133c28f068578c0fb362d132","other":"5019a6b7ab464e4c443a1fb74a94fbf4fe2754999ad2b08a6585cc44e0cf53a0a964d5e2cf5069b5a5660b0346a4fd9f6d998b8843be6b4be8858431c813bd23","up":true,"reverse":false,"distance":69},{"one":"b212f4df8ee646c3a6cd566a6544ec4534ebcc3be9ab697010225014136ab9cdeaca96b8119ca07e3ff69f7f097e162793d8262aaee2a79367a298a77ae2cfeb","other":"17917299fdc3a358f7b7336157e927c22e3e0c661fb0e630df3821f238fff46e2e6387cfaf2a6fdb33cf5bb005a6248bea664645133c28f068578c0fb362d132","up":true,"reverse":true,"distance":65}]} \ No newline at end of file diff --git a/swarm/network/simulations/overlay.go b/swarm/network/simulations/overlay.go new file mode 100644 index 0000000000..9419de0c6f --- /dev/null +++ b/swarm/network/simulations/overlay.go @@ -0,0 +1,144 @@ +// 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 . + +// You can run this simulation using +// +// go run ./swarm/network/simulations/overlay.go +package main + +import ( + "flag" + "fmt" + "net/http" + "runtime" + "sync" + "time" + + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/node" + "github.com/ethereum/go-ethereum/p2p/discover" + "github.com/ethereum/go-ethereum/p2p/simulations" + "github.com/ethereum/go-ethereum/p2p/simulations/adapters" + "github.com/ethereum/go-ethereum/swarm/network" + "github.com/ethereum/go-ethereum/swarm/state" + colorable "github.com/mattn/go-colorable" +) + +var ( + noDiscovery = flag.Bool("no-discovery", false, "disable discovery (useful if you want to load a snapshot)") + vmodule = flag.String("vmodule", "", "log filters for logger via Vmodule") + verbosity = flag.Int("verbosity", 0, "log filters for logger via Vmodule") + httpSimPort = 8888 +) + +func init() { + flag.Parse() + //initialize the logger + //this is a demonstration on how to use Vmodule for filtering logs + //provide -vmodule as param, and comma-separated values, e.g.: + //-vmodule overlay_test.go=4,simulations=3 + //above examples sets overlay_test.go logs to level 4, while packages ending with "simulations" to 3 + if *vmodule != "" { + //only enable the pattern matching handler if the flag has been provided + glogger := log.NewGlogHandler(log.StreamHandler(colorable.NewColorableStderr(), log.TerminalFormat(true))) + if *verbosity > 0 { + glogger.Verbosity(log.Lvl(*verbosity)) + } + glogger.Vmodule(*vmodule) + log.Root().SetHandler(glogger) + } +} + +type Simulation struct { + mtx sync.Mutex + stores map[discover.NodeID]*state.InmemoryStore +} + +func NewSimulation() *Simulation { + return &Simulation{ + stores: make(map[discover.NodeID]*state.InmemoryStore), + } +} + +func (s *Simulation) NewService(ctx *adapters.ServiceContext) (node.Service, error) { + id := ctx.Config.ID + s.mtx.Lock() + store, ok := s.stores[id] + if !ok { + store = state.NewInmemoryStore() + s.stores[id] = store + } + s.mtx.Unlock() + + addr := network.NewAddrFromNodeID(id) + + kp := network.NewKadParams() + kp.MinProxBinSize = 2 + kp.MaxBinSize = 4 + kp.MinBinSize = 1 + kp.MaxRetries = 1000 + kp.RetryExponent = 2 + kp.RetryInterval = 1000000 + kad := network.NewKademlia(addr.Over(), kp) + hp := network.NewHiveParams() + hp.Discovery = !*noDiscovery + hp.KeepAliveInterval = 300 * time.Millisecond + + config := &network.BzzConfig{ + OverlayAddr: addr.Over(), + UnderlayAddr: addr.Under(), + HiveParams: hp, + } + + return network.NewBzz(config, kad, store, nil, nil), nil +} + +//create the simulation network +func newSimulationNetwork() *simulations.Network { + + s := NewSimulation() + services := adapters.Services{ + "overlay": s.NewService, + } + adapter := adapters.NewSimAdapter(services) + simNetwork := simulations.NewNetwork(adapter, &simulations.NetworkConfig{ + DefaultService: "overlay", + }) + return simNetwork +} + +//return a new http server +func newOverlaySim(sim *simulations.Network) *simulations.Server { + return simulations.NewServer(sim) +} + +// var server +func main() { + //cpu optimization + runtime.GOMAXPROCS(runtime.NumCPU()) + //run the sim + runOverlaySim() +} + +func runOverlaySim() { + //create the simulation network + net := newSimulationNetwork() + //create a http server with it + sim := newOverlaySim(net) + log.Info(fmt.Sprintf("starting simulation server on 0.0.0.0:%d...", httpSimPort)) + //start the HTTP server + http.ListenAndServe(fmt.Sprintf(":%d", httpSimPort), sim) +} diff --git a/swarm/network/simulations/overlay_test.go b/swarm/network/simulations/overlay_test.go new file mode 100644 index 0000000000..4d4eb6c371 --- /dev/null +++ b/swarm/network/simulations/overlay_test.go @@ -0,0 +1,195 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . +package main + +import ( + "context" + "encoding/json" + "fmt" + "io/ioutil" + "net/http" + "net/http/httptest" + "net/url" + "testing" + "time" + + "github.com/ethereum/go-ethereum/p2p/discover" + "github.com/ethereum/go-ethereum/p2p/simulations" + "github.com/ethereum/go-ethereum/swarm/log" +) + +var ( + nodeCount = 16 +) + +//This test is used to test the overlay simulation. +//As the simulation is executed via a main, it is easily missed on changes +//An automated test will prevent that +//The test just connects to the simulations, starts the network, +//starts the mocker, gets the number of nodes, and stops it again. +//It also provides a documentation on the steps needed by frontends +//to use the simulations +func TestOverlaySim(t *testing.T) { + t.Skip("Test is flaky, see: https://github.com/ethersphere/go-ethereum/issues/592") + //start the simulation + log.Info("Start simulation backend") + //get the simulation networ; needed to subscribe for up events + net := newSimulationNetwork() + //create the overlay simulation + sim := newOverlaySim(net) + //create a http test server with it + srv := httptest.NewServer(sim) + defer srv.Close() + + log.Debug("Http simulation server started. Start simulation network") + //start the simulation network (initialization of simulation) + resp, err := http.Post(srv.URL+"/start", "application/json", nil) + if err != nil { + t.Fatal(err) + } + defer resp.Body.Close() + if resp.StatusCode != http.StatusOK { + t.Fatalf("Expected Status Code %d, got %d", http.StatusOK, resp.StatusCode) + } + + log.Debug("Start mocker") + //start the mocker, needs a node count and an ID + resp, err = http.PostForm(srv.URL+"/mocker/start", + url.Values{ + "node-count": {fmt.Sprintf("%d", nodeCount)}, + "mocker-type": {simulations.GetMockerList()[0]}, + }) + if err != nil { + t.Fatal(err) + } + defer resp.Body.Close() + if resp.StatusCode != http.StatusOK { + reason, err := ioutil.ReadAll(resp.Body) + if err != nil { + t.Fatal(err) + } + t.Fatalf("Expected Status Code %d, got %d, response body %s", http.StatusOK, resp.StatusCode, string(reason)) + } + + //variables needed to wait for nodes being up + var upCount int + trigger := make(chan discover.NodeID) + + //wait for all nodes to be up + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + + //start watching node up events... + go watchSimEvents(net, ctx, trigger) + + //...and wait until all expected up events (nodeCount) have been received +LOOP: + for { + select { + case <-trigger: + //new node up event received, increase counter + upCount++ + //all expected node up events received + if upCount == nodeCount { + break LOOP + } + case <-ctx.Done(): + t.Fatalf("Timed out waiting for up events") + } + + } + + //at this point we can query the server + log.Info("Get number of nodes") + //get the number of nodes + resp, err = http.Get(srv.URL + "/nodes") + if err != nil { + t.Fatal(err) + } + + defer resp.Body.Close() + if resp.StatusCode != http.StatusOK { + t.Fatalf("err %s", resp.Status) + } + b, err := ioutil.ReadAll(resp.Body) + if err != nil { + t.Fatal(err) + } + + //unmarshal number of nodes from JSON response + var nodesArr []simulations.Node + err = json.Unmarshal(b, &nodesArr) + if err != nil { + t.Fatal(err) + } + + //check if number of nodes received is same as sent + if len(nodesArr) != nodeCount { + t.Fatal(fmt.Errorf("Expected %d number of nodes, got %d", nodeCount, len(nodesArr))) + } + + //need to let it run for a little while, otherwise stopping it immediately can crash due running nodes + //wanting to connect to already stopped nodes + time.Sleep(1 * time.Second) + + log.Info("Stop the network") + //stop the network + resp, err = http.Post(srv.URL+"/stop", "application/json", nil) + if err != nil { + t.Fatal(err) + } + defer resp.Body.Close() + if resp.StatusCode != http.StatusOK { + t.Fatalf("err %s", resp.Status) + } + + log.Info("Reset the network") + //reset the network (removes all nodes and connections) + resp, err = http.Post(srv.URL+"/reset", "application/json", nil) + if err != nil { + t.Fatal(err) + } + defer resp.Body.Close() + if resp.StatusCode != http.StatusOK { + t.Fatalf("err %s", resp.Status) + } +} + +//watch for events so we know when all nodes are up +func watchSimEvents(net *simulations.Network, ctx context.Context, trigger chan discover.NodeID) { + events := make(chan *simulations.Event) + sub := net.Events().Subscribe(events) + defer sub.Unsubscribe() + + for { + select { + case ev := <-events: + //only catch node up events + if ev.Type == simulations.EventTypeNode { + if ev.Node.Up { + log.Debug("got node up event", "event", ev, "node", ev.Node.Config.ID) + select { + case trigger <- ev.Node.Config.ID: + case <-ctx.Done(): + return + } + } + } + case <-ctx.Done(): + return + } + } +} diff --git a/swarm/network/stream/common_test.go b/swarm/network/stream/common_test.go new file mode 100644 index 0000000000..491dc9fd58 --- /dev/null +++ b/swarm/network/stream/common_test.go @@ -0,0 +1,255 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package stream + +import ( + "context" + crand "crypto/rand" + "errors" + "flag" + "fmt" + "io" + "io/ioutil" + "math/rand" + "os" + "strings" + "sync/atomic" + "testing" + "time" + + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/p2p/discover" + p2ptest "github.com/ethereum/go-ethereum/p2p/testing" + "github.com/ethereum/go-ethereum/swarm/network" + "github.com/ethereum/go-ethereum/swarm/network/simulation" + "github.com/ethereum/go-ethereum/swarm/pot" + "github.com/ethereum/go-ethereum/swarm/state" + "github.com/ethereum/go-ethereum/swarm/storage" + mockdb "github.com/ethereum/go-ethereum/swarm/storage/mock/db" + colorable "github.com/mattn/go-colorable" +) + +var ( + loglevel = flag.Int("loglevel", 2, "verbosity of logs") + nodes = flag.Int("nodes", 0, "number of nodes") + chunks = flag.Int("chunks", 0, "number of chunks") + useMockStore = flag.Bool("mockstore", false, "disabled mock store (default: enabled)") + longrunning = flag.Bool("longrunning", false, "do run long-running tests") + + bucketKeyDB = simulation.BucketKey("db") + bucketKeyStore = simulation.BucketKey("store") + bucketKeyFileStore = simulation.BucketKey("filestore") + bucketKeyNetStore = simulation.BucketKey("netstore") + bucketKeyDelivery = simulation.BucketKey("delivery") + bucketKeyRegistry = simulation.BucketKey("registry") + + chunkSize = 4096 + pof = pot.DefaultPof(256) +) + +func init() { + flag.Parse() + rand.Seed(time.Now().UnixNano()) + + log.PrintOrigins(true) + log.Root().SetHandler(log.LvlFilterHandler(log.Lvl(*loglevel), log.StreamHandler(colorable.NewColorableStderr(), log.TerminalFormat(true)))) +} + +func createGlobalStore() (string, *mockdb.GlobalStore, error) { + var globalStore *mockdb.GlobalStore + globalStoreDir, err := ioutil.TempDir("", "global.store") + if err != nil { + log.Error("Error initiating global store temp directory!", "err", err) + return "", nil, err + } + globalStore, err = mockdb.NewGlobalStore(globalStoreDir) + if err != nil { + log.Error("Error initiating global store!", "err", err) + return "", nil, err + } + return globalStoreDir, globalStore, nil +} + +func newStreamerTester(t *testing.T) (*p2ptest.ProtocolTester, *Registry, *storage.LocalStore, func(), error) { + // setup + addr := network.RandomAddr() // tested peers peer address + to := network.NewKademlia(addr.OAddr, network.NewKadParams()) + + // temp datadir + datadir, err := ioutil.TempDir("", "streamer") + if err != nil { + return nil, nil, nil, func() {}, err + } + removeDataDir := func() { + os.RemoveAll(datadir) + } + + params := storage.NewDefaultLocalStoreParams() + params.Init(datadir) + params.BaseKey = addr.Over() + + localStore, err := storage.NewTestLocalStoreForAddr(params) + if err != nil { + return nil, nil, nil, removeDataDir, err + } + + db := storage.NewDBAPI(localStore) + delivery := NewDelivery(to, db) + streamer := NewRegistry(addr, delivery, db, state.NewInmemoryStore(), nil) + teardown := func() { + streamer.Close() + removeDataDir() + } + protocolTester := p2ptest.NewProtocolTester(t, network.NewNodeIDFromAddr(addr), 1, streamer.runProtocol) + + err = waitForPeers(streamer, 1*time.Second, 1) + if err != nil { + return nil, nil, nil, nil, errors.New("timeout: peer is not created") + } + + return protocolTester, streamer, localStore, teardown, nil +} + +func waitForPeers(streamer *Registry, timeout time.Duration, expectedPeers int) error { + ticker := time.NewTicker(10 * time.Millisecond) + timeoutTimer := time.NewTimer(timeout) + for { + select { + case <-ticker.C: + if streamer.peersCount() >= expectedPeers { + return nil + } + case <-timeoutTimer.C: + return errors.New("timeout") + } + } +} + +type roundRobinStore struct { + index uint32 + stores []storage.ChunkStore +} + +func newRoundRobinStore(stores ...storage.ChunkStore) *roundRobinStore { + return &roundRobinStore{ + stores: stores, + } +} + +func (rrs *roundRobinStore) Get(ctx context.Context, addr storage.Address) (*storage.Chunk, error) { + return nil, errors.New("get not well defined on round robin store") +} + +func (rrs *roundRobinStore) Put(ctx context.Context, chunk *storage.Chunk) { + i := atomic.AddUint32(&rrs.index, 1) + idx := int(i) % len(rrs.stores) + rrs.stores[idx].Put(ctx, chunk) +} + +func (rrs *roundRobinStore) Close() { + for _, store := range rrs.stores { + store.Close() + } +} + +func readAll(fileStore *storage.FileStore, hash []byte) (int64, error) { + r, _ := fileStore.Retrieve(context.TODO(), hash) + buf := make([]byte, 1024) + var n int + var total int64 + var err error + for (total == 0 || n > 0) && err == nil { + n, err = r.ReadAt(buf, total) + total += int64(n) + } + if err != nil && err != io.EOF { + return total, err + } + return total, nil +} + +func uploadFilesToNodes(sim *simulation.Simulation) ([]storage.Address, []string, error) { + nodes := sim.UpNodeIDs() + nodeCnt := len(nodes) + log.Debug(fmt.Sprintf("Uploading %d files to nodes", nodeCnt)) + //array holding generated files + rfiles := make([]string, nodeCnt) + //array holding the root hashes of the files + rootAddrs := make([]storage.Address, nodeCnt) + + var err error + //for every node, generate a file and upload + for i, id := range nodes { + item, ok := sim.NodeItem(id, bucketKeyFileStore) + if !ok { + return nil, nil, fmt.Errorf("Error accessing localstore") + } + fileStore := item.(*storage.FileStore) + //generate a file + rfiles[i], err = generateRandomFile() + if err != nil { + return nil, nil, err + } + //store it (upload it) on the FileStore + ctx := context.TODO() + rk, wait, err := fileStore.Store(ctx, strings.NewReader(rfiles[i]), int64(len(rfiles[i])), false) + log.Debug("Uploaded random string file to node") + if err != nil { + return nil, nil, err + } + err = wait(ctx) + if err != nil { + return nil, nil, err + } + rootAddrs[i] = rk + } + return rootAddrs, rfiles, nil +} + +//generate a random file (string) +func generateRandomFile() (string, error) { + //generate a random file size between minFileSize and maxFileSize + fileSize := rand.Intn(maxFileSize-minFileSize) + minFileSize + log.Debug(fmt.Sprintf("Generated file with filesize %d kB", fileSize)) + b := make([]byte, fileSize*1024) + _, err := crand.Read(b) + if err != nil { + log.Error("Error generating random file.", "err", err) + return "", err + } + return string(b), nil +} + +//create a local store for the given node +func createTestLocalStorageForID(id discover.NodeID, addr *network.BzzAddr) (storage.ChunkStore, string, error) { + var datadir string + var err error + datadir, err = ioutil.TempDir("", fmt.Sprintf("syncer-test-%s", id.TerminalString())) + if err != nil { + return nil, "", err + } + var store storage.ChunkStore + params := storage.NewDefaultLocalStoreParams() + params.ChunkDbPath = datadir + params.BaseKey = addr.Over() + store, err = storage.NewTestLocalStoreForAddr(params) + if err != nil { + os.RemoveAll(datadir) + return nil, "", err + } + return store, datadir, nil +} diff --git a/swarm/network/stream/delivery.go b/swarm/network/stream/delivery.go new file mode 100644 index 0000000000..fa210e3007 --- /dev/null +++ b/swarm/network/stream/delivery.go @@ -0,0 +1,293 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package stream + +import ( + "context" + "errors" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/metrics" + "github.com/ethereum/go-ethereum/p2p/discover" + "github.com/ethereum/go-ethereum/swarm/log" + "github.com/ethereum/go-ethereum/swarm/network" + "github.com/ethereum/go-ethereum/swarm/spancontext" + "github.com/ethereum/go-ethereum/swarm/storage" + opentracing "github.com/opentracing/opentracing-go" +) + +const ( + swarmChunkServerStreamName = "RETRIEVE_REQUEST" + deliveryCap = 32 +) + +var ( + processReceivedChunksCount = metrics.NewRegisteredCounter("network.stream.received_chunks.count", nil) + handleRetrieveRequestMsgCount = metrics.NewRegisteredCounter("network.stream.handle_retrieve_request_msg.count", nil) + + requestFromPeersCount = metrics.NewRegisteredCounter("network.stream.request_from_peers.count", nil) + requestFromPeersEachCount = metrics.NewRegisteredCounter("network.stream.request_from_peers_each.count", nil) +) + +type Delivery struct { + db *storage.DBAPI + overlay network.Overlay + receiveC chan *ChunkDeliveryMsg + getPeer func(discover.NodeID) *Peer +} + +func NewDelivery(overlay network.Overlay, db *storage.DBAPI) *Delivery { + d := &Delivery{ + db: db, + overlay: overlay, + receiveC: make(chan *ChunkDeliveryMsg, deliveryCap), + } + + go d.processReceivedChunks() + return d +} + +// SwarmChunkServer implements Server +type SwarmChunkServer struct { + deliveryC chan []byte + batchC chan []byte + db *storage.DBAPI + currentLen uint64 + quit chan struct{} +} + +// NewSwarmChunkServer is SwarmChunkServer constructor +func NewSwarmChunkServer(db *storage.DBAPI) *SwarmChunkServer { + s := &SwarmChunkServer{ + deliveryC: make(chan []byte, deliveryCap), + batchC: make(chan []byte), + db: db, + quit: make(chan struct{}), + } + go s.processDeliveries() + return s +} + +// processDeliveries handles delivered chunk hashes +func (s *SwarmChunkServer) processDeliveries() { + var hashes []byte + var batchC chan []byte + for { + select { + case <-s.quit: + return + case hash := <-s.deliveryC: + hashes = append(hashes, hash...) + batchC = s.batchC + case batchC <- hashes: + hashes = nil + batchC = nil + } + } +} + +// SetNextBatch +func (s *SwarmChunkServer) SetNextBatch(_, _ uint64) (hashes []byte, from uint64, to uint64, proof *HandoverProof, err error) { + select { + case hashes = <-s.batchC: + case <-s.quit: + return + } + + from = s.currentLen + s.currentLen += uint64(len(hashes)) + to = s.currentLen + return +} + +// Close needs to be called on a stream server +func (s *SwarmChunkServer) Close() { + close(s.quit) +} + +// GetData retrives chunk data from db store +func (s *SwarmChunkServer) GetData(ctx context.Context, key []byte) ([]byte, error) { + chunk, err := s.db.Get(ctx, storage.Address(key)) + if err == storage.ErrFetching { + <-chunk.ReqC + } else if err != nil { + return nil, err + } + return chunk.SData, nil +} + +// RetrieveRequestMsg is the protocol msg for chunk retrieve requests +type RetrieveRequestMsg struct { + Addr storage.Address + SkipCheck bool +} + +func (d *Delivery) handleRetrieveRequestMsg(ctx context.Context, sp *Peer, req *RetrieveRequestMsg) error { + log.Trace("received request", "peer", sp.ID(), "hash", req.Addr) + handleRetrieveRequestMsgCount.Inc(1) + + var osp opentracing.Span + ctx, osp = spancontext.StartSpan( + ctx, + "retrieve.request") + defer osp.Finish() + + s, err := sp.getServer(NewStream(swarmChunkServerStreamName, "", false)) + if err != nil { + return err + } + streamer := s.Server.(*SwarmChunkServer) + chunk, created := d.db.GetOrCreateRequest(ctx, req.Addr) + if chunk.ReqC != nil { + if created { + if err := d.RequestFromPeers(ctx, chunk.Addr[:], true, sp.ID()); err != nil { + log.Warn("unable to forward chunk request", "peer", sp.ID(), "key", chunk.Addr, "err", err) + chunk.SetErrored(storage.ErrChunkForward) + return nil + } + } + go func() { + var osp opentracing.Span + ctx, osp = spancontext.StartSpan( + ctx, + "waiting.delivery") + defer osp.Finish() + + t := time.NewTimer(10 * time.Minute) + defer t.Stop() + + log.Debug("waiting delivery", "peer", sp.ID(), "hash", req.Addr, "node", common.Bytes2Hex(d.overlay.BaseAddr()), "created", created) + start := time.Now() + select { + case <-chunk.ReqC: + log.Debug("retrieve request ReqC closed", "peer", sp.ID(), "hash", req.Addr, "time", time.Since(start)) + case <-t.C: + log.Debug("retrieve request timeout", "peer", sp.ID(), "hash", req.Addr) + chunk.SetErrored(storage.ErrChunkTimeout) + return + } + chunk.SetErrored(nil) + + if req.SkipCheck { + err := sp.Deliver(ctx, chunk, s.priority) + if err != nil { + log.Warn("ERROR in handleRetrieveRequestMsg, DROPPING peer!", "err", err) + sp.Drop(err) + } + } + streamer.deliveryC <- chunk.Addr[:] + }() + return nil + } + // TODO: call the retrieve function of the outgoing syncer + if req.SkipCheck { + log.Trace("deliver", "peer", sp.ID(), "hash", chunk.Addr) + if length := len(chunk.SData); length < 9 { + log.Error("Chunk.SData to deliver is too short", "len(chunk.SData)", length, "address", chunk.Addr) + } + return sp.Deliver(ctx, chunk, s.priority) + } + streamer.deliveryC <- chunk.Addr[:] + return nil +} + +type ChunkDeliveryMsg struct { + Addr storage.Address + SData []byte // the stored chunk Data (incl size) + peer *Peer // set in handleChunkDeliveryMsg +} + +func (d *Delivery) handleChunkDeliveryMsg(ctx context.Context, sp *Peer, req *ChunkDeliveryMsg) error { + var osp opentracing.Span + ctx, osp = spancontext.StartSpan( + ctx, + "chunk.delivery") + defer osp.Finish() + + req.peer = sp + d.receiveC <- req + return nil +} + +func (d *Delivery) processReceivedChunks() { +R: + for req := range d.receiveC { + processReceivedChunksCount.Inc(1) + + // this should be has locally + chunk, err := d.db.Get(context.TODO(), req.Addr) + if err == nil { + continue R + } + if err != storage.ErrFetching { + log.Error("processReceivedChunks db error", "addr", req.Addr, "err", err, "chunk", chunk) + continue R + } + select { + case <-chunk.ReqC: + log.Error("someone else delivered?", "hash", chunk.Addr.Hex()) + continue R + default: + } + chunk.SData = req.SData + d.db.Put(context.TODO(), chunk) + + go func(req *ChunkDeliveryMsg) { + err := chunk.WaitToStore() + if err == storage.ErrChunkInvalid { + req.peer.Drop(err) + } + }(req) + } +} + +// RequestFromPeers sends a chunk retrieve request to +func (d *Delivery) RequestFromPeers(ctx context.Context, hash []byte, skipCheck bool, peersToSkip ...discover.NodeID) error { + var success bool + var err error + requestFromPeersCount.Inc(1) + + d.overlay.EachConn(hash, 255, func(p network.OverlayConn, po int, nn bool) bool { + spId := p.(network.Peer).ID() + for _, p := range peersToSkip { + if p == spId { + log.Trace("Delivery.RequestFromPeers: skip peer", "peer", spId) + return true + } + } + sp := d.getPeer(spId) + if sp == nil { + log.Warn("Delivery.RequestFromPeers: peer not found", "id", spId) + return true + } + err = sp.SendPriority(ctx, &RetrieveRequestMsg{ + Addr: hash, + SkipCheck: skipCheck, + }, Top) + if err != nil { + return true + } + requestFromPeersEachCount.Inc(1) + success = true + return false + }) + if success { + return nil + } + return errors.New("no peer found") +} diff --git a/swarm/network/stream/delivery_test.go b/swarm/network/stream/delivery_test.go new file mode 100644 index 0000000000..ae007e5b0a --- /dev/null +++ b/swarm/network/stream/delivery_test.go @@ -0,0 +1,641 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package stream + +import ( + "bytes" + "context" + crand "crypto/rand" + "fmt" + "io" + "os" + "sync" + "testing" + "time" + + "github.com/ethereum/go-ethereum/node" + "github.com/ethereum/go-ethereum/p2p" + "github.com/ethereum/go-ethereum/p2p/simulations/adapters" + p2ptest "github.com/ethereum/go-ethereum/p2p/testing" + "github.com/ethereum/go-ethereum/swarm/log" + "github.com/ethereum/go-ethereum/swarm/network" + "github.com/ethereum/go-ethereum/swarm/network/simulation" + "github.com/ethereum/go-ethereum/swarm/state" + "github.com/ethereum/go-ethereum/swarm/storage" +) + +func TestStreamerRetrieveRequest(t *testing.T) { + tester, streamer, _, teardown, err := newStreamerTester(t) + defer teardown() + if err != nil { + t.Fatal(err) + } + + peerID := tester.IDs[0] + + streamer.delivery.RequestFromPeers(context.TODO(), hash0[:], true) + + err = tester.TestExchanges(p2ptest.Exchange{ + Label: "RetrieveRequestMsg", + Expects: []p2ptest.Expect{ + { + Code: 5, + Msg: &RetrieveRequestMsg{ + Addr: hash0[:], + SkipCheck: true, + }, + Peer: peerID, + }, + }, + }) + + if err != nil { + t.Fatalf("Expected no error, got %v", err) + } +} + +func TestStreamerUpstreamRetrieveRequestMsgExchangeWithoutStore(t *testing.T) { + tester, streamer, _, teardown, err := newStreamerTester(t) + defer teardown() + if err != nil { + t.Fatal(err) + } + + peerID := tester.IDs[0] + + chunk := storage.NewChunk(storage.Address(hash0[:]), nil) + + peer := streamer.getPeer(peerID) + + peer.handleSubscribeMsg(context.TODO(), &SubscribeMsg{ + Stream: NewStream(swarmChunkServerStreamName, "", false), + History: nil, + Priority: Top, + }) + + err = tester.TestExchanges(p2ptest.Exchange{ + Label: "RetrieveRequestMsg", + Triggers: []p2ptest.Trigger{ + { + Code: 5, + Msg: &RetrieveRequestMsg{ + Addr: chunk.Addr[:], + }, + Peer: peerID, + }, + }, + Expects: []p2ptest.Expect{ + { + Code: 1, + Msg: &OfferedHashesMsg{ + HandoverProof: nil, + Hashes: nil, + From: 0, + To: 0, + }, + Peer: peerID, + }, + }, + }) + + expectedError := `exchange #0 "RetrieveRequestMsg": timed out` + if err == nil || err.Error() != expectedError { + t.Fatalf("Expected error %v, got %v", expectedError, err) + } +} + +// upstream request server receives a retrieve Request and responds with +// offered hashes or delivery if skipHash is set to true +func TestStreamerUpstreamRetrieveRequestMsgExchange(t *testing.T) { + tester, streamer, localStore, teardown, err := newStreamerTester(t) + defer teardown() + if err != nil { + t.Fatal(err) + } + + peerID := tester.IDs[0] + peer := streamer.getPeer(peerID) + + stream := NewStream(swarmChunkServerStreamName, "", false) + + peer.handleSubscribeMsg(context.TODO(), &SubscribeMsg{ + Stream: stream, + History: nil, + Priority: Top, + }) + + hash := storage.Address(hash0[:]) + chunk := storage.NewChunk(hash, nil) + chunk.SData = hash + localStore.Put(context.TODO(), chunk) + chunk.WaitToStore() + + err = tester.TestExchanges(p2ptest.Exchange{ + Label: "RetrieveRequestMsg", + Triggers: []p2ptest.Trigger{ + { + Code: 5, + Msg: &RetrieveRequestMsg{ + Addr: hash, + }, + Peer: peerID, + }, + }, + Expects: []p2ptest.Expect{ + { + Code: 1, + Msg: &OfferedHashesMsg{ + HandoverProof: &HandoverProof{ + Handover: &Handover{}, + }, + Hashes: hash, + From: 0, + // TODO: why is this 32??? + To: 32, + Stream: stream, + }, + Peer: peerID, + }, + }, + }) + + if err != nil { + t.Fatal(err) + } + + hash = storage.Address(hash1[:]) + chunk = storage.NewChunk(hash, nil) + chunk.SData = hash1[:] + localStore.Put(context.TODO(), chunk) + chunk.WaitToStore() + + err = tester.TestExchanges(p2ptest.Exchange{ + Label: "RetrieveRequestMsg", + Triggers: []p2ptest.Trigger{ + { + Code: 5, + Msg: &RetrieveRequestMsg{ + Addr: hash, + SkipCheck: true, + }, + Peer: peerID, + }, + }, + Expects: []p2ptest.Expect{ + { + Code: 6, + Msg: &ChunkDeliveryMsg{ + Addr: hash, + SData: hash, + }, + Peer: peerID, + }, + }, + }) + + if err != nil { + t.Fatal(err) + } +} + +func TestStreamerDownstreamChunkDeliveryMsgExchange(t *testing.T) { + tester, streamer, localStore, teardown, err := newStreamerTester(t) + defer teardown() + if err != nil { + t.Fatal(err) + } + + streamer.RegisterClientFunc("foo", func(p *Peer, t string, live bool) (Client, error) { + return &testClient{ + t: t, + }, nil + }) + + peerID := tester.IDs[0] + + stream := NewStream("foo", "", true) + err = streamer.Subscribe(peerID, stream, NewRange(5, 8), Top) + if err != nil { + t.Fatalf("Expected no error, got %v", err) + } + + chunkKey := hash0[:] + chunkData := hash1[:] + chunk, created := localStore.GetOrCreateRequest(context.TODO(), chunkKey) + + if !created { + t.Fatal("chunk already exists") + } + select { + case <-chunk.ReqC: + t.Fatal("chunk is already received") + default: + } + + err = tester.TestExchanges(p2ptest.Exchange{ + Label: "Subscribe message", + Expects: []p2ptest.Expect{ + { + Code: 4, + Msg: &SubscribeMsg{ + Stream: stream, + History: NewRange(5, 8), + Priority: Top, + }, + Peer: peerID, + }, + }, + }, + p2ptest.Exchange{ + Label: "ChunkDeliveryRequest message", + Triggers: []p2ptest.Trigger{ + { + Code: 6, + Msg: &ChunkDeliveryMsg{ + Addr: chunkKey, + SData: chunkData, + }, + Peer: peerID, + }, + }, + }) + + if err != nil { + t.Fatalf("Expected no error, got %v", err) + } + + timeout := time.NewTimer(1 * time.Second) + + select { + case <-timeout.C: + t.Fatal("timeout receiving chunk") + case <-chunk.ReqC: + } + + storedChunk, err := localStore.Get(context.TODO(), chunkKey) + if err != nil { + t.Fatalf("Expected no error, got %v", err) + } + + if !bytes.Equal(storedChunk.SData, chunkData) { + t.Fatal("Retrieved chunk has different data than original") + } + +} + +func TestDeliveryFromNodes(t *testing.T) { + testDeliveryFromNodes(t, 2, 1, dataChunkCount, true) + testDeliveryFromNodes(t, 2, 1, dataChunkCount, false) + testDeliveryFromNodes(t, 4, 1, dataChunkCount, true) + testDeliveryFromNodes(t, 4, 1, dataChunkCount, false) + testDeliveryFromNodes(t, 8, 1, dataChunkCount, true) + testDeliveryFromNodes(t, 8, 1, dataChunkCount, false) + testDeliveryFromNodes(t, 16, 1, dataChunkCount, true) + testDeliveryFromNodes(t, 16, 1, dataChunkCount, false) +} + +func testDeliveryFromNodes(t *testing.T, nodes, conns, chunkCount int, skipCheck bool) { + sim := simulation.New(map[string]simulation.ServiceFunc{ + "streamer": func(ctx *adapters.ServiceContext, bucket *sync.Map) (s node.Service, cleanup func(), err error) { + + id := ctx.Config.ID + addr := network.NewAddrFromNodeID(id) + store, datadir, err := createTestLocalStorageForID(id, addr) + if err != nil { + return nil, nil, err + } + bucket.Store(bucketKeyStore, store) + cleanup = func() { + os.RemoveAll(datadir) + store.Close() + } + localStore := store.(*storage.LocalStore) + db := storage.NewDBAPI(localStore) + kad := network.NewKademlia(addr.Over(), network.NewKadParams()) + delivery := NewDelivery(kad, db) + + r := NewRegistry(addr, delivery, db, state.NewInmemoryStore(), &RegistryOptions{ + SkipCheck: skipCheck, + }) + bucket.Store(bucketKeyRegistry, r) + + retrieveFunc := func(ctx context.Context, chunk *storage.Chunk) error { + return delivery.RequestFromPeers(ctx, chunk.Addr[:], skipCheck) + } + netStore := storage.NewNetStore(localStore, retrieveFunc) + fileStore := storage.NewFileStore(netStore, storage.NewFileStoreParams()) + bucket.Store(bucketKeyFileStore, fileStore) + + return r, cleanup, nil + + }, + }) + defer sim.Close() + + log.Info("Adding nodes to simulation") + _, err := sim.AddNodesAndConnectChain(nodes) + if err != nil { + t.Fatal(err) + } + + log.Info("Starting simulation") + ctx := context.Background() + result := sim.Run(ctx, func(ctx context.Context, sim *simulation.Simulation) error { + nodeIDs := sim.UpNodeIDs() + //determine the pivot node to be the first node of the simulation + sim.SetPivotNode(nodeIDs[0]) + //distribute chunks of a random file into Stores of nodes 1 to nodes + //we will do this by creating a file store with an underlying round-robin store: + //the file store will create a hash for the uploaded file, but every chunk will be + //distributed to different nodes via round-robin scheduling + log.Debug("Writing file to round-robin file store") + //to do this, we create an array for chunkstores (length minus one, the pivot node) + stores := make([]storage.ChunkStore, len(nodeIDs)-1) + //we then need to get all stores from the sim.... + lStores := sim.NodesItems(bucketKeyStore) + i := 0 + //...iterate the buckets... + for id, bucketVal := range lStores { + //...and remove the one which is the pivot node + if id == *sim.PivotNodeID() { + continue + } + //the other ones are added to the array... + stores[i] = bucketVal.(storage.ChunkStore) + i++ + } + //...which then gets passed to the round-robin file store + roundRobinFileStore := storage.NewFileStore(newRoundRobinStore(stores...), storage.NewFileStoreParams()) + //now we can actually upload a (random) file to the round-robin store + size := chunkCount * chunkSize + log.Debug("Storing data to file store") + fileHash, wait, err := roundRobinFileStore.Store(ctx, io.LimitReader(crand.Reader, int64(size)), int64(size), false) + // wait until all chunks stored + if err != nil { + return err + } + err = wait(ctx) + if err != nil { + return err + } + + //each of the nodes (except pivot node) subscribes to the stream of the next node + for j, node := range nodeIDs[0 : nodes-1] { + sid := nodeIDs[j+1] + item, ok := sim.NodeItem(node, bucketKeyRegistry) + if !ok { + return fmt.Errorf("No registry") + } + registry := item.(*Registry) + err = registry.Subscribe(sid, NewStream(swarmChunkServerStreamName, "", false), NewRange(0, 0), Top) + if err != nil { + return err + } + } + + //get the pivot node's filestore + item, ok := sim.NodeItem(*sim.PivotNodeID(), bucketKeyFileStore) + if !ok { + return fmt.Errorf("No filestore") + } + pivotFileStore := item.(*storage.FileStore) + log.Debug("Starting retrieval routine") + go func() { + // start the retrieval on the pivot node - this will spawn retrieve requests for missing chunks + // we must wait for the peer connections to have started before requesting + n, err := readAll(pivotFileStore, fileHash) + log.Info(fmt.Sprintf("retrieved %v", fileHash), "read", n, "err", err) + if err != nil { + t.Fatalf("requesting chunks action error: %v", err) + } + }() + + log.Debug("Waiting for kademlia") + if _, err := sim.WaitTillHealthy(ctx, 2); err != nil { + return err + } + + log.Debug("Watching for disconnections") + disconnections := sim.PeerEvents( + context.Background(), + sim.NodeIDs(), + simulation.NewPeerEventsFilter().Type(p2p.PeerEventTypeDrop), + ) + + go func() { + for d := range disconnections { + if d.Error != nil { + log.Error("peer drop", "node", d.NodeID, "peer", d.Event.Peer) + t.Fatal(d.Error) + } + } + }() + + //finally check that the pivot node gets all chunks via the root hash + log.Debug("Check retrieval") + success := true + var total int64 + total, err = readAll(pivotFileStore, fileHash) + if err != nil { + return err + } + log.Info(fmt.Sprintf("check if %08x is available locally: number of bytes read %v/%v (error: %v)", fileHash, total, size, err)) + if err != nil || total != int64(size) { + success = false + } + + if !success { + return fmt.Errorf("Test failed, chunks not available on all nodes") + } + log.Debug("Test terminated successfully") + return nil + }) + if result.Error != nil { + t.Fatal(result.Error) + } +} + +func BenchmarkDeliveryFromNodesWithoutCheck(b *testing.B) { + for chunks := 32; chunks <= 128; chunks *= 2 { + for i := 2; i < 32; i *= 2 { + b.Run( + fmt.Sprintf("nodes=%v,chunks=%v", i, chunks), + func(b *testing.B) { + benchmarkDeliveryFromNodes(b, i, 1, chunks, true) + }, + ) + } + } +} + +func BenchmarkDeliveryFromNodesWithCheck(b *testing.B) { + for chunks := 32; chunks <= 128; chunks *= 2 { + for i := 2; i < 32; i *= 2 { + b.Run( + fmt.Sprintf("nodes=%v,chunks=%v", i, chunks), + func(b *testing.B) { + benchmarkDeliveryFromNodes(b, i, 1, chunks, false) + }, + ) + } + } +} + +func benchmarkDeliveryFromNodes(b *testing.B, nodes, conns, chunkCount int, skipCheck bool) { + sim := simulation.New(map[string]simulation.ServiceFunc{ + "streamer": func(ctx *adapters.ServiceContext, bucket *sync.Map) (s node.Service, cleanup func(), err error) { + + id := ctx.Config.ID + addr := network.NewAddrFromNodeID(id) + store, datadir, err := createTestLocalStorageForID(id, addr) + if err != nil { + return nil, nil, err + } + bucket.Store(bucketKeyStore, store) + cleanup = func() { + os.RemoveAll(datadir) + store.Close() + } + localStore := store.(*storage.LocalStore) + db := storage.NewDBAPI(localStore) + kad := network.NewKademlia(addr.Over(), network.NewKadParams()) + delivery := NewDelivery(kad, db) + + r := NewRegistry(addr, delivery, db, state.NewInmemoryStore(), &RegistryOptions{ + SkipCheck: skipCheck, + DoSync: true, + SyncUpdateDelay: 0, + }) + + retrieveFunc := func(ctx context.Context, chunk *storage.Chunk) error { + return delivery.RequestFromPeers(ctx, chunk.Addr[:], skipCheck) + } + netStore := storage.NewNetStore(localStore, retrieveFunc) + fileStore := storage.NewFileStore(netStore, storage.NewFileStoreParams()) + bucket.Store(bucketKeyFileStore, fileStore) + + return r, cleanup, nil + + }, + }) + defer sim.Close() + + log.Info("Initializing test config") + _, err := sim.AddNodesAndConnectChain(nodes) + if err != nil { + b.Fatal(err) + } + + ctx := context.Background() + result := sim.Run(ctx, func(ctx context.Context, sim *simulation.Simulation) error { + nodeIDs := sim.UpNodeIDs() + node := nodeIDs[len(nodeIDs)-1] + + item, ok := sim.NodeItem(node, bucketKeyFileStore) + if !ok { + b.Fatal("No filestore") + } + remoteFileStore := item.(*storage.FileStore) + + pivotNode := nodeIDs[0] + item, ok = sim.NodeItem(pivotNode, bucketKeyNetStore) + if !ok { + b.Fatal("No filestore") + } + netStore := item.(*storage.NetStore) + + if _, err := sim.WaitTillHealthy(ctx, 2); err != nil { + return err + } + + disconnections := sim.PeerEvents( + context.Background(), + sim.NodeIDs(), + simulation.NewPeerEventsFilter().Type(p2p.PeerEventTypeDrop), + ) + + go func() { + for d := range disconnections { + if d.Error != nil { + log.Error("peer drop", "node", d.NodeID, "peer", d.Event.Peer) + b.Fatal(d.Error) + } + } + }() + // benchmark loop + b.ResetTimer() + b.StopTimer() + Loop: + for i := 0; i < b.N; i++ { + // uploading chunkCount random chunks to the last node + hashes := make([]storage.Address, chunkCount) + for i := 0; i < chunkCount; i++ { + // create actual size real chunks + ctx := context.TODO() + hash, wait, err := remoteFileStore.Store(ctx, io.LimitReader(crand.Reader, int64(chunkSize)), int64(chunkSize), false) + if err != nil { + b.Fatalf("expected no error. got %v", err) + } + // wait until all chunks stored + err = wait(ctx) + if err != nil { + b.Fatalf("expected no error. got %v", err) + } + // collect the hashes + hashes[i] = hash + } + // now benchmark the actual retrieval + // netstore.Get is called for each hash in a go routine and errors are collected + b.StartTimer() + errs := make(chan error) + for _, hash := range hashes { + go func(h storage.Address) { + _, err := netStore.Get(ctx, h) + log.Warn("test check netstore get", "hash", h, "err", err) + errs <- err + }(hash) + } + // count and report retrieval errors + // if there are misses then chunk timeout is too low for the distance and volume (?) + var total, misses int + for err := range errs { + if err != nil { + log.Warn(err.Error()) + misses++ + } + total++ + if total == chunkCount { + break + } + } + b.StopTimer() + + if misses > 0 { + err = fmt.Errorf("%v chunk not found out of %v", misses, total) + break Loop + } + } + if err != nil { + b.Fatal(err) + } + return nil + }) + if result.Error != nil { + b.Fatal(result.Error) + } + +} diff --git a/crypto/randentropy/rand_entropy.go b/swarm/network/stream/intervals/dbstore_test.go similarity index 61% rename from crypto/randentropy/rand_entropy.go rename to swarm/network/stream/intervals/dbstore_test.go index 539d3ac894..6716e593ab 100644 --- a/crypto/randentropy/rand_entropy.go +++ b/swarm/network/stream/intervals/dbstore_test.go @@ -1,4 +1,4 @@ -// Copyright 2015 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 @@ -14,29 +14,29 @@ // You should have received a copy of the GNU Lesser General Public License // along with the go-ethereum library. If not, see . -package randentropy +package intervals import ( - crand "crypto/rand" - "io" + "io/ioutil" + "os" + "testing" + + "github.com/ethereum/go-ethereum/swarm/state" ) -var Reader io.Reader = &randEntropy{} - -type randEntropy struct { -} - -func (*randEntropy) Read(bytes []byte) (n int, err error) { - readBytes := GetEntropyCSPRNG(len(bytes)) - copy(bytes, readBytes) - return len(bytes), nil -} - -func GetEntropyCSPRNG(n int) []byte { - mainBuff := make([]byte, n) - _, err := io.ReadFull(crand.Reader, mainBuff) +// TestDBStore tests basic functionality of DBStore. +func TestDBStore(t *testing.T) { + dir, err := ioutil.TempDir("", "intervals_test_db_store") if err != nil { - panic("reading from crypto/rand failed: " + err.Error()) + panic(err) } - return mainBuff + defer os.RemoveAll(dir) + + store, err := state.NewDBStore(dir) + if err != nil { + t.Fatal(err) + } + defer store.Close() + + testStore(t, store) } diff --git a/swarm/network/stream/intervals/intervals.go b/swarm/network/stream/intervals/intervals.go new file mode 100644 index 0000000000..5fd820da87 --- /dev/null +++ b/swarm/network/stream/intervals/intervals.go @@ -0,0 +1,206 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package intervals + +import ( + "bytes" + "fmt" + "strconv" + "sync" +) + +// Intervals store a list of intervals. Its purpose is to provide +// methods to add new intervals and retrieve missing intervals that +// need to be added. +// It may be used in synchronization of streaming data to persist +// retrieved data ranges between sessions. +type Intervals struct { + start uint64 + ranges [][2]uint64 + mu sync.RWMutex +} + +// New creates a new instance of Intervals. +// Start argument limits the lower bound of intervals. +// No range bellow start bound will be added by Add method or +// returned by Next method. This limit may be used for +// tracking "live" synchronization, where the sync session +// starts from a specific value, and if "live" sync intervals +// need to be merged with historical ones, it can be safely done. +func NewIntervals(start uint64) *Intervals { + return &Intervals{ + start: start, + } +} + +// Add adds a new range to intervals. Range start and end are values +// are both inclusive. +func (i *Intervals) Add(start, end uint64) { + i.mu.Lock() + defer i.mu.Unlock() + + i.add(start, end) +} + +func (i *Intervals) add(start, end uint64) { + if start < i.start { + start = i.start + } + if end < i.start { + return + } + minStartJ := -1 + maxEndJ := -1 + j := 0 + for ; j < len(i.ranges); j++ { + if minStartJ < 0 { + if (start <= i.ranges[j][0] && end+1 >= i.ranges[j][0]) || (start <= i.ranges[j][1]+1 && end+1 >= i.ranges[j][1]) { + if i.ranges[j][0] < start { + start = i.ranges[j][0] + } + minStartJ = j + } + } + if (start <= i.ranges[j][1] && end+1 >= i.ranges[j][1]) || (start <= i.ranges[j][0] && end+1 >= i.ranges[j][0]) { + if i.ranges[j][1] > end { + end = i.ranges[j][1] + } + maxEndJ = j + } + if end+1 <= i.ranges[j][0] { + break + } + } + if minStartJ < 0 && maxEndJ < 0 { + i.ranges = append(i.ranges[:j], append([][2]uint64{{start, end}}, i.ranges[j:]...)...) + return + } + if minStartJ >= 0 { + i.ranges[minStartJ][0] = start + } + if maxEndJ >= 0 { + i.ranges[maxEndJ][1] = end + } + if minStartJ >= 0 && maxEndJ >= 0 && minStartJ != maxEndJ { + i.ranges[maxEndJ][0] = start + i.ranges = append(i.ranges[:minStartJ], i.ranges[maxEndJ:]...) + } +} + +// Merge adds all the intervals from the the m Interval to current one. +func (i *Intervals) Merge(m *Intervals) { + m.mu.RLock() + defer m.mu.RUnlock() + i.mu.Lock() + defer i.mu.Unlock() + + for _, r := range m.ranges { + i.add(r[0], r[1]) + } +} + +// Next returns the first range interval that is not fulfilled. Returned +// start and end values are both inclusive, meaning that the whole range +// including start and end need to be added in order to full the gap +// in intervals. +// Returned value for end is 0 if the next interval is after the whole +// range that is stored in Intervals. Zero end value represents no limit +// on the next interval length. +func (i *Intervals) Next() (start, end uint64) { + i.mu.RLock() + defer i.mu.RUnlock() + + l := len(i.ranges) + if l == 0 { + return i.start, 0 + } + if i.ranges[0][0] != i.start { + return i.start, i.ranges[0][0] - 1 + } + if l == 1 { + return i.ranges[0][1] + 1, 0 + } + return i.ranges[0][1] + 1, i.ranges[1][0] - 1 +} + +// Last returns the value that is at the end of the last interval. +func (i *Intervals) Last() (end uint64) { + i.mu.RLock() + defer i.mu.RUnlock() + + l := len(i.ranges) + if l == 0 { + return 0 + } + return i.ranges[l-1][1] +} + +// String returns a descriptive representation of range intervals +// in [] notation, as a list of two element vectors. +func (i *Intervals) String() string { + return fmt.Sprint(i.ranges) +} + +// MarshalBinary encodes Intervals parameters into a semicolon separated list. +// The first element in the list is base36-encoded start value. The following +// elements are two base36-encoded value ranges separated by comma. +func (i *Intervals) MarshalBinary() (data []byte, err error) { + d := make([][]byte, len(i.ranges)+1) + d[0] = []byte(strconv.FormatUint(i.start, 36)) + for j := range i.ranges { + r := i.ranges[j] + d[j+1] = []byte(strconv.FormatUint(r[0], 36) + "," + strconv.FormatUint(r[1], 36)) + } + return bytes.Join(d, []byte(";")), nil +} + +// UnmarshalBinary decodes data according to the Intervals.MarshalBinary format. +func (i *Intervals) UnmarshalBinary(data []byte) (err error) { + d := bytes.Split(data, []byte(";")) + l := len(d) + if l == 0 { + return nil + } + if l >= 1 { + i.start, err = strconv.ParseUint(string(d[0]), 36, 64) + if err != nil { + return err + } + } + if l == 1 { + return nil + } + + i.ranges = make([][2]uint64, 0, l-1) + for j := 1; j < l; j++ { + r := bytes.SplitN(d[j], []byte(","), 2) + if len(r) < 2 { + return fmt.Errorf("range %d has less then 2 elements", j) + } + start, err := strconv.ParseUint(string(r[0]), 36, 64) + if err != nil { + return fmt.Errorf("parsing the first element in range %d: %v", j, err) + } + end, err := strconv.ParseUint(string(r[1]), 36, 64) + if err != nil { + return fmt.Errorf("parsing the second element in range %d: %v", j, err) + } + i.ranges = append(i.ranges, [2]uint64{start, end}) + } + + return nil +} diff --git a/swarm/network/stream/intervals/intervals_test.go b/swarm/network/stream/intervals/intervals_test.go new file mode 100644 index 0000000000..b5212f0d91 --- /dev/null +++ b/swarm/network/stream/intervals/intervals_test.go @@ -0,0 +1,395 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package intervals + +import "testing" + +// Test tests Interval methods Add, Next and Last for various +// initial state. +func Test(t *testing.T) { + for i, tc := range []struct { + startLimit uint64 + initial [][2]uint64 + start uint64 + end uint64 + expected string + nextStart uint64 + nextEnd uint64 + last uint64 + }{ + { + initial: nil, + start: 0, + end: 0, + expected: "[[0 0]]", + nextStart: 1, + nextEnd: 0, + last: 0, + }, + { + initial: nil, + start: 0, + end: 10, + expected: "[[0 10]]", + nextStart: 11, + nextEnd: 0, + last: 10, + }, + { + initial: nil, + start: 5, + end: 15, + expected: "[[5 15]]", + nextStart: 0, + nextEnd: 4, + last: 15, + }, + { + initial: [][2]uint64{{0, 0}}, + start: 0, + end: 0, + expected: "[[0 0]]", + nextStart: 1, + nextEnd: 0, + last: 0, + }, + { + initial: [][2]uint64{{0, 0}}, + start: 5, + end: 15, + expected: "[[0 0] [5 15]]", + nextStart: 1, + nextEnd: 4, + last: 15, + }, + { + initial: [][2]uint64{{5, 15}}, + start: 5, + end: 15, + expected: "[[5 15]]", + nextStart: 0, + nextEnd: 4, + last: 15, + }, + { + initial: [][2]uint64{{5, 15}}, + start: 5, + end: 20, + expected: "[[5 20]]", + nextStart: 0, + nextEnd: 4, + last: 20, + }, + { + initial: [][2]uint64{{5, 15}}, + start: 10, + end: 20, + expected: "[[5 20]]", + nextStart: 0, + nextEnd: 4, + last: 20, + }, + { + initial: [][2]uint64{{5, 15}}, + start: 0, + end: 20, + expected: "[[0 20]]", + nextStart: 21, + nextEnd: 0, + last: 20, + }, + { + initial: [][2]uint64{{5, 15}}, + start: 2, + end: 10, + expected: "[[2 15]]", + nextStart: 0, + nextEnd: 1, + last: 15, + }, + { + initial: [][2]uint64{{5, 15}}, + start: 2, + end: 4, + expected: "[[2 15]]", + nextStart: 0, + nextEnd: 1, + last: 15, + }, + { + initial: [][2]uint64{{5, 15}}, + start: 2, + end: 5, + expected: "[[2 15]]", + nextStart: 0, + nextEnd: 1, + last: 15, + }, + { + initial: [][2]uint64{{5, 15}}, + start: 2, + end: 3, + expected: "[[2 3] [5 15]]", + nextStart: 0, + nextEnd: 1, + last: 15, + }, + { + initial: [][2]uint64{{5, 15}}, + start: 2, + end: 4, + expected: "[[2 15]]", + nextStart: 0, + nextEnd: 1, + last: 15, + }, + { + initial: [][2]uint64{{0, 1}, {5, 15}}, + start: 2, + end: 4, + expected: "[[0 15]]", + nextStart: 16, + nextEnd: 0, + last: 15, + }, + { + initial: [][2]uint64{{0, 5}, {15, 20}}, + start: 2, + end: 10, + expected: "[[0 10] [15 20]]", + nextStart: 11, + nextEnd: 14, + last: 20, + }, + { + initial: [][2]uint64{{0, 5}, {15, 20}}, + start: 8, + end: 18, + expected: "[[0 5] [8 20]]", + nextStart: 6, + nextEnd: 7, + last: 20, + }, + { + initial: [][2]uint64{{0, 5}, {15, 20}}, + start: 2, + end: 17, + expected: "[[0 20]]", + nextStart: 21, + nextEnd: 0, + last: 20, + }, + { + initial: [][2]uint64{{0, 5}, {15, 20}}, + start: 2, + end: 25, + expected: "[[0 25]]", + nextStart: 26, + nextEnd: 0, + last: 25, + }, + { + initial: [][2]uint64{{0, 5}, {15, 20}}, + start: 5, + end: 14, + expected: "[[0 20]]", + nextStart: 21, + nextEnd: 0, + last: 20, + }, + { + initial: [][2]uint64{{0, 5}, {15, 20}}, + start: 6, + end: 14, + expected: "[[0 20]]", + nextStart: 21, + nextEnd: 0, + last: 20, + }, + { + initial: [][2]uint64{{0, 5}, {15, 20}, {30, 40}}, + start: 6, + end: 29, + expected: "[[0 40]]", + nextStart: 41, + nextEnd: 0, + last: 40, + }, + { + initial: [][2]uint64{{0, 5}, {15, 20}, {30, 40}, {50, 60}}, + start: 3, + end: 55, + expected: "[[0 60]]", + nextStart: 61, + nextEnd: 0, + last: 60, + }, + { + initial: [][2]uint64{{0, 5}, {15, 20}, {30, 40}, {50, 60}}, + start: 21, + end: 49, + expected: "[[0 5] [15 60]]", + nextStart: 6, + nextEnd: 14, + last: 60, + }, + { + initial: [][2]uint64{{0, 5}, {15, 20}, {30, 40}, {50, 60}}, + start: 0, + end: 100, + expected: "[[0 100]]", + nextStart: 101, + nextEnd: 0, + last: 100, + }, + { + startLimit: 100, + initial: nil, + start: 0, + end: 0, + expected: "[]", + nextStart: 100, + nextEnd: 0, + last: 0, + }, + { + startLimit: 100, + initial: nil, + start: 20, + end: 30, + expected: "[]", + nextStart: 100, + nextEnd: 0, + last: 0, + }, + { + startLimit: 100, + initial: nil, + start: 50, + end: 100, + expected: "[[100 100]]", + nextStart: 101, + nextEnd: 0, + last: 100, + }, + { + startLimit: 100, + initial: nil, + start: 50, + end: 110, + expected: "[[100 110]]", + nextStart: 111, + nextEnd: 0, + last: 110, + }, + { + startLimit: 100, + initial: nil, + start: 120, + end: 130, + expected: "[[120 130]]", + nextStart: 100, + nextEnd: 119, + last: 130, + }, + { + startLimit: 100, + initial: nil, + start: 120, + end: 130, + expected: "[[120 130]]", + nextStart: 100, + nextEnd: 119, + last: 130, + }, + } { + intervals := NewIntervals(tc.startLimit) + intervals.ranges = tc.initial + intervals.Add(tc.start, tc.end) + got := intervals.String() + if got != tc.expected { + t.Errorf("interval #%d: expected %s, got %s", i, tc.expected, got) + } + nextStart, nextEnd := intervals.Next() + if nextStart != tc.nextStart { + t.Errorf("interval #%d, expected next start %d, got %d", i, tc.nextStart, nextStart) + } + if nextEnd != tc.nextEnd { + t.Errorf("interval #%d, expected next end %d, got %d", i, tc.nextEnd, nextEnd) + } + last := intervals.Last() + if last != tc.last { + t.Errorf("interval #%d, expected last %d, got %d", i, tc.last, last) + } + } +} + +func TestMerge(t *testing.T) { + for i, tc := range []struct { + initial [][2]uint64 + merge [][2]uint64 + expected string + }{ + { + initial: nil, + merge: nil, + expected: "[]", + }, + { + initial: [][2]uint64{{10, 20}}, + merge: nil, + expected: "[[10 20]]", + }, + { + initial: nil, + merge: [][2]uint64{{15, 25}}, + expected: "[[15 25]]", + }, + { + initial: [][2]uint64{{0, 100}}, + merge: [][2]uint64{{150, 250}}, + expected: "[[0 100] [150 250]]", + }, + { + initial: [][2]uint64{{0, 100}}, + merge: [][2]uint64{{101, 250}}, + expected: "[[0 250]]", + }, + { + initial: [][2]uint64{{0, 10}, {30, 40}}, + merge: [][2]uint64{{20, 25}, {41, 50}}, + expected: "[[0 10] [20 25] [30 50]]", + }, + { + initial: [][2]uint64{{0, 5}, {15, 20}, {30, 40}, {50, 60}}, + merge: [][2]uint64{{6, 25}}, + expected: "[[0 25] [30 40] [50 60]]", + }, + } { + intervals := NewIntervals(0) + intervals.ranges = tc.initial + m := NewIntervals(0) + m.ranges = tc.merge + + intervals.Merge(m) + + got := intervals.String() + if got != tc.expected { + t.Errorf("interval #%d: expected %s, got %s", i, tc.expected, got) + } + } +} diff --git a/swarm/network/stream/intervals/store_test.go b/swarm/network/stream/intervals/store_test.go new file mode 100644 index 0000000000..0ab14c065c --- /dev/null +++ b/swarm/network/stream/intervals/store_test.go @@ -0,0 +1,80 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package intervals + +import ( + "errors" + "testing" + + "github.com/ethereum/go-ethereum/swarm/state" +) + +var ErrNotFound = errors.New("not found") + +// TestInmemoryStore tests basic functionality of InmemoryStore. +func TestInmemoryStore(t *testing.T) { + testStore(t, state.NewInmemoryStore()) +} + +// testStore is a helper function to test various Store implementations. +func testStore(t *testing.T, s state.Store) { + key1 := "key1" + i1 := NewIntervals(0) + i1.Add(10, 20) + if err := s.Put(key1, i1); err != nil { + t.Fatal(err) + } + i := &Intervals{} + err := s.Get(key1, i) + if err != nil { + t.Fatal(err) + } + if i.String() != i1.String() { + t.Errorf("expected interval %s, got %s", i1, i) + } + + key2 := "key2" + i2 := NewIntervals(0) + i2.Add(10, 20) + if err := s.Put(key2, i2); err != nil { + t.Fatal(err) + } + err = s.Get(key2, i) + if err != nil { + t.Fatal(err) + } + if i.String() != i2.String() { + t.Errorf("expected interval %s, got %s", i2, i) + } + + if err := s.Delete(key1); err != nil { + t.Fatal(err) + } + if err := s.Get(key1, i); err != state.ErrNotFound { + t.Errorf("expected error %v, got %s", state.ErrNotFound, err) + } + if err := s.Get(key2, i); err != nil { + t.Errorf("expected error %v, got %s", nil, err) + } + + if err := s.Delete(key2); err != nil { + t.Fatal(err) + } + if err := s.Get(key2, i); err != state.ErrNotFound { + t.Errorf("expected error %v, got %s", state.ErrNotFound, err) + } +} diff --git a/swarm/network/stream/intervals_test.go b/swarm/network/stream/intervals_test.go new file mode 100644 index 0000000000..f4294134b9 --- /dev/null +++ b/swarm/network/stream/intervals_test.go @@ -0,0 +1,387 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package stream + +import ( + "context" + crand "crypto/rand" + "encoding/binary" + "fmt" + "io" + "os" + "sync" + "testing" + "time" + + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/node" + "github.com/ethereum/go-ethereum/p2p" + "github.com/ethereum/go-ethereum/p2p/discover" + "github.com/ethereum/go-ethereum/p2p/simulations/adapters" + "github.com/ethereum/go-ethereum/swarm/network" + "github.com/ethereum/go-ethereum/swarm/network/simulation" + "github.com/ethereum/go-ethereum/swarm/state" + "github.com/ethereum/go-ethereum/swarm/storage" +) + +func TestIntervals(t *testing.T) { + testIntervals(t, true, nil, false) + testIntervals(t, false, NewRange(9, 26), false) + testIntervals(t, true, NewRange(9, 26), false) + + testIntervals(t, true, nil, true) + testIntervals(t, false, NewRange(9, 26), true) + testIntervals(t, true, NewRange(9, 26), true) +} + +func testIntervals(t *testing.T, live bool, history *Range, skipCheck bool) { + nodes := 2 + chunkCount := dataChunkCount + externalStreamName := "externalStream" + externalStreamSessionAt := uint64(50) + externalStreamMaxKeys := uint64(100) + + sim := simulation.New(map[string]simulation.ServiceFunc{ + "intervalsStreamer": func(ctx *adapters.ServiceContext, bucket *sync.Map) (s node.Service, cleanup func(), err error) { + + id := ctx.Config.ID + addr := network.NewAddrFromNodeID(id) + store, datadir, err := createTestLocalStorageForID(id, addr) + if err != nil { + return nil, nil, err + } + bucket.Store(bucketKeyStore, store) + cleanup = func() { + store.Close() + os.RemoveAll(datadir) + } + localStore := store.(*storage.LocalStore) + db := storage.NewDBAPI(localStore) + kad := network.NewKademlia(addr.Over(), network.NewKadParams()) + delivery := NewDelivery(kad, db) + + r := NewRegistry(addr, delivery, db, state.NewInmemoryStore(), &RegistryOptions{ + SkipCheck: skipCheck, + }) + bucket.Store(bucketKeyRegistry, r) + + r.RegisterClientFunc(externalStreamName, func(p *Peer, t string, live bool) (Client, error) { + return newTestExternalClient(db), nil + }) + r.RegisterServerFunc(externalStreamName, func(p *Peer, t string, live bool) (Server, error) { + return newTestExternalServer(t, externalStreamSessionAt, externalStreamMaxKeys, nil), nil + }) + + fileStore := storage.NewFileStore(localStore, storage.NewFileStoreParams()) + bucket.Store(bucketKeyFileStore, fileStore) + + return r, cleanup, nil + + }, + }) + defer sim.Close() + + log.Info("Adding nodes to simulation") + _, err := sim.AddNodesAndConnectChain(nodes) + if err != nil { + t.Fatal(err) + } + + ctx, cancel := context.WithTimeout(context.Background(), 100*time.Second) + defer cancel() + + result := sim.Run(ctx, func(ctx context.Context, sim *simulation.Simulation) error { + nodeIDs := sim.UpNodeIDs() + storer := nodeIDs[0] + checker := nodeIDs[1] + + item, ok := sim.NodeItem(storer, bucketKeyFileStore) + if !ok { + return fmt.Errorf("No filestore") + } + fileStore := item.(*storage.FileStore) + + size := chunkCount * chunkSize + _, wait, err := fileStore.Store(ctx, io.LimitReader(crand.Reader, int64(size)), int64(size), false) + if err != nil { + log.Error("Store error: %v", "err", err) + t.Fatal(err) + } + err = wait(ctx) + if err != nil { + log.Error("Wait error: %v", "err", err) + t.Fatal(err) + } + + item, ok = sim.NodeItem(checker, bucketKeyRegistry) + if !ok { + return fmt.Errorf("No registry") + } + registry := item.(*Registry) + + liveErrC := make(chan error) + historyErrC := make(chan error) + + if _, err := sim.WaitTillHealthy(ctx, 2); err != nil { + log.Error("WaitKademlia error: %v", "err", err) + return err + } + + log.Debug("Watching for disconnections") + disconnections := sim.PeerEvents( + context.Background(), + sim.NodeIDs(), + simulation.NewPeerEventsFilter().Type(p2p.PeerEventTypeDrop), + ) + + go func() { + for d := range disconnections { + if d.Error != nil { + log.Error("peer drop", "node", d.NodeID, "peer", d.Event.Peer) + t.Fatal(d.Error) + } + } + }() + + go func() { + if !live { + close(liveErrC) + return + } + + var err error + defer func() { + liveErrC <- err + }() + + // live stream + var liveHashesChan chan []byte + liveHashesChan, err = getHashes(ctx, registry, storer, NewStream(externalStreamName, "", true)) + if err != nil { + log.Error("Subscription error: %v", "err", err) + return + } + i := externalStreamSessionAt + + // we have subscribed, enable notifications + err = enableNotifications(registry, storer, NewStream(externalStreamName, "", true)) + if err != nil { + return + } + + for { + select { + case hash := <-liveHashesChan: + h := binary.BigEndian.Uint64(hash) + if h != i { + err = fmt.Errorf("expected live hash %d, got %d", i, h) + return + } + i++ + if i > externalStreamMaxKeys { + return + } + case <-ctx.Done(): + return + } + } + }() + + go func() { + if live && history == nil { + close(historyErrC) + return + } + + var err error + defer func() { + historyErrC <- err + }() + + // history stream + var historyHashesChan chan []byte + historyHashesChan, err = getHashes(ctx, registry, storer, NewStream(externalStreamName, "", false)) + if err != nil { + return + } + + var i uint64 + historyTo := externalStreamMaxKeys + if history != nil { + i = history.From + if history.To != 0 { + historyTo = history.To + } + } + + // we have subscribed, enable notifications + err = enableNotifications(registry, storer, NewStream(externalStreamName, "", false)) + if err != nil { + return + } + + for { + select { + case hash := <-historyHashesChan: + h := binary.BigEndian.Uint64(hash) + if h != i { + err = fmt.Errorf("expected history hash %d, got %d", i, h) + return + } + i++ + if i > historyTo { + return + } + case <-ctx.Done(): + return + } + } + }() + + err = registry.Subscribe(storer, NewStream(externalStreamName, "", live), history, Top) + if err != nil { + return err + } + if err := <-liveErrC; err != nil { + return err + } + if err := <-historyErrC; err != nil { + return err + } + + return nil + }) + + if result.Error != nil { + t.Fatal(result.Error) + } +} + +func getHashes(ctx context.Context, r *Registry, peerID discover.NodeID, s Stream) (chan []byte, error) { + peer := r.getPeer(peerID) + + client, err := peer.getClient(ctx, s) + if err != nil { + return nil, err + } + + c := client.Client.(*testExternalClient) + + return c.hashes, nil +} + +func enableNotifications(r *Registry, peerID discover.NodeID, s Stream) error { + peer := r.getPeer(peerID) + + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + + client, err := peer.getClient(ctx, s) + if err != nil { + return err + } + + close(client.Client.(*testExternalClient).enableNotificationsC) + + return nil +} + +type testExternalClient struct { + hashes chan []byte + db *storage.DBAPI + enableNotificationsC chan struct{} +} + +func newTestExternalClient(db *storage.DBAPI) *testExternalClient { + return &testExternalClient{ + hashes: make(chan []byte), + db: db, + enableNotificationsC: make(chan struct{}), + } +} + +func (c *testExternalClient) NeedData(ctx context.Context, hash []byte) func() { + chunk, _ := c.db.GetOrCreateRequest(ctx, hash) + if chunk.ReqC == nil { + return nil + } + c.hashes <- hash + //NOTE: This was failing on go1.9.x with a deadlock. + //Sometimes this function would just block + //It is commented now, but it may be well worth after the chunk refactor + //to re-enable this and see if the problem has been addressed + /* + return func() { + return chunk.WaitToStore() + } + */ + return nil +} + +func (c *testExternalClient) BatchDone(Stream, uint64, []byte, []byte) func() (*TakeoverProof, error) { + return nil +} + +func (c *testExternalClient) Close() {} + +const testExternalServerBatchSize = 10 + +type testExternalServer struct { + t string + keyFunc func(key []byte, index uint64) + sessionAt uint64 + maxKeys uint64 +} + +func newTestExternalServer(t string, sessionAt, maxKeys uint64, keyFunc func(key []byte, index uint64)) *testExternalServer { + if keyFunc == nil { + keyFunc = binary.BigEndian.PutUint64 + } + return &testExternalServer{ + t: t, + keyFunc: keyFunc, + sessionAt: sessionAt, + maxKeys: maxKeys, + } +} + +func (s *testExternalServer) SetNextBatch(from uint64, to uint64) ([]byte, uint64, uint64, *HandoverProof, error) { + if from == 0 && to == 0 { + from = s.sessionAt + to = s.sessionAt + testExternalServerBatchSize + } + if to-from > testExternalServerBatchSize { + to = from + testExternalServerBatchSize - 1 + } + if from >= s.maxKeys && to > s.maxKeys { + return nil, 0, 0, nil, io.EOF + } + if to > s.maxKeys { + to = s.maxKeys + } + b := make([]byte, HashSize*(to-from+1)) + for i := from; i <= to; i++ { + s.keyFunc(b[(i-from)*HashSize:(i-from+1)*HashSize], i) + } + return b, from, to, nil, nil +} + +func (s *testExternalServer) GetData(context.Context, []byte) ([]byte, error) { + return make([]byte, 4096), nil +} + +func (s *testExternalServer) Close() {} diff --git a/swarm/network/stream/messages.go b/swarm/network/stream/messages.go new file mode 100644 index 0000000000..a19f635892 --- /dev/null +++ b/swarm/network/stream/messages.go @@ -0,0 +1,379 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package stream + +import ( + "context" + "errors" + "fmt" + "sync" + "time" + + "github.com/ethereum/go-ethereum/metrics" + "github.com/ethereum/go-ethereum/swarm/log" + bv "github.com/ethereum/go-ethereum/swarm/network/bitvector" + "github.com/ethereum/go-ethereum/swarm/spancontext" + "github.com/ethereum/go-ethereum/swarm/storage" + opentracing "github.com/opentracing/opentracing-go" +) + +// Stream defines a unique stream identifier. +type Stream struct { + // Name is used for Client and Server functions identification. + Name string + // Key is the name of specific stream data. + Key string + // Live defines whether the stream delivers only new data + // for the specific stream. + Live bool +} + +func NewStream(name string, key string, live bool) Stream { + return Stream{ + Name: name, + Key: key, + Live: live, + } +} + +// String return a stream id based on all Stream fields. +func (s Stream) String() string { + t := "h" + if s.Live { + t = "l" + } + return fmt.Sprintf("%s|%s|%s", s.Name, s.Key, t) +} + +// SubcribeMsg is the protocol msg for requesting a stream(section) +type SubscribeMsg struct { + Stream Stream + History *Range `rlp:"nil"` + Priority uint8 // delivered on priority channel +} + +// RequestSubscriptionMsg is the protocol msg for a node to request subscription to a +// specific stream +type RequestSubscriptionMsg struct { + Stream Stream + History *Range `rlp:"nil"` + Priority uint8 // delivered on priority channel +} + +func (p *Peer) handleRequestSubscription(ctx context.Context, req *RequestSubscriptionMsg) (err error) { + log.Debug(fmt.Sprintf("handleRequestSubscription: streamer %s to subscribe to %s with stream %s", p.streamer.addr.ID(), p.ID(), req.Stream)) + return p.streamer.Subscribe(p.ID(), req.Stream, req.History, req.Priority) +} + +func (p *Peer) handleSubscribeMsg(ctx context.Context, req *SubscribeMsg) (err error) { + metrics.GetOrRegisterCounter("peer.handlesubscribemsg", nil).Inc(1) + + defer func() { + if err != nil { + if e := p.Send(context.TODO(), SubscribeErrorMsg{ + Error: err.Error(), + }); e != nil { + log.Error("send stream subscribe error message", "err", err) + } + } + }() + + log.Debug("received subscription", "from", p.streamer.addr.ID(), "peer", p.ID(), "stream", req.Stream, "history", req.History) + + f, err := p.streamer.GetServerFunc(req.Stream.Name) + if err != nil { + return err + } + + s, err := f(p, req.Stream.Key, req.Stream.Live) + if err != nil { + return err + } + os, err := p.setServer(req.Stream, s, req.Priority) + if err != nil { + return err + } + + var from uint64 + var to uint64 + if !req.Stream.Live && req.History != nil { + from = req.History.From + to = req.History.To + } + + go func() { + if err := p.SendOfferedHashes(os, from, to); err != nil { + log.Warn("SendOfferedHashes dropping peer", "err", err) + p.Drop(err) + } + }() + + if req.Stream.Live && req.History != nil { + // subscribe to the history stream + s, err := f(p, req.Stream.Key, false) + if err != nil { + return err + } + + os, err := p.setServer(getHistoryStream(req.Stream), s, getHistoryPriority(req.Priority)) + if err != nil { + return err + } + go func() { + if err := p.SendOfferedHashes(os, req.History.From, req.History.To); err != nil { + log.Warn("SendOfferedHashes dropping peer", "err", err) + p.Drop(err) + } + }() + } + + return nil +} + +type SubscribeErrorMsg struct { + Error string +} + +func (p *Peer) handleSubscribeErrorMsg(req *SubscribeErrorMsg) (err error) { + return fmt.Errorf("subscribe to peer %s: %v", p.ID(), req.Error) +} + +type UnsubscribeMsg struct { + Stream Stream +} + +func (p *Peer) handleUnsubscribeMsg(req *UnsubscribeMsg) error { + return p.removeServer(req.Stream) +} + +type QuitMsg struct { + Stream Stream +} + +func (p *Peer) handleQuitMsg(req *QuitMsg) error { + return p.removeClient(req.Stream) +} + +// OfferedHashesMsg is the protocol msg for offering to hand over a +// stream section +type OfferedHashesMsg struct { + Stream Stream // name of Stream + From, To uint64 // peer and db-specific entry count + Hashes []byte // stream of hashes (128) + *HandoverProof // HandoverProof +} + +// String pretty prints OfferedHashesMsg +func (m OfferedHashesMsg) String() string { + return fmt.Sprintf("Stream '%v' [%v-%v] (%v)", m.Stream, m.From, m.To, len(m.Hashes)/HashSize) +} + +// handleOfferedHashesMsg protocol msg handler calls the incoming streamer interface +// Filter method +func (p *Peer) handleOfferedHashesMsg(ctx context.Context, req *OfferedHashesMsg) error { + metrics.GetOrRegisterCounter("peer.handleofferedhashes", nil).Inc(1) + + var sp opentracing.Span + ctx, sp = spancontext.StartSpan( + ctx, + "handle.offered.hashes") + defer sp.Finish() + + c, _, err := p.getOrSetClient(req.Stream, req.From, req.To) + if err != nil { + return err + } + hashes := req.Hashes + want, err := bv.New(len(hashes) / HashSize) + if err != nil { + return fmt.Errorf("error initiaising bitvector of length %v: %v", len(hashes)/HashSize, err) + } + wg := sync.WaitGroup{} + for i := 0; i < len(hashes); i += HashSize { + hash := hashes[i : i+HashSize] + + if wait := c.NeedData(ctx, hash); wait != nil { + want.Set(i/HashSize, true) + wg.Add(1) + // create request and wait until the chunk data arrives and is stored + go func(w func()) { + w() + wg.Done() + }(wait) + } + } + // done := make(chan bool) + // go func() { + // wg.Wait() + // close(done) + // }() + // go func() { + // select { + // case <-done: + // s.next <- s.batchDone(p, req, hashes) + // case <-time.After(1 * time.Second): + // p.Drop(errors.New("timeout waiting for batch to be delivered")) + // } + // }() + go func() { + wg.Wait() + select { + case c.next <- c.batchDone(p, req, hashes): + case <-c.quit: + } + }() + // only send wantedKeysMsg if all missing chunks of the previous batch arrived + // except + if c.stream.Live { + c.sessionAt = req.From + } + from, to := c.nextBatch(req.To + 1) + log.Trace("received offered batch", "peer", p.ID(), "stream", req.Stream, "from", req.From, "to", req.To) + if from == to { + return nil + } + + msg := &WantedHashesMsg{ + Stream: req.Stream, + Want: want.Bytes(), + From: from, + To: to, + } + go func() { + select { + case <-time.After(120 * time.Second): + log.Warn("handleOfferedHashesMsg timeout, so dropping peer") + p.Drop(errors.New("handle offered hashes timeout")) + return + case err := <-c.next: + if err != nil { + log.Warn("c.next dropping peer", "err", err) + p.Drop(err) + return + } + case <-c.quit: + return + } + log.Trace("sending want batch", "peer", p.ID(), "stream", msg.Stream, "from", msg.From, "to", msg.To) + err := p.SendPriority(ctx, msg, c.priority) + if err != nil { + log.Warn("SendPriority err, so dropping peer", "err", err) + p.Drop(err) + } + }() + return nil +} + +// WantedHashesMsg is the protocol msg data for signaling which hashes +// offered in OfferedHashesMsg downstream peer actually wants sent over +type WantedHashesMsg struct { + Stream Stream + Want []byte // bitvector indicating which keys of the batch needed + From, To uint64 // next interval offset - empty if not to be continued +} + +// String pretty prints WantedHashesMsg +func (m WantedHashesMsg) String() string { + return fmt.Sprintf("Stream '%v', Want: %x, Next: [%v-%v]", m.Stream, m.Want, m.From, m.To) +} + +// handleWantedHashesMsg protocol msg handler +// * sends the next batch of unsynced keys +// * sends the actual data chunks as per WantedHashesMsg +func (p *Peer) handleWantedHashesMsg(ctx context.Context, req *WantedHashesMsg) error { + metrics.GetOrRegisterCounter("peer.handlewantedhashesmsg", nil).Inc(1) + + log.Trace("received wanted batch", "peer", p.ID(), "stream", req.Stream, "from", req.From, "to", req.To) + s, err := p.getServer(req.Stream) + if err != nil { + return err + } + hashes := s.currentBatch + // launch in go routine since GetBatch blocks until new hashes arrive + go func() { + if err := p.SendOfferedHashes(s, req.From, req.To); err != nil { + log.Warn("SendOfferedHashes dropping peer", "err", err) + p.Drop(err) + } + }() + // go p.SendOfferedHashes(s, req.From, req.To) + l := len(hashes) / HashSize + + log.Trace("wanted batch length", "peer", p.ID(), "stream", req.Stream, "from", req.From, "to", req.To, "lenhashes", len(hashes), "l", l) + want, err := bv.NewFromBytes(req.Want, l) + if err != nil { + return fmt.Errorf("error initiaising bitvector of length %v: %v", l, err) + } + for i := 0; i < l; i++ { + if want.Get(i) { + metrics.GetOrRegisterCounter("peer.handlewantedhashesmsg.actualget", nil).Inc(1) + + hash := hashes[i*HashSize : (i+1)*HashSize] + data, err := s.GetData(ctx, hash) + if err != nil { + return fmt.Errorf("handleWantedHashesMsg get data %x: %v", hash, err) + } + chunk := storage.NewChunk(hash, nil) + chunk.SData = data + if length := len(chunk.SData); length < 9 { + log.Error("Chunk.SData to sync is too short", "len(chunk.SData)", length, "address", chunk.Addr) + } + if err := p.Deliver(ctx, chunk, s.priority); err != nil { + return err + } + } + } + return nil +} + +// Handover represents a statement that the upstream peer hands over the stream section +type Handover struct { + Stream Stream // name of stream + Start, End uint64 // index of hashes + Root []byte // Root hash for indexed segment inclusion proofs +} + +// HandoverProof represents a signed statement that the upstream peer handed over the stream section +type HandoverProof struct { + Sig []byte // Sign(Hash(Serialisation(Handover))) + *Handover +} + +// Takeover represents a statement that downstream peer took over (stored all data) +// handed over +type Takeover Handover + +// TakeoverProof represents a signed statement that the downstream peer took over +// the stream section +type TakeoverProof struct { + Sig []byte // Sign(Hash(Serialisation(Takeover))) + *Takeover +} + +// TakeoverProofMsg is the protocol msg sent by downstream peer +type TakeoverProofMsg TakeoverProof + +// String pretty prints TakeoverProofMsg +func (m TakeoverProofMsg) String() string { + return fmt.Sprintf("Stream: '%v' [%v-%v], Root: %x, Sig: %x", m.Stream, m.Start, m.End, m.Root, m.Sig) +} + +func (p *Peer) handleTakeoverProofMsg(ctx context.Context, req *TakeoverProofMsg) error { + _, err := p.getServer(req.Stream) + // store the strongest takeoverproof for the stream in streamer + return err +} diff --git a/swarm/network/stream/peer.go b/swarm/network/stream/peer.go new file mode 100644 index 0000000000..80b9ab711a --- /dev/null +++ b/swarm/network/stream/peer.go @@ -0,0 +1,354 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package stream + +import ( + "context" + "fmt" + "sync" + "time" + + "github.com/ethereum/go-ethereum/metrics" + "github.com/ethereum/go-ethereum/p2p/protocols" + "github.com/ethereum/go-ethereum/swarm/log" + pq "github.com/ethereum/go-ethereum/swarm/network/priorityqueue" + "github.com/ethereum/go-ethereum/swarm/network/stream/intervals" + "github.com/ethereum/go-ethereum/swarm/spancontext" + "github.com/ethereum/go-ethereum/swarm/state" + "github.com/ethereum/go-ethereum/swarm/storage" + opentracing "github.com/opentracing/opentracing-go" +) + +var sendTimeout = 30 * time.Second + +type notFoundError struct { + t string + s Stream +} + +func newNotFoundError(t string, s Stream) *notFoundError { + return ¬FoundError{t: t, s: s} +} + +func (e *notFoundError) Error() string { + return fmt.Sprintf("%s not found for stream %q", e.t, e.s) +} + +// Peer is the Peer extension for the streaming protocol +type Peer struct { + *protocols.Peer + streamer *Registry + pq *pq.PriorityQueue + serverMu sync.RWMutex + clientMu sync.RWMutex // protects both clients and clientParams + servers map[Stream]*server + clients map[Stream]*client + // clientParams map keeps required client arguments + // that are set on Registry.Subscribe and used + // on creating a new client in offered hashes handler. + clientParams map[Stream]*clientParams + quit chan struct{} +} + +type WrappedPriorityMsg struct { + Context context.Context + Msg interface{} +} + +// NewPeer is the constructor for Peer +func NewPeer(peer *protocols.Peer, streamer *Registry) *Peer { + p := &Peer{ + Peer: peer, + pq: pq.New(int(PriorityQueue), PriorityQueueCap), + streamer: streamer, + servers: make(map[Stream]*server), + clients: make(map[Stream]*client), + clientParams: make(map[Stream]*clientParams), + quit: make(chan struct{}), + } + ctx, cancel := context.WithCancel(context.Background()) + go p.pq.Run(ctx, func(i interface{}) { + wmsg := i.(WrappedPriorityMsg) + p.Send(wmsg.Context, wmsg.Msg) + }) + go func() { + <-p.quit + cancel() + }() + return p +} + +// Deliver sends a storeRequestMsg protocol message to the peer +func (p *Peer) Deliver(ctx context.Context, chunk *storage.Chunk, priority uint8) error { + var sp opentracing.Span + ctx, sp = spancontext.StartSpan( + ctx, + "send.chunk.delivery") + defer sp.Finish() + + msg := &ChunkDeliveryMsg{ + Addr: chunk.Addr, + SData: chunk.SData, + } + return p.SendPriority(ctx, msg, priority) +} + +// SendPriority sends message to the peer using the outgoing priority queue +func (p *Peer) SendPriority(ctx context.Context, msg interface{}, priority uint8) error { + defer metrics.GetOrRegisterResettingTimer(fmt.Sprintf("peer.sendpriority_t.%d", priority), nil).UpdateSince(time.Now()) + metrics.GetOrRegisterCounter(fmt.Sprintf("peer.sendpriority.%d", priority), nil).Inc(1) + cctx, cancel := context.WithTimeout(context.Background(), sendTimeout) + defer cancel() + wmsg := WrappedPriorityMsg{ + Context: ctx, + Msg: msg, + } + return p.pq.Push(cctx, wmsg, int(priority)) +} + +// SendOfferedHashes sends OfferedHashesMsg protocol msg +func (p *Peer) SendOfferedHashes(s *server, f, t uint64) error { + var sp opentracing.Span + ctx, sp := spancontext.StartSpan( + context.TODO(), + "send.offered.hashes") + defer sp.Finish() + + hashes, from, to, proof, err := s.SetNextBatch(f, t) + if err != nil { + return err + } + // true only when quiting + if len(hashes) == 0 { + return nil + } + if proof == nil { + proof = &HandoverProof{ + Handover: &Handover{}, + } + } + s.currentBatch = hashes + msg := &OfferedHashesMsg{ + HandoverProof: proof, + Hashes: hashes, + From: from, + To: to, + Stream: s.stream, + } + log.Trace("Swarm syncer offer batch", "peer", p.ID(), "stream", s.stream, "len", len(hashes), "from", from, "to", to) + return p.SendPriority(ctx, msg, s.priority) +} + +func (p *Peer) getServer(s Stream) (*server, error) { + p.serverMu.RLock() + defer p.serverMu.RUnlock() + + server := p.servers[s] + if server == nil { + return nil, newNotFoundError("server", s) + } + return server, nil +} + +func (p *Peer) setServer(s Stream, o Server, priority uint8) (*server, error) { + p.serverMu.Lock() + defer p.serverMu.Unlock() + + if p.servers[s] != nil { + return nil, fmt.Errorf("server %s already registered", s) + } + os := &server{ + Server: o, + stream: s, + priority: priority, + } + p.servers[s] = os + return os, nil +} + +func (p *Peer) removeServer(s Stream) error { + p.serverMu.Lock() + defer p.serverMu.Unlock() + + server, ok := p.servers[s] + if !ok { + return newNotFoundError("server", s) + } + server.Close() + delete(p.servers, s) + return nil +} + +func (p *Peer) getClient(ctx context.Context, s Stream) (c *client, err error) { + var params *clientParams + func() { + p.clientMu.RLock() + defer p.clientMu.RUnlock() + + c = p.clients[s] + if c != nil { + return + } + params = p.clientParams[s] + }() + if c != nil { + return c, nil + } + + if params != nil { + //debug.PrintStack() + if err := params.waitClient(ctx); err != nil { + return nil, err + } + } + + p.clientMu.RLock() + defer p.clientMu.RUnlock() + + c = p.clients[s] + if c != nil { + return c, nil + } + return nil, newNotFoundError("client", s) +} + +func (p *Peer) getOrSetClient(s Stream, from, to uint64) (c *client, created bool, err error) { + p.clientMu.Lock() + defer p.clientMu.Unlock() + + c = p.clients[s] + if c != nil { + return c, false, nil + } + + f, err := p.streamer.GetClientFunc(s.Name) + if err != nil { + return nil, false, err + } + + is, err := f(p, s.Key, s.Live) + if err != nil { + return nil, false, err + } + + cp, err := p.getClientParams(s) + if err != nil { + return nil, false, err + } + defer func() { + if err == nil { + if err := p.removeClientParams(s); err != nil { + log.Error("stream set client: remove client params", "stream", s, "peer", p, "err", err) + } + } + }() + + intervalsKey := peerStreamIntervalsKey(p, s) + if s.Live { + // try to find previous history and live intervals and merge live into history + historyKey := peerStreamIntervalsKey(p, NewStream(s.Name, s.Key, false)) + historyIntervals := &intervals.Intervals{} + err := p.streamer.intervalsStore.Get(historyKey, historyIntervals) + switch err { + case nil: + liveIntervals := &intervals.Intervals{} + err := p.streamer.intervalsStore.Get(intervalsKey, liveIntervals) + switch err { + case nil: + historyIntervals.Merge(liveIntervals) + if err := p.streamer.intervalsStore.Put(historyKey, historyIntervals); err != nil { + log.Error("stream set client: put history intervals", "stream", s, "peer", p, "err", err) + } + case state.ErrNotFound: + default: + log.Error("stream set client: get live intervals", "stream", s, "peer", p, "err", err) + } + case state.ErrNotFound: + default: + log.Error("stream set client: get history intervals", "stream", s, "peer", p, "err", err) + } + } + + if err := p.streamer.intervalsStore.Put(intervalsKey, intervals.NewIntervals(from)); err != nil { + return nil, false, err + } + + next := make(chan error, 1) + c = &client{ + Client: is, + stream: s, + priority: cp.priority, + to: cp.to, + next: next, + quit: make(chan struct{}), + intervalsStore: p.streamer.intervalsStore, + intervalsKey: intervalsKey, + } + p.clients[s] = c + cp.clientCreated() // unblock all possible getClient calls that are waiting + next <- nil // this is to allow wantedKeysMsg before first batch arrives + return c, true, nil +} + +func (p *Peer) removeClient(s Stream) error { + p.clientMu.Lock() + defer p.clientMu.Unlock() + + client, ok := p.clients[s] + if !ok { + return newNotFoundError("client", s) + } + client.close() + return nil +} + +func (p *Peer) setClientParams(s Stream, params *clientParams) error { + p.clientMu.Lock() + defer p.clientMu.Unlock() + + if p.clients[s] != nil { + return fmt.Errorf("client %s already exists", s) + } + if p.clientParams[s] != nil { + return fmt.Errorf("client params %s already set", s) + } + p.clientParams[s] = params + return nil +} + +func (p *Peer) getClientParams(s Stream) (*clientParams, error) { + params := p.clientParams[s] + if params == nil { + return nil, fmt.Errorf("client params '%v' not provided to peer %v", s, p.ID()) + } + return params, nil +} + +func (p *Peer) removeClientParams(s Stream) error { + _, ok := p.clientParams[s] + if !ok { + return newNotFoundError("client params", s) + } + delete(p.clientParams, s) + return nil +} + +func (p *Peer) close() { + for _, s := range p.servers { + s.Close() + } +} diff --git a/swarm/network/stream/snapshot_retrieval_test.go b/swarm/network/stream/snapshot_retrieval_test.go new file mode 100644 index 0000000000..4ff947b215 --- /dev/null +++ b/swarm/network/stream/snapshot_retrieval_test.go @@ -0,0 +1,390 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . +package stream + +import ( + "context" + "fmt" + "os" + "sync" + "testing" + "time" + + "github.com/ethereum/go-ethereum/node" + "github.com/ethereum/go-ethereum/p2p/discover" + "github.com/ethereum/go-ethereum/p2p/simulations/adapters" + "github.com/ethereum/go-ethereum/swarm/log" + "github.com/ethereum/go-ethereum/swarm/network" + "github.com/ethereum/go-ethereum/swarm/network/simulation" + "github.com/ethereum/go-ethereum/swarm/state" + "github.com/ethereum/go-ethereum/swarm/storage" +) + +//constants for random file generation +const ( + minFileSize = 2 + maxFileSize = 40 +) + +//This test is a retrieval test for nodes. +//A configurable number of nodes can be +//provided to the test. +//Files are uploaded to nodes, other nodes try to retrieve the file +//Number of nodes can be provided via commandline too. +func TestFileRetrieval(t *testing.T) { + if *nodes != 0 { + err := runFileRetrievalTest(*nodes) + if err != nil { + t.Fatal(err) + } + } else { + nodeCnt := []int{16} + //if the `longrunning` flag has been provided + //run more test combinations + if *longrunning { + nodeCnt = append(nodeCnt, 32, 64, 128) + } + for _, n := range nodeCnt { + err := runFileRetrievalTest(n) + if err != nil { + t.Fatal(err) + } + } + } +} + +//This test is a retrieval test for nodes. +//One node is randomly selected to be the pivot node. +//A configurable number of chunks and nodes can be +//provided to the test, the number of chunks is uploaded +//to the pivot node and other nodes try to retrieve the chunk(s). +//Number of chunks and nodes can be provided via commandline too. +func TestRetrieval(t *testing.T) { + //if nodes/chunks have been provided via commandline, + //run the tests with these values + if *nodes != 0 && *chunks != 0 { + err := runRetrievalTest(*chunks, *nodes) + if err != nil { + t.Fatal(err) + } + } else { + var nodeCnt []int + var chnkCnt []int + //if the `longrunning` flag has been provided + //run more test combinations + if *longrunning { + nodeCnt = []int{16, 32, 128} + chnkCnt = []int{4, 32, 256} + } else { + //default test + nodeCnt = []int{16} + chnkCnt = []int{32} + } + for _, n := range nodeCnt { + for _, c := range chnkCnt { + err := runRetrievalTest(c, n) + if err != nil { + t.Fatal(err) + } + } + } + } +} + +/* + +The test loads a snapshot file to construct the swarm network, +assuming that the snapshot file identifies a healthy +kademlia network. Nevertheless a health check runs in the +simulation's `action` function. + +The snapshot should have 'streamer' in its service list. +*/ +func runFileRetrievalTest(nodeCount int) error { + sim := simulation.New(map[string]simulation.ServiceFunc{ + "streamer": func(ctx *adapters.ServiceContext, bucket *sync.Map) (s node.Service, cleanup func(), err error) { + + id := ctx.Config.ID + addr := network.NewAddrFromNodeID(id) + store, datadir, err := createTestLocalStorageForID(id, addr) + if err != nil { + return nil, nil, err + } + bucket.Store(bucketKeyStore, store) + cleanup = func() { + os.RemoveAll(datadir) + store.Close() + } + localStore := store.(*storage.LocalStore) + db := storage.NewDBAPI(localStore) + kad := network.NewKademlia(addr.Over(), network.NewKadParams()) + delivery := NewDelivery(kad, db) + + r := NewRegistry(addr, delivery, db, state.NewInmemoryStore(), &RegistryOptions{ + DoSync: true, + SyncUpdateDelay: 3 * time.Second, + }) + + fileStore := storage.NewFileStore(storage.NewNetStore(localStore, nil), storage.NewFileStoreParams()) + bucket.Store(bucketKeyFileStore, fileStore) + + return r, cleanup, nil + + }, + }) + defer sim.Close() + + log.Info("Initializing test config") + + conf := &synctestConfig{} + //map of discover ID to indexes of chunks expected at that ID + conf.idToChunksMap = make(map[discover.NodeID][]int) + //map of overlay address to discover ID + conf.addrToIDMap = make(map[string]discover.NodeID) + //array where the generated chunk hashes will be stored + conf.hashes = make([]storage.Address, 0) + + err := sim.UploadSnapshot(fmt.Sprintf("testing/snapshot_%d.json", nodeCount)) + if err != nil { + return err + } + + ctx, cancelSimRun := context.WithTimeout(context.Background(), 1*time.Minute) + defer cancelSimRun() + + result := sim.Run(ctx, func(ctx context.Context, sim *simulation.Simulation) error { + nodeIDs := sim.UpNodeIDs() + for _, n := range nodeIDs { + //get the kademlia overlay address from this ID + a := network.ToOverlayAddr(n.Bytes()) + //append it to the array of all overlay addresses + conf.addrs = append(conf.addrs, a) + //the proximity calculation is on overlay addr, + //the p2p/simulations check func triggers on discover.NodeID, + //so we need to know which overlay addr maps to which nodeID + conf.addrToIDMap[string(a)] = n + } + + //an array for the random files + var randomFiles []string + //channel to signal when the upload has finished + //uploadFinished := make(chan struct{}) + //channel to trigger new node checks + + conf.hashes, randomFiles, err = uploadFilesToNodes(sim) + if err != nil { + return err + } + if _, err := sim.WaitTillHealthy(ctx, 2); err != nil { + return err + } + + // File retrieval check is repeated until all uploaded files are retrieved from all nodes + // or until the timeout is reached. + allSuccess := false + for !allSuccess { + for _, id := range nodeIDs { + //for each expected chunk, check if it is in the local store + localChunks := conf.idToChunksMap[id] + localSuccess := true + for _, ch := range localChunks { + //get the real chunk by the index in the index array + chunk := conf.hashes[ch] + log.Trace(fmt.Sprintf("node has chunk: %s:", chunk)) + //check if the expected chunk is indeed in the localstore + var err error + //check on the node's FileStore (netstore) + item, ok := sim.NodeItem(id, bucketKeyFileStore) + if !ok { + return fmt.Errorf("No registry") + } + fileStore := item.(*storage.FileStore) + //check all chunks + for i, hash := range conf.hashes { + reader, _ := fileStore.Retrieve(context.TODO(), hash) + //check that we can read the file size and that it corresponds to the generated file size + if s, err := reader.Size(ctx, nil); err != nil || s != int64(len(randomFiles[i])) { + allSuccess = false + log.Warn("Retrieve error", "err", err, "hash", hash, "nodeId", id) + } else { + log.Debug(fmt.Sprintf("File with root hash %x successfully retrieved", hash)) + } + } + if err != nil { + log.Warn(fmt.Sprintf("Chunk %s NOT found for id %s", chunk, id)) + localSuccess = false + } else { + log.Debug(fmt.Sprintf("Chunk %s IS FOUND for id %s", chunk, id)) + } + } + allSuccess = localSuccess + } + } + if !allSuccess { + return fmt.Errorf("Not all chunks succeeded!") + } + return nil + }) + + if result.Error != nil { + return result.Error + } + + return nil +} + +/* +The test generates the given number of chunks. + +The test loads a snapshot file to construct the swarm network, +assuming that the snapshot file identifies a healthy +kademlia network. Nevertheless a health check runs in the +simulation's `action` function. + +The snapshot should have 'streamer' in its service list. +*/ +func runRetrievalTest(chunkCount int, nodeCount int) error { + sim := simulation.New(map[string]simulation.ServiceFunc{ + "streamer": func(ctx *adapters.ServiceContext, bucket *sync.Map) (s node.Service, cleanup func(), err error) { + + id := ctx.Config.ID + addr := network.NewAddrFromNodeID(id) + store, datadir, err := createTestLocalStorageForID(id, addr) + if err != nil { + return nil, nil, err + } + bucket.Store(bucketKeyStore, store) + cleanup = func() { + os.RemoveAll(datadir) + store.Close() + } + localStore := store.(*storage.LocalStore) + db := storage.NewDBAPI(localStore) + kad := network.NewKademlia(addr.Over(), network.NewKadParams()) + delivery := NewDelivery(kad, db) + + r := NewRegistry(addr, delivery, db, state.NewInmemoryStore(), &RegistryOptions{ + DoSync: true, + SyncUpdateDelay: 0, + }) + + fileStore := storage.NewFileStore(storage.NewNetStore(localStore, nil), storage.NewFileStoreParams()) + bucketKeyFileStore = simulation.BucketKey("filestore") + bucket.Store(bucketKeyFileStore, fileStore) + + return r, cleanup, nil + + }, + }) + defer sim.Close() + + conf := &synctestConfig{} + //map of discover ID to indexes of chunks expected at that ID + conf.idToChunksMap = make(map[discover.NodeID][]int) + //map of overlay address to discover ID + conf.addrToIDMap = make(map[string]discover.NodeID) + //array where the generated chunk hashes will be stored + conf.hashes = make([]storage.Address, 0) + + err := sim.UploadSnapshot(fmt.Sprintf("testing/snapshot_%d.json", nodeCount)) + if err != nil { + return err + } + + ctx := context.Background() + result := sim.Run(ctx, func(ctx context.Context, sim *simulation.Simulation) error { + nodeIDs := sim.UpNodeIDs() + for _, n := range nodeIDs { + //get the kademlia overlay address from this ID + a := network.ToOverlayAddr(n.Bytes()) + //append it to the array of all overlay addresses + conf.addrs = append(conf.addrs, a) + //the proximity calculation is on overlay addr, + //the p2p/simulations check func triggers on discover.NodeID, + //so we need to know which overlay addr maps to which nodeID + conf.addrToIDMap[string(a)] = n + } + + //an array for the random files + var randomFiles []string + //this is the node selected for upload + node := sim.RandomUpNode() + item, ok := sim.NodeItem(node.ID, bucketKeyStore) + if !ok { + return fmt.Errorf("No localstore") + } + lstore := item.(*storage.LocalStore) + conf.hashes, err = uploadFileToSingleNodeStore(node.ID, chunkCount, lstore) + if err != nil { + return err + } + if _, err := sim.WaitTillHealthy(ctx, 2); err != nil { + return err + } + + // File retrieval check is repeated until all uploaded files are retrieved from all nodes + // or until the timeout is reached. + allSuccess := false + for !allSuccess { + for _, id := range nodeIDs { + //for each expected chunk, check if it is in the local store + localChunks := conf.idToChunksMap[id] + localSuccess := true + for _, ch := range localChunks { + //get the real chunk by the index in the index array + chunk := conf.hashes[ch] + log.Trace(fmt.Sprintf("node has chunk: %s:", chunk)) + //check if the expected chunk is indeed in the localstore + var err error + //check on the node's FileStore (netstore) + item, ok := sim.NodeItem(id, bucketKeyFileStore) + if !ok { + return fmt.Errorf("No registry") + } + fileStore := item.(*storage.FileStore) + //check all chunks + for i, hash := range conf.hashes { + reader, _ := fileStore.Retrieve(context.TODO(), hash) + //check that we can read the file size and that it corresponds to the generated file size + if s, err := reader.Size(ctx, nil); err != nil || s != int64(len(randomFiles[i])) { + allSuccess = false + log.Warn("Retrieve error", "err", err, "hash", hash, "nodeId", id) + } else { + log.Debug(fmt.Sprintf("File with root hash %x successfully retrieved", hash)) + } + } + if err != nil { + log.Warn(fmt.Sprintf("Chunk %s NOT found for id %s", chunk, id)) + localSuccess = false + } else { + log.Debug(fmt.Sprintf("Chunk %s IS FOUND for id %s", chunk, id)) + } + } + allSuccess = localSuccess + } + } + if !allSuccess { + return fmt.Errorf("Not all chunks succeeded!") + } + return nil + }) + + if result.Error != nil { + return result.Error + } + + return nil +} diff --git a/swarm/network/stream/snapshot_sync_test.go b/swarm/network/stream/snapshot_sync_test.go new file mode 100644 index 0000000000..2dfc5898fe --- /dev/null +++ b/swarm/network/stream/snapshot_sync_test.go @@ -0,0 +1,542 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . +package stream + +import ( + "context" + crand "crypto/rand" + "fmt" + "io" + "os" + "sync" + "testing" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/node" + "github.com/ethereum/go-ethereum/p2p" + "github.com/ethereum/go-ethereum/p2p/discover" + "github.com/ethereum/go-ethereum/p2p/simulations/adapters" + "github.com/ethereum/go-ethereum/swarm/network" + "github.com/ethereum/go-ethereum/swarm/network/simulation" + "github.com/ethereum/go-ethereum/swarm/pot" + "github.com/ethereum/go-ethereum/swarm/state" + "github.com/ethereum/go-ethereum/swarm/storage" + mockdb "github.com/ethereum/go-ethereum/swarm/storage/mock/db" +) + +const testMinProxBinSize = 2 +const MaxTimeout = 600 + +type synctestConfig struct { + addrs [][]byte + hashes []storage.Address + idToChunksMap map[discover.NodeID][]int + chunksToNodesMap map[string][]int + addrToIDMap map[string]discover.NodeID +} + +//This test is a syncing test for nodes. +//One node is randomly selected to be the pivot node. +//A configurable number of chunks and nodes can be +//provided to the test, the number of chunks is uploaded +//to the pivot node, and we check that nodes get the chunks +//they are expected to store based on the syncing protocol. +//Number of chunks and nodes can be provided via commandline too. +func TestSyncingViaGlobalSync(t *testing.T) { + //if nodes/chunks have been provided via commandline, + //run the tests with these values + if *nodes != 0 && *chunks != 0 { + log.Info(fmt.Sprintf("Running test with %d chunks and %d nodes...", *chunks, *nodes)) + testSyncingViaGlobalSync(t, *chunks, *nodes) + } else { + var nodeCnt []int + var chnkCnt []int + //if the `longrunning` flag has been provided + //run more test combinations + if *longrunning { + chnkCnt = []int{1, 8, 32, 256, 1024} + nodeCnt = []int{16, 32, 64, 128, 256} + } else { + //default test + chnkCnt = []int{4, 32} + nodeCnt = []int{32, 16} + } + for _, chnk := range chnkCnt { + for _, n := range nodeCnt { + log.Info(fmt.Sprintf("Long running test with %d chunks and %d nodes...", chnk, n)) + testSyncingViaGlobalSync(t, chnk, n) + } + } + } +} + +func TestSyncingViaDirectSubscribe(t *testing.T) { + //if nodes/chunks have been provided via commandline, + //run the tests with these values + if *nodes != 0 && *chunks != 0 { + log.Info(fmt.Sprintf("Running test with %d chunks and %d nodes...", *chunks, *nodes)) + err := testSyncingViaDirectSubscribe(*chunks, *nodes) + if err != nil { + t.Fatal(err) + } + } else { + var nodeCnt []int + var chnkCnt []int + //if the `longrunning` flag has been provided + //run more test combinations + if *longrunning { + chnkCnt = []int{1, 8, 32, 256, 1024} + nodeCnt = []int{32, 16} + } else { + //default test + chnkCnt = []int{4, 32} + nodeCnt = []int{32, 16} + } + for _, chnk := range chnkCnt { + for _, n := range nodeCnt { + log.Info(fmt.Sprintf("Long running test with %d chunks and %d nodes...", chnk, n)) + err := testSyncingViaDirectSubscribe(chnk, n) + if err != nil { + t.Fatal(err) + } + } + } + } +} + +func testSyncingViaGlobalSync(t *testing.T, chunkCount int, nodeCount int) { + sim := simulation.New(map[string]simulation.ServiceFunc{ + "streamer": func(ctx *adapters.ServiceContext, bucket *sync.Map) (s node.Service, cleanup func(), err error) { + + id := ctx.Config.ID + addr := network.NewAddrFromNodeID(id) + store, datadir, err := createTestLocalStorageForID(id, addr) + if err != nil { + return nil, nil, err + } + bucket.Store(bucketKeyStore, store) + cleanup = func() { + os.RemoveAll(datadir) + store.Close() + } + localStore := store.(*storage.LocalStore) + db := storage.NewDBAPI(localStore) + kad := network.NewKademlia(addr.Over(), network.NewKadParams()) + delivery := NewDelivery(kad, db) + + r := NewRegistry(addr, delivery, db, state.NewInmemoryStore(), &RegistryOptions{ + DoSync: true, + SyncUpdateDelay: 3 * time.Second, + }) + bucket.Store(bucketKeyRegistry, r) + + return r, cleanup, nil + + }, + }) + defer sim.Close() + + log.Info("Initializing test config") + + conf := &synctestConfig{} + //map of discover ID to indexes of chunks expected at that ID + conf.idToChunksMap = make(map[discover.NodeID][]int) + //map of overlay address to discover ID + conf.addrToIDMap = make(map[string]discover.NodeID) + //array where the generated chunk hashes will be stored + conf.hashes = make([]storage.Address, 0) + + err := sim.UploadSnapshot(fmt.Sprintf("testing/snapshot_%d.json", nodeCount)) + if err != nil { + t.Fatal(err) + } + + ctx, cancelSimRun := context.WithTimeout(context.Background(), 1*time.Minute) + defer cancelSimRun() + + result := sim.Run(ctx, func(ctx context.Context, sim *simulation.Simulation) error { + nodeIDs := sim.UpNodeIDs() + for _, n := range nodeIDs { + //get the kademlia overlay address from this ID + a := network.ToOverlayAddr(n.Bytes()) + //append it to the array of all overlay addresses + conf.addrs = append(conf.addrs, a) + //the proximity calculation is on overlay addr, + //the p2p/simulations check func triggers on discover.NodeID, + //so we need to know which overlay addr maps to which nodeID + conf.addrToIDMap[string(a)] = n + } + + //get the the node at that index + //this is the node selected for upload + node := sim.RandomUpNode() + item, ok := sim.NodeItem(node.ID, bucketKeyStore) + if !ok { + return fmt.Errorf("No localstore") + } + lstore := item.(*storage.LocalStore) + hashes, err := uploadFileToSingleNodeStore(node.ID, chunkCount, lstore) + if err != nil { + return err + } + conf.hashes = append(conf.hashes, hashes...) + mapKeysToNodes(conf) + + if _, err := sim.WaitTillHealthy(ctx, 2); err != nil { + return err + } + + // File retrieval check is repeated until all uploaded files are retrieved from all nodes + // or until the timeout is reached. + allSuccess := false + var gDir string + var globalStore *mockdb.GlobalStore + if *useMockStore { + gDir, globalStore, err = createGlobalStore() + if err != nil { + return fmt.Errorf("Something went wrong; using mockStore enabled but globalStore is nil") + } + defer func() { + os.RemoveAll(gDir) + err := globalStore.Close() + if err != nil { + log.Error("Error closing global store! %v", "err", err) + } + }() + } + for !allSuccess { + for _, id := range nodeIDs { + //for each expected chunk, check if it is in the local store + localChunks := conf.idToChunksMap[id] + localSuccess := true + for _, ch := range localChunks { + //get the real chunk by the index in the index array + chunk := conf.hashes[ch] + log.Trace(fmt.Sprintf("node has chunk: %s:", chunk)) + //check if the expected chunk is indeed in the localstore + var err error + if *useMockStore { + //use the globalStore if the mockStore should be used; in that case, + //the complete localStore stack is bypassed for getting the chunk + _, err = globalStore.Get(common.BytesToAddress(id.Bytes()), chunk) + } else { + //use the actual localstore + item, ok := sim.NodeItem(id, bucketKeyStore) + if !ok { + return fmt.Errorf("Error accessing localstore") + } + lstore := item.(*storage.LocalStore) + _, err = lstore.Get(ctx, chunk) + } + if err != nil { + log.Warn(fmt.Sprintf("Chunk %s NOT found for id %s", chunk, id)) + localSuccess = false + } else { + log.Debug(fmt.Sprintf("Chunk %s IS FOUND for id %s", chunk, id)) + } + } + allSuccess = localSuccess + } + } + if !allSuccess { + return fmt.Errorf("Not all chunks succeeded!") + } + return nil + }) + + if result.Error != nil { + t.Fatal(result.Error) + } +} + +/* +The test generates the given number of chunks + +For every chunk generated, the nearest node addresses +are identified, we verify that the nodes closer to the +chunk addresses actually do have the chunks in their local stores. + +The test loads a snapshot file to construct the swarm network, +assuming that the snapshot file identifies a healthy +kademlia network. The snapshot should have 'streamer' in its service list. +*/ +func testSyncingViaDirectSubscribe(chunkCount int, nodeCount int) error { + sim := simulation.New(map[string]simulation.ServiceFunc{ + "streamer": func(ctx *adapters.ServiceContext, bucket *sync.Map) (s node.Service, cleanup func(), err error) { + + id := ctx.Config.ID + addr := network.NewAddrFromNodeID(id) + store, datadir, err := createTestLocalStorageForID(id, addr) + if err != nil { + return nil, nil, err + } + bucket.Store(bucketKeyStore, store) + cleanup = func() { + os.RemoveAll(datadir) + store.Close() + } + localStore := store.(*storage.LocalStore) + db := storage.NewDBAPI(localStore) + kad := network.NewKademlia(addr.Over(), network.NewKadParams()) + delivery := NewDelivery(kad, db) + + r := NewRegistry(addr, delivery, db, state.NewInmemoryStore(), nil) + bucket.Store(bucketKeyRegistry, r) + + fileStore := storage.NewFileStore(storage.NewNetStore(localStore, nil), storage.NewFileStoreParams()) + bucket.Store(bucketKeyFileStore, fileStore) + + return r, cleanup, nil + + }, + }) + defer sim.Close() + + ctx, cancelSimRun := context.WithTimeout(context.Background(), 1*time.Minute) + defer cancelSimRun() + + conf := &synctestConfig{} + //map of discover ID to indexes of chunks expected at that ID + conf.idToChunksMap = make(map[discover.NodeID][]int) + //map of overlay address to discover ID + conf.addrToIDMap = make(map[string]discover.NodeID) + //array where the generated chunk hashes will be stored + conf.hashes = make([]storage.Address, 0) + + err := sim.UploadSnapshot(fmt.Sprintf("testing/snapshot_%d.json", nodeCount)) + if err != nil { + return err + } + + result := sim.Run(ctx, func(ctx context.Context, sim *simulation.Simulation) error { + nodeIDs := sim.UpNodeIDs() + for _, n := range nodeIDs { + //get the kademlia overlay address from this ID + a := network.ToOverlayAddr(n.Bytes()) + //append it to the array of all overlay addresses + conf.addrs = append(conf.addrs, a) + //the proximity calculation is on overlay addr, + //the p2p/simulations check func triggers on discover.NodeID, + //so we need to know which overlay addr maps to which nodeID + conf.addrToIDMap[string(a)] = n + } + + var subscriptionCount int + + filter := simulation.NewPeerEventsFilter().Type(p2p.PeerEventTypeMsgRecv).Protocol("stream").MsgCode(4) + eventC := sim.PeerEvents(ctx, nodeIDs, filter) + + for j, node := range nodeIDs { + log.Trace(fmt.Sprintf("Start syncing subscriptions: %d", j)) + //start syncing! + item, ok := sim.NodeItem(node, bucketKeyRegistry) + if !ok { + return fmt.Errorf("No registry") + } + registry := item.(*Registry) + + var cnt int + cnt, err = startSyncing(registry, conf) + if err != nil { + return err + } + //increment the number of subscriptions we need to wait for + //by the count returned from startSyncing (SYNC subscriptions) + subscriptionCount += cnt + } + + for e := range eventC { + if e.Error != nil { + return e.Error + } + subscriptionCount-- + if subscriptionCount == 0 { + break + } + } + //select a random node for upload + node := sim.RandomUpNode() + item, ok := sim.NodeItem(node.ID, bucketKeyStore) + if !ok { + return fmt.Errorf("No localstore") + } + lstore := item.(*storage.LocalStore) + hashes, err := uploadFileToSingleNodeStore(node.ID, chunkCount, lstore) + if err != nil { + return err + } + conf.hashes = append(conf.hashes, hashes...) + mapKeysToNodes(conf) + + if _, err := sim.WaitTillHealthy(ctx, 2); err != nil { + return err + } + + var gDir string + var globalStore *mockdb.GlobalStore + if *useMockStore { + gDir, globalStore, err = createGlobalStore() + if err != nil { + return fmt.Errorf("Something went wrong; using mockStore enabled but globalStore is nil") + } + defer os.RemoveAll(gDir) + } + // File retrieval check is repeated until all uploaded files are retrieved from all nodes + // or until the timeout is reached. + allSuccess := false + for !allSuccess { + for _, id := range nodeIDs { + //for each expected chunk, check if it is in the local store + localChunks := conf.idToChunksMap[id] + localSuccess := true + for _, ch := range localChunks { + //get the real chunk by the index in the index array + chunk := conf.hashes[ch] + log.Trace(fmt.Sprintf("node has chunk: %s:", chunk)) + //check if the expected chunk is indeed in the localstore + var err error + if *useMockStore { + //use the globalStore if the mockStore should be used; in that case, + //the complete localStore stack is bypassed for getting the chunk + _, err = globalStore.Get(common.BytesToAddress(id.Bytes()), chunk) + } else { + //use the actual localstore + item, ok := sim.NodeItem(id, bucketKeyStore) + if !ok { + return fmt.Errorf("Error accessing localstore") + } + lstore := item.(*storage.LocalStore) + _, err = lstore.Get(ctx, chunk) + } + if err != nil { + log.Warn(fmt.Sprintf("Chunk %s NOT found for id %s", chunk, id)) + localSuccess = false + } else { + log.Debug(fmt.Sprintf("Chunk %s IS FOUND for id %s", chunk, id)) + } + } + allSuccess = localSuccess + } + } + if !allSuccess { + return fmt.Errorf("Not all chunks succeeded!") + } + return nil + }) + + if result.Error != nil { + return result.Error + } + + log.Info("Simulation terminated") + return nil +} + +//the server func to start syncing +//issues `RequestSubscriptionMsg` to peers, based on po, by iterating over +//the kademlia's `EachBin` function. +//returns the number of subscriptions requested +func startSyncing(r *Registry, conf *synctestConfig) (int, error) { + var err error + + kad, ok := r.delivery.overlay.(*network.Kademlia) + if !ok { + return 0, fmt.Errorf("Not a Kademlia!") + } + + subCnt := 0 + //iterate over each bin and solicit needed subscription to bins + kad.EachBin(r.addr.Over(), pof, 0, func(conn network.OverlayConn, po int) bool { + //identify begin and start index of the bin(s) we want to subscribe to + histRange := &Range{} + + subCnt++ + err = r.RequestSubscription(conf.addrToIDMap[string(conn.Address())], NewStream("SYNC", FormatSyncBinKey(uint8(po)), true), histRange, Top) + if err != nil { + log.Error(fmt.Sprintf("Error in RequestSubsciption! %v", err)) + return false + } + return true + + }) + return subCnt, nil +} + +//map chunk keys to addresses which are responsible +func mapKeysToNodes(conf *synctestConfig) { + kmap := make(map[string][]int) + nodemap := make(map[string][]int) + //build a pot for chunk hashes + np := pot.NewPot(nil, 0) + indexmap := make(map[string]int) + for i, a := range conf.addrs { + indexmap[string(a)] = i + np, _, _ = pot.Add(np, a, pof) + } + //for each address, run EachNeighbour on the chunk hashes pot to identify closest nodes + log.Trace(fmt.Sprintf("Generated hash chunk(s): %v", conf.hashes)) + for i := 0; i < len(conf.hashes); i++ { + pl := 256 //highest possible proximity + var nns []int + np.EachNeighbour([]byte(conf.hashes[i]), pof, func(val pot.Val, po int) bool { + a := val.([]byte) + if pl < 256 && pl != po { + return false + } + if pl == 256 || pl == po { + log.Trace(fmt.Sprintf("appending %s", conf.addrToIDMap[string(a)])) + nns = append(nns, indexmap[string(a)]) + nodemap[string(a)] = append(nodemap[string(a)], i) + } + if pl == 256 && len(nns) >= testMinProxBinSize { + //maxProxBinSize has been reached at this po, so save it + //we will add all other nodes at the same po + pl = po + } + return true + }) + kmap[string(conf.hashes[i])] = nns + } + for addr, chunks := range nodemap { + //this selects which chunks are expected to be found with the given node + conf.idToChunksMap[conf.addrToIDMap[addr]] = chunks + } + log.Debug(fmt.Sprintf("Map of expected chunks by ID: %v", conf.idToChunksMap)) + conf.chunksToNodesMap = kmap +} + +//upload a file(chunks) to a single local node store +func uploadFileToSingleNodeStore(id discover.NodeID, chunkCount int, lstore *storage.LocalStore) ([]storage.Address, error) { + log.Debug(fmt.Sprintf("Uploading to node id: %s", id)) + fileStore := storage.NewFileStore(lstore, storage.NewFileStoreParams()) + size := chunkSize + var rootAddrs []storage.Address + for i := 0; i < chunkCount; i++ { + rk, wait, err := fileStore.Store(context.TODO(), io.LimitReader(crand.Reader, int64(size)), int64(size), false) + if err != nil { + return nil, err + } + err = wait(context.TODO()) + if err != nil { + return nil, err + } + rootAddrs = append(rootAddrs, (rk)) + } + + return rootAddrs, nil +} diff --git a/swarm/network/stream/stream.go b/swarm/network/stream/stream.go new file mode 100644 index 0000000000..cd0580a0c0 --- /dev/null +++ b/swarm/network/stream/stream.go @@ -0,0 +1,747 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package stream + +import ( + "context" + "fmt" + "math" + "sync" + "time" + + "github.com/ethereum/go-ethereum/metrics" + "github.com/ethereum/go-ethereum/p2p" + "github.com/ethereum/go-ethereum/p2p/discover" + "github.com/ethereum/go-ethereum/p2p/protocols" + "github.com/ethereum/go-ethereum/rpc" + "github.com/ethereum/go-ethereum/swarm/log" + "github.com/ethereum/go-ethereum/swarm/network" + "github.com/ethereum/go-ethereum/swarm/network/stream/intervals" + "github.com/ethereum/go-ethereum/swarm/pot" + "github.com/ethereum/go-ethereum/swarm/spancontext" + "github.com/ethereum/go-ethereum/swarm/state" + "github.com/ethereum/go-ethereum/swarm/storage" + opentracing "github.com/opentracing/opentracing-go" +) + +const ( + Low uint8 = iota + Mid + High + Top + PriorityQueue // number of queues + PriorityQueueCap = 32 // queue capacity + HashSize = 32 +) + +// Registry registry for outgoing and incoming streamer constructors +type Registry struct { + api *API + addr *network.BzzAddr + skipCheck bool + clientMu sync.RWMutex + serverMu sync.RWMutex + peersMu sync.RWMutex + serverFuncs map[string]func(*Peer, string, bool) (Server, error) + clientFuncs map[string]func(*Peer, string, bool) (Client, error) + peers map[discover.NodeID]*Peer + delivery *Delivery + intervalsStore state.Store + doRetrieve bool +} + +// RegistryOptions holds optional values for NewRegistry constructor. +type RegistryOptions struct { + SkipCheck bool + DoSync bool + DoRetrieve bool + SyncUpdateDelay time.Duration +} + +// NewRegistry is Streamer constructor +func NewRegistry(addr *network.BzzAddr, delivery *Delivery, db *storage.DBAPI, intervalsStore state.Store, options *RegistryOptions) *Registry { + if options == nil { + options = &RegistryOptions{} + } + if options.SyncUpdateDelay <= 0 { + options.SyncUpdateDelay = 15 * time.Second + } + streamer := &Registry{ + addr: addr, + skipCheck: options.SkipCheck, + serverFuncs: make(map[string]func(*Peer, string, bool) (Server, error)), + clientFuncs: make(map[string]func(*Peer, string, bool) (Client, error)), + peers: make(map[discover.NodeID]*Peer), + delivery: delivery, + intervalsStore: intervalsStore, + doRetrieve: options.DoRetrieve, + } + streamer.api = NewAPI(streamer) + delivery.getPeer = streamer.getPeer + streamer.RegisterServerFunc(swarmChunkServerStreamName, func(_ *Peer, _ string, _ bool) (Server, error) { + return NewSwarmChunkServer(delivery.db), nil + }) + streamer.RegisterClientFunc(swarmChunkServerStreamName, func(p *Peer, t string, live bool) (Client, error) { + return NewSwarmSyncerClient(p, delivery.db, false, NewStream(swarmChunkServerStreamName, t, live)) + }) + RegisterSwarmSyncerServer(streamer, db) + RegisterSwarmSyncerClient(streamer, db) + + if options.DoSync { + // latestIntC function ensures that + // - receiving from the in chan is not blocked by processing inside the for loop + // - the latest int value is delivered to the loop after the processing is done + // In context of NeighbourhoodDepthC: + // after the syncing is done updating inside the loop, we do not need to update on the intermediate + // depth changes, only to the latest one + latestIntC := func(in <-chan int) <-chan int { + out := make(chan int, 1) + + go func() { + defer close(out) + + for i := range in { + select { + case <-out: + default: + } + out <- i + } + }() + + return out + } + + go func() { + // wait for kademlia table to be healthy + time.Sleep(options.SyncUpdateDelay) + + kad := streamer.delivery.overlay.(*network.Kademlia) + depthC := latestIntC(kad.NeighbourhoodDepthC()) + addressBookSizeC := latestIntC(kad.AddrCountC()) + + // initial requests for syncing subscription to peers + streamer.updateSyncing() + + for depth := range depthC { + log.Debug("Kademlia neighbourhood depth change", "depth", depth) + + // Prevent too early sync subscriptions by waiting until there are no + // new peers connecting. Sync streams updating will be done after no + // peers are connected for at least SyncUpdateDelay period. + timer := time.NewTimer(options.SyncUpdateDelay) + // Hard limit to sync update delay, preventing long delays + // on a very dynamic network + maxTimer := time.NewTimer(3 * time.Minute) + loop: + for { + select { + case <-maxTimer.C: + // force syncing update when a hard timeout is reached + log.Trace("Sync subscriptions update on hard timeout") + // request for syncing subscription to new peers + streamer.updateSyncing() + break loop + case <-timer.C: + // start syncing as no new peers has been added to kademlia + // for some time + log.Trace("Sync subscriptions update") + // request for syncing subscription to new peers + streamer.updateSyncing() + break loop + case size := <-addressBookSizeC: + log.Trace("Kademlia address book size changed on depth change", "size", size) + // new peers has been added to kademlia, + // reset the timer to prevent early sync subscriptions + if !timer.Stop() { + <-timer.C + } + timer.Reset(options.SyncUpdateDelay) + } + } + timer.Stop() + maxTimer.Stop() + } + }() + } + + return streamer +} + +// RegisterClient registers an incoming streamer constructor +func (r *Registry) RegisterClientFunc(stream string, f func(*Peer, string, bool) (Client, error)) { + r.clientMu.Lock() + defer r.clientMu.Unlock() + + r.clientFuncs[stream] = f +} + +// RegisterServer registers an outgoing streamer constructor +func (r *Registry) RegisterServerFunc(stream string, f func(*Peer, string, bool) (Server, error)) { + r.serverMu.Lock() + defer r.serverMu.Unlock() + + r.serverFuncs[stream] = f +} + +// GetClient accessor for incoming streamer constructors +func (r *Registry) GetClientFunc(stream string) (func(*Peer, string, bool) (Client, error), error) { + r.clientMu.RLock() + defer r.clientMu.RUnlock() + + f := r.clientFuncs[stream] + if f == nil { + return nil, fmt.Errorf("stream %v not registered", stream) + } + return f, nil +} + +// GetServer accessor for incoming streamer constructors +func (r *Registry) GetServerFunc(stream string) (func(*Peer, string, bool) (Server, error), error) { + r.serverMu.RLock() + defer r.serverMu.RUnlock() + + f := r.serverFuncs[stream] + if f == nil { + return nil, fmt.Errorf("stream %v not registered", stream) + } + return f, nil +} + +func (r *Registry) RequestSubscription(peerId discover.NodeID, s Stream, h *Range, prio uint8) error { + // check if the stream is registered + if _, err := r.GetServerFunc(s.Name); err != nil { + return err + } + + peer := r.getPeer(peerId) + if peer == nil { + return fmt.Errorf("peer not found %v", peerId) + } + + if _, err := peer.getServer(s); err != nil { + if e, ok := err.(*notFoundError); ok && e.t == "server" { + // request subscription only if the server for this stream is not created + log.Debug("RequestSubscription ", "peer", peerId, "stream", s, "history", h) + return peer.Send(context.TODO(), &RequestSubscriptionMsg{ + Stream: s, + History: h, + Priority: prio, + }) + } + return err + } + log.Trace("RequestSubscription: already subscribed", "peer", peerId, "stream", s, "history", h) + return nil +} + +// Subscribe initiates the streamer +func (r *Registry) Subscribe(peerId discover.NodeID, s Stream, h *Range, priority uint8) error { + // check if the stream is registered + if _, err := r.GetClientFunc(s.Name); err != nil { + return err + } + + peer := r.getPeer(peerId) + if peer == nil { + return fmt.Errorf("peer not found %v", peerId) + } + + var to uint64 + if !s.Live && h != nil { + to = h.To + } + + err := peer.setClientParams(s, newClientParams(priority, to)) + if err != nil { + return err + } + + if s.Live && h != nil { + if err := peer.setClientParams( + getHistoryStream(s), + newClientParams(getHistoryPriority(priority), h.To), + ); err != nil { + return err + } + } + + msg := &SubscribeMsg{ + Stream: s, + History: h, + Priority: priority, + } + log.Debug("Subscribe ", "peer", peerId, "stream", s, "history", h) + + return peer.SendPriority(context.TODO(), msg, priority) +} + +func (r *Registry) Unsubscribe(peerId discover.NodeID, s Stream) error { + peer := r.getPeer(peerId) + if peer == nil { + return fmt.Errorf("peer not found %v", peerId) + } + + msg := &UnsubscribeMsg{ + Stream: s, + } + log.Debug("Unsubscribe ", "peer", peerId, "stream", s) + + if err := peer.Send(context.TODO(), msg); err != nil { + return err + } + return peer.removeClient(s) +} + +// Quit sends the QuitMsg to the peer to remove the +// stream peer client and terminate the streaming. +func (r *Registry) Quit(peerId discover.NodeID, s Stream) error { + peer := r.getPeer(peerId) + if peer == nil { + log.Debug("stream quit: peer not found", "peer", peerId, "stream", s) + // if the peer is not found, abort the request + return nil + } + + msg := &QuitMsg{ + Stream: s, + } + log.Debug("Quit ", "peer", peerId, "stream", s) + + return peer.Send(context.TODO(), msg) +} + +func (r *Registry) Retrieve(ctx context.Context, chunk *storage.Chunk) error { + var sp opentracing.Span + ctx, sp = spancontext.StartSpan( + ctx, + "registry.retrieve") + defer sp.Finish() + + return r.delivery.RequestFromPeers(ctx, chunk.Addr[:], r.skipCheck) +} + +func (r *Registry) NodeInfo() interface{} { + return nil +} + +func (r *Registry) PeerInfo(id discover.NodeID) interface{} { + return nil +} + +func (r *Registry) Close() error { + return r.intervalsStore.Close() +} + +func (r *Registry) getPeer(peerId discover.NodeID) *Peer { + r.peersMu.RLock() + defer r.peersMu.RUnlock() + + return r.peers[peerId] +} + +func (r *Registry) setPeer(peer *Peer) { + r.peersMu.Lock() + r.peers[peer.ID()] = peer + metrics.GetOrRegisterGauge("registry.peers", nil).Update(int64(len(r.peers))) + r.peersMu.Unlock() +} + +func (r *Registry) deletePeer(peer *Peer) { + r.peersMu.Lock() + delete(r.peers, peer.ID()) + metrics.GetOrRegisterGauge("registry.peers", nil).Update(int64(len(r.peers))) + r.peersMu.Unlock() +} + +func (r *Registry) peersCount() (c int) { + r.peersMu.Lock() + c = len(r.peers) + r.peersMu.Unlock() + return +} + +// Run protocol run function +func (r *Registry) Run(p *network.BzzPeer) error { + sp := NewPeer(p.Peer, r) + r.setPeer(sp) + defer r.deletePeer(sp) + defer close(sp.quit) + defer sp.close() + + if r.doRetrieve { + err := r.Subscribe(p.ID(), NewStream(swarmChunkServerStreamName, "", false), nil, Top) + if err != nil { + return err + } + } + + return sp.Run(sp.HandleMsg) +} + +// updateSyncing subscribes to SYNC streams by iterating over the +// kademlia connections and bins. If there are existing SYNC streams +// and they are no longer required after iteration, request to Quit +// them will be send to appropriate peers. +func (r *Registry) updateSyncing() { + // if overlay in not Kademlia, panic + kad := r.delivery.overlay.(*network.Kademlia) + + // map of all SYNC streams for all peers + // used at the and of the function to remove servers + // that are not needed anymore + subs := make(map[discover.NodeID]map[Stream]struct{}) + r.peersMu.RLock() + for id, peer := range r.peers { + peer.serverMu.RLock() + for stream := range peer.servers { + if stream.Name == "SYNC" { + if _, ok := subs[id]; !ok { + subs[id] = make(map[Stream]struct{}) + } + subs[id][stream] = struct{}{} + } + } + peer.serverMu.RUnlock() + } + r.peersMu.RUnlock() + + // request subscriptions for all nodes and bins + kad.EachBin(r.addr.Over(), pot.DefaultPof(256), 0, func(conn network.OverlayConn, bin int) bool { + p := conn.(network.Peer) + log.Debug(fmt.Sprintf("Requesting subscription by: registry %s from peer %s for bin: %d", r.addr.ID(), p.ID(), bin)) + + // bin is always less then 256 and it is safe to convert it to type uint8 + stream := NewStream("SYNC", FormatSyncBinKey(uint8(bin)), true) + if streams, ok := subs[p.ID()]; ok { + // delete live and history streams from the map, so that it won't be removed with a Quit request + delete(streams, stream) + delete(streams, getHistoryStream(stream)) + } + err := r.RequestSubscription(p.ID(), stream, NewRange(0, 0), High) + if err != nil { + log.Debug("Request subscription", "err", err, "peer", p.ID(), "stream", stream) + return false + } + return true + }) + + // remove SYNC servers that do not need to be subscribed + for id, streams := range subs { + if len(streams) == 0 { + continue + } + peer := r.getPeer(id) + if peer == nil { + continue + } + for stream := range streams { + log.Debug("Remove sync server", "peer", id, "stream", stream) + err := r.Quit(peer.ID(), stream) + if err != nil && err != p2p.ErrShuttingDown { + log.Error("quit", "err", err, "peer", peer.ID(), "stream", stream) + } + } + } +} + +func (r *Registry) runProtocol(p *p2p.Peer, rw p2p.MsgReadWriter) error { + peer := protocols.NewPeer(p, rw, Spec) + bzzPeer := network.NewBzzTestPeer(peer, r.addr) + r.delivery.overlay.On(bzzPeer) + defer r.delivery.overlay.Off(bzzPeer) + return r.Run(bzzPeer) +} + +// HandleMsg is the message handler that delegates incoming messages +func (p *Peer) HandleMsg(ctx context.Context, msg interface{}) error { + switch msg := msg.(type) { + + case *SubscribeMsg: + return p.handleSubscribeMsg(ctx, msg) + + case *SubscribeErrorMsg: + return p.handleSubscribeErrorMsg(msg) + + case *UnsubscribeMsg: + return p.handleUnsubscribeMsg(msg) + + case *OfferedHashesMsg: + return p.handleOfferedHashesMsg(ctx, msg) + + case *TakeoverProofMsg: + return p.handleTakeoverProofMsg(ctx, msg) + + case *WantedHashesMsg: + return p.handleWantedHashesMsg(ctx, msg) + + case *ChunkDeliveryMsg: + return p.streamer.delivery.handleChunkDeliveryMsg(ctx, p, msg) + + case *RetrieveRequestMsg: + return p.streamer.delivery.handleRetrieveRequestMsg(ctx, p, msg) + + case *RequestSubscriptionMsg: + return p.handleRequestSubscription(ctx, msg) + + case *QuitMsg: + return p.handleQuitMsg(msg) + + default: + return fmt.Errorf("unknown message type: %T", msg) + } +} + +type server struct { + Server + stream Stream + priority uint8 + currentBatch []byte +} + +// Server interface for outgoing peer Streamer +type Server interface { + SetNextBatch(uint64, uint64) (hashes []byte, from uint64, to uint64, proof *HandoverProof, err error) + GetData(context.Context, []byte) ([]byte, error) + Close() +} + +type client struct { + Client + stream Stream + priority uint8 + sessionAt uint64 + to uint64 + next chan error + quit chan struct{} + + intervalsKey string + intervalsStore state.Store +} + +func peerStreamIntervalsKey(p *Peer, s Stream) string { + return p.ID().String() + s.String() +} + +func (c client) AddInterval(start, end uint64) (err error) { + i := &intervals.Intervals{} + err = c.intervalsStore.Get(c.intervalsKey, i) + if err != nil { + return err + } + i.Add(start, end) + return c.intervalsStore.Put(c.intervalsKey, i) +} + +func (c client) NextInterval() (start, end uint64, err error) { + i := &intervals.Intervals{} + err = c.intervalsStore.Get(c.intervalsKey, i) + if err != nil { + return 0, 0, err + } + start, end = i.Next() + return start, end, nil +} + +// Client interface for incoming peer Streamer +type Client interface { + NeedData(context.Context, []byte) func() + BatchDone(Stream, uint64, []byte, []byte) func() (*TakeoverProof, error) + Close() +} + +func (c *client) nextBatch(from uint64) (nextFrom uint64, nextTo uint64) { + if c.to > 0 && from >= c.to { + return 0, 0 + } + if c.stream.Live { + return from, 0 + } else if from >= c.sessionAt { + if c.to > 0 { + return from, c.to + } + return from, math.MaxUint64 + } + nextFrom, nextTo, err := c.NextInterval() + if err != nil { + log.Error("next intervals", "stream", c.stream) + return + } + if nextTo > c.to { + nextTo = c.to + } + if nextTo == 0 { + nextTo = c.sessionAt + } + return +} + +func (c *client) batchDone(p *Peer, req *OfferedHashesMsg, hashes []byte) error { + if tf := c.BatchDone(req.Stream, req.From, hashes, req.Root); tf != nil { + tp, err := tf() + if err != nil { + return err + } + if err := p.SendPriority(context.TODO(), tp, c.priority); err != nil { + return err + } + if c.to > 0 && tp.Takeover.End >= c.to { + return p.streamer.Unsubscribe(p.Peer.ID(), req.Stream) + } + return nil + } + // TODO: make a test case for testing if the interval is added when the batch is done + if err := c.AddInterval(req.From, req.To); err != nil { + return err + } + return nil +} + +func (c *client) close() { + select { + case <-c.quit: + default: + close(c.quit) + } + c.Close() +} + +// clientParams store parameters for the new client +// between a subscription and initial offered hashes request handling. +type clientParams struct { + priority uint8 + to uint64 + // signal when the client is created + clientCreatedC chan struct{} +} + +func newClientParams(priority uint8, to uint64) *clientParams { + return &clientParams{ + priority: priority, + to: to, + clientCreatedC: make(chan struct{}), + } +} + +func (c *clientParams) waitClient(ctx context.Context) error { + select { + case <-ctx.Done(): + return ctx.Err() + case <-c.clientCreatedC: + return nil + } +} + +func (c *clientParams) clientCreated() { + close(c.clientCreatedC) +} + +// Spec is the spec of the streamer protocol +var Spec = &protocols.Spec{ + Name: "stream", + Version: 5, + MaxMsgSize: 10 * 1024 * 1024, + Messages: []interface{}{ + UnsubscribeMsg{}, + OfferedHashesMsg{}, + WantedHashesMsg{}, + TakeoverProofMsg{}, + SubscribeMsg{}, + RetrieveRequestMsg{}, + ChunkDeliveryMsg{}, + SubscribeErrorMsg{}, + RequestSubscriptionMsg{}, + QuitMsg{}, + }, +} + +func (r *Registry) Protocols() []p2p.Protocol { + return []p2p.Protocol{ + { + Name: Spec.Name, + Version: Spec.Version, + Length: Spec.Length(), + Run: r.runProtocol, + // NodeInfo: , + // PeerInfo: , + }, + } +} + +func (r *Registry) APIs() []rpc.API { + return []rpc.API{ + { + Namespace: "stream", + Version: "3.0", + Service: r.api, + Public: true, + }, + } +} + +func (r *Registry) Start(server *p2p.Server) error { + log.Info("Streamer started") + return nil +} + +func (r *Registry) Stop() error { + return nil +} + +type Range struct { + From, To uint64 +} + +func NewRange(from, to uint64) *Range { + return &Range{ + From: from, + To: to, + } +} + +func (r *Range) String() string { + return fmt.Sprintf("%v-%v", r.From, r.To) +} + +func getHistoryPriority(priority uint8) uint8 { + if priority == 0 { + return 0 + } + return priority - 1 +} + +func getHistoryStream(s Stream) Stream { + return NewStream(s.Name, s.Key, false) +} + +type API struct { + streamer *Registry +} + +func NewAPI(r *Registry) *API { + return &API{ + streamer: r, + } +} + +func (api *API) SubscribeStream(peerId discover.NodeID, s Stream, history *Range, priority uint8) error { + return api.streamer.Subscribe(peerId, s, history, priority) +} + +func (api *API) UnsubscribeStream(peerId discover.NodeID, s Stream) error { + return api.streamer.Unsubscribe(peerId, s) +} diff --git a/swarm/network/stream/streamer_test.go b/swarm/network/stream/streamer_test.go new file mode 100644 index 0000000000..7523860c9c --- /dev/null +++ b/swarm/network/stream/streamer_test.go @@ -0,0 +1,685 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package stream + +import ( + "bytes" + "context" + "testing" + "time" + + "github.com/ethereum/go-ethereum/crypto/sha3" + p2ptest "github.com/ethereum/go-ethereum/p2p/testing" +) + +func TestStreamerSubscribe(t *testing.T) { + tester, streamer, _, teardown, err := newStreamerTester(t) + defer teardown() + if err != nil { + t.Fatal(err) + } + + stream := NewStream("foo", "", true) + err = streamer.Subscribe(tester.IDs[0], stream, NewRange(0, 0), Top) + if err == nil || err.Error() != "stream foo not registered" { + t.Fatalf("Expected error %v, got %v", "stream foo not registered", err) + } +} + +func TestStreamerRequestSubscription(t *testing.T) { + tester, streamer, _, teardown, err := newStreamerTester(t) + defer teardown() + if err != nil { + t.Fatal(err) + } + + stream := NewStream("foo", "", false) + err = streamer.RequestSubscription(tester.IDs[0], stream, &Range{}, Top) + if err == nil || err.Error() != "stream foo not registered" { + t.Fatalf("Expected error %v, got %v", "stream foo not registered", err) + } +} + +var ( + hash0 = sha3.Sum256([]byte{0}) + hash1 = sha3.Sum256([]byte{1}) + hash2 = sha3.Sum256([]byte{2}) + hashesTmp = append(hash0[:], hash1[:]...) + hashes = append(hashesTmp, hash2[:]...) +) + +type testClient struct { + t string + wait0 chan bool + wait2 chan bool + batchDone chan bool + receivedHashes map[string][]byte +} + +func newTestClient(t string) *testClient { + return &testClient{ + t: t, + wait0: make(chan bool), + wait2: make(chan bool), + batchDone: make(chan bool), + receivedHashes: make(map[string][]byte), + } +} + +func (self *testClient) NeedData(ctx context.Context, hash []byte) func() { + self.receivedHashes[string(hash)] = hash + if bytes.Equal(hash, hash0[:]) { + return func() { + <-self.wait0 + } + } else if bytes.Equal(hash, hash2[:]) { + return func() { + <-self.wait2 + } + } + return nil +} + +func (self *testClient) BatchDone(Stream, uint64, []byte, []byte) func() (*TakeoverProof, error) { + close(self.batchDone) + return nil +} + +func (self *testClient) Close() {} + +type testServer struct { + t string +} + +func newTestServer(t string) *testServer { + return &testServer{ + t: t, + } +} + +func (self *testServer) SetNextBatch(from uint64, to uint64) ([]byte, uint64, uint64, *HandoverProof, error) { + return make([]byte, HashSize), from + 1, to + 1, nil, nil +} + +func (self *testServer) GetData(context.Context, []byte) ([]byte, error) { + return nil, nil +} + +func (self *testServer) Close() { +} + +func TestStreamerDownstreamSubscribeUnsubscribeMsgExchange(t *testing.T) { + tester, streamer, _, teardown, err := newStreamerTester(t) + defer teardown() + if err != nil { + t.Fatal(err) + } + + streamer.RegisterClientFunc("foo", func(p *Peer, t string, live bool) (Client, error) { + return newTestClient(t), nil + }) + + peerID := tester.IDs[0] + + stream := NewStream("foo", "", true) + err = streamer.Subscribe(peerID, stream, NewRange(5, 8), Top) + if err != nil { + t.Fatalf("Expected no error, got %v", err) + } + + err = tester.TestExchanges( + p2ptest.Exchange{ + Label: "Subscribe message", + Expects: []p2ptest.Expect{ + { + Code: 4, + Msg: &SubscribeMsg{ + Stream: stream, + History: NewRange(5, 8), + Priority: Top, + }, + Peer: peerID, + }, + }, + }, + // trigger OfferedHashesMsg to actually create the client + p2ptest.Exchange{ + Label: "OfferedHashes message", + Triggers: []p2ptest.Trigger{ + { + Code: 1, + Msg: &OfferedHashesMsg{ + HandoverProof: &HandoverProof{ + Handover: &Handover{}, + }, + Hashes: hashes, + From: 5, + To: 8, + Stream: stream, + }, + Peer: peerID, + }, + }, + Expects: []p2ptest.Expect{ + { + Code: 2, + Msg: &WantedHashesMsg{ + Stream: stream, + Want: []byte{5}, + From: 9, + To: 0, + }, + Peer: peerID, + }, + }, + }, + ) + if err != nil { + t.Fatal(err) + } + + err = streamer.Unsubscribe(peerID, stream) + if err != nil { + t.Fatalf("Expected no error, got %v", err) + } + + err = tester.TestExchanges(p2ptest.Exchange{ + Label: "Unsubscribe message", + Expects: []p2ptest.Expect{ + { + Code: 0, + Msg: &UnsubscribeMsg{ + Stream: stream, + }, + Peer: peerID, + }, + }, + }) + + if err != nil { + t.Fatal(err) + } +} + +func TestStreamerUpstreamSubscribeUnsubscribeMsgExchange(t *testing.T) { + tester, streamer, _, teardown, err := newStreamerTester(t) + defer teardown() + if err != nil { + t.Fatal(err) + } + + stream := NewStream("foo", "", false) + + streamer.RegisterServerFunc("foo", func(p *Peer, t string, live bool) (Server, error) { + return newTestServer(t), nil + }) + + peerID := tester.IDs[0] + + err = tester.TestExchanges(p2ptest.Exchange{ + Label: "Subscribe message", + Triggers: []p2ptest.Trigger{ + { + Code: 4, + Msg: &SubscribeMsg{ + Stream: stream, + History: NewRange(5, 8), + Priority: Top, + }, + Peer: peerID, + }, + }, + Expects: []p2ptest.Expect{ + { + Code: 1, + Msg: &OfferedHashesMsg{ + Stream: stream, + HandoverProof: &HandoverProof{ + Handover: &Handover{}, + }, + Hashes: make([]byte, HashSize), + From: 6, + To: 9, + }, + Peer: peerID, + }, + }, + }) + + if err != nil { + t.Fatal(err) + } + + err = tester.TestExchanges(p2ptest.Exchange{ + Label: "unsubscribe message", + Triggers: []p2ptest.Trigger{ + { + Code: 0, + Msg: &UnsubscribeMsg{ + Stream: stream, + }, + Peer: peerID, + }, + }, + }) + + if err != nil { + t.Fatal(err) + } +} + +func TestStreamerUpstreamSubscribeUnsubscribeMsgExchangeLive(t *testing.T) { + tester, streamer, _, teardown, err := newStreamerTester(t) + defer teardown() + if err != nil { + t.Fatal(err) + } + + stream := NewStream("foo", "", true) + + streamer.RegisterServerFunc("foo", func(p *Peer, t string, live bool) (Server, error) { + return newTestServer(t), nil + }) + + peerID := tester.IDs[0] + + err = tester.TestExchanges(p2ptest.Exchange{ + Label: "Subscribe message", + Triggers: []p2ptest.Trigger{ + { + Code: 4, + Msg: &SubscribeMsg{ + Stream: stream, + Priority: Top, + }, + Peer: peerID, + }, + }, + Expects: []p2ptest.Expect{ + { + Code: 1, + Msg: &OfferedHashesMsg{ + Stream: stream, + HandoverProof: &HandoverProof{ + Handover: &Handover{}, + }, + Hashes: make([]byte, HashSize), + From: 1, + To: 1, + }, + Peer: peerID, + }, + }, + }) + + if err != nil { + t.Fatal(err) + } + + err = tester.TestExchanges(p2ptest.Exchange{ + Label: "unsubscribe message", + Triggers: []p2ptest.Trigger{ + { + Code: 0, + Msg: &UnsubscribeMsg{ + Stream: stream, + }, + Peer: peerID, + }, + }, + }) + + if err != nil { + t.Fatal(err) + } +} + +func TestStreamerUpstreamSubscribeErrorMsgExchange(t *testing.T) { + tester, streamer, _, teardown, err := newStreamerTester(t) + defer teardown() + if err != nil { + t.Fatal(err) + } + + streamer.RegisterServerFunc("foo", func(p *Peer, t string, live bool) (Server, error) { + return newTestServer(t), nil + }) + + stream := NewStream("bar", "", true) + + peerID := tester.IDs[0] + + err = tester.TestExchanges(p2ptest.Exchange{ + Label: "Subscribe message", + Triggers: []p2ptest.Trigger{ + { + Code: 4, + Msg: &SubscribeMsg{ + Stream: stream, + History: NewRange(5, 8), + Priority: Top, + }, + Peer: peerID, + }, + }, + Expects: []p2ptest.Expect{ + { + Code: 7, + Msg: &SubscribeErrorMsg{ + Error: "stream bar not registered", + }, + Peer: peerID, + }, + }, + }) + + if err != nil { + t.Fatal(err) + } +} + +func TestStreamerUpstreamSubscribeLiveAndHistory(t *testing.T) { + tester, streamer, _, teardown, err := newStreamerTester(t) + defer teardown() + if err != nil { + t.Fatal(err) + } + + stream := NewStream("foo", "", true) + + streamer.RegisterServerFunc("foo", func(p *Peer, t string, live bool) (Server, error) { + return &testServer{ + t: t, + }, nil + }) + + peerID := tester.IDs[0] + + err = tester.TestExchanges(p2ptest.Exchange{ + Label: "Subscribe message", + Triggers: []p2ptest.Trigger{ + { + Code: 4, + Msg: &SubscribeMsg{ + Stream: stream, + History: NewRange(5, 8), + Priority: Top, + }, + Peer: peerID, + }, + }, + Expects: []p2ptest.Expect{ + { + Code: 1, + Msg: &OfferedHashesMsg{ + Stream: NewStream("foo", "", false), + HandoverProof: &HandoverProof{ + Handover: &Handover{}, + }, + Hashes: make([]byte, HashSize), + From: 6, + To: 9, + }, + Peer: peerID, + }, + { + Code: 1, + Msg: &OfferedHashesMsg{ + Stream: stream, + HandoverProof: &HandoverProof{ + Handover: &Handover{}, + }, + From: 1, + To: 1, + Hashes: make([]byte, HashSize), + }, + Peer: peerID, + }, + }, + }) + + if err != nil { + t.Fatal(err) + } +} + +func TestStreamerDownstreamOfferedHashesMsgExchange(t *testing.T) { + tester, streamer, _, teardown, err := newStreamerTester(t) + defer teardown() + if err != nil { + t.Fatal(err) + } + + stream := NewStream("foo", "", true) + + var tc *testClient + + streamer.RegisterClientFunc("foo", func(p *Peer, t string, live bool) (Client, error) { + tc = newTestClient(t) + return tc, nil + }) + + peerID := tester.IDs[0] + + err = streamer.Subscribe(peerID, stream, NewRange(5, 8), Top) + if err != nil { + t.Fatalf("Expected no error, got %v", err) + } + + err = tester.TestExchanges(p2ptest.Exchange{ + Label: "Subscribe message", + Expects: []p2ptest.Expect{ + { + Code: 4, + Msg: &SubscribeMsg{ + Stream: stream, + History: NewRange(5, 8), + Priority: Top, + }, + Peer: peerID, + }, + }, + }, + p2ptest.Exchange{ + Label: "WantedHashes message", + Triggers: []p2ptest.Trigger{ + { + Code: 1, + Msg: &OfferedHashesMsg{ + HandoverProof: &HandoverProof{ + Handover: &Handover{}, + }, + Hashes: hashes, + From: 5, + To: 8, + Stream: stream, + }, + Peer: peerID, + }, + }, + Expects: []p2ptest.Expect{ + { + Code: 2, + Msg: &WantedHashesMsg{ + Stream: stream, + Want: []byte{5}, + From: 9, + To: 0, + }, + Peer: peerID, + }, + }, + }) + if err != nil { + t.Fatal(err) + } + + if len(tc.receivedHashes) != 3 { + t.Fatalf("Expected number of received hashes %v, got %v", 3, len(tc.receivedHashes)) + } + + close(tc.wait0) + + timeout := time.NewTimer(100 * time.Millisecond) + defer timeout.Stop() + + select { + case <-tc.batchDone: + t.Fatal("batch done early") + case <-timeout.C: + } + + close(tc.wait2) + + timeout2 := time.NewTimer(10000 * time.Millisecond) + defer timeout2.Stop() + + select { + case <-tc.batchDone: + case <-timeout2.C: + t.Fatal("timeout waiting batchdone call") + } + +} + +func TestStreamerRequestSubscriptionQuitMsgExchange(t *testing.T) { + tester, streamer, _, teardown, err := newStreamerTester(t) + defer teardown() + if err != nil { + t.Fatal(err) + } + + streamer.RegisterServerFunc("foo", func(p *Peer, t string, live bool) (Server, error) { + return newTestServer(t), nil + }) + + peerID := tester.IDs[0] + + stream := NewStream("foo", "", true) + err = streamer.RequestSubscription(peerID, stream, NewRange(5, 8), Top) + if err != nil { + t.Fatalf("Expected no error, got %v", err) + } + + err = tester.TestExchanges( + p2ptest.Exchange{ + Label: "RequestSubscription message", + Expects: []p2ptest.Expect{ + { + Code: 8, + Msg: &RequestSubscriptionMsg{ + Stream: stream, + History: NewRange(5, 8), + Priority: Top, + }, + Peer: peerID, + }, + }, + }, + p2ptest.Exchange{ + Label: "Subscribe message", + Triggers: []p2ptest.Trigger{ + { + Code: 4, + Msg: &SubscribeMsg{ + Stream: stream, + History: NewRange(5, 8), + Priority: Top, + }, + Peer: peerID, + }, + }, + Expects: []p2ptest.Expect{ + { + Code: 1, + Msg: &OfferedHashesMsg{ + Stream: NewStream("foo", "", false), + HandoverProof: &HandoverProof{ + Handover: &Handover{}, + }, + Hashes: make([]byte, HashSize), + From: 6, + To: 9, + }, + Peer: peerID, + }, + { + Code: 1, + Msg: &OfferedHashesMsg{ + Stream: stream, + HandoverProof: &HandoverProof{ + Handover: &Handover{}, + }, + From: 1, + To: 1, + Hashes: make([]byte, HashSize), + }, + Peer: peerID, + }, + }, + }, + ) + if err != nil { + t.Fatal(err) + } + + err = streamer.Quit(peerID, stream) + if err != nil { + t.Fatalf("Expected no error, got %v", err) + } + + err = tester.TestExchanges(p2ptest.Exchange{ + Label: "Quit message", + Expects: []p2ptest.Expect{ + { + Code: 9, + Msg: &QuitMsg{ + Stream: stream, + }, + Peer: peerID, + }, + }, + }) + + if err != nil { + t.Fatal(err) + } + + historyStream := getHistoryStream(stream) + + err = streamer.Quit(peerID, historyStream) + if err != nil { + t.Fatalf("Expected no error, got %v", err) + } + + err = tester.TestExchanges(p2ptest.Exchange{ + Label: "Quit message", + Expects: []p2ptest.Expect{ + { + Code: 9, + Msg: &QuitMsg{ + Stream: historyStream, + }, + Peer: peerID, + }, + }, + }) + + if err != nil { + t.Fatal(err) + } +} diff --git a/swarm/network/stream/syncer.go b/swarm/network/stream/syncer.go new file mode 100644 index 0000000000..d7febe4a3e --- /dev/null +++ b/swarm/network/stream/syncer.go @@ -0,0 +1,298 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package stream + +import ( + "context" + "math" + "strconv" + "time" + + "github.com/ethereum/go-ethereum/metrics" + "github.com/ethereum/go-ethereum/swarm/log" + "github.com/ethereum/go-ethereum/swarm/storage" +) + +const ( + // BatchSize = 2 + BatchSize = 128 +) + +// SwarmSyncerServer implements an Server for history syncing on bins +// offered streams: +// * live request delivery with or without checkback +// * (live/non-live historical) chunk syncing per proximity bin +type SwarmSyncerServer struct { + po uint8 + db *storage.DBAPI + sessionAt uint64 + start uint64 + quit chan struct{} +} + +// NewSwarmSyncerServer is contructor for SwarmSyncerServer +func NewSwarmSyncerServer(live bool, po uint8, db *storage.DBAPI) (*SwarmSyncerServer, error) { + sessionAt := db.CurrentBucketStorageIndex(po) + var start uint64 + if live { + start = sessionAt + } + return &SwarmSyncerServer{ + po: po, + db: db, + sessionAt: sessionAt, + start: start, + quit: make(chan struct{}), + }, nil +} + +func RegisterSwarmSyncerServer(streamer *Registry, db *storage.DBAPI) { + streamer.RegisterServerFunc("SYNC", func(p *Peer, t string, live bool) (Server, error) { + po, err := ParseSyncBinKey(t) + if err != nil { + return nil, err + } + return NewSwarmSyncerServer(live, po, db) + }) + // streamer.RegisterServerFunc(stream, func(p *Peer) (Server, error) { + // return NewOutgoingProvableSwarmSyncer(po, db) + // }) +} + +// Close needs to be called on a stream server +func (s *SwarmSyncerServer) Close() { + close(s.quit) +} + +// GetSection retrieves the actual chunk from localstore +func (s *SwarmSyncerServer) GetData(ctx context.Context, key []byte) ([]byte, error) { + chunk, err := s.db.Get(ctx, storage.Address(key)) + if err == storage.ErrFetching { + <-chunk.ReqC + } else if err != nil { + return nil, err + } + return chunk.SData, nil +} + +// GetBatch retrieves the next batch of hashes from the dbstore +func (s *SwarmSyncerServer) SetNextBatch(from, to uint64) ([]byte, uint64, uint64, *HandoverProof, error) { + var batch []byte + i := 0 + if from == 0 { + from = s.start + } + if to <= from || from >= s.sessionAt { + to = math.MaxUint64 + } + var ticker *time.Ticker + defer func() { + if ticker != nil { + ticker.Stop() + } + }() + var wait bool + for { + if wait { + if ticker == nil { + ticker = time.NewTicker(1000 * time.Millisecond) + } + select { + case <-ticker.C: + case <-s.quit: + return nil, 0, 0, nil, nil + } + } + + metrics.GetOrRegisterCounter("syncer.setnextbatch.iterator", nil).Inc(1) + err := s.db.Iterator(from, to, s.po, func(addr storage.Address, idx uint64) bool { + batch = append(batch, addr[:]...) + i++ + to = idx + return i < BatchSize + }) + if err != nil { + return nil, 0, 0, nil, err + } + if len(batch) > 0 { + break + } + wait = true + } + + log.Trace("Swarm syncer offer batch", "po", s.po, "len", i, "from", from, "to", to, "current store count", s.db.CurrentBucketStorageIndex(s.po)) + return batch, from, to, nil, nil +} + +// SwarmSyncerClient +type SwarmSyncerClient struct { + sessionAt uint64 + nextC chan struct{} + sessionRoot storage.Address + sessionReader storage.LazySectionReader + retrieveC chan *storage.Chunk + storeC chan *storage.Chunk + db *storage.DBAPI + // chunker storage.Chunker + currentRoot storage.Address + requestFunc func(chunk *storage.Chunk) + end, start uint64 + peer *Peer + ignoreExistingRequest bool + stream Stream +} + +// NewSwarmSyncerClient is a contructor for provable data exchange syncer +func NewSwarmSyncerClient(p *Peer, db *storage.DBAPI, ignoreExistingRequest bool, stream Stream) (*SwarmSyncerClient, error) { + return &SwarmSyncerClient{ + db: db, + peer: p, + ignoreExistingRequest: ignoreExistingRequest, + stream: stream, + }, nil +} + +// // NewIncomingProvableSwarmSyncer is a contructor for provable data exchange syncer +// func NewIncomingProvableSwarmSyncer(po int, priority int, index uint64, sessionAt uint64, intervals []uint64, sessionRoot storage.Key, chunker *storage.PyramidChunker, store storage.ChunkStore, p Peer) *SwarmSyncerClient { +// retrieveC := make(storage.Chunk, chunksCap) +// RunChunkRequestor(p, retrieveC) +// storeC := make(storage.Chunk, chunksCap) +// RunChunkStorer(store, storeC) +// s := &SwarmSyncerClient{ +// po: po, +// priority: priority, +// sessionAt: sessionAt, +// start: index, +// end: index, +// nextC: make(chan struct{}, 1), +// intervals: intervals, +// sessionRoot: sessionRoot, +// sessionReader: chunker.Join(sessionRoot, retrieveC), +// retrieveC: retrieveC, +// storeC: storeC, +// } +// return s +// } + +// // StartSyncing is called on the Peer to start the syncing process +// // the idea is that it is called only after kademlia is close to healthy +// func StartSyncing(s *Streamer, peerId discover.NodeID, po uint8, nn bool) { +// lastPO := po +// if nn { +// lastPO = maxPO +// } +// +// for i := po; i <= lastPO; i++ { +// s.Subscribe(peerId, "SYNC", newSyncLabel("LIVE", po), 0, 0, High, true) +// s.Subscribe(peerId, "SYNC", newSyncLabel("HISTORY", po), 0, 0, Mid, false) +// } +// } + +// RegisterSwarmSyncerClient registers the client constructor function for +// to handle incoming sync streams +func RegisterSwarmSyncerClient(streamer *Registry, db *storage.DBAPI) { + streamer.RegisterClientFunc("SYNC", func(p *Peer, t string, live bool) (Client, error) { + return NewSwarmSyncerClient(p, db, true, NewStream("SYNC", t, live)) + }) +} + +// NeedData +func (s *SwarmSyncerClient) NeedData(ctx context.Context, key []byte) (wait func()) { + chunk, _ := s.db.GetOrCreateRequest(ctx, key) + // TODO: we may want to request from this peer anyway even if the request exists + + // ignoreExistingRequest is temporary commented out until its functionality is verified. + // For now, this optimization can be disabled. + if chunk.ReqC == nil { //|| (s.ignoreExistingRequest && !created) { + return nil + } + // create request and wait until the chunk data arrives and is stored + return func() { + chunk.WaitToStore() + } +} + +// BatchDone +func (s *SwarmSyncerClient) BatchDone(stream Stream, from uint64, hashes []byte, root []byte) func() (*TakeoverProof, error) { + // TODO: reenable this with putter/getter refactored code + // if s.chunker != nil { + // return func() (*TakeoverProof, error) { return s.TakeoverProof(stream, from, hashes, root) } + // } + return nil +} + +func (s *SwarmSyncerClient) TakeoverProof(stream Stream, from uint64, hashes []byte, root storage.Address) (*TakeoverProof, error) { + // for provable syncer currentRoot is non-zero length + // TODO: reenable this with putter/getter + // if s.chunker != nil { + // if from > s.sessionAt { // for live syncing currentRoot is always updated + // //expRoot, err := s.chunker.Append(s.currentRoot, bytes.NewReader(hashes), s.retrieveC, s.storeC) + // expRoot, _, err := s.chunker.Append(s.currentRoot, bytes.NewReader(hashes), s.retrieveC) + // if err != nil { + // return nil, err + // } + // if !bytes.Equal(root, expRoot) { + // return nil, fmt.Errorf("HandoverProof mismatch") + // } + // s.currentRoot = root + // } else { + // expHashes := make([]byte, len(hashes)) + // _, err := s.sessionReader.ReadAt(expHashes, int64(s.end*HashSize)) + // if err != nil && err != io.EOF { + // return nil, err + // } + // if !bytes.Equal(expHashes, hashes) { + // return nil, errors.New("invalid proof") + // } + // } + // return nil, nil + // } + s.end += uint64(len(hashes)) / HashSize + takeover := &Takeover{ + Stream: stream, + Start: s.start, + End: s.end, + Root: root, + } + // serialise and sign + return &TakeoverProof{ + Takeover: takeover, + Sig: nil, + }, nil +} + +func (s *SwarmSyncerClient) Close() {} + +// base for parsing and formating sync bin key +// it must be 2 <= base <= 36 +const syncBinKeyBase = 36 + +// FormatSyncBinKey returns a string representation of +// Kademlia bin number to be used as key for SYNC stream. +func FormatSyncBinKey(bin uint8) string { + return strconv.FormatUint(uint64(bin), syncBinKeyBase) +} + +// ParseSyncBinKey parses the string representation +// and returns the Kademlia bin number. +func ParseSyncBinKey(s string) (uint8, error) { + bin, err := strconv.ParseUint(s, syncBinKeyBase, 8) + if err != nil { + return 0, err + } + return uint8(bin), nil +} diff --git a/swarm/network/stream/syncer_test.go b/swarm/network/stream/syncer_test.go new file mode 100644 index 0000000000..f72aa34441 --- /dev/null +++ b/swarm/network/stream/syncer_test.go @@ -0,0 +1,242 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package stream + +import ( + "context" + crand "crypto/rand" + "fmt" + "io" + "io/ioutil" + "math" + "os" + "sync" + "testing" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/node" + "github.com/ethereum/go-ethereum/p2p" + "github.com/ethereum/go-ethereum/p2p/discover" + "github.com/ethereum/go-ethereum/p2p/simulations/adapters" + "github.com/ethereum/go-ethereum/swarm/log" + "github.com/ethereum/go-ethereum/swarm/network" + "github.com/ethereum/go-ethereum/swarm/network/simulation" + "github.com/ethereum/go-ethereum/swarm/state" + "github.com/ethereum/go-ethereum/swarm/storage" + mockdb "github.com/ethereum/go-ethereum/swarm/storage/mock/db" +) + +const dataChunkCount = 200 + +func TestSyncerSimulation(t *testing.T) { + testSyncBetweenNodes(t, 2, 1, dataChunkCount, true, 1) + testSyncBetweenNodes(t, 4, 1, dataChunkCount, true, 1) + testSyncBetweenNodes(t, 8, 1, dataChunkCount, true, 1) + testSyncBetweenNodes(t, 16, 1, dataChunkCount, true, 1) +} + +func createMockStore(globalStore *mockdb.GlobalStore, id discover.NodeID, addr *network.BzzAddr) (lstore storage.ChunkStore, datadir string, err error) { + address := common.BytesToAddress(id.Bytes()) + mockStore := globalStore.NewNodeStore(address) + params := storage.NewDefaultLocalStoreParams() + + datadir, err = ioutil.TempDir("", "localMockStore-"+id.TerminalString()) + if err != nil { + return nil, "", err + } + params.Init(datadir) + params.BaseKey = addr.Over() + lstore, err = storage.NewLocalStore(params, mockStore) + return lstore, datadir, nil +} + +func testSyncBetweenNodes(t *testing.T, nodes, conns, chunkCount int, skipCheck bool, po uint8) { + sim := simulation.New(map[string]simulation.ServiceFunc{ + "streamer": func(ctx *adapters.ServiceContext, bucket *sync.Map) (s node.Service, cleanup func(), err error) { + var store storage.ChunkStore + var globalStore *mockdb.GlobalStore + var gDir, datadir string + + id := ctx.Config.ID + addr := network.NewAddrFromNodeID(id) + //hack to put addresses in same space + addr.OAddr[0] = byte(0) + + if *useMockStore { + gDir, globalStore, err = createGlobalStore() + if err != nil { + return nil, nil, fmt.Errorf("Something went wrong; using mockStore enabled but globalStore is nil") + } + store, datadir, err = createMockStore(globalStore, id, addr) + } else { + store, datadir, err = createTestLocalStorageForID(id, addr) + } + if err != nil { + return nil, nil, err + } + bucket.Store(bucketKeyStore, store) + cleanup = func() { + store.Close() + os.RemoveAll(datadir) + if *useMockStore { + err := globalStore.Close() + if err != nil { + log.Error("Error closing global store! %v", "err", err) + } + os.RemoveAll(gDir) + } + } + localStore := store.(*storage.LocalStore) + db := storage.NewDBAPI(localStore) + bucket.Store(bucketKeyDB, db) + kad := network.NewKademlia(addr.Over(), network.NewKadParams()) + delivery := NewDelivery(kad, db) + bucket.Store(bucketKeyDelivery, delivery) + + r := NewRegistry(addr, delivery, db, state.NewInmemoryStore(), &RegistryOptions{ + SkipCheck: skipCheck, + }) + + fileStore := storage.NewFileStore(storage.NewNetStore(localStore, nil), storage.NewFileStoreParams()) + bucket.Store(bucketKeyFileStore, fileStore) + + return r, cleanup, nil + + }, + }) + defer sim.Close() + + // create context for simulation run + timeout := 30 * time.Second + ctx, cancel := context.WithTimeout(context.Background(), timeout) + // defer cancel should come before defer simulation teardown + defer cancel() + + _, err := sim.AddNodesAndConnectChain(nodes) + if err != nil { + t.Fatal(err) + } + result := sim.Run(ctx, func(ctx context.Context, sim *simulation.Simulation) error { + nodeIDs := sim.UpNodeIDs() + + nodeIndex := make(map[discover.NodeID]int) + for i, id := range nodeIDs { + nodeIndex[id] = i + } + + disconnections := sim.PeerEvents( + context.Background(), + sim.NodeIDs(), + simulation.NewPeerEventsFilter().Type(p2p.PeerEventTypeDrop), + ) + + go func() { + for d := range disconnections { + if d.Error != nil { + log.Error("peer drop", "node", d.NodeID, "peer", d.Event.Peer) + t.Fatal(d.Error) + } + } + }() + + // each node Subscribes to each other's swarmChunkServerStreamName + for j := 0; j < nodes-1; j++ { + id := nodeIDs[j] + client, err := sim.Net.GetNode(id).Client() + if err != nil { + t.Fatal(err) + } + sid := nodeIDs[j+1] + client.CallContext(ctx, nil, "stream_subscribeStream", sid, NewStream("SYNC", FormatSyncBinKey(1), false), NewRange(0, 0), Top) + if err != nil { + return err + } + if j > 0 || nodes == 2 { + item, ok := sim.NodeItem(nodeIDs[j], bucketKeyFileStore) + if !ok { + return fmt.Errorf("No filestore") + } + fileStore := item.(*storage.FileStore) + size := chunkCount * chunkSize + _, wait, err := fileStore.Store(ctx, io.LimitReader(crand.Reader, int64(size)), int64(size), false) + if err != nil { + t.Fatal(err.Error()) + } + wait(ctx) + } + } + // here we distribute chunks of a random file into stores 1...nodes + if _, err := sim.WaitTillHealthy(ctx, 2); err != nil { + return err + } + + // collect hashes in po 1 bin for each node + hashes := make([][]storage.Address, nodes) + totalHashes := 0 + hashCounts := make([]int, nodes) + for i := nodes - 1; i >= 0; i-- { + if i < nodes-1 { + hashCounts[i] = hashCounts[i+1] + } + item, ok := sim.NodeItem(nodeIDs[i], bucketKeyDB) + if !ok { + return fmt.Errorf("No DB") + } + db := item.(*storage.DBAPI) + db.Iterator(0, math.MaxUint64, po, func(addr storage.Address, index uint64) bool { + hashes[i] = append(hashes[i], addr) + totalHashes++ + hashCounts[i]++ + return true + }) + } + var total, found int + for _, node := range nodeIDs { + i := nodeIndex[node] + + for j := i; j < nodes; j++ { + total += len(hashes[j]) + for _, key := range hashes[j] { + item, ok := sim.NodeItem(nodeIDs[j], bucketKeyDB) + if !ok { + return fmt.Errorf("No DB") + } + db := item.(*storage.DBAPI) + chunk, err := db.Get(ctx, key) + if err == storage.ErrFetching { + <-chunk.ReqC + } else if err != nil { + continue + } + // needed for leveldb not to be closed? + // chunk.WaitToStore() + found++ + } + } + log.Debug("sync check", "node", node, "index", i, "bin", po, "found", found, "total", total) + } + if total == found && total > 0 { + return nil + } + return fmt.Errorf("Total not equallying found: total is %d", total) + }) + + if result.Error != nil { + t.Fatal(result.Error) + } +} diff --git a/swarm/network/stream/testing/snapshot_128.json b/swarm/network/stream/testing/snapshot_128.json new file mode 100644 index 0000000000..e9d043e4e3 --- /dev/null +++ b/swarm/network/stream/testing/snapshot_128.json @@ -0,0 +1 @@ +{"nodes":[{"node":{"info":{"id":"a9e0b763852706722dc904b494293f9399c0fa32255890aa720285b8160335bb618f36b68a81b875a805384179f600defef474d486b4ea04b003ef6477ab7907","name":"node_a9e0b763852706722dc904b494293f9399c0fa32255890aa720285b8160335bb618f36b68a81b875a805384179f600defef474d486b4ea04b003ef6477ab7907","enode":"enode://a9e0b763852706722dc904b494293f9399c0fa32255890aa720285b8160335bb618f36b68a81b875a805384179f600defef474d486b4ea04b003ef6477ab7907@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"GPbMQHc6Qt2tPj5sX9hlplLLtC6QVPDkbfrtF6QdT08=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 18f6cc\npopulation: 16 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 f07c | 68 aec5 (0) ac23 (0) aa19 (0) a8ba (0)\n001 3 7f5f 78bf 6a57 | 37 740b (0) 7692 (0) 7628 (0) 7c76 (0)\n002 4 2dc2 2aef 3f1e 314e | 12 237b (0) 2650 (0) 2dc2 (0) 2fee (0)\n003 2 059a 0400 | 4 0047 (0) 06db (0) 059a (0) 0400 (0)\n004 2 11a6 1385 | 2 11a6 (0) 1385 (0)\n005 2 1ea8 1f2a | 2 1ea8 (0) 1f2a (0)\n============ DEPTH: 6 ==========================================\n006 1 1ab1 | 1 1ab1 (0)\n007 1 1943 | 1 1943 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"a9e0b763852706722dc904b494293f9399c0fa32255890aa720285b8160335bb618f36b68a81b875a805384179f600defef474d486b4ea04b003ef6477ab7907","private_key":"73015943fd2c673001da6bf6658a12a22e057fc545ac0ebc78421f90f1370093","name":"node_a9e0b763852706722dc904b494293f9399c0fa32255890aa720285b8160335bb618f36b68a81b875a805384179f600defef474d486b4ea04b003ef6477ab7907","services":["streamer"],"enable_msg_events":true,"port":63042},"up":true}},{"node":{"info":{"id":"87e696a354d249493217dc4e0190082f30e09616873803efa376871d4b34f86f0eeb4643d4822d8a0fbcdedb27cd6ba5438e98943d358d960c4835e82261c93e","name":"node_87e696a354d249493217dc4e0190082f30e09616873803efa376871d4b34f86f0eeb4643d4822d8a0fbcdedb27cd6ba5438e98943d358d960c4835e82261c93e","enode":"enode://87e696a354d249493217dc4e0190082f30e09616873803efa376871d4b34f86f0eeb4643d4822d8a0fbcdedb27cd6ba5438e98943d358d960c4835e82261c93e@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"8Hwe4PnK3ylxoMsAItHGf6gsefY8uYdpsxzPsE0FwKg=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: f07c1e\npopulation: 13 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 53ea 18f6 | 60 740b (0) 7692 (0) 7628 (0) 7c76 (0)\n001 2 92e2 9cbc | 32 aec5 (0) ac23 (0) aa19 (0) a8ba (0)\n002 3 d7f9 cac9 c243 | 17 db59 (0) d87f (0) d80b (0) d916 (0)\n003 1 e0ac | 9 ec3b (0) ebf9 (0) ea51 (0) ea94 (0)\n004 2 f80e fa62 | 6 feb3 (0) f995 (0) f836 (0) f80e (0)\n005 0 | 0\n============ DEPTH: 6 ==========================================\n006 3 f2b8 f29f f3a1 | 3 f2b8 (0) f29f (0) f3a1 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"87e696a354d249493217dc4e0190082f30e09616873803efa376871d4b34f86f0eeb4643d4822d8a0fbcdedb27cd6ba5438e98943d358d960c4835e82261c93e","private_key":"89cbfe6d806f2aeaee6a59667df3c3059ff7531bb33d64661586b004fcb6b831","name":"node_87e696a354d249493217dc4e0190082f30e09616873803efa376871d4b34f86f0eeb4643d4822d8a0fbcdedb27cd6ba5438e98943d358d960c4835e82261c93e","services":["streamer"],"enable_msg_events":true,"port":63043},"up":true}},{"node":{"info":{"id":"18bb6572965f4263c5a4d59a73027abc57a46122125ee58d871e95c993e6a1e8230438ce696a5f8880a08749837268b54319f7b0aa254c1a5bd453a8e9bcf84f","name":"node_18bb6572965f4263c5a4d59a73027abc57a46122125ee58d871e95c993e6a1e8230438ce696a5f8880a08749837268b54319f7b0aa254c1a5bd453a8e9bcf84f","enode":"enode://18bb6572965f4263c5a4d59a73027abc57a46122125ee58d871e95c993e6a1e8230438ce696a5f8880a08749837268b54319f7b0aa254c1a5bd453a8e9bcf84f@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"U+qpCRMTSlvap4DRi80z6FsZMtmxW8wQlvxGWOpep/g=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 53eaa9\npopulation: 18 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 8230 f07c | 68 b9e5 (0) bf7b (0) b220 (0) b1bf (0)\n001 3 0047 3f1e 314e | 23 237b (0) 2650 (0) 2dc2 (0) 2fee (0)\n002 4 6a57 6ac7 78bf 7f5f | 21 740b (0) 7692 (0) 7628 (0) 7c76 (0)\n003 5 4827 4ae6 4236 4454 | 11 4827 (0) 48a1 (0) 4ae6 (0) 4087 (0)\n004 2 5d6d 5b36 | 2 5d6d (0) 5b36 (0)\n============ DEPTH: 5 ==========================================\n005 1 57df | 1 57df (0)\n006 1 500f | 1 500f (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"18bb6572965f4263c5a4d59a73027abc57a46122125ee58d871e95c993e6a1e8230438ce696a5f8880a08749837268b54319f7b0aa254c1a5bd453a8e9bcf84f","private_key":"ff2ac479a33dc7fff5f87e4bb3078dfbcbb1567b76e35792faf104a383ebf896","name":"node_18bb6572965f4263c5a4d59a73027abc57a46122125ee58d871e95c993e6a1e8230438ce696a5f8880a08749837268b54319f7b0aa254c1a5bd453a8e9bcf84f","services":["streamer"],"enable_msg_events":true,"port":63044},"up":true}},{"node":{"info":{"id":"3103510e00a3f49a5e715719049fc8c9c67a2373a548f326458aeb6d9c75ed92b94373638fd075def0209113b4e85d972c23f064539f7b041596184e40d7f9a2","name":"node_3103510e00a3f49a5e715719049fc8c9c67a2373a548f326458aeb6d9c75ed92b94373638fd075def0209113b4e85d972c23f064539f7b041596184e40d7f9a2","enode":"enode://3103510e00a3f49a5e715719049fc8c9c67a2373a548f326458aeb6d9c75ed92b94373638fd075def0209113b4e85d972c23f064539f7b041596184e40d7f9a2@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"MU4eio2a4Y0LVRA0Gm+rD4ZUpyY6XbiVSArKYGtqmFk=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 314e1e\npopulation: 21 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 5 8ec6 9f97 b1bf b220 | 68 f07c (0) f2b8 (0) f29f (0) f3a1 (0)\n001 6 7f5f 7628 57df 53ea | 37 740b (0) 7692 (0) 7628 (0) 7c76 (0)\n002 2 18f6 0400 | 11 11a6 (0) 1385 (0) 1ea8 (0) 1f2a (0)\n003 4 2650 2fee 2dc2 2aef | 6 237b (0) 2650 (0) 2dc2 (0) 2fee (0)\n004 2 3e4f 3f1e | 3 3d3a (0) 3e4f (0) 3f1e (0)\n005 0 | 0\n006 0 | 0\n============ DEPTH: 7 ==========================================\n007 1 30a0 | 1 30a0 (0)\n008 0 | 0\n009 1 311f | 1 311f (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"3103510e00a3f49a5e715719049fc8c9c67a2373a548f326458aeb6d9c75ed92b94373638fd075def0209113b4e85d972c23f064539f7b041596184e40d7f9a2","private_key":"4800e21ac6431c61873444c525e207b48bb7a09ba2793b482ba6cf8cce81e353","name":"node_3103510e00a3f49a5e715719049fc8c9c67a2373a548f326458aeb6d9c75ed92b94373638fd075def0209113b4e85d972c23f064539f7b041596184e40d7f9a2","services":["streamer"],"enable_msg_events":true,"port":63045},"up":true}},{"node":{"info":{"id":"077d2d032874e5ce70e9b928b7fe72c0326ba92394e16245e31d48b5731d3d32bfd86acf40825decff54bcd735e9ebfd94eba677c418ea7007baec9db4af676d","name":"node_077d2d032874e5ce70e9b928b7fe72c0326ba92394e16245e31d48b5731d3d32bfd86acf40825decff54bcd735e9ebfd94eba677c418ea7007baec9db4af676d","enode":"enode://077d2d032874e5ce70e9b928b7fe72c0326ba92394e16245e31d48b5731d3d32bfd86acf40825decff54bcd735e9ebfd94eba677c418ea7007baec9db4af676d@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"R3jP9Cv8Xs9qh+ek5aYyg50wuPsQ5i+B63XZFeb0V64=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 4778cf\npopulation: 23 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 dc2a d68e | 68 f07c (0) f2b8 (0) f29f (0) f3a1 (0)\n001 1 314e | 23 11a6 (0) 1385 (0) 1ea8 (0) 1f2a (0)\n002 7 78bf 7bcf 7f62 7f5f | 21 740b (0) 7692 (0) 7628 (0) 7c76 (0)\n003 3 57df 53ea 5b36 | 5 57df (0) 500f (0) 53ea (0) 5d6d (0)\n004 3 4827 48a1 4ae6 | 3 4827 (0) 48a1 (0) 4ae6 (0)\n============ DEPTH: 5 ==========================================\n005 6 4087 4124 436c 4309 | 6 4087 (0) 4124 (0) 436c (0) 4309 (0)\n006 1 4454 | 1 4454 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"077d2d032874e5ce70e9b928b7fe72c0326ba92394e16245e31d48b5731d3d32bfd86acf40825decff54bcd735e9ebfd94eba677c418ea7007baec9db4af676d","private_key":"7e26b011ae2eabac951145e7840169b1f279577c06c40b4ba3a62da3ddb58de5","name":"node_077d2d032874e5ce70e9b928b7fe72c0326ba92394e16245e31d48b5731d3d32bfd86acf40825decff54bcd735e9ebfd94eba677c418ea7007baec9db4af676d","services":["streamer"],"enable_msg_events":true,"port":63046},"up":true}},{"node":{"info":{"id":"d90a81a583c82d626b92f27244f027da4a0ae76e6d3bdc1de0af7be01798f1fb04b34ce60c6d8651a39d7a70915438a4aa63e5adf844a9f7e38dbf0b1dba754d","name":"node_d90a81a583c82d626b92f27244f027da4a0ae76e6d3bdc1de0af7be01798f1fb04b34ce60c6d8651a39d7a70915438a4aa63e5adf844a9f7e38dbf0b1dba754d","enode":"enode://d90a81a583c82d626b92f27244f027da4a0ae76e6d3bdc1de0af7be01798f1fb04b34ce60c6d8651a39d7a70915438a4aa63e5adf844a9f7e38dbf0b1dba754d@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"Wzawq0hyhlpPhvKqE3uou0JzCQ5X/eMOwnpYrLFYwi8=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 5b36b0\npopulation: 24 (125), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 7 8bf5 87e0 8230 9cbc | 66 f80e (0) f995 (0) fba8 (0) fa62 (0)\n001 4 0047 0400 2650 3f1e | 23 11a6 (0) 1385 (0) 1f2a (0) 1ea8 (0)\n002 5 78bf 740b 7628 6ac7 | 21 740b (0) 7692 (0) 7628 (0) 7c76 (0)\n003 4 48a1 4ae6 4236 4778 | 11 4827 (0) 48a1 (0) 4ae6 (0) 4087 (0)\n============ DEPTH: 4 ==========================================\n004 3 57df 500f 53ea | 3 57df (0) 500f (0) 53ea (0)\n005 1 5d6d | 1 5d6d (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"d90a81a583c82d626b92f27244f027da4a0ae76e6d3bdc1de0af7be01798f1fb04b34ce60c6d8651a39d7a70915438a4aa63e5adf844a9f7e38dbf0b1dba754d","private_key":"1fbf6b44eeb20ef012046cf8b7d3400ef3e586586aaf1cf6a2e5115ff5e3d868","name":"node_d90a81a583c82d626b92f27244f027da4a0ae76e6d3bdc1de0af7be01798f1fb04b34ce60c6d8651a39d7a70915438a4aa63e5adf844a9f7e38dbf0b1dba754d","services":["streamer"],"enable_msg_events":true,"port":63047},"up":true}},{"node":{"info":{"id":"31ac37862416c0e229c4a088ec179f23bdd1bf12dd464eb11c630ad531d7c3438671862e5458e2f6fbb32b857f857e6b8c17e5d93eb29a0e78bb5a65d7eb648c","name":"node_31ac37862416c0e229c4a088ec179f23bdd1bf12dd464eb11c630ad531d7c3438671862e5458e2f6fbb32b857f857e6b8c17e5d93eb29a0e78bb5a65d7eb648c","enode":"enode://31ac37862416c0e229c4a088ec179f23bdd1bf12dd464eb11c630ad531d7c3438671862e5458e2f6fbb32b857f857e6b8c17e5d93eb29a0e78bb5a65d7eb648c@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"Px7ikS1URuTN96QlgvLjCiS83dZCKptqYfKH2iVtC94=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 3f1ee2\npopulation: 18 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 5 f2b8 9f97 8230 8ec6 | 68 e0ac (0) e39e (0) e3c3 (0) e5cd (0)\n001 4 78bf 4ae6 53ea 5b36 | 37 740b (0) 7628 (0) 7692 (0) 7c76 (0)\n002 3 18f6 0047 0400 | 11 11a6 (0) 1385 (0) 1ea8 (0) 1f2a (0)\n003 2 2fee 2aef | 6 237b (0) 2650 (0) 2dc2 (0) 2fee (0)\n004 2 30a0 314e | 3 30a0 (0) 311f (0) 314e (0)\n005 0 | 0\n============ DEPTH: 6 ==========================================\n006 1 3d3a | 1 3d3a (0)\n007 1 3e4f | 1 3e4f (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"31ac37862416c0e229c4a088ec179f23bdd1bf12dd464eb11c630ad531d7c3438671862e5458e2f6fbb32b857f857e6b8c17e5d93eb29a0e78bb5a65d7eb648c","private_key":"f32eafbb366e4b7655d302a06aac2e62ff8f4b9c07bb18175e58e534193b8554","name":"node_31ac37862416c0e229c4a088ec179f23bdd1bf12dd464eb11c630ad531d7c3438671862e5458e2f6fbb32b857f857e6b8c17e5d93eb29a0e78bb5a65d7eb648c","services":["streamer"],"enable_msg_events":true,"port":63048},"up":true}},{"node":{"info":{"id":"1e3c83cabbe6852c987ae521b7fcb33185cf855c59b6235ebb8e57a6f860ccc159ddc01b4a21d251c8faca4559ceb271e046a51493ba148c0d3aed97ad208969","name":"node_1e3c83cabbe6852c987ae521b7fcb33185cf855c59b6235ebb8e57a6f860ccc159ddc01b4a21d251c8faca4559ceb271e046a51493ba148c0d3aed97ad208969","enode":"enode://1e3c83cabbe6852c987ae521b7fcb33185cf855c59b6235ebb8e57a6f860ccc159ddc01b4a21d251c8faca4559ceb271e046a51493ba148c0d3aed97ad208969@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"i/Wdyc6X5uLyvjZDgKyjj5jd7CSOcwQi9YH1u1YXHjQ=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 8bf59d\npopulation: 14 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 5b36 3f1e | 60 740b (0) 7628 (0) 7692 (0) 7c76 (0)\n001 2 cac9 c243 | 36 ec3b (0) ea51 (0) ea94 (0) ebf9 (0)\n002 1 a250 | 12 b1bf (0) b220 (0) b9e5 (0) bf7b (0)\n003 3 97a5 96e9 9cbc | 10 981b (0) 9f97 (0) 9cbc (0) 931a (0)\n004 2 8230 87e0 | 5 811d (0) 8311 (0) 83bc (0) 8230 (0)\n============ DEPTH: 5 ==========================================\n005 4 8c5b 8e31 8ec6 8fe2 | 4 8c5b (0) 8e31 (0) 8ec6 (0) 8fe2 (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"1e3c83cabbe6852c987ae521b7fcb33185cf855c59b6235ebb8e57a6f860ccc159ddc01b4a21d251c8faca4559ceb271e046a51493ba148c0d3aed97ad208969","private_key":"6a809d9de0380db0b8bae8769cf41f9b05576137d0e2eefa69b7ddd921c6ac77","name":"node_1e3c83cabbe6852c987ae521b7fcb33185cf855c59b6235ebb8e57a6f860ccc159ddc01b4a21d251c8faca4559ceb271e046a51493ba148c0d3aed97ad208969","services":["streamer"],"enable_msg_events":true,"port":63049},"up":true}},{"node":{"info":{"id":"2fdb4382c4bc2950948a8cff13a7df65627bc0b20661cae20fd29acab166c97701594ee3151d75c006ba86d1d68b624b1d1f78e3d1e2fc297844956ef82208a8","name":"node_2fdb4382c4bc2950948a8cff13a7df65627bc0b20661cae20fd29acab166c97701594ee3151d75c006ba86d1d68b624b1d1f78e3d1e2fc297844956ef82208a8","enode":"enode://2fdb4382c4bc2950948a8cff13a7df65627bc0b20661cae20fd29acab166c97701594ee3151d75c006ba86d1d68b624b1d1f78e3d1e2fc297844956ef82208a8@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"h+AjKsxxJ+pHYEpb/oTYDjgpKQJQLCpxTg+W2AkOtP4=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 87e023\npopulation: 18 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 7f5f 5b36 4ae6 | 60 237b (0) 2650 (0) 2fee (0) 2dc2 (0)\n001 2 f3a1 c243 | 36 ec3b (0) ea94 (0) ea51 (0) ebf9 (0)\n002 2 bf7b a250 | 12 a8ba (0) aa19 (0) aec5 (0) ac23 (0)\n003 4 981b 9f97 9cbc 96e9 | 10 981b (0) 9f97 (0) 9cbc (0) 931a (0)\n004 3 8ec6 8fe2 8bf5 | 5 8c5b (0) 8fe2 (0) 8e31 (0) 8ec6 (0)\n============ DEPTH: 5 ==========================================\n005 4 811d 83bc 8311 8230 | 4 811d (0) 83bc (0) 8311 (0) 8230 (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"2fdb4382c4bc2950948a8cff13a7df65627bc0b20661cae20fd29acab166c97701594ee3151d75c006ba86d1d68b624b1d1f78e3d1e2fc297844956ef82208a8","private_key":"f23b80b698ec97210ddaa65807a07cee7b411018ddd96c9d700e92a83120cf9e","name":"node_2fdb4382c4bc2950948a8cff13a7df65627bc0b20661cae20fd29acab166c97701594ee3151d75c006ba86d1d68b624b1d1f78e3d1e2fc297844956ef82208a8","services":["streamer"],"enable_msg_events":true,"port":63050},"up":true}},{"node":{"info":{"id":"87fce129511a1be2777052d24b606acdfe7067f4e874ab04674a68664b378ea208975f7269a72af889d3d23cd930b6a181afa2cdef3f9f9491f715bd96ad8dc0","name":"node_87fce129511a1be2777052d24b606acdfe7067f4e874ab04674a68664b378ea208975f7269a72af889d3d23cd930b6a181afa2cdef3f9f9491f715bd96ad8dc0","enode":"enode://87fce129511a1be2777052d24b606acdfe7067f4e874ab04674a68664b378ea208975f7269a72af889d3d23cd930b6a181afa2cdef3f9f9491f715bd96ad8dc0@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"SuYUSQ2HOSBXc9FsgCfEa2fZO9M2wzBx2HB/6mrBrPM=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 4ae614\npopulation: 17 (123), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 87e0 | 64 ec3b (0) ea94 (0) ea51 (0) ebf9 (0)\n001 3 3f1e 0400 0047 | 23 237b (0) 2650 (0) 2dc2 (0) 2fee (0)\n002 1 6a57 | 21 7bcf (0) 78bf (0) 7c76 (0) 7e65 (0)\n003 3 57df 53ea 5b36 | 5 57df (0) 500f (0) 53ea (0) 5d6d (0)\n004 7 4087 4124 436c 4259 | 8 4087 (0) 4124 (0) 4309 (0) 436c (0)\n005 0 | 0\n============ DEPTH: 6 ==========================================\n006 2 4827 48a1 | 2 4827 (0) 48a1 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"87fce129511a1be2777052d24b606acdfe7067f4e874ab04674a68664b378ea208975f7269a72af889d3d23cd930b6a181afa2cdef3f9f9491f715bd96ad8dc0","private_key":"d2d74e454118a6e150810c74080ee7707b92b4575e7fe13c8887caf521cc734d","name":"node_87fce129511a1be2777052d24b606acdfe7067f4e874ab04674a68664b378ea208975f7269a72af889d3d23cd930b6a181afa2cdef3f9f9491f715bd96ad8dc0","services":["streamer"],"enable_msg_events":true,"port":63051},"up":true}},{"node":{"info":{"id":"c773af3af01ee8ab9fa8d06987baf4f10c394fdd386d69b7a7362f4b68fd6fc082337d3b33a19d584c5801a3e9198225d7b61f6629e34ce823be70908339f4c7","name":"node_c773af3af01ee8ab9fa8d06987baf4f10c394fdd386d69b7a7362f4b68fd6fc082337d3b33a19d584c5801a3e9198225d7b61f6629e34ce823be70908339f4c7","enode":"enode://c773af3af01ee8ab9fa8d06987baf4f10c394fdd386d69b7a7362f4b68fd6fc082337d3b33a19d584c5801a3e9198225d7b61f6629e34ce823be70908339f4c7@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"AEcQsuIZSozREpLv6Lb4G+xMG2c6nIpFt7U5H18EmJU=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 004710\npopulation: 11 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 a250 | 68 ec3b (0) ea94 (0) ea51 (0) ebf9 (0)\n001 5 78bf 6a57 5b36 53ea | 37 740b (0) 7628 (0) 7692 (0) 7c76 (0)\n002 1 3f1e | 12 237b (0) 2650 (0) 2dc2 (0) 2fee (0)\n003 1 1ea8 | 7 11a6 (0) 1385 (0) 1ab1 (0) 1943 (0)\n004 0 | 0\n============ DEPTH: 5 ==========================================\n005 3 06db 059a 0400 | 3 06db (0) 059a (0) 0400 (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"c773af3af01ee8ab9fa8d06987baf4f10c394fdd386d69b7a7362f4b68fd6fc082337d3b33a19d584c5801a3e9198225d7b61f6629e34ce823be70908339f4c7","private_key":"cdc72a1d2e475117e77abccdee1816e4d84fb059d712b717e8bd063239b6fd58","name":"node_c773af3af01ee8ab9fa8d06987baf4f10c394fdd386d69b7a7362f4b68fd6fc082337d3b33a19d584c5801a3e9198225d7b61f6629e34ce823be70908339f4c7","services":["streamer"],"enable_msg_events":true,"port":63052},"up":true}},{"node":{"info":{"id":"56b25623ac935f3a8aac1e2603a6bd15ace1e5714671954b47f2cab960cf47922828f415105602408d0a732a893ebeea6f9afab7f889bb235c81589548d09391","name":"node_56b25623ac935f3a8aac1e2603a6bd15ace1e5714671954b47f2cab960cf47922828f415105602408d0a732a893ebeea6f9afab7f889bb235c81589548d09391","enode":"enode://56b25623ac935f3a8aac1e2603a6bd15ace1e5714671954b47f2cab960cf47922828f415105602408d0a732a893ebeea6f9afab7f889bb235c81589548d09391@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"olBLw4yUt5Er+vxCx6RTHNJ3dUcwceeiYXPE25Mr+ew=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: a2504b\npopulation: 16 (125), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 500f 0047 | 58 740b (0) 7628 (0) 7692 (0) 7c76 (0)\n001 3 c243 fa62 e0ac | 36 ec3b (0) ebf9 (0) ea51 (0) ea94 (0)\n002 5 9cbc 96e9 8bf5 87e0 | 20 981b (0) 9f97 (0) 9cbc (0) 931a (0)\n003 1 bf7b | 4 b220 (0) b1bf (0) b9e5 (0) bf7b (0)\n004 2 ac23 aec5 | 4 a8ba (0) aa19 (0) ac23 (0) aec5 (0)\n005 1 a60b | 1 a60b (0)\n============ DEPTH: 6 ==========================================\n006 1 a12e | 1 a12e (0)\n007 1 a3fc | 1 a3fc (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"56b25623ac935f3a8aac1e2603a6bd15ace1e5714671954b47f2cab960cf47922828f415105602408d0a732a893ebeea6f9afab7f889bb235c81589548d09391","private_key":"b1b2452fe8ea070ff3b181fdc538144e1231f0c6f467713712662375dc6c4bb1","name":"node_56b25623ac935f3a8aac1e2603a6bd15ace1e5714671954b47f2cab960cf47922828f415105602408d0a732a893ebeea6f9afab7f889bb235c81589548d09391","services":["streamer"],"enable_msg_events":true,"port":63053},"up":true}},{"node":{"info":{"id":"09b60de1e85bb6f7d2caf5b1ab58204d7d04531ece300dcd7bcc9157b8b3ef2a182758808a0eec6056034f29f52caadb7c690f498c1c8832ff7a6a9ecff308bd","name":"node_09b60de1e85bb6f7d2caf5b1ab58204d7d04531ece300dcd7bcc9157b8b3ef2a182758808a0eec6056034f29f52caadb7c690f498c1c8832ff7a6a9ecff308bd","enode":"enode://09b60de1e85bb6f7d2caf5b1ab58204d7d04531ece300dcd7bcc9157b8b3ef2a182758808a0eec6056034f29f52caadb7c690f498c1c8832ff7a6a9ecff308bd@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"gjDkmcnAHLblcXM286iLaowQEAgXEvv6uWwwHiMETRQ=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 8230e4\npopulation: 22 (122), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 6 3f1e 0400 5b36 53ea | 55 7628 (0) 7692 (0) 740b (0) 7c76 (0)\n001 5 f3a1 e0ac e425 e5cd | 36 ec3b (0) ea94 (0) ea51 (0) ebf9 (0)\n002 1 a250 | 12 b220 (0) b1bf (0) b9e5 (0) bf7b (0)\n003 4 981b 9f97 9cbc 96e9 | 10 981b (0) 9f97 (0) 9cbc (0) 931a (0)\n004 2 8ec6 8bf5 | 5 8c5b (0) 8fe2 (0) 8e31 (0) 8ec6 (0)\n005 1 87e0 | 1 87e0 (0)\n006 1 811d | 1 811d (0)\n============ DEPTH: 7 ==========================================\n007 2 83bc 8311 | 2 83bc (0) 8311 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"09b60de1e85bb6f7d2caf5b1ab58204d7d04531ece300dcd7bcc9157b8b3ef2a182758808a0eec6056034f29f52caadb7c690f498c1c8832ff7a6a9ecff308bd","private_key":"e87535b0ec914ff93ea21f722eff61dd6cfea4f5542f68aab0af93c58e2afc25","name":"node_09b60de1e85bb6f7d2caf5b1ab58204d7d04531ece300dcd7bcc9157b8b3ef2a182758808a0eec6056034f29f52caadb7c690f498c1c8832ff7a6a9ecff308bd","services":["streamer"],"enable_msg_events":true,"port":63054},"up":true}},{"node":{"info":{"id":"f2ea93f43be9d0c3fa21f1496dc13c778977a6afdcba24c8b146de7dca2cdde62a5b792aab969e5b4b6c56f63066b336580d911f206049cc24cac32a25fc4306","name":"node_f2ea93f43be9d0c3fa21f1496dc13c778977a6afdcba24c8b146de7dca2cdde62a5b792aab969e5b4b6c56f63066b336580d911f206049cc24cac32a25fc4306","enode":"enode://f2ea93f43be9d0c3fa21f1496dc13c778977a6afdcba24c8b146de7dca2cdde62a5b792aab969e5b4b6c56f63066b336580d911f206049cc24cac32a25fc4306@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"wkMAOxESWbPN/dSsw2EKyNplv1gojVETPQPmgKQtcDQ=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: c24300\npopulation: 31 (105), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 0400 5b36 500f | 38 3f1e (0) 30a0 (0) 314e (0) 2650 (0)\n001 8 a250 981b 9cbc 96e9 | 32 b220 (0) b1bf (0) b9e5 (0) bf7b (0)\n002 6 ebf9 e425 f07c f29f | 19 ec3b (0) ea94 (0) ea51 (0) ebf9 (0)\n003 10 d916 d87f db59 d382 | 12 d192 (0) d386 (0) d382 (0) d552 (0)\n004 2 ca97 cac9 | 2 ca97 (0) cac9 (0)\n============ DEPTH: 5 ==========================================\n005 1 c7fd | 1 c7fd (0)\n006 0 | 0\n007 1 c358 | 1 c358 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"f2ea93f43be9d0c3fa21f1496dc13c778977a6afdcba24c8b146de7dca2cdde62a5b792aab969e5b4b6c56f63066b336580d911f206049cc24cac32a25fc4306","private_key":"3ae9a961f597c04b695a6d25fd0e6e47b131854f55f89d8ac25cce7411aa4107","name":"node_f2ea93f43be9d0c3fa21f1496dc13c778977a6afdcba24c8b146de7dca2cdde62a5b792aab969e5b4b6c56f63066b336580d911f206049cc24cac32a25fc4306","services":["streamer"],"enable_msg_events":true,"port":63055},"up":true}},{"node":{"info":{"id":"872cdbb6d74fb55fd2d51877ef7804bdd2eeb6de0297eb2ce18b67e52379b147d54a46d2385ec9293eb21736bed4191d92c5c75e8e81fc5a6c691970e019f570","name":"node_872cdbb6d74fb55fd2d51877ef7804bdd2eeb6de0297eb2ce18b67e52379b147d54a46d2385ec9293eb21736bed4191d92c5c75e8e81fc5a6c691970e019f570","enode":"enode://872cdbb6d74fb55fd2d51877ef7804bdd2eeb6de0297eb2ce18b67e52379b147d54a46d2385ec9293eb21736bed4191d92c5c75e8e81fc5a6c691970e019f570@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"UA8hNdsa2v4i2KYq9j8WWdb0U49JDugVHp25cPokOJs=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 500f21\npopulation: 12 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 a250 c243 | 68 b1bf (0) b220 (0) b9e5 (0) bf7b (0)\n001 2 2aef 0400 | 23 3d3a (0) 3e4f (0) 3f1e (0) 30a0 (0)\n002 1 6a57 | 21 740b (0) 7628 (0) 7692 (0) 7c76 (0)\n003 3 48a1 4259 4454 | 11 4827 (0) 48a1 (0) 4ae6 (0) 4124 (0)\n004 2 5d6d 5b36 | 2 5d6d (0) 5b36 (0)\n============ DEPTH: 5 ==========================================\n005 1 57df | 1 57df (0)\n006 1 53ea | 1 53ea (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"872cdbb6d74fb55fd2d51877ef7804bdd2eeb6de0297eb2ce18b67e52379b147d54a46d2385ec9293eb21736bed4191d92c5c75e8e81fc5a6c691970e019f570","private_key":"1676fda16b41e3ec275f0d30ad691055248be71252ad15422b9c0260671aaf4c","name":"node_872cdbb6d74fb55fd2d51877ef7804bdd2eeb6de0297eb2ce18b67e52379b147d54a46d2385ec9293eb21736bed4191d92c5c75e8e81fc5a6c691970e019f570","services":["streamer"],"enable_msg_events":true,"port":63056},"up":true}},{"node":{"info":{"id":"da3e0fd71eb96ba2cab7f920d32f5425d1aad41d00765fdffb0b215d9dd5b60e2bc5929eafebee5b2b5a11aec164e141beff19d828aac7d1fabd3ffb0bfb8450","name":"node_da3e0fd71eb96ba2cab7f920d32f5425d1aad41d00765fdffb0b215d9dd5b60e2bc5929eafebee5b2b5a11aec164e141beff19d828aac7d1fabd3ffb0bfb8450","enode":"enode://da3e0fd71eb96ba2cab7f920d32f5425d1aad41d00765fdffb0b215d9dd5b60e2bc5929eafebee5b2b5a11aec164e141beff19d828aac7d1fabd3ffb0bfb8450@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"BAC3lY2fAnDb4xRrgPqCHbrosM9w0RyaPT0UsUAS/ko=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 0400b7\npopulation: 23 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 6 8230 96e9 dc2a c243 | 68 b220 (0) b1bf (0) b9e5 (0) bf7b (0)\n001 4 78bf 4ae6 5b36 500f | 37 6632 (0) 6640 (0) 60ad (0) 6099 (0)\n002 4 2650 2aef 3f1e 314e | 12 3d3a (0) 3e4f (0) 3f1e (0) 30a0 (0)\n003 6 1385 1f2a 1ea8 1ab1 | 7 11a6 (0) 1385 (0) 1ea8 (0) 1f2a (0)\n004 0 | 0\n005 1 0047 | 1 0047 (0)\n============ DEPTH: 6 ==========================================\n006 1 06db | 1 06db (0)\n007 1 059a | 1 059a (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"da3e0fd71eb96ba2cab7f920d32f5425d1aad41d00765fdffb0b215d9dd5b60e2bc5929eafebee5b2b5a11aec164e141beff19d828aac7d1fabd3ffb0bfb8450","private_key":"6c989b24f2387e5a639effc8cd15b6d60c587fd14615496c9463d1f1a7ff6ad5","name":"node_da3e0fd71eb96ba2cab7f920d32f5425d1aad41d00765fdffb0b215d9dd5b60e2bc5929eafebee5b2b5a11aec164e141beff19d828aac7d1fabd3ffb0bfb8450","services":["streamer"],"enable_msg_events":true,"port":63057},"up":true}},{"node":{"info":{"id":"489660042a8867d90a16ebb013968db26ca3edfc70f53320f511e35b3703eed09fbd787be5c06726a570a54aa15d129cd10db741523adf297929f909be4a0c71","name":"node_489660042a8867d90a16ebb013968db26ca3edfc70f53320f511e35b3703eed09fbd787be5c06726a570a54aa15d129cd10db741523adf297929f909be4a0c71","enode":"enode://489660042a8867d90a16ebb013968db26ca3edfc70f53320f511e35b3703eed09fbd787be5c06726a570a54aa15d129cd10db741523adf297929f909be4a0c71@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"4KxrNNBLwDYCZ2coio8PlnIPSj76W1KzuGQ5+6VivPQ=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: e0ac6b\npopulation: 18 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 2dc2 0400 | 60 6632 (0) 6640 (0) 60ad (0) 6099 (0)\n001 4 a250 8230 9cbc 96e9 | 32 ac23 (0) aec5 (0) aa19 (0) a8ba (0)\n002 1 d68e | 17 d192 (0) d386 (0) d382 (0) d552 (0)\n003 5 f07c f2b8 f29f f3a1 | 10 f07c (0) f2b8 (0) f29f (0) f3a1 (0)\n004 2 ec3b ea51 | 4 ec3b (0) ea94 (0) ea51 (0) ebf9 (0)\n005 2 e5cd e425 | 2 e5cd (0) e425 (0)\n============ DEPTH: 6 ==========================================\n006 2 e39e e3c3 | 2 e39e (0) e3c3 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"489660042a8867d90a16ebb013968db26ca3edfc70f53320f511e35b3703eed09fbd787be5c06726a570a54aa15d129cd10db741523adf297929f909be4a0c71","private_key":"a1befe78e67ca8b4972ba564c3bd03ad2ca6b996ded22166468d7a268a4c77d3","name":"node_489660042a8867d90a16ebb013968db26ca3edfc70f53320f511e35b3703eed09fbd787be5c06726a570a54aa15d129cd10db741523adf297929f909be4a0c71","services":["streamer"],"enable_msg_events":true,"port":63058},"up":true}},{"node":{"info":{"id":"4448a59bde9edb93edcdb4a77f3e2277b9c01ffea45496ee0533eb5192955a08a0f982e25cf772e0dae68735a55b7acd221f6ba7b134f1e999087bee182330e8","name":"node_4448a59bde9edb93edcdb4a77f3e2277b9c01ffea45496ee0533eb5192955a08a0f982e25cf772e0dae68735a55b7acd221f6ba7b134f1e999087bee182330e8","enode":"enode://4448a59bde9edb93edcdb4a77f3e2277b9c01ffea45496ee0533eb5192955a08a0f982e25cf772e0dae68735a55b7acd221f6ba7b134f1e999087bee182330e8@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"luma37jY1ThtVzNJdflSXeCr1EGOUo8qjBphzCGHFCM=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 96e99a\npopulation: 24 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 0400 5b36 6a57 | 60 500f (0) 53ea (0) 57df (0) 5d6d (0)\n001 3 c243 e0ac fa62 | 36 d192 (0) d386 (0) d382 (0) d552 (0)\n002 2 bf7b a250 | 12 ac23 (0) aec5 (0) a8ba (0) aa19 (0)\n003 7 8fe2 8ec6 8bf5 87e0 | 10 8c5b (0) 8fe2 (0) 8e31 (0) 8ec6 (0)\n004 3 981b 9f97 9cbc | 3 981b (0) 9f97 (0) 9cbc (0)\n005 3 931a 9386 92e2 | 3 931a (0) 9386 (0) 92e2 (0)\n006 1 954a | 1 954a (0)\n============ DEPTH: 7 ==========================================\n007 1 97a5 | 1 97a5 (0)\n008 0 | 0\n009 1 96b7 | 1 96b7 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"4448a59bde9edb93edcdb4a77f3e2277b9c01ffea45496ee0533eb5192955a08a0f982e25cf772e0dae68735a55b7acd221f6ba7b134f1e999087bee182330e8","private_key":"6b9ad7d1da45cff60c3bdcac68f0af30e0a6e0e30e4ad73731c00368e9b0254a","name":"node_4448a59bde9edb93edcdb4a77f3e2277b9c01ffea45496ee0533eb5192955a08a0f982e25cf772e0dae68735a55b7acd221f6ba7b134f1e999087bee182330e8","services":["streamer"],"enable_msg_events":true,"port":63059},"up":true}},{"node":{"info":{"id":"73319a301ad3cf0ec09549d817c9523d61b74abb0cad87b737d41d900321e52722a84355f6f87bc7a5f848818c89a021bb0f3e5994f67c9a7b5bbfc98188a376","name":"node_73319a301ad3cf0ec09549d817c9523d61b74abb0cad87b737d41d900321e52722a84355f6f87bc7a5f848818c89a021bb0f3e5994f67c9a7b5bbfc98188a376","enode":"enode://73319a301ad3cf0ec09549d817c9523d61b74abb0cad87b737d41d900321e52722a84355f6f87bc7a5f848818c89a021bb0f3e5994f67c9a7b5bbfc98188a376@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"+mK2ha6KmqxmnSRRAs5osDDw8nDZXXyIlpv9yZePkHA=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: fa62b6\npopulation: 20 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 0400 2dc2 2aef | 60 500f (0) 53ea (0) 57df (0) 5d6d (0)\n001 3 a250 9cbc 96e9 | 32 aa19 (0) a8ba (0) ac23 (0) aec5 (0)\n002 1 c243 | 17 d192 (0) d386 (0) d382 (0) d552 (0)\n003 4 ebf9 e5cd e425 e0ac | 9 ec3b (0) ea94 (0) ea51 (0) ebf9 (0)\n004 4 f07c f2b8 f29f f3a1 | 4 f07c (0) f2b8 (0) f29f (0) f3a1 (0)\n005 1 feb3 | 1 feb3 (0)\n============ DEPTH: 6 ==========================================\n006 3 f995 f80e f836 | 3 f995 (0) f80e (0) f836 (0)\n007 1 fba8 | 1 fba8 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"73319a301ad3cf0ec09549d817c9523d61b74abb0cad87b737d41d900321e52722a84355f6f87bc7a5f848818c89a021bb0f3e5994f67c9a7b5bbfc98188a376","private_key":"157e46312708757a331443dd95e1a0c012502430f4a8f8756f0aeaf35bde1f6d","name":"node_73319a301ad3cf0ec09549d817c9523d61b74abb0cad87b737d41d900321e52722a84355f6f87bc7a5f848818c89a021bb0f3e5994f67c9a7b5bbfc98188a376","services":["streamer"],"enable_msg_events":true,"port":63060},"up":true}},{"node":{"info":{"id":"caad8529d498a4a1e1ba7573689a913500bd409345ef8e3656abca748269eb73b919282f7f2eb0087f81f7bc52c367657ac8be0cdac65d2490c7c50c874444b7","name":"node_caad8529d498a4a1e1ba7573689a913500bd409345ef8e3656abca748269eb73b919282f7f2eb0087f81f7bc52c367657ac8be0cdac65d2490c7c50c874444b7","enode":"enode://caad8529d498a4a1e1ba7573689a913500bd409345ef8e3656abca748269eb73b919282f7f2eb0087f81f7bc52c367657ac8be0cdac65d2490c7c50c874444b7@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"Ku+MTaTji2qIV4XkBpEs72CHNEtL6eE14sWXRosAMxU=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 2aef8c\npopulation: 15 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 9cbc f2b8 fa62 | 68 a8ba (0) aa19 (0) aec5 (0) ac23 (0)\n001 2 500f 7692 | 37 500f (0) 53ea (0) 57df (0) 5d6d (0)\n002 2 0400 18f6 | 11 0047 (0) 06db (0) 059a (0) 0400 (0)\n003 3 3e4f 3f1e 314e | 6 3d3a (0) 3e4f (0) 3f1e (0) 30a0 (0)\n004 2 237b 2650 | 2 237b (0) 2650 (0)\n============ DEPTH: 5 ==========================================\n005 2 2dc2 2fee | 2 2dc2 (0) 2fee (0)\n006 0 | 0\n007 0 | 0\n008 1 2a2b | 1 2a2b (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"caad8529d498a4a1e1ba7573689a913500bd409345ef8e3656abca748269eb73b919282f7f2eb0087f81f7bc52c367657ac8be0cdac65d2490c7c50c874444b7","private_key":"11148e1d9812b7bb8870b7960332ba4b32ea6aa43a57f9a27c30c2fafb609570","name":"node_caad8529d498a4a1e1ba7573689a913500bd409345ef8e3656abca748269eb73b919282f7f2eb0087f81f7bc52c367657ac8be0cdac65d2490c7c50c874444b7","services":["streamer"],"enable_msg_events":true,"port":63061},"up":true}},{"node":{"info":{"id":"44462055ba68fdef337dd19d8123aace9a12284c13bc97687416b6b4ca0c94234ba7db6823651fc021d6ac1539e0c5321e763a7a12c9e7c8a583aac5369817d8","name":"node_44462055ba68fdef337dd19d8123aace9a12284c13bc97687416b6b4ca0c94234ba7db6823651fc021d6ac1539e0c5321e763a7a12c9e7c8a583aac5369817d8","enode":"enode://44462055ba68fdef337dd19d8123aace9a12284c13bc97687416b6b4ca0c94234ba7db6823651fc021d6ac1539e0c5321e763a7a12c9e7c8a583aac5369817d8@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"nLyWqtj73eDC8ITzzvebVsFQ7H/DDcwthTXv6bM39MI=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 9cbc96\npopulation: 23 (75), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 2aef 5b36 7692 | 30 0047 (0) 0400 (0) 1385 (0) 11a6 (0)\n001 6 fa62 f3a1 f07c e5cd | 26 d192 (0) d382 (0) d68e (0) d7f9 (0)\n002 2 a250 b220 | 5 aec5 (0) a250 (0) bf7b (0) b1bf (0)\n003 4 8ec6 8bf5 87e0 8230 | 6 8fe2 (0) 8ec6 (0) 8bf5 (0) 87e0 (0)\n004 6 9386 931a 92e2 97a5 | 6 9386 (0) 931a (0) 92e2 (0) 97a5 (0)\n============ DEPTH: 5 ==========================================\n005 1 981b | 1 981b (0)\n006 1 9f97 | 1 9f97 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"44462055ba68fdef337dd19d8123aace9a12284c13bc97687416b6b4ca0c94234ba7db6823651fc021d6ac1539e0c5321e763a7a12c9e7c8a583aac5369817d8","private_key":"896c3ee65d71ddcbf6030b920c0bf7748971170583e45fa2e33c19b3222e3945","name":"node_44462055ba68fdef337dd19d8123aace9a12284c13bc97687416b6b4ca0c94234ba7db6823651fc021d6ac1539e0c5321e763a7a12c9e7c8a583aac5369817d8","services":["streamer"],"enable_msg_events":true,"port":63062},"up":true}},{"node":{"info":{"id":"ecbdca037cd7892752345b48b4219478b1b334f83ce7140fcc72eb71784436b690ce7a41b03e013cefc19d64a34a20cfef1b9e2b535d938bcdcb39fe63645a42","name":"node_ecbdca037cd7892752345b48b4219478b1b334f83ce7140fcc72eb71784436b690ce7a41b03e013cefc19d64a34a20cfef1b9e2b535d938bcdcb39fe63645a42","enode":"enode://ecbdca037cd7892752345b48b4219478b1b334f83ce7140fcc72eb71784436b690ce7a41b03e013cefc19d64a34a20cfef1b9e2b535d938bcdcb39fe63645a42@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"dpI5nwEXfyqJdtTDk6aBPFOCDl9O31STRBTRvN+4OSw=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 769239\npopulation: 19 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 f3a1 ac23 9cbc | 68 d192 (0) d386 (0) d382 (0) d552 (0)\n001 3 1943 3d3a 2aef | 23 0047 (0) 06db (0) 059a (0) 0400 (0)\n002 3 57df 4778 4087 | 16 500f (0) 53ea (0) 57df (0) 5d6d (0)\n003 3 6cf1 6a57 6120 | 12 6640 (0) 6632 (0) 6099 (0) 60ad (0)\n004 5 7e65 7f62 7f5f 7c76 | 6 7c76 (0) 7e65 (0) 7f62 (0) 7f5f (0)\n005 0 | 0\n============ DEPTH: 6 ==========================================\n006 1 740b | 1 740b (0)\n007 0 | 0\n008 1 7628 | 1 7628 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"ecbdca037cd7892752345b48b4219478b1b334f83ce7140fcc72eb71784436b690ce7a41b03e013cefc19d64a34a20cfef1b9e2b535d938bcdcb39fe63645a42","private_key":"043c2adc5bdb3449b2f770e1207eac21128e77e89c9e1fe8876cecf1792f8b24","name":"node_ecbdca037cd7892752345b48b4219478b1b334f83ce7140fcc72eb71784436b690ce7a41b03e013cefc19d64a34a20cfef1b9e2b535d938bcdcb39fe63645a42","services":["streamer"],"enable_msg_events":true,"port":63063},"up":true}},{"node":{"info":{"id":"51ba4faf0988717a37dcddc0a60a70ead33bde310184fc450f9ca73c67f931e6767ad5930bcf409e5aeb613a9ff7a03e47de6fc13b33d8af0b87b38822ae6888","name":"node_51ba4faf0988717a37dcddc0a60a70ead33bde310184fc450f9ca73c67f931e6767ad5930bcf409e5aeb613a9ff7a03e47de6fc13b33d8af0b87b38822ae6888","enode":"enode://51ba4faf0988717a37dcddc0a60a70ead33bde310184fc450f9ca73c67f931e6767ad5930bcf409e5aeb613a9ff7a03e47de6fc13b33d8af0b87b38822ae6888@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"86FDjPyLCaOpwfyEVerZBB6VMu8+mnf/7o5e9iryZww=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: f3a143\npopulation: 19 (126), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 7692 4087 | 59 3d3a (0) 3e4f (0) 3f1e (0) 30a0 (0)\n001 3 9cbc 8230 87e0 | 32 b1bf (0) b220 (0) b9e5 (0) bf7b (0)\n002 3 ca97 c243 d80b | 17 c7fd (0) c358 (0) c243 (0) cac9 (0)\n003 3 ea51 e0ac e5cd | 9 ec3b (0) ebf9 (0) ea94 (0) ea51 (0)\n004 5 feb3 f995 f836 fba8 | 6 feb3 (0) f995 (0) f80e (0) f836 (0)\n005 0 | 0\n006 1 f07c | 1 f07c (0)\n============ DEPTH: 7 ==========================================\n007 2 f2b8 f29f | 2 f2b8 (0) f29f (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"51ba4faf0988717a37dcddc0a60a70ead33bde310184fc450f9ca73c67f931e6767ad5930bcf409e5aeb613a9ff7a03e47de6fc13b33d8af0b87b38822ae6888","private_key":"88f2cc06ba260e7c09cdd93e48c55c000d7a988ef65ccfc5331d1eac3c66d7b1","name":"node_51ba4faf0988717a37dcddc0a60a70ead33bde310184fc450f9ca73c67f931e6767ad5930bcf409e5aeb613a9ff7a03e47de6fc13b33d8af0b87b38822ae6888","services":["streamer"],"enable_msg_events":true,"port":63064},"up":true}},{"node":{"info":{"id":"750ca601f07d65f426f6ea5f34e06238f9d7a931f022f9b0ebc811943d3725500cb3c6f00c8d05eb8d5b353c6534136dff38b9a8d3d4dc5bf49cd96875704d07","name":"node_750ca601f07d65f426f6ea5f34e06238f9d7a931f022f9b0ebc811943d3725500cb3c6f00c8d05eb8d5b353c6534136dff38b9a8d3d4dc5bf49cd96875704d07","enode":"enode://750ca601f07d65f426f6ea5f34e06238f9d7a931f022f9b0ebc811943d3725500cb3c6f00c8d05eb8d5b353c6534136dff38b9a8d3d4dc5bf49cd96875704d07@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"QIccvH7/iW8V5VjixjismA/YnHGIgc0RCghsM5e1ZMA=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 40871c\npopulation: 19 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 5 ca97 d80b ea51 e5cd | 68 b1bf (0) b220 (0) bf7b (0) b9e5 (0)\n001 2 3d3a 2dc2 | 23 2fee (0) 2dc2 (0) 2aef (0) 2a2b (0)\n002 1 7692 | 21 60ad (0) 6099 (0) 6120 (0) 6632 (0)\n003 2 5d6d 57df | 5 5b36 (0) 5d6d (0) 53ea (0) 500f (0)\n004 2 4ae6 4827 | 3 4ae6 (0) 48a1 (0) 4827 (0)\n005 2 4778 4454 | 2 4454 (0) 4778 (0)\n============ DEPTH: 6 ==========================================\n006 4 4259 4236 436c 4309 | 4 4259 (0) 4236 (0) 436c (0) 4309 (0)\n007 1 4124 | 1 4124 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"750ca601f07d65f426f6ea5f34e06238f9d7a931f022f9b0ebc811943d3725500cb3c6f00c8d05eb8d5b353c6534136dff38b9a8d3d4dc5bf49cd96875704d07","private_key":"8c64fc376a830b9237a1d1609a24e18396eb82cd6cd64b8ff572c9f946aaab2c","name":"node_750ca601f07d65f426f6ea5f34e06238f9d7a931f022f9b0ebc811943d3725500cb3c6f00c8d05eb8d5b353c6534136dff38b9a8d3d4dc5bf49cd96875704d07","services":["streamer"],"enable_msg_events":true,"port":63065},"up":true}},{"node":{"info":{"id":"41994605708232b4ca7448c3bc0760a7b86bf26d442091e5ce6e92eac94925721d7e0eca04bdd03bb1bba1ef92deeccd4bf1b7c6c3318b7e8d031965c6646761","name":"node_41994605708232b4ca7448c3bc0760a7b86bf26d442091e5ce6e92eac94925721d7e0eca04bdd03bb1bba1ef92deeccd4bf1b7c6c3318b7e8d031965c6646761","enode":"enode://41994605708232b4ca7448c3bc0760a7b86bf26d442091e5ce6e92eac94925721d7e0eca04bdd03bb1bba1ef92deeccd4bf1b7c6c3318b7e8d031965c6646761@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"V9/tZRun8Ktvnh1dLUrhj+5RogD1CSWojIYZgrtHacs=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 57dfed\npopulation: 16 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 ea51 d87f d80b | 68 b1bf (0) b220 (0) bf7b (0) b9e5 (0)\n001 2 3d3a 314e | 23 314e (0) 311f (0) 30a0 (0) 3d3a (0)\n002 1 7692 | 21 6640 (0) 6632 (0) 6099 (0) 60ad (0)\n003 6 4ae6 4778 4259 4236 | 11 48a1 (0) 4827 (0) 4ae6 (0) 4454 (0)\n004 2 5b36 5d6d | 2 5d6d (0) 5b36 (0)\n============ DEPTH: 5 ==========================================\n005 2 500f 53ea | 2 500f (0) 53ea (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"41994605708232b4ca7448c3bc0760a7b86bf26d442091e5ce6e92eac94925721d7e0eca04bdd03bb1bba1ef92deeccd4bf1b7c6c3318b7e8d031965c6646761","private_key":"545e42fc4dfd38b62f1481fe46895a3cb9c6632930c8df8358d66a3988e6fe72","name":"node_41994605708232b4ca7448c3bc0760a7b86bf26d442091e5ce6e92eac94925721d7e0eca04bdd03bb1bba1ef92deeccd4bf1b7c6c3318b7e8d031965c6646761","services":["streamer"],"enable_msg_events":true,"port":63066},"up":true}},{"node":{"info":{"id":"28afc20d8f4779b285bb14870062dbb54796ec77623302e51bc1bafed9e2c35751c8469ffc482718e059875dfa2226195ed10999e251498cba3a444896cb67db","name":"node_28afc20d8f4779b285bb14870062dbb54796ec77623302e51bc1bafed9e2c35751c8469ffc482718e059875dfa2226195ed10999e251498cba3a444896cb67db","enode":"enode://28afc20d8f4779b285bb14870062dbb54796ec77623302e51bc1bafed9e2c35751c8469ffc482718e059875dfa2226195ed10999e251498cba3a444896cb67db@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"2AtZsYe3dlQ5sOTJQPdmrnGpA/WZrEGoTZcuhwP3yf8=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: d80b59\npopulation: 17 (123), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 4087 57df | 56 2650 (0) 2a2b (0) 2aef (0) 2fee (0)\n001 5 aec5 a8ba a12e a3fc | 32 b220 (0) b1bf (0) bf7b (0) b9e5 (0)\n002 2 f2b8 f3a1 | 19 feb3 (0) fa62 (0) fba8 (0) f995 (0)\n003 2 c7fd ca97 | 5 c358 (0) c243 (0) c7fd (0) cac9 (0)\n004 2 d7f9 d68e | 7 d382 (0) d386 (0) d192 (0) d552 (0)\n005 1 dc2a | 1 dc2a (0)\n006 1 db59 | 1 db59 (0)\n============ DEPTH: 7 ==========================================\n007 1 d916 | 1 d916 (0)\n008 0 | 0\n009 1 d87f | 1 d87f (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"28afc20d8f4779b285bb14870062dbb54796ec77623302e51bc1bafed9e2c35751c8469ffc482718e059875dfa2226195ed10999e251498cba3a444896cb67db","private_key":"3e5b24d432307724a3e619c479ad5c87a93c6ee96d2b6ab0dad17da7e84eea55","name":"node_28afc20d8f4779b285bb14870062dbb54796ec77623302e51bc1bafed9e2c35751c8469ffc482718e059875dfa2226195ed10999e251498cba3a444896cb67db","services":["streamer"],"enable_msg_events":true,"port":63067},"up":true}},{"node":{"info":{"id":"805d784527be4e32e84ddf045baee1ccf348cdf8288de3aae1a5379f762576b957525ef358d9b42c68a93394017880adc09bb2b1b5e01102dc7e4240baf2af95","name":"node_805d784527be4e32e84ddf045baee1ccf348cdf8288de3aae1a5379f762576b957525ef358d9b42c68a93394017880adc09bb2b1b5e01102dc7e4240baf2af95","enode":"enode://805d784527be4e32e84ddf045baee1ccf348cdf8288de3aae1a5379f762576b957525ef358d9b42c68a93394017880adc09bb2b1b5e01102dc7e4240baf2af95@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"ypchtRSXxdVwc46tw3x5/I1VJXSd77mMJSNxeTwqb1w=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: ca9721\npopulation: 13 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 4087 | 60 237b (0) 2650 (0) 2a2b (0) 2aef (0)\n001 1 b9e5 | 32 b1bf (0) b220 (0) bf7b (0) b9e5 (0)\n002 4 f3a1 ea51 e3c3 e5cd | 19 feb3 (0) fba8 (0) fa62 (0) f836 (0)\n003 3 d798 d87f d80b | 12 d386 (0) d382 (0) d192 (0) d552 (0)\n============ DEPTH: 4 ==========================================\n004 3 c358 c243 c7fd | 3 c243 (0) c358 (0) c7fd (0)\n005 0 | 0\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 1 cac9 | 1 cac9 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"805d784527be4e32e84ddf045baee1ccf348cdf8288de3aae1a5379f762576b957525ef358d9b42c68a93394017880adc09bb2b1b5e01102dc7e4240baf2af95","private_key":"cab0eaf666548a84a7ceb4a34a29b7079c66b0df29e7fd315e851e02a8c9a5ed","name":"node_805d784527be4e32e84ddf045baee1ccf348cdf8288de3aae1a5379f762576b957525ef358d9b42c68a93394017880adc09bb2b1b5e01102dc7e4240baf2af95","services":["streamer"],"enable_msg_events":true,"port":63068},"up":true}},{"node":{"info":{"id":"9c6dcfef0e128dbfeca58b8ac625b08fb447b0d579bd3f18bc0e2be60d1ec2274595d0554ddba0ca7eb660099d3ea146d8076792b46c93841d2ecf8cf608f5ba","name":"node_9c6dcfef0e128dbfeca58b8ac625b08fb447b0d579bd3f18bc0e2be60d1ec2274595d0554ddba0ca7eb660099d3ea146d8076792b46c93841d2ecf8cf608f5ba","enode":"enode://9c6dcfef0e128dbfeca58b8ac625b08fb447b0d579bd3f18bc0e2be60d1ec2274595d0554ddba0ca7eb660099d3ea146d8076792b46c93841d2ecf8cf608f5ba@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"5c12nbzEKVh+OpKxkldZZcCsGOiMmlS591k22SnEPGI=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: e5cd76\npopulation: 19 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 4087 | 60 2dc2 (0) 2fee (0) 2a2b (0) 2aef (0)\n001 6 8230 9cbc a3fc a8ba | 32 b1bf (0) b220 (0) bf7b (0) b9e5 (0)\n002 1 ca97 | 17 d386 (0) d382 (0) d192 (0) d7f9 (0)\n003 5 fba8 fa62 f2b8 f29f | 10 feb3 (0) f995 (0) f80e (0) f836 (0)\n004 2 ec3b ea51 | 4 ec3b (0) ebf9 (0) ea94 (0) ea51 (0)\n============ DEPTH: 5 ==========================================\n005 3 e39e e3c3 e0ac | 3 e0ac (0) e39e (0) e3c3 (0)\n006 0 | 0\n007 1 e425 | 1 e425 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"9c6dcfef0e128dbfeca58b8ac625b08fb447b0d579bd3f18bc0e2be60d1ec2274595d0554ddba0ca7eb660099d3ea146d8076792b46c93841d2ecf8cf608f5ba","private_key":"8c48ba58bc5ac8c0f3f0295c73df1572e80465f15a97f1c5537735474b11da89","name":"node_9c6dcfef0e128dbfeca58b8ac625b08fb447b0d579bd3f18bc0e2be60d1ec2274595d0554ddba0ca7eb660099d3ea146d8076792b46c93841d2ecf8cf608f5ba","services":["streamer"],"enable_msg_events":true,"port":63069},"up":true}},{"node":{"info":{"id":"6ce3a68cb1e2924ad97f22006094c709a3dd8b4ca1546fbb037f841a9e5ac62def242015dbf6221bda610153db064edcbb58a78a35a06077b8c02bf5b2a33c04","name":"node_6ce3a68cb1e2924ad97f22006094c709a3dd8b4ca1546fbb037f841a9e5ac62def242015dbf6221bda610153db064edcbb58a78a35a06077b8c02bf5b2a33c04","enode":"enode://6ce3a68cb1e2924ad97f22006094c709a3dd8b4ca1546fbb037f841a9e5ac62def242015dbf6221bda610153db064edcbb58a78a35a06077b8c02bf5b2a33c04@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"6lFFnFrBQjkSl7tzqiZQHq5lvG9mG1NKkaNE3o26L08=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: ea5145\npopulation: 23 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 4087 57df | 60 237b (0) 2650 (0) 2dc2 (0) 2fee (0)\n001 4 954a 92e2 9386 811d | 32 b1bf (0) b220 (0) bf7b (0) b9e5 (0)\n002 4 d386 d798 d87f ca97 | 17 c243 (0) c358 (0) c7fd (0) cac9 (0)\n003 5 feb3 fba8 f80e f995 | 10 feb3 (0) fba8 (0) fa62 (0) f836 (0)\n004 5 e0ac e39e e3c3 e425 | 5 e0ac (0) e39e (0) e3c3 (0) e425 (0)\n005 1 ec3b | 1 ec3b (0)\n006 0 | 0\n============ DEPTH: 7 ==========================================\n007 1 ebf9 | 1 ebf9 (0)\n008 1 ea94 | 1 ea94 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"6ce3a68cb1e2924ad97f22006094c709a3dd8b4ca1546fbb037f841a9e5ac62def242015dbf6221bda610153db064edcbb58a78a35a06077b8c02bf5b2a33c04","private_key":"0939af4a1ac3398bd818e5ac35e1003530a80a0abba5bf4c586664ab0b15a391","name":"node_6ce3a68cb1e2924ad97f22006094c709a3dd8b4ca1546fbb037f841a9e5ac62def242015dbf6221bda610153db064edcbb58a78a35a06077b8c02bf5b2a33c04","services":["streamer"],"enable_msg_events":true,"port":63070},"up":true}},{"node":{"info":{"id":"178d5ce398a7114a63a0c953a59932e769891420f6b1544f08c082cd37b531b66757652d279b3036b03b04f8d46eceb0b46fb95646c6668e2921af75c06c3d97","name":"node_178d5ce398a7114a63a0c953a59932e769891420f6b1544f08c082cd37b531b66757652d279b3036b03b04f8d46eceb0b46fb95646c6668e2921af75c06c3d97","enode":"enode://178d5ce398a7114a63a0c953a59932e769891420f6b1544f08c082cd37b531b66757652d279b3036b03b04f8d46eceb0b46fb95646c6668e2921af75c06c3d97@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"gR115+5QaiDtQPhFEGb12fbWPFd0AEqia9MFQBN//TA=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 811d75\npopulation: 24 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 7 6aef 4259 436c 1ab1 | 60 237b (0) 2650 (0) 2dc2 (0) 2fee (0)\n001 5 d386 d192 d87f feb3 | 36 c7fd (0) c243 (0) c358 (0) cac9 (0)\n002 2 a12e a8ba | 12 b1bf (0) b220 (0) bf7b (0) b9e5 (0)\n003 4 954a 96b7 931a 9386 | 10 981b (0) 9f97 (0) 9cbc (0) 954a (0)\n004 2 8c5b 8e31 | 5 8bf5 (0) 8c5b (0) 8fe2 (0) 8ec6 (0)\n005 1 87e0 | 1 87e0 (0)\n============ DEPTH: 6 ==========================================\n006 3 83bc 8311 8230 | 3 8311 (0) 83bc (0) 8230 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"178d5ce398a7114a63a0c953a59932e769891420f6b1544f08c082cd37b531b66757652d279b3036b03b04f8d46eceb0b46fb95646c6668e2921af75c06c3d97","private_key":"bfdc13ed4844405928ae3f67e209353779af203143a9f43fd8d1fc899ddd56a7","name":"node_178d5ce398a7114a63a0c953a59932e769891420f6b1544f08c082cd37b531b66757652d279b3036b03b04f8d46eceb0b46fb95646c6668e2921af75c06c3d97","services":["streamer"],"enable_msg_events":true,"port":63071},"up":true}},{"node":{"info":{"id":"59730132a01ba848a3c050bb6234bca9a72deba33716960fc3ec89b186bfcd313b9bbf049939d5805ff98db2c53a9421ce6ec97d8b4cdbaea53ba264d80d0734","name":"node_59730132a01ba848a3c050bb6234bca9a72deba33716960fc3ec89b186bfcd313b9bbf049939d5805ff98db2c53a9421ce6ec97d8b4cdbaea53ba264d80d0734","enode":"enode://59730132a01ba848a3c050bb6234bca9a72deba33716960fc3ec89b186bfcd313b9bbf049939d5805ff98db2c53a9421ce6ec97d8b4cdbaea53ba264d80d0734@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"2H+YOu/Y9zLClxipX038VKEGQNXJ/dc7dyw8MN8mnYg=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: d87f98\npopulation: 21 (126), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 57df 1ab1 | 59 237b (0) 2650 (0) 2dc2 (0) 2fee (0)\n001 7 954a 9386 811d a8ba | 32 981b (0) 9cbc (0) 9f97 (0) 97a5 (0)\n002 4 ec3b ea51 feb3 f995 | 19 f07c (0) f29f (0) f2b8 (0) f3a1 (0)\n003 2 c243 ca97 | 5 c243 (0) c358 (0) c7fd (0) cac9 (0)\n004 2 d192 d798 | 7 d382 (0) d386 (0) d192 (0) d552 (0)\n005 1 dc2a | 1 dc2a (0)\n006 1 db59 | 1 db59 (0)\n============ DEPTH: 7 ==========================================\n007 1 d916 | 1 d916 (0)\n008 0 | 0\n009 1 d80b | 1 d80b (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"59730132a01ba848a3c050bb6234bca9a72deba33716960fc3ec89b186bfcd313b9bbf049939d5805ff98db2c53a9421ce6ec97d8b4cdbaea53ba264d80d0734","private_key":"d52f5bca67f434e20d72348971b791cb18def6182b002a3342c721ed06e9ad84","name":"node_59730132a01ba848a3c050bb6234bca9a72deba33716960fc3ec89b186bfcd313b9bbf049939d5805ff98db2c53a9421ce6ec97d8b4cdbaea53ba264d80d0734","services":["streamer"],"enable_msg_events":true,"port":63072},"up":true}},{"node":{"info":{"id":"93987e431a0058f2e942ccf8d3486d249cd2734d6494131b343e2c3a8fdd86cfcb12d0aaaf8fcb911ad3cdd682cc82118198195a7fdc915ab7853223f012eab6","name":"node_93987e431a0058f2e942ccf8d3486d249cd2734d6494131b343e2c3a8fdd86cfcb12d0aaaf8fcb911ad3cdd682cc82118198195a7fdc915ab7853223f012eab6","enode":"enode://93987e431a0058f2e942ccf8d3486d249cd2734d6494131b343e2c3a8fdd86cfcb12d0aaaf8fcb911ad3cdd682cc82118198195a7fdc915ab7853223f012eab6@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"oS5z7pz3NpglwUI2CM4HnPcN910PC7xW0H1IQWn8om0=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: a12e73\npopulation: 19 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 4259 6aef 2a2b 3d3a | 60 7bcf (0) 78bf (0) 7c76 (0) 7e65 (0)\n001 3 feb3 d80b d87f | 36 ec3b (0) ebf9 (0) ea94 (0) ea51 (0)\n002 5 96b7 954a 8c5b 8e31 | 20 8bf5 (0) 8c5b (0) 8fe2 (0) 8ec6 (0)\n003 1 b9e5 | 4 b1bf (0) b220 (0) bf7b (0) b9e5 (0)\n004 3 a8ba aec5 ac23 | 4 aa19 (0) a8ba (0) aec5 (0) ac23 (0)\n005 1 a60b | 1 a60b (0)\n============ DEPTH: 6 ==========================================\n006 2 a250 a3fc | 2 a250 (0) a3fc (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"93987e431a0058f2e942ccf8d3486d249cd2734d6494131b343e2c3a8fdd86cfcb12d0aaaf8fcb911ad3cdd682cc82118198195a7fdc915ab7853223f012eab6","private_key":"7d5751c36a856dbc2403a058a432e1f2bd142ae438444db9febdaa22480dd404","name":"node_93987e431a0058f2e942ccf8d3486d249cd2734d6494131b343e2c3a8fdd86cfcb12d0aaaf8fcb911ad3cdd682cc82118198195a7fdc915ab7853223f012eab6","services":["streamer"],"enable_msg_events":true,"port":63073},"up":true}},{"node":{"info":{"id":"665c3288c14dc1c17d85d17d634910f42183482c7e77c47e68f9b4f475b93e8c152246b9e34781606315ff6ef0f8360342500d15e4a2d67d9df6b72f30af64a7","name":"node_665c3288c14dc1c17d85d17d634910f42183482c7e77c47e68f9b4f475b93e8c152246b9e34781606315ff6ef0f8360342500d15e4a2d67d9df6b72f30af64a7","enode":"enode://665c3288c14dc1c17d85d17d634910f42183482c7e77c47e68f9b4f475b93e8c152246b9e34781606315ff6ef0f8360342500d15e4a2d67d9df6b72f30af64a7@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"PTrO42V9mBaOL05kY5R2RlYLWtHKJLSoqX5ChMObAuE=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 3d3ace\npopulation: 16 (119), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 d192 a12e | 60 ec3b (0) ebf9 (0) ea51 (0) e5cd (0)\n001 8 6120 6e83 7692 4124 | 37 7c76 (0) 7e65 (0) 7f5f (0) 7f62 (0)\n002 2 1943 1ab1 | 11 0047 (0) 059a (0) 0400 (0) 06db (0)\n003 1 2a2b | 6 2650 (0) 237b (0) 2dc2 (0) 2fee (0)\n004 1 30a0 | 3 314e (0) 311f (0) 30a0 (0)\n005 0 | 0\n============ DEPTH: 6 ==========================================\n006 2 3f1e 3e4f | 2 3f1e (0) 3e4f (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"665c3288c14dc1c17d85d17d634910f42183482c7e77c47e68f9b4f475b93e8c152246b9e34781606315ff6ef0f8360342500d15e4a2d67d9df6b72f30af64a7","private_key":"5cb8cc7f27d0f0e28e9ca55b592a38839058155cfce8528b5a464f98025eb54d","name":"node_665c3288c14dc1c17d85d17d634910f42183482c7e77c47e68f9b4f475b93e8c152246b9e34781606315ff6ef0f8360342500d15e4a2d67d9df6b72f30af64a7","services":["streamer"],"enable_msg_events":true,"port":63074},"up":true}},{"node":{"info":{"id":"562119edffe8270f6f7a5ad9b13d4c65d643e52a2331d1fee16f7e9b5567f44cfea62df3e8965a22cf08db8fa918f0a0bcae8da2936677e6d25bc88ed85ed2f1","name":"node_562119edffe8270f6f7a5ad9b13d4c65d643e52a2331d1fee16f7e9b5567f44cfea62df3e8965a22cf08db8fa918f0a0bcae8da2936677e6d25bc88ed85ed2f1","enode":"enode://562119edffe8270f6f7a5ad9b13d4c65d643e52a2331d1fee16f7e9b5567f44cfea62df3e8965a22cf08db8fa918f0a0bcae8da2936677e6d25bc88ed85ed2f1@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"0ZLGTgmHm1EHUH4ZP+ojsCRKV04NZuRE96Ml3jLBI/0=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: d192c6\npopulation: 13 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 1ab1 3d3a | 60 7c76 (0) 7e65 (0) 7f62 (0) 7f5f (0)\n001 2 9386 811d | 32 8bf5 (0) 8fe2 (0) 8ec6 (0) 8e31 (0)\n002 3 feb3 f995 f836 | 19 ec3b (0) ebf9 (0) ea94 (0) ea51 (0)\n003 1 c243 | 5 c243 (0) c358 (0) c7fd (0) cac9 (0)\n004 2 d916 d87f | 5 dc2a (0) db59 (0) d916 (0) d80b (0)\n005 1 d798 | 4 d552 (0) d68e (0) d7f9 (0) d798 (0)\n============ DEPTH: 6 ==========================================\n006 2 d386 d382 | 2 d386 (0) d382 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"562119edffe8270f6f7a5ad9b13d4c65d643e52a2331d1fee16f7e9b5567f44cfea62df3e8965a22cf08db8fa918f0a0bcae8da2936677e6d25bc88ed85ed2f1","private_key":"3901f39cd02354a635723259be3a5e7c28de3f7406c889fc9353d3adb22b9d82","name":"node_562119edffe8270f6f7a5ad9b13d4c65d643e52a2331d1fee16f7e9b5567f44cfea62df3e8965a22cf08db8fa918f0a0bcae8da2936677e6d25bc88ed85ed2f1","services":["streamer"],"enable_msg_events":true,"port":63075},"up":true}},{"node":{"info":{"id":"2502fc8ee0ccda79ad1dbd9c7cec625da85980b9116bdd56dc367d508039e25e5f65183293006e5b0df72fa9037a48bd2b133a757940d3587ff77ae2392e3eaf","name":"node_2502fc8ee0ccda79ad1dbd9c7cec625da85980b9116bdd56dc367d508039e25e5f65183293006e5b0df72fa9037a48bd2b133a757940d3587ff77ae2392e3eaf","enode":"enode://2502fc8ee0ccda79ad1dbd9c7cec625da85980b9116bdd56dc367d508039e25e5f65183293006e5b0df72fa9037a48bd2b133a757940d3587ff77ae2392e3eaf@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"+DazyoL3W8CQHYOywC4kF0vueMXqubVa+cSSQGlCY3o=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: f836b3\npopulation: 13 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 1ab1 1943 | 60 78bf (0) 7bcf (0) 7c76 (0) 7e65 (0)\n001 3 954a 9386 a3fc | 32 b1bf (0) b220 (0) bf7b (0) b9e5 (0)\n002 1 d192 | 17 c243 (0) c358 (0) c7fd (0) cac9 (0)\n003 1 ec3b | 9 ec3b (0) ebf9 (0) ea94 (0) ea51 (0)\n004 1 f3a1 | 4 f07c (0) f2b8 (0) f29f (0) f3a1 (0)\n005 1 feb3 | 1 feb3 (0)\n006 2 fba8 fa62 | 2 fba8 (0) fa62 (0)\n============ DEPTH: 7 ==========================================\n007 1 f995 | 1 f995 (0)\n008 0 | 0\n009 0 | 0\n010 1 f80e | 1 f80e (0)\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"2502fc8ee0ccda79ad1dbd9c7cec625da85980b9116bdd56dc367d508039e25e5f65183293006e5b0df72fa9037a48bd2b133a757940d3587ff77ae2392e3eaf","private_key":"4e740dfca715720a19f56d32d6b9783810e1d6da09425e01dfbe3b55714416c0","name":"node_2502fc8ee0ccda79ad1dbd9c7cec625da85980b9116bdd56dc367d508039e25e5f65183293006e5b0df72fa9037a48bd2b133a757940d3587ff77ae2392e3eaf","services":["streamer"],"enable_msg_events":true,"port":63076},"up":true}},{"node":{"info":{"id":"e9f7e58fda4b504275441d51929fbc98214abdc9ed552c7aa94c600a85d4e791d60c032304b29ae028adccec94984fc9a3d705a81462632f50ef45024eb0f64e","name":"node_e9f7e58fda4b504275441d51929fbc98214abdc9ed552c7aa94c600a85d4e791d60c032304b29ae028adccec94984fc9a3d705a81462632f50ef45024eb0f64e","enode":"enode://e9f7e58fda4b504275441d51929fbc98214abdc9ed552c7aa94c600a85d4e791d60c032304b29ae028adccec94984fc9a3d705a81462632f50ef45024eb0f64e@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"GUPBRC2imHLnfkz9KC6agUkMYT6Zy+RQPkcLfyPOdfs=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 1943c1\npopulation: 21 (114), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 e3c3 f836 954a | 57 ec3b (0) ebf9 (0) ea94 (0) ea51 (0)\n001 7 7c76 7692 6e83 5d6d | 35 6640 (0) 6632 (0) 6099 (0) 60ad (0)\n002 4 30a0 3d3a 237b 2a2b | 12 3f1e (0) 3e4f (0) 3d3a (0) 314e (0)\n003 1 0400 | 4 0047 (0) 06db (0) 059a (0) 0400 (0)\n004 2 1385 11a6 | 2 1385 (0) 11a6 (0)\n005 2 1f2a 1ea8 | 2 1f2a (0) 1ea8 (0)\n============ DEPTH: 6 ==========================================\n006 1 1ab1 | 1 1ab1 (0)\n007 1 18f6 | 1 18f6 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"e9f7e58fda4b504275441d51929fbc98214abdc9ed552c7aa94c600a85d4e791d60c032304b29ae028adccec94984fc9a3d705a81462632f50ef45024eb0f64e","private_key":"765219c4fea7ac80a0c5d26a096829226933310ad22d889ee19eb23915363fda","name":"node_e9f7e58fda4b504275441d51929fbc98214abdc9ed552c7aa94c600a85d4e791d60c032304b29ae028adccec94984fc9a3d705a81462632f50ef45024eb0f64e","services":["streamer"],"enable_msg_events":true,"port":63077},"up":true}},{"node":{"info":{"id":"9e6c1c6e871638182c4b54ac89352ef5c2bca0a99424a1369013e7c182883da0e8d7ab96b3c8254c31fa315b941d8ddee153157626821fc78c2cae951c1c9053","name":"node_9e6c1c6e871638182c4b54ac89352ef5c2bca0a99424a1369013e7c182883da0e8d7ab96b3c8254c31fa315b941d8ddee153157626821fc78c2cae951c1c9053","enode":"enode://9e6c1c6e871638182c4b54ac89352ef5c2bca0a99424a1369013e7c182883da0e8d7ab96b3c8254c31fa315b941d8ddee153157626821fc78c2cae951c1c9053@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"lUoixv19Y/zkfYaF0yu4krzA/qtCCdXcfDYB78KOfW0=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 954a22\npopulation: 18 (118), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 1943 5d6d | 55 3e4f (0) 3f1e (0) 3d3a (0) 314e (0)\n001 6 d87f f836 feb3 e3c3 | 34 ec3b (0) ebf9 (0) ea94 (0) ea51 (0)\n002 1 a12e | 10 b220 (0) b9e5 (0) a60b (0) a250 (0)\n003 2 811d 8e31 | 10 87e0 (0) 8230 (0) 83bc (0) 8311 (0)\n004 1 9f97 | 3 981b (0) 9cbc (0) 9f97 (0)\n005 3 92e2 931a 9386 | 3 92e2 (0) 931a (0) 9386 (0)\n============ DEPTH: 6 ==========================================\n006 3 97a5 96e9 96b7 | 3 97a5 (0) 96e9 (0) 96b7 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"9e6c1c6e871638182c4b54ac89352ef5c2bca0a99424a1369013e7c182883da0e8d7ab96b3c8254c31fa315b941d8ddee153157626821fc78c2cae951c1c9053","private_key":"edf1f1608ee4b7c320472a071f2d60d53c7b74e58fba190b5353e92056f30751","name":"node_9e6c1c6e871638182c4b54ac89352ef5c2bca0a99424a1369013e7c182883da0e8d7ab96b3c8254c31fa315b941d8ddee153157626821fc78c2cae951c1c9053","services":["streamer"],"enable_msg_events":true,"port":63078},"up":true}},{"node":{"info":{"id":"bfef26733f5196a11484bcc28d88776e747189ae7cec883ff39a27cfeee6d9d1efb34560c9f8e75eec43fc069a2ce5f0c78107a36cc8a569d37bd5306aecf23a","name":"node_bfef26733f5196a11484bcc28d88776e747189ae7cec883ff39a27cfeee6d9d1efb34560c9f8e75eec43fc069a2ce5f0c78107a36cc8a569d37bd5306aecf23a","enode":"enode://bfef26733f5196a11484bcc28d88776e747189ae7cec883ff39a27cfeee6d9d1efb34560c9f8e75eec43fc069a2ce5f0c78107a36cc8a569d37bd5306aecf23a@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"XW2jJgUE+AY68klgrJAb3AxUoSa4LUFWVqCDxJbItrg=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 5d6da3\npopulation: 14 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 8e31 954a | 68 ebf9 (0) ea94 (0) ea51 (0) ec3b (0)\n001 2 1943 3d3a | 23 3f1e (0) 3e4f (0) 3d3a (0) 314e (0)\n002 1 7c76 | 21 6640 (0) 6632 (0) 6099 (0) 60ad (0)\n003 5 4087 4124 4259 436c | 11 4ae6 (0) 48a1 (0) 4827 (0) 4454 (0)\n============ DEPTH: 4 ==========================================\n004 3 500f 53ea 57df | 3 500f (0) 53ea (0) 57df (0)\n005 1 5b36 | 1 5b36 (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"bfef26733f5196a11484bcc28d88776e747189ae7cec883ff39a27cfeee6d9d1efb34560c9f8e75eec43fc069a2ce5f0c78107a36cc8a569d37bd5306aecf23a","private_key":"16e405179555f907062a85c408713f0fa46a5f1f6714c99272bb705ae226b2a5","name":"node_bfef26733f5196a11484bcc28d88776e747189ae7cec883ff39a27cfeee6d9d1efb34560c9f8e75eec43fc069a2ce5f0c78107a36cc8a569d37bd5306aecf23a","services":["streamer"],"enable_msg_events":true,"port":63079},"up":true}},{"node":{"info":{"id":"f6a07a1d361a4671e997d5eaadae61736291aff3896cb69f06bbc19bf7536dd152e0b15422b2fd9f8a9d2f9a251c9a07d0140319900e2cc9f25a59025c7dc91f","name":"node_f6a07a1d361a4671e997d5eaadae61736291aff3896cb69f06bbc19bf7536dd152e0b15422b2fd9f8a9d2f9a251c9a07d0140319900e2cc9f25a59025c7dc91f","enode":"enode://f6a07a1d361a4671e997d5eaadae61736291aff3896cb69f06bbc19bf7536dd152e0b15422b2fd9f8a9d2f9a251c9a07d0140319900e2cc9f25a59025c7dc91f@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"jjFxUil9XQSMpFEvcz5j5Iw9xmkQutVB0z88/HaCjLk=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 8e3171\npopulation: 15 (125), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 4259 5d6d | 59 3f1e (0) 3e4f (0) 3d3a (0) 314e (0)\n001 3 f80e d386 d798 | 36 ebf9 (0) ea94 (0) ea51 (0) ec3b (0)\n002 3 ac23 a8ba a12e | 11 b220 (0) bf7b (0) b9e5 (0) a60b (0)\n003 2 9386 954a | 10 981b (0) 9cbc (0) 9f97 (0) 92e2 (0)\n004 1 811d | 5 87e0 (0) 8230 (0) 83bc (0) 8311 (0)\n005 1 8bf5 | 1 8bf5 (0)\n006 1 8c5b | 1 8c5b (0)\n============ DEPTH: 7 ==========================================\n007 1 8fe2 | 1 8fe2 (0)\n008 1 8ec6 | 1 8ec6 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"f6a07a1d361a4671e997d5eaadae61736291aff3896cb69f06bbc19bf7536dd152e0b15422b2fd9f8a9d2f9a251c9a07d0140319900e2cc9f25a59025c7dc91f","private_key":"8337241aad3fa93ccc78bab1ff15a2aa218fbd7d026bffe74b7dadd8e6aa787f","name":"node_f6a07a1d361a4671e997d5eaadae61736291aff3896cb69f06bbc19bf7536dd152e0b15422b2fd9f8a9d2f9a251c9a07d0140319900e2cc9f25a59025c7dc91f","services":["streamer"],"enable_msg_events":true,"port":63080},"up":true}},{"node":{"info":{"id":"08900197e74e285a5a8a9cc53fbd420bb35043ab27eb2d9eab22615e736a093abfa235c17f667dcc791cb50b9022082eafd9fba030194cc84f0358b769adc85b","name":"node_08900197e74e285a5a8a9cc53fbd420bb35043ab27eb2d9eab22615e736a093abfa235c17f667dcc791cb50b9022082eafd9fba030194cc84f0358b769adc85b","enode":"enode://08900197e74e285a5a8a9cc53fbd420bb35043ab27eb2d9eab22615e736a093abfa235c17f667dcc791cb50b9022082eafd9fba030194cc84f0358b769adc85b@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"15g4xBm+eTKSok/q8bnSbGfwxa/hW66FaJQg3jQ2rZU=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: d79838\npopulation: 16 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 7c76 | 60 0047 (0) 06db (0) 0400 (0) 059a (0)\n001 1 8e31 | 32 b1bf (0) b220 (0) bf7b (0) b9e5 (0)\n002 2 ec3b ea51 | 19 ebf9 (0) ea94 (0) ea51 (0) ec3b (0)\n003 5 ca97 cac9 c7fd c358 | 5 c243 (0) c358 (0) c7fd (0) cac9 (0)\n004 2 dc2a d87f | 5 dc2a (0) db59 (0) d916 (0) d80b (0)\n005 2 d386 d192 | 3 d386 (0) d382 (0) d192 (0)\n006 1 d552 | 1 d552 (0)\n============ DEPTH: 7 ==========================================\n007 1 d68e | 1 d68e (0)\n008 0 | 0\n009 1 d7f9 | 1 d7f9 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"08900197e74e285a5a8a9cc53fbd420bb35043ab27eb2d9eab22615e736a093abfa235c17f667dcc791cb50b9022082eafd9fba030194cc84f0358b769adc85b","private_key":"af0eb33b99b22cff74cc8137b4bb9477f8f47c895a61807279436daefaf9cac8","name":"node_08900197e74e285a5a8a9cc53fbd420bb35043ab27eb2d9eab22615e736a093abfa235c17f667dcc791cb50b9022082eafd9fba030194cc84f0358b769adc85b","services":["streamer"],"enable_msg_events":true,"port":63081},"up":true}},{"node":{"info":{"id":"afb5754b4748b7ac5628e32b242c90aab0e2fc7da58d8d5c8c775d13d8a6fd32240f1b89021587858168cbe7b3ea7ad07807728655eae0a9907060494a7c99ca","name":"node_afb5754b4748b7ac5628e32b242c90aab0e2fc7da58d8d5c8c775d13d8a6fd32240f1b89021587858168cbe7b3ea7ad07807728655eae0a9907060494a7c99ca","enode":"enode://afb5754b4748b7ac5628e32b242c90aab0e2fc7da58d8d5c8c775d13d8a6fd32240f1b89021587858168cbe7b3ea7ad07807728655eae0a9907060494a7c99ca@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"fHZrVyc3d8xn90hwVgRJyVQs/sc0tYsWeu+Z4Jrq6WI=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 7c766b\npopulation: 15 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 d798 | 68 b1bf (0) b220 (0) bf7b (0) b9e5 (0)\n001 3 1943 311f 2a2b | 23 0047 (0) 06db (0) 0400 (0) 059a (0)\n002 2 4827 5d6d | 16 5b36 (0) 5d6d (0) 57df (0) 500f (0)\n003 3 6120 6cf1 6e83 | 12 6640 (0) 6632 (0) 6099 (0) 60ad (0)\n004 1 7692 | 3 740b (0) 7628 (0) 7692 (0)\n005 2 78bf 7bcf | 2 7bcf (0) 78bf (0)\n============ DEPTH: 6 ==========================================\n006 3 7e65 7f62 7f5f | 3 7e65 (0) 7f62 (0) 7f5f (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"afb5754b4748b7ac5628e32b242c90aab0e2fc7da58d8d5c8c775d13d8a6fd32240f1b89021587858168cbe7b3ea7ad07807728655eae0a9907060494a7c99ca","private_key":"3c9a377e5ae9212adee118e04b3cd9cead5b4830ee51492dffbec8f015b5b757","name":"node_afb5754b4748b7ac5628e32b242c90aab0e2fc7da58d8d5c8c775d13d8a6fd32240f1b89021587858168cbe7b3ea7ad07807728655eae0a9907060494a7c99ca","services":["streamer"],"enable_msg_events":true,"port":63082},"up":true}},{"node":{"info":{"id":"8f625a4e4f4fd980c796d3aa535e58a39722492480cf6982d43fab02de63a5b4c1b5c7cd8402171dd792bb5d9c3e2bdd38176c061dbe3e5b0592af1339e3fd82","name":"node_8f625a4e4f4fd980c796d3aa535e58a39722492480cf6982d43fab02de63a5b4c1b5c7cd8402171dd792bb5d9c3e2bdd38176c061dbe3e5b0592af1339e3fd82","enode":"enode://8f625a4e4f4fd980c796d3aa535e58a39722492480cf6982d43fab02de63a5b4c1b5c7cd8402171dd792bb5d9c3e2bdd38176c061dbe3e5b0592af1339e3fd82@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"KivLQEBKQnpQU4rZ0b//HFsadnOZDL0g2DB4f9lqAOU=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 2a2bcb\npopulation: 21 (112), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 6 a8ba a12e a3fc b9e5 | 56 8bf5 (0) 8c5b (0) 8fe2 (0) 8ec6 (0)\n001 4 436c 4124 6120 7c76 | 34 5d6d (0) 53ea (0) 500f (0) 57df (0)\n002 2 1943 1ab1 | 11 0047 (0) 06db (0) 0400 (0) 059a (0)\n003 4 3e4f 3d3a 311f 30a0 | 6 3f1e (0) 3e4f (0) 3d3a (0) 314e (0)\n004 2 2650 237b | 2 2650 (0) 237b (0)\n============ DEPTH: 5 ==========================================\n005 2 2dc2 2fee | 2 2dc2 (0) 2fee (0)\n006 0 | 0\n007 0 | 0\n008 1 2aef | 1 2aef (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"8f625a4e4f4fd980c796d3aa535e58a39722492480cf6982d43fab02de63a5b4c1b5c7cd8402171dd792bb5d9c3e2bdd38176c061dbe3e5b0592af1339e3fd82","private_key":"5ccc64d0c951c9f50f0f7053504f54f965e22a22fb06b0bd14f206d72d822fa6","name":"node_8f625a4e4f4fd980c796d3aa535e58a39722492480cf6982d43fab02de63a5b4c1b5c7cd8402171dd792bb5d9c3e2bdd38176c061dbe3e5b0592af1339e3fd82","services":["streamer"],"enable_msg_events":true,"port":63083},"up":true}},{"node":{"info":{"id":"ab3814579882e9fd8d464f4f3c8a421be37822ba7f42c5f5e787e81125ec032f9ccf90a138c0b57f0a813b55b583f80d66284f795e2c82d80d2869e1fc770be5","name":"node_ab3814579882e9fd8d464f4f3c8a421be37822ba7f42c5f5e787e81125ec032f9ccf90a138c0b57f0a813b55b583f80d66284f795e2c82d80d2869e1fc770be5","enode":"enode://ab3814579882e9fd8d464f4f3c8a421be37822ba7f42c5f5e787e81125ec032f9ccf90a138c0b57f0a813b55b583f80d66284f795e2c82d80d2869e1fc770be5@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"MKDvS/H2arTQKgJ6JLofmyiOqT6Gpc6rZOGYWqTvy9A=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 30a0ef\npopulation: 12 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 811d | 68 8bf5 (0) 8c5b (0) 8fe2 (0) 8ec6 (0)\n001 2 436c 6120 | 37 5b36 (0) 5d6d (0) 53ea (0) 500f (0)\n002 2 1943 1ab1 | 11 0047 (0) 06db (0) 0400 (0) 059a (0)\n003 2 237b 2a2b | 6 237b (0) 2650 (0) 2dc2 (0) 2fee (0)\n004 3 3f1e 3e4f 3d3a | 3 3f1e (0) 3e4f (0) 3d3a (0)\n005 0 | 0\n006 0 | 0\n============ DEPTH: 7 ==========================================\n007 2 314e 311f | 2 314e (0) 311f (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"ab3814579882e9fd8d464f4f3c8a421be37822ba7f42c5f5e787e81125ec032f9ccf90a138c0b57f0a813b55b583f80d66284f795e2c82d80d2869e1fc770be5","private_key":"f44a9e23990fd65de4da61711cb5a720a4474421ea0a653c7ce5ed76149b335d","name":"node_ab3814579882e9fd8d464f4f3c8a421be37822ba7f42c5f5e787e81125ec032f9ccf90a138c0b57f0a813b55b583f80d66284f795e2c82d80d2869e1fc770be5","services":["streamer"],"enable_msg_events":true,"port":63084},"up":true}},{"node":{"info":{"id":"670949178a5fad22da03af1e206c814a797c0e9eb4e3371f83612f121e5b56e767706a3ae36628cd0c86dd7bd1586ca4df57e2de27b28a31284ecf9176d330e5","name":"node_670949178a5fad22da03af1e206c814a797c0e9eb4e3371f83612f121e5b56e767706a3ae36628cd0c86dd7bd1586ca4df57e2de27b28a31284ecf9176d330e5","enode":"enode://670949178a5fad22da03af1e206c814a797c0e9eb4e3371f83612f121e5b56e767706a3ae36628cd0c86dd7bd1586ca4df57e2de27b28a31284ecf9176d330e5@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"YSB/T8E8iZuI6bcn6yAqi6sAhovQfZRRALLlbbzWdoM=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 61207f\npopulation: 18 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 f995 | 68 8bf5 (0) 8c5b (0) 8fe2 (0) 8ec6 (0)\n001 3 2a2b 3d3a 30a0 | 23 0047 (0) 06db (0) 0400 (0) 059a (0)\n002 3 4124 436c 4309 | 16 5b36 (0) 5d6d (0) 53ea (0) 500f (0)\n003 2 7692 7c76 | 9 7bcf (0) 78bf (0) 7e65 (0) 7f62 (0)\n004 5 6a57 6ac7 6c1f 6cf1 | 7 6838 (0) 6a57 (0) 6aef (0) 6ac7 (0)\n005 2 6632 6640 | 2 6632 (0) 6640 (0)\n006 0 | 0\n============ DEPTH: 7 ==========================================\n007 2 6099 60ad | 2 6099 (0) 60ad (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"670949178a5fad22da03af1e206c814a797c0e9eb4e3371f83612f121e5b56e767706a3ae36628cd0c86dd7bd1586ca4df57e2de27b28a31284ecf9176d330e5","private_key":"4fd7ee5ba8003bb9b914612e6283cf5738550412c71e4475e07eb8bef32e96a4","name":"node_670949178a5fad22da03af1e206c814a797c0e9eb4e3371f83612f121e5b56e767706a3ae36628cd0c86dd7bd1586ca4df57e2de27b28a31284ecf9176d330e5","services":["streamer"],"enable_msg_events":true,"port":63085},"up":true}},{"node":{"info":{"id":"fd12c5c96df6ee76dd7beb9e4e4768dda4d2c498851b6435f13ca0175980d0e4a4ff1c002e4daf41a995f118500604764f88496fb9b2c22e28308d8649b525ce","name":"node_fd12c5c96df6ee76dd7beb9e4e4768dda4d2c498851b6435f13ca0175980d0e4a4ff1c002e4daf41a995f118500604764f88496fb9b2c22e28308d8649b525ce","enode":"enode://fd12c5c96df6ee76dd7beb9e4e4768dda4d2c498851b6435f13ca0175980d0e4a4ff1c002e4daf41a995f118500604764f88496fb9b2c22e28308d8649b525ce@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"+ZUD3GpKzjMXMg2EVLOsGll39QiugQxNUGAB7QEmg4s=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: f99503\npopulation: 12 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 6120 | 60 06db (0) 059a (0) 0400 (0) 0047 (0)\n001 1 ac23 | 32 8bf5 (0) 8c5b (0) 8fe2 (0) 8ec6 (0)\n002 3 d192 db59 d87f | 17 c243 (0) c358 (0) c7fd (0) cac9 (0)\n003 1 ea51 | 9 ebf9 (0) ea94 (0) ea51 (0) ec3b (0)\n004 1 f3a1 | 4 f07c (0) f2b8 (0) f29f (0) f3a1 (0)\n005 1 feb3 | 1 feb3 (0)\n006 2 fba8 fa62 | 2 fba8 (0) fa62 (0)\n============ DEPTH: 7 ==========================================\n007 2 f80e f836 | 2 f80e (0) f836 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"fd12c5c96df6ee76dd7beb9e4e4768dda4d2c498851b6435f13ca0175980d0e4a4ff1c002e4daf41a995f118500604764f88496fb9b2c22e28308d8649b525ce","private_key":"d0df7b482eb60b2f1ed4c2562768f60fe5ee8997e542bc9c7310db55391553d4","name":"node_fd12c5c96df6ee76dd7beb9e4e4768dda4d2c498851b6435f13ca0175980d0e4a4ff1c002e4daf41a995f118500604764f88496fb9b2c22e28308d8649b525ce","services":["streamer"],"enable_msg_events":true,"port":63086},"up":true}},{"node":{"info":{"id":"ed1ab28230ed533abf25633508d54f32bbff78a10c7a15fad5c2320cda9d9669c6d0e15689d8885400e64cbcd81730456f8f4bd5c98681d2cd8a8d4e1daec553","name":"node_ed1ab28230ed533abf25633508d54f32bbff78a10c7a15fad5c2320cda9d9669c6d0e15689d8885400e64cbcd81730456f8f4bd5c98681d2cd8a8d4e1daec553","enode":"enode://ed1ab28230ed533abf25633508d54f32bbff78a10c7a15fad5c2320cda9d9669c6d0e15689d8885400e64cbcd81730456f8f4bd5c98681d2cd8a8d4e1daec553@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"rCMZDunuMN15O/Pt7zVUUFItP1aXOraxrLtt/Z1kE3o=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: ac2319\npopulation: 20 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 1ab1 6e83 7692 | 60 7bcf (0) 78bf (0) 7e65 (0) 7f62 (0)\n001 5 d87f cac9 f995 e5cd | 36 c358 (0) c243 (0) c7fd (0) cac9 (0)\n002 4 8e31 8c5b 92e2 96b7 | 20 8bf5 (0) 8c5b (0) 8fe2 (0) 8ec6 (0)\n003 1 b9e5 | 4 b1bf (0) b220 (0) bf7b (0) b9e5 (0)\n004 4 a60b a250 a3fc a12e | 4 a60b (0) a250 (0) a3fc (0) a12e (0)\n============ DEPTH: 5 ==========================================\n005 2 aa19 a8ba | 2 aa19 (0) a8ba (0)\n006 1 aec5 | 1 aec5 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"ed1ab28230ed533abf25633508d54f32bbff78a10c7a15fad5c2320cda9d9669c6d0e15689d8885400e64cbcd81730456f8f4bd5c98681d2cd8a8d4e1daec553","private_key":"7771ce12670dba4c28198f6df284ad58c9ca877a25ceb912ec3af5ac83f6e143","name":"node_ed1ab28230ed533abf25633508d54f32bbff78a10c7a15fad5c2320cda9d9669c6d0e15689d8885400e64cbcd81730456f8f4bd5c98681d2cd8a8d4e1daec553","services":["streamer"],"enable_msg_events":true,"port":63087},"up":true}},{"node":{"info":{"id":"a05a18161c2d01a0f122548c66509dd1fcf3ee52975035bc79fb059e9613b743a16cd6f5ac54090e68f51bcf76ff21fb3805ba3197a96b4236afb80f791df802","name":"node_a05a18161c2d01a0f122548c66509dd1fcf3ee52975035bc79fb059e9613b743a16cd6f5ac54090e68f51bcf76ff21fb3805ba3197a96b4236afb80f791df802","enode":"enode://a05a18161c2d01a0f122548c66509dd1fcf3ee52975035bc79fb059e9613b743a16cd6f5ac54090e68f51bcf76ff21fb3805ba3197a96b4236afb80f791df802@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"48P3Y7d6C7cpMtXT38oBbijSexw3dpDSsHSIGxoqMlk=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: e3c3f7\npopulation: 14 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 1943 | 60 06db (0) 059a (0) 0400 (0) 0047 (0)\n001 3 954a 9386 ac23 | 32 8bf5 (0) 8c5b (0) 8fe2 (0) 8ec6 (0)\n002 2 d386 ca97 | 17 c7fd (0) c358 (0) c243 (0) cac9 (0)\n003 2 f80e feb3 | 10 f07c (0) f2b8 (0) f29f (0) f3a1 (0)\n004 2 ea51 ec3b | 4 ebf9 (0) ea94 (0) ea51 (0) ec3b (0)\n005 2 e425 e5cd | 2 e425 (0) e5cd (0)\n============ DEPTH: 6 ==========================================\n006 1 e0ac | 1 e0ac (0)\n007 0 | 0\n008 0 | 0\n009 1 e39e | 1 e39e (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"a05a18161c2d01a0f122548c66509dd1fcf3ee52975035bc79fb059e9613b743a16cd6f5ac54090e68f51bcf76ff21fb3805ba3197a96b4236afb80f791df802","private_key":"97cc28baaa8c94c905d348295eb19ef607599d22742989105d03eff39a5d6d51","name":"node_a05a18161c2d01a0f122548c66509dd1fcf3ee52975035bc79fb059e9613b743a16cd6f5ac54090e68f51bcf76ff21fb3805ba3197a96b4236afb80f791df802","services":["streamer"],"enable_msg_events":true,"port":63088},"up":true}},{"node":{"info":{"id":"c89dbada7195464e732671ac6fff014cacfb4c879b63b6b84e7c1bce367522f759bd06e504b15f43a1735c6322356747fa5c4951882d4fd6cdf6f7cf13726719","name":"node_c89dbada7195464e732671ac6fff014cacfb4c879b63b6b84e7c1bce367522f759bd06e504b15f43a1735c6322356747fa5c4951882d4fd6cdf6f7cf13726719","enode":"enode://c89dbada7195464e732671ac6fff014cacfb4c879b63b6b84e7c1bce367522f759bd06e504b15f43a1735c6322356747fa5c4951882d4fd6cdf6f7cf13726719@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"/rNFUzayY2W4HfyMuio5BpDOmW4H/LfxImcg0mMgWt8=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: feb345\npopulation: 17 (106), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 4309 | 46 059a (0) 0400 (0) 1385 (0) 11a6 (0)\n001 5 9386 954a 811d a12e | 26 b220 (0) b1bf (0) b9e5 (0) a60b (0)\n002 2 d192 d87f | 16 c7fd (0) c243 (0) ca97 (0) cac9 (0)\n003 3 ea51 ec3b e3c3 | 9 ebf9 (0) ea94 (0) ea51 (0) ec3b (0)\n004 1 f3a1 | 4 f07c (0) f29f (0) f2b8 (0) f3a1 (0)\n============ DEPTH: 5 ==========================================\n005 5 fba8 fa62 f80e f836 | 5 fba8 (0) fa62 (0) f80e (0) f836 (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"c89dbada7195464e732671ac6fff014cacfb4c879b63b6b84e7c1bce367522f759bd06e504b15f43a1735c6322356747fa5c4951882d4fd6cdf6f7cf13726719","private_key":"9f191333ec4b20a2380317b819e71ffc234e63e85ec57548c407e1740c07f41f","name":"node_c89dbada7195464e732671ac6fff014cacfb4c879b63b6b84e7c1bce367522f759bd06e504b15f43a1735c6322356747fa5c4951882d4fd6cdf6f7cf13726719","services":["streamer"],"enable_msg_events":true,"port":63089},"up":true}},{"node":{"info":{"id":"51302ef7b50922398ad802e917390bb4a3c24c877f2c2bcb7fcb34de9feca22673a2c594639914fe46a28837ffadfd03bb673afbc856aff5e59caf8e76082482","name":"node_51302ef7b50922398ad802e917390bb4a3c24c877f2c2bcb7fcb34de9feca22673a2c594639914fe46a28837ffadfd03bb673afbc856aff5e59caf8e76082482","enode":"enode://51302ef7b50922398ad802e917390bb4a3c24c877f2c2bcb7fcb34de9feca22673a2c594639914fe46a28837ffadfd03bb673afbc856aff5e59caf8e76082482@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"QwnC2WPZHmX36OirQt9S51+NN31OsH0aBIwAgq9PUB4=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 4309c2\npopulation: 14 (125), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 feb3 | 66 b1bf (0) b220 (0) b9e5 (0) bf7b (0)\n001 1 1943 | 23 0047 (0) 06db (0) 059a (0) 0400 (0)\n002 2 6120 6e83 | 21 7628 (0) 7692 (0) 740b (0) 7c76 (0)\n003 1 5d6d | 5 500f (0) 53ea (0) 57df (0) 5b36 (0)\n004 2 48a1 4827 | 3 4ae6 (0) 48a1 (0) 4827 (0)\n005 2 4454 4778 | 2 4454 (0) 4778 (0)\n006 2 4087 4124 | 2 4087 (0) 4124 (0)\n============ DEPTH: 7 ==========================================\n007 2 4259 4236 | 2 4259 (0) 4236 (0)\n008 0 | 0\n009 1 436c | 1 436c (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"51302ef7b50922398ad802e917390bb4a3c24c877f2c2bcb7fcb34de9feca22673a2c594639914fe46a28837ffadfd03bb673afbc856aff5e59caf8e76082482","private_key":"9b597a8aa9ae03a20ec963fd3eeaca13823d7efd28a70c4c44ebfa6e147bb24a","name":"node_51302ef7b50922398ad802e917390bb4a3c24c877f2c2bcb7fcb34de9feca22673a2c594639914fe46a28837ffadfd03bb673afbc856aff5e59caf8e76082482","services":["streamer"],"enable_msg_events":true,"port":63090},"up":true}},{"node":{"info":{"id":"a40391285d1a97f1fb368b20c8e4d02be1bdebc0db41f00f99aac2f01893dc12256cd5a711117a981fbb3f9dfea18c19cf3603e925dbd67c4032b22b41eab8d5","name":"node_a40391285d1a97f1fb368b20c8e4d02be1bdebc0db41f00f99aac2f01893dc12256cd5a711117a981fbb3f9dfea18c19cf3603e925dbd67c4032b22b41eab8d5","enode":"enode://a40391285d1a97f1fb368b20c8e4d02be1bdebc0db41f00f99aac2f01893dc12256cd5a711117a981fbb3f9dfea18c19cf3603e925dbd67c4032b22b41eab8d5@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"Q2yMKlbLwDMQI3xkbHIm+OS9Zy9oJRrIzJZ40xJueqg=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 436c8c\npopulation: 25 (112), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 9386 811d a8ba | 54 bf7b (0) b9e5 (0) b1bf (0) b220 (0)\n001 6 2a2b 30a0 3d3a 059a | 22 0047 (0) 06db (0) 0400 (0) 059a (0)\n002 4 7bcf 6640 6120 6e83 | 21 740b (0) 7628 (0) 7692 (0) 78bf (0)\n003 2 57df 5d6d | 5 53ea (0) 500f (0) 57df (0) 5b36 (0)\n004 3 4ae6 4827 48a1 | 3 4827 (0) 48a1 (0) 4ae6 (0)\n005 2 4778 4454 | 2 4778 (0) 4454 (0)\n006 2 4087 4124 | 2 4087 (0) 4124 (0)\n============ DEPTH: 7 ==========================================\n007 2 4236 4259 | 2 4236 (0) 4259 (0)\n008 0 | 0\n009 1 4309 | 1 4309 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"a40391285d1a97f1fb368b20c8e4d02be1bdebc0db41f00f99aac2f01893dc12256cd5a711117a981fbb3f9dfea18c19cf3603e925dbd67c4032b22b41eab8d5","private_key":"342dbb181da6045ae41eacef680b93f58765c7c5d65713f25f8b0627863c7983","name":"node_a40391285d1a97f1fb368b20c8e4d02be1bdebc0db41f00f99aac2f01893dc12256cd5a711117a981fbb3f9dfea18c19cf3603e925dbd67c4032b22b41eab8d5","services":["streamer"],"enable_msg_events":true,"port":63091},"up":true}},{"node":{"info":{"id":"e0420ba2a293315d810928a0e09a507c6aaf93977ba2c7598e9b83723b4a66682398ea17542c26767c7ff0f4ca09c537d3cc10dad283f079f1de73e25e87cb5c","name":"node_e0420ba2a293315d810928a0e09a507c6aaf93977ba2c7598e9b83723b4a66682398ea17542c26767c7ff0f4ca09c537d3cc10dad283f079f1de73e25e87cb5c","enode":"enode://e0420ba2a293315d810928a0e09a507c6aaf93977ba2c7598e9b83723b4a66682398ea17542c26767c7ff0f4ca09c537d3cc10dad283f079f1de73e25e87cb5c@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"boMV3FUsgRLcsB6TArXkf+9/vcgfvnodCyfgz4CmXKQ=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 6e8315\npopulation: 17 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 a8ba ac23 | 68 bf7b (0) b9e5 (0) b1bf (0) b220 (0)\n001 3 3d3a 1943 1ab1 | 23 3e4f (0) 3f1e (0) 3d3a (0) 314e (0)\n002 3 4124 4309 436c | 16 57df (0) 500f (0) 53ea (0) 5b36 (0)\n003 3 78bf 7f5f 7c76 | 9 740b (0) 7628 (0) 7692 (0) 7bcf (0)\n004 1 6120 | 5 6640 (0) 6632 (0) 6099 (0) 60ad (0)\n005 3 6a57 6aef 6838 | 4 6838 (0) 6aef (0) 6ac7 (0) 6a57 (0)\n============ DEPTH: 6 ==========================================\n006 2 6c1f 6cf1 | 2 6c1f (0) 6cf1 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"e0420ba2a293315d810928a0e09a507c6aaf93977ba2c7598e9b83723b4a66682398ea17542c26767c7ff0f4ca09c537d3cc10dad283f079f1de73e25e87cb5c","private_key":"af173c26c979843230716c1a7f4aade4f9a19a23e2ee665d0a0ecae0f793188e","name":"node_e0420ba2a293315d810928a0e09a507c6aaf93977ba2c7598e9b83723b4a66682398ea17542c26767c7ff0f4ca09c537d3cc10dad283f079f1de73e25e87cb5c","services":["streamer"],"enable_msg_events":true,"port":63092},"up":true}},{"node":{"info":{"id":"33e3ab7108ced43102003c3b3192b194100f32b6bcb67bb772ea9696e35721196699cf01e443f7cdf8076ad83aaf7468b75c71d03efb95f4c07cf0742ea9af81","name":"node_33e3ab7108ced43102003c3b3192b194100f32b6bcb67bb772ea9696e35721196699cf01e443f7cdf8076ad83aaf7468b75c71d03efb95f4c07cf0742ea9af81","enode":"enode://33e3ab7108ced43102003c3b3192b194100f32b6bcb67bb772ea9696e35721196699cf01e443f7cdf8076ad83aaf7468b75c71d03efb95f4c07cf0742ea9af81@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"GrFZFDH4uipaoREP+Xkmy/gNCA3tCRktyuDEv+rqHsA=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 1ab159\npopulation: 22 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 7 f836 d192 d87f ac23 | 68 b9e5 (0) bf7b (0) b220 (0) b1bf (0)\n001 3 6e83 436c 4124 | 37 740b (0) 7628 (0) 7692 (0) 7bcf (0)\n002 5 3d3a 311f 30a0 237b | 12 3f1e (0) 3e4f (0) 3d3a (0) 314e (0)\n003 1 0400 | 4 0047 (0) 06db (0) 059a (0) 0400 (0)\n004 2 1385 11a6 | 2 1385 (0) 11a6 (0)\n005 2 1f2a 1ea8 | 2 1f2a (0) 1ea8 (0)\n============ DEPTH: 6 ==========================================\n006 2 18f6 1943 | 2 18f6 (0) 1943 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"33e3ab7108ced43102003c3b3192b194100f32b6bcb67bb772ea9696e35721196699cf01e443f7cdf8076ad83aaf7468b75c71d03efb95f4c07cf0742ea9af81","private_key":"4598804bbccfa26a362afa9773f283bfbc0ab7660240791e38f7ba858e45280d","name":"node_33e3ab7108ced43102003c3b3192b194100f32b6bcb67bb772ea9696e35721196699cf01e443f7cdf8076ad83aaf7468b75c71d03efb95f4c07cf0742ea9af81","services":["streamer"],"enable_msg_events":true,"port":63093},"up":true}},{"node":{"info":{"id":"cbed12dcab0aa04a96ec7e25bc2ee03b337c7b2006391baa7d2aff042c17ec70b82c5fb2dc916d085a7948541719d329f9b528b67ec6adb1ac2cc594d4ef1e42","name":"node_cbed12dcab0aa04a96ec7e25bc2ee03b337c7b2006391baa7d2aff042c17ec70b82c5fb2dc916d085a7948541719d329f9b528b67ec6adb1ac2cc594d4ef1e42","enode":"enode://cbed12dcab0aa04a96ec7e25bc2ee03b337c7b2006391baa7d2aff042c17ec70b82c5fb2dc916d085a7948541719d329f9b528b67ec6adb1ac2cc594d4ef1e42@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"QSToNRVICBjCUKPKLYp7FZyJCYPDUWXuUx0uFQZscgM=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 4124e8\npopulation: 17 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 9386 | 68 cac9 (0) ca97 (0) c7fd (0) c358 (0)\n001 4 3d3a 2a2b 1943 1ab1 | 23 3f1e (0) 3e4f (0) 3d3a (0) 314e (0)\n002 2 6120 6e83 | 21 740b (0) 7628 (0) 7692 (0) 7bcf (0)\n003 1 5d6d | 5 57df (0) 500f (0) 53ea (0) 5b36 (0)\n004 2 4827 4ae6 | 3 4ae6 (0) 48a1 (0) 4827 (0)\n005 2 4778 4454 | 2 4454 (0) 4778 (0)\n============ DEPTH: 6 ==========================================\n006 4 4236 4259 4309 436c | 4 4259 (0) 4236 (0) 4309 (0) 436c (0)\n007 1 4087 | 1 4087 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"cbed12dcab0aa04a96ec7e25bc2ee03b337c7b2006391baa7d2aff042c17ec70b82c5fb2dc916d085a7948541719d329f9b528b67ec6adb1ac2cc594d4ef1e42","private_key":"253935f834190e90b6bf0646618d2992233bf386ea31a58770e1926cb063050c","name":"node_cbed12dcab0aa04a96ec7e25bc2ee03b337c7b2006391baa7d2aff042c17ec70b82c5fb2dc916d085a7948541719d329f9b528b67ec6adb1ac2cc594d4ef1e42","services":["streamer"],"enable_msg_events":true,"port":63094},"up":true}},{"node":{"info":{"id":"03d2d77c008b5fa1063b1abc3152b879a529fe4fdb2dc174d6d85312264a38ee4cc49b342507a10fff1a4b0730f1ef8e008b0897d97bfd6f70050adb124d3596","name":"node_03d2d77c008b5fa1063b1abc3152b879a529fe4fdb2dc174d6d85312264a38ee4cc49b342507a10fff1a4b0730f1ef8e008b0897d97bfd6f70050adb124d3596","enode":"enode://03d2d77c008b5fa1063b1abc3152b879a529fe4fdb2dc174d6d85312264a38ee4cc49b342507a10fff1a4b0730f1ef8e008b0897d97bfd6f70050adb124d3596@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"k4aO+Q/Inf8YXX5Z26NLPpRJqwM2//EsZP9OzD8DO3g=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 93868e\npopulation: 26 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 7 2a2b 1ab1 6aef 60ad | 60 3f1e (0) 3e4f (0) 3d3a (0) 314e (0)\n001 6 d192 d87f feb3 f836 | 36 c7fd (0) c243 (0) c358 (0) cac9 (0)\n002 2 aec5 a8ba | 12 bf7b (0) b9e5 (0) b1bf (0) b220 (0)\n003 3 8e31 8c5b 811d | 10 8bf5 (0) 8fe2 (0) 8ec6 (0) 8e31 (0)\n004 2 9f97 9cbc | 3 981b (0) 9f97 (0) 9cbc (0)\n005 4 954a 97a5 96e9 96b7 | 4 954a (0) 97a5 (0) 96e9 (0) 96b7 (0)\n006 0 | 0\n============ DEPTH: 7 ==========================================\n007 1 92e2 | 1 92e2 (0)\n008 1 931a | 1 931a (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"03d2d77c008b5fa1063b1abc3152b879a529fe4fdb2dc174d6d85312264a38ee4cc49b342507a10fff1a4b0730f1ef8e008b0897d97bfd6f70050adb124d3596","private_key":"f6d280904f13397798c441bffafc78ab98461c9d84f01f4b9b73de50d5595fd0","name":"node_03d2d77c008b5fa1063b1abc3152b879a529fe4fdb2dc174d6d85312264a38ee4cc49b342507a10fff1a4b0730f1ef8e008b0897d97bfd6f70050adb124d3596","services":["streamer"],"enable_msg_events":true,"port":63095},"up":true}},{"node":{"info":{"id":"f0299035cbddfdf7a78e5e3a400aaedf2d719d04e907ac0f9f067525e2f9bb913d985308a3a0d05467a64adf58c68a615c6327acf716c23631d0e829903f8b34","name":"node_f0299035cbddfdf7a78e5e3a400aaedf2d719d04e907ac0f9f067525e2f9bb913d985308a3a0d05467a64adf58c68a615c6327acf716c23631d0e829903f8b34","enode":"enode://f0299035cbddfdf7a78e5e3a400aaedf2d719d04e907ac0f9f067525e2f9bb913d985308a3a0d05467a64adf58c68a615c6327acf716c23631d0e829903f8b34@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"qLowjv7A7TGNaL01YaQfuwr4Q4Pj9TM+JkKsnWAAWrk=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: a8ba30\npopulation: 23 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 5 2a2b 06db 1ab1 6e83 | 60 0047 (0) 06db (0) 0400 (0) 059a (0)\n001 6 d87f d80b d552 feb3 | 36 ca97 (0) cac9 (0) c7fd (0) c243 (0)\n002 6 8c5b 8e31 811d 96b7 | 20 8bf5 (0) 8c5b (0) 8fe2 (0) 8ec6 (0)\n003 1 b9e5 | 4 b1bf (0) b220 (0) bf7b (0) b9e5 (0)\n004 2 a12e a3fc | 4 a60b (0) a12e (0) a250 (0) a3fc (0)\n============ DEPTH: 5 ==========================================\n005 2 aec5 ac23 | 2 aec5 (0) ac23 (0)\n006 1 aa19 | 1 aa19 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"f0299035cbddfdf7a78e5e3a400aaedf2d719d04e907ac0f9f067525e2f9bb913d985308a3a0d05467a64adf58c68a615c6327acf716c23631d0e829903f8b34","private_key":"5237d9097b72efee4e45c4d3d14e320e49ded470809478f3ccf6a9a7cf732d74","name":"node_f0299035cbddfdf7a78e5e3a400aaedf2d719d04e907ac0f9f067525e2f9bb913d985308a3a0d05467a64adf58c68a615c6327acf716c23631d0e829903f8b34","services":["streamer"],"enable_msg_events":true,"port":63096},"up":true}},{"node":{"info":{"id":"276256790c9317d09ff7802f4ad0a85840fe62527390ce1790e1e3186e8b3f04acfaa41dcd02303d333423678a4037e4f4854676e79ced3232a3dbd772cc2680","name":"node_276256790c9317d09ff7802f4ad0a85840fe62527390ce1790e1e3186e8b3f04acfaa41dcd02303d333423678a4037e4f4854676e79ced3232a3dbd772cc2680","enode":"enode://276256790c9317d09ff7802f4ad0a85840fe62527390ce1790e1e3186e8b3f04acfaa41dcd02303d333423678a4037e4f4854676e79ced3232a3dbd772cc2680@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"7DteoLxDwe8a4nROp0eIfcWO81JuqGAYVvHhjn8BoZc=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: ec3b5e\npopulation: 22 (118), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 7f62 4827 | 55 0047 (0) 06db (0) 0400 (0) 059a (0)\n001 3 954a a3fc a8ba | 28 b1bf (0) b220 (0) bf7b (0) b9e5 (0)\n002 7 d87f d552 d798 d386 | 17 d192 (0) d386 (0) d382 (0) d68e (0)\n003 2 f836 feb3 | 10 f07c (0) f2b8 (0) f29f (0) f3a1 (0)\n004 5 e425 e5cd e0ac e39e | 5 e425 (0) e5cd (0) e0ac (0) e39e (0)\n============ DEPTH: 5 ==========================================\n005 3 ebf9 ea94 ea51 | 3 ebf9 (0) ea94 (0) ea51 (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"276256790c9317d09ff7802f4ad0a85840fe62527390ce1790e1e3186e8b3f04acfaa41dcd02303d333423678a4037e4f4854676e79ced3232a3dbd772cc2680","private_key":"a8d169922df4dcd07e1f102e3eae5692eb87b1f368124cb5c65fcca22f9743aa","name":"node_276256790c9317d09ff7802f4ad0a85840fe62527390ce1790e1e3186e8b3f04acfaa41dcd02303d333423678a4037e4f4854676e79ced3232a3dbd772cc2680","services":["streamer"],"enable_msg_events":true,"port":63097},"up":true}},{"node":{"info":{"id":"155805f787600f9f9518cf8836f491885b64868bfe0023975bcd12776925a424fb5aa3199dc178e83294e97f347a373d05d2422578a08eeeb2d15a178d28964f","name":"node_155805f787600f9f9518cf8836f491885b64868bfe0023975bcd12776925a424fb5aa3199dc178e83294e97f347a373d05d2422578a08eeeb2d15a178d28964f","enode":"enode://155805f787600f9f9518cf8836f491885b64868bfe0023975bcd12776925a424fb5aa3199dc178e83294e97f347a373d05d2422578a08eeeb2d15a178d28964f@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"SCdKNT3ubAQlN8mZ+JzN3depwTn6i4JHUElr188nJrI=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 48274a\npopulation: 23 (96), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 931a 96b7 ec3b | 47 bf7b (0) b9e5 (0) a60b (0) a12e (0)\n001 4 1ea8 11a6 3e4f 311f | 20 06db (0) 059a (0) 0047 (0) 11a6 (0)\n002 6 7c76 7e65 7f62 6632 | 18 6099 (0) 60ad (0) 6120 (0) 6640 (0)\n003 1 53ea | 2 57df (0) 53ea (0)\n004 7 4778 4087 4124 4236 | 7 4778 (0) 4087 (0) 4124 (0) 4236 (0)\n005 0 | 0\n============ DEPTH: 6 ==========================================\n006 1 4ae6 | 1 4ae6 (0)\n007 0 | 0\n008 1 48a1 | 1 48a1 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"155805f787600f9f9518cf8836f491885b64868bfe0023975bcd12776925a424fb5aa3199dc178e83294e97f347a373d05d2422578a08eeeb2d15a178d28964f","private_key":"8b927156a8aa7b6cc711c9c2ce3016cab2e9d1ce220e9792207cc5b40fca3047","name":"node_155805f787600f9f9518cf8836f491885b64868bfe0023975bcd12776925a424fb5aa3199dc178e83294e97f347a373d05d2422578a08eeeb2d15a178d28964f","services":["streamer"],"enable_msg_events":true,"port":63098},"up":true}},{"node":{"info":{"id":"4de606aa7e722197b918c5f7f0db86a3081d48e89d21428b04f19c3ff3755eac0bddbff5fad8bda94b9e57f58fba2fecdbabbf710f7afb381bf4f1a4fe55cd93","name":"node_4de606aa7e722197b918c5f7f0db86a3081d48e89d21428b04f19c3ff3755eac0bddbff5fad8bda94b9e57f58fba2fecdbabbf710f7afb381bf4f1a4fe55cd93","enode":"enode://4de606aa7e722197b918c5f7f0db86a3081d48e89d21428b04f19c3ff3755eac0bddbff5fad8bda94b9e57f58fba2fecdbabbf710f7afb381bf4f1a4fe55cd93@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"lrcj3ghA9lbJFGdK0gIE2oMMBNTWlWwy4gFUy8xA+e8=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 96b723\npopulation: 18 (118), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 4827 | 53 0400 (0) 059a (0) 0047 (0) 1385 (0)\n001 3 d552 d382 d386 | 34 d192 (0) d382 (0) d386 (0) d68e (0)\n002 6 b9e5 a3fc a12e a8ba | 12 b1bf (0) b220 (0) bf7b (0) b9e5 (0)\n003 1 811d | 10 8bf5 (0) 8c5b (0) 8fe2 (0) 8ec6 (0)\n004 1 9cbc | 3 981b (0) 9f97 (0) 9cbc (0)\n005 3 92e2 931a 9386 | 3 92e2 (0) 931a (0) 9386 (0)\n006 1 954a | 1 954a (0)\n============ DEPTH: 7 ==========================================\n007 1 97a5 | 1 97a5 (0)\n008 0 | 0\n009 1 96e9 | 1 96e9 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"4de606aa7e722197b918c5f7f0db86a3081d48e89d21428b04f19c3ff3755eac0bddbff5fad8bda94b9e57f58fba2fecdbabbf710f7afb381bf4f1a4fe55cd93","private_key":"d2b8d940f626faf3204dd38721f5528e1c9db4b5d0cc28d0d627c7d191c1f21f","name":"node_4de606aa7e722197b918c5f7f0db86a3081d48e89d21428b04f19c3ff3755eac0bddbff5fad8bda94b9e57f58fba2fecdbabbf710f7afb381bf4f1a4fe55cd93","services":["streamer"],"enable_msg_events":true,"port":63099},"up":true}},{"node":{"info":{"id":"82a774be7146766585d2bec6b69b7803aa956f492a53d8ed5f071becdbbc617562885d8430f0afd505210aab7b032428fbea32c82dffbd12d9ccba776ef4729b","name":"node_82a774be7146766585d2bec6b69b7803aa956f492a53d8ed5f071becdbbc617562885d8430f0afd505210aab7b032428fbea32c82dffbd12d9ccba776ef4729b","enode":"enode://82a774be7146766585d2bec6b69b7803aa956f492a53d8ed5f071becdbbc617562885d8430f0afd505210aab7b032428fbea32c82dffbd12d9ccba776ef4729b@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"rsUg9Qfu3V11K2uooLUJ8UEF5eRX7vC2U3AV45Vpdis=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: aec520\npopulation: 19 (125), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 7 7f62 7e65 6c1f 6cf1 | 58 0400 (0) 059a (0) 06db (0) 0047 (0)\n001 2 d552 d80b | 36 d68e (0) d7f9 (0) d798 (0) d552 (0)\n002 3 92e2 9386 96b7 | 20 8bf5 (0) 8c5b (0) 8fe2 (0) 8ec6 (0)\n003 1 b9e5 | 4 b220 (0) b1bf (0) bf7b (0) b9e5 (0)\n004 3 a12e a250 a3fc | 4 a60b (0) a12e (0) a250 (0) a3fc (0)\n============ DEPTH: 5 ==========================================\n005 2 aa19 a8ba | 2 aa19 (0) a8ba (0)\n006 1 ac23 | 1 ac23 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"82a774be7146766585d2bec6b69b7803aa956f492a53d8ed5f071becdbbc617562885d8430f0afd505210aab7b032428fbea32c82dffbd12d9ccba776ef4729b","private_key":"1cd1a1e084096aa4f8f9933b0871657638dad24b3f47d18c9eb0007595ce46f1","name":"node_82a774be7146766585d2bec6b69b7803aa956f492a53d8ed5f071becdbbc617562885d8430f0afd505210aab7b032428fbea32c82dffbd12d9ccba776ef4729b","services":["streamer"],"enable_msg_events":true,"port":63100},"up":true}},{"node":{"info":{"id":"340420ee18d55913f790d0fcc2305b40b1e7bef2eddb79dda57801690aeeead693ebd1a9ff8557671f5ae136b3e65733306924bd00444cbc6e7c6235e5a2c77f","name":"node_340420ee18d55913f790d0fcc2305b40b1e7bef2eddb79dda57801690aeeead693ebd1a9ff8557671f5ae136b3e65733306924bd00444cbc6e7c6235e5a2c77f","enode":"enode://340420ee18d55913f790d0fcc2305b40b1e7bef2eddb79dda57801690aeeead693ebd1a9ff8557671f5ae136b3e65733306924bd00444cbc6e7c6235e5a2c77f@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"o/zvj/i8cCxkUrDEp7iZ38VRu4KTsX8vYTPMeNZlgdg=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: a3fcef\npopulation: 24 (78), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 8 2a2b 11a6 1ea8 4259 | 30 4827 (0) 436c (0) 4236 (0) 4259 (0)\n001 5 d87f d80b ec3b e5cd | 27 f07c (0) f29f (0) f3a1 (0) feb3 (0)\n002 3 8c5b 96b7 931a | 11 8e31 (0) 8c5b (0) 87e0 (0) 8230 (0)\n003 1 b9e5 | 3 b1bf (0) bf7b (0) b9e5 (0)\n004 4 aa19 a8ba ac23 aec5 | 4 aa19 (0) a8ba (0) ac23 (0) aec5 (0)\n005 1 a60b | 1 a60b (0)\n============ DEPTH: 6 ==========================================\n006 1 a12e | 1 a12e (0)\n007 1 a250 | 1 a250 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"340420ee18d55913f790d0fcc2305b40b1e7bef2eddb79dda57801690aeeead693ebd1a9ff8557671f5ae136b3e65733306924bd00444cbc6e7c6235e5a2c77f","private_key":"8ec23f2c16d923996d6bd74aa374cb6e5a69fab748ea8efa538d01a12ac62e16","name":"node_340420ee18d55913f790d0fcc2305b40b1e7bef2eddb79dda57801690aeeead693ebd1a9ff8557671f5ae136b3e65733306924bd00444cbc6e7c6235e5a2c77f","services":["streamer"],"enable_msg_events":true,"port":63101},"up":true}},{"node":{"info":{"id":"7a509686ebce91778fe22e834a94ab03f92457d41385099ba657fe62c7469a9669bddb9a3d7b0150efa1d2f40c69bc786c7f4ede1cf8b19411eea1d23cb7d56c","name":"node_7a509686ebce91778fe22e834a94ab03f92457d41385099ba657fe62c7469a9669bddb9a3d7b0150efa1d2f40c69bc786c7f4ede1cf8b19411eea1d23cb7d56c","enode":"enode://7a509686ebce91778fe22e834a94ab03f92457d41385099ba657fe62c7469a9669bddb9a3d7b0150efa1d2f40c69bc786c7f4ede1cf8b19411eea1d23cb7d56c@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"kxo2mAygeIYWyxyYUfYGnkTZRnGioFbhKn18r+WX3uU=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 931a36\npopulation: 11 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 4827 | 60 57df (0) 500f (0) 53ea (0) 5b36 (0)\n001 2 ebf9 db59 | 36 f07c (0) f2b8 (0) f29f (0) f3a1 (0)\n002 1 a3fc | 12 b1bf (0) b220 (0) bf7b (0) b9e5 (0)\n003 1 811d | 10 8bf5 (0) 8c5b (0) 8fe2 (0) 8ec6 (0)\n004 1 9cbc | 3 981b (0) 9f97 (0) 9cbc (0)\n005 3 954a 96e9 96b7 | 4 954a (0) 97a5 (0) 96e9 (0) 96b7 (0)\n006 0 | 0\n============ DEPTH: 7 ==========================================\n007 1 92e2 | 1 92e2 (0)\n008 1 9386 | 1 9386 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"7a509686ebce91778fe22e834a94ab03f92457d41385099ba657fe62c7469a9669bddb9a3d7b0150efa1d2f40c69bc786c7f4ede1cf8b19411eea1d23cb7d56c","private_key":"b7a9a55daea83c1d769fe68e820de46f4a8df4c425ea7ab98a44cb7ad3c7963e","name":"node_7a509686ebce91778fe22e834a94ab03f92457d41385099ba657fe62c7469a9669bddb9a3d7b0150efa1d2f40c69bc786c7f4ede1cf8b19411eea1d23cb7d56c","services":["streamer"],"enable_msg_events":true,"port":63102},"up":true}},{"node":{"info":{"id":"816e91fa8ff68ba067a89390ef61e7f23211e5e05049daa103ad1ff84b94fbcf535a6f6b515fb571939f5656869767c608513808800baba7e5d2b5f3a17a9691","name":"node_816e91fa8ff68ba067a89390ef61e7f23211e5e05049daa103ad1ff84b94fbcf535a6f6b515fb571939f5656869767c608513808800baba7e5d2b5f3a17a9691","enode":"enode://816e91fa8ff68ba067a89390ef61e7f23211e5e05049daa103ad1ff84b94fbcf535a6f6b515fb571939f5656869767c608513808800baba7e5d2b5f3a17a9691@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"21lvT/P4wlg1+fEBduh6iCPq8dOaUTiC8c6rkx2r/tk=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: db596f\npopulation: 12 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 11a6 | 60 57df (0) 500f (0) 53ea (0) 5b36 (0)\n001 1 931a | 32 b1bf (0) b220 (0) bf7b (0) b9e5 (0)\n002 1 f995 | 19 f07c (0) f2b8 (0) f29f (0) f3a1 (0)\n003 3 cac9 c243 c7fd | 5 cac9 (0) ca97 (0) c243 (0) c358 (0)\n004 2 d382 d386 | 7 d68e (0) d7f9 (0) d798 (0) d552 (0)\n005 1 dc2a | 1 dc2a (0)\n============ DEPTH: 6 ==========================================\n006 3 d80b d87f d916 | 3 d87f (0) d80b (0) d916 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"816e91fa8ff68ba067a89390ef61e7f23211e5e05049daa103ad1ff84b94fbcf535a6f6b515fb571939f5656869767c608513808800baba7e5d2b5f3a17a9691","private_key":"c1478fa3ebc5b2bd2a32567455e71e73a1787b1c8c6571fd94ee0d487d5fea4d","name":"node_816e91fa8ff68ba067a89390ef61e7f23211e5e05049daa103ad1ff84b94fbcf535a6f6b515fb571939f5656869767c608513808800baba7e5d2b5f3a17a9691","services":["streamer"],"enable_msg_events":true,"port":63103},"up":true}},{"node":{"info":{"id":"77327983685f39f006806170fe351063a58ff1bd8dedc222d538e86cfd18abdfefd548328f25fc5afde8170aa5c35311353019468f2b439c331837ddfbb25a52","name":"node_77327983685f39f006806170fe351063a58ff1bd8dedc222d538e86cfd18abdfefd548328f25fc5afde8170aa5c35311353019468f2b439c331837ddfbb25a52","enode":"enode://77327983685f39f006806170fe351063a58ff1bd8dedc222d538e86cfd18abdfefd548328f25fc5afde8170aa5c35311353019468f2b439c331837ddfbb25a52@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"EaYNQ9YnRw3xwevcQECT9q6Dx1s6lUaTFriaAYXuqoY=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 11a60d\npopulation: 14 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 a3fc db59 | 68 b1bf (0) b220 (0) bf7b (0) b9e5 (0)\n001 3 4827 6632 6cf1 | 37 57df (0) 500f (0) 53ea (0) 5b36 (0)\n002 2 3e4f 311f | 12 237b (0) 2650 (0) 2dc2 (0) 2fee (0)\n003 1 059a | 4 0047 (0) 06db (0) 0400 (0) 059a (0)\n============ DEPTH: 4 ==========================================\n004 5 1943 18f6 1ab1 1f2a | 5 18f6 (0) 1943 (0) 1ab1 (0) 1f2a (0)\n005 0 | 0\n006 1 1385 | 1 1385 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"77327983685f39f006806170fe351063a58ff1bd8dedc222d538e86cfd18abdfefd548328f25fc5afde8170aa5c35311353019468f2b439c331837ddfbb25a52","private_key":"bb118c1ce93cddc4fb540863d575d6ae584ebc2f2e2f221c9622cc105e7fd7b9","name":"node_77327983685f39f006806170fe351063a58ff1bd8dedc222d538e86cfd18abdfefd548328f25fc5afde8170aa5c35311353019468f2b439c331837ddfbb25a52","services":["streamer"],"enable_msg_events":true,"port":63104},"up":true}},{"node":{"info":{"id":"7a18392b8338108a996196ee190a93a1b9954c8e05a062c421da513a1828dfa739e7b224878c0670cf74bbc743c7ca7ee8cfee6b6a602fe1f4a82ecfbd38c2f4","name":"node_7a18392b8338108a996196ee190a93a1b9954c8e05a062c421da513a1828dfa739e7b224878c0670cf74bbc743c7ca7ee8cfee6b6a602fe1f4a82ecfbd38c2f4","enode":"enode://7a18392b8338108a996196ee190a93a1b9954c8e05a062c421da513a1828dfa739e7b224878c0670cf74bbc743c7ca7ee8cfee6b6a602fe1f4a82ecfbd38c2f4@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"bPHTCwY8+DUnlaksavJsFU/ES+Bsaeqf1Nn23MYm7aE=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 6cf1d3\npopulation: 16 (126), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 aec5 a3fc c7fd | 68 dc2a (0) db59 (0) d87f (0) d80b (0)\n001 2 311f 11a6 | 22 237b (0) 2650 (0) 2dc2 (0) 2fee (0)\n002 1 4827 | 16 5b36 (0) 5d6d (0) 57df (0) 500f (0)\n003 5 7692 7c76 7e65 7f5f | 9 740b (0) 7628 (0) 7692 (0) 78bf (0)\n004 1 6120 | 5 6640 (0) 6632 (0) 60ad (0) 6099 (0)\n005 2 6a57 6ac7 | 4 6838 (0) 6aef (0) 6ac7 (0) 6a57 (0)\n============ DEPTH: 6 ==========================================\n006 1 6e83 | 1 6e83 (0)\n007 0 | 0\n008 1 6c1f | 1 6c1f (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"7a18392b8338108a996196ee190a93a1b9954c8e05a062c421da513a1828dfa739e7b224878c0670cf74bbc743c7ca7ee8cfee6b6a602fe1f4a82ecfbd38c2f4","private_key":"7cbe501dc7bdd1bafc62c5c56af215559b06aef4ed398d4a3acdb78f3c84a735","name":"node_7a18392b8338108a996196ee190a93a1b9954c8e05a062c421da513a1828dfa739e7b224878c0670cf74bbc743c7ca7ee8cfee6b6a602fe1f4a82ecfbd38c2f4","services":["streamer"],"enable_msg_events":true,"port":63105},"up":true}},{"node":{"info":{"id":"e7bb63c5187ee85d965fed5cb33d1678c0e090b4e4c3f3d859755565db18046cb60025453bdebf136373c416a2e6e56be063bca6c9257b7b175dcf966e274205","name":"node_e7bb63c5187ee85d965fed5cb33d1678c0e090b4e4c3f3d859755565db18046cb60025453bdebf136373c416a2e6e56be063bca6c9257b7b175dcf966e274205","enode":"enode://e7bb63c5187ee85d965fed5cb33d1678c0e090b4e4c3f3d859755565db18046cb60025453bdebf136373c416a2e6e56be063bca6c9257b7b175dcf966e274205@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"f2INMG4FusDweDi33mottpqmSU3z2wnyZiTtFnMYp1o=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 7f620d\npopulation: 18 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 ec3b aec5 a3fc b9e5 | 68 dc2a (0) db59 (0) d87f (0) d80b (0)\n001 2 311f 1ea8 | 23 237b (0) 2650 (0) 2dc2 (0) 2fee (0)\n002 2 4778 4827 | 16 5d6d (0) 5b36 (0) 57df (0) 500f (0)\n003 4 6632 6ac7 6c1f 6cf1 | 12 6640 (0) 6632 (0) 6099 (0) 60ad (0)\n004 1 7692 | 3 740b (0) 7628 (0) 7692 (0)\n005 2 7bcf 78bf | 2 78bf (0) 7bcf (0)\n006 1 7c76 | 1 7c76 (0)\n============ DEPTH: 7 ==========================================\n007 1 7e65 | 1 7e65 (0)\n008 0 | 0\n009 0 | 0\n010 1 7f5f | 1 7f5f (0)\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"e7bb63c5187ee85d965fed5cb33d1678c0e090b4e4c3f3d859755565db18046cb60025453bdebf136373c416a2e6e56be063bca6c9257b7b175dcf966e274205","private_key":"e853260ddb20771587ed33007ef55b07368a08f79ea0a64cf9830ab69498238f","name":"node_e7bb63c5187ee85d965fed5cb33d1678c0e090b4e4c3f3d859755565db18046cb60025453bdebf136373c416a2e6e56be063bca6c9257b7b175dcf966e274205","services":["streamer"],"enable_msg_events":true,"port":63106},"up":true}},{"node":{"info":{"id":"545850cb90787d49c579b1ed54a753ebd00eaafe3f1bd04d57266e4912fb1cdd654446ef054a973a583ce8dfc6cc130b6f90e63bcf75372fc21c445f8e1e6005","name":"node_545850cb90787d49c579b1ed54a753ebd00eaafe3f1bd04d57266e4912fb1cdd654446ef054a973a583ce8dfc6cc130b6f90e63bcf75372fc21c445f8e1e6005","enode":"enode://545850cb90787d49c579b1ed54a753ebd00eaafe3f1bd04d57266e4912fb1cdd654446ef054a973a583ce8dfc6cc130b6f90e63bcf75372fc21c445f8e1e6005@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"ueUAa5C/+ugJE2rVfja3hLGONfdJHEcxmAf2hp1iRGU=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: b9e500\npopulation: 18 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 2a2b 7f62 | 60 237b (0) 2650 (0) 2dc2 (0) 2fee (0)\n001 4 e5cd d80b ca97 c7fd | 36 f07c (0) f2b8 (0) f29f (0) f3a1 (0)\n002 2 96b7 8c5b | 20 8bf5 (0) 8c5b (0) 8fe2 (0) 8ec6 (0)\n003 7 aa19 a8ba ac23 aec5 | 8 a60b (0) a250 (0) a3fc (0) a12e (0)\n============ DEPTH: 4 ==========================================\n004 2 b1bf b220 | 2 b1bf (0) b220 (0)\n005 1 bf7b | 1 bf7b (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"545850cb90787d49c579b1ed54a753ebd00eaafe3f1bd04d57266e4912fb1cdd654446ef054a973a583ce8dfc6cc130b6f90e63bcf75372fc21c445f8e1e6005","private_key":"23c3dd23f790b16480c58305ab528346a7046dddd1d9f5c699a4963bfb926fb3","name":"node_545850cb90787d49c579b1ed54a753ebd00eaafe3f1bd04d57266e4912fb1cdd654446ef054a973a583ce8dfc6cc130b6f90e63bcf75372fc21c445f8e1e6005","services":["streamer"],"enable_msg_events":true,"port":63107},"up":true}},{"node":{"info":{"id":"86b84ddf64d301f6a9c4504c59eb4031d3167fb74101abea3b694845a009dc522be7b2e2720097ceea9f36058e160f42a2a438a33034929a5c1a7793c7ccef7b","name":"node_86b84ddf64d301f6a9c4504c59eb4031d3167fb74101abea3b694845a009dc522be7b2e2720097ceea9f36058e160f42a2a438a33034929a5c1a7793c7ccef7b","enode":"enode://86b84ddf64d301f6a9c4504c59eb4031d3167fb74101abea3b694845a009dc522be7b2e2720097ceea9f36058e160f42a2a438a33034929a5c1a7793c7ccef7b@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"x/2Ihkcx5reaz0NqdpCLkcYboHaAaZws2jFhecNxnoo=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: c7fd88\npopulation: 15 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 6cf1 7e65 | 60 2dc2 (0) 2fee (0) 2aef (0) 2a2b (0)\n001 2 a60b b9e5 | 32 8bf5 (0) 8c5b (0) 8fe2 (0) 8ec6 (0)\n002 1 ec3b | 19 f07c (0) f2b8 (0) f29f (0) f3a1 (0)\n003 6 d798 d552 d382 d386 | 12 dc2a (0) d916 (0) d87f (0) d80b (0)\n004 2 cac9 ca97 | 2 cac9 (0) ca97 (0)\n============ DEPTH: 5 ==========================================\n005 2 c243 c358 | 2 c243 (0) c358 (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"86b84ddf64d301f6a9c4504c59eb4031d3167fb74101abea3b694845a009dc522be7b2e2720097ceea9f36058e160f42a2a438a33034929a5c1a7793c7ccef7b","private_key":"e0f2a273dc23035aaf88bb97d7f5ccf57ee6304b184e7d61183556b28040076b","name":"node_86b84ddf64d301f6a9c4504c59eb4031d3167fb74101abea3b694845a009dc522be7b2e2720097ceea9f36058e160f42a2a438a33034929a5c1a7793c7ccef7b","services":["streamer"],"enable_msg_events":true,"port":63108},"up":true}},{"node":{"info":{"id":"bf1e6eeb8b229f63b49213db499b71dcfe0ae45ee3f14685c7cbfa3f0a2150e52a89c853f4cd8c7a92e6e5f6083044efddfa17391662e3cff6290da679520404","name":"node_bf1e6eeb8b229f63b49213db499b71dcfe0ae45ee3f14685c7cbfa3f0a2150e52a89c853f4cd8c7a92e6e5f6083044efddfa17391662e3cff6290da679520404","enode":"enode://bf1e6eeb8b229f63b49213db499b71dcfe0ae45ee3f14685c7cbfa3f0a2150e52a89c853f4cd8c7a92e6e5f6083044efddfa17391662e3cff6290da679520404@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"fmUGf6XbUtQMChYkMiAMptDTkXslytFc5Jj6a1N1vI0=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 7e6506\npopulation: 16 (121), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 aec5 a3fc c7fd | 62 8c5b (0) 8e31 (0) 8230 (0) 83bc (0)\n001 2 311f 1ea8 | 23 237b (0) 2650 (0) 2a2b (0) 2aef (0)\n002 1 4827 | 16 5d6d (0) 5b36 (0) 57df (0) 500f (0)\n003 3 6ac7 6c1f 6cf1 | 12 6640 (0) 6632 (0) 6099 (0) 60ad (0)\n004 2 7628 7692 | 3 740b (0) 7628 (0) 7692 (0)\n005 2 78bf 7bcf | 2 78bf (0) 7bcf (0)\n006 1 7c76 | 1 7c76 (0)\n============ DEPTH: 7 ==========================================\n007 2 7f5f 7f62 | 2 7f5f (0) 7f62 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"bf1e6eeb8b229f63b49213db499b71dcfe0ae45ee3f14685c7cbfa3f0a2150e52a89c853f4cd8c7a92e6e5f6083044efddfa17391662e3cff6290da679520404","private_key":"dacac1dfd252a4ad8878c023bd34aa1bc81b63d66d70c8ba9aafcfa8425bb253","name":"node_bf1e6eeb8b229f63b49213db499b71dcfe0ae45ee3f14685c7cbfa3f0a2150e52a89c853f4cd8c7a92e6e5f6083044efddfa17391662e3cff6290da679520404","services":["streamer"],"enable_msg_events":true,"port":63109},"up":true}},{"node":{"info":{"id":"a58a2dd3f5ee2471f0ddd555ffcc45d86e2d8c325585e3fe55eee878b8a626faccce73679d32811fc5d068c153e671673f4cd020f3c7fb37bc6fd9646931646a","name":"node_a58a2dd3f5ee2471f0ddd555ffcc45d86e2d8c325585e3fe55eee878b8a626faccce73679d32811fc5d068c153e671673f4cd020f3c7fb37bc6fd9646931646a","enode":"enode://a58a2dd3f5ee2471f0ddd555ffcc45d86e2d8c325585e3fe55eee878b8a626faccce73679d32811fc5d068c153e671673f4cd020f3c7fb37bc6fd9646931646a@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"HqicPxW4I4XF34gQ7Hy9MOjkpOBcHd9dvnEC7aoHr9I=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 1ea89c\npopulation: 17 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 a3fc aec5 d386 | 68 8bf5 (0) 8c5b (0) 8fe2 (0) 8ec6 (0)\n001 3 4827 7f62 7e65 | 37 5d6d (0) 5b36 (0) 57df (0) 500f (0)\n002 2 311f 3e4f | 12 237b (0) 2650 (0) 2dc2 (0) 2fee (0)\n003 3 059a 0400 0047 | 4 0047 (0) 06db (0) 0400 (0) 059a (0)\n004 2 1385 11a6 | 2 1385 (0) 11a6 (0)\n============ DEPTH: 5 ==========================================\n005 3 1943 18f6 1ab1 | 3 18f6 (0) 1943 (0) 1ab1 (0)\n006 0 | 0\n007 1 1f2a | 1 1f2a (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"a58a2dd3f5ee2471f0ddd555ffcc45d86e2d8c325585e3fe55eee878b8a626faccce73679d32811fc5d068c153e671673f4cd020f3c7fb37bc6fd9646931646a","private_key":"57a2dcb70aa306ae204744fce4dd4b4ad9b02516e080dca195604406e240627c","name":"node_a58a2dd3f5ee2471f0ddd555ffcc45d86e2d8c325585e3fe55eee878b8a626faccce73679d32811fc5d068c153e671673f4cd020f3c7fb37bc6fd9646931646a","services":["streamer"],"enable_msg_events":true,"port":63110},"up":true}},{"node":{"info":{"id":"896c74ca4cc4cbb9d2b6606d0ebfd6427952c2e16aedbf36933fa3d01f1c505fcd663f3d01c0cf096bef9cfd0bae4595ec7c221cfc362e19a5b7c60614a9658b","name":"node_896c74ca4cc4cbb9d2b6606d0ebfd6427952c2e16aedbf36933fa3d01f1c505fcd663f3d01c0cf096bef9cfd0bae4595ec7c221cfc362e19a5b7c60614a9658b","enode":"enode://896c74ca4cc4cbb9d2b6606d0ebfd6427952c2e16aedbf36933fa3d01f1c505fcd663f3d01c0cf096bef9cfd0bae4595ec7c221cfc362e19a5b7c60614a9658b@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"04ZMFg5tj8s/VAuGTm7hHZHKcI8svh5f0EvrK2wdiTA=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: d3864c\npopulation: 18 (125), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 311f 1ea8 | 58 57df (0) 53ea (0) 500f (0) 5d6d (0)\n001 4 811d 8e31 8c5b 96b7 | 32 8bf5 (0) 8c5b (0) 8fe2 (0) 8ec6 (0)\n002 3 e3c3 ea51 ec3b | 19 fba8 (0) fa62 (0) f995 (0) f80e (0)\n003 3 c243 c358 c7fd | 5 ca97 (0) cac9 (0) c7fd (0) c243 (0)\n004 1 db59 | 5 dc2a (0) d916 (0) d87f (0) d80b (0)\n005 3 d7f9 d798 d552 | 4 d68e (0) d7f9 (0) d798 (0) d552 (0)\n============ DEPTH: 6 ==========================================\n006 1 d192 | 1 d192 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 1 d382 | 1 d382 (0)\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"896c74ca4cc4cbb9d2b6606d0ebfd6427952c2e16aedbf36933fa3d01f1c505fcd663f3d01c0cf096bef9cfd0bae4595ec7c221cfc362e19a5b7c60614a9658b","private_key":"4314dbd43bea3cdbe75a24ef256ee0dca9008f5133f8b1d6c9adf9a84210c2e1","name":"node_896c74ca4cc4cbb9d2b6606d0ebfd6427952c2e16aedbf36933fa3d01f1c505fcd663f3d01c0cf096bef9cfd0bae4595ec7c221cfc362e19a5b7c60614a9658b","services":["streamer"],"enable_msg_events":true,"port":63111},"up":true}},{"node":{"info":{"id":"1e0a46ff50fb6d9a2c218a851763ff86c42e4d61dddffb7188481febc0f3180bc8f31973d336b2a6e25802acd4fed6d905d89c6d4d7d8080fb12741f9c5ab7e6","name":"node_1e0a46ff50fb6d9a2c218a851763ff86c42e4d61dddffb7188481febc0f3180bc8f31973d336b2a6e25802acd4fed6d905d89c6d4d7d8080fb12741f9c5ab7e6","enode":"enode://1e0a46ff50fb6d9a2c218a851763ff86c42e4d61dddffb7188481febc0f3180bc8f31973d336b2a6e25802acd4fed6d905d89c6d4d7d8080fb12741f9c5ab7e6@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"MR/IS86QsbwdGYPHjkWx6CpwPNt8++VNUem8QM/gQQM=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 311fc8\npopulation: 15 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 aec5 d386 | 68 8bf5 (0) 8c5b (0) 8fe2 (0) 8ec6 (0)\n001 6 6c1f 6cf1 7c76 7e65 | 37 5d6d (0) 5b36 (0) 57df (0) 500f (0)\n002 3 1ab1 1ea8 11a6 | 11 0047 (0) 06db (0) 059a (0) 0400 (0)\n003 1 2a2b | 6 2650 (0) 237b (0) 2fee (0) 2dc2 (0)\n004 1 3e4f | 3 3d3a (0) 3f1e (0) 3e4f (0)\n005 0 | 0\n006 0 | 0\n============ DEPTH: 7 ==========================================\n007 1 30a0 | 1 30a0 (0)\n008 0 | 0\n009 1 314e | 1 314e (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"1e0a46ff50fb6d9a2c218a851763ff86c42e4d61dddffb7188481febc0f3180bc8f31973d336b2a6e25802acd4fed6d905d89c6d4d7d8080fb12741f9c5ab7e6","private_key":"2b4bd5ee9da5de0932418460699900ba0e40139dc910b087c586210e52816b77","name":"node_1e0a46ff50fb6d9a2c218a851763ff86c42e4d61dddffb7188481febc0f3180bc8f31973d336b2a6e25802acd4fed6d905d89c6d4d7d8080fb12741f9c5ab7e6","services":["streamer"],"enable_msg_events":true,"port":63112},"up":true}},{"node":{"info":{"id":"b2bea653b6ec9629c6f934be72fccf30acf836698e21e81dd8085f070ba8259ba43eee43c342738a4b782f5fbddd44caa28f56dffc08237ca7567c965ac3beca","name":"node_b2bea653b6ec9629c6f934be72fccf30acf836698e21e81dd8085f070ba8259ba43eee43c342738a4b782f5fbddd44caa28f56dffc08237ca7567c965ac3beca","enode":"enode://b2bea653b6ec9629c6f934be72fccf30acf836698e21e81dd8085f070ba8259ba43eee43c342738a4b782f5fbddd44caa28f56dffc08237ca7567c965ac3beca@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"Pk+6tlDL1Tk4P34mEowKqncPEsSh+kTVU96d2gc/DLI=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 3e4fba\npopulation: 17 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 aec5 811d d382 | 68 8bf5 (0) 8fe2 (0) 8ec6 (0) 8e31 (0)\n001 2 4827 6c1f | 37 5b36 (0) 5d6d (0) 500f (0) 53ea (0)\n002 2 11a6 1ea8 | 11 0047 (0) 06db (0) 0400 (0) 059a (0)\n003 5 2a2b 2aef 2fee 2dc2 | 6 237b (0) 2650 (0) 2dc2 (0) 2fee (0)\n004 3 30a0 314e 311f | 3 30a0 (0) 314e (0) 311f (0)\n005 0 | 0\n============ DEPTH: 6 ==========================================\n006 1 3d3a | 1 3d3a (0)\n007 1 3f1e | 1 3f1e (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"b2bea653b6ec9629c6f934be72fccf30acf836698e21e81dd8085f070ba8259ba43eee43c342738a4b782f5fbddd44caa28f56dffc08237ca7567c965ac3beca","private_key":"dd2b5c2e466c7276ff4c6c1a641ac204a34ddcb145523ab175701ba31faf44de","name":"node_b2bea653b6ec9629c6f934be72fccf30acf836698e21e81dd8085f070ba8259ba43eee43c342738a4b782f5fbddd44caa28f56dffc08237ca7567c965ac3beca","services":["streamer"],"enable_msg_events":true,"port":63113},"up":true}},{"node":{"info":{"id":"5771bef7f50439f9b81d2a7bf7060b1ad4b38675d8f6abbac3cc4c215fb0cb5dd07f6873545b42218337556925566025476e2915b7b98e662a3dcd28bebf0eb4","name":"node_5771bef7f50439f9b81d2a7bf7060b1ad4b38675d8f6abbac3cc4c215fb0cb5dd07f6873545b42218337556925566025476e2915b7b98e662a3dcd28bebf0eb4","enode":"enode://5771bef7f50439f9b81d2a7bf7060b1ad4b38675d8f6abbac3cc4c215fb0cb5dd07f6873545b42218337556925566025476e2915b7b98e662a3dcd28bebf0eb4@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"bB+Cw6e8MnTP2scQyuxPyBTJ9aZ5dnRFdBTdlL5Xeps=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 6c1f82\npopulation: 13 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 aec5 8c5b | 68 b1bf (0) b220 (0) bf7b (0) b9e5 (0)\n001 2 311f 3e4f | 23 0047 (0) 06db (0) 0400 (0) 059a (0)\n002 1 4827 | 16 5b36 (0) 5d6d (0) 500f (0) 53ea (0)\n003 2 7e65 7f62 | 9 740b (0) 7628 (0) 7692 (0) 78bf (0)\n004 1 6120 | 5 6640 (0) 6632 (0) 6099 (0) 60ad (0)\n005 3 6838 6ac7 6a57 | 4 6838 (0) 6aef (0) 6ac7 (0) 6a57 (0)\n============ DEPTH: 6 ==========================================\n006 1 6e83 | 1 6e83 (0)\n007 0 | 0\n008 1 6cf1 | 1 6cf1 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"5771bef7f50439f9b81d2a7bf7060b1ad4b38675d8f6abbac3cc4c215fb0cb5dd07f6873545b42218337556925566025476e2915b7b98e662a3dcd28bebf0eb4","private_key":"17f5b5341d575c1cfe673efd9957ca29a50fa23c028c5f5f7561b23e7dc92e04","name":"node_5771bef7f50439f9b81d2a7bf7060b1ad4b38675d8f6abbac3cc4c215fb0cb5dd07f6873545b42218337556925566025476e2915b7b98e662a3dcd28bebf0eb4","services":["streamer"],"enable_msg_events":true,"port":63114},"up":true}},{"node":{"info":{"id":"0e8c1a6b70524c4fdc492c74348bac4ccd5d140bd41352607e8cfba45561afb1e6e12f3e2fcf03c1778c9ae5ae19cb9218ee2d613983768f54e3f54e69bb6600","name":"node_0e8c1a6b70524c4fdc492c74348bac4ccd5d140bd41352607e8cfba45561afb1e6e12f3e2fcf03c1778c9ae5ae19cb9218ee2d613983768f54e3f54e69bb6600","enode":"enode://0e8c1a6b70524c4fdc492c74348bac4ccd5d140bd41352607e8cfba45561afb1e6e12f3e2fcf03c1778c9ae5ae19cb9218ee2d613983768f54e3f54e69bb6600@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"jFuVvxdD4tipchDFtktnMvNhXENp+jpS5Cb5PhaK4W8=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 8c5b95\npopulation: 17 (125), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 6c1f | 58 237b (0) 2650 (0) 2fee (0) 2dc2 (0)\n001 3 c358 d386 d382 | 36 ec3b (0) ebf9 (0) ea94 (0) ea51 (0)\n002 7 b9e5 ac23 a8ba aa19 | 12 b1bf (0) b220 (0) bf7b (0) b9e5 (0)\n003 1 9386 | 10 981b (0) 9cbc (0) 9f97 (0) 97a5 (0)\n004 1 811d | 5 87e0 (0) 8230 (0) 83bc (0) 8311 (0)\n005 1 8bf5 | 1 8bf5 (0)\n============ DEPTH: 6 ==========================================\n006 3 8e31 8ec6 8fe2 | 3 8e31 (0) 8ec6 (0) 8fe2 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"0e8c1a6b70524c4fdc492c74348bac4ccd5d140bd41352607e8cfba45561afb1e6e12f3e2fcf03c1778c9ae5ae19cb9218ee2d613983768f54e3f54e69bb6600","private_key":"eeb9367b7cabbd3e4076edb5fb97cc2fba7445cf37f523685f2b24e617d718c3","name":"node_0e8c1a6b70524c4fdc492c74348bac4ccd5d140bd41352607e8cfba45561afb1e6e12f3e2fcf03c1778c9ae5ae19cb9218ee2d613983768f54e3f54e69bb6600","services":["streamer"],"enable_msg_events":true,"port":63115},"up":true}},{"node":{"info":{"id":"d71c50805f284ed3a759e2e81f220fbc73d6d0a7a261b4c9e7878c3da143cfc07afa83e1635b6a45530f71a60b9f17c485a2fd6617c6c2bff82bacc71c208087","name":"node_d71c50805f284ed3a759e2e81f220fbc73d6d0a7a261b4c9e7878c3da143cfc07afa83e1635b6a45530f71a60b9f17c485a2fd6617c6c2bff82bacc71c208087","enode":"enode://d71c50805f284ed3a759e2e81f220fbc73d6d0a7a261b4c9e7878c3da143cfc07afa83e1635b6a45530f71a60b9f17c485a2fd6617c6c2bff82bacc71c208087@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"04LjbbfxMYDMp7Fp6FEcm5ILtIGjQNimHdnklppWBbY=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: d382e3\npopulation: 16 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 3e4f | 60 237b (0) 2650 (0) 2dc2 (0) 2fee (0)\n001 2 96b7 8c5b | 32 b1bf (0) b220 (0) bf7b (0) b9e5 (0)\n002 3 ec3b e39e f80e | 19 ec3b (0) ebf9 (0) ea94 (0) ea51 (0)\n003 3 c7fd c243 c358 | 5 ca97 (0) cac9 (0) c7fd (0) c243 (0)\n004 2 db59 d916 | 5 dc2a (0) db59 (0) d87f (0) d80b (0)\n005 3 d7f9 d68e d552 | 4 d68e (0) d7f9 (0) d798 (0) d552 (0)\n============ DEPTH: 6 ==========================================\n006 1 d192 | 1 d192 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 1 d386 | 1 d386 (0)\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"d71c50805f284ed3a759e2e81f220fbc73d6d0a7a261b4c9e7878c3da143cfc07afa83e1635b6a45530f71a60b9f17c485a2fd6617c6c2bff82bacc71c208087","private_key":"a9a6414dc37916ed5794a644a51d6cc1c23c27d707b2dfb9957f9ee28af64e60","name":"node_d71c50805f284ed3a759e2e81f220fbc73d6d0a7a261b4c9e7878c3da143cfc07afa83e1635b6a45530f71a60b9f17c485a2fd6617c6c2bff82bacc71c208087","services":["streamer"],"enable_msg_events":true,"port":63116},"up":true}},{"node":{"info":{"id":"06472c89def07fa73188d253cf1acddc2be984842f3a234edb3db95449ba74928ab1395eca1b8978987769863afffb488fc27c9ac723aa24837b66c12f38d735","name":"node_06472c89def07fa73188d253cf1acddc2be984842f3a234edb3db95449ba74928ab1395eca1b8978987769863afffb488fc27c9ac723aa24837b66c12f38d735","enode":"enode://06472c89def07fa73188d253cf1acddc2be984842f3a234edb3db95449ba74928ab1395eca1b8978987769863afffb488fc27c9ac723aa24837b66c12f38d735@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"+A4c4jhpx9pEU/BlIfoyBjIFcZTJ+bPc3Xd8wfBmA+s=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: f80e1c\npopulation: 12 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 6632 | 60 237b (0) 2650 (0) 2dc2 (0) 2fee (0)\n001 1 8e31 | 32 8bf5 (0) 8c5b (0) 8fe2 (0) 8ec6 (0)\n002 1 d382 | 17 ca97 (0) cac9 (0) c7fd (0) c243 (0)\n003 3 ea51 e3c3 e39e | 9 ec3b (0) ebf9 (0) ea94 (0) ea51 (0)\n004 1 f07c | 4 f07c (0) f2b8 (0) f29f (0) f3a1 (0)\n005 1 feb3 | 1 feb3 (0)\n006 2 fba8 fa62 | 2 fba8 (0) fa62 (0)\n============ DEPTH: 7 ==========================================\n007 1 f995 | 1 f995 (0)\n008 0 | 0\n009 0 | 0\n010 1 f836 | 1 f836 (0)\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"06472c89def07fa73188d253cf1acddc2be984842f3a234edb3db95449ba74928ab1395eca1b8978987769863afffb488fc27c9ac723aa24837b66c12f38d735","private_key":"29c714e8c1983b179cad17ffaa617cfbdd50272b496803b4a602afdb05d78117","name":"node_06472c89def07fa73188d253cf1acddc2be984842f3a234edb3db95449ba74928ab1395eca1b8978987769863afffb488fc27c9ac723aa24837b66c12f38d735","services":["streamer"],"enable_msg_events":true,"port":63117},"up":true}},{"node":{"info":{"id":"eb097186ff58d96a7ead7a7f9c05a44075d84537bd4fd3f82857bf2c45bee1c6dece434a7707cde69e96f02366859cab4c991fdb7615e113a868d4b9c7524a45","name":"node_eb097186ff58d96a7ead7a7f9c05a44075d84537bd4fd3f82857bf2c45bee1c6dece434a7707cde69e96f02366859cab4c991fdb7615e113a868d4b9c7524a45","enode":"enode://eb097186ff58d96a7ead7a7f9c05a44075d84537bd4fd3f82857bf2c45bee1c6dece434a7707cde69e96f02366859cab4c991fdb7615e113a868d4b9c7524a45@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"ZjKosj1C38VaED1iWjZE8AZ6uq5VTrdaeLEJSteyTBY=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 6632a8\npopulation: 18 (115), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 f80e a60b | 57 ca97 (0) cac9 (0) c7fd (0) c243 (0)\n001 4 1f2a 11a6 06db 059a | 23 3d3a (0) 3f1e (0) 3e4f (0) 30a0 (0)\n002 3 4236 4827 48a1 | 15 5d6d (0) 5b36 (0) 500f (0) 53ea (0)\n003 2 7bcf 7f62 | 9 7628 (0) 7692 (0) 740b (0) 78bf (0)\n004 3 6838 6ac7 6aef | 7 6e83 (0) 6cf1 (0) 6c1f (0) 6838 (0)\n============ DEPTH: 5 ==========================================\n005 3 6120 6099 60ad | 3 6120 (0) 6099 (0) 60ad (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 1 6640 | 1 6640 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"eb097186ff58d96a7ead7a7f9c05a44075d84537bd4fd3f82857bf2c45bee1c6dece434a7707cde69e96f02366859cab4c991fdb7615e113a868d4b9c7524a45","private_key":"f00cf99cd4b64e4242b7c878a4ce70044f1fe91966dd723b940e3a312f1b9f63","name":"node_eb097186ff58d96a7ead7a7f9c05a44075d84537bd4fd3f82857bf2c45bee1c6dece434a7707cde69e96f02366859cab4c991fdb7615e113a868d4b9c7524a45","services":["streamer"],"enable_msg_events":true,"port":63118},"up":true}},{"node":{"info":{"id":"57bfbde13c71e035c96513870aa8215198f78806e7cdb01c54fbdb392de2c40386d768d6fdc4c68534a67e531867ca74d8ca4dcf34ff7f7f64ec35edee3e5f68","name":"node_57bfbde13c71e035c96513870aa8215198f78806e7cdb01c54fbdb392de2c40386d768d6fdc4c68534a67e531867ca74d8ca4dcf34ff7f7f64ec35edee3e5f68","enode":"enode://57bfbde13c71e035c96513870aa8215198f78806e7cdb01c54fbdb392de2c40386d768d6fdc4c68534a67e531867ca74d8ca4dcf34ff7f7f64ec35edee3e5f68@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"pgtF26ucHeGHg/7Z7tivbauvvDP9xbP+8e9FabxscNk=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: a60b45\npopulation: 14 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 059a 4259 6632 | 60 30a0 (0) 311f (0) 314e (0) 3d3a (0)\n001 2 e39e c7fd | 36 ca97 (0) cac9 (0) c7fd (0) c243 (0)\n002 2 92e2 8c5b | 20 8bf5 (0) 8c5b (0) 8fe2 (0) 8ec6 (0)\n003 2 b1bf b9e5 | 4 b1bf (0) b220 (0) bf7b (0) b9e5 (0)\n004 2 ac23 aa19 | 4 aec5 (0) ac23 (0) a8ba (0) aa19 (0)\n============ DEPTH: 5 ==========================================\n005 3 a250 a3fc a12e | 3 a250 (0) a3fc (0) a12e (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"57bfbde13c71e035c96513870aa8215198f78806e7cdb01c54fbdb392de2c40386d768d6fdc4c68534a67e531867ca74d8ca4dcf34ff7f7f64ec35edee3e5f68","private_key":"d089b29e9ea18a2cf17256e0e06c907164f712564fbebce476b40f67e39bcc73","name":"node_57bfbde13c71e035c96513870aa8215198f78806e7cdb01c54fbdb392de2c40386d768d6fdc4c68534a67e531867ca74d8ca4dcf34ff7f7f64ec35edee3e5f68","services":["streamer"],"enable_msg_events":true,"port":63119},"up":true}},{"node":{"info":{"id":"5b4de68680c5d1a75cccd5e7a82319c031f5d61d79cbb6532e1254ab81c833c3fafb54390cca7a770e84690c490fcba90482b35321870f8506335a2f57cc052e","name":"node_5b4de68680c5d1a75cccd5e7a82319c031f5d61d79cbb6532e1254ab81c833c3fafb54390cca7a770e84690c490fcba90482b35321870f8506335a2f57cc052e","enode":"enode://5b4de68680c5d1a75cccd5e7a82319c031f5d61d79cbb6532e1254ab81c833c3fafb54390cca7a770e84690c490fcba90482b35321870f8506335a2f57cc052e@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"BZotDl2ywCBMELZu8EusyW1kRTBz7+7oG6fjDUMGGmE=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 059a2d\npopulation: 18 (126), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 a60b e39e | 67 981b (0) 9cbc (0) 9f97 (0) 954a (0)\n001 6 4454 436c 6aef 60ad | 37 5d6d (0) 5b36 (0) 57df (0) 500f (0)\n002 3 2650 237b 2dc2 | 12 3e4f (0) 3f1e (0) 3d3a (0) 30a0 (0)\n003 4 18f6 1ea8 1f2a 11a6 | 7 1385 (0) 11a6 (0) 1ab1 (0) 18f6 (0)\n004 0 | 0\n005 1 0047 | 1 0047 (0)\n============ DEPTH: 6 ==========================================\n006 1 06db | 1 06db (0)\n007 1 0400 | 1 0400 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"5b4de68680c5d1a75cccd5e7a82319c031f5d61d79cbb6532e1254ab81c833c3fafb54390cca7a770e84690c490fcba90482b35321870f8506335a2f57cc052e","private_key":"219f34180d582584fdc64b9b7712bb15e490bcb2eaa2f4d2847f838196c6afe0","name":"node_5b4de68680c5d1a75cccd5e7a82319c031f5d61d79cbb6532e1254ab81c833c3fafb54390cca7a770e84690c490fcba90482b35321870f8506335a2f57cc052e","services":["streamer"],"enable_msg_events":true,"port":63120},"up":true}},{"node":{"info":{"id":"cd0e9a45b45f9a67417fcde29d9f92c45ca4db46eebbfe47dcf6999e23e549e4205f42ada8e3fcd00e2fb5f832bb92a27a59b43c4a5909148d81399c2e8ce492","name":"node_cd0e9a45b45f9a67417fcde29d9f92c45ca4db46eebbfe47dcf6999e23e549e4205f42ada8e3fcd00e2fb5f832bb92a27a59b43c4a5909148d81399c2e8ce492","enode":"enode://cd0e9a45b45f9a67417fcde29d9f92c45ca4db46eebbfe47dcf6999e23e549e4205f42ada8e3fcd00e2fb5f832bb92a27a59b43c4a5909148d81399c2e8ce492@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"456Aksl7U9vq9cpz2Vxx6OQaKQaqo3f+DBsjdSyMdCM=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: e39e80\npopulation: 12 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 059a | 60 5d6d (0) 5b36 (0) 57df (0) 500f (0)\n001 2 a60b aa19 | 32 981b (0) 9f97 (0) 9cbc (0) 954a (0)\n002 2 d382 d552 | 17 c7fd (0) c243 (0) c358 (0) cac9 (0)\n003 1 f80e | 10 f07c (0) f2b8 (0) f29f (0) f3a1 (0)\n004 2 ec3b ea51 | 4 ebf9 (0) ea94 (0) ea51 (0) ec3b (0)\n005 2 e5cd e425 | 2 e5cd (0) e425 (0)\n============ DEPTH: 6 ==========================================\n006 1 e0ac | 1 e0ac (0)\n007 0 | 0\n008 0 | 0\n009 1 e3c3 | 1 e3c3 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"cd0e9a45b45f9a67417fcde29d9f92c45ca4db46eebbfe47dcf6999e23e549e4205f42ada8e3fcd00e2fb5f832bb92a27a59b43c4a5909148d81399c2e8ce492","private_key":"223faa782246247751eeb3191f8823874455005721e6738d5f5b5b631cda858b","name":"node_cd0e9a45b45f9a67417fcde29d9f92c45ca4db46eebbfe47dcf6999e23e549e4205f42ada8e3fcd00e2fb5f832bb92a27a59b43c4a5909148d81399c2e8ce492","services":["streamer"],"enable_msg_events":true,"port":63121},"up":true}},{"node":{"info":{"id":"5d917ffc9d70a38670941ce206aa7ea1b9ea65c1d783f14ebdf7c7afa6ca8b237112aaa9b1a3f757132093a604ef378280c5bdef02c2688049a91a412c399bfe","name":"node_5d917ffc9d70a38670941ce206aa7ea1b9ea65c1d783f14ebdf7c7afa6ca8b237112aaa9b1a3f757132093a604ef378280c5bdef02c2688049a91a412c399bfe","enode":"enode://5d917ffc9d70a38670941ce206aa7ea1b9ea65c1d783f14ebdf7c7afa6ca8b237112aaa9b1a3f757132093a604ef378280c5bdef02c2688049a91a412c399bfe@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"qhn7NWWiZ3gosThPSD4+t+oRKUDSHQqqexYTnHU8adc=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: aa19fb\npopulation: 12 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 6640 | 60 1385 (0) 11a6 (0) 1ab1 (0) 1943 (0)\n001 1 e39e | 36 ca97 (0) cac9 (0) c7fd (0) c243 (0)\n002 2 92e2 8c5b | 20 8bf5 (0) 8c5b (0) 8fe2 (0) 8ec6 (0)\n003 3 b220 b1bf b9e5 | 4 b220 (0) b1bf (0) bf7b (0) b9e5 (0)\n004 2 a3fc a60b | 4 a60b (0) a12e (0) a250 (0) a3fc (0)\n============ DEPTH: 5 ==========================================\n005 2 ac23 aec5 | 2 aec5 (0) ac23 (0)\n006 1 a8ba | 1 a8ba (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"5d917ffc9d70a38670941ce206aa7ea1b9ea65c1d783f14ebdf7c7afa6ca8b237112aaa9b1a3f757132093a604ef378280c5bdef02c2688049a91a412c399bfe","private_key":"2e3b422e1762ce5c22bc9cd6fa78cfb62f3ada7732d7e0b16d91ecc5f5ab9047","name":"node_5d917ffc9d70a38670941ce206aa7ea1b9ea65c1d783f14ebdf7c7afa6ca8b237112aaa9b1a3f757132093a604ef378280c5bdef02c2688049a91a412c399bfe","services":["streamer"],"enable_msg_events":true,"port":63122},"up":true}},{"node":{"info":{"id":"26cf4ea45b9a76daab82a57126f9c6f8726d2eb973e205ab4ab69c8b8be11a32a7eb5c3807e952cd428ce5ddd88f143d4fc9ff8c3de3d159855675afce715615","name":"node_26cf4ea45b9a76daab82a57126f9c6f8726d2eb973e205ab4ab69c8b8be11a32a7eb5c3807e952cd428ce5ddd88f143d4fc9ff8c3de3d159855675afce715615","enode":"enode://26cf4ea45b9a76daab82a57126f9c6f8726d2eb973e205ab4ab69c8b8be11a32a7eb5c3807e952cd428ce5ddd88f143d4fc9ff8c3de3d159855675afce715615@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"ZkCoNDuBA5lSVUXuFUWlDjx2VI93bIPVVGUHHLVaALE=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 6640a8\npopulation: 15 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 aa19 | 68 ca97 (0) cac9 (0) c7fd (0) c243 (0)\n001 3 06db 2650 237b | 23 1385 (0) 11a6 (0) 1ab1 (0) 18f6 (0)\n002 5 4259 4236 436c 4454 | 16 5d6d (0) 5b36 (0) 57df (0) 53ea (0)\n003 1 7bcf | 9 740b (0) 7692 (0) 7628 (0) 7c76 (0)\n004 1 6aef | 7 6c1f (0) 6cf1 (0) 6e83 (0) 6838 (0)\n============ DEPTH: 5 ==========================================\n005 3 6120 6099 60ad | 3 6120 (0) 6099 (0) 60ad (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 1 6632 | 1 6632 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"26cf4ea45b9a76daab82a57126f9c6f8726d2eb973e205ab4ab69c8b8be11a32a7eb5c3807e952cd428ce5ddd88f143d4fc9ff8c3de3d159855675afce715615","private_key":"a3f487830e9fd87b5b404bc91d0f49d866cddfa869d32c08853273b9a2eaea7b","name":"node_26cf4ea45b9a76daab82a57126f9c6f8726d2eb973e205ab4ab69c8b8be11a32a7eb5c3807e952cd428ce5ddd88f143d4fc9ff8c3de3d159855675afce715615","services":["streamer"],"enable_msg_events":true,"port":63123},"up":true}},{"node":{"info":{"id":"20f171ab01a814a2856a6cbe7929269f18f6329914289515e2cb9d078ac14ebdae457789dd638c6415b062799114570f556147d4bf9ac850f00b6d0762765ac1","name":"node_20f171ab01a814a2856a6cbe7929269f18f6329914289515e2cb9d078ac14ebdae457789dd638c6415b062799114570f556147d4bf9ac850f00b6d0762765ac1","enode":"enode://20f171ab01a814a2856a6cbe7929269f18f6329914289515e2cb9d078ac14ebdae457789dd638c6415b062799114570f556147d4bf9ac850f00b6d0762765ac1@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"I3tUqn7wd5cvxl+yIs5w3wEp+MjU01UF/L3Cgbt9KM4=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 237b54\npopulation: 16 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 d552 | 68 8bf5 (0) 8c5b (0) 8fe2 (0) 8ec6 (0)\n001 4 48a1 7bcf 60ad 6640 | 37 57df (0) 53ea (0) 500f (0) 5b36 (0)\n002 5 1943 1ab1 1f2a 059a | 11 11a6 (0) 1385 (0) 1ab1 (0) 18f6 (0)\n003 1 30a0 | 6 3d3a (0) 3e4f (0) 3f1e (0) 311f (0)\n============ DEPTH: 4 ==========================================\n004 4 2fee 2dc2 2a2b 2aef | 4 2aef (0) 2a2b (0) 2dc2 (0) 2fee (0)\n005 1 2650 | 1 2650 (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"20f171ab01a814a2856a6cbe7929269f18f6329914289515e2cb9d078ac14ebdae457789dd638c6415b062799114570f556147d4bf9ac850f00b6d0762765ac1","private_key":"9a3fe8b50af54e2b6ea84f05b832426f911dd557e1e874bb291075981a46baa7","name":"node_20f171ab01a814a2856a6cbe7929269f18f6329914289515e2cb9d078ac14ebdae457789dd638c6415b062799114570f556147d4bf9ac850f00b6d0762765ac1","services":["streamer"],"enable_msg_events":true,"port":63124},"up":true}},{"node":{"info":{"id":"f0b2f1e8d46be656109adb18c60677ac9eb8fce7f42e15d9dbb25f94b4e426064780eaf32b79954b9bb72ea89953175da8de35380aaba18931cca374a7de2b11","name":"node_f0b2f1e8d46be656109adb18c60677ac9eb8fce7f42e15d9dbb25f94b4e426064780eaf32b79954b9bb72ea89953175da8de35380aaba18931cca374a7de2b11","enode":"enode://f0b2f1e8d46be656109adb18c60677ac9eb8fce7f42e15d9dbb25f94b4e426064780eaf32b79954b9bb72ea89953175da8de35380aaba18931cca374a7de2b11@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"1VIT09wnVCp4BHJWSkqMHOR2aOBXEL4Xi68yOMqIhrY=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: d55213\npopulation: 20 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 237b 1f2a | 60 740b (0) 7628 (0) 7692 (0) 7c76 (0)\n001 3 96b7 aec5 a8ba | 32 8bf5 (0) 8c5b (0) 8fe2 (0) 8ec6 (0)\n002 5 f2b8 fba8 ec3b ebf9 | 19 f2b8 (0) f29f (0) f3a1 (0) f07c (0)\n003 3 c7fd c243 c358 | 5 ca97 (0) cac9 (0) c7fd (0) c243 (0)\n004 2 dc2a d916 | 5 dc2a (0) db59 (0) d87f (0) d80b (0)\n005 2 d386 d382 | 3 d192 (0) d386 (0) d382 (0)\n============ DEPTH: 6 ==========================================\n006 3 d7f9 d798 d68e | 3 d68e (0) d7f9 (0) d798 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"f0b2f1e8d46be656109adb18c60677ac9eb8fce7f42e15d9dbb25f94b4e426064780eaf32b79954b9bb72ea89953175da8de35380aaba18931cca374a7de2b11","private_key":"8e83e239128a2ef402e58ceaffa0fe2d59d913588d12536ba4e7a88bac14ab5a","name":"node_f0b2f1e8d46be656109adb18c60677ac9eb8fce7f42e15d9dbb25f94b4e426064780eaf32b79954b9bb72ea89953175da8de35380aaba18931cca374a7de2b11","services":["streamer"],"enable_msg_events":true,"port":63125},"up":true}},{"node":{"info":{"id":"a6ca1d5340f2d7021f541c81cf9aea519675462c8443bb6ddd93919962561b8f5a8431c3ec7e7e7d46c600b653e9a0638d2bb07cf4e29516bf9c4d3653f451b0","name":"node_a6ca1d5340f2d7021f541c81cf9aea519675462c8443bb6ddd93919962561b8f5a8431c3ec7e7e7d46c600b653e9a0638d2bb07cf4e29516bf9c4d3653f451b0","enode":"enode://a6ca1d5340f2d7021f541c81cf9aea519675462c8443bb6ddd93919962561b8f5a8431c3ec7e7e7d46c600b653e9a0638d2bb07cf4e29516bf9c4d3653f451b0@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"HyoWKk54yJNe0X7uIGqFEu834Sa7etn/dE97RsSxmu4=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 1f2a16\npopulation: 20 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 d552 | 68 8bf5 (0) 8c5b (0) 8fe2 (0) 8ec6 (0)\n001 8 7bcf 6632 60ad 6099 | 37 6120 (0) 6099 (0) 60ad (0) 6632 (0)\n002 2 2dc2 237b | 12 30a0 (0) 311f (0) 314e (0) 3d3a (0)\n003 3 0400 059a 06db | 4 0047 (0) 0400 (0) 059a (0) 06db (0)\n004 2 11a6 1385 | 2 11a6 (0) 1385 (0)\n============ DEPTH: 5 ==========================================\n005 3 1ab1 1943 18f6 | 3 1ab1 (0) 1943 (0) 18f6 (0)\n006 0 | 0\n007 1 1ea8 | 1 1ea8 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"a6ca1d5340f2d7021f541c81cf9aea519675462c8443bb6ddd93919962561b8f5a8431c3ec7e7e7d46c600b653e9a0638d2bb07cf4e29516bf9c4d3653f451b0","private_key":"81b194e85dff3ff43272bbf73e58a6dac8a9e3ad125f7ba3e71cb5de5341a975","name":"node_a6ca1d5340f2d7021f541c81cf9aea519675462c8443bb6ddd93919962561b8f5a8431c3ec7e7e7d46c600b653e9a0638d2bb07cf4e29516bf9c4d3653f451b0","services":["streamer"],"enable_msg_events":true,"port":63126},"up":true}},{"node":{"info":{"id":"d8cfadac10473b31a4560c711636a05615f13054388065344642ff1d04246fb62eafeec06805264eafead111ed8134e11a8e21f42a0eb950c23b142e627bd8cb","name":"node_d8cfadac10473b31a4560c711636a05615f13054388065344642ff1d04246fb62eafeec06805264eafead111ed8134e11a8e21f42a0eb950c23b142e627bd8cb","enode":"enode://d8cfadac10473b31a4560c711636a05615f13054388065344642ff1d04246fb62eafeec06805264eafead111ed8134e11a8e21f42a0eb950c23b142e627bd8cb@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"RFQKFS+fySTxD+/AEwWdmtIo50+SGmeGbvKHWPGIYyA=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 44540a\npopulation: 17 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 c358 | 68 8bf5 (0) 8c5b (0) 8fe2 (0) 8ec6 (0)\n001 2 059a 1f2a | 23 3e4f (0) 3f1e (0) 3d3a (0) 311f (0)\n002 3 6838 6640 7bcf | 21 6120 (0) 6099 (0) 60ad (0) 6632 (0)\n003 2 53ea 500f | 5 5b36 (0) 5d6d (0) 57df (0) 53ea (0)\n004 2 4ae6 48a1 | 3 4ae6 (0) 4827 (0) 48a1 (0)\n============ DEPTH: 5 ==========================================\n005 6 4087 4124 4309 436c | 6 4124 (0) 4087 (0) 4309 (0) 436c (0)\n006 1 4778 | 1 4778 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"d8cfadac10473b31a4560c711636a05615f13054388065344642ff1d04246fb62eafeec06805264eafead111ed8134e11a8e21f42a0eb950c23b142e627bd8cb","private_key":"b4ec9b24f6a962422bb63d20e415a5dc2f85168297e8abed3cb20e3fc0d70e25","name":"node_d8cfadac10473b31a4560c711636a05615f13054388065344642ff1d04246fb62eafeec06805264eafead111ed8134e11a8e21f42a0eb950c23b142e627bd8cb","services":["streamer"],"enable_msg_events":true,"port":63127},"up":true}},{"node":{"info":{"id":"49eb706cd7e95ad78502a508487d88b818861d94334aee36b2acef5c25cfff5c0efc2df9dc5dbb18acd4003d5cc0c843d3b40363adf2f62a14c04d814268fdee","name":"node_49eb706cd7e95ad78502a508487d88b818861d94334aee36b2acef5c25cfff5c0efc2df9dc5dbb18acd4003d5cc0c843d3b40363adf2f62a14c04d814268fdee","enode":"enode://49eb706cd7e95ad78502a508487d88b818861d94334aee36b2acef5c25cfff5c0efc2df9dc5dbb18acd4003d5cc0c843d3b40363adf2f62a14c04d814268fdee@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"w1iT6jWrdkAF/YHuENGpqz82HgRKpT4o7mTv/Kko0J0=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: c35893\npopulation: 14 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 4454 7bcf | 60 3e4f (0) 3f1e (0) 3d3a (0) 311f (0)\n001 1 8c5b | 32 8bf5 (0) 8c5b (0) 8fe2 (0) 8ec6 (0)\n002 1 ec3b | 19 f2b8 (0) f29f (0) f3a1 (0) f07c (0)\n003 6 d916 d386 d382 d798 | 12 dc2a (0) db59 (0) d87f (0) d80b (0)\n004 2 ca97 cac9 | 2 ca97 (0) cac9 (0)\n============ DEPTH: 5 ==========================================\n005 1 c7fd | 1 c7fd (0)\n006 0 | 0\n007 1 c243 | 1 c243 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"49eb706cd7e95ad78502a508487d88b818861d94334aee36b2acef5c25cfff5c0efc2df9dc5dbb18acd4003d5cc0c843d3b40363adf2f62a14c04d814268fdee","private_key":"cd0667c4d17b56321858cceaca611f1c46758fa276d3d991f3a9fbb0c686af3a","name":"node_49eb706cd7e95ad78502a508487d88b818861d94334aee36b2acef5c25cfff5c0efc2df9dc5dbb18acd4003d5cc0c843d3b40363adf2f62a14c04d814268fdee","services":["streamer"],"enable_msg_events":true,"port":63128},"up":true}},{"node":{"info":{"id":"c93cb2df7ba6de8009872f5f7565891040d42e3b193ef1cdb321a0c167cc8fb8138900982bb8f6918fbaefac6e02dda01ee40f7a6beba1990dd44abe03cc3d01","name":"node_c93cb2df7ba6de8009872f5f7565891040d42e3b193ef1cdb321a0c167cc8fb8138900982bb8f6918fbaefac6e02dda01ee40f7a6beba1990dd44abe03cc3d01","enode":"enode://c93cb2df7ba6de8009872f5f7565891040d42e3b193ef1cdb321a0c167cc8fb8138900982bb8f6918fbaefac6e02dda01ee40f7a6beba1990dd44abe03cc3d01@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"e8/JKF9qLODTw8xEVcAmoA6W7WNjAW4J7WLsA6LJ9oE=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 7bcfc9\npopulation: 22 (112), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 bf7b c358 | 54 8bf5 (0) 8c5b (0) 8fe2 (0) 8ec6 (0)\n001 3 237b 1f2a 06db | 23 3d3a (0) 3f1e (0) 3e4f (0) 311f (0)\n002 5 48a1 4778 4454 436c | 16 5b36 (0) 5d6d (0) 57df (0) 53ea (0)\n003 6 6838 6aef 6640 6632 | 11 6120 (0) 6099 (0) 60ad (0) 6632 (0)\n004 1 740b | 3 7628 (0) 7692 (0) 740b (0)\n============ DEPTH: 5 ==========================================\n005 4 7e65 7f5f 7f62 7c76 | 4 7e65 (0) 7f5f (0) 7f62 (0) 7c76 (0)\n006 1 78bf | 1 78bf (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"c93cb2df7ba6de8009872f5f7565891040d42e3b193ef1cdb321a0c167cc8fb8138900982bb8f6918fbaefac6e02dda01ee40f7a6beba1990dd44abe03cc3d01","private_key":"4556340931a4e95daa2043706f516eba3744d2ba4340bcb95358b58c95534090","name":"node_c93cb2df7ba6de8009872f5f7565891040d42e3b193ef1cdb321a0c167cc8fb8138900982bb8f6918fbaefac6e02dda01ee40f7a6beba1990dd44abe03cc3d01","services":["streamer"],"enable_msg_events":true,"port":63129},"up":true}},{"node":{"info":{"id":"3e9c0bbd146d8b1040b4f379eecf802c27c4d0a70e64a9fb2e941a7edab9b00396b0b67fc5c891652743cdba3b342973ed49615b32da54b925954a799240431c","name":"node_3e9c0bbd146d8b1040b4f379eecf802c27c4d0a70e64a9fb2e941a7edab9b00396b0b67fc5c891652743cdba3b342973ed49615b32da54b925954a799240431c","enode":"enode://3e9c0bbd146d8b1040b4f379eecf802c27c4d0a70e64a9fb2e941a7edab9b00396b0b67fc5c891652743cdba3b342973ed49615b32da54b925954a799240431c@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"QllZqAUIBbqpjAXM1kAmHt0/JubPMgW0p50rCGwHAzk=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 425959\npopulation: 26 (124), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 7 a3fc a12e a60b bf7b | 68 8bf5 (0) 8c5b (0) 8fe2 (0) 8ec6 (0)\n001 2 1f2a 06db | 20 311f (0) 314e (0) 30a0 (0) 3d3a (0)\n002 4 6838 6640 60ad 7bcf | 21 6120 (0) 6099 (0) 60ad (0) 6632 (0)\n003 3 5d6d 57df 500f | 5 5b36 (0) 5d6d (0) 57df (0) 53ea (0)\n004 3 4ae6 4827 48a1 | 3 4ae6 (0) 4827 (0) 48a1 (0)\n005 2 4778 4454 | 2 4778 (0) 4454 (0)\n006 2 4087 4124 | 2 4087 (0) 4124 (0)\n============ DEPTH: 7 ==========================================\n007 2 4309 436c | 2 4309 (0) 436c (0)\n008 0 | 0\n009 1 4236 | 1 4236 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"3e9c0bbd146d8b1040b4f379eecf802c27c4d0a70e64a9fb2e941a7edab9b00396b0b67fc5c891652743cdba3b342973ed49615b32da54b925954a799240431c","private_key":"f1b36e9da20cfc2416f02f9194a0522b426be8679b6478118962624b4963af27","name":"node_3e9c0bbd146d8b1040b4f379eecf802c27c4d0a70e64a9fb2e941a7edab9b00396b0b67fc5c891652743cdba3b342973ed49615b32da54b925954a799240431c","services":["streamer"],"enable_msg_events":true,"port":63130},"up":true}},{"node":{"info":{"id":"b38213eaa5b419de787b70073ad8c7c819e48c5f76dec1507b54f1d7cb027211facbe7a170ac50212abe130935e8947d5a19d6b13790114e71cc18357902a889","name":"node_b38213eaa5b419de787b70073ad8c7c819e48c5f76dec1507b54f1d7cb027211facbe7a170ac50212abe130935e8947d5a19d6b13790114e71cc18357902a889","enode":"enode://b38213eaa5b419de787b70073ad8c7c819e48c5f76dec1507b54f1d7cb027211facbe7a170ac50212abe130935e8947d5a19d6b13790114e71cc18357902a889@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"BttuJEITdF4CF1zKEQHnJ5nAkjaDiv/YoCCgXluI4r0=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 06db6e\npopulation: 17 (103), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 f29f d68e d916 a8ba | 53 9f97 (0) 981b (0) 97a5 (0) 96b7 (0)\n001 7 48a1 4259 7bcf 60ad | 28 5b36 (0) 500f (0) 53ea (0) 4454 (0)\n002 2 2dc2 237b | 12 3d3a (0) 3e4f (0) 3f1e (0) 311f (0)\n003 1 1f2a | 7 1385 (0) 11a6 (0) 18f6 (0) 1943 (0)\n004 0 | 0\n005 1 0047 | 1 0047 (0)\n============ DEPTH: 6 ==========================================\n006 2 0400 059a | 2 0400 (0) 059a (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"b38213eaa5b419de787b70073ad8c7c819e48c5f76dec1507b54f1d7cb027211facbe7a170ac50212abe130935e8947d5a19d6b13790114e71cc18357902a889","private_key":"7f720ab5ccb4e3dbca347ff7104c677d8215261910d8e8e2ade703020d566842","name":"node_b38213eaa5b419de787b70073ad8c7c819e48c5f76dec1507b54f1d7cb027211facbe7a170ac50212abe130935e8947d5a19d6b13790114e71cc18357902a889","services":["streamer"],"enable_msg_events":true,"port":63131},"up":true}},{"node":{"info":{"id":"20bdc859d58d8bf419df64fd6ee1d4363c1d5f403af3abef2720d7d3933924672e12e23e5d76b28e0f6726acf58bdc5eb258cba635e327cbd0b564523305da75","name":"node_20bdc859d58d8bf419df64fd6ee1d4363c1d5f403af3abef2720d7d3933924672e12e23e5d76b28e0f6726acf58bdc5eb258cba635e327cbd0b564523305da75","enode":"enode://20bdc859d58d8bf419df64fd6ee1d4363c1d5f403af3abef2720d7d3933924672e12e23e5d76b28e0f6726acf58bdc5eb258cba635e327cbd0b564523305da75@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"au9+lGAubnSrTNtXZo+3UfoggHdR94bQIyhw2grjLP0=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 6aef7e\npopulation: 20 (126), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 7 a3fc a12e bf7b b220 | 67 981b (0) 9f97 (0) 9cbc (0) 954a (0)\n001 3 2650 059a 06db | 23 3d3a (0) 3f1e (0) 3e4f (0) 311f (0)\n002 1 48a1 | 16 57df (0) 53ea (0) 500f (0) 5d6d (0)\n003 1 7bcf | 9 7628 (0) 7692 (0) 740b (0) 7e65 (0)\n004 4 6640 6632 6099 60ad | 5 6632 (0) 6640 (0) 6120 (0) 6099 (0)\n005 1 6e83 | 3 6c1f (0) 6cf1 (0) 6e83 (0)\n006 1 6838 | 1 6838 (0)\n007 0 | 0\n============ DEPTH: 8 ==========================================\n008 1 6a57 | 1 6a57 (0)\n009 0 | 0\n010 1 6ac7 | 1 6ac7 (0)\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"20bdc859d58d8bf419df64fd6ee1d4363c1d5f403af3abef2720d7d3933924672e12e23e5d76b28e0f6726acf58bdc5eb258cba635e327cbd0b564523305da75","private_key":"1a4d1e1d6e198ac61f91d9ccba4212fdd32e9075df2fda41caa11a0a25e694f0","name":"node_20bdc859d58d8bf419df64fd6ee1d4363c1d5f403af3abef2720d7d3933924672e12e23e5d76b28e0f6726acf58bdc5eb258cba635e327cbd0b564523305da75","services":["streamer"],"enable_msg_events":true,"port":63132},"up":true}},{"node":{"info":{"id":"c6d1404873174254c0f15f25804da9a9d90db9c11c5cc895fab613b4deb7820f1733680b4ba9e4b61a664642ed6ee9ff012e13a0619c64ae067be6bab26962c6","name":"node_c6d1404873174254c0f15f25804da9a9d90db9c11c5cc895fab613b4deb7820f1733680b4ba9e4b61a664642ed6ee9ff012e13a0619c64ae067be6bab26962c6","enode":"enode://c6d1404873174254c0f15f25804da9a9d90db9c11c5cc895fab613b4deb7820f1733680b4ba9e4b61a664642ed6ee9ff012e13a0619c64ae067be6bab26962c6@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"YK0EHeuM9y8NKymsyyBKfhg4NHslDhBaxyoKTxfcX0c=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 60ad04\npopulation: 15 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 bf7b 9386 | 68 981b (0) 9f97 (0) 9cbc (0) 97a5 (0)\n001 4 237b 1f2a 059a 06db | 23 3d3a (0) 3e4f (0) 3f1e (0) 311f (0)\n002 2 4259 48a1 | 16 5b36 (0) 5d6d (0) 57df (0) 53ea (0)\n003 1 7bcf | 9 740b (0) 7628 (0) 7692 (0) 7e65 (0)\n004 2 6838 6aef | 7 6c1f (0) 6cf1 (0) 6e83 (0) 6838 (0)\n005 2 6640 6632 | 2 6632 (0) 6640 (0)\n006 0 | 0\n============ DEPTH: 7 ==========================================\n007 1 6120 | 1 6120 (0)\n008 0 | 0\n009 0 | 0\n010 1 6099 | 1 6099 (0)\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"c6d1404873174254c0f15f25804da9a9d90db9c11c5cc895fab613b4deb7820f1733680b4ba9e4b61a664642ed6ee9ff012e13a0619c64ae067be6bab26962c6","private_key":"9fc5b25f84b416e8224c296213b062e1dec7eb7074402a494a23cc1c70ef394b","name":"node_c6d1404873174254c0f15f25804da9a9d90db9c11c5cc895fab613b4deb7820f1733680b4ba9e4b61a664642ed6ee9ff012e13a0619c64ae067be6bab26962c6","services":["streamer"],"enable_msg_events":true,"port":63133},"up":true}},{"node":{"info":{"id":"f04c3ae9fe957a14c249acf3ea2e8407d04d108fc01e75f6d52aaf5073b3450025012d138a75b857473eea4d20e57c99b92bff9041f269d995543d7c67a92ec6","name":"node_f04c3ae9fe957a14c249acf3ea2e8407d04d108fc01e75f6d52aaf5073b3450025012d138a75b857473eea4d20e57c99b92bff9041f269d995543d7c67a92ec6","enode":"enode://f04c3ae9fe957a14c249acf3ea2e8407d04d108fc01e75f6d52aaf5073b3450025012d138a75b857473eea4d20e57c99b92bff9041f269d995543d7c67a92ec6@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"SKGd6gPrgGjoklQHxYKgkT/SQSek92s4NgFxxbCwxUU=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 48a19d\npopulation: 22 (119), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 bf7b 8311 | 60 c358 (0) c243 (0) c7fd (0) ca97 (0)\n001 4 237b 2650 06db 1f2a | 23 0047 (0) 059a (0) 0400 (0) 06db (0)\n002 6 7bcf 6838 6aef 6632 | 21 740b (0) 7628 (0) 7692 (0) 7c76 (0)\n003 2 500f 5b36 | 5 57df (0) 500f (0) 53ea (0) 5d6d (0)\n004 6 4454 4778 4309 436c | 8 4454 (0) 4778 (0) 4087 (0) 4124 (0)\n005 0 | 0\n============ DEPTH: 6 ==========================================\n006 1 4ae6 | 1 4ae6 (0)\n007 0 | 0\n008 1 4827 | 1 4827 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"f04c3ae9fe957a14c249acf3ea2e8407d04d108fc01e75f6d52aaf5073b3450025012d138a75b857473eea4d20e57c99b92bff9041f269d995543d7c67a92ec6","private_key":"43a6ff2fe67bdd16cdd0a4e7ba3eb8188632a796b90d34b477fcb5e0f5ba0b43","name":"node_f04c3ae9fe957a14c249acf3ea2e8407d04d108fc01e75f6d52aaf5073b3450025012d138a75b857473eea4d20e57c99b92bff9041f269d995543d7c67a92ec6","services":["streamer"],"enable_msg_events":true,"port":63134},"up":true}},{"node":{"info":{"id":"8e8de10fb3f53bd3a48455ebfa0a38ea5bd28c607e65506b263ece53a24d2361c2af7d7cd207e45b11bf71a3c33fa325fc8fd40a18b9c73019cce219c757c7ef","name":"node_8e8de10fb3f53bd3a48455ebfa0a38ea5bd28c607e65506b263ece53a24d2361c2af7d7cd207e45b11bf71a3c33fa325fc8fd40a18b9c73019cce219c757c7ef","enode":"enode://8e8de10fb3f53bd3a48455ebfa0a38ea5bd28c607e65506b263ece53a24d2361c2af7d7cd207e45b11bf71a3c33fa325fc8fd40a18b9c73019cce219c757c7ef@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"gxGXcKgBpA8PQBXOiozGz6bbwhHeruGTxdsFEwAC+ac=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 831197\npopulation: 15 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 2650 7f5f 48a1 | 60 1943 (0) 18f6 (0) 1ab1 (0) 1ea8 (0)\n001 3 d916 d7f9 c243 | 36 c7fd (0) c358 (0) c243 (0) ca97 (0)\n002 1 bf7b | 12 aa19 (0) a8ba (0) aec5 (0) ac23 (0)\n003 3 96e9 9f97 981b | 10 9386 (0) 931a (0) 92e2 (0) 954a (0)\n004 1 8ec6 | 5 8bf5 (0) 8c5b (0) 8e31 (0) 8ec6 (0)\n005 1 87e0 | 1 87e0 (0)\n006 1 811d | 1 811d (0)\n============ DEPTH: 7 ==========================================\n007 1 8230 | 1 8230 (0)\n008 1 83bc | 1 83bc (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"8e8de10fb3f53bd3a48455ebfa0a38ea5bd28c607e65506b263ece53a24d2361c2af7d7cd207e45b11bf71a3c33fa325fc8fd40a18b9c73019cce219c757c7ef","private_key":"9202da3ce5dfea8df87f9f6145867414b45131634f70cd32dffffeb8975e0e86","name":"node_8e8de10fb3f53bd3a48455ebfa0a38ea5bd28c607e65506b263ece53a24d2361c2af7d7cd207e45b11bf71a3c33fa325fc8fd40a18b9c73019cce219c757c7ef","services":["streamer"],"enable_msg_events":true,"port":63135},"up":true}},{"node":{"info":{"id":"cdd86dea7dde96ff7cc1e3248fd17d107c83f2cc7ce2111c41530448962763309e91a05b5dad4663d0e02db59ed4129ab0c3e1eedc42c654e39d29f99038063b","name":"node_cdd86dea7dde96ff7cc1e3248fd17d107c83f2cc7ce2111c41530448962763309e91a05b5dad4663d0e02db59ed4129ab0c3e1eedc42c654e39d29f99038063b","enode":"enode://cdd86dea7dde96ff7cc1e3248fd17d107c83f2cc7ce2111c41530448962763309e91a05b5dad4663d0e02db59ed4129ab0c3e1eedc42c654e39d29f99038063b@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"JlBA0S0LechgkjIGCz3dasFvuJW1K7fz/uXG6LY6TXk=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 265040\npopulation: 19 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 8311 ea94 | 68 a60b (0) a12e (0) a250 (0) a3fc (0)\n001 7 5b36 48a1 740b 6aef | 37 57df (0) 500f (0) 53ea (0) 5d6d (0)\n002 3 059a 0400 1385 | 11 0047 (0) 06db (0) 059a (0) 0400 (0)\n003 2 3e4f 314e | 6 3d3a (0) 3f1e (0) 3e4f (0) 30a0 (0)\n============ DEPTH: 4 ==========================================\n004 4 2dc2 2fee 2a2b 2aef | 4 2dc2 (0) 2fee (0) 2a2b (0) 2aef (0)\n005 1 237b | 1 237b (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"cdd86dea7dde96ff7cc1e3248fd17d107c83f2cc7ce2111c41530448962763309e91a05b5dad4663d0e02db59ed4129ab0c3e1eedc42c654e39d29f99038063b","private_key":"6f53e22eece8ebd80ce64720dacf85c36c8aa737fe54d05c884ae9ad693144fb","name":"node_cdd86dea7dde96ff7cc1e3248fd17d107c83f2cc7ce2111c41530448962763309e91a05b5dad4663d0e02db59ed4129ab0c3e1eedc42c654e39d29f99038063b","services":["streamer"],"enable_msg_events":true,"port":63136},"up":true}},{"node":{"info":{"id":"da15d60a4b9a8816ce24c20f6c941c51229c1fb5e070b8b29be2977c2f7b41f8f17e4b6efe75f465e7935ded1ba17472f046eac73393db7197018fa86d11c31f","name":"node_da15d60a4b9a8816ce24c20f6c941c51229c1fb5e070b8b29be2977c2f7b41f8f17e4b6efe75f465e7935ded1ba17472f046eac73393db7197018fa86d11c31f","enode":"enode://da15d60a4b9a8816ce24c20f6c941c51229c1fb5e070b8b29be2977c2f7b41f8f17e4b6efe75f465e7935ded1ba17472f046eac73393db7197018fa86d11c31f@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"6pSQ8XgT4OXznoBl9MOVQWPzvKboCvynosdtXKMRblM=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: ea9490\npopulation: 13 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 6838 2650 | 60 57df (0) 53ea (0) 500f (0) 5b36 (0)\n001 3 8fe2 981b b1bf | 32 aec5 (0) ac23 (0) aa19 (0) a8ba (0)\n002 2 d7f9 d68e | 17 c7fd (0) c358 (0) c243 (0) ca97 (0)\n003 2 fba8 f29f | 10 f07c (0) f3a1 (0) f2b8 (0) f29f (0)\n004 1 e425 | 5 e0ac (0) e39e (0) e3c3 (0) e5cd (0)\n005 1 ec3b | 1 ec3b (0)\n006 0 | 0\n============ DEPTH: 7 ==========================================\n007 1 ebf9 | 1 ebf9 (0)\n008 1 ea51 | 1 ea51 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"da15d60a4b9a8816ce24c20f6c941c51229c1fb5e070b8b29be2977c2f7b41f8f17e4b6efe75f465e7935ded1ba17472f046eac73393db7197018fa86d11c31f","private_key":"ba12a0d7056bd5d7f8b80a1e30c126d8641ec4a20b2e8c9b890764785350cb7f","name":"node_da15d60a4b9a8816ce24c20f6c941c51229c1fb5e070b8b29be2977c2f7b41f8f17e4b6efe75f465e7935ded1ba17472f046eac73393db7197018fa86d11c31f","services":["streamer"],"enable_msg_events":true,"port":63137},"up":true}},{"node":{"info":{"id":"03e478a3aae82e06e215e40272a420037a61442d11c49c367a5ee6a21868d29a17ea8b9284f013d020c4740f296a6a22bc64d33d1c2807f9ab8dc48c0cfec18a","name":"node_03e478a3aae82e06e215e40272a420037a61442d11c49c367a5ee6a21868d29a17ea8b9284f013d020c4740f296a6a22bc64d33d1c2807f9ab8dc48c0cfec18a","enode":"enode://03e478a3aae82e06e215e40272a420037a61442d11c49c367a5ee6a21868d29a17ea8b9284f013d020c4740f296a6a22bc64d33d1c2807f9ab8dc48c0cfec18a@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"aDi4j/ccVBnT/SKkwAenuCJAWxhC1TQnqcB10JPBMEc=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 6838b8\npopulation: 15 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 ea94 | 68 a8ba (0) aa19 (0) aec5 (0) ac23 (0)\n001 2 2650 1385 | 23 3d3a (0) 3f1e (0) 3e4f (0) 30a0 (0)\n002 3 4454 4259 48a1 | 16 5b36 (0) 5d6d (0) 57df (0) 500f (0)\n003 1 7bcf | 9 7628 (0) 7692 (0) 740b (0) 7e65 (0)\n004 3 6632 60ad 6099 | 5 6640 (0) 6632 (0) 6120 (0) 6099 (0)\n005 2 6c1f 6e83 | 3 6cf1 (0) 6c1f (0) 6e83 (0)\n============ DEPTH: 6 ==========================================\n006 3 6a57 6ac7 6aef | 3 6a57 (0) 6ac7 (0) 6aef (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"03e478a3aae82e06e215e40272a420037a61442d11c49c367a5ee6a21868d29a17ea8b9284f013d020c4740f296a6a22bc64d33d1c2807f9ab8dc48c0cfec18a","private_key":"f68a07d7241789486ffebae385ee73f2b9050d22612e9770a1aad1870e347556","name":"node_03e478a3aae82e06e215e40272a420037a61442d11c49c367a5ee6a21868d29a17ea8b9284f013d020c4740f296a6a22bc64d33d1c2807f9ab8dc48c0cfec18a","services":["streamer"],"enable_msg_events":true,"port":63138},"up":true}},{"node":{"info":{"id":"3df030a522a157e36f6b369aab048b9287792743a411a47073c4f9ef7686528f39bf7bf91c48e4d46afe180c8d08430b012bd216d50876baa3b1e7bc17cb55ef","name":"node_3df030a522a157e36f6b369aab048b9287792743a411a47073c4f9ef7686528f39bf7bf91c48e4d46afe180c8d08430b012bd216d50876baa3b1e7bc17cb55ef","enode":"enode://3df030a522a157e36f6b369aab048b9287792743a411a47073c4f9ef7686528f39bf7bf91c48e4d46afe180c8d08430b012bd216d50876baa3b1e7bc17cb55ef@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"E4Xpe4edqQIaumWy3za5FlCq+zVKCcW+ipUy0et9Rys=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 1385e9\npopulation: 11 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 d68e | 68 a60b (0) a12e (0) a3fc (0) a250 (0)\n001 1 6838 | 37 5d6d (0) 5b36 (0) 57df (0) 500f (0)\n002 2 2fee 2650 | 12 3d3a (0) 3e4f (0) 3f1e (0) 30a0 (0)\n003 1 0400 | 4 0047 (0) 06db (0) 059a (0) 0400 (0)\n============ DEPTH: 4 ==========================================\n004 5 1ab1 1943 18f6 1ea8 | 5 1ab1 (0) 1943 (0) 18f6 (0) 1ea8 (0)\n005 0 | 0\n006 1 11a6 | 1 11a6 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"3df030a522a157e36f6b369aab048b9287792743a411a47073c4f9ef7686528f39bf7bf91c48e4d46afe180c8d08430b012bd216d50876baa3b1e7bc17cb55ef","private_key":"f9fa950ad709b5c36e36f5f49a4260ab81e08145d8c10611a2d46e1395ac87f6","name":"node_3df030a522a157e36f6b369aab048b9287792743a411a47073c4f9ef7686528f39bf7bf91c48e4d46afe180c8d08430b012bd216d50876baa3b1e7bc17cb55ef","services":["streamer"],"enable_msg_events":true,"port":63139},"up":true}},{"node":{"info":{"id":"4bd17847bdf60ea93a670a84a0ff8fe028d35228e814d6ebc0ae4fa586ddef03cd79390d541d28ca3c05a7241ffe92ac182e63c251176b40db8fe05fefaa82be","name":"node_4bd17847bdf60ea93a670a84a0ff8fe028d35228e814d6ebc0ae4fa586ddef03cd79390d541d28ca3c05a7241ffe92ac182e63c251176b40db8fe05fefaa82be","enode":"enode://4bd17847bdf60ea93a670a84a0ff8fe028d35228e814d6ebc0ae4fa586ddef03cd79390d541d28ca3c05a7241ffe92ac182e63c251176b40db8fe05fefaa82be@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"1o4JXnckbDwI3y6uwpSWW8otAfooGdnNBsbvhzDFmrQ=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: d68e09\npopulation: 20 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 4778 314e 06db 1385 | 60 5d6d (0) 5b36 (0) 57df (0) 500f (0)\n001 1 b1bf | 32 a60b (0) a12e (0) a3fc (0) a250 (0)\n002 5 fba8 f29f e0ac ea94 | 19 f07c (0) f3a1 (0) f2b8 (0) f29f (0)\n003 3 cac9 c358 c243 | 5 c7fd (0) c358 (0) c243 (0) ca97 (0)\n004 3 d80b d916 dc2a | 5 db59 (0) d80b (0) d87f (0) d916 (0)\n005 1 d382 | 3 d192 (0) d386 (0) d382 (0)\n006 1 d552 | 1 d552 (0)\n============ DEPTH: 7 ==========================================\n007 2 d798 d7f9 | 2 d798 (0) d7f9 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"4bd17847bdf60ea93a670a84a0ff8fe028d35228e814d6ebc0ae4fa586ddef03cd79390d541d28ca3c05a7241ffe92ac182e63c251176b40db8fe05fefaa82be","private_key":"27eb2337ccaec369a786c3e86e92bfc20b6bd03e70244b7d1266e783f087a16f","name":"node_4bd17847bdf60ea93a670a84a0ff8fe028d35228e814d6ebc0ae4fa586ddef03cd79390d541d28ca3c05a7241ffe92ac182e63c251176b40db8fe05fefaa82be","services":["streamer"],"enable_msg_events":true,"port":63140},"up":true}},{"node":{"info":{"id":"f8052e328014f39157036f3dcecdb23419c0959473a88282605f10add681ef5cbfb1e926b522f98b8401272113b677a67225874d1afb0bff4b11140cc071de44","name":"node_f8052e328014f39157036f3dcecdb23419c0959473a88282605f10add681ef5cbfb1e926b522f98b8401272113b677a67225874d1afb0bff4b11140cc071de44","enode":"enode://f8052e328014f39157036f3dcecdb23419c0959473a88282605f10add681ef5cbfb1e926b522f98b8401272113b677a67225874d1afb0bff4b11140cc071de44@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"6/mmQltHp43xyZ/k1ipIwm0vTvlmqFkoAtW16V5sEus=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: ebf9a6\npopulation: 20 (109), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 2dc2 6099 | 47 3e4f (0) 3f1e (0) 30a0 (0) 311f (0)\n001 4 931a 92e2 981b 8fe2 | 29 92e2 (0) 931a (0) 9386 (0) 97a5 (0)\n002 6 c243 dc2a d916 d552 | 15 c358 (0) c243 (0) ca97 (0) cac9 (0)\n003 4 f2b8 f29f fa62 fba8 | 10 f07c (0) f3a1 (0) f2b8 (0) f29f (0)\n004 1 e425 | 5 e0ac (0) e39e (0) e3c3 (0) e5cd (0)\n005 1 ec3b | 1 ec3b (0)\n006 0 | 0\n============ DEPTH: 7 ==========================================\n007 2 ea51 ea94 | 2 ea51 (0) ea94 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"f8052e328014f39157036f3dcecdb23419c0959473a88282605f10add681ef5cbfb1e926b522f98b8401272113b677a67225874d1afb0bff4b11140cc071de44","private_key":"dc23bae09e0ef5811f615cd80fa3c264a5011f501f3fa6f91cf6772a408ba5b3","name":"node_f8052e328014f39157036f3dcecdb23419c0959473a88282605f10add681ef5cbfb1e926b522f98b8401272113b677a67225874d1afb0bff4b11140cc071de44","services":["streamer"],"enable_msg_events":true,"port":63141},"up":true}},{"node":{"info":{"id":"3274b5f48e6929e2305e980b558a4ca3c7cf800b75a6445ea2875cb379e127f3e793e9450a11e927682aa91b8af52e9560dece633833e0f207a8a8a38b7b9c54","name":"node_3274b5f48e6929e2305e980b558a4ca3c7cf800b75a6445ea2875cb379e127f3e793e9450a11e927682aa91b8af52e9560dece633833e0f207a8a8a38b7b9c54","enode":"enode://3274b5f48e6929e2305e980b558a4ca3c7cf800b75a6445ea2875cb379e127f3e793e9450a11e927682aa91b8af52e9560dece633833e0f207a8a8a38b7b9c54@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"YJlYkh2RB+qubzFB6U8Ss6KP7CA+sOW2dO2CaJNL7Mc=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 609958\npopulation: 13 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 d916 ebf9 | 68 97a5 (0) 96e9 (0) 96b7 (0) 954a (0)\n001 3 059a 1f2a 2650 | 23 3d3a (0) 3e4f (0) 3f1e (0) 311f (0)\n002 1 4778 | 16 5b36 (0) 5d6d (0) 57df (0) 53ea (0)\n003 1 7bcf | 9 740b (0) 7628 (0) 7692 (0) 7e65 (0)\n004 2 6aef 6838 | 7 6c1f (0) 6cf1 (0) 6e83 (0) 6a57 (0)\n005 2 6632 6640 | 2 6640 (0) 6632 (0)\n006 0 | 0\n============ DEPTH: 7 ==========================================\n007 1 6120 | 1 6120 (0)\n008 0 | 0\n009 0 | 0\n010 1 60ad | 1 60ad (0)\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"3274b5f48e6929e2305e980b558a4ca3c7cf800b75a6445ea2875cb379e127f3e793e9450a11e927682aa91b8af52e9560dece633833e0f207a8a8a38b7b9c54","private_key":"f37b323598ac406038a1fba2fb8acf1ac7899c6606f263470141e3d8f364c70a","name":"node_3274b5f48e6929e2305e980b558a4ca3c7cf800b75a6445ea2875cb379e127f3e793e9450a11e927682aa91b8af52e9560dece633833e0f207a8a8a38b7b9c54","services":["streamer"],"enable_msg_events":true,"port":63142},"up":true}},{"node":{"info":{"id":"e59940a6dfe35a6214e2e3daba9ad94e630004cd8f029e13a6649a56dc528ff94bc09d8d21a2f14a56b4ff759b60ebf3d27c1029862c183b8416fa3e950bdb55","name":"node_e59940a6dfe35a6214e2e3daba9ad94e630004cd8f029e13a6649a56dc528ff94bc09d8d21a2f14a56b4ff759b60ebf3d27c1029862c183b8416fa3e950bdb55","enode":"enode://e59940a6dfe35a6214e2e3daba9ad94e630004cd8f029e13a6649a56dc528ff94bc09d8d21a2f14a56b4ff759b60ebf3d27c1029862c183b8416fa3e950bdb55@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"2RafgGg6JVJHXWDmmC9wxmBfm0AwDytgiVqiHNxC24k=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: d9169f\npopulation: 21 (122), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 06db 6099 | 55 2fee (0) 2dc2 (0) 2a2b (0) 2aef (0)\n001 3 8311 981b bf7b | 32 92e2 (0) 9386 (0) 931a (0) 954a (0)\n002 5 f2b8 f29f fba8 e425 | 19 f07c (0) f3a1 (0) f2b8 (0) f29f (0)\n003 2 c243 c358 | 5 ca97 (0) cac9 (0) c7fd (0) c243 (0)\n004 5 d192 d382 d7f9 d68e | 7 d192 (0) d386 (0) d382 (0) d552 (0)\n005 1 dc2a | 1 dc2a (0)\n006 1 db59 | 1 db59 (0)\n============ DEPTH: 7 ==========================================\n007 2 d80b d87f | 2 d80b (0) d87f (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"e59940a6dfe35a6214e2e3daba9ad94e630004cd8f029e13a6649a56dc528ff94bc09d8d21a2f14a56b4ff759b60ebf3d27c1029862c183b8416fa3e950bdb55","private_key":"fa14be3b746acd18c44299337f26807c3f0034349cc7eb6ad398a32061e68e12","name":"node_e59940a6dfe35a6214e2e3daba9ad94e630004cd8f029e13a6649a56dc528ff94bc09d8d21a2f14a56b4ff759b60ebf3d27c1029862c183b8416fa3e950bdb55","services":["streamer"],"enable_msg_events":true,"port":63143},"up":true}},{"node":{"info":{"id":"f7637cdd5ef26de40b9055c1df91a45725670c8df11ae934c0d99d2547c3eb4c42a16dbb2e75bcaf4b1b9347c48db65f549a0623179a08dd8cbad92f5bca08cf","name":"node_f7637cdd5ef26de40b9055c1df91a45725670c8df11ae934c0d99d2547c3eb4c42a16dbb2e75bcaf4b1b9347c48db65f549a0623179a08dd8cbad92f5bca08cf","enode":"enode://f7637cdd5ef26de40b9055c1df91a45725670c8df11ae934c0d99d2547c3eb4c42a16dbb2e75bcaf4b1b9347c48db65f549a0623179a08dd8cbad92f5bca08cf@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"v3sLmCW5yHj3cwAUx0WPxS7jSQyY7lri9keo1z5EZPM=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: bf7b0b\npopulation: 18 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 5 6aef 60ad 7bcf 48a1 | 60 5b36 (0) 5d6d (0) 57df (0) 500f (0)\n001 2 fba8 d916 | 36 ec3b (0) ea94 (0) ea51 (0) ebf9 (0)\n002 7 9f97 96e9 8ec6 8fe2 | 20 931a (0) 9386 (0) 92e2 (0) 954a (0)\n003 1 a250 | 8 aa19 (0) a8ba (0) aec5 (0) ac23 (0)\n============ DEPTH: 4 ==========================================\n004 2 b220 b1bf | 2 b220 (0) b1bf (0)\n005 1 b9e5 | 1 b9e5 (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"f7637cdd5ef26de40b9055c1df91a45725670c8df11ae934c0d99d2547c3eb4c42a16dbb2e75bcaf4b1b9347c48db65f549a0623179a08dd8cbad92f5bca08cf","private_key":"67c3621e70643b370db5377452ca3a8bfe78a01172983da0ba5fb979ce341bd1","name":"node_f7637cdd5ef26de40b9055c1df91a45725670c8df11ae934c0d99d2547c3eb4c42a16dbb2e75bcaf4b1b9347c48db65f549a0623179a08dd8cbad92f5bca08cf","services":["streamer"],"enable_msg_events":true,"port":63144},"up":true}},{"node":{"info":{"id":"fa897ba112f34839064c6871a4c9504c5d709eff5095a137c6a42726d58eb623af976cb96cc30db67e6ac9347c769f032aa4ebda884285a057059040c008ad3e","name":"node_fa897ba112f34839064c6871a4c9504c5d709eff5095a137c6a42726d58eb623af976cb96cc30db67e6ac9347c769f032aa4ebda884285a057059040c008ad3e","enode":"enode://fa897ba112f34839064c6871a4c9504c5d709eff5095a137c6a42726d58eb623af976cb96cc30db67e6ac9347c769f032aa4ebda884285a057059040c008ad3e@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"+6ifgMNeX2/75uVSHyARyuyYXYIP5CdZ7xqqNtSQLzc=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: fba89f\npopulation: 21 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 2dc2 740b | 60 237b (0) 2650 (0) 2a2b (0) 2aef (0)\n001 1 bf7b | 32 87e0 (0) 811d (0) 8230 (0) 83bc (0)\n002 5 d552 d68e d7f9 d916 | 17 c7fd (0) c358 (0) c243 (0) ca97 (0)\n003 5 ea51 ea94 ebf9 e5cd | 9 ec3b (0) ea94 (0) ea51 (0) ebf9 (0)\n004 3 f3a1 f2b8 f29f | 4 f07c (0) f3a1 (0) f2b8 (0) f29f (0)\n005 1 feb3 | 1 feb3 (0)\n============ DEPTH: 6 ==========================================\n006 3 f995 f80e f836 | 3 f995 (0) f80e (0) f836 (0)\n007 1 fa62 | 1 fa62 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"fa897ba112f34839064c6871a4c9504c5d709eff5095a137c6a42726d58eb623af976cb96cc30db67e6ac9347c769f032aa4ebda884285a057059040c008ad3e","private_key":"e4e774ffb3fee42b1fb038f560cbb7ef3f4ec4f12d077fd90c38de877841eddd","name":"node_fa897ba112f34839064c6871a4c9504c5d709eff5095a137c6a42726d58eb623af976cb96cc30db67e6ac9347c769f032aa4ebda884285a057059040c008ad3e","services":["streamer"],"enable_msg_events":true,"port":63145},"up":true}},{"node":{"info":{"id":"5d96577324edf1b5a1626999925982af1e0ba7bed8edcc3f740ba434f4b003cbbe2d632cad327c76e5b490d08c091c4a7b473353ab59139493657eb9525b8be2","name":"node_5d96577324edf1b5a1626999925982af1e0ba7bed8edcc3f740ba434f4b003cbbe2d632cad327c76e5b490d08c091c4a7b473353ab59139493657eb9525b8be2","enode":"enode://5d96577324edf1b5a1626999925982af1e0ba7bed8edcc3f740ba434f4b003cbbe2d632cad327c76e5b490d08c091c4a7b473353ab59139493657eb9525b8be2@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"3CroG3CKFPi24TSYYHWDWZTHHShLm9n6GdLvpzNG814=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: dc2ae8\npopulation: 21 (124), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 6 7628 740b 4778 4236 | 58 237b (0) 2650 (0) 2fee (0) 2dc2 (0)\n001 2 b220 8fe2 | 31 aa19 (0) ac23 (0) aec5 (0) a60b (0)\n002 4 ebf9 f2b8 f29f fba8 | 19 ec3b (0) ea94 (0) ea51 (0) ebf9 (0)\n003 1 cac9 | 5 c7fd (0) c358 (0) c243 (0) ca97 (0)\n004 4 d552 d798 d7f9 d68e | 7 d192 (0) d386 (0) d382 (0) d552 (0)\n============ DEPTH: 5 ==========================================\n005 4 db59 d80b d87f d916 | 4 db59 (0) d80b (0) d87f (0) d916 (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"5d96577324edf1b5a1626999925982af1e0ba7bed8edcc3f740ba434f4b003cbbe2d632cad327c76e5b490d08c091c4a7b473353ab59139493657eb9525b8be2","private_key":"9fdcb97101ee0351d72b1cb7b832fc95f339a434e9d1e146af4062d0d43a88c6","name":"node_5d96577324edf1b5a1626999925982af1e0ba7bed8edcc3f740ba434f4b003cbbe2d632cad327c76e5b490d08c091c4a7b473353ab59139493657eb9525b8be2","services":["streamer"],"enable_msg_events":true,"port":63146},"up":true}},{"node":{"info":{"id":"b09af9e5552e72f918174963dad58a4492d3afa120f78e43820df7bff7fae9f6b52bc6c8c73d3a9af91d20134f4ff1b037db2ef0bc3d8c495a771d63de678bc0","name":"node_b09af9e5552e72f918174963dad58a4492d3afa120f78e43820df7bff7fae9f6b52bc6c8c73d3a9af91d20134f4ff1b037db2ef0bc3d8c495a771d63de678bc0","enode":"enode://b09af9e5552e72f918174963dad58a4492d3afa120f78e43820df7bff7fae9f6b52bc6c8c73d3a9af91d20134f4ff1b037db2ef0bc3d8c495a771d63de678bc0@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"j+IS/JrxKCH1m182T4b3i1Rb5QGTO5JvxHttfer8qUE=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 8fe212\npopulation: 16 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 6aef 7628 | 60 237b (0) 2650 (0) 2fee (0) 2dc2 (0)\n001 3 ebf9 ea94 dc2a | 36 ec3b (0) ea94 (0) ea51 (0) ebf9 (0)\n002 1 bf7b | 12 a60b (0) a12e (0) a3fc (0) a250 (0)\n003 4 96e9 97a5 9f97 981b | 10 931a (0) 9386 (0) 92e2 (0) 954a (0)\n004 2 83bc 87e0 | 5 87e0 (0) 811d (0) 8230 (0) 83bc (0)\n005 1 8bf5 | 1 8bf5 (0)\n006 1 8c5b | 1 8c5b (0)\n============ DEPTH: 7 ==========================================\n007 2 8e31 8ec6 | 2 8e31 (0) 8ec6 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"b09af9e5552e72f918174963dad58a4492d3afa120f78e43820df7bff7fae9f6b52bc6c8c73d3a9af91d20134f4ff1b037db2ef0bc3d8c495a771d63de678bc0","private_key":"05ba41be88727fe8ceb3dd01ae6314f6eb66de9c223da829a6cb0fcb9633dbc7","name":"node_b09af9e5552e72f918174963dad58a4492d3afa120f78e43820df7bff7fae9f6b52bc6c8c73d3a9af91d20134f4ff1b037db2ef0bc3d8c495a771d63de678bc0","services":["streamer"],"enable_msg_events":true,"port":63147},"up":true}},{"node":{"info":{"id":"1955bedf0bc9044b13a2c16158087123197c74147c86aa3b9389d308a364e80edbc573bcc836d8a262a77f3c9233ebddb1b82eca83cd0a0e4bda6564c443bb70","name":"node_1955bedf0bc9044b13a2c16158087123197c74147c86aa3b9389d308a364e80edbc573bcc836d8a262a77f3c9233ebddb1b82eca83cd0a0e4bda6564c443bb70","enode":"enode://1955bedf0bc9044b13a2c16158087123197c74147c86aa3b9389d308a364e80edbc573bcc836d8a262a77f3c9233ebddb1b82eca83cd0a0e4bda6564c443bb70@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"dii89kUyyj7Ck9JvYHkaKmJUKy9fPxx4J5kHU4PM3gA=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 7628bc\npopulation: 10 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 dc2a f29f 8fe2 | 68 ec3b (0) ea94 (0) ea51 (0) ebf9 (0)\n001 1 314e | 23 237b (0) 2650 (0) 2fee (0) 2dc2 (0)\n002 2 4778 5b36 | 16 57df (0) 500f (0) 53ea (0) 5d6d (0)\n003 1 6a57 | 12 6632 (0) 6640 (0) 6120 (0) 6099 (0)\n004 1 7e65 | 6 7bcf (0) 78bf (0) 7c76 (0) 7e65 (0)\n005 0 | 0\n============ DEPTH: 6 ==========================================\n006 1 740b | 1 740b (0)\n007 0 | 0\n008 1 7692 | 1 7692 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"1955bedf0bc9044b13a2c16158087123197c74147c86aa3b9389d308a364e80edbc573bcc836d8a262a77f3c9233ebddb1b82eca83cd0a0e4bda6564c443bb70","private_key":"4f458de05e760aece8dffaa29333d3a51382cceb7bb8265be7a25ea65cfaf2d2","name":"node_1955bedf0bc9044b13a2c16158087123197c74147c86aa3b9389d308a364e80edbc573bcc836d8a262a77f3c9233ebddb1b82eca83cd0a0e4bda6564c443bb70","services":["streamer"],"enable_msg_events":true,"port":63148},"up":true}},{"node":{"info":{"id":"5984a296b49bfba30315501ce2ae88ed0392ab2959ac4e7e6b9a29090f344b9dd13873ca137e8317c402cd2e14a61965d5707065b8ded46c41a054731933719f","name":"node_5984a296b49bfba30315501ce2ae88ed0392ab2959ac4e7e6b9a29090f344b9dd13873ca137e8317c402cd2e14a61965d5707065b8ded46c41a054731933719f","enode":"enode://5984a296b49bfba30315501ce2ae88ed0392ab2959ac4e7e6b9a29090f344b9dd13873ca137e8317c402cd2e14a61965d5707065b8ded46c41a054731933719f@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"dAvr9FRuLtMrK9J3VVaF474HGspLGZDHwJXhLiT6Rpk=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 740beb\npopulation: 10 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 dc2a f29f fba8 981b | 68 ec3b (0) ea94 (0) ea51 (0) ebf9 (0)\n001 1 2650 | 23 237b (0) 2650 (0) 2fee (0) 2dc2 (0)\n002 1 5b36 | 16 57df (0) 500f (0) 53ea (0) 5d6d (0)\n003 1 6a57 | 12 6632 (0) 6640 (0) 6120 (0) 6099 (0)\n004 1 7bcf | 6 7bcf (0) 78bf (0) 7c76 (0) 7e65 (0)\n005 0 | 0\n============ DEPTH: 6 ==========================================\n006 2 7692 7628 | 2 7692 (0) 7628 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"5984a296b49bfba30315501ce2ae88ed0392ab2959ac4e7e6b9a29090f344b9dd13873ca137e8317c402cd2e14a61965d5707065b8ded46c41a054731933719f","private_key":"c2adb7237525d3d280b964361432cfe1d2863e3011b4b83167648da04a8b22fb","name":"node_5984a296b49bfba30315501ce2ae88ed0392ab2959ac4e7e6b9a29090f344b9dd13873ca137e8317c402cd2e14a61965d5707065b8ded46c41a054731933719f","services":["streamer"],"enable_msg_events":true,"port":63149},"up":true}},{"node":{"info":{"id":"9c3be147f9fe0fa34e553d9e4332969086ea7fa65294b61ca35c9f731f6b81d0b70cdcfe2ba52b6cea3c0de14b7ea40031b5cc40661c4bb821147894130d7bf5","name":"node_9c3be147f9fe0fa34e553d9e4332969086ea7fa65294b61ca35c9f731f6b81d0b70cdcfe2ba52b6cea3c0de14b7ea40031b5cc40661c4bb821147894130d7bf5","enode":"enode://9c3be147f9fe0fa34e553d9e4332969086ea7fa65294b61ca35c9f731f6b81d0b70cdcfe2ba52b6cea3c0de14b7ea40031b5cc40661c4bb821147894130d7bf5@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"mBvg0hvbEayAfcKZN8ajrCrjwvRSacDtwhFy1VUPTak=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 981be0\npopulation: 18 (107), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 740b | 43 2650 (0) 237b (0) 2dc2 (0) 2fee (0)\n001 5 ebf9 ea94 cac9 c243 | 35 c7fd (0) c358 (0) c243 (0) ca97 (0)\n002 1 b1bf | 10 aa19 (0) a8ba (0) ac23 (0) aec5 (0)\n003 6 8ec6 8fe2 87e0 8230 | 10 87e0 (0) 811d (0) 8230 (0) 83bc (0)\n004 3 97a5 96e9 92e2 | 7 931a (0) 9386 (0) 92e2 (0) 954a (0)\n============ DEPTH: 5 ==========================================\n005 2 9cbc 9f97 | 2 9cbc (0) 9f97 (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"9c3be147f9fe0fa34e553d9e4332969086ea7fa65294b61ca35c9f731f6b81d0b70cdcfe2ba52b6cea3c0de14b7ea40031b5cc40661c4bb821147894130d7bf5","private_key":"43223de0a2e5b61580a85a150f19528acd484002efde9df5041f8b93b5d9f0e9","name":"node_9c3be147f9fe0fa34e553d9e4332969086ea7fa65294b61ca35c9f731f6b81d0b70cdcfe2ba52b6cea3c0de14b7ea40031b5cc40661c4bb821147894130d7bf5","services":["streamer"],"enable_msg_events":true,"port":63150},"up":true}},{"node":{"info":{"id":"ce1309c8505b446363ae37cd3b1ee3e03ced537bed20aca5d8c4be2133917c408845ef5d0f65876974be2803dfb824827cf5c5a2d050d6ef26cdabcbf3a2dc31","name":"node_ce1309c8505b446363ae37cd3b1ee3e03ced537bed20aca5d8c4be2133917c408845ef5d0f65876974be2803dfb824827cf5c5a2d050d6ef26cdabcbf3a2dc31","enode":"enode://ce1309c8505b446363ae37cd3b1ee3e03ced537bed20aca5d8c4be2133917c408845ef5d0f65876974be2803dfb824827cf5c5a2d050d6ef26cdabcbf3a2dc31@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"sb96BXLB788DS/QvVPczR0PFn3e2ciWqPH2TVSB0q1Y=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: b1bf7a\npopulation: 11 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 314e | 60 0047 (0) 06db (0) 059a (0) 0400 (0)\n001 3 d68e ea94 e425 | 36 c7fd (0) c358 (0) c243 (0) ca97 (0)\n002 2 83bc 981b | 20 9386 (0) 931a (0) 92e2 (0) 954a (0)\n003 2 a60b aa19 | 8 aec5 (0) ac23 (0) a8ba (0) aa19 (0)\n============ DEPTH: 4 ==========================================\n004 2 b9e5 bf7b | 2 b9e5 (0) bf7b (0)\n005 0 | 0\n006 1 b220 | 1 b220 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"ce1309c8505b446363ae37cd3b1ee3e03ced537bed20aca5d8c4be2133917c408845ef5d0f65876974be2803dfb824827cf5c5a2d050d6ef26cdabcbf3a2dc31","private_key":"863d1cfaeee0df7e89ff906a00c0165a9e579fda9f82bc3fd9b694a593e37139","name":"node_ce1309c8505b446363ae37cd3b1ee3e03ced537bed20aca5d8c4be2133917c408845ef5d0f65876974be2803dfb824827cf5c5a2d050d6ef26cdabcbf3a2dc31","services":["streamer"],"enable_msg_events":true,"port":63151},"up":true}},{"node":{"info":{"id":"3e7820bb15c07f515bd63791b66136723dcc9878b3145fe0f238f6b41e3f2f7565ae55ef24f08ae461950ce1ae0c8a80fe5e4fd4f2f88c4acf4a2c94640df239","name":"node_3e7820bb15c07f515bd63791b66136723dcc9878b3145fe0f238f6b41e3f2f7565ae55ef24f08ae461950ce1ae0c8a80fe5e4fd4f2f88c4acf4a2c94640df239","enode":"enode://3e7820bb15c07f515bd63791b66136723dcc9878b3145fe0f238f6b41e3f2f7565ae55ef24f08ae461950ce1ae0c8a80fe5e4fd4f2f88c4acf4a2c94640df239@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"5CVM2pAydSlvF7R+Xcq78W0fp0MrZODm4FYvzYneU00=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: e4254c\npopulation: 17 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 2dc2 | 60 5b36 (0) 5d6d (0) 57df (0) 500f (0)\n001 2 8230 b1bf | 32 9386 (0) 931a (0) 92e2 (0) 954a (0)\n002 2 d916 c243 | 17 c7fd (0) c358 (0) c243 (0) ca97 (0)\n003 4 f2b8 f29f fa62 fba8 | 10 f07c (0) f3a1 (0) f2b8 (0) f29f (0)\n004 4 ec3b ea51 ea94 ebf9 | 4 ec3b (0) ea94 (0) ea51 (0) ebf9 (0)\n============ DEPTH: 5 ==========================================\n005 3 e3c3 e39e e0ac | 3 e39e (0) e3c3 (0) e0ac (0)\n006 0 | 0\n007 1 e5cd | 1 e5cd (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"3e7820bb15c07f515bd63791b66136723dcc9878b3145fe0f238f6b41e3f2f7565ae55ef24f08ae461950ce1ae0c8a80fe5e4fd4f2f88c4acf4a2c94640df239","private_key":"f8f2976509e8c27362fc450e79db0e7b99ee036277d5a1c860f265be28b6525c","name":"node_3e7820bb15c07f515bd63791b66136723dcc9878b3145fe0f238f6b41e3f2f7565ae55ef24f08ae461950ce1ae0c8a80fe5e4fd4f2f88c4acf4a2c94640df239","services":["streamer"],"enable_msg_events":true,"port":63152},"up":true}},{"node":{"info":{"id":"dafb58b2fc8a14f2b23b7df33d28aa7847a08f80e9c21a654d4c97d928e1afe6585644d27f22442cf70d229c32783be6a03c0920be153fc4d9f3b273dfa90ec3","name":"node_dafb58b2fc8a14f2b23b7df33d28aa7847a08f80e9c21a654d4c97d928e1afe6585644d27f22442cf70d229c32783be6a03c0920be153fc4d9f3b273dfa90ec3","enode":"enode://dafb58b2fc8a14f2b23b7df33d28aa7847a08f80e9c21a654d4c97d928e1afe6585644d27f22442cf70d229c32783be6a03c0920be153fc4d9f3b273dfa90ec3@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"LcKRT3bsmykbIIW+ptLg9tRb61W7peOpAFm5boMBAxg=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 2dc291\npopulation: 21 (112), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 7 83bc fba8 fa62 f29f | 60 9386 (0) 931a (0) 92e2 (0) 97a5 (0)\n001 3 4087 4236 7f5f | 33 5d6d (0) 5b36 (0) 57df (0) 500f (0)\n002 4 059a 06db 1f2a 18f6 | 8 059a (0) 0400 (0) 06db (0) 11a6 (0)\n003 2 3e4f 314e | 6 3d3a (0) 3f1e (0) 3e4f (0) 30a0 (0)\n004 2 2650 237b | 2 2650 (0) 237b (0)\n============ DEPTH: 5 ==========================================\n005 2 2a2b 2aef | 2 2a2b (0) 2aef (0)\n006 1 2fee | 1 2fee (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"dafb58b2fc8a14f2b23b7df33d28aa7847a08f80e9c21a654d4c97d928e1afe6585644d27f22442cf70d229c32783be6a03c0920be153fc4d9f3b273dfa90ec3","private_key":"eac78f03be8f9529f9c85dceadffbc6ff39de01456bab5c864f9ea5a4198ee23","name":"node_dafb58b2fc8a14f2b23b7df33d28aa7847a08f80e9c21a654d4c97d928e1afe6585644d27f22442cf70d229c32783be6a03c0920be153fc4d9f3b273dfa90ec3","services":["streamer"],"enable_msg_events":true,"port":63153},"up":true}},{"node":{"info":{"id":"622646c74fdbae39ba191dbafff4906fb683fe0b0f2c303d080f5577a070876c41c8d3786ae7b953e5f682b8ec647727550d47302229ebb9f82bed24cea61132","name":"node_622646c74fdbae39ba191dbafff4906fb683fe0b0f2c303d080f5577a070876c41c8d3786ae7b953e5f682b8ec647727550d47302229ebb9f82bed24cea61132","enode":"enode://622646c74fdbae39ba191dbafff4906fb683fe0b0f2c303d080f5577a070876c41c8d3786ae7b953e5f682b8ec647727550d47302229ebb9f82bed24cea61132@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"g7yEDaTh+SAfDoXbLEQ2TwbBiP7e8w/S9yy95w9s/bk=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 83bc84\npopulation: 15 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 2dc2 7f5f | 60 06db (0) 0400 (0) 059a (0) 0047 (0)\n001 1 d7f9 | 36 c7fd (0) c358 (0) c243 (0) ca97 (0)\n002 3 bf7b b220 b1bf | 12 aec5 (0) ac23 (0) a8ba (0) aa19 (0)\n003 3 96e9 9f97 981b | 10 931a (0) 9386 (0) 92e2 (0) 954a (0)\n004 2 8fe2 8ec6 | 5 8bf5 (0) 8c5b (0) 8fe2 (0) 8e31 (0)\n005 1 87e0 | 1 87e0 (0)\n006 1 811d | 1 811d (0)\n============ DEPTH: 7 ==========================================\n007 1 8230 | 1 8230 (0)\n008 1 8311 | 1 8311 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"622646c74fdbae39ba191dbafff4906fb683fe0b0f2c303d080f5577a070876c41c8d3786ae7b953e5f682b8ec647727550d47302229ebb9f82bed24cea61132","private_key":"6488421507de8fcdef9f2e89a73b5e9182ec8c0cb7d564e630dfe38ebcd732a1","name":"node_622646c74fdbae39ba191dbafff4906fb683fe0b0f2c303d080f5577a070876c41c8d3786ae7b953e5f682b8ec647727550d47302229ebb9f82bed24cea61132","services":["streamer"],"enable_msg_events":true,"port":63154},"up":true}},{"node":{"info":{"id":"2d6d55edd34c0d9a0130b4806e409bbe18cdda5c2b221cf46136718ec20ffc9d8e92838d78aff92fbcc85f5d081da361dd1e3d7f3d4e1ea57877d6bb7aa0b6f7","name":"node_2d6d55edd34c0d9a0130b4806e409bbe18cdda5c2b221cf46136718ec20ffc9d8e92838d78aff92fbcc85f5d081da361dd1e3d7f3d4e1ea57877d6bb7aa0b6f7","enode":"enode://2d6d55edd34c0d9a0130b4806e409bbe18cdda5c2b221cf46136718ec20ffc9d8e92838d78aff92fbcc85f5d081da361dd1e3d7f3d4e1ea57877d6bb7aa0b6f7@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"f1+flV42jJBnRtQpU+MOeBqOtzQor1qmCK+Wr5v09go=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 7f5f9f\npopulation: 21 (125), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 5 d7f9 87e0 8230 8311 | 66 c7fd (0) c358 (0) c243 (0) ca97 (0)\n001 3 18f6 314e 2dc2 | 23 06db (0) 059a (0) 0400 (0) 0047 (0)\n002 3 53ea 4778 4236 | 16 5d6d (0) 5b36 (0) 57df (0) 500f (0)\n003 4 6cf1 6e83 6ac7 6a57 | 12 6640 (0) 6632 (0) 60ad (0) 6099 (0)\n004 1 7692 | 3 740b (0) 7628 (0) 7692 (0)\n005 2 7bcf 78bf | 2 7bcf (0) 78bf (0)\n006 1 7c76 | 1 7c76 (0)\n============ DEPTH: 7 ==========================================\n007 1 7e65 | 1 7e65 (0)\n008 0 | 0\n009 0 | 0\n010 1 7f62 | 1 7f62 (0)\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"2d6d55edd34c0d9a0130b4806e409bbe18cdda5c2b221cf46136718ec20ffc9d8e92838d78aff92fbcc85f5d081da361dd1e3d7f3d4e1ea57877d6bb7aa0b6f7","private_key":"7f547289aa8ba8dade535a2e50bfc2111536e7149162e360ea5e4db15c12d42a","name":"node_2d6d55edd34c0d9a0130b4806e409bbe18cdda5c2b221cf46136718ec20ffc9d8e92838d78aff92fbcc85f5d081da361dd1e3d7f3d4e1ea57877d6bb7aa0b6f7","services":["streamer"],"enable_msg_events":true,"port":63155},"up":true}},{"node":{"info":{"id":"f62bd19b0fd052207743ce53c3d48a3a71e9219b75e41a9497a43e6368e559d5487ff1ab644f2df4106b500583e4344515f73187eec773115deb977b4ebc3514","name":"node_f62bd19b0fd052207743ce53c3d48a3a71e9219b75e41a9497a43e6368e559d5487ff1ab644f2df4106b500583e4344515f73187eec773115deb977b4ebc3514","enode":"enode://f62bd19b0fd052207743ce53c3d48a3a71e9219b75e41a9497a43e6368e559d5487ff1ab644f2df4106b500583e4344515f73187eec773115deb977b4ebc3514@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"1/lW0PZEUgJpm/Y3ANpAgjf9zs0n4uitlp5R1+jmFIM=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: d7f956\npopulation: 21 (119), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 7f5f | 52 0047 (0) 06db (0) 0400 (0) 1385 (0)\n001 5 83bc 8311 8ec6 9f97 | 32 9386 (0) 931a (0) 92e2 (0) 954a (0)\n002 5 ebf9 ea94 fba8 f07c | 19 e39e (0) e3c3 (0) e0ac (0) e425 (0)\n003 2 cac9 c243 | 5 c7fd (0) c358 (0) c243 (0) ca97 (0)\n004 3 d80b d916 dc2a | 5 db59 (0) d80b (0) d87f (0) d916 (0)\n005 2 d382 d386 | 3 d192 (0) d386 (0) d382 (0)\n006 1 d552 | 1 d552 (0)\n============ DEPTH: 7 ==========================================\n007 1 d68e | 1 d68e (0)\n008 0 | 0\n009 1 d798 | 1 d798 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"f62bd19b0fd052207743ce53c3d48a3a71e9219b75e41a9497a43e6368e559d5487ff1ab644f2df4106b500583e4344515f73187eec773115deb977b4ebc3514","private_key":"f3d8d6aa0db8c604198cf9a317b45fb96b8407cb029951d7ef06042abedf5e1f","name":"node_f62bd19b0fd052207743ce53c3d48a3a71e9219b75e41a9497a43e6368e559d5487ff1ab644f2df4106b500583e4344515f73187eec773115deb977b4ebc3514","services":["streamer"],"enable_msg_events":true,"port":63156},"up":true}},{"node":{"info":{"id":"a1b2d0c6f24f5924c61e057fc65b994d9a6755560d740018b4c9ad0bb69212ec69974e22cb037dfeb7ea90a4493997f4c94029870bcc5fd47013b51ca0a26b5d","name":"node_a1b2d0c6f24f5924c61e057fc65b994d9a6755560d740018b4c9ad0bb69212ec69974e22cb037dfeb7ea90a4493997f4c94029870bcc5fd47013b51ca0a26b5d","enode":"enode://a1b2d0c6f24f5924c61e057fc65b994d9a6755560d740018b4c9ad0bb69212ec69974e22cb037dfeb7ea90a4493997f4c94029870bcc5fd47013b51ca0a26b5d@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"8p/3NvuUT4+DOaThD2nucvEI7R1otagNBqgUsIB+hoY=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: f29ff7\npopulation: 21 (110), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 06db 2dc2 7628 740b | 44 237b (0) 2650 (0) 2aef (0) 2fee (0)\n001 1 b220 | 31 9386 (0) 92e2 (0) 954a (0) 96b7 (0)\n002 6 c243 cac9 dc2a d916 | 17 c7fd (0) c358 (0) c243 (0) ca97 (0)\n003 5 ebf9 ea94 e0ac e5cd | 9 ec3b (0) ea51 (0) ea94 (0) ebf9 (0)\n004 2 fa62 fba8 | 6 feb3 (0) f995 (0) f80e (0) f836 (0)\n005 0 | 0\n006 1 f07c | 1 f07c (0)\n============ DEPTH: 7 ==========================================\n007 1 f3a1 | 1 f3a1 (0)\n008 0 | 0\n009 0 | 0\n010 1 f2b8 | 1 f2b8 (0)\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"a1b2d0c6f24f5924c61e057fc65b994d9a6755560d740018b4c9ad0bb69212ec69974e22cb037dfeb7ea90a4493997f4c94029870bcc5fd47013b51ca0a26b5d","private_key":"cc5627eea1858ac168bbf1e34a3bb3410ade5b379cde7f67601bbe359506e76d","name":"node_a1b2d0c6f24f5924c61e057fc65b994d9a6755560d740018b4c9ad0bb69212ec69974e22cb037dfeb7ea90a4493997f4c94029870bcc5fd47013b51ca0a26b5d","services":["streamer"],"enable_msg_events":true,"port":63157},"up":true}},{"node":{"info":{"id":"188bf77c9c1e45f009efe7aefdb040bdb47763980fe7eb0851295d657fa2a8978efbd2997c1dc30f4f0874eecf9ca9550487cf41da237b84d071963d35b6baff","name":"node_188bf77c9c1e45f009efe7aefdb040bdb47763980fe7eb0851295d657fa2a8978efbd2997c1dc30f4f0874eecf9ca9550487cf41da237b84d071963d35b6baff","enode":"enode://188bf77c9c1e45f009efe7aefdb040bdb47763980fe7eb0851295d657fa2a8978efbd2997c1dc30f4f0874eecf9ca9550487cf41da237b84d071963d35b6baff@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"siB42bXz1X3sP7F5ZZnV8E/LMtQoiTlDHs6oUWvna1g=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: b22078\npopulation: 13 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 6aef 314e | 60 2fee (0) 2dc2 (0) 2a2b (0) 2aef (0)\n001 3 dc2a d7f9 f29f | 36 c7fd (0) c358 (0) c243 (0) ca97 (0)\n002 4 83bc 97a5 9cbc 9f97 | 20 8bf5 (0) 8c5b (0) 8fe2 (0) 8e31 (0)\n003 1 aa19 | 8 aec5 (0) ac23 (0) a8ba (0) aa19 (0)\n============ DEPTH: 4 ==========================================\n004 2 b9e5 bf7b | 2 b9e5 (0) bf7b (0)\n005 0 | 0\n006 1 b1bf | 1 b1bf (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"188bf77c9c1e45f009efe7aefdb040bdb47763980fe7eb0851295d657fa2a8978efbd2997c1dc30f4f0874eecf9ca9550487cf41da237b84d071963d35b6baff","private_key":"77d99b72e19bbe2da2d6d931653dc7b541dfe27092b944936562bafddd6114fa","name":"node_188bf77c9c1e45f009efe7aefdb040bdb47763980fe7eb0851295d657fa2a8978efbd2997c1dc30f4f0874eecf9ca9550487cf41da237b84d071963d35b6baff","services":["streamer"],"enable_msg_events":true,"port":63158},"up":true}},{"node":{"info":{"id":"f06ec3a90d34300f9fa2d48aea0c6b5f2f01f7833ffb0fad30e7f57e3916e344f3a4f9efe38e222443b8b00d3c7f5221c672491a129e4958e574afc283bd45b1","name":"node_f06ec3a90d34300f9fa2d48aea0c6b5f2f01f7833ffb0fad30e7f57e3916e344f3a4f9efe38e222443b8b00d3c7f5221c672491a129e4958e574afc283bd45b1","enode":"enode://f06ec3a90d34300f9fa2d48aea0c6b5f2f01f7833ffb0fad30e7f57e3916e344f3a4f9efe38e222443b8b00d3c7f5221c672491a129e4958e574afc283bd45b1@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"n5cAyjlfNshKOIOMEfaInQABXZeqx5Q8J890OT4/wi8=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 9f9700\npopulation: 18 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 314e 3f1e | 60 237b (0) 2650 (0) 2a2b (0) 2aef (0)\n001 1 d7f9 | 36 f07c (0) f2b8 (0) f29f (0) f3a1 (0)\n002 2 bf7b b220 | 12 ac23 (0) aec5 (0) a8ba (0) aa19 (0)\n003 6 8311 83bc 8230 87e0 | 10 87e0 (0) 811d (0) 8230 (0) 8311 (0)\n004 5 9386 92e2 954a 96e9 | 7 931a (0) 9386 (0) 92e2 (0) 954a (0)\n============ DEPTH: 5 ==========================================\n005 1 981b | 1 981b (0)\n006 1 9cbc | 1 9cbc (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"f06ec3a90d34300f9fa2d48aea0c6b5f2f01f7833ffb0fad30e7f57e3916e344f3a4f9efe38e222443b8b00d3c7f5221c672491a129e4958e574afc283bd45b1","private_key":"e6874592c3f2d2fa94b126d565cec571767e64ef9067970a9f8d1f8ce7e88d0f","name":"node_f06ec3a90d34300f9fa2d48aea0c6b5f2f01f7833ffb0fad30e7f57e3916e344f3a4f9efe38e222443b8b00d3c7f5221c672491a129e4958e574afc283bd45b1","services":["streamer"],"enable_msg_events":true,"port":63159},"up":true}},{"node":{"info":{"id":"3c6faa2e75a1699ddadd0e21fd35d3d6215715cfdc2dc89961cfd66773d2541776e785f3ebc833a70e3d1017a4edc571a5d5d9f9fbfc3fa0a8588f6c5023c164","name":"node_3c6faa2e75a1699ddadd0e21fd35d3d6215715cfdc2dc89961cfd66773d2541776e785f3ebc833a70e3d1017a4edc571a5d5d9f9fbfc3fa0a8588f6c5023c164","enode":"enode://3c6faa2e75a1699ddadd0e21fd35d3d6215715cfdc2dc89961cfd66773d2541776e785f3ebc833a70e3d1017a4edc571a5d5d9f9fbfc3fa0a8588f6c5023c164@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"jsZjwi7/jtGFuBlMEkD/WN8THF8xDfCpG5eQ7BZuQ0Y=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 8ec663\npopulation: 19 (126), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 314e 3f1e | 60 237b (0) 2650 (0) 2dc2 (0) 2fee (0)\n001 2 d7f9 f2b8 | 35 d87f (0) d80b (0) d916 (0) db59 (0)\n002 1 bf7b | 12 aa19 (0) a8ba (0) aec5 (0) ac23 (0)\n003 6 92e2 96e9 97a5 981b | 10 981b (0) 9cbc (0) 9f97 (0) 931a (0)\n004 4 87e0 8230 8311 83bc | 5 87e0 (0) 811d (0) 8230 (0) 8311 (0)\n005 1 8bf5 | 1 8bf5 (0)\n006 1 8c5b | 1 8c5b (0)\n============ DEPTH: 7 ==========================================\n007 1 8fe2 | 1 8fe2 (0)\n008 1 8e31 | 1 8e31 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"3c6faa2e75a1699ddadd0e21fd35d3d6215715cfdc2dc89961cfd66773d2541776e785f3ebc833a70e3d1017a4edc571a5d5d9f9fbfc3fa0a8588f6c5023c164","private_key":"d733b22563798aae07facf0a489367c7cf0d6d3ebf786992b6ae98696d295cd2","name":"node_3c6faa2e75a1699ddadd0e21fd35d3d6215715cfdc2dc89961cfd66773d2541776e785f3ebc833a70e3d1017a4edc571a5d5d9f9fbfc3fa0a8588f6c5023c164","services":["streamer"],"enable_msg_events":true,"port":63160},"up":true}},{"node":{"info":{"id":"56e8f792ec9a75ec9e91d472b8a4b023655dd68c2a448a33397b125fe3584a5efa1b492e47077b24acfe0396b73e1cb564a6a6b2aee1b457781dfaf6d43fcaed","name":"node_56e8f792ec9a75ec9e91d472b8a4b023655dd68c2a448a33397b125fe3584a5efa1b492e47077b24acfe0396b73e1cb564a6a6b2aee1b457781dfaf6d43fcaed","enode":"enode://56e8f792ec9a75ec9e91d472b8a4b023655dd68c2a448a33397b125fe3584a5efa1b492e47077b24acfe0396b73e1cb564a6a6b2aee1b457781dfaf6d43fcaed@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"8rgJ6X08OmUsTdzhnKErAcHeJfLOAH1WH9VgboVUDWQ=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: f2b809\npopulation: 17 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 3f1e 2aef | 60 2650 (0) 237b (0) 2fee (0) 2dc2 (0)\n001 2 8ec6 97a5 | 32 ac23 (0) aec5 (0) a8ba (0) aa19 (0)\n002 4 d552 d80b d916 dc2a | 17 db59 (0) d87f (0) d80b (0) d916 (0)\n003 4 ebf9 e0ac e425 e5cd | 9 ec3b (0) ea51 (0) ea94 (0) ebf9 (0)\n004 2 fba8 fa62 | 6 feb3 (0) f995 (0) f80e (0) f836 (0)\n005 0 | 0\n006 1 f07c | 1 f07c (0)\n============ DEPTH: 7 ==========================================\n007 1 f3a1 | 1 f3a1 (0)\n008 0 | 0\n009 0 | 0\n010 1 f29f | 1 f29f (0)\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"56e8f792ec9a75ec9e91d472b8a4b023655dd68c2a448a33397b125fe3584a5efa1b492e47077b24acfe0396b73e1cb564a6a6b2aee1b457781dfaf6d43fcaed","private_key":"145ffd39a00647c0142f3bce7ba2f21f4e168663488e0683b4c8cc72afa7b02b","name":"node_56e8f792ec9a75ec9e91d472b8a4b023655dd68c2a448a33397b125fe3584a5efa1b492e47077b24acfe0396b73e1cb564a6a6b2aee1b457781dfaf6d43fcaed","services":["streamer"],"enable_msg_events":true,"port":63161},"up":true}},{"node":{"info":{"id":"3572a22097a313b3adef95a7b6cc679f8d1201a156d764e61a9fbc63d123fb4826f7125402fb6569beed359e1c1e5e6cb6993a75975da6cd4ce15669a2eea758","name":"node_3572a22097a313b3adef95a7b6cc679f8d1201a156d764e61a9fbc63d123fb4826f7125402fb6569beed359e1c1e5e6cb6993a75975da6cd4ce15669a2eea758","enode":"enode://3572a22097a313b3adef95a7b6cc679f8d1201a156d764e61a9fbc63d123fb4826f7125402fb6569beed359e1c1e5e6cb6993a75975da6cd4ce15669a2eea758@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"l6WVm5VmL26CChsBGn6HVo4O/SJXpzv5GGjJjEblpXE=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 97a595\npopulation: 14 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 2fee | 60 57df (0) 500f (0) 53ea (0) 5d6d (0)\n001 1 f2b8 | 36 db59 (0) d916 (0) d80b (0) d87f (0)\n002 1 b220 | 12 ac23 (0) aec5 (0) a8ba (0) aa19 (0)\n003 3 8bf5 8fe2 8ec6 | 10 87e0 (0) 811d (0) 8230 (0) 8311 (0)\n004 3 981b 9cbc 9f97 | 3 981b (0) 9cbc (0) 9f97 (0)\n005 2 9386 92e2 | 3 931a (0) 9386 (0) 92e2 (0)\n006 1 954a | 1 954a (0)\n============ DEPTH: 7 ==========================================\n007 2 96b7 96e9 | 2 96b7 (0) 96e9 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"3572a22097a313b3adef95a7b6cc679f8d1201a156d764e61a9fbc63d123fb4826f7125402fb6569beed359e1c1e5e6cb6993a75975da6cd4ce15669a2eea758","private_key":"83fa451e08386b0966a5b8ec4b56c861bc367f0cbaa7e6e3a8c20564dbc0f1af","name":"node_3572a22097a313b3adef95a7b6cc679f8d1201a156d764e61a9fbc63d123fb4826f7125402fb6569beed359e1c1e5e6cb6993a75975da6cd4ce15669a2eea758","services":["streamer"],"enable_msg_events":true,"port":63162},"up":true}},{"node":{"info":{"id":"e3f2e777a96b2137b3104b84d5d827d484eac9ee1b585430e09f790d7e26978da12802325927c3c483bc19973e09cd3f70c513c34798e5da650f8d2f0c8c5c47","name":"node_e3f2e777a96b2137b3104b84d5d827d484eac9ee1b585430e09f790d7e26978da12802325927c3c483bc19973e09cd3f70c513c34798e5da650f8d2f0c8c5c47","enode":"enode://e3f2e777a96b2137b3104b84d5d827d484eac9ee1b585430e09f790d7e26978da12802325927c3c483bc19973e09cd3f70c513c34798e5da650f8d2f0c8c5c47@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"L+7WawO3sFfhpko/h3rZworaluMLmKeDk7VOoxuY9Po=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 2feed6\npopulation: 11 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 97a5 | 68 d80b (0) d87f (0) d916 (0) db59 (0)\n001 1 6ac7 | 37 57df (0) 500f (0) 53ea (0) 5d6d (0)\n002 1 1385 | 11 11a6 (0) 1385 (0) 1ea8 (0) 1f2a (0)\n003 3 3e4f 3f1e 314e | 6 3d3a (0) 3e4f (0) 3f1e (0) 30a0 (0)\n004 2 237b 2650 | 2 237b (0) 2650 (0)\n============ DEPTH: 5 ==========================================\n005 2 2a2b 2aef | 2 2a2b (0) 2aef (0)\n006 1 2dc2 | 1 2dc2 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"e3f2e777a96b2137b3104b84d5d827d484eac9ee1b585430e09f790d7e26978da12802325927c3c483bc19973e09cd3f70c513c34798e5da650f8d2f0c8c5c47","private_key":"2057ae928cb89d7759bda21739956c8527bf11bb02571ee2e9bda07702779aae","name":"node_e3f2e777a96b2137b3104b84d5d827d484eac9ee1b585430e09f790d7e26978da12802325927c3c483bc19973e09cd3f70c513c34798e5da650f8d2f0c8c5c47","services":["streamer"],"enable_msg_events":true,"port":63163},"up":true}},{"node":{"info":{"id":"1480f62d85ea32226d9f77ccd31780b3e704fb60618a588ae85dcd1c0e84e878c5fc092adfb306e8ebc7abba9ec429cb2447754502ef847cf931467f31fa50b2","name":"node_1480f62d85ea32226d9f77ccd31780b3e704fb60618a588ae85dcd1c0e84e878c5fc092adfb306e8ebc7abba9ec429cb2447754502ef847cf931467f31fa50b2","enode":"enode://1480f62d85ea32226d9f77ccd31780b3e704fb60618a588ae85dcd1c0e84e878c5fc092adfb306e8ebc7abba9ec429cb2447754502ef847cf931467f31fa50b2@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"ascdVemEq+Mjx06oWsGu0bBuVmMsB8OJ54AmgnSiOBA=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 6ac71d\npopulation: 15 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 92e2 | 68 ec3b (0) ea94 (0) ea51 (0) ebf9 (0)\n001 1 2fee | 23 11a6 (0) 1385 (0) 1ea8 (0) 1f2a (0)\n002 2 5b36 53ea | 16 57df (0) 500f (0) 53ea (0) 5d6d (0)\n003 4 7e65 7f62 7f5f 78bf | 9 740b (0) 7692 (0) 7628 (0) 7bcf (0)\n004 2 6632 6120 | 5 6640 (0) 6632 (0) 6099 (0) 60ad (0)\n005 2 6cf1 6c1f | 3 6e83 (0) 6c1f (0) 6cf1 (0)\n006 1 6838 | 1 6838 (0)\n007 0 | 0\n============ DEPTH: 8 ==========================================\n008 1 6a57 | 1 6a57 (0)\n009 0 | 0\n010 1 6aef | 1 6aef (0)\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"1480f62d85ea32226d9f77ccd31780b3e704fb60618a588ae85dcd1c0e84e878c5fc092adfb306e8ebc7abba9ec429cb2447754502ef847cf931467f31fa50b2","private_key":"4fb682db9263cc8ae4d32757a0837296654120fc17593b9d0c3219a307193655","name":"node_1480f62d85ea32226d9f77ccd31780b3e704fb60618a588ae85dcd1c0e84e878c5fc092adfb306e8ebc7abba9ec429cb2447754502ef847cf931467f31fa50b2","services":["streamer"],"enable_msg_events":true,"port":63164},"up":true}},{"node":{"info":{"id":"3540d888c3207d6df233afd1164ff9dde2551730862772547e04f7311de364968e113f38a7dea1ab0916a7f8307017de5b49578fa4ebcc39651e541fde51be48","name":"node_3540d888c3207d6df233afd1164ff9dde2551730862772547e04f7311de364968e113f38a7dea1ab0916a7f8307017de5b49578fa4ebcc39651e541fde51be48","enode":"enode://3540d888c3207d6df233afd1164ff9dde2551730862772547e04f7311de364968e113f38a7dea1ab0916a7f8307017de5b49578fa4ebcc39651e541fde51be48@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"kuL47DAeWFj3Fot4UECVXSi/+uDJjl0/Wf+fqGNv5CM=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 92e2f8\npopulation: 20 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 4236 6ac7 | 60 11a6 (0) 1385 (0) 1ea8 (0) 1f2a (0)\n001 3 f07c ebf9 ea51 | 36 ec3b (0) ea94 (0) ea51 (0) ebf9 (0)\n002 5 a60b aa19 a8ba aec5 | 12 ac23 (0) aec5 (0) a8ba (0) aa19 (0)\n003 1 8ec6 | 10 8bf5 (0) 8c5b (0) 8e31 (0) 8ec6 (0)\n004 3 9cbc 9f97 981b | 3 981b (0) 9f97 (0) 9cbc (0)\n005 4 954a 97a5 96b7 96e9 | 4 954a (0) 97a5 (0) 96b7 (0) 96e9 (0)\n006 0 | 0\n============ DEPTH: 7 ==========================================\n007 2 931a 9386 | 2 931a (0) 9386 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"3540d888c3207d6df233afd1164ff9dde2551730862772547e04f7311de364968e113f38a7dea1ab0916a7f8307017de5b49578fa4ebcc39651e541fde51be48","private_key":"7f212e2fa6d29b93f32d27a27b02eab5b9aa946ba044f1a20bada9f7db133907","name":"node_3540d888c3207d6df233afd1164ff9dde2551730862772547e04f7311de364968e113f38a7dea1ab0916a7f8307017de5b49578fa4ebcc39651e541fde51be48","services":["streamer"],"enable_msg_events":true,"port":63165},"up":true}},{"node":{"info":{"id":"077bcadade93e0d361e94f76dff464d61912bc067ce2ce17ebcabd757cca201cd64624ea809d99dd8ecb749d40528db9b3eb503ef5ec05e8845044cfaef720dc","name":"node_077bcadade93e0d361e94f76dff464d61912bc067ce2ce17ebcabd757cca201cd64624ea809d99dd8ecb749d40528db9b3eb503ef5ec05e8845044cfaef720dc","enode":"enode://077bcadade93e0d361e94f76dff464d61912bc067ce2ce17ebcabd757cca201cd64624ea809d99dd8ecb749d40528db9b3eb503ef5ec05e8845044cfaef720dc@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"QjZcsTTjKecgVVmDj5JK/+qJPIMuqdhsThsZ7Cxs5bE=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 42365c\npopulation: 23 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 92e2 dc2a cac9 | 68 ac23 (0) aec5 (0) a8ba (0) aa19 (0)\n001 3 1f2a 2dc2 314e | 23 237b (0) 2650 (0) 2dc2 (0) 2fee (0)\n002 4 6640 6632 78bf 7f5f | 21 6640 (0) 6632 (0) 60ad (0) 6099 (0)\n003 3 57df 53ea 5b36 | 5 57df (0) 500f (0) 53ea (0) 5d6d (0)\n004 3 4827 48a1 4ae6 | 3 4827 (0) 48a1 (0) 4ae6 (0)\n005 2 4454 4778 | 2 4454 (0) 4778 (0)\n006 2 4124 4087 | 2 4124 (0) 4087 (0)\n============ DEPTH: 7 ==========================================\n007 2 4309 436c | 2 4309 (0) 436c (0)\n008 0 | 0\n009 1 4259 | 1 4259 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"077bcadade93e0d361e94f76dff464d61912bc067ce2ce17ebcabd757cca201cd64624ea809d99dd8ecb749d40528db9b3eb503ef5ec05e8845044cfaef720dc","private_key":"d209b8a302d27579c28dd86104e2eab3c74101ff06bb17200388b614ec3f05ff","name":"node_077bcadade93e0d361e94f76dff464d61912bc067ce2ce17ebcabd757cca201cd64624ea809d99dd8ecb749d40528db9b3eb503ef5ec05e8845044cfaef720dc","services":["streamer"],"enable_msg_events":true,"port":63166},"up":true}},{"node":{"info":{"id":"73be4d2291c68ca4554a86fa170f7595210e1b6bbbeef3c1d5623a2b5d03a8fd6e26caa26afc639c20c8a351a89dad1086f91734f09afab62d28ec17b700fa01","name":"node_73be4d2291c68ca4554a86fa170f7595210e1b6bbbeef3c1d5623a2b5d03a8fd6e26caa26afc639c20c8a351a89dad1086f91734f09afab62d28ec17b700fa01","enode":"enode://73be4d2291c68ca4554a86fa170f7595210e1b6bbbeef3c1d5623a2b5d03a8fd6e26caa26afc639c20c8a351a89dad1086f91734f09afab62d28ec17b700fa01@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"ysl8cCYYSi1rorF/zQxUQL7FOJYa+DamDy+tt4oxCnc=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: cac97c\npopulation: 17 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 6a57 78bf 4236 | 60 237b (0) 2650 (0) 2dc2 (0) 2fee (0)\n001 3 981b 8bf5 ac23 | 32 ac23 (0) aec5 (0) a8ba (0) aa19 (0)\n002 2 f07c f29f | 19 ec3b (0) ea94 (0) ea51 (0) ebf9 (0)\n003 5 d798 d7f9 d68e db59 | 12 db59 (0) d80b (0) d87f (0) d916 (0)\n============ DEPTH: 4 ==========================================\n004 3 c7fd c358 c243 | 3 c7fd (0) c358 (0) c243 (0)\n005 0 | 0\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 1 ca97 | 1 ca97 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"73be4d2291c68ca4554a86fa170f7595210e1b6bbbeef3c1d5623a2b5d03a8fd6e26caa26afc639c20c8a351a89dad1086f91734f09afab62d28ec17b700fa01","private_key":"f0317274abc992d76728cf9a59b6dfd16b1422fea0c0089a47f0cbffbce53c34","name":"node_73be4d2291c68ca4554a86fa170f7595210e1b6bbbeef3c1d5623a2b5d03a8fd6e26caa26afc639c20c8a351a89dad1086f91734f09afab62d28ec17b700fa01","services":["streamer"],"enable_msg_events":true,"port":63167},"up":true}},{"node":{"info":{"id":"a5cdff211813e17fadd43ec55a6cf4e97e6ca0c3b2cef0db58923b27d36207fd1a77146efb6093bd94d7eb89cc77d8c735fc64ab098839efc74a00b5e8687555","name":"node_a5cdff211813e17fadd43ec55a6cf4e97e6ca0c3b2cef0db58923b27d36207fd1a77146efb6093bd94d7eb89cc77d8c735fc64ab098839efc74a00b5e8687555","enode":"enode://a5cdff211813e17fadd43ec55a6cf4e97e6ca0c3b2cef0db58923b27d36207fd1a77146efb6093bd94d7eb89cc77d8c735fc64ab098839efc74a00b5e8687555@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"eL+vEi0Q7l5TBP3SR0NMArMt5Xe7QQ3ATY/+GQYpT9s=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 78bfaf\npopulation: 18 (113), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 cac9 | 55 ac23 (0) a8ba (0) aa19 (0) a12e (0)\n001 4 3f1e 0047 0400 18f6 | 22 237b (0) 2650 (0) 2a2b (0) 2aef (0)\n002 4 4236 4778 5b36 53ea | 16 57df (0) 500f (0) 53ea (0) 5d6d (0)\n003 3 6e83 6ac7 6a57 | 12 6099 (0) 60ad (0) 6120 (0) 6640 (0)\n004 1 7692 | 3 740b (0) 7628 (0) 7692 (0)\n============ DEPTH: 5 ==========================================\n005 4 7c76 7e65 7f62 7f5f | 4 7c76 (0) 7e65 (0) 7f62 (0) 7f5f (0)\n006 1 7bcf | 1 7bcf (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"a5cdff211813e17fadd43ec55a6cf4e97e6ca0c3b2cef0db58923b27d36207fd1a77146efb6093bd94d7eb89cc77d8c735fc64ab098839efc74a00b5e8687555","private_key":"8d5bfe9aaf70d634b185efff991adfde6d80ee5d1c60e68eb1a105c17a4e03af","name":"node_a5cdff211813e17fadd43ec55a6cf4e97e6ca0c3b2cef0db58923b27d36207fd1a77146efb6093bd94d7eb89cc77d8c735fc64ab098839efc74a00b5e8687555","services":["streamer"],"enable_msg_events":true,"port":63168},"up":true}},{"node":{"info":{"id":"27fb8fcda1986644f985d68430c399f0299644b00b234c355362721081d12f9eb7686eea8f92eabda1d342bf56255e51c07b200c6233f95ac009f15b874eee97","name":"node_27fb8fcda1986644f985d68430c399f0299644b00b234c355362721081d12f9eb7686eea8f92eabda1d342bf56255e51c07b200c6233f95ac009f15b874eee97","enode":"enode://27fb8fcda1986644f985d68430c399f0299644b00b234c355362721081d12f9eb7686eea8f92eabda1d342bf56255e51c07b200c6233f95ac009f15b874eee97@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"alfNNV1kHRUGlXqYjZOy0/mmE6c1TCQTCtl9vEyCls4=","hive":"\n=========================================================================\nTue Apr 10 09:56:22 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 6a57cd\npopulation: 21 (102), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 cac9 8230 96e9 | 46 ea94 (0) ea51 (0) ebf9 (0) e5cd (0)\n001 2 0047 18f6 | 21 2650 (0) 2dc2 (0) 2fee (0) 2a2b (0)\n002 4 4ae6 53ea 500f 5b36 | 16 4827 (0) 48a1 (0) 4ae6 (0) 4454 (0)\n003 5 7692 7628 740b 7f5f | 9 740b (0) 7692 (0) 7628 (0) 7c76 (0)\n004 1 6120 | 4 6640 (0) 6632 (0) 60ad (0) 6120 (0)\n005 3 6e83 6cf1 6c1f | 3 6e83 (0) 6cf1 (0) 6c1f (0)\n006 1 6838 | 1 6838 (0)\n007 0 | 0\n============ DEPTH: 8 ==========================================\n008 2 6aef 6ac7 | 2 6aef (0) 6ac7 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"27fb8fcda1986644f985d68430c399f0299644b00b234c355362721081d12f9eb7686eea8f92eabda1d342bf56255e51c07b200c6233f95ac009f15b874eee97","private_key":"bd99f18955320e921a98f8103d8b4c1713d800d49c0a7bc946cb52fdf79e03d4","name":"node_27fb8fcda1986644f985d68430c399f0299644b00b234c355362721081d12f9eb7686eea8f92eabda1d342bf56255e51c07b200c6233f95ac009f15b874eee97","services":["streamer"],"enable_msg_events":true,"port":63169},"up":true}}],"conns":[{"one":"3103510e00a3f49a5e715719049fc8c9c67a2373a548f326458aeb6d9c75ed92b94373638fd075def0209113b4e85d972c23f064539f7b041596184e40d7f9a2","other":"077d2d032874e5ce70e9b928b7fe72c0326ba92394e16245e31d48b5731d3d32bfd86acf40825decff54bcd735e9ebfd94eba677c418ea7007baec9db4af676d","up":true},{"one":"51ba4faf0988717a37dcddc0a60a70ead33bde310184fc450f9ca73c67f931e6767ad5930bcf409e5aeb613a9ff7a03e47de6fc13b33d8af0b87b38822ae6888","other":"750ca601f07d65f426f6ea5f34e06238f9d7a931f022f9b0ebc811943d3725500cb3c6f00c8d05eb8d5b353c6534136dff38b9a8d3d4dc5bf49cd96875704d07","up":true},{"one":"31ac37862416c0e229c4a088ec179f23bdd1bf12dd464eb11c630ad531d7c3438671862e5458e2f6fbb32b857f857e6b8c17e5d93eb29a0e78bb5a65d7eb648c","other":"1e3c83cabbe6852c987ae521b7fcb33185cf855c59b6235ebb8e57a6f860ccc159ddc01b4a21d251c8faca4559ceb271e046a51493ba148c0d3aed97ad208969","up":true},{"one":"750ca601f07d65f426f6ea5f34e06238f9d7a931f022f9b0ebc811943d3725500cb3c6f00c8d05eb8d5b353c6534136dff38b9a8d3d4dc5bf49cd96875704d07","other":"41994605708232b4ca7448c3bc0760a7b86bf26d442091e5ce6e92eac94925721d7e0eca04bdd03bb1bba1ef92deeccd4bf1b7c6c3318b7e8d031965c6646761","up":true},{"one":"077d2d032874e5ce70e9b928b7fe72c0326ba92394e16245e31d48b5731d3d32bfd86acf40825decff54bcd735e9ebfd94eba677c418ea7007baec9db4af676d","other":"d90a81a583c82d626b92f27244f027da4a0ae76e6d3bdc1de0af7be01798f1fb04b34ce60c6d8651a39d7a70915438a4aa63e5adf844a9f7e38dbf0b1dba754d","up":true},{"one":"d90a81a583c82d626b92f27244f027da4a0ae76e6d3bdc1de0af7be01798f1fb04b34ce60c6d8651a39d7a70915438a4aa63e5adf844a9f7e38dbf0b1dba754d","other":"31ac37862416c0e229c4a088ec179f23bdd1bf12dd464eb11c630ad531d7c3438671862e5458e2f6fbb32b857f857e6b8c17e5d93eb29a0e78bb5a65d7eb648c","up":true},{"one":"a9e0b763852706722dc904b494293f9399c0fa32255890aa720285b8160335bb618f36b68a81b875a805384179f600defef474d486b4ea04b003ef6477ab7907","other":"87e696a354d249493217dc4e0190082f30e09616873803efa376871d4b34f86f0eeb4643d4822d8a0fbcdedb27cd6ba5438e98943d358d960c4835e82261c93e","up":true},{"one":"2fdb4382c4bc2950948a8cff13a7df65627bc0b20661cae20fd29acab166c97701594ee3151d75c006ba86d1d68b624b1d1f78e3d1e2fc297844956ef82208a8","other":"87fce129511a1be2777052d24b606acdfe7067f4e874ab04674a68664b378ea208975f7269a72af889d3d23cd930b6a181afa2cdef3f9f9491f715bd96ad8dc0","up":true},{"one":"c773af3af01ee8ab9fa8d06987baf4f10c394fdd386d69b7a7362f4b68fd6fc082337d3b33a19d584c5801a3e9198225d7b61f6629e34ce823be70908339f4c7","other":"56b25623ac935f3a8aac1e2603a6bd15ace1e5714671954b47f2cab960cf47922828f415105602408d0a732a893ebeea6f9afab7f889bb235c81589548d09391","up":true},{"one":"87e696a354d249493217dc4e0190082f30e09616873803efa376871d4b34f86f0eeb4643d4822d8a0fbcdedb27cd6ba5438e98943d358d960c4835e82261c93e","other":"18bb6572965f4263c5a4d59a73027abc57a46122125ee58d871e95c993e6a1e8230438ce696a5f8880a08749837268b54319f7b0aa254c1a5bd453a8e9bcf84f","up":true},{"one":"87fce129511a1be2777052d24b606acdfe7067f4e874ab04674a68664b378ea208975f7269a72af889d3d23cd930b6a181afa2cdef3f9f9491f715bd96ad8dc0","other":"c773af3af01ee8ab9fa8d06987baf4f10c394fdd386d69b7a7362f4b68fd6fc082337d3b33a19d584c5801a3e9198225d7b61f6629e34ce823be70908339f4c7","up":true},{"one":"1e3c83cabbe6852c987ae521b7fcb33185cf855c59b6235ebb8e57a6f860ccc159ddc01b4a21d251c8faca4559ceb271e046a51493ba148c0d3aed97ad208969","other":"2fdb4382c4bc2950948a8cff13a7df65627bc0b20661cae20fd29acab166c97701594ee3151d75c006ba86d1d68b624b1d1f78e3d1e2fc297844956ef82208a8","up":true},{"one":"da3e0fd71eb96ba2cab7f920d32f5425d1aad41d00765fdffb0b215d9dd5b60e2bc5929eafebee5b2b5a11aec164e141beff19d828aac7d1fabd3ffb0bfb8450","other":"489660042a8867d90a16ebb013968db26ca3edfc70f53320f511e35b3703eed09fbd787be5c06726a570a54aa15d129cd10db741523adf297929f909be4a0c71","up":true},{"one":"18bb6572965f4263c5a4d59a73027abc57a46122125ee58d871e95c993e6a1e8230438ce696a5f8880a08749837268b54319f7b0aa254c1a5bd453a8e9bcf84f","other":"3103510e00a3f49a5e715719049fc8c9c67a2373a548f326458aeb6d9c75ed92b94373638fd075def0209113b4e85d972c23f064539f7b041596184e40d7f9a2","up":true},{"one":"09b60de1e85bb6f7d2caf5b1ab58204d7d04531ece300dcd7bcc9157b8b3ef2a182758808a0eec6056034f29f52caadb7c690f498c1c8832ff7a6a9ecff308bd","other":"f2ea93f43be9d0c3fa21f1496dc13c778977a6afdcba24c8b146de7dca2cdde62a5b792aab969e5b4b6c56f63066b336580d911f206049cc24cac32a25fc4306","up":true},{"one":"f2ea93f43be9d0c3fa21f1496dc13c778977a6afdcba24c8b146de7dca2cdde62a5b792aab969e5b4b6c56f63066b336580d911f206049cc24cac32a25fc4306","other":"872cdbb6d74fb55fd2d51877ef7804bdd2eeb6de0297eb2ce18b67e52379b147d54a46d2385ec9293eb21736bed4191d92c5c75e8e81fc5a6c691970e019f570","up":true},{"one":"4448a59bde9edb93edcdb4a77f3e2277b9c01ffea45496ee0533eb5192955a08a0f982e25cf772e0dae68735a55b7acd221f6ba7b134f1e999087bee182330e8","other":"73319a301ad3cf0ec09549d817c9523d61b74abb0cad87b737d41d900321e52722a84355f6f87bc7a5f848818c89a021bb0f3e5994f67c9a7b5bbfc98188a376","up":true},{"one":"56b25623ac935f3a8aac1e2603a6bd15ace1e5714671954b47f2cab960cf47922828f415105602408d0a732a893ebeea6f9afab7f889bb235c81589548d09391","other":"09b60de1e85bb6f7d2caf5b1ab58204d7d04531ece300dcd7bcc9157b8b3ef2a182758808a0eec6056034f29f52caadb7c690f498c1c8832ff7a6a9ecff308bd","up":true},{"one":"872cdbb6d74fb55fd2d51877ef7804bdd2eeb6de0297eb2ce18b67e52379b147d54a46d2385ec9293eb21736bed4191d92c5c75e8e81fc5a6c691970e019f570","other":"da3e0fd71eb96ba2cab7f920d32f5425d1aad41d00765fdffb0b215d9dd5b60e2bc5929eafebee5b2b5a11aec164e141beff19d828aac7d1fabd3ffb0bfb8450","up":true},{"one":"73319a301ad3cf0ec09549d817c9523d61b74abb0cad87b737d41d900321e52722a84355f6f87bc7a5f848818c89a021bb0f3e5994f67c9a7b5bbfc98188a376","other":"caad8529d498a4a1e1ba7573689a913500bd409345ef8e3656abca748269eb73b919282f7f2eb0087f81f7bc52c367657ac8be0cdac65d2490c7c50c874444b7","up":true},{"one":"caad8529d498a4a1e1ba7573689a913500bd409345ef8e3656abca748269eb73b919282f7f2eb0087f81f7bc52c367657ac8be0cdac65d2490c7c50c874444b7","other":"44462055ba68fdef337dd19d8123aace9a12284c13bc97687416b6b4ca0c94234ba7db6823651fc021d6ac1539e0c5321e763a7a12c9e7c8a583aac5369817d8","up":true},{"one":"489660042a8867d90a16ebb013968db26ca3edfc70f53320f511e35b3703eed09fbd787be5c06726a570a54aa15d129cd10db741523adf297929f909be4a0c71","other":"4448a59bde9edb93edcdb4a77f3e2277b9c01ffea45496ee0533eb5192955a08a0f982e25cf772e0dae68735a55b7acd221f6ba7b134f1e999087bee182330e8","up":true},{"one":"44462055ba68fdef337dd19d8123aace9a12284c13bc97687416b6b4ca0c94234ba7db6823651fc021d6ac1539e0c5321e763a7a12c9e7c8a583aac5369817d8","other":"ecbdca037cd7892752345b48b4219478b1b334f83ce7140fcc72eb71784436b690ce7a41b03e013cefc19d64a34a20cfef1b9e2b535d938bcdcb39fe63645a42","up":true},{"one":"41994605708232b4ca7448c3bc0760a7b86bf26d442091e5ce6e92eac94925721d7e0eca04bdd03bb1bba1ef92deeccd4bf1b7c6c3318b7e8d031965c6646761","other":"28afc20d8f4779b285bb14870062dbb54796ec77623302e51bc1bafed9e2c35751c8469ffc482718e059875dfa2226195ed10999e251498cba3a444896cb67db","up":true},{"one":"28afc20d8f4779b285bb14870062dbb54796ec77623302e51bc1bafed9e2c35751c8469ffc482718e059875dfa2226195ed10999e251498cba3a444896cb67db","other":"805d784527be4e32e84ddf045baee1ccf348cdf8288de3aae1a5379f762576b957525ef358d9b42c68a93394017880adc09bb2b1b5e01102dc7e4240baf2af95","up":true},{"one":"805d784527be4e32e84ddf045baee1ccf348cdf8288de3aae1a5379f762576b957525ef358d9b42c68a93394017880adc09bb2b1b5e01102dc7e4240baf2af95","other":"9c6dcfef0e128dbfeca58b8ac625b08fb447b0d579bd3f18bc0e2be60d1ec2274595d0554ddba0ca7eb660099d3ea146d8076792b46c93841d2ecf8cf608f5ba","up":true},{"one":"e9f7e58fda4b504275441d51929fbc98214abdc9ed552c7aa94c600a85d4e791d60c032304b29ae028adccec94984fc9a3d705a81462632f50ef45024eb0f64e","other":"9e6c1c6e871638182c4b54ac89352ef5c2bca0a99424a1369013e7c182883da0e8d7ab96b3c8254c31fa315b941d8ddee153157626821fc78c2cae951c1c9053","up":true},{"one":"93987e431a0058f2e942ccf8d3486d249cd2734d6494131b343e2c3a8fdd86cfcb12d0aaaf8fcb911ad3cdd682cc82118198195a7fdc915ab7853223f012eab6","other":"665c3288c14dc1c17d85d17d634910f42183482c7e77c47e68f9b4f475b93e8c152246b9e34781606315ff6ef0f8360342500d15e4a2d67d9df6b72f30af64a7","up":true},{"one":"9e6c1c6e871638182c4b54ac89352ef5c2bca0a99424a1369013e7c182883da0e8d7ab96b3c8254c31fa315b941d8ddee153157626821fc78c2cae951c1c9053","other":"bfef26733f5196a11484bcc28d88776e747189ae7cec883ff39a27cfeee6d9d1efb34560c9f8e75eec43fc069a2ce5f0c78107a36cc8a569d37bd5306aecf23a","up":true},{"one":"bfef26733f5196a11484bcc28d88776e747189ae7cec883ff39a27cfeee6d9d1efb34560c9f8e75eec43fc069a2ce5f0c78107a36cc8a569d37bd5306aecf23a","other":"f6a07a1d361a4671e997d5eaadae61736291aff3896cb69f06bbc19bf7536dd152e0b15422b2fd9f8a9d2f9a251c9a07d0140319900e2cc9f25a59025c7dc91f","up":true},{"one":"665c3288c14dc1c17d85d17d634910f42183482c7e77c47e68f9b4f475b93e8c152246b9e34781606315ff6ef0f8360342500d15e4a2d67d9df6b72f30af64a7","other":"562119edffe8270f6f7a5ad9b13d4c65d643e52a2331d1fee16f7e9b5567f44cfea62df3e8965a22cf08db8fa918f0a0bcae8da2936677e6d25bc88ed85ed2f1","up":true},{"one":"27fb8fcda1986644f985d68430c399f0299644b00b234c355362721081d12f9eb7686eea8f92eabda1d342bf56255e51c07b200c6233f95ac009f15b874eee97","other":"a9e0b763852706722dc904b494293f9399c0fa32255890aa720285b8160335bb618f36b68a81b875a805384179f600defef474d486b4ea04b003ef6477ab7907","up":true},{"one":"ecbdca037cd7892752345b48b4219478b1b334f83ce7140fcc72eb71784436b690ce7a41b03e013cefc19d64a34a20cfef1b9e2b535d938bcdcb39fe63645a42","other":"51ba4faf0988717a37dcddc0a60a70ead33bde310184fc450f9ca73c67f931e6767ad5930bcf409e5aeb613a9ff7a03e47de6fc13b33d8af0b87b38822ae6888","up":true},{"one":"f6a07a1d361a4671e997d5eaadae61736291aff3896cb69f06bbc19bf7536dd152e0b15422b2fd9f8a9d2f9a251c9a07d0140319900e2cc9f25a59025c7dc91f","other":"08900197e74e285a5a8a9cc53fbd420bb35043ab27eb2d9eab22615e736a093abfa235c17f667dcc791cb50b9022082eafd9fba030194cc84f0358b769adc85b","up":true},{"one":"562119edffe8270f6f7a5ad9b13d4c65d643e52a2331d1fee16f7e9b5567f44cfea62df3e8965a22cf08db8fa918f0a0bcae8da2936677e6d25bc88ed85ed2f1","other":"2502fc8ee0ccda79ad1dbd9c7cec625da85980b9116bdd56dc367d508039e25e5f65183293006e5b0df72fa9037a48bd2b133a757940d3587ff77ae2392e3eaf","up":true},{"one":"08900197e74e285a5a8a9cc53fbd420bb35043ab27eb2d9eab22615e736a093abfa235c17f667dcc791cb50b9022082eafd9fba030194cc84f0358b769adc85b","other":"afb5754b4748b7ac5628e32b242c90aab0e2fc7da58d8d5c8c775d13d8a6fd32240f1b89021587858168cbe7b3ea7ad07807728655eae0a9907060494a7c99ca","up":true},{"one":"2502fc8ee0ccda79ad1dbd9c7cec625da85980b9116bdd56dc367d508039e25e5f65183293006e5b0df72fa9037a48bd2b133a757940d3587ff77ae2392e3eaf","other":"e9f7e58fda4b504275441d51929fbc98214abdc9ed552c7aa94c600a85d4e791d60c032304b29ae028adccec94984fc9a3d705a81462632f50ef45024eb0f64e","up":true},{"one":"afb5754b4748b7ac5628e32b242c90aab0e2fc7da58d8d5c8c775d13d8a6fd32240f1b89021587858168cbe7b3ea7ad07807728655eae0a9907060494a7c99ca","other":"8f625a4e4f4fd980c796d3aa535e58a39722492480cf6982d43fab02de63a5b4c1b5c7cd8402171dd792bb5d9c3e2bdd38176c061dbe3e5b0592af1339e3fd82","up":true},{"one":"670949178a5fad22da03af1e206c814a797c0e9eb4e3371f83612f121e5b56e767706a3ae36628cd0c86dd7bd1586ca4df57e2de27b28a31284ecf9176d330e5","other":"fd12c5c96df6ee76dd7beb9e4e4768dda4d2c498851b6435f13ca0175980d0e4a4ff1c002e4daf41a995f118500604764f88496fb9b2c22e28308d8649b525ce","up":true},{"one":"8f625a4e4f4fd980c796d3aa535e58a39722492480cf6982d43fab02de63a5b4c1b5c7cd8402171dd792bb5d9c3e2bdd38176c061dbe3e5b0592af1339e3fd82","other":"ab3814579882e9fd8d464f4f3c8a421be37822ba7f42c5f5e787e81125ec032f9ccf90a138c0b57f0a813b55b583f80d66284f795e2c82d80d2869e1fc770be5","up":true},{"one":"ab3814579882e9fd8d464f4f3c8a421be37822ba7f42c5f5e787e81125ec032f9ccf90a138c0b57f0a813b55b583f80d66284f795e2c82d80d2869e1fc770be5","other":"670949178a5fad22da03af1e206c814a797c0e9eb4e3371f83612f121e5b56e767706a3ae36628cd0c86dd7bd1586ca4df57e2de27b28a31284ecf9176d330e5","up":true},{"one":"fd12c5c96df6ee76dd7beb9e4e4768dda4d2c498851b6435f13ca0175980d0e4a4ff1c002e4daf41a995f118500604764f88496fb9b2c22e28308d8649b525ce","other":"ed1ab28230ed533abf25633508d54f32bbff78a10c7a15fad5c2320cda9d9669c6d0e15689d8885400e64cbcd81730456f8f4bd5c98681d2cd8a8d4e1daec553","up":true},{"one":"a05a18161c2d01a0f122548c66509dd1fcf3ee52975035bc79fb059e9613b743a16cd6f5ac54090e68f51bcf76ff21fb3805ba3197a96b4236afb80f791df802","other":"c89dbada7195464e732671ac6fff014cacfb4c879b63b6b84e7c1bce367522f759bd06e504b15f43a1735c6322356747fa5c4951882d4fd6cdf6f7cf13726719","up":true},{"one":"ed1ab28230ed533abf25633508d54f32bbff78a10c7a15fad5c2320cda9d9669c6d0e15689d8885400e64cbcd81730456f8f4bd5c98681d2cd8a8d4e1daec553","other":"a05a18161c2d01a0f122548c66509dd1fcf3ee52975035bc79fb059e9613b743a16cd6f5ac54090e68f51bcf76ff21fb3805ba3197a96b4236afb80f791df802","up":true},{"one":"340420ee18d55913f790d0fcc2305b40b1e7bef2eddb79dda57801690aeeead693ebd1a9ff8557671f5ae136b3e65733306924bd00444cbc6e7c6235e5a2c77f","other":"7a509686ebce91778fe22e834a94ab03f92457d41385099ba657fe62c7469a9669bddb9a3d7b0150efa1d2f40c69bc786c7f4ede1cf8b19411eea1d23cb7d56c","up":true},{"one":"c89dbada7195464e732671ac6fff014cacfb4c879b63b6b84e7c1bce367522f759bd06e504b15f43a1735c6322356747fa5c4951882d4fd6cdf6f7cf13726719","other":"51302ef7b50922398ad802e917390bb4a3c24c877f2c2bcb7fcb34de9feca22673a2c594639914fe46a28837ffadfd03bb673afbc856aff5e59caf8e76082482","up":true},{"one":"7a509686ebce91778fe22e834a94ab03f92457d41385099ba657fe62c7469a9669bddb9a3d7b0150efa1d2f40c69bc786c7f4ede1cf8b19411eea1d23cb7d56c","other":"816e91fa8ff68ba067a89390ef61e7f23211e5e05049daa103ad1ff84b94fbcf535a6f6b515fb571939f5656869767c608513808800baba7e5d2b5f3a17a9691","up":true},{"one":"51302ef7b50922398ad802e917390bb4a3c24c877f2c2bcb7fcb34de9feca22673a2c594639914fe46a28837ffadfd03bb673afbc856aff5e59caf8e76082482","other":"a40391285d1a97f1fb368b20c8e4d02be1bdebc0db41f00f99aac2f01893dc12256cd5a711117a981fbb3f9dfea18c19cf3603e925dbd67c4032b22b41eab8d5","up":true},{"one":"a40391285d1a97f1fb368b20c8e4d02be1bdebc0db41f00f99aac2f01893dc12256cd5a711117a981fbb3f9dfea18c19cf3603e925dbd67c4032b22b41eab8d5","other":"e0420ba2a293315d810928a0e09a507c6aaf93977ba2c7598e9b83723b4a66682398ea17542c26767c7ff0f4ca09c537d3cc10dad283f079f1de73e25e87cb5c","up":true},{"one":"816e91fa8ff68ba067a89390ef61e7f23211e5e05049daa103ad1ff84b94fbcf535a6f6b515fb571939f5656869767c608513808800baba7e5d2b5f3a17a9691","other":"77327983685f39f006806170fe351063a58ff1bd8dedc222d538e86cfd18abdfefd548328f25fc5afde8170aa5c35311353019468f2b439c331837ddfbb25a52","up":true},{"one":"33e3ab7108ced43102003c3b3192b194100f32b6bcb67bb772ea9696e35721196699cf01e443f7cdf8076ad83aaf7468b75c71d03efb95f4c07cf0742ea9af81","other":"cbed12dcab0aa04a96ec7e25bc2ee03b337c7b2006391baa7d2aff042c17ec70b82c5fb2dc916d085a7948541719d329f9b528b67ec6adb1ac2cc594d4ef1e42","up":true},{"one":"e0420ba2a293315d810928a0e09a507c6aaf93977ba2c7598e9b83723b4a66682398ea17542c26767c7ff0f4ca09c537d3cc10dad283f079f1de73e25e87cb5c","other":"33e3ab7108ced43102003c3b3192b194100f32b6bcb67bb772ea9696e35721196699cf01e443f7cdf8076ad83aaf7468b75c71d03efb95f4c07cf0742ea9af81","up":true},{"one":"77327983685f39f006806170fe351063a58ff1bd8dedc222d538e86cfd18abdfefd548328f25fc5afde8170aa5c35311353019468f2b439c331837ddfbb25a52","other":"7a18392b8338108a996196ee190a93a1b9954c8e05a062c421da513a1828dfa739e7b224878c0670cf74bbc743c7ca7ee8cfee6b6a602fe1f4a82ecfbd38c2f4","up":true},{"one":"cbed12dcab0aa04a96ec7e25bc2ee03b337c7b2006391baa7d2aff042c17ec70b82c5fb2dc916d085a7948541719d329f9b528b67ec6adb1ac2cc594d4ef1e42","other":"03d2d77c008b5fa1063b1abc3152b879a529fe4fdb2dc174d6d85312264a38ee4cc49b342507a10fff1a4b0730f1ef8e008b0897d97bfd6f70050adb124d3596","up":true},{"one":"276256790c9317d09ff7802f4ad0a85840fe62527390ce1790e1e3186e8b3f04acfaa41dcd02303d333423678a4037e4f4854676e79ced3232a3dbd772cc2680","other":"155805f787600f9f9518cf8836f491885b64868bfe0023975bcd12776925a424fb5aa3199dc178e83294e97f347a373d05d2422578a08eeeb2d15a178d28964f","up":true},{"one":"7a18392b8338108a996196ee190a93a1b9954c8e05a062c421da513a1828dfa739e7b224878c0670cf74bbc743c7ca7ee8cfee6b6a602fe1f4a82ecfbd38c2f4","other":"e7bb63c5187ee85d965fed5cb33d1678c0e090b4e4c3f3d859755565db18046cb60025453bdebf136373c416a2e6e56be063bca6c9257b7b175dcf966e274205","up":true},{"one":"155805f787600f9f9518cf8836f491885b64868bfe0023975bcd12776925a424fb5aa3199dc178e83294e97f347a373d05d2422578a08eeeb2d15a178d28964f","other":"4de606aa7e722197b918c5f7f0db86a3081d48e89d21428b04f19c3ff3755eac0bddbff5fad8bda94b9e57f58fba2fecdbabbf710f7afb381bf4f1a4fe55cd93","up":true},{"one":"9c6dcfef0e128dbfeca58b8ac625b08fb447b0d579bd3f18bc0e2be60d1ec2274595d0554ddba0ca7eb660099d3ea146d8076792b46c93841d2ecf8cf608f5ba","other":"6ce3a68cb1e2924ad97f22006094c709a3dd8b4ca1546fbb037f841a9e5ac62def242015dbf6221bda610153db064edcbb58a78a35a06077b8c02bf5b2a33c04","up":true},{"one":"e7bb63c5187ee85d965fed5cb33d1678c0e090b4e4c3f3d859755565db18046cb60025453bdebf136373c416a2e6e56be063bca6c9257b7b175dcf966e274205","other":"545850cb90787d49c579b1ed54a753ebd00eaafe3f1bd04d57266e4912fb1cdd654446ef054a973a583ce8dfc6cc130b6f90e63bcf75372fc21c445f8e1e6005","up":true},{"one":"6ce3a68cb1e2924ad97f22006094c709a3dd8b4ca1546fbb037f841a9e5ac62def242015dbf6221bda610153db064edcbb58a78a35a06077b8c02bf5b2a33c04","other":"178d5ce398a7114a63a0c953a59932e769891420f6b1544f08c082cd37b531b66757652d279b3036b03b04f8d46eceb0b46fb95646c6668e2921af75c06c3d97","up":true},{"one":"4de606aa7e722197b918c5f7f0db86a3081d48e89d21428b04f19c3ff3755eac0bddbff5fad8bda94b9e57f58fba2fecdbabbf710f7afb381bf4f1a4fe55cd93","other":"82a774be7146766585d2bec6b69b7803aa956f492a53d8ed5f071becdbbc617562885d8430f0afd505210aab7b032428fbea32c82dffbd12d9ccba776ef4729b","up":true},{"one":"03d2d77c008b5fa1063b1abc3152b879a529fe4fdb2dc174d6d85312264a38ee4cc49b342507a10fff1a4b0730f1ef8e008b0897d97bfd6f70050adb124d3596","other":"f0299035cbddfdf7a78e5e3a400aaedf2d719d04e907ac0f9f067525e2f9bb913d985308a3a0d05467a64adf58c68a615c6327acf716c23631d0e829903f8b34","up":true},{"one":"82a774be7146766585d2bec6b69b7803aa956f492a53d8ed5f071becdbbc617562885d8430f0afd505210aab7b032428fbea32c82dffbd12d9ccba776ef4729b","other":"340420ee18d55913f790d0fcc2305b40b1e7bef2eddb79dda57801690aeeead693ebd1a9ff8557671f5ae136b3e65733306924bd00444cbc6e7c6235e5a2c77f","up":true},{"one":"178d5ce398a7114a63a0c953a59932e769891420f6b1544f08c082cd37b531b66757652d279b3036b03b04f8d46eceb0b46fb95646c6668e2921af75c06c3d97","other":"59730132a01ba848a3c050bb6234bca9a72deba33716960fc3ec89b186bfcd313b9bbf049939d5805ff98db2c53a9421ce6ec97d8b4cdbaea53ba264d80d0734","up":true},{"one":"59730132a01ba848a3c050bb6234bca9a72deba33716960fc3ec89b186bfcd313b9bbf049939d5805ff98db2c53a9421ce6ec97d8b4cdbaea53ba264d80d0734","other":"93987e431a0058f2e942ccf8d3486d249cd2734d6494131b343e2c3a8fdd86cfcb12d0aaaf8fcb911ad3cdd682cc82118198195a7fdc915ab7853223f012eab6","up":true},{"one":"545850cb90787d49c579b1ed54a753ebd00eaafe3f1bd04d57266e4912fb1cdd654446ef054a973a583ce8dfc6cc130b6f90e63bcf75372fc21c445f8e1e6005","other":"86b84ddf64d301f6a9c4504c59eb4031d3167fb74101abea3b694845a009dc522be7b2e2720097ceea9f36058e160f42a2a438a33034929a5c1a7793c7ccef7b","up":true},{"one":"86b84ddf64d301f6a9c4504c59eb4031d3167fb74101abea3b694845a009dc522be7b2e2720097ceea9f36058e160f42a2a438a33034929a5c1a7793c7ccef7b","other":"bf1e6eeb8b229f63b49213db499b71dcfe0ae45ee3f14685c7cbfa3f0a2150e52a89c853f4cd8c7a92e6e5f6083044efddfa17391662e3cff6290da679520404","up":true},{"one":"bf1e6eeb8b229f63b49213db499b71dcfe0ae45ee3f14685c7cbfa3f0a2150e52a89c853f4cd8c7a92e6e5f6083044efddfa17391662e3cff6290da679520404","other":"a58a2dd3f5ee2471f0ddd555ffcc45d86e2d8c325585e3fe55eee878b8a626faccce73679d32811fc5d068c153e671673f4cd020f3c7fb37bc6fd9646931646a","up":true},{"one":"a58a2dd3f5ee2471f0ddd555ffcc45d86e2d8c325585e3fe55eee878b8a626faccce73679d32811fc5d068c153e671673f4cd020f3c7fb37bc6fd9646931646a","other":"896c74ca4cc4cbb9d2b6606d0ebfd6427952c2e16aedbf36933fa3d01f1c505fcd663f3d01c0cf096bef9cfd0bae4595ec7c221cfc362e19a5b7c60614a9658b","up":true},{"one":"896c74ca4cc4cbb9d2b6606d0ebfd6427952c2e16aedbf36933fa3d01f1c505fcd663f3d01c0cf096bef9cfd0bae4595ec7c221cfc362e19a5b7c60614a9658b","other":"1e0a46ff50fb6d9a2c218a851763ff86c42e4d61dddffb7188481febc0f3180bc8f31973d336b2a6e25802acd4fed6d905d89c6d4d7d8080fb12741f9c5ab7e6","up":true},{"one":"1e0a46ff50fb6d9a2c218a851763ff86c42e4d61dddffb7188481febc0f3180bc8f31973d336b2a6e25802acd4fed6d905d89c6d4d7d8080fb12741f9c5ab7e6","other":"b2bea653b6ec9629c6f934be72fccf30acf836698e21e81dd8085f070ba8259ba43eee43c342738a4b782f5fbddd44caa28f56dffc08237ca7567c965ac3beca","up":true},{"one":"b2bea653b6ec9629c6f934be72fccf30acf836698e21e81dd8085f070ba8259ba43eee43c342738a4b782f5fbddd44caa28f56dffc08237ca7567c965ac3beca","other":"5771bef7f50439f9b81d2a7bf7060b1ad4b38675d8f6abbac3cc4c215fb0cb5dd07f6873545b42218337556925566025476e2915b7b98e662a3dcd28bebf0eb4","up":true},{"one":"5771bef7f50439f9b81d2a7bf7060b1ad4b38675d8f6abbac3cc4c215fb0cb5dd07f6873545b42218337556925566025476e2915b7b98e662a3dcd28bebf0eb4","other":"0e8c1a6b70524c4fdc492c74348bac4ccd5d140bd41352607e8cfba45561afb1e6e12f3e2fcf03c1778c9ae5ae19cb9218ee2d613983768f54e3f54e69bb6600","up":true},{"one":"f0299035cbddfdf7a78e5e3a400aaedf2d719d04e907ac0f9f067525e2f9bb913d985308a3a0d05467a64adf58c68a615c6327acf716c23631d0e829903f8b34","other":"276256790c9317d09ff7802f4ad0a85840fe62527390ce1790e1e3186e8b3f04acfaa41dcd02303d333423678a4037e4f4854676e79ced3232a3dbd772cc2680","up":true},{"one":"0e8c1a6b70524c4fdc492c74348bac4ccd5d140bd41352607e8cfba45561afb1e6e12f3e2fcf03c1778c9ae5ae19cb9218ee2d613983768f54e3f54e69bb6600","other":"d71c50805f284ed3a759e2e81f220fbc73d6d0a7a261b4c9e7878c3da143cfc07afa83e1635b6a45530f71a60b9f17c485a2fd6617c6c2bff82bacc71c208087","up":true},{"one":"3e7820bb15c07f515bd63791b66136723dcc9878b3145fe0f238f6b41e3f2f7565ae55ef24f08ae461950ce1ae0c8a80fe5e4fd4f2f88c4acf4a2c94640df239","other":"dafb58b2fc8a14f2b23b7df33d28aa7847a08f80e9c21a654d4c97d928e1afe6585644d27f22442cf70d229c32783be6a03c0920be153fc4d9f3b273dfa90ec3","up":true},{"one":"3572a22097a313b3adef95a7b6cc679f8d1201a156d764e61a9fbc63d123fb4826f7125402fb6569beed359e1c1e5e6cb6993a75975da6cd4ce15669a2eea758","other":"e3f2e777a96b2137b3104b84d5d827d484eac9ee1b585430e09f790d7e26978da12802325927c3c483bc19973e09cd3f70c513c34798e5da650f8d2f0c8c5c47","up":true},{"one":"ce1309c8505b446363ae37cd3b1ee3e03ced537bed20aca5d8c4be2133917c408845ef5d0f65876974be2803dfb824827cf5c5a2d050d6ef26cdabcbf3a2dc31","other":"3e7820bb15c07f515bd63791b66136723dcc9878b3145fe0f238f6b41e3f2f7565ae55ef24f08ae461950ce1ae0c8a80fe5e4fd4f2f88c4acf4a2c94640df239","up":true},{"one":"56e8f792ec9a75ec9e91d472b8a4b023655dd68c2a448a33397b125fe3584a5efa1b492e47077b24acfe0396b73e1cb564a6a6b2aee1b457781dfaf6d43fcaed","other":"3572a22097a313b3adef95a7b6cc679f8d1201a156d764e61a9fbc63d123fb4826f7125402fb6569beed359e1c1e5e6cb6993a75975da6cd4ce15669a2eea758","up":true},{"one":"5d96577324edf1b5a1626999925982af1e0ba7bed8edcc3f740ba434f4b003cbbe2d632cad327c76e5b490d08c091c4a7b473353ab59139493657eb9525b8be2","other":"b09af9e5552e72f918174963dad58a4492d3afa120f78e43820df7bff7fae9f6b52bc6c8c73d3a9af91d20134f4ff1b037db2ef0bc3d8c495a771d63de678bc0","up":true},{"one":"622646c74fdbae39ba191dbafff4906fb683fe0b0f2c303d080f5577a070876c41c8d3786ae7b953e5f682b8ec647727550d47302229ebb9f82bed24cea61132","other":"2d6d55edd34c0d9a0130b4806e409bbe18cdda5c2b221cf46136718ec20ffc9d8e92838d78aff92fbcc85f5d081da361dd1e3d7f3d4e1ea57877d6bb7aa0b6f7","up":true},{"one":"dafb58b2fc8a14f2b23b7df33d28aa7847a08f80e9c21a654d4c97d928e1afe6585644d27f22442cf70d229c32783be6a03c0920be153fc4d9f3b273dfa90ec3","other":"622646c74fdbae39ba191dbafff4906fb683fe0b0f2c303d080f5577a070876c41c8d3786ae7b953e5f682b8ec647727550d47302229ebb9f82bed24cea61132","up":true},{"one":"1955bedf0bc9044b13a2c16158087123197c74147c86aa3b9389d308a364e80edbc573bcc836d8a262a77f3c9233ebddb1b82eca83cd0a0e4bda6564c443bb70","other":"5984a296b49bfba30315501ce2ae88ed0392ab2959ac4e7e6b9a29090f344b9dd13873ca137e8317c402cd2e14a61965d5707065b8ded46c41a054731933719f","up":true},{"one":"b09af9e5552e72f918174963dad58a4492d3afa120f78e43820df7bff7fae9f6b52bc6c8c73d3a9af91d20134f4ff1b037db2ef0bc3d8c495a771d63de678bc0","other":"1955bedf0bc9044b13a2c16158087123197c74147c86aa3b9389d308a364e80edbc573bcc836d8a262a77f3c9233ebddb1b82eca83cd0a0e4bda6564c443bb70","up":true},{"one":"5b4de68680c5d1a75cccd5e7a82319c031f5d61d79cbb6532e1254ab81c833c3fafb54390cca7a770e84690c490fcba90482b35321870f8506335a2f57cc052e","other":"cd0e9a45b45f9a67417fcde29d9f92c45ca4db46eebbfe47dcf6999e23e549e4205f42ada8e3fcd00e2fb5f832bb92a27a59b43c4a5909148d81399c2e8ce492","up":true},{"one":"a6ca1d5340f2d7021f541c81cf9aea519675462c8443bb6ddd93919962561b8f5a8431c3ec7e7e7d46c600b653e9a0638d2bb07cf4e29516bf9c4d3653f451b0","other":"d8cfadac10473b31a4560c711636a05615f13054388065344642ff1d04246fb62eafeec06805264eafead111ed8134e11a8e21f42a0eb950c23b142e627bd8cb","up":true},{"one":"1480f62d85ea32226d9f77ccd31780b3e704fb60618a588ae85dcd1c0e84e878c5fc092adfb306e8ebc7abba9ec429cb2447754502ef847cf931467f31fa50b2","other":"3540d888c3207d6df233afd1164ff9dde2551730862772547e04f7311de364968e113f38a7dea1ab0916a7f8307017de5b49578fa4ebcc39651e541fde51be48","up":true},{"one":"20bdc859d58d8bf419df64fd6ee1d4363c1d5f403af3abef2720d7d3933924672e12e23e5d76b28e0f6726acf58bdc5eb258cba635e327cbd0b564523305da75","other":"c6d1404873174254c0f15f25804da9a9d90db9c11c5cc895fab613b4deb7820f1733680b4ba9e4b61a664642ed6ee9ff012e13a0619c64ae067be6bab26962c6","up":true},{"one":"b38213eaa5b419de787b70073ad8c7c819e48c5f76dec1507b54f1d7cb027211facbe7a170ac50212abe130935e8947d5a19d6b13790114e71cc18357902a889","other":"20bdc859d58d8bf419df64fd6ee1d4363c1d5f403af3abef2720d7d3933924672e12e23e5d76b28e0f6726acf58bdc5eb258cba635e327cbd0b564523305da75","up":true},{"one":"f8052e328014f39157036f3dcecdb23419c0959473a88282605f10add681ef5cbfb1e926b522f98b8401272113b677a67225874d1afb0bff4b11140cc071de44","other":"3274b5f48e6929e2305e980b558a4ca3c7cf800b75a6445ea2875cb379e127f3e793e9450a11e927682aa91b8af52e9560dece633833e0f207a8a8a38b7b9c54","up":true},{"one":"3c6faa2e75a1699ddadd0e21fd35d3d6215715cfdc2dc89961cfd66773d2541776e785f3ebc833a70e3d1017a4edc571a5d5d9f9fbfc3fa0a8588f6c5023c164","other":"56e8f792ec9a75ec9e91d472b8a4b023655dd68c2a448a33397b125fe3584a5efa1b492e47077b24acfe0396b73e1cb564a6a6b2aee1b457781dfaf6d43fcaed","up":true},{"one":"3274b5f48e6929e2305e980b558a4ca3c7cf800b75a6445ea2875cb379e127f3e793e9450a11e927682aa91b8af52e9560dece633833e0f207a8a8a38b7b9c54","other":"e59940a6dfe35a6214e2e3daba9ad94e630004cd8f029e13a6649a56dc528ff94bc09d8d21a2f14a56b4ff759b60ebf3d27c1029862c183b8416fa3e950bdb55","up":true},{"one":"cdd86dea7dde96ff7cc1e3248fd17d107c83f2cc7ce2111c41530448962763309e91a05b5dad4663d0e02db59ed4129ab0c3e1eedc42c654e39d29f99038063b","other":"da15d60a4b9a8816ce24c20f6c941c51229c1fb5e070b8b29be2977c2f7b41f8f17e4b6efe75f465e7935ded1ba17472f046eac73393db7197018fa86d11c31f","up":true},{"one":"5d917ffc9d70a38670941ce206aa7ea1b9ea65c1d783f14ebdf7c7afa6ca8b237112aaa9b1a3f757132093a604ef378280c5bdef02c2688049a91a412c399bfe","other":"26cf4ea45b9a76daab82a57126f9c6f8726d2eb973e205ab4ab69c8b8be11a32a7eb5c3807e952cd428ce5ddd88f143d4fc9ff8c3de3d159855675afce715615","up":true},{"one":"03e478a3aae82e06e215e40272a420037a61442d11c49c367a5ee6a21868d29a17ea8b9284f013d020c4740f296a6a22bc64d33d1c2807f9ab8dc48c0cfec18a","other":"3df030a522a157e36f6b369aab048b9287792743a411a47073c4f9ef7686528f39bf7bf91c48e4d46afe180c8d08430b012bd216d50876baa3b1e7bc17cb55ef","up":true},{"one":"9c3be147f9fe0fa34e553d9e4332969086ea7fa65294b61ca35c9f731f6b81d0b70cdcfe2ba52b6cea3c0de14b7ea40031b5cc40661c4bb821147894130d7bf5","other":"ce1309c8505b446363ae37cd3b1ee3e03ced537bed20aca5d8c4be2133917c408845ef5d0f65876974be2803dfb824827cf5c5a2d050d6ef26cdabcbf3a2dc31","up":true},{"one":"e59940a6dfe35a6214e2e3daba9ad94e630004cd8f029e13a6649a56dc528ff94bc09d8d21a2f14a56b4ff759b60ebf3d27c1029862c183b8416fa3e950bdb55","other":"f7637cdd5ef26de40b9055c1df91a45725670c8df11ae934c0d99d2547c3eb4c42a16dbb2e75bcaf4b1b9347c48db65f549a0623179a08dd8cbad92f5bca08cf","up":true},{"one":"f06ec3a90d34300f9fa2d48aea0c6b5f2f01f7833ffb0fad30e7f57e3916e344f3a4f9efe38e222443b8b00d3c7f5221c672491a129e4958e574afc283bd45b1","other":"3c6faa2e75a1699ddadd0e21fd35d3d6215715cfdc2dc89961cfd66773d2541776e785f3ebc833a70e3d1017a4edc571a5d5d9f9fbfc3fa0a8588f6c5023c164","up":true},{"one":"f04c3ae9fe957a14c249acf3ea2e8407d04d108fc01e75f6d52aaf5073b3450025012d138a75b857473eea4d20e57c99b92bff9041f269d995543d7c67a92ec6","other":"8e8de10fb3f53bd3a48455ebfa0a38ea5bd28c607e65506b263ece53a24d2361c2af7d7cd207e45b11bf71a3c33fa325fc8fd40a18b9c73019cce219c757c7ef","up":true},{"one":"c93cb2df7ba6de8009872f5f7565891040d42e3b193ef1cdb321a0c167cc8fb8138900982bb8f6918fbaefac6e02dda01ee40f7a6beba1990dd44abe03cc3d01","other":"3e9c0bbd146d8b1040b4f379eecf802c27c4d0a70e64a9fb2e941a7edab9b00396b0b67fc5c891652743cdba3b342973ed49615b32da54b925954a799240431c","up":true},{"one":"5984a296b49bfba30315501ce2ae88ed0392ab2959ac4e7e6b9a29090f344b9dd13873ca137e8317c402cd2e14a61965d5707065b8ded46c41a054731933719f","other":"9c3be147f9fe0fa34e553d9e4332969086ea7fa65294b61ca35c9f731f6b81d0b70cdcfe2ba52b6cea3c0de14b7ea40031b5cc40661c4bb821147894130d7bf5","up":true},{"one":"4bd17847bdf60ea93a670a84a0ff8fe028d35228e814d6ebc0ae4fa586ddef03cd79390d541d28ca3c05a7241ffe92ac182e63c251176b40db8fe05fefaa82be","other":"f8052e328014f39157036f3dcecdb23419c0959473a88282605f10add681ef5cbfb1e926b522f98b8401272113b677a67225874d1afb0bff4b11140cc071de44","up":true},{"one":"da15d60a4b9a8816ce24c20f6c941c51229c1fb5e070b8b29be2977c2f7b41f8f17e4b6efe75f465e7935ded1ba17472f046eac73393db7197018fa86d11c31f","other":"03e478a3aae82e06e215e40272a420037a61442d11c49c367a5ee6a21868d29a17ea8b9284f013d020c4740f296a6a22bc64d33d1c2807f9ab8dc48c0cfec18a","up":true},{"one":"3df030a522a157e36f6b369aab048b9287792743a411a47073c4f9ef7686528f39bf7bf91c48e4d46afe180c8d08430b012bd216d50876baa3b1e7bc17cb55ef","other":"4bd17847bdf60ea93a670a84a0ff8fe028d35228e814d6ebc0ae4fa586ddef03cd79390d541d28ca3c05a7241ffe92ac182e63c251176b40db8fe05fefaa82be","up":true},{"one":"8e8de10fb3f53bd3a48455ebfa0a38ea5bd28c607e65506b263ece53a24d2361c2af7d7cd207e45b11bf71a3c33fa325fc8fd40a18b9c73019cce219c757c7ef","other":"cdd86dea7dde96ff7cc1e3248fd17d107c83f2cc7ce2111c41530448962763309e91a05b5dad4663d0e02db59ed4129ab0c3e1eedc42c654e39d29f99038063b","up":true},{"one":"fa897ba112f34839064c6871a4c9504c5d709eff5095a137c6a42726d58eb623af976cb96cc30db67e6ac9347c769f032aa4ebda884285a057059040c008ad3e","other":"5d96577324edf1b5a1626999925982af1e0ba7bed8edcc3f740ba434f4b003cbbe2d632cad327c76e5b490d08c091c4a7b473353ab59139493657eb9525b8be2","up":true},{"one":"57bfbde13c71e035c96513870aa8215198f78806e7cdb01c54fbdb392de2c40386d768d6fdc4c68534a67e531867ca74d8ca4dcf34ff7f7f64ec35edee3e5f68","other":"5b4de68680c5d1a75cccd5e7a82319c031f5d61d79cbb6532e1254ab81c833c3fafb54390cca7a770e84690c490fcba90482b35321870f8506335a2f57cc052e","up":true},{"one":"f7637cdd5ef26de40b9055c1df91a45725670c8df11ae934c0d99d2547c3eb4c42a16dbb2e75bcaf4b1b9347c48db65f549a0623179a08dd8cbad92f5bca08cf","other":"fa897ba112f34839064c6871a4c9504c5d709eff5095a137c6a42726d58eb623af976cb96cc30db67e6ac9347c769f032aa4ebda884285a057059040c008ad3e","up":true},{"one":"49eb706cd7e95ad78502a508487d88b818861d94334aee36b2acef5c25cfff5c0efc2df9dc5dbb18acd4003d5cc0c843d3b40363adf2f62a14c04d814268fdee","other":"c93cb2df7ba6de8009872f5f7565891040d42e3b193ef1cdb321a0c167cc8fb8138900982bb8f6918fbaefac6e02dda01ee40f7a6beba1990dd44abe03cc3d01","up":true},{"one":"eb097186ff58d96a7ead7a7f9c05a44075d84537bd4fd3f82857bf2c45bee1c6dece434a7707cde69e96f02366859cab4c991fdb7615e113a868d4b9c7524a45","other":"57bfbde13c71e035c96513870aa8215198f78806e7cdb01c54fbdb392de2c40386d768d6fdc4c68534a67e531867ca74d8ca4dcf34ff7f7f64ec35edee3e5f68","up":true},{"one":"d71c50805f284ed3a759e2e81f220fbc73d6d0a7a261b4c9e7878c3da143cfc07afa83e1635b6a45530f71a60b9f17c485a2fd6617c6c2bff82bacc71c208087","other":"06472c89def07fa73188d253cf1acddc2be984842f3a234edb3db95449ba74928ab1395eca1b8978987769863afffb488fc27c9ac723aa24837b66c12f38d735","up":true},{"one":"f62bd19b0fd052207743ce53c3d48a3a71e9219b75e41a9497a43e6368e559d5487ff1ab644f2df4106b500583e4344515f73187eec773115deb977b4ebc3514","other":"a1b2d0c6f24f5924c61e057fc65b994d9a6755560d740018b4c9ad0bb69212ec69974e22cb037dfeb7ea90a4493997f4c94029870bcc5fd47013b51ca0a26b5d","up":true},{"one":"06472c89def07fa73188d253cf1acddc2be984842f3a234edb3db95449ba74928ab1395eca1b8978987769863afffb488fc27c9ac723aa24837b66c12f38d735","other":"eb097186ff58d96a7ead7a7f9c05a44075d84537bd4fd3f82857bf2c45bee1c6dece434a7707cde69e96f02366859cab4c991fdb7615e113a868d4b9c7524a45","up":true},{"one":"d8cfadac10473b31a4560c711636a05615f13054388065344642ff1d04246fb62eafeec06805264eafead111ed8134e11a8e21f42a0eb950c23b142e627bd8cb","other":"49eb706cd7e95ad78502a508487d88b818861d94334aee36b2acef5c25cfff5c0efc2df9dc5dbb18acd4003d5cc0c843d3b40363adf2f62a14c04d814268fdee","up":true},{"one":"a1b2d0c6f24f5924c61e057fc65b994d9a6755560d740018b4c9ad0bb69212ec69974e22cb037dfeb7ea90a4493997f4c94029870bcc5fd47013b51ca0a26b5d","other":"188bf77c9c1e45f009efe7aefdb040bdb47763980fe7eb0851295d657fa2a8978efbd2997c1dc30f4f0874eecf9ca9550487cf41da237b84d071963d35b6baff","up":true},{"one":"26cf4ea45b9a76daab82a57126f9c6f8726d2eb973e205ab4ab69c8b8be11a32a7eb5c3807e952cd428ce5ddd88f143d4fc9ff8c3de3d159855675afce715615","other":"20f171ab01a814a2856a6cbe7929269f18f6329914289515e2cb9d078ac14ebdae457789dd638c6415b062799114570f556147d4bf9ac850f00b6d0762765ac1","up":true},{"one":"cd0e9a45b45f9a67417fcde29d9f92c45ca4db46eebbfe47dcf6999e23e549e4205f42ada8e3fcd00e2fb5f832bb92a27a59b43c4a5909148d81399c2e8ce492","other":"5d917ffc9d70a38670941ce206aa7ea1b9ea65c1d783f14ebdf7c7afa6ca8b237112aaa9b1a3f757132093a604ef378280c5bdef02c2688049a91a412c399bfe","up":true},{"one":"a5cdff211813e17fadd43ec55a6cf4e97e6ca0c3b2cef0db58923b27d36207fd1a77146efb6093bd94d7eb89cc77d8c735fc64ab098839efc74a00b5e8687555","other":"27fb8fcda1986644f985d68430c399f0299644b00b234c355362721081d12f9eb7686eea8f92eabda1d342bf56255e51c07b200c6233f95ac009f15b874eee97","up":true},{"one":"188bf77c9c1e45f009efe7aefdb040bdb47763980fe7eb0851295d657fa2a8978efbd2997c1dc30f4f0874eecf9ca9550487cf41da237b84d071963d35b6baff","other":"f06ec3a90d34300f9fa2d48aea0c6b5f2f01f7833ffb0fad30e7f57e3916e344f3a4f9efe38e222443b8b00d3c7f5221c672491a129e4958e574afc283bd45b1","up":true},{"one":"077bcadade93e0d361e94f76dff464d61912bc067ce2ce17ebcabd757cca201cd64624ea809d99dd8ecb749d40528db9b3eb503ef5ec05e8845044cfaef720dc","other":"73be4d2291c68ca4554a86fa170f7595210e1b6bbbeef3c1d5623a2b5d03a8fd6e26caa26afc639c20c8a351a89dad1086f91734f09afab62d28ec17b700fa01","up":true},{"one":"e3f2e777a96b2137b3104b84d5d827d484eac9ee1b585430e09f790d7e26978da12802325927c3c483bc19973e09cd3f70c513c34798e5da650f8d2f0c8c5c47","other":"1480f62d85ea32226d9f77ccd31780b3e704fb60618a588ae85dcd1c0e84e878c5fc092adfb306e8ebc7abba9ec429cb2447754502ef847cf931467f31fa50b2","up":true},{"one":"c6d1404873174254c0f15f25804da9a9d90db9c11c5cc895fab613b4deb7820f1733680b4ba9e4b61a664642ed6ee9ff012e13a0619c64ae067be6bab26962c6","other":"f04c3ae9fe957a14c249acf3ea2e8407d04d108fc01e75f6d52aaf5073b3450025012d138a75b857473eea4d20e57c99b92bff9041f269d995543d7c67a92ec6","up":true},{"one":"73be4d2291c68ca4554a86fa170f7595210e1b6bbbeef3c1d5623a2b5d03a8fd6e26caa26afc639c20c8a351a89dad1086f91734f09afab62d28ec17b700fa01","other":"a5cdff211813e17fadd43ec55a6cf4e97e6ca0c3b2cef0db58923b27d36207fd1a77146efb6093bd94d7eb89cc77d8c735fc64ab098839efc74a00b5e8687555","up":true},{"one":"f0b2f1e8d46be656109adb18c60677ac9eb8fce7f42e15d9dbb25f94b4e426064780eaf32b79954b9bb72ea89953175da8de35380aaba18931cca374a7de2b11","other":"a6ca1d5340f2d7021f541c81cf9aea519675462c8443bb6ddd93919962561b8f5a8431c3ec7e7e7d46c600b653e9a0638d2bb07cf4e29516bf9c4d3653f451b0","up":true},{"one":"3540d888c3207d6df233afd1164ff9dde2551730862772547e04f7311de364968e113f38a7dea1ab0916a7f8307017de5b49578fa4ebcc39651e541fde51be48","other":"077bcadade93e0d361e94f76dff464d61912bc067ce2ce17ebcabd757cca201cd64624ea809d99dd8ecb749d40528db9b3eb503ef5ec05e8845044cfaef720dc","up":true},{"one":"2d6d55edd34c0d9a0130b4806e409bbe18cdda5c2b221cf46136718ec20ffc9d8e92838d78aff92fbcc85f5d081da361dd1e3d7f3d4e1ea57877d6bb7aa0b6f7","other":"f62bd19b0fd052207743ce53c3d48a3a71e9219b75e41a9497a43e6368e559d5487ff1ab644f2df4106b500583e4344515f73187eec773115deb977b4ebc3514","up":true},{"one":"20f171ab01a814a2856a6cbe7929269f18f6329914289515e2cb9d078ac14ebdae457789dd638c6415b062799114570f556147d4bf9ac850f00b6d0762765ac1","other":"f0b2f1e8d46be656109adb18c60677ac9eb8fce7f42e15d9dbb25f94b4e426064780eaf32b79954b9bb72ea89953175da8de35380aaba18931cca374a7de2b11","up":true},{"one":"3e9c0bbd146d8b1040b4f379eecf802c27c4d0a70e64a9fb2e941a7edab9b00396b0b67fc5c891652743cdba3b342973ed49615b32da54b925954a799240431c","other":"b38213eaa5b419de787b70073ad8c7c819e48c5f76dec1507b54f1d7cb027211facbe7a170ac50212abe130935e8947d5a19d6b13790114e71cc18357902a889","up":true},{"one":"750ca601f07d65f426f6ea5f34e06238f9d7a931f022f9b0ebc811943d3725500cb3c6f00c8d05eb8d5b353c6534136dff38b9a8d3d4dc5bf49cd96875704d07","other":"28afc20d8f4779b285bb14870062dbb54796ec77623302e51bc1bafed9e2c35751c8469ffc482718e059875dfa2226195ed10999e251498cba3a444896cb67db","up":true},{"one":"da3e0fd71eb96ba2cab7f920d32f5425d1aad41d00765fdffb0b215d9dd5b60e2bc5929eafebee5b2b5a11aec164e141beff19d828aac7d1fabd3ffb0bfb8450","other":"f2ea93f43be9d0c3fa21f1496dc13c778977a6afdcba24c8b146de7dca2cdde62a5b792aab969e5b4b6c56f63066b336580d911f206049cc24cac32a25fc4306","up":true},{"one":"87fce129511a1be2777052d24b606acdfe7067f4e874ab04674a68664b378ea208975f7269a72af889d3d23cd930b6a181afa2cdef3f9f9491f715bd96ad8dc0","other":"d90a81a583c82d626b92f27244f027da4a0ae76e6d3bdc1de0af7be01798f1fb04b34ce60c6d8651a39d7a70915438a4aa63e5adf844a9f7e38dbf0b1dba754d","up":true},{"one":"d90a81a583c82d626b92f27244f027da4a0ae76e6d3bdc1de0af7be01798f1fb04b34ce60c6d8651a39d7a70915438a4aa63e5adf844a9f7e38dbf0b1dba754d","other":"18bb6572965f4263c5a4d59a73027abc57a46122125ee58d871e95c993e6a1e8230438ce696a5f8880a08749837268b54319f7b0aa254c1a5bd453a8e9bcf84f","up":true},{"one":"805d784527be4e32e84ddf045baee1ccf348cdf8288de3aae1a5379f762576b957525ef358d9b42c68a93394017880adc09bb2b1b5e01102dc7e4240baf2af95","other":"750ca601f07d65f426f6ea5f34e06238f9d7a931f022f9b0ebc811943d3725500cb3c6f00c8d05eb8d5b353c6534136dff38b9a8d3d4dc5bf49cd96875704d07","up":true},{"one":"e7bb63c5187ee85d965fed5cb33d1678c0e090b4e4c3f3d859755565db18046cb60025453bdebf136373c416a2e6e56be063bca6c9257b7b175dcf966e274205","other":"276256790c9317d09ff7802f4ad0a85840fe62527390ce1790e1e3186e8b3f04acfaa41dcd02303d333423678a4037e4f4854676e79ced3232a3dbd772cc2680","up":true},{"one":"3103510e00a3f49a5e715719049fc8c9c67a2373a548f326458aeb6d9c75ed92b94373638fd075def0209113b4e85d972c23f064539f7b041596184e40d7f9a2","other":"da3e0fd71eb96ba2cab7f920d32f5425d1aad41d00765fdffb0b215d9dd5b60e2bc5929eafebee5b2b5a11aec164e141beff19d828aac7d1fabd3ffb0bfb8450","up":true},{"one":"077d2d032874e5ce70e9b928b7fe72c0326ba92394e16245e31d48b5731d3d32bfd86acf40825decff54bcd735e9ebfd94eba677c418ea7007baec9db4af676d","other":"18bb6572965f4263c5a4d59a73027abc57a46122125ee58d871e95c993e6a1e8230438ce696a5f8880a08749837268b54319f7b0aa254c1a5bd453a8e9bcf84f","up":true},{"one":"a9e0b763852706722dc904b494293f9399c0fa32255890aa720285b8160335bb618f36b68a81b875a805384179f600defef474d486b4ea04b003ef6477ab7907","other":"da3e0fd71eb96ba2cab7f920d32f5425d1aad41d00765fdffb0b215d9dd5b60e2bc5929eafebee5b2b5a11aec164e141beff19d828aac7d1fabd3ffb0bfb8450","up":true},{"one":"c89dbada7195464e732671ac6fff014cacfb4c879b63b6b84e7c1bce367522f759bd06e504b15f43a1735c6322356747fa5c4951882d4fd6cdf6f7cf13726719","other":"fd12c5c96df6ee76dd7beb9e4e4768dda4d2c498851b6435f13ca0175980d0e4a4ff1c002e4daf41a995f118500604764f88496fb9b2c22e28308d8649b525ce","up":true},{"one":"f2ea93f43be9d0c3fa21f1496dc13c778977a6afdcba24c8b146de7dca2cdde62a5b792aab969e5b4b6c56f63066b336580d911f206049cc24cac32a25fc4306","other":"4448a59bde9edb93edcdb4a77f3e2277b9c01ffea45496ee0533eb5192955a08a0f982e25cf772e0dae68735a55b7acd221f6ba7b134f1e999087bee182330e8","up":true},{"one":"09b60de1e85bb6f7d2caf5b1ab58204d7d04531ece300dcd7bcc9157b8b3ef2a182758808a0eec6056034f29f52caadb7c690f498c1c8832ff7a6a9ecff308bd","other":"4448a59bde9edb93edcdb4a77f3e2277b9c01ffea45496ee0533eb5192955a08a0f982e25cf772e0dae68735a55b7acd221f6ba7b134f1e999087bee182330e8","up":true},{"one":"e9f7e58fda4b504275441d51929fbc98214abdc9ed552c7aa94c600a85d4e791d60c032304b29ae028adccec94984fc9a3d705a81462632f50ef45024eb0f64e","other":"33e3ab7108ced43102003c3b3192b194100f32b6bcb67bb772ea9696e35721196699cf01e443f7cdf8076ad83aaf7468b75c71d03efb95f4c07cf0742ea9af81","up":true},{"one":"489660042a8867d90a16ebb013968db26ca3edfc70f53320f511e35b3703eed09fbd787be5c06726a570a54aa15d129cd10db741523adf297929f909be4a0c71","other":"73319a301ad3cf0ec09549d817c9523d61b74abb0cad87b737d41d900321e52722a84355f6f87bc7a5f848818c89a021bb0f3e5994f67c9a7b5bbfc98188a376","up":true},{"one":"73319a301ad3cf0ec09549d817c9523d61b74abb0cad87b737d41d900321e52722a84355f6f87bc7a5f848818c89a021bb0f3e5994f67c9a7b5bbfc98188a376","other":"51ba4faf0988717a37dcddc0a60a70ead33bde310184fc450f9ca73c67f931e6767ad5930bcf409e5aeb613a9ff7a03e47de6fc13b33d8af0b87b38822ae6888","up":true},{"one":"caad8529d498a4a1e1ba7573689a913500bd409345ef8e3656abca748269eb73b919282f7f2eb0087f81f7bc52c367657ac8be0cdac65d2490c7c50c874444b7","other":"ecbdca037cd7892752345b48b4219478b1b334f83ce7140fcc72eb71784436b690ce7a41b03e013cefc19d64a34a20cfef1b9e2b535d938bcdcb39fe63645a42","up":true},{"one":"31ac37862416c0e229c4a088ec179f23bdd1bf12dd464eb11c630ad531d7c3438671862e5458e2f6fbb32b857f857e6b8c17e5d93eb29a0e78bb5a65d7eb648c","other":"da3e0fd71eb96ba2cab7f920d32f5425d1aad41d00765fdffb0b215d9dd5b60e2bc5929eafebee5b2b5a11aec164e141beff19d828aac7d1fabd3ffb0bfb8450","up":true},{"one":"41994605708232b4ca7448c3bc0760a7b86bf26d442091e5ce6e92eac94925721d7e0eca04bdd03bb1bba1ef92deeccd4bf1b7c6c3318b7e8d031965c6646761","other":"6ce3a68cb1e2924ad97f22006094c709a3dd8b4ca1546fbb037f841a9e5ac62def242015dbf6221bda610153db064edcbb58a78a35a06077b8c02bf5b2a33c04","up":true},{"one":"27fb8fcda1986644f985d68430c399f0299644b00b234c355362721081d12f9eb7686eea8f92eabda1d342bf56255e51c07b200c6233f95ac009f15b874eee97","other":"4448a59bde9edb93edcdb4a77f3e2277b9c01ffea45496ee0533eb5192955a08a0f982e25cf772e0dae68735a55b7acd221f6ba7b134f1e999087bee182330e8","up":true},{"one":"665c3288c14dc1c17d85d17d634910f42183482c7e77c47e68f9b4f475b93e8c152246b9e34781606315ff6ef0f8360342500d15e4a2d67d9df6b72f30af64a7","other":"ab3814579882e9fd8d464f4f3c8a421be37822ba7f42c5f5e787e81125ec032f9ccf90a138c0b57f0a813b55b583f80d66284f795e2c82d80d2869e1fc770be5","up":true},{"one":"a40391285d1a97f1fb368b20c8e4d02be1bdebc0db41f00f99aac2f01893dc12256cd5a711117a981fbb3f9dfea18c19cf3603e925dbd67c4032b22b41eab8d5","other":"cbed12dcab0aa04a96ec7e25bc2ee03b337c7b2006391baa7d2aff042c17ec70b82c5fb2dc916d085a7948541719d329f9b528b67ec6adb1ac2cc594d4ef1e42","up":true},{"one":"178d5ce398a7114a63a0c953a59932e769891420f6b1544f08c082cd37b531b66757652d279b3036b03b04f8d46eceb0b46fb95646c6668e2921af75c06c3d97","other":"03d2d77c008b5fa1063b1abc3152b879a529fe4fdb2dc174d6d85312264a38ee4cc49b342507a10fff1a4b0730f1ef8e008b0897d97bfd6f70050adb124d3596","up":true},{"one":"340420ee18d55913f790d0fcc2305b40b1e7bef2eddb79dda57801690aeeead693ebd1a9ff8557671f5ae136b3e65733306924bd00444cbc6e7c6235e5a2c77f","other":"f0299035cbddfdf7a78e5e3a400aaedf2d719d04e907ac0f9f067525e2f9bb913d985308a3a0d05467a64adf58c68a615c6327acf716c23631d0e829903f8b34","up":true},{"one":"93987e431a0058f2e942ccf8d3486d249cd2734d6494131b343e2c3a8fdd86cfcb12d0aaaf8fcb911ad3cdd682cc82118198195a7fdc915ab7853223f012eab6","other":"ed1ab28230ed533abf25633508d54f32bbff78a10c7a15fad5c2320cda9d9669c6d0e15689d8885400e64cbcd81730456f8f4bd5c98681d2cd8a8d4e1daec553","up":true},{"one":"2fdb4382c4bc2950948a8cff13a7df65627bc0b20661cae20fd29acab166c97701594ee3151d75c006ba86d1d68b624b1d1f78e3d1e2fc297844956ef82208a8","other":"09b60de1e85bb6f7d2caf5b1ab58204d7d04531ece300dcd7bcc9157b8b3ef2a182758808a0eec6056034f29f52caadb7c690f498c1c8832ff7a6a9ecff308bd","up":true},{"one":"08900197e74e285a5a8a9cc53fbd420bb35043ab27eb2d9eab22615e736a093abfa235c17f667dcc791cb50b9022082eafd9fba030194cc84f0358b769adc85b","other":"562119edffe8270f6f7a5ad9b13d4c65d643e52a2331d1fee16f7e9b5567f44cfea62df3e8965a22cf08db8fa918f0a0bcae8da2936677e6d25bc88ed85ed2f1","up":true},{"one":"8f625a4e4f4fd980c796d3aa535e58a39722492480cf6982d43fab02de63a5b4c1b5c7cd8402171dd792bb5d9c3e2bdd38176c061dbe3e5b0592af1339e3fd82","other":"33e3ab7108ced43102003c3b3192b194100f32b6bcb67bb772ea9696e35721196699cf01e443f7cdf8076ad83aaf7468b75c71d03efb95f4c07cf0742ea9af81","up":true},{"one":"ab3814579882e9fd8d464f4f3c8a421be37822ba7f42c5f5e787e81125ec032f9ccf90a138c0b57f0a813b55b583f80d66284f795e2c82d80d2869e1fc770be5","other":"33e3ab7108ced43102003c3b3192b194100f32b6bcb67bb772ea9696e35721196699cf01e443f7cdf8076ad83aaf7468b75c71d03efb95f4c07cf0742ea9af81","up":true},{"one":"4448a59bde9edb93edcdb4a77f3e2277b9c01ffea45496ee0533eb5192955a08a0f982e25cf772e0dae68735a55b7acd221f6ba7b134f1e999087bee182330e8","other":"44462055ba68fdef337dd19d8123aace9a12284c13bc97687416b6b4ca0c94234ba7db6823651fc021d6ac1539e0c5321e763a7a12c9e7c8a583aac5369817d8","up":true},{"one":"a05a18161c2d01a0f122548c66509dd1fcf3ee52975035bc79fb059e9613b743a16cd6f5ac54090e68f51bcf76ff21fb3805ba3197a96b4236afb80f791df802","other":"276256790c9317d09ff7802f4ad0a85840fe62527390ce1790e1e3186e8b3f04acfaa41dcd02303d333423678a4037e4f4854676e79ced3232a3dbd772cc2680","up":true},{"one":"ed1ab28230ed533abf25633508d54f32bbff78a10c7a15fad5c2320cda9d9669c6d0e15689d8885400e64cbcd81730456f8f4bd5c98681d2cd8a8d4e1daec553","other":"f0299035cbddfdf7a78e5e3a400aaedf2d719d04e907ac0f9f067525e2f9bb913d985308a3a0d05467a64adf58c68a615c6327acf716c23631d0e829903f8b34","up":true},{"one":"afb5754b4748b7ac5628e32b242c90aab0e2fc7da58d8d5c8c775d13d8a6fd32240f1b89021587858168cbe7b3ea7ad07807728655eae0a9907060494a7c99ca","other":"e0420ba2a293315d810928a0e09a507c6aaf93977ba2c7598e9b83723b4a66682398ea17542c26767c7ff0f4ca09c537d3cc10dad283f079f1de73e25e87cb5c","up":true},{"one":"188bf77c9c1e45f009efe7aefdb040bdb47763980fe7eb0851295d657fa2a8978efbd2997c1dc30f4f0874eecf9ca9550487cf41da237b84d071963d35b6baff","other":"f62bd19b0fd052207743ce53c3d48a3a71e9219b75e41a9497a43e6368e559d5487ff1ab644f2df4106b500583e4344515f73187eec773115deb977b4ebc3514","up":true},{"one":"2502fc8ee0ccda79ad1dbd9c7cec625da85980b9116bdd56dc367d508039e25e5f65183293006e5b0df72fa9037a48bd2b133a757940d3587ff77ae2392e3eaf","other":"c89dbada7195464e732671ac6fff014cacfb4c879b63b6b84e7c1bce367522f759bd06e504b15f43a1735c6322356747fa5c4951882d4fd6cdf6f7cf13726719","up":true},{"one":"5984a296b49bfba30315501ce2ae88ed0392ab2959ac4e7e6b9a29090f344b9dd13873ca137e8317c402cd2e14a61965d5707065b8ded46c41a054731933719f","other":"fa897ba112f34839064c6871a4c9504c5d709eff5095a137c6a42726d58eb623af976cb96cc30db67e6ac9347c769f032aa4ebda884285a057059040c008ad3e","up":true},{"one":"3c6faa2e75a1699ddadd0e21fd35d3d6215715cfdc2dc89961cfd66773d2541776e785f3ebc833a70e3d1017a4edc571a5d5d9f9fbfc3fa0a8588f6c5023c164","other":"3572a22097a313b3adef95a7b6cc679f8d1201a156d764e61a9fbc63d123fb4826f7125402fb6569beed359e1c1e5e6cb6993a75975da6cd4ce15669a2eea758","up":true},{"one":"51302ef7b50922398ad802e917390bb4a3c24c877f2c2bcb7fcb34de9feca22673a2c594639914fe46a28837ffadfd03bb673afbc856aff5e59caf8e76082482","other":"cbed12dcab0aa04a96ec7e25bc2ee03b337c7b2006391baa7d2aff042c17ec70b82c5fb2dc916d085a7948541719d329f9b528b67ec6adb1ac2cc594d4ef1e42","up":true},{"one":"c6d1404873174254c0f15f25804da9a9d90db9c11c5cc895fab613b4deb7820f1733680b4ba9e4b61a664642ed6ee9ff012e13a0619c64ae067be6bab26962c6","other":"3e9c0bbd146d8b1040b4f379eecf802c27c4d0a70e64a9fb2e941a7edab9b00396b0b67fc5c891652743cdba3b342973ed49615b32da54b925954a799240431c","up":true},{"one":"73be4d2291c68ca4554a86fa170f7595210e1b6bbbeef3c1d5623a2b5d03a8fd6e26caa26afc639c20c8a351a89dad1086f91734f09afab62d28ec17b700fa01","other":"27fb8fcda1986644f985d68430c399f0299644b00b234c355362721081d12f9eb7686eea8f92eabda1d342bf56255e51c07b200c6233f95ac009f15b874eee97","up":true},{"one":"fd12c5c96df6ee76dd7beb9e4e4768dda4d2c498851b6435f13ca0175980d0e4a4ff1c002e4daf41a995f118500604764f88496fb9b2c22e28308d8649b525ce","other":"2502fc8ee0ccda79ad1dbd9c7cec625da85980b9116bdd56dc367d508039e25e5f65183293006e5b0df72fa9037a48bd2b133a757940d3587ff77ae2392e3eaf","up":true},{"one":"ecbdca037cd7892752345b48b4219478b1b334f83ce7140fcc72eb71784436b690ce7a41b03e013cefc19d64a34a20cfef1b9e2b535d938bcdcb39fe63645a42","other":"750ca601f07d65f426f6ea5f34e06238f9d7a931f022f9b0ebc811943d3725500cb3c6f00c8d05eb8d5b353c6534136dff38b9a8d3d4dc5bf49cd96875704d07","up":true},{"one":"f0299035cbddfdf7a78e5e3a400aaedf2d719d04e907ac0f9f067525e2f9bb913d985308a3a0d05467a64adf58c68a615c6327acf716c23631d0e829903f8b34","other":"178d5ce398a7114a63a0c953a59932e769891420f6b1544f08c082cd37b531b66757652d279b3036b03b04f8d46eceb0b46fb95646c6668e2921af75c06c3d97","up":true},{"one":"805d784527be4e32e84ddf045baee1ccf348cdf8288de3aae1a5379f762576b957525ef358d9b42c68a93394017880adc09bb2b1b5e01102dc7e4240baf2af95","other":"6ce3a68cb1e2924ad97f22006094c709a3dd8b4ca1546fbb037f841a9e5ac62def242015dbf6221bda610153db064edcbb58a78a35a06077b8c02bf5b2a33c04","up":true},{"one":"e7bb63c5187ee85d965fed5cb33d1678c0e090b4e4c3f3d859755565db18046cb60025453bdebf136373c416a2e6e56be063bca6c9257b7b175dcf966e274205","other":"a58a2dd3f5ee2471f0ddd555ffcc45d86e2d8c325585e3fe55eee878b8a626faccce73679d32811fc5d068c153e671673f4cd020f3c7fb37bc6fd9646931646a","up":true},{"one":"bf1e6eeb8b229f63b49213db499b71dcfe0ae45ee3f14685c7cbfa3f0a2150e52a89c853f4cd8c7a92e6e5f6083044efddfa17391662e3cff6290da679520404","other":"7a18392b8338108a996196ee190a93a1b9954c8e05a062c421da513a1828dfa739e7b224878c0670cf74bbc743c7ca7ee8cfee6b6a602fe1f4a82ecfbd38c2f4","up":true},{"one":"56b25623ac935f3a8aac1e2603a6bd15ace1e5714671954b47f2cab960cf47922828f415105602408d0a732a893ebeea6f9afab7f889bb235c81589548d09391","other":"1e3c83cabbe6852c987ae521b7fcb33185cf855c59b6235ebb8e57a6f860ccc159ddc01b4a21d251c8faca4559ceb271e046a51493ba148c0d3aed97ad208969","up":true},{"one":"7a18392b8338108a996196ee190a93a1b9954c8e05a062c421da513a1828dfa739e7b224878c0670cf74bbc743c7ca7ee8cfee6b6a602fe1f4a82ecfbd38c2f4","other":"86b84ddf64d301f6a9c4504c59eb4031d3167fb74101abea3b694845a009dc522be7b2e2720097ceea9f36058e160f42a2a438a33034929a5c1a7793c7ccef7b","up":true},{"one":"b2bea653b6ec9629c6f934be72fccf30acf836698e21e81dd8085f070ba8259ba43eee43c342738a4b782f5fbddd44caa28f56dffc08237ca7567c965ac3beca","other":"a58a2dd3f5ee2471f0ddd555ffcc45d86e2d8c325585e3fe55eee878b8a626faccce73679d32811fc5d068c153e671673f4cd020f3c7fb37bc6fd9646931646a","up":true},{"one":"5771bef7f50439f9b81d2a7bf7060b1ad4b38675d8f6abbac3cc4c215fb0cb5dd07f6873545b42218337556925566025476e2915b7b98e662a3dcd28bebf0eb4","other":"7a18392b8338108a996196ee190a93a1b9954c8e05a062c421da513a1828dfa739e7b224878c0670cf74bbc743c7ca7ee8cfee6b6a602fe1f4a82ecfbd38c2f4","up":true},{"one":"06472c89def07fa73188d253cf1acddc2be984842f3a234edb3db95449ba74928ab1395eca1b8978987769863afffb488fc27c9ac723aa24837b66c12f38d735","other":"cd0e9a45b45f9a67417fcde29d9f92c45ca4db46eebbfe47dcf6999e23e549e4205f42ada8e3fcd00e2fb5f832bb92a27a59b43c4a5909148d81399c2e8ce492","up":true},{"one":"a6ca1d5340f2d7021f541c81cf9aea519675462c8443bb6ddd93919962561b8f5a8431c3ec7e7e7d46c600b653e9a0638d2bb07cf4e29516bf9c4d3653f451b0","other":"b38213eaa5b419de787b70073ad8c7c819e48c5f76dec1507b54f1d7cb027211facbe7a170ac50212abe130935e8947d5a19d6b13790114e71cc18357902a889","up":true},{"one":"f0b2f1e8d46be656109adb18c60677ac9eb8fce7f42e15d9dbb25f94b4e426064780eaf32b79954b9bb72ea89953175da8de35380aaba18931cca374a7de2b11","other":"f0299035cbddfdf7a78e5e3a400aaedf2d719d04e907ac0f9f067525e2f9bb913d985308a3a0d05467a64adf58c68a615c6327acf716c23631d0e829903f8b34","up":true},{"one":"20f171ab01a814a2856a6cbe7929269f18f6329914289515e2cb9d078ac14ebdae457789dd638c6415b062799114570f556147d4bf9ac850f00b6d0762765ac1","other":"b38213eaa5b419de787b70073ad8c7c819e48c5f76dec1507b54f1d7cb027211facbe7a170ac50212abe130935e8947d5a19d6b13790114e71cc18357902a889","up":true},{"one":"49eb706cd7e95ad78502a508487d88b818861d94334aee36b2acef5c25cfff5c0efc2df9dc5dbb18acd4003d5cc0c843d3b40363adf2f62a14c04d814268fdee","other":"f0b2f1e8d46be656109adb18c60677ac9eb8fce7f42e15d9dbb25f94b4e426064780eaf32b79954b9bb72ea89953175da8de35380aaba18931cca374a7de2b11","up":true},{"one":"d8cfadac10473b31a4560c711636a05615f13054388065344642ff1d04246fb62eafeec06805264eafead111ed8134e11a8e21f42a0eb950c23b142e627bd8cb","other":"c93cb2df7ba6de8009872f5f7565891040d42e3b193ef1cdb321a0c167cc8fb8138900982bb8f6918fbaefac6e02dda01ee40f7a6beba1990dd44abe03cc3d01","up":true},{"one":"8e8de10fb3f53bd3a48455ebfa0a38ea5bd28c607e65506b263ece53a24d2361c2af7d7cd207e45b11bf71a3c33fa325fc8fd40a18b9c73019cce219c757c7ef","other":"9c3be147f9fe0fa34e553d9e4332969086ea7fa65294b61ca35c9f731f6b81d0b70cdcfe2ba52b6cea3c0de14b7ea40031b5cc40661c4bb821147894130d7bf5","up":true},{"one":"7a509686ebce91778fe22e834a94ab03f92457d41385099ba657fe62c7469a9669bddb9a3d7b0150efa1d2f40c69bc786c7f4ede1cf8b19411eea1d23cb7d56c","other":"03d2d77c008b5fa1063b1abc3152b879a529fe4fdb2dc174d6d85312264a38ee4cc49b342507a10fff1a4b0730f1ef8e008b0897d97bfd6f70050adb124d3596","up":true},{"one":"51ba4faf0988717a37dcddc0a60a70ead33bde310184fc450f9ca73c67f931e6767ad5930bcf409e5aeb613a9ff7a03e47de6fc13b33d8af0b87b38822ae6888","other":"9c6dcfef0e128dbfeca58b8ac625b08fb447b0d579bd3f18bc0e2be60d1ec2274595d0554ddba0ca7eb660099d3ea146d8076792b46c93841d2ecf8cf608f5ba","up":true},{"one":"e59940a6dfe35a6214e2e3daba9ad94e630004cd8f029e13a6649a56dc528ff94bc09d8d21a2f14a56b4ff759b60ebf3d27c1029862c183b8416fa3e950bdb55","other":"5d96577324edf1b5a1626999925982af1e0ba7bed8edcc3f740ba434f4b003cbbe2d632cad327c76e5b490d08c091c4a7b473353ab59139493657eb9525b8be2","up":true},{"one":"1e3c83cabbe6852c987ae521b7fcb33185cf855c59b6235ebb8e57a6f860ccc159ddc01b4a21d251c8faca4559ceb271e046a51493ba148c0d3aed97ad208969","other":"09b60de1e85bb6f7d2caf5b1ab58204d7d04531ece300dcd7bcc9157b8b3ef2a182758808a0eec6056034f29f52caadb7c690f498c1c8832ff7a6a9ecff308bd","up":true},{"one":"f6a07a1d361a4671e997d5eaadae61736291aff3896cb69f06bbc19bf7536dd152e0b15422b2fd9f8a9d2f9a251c9a07d0140319900e2cc9f25a59025c7dc91f","other":"178d5ce398a7114a63a0c953a59932e769891420f6b1544f08c082cd37b531b66757652d279b3036b03b04f8d46eceb0b46fb95646c6668e2921af75c06c3d97","up":true},{"one":"d71c50805f284ed3a759e2e81f220fbc73d6d0a7a261b4c9e7878c3da143cfc07afa83e1635b6a45530f71a60b9f17c485a2fd6617c6c2bff82bacc71c208087","other":"f0b2f1e8d46be656109adb18c60677ac9eb8fce7f42e15d9dbb25f94b4e426064780eaf32b79954b9bb72ea89953175da8de35380aaba18931cca374a7de2b11","up":true},{"one":"4bd17847bdf60ea93a670a84a0ff8fe028d35228e814d6ebc0ae4fa586ddef03cd79390d541d28ca3c05a7241ffe92ac182e63c251176b40db8fe05fefaa82be","other":"5d96577324edf1b5a1626999925982af1e0ba7bed8edcc3f740ba434f4b003cbbe2d632cad327c76e5b490d08c091c4a7b473353ab59139493657eb9525b8be2","up":true},{"one":"59730132a01ba848a3c050bb6234bca9a72deba33716960fc3ec89b186bfcd313b9bbf049939d5805ff98db2c53a9421ce6ec97d8b4cdbaea53ba264d80d0734","other":"28afc20d8f4779b285bb14870062dbb54796ec77623302e51bc1bafed9e2c35751c8469ffc482718e059875dfa2226195ed10999e251498cba3a444896cb67db","up":true},{"one":"f62bd19b0fd052207743ce53c3d48a3a71e9219b75e41a9497a43e6368e559d5487ff1ab644f2df4106b500583e4344515f73187eec773115deb977b4ebc3514","other":"f06ec3a90d34300f9fa2d48aea0c6b5f2f01f7833ffb0fad30e7f57e3916e344f3a4f9efe38e222443b8b00d3c7f5221c672491a129e4958e574afc283bd45b1","up":true},{"one":"b09af9e5552e72f918174963dad58a4492d3afa120f78e43820df7bff7fae9f6b52bc6c8c73d3a9af91d20134f4ff1b037db2ef0bc3d8c495a771d63de678bc0","other":"9c3be147f9fe0fa34e553d9e4332969086ea7fa65294b61ca35c9f731f6b81d0b70cdcfe2ba52b6cea3c0de14b7ea40031b5cc40661c4bb821147894130d7bf5","up":true},{"one":"cbed12dcab0aa04a96ec7e25bc2ee03b337c7b2006391baa7d2aff042c17ec70b82c5fb2dc916d085a7948541719d329f9b528b67ec6adb1ac2cc594d4ef1e42","other":"e0420ba2a293315d810928a0e09a507c6aaf93977ba2c7598e9b83723b4a66682398ea17542c26767c7ff0f4ca09c537d3cc10dad283f079f1de73e25e87cb5c","up":true},{"one":"5984a296b49bfba30315501ce2ae88ed0392ab2959ac4e7e6b9a29090f344b9dd13873ca137e8317c402cd2e14a61965d5707065b8ded46c41a054731933719f","other":"a1b2d0c6f24f5924c61e057fc65b994d9a6755560d740018b4c9ad0bb69212ec69974e22cb037dfeb7ea90a4493997f4c94029870bcc5fd47013b51ca0a26b5d","up":true},{"one":"d90a81a583c82d626b92f27244f027da4a0ae76e6d3bdc1de0af7be01798f1fb04b34ce60c6d8651a39d7a70915438a4aa63e5adf844a9f7e38dbf0b1dba754d","other":"27fb8fcda1986644f985d68430c399f0299644b00b234c355362721081d12f9eb7686eea8f92eabda1d342bf56255e51c07b200c6233f95ac009f15b874eee97","up":true},{"one":"da3e0fd71eb96ba2cab7f920d32f5425d1aad41d00765fdffb0b215d9dd5b60e2bc5929eafebee5b2b5a11aec164e141beff19d828aac7d1fabd3ffb0bfb8450","other":"4448a59bde9edb93edcdb4a77f3e2277b9c01ffea45496ee0533eb5192955a08a0f982e25cf772e0dae68735a55b7acd221f6ba7b134f1e999087bee182330e8","up":true},{"one":"a9e0b763852706722dc904b494293f9399c0fa32255890aa720285b8160335bb618f36b68a81b875a805384179f600defef474d486b4ea04b003ef6477ab7907","other":"3103510e00a3f49a5e715719049fc8c9c67a2373a548f326458aeb6d9c75ed92b94373638fd075def0209113b4e85d972c23f064539f7b041596184e40d7f9a2","up":true},{"one":"3103510e00a3f49a5e715719049fc8c9c67a2373a548f326458aeb6d9c75ed92b94373638fd075def0209113b4e85d972c23f064539f7b041596184e40d7f9a2","other":"077bcadade93e0d361e94f76dff464d61912bc067ce2ce17ebcabd757cca201cd64624ea809d99dd8ecb749d40528db9b3eb503ef5ec05e8845044cfaef720dc","up":true},{"one":"57bfbde13c71e035c96513870aa8215198f78806e7cdb01c54fbdb392de2c40386d768d6fdc4c68534a67e531867ca74d8ca4dcf34ff7f7f64ec35edee3e5f68","other":"5d917ffc9d70a38670941ce206aa7ea1b9ea65c1d783f14ebdf7c7afa6ca8b237112aaa9b1a3f757132093a604ef378280c5bdef02c2688049a91a412c399bfe","up":true},{"one":"077d2d032874e5ce70e9b928b7fe72c0326ba92394e16245e31d48b5731d3d32bfd86acf40825decff54bcd735e9ebfd94eba677c418ea7007baec9db4af676d","other":"077bcadade93e0d361e94f76dff464d61912bc067ce2ce17ebcabd757cca201cd64624ea809d99dd8ecb749d40528db9b3eb503ef5ec05e8845044cfaef720dc","up":true},{"one":"3e7820bb15c07f515bd63791b66136723dcc9878b3145fe0f238f6b41e3f2f7565ae55ef24f08ae461950ce1ae0c8a80fe5e4fd4f2f88c4acf4a2c94640df239","other":"fa897ba112f34839064c6871a4c9504c5d709eff5095a137c6a42726d58eb623af976cb96cc30db67e6ac9347c769f032aa4ebda884285a057059040c008ad3e","up":true},{"one":"c6d1404873174254c0f15f25804da9a9d90db9c11c5cc895fab613b4deb7820f1733680b4ba9e4b61a664642ed6ee9ff012e13a0619c64ae067be6bab26962c6","other":"c93cb2df7ba6de8009872f5f7565891040d42e3b193ef1cdb321a0c167cc8fb8138900982bb8f6918fbaefac6e02dda01ee40f7a6beba1990dd44abe03cc3d01","up":true},{"one":"31ac37862416c0e229c4a088ec179f23bdd1bf12dd464eb11c630ad531d7c3438671862e5458e2f6fbb32b857f857e6b8c17e5d93eb29a0e78bb5a65d7eb648c","other":"18bb6572965f4263c5a4d59a73027abc57a46122125ee58d871e95c993e6a1e8230438ce696a5f8880a08749837268b54319f7b0aa254c1a5bd453a8e9bcf84f","up":true},{"one":"1955bedf0bc9044b13a2c16158087123197c74147c86aa3b9389d308a364e80edbc573bcc836d8a262a77f3c9233ebddb1b82eca83cd0a0e4bda6564c443bb70","other":"a1b2d0c6f24f5924c61e057fc65b994d9a6755560d740018b4c9ad0bb69212ec69974e22cb037dfeb7ea90a4493997f4c94029870bcc5fd47013b51ca0a26b5d","up":true},{"one":"03d2d77c008b5fa1063b1abc3152b879a529fe4fdb2dc174d6d85312264a38ee4cc49b342507a10fff1a4b0730f1ef8e008b0897d97bfd6f70050adb124d3596","other":"a05a18161c2d01a0f122548c66509dd1fcf3ee52975035bc79fb059e9613b743a16cd6f5ac54090e68f51bcf76ff21fb3805ba3197a96b4236afb80f791df802","up":true},{"one":"2fdb4382c4bc2950948a8cff13a7df65627bc0b20661cae20fd29acab166c97701594ee3151d75c006ba86d1d68b624b1d1f78e3d1e2fc297844956ef82208a8","other":"f2ea93f43be9d0c3fa21f1496dc13c778977a6afdcba24c8b146de7dca2cdde62a5b792aab969e5b4b6c56f63066b336580d911f206049cc24cac32a25fc4306","up":true},{"one":"816e91fa8ff68ba067a89390ef61e7f23211e5e05049daa103ad1ff84b94fbcf535a6f6b515fb571939f5656869767c608513808800baba7e5d2b5f3a17a9691","other":"86b84ddf64d301f6a9c4504c59eb4031d3167fb74101abea3b694845a009dc522be7b2e2720097ceea9f36058e160f42a2a438a33034929a5c1a7793c7ccef7b","up":true},{"one":"a1b2d0c6f24f5924c61e057fc65b994d9a6755560d740018b4c9ad0bb69212ec69974e22cb037dfeb7ea90a4493997f4c94029870bcc5fd47013b51ca0a26b5d","other":"73be4d2291c68ca4554a86fa170f7595210e1b6bbbeef3c1d5623a2b5d03a8fd6e26caa26afc639c20c8a351a89dad1086f91734f09afab62d28ec17b700fa01","up":true},{"one":"f06ec3a90d34300f9fa2d48aea0c6b5f2f01f7833ffb0fad30e7f57e3916e344f3a4f9efe38e222443b8b00d3c7f5221c672491a129e4958e574afc283bd45b1","other":"3572a22097a313b3adef95a7b6cc679f8d1201a156d764e61a9fbc63d123fb4826f7125402fb6569beed359e1c1e5e6cb6993a75975da6cd4ce15669a2eea758","up":true},{"one":"188bf77c9c1e45f009efe7aefdb040bdb47763980fe7eb0851295d657fa2a8978efbd2997c1dc30f4f0874eecf9ca9550487cf41da237b84d071963d35b6baff","other":"3572a22097a313b3adef95a7b6cc679f8d1201a156d764e61a9fbc63d123fb4826f7125402fb6569beed359e1c1e5e6cb6993a75975da6cd4ce15669a2eea758","up":true},{"one":"3c6faa2e75a1699ddadd0e21fd35d3d6215715cfdc2dc89961cfd66773d2541776e785f3ebc833a70e3d1017a4edc571a5d5d9f9fbfc3fa0a8588f6c5023c164","other":"622646c74fdbae39ba191dbafff4906fb683fe0b0f2c303d080f5577a070876c41c8d3786ae7b953e5f682b8ec647727550d47302229ebb9f82bed24cea61132","up":true},{"one":"3274b5f48e6929e2305e980b558a4ca3c7cf800b75a6445ea2875cb379e127f3e793e9450a11e927682aa91b8af52e9560dece633833e0f207a8a8a38b7b9c54","other":"c6d1404873174254c0f15f25804da9a9d90db9c11c5cc895fab613b4deb7820f1733680b4ba9e4b61a664642ed6ee9ff012e13a0619c64ae067be6bab26962c6","up":true},{"one":"f2ea93f43be9d0c3fa21f1496dc13c778977a6afdcba24c8b146de7dca2cdde62a5b792aab969e5b4b6c56f63066b336580d911f206049cc24cac32a25fc4306","other":"73319a301ad3cf0ec09549d817c9523d61b74abb0cad87b737d41d900321e52722a84355f6f87bc7a5f848818c89a021bb0f3e5994f67c9a7b5bbfc98188a376","up":true},{"one":"09b60de1e85bb6f7d2caf5b1ab58204d7d04531ece300dcd7bcc9157b8b3ef2a182758808a0eec6056034f29f52caadb7c690f498c1c8832ff7a6a9ecff308bd","other":"44462055ba68fdef337dd19d8123aace9a12284c13bc97687416b6b4ca0c94234ba7db6823651fc021d6ac1539e0c5321e763a7a12c9e7c8a583aac5369817d8","up":true},{"one":"87fce129511a1be2777052d24b606acdfe7067f4e874ab04674a68664b378ea208975f7269a72af889d3d23cd930b6a181afa2cdef3f9f9491f715bd96ad8dc0","other":"18bb6572965f4263c5a4d59a73027abc57a46122125ee58d871e95c993e6a1e8230438ce696a5f8880a08749837268b54319f7b0aa254c1a5bd453a8e9bcf84f","up":true},{"one":"4448a59bde9edb93edcdb4a77f3e2277b9c01ffea45496ee0533eb5192955a08a0f982e25cf772e0dae68735a55b7acd221f6ba7b134f1e999087bee182330e8","other":"2fdb4382c4bc2950948a8cff13a7df65627bc0b20661cae20fd29acab166c97701594ee3151d75c006ba86d1d68b624b1d1f78e3d1e2fc297844956ef82208a8","up":true},{"one":"3540d888c3207d6df233afd1164ff9dde2551730862772547e04f7311de364968e113f38a7dea1ab0916a7f8307017de5b49578fa4ebcc39651e541fde51be48","other":"4448a59bde9edb93edcdb4a77f3e2277b9c01ffea45496ee0533eb5192955a08a0f982e25cf772e0dae68735a55b7acd221f6ba7b134f1e999087bee182330e8","up":true},{"one":"caad8529d498a4a1e1ba7573689a913500bd409345ef8e3656abca748269eb73b919282f7f2eb0087f81f7bc52c367657ac8be0cdac65d2490c7c50c874444b7","other":"a9e0b763852706722dc904b494293f9399c0fa32255890aa720285b8160335bb618f36b68a81b875a805384179f600defef474d486b4ea04b003ef6477ab7907","up":true},{"one":"489660042a8867d90a16ebb013968db26ca3edfc70f53320f511e35b3703eed09fbd787be5c06726a570a54aa15d129cd10db741523adf297929f909be4a0c71","other":"51ba4faf0988717a37dcddc0a60a70ead33bde310184fc450f9ca73c67f931e6767ad5930bcf409e5aeb613a9ff7a03e47de6fc13b33d8af0b87b38822ae6888","up":true},{"one":"ecbdca037cd7892752345b48b4219478b1b334f83ce7140fcc72eb71784436b690ce7a41b03e013cefc19d64a34a20cfef1b9e2b535d938bcdcb39fe63645a42","other":"a5cdff211813e17fadd43ec55a6cf4e97e6ca0c3b2cef0db58923b27d36207fd1a77146efb6093bd94d7eb89cc77d8c735fc64ab098839efc74a00b5e8687555","up":true},{"one":"077bcadade93e0d361e94f76dff464d61912bc067ce2ce17ebcabd757cca201cd64624ea809d99dd8ecb749d40528db9b3eb503ef5ec05e8845044cfaef720dc","other":"d90a81a583c82d626b92f27244f027da4a0ae76e6d3bdc1de0af7be01798f1fb04b34ce60c6d8651a39d7a70915438a4aa63e5adf844a9f7e38dbf0b1dba754d","up":true},{"one":"73be4d2291c68ca4554a86fa170f7595210e1b6bbbeef3c1d5623a2b5d03a8fd6e26caa26afc639c20c8a351a89dad1086f91734f09afab62d28ec17b700fa01","other":"f2ea93f43be9d0c3fa21f1496dc13c778977a6afdcba24c8b146de7dca2cdde62a5b792aab969e5b4b6c56f63066b336580d911f206049cc24cac32a25fc4306","up":true},{"one":"41994605708232b4ca7448c3bc0760a7b86bf26d442091e5ce6e92eac94925721d7e0eca04bdd03bb1bba1ef92deeccd4bf1b7c6c3318b7e8d031965c6646761","other":"ecbdca037cd7892752345b48b4219478b1b334f83ce7140fcc72eb71784436b690ce7a41b03e013cefc19d64a34a20cfef1b9e2b535d938bcdcb39fe63645a42","up":true},{"one":"27fb8fcda1986644f985d68430c399f0299644b00b234c355362721081d12f9eb7686eea8f92eabda1d342bf56255e51c07b200c6233f95ac009f15b874eee97","other":"1480f62d85ea32226d9f77ccd31780b3e704fb60618a588ae85dcd1c0e84e878c5fc092adfb306e8ebc7abba9ec429cb2447754502ef847cf931467f31fa50b2","up":true},{"one":"4de606aa7e722197b918c5f7f0db86a3081d48e89d21428b04f19c3ff3755eac0bddbff5fad8bda94b9e57f58fba2fecdbabbf710f7afb381bf4f1a4fe55cd93","other":"03d2d77c008b5fa1063b1abc3152b879a529fe4fdb2dc174d6d85312264a38ee4cc49b342507a10fff1a4b0730f1ef8e008b0897d97bfd6f70050adb124d3596","up":true},{"one":"670949178a5fad22da03af1e206c814a797c0e9eb4e3371f83612f121e5b56e767706a3ae36628cd0c86dd7bd1586ca4df57e2de27b28a31284ecf9176d330e5","other":"e0420ba2a293315d810928a0e09a507c6aaf93977ba2c7598e9b83723b4a66682398ea17542c26767c7ff0f4ca09c537d3cc10dad283f079f1de73e25e87cb5c","up":true},{"one":"805d784527be4e32e84ddf045baee1ccf348cdf8288de3aae1a5379f762576b957525ef358d9b42c68a93394017880adc09bb2b1b5e01102dc7e4240baf2af95","other":"59730132a01ba848a3c050bb6234bca9a72deba33716960fc3ec89b186bfcd313b9bbf049939d5805ff98db2c53a9421ce6ec97d8b4cdbaea53ba264d80d0734","up":true},{"one":"e9f7e58fda4b504275441d51929fbc98214abdc9ed552c7aa94c600a85d4e791d60c032304b29ae028adccec94984fc9a3d705a81462632f50ef45024eb0f64e","other":"8f625a4e4f4fd980c796d3aa535e58a39722492480cf6982d43fab02de63a5b4c1b5c7cd8402171dd792bb5d9c3e2bdd38176c061dbe3e5b0592af1339e3fd82","up":true},{"one":"93987e431a0058f2e942ccf8d3486d249cd2734d6494131b343e2c3a8fdd86cfcb12d0aaaf8fcb911ad3cdd682cc82118198195a7fdc915ab7853223f012eab6","other":"340420ee18d55913f790d0fcc2305b40b1e7bef2eddb79dda57801690aeeead693ebd1a9ff8557671f5ae136b3e65733306924bd00444cbc6e7c6235e5a2c77f","up":true},{"one":"178d5ce398a7114a63a0c953a59932e769891420f6b1544f08c082cd37b531b66757652d279b3036b03b04f8d46eceb0b46fb95646c6668e2921af75c06c3d97","other":"93987e431a0058f2e942ccf8d3486d249cd2734d6494131b343e2c3a8fdd86cfcb12d0aaaf8fcb911ad3cdd682cc82118198195a7fdc915ab7853223f012eab6","up":true},{"one":"665c3288c14dc1c17d85d17d634910f42183482c7e77c47e68f9b4f475b93e8c152246b9e34781606315ff6ef0f8360342500d15e4a2d67d9df6b72f30af64a7","other":"8f625a4e4f4fd980c796d3aa535e58a39722492480cf6982d43fab02de63a5b4c1b5c7cd8402171dd792bb5d9c3e2bdd38176c061dbe3e5b0592af1339e3fd82","up":true},{"one":"a40391285d1a97f1fb368b20c8e4d02be1bdebc0db41f00f99aac2f01893dc12256cd5a711117a981fbb3f9dfea18c19cf3603e925dbd67c4032b22b41eab8d5","other":"f0299035cbddfdf7a78e5e3a400aaedf2d719d04e907ac0f9f067525e2f9bb913d985308a3a0d05467a64adf58c68a615c6327acf716c23631d0e829903f8b34","up":true},{"one":"340420ee18d55913f790d0fcc2305b40b1e7bef2eddb79dda57801690aeeead693ebd1a9ff8557671f5ae136b3e65733306924bd00444cbc6e7c6235e5a2c77f","other":"545850cb90787d49c579b1ed54a753ebd00eaafe3f1bd04d57266e4912fb1cdd654446ef054a973a583ce8dfc6cc130b6f90e63bcf75372fc21c445f8e1e6005","up":true},{"one":"cd0e9a45b45f9a67417fcde29d9f92c45ca4db46eebbfe47dcf6999e23e549e4205f42ada8e3fcd00e2fb5f832bb92a27a59b43c4a5909148d81399c2e8ce492","other":"f0b2f1e8d46be656109adb18c60677ac9eb8fce7f42e15d9dbb25f94b4e426064780eaf32b79954b9bb72ea89953175da8de35380aaba18931cca374a7de2b11","up":true},{"one":"b38213eaa5b419de787b70073ad8c7c819e48c5f76dec1507b54f1d7cb027211facbe7a170ac50212abe130935e8947d5a19d6b13790114e71cc18357902a889","other":"26cf4ea45b9a76daab82a57126f9c6f8726d2eb973e205ab4ab69c8b8be11a32a7eb5c3807e952cd428ce5ddd88f143d4fc9ff8c3de3d159855675afce715615","up":true},{"one":"08900197e74e285a5a8a9cc53fbd420bb35043ab27eb2d9eab22615e736a093abfa235c17f667dcc791cb50b9022082eafd9fba030194cc84f0358b769adc85b","other":"59730132a01ba848a3c050bb6234bca9a72deba33716960fc3ec89b186bfcd313b9bbf049939d5805ff98db2c53a9421ce6ec97d8b4cdbaea53ba264d80d0734","up":true},{"one":"2502fc8ee0ccda79ad1dbd9c7cec625da85980b9116bdd56dc367d508039e25e5f65183293006e5b0df72fa9037a48bd2b133a757940d3587ff77ae2392e3eaf","other":"340420ee18d55913f790d0fcc2305b40b1e7bef2eddb79dda57801690aeeead693ebd1a9ff8557671f5ae136b3e65733306924bd00444cbc6e7c6235e5a2c77f","up":true},{"one":"afb5754b4748b7ac5628e32b242c90aab0e2fc7da58d8d5c8c775d13d8a6fd32240f1b89021587858168cbe7b3ea7ad07807728655eae0a9907060494a7c99ca","other":"ecbdca037cd7892752345b48b4219478b1b334f83ce7140fcc72eb71784436b690ce7a41b03e013cefc19d64a34a20cfef1b9e2b535d938bcdcb39fe63645a42","up":true},{"one":"a05a18161c2d01a0f122548c66509dd1fcf3ee52975035bc79fb059e9613b743a16cd6f5ac54090e68f51bcf76ff21fb3805ba3197a96b4236afb80f791df802","other":"6ce3a68cb1e2924ad97f22006094c709a3dd8b4ca1546fbb037f841a9e5ac62def242015dbf6221bda610153db064edcbb58a78a35a06077b8c02bf5b2a33c04","up":true},{"one":"ed1ab28230ed533abf25633508d54f32bbff78a10c7a15fad5c2320cda9d9669c6d0e15689d8885400e64cbcd81730456f8f4bd5c98681d2cd8a8d4e1daec553","other":"340420ee18d55913f790d0fcc2305b40b1e7bef2eddb79dda57801690aeeead693ebd1a9ff8557671f5ae136b3e65733306924bd00444cbc6e7c6235e5a2c77f","up":true},{"one":"da15d60a4b9a8816ce24c20f6c941c51229c1fb5e070b8b29be2977c2f7b41f8f17e4b6efe75f465e7935ded1ba17472f046eac73393db7197018fa86d11c31f","other":"f8052e328014f39157036f3dcecdb23419c0959473a88282605f10add681ef5cbfb1e926b522f98b8401272113b677a67225874d1afb0bff4b11140cc071de44","up":true},{"one":"86b84ddf64d301f6a9c4504c59eb4031d3167fb74101abea3b694845a009dc522be7b2e2720097ceea9f36058e160f42a2a438a33034929a5c1a7793c7ccef7b","other":"49eb706cd7e95ad78502a508487d88b818861d94334aee36b2acef5c25cfff5c0efc2df9dc5dbb18acd4003d5cc0c843d3b40363adf2f62a14c04d814268fdee","up":true},{"one":"ab3814579882e9fd8d464f4f3c8a421be37822ba7f42c5f5e787e81125ec032f9ccf90a138c0b57f0a813b55b583f80d66284f795e2c82d80d2869e1fc770be5","other":"178d5ce398a7114a63a0c953a59932e769891420f6b1544f08c082cd37b531b66757652d279b3036b03b04f8d46eceb0b46fb95646c6668e2921af75c06c3d97","up":true},{"one":"fd12c5c96df6ee76dd7beb9e4e4768dda4d2c498851b6435f13ca0175980d0e4a4ff1c002e4daf41a995f118500604764f88496fb9b2c22e28308d8649b525ce","other":"59730132a01ba848a3c050bb6234bca9a72deba33716960fc3ec89b186bfcd313b9bbf049939d5805ff98db2c53a9421ce6ec97d8b4cdbaea53ba264d80d0734","up":true},{"one":"51302ef7b50922398ad802e917390bb4a3c24c877f2c2bcb7fcb34de9feca22673a2c594639914fe46a28837ffadfd03bb673afbc856aff5e59caf8e76082482","other":"e9f7e58fda4b504275441d51929fbc98214abdc9ed552c7aa94c600a85d4e791d60c032304b29ae028adccec94984fc9a3d705a81462632f50ef45024eb0f64e","up":true},{"one":"1e0a46ff50fb6d9a2c218a851763ff86c42e4d61dddffb7188481febc0f3180bc8f31973d336b2a6e25802acd4fed6d905d89c6d4d7d8080fb12741f9c5ab7e6","other":"77327983685f39f006806170fe351063a58ff1bd8dedc222d538e86cfd18abdfefd548328f25fc5afde8170aa5c35311353019468f2b439c331837ddfbb25a52","up":true},{"one":"bfef26733f5196a11484bcc28d88776e747189ae7cec883ff39a27cfeee6d9d1efb34560c9f8e75eec43fc069a2ce5f0c78107a36cc8a569d37bd5306aecf23a","other":"51302ef7b50922398ad802e917390bb4a3c24c877f2c2bcb7fcb34de9feca22673a2c594639914fe46a28837ffadfd03bb673afbc856aff5e59caf8e76082482","up":true},{"one":"f0299035cbddfdf7a78e5e3a400aaedf2d719d04e907ac0f9f067525e2f9bb913d985308a3a0d05467a64adf58c68a615c6327acf716c23631d0e829903f8b34","other":"93987e431a0058f2e942ccf8d3486d249cd2734d6494131b343e2c3a8fdd86cfcb12d0aaaf8fcb911ad3cdd682cc82118198195a7fdc915ab7853223f012eab6","up":true},{"one":"d90a81a583c82d626b92f27244f027da4a0ae76e6d3bdc1de0af7be01798f1fb04b34ce60c6d8651a39d7a70915438a4aa63e5adf844a9f7e38dbf0b1dba754d","other":"f2ea93f43be9d0c3fa21f1496dc13c778977a6afdcba24c8b146de7dca2cdde62a5b792aab969e5b4b6c56f63066b336580d911f206049cc24cac32a25fc4306","up":true},{"one":"f7637cdd5ef26de40b9055c1df91a45725670c8df11ae934c0d99d2547c3eb4c42a16dbb2e75bcaf4b1b9347c48db65f549a0623179a08dd8cbad92f5bca08cf","other":"ce1309c8505b446363ae37cd3b1ee3e03ced537bed20aca5d8c4be2133917c408845ef5d0f65876974be2803dfb824827cf5c5a2d050d6ef26cdabcbf3a2dc31","up":true},{"one":"7a509686ebce91778fe22e834a94ab03f92457d41385099ba657fe62c7469a9669bddb9a3d7b0150efa1d2f40c69bc786c7f4ede1cf8b19411eea1d23cb7d56c","other":"178d5ce398a7114a63a0c953a59932e769891420f6b1544f08c082cd37b531b66757652d279b3036b03b04f8d46eceb0b46fb95646c6668e2921af75c06c3d97","up":true},{"one":"c773af3af01ee8ab9fa8d06987baf4f10c394fdd386d69b7a7362f4b68fd6fc082337d3b33a19d584c5801a3e9198225d7b61f6629e34ce823be70908339f4c7","other":"da3e0fd71eb96ba2cab7f920d32f5425d1aad41d00765fdffb0b215d9dd5b60e2bc5929eafebee5b2b5a11aec164e141beff19d828aac7d1fabd3ffb0bfb8450","up":true},{"one":"da3e0fd71eb96ba2cab7f920d32f5425d1aad41d00765fdffb0b215d9dd5b60e2bc5929eafebee5b2b5a11aec164e141beff19d828aac7d1fabd3ffb0bfb8450","other":"caad8529d498a4a1e1ba7573689a913500bd409345ef8e3656abca748269eb73b919282f7f2eb0087f81f7bc52c367657ac8be0cdac65d2490c7c50c874444b7","up":true},{"one":"750ca601f07d65f426f6ea5f34e06238f9d7a931f022f9b0ebc811943d3725500cb3c6f00c8d05eb8d5b353c6534136dff38b9a8d3d4dc5bf49cd96875704d07","other":"9c6dcfef0e128dbfeca58b8ac625b08fb447b0d579bd3f18bc0e2be60d1ec2274595d0554ddba0ca7eb660099d3ea146d8076792b46c93841d2ecf8cf608f5ba","up":true},{"one":"77327983685f39f006806170fe351063a58ff1bd8dedc222d538e86cfd18abdfefd548328f25fc5afde8170aa5c35311353019468f2b439c331837ddfbb25a52","other":"a58a2dd3f5ee2471f0ddd555ffcc45d86e2d8c325585e3fe55eee878b8a626faccce73679d32811fc5d068c153e671673f4cd020f3c7fb37bc6fd9646931646a","up":true},{"one":"e7bb63c5187ee85d965fed5cb33d1678c0e090b4e4c3f3d859755565db18046cb60025453bdebf136373c416a2e6e56be063bca6c9257b7b175dcf966e274205","other":"bf1e6eeb8b229f63b49213db499b71dcfe0ae45ee3f14685c7cbfa3f0a2150e52a89c853f4cd8c7a92e6e5f6083044efddfa17391662e3cff6290da679520404","up":true},{"one":"7a18392b8338108a996196ee190a93a1b9954c8e05a062c421da513a1828dfa739e7b224878c0670cf74bbc743c7ca7ee8cfee6b6a602fe1f4a82ecfbd38c2f4","other":"155805f787600f9f9518cf8836f491885b64868bfe0023975bcd12776925a424fb5aa3199dc178e83294e97f347a373d05d2422578a08eeeb2d15a178d28964f","up":true},{"one":"f04c3ae9fe957a14c249acf3ea2e8407d04d108fc01e75f6d52aaf5073b3450025012d138a75b857473eea4d20e57c99b92bff9041f269d995543d7c67a92ec6","other":"3e9c0bbd146d8b1040b4f379eecf802c27c4d0a70e64a9fb2e941a7edab9b00396b0b67fc5c891652743cdba3b342973ed49615b32da54b925954a799240431c","up":true},{"one":"eb097186ff58d96a7ead7a7f9c05a44075d84537bd4fd3f82857bf2c45bee1c6dece434a7707cde69e96f02366859cab4c991fdb7615e113a868d4b9c7524a45","other":"c6d1404873174254c0f15f25804da9a9d90db9c11c5cc895fab613b4deb7820f1733680b4ba9e4b61a664642ed6ee9ff012e13a0619c64ae067be6bab26962c6","up":true},{"one":"816e91fa8ff68ba067a89390ef61e7f23211e5e05049daa103ad1ff84b94fbcf535a6f6b515fb571939f5656869767c608513808800baba7e5d2b5f3a17a9691","other":"896c74ca4cc4cbb9d2b6606d0ebfd6427952c2e16aedbf36933fa3d01f1c505fcd663f3d01c0cf096bef9cfd0bae4595ec7c221cfc362e19a5b7c60614a9658b","up":true},{"one":"b2bea653b6ec9629c6f934be72fccf30acf836698e21e81dd8085f070ba8259ba43eee43c342738a4b782f5fbddd44caa28f56dffc08237ca7567c965ac3beca","other":"77327983685f39f006806170fe351063a58ff1bd8dedc222d538e86cfd18abdfefd548328f25fc5afde8170aa5c35311353019468f2b439c331837ddfbb25a52","up":true},{"one":"a5cdff211813e17fadd43ec55a6cf4e97e6ca0c3b2cef0db58923b27d36207fd1a77146efb6093bd94d7eb89cc77d8c735fc64ab098839efc74a00b5e8687555","other":"2d6d55edd34c0d9a0130b4806e409bbe18cdda5c2b221cf46136718ec20ffc9d8e92838d78aff92fbcc85f5d081da361dd1e3d7f3d4e1ea57877d6bb7aa0b6f7","up":true},{"one":"03e478a3aae82e06e215e40272a420037a61442d11c49c367a5ee6a21868d29a17ea8b9284f013d020c4740f296a6a22bc64d33d1c2807f9ab8dc48c0cfec18a","other":"20bdc859d58d8bf419df64fd6ee1d4363c1d5f403af3abef2720d7d3933924672e12e23e5d76b28e0f6726acf58bdc5eb258cba635e327cbd0b564523305da75","up":true},{"one":"d71c50805f284ed3a759e2e81f220fbc73d6d0a7a261b4c9e7878c3da143cfc07afa83e1635b6a45530f71a60b9f17c485a2fd6617c6c2bff82bacc71c208087","other":"e59940a6dfe35a6214e2e3daba9ad94e630004cd8f029e13a6649a56dc528ff94bc09d8d21a2f14a56b4ff759b60ebf3d27c1029862c183b8416fa3e950bdb55","up":true},{"one":"5771bef7f50439f9b81d2a7bf7060b1ad4b38675d8f6abbac3cc4c215fb0cb5dd07f6873545b42218337556925566025476e2915b7b98e662a3dcd28bebf0eb4","other":"e7bb63c5187ee85d965fed5cb33d1678c0e090b4e4c3f3d859755565db18046cb60025453bdebf136373c416a2e6e56be063bca6c9257b7b175dcf966e274205","up":true},{"one":"06472c89def07fa73188d253cf1acddc2be984842f3a234edb3db95449ba74928ab1395eca1b8978987769863afffb488fc27c9ac723aa24837b66c12f38d735","other":"a05a18161c2d01a0f122548c66509dd1fcf3ee52975035bc79fb059e9613b743a16cd6f5ac54090e68f51bcf76ff21fb3805ba3197a96b4236afb80f791df802","up":true},{"one":"57bfbde13c71e035c96513870aa8215198f78806e7cdb01c54fbdb392de2c40386d768d6fdc4c68534a67e531867ca74d8ca4dcf34ff7f7f64ec35edee3e5f68","other":"93987e431a0058f2e942ccf8d3486d249cd2734d6494131b343e2c3a8fdd86cfcb12d0aaaf8fcb911ad3cdd682cc82118198195a7fdc915ab7853223f012eab6","up":true},{"one":"f0b2f1e8d46be656109adb18c60677ac9eb8fce7f42e15d9dbb25f94b4e426064780eaf32b79954b9bb72ea89953175da8de35380aaba18931cca374a7de2b11","other":"e59940a6dfe35a6214e2e3daba9ad94e630004cd8f029e13a6649a56dc528ff94bc09d8d21a2f14a56b4ff759b60ebf3d27c1029862c183b8416fa3e950bdb55","up":true},{"one":"20f171ab01a814a2856a6cbe7929269f18f6329914289515e2cb9d078ac14ebdae457789dd638c6415b062799114570f556147d4bf9ac850f00b6d0762765ac1","other":"a6ca1d5340f2d7021f541c81cf9aea519675462c8443bb6ddd93919962561b8f5a8431c3ec7e7e7d46c600b653e9a0638d2bb07cf4e29516bf9c4d3653f451b0","up":true},{"one":"d8cfadac10473b31a4560c711636a05615f13054388065344642ff1d04246fb62eafeec06805264eafead111ed8134e11a8e21f42a0eb950c23b142e627bd8cb","other":"3e9c0bbd146d8b1040b4f379eecf802c27c4d0a70e64a9fb2e941a7edab9b00396b0b67fc5c891652743cdba3b342973ed49615b32da54b925954a799240431c","up":true},{"one":"49eb706cd7e95ad78502a508487d88b818861d94334aee36b2acef5c25cfff5c0efc2df9dc5dbb18acd4003d5cc0c843d3b40363adf2f62a14c04d814268fdee","other":"d71c50805f284ed3a759e2e81f220fbc73d6d0a7a261b4c9e7878c3da143cfc07afa83e1635b6a45530f71a60b9f17c485a2fd6617c6c2bff82bacc71c208087","up":true},{"one":"44462055ba68fdef337dd19d8123aace9a12284c13bc97687416b6b4ca0c94234ba7db6823651fc021d6ac1539e0c5321e763a7a12c9e7c8a583aac5369817d8","other":"f2ea93f43be9d0c3fa21f1496dc13c778977a6afdcba24c8b146de7dca2cdde62a5b792aab969e5b4b6c56f63066b336580d911f206049cc24cac32a25fc4306","up":true},{"one":"c6d1404873174254c0f15f25804da9a9d90db9c11c5cc895fab613b4deb7820f1733680b4ba9e4b61a664642ed6ee9ff012e13a0619c64ae067be6bab26962c6","other":"26cf4ea45b9a76daab82a57126f9c6f8726d2eb973e205ab4ab69c8b8be11a32a7eb5c3807e952cd428ce5ddd88f143d4fc9ff8c3de3d159855675afce715615","up":true},{"one":"872cdbb6d74fb55fd2d51877ef7804bdd2eeb6de0297eb2ce18b67e52379b147d54a46d2385ec9293eb21736bed4191d92c5c75e8e81fc5a6c691970e019f570","other":"18bb6572965f4263c5a4d59a73027abc57a46122125ee58d871e95c993e6a1e8230438ce696a5f8880a08749837268b54319f7b0aa254c1a5bd453a8e9bcf84f","up":true},{"one":"dafb58b2fc8a14f2b23b7df33d28aa7847a08f80e9c21a654d4c97d928e1afe6585644d27f22442cf70d229c32783be6a03c0920be153fc4d9f3b273dfa90ec3","other":"2d6d55edd34c0d9a0130b4806e409bbe18cdda5c2b221cf46136718ec20ffc9d8e92838d78aff92fbcc85f5d081da361dd1e3d7f3d4e1ea57877d6bb7aa0b6f7","up":true},{"one":"5d917ffc9d70a38670941ce206aa7ea1b9ea65c1d783f14ebdf7c7afa6ca8b237112aaa9b1a3f757132093a604ef378280c5bdef02c2688049a91a412c399bfe","other":"f0299035cbddfdf7a78e5e3a400aaedf2d719d04e907ac0f9f067525e2f9bb913d985308a3a0d05467a64adf58c68a615c6327acf716c23631d0e829903f8b34","up":true},{"one":"8e8de10fb3f53bd3a48455ebfa0a38ea5bd28c607e65506b263ece53a24d2361c2af7d7cd207e45b11bf71a3c33fa325fc8fd40a18b9c73019cce219c757c7ef","other":"2fdb4382c4bc2950948a8cff13a7df65627bc0b20661cae20fd29acab166c97701594ee3151d75c006ba86d1d68b624b1d1f78e3d1e2fc297844956ef82208a8","up":true},{"one":"56b25623ac935f3a8aac1e2603a6bd15ace1e5714671954b47f2cab960cf47922828f415105602408d0a732a893ebeea6f9afab7f889bb235c81589548d09391","other":"2fdb4382c4bc2950948a8cff13a7df65627bc0b20661cae20fd29acab166c97701594ee3151d75c006ba86d1d68b624b1d1f78e3d1e2fc297844956ef82208a8","up":true},{"one":"f8052e328014f39157036f3dcecdb23419c0959473a88282605f10add681ef5cbfb1e926b522f98b8401272113b677a67225874d1afb0bff4b11140cc071de44","other":"3e7820bb15c07f515bd63791b66136723dcc9878b3145fe0f238f6b41e3f2f7565ae55ef24f08ae461950ce1ae0c8a80fe5e4fd4f2f88c4acf4a2c94640df239","up":true},{"one":"4bd17847bdf60ea93a670a84a0ff8fe028d35228e814d6ebc0ae4fa586ddef03cd79390d541d28ca3c05a7241ffe92ac182e63c251176b40db8fe05fefaa82be","other":"f62bd19b0fd052207743ce53c3d48a3a71e9219b75e41a9497a43e6368e559d5487ff1ab644f2df4106b500583e4344515f73187eec773115deb977b4ebc3514","up":true},{"one":"1955bedf0bc9044b13a2c16158087123197c74147c86aa3b9389d308a364e80edbc573bcc836d8a262a77f3c9233ebddb1b82eca83cd0a0e4bda6564c443bb70","other":"d90a81a583c82d626b92f27244f027da4a0ae76e6d3bdc1de0af7be01798f1fb04b34ce60c6d8651a39d7a70915438a4aa63e5adf844a9f7e38dbf0b1dba754d","up":true},{"one":"9c3be147f9fe0fa34e553d9e4332969086ea7fa65294b61ca35c9f731f6b81d0b70cdcfe2ba52b6cea3c0de14b7ea40031b5cc40661c4bb821147894130d7bf5","other":"f06ec3a90d34300f9fa2d48aea0c6b5f2f01f7833ffb0fad30e7f57e3916e344f3a4f9efe38e222443b8b00d3c7f5221c672491a129e4958e574afc283bd45b1","up":true},{"one":"b09af9e5552e72f918174963dad58a4492d3afa120f78e43820df7bff7fae9f6b52bc6c8c73d3a9af91d20134f4ff1b037db2ef0bc3d8c495a771d63de678bc0","other":"3c6faa2e75a1699ddadd0e21fd35d3d6215715cfdc2dc89961cfd66773d2541776e785f3ebc833a70e3d1017a4edc571a5d5d9f9fbfc3fa0a8588f6c5023c164","up":true},{"one":"3274b5f48e6929e2305e980b558a4ca3c7cf800b75a6445ea2875cb379e127f3e793e9450a11e927682aa91b8af52e9560dece633833e0f207a8a8a38b7b9c54","other":"03e478a3aae82e06e215e40272a420037a61442d11c49c367a5ee6a21868d29a17ea8b9284f013d020c4740f296a6a22bc64d33d1c2807f9ab8dc48c0cfec18a","up":true},{"one":"2d6d55edd34c0d9a0130b4806e409bbe18cdda5c2b221cf46136718ec20ffc9d8e92838d78aff92fbcc85f5d081da361dd1e3d7f3d4e1ea57877d6bb7aa0b6f7","other":"077bcadade93e0d361e94f76dff464d61912bc067ce2ce17ebcabd757cca201cd64624ea809d99dd8ecb749d40528db9b3eb503ef5ec05e8845044cfaef720dc","up":true},{"one":"622646c74fdbae39ba191dbafff4906fb683fe0b0f2c303d080f5577a070876c41c8d3786ae7b953e5f682b8ec647727550d47302229ebb9f82bed24cea61132","other":"8e8de10fb3f53bd3a48455ebfa0a38ea5bd28c607e65506b263ece53a24d2361c2af7d7cd207e45b11bf71a3c33fa325fc8fd40a18b9c73019cce219c757c7ef","up":true},{"one":"5984a296b49bfba30315501ce2ae88ed0392ab2959ac4e7e6b9a29090f344b9dd13873ca137e8317c402cd2e14a61965d5707065b8ded46c41a054731933719f","other":"d90a81a583c82d626b92f27244f027da4a0ae76e6d3bdc1de0af7be01798f1fb04b34ce60c6d8651a39d7a70915438a4aa63e5adf844a9f7e38dbf0b1dba754d","up":true},{"one":"9e6c1c6e871638182c4b54ac89352ef5c2bca0a99424a1369013e7c182883da0e8d7ab96b3c8254c31fa315b941d8ddee153157626821fc78c2cae951c1c9053","other":"03d2d77c008b5fa1063b1abc3152b879a529fe4fdb2dc174d6d85312264a38ee4cc49b342507a10fff1a4b0730f1ef8e008b0897d97bfd6f70050adb124d3596","up":true},{"one":"a9e0b763852706722dc904b494293f9399c0fa32255890aa720285b8160335bb618f36b68a81b875a805384179f600defef474d486b4ea04b003ef6477ab7907","other":"31ac37862416c0e229c4a088ec179f23bdd1bf12dd464eb11c630ad531d7c3438671862e5458e2f6fbb32b857f857e6b8c17e5d93eb29a0e78bb5a65d7eb648c","up":true},{"one":"3103510e00a3f49a5e715719049fc8c9c67a2373a548f326458aeb6d9c75ed92b94373638fd075def0209113b4e85d972c23f064539f7b041596184e40d7f9a2","other":"31ac37862416c0e229c4a088ec179f23bdd1bf12dd464eb11c630ad531d7c3438671862e5458e2f6fbb32b857f857e6b8c17e5d93eb29a0e78bb5a65d7eb648c","up":true},{"one":"c93cb2df7ba6de8009872f5f7565891040d42e3b193ef1cdb321a0c167cc8fb8138900982bb8f6918fbaefac6e02dda01ee40f7a6beba1990dd44abe03cc3d01","other":"20bdc859d58d8bf419df64fd6ee1d4363c1d5f403af3abef2720d7d3933924672e12e23e5d76b28e0f6726acf58bdc5eb258cba635e327cbd0b564523305da75","up":true},{"one":"077d2d032874e5ce70e9b928b7fe72c0326ba92394e16245e31d48b5731d3d32bfd86acf40825decff54bcd735e9ebfd94eba677c418ea7007baec9db4af676d","other":"87fce129511a1be2777052d24b606acdfe7067f4e874ab04674a68664b378ea208975f7269a72af889d3d23cd930b6a181afa2cdef3f9f9491f715bd96ad8dc0","up":true},{"one":"3e7820bb15c07f515bd63791b66136723dcc9878b3145fe0f238f6b41e3f2f7565ae55ef24f08ae461950ce1ae0c8a80fe5e4fd4f2f88c4acf4a2c94640df239","other":"a1b2d0c6f24f5924c61e057fc65b994d9a6755560d740018b4c9ad0bb69212ec69974e22cb037dfeb7ea90a4493997f4c94029870bcc5fd47013b51ca0a26b5d","up":true},{"one":"276256790c9317d09ff7802f4ad0a85840fe62527390ce1790e1e3186e8b3f04acfaa41dcd02303d333423678a4037e4f4854676e79ced3232a3dbd772cc2680","other":"6ce3a68cb1e2924ad97f22006094c709a3dd8b4ca1546fbb037f841a9e5ac62def242015dbf6221bda610153db064edcbb58a78a35a06077b8c02bf5b2a33c04","up":true},{"one":"c89dbada7195464e732671ac6fff014cacfb4c879b63b6b84e7c1bce367522f759bd06e504b15f43a1735c6322356747fa5c4951882d4fd6cdf6f7cf13726719","other":"276256790c9317d09ff7802f4ad0a85840fe62527390ce1790e1e3186e8b3f04acfaa41dcd02303d333423678a4037e4f4854676e79ced3232a3dbd772cc2680","up":true},{"one":"2fdb4382c4bc2950948a8cff13a7df65627bc0b20661cae20fd29acab166c97701594ee3151d75c006ba86d1d68b624b1d1f78e3d1e2fc297844956ef82208a8","other":"f7637cdd5ef26de40b9055c1df91a45725670c8df11ae934c0d99d2547c3eb4c42a16dbb2e75bcaf4b1b9347c48db65f549a0623179a08dd8cbad92f5bca08cf","up":true},{"one":"188bf77c9c1e45f009efe7aefdb040bdb47763980fe7eb0851295d657fa2a8978efbd2997c1dc30f4f0874eecf9ca9550487cf41da237b84d071963d35b6baff","other":"f7637cdd5ef26de40b9055c1df91a45725670c8df11ae934c0d99d2547c3eb4c42a16dbb2e75bcaf4b1b9347c48db65f549a0623179a08dd8cbad92f5bca08cf","up":true},{"one":"09b60de1e85bb6f7d2caf5b1ab58204d7d04531ece300dcd7bcc9157b8b3ef2a182758808a0eec6056034f29f52caadb7c690f498c1c8832ff7a6a9ecff308bd","other":"3c6faa2e75a1699ddadd0e21fd35d3d6215715cfdc2dc89961cfd66773d2541776e785f3ebc833a70e3d1017a4edc571a5d5d9f9fbfc3fa0a8588f6c5023c164","up":true},{"one":"f2ea93f43be9d0c3fa21f1496dc13c778977a6afdcba24c8b146de7dca2cdde62a5b792aab969e5b4b6c56f63066b336580d911f206049cc24cac32a25fc4306","other":"f62bd19b0fd052207743ce53c3d48a3a71e9219b75e41a9497a43e6368e559d5487ff1ab644f2df4106b500583e4344515f73187eec773115deb977b4ebc3514","up":true},{"one":"4448a59bde9edb93edcdb4a77f3e2277b9c01ffea45496ee0533eb5192955a08a0f982e25cf772e0dae68735a55b7acd221f6ba7b134f1e999087bee182330e8","other":"f06ec3a90d34300f9fa2d48aea0c6b5f2f01f7833ffb0fad30e7f57e3916e344f3a4f9efe38e222443b8b00d3c7f5221c672491a129e4958e574afc283bd45b1","up":true},{"one":"3540d888c3207d6df233afd1164ff9dde2551730862772547e04f7311de364968e113f38a7dea1ab0916a7f8307017de5b49578fa4ebcc39651e541fde51be48","other":"9c3be147f9fe0fa34e553d9e4332969086ea7fa65294b61ca35c9f731f6b81d0b70cdcfe2ba52b6cea3c0de14b7ea40031b5cc40661c4bb821147894130d7bf5","up":true},{"one":"33e3ab7108ced43102003c3b3192b194100f32b6bcb67bb772ea9696e35721196699cf01e443f7cdf8076ad83aaf7468b75c71d03efb95f4c07cf0742ea9af81","other":"665c3288c14dc1c17d85d17d634910f42183482c7e77c47e68f9b4f475b93e8c152246b9e34781606315ff6ef0f8360342500d15e4a2d67d9df6b72f30af64a7","up":true},{"one":"ce1309c8505b446363ae37cd3b1ee3e03ced537bed20aca5d8c4be2133917c408845ef5d0f65876974be2803dfb824827cf5c5a2d050d6ef26cdabcbf3a2dc31","other":"188bf77c9c1e45f009efe7aefdb040bdb47763980fe7eb0851295d657fa2a8978efbd2997c1dc30f4f0874eecf9ca9550487cf41da237b84d071963d35b6baff","up":true},{"one":"a1b2d0c6f24f5924c61e057fc65b994d9a6755560d740018b4c9ad0bb69212ec69974e22cb037dfeb7ea90a4493997f4c94029870bcc5fd47013b51ca0a26b5d","other":"51ba4faf0988717a37dcddc0a60a70ead33bde310184fc450f9ca73c67f931e6767ad5930bcf409e5aeb613a9ff7a03e47de6fc13b33d8af0b87b38822ae6888","up":true},{"one":"489660042a8867d90a16ebb013968db26ca3edfc70f53320f511e35b3703eed09fbd787be5c06726a570a54aa15d129cd10db741523adf297929f909be4a0c71","other":"a1b2d0c6f24f5924c61e057fc65b994d9a6755560d740018b4c9ad0bb69212ec69974e22cb037dfeb7ea90a4493997f4c94029870bcc5fd47013b51ca0a26b5d","up":true},{"one":"caad8529d498a4a1e1ba7573689a913500bd409345ef8e3656abca748269eb73b919282f7f2eb0087f81f7bc52c367657ac8be0cdac65d2490c7c50c874444b7","other":"3103510e00a3f49a5e715719049fc8c9c67a2373a548f326458aeb6d9c75ed92b94373638fd075def0209113b4e85d972c23f064539f7b041596184e40d7f9a2","up":true},{"one":"82a774be7146766585d2bec6b69b7803aa956f492a53d8ed5f071becdbbc617562885d8430f0afd505210aab7b032428fbea32c82dffbd12d9ccba776ef4729b","other":"ed1ab28230ed533abf25633508d54f32bbff78a10c7a15fad5c2320cda9d9669c6d0e15689d8885400e64cbcd81730456f8f4bd5c98681d2cd8a8d4e1daec553","up":true},{"one":"73be4d2291c68ca4554a86fa170f7595210e1b6bbbeef3c1d5623a2b5d03a8fd6e26caa26afc639c20c8a351a89dad1086f91734f09afab62d28ec17b700fa01","other":"5d96577324edf1b5a1626999925982af1e0ba7bed8edcc3f740ba434f4b003cbbe2d632cad327c76e5b490d08c091c4a7b473353ab59139493657eb9525b8be2","up":true},{"one":"ecbdca037cd7892752345b48b4219478b1b334f83ce7140fcc72eb71784436b690ce7a41b03e013cefc19d64a34a20cfef1b9e2b535d938bcdcb39fe63645a42","other":"2d6d55edd34c0d9a0130b4806e409bbe18cdda5c2b221cf46136718ec20ffc9d8e92838d78aff92fbcc85f5d081da361dd1e3d7f3d4e1ea57877d6bb7aa0b6f7","up":true},{"one":"077bcadade93e0d361e94f76dff464d61912bc067ce2ce17ebcabd757cca201cd64624ea809d99dd8ecb749d40528db9b3eb503ef5ec05e8845044cfaef720dc","other":"87fce129511a1be2777052d24b606acdfe7067f4e874ab04674a68664b378ea208975f7269a72af889d3d23cd930b6a181afa2cdef3f9f9491f715bd96ad8dc0","up":true},{"one":"340420ee18d55913f790d0fcc2305b40b1e7bef2eddb79dda57801690aeeead693ebd1a9ff8557671f5ae136b3e65733306924bd00444cbc6e7c6235e5a2c77f","other":"e7bb63c5187ee85d965fed5cb33d1678c0e090b4e4c3f3d859755565db18046cb60025453bdebf136373c416a2e6e56be063bca6c9257b7b175dcf966e274205","up":true},{"one":"27fb8fcda1986644f985d68430c399f0299644b00b234c355362721081d12f9eb7686eea8f92eabda1d342bf56255e51c07b200c6233f95ac009f15b874eee97","other":"2d6d55edd34c0d9a0130b4806e409bbe18cdda5c2b221cf46136718ec20ffc9d8e92838d78aff92fbcc85f5d081da361dd1e3d7f3d4e1ea57877d6bb7aa0b6f7","up":true},{"one":"6ce3a68cb1e2924ad97f22006094c709a3dd8b4ca1546fbb037f841a9e5ac62def242015dbf6221bda610153db064edcbb58a78a35a06077b8c02bf5b2a33c04","other":"51ba4faf0988717a37dcddc0a60a70ead33bde310184fc450f9ca73c67f931e6767ad5930bcf409e5aeb613a9ff7a03e47de6fc13b33d8af0b87b38822ae6888","up":true},{"one":"41994605708232b4ca7448c3bc0760a7b86bf26d442091e5ce6e92eac94925721d7e0eca04bdd03bb1bba1ef92deeccd4bf1b7c6c3318b7e8d031965c6646761","other":"87fce129511a1be2777052d24b606acdfe7067f4e874ab04674a68664b378ea208975f7269a72af889d3d23cd930b6a181afa2cdef3f9f9491f715bd96ad8dc0","up":true},{"one":"805d784527be4e32e84ddf045baee1ccf348cdf8288de3aae1a5379f762576b957525ef358d9b42c68a93394017880adc09bb2b1b5e01102dc7e4240baf2af95","other":"545850cb90787d49c579b1ed54a753ebd00eaafe3f1bd04d57266e4912fb1cdd654446ef054a973a583ce8dfc6cc130b6f90e63bcf75372fc21c445f8e1e6005","up":true},{"one":"18bb6572965f4263c5a4d59a73027abc57a46122125ee58d871e95c993e6a1e8230438ce696a5f8880a08749837268b54319f7b0aa254c1a5bd453a8e9bcf84f","other":"077bcadade93e0d361e94f76dff464d61912bc067ce2ce17ebcabd757cca201cd64624ea809d99dd8ecb749d40528db9b3eb503ef5ec05e8845044cfaef720dc","up":true},{"one":"178d5ce398a7114a63a0c953a59932e769891420f6b1544f08c082cd37b531b66757652d279b3036b03b04f8d46eceb0b46fb95646c6668e2921af75c06c3d97","other":"33e3ab7108ced43102003c3b3192b194100f32b6bcb67bb772ea9696e35721196699cf01e443f7cdf8076ad83aaf7468b75c71d03efb95f4c07cf0742ea9af81","up":true},{"one":"0e8c1a6b70524c4fdc492c74348bac4ccd5d140bd41352607e8cfba45561afb1e6e12f3e2fcf03c1778c9ae5ae19cb9218ee2d613983768f54e3f54e69bb6600","other":"178d5ce398a7114a63a0c953a59932e769891420f6b1544f08c082cd37b531b66757652d279b3036b03b04f8d46eceb0b46fb95646c6668e2921af75c06c3d97","up":true},{"one":"51ba4faf0988717a37dcddc0a60a70ead33bde310184fc450f9ca73c67f931e6767ad5930bcf409e5aeb613a9ff7a03e47de6fc13b33d8af0b87b38822ae6888","other":"28afc20d8f4779b285bb14870062dbb54796ec77623302e51bc1bafed9e2c35751c8469ffc482718e059875dfa2226195ed10999e251498cba3a444896cb67db","up":true},{"one":"e59940a6dfe35a6214e2e3daba9ad94e630004cd8f029e13a6649a56dc528ff94bc09d8d21a2f14a56b4ff759b60ebf3d27c1029862c183b8416fa3e950bdb55","other":"4bd17847bdf60ea93a670a84a0ff8fe028d35228e814d6ebc0ae4fa586ddef03cd79390d541d28ca3c05a7241ffe92ac182e63c251176b40db8fe05fefaa82be","up":true},{"one":"1e3c83cabbe6852c987ae521b7fcb33185cf855c59b6235ebb8e57a6f860ccc159ddc01b4a21d251c8faca4559ceb271e046a51493ba148c0d3aed97ad208969","other":"44462055ba68fdef337dd19d8123aace9a12284c13bc97687416b6b4ca0c94234ba7db6823651fc021d6ac1539e0c5321e763a7a12c9e7c8a583aac5369817d8","up":true},{"one":"f6a07a1d361a4671e997d5eaadae61736291aff3896cb69f06bbc19bf7536dd152e0b15422b2fd9f8a9d2f9a251c9a07d0140319900e2cc9f25a59025c7dc91f","other":"9e6c1c6e871638182c4b54ac89352ef5c2bca0a99424a1369013e7c182883da0e8d7ab96b3c8254c31fa315b941d8ddee153157626821fc78c2cae951c1c9053","up":true},{"one":"f62bd19b0fd052207743ce53c3d48a3a71e9219b75e41a9497a43e6368e559d5487ff1ab644f2df4106b500583e4344515f73187eec773115deb977b4ebc3514","other":"3c6faa2e75a1699ddadd0e21fd35d3d6215715cfdc2dc89961cfd66773d2541776e785f3ebc833a70e3d1017a4edc571a5d5d9f9fbfc3fa0a8588f6c5023c164","up":true},{"one":"2502fc8ee0ccda79ad1dbd9c7cec625da85980b9116bdd56dc367d508039e25e5f65183293006e5b0df72fa9037a48bd2b133a757940d3587ff77ae2392e3eaf","other":"276256790c9317d09ff7802f4ad0a85840fe62527390ce1790e1e3186e8b3f04acfaa41dcd02303d333423678a4037e4f4854676e79ced3232a3dbd772cc2680","up":true},{"one":"59730132a01ba848a3c050bb6234bca9a72deba33716960fc3ec89b186bfcd313b9bbf049939d5805ff98db2c53a9421ce6ec97d8b4cdbaea53ba264d80d0734","other":"6ce3a68cb1e2924ad97f22006094c709a3dd8b4ca1546fbb037f841a9e5ac62def242015dbf6221bda610153db064edcbb58a78a35a06077b8c02bf5b2a33c04","up":true},{"one":"08900197e74e285a5a8a9cc53fbd420bb35043ab27eb2d9eab22615e736a093abfa235c17f667dcc791cb50b9022082eafd9fba030194cc84f0358b769adc85b","other":"6ce3a68cb1e2924ad97f22006094c709a3dd8b4ca1546fbb037f841a9e5ac62def242015dbf6221bda610153db064edcbb58a78a35a06077b8c02bf5b2a33c04","up":true},{"one":"afb5754b4748b7ac5628e32b242c90aab0e2fc7da58d8d5c8c775d13d8a6fd32240f1b89021587858168cbe7b3ea7ad07807728655eae0a9907060494a7c99ca","other":"670949178a5fad22da03af1e206c814a797c0e9eb4e3371f83612f121e5b56e767706a3ae36628cd0c86dd7bd1586ca4df57e2de27b28a31284ecf9176d330e5","up":true},{"one":"750ca601f07d65f426f6ea5f34e06238f9d7a931f022f9b0ebc811943d3725500cb3c6f00c8d05eb8d5b353c6534136dff38b9a8d3d4dc5bf49cd96875704d07","other":"6ce3a68cb1e2924ad97f22006094c709a3dd8b4ca1546fbb037f841a9e5ac62def242015dbf6221bda610153db064edcbb58a78a35a06077b8c02bf5b2a33c04","up":true},{"one":"fd12c5c96df6ee76dd7beb9e4e4768dda4d2c498851b6435f13ca0175980d0e4a4ff1c002e4daf41a995f118500604764f88496fb9b2c22e28308d8649b525ce","other":"6ce3a68cb1e2924ad97f22006094c709a3dd8b4ca1546fbb037f841a9e5ac62def242015dbf6221bda610153db064edcbb58a78a35a06077b8c02bf5b2a33c04","up":true},{"one":"a05a18161c2d01a0f122548c66509dd1fcf3ee52975035bc79fb059e9613b743a16cd6f5ac54090e68f51bcf76ff21fb3805ba3197a96b4236afb80f791df802","other":"e9f7e58fda4b504275441d51929fbc98214abdc9ed552c7aa94c600a85d4e791d60c032304b29ae028adccec94984fc9a3d705a81462632f50ef45024eb0f64e","up":true},{"one":"5d96577324edf1b5a1626999925982af1e0ba7bed8edcc3f740ba434f4b003cbbe2d632cad327c76e5b490d08c091c4a7b473353ab59139493657eb9525b8be2","other":"f62bd19b0fd052207743ce53c3d48a3a71e9219b75e41a9497a43e6368e559d5487ff1ab644f2df4106b500583e4344515f73187eec773115deb977b4ebc3514","up":true},{"one":"bf1e6eeb8b229f63b49213db499b71dcfe0ae45ee3f14685c7cbfa3f0a2150e52a89c853f4cd8c7a92e6e5f6083044efddfa17391662e3cff6290da679520404","other":"5771bef7f50439f9b81d2a7bf7060b1ad4b38675d8f6abbac3cc4c215fb0cb5dd07f6873545b42218337556925566025476e2915b7b98e662a3dcd28bebf0eb4","up":true},{"one":"562119edffe8270f6f7a5ad9b13d4c65d643e52a2331d1fee16f7e9b5567f44cfea62df3e8965a22cf08db8fa918f0a0bcae8da2936677e6d25bc88ed85ed2f1","other":"59730132a01ba848a3c050bb6234bca9a72deba33716960fc3ec89b186bfcd313b9bbf049939d5805ff98db2c53a9421ce6ec97d8b4cdbaea53ba264d80d0734","up":true},{"one":"896c74ca4cc4cbb9d2b6606d0ebfd6427952c2e16aedbf36933fa3d01f1c505fcd663f3d01c0cf096bef9cfd0bae4595ec7c221cfc362e19a5b7c60614a9658b","other":"d71c50805f284ed3a759e2e81f220fbc73d6d0a7a261b4c9e7878c3da143cfc07afa83e1635b6a45530f71a60b9f17c485a2fd6617c6c2bff82bacc71c208087","up":true},{"one":"bfef26733f5196a11484bcc28d88776e747189ae7cec883ff39a27cfeee6d9d1efb34560c9f8e75eec43fc069a2ce5f0c78107a36cc8a569d37bd5306aecf23a","other":"a40391285d1a97f1fb368b20c8e4d02be1bdebc0db41f00f99aac2f01893dc12256cd5a711117a981fbb3f9dfea18c19cf3603e925dbd67c4032b22b41eab8d5","up":true},{"one":"51302ef7b50922398ad802e917390bb4a3c24c877f2c2bcb7fcb34de9feca22673a2c594639914fe46a28837ffadfd03bb673afbc856aff5e59caf8e76082482","other":"e0420ba2a293315d810928a0e09a507c6aaf93977ba2c7598e9b83723b4a66682398ea17542c26767c7ff0f4ca09c537d3cc10dad283f079f1de73e25e87cb5c","up":true},{"one":"87e696a354d249493217dc4e0190082f30e09616873803efa376871d4b34f86f0eeb4643d4822d8a0fbcdedb27cd6ba5438e98943d358d960c4835e82261c93e","other":"73319a301ad3cf0ec09549d817c9523d61b74abb0cad87b737d41d900321e52722a84355f6f87bc7a5f848818c89a021bb0f3e5994f67c9a7b5bbfc98188a376","up":true},{"one":"a6ca1d5340f2d7021f541c81cf9aea519675462c8443bb6ddd93919962561b8f5a8431c3ec7e7e7d46c600b653e9a0638d2bb07cf4e29516bf9c4d3653f451b0","other":"077bcadade93e0d361e94f76dff464d61912bc067ce2ce17ebcabd757cca201cd64624ea809d99dd8ecb749d40528db9b3eb503ef5ec05e8845044cfaef720dc","up":true},{"one":"f0299035cbddfdf7a78e5e3a400aaedf2d719d04e907ac0f9f067525e2f9bb913d985308a3a0d05467a64adf58c68a615c6327acf716c23631d0e829903f8b34","other":"82a774be7146766585d2bec6b69b7803aa956f492a53d8ed5f071becdbbc617562885d8430f0afd505210aab7b032428fbea32c82dffbd12d9ccba776ef4729b","up":true},{"one":"7a509686ebce91778fe22e834a94ab03f92457d41385099ba657fe62c7469a9669bddb9a3d7b0150efa1d2f40c69bc786c7f4ede1cf8b19411eea1d23cb7d56c","other":"155805f787600f9f9518cf8836f491885b64868bfe0023975bcd12776925a424fb5aa3199dc178e83294e97f347a373d05d2422578a08eeeb2d15a178d28964f","up":true},{"one":"816e91fa8ff68ba067a89390ef61e7f23211e5e05049daa103ad1ff84b94fbcf535a6f6b515fb571939f5656869767c608513808800baba7e5d2b5f3a17a9691","other":"d71c50805f284ed3a759e2e81f220fbc73d6d0a7a261b4c9e7878c3da143cfc07afa83e1635b6a45530f71a60b9f17c485a2fd6617c6c2bff82bacc71c208087","up":true},{"one":"e7bb63c5187ee85d965fed5cb33d1678c0e090b4e4c3f3d859755565db18046cb60025453bdebf136373c416a2e6e56be063bca6c9257b7b175dcf966e274205","other":"155805f787600f9f9518cf8836f491885b64868bfe0023975bcd12776925a424fb5aa3199dc178e83294e97f347a373d05d2422578a08eeeb2d15a178d28964f","up":true},{"one":"a58a2dd3f5ee2471f0ddd555ffcc45d86e2d8c325585e3fe55eee878b8a626faccce73679d32811fc5d068c153e671673f4cd020f3c7fb37bc6fd9646931646a","other":"1e0a46ff50fb6d9a2c218a851763ff86c42e4d61dddffb7188481febc0f3180bc8f31973d336b2a6e25802acd4fed6d905d89c6d4d7d8080fb12741f9c5ab7e6","up":true},{"one":"b2bea653b6ec9629c6f934be72fccf30acf836698e21e81dd8085f070ba8259ba43eee43c342738a4b782f5fbddd44caa28f56dffc08237ca7567c965ac3beca","other":"178d5ce398a7114a63a0c953a59932e769891420f6b1544f08c082cd37b531b66757652d279b3036b03b04f8d46eceb0b46fb95646c6668e2921af75c06c3d97","up":true},{"one":"4de606aa7e722197b918c5f7f0db86a3081d48e89d21428b04f19c3ff3755eac0bddbff5fad8bda94b9e57f58fba2fecdbabbf710f7afb381bf4f1a4fe55cd93","other":"178d5ce398a7114a63a0c953a59932e769891420f6b1544f08c082cd37b531b66757652d279b3036b03b04f8d46eceb0b46fb95646c6668e2921af75c06c3d97","up":true},{"one":"d71c50805f284ed3a759e2e81f220fbc73d6d0a7a261b4c9e7878c3da143cfc07afa83e1635b6a45530f71a60b9f17c485a2fd6617c6c2bff82bacc71c208087","other":"b2bea653b6ec9629c6f934be72fccf30acf836698e21e81dd8085f070ba8259ba43eee43c342738a4b782f5fbddd44caa28f56dffc08237ca7567c965ac3beca","up":true},{"one":"9c6dcfef0e128dbfeca58b8ac625b08fb447b0d579bd3f18bc0e2be60d1ec2274595d0554ddba0ca7eb660099d3ea146d8076792b46c93841d2ecf8cf608f5ba","other":"545850cb90787d49c579b1ed54a753ebd00eaafe3f1bd04d57266e4912fb1cdd654446ef054a973a583ce8dfc6cc130b6f90e63bcf75372fc21c445f8e1e6005","up":true},{"one":"06472c89def07fa73188d253cf1acddc2be984842f3a234edb3db95449ba74928ab1395eca1b8978987769863afffb488fc27c9ac723aa24837b66c12f38d735","other":"6ce3a68cb1e2924ad97f22006094c709a3dd8b4ca1546fbb037f841a9e5ac62def242015dbf6221bda610153db064edcbb58a78a35a06077b8c02bf5b2a33c04","up":true},{"one":"57bfbde13c71e035c96513870aa8215198f78806e7cdb01c54fbdb392de2c40386d768d6fdc4c68534a67e531867ca74d8ca4dcf34ff7f7f64ec35edee3e5f68","other":"340420ee18d55913f790d0fcc2305b40b1e7bef2eddb79dda57801690aeeead693ebd1a9ff8557671f5ae136b3e65733306924bd00444cbc6e7c6235e5a2c77f","up":true},{"one":"545850cb90787d49c579b1ed54a753ebd00eaafe3f1bd04d57266e4912fb1cdd654446ef054a973a583ce8dfc6cc130b6f90e63bcf75372fc21c445f8e1e6005","other":"82a774be7146766585d2bec6b69b7803aa956f492a53d8ed5f071becdbbc617562885d8430f0afd505210aab7b032428fbea32c82dffbd12d9ccba776ef4729b","up":true},{"one":"5d917ffc9d70a38670941ce206aa7ea1b9ea65c1d783f14ebdf7c7afa6ca8b237112aaa9b1a3f757132093a604ef378280c5bdef02c2688049a91a412c399bfe","other":"82a774be7146766585d2bec6b69b7803aa956f492a53d8ed5f071becdbbc617562885d8430f0afd505210aab7b032428fbea32c82dffbd12d9ccba776ef4729b","up":true},{"one":"3572a22097a313b3adef95a7b6cc679f8d1201a156d764e61a9fbc63d123fb4826f7125402fb6569beed359e1c1e5e6cb6993a75975da6cd4ce15669a2eea758","other":"4448a59bde9edb93edcdb4a77f3e2277b9c01ffea45496ee0533eb5192955a08a0f982e25cf772e0dae68735a55b7acd221f6ba7b134f1e999087bee182330e8","up":true},{"one":"670949178a5fad22da03af1e206c814a797c0e9eb4e3371f83612f121e5b56e767706a3ae36628cd0c86dd7bd1586ca4df57e2de27b28a31284ecf9176d330e5","other":"ecbdca037cd7892752345b48b4219478b1b334f83ce7140fcc72eb71784436b690ce7a41b03e013cefc19d64a34a20cfef1b9e2b535d938bcdcb39fe63645a42","up":true},{"one":"31ac37862416c0e229c4a088ec179f23bdd1bf12dd464eb11c630ad531d7c3438671862e5458e2f6fbb32b857f857e6b8c17e5d93eb29a0e78bb5a65d7eb648c","other":"caad8529d498a4a1e1ba7573689a913500bd409345ef8e3656abca748269eb73b919282f7f2eb0087f81f7bc52c367657ac8be0cdac65d2490c7c50c874444b7","up":true},{"one":"3c6faa2e75a1699ddadd0e21fd35d3d6215715cfdc2dc89961cfd66773d2541776e785f3ebc833a70e3d1017a4edc571a5d5d9f9fbfc3fa0a8588f6c5023c164","other":"8e8de10fb3f53bd3a48455ebfa0a38ea5bd28c607e65506b263ece53a24d2361c2af7d7cd207e45b11bf71a3c33fa325fc8fd40a18b9c73019cce219c757c7ef","up":true},{"one":"fa897ba112f34839064c6871a4c9504c5d709eff5095a137c6a42726d58eb623af976cb96cc30db67e6ac9347c769f032aa4ebda884285a057059040c008ad3e","other":"73319a301ad3cf0ec09549d817c9523d61b74abb0cad87b737d41d900321e52722a84355f6f87bc7a5f848818c89a021bb0f3e5994f67c9a7b5bbfc98188a376","up":true},{"one":"49eb706cd7e95ad78502a508487d88b818861d94334aee36b2acef5c25cfff5c0efc2df9dc5dbb18acd4003d5cc0c843d3b40363adf2f62a14c04d814268fdee","other":"e59940a6dfe35a6214e2e3daba9ad94e630004cd8f029e13a6649a56dc528ff94bc09d8d21a2f14a56b4ff759b60ebf3d27c1029862c183b8416fa3e950bdb55","up":true},{"one":"d8cfadac10473b31a4560c711636a05615f13054388065344642ff1d04246fb62eafeec06805264eafead111ed8134e11a8e21f42a0eb950c23b142e627bd8cb","other":"077bcadade93e0d361e94f76dff464d61912bc067ce2ce17ebcabd757cca201cd64624ea809d99dd8ecb749d40528db9b3eb503ef5ec05e8845044cfaef720dc","up":true},{"one":"c6d1404873174254c0f15f25804da9a9d90db9c11c5cc895fab613b4deb7820f1733680b4ba9e4b61a664642ed6ee9ff012e13a0619c64ae067be6bab26962c6","other":"03d2d77c008b5fa1063b1abc3152b879a529fe4fdb2dc174d6d85312264a38ee4cc49b342507a10fff1a4b0730f1ef8e008b0897d97bfd6f70050adb124d3596","up":true},{"one":"665c3288c14dc1c17d85d17d634910f42183482c7e77c47e68f9b4f475b93e8c152246b9e34781606315ff6ef0f8360342500d15e4a2d67d9df6b72f30af64a7","other":"e9f7e58fda4b504275441d51929fbc98214abdc9ed552c7aa94c600a85d4e791d60c032304b29ae028adccec94984fc9a3d705a81462632f50ef45024eb0f64e","up":true},{"one":"8e8de10fb3f53bd3a48455ebfa0a38ea5bd28c607e65506b263ece53a24d2361c2af7d7cd207e45b11bf71a3c33fa325fc8fd40a18b9c73019cce219c757c7ef","other":"09b60de1e85bb6f7d2caf5b1ab58204d7d04531ece300dcd7bcc9157b8b3ef2a182758808a0eec6056034f29f52caadb7c690f498c1c8832ff7a6a9ecff308bd","up":true},{"one":"4bd17847bdf60ea93a670a84a0ff8fe028d35228e814d6ebc0ae4fa586ddef03cd79390d541d28ca3c05a7241ffe92ac182e63c251176b40db8fe05fefaa82be","other":"f0b2f1e8d46be656109adb18c60677ac9eb8fce7f42e15d9dbb25f94b4e426064780eaf32b79954b9bb72ea89953175da8de35380aaba18931cca374a7de2b11","up":true},{"one":"3274b5f48e6929e2305e980b558a4ca3c7cf800b75a6445ea2875cb379e127f3e793e9450a11e927682aa91b8af52e9560dece633833e0f207a8a8a38b7b9c54","other":"26cf4ea45b9a76daab82a57126f9c6f8726d2eb973e205ab4ab69c8b8be11a32a7eb5c3807e952cd428ce5ddd88f143d4fc9ff8c3de3d159855675afce715615","up":true},{"one":"28afc20d8f4779b285bb14870062dbb54796ec77623302e51bc1bafed9e2c35751c8469ffc482718e059875dfa2226195ed10999e251498cba3a444896cb67db","other":"545850cb90787d49c579b1ed54a753ebd00eaafe3f1bd04d57266e4912fb1cdd654446ef054a973a583ce8dfc6cc130b6f90e63bcf75372fc21c445f8e1e6005","up":true},{"one":"2fdb4382c4bc2950948a8cff13a7df65627bc0b20661cae20fd29acab166c97701594ee3151d75c006ba86d1d68b624b1d1f78e3d1e2fc297844956ef82208a8","other":"622646c74fdbae39ba191dbafff4906fb683fe0b0f2c303d080f5577a070876c41c8d3786ae7b953e5f682b8ec647727550d47302229ebb9f82bed24cea61132","up":true},{"one":"3e7820bb15c07f515bd63791b66136723dcc9878b3145fe0f238f6b41e3f2f7565ae55ef24f08ae461950ce1ae0c8a80fe5e4fd4f2f88c4acf4a2c94640df239","other":"73319a301ad3cf0ec09549d817c9523d61b74abb0cad87b737d41d900321e52722a84355f6f87bc7a5f848818c89a021bb0f3e5994f67c9a7b5bbfc98188a376","up":true},{"one":"077d2d032874e5ce70e9b928b7fe72c0326ba92394e16245e31d48b5731d3d32bfd86acf40825decff54bcd735e9ebfd94eba677c418ea7007baec9db4af676d","other":"4bd17847bdf60ea93a670a84a0ff8fe028d35228e814d6ebc0ae4fa586ddef03cd79390d541d28ca3c05a7241ffe92ac182e63c251176b40db8fe05fefaa82be","up":true},{"one":"b09af9e5552e72f918174963dad58a4492d3afa120f78e43820df7bff7fae9f6b52bc6c8c73d3a9af91d20134f4ff1b037db2ef0bc3d8c495a771d63de678bc0","other":"1e3c83cabbe6852c987ae521b7fcb33185cf855c59b6235ebb8e57a6f860ccc159ddc01b4a21d251c8faca4559ceb271e046a51493ba148c0d3aed97ad208969","up":true},{"one":"1955bedf0bc9044b13a2c16158087123197c74147c86aa3b9389d308a364e80edbc573bcc836d8a262a77f3c9233ebddb1b82eca83cd0a0e4bda6564c443bb70","other":"27fb8fcda1986644f985d68430c399f0299644b00b234c355362721081d12f9eb7686eea8f92eabda1d342bf56255e51c07b200c6233f95ac009f15b874eee97","up":true},{"one":"188bf77c9c1e45f009efe7aefdb040bdb47763980fe7eb0851295d657fa2a8978efbd2997c1dc30f4f0874eecf9ca9550487cf41da237b84d071963d35b6baff","other":"44462055ba68fdef337dd19d8123aace9a12284c13bc97687416b6b4ca0c94234ba7db6823651fc021d6ac1539e0c5321e763a7a12c9e7c8a583aac5369817d8","up":true},{"one":"5984a296b49bfba30315501ce2ae88ed0392ab2959ac4e7e6b9a29090f344b9dd13873ca137e8317c402cd2e14a61965d5707065b8ded46c41a054731933719f","other":"27fb8fcda1986644f985d68430c399f0299644b00b234c355362721081d12f9eb7686eea8f92eabda1d342bf56255e51c07b200c6233f95ac009f15b874eee97","up":true},{"one":"3103510e00a3f49a5e715719049fc8c9c67a2373a548f326458aeb6d9c75ed92b94373638fd075def0209113b4e85d972c23f064539f7b041596184e40d7f9a2","other":"4bd17847bdf60ea93a670a84a0ff8fe028d35228e814d6ebc0ae4fa586ddef03cd79390d541d28ca3c05a7241ffe92ac182e63c251176b40db8fe05fefaa82be","up":true},{"one":"f2ea93f43be9d0c3fa21f1496dc13c778977a6afdcba24c8b146de7dca2cdde62a5b792aab969e5b4b6c56f63066b336580d911f206049cc24cac32a25fc4306","other":"4bd17847bdf60ea93a670a84a0ff8fe028d35228e814d6ebc0ae4fa586ddef03cd79390d541d28ca3c05a7241ffe92ac182e63c251176b40db8fe05fefaa82be","up":true},{"one":"489660042a8867d90a16ebb013968db26ca3edfc70f53320f511e35b3703eed09fbd787be5c06726a570a54aa15d129cd10db741523adf297929f909be4a0c71","other":"3e7820bb15c07f515bd63791b66136723dcc9878b3145fe0f238f6b41e3f2f7565ae55ef24f08ae461950ce1ae0c8a80fe5e4fd4f2f88c4acf4a2c94640df239","up":true},{"one":"e3f2e777a96b2137b3104b84d5d827d484eac9ee1b585430e09f790d7e26978da12802325927c3c483bc19973e09cd3f70c513c34798e5da650f8d2f0c8c5c47","other":"caad8529d498a4a1e1ba7573689a913500bd409345ef8e3656abca748269eb73b919282f7f2eb0087f81f7bc52c367657ac8be0cdac65d2490c7c50c874444b7","up":true},{"one":"3540d888c3207d6df233afd1164ff9dde2551730862772547e04f7311de364968e113f38a7dea1ab0916a7f8307017de5b49578fa4ebcc39651e541fde51be48","other":"f06ec3a90d34300f9fa2d48aea0c6b5f2f01f7833ffb0fad30e7f57e3916e344f3a4f9efe38e222443b8b00d3c7f5221c672491a129e4958e574afc283bd45b1","up":true},{"one":"93987e431a0058f2e942ccf8d3486d249cd2734d6494131b343e2c3a8fdd86cfcb12d0aaaf8fcb911ad3cdd682cc82118198195a7fdc915ab7853223f012eab6","other":"545850cb90787d49c579b1ed54a753ebd00eaafe3f1bd04d57266e4912fb1cdd654446ef054a973a583ce8dfc6cc130b6f90e63bcf75372fc21c445f8e1e6005","up":true},{"one":"3df030a522a157e36f6b369aab048b9287792743a411a47073c4f9ef7686528f39bf7bf91c48e4d46afe180c8d08430b012bd216d50876baa3b1e7bc17cb55ef","other":"cdd86dea7dde96ff7cc1e3248fd17d107c83f2cc7ce2111c41530448962763309e91a05b5dad4663d0e02db59ed4129ab0c3e1eedc42c654e39d29f99038063b","up":true},{"one":"ecbdca037cd7892752345b48b4219478b1b334f83ce7140fcc72eb71784436b690ce7a41b03e013cefc19d64a34a20cfef1b9e2b535d938bcdcb39fe63645a42","other":"1955bedf0bc9044b13a2c16158087123197c74147c86aa3b9389d308a364e80edbc573bcc836d8a262a77f3c9233ebddb1b82eca83cd0a0e4bda6564c443bb70","up":true},{"one":"73be4d2291c68ca4554a86fa170f7595210e1b6bbbeef3c1d5623a2b5d03a8fd6e26caa26afc639c20c8a351a89dad1086f91734f09afab62d28ec17b700fa01","other":"4bd17847bdf60ea93a670a84a0ff8fe028d35228e814d6ebc0ae4fa586ddef03cd79390d541d28ca3c05a7241ffe92ac182e63c251176b40db8fe05fefaa82be","up":true},{"one":"da15d60a4b9a8816ce24c20f6c941c51229c1fb5e070b8b29be2977c2f7b41f8f17e4b6efe75f465e7935ded1ba17472f046eac73393db7197018fa86d11c31f","other":"a1b2d0c6f24f5924c61e057fc65b994d9a6755560d740018b4c9ad0bb69212ec69974e22cb037dfeb7ea90a4493997f4c94029870bcc5fd47013b51ca0a26b5d","up":true},{"one":"8f625a4e4f4fd980c796d3aa535e58a39722492480cf6982d43fab02de63a5b4c1b5c7cd8402171dd792bb5d9c3e2bdd38176c061dbe3e5b0592af1339e3fd82","other":"178d5ce398a7114a63a0c953a59932e769891420f6b1544f08c082cd37b531b66757652d279b3036b03b04f8d46eceb0b46fb95646c6668e2921af75c06c3d97","up":true},{"one":"86b84ddf64d301f6a9c4504c59eb4031d3167fb74101abea3b694845a009dc522be7b2e2720097ceea9f36058e160f42a2a438a33034929a5c1a7793c7ccef7b","other":"896c74ca4cc4cbb9d2b6606d0ebfd6427952c2e16aedbf36933fa3d01f1c505fcd663f3d01c0cf096bef9cfd0bae4595ec7c221cfc362e19a5b7c60614a9658b","up":true},{"one":"cbed12dcab0aa04a96ec7e25bc2ee03b337c7b2006391baa7d2aff042c17ec70b82c5fb2dc916d085a7948541719d329f9b528b67ec6adb1ac2cc594d4ef1e42","other":"8f625a4e4f4fd980c796d3aa535e58a39722492480cf6982d43fab02de63a5b4c1b5c7cd8402171dd792bb5d9c3e2bdd38176c061dbe3e5b0592af1339e3fd82","up":true},{"one":"d90a81a583c82d626b92f27244f027da4a0ae76e6d3bdc1de0af7be01798f1fb04b34ce60c6d8651a39d7a70915438a4aa63e5adf844a9f7e38dbf0b1dba754d","other":"4448a59bde9edb93edcdb4a77f3e2277b9c01ffea45496ee0533eb5192955a08a0f982e25cf772e0dae68735a55b7acd221f6ba7b134f1e999087bee182330e8","up":true},{"one":"c773af3af01ee8ab9fa8d06987baf4f10c394fdd386d69b7a7362f4b68fd6fc082337d3b33a19d584c5801a3e9198225d7b61f6629e34ce823be70908339f4c7","other":"31ac37862416c0e229c4a088ec179f23bdd1bf12dd464eb11c630ad531d7c3438671862e5458e2f6fbb32b857f857e6b8c17e5d93eb29a0e78bb5a65d7eb648c","up":true},{"one":"f7637cdd5ef26de40b9055c1df91a45725670c8df11ae934c0d99d2547c3eb4c42a16dbb2e75bcaf4b1b9347c48db65f549a0623179a08dd8cbad92f5bca08cf","other":"8e8de10fb3f53bd3a48455ebfa0a38ea5bd28c607e65506b263ece53a24d2361c2af7d7cd207e45b11bf71a3c33fa325fc8fd40a18b9c73019cce219c757c7ef","up":true},{"one":"da3e0fd71eb96ba2cab7f920d32f5425d1aad41d00765fdffb0b215d9dd5b60e2bc5929eafebee5b2b5a11aec164e141beff19d828aac7d1fabd3ffb0bfb8450","other":"73319a301ad3cf0ec09549d817c9523d61b74abb0cad87b737d41d900321e52722a84355f6f87bc7a5f848818c89a021bb0f3e5994f67c9a7b5bbfc98188a376","up":true},{"one":"20bdc859d58d8bf419df64fd6ee1d4363c1d5f403af3abef2720d7d3933924672e12e23e5d76b28e0f6726acf58bdc5eb258cba635e327cbd0b564523305da75","other":"3274b5f48e6929e2305e980b558a4ca3c7cf800b75a6445ea2875cb379e127f3e793e9450a11e927682aa91b8af52e9560dece633833e0f207a8a8a38b7b9c54","up":true},{"one":"41994605708232b4ca7448c3bc0760a7b86bf26d442091e5ce6e92eac94925721d7e0eca04bdd03bb1bba1ef92deeccd4bf1b7c6c3318b7e8d031965c6646761","other":"18bb6572965f4263c5a4d59a73027abc57a46122125ee58d871e95c993e6a1e8230438ce696a5f8880a08749837268b54319f7b0aa254c1a5bd453a8e9bcf84f","up":true},{"one":"ed1ab28230ed533abf25633508d54f32bbff78a10c7a15fad5c2320cda9d9669c6d0e15689d8885400e64cbcd81730456f8f4bd5c98681d2cd8a8d4e1daec553","other":"57bfbde13c71e035c96513870aa8215198f78806e7cdb01c54fbdb392de2c40386d768d6fdc4c68534a67e531867ca74d8ca4dcf34ff7f7f64ec35edee3e5f68","up":true},{"one":"f04c3ae9fe957a14c249acf3ea2e8407d04d108fc01e75f6d52aaf5073b3450025012d138a75b857473eea4d20e57c99b92bff9041f269d995543d7c67a92ec6","other":"077bcadade93e0d361e94f76dff464d61912bc067ce2ce17ebcabd757cca201cd64624ea809d99dd8ecb749d40528db9b3eb503ef5ec05e8845044cfaef720dc","up":true},{"one":"e0420ba2a293315d810928a0e09a507c6aaf93977ba2c7598e9b83723b4a66682398ea17542c26767c7ff0f4ca09c537d3cc10dad283f079f1de73e25e87cb5c","other":"a5cdff211813e17fadd43ec55a6cf4e97e6ca0c3b2cef0db58923b27d36207fd1a77146efb6093bd94d7eb89cc77d8c735fc64ab098839efc74a00b5e8687555","up":true},{"one":"eb097186ff58d96a7ead7a7f9c05a44075d84537bd4fd3f82857bf2c45bee1c6dece434a7707cde69e96f02366859cab4c991fdb7615e113a868d4b9c7524a45","other":"20bdc859d58d8bf419df64fd6ee1d4363c1d5f403af3abef2720d7d3933924672e12e23e5d76b28e0f6726acf58bdc5eb258cba635e327cbd0b564523305da75","up":true},{"one":"3e9c0bbd146d8b1040b4f379eecf802c27c4d0a70e64a9fb2e941a7edab9b00396b0b67fc5c891652743cdba3b342973ed49615b32da54b925954a799240431c","other":"077bcadade93e0d361e94f76dff464d61912bc067ce2ce17ebcabd757cca201cd64624ea809d99dd8ecb749d40528db9b3eb503ef5ec05e8845044cfaef720dc","up":true},{"one":"03d2d77c008b5fa1063b1abc3152b879a529fe4fdb2dc174d6d85312264a38ee4cc49b342507a10fff1a4b0730f1ef8e008b0897d97bfd6f70050adb124d3596","other":"6ce3a68cb1e2924ad97f22006094c709a3dd8b4ca1546fbb037f841a9e5ac62def242015dbf6221bda610153db064edcbb58a78a35a06077b8c02bf5b2a33c04","up":true},{"one":"a5cdff211813e17fadd43ec55a6cf4e97e6ca0c3b2cef0db58923b27d36207fd1a77146efb6093bd94d7eb89cc77d8c735fc64ab098839efc74a00b5e8687555","other":"1480f62d85ea32226d9f77ccd31780b3e704fb60618a588ae85dcd1c0e84e878c5fc092adfb306e8ebc7abba9ec429cb2447754502ef847cf931467f31fa50b2","up":true},{"one":"03e478a3aae82e06e215e40272a420037a61442d11c49c367a5ee6a21868d29a17ea8b9284f013d020c4740f296a6a22bc64d33d1c2807f9ab8dc48c0cfec18a","other":"c6d1404873174254c0f15f25804da9a9d90db9c11c5cc895fab613b4deb7820f1733680b4ba9e4b61a664642ed6ee9ff012e13a0619c64ae067be6bab26962c6","up":true},{"one":"87fce129511a1be2777052d24b606acdfe7067f4e874ab04674a68664b378ea208975f7269a72af889d3d23cd930b6a181afa2cdef3f9f9491f715bd96ad8dc0","other":"27fb8fcda1986644f985d68430c399f0299644b00b234c355362721081d12f9eb7686eea8f92eabda1d342bf56255e51c07b200c6233f95ac009f15b874eee97","up":true},{"one":"44462055ba68fdef337dd19d8123aace9a12284c13bc97687416b6b4ca0c94234ba7db6823651fc021d6ac1539e0c5321e763a7a12c9e7c8a583aac5369817d8","other":"2fdb4382c4bc2950948a8cff13a7df65627bc0b20661cae20fd29acab166c97701594ee3151d75c006ba86d1d68b624b1d1f78e3d1e2fc297844956ef82208a8","up":true},{"one":"872cdbb6d74fb55fd2d51877ef7804bdd2eeb6de0297eb2ce18b67e52379b147d54a46d2385ec9293eb21736bed4191d92c5c75e8e81fc5a6c691970e019f570","other":"d90a81a583c82d626b92f27244f027da4a0ae76e6d3bdc1de0af7be01798f1fb04b34ce60c6d8651a39d7a70915438a4aa63e5adf844a9f7e38dbf0b1dba754d","up":true},{"one":"dafb58b2fc8a14f2b23b7df33d28aa7847a08f80e9c21a654d4c97d928e1afe6585644d27f22442cf70d229c32783be6a03c0920be153fc4d9f3b273dfa90ec3","other":"077bcadade93e0d361e94f76dff464d61912bc067ce2ce17ebcabd757cca201cd64624ea809d99dd8ecb749d40528db9b3eb503ef5ec05e8845044cfaef720dc","up":true},{"one":"bfef26733f5196a11484bcc28d88776e747189ae7cec883ff39a27cfeee6d9d1efb34560c9f8e75eec43fc069a2ce5f0c78107a36cc8a569d37bd5306aecf23a","other":"cbed12dcab0aa04a96ec7e25bc2ee03b337c7b2006391baa7d2aff042c17ec70b82c5fb2dc916d085a7948541719d329f9b528b67ec6adb1ac2cc594d4ef1e42","up":true},{"one":"5771bef7f50439f9b81d2a7bf7060b1ad4b38675d8f6abbac3cc4c215fb0cb5dd07f6873545b42218337556925566025476e2915b7b98e662a3dcd28bebf0eb4","other":"155805f787600f9f9518cf8836f491885b64868bfe0023975bcd12776925a424fb5aa3199dc178e83294e97f347a373d05d2422578a08eeeb2d15a178d28964f","up":true},{"one":"afb5754b4748b7ac5628e32b242c90aab0e2fc7da58d8d5c8c775d13d8a6fd32240f1b89021587858168cbe7b3ea7ad07807728655eae0a9907060494a7c99ca","other":"2d6d55edd34c0d9a0130b4806e409bbe18cdda5c2b221cf46136718ec20ffc9d8e92838d78aff92fbcc85f5d081da361dd1e3d7f3d4e1ea57877d6bb7aa0b6f7","up":true},{"one":"f8052e328014f39157036f3dcecdb23419c0959473a88282605f10add681ef5cbfb1e926b522f98b8401272113b677a67225874d1afb0bff4b11140cc071de44","other":"fa897ba112f34839064c6871a4c9504c5d709eff5095a137c6a42726d58eb623af976cb96cc30db67e6ac9347c769f032aa4ebda884285a057059040c008ad3e","up":true},{"one":"9c3be147f9fe0fa34e553d9e4332969086ea7fa65294b61ca35c9f731f6b81d0b70cdcfe2ba52b6cea3c0de14b7ea40031b5cc40661c4bb821147894130d7bf5","other":"4448a59bde9edb93edcdb4a77f3e2277b9c01ffea45496ee0533eb5192955a08a0f982e25cf772e0dae68735a55b7acd221f6ba7b134f1e999087bee182330e8","up":true},{"one":"622646c74fdbae39ba191dbafff4906fb683fe0b0f2c303d080f5577a070876c41c8d3786ae7b953e5f682b8ec647727550d47302229ebb9f82bed24cea61132","other":"09b60de1e85bb6f7d2caf5b1ab58204d7d04531ece300dcd7bcc9157b8b3ef2a182758808a0eec6056034f29f52caadb7c690f498c1c8832ff7a6a9ecff308bd","up":true},{"one":"ab3814579882e9fd8d464f4f3c8a421be37822ba7f42c5f5e787e81125ec032f9ccf90a138c0b57f0a813b55b583f80d66284f795e2c82d80d2869e1fc770be5","other":"1e0a46ff50fb6d9a2c218a851763ff86c42e4d61dddffb7188481febc0f3180bc8f31973d336b2a6e25802acd4fed6d905d89c6d4d7d8080fb12741f9c5ab7e6","up":true},{"one":"a05a18161c2d01a0f122548c66509dd1fcf3ee52975035bc79fb059e9613b743a16cd6f5ac54090e68f51bcf76ff21fb3805ba3197a96b4236afb80f791df802","other":"cd0e9a45b45f9a67417fcde29d9f92c45ca4db46eebbfe47dcf6999e23e549e4205f42ada8e3fcd00e2fb5f832bb92a27a59b43c4a5909148d81399c2e8ce492","up":true},{"one":"f0299035cbddfdf7a78e5e3a400aaedf2d719d04e907ac0f9f067525e2f9bb913d985308a3a0d05467a64adf58c68a615c6327acf716c23631d0e829903f8b34","other":"545850cb90787d49c579b1ed54a753ebd00eaafe3f1bd04d57266e4912fb1cdd654446ef054a973a583ce8dfc6cc130b6f90e63bcf75372fc21c445f8e1e6005","up":true},{"one":"276256790c9317d09ff7802f4ad0a85840fe62527390ce1790e1e3186e8b3f04acfaa41dcd02303d333423678a4037e4f4854676e79ced3232a3dbd772cc2680","other":"86b84ddf64d301f6a9c4504c59eb4031d3167fb74101abea3b694845a009dc522be7b2e2720097ceea9f36058e160f42a2a438a33034929a5c1a7793c7ccef7b","up":true},{"one":"f06ec3a90d34300f9fa2d48aea0c6b5f2f01f7833ffb0fad30e7f57e3916e344f3a4f9efe38e222443b8b00d3c7f5221c672491a129e4958e574afc283bd45b1","other":"b09af9e5552e72f918174963dad58a4492d3afa120f78e43820df7bff7fae9f6b52bc6c8c73d3a9af91d20134f4ff1b037db2ef0bc3d8c495a771d63de678bc0","up":true},{"one":"26cf4ea45b9a76daab82a57126f9c6f8726d2eb973e205ab4ab69c8b8be11a32a7eb5c3807e952cd428ce5ddd88f143d4fc9ff8c3de3d159855675afce715615","other":"eb097186ff58d96a7ead7a7f9c05a44075d84537bd4fd3f82857bf2c45bee1c6dece434a7707cde69e96f02366859cab4c991fdb7615e113a868d4b9c7524a45","up":true},{"one":"c93cb2df7ba6de8009872f5f7565891040d42e3b193ef1cdb321a0c167cc8fb8138900982bb8f6918fbaefac6e02dda01ee40f7a6beba1990dd44abe03cc3d01","other":"03e478a3aae82e06e215e40272a420037a61442d11c49c367a5ee6a21868d29a17ea8b9284f013d020c4740f296a6a22bc64d33d1c2807f9ab8dc48c0cfec18a","up":true},{"one":"e9f7e58fda4b504275441d51929fbc98214abdc9ed552c7aa94c600a85d4e791d60c032304b29ae028adccec94984fc9a3d705a81462632f50ef45024eb0f64e","other":"ab3814579882e9fd8d464f4f3c8a421be37822ba7f42c5f5e787e81125ec032f9ccf90a138c0b57f0a813b55b583f80d66284f795e2c82d80d2869e1fc770be5","up":true},{"one":"33e3ab7108ced43102003c3b3192b194100f32b6bcb67bb772ea9696e35721196699cf01e443f7cdf8076ad83aaf7468b75c71d03efb95f4c07cf0742ea9af81","other":"f0299035cbddfdf7a78e5e3a400aaedf2d719d04e907ac0f9f067525e2f9bb913d985308a3a0d05467a64adf58c68a615c6327acf716c23631d0e829903f8b34","up":true},{"one":"a40391285d1a97f1fb368b20c8e4d02be1bdebc0db41f00f99aac2f01893dc12256cd5a711117a981fbb3f9dfea18c19cf3603e925dbd67c4032b22b41eab8d5","other":"178d5ce398a7114a63a0c953a59932e769891420f6b1544f08c082cd37b531b66757652d279b3036b03b04f8d46eceb0b46fb95646c6668e2921af75c06c3d97","up":true},{"one":"7a18392b8338108a996196ee190a93a1b9954c8e05a062c421da513a1828dfa739e7b224878c0670cf74bbc743c7ca7ee8cfee6b6a602fe1f4a82ecfbd38c2f4","other":"afb5754b4748b7ac5628e32b242c90aab0e2fc7da58d8d5c8c775d13d8a6fd32240f1b89021587858168cbe7b3ea7ad07807728655eae0a9907060494a7c99ca","up":true},{"one":"155805f787600f9f9518cf8836f491885b64868bfe0023975bcd12776925a424fb5aa3199dc178e83294e97f347a373d05d2422578a08eeeb2d15a178d28964f","other":"bf1e6eeb8b229f63b49213db499b71dcfe0ae45ee3f14685c7cbfa3f0a2150e52a89c853f4cd8c7a92e6e5f6083044efddfa17391662e3cff6290da679520404","up":true},{"one":"e7bb63c5187ee85d965fed5cb33d1678c0e090b4e4c3f3d859755565db18046cb60025453bdebf136373c416a2e6e56be063bca6c9257b7b175dcf966e274205","other":"afb5754b4748b7ac5628e32b242c90aab0e2fc7da58d8d5c8c775d13d8a6fd32240f1b89021587858168cbe7b3ea7ad07807728655eae0a9907060494a7c99ca","up":true},{"one":"cdd86dea7dde96ff7cc1e3248fd17d107c83f2cc7ce2111c41530448962763309e91a05b5dad4663d0e02db59ed4129ab0c3e1eedc42c654e39d29f99038063b","other":"20f171ab01a814a2856a6cbe7929269f18f6329914289515e2cb9d078ac14ebdae457789dd638c6415b062799114570f556147d4bf9ac850f00b6d0762765ac1","up":true},{"one":"cd0e9a45b45f9a67417fcde29d9f92c45ca4db46eebbfe47dcf6999e23e549e4205f42ada8e3fcd00e2fb5f832bb92a27a59b43c4a5909148d81399c2e8ce492","other":"d71c50805f284ed3a759e2e81f220fbc73d6d0a7a261b4c9e7878c3da143cfc07afa83e1635b6a45530f71a60b9f17c485a2fd6617c6c2bff82bacc71c208087","up":true},{"one":"b38213eaa5b419de787b70073ad8c7c819e48c5f76dec1507b54f1d7cb027211facbe7a170ac50212abe130935e8947d5a19d6b13790114e71cc18357902a889","other":"c6d1404873174254c0f15f25804da9a9d90db9c11c5cc895fab613b4deb7820f1733680b4ba9e4b61a664642ed6ee9ff012e13a0619c64ae067be6bab26962c6","up":true},{"one":"ce1309c8505b446363ae37cd3b1ee3e03ced537bed20aca5d8c4be2133917c408845ef5d0f65876974be2803dfb824827cf5c5a2d050d6ef26cdabcbf3a2dc31","other":"622646c74fdbae39ba191dbafff4906fb683fe0b0f2c303d080f5577a070876c41c8d3786ae7b953e5f682b8ec647727550d47302229ebb9f82bed24cea61132","up":true},{"one":"a1b2d0c6f24f5924c61e057fc65b994d9a6755560d740018b4c9ad0bb69212ec69974e22cb037dfeb7ea90a4493997f4c94029870bcc5fd47013b51ca0a26b5d","other":"fa897ba112f34839064c6871a4c9504c5d709eff5095a137c6a42726d58eb623af976cb96cc30db67e6ac9347c769f032aa4ebda884285a057059040c008ad3e","up":true},{"one":"b2bea653b6ec9629c6f934be72fccf30acf836698e21e81dd8085f070ba8259ba43eee43c342738a4b782f5fbddd44caa28f56dffc08237ca7567c965ac3beca","other":"ab3814579882e9fd8d464f4f3c8a421be37822ba7f42c5f5e787e81125ec032f9ccf90a138c0b57f0a813b55b583f80d66284f795e2c82d80d2869e1fc770be5","up":true},{"one":"545850cb90787d49c579b1ed54a753ebd00eaafe3f1bd04d57266e4912fb1cdd654446ef054a973a583ce8dfc6cc130b6f90e63bcf75372fc21c445f8e1e6005","other":"ed1ab28230ed533abf25633508d54f32bbff78a10c7a15fad5c2320cda9d9669c6d0e15689d8885400e64cbcd81730456f8f4bd5c98681d2cd8a8d4e1daec553","up":true},{"one":"77327983685f39f006806170fe351063a58ff1bd8dedc222d538e86cfd18abdfefd548328f25fc5afde8170aa5c35311353019468f2b439c331837ddfbb25a52","other":"33e3ab7108ced43102003c3b3192b194100f32b6bcb67bb772ea9696e35721196699cf01e443f7cdf8076ad83aaf7468b75c71d03efb95f4c07cf0742ea9af81","up":true},{"one":"7a509686ebce91778fe22e834a94ab03f92457d41385099ba657fe62c7469a9669bddb9a3d7b0150efa1d2f40c69bc786c7f4ede1cf8b19411eea1d23cb7d56c","other":"4de606aa7e722197b918c5f7f0db86a3081d48e89d21428b04f19c3ff3755eac0bddbff5fad8bda94b9e57f58fba2fecdbabbf710f7afb381bf4f1a4fe55cd93","up":true},{"one":"816e91fa8ff68ba067a89390ef61e7f23211e5e05049daa103ad1ff84b94fbcf535a6f6b515fb571939f5656869767c608513808800baba7e5d2b5f3a17a9691","other":"e59940a6dfe35a6214e2e3daba9ad94e630004cd8f029e13a6649a56dc528ff94bc09d8d21a2f14a56b4ff759b60ebf3d27c1029862c183b8416fa3e950bdb55","up":true},{"one":"56e8f792ec9a75ec9e91d472b8a4b023655dd68c2a448a33397b125fe3584a5efa1b492e47077b24acfe0396b73e1cb564a6a6b2aee1b457781dfaf6d43fcaed","other":"a1b2d0c6f24f5924c61e057fc65b994d9a6755560d740018b4c9ad0bb69212ec69974e22cb037dfeb7ea90a4493997f4c94029870bcc5fd47013b51ca0a26b5d","up":true},{"one":"73319a301ad3cf0ec09549d817c9523d61b74abb0cad87b737d41d900321e52722a84355f6f87bc7a5f848818c89a021bb0f3e5994f67c9a7b5bbfc98188a376","other":"a1b2d0c6f24f5924c61e057fc65b994d9a6755560d740018b4c9ad0bb69212ec69974e22cb037dfeb7ea90a4493997f4c94029870bcc5fd47013b51ca0a26b5d","up":true},{"one":"18bb6572965f4263c5a4d59a73027abc57a46122125ee58d871e95c993e6a1e8230438ce696a5f8880a08749837268b54319f7b0aa254c1a5bd453a8e9bcf84f","other":"2d6d55edd34c0d9a0130b4806e409bbe18cdda5c2b221cf46136718ec20ffc9d8e92838d78aff92fbcc85f5d081da361dd1e3d7f3d4e1ea57877d6bb7aa0b6f7","up":true},{"one":"d71c50805f284ed3a759e2e81f220fbc73d6d0a7a261b4c9e7878c3da143cfc07afa83e1635b6a45530f71a60b9f17c485a2fd6617c6c2bff82bacc71c208087","other":"4bd17847bdf60ea93a670a84a0ff8fe028d35228e814d6ebc0ae4fa586ddef03cd79390d541d28ca3c05a7241ffe92ac182e63c251176b40db8fe05fefaa82be","up":true},{"one":"93987e431a0058f2e942ccf8d3486d249cd2734d6494131b343e2c3a8fdd86cfcb12d0aaaf8fcb911ad3cdd682cc82118198195a7fdc915ab7853223f012eab6","other":"82a774be7146766585d2bec6b69b7803aa956f492a53d8ed5f071becdbbc617562885d8430f0afd505210aab7b032428fbea32c82dffbd12d9ccba776ef4729b","up":true},{"one":"06472c89def07fa73188d253cf1acddc2be984842f3a234edb3db95449ba74928ab1395eca1b8978987769863afffb488fc27c9ac723aa24837b66c12f38d735","other":"c89dbada7195464e732671ac6fff014cacfb4c879b63b6b84e7c1bce367522f759bd06e504b15f43a1735c6322356747fa5c4951882d4fd6cdf6f7cf13726719","up":true},{"one":"5b4de68680c5d1a75cccd5e7a82319c031f5d61d79cbb6532e1254ab81c833c3fafb54390cca7a770e84690c490fcba90482b35321870f8506335a2f57cc052e","other":"b38213eaa5b419de787b70073ad8c7c819e48c5f76dec1507b54f1d7cb027211facbe7a170ac50212abe130935e8947d5a19d6b13790114e71cc18357902a889","up":true},{"one":"0e8c1a6b70524c4fdc492c74348bac4ccd5d140bd41352607e8cfba45561afb1e6e12f3e2fcf03c1778c9ae5ae19cb9218ee2d613983768f54e3f54e69bb6600","other":"03d2d77c008b5fa1063b1abc3152b879a529fe4fdb2dc174d6d85312264a38ee4cc49b342507a10fff1a4b0730f1ef8e008b0897d97bfd6f70050adb124d3596","up":true},{"one":"e59940a6dfe35a6214e2e3daba9ad94e630004cd8f029e13a6649a56dc528ff94bc09d8d21a2f14a56b4ff759b60ebf3d27c1029862c183b8416fa3e950bdb55","other":"f8052e328014f39157036f3dcecdb23419c0959473a88282605f10add681ef5cbfb1e926b522f98b8401272113b677a67225874d1afb0bff4b11140cc071de44","up":true},{"one":"27fb8fcda1986644f985d68430c399f0299644b00b234c355362721081d12f9eb7686eea8f92eabda1d342bf56255e51c07b200c6233f95ac009f15b874eee97","other":"ecbdca037cd7892752345b48b4219478b1b334f83ce7140fcc72eb71784436b690ce7a41b03e013cefc19d64a34a20cfef1b9e2b535d938bcdcb39fe63645a42","up":true},{"one":"57bfbde13c71e035c96513870aa8215198f78806e7cdb01c54fbdb392de2c40386d768d6fdc4c68534a67e531867ca74d8ca4dcf34ff7f7f64ec35edee3e5f68","other":"86b84ddf64d301f6a9c4504c59eb4031d3167fb74101abea3b694845a009dc522be7b2e2720097ceea9f36058e160f42a2a438a33034929a5c1a7793c7ccef7b","up":true},{"one":"5d917ffc9d70a38670941ce206aa7ea1b9ea65c1d783f14ebdf7c7afa6ca8b237112aaa9b1a3f757132093a604ef378280c5bdef02c2688049a91a412c399bfe","other":"ed1ab28230ed533abf25633508d54f32bbff78a10c7a15fad5c2320cda9d9669c6d0e15689d8885400e64cbcd81730456f8f4bd5c98681d2cd8a8d4e1daec553","up":true},{"one":"1e0a46ff50fb6d9a2c218a851763ff86c42e4d61dddffb7188481febc0f3180bc8f31973d336b2a6e25802acd4fed6d905d89c6d4d7d8080fb12741f9c5ab7e6","other":"155805f787600f9f9518cf8836f491885b64868bfe0023975bcd12776925a424fb5aa3199dc178e83294e97f347a373d05d2422578a08eeeb2d15a178d28964f","up":true},{"one":"f0b2f1e8d46be656109adb18c60677ac9eb8fce7f42e15d9dbb25f94b4e426064780eaf32b79954b9bb72ea89953175da8de35380aaba18931cca374a7de2b11","other":"08900197e74e285a5a8a9cc53fbd420bb35043ab27eb2d9eab22615e736a093abfa235c17f667dcc791cb50b9022082eafd9fba030194cc84f0358b769adc85b","up":true},{"one":"49eb706cd7e95ad78502a508487d88b818861d94334aee36b2acef5c25cfff5c0efc2df9dc5dbb18acd4003d5cc0c843d3b40363adf2f62a14c04d814268fdee","other":"4bd17847bdf60ea93a670a84a0ff8fe028d35228e814d6ebc0ae4fa586ddef03cd79390d541d28ca3c05a7241ffe92ac182e63c251176b40db8fe05fefaa82be","up":true},{"one":"d8cfadac10473b31a4560c711636a05615f13054388065344642ff1d04246fb62eafeec06805264eafead111ed8134e11a8e21f42a0eb950c23b142e627bd8cb","other":"077d2d032874e5ce70e9b928b7fe72c0326ba92394e16245e31d48b5731d3d32bfd86acf40825decff54bcd735e9ebfd94eba677c418ea7007baec9db4af676d","up":true},{"one":"8e8de10fb3f53bd3a48455ebfa0a38ea5bd28c607e65506b263ece53a24d2361c2af7d7cd207e45b11bf71a3c33fa325fc8fd40a18b9c73019cce219c757c7ef","other":"f2ea93f43be9d0c3fa21f1496dc13c778977a6afdcba24c8b146de7dca2cdde62a5b792aab969e5b4b6c56f63066b336580d911f206049cc24cac32a25fc4306","up":true},{"one":"c6d1404873174254c0f15f25804da9a9d90db9c11c5cc895fab613b4deb7820f1733680b4ba9e4b61a664642ed6ee9ff012e13a0619c64ae067be6bab26962c6","other":"20f171ab01a814a2856a6cbe7929269f18f6329914289515e2cb9d078ac14ebdae457789dd638c6415b062799114570f556147d4bf9ac850f00b6d0762765ac1","up":true},{"one":"ed1ab28230ed533abf25633508d54f32bbff78a10c7a15fad5c2320cda9d9669c6d0e15689d8885400e64cbcd81730456f8f4bd5c98681d2cd8a8d4e1daec553","other":"ecbdca037cd7892752345b48b4219478b1b334f83ce7140fcc72eb71784436b690ce7a41b03e013cefc19d64a34a20cfef1b9e2b535d938bcdcb39fe63645a42","up":true},{"one":"5d96577324edf1b5a1626999925982af1e0ba7bed8edcc3f740ba434f4b003cbbe2d632cad327c76e5b490d08c091c4a7b473353ab59139493657eb9525b8be2","other":"da3e0fd71eb96ba2cab7f920d32f5425d1aad41d00765fdffb0b215d9dd5b60e2bc5929eafebee5b2b5a11aec164e141beff19d828aac7d1fabd3ffb0bfb8450","up":true},{"one":"e0420ba2a293315d810928a0e09a507c6aaf93977ba2c7598e9b83723b4a66682398ea17542c26767c7ff0f4ca09c537d3cc10dad283f079f1de73e25e87cb5c","other":"2d6d55edd34c0d9a0130b4806e409bbe18cdda5c2b221cf46136718ec20ffc9d8e92838d78aff92fbcc85f5d081da361dd1e3d7f3d4e1ea57877d6bb7aa0b6f7","up":true},{"one":"4bd17847bdf60ea93a670a84a0ff8fe028d35228e814d6ebc0ae4fa586ddef03cd79390d541d28ca3c05a7241ffe92ac182e63c251176b40db8fe05fefaa82be","other":"ce1309c8505b446363ae37cd3b1ee3e03ced537bed20aca5d8c4be2133917c408845ef5d0f65876974be2803dfb824827cf5c5a2d050d6ef26cdabcbf3a2dc31","up":true},{"one":"3df030a522a157e36f6b369aab048b9287792743a411a47073c4f9ef7686528f39bf7bf91c48e4d46afe180c8d08430b012bd216d50876baa3b1e7bc17cb55ef","other":"a6ca1d5340f2d7021f541c81cf9aea519675462c8443bb6ddd93919962561b8f5a8431c3ec7e7e7d46c600b653e9a0638d2bb07cf4e29516bf9c4d3653f451b0","up":true},{"one":"896c74ca4cc4cbb9d2b6606d0ebfd6427952c2e16aedbf36933fa3d01f1c505fcd663f3d01c0cf096bef9cfd0bae4595ec7c221cfc362e19a5b7c60614a9658b","other":"f0b2f1e8d46be656109adb18c60677ac9eb8fce7f42e15d9dbb25f94b4e426064780eaf32b79954b9bb72ea89953175da8de35380aaba18931cca374a7de2b11","up":true},{"one":"03d2d77c008b5fa1063b1abc3152b879a529fe4fdb2dc174d6d85312264a38ee4cc49b342507a10fff1a4b0730f1ef8e008b0897d97bfd6f70050adb124d3596","other":"59730132a01ba848a3c050bb6234bca9a72deba33716960fc3ec89b186bfcd313b9bbf049939d5805ff98db2c53a9421ce6ec97d8b4cdbaea53ba264d80d0734","up":true},{"one":"562119edffe8270f6f7a5ad9b13d4c65d643e52a2331d1fee16f7e9b5567f44cfea62df3e8965a22cf08db8fa918f0a0bcae8da2936677e6d25bc88ed85ed2f1","other":"fd12c5c96df6ee76dd7beb9e4e4768dda4d2c498851b6435f13ca0175980d0e4a4ff1c002e4daf41a995f118500604764f88496fb9b2c22e28308d8649b525ce","up":true},{"one":"87e696a354d249493217dc4e0190082f30e09616873803efa376871d4b34f86f0eeb4643d4822d8a0fbcdedb27cd6ba5438e98943d358d960c4835e82261c93e","other":"489660042a8867d90a16ebb013968db26ca3edfc70f53320f511e35b3703eed09fbd787be5c06726a570a54aa15d129cd10db741523adf297929f909be4a0c71","up":true},{"one":"3274b5f48e6929e2305e980b558a4ca3c7cf800b75a6445ea2875cb379e127f3e793e9450a11e927682aa91b8af52e9560dece633833e0f207a8a8a38b7b9c54","other":"eb097186ff58d96a7ead7a7f9c05a44075d84537bd4fd3f82857bf2c45bee1c6dece434a7707cde69e96f02366859cab4c991fdb7615e113a868d4b9c7524a45","up":true},{"one":"56b25623ac935f3a8aac1e2603a6bd15ace1e5714671954b47f2cab960cf47922828f415105602408d0a732a893ebeea6f9afab7f889bb235c81589548d09391","other":"4448a59bde9edb93edcdb4a77f3e2277b9c01ffea45496ee0533eb5192955a08a0f982e25cf772e0dae68735a55b7acd221f6ba7b134f1e999087bee182330e8","up":true},{"one":"b09af9e5552e72f918174963dad58a4492d3afa120f78e43820df7bff7fae9f6b52bc6c8c73d3a9af91d20134f4ff1b037db2ef0bc3d8c495a771d63de678bc0","other":"f7637cdd5ef26de40b9055c1df91a45725670c8df11ae934c0d99d2547c3eb4c42a16dbb2e75bcaf4b1b9347c48db65f549a0623179a08dd8cbad92f5bca08cf","up":true},{"one":"1955bedf0bc9044b13a2c16158087123197c74147c86aa3b9389d308a364e80edbc573bcc836d8a262a77f3c9233ebddb1b82eca83cd0a0e4bda6564c443bb70","other":"3103510e00a3f49a5e715719049fc8c9c67a2373a548f326458aeb6d9c75ed92b94373638fd075def0209113b4e85d972c23f064539f7b041596184e40d7f9a2","up":true},{"one":"9e6c1c6e871638182c4b54ac89352ef5c2bca0a99424a1369013e7c182883da0e8d7ab96b3c8254c31fa315b941d8ddee153157626821fc78c2cae951c1c9053","other":"178d5ce398a7114a63a0c953a59932e769891420f6b1544f08c082cd37b531b66757652d279b3036b03b04f8d46eceb0b46fb95646c6668e2921af75c06c3d97","up":true},{"one":"2d6d55edd34c0d9a0130b4806e409bbe18cdda5c2b221cf46136718ec20ffc9d8e92838d78aff92fbcc85f5d081da361dd1e3d7f3d4e1ea57877d6bb7aa0b6f7","other":"3103510e00a3f49a5e715719049fc8c9c67a2373a548f326458aeb6d9c75ed92b94373638fd075def0209113b4e85d972c23f064539f7b041596184e40d7f9a2","up":true},{"one":"9c6dcfef0e128dbfeca58b8ac625b08fb447b0d579bd3f18bc0e2be60d1ec2274595d0554ddba0ca7eb660099d3ea146d8076792b46c93841d2ecf8cf608f5ba","other":"ed1ab28230ed533abf25633508d54f32bbff78a10c7a15fad5c2320cda9d9669c6d0e15689d8885400e64cbcd81730456f8f4bd5c98681d2cd8a8d4e1daec553","up":true},{"one":"5984a296b49bfba30315501ce2ae88ed0392ab2959ac4e7e6b9a29090f344b9dd13873ca137e8317c402cd2e14a61965d5707065b8ded46c41a054731933719f","other":"ecbdca037cd7892752345b48b4219478b1b334f83ce7140fcc72eb71784436b690ce7a41b03e013cefc19d64a34a20cfef1b9e2b535d938bcdcb39fe63645a42","up":true},{"one":"a9e0b763852706722dc904b494293f9399c0fa32255890aa720285b8160335bb618f36b68a81b875a805384179f600defef474d486b4ea04b003ef6477ab7907","other":"a6ca1d5340f2d7021f541c81cf9aea519675462c8443bb6ddd93919962561b8f5a8431c3ec7e7e7d46c600b653e9a0638d2bb07cf4e29516bf9c4d3653f451b0","up":true},{"one":"3572a22097a313b3adef95a7b6cc679f8d1201a156d764e61a9fbc63d123fb4826f7125402fb6569beed359e1c1e5e6cb6993a75975da6cd4ce15669a2eea758","other":"3540d888c3207d6df233afd1164ff9dde2551730862772547e04f7311de364968e113f38a7dea1ab0916a7f8307017de5b49578fa4ebcc39651e541fde51be48","up":true},{"one":"3103510e00a3f49a5e715719049fc8c9c67a2373a548f326458aeb6d9c75ed92b94373638fd075def0209113b4e85d972c23f064539f7b041596184e40d7f9a2","other":"cdd86dea7dde96ff7cc1e3248fd17d107c83f2cc7ce2111c41530448962763309e91a05b5dad4663d0e02db59ed4129ab0c3e1eedc42c654e39d29f99038063b","up":true},{"one":"c89dbada7195464e732671ac6fff014cacfb4c879b63b6b84e7c1bce367522f759bd06e504b15f43a1735c6322356747fa5c4951882d4fd6cdf6f7cf13726719","other":"6ce3a68cb1e2924ad97f22006094c709a3dd8b4ca1546fbb037f841a9e5ac62def242015dbf6221bda610153db064edcbb58a78a35a06077b8c02bf5b2a33c04","up":true},{"one":"3e7820bb15c07f515bd63791b66136723dcc9878b3145fe0f238f6b41e3f2f7565ae55ef24f08ae461950ce1ae0c8a80fe5e4fd4f2f88c4acf4a2c94640df239","other":"9c6dcfef0e128dbfeca58b8ac625b08fb447b0d579bd3f18bc0e2be60d1ec2274595d0554ddba0ca7eb660099d3ea146d8076792b46c93841d2ecf8cf608f5ba","up":true},{"one":"1480f62d85ea32226d9f77ccd31780b3e704fb60618a588ae85dcd1c0e84e878c5fc092adfb306e8ebc7abba9ec429cb2447754502ef847cf931467f31fa50b2","other":"670949178a5fad22da03af1e206c814a797c0e9eb4e3371f83612f121e5b56e767706a3ae36628cd0c86dd7bd1586ca4df57e2de27b28a31284ecf9176d330e5","up":true},{"one":"09b60de1e85bb6f7d2caf5b1ab58204d7d04531ece300dcd7bcc9157b8b3ef2a182758808a0eec6056034f29f52caadb7c690f498c1c8832ff7a6a9ecff308bd","other":"27fb8fcda1986644f985d68430c399f0299644b00b234c355362721081d12f9eb7686eea8f92eabda1d342bf56255e51c07b200c6233f95ac009f15b874eee97","up":true},{"one":"28afc20d8f4779b285bb14870062dbb54796ec77623302e51bc1bafed9e2c35751c8469ffc482718e059875dfa2226195ed10999e251498cba3a444896cb67db","other":"340420ee18d55913f790d0fcc2305b40b1e7bef2eddb79dda57801690aeeead693ebd1a9ff8557671f5ae136b3e65733306924bd00444cbc6e7c6235e5a2c77f","up":true},{"one":"188bf77c9c1e45f009efe7aefdb040bdb47763980fe7eb0851295d657fa2a8978efbd2997c1dc30f4f0874eecf9ca9550487cf41da237b84d071963d35b6baff","other":"3103510e00a3f49a5e715719049fc8c9c67a2373a548f326458aeb6d9c75ed92b94373638fd075def0209113b4e85d972c23f064539f7b041596184e40d7f9a2","up":true},{"one":"4448a59bde9edb93edcdb4a77f3e2277b9c01ffea45496ee0533eb5192955a08a0f982e25cf772e0dae68735a55b7acd221f6ba7b134f1e999087bee182330e8","other":"f7637cdd5ef26de40b9055c1df91a45725670c8df11ae934c0d99d2547c3eb4c42a16dbb2e75bcaf4b1b9347c48db65f549a0623179a08dd8cbad92f5bca08cf","up":true},{"one":"ce1309c8505b446363ae37cd3b1ee3e03ced537bed20aca5d8c4be2133917c408845ef5d0f65876974be2803dfb824827cf5c5a2d050d6ef26cdabcbf3a2dc31","other":"3103510e00a3f49a5e715719049fc8c9c67a2373a548f326458aeb6d9c75ed92b94373638fd075def0209113b4e85d972c23f064539f7b041596184e40d7f9a2","up":true},{"one":"f2ea93f43be9d0c3fa21f1496dc13c778977a6afdcba24c8b146de7dca2cdde62a5b792aab969e5b4b6c56f63066b336580d911f206049cc24cac32a25fc4306","other":"f0b2f1e8d46be656109adb18c60677ac9eb8fce7f42e15d9dbb25f94b4e426064780eaf32b79954b9bb72ea89953175da8de35380aaba18931cca374a7de2b11","up":true},{"one":"489660042a8867d90a16ebb013968db26ca3edfc70f53320f511e35b3703eed09fbd787be5c06726a570a54aa15d129cd10db741523adf297929f909be4a0c71","other":"9c6dcfef0e128dbfeca58b8ac625b08fb447b0d579bd3f18bc0e2be60d1ec2274595d0554ddba0ca7eb660099d3ea146d8076792b46c93841d2ecf8cf608f5ba","up":true},{"one":"e3f2e777a96b2137b3104b84d5d827d484eac9ee1b585430e09f790d7e26978da12802325927c3c483bc19973e09cd3f70c513c34798e5da650f8d2f0c8c5c47","other":"dafb58b2fc8a14f2b23b7df33d28aa7847a08f80e9c21a654d4c97d928e1afe6585644d27f22442cf70d229c32783be6a03c0920be153fc4d9f3b273dfa90ec3","up":true},{"one":"caad8529d498a4a1e1ba7573689a913500bd409345ef8e3656abca748269eb73b919282f7f2eb0087f81f7bc52c367657ac8be0cdac65d2490c7c50c874444b7","other":"dafb58b2fc8a14f2b23b7df33d28aa7847a08f80e9c21a654d4c97d928e1afe6585644d27f22442cf70d229c32783be6a03c0920be153fc4d9f3b273dfa90ec3","up":true},{"one":"3540d888c3207d6df233afd1164ff9dde2551730862772547e04f7311de364968e113f38a7dea1ab0916a7f8307017de5b49578fa4ebcc39651e541fde51be48","other":"44462055ba68fdef337dd19d8123aace9a12284c13bc97687416b6b4ca0c94234ba7db6823651fc021d6ac1539e0c5321e763a7a12c9e7c8a583aac5369817d8","up":true},{"one":"ecbdca037cd7892752345b48b4219478b1b334f83ce7140fcc72eb71784436b690ce7a41b03e013cefc19d64a34a20cfef1b9e2b535d938bcdcb39fe63645a42","other":"bf1e6eeb8b229f63b49213db499b71dcfe0ae45ee3f14685c7cbfa3f0a2150e52a89c853f4cd8c7a92e6e5f6083044efddfa17391662e3cff6290da679520404","up":true},{"one":"73be4d2291c68ca4554a86fa170f7595210e1b6bbbeef3c1d5623a2b5d03a8fd6e26caa26afc639c20c8a351a89dad1086f91734f09afab62d28ec17b700fa01","other":"816e91fa8ff68ba067a89390ef61e7f23211e5e05049daa103ad1ff84b94fbcf535a6f6b515fb571939f5656869767c608513808800baba7e5d2b5f3a17a9691","up":true},{"one":"41994605708232b4ca7448c3bc0760a7b86bf26d442091e5ce6e92eac94925721d7e0eca04bdd03bb1bba1ef92deeccd4bf1b7c6c3318b7e8d031965c6646761","other":"077d2d032874e5ce70e9b928b7fe72c0326ba92394e16245e31d48b5731d3d32bfd86acf40825decff54bcd735e9ebfd94eba677c418ea7007baec9db4af676d","up":true},{"one":"805d784527be4e32e84ddf045baee1ccf348cdf8288de3aae1a5379f762576b957525ef358d9b42c68a93394017880adc09bb2b1b5e01102dc7e4240baf2af95","other":"86b84ddf64d301f6a9c4504c59eb4031d3167fb74101abea3b694845a009dc522be7b2e2720097ceea9f36058e160f42a2a438a33034929a5c1a7793c7ccef7b","up":true},{"one":"2502fc8ee0ccda79ad1dbd9c7cec625da85980b9116bdd56dc367d508039e25e5f65183293006e5b0df72fa9037a48bd2b133a757940d3587ff77ae2392e3eaf","other":"51ba4faf0988717a37dcddc0a60a70ead33bde310184fc450f9ca73c67f931e6767ad5930bcf409e5aeb613a9ff7a03e47de6fc13b33d8af0b87b38822ae6888","up":true},{"one":"bfef26733f5196a11484bcc28d88776e747189ae7cec883ff39a27cfeee6d9d1efb34560c9f8e75eec43fc069a2ce5f0c78107a36cc8a569d37bd5306aecf23a","other":"665c3288c14dc1c17d85d17d634910f42183482c7e77c47e68f9b4f475b93e8c152246b9e34781606315ff6ef0f8360342500d15e4a2d67d9df6b72f30af64a7","up":true},{"one":"51ba4faf0988717a37dcddc0a60a70ead33bde310184fc450f9ca73c67f931e6767ad5930bcf409e5aeb613a9ff7a03e47de6fc13b33d8af0b87b38822ae6888","other":"f2ea93f43be9d0c3fa21f1496dc13c778977a6afdcba24c8b146de7dca2cdde62a5b792aab969e5b4b6c56f63066b336580d911f206049cc24cac32a25fc4306","up":true},{"one":"1e3c83cabbe6852c987ae521b7fcb33185cf855c59b6235ebb8e57a6f860ccc159ddc01b4a21d251c8faca4559ceb271e046a51493ba148c0d3aed97ad208969","other":"4448a59bde9edb93edcdb4a77f3e2277b9c01ffea45496ee0533eb5192955a08a0f982e25cf772e0dae68735a55b7acd221f6ba7b134f1e999087bee182330e8","up":true},{"one":"afb5754b4748b7ac5628e32b242c90aab0e2fc7da58d8d5c8c775d13d8a6fd32240f1b89021587858168cbe7b3ea7ad07807728655eae0a9907060494a7c99ca","other":"bf1e6eeb8b229f63b49213db499b71dcfe0ae45ee3f14685c7cbfa3f0a2150e52a89c853f4cd8c7a92e6e5f6083044efddfa17391662e3cff6290da679520404","up":true},{"one":"fd12c5c96df6ee76dd7beb9e4e4768dda4d2c498851b6435f13ca0175980d0e4a4ff1c002e4daf41a995f118500604764f88496fb9b2c22e28308d8649b525ce","other":"06472c89def07fa73188d253cf1acddc2be984842f3a234edb3db95449ba74928ab1395eca1b8978987769863afffb488fc27c9ac723aa24837b66c12f38d735","up":true},{"one":"f62bd19b0fd052207743ce53c3d48a3a71e9219b75e41a9497a43e6368e559d5487ff1ab644f2df4106b500583e4344515f73187eec773115deb977b4ebc3514","other":"73be4d2291c68ca4554a86fa170f7595210e1b6bbbeef3c1d5623a2b5d03a8fd6e26caa26afc639c20c8a351a89dad1086f91734f09afab62d28ec17b700fa01","up":true},{"one":"f6a07a1d361a4671e997d5eaadae61736291aff3896cb69f06bbc19bf7536dd152e0b15422b2fd9f8a9d2f9a251c9a07d0140319900e2cc9f25a59025c7dc91f","other":"03d2d77c008b5fa1063b1abc3152b879a529fe4fdb2dc174d6d85312264a38ee4cc49b342507a10fff1a4b0730f1ef8e008b0897d97bfd6f70050adb124d3596","up":true},{"one":"a05a18161c2d01a0f122548c66509dd1fcf3ee52975035bc79fb059e9613b743a16cd6f5ac54090e68f51bcf76ff21fb3805ba3197a96b4236afb80f791df802","other":"9c6dcfef0e128dbfeca58b8ac625b08fb447b0d579bd3f18bc0e2be60d1ec2274595d0554ddba0ca7eb660099d3ea146d8076792b46c93841d2ecf8cf608f5ba","up":true},{"one":"08900197e74e285a5a8a9cc53fbd420bb35043ab27eb2d9eab22615e736a093abfa235c17f667dcc791cb50b9022082eafd9fba030194cc84f0358b769adc85b","other":"f62bd19b0fd052207743ce53c3d48a3a71e9219b75e41a9497a43e6368e559d5487ff1ab644f2df4106b500583e4344515f73187eec773115deb977b4ebc3514","up":true},{"one":"c773af3af01ee8ab9fa8d06987baf4f10c394fdd386d69b7a7362f4b68fd6fc082337d3b33a19d584c5801a3e9198225d7b61f6629e34ce823be70908339f4c7","other":"18bb6572965f4263c5a4d59a73027abc57a46122125ee58d871e95c993e6a1e8230438ce696a5f8880a08749837268b54319f7b0aa254c1a5bd453a8e9bcf84f","up":true},{"one":"da3e0fd71eb96ba2cab7f920d32f5425d1aad41d00765fdffb0b215d9dd5b60e2bc5929eafebee5b2b5a11aec164e141beff19d828aac7d1fabd3ffb0bfb8450","other":"d90a81a583c82d626b92f27244f027da4a0ae76e6d3bdc1de0af7be01798f1fb04b34ce60c6d8651a39d7a70915438a4aa63e5adf844a9f7e38dbf0b1dba754d","up":true},{"one":"3e9c0bbd146d8b1040b4f379eecf802c27c4d0a70e64a9fb2e941a7edab9b00396b0b67fc5c891652743cdba3b342973ed49615b32da54b925954a799240431c","other":"a40391285d1a97f1fb368b20c8e4d02be1bdebc0db41f00f99aac2f01893dc12256cd5a711117a981fbb3f9dfea18c19cf3603e925dbd67c4032b22b41eab8d5","up":true},{"one":"e0420ba2a293315d810928a0e09a507c6aaf93977ba2c7598e9b83723b4a66682398ea17542c26767c7ff0f4ca09c537d3cc10dad283f079f1de73e25e87cb5c","other":"7a18392b8338108a996196ee190a93a1b9954c8e05a062c421da513a1828dfa739e7b224878c0670cf74bbc743c7ca7ee8cfee6b6a602fe1f4a82ecfbd38c2f4","up":true},{"one":"7a509686ebce91778fe22e834a94ab03f92457d41385099ba657fe62c7469a9669bddb9a3d7b0150efa1d2f40c69bc786c7f4ede1cf8b19411eea1d23cb7d56c","other":"44462055ba68fdef337dd19d8123aace9a12284c13bc97687416b6b4ca0c94234ba7db6823651fc021d6ac1539e0c5321e763a7a12c9e7c8a583aac5369817d8","up":true},{"one":"816e91fa8ff68ba067a89390ef61e7f23211e5e05049daa103ad1ff84b94fbcf535a6f6b515fb571939f5656869767c608513808800baba7e5d2b5f3a17a9691","other":"59730132a01ba848a3c050bb6234bca9a72deba33716960fc3ec89b186bfcd313b9bbf049939d5805ff98db2c53a9421ce6ec97d8b4cdbaea53ba264d80d0734","up":true},{"one":"77327983685f39f006806170fe351063a58ff1bd8dedc222d538e86cfd18abdfefd548328f25fc5afde8170aa5c35311353019468f2b439c331837ddfbb25a52","other":"3df030a522a157e36f6b369aab048b9287792743a411a47073c4f9ef7686528f39bf7bf91c48e4d46afe180c8d08430b012bd216d50876baa3b1e7bc17cb55ef","up":true},{"one":"562119edffe8270f6f7a5ad9b13d4c65d643e52a2331d1fee16f7e9b5567f44cfea62df3e8965a22cf08db8fa918f0a0bcae8da2936677e6d25bc88ed85ed2f1","other":"178d5ce398a7114a63a0c953a59932e769891420f6b1544f08c082cd37b531b66757652d279b3036b03b04f8d46eceb0b46fb95646c6668e2921af75c06c3d97","up":true},{"one":"a6ca1d5340f2d7021f541c81cf9aea519675462c8443bb6ddd93919962561b8f5a8431c3ec7e7e7d46c600b653e9a0638d2bb07cf4e29516bf9c4d3653f451b0","other":"3e9c0bbd146d8b1040b4f379eecf802c27c4d0a70e64a9fb2e941a7edab9b00396b0b67fc5c891652743cdba3b342973ed49615b32da54b925954a799240431c","up":true},{"one":"e7bb63c5187ee85d965fed5cb33d1678c0e090b4e4c3f3d859755565db18046cb60025453bdebf136373c416a2e6e56be063bca6c9257b7b175dcf966e274205","other":"2d6d55edd34c0d9a0130b4806e409bbe18cdda5c2b221cf46136718ec20ffc9d8e92838d78aff92fbcc85f5d081da361dd1e3d7f3d4e1ea57877d6bb7aa0b6f7","up":true},{"one":"545850cb90787d49c579b1ed54a753ebd00eaafe3f1bd04d57266e4912fb1cdd654446ef054a973a583ce8dfc6cc130b6f90e63bcf75372fc21c445f8e1e6005","other":"5d917ffc9d70a38670941ce206aa7ea1b9ea65c1d783f14ebdf7c7afa6ca8b237112aaa9b1a3f757132093a604ef378280c5bdef02c2688049a91a412c399bfe","up":true},{"one":"4de606aa7e722197b918c5f7f0db86a3081d48e89d21428b04f19c3ff3755eac0bddbff5fad8bda94b9e57f58fba2fecdbabbf710f7afb381bf4f1a4fe55cd93","other":"ed1ab28230ed533abf25633508d54f32bbff78a10c7a15fad5c2320cda9d9669c6d0e15689d8885400e64cbcd81730456f8f4bd5c98681d2cd8a8d4e1daec553","up":true},{"one":"5771bef7f50439f9b81d2a7bf7060b1ad4b38675d8f6abbac3cc4c215fb0cb5dd07f6873545b42218337556925566025476e2915b7b98e662a3dcd28bebf0eb4","other":"e0420ba2a293315d810928a0e09a507c6aaf93977ba2c7598e9b83723b4a66682398ea17542c26767c7ff0f4ca09c537d3cc10dad283f079f1de73e25e87cb5c","up":true},{"one":"06472c89def07fa73188d253cf1acddc2be984842f3a234edb3db95449ba74928ab1395eca1b8978987769863afffb488fc27c9ac723aa24837b66c12f38d735","other":"2502fc8ee0ccda79ad1dbd9c7cec625da85980b9116bdd56dc367d508039e25e5f65183293006e5b0df72fa9037a48bd2b133a757940d3587ff77ae2392e3eaf","up":true},{"one":"670949178a5fad22da03af1e206c814a797c0e9eb4e3371f83612f121e5b56e767706a3ae36628cd0c86dd7bd1586ca4df57e2de27b28a31284ecf9176d330e5","other":"51302ef7b50922398ad802e917390bb4a3c24c877f2c2bcb7fcb34de9feca22673a2c594639914fe46a28837ffadfd03bb673afbc856aff5e59caf8e76082482","up":true},{"one":"077d2d032874e5ce70e9b928b7fe72c0326ba92394e16245e31d48b5731d3d32bfd86acf40825decff54bcd735e9ebfd94eba677c418ea7007baec9db4af676d","other":"3e9c0bbd146d8b1040b4f379eecf802c27c4d0a70e64a9fb2e941a7edab9b00396b0b67fc5c891652743cdba3b342973ed49615b32da54b925954a799240431c","up":true},{"one":"57bfbde13c71e035c96513870aa8215198f78806e7cdb01c54fbdb392de2c40386d768d6fdc4c68534a67e531867ca74d8ca4dcf34ff7f7f64ec35edee3e5f68","other":"0e8c1a6b70524c4fdc492c74348bac4ccd5d140bd41352607e8cfba45561afb1e6e12f3e2fcf03c1778c9ae5ae19cb9218ee2d613983768f54e3f54e69bb6600","up":true},{"one":"5d917ffc9d70a38670941ce206aa7ea1b9ea65c1d783f14ebdf7c7afa6ca8b237112aaa9b1a3f757132093a604ef378280c5bdef02c2688049a91a412c399bfe","other":"0e8c1a6b70524c4fdc492c74348bac4ccd5d140bd41352607e8cfba45561afb1e6e12f3e2fcf03c1778c9ae5ae19cb9218ee2d613983768f54e3f54e69bb6600","up":true},{"one":"20f171ab01a814a2856a6cbe7929269f18f6329914289515e2cb9d078ac14ebdae457789dd638c6415b062799114570f556147d4bf9ac850f00b6d0762765ac1","other":"33e3ab7108ced43102003c3b3192b194100f32b6bcb67bb772ea9696e35721196699cf01e443f7cdf8076ad83aaf7468b75c71d03efb95f4c07cf0742ea9af81","up":true},{"one":"f0b2f1e8d46be656109adb18c60677ac9eb8fce7f42e15d9dbb25f94b4e426064780eaf32b79954b9bb72ea89953175da8de35380aaba18931cca374a7de2b11","other":"f62bd19b0fd052207743ce53c3d48a3a71e9219b75e41a9497a43e6368e559d5487ff1ab644f2df4106b500583e4344515f73187eec773115deb977b4ebc3514","up":true},{"one":"49eb706cd7e95ad78502a508487d88b818861d94334aee36b2acef5c25cfff5c0efc2df9dc5dbb18acd4003d5cc0c843d3b40363adf2f62a14c04d814268fdee","other":"f2ea93f43be9d0c3fa21f1496dc13c778977a6afdcba24c8b146de7dca2cdde62a5b792aab969e5b4b6c56f63066b336580d911f206049cc24cac32a25fc4306","up":true},{"one":"d8cfadac10473b31a4560c711636a05615f13054388065344642ff1d04246fb62eafeec06805264eafead111ed8134e11a8e21f42a0eb950c23b142e627bd8cb","other":"a40391285d1a97f1fb368b20c8e4d02be1bdebc0db41f00f99aac2f01893dc12256cd5a711117a981fbb3f9dfea18c19cf3603e925dbd67c4032b22b41eab8d5","up":true},{"one":"a58a2dd3f5ee2471f0ddd555ffcc45d86e2d8c325585e3fe55eee878b8a626faccce73679d32811fc5d068c153e671673f4cd020f3c7fb37bc6fd9646931646a","other":"33e3ab7108ced43102003c3b3192b194100f32b6bcb67bb772ea9696e35721196699cf01e443f7cdf8076ad83aaf7468b75c71d03efb95f4c07cf0742ea9af81","up":true},{"one":"b2bea653b6ec9629c6f934be72fccf30acf836698e21e81dd8085f070ba8259ba43eee43c342738a4b782f5fbddd44caa28f56dffc08237ca7567c965ac3beca","other":"665c3288c14dc1c17d85d17d634910f42183482c7e77c47e68f9b4f475b93e8c152246b9e34781606315ff6ef0f8360342500d15e4a2d67d9df6b72f30af64a7","up":true},{"one":"d71c50805f284ed3a759e2e81f220fbc73d6d0a7a261b4c9e7878c3da143cfc07afa83e1635b6a45530f71a60b9f17c485a2fd6617c6c2bff82bacc71c208087","other":"562119edffe8270f6f7a5ad9b13d4c65d643e52a2331d1fee16f7e9b5567f44cfea62df3e8965a22cf08db8fa918f0a0bcae8da2936677e6d25bc88ed85ed2f1","up":true},{"one":"3df030a522a157e36f6b369aab048b9287792743a411a47073c4f9ef7686528f39bf7bf91c48e4d46afe180c8d08430b012bd216d50876baa3b1e7bc17cb55ef","other":"a9e0b763852706722dc904b494293f9399c0fa32255890aa720285b8160335bb618f36b68a81b875a805384179f600defef474d486b4ea04b003ef6477ab7907","up":true},{"one":"4bd17847bdf60ea93a670a84a0ff8fe028d35228e814d6ebc0ae4fa586ddef03cd79390d541d28ca3c05a7241ffe92ac182e63c251176b40db8fe05fefaa82be","other":"08900197e74e285a5a8a9cc53fbd420bb35043ab27eb2d9eab22615e736a093abfa235c17f667dcc791cb50b9022082eafd9fba030194cc84f0358b769adc85b","up":true},{"one":"3274b5f48e6929e2305e980b558a4ca3c7cf800b75a6445ea2875cb379e127f3e793e9450a11e927682aa91b8af52e9560dece633833e0f207a8a8a38b7b9c54","other":"cdd86dea7dde96ff7cc1e3248fd17d107c83f2cc7ce2111c41530448962763309e91a05b5dad4663d0e02db59ed4129ab0c3e1eedc42c654e39d29f99038063b","up":true},{"one":"28afc20d8f4779b285bb14870062dbb54796ec77623302e51bc1bafed9e2c35751c8469ffc482718e059875dfa2226195ed10999e251498cba3a444896cb67db","other":"86b84ddf64d301f6a9c4504c59eb4031d3167fb74101abea3b694845a009dc522be7b2e2720097ceea9f36058e160f42a2a438a33034929a5c1a7793c7ccef7b","up":true},{"one":"b09af9e5552e72f918174963dad58a4492d3afa120f78e43820df7bff7fae9f6b52bc6c8c73d3a9af91d20134f4ff1b037db2ef0bc3d8c495a771d63de678bc0","other":"2fdb4382c4bc2950948a8cff13a7df65627bc0b20661cae20fd29acab166c97701594ee3151d75c006ba86d1d68b624b1d1f78e3d1e2fc297844956ef82208a8","up":true},{"one":"1955bedf0bc9044b13a2c16158087123197c74147c86aa3b9389d308a364e80edbc573bcc836d8a262a77f3c9233ebddb1b82eca83cd0a0e4bda6564c443bb70","other":"bf1e6eeb8b229f63b49213db499b71dcfe0ae45ee3f14685c7cbfa3f0a2150e52a89c853f4cd8c7a92e6e5f6083044efddfa17391662e3cff6290da679520404","up":true},{"one":"56e8f792ec9a75ec9e91d472b8a4b023655dd68c2a448a33397b125fe3584a5efa1b492e47077b24acfe0396b73e1cb564a6a6b2aee1b457781dfaf6d43fcaed","other":"51ba4faf0988717a37dcddc0a60a70ead33bde310184fc450f9ca73c67f931e6767ad5930bcf409e5aeb613a9ff7a03e47de6fc13b33d8af0b87b38822ae6888","up":true},{"one":"5984a296b49bfba30315501ce2ae88ed0392ab2959ac4e7e6b9a29090f344b9dd13873ca137e8317c402cd2e14a61965d5707065b8ded46c41a054731933719f","other":"cdd86dea7dde96ff7cc1e3248fd17d107c83f2cc7ce2111c41530448962763309e91a05b5dad4663d0e02db59ed4129ab0c3e1eedc42c654e39d29f99038063b","up":true},{"one":"3103510e00a3f49a5e715719049fc8c9c67a2373a548f326458aeb6d9c75ed92b94373638fd075def0209113b4e85d972c23f064539f7b041596184e40d7f9a2","other":"dafb58b2fc8a14f2b23b7df33d28aa7847a08f80e9c21a654d4c97d928e1afe6585644d27f22442cf70d229c32783be6a03c0920be153fc4d9f3b273dfa90ec3","up":true},{"one":"ce1309c8505b446363ae37cd3b1ee3e03ced537bed20aca5d8c4be2133917c408845ef5d0f65876974be2803dfb824827cf5c5a2d050d6ef26cdabcbf3a2dc31","other":"5d917ffc9d70a38670941ce206aa7ea1b9ea65c1d783f14ebdf7c7afa6ca8b237112aaa9b1a3f757132093a604ef378280c5bdef02c2688049a91a412c399bfe","up":true},{"one":"3e7820bb15c07f515bd63791b66136723dcc9878b3145fe0f238f6b41e3f2f7565ae55ef24f08ae461950ce1ae0c8a80fe5e4fd4f2f88c4acf4a2c94640df239","other":"f2ea93f43be9d0c3fa21f1496dc13c778977a6afdcba24c8b146de7dca2cdde62a5b792aab969e5b4b6c56f63066b336580d911f206049cc24cac32a25fc4306","up":true},{"one":"18bb6572965f4263c5a4d59a73027abc57a46122125ee58d871e95c993e6a1e8230438ce696a5f8880a08749837268b54319f7b0aa254c1a5bd453a8e9bcf84f","other":"a5cdff211813e17fadd43ec55a6cf4e97e6ca0c3b2cef0db58923b27d36207fd1a77146efb6093bd94d7eb89cc77d8c735fc64ab098839efc74a00b5e8687555","up":true},{"one":"5b4de68680c5d1a75cccd5e7a82319c031f5d61d79cbb6532e1254ab81c833c3fafb54390cca7a770e84690c490fcba90482b35321870f8506335a2f57cc052e","other":"77327983685f39f006806170fe351063a58ff1bd8dedc222d538e86cfd18abdfefd548328f25fc5afde8170aa5c35311353019468f2b439c331837ddfbb25a52","up":true},{"one":"188bf77c9c1e45f009efe7aefdb040bdb47763980fe7eb0851295d657fa2a8978efbd2997c1dc30f4f0874eecf9ca9550487cf41da237b84d071963d35b6baff","other":"5d917ffc9d70a38670941ce206aa7ea1b9ea65c1d783f14ebdf7c7afa6ca8b237112aaa9b1a3f757132093a604ef378280c5bdef02c2688049a91a412c399bfe","up":true},{"one":"da15d60a4b9a8816ce24c20f6c941c51229c1fb5e070b8b29be2977c2f7b41f8f17e4b6efe75f465e7935ded1ba17472f046eac73393db7197018fa86d11c31f","other":"fa897ba112f34839064c6871a4c9504c5d709eff5095a137c6a42726d58eb623af976cb96cc30db67e6ac9347c769f032aa4ebda884285a057059040c008ad3e","up":true},{"one":"e3f2e777a96b2137b3104b84d5d827d484eac9ee1b585430e09f790d7e26978da12802325927c3c483bc19973e09cd3f70c513c34798e5da650f8d2f0c8c5c47","other":"3df030a522a157e36f6b369aab048b9287792743a411a47073c4f9ef7686528f39bf7bf91c48e4d46afe180c8d08430b012bd216d50876baa3b1e7bc17cb55ef","up":true},{"one":"489660042a8867d90a16ebb013968db26ca3edfc70f53320f511e35b3703eed09fbd787be5c06726a570a54aa15d129cd10db741523adf297929f909be4a0c71","other":"4bd17847bdf60ea93a670a84a0ff8fe028d35228e814d6ebc0ae4fa586ddef03cd79390d541d28ca3c05a7241ffe92ac182e63c251176b40db8fe05fefaa82be","up":true},{"one":"caad8529d498a4a1e1ba7573689a913500bd409345ef8e3656abca748269eb73b919282f7f2eb0087f81f7bc52c367657ac8be0cdac65d2490c7c50c874444b7","other":"cdd86dea7dde96ff7cc1e3248fd17d107c83f2cc7ce2111c41530448962763309e91a05b5dad4663d0e02db59ed4129ab0c3e1eedc42c654e39d29f99038063b","up":true},{"one":"3540d888c3207d6df233afd1164ff9dde2551730862772547e04f7311de364968e113f38a7dea1ab0916a7f8307017de5b49578fa4ebcc39651e541fde51be48","other":"6ce3a68cb1e2924ad97f22006094c709a3dd8b4ca1546fbb037f841a9e5ac62def242015dbf6221bda610153db064edcbb58a78a35a06077b8c02bf5b2a33c04","up":true},{"one":"86b84ddf64d301f6a9c4504c59eb4031d3167fb74101abea3b694845a009dc522be7b2e2720097ceea9f36058e160f42a2a438a33034929a5c1a7793c7ccef7b","other":"d71c50805f284ed3a759e2e81f220fbc73d6d0a7a261b4c9e7878c3da143cfc07afa83e1635b6a45530f71a60b9f17c485a2fd6617c6c2bff82bacc71c208087","up":true},{"one":"20bdc859d58d8bf419df64fd6ee1d4363c1d5f403af3abef2720d7d3933924672e12e23e5d76b28e0f6726acf58bdc5eb258cba635e327cbd0b564523305da75","other":"26cf4ea45b9a76daab82a57126f9c6f8726d2eb973e205ab4ab69c8b8be11a32a7eb5c3807e952cd428ce5ddd88f143d4fc9ff8c3de3d159855675afce715615","up":true},{"one":"ed1ab28230ed533abf25633508d54f32bbff78a10c7a15fad5c2320cda9d9669c6d0e15689d8885400e64cbcd81730456f8f4bd5c98681d2cd8a8d4e1daec553","other":"e0420ba2a293315d810928a0e09a507c6aaf93977ba2c7598e9b83723b4a66682398ea17542c26767c7ff0f4ca09c537d3cc10dad283f079f1de73e25e87cb5c","up":true},{"one":"f04c3ae9fe957a14c249acf3ea2e8407d04d108fc01e75f6d52aaf5073b3450025012d138a75b857473eea4d20e57c99b92bff9041f269d995543d7c67a92ec6","other":"20bdc859d58d8bf419df64fd6ee1d4363c1d5f403af3abef2720d7d3933924672e12e23e5d76b28e0f6726acf58bdc5eb258cba635e327cbd0b564523305da75","up":true},{"one":"eb097186ff58d96a7ead7a7f9c05a44075d84537bd4fd3f82857bf2c45bee1c6dece434a7707cde69e96f02366859cab4c991fdb7615e113a868d4b9c7524a45","other":"e7bb63c5187ee85d965fed5cb33d1678c0e090b4e4c3f3d859755565db18046cb60025453bdebf136373c416a2e6e56be063bca6c9257b7b175dcf966e274205","up":true},{"one":"73be4d2291c68ca4554a86fa170f7595210e1b6bbbeef3c1d5623a2b5d03a8fd6e26caa26afc639c20c8a351a89dad1086f91734f09afab62d28ec17b700fa01","other":"49eb706cd7e95ad78502a508487d88b818861d94334aee36b2acef5c25cfff5c0efc2df9dc5dbb18acd4003d5cc0c843d3b40363adf2f62a14c04d814268fdee","up":true},{"one":"03d2d77c008b5fa1063b1abc3152b879a529fe4fdb2dc174d6d85312264a38ee4cc49b342507a10fff1a4b0730f1ef8e008b0897d97bfd6f70050adb124d3596","other":"562119edffe8270f6f7a5ad9b13d4c65d643e52a2331d1fee16f7e9b5567f44cfea62df3e8965a22cf08db8fa918f0a0bcae8da2936677e6d25bc88ed85ed2f1","up":true},{"one":"7a18392b8338108a996196ee190a93a1b9954c8e05a062c421da513a1828dfa739e7b224878c0670cf74bbc743c7ca7ee8cfee6b6a602fe1f4a82ecfbd38c2f4","other":"670949178a5fad22da03af1e206c814a797c0e9eb4e3371f83612f121e5b56e767706a3ae36628cd0c86dd7bd1586ca4df57e2de27b28a31284ecf9176d330e5","up":true},{"one":"41994605708232b4ca7448c3bc0760a7b86bf26d442091e5ce6e92eac94925721d7e0eca04bdd03bb1bba1ef92deeccd4bf1b7c6c3318b7e8d031965c6646761","other":"a40391285d1a97f1fb368b20c8e4d02be1bdebc0db41f00f99aac2f01893dc12256cd5a711117a981fbb3f9dfea18c19cf3603e925dbd67c4032b22b41eab8d5","up":true},{"one":"a5cdff211813e17fadd43ec55a6cf4e97e6ca0c3b2cef0db58923b27d36207fd1a77146efb6093bd94d7eb89cc77d8c735fc64ab098839efc74a00b5e8687555","other":"a9e0b763852706722dc904b494293f9399c0fa32255890aa720285b8160335bb618f36b68a81b875a805384179f600defef474d486b4ea04b003ef6477ab7907","up":true},{"one":"dafb58b2fc8a14f2b23b7df33d28aa7847a08f80e9c21a654d4c97d928e1afe6585644d27f22442cf70d229c32783be6a03c0920be153fc4d9f3b273dfa90ec3","other":"a1b2d0c6f24f5924c61e057fc65b994d9a6755560d740018b4c9ad0bb69212ec69974e22cb037dfeb7ea90a4493997f4c94029870bcc5fd47013b51ca0a26b5d","up":true},{"one":"805d784527be4e32e84ddf045baee1ccf348cdf8288de3aae1a5379f762576b957525ef358d9b42c68a93394017880adc09bb2b1b5e01102dc7e4240baf2af95","other":"f2ea93f43be9d0c3fa21f1496dc13c778977a6afdcba24c8b146de7dca2cdde62a5b792aab969e5b4b6c56f63066b336580d911f206049cc24cac32a25fc4306","up":true},{"one":"6ce3a68cb1e2924ad97f22006094c709a3dd8b4ca1546fbb037f841a9e5ac62def242015dbf6221bda610153db064edcbb58a78a35a06077b8c02bf5b2a33c04","other":"cd0e9a45b45f9a67417fcde29d9f92c45ca4db46eebbfe47dcf6999e23e549e4205f42ada8e3fcd00e2fb5f832bb92a27a59b43c4a5909148d81399c2e8ce492","up":true},{"one":"872cdbb6d74fb55fd2d51877ef7804bdd2eeb6de0297eb2ce18b67e52379b147d54a46d2385ec9293eb21736bed4191d92c5c75e8e81fc5a6c691970e019f570","other":"27fb8fcda1986644f985d68430c399f0299644b00b234c355362721081d12f9eb7686eea8f92eabda1d342bf56255e51c07b200c6233f95ac009f15b874eee97","up":true},{"one":"f8052e328014f39157036f3dcecdb23419c0959473a88282605f10add681ef5cbfb1e926b522f98b8401272113b677a67225874d1afb0bff4b11140cc071de44","other":"a1b2d0c6f24f5924c61e057fc65b994d9a6755560d740018b4c9ad0bb69212ec69974e22cb037dfeb7ea90a4493997f4c94029870bcc5fd47013b51ca0a26b5d","up":true},{"one":"562119edffe8270f6f7a5ad9b13d4c65d643e52a2331d1fee16f7e9b5567f44cfea62df3e8965a22cf08db8fa918f0a0bcae8da2936677e6d25bc88ed85ed2f1","other":"e59940a6dfe35a6214e2e3daba9ad94e630004cd8f029e13a6649a56dc528ff94bc09d8d21a2f14a56b4ff759b60ebf3d27c1029862c183b8416fa3e950bdb55","up":true},{"one":"9c3be147f9fe0fa34e553d9e4332969086ea7fa65294b61ca35c9f731f6b81d0b70cdcfe2ba52b6cea3c0de14b7ea40031b5cc40661c4bb821147894130d7bf5","other":"2fdb4382c4bc2950948a8cff13a7df65627bc0b20661cae20fd29acab166c97701594ee3151d75c006ba86d1d68b624b1d1f78e3d1e2fc297844956ef82208a8","up":true},{"one":"bfef26733f5196a11484bcc28d88776e747189ae7cec883ff39a27cfeee6d9d1efb34560c9f8e75eec43fc069a2ce5f0c78107a36cc8a569d37bd5306aecf23a","other":"750ca601f07d65f426f6ea5f34e06238f9d7a931f022f9b0ebc811943d3725500cb3c6f00c8d05eb8d5b353c6534136dff38b9a8d3d4dc5bf49cd96875704d07","up":true},{"one":"276256790c9317d09ff7802f4ad0a85840fe62527390ce1790e1e3186e8b3f04acfaa41dcd02303d333423678a4037e4f4854676e79ced3232a3dbd772cc2680","other":"49eb706cd7e95ad78502a508487d88b818861d94334aee36b2acef5c25cfff5c0efc2df9dc5dbb18acd4003d5cc0c843d3b40363adf2f62a14c04d814268fdee","up":true},{"one":"afb5754b4748b7ac5628e32b242c90aab0e2fc7da58d8d5c8c775d13d8a6fd32240f1b89021587858168cbe7b3ea7ad07807728655eae0a9907060494a7c99ca","other":"bfef26733f5196a11484bcc28d88776e747189ae7cec883ff39a27cfeee6d9d1efb34560c9f8e75eec43fc069a2ce5f0c78107a36cc8a569d37bd5306aecf23a","up":true},{"one":"fd12c5c96df6ee76dd7beb9e4e4768dda4d2c498851b6435f13ca0175980d0e4a4ff1c002e4daf41a995f118500604764f88496fb9b2c22e28308d8649b525ce","other":"51ba4faf0988717a37dcddc0a60a70ead33bde310184fc450f9ca73c67f931e6767ad5930bcf409e5aeb613a9ff7a03e47de6fc13b33d8af0b87b38822ae6888","up":true},{"one":"ab3814579882e9fd8d464f4f3c8a421be37822ba7f42c5f5e787e81125ec032f9ccf90a138c0b57f0a813b55b583f80d66284f795e2c82d80d2869e1fc770be5","other":"31ac37862416c0e229c4a088ec179f23bdd1bf12dd464eb11c630ad531d7c3438671862e5458e2f6fbb32b857f857e6b8c17e5d93eb29a0e78bb5a65d7eb648c","up":true},{"one":"a05a18161c2d01a0f122548c66509dd1fcf3ee52975035bc79fb059e9613b743a16cd6f5ac54090e68f51bcf76ff21fb3805ba3197a96b4236afb80f791df802","other":"805d784527be4e32e84ddf045baee1ccf348cdf8288de3aae1a5379f762576b957525ef358d9b42c68a93394017880adc09bb2b1b5e01102dc7e4240baf2af95","up":true},{"one":"51302ef7b50922398ad802e917390bb4a3c24c877f2c2bcb7fcb34de9feca22673a2c594639914fe46a28837ffadfd03bb673afbc856aff5e59caf8e76082482","other":"750ca601f07d65f426f6ea5f34e06238f9d7a931f022f9b0ebc811943d3725500cb3c6f00c8d05eb8d5b353c6534136dff38b9a8d3d4dc5bf49cd96875704d07","up":true},{"one":"3c6faa2e75a1699ddadd0e21fd35d3d6215715cfdc2dc89961cfd66773d2541776e785f3ebc833a70e3d1017a4edc571a5d5d9f9fbfc3fa0a8588f6c5023c164","other":"2fdb4382c4bc2950948a8cff13a7df65627bc0b20661cae20fd29acab166c97701594ee3151d75c006ba86d1d68b624b1d1f78e3d1e2fc297844956ef82208a8","up":true},{"one":"fa897ba112f34839064c6871a4c9504c5d709eff5095a137c6a42726d58eb623af976cb96cc30db67e6ac9347c769f032aa4ebda884285a057059040c008ad3e","other":"e59940a6dfe35a6214e2e3daba9ad94e630004cd8f029e13a6649a56dc528ff94bc09d8d21a2f14a56b4ff759b60ebf3d27c1029862c183b8416fa3e950bdb55","up":true},{"one":"7a509686ebce91778fe22e834a94ab03f92457d41385099ba657fe62c7469a9669bddb9a3d7b0150efa1d2f40c69bc786c7f4ede1cf8b19411eea1d23cb7d56c","other":"9e6c1c6e871638182c4b54ac89352ef5c2bca0a99424a1369013e7c182883da0e8d7ab96b3c8254c31fa315b941d8ddee153157626821fc78c2cae951c1c9053","up":true},{"one":"c93cb2df7ba6de8009872f5f7565891040d42e3b193ef1cdb321a0c167cc8fb8138900982bb8f6918fbaefac6e02dda01ee40f7a6beba1990dd44abe03cc3d01","other":"3274b5f48e6929e2305e980b558a4ca3c7cf800b75a6445ea2875cb379e127f3e793e9450a11e927682aa91b8af52e9560dece633833e0f207a8a8a38b7b9c54","up":true},{"one":"665c3288c14dc1c17d85d17d634910f42183482c7e77c47e68f9b4f475b93e8c152246b9e34781606315ff6ef0f8360342500d15e4a2d67d9df6b72f30af64a7","other":"ecbdca037cd7892752345b48b4219478b1b334f83ce7140fcc72eb71784436b690ce7a41b03e013cefc19d64a34a20cfef1b9e2b535d938bcdcb39fe63645a42","up":true},{"one":"82a774be7146766585d2bec6b69b7803aa956f492a53d8ed5f071becdbbc617562885d8430f0afd505210aab7b032428fbea32c82dffbd12d9ccba776ef4729b","other":"03d2d77c008b5fa1063b1abc3152b879a529fe4fdb2dc174d6d85312264a38ee4cc49b342507a10fff1a4b0730f1ef8e008b0897d97bfd6f70050adb124d3596","up":true},{"one":"816e91fa8ff68ba067a89390ef61e7f23211e5e05049daa103ad1ff84b94fbcf535a6f6b515fb571939f5656869767c608513808800baba7e5d2b5f3a17a9691","other":"28afc20d8f4779b285bb14870062dbb54796ec77623302e51bc1bafed9e2c35751c8469ffc482718e059875dfa2226195ed10999e251498cba3a444896cb67db","up":true},{"one":"77327983685f39f006806170fe351063a58ff1bd8dedc222d538e86cfd18abdfefd548328f25fc5afde8170aa5c35311353019468f2b439c331837ddfbb25a52","other":"a6ca1d5340f2d7021f541c81cf9aea519675462c8443bb6ddd93919962561b8f5a8431c3ec7e7e7d46c600b653e9a0638d2bb07cf4e29516bf9c4d3653f451b0","up":true},{"one":"a40391285d1a97f1fb368b20c8e4d02be1bdebc0db41f00f99aac2f01893dc12256cd5a711117a981fbb3f9dfea18c19cf3603e925dbd67c4032b22b41eab8d5","other":"03d2d77c008b5fa1063b1abc3152b879a529fe4fdb2dc174d6d85312264a38ee4cc49b342507a10fff1a4b0730f1ef8e008b0897d97bfd6f70050adb124d3596","up":true},{"one":"33e3ab7108ced43102003c3b3192b194100f32b6bcb67bb772ea9696e35721196699cf01e443f7cdf8076ad83aaf7468b75c71d03efb95f4c07cf0742ea9af81","other":"03d2d77c008b5fa1063b1abc3152b879a529fe4fdb2dc174d6d85312264a38ee4cc49b342507a10fff1a4b0730f1ef8e008b0897d97bfd6f70050adb124d3596","up":true},{"one":"1480f62d85ea32226d9f77ccd31780b3e704fb60618a588ae85dcd1c0e84e878c5fc092adfb306e8ebc7abba9ec429cb2447754502ef847cf931467f31fa50b2","other":"2d6d55edd34c0d9a0130b4806e409bbe18cdda5c2b221cf46136718ec20ffc9d8e92838d78aff92fbcc85f5d081da361dd1e3d7f3d4e1ea57877d6bb7aa0b6f7","up":true},{"one":"cdd86dea7dde96ff7cc1e3248fd17d107c83f2cc7ce2111c41530448962763309e91a05b5dad4663d0e02db59ed4129ab0c3e1eedc42c654e39d29f99038063b","other":"da3e0fd71eb96ba2cab7f920d32f5425d1aad41d00765fdffb0b215d9dd5b60e2bc5929eafebee5b2b5a11aec164e141beff19d828aac7d1fabd3ffb0bfb8450","up":true},{"one":"e7bb63c5187ee85d965fed5cb33d1678c0e090b4e4c3f3d859755565db18046cb60025453bdebf136373c416a2e6e56be063bca6c9257b7b175dcf966e274205","other":"ecbdca037cd7892752345b48b4219478b1b334f83ce7140fcc72eb71784436b690ce7a41b03e013cefc19d64a34a20cfef1b9e2b535d938bcdcb39fe63645a42","up":true},{"one":"545850cb90787d49c579b1ed54a753ebd00eaafe3f1bd04d57266e4912fb1cdd654446ef054a973a583ce8dfc6cc130b6f90e63bcf75372fc21c445f8e1e6005","other":"57bfbde13c71e035c96513870aa8215198f78806e7cdb01c54fbdb392de2c40386d768d6fdc4c68534a67e531867ca74d8ca4dcf34ff7f7f64ec35edee3e5f68","up":true},{"one":"a58a2dd3f5ee2471f0ddd555ffcc45d86e2d8c325585e3fe55eee878b8a626faccce73679d32811fc5d068c153e671673f4cd020f3c7fb37bc6fd9646931646a","other":"a6ca1d5340f2d7021f541c81cf9aea519675462c8443bb6ddd93919962561b8f5a8431c3ec7e7e7d46c600b653e9a0638d2bb07cf4e29516bf9c4d3653f451b0","up":true},{"one":"b2bea653b6ec9629c6f934be72fccf30acf836698e21e81dd8085f070ba8259ba43eee43c342738a4b782f5fbddd44caa28f56dffc08237ca7567c965ac3beca","other":"31ac37862416c0e229c4a088ec179f23bdd1bf12dd464eb11c630ad531d7c3438671862e5458e2f6fbb32b857f857e6b8c17e5d93eb29a0e78bb5a65d7eb648c","up":true},{"one":"5771bef7f50439f9b81d2a7bf7060b1ad4b38675d8f6abbac3cc4c215fb0cb5dd07f6873545b42218337556925566025476e2915b7b98e662a3dcd28bebf0eb4","other":"670949178a5fad22da03af1e206c814a797c0e9eb4e3371f83612f121e5b56e767706a3ae36628cd0c86dd7bd1586ca4df57e2de27b28a31284ecf9176d330e5","up":true},{"one":"f2ea93f43be9d0c3fa21f1496dc13c778977a6afdcba24c8b146de7dca2cdde62a5b792aab969e5b4b6c56f63066b336580d911f206049cc24cac32a25fc4306","other":"86b84ddf64d301f6a9c4504c59eb4031d3167fb74101abea3b694845a009dc522be7b2e2720097ceea9f36058e160f42a2a438a33034929a5c1a7793c7ccef7b","up":true},{"one":"0e8c1a6b70524c4fdc492c74348bac4ccd5d140bd41352607e8cfba45561afb1e6e12f3e2fcf03c1778c9ae5ae19cb9218ee2d613983768f54e3f54e69bb6600","other":"340420ee18d55913f790d0fcc2305b40b1e7bef2eddb79dda57801690aeeead693ebd1a9ff8557671f5ae136b3e65733306924bd00444cbc6e7c6235e5a2c77f","up":true},{"one":"8f625a4e4f4fd980c796d3aa535e58a39722492480cf6982d43fab02de63a5b4c1b5c7cd8402171dd792bb5d9c3e2bdd38176c061dbe3e5b0592af1339e3fd82","other":"03d2d77c008b5fa1063b1abc3152b879a529fe4fdb2dc174d6d85312264a38ee4cc49b342507a10fff1a4b0730f1ef8e008b0897d97bfd6f70050adb124d3596","up":true},{"one":"cbed12dcab0aa04a96ec7e25bc2ee03b337c7b2006391baa7d2aff042c17ec70b82c5fb2dc916d085a7948541719d329f9b528b67ec6adb1ac2cc594d4ef1e42","other":"e9f7e58fda4b504275441d51929fbc98214abdc9ed552c7aa94c600a85d4e791d60c032304b29ae028adccec94984fc9a3d705a81462632f50ef45024eb0f64e","up":true},{"one":"57bfbde13c71e035c96513870aa8215198f78806e7cdb01c54fbdb392de2c40386d768d6fdc4c68534a67e531867ca74d8ca4dcf34ff7f7f64ec35edee3e5f68","other":"ce1309c8505b446363ae37cd3b1ee3e03ced537bed20aca5d8c4be2133917c408845ef5d0f65876974be2803dfb824827cf5c5a2d050d6ef26cdabcbf3a2dc31","up":true},{"one":"06472c89def07fa73188d253cf1acddc2be984842f3a234edb3db95449ba74928ab1395eca1b8978987769863afffb488fc27c9ac723aa24837b66c12f38d735","other":"f6a07a1d361a4671e997d5eaadae61736291aff3896cb69f06bbc19bf7536dd152e0b15422b2fd9f8a9d2f9a251c9a07d0140319900e2cc9f25a59025c7dc91f","up":true},{"one":"1e0a46ff50fb6d9a2c218a851763ff86c42e4d61dddffb7188481febc0f3180bc8f31973d336b2a6e25802acd4fed6d905d89c6d4d7d8080fb12741f9c5ab7e6","other":"e7bb63c5187ee85d965fed5cb33d1678c0e090b4e4c3f3d859755565db18046cb60025453bdebf136373c416a2e6e56be063bca6c9257b7b175dcf966e274205","up":true},{"one":"5d96577324edf1b5a1626999925982af1e0ba7bed8edcc3f740ba434f4b003cbbe2d632cad327c76e5b490d08c091c4a7b473353ab59139493657eb9525b8be2","other":"d90a81a583c82d626b92f27244f027da4a0ae76e6d3bdc1de0af7be01798f1fb04b34ce60c6d8651a39d7a70915438a4aa63e5adf844a9f7e38dbf0b1dba754d","up":true},{"one":"49eb706cd7e95ad78502a508487d88b818861d94334aee36b2acef5c25cfff5c0efc2df9dc5dbb18acd4003d5cc0c843d3b40363adf2f62a14c04d814268fdee","other":"0e8c1a6b70524c4fdc492c74348bac4ccd5d140bd41352607e8cfba45561afb1e6e12f3e2fcf03c1778c9ae5ae19cb9218ee2d613983768f54e3f54e69bb6600","up":true},{"one":"d8cfadac10473b31a4560c711636a05615f13054388065344642ff1d04246fb62eafeec06805264eafead111ed8134e11a8e21f42a0eb950c23b142e627bd8cb","other":"872cdbb6d74fb55fd2d51877ef7804bdd2eeb6de0297eb2ce18b67e52379b147d54a46d2385ec9293eb21736bed4191d92c5c75e8e81fc5a6c691970e019f570","up":true},{"one":"20f171ab01a814a2856a6cbe7929269f18f6329914289515e2cb9d078ac14ebdae457789dd638c6415b062799114570f556147d4bf9ac850f00b6d0762765ac1","other":"e9f7e58fda4b504275441d51929fbc98214abdc9ed552c7aa94c600a85d4e791d60c032304b29ae028adccec94984fc9a3d705a81462632f50ef45024eb0f64e","up":true},{"one":"896c74ca4cc4cbb9d2b6606d0ebfd6427952c2e16aedbf36933fa3d01f1c505fcd663f3d01c0cf096bef9cfd0bae4595ec7c221cfc362e19a5b7c60614a9658b","other":"08900197e74e285a5a8a9cc53fbd420bb35043ab27eb2d9eab22615e736a093abfa235c17f667dcc791cb50b9022082eafd9fba030194cc84f0358b769adc85b","up":true},{"one":"03e478a3aae82e06e215e40272a420037a61442d11c49c367a5ee6a21868d29a17ea8b9284f013d020c4740f296a6a22bc64d33d1c2807f9ab8dc48c0cfec18a","other":"f04c3ae9fe957a14c249acf3ea2e8407d04d108fc01e75f6d52aaf5073b3450025012d138a75b857473eea4d20e57c99b92bff9041f269d995543d7c67a92ec6","up":true},{"one":"87e696a354d249493217dc4e0190082f30e09616873803efa376871d4b34f86f0eeb4643d4822d8a0fbcdedb27cd6ba5438e98943d358d960c4835e82261c93e","other":"f2ea93f43be9d0c3fa21f1496dc13c778977a6afdcba24c8b146de7dca2cdde62a5b792aab969e5b4b6c56f63066b336580d911f206049cc24cac32a25fc4306","up":true},{"one":"87fce129511a1be2777052d24b606acdfe7067f4e874ab04674a68664b378ea208975f7269a72af889d3d23cd930b6a181afa2cdef3f9f9491f715bd96ad8dc0","other":"da3e0fd71eb96ba2cab7f920d32f5425d1aad41d00765fdffb0b215d9dd5b60e2bc5929eafebee5b2b5a11aec164e141beff19d828aac7d1fabd3ffb0bfb8450","up":true},{"one":"9e6c1c6e871638182c4b54ac89352ef5c2bca0a99424a1369013e7c182883da0e8d7ab96b3c8254c31fa315b941d8ddee153157626821fc78c2cae951c1c9053","other":"93987e431a0058f2e942ccf8d3486d249cd2734d6494131b343e2c3a8fdd86cfcb12d0aaaf8fcb911ad3cdd682cc82118198195a7fdc915ab7853223f012eab6","up":true},{"one":"622646c74fdbae39ba191dbafff4906fb683fe0b0f2c303d080f5577a070876c41c8d3786ae7b953e5f682b8ec647727550d47302229ebb9f82bed24cea61132","other":"b09af9e5552e72f918174963dad58a4492d3afa120f78e43820df7bff7fae9f6b52bc6c8c73d3a9af91d20134f4ff1b037db2ef0bc3d8c495a771d63de678bc0","up":true},{"one":"3572a22097a313b3adef95a7b6cc679f8d1201a156d764e61a9fbc63d123fb4826f7125402fb6569beed359e1c1e5e6cb6993a75975da6cd4ce15669a2eea758","other":"44462055ba68fdef337dd19d8123aace9a12284c13bc97687416b6b4ca0c94234ba7db6823651fc021d6ac1539e0c5321e763a7a12c9e7c8a583aac5369817d8","up":true},{"one":"3df030a522a157e36f6b369aab048b9287792743a411a47073c4f9ef7686528f39bf7bf91c48e4d46afe180c8d08430b012bd216d50876baa3b1e7bc17cb55ef","other":"da3e0fd71eb96ba2cab7f920d32f5425d1aad41d00765fdffb0b215d9dd5b60e2bc5929eafebee5b2b5a11aec164e141beff19d828aac7d1fabd3ffb0bfb8450","up":true},{"one":"3274b5f48e6929e2305e980b558a4ca3c7cf800b75a6445ea2875cb379e127f3e793e9450a11e927682aa91b8af52e9560dece633833e0f207a8a8a38b7b9c54","other":"077d2d032874e5ce70e9b928b7fe72c0326ba92394e16245e31d48b5731d3d32bfd86acf40825decff54bcd735e9ebfd94eba677c418ea7007baec9db4af676d","up":true},{"one":"5984a296b49bfba30315501ce2ae88ed0392ab2959ac4e7e6b9a29090f344b9dd13873ca137e8317c402cd2e14a61965d5707065b8ded46c41a054731933719f","other":"c93cb2df7ba6de8009872f5f7565891040d42e3b193ef1cdb321a0c167cc8fb8138900982bb8f6918fbaefac6e02dda01ee40f7a6beba1990dd44abe03cc3d01","up":true},{"one":"08900197e74e285a5a8a9cc53fbd420bb35043ab27eb2d9eab22615e736a093abfa235c17f667dcc791cb50b9022082eafd9fba030194cc84f0358b769adc85b","other":"f2ea93f43be9d0c3fa21f1496dc13c778977a6afdcba24c8b146de7dca2cdde62a5b792aab969e5b4b6c56f63066b336580d911f206049cc24cac32a25fc4306","up":true},{"one":"a9e0b763852706722dc904b494293f9399c0fa32255890aa720285b8160335bb618f36b68a81b875a805384179f600defef474d486b4ea04b003ef6477ab7907","other":"77327983685f39f006806170fe351063a58ff1bd8dedc222d538e86cfd18abdfefd548328f25fc5afde8170aa5c35311353019468f2b439c331837ddfbb25a52","up":true},{"one":"3103510e00a3f49a5e715719049fc8c9c67a2373a548f326458aeb6d9c75ed92b94373638fd075def0209113b4e85d972c23f064539f7b041596184e40d7f9a2","other":"e3f2e777a96b2137b3104b84d5d827d484eac9ee1b585430e09f790d7e26978da12802325927c3c483bc19973e09cd3f70c513c34798e5da650f8d2f0c8c5c47","up":true},{"one":"ce1309c8505b446363ae37cd3b1ee3e03ced537bed20aca5d8c4be2133917c408845ef5d0f65876974be2803dfb824827cf5c5a2d050d6ef26cdabcbf3a2dc31","other":"545850cb90787d49c579b1ed54a753ebd00eaafe3f1bd04d57266e4912fb1cdd654446ef054a973a583ce8dfc6cc130b6f90e63bcf75372fc21c445f8e1e6005","up":true},{"one":"188bf77c9c1e45f009efe7aefdb040bdb47763980fe7eb0851295d657fa2a8978efbd2997c1dc30f4f0874eecf9ca9550487cf41da237b84d071963d35b6baff","other":"545850cb90787d49c579b1ed54a753ebd00eaafe3f1bd04d57266e4912fb1cdd654446ef054a973a583ce8dfc6cc130b6f90e63bcf75372fc21c445f8e1e6005","up":true},{"one":"e0420ba2a293315d810928a0e09a507c6aaf93977ba2c7598e9b83723b4a66682398ea17542c26767c7ff0f4ca09c537d3cc10dad283f079f1de73e25e87cb5c","other":"03e478a3aae82e06e215e40272a420037a61442d11c49c367a5ee6a21868d29a17ea8b9284f013d020c4740f296a6a22bc64d33d1c2807f9ab8dc48c0cfec18a","up":true},{"one":"489660042a8867d90a16ebb013968db26ca3edfc70f53320f511e35b3703eed09fbd787be5c06726a570a54aa15d129cd10db741523adf297929f909be4a0c71","other":"6ce3a68cb1e2924ad97f22006094c709a3dd8b4ca1546fbb037f841a9e5ac62def242015dbf6221bda610153db064edcbb58a78a35a06077b8c02bf5b2a33c04","up":true},{"one":"e3f2e777a96b2137b3104b84d5d827d484eac9ee1b585430e09f790d7e26978da12802325927c3c483bc19973e09cd3f70c513c34798e5da650f8d2f0c8c5c47","other":"31ac37862416c0e229c4a088ec179f23bdd1bf12dd464eb11c630ad531d7c3438671862e5458e2f6fbb32b857f857e6b8c17e5d93eb29a0e78bb5a65d7eb648c","up":true},{"one":"f06ec3a90d34300f9fa2d48aea0c6b5f2f01f7833ffb0fad30e7f57e3916e344f3a4f9efe38e222443b8b00d3c7f5221c672491a129e4958e574afc283bd45b1","other":"2fdb4382c4bc2950948a8cff13a7df65627bc0b20661cae20fd29acab166c97701594ee3151d75c006ba86d1d68b624b1d1f78e3d1e2fc297844956ef82208a8","up":true},{"one":"3540d888c3207d6df233afd1164ff9dde2551730862772547e04f7311de364968e113f38a7dea1ab0916a7f8307017de5b49578fa4ebcc39651e541fde51be48","other":"03d2d77c008b5fa1063b1abc3152b879a529fe4fdb2dc174d6d85312264a38ee4cc49b342507a10fff1a4b0730f1ef8e008b0897d97bfd6f70050adb124d3596","up":true},{"one":"26cf4ea45b9a76daab82a57126f9c6f8726d2eb973e205ab4ab69c8b8be11a32a7eb5c3807e952cd428ce5ddd88f143d4fc9ff8c3de3d159855675afce715615","other":"f04c3ae9fe957a14c249acf3ea2e8407d04d108fc01e75f6d52aaf5073b3450025012d138a75b857473eea4d20e57c99b92bff9041f269d995543d7c67a92ec6","up":true},{"one":"e9f7e58fda4b504275441d51929fbc98214abdc9ed552c7aa94c600a85d4e791d60c032304b29ae028adccec94984fc9a3d705a81462632f50ef45024eb0f64e","other":"bfef26733f5196a11484bcc28d88776e747189ae7cec883ff39a27cfeee6d9d1efb34560c9f8e75eec43fc069a2ce5f0c78107a36cc8a569d37bd5306aecf23a","up":true},{"one":"340420ee18d55913f790d0fcc2305b40b1e7bef2eddb79dda57801690aeeead693ebd1a9ff8557671f5ae136b3e65733306924bd00444cbc6e7c6235e5a2c77f","other":"7a18392b8338108a996196ee190a93a1b9954c8e05a062c421da513a1828dfa739e7b224878c0670cf74bbc743c7ca7ee8cfee6b6a602fe1f4a82ecfbd38c2f4","up":true},{"one":"73be4d2291c68ca4554a86fa170f7595210e1b6bbbeef3c1d5623a2b5d03a8fd6e26caa26afc639c20c8a351a89dad1086f91734f09afab62d28ec17b700fa01","other":"805d784527be4e32e84ddf045baee1ccf348cdf8288de3aae1a5379f762576b957525ef358d9b42c68a93394017880adc09bb2b1b5e01102dc7e4240baf2af95","up":true},{"one":"077bcadade93e0d361e94f76dff464d61912bc067ce2ce17ebcabd757cca201cd64624ea809d99dd8ecb749d40528db9b3eb503ef5ec05e8845044cfaef720dc","other":"a40391285d1a97f1fb368b20c8e4d02be1bdebc0db41f00f99aac2f01893dc12256cd5a711117a981fbb3f9dfea18c19cf3603e925dbd67c4032b22b41eab8d5","up":true},{"one":"155805f787600f9f9518cf8836f491885b64868bfe0023975bcd12776925a424fb5aa3199dc178e83294e97f347a373d05d2422578a08eeeb2d15a178d28964f","other":"77327983685f39f006806170fe351063a58ff1bd8dedc222d538e86cfd18abdfefd548328f25fc5afde8170aa5c35311353019468f2b439c331837ddfbb25a52","up":true},{"one":"a40391285d1a97f1fb368b20c8e4d02be1bdebc0db41f00f99aac2f01893dc12256cd5a711117a981fbb3f9dfea18c19cf3603e925dbd67c4032b22b41eab8d5","other":"e9f7e58fda4b504275441d51929fbc98214abdc9ed552c7aa94c600a85d4e791d60c032304b29ae028adccec94984fc9a3d705a81462632f50ef45024eb0f64e","up":true},{"one":"41994605708232b4ca7448c3bc0760a7b86bf26d442091e5ce6e92eac94925721d7e0eca04bdd03bb1bba1ef92deeccd4bf1b7c6c3318b7e8d031965c6646761","other":"077bcadade93e0d361e94f76dff464d61912bc067ce2ce17ebcabd757cca201cd64624ea809d99dd8ecb749d40528db9b3eb503ef5ec05e8845044cfaef720dc","up":true},{"one":"cd0e9a45b45f9a67417fcde29d9f92c45ca4db46eebbfe47dcf6999e23e549e4205f42ada8e3fcd00e2fb5f832bb92a27a59b43c4a5909148d81399c2e8ce492","other":"57bfbde13c71e035c96513870aa8215198f78806e7cdb01c54fbdb392de2c40386d768d6fdc4c68534a67e531867ca74d8ca4dcf34ff7f7f64ec35edee3e5f68","up":true},{"one":"b38213eaa5b419de787b70073ad8c7c819e48c5f76dec1507b54f1d7cb027211facbe7a170ac50212abe130935e8947d5a19d6b13790114e71cc18357902a889","other":"c93cb2df7ba6de8009872f5f7565891040d42e3b193ef1cdb321a0c167cc8fb8138900982bb8f6918fbaefac6e02dda01ee40f7a6beba1990dd44abe03cc3d01","up":true},{"one":"a1b2d0c6f24f5924c61e057fc65b994d9a6755560d740018b4c9ad0bb69212ec69974e22cb037dfeb7ea90a4493997f4c94029870bcc5fd47013b51ca0a26b5d","other":"9c6dcfef0e128dbfeca58b8ac625b08fb447b0d579bd3f18bc0e2be60d1ec2274595d0554ddba0ca7eb660099d3ea146d8076792b46c93841d2ecf8cf608f5ba","up":true},{"one":"56e8f792ec9a75ec9e91d472b8a4b023655dd68c2a448a33397b125fe3584a5efa1b492e47077b24acfe0396b73e1cb564a6a6b2aee1b457781dfaf6d43fcaed","other":"73319a301ad3cf0ec09549d817c9523d61b74abb0cad87b737d41d900321e52722a84355f6f87bc7a5f848818c89a021bb0f3e5994f67c9a7b5bbfc98188a376","up":true},{"one":"5b4de68680c5d1a75cccd5e7a82319c031f5d61d79cbb6532e1254ab81c833c3fafb54390cca7a770e84690c490fcba90482b35321870f8506335a2f57cc052e","other":"a6ca1d5340f2d7021f541c81cf9aea519675462c8443bb6ddd93919962561b8f5a8431c3ec7e7e7d46c600b653e9a0638d2bb07cf4e29516bf9c4d3653f451b0","up":true},{"one":"e59940a6dfe35a6214e2e3daba9ad94e630004cd8f029e13a6649a56dc528ff94bc09d8d21a2f14a56b4ff759b60ebf3d27c1029862c183b8416fa3e950bdb55","other":"a1b2d0c6f24f5924c61e057fc65b994d9a6755560d740018b4c9ad0bb69212ec69974e22cb037dfeb7ea90a4493997f4c94029870bcc5fd47013b51ca0a26b5d","up":true},{"one":"da15d60a4b9a8816ce24c20f6c941c51229c1fb5e070b8b29be2977c2f7b41f8f17e4b6efe75f465e7935ded1ba17472f046eac73393db7197018fa86d11c31f","other":"3e7820bb15c07f515bd63791b66136723dcc9878b3145fe0f238f6b41e3f2f7565ae55ef24f08ae461950ce1ae0c8a80fe5e4fd4f2f88c4acf4a2c94640df239","up":true},{"one":"562119edffe8270f6f7a5ad9b13d4c65d643e52a2331d1fee16f7e9b5567f44cfea62df3e8965a22cf08db8fa918f0a0bcae8da2936677e6d25bc88ed85ed2f1","other":"896c74ca4cc4cbb9d2b6606d0ebfd6427952c2e16aedbf36933fa3d01f1c505fcd663f3d01c0cf096bef9cfd0bae4595ec7c221cfc362e19a5b7c60614a9658b","up":true},{"one":"59730132a01ba848a3c050bb6234bca9a72deba33716960fc3ec89b186bfcd313b9bbf049939d5805ff98db2c53a9421ce6ec97d8b4cdbaea53ba264d80d0734","other":"340420ee18d55913f790d0fcc2305b40b1e7bef2eddb79dda57801690aeeead693ebd1a9ff8557671f5ae136b3e65733306924bd00444cbc6e7c6235e5a2c77f","up":true},{"one":"f7637cdd5ef26de40b9055c1df91a45725670c8df11ae934c0d99d2547c3eb4c42a16dbb2e75bcaf4b1b9347c48db65f549a0623179a08dd8cbad92f5bca08cf","other":"3c6faa2e75a1699ddadd0e21fd35d3d6215715cfdc2dc89961cfd66773d2541776e785f3ebc833a70e3d1017a4edc571a5d5d9f9fbfc3fa0a8588f6c5023c164","up":true},{"one":"bfef26733f5196a11484bcc28d88776e747189ae7cec883ff39a27cfeee6d9d1efb34560c9f8e75eec43fc069a2ce5f0c78107a36cc8a569d37bd5306aecf23a","other":"41994605708232b4ca7448c3bc0760a7b86bf26d442091e5ce6e92eac94925721d7e0eca04bdd03bb1bba1ef92deeccd4bf1b7c6c3318b7e8d031965c6646761","up":true},{"one":"c773af3af01ee8ab9fa8d06987baf4f10c394fdd386d69b7a7362f4b68fd6fc082337d3b33a19d584c5801a3e9198225d7b61f6629e34ce823be70908339f4c7","other":"d90a81a583c82d626b92f27244f027da4a0ae76e6d3bdc1de0af7be01798f1fb04b34ce60c6d8651a39d7a70915438a4aa63e5adf844a9f7e38dbf0b1dba754d","up":true},{"one":"afb5754b4748b7ac5628e32b242c90aab0e2fc7da58d8d5c8c775d13d8a6fd32240f1b89021587858168cbe7b3ea7ad07807728655eae0a9907060494a7c99ca","other":"c93cb2df7ba6de8009872f5f7565891040d42e3b193ef1cdb321a0c167cc8fb8138900982bb8f6918fbaefac6e02dda01ee40f7a6beba1990dd44abe03cc3d01","up":true},{"one":"56b25623ac935f3a8aac1e2603a6bd15ace1e5714671954b47f2cab960cf47922828f415105602408d0a732a893ebeea6f9afab7f889bb235c81589548d09391","other":"489660042a8867d90a16ebb013968db26ca3edfc70f53320f511e35b3703eed09fbd787be5c06726a570a54aa15d129cd10db741523adf297929f909be4a0c71","up":true},{"one":"87e696a354d249493217dc4e0190082f30e09616873803efa376871d4b34f86f0eeb4643d4822d8a0fbcdedb27cd6ba5438e98943d358d960c4835e82261c93e","other":"51ba4faf0988717a37dcddc0a60a70ead33bde310184fc450f9ca73c67f931e6767ad5930bcf409e5aeb613a9ff7a03e47de6fc13b33d8af0b87b38822ae6888","up":true},{"one":"2d6d55edd34c0d9a0130b4806e409bbe18cdda5c2b221cf46136718ec20ffc9d8e92838d78aff92fbcc85f5d081da361dd1e3d7f3d4e1ea57877d6bb7aa0b6f7","other":"8e8de10fb3f53bd3a48455ebfa0a38ea5bd28c607e65506b263ece53a24d2361c2af7d7cd207e45b11bf71a3c33fa325fc8fd40a18b9c73019cce219c757c7ef","up":true},{"one":"9c6dcfef0e128dbfeca58b8ac625b08fb447b0d579bd3f18bc0e2be60d1ec2274595d0554ddba0ca7eb660099d3ea146d8076792b46c93841d2ecf8cf608f5ba","other":"f0299035cbddfdf7a78e5e3a400aaedf2d719d04e907ac0f9f067525e2f9bb913d985308a3a0d05467a64adf58c68a615c6327acf716c23631d0e829903f8b34","up":true},{"one":"872cdbb6d74fb55fd2d51877ef7804bdd2eeb6de0297eb2ce18b67e52379b147d54a46d2385ec9293eb21736bed4191d92c5c75e8e81fc5a6c691970e019f570","other":"caad8529d498a4a1e1ba7573689a913500bd409345ef8e3656abca748269eb73b919282f7f2eb0087f81f7bc52c367657ac8be0cdac65d2490c7c50c874444b7","up":true},{"one":"4de606aa7e722197b918c5f7f0db86a3081d48e89d21428b04f19c3ff3755eac0bddbff5fad8bda94b9e57f58fba2fecdbabbf710f7afb381bf4f1a4fe55cd93","other":"f0299035cbddfdf7a78e5e3a400aaedf2d719d04e907ac0f9f067525e2f9bb913d985308a3a0d05467a64adf58c68a615c6327acf716c23631d0e829903f8b34","up":true},{"one":"9c6dcfef0e128dbfeca58b8ac625b08fb447b0d579bd3f18bc0e2be60d1ec2274595d0554ddba0ca7eb660099d3ea146d8076792b46c93841d2ecf8cf608f5ba","other":"340420ee18d55913f790d0fcc2305b40b1e7bef2eddb79dda57801690aeeead693ebd1a9ff8557671f5ae136b3e65733306924bd00444cbc6e7c6235e5a2c77f","up":true},{"one":"51302ef7b50922398ad802e917390bb4a3c24c877f2c2bcb7fcb34de9feca22673a2c594639914fe46a28837ffadfd03bb673afbc856aff5e59caf8e76082482","other":"077d2d032874e5ce70e9b928b7fe72c0326ba92394e16245e31d48b5731d3d32bfd86acf40825decff54bcd735e9ebfd94eba677c418ea7007baec9db4af676d","up":true},{"one":"077d2d032874e5ce70e9b928b7fe72c0326ba92394e16245e31d48b5731d3d32bfd86acf40825decff54bcd735e9ebfd94eba677c418ea7007baec9db4af676d","other":"f04c3ae9fe957a14c249acf3ea2e8407d04d108fc01e75f6d52aaf5073b3450025012d138a75b857473eea4d20e57c99b92bff9041f269d995543d7c67a92ec6","up":true},{"one":"7a509686ebce91778fe22e834a94ab03f92457d41385099ba657fe62c7469a9669bddb9a3d7b0150efa1d2f40c69bc786c7f4ede1cf8b19411eea1d23cb7d56c","other":"3540d888c3207d6df233afd1164ff9dde2551730862772547e04f7311de364968e113f38a7dea1ab0916a7f8307017de5b49578fa4ebcc39651e541fde51be48","up":true},{"one":"816e91fa8ff68ba067a89390ef61e7f23211e5e05049daa103ad1ff84b94fbcf535a6f6b515fb571939f5656869767c608513808800baba7e5d2b5f3a17a9691","other":"fd12c5c96df6ee76dd7beb9e4e4768dda4d2c498851b6435f13ca0175980d0e4a4ff1c002e4daf41a995f118500604764f88496fb9b2c22e28308d8649b525ce","up":true},{"one":"e0420ba2a293315d810928a0e09a507c6aaf93977ba2c7598e9b83723b4a66682398ea17542c26767c7ff0f4ca09c537d3cc10dad283f079f1de73e25e87cb5c","other":"f0299035cbddfdf7a78e5e3a400aaedf2d719d04e907ac0f9f067525e2f9bb913d985308a3a0d05467a64adf58c68a615c6327acf716c23631d0e829903f8b34","up":true},{"one":"77327983685f39f006806170fe351063a58ff1bd8dedc222d538e86cfd18abdfefd548328f25fc5afde8170aa5c35311353019468f2b439c331837ddfbb25a52","other":"e9f7e58fda4b504275441d51929fbc98214abdc9ed552c7aa94c600a85d4e791d60c032304b29ae028adccec94984fc9a3d705a81462632f50ef45024eb0f64e","up":true},{"one":"f06ec3a90d34300f9fa2d48aea0c6b5f2f01f7833ffb0fad30e7f57e3916e344f3a4f9efe38e222443b8b00d3c7f5221c672491a129e4958e574afc283bd45b1","other":"44462055ba68fdef337dd19d8123aace9a12284c13bc97687416b6b4ca0c94234ba7db6823651fc021d6ac1539e0c5321e763a7a12c9e7c8a583aac5369817d8","up":true},{"one":"e7bb63c5187ee85d965fed5cb33d1678c0e090b4e4c3f3d859755565db18046cb60025453bdebf136373c416a2e6e56be063bca6c9257b7b175dcf966e274205","other":"a5cdff211813e17fadd43ec55a6cf4e97e6ca0c3b2cef0db58923b27d36207fd1a77146efb6093bd94d7eb89cc77d8c735fc64ab098839efc74a00b5e8687555","up":true},{"one":"545850cb90787d49c579b1ed54a753ebd00eaafe3f1bd04d57266e4912fb1cdd654446ef054a973a583ce8dfc6cc130b6f90e63bcf75372fc21c445f8e1e6005","other":"f7637cdd5ef26de40b9055c1df91a45725670c8df11ae934c0d99d2547c3eb4c42a16dbb2e75bcaf4b1b9347c48db65f549a0623179a08dd8cbad92f5bca08cf","up":true},{"one":"b2bea653b6ec9629c6f934be72fccf30acf836698e21e81dd8085f070ba8259ba43eee43c342738a4b782f5fbddd44caa28f56dffc08237ca7567c965ac3beca","other":"cdd86dea7dde96ff7cc1e3248fd17d107c83f2cc7ce2111c41530448962763309e91a05b5dad4663d0e02db59ed4129ab0c3e1eedc42c654e39d29f99038063b","up":true},{"one":"5771bef7f50439f9b81d2a7bf7060b1ad4b38675d8f6abbac3cc4c215fb0cb5dd07f6873545b42218337556925566025476e2915b7b98e662a3dcd28bebf0eb4","other":"27fb8fcda1986644f985d68430c399f0299644b00b234c355362721081d12f9eb7686eea8f92eabda1d342bf56255e51c07b200c6233f95ac009f15b874eee97","up":true},{"one":"a58a2dd3f5ee2471f0ddd555ffcc45d86e2d8c325585e3fe55eee878b8a626faccce73679d32811fc5d068c153e671673f4cd020f3c7fb37bc6fd9646931646a","other":"a9e0b763852706722dc904b494293f9399c0fa32255890aa720285b8160335bb618f36b68a81b875a805384179f600defef474d486b4ea04b003ef6477ab7907","up":true},{"one":"06472c89def07fa73188d253cf1acddc2be984842f3a234edb3db95449ba74928ab1395eca1b8978987769863afffb488fc27c9ac723aa24837b66c12f38d735","other":"87e696a354d249493217dc4e0190082f30e09616873803efa376871d4b34f86f0eeb4643d4822d8a0fbcdedb27cd6ba5438e98943d358d960c4835e82261c93e","up":true},{"one":"d8cfadac10473b31a4560c711636a05615f13054388065344642ff1d04246fb62eafeec06805264eafead111ed8134e11a8e21f42a0eb950c23b142e627bd8cb","other":"f04c3ae9fe957a14c249acf3ea2e8407d04d108fc01e75f6d52aaf5073b3450025012d138a75b857473eea4d20e57c99b92bff9041f269d995543d7c67a92ec6","up":true},{"one":"09b60de1e85bb6f7d2caf5b1ab58204d7d04531ece300dcd7bcc9157b8b3ef2a182758808a0eec6056034f29f52caadb7c690f498c1c8832ff7a6a9ecff308bd","other":"18bb6572965f4263c5a4d59a73027abc57a46122125ee58d871e95c993e6a1e8230438ce696a5f8880a08749837268b54319f7b0aa254c1a5bd453a8e9bcf84f","up":true},{"one":"3df030a522a157e36f6b369aab048b9287792743a411a47073c4f9ef7686528f39bf7bf91c48e4d46afe180c8d08430b012bd216d50876baa3b1e7bc17cb55ef","other":"a58a2dd3f5ee2471f0ddd555ffcc45d86e2d8c325585e3fe55eee878b8a626faccce73679d32811fc5d068c153e671673f4cd020f3c7fb37bc6fd9646931646a","up":true},{"one":"a9e0b763852706722dc904b494293f9399c0fa32255890aa720285b8160335bb618f36b68a81b875a805384179f600defef474d486b4ea04b003ef6477ab7907","other":"e9f7e58fda4b504275441d51929fbc98214abdc9ed552c7aa94c600a85d4e791d60c032304b29ae028adccec94984fc9a3d705a81462632f50ef45024eb0f64e","up":true},{"one":"cd0e9a45b45f9a67417fcde29d9f92c45ca4db46eebbfe47dcf6999e23e549e4205f42ada8e3fcd00e2fb5f832bb92a27a59b43c4a5909148d81399c2e8ce492","other":"276256790c9317d09ff7802f4ad0a85840fe62527390ce1790e1e3186e8b3f04acfaa41dcd02303d333423678a4037e4f4854676e79ced3232a3dbd772cc2680","up":true},{"one":"3103510e00a3f49a5e715719049fc8c9c67a2373a548f326458aeb6d9c75ed92b94373638fd075def0209113b4e85d972c23f064539f7b041596184e40d7f9a2","other":"ab3814579882e9fd8d464f4f3c8a421be37822ba7f42c5f5e787e81125ec032f9ccf90a138c0b57f0a813b55b583f80d66284f795e2c82d80d2869e1fc770be5","up":true},{"one":"3e7820bb15c07f515bd63791b66136723dcc9878b3145fe0f238f6b41e3f2f7565ae55ef24f08ae461950ce1ae0c8a80fe5e4fd4f2f88c4acf4a2c94640df239","other":"cd0e9a45b45f9a67417fcde29d9f92c45ca4db46eebbfe47dcf6999e23e549e4205f42ada8e3fcd00e2fb5f832bb92a27a59b43c4a5909148d81399c2e8ce492","up":true},{"one":"73319a301ad3cf0ec09549d817c9523d61b74abb0cad87b737d41d900321e52722a84355f6f87bc7a5f848818c89a021bb0f3e5994f67c9a7b5bbfc98188a376","other":"9c6dcfef0e128dbfeca58b8ac625b08fb447b0d579bd3f18bc0e2be60d1ec2274595d0554ddba0ca7eb660099d3ea146d8076792b46c93841d2ecf8cf608f5ba","up":true},{"one":"805d784527be4e32e84ddf045baee1ccf348cdf8288de3aae1a5379f762576b957525ef358d9b42c68a93394017880adc09bb2b1b5e01102dc7e4240baf2af95","other":"49eb706cd7e95ad78502a508487d88b818861d94334aee36b2acef5c25cfff5c0efc2df9dc5dbb18acd4003d5cc0c843d3b40363adf2f62a14c04d814268fdee","up":true},{"one":"51ba4faf0988717a37dcddc0a60a70ead33bde310184fc450f9ca73c67f931e6767ad5930bcf409e5aeb613a9ff7a03e47de6fc13b33d8af0b87b38822ae6888","other":"805d784527be4e32e84ddf045baee1ccf348cdf8288de3aae1a5379f762576b957525ef358d9b42c68a93394017880adc09bb2b1b5e01102dc7e4240baf2af95","up":true},{"one":"1e3c83cabbe6852c987ae521b7fcb33185cf855c59b6235ebb8e57a6f860ccc159ddc01b4a21d251c8faca4559ceb271e046a51493ba148c0d3aed97ad208969","other":"f2ea93f43be9d0c3fa21f1496dc13c778977a6afdcba24c8b146de7dca2cdde62a5b792aab969e5b4b6c56f63066b336580d911f206049cc24cac32a25fc4306","up":true},{"one":"f62bd19b0fd052207743ce53c3d48a3a71e9219b75e41a9497a43e6368e559d5487ff1ab644f2df4106b500583e4344515f73187eec773115deb977b4ebc3514","other":"8e8de10fb3f53bd3a48455ebfa0a38ea5bd28c607e65506b263ece53a24d2361c2af7d7cd207e45b11bf71a3c33fa325fc8fd40a18b9c73019cce219c757c7ef","up":true},{"one":"f6a07a1d361a4671e997d5eaadae61736291aff3896cb69f06bbc19bf7536dd152e0b15422b2fd9f8a9d2f9a251c9a07d0140319900e2cc9f25a59025c7dc91f","other":"93987e431a0058f2e942ccf8d3486d249cd2734d6494131b343e2c3a8fdd86cfcb12d0aaaf8fcb911ad3cdd682cc82118198195a7fdc915ab7853223f012eab6","up":true},{"one":"489660042a8867d90a16ebb013968db26ca3edfc70f53320f511e35b3703eed09fbd787be5c06726a570a54aa15d129cd10db741523adf297929f909be4a0c71","other":"a05a18161c2d01a0f122548c66509dd1fcf3ee52975035bc79fb059e9613b743a16cd6f5ac54090e68f51bcf76ff21fb3805ba3197a96b4236afb80f791df802","up":true},{"one":"e3f2e777a96b2137b3104b84d5d827d484eac9ee1b585430e09f790d7e26978da12802325927c3c483bc19973e09cd3f70c513c34798e5da650f8d2f0c8c5c47","other":"8f625a4e4f4fd980c796d3aa535e58a39722492480cf6982d43fab02de63a5b4c1b5c7cd8402171dd792bb5d9c3e2bdd38176c061dbe3e5b0592af1339e3fd82","up":true},{"one":"20bdc859d58d8bf419df64fd6ee1d4363c1d5f403af3abef2720d7d3933924672e12e23e5d76b28e0f6726acf58bdc5eb258cba635e327cbd0b564523305da75","other":"03d2d77c008b5fa1063b1abc3152b879a529fe4fdb2dc174d6d85312264a38ee4cc49b342507a10fff1a4b0730f1ef8e008b0897d97bfd6f70050adb124d3596","up":true},{"one":"3e9c0bbd146d8b1040b4f379eecf802c27c4d0a70e64a9fb2e941a7edab9b00396b0b67fc5c891652743cdba3b342973ed49615b32da54b925954a799240431c","other":"f6a07a1d361a4671e997d5eaadae61736291aff3896cb69f06bbc19bf7536dd152e0b15422b2fd9f8a9d2f9a251c9a07d0140319900e2cc9f25a59025c7dc91f","up":true},{"one":"eb097186ff58d96a7ead7a7f9c05a44075d84537bd4fd3f82857bf2c45bee1c6dece434a7707cde69e96f02366859cab4c991fdb7615e113a868d4b9c7524a45","other":"f04c3ae9fe957a14c249acf3ea2e8407d04d108fc01e75f6d52aaf5073b3450025012d138a75b857473eea4d20e57c99b92bff9041f269d995543d7c67a92ec6","up":true},{"one":"7a18392b8338108a996196ee190a93a1b9954c8e05a062c421da513a1828dfa739e7b224878c0670cf74bbc743c7ca7ee8cfee6b6a602fe1f4a82ecfbd38c2f4","other":"2d6d55edd34c0d9a0130b4806e409bbe18cdda5c2b221cf46136718ec20ffc9d8e92838d78aff92fbcc85f5d081da361dd1e3d7f3d4e1ea57877d6bb7aa0b6f7","up":true},{"one":"a6ca1d5340f2d7021f541c81cf9aea519675462c8443bb6ddd93919962561b8f5a8431c3ec7e7e7d46c600b653e9a0638d2bb07cf4e29516bf9c4d3653f451b0","other":"f04c3ae9fe957a14c249acf3ea2e8407d04d108fc01e75f6d52aaf5073b3450025012d138a75b857473eea4d20e57c99b92bff9041f269d995543d7c67a92ec6","up":true},{"one":"077bcadade93e0d361e94f76dff464d61912bc067ce2ce17ebcabd757cca201cd64624ea809d99dd8ecb749d40528db9b3eb503ef5ec05e8845044cfaef720dc","other":"750ca601f07d65f426f6ea5f34e06238f9d7a931f022f9b0ebc811943d3725500cb3c6f00c8d05eb8d5b353c6534136dff38b9a8d3d4dc5bf49cd96875704d07","up":true},{"one":"73be4d2291c68ca4554a86fa170f7595210e1b6bbbeef3c1d5623a2b5d03a8fd6e26caa26afc639c20c8a351a89dad1086f91734f09afab62d28ec17b700fa01","other":"86b84ddf64d301f6a9c4504c59eb4031d3167fb74101abea3b694845a009dc522be7b2e2720097ceea9f36058e160f42a2a438a33034929a5c1a7793c7ccef7b","up":true},{"one":"caad8529d498a4a1e1ba7573689a913500bd409345ef8e3656abca748269eb73b919282f7f2eb0087f81f7bc52c367657ac8be0cdac65d2490c7c50c874444b7","other":"8f625a4e4f4fd980c796d3aa535e58a39722492480cf6982d43fab02de63a5b4c1b5c7cd8402171dd792bb5d9c3e2bdd38176c061dbe3e5b0592af1339e3fd82","up":true},{"one":"9e6c1c6e871638182c4b54ac89352ef5c2bca0a99424a1369013e7c182883da0e8d7ab96b3c8254c31fa315b941d8ddee153157626821fc78c2cae951c1c9053","other":"276256790c9317d09ff7802f4ad0a85840fe62527390ce1790e1e3186e8b3f04acfaa41dcd02303d333423678a4037e4f4854676e79ced3232a3dbd772cc2680","up":true},{"one":"41994605708232b4ca7448c3bc0760a7b86bf26d442091e5ce6e92eac94925721d7e0eca04bdd03bb1bba1ef92deeccd4bf1b7c6c3318b7e8d031965c6646761","other":"d90a81a583c82d626b92f27244f027da4a0ae76e6d3bdc1de0af7be01798f1fb04b34ce60c6d8651a39d7a70915438a4aa63e5adf844a9f7e38dbf0b1dba754d","up":true},{"one":"6ce3a68cb1e2924ad97f22006094c709a3dd8b4ca1546fbb037f841a9e5ac62def242015dbf6221bda610153db064edcbb58a78a35a06077b8c02bf5b2a33c04","other":"3e7820bb15c07f515bd63791b66136723dcc9878b3145fe0f238f6b41e3f2f7565ae55ef24f08ae461950ce1ae0c8a80fe5e4fd4f2f88c4acf4a2c94640df239","up":true},{"one":"670949178a5fad22da03af1e206c814a797c0e9eb4e3371f83612f121e5b56e767706a3ae36628cd0c86dd7bd1586ca4df57e2de27b28a31284ecf9176d330e5","other":"a40391285d1a97f1fb368b20c8e4d02be1bdebc0db41f00f99aac2f01893dc12256cd5a711117a981fbb3f9dfea18c19cf3603e925dbd67c4032b22b41eab8d5","up":true},{"one":"c89dbada7195464e732671ac6fff014cacfb4c879b63b6b84e7c1bce367522f759bd06e504b15f43a1735c6322356747fa5c4951882d4fd6cdf6f7cf13726719","other":"59730132a01ba848a3c050bb6234bca9a72deba33716960fc3ec89b186bfcd313b9bbf049939d5805ff98db2c53a9421ce6ec97d8b4cdbaea53ba264d80d0734","up":true},{"one":"562119edffe8270f6f7a5ad9b13d4c65d643e52a2331d1fee16f7e9b5567f44cfea62df3e8965a22cf08db8fa918f0a0bcae8da2936677e6d25bc88ed85ed2f1","other":"f2ea93f43be9d0c3fa21f1496dc13c778977a6afdcba24c8b146de7dca2cdde62a5b792aab969e5b4b6c56f63066b336580d911f206049cc24cac32a25fc4306","up":true},{"one":"bfef26733f5196a11484bcc28d88776e747189ae7cec883ff39a27cfeee6d9d1efb34560c9f8e75eec43fc069a2ce5f0c78107a36cc8a569d37bd5306aecf23a","other":"18bb6572965f4263c5a4d59a73027abc57a46122125ee58d871e95c993e6a1e8230438ce696a5f8880a08749837268b54319f7b0aa254c1a5bd453a8e9bcf84f","up":true},{"one":"cbed12dcab0aa04a96ec7e25bc2ee03b337c7b2006391baa7d2aff042c17ec70b82c5fb2dc916d085a7948541719d329f9b528b67ec6adb1ac2cc594d4ef1e42","other":"750ca601f07d65f426f6ea5f34e06238f9d7a931f022f9b0ebc811943d3725500cb3c6f00c8d05eb8d5b353c6534136dff38b9a8d3d4dc5bf49cd96875704d07","up":true},{"one":"82a774be7146766585d2bec6b69b7803aa956f492a53d8ed5f071becdbbc617562885d8430f0afd505210aab7b032428fbea32c82dffbd12d9ccba776ef4729b","other":"a58a2dd3f5ee2471f0ddd555ffcc45d86e2d8c325585e3fe55eee878b8a626faccce73679d32811fc5d068c153e671673f4cd020f3c7fb37bc6fd9646931646a","up":true},{"one":"816e91fa8ff68ba067a89390ef61e7f23211e5e05049daa103ad1ff84b94fbcf535a6f6b515fb571939f5656869767c608513808800baba7e5d2b5f3a17a9691","other":"5d96577324edf1b5a1626999925982af1e0ba7bed8edcc3f740ba434f4b003cbbe2d632cad327c76e5b490d08c091c4a7b473353ab59139493657eb9525b8be2","up":true},{"one":"545850cb90787d49c579b1ed54a753ebd00eaafe3f1bd04d57266e4912fb1cdd654446ef054a973a583ce8dfc6cc130b6f90e63bcf75372fc21c445f8e1e6005","other":"0e8c1a6b70524c4fdc492c74348bac4ccd5d140bd41352607e8cfba45561afb1e6e12f3e2fcf03c1778c9ae5ae19cb9218ee2d613983768f54e3f54e69bb6600","up":true},{"one":"a40391285d1a97f1fb368b20c8e4d02be1bdebc0db41f00f99aac2f01893dc12256cd5a711117a981fbb3f9dfea18c19cf3603e925dbd67c4032b22b41eab8d5","other":"33e3ab7108ced43102003c3b3192b194100f32b6bcb67bb772ea9696e35721196699cf01e443f7cdf8076ad83aaf7468b75c71d03efb95f4c07cf0742ea9af81","up":true},{"one":"1480f62d85ea32226d9f77ccd31780b3e704fb60618a588ae85dcd1c0e84e878c5fc092adfb306e8ebc7abba9ec429cb2447754502ef847cf931467f31fa50b2","other":"e7bb63c5187ee85d965fed5cb33d1678c0e090b4e4c3f3d859755565db18046cb60025453bdebf136373c416a2e6e56be063bca6c9257b7b175dcf966e274205","up":true},{"one":"4448a59bde9edb93edcdb4a77f3e2277b9c01ffea45496ee0533eb5192955a08a0f982e25cf772e0dae68735a55b7acd221f6ba7b134f1e999087bee182330e8","other":"3c6faa2e75a1699ddadd0e21fd35d3d6215715cfdc2dc89961cfd66773d2541776e785f3ebc833a70e3d1017a4edc571a5d5d9f9fbfc3fa0a8588f6c5023c164","up":true},{"one":"5771bef7f50439f9b81d2a7bf7060b1ad4b38675d8f6abbac3cc4c215fb0cb5dd07f6873545b42218337556925566025476e2915b7b98e662a3dcd28bebf0eb4","other":"03e478a3aae82e06e215e40272a420037a61442d11c49c367a5ee6a21868d29a17ea8b9284f013d020c4740f296a6a22bc64d33d1c2807f9ab8dc48c0cfec18a","up":true},{"one":"28afc20d8f4779b285bb14870062dbb54796ec77623302e51bc1bafed9e2c35751c8469ffc482718e059875dfa2226195ed10999e251498cba3a444896cb67db","other":"93987e431a0058f2e942ccf8d3486d249cd2734d6494131b343e2c3a8fdd86cfcb12d0aaaf8fcb911ad3cdd682cc82118198195a7fdc915ab7853223f012eab6","up":true},{"one":"20f171ab01a814a2856a6cbe7929269f18f6329914289515e2cb9d078ac14ebdae457789dd638c6415b062799114570f556147d4bf9ac850f00b6d0762765ac1","other":"ab3814579882e9fd8d464f4f3c8a421be37822ba7f42c5f5e787e81125ec032f9ccf90a138c0b57f0a813b55b583f80d66284f795e2c82d80d2869e1fc770be5","up":true},{"one":"18bb6572965f4263c5a4d59a73027abc57a46122125ee58d871e95c993e6a1e8230438ce696a5f8880a08749837268b54319f7b0aa254c1a5bd453a8e9bcf84f","other":"1480f62d85ea32226d9f77ccd31780b3e704fb60618a588ae85dcd1c0e84e878c5fc092adfb306e8ebc7abba9ec429cb2447754502ef847cf931467f31fa50b2","up":true},{"one":"d8cfadac10473b31a4560c711636a05615f13054388065344642ff1d04246fb62eafeec06805264eafead111ed8134e11a8e21f42a0eb950c23b142e627bd8cb","other":"51302ef7b50922398ad802e917390bb4a3c24c877f2c2bcb7fcb34de9feca22673a2c594639914fe46a28837ffadfd03bb673afbc856aff5e59caf8e76082482","up":true},{"one":"e59940a6dfe35a6214e2e3daba9ad94e630004cd8f029e13a6649a56dc528ff94bc09d8d21a2f14a56b4ff759b60ebf3d27c1029862c183b8416fa3e950bdb55","other":"f62bd19b0fd052207743ce53c3d48a3a71e9219b75e41a9497a43e6368e559d5487ff1ab644f2df4106b500583e4344515f73187eec773115deb977b4ebc3514","up":true},{"one":"d90a81a583c82d626b92f27244f027da4a0ae76e6d3bdc1de0af7be01798f1fb04b34ce60c6d8651a39d7a70915438a4aa63e5adf844a9f7e38dbf0b1dba754d","other":"09b60de1e85bb6f7d2caf5b1ab58204d7d04531ece300dcd7bcc9157b8b3ef2a182758808a0eec6056034f29f52caadb7c690f498c1c8832ff7a6a9ecff308bd","up":true},{"one":"f04c3ae9fe957a14c249acf3ea2e8407d04d108fc01e75f6d52aaf5073b3450025012d138a75b857473eea4d20e57c99b92bff9041f269d995543d7c67a92ec6","other":"c93cb2df7ba6de8009872f5f7565891040d42e3b193ef1cdb321a0c167cc8fb8138900982bb8f6918fbaefac6e02dda01ee40f7a6beba1990dd44abe03cc3d01","up":true},{"one":"3540d888c3207d6df233afd1164ff9dde2551730862772547e04f7311de364968e113f38a7dea1ab0916a7f8307017de5b49578fa4ebcc39651e541fde51be48","other":"ed1ab28230ed533abf25633508d54f32bbff78a10c7a15fad5c2320cda9d9669c6d0e15689d8885400e64cbcd81730456f8f4bd5c98681d2cd8a8d4e1daec553","up":true},{"one":"a5cdff211813e17fadd43ec55a6cf4e97e6ca0c3b2cef0db58923b27d36207fd1a77146efb6093bd94d7eb89cc77d8c735fc64ab098839efc74a00b5e8687555","other":"da3e0fd71eb96ba2cab7f920d32f5425d1aad41d00765fdffb0b215d9dd5b60e2bc5929eafebee5b2b5a11aec164e141beff19d828aac7d1fabd3ffb0bfb8450","up":true},{"one":"dafb58b2fc8a14f2b23b7df33d28aa7847a08f80e9c21a654d4c97d928e1afe6585644d27f22442cf70d229c32783be6a03c0920be153fc4d9f3b273dfa90ec3","other":"73319a301ad3cf0ec09549d817c9523d61b74abb0cad87b737d41d900321e52722a84355f6f87bc7a5f848818c89a021bb0f3e5994f67c9a7b5bbfc98188a376","up":true},{"one":"44462055ba68fdef337dd19d8123aace9a12284c13bc97687416b6b4ca0c94234ba7db6823651fc021d6ac1539e0c5321e763a7a12c9e7c8a583aac5369817d8","other":"489660042a8867d90a16ebb013968db26ca3edfc70f53320f511e35b3703eed09fbd787be5c06726a570a54aa15d129cd10db741523adf297929f909be4a0c71","up":true},{"one":"3df030a522a157e36f6b369aab048b9287792743a411a47073c4f9ef7686528f39bf7bf91c48e4d46afe180c8d08430b012bd216d50876baa3b1e7bc17cb55ef","other":"33e3ab7108ced43102003c3b3192b194100f32b6bcb67bb772ea9696e35721196699cf01e443f7cdf8076ad83aaf7468b75c71d03efb95f4c07cf0742ea9af81","up":true},{"one":"f8052e328014f39157036f3dcecdb23419c0959473a88282605f10add681ef5cbfb1e926b522f98b8401272113b677a67225874d1afb0bff4b11140cc071de44","other":"5d96577324edf1b5a1626999925982af1e0ba7bed8edcc3f740ba434f4b003cbbe2d632cad327c76e5b490d08c091c4a7b473353ab59139493657eb9525b8be2","up":true},{"one":"9c3be147f9fe0fa34e553d9e4332969086ea7fa65294b61ca35c9f731f6b81d0b70cdcfe2ba52b6cea3c0de14b7ea40031b5cc40661c4bb821147894130d7bf5","other":"09b60de1e85bb6f7d2caf5b1ab58204d7d04531ece300dcd7bcc9157b8b3ef2a182758808a0eec6056034f29f52caadb7c690f498c1c8832ff7a6a9ecff308bd","up":true},{"one":"08900197e74e285a5a8a9cc53fbd420bb35043ab27eb2d9eab22615e736a093abfa235c17f667dcc791cb50b9022082eafd9fba030194cc84f0358b769adc85b","other":"49eb706cd7e95ad78502a508487d88b818861d94334aee36b2acef5c25cfff5c0efc2df9dc5dbb18acd4003d5cc0c843d3b40363adf2f62a14c04d814268fdee","up":true},{"one":"276256790c9317d09ff7802f4ad0a85840fe62527390ce1790e1e3186e8b3f04acfaa41dcd02303d333423678a4037e4f4854676e79ced3232a3dbd772cc2680","other":"d71c50805f284ed3a759e2e81f220fbc73d6d0a7a261b4c9e7878c3da143cfc07afa83e1635b6a45530f71a60b9f17c485a2fd6617c6c2bff82bacc71c208087","up":true},{"one":"a9e0b763852706722dc904b494293f9399c0fa32255890aa720285b8160335bb618f36b68a81b875a805384179f600defef474d486b4ea04b003ef6477ab7907","other":"33e3ab7108ced43102003c3b3192b194100f32b6bcb67bb772ea9696e35721196699cf01e443f7cdf8076ad83aaf7468b75c71d03efb95f4c07cf0742ea9af81","up":true},{"one":"3103510e00a3f49a5e715719049fc8c9c67a2373a548f326458aeb6d9c75ed92b94373638fd075def0209113b4e85d972c23f064539f7b041596184e40d7f9a2","other":"1e0a46ff50fb6d9a2c218a851763ff86c42e4d61dddffb7188481febc0f3180bc8f31973d336b2a6e25802acd4fed6d905d89c6d4d7d8080fb12741f9c5ab7e6","up":true},{"one":"3e7820bb15c07f515bd63791b66136723dcc9878b3145fe0f238f6b41e3f2f7565ae55ef24f08ae461950ce1ae0c8a80fe5e4fd4f2f88c4acf4a2c94640df239","other":"a05a18161c2d01a0f122548c66509dd1fcf3ee52975035bc79fb059e9613b743a16cd6f5ac54090e68f51bcf76ff21fb3805ba3197a96b4236afb80f791df802","up":true},{"one":"31ac37862416c0e229c4a088ec179f23bdd1bf12dd464eb11c630ad531d7c3438671862e5458e2f6fbb32b857f857e6b8c17e5d93eb29a0e78bb5a65d7eb648c","other":"665c3288c14dc1c17d85d17d634910f42183482c7e77c47e68f9b4f475b93e8c152246b9e34781606315ff6ef0f8360342500d15e4a2d67d9df6b72f30af64a7","up":true},{"one":"c93cb2df7ba6de8009872f5f7565891040d42e3b193ef1cdb321a0c167cc8fb8138900982bb8f6918fbaefac6e02dda01ee40f7a6beba1990dd44abe03cc3d01","other":"eb097186ff58d96a7ead7a7f9c05a44075d84537bd4fd3f82857bf2c45bee1c6dece434a7707cde69e96f02366859cab4c991fdb7615e113a868d4b9c7524a45","up":true},{"one":"e3f2e777a96b2137b3104b84d5d827d484eac9ee1b585430e09f790d7e26978da12802325927c3c483bc19973e09cd3f70c513c34798e5da650f8d2f0c8c5c47","other":"cdd86dea7dde96ff7cc1e3248fd17d107c83f2cc7ce2111c41530448962763309e91a05b5dad4663d0e02db59ed4129ab0c3e1eedc42c654e39d29f99038063b","up":true},{"one":"489660042a8867d90a16ebb013968db26ca3edfc70f53320f511e35b3703eed09fbd787be5c06726a570a54aa15d129cd10db741523adf297929f909be4a0c71","other":"cd0e9a45b45f9a67417fcde29d9f92c45ca4db46eebbfe47dcf6999e23e549e4205f42ada8e3fcd00e2fb5f832bb92a27a59b43c4a5909148d81399c2e8ce492","up":true},{"one":"33e3ab7108ced43102003c3b3192b194100f32b6bcb67bb772ea9696e35721196699cf01e443f7cdf8076ad83aaf7468b75c71d03efb95f4c07cf0742ea9af81","other":"59730132a01ba848a3c050bb6234bca9a72deba33716960fc3ec89b186bfcd313b9bbf049939d5805ff98db2c53a9421ce6ec97d8b4cdbaea53ba264d80d0734","up":true},{"one":"077bcadade93e0d361e94f76dff464d61912bc067ce2ce17ebcabd757cca201cd64624ea809d99dd8ecb749d40528db9b3eb503ef5ec05e8845044cfaef720dc","other":"51302ef7b50922398ad802e917390bb4a3c24c877f2c2bcb7fcb34de9feca22673a2c594639914fe46a28837ffadfd03bb673afbc856aff5e59caf8e76082482","up":true},{"one":"a58a2dd3f5ee2471f0ddd555ffcc45d86e2d8c325585e3fe55eee878b8a626faccce73679d32811fc5d068c153e671673f4cd020f3c7fb37bc6fd9646931646a","other":"e9f7e58fda4b504275441d51929fbc98214abdc9ed552c7aa94c600a85d4e791d60c032304b29ae028adccec94984fc9a3d705a81462632f50ef45024eb0f64e","up":true},{"one":"b2bea653b6ec9629c6f934be72fccf30acf836698e21e81dd8085f070ba8259ba43eee43c342738a4b782f5fbddd44caa28f56dffc08237ca7567c965ac3beca","other":"dafb58b2fc8a14f2b23b7df33d28aa7847a08f80e9c21a654d4c97d928e1afe6585644d27f22442cf70d229c32783be6a03c0920be153fc4d9f3b273dfa90ec3","up":true},{"one":"73be4d2291c68ca4554a86fa170f7595210e1b6bbbeef3c1d5623a2b5d03a8fd6e26caa26afc639c20c8a351a89dad1086f91734f09afab62d28ec17b700fa01","other":"ed1ab28230ed533abf25633508d54f32bbff78a10c7a15fad5c2320cda9d9669c6d0e15689d8885400e64cbcd81730456f8f4bd5c98681d2cd8a8d4e1daec553","up":true},{"one":"41994605708232b4ca7448c3bc0760a7b86bf26d442091e5ce6e92eac94925721d7e0eca04bdd03bb1bba1ef92deeccd4bf1b7c6c3318b7e8d031965c6646761","other":"872cdbb6d74fb55fd2d51877ef7804bdd2eeb6de0297eb2ce18b67e52379b147d54a46d2385ec9293eb21736bed4191d92c5c75e8e81fc5a6c691970e019f570","up":true},{"one":"56e8f792ec9a75ec9e91d472b8a4b023655dd68c2a448a33397b125fe3584a5efa1b492e47077b24acfe0396b73e1cb564a6a6b2aee1b457781dfaf6d43fcaed","other":"fa897ba112f34839064c6871a4c9504c5d709eff5095a137c6a42726d58eb623af976cb96cc30db67e6ac9347c769f032aa4ebda884285a057059040c008ad3e","up":true},{"one":"5b4de68680c5d1a75cccd5e7a82319c031f5d61d79cbb6532e1254ab81c833c3fafb54390cca7a770e84690c490fcba90482b35321870f8506335a2f57cc052e","other":"eb097186ff58d96a7ead7a7f9c05a44075d84537bd4fd3f82857bf2c45bee1c6dece434a7707cde69e96f02366859cab4c991fdb7615e113a868d4b9c7524a45","up":true},{"one":"0e8c1a6b70524c4fdc492c74348bac4ccd5d140bd41352607e8cfba45561afb1e6e12f3e2fcf03c1778c9ae5ae19cb9218ee2d613983768f54e3f54e69bb6600","other":"93987e431a0058f2e942ccf8d3486d249cd2734d6494131b343e2c3a8fdd86cfcb12d0aaaf8fcb911ad3cdd682cc82118198195a7fdc915ab7853223f012eab6","up":true},{"one":"6ce3a68cb1e2924ad97f22006094c709a3dd8b4ca1546fbb037f841a9e5ac62def242015dbf6221bda610153db064edcbb58a78a35a06077b8c02bf5b2a33c04","other":"da15d60a4b9a8816ce24c20f6c941c51229c1fb5e070b8b29be2977c2f7b41f8f17e4b6efe75f465e7935ded1ba17472f046eac73393db7197018fa86d11c31f","up":true},{"one":"93987e431a0058f2e942ccf8d3486d249cd2734d6494131b343e2c3a8fdd86cfcb12d0aaaf8fcb911ad3cdd682cc82118198195a7fdc915ab7853223f012eab6","other":"56b25623ac935f3a8aac1e2603a6bd15ace1e5714671954b47f2cab960cf47922828f415105602408d0a732a893ebeea6f9afab7f889bb235c81589548d09391","up":true},{"one":"1e0a46ff50fb6d9a2c218a851763ff86c42e4d61dddffb7188481febc0f3180bc8f31973d336b2a6e25802acd4fed6d905d89c6d4d7d8080fb12741f9c5ab7e6","other":"bf1e6eeb8b229f63b49213db499b71dcfe0ae45ee3f14685c7cbfa3f0a2150e52a89c853f4cd8c7a92e6e5f6083044efddfa17391662e3cff6290da679520404","up":true},{"one":"2502fc8ee0ccda79ad1dbd9c7cec625da85980b9116bdd56dc367d508039e25e5f65183293006e5b0df72fa9037a48bd2b133a757940d3587ff77ae2392e3eaf","other":"73319a301ad3cf0ec09549d817c9523d61b74abb0cad87b737d41d900321e52722a84355f6f87bc7a5f848818c89a021bb0f3e5994f67c9a7b5bbfc98188a376","up":true},{"one":"5d96577324edf1b5a1626999925982af1e0ba7bed8edcc3f740ba434f4b003cbbe2d632cad327c76e5b490d08c091c4a7b473353ab59139493657eb9525b8be2","other":"077bcadade93e0d361e94f76dff464d61912bc067ce2ce17ebcabd757cca201cd64624ea809d99dd8ecb749d40528db9b3eb503ef5ec05e8845044cfaef720dc","up":true},{"one":"03d2d77c008b5fa1063b1abc3152b879a529fe4fdb2dc174d6d85312264a38ee4cc49b342507a10fff1a4b0730f1ef8e008b0897d97bfd6f70050adb124d3596","other":"2502fc8ee0ccda79ad1dbd9c7cec625da85980b9116bdd56dc367d508039e25e5f65183293006e5b0df72fa9037a48bd2b133a757940d3587ff77ae2392e3eaf","up":true},{"one":"896c74ca4cc4cbb9d2b6606d0ebfd6427952c2e16aedbf36933fa3d01f1c505fcd663f3d01c0cf096bef9cfd0bae4595ec7c221cfc362e19a5b7c60614a9658b","other":"49eb706cd7e95ad78502a508487d88b818861d94334aee36b2acef5c25cfff5c0efc2df9dc5dbb18acd4003d5cc0c843d3b40363adf2f62a14c04d814268fdee","up":true},{"one":"03e478a3aae82e06e215e40272a420037a61442d11c49c367a5ee6a21868d29a17ea8b9284f013d020c4740f296a6a22bc64d33d1c2807f9ab8dc48c0cfec18a","other":"3e9c0bbd146d8b1040b4f379eecf802c27c4d0a70e64a9fb2e941a7edab9b00396b0b67fc5c891652743cdba3b342973ed49615b32da54b925954a799240431c","up":true},{"one":"bfef26733f5196a11484bcc28d88776e747189ae7cec883ff39a27cfeee6d9d1efb34560c9f8e75eec43fc069a2ce5f0c78107a36cc8a569d37bd5306aecf23a","other":"d90a81a583c82d626b92f27244f027da4a0ae76e6d3bdc1de0af7be01798f1fb04b34ce60c6d8651a39d7a70915438a4aa63e5adf844a9f7e38dbf0b1dba754d","up":true},{"one":"fd12c5c96df6ee76dd7beb9e4e4768dda4d2c498851b6435f13ca0175980d0e4a4ff1c002e4daf41a995f118500604764f88496fb9b2c22e28308d8649b525ce","other":"73319a301ad3cf0ec09549d817c9523d61b74abb0cad87b737d41d900321e52722a84355f6f87bc7a5f848818c89a021bb0f3e5994f67c9a7b5bbfc98188a376","up":true},{"one":"51302ef7b50922398ad802e917390bb4a3c24c877f2c2bcb7fcb34de9feca22673a2c594639914fe46a28837ffadfd03bb673afbc856aff5e59caf8e76082482","other":"3e9c0bbd146d8b1040b4f379eecf802c27c4d0a70e64a9fb2e941a7edab9b00396b0b67fc5c891652743cdba3b342973ed49615b32da54b925954a799240431c","up":true},{"one":"cbed12dcab0aa04a96ec7e25bc2ee03b337c7b2006391baa7d2aff042c17ec70b82c5fb2dc916d085a7948541719d329f9b528b67ec6adb1ac2cc594d4ef1e42","other":"3e9c0bbd146d8b1040b4f379eecf802c27c4d0a70e64a9fb2e941a7edab9b00396b0b67fc5c891652743cdba3b342973ed49615b32da54b925954a799240431c","up":true},{"one":"87fce129511a1be2777052d24b606acdfe7067f4e874ab04674a68664b378ea208975f7269a72af889d3d23cd930b6a181afa2cdef3f9f9491f715bd96ad8dc0","other":"31ac37862416c0e229c4a088ec179f23bdd1bf12dd464eb11c630ad531d7c3438671862e5458e2f6fbb32b857f857e6b8c17e5d93eb29a0e78bb5a65d7eb648c","up":true},{"one":"3572a22097a313b3adef95a7b6cc679f8d1201a156d764e61a9fbc63d123fb4826f7125402fb6569beed359e1c1e5e6cb6993a75975da6cd4ce15669a2eea758","other":"9c3be147f9fe0fa34e553d9e4332969086ea7fa65294b61ca35c9f731f6b81d0b70cdcfe2ba52b6cea3c0de14b7ea40031b5cc40661c4bb821147894130d7bf5","up":true},{"one":"06472c89def07fa73188d253cf1acddc2be984842f3a234edb3db95449ba74928ab1395eca1b8978987769863afffb488fc27c9ac723aa24837b66c12f38d735","other":"73319a301ad3cf0ec09549d817c9523d61b74abb0cad87b737d41d900321e52722a84355f6f87bc7a5f848818c89a021bb0f3e5994f67c9a7b5bbfc98188a376","up":true},{"one":"57bfbde13c71e035c96513870aa8215198f78806e7cdb01c54fbdb392de2c40386d768d6fdc4c68534a67e531867ca74d8ca4dcf34ff7f7f64ec35edee3e5f68","other":"56b25623ac935f3a8aac1e2603a6bd15ace1e5714671954b47f2cab960cf47922828f415105602408d0a732a893ebeea6f9afab7f889bb235c81589548d09391","up":true},{"one":"fa897ba112f34839064c6871a4c9504c5d709eff5095a137c6a42726d58eb623af976cb96cc30db67e6ac9347c769f032aa4ebda884285a057059040c008ad3e","other":"f62bd19b0fd052207743ce53c3d48a3a71e9219b75e41a9497a43e6368e559d5487ff1ab644f2df4106b500583e4344515f73187eec773115deb977b4ebc3514","up":true},{"one":"665c3288c14dc1c17d85d17d634910f42183482c7e77c47e68f9b4f475b93e8c152246b9e34781606315ff6ef0f8360342500d15e4a2d67d9df6b72f30af64a7","other":"e0420ba2a293315d810928a0e09a507c6aaf93977ba2c7598e9b83723b4a66682398ea17542c26767c7ff0f4ca09c537d3cc10dad283f079f1de73e25e87cb5c","up":true},{"one":"20f171ab01a814a2856a6cbe7929269f18f6329914289515e2cb9d078ac14ebdae457789dd638c6415b062799114570f556147d4bf9ac850f00b6d0762765ac1","other":"caad8529d498a4a1e1ba7573689a913500bd409345ef8e3656abca748269eb73b919282f7f2eb0087f81f7bc52c367657ac8be0cdac65d2490c7c50c874444b7","up":true},{"one":"d8cfadac10473b31a4560c711636a05615f13054388065344642ff1d04246fb62eafeec06805264eafead111ed8134e11a8e21f42a0eb950c23b142e627bd8cb","other":"cbed12dcab0aa04a96ec7e25bc2ee03b337c7b2006391baa7d2aff042c17ec70b82c5fb2dc916d085a7948541719d329f9b528b67ec6adb1ac2cc594d4ef1e42","up":true},{"one":"cdd86dea7dde96ff7cc1e3248fd17d107c83f2cc7ce2111c41530448962763309e91a05b5dad4663d0e02db59ed4129ab0c3e1eedc42c654e39d29f99038063b","other":"03e478a3aae82e06e215e40272a420037a61442d11c49c367a5ee6a21868d29a17ea8b9284f013d020c4740f296a6a22bc64d33d1c2807f9ab8dc48c0cfec18a","up":true},{"one":"8f625a4e4f4fd980c796d3aa535e58a39722492480cf6982d43fab02de63a5b4c1b5c7cd8402171dd792bb5d9c3e2bdd38176c061dbe3e5b0592af1339e3fd82","other":"545850cb90787d49c579b1ed54a753ebd00eaafe3f1bd04d57266e4912fb1cdd654446ef054a973a583ce8dfc6cc130b6f90e63bcf75372fc21c445f8e1e6005","up":true},{"one":"f7637cdd5ef26de40b9055c1df91a45725670c8df11ae934c0d99d2547c3eb4c42a16dbb2e75bcaf4b1b9347c48db65f549a0623179a08dd8cbad92f5bca08cf","other":"f06ec3a90d34300f9fa2d48aea0c6b5f2f01f7833ffb0fad30e7f57e3916e344f3a4f9efe38e222443b8b00d3c7f5221c672491a129e4958e574afc283bd45b1","up":true},{"one":"86b84ddf64d301f6a9c4504c59eb4031d3167fb74101abea3b694845a009dc522be7b2e2720097ceea9f36058e160f42a2a438a33034929a5c1a7793c7ccef7b","other":"f0b2f1e8d46be656109adb18c60677ac9eb8fce7f42e15d9dbb25f94b4e426064780eaf32b79954b9bb72ea89953175da8de35380aaba18931cca374a7de2b11","up":true},{"one":"c773af3af01ee8ab9fa8d06987baf4f10c394fdd386d69b7a7362f4b68fd6fc082337d3b33a19d584c5801a3e9198225d7b61f6629e34ce823be70908339f4c7","other":"27fb8fcda1986644f985d68430c399f0299644b00b234c355362721081d12f9eb7686eea8f92eabda1d342bf56255e51c07b200c6233f95ac009f15b874eee97","up":true},{"one":"3df030a522a157e36f6b369aab048b9287792743a411a47073c4f9ef7686528f39bf7bf91c48e4d46afe180c8d08430b012bd216d50876baa3b1e7bc17cb55ef","other":"e9f7e58fda4b504275441d51929fbc98214abdc9ed552c7aa94c600a85d4e791d60c032304b29ae028adccec94984fc9a3d705a81462632f50ef45024eb0f64e","up":true},{"one":"eb097186ff58d96a7ead7a7f9c05a44075d84537bd4fd3f82857bf2c45bee1c6dece434a7707cde69e96f02366859cab4c991fdb7615e113a868d4b9c7524a45","other":"077bcadade93e0d361e94f76dff464d61912bc067ce2ce17ebcabd757cca201cd64624ea809d99dd8ecb749d40528db9b3eb503ef5ec05e8845044cfaef720dc","up":true},{"one":"56b25623ac935f3a8aac1e2603a6bd15ace1e5714671954b47f2cab960cf47922828f415105602408d0a732a893ebeea6f9afab7f889bb235c81589548d09391","other":"73319a301ad3cf0ec09549d817c9523d61b74abb0cad87b737d41d900321e52722a84355f6f87bc7a5f848818c89a021bb0f3e5994f67c9a7b5bbfc98188a376","up":true},{"one":"9e6c1c6e871638182c4b54ac89352ef5c2bca0a99424a1369013e7c182883da0e8d7ab96b3c8254c31fa315b941d8ddee153157626821fc78c2cae951c1c9053","other":"6ce3a68cb1e2924ad97f22006094c709a3dd8b4ca1546fbb037f841a9e5ac62def242015dbf6221bda610153db064edcbb58a78a35a06077b8c02bf5b2a33c04","up":true},{"one":"622646c74fdbae39ba191dbafff4906fb683fe0b0f2c303d080f5577a070876c41c8d3786ae7b953e5f682b8ec647727550d47302229ebb9f82bed24cea61132","other":"9c3be147f9fe0fa34e553d9e4332969086ea7fa65294b61ca35c9f731f6b81d0b70cdcfe2ba52b6cea3c0de14b7ea40031b5cc40661c4bb821147894130d7bf5","up":true},{"one":"750ca601f07d65f426f6ea5f34e06238f9d7a931f022f9b0ebc811943d3725500cb3c6f00c8d05eb8d5b353c6534136dff38b9a8d3d4dc5bf49cd96875704d07","other":"a40391285d1a97f1fb368b20c8e4d02be1bdebc0db41f00f99aac2f01893dc12256cd5a711117a981fbb3f9dfea18c19cf3603e925dbd67c4032b22b41eab8d5","up":true},{"one":"41994605708232b4ca7448c3bc0760a7b86bf26d442091e5ce6e92eac94925721d7e0eca04bdd03bb1bba1ef92deeccd4bf1b7c6c3318b7e8d031965c6646761","other":"3103510e00a3f49a5e715719049fc8c9c67a2373a548f326458aeb6d9c75ed92b94373638fd075def0209113b4e85d972c23f064539f7b041596184e40d7f9a2","up":true},{"one":"077d2d032874e5ce70e9b928b7fe72c0326ba92394e16245e31d48b5731d3d32bfd86acf40825decff54bcd735e9ebfd94eba677c418ea7007baec9db4af676d","other":"ecbdca037cd7892752345b48b4219478b1b334f83ce7140fcc72eb71784436b690ce7a41b03e013cefc19d64a34a20cfef1b9e2b535d938bcdcb39fe63645a42","up":true},{"one":"3c6faa2e75a1699ddadd0e21fd35d3d6215715cfdc2dc89961cfd66773d2541776e785f3ebc833a70e3d1017a4edc571a5d5d9f9fbfc3fa0a8588f6c5023c164","other":"3540d888c3207d6df233afd1164ff9dde2551730862772547e04f7311de364968e113f38a7dea1ab0916a7f8307017de5b49578fa4ebcc39651e541fde51be48","up":true},{"one":"9c6dcfef0e128dbfeca58b8ac625b08fb447b0d579bd3f18bc0e2be60d1ec2274595d0554ddba0ca7eb660099d3ea146d8076792b46c93841d2ecf8cf608f5ba","other":"cd0e9a45b45f9a67417fcde29d9f92c45ca4db46eebbfe47dcf6999e23e549e4205f42ada8e3fcd00e2fb5f832bb92a27a59b43c4a5909148d81399c2e8ce492","up":true},{"one":"6ce3a68cb1e2924ad97f22006094c709a3dd8b4ca1546fbb037f841a9e5ac62def242015dbf6221bda610153db064edcbb58a78a35a06077b8c02bf5b2a33c04","other":"f8052e328014f39157036f3dcecdb23419c0959473a88282605f10add681ef5cbfb1e926b522f98b8401272113b677a67225874d1afb0bff4b11140cc071de44","up":true},{"one":"178d5ce398a7114a63a0c953a59932e769891420f6b1544f08c082cd37b531b66757652d279b3036b03b04f8d46eceb0b46fb95646c6668e2921af75c06c3d97","other":"09b60de1e85bb6f7d2caf5b1ab58204d7d04531ece300dcd7bcc9157b8b3ef2a182758808a0eec6056034f29f52caadb7c690f498c1c8832ff7a6a9ecff308bd","up":true},{"one":"26cf4ea45b9a76daab82a57126f9c6f8726d2eb973e205ab4ab69c8b8be11a32a7eb5c3807e952cd428ce5ddd88f143d4fc9ff8c3de3d159855675afce715615","other":"d8cfadac10473b31a4560c711636a05615f13054388065344642ff1d04246fb62eafeec06805264eafead111ed8134e11a8e21f42a0eb950c23b142e627bd8cb","up":true},{"one":"340420ee18d55913f790d0fcc2305b40b1e7bef2eddb79dda57801690aeeead693ebd1a9ff8557671f5ae136b3e65733306924bd00444cbc6e7c6235e5a2c77f","other":"a58a2dd3f5ee2471f0ddd555ffcc45d86e2d8c325585e3fe55eee878b8a626faccce73679d32811fc5d068c153e671673f4cd020f3c7fb37bc6fd9646931646a","up":true},{"one":"155805f787600f9f9518cf8836f491885b64868bfe0023975bcd12776925a424fb5aa3199dc178e83294e97f347a373d05d2422578a08eeeb2d15a178d28964f","other":"a58a2dd3f5ee2471f0ddd555ffcc45d86e2d8c325585e3fe55eee878b8a626faccce73679d32811fc5d068c153e671673f4cd020f3c7fb37bc6fd9646931646a","up":true},{"one":"a40391285d1a97f1fb368b20c8e4d02be1bdebc0db41f00f99aac2f01893dc12256cd5a711117a981fbb3f9dfea18c19cf3603e925dbd67c4032b22b41eab8d5","other":"665c3288c14dc1c17d85d17d634910f42183482c7e77c47e68f9b4f475b93e8c152246b9e34781606315ff6ef0f8360342500d15e4a2d67d9df6b72f30af64a7","up":true},{"one":"b38213eaa5b419de787b70073ad8c7c819e48c5f76dec1507b54f1d7cb027211facbe7a170ac50212abe130935e8947d5a19d6b13790114e71cc18357902a889","other":"f04c3ae9fe957a14c249acf3ea2e8407d04d108fc01e75f6d52aaf5073b3450025012d138a75b857473eea4d20e57c99b92bff9041f269d995543d7c67a92ec6","up":true},{"one":"a58a2dd3f5ee2471f0ddd555ffcc45d86e2d8c325585e3fe55eee878b8a626faccce73679d32811fc5d068c153e671673f4cd020f3c7fb37bc6fd9646931646a","other":"c773af3af01ee8ab9fa8d06987baf4f10c394fdd386d69b7a7362f4b68fd6fc082337d3b33a19d584c5801a3e9198225d7b61f6629e34ce823be70908339f4c7","up":true},{"one":"da15d60a4b9a8816ce24c20f6c941c51229c1fb5e070b8b29be2977c2f7b41f8f17e4b6efe75f465e7935ded1ba17472f046eac73393db7197018fa86d11c31f","other":"4bd17847bdf60ea93a670a84a0ff8fe028d35228e814d6ebc0ae4fa586ddef03cd79390d541d28ca3c05a7241ffe92ac182e63c251176b40db8fe05fefaa82be","up":true},{"one":"bfef26733f5196a11484bcc28d88776e747189ae7cec883ff39a27cfeee6d9d1efb34560c9f8e75eec43fc069a2ce5f0c78107a36cc8a569d37bd5306aecf23a","other":"872cdbb6d74fb55fd2d51877ef7804bdd2eeb6de0297eb2ce18b67e52379b147d54a46d2385ec9293eb21736bed4191d92c5c75e8e81fc5a6c691970e019f570","up":true},{"one":"59730132a01ba848a3c050bb6234bca9a72deba33716960fc3ec89b186bfcd313b9bbf049939d5805ff98db2c53a9421ce6ec97d8b4cdbaea53ba264d80d0734","other":"ed1ab28230ed533abf25633508d54f32bbff78a10c7a15fad5c2320cda9d9669c6d0e15689d8885400e64cbcd81730456f8f4bd5c98681d2cd8a8d4e1daec553","up":true},{"one":"f6a07a1d361a4671e997d5eaadae61736291aff3896cb69f06bbc19bf7536dd152e0b15422b2fd9f8a9d2f9a251c9a07d0140319900e2cc9f25a59025c7dc91f","other":"f0299035cbddfdf7a78e5e3a400aaedf2d719d04e907ac0f9f067525e2f9bb913d985308a3a0d05467a64adf58c68a615c6327acf716c23631d0e829903f8b34","up":true},{"one":"d90a81a583c82d626b92f27244f027da4a0ae76e6d3bdc1de0af7be01798f1fb04b34ce60c6d8651a39d7a70915438a4aa63e5adf844a9f7e38dbf0b1dba754d","other":"44462055ba68fdef337dd19d8123aace9a12284c13bc97687416b6b4ca0c94234ba7db6823651fc021d6ac1539e0c5321e763a7a12c9e7c8a583aac5369817d8","up":true},{"one":"20bdc859d58d8bf419df64fd6ee1d4363c1d5f403af3abef2720d7d3933924672e12e23e5d76b28e0f6726acf58bdc5eb258cba635e327cbd0b564523305da75","other":"178d5ce398a7114a63a0c953a59932e769891420f6b1544f08c082cd37b531b66757652d279b3036b03b04f8d46eceb0b46fb95646c6668e2921af75c06c3d97","up":true},{"one":"51302ef7b50922398ad802e917390bb4a3c24c877f2c2bcb7fcb34de9feca22673a2c594639914fe46a28837ffadfd03bb673afbc856aff5e59caf8e76082482","other":"155805f787600f9f9518cf8836f491885b64868bfe0023975bcd12776925a424fb5aa3199dc178e83294e97f347a373d05d2422578a08eeeb2d15a178d28964f","up":true},{"one":"cbed12dcab0aa04a96ec7e25bc2ee03b337c7b2006391baa7d2aff042c17ec70b82c5fb2dc916d085a7948541719d329f9b528b67ec6adb1ac2cc594d4ef1e42","other":"077bcadade93e0d361e94f76dff464d61912bc067ce2ce17ebcabd757cca201cd64624ea809d99dd8ecb749d40528db9b3eb503ef5ec05e8845044cfaef720dc","up":true},{"one":"f7637cdd5ef26de40b9055c1df91a45725670c8df11ae934c0d99d2547c3eb4c42a16dbb2e75bcaf4b1b9347c48db65f549a0623179a08dd8cbad92f5bca08cf","other":"3e9c0bbd146d8b1040b4f379eecf802c27c4d0a70e64a9fb2e941a7edab9b00396b0b67fc5c891652743cdba3b342973ed49615b32da54b925954a799240431c","up":true},{"one":"3540d888c3207d6df233afd1164ff9dde2551730862772547e04f7311de364968e113f38a7dea1ab0916a7f8307017de5b49578fa4ebcc39651e541fde51be48","other":"82a774be7146766585d2bec6b69b7803aa956f492a53d8ed5f071becdbbc617562885d8430f0afd505210aab7b032428fbea32c82dffbd12d9ccba776ef4729b","up":true},{"one":"7a18392b8338108a996196ee190a93a1b9954c8e05a062c421da513a1828dfa739e7b224878c0670cf74bbc743c7ca7ee8cfee6b6a602fe1f4a82ecfbd38c2f4","other":"ecbdca037cd7892752345b48b4219478b1b334f83ce7140fcc72eb71784436b690ce7a41b03e013cefc19d64a34a20cfef1b9e2b535d938bcdcb39fe63645a42","up":true},{"one":"d8cfadac10473b31a4560c711636a05615f13054388065344642ff1d04246fb62eafeec06805264eafead111ed8134e11a8e21f42a0eb950c23b142e627bd8cb","other":"750ca601f07d65f426f6ea5f34e06238f9d7a931f022f9b0ebc811943d3725500cb3c6f00c8d05eb8d5b353c6534136dff38b9a8d3d4dc5bf49cd96875704d07","up":true},{"one":"20f171ab01a814a2856a6cbe7929269f18f6329914289515e2cb9d078ac14ebdae457789dd638c6415b062799114570f556147d4bf9ac850f00b6d0762765ac1","other":"8f625a4e4f4fd980c796d3aa535e58a39722492480cf6982d43fab02de63a5b4c1b5c7cd8402171dd792bb5d9c3e2bdd38176c061dbe3e5b0592af1339e3fd82","up":true},{"one":"dafb58b2fc8a14f2b23b7df33d28aa7847a08f80e9c21a654d4c97d928e1afe6585644d27f22442cf70d229c32783be6a03c0920be153fc4d9f3b273dfa90ec3","other":"489660042a8867d90a16ebb013968db26ca3edfc70f53320f511e35b3703eed09fbd787be5c06726a570a54aa15d129cd10db741523adf297929f909be4a0c71","up":true},{"one":"87e696a354d249493217dc4e0190082f30e09616873803efa376871d4b34f86f0eeb4643d4822d8a0fbcdedb27cd6ba5438e98943d358d960c4835e82261c93e","other":"73be4d2291c68ca4554a86fa170f7595210e1b6bbbeef3c1d5623a2b5d03a8fd6e26caa26afc639c20c8a351a89dad1086f91734f09afab62d28ec17b700fa01","up":true},{"one":"2d6d55edd34c0d9a0130b4806e409bbe18cdda5c2b221cf46136718ec20ffc9d8e92838d78aff92fbcc85f5d081da361dd1e3d7f3d4e1ea57877d6bb7aa0b6f7","other":"09b60de1e85bb6f7d2caf5b1ab58204d7d04531ece300dcd7bcc9157b8b3ef2a182758808a0eec6056034f29f52caadb7c690f498c1c8832ff7a6a9ecff308bd","up":true},{"one":"872cdbb6d74fb55fd2d51877ef7804bdd2eeb6de0297eb2ce18b67e52379b147d54a46d2385ec9293eb21736bed4191d92c5c75e8e81fc5a6c691970e019f570","other":"56b25623ac935f3a8aac1e2603a6bd15ace1e5714671954b47f2cab960cf47922828f415105602408d0a732a893ebeea6f9afab7f889bb235c81589548d09391","up":true},{"one":"4de606aa7e722197b918c5f7f0db86a3081d48e89d21428b04f19c3ff3755eac0bddbff5fad8bda94b9e57f58fba2fecdbabbf710f7afb381bf4f1a4fe55cd93","other":"93987e431a0058f2e942ccf8d3486d249cd2734d6494131b343e2c3a8fdd86cfcb12d0aaaf8fcb911ad3cdd682cc82118198195a7fdc915ab7853223f012eab6","up":true},{"one":"c89dbada7195464e732671ac6fff014cacfb4c879b63b6b84e7c1bce367522f759bd06e504b15f43a1735c6322356747fa5c4951882d4fd6cdf6f7cf13726719","other":"f0299035cbddfdf7a78e5e3a400aaedf2d719d04e907ac0f9f067525e2f9bb913d985308a3a0d05467a64adf58c68a615c6327acf716c23631d0e829903f8b34","up":true},{"one":"09b60de1e85bb6f7d2caf5b1ab58204d7d04531ece300dcd7bcc9157b8b3ef2a182758808a0eec6056034f29f52caadb7c690f498c1c8832ff7a6a9ecff308bd","other":"da3e0fd71eb96ba2cab7f920d32f5425d1aad41d00765fdffb0b215d9dd5b60e2bc5929eafebee5b2b5a11aec164e141beff19d828aac7d1fabd3ffb0bfb8450","up":true},{"one":"82a774be7146766585d2bec6b69b7803aa956f492a53d8ed5f071becdbbc617562885d8430f0afd505210aab7b032428fbea32c82dffbd12d9ccba776ef4729b","other":"b2bea653b6ec9629c6f934be72fccf30acf836698e21e81dd8085f070ba8259ba43eee43c342738a4b782f5fbddd44caa28f56dffc08237ca7567c965ac3beca","up":true},{"one":"1480f62d85ea32226d9f77ccd31780b3e704fb60618a588ae85dcd1c0e84e878c5fc092adfb306e8ebc7abba9ec429cb2447754502ef847cf931467f31fa50b2","other":"bf1e6eeb8b229f63b49213db499b71dcfe0ae45ee3f14685c7cbfa3f0a2150e52a89c853f4cd8c7a92e6e5f6083044efddfa17391662e3cff6290da679520404","up":true},{"one":"da3e0fd71eb96ba2cab7f920d32f5425d1aad41d00765fdffb0b215d9dd5b60e2bc5929eafebee5b2b5a11aec164e141beff19d828aac7d1fabd3ffb0bfb8450","other":"e9f7e58fda4b504275441d51929fbc98214abdc9ed552c7aa94c600a85d4e791d60c032304b29ae028adccec94984fc9a3d705a81462632f50ef45024eb0f64e","up":true},{"one":"b2bea653b6ec9629c6f934be72fccf30acf836698e21e81dd8085f070ba8259ba43eee43c342738a4b782f5fbddd44caa28f56dffc08237ca7567c965ac3beca","other":"e3f2e777a96b2137b3104b84d5d827d484eac9ee1b585430e09f790d7e26978da12802325927c3c483bc19973e09cd3f70c513c34798e5da650f8d2f0c8c5c47","up":true},{"one":"73319a301ad3cf0ec09549d817c9523d61b74abb0cad87b737d41d900321e52722a84355f6f87bc7a5f848818c89a021bb0f3e5994f67c9a7b5bbfc98188a376","other":"f8052e328014f39157036f3dcecdb23419c0959473a88282605f10add681ef5cbfb1e926b522f98b8401272113b677a67225874d1afb0bff4b11140cc071de44","up":true},{"one":"51ba4faf0988717a37dcddc0a60a70ead33bde310184fc450f9ca73c67f931e6767ad5930bcf409e5aeb613a9ff7a03e47de6fc13b33d8af0b87b38822ae6888","other":"2fdb4382c4bc2950948a8cff13a7df65627bc0b20661cae20fd29acab166c97701594ee3151d75c006ba86d1d68b624b1d1f78e3d1e2fc297844956ef82208a8","up":true},{"one":"f2ea93f43be9d0c3fa21f1496dc13c778977a6afdcba24c8b146de7dca2cdde62a5b792aab969e5b4b6c56f63066b336580d911f206049cc24cac32a25fc4306","other":"896c74ca4cc4cbb9d2b6606d0ebfd6427952c2e16aedbf36933fa3d01f1c505fcd663f3d01c0cf096bef9cfd0bae4595ec7c221cfc362e19a5b7c60614a9658b","up":true},{"one":"f62bd19b0fd052207743ce53c3d48a3a71e9219b75e41a9497a43e6368e559d5487ff1ab644f2df4106b500583e4344515f73187eec773115deb977b4ebc3514","other":"622646c74fdbae39ba191dbafff4906fb683fe0b0f2c303d080f5577a070876c41c8d3786ae7b953e5f682b8ec647727550d47302229ebb9f82bed24cea61132","up":true},{"one":"750ca601f07d65f426f6ea5f34e06238f9d7a931f022f9b0ebc811943d3725500cb3c6f00c8d05eb8d5b353c6534136dff38b9a8d3d4dc5bf49cd96875704d07","other":"3e9c0bbd146d8b1040b4f379eecf802c27c4d0a70e64a9fb2e941a7edab9b00396b0b67fc5c891652743cdba3b342973ed49615b32da54b925954a799240431c","up":true},{"one":"178d5ce398a7114a63a0c953a59932e769891420f6b1544f08c082cd37b531b66757652d279b3036b03b04f8d46eceb0b46fb95646c6668e2921af75c06c3d97","other":"2fdb4382c4bc2950948a8cff13a7df65627bc0b20661cae20fd29acab166c97701594ee3151d75c006ba86d1d68b624b1d1f78e3d1e2fc297844956ef82208a8","up":true},{"one":"3e9c0bbd146d8b1040b4f379eecf802c27c4d0a70e64a9fb2e941a7edab9b00396b0b67fc5c891652743cdba3b342973ed49615b32da54b925954a799240431c","other":"178d5ce398a7114a63a0c953a59932e769891420f6b1544f08c082cd37b531b66757652d279b3036b03b04f8d46eceb0b46fb95646c6668e2921af75c06c3d97","up":true},{"one":"86b84ddf64d301f6a9c4504c59eb4031d3167fb74101abea3b694845a009dc522be7b2e2720097ceea9f36058e160f42a2a438a33034929a5c1a7793c7ccef7b","other":"08900197e74e285a5a8a9cc53fbd420bb35043ab27eb2d9eab22615e736a093abfa235c17f667dcc791cb50b9022082eafd9fba030194cc84f0358b769adc85b","up":true},{"one":"a6ca1d5340f2d7021f541c81cf9aea519675462c8443bb6ddd93919962561b8f5a8431c3ec7e7e7d46c600b653e9a0638d2bb07cf4e29516bf9c4d3653f451b0","other":"3274b5f48e6929e2305e980b558a4ca3c7cf800b75a6445ea2875cb379e127f3e793e9450a11e927682aa91b8af52e9560dece633833e0f207a8a8a38b7b9c54","up":true},{"one":"cbed12dcab0aa04a96ec7e25bc2ee03b337c7b2006391baa7d2aff042c17ec70b82c5fb2dc916d085a7948541719d329f9b528b67ec6adb1ac2cc594d4ef1e42","other":"87fce129511a1be2777052d24b606acdfe7067f4e874ab04674a68664b378ea208975f7269a72af889d3d23cd930b6a181afa2cdef3f9f9491f715bd96ad8dc0","up":true},{"one":"276256790c9317d09ff7802f4ad0a85840fe62527390ce1790e1e3186e8b3f04acfaa41dcd02303d333423678a4037e4f4854676e79ced3232a3dbd772cc2680","other":"896c74ca4cc4cbb9d2b6606d0ebfd6427952c2e16aedbf36933fa3d01f1c505fcd663f3d01c0cf096bef9cfd0bae4595ec7c221cfc362e19a5b7c60614a9658b","up":true},{"one":"670949178a5fad22da03af1e206c814a797c0e9eb4e3371f83612f121e5b56e767706a3ae36628cd0c86dd7bd1586ca4df57e2de27b28a31284ecf9176d330e5","other":"cbed12dcab0aa04a96ec7e25bc2ee03b337c7b2006391baa7d2aff042c17ec70b82c5fb2dc916d085a7948541719d329f9b528b67ec6adb1ac2cc594d4ef1e42","up":true},{"one":"f06ec3a90d34300f9fa2d48aea0c6b5f2f01f7833ffb0fad30e7f57e3916e344f3a4f9efe38e222443b8b00d3c7f5221c672491a129e4958e574afc283bd45b1","other":"09b60de1e85bb6f7d2caf5b1ab58204d7d04531ece300dcd7bcc9157b8b3ef2a182758808a0eec6056034f29f52caadb7c690f498c1c8832ff7a6a9ecff308bd","up":true},{"one":"3c6faa2e75a1699ddadd0e21fd35d3d6215715cfdc2dc89961cfd66773d2541776e785f3ebc833a70e3d1017a4edc571a5d5d9f9fbfc3fa0a8588f6c5023c164","other":"1e3c83cabbe6852c987ae521b7fcb33185cf855c59b6235ebb8e57a6f860ccc159ddc01b4a21d251c8faca4559ceb271e046a51493ba148c0d3aed97ad208969","up":true},{"one":"c93cb2df7ba6de8009872f5f7565891040d42e3b193ef1cdb321a0c167cc8fb8138900982bb8f6918fbaefac6e02dda01ee40f7a6beba1990dd44abe03cc3d01","other":"26cf4ea45b9a76daab82a57126f9c6f8726d2eb973e205ab4ab69c8b8be11a32a7eb5c3807e952cd428ce5ddd88f143d4fc9ff8c3de3d159855675afce715615","up":true},{"one":"1480f62d85ea32226d9f77ccd31780b3e704fb60618a588ae85dcd1c0e84e878c5fc092adfb306e8ebc7abba9ec429cb2447754502ef847cf931467f31fa50b2","other":"eb097186ff58d96a7ead7a7f9c05a44075d84537bd4fd3f82857bf2c45bee1c6dece434a7707cde69e96f02366859cab4c991fdb7615e113a868d4b9c7524a45","up":true},{"one":"a1b2d0c6f24f5924c61e057fc65b994d9a6755560d740018b4c9ad0bb69212ec69974e22cb037dfeb7ea90a4493997f4c94029870bcc5fd47013b51ca0a26b5d","other":"4bd17847bdf60ea93a670a84a0ff8fe028d35228e814d6ebc0ae4fa586ddef03cd79390d541d28ca3c05a7241ffe92ac182e63c251176b40db8fe05fefaa82be","up":true},{"one":"28afc20d8f4779b285bb14870062dbb54796ec77623302e51bc1bafed9e2c35751c8469ffc482718e059875dfa2226195ed10999e251498cba3a444896cb67db","other":"f0299035cbddfdf7a78e5e3a400aaedf2d719d04e907ac0f9f067525e2f9bb913d985308a3a0d05467a64adf58c68a615c6327acf716c23631d0e829903f8b34","up":true},{"one":"18bb6572965f4263c5a4d59a73027abc57a46122125ee58d871e95c993e6a1e8230438ce696a5f8880a08749837268b54319f7b0aa254c1a5bd453a8e9bcf84f","other":"27fb8fcda1986644f985d68430c399f0299644b00b234c355362721081d12f9eb7686eea8f92eabda1d342bf56255e51c07b200c6233f95ac009f15b874eee97","up":true},{"one":"56e8f792ec9a75ec9e91d472b8a4b023655dd68c2a448a33397b125fe3584a5efa1b492e47077b24acfe0396b73e1cb564a6a6b2aee1b457781dfaf6d43fcaed","other":"9c6dcfef0e128dbfeca58b8ac625b08fb447b0d579bd3f18bc0e2be60d1ec2274595d0554ddba0ca7eb660099d3ea146d8076792b46c93841d2ecf8cf608f5ba","up":true},{"one":"5b4de68680c5d1a75cccd5e7a82319c031f5d61d79cbb6532e1254ab81c833c3fafb54390cca7a770e84690c490fcba90482b35321870f8506335a2f57cc052e","other":"3274b5f48e6929e2305e980b558a4ca3c7cf800b75a6445ea2875cb379e127f3e793e9450a11e927682aa91b8af52e9560dece633833e0f207a8a8a38b7b9c54","up":true},{"one":"20f171ab01a814a2856a6cbe7929269f18f6329914289515e2cb9d078ac14ebdae457789dd638c6415b062799114570f556147d4bf9ac850f00b6d0762765ac1","other":"dafb58b2fc8a14f2b23b7df33d28aa7847a08f80e9c21a654d4c97d928e1afe6585644d27f22442cf70d229c32783be6a03c0920be153fc4d9f3b273dfa90ec3","up":true},{"one":"c6d1404873174254c0f15f25804da9a9d90db9c11c5cc895fab613b4deb7820f1733680b4ba9e4b61a664642ed6ee9ff012e13a0619c64ae067be6bab26962c6","other":"670949178a5fad22da03af1e206c814a797c0e9eb4e3371f83612f121e5b56e767706a3ae36628cd0c86dd7bd1586ca4df57e2de27b28a31284ecf9176d330e5","up":true},{"one":"3274b5f48e6929e2305e980b558a4ca3c7cf800b75a6445ea2875cb379e127f3e793e9450a11e927682aa91b8af52e9560dece633833e0f207a8a8a38b7b9c54","other":"670949178a5fad22da03af1e206c814a797c0e9eb4e3371f83612f121e5b56e767706a3ae36628cd0c86dd7bd1586ca4df57e2de27b28a31284ecf9176d330e5","up":true},{"one":"e59940a6dfe35a6214e2e3daba9ad94e630004cd8f029e13a6649a56dc528ff94bc09d8d21a2f14a56b4ff759b60ebf3d27c1029862c183b8416fa3e950bdb55","other":"3e7820bb15c07f515bd63791b66136723dcc9878b3145fe0f238f6b41e3f2f7565ae55ef24f08ae461950ce1ae0c8a80fe5e4fd4f2f88c4acf4a2c94640df239","up":true},{"one":"a5cdff211813e17fadd43ec55a6cf4e97e6ca0c3b2cef0db58923b27d36207fd1a77146efb6093bd94d7eb89cc77d8c735fc64ab098839efc74a00b5e8687555","other":"d90a81a583c82d626b92f27244f027da4a0ae76e6d3bdc1de0af7be01798f1fb04b34ce60c6d8651a39d7a70915438a4aa63e5adf844a9f7e38dbf0b1dba754d","up":true},{"one":"44462055ba68fdef337dd19d8123aace9a12284c13bc97687416b6b4ca0c94234ba7db6823651fc021d6ac1539e0c5321e763a7a12c9e7c8a583aac5369817d8","other":"9c6dcfef0e128dbfeca58b8ac625b08fb447b0d579bd3f18bc0e2be60d1ec2274595d0554ddba0ca7eb660099d3ea146d8076792b46c93841d2ecf8cf608f5ba","up":true},{"one":"9e6c1c6e871638182c4b54ac89352ef5c2bca0a99424a1369013e7c182883da0e8d7ab96b3c8254c31fa315b941d8ddee153157626821fc78c2cae951c1c9053","other":"a05a18161c2d01a0f122548c66509dd1fcf3ee52975035bc79fb059e9613b743a16cd6f5ac54090e68f51bcf76ff21fb3805ba3197a96b4236afb80f791df802","up":true},{"one":"9c3be147f9fe0fa34e553d9e4332969086ea7fa65294b61ca35c9f731f6b81d0b70cdcfe2ba52b6cea3c0de14b7ea40031b5cc40661c4bb821147894130d7bf5","other":"3c6faa2e75a1699ddadd0e21fd35d3d6215715cfdc2dc89961cfd66773d2541776e785f3ebc833a70e3d1017a4edc571a5d5d9f9fbfc3fa0a8588f6c5023c164","up":true},{"one":"08900197e74e285a5a8a9cc53fbd420bb35043ab27eb2d9eab22615e736a093abfa235c17f667dcc791cb50b9022082eafd9fba030194cc84f0358b769adc85b","other":"73be4d2291c68ca4554a86fa170f7595210e1b6bbbeef3c1d5623a2b5d03a8fd6e26caa26afc639c20c8a351a89dad1086f91734f09afab62d28ec17b700fa01","up":true},{"one":"fa897ba112f34839064c6871a4c9504c5d709eff5095a137c6a42726d58eb623af976cb96cc30db67e6ac9347c769f032aa4ebda884285a057059040c008ad3e","other":"9c6dcfef0e128dbfeca58b8ac625b08fb447b0d579bd3f18bc0e2be60d1ec2274595d0554ddba0ca7eb660099d3ea146d8076792b46c93841d2ecf8cf608f5ba","up":true},{"one":"e9f7e58fda4b504275441d51929fbc98214abdc9ed552c7aa94c600a85d4e791d60c032304b29ae028adccec94984fc9a3d705a81462632f50ef45024eb0f64e","other":"e0420ba2a293315d810928a0e09a507c6aaf93977ba2c7598e9b83723b4a66682398ea17542c26767c7ff0f4ca09c537d3cc10dad283f079f1de73e25e87cb5c","up":true},{"one":"155805f787600f9f9518cf8836f491885b64868bfe0023975bcd12776925a424fb5aa3199dc178e83294e97f347a373d05d2422578a08eeeb2d15a178d28964f","other":"afb5754b4748b7ac5628e32b242c90aab0e2fc7da58d8d5c8c775d13d8a6fd32240f1b89021587858168cbe7b3ea7ad07807728655eae0a9907060494a7c99ca","up":true},{"one":"03d2d77c008b5fa1063b1abc3152b879a529fe4fdb2dc174d6d85312264a38ee4cc49b342507a10fff1a4b0730f1ef8e008b0897d97bfd6f70050adb124d3596","other":"3572a22097a313b3adef95a7b6cc679f8d1201a156d764e61a9fbc63d123fb4826f7125402fb6569beed359e1c1e5e6cb6993a75975da6cd4ce15669a2eea758","up":true},{"one":"8e8de10fb3f53bd3a48455ebfa0a38ea5bd28c607e65506b263ece53a24d2361c2af7d7cd207e45b11bf71a3c33fa325fc8fd40a18b9c73019cce219c757c7ef","other":"178d5ce398a7114a63a0c953a59932e769891420f6b1544f08c082cd37b531b66757652d279b3036b03b04f8d46eceb0b46fb95646c6668e2921af75c06c3d97","up":true},{"one":"33e3ab7108ced43102003c3b3192b194100f32b6bcb67bb772ea9696e35721196699cf01e443f7cdf8076ad83aaf7468b75c71d03efb95f4c07cf0742ea9af81","other":"562119edffe8270f6f7a5ad9b13d4c65d643e52a2331d1fee16f7e9b5567f44cfea62df3e8965a22cf08db8fa918f0a0bcae8da2936677e6d25bc88ed85ed2f1","up":true},{"one":"da3e0fd71eb96ba2cab7f920d32f5425d1aad41d00765fdffb0b215d9dd5b60e2bc5929eafebee5b2b5a11aec164e141beff19d828aac7d1fabd3ffb0bfb8450","other":"5b4de68680c5d1a75cccd5e7a82319c031f5d61d79cbb6532e1254ab81c833c3fafb54390cca7a770e84690c490fcba90482b35321870f8506335a2f57cc052e","up":true},{"one":"1480f62d85ea32226d9f77ccd31780b3e704fb60618a588ae85dcd1c0e84e878c5fc092adfb306e8ebc7abba9ec429cb2447754502ef847cf931467f31fa50b2","other":"5771bef7f50439f9b81d2a7bf7060b1ad4b38675d8f6abbac3cc4c215fb0cb5dd07f6873545b42218337556925566025476e2915b7b98e662a3dcd28bebf0eb4","up":true},{"one":"cdd86dea7dde96ff7cc1e3248fd17d107c83f2cc7ce2111c41530448962763309e91a05b5dad4663d0e02db59ed4129ab0c3e1eedc42c654e39d29f99038063b","other":"20bdc859d58d8bf419df64fd6ee1d4363c1d5f403af3abef2720d7d3933924672e12e23e5d76b28e0f6726acf58bdc5eb258cba635e327cbd0b564523305da75","up":true},{"one":"a58a2dd3f5ee2471f0ddd555ffcc45d86e2d8c325585e3fe55eee878b8a626faccce73679d32811fc5d068c153e671673f4cd020f3c7fb37bc6fd9646931646a","other":"da3e0fd71eb96ba2cab7f920d32f5425d1aad41d00765fdffb0b215d9dd5b60e2bc5929eafebee5b2b5a11aec164e141beff19d828aac7d1fabd3ffb0bfb8450","up":true},{"one":"0e8c1a6b70524c4fdc492c74348bac4ccd5d140bd41352607e8cfba45561afb1e6e12f3e2fcf03c1778c9ae5ae19cb9218ee2d613983768f54e3f54e69bb6600","other":"ed1ab28230ed533abf25633508d54f32bbff78a10c7a15fad5c2320cda9d9669c6d0e15689d8885400e64cbcd81730456f8f4bd5c98681d2cd8a8d4e1daec553","up":true},{"one":"1e0a46ff50fb6d9a2c218a851763ff86c42e4d61dddffb7188481febc0f3180bc8f31973d336b2a6e25802acd4fed6d905d89c6d4d7d8080fb12741f9c5ab7e6","other":"7a18392b8338108a996196ee190a93a1b9954c8e05a062c421da513a1828dfa739e7b224878c0670cf74bbc743c7ca7ee8cfee6b6a602fe1f4a82ecfbd38c2f4","up":true},{"one":"5d96577324edf1b5a1626999925982af1e0ba7bed8edcc3f740ba434f4b003cbbe2d632cad327c76e5b490d08c091c4a7b473353ab59139493657eb9525b8be2","other":"5984a296b49bfba30315501ce2ae88ed0392ab2959ac4e7e6b9a29090f344b9dd13873ca137e8317c402cd2e14a61965d5707065b8ded46c41a054731933719f","up":true},{"one":"f04c3ae9fe957a14c249acf3ea2e8407d04d108fc01e75f6d52aaf5073b3450025012d138a75b857473eea4d20e57c99b92bff9041f269d995543d7c67a92ec6","other":"cdd86dea7dde96ff7cc1e3248fd17d107c83f2cc7ce2111c41530448962763309e91a05b5dad4663d0e02db59ed4129ab0c3e1eedc42c654e39d29f99038063b","up":true},{"one":"f7637cdd5ef26de40b9055c1df91a45725670c8df11ae934c0d99d2547c3eb4c42a16dbb2e75bcaf4b1b9347c48db65f549a0623179a08dd8cbad92f5bca08cf","other":"f04c3ae9fe957a14c249acf3ea2e8407d04d108fc01e75f6d52aaf5073b3450025012d138a75b857473eea4d20e57c99b92bff9041f269d995543d7c67a92ec6","up":true},{"one":"56b25623ac935f3a8aac1e2603a6bd15ace1e5714671954b47f2cab960cf47922828f415105602408d0a732a893ebeea6f9afab7f889bb235c81589548d09391","other":"f2ea93f43be9d0c3fa21f1496dc13c778977a6afdcba24c8b146de7dca2cdde62a5b792aab969e5b4b6c56f63066b336580d911f206049cc24cac32a25fc4306","up":true},{"one":"3572a22097a313b3adef95a7b6cc679f8d1201a156d764e61a9fbc63d123fb4826f7125402fb6569beed359e1c1e5e6cb6993a75975da6cd4ce15669a2eea758","other":"b09af9e5552e72f918174963dad58a4492d3afa120f78e43820df7bff7fae9f6b52bc6c8c73d3a9af91d20134f4ff1b037db2ef0bc3d8c495a771d63de678bc0","up":true},{"one":"f8052e328014f39157036f3dcecdb23419c0959473a88282605f10add681ef5cbfb1e926b522f98b8401272113b677a67225874d1afb0bff4b11140cc071de44","other":"f0b2f1e8d46be656109adb18c60677ac9eb8fce7f42e15d9dbb25f94b4e426064780eaf32b79954b9bb72ea89953175da8de35380aaba18931cca374a7de2b11","up":true},{"one":"cbed12dcab0aa04a96ec7e25bc2ee03b337c7b2006391baa7d2aff042c17ec70b82c5fb2dc916d085a7948541719d329f9b528b67ec6adb1ac2cc594d4ef1e42","other":"155805f787600f9f9518cf8836f491885b64868bfe0023975bcd12776925a424fb5aa3199dc178e83294e97f347a373d05d2422578a08eeeb2d15a178d28964f","up":true},{"one":"750ca601f07d65f426f6ea5f34e06238f9d7a931f022f9b0ebc811943d3725500cb3c6f00c8d05eb8d5b353c6534136dff38b9a8d3d4dc5bf49cd96875704d07","other":"dafb58b2fc8a14f2b23b7df33d28aa7847a08f80e9c21a654d4c97d928e1afe6585644d27f22442cf70d229c32783be6a03c0920be153fc4d9f3b273dfa90ec3","up":true},{"one":"26cf4ea45b9a76daab82a57126f9c6f8726d2eb973e205ab4ab69c8b8be11a32a7eb5c3807e952cd428ce5ddd88f143d4fc9ff8c3de3d159855675afce715615","other":"a40391285d1a97f1fb368b20c8e4d02be1bdebc0db41f00f99aac2f01893dc12256cd5a711117a981fbb3f9dfea18c19cf3603e925dbd67c4032b22b41eab8d5","up":true},{"one":"c89dbada7195464e732671ac6fff014cacfb4c879b63b6b84e7c1bce367522f759bd06e504b15f43a1735c6322356747fa5c4951882d4fd6cdf6f7cf13726719","other":"178d5ce398a7114a63a0c953a59932e769891420f6b1544f08c082cd37b531b66757652d279b3036b03b04f8d46eceb0b46fb95646c6668e2921af75c06c3d97","up":true},{"one":"82a774be7146766585d2bec6b69b7803aa956f492a53d8ed5f071becdbbc617562885d8430f0afd505210aab7b032428fbea32c82dffbd12d9ccba776ef4729b","other":"1e0a46ff50fb6d9a2c218a851763ff86c42e4d61dddffb7188481febc0f3180bc8f31973d336b2a6e25802acd4fed6d905d89c6d4d7d8080fb12741f9c5ab7e6","up":true},{"one":"4448a59bde9edb93edcdb4a77f3e2277b9c01ffea45496ee0533eb5192955a08a0f982e25cf772e0dae68735a55b7acd221f6ba7b134f1e999087bee182330e8","other":"622646c74fdbae39ba191dbafff4906fb683fe0b0f2c303d080f5577a070876c41c8d3786ae7b953e5f682b8ec647727550d47302229ebb9f82bed24cea61132","up":true},{"one":"a40391285d1a97f1fb368b20c8e4d02be1bdebc0db41f00f99aac2f01893dc12256cd5a711117a981fbb3f9dfea18c19cf3603e925dbd67c4032b22b41eab8d5","other":"ab3814579882e9fd8d464f4f3c8a421be37822ba7f42c5f5e787e81125ec032f9ccf90a138c0b57f0a813b55b583f80d66284f795e2c82d80d2869e1fc770be5","up":true},{"one":"20f171ab01a814a2856a6cbe7929269f18f6329914289515e2cb9d078ac14ebdae457789dd638c6415b062799114570f556147d4bf9ac850f00b6d0762765ac1","other":"e3f2e777a96b2137b3104b84d5d827d484eac9ee1b585430e09f790d7e26978da12802325927c3c483bc19973e09cd3f70c513c34798e5da650f8d2f0c8c5c47","up":true},{"one":"1e3c83cabbe6852c987ae521b7fcb33185cf855c59b6235ebb8e57a6f860ccc159ddc01b4a21d251c8faca4559ceb271e046a51493ba148c0d3aed97ad208969","other":"73be4d2291c68ca4554a86fa170f7595210e1b6bbbeef3c1d5623a2b5d03a8fd6e26caa26afc639c20c8a351a89dad1086f91734f09afab62d28ec17b700fa01","up":true},{"one":"f6a07a1d361a4671e997d5eaadae61736291aff3896cb69f06bbc19bf7536dd152e0b15422b2fd9f8a9d2f9a251c9a07d0140319900e2cc9f25a59025c7dc91f","other":"ed1ab28230ed533abf25633508d54f32bbff78a10c7a15fad5c2320cda9d9669c6d0e15689d8885400e64cbcd81730456f8f4bd5c98681d2cd8a8d4e1daec553","up":true},{"one":"20bdc859d58d8bf419df64fd6ee1d4363c1d5f403af3abef2720d7d3933924672e12e23e5d76b28e0f6726acf58bdc5eb258cba635e327cbd0b564523305da75","other":"b09af9e5552e72f918174963dad58a4492d3afa120f78e43820df7bff7fae9f6b52bc6c8c73d3a9af91d20134f4ff1b037db2ef0bc3d8c495a771d63de678bc0","up":true},{"one":"896c74ca4cc4cbb9d2b6606d0ebfd6427952c2e16aedbf36933fa3d01f1c505fcd663f3d01c0cf096bef9cfd0bae4595ec7c221cfc362e19a5b7c60614a9658b","other":"6ce3a68cb1e2924ad97f22006094c709a3dd8b4ca1546fbb037f841a9e5ac62def242015dbf6221bda610153db064edcbb58a78a35a06077b8c02bf5b2a33c04","up":true},{"one":"3540d888c3207d6df233afd1164ff9dde2551730862772547e04f7311de364968e113f38a7dea1ab0916a7f8307017de5b49578fa4ebcc39651e541fde51be48","other":"f0299035cbddfdf7a78e5e3a400aaedf2d719d04e907ac0f9f067525e2f9bb913d985308a3a0d05467a64adf58c68a615c6327acf716c23631d0e829903f8b34","up":true},{"one":"03e478a3aae82e06e215e40272a420037a61442d11c49c367a5ee6a21868d29a17ea8b9284f013d020c4740f296a6a22bc64d33d1c2807f9ab8dc48c0cfec18a","other":"eb097186ff58d96a7ead7a7f9c05a44075d84537bd4fd3f82857bf2c45bee1c6dece434a7707cde69e96f02366859cab4c991fdb7615e113a868d4b9c7524a45","up":true},{"one":"dafb58b2fc8a14f2b23b7df33d28aa7847a08f80e9c21a654d4c97d928e1afe6585644d27f22442cf70d229c32783be6a03c0920be153fc4d9f3b273dfa90ec3","other":"f8052e328014f39157036f3dcecdb23419c0959473a88282605f10add681ef5cbfb1e926b522f98b8401272113b677a67225874d1afb0bff4b11140cc071de44","up":true},{"one":"56b25623ac935f3a8aac1e2603a6bd15ace1e5714671954b47f2cab960cf47922828f415105602408d0a732a893ebeea6f9afab7f889bb235c81589548d09391","other":"44462055ba68fdef337dd19d8123aace9a12284c13bc97687416b6b4ca0c94234ba7db6823651fc021d6ac1539e0c5321e763a7a12c9e7c8a583aac5369817d8","up":true},{"one":"077d2d032874e5ce70e9b928b7fe72c0326ba92394e16245e31d48b5731d3d32bfd86acf40825decff54bcd735e9ebfd94eba677c418ea7007baec9db4af676d","other":"1955bedf0bc9044b13a2c16158087123197c74147c86aa3b9389d308a364e80edbc573bcc836d8a262a77f3c9233ebddb1b82eca83cd0a0e4bda6564c443bb70","up":true},{"one":"178d5ce398a7114a63a0c953a59932e769891420f6b1544f08c082cd37b531b66757652d279b3036b03b04f8d46eceb0b46fb95646c6668e2921af75c06c3d97","other":"622646c74fdbae39ba191dbafff4906fb683fe0b0f2c303d080f5577a070876c41c8d3786ae7b953e5f682b8ec647727550d47302229ebb9f82bed24cea61132","up":true},{"one":"665c3288c14dc1c17d85d17d634910f42183482c7e77c47e68f9b4f475b93e8c152246b9e34781606315ff6ef0f8360342500d15e4a2d67d9df6b72f30af64a7","other":"41994605708232b4ca7448c3bc0760a7b86bf26d442091e5ce6e92eac94925721d7e0eca04bdd03bb1bba1ef92deeccd4bf1b7c6c3318b7e8d031965c6646761","up":true},{"one":"b2bea653b6ec9629c6f934be72fccf30acf836698e21e81dd8085f070ba8259ba43eee43c342738a4b782f5fbddd44caa28f56dffc08237ca7567c965ac3beca","other":"caad8529d498a4a1e1ba7573689a913500bd409345ef8e3656abca748269eb73b919282f7f2eb0087f81f7bc52c367657ac8be0cdac65d2490c7c50c874444b7","up":true},{"one":"da3e0fd71eb96ba2cab7f920d32f5425d1aad41d00765fdffb0b215d9dd5b60e2bc5929eafebee5b2b5a11aec164e141beff19d828aac7d1fabd3ffb0bfb8450","other":"33e3ab7108ced43102003c3b3192b194100f32b6bcb67bb772ea9696e35721196699cf01e443f7cdf8076ad83aaf7468b75c71d03efb95f4c07cf0742ea9af81","up":true},{"one":"1480f62d85ea32226d9f77ccd31780b3e704fb60618a588ae85dcd1c0e84e878c5fc092adfb306e8ebc7abba9ec429cb2447754502ef847cf931467f31fa50b2","other":"7a18392b8338108a996196ee190a93a1b9954c8e05a062c421da513a1828dfa739e7b224878c0670cf74bbc743c7ca7ee8cfee6b6a602fe1f4a82ecfbd38c2f4","up":true},{"one":"27fb8fcda1986644f985d68430c399f0299644b00b234c355362721081d12f9eb7686eea8f92eabda1d342bf56255e51c07b200c6233f95ac009f15b874eee97","other":"670949178a5fad22da03af1e206c814a797c0e9eb4e3371f83612f121e5b56e767706a3ae36628cd0c86dd7bd1586ca4df57e2de27b28a31284ecf9176d330e5","up":true},{"one":"da15d60a4b9a8816ce24c20f6c941c51229c1fb5e070b8b29be2977c2f7b41f8f17e4b6efe75f465e7935ded1ba17472f046eac73393db7197018fa86d11c31f","other":"f62bd19b0fd052207743ce53c3d48a3a71e9219b75e41a9497a43e6368e559d5487ff1ab644f2df4106b500583e4344515f73187eec773115deb977b4ebc3514","up":true},{"one":"59730132a01ba848a3c050bb6234bca9a72deba33716960fc3ec89b186bfcd313b9bbf049939d5805ff98db2c53a9421ce6ec97d8b4cdbaea53ba264d80d0734","other":"f0299035cbddfdf7a78e5e3a400aaedf2d719d04e907ac0f9f067525e2f9bb913d985308a3a0d05467a64adf58c68a615c6327acf716c23631d0e829903f8b34","up":true},{"one":"8f625a4e4f4fd980c796d3aa535e58a39722492480cf6982d43fab02de63a5b4c1b5c7cd8402171dd792bb5d9c3e2bdd38176c061dbe3e5b0592af1339e3fd82","other":"340420ee18d55913f790d0fcc2305b40b1e7bef2eddb79dda57801690aeeead693ebd1a9ff8557671f5ae136b3e65733306924bd00444cbc6e7c6235e5a2c77f","up":true},{"one":"87fce129511a1be2777052d24b606acdfe7067f4e874ab04674a68664b378ea208975f7269a72af889d3d23cd930b6a181afa2cdef3f9f9491f715bd96ad8dc0","other":"d8cfadac10473b31a4560c711636a05615f13054388065344642ff1d04246fb62eafeec06805264eafead111ed8134e11a8e21f42a0eb950c23b142e627bd8cb","up":true},{"one":"eb097186ff58d96a7ead7a7f9c05a44075d84537bd4fd3f82857bf2c45bee1c6dece434a7707cde69e96f02366859cab4c991fdb7615e113a868d4b9c7524a45","other":"155805f787600f9f9518cf8836f491885b64868bfe0023975bcd12776925a424fb5aa3199dc178e83294e97f347a373d05d2422578a08eeeb2d15a178d28964f","up":true},{"one":"a5cdff211813e17fadd43ec55a6cf4e97e6ca0c3b2cef0db58923b27d36207fd1a77146efb6093bd94d7eb89cc77d8c735fc64ab098839efc74a00b5e8687555","other":"31ac37862416c0e229c4a088ec179f23bdd1bf12dd464eb11c630ad531d7c3438671862e5458e2f6fbb32b857f857e6b8c17e5d93eb29a0e78bb5a65d7eb648c","up":true},{"one":"87e696a354d249493217dc4e0190082f30e09616873803efa376871d4b34f86f0eeb4643d4822d8a0fbcdedb27cd6ba5438e98943d358d960c4835e82261c93e","other":"f62bd19b0fd052207743ce53c3d48a3a71e9219b75e41a9497a43e6368e559d5487ff1ab644f2df4106b500583e4344515f73187eec773115deb977b4ebc3514","up":true},{"one":"750ca601f07d65f426f6ea5f34e06238f9d7a931f022f9b0ebc811943d3725500cb3c6f00c8d05eb8d5b353c6534136dff38b9a8d3d4dc5bf49cd96875704d07","other":"87fce129511a1be2777052d24b606acdfe7067f4e874ab04674a68664b378ea208975f7269a72af889d3d23cd930b6a181afa2cdef3f9f9491f715bd96ad8dc0","up":true},{"one":"03d2d77c008b5fa1063b1abc3152b879a529fe4fdb2dc174d6d85312264a38ee4cc49b342507a10fff1a4b0730f1ef8e008b0897d97bfd6f70050adb124d3596","other":"44462055ba68fdef337dd19d8123aace9a12284c13bc97687416b6b4ca0c94234ba7db6823651fc021d6ac1539e0c5321e763a7a12c9e7c8a583aac5369817d8","up":true},{"one":"622646c74fdbae39ba191dbafff4906fb683fe0b0f2c303d080f5577a070876c41c8d3786ae7b953e5f682b8ec647727550d47302229ebb9f82bed24cea61132","other":"f06ec3a90d34300f9fa2d48aea0c6b5f2f01f7833ffb0fad30e7f57e3916e344f3a4f9efe38e222443b8b00d3c7f5221c672491a129e4958e574afc283bd45b1","up":true},{"one":"340420ee18d55913f790d0fcc2305b40b1e7bef2eddb79dda57801690aeeead693ebd1a9ff8557671f5ae136b3e65733306924bd00444cbc6e7c6235e5a2c77f","other":"77327983685f39f006806170fe351063a58ff1bd8dedc222d538e86cfd18abdfefd548328f25fc5afde8170aa5c35311353019468f2b439c331837ddfbb25a52","up":true},{"one":"b38213eaa5b419de787b70073ad8c7c819e48c5f76dec1507b54f1d7cb027211facbe7a170ac50212abe130935e8947d5a19d6b13790114e71cc18357902a889","other":"f0299035cbddfdf7a78e5e3a400aaedf2d719d04e907ac0f9f067525e2f9bb913d985308a3a0d05467a64adf58c68a615c6327acf716c23631d0e829903f8b34","up":true},{"one":"1e0a46ff50fb6d9a2c218a851763ff86c42e4d61dddffb7188481febc0f3180bc8f31973d336b2a6e25802acd4fed6d905d89c6d4d7d8080fb12741f9c5ab7e6","other":"afb5754b4748b7ac5628e32b242c90aab0e2fc7da58d8d5c8c775d13d8a6fd32240f1b89021587858168cbe7b3ea7ad07807728655eae0a9907060494a7c99ca","up":true},{"one":"d90a81a583c82d626b92f27244f027da4a0ae76e6d3bdc1de0af7be01798f1fb04b34ce60c6d8651a39d7a70915438a4aa63e5adf844a9f7e38dbf0b1dba754d","other":"2fdb4382c4bc2950948a8cff13a7df65627bc0b20661cae20fd29acab166c97701594ee3151d75c006ba86d1d68b624b1d1f78e3d1e2fc297844956ef82208a8","up":true},{"one":"3e9c0bbd146d8b1040b4f379eecf802c27c4d0a70e64a9fb2e941a7edab9b00396b0b67fc5c891652743cdba3b342973ed49615b32da54b925954a799240431c","other":"03d2d77c008b5fa1063b1abc3152b879a529fe4fdb2dc174d6d85312264a38ee4cc49b342507a10fff1a4b0730f1ef8e008b0897d97bfd6f70050adb124d3596","up":true},{"one":"7a18392b8338108a996196ee190a93a1b9954c8e05a062c421da513a1828dfa739e7b224878c0670cf74bbc743c7ca7ee8cfee6b6a602fe1f4a82ecfbd38c2f4","other":"27fb8fcda1986644f985d68430c399f0299644b00b234c355362721081d12f9eb7686eea8f92eabda1d342bf56255e51c07b200c6233f95ac009f15b874eee97","up":true},{"one":"2d6d55edd34c0d9a0130b4806e409bbe18cdda5c2b221cf46136718ec20ffc9d8e92838d78aff92fbcc85f5d081da361dd1e3d7f3d4e1ea57877d6bb7aa0b6f7","other":"2fdb4382c4bc2950948a8cff13a7df65627bc0b20661cae20fd29acab166c97701594ee3151d75c006ba86d1d68b624b1d1f78e3d1e2fc297844956ef82208a8","up":true},{"one":"9e6c1c6e871638182c4b54ac89352ef5c2bca0a99424a1369013e7c182883da0e8d7ab96b3c8254c31fa315b941d8ddee153157626821fc78c2cae951c1c9053","other":"c89dbada7195464e732671ac6fff014cacfb4c879b63b6b84e7c1bce367522f759bd06e504b15f43a1735c6322356747fa5c4951882d4fd6cdf6f7cf13726719","up":true},{"one":"4de606aa7e722197b918c5f7f0db86a3081d48e89d21428b04f19c3ff3755eac0bddbff5fad8bda94b9e57f58fba2fecdbabbf710f7afb381bf4f1a4fe55cd93","other":"340420ee18d55913f790d0fcc2305b40b1e7bef2eddb79dda57801690aeeead693ebd1a9ff8557671f5ae136b3e65733306924bd00444cbc6e7c6235e5a2c77f","up":true},{"one":"cbed12dcab0aa04a96ec7e25bc2ee03b337c7b2006391baa7d2aff042c17ec70b82c5fb2dc916d085a7948541719d329f9b528b67ec6adb1ac2cc594d4ef1e42","other":"077d2d032874e5ce70e9b928b7fe72c0326ba92394e16245e31d48b5731d3d32bfd86acf40825decff54bcd735e9ebfd94eba677c418ea7007baec9db4af676d","up":true},{"one":"09b60de1e85bb6f7d2caf5b1ab58204d7d04531ece300dcd7bcc9157b8b3ef2a182758808a0eec6056034f29f52caadb7c690f498c1c8832ff7a6a9ecff308bd","other":"31ac37862416c0e229c4a088ec179f23bdd1bf12dd464eb11c630ad531d7c3438671862e5458e2f6fbb32b857f857e6b8c17e5d93eb29a0e78bb5a65d7eb648c","up":true},{"one":"c89dbada7195464e732671ac6fff014cacfb4c879b63b6b84e7c1bce367522f759bd06e504b15f43a1735c6322356747fa5c4951882d4fd6cdf6f7cf13726719","other":"03d2d77c008b5fa1063b1abc3152b879a529fe4fdb2dc174d6d85312264a38ee4cc49b342507a10fff1a4b0730f1ef8e008b0897d97bfd6f70050adb124d3596","up":true},{"one":"c93cb2df7ba6de8009872f5f7565891040d42e3b193ef1cdb321a0c167cc8fb8138900982bb8f6918fbaefac6e02dda01ee40f7a6beba1990dd44abe03cc3d01","other":"20f171ab01a814a2856a6cbe7929269f18f6329914289515e2cb9d078ac14ebdae457789dd638c6415b062799114570f556147d4bf9ac850f00b6d0762765ac1","up":true},{"one":"a58a2dd3f5ee2471f0ddd555ffcc45d86e2d8c325585e3fe55eee878b8a626faccce73679d32811fc5d068c153e671673f4cd020f3c7fb37bc6fd9646931646a","other":"5b4de68680c5d1a75cccd5e7a82319c031f5d61d79cbb6532e1254ab81c833c3fafb54390cca7a770e84690c490fcba90482b35321870f8506335a2f57cc052e","up":true},{"one":"56e8f792ec9a75ec9e91d472b8a4b023655dd68c2a448a33397b125fe3584a5efa1b492e47077b24acfe0396b73e1cb564a6a6b2aee1b457781dfaf6d43fcaed","other":"3e7820bb15c07f515bd63791b66136723dcc9878b3145fe0f238f6b41e3f2f7565ae55ef24f08ae461950ce1ae0c8a80fe5e4fd4f2f88c4acf4a2c94640df239","up":true},{"one":"5b4de68680c5d1a75cccd5e7a82319c031f5d61d79cbb6532e1254ab81c833c3fafb54390cca7a770e84690c490fcba90482b35321870f8506335a2f57cc052e","other":"c6d1404873174254c0f15f25804da9a9d90db9c11c5cc895fab613b4deb7820f1733680b4ba9e4b61a664642ed6ee9ff012e13a0619c64ae067be6bab26962c6","up":true},{"one":"f2ea93f43be9d0c3fa21f1496dc13c778977a6afdcba24c8b146de7dca2cdde62a5b792aab969e5b4b6c56f63066b336580d911f206049cc24cac32a25fc4306","other":"d71c50805f284ed3a759e2e81f220fbc73d6d0a7a261b4c9e7878c3da143cfc07afa83e1635b6a45530f71a60b9f17c485a2fd6617c6c2bff82bacc71c208087","up":true},{"one":"03d2d77c008b5fa1063b1abc3152b879a529fe4fdb2dc174d6d85312264a38ee4cc49b342507a10fff1a4b0730f1ef8e008b0897d97bfd6f70050adb124d3596","other":"f06ec3a90d34300f9fa2d48aea0c6b5f2f01f7833ffb0fad30e7f57e3916e344f3a4f9efe38e222443b8b00d3c7f5221c672491a129e4958e574afc283bd45b1","up":true},{"one":"59730132a01ba848a3c050bb6234bca9a72deba33716960fc3ec89b186bfcd313b9bbf049939d5805ff98db2c53a9421ce6ec97d8b4cdbaea53ba264d80d0734","other":"41994605708232b4ca7448c3bc0760a7b86bf26d442091e5ce6e92eac94925721d7e0eca04bdd03bb1bba1ef92deeccd4bf1b7c6c3318b7e8d031965c6646761","up":true},{"one":"c773af3af01ee8ab9fa8d06987baf4f10c394fdd386d69b7a7362f4b68fd6fc082337d3b33a19d584c5801a3e9198225d7b61f6629e34ce823be70908339f4c7","other":"a5cdff211813e17fadd43ec55a6cf4e97e6ca0c3b2cef0db58923b27d36207fd1a77146efb6093bd94d7eb89cc77d8c735fc64ab098839efc74a00b5e8687555","up":true},{"one":"5d96577324edf1b5a1626999925982af1e0ba7bed8edcc3f740ba434f4b003cbbe2d632cad327c76e5b490d08c091c4a7b473353ab59139493657eb9525b8be2","other":"077d2d032874e5ce70e9b928b7fe72c0326ba92394e16245e31d48b5731d3d32bfd86acf40825decff54bcd735e9ebfd94eba677c418ea7007baec9db4af676d","up":true},{"one":"eb097186ff58d96a7ead7a7f9c05a44075d84537bd4fd3f82857bf2c45bee1c6dece434a7707cde69e96f02366859cab4c991fdb7615e113a868d4b9c7524a45","other":"77327983685f39f006806170fe351063a58ff1bd8dedc222d538e86cfd18abdfefd548328f25fc5afde8170aa5c35311353019468f2b439c331837ddfbb25a52","up":true},{"one":"a6ca1d5340f2d7021f541c81cf9aea519675462c8443bb6ddd93919962561b8f5a8431c3ec7e7e7d46c600b653e9a0638d2bb07cf4e29516bf9c4d3653f451b0","other":"c6d1404873174254c0f15f25804da9a9d90db9c11c5cc895fab613b4deb7820f1733680b4ba9e4b61a664642ed6ee9ff012e13a0619c64ae067be6bab26962c6","up":true},{"one":"87e696a354d249493217dc4e0190082f30e09616873803efa376871d4b34f86f0eeb4643d4822d8a0fbcdedb27cd6ba5438e98943d358d960c4835e82261c93e","other":"44462055ba68fdef337dd19d8123aace9a12284c13bc97687416b6b4ca0c94234ba7db6823651fc021d6ac1539e0c5321e763a7a12c9e7c8a583aac5369817d8","up":true},{"one":"750ca601f07d65f426f6ea5f34e06238f9d7a931f022f9b0ebc811943d3725500cb3c6f00c8d05eb8d5b353c6534136dff38b9a8d3d4dc5bf49cd96875704d07","other":"155805f787600f9f9518cf8836f491885b64868bfe0023975bcd12776925a424fb5aa3199dc178e83294e97f347a373d05d2422578a08eeeb2d15a178d28964f","up":true},{"one":"276256790c9317d09ff7802f4ad0a85840fe62527390ce1790e1e3186e8b3f04acfaa41dcd02303d333423678a4037e4f4854676e79ced3232a3dbd772cc2680","other":"08900197e74e285a5a8a9cc53fbd420bb35043ab27eb2d9eab22615e736a093abfa235c17f667dcc791cb50b9022082eafd9fba030194cc84f0358b769adc85b","up":true},{"one":"670949178a5fad22da03af1e206c814a797c0e9eb4e3371f83612f121e5b56e767706a3ae36628cd0c86dd7bd1586ca4df57e2de27b28a31284ecf9176d330e5","other":"665c3288c14dc1c17d85d17d634910f42183482c7e77c47e68f9b4f475b93e8c152246b9e34781606315ff6ef0f8360342500d15e4a2d67d9df6b72f30af64a7","up":true},{"one":"26cf4ea45b9a76daab82a57126f9c6f8726d2eb973e205ab4ab69c8b8be11a32a7eb5c3807e952cd428ce5ddd88f143d4fc9ff8c3de3d159855675afce715615","other":"077bcadade93e0d361e94f76dff464d61912bc067ce2ce17ebcabd757cca201cd64624ea809d99dd8ecb749d40528db9b3eb503ef5ec05e8845044cfaef720dc","up":true},{"one":"82a774be7146766585d2bec6b69b7803aa956f492a53d8ed5f071becdbbc617562885d8430f0afd505210aab7b032428fbea32c82dffbd12d9ccba776ef4729b","other":"7a18392b8338108a996196ee190a93a1b9954c8e05a062c421da513a1828dfa739e7b224878c0670cf74bbc743c7ca7ee8cfee6b6a602fe1f4a82ecfbd38c2f4","up":true},{"one":"c89dbada7195464e732671ac6fff014cacfb4c879b63b6b84e7c1bce367522f759bd06e504b15f43a1735c6322356747fa5c4951882d4fd6cdf6f7cf13726719","other":"93987e431a0058f2e942ccf8d3486d249cd2734d6494131b343e2c3a8fdd86cfcb12d0aaaf8fcb911ad3cdd682cc82118198195a7fdc915ab7853223f012eab6","up":true},{"one":"28afc20d8f4779b285bb14870062dbb54796ec77623302e51bc1bafed9e2c35751c8469ffc482718e059875dfa2226195ed10999e251498cba3a444896cb67db","other":"82a774be7146766585d2bec6b69b7803aa956f492a53d8ed5f071becdbbc617562885d8430f0afd505210aab7b032428fbea32c82dffbd12d9ccba776ef4729b","up":true},{"one":"cdd86dea7dde96ff7cc1e3248fd17d107c83f2cc7ce2111c41530448962763309e91a05b5dad4663d0e02db59ed4129ab0c3e1eedc42c654e39d29f99038063b","other":"26cf4ea45b9a76daab82a57126f9c6f8726d2eb973e205ab4ab69c8b8be11a32a7eb5c3807e952cd428ce5ddd88f143d4fc9ff8c3de3d159855675afce715615","up":true},{"one":"51ba4faf0988717a37dcddc0a60a70ead33bde310184fc450f9ca73c67f931e6767ad5930bcf409e5aeb613a9ff7a03e47de6fc13b33d8af0b87b38822ae6888","other":"09b60de1e85bb6f7d2caf5b1ab58204d7d04531ece300dcd7bcc9157b8b3ef2a182758808a0eec6056034f29f52caadb7c690f498c1c8832ff7a6a9ecff308bd","up":true},{"one":"da15d60a4b9a8816ce24c20f6c941c51229c1fb5e070b8b29be2977c2f7b41f8f17e4b6efe75f465e7935ded1ba17472f046eac73393db7197018fa86d11c31f","other":"ce1309c8505b446363ae37cd3b1ee3e03ced537bed20aca5d8c4be2133917c408845ef5d0f65876974be2803dfb824827cf5c5a2d050d6ef26cdabcbf3a2dc31","up":true},{"one":"20bdc859d58d8bf419df64fd6ee1d4363c1d5f403af3abef2720d7d3933924672e12e23e5d76b28e0f6726acf58bdc5eb258cba635e327cbd0b564523305da75","other":"188bf77c9c1e45f009efe7aefdb040bdb47763980fe7eb0851295d657fa2a8978efbd2997c1dc30f4f0874eecf9ca9550487cf41da237b84d071963d35b6baff","up":true},{"one":"5d96577324edf1b5a1626999925982af1e0ba7bed8edcc3f740ba434f4b003cbbe2d632cad327c76e5b490d08c091c4a7b473353ab59139493657eb9525b8be2","other":"f0b2f1e8d46be656109adb18c60677ac9eb8fce7f42e15d9dbb25f94b4e426064780eaf32b79954b9bb72ea89953175da8de35380aaba18931cca374a7de2b11","up":true},{"one":"87fce129511a1be2777052d24b606acdfe7067f4e874ab04674a68664b378ea208975f7269a72af889d3d23cd930b6a181afa2cdef3f9f9491f715bd96ad8dc0","other":"3e9c0bbd146d8b1040b4f379eecf802c27c4d0a70e64a9fb2e941a7edab9b00396b0b67fc5c891652743cdba3b342973ed49615b32da54b925954a799240431c","up":true},{"one":"f04c3ae9fe957a14c249acf3ea2e8407d04d108fc01e75f6d52aaf5073b3450025012d138a75b857473eea4d20e57c99b92bff9041f269d995543d7c67a92ec6","other":"20f171ab01a814a2856a6cbe7929269f18f6329914289515e2cb9d078ac14ebdae457789dd638c6415b062799114570f556147d4bf9ac850f00b6d0762765ac1","up":true},{"one":"44462055ba68fdef337dd19d8123aace9a12284c13bc97687416b6b4ca0c94234ba7db6823651fc021d6ac1539e0c5321e763a7a12c9e7c8a583aac5369817d8","other":"51ba4faf0988717a37dcddc0a60a70ead33bde310184fc450f9ca73c67f931e6767ad5930bcf409e5aeb613a9ff7a03e47de6fc13b33d8af0b87b38822ae6888","up":true},{"one":"f7637cdd5ef26de40b9055c1df91a45725670c8df11ae934c0d99d2547c3eb4c42a16dbb2e75bcaf4b1b9347c48db65f549a0623179a08dd8cbad92f5bca08cf","other":"c93cb2df7ba6de8009872f5f7565891040d42e3b193ef1cdb321a0c167cc8fb8138900982bb8f6918fbaefac6e02dda01ee40f7a6beba1990dd44abe03cc3d01","up":true},{"one":"08900197e74e285a5a8a9cc53fbd420bb35043ab27eb2d9eab22615e736a093abfa235c17f667dcc791cb50b9022082eafd9fba030194cc84f0358b769adc85b","other":"805d784527be4e32e84ddf045baee1ccf348cdf8288de3aae1a5379f762576b957525ef358d9b42c68a93394017880adc09bb2b1b5e01102dc7e4240baf2af95","up":true},{"one":"f06ec3a90d34300f9fa2d48aea0c6b5f2f01f7833ffb0fad30e7f57e3916e344f3a4f9efe38e222443b8b00d3c7f5221c672491a129e4958e574afc283bd45b1","other":"8e8de10fb3f53bd3a48455ebfa0a38ea5bd28c607e65506b263ece53a24d2361c2af7d7cd207e45b11bf71a3c33fa325fc8fd40a18b9c73019cce219c757c7ef","up":true},{"one":"fa897ba112f34839064c6871a4c9504c5d709eff5095a137c6a42726d58eb623af976cb96cc30db67e6ac9347c769f032aa4ebda884285a057059040c008ad3e","other":"f0b2f1e8d46be656109adb18c60677ac9eb8fce7f42e15d9dbb25f94b4e426064780eaf32b79954b9bb72ea89953175da8de35380aaba18931cca374a7de2b11","up":true},{"one":"665c3288c14dc1c17d85d17d634910f42183482c7e77c47e68f9b4f475b93e8c152246b9e34781606315ff6ef0f8360342500d15e4a2d67d9df6b72f30af64a7","other":"750ca601f07d65f426f6ea5f34e06238f9d7a931f022f9b0ebc811943d3725500cb3c6f00c8d05eb8d5b353c6534136dff38b9a8d3d4dc5bf49cd96875704d07","up":true},{"one":"4448a59bde9edb93edcdb4a77f3e2277b9c01ffea45496ee0533eb5192955a08a0f982e25cf772e0dae68735a55b7acd221f6ba7b134f1e999087bee182330e8","other":"b09af9e5552e72f918174963dad58a4492d3afa120f78e43820df7bff7fae9f6b52bc6c8c73d3a9af91d20134f4ff1b037db2ef0bc3d8c495a771d63de678bc0","up":true},{"one":"a40391285d1a97f1fb368b20c8e4d02be1bdebc0db41f00f99aac2f01893dc12256cd5a711117a981fbb3f9dfea18c19cf3603e925dbd67c4032b22b41eab8d5","other":"8f625a4e4f4fd980c796d3aa535e58a39722492480cf6982d43fab02de63a5b4c1b5c7cd8402171dd792bb5d9c3e2bdd38176c061dbe3e5b0592af1339e3fd82","up":true},{"one":"340420ee18d55913f790d0fcc2305b40b1e7bef2eddb79dda57801690aeeead693ebd1a9ff8557671f5ae136b3e65733306924bd00444cbc6e7c6235e5a2c77f","other":"bf1e6eeb8b229f63b49213db499b71dcfe0ae45ee3f14685c7cbfa3f0a2150e52a89c853f4cd8c7a92e6e5f6083044efddfa17391662e3cff6290da679520404","up":true},{"one":"33e3ab7108ced43102003c3b3192b194100f32b6bcb67bb772ea9696e35721196699cf01e443f7cdf8076ad83aaf7468b75c71d03efb95f4c07cf0742ea9af81","other":"2502fc8ee0ccda79ad1dbd9c7cec625da85980b9116bdd56dc367d508039e25e5f65183293006e5b0df72fa9037a48bd2b133a757940d3587ff77ae2392e3eaf","up":true},{"one":"18bb6572965f4263c5a4d59a73027abc57a46122125ee58d871e95c993e6a1e8230438ce696a5f8880a08749837268b54319f7b0aa254c1a5bd453a8e9bcf84f","other":"d8cfadac10473b31a4560c711636a05615f13054388065344642ff1d04246fb62eafeec06805264eafead111ed8134e11a8e21f42a0eb950c23b142e627bd8cb","up":true},{"one":"f62bd19b0fd052207743ce53c3d48a3a71e9219b75e41a9497a43e6368e559d5487ff1ab644f2df4106b500583e4344515f73187eec773115deb977b4ebc3514","other":"896c74ca4cc4cbb9d2b6606d0ebfd6427952c2e16aedbf36933fa3d01f1c505fcd663f3d01c0cf096bef9cfd0bae4595ec7c221cfc362e19a5b7c60614a9658b","up":true},{"one":"da3e0fd71eb96ba2cab7f920d32f5425d1aad41d00765fdffb0b215d9dd5b60e2bc5929eafebee5b2b5a11aec164e141beff19d828aac7d1fabd3ffb0bfb8450","other":"a6ca1d5340f2d7021f541c81cf9aea519675462c8443bb6ddd93919962561b8f5a8431c3ec7e7e7d46c600b653e9a0638d2bb07cf4e29516bf9c4d3653f451b0","up":true},{"one":"0e8c1a6b70524c4fdc492c74348bac4ccd5d140bd41352607e8cfba45561afb1e6e12f3e2fcf03c1778c9ae5ae19cb9218ee2d613983768f54e3f54e69bb6600","other":"f0299035cbddfdf7a78e5e3a400aaedf2d719d04e907ac0f9f067525e2f9bb913d985308a3a0d05467a64adf58c68a615c6327acf716c23631d0e829903f8b34","up":true},{"one":"1480f62d85ea32226d9f77ccd31780b3e704fb60618a588ae85dcd1c0e84e878c5fc092adfb306e8ebc7abba9ec429cb2447754502ef847cf931467f31fa50b2","other":"20bdc859d58d8bf419df64fd6ee1d4363c1d5f403af3abef2720d7d3933924672e12e23e5d76b28e0f6726acf58bdc5eb258cba635e327cbd0b564523305da75","up":true},{"one":"c773af3af01ee8ab9fa8d06987baf4f10c394fdd386d69b7a7362f4b68fd6fc082337d3b33a19d584c5801a3e9198225d7b61f6629e34ce823be70908339f4c7","other":"5b4de68680c5d1a75cccd5e7a82319c031f5d61d79cbb6532e1254ab81c833c3fafb54390cca7a770e84690c490fcba90482b35321870f8506335a2f57cc052e","up":true},{"one":"59730132a01ba848a3c050bb6234bca9a72deba33716960fc3ec89b186bfcd313b9bbf049939d5805ff98db2c53a9421ce6ec97d8b4cdbaea53ba264d80d0734","other":"e59940a6dfe35a6214e2e3daba9ad94e630004cd8f029e13a6649a56dc528ff94bc09d8d21a2f14a56b4ff759b60ebf3d27c1029862c183b8416fa3e950bdb55","up":true},{"one":"3540d888c3207d6df233afd1164ff9dde2551730862772547e04f7311de364968e113f38a7dea1ab0916a7f8307017de5b49578fa4ebcc39651e541fde51be48","other":"5d917ffc9d70a38670941ce206aa7ea1b9ea65c1d783f14ebdf7c7afa6ca8b237112aaa9b1a3f757132093a604ef378280c5bdef02c2688049a91a412c399bfe","up":true},{"one":"3572a22097a313b3adef95a7b6cc679f8d1201a156d764e61a9fbc63d123fb4826f7125402fb6569beed359e1c1e5e6cb6993a75975da6cd4ce15669a2eea758","other":"1e3c83cabbe6852c987ae521b7fcb33185cf855c59b6235ebb8e57a6f860ccc159ddc01b4a21d251c8faca4559ceb271e046a51493ba148c0d3aed97ad208969","up":true},{"one":"f7637cdd5ef26de40b9055c1df91a45725670c8df11ae934c0d99d2547c3eb4c42a16dbb2e75bcaf4b1b9347c48db65f549a0623179a08dd8cbad92f5bca08cf","other":"c6d1404873174254c0f15f25804da9a9d90db9c11c5cc895fab613b4deb7820f1733680b4ba9e4b61a664642ed6ee9ff012e13a0619c64ae067be6bab26962c6","up":true},{"one":"622646c74fdbae39ba191dbafff4906fb683fe0b0f2c303d080f5577a070876c41c8d3786ae7b953e5f682b8ec647727550d47302229ebb9f82bed24cea61132","other":"188bf77c9c1e45f009efe7aefdb040bdb47763980fe7eb0851295d657fa2a8978efbd2997c1dc30f4f0874eecf9ca9550487cf41da237b84d071963d35b6baff","up":true},{"one":"87e696a354d249493217dc4e0190082f30e09616873803efa376871d4b34f86f0eeb4643d4822d8a0fbcdedb27cd6ba5438e98943d358d960c4835e82261c93e","other":"a1b2d0c6f24f5924c61e057fc65b994d9a6755560d740018b4c9ad0bb69212ec69974e22cb037dfeb7ea90a4493997f4c94029870bcc5fd47013b51ca0a26b5d","up":true},{"one":"f7637cdd5ef26de40b9055c1df91a45725670c8df11ae934c0d99d2547c3eb4c42a16dbb2e75bcaf4b1b9347c48db65f549a0623179a08dd8cbad92f5bca08cf","other":"20bdc859d58d8bf419df64fd6ee1d4363c1d5f403af3abef2720d7d3933924672e12e23e5d76b28e0f6726acf58bdc5eb258cba635e327cbd0b564523305da75","up":true},{"one":"08900197e74e285a5a8a9cc53fbd420bb35043ab27eb2d9eab22615e736a093abfa235c17f667dcc791cb50b9022082eafd9fba030194cc84f0358b769adc85b","other":"5d96577324edf1b5a1626999925982af1e0ba7bed8edcc3f740ba434f4b003cbbe2d632cad327c76e5b490d08c091c4a7b473353ab59139493657eb9525b8be2","up":true},{"one":"750ca601f07d65f426f6ea5f34e06238f9d7a931f022f9b0ebc811943d3725500cb3c6f00c8d05eb8d5b353c6534136dff38b9a8d3d4dc5bf49cd96875704d07","other":"077d2d032874e5ce70e9b928b7fe72c0326ba92394e16245e31d48b5731d3d32bfd86acf40825decff54bcd735e9ebfd94eba677c418ea7007baec9db4af676d","up":true},{"one":"622646c74fdbae39ba191dbafff4906fb683fe0b0f2c303d080f5577a070876c41c8d3786ae7b953e5f682b8ec647727550d47302229ebb9f82bed24cea61132","other":"f7637cdd5ef26de40b9055c1df91a45725670c8df11ae934c0d99d2547c3eb4c42a16dbb2e75bcaf4b1b9347c48db65f549a0623179a08dd8cbad92f5bca08cf","up":true},{"one":"87e696a354d249493217dc4e0190082f30e09616873803efa376871d4b34f86f0eeb4643d4822d8a0fbcdedb27cd6ba5438e98943d358d960c4835e82261c93e","other":"3540d888c3207d6df233afd1164ff9dde2551730862772547e04f7311de364968e113f38a7dea1ab0916a7f8307017de5b49578fa4ebcc39651e541fde51be48","up":true},{"one":"c773af3af01ee8ab9fa8d06987baf4f10c394fdd386d69b7a7362f4b68fd6fc082337d3b33a19d584c5801a3e9198225d7b61f6629e34ce823be70908339f4c7","other":"b38213eaa5b419de787b70073ad8c7c819e48c5f76dec1507b54f1d7cb027211facbe7a170ac50212abe130935e8947d5a19d6b13790114e71cc18357902a889","up":true},{"one":"077d2d032874e5ce70e9b928b7fe72c0326ba92394e16245e31d48b5731d3d32bfd86acf40825decff54bcd735e9ebfd94eba677c418ea7007baec9db4af676d","other":"e7bb63c5187ee85d965fed5cb33d1678c0e090b4e4c3f3d859755565db18046cb60025453bdebf136373c416a2e6e56be063bca6c9257b7b175dcf966e274205","up":true},{"one":"f06ec3a90d34300f9fa2d48aea0c6b5f2f01f7833ffb0fad30e7f57e3916e344f3a4f9efe38e222443b8b00d3c7f5221c672491a129e4958e574afc283bd45b1","other":"31ac37862416c0e229c4a088ec179f23bdd1bf12dd464eb11c630ad531d7c3438671862e5458e2f6fbb32b857f857e6b8c17e5d93eb29a0e78bb5a65d7eb648c","up":true},{"one":"3c6faa2e75a1699ddadd0e21fd35d3d6215715cfdc2dc89961cfd66773d2541776e785f3ebc833a70e3d1017a4edc571a5d5d9f9fbfc3fa0a8588f6c5023c164","other":"44462055ba68fdef337dd19d8123aace9a12284c13bc97687416b6b4ca0c94234ba7db6823651fc021d6ac1539e0c5321e763a7a12c9e7c8a583aac5369817d8","up":true},{"one":"1480f62d85ea32226d9f77ccd31780b3e704fb60618a588ae85dcd1c0e84e878c5fc092adfb306e8ebc7abba9ec429cb2447754502ef847cf931467f31fa50b2","other":"03e478a3aae82e06e215e40272a420037a61442d11c49c367a5ee6a21868d29a17ea8b9284f013d020c4740f296a6a22bc64d33d1c2807f9ab8dc48c0cfec18a","up":true},{"one":"276256790c9317d09ff7802f4ad0a85840fe62527390ce1790e1e3186e8b3f04acfaa41dcd02303d333423678a4037e4f4854676e79ced3232a3dbd772cc2680","other":"f0b2f1e8d46be656109adb18c60677ac9eb8fce7f42e15d9dbb25f94b4e426064780eaf32b79954b9bb72ea89953175da8de35380aaba18931cca374a7de2b11","up":true},{"one":"077d2d032874e5ce70e9b928b7fe72c0326ba92394e16245e31d48b5731d3d32bfd86acf40825decff54bcd735e9ebfd94eba677c418ea7007baec9db4af676d","other":"2d6d55edd34c0d9a0130b4806e409bbe18cdda5c2b221cf46136718ec20ffc9d8e92838d78aff92fbcc85f5d081da361dd1e3d7f3d4e1ea57877d6bb7aa0b6f7","up":true},{"one":"fa897ba112f34839064c6871a4c9504c5d709eff5095a137c6a42726d58eb623af976cb96cc30db67e6ac9347c769f032aa4ebda884285a057059040c008ad3e","other":"6ce3a68cb1e2924ad97f22006094c709a3dd8b4ca1546fbb037f841a9e5ac62def242015dbf6221bda610153db064edcbb58a78a35a06077b8c02bf5b2a33c04","up":true},{"one":"f06ec3a90d34300f9fa2d48aea0c6b5f2f01f7833ffb0fad30e7f57e3916e344f3a4f9efe38e222443b8b00d3c7f5221c672491a129e4958e574afc283bd45b1","other":"3103510e00a3f49a5e715719049fc8c9c67a2373a548f326458aeb6d9c75ed92b94373638fd075def0209113b4e85d972c23f064539f7b041596184e40d7f9a2","up":true},{"one":"3c6faa2e75a1699ddadd0e21fd35d3d6215715cfdc2dc89961cfd66773d2541776e785f3ebc833a70e3d1017a4edc571a5d5d9f9fbfc3fa0a8588f6c5023c164","other":"31ac37862416c0e229c4a088ec179f23bdd1bf12dd464eb11c630ad531d7c3438671862e5458e2f6fbb32b857f857e6b8c17e5d93eb29a0e78bb5a65d7eb648c","up":true},{"one":"4de606aa7e722197b918c5f7f0db86a3081d48e89d21428b04f19c3ff3755eac0bddbff5fad8bda94b9e57f58fba2fecdbabbf710f7afb381bf4f1a4fe55cd93","other":"545850cb90787d49c579b1ed54a753ebd00eaafe3f1bd04d57266e4912fb1cdd654446ef054a973a583ce8dfc6cc130b6f90e63bcf75372fc21c445f8e1e6005","up":true},{"one":"276256790c9317d09ff7802f4ad0a85840fe62527390ce1790e1e3186e8b3f04acfaa41dcd02303d333423678a4037e4f4854676e79ced3232a3dbd772cc2680","other":"59730132a01ba848a3c050bb6234bca9a72deba33716960fc3ec89b186bfcd313b9bbf049939d5805ff98db2c53a9421ce6ec97d8b4cdbaea53ba264d80d0734","up":true},{"one":"fa897ba112f34839064c6871a4c9504c5d709eff5095a137c6a42726d58eb623af976cb96cc30db67e6ac9347c769f032aa4ebda884285a057059040c008ad3e","other":"4bd17847bdf60ea93a670a84a0ff8fe028d35228e814d6ebc0ae4fa586ddef03cd79390d541d28ca3c05a7241ffe92ac182e63c251176b40db8fe05fefaa82be","up":true},{"one":"e9f7e58fda4b504275441d51929fbc98214abdc9ed552c7aa94c600a85d4e791d60c032304b29ae028adccec94984fc9a3d705a81462632f50ef45024eb0f64e","other":"ecbdca037cd7892752345b48b4219478b1b334f83ce7140fcc72eb71784436b690ce7a41b03e013cefc19d64a34a20cfef1b9e2b535d938bcdcb39fe63645a42","up":true},{"one":"09b60de1e85bb6f7d2caf5b1ab58204d7d04531ece300dcd7bcc9157b8b3ef2a182758808a0eec6056034f29f52caadb7c690f498c1c8832ff7a6a9ecff308bd","other":"9c6dcfef0e128dbfeca58b8ac625b08fb447b0d579bd3f18bc0e2be60d1ec2274595d0554ddba0ca7eb660099d3ea146d8076792b46c93841d2ecf8cf608f5ba","up":true},{"one":"73319a301ad3cf0ec09549d817c9523d61b74abb0cad87b737d41d900321e52722a84355f6f87bc7a5f848818c89a021bb0f3e5994f67c9a7b5bbfc98188a376","other":"c89dbada7195464e732671ac6fff014cacfb4c879b63b6b84e7c1bce367522f759bd06e504b15f43a1735c6322356747fa5c4951882d4fd6cdf6f7cf13726719","up":true},{"one":"670949178a5fad22da03af1e206c814a797c0e9eb4e3371f83612f121e5b56e767706a3ae36628cd0c86dd7bd1586ca4df57e2de27b28a31284ecf9176d330e5","other":"8f625a4e4f4fd980c796d3aa535e58a39722492480cf6982d43fab02de63a5b4c1b5c7cd8402171dd792bb5d9c3e2bdd38176c061dbe3e5b0592af1339e3fd82","up":true},{"one":"4de606aa7e722197b918c5f7f0db86a3081d48e89d21428b04f19c3ff3755eac0bddbff5fad8bda94b9e57f58fba2fecdbabbf710f7afb381bf4f1a4fe55cd93","other":"896c74ca4cc4cbb9d2b6606d0ebfd6427952c2e16aedbf36933fa3d01f1c505fcd663f3d01c0cf096bef9cfd0bae4595ec7c221cfc362e19a5b7c60614a9658b","up":true},{"one":"e9f7e58fda4b504275441d51929fbc98214abdc9ed552c7aa94c600a85d4e791d60c032304b29ae028adccec94984fc9a3d705a81462632f50ef45024eb0f64e","other":"afb5754b4748b7ac5628e32b242c90aab0e2fc7da58d8d5c8c775d13d8a6fd32240f1b89021587858168cbe7b3ea7ad07807728655eae0a9907060494a7c99ca","up":true},{"one":"26cf4ea45b9a76daab82a57126f9c6f8726d2eb973e205ab4ab69c8b8be11a32a7eb5c3807e952cd428ce5ddd88f143d4fc9ff8c3de3d159855675afce715615","other":"3e9c0bbd146d8b1040b4f379eecf802c27c4d0a70e64a9fb2e941a7edab9b00396b0b67fc5c891652743cdba3b342973ed49615b32da54b925954a799240431c","up":true},{"one":"09b60de1e85bb6f7d2caf5b1ab58204d7d04531ece300dcd7bcc9157b8b3ef2a182758808a0eec6056034f29f52caadb7c690f498c1c8832ff7a6a9ecff308bd","other":"3e7820bb15c07f515bd63791b66136723dcc9878b3145fe0f238f6b41e3f2f7565ae55ef24f08ae461950ce1ae0c8a80fe5e4fd4f2f88c4acf4a2c94640df239","up":true},{"one":"09b60de1e85bb6f7d2caf5b1ab58204d7d04531ece300dcd7bcc9157b8b3ef2a182758808a0eec6056034f29f52caadb7c690f498c1c8832ff7a6a9ecff308bd","other":"489660042a8867d90a16ebb013968db26ca3edfc70f53320f511e35b3703eed09fbd787be5c06726a570a54aa15d129cd10db741523adf297929f909be4a0c71","up":true},{"one":"4448a59bde9edb93edcdb4a77f3e2277b9c01ffea45496ee0533eb5192955a08a0f982e25cf772e0dae68735a55b7acd221f6ba7b134f1e999087bee182330e8","other":"8e8de10fb3f53bd3a48455ebfa0a38ea5bd28c607e65506b263ece53a24d2361c2af7d7cd207e45b11bf71a3c33fa325fc8fd40a18b9c73019cce219c757c7ef","up":true},{"one":"4de606aa7e722197b918c5f7f0db86a3081d48e89d21428b04f19c3ff3755eac0bddbff5fad8bda94b9e57f58fba2fecdbabbf710f7afb381bf4f1a4fe55cd93","other":"f0b2f1e8d46be656109adb18c60677ac9eb8fce7f42e15d9dbb25f94b4e426064780eaf32b79954b9bb72ea89953175da8de35380aaba18931cca374a7de2b11","up":true},{"one":"155805f787600f9f9518cf8836f491885b64868bfe0023975bcd12776925a424fb5aa3199dc178e83294e97f347a373d05d2422578a08eeeb2d15a178d28964f","other":"b2bea653b6ec9629c6f934be72fccf30acf836698e21e81dd8085f070ba8259ba43eee43c342738a4b782f5fbddd44caa28f56dffc08237ca7567c965ac3beca","up":true},{"one":"3c6faa2e75a1699ddadd0e21fd35d3d6215715cfdc2dc89961cfd66773d2541776e785f3ebc833a70e3d1017a4edc571a5d5d9f9fbfc3fa0a8588f6c5023c164","other":"3103510e00a3f49a5e715719049fc8c9c67a2373a548f326458aeb6d9c75ed92b94373638fd075def0209113b4e85d972c23f064539f7b041596184e40d7f9a2","up":true},{"one":"fa897ba112f34839064c6871a4c9504c5d709eff5095a137c6a42726d58eb623af976cb96cc30db67e6ac9347c769f032aa4ebda884285a057059040c008ad3e","other":"51ba4faf0988717a37dcddc0a60a70ead33bde310184fc450f9ca73c67f931e6767ad5930bcf409e5aeb613a9ff7a03e47de6fc13b33d8af0b87b38822ae6888","up":true},{"one":"b09af9e5552e72f918174963dad58a4492d3afa120f78e43820df7bff7fae9f6b52bc6c8c73d3a9af91d20134f4ff1b037db2ef0bc3d8c495a771d63de678bc0","other":"0e8c1a6b70524c4fdc492c74348bac4ccd5d140bd41352607e8cfba45561afb1e6e12f3e2fcf03c1778c9ae5ae19cb9218ee2d613983768f54e3f54e69bb6600","up":true},{"one":"a6ca1d5340f2d7021f541c81cf9aea519675462c8443bb6ddd93919962561b8f5a8431c3ec7e7e7d46c600b653e9a0638d2bb07cf4e29516bf9c4d3653f451b0","other":"33e3ab7108ced43102003c3b3192b194100f32b6bcb67bb772ea9696e35721196699cf01e443f7cdf8076ad83aaf7468b75c71d03efb95f4c07cf0742ea9af81","up":true},{"one":"f7637cdd5ef26de40b9055c1df91a45725670c8df11ae934c0d99d2547c3eb4c42a16dbb2e75bcaf4b1b9347c48db65f549a0623179a08dd8cbad92f5bca08cf","other":"56b25623ac935f3a8aac1e2603a6bd15ace1e5714671954b47f2cab960cf47922828f415105602408d0a732a893ebeea6f9afab7f889bb235c81589548d09391","up":true},{"one":"665c3288c14dc1c17d85d17d634910f42183482c7e77c47e68f9b4f475b93e8c152246b9e34781606315ff6ef0f8360342500d15e4a2d67d9df6b72f30af64a7","other":"cbed12dcab0aa04a96ec7e25bc2ee03b337c7b2006391baa7d2aff042c17ec70b82c5fb2dc916d085a7948541719d329f9b528b67ec6adb1ac2cc594d4ef1e42","up":true},{"one":"82a774be7146766585d2bec6b69b7803aa956f492a53d8ed5f071becdbbc617562885d8430f0afd505210aab7b032428fbea32c82dffbd12d9ccba776ef4729b","other":"5771bef7f50439f9b81d2a7bf7060b1ad4b38675d8f6abbac3cc4c215fb0cb5dd07f6873545b42218337556925566025476e2915b7b98e662a3dcd28bebf0eb4","up":true},{"one":"c93cb2df7ba6de8009872f5f7565891040d42e3b193ef1cdb321a0c167cc8fb8138900982bb8f6918fbaefac6e02dda01ee40f7a6beba1990dd44abe03cc3d01","other":"a6ca1d5340f2d7021f541c81cf9aea519675462c8443bb6ddd93919962561b8f5a8431c3ec7e7e7d46c600b653e9a0638d2bb07cf4e29516bf9c4d3653f451b0","up":true},{"one":"82a774be7146766585d2bec6b69b7803aa956f492a53d8ed5f071becdbbc617562885d8430f0afd505210aab7b032428fbea32c82dffbd12d9ccba776ef4729b","other":"bf1e6eeb8b229f63b49213db499b71dcfe0ae45ee3f14685c7cbfa3f0a2150e52a89c853f4cd8c7a92e6e5f6083044efddfa17391662e3cff6290da679520404","up":true},{"one":"82a774be7146766585d2bec6b69b7803aa956f492a53d8ed5f071becdbbc617562885d8430f0afd505210aab7b032428fbea32c82dffbd12d9ccba776ef4729b","other":"e7bb63c5187ee85d965fed5cb33d1678c0e090b4e4c3f3d859755565db18046cb60025453bdebf136373c416a2e6e56be063bca6c9257b7b175dcf966e274205","up":true},{"one":"b2bea653b6ec9629c6f934be72fccf30acf836698e21e81dd8085f070ba8259ba43eee43c342738a4b782f5fbddd44caa28f56dffc08237ca7567c965ac3beca","other":"8f625a4e4f4fd980c796d3aa535e58a39722492480cf6982d43fab02de63a5b4c1b5c7cd8402171dd792bb5d9c3e2bdd38176c061dbe3e5b0592af1339e3fd82","up":true},{"one":"340420ee18d55913f790d0fcc2305b40b1e7bef2eddb79dda57801690aeeead693ebd1a9ff8557671f5ae136b3e65733306924bd00444cbc6e7c6235e5a2c77f","other":"5d917ffc9d70a38670941ce206aa7ea1b9ea65c1d783f14ebdf7c7afa6ca8b237112aaa9b1a3f757132093a604ef378280c5bdef02c2688049a91a412c399bfe","up":true},{"one":"340420ee18d55913f790d0fcc2305b40b1e7bef2eddb79dda57801690aeeead693ebd1a9ff8557671f5ae136b3e65733306924bd00444cbc6e7c6235e5a2c77f","other":"276256790c9317d09ff7802f4ad0a85840fe62527390ce1790e1e3186e8b3f04acfaa41dcd02303d333423678a4037e4f4854676e79ced3232a3dbd772cc2680","up":true},{"one":"a1b2d0c6f24f5924c61e057fc65b994d9a6755560d740018b4c9ad0bb69212ec69974e22cb037dfeb7ea90a4493997f4c94029870bcc5fd47013b51ca0a26b5d","other":"5d96577324edf1b5a1626999925982af1e0ba7bed8edcc3f740ba434f4b003cbbe2d632cad327c76e5b490d08c091c4a7b473353ab59139493657eb9525b8be2","up":true},{"one":"a6ca1d5340f2d7021f541c81cf9aea519675462c8443bb6ddd93919962561b8f5a8431c3ec7e7e7d46c600b653e9a0638d2bb07cf4e29516bf9c4d3653f451b0","other":"e9f7e58fda4b504275441d51929fbc98214abdc9ed552c7aa94c600a85d4e791d60c032304b29ae028adccec94984fc9a3d705a81462632f50ef45024eb0f64e","up":false},{"one":"c93cb2df7ba6de8009872f5f7565891040d42e3b193ef1cdb321a0c167cc8fb8138900982bb8f6918fbaefac6e02dda01ee40f7a6beba1990dd44abe03cc3d01","other":"077d2d032874e5ce70e9b928b7fe72c0326ba92394e16245e31d48b5731d3d32bfd86acf40825decff54bcd735e9ebfd94eba677c418ea7007baec9db4af676d","up":true},{"one":"c93cb2df7ba6de8009872f5f7565891040d42e3b193ef1cdb321a0c167cc8fb8138900982bb8f6918fbaefac6e02dda01ee40f7a6beba1990dd44abe03cc3d01","other":"a40391285d1a97f1fb368b20c8e4d02be1bdebc0db41f00f99aac2f01893dc12256cd5a711117a981fbb3f9dfea18c19cf3603e925dbd67c4032b22b41eab8d5","up":true},{"one":"33e3ab7108ced43102003c3b3192b194100f32b6bcb67bb772ea9696e35721196699cf01e443f7cdf8076ad83aaf7468b75c71d03efb95f4c07cf0742ea9af81","other":"1e0a46ff50fb6d9a2c218a851763ff86c42e4d61dddffb7188481febc0f3180bc8f31973d336b2a6e25802acd4fed6d905d89c6d4d7d8080fb12741f9c5ab7e6","up":true},{"one":"fa897ba112f34839064c6871a4c9504c5d709eff5095a137c6a42726d58eb623af976cb96cc30db67e6ac9347c769f032aa4ebda884285a057059040c008ad3e","other":"2502fc8ee0ccda79ad1dbd9c7cec625da85980b9116bdd56dc367d508039e25e5f65183293006e5b0df72fa9037a48bd2b133a757940d3587ff77ae2392e3eaf","up":true},{"one":"b2bea653b6ec9629c6f934be72fccf30acf836698e21e81dd8085f070ba8259ba43eee43c342738a4b782f5fbddd44caa28f56dffc08237ca7567c965ac3beca","other":"3103510e00a3f49a5e715719049fc8c9c67a2373a548f326458aeb6d9c75ed92b94373638fd075def0209113b4e85d972c23f064539f7b041596184e40d7f9a2","up":true},{"one":"a1b2d0c6f24f5924c61e057fc65b994d9a6755560d740018b4c9ad0bb69212ec69974e22cb037dfeb7ea90a4493997f4c94029870bcc5fd47013b51ca0a26b5d","other":"f2ea93f43be9d0c3fa21f1496dc13c778977a6afdcba24c8b146de7dca2cdde62a5b792aab969e5b4b6c56f63066b336580d911f206049cc24cac32a25fc4306","up":true},{"one":"b38213eaa5b419de787b70073ad8c7c819e48c5f76dec1507b54f1d7cb027211facbe7a170ac50212abe130935e8947d5a19d6b13790114e71cc18357902a889","other":"a1b2d0c6f24f5924c61e057fc65b994d9a6755560d740018b4c9ad0bb69212ec69974e22cb037dfeb7ea90a4493997f4c94029870bcc5fd47013b51ca0a26b5d","up":true},{"one":"33e3ab7108ced43102003c3b3192b194100f32b6bcb67bb772ea9696e35721196699cf01e443f7cdf8076ad83aaf7468b75c71d03efb95f4c07cf0742ea9af81","other":"ed1ab28230ed533abf25633508d54f32bbff78a10c7a15fad5c2320cda9d9669c6d0e15689d8885400e64cbcd81730456f8f4bd5c98681d2cd8a8d4e1daec553","up":true},{"one":"4de606aa7e722197b918c5f7f0db86a3081d48e89d21428b04f19c3ff3755eac0bddbff5fad8bda94b9e57f58fba2fecdbabbf710f7afb381bf4f1a4fe55cd93","other":"9e6c1c6e871638182c4b54ac89352ef5c2bca0a99424a1369013e7c182883da0e8d7ab96b3c8254c31fa315b941d8ddee153157626821fc78c2cae951c1c9053","up":true},{"one":"82a774be7146766585d2bec6b69b7803aa956f492a53d8ed5f071becdbbc617562885d8430f0afd505210aab7b032428fbea32c82dffbd12d9ccba776ef4729b","other":"f0b2f1e8d46be656109adb18c60677ac9eb8fce7f42e15d9dbb25f94b4e426064780eaf32b79954b9bb72ea89953175da8de35380aaba18931cca374a7de2b11","up":true},{"one":"56e8f792ec9a75ec9e91d472b8a4b023655dd68c2a448a33397b125fe3584a5efa1b492e47077b24acfe0396b73e1cb564a6a6b2aee1b457781dfaf6d43fcaed","other":"489660042a8867d90a16ebb013968db26ca3edfc70f53320f511e35b3703eed09fbd787be5c06726a570a54aa15d129cd10db741523adf297929f909be4a0c71","up":true},{"one":"c89dbada7195464e732671ac6fff014cacfb4c879b63b6b84e7c1bce367522f759bd06e504b15f43a1735c6322356747fa5c4951882d4fd6cdf6f7cf13726719","other":"562119edffe8270f6f7a5ad9b13d4c65d643e52a2331d1fee16f7e9b5567f44cfea62df3e8965a22cf08db8fa918f0a0bcae8da2936677e6d25bc88ed85ed2f1","up":true},{"one":"b38213eaa5b419de787b70073ad8c7c819e48c5f76dec1507b54f1d7cb027211facbe7a170ac50212abe130935e8947d5a19d6b13790114e71cc18357902a889","other":"e59940a6dfe35a6214e2e3daba9ad94e630004cd8f029e13a6649a56dc528ff94bc09d8d21a2f14a56b4ff759b60ebf3d27c1029862c183b8416fa3e950bdb55","up":true},{"one":"26cf4ea45b9a76daab82a57126f9c6f8726d2eb973e205ab4ab69c8b8be11a32a7eb5c3807e952cd428ce5ddd88f143d4fc9ff8c3de3d159855675afce715615","other":"670949178a5fad22da03af1e206c814a797c0e9eb4e3371f83612f121e5b56e767706a3ae36628cd0c86dd7bd1586ca4df57e2de27b28a31284ecf9176d330e5","up":false},{"one":"b38213eaa5b419de787b70073ad8c7c819e48c5f76dec1507b54f1d7cb027211facbe7a170ac50212abe130935e8947d5a19d6b13790114e71cc18357902a889","other":"4bd17847bdf60ea93a670a84a0ff8fe028d35228e814d6ebc0ae4fa586ddef03cd79390d541d28ca3c05a7241ffe92ac182e63c251176b40db8fe05fefaa82be","up":true},{"one":"fa897ba112f34839064c6871a4c9504c5d709eff5095a137c6a42726d58eb623af976cb96cc30db67e6ac9347c769f032aa4ebda884285a057059040c008ad3e","other":"fd12c5c96df6ee76dd7beb9e4e4768dda4d2c498851b6435f13ca0175980d0e4a4ff1c002e4daf41a995f118500604764f88496fb9b2c22e28308d8649b525ce","up":true},{"one":"b09af9e5552e72f918174963dad58a4492d3afa120f78e43820df7bff7fae9f6b52bc6c8c73d3a9af91d20134f4ff1b037db2ef0bc3d8c495a771d63de678bc0","other":"f6a07a1d361a4671e997d5eaadae61736291aff3896cb69f06bbc19bf7536dd152e0b15422b2fd9f8a9d2f9a251c9a07d0140319900e2cc9f25a59025c7dc91f","up":true},{"one":"5b4de68680c5d1a75cccd5e7a82319c031f5d61d79cbb6532e1254ab81c833c3fafb54390cca7a770e84690c490fcba90482b35321870f8506335a2f57cc052e","other":"20bdc859d58d8bf419df64fd6ee1d4363c1d5f403af3abef2720d7d3933924672e12e23e5d76b28e0f6726acf58bdc5eb258cba635e327cbd0b564523305da75","up":true},{"one":"56e8f792ec9a75ec9e91d472b8a4b023655dd68c2a448a33397b125fe3584a5efa1b492e47077b24acfe0396b73e1cb564a6a6b2aee1b457781dfaf6d43fcaed","other":"f8052e328014f39157036f3dcecdb23419c0959473a88282605f10add681ef5cbfb1e926b522f98b8401272113b677a67225874d1afb0bff4b11140cc071de44","up":true},{"one":"cdd86dea7dde96ff7cc1e3248fd17d107c83f2cc7ce2111c41530448962763309e91a05b5dad4663d0e02db59ed4129ab0c3e1eedc42c654e39d29f99038063b","other":"d90a81a583c82d626b92f27244f027da4a0ae76e6d3bdc1de0af7be01798f1fb04b34ce60c6d8651a39d7a70915438a4aa63e5adf844a9f7e38dbf0b1dba754d","up":true},{"one":"5b4de68680c5d1a75cccd5e7a82319c031f5d61d79cbb6532e1254ab81c833c3fafb54390cca7a770e84690c490fcba90482b35321870f8506335a2f57cc052e","other":"d8cfadac10473b31a4560c711636a05615f13054388065344642ff1d04246fb62eafeec06805264eafead111ed8134e11a8e21f42a0eb950c23b142e627bd8cb","up":true},{"one":"5b4de68680c5d1a75cccd5e7a82319c031f5d61d79cbb6532e1254ab81c833c3fafb54390cca7a770e84690c490fcba90482b35321870f8506335a2f57cc052e","other":"a40391285d1a97f1fb368b20c8e4d02be1bdebc0db41f00f99aac2f01893dc12256cd5a711117a981fbb3f9dfea18c19cf3603e925dbd67c4032b22b41eab8d5","up":true},{"one":"fa897ba112f34839064c6871a4c9504c5d709eff5095a137c6a42726d58eb623af976cb96cc30db67e6ac9347c769f032aa4ebda884285a057059040c008ad3e","other":"06472c89def07fa73188d253cf1acddc2be984842f3a234edb3db95449ba74928ab1395eca1b8978987769863afffb488fc27c9ac723aa24837b66c12f38d735","up":true},{"one":"e59940a6dfe35a6214e2e3daba9ad94e630004cd8f029e13a6649a56dc528ff94bc09d8d21a2f14a56b4ff759b60ebf3d27c1029862c183b8416fa3e950bdb55","other":"9c3be147f9fe0fa34e553d9e4332969086ea7fa65294b61ca35c9f731f6b81d0b70cdcfe2ba52b6cea3c0de14b7ea40031b5cc40661c4bb821147894130d7bf5","up":true},{"one":"3c6faa2e75a1699ddadd0e21fd35d3d6215715cfdc2dc89961cfd66773d2541776e785f3ebc833a70e3d1017a4edc571a5d5d9f9fbfc3fa0a8588f6c5023c164","other":"0e8c1a6b70524c4fdc492c74348bac4ccd5d140bd41352607e8cfba45561afb1e6e12f3e2fcf03c1778c9ae5ae19cb9218ee2d613983768f54e3f54e69bb6600","up":true},{"one":"56e8f792ec9a75ec9e91d472b8a4b023655dd68c2a448a33397b125fe3584a5efa1b492e47077b24acfe0396b73e1cb564a6a6b2aee1b457781dfaf6d43fcaed","other":"caad8529d498a4a1e1ba7573689a913500bd409345ef8e3656abca748269eb73b919282f7f2eb0087f81f7bc52c367657ac8be0cdac65d2490c7c50c874444b7","up":true},{"one":"4448a59bde9edb93edcdb4a77f3e2277b9c01ffea45496ee0533eb5192955a08a0f982e25cf772e0dae68735a55b7acd221f6ba7b134f1e999087bee182330e8","other":"03d2d77c008b5fa1063b1abc3152b879a529fe4fdb2dc174d6d85312264a38ee4cc49b342507a10fff1a4b0730f1ef8e008b0897d97bfd6f70050adb124d3596","up":false},{"one":"e59940a6dfe35a6214e2e3daba9ad94e630004cd8f029e13a6649a56dc528ff94bc09d8d21a2f14a56b4ff759b60ebf3d27c1029862c183b8416fa3e950bdb55","other":"8e8de10fb3f53bd3a48455ebfa0a38ea5bd28c607e65506b263ece53a24d2361c2af7d7cd207e45b11bf71a3c33fa325fc8fd40a18b9c73019cce219c757c7ef","up":true},{"one":"da15d60a4b9a8816ce24c20f6c941c51229c1fb5e070b8b29be2977c2f7b41f8f17e4b6efe75f465e7935ded1ba17472f046eac73393db7197018fa86d11c31f","other":"9c3be147f9fe0fa34e553d9e4332969086ea7fa65294b61ca35c9f731f6b81d0b70cdcfe2ba52b6cea3c0de14b7ea40031b5cc40661c4bb821147894130d7bf5","up":true},{"one":"da15d60a4b9a8816ce24c20f6c941c51229c1fb5e070b8b29be2977c2f7b41f8f17e4b6efe75f465e7935ded1ba17472f046eac73393db7197018fa86d11c31f","other":"b09af9e5552e72f918174963dad58a4492d3afa120f78e43820df7bff7fae9f6b52bc6c8c73d3a9af91d20134f4ff1b037db2ef0bc3d8c495a771d63de678bc0","up":true},{"one":"0e8c1a6b70524c4fdc492c74348bac4ccd5d140bd41352607e8cfba45561afb1e6e12f3e2fcf03c1778c9ae5ae19cb9218ee2d613983768f54e3f54e69bb6600","other":"896c74ca4cc4cbb9d2b6606d0ebfd6427952c2e16aedbf36933fa3d01f1c505fcd663f3d01c0cf096bef9cfd0bae4595ec7c221cfc362e19a5b7c60614a9658b","up":true},{"one":"28afc20d8f4779b285bb14870062dbb54796ec77623302e51bc1bafed9e2c35751c8469ffc482718e059875dfa2226195ed10999e251498cba3a444896cb67db","other":"e59940a6dfe35a6214e2e3daba9ad94e630004cd8f029e13a6649a56dc528ff94bc09d8d21a2f14a56b4ff759b60ebf3d27c1029862c183b8416fa3e950bdb55","up":false},{"one":"f62bd19b0fd052207743ce53c3d48a3a71e9219b75e41a9497a43e6368e559d5487ff1ab644f2df4106b500583e4344515f73187eec773115deb977b4ebc3514","other":"d71c50805f284ed3a759e2e81f220fbc73d6d0a7a261b4c9e7878c3da143cfc07afa83e1635b6a45530f71a60b9f17c485a2fd6617c6c2bff82bacc71c208087","up":false},{"one":"f2ea93f43be9d0c3fa21f1496dc13c778977a6afdcba24c8b146de7dca2cdde62a5b792aab969e5b4b6c56f63066b336580d911f206049cc24cac32a25fc4306","other":"816e91fa8ff68ba067a89390ef61e7f23211e5e05049daa103ad1ff84b94fbcf535a6f6b515fb571939f5656869767c608513808800baba7e5d2b5f3a17a9691","up":true},{"one":"4de606aa7e722197b918c5f7f0db86a3081d48e89d21428b04f19c3ff3755eac0bddbff5fad8bda94b9e57f58fba2fecdbabbf710f7afb381bf4f1a4fe55cd93","other":"d71c50805f284ed3a759e2e81f220fbc73d6d0a7a261b4c9e7878c3da143cfc07afa83e1635b6a45530f71a60b9f17c485a2fd6617c6c2bff82bacc71c208087","up":false},{"one":"1e0a46ff50fb6d9a2c218a851763ff86c42e4d61dddffb7188481febc0f3180bc8f31973d336b2a6e25802acd4fed6d905d89c6d4d7d8080fb12741f9c5ab7e6","other":"5771bef7f50439f9b81d2a7bf7060b1ad4b38675d8f6abbac3cc4c215fb0cb5dd07f6873545b42218337556925566025476e2915b7b98e662a3dcd28bebf0eb4","up":true},{"one":"8f625a4e4f4fd980c796d3aa535e58a39722492480cf6982d43fab02de63a5b4c1b5c7cd8402171dd792bb5d9c3e2bdd38176c061dbe3e5b0592af1339e3fd82","other":"93987e431a0058f2e942ccf8d3486d249cd2734d6494131b343e2c3a8fdd86cfcb12d0aaaf8fcb911ad3cdd682cc82118198195a7fdc915ab7853223f012eab6","up":true},{"one":"f2ea93f43be9d0c3fa21f1496dc13c778977a6afdcba24c8b146de7dca2cdde62a5b792aab969e5b4b6c56f63066b336580d911f206049cc24cac32a25fc4306","other":"e59940a6dfe35a6214e2e3daba9ad94e630004cd8f029e13a6649a56dc528ff94bc09d8d21a2f14a56b4ff759b60ebf3d27c1029862c183b8416fa3e950bdb55","up":true},{"one":"896c74ca4cc4cbb9d2b6606d0ebfd6427952c2e16aedbf36933fa3d01f1c505fcd663f3d01c0cf096bef9cfd0bae4595ec7c221cfc362e19a5b7c60614a9658b","other":"a05a18161c2d01a0f122548c66509dd1fcf3ee52975035bc79fb059e9613b743a16cd6f5ac54090e68f51bcf76ff21fb3805ba3197a96b4236afb80f791df802","up":true},{"one":"3e9c0bbd146d8b1040b4f379eecf802c27c4d0a70e64a9fb2e941a7edab9b00396b0b67fc5c891652743cdba3b342973ed49615b32da54b925954a799240431c","other":"57bfbde13c71e035c96513870aa8215198f78806e7cdb01c54fbdb392de2c40386d768d6fdc4c68534a67e531867ca74d8ca4dcf34ff7f7f64ec35edee3e5f68","up":true},{"one":"c93cb2df7ba6de8009872f5f7565891040d42e3b193ef1cdb321a0c167cc8fb8138900982bb8f6918fbaefac6e02dda01ee40f7a6beba1990dd44abe03cc3d01","other":"e7bb63c5187ee85d965fed5cb33d1678c0e090b4e4c3f3d859755565db18046cb60025453bdebf136373c416a2e6e56be063bca6c9257b7b175dcf966e274205","up":false},{"one":"8f625a4e4f4fd980c796d3aa535e58a39722492480cf6982d43fab02de63a5b4c1b5c7cd8402171dd792bb5d9c3e2bdd38176c061dbe3e5b0592af1339e3fd82","other":"f0299035cbddfdf7a78e5e3a400aaedf2d719d04e907ac0f9f067525e2f9bb913d985308a3a0d05467a64adf58c68a615c6327acf716c23631d0e829903f8b34","up":true},{"one":"d90a81a583c82d626b92f27244f027da4a0ae76e6d3bdc1de0af7be01798f1fb04b34ce60c6d8651a39d7a70915438a4aa63e5adf844a9f7e38dbf0b1dba754d","other":"1e3c83cabbe6852c987ae521b7fcb33185cf855c59b6235ebb8e57a6f860ccc159ddc01b4a21d251c8faca4559ceb271e046a51493ba148c0d3aed97ad208969","up":true},{"one":"896c74ca4cc4cbb9d2b6606d0ebfd6427952c2e16aedbf36933fa3d01f1c505fcd663f3d01c0cf096bef9cfd0bae4595ec7c221cfc362e19a5b7c60614a9658b","other":"f6a07a1d361a4671e997d5eaadae61736291aff3896cb69f06bbc19bf7536dd152e0b15422b2fd9f8a9d2f9a251c9a07d0140319900e2cc9f25a59025c7dc91f","up":true},{"one":"896c74ca4cc4cbb9d2b6606d0ebfd6427952c2e16aedbf36933fa3d01f1c505fcd663f3d01c0cf096bef9cfd0bae4595ec7c221cfc362e19a5b7c60614a9658b","other":"178d5ce398a7114a63a0c953a59932e769891420f6b1544f08c082cd37b531b66757652d279b3036b03b04f8d46eceb0b46fb95646c6668e2921af75c06c3d97","up":true},{"one":"fa897ba112f34839064c6871a4c9504c5d709eff5095a137c6a42726d58eb623af976cb96cc30db67e6ac9347c769f032aa4ebda884285a057059040c008ad3e","other":"c89dbada7195464e732671ac6fff014cacfb4c879b63b6b84e7c1bce367522f759bd06e504b15f43a1735c6322356747fa5c4951882d4fd6cdf6f7cf13726719","up":false},{"one":"da3e0fd71eb96ba2cab7f920d32f5425d1aad41d00765fdffb0b215d9dd5b60e2bc5929eafebee5b2b5a11aec164e141beff19d828aac7d1fabd3ffb0bfb8450","other":"b38213eaa5b419de787b70073ad8c7c819e48c5f76dec1507b54f1d7cb027211facbe7a170ac50212abe130935e8947d5a19d6b13790114e71cc18357902a889","up":false},{"one":"87e696a354d249493217dc4e0190082f30e09616873803efa376871d4b34f86f0eeb4643d4822d8a0fbcdedb27cd6ba5438e98943d358d960c4835e82261c93e","other":"56e8f792ec9a75ec9e91d472b8a4b023655dd68c2a448a33397b125fe3584a5efa1b492e47077b24acfe0396b73e1cb564a6a6b2aee1b457781dfaf6d43fcaed","up":false},{"one":"3e9c0bbd146d8b1040b4f379eecf802c27c4d0a70e64a9fb2e941a7edab9b00396b0b67fc5c891652743cdba3b342973ed49615b32da54b925954a799240431c","other":"93987e431a0058f2e942ccf8d3486d249cd2734d6494131b343e2c3a8fdd86cfcb12d0aaaf8fcb911ad3cdd682cc82118198195a7fdc915ab7853223f012eab6","up":false},{"one":"3e9c0bbd146d8b1040b4f379eecf802c27c4d0a70e64a9fb2e941a7edab9b00396b0b67fc5c891652743cdba3b342973ed49615b32da54b925954a799240431c","other":"340420ee18d55913f790d0fcc2305b40b1e7bef2eddb79dda57801690aeeead693ebd1a9ff8557671f5ae136b3e65733306924bd00444cbc6e7c6235e5a2c77f","up":true},{"one":"f2ea93f43be9d0c3fa21f1496dc13c778977a6afdcba24c8b146de7dca2cdde62a5b792aab969e5b4b6c56f63066b336580d911f206049cc24cac32a25fc4306","other":"59730132a01ba848a3c050bb6234bca9a72deba33716960fc3ec89b186bfcd313b9bbf049939d5805ff98db2c53a9421ce6ec97d8b4cdbaea53ba264d80d0734","up":true},{"one":"20bdc859d58d8bf419df64fd6ee1d4363c1d5f403af3abef2720d7d3933924672e12e23e5d76b28e0f6726acf58bdc5eb258cba635e327cbd0b564523305da75","other":"93987e431a0058f2e942ccf8d3486d249cd2734d6494131b343e2c3a8fdd86cfcb12d0aaaf8fcb911ad3cdd682cc82118198195a7fdc915ab7853223f012eab6","up":true},{"one":"3e9c0bbd146d8b1040b4f379eecf802c27c4d0a70e64a9fb2e941a7edab9b00396b0b67fc5c891652743cdba3b342973ed49615b32da54b925954a799240431c","other":"872cdbb6d74fb55fd2d51877ef7804bdd2eeb6de0297eb2ce18b67e52379b147d54a46d2385ec9293eb21736bed4191d92c5c75e8e81fc5a6c691970e019f570","up":true},{"one":"8f625a4e4f4fd980c796d3aa535e58a39722492480cf6982d43fab02de63a5b4c1b5c7cd8402171dd792bb5d9c3e2bdd38176c061dbe3e5b0592af1339e3fd82","other":"1e0a46ff50fb6d9a2c218a851763ff86c42e4d61dddffb7188481febc0f3180bc8f31973d336b2a6e25802acd4fed6d905d89c6d4d7d8080fb12741f9c5ab7e6","up":true},{"one":"03e478a3aae82e06e215e40272a420037a61442d11c49c367a5ee6a21868d29a17ea8b9284f013d020c4740f296a6a22bc64d33d1c2807f9ab8dc48c0cfec18a","other":"d8cfadac10473b31a4560c711636a05615f13054388065344642ff1d04246fb62eafeec06805264eafead111ed8134e11a8e21f42a0eb950c23b142e627bd8cb","up":true},{"one":"3540d888c3207d6df233afd1164ff9dde2551730862772547e04f7311de364968e113f38a7dea1ab0916a7f8307017de5b49578fa4ebcc39651e541fde51be48","other":"57bfbde13c71e035c96513870aa8215198f78806e7cdb01c54fbdb392de2c40386d768d6fdc4c68534a67e531867ca74d8ca4dcf34ff7f7f64ec35edee3e5f68","up":false},{"one":"d90a81a583c82d626b92f27244f027da4a0ae76e6d3bdc1de0af7be01798f1fb04b34ce60c6d8651a39d7a70915438a4aa63e5adf844a9f7e38dbf0b1dba754d","other":"1480f62d85ea32226d9f77ccd31780b3e704fb60618a588ae85dcd1c0e84e878c5fc092adfb306e8ebc7abba9ec429cb2447754502ef847cf931467f31fa50b2","up":true},{"one":"20bdc859d58d8bf419df64fd6ee1d4363c1d5f403af3abef2720d7d3933924672e12e23e5d76b28e0f6726acf58bdc5eb258cba635e327cbd0b564523305da75","other":"340420ee18d55913f790d0fcc2305b40b1e7bef2eddb79dda57801690aeeead693ebd1a9ff8557671f5ae136b3e65733306924bd00444cbc6e7c6235e5a2c77f","up":true},{"one":"28afc20d8f4779b285bb14870062dbb54796ec77623302e51bc1bafed9e2c35751c8469ffc482718e059875dfa2226195ed10999e251498cba3a444896cb67db","other":"4bd17847bdf60ea93a670a84a0ff8fe028d35228e814d6ebc0ae4fa586ddef03cd79390d541d28ca3c05a7241ffe92ac182e63c251176b40db8fe05fefaa82be","up":false},{"one":"c89dbada7195464e732671ac6fff014cacfb4c879b63b6b84e7c1bce367522f759bd06e504b15f43a1735c6322356747fa5c4951882d4fd6cdf6f7cf13726719","other":"51ba4faf0988717a37dcddc0a60a70ead33bde310184fc450f9ca73c67f931e6767ad5930bcf409e5aeb613a9ff7a03e47de6fc13b33d8af0b87b38822ae6888","up":false},{"one":"4de606aa7e722197b918c5f7f0db86a3081d48e89d21428b04f19c3ff3755eac0bddbff5fad8bda94b9e57f58fba2fecdbabbf710f7afb381bf4f1a4fe55cd93","other":"3540d888c3207d6df233afd1164ff9dde2551730862772547e04f7311de364968e113f38a7dea1ab0916a7f8307017de5b49578fa4ebcc39651e541fde51be48","up":false},{"one":"5d96577324edf1b5a1626999925982af1e0ba7bed8edcc3f740ba434f4b003cbbe2d632cad327c76e5b490d08c091c4a7b473353ab59139493657eb9525b8be2","other":"1955bedf0bc9044b13a2c16158087123197c74147c86aa3b9389d308a364e80edbc573bcc836d8a262a77f3c9233ebddb1b82eca83cd0a0e4bda6564c443bb70","up":true},{"one":"5d96577324edf1b5a1626999925982af1e0ba7bed8edcc3f740ba434f4b003cbbe2d632cad327c76e5b490d08c091c4a7b473353ab59139493657eb9525b8be2","other":"188bf77c9c1e45f009efe7aefdb040bdb47763980fe7eb0851295d657fa2a8978efbd2997c1dc30f4f0874eecf9ca9550487cf41da237b84d071963d35b6baff","up":true},{"one":"dafb58b2fc8a14f2b23b7df33d28aa7847a08f80e9c21a654d4c97d928e1afe6585644d27f22442cf70d229c32783be6a03c0920be153fc4d9f3b273dfa90ec3","other":"fa897ba112f34839064c6871a4c9504c5d709eff5095a137c6a42726d58eb623af976cb96cc30db67e6ac9347c769f032aa4ebda884285a057059040c008ad3e","up":true},{"one":"44462055ba68fdef337dd19d8123aace9a12284c13bc97687416b6b4ca0c94234ba7db6823651fc021d6ac1539e0c5321e763a7a12c9e7c8a583aac5369817d8","other":"73319a301ad3cf0ec09549d817c9523d61b74abb0cad87b737d41d900321e52722a84355f6f87bc7a5f848818c89a021bb0f3e5994f67c9a7b5bbfc98188a376","up":true},{"one":"eb097186ff58d96a7ead7a7f9c05a44075d84537bd4fd3f82857bf2c45bee1c6dece434a7707cde69e96f02366859cab4c991fdb7615e113a868d4b9c7524a45","other":"a6ca1d5340f2d7021f541c81cf9aea519675462c8443bb6ddd93919962561b8f5a8431c3ec7e7e7d46c600b653e9a0638d2bb07cf4e29516bf9c4d3653f451b0","up":true},{"one":"2d6d55edd34c0d9a0130b4806e409bbe18cdda5c2b221cf46136718ec20ffc9d8e92838d78aff92fbcc85f5d081da361dd1e3d7f3d4e1ea57877d6bb7aa0b6f7","other":"a9e0b763852706722dc904b494293f9399c0fa32255890aa720285b8160335bb618f36b68a81b875a805384179f600defef474d486b4ea04b003ef6477ab7907","up":true},{"one":"3e9c0bbd146d8b1040b4f379eecf802c27c4d0a70e64a9fb2e941a7edab9b00396b0b67fc5c891652743cdba3b342973ed49615b32da54b925954a799240431c","other":"bfef26733f5196a11484bcc28d88776e747189ae7cec883ff39a27cfeee6d9d1efb34560c9f8e75eec43fc069a2ce5f0c78107a36cc8a569d37bd5306aecf23a","up":false},{"one":"eb097186ff58d96a7ead7a7f9c05a44075d84537bd4fd3f82857bf2c45bee1c6dece434a7707cde69e96f02366859cab4c991fdb7615e113a868d4b9c7524a45","other":"b38213eaa5b419de787b70073ad8c7c819e48c5f76dec1507b54f1d7cb027211facbe7a170ac50212abe130935e8947d5a19d6b13790114e71cc18357902a889","up":true},{"one":"a5cdff211813e17fadd43ec55a6cf4e97e6ca0c3b2cef0db58923b27d36207fd1a77146efb6093bd94d7eb89cc77d8c735fc64ab098839efc74a00b5e8687555","other":"077d2d032874e5ce70e9b928b7fe72c0326ba92394e16245e31d48b5731d3d32bfd86acf40825decff54bcd735e9ebfd94eba677c418ea7007baec9db4af676d","up":true},{"one":"1e3c83cabbe6852c987ae521b7fcb33185cf855c59b6235ebb8e57a6f860ccc159ddc01b4a21d251c8faca4559ceb271e046a51493ba148c0d3aed97ad208969","other":"f6a07a1d361a4671e997d5eaadae61736291aff3896cb69f06bbc19bf7536dd152e0b15422b2fd9f8a9d2f9a251c9a07d0140319900e2cc9f25a59025c7dc91f","up":false},{"one":"87fce129511a1be2777052d24b606acdfe7067f4e874ab04674a68664b378ea208975f7269a72af889d3d23cd930b6a181afa2cdef3f9f9491f715bd96ad8dc0","other":"f04c3ae9fe957a14c249acf3ea2e8407d04d108fc01e75f6d52aaf5073b3450025012d138a75b857473eea4d20e57c99b92bff9041f269d995543d7c67a92ec6","up":true},{"one":"f8052e328014f39157036f3dcecdb23419c0959473a88282605f10add681ef5cbfb1e926b522f98b8401272113b677a67225874d1afb0bff4b11140cc071de44","other":"f62bd19b0fd052207743ce53c3d48a3a71e9219b75e41a9497a43e6368e559d5487ff1ab644f2df4106b500583e4344515f73187eec773115deb977b4ebc3514","up":true},{"one":"9e6c1c6e871638182c4b54ac89352ef5c2bca0a99424a1369013e7c182883da0e8d7ab96b3c8254c31fa315b941d8ddee153157626821fc78c2cae951c1c9053","other":"2502fc8ee0ccda79ad1dbd9c7cec625da85980b9116bdd56dc367d508039e25e5f65183293006e5b0df72fa9037a48bd2b133a757940d3587ff77ae2392e3eaf","up":true},{"one":"a5cdff211813e17fadd43ec55a6cf4e97e6ca0c3b2cef0db58923b27d36207fd1a77146efb6093bd94d7eb89cc77d8c735fc64ab098839efc74a00b5e8687555","other":"077bcadade93e0d361e94f76dff464d61912bc067ce2ce17ebcabd757cca201cd64624ea809d99dd8ecb749d40528db9b3eb503ef5ec05e8845044cfaef720dc","up":true},{"one":"28afc20d8f4779b285bb14870062dbb54796ec77623302e51bc1bafed9e2c35751c8469ffc482718e059875dfa2226195ed10999e251498cba3a444896cb67db","other":"f62bd19b0fd052207743ce53c3d48a3a71e9219b75e41a9497a43e6368e559d5487ff1ab644f2df4106b500583e4344515f73187eec773115deb977b4ebc3514","up":false},{"one":"9c3be147f9fe0fa34e553d9e4332969086ea7fa65294b61ca35c9f731f6b81d0b70cdcfe2ba52b6cea3c0de14b7ea40031b5cc40661c4bb821147894130d7bf5","other":"f2ea93f43be9d0c3fa21f1496dc13c778977a6afdcba24c8b146de7dca2cdde62a5b792aab969e5b4b6c56f63066b336580d911f206049cc24cac32a25fc4306","up":true},{"one":"f8052e328014f39157036f3dcecdb23419c0959473a88282605f10add681ef5cbfb1e926b522f98b8401272113b677a67225874d1afb0bff4b11140cc071de44","other":"f2ea93f43be9d0c3fa21f1496dc13c778977a6afdcba24c8b146de7dca2cdde62a5b792aab969e5b4b6c56f63066b336580d911f206049cc24cac32a25fc4306","up":true},{"one":"9e6c1c6e871638182c4b54ac89352ef5c2bca0a99424a1369013e7c182883da0e8d7ab96b3c8254c31fa315b941d8ddee153157626821fc78c2cae951c1c9053","other":"59730132a01ba848a3c050bb6234bca9a72deba33716960fc3ec89b186bfcd313b9bbf049939d5805ff98db2c53a9421ce6ec97d8b4cdbaea53ba264d80d0734","up":true},{"one":"9c3be147f9fe0fa34e553d9e4332969086ea7fa65294b61ca35c9f731f6b81d0b70cdcfe2ba52b6cea3c0de14b7ea40031b5cc40661c4bb821147894130d7bf5","other":"73be4d2291c68ca4554a86fa170f7595210e1b6bbbeef3c1d5623a2b5d03a8fd6e26caa26afc639c20c8a351a89dad1086f91734f09afab62d28ec17b700fa01","up":true},{"one":"3572a22097a313b3adef95a7b6cc679f8d1201a156d764e61a9fbc63d123fb4826f7125402fb6569beed359e1c1e5e6cb6993a75975da6cd4ce15669a2eea758","other":"4de606aa7e722197b918c5f7f0db86a3081d48e89d21428b04f19c3ff3755eac0bddbff5fad8bda94b9e57f58fba2fecdbabbf710f7afb381bf4f1a4fe55cd93","up":false},{"one":"077d2d032874e5ce70e9b928b7fe72c0326ba92394e16245e31d48b5731d3d32bfd86acf40825decff54bcd735e9ebfd94eba677c418ea7007baec9db4af676d","other":"a40391285d1a97f1fb368b20c8e4d02be1bdebc0db41f00f99aac2f01893dc12256cd5a711117a981fbb3f9dfea18c19cf3603e925dbd67c4032b22b41eab8d5","up":true},{"one":"f6a07a1d361a4671e997d5eaadae61736291aff3896cb69f06bbc19bf7536dd152e0b15422b2fd9f8a9d2f9a251c9a07d0140319900e2cc9f25a59025c7dc91f","other":"0e8c1a6b70524c4fdc492c74348bac4ccd5d140bd41352607e8cfba45561afb1e6e12f3e2fcf03c1778c9ae5ae19cb9218ee2d613983768f54e3f54e69bb6600","up":true},{"one":"3572a22097a313b3adef95a7b6cc679f8d1201a156d764e61a9fbc63d123fb4826f7125402fb6569beed359e1c1e5e6cb6993a75975da6cd4ce15669a2eea758","other":"9e6c1c6e871638182c4b54ac89352ef5c2bca0a99424a1369013e7c182883da0e8d7ab96b3c8254c31fa315b941d8ddee153157626821fc78c2cae951c1c9053","up":true},{"one":"c93cb2df7ba6de8009872f5f7565891040d42e3b193ef1cdb321a0c167cc8fb8138900982bb8f6918fbaefac6e02dda01ee40f7a6beba1990dd44abe03cc3d01","other":"bf1e6eeb8b229f63b49213db499b71dcfe0ae45ee3f14685c7cbfa3f0a2150e52a89c853f4cd8c7a92e6e5f6083044efddfa17391662e3cff6290da679520404","up":false},{"one":"56e8f792ec9a75ec9e91d472b8a4b023655dd68c2a448a33397b125fe3584a5efa1b492e47077b24acfe0396b73e1cb564a6a6b2aee1b457781dfaf6d43fcaed","other":"31ac37862416c0e229c4a088ec179f23bdd1bf12dd464eb11c630ad531d7c3438671862e5458e2f6fbb32b857f857e6b8c17e5d93eb29a0e78bb5a65d7eb648c","up":false},{"one":"dafb58b2fc8a14f2b23b7df33d28aa7847a08f80e9c21a654d4c97d928e1afe6585644d27f22442cf70d229c32783be6a03c0920be153fc4d9f3b273dfa90ec3","other":"a9e0b763852706722dc904b494293f9399c0fa32255890aa720285b8160335bb618f36b68a81b875a805384179f600defef474d486b4ea04b003ef6477ab7907","up":false},{"one":"f8052e328014f39157036f3dcecdb23419c0959473a88282605f10add681ef5cbfb1e926b522f98b8401272113b677a67225874d1afb0bff4b11140cc071de44","other":"9c3be147f9fe0fa34e553d9e4332969086ea7fa65294b61ca35c9f731f6b81d0b70cdcfe2ba52b6cea3c0de14b7ea40031b5cc40661c4bb821147894130d7bf5","up":true},{"one":"44462055ba68fdef337dd19d8123aace9a12284c13bc97687416b6b4ca0c94234ba7db6823651fc021d6ac1539e0c5321e763a7a12c9e7c8a583aac5369817d8","other":"9c3be147f9fe0fa34e553d9e4332969086ea7fa65294b61ca35c9f731f6b81d0b70cdcfe2ba52b6cea3c0de14b7ea40031b5cc40661c4bb821147894130d7bf5","up":true},{"one":"56e8f792ec9a75ec9e91d472b8a4b023655dd68c2a448a33397b125fe3584a5efa1b492e47077b24acfe0396b73e1cb564a6a6b2aee1b457781dfaf6d43fcaed","other":"5d96577324edf1b5a1626999925982af1e0ba7bed8edcc3f740ba434f4b003cbbe2d632cad327c76e5b490d08c091c4a7b473353ab59139493657eb9525b8be2","up":false},{"one":"bf1e6eeb8b229f63b49213db499b71dcfe0ae45ee3f14685c7cbfa3f0a2150e52a89c853f4cd8c7a92e6e5f6083044efddfa17391662e3cff6290da679520404","other":"2d6d55edd34c0d9a0130b4806e409bbe18cdda5c2b221cf46136718ec20ffc9d8e92838d78aff92fbcc85f5d081da361dd1e3d7f3d4e1ea57877d6bb7aa0b6f7","up":false},{"one":"3e9c0bbd146d8b1040b4f379eecf802c27c4d0a70e64a9fb2e941a7edab9b00396b0b67fc5c891652743cdba3b342973ed49615b32da54b925954a799240431c","other":"41994605708232b4ca7448c3bc0760a7b86bf26d442091e5ce6e92eac94925721d7e0eca04bdd03bb1bba1ef92deeccd4bf1b7c6c3318b7e8d031965c6646761","up":false},{"one":"f8052e328014f39157036f3dcecdb23419c0959473a88282605f10add681ef5cbfb1e926b522f98b8401272113b677a67225874d1afb0bff4b11140cc071de44","other":"b09af9e5552e72f918174963dad58a4492d3afa120f78e43820df7bff7fae9f6b52bc6c8c73d3a9af91d20134f4ff1b037db2ef0bc3d8c495a771d63de678bc0","up":false},{"one":"3c6faa2e75a1699ddadd0e21fd35d3d6215715cfdc2dc89961cfd66773d2541776e785f3ebc833a70e3d1017a4edc571a5d5d9f9fbfc3fa0a8588f6c5023c164","other":"f6a07a1d361a4671e997d5eaadae61736291aff3896cb69f06bbc19bf7536dd152e0b15422b2fd9f8a9d2f9a251c9a07d0140319900e2cc9f25a59025c7dc91f","up":false},{"one":"c93cb2df7ba6de8009872f5f7565891040d42e3b193ef1cdb321a0c167cc8fb8138900982bb8f6918fbaefac6e02dda01ee40f7a6beba1990dd44abe03cc3d01","other":"a5cdff211813e17fadd43ec55a6cf4e97e6ca0c3b2cef0db58923b27d36207fd1a77146efb6093bd94d7eb89cc77d8c735fc64ab098839efc74a00b5e8687555","up":false},{"one":"20bdc859d58d8bf419df64fd6ee1d4363c1d5f403af3abef2720d7d3933924672e12e23e5d76b28e0f6726acf58bdc5eb258cba635e327cbd0b564523305da75","other":"e0420ba2a293315d810928a0e09a507c6aaf93977ba2c7598e9b83723b4a66682398ea17542c26767c7ff0f4ca09c537d3cc10dad283f079f1de73e25e87cb5c","up":false},{"one":"56e8f792ec9a75ec9e91d472b8a4b023655dd68c2a448a33397b125fe3584a5efa1b492e47077b24acfe0396b73e1cb564a6a6b2aee1b457781dfaf6d43fcaed","other":"f0b2f1e8d46be656109adb18c60677ac9eb8fce7f42e15d9dbb25f94b4e426064780eaf32b79954b9bb72ea89953175da8de35380aaba18931cca374a7de2b11","up":false},{"one":"87fce129511a1be2777052d24b606acdfe7067f4e874ab04674a68664b378ea208975f7269a72af889d3d23cd930b6a181afa2cdef3f9f9491f715bd96ad8dc0","other":"155805f787600f9f9518cf8836f491885b64868bfe0023975bcd12776925a424fb5aa3199dc178e83294e97f347a373d05d2422578a08eeeb2d15a178d28964f","up":false},{"one":"155805f787600f9f9518cf8836f491885b64868bfe0023975bcd12776925a424fb5aa3199dc178e83294e97f347a373d05d2422578a08eeeb2d15a178d28964f","other":"f04c3ae9fe957a14c249acf3ea2e8407d04d108fc01e75f6d52aaf5073b3450025012d138a75b857473eea4d20e57c99b92bff9041f269d995543d7c67a92ec6","up":false},{"one":"f04c3ae9fe957a14c249acf3ea2e8407d04d108fc01e75f6d52aaf5073b3450025012d138a75b857473eea4d20e57c99b92bff9041f269d995543d7c67a92ec6","other":"d90a81a583c82d626b92f27244f027da4a0ae76e6d3bdc1de0af7be01798f1fb04b34ce60c6d8651a39d7a70915438a4aa63e5adf844a9f7e38dbf0b1dba754d","up":false},{"one":"56e8f792ec9a75ec9e91d472b8a4b023655dd68c2a448a33397b125fe3584a5efa1b492e47077b24acfe0396b73e1cb564a6a6b2aee1b457781dfaf6d43fcaed","other":"e59940a6dfe35a6214e2e3daba9ad94e630004cd8f029e13a6649a56dc528ff94bc09d8d21a2f14a56b4ff759b60ebf3d27c1029862c183b8416fa3e950bdb55","up":false},{"one":"f8052e328014f39157036f3dcecdb23419c0959473a88282605f10add681ef5cbfb1e926b522f98b8401272113b677a67225874d1afb0bff4b11140cc071de44","other":"3540d888c3207d6df233afd1164ff9dde2551730862772547e04f7311de364968e113f38a7dea1ab0916a7f8307017de5b49578fa4ebcc39651e541fde51be48","up":false},{"one":"56e8f792ec9a75ec9e91d472b8a4b023655dd68c2a448a33397b125fe3584a5efa1b492e47077b24acfe0396b73e1cb564a6a6b2aee1b457781dfaf6d43fcaed","other":"28afc20d8f4779b285bb14870062dbb54796ec77623302e51bc1bafed9e2c35751c8469ffc482718e059875dfa2226195ed10999e251498cba3a444896cb67db","up":false},{"one":"f04c3ae9fe957a14c249acf3ea2e8407d04d108fc01e75f6d52aaf5073b3450025012d138a75b857473eea4d20e57c99b92bff9041f269d995543d7c67a92ec6","other":"a40391285d1a97f1fb368b20c8e4d02be1bdebc0db41f00f99aac2f01893dc12256cd5a711117a981fbb3f9dfea18c19cf3603e925dbd67c4032b22b41eab8d5","up":false},{"one":"f8052e328014f39157036f3dcecdb23419c0959473a88282605f10add681ef5cbfb1e926b522f98b8401272113b677a67225874d1afb0bff4b11140cc071de44","other":"7a509686ebce91778fe22e834a94ab03f92457d41385099ba657fe62c7469a9669bddb9a3d7b0150efa1d2f40c69bc786c7f4ede1cf8b19411eea1d23cb7d56c","up":false},{"one":"1e3c83cabbe6852c987ae521b7fcb33185cf855c59b6235ebb8e57a6f860ccc159ddc01b4a21d251c8faca4559ceb271e046a51493ba148c0d3aed97ad208969","other":"0e8c1a6b70524c4fdc492c74348bac4ccd5d140bd41352607e8cfba45561afb1e6e12f3e2fcf03c1778c9ae5ae19cb9218ee2d613983768f54e3f54e69bb6600","up":false},{"one":"4448a59bde9edb93edcdb4a77f3e2277b9c01ffea45496ee0533eb5192955a08a0f982e25cf772e0dae68735a55b7acd221f6ba7b134f1e999087bee182330e8","other":"9e6c1c6e871638182c4b54ac89352ef5c2bca0a99424a1369013e7c182883da0e8d7ab96b3c8254c31fa315b941d8ddee153157626821fc78c2cae951c1c9053","up":false},{"one":"59730132a01ba848a3c050bb6234bca9a72deba33716960fc3ec89b186bfcd313b9bbf049939d5805ff98db2c53a9421ce6ec97d8b4cdbaea53ba264d80d0734","other":"5d96577324edf1b5a1626999925982af1e0ba7bed8edcc3f740ba434f4b003cbbe2d632cad327c76e5b490d08c091c4a7b473353ab59139493657eb9525b8be2","up":false},{"one":"276256790c9317d09ff7802f4ad0a85840fe62527390ce1790e1e3186e8b3f04acfaa41dcd02303d333423678a4037e4f4854676e79ced3232a3dbd772cc2680","other":"9c6dcfef0e128dbfeca58b8ac625b08fb447b0d579bd3f18bc0e2be60d1ec2274595d0554ddba0ca7eb660099d3ea146d8076792b46c93841d2ecf8cf608f5ba","up":false},{"one":"27fb8fcda1986644f985d68430c399f0299644b00b234c355362721081d12f9eb7686eea8f92eabda1d342bf56255e51c07b200c6233f95ac009f15b874eee97","other":"03e478a3aae82e06e215e40272a420037a61442d11c49c367a5ee6a21868d29a17ea8b9284f013d020c4740f296a6a22bc64d33d1c2807f9ab8dc48c0cfec18a","up":false},{"one":"9e6c1c6e871638182c4b54ac89352ef5c2bca0a99424a1369013e7c182883da0e8d7ab96b3c8254c31fa315b941d8ddee153157626821fc78c2cae951c1c9053","other":"3540d888c3207d6df233afd1164ff9dde2551730862772547e04f7311de364968e113f38a7dea1ab0916a7f8307017de5b49578fa4ebcc39651e541fde51be48","up":false},{"one":"4de606aa7e722197b918c5f7f0db86a3081d48e89d21428b04f19c3ff3755eac0bddbff5fad8bda94b9e57f58fba2fecdbabbf710f7afb381bf4f1a4fe55cd93","other":"44462055ba68fdef337dd19d8123aace9a12284c13bc97687416b6b4ca0c94234ba7db6823651fc021d6ac1539e0c5321e763a7a12c9e7c8a583aac5369817d8","up":false},{"one":"276256790c9317d09ff7802f4ad0a85840fe62527390ce1790e1e3186e8b3f04acfaa41dcd02303d333423678a4037e4f4854676e79ced3232a3dbd772cc2680","other":"3e7820bb15c07f515bd63791b66136723dcc9878b3145fe0f238f6b41e3f2f7565ae55ef24f08ae461950ce1ae0c8a80fe5e4fd4f2f88c4acf4a2c94640df239","up":false},{"one":"f04c3ae9fe957a14c249acf3ea2e8407d04d108fc01e75f6d52aaf5073b3450025012d138a75b857473eea4d20e57c99b92bff9041f269d995543d7c67a92ec6","other":"51302ef7b50922398ad802e917390bb4a3c24c877f2c2bcb7fcb34de9feca22673a2c594639914fe46a28837ffadfd03bb673afbc856aff5e59caf8e76082482","up":false},{"one":"cdd86dea7dde96ff7cc1e3248fd17d107c83f2cc7ce2111c41530448962763309e91a05b5dad4663d0e02db59ed4129ab0c3e1eedc42c654e39d29f99038063b","other":"dafb58b2fc8a14f2b23b7df33d28aa7847a08f80e9c21a654d4c97d928e1afe6585644d27f22442cf70d229c32783be6a03c0920be153fc4d9f3b273dfa90ec3","up":false},{"one":"4448a59bde9edb93edcdb4a77f3e2277b9c01ffea45496ee0533eb5192955a08a0f982e25cf772e0dae68735a55b7acd221f6ba7b134f1e999087bee182330e8","other":"7a509686ebce91778fe22e834a94ab03f92457d41385099ba657fe62c7469a9669bddb9a3d7b0150efa1d2f40c69bc786c7f4ede1cf8b19411eea1d23cb7d56c","up":false},{"one":"a5cdff211813e17fadd43ec55a6cf4e97e6ca0c3b2cef0db58923b27d36207fd1a77146efb6093bd94d7eb89cc77d8c735fc64ab098839efc74a00b5e8687555","other":"bf1e6eeb8b229f63b49213db499b71dcfe0ae45ee3f14685c7cbfa3f0a2150e52a89c853f4cd8c7a92e6e5f6083044efddfa17391662e3cff6290da679520404","up":false},{"one":"27fb8fcda1986644f985d68430c399f0299644b00b234c355362721081d12f9eb7686eea8f92eabda1d342bf56255e51c07b200c6233f95ac009f15b874eee97","other":"e0420ba2a293315d810928a0e09a507c6aaf93977ba2c7598e9b83723b4a66682398ea17542c26767c7ff0f4ca09c537d3cc10dad283f079f1de73e25e87cb5c","up":false},{"one":"eb097186ff58d96a7ead7a7f9c05a44075d84537bd4fd3f82857bf2c45bee1c6dece434a7707cde69e96f02366859cab4c991fdb7615e113a868d4b9c7524a45","other":"670949178a5fad22da03af1e206c814a797c0e9eb4e3371f83612f121e5b56e767706a3ae36628cd0c86dd7bd1586ca4df57e2de27b28a31284ecf9176d330e5","up":false},{"one":"dafb58b2fc8a14f2b23b7df33d28aa7847a08f80e9c21a654d4c97d928e1afe6585644d27f22442cf70d229c32783be6a03c0920be153fc4d9f3b273dfa90ec3","other":"b38213eaa5b419de787b70073ad8c7c819e48c5f76dec1507b54f1d7cb027211facbe7a170ac50212abe130935e8947d5a19d6b13790114e71cc18357902a889","up":false},{"one":"27fb8fcda1986644f985d68430c399f0299644b00b234c355362721081d12f9eb7686eea8f92eabda1d342bf56255e51c07b200c6233f95ac009f15b874eee97","other":"20bdc859d58d8bf419df64fd6ee1d4363c1d5f403af3abef2720d7d3933924672e12e23e5d76b28e0f6726acf58bdc5eb258cba635e327cbd0b564523305da75","up":false},{"one":"4448a59bde9edb93edcdb4a77f3e2277b9c01ffea45496ee0533eb5192955a08a0f982e25cf772e0dae68735a55b7acd221f6ba7b134f1e999087bee182330e8","other":"4de606aa7e722197b918c5f7f0db86a3081d48e89d21428b04f19c3ff3755eac0bddbff5fad8bda94b9e57f58fba2fecdbabbf710f7afb381bf4f1a4fe55cd93","up":false},{"one":"276256790c9317d09ff7802f4ad0a85840fe62527390ce1790e1e3186e8b3f04acfaa41dcd02303d333423678a4037e4f4854676e79ced3232a3dbd772cc2680","other":"489660042a8867d90a16ebb013968db26ca3edfc70f53320f511e35b3703eed09fbd787be5c06726a570a54aa15d129cd10db741523adf297929f909be4a0c71","up":false},{"one":"155805f787600f9f9518cf8836f491885b64868bfe0023975bcd12776925a424fb5aa3199dc178e83294e97f347a373d05d2422578a08eeeb2d15a178d28964f","other":"3e9c0bbd146d8b1040b4f379eecf802c27c4d0a70e64a9fb2e941a7edab9b00396b0b67fc5c891652743cdba3b342973ed49615b32da54b925954a799240431c","up":false},{"one":"f04c3ae9fe957a14c249acf3ea2e8407d04d108fc01e75f6d52aaf5073b3450025012d138a75b857473eea4d20e57c99b92bff9041f269d995543d7c67a92ec6","other":"872cdbb6d74fb55fd2d51877ef7804bdd2eeb6de0297eb2ce18b67e52379b147d54a46d2385ec9293eb21736bed4191d92c5c75e8e81fc5a6c691970e019f570","up":false},{"one":"dafb58b2fc8a14f2b23b7df33d28aa7847a08f80e9c21a654d4c97d928e1afe6585644d27f22442cf70d229c32783be6a03c0920be153fc4d9f3b273dfa90ec3","other":"a6ca1d5340f2d7021f541c81cf9aea519675462c8443bb6ddd93919962561b8f5a8431c3ec7e7e7d46c600b653e9a0638d2bb07cf4e29516bf9c4d3653f451b0","up":false},{"one":"a5cdff211813e17fadd43ec55a6cf4e97e6ca0c3b2cef0db58923b27d36207fd1a77146efb6093bd94d7eb89cc77d8c735fc64ab098839efc74a00b5e8687555","other":"afb5754b4748b7ac5628e32b242c90aab0e2fc7da58d8d5c8c775d13d8a6fd32240f1b89021587858168cbe7b3ea7ad07807728655eae0a9907060494a7c99ca","up":false},{"one":"340420ee18d55913f790d0fcc2305b40b1e7bef2eddb79dda57801690aeeead693ebd1a9ff8557671f5ae136b3e65733306924bd00444cbc6e7c6235e5a2c77f","other":"56b25623ac935f3a8aac1e2603a6bd15ace1e5714671954b47f2cab960cf47922828f415105602408d0a732a893ebeea6f9afab7f889bb235c81589548d09391","up":false},{"one":"a40391285d1a97f1fb368b20c8e4d02be1bdebc0db41f00f99aac2f01893dc12256cd5a711117a981fbb3f9dfea18c19cf3603e925dbd67c4032b22b41eab8d5","other":"87fce129511a1be2777052d24b606acdfe7067f4e874ab04674a68664b378ea208975f7269a72af889d3d23cd930b6a181afa2cdef3f9f9491f715bd96ad8dc0","up":false},{"one":"c93cb2df7ba6de8009872f5f7565891040d42e3b193ef1cdb321a0c167cc8fb8138900982bb8f6918fbaefac6e02dda01ee40f7a6beba1990dd44abe03cc3d01","other":"2d6d55edd34c0d9a0130b4806e409bbe18cdda5c2b221cf46136718ec20ffc9d8e92838d78aff92fbcc85f5d081da361dd1e3d7f3d4e1ea57877d6bb7aa0b6f7","up":false},{"one":"5b4de68680c5d1a75cccd5e7a82319c031f5d61d79cbb6532e1254ab81c833c3fafb54390cca7a770e84690c490fcba90482b35321870f8506335a2f57cc052e","other":"dafb58b2fc8a14f2b23b7df33d28aa7847a08f80e9c21a654d4c97d928e1afe6585644d27f22442cf70d229c32783be6a03c0920be153fc4d9f3b273dfa90ec3","up":false},{"one":"276256790c9317d09ff7802f4ad0a85840fe62527390ce1790e1e3186e8b3f04acfaa41dcd02303d333423678a4037e4f4854676e79ced3232a3dbd772cc2680","other":"f8052e328014f39157036f3dcecdb23419c0959473a88282605f10add681ef5cbfb1e926b522f98b8401272113b677a67225874d1afb0bff4b11140cc071de44","up":false},{"one":"5b4de68680c5d1a75cccd5e7a82319c031f5d61d79cbb6532e1254ab81c833c3fafb54390cca7a770e84690c490fcba90482b35321870f8506335a2f57cc052e","other":"a9e0b763852706722dc904b494293f9399c0fa32255890aa720285b8160335bb618f36b68a81b875a805384179f600defef474d486b4ea04b003ef6477ab7907","up":false},{"one":"56b25623ac935f3a8aac1e2603a6bd15ace1e5714671954b47f2cab960cf47922828f415105602408d0a732a893ebeea6f9afab7f889bb235c81589548d09391","other":"82a774be7146766585d2bec6b69b7803aa956f492a53d8ed5f071becdbbc617562885d8430f0afd505210aab7b032428fbea32c82dffbd12d9ccba776ef4729b","up":false},{"one":"9e6c1c6e871638182c4b54ac89352ef5c2bca0a99424a1369013e7c182883da0e8d7ab96b3c8254c31fa315b941d8ddee153157626821fc78c2cae951c1c9053","other":"f06ec3a90d34300f9fa2d48aea0c6b5f2f01f7833ffb0fad30e7f57e3916e344f3a4f9efe38e222443b8b00d3c7f5221c672491a129e4958e574afc283bd45b1","up":false},{"one":"da15d60a4b9a8816ce24c20f6c941c51229c1fb5e070b8b29be2977c2f7b41f8f17e4b6efe75f465e7935ded1ba17472f046eac73393db7197018fa86d11c31f","other":"276256790c9317d09ff7802f4ad0a85840fe62527390ce1790e1e3186e8b3f04acfaa41dcd02303d333423678a4037e4f4854676e79ced3232a3dbd772cc2680","up":false},{"one":"155805f787600f9f9518cf8836f491885b64868bfe0023975bcd12776925a424fb5aa3199dc178e83294e97f347a373d05d2422578a08eeeb2d15a178d28964f","other":"077d2d032874e5ce70e9b928b7fe72c0326ba92394e16245e31d48b5731d3d32bfd86acf40825decff54bcd735e9ebfd94eba677c418ea7007baec9db4af676d","up":false},{"one":"155805f787600f9f9518cf8836f491885b64868bfe0023975bcd12776925a424fb5aa3199dc178e83294e97f347a373d05d2422578a08eeeb2d15a178d28964f","other":"077bcadade93e0d361e94f76dff464d61912bc067ce2ce17ebcabd757cca201cd64624ea809d99dd8ecb749d40528db9b3eb503ef5ec05e8845044cfaef720dc","up":false},{"one":"cdd86dea7dde96ff7cc1e3248fd17d107c83f2cc7ce2111c41530448962763309e91a05b5dad4663d0e02db59ed4129ab0c3e1eedc42c654e39d29f99038063b","other":"8f625a4e4f4fd980c796d3aa535e58a39722492480cf6982d43fab02de63a5b4c1b5c7cd8402171dd792bb5d9c3e2bdd38176c061dbe3e5b0592af1339e3fd82","up":false},{"one":"5b4de68680c5d1a75cccd5e7a82319c031f5d61d79cbb6532e1254ab81c833c3fafb54390cca7a770e84690c490fcba90482b35321870f8506335a2f57cc052e","other":"20f171ab01a814a2856a6cbe7929269f18f6329914289515e2cb9d078ac14ebdae457789dd638c6415b062799114570f556147d4bf9ac850f00b6d0762765ac1","up":false},{"one":"5d96577324edf1b5a1626999925982af1e0ba7bed8edcc3f740ba434f4b003cbbe2d632cad327c76e5b490d08c091c4a7b473353ab59139493657eb9525b8be2","other":"28afc20d8f4779b285bb14870062dbb54796ec77623302e51bc1bafed9e2c35751c8469ffc482718e059875dfa2226195ed10999e251498cba3a444896cb67db","up":false},{"one":"5b4de68680c5d1a75cccd5e7a82319c031f5d61d79cbb6532e1254ab81c833c3fafb54390cca7a770e84690c490fcba90482b35321870f8506335a2f57cc052e","other":"cdd86dea7dde96ff7cc1e3248fd17d107c83f2cc7ce2111c41530448962763309e91a05b5dad4663d0e02db59ed4129ab0c3e1eedc42c654e39d29f99038063b","up":false},{"one":"56b25623ac935f3a8aac1e2603a6bd15ace1e5714671954b47f2cab960cf47922828f415105602408d0a732a893ebeea6f9afab7f889bb235c81589548d09391","other":"ed1ab28230ed533abf25633508d54f32bbff78a10c7a15fad5c2320cda9d9669c6d0e15689d8885400e64cbcd81730456f8f4bd5c98681d2cd8a8d4e1daec553","up":false},{"one":"8f625a4e4f4fd980c796d3aa535e58a39722492480cf6982d43fab02de63a5b4c1b5c7cd8402171dd792bb5d9c3e2bdd38176c061dbe3e5b0592af1339e3fd82","other":"dafb58b2fc8a14f2b23b7df33d28aa7847a08f80e9c21a654d4c97d928e1afe6585644d27f22442cf70d229c32783be6a03c0920be153fc4d9f3b273dfa90ec3","up":false},{"one":"155805f787600f9f9518cf8836f491885b64868bfe0023975bcd12776925a424fb5aa3199dc178e83294e97f347a373d05d2422578a08eeeb2d15a178d28964f","other":"18bb6572965f4263c5a4d59a73027abc57a46122125ee58d871e95c993e6a1e8230438ce696a5f8880a08749837268b54319f7b0aa254c1a5bd453a8e9bcf84f","up":false},{"one":"155805f787600f9f9518cf8836f491885b64868bfe0023975bcd12776925a424fb5aa3199dc178e83294e97f347a373d05d2422578a08eeeb2d15a178d28964f","other":"a40391285d1a97f1fb368b20c8e4d02be1bdebc0db41f00f99aac2f01893dc12256cd5a711117a981fbb3f9dfea18c19cf3603e925dbd67c4032b22b41eab8d5","up":false}]} \ No newline at end of file diff --git a/swarm/network/stream/testing/snapshot_16.json b/swarm/network/stream/testing/snapshot_16.json new file mode 100644 index 0000000000..3d30298d76 --- /dev/null +++ b/swarm/network/stream/testing/snapshot_16.json @@ -0,0 +1 @@ +{"nodes":[{"node":{"info":{"id":"279f0a191892115b8db4e2689cc5e1bc19019e8f5228f4f093f35c48fa2f606fd00a2ec5cf0fa4657ad3606e14643c3be8d49350ad2673f2ad12e17c0174b0d8","name":"node_279f0a191892115b8db4e2689cc5e1bc19019e8f5228f4f093f35c48fa2f606fd00a2ec5cf0fa4657ad3606e14643c3be8d49350ad2673f2ad12e17c0174b0d8","enode":"enode://279f0a191892115b8db4e2689cc5e1bc19019e8f5228f4f093f35c48fa2f606fd00a2ec5cf0fa4657ad3606e14643c3be8d49350ad2673f2ad12e17c0174b0d8@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"o3kFYsggm36W56vvmtKN4uRwoBknI05ISJZuDNFWUuk=","hive":"\n=========================================================================\nTue Apr 10 09:54:41 UTC 2018 KΛÐΞMLIΛ hive: queen's address: a37905\npopulation: 6 (15), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 4ce6 | 5 3c42 (0) 615c (0) 6d8b (0) 55cc (0)\n001 1 f64d | 3 f64d (0) fb55 (0) fc37 (0)\n002 2 9112 8484 | 5 8484 (0) 8bf9 (0) 9112 (0) 9121 (0)\n003 0 | 0\n============ DEPTH: 4 ==========================================\n004 2 a873 af99 | 2 a873 (0) af99 (0)\n005 0 | 0\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"279f0a191892115b8db4e2689cc5e1bc19019e8f5228f4f093f35c48fa2f606fd00a2ec5cf0fa4657ad3606e14643c3be8d49350ad2673f2ad12e17c0174b0d8","private_key":"3ff3a0c7dc8b63cac9255233d84cccad53d61f8c9e47539329c07e4f248fc6dd","name":"node_279f0a191892115b8db4e2689cc5e1bc19019e8f5228f4f093f35c48fa2f606fd00a2ec5cf0fa4657ad3606e14643c3be8d49350ad2673f2ad12e17c0174b0d8","services":["streamer"],"enable_msg_events":true,"port":62851},"up":true}},{"node":{"info":{"id":"2c3d17a3b019d9d32922f06aef03ac03f67777e382f0b86c6e4dac07e590f2dbf4cbd1cc7ed136b52bba897e7163dee926caa627111db6d948581ad1b2edbc3f","name":"node_2c3d17a3b019d9d32922f06aef03ac03f67777e382f0b86c6e4dac07e590f2dbf4cbd1cc7ed136b52bba897e7163dee926caa627111db6d948581ad1b2edbc3f","enode":"enode://2c3d17a3b019d9d32922f06aef03ac03f67777e382f0b86c6e4dac07e590f2dbf4cbd1cc7ed136b52bba897e7163dee926caa627111db6d948581ad1b2edbc3f@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"TOZVSPyEkMAuTGwFSb5zKaigXAkNYocK0QdeUuIEo7U=","hive":"\n=========================================================================\nTue Apr 10 09:54:41 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 4ce655\npopulation: 6 (15), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 8bf9 a379 | 11 f64d (0) fb55 (0) fc37 (0) 9fcd (0)\n001 1 3c42 | 1 3c42 (0)\n============ DEPTH: 2 ==========================================\n002 2 615c 6d8b | 2 615c (0) 6d8b (0)\n003 1 55cc | 1 55cc (0)\n004 0 | 0\n005 0 | 0\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"2c3d17a3b019d9d32922f06aef03ac03f67777e382f0b86c6e4dac07e590f2dbf4cbd1cc7ed136b52bba897e7163dee926caa627111db6d948581ad1b2edbc3f","private_key":"1ab5fd3f1885661af1829b42683ca1379ca90b1b2c5a0132027346c74001a154","name":"node_2c3d17a3b019d9d32922f06aef03ac03f67777e382f0b86c6e4dac07e590f2dbf4cbd1cc7ed136b52bba897e7163dee926caa627111db6d948581ad1b2edbc3f","services":["streamer"],"enable_msg_events":true,"port":62852},"up":true}},{"node":{"info":{"id":"6e327c2d9d3ffdae707ed067d15b83ad0ea81b96bb2a07331436f01c1e194ed90f630ef0eb6511f4849ede30c403e3c4ff3c2cb8021317de97f3ed5b1d990f49","name":"node_6e327c2d9d3ffdae707ed067d15b83ad0ea81b96bb2a07331436f01c1e194ed90f630ef0eb6511f4849ede30c403e3c4ff3c2cb8021317de97f3ed5b1d990f49","enode":"enode://6e327c2d9d3ffdae707ed067d15b83ad0ea81b96bb2a07331436f01c1e194ed90f630ef0eb6511f4849ede30c403e3c4ff3c2cb8021317de97f3ed5b1d990f49@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"i/l+wptrPKY47YL6MNA9DYMJyejx2yBx9KN96AUycQg=","hive":"\n=========================================================================\nTue Apr 10 09:54:41 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 8bf97e\npopulation: 7 (15), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 4ce6 | 5 3c42 (0) 615c (0) 6d8b (0) 55cc (0)\n001 1 fb55 | 3 fb55 (0) fc37 (0) f64d (0)\n002 1 af99 | 3 af99 (0) a873 (0) a379 (0)\n============ DEPTH: 3 ==========================================\n003 3 9fcd 9112 9121 | 3 9fcd (0) 9112 (0) 9121 (0)\n004 1 8484 | 1 8484 (0)\n005 0 | 0\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"6e327c2d9d3ffdae707ed067d15b83ad0ea81b96bb2a07331436f01c1e194ed90f630ef0eb6511f4849ede30c403e3c4ff3c2cb8021317de97f3ed5b1d990f49","private_key":"a90fea5197ac84a162db7a06ec739e075ee334026e792d83a3269526888c8b5d","name":"node_6e327c2d9d3ffdae707ed067d15b83ad0ea81b96bb2a07331436f01c1e194ed90f630ef0eb6511f4849ede30c403e3c4ff3c2cb8021317de97f3ed5b1d990f49","services":["streamer"],"enable_msg_events":true,"port":62853},"up":true}},{"node":{"info":{"id":"9aa1df8ddddd035e81ffc950f063714c3b6be24013108f8b99c32c25fc3a8582904f68c73fe63ebfb96143a12ab398f36c4070a3055c039491ca2f20be6774c2","name":"node_9aa1df8ddddd035e81ffc950f063714c3b6be24013108f8b99c32c25fc3a8582904f68c73fe63ebfb96143a12ab398f36c4070a3055c039491ca2f20be6774c2","enode":"enode://9aa1df8ddddd035e81ffc950f063714c3b6be24013108f8b99c32c25fc3a8582904f68c73fe63ebfb96143a12ab398f36c4070a3055c039491ca2f20be6774c2@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"kSHD/qfMyZd1+1reRg96DLdgAyMdE9RO0+TzzKGUcic=","hive":"\n=========================================================================\nTue Apr 10 09:54:41 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 9121c3\npopulation: 7 (15), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 3c42 | 5 3c42 (0) 615c (0) 6d8b (0) 55cc (0)\n001 1 fb55 | 3 f64d (0) fc37 (0) fb55 (0)\n002 1 af99 | 3 af99 (0) a873 (0) a379 (0)\n003 2 8484 8bf9 | 2 8484 (0) 8bf9 (0)\n============ DEPTH: 4 ==========================================\n004 1 9fcd | 1 9fcd (0)\n005 0 | 0\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 1 9112 | 1 9112 (0)\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"9aa1df8ddddd035e81ffc950f063714c3b6be24013108f8b99c32c25fc3a8582904f68c73fe63ebfb96143a12ab398f36c4070a3055c039491ca2f20be6774c2","private_key":"76b6f09c28f5568e7724e9850116bdbd6356152fefedc4b0a9747361d712964b","name":"node_9aa1df8ddddd035e81ffc950f063714c3b6be24013108f8b99c32c25fc3a8582904f68c73fe63ebfb96143a12ab398f36c4070a3055c039491ca2f20be6774c2","services":["streamer"],"enable_msg_events":true,"port":62854},"up":true}},{"node":{"info":{"id":"a1226991909b92dd4f22150b798e2b6312ffc62bad7a47d250e811c7e60cf5ceb6a87998f295e0bd392c0f5c15213115000781e498dd7eae79b67c7e7e19cf81","name":"node_a1226991909b92dd4f22150b798e2b6312ffc62bad7a47d250e811c7e60cf5ceb6a87998f295e0bd392c0f5c15213115000781e498dd7eae79b67c7e7e19cf81","enode":"enode://a1226991909b92dd4f22150b798e2b6312ffc62bad7a47d250e811c7e60cf5ceb6a87998f295e0bd392c0f5c15213115000781e498dd7eae79b67c7e7e19cf81@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"+1VYhbltV0KhDmiL18G7hC8ENMMZvwdtB/VF5MBVBgE=","hive":"\n=========================================================================\nTue Apr 10 09:54:41 UTC 2018 KΛÐΞMLIΛ hive: queen's address: fb5558\npopulation: 6 (15), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 3c42 | 5 3c42 (0) 615c (0) 6d8b (0) 55cc (0)\n001 3 8484 8bf9 9121 | 8 af99 (0) a873 (0) a379 (0) 8484 (0)\n002 0 | 0\n003 0 | 0\n============ DEPTH: 4 ==========================================\n004 1 f64d | 1 f64d (0)\n005 1 fc37 | 1 fc37 (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"a1226991909b92dd4f22150b798e2b6312ffc62bad7a47d250e811c7e60cf5ceb6a87998f295e0bd392c0f5c15213115000781e498dd7eae79b67c7e7e19cf81","private_key":"f7e7d60abb7d43d973131804e684ec99e77e81bf38165dda29f3ae026eb169f1","name":"node_a1226991909b92dd4f22150b798e2b6312ffc62bad7a47d250e811c7e60cf5ceb6a87998f295e0bd392c0f5c15213115000781e498dd7eae79b67c7e7e19cf81","services":["streamer"],"enable_msg_events":true,"port":62855},"up":true}},{"node":{"info":{"id":"1dcbfc79418f9a665e3154e07663b296ce086e54c23458b7113a011dca62e635245cab144d392716e5e90b60336b60927270b72bb4a1c5c85fbf959060fb3ee4","name":"node_1dcbfc79418f9a665e3154e07663b296ce086e54c23458b7113a011dca62e635245cab144d392716e5e90b60336b60927270b72bb4a1c5c85fbf959060fb3ee4","enode":"enode://1dcbfc79418f9a665e3154e07663b296ce086e54c23458b7113a011dca62e635245cab144d392716e5e90b60336b60927270b72bb4a1c5c85fbf959060fb3ee4@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"9k0xBtK7meaeJsB94Wj3/Or4VnKFn3wcA4/U3WttdYg=","hive":"\n=========================================================================\nTue Apr 10 09:54:41 UTC 2018 KΛÐΞMLIΛ hive: queen's address: f64d31\npopulation: 6 (15), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 3c42 | 5 615c (0) 6d8b (0) 55cc (0) 4ce6 (0)\n001 3 9112 a873 a379 | 8 8484 (0) 8bf9 (0) 9112 (0) 9121 (0)\n002 0 | 0\n003 0 | 0\n============ DEPTH: 4 ==========================================\n004 2 fc37 fb55 | 2 fc37 (0) fb55 (0)\n005 0 | 0\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"1dcbfc79418f9a665e3154e07663b296ce086e54c23458b7113a011dca62e635245cab144d392716e5e90b60336b60927270b72bb4a1c5c85fbf959060fb3ee4","private_key":"f88cd88c2c219d13b699ba7c7cf9adf16fc10be5d8e1f35b2ea260e7987ab76e","name":"node_1dcbfc79418f9a665e3154e07663b296ce086e54c23458b7113a011dca62e635245cab144d392716e5e90b60336b60927270b72bb4a1c5c85fbf959060fb3ee4","services":["streamer"],"enable_msg_events":true,"port":62856},"up":true}},{"node":{"info":{"id":"571afb6ce94d28cb7d5cd49b3af35d2b1e44c917a9d3d207ab6c7ae960eb625377334e62317f6c69b3004e2eef92682649df828f4a645a75309ee7014ee4a940","name":"node_571afb6ce94d28cb7d5cd49b3af35d2b1e44c917a9d3d207ab6c7ae960eb625377334e62317f6c69b3004e2eef92682649df828f4a645a75309ee7014ee4a940","enode":"enode://571afb6ce94d28cb7d5cd49b3af35d2b1e44c917a9d3d207ab6c7ae960eb625377334e62317f6c69b3004e2eef92682649df828f4a645a75309ee7014ee4a940@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"PEKHt3IvcesDo9VPtrGK6wv4SVz/vowQP+kCKfCDkso=","hive":"\n=========================================================================\nTue Apr 10 09:54:41 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 3c4287\npopulation: 10 (15), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 6 9fcd 9121 af99 fc37 | 11 fc37 (0) fb55 (0) f64d (0) af99 (0)\n============ DEPTH: 1 ==========================================\n001 4 4ce6 55cc 6d8b 615c | 4 55cc (0) 4ce6 (0) 6d8b (0) 615c (0)\n002 0 | 0\n003 0 | 0\n004 0 | 0\n005 0 | 0\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"571afb6ce94d28cb7d5cd49b3af35d2b1e44c917a9d3d207ab6c7ae960eb625377334e62317f6c69b3004e2eef92682649df828f4a645a75309ee7014ee4a940","private_key":"8fa1673a72b2ab000a4a7c8ad4540484d5286b69c93a5c608ef0977f783b7c4c","name":"node_571afb6ce94d28cb7d5cd49b3af35d2b1e44c917a9d3d207ab6c7ae960eb625377334e62317f6c69b3004e2eef92682649df828f4a645a75309ee7014ee4a940","services":["streamer"],"enable_msg_events":true,"port":62857},"up":true}},{"node":{"info":{"id":"f1e669bb6e5b89c04e07e3dcdc445d498ac54c8ab2e9a62e622a492b6f9781bfa27f75ef7448d06caa28d9afa40c1c089066358cbcca40018bc0f903eab9508e","name":"node_f1e669bb6e5b89c04e07e3dcdc445d498ac54c8ab2e9a62e622a492b6f9781bfa27f75ef7448d06caa28d9afa40c1c089066358cbcca40018bc0f903eab9508e","enode":"enode://f1e669bb6e5b89c04e07e3dcdc445d498ac54c8ab2e9a62e622a492b6f9781bfa27f75ef7448d06caa28d9afa40c1c089066358cbcca40018bc0f903eab9508e@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"YVx/z3qAY15CcZwK4fuSS6cD7jngIYmL5WuB7w9XX2I=","hive":"\n=========================================================================\nTue Apr 10 09:54:41 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 615c7f\npopulation: 5 (15), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 8484 | 11 fc37 (0) fb55 (0) f64d (0) a873 (0)\n001 1 3c42 | 1 3c42 (0)\n============ DEPTH: 2 ==========================================\n002 2 4ce6 55cc | 2 55cc (0) 4ce6 (0)\n003 0 | 0\n004 1 6d8b | 1 6d8b (0)\n005 0 | 0\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"f1e669bb6e5b89c04e07e3dcdc445d498ac54c8ab2e9a62e622a492b6f9781bfa27f75ef7448d06caa28d9afa40c1c089066358cbcca40018bc0f903eab9508e","private_key":"daa9c74fbb0b897acdf20f1b955a608b086ce5b45dc8e2b76a44f277d25e3377","name":"node_f1e669bb6e5b89c04e07e3dcdc445d498ac54c8ab2e9a62e622a492b6f9781bfa27f75ef7448d06caa28d9afa40c1c089066358cbcca40018bc0f903eab9508e","services":["streamer"],"enable_msg_events":true,"port":62858},"up":true}},{"node":{"info":{"id":"526d25e0aa47e64d8f681255348a3d3c94fc68bedcb7111532f4ed50d47ef064b1e97e3a6bcd13ac8eaf44ce676b22d2b343a94dfa38b48cf964bfc3f338d4bd","name":"node_526d25e0aa47e64d8f681255348a3d3c94fc68bedcb7111532f4ed50d47ef064b1e97e3a6bcd13ac8eaf44ce676b22d2b343a94dfa38b48cf964bfc3f338d4bd","enode":"enode://526d25e0aa47e64d8f681255348a3d3c94fc68bedcb7111532f4ed50d47ef064b1e97e3a6bcd13ac8eaf44ce676b22d2b343a94dfa38b48cf964bfc3f338d4bd@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"hIQrxSYowL7YhTnuQPIR3jB7PnKKtcDKeAMrhgKLSds=","hive":"\n=========================================================================\nTue Apr 10 09:54:41 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 84842b\npopulation: 7 (15), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 615c | 5 3c42 (0) 55cc (0) 4ce6 (0) 6d8b (0)\n001 1 fb55 | 3 fb55 (0) fc37 (0) f64d (0)\n002 1 a379 | 3 a379 (0) a873 (0) af99 (0)\n============ DEPTH: 3 ==========================================\n003 3 9fcd 9121 9112 | 3 9fcd (0) 9121 (0) 9112 (0)\n004 1 8bf9 | 1 8bf9 (0)\n005 0 | 0\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"526d25e0aa47e64d8f681255348a3d3c94fc68bedcb7111532f4ed50d47ef064b1e97e3a6bcd13ac8eaf44ce676b22d2b343a94dfa38b48cf964bfc3f338d4bd","private_key":"eb94b600be5949e3ca545e81b4d0a5fff3ae9f51f63c722d10f5098f9e1a883a","name":"node_526d25e0aa47e64d8f681255348a3d3c94fc68bedcb7111532f4ed50d47ef064b1e97e3a6bcd13ac8eaf44ce676b22d2b343a94dfa38b48cf964bfc3f338d4bd","services":["streamer"],"enable_msg_events":true,"port":62859},"up":true}},{"node":{"info":{"id":"fa81c440829adcbb3eba9196dc8255e319a976e53db0aceedcda25c2605f21b8778bf8c89e08744f7455c909568855f2a5be7bc88646796d21598ddda810390a","name":"node_fa81c440829adcbb3eba9196dc8255e319a976e53db0aceedcda25c2605f21b8778bf8c89e08744f7455c909568855f2a5be7bc88646796d21598ddda810390a","enode":"enode://fa81c440829adcbb3eba9196dc8255e319a976e53db0aceedcda25c2605f21b8778bf8c89e08744f7455c909568855f2a5be7bc88646796d21598ddda810390a@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"kRKccTW/8rfLHhFivdU5kZJ5C9tPwuqltM6lP+emnYw=","hive":"\n=========================================================================\nTue Apr 10 09:54:41 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 91129c\npopulation: 7 (15), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 6d8b | 5 3c42 (0) 4ce6 (0) 55cc (0) 615c (0)\n001 1 f64d | 3 f64d (0) fb55 (0) fc37 (0)\n002 1 a379 | 3 a379 (0) a873 (0) af99 (0)\n003 2 8bf9 8484 | 2 8bf9 (0) 8484 (0)\n============ DEPTH: 4 ==========================================\n004 1 9fcd | 1 9fcd (0)\n005 0 | 0\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 1 9121 | 1 9121 (0)\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"fa81c440829adcbb3eba9196dc8255e319a976e53db0aceedcda25c2605f21b8778bf8c89e08744f7455c909568855f2a5be7bc88646796d21598ddda810390a","private_key":"4e5d074bc46efbd0d18310e6a74e72e98b92080329d9c4e2b5ae99eb2fcfaf89","name":"node_fa81c440829adcbb3eba9196dc8255e319a976e53db0aceedcda25c2605f21b8778bf8c89e08744f7455c909568855f2a5be7bc88646796d21598ddda810390a","services":["streamer"],"enable_msg_events":true,"port":62860},"up":true}},{"node":{"info":{"id":"5702eeccd7cb8c18dd25e5700919a544fb5e15fd53c5d4b56226021a9031a2206a694eb3b7334e4bd24fc510f7c1ea4f7a98e17e3394b4bd8d356a4d048b47dc","name":"node_5702eeccd7cb8c18dd25e5700919a544fb5e15fd53c5d4b56226021a9031a2206a694eb3b7334e4bd24fc510f7c1ea4f7a98e17e3394b4bd8d356a4d048b47dc","enode":"enode://5702eeccd7cb8c18dd25e5700919a544fb5e15fd53c5d4b56226021a9031a2206a694eb3b7334e4bd24fc510f7c1ea4f7a98e17e3394b4bd8d356a4d048b47dc@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"bYtogdNrxfSkqC9dcHgHry7vLq9FJ+trFvYs11qSu4w=","hive":"\n=========================================================================\nTue Apr 10 09:54:41 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 6d8b68\npopulation: 5 (15), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 9112 | 11 f64d (0) fb55 (0) fc37 (0) a379 (0)\n001 1 3c42 | 1 3c42 (0)\n============ DEPTH: 2 ==========================================\n002 2 4ce6 55cc | 2 4ce6 (0) 55cc (0)\n003 0 | 0\n004 1 615c | 1 615c (0)\n005 0 | 0\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"5702eeccd7cb8c18dd25e5700919a544fb5e15fd53c5d4b56226021a9031a2206a694eb3b7334e4bd24fc510f7c1ea4f7a98e17e3394b4bd8d356a4d048b47dc","private_key":"73c752d26f3438acdc54e9eaae6b1194d3706c65932939a593f1c8c5d451daf6","name":"node_5702eeccd7cb8c18dd25e5700919a544fb5e15fd53c5d4b56226021a9031a2206a694eb3b7334e4bd24fc510f7c1ea4f7a98e17e3394b4bd8d356a4d048b47dc","services":["streamer"],"enable_msg_events":true,"port":62861},"up":true}},{"node":{"info":{"id":"6311f5a830849b47094d84129fd987fcd3d511d000bf0a8b888c9a457545950fdae6ae10a2a85b47721a1d1ece8c1c62d866a26577380048d30f205c4e7cd7e8","name":"node_6311f5a830849b47094d84129fd987fcd3d511d000bf0a8b888c9a457545950fdae6ae10a2a85b47721a1d1ece8c1c62d866a26577380048d30f205c4e7cd7e8","enode":"enode://6311f5a830849b47094d84129fd987fcd3d511d000bf0a8b888c9a457545950fdae6ae10a2a85b47721a1d1ece8c1c62d866a26577380048d30f205c4e7cd7e8@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"Vcyb0IOQ7se8BQkk4wEbJRxsTgiKwq3aJ0kwZLdfCrg=","hive":"\n=========================================================================\nTue Apr 10 09:54:41 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 55cc9b\npopulation: 5 (15), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 a873 | 11 f64d (0) fb55 (0) fc37 (0) 8484 (0)\n001 1 3c42 | 1 3c42 (0)\n============ DEPTH: 2 ==========================================\n002 2 615c 6d8b | 2 615c (0) 6d8b (0)\n003 1 4ce6 | 1 4ce6 (0)\n004 0 | 0\n005 0 | 0\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"6311f5a830849b47094d84129fd987fcd3d511d000bf0a8b888c9a457545950fdae6ae10a2a85b47721a1d1ece8c1c62d866a26577380048d30f205c4e7cd7e8","private_key":"2e6321d9dda81fc0f863f09868b280dea3300105cf9d224294aa138caf10b4a6","name":"node_6311f5a830849b47094d84129fd987fcd3d511d000bf0a8b888c9a457545950fdae6ae10a2a85b47721a1d1ece8c1c62d866a26577380048d30f205c4e7cd7e8","services":["streamer"],"enable_msg_events":true,"port":62862},"up":true}},{"node":{"info":{"id":"dbef367277df652c8d3380efcf5f9d445d77fa6e7957b50b2467f90b7190e70d4eb4febbbffa6b3fc2b04bbf74dc7191e2b98923c3a62ecb80ba5336195994c7","name":"node_dbef367277df652c8d3380efcf5f9d445d77fa6e7957b50b2467f90b7190e70d4eb4febbbffa6b3fc2b04bbf74dc7191e2b98923c3a62ecb80ba5336195994c7","enode":"enode://dbef367277df652c8d3380efcf5f9d445d77fa6e7957b50b2467f90b7190e70d4eb4febbbffa6b3fc2b04bbf74dc7191e2b98923c3a62ecb80ba5336195994c7@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"qHPpcQQt/VqutW19kInjW8jdQQRRpmdA6+fqB1KHASA=","hive":"\n=========================================================================\nTue Apr 10 09:54:41 UTC 2018 KΛÐΞMLIΛ hive: queen's address: a873e9\npopulation: 5 (15), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 55cc | 5 3c42 (0) 615c (0) 6d8b (0) 4ce6 (0)\n001 1 f64d | 3 f64d (0) fb55 (0) fc37 (0)\n002 1 9fcd | 5 8484 (0) 8bf9 (0) 9112 (0) 9121 (0)\n003 0 | 0\n============ DEPTH: 4 ==========================================\n004 1 a379 | 1 a379 (0)\n005 1 af99 | 1 af99 (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"dbef367277df652c8d3380efcf5f9d445d77fa6e7957b50b2467f90b7190e70d4eb4febbbffa6b3fc2b04bbf74dc7191e2b98923c3a62ecb80ba5336195994c7","private_key":"200b7caaf8a33b8ea47947eb842fb8d8aac90951c70bb2f555f902380eb7f1ee","name":"node_dbef367277df652c8d3380efcf5f9d445d77fa6e7957b50b2467f90b7190e70d4eb4febbbffa6b3fc2b04bbf74dc7191e2b98923c3a62ecb80ba5336195994c7","services":["streamer"],"enable_msg_events":true,"port":62863},"up":true}},{"node":{"info":{"id":"a4cdf723b3d7ead36bcb1bba582c8758271d5f08651694e1def0ae2ceca079d4fca81730a84a14749a81bc3ea41a66f1320788310823de5d1ceecd608ed5b88e","name":"node_a4cdf723b3d7ead36bcb1bba582c8758271d5f08651694e1def0ae2ceca079d4fca81730a84a14749a81bc3ea41a66f1320788310823de5d1ceecd608ed5b88e","enode":"enode://a4cdf723b3d7ead36bcb1bba582c8758271d5f08651694e1def0ae2ceca079d4fca81730a84a14749a81bc3ea41a66f1320788310823de5d1ceecd608ed5b88e@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"n83vK4GOik/MB/7bcG2fiMxZcDIwr09SBDyE+b03zFc=","hive":"\n=========================================================================\nTue Apr 10 09:54:41 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 9fcdef\npopulation: 7 (15), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 3c42 | 5 3c42 (0) 55cc (0) 4ce6 (0) 615c (0)\n001 1 fc37 | 3 f64d (0) fb55 (0) fc37 (0)\n002 1 a873 | 3 a379 (0) af99 (0) a873 (0)\n003 2 8484 8bf9 | 2 8484 (0) 8bf9 (0)\n============ DEPTH: 4 ==========================================\n004 2 9112 9121 | 2 9112 (0) 9121 (0)\n005 0 | 0\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"a4cdf723b3d7ead36bcb1bba582c8758271d5f08651694e1def0ae2ceca079d4fca81730a84a14749a81bc3ea41a66f1320788310823de5d1ceecd608ed5b88e","private_key":"b58a24805bb0c417e5666f2bf3f3342b8359d3c0d30a631c0104fcdfb6d0809b","name":"node_a4cdf723b3d7ead36bcb1bba582c8758271d5f08651694e1def0ae2ceca079d4fca81730a84a14749a81bc3ea41a66f1320788310823de5d1ceecd608ed5b88e","services":["streamer"],"enable_msg_events":true,"port":62864},"up":true}},{"node":{"info":{"id":"67cc8be0fd092c82e53efc53c418db257eff1135ad0058fd10e3eb77b205cb3e6fa87dfed4ec008c371f77546d4c117d8c34734bfe594da4c96fc08e0d2ede32","name":"node_67cc8be0fd092c82e53efc53c418db257eff1135ad0058fd10e3eb77b205cb3e6fa87dfed4ec008c371f77546d4c117d8c34734bfe594da4c96fc08e0d2ede32","enode":"enode://67cc8be0fd092c82e53efc53c418db257eff1135ad0058fd10e3eb77b205cb3e6fa87dfed4ec008c371f77546d4c117d8c34734bfe594da4c96fc08e0d2ede32@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"/Dc89OiSUBBz7Ye5gjHw0AHm23ChoIFIA1+9+i3/s9M=","hive":"\n=========================================================================\nTue Apr 10 09:54:41 UTC 2018 KΛÐΞMLIΛ hive: queen's address: fc373c\npopulation: 5 (15), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 3c42 | 5 3c42 (0) 55cc (0) 4ce6 (0) 615c (0)\n001 2 9fcd af99 | 8 8484 (0) 8bf9 (0) 9112 (0) 9121 (0)\n002 0 | 0\n003 0 | 0\n============ DEPTH: 4 ==========================================\n004 1 f64d | 1 f64d (0)\n005 1 fb55 | 1 fb55 (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"67cc8be0fd092c82e53efc53c418db257eff1135ad0058fd10e3eb77b205cb3e6fa87dfed4ec008c371f77546d4c117d8c34734bfe594da4c96fc08e0d2ede32","private_key":"422d3b2c1b37b851ad524c8f26700fb5eec0d9a2fff1cb157ae931baa52d9521","name":"node_67cc8be0fd092c82e53efc53c418db257eff1135ad0058fd10e3eb77b205cb3e6fa87dfed4ec008c371f77546d4c117d8c34734bfe594da4c96fc08e0d2ede32","services":["streamer"],"enable_msg_events":true,"port":62865},"up":true}},{"node":{"info":{"id":"4da7d1c9577afb52a5fe1de9f99824ceff314828c581caed8a3a33168df699d7b3befb4e888419264a9eeb3c9e5e9dac468e01edd71eb6f0ef41d15f7651042d","name":"node_4da7d1c9577afb52a5fe1de9f99824ceff314828c581caed8a3a33168df699d7b3befb4e888419264a9eeb3c9e5e9dac468e01edd71eb6f0ef41d15f7651042d","enode":"enode://4da7d1c9577afb52a5fe1de9f99824ceff314828c581caed8a3a33168df699d7b3befb4e888419264a9eeb3c9e5e9dac468e01edd71eb6f0ef41d15f7651042d@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"r5nUbBh3Nf8DfhJk8tvKKYVpTZBt4OLJ5S1VE6b+szE=","hive":"\n=========================================================================\nTue Apr 10 09:54:41 UTC 2018 KΛÐΞMLIΛ hive: queen's address: af99d4\npopulation: 6 (15), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 3c42 | 5 3c42 (0) 615c (0) 6d8b (0) 55cc (0)\n001 1 fc37 | 3 f64d (0) fb55 (0) fc37 (0)\n002 2 9121 8bf9 | 5 8484 (0) 8bf9 (0) 9112 (0) 9121 (0)\n003 0 | 0\n============ DEPTH: 4 ==========================================\n004 1 a379 | 1 a379 (0)\n005 1 a873 | 1 a873 (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"4da7d1c9577afb52a5fe1de9f99824ceff314828c581caed8a3a33168df699d7b3befb4e888419264a9eeb3c9e5e9dac468e01edd71eb6f0ef41d15f7651042d","private_key":"7871010c8b88b9594c71b9f43aecfefdca39da348e31f47ef2645c20c100d072","name":"node_4da7d1c9577afb52a5fe1de9f99824ceff314828c581caed8a3a33168df699d7b3befb4e888419264a9eeb3c9e5e9dac468e01edd71eb6f0ef41d15f7651042d","services":["streamer"],"enable_msg_events":true,"port":62866},"up":true}}],"conns":[{"one":"4da7d1c9577afb52a5fe1de9f99824ceff314828c581caed8a3a33168df699d7b3befb4e888419264a9eeb3c9e5e9dac468e01edd71eb6f0ef41d15f7651042d","other":"279f0a191892115b8db4e2689cc5e1bc19019e8f5228f4f093f35c48fa2f606fd00a2ec5cf0fa4657ad3606e14643c3be8d49350ad2673f2ad12e17c0174b0d8","up":true},{"one":"1dcbfc79418f9a665e3154e07663b296ce086e54c23458b7113a011dca62e635245cab144d392716e5e90b60336b60927270b72bb4a1c5c85fbf959060fb3ee4","other":"571afb6ce94d28cb7d5cd49b3af35d2b1e44c917a9d3d207ab6c7ae960eb625377334e62317f6c69b3004e2eef92682649df828f4a645a75309ee7014ee4a940","up":true},{"one":"279f0a191892115b8db4e2689cc5e1bc19019e8f5228f4f093f35c48fa2f606fd00a2ec5cf0fa4657ad3606e14643c3be8d49350ad2673f2ad12e17c0174b0d8","other":"2c3d17a3b019d9d32922f06aef03ac03f67777e382f0b86c6e4dac07e590f2dbf4cbd1cc7ed136b52bba897e7163dee926caa627111db6d948581ad1b2edbc3f","up":true},{"one":"2c3d17a3b019d9d32922f06aef03ac03f67777e382f0b86c6e4dac07e590f2dbf4cbd1cc7ed136b52bba897e7163dee926caa627111db6d948581ad1b2edbc3f","other":"6e327c2d9d3ffdae707ed067d15b83ad0ea81b96bb2a07331436f01c1e194ed90f630ef0eb6511f4849ede30c403e3c4ff3c2cb8021317de97f3ed5b1d990f49","up":true},{"one":"6e327c2d9d3ffdae707ed067d15b83ad0ea81b96bb2a07331436f01c1e194ed90f630ef0eb6511f4849ede30c403e3c4ff3c2cb8021317de97f3ed5b1d990f49","other":"9aa1df8ddddd035e81ffc950f063714c3b6be24013108f8b99c32c25fc3a8582904f68c73fe63ebfb96143a12ab398f36c4070a3055c039491ca2f20be6774c2","up":true},{"one":"9aa1df8ddddd035e81ffc950f063714c3b6be24013108f8b99c32c25fc3a8582904f68c73fe63ebfb96143a12ab398f36c4070a3055c039491ca2f20be6774c2","other":"a1226991909b92dd4f22150b798e2b6312ffc62bad7a47d250e811c7e60cf5ceb6a87998f295e0bd392c0f5c15213115000781e498dd7eae79b67c7e7e19cf81","up":true},{"one":"a1226991909b92dd4f22150b798e2b6312ffc62bad7a47d250e811c7e60cf5ceb6a87998f295e0bd392c0f5c15213115000781e498dd7eae79b67c7e7e19cf81","other":"1dcbfc79418f9a665e3154e07663b296ce086e54c23458b7113a011dca62e635245cab144d392716e5e90b60336b60927270b72bb4a1c5c85fbf959060fb3ee4","up":true},{"one":"5702eeccd7cb8c18dd25e5700919a544fb5e15fd53c5d4b56226021a9031a2206a694eb3b7334e4bd24fc510f7c1ea4f7a98e17e3394b4bd8d356a4d048b47dc","other":"6311f5a830849b47094d84129fd987fcd3d511d000bf0a8b888c9a457545950fdae6ae10a2a85b47721a1d1ece8c1c62d866a26577380048d30f205c4e7cd7e8","up":true},{"one":"571afb6ce94d28cb7d5cd49b3af35d2b1e44c917a9d3d207ab6c7ae960eb625377334e62317f6c69b3004e2eef92682649df828f4a645a75309ee7014ee4a940","other":"f1e669bb6e5b89c04e07e3dcdc445d498ac54c8ab2e9a62e622a492b6f9781bfa27f75ef7448d06caa28d9afa40c1c089066358cbcca40018bc0f903eab9508e","up":true},{"one":"f1e669bb6e5b89c04e07e3dcdc445d498ac54c8ab2e9a62e622a492b6f9781bfa27f75ef7448d06caa28d9afa40c1c089066358cbcca40018bc0f903eab9508e","other":"526d25e0aa47e64d8f681255348a3d3c94fc68bedcb7111532f4ed50d47ef064b1e97e3a6bcd13ac8eaf44ce676b22d2b343a94dfa38b48cf964bfc3f338d4bd","up":true},{"one":"526d25e0aa47e64d8f681255348a3d3c94fc68bedcb7111532f4ed50d47ef064b1e97e3a6bcd13ac8eaf44ce676b22d2b343a94dfa38b48cf964bfc3f338d4bd","other":"fa81c440829adcbb3eba9196dc8255e319a976e53db0aceedcda25c2605f21b8778bf8c89e08744f7455c909568855f2a5be7bc88646796d21598ddda810390a","up":true},{"one":"fa81c440829adcbb3eba9196dc8255e319a976e53db0aceedcda25c2605f21b8778bf8c89e08744f7455c909568855f2a5be7bc88646796d21598ddda810390a","other":"5702eeccd7cb8c18dd25e5700919a544fb5e15fd53c5d4b56226021a9031a2206a694eb3b7334e4bd24fc510f7c1ea4f7a98e17e3394b4bd8d356a4d048b47dc","up":true},{"one":"dbef367277df652c8d3380efcf5f9d445d77fa6e7957b50b2467f90b7190e70d4eb4febbbffa6b3fc2b04bbf74dc7191e2b98923c3a62ecb80ba5336195994c7","other":"a4cdf723b3d7ead36bcb1bba582c8758271d5f08651694e1def0ae2ceca079d4fca81730a84a14749a81bc3ea41a66f1320788310823de5d1ceecd608ed5b88e","up":true},{"one":"6311f5a830849b47094d84129fd987fcd3d511d000bf0a8b888c9a457545950fdae6ae10a2a85b47721a1d1ece8c1c62d866a26577380048d30f205c4e7cd7e8","other":"dbef367277df652c8d3380efcf5f9d445d77fa6e7957b50b2467f90b7190e70d4eb4febbbffa6b3fc2b04bbf74dc7191e2b98923c3a62ecb80ba5336195994c7","up":true},{"one":"a4cdf723b3d7ead36bcb1bba582c8758271d5f08651694e1def0ae2ceca079d4fca81730a84a14749a81bc3ea41a66f1320788310823de5d1ceecd608ed5b88e","other":"67cc8be0fd092c82e53efc53c418db257eff1135ad0058fd10e3eb77b205cb3e6fa87dfed4ec008c371f77546d4c117d8c34734bfe594da4c96fc08e0d2ede32","up":true},{"one":"67cc8be0fd092c82e53efc53c418db257eff1135ad0058fd10e3eb77b205cb3e6fa87dfed4ec008c371f77546d4c117d8c34734bfe594da4c96fc08e0d2ede32","other":"4da7d1c9577afb52a5fe1de9f99824ceff314828c581caed8a3a33168df699d7b3befb4e888419264a9eeb3c9e5e9dac468e01edd71eb6f0ef41d15f7651042d","up":true},{"one":"279f0a191892115b8db4e2689cc5e1bc19019e8f5228f4f093f35c48fa2f606fd00a2ec5cf0fa4657ad3606e14643c3be8d49350ad2673f2ad12e17c0174b0d8","other":"dbef367277df652c8d3380efcf5f9d445d77fa6e7957b50b2467f90b7190e70d4eb4febbbffa6b3fc2b04bbf74dc7191e2b98923c3a62ecb80ba5336195994c7","up":true},{"one":"9aa1df8ddddd035e81ffc950f063714c3b6be24013108f8b99c32c25fc3a8582904f68c73fe63ebfb96143a12ab398f36c4070a3055c039491ca2f20be6774c2","other":"a4cdf723b3d7ead36bcb1bba582c8758271d5f08651694e1def0ae2ceca079d4fca81730a84a14749a81bc3ea41a66f1320788310823de5d1ceecd608ed5b88e","up":true},{"one":"a1226991909b92dd4f22150b798e2b6312ffc62bad7a47d250e811c7e60cf5ceb6a87998f295e0bd392c0f5c15213115000781e498dd7eae79b67c7e7e19cf81","other":"67cc8be0fd092c82e53efc53c418db257eff1135ad0058fd10e3eb77b205cb3e6fa87dfed4ec008c371f77546d4c117d8c34734bfe594da4c96fc08e0d2ede32","up":true},{"one":"dbef367277df652c8d3380efcf5f9d445d77fa6e7957b50b2467f90b7190e70d4eb4febbbffa6b3fc2b04bbf74dc7191e2b98923c3a62ecb80ba5336195994c7","other":"4da7d1c9577afb52a5fe1de9f99824ceff314828c581caed8a3a33168df699d7b3befb4e888419264a9eeb3c9e5e9dac468e01edd71eb6f0ef41d15f7651042d","up":true},{"one":"a4cdf723b3d7ead36bcb1bba582c8758271d5f08651694e1def0ae2ceca079d4fca81730a84a14749a81bc3ea41a66f1320788310823de5d1ceecd608ed5b88e","other":"6e327c2d9d3ffdae707ed067d15b83ad0ea81b96bb2a07331436f01c1e194ed90f630ef0eb6511f4849ede30c403e3c4ff3c2cb8021317de97f3ed5b1d990f49","up":true},{"one":"4da7d1c9577afb52a5fe1de9f99824ceff314828c581caed8a3a33168df699d7b3befb4e888419264a9eeb3c9e5e9dac468e01edd71eb6f0ef41d15f7651042d","other":"571afb6ce94d28cb7d5cd49b3af35d2b1e44c917a9d3d207ab6c7ae960eb625377334e62317f6c69b3004e2eef92682649df828f4a645a75309ee7014ee4a940","up":true},{"one":"fa81c440829adcbb3eba9196dc8255e319a976e53db0aceedcda25c2605f21b8778bf8c89e08744f7455c909568855f2a5be7bc88646796d21598ddda810390a","other":"9aa1df8ddddd035e81ffc950f063714c3b6be24013108f8b99c32c25fc3a8582904f68c73fe63ebfb96143a12ab398f36c4070a3055c039491ca2f20be6774c2","up":true},{"one":"1dcbfc79418f9a665e3154e07663b296ce086e54c23458b7113a011dca62e635245cab144d392716e5e90b60336b60927270b72bb4a1c5c85fbf959060fb3ee4","other":"67cc8be0fd092c82e53efc53c418db257eff1135ad0058fd10e3eb77b205cb3e6fa87dfed4ec008c371f77546d4c117d8c34734bfe594da4c96fc08e0d2ede32","up":true},{"one":"279f0a191892115b8db4e2689cc5e1bc19019e8f5228f4f093f35c48fa2f606fd00a2ec5cf0fa4657ad3606e14643c3be8d49350ad2673f2ad12e17c0174b0d8","other":"1dcbfc79418f9a665e3154e07663b296ce086e54c23458b7113a011dca62e635245cab144d392716e5e90b60336b60927270b72bb4a1c5c85fbf959060fb3ee4","up":true},{"one":"9aa1df8ddddd035e81ffc950f063714c3b6be24013108f8b99c32c25fc3a8582904f68c73fe63ebfb96143a12ab398f36c4070a3055c039491ca2f20be6774c2","other":"571afb6ce94d28cb7d5cd49b3af35d2b1e44c917a9d3d207ab6c7ae960eb625377334e62317f6c69b3004e2eef92682649df828f4a645a75309ee7014ee4a940","up":true},{"one":"a1226991909b92dd4f22150b798e2b6312ffc62bad7a47d250e811c7e60cf5ceb6a87998f295e0bd392c0f5c15213115000781e498dd7eae79b67c7e7e19cf81","other":"571afb6ce94d28cb7d5cd49b3af35d2b1e44c917a9d3d207ab6c7ae960eb625377334e62317f6c69b3004e2eef92682649df828f4a645a75309ee7014ee4a940","up":true},{"one":"fa81c440829adcbb3eba9196dc8255e319a976e53db0aceedcda25c2605f21b8778bf8c89e08744f7455c909568855f2a5be7bc88646796d21598ddda810390a","other":"a4cdf723b3d7ead36bcb1bba582c8758271d5f08651694e1def0ae2ceca079d4fca81730a84a14749a81bc3ea41a66f1320788310823de5d1ceecd608ed5b88e","up":true},{"one":"4da7d1c9577afb52a5fe1de9f99824ceff314828c581caed8a3a33168df699d7b3befb4e888419264a9eeb3c9e5e9dac468e01edd71eb6f0ef41d15f7651042d","other":"6e327c2d9d3ffdae707ed067d15b83ad0ea81b96bb2a07331436f01c1e194ed90f630ef0eb6511f4849ede30c403e3c4ff3c2cb8021317de97f3ed5b1d990f49","up":true},{"one":"a4cdf723b3d7ead36bcb1bba582c8758271d5f08651694e1def0ae2ceca079d4fca81730a84a14749a81bc3ea41a66f1320788310823de5d1ceecd608ed5b88e","other":"571afb6ce94d28cb7d5cd49b3af35d2b1e44c917a9d3d207ab6c7ae960eb625377334e62317f6c69b3004e2eef92682649df828f4a645a75309ee7014ee4a940","up":true},{"one":"dbef367277df652c8d3380efcf5f9d445d77fa6e7957b50b2467f90b7190e70d4eb4febbbffa6b3fc2b04bbf74dc7191e2b98923c3a62ecb80ba5336195994c7","other":"1dcbfc79418f9a665e3154e07663b296ce086e54c23458b7113a011dca62e635245cab144d392716e5e90b60336b60927270b72bb4a1c5c85fbf959060fb3ee4","up":true},{"one":"571afb6ce94d28cb7d5cd49b3af35d2b1e44c917a9d3d207ab6c7ae960eb625377334e62317f6c69b3004e2eef92682649df828f4a645a75309ee7014ee4a940","other":"5702eeccd7cb8c18dd25e5700919a544fb5e15fd53c5d4b56226021a9031a2206a694eb3b7334e4bd24fc510f7c1ea4f7a98e17e3394b4bd8d356a4d048b47dc","up":true},{"one":"526d25e0aa47e64d8f681255348a3d3c94fc68bedcb7111532f4ed50d47ef064b1e97e3a6bcd13ac8eaf44ce676b22d2b343a94dfa38b48cf964bfc3f338d4bd","other":"6e327c2d9d3ffdae707ed067d15b83ad0ea81b96bb2a07331436f01c1e194ed90f630ef0eb6511f4849ede30c403e3c4ff3c2cb8021317de97f3ed5b1d990f49","up":true},{"one":"6311f5a830849b47094d84129fd987fcd3d511d000bf0a8b888c9a457545950fdae6ae10a2a85b47721a1d1ece8c1c62d866a26577380048d30f205c4e7cd7e8","other":"2c3d17a3b019d9d32922f06aef03ac03f67777e382f0b86c6e4dac07e590f2dbf4cbd1cc7ed136b52bba897e7163dee926caa627111db6d948581ad1b2edbc3f","up":true},{"one":"f1e669bb6e5b89c04e07e3dcdc445d498ac54c8ab2e9a62e622a492b6f9781bfa27f75ef7448d06caa28d9afa40c1c089066358cbcca40018bc0f903eab9508e","other":"5702eeccd7cb8c18dd25e5700919a544fb5e15fd53c5d4b56226021a9031a2206a694eb3b7334e4bd24fc510f7c1ea4f7a98e17e3394b4bd8d356a4d048b47dc","up":true},{"one":"279f0a191892115b8db4e2689cc5e1bc19019e8f5228f4f093f35c48fa2f606fd00a2ec5cf0fa4657ad3606e14643c3be8d49350ad2673f2ad12e17c0174b0d8","other":"526d25e0aa47e64d8f681255348a3d3c94fc68bedcb7111532f4ed50d47ef064b1e97e3a6bcd13ac8eaf44ce676b22d2b343a94dfa38b48cf964bfc3f338d4bd","up":true},{"one":"9aa1df8ddddd035e81ffc950f063714c3b6be24013108f8b99c32c25fc3a8582904f68c73fe63ebfb96143a12ab398f36c4070a3055c039491ca2f20be6774c2","other":"4da7d1c9577afb52a5fe1de9f99824ceff314828c581caed8a3a33168df699d7b3befb4e888419264a9eeb3c9e5e9dac468e01edd71eb6f0ef41d15f7651042d","up":true},{"one":"571afb6ce94d28cb7d5cd49b3af35d2b1e44c917a9d3d207ab6c7ae960eb625377334e62317f6c69b3004e2eef92682649df828f4a645a75309ee7014ee4a940","other":"6311f5a830849b47094d84129fd987fcd3d511d000bf0a8b888c9a457545950fdae6ae10a2a85b47721a1d1ece8c1c62d866a26577380048d30f205c4e7cd7e8","up":true},{"one":"f1e669bb6e5b89c04e07e3dcdc445d498ac54c8ab2e9a62e622a492b6f9781bfa27f75ef7448d06caa28d9afa40c1c089066358cbcca40018bc0f903eab9508e","other":"6311f5a830849b47094d84129fd987fcd3d511d000bf0a8b888c9a457545950fdae6ae10a2a85b47721a1d1ece8c1c62d866a26577380048d30f205c4e7cd7e8","up":true},{"one":"526d25e0aa47e64d8f681255348a3d3c94fc68bedcb7111532f4ed50d47ef064b1e97e3a6bcd13ac8eaf44ce676b22d2b343a94dfa38b48cf964bfc3f338d4bd","other":"9aa1df8ddddd035e81ffc950f063714c3b6be24013108f8b99c32c25fc3a8582904f68c73fe63ebfb96143a12ab398f36c4070a3055c039491ca2f20be6774c2","up":true},{"one":"fa81c440829adcbb3eba9196dc8255e319a976e53db0aceedcda25c2605f21b8778bf8c89e08744f7455c909568855f2a5be7bc88646796d21598ddda810390a","other":"1dcbfc79418f9a665e3154e07663b296ce086e54c23458b7113a011dca62e635245cab144d392716e5e90b60336b60927270b72bb4a1c5c85fbf959060fb3ee4","up":true},{"one":"5702eeccd7cb8c18dd25e5700919a544fb5e15fd53c5d4b56226021a9031a2206a694eb3b7334e4bd24fc510f7c1ea4f7a98e17e3394b4bd8d356a4d048b47dc","other":"2c3d17a3b019d9d32922f06aef03ac03f67777e382f0b86c6e4dac07e590f2dbf4cbd1cc7ed136b52bba897e7163dee926caa627111db6d948581ad1b2edbc3f","up":true},{"one":"67cc8be0fd092c82e53efc53c418db257eff1135ad0058fd10e3eb77b205cb3e6fa87dfed4ec008c371f77546d4c117d8c34734bfe594da4c96fc08e0d2ede32","other":"571afb6ce94d28cb7d5cd49b3af35d2b1e44c917a9d3d207ab6c7ae960eb625377334e62317f6c69b3004e2eef92682649df828f4a645a75309ee7014ee4a940","up":true},{"one":"571afb6ce94d28cb7d5cd49b3af35d2b1e44c917a9d3d207ab6c7ae960eb625377334e62317f6c69b3004e2eef92682649df828f4a645a75309ee7014ee4a940","other":"2c3d17a3b019d9d32922f06aef03ac03f67777e382f0b86c6e4dac07e590f2dbf4cbd1cc7ed136b52bba897e7163dee926caa627111db6d948581ad1b2edbc3f","up":true},{"one":"f1e669bb6e5b89c04e07e3dcdc445d498ac54c8ab2e9a62e622a492b6f9781bfa27f75ef7448d06caa28d9afa40c1c089066358cbcca40018bc0f903eab9508e","other":"2c3d17a3b019d9d32922f06aef03ac03f67777e382f0b86c6e4dac07e590f2dbf4cbd1cc7ed136b52bba897e7163dee926caa627111db6d948581ad1b2edbc3f","up":true},{"one":"526d25e0aa47e64d8f681255348a3d3c94fc68bedcb7111532f4ed50d47ef064b1e97e3a6bcd13ac8eaf44ce676b22d2b343a94dfa38b48cf964bfc3f338d4bd","other":"a4cdf723b3d7ead36bcb1bba582c8758271d5f08651694e1def0ae2ceca079d4fca81730a84a14749a81bc3ea41a66f1320788310823de5d1ceecd608ed5b88e","up":true},{"one":"fa81c440829adcbb3eba9196dc8255e319a976e53db0aceedcda25c2605f21b8778bf8c89e08744f7455c909568855f2a5be7bc88646796d21598ddda810390a","other":"279f0a191892115b8db4e2689cc5e1bc19019e8f5228f4f093f35c48fa2f606fd00a2ec5cf0fa4657ad3606e14643c3be8d49350ad2673f2ad12e17c0174b0d8","up":true},{"one":"6e327c2d9d3ffdae707ed067d15b83ad0ea81b96bb2a07331436f01c1e194ed90f630ef0eb6511f4849ede30c403e3c4ff3c2cb8021317de97f3ed5b1d990f49","other":"fa81c440829adcbb3eba9196dc8255e319a976e53db0aceedcda25c2605f21b8778bf8c89e08744f7455c909568855f2a5be7bc88646796d21598ddda810390a","up":true},{"one":"6e327c2d9d3ffdae707ed067d15b83ad0ea81b96bb2a07331436f01c1e194ed90f630ef0eb6511f4849ede30c403e3c4ff3c2cb8021317de97f3ed5b1d990f49","other":"a1226991909b92dd4f22150b798e2b6312ffc62bad7a47d250e811c7e60cf5ceb6a87998f295e0bd392c0f5c15213115000781e498dd7eae79b67c7e7e19cf81","up":true},{"one":"526d25e0aa47e64d8f681255348a3d3c94fc68bedcb7111532f4ed50d47ef064b1e97e3a6bcd13ac8eaf44ce676b22d2b343a94dfa38b48cf964bfc3f338d4bd","other":"a1226991909b92dd4f22150b798e2b6312ffc62bad7a47d250e811c7e60cf5ceb6a87998f295e0bd392c0f5c15213115000781e498dd7eae79b67c7e7e19cf81","up":true}]} \ No newline at end of file diff --git a/swarm/network/stream/testing/snapshot_256.json b/swarm/network/stream/testing/snapshot_256.json new file mode 100644 index 0000000000..2ff66f288b --- /dev/null +++ b/swarm/network/stream/testing/snapshot_256.json @@ -0,0 +1 @@ +{"nodes":[{"node":{"info":{"id":"57fb1bb32bb2b1a87e44c6a7557e9c47c2032d107bcb0e34acd9ffd54d5d3df5701232db16f62f7549ba2721021898b03160b1dc5201e79606648c1dbc4a373b","name":"node_57fb1bb32bb2b1a87e44c6a7557e9c47c2032d107bcb0e34acd9ffd54d5d3df5701232db16f62f7549ba2721021898b03160b1dc5201e79606648c1dbc4a373b","enode":"enode://57fb1bb32bb2b1a87e44c6a7557e9c47c2032d107bcb0e34acd9ffd54d5d3df5701232db16f62f7549ba2721021898b03160b1dc5201e79606648c1dbc4a373b@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"mRjaHBeUFPdcjScQPDKXo79czGKuC7E4WWEQRlNqWVk=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 9918da\npopulation: 21 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 7299 3ab2 24f8 | 122 48ec (0) 48df (0) 4b70 (0) 4bf8 (0)\n001 2 e406 e5d2 | 71 c3d8 (0) c301 (0) c409 (0) c60e (0)\n002 3 a9df a3f2 a105 | 30 b40d (0) b45f (0) b7aa (0) b30e (0)\n003 1 8a54 | 15 802e (0) 802f (0) 83d0 (0) 853b (0)\n004 3 9493 9404 910d | 8 9641 (0) 9747 (0) 9493 (0) 9404 (0)\n005 1 9f4c | 1 9f4c (0)\n006 3 9b87 9bc3 9a09 | 3 9bc3 (0) 9b87 (0) 9a09 (0)\n007 3 985f 98bc 98aa | 3 985f (0) 98bc (0) 98aa (0)\n============ DEPTH: 8 ==========================================\n008 1 99eb | 1 99eb (0)\n009 0 | 0\n010 1 9929 | 1 9929 (0)\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"57fb1bb32bb2b1a87e44c6a7557e9c47c2032d107bcb0e34acd9ffd54d5d3df5701232db16f62f7549ba2721021898b03160b1dc5201e79606648c1dbc4a373b","private_key":"859f1f6b352bfdd6f8b7a7a80ef60a7fa41a514a091d5c19d0ea7ab44c24c614","name":"node_57fb1bb32bb2b1a87e44c6a7557e9c47c2032d107bcb0e34acd9ffd54d5d3df5701232db16f62f7549ba2721021898b03160b1dc5201e79606648c1dbc4a373b","services":["streamer"],"enable_msg_events":true,"port":63226},"up":true}},{"node":{"info":{"id":"7f357b8d81bc2e5c6fcb081f23a42b3e2439f050d45c45851994a268d1c71fcb1f39f8c3f75ce921d3fbf80fc0e73f0b9609d72001dc4a6b65b526d312a4f43a","name":"node_7f357b8d81bc2e5c6fcb081f23a42b3e2439f050d45c45851994a268d1c71fcb1f39f8c3f75ce921d3fbf80fc0e73f0b9609d72001dc4a6b65b526d312a4f43a","enode":"enode://7f357b8d81bc2e5c6fcb081f23a42b3e2439f050d45c45851994a268d1c71fcb1f39f8c3f75ce921d3fbf80fc0e73f0b9609d72001dc4a6b65b526d312a4f43a@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"pr29dfA/oxFwChf/QFTr8oVfBas/L0r4LK1XPZFBeoM=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: a6bdbd\npopulation: 27 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 7299 24f8 167b | 122 05a4 (0) 0536 (0) 07a6 (0) 00c8 (0)\n001 4 e6b7 e5d2 e406 f97e | 71 c3d8 (0) c301 (0) c409 (0) c60e (0)\n002 1 910d | 33 802f (0) 802e (0) 83d0 (0) 853b (0)\n003 8 b820 bf6b b7aa b45f | 13 b40d (0) b45f (0) b7aa (0) b30e (0)\n004 3 ac62 a936 a9df | 5 af8f (0) ac62 (0) aa78 (0) a936 (0)\n005 6 a105 a1b6 a077 a0c9 | 9 a317 (0) a3f2 (0) a077 (0) a011 (10)\n============ DEPTH: 6 ==========================================\n006 1 a478 | 1 a478 (0)\n007 1 a75d | 1 a75d (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"7f357b8d81bc2e5c6fcb081f23a42b3e2439f050d45c45851994a268d1c71fcb1f39f8c3f75ce921d3fbf80fc0e73f0b9609d72001dc4a6b65b526d312a4f43a","private_key":"681d7bb10f2022ae6f74a5afa7e0d42dfa6efd2e55abe22a395db640b6f5c70b","name":"node_7f357b8d81bc2e5c6fcb081f23a42b3e2439f050d45c45851994a268d1c71fcb1f39f8c3f75ce921d3fbf80fc0e73f0b9609d72001dc4a6b65b526d312a4f43a","services":["streamer"],"enable_msg_events":true,"port":63227},"up":true}},{"node":{"info":{"id":"cb94a8270d0050378116b5815ff17dafbe20f5303839c4fd57b981d4687a4b145e4bccec7e9af9b9475005930148ffbfa97781a0762c8e9f352dc95565fc8732","name":"node_cb94a8270d0050378116b5815ff17dafbe20f5303839c4fd57b981d4687a4b145e4bccec7e9af9b9475005930148ffbfa97781a0762c8e9f352dc95565fc8732","enode":"enode://cb94a8270d0050378116b5815ff17dafbe20f5303839c4fd57b981d4687a4b145e4bccec7e9af9b9475005930148ffbfa97781a0762c8e9f352dc95565fc8732@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"cpnfXOTZDi57+ukp/D/KcXW4iZaB5iYEHY5XIbLOjp8=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 7299df\npopulation: 30 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 6 c3d8 9918 b391 a9df | 134 c3d8 (0) c301 (0) c409 (0) c60e (0)\n001 5 1dfd 1758 07a6 0536 | 72 05a4 (0) 0536 (0) 07a6 (0) 00c8 (0)\n002 3 47a8 5b30 56bb | 31 48ec (0) 48df (0) 4b70 (0) 4bf8 (0)\n003 7 67ee 65a6 60bc 6f1c | 9 63de (0) 60bc (0) 6701 (0) 67ee (0)\n004 4 7aef 7810 7e45 7ec4 | 4 7ec4 (0) 7e45 (0) 7810 (0) 7aef (0)\n005 2 77bc 76a5 | 2 77bc (0) 76a5 (0)\n============ DEPTH: 6 ==========================================\n006 2 71bf 715b | 2 71bf (0) 715b (0)\n007 0 | 0\n008 1 7239 | 1 7239 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"cb94a8270d0050378116b5815ff17dafbe20f5303839c4fd57b981d4687a4b145e4bccec7e9af9b9475005930148ffbfa97781a0762c8e9f352dc95565fc8732","private_key":"fe0d4b827c015eddc1928a6f9691bb26ba2100a6232168890d11ebc7f7222891","name":"node_cb94a8270d0050378116b5815ff17dafbe20f5303839c4fd57b981d4687a4b145e4bccec7e9af9b9475005930148ffbfa97781a0762c8e9f352dc95565fc8732","services":["streamer"],"enable_msg_events":true,"port":63228},"up":true}},{"node":{"info":{"id":"76cbf9fc0f3517fb615fa96104780218e85d064ee5a1d518f3b78f4dbebf144df38c427445fdd6c9b436489c00ff9497d747a8fd70f380f95601d59e52e021e8","name":"node_76cbf9fc0f3517fb615fa96104780218e85d064ee5a1d518f3b78f4dbebf144df38c427445fdd6c9b436489c00ff9497d747a8fd70f380f95601d59e52e021e8","enode":"enode://76cbf9fc0f3517fb615fa96104780218e85d064ee5a1d518f3b78f4dbebf144df38c427445fdd6c9b436489c00ff9497d747a8fd70f380f95601d59e52e021e8@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"VrvZdf9nX3O1ZrRH6JTTEbhjFDgWO2JUNmhbAZoVITs=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 56bbd9\npopulation: 28 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 a9df a3f2 8a54 | 134 bd39 (0) bf6b (0) beb7 (0) bb31 (0)\n001 9 1758 2f23 2c16 2c4e | 72 05a4 (0) 0536 (0) 07a6 (0) 00c8 (0)\n002 2 7299 6f1c | 19 63de (0) 60bc (0) 65a6 (0) 6701 (0)\n003 3 4bbc 47a8 43fb | 16 4dc4 (0) 4c97 (0) 48ec (0) 48df (0)\n004 3 5c9b 581a 5b30 | 6 5e3e (0) 5cae (0) 5c9b (0) 581a (0)\n005 5 5237 5399 5070 5062 | 5 5237 (0) 5399 (0) 5070 (0) 5062 (0)\n006 0 | 0\n============ DEPTH: 7 ==========================================\n007 3 57ee 5741 5765 | 3 57ee (0) 5741 (0) 5765 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"76cbf9fc0f3517fb615fa96104780218e85d064ee5a1d518f3b78f4dbebf144df38c427445fdd6c9b436489c00ff9497d747a8fd70f380f95601d59e52e021e8","private_key":"0172e330c8b3ba8151689716c455034d43e9600eafceaffa6c9b162c36920109","name":"node_76cbf9fc0f3517fb615fa96104780218e85d064ee5a1d518f3b78f4dbebf144df38c427445fdd6c9b436489c00ff9497d747a8fd70f380f95601d59e52e021e8","services":["streamer"],"enable_msg_events":true,"port":63229},"up":true}},{"node":{"info":{"id":"e023a51c5bd26e1754d6461345143e94baeac799947579ec7adeccd105de39f85afbceeb5037cfc0b820b9f4446433f034d9e7de7326d45df5a967a8099dbb10","name":"node_e023a51c5bd26e1754d6461345143e94baeac799947579ec7adeccd105de39f85afbceeb5037cfc0b820b9f4446433f034d9e7de7326d45df5a967a8099dbb10","enode":"enode://e023a51c5bd26e1754d6461345143e94baeac799947579ec7adeccd105de39f85afbceeb5037cfc0b820b9f4446433f034d9e7de7326d45df5a967a8099dbb10@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"NOSL1lYqMIzPakoCV/JT6QjpfRbe/i8aMeBG1VWKR2k=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 34e48b\npopulation: 20 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 910d 8a54 a3f2 f97e | 134 bd39 (0) beb7 (0) bf6b (0) baaf (0)\n001 1 56bb | 50 63de (0) 60bc (0) 6701 (0) 67ee (0)\n002 1 0fa0 | 37 1254 (0) 11a0 (0) 10b1 (0) 14e4 (0)\n003 4 2c4e 2c16 24f8 2224 | 15 2a7d (0) 2940 (0) 293f (0) 2e3b (0)\n004 4 3ef6 3ff8 3c5a 3baa | 10 3d17 (0) 3c5a (0) 3ef6 (0) 3ff8 (0)\n005 2 307c 3054 | 5 3227 (0) 3388 (0) 3085 (0) 307c (0)\n============ DEPTH: 6 ==========================================\n006 4 3799 3734 3658 3607 | 4 3799 (0) 3734 (0) 3658 (0) 3607 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"e023a51c5bd26e1754d6461345143e94baeac799947579ec7adeccd105de39f85afbceeb5037cfc0b820b9f4446433f034d9e7de7326d45df5a967a8099dbb10","private_key":"2e9b4ad5021be5fdbcdd374c9569d467f370261662cb56e23b98ff5588c8d99d","name":"node_e023a51c5bd26e1754d6461345143e94baeac799947579ec7adeccd105de39f85afbceeb5037cfc0b820b9f4446433f034d9e7de7326d45df5a967a8099dbb10","services":["streamer"],"enable_msg_events":true,"port":63230},"up":true}},{"node":{"info":{"id":"68cc8b9a995eef6170abf88bd5fedca06ffcc8d75f247f6041c13e7dfd292727ebda1ff86b776e33b6634355c55e0f8c22fcdb5f9a6e2f22fe1af7854c3b4273","name":"node_68cc8b9a995eef6170abf88bd5fedca06ffcc8d75f247f6041c13e7dfd292727ebda1ff86b776e33b6634355c55e0f8c22fcdb5f9a6e2f22fe1af7854c3b4273","enode":"enode://68cc8b9a995eef6170abf88bd5fedca06ffcc8d75f247f6041c13e7dfd292727ebda1ff86b776e33b6634355c55e0f8c22fcdb5f9a6e2f22fe1af7854c3b4273@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"IiS9zhFOnodiGrRNGlSxHncU8wumlcg1OpVzrfz4Ivo=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 2224bd\npopulation: 23 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 a3f2 f97e | 134 bd39 (0) beb7 (0) bf6b (0) b820 (0)\n001 2 47a8 56bb | 50 63de (0) 60bc (0) 65a6 (0) 6701 (0)\n002 2 1dfd 0ca9 | 37 05a4 (0) 0536 (0) 07a6 (0) 00c8 (0)\n003 4 3baa 307c 3054 34e4 | 20 3d17 (0) 3c5a (0) 3ef6 (0) 3ff8 (0)\n004 9 2a7d 2940 293f 2e3b | 10 2a7d (0) 2940 (0) 293f (0) 2e3b (0)\n005 2 2737 24f8 | 2 2737 (0) 24f8 (0)\n============ DEPTH: 6 ==========================================\n006 1 208e | 1 208e (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 1 2220 | 1 2220 (0)\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"68cc8b9a995eef6170abf88bd5fedca06ffcc8d75f247f6041c13e7dfd292727ebda1ff86b776e33b6634355c55e0f8c22fcdb5f9a6e2f22fe1af7854c3b4273","private_key":"059dc1a60c68b91d75f771391bae103fb3d7dc30c5dfdc9498980591bc09e0df","name":"node_68cc8b9a995eef6170abf88bd5fedca06ffcc8d75f247f6041c13e7dfd292727ebda1ff86b776e33b6634355c55e0f8c22fcdb5f9a6e2f22fe1af7854c3b4273","services":["streamer"],"enable_msg_events":true,"port":63231},"up":true}},{"node":{"info":{"id":"54b3c57a4adf4dbaf31b85ed1b8dccd6249faa16dd96dd230189f47f57970caeed36627cc8e1b0794707418d580f5bd6001c07be6a79216695f1253db24926bb","name":"node_54b3c57a4adf4dbaf31b85ed1b8dccd6249faa16dd96dd230189f47f57970caeed36627cc8e1b0794707418d580f5bd6001c07be6a79216695f1253db24926bb","enode":"enode://54b3c57a4adf4dbaf31b85ed1b8dccd6249faa16dd96dd230189f47f57970caeed36627cc8e1b0794707418d580f5bd6001c07be6a79216695f1253db24926bb@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"+X6H+A5tswYJoIEb71zHpYhDJqvtXMlw885YBHbQk1w=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: f97e87\npopulation: 26 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 5b30 2224 34e4 3054 | 122 63de (0) 60bc (0) 67ee (0) 6701 (0)\n001 7 b391 baaf a6bd a3f2 | 63 bd39 (0) beb7 (0) bf6b (0) b820 (0)\n002 2 d1bc d07c | 33 c95a (0) c914 (0) c911 (0) caa3 (0)\n003 6 e6b7 e5d2 e406 ebe8 | 25 e190 (0) e255 (0) e3d8 (0) e31e (0)\n004 3 f1ad f054 f0b8 | 8 f6a6 (0) f2f5 (0) f2b2 (0) f293 (0)\n============ DEPTH: 5 ==========================================\n005 4 ffb7 fc88 fd3f fd44 | 4 fc88 (0) fd3f (0) fd44 (0) ffb7 (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"54b3c57a4adf4dbaf31b85ed1b8dccd6249faa16dd96dd230189f47f57970caeed36627cc8e1b0794707418d580f5bd6001c07be6a79216695f1253db24926bb","private_key":"bf0aa2cb855d1702f8353aaf7cf03b846cbe1bdc6a0b66b18dfa8f03ab7dee43","name":"node_54b3c57a4adf4dbaf31b85ed1b8dccd6249faa16dd96dd230189f47f57970caeed36627cc8e1b0794707418d580f5bd6001c07be6a79216695f1253db24926bb","services":["streamer"],"enable_msg_events":true,"port":63232},"up":true}},{"node":{"info":{"id":"df4c3505e09e1baa88470117b964e758c94f77a4546489ab5ab7f4aebfdce424729ace8867475715fb68f05c66c9674a5767549e266c4fadd1c703ddd735908f","name":"node_df4c3505e09e1baa88470117b964e758c94f77a4546489ab5ab7f4aebfdce424729ace8867475715fb68f05c66c9674a5767549e266c4fadd1c703ddd735908f","enode":"enode://df4c3505e09e1baa88470117b964e758c94f77a4546489ab5ab7f4aebfdce424729ace8867475715fb68f05c66c9674a5767549e266c4fadd1c703ddd735908f@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"MFTOm1Qu8q82qytdRZDyuXlBB7u+VcrBCezV3+VtjDI=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 3054ce\npopulation: 24 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 a3f2 9a09 8a54 f97e | 134 bd39 (0) beb7 (0) bf6b (0) b820 (0)\n001 4 6f1c 47a8 5b30 56bb | 50 63de (0) 60bc (0) 65a6 (0) 6701 (0)\n002 3 1dfd 0ca9 0fa0 | 37 1254 (0) 10b1 (0) 11a0 (0) 167b (0)\n003 5 2f23 2c4e 2c16 24f8 | 15 2a7d (0) 2940 (0) 293f (0) 2e3b (0)\n004 3 3c5a 3baa 3ab2 | 10 3ef6 (0) 3ff8 (0) 3d17 (0) 3c5a (0)\n005 1 34e4 | 5 3734 (0) 3799 (0) 3607 (0) 3658 (0)\n006 2 3227 3388 | 2 3227 (0) 3388 (0)\n007 0 | 0\n============ DEPTH: 8 ==========================================\n008 1 3085 | 1 3085 (0)\n009 0 | 0\n010 1 307c | 1 307c (0)\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"df4c3505e09e1baa88470117b964e758c94f77a4546489ab5ab7f4aebfdce424729ace8867475715fb68f05c66c9674a5767549e266c4fadd1c703ddd735908f","private_key":"8b9685b4c43d0de26290fc8646737787fe8ff7e6c32c082060380b41fe2c5f3c","name":"node_df4c3505e09e1baa88470117b964e758c94f77a4546489ab5ab7f4aebfdce424729ace8867475715fb68f05c66c9674a5767549e266c4fadd1c703ddd735908f","services":["streamer"],"enable_msg_events":true,"port":63233},"up":true}},{"node":{"info":{"id":"24662a43944228e4ff74736bcf0a0a4f79c87ecfdb739225b2fc45110c11bfc38aaf2d09d98e5817477848e553f187ac5408bdb864518dfa7f5df542768828db","name":"node_24662a43944228e4ff74736bcf0a0a4f79c87ecfdb739225b2fc45110c11bfc38aaf2d09d98e5817477848e553f187ac5408bdb864518dfa7f5df542768828db","enode":"enode://24662a43944228e4ff74736bcf0a0a4f79c87ecfdb739225b2fc45110c11bfc38aaf2d09d98e5817477848e553f187ac5408bdb864518dfa7f5df542768828db@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"ilQ5rfmYf44N8FK1wyWZ26CiXT5F3OTK/fLS3f2uL0I=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 8a5439\npopulation: 23 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 56bb 5b30 34e4 3054 | 122 63de (0) 60bc (0) 6701 (0) 67ee (0)\n001 2 d1bc f97e | 71 cf77 (0) ce71 (0) caa3 (0) ca8c (0)\n002 3 b391 b049 a3f2 | 30 bd39 (0) beb7 (0) bf6b (0) b820 (0)\n003 4 910d 9918 9b87 9a09 | 18 9641 (0) 9747 (0) 9404 (0) 9493 (0)\n004 4 802e 83d0 8434 8611 | 8 802f (0) 802e (0) 83d0 (0) 853b (0)\n005 4 8d85 8d3c 8ee7 8ea9 | 4 8d3c (0) 8d85 (0) 8ee7 (0) 8ea9 (0)\n============ DEPTH: 6 ==========================================\n006 1 89ef | 1 89ef (0)\n007 0 | 0\n008 1 8ae8 | 1 8ae8 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"24662a43944228e4ff74736bcf0a0a4f79c87ecfdb739225b2fc45110c11bfc38aaf2d09d98e5817477848e553f187ac5408bdb864518dfa7f5df542768828db","private_key":"a5bf3b5b166cc21128321759e5be62f691455e382d8ed35e48805cbb2d884a97","name":"node_24662a43944228e4ff74736bcf0a0a4f79c87ecfdb739225b2fc45110c11bfc38aaf2d09d98e5817477848e553f187ac5408bdb864518dfa7f5df542768828db","services":["streamer"],"enable_msg_events":true,"port":63234},"up":true}},{"node":{"info":{"id":"27d9048707a89f1a61e44fdae523c0128f2a7050308bd3cfefa6c3e03040a0e22f11ab41275f22b8706e6695ab93320e2af35179d772581db5f49f960750f2f7","name":"node_27d9048707a89f1a61e44fdae523c0128f2a7050308bd3cfefa6c3e03040a0e22f11ab41275f22b8706e6695ab93320e2af35179d772581db5f49f960750f2f7","enode":"enode://27d9048707a89f1a61e44fdae523c0128f2a7050308bd3cfefa6c3e03040a0e22f11ab41275f22b8706e6695ab93320e2af35179d772581db5f49f960750f2f7@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"o/Kg09/xkUYkrhE90N/vchdfA97Vy6iev3XjUMRlFSU=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: a3f2a0\npopulation: 24 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 6 167b 2224 34e4 3054 | 122 1254 (0) 10b1 (0) 11a0 (0) 167b (0)\n001 1 f97e | 71 c3d8 (0) c301 (0) c409 (0) c60e (0)\n002 3 8a54 9918 9a09 | 33 802f (0) 802e (0) 83d0 (0) 853b (0)\n003 2 b391 b049 | 13 bd39 (0) beb7 (0) bf6b (0) b820 (0)\n004 1 a9df | 5 ac62 (0) af8f (0) aa78 (0) a936 (0)\n005 3 a478 a6bd a75d | 3 a478 (0) a75d (0) a6bd (0)\n============ DEPTH: 6 ==========================================\n006 7 a077 a011 a0e4 a0c9 | 7 a077 (0) a011 (0) a0e4 (0) a0c9 (0)\n007 0 | 0\n008 1 a317 | 1 a317 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"27d9048707a89f1a61e44fdae523c0128f2a7050308bd3cfefa6c3e03040a0e22f11ab41275f22b8706e6695ab93320e2af35179d772581db5f49f960750f2f7","private_key":"b64868a78b7e20e3914999f841765a445e99246e67a0d8706639a2e940c1dfef","name":"node_27d9048707a89f1a61e44fdae523c0128f2a7050308bd3cfefa6c3e03040a0e22f11ab41275f22b8706e6695ab93320e2af35179d772581db5f49f960750f2f7","services":["streamer"],"enable_msg_events":true,"port":63235},"up":true}},{"node":{"info":{"id":"ea57884dd42aec5a76eab43483bf7c4ae2c19eebf365013731de64494d10a3b4cfe34c86c79437f9012bc8cf6bd761435eefadec17600f4b9e4bc234532d6282","name":"node_ea57884dd42aec5a76eab43483bf7c4ae2c19eebf365013731de64494d10a3b4cfe34c86c79437f9012bc8cf6bd761435eefadec17600f4b9e4bc234532d6282","enode":"enode://ea57884dd42aec5a76eab43483bf7c4ae2c19eebf365013731de64494d10a3b4cfe34c86c79437f9012bc8cf6bd761435eefadec17600f4b9e4bc234532d6282@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"mgmqFo9/Tr2QZS1pAKzhuoi4eFKQsmh3g9SiPpvbkO4=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 9a09aa\npopulation: 21 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 3054 5b30 | 122 1953 (0) 1af6 (0) 1a85 (0) 1a8e (0)\n001 1 f97e | 71 c3d8 (0) c301 (0) c60e (0) c7fa (0)\n002 2 b049 a3f2 | 30 bd39 (0) beb7 (0) bf6b (0) b820 (0)\n003 3 83d0 8ea9 8a54 | 15 802f (0) 802e (0) 83d0 (0) 853b (0)\n004 4 9493 9404 92d5 910d | 8 9747 (0) 9641 (0) 9493 (0) 9404 (0)\n005 1 9f4c | 1 9f4c (0)\n006 6 985f 98bc 98aa 99eb | 6 99eb (0) 9929 (0) 9918 (0) 98bc (0)\n============ DEPTH: 7 ==========================================\n007 2 9bc3 9b87 | 2 9bc3 (0) 9b87 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"ea57884dd42aec5a76eab43483bf7c4ae2c19eebf365013731de64494d10a3b4cfe34c86c79437f9012bc8cf6bd761435eefadec17600f4b9e4bc234532d6282","private_key":"f72fdd8aca59748c35831f451f405cbd0aa950ce62699f1f7c9c10d76cf1e588","name":"node_ea57884dd42aec5a76eab43483bf7c4ae2c19eebf365013731de64494d10a3b4cfe34c86c79437f9012bc8cf6bd761435eefadec17600f4b9e4bc234532d6282","services":["streamer"],"enable_msg_events":true,"port":63236},"up":true}},{"node":{"info":{"id":"3b570117addeec03c2694baf28e246f91907268fe665c6c90356120332794258ee57a60853c19e9fe25d042ca42a5be7fe0797d84199174de8132f1ef4a9349b","name":"node_3b570117addeec03c2694baf28e246f91907268fe665c6c90356120332794258ee57a60853c19e9fe25d042ca42a5be7fe0797d84199174de8132f1ef4a9349b","enode":"enode://3b570117addeec03c2694baf28e246f91907268fe665c6c90356120332794258ee57a60853c19e9fe25d042ca42a5be7fe0797d84199174de8132f1ef4a9349b@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"WzCLJc/jDQtoeE3HO+Rk36hajknd1vYnH/DuK2N5iSg=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 5b308b\npopulation: 21 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 f97e a3f2 8a54 9a09 | 134 c3d8 (0) c301 (0) c409 (0) c60e (0)\n001 6 1758 0fa0 3054 307c | 72 1953 (0) 1af6 (0) 1a85 (0) 1a8e (0)\n002 3 7299 60bc 63de | 19 63de (0) 60bc (0) 6701 (0) 67ee (0)\n003 1 47a8 | 16 4dc4 (0) 4c97 (0) 48ec (0) 48df (0)\n004 2 510c 56bb | 9 5237 (0) 5399 (0) 5070 (0) 5062 (0)\n005 3 5e3e 5cae 5c9b | 3 5e3e (0) 5cae (0) 5c9b (0)\n============ DEPTH: 6 ==========================================\n006 1 581a | 1 581a (0)\n007 1 5a67 | 1 5a67 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"3b570117addeec03c2694baf28e246f91907268fe665c6c90356120332794258ee57a60853c19e9fe25d042ca42a5be7fe0797d84199174de8132f1ef4a9349b","private_key":"9a8b5a154d6b376a8d8a1c5357272f164206a01554ae4fcdf479ffa3e80ec4a6","name":"node_3b570117addeec03c2694baf28e246f91907268fe665c6c90356120332794258ee57a60853c19e9fe25d042ca42a5be7fe0797d84199174de8132f1ef4a9349b","services":["streamer"],"enable_msg_events":true,"port":63237},"up":true}},{"node":{"info":{"id":"0cacda5560faff9d20e29a0625d3cd340ec075f198a50ab8b79338cee0e0db84c7c7e71042fd8c8f73e507b570de5d26c39473136b575f0167625a1168309ec5","name":"node_0cacda5560faff9d20e29a0625d3cd340ec075f198a50ab8b79338cee0e0db84c7c7e71042fd8c8f73e507b570de5d26c39473136b575f0167625a1168309ec5","enode":"enode://0cacda5560faff9d20e29a0625d3cd340ec075f198a50ab8b79338cee0e0db84c7c7e71042fd8c8f73e507b570de5d26c39473136b575f0167625a1168309ec5@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"LBZhEikhfpbmnT1KBvfUTXzCblEagW2wNi61K8oc4+A=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 2c1661\npopulation: 25 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 d1bc | 134 9641 (0) 9747 (0) 9493 (0) 9404 (0)\n001 3 47a8 56bb 5b30 | 50 63de (0) 60bc (0) 65a6 (0) 6701 (0)\n002 5 1dfd 15ec 0bc3 0ca9 | 37 1af6 (0) 1a85 (0) 1a8e (0) 1953 (0)\n003 7 3baa 3c5a 3658 34e4 | 20 398b (0) 38d7 (0) 3843 (0) 3a18 (0)\n004 2 24f8 2224 | 5 2737 (0) 24f8 (0) 208e (0) 2220 (0)\n005 1 293f | 3 2a7d (0) 2940 (0) 293f (0)\n006 3 2e3b 2f1f 2f23 | 3 2e3b (0) 2f1f (0) 2f23 (0)\n007 0 | 0\n============ DEPTH: 8 ==========================================\n008 2 2cb1 2cab | 2 2cb1 (0) 2cab (0)\n009 1 2c4e | 1 2c4e (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"0cacda5560faff9d20e29a0625d3cd340ec075f198a50ab8b79338cee0e0db84c7c7e71042fd8c8f73e507b570de5d26c39473136b575f0167625a1168309ec5","private_key":"5007a8f6bdeaf7620240976e1d41aca23e841378ec3a157b199d5fea27b1e0c7","name":"node_0cacda5560faff9d20e29a0625d3cd340ec075f198a50ab8b79338cee0e0db84c7c7e71042fd8c8f73e507b570de5d26c39473136b575f0167625a1168309ec5","services":["streamer"],"enable_msg_events":true,"port":63238},"up":true}},{"node":{"info":{"id":"88d5c5fe61ee1e6fa5878e0eaa13bdabaa0ec3d38a5d25b95a467da7627424f25fb5d30535aa0a5ad01c16fe2598dbf570b78cc152a7f4ef66d46fc9ae43592f","name":"node_88d5c5fe61ee1e6fa5878e0eaa13bdabaa0ec3d38a5d25b95a467da7627424f25fb5d30535aa0a5ad01c16fe2598dbf570b78cc152a7f4ef66d46fc9ae43592f","enode":"enode://88d5c5fe61ee1e6fa5878e0eaa13bdabaa0ec3d38a5d25b95a467da7627424f25fb5d30535aa0a5ad01c16fe2598dbf570b78cc152a7f4ef66d46fc9ae43592f@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"0bwmOCosZtk/lvgrqmMkpioaVXS3pweLV5xFJCnmHK4=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: d1bc26\npopulation: 22 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 0fa0 2c4e 2c16 | 122 6923 (0) 69d8 (0) 6caa (0) 6f1c (0)\n001 3 8a54 b391 b049 | 63 9641 (0) 9747 (0) 9404 (0) 9493 (0)\n002 6 f97e e9fa ebe8 e6b7 | 38 f6a6 (0) f2f5 (0) f2b2 (0) f293 (0)\n003 1 c301 | 14 c95a (0) c911 (0) c914 (0) caa3 (0)\n004 1 de1d | 5 dad3 (0) d90b (0) d96e (0) df52 (0)\n005 2 d777 d717 | 7 d455 (0) d560 (0) d66f (0) d606 (0)\n006 3 d2ac d3bd d35c | 3 d35c (0) d3bd (0) d2ac (0)\n============ DEPTH: 7 ==========================================\n007 3 d0b7 d07c d044 | 3 d0b7 (0) d044 (0) d07c (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"88d5c5fe61ee1e6fa5878e0eaa13bdabaa0ec3d38a5d25b95a467da7627424f25fb5d30535aa0a5ad01c16fe2598dbf570b78cc152a7f4ef66d46fc9ae43592f","private_key":"a7d2d7f12b632dd6c409c8e7cd5da6f2009d1ed9d27eff101c0e850934695ee6","name":"node_88d5c5fe61ee1e6fa5878e0eaa13bdabaa0ec3d38a5d25b95a467da7627424f25fb5d30535aa0a5ad01c16fe2598dbf570b78cc152a7f4ef66d46fc9ae43592f","services":["streamer"],"enable_msg_events":true,"port":63239},"up":true}},{"node":{"info":{"id":"80d997b87856099d844187d3d1fa40846ded652a62c1611b35919c2543915b64ff62476636488556f678e436ea26fcc40db7c6b6bbcb78f590d61c1ff0e424b5","name":"node_80d997b87856099d844187d3d1fa40846ded652a62c1611b35919c2543915b64ff62476636488556f678e436ea26fcc40db7c6b6bbcb78f590d61c1ff0e424b5","enode":"enode://80d997b87856099d844187d3d1fa40846ded652a62c1611b35919c2543915b64ff62476636488556f678e436ea26fcc40db7c6b6bbcb78f590d61c1ff0e424b5@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"0HwsPWhGhKMXi6yPRXjRRHEX9gS8R17+EI3OViFkOEY=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: d07c2c\npopulation: 22 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 0fa0 307c | 122 63de (0) 60bc (0) 65a6 (0) 67ee (0)\n001 2 b391 b049 | 63 93f8 (0) 92d5 (0) 9108 (0) 910d (0)\n002 6 f97e e6b7 e406 e5d2 | 38 f6a6 (0) f2f5 (0) f2b2 (0) f293 (0)\n003 3 ce71 c7fa c301 | 14 c3d8 (0) c301 (0) c409 (0) c60e (0)\n004 1 de1d | 5 dad3 (0) d90b (0) d96e (0) df52 (0)\n005 2 d66f d7c1 | 7 d455 (0) d560 (0) d606 (0) d66f (0)\n006 3 d35c d3bd d2ac | 3 d35c (0) d3bd (0) d2ac (0)\n007 1 d1bc | 1 d1bc (0)\n============ DEPTH: 8 ==========================================\n008 1 d0b7 | 1 d0b7 (0)\n009 0 | 0\n010 1 d044 | 1 d044 (0)\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"80d997b87856099d844187d3d1fa40846ded652a62c1611b35919c2543915b64ff62476636488556f678e436ea26fcc40db7c6b6bbcb78f590d61c1ff0e424b5","private_key":"9e7d9771bc8ee20b1bf0743ba1e8cf1501c54606fcf9e174930cf61de03ba696","name":"node_80d997b87856099d844187d3d1fa40846ded652a62c1611b35919c2543915b64ff62476636488556f678e436ea26fcc40db7c6b6bbcb78f590d61c1ff0e424b5","services":["streamer"],"enable_msg_events":true,"port":63240},"up":true}},{"node":{"info":{"id":"6bf9fb6a25521c16c2ebeb6203d046d7dd40f29cc2ddb067c0222ef56d7012d2ee5d037f71f6668ea56767610b2a54c144aed74b7f68d06993cbd52fa1dc7630","name":"node_6bf9fb6a25521c16c2ebeb6203d046d7dd40f29cc2ddb067c0222ef56d7012d2ee5d037f71f6668ea56767610b2a54c144aed74b7f68d06993cbd52fa1dc7630","enode":"enode://6bf9fb6a25521c16c2ebeb6203d046d7dd40f29cc2ddb067c0222ef56d7012d2ee5d037f71f6668ea56767610b2a54c144aed74b7f68d06993cbd52fa1dc7630@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"MHw2qUf1xMWXB12DRqXbYTP70sFNoJn4XB0rfW2DMfI=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 307c36\npopulation: 20 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 b391 d07c | 134 f6a6 (0) f293 (0) f2b2 (0) f2f5 (0)\n001 1 5b30 | 50 63de (0) 60bc (0) 6701 (0) 67ee (0)\n002 4 15ec 0bc3 0ca9 0fa0 | 37 1953 (0) 1af6 (0) 1a85 (0) 1a8e (0)\n003 4 2224 2f23 2c4e 2c16 | 15 2737 (0) 24f8 (0) 208e (0) 2220 (0)\n004 3 3baa 3d17 3ff8 | 10 398b (0) 38d7 (0) 3843 (0) 3baa (0)\n005 2 34e4 3658 | 5 34e4 (0) 3734 (0) 3799 (0) 3607 (0)\n006 2 3227 3388 | 2 3227 (0) 3388 (0)\n007 0 | 0\n============ DEPTH: 8 ==========================================\n008 1 3085 | 1 3085 (0)\n009 0 | 0\n010 1 3054 | 1 3054 (0)\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"6bf9fb6a25521c16c2ebeb6203d046d7dd40f29cc2ddb067c0222ef56d7012d2ee5d037f71f6668ea56767610b2a54c144aed74b7f68d06993cbd52fa1dc7630","private_key":"f28a26c4cb4589d2ffe6731d30ce96e197684de24e886f252b6cda9eb4bca962","name":"node_6bf9fb6a25521c16c2ebeb6203d046d7dd40f29cc2ddb067c0222ef56d7012d2ee5d037f71f6668ea56767610b2a54c144aed74b7f68d06993cbd52fa1dc7630","services":["streamer"],"enable_msg_events":true,"port":63241},"up":true}},{"node":{"info":{"id":"23f9bdc82efbf57d3d40a1f2617d0311678fb4a3d6a50cb7e608c649bb618124a76c7ffd17387de963e1cd28d2bd5a61c98613f6e009a8a2a90d989827b35de0","name":"node_23f9bdc82efbf57d3d40a1f2617d0311678fb4a3d6a50cb7e608c649bb618124a76c7ffd17387de963e1cd28d2bd5a61c98613f6e009a8a2a90d989827b35de0","enode":"enode://23f9bdc82efbf57d3d40a1f2617d0311678fb4a3d6a50cb7e608c649bb618124a76c7ffd17387de963e1cd28d2bd5a61c98613f6e009a8a2a90d989827b35de0@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"s5EOaT72nDfN/J+DHwT6hUl5ft0WrDFqlf5fn946s6I=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: b3910e\npopulation: 24 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 5 4c97 7299 0bc3 307c | 122 65a6 (0) 67ee (0) 6701 (0) 60bc (0)\n001 4 d1bc d07c e9fa f97e | 71 f6a6 (0) f2f5 (0) f293 (0) f2b2 (0)\n002 1 8a54 | 33 910d (0) 9108 (0) 93f8 (0) 92d5 (0)\n003 6 a936 a9df a0c9 a1b6 | 17 af8f (0) ac62 (0) aa78 (0) a936 (0)\n004 3 b820 bbcb baaf | 7 bd39 (0) beb7 (0) bf6b (0) b820 (0)\n005 3 b7aa b45f b40d | 3 b40d (0) b45f (0) b7aa (0)\n============ DEPTH: 6 ==========================================\n006 1 b049 | 1 b049 (0)\n007 0 | 0\n008 1 b30e | 1 b30e (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"23f9bdc82efbf57d3d40a1f2617d0311678fb4a3d6a50cb7e608c649bb618124a76c7ffd17387de963e1cd28d2bd5a61c98613f6e009a8a2a90d989827b35de0","private_key":"03c65c150995cc6ea4d0a925bbeb304f8b289d695855b69197bd9284c537e8e5","name":"node_23f9bdc82efbf57d3d40a1f2617d0311678fb4a3d6a50cb7e608c649bb618124a76c7ffd17387de963e1cd28d2bd5a61c98613f6e009a8a2a90d989827b35de0","services":["streamer"],"enable_msg_events":true,"port":63242},"up":true}},{"node":{"info":{"id":"f6ca39b3ad803e99f4e4e9cf759fff6abdf06e6972bdbe524f6eb930c669d6f0e9b91f3de9df394b0d661b068273861391bdbac948ad911351c48cf02f874db6","name":"node_f6ca39b3ad803e99f4e4e9cf759fff6abdf06e6972bdbe524f6eb930c669d6f0e9b91f3de9df394b0d661b068273861391bdbac948ad911351c48cf02f874db6","enode":"enode://f6ca39b3ad803e99f4e4e9cf759fff6abdf06e6972bdbe524f6eb930c669d6f0e9b91f3de9df394b0d661b068273861391bdbac948ad911351c48cf02f874db6@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"LE6xPj0CyR4EMTDwT54kjD0euax1eLOCX6vLMIhP07A=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 2c4eb1\npopulation: 27 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 b391 d1bc e9fa | 134 c3d8 (0) c301 (0) c409 (0) c60e (0)\n001 2 56bb 5b30 | 50 7ec4 (0) 7e45 (0) 7810 (0) 7aef (0)\n002 4 15ec 1758 0bc3 0fa0 | 37 1953 (0) 1af6 (0) 1a85 (0) 1a8e (0)\n003 8 3d17 3baa 34e4 3658 | 20 398b (0) 38d7 (0) 3843 (0) 3a18 (0)\n004 3 24f8 2220 2224 | 5 2737 (0) 24f8 (0) 208e (0) 2220 (0)\n005 1 293f | 3 2a7d (0) 2940 (0) 293f (0)\n006 3 2e3b 2f1f 2f23 | 3 2e3b (0) 2f1f (0) 2f23 (0)\n007 0 | 0\n============ DEPTH: 8 ==========================================\n008 2 2cb1 2cab | 2 2cb1 (0) 2cab (0)\n009 1 2c16 | 1 2c16 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"f6ca39b3ad803e99f4e4e9cf759fff6abdf06e6972bdbe524f6eb930c669d6f0e9b91f3de9df394b0d661b068273861391bdbac948ad911351c48cf02f874db6","private_key":"0af9f76e6251f7612eb7fde7f20ebf9dc8334ae1139a6e2dd068a97a896860ba","name":"node_f6ca39b3ad803e99f4e4e9cf759fff6abdf06e6972bdbe524f6eb930c669d6f0e9b91f3de9df394b0d661b068273861391bdbac948ad911351c48cf02f874db6","services":["streamer"],"enable_msg_events":true,"port":63243},"up":true}},{"node":{"info":{"id":"385168340139236a0e0f537fa693122db9fa02a377c96f31aae54718e92624fc0288164877e63616651565e055c53f7074ab2fdd18a837da6faf644941305bf0","name":"node_385168340139236a0e0f537fa693122db9fa02a377c96f31aae54718e92624fc0288164877e63616651565e055c53f7074ab2fdd18a837da6faf644941305bf0","enode":"enode://385168340139236a0e0f537fa693122db9fa02a377c96f31aae54718e92624fc0288164877e63616651565e055c53f7074ab2fdd18a837da6faf644941305bf0@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"D6Ar7c6qKGGPSPMZ04tlejVgmayYc09ALEyEakw1tng=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 0fa02b\npopulation: 26 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 5 b049 d1bc d07c ec78 | 134 9747 (0) 9641 (0) 9493 (0) 9404 (0)\n001 1 5b30 | 50 6923 (0) 69d8 (0) 6f1c (0) 6caa (0)\n002 7 34e4 3658 3388 3054 | 35 398b (0) 38d7 (0) 3843 (0) 3a18 (0)\n003 2 15ec 1dfc | 19 1953 (0) 1af6 (0) 1a8e (0) 1a85 (0)\n004 2 0305 0020 | 7 05a4 (0) 0536 (0) 07a6 (0) 00c8 (0)\n005 3 09d1 0a3f 0bc3 | 4 09d1 (0) 0ad6 (0) 0a3f (0) 0bc3 (0)\n============ DEPTH: 6 ==========================================\n006 5 0daf 0d97 0c72 0c19 | 5 0daf (0) 0d97 (0) 0c72 (0) 0c19 (0)\n007 0 | 0\n008 1 0f65 | 1 0f65 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"385168340139236a0e0f537fa693122db9fa02a377c96f31aae54718e92624fc0288164877e63616651565e055c53f7074ab2fdd18a837da6faf644941305bf0","private_key":"1058a6e2e08d811ed1ab6b6eb927323ad28292591a70269330779d52491c6d64","name":"node_385168340139236a0e0f537fa693122db9fa02a377c96f31aae54718e92624fc0288164877e63616651565e055c53f7074ab2fdd18a837da6faf644941305bf0","services":["streamer"],"enable_msg_events":true,"port":63244},"up":true}},{"node":{"info":{"id":"9194a3a4c8f3235203e48bdb10902d958d26c342805ea6365af9711213536509719d917c694f9a4fbdde6889a4c92299a5301f0275bda4dbcd2541b5bff5b271","name":"node_9194a3a4c8f3235203e48bdb10902d958d26c342805ea6365af9711213536509719d917c694f9a4fbdde6889a4c92299a5301f0275bda4dbcd2541b5bff5b271","enode":"enode://9194a3a4c8f3235203e48bdb10902d958d26c342805ea6365af9711213536509719d917c694f9a4fbdde6889a4c92299a5301f0275bda4dbcd2541b5bff5b271@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"6foahSnd3OJ29mx4IjygbOsC+slepuGLURigQXs3Cgk=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: e9fa1a\npopulation: 26 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 7 3ff8 3388 2f23 2c4e | 122 6923 (0) 69d8 (0) 6caa (0) 6f1c (0)\n001 2 b391 b049 | 63 92d5 (0) 93f8 (0) 9108 (0) 910d (0)\n002 3 de1d d1bc d07c | 33 c3d8 (0) c301 (0) c409 (0) c60e (0)\n003 1 f97e | 13 f6a6 (0) f2f5 (0) f2b2 (0) f293 (0)\n004 3 e190 e406 e5d2 | 13 e190 (0) e255 (0) e3d8 (0) e31e (0)\n005 7 ec78 ecff ee52 ee3f | 8 ec78 (0) ecff (0) ee3f (0) ee52 (0)\n============ DEPTH: 6 ==========================================\n006 2 ebe8 ebc9 | 2 ebc9 (0) ebe8 (0)\n007 1 e850 | 1 e850 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"9194a3a4c8f3235203e48bdb10902d958d26c342805ea6365af9711213536509719d917c694f9a4fbdde6889a4c92299a5301f0275bda4dbcd2541b5bff5b271","private_key":"85e1a2673b4ec4f876778b6fb175fae0e36e9e6456c8d8fa2a11bca2dcc8b376","name":"node_9194a3a4c8f3235203e48bdb10902d958d26c342805ea6365af9711213536509719d917c694f9a4fbdde6889a4c92299a5301f0275bda4dbcd2541b5bff5b271","services":["streamer"],"enable_msg_events":true,"port":63245},"up":true}},{"node":{"info":{"id":"c2705ee7238ef9305e4da196653cde707649435a1e8b5b797d164e5ca06184a77af5bd7fa938c995fdfcbce724fa7eca3d908ee34891ab62cc6dfd411c3fa1da","name":"node_c2705ee7238ef9305e4da196653cde707649435a1e8b5b797d164e5ca06184a77af5bd7fa938c995fdfcbce724fa7eca3d908ee34891ab62cc6dfd411c3fa1da","enode":"enode://c2705ee7238ef9305e4da196653cde707649435a1e8b5b797d164e5ca06184a77af5bd7fa938c995fdfcbce724fa7eca3d908ee34891ab62cc6dfd411c3fa1da@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"sEkx6oQoJYr0EoY3cELKTvey9QfvO6FFErNqBDoYQlM=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: b04931\npopulation: 28 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 8 2f23 3ff8 3658 3388 | 122 7e45 (0) 7ec4 (0) 7810 (0) 7aef (0)\n001 4 de1d d1bc d07c e9fa | 71 cf77 (0) ce71 (0) c95a (0) c914 (0)\n002 2 9a09 8a54 | 33 9747 (0) 9641 (0) 9493 (0) 9404 (0)\n003 6 a9df a6bd a3f2 a0c9 | 17 af8f (0) ac62 (0) aa78 (0) a936 (0)\n004 3 bf6b bbcb baaf | 7 bd39 (0) beb7 (0) bf6b (0) b820 (0)\n005 3 b7aa b40d b45f | 3 b40d (0) b45f (0) b7aa (0)\n============ DEPTH: 6 ==========================================\n006 2 b391 b30e | 2 b30e (0) b391 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"c2705ee7238ef9305e4da196653cde707649435a1e8b5b797d164e5ca06184a77af5bd7fa938c995fdfcbce724fa7eca3d908ee34891ab62cc6dfd411c3fa1da","private_key":"54906c0600d9da9afc0e64bb94c7902ff60042840c9143900f2ae8fe9ba69c63","name":"node_c2705ee7238ef9305e4da196653cde707649435a1e8b5b797d164e5ca06184a77af5bd7fa938c995fdfcbce724fa7eca3d908ee34891ab62cc6dfd411c3fa1da","services":["streamer"],"enable_msg_events":true,"port":63246},"up":true}},{"node":{"info":{"id":"bf4ff51cc3d9a9d8cefd7e346ce1384d06450228a6086fe12fb0c60fec54bb6478f090bb638fbdbf8f41f7bc6420cd8a5c8b1b8566229b6851167375ef412f46","name":"node_bf4ff51cc3d9a9d8cefd7e346ce1384d06450228a6086fe12fb0c60fec54bb6478f090bb638fbdbf8f41f7bc6420cd8a5c8b1b8566229b6851167375ef412f46","enode":"enode://bf4ff51cc3d9a9d8cefd7e346ce1384d06450228a6086fe12fb0c60fec54bb6478f090bb638fbdbf8f41f7bc6420cd8a5c8b1b8566229b6851167375ef412f46@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"C8MKVH5g3DWPG0Mbj0TUZHHBneVGcj2hXl7D06/S3fg=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 0bc30a\npopulation: 22 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 e9fa b391 b049 | 134 cf77 (0) ce71 (0) c95a (0) c914 (0)\n001 2 43fb 581a | 50 6f1c (0) 6caa (0) 6923 (0) 69d8 (0)\n002 7 3ff8 3658 307c 3388 | 35 34e4 (0) 3734 (0) 3799 (0) 3607 (0)\n003 3 1dfc 1758 15ec | 19 1953 (0) 1af6 (0) 1a8e (0) 1a85 (0)\n004 2 0020 0305 | 7 05a4 (0) 0536 (0) 07a6 (0) 00c8 (0)\n005 2 0ca9 0fa0 | 7 0daf (0) 0d97 (0) 0c72 (0) 0c19 (0)\n006 1 09d1 | 1 09d1 (0)\n============ DEPTH: 7 ==========================================\n007 2 0a3f 0ad6 | 2 0ad6 (0) 0a3f (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"bf4ff51cc3d9a9d8cefd7e346ce1384d06450228a6086fe12fb0c60fec54bb6478f090bb638fbdbf8f41f7bc6420cd8a5c8b1b8566229b6851167375ef412f46","private_key":"b798233dd61ca3bf4bcf5729b06de9bee5447b3c0c4f604eb12e856ff1363492","name":"node_bf4ff51cc3d9a9d8cefd7e346ce1384d06450228a6086fe12fb0c60fec54bb6478f090bb638fbdbf8f41f7bc6420cd8a5c8b1b8566229b6851167375ef412f46","services":["streamer"],"enable_msg_events":true,"port":63247},"up":true}},{"node":{"info":{"id":"f33d1f3e460574706ac1c7fc9ebb4683b173496ce3e80017d1c3521bca03d5a41a9c7a6cde8347d2238917b7cc58cab000ce7ccf6bb408561015a2ecbe613408","name":"node_f33d1f3e460574706ac1c7fc9ebb4683b173496ce3e80017d1c3521bca03d5a41a9c7a6cde8347d2238917b7cc58cab000ce7ccf6bb408561015a2ecbe613408","enode":"enode://f33d1f3e460574706ac1c7fc9ebb4683b173496ce3e80017d1c3521bca03d5a41a9c7a6cde8347d2238917b7cc58cab000ce7ccf6bb408561015a2ecbe613408@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"LyMBZt4DYqyr5CWKGf4Z1JORLg4GE2dKbMljz0izdvE=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 2f2301\npopulation: 28 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 e9fa 8611 b049 | 134 ca8c (0) caa3 (0) cba4 (0) cbd3 (0)\n001 5 43fb 4bbc 581a 56bb | 50 7810 (0) 7aef (0) 7e45 (0) 7ec4 (0)\n002 4 1dfc 15ec 1758 0bc3 | 37 1953 (0) 1af6 (0) 1a85 (0) 1a8e (0)\n003 7 307c 3054 3388 3607 | 20 34e4 (0) 3734 (0) 3799 (0) 3607 (0)\n004 2 2224 24f8 | 5 208e (0) 2220 (0) 2224 (0) 2737 (0)\n005 1 293f | 3 2a7d (0) 2940 (0) 293f (0)\n006 4 2cb1 2cab 2c16 2c4e | 4 2cab (0) 2cb1 (0) 2c16 (0) 2c4e (0)\n============ DEPTH: 7 ==========================================\n007 1 2e3b | 1 2e3b (0)\n008 0 | 0\n009 0 | 0\n010 1 2f1f | 1 2f1f (0)\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"f33d1f3e460574706ac1c7fc9ebb4683b173496ce3e80017d1c3521bca03d5a41a9c7a6cde8347d2238917b7cc58cab000ce7ccf6bb408561015a2ecbe613408","private_key":"529b3a0af71a5e49aeaa2a7ec622d5a1fb3a920fa64f8d200af8f96f0c2d5d21","name":"node_f33d1f3e460574706ac1c7fc9ebb4683b173496ce3e80017d1c3521bca03d5a41a9c7a6cde8347d2238917b7cc58cab000ce7ccf6bb408561015a2ecbe613408","services":["streamer"],"enable_msg_events":true,"port":63248},"up":true}},{"node":{"info":{"id":"083e67bb19e30d14e4df6d2483367d6659d9b56744d53d9cf7fd15954c327e1bc88a5d0db8833634e1dad7209164451f8934b59f76b5990059261abfd650519a","name":"node_083e67bb19e30d14e4df6d2483367d6659d9b56744d53d9cf7fd15954c327e1bc88a5d0db8833634e1dad7209164451f8934b59f76b5990059261abfd650519a","enode":"enode://083e67bb19e30d14e4df6d2483367d6659d9b56744d53d9cf7fd15954c327e1bc88a5d0db8833634e1dad7209164451f8934b59f76b5990059261abfd650519a@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"P/gAiaLvN3sYRIgTALPoUEGxbw51CLAeWaDna2PIJE4=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 3ff800\npopulation: 35 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 5 e9fa 8611 9b87 a1b6 | 134 c301 (0) c3d8 (0) c7fa (0) c60e (0)\n001 7 43fb 4bbc 5cae 581a | 50 6f1c (0) 6caa (0) 6923 (0) 69d8 (0)\n002 4 1758 15ec 05a4 0bc3 | 37 0536 (0) 05a4 (0) 07a6 (0) 00c8 (0)\n003 3 2220 208e 2f23 | 15 24f8 (0) 2737 (0) 2224 (0) 2220 (0)\n004 7 34e4 3799 3607 3658 | 10 34e4 (0) 3734 (0) 3799 (0) 3607 (0)\n005 6 398b 38d7 3843 3baa | 6 398b (0) 38d7 (0) 3843 (0) 3baa (0)\n============ DEPTH: 6 ==========================================\n006 2 3d17 3c5a | 2 3d17 (0) 3c5a (0)\n007 1 3ef6 | 1 3ef6 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"083e67bb19e30d14e4df6d2483367d6659d9b56744d53d9cf7fd15954c327e1bc88a5d0db8833634e1dad7209164451f8934b59f76b5990059261abfd650519a","private_key":"d6dd6c5f414a03e6e909bb7447653cbdc2b5adf6bcb2a4643c2cc7572e574a11","name":"node_083e67bb19e30d14e4df6d2483367d6659d9b56744d53d9cf7fd15954c327e1bc88a5d0db8833634e1dad7209164451f8934b59f76b5990059261abfd650519a","services":["streamer"],"enable_msg_events":true,"port":63249},"up":true}},{"node":{"info":{"id":"0c14dd51a56130c51009e3ce47c96b2afef26b7e86cfca65d8a9bae1abef13b3a7a192b422d894c39e24ab00be412d166a3571cc259ff4462d4ad8925a153766","name":"node_0c14dd51a56130c51009e3ce47c96b2afef26b7e86cfca65d8a9bae1abef13b3a7a192b422d894c39e24ab00be412d166a3571cc259ff4462d4ad8925a153766","enode":"enode://0c14dd51a56130c51009e3ce47c96b2afef26b7e86cfca65d8a9bae1abef13b3a7a192b422d894c39e24ab00be412d166a3571cc259ff4462d4ad8925a153766@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"M4gSO6078d6/UcWSHAnQb3Yn0F9hFa852S2+my8jE9w=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 338812\npopulation: 19 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 e9fa b049 | 134 caa3 (0) ca8c (0) cba4 (0) cbd3 (0)\n001 1 43fb | 50 7e45 (0) 7ec4 (0) 7810 (0) 7aef (0)\n002 5 0305 0fa0 0bc3 15ec | 37 0536 (0) 05a4 (0) 07a6 (0) 00c8 (0)\n003 3 2c4e 2c16 2f23 | 15 2737 (0) 24f8 (0) 208e (0) 2220 (0)\n004 2 3baa 3ff8 | 10 398b (0) 38d7 (0) 3843 (0) 3ab2 (0)\n005 2 3607 3658 | 5 34e4 (0) 3799 (0) 3734 (0) 3607 (0)\n============ DEPTH: 6 ==========================================\n006 3 3085 3054 307c | 3 3085 (0) 3054 (0) 307c (0)\n007 1 3227 | 1 3227 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"0c14dd51a56130c51009e3ce47c96b2afef26b7e86cfca65d8a9bae1abef13b3a7a192b422d894c39e24ab00be412d166a3571cc259ff4462d4ad8925a153766","private_key":"ad02d38ce01c0291ad949b92338b10b0427a30de149df0a3c7457c2b2340a963","name":"node_0c14dd51a56130c51009e3ce47c96b2afef26b7e86cfca65d8a9bae1abef13b3a7a192b422d894c39e24ab00be412d166a3571cc259ff4462d4ad8925a153766","services":["streamer"],"enable_msg_events":true,"port":63250},"up":true}},{"node":{"info":{"id":"855bdf057f4a6b095e2000ada199447b5b4f2f8d78d2ecbaa0ff1fbf761788870ee999266ad3b26efa02be1a46a4d92ac0debb85a2ceab3442394ee7d99e5355","name":"node_855bdf057f4a6b095e2000ada199447b5b4f2f8d78d2ecbaa0ff1fbf761788870ee999266ad3b26efa02be1a46a4d92ac0debb85a2ceab3442394ee7d99e5355","enode":"enode://855bdf057f4a6b095e2000ada199447b5b4f2f8d78d2ecbaa0ff1fbf761788870ee999266ad3b26efa02be1a46a4d92ac0debb85a2ceab3442394ee7d99e5355@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"F1hzAFzYsNt9pDHMbMB3YVpceaiMRpihrmHzvqISmW8=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 175873\npopulation: 27 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 9bc3 8611 e9fa de1d | 134 ce71 (0) cf77 (0) c914 (0) c911 (0)\n001 8 581a 5b30 56bb 57ee | 50 7ec4 (0) 7e45 (0) 7810 (0) 7aef (0)\n002 5 2c4e 2f23 3ff8 3658 | 35 2737 (0) 24f8 (0) 208e (0) 2220 (0)\n003 1 0bc3 | 18 05a4 (0) 0536 (0) 07a6 (0) 00c8 (0)\n004 3 1fab 1dfd 1dfc | 10 1953 (0) 1af6 (0) 1a85 (0) 1a8e (0)\n005 1 1254 | 3 11a0 (0) 10b1 (0) 1254 (0)\n006 3 14e4 1587 15ec | 3 14e4 (0) 1587 (0) 15ec (0)\n============ DEPTH: 7 ==========================================\n007 1 167b | 1 167b (0)\n008 1 17a0 | 1 17a0 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"855bdf057f4a6b095e2000ada199447b5b4f2f8d78d2ecbaa0ff1fbf761788870ee999266ad3b26efa02be1a46a4d92ac0debb85a2ceab3442394ee7d99e5355","private_key":"5f33ccc756728e5919332381312dc8eb9f6009e9a407654eb70b995c12338ee7","name":"node_855bdf057f4a6b095e2000ada199447b5b4f2f8d78d2ecbaa0ff1fbf761788870ee999266ad3b26efa02be1a46a4d92ac0debb85a2ceab3442394ee7d99e5355","services":["streamer"],"enable_msg_events":true,"port":63251},"up":true}},{"node":{"info":{"id":"b53078000796f1cdb04dfeac424d5e3e37e30f00bd5bebf9a9ea0525c62917612b3a8f508df6bea59e3c7e4cd1aa530841f9a8af54e44f5617a13dee2c6ff007","name":"node_b53078000796f1cdb04dfeac424d5e3e37e30f00bd5bebf9a9ea0525c62917612b3a8f508df6bea59e3c7e4cd1aa530841f9a8af54e44f5617a13dee2c6ff007","enode":"enode://b53078000796f1cdb04dfeac424d5e3e37e30f00bd5bebf9a9ea0525c62917612b3a8f508df6bea59e3c7e4cd1aa530841f9a8af54e44f5617a13dee2c6ff007@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"Fez9Ds6dQ98csFvyzzGcnZVFV/PCafewzX8+22yJ5YE=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 15ecfd\npopulation: 34 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 6 9bc3 9b87 8611 8ea9 | 134 cf77 (0) ce71 (0) c911 (0) c914 (0)\n001 2 581a 43fb | 50 7e45 (0) 7ec4 (0) 7810 (0) 7aef (0)\n002 7 2f23 2c4e 2c16 3ff8 | 35 2737 (0) 24f8 (0) 208e (0) 2220 (0)\n003 5 07a6 0305 0020 0fa0 | 18 05a4 (0) 0536 (0) 07a6 (0) 00c8 (0)\n004 6 1a85 1a8e 1953 1dfd | 10 1953 (0) 1af6 (0) 1a8e (0) 1a85 (0)\n005 3 1254 10b1 11a0 | 3 11a0 (0) 10b1 (0) 1254 (0)\n006 3 167b 17a0 1758 | 3 167b (0) 17a0 (0) 1758 (0)\n============ DEPTH: 7 ==========================================\n007 1 14e4 | 1 14e4 (0)\n008 0 | 0\n009 1 1587 | 1 1587 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"b53078000796f1cdb04dfeac424d5e3e37e30f00bd5bebf9a9ea0525c62917612b3a8f508df6bea59e3c7e4cd1aa530841f9a8af54e44f5617a13dee2c6ff007","private_key":"7645086a0c4af854131d0ff4a95ef3a1d8ed9bb6620c934708a2b4f317c6f964","name":"node_b53078000796f1cdb04dfeac424d5e3e37e30f00bd5bebf9a9ea0525c62917612b3a8f508df6bea59e3c7e4cd1aa530841f9a8af54e44f5617a13dee2c6ff007","services":["streamer"],"enable_msg_events":true,"port":63252},"up":true}},{"node":{"info":{"id":"5526d86ba9df651091d88460a9bedb9cedb957d452a635e1db46b9fed78082022adec0047cd7485956a4ecbb0e18107595de0de3c35242527cd302bf74a19260","name":"node_5526d86ba9df651091d88460a9bedb9cedb957d452a635e1db46b9fed78082022adec0047cd7485956a4ecbb0e18107595de0de3c35242527cd302bf74a19260","enode":"enode://5526d86ba9df651091d88460a9bedb9cedb957d452a635e1db46b9fed78082022adec0047cd7485956a4ecbb0e18107595de0de3c35242527cd302bf74a19260@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"Nlic7LGC5F0+nzXiQF7ZqLzMRSAouQPTByjOCZMj/Vs=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 36589c\npopulation: 27 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 6 9b87 8ea9 b049 a1b6 | 134 b820 (0) bb31 (0) bbcb (0) baaf (0)\n001 2 581a 43fb | 50 6f1c (0) 6caa (0) 69d8 (0) 6923 (0)\n002 6 0305 0fa0 0a3f 0bc3 | 37 0536 (0) 05a4 (0) 07a6 (0) 00c8 (0)\n003 4 2c4e 2c16 2f1f 2f23 | 15 2737 (0) 24f8 (0) 208e (0) 2220 (0)\n004 3 3baa 3d17 3ff8 | 10 398b (0) 38d7 (0) 3843 (0) 3ab2 (0)\n005 2 307c 3388 | 5 3085 (0) 3054 (0) 307c (0) 3227 (0)\n006 1 34e4 | 1 34e4 (0)\n============ DEPTH: 7 ==========================================\n007 2 3799 3734 | 2 3799 (0) 3734 (0)\n008 0 | 0\n009 1 3607 | 1 3607 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"5526d86ba9df651091d88460a9bedb9cedb957d452a635e1db46b9fed78082022adec0047cd7485956a4ecbb0e18107595de0de3c35242527cd302bf74a19260","private_key":"96bc72358e15d649f871e17f6fbb7ddec911aaeb3b5bbd55929512756cee6a67","name":"node_5526d86ba9df651091d88460a9bedb9cedb957d452a635e1db46b9fed78082022adec0047cd7485956a4ecbb0e18107595de0de3c35242527cd302bf74a19260","services":["streamer"],"enable_msg_events":true,"port":63253},"up":true}},{"node":{"info":{"id":"a7378ee34876af17c6cd94a69b6b741ec7891ff5375bc4241d48608d047455ed48e6baae80ee88d4710c69ae615cf195cee26c94b54de1bb935628ce1e3a723a","name":"node_a7378ee34876af17c6cd94a69b6b741ec7891ff5375bc4241d48608d047455ed48e6baae80ee88d4710c69ae615cf195cee26c94b54de1bb935628ce1e3a723a","enode":"enode://a7378ee34876af17c6cd94a69b6b741ec7891ff5375bc4241d48608d047455ed48e6baae80ee88d4710c69ae615cf195cee26c94b54de1bb935628ce1e3a723a@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"3h0+RmoXGu9L1HtlRtJcEqHzEg8KX2jTd9wBNitAii4=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: de1d3e\npopulation: 24 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 1758 3658 | 122 7e45 (0) 7ec4 (0) 7810 (0) 7aef (0)\n001 9 9404 9f4c 9b87 8611 | 63 802e (0) 802f (0) 83d0 (0) 853b (0)\n002 2 e9fa ebe8 | 38 f6a6 (0) f0b8 (0) f054 (0) f1b9 (0)\n003 1 c409 | 14 cf77 (0) ce71 (0) c95a (0) c911 (0)\n004 6 d717 d3bd d2ac d1bc | 14 d455 (0) d560 (0) d66f (0) d606 (0)\n============ DEPTH: 5 ==========================================\n005 3 d90b d96e dad3 | 3 dad3 (0) d90b (0) d96e (0)\n006 0 | 0\n007 1 df52 | 1 df52 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"a7378ee34876af17c6cd94a69b6b741ec7891ff5375bc4241d48608d047455ed48e6baae80ee88d4710c69ae615cf195cee26c94b54de1bb935628ce1e3a723a","private_key":"3348eec47933810a23d583715b1a18b2a8332e8cd45bdc57bcc5232c6b5c0164","name":"node_a7378ee34876af17c6cd94a69b6b741ec7891ff5375bc4241d48608d047455ed48e6baae80ee88d4710c69ae615cf195cee26c94b54de1bb935628ce1e3a723a","services":["streamer"],"enable_msg_events":true,"port":63254},"up":true}},{"node":{"info":{"id":"3e488a7208ce0e097ce47fc6651a13e95cae137d1a054a09b04d2f59d45faa2594a8c3b395e77ad1a3c2edcd827dda73c0c97dbaa6d9519a79184a0aca01ac4b","name":"node_3e488a7208ce0e097ce47fc6651a13e95cae137d1a054a09b04d2f59d45faa2594a8c3b395e77ad1a3c2edcd827dda73c0c97dbaa6d9519a79184a0aca01ac4b","enode":"enode://3e488a7208ce0e097ce47fc6651a13e95cae137d1a054a09b04d2f59d45faa2594a8c3b395e77ad1a3c2edcd827dda73c0c97dbaa6d9519a79184a0aca01ac4b@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"obahqYlFX58ZVSdqCztbTBlyas+Po/chj6tCADb6mI8=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: a1b6a1\npopulation: 28 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 15ec 3ff8 3658 | 122 76a5 (0) 77bc (0) 71bf (0) 715b (0)\n001 2 ebe8 de1d | 71 f6a6 (0) f2f5 (0) f293 (0) f2b2 (0)\n002 8 8434 8611 89ef 8ea9 | 33 802f (0) 802e (0) 83d0 (0) 853b (0)\n003 3 baaf b391 b049 | 13 bd39 (0) beb7 (0) bf6b (0) b820 (0)\n004 2 a9df a936 | 5 af8f (0) ac62 (0) aa78 (0) a936 (0)\n005 3 a6bd a75d a478 | 3 a478 (0) a75d (0) a6bd (0)\n006 2 a317 a3f2 | 2 a317 (0) a3f2 (0)\n007 3 a077 a0e4 a0c9 | 4 a077 (0) a011 (0) a0e4 (0) a0c9 (0)\n============ DEPTH: 8 ==========================================\n008 1 a105 | 1 a105 (0)\n009 1 a1f1 | 1 a1f1 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"3e488a7208ce0e097ce47fc6651a13e95cae137d1a054a09b04d2f59d45faa2594a8c3b395e77ad1a3c2edcd827dda73c0c97dbaa6d9519a79184a0aca01ac4b","private_key":"553bb09d30fcd504ead604d830aeb0e3d0a5edfa58c94ec3da1508184f7c059c","name":"node_3e488a7208ce0e097ce47fc6651a13e95cae137d1a054a09b04d2f59d45faa2594a8c3b395e77ad1a3c2edcd827dda73c0c97dbaa6d9519a79184a0aca01ac4b","services":["streamer"],"enable_msg_events":true,"port":63255},"up":true}},{"node":{"info":{"id":"07f25fdeab2b44b2e92fc80fca7de9e4a8547d27a98a54593b3395c270a9ff3f2a5da62a2e8531ce86359f0cdc5b6513b773dfd64cce1b83e47065d9760a2c7e","name":"node_07f25fdeab2b44b2e92fc80fca7de9e4a8547d27a98a54593b3395c270a9ff3f2a5da62a2e8531ce86359f0cdc5b6513b773dfd64cce1b83e47065d9760a2c7e","enode":"enode://07f25fdeab2b44b2e92fc80fca7de9e4a8547d27a98a54593b3395c270a9ff3f2a5da62a2e8531ce86359f0cdc5b6513b773dfd64cce1b83e47065d9760a2c7e@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"m4f91NlrgiYwA8kDRvwJcAj/aBvSRiJ6Ne/ztDHWNC4=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 9b87fd\npopulation: 24 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 43fb 3658 3ff8 15ec | 122 7e45 (0) 7ec4 (0) 7810 (0) 7aef (0)\n001 1 de1d | 71 f6a6 (0) f1b9 (0) f1ad (0) f054 (0)\n002 3 baaf a0c9 a1b6 | 30 bd39 (0) beb7 (0) bf6b (0) b820 (0)\n003 5 8434 8611 89ef 8a54 | 15 802f (0) 802e (0) 83d0 (0) 853b (0)\n004 2 9493 910d | 8 9747 (0) 9641 (0) 9404 (0) 9493 (0)\n005 1 9f4c | 1 9f4c (0)\n006 6 9918 9929 99eb 985f | 6 99eb (0) 9929 (0) 9918 (0) 98aa (0)\n============ DEPTH: 7 ==========================================\n007 1 9a09 | 1 9a09 (0)\n008 0 | 0\n009 1 9bc3 | 1 9bc3 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"07f25fdeab2b44b2e92fc80fca7de9e4a8547d27a98a54593b3395c270a9ff3f2a5da62a2e8531ce86359f0cdc5b6513b773dfd64cce1b83e47065d9760a2c7e","private_key":"60b600c6cca2712771a98d797a46fbeb7be68a054d94d8eaabb8ecac6d3520a2","name":"node_07f25fdeab2b44b2e92fc80fca7de9e4a8547d27a98a54593b3395c270a9ff3f2a5da62a2e8531ce86359f0cdc5b6513b773dfd64cce1b83e47065d9760a2c7e","services":["streamer"],"enable_msg_events":true,"port":63256},"up":true}},{"node":{"info":{"id":"0f9f7e2dce4ca266c3ac0ec3a8854200b54487f5308e3db418461aeb5f67c81d332619b6441b468e480941e63100ed1b263e7adc20689dc3dcda578bfca538fa","name":"node_0f9f7e2dce4ca266c3ac0ec3a8854200b54487f5308e3db418461aeb5f67c81d332619b6441b468e480941e63100ed1b263e7adc20689dc3dcda578bfca538fa","enode":"enode://0f9f7e2dce4ca266c3ac0ec3a8854200b54487f5308e3db418461aeb5f67c81d332619b6441b468e480941e63100ed1b263e7adc20689dc3dcda578bfca538fa@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"oMmPcsq6XLekAJk3/5SbdFsjMO2LGnHOcPTlnVBFlEk=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: a0c98f\npopulation: 25 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 43fb 3658 | 122 7e45 (0) 7ec4 (0) 7810 (0) 7aef (0)\n001 2 ebe8 de1d | 71 f6a6 (0) f2f5 (0) f2b2 (0) f293 (0)\n002 6 9f4c 9b87 8434 8611 | 33 92d5 (0) 93f8 (0) 9108 (0) 910d (0)\n003 3 baaf b391 b049 | 13 bd39 (0) bf6b (0) beb7 (0) b820 (0)\n004 2 a9df a936 | 5 ac62 (0) af8f (0) aa78 (0) a936 (0)\n005 3 a6bd a75d a478 | 3 a478 (0) a75d (0) a6bd (0)\n006 2 a317 a3f2 | 2 a317 (0) a3f2 (0)\n007 2 a105 a1b6 | 3 a105 (0) a1f1 (0) a1b6 (0)\n============ DEPTH: 8 ==========================================\n008 2 a077 a011 | 2 a077 (0) a011 (0)\n009 0 | 0\n010 1 a0e4 | 1 a0e4 (0)\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"0f9f7e2dce4ca266c3ac0ec3a8854200b54487f5308e3db418461aeb5f67c81d332619b6441b468e480941e63100ed1b263e7adc20689dc3dcda578bfca538fa","private_key":"4bb86dfcc439dc83032e6189165d986a8f315558aa7fe1b6bb2f91e521a837b8","name":"node_0f9f7e2dce4ca266c3ac0ec3a8854200b54487f5308e3db418461aeb5f67c81d332619b6441b468e480941e63100ed1b263e7adc20689dc3dcda578bfca538fa","services":["streamer"],"enable_msg_events":true,"port":63257},"up":true}},{"node":{"info":{"id":"a1560ce7c1f1d5972f027a8e9cff820611d84764aa067434a75b63887bc4268a259101486d34b7fe83dd735e799789986cd3e9b156c86ede598bd86af4454924","name":"node_a1560ce7c1f1d5972f027a8e9cff820611d84764aa067434a75b63887bc4268a259101486d34b7fe83dd735e799789986cd3e9b156c86ede598bd86af4454924","enode":"enode://a1560ce7c1f1d5972f027a8e9cff820611d84764aa067434a75b63887bc4268a259101486d34b7fe83dd735e799789986cd3e9b156c86ede598bd86af4454924@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"jql/ar1A1wcXaIxd042vb2sSAF3yGuOX37cA+/40R6w=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 8ea97f\npopulation: 18 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 15ec 3658 | 122 7ec4 (0) 7e45 (0) 7810 (0) 7aef (0)\n001 1 de1d | 71 f6a6 (0) f2f5 (0) f2b2 (0) f293 (0)\n002 3 baaf a1b6 a0c9 | 30 bd39 (0) beb7 (0) bf6b (0) b820 (0)\n003 5 9493 9f4c 985f 9a09 | 18 92d5 (0) 93f8 (0) 9108 (0) 910d (0)\n004 2 8434 8611 | 8 802f (0) 802e (0) 83d0 (0) 853b (0)\n005 2 89ef 8a54 | 3 89ef (0) 8ae8 (0) 8a54 (0)\n============ DEPTH: 6 ==========================================\n006 2 8d85 8d3c | 2 8d3c (0) 8d85 (0)\n007 0 | 0\n008 0 | 0\n009 1 8ee7 | 1 8ee7 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"a1560ce7c1f1d5972f027a8e9cff820611d84764aa067434a75b63887bc4268a259101486d34b7fe83dd735e799789986cd3e9b156c86ede598bd86af4454924","private_key":"ff9eae2bb1fe93a164f54d3ac907b4c4ec79fa41eece5a44aeb70c083ad80ce6","name":"node_a1560ce7c1f1d5972f027a8e9cff820611d84764aa067434a75b63887bc4268a259101486d34b7fe83dd735e799789986cd3e9b156c86ede598bd86af4454924","services":["streamer"],"enable_msg_events":true,"port":63258},"up":true}},{"node":{"info":{"id":"e06a789a7f6988e1ba5e8358b6cd4292555c7f9f7f0dda6fc01cc26d24e49a8c1ad694423ad74aec6d80f4b99e2bedc49b6a5f2670744cedee3a3e1848e6dd07","name":"node_e06a789a7f6988e1ba5e8358b6cd4292555c7f9f7f0dda6fc01cc26d24e49a8c1ad694423ad74aec6d80f4b99e2bedc49b6a5f2670744cedee3a3e1848e6dd07","enode":"enode://e06a789a7f6988e1ba5e8358b6cd4292555c7f9f7f0dda6fc01cc26d24e49a8c1ad694423ad74aec6d80f4b99e2bedc49b6a5f2670744cedee3a3e1848e6dd07@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"hhE/in1DBP/hWMzA6Ur5GUzduydgTMwI3Srb6ph4vi8=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 86113f\npopulation: 25 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 7 581a 3ff8 2f23 15ec | 122 7ec4 (0) 7e45 (0) 7810 (0) 7aef (0)\n001 1 de1d | 71 f6a6 (0) f2f5 (0) f2b2 (0) f293 (0)\n002 3 baaf a0c9 a1b6 | 30 bd39 (0) beb7 (0) bf6b (0) b820 (0)\n003 3 985f 9b87 9f4c | 18 92d5 (0) 93f8 (0) 9108 (0) 910d (0)\n004 4 89ef 8a54 8d85 8ea9 | 7 89ef (0) 8ae8 (0) 8a54 (0) 8d3c (0)\n005 3 802e 802f 83d0 | 3 802e (0) 802f (0) 83d0 (0)\n============ DEPTH: 6 ==========================================\n006 3 853b 8564 8434 | 3 853b (0) 8564 (0) 8434 (0)\n007 0 | 0\n008 1 86d3 | 1 86d3 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"e06a789a7f6988e1ba5e8358b6cd4292555c7f9f7f0dda6fc01cc26d24e49a8c1ad694423ad74aec6d80f4b99e2bedc49b6a5f2670744cedee3a3e1848e6dd07","private_key":"f23f43541bab9bd56083d663c140d382c5a9461060c285f1c1b1c6621d8e2e1b","name":"node_e06a789a7f6988e1ba5e8358b6cd4292555c7f9f7f0dda6fc01cc26d24e49a8c1ad694423ad74aec6d80f4b99e2bedc49b6a5f2670744cedee3a3e1848e6dd07","services":["streamer"],"enable_msg_events":true,"port":63259},"up":true}},{"node":{"info":{"id":"57b47f692f4d69a5d2c9c193680eb4ccb5a6c574662df0138504a549f3ea74f20c5b866ac4d9e76c4b49c83f5fd692ead928ea20dfcf643a11a1c1e841c0ec42","name":"node_57b47f692f4d69a5d2c9c193680eb4ccb5a6c574662df0138504a549f3ea74f20c5b866ac4d9e76c4b49c83f5fd692ead928ea20dfcf643a11a1c1e841c0ec42","enode":"enode://57b47f692f4d69a5d2c9c193680eb4ccb5a6c574662df0138504a549f3ea74f20c5b866ac4d9e76c4b49c83f5fd692ead928ea20dfcf643a11a1c1e841c0ec42@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"ACB2jZb8oM9HqWMsol/3lMmWBC8HpyQux8cPvHXg5F4=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 002076\npopulation: 17 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 9f4c 8611 | 134 f1ad (0) f1b9 (0) f054 (0) f0b8 (0)\n001 1 581a | 50 71bf (0) 715b (0) 7239 (0) 7299 (0)\n002 2 2e3b 3607 | 35 2737 (0) 24f8 (0) 208e (0) 2220 (0)\n003 3 1ea1 1dfc 15ec | 19 1953 (0) 1af6 (0) 1a8e (0) 1a85 (0)\n004 5 0ca9 0fa0 09d1 0bc3 | 11 0daf (0) 0d97 (0) 0c72 (0) 0c19 (0)\n005 1 07a6 | 3 05a4 (0) 0536 (0) 07a6 (0)\n============ DEPTH: 6 ==========================================\n006 2 020f 0305 | 2 020f (0) 0305 (0)\n007 0 | 0\n008 1 00c8 | 1 00c8 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"57b47f692f4d69a5d2c9c193680eb4ccb5a6c574662df0138504a549f3ea74f20c5b866ac4d9e76c4b49c83f5fd692ead928ea20dfcf643a11a1c1e841c0ec42","private_key":"e3853d7bcb9111bc645eaaec38093b38a0b16e80774deb42bbf5431e78e9ae9a","name":"node_57b47f692f4d69a5d2c9c193680eb4ccb5a6c574662df0138504a549f3ea74f20c5b866ac4d9e76c4b49c83f5fd692ead928ea20dfcf643a11a1c1e841c0ec42","services":["streamer"],"enable_msg_events":true,"port":63260},"up":true}},{"node":{"info":{"id":"2ddd49fae11d8bd2e7e75a481be267fa846f51cc1160bc326aeea51c542323ff444909de11e2731e835140bc0b1b32020e1e73fa652511a381222bf0aebc4081","name":"node_2ddd49fae11d8bd2e7e75a481be267fa846f51cc1160bc326aeea51c542323ff444909de11e2731e835140bc0b1b32020e1e73fa652511a381222bf0aebc4081","enode":"enode://2ddd49fae11d8bd2e7e75a481be267fa846f51cc1160bc326aeea51c542323ff444909de11e2731e835140bc0b1b32020e1e73fa652511a381222bf0aebc4081@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"WBq53w0QnZQpEzG2jLv4vHANlpsvnkPQcX+I9UCfuBU=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 581ab9\npopulation: 22 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 8611 9f4c | 134 cf77 (0) ce71 (0) c95a (0) c914 (0)\n001 9 2f23 3ff8 3658 1758 | 72 2737 (0) 24f8 (0) 208e (0) 2220 (0)\n002 1 65a6 | 19 7e45 (0) 7ec4 (0) 7810 (0) 7aef (0)\n003 2 4bbc 43fb | 16 4dc4 (0) 4c97 (0) 48ec (0) 48df (0)\n004 3 5062 5070 56bb | 9 5237 (0) 5399 (0) 5070 (0) 5062 (0)\n005 3 5e3e 5c9b 5cae | 3 5e3e (0) 5cae (0) 5c9b (0)\n============ DEPTH: 6 ==========================================\n006 2 5b30 5a67 | 2 5b30 (0) 5a67 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"2ddd49fae11d8bd2e7e75a481be267fa846f51cc1160bc326aeea51c542323ff444909de11e2731e835140bc0b1b32020e1e73fa652511a381222bf0aebc4081","private_key":"cf8c79a1a70472ac10e1dcd59e8a498cce13cc78f13a28a1b31ef8070e8201af","name":"node_2ddd49fae11d8bd2e7e75a481be267fa846f51cc1160bc326aeea51c542323ff444909de11e2731e835140bc0b1b32020e1e73fa652511a381222bf0aebc4081","services":["streamer"],"enable_msg_events":true,"port":63261},"up":true}},{"node":{"info":{"id":"420b9c90584651c5a3fe3c16aa377444a321dca934f8a097d01a616554067feabebf2fdc8d2a25797f29a8fef30d5e2c82f8e85b20f509a880367b9b0ccdea47","name":"node_420b9c90584651c5a3fe3c16aa377444a321dca934f8a097d01a616554067feabebf2fdc8d2a25797f29a8fef30d5e2c82f8e85b20f509a880367b9b0ccdea47","enode":"enode://420b9c90584651c5a3fe3c16aa377444a321dca934f8a097d01a616554067feabebf2fdc8d2a25797f29a8fef30d5e2c82f8e85b20f509a880367b9b0ccdea47@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"n0wuexyAF1qdfYXJg9nuQG5de6ZEsPjoUZbIvHy8v3E=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 9f4c2e\npopulation: 29 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 8 3607 020f 0305 0020 | 122 2737 (0) 24f8 (0) 208e (0) 2220 (0)\n001 1 de1d | 71 f6a6 (0) f1b9 (0) f1ad (0) f0b8 (0)\n002 3 a1b6 a0c9 baaf | 30 ac62 (0) af8f (0) aa78 (0) a936 (0)\n003 4 89ef 8ea9 8434 8611 | 15 89ef (0) 8ae8 (0) 8a54 (0) 8d3c (0)\n004 4 92d5 910d 9641 9493 | 8 93f8 (0) 92d5 (0) 9108 (0) 910d (0)\n============ DEPTH: 5 ==========================================\n005 9 99eb 9929 9918 985f | 9 99eb (0) 9929 (0) 9918 (0) 98bc (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"420b9c90584651c5a3fe3c16aa377444a321dca934f8a097d01a616554067feabebf2fdc8d2a25797f29a8fef30d5e2c82f8e85b20f509a880367b9b0ccdea47","private_key":"872f89492c87094f84d4db636ac19e5c87ac57cce008931d2db6d7aca72dc552","name":"node_420b9c90584651c5a3fe3c16aa377444a321dca934f8a097d01a616554067feabebf2fdc8d2a25797f29a8fef30d5e2c82f8e85b20f509a880367b9b0ccdea47","services":["streamer"],"enable_msg_events":true,"port":63262},"up":true}},{"node":{"info":{"id":"5bf29c02f07faf7ae8e46389e1b98df4f5e88c9316b5151685e6ae7b4e622cf171ff09f996aaa8ad846643b3bfcbd1ad96cdc249afccce439bb5c55246b95801","name":"node_5bf29c02f07faf7ae8e46389e1b98df4f5e88c9316b5151685e6ae7b4e622cf171ff09f996aaa8ad846643b3bfcbd1ad96cdc249afccce439bb5c55246b95801","enode":"enode://5bf29c02f07faf7ae8e46389e1b98df4f5e88c9316b5151685e6ae7b4e622cf171ff09f996aaa8ad846643b3bfcbd1ad96cdc249afccce439bb5c55246b95801@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"B6aHPH6ttlEZanarMCQcwcmEVJxQhvHDuxvnvUkzRr4=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 07a687\npopulation: 16 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 baaf 9f4c | 134 cf77 (0) ce71 (0) c95a (0) c914 (0)\n001 3 7299 43fb 581a | 50 7e45 (0) 7ec4 (0) 7810 (0) 7aef (0)\n002 1 3607 | 35 2737 (0) 24f8 (0) 208e (0) 2220 (0)\n003 2 15ec 1dfc | 19 11a0 (0) 10b1 (0) 1254 (0) 167b (0)\n004 2 0a3f 0ca9 | 11 0daf (0) 0d97 (0) 0c72 (0) 0c19 (0)\n005 4 00c8 0020 0305 020f | 4 00c8 (0) 0020 (0) 0305 (0) 020f (0)\n============ DEPTH: 6 ==========================================\n006 2 05a4 0536 | 2 05a4 (0) 0536 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"5bf29c02f07faf7ae8e46389e1b98df4f5e88c9316b5151685e6ae7b4e622cf171ff09f996aaa8ad846643b3bfcbd1ad96cdc249afccce439bb5c55246b95801","private_key":"9c7cd9b75a3b821c0ec74e08d8727fa6ce5aa184479038762b1ae4f3c07b3782","name":"node_5bf29c02f07faf7ae8e46389e1b98df4f5e88c9316b5151685e6ae7b4e622cf171ff09f996aaa8ad846643b3bfcbd1ad96cdc249afccce439bb5c55246b95801","services":["streamer"],"enable_msg_events":true,"port":63263},"up":true}},{"node":{"info":{"id":"e3c8a97a2d95dd543f9e2b41d9dce6256e284296f866f4f92e9925f8c7519dea23fd6d1a11153b93c10d6a32295e7b9bcc16024e690e4a0dc84fd25ee0f31b2c","name":"node_e3c8a97a2d95dd543f9e2b41d9dce6256e284296f866f4f92e9925f8c7519dea23fd6d1a11153b93c10d6a32295e7b9bcc16024e690e4a0dc84fd25ee0f31b2c","enode":"enode://e3c8a97a2d95dd543f9e2b41d9dce6256e284296f866f4f92e9925f8c7519dea23fd6d1a11153b93c10d6a32295e7b9bcc16024e690e4a0dc84fd25ee0f31b2c@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"Ag9Xw2m2UhVS90mORErtIaxXgy7T/6p7RfYHeT6hqGw=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 020f57\npopulation: 15 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 9f4c | 134 cf77 (0) ce71 (0) c95a (0) c914 (0)\n001 4 77bc 65a6 43fb 4bbc | 50 7e45 (0) 7ec4 (0) 7810 (0) 7aef (0)\n002 2 2e3b 3607 | 35 2737 (0) 24f8 (0) 208e (0) 2220 (0)\n003 2 1ea1 1dfc | 19 11a0 (0) 10b1 (0) 1254 (0) 167b (0)\n004 2 0a3f 0daf | 11 0daf (0) 0d97 (0) 0c72 (0) 0c19 (0)\n005 1 07a6 | 3 05a4 (0) 0536 (0) 07a6 (0)\n============ DEPTH: 6 ==========================================\n006 2 00c8 0020 | 2 00c8 (0) 0020 (0)\n007 1 0305 | 1 0305 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"e3c8a97a2d95dd543f9e2b41d9dce6256e284296f866f4f92e9925f8c7519dea23fd6d1a11153b93c10d6a32295e7b9bcc16024e690e4a0dc84fd25ee0f31b2c","private_key":"ea03297fa8e550df89d0595b3026c5367bd7b0076c7a9fd5c6071f0944373202","name":"node_e3c8a97a2d95dd543f9e2b41d9dce6256e284296f866f4f92e9925f8c7519dea23fd6d1a11153b93c10d6a32295e7b9bcc16024e690e4a0dc84fd25ee0f31b2c","services":["streamer"],"enable_msg_events":true,"port":63264},"up":true}},{"node":{"info":{"id":"7aaf7817b93aa6d2f50513791f9ad7629a901ed0dcb151189f44763f83423446b20ec79a48fa260cd9bc2907d5f0ad06b2c4c5e6d812f3d8876c8020ebe41019","name":"node_7aaf7817b93aa6d2f50513791f9ad7629a901ed0dcb151189f44763f83423446b20ec79a48fa260cd9bc2907d5f0ad06b2c4c5e6d812f3d8876c8020ebe41019","enode":"enode://7aaf7817b93aa6d2f50513791f9ad7629a901ed0dcb151189f44763f83423446b20ec79a48fa260cd9bc2907d5f0ad06b2c4c5e6d812f3d8876c8020ebe41019@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"NgcLUimQbAEPPXVsa5UB+AdX/bomHjjqKilLUEf2dzk=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 36070b\npopulation: 27 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 910d 9f4c baaf | 134 c301 (0) c3d8 (0) c7fa (0) c60e (0)\n001 4 77bc 65a6 4bbc 43fb | 50 7e45 (0) 7ec4 (0) 7810 (0) 7aef (0)\n002 6 1dfc 0a3f 07a6 0020 | 37 11a0 (0) 10b1 (0) 1254 (0) 167b (0)\n003 2 2f23 2c4e | 15 2737 (0) 24f8 (0) 208e (0) 2220 (0)\n004 5 38d7 3843 3d17 3ef6 | 10 3baa (0) 3ab2 (0) 3a18 (0) 398b (0)\n005 3 3085 3227 3388 | 5 3085 (0) 3054 (0) 307c (0) 3227 (0)\n006 1 34e4 | 1 34e4 (0)\n============ DEPTH: 7 ==========================================\n007 2 3734 3799 | 2 3734 (0) 3799 (0)\n008 0 | 0\n009 1 3658 | 1 3658 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"7aaf7817b93aa6d2f50513791f9ad7629a901ed0dcb151189f44763f83423446b20ec79a48fa260cd9bc2907d5f0ad06b2c4c5e6d812f3d8876c8020ebe41019","private_key":"dc424f98922ec5d19a5a8d5ee2acaf077778ed0fd92db276f88bda3cc4fdb5a6","name":"node_7aaf7817b93aa6d2f50513791f9ad7629a901ed0dcb151189f44763f83423446b20ec79a48fa260cd9bc2907d5f0ad06b2c4c5e6d812f3d8876c8020ebe41019","services":["streamer"],"enable_msg_events":true,"port":63265},"up":true}},{"node":{"info":{"id":"062e0ca43a1885c4a7ab2a5169790f9081e3e9a2dfa286b8cc592d5ccbf13d7a82b72d23361a19026d04fcf41b752ea320d98359d770aedfcee626e21c3494b3","name":"node_062e0ca43a1885c4a7ab2a5169790f9081e3e9a2dfa286b8cc592d5ccbf13d7a82b72d23361a19026d04fcf41b752ea320d98359d770aedfcee626e21c3494b3","enode":"enode://062e0ca43a1885c4a7ab2a5169790f9081e3e9a2dfa286b8cc592d5ccbf13d7a82b72d23361a19026d04fcf41b752ea320d98359d770aedfcee626e21c3494b3@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"AwWQd9P632J5R1b2lH/DLtANghYtvj5uvNMpUr1CEyE=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 030590\npopulation: 21 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 9f4c 8611 baaf | 134 cf77 (0) ce71 (0) c95a (0) c914 (0)\n001 5 77bc 65a6 581a 43fb | 50 7e45 (0) 7ec4 (0) 7810 (0) 7aef (0)\n002 3 3388 3658 3607 | 35 2737 (0) 24f8 (0) 208e (0) 2220 (0)\n003 2 15ec 1dfc | 19 11a0 (0) 10b1 (0) 1254 (0) 167b (0)\n004 4 0ca9 0fa0 0bc3 0a3f | 11 0daf (0) 0d97 (0) 0c72 (0) 0c19 (0)\n005 1 07a6 | 3 05a4 (0) 0536 (0) 07a6 (0)\n============ DEPTH: 6 ==========================================\n006 2 00c8 0020 | 2 00c8 (0) 0020 (0)\n007 1 020f | 1 020f (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"062e0ca43a1885c4a7ab2a5169790f9081e3e9a2dfa286b8cc592d5ccbf13d7a82b72d23361a19026d04fcf41b752ea320d98359d770aedfcee626e21c3494b3","private_key":"baad13cad07e0edde7209f5e70451c82d07d1c4d4bd5ad6f85acefd48d14a253","name":"node_062e0ca43a1885c4a7ab2a5169790f9081e3e9a2dfa286b8cc592d5ccbf13d7a82b72d23361a19026d04fcf41b752ea320d98359d770aedfcee626e21c3494b3","services":["streamer"],"enable_msg_events":true,"port":63266},"up":true}},{"node":{"info":{"id":"f9ffe87c52ff4c22bd9696af32e0a9d34bb81fb84d9d8bf5aafe2ef9696e7b3d6460bf2a93aecb066133f53416bde841a02d6967bd06e3d4a714f3b2c123a947","name":"node_f9ffe87c52ff4c22bd9696af32e0a9d34bb81fb84d9d8bf5aafe2ef9696e7b3d6460bf2a93aecb066133f53416bde841a02d6967bd06e3d4a714f3b2c123a947","enode":"enode://f9ffe87c52ff4c22bd9696af32e0a9d34bb81fb84d9d8bf5aafe2ef9696e7b3d6460bf2a93aecb066133f53416bde841a02d6967bd06e3d4a714f3b2c123a947@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"uq/Q1dA+UHI0Hp4+abjEgEHNapyj2lahpJNAhNtuIr0=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: baafd0\npopulation: 31 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 7 3607 1dfc 07a6 0305 | 122 2737 (0) 24f8 (0) 208e (0) 2220 (0)\n001 5 de1d ebe8 e190 fd44 | 71 cf77 (0) ce71 (0) c914 (0) c911 (0)\n002 9 89ef 8ea9 8434 8611 | 33 802e (0) 802f (0) 83d0 (0) 853b (0)\n003 2 a0c9 a1b6 | 17 af8f (0) ac62 (0) aa78 (0) a936 (0)\n004 2 b391 b049 | 6 b40d (0) b45f (0) b7aa (0) b30e (0)\n005 3 bf6b beb7 bd39 | 3 bd39 (0) beb7 (0) bf6b (0)\n006 1 b820 | 1 b820 (0)\n============ DEPTH: 7 ==========================================\n007 2 bb31 bbcb | 2 bb31 (0) bbcb (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"f9ffe87c52ff4c22bd9696af32e0a9d34bb81fb84d9d8bf5aafe2ef9696e7b3d6460bf2a93aecb066133f53416bde841a02d6967bd06e3d4a714f3b2c123a947","private_key":"613f528e83e5bfe55db16791b917891c139ea8ab7599058a204c7836f71feb95","name":"node_f9ffe87c52ff4c22bd9696af32e0a9d34bb81fb84d9d8bf5aafe2ef9696e7b3d6460bf2a93aecb066133f53416bde841a02d6967bd06e3d4a714f3b2c123a947","services":["streamer"],"enable_msg_events":true,"port":63267},"up":true}},{"node":{"info":{"id":"bcf8e831821a5bca359fb824c7dc4d66906de82f3663a0a853d96880a8ca0bdddcceb1b66dd1f13f75ee20fde50fc9de545bc25767f228baee910e0dbfa8cc27","name":"node_bcf8e831821a5bca359fb824c7dc4d66906de82f3663a0a853d96880a8ca0bdddcceb1b66dd1f13f75ee20fde50fc9de545bc25767f228baee910e0dbfa8cc27","enode":"enode://bcf8e831821a5bca359fb824c7dc4d66906de82f3663a0a853d96880a8ca0bdddcceb1b66dd1f13f75ee20fde50fc9de545bc25767f228baee910e0dbfa8cc27@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"Q/u++n7V+ztJbBJr9Up3t8xltAxn+sv5YF+vvk4Dl60=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 43fbbe\npopulation: 30 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 9b87 9f4c a0c9 baaf | 134 cf77 (0) ce71 (0) c95a (0) c911 (0)\n001 11 2f23 3ff8 3388 3658 | 72 2737 (0) 24f8 (0) 208e (0) 2220 (0)\n002 1 65a6 | 19 7e45 (0) 7ec4 (0) 7810 (0) 7aef (0)\n003 6 5062 5399 57ee 56bb | 15 5237 (0) 5399 (0) 5070 (0) 5062 (0)\n004 1 4bbc | 8 4dc4 (0) 4c97 (0) 48ec (0) 48df (0)\n005 4 464b 47a8 44c8 44b7 | 4 464b (0) 47a8 (0) 44c8 (0) 44b7 (0)\n============ DEPTH: 6 ==========================================\n006 2 413b 41b2 | 2 413b (0) 41b2 (0)\n007 1 42d6 | 1 42d6 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"bcf8e831821a5bca359fb824c7dc4d66906de82f3663a0a853d96880a8ca0bdddcceb1b66dd1f13f75ee20fde50fc9de545bc25767f228baee910e0dbfa8cc27","private_key":"873d0f70715479bbed36c4b74c9391b723fce386d150bbbd613d33eaf08cf257","name":"node_bcf8e831821a5bca359fb824c7dc4d66906de82f3663a0a853d96880a8ca0bdddcceb1b66dd1f13f75ee20fde50fc9de545bc25767f228baee910e0dbfa8cc27","services":["streamer"],"enable_msg_events":true,"port":63268},"up":true}},{"node":{"info":{"id":"3d2df188704eeac09c8b291bf275a73888199a231c832c51dbc3d746968d4b51a7d5eae0c7c9b8c8e19f5e28d38c375e01abefa343f31dbe221deb837ab8a0df","name":"node_3d2df188704eeac09c8b291bf275a73888199a231c832c51dbc3d746968d4b51a7d5eae0c7c9b8c8e19f5e28d38c375e01abefa343f31dbe221deb837ab8a0df","enode":"enode://3d2df188704eeac09c8b291bf275a73888199a231c832c51dbc3d746968d4b51a7d5eae0c7c9b8c8e19f5e28d38c375e01abefa343f31dbe221deb837ab8a0df@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"S7wolUb9et6LIU2qToojE5qF1+RtcKVXAlM59vu+6H4=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 4bbc28\npopulation: 27 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 9f4c baaf | 134 cf77 (0) ce71 (0) c95a (0) c911 (0)\n001 7 2f23 3ff8 3607 020f | 72 2737 (0) 24f8 (0) 208e (0) 2220 (0)\n002 1 65a6 | 19 7e45 (0) 7ec4 (0) 7810 (0) 7aef (0)\n003 5 5237 57ee 56bb 5a67 | 15 5237 (0) 5399 (0) 5070 (0) 5062 (0)\n004 5 44b7 44c8 47a8 42d6 | 8 464b (0) 47a8 (0) 44c8 (0) 44b7 (0)\n005 2 4dc4 4c97 | 2 4dc4 (0) 4c97 (0)\n006 2 48ec 48df | 2 48ec (0) 48df (0)\n007 0 | 0\n008 1 4b70 | 1 4b70 (0)\n============ DEPTH: 9 ==========================================\n009 1 4bf8 | 1 4bf8 (0)\n010 1 4b8a | 1 4b8a (0)\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"3d2df188704eeac09c8b291bf275a73888199a231c832c51dbc3d746968d4b51a7d5eae0c7c9b8c8e19f5e28d38c375e01abefa343f31dbe221deb837ab8a0df","private_key":"48e7cd643d45488597f25de324e8b7553c26e1cf8e8d44261d610ee9041c898d","name":"node_3d2df188704eeac09c8b291bf275a73888199a231c832c51dbc3d746968d4b51a7d5eae0c7c9b8c8e19f5e28d38c375e01abefa343f31dbe221deb837ab8a0df","services":["streamer"],"enable_msg_events":true,"port":63269},"up":true}},{"node":{"info":{"id":"8f88c7ec044f758f29bd8d12a5170bd973aec8f6cddbf512b910c4b75a0fec09c5e198bcd65622037f897759db68da2328b4a7ca93585dc9cb62e46d2a6c0864","name":"node_8f88c7ec044f758f29bd8d12a5170bd973aec8f6cddbf512b910c4b75a0fec09c5e198bcd65622037f897759db68da2328b4a7ca93585dc9cb62e46d2a6c0864","enode":"enode://8f88c7ec044f758f29bd8d12a5170bd973aec8f6cddbf512b910c4b75a0fec09c5e198bcd65622037f897759db68da2328b4a7ca93585dc9cb62e46d2a6c0864@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"ZaZwJgr084YDdX+6kEzeXcjx0yQK1exryjFTpL68FHo=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 65a670\npopulation: 23 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 ebe8 985f baaf | 134 802e (0) 802f (0) 83d0 (0) 853b (0)\n001 6 2f23 3607 0305 020f | 72 2737 (0) 24f8 (0) 208e (0) 2220 (0)\n002 5 5a67 581a 43fb 4c97 | 31 5237 (0) 5399 (0) 5070 (0) 5062 (0)\n003 3 7299 77bc 7aef | 10 76a5 (0) 77bc (0) 71bf (0) 715b (0)\n004 2 6caa 69d8 | 4 6f1c (0) 6caa (0) 6923 (0) 69d8 (0)\n005 2 63de 60bc | 2 63de (0) 60bc (0)\n============ DEPTH: 6 ==========================================\n006 2 6701 67ee | 2 6701 (0) 67ee (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"8f88c7ec044f758f29bd8d12a5170bd973aec8f6cddbf512b910c4b75a0fec09c5e198bcd65622037f897759db68da2328b4a7ca93585dc9cb62e46d2a6c0864","private_key":"f88a54bfc74bebed6bc8bf6d7b98aad4ea4f8b8aea6cb1514aecf398bee41960","name":"node_8f88c7ec044f758f29bd8d12a5170bd973aec8f6cddbf512b910c4b75a0fec09c5e198bcd65622037f897759db68da2328b4a7ca93585dc9cb62e46d2a6c0864","services":["streamer"],"enable_msg_events":true,"port":63270},"up":true}},{"node":{"info":{"id":"4314b0b04331973ed29a58843951f144ac3d09bd5d57b6cd9aaff9b73a7b2ec81e344a3e4ece462bd2081b837a06310e787ef3bb889dabad46fe7efd394c8342","name":"node_4314b0b04331973ed29a58843951f144ac3d09bd5d57b6cd9aaff9b73a7b2ec81e344a3e4ece462bd2081b837a06310e787ef3bb889dabad46fe7efd394c8342","enode":"enode://4314b0b04331973ed29a58843951f144ac3d09bd5d57b6cd9aaff9b73a7b2ec81e344a3e4ece462bd2081b837a06310e787ef3bb889dabad46fe7efd394c8342@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"Hfyqtnap2ag8fwdkSaoNhEZ3DsCWBlXhIC/X7kJjg+s=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 1dfcaa\npopulation: 23 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 9bc3 baaf ebe8 | 134 8ae8 (0) 8a54 (0) 89ef (0) 8d3c (0)\n001 3 4bbc 43fb 65a6 | 50 5237 (0) 5399 (0) 5070 (0) 5062 (0)\n002 2 2f23 3607 | 35 2737 (0) 24f8 (0) 208e (0) 2220 (0)\n003 7 07a6 0020 020f 0305 | 18 0daf (0) 0d97 (0) 0c72 (0) 0c19 (0)\n004 2 15ec 1758 | 9 11a0 (0) 10b1 (0) 1254 (0) 167b (0)\n005 1 1a85 | 4 1953 (0) 1af6 (0) 1a8e (0) 1a85 (0)\n006 2 1ea1 1fab | 2 1ea1 (0) 1fab (0)\n007 0 | 0\n008 1 1d5b | 1 1d5b (0)\n============ DEPTH: 9 ==========================================\n009 1 1daa | 1 1daa (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 1 1dfd | 1 1dfd (0)\n========================================================================="}},"config":{"id":"4314b0b04331973ed29a58843951f144ac3d09bd5d57b6cd9aaff9b73a7b2ec81e344a3e4ece462bd2081b837a06310e787ef3bb889dabad46fe7efd394c8342","private_key":"a5b02d5d5ff64f5330758019a5ba0583f2b74b423be4695b4ffd94231ffd58c8","name":"node_4314b0b04331973ed29a58843951f144ac3d09bd5d57b6cd9aaff9b73a7b2ec81e344a3e4ece462bd2081b837a06310e787ef3bb889dabad46fe7efd394c8342","services":["streamer"],"enable_msg_events":true,"port":63271},"up":true}},{"node":{"info":{"id":"3612863ce0456c91785a829bf5c9d2b2fb97dda083a1847e5a4ebaa6fce1260faf4d1eb374c2225431a82774163835fb59c8cb0fa9fc0969eab5410c71109cc2","name":"node_3612863ce0456c91785a829bf5c9d2b2fb97dda083a1847e5a4ebaa6fce1260faf4d1eb374c2225431a82774163835fb59c8cb0fa9fc0969eab5410c71109cc2","enode":"enode://3612863ce0456c91785a829bf5c9d2b2fb97dda083a1847e5a4ebaa6fce1260faf4d1eb374c2225431a82774163835fb59c8cb0fa9fc0969eab5410c71109cc2@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"6+gDehNE+bWZzKGspASGHEGUUpq3yyOz96CB9hVCdXU=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: ebe803\npopulation: 33 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 65a6 0a3f 1dfc | 122 5237 (0) 5399 (0) 510c (0) 5070 (0)\n001 5 985f baaf a1b6 a0c9 | 63 ac62 (0) af8f (0) aa78 (0) a9df (0)\n002 5 c409 d1bc d07c d2ac | 33 d90b (0) d96e (0) dad3 (0) df52 (0)\n003 3 f293 f97e fd44 | 13 f6a6 (0) f1b9 (0) f1ad (0) f054 (0)\n004 6 e5d2 e406 e4d6 e6b7 | 13 e56c (0) e54d (0) e5d2 (0) e4d6 (0)\n005 8 ecff ec78 efbb efc1 | 8 ecff (0) ec78 (0) efbb (0) efdd (0)\n============ DEPTH: 6 ==========================================\n006 2 e9fa e850 | 2 e850 (0) e9fa (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 1 ebc9 | 1 ebc9 (0)\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"3612863ce0456c91785a829bf5c9d2b2fb97dda083a1847e5a4ebaa6fce1260faf4d1eb374c2225431a82774163835fb59c8cb0fa9fc0969eab5410c71109cc2","private_key":"9e96b56ea6abe86960b688d477b9c689309a7f304c5e4bd108459144e68448c4","name":"node_3612863ce0456c91785a829bf5c9d2b2fb97dda083a1847e5a4ebaa6fce1260faf4d1eb374c2225431a82774163835fb59c8cb0fa9fc0969eab5410c71109cc2","services":["streamer"],"enable_msg_events":true,"port":63272},"up":true}},{"node":{"info":{"id":"2ac522ebfa49d37f86c6270ad4cdad0e766493f0e463b18c9906c70fbd2e5c6ff6b0d5879de6e3894418370636963a78b0c0cf087a8684c2ca30c9c736e49228","name":"node_2ac522ebfa49d37f86c6270ad4cdad0e766493f0e463b18c9906c70fbd2e5c6ff6b0d5879de6e3894418370636963a78b0c0cf087a8684c2ca30c9c736e49228","enode":"enode://2ac522ebfa49d37f86c6270ad4cdad0e766493f0e463b18c9906c70fbd2e5c6ff6b0d5879de6e3894418370636963a78b0c0cf087a8684c2ca30c9c736e49228@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"Cj/mUW7f8zzeavxGxhdKhWLxdFS2861BvowS6/GwoH0=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 0a3fe6\npopulation: 21 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 985f b049 ebe8 ee3f | 134 b45f (0) b40d (0) b7aa (0) b049 (0)\n001 1 77bc | 50 47a8 (0) 464b (0) 44b7 (0) 44c8 (0)\n002 4 3ef6 3799 3658 3607 | 35 208e (0) 2220 (0) 2224 (0) 24f8 (0)\n003 1 1dfc | 19 1254 (0) 11a0 (0) 10b1 (0) 14e4 (0)\n004 4 07a6 0020 020f 0305 | 7 05a4 (0) 0536 (0) 07a6 (0) 00c8 (0)\n005 4 0d97 0c19 0ca9 0fa0 | 7 0ca9 (0) 0c72 (0) 0c19 (0) 0daf (0)\n006 1 09d1 | 1 09d1 (0)\n============ DEPTH: 7 ==========================================\n007 1 0bc3 | 1 0bc3 (0)\n008 1 0ad6 | 1 0ad6 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"2ac522ebfa49d37f86c6270ad4cdad0e766493f0e463b18c9906c70fbd2e5c6ff6b0d5879de6e3894418370636963a78b0c0cf087a8684c2ca30c9c736e49228","private_key":"5bec215e5024e8ce65d46fbf9b69e1718c1173478f8654d2ef451b6217ac6db3","name":"node_2ac522ebfa49d37f86c6270ad4cdad0e766493f0e463b18c9906c70fbd2e5c6ff6b0d5879de6e3894418370636963a78b0c0cf087a8684c2ca30c9c736e49228","services":["streamer"],"enable_msg_events":true,"port":63273},"up":true}},{"node":{"info":{"id":"62666b24d1026345349edb6a878cdc27d6fee8254e83f79a298ce2805260d97aa46423deae440f86ced5cd99b30e970c8e1ea1046752b17d8c80dc68d9a49b60","name":"node_62666b24d1026345349edb6a878cdc27d6fee8254e83f79a298ce2805260d97aa46423deae440f86ced5cd99b30e970c8e1ea1046752b17d8c80dc68d9a49b60","enode":"enode://62666b24d1026345349edb6a878cdc27d6fee8254e83f79a298ce2805260d97aa46423deae440f86ced5cd99b30e970c8e1ea1046752b17d8c80dc68d9a49b60@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"mF8bbWQqn7cTAv4yWz85qq88HH7NP+2zCMN1P33U4jU=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 985f1b\npopulation: 30 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 5 0a3f 3799 65a6 77bc | 122 7e45 (0) 7ec4 (0) 7810 (0) 7aef (0)\n001 6 d2ac c409 fd44 ee3f | 71 df52 (0) de1d (0) d96e (0) d90b (0)\n002 3 baaf a936 ac62 | 30 af8f (0) ac62 (0) aa78 (0) a936 (0)\n003 4 8611 8434 8ea9 89ef | 15 802e (0) 802f (0) 83d0 (0) 86d3 (0)\n004 3 9493 910d 92d5 | 8 92d5 (0) 93f8 (5) 9108 (0) 910d (0)\n005 1 9f4c | 1 9f4c (0)\n006 3 9a09 9bc3 9b87 | 3 9a09 (0) 9b87 (0) 9bc3 (0)\n007 3 99eb 9918 9929 | 3 99eb (0) 9929 (0) 9918 (0)\n============ DEPTH: 8 ==========================================\n008 2 98bc 98aa | 2 98aa (0) 98bc (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"62666b24d1026345349edb6a878cdc27d6fee8254e83f79a298ce2805260d97aa46423deae440f86ced5cd99b30e970c8e1ea1046752b17d8c80dc68d9a49b60","private_key":"00dd6637412fc5209eeee1423b4eae49fbba97d8d5c37c9ae6819f7afc53569e","name":"node_62666b24d1026345349edb6a878cdc27d6fee8254e83f79a298ce2805260d97aa46423deae440f86ced5cd99b30e970c8e1ea1046752b17d8c80dc68d9a49b60","services":["streamer"],"enable_msg_events":true,"port":63274},"up":true}},{"node":{"info":{"id":"9ce6b9decb69d66075993e903a0727ec109a04335634616097c0e60b08f94f764634fa00891b1070f6ea1ce896bc7d11d3aea92a00f281f902d960894cef296f","name":"node_9ce6b9decb69d66075993e903a0727ec109a04335634616097c0e60b08f94f764634fa00891b1070f6ea1ce896bc7d11d3aea92a00f281f902d960894cef296f","enode":"enode://9ce6b9decb69d66075993e903a0727ec109a04335634616097c0e60b08f94f764634fa00891b1070f6ea1ce896bc7d11d3aea92a00f281f902d960894cef296f@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"4ZCf9wsX9mbXTHPo2YA98ebiBzPkruzceOREtmMtksk=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: e1909f\npopulation: 18 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 3799 | 122 7e45 (0) 7ec4 (0) 7810 (0) 7aef (0)\n001 3 baaf 985f 89ef | 63 ac62 (0) af8f (0) aa78 (0) a936 (0)\n002 2 d2ac c409 | 33 d96e (0) d90b (0) dad3 (0) df52 (0)\n003 1 fd44 | 13 f6a6 (0) f1ad (0) f1b9 (0) f054 (0)\n004 6 e9fa ebe8 ec78 efc1 | 12 e850 (0) e9fa (0) ebc9 (0) ebe8 (0)\n005 2 e469 e5d2 | 9 e54d (0) e56c (0) e5d2 (0) e469 (0)\n============ DEPTH: 6 ==========================================\n006 3 e255 e31e e3d8 | 3 e255 (0) e31e (0) e3d8 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"9ce6b9decb69d66075993e903a0727ec109a04335634616097c0e60b08f94f764634fa00891b1070f6ea1ce896bc7d11d3aea92a00f281f902d960894cef296f","private_key":"88ceb50dc965b4e3279c8e7729db14ea34238126f1ab694c621d5ab9183acb52","name":"node_9ce6b9decb69d66075993e903a0727ec109a04335634616097c0e60b08f94f764634fa00891b1070f6ea1ce896bc7d11d3aea92a00f281f902d960894cef296f","services":["streamer"],"enable_msg_events":true,"port":63275},"up":true}},{"node":{"info":{"id":"b870935867183bbfb84add16b9f56c02c834b7042fc24ce6bcb2a7f174e6d2239357a00be4272c1ef05c7f9baf5a9f16b53bc18328a9b7aca8540c2916805b57","name":"node_b870935867183bbfb84add16b9f56c02c834b7042fc24ce6bcb2a7f174e6d2239357a00be4272c1ef05c7f9baf5a9f16b53bc18328a9b7aca8540c2916805b57","enode":"enode://b870935867183bbfb84add16b9f56c02c834b7042fc24ce6bcb2a7f174e6d2239357a00be4272c1ef05c7f9baf5a9f16b53bc18328a9b7aca8540c2916805b57@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"N5nF8+uq1wEw/PALuBMceJUaj0u9Z60r2t//So9mcUM=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 3799c5\npopulation: 22 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 8 985f 910d 89ef c409 | 134 ac62 (0) af8f (0) aa78 (0) a9df (0)\n001 2 77bc 5a67 | 50 7239 (0) 7299 (0) 71bf (0) 715b (0)\n002 1 0a3f | 37 1953 (0) 1af6 (0) 1a8e (0) 1a85 (0)\n003 2 2f1f 2737 | 15 2940 (0) 293f (0) 2a7d (0) 2e3b (0)\n004 3 3843 3ff8 3ef6 | 10 3baa (0) 3ab2 (0) 3a18 (0) 398b (0)\n005 2 3085 3227 | 5 307c (0) 3054 (0) 3085 (0) 3388 (0)\n006 1 34e4 | 1 34e4 (0)\n============ DEPTH: 7 ==========================================\n007 2 3658 3607 | 2 3658 (0) 3607 (0)\n008 1 3734 | 1 3734 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"b870935867183bbfb84add16b9f56c02c834b7042fc24ce6bcb2a7f174e6d2239357a00be4272c1ef05c7f9baf5a9f16b53bc18328a9b7aca8540c2916805b57","private_key":"638176a3cb343c140131c887892f37f9ad69e9c87c0a256dbbf2fbf8dd2a6b08","name":"node_b870935867183bbfb84add16b9f56c02c834b7042fc24ce6bcb2a7f174e6d2239357a00be4272c1ef05c7f9baf5a9f16b53bc18328a9b7aca8540c2916805b57","services":["streamer"],"enable_msg_events":true,"port":63276},"up":true}},{"node":{"info":{"id":"c83985973a9564ade7d90aa54911ac57077600676a1d27292d98e058bf1315887bad84ccd708cb7f52a695a1405fb7d491d7ca2ae9caa3ff58a5ad78ce4dc9d9","name":"node_c83985973a9564ade7d90aa54911ac57077600676a1d27292d98e058bf1315887bad84ccd708cb7f52a695a1405fb7d491d7ca2ae9caa3ff58a5ad78ce4dc9d9","enode":"enode://c83985973a9564ade7d90aa54911ac57077600676a1d27292d98e058bf1315887bad84ccd708cb7f52a695a1405fb7d491d7ca2ae9caa3ff58a5ad78ce4dc9d9@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"/UTyYWdVqtPvrLqezx2S0KuYa6Z5AH9zXIvPPGuUwVA=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: fd44f2\npopulation: 24 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 3799 | 122 7239 (0) 7299 (0) 71bf (0) 715b (0)\n001 5 baaf 8434 89ef 985f | 63 af8f (0) ac62 (0) aa78 (0) a936 (0)\n002 2 c409 d2ac | 33 cf77 (0) ce71 (0) c914 (0) c911 (0)\n003 7 ebe8 ec78 efc1 eee1 | 25 e850 (0) e9fa (0) ebc9 (0) ebe8 (0)\n004 5 f6a6 f0b8 f1b9 f2b2 | 8 f6a6 (0) f1ad (0) f1b9 (0) f054 (0)\n005 1 f97e | 1 f97e (0)\n006 1 ffb7 | 1 ffb7 (0)\n============ DEPTH: 7 ==========================================\n007 1 fc88 | 1 fc88 (0)\n008 0 | 0\n009 1 fd3f | 1 fd3f (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"c83985973a9564ade7d90aa54911ac57077600676a1d27292d98e058bf1315887bad84ccd708cb7f52a695a1405fb7d491d7ca2ae9caa3ff58a5ad78ce4dc9d9","private_key":"4da9834c8665dcfed17ee5eb89c5bfa3c0d1cc4340088a4038f746dae4cc23e6","name":"node_c83985973a9564ade7d90aa54911ac57077600676a1d27292d98e058bf1315887bad84ccd708cb7f52a695a1405fb7d491d7ca2ae9caa3ff58a5ad78ce4dc9d9","services":["streamer"],"enable_msg_events":true,"port":63277},"up":true}},{"node":{"info":{"id":"acb4088c27ee2ee130ece3506596432afdb9e9757ec11ebdd35c5a6e87239545c48466913a646980104c8fd7a9a335e177f04efffe9dc952dfd7cd5c1bb9aac6","name":"node_acb4088c27ee2ee130ece3506596432afdb9e9757ec11ebdd35c5a6e87239545c48466913a646980104c8fd7a9a335e177f04efffe9dc952dfd7cd5c1bb9aac6","enode":"enode://acb4088c27ee2ee130ece3506596432afdb9e9757ec11ebdd35c5a6e87239545c48466913a646980104c8fd7a9a335e177f04efffe9dc952dfd7cd5c1bb9aac6@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"0qya+Rmnv+qdCs0RvGOHS+uMchOUESi6fndBx+eehx8=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: d2ac9a\npopulation: 23 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 3799 | 122 71bf (0) 715b (0) 7239 (0) 7299 (0)\n001 2 985f 9bc3 | 63 aa78 (0) a936 (0) a9df (0) ac62 (0)\n002 7 e190 ebe8 ec78 efc1 | 38 e850 (0) e9fa (0) ebc9 (0) ebe8 (0)\n003 3 cbd3 cba4 c409 | 14 cf77 (0) ce71 (0) c914 (0) c911 (0)\n004 2 de1d dad3 | 5 df52 (0) de1d (0) d96e (0) d90b (0)\n005 3 d66f d606 d717 | 7 d455 (0) d560 (0) d606 (0) d66f (0)\n006 3 d1bc d07c d044 | 4 d1bc (0) d0b7 (0) d07c (0) d044 (0)\n============ DEPTH: 7 ==========================================\n007 2 d3bd d35c | 2 d3bd (0) d35c (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"acb4088c27ee2ee130ece3506596432afdb9e9757ec11ebdd35c5a6e87239545c48466913a646980104c8fd7a9a335e177f04efffe9dc952dfd7cd5c1bb9aac6","private_key":"05eb5751d81653e8ce409be43c9da42ff90f90c6e68981e69cd03a867d93b800","name":"node_acb4088c27ee2ee130ece3506596432afdb9e9757ec11ebdd35c5a6e87239545c48466913a646980104c8fd7a9a335e177f04efffe9dc952dfd7cd5c1bb9aac6","services":["streamer"],"enable_msg_events":true,"port":63278},"up":true}},{"node":{"info":{"id":"b4fd11306b1416a9bcf4719578976188e104b8c5028b9abd3214d257446b97b70a22e6c00934d80caddde15e8e4d16af03bb399583047983fba373d8313226b7","name":"node_b4fd11306b1416a9bcf4719578976188e104b8c5028b9abd3214d257446b97b70a22e6c00934d80caddde15e8e4d16af03bb399583047983fba373d8313226b7","enode":"enode://b4fd11306b1416a9bcf4719578976188e104b8c5028b9abd3214d257446b97b70a22e6c00934d80caddde15e8e4d16af03bb399583047983fba373d8313226b7@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"xAkOw3zd/KLfrlLYWZOmNc9HVHyRflxpGQ4kpI23yv0=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: c4090e\npopulation: 24 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 3799 3ef6 | 122 7239 (0) 7299 (0) 71bf (0) 715b (0)\n001 4 9bc3 985f 8434 89ef | 63 ac62 (0) af8f (0) aa78 (0) a9df (0)\n002 7 fd44 e190 ebe8 ec78 | 38 e850 (0) e9fa (0) ebc9 (0) ebe8 (0)\n003 4 dad3 de1d d560 d2ac | 19 df52 (0) de1d (0) d96e (0) d90b (0)\n004 3 ce71 cba4 cbd3 | 9 cf77 (0) ce71 (0) c914 (0) c911 (0)\n005 2 c3d8 c301 | 2 c3d8 (0) c301 (0)\n============ DEPTH: 6 ==========================================\n006 2 c60e c7fa | 2 c60e (0) c7fa (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"b4fd11306b1416a9bcf4719578976188e104b8c5028b9abd3214d257446b97b70a22e6c00934d80caddde15e8e4d16af03bb399583047983fba373d8313226b7","private_key":"846035be661387d6163b5472ea225ecc9d3851349f480fb901d2e31bb8ffe858","name":"node_b4fd11306b1416a9bcf4719578976188e104b8c5028b9abd3214d257446b97b70a22e6c00934d80caddde15e8e4d16af03bb399583047983fba373d8313226b7","services":["streamer"],"enable_msg_events":true,"port":63279},"up":true}},{"node":{"info":{"id":"7b35c856916eb3fc1b1f451667e240b95aff8f4731cc0f6743740923081ff1ddf2eec81bdccf4691a7bcc053d23eacfc15809c384a73448f618317bf605bd1cd","name":"node_7b35c856916eb3fc1b1f451667e240b95aff8f4731cc0f6743740923081ff1ddf2eec81bdccf4691a7bcc053d23eacfc15809c384a73448f618317bf605bd1cd","enode":"enode://7b35c856916eb3fc1b1f451667e240b95aff8f4731cc0f6743740923081ff1ddf2eec81bdccf4691a7bcc053d23eacfc15809c384a73448f618317bf605bd1cd@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"Pva7Hc03Ng/kpGO3Ct1s1LoRKikxEpEbIwSrBbTBtUM=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 3ef6bb\npopulation: 21 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 ec78 ee3f c409 | 134 af8f (0) ac62 (0) a9df (0) a936 (0)\n001 4 5a67 67ee 77bc 7aef | 50 71bf (0) 715b (0) 7239 (0) 7299 (0)\n002 3 0a3f 11a0 1254 | 37 1254 (0) 11a0 (0) 10b1 (0) 14e4 (0)\n003 1 2cb1 | 15 2737 (0) 24f8 (0) 208e (0) 2224 (0)\n004 5 3227 34e4 3607 3734 | 10 3085 (0) 3054 (0) 307c (0) 3388 (0)\n005 2 3843 3a18 | 6 398b (0) 38d7 (0) 3843 (0) 3baa (0)\n============ DEPTH: 6 ==========================================\n006 2 3d17 3c5a | 2 3d17 (0) 3c5a (0)\n007 1 3ff8 | 1 3ff8 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"7b35c856916eb3fc1b1f451667e240b95aff8f4731cc0f6743740923081ff1ddf2eec81bdccf4691a7bcc053d23eacfc15809c384a73448f618317bf605bd1cd","private_key":"b34c69cee56a834b8a36ae964f1847d1825821a21d104396039175a8dce5ac73","name":"node_7b35c856916eb3fc1b1f451667e240b95aff8f4731cc0f6743740923081ff1ddf2eec81bdccf4691a7bcc053d23eacfc15809c384a73448f618317bf605bd1cd","services":["streamer"],"enable_msg_events":true,"port":63280},"up":true}},{"node":{"info":{"id":"2ab9513899c3c829b6284e56bf2b9862dd0156ec052b58615dba77d450dac642e534ec36ae5d3234262aff54e19f99856e908b9d8c1da660a7834a445610715b","name":"node_2ab9513899c3c829b6284e56bf2b9862dd0156ec052b58615dba77d450dac642e534ec36ae5d3234262aff54e19f99856e908b9d8c1da660a7834a445610715b","enode":"enode://2ab9513899c3c829b6284e56bf2b9862dd0156ec052b58615dba77d450dac642e534ec36ae5d3234262aff54e19f99856e908b9d8c1da660a7834a445610715b@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"7j8j5+YvmvKQZwPrmh3VGowqs6nKecRg4ICF5WWAbrM=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: ee3f23\npopulation: 22 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 0a3f 3799 3ef6 | 122 7239 (0) 7299 (0) 71bf (0) 715b (0)\n001 4 985f 9bc3 8434 89ef | 63 aa78 (0) a936 (0) a9df (0) af8f (0)\n002 2 c409 d2ac | 33 df52 (0) de1d (0) d96e (0) d90b (0)\n003 2 f293 fd44 | 13 f6a6 (0) f1ad (0) f1b9 (0) f054 (0)\n004 2 e3d8 e190 | 13 e56c (0) e54d (0) e5d2 (0) e4d6 (0)\n005 2 e9fa ebe8 | 4 e850 (0) e9fa (0) ebc9 (0) ebe8 (0)\n006 2 ec78 ecff | 2 ecff (0) ec78 (0)\n007 3 efbb efdd efc1 | 3 efbb (0) efdd (0) efc1 (0)\n============ DEPTH: 8 ==========================================\n008 1 eee1 | 1 eee1 (0)\n009 1 ee52 | 1 ee52 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"2ab9513899c3c829b6284e56bf2b9862dd0156ec052b58615dba77d450dac642e534ec36ae5d3234262aff54e19f99856e908b9d8c1da660a7834a445610715b","private_key":"3d1ea95ac16f7d903cb8630a8c06052560a974b0abd3410d9f8b2968e7cf653d","name":"node_2ab9513899c3c829b6284e56bf2b9862dd0156ec052b58615dba77d450dac642e534ec36ae5d3234262aff54e19f99856e908b9d8c1da660a7834a445610715b","services":["streamer"],"enable_msg_events":true,"port":63281},"up":true}},{"node":{"info":{"id":"e087230634f556b818a416b66ba3f1d1dbe3e0dd0698bbb26fa86a2499acd169466f564dc18adf2f9be4d1ada0e86c11549754097601e10aff4f3a57ddffa24a","name":"node_e087230634f556b818a416b66ba3f1d1dbe3e0dd0698bbb26fa86a2499acd169466f564dc18adf2f9be4d1ada0e86c11549754097601e10aff4f3a57ddffa24a","enode":"enode://e087230634f556b818a416b66ba3f1d1dbe3e0dd0698bbb26fa86a2499acd169466f564dc18adf2f9be4d1ada0e86c11549754097601e10aff4f3a57ddffa24a@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"ie/tZvsZLxUwutl4JhxmDPGEc7wq1Ny2wzNq/v6K6/I=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 89efed\npopulation: 22 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 3799 5a67 | 122 71bf (0) 715b (0) 7239 (0) 7299 (0)\n001 4 c409 fd44 e190 ee3f | 71 df52 (0) de1d (0) d90b (0) d96e (0)\n002 3 baaf a1b6 a0c9 | 30 af8f (0) ac62 (0) aa78 (0) a9df (0)\n003 5 9493 9f4c 985f 9bc3 | 18 92d5 (0) 93f8 (0) 9108 (0) 910d (0)\n004 2 8611 8434 | 8 802f (0) 802e (0) 83d0 (0) 86d3 (0)\n005 4 8d85 8d3c 8ee7 8ea9 | 4 8d3c (0) 8d85 (0) 8ee7 (0) 8ea9 (0)\n============ DEPTH: 6 ==========================================\n006 2 8ae8 8a54 | 2 8ae8 (0) 8a54 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"e087230634f556b818a416b66ba3f1d1dbe3e0dd0698bbb26fa86a2499acd169466f564dc18adf2f9be4d1ada0e86c11549754097601e10aff4f3a57ddffa24a","private_key":"70a577ae497edece947ef065da29014e45dcc1d942969597600a64b55e8bf718","name":"node_e087230634f556b818a416b66ba3f1d1dbe3e0dd0698bbb26fa86a2499acd169466f564dc18adf2f9be4d1ada0e86c11549754097601e10aff4f3a57ddffa24a","services":["streamer"],"enable_msg_events":true,"port":63282},"up":true}},{"node":{"info":{"id":"66beee3968dbcf3addc6feaf070a4e3e82b5bb164fb72f40add89f732c12e8d0a31a7ee1f1e24a4674e4dfc9a4912b02c17ce3c224d257d78b7156544d6507dc","name":"node_66beee3968dbcf3addc6feaf070a4e3e82b5bb164fb72f40add89f732c12e8d0a31a7ee1f1e24a4674e4dfc9a4912b02c17ce3c224d257d78b7156544d6507dc","enode":"enode://66beee3968dbcf3addc6feaf070a4e3e82b5bb164fb72f40add89f732c12e8d0a31a7ee1f1e24a4674e4dfc9a4912b02c17ce3c224d257d78b7156544d6507dc@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"Wme/8iDbdaoiZnQmFM8VAlucBqpzPIBdA3LxCILCkqE=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 5a67bf\npopulation: 23 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 89ef | 134 df52 (0) de1d (0) d90b (0) d96e (0)\n001 2 3ef6 3799 | 72 11a0 (0) 10b1 (0) 1254 (0) 14e4 (0)\n002 5 77bc 7aef 69d8 65a6 | 19 71bf (0) 715b (0) 7239 (0) 7299 (0)\n003 5 44c8 43fb 4c97 4bbc | 16 4dc4 (0) 4c97 (0) 48ec (0) 48df (0)\n004 5 5399 5070 5062 5741 | 9 510c (0) 5070 (0) 5062 (0) 5237 (0)\n005 3 5c9b 5cae 5e3e | 3 5c9b (0) 5cae (0) 5e3e (0)\n============ DEPTH: 6 ==========================================\n006 1 581a | 1 581a (0)\n007 1 5b30 | 1 5b30 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"66beee3968dbcf3addc6feaf070a4e3e82b5bb164fb72f40add89f732c12e8d0a31a7ee1f1e24a4674e4dfc9a4912b02c17ce3c224d257d78b7156544d6507dc","private_key":"28ee397105a113c5c4e7d7cb1b3dd17b6db66c3cd8f3b621df0271e544fb446c","name":"node_66beee3968dbcf3addc6feaf070a4e3e82b5bb164fb72f40add89f732c12e8d0a31a7ee1f1e24a4674e4dfc9a4912b02c17ce3c224d257d78b7156544d6507dc","services":["streamer"],"enable_msg_events":true,"port":63283},"up":true}},{"node":{"info":{"id":"a08e47137bf611dfbd20308a22bdd3ca00121386f121d6d712ade86e9a1601a4237766887cd91c8516e20b6e323d2ef49c1c7e177a0afb4c813f0f344daf779b","name":"node_a08e47137bf611dfbd20308a22bdd3ca00121386f121d6d712ade86e9a1601a4237766887cd91c8516e20b6e323d2ef49c1c7e177a0afb4c813f0f344daf779b","enode":"enode://a08e47137bf611dfbd20308a22bdd3ca00121386f121d6d712ade86e9a1601a4237766887cd91c8516e20b6e323d2ef49c1c7e177a0afb4c813f0f344daf779b@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"Z+5nuPTT7lDYzdAnupbksvjvkBe6whe9Wi2dyjUyVRk=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 67ee67\npopulation: 15 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 9bc3 8434 | 134 df52 (0) de1d (0) d90b (0) d96e (0)\n001 2 1758 3ef6 | 72 14e4 (0) 1587 (0) 15ec (0) 1758 (0)\n002 1 5a67 | 31 4c97 (0) 4dc4 (0) 48df (0) 48ec (0)\n003 3 7299 77bc 7aef | 10 71bf (0) 715b (0) 7239 (0) 7299 (0)\n004 3 6f1c 6caa 69d8 | 4 6f1c (0) 6caa (0) 6923 (0) 69d8 (0)\n005 2 60bc 63de | 2 63de (0) 60bc (0)\n============ DEPTH: 6 ==========================================\n006 1 65a6 | 1 65a6 (0)\n007 0 | 0\n008 1 6701 | 1 6701 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"a08e47137bf611dfbd20308a22bdd3ca00121386f121d6d712ade86e9a1601a4237766887cd91c8516e20b6e323d2ef49c1c7e177a0afb4c813f0f344daf779b","private_key":"b6feae1f667895ada3116380a2cabb0c702b44b24d45415edd143d27dfe5643d","name":"node_a08e47137bf611dfbd20308a22bdd3ca00121386f121d6d712ade86e9a1601a4237766887cd91c8516e20b6e323d2ef49c1c7e177a0afb4c813f0f344daf779b","services":["streamer"],"enable_msg_events":true,"port":63284},"up":true}},{"node":{"info":{"id":"990b1db3ab1390219e8866d39fa4441bb5bb89ad786b3e255771869fcd08906dcf63f34007481769c7462edbcc665acc0a552e3733360b8d8c310c9321a5550f","name":"node_990b1db3ab1390219e8866d39fa4441bb5bb89ad786b3e255771869fcd08906dcf63f34007481769c7462edbcc665acc0a552e3733360b8d8c310c9321a5550f","enode":"enode://990b1db3ab1390219e8866d39fa4441bb5bb89ad786b3e255771869fcd08906dcf63f34007481769c7462edbcc665acc0a552e3733360b8d8c310c9321a5550f@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"eu8WJUCfR57hq61WX41+c7F3FOd/VNGsGy/oA4KgWMw=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 7aef16\npopulation: 20 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 985f 8434 eee1 | 134 df52 (0) de1d (0) d90b (0) d96e (0)\n001 3 38d7 3ff8 3ef6 | 72 14e4 (0) 15ec (0) 1587 (0) 167b (0)\n002 1 5a67 | 31 4c97 (0) 4dc4 (0) 48df (0) 48ec (0)\n003 5 6caa 69d8 60bc 65a6 | 9 6f1c (0) 6caa (0) 6923 (0) 69d8 (0)\n004 5 71bf 7299 7239 76a5 | 6 71bf (0) 715b (0) 7239 (0) 7299 (0)\n============ DEPTH: 5 ==========================================\n005 2 7e45 7ec4 | 2 7ec4 (0) 7e45 (0)\n006 1 7810 | 1 7810 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"990b1db3ab1390219e8866d39fa4441bb5bb89ad786b3e255771869fcd08906dcf63f34007481769c7462edbcc665acc0a552e3733360b8d8c310c9321a5550f","private_key":"a643e845285aa039d6f84cb124b618bac45c970fe0b15fdbbbdef834300b4857","name":"node_990b1db3ab1390219e8866d39fa4441bb5bb89ad786b3e255771869fcd08906dcf63f34007481769c7462edbcc665acc0a552e3733360b8d8c310c9321a5550f","services":["streamer"],"enable_msg_events":true,"port":63285},"up":true}},{"node":{"info":{"id":"7865b82e44add2cea6ebcbaba9c152184331a2940fe73f6f9bb940bda8a59ab4cf4760894b9cadcaa54e36fbb712ad619346a49a85e32cdf2b53cda1ac1e0658","name":"node_7865b82e44add2cea6ebcbaba9c152184331a2940fe73f6f9bb940bda8a59ab4cf4760894b9cadcaa54e36fbb712ad619346a49a85e32cdf2b53cda1ac1e0658","enode":"enode://7865b82e44add2cea6ebcbaba9c152184331a2940fe73f6f9bb940bda8a59ab4cf4760894b9cadcaa54e36fbb712ad619346a49a85e32cdf2b53cda1ac1e0658@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"m8PMf/GPHszTaUjmgxzhTQIjonsjPVuDm4Zi4W+ftDU=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 9bc3cc\npopulation: 27 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 6 15ec 1758 1dfc 57ee | 122 1953 (0) 1a85 (0) 1a8e (0) 1af6 (0)\n001 6 c409 d2ac fd44 ee3f | 71 df52 (0) de1d (0) d96e (0) d90b (0)\n002 2 a1b6 baaf | 30 ac62 (0) af8f (0) aa78 (0) a9df (0)\n003 2 89ef 8434 | 15 8d3c (0) 8d85 (0) 8ee7 (0) 8ea9 (0)\n004 2 9493 910d | 8 92d5 (0) 93f8 (0) 9108 (0) 910d (0)\n005 1 9f4c | 1 9f4c (0)\n006 6 985f 98bc 98aa 9918 | 6 9929 (0) 9918 (0) 99eb (0) 98aa (0)\n============ DEPTH: 7 ==========================================\n007 1 9a09 | 1 9a09 (0)\n008 0 | 0\n009 1 9b87 | 1 9b87 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"7865b82e44add2cea6ebcbaba9c152184331a2940fe73f6f9bb940bda8a59ab4cf4760894b9cadcaa54e36fbb712ad619346a49a85e32cdf2b53cda1ac1e0658","private_key":"1b31bc34d4ea49b0c1df457ad06513d0f47c56ab106b0f0ac97c43ccdc64db31","name":"node_7865b82e44add2cea6ebcbaba9c152184331a2940fe73f6f9bb940bda8a59ab4cf4760894b9cadcaa54e36fbb712ad619346a49a85e32cdf2b53cda1ac1e0658","services":["streamer"],"enable_msg_events":true,"port":63286},"up":true}},{"node":{"info":{"id":"292c78c8e41606e98428096bc6f4609a7aa48e5c4d17eecc64d65faae4a7270b0c15f0cd74274015688ea0a9aff34f215c29118222e362a29c8d637963973a55","name":"node_292c78c8e41606e98428096bc6f4609a7aa48e5c4d17eecc64d65faae4a7270b0c15f0cd74274015688ea0a9aff34f215c29118222e362a29c8d637963973a55","enode":"enode://292c78c8e41606e98428096bc6f4609a7aa48e5c4d17eecc64d65faae4a7270b0c15f0cd74274015688ea0a9aff34f215c29118222e362a29c8d637963973a55@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"hDT/tiTzNvMA+MTzMV7crrmbf1QsizwslyqmvCENEwI=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 8434ff\npopulation: 28 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 57ee 7aef 77bc 67ee | 122 1254 (0) 11a0 (0) 10b1 (0) 1587 (0)\n001 6 c409 fd44 ec78 ee3f | 71 d455 (0) d560 (0) d66f (0) d606 (0)\n002 4 b820 baaf a1b6 a0c9 | 30 a9df (0) a936 (0) aa78 (0) ac62 (0)\n003 5 9493 9f4c 985f 9bc3 | 18 93f8 (0) 92d5 (0) 9108 (0) 910d (0)\n004 3 8ea9 8a54 89ef | 7 8d3c (0) 8d85 (0) 8ee7 (0) 8ea9 (0)\n005 2 802e 83d0 | 3 802f (0) 802e (0) 83d0 (0)\n006 2 86d3 8611 | 2 86d3 (0) 8611 (0)\n============ DEPTH: 7 ==========================================\n007 2 8564 853b | 2 8564 (0) 853b (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"292c78c8e41606e98428096bc6f4609a7aa48e5c4d17eecc64d65faae4a7270b0c15f0cd74274015688ea0a9aff34f215c29118222e362a29c8d637963973a55","private_key":"b380737ac46f320eb5884ca8a60e1693caba904545b68396e33fb92cd19aa18e","name":"node_292c78c8e41606e98428096bc6f4609a7aa48e5c4d17eecc64d65faae4a7270b0c15f0cd74274015688ea0a9aff34f215c29118222e362a29c8d637963973a55","services":["streamer"],"enable_msg_events":true,"port":63287},"up":true}},{"node":{"info":{"id":"ee36d1d5dd69fd30242d7da2e941b34ade5581c7164fcc43288ecfc52937a98f1b31ade5d1e4dbf611cbe1c7875b2840c89435081cde471c271d7bc60e9ef211","name":"node_ee36d1d5dd69fd30242d7da2e941b34ade5581c7164fcc43288ecfc52937a98f1b31ade5d1e4dbf611cbe1c7875b2840c89435081cde471c271d7bc60e9ef211","enode":"enode://ee36d1d5dd69fd30242d7da2e941b34ade5581c7164fcc43288ecfc52937a98f1b31ade5d1e4dbf611cbe1c7875b2840c89435081cde471c271d7bc60e9ef211@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"d7xWKO3q+s7RDx83J6T1ebxp5FdyASdobSdUv5gDpEY=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 77bc56\npopulation: 28 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 7 ec78 efc1 eee1 8434 | 134 df52 (0) de1d (0) d96e (0) d90b (0)\n001 8 2cb1 3ef6 3799 3607 | 72 1ea1 (0) 1fab (0) 1d5b (0) 1daa (0)\n002 3 44c8 57ee 5a67 | 31 4c97 (0) 4dc4 (0) 48ec (0) 48df (0)\n003 2 65a6 67ee | 9 6f1c (0) 6caa (0) 6923 (0) 69d8 (0)\n004 3 7e45 7810 7aef | 4 7ec4 (0) 7e45 (0) 7810 (0) 7aef (0)\n============ DEPTH: 5 ==========================================\n005 4 7239 7299 71bf 715b | 4 71bf (0) 715b (0) 7239 (0) 7299 (0)\n006 0 | 0\n007 1 76a5 | 1 76a5 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"ee36d1d5dd69fd30242d7da2e941b34ade5581c7164fcc43288ecfc52937a98f1b31ade5d1e4dbf611cbe1c7875b2840c89435081cde471c271d7bc60e9ef211","private_key":"d18c1536cd7d9771bc9b64595184285ed499519ef810b3f013fca2fc01018048","name":"node_ee36d1d5dd69fd30242d7da2e941b34ade5581c7164fcc43288ecfc52937a98f1b31ade5d1e4dbf611cbe1c7875b2840c89435081cde471c271d7bc60e9ef211","services":["streamer"],"enable_msg_events":true,"port":63288},"up":true}},{"node":{"info":{"id":"bd1a7c63fca9e1fcc67d7fd62670beefe2bce483cf1dc1233ee85eb90db607917cd9a5d7170b10e80b925a20e2af2c54d286b01805ac34967410859f4f03da09","name":"node_bd1a7c63fca9e1fcc67d7fd62670beefe2bce483cf1dc1233ee85eb90db607917cd9a5d7170b10e80b925a20e2af2c54d286b01805ac34967410859f4f03da09","enode":"enode://bd1a7c63fca9e1fcc67d7fd62670beefe2bce483cf1dc1233ee85eb90db607917cd9a5d7170b10e80b925a20e2af2c54d286b01805ac34967410859f4f03da09@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"7uFbXF/8vQqlaHempFqqMjNnYUGA0+XPe0ru+nidgxc=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: eee15b\npopulation: 24 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 3a18 57ee 7aef 77bc | 122 1254 (0) 11a0 (0) 10b1 (0) 14e4 (0)\n001 3 8434 9bc3 9493 | 63 aa78 (0) a9df (0) a936 (0) af8f (0)\n002 4 dad3 d2ac cbd3 c409 | 33 df52 (0) de1d (0) d96e (0) d90b (0)\n003 2 fd44 f293 | 13 f97e (0) ffb7 (0) fc88 (0) fd3f (0)\n004 2 e190 e3d8 | 13 e724 (0) e6b7 (0) e54d (0) e56c (0)\n005 2 ebe8 e9fa | 4 e9fa (0) e850 (0) ebc9 (0) ebe8 (0)\n006 2 ecff ec78 | 2 ecff (0) ec78 (0)\n007 3 efbb efdd efc1 | 3 efbb (0) efdd (0) efc1 (0)\n============ DEPTH: 8 ==========================================\n008 2 ee52 ee3f | 2 ee52 (0) ee3f (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"bd1a7c63fca9e1fcc67d7fd62670beefe2bce483cf1dc1233ee85eb90db607917cd9a5d7170b10e80b925a20e2af2c54d286b01805ac34967410859f4f03da09","private_key":"186743aa8dc07042c40bb95b2efe30149139f3c2ea4a4bd193d3be68e8f4485a","name":"node_bd1a7c63fca9e1fcc67d7fd62670beefe2bce483cf1dc1233ee85eb90db607917cd9a5d7170b10e80b925a20e2af2c54d286b01805ac34967410859f4f03da09","services":["streamer"],"enable_msg_events":true,"port":63289},"up":true}},{"node":{"info":{"id":"9db1f94d74a00d1e5e2a391f1bcddf16b6d0670a2c6d91d946d38112c58634444b6fea8e8c05ab4b73bacdd62a0b575f6fb8729978edc216c7842b177b9f9cd9","name":"node_9db1f94d74a00d1e5e2a391f1bcddf16b6d0670a2c6d91d946d38112c58634444b6fea8e8c05ab4b73bacdd62a0b575f6fb8729978edc216c7842b177b9f9cd9","enode":"enode://9db1f94d74a00d1e5e2a391f1bcddf16b6d0670a2c6d91d946d38112c58634444b6fea8e8c05ab4b73bacdd62a0b575f6fb8729978edc216c7842b177b9f9cd9@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"lJOG6CMjTRr98qITRjCoAohovc3yZEPaTbIuzniHGJk=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 949386\npopulation: 29 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 57ee 77bc 3a18 | 122 07a6 (0) 05a4 (0) 0536 (0) 00c8 (0)\n001 7 cbd3 d717 dad3 f293 | 71 c301 (0) c3d8 (0) c7fa (0) c60e (0)\n002 2 a1b6 baaf | 30 ac62 (0) af8f (0) aa78 (0) a9df (0)\n003 3 8434 8ea9 89ef | 15 8d3c (0) 8d85 (0) 8ee7 (0) 8ea9 (0)\n004 8 9f4c 985f 98bc 99eb | 10 9f4c (0) 9929 (0) 9918 (0) 99eb (0)\n005 3 93f8 9108 910d | 4 92d5 (0) 93f8 (0) 9108 (0) 910d (0)\n============ DEPTH: 6 ==========================================\n006 2 9747 9641 | 2 9747 (0) 9641 (0)\n007 0 | 0\n008 1 9404 | 1 9404 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"9db1f94d74a00d1e5e2a391f1bcddf16b6d0670a2c6d91d946d38112c58634444b6fea8e8c05ab4b73bacdd62a0b575f6fb8729978edc216c7842b177b9f9cd9","private_key":"2e960819700f3330b00d2d58461403843026ffc7629b2514568c6b571fc99488","name":"node_9db1f94d74a00d1e5e2a391f1bcddf16b6d0670a2c6d91d946d38112c58634444b6fea8e8c05ab4b73bacdd62a0b575f6fb8729978edc216c7842b177b9f9cd9","services":["streamer"],"enable_msg_events":true,"port":63290},"up":true}},{"node":{"info":{"id":"934a5fe1b91c1891ef4df7f67c027e0eb115d4c2ca4a1b76a135ebd4315c4fb835d6625223194e6a134407b38b0d3928fbc7bc924a3c6a538989a6cf200bf4bd","name":"node_934a5fe1b91c1891ef4df7f67c027e0eb115d4c2ca4a1b76a135ebd4315c4fb835d6625223194e6a134407b38b0d3928fbc7bc924a3c6a538989a6cf200bf4bd","enode":"enode://934a5fe1b91c1891ef4df7f67c027e0eb115d4c2ca4a1b76a135ebd4315c4fb835d6625223194e6a134407b38b0d3928fbc7bc924a3c6a538989a6cf200bf4bd@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"78EozmWjiNswPZfx8YRPIFD40KlYIOiFmGVJDuJzsM4=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: efc128\npopulation: 24 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 77bc 57ee | 122 11a0 (0) 10b1 (0) 1254 (0) 14e4 (0)\n001 2 8434 9493 | 63 af8f (0) ac62 (0) aa78 (0) a9df (0)\n002 5 d2ac d717 dad3 c409 | 33 cf77 (0) ce71 (0) c914 (0) c911 (0)\n003 2 fd44 f293 | 13 f97e (0) ffb7 (0) fc88 (0) fd3f (0)\n004 2 e190 e3d8 | 13 e724 (0) e6b7 (0) e56c (0) e54d (0)\n005 4 ebc9 ebe8 e9fa e850 | 4 e850 (0) e9fa (0) ebc9 (0) ebe8 (0)\n006 2 ecff ec78 | 2 ecff (0) ec78 (0)\n007 3 ee52 ee3f eee1 | 3 ee52 (0) ee3f (0) eee1 (0)\n008 0 | 0\n============ DEPTH: 9 ==========================================\n009 1 efbb | 1 efbb (0)\n010 0 | 0\n011 1 efdd | 1 efdd (0)\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"934a5fe1b91c1891ef4df7f67c027e0eb115d4c2ca4a1b76a135ebd4315c4fb835d6625223194e6a134407b38b0d3928fbc7bc924a3c6a538989a6cf200bf4bd","private_key":"50c27493a6d9ddee175040dafa1f40c6ad503b55590479001ec085212c5cc08b","name":"node_934a5fe1b91c1891ef4df7f67c027e0eb115d4c2ca4a1b76a135ebd4315c4fb835d6625223194e6a134407b38b0d3928fbc7bc924a3c6a538989a6cf200bf4bd","services":["streamer"],"enable_msg_events":true,"port":63291},"up":true}},{"node":{"info":{"id":"485825745d97654cbb92a14e0cd1078691d3c28f4d82b1046284b676a42b44ca58eb43474e45e415d3bd3f3c383f9a1a3365821ed7ba6a9f2603b29d58031dc7","name":"node_485825745d97654cbb92a14e0cd1078691d3c28f4d82b1046284b676a42b44ca58eb43474e45e415d3bd3f3c383f9a1a3365821ed7ba6a9f2603b29d58031dc7","enode":"enode://485825745d97654cbb92a14e0cd1078691d3c28f4d82b1046284b676a42b44ca58eb43474e45e415d3bd3f3c383f9a1a3365821ed7ba6a9f2603b29d58031dc7@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"7Hha8vtmwK9MfWrHUOM3painlaIgIsr6ikPff7oR2eE=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: ec785a\npopulation: 28 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 5 3ef6 2cb1 0fa0 77bc | 122 1d5b (0) 1daa (0) 1dfc (0) 1dfd (0)\n001 3 8434 9bc3 9493 | 63 af8f (0) ac62 (0) a9df (0) a936 (0)\n002 4 dad3 d2ac cba4 c409 | 33 cf77 (0) ce71 (0) c95a (0) c914 (0)\n003 2 fd44 f293 | 13 f97e (0) ffb7 (0) fc88 (0) fd3f (0)\n004 4 e724 e56c e190 e3d8 | 13 e6b7 (0) e724 (0) e5d2 (0) e56c (0)\n005 3 e850 e9fa ebe8 | 4 e9fa (0) e850 (0) ebc9 (0) ebe8 (0)\n============ DEPTH: 6 ==========================================\n006 6 ee3f ee52 eee1 efbb | 6 ee52 (0) ee3f (0) eee1 (0) efbb (0)\n007 0 | 0\n008 1 ecff | 1 ecff (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"485825745d97654cbb92a14e0cd1078691d3c28f4d82b1046284b676a42b44ca58eb43474e45e415d3bd3f3c383f9a1a3365821ed7ba6a9f2603b29d58031dc7","private_key":"4c67752b215e2cfc06120964f06976fce2a1dba599c0f32c0f4393b9d77ef872","name":"node_485825745d97654cbb92a14e0cd1078691d3c28f4d82b1046284b676a42b44ca58eb43474e45e415d3bd3f3c383f9a1a3365821ed7ba6a9f2603b29d58031dc7","services":["streamer"],"enable_msg_events":true,"port":63292},"up":true}},{"node":{"info":{"id":"5bae82d4832092c17bd11474f7748015b8b69b896ab8f683a7c0024fc98740cecbb9e31c6275269f9000e5bfe51d7f45cd5dcd4433e0c87b5741685b40fe3983","name":"node_5bae82d4832092c17bd11474f7748015b8b69b896ab8f683a7c0024fc98740cecbb9e31c6275269f9000e5bfe51d7f45cd5dcd4433e0c87b5741685b40fe3983","enode":"enode://5bae82d4832092c17bd11474f7748015b8b69b896ab8f683a7c0024fc98740cecbb9e31c6275269f9000e5bfe51d7f45cd5dcd4433e0c87b5741685b40fe3983@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"V+5tPRPgIa5bsafoLEy9/rAhZNQwXAtGGaXqMYTRk1Q=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 57ee6d\npopulation: 22 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 8 8434 9bc3 9493 dad3 | 134 a936 (0) a9df (0) aa78 (0) af8f (0)\n001 3 1758 2cb1 3a18 | 72 1254 (0) 10b1 (0) 11a0 (0) 14e4 (0)\n002 1 77bc | 19 65a6 (0) 6701 (0) 67ee (0) 60bc (0)\n003 3 4bbc 43fb 44c8 | 16 4c97 (0) 4dc4 (0) 48df (0) 48ec (0)\n004 3 5e3e 5cae 5a67 | 6 5e3e (0) 5c9b (0) 5cae (0) 581a (0)\n005 1 5399 | 5 5070 (0) 5062 (0) 510c (0) 5237 (0)\n006 0 | 0\n007 1 56bb | 1 56bb (0)\n============ DEPTH: 8 ==========================================\n008 2 5765 5741 | 2 5765 (0) 5741 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"5bae82d4832092c17bd11474f7748015b8b69b896ab8f683a7c0024fc98740cecbb9e31c6275269f9000e5bfe51d7f45cd5dcd4433e0c87b5741685b40fe3983","private_key":"21acc46816414d3a1d76bca30d2c2e1e55d420e9ce704d0720696f7f7fa0bf33","name":"node_5bae82d4832092c17bd11474f7748015b8b69b896ab8f683a7c0024fc98740cecbb9e31c6275269f9000e5bfe51d7f45cd5dcd4433e0c87b5741685b40fe3983","services":["streamer"],"enable_msg_events":true,"port":63293},"up":true}},{"node":{"info":{"id":"732393b99c490c76fa45e3e404ee095f2fa445fcc123af7ac8ab1d2fdd7cf2483f5b82bb818bd8a82b1a3b73e63bcc2c83d8f24d9aad9afe36503735e7967be7","name":"node_732393b99c490c76fa45e3e404ee095f2fa445fcc123af7ac8ab1d2fdd7cf2483f5b82bb818bd8a82b1a3b73e63bcc2c83d8f24d9aad9afe36503735e7967be7","enode":"enode://732393b99c490c76fa45e3e404ee095f2fa445fcc123af7ac8ab1d2fdd7cf2483f5b82bb818bd8a82b1a3b73e63bcc2c83d8f24d9aad9afe36503735e7967be7@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"8pNliyg3zUHPtPnqoY0AJfxYd7zscBqX35FIgvS/5D4=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: f29365\npopulation: 23 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 2cb1 3a18 57ee | 122 1254 (0) 11a0 (0) 10b1 (0) 14e4 (0)\n001 1 9493 | 63 af8f (0) ac62 (0) a9df (0) a936 (0)\n002 3 cbd3 d717 dad3 | 33 c301 (0) c3d8 (0) c7fa (0) c60e (0)\n003 9 e469 e3d8 ebe8 ee3f | 25 e724 (0) e6b7 (0) e5d2 (0) e54d (0)\n004 2 fd44 fd3f | 5 f97e (0) ffb7 (0) fc88 (0) fd44 (0)\n005 1 f6a6 | 1 f6a6 (0)\n006 2 f054 f1b9 | 4 f0b8 (0) f054 (0) f1ad (0) f1b9 (0)\n007 0 | 0\n008 0 | 0\n============ DEPTH: 9 ==========================================\n009 1 f2f5 | 1 f2f5 (0)\n010 1 f2b2 | 1 f2b2 (0)\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"732393b99c490c76fa45e3e404ee095f2fa445fcc123af7ac8ab1d2fdd7cf2483f5b82bb818bd8a82b1a3b73e63bcc2c83d8f24d9aad9afe36503735e7967be7","private_key":"4542e37f43858e396004d8d8801bae1905d2496a3ab44f75cc29bd2c2a472f94","name":"node_732393b99c490c76fa45e3e404ee095f2fa445fcc123af7ac8ab1d2fdd7cf2483f5b82bb818bd8a82b1a3b73e63bcc2c83d8f24d9aad9afe36503735e7967be7","services":["streamer"],"enable_msg_events":true,"port":63294},"up":true}},{"node":{"info":{"id":"4de378164d77a28c90cf162dd1b465e0282ee17aa7d3bb3179252466f72da33a36c9f298f7c9498e38dba4018e7ce3e5fe631c83842cd9059e23a7fece366d87","name":"node_4de378164d77a28c90cf162dd1b465e0282ee17aa7d3bb3179252466f72da33a36c9f298f7c9498e38dba4018e7ce3e5fe631c83842cd9059e23a7fece366d87","enode":"enode://4de378164d77a28c90cf162dd1b465e0282ee17aa7d3bb3179252466f72da33a36c9f298f7c9498e38dba4018e7ce3e5fe631c83842cd9059e23a7fece366d87@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"Ohgrd0rA+p1uoEcgyulyuuDLudlnOJGrq4rhfkY+WC8=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 3a182b\npopulation: 25 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 7 9493 caa3 cba4 d717 | 134 af8f (0) ac62 (0) a9df (0) a936 (0)\n001 2 57ee 44c8 | 50 60bc (0) 63de (0) 65a6 (0) 6701 (0)\n002 1 1a8e | 37 0305 (0) 020f (0) 0020 (0) 00c8 (0)\n003 4 2220 208e 2a7d 2cb1 | 15 24f8 (0) 2737 (0) 208e (0) 2224 (0)\n004 2 3734 3227 | 10 34e4 (0) 3658 (0) 3607 (0) 3799 (0)\n005 4 3d17 3c5a 3ff8 3ef6 | 4 3c5a (0) 3d17 (0) 3ff8 (0) 3ef6 (0)\n006 3 398b 38d7 3843 | 3 398b (0) 38d7 (0) 3843 (0)\n============ DEPTH: 7 ==========================================\n007 1 3baa | 1 3baa (0)\n008 1 3ab2 | 1 3ab2 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"4de378164d77a28c90cf162dd1b465e0282ee17aa7d3bb3179252466f72da33a36c9f298f7c9498e38dba4018e7ce3e5fe631c83842cd9059e23a7fece366d87","private_key":"a8e588af7acfd6024b3d71be7be630345ca80708a69214fd31e3b4485f039c90","name":"node_4de378164d77a28c90cf162dd1b465e0282ee17aa7d3bb3179252466f72da33a36c9f298f7c9498e38dba4018e7ce3e5fe631c83842cd9059e23a7fece366d87","services":["streamer"],"enable_msg_events":true,"port":63295},"up":true}},{"node":{"info":{"id":"155e4879643a472420012e040a87dbff776fc1976814c0c6cd0d5e157f0d0baac04aa7f2535786c09acc2700547383d2119b64a6f62115f1aff1708738844d8c","name":"node_155e4879643a472420012e040a87dbff776fc1976814c0c6cd0d5e157f0d0baac04aa7f2535786c09acc2700547383d2119b64a6f62115f1aff1708738844d8c","enode":"enode://155e4879643a472420012e040a87dbff776fc1976814c0c6cd0d5e157f0d0baac04aa7f2535786c09acc2700547383d2119b64a6f62115f1aff1708738844d8c@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"2tNbk3plAfzXSDRn2BKWpshUHe+I0M5FpwKh0XJb9Wc=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: dad35b\npopulation: 26 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 57ee 5cae 3a18 2cb1 | 122 6f1c (0) 6caa (0) 6923 (0) 69d8 (0)\n001 2 9404 9493 | 63 af8f (0) ac62 (0) aa78 (0) a9df (0)\n002 5 ec78 efc1 eee1 e3d8 | 38 e724 (0) e6b7 (0) e5d2 (0) e54d (0)\n003 3 c409 cbd3 cba4 | 14 c301 (0) c3d8 (0) c7fa (0) c60e (0)\n004 8 d044 d35c d2ac d560 | 14 d1bc (0) d0b7 (0) d07c (0) d044 (0)\n005 2 de1d df52 | 2 df52 (0) de1d (0)\n============ DEPTH: 6 ==========================================\n006 2 d96e d90b | 2 d96e (0) d90b (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"155e4879643a472420012e040a87dbff776fc1976814c0c6cd0d5e157f0d0baac04aa7f2535786c09acc2700547383d2119b64a6f62115f1aff1708738844d8c","private_key":"e3d1a9d4621d7f77d9c2fa224f0d8c8211c2bf461554a1d50afa8f34a82a4754","name":"node_155e4879643a472420012e040a87dbff776fc1976814c0c6cd0d5e157f0d0baac04aa7f2535786c09acc2700547383d2119b64a6f62115f1aff1708738844d8c","services":["streamer"],"enable_msg_events":true,"port":63296},"up":true}},{"node":{"info":{"id":"81288bb0584b7ffc1546043e052e1df10fd5371b35dedd0bb42ec5b30ce69b741b2f7857af5984d4754b39d7253575fde9298504999b78380ef602d391c4bb1d","name":"node_81288bb0584b7ffc1546043e052e1df10fd5371b35dedd0bb42ec5b30ce69b741b2f7857af5984d4754b39d7253575fde9298504999b78380ef602d391c4bb1d","enode":"enode://81288bb0584b7ffc1546043e052e1df10fd5371b35dedd0bb42ec5b30ce69b741b2f7857af5984d4754b39d7253575fde9298504999b78380ef602d391c4bb1d@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"LLGKbdVkMJGztBU4uzLcQUeF/PGApcUfEMi7zbxqeEc=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 2cb18a\npopulation: 26 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 5 ec78 f293 cba4 d717 | 134 aa78 (0) a936 (0) a9df (0) af8f (0)\n001 4 77bc 57ee 5cae 44c8 | 50 7ec4 (0) 7e45 (0) 7810 (0) 7aef (0)\n002 2 1a8e 0d97 | 37 11a0 (0) 10b1 (0) 1254 (0) 1587 (0)\n003 5 3227 3734 3ef6 3843 | 20 34e4 (0) 3658 (0) 3607 (0) 3799 (0)\n004 2 2220 2737 | 5 24f8 (0) 2737 (0) 208e (0) 2224 (0)\n005 2 2940 2a7d | 3 293f (0) 2940 (0) 2a7d (0)\n006 3 2f23 2f1f 2e3b | 3 2e3b (0) 2f23 (0) 2f1f (0)\n007 0 | 0\n============ DEPTH: 8 ==========================================\n008 2 2c16 2c4e | 2 2c16 (0) 2c4e (0)\n009 0 | 0\n010 0 | 0\n011 1 2cab | 1 2cab (0)\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"81288bb0584b7ffc1546043e052e1df10fd5371b35dedd0bb42ec5b30ce69b741b2f7857af5984d4754b39d7253575fde9298504999b78380ef602d391c4bb1d","private_key":"6522d077629e8c313d832a7a87e5dce9e989618cd1eff1b1eb3c8b63756159e5","name":"node_81288bb0584b7ffc1546043e052e1df10fd5371b35dedd0bb42ec5b30ce69b741b2f7857af5984d4754b39d7253575fde9298504999b78380ef602d391c4bb1d","services":["streamer"],"enable_msg_events":true,"port":63297},"up":true}},{"node":{"info":{"id":"109556abac422a912ecffec0d8796f8f16e92e8f95cecf72dc89e97a8bf1fd37aad3c66aa3cf134acade6d065c31821f977171d5c5463305b57ce3eee99a7ab4","name":"node_109556abac422a912ecffec0d8796f8f16e92e8f95cecf72dc89e97a8bf1fd37aad3c66aa3cf134acade6d065c31821f977171d5c5463305b57ce3eee99a7ab4","enode":"enode://109556abac422a912ecffec0d8796f8f16e92e8f95cecf72dc89e97a8bf1fd37aad3c66aa3cf134acade6d065c31821f977171d5c5463305b57ce3eee99a7ab4@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"1xc3eu0J2bDU8HKr0T9J0+T2T9jsQKpFpH0Q/ccW4iU=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: d71737\npopulation: 22 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 3a18 2cb1 5cae 44c8 | 122 11a0 (0) 10b1 (0) 1254 (0) 14e4 (0)\n001 2 9493 b30e | 63 af8f (0) ac62 (0) a9df (0) a936 (0)\n002 4 fd3f f293 efc1 e3d8 | 38 f97e (0) ffb7 (0) fc88 (0) fd44 (0)\n003 2 cba4 cbd3 | 14 c301 (0) c3d8 (0) c409 (0) c7fa (0)\n004 2 de1d dad3 | 5 df52 (0) de1d (0) d90b (0) d96e (0)\n005 2 d1bc d2ac | 7 d1bc (0) d0b7 (0) d07c (0) d044 (0)\n006 2 d560 d455 | 2 d560 (0) d455 (0)\n007 2 d66f d606 | 2 d66f (0) d606 (0)\n============ DEPTH: 8 ==========================================\n008 1 d7c1 | 1 d7c1 (0)\n009 1 d777 | 1 d777 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"109556abac422a912ecffec0d8796f8f16e92e8f95cecf72dc89e97a8bf1fd37aad3c66aa3cf134acade6d065c31821f977171d5c5463305b57ce3eee99a7ab4","private_key":"f90016392c8768d222055de5cd1c3a512d3c46b7c7be34a93cbd016aea9ce753","name":"node_109556abac422a912ecffec0d8796f8f16e92e8f95cecf72dc89e97a8bf1fd37aad3c66aa3cf134acade6d065c31821f977171d5c5463305b57ce3eee99a7ab4","services":["streamer"],"enable_msg_events":true,"port":63298},"up":true}},{"node":{"info":{"id":"759f46661056bcbb30c7706c9fb87e22a30feb523bd53ae5d18db043efa45b49a2b8982abebdd598fe0912a05896390ec2eabe5e160cbafc0771990708ad8c28","name":"node_759f46661056bcbb30c7706c9fb87e22a30feb523bd53ae5d18db043efa45b49a2b8982abebdd598fe0912a05896390ec2eabe5e160cbafc0771990708ad8c28","enode":"enode://759f46661056bcbb30c7706c9fb87e22a30feb523bd53ae5d18db043efa45b49a2b8982abebdd598fe0912a05896390ec2eabe5e160cbafc0771990708ad8c28@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"RMjCYgT+WgpIxiRmvoB5pgtEW0OBQiJCWE2OGRjN50g=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 44c8c2\npopulation: 25 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 5 fd3f e3d8 cbd3 cba4 | 134 a478 (0) a75d (0) a6bd (0) a3f2 (0)\n001 5 3a18 2a7d 2cb1 05a4 | 72 09d1 (0) 0bc3 (0) 0ad6 (0) 0a3f (0)\n002 3 77bc 6caa 69d8 | 19 7ec4 (0) 7e45 (0) 7810 (0) 7aef (0)\n003 4 5741 57ee 5a67 5cae | 15 510c (0) 5070 (0) 5062 (0) 5399 (0)\n004 3 4dc4 4bbc 4bf8 | 8 4c97 (0) 4dc4 (0) 48df (0) 48ec (0)\n005 2 41b2 43fb | 4 413b (0) 41b2 (0) 42d6 (0) 43fb (0)\n============ DEPTH: 6 ==========================================\n006 2 464b 47a8 | 2 464b (0) 47a8 (0)\n007 0 | 0\n008 0 | 0\n009 1 44b7 | 1 44b7 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"759f46661056bcbb30c7706c9fb87e22a30feb523bd53ae5d18db043efa45b49a2b8982abebdd598fe0912a05896390ec2eabe5e160cbafc0771990708ad8c28","private_key":"49f3b1f88009b94bc7beef8d891816672e9075f3015f5954a9ae9d13c8c07290","name":"node_759f46661056bcbb30c7706c9fb87e22a30feb523bd53ae5d18db043efa45b49a2b8982abebdd598fe0912a05896390ec2eabe5e160cbafc0771990708ad8c28","services":["streamer"],"enable_msg_events":true,"port":63299},"up":true}},{"node":{"info":{"id":"baa5924e1547c177011285d292aa161a15e5ff282da2cd0afb83c9caffb07bdbb3662c227fa7b26e6dc8be9b8863e647eb5f8ce81640532f8f5c9a7f36557e63","name":"node_baa5924e1547c177011285d292aa161a15e5ff282da2cd0afb83c9caffb07bdbb3662c227fa7b26e6dc8be9b8863e647eb5f8ce81640532f8f5c9a7f36557e63","enode":"enode://baa5924e1547c177011285d292aa161a15e5ff282da2cd0afb83c9caffb07bdbb3662c227fa7b26e6dc8be9b8863e647eb5f8ce81640532f8f5c9a7f36557e63@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"XK6mygRsXi08niOJYAw20/66gKRVlEhCwutVxbFEMYo=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 5caea6\npopulation: 24 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 6 dad3 d717 cba4 cbd3 | 134 8d85 (0) 8d3c (0) 8ee7 (0) 8ea9 (0)\n001 5 1a8e 05a4 3ff8 2cb1 | 72 14e4 (0) 15ec (0) 1587 (0) 1758 (0)\n002 1 69d8 | 19 7239 (0) 7299 (0) 71bf (0) 715b (0)\n003 3 4bf8 41b2 44c8 | 16 4c97 (0) 4dc4 (0) 48df (0) 48ec (0)\n004 4 5399 57ee 5765 5741 | 9 5070 (0) 5062 (0) 510c (0) 5237 (0)\n005 3 581a 5b30 5a67 | 3 581a (0) 5b30 (0) 5a67 (0)\n============ DEPTH: 6 ==========================================\n006 1 5e3e | 1 5e3e (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 1 5c9b | 1 5c9b (0)\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"baa5924e1547c177011285d292aa161a15e5ff282da2cd0afb83c9caffb07bdbb3662c227fa7b26e6dc8be9b8863e647eb5f8ce81640532f8f5c9a7f36557e63","private_key":"65f5fa03f2989a02e37bb664102504038f14adb483b2116b07355296346912f7","name":"node_baa5924e1547c177011285d292aa161a15e5ff282da2cd0afb83c9caffb07bdbb3662c227fa7b26e6dc8be9b8863e647eb5f8ce81640532f8f5c9a7f36557e63","services":["streamer"],"enable_msg_events":true,"port":63300},"up":true}},{"node":{"info":{"id":"deb7af800cd20a647335f0feff5bfb3e182f99f4c2d1ade10da36ecfdbac3b5fba4e8f0a4595443fe395b44af3a95617669850944655def85d57cc81c5682a3b","name":"node_deb7af800cd20a647335f0feff5bfb3e182f99f4c2d1ade10da36ecfdbac3b5fba4e8f0a4595443fe395b44af3a95617669850944655def85d57cc81c5682a3b","enode":"enode://deb7af800cd20a647335f0feff5bfb3e182f99f4c2d1ade10da36ecfdbac3b5fba4e8f0a4595443fe395b44af3a95617669850944655def85d57cc81c5682a3b@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"49jL2IQFCQNPCBhZQivFmXUPpPBA0vkDArlRO0M4R/g=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: e3d8cb\npopulation: 24 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 44c8 5cae | 122 11a0 (0) 10b1 (0) 1254 (0) 14e4 (0)\n001 1 b30e | 63 9f4c (0) 9a09 (0) 9b87 (0) 9bc3 (0)\n002 5 d606 d717 dad3 cba4 | 33 d1bc (0) d0b7 (0) d07c (0) d044 (0)\n003 4 f2b2 f293 fd44 fd3f | 13 f6a6 (0) f054 (0) f0b8 (0) f1ad (0)\n004 7 ebe8 ec78 efc1 efdd | 12 e9fa (0) e850 (0) ebc9 (0) ebe8 (0)\n005 2 e4d6 e56c | 9 e724 (0) e6b7 (0) e5d2 (0) e54d (0)\n006 1 e190 | 1 e190 (0)\n============ DEPTH: 7 ==========================================\n007 1 e255 | 1 e255 (0)\n008 1 e31e | 1 e31e (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"deb7af800cd20a647335f0feff5bfb3e182f99f4c2d1ade10da36ecfdbac3b5fba4e8f0a4595443fe395b44af3a95617669850944655def85d57cc81c5682a3b","private_key":"87514536801d0d46fcca5c10334c9a6a34ad982fbbcf65b2f881e99a0c8ab27e","name":"node_deb7af800cd20a647335f0feff5bfb3e182f99f4c2d1ade10da36ecfdbac3b5fba4e8f0a4595443fe395b44af3a95617669850944655def85d57cc81c5682a3b","services":["streamer"],"enable_msg_events":true,"port":63301},"up":true}},{"node":{"info":{"id":"17917fa4da06068b587c17899569dcc768b9cd2c27117a4ed67aab26a7e70cf8d32b881db258061ffd89a332a3b29bfd963d8e171a06c3e208ba0de1c42a2b39","name":"node_17917fa4da06068b587c17899569dcc768b9cd2c27117a4ed67aab26a7e70cf8d32b881db258061ffd89a332a3b29bfd963d8e171a06c3e208ba0de1c42a2b39","enode":"enode://17917fa4da06068b587c17899569dcc768b9cd2c27117a4ed67aab26a7e70cf8d32b881db258061ffd89a332a3b29bfd963d8e171a06c3e208ba0de1c42a2b39@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"y9PcQWzWRmh9LMA3O9159E139e53XimKCD2MYr4kjzw=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: cbd3dc\npopulation: 25 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 44c8 5cae 1a8e | 122 63de (0) 60bc (0) 6701 (0) 67ee (0)\n001 2 9641 9493 | 63 a9df (0) a936 (0) aa78 (0) af8f (0)\n002 5 f2b2 f293 fd3f eee1 | 38 e9fa (0) e850 (0) ebc9 (0) ebe8 (0)\n003 5 dad3 d35c d2ac d606 | 19 de1d (0) df52 (0) d90b (0) d96e (0)\n004 3 c3d8 c60e c409 | 5 c301 (0) c3d8 (0) c7fa (0) c60e (0)\n005 2 cf77 ce71 | 2 cf77 (0) ce71 (0)\n006 2 c911 c95a | 3 c914 (0) c911 (0) c95a (0)\n============ DEPTH: 7 ==========================================\n007 2 caa3 ca8c | 2 ca8c (0) caa3 (0)\n008 0 | 0\n009 1 cba4 | 1 cba4 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"17917fa4da06068b587c17899569dcc768b9cd2c27117a4ed67aab26a7e70cf8d32b881db258061ffd89a332a3b29bfd963d8e171a06c3e208ba0de1c42a2b39","private_key":"c69b71039aa3f28c158e5e639d35069ee66cc88565ae886e75651d88fae8aacf","name":"node_17917fa4da06068b587c17899569dcc768b9cd2c27117a4ed67aab26a7e70cf8d32b881db258061ffd89a332a3b29bfd963d8e171a06c3e208ba0de1c42a2b39","services":["streamer"],"enable_msg_events":true,"port":63302},"up":true}},{"node":{"info":{"id":"032b9bf2f59f15571821611d3ee541aa748c86d47fbe5f049fd0069be53e5d7c41991d82957e9c727654c3aa73ec94997c03d8a6c1d2007c9bb1a703f6215158","name":"node_032b9bf2f59f15571821611d3ee541aa748c86d47fbe5f049fd0069be53e5d7c41991d82957e9c727654c3aa73ec94997c03d8a6c1d2007c9bb1a703f6215158","enode":"enode://032b9bf2f59f15571821611d3ee541aa748c86d47fbe5f049fd0069be53e5d7c41991d82957e9c727654c3aa73ec94997c03d8a6c1d2007c9bb1a703f6215158@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"Go7L3oi+Iqm7tfPvGb5Td5I9ZV/ZzYOPnQikQmFHQsM=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 1a8ecb\npopulation: 18 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 cbd3 | 134 af8f (0) ac62 (0) a9df (0) a936 (0)\n001 2 5cae 44c8 | 50 63de (0) 60bc (0) 65a6 (0) 6701 (0)\n002 4 3a18 2cab 2cb1 2a7d | 35 34e4 (0) 3658 (0) 3607 (0) 3799 (0)\n003 2 0d97 05a4 | 18 09d1 (0) 0bc3 (0) 0a3f (0) 0ad6 (0)\n004 2 15ec 1254 | 9 14e4 (0) 15ec (0) 1587 (0) 1758 (0)\n005 4 1ea1 1fab 1dfd 1d5b | 6 1ea1 (0) 1fab (0) 1dfd (0) 1dfc (0)\n006 1 1953 | 1 1953 (0)\n007 0 | 0\n008 0 | 0\n============ DEPTH: 9 ==========================================\n009 1 1af6 | 1 1af6 (0)\n010 0 | 0\n011 0 | 0\n012 1 1a85 | 1 1a85 (0)\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"032b9bf2f59f15571821611d3ee541aa748c86d47fbe5f049fd0069be53e5d7c41991d82957e9c727654c3aa73ec94997c03d8a6c1d2007c9bb1a703f6215158","private_key":"76998bb1133735934b6d8cbebf029318feaf9b103165cd460a4a9ae04ad26c5d","name":"node_032b9bf2f59f15571821611d3ee541aa748c86d47fbe5f049fd0069be53e5d7c41991d82957e9c727654c3aa73ec94997c03d8a6c1d2007c9bb1a703f6215158","services":["streamer"],"enable_msg_events":true,"port":63303},"up":true}},{"node":{"info":{"id":"be026dfb24847cac2d00f483104edad06ca8ecb9e1229c479ef5650c7b427cd5dc34a1cf06172c17c9d0406ce17009712e82446394743d4cd9bbc41c537ebc14","name":"node_be026dfb24847cac2d00f483104edad06ca8ecb9e1229c479ef5650c7b427cd5dc34a1cf06172c17c9d0406ce17009712e82446394743d4cd9bbc41c537ebc14","enode":"enode://be026dfb24847cac2d00f483104edad06ca8ecb9e1229c479ef5650c7b427cd5dc34a1cf06172c17c9d0406ce17009712e82446394743d4cd9bbc41c537ebc14@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"BaR3jhvn2pScGnv/o0CAILZrTuPJjh9i410hLHfoOto=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 05a477\npopulation: 15 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 b30e | 134 df52 (0) de1d (0) d90b (0) d96e (0)\n001 2 5cae 44c8 | 50 7aef (0) 7810 (0) 7e45 (0) 7ec4 (0)\n002 2 3ff8 2a7d | 35 34e4 (0) 3607 (0) 3658 (0) 3799 (0)\n003 4 1254 1953 1a85 1a8e | 19 11a0 (0) 10b1 (0) 1254 (0) 14e4 (0)\n004 3 0c72 0c19 0d97 | 11 09d1 (0) 0bc3 (0) 0a3f (0) 0ad6 (0)\n005 1 00c8 | 4 0305 (0) 020f (0) 0020 (0) 00c8 (0)\n============ DEPTH: 6 ==========================================\n006 1 07a6 | 1 07a6 (0)\n007 0 | 0\n008 1 0536 | 1 0536 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"be026dfb24847cac2d00f483104edad06ca8ecb9e1229c479ef5650c7b427cd5dc34a1cf06172c17c9d0406ce17009712e82446394743d4cd9bbc41c537ebc14","private_key":"424a19356346001136b4df8a6119a510d526b508d0378eb5b67ffbc471757c08","name":"node_be026dfb24847cac2d00f483104edad06ca8ecb9e1229c479ef5650c7b427cd5dc34a1cf06172c17c9d0406ce17009712e82446394743d4cd9bbc41c537ebc14","services":["streamer"],"enable_msg_events":true,"port":63304},"up":true}},{"node":{"info":{"id":"389b5c1a805f87427e6d647ec5488342a3f7d700615943d5ad98ca5c111f33c7ee007970b4d3e475892095c0d5a79b7ed52d12598398818159000d4b9b719126","name":"node_389b5c1a805f87427e6d647ec5488342a3f7d700615943d5ad98ca5c111f33c7ee007970b4d3e475892095c0d5a79b7ed52d12598398818159000d4b9b719126","enode":"enode://389b5c1a805f87427e6d647ec5488342a3f7d700615943d5ad98ca5c111f33c7ee007970b4d3e475892095c0d5a79b7ed52d12598398818159000d4b9b719126@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"sw7tUalYqCJSixJkcc9wiEJKeROl6J1qr5iclooMS+k=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: b30eed\npopulation: 24 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 69d8 05a4 | 122 7e45 (0) 7ec4 (0) 7810 (0) 7aef (0)\n001 6 d606 d717 cba4 e3d8 | 71 de1d (0) df52 (0) d96e (0) d90b (0)\n002 5 98bc 99eb 93f8 9108 | 33 83d0 (0) 802f (0) 802e (0) 8434 (0)\n003 5 aa78 ac62 a6bd a0e4 | 17 a478 (0) a6bd (0) a75d (0) a3f2 (0)\n004 2 bd39 beb7 | 7 b820 (0) bb31 (0) bbcb (0) baaf (0)\n005 2 b45f b40d | 3 b7aa (0) b45f (0) b40d (0)\n============ DEPTH: 6 ==========================================\n006 1 b049 | 1 b049 (0)\n007 0 | 0\n008 1 b391 | 1 b391 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"389b5c1a805f87427e6d647ec5488342a3f7d700615943d5ad98ca5c111f33c7ee007970b4d3e475892095c0d5a79b7ed52d12598398818159000d4b9b719126","private_key":"06aade0419624ec355a3e8e47144b1efd1853293246628e0d3ce856bf3bb64be","name":"node_389b5c1a805f87427e6d647ec5488342a3f7d700615943d5ad98ca5c111f33c7ee007970b4d3e475892095c0d5a79b7ed52d12598398818159000d4b9b719126","services":["streamer"],"enable_msg_events":true,"port":63305},"up":true}},{"node":{"info":{"id":"c57ea182bdb42ba9b0870b5c870e467f52693e5c0df752fb6eb0dfbacce7763f73caee10db40f4fd90f19f504ee586eaf9da41f5ee93ee515d885fec99374116","name":"node_c57ea182bdb42ba9b0870b5c870e467f52693e5c0df752fb6eb0dfbacce7763f73caee10db40f4fd90f19f504ee586eaf9da41f5ee93ee515d885fec99374116","enode":"enode://c57ea182bdb42ba9b0870b5c870e467f52693e5c0df752fb6eb0dfbacce7763f73caee10db40f4fd90f19f504ee586eaf9da41f5ee93ee515d885fec99374116@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"/T/LMn4ZiMR4ba1FpuMlsvqe8H7mJyGqXNr9VSm9El0=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: fd3fcb\npopulation: 26 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 5 69d8 44c8 5cae 0d97 | 122 7ec4 (0) 7e45 (0) 7aef (0) 7810 (0)\n001 3 9641 99eb b30e | 63 8d85 (0) 8d3c (0) 8ea9 (0) 8ee7 (0)\n002 5 d717 d606 c911 cba4 | 33 de1d (0) df52 (0) d96e (0) d90b (0)\n003 3 e850 e255 e3d8 | 25 e9fa (0) e850 (0) ebc9 (0) ebe8 (0)\n004 6 f6a6 f054 f1b9 f2f5 | 8 f6a6 (0) f0b8 (0) f054 (0) f1ad (0)\n005 1 f97e | 1 f97e (0)\n006 1 ffb7 | 1 ffb7 (0)\n============ DEPTH: 7 ==========================================\n007 1 fc88 | 1 fc88 (0)\n008 0 | 0\n009 1 fd44 | 1 fd44 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"c57ea182bdb42ba9b0870b5c870e467f52693e5c0df752fb6eb0dfbacce7763f73caee10db40f4fd90f19f504ee586eaf9da41f5ee93ee515d885fec99374116","private_key":"903c726d393f3a34e861aee6a1b42ea078da78c23d1dcdbd0fd8c30e80b65bf1","name":"node_c57ea182bdb42ba9b0870b5c870e467f52693e5c0df752fb6eb0dfbacce7763f73caee10db40f4fd90f19f504ee586eaf9da41f5ee93ee515d885fec99374116","services":["streamer"],"enable_msg_events":true,"port":63306},"up":true}},{"node":{"info":{"id":"2ac93c31937ca205d61cc5c2a1b9037871cac55e9b306b999b28e19566b3316f6539455e014840ea50c2db8a7c97d78804d3a2dcd7cd9c1f32ace0d36e5dd339","name":"node_2ac93c31937ca205d61cc5c2a1b9037871cac55e9b306b999b28e19566b3316f6539455e014840ea50c2db8a7c97d78804d3a2dcd7cd9c1f32ace0d36e5dd339","enode":"enode://2ac93c31937ca205d61cc5c2a1b9037871cac55e9b306b999b28e19566b3316f6539455e014840ea50c2db8a7c97d78804d3a2dcd7cd9c1f32ace0d36e5dd339@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"Kn0TFtpR/F4TeDZqVDpz/EDbHrc1Wz4ZnuI3zB24Gr8=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 2a7d13\npopulation: 22 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 e255 fd3f cba4 | 134 8d85 (0) 8d3c (0) 8ea9 (0) 8ee7 (0)\n001 4 69d8 44c8 44b7 5cae | 50 7ec4 (0) 7e45 (0) 7810 (0) 7aef (0)\n002 5 1a8e 0c72 0d97 00c8 | 37 11a0 (0) 10b1 (0) 1254 (0) 14e4 (0)\n003 2 3a18 3843 | 20 34e4 (0) 3658 (0) 3607 (0) 3799 (0)\n004 3 2220 2224 2737 | 5 24f8 (0) 2737 (0) 208e (0) 2224 (0)\n005 3 2e3b 2cb1 2cab | 7 2f1f (0) 2f23 (0) 2e3b (0) 2c16 (0)\n============ DEPTH: 6 ==========================================\n006 2 293f 2940 | 2 293f (0) 2940 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"2ac93c31937ca205d61cc5c2a1b9037871cac55e9b306b999b28e19566b3316f6539455e014840ea50c2db8a7c97d78804d3a2dcd7cd9c1f32ace0d36e5dd339","private_key":"29f2f00196b61b834638899c2e440c57b99668fbd93d7eed220c4556a76cf89e","name":"node_2ac93c31937ca205d61cc5c2a1b9037871cac55e9b306b999b28e19566b3316f6539455e014840ea50c2db8a7c97d78804d3a2dcd7cd9c1f32ace0d36e5dd339","services":["streamer"],"enable_msg_events":true,"port":63307},"up":true}},{"node":{"info":{"id":"ca1aff0d847c6fdacb623ad9078a0885b3208614fea20d5ff11779779b486bf5e9c794aacf848d3c2d58cfcc1eda8356df82f5fbdd0a5236beffe8e6042848c4","name":"node_ca1aff0d847c6fdacb623ad9078a0885b3208614fea20d5ff11779779b486bf5e9c794aacf848d3c2d58cfcc1eda8356df82f5fbdd0a5236beffe8e6042848c4","enode":"enode://ca1aff0d847c6fdacb623ad9078a0885b3208614fea20d5ff11779779b486bf5e9c794aacf848d3c2d58cfcc1eda8356df82f5fbdd0a5236beffe8e6042848c4@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"y6RARtaTYpqHKiKBLrzJkZ3dgUjscIWyO7uCjyWLSPI=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: cba440\npopulation: 33 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 7 69d8 44c8 5cae 3a18 | 122 4c97 (0) 4dc4 (0) 48df (0) 48ec (0)\n001 4 98bc 99eb 9641 b30e | 63 a936 (0) a9df (0) aa78 (0) af8f (0)\n002 7 f2f5 f2b2 fd3f ec78 | 38 f6a6 (0) f0b8 (0) f054 (0) f1ad (0)\n003 4 dad3 d2ac d717 d606 | 19 df52 (0) de1d (0) d96e (0) d90b (0)\n004 3 c3d8 c409 c60e | 5 c301 (0) c3d8 (0) c409 (0) c7fa (0)\n005 2 ce71 cf77 | 2 ce71 (0) cf77 (0)\n006 3 c95a c914 c911 | 3 c95a (0) c914 (0) c911 (0)\n============ DEPTH: 7 ==========================================\n007 2 caa3 ca8c | 2 ca8c (0) caa3 (0)\n008 0 | 0\n009 1 cbd3 | 1 cbd3 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"ca1aff0d847c6fdacb623ad9078a0885b3208614fea20d5ff11779779b486bf5e9c794aacf848d3c2d58cfcc1eda8356df82f5fbdd0a5236beffe8e6042848c4","private_key":"682a2f9130cdf75915282000edc627563ea4e9de499ddc8d55efad472a94091b","name":"node_ca1aff0d847c6fdacb623ad9078a0885b3208614fea20d5ff11779779b486bf5e9c794aacf848d3c2d58cfcc1eda8356df82f5fbdd0a5236beffe8e6042848c4","services":["streamer"],"enable_msg_events":true,"port":63308},"up":true}},{"node":{"info":{"id":"2e409baefbd821485a151993356730e5989810d581e68190fbaa142799c9335bcf98310ad188fed10ae6eb6e2e789730393e509962ec5c0fef0342d72ed088d9","name":"node_2e409baefbd821485a151993356730e5989810d581e68190fbaa142799c9335bcf98310ad188fed10ae6eb6e2e789730393e509962ec5c0fef0342d72ed088d9","enode":"enode://2e409baefbd821485a151993356730e5989810d581e68190fbaa142799c9335bcf98310ad188fed10ae6eb6e2e789730393e509962ec5c0fef0342d72ed088d9@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"DZeCf26oUMMQwxJZjr4aks6uCNHgVcoXDx4wX4Nro5g=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 0d9782\npopulation: 22 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 5 e255 f2b2 fd3f cba4 | 134 aa78 (0) a936 (0) a9df (0) af8f (0)\n001 1 69d8 | 50 4c97 (0) 4dc4 (0) 48df (0) 48ec (0)\n002 2 2cb1 2a7d | 35 34e4 (0) 3607 (0) 3658 (0) 3799 (0)\n003 2 167b 1a8e | 19 11a0 (0) 10b1 (0) 1254 (0) 14e4 (0)\n004 3 00c8 0536 05a4 | 7 0305 (0) 020f (0) 0020 (0) 00c8 (0)\n005 3 09d1 0a3f 0ad6 | 4 09d1 (0) 0bc3 (0) 0ad6 (0) 0a3f (0)\n006 2 0fa0 0f65 | 2 0fa0 (0) 0f65 (0)\n============ DEPTH: 7 ==========================================\n007 3 0ca9 0c19 0c72 | 3 0ca9 (0) 0c19 (0) 0c72 (0)\n008 0 | 0\n009 0 | 0\n010 1 0daf | 1 0daf (0)\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"2e409baefbd821485a151993356730e5989810d581e68190fbaa142799c9335bcf98310ad188fed10ae6eb6e2e789730393e509962ec5c0fef0342d72ed088d9","private_key":"d1b4b3adc1b17a79626152a1c7362bddd7c47886990759955595a1de27f7b70b","name":"node_2e409baefbd821485a151993356730e5989810d581e68190fbaa142799c9335bcf98310ad188fed10ae6eb6e2e789730393e509962ec5c0fef0342d72ed088d9","services":["streamer"],"enable_msg_events":true,"port":63309},"up":true}},{"node":{"info":{"id":"7b5c0e81c7f4e3ae29d745f6028cfa10b29a16a9c261b65fb8dd05d6eccc634612ad5d3029c8e9f39863a2cdb2682c25f090139bf5c4950e25647e39dcb40e63","name":"node_7b5c0e81c7f4e3ae29d745f6028cfa10b29a16a9c261b65fb8dd05d6eccc634612ad5d3029c8e9f39863a2cdb2682c25f090139bf5c4950e25647e39dcb40e63","enode":"enode://7b5c0e81c7f4e3ae29d745f6028cfa10b29a16a9c261b65fb8dd05d6eccc634612ad5d3029c8e9f39863a2cdb2682c25f090139bf5c4950e25647e39dcb40e63@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"1gZE+2nt8dNgpbPUgAMN+XYAo9lKGJ2pi1jEN1jJgzE=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: d60644\npopulation: 20 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 69d8 0d97 | 122 4c97 (0) 4dc4 (0) 48df (0) 48ec (0)\n001 2 b30e 9641 | 63 a9df (0) a936 (0) aa78 (0) af8f (0)\n002 4 e3d8 e255 f2b2 fd3f | 38 f97e (0) ffb7 (0) fc88 (0) fd44 (0)\n003 3 c911 cbd3 cba4 | 14 c301 (0) c3d8 (0) c409 (0) c7fa (0)\n004 1 dad3 | 5 de1d (0) df52 (0) d90b (0) d96e (0)\n005 2 d3bd d2ac | 7 d1bc (0) d0b7 (0) d07c (0) d044 (0)\n006 2 d455 d560 | 2 d455 (0) d560 (0)\n============ DEPTH: 7 ==========================================\n007 3 d7c1 d777 d717 | 3 d7c1 (0) d777 (0) d717 (0)\n008 0 | 0\n009 1 d66f | 1 d66f (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"7b5c0e81c7f4e3ae29d745f6028cfa10b29a16a9c261b65fb8dd05d6eccc634612ad5d3029c8e9f39863a2cdb2682c25f090139bf5c4950e25647e39dcb40e63","private_key":"34a5057b2a2c507010da7a091827d28ddba4f59c9b5f15f7cb7bf0578e4141c3","name":"node_7b5c0e81c7f4e3ae29d745f6028cfa10b29a16a9c261b65fb8dd05d6eccc634612ad5d3029c8e9f39863a2cdb2682c25f090139bf5c4950e25647e39dcb40e63","services":["streamer"],"enable_msg_events":true,"port":63310},"up":true}},{"node":{"info":{"id":"663535b22018a4ef0b151572ef286fa66c22c6e9b2913a69c4a735d4b0149bdf6c84bd83d710f8aa2627e8993b7f020750fbc6f56a3365ce4c840e2b3de1a6c1","name":"node_663535b22018a4ef0b151572ef286fa66c22c6e9b2913a69c4a735d4b0149bdf6c84bd83d710f8aa2627e8993b7f020750fbc6f56a3365ce4c840e2b3de1a6c1","enode":"enode://663535b22018a4ef0b151572ef286fa66c22c6e9b2913a69c4a735d4b0149bdf6c84bd83d710f8aa2627e8993b7f020750fbc6f56a3365ce4c840e2b3de1a6c1@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"adiAH58Z/sUbY2zCf8osk+Z9rI82UK6jUlnQEpPVyeY=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 69d880\npopulation: 18 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 6 fd3f cba4 d606 b30e | 134 f97e (0) ffb7 (0) fc88 (0) fd44 (0)\n001 2 2a7d 0d97 | 72 34e4 (0) 3658 (0) 3607 (0) 3799 (0)\n002 3 5a67 5cae 44c8 | 31 4c97 (0) 4dc4 (0) 48df (0) 48ec (0)\n003 2 7299 7aef | 10 7ec4 (0) 7e45 (0) 7810 (0) 7aef (0)\n004 2 65a6 67ee | 5 63de (0) 60bc (0) 65a6 (0) 6701 (0)\n============ DEPTH: 5 ==========================================\n005 2 6f1c 6caa | 2 6f1c (0) 6caa (0)\n006 0 | 0\n007 0 | 0\n008 1 6923 | 1 6923 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"663535b22018a4ef0b151572ef286fa66c22c6e9b2913a69c4a735d4b0149bdf6c84bd83d710f8aa2627e8993b7f020750fbc6f56a3365ce4c840e2b3de1a6c1","private_key":"7b608c298477c4687c50adba466567e19c08492da2684417c129d730caef7594","name":"node_663535b22018a4ef0b151572ef286fa66c22c6e9b2913a69c4a735d4b0149bdf6c84bd83d710f8aa2627e8993b7f020750fbc6f56a3365ce4c840e2b3de1a6c1","services":["streamer"],"enable_msg_events":true,"port":63311},"up":true}},{"node":{"info":{"id":"7b1e20217f594f87350542df31ff5ae8a635679bac7962d49c97e02190c644b673d03e7eba2626b45ca7ebf98d8a972dadbba02c18a8d2cbfc3e7a4cced5b4b7","name":"node_7b1e20217f594f87350542df31ff5ae8a635679bac7962d49c97e02190c644b673d03e7eba2626b45ca7ebf98d8a972dadbba02c18a8d2cbfc3e7a4cced5b4b7","enode":"enode://7b1e20217f594f87350542df31ff5ae8a635679bac7962d49c97e02190c644b673d03e7eba2626b45ca7ebf98d8a972dadbba02c18a8d2cbfc3e7a4cced5b4b7@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"lkGaJG9cpE8nltkczFWzrEd+F1TnTSAs3RM+a1uWBRs=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 96419a\npopulation: 18 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 69d8 | 122 34e4 (0) 3658 (0) 3607 (0) 3799 (0)\n001 6 cbd3 cba4 d606 f2b2 | 71 f97e (0) ffb7 (0) fc88 (0) fd44 (0)\n002 1 b30e | 30 a478 (0) a6bd (0) a75d (0) a317 (0)\n003 1 8ae8 | 15 83d0 (0) 802f (0) 802e (0) 8434 (0)\n004 3 99eb 98bc 9f4c | 10 9f4c (0) 9a09 (0) 9b87 (0) 9bc3 (0)\n005 3 9108 93f8 92d5 | 4 910d (0) 9108 (0) 93f8 (0) 92d5 (0)\n============ DEPTH: 6 ==========================================\n006 2 9404 9493 | 2 9404 (0) 9493 (0)\n007 1 9747 | 1 9747 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"7b1e20217f594f87350542df31ff5ae8a635679bac7962d49c97e02190c644b673d03e7eba2626b45ca7ebf98d8a972dadbba02c18a8d2cbfc3e7a4cced5b4b7","private_key":"d9d17f1baee1ccba3fea764f5f5797475ebb9f206d735105ba8fa2c32fe02f0d","name":"node_7b1e20217f594f87350542df31ff5ae8a635679bac7962d49c97e02190c644b673d03e7eba2626b45ca7ebf98d8a972dadbba02c18a8d2cbfc3e7a4cced5b4b7","services":["streamer"],"enable_msg_events":true,"port":63312},"up":true}},{"node":{"info":{"id":"84abcbc7b5598ecfd91ceace0927921a5a3404fdb274fc2a2549abbede5f8e4f62c15688a4dc9a2d80262c45970c88898da245c6eb779f327a81d53a17bbc74c","name":"node_84abcbc7b5598ecfd91ceace0927921a5a3404fdb274fc2a2549abbede5f8e4f62c15688a4dc9a2d80262c45970c88898da245c6eb779f327a81d53a17bbc74c","enode":"enode://84abcbc7b5598ecfd91ceace0927921a5a3404fdb274fc2a2549abbede5f8e4f62c15688a4dc9a2d80262c45970c88898da245c6eb779f327a81d53a17bbc74c@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"4lVNG/FF7A5wJ8qOi6DIX8aXvEtU42ps3FPx76N6ZjQ=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: e2554d\npopulation: 20 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 00c8 0d97 0c72 2a7d | 122 7ec4 (0) 7e45 (0) 7aef (0) 7810 (0)\n001 3 99eb 98bc 9641 | 63 a478 (0) a6bd (0) a75d (0) a317 (0)\n002 3 d606 c911 cba4 | 33 de1d (0) df52 (0) d90b (0) d96e (0)\n003 4 fd3f f1b9 f2f5 f2b2 | 13 f97e (0) ffb7 (0) fc88 (0) fd44 (0)\n004 2 ee52 efdd | 12 ebc9 (0) ebe8 (0) e9fa (0) e850 (0)\n005 1 e56c | 9 e724 (0) e6b7 (0) e5d2 (0) e54d (0)\n006 1 e190 | 1 e190 (0)\n============ DEPTH: 7 ==========================================\n007 2 e31e e3d8 | 2 e31e (0) e3d8 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"84abcbc7b5598ecfd91ceace0927921a5a3404fdb274fc2a2549abbede5f8e4f62c15688a4dc9a2d80262c45970c88898da245c6eb779f327a81d53a17bbc74c","private_key":"cea9931b34475ad432aecae3d385d895f0ab3e93cdf1d9fdbb356753ec9c7a59","name":"node_84abcbc7b5598ecfd91ceace0927921a5a3404fdb274fc2a2549abbede5f8e4f62c15688a4dc9a2d80262c45970c88898da245c6eb779f327a81d53a17bbc74c","services":["streamer"],"enable_msg_events":true,"port":63313},"up":true}},{"node":{"info":{"id":"eab86c521f8f1ac67c015ab713f1236a08b0200757a96bf87ab8301e7967ae62361f0e14da14ca294fc8cb3b4726b52f4773101e21b032977c6a647241b59c73","name":"node_eab86c521f8f1ac67c015ab713f1236a08b0200757a96bf87ab8301e7967ae62361f0e14da14ca294fc8cb3b4726b52f4773101e21b032977c6a647241b59c73","enode":"enode://eab86c521f8f1ac67c015ab713f1236a08b0200757a96bf87ab8301e7967ae62361f0e14da14ca294fc8cb3b4726b52f4773101e21b032977c6a647241b59c73@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"8rJHE7j4vKshCBvRfRHYWd1f+yHJut3Zcf3y1LUcGsY=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: f2b247\npopulation: 24 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 3843 0d97 0c72 00c8 | 122 56bb (0) 57ee (0) 5741 (0) 5765 (0)\n001 3 b30e 9641 99eb | 63 a478 (0) a75d (0) a6bd (0) a3f2 (0)\n002 4 d606 cbd3 cba4 c911 | 33 de1d (0) df52 (0) d96e (0) d90b (0)\n003 2 e3d8 e255 | 25 e9fa (0) e850 (0) ebc9 (0) ebe8 (0)\n004 4 ffb7 fc88 fd44 fd3f | 5 f97e (0) ffb7 (0) fc88 (0) fd44 (0)\n005 1 f6a6 | 1 f6a6 (0)\n006 4 f0b8 f054 f1ad f1b9 | 4 f0b8 (0) f054 (0) f1ad (0) f1b9 (0)\n007 0 | 0\n008 0 | 0\n============ DEPTH: 9 ==========================================\n009 1 f2f5 | 1 f2f5 (0)\n010 1 f293 | 1 f293 (0)\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"eab86c521f8f1ac67c015ab713f1236a08b0200757a96bf87ab8301e7967ae62361f0e14da14ca294fc8cb3b4726b52f4773101e21b032977c6a647241b59c73","private_key":"362c6622af8998cc3c5cf88ad71f308b632f8f7d0e8ea7ae341f8c8ad44cda5e","name":"node_eab86c521f8f1ac67c015ab713f1236a08b0200757a96bf87ab8301e7967ae62361f0e14da14ca294fc8cb3b4726b52f4773101e21b032977c6a647241b59c73","services":["streamer"],"enable_msg_events":true,"port":63314},"up":true}},{"node":{"info":{"id":"e6779e3bbecf81dde8b27d652ed2726c45c205db0d0405c4580014a4c91d739830276f77079108c98ac516ffa00194e77a0795f7140bdf36069b6475e58213f9","name":"node_e6779e3bbecf81dde8b27d652ed2726c45c205db0d0405c4580014a4c91d739830276f77079108c98ac516ffa00194e77a0795f7140bdf36069b6475e58213f9","enode":"enode://e6779e3bbecf81dde8b27d652ed2726c45c205db0d0405c4580014a4c91d739830276f77079108c98ac516ffa00194e77a0795f7140bdf36069b6475e58213f9@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"mesxSs+d4rb3CF2iR6VSEl5hyXxrVDiKIcBHTXF+NZA=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 99eb31\npopulation: 26 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 69d8 3843 00c8 0c72 | 122 581a (0) 5b30 (0) 5a67 (0) 5e3e (0)\n001 4 cba4 e255 fd3f f2b2 | 71 de1d (0) df52 (0) d90b (0) d96e (0)\n002 1 b30e | 30 a3f2 (0) a317 (0) a1f1 (0) a1b6 (0)\n003 2 86d3 8ae8 | 15 802f (0) 802e (0) 83d0 (0) 8434 (0)\n004 6 93f8 92d5 9108 9493 | 8 910d (0) 9108 (0) 93f8 (0) 92d5 (0)\n005 1 9f4c | 1 9f4c (0)\n006 3 9a09 9b87 9bc3 | 3 9a09 (0) 9b87 (0) 9bc3 (0)\n007 3 985f 98bc 98aa | 3 985f (0) 98aa (0) 98bc (0)\n============ DEPTH: 8 ==========================================\n008 2 9929 9918 | 2 9929 (0) 9918 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"e6779e3bbecf81dde8b27d652ed2726c45c205db0d0405c4580014a4c91d739830276f77079108c98ac516ffa00194e77a0795f7140bdf36069b6475e58213f9","private_key":"9b28fbe1dfa137bce975e179d3acfe046e5d148e1f9b1aeb16bdbc2cf7abd071","name":"node_e6779e3bbecf81dde8b27d652ed2726c45c205db0d0405c4580014a4c91d739830276f77079108c98ac516ffa00194e77a0795f7140bdf36069b6475e58213f9","services":["streamer"],"enable_msg_events":true,"port":63315},"up":true}},{"node":{"info":{"id":"9133b0b3c8f680286eae90c3beebc3099a13de38775a3ff2abdeced62d05eb2ced5ac85eac0870156be03101024da5e1d9fbf3e1066ddb3f088221e64149acec","name":"node_9133b0b3c8f680286eae90c3beebc3099a13de38775a3ff2abdeced62d05eb2ced5ac85eac0870156be03101024da5e1d9fbf3e1066ddb3f088221e64149acec","enode":"enode://9133b0b3c8f680286eae90c3beebc3099a13de38775a3ff2abdeced62d05eb2ced5ac85eac0870156be03101024da5e1d9fbf3e1066ddb3f088221e64149acec@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"DHKMF0ol4RvBcdfTXqqjl0hZpNv3pk4dnJ2ms61jsho=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 0c728c\npopulation: 19 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 e255 f2b2 99eb | 134 df52 (0) de1d (0) d96e (0) d90b (0)\n001 1 44b7 | 50 7e45 (0) 7ec4 (0) 7aef (0) 7810 (0)\n002 3 3843 2cab 2a7d | 35 24f8 (0) 2737 (0) 208e (0) 2224 (0)\n003 2 167b 1254 | 19 11a0 (0) 10b1 (0) 1254 (0) 14e4 (0)\n004 3 05a4 0536 00c8 | 7 07a6 (0) 0536 (0) 05a4 (0) 0305 (0)\n005 1 0ad6 | 4 09d1 (0) 0bc3 (0) 0a3f (0) 0ad6 (0)\n006 2 0fa0 0f65 | 2 0fa0 (0) 0f65 (0)\n007 2 0daf 0d97 | 2 0d97 (0) 0daf (0)\n============ DEPTH: 8 ==========================================\n008 1 0ca9 | 1 0ca9 (0)\n009 1 0c19 | 1 0c19 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"9133b0b3c8f680286eae90c3beebc3099a13de38775a3ff2abdeced62d05eb2ced5ac85eac0870156be03101024da5e1d9fbf3e1066ddb3f088221e64149acec","private_key":"85e559f97ba5553b0773479fed666bd92a928924af8164f41e92e8acfd51e896","name":"node_9133b0b3c8f680286eae90c3beebc3099a13de38775a3ff2abdeced62d05eb2ced5ac85eac0870156be03101024da5e1d9fbf3e1066ddb3f088221e64149acec","services":["streamer"],"enable_msg_events":true,"port":63316},"up":true}},{"node":{"info":{"id":"e1ecad3beeb6c19dce551e4a603c7b440b4498c44e298dc67bfaf4ed2c75bbea95df48b1cd1318e2ccb962cbae7c30ff258e73f8c3fc6b7e9ae7a47f7cf8e53c","name":"node_e1ecad3beeb6c19dce551e4a603c7b440b4498c44e298dc67bfaf4ed2c75bbea95df48b1cd1318e2ccb962cbae7c30ff258e73f8c3fc6b7e9ae7a47f7cf8e53c","enode":"enode://e1ecad3beeb6c19dce551e4a603c7b440b4498c44e298dc67bfaf4ed2c75bbea95df48b1cd1318e2ccb962cbae7c30ff258e73f8c3fc6b7e9ae7a47f7cf8e53c@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"AMg+h5AJckcuJHoTrNZUUKAUpO3wqxVIGZaZ7etQiGw=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 00c83e\npopulation: 23 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 5 c911 e255 f2f5 f2b2 | 134 df52 (0) de1d (0) d96e (0) d90b (0)\n001 1 44b7 | 50 7aef (0) 7810 (0) 7e45 (0) 7ec4 (0)\n002 3 2cab 2a7d 3843 | 35 24f8 (0) 2737 (0) 208e (0) 2224 (0)\n003 2 10b1 1953 | 19 11a0 (0) 10b1 (0) 1254 (0) 14e4 (0)\n004 6 0ad6 0f65 0d97 0daf | 11 09d1 (0) 0bc3 (0) 0a3f (0) 0ad6 (0)\n005 3 07a6 05a4 0536 | 3 07a6 (0) 05a4 (0) 0536 (0)\n============ DEPTH: 6 ==========================================\n006 2 0305 020f | 2 0305 (0) 020f (0)\n007 0 | 0\n008 1 0020 | 1 0020 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"e1ecad3beeb6c19dce551e4a603c7b440b4498c44e298dc67bfaf4ed2c75bbea95df48b1cd1318e2ccb962cbae7c30ff258e73f8c3fc6b7e9ae7a47f7cf8e53c","private_key":"652705ca7c47c641c033e01212d96759539f317508df53dcf7397dcee0e20422","name":"node_e1ecad3beeb6c19dce551e4a603c7b440b4498c44e298dc67bfaf4ed2c75bbea95df48b1cd1318e2ccb962cbae7c30ff258e73f8c3fc6b7e9ae7a47f7cf8e53c","services":["streamer"],"enable_msg_events":true,"port":63317},"up":true}},{"node":{"info":{"id":"1d0244a13affe60996fe3cf51ba624adc746de0c7ea68ec5a31311a36077c5b5495e3d95c9642875db44c7ecae6ffed22e45f2e2d024d486760be2af9f4cf2cd","name":"node_1d0244a13affe60996fe3cf51ba624adc746de0c7ea68ec5a31311a36077c5b5495e3d95c9642875db44c7ecae6ffed22e45f2e2d024d486760be2af9f4cf2cd","enode":"enode://1d0244a13affe60996fe3cf51ba624adc746de0c7ea68ec5a31311a36077c5b5495e3d95c9642875db44c7ecae6ffed22e45f2e2d024d486760be2af9f4cf2cd@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"OEMFr/VpgqiF1kPytyicXzVlitXDanbB2XAwr2Dtl18=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 384305\npopulation: 26 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 99eb f2f5 f2b2 | 134 df52 (0) de1d (0) d96e (0) d90b (0)\n001 1 44b7 | 50 7aef (0) 7810 (0) 7e45 (0) 7ec4 (0)\n002 4 0c19 0c72 0daf 00c8 | 37 11a0 (0) 10b1 (0) 1254 (0) 14e4 (0)\n003 5 2220 2a7d 2e3b 2cb1 | 15 24f8 (0) 2737 (0) 208e (0) 2224 (0)\n004 4 3227 3607 3799 3734 | 10 3085 (0) 3054 (0) 307c (0) 3388 (0)\n005 4 3d17 3c5a 3ff8 3ef6 | 4 3c5a (0) 3d17 (0) 3ff8 (0) 3ef6 (0)\n006 3 3baa 3ab2 3a18 | 3 3baa (0) 3ab2 (0) 3a18 (0)\n============ DEPTH: 7 ==========================================\n007 1 398b | 1 398b (0)\n008 1 38d7 | 1 38d7 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"1d0244a13affe60996fe3cf51ba624adc746de0c7ea68ec5a31311a36077c5b5495e3d95c9642875db44c7ecae6ffed22e45f2e2d024d486760be2af9f4cf2cd","private_key":"2578458d6da6ee18aceaf48f57a0f211f9b0a0a49149cc71356d1ccb989b55d8","name":"node_1d0244a13affe60996fe3cf51ba624adc746de0c7ea68ec5a31311a36077c5b5495e3d95c9642875db44c7ecae6ffed22e45f2e2d024d486760be2af9f4cf2cd","services":["streamer"],"enable_msg_events":true,"port":63318},"up":true}},{"node":{"info":{"id":"d9bbcdfd949010e6b2cbf6d0f34b27593ae410bdc1838876aeca35679571fe431d040a5ab085c0a77f111688bebed891da3587277cd794702437cb20d6aa4256","name":"node_d9bbcdfd949010e6b2cbf6d0f34b27593ae410bdc1838876aeca35679571fe431d040a5ab085c0a77f111688bebed891da3587277cd794702437cb20d6aa4256","enode":"enode://d9bbcdfd949010e6b2cbf6d0f34b27593ae410bdc1838876aeca35679571fe431d040a5ab085c0a77f111688bebed891da3587277cd794702437cb20d6aa4256@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"Da+BW3SXUHCo7wU7grL0+nkZ1IiNRy98V9e2DHtW4FY=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 0daf81\npopulation: 23 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 98bc f2f5 c60e c911 | 134 af8f (0) ac62 (0) a936 (0) a9df (0)\n001 2 6caa 44b7 | 50 7aef (0) 7810 (0) 7e45 (0) 7ec4 (0)\n002 3 2cab 3734 3843 | 35 24f8 (0) 2737 (0) 208e (0) 2224 (0)\n003 4 10b1 1254 1a85 1953 | 19 14e4 (0) 1587 (0) 15ec (0) 1758 (0)\n004 3 0536 020f 00c8 | 7 07a6 (0) 05a4 (0) 0536 (0) 0305 (0)\n005 1 0ad6 | 4 09d1 (0) 0bc3 (0) 0a3f (0) 0ad6 (0)\n006 2 0fa0 0f65 | 2 0fa0 (0) 0f65 (0)\n============ DEPTH: 7 ==========================================\n007 3 0ca9 0c72 0c19 | 3 0ca9 (0) 0c72 (0) 0c19 (0)\n008 0 | 0\n009 0 | 0\n010 1 0d97 | 1 0d97 (0)\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"d9bbcdfd949010e6b2cbf6d0f34b27593ae410bdc1838876aeca35679571fe431d040a5ab085c0a77f111688bebed891da3587277cd794702437cb20d6aa4256","private_key":"35b91179894d9195f220f768d849bcef7b2752c1d63a4d373be189c4e35b68a4","name":"node_d9bbcdfd949010e6b2cbf6d0f34b27593ae410bdc1838876aeca35679571fe431d040a5ab085c0a77f111688bebed891da3587277cd794702437cb20d6aa4256","services":["streamer"],"enable_msg_events":true,"port":63319},"up":true}},{"node":{"info":{"id":"0a4eec7b0e05da799aca5b36d9e2530f2a89d1426b1fcb7d8f9a662df8a8b5b763767a20db3c9c63e0bd13c2a6e16d3ba8f03baf84f5e5d24917b3f211d9bcfc","name":"node_0a4eec7b0e05da799aca5b36d9e2530f2a89d1426b1fcb7d8f9a662df8a8b5b763767a20db3c9c63e0bd13c2a6e16d3ba8f03baf84f5e5d24917b3f211d9bcfc","enode":"enode://0a4eec7b0e05da799aca5b36d9e2530f2a89d1426b1fcb7d8f9a662df8a8b5b763767a20db3c9c63e0bd13c2a6e16d3ba8f03baf84f5e5d24917b3f211d9bcfc@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"yRFNxYip17pz5BqUPQjFKPOk6BHciyFs1KtYFx0PZCw=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: c9114d\npopulation: 23 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 1953 00c8 0c19 0daf | 122 7299 (0) 7239 (0) 71bf (0) 715b (0)\n001 2 98bc af8f | 63 af8f (0) ac62 (0) a9df (0) a936 (0)\n002 4 e255 fd3f f2b2 f2f5 | 38 e9fa (0) e850 (0) ebc9 (0) ebe8 (0)\n003 4 d606 d455 d044 d35c | 19 de1d (0) df52 (0) d90b (0) d96e (0)\n004 2 c3d8 c60e | 5 c301 (0) c3d8 (0) c409 (0) c7fa (0)\n005 2 ce71 cf77 | 2 ce71 (0) cf77 (0)\n006 3 caa3 cbd3 cba4 | 4 ca8c (0) caa3 (0) cbd3 (0) cba4 (0)\n007 0 | 0\n008 0 | 0\n============ DEPTH: 9 ==========================================\n009 1 c95a | 1 c95a (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 1 c914 | 1 c914 (0)\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"0a4eec7b0e05da799aca5b36d9e2530f2a89d1426b1fcb7d8f9a662df8a8b5b763767a20db3c9c63e0bd13c2a6e16d3ba8f03baf84f5e5d24917b3f211d9bcfc","private_key":"62fbe89ba6bc5d8f608f65baf5a0a87c9cffd1f428ecacaadcc777a117a88fa2","name":"node_0a4eec7b0e05da799aca5b36d9e2530f2a89d1426b1fcb7d8f9a662df8a8b5b763767a20db3c9c63e0bd13c2a6e16d3ba8f03baf84f5e5d24917b3f211d9bcfc","services":["streamer"],"enable_msg_events":true,"port":63320},"up":true}},{"node":{"info":{"id":"9bbbfac8be4a000f51a4ce8d024d2595b5d491afec0138922dddfde5ef62c664040c2e9304cc6b7bc688233b5d0c4644b8c8793227c078285a3ab894ef0497a3","name":"node_9bbbfac8be4a000f51a4ce8d024d2595b5d491afec0138922dddfde5ef62c664040c2e9304cc6b7bc688233b5d0c4644b8c8793227c078285a3ab894ef0497a3","enode":"enode://9bbbfac8be4a000f51a4ce8d024d2595b5d491afec0138922dddfde5ef62c664040c2e9304cc6b7bc688233b5d0c4644b8c8793227c078285a3ab894ef0497a3@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"8vXoLPgfB/jPgscXHF7lpCt5Y2Gfr9QpUTc1fOobe7A=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: f2f5e8\npopulation: 19 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 6 3843 00c8 0c19 0daf | 122 208e (0) 2224 (0) 2220 (0) 24f8 (0)\n001 3 98bc a0e4 a077 | 63 a478 (0) a75d (0) a6bd (0) a317 (0)\n002 3 c60e cba4 c911 | 33 de1d (0) df52 (0) d96e (0) d90b (0)\n003 1 e255 | 25 e9fa (0) e850 (0) ebe8 (0) ebc9 (0)\n004 1 fd3f | 5 f97e (0) ffb7 (0) fc88 (0) fd44 (0)\n005 1 f6a6 | 1 f6a6 (0)\n006 2 f1ad f1b9 | 4 f054 (0) f0b8 (0) f1ad (0) f1b9 (0)\n007 0 | 0\n008 0 | 0\n============ DEPTH: 9 ==========================================\n009 2 f293 f2b2 | 2 f293 (0) f2b2 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"9bbbfac8be4a000f51a4ce8d024d2595b5d491afec0138922dddfde5ef62c664040c2e9304cc6b7bc688233b5d0c4644b8c8793227c078285a3ab894ef0497a3","private_key":"85b477146d09b052deacbb0f7cc22f61fe3093095e7677ce89c086db68c8c939","name":"node_9bbbfac8be4a000f51a4ce8d024d2595b5d491afec0138922dddfde5ef62c664040c2e9304cc6b7bc688233b5d0c4644b8c8793227c078285a3ab894ef0497a3","services":["streamer"],"enable_msg_events":true,"port":63321},"up":true}},{"node":{"info":{"id":"016f8f4619a16a07fbde5a18e362158d696e4d9f104a77787f26e32a25cd7d278256f8e0db865c488a99511ec27a5eddd5ebbd1c1397fa7f8db111062e5fe959","name":"node_016f8f4619a16a07fbde5a18e362158d696e4d9f104a77787f26e32a25cd7d278256f8e0db865c488a99511ec27a5eddd5ebbd1c1397fa7f8db111062e5fe959","enode":"enode://016f8f4619a16a07fbde5a18e362158d696e4d9f104a77787f26e32a25cd7d278256f8e0db865c488a99511ec27a5eddd5ebbd1c1397fa7f8db111062e5fe959@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"RLcBO81eC9Nu1SZgJhTxOpHJ/PqGEzEq4i2chzd6WUk=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 44b701\npopulation: 28 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 f2f5 | 134 a317 (0) a3f2 (0) a011 (0) a077 (0)\n001 16 2940 2a7d 2cab 3734 | 72 208e (0) 2220 (0) 2224 (0) 24f8 (0)\n002 1 6caa | 19 7e45 (0) 7ec4 (0) 7aef (0) 7810 (0)\n003 1 5399 | 15 581a (0) 5a67 (0) 5b30 (0) 5e3e (0)\n004 2 4bbc 4bf8 | 8 4dc4 (0) 4c97 (0) 48df (0) 48ec (0)\n005 4 42d6 43fb 413b 41b2 | 4 42d6 (0) 43fb (0) 413b (0) 41b2 (0)\n============ DEPTH: 6 ==========================================\n006 2 464b 47a8 | 2 47a8 (0) 464b (0)\n007 0 | 0\n008 0 | 0\n009 1 44c8 | 1 44c8 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"016f8f4619a16a07fbde5a18e362158d696e4d9f104a77787f26e32a25cd7d278256f8e0db865c488a99511ec27a5eddd5ebbd1c1397fa7f8db111062e5fe959","private_key":"b3caf8e1271504098be33349fd983395e57f6cc7f4c0d74df8dec7643c0cd09b","name":"node_016f8f4619a16a07fbde5a18e362158d696e4d9f104a77787f26e32a25cd7d278256f8e0db865c488a99511ec27a5eddd5ebbd1c1397fa7f8db111062e5fe959","services":["streamer"],"enable_msg_events":true,"port":63322},"up":true}},{"node":{"info":{"id":"7acddc7fb6ac587b7e343804c768e4291cd28dd2b2b9207dea6ee82360d848a52d84f94e4c49e9c421f4f90e2d24f6291e2358783ab0230e6ecde82e69b4ac52","name":"node_7acddc7fb6ac587b7e343804c768e4291cd28dd2b2b9207dea6ee82360d848a52d84f94e4c49e9c421f4f90e2d24f6291e2358783ab0230e6ecde82e69b4ac52","enode":"enode://7acddc7fb6ac587b7e343804c768e4291cd28dd2b2b9207dea6ee82360d848a52d84f94e4c49e9c421f4f90e2d24f6291e2358783ab0230e6ecde82e69b4ac52@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"DBlWytOXycuTUkyyP7+rmd8qeXgK5Za5PHf9nbBvf3o=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 0c1956\npopulation: 24 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 98bc f2f5 c60e c911 | 134 af8f (0) ac62 (0) a9df (0) a936 (0)\n001 2 6caa 44b7 | 50 7aef (0) 7810 (0) 7ec4 (0) 7e45 (0)\n002 3 3734 3843 2cab | 35 24f8 (0) 2737 (0) 208e (0) 2224 (0)\n003 4 167b 10b1 1a85 1953 | 19 11a0 (0) 10b1 (0) 1254 (0) 14e4 (0)\n004 3 05a4 0536 00c8 | 7 07a6 (0) 05a4 (0) 0536 (0) 0305 (0)\n005 2 0a3f 0ad6 | 4 09d1 (0) 0bc3 (0) 0a3f (0) 0ad6 (0)\n006 2 0fa0 0f65 | 2 0fa0 (0) 0f65 (0)\n007 2 0d97 0daf | 2 0d97 (0) 0daf (0)\n============ DEPTH: 8 ==========================================\n008 1 0ca9 | 1 0ca9 (0)\n009 1 0c72 | 1 0c72 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"7acddc7fb6ac587b7e343804c768e4291cd28dd2b2b9207dea6ee82360d848a52d84f94e4c49e9c421f4f90e2d24f6291e2358783ab0230e6ecde82e69b4ac52","private_key":"a61a6a7469d5c9abf20daf3df75109b9139cf36c1194d9bc00046d1359c44823","name":"node_7acddc7fb6ac587b7e343804c768e4291cd28dd2b2b9207dea6ee82360d848a52d84f94e4c49e9c421f4f90e2d24f6291e2358783ab0230e6ecde82e69b4ac52","services":["streamer"],"enable_msg_events":true,"port":63323},"up":true}},{"node":{"info":{"id":"9b59b76dc61223c7b37083b0ebdda22d3599563b3e3986f5db9d5b12f8c806cbdeb2345454efe957cbfa11eea9c7896aefd9a461210524805452ca100a9ea431","name":"node_9b59b76dc61223c7b37083b0ebdda22d3599563b3e3986f5db9d5b12f8c806cbdeb2345454efe957cbfa11eea9c7896aefd9a461210524805452ca100a9ea431","enode":"enode://9b59b76dc61223c7b37083b0ebdda22d3599563b3e3986f5db9d5b12f8c806cbdeb2345454efe957cbfa11eea9c7896aefd9a461210524805452ca100a9ea431@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"GVPffimBOwCwE3EYYjts40ET0X1Pmqpgi4Hy7ljqP+M=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 1953df\npopulation: 21 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 c60e c911 f2f5 | 134 e9fa (0) e850 (0) ebc9 (0) ebe8 (0)\n001 1 44b7 | 50 581a (0) 5a67 (0) 5b30 (0) 5e3e (0)\n002 1 2cab | 35 3085 (0) 3054 (0) 307c (0) 3388 (0)\n003 4 05a4 00c8 0daf 0c19 | 18 07a6 (0) 05a4 (0) 0536 (0) 0305 (0)\n004 5 15ec 167b 17a0 10b1 | 9 14e4 (0) 15ec (0) 1587 (0) 1758 (0)\n005 4 1fab 1daa 1dfd 1d5b | 6 1ea1 (0) 1fab (0) 1dfd (0) 1dfc (0)\n============ DEPTH: 6 ==========================================\n006 3 1af6 1a8e 1a85 | 3 1af6 (0) 1a8e (0) 1a85 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"9b59b76dc61223c7b37083b0ebdda22d3599563b3e3986f5db9d5b12f8c806cbdeb2345454efe957cbfa11eea9c7896aefd9a461210524805452ca100a9ea431","private_key":"629bf1b9c1de816ee9d1abd91d2cef359ce96216dc1d798c7f246ecc5bba8ed4","name":"node_9b59b76dc61223c7b37083b0ebdda22d3599563b3e3986f5db9d5b12f8c806cbdeb2345454efe957cbfa11eea9c7896aefd9a461210524805452ca100a9ea431","services":["streamer"],"enable_msg_events":true,"port":63324},"up":true}},{"node":{"info":{"id":"e2e0419a41bdfc5bd76deae2ddce6ac865f886d764c9bd18799b79fa3b2b6ba66d765d26da2037e98317e1d7e8232a61e63c1d0cfa98c9137424151b46e07171","name":"node_e2e0419a41bdfc5bd76deae2ddce6ac865f886d764c9bd18799b79fa3b2b6ba66d765d26da2037e98317e1d7e8232a61e63c1d0cfa98c9137424151b46e07171","enode":"enode://e2e0419a41bdfc5bd76deae2ddce6ac865f886d764c9bd18799b79fa3b2b6ba66d765d26da2037e98317e1d7e8232a61e63c1d0cfa98c9137424151b46e07171@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"LKtr7Pza+svJ5Th8ebxw3LnBbheJtATt9X4FNU8FZ50=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 2cab6b\npopulation: 32 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 98bc c60e | 134 e9fa (0) e850 (0) ebc9 (0) ebe8 (0)\n001 4 6caa 44b7 4bf8 5399 | 50 581a (0) 5a67 (0) 5b30 (0) 5e3e (0)\n002 10 00c8 0ad6 0c72 0c19 | 37 07a6 (0) 05a4 (0) 0536 (0) 020f (0)\n003 3 3734 3227 3843 | 20 3085 (0) 3054 (0) 307c (0) 3388 (0)\n004 4 2220 2224 208e 2737 | 5 2224 (0) 2220 (0) 208e (0) 24f8 (0)\n005 3 293f 2940 2a7d | 3 293f (0) 2940 (0) 2a7d (0)\n006 3 2e3b 2f23 2f1f | 3 2f1f (0) 2f23 (0) 2e3b (0)\n007 0 | 0\n============ DEPTH: 8 ==========================================\n008 2 2c16 2c4e | 2 2c16 (0) 2c4e (0)\n009 0 | 0\n010 0 | 0\n011 1 2cb1 | 1 2cb1 (0)\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"e2e0419a41bdfc5bd76deae2ddce6ac865f886d764c9bd18799b79fa3b2b6ba66d765d26da2037e98317e1d7e8232a61e63c1d0cfa98c9137424151b46e07171","private_key":"880c61b8c84f87c55e85aa9b07944500eed52b76b64b6d15c93d8e7c23000042","name":"node_e2e0419a41bdfc5bd76deae2ddce6ac865f886d764c9bd18799b79fa3b2b6ba66d765d26da2037e98317e1d7e8232a61e63c1d0cfa98c9137424151b46e07171","services":["streamer"],"enable_msg_events":true,"port":63325},"up":true}},{"node":{"info":{"id":"5df58ba12334a1b4f983d642fe435901261767cd81f8f37c43e359f5584664e4d287e8c2275995604a3b3a4823418e35cd899a3db2a7db31570e19512f375481","name":"node_5df58ba12334a1b4f983d642fe435901261767cd81f8f37c43e359f5584664e4d287e8c2275995604a3b3a4823418e35cd899a3db2a7db31570e19512f375481","enode":"enode://5df58ba12334a1b4f983d642fe435901261767cd81f8f37c43e359f5584664e4d287e8c2275995604a3b3a4823418e35cd899a3db2a7db31570e19512f375481@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"ElSx5cnoCzZ1IL/vw1zzKmCv9WxIMVEHxLB6oaeGavk=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 1254b1\npopulation: 20 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 c60e | 134 ebc9 (0) ebe8 (0) e9fa (0) e850 (0)\n001 2 44b7 6caa | 50 581a (0) 5a67 (0) 5b30 (0) 5e3e (0)\n002 2 3ef6 2cab | 35 3085 (0) 3054 (0) 307c (0) 3388 (0)\n003 3 05a4 0c72 0daf | 18 07a6 (0) 05a4 (0) 0536 (0) 0305 (0)\n004 6 1dfd 1d5b 1953 1af6 | 10 1ea1 (0) 1fab (0) 1dfd (0) 1dfc (0)\n005 4 15ec 1758 17a0 167b | 6 14e4 (0) 15ec (0) 1587 (0) 1758 (0)\n============ DEPTH: 6 ==========================================\n006 2 11a0 10b1 | 2 11a0 (0) 10b1 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"5df58ba12334a1b4f983d642fe435901261767cd81f8f37c43e359f5584664e4d287e8c2275995604a3b3a4823418e35cd899a3db2a7db31570e19512f375481","private_key":"dc74709b0972c1ec957a2c056059ce117c9291997ea47107228e80d28af70acd","name":"node_5df58ba12334a1b4f983d642fe435901261767cd81f8f37c43e359f5584664e4d287e8c2275995604a3b3a4823418e35cd899a3db2a7db31570e19512f375481","services":["streamer"],"enable_msg_events":true,"port":63326},"up":true}},{"node":{"info":{"id":"5e86f39cf8338ba098a85d41e601a303fde311662b216ad32a2b7bfaf2b2b6dd1af3775784b39f2d85ac5fac96f05f3abdd8a2bd28ba16d939725fd6a33ae1b6","name":"node_5e86f39cf8338ba098a85d41e601a303fde311662b216ad32a2b7bfaf2b2b6dd1af3775784b39f2d85ac5fac96f05f3abdd8a2bd28ba16d939725fd6a33ae1b6","enode":"enode://5e86f39cf8338ba098a85d41e601a303fde311662b216ad32a2b7bfaf2b2b6dd1af3775784b39f2d85ac5fac96f05f3abdd8a2bd28ba16d939725fd6a33ae1b6@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"GoXhPirYLI/6EK1Ss4KUfmOANhIBiK5hH7H7Mzy1Iys=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 1a85e1\npopulation: 18 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 c60e | 134 ebc9 (0) ebe8 (0) e9fa (0) e850 (0)\n001 2 44b7 6caa | 50 581a (0) 5a67 (0) 5b30 (0) 5e3e (0)\n002 1 2cab | 35 3085 (0) 3054 (0) 307c (0) 3388 (0)\n003 3 05a4 0c19 0daf | 18 07a6 (0) 05a4 (0) 0536 (0) 0305 (0)\n004 3 15ec 167b 1254 | 9 14e4 (0) 15ec (0) 1587 (0) 1758 (0)\n005 5 1fab 1daa 1dfd 1dfc | 6 1ea1 (0) 1fab (0) 1dfd (0) 1dfc (0)\n006 1 1953 | 1 1953 (0)\n007 0 | 0\n008 0 | 0\n============ DEPTH: 9 ==========================================\n009 1 1af6 | 1 1af6 (0)\n010 0 | 0\n011 0 | 0\n012 1 1a8e | 1 1a8e (0)\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"5e86f39cf8338ba098a85d41e601a303fde311662b216ad32a2b7bfaf2b2b6dd1af3775784b39f2d85ac5fac96f05f3abdd8a2bd28ba16d939725fd6a33ae1b6","private_key":"52e14edd67adc3154d0d5a91f91e042773a79af41c5cce9120e2dc03318a7fdd","name":"node_5e86f39cf8338ba098a85d41e601a303fde311662b216ad32a2b7bfaf2b2b6dd1af3775784b39f2d85ac5fac96f05f3abdd8a2bd28ba16d939725fd6a33ae1b6","services":["streamer"],"enable_msg_events":true,"port":63327},"up":true}},{"node":{"info":{"id":"df54af3bae257d437c5657905484e0d72e9560c46f8ba6b3437730234e05259b404cca40b0831e911605ff8a68a19e8fd7e958069ec8b40595928892f4fa220c","name":"node_df54af3bae257d437c5657905484e0d72e9560c46f8ba6b3437730234e05259b404cca40b0831e911605ff8a68a19e8fd7e958069ec8b40595928892f4fa220c","enode":"enode://df54af3bae257d437c5657905484e0d72e9560c46f8ba6b3437730234e05259b404cca40b0831e911605ff8a68a19e8fd7e958069ec8b40595928892f4fa220c@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"mLx+iklBsGW5j2YRk1+rCW3U4L39OKnyyktj8oUeJwQ=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 98bc7e\npopulation: 28 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 6caa 2cab 0c19 0daf | 122 581a (0) 5a67 (0) 5b30 (0) 5c9b (0)\n001 5 f2f5 e255 cba4 c911 | 71 ebc9 (0) ebe8 (0) e9fa (0) e850 (0)\n002 1 b30e | 30 af8f (0) ac62 (0) a936 (0) a9df (0)\n003 1 8ae8 | 15 83d0 (0) 802f (0) 802e (0) 8434 (0)\n004 8 9404 9493 9747 9641 | 8 910d (0) 9108 (0) 93f8 (0) 92d5 (0)\n005 1 9f4c | 1 9f4c (0)\n006 3 9b87 9bc3 9a09 | 3 9a09 (0) 9b87 (0) 9bc3 (0)\n007 3 99eb 9918 9929 | 3 9918 (0) 9929 (0) 99eb (0)\n============ DEPTH: 8 ==========================================\n008 1 985f | 1 985f (0)\n009 0 | 0\n010 0 | 0\n011 1 98aa | 1 98aa (0)\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"df54af3bae257d437c5657905484e0d72e9560c46f8ba6b3437730234e05259b404cca40b0831e911605ff8a68a19e8fd7e958069ec8b40595928892f4fa220c","private_key":"ba201a301c109cac7dc4f762066312478f6a3b92b80495c19d238b8e728e3f63","name":"node_df54af3bae257d437c5657905484e0d72e9560c46f8ba6b3437730234e05259b404cca40b0831e911605ff8a68a19e8fd7e958069ec8b40595928892f4fa220c","services":["streamer"],"enable_msg_events":true,"port":63328},"up":true}},{"node":{"info":{"id":"4ee37acec2178ef120166265aaa2b64b09b315fb53861405ef46f2503c273eb9692e9cb4c2e67a8652254d430fd6e02dd3fe4cded20bb231a9fb834d292b0b24","name":"node_4ee37acec2178ef120166265aaa2b64b09b315fb53861405ef46f2503c273eb9692e9cb4c2e67a8652254d430fd6e02dd3fe4cded20bb231a9fb834d292b0b24","enode":"enode://4ee37acec2178ef120166265aaa2b64b09b315fb53861405ef46f2503c273eb9692e9cb4c2e67a8652254d430fd6e02dd3fe4cded20bb231a9fb834d292b0b24@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"xg4KjDLWhCRTeSEk1JWvMHIeefKZR5OBNfNbNBxDPvQ=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: c60e0a\npopulation: 28 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 11 2220 2cab 3734 0ad6 | 122 5a67 (0) 5b30 (0) 581a (0) 5c9b (0)\n001 2 98bc 93f8 | 63 a3f2 (0) a317 (0) a105 (0) a1f1 (0)\n002 3 e4d6 e850 f2f5 | 38 ebc9 (0) ebe8 (0) e9fa (0) e850 (0)\n003 3 d66f d455 d35c | 19 df52 (0) de1d (0) d96e (0) d90b (0)\n004 5 caa3 cbd3 cba4 c95a | 9 ce71 (0) cf77 (0) ca8c (0) caa3 (0)\n005 2 c301 c3d8 | 2 c301 (0) c3d8 (0)\n============ DEPTH: 6 ==========================================\n006 1 c409 | 1 c409 (0)\n007 1 c7fa | 1 c7fa (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"4ee37acec2178ef120166265aaa2b64b09b315fb53861405ef46f2503c273eb9692e9cb4c2e67a8652254d430fd6e02dd3fe4cded20bb231a9fb834d292b0b24","private_key":"4f8dbb09790674afc8ae90210897ff3196d82a7d8cacd67ab970ab02fd61136e","name":"node_4ee37acec2178ef120166265aaa2b64b09b315fb53861405ef46f2503c273eb9692e9cb4c2e67a8652254d430fd6e02dd3fe4cded20bb231a9fb834d292b0b24","services":["streamer"],"enable_msg_events":true,"port":63329},"up":true}},{"node":{"info":{"id":"abd8f5a4d700c06ec00684b23d2d25c4df1a9554fcfc57b0ddc3fa476e6a699ba75e1213449f900803f83ab8194c6746664b547202047f35b8b3e216c7147bf8","name":"node_abd8f5a4d700c06ec00684b23d2d25c4df1a9554fcfc57b0ddc3fa476e6a699ba75e1213449f900803f83ab8194c6746664b547202047f35b8b3e216c7147bf8","enode":"enode://abd8f5a4d700c06ec00684b23d2d25c4df1a9554fcfc57b0ddc3fa476e6a699ba75e1213449f900803f83ab8194c6746664b547202047f35b8b3e216c7147bf8@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"bKpKhBOO60y+VXPt9MI4Ht8BvThsV/Un3eN3mDMBpWM=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 6caa4a\npopulation: 27 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 98bc c60e | 134 af8f (0) ac62 (0) a9df (0) a936 (0)\n001 8 2cab 3734 0ad6 0c19 | 72 24f8 (0) 2737 (0) 208e (0) 2224 (0)\n002 5 44c8 44b7 4bf8 5765 | 31 42d6 (0) 43fb (0) 413b (0) 41b2 (0)\n003 6 7299 76a5 7e45 7ec4 | 10 7239 (0) 7299 (0) 71bf (0) 715b (0)\n004 3 63de 65a6 67ee | 5 60bc (0) 63de (0) 65a6 (0) 6701 (0)\n============ DEPTH: 5 ==========================================\n005 2 6923 69d8 | 2 6923 (0) 69d8 (0)\n006 1 6f1c | 1 6f1c (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"abd8f5a4d700c06ec00684b23d2d25c4df1a9554fcfc57b0ddc3fa476e6a699ba75e1213449f900803f83ab8194c6746664b547202047f35b8b3e216c7147bf8","private_key":"fd9060fd74b7db28d5b02541febcaab4e1706cb1ae50b22d20a7f619fbc774cb","name":"node_abd8f5a4d700c06ec00684b23d2d25c4df1a9554fcfc57b0ddc3fa476e6a699ba75e1213449f900803f83ab8194c6746664b547202047f35b8b3e216c7147bf8","services":["streamer"],"enable_msg_events":true,"port":63330},"up":true}},{"node":{"info":{"id":"cb321c9b0fe2eb3617b8e2461aab170a9dad2c9b04a10eead4e37e551197ea0a7500eb1cb7b155efe1886486ef3d252d8ff0d309f2906a1126ca011d037da70a","name":"node_cb321c9b0fe2eb3617b8e2461aab170a9dad2c9b04a10eead4e37e551197ea0a7500eb1cb7b155efe1886486ef3d252d8ff0d309f2906a1126ca011d037da70a","enode":"enode://cb321c9b0fe2eb3617b8e2461aab170a9dad2c9b04a10eead4e37e551197ea0a7500eb1cb7b155efe1886486ef3d252d8ff0d309f2906a1126ca011d037da70a@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"FnvIH30m+Zzu7agU3lu/p1+PKmFXVXBZa8Wjxhj10jA=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 167bc8\npopulation: 27 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 6 a3f2 a317 a6bd d455 | 134 a478 (0) a75d (0) a6bd (0) a3f2 (0)\n001 3 6caa 44b7 5399 | 50 4c97 (0) 4dc4 (0) 48df (0) 48ec (0)\n002 2 2cab 3734 | 35 24f8 (0) 2737 (0) 208e (0) 2224 (0)\n003 4 0d97 0c72 0c19 0ad6 | 18 07a6 (0) 05a4 (0) 0536 (0) 0305 (0)\n004 4 1ea1 1d5b 1953 1a85 | 10 1ea1 (0) 1fab (0) 1dfd (0) 1dfc (0)\n005 3 10b1 11a0 1254 | 3 11a0 (0) 10b1 (0) 1254 (0)\n006 3 14e4 1587 15ec | 3 14e4 (0) 15ec (0) 1587 (0)\n============ DEPTH: 7 ==========================================\n007 2 17a0 1758 | 2 1758 (0) 17a0 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"cb321c9b0fe2eb3617b8e2461aab170a9dad2c9b04a10eead4e37e551197ea0a7500eb1cb7b155efe1886486ef3d252d8ff0d309f2906a1126ca011d037da70a","private_key":"3034bb94560e7e8d146cf275664f91426fbeadbea78cc96662a0e762f5491d3c","name":"node_cb321c9b0fe2eb3617b8e2461aab170a9dad2c9b04a10eead4e37e551197ea0a7500eb1cb7b155efe1886486ef3d252d8ff0d309f2906a1126ca011d037da70a","services":["streamer"],"enable_msg_events":true,"port":63331},"up":true}},{"node":{"info":{"id":"c665a6b1b7ad39b86bd4b1fe38b7ee95a0fbb1db15e91381ec9e5a235e33b69ffdc92c60dafd74b7b4dafca1b000e9274bf045abe5b93b1a9c2b31ae071a9898","name":"node_c665a6b1b7ad39b86bd4b1fe38b7ee95a0fbb1db15e91381ec9e5a235e33b69ffdc92c60dafd74b7b4dafca1b000e9274bf045abe5b93b1a9c2b31ae071a9898","enode":"enode://c665a6b1b7ad39b86bd4b1fe38b7ee95a0fbb1db15e91381ec9e5a235e33b69ffdc92c60dafd74b7b4dafca1b000e9274bf045abe5b93b1a9c2b31ae071a9898@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"NzR9FZQYhzIQo9z6YMD2ylD5AHzm8BJu7qaRi9oIst4=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 37347d\npopulation: 26 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 d35c c60e | 134 ac62 (0) af8f (0) aa78 (0) a936 (0)\n001 3 44b7 5399 6caa | 50 42d6 (0) 43fb (0) 413b (0) 41b2 (0)\n002 7 0f65 0c19 0daf 0ad6 | 37 07a6 (0) 05a4 (0) 0536 (0) 0305 (0)\n003 5 2220 2940 2f1f 2cb1 | 15 24f8 (0) 2737 (0) 208e (0) 2224 (0)\n004 4 3ef6 3a18 38d7 3843 | 10 3c5a (0) 3d17 (0) 3ff8 (0) 3ef6 (0)\n005 1 3227 | 5 3085 (0) 3054 (0) 307c (0) 3388 (0)\n006 1 34e4 | 1 34e4 (0)\n============ DEPTH: 7 ==========================================\n007 2 3658 3607 | 2 3658 (0) 3607 (0)\n008 1 3799 | 1 3799 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"c665a6b1b7ad39b86bd4b1fe38b7ee95a0fbb1db15e91381ec9e5a235e33b69ffdc92c60dafd74b7b4dafca1b000e9274bf045abe5b93b1a9c2b31ae071a9898","private_key":"1e3e9ddcbac955dd113066c5a41e5b3b16da5cd7bfa036ee1066ff3ceb69d7c9","name":"node_c665a6b1b7ad39b86bd4b1fe38b7ee95a0fbb1db15e91381ec9e5a235e33b69ffdc92c60dafd74b7b4dafca1b000e9274bf045abe5b93b1a9c2b31ae071a9898","services":["streamer"],"enable_msg_events":true,"port":63332},"up":true}},{"node":{"info":{"id":"53df9cce9b0169e58ced53a123d1d8f6e8fdcfb4c2d781ecbb91bb7c8eba36946dd9d21c749259769825d8a6b3faa6bb87c8c6085a522f8a3e376061f59144d9","name":"node_53df9cce9b0169e58ced53a123d1d8f6e8fdcfb4c2d781ecbb91bb7c8eba36946dd9d21c749259769825d8a6b3faa6bb87c8c6085a522f8a3e376061f59144d9","enode":"enode://53df9cce9b0169e58ced53a123d1d8f6e8fdcfb4c2d781ecbb91bb7c8eba36946dd9d21c749259769825d8a6b3faa6bb87c8c6085a522f8a3e376061f59144d9@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"CtZUlUrZshx1gxOJyJV0p4caa6jh1UySzybGTDMUi0I=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 0ad654\npopulation: 24 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 e4d6 d35c d455 c60e | 134 ac62 (0) af8f (0) a9df (0) a936 (0)\n001 5 6caa 44b7 4bf8 5765 | 50 7239 (0) 7299 (0) 71bf (0) 715b (0)\n002 2 2cab 3734 | 35 2224 (0) 2220 (0) 208e (0) 24f8 (0)\n003 3 1d5b 167b 10b1 | 19 1af6 (0) 1a8e (0) 1a85 (0) 1953 (0)\n004 2 00c8 0536 | 7 0305 (0) 020f (0) 0020 (0) 00c8 (0)\n005 5 0f65 0d97 0daf 0c72 | 7 0fa0 (0) 0f65 (0) 0d97 (0) 0daf (0)\n006 1 09d1 | 1 09d1 (0)\n============ DEPTH: 7 ==========================================\n007 1 0bc3 | 1 0bc3 (0)\n008 1 0a3f | 1 0a3f (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"53df9cce9b0169e58ced53a123d1d8f6e8fdcfb4c2d781ecbb91bb7c8eba36946dd9d21c749259769825d8a6b3faa6bb87c8c6085a522f8a3e376061f59144d9","private_key":"9dcf01557c9cd252eba6d06bab3e12ad039e64f5d33b732bae4afdee4f4c63af","name":"node_53df9cce9b0169e58ced53a123d1d8f6e8fdcfb4c2d781ecbb91bb7c8eba36946dd9d21c749259769825d8a6b3faa6bb87c8c6085a522f8a3e376061f59144d9","services":["streamer"],"enable_msg_events":true,"port":63333},"up":true}},{"node":{"info":{"id":"d7a319f69013b8375e64d19f015547462c84565b882337998f9e669c5fadd3d2ecf6374109903003e09f5d453424b5c7fdf52163d2cc8084cf81f94844946b63","name":"node_d7a319f69013b8375e64d19f015547462c84565b882337998f9e669c5fadd3d2ecf6374109903003e09f5d453424b5c7fdf52163d2cc8084cf81f94844946b63","enode":"enode://d7a319f69013b8375e64d19f015547462c84565b882337998f9e669c5fadd3d2ecf6374109903003e09f5d453424b5c7fdf52163d2cc8084cf81f94844946b63@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"U5mAqb/FznS8NdgcwmT0wNUpp13wyHC54LnORWUKnyk=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 539980\npopulation: 25 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 d455 d35c | 134 ac62 (0) af8f (0) aa78 (0) a9df (0)\n001 6 2cab 3734 167b 1d5b | 72 24f8 (0) 2737 (0) 208e (0) 2224 (0)\n002 2 7e45 6caa | 19 7e45 (0) 7ec4 (0) 7aef (0) 7810 (0)\n003 4 44b7 43fb 41b2 4bf8 | 16 464b (0) 47a8 (0) 44c8 (0) 44b7 (0)\n004 3 5a67 5cae 5e3e | 6 581a (0) 5b30 (0) 5a67 (0) 5c9b (0)\n005 4 56bb 57ee 5741 5765 | 4 56bb (0) 57ee (0) 5741 (0) 5765 (0)\n============ DEPTH: 6 ==========================================\n006 3 510c 5062 5070 | 3 510c (0) 5062 (0) 5070 (0)\n007 1 5237 | 1 5237 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"d7a319f69013b8375e64d19f015547462c84565b882337998f9e669c5fadd3d2ecf6374109903003e09f5d453424b5c7fdf52163d2cc8084cf81f94844946b63","private_key":"290d07cdf29c35f369b7053b54ad174e4db589026d3d4b0553bcccc0a0e4145d","name":"node_d7a319f69013b8375e64d19f015547462c84565b882337998f9e669c5fadd3d2ecf6374109903003e09f5d453424b5c7fdf52163d2cc8084cf81f94844946b63","services":["streamer"],"enable_msg_events":true,"port":63334},"up":true}},{"node":{"info":{"id":"f38a9d792173a29c61389f5d84c005d78eac6e750659aad42e2d6df883f04eb3126b2c38fac95076eeed455b2031aaf694143922aa93a2d50412a2454dc56e28","name":"node_f38a9d792173a29c61389f5d84c005d78eac6e750659aad42e2d6df883f04eb3126b2c38fac95076eeed455b2031aaf694143922aa93a2d50412a2454dc56e28","enode":"enode://f38a9d792173a29c61389f5d84c005d78eac6e750659aad42e2d6df883f04eb3126b2c38fac95076eeed455b2031aaf694143922aa93a2d50412a2454dc56e28@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"01wS81K16GA7bjVENN6DEONfmQGvVjo+x3W/oAuAbyM=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: d35c12\npopulation: 25 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 6 167b 0ad6 3734 4bf8 | 122 208e (0) 2224 (0) 2220 (0) 24f8 (0)\n001 3 93f8 92d5 9108 | 63 a478 (0) a75d (0) a6bd (0) a3f2 (0)\n002 2 e4d6 ee52 | 38 f97e (0) ffb7 (0) fc88 (0) fd44 (0)\n003 5 caa3 cbd3 c911 c95a | 14 cf77 (0) ce71 (0) cba4 (0) cbd3 (0)\n004 1 dad3 | 5 df52 (0) de1d (0) d90b (0) d96e (0)\n005 3 d7c1 d66f d455 | 7 d717 (0) d777 (0) d7c1 (0) d606 (0)\n006 3 d1bc d07c d044 | 4 d1bc (0) d0b7 (0) d07c (0) d044 (0)\n============ DEPTH: 7 ==========================================\n007 1 d2ac | 1 d2ac (0)\n008 1 d3bd | 1 d3bd (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"f38a9d792173a29c61389f5d84c005d78eac6e750659aad42e2d6df883f04eb3126b2c38fac95076eeed455b2031aaf694143922aa93a2d50412a2454dc56e28","private_key":"2a549958a13f2e346b477edf55e1056a1c7c1051b3cb277aba17bd7db522aba6","name":"node_f38a9d792173a29c61389f5d84c005d78eac6e750659aad42e2d6df883f04eb3126b2c38fac95076eeed455b2031aaf694143922aa93a2d50412a2454dc56e28","services":["streamer"],"enable_msg_events":true,"port":63335},"up":true}},{"node":{"info":{"id":"4f5ab12b9c5127c16739ad0d4f51adce90ba6736cd096eb185ea632789f4b26f1ebabdea4fd3b39dda5409ece6c2d92fd469cf4aecf9d29453e3e042c19b893b","name":"node_4f5ab12b9c5127c16739ad0d4f51adce90ba6736cd096eb185ea632789f4b26f1ebabdea4fd3b39dda5409ece6c2d92fd469cf4aecf9d29453e3e042c19b893b","enode":"enode://4f5ab12b9c5127c16739ad0d4f51adce90ba6736cd096eb185ea632789f4b26f1ebabdea4fd3b39dda5409ece6c2d92fd469cf4aecf9d29453e3e042c19b893b@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"1FUDTQQyLOdmtI+CXcrGnqmw90m9XLirLE46GLHHDvg=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: d45503\npopulation: 24 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 5 167b 0ad6 5765 5399 | 122 24f8 (0) 2737 (0) 208e (0) 2224 (0)\n001 3 9108 93f8 92d5 | 63 a9df (0) a936 (0) aa78 (0) af8f (0)\n002 2 e4d6 ee52 | 38 f97e (0) ffb7 (0) fc88 (0) fd44 (0)\n003 4 caa3 c911 c95a c60e | 14 ce71 (0) cf77 (0) cbd3 (0) cba4 (0)\n004 1 dad3 | 5 de1d (0) df52 (0) d90b (0) d96e (0)\n005 3 d044 d3bd d35c | 7 d1bc (0) d0b7 (0) d07c (0) d044 (0)\n============ DEPTH: 6 ==========================================\n006 5 d7c1 d777 d717 d606 | 5 d7c1 (0) d777 (0) d717 (0) d606 (0)\n007 1 d560 | 1 d560 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"4f5ab12b9c5127c16739ad0d4f51adce90ba6736cd096eb185ea632789f4b26f1ebabdea4fd3b39dda5409ece6c2d92fd469cf4aecf9d29453e3e042c19b893b","private_key":"72cba007b6bddfa0e57451e0f28d74cd7936955babeefb16b4c3de62400c8ef2","name":"node_4f5ab12b9c5127c16739ad0d4f51adce90ba6736cd096eb185ea632789f4b26f1ebabdea4fd3b39dda5409ece6c2d92fd469cf4aecf9d29453e3e042c19b893b","services":["streamer"],"enable_msg_events":true,"port":63336},"up":true}},{"node":{"info":{"id":"11d560045536e9d1b0b1b9e8944e00f0ca7f1e6788c9fdb51061820bbb3008ead92bb7836621bf58da7035c87a28328faecb4cb2e3cdb9d7fa4f45790e6bf352","name":"node_11d560045536e9d1b0b1b9e8944e00f0ca7f1e6788c9fdb51061820bbb3008ead92bb7836621bf58da7035c87a28328faecb4cb2e3cdb9d7fa4f45790e6bf352","enode":"enode://11d560045536e9d1b0b1b9e8944e00f0ca7f1e6788c9fdb51061820bbb3008ead92bb7836621bf58da7035c87a28328faecb4cb2e3cdb9d7fa4f45790e6bf352@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"S/jYxVUJQN+XEtdYvkcRAUNmrz6mtZiMXIYQ8zHzcEI=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 4bf8d8\npopulation: 28 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 93f8 e4d6 d35c d455 | 134 a478 (0) a6bd (0) a75d (0) a317 (0)\n001 5 2cab 1d5b 10b1 0536 | 72 24f8 (0) 2737 (0) 208e (0) 2224 (0)\n002 2 7e45 6caa | 19 7ec4 (0) 7e45 (0) 7aef (0) 7810 (0)\n003 6 5a67 5cae 5e3e 5399 | 15 581a (0) 5b30 (0) 5a67 (0) 5c9b (0)\n004 4 464b 44c8 44b7 41b2 | 8 47a8 (0) 464b (0) 44c8 (0) 44b7 (0)\n005 2 4c97 4dc4 | 2 4c97 (0) 4dc4 (0)\n006 2 48df 48ec | 2 48df (0) 48ec (0)\n007 0 | 0\n008 1 4b70 | 1 4b70 (0)\n============ DEPTH: 9 ==========================================\n009 2 4bbc 4b8a | 2 4bbc (0) 4b8a (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"11d560045536e9d1b0b1b9e8944e00f0ca7f1e6788c9fdb51061820bbb3008ead92bb7836621bf58da7035c87a28328faecb4cb2e3cdb9d7fa4f45790e6bf352","private_key":"5a603b46da0d4b5d7b48ca9ee9f08ca4cde411e8e279454ac25624f0a81580d5","name":"node_11d560045536e9d1b0b1b9e8944e00f0ca7f1e6788c9fdb51061820bbb3008ead92bb7836621bf58da7035c87a28328faecb4cb2e3cdb9d7fa4f45790e6bf352","services":["streamer"],"enable_msg_events":true,"port":63337},"up":true}},{"node":{"info":{"id":"94088fe273f76e62ca4e43c095ad12215b4ae4c59942328b3985416fb19bbda0cacc143a49eff3fb644ad53a19d3f043260e43dbb70a0aa9c15829c21cecd3c7","name":"node_94088fe273f76e62ca4e43c095ad12215b4ae4c59942328b3985416fb19bbda0cacc143a49eff3fb644ad53a19d3f043260e43dbb70a0aa9c15829c21cecd3c7","enode":"enode://94088fe273f76e62ca4e43c095ad12215b4ae4c59942328b3985416fb19bbda0cacc143a49eff3fb644ad53a19d3f043260e43dbb70a0aa9c15829c21cecd3c7@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"V2V+e30mQsbl2u/ScADQ2kGYJJFIb9Gu5X0PmfBypHE=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 57657e\npopulation: 21 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 e4d6 d455 d35c | 134 a478 (0) a75d (0) a6bd (0) a317 (0)\n001 3 10b1 1d5b 0ad6 | 72 24f8 (0) 2737 (0) 208e (0) 2224 (0)\n002 4 6caa 7e45 7810 76a5 | 19 7e45 (0) 7ec4 (0) 7aef (0) 7810 (0)\n003 2 41b2 4bf8 | 16 464b (0) 47a8 (0) 44c8 (0) 44b7 (0)\n004 3 5c9b 5cae 5e3e | 6 581a (0) 5b30 (0) 5a67 (0) 5c9b (0)\n005 3 5070 510c 5399 | 5 510c (0) 5062 (0) 5070 (0) 5237 (0)\n006 0 | 0\n007 1 56bb | 1 56bb (0)\n============ DEPTH: 8 ==========================================\n008 1 57ee | 1 57ee (0)\n009 0 | 0\n010 1 5741 | 1 5741 (0)\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"94088fe273f76e62ca4e43c095ad12215b4ae4c59942328b3985416fb19bbda0cacc143a49eff3fb644ad53a19d3f043260e43dbb70a0aa9c15829c21cecd3c7","private_key":"955c0d00b5c9a641e3e9958a032163ac01fd30e25660ec50db255cf9349573cf","name":"node_94088fe273f76e62ca4e43c095ad12215b4ae4c59942328b3985416fb19bbda0cacc143a49eff3fb644ad53a19d3f043260e43dbb70a0aa9c15829c21cecd3c7","services":["streamer"],"enable_msg_events":true,"port":63338},"up":true}},{"node":{"info":{"id":"535f93057d46c4aae0902546550880be0b5ba67dca12350117d471d67f4f2b3f7bdff29bdc918767974c465df8fa1afa6bd6c29c0a36d51f71c4183673d906f3","name":"node_535f93057d46c4aae0902546550880be0b5ba67dca12350117d471d67f4f2b3f7bdff29bdc918767974c465df8fa1afa6bd6c29c0a36d51f71c4183673d906f3","enode":"enode://535f93057d46c4aae0902546550880be0b5ba67dca12350117d471d67f4f2b3f7bdff29bdc918767974c465df8fa1afa6bd6c29c0a36d51f71c4183673d906f3@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"5Na3iJ1FTNAe6TP5rigiFwJJXXmsvRBFgILOkMCftpE=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: e4d6b7\npopulation: 29 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 6 5765 4bf8 2737 0ad6 | 122 208e (0) 2220 (0) 2224 (0) 24f8 (0)\n001 3 beb7 9108 93f8 | 63 af8f (0) ac62 (0) aa78 (0) a9df (0)\n002 5 c60e d35c d044 d455 | 33 ce71 (0) cf77 (0) cbd3 (0) cba4 (0)\n003 1 f1b9 | 13 f97e (0) ffb7 (0) fc88 (0) fd44 (0)\n004 4 efdd ee52 e850 ebe8 | 12 ebc9 (0) ebe8 (0) e9fa (0) e850 (0)\n005 2 e3d8 e31e | 4 e190 (0) e31e (0) e3d8 (0) e255 (0)\n006 2 e724 e6b7 | 2 e6b7 (0) e724 (0)\n007 3 e5d2 e56c e54d | 3 e5d2 (0) e56c (0) e54d (0)\n============ DEPTH: 8 ==========================================\n008 2 e469 e406 | 2 e406 (0) e469 (0)\n009 0 | 0\n010 1 e4e9 | 1 e4e9 (0)\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"535f93057d46c4aae0902546550880be0b5ba67dca12350117d471d67f4f2b3f7bdff29bdc918767974c465df8fa1afa6bd6c29c0a36d51f71c4183673d906f3","private_key":"3a0fa647e1aa93088fd931cceb89e4426c10861ebbddde0f14a58e2a3969c252","name":"node_535f93057d46c4aae0902546550880be0b5ba67dca12350117d471d67f4f2b3f7bdff29bdc918767974c465df8fa1afa6bd6c29c0a36d51f71c4183673d906f3","services":["streamer"],"enable_msg_events":true,"port":63339},"up":true}},{"node":{"info":{"id":"7ac5b07eb555af3bb4ca3f0f4b45204d43cc3798c244435909b97d9a32fc3abf0b50666e260e046bce826a7a102a92d389f8f39c5311e83bb34beddac29d50e3","name":"node_7ac5b07eb555af3bb4ca3f0f4b45204d43cc3798c244435909b97d9a32fc3abf0b50666e260e046bce826a7a102a92d389f8f39c5311e83bb34beddac29d50e3","enode":"enode://7ac5b07eb555af3bb4ca3f0f4b45204d43cc3798c244435909b97d9a32fc3abf0b50666e260e046bce826a7a102a92d389f8f39c5311e83bb34beddac29d50e3@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"HVuFRo2GjOwvG+Xxx9yJsz9h0nqwTnUKVWseOq8/fBU=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 1d5b85\npopulation: 27 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 93f8 e4d6 ee52 | 134 af8f (0) ac62 (0) aa78 (0) a9df (0)\n001 5 5399 5765 5741 4bf8 | 50 7ec4 (0) 7e45 (0) 7aef (0) 7810 (0)\n002 3 2220 3734 3227 | 35 24f8 (0) 2737 (0) 208e (0) 2224 (0)\n003 3 0536 0f65 0ad6 | 18 0d97 (0) 0daf (0) 0ca9 (0) 0c19 (0)\n004 4 17a0 167b 1254 10b1 | 9 14e4 (0) 1587 (0) 15ec (0) 1758 (0)\n005 4 1953 1a8e 1a85 1af6 | 4 1953 (0) 1a8e (0) 1a85 (0) 1af6 (0)\n006 2 1ea1 1fab | 2 1ea1 (0) 1fab (0)\n007 0 | 0\n============ DEPTH: 8 ==========================================\n008 3 1daa 1dfd 1dfc | 3 1daa (0) 1dfd (0) 1dfc (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"7ac5b07eb555af3bb4ca3f0f4b45204d43cc3798c244435909b97d9a32fc3abf0b50666e260e046bce826a7a102a92d389f8f39c5311e83bb34beddac29d50e3","private_key":"22c2b405d07e440cdef6e1e9d93738f3bf3add71f54493b68b2fa368c3187755","name":"node_7ac5b07eb555af3bb4ca3f0f4b45204d43cc3798c244435909b97d9a32fc3abf0b50666e260e046bce826a7a102a92d389f8f39c5311e83bb34beddac29d50e3","services":["streamer"],"enable_msg_events":true,"port":63340},"up":true}},{"node":{"info":{"id":"1944f98d4db32c56a5efda5a79aa5f276bfab1e084d6611fec0e735b8bc0f45b457cdb74a23fc83b2377821fa8316123c9877acd6db7c41058ca5d3cfedaecf9","name":"node_1944f98d4db32c56a5efda5a79aa5f276bfab1e084d6611fec0e735b8bc0f45b457cdb74a23fc83b2377821fa8316123c9877acd6db7c41058ca5d3cfedaecf9","enode":"enode://1944f98d4db32c56a5efda5a79aa5f276bfab1e084d6611fec0e735b8bc0f45b457cdb74a23fc83b2377821fa8316123c9877acd6db7c41058ca5d3cfedaecf9@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"ELFtU9FqzJ/MnSMhvsfPardgC/EdqVXdT2KNC7ktmc4=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 10b16d\npopulation: 24 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 e4d6 ee52 | 134 af8f (0) ac62 (0) a9df (0) a936 (0)\n001 5 5765 5741 4bf8 44b7 | 50 7ec4 (0) 7e45 (0) 7aef (0) 7810 (0)\n002 2 3734 3227 | 35 24f8 (0) 2737 (0) 208e (0) 2224 (0)\n003 6 0ad6 0c19 0daf 0f65 | 18 0305 (0) 020f (0) 0020 (0) 00c8 (0)\n004 4 1953 1af6 1dfd 1d5b | 10 1953 (0) 1a8e (0) 1a85 (0) 1af6 (0)\n005 3 15ec 167b 17a0 | 6 14e4 (0) 1587 (0) 15ec (0) 167b (0)\n============ DEPTH: 6 ==========================================\n006 1 1254 | 1 1254 (0)\n007 1 11a0 | 1 11a0 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"1944f98d4db32c56a5efda5a79aa5f276bfab1e084d6611fec0e735b8bc0f45b457cdb74a23fc83b2377821fa8316123c9877acd6db7c41058ca5d3cfedaecf9","private_key":"98f9b63dc3d1c346c60957731df1731c8b5f7cbfa63ec1e4de06d1b9f70f7597","name":"node_1944f98d4db32c56a5efda5a79aa5f276bfab1e084d6611fec0e735b8bc0f45b457cdb74a23fc83b2377821fa8316123c9877acd6db7c41058ca5d3cfedaecf9","services":["streamer"],"enable_msg_events":true,"port":63341},"up":true}},{"node":{"info":{"id":"1c2f7ce55a6e38487f3b3fe6083a79f914cd6d7e4aee8f5d56b4a61b3eb584e128c56998db0e13e775edee3adacf54f09960a041dab3daa80a4f8a3b42760c1c","name":"node_1c2f7ce55a6e38487f3b3fe6083a79f914cd6d7e4aee8f5d56b4a61b3eb584e128c56998db0e13e775edee3adacf54f09960a041dab3daa80a4f8a3b42760c1c","enode":"enode://1c2f7ce55a6e38487f3b3fe6083a79f914cd6d7e4aee8f5d56b4a61b3eb584e128c56998db0e13e775edee3adacf54f09960a041dab3daa80a4f8a3b42760c1c@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"QbK3E9ujoRaDrYPRy0vrn/T1qvSfKtGsIkfISoXUClY=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 41b2b7\npopulation: 18 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 93f8 | 134 a75d (0) a6bd (0) a478 (0) a317 (0)\n001 3 3227 1d5b 10b1 | 72 24f8 (0) 2737 (0) 208e (0) 2224 (0)\n002 2 7e45 76a5 | 19 7ec4 (0) 7e45 (0) 7aef (0) 7810 (0)\n003 5 5cae 5e3e 5399 5765 | 15 581a (0) 5b30 (0) 5a67 (0) 5c9b (0)\n004 2 4dc4 4bf8 | 8 4c97 (0) 4dc4 (0) 48df (0) 48ec (0)\n005 2 44c8 44b7 | 4 47a8 (0) 464b (0) 44c8 (0) 44b7 (0)\n============ DEPTH: 6 ==========================================\n006 2 42d6 43fb | 2 42d6 (0) 43fb (0)\n007 0 | 0\n008 1 413b | 1 413b (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"1c2f7ce55a6e38487f3b3fe6083a79f914cd6d7e4aee8f5d56b4a61b3eb584e128c56998db0e13e775edee3adacf54f09960a041dab3daa80a4f8a3b42760c1c","private_key":"fef764b306a01b333cb965c1faf6970b6bf206dd19c10f666d0188e532d27a7c","name":"node_1c2f7ce55a6e38487f3b3fe6083a79f914cd6d7e4aee8f5d56b4a61b3eb584e128c56998db0e13e775edee3adacf54f09960a041dab3daa80a4f8a3b42760c1c","services":["streamer"],"enable_msg_events":true,"port":63342},"up":true}},{"node":{"info":{"id":"6ab6ec15635b2fda22542c99df0a3313ad4583ba0fb3f31b8f314e3ecad446d3fb0fdfcd2be9b08374b1a7e049fb68e69e8dacdd13f1df5007a656f6b11adc5b","name":"node_6ab6ec15635b2fda22542c99df0a3313ad4583ba0fb3f31b8f314e3ecad446d3fb0fdfcd2be9b08374b1a7e049fb68e69e8dacdd13f1df5007a656f6b11adc5b","enode":"enode://6ab6ec15635b2fda22542c99df0a3313ad4583ba0fb3f31b8f314e3ecad446d3fb0fdfcd2be9b08374b1a7e049fb68e69e8dacdd13f1df5007a656f6b11adc5b@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"V0EBUA9k6aG/vzH083mmCg6pvuRJrxzSmWIhTdlgs8Y=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 574101\npopulation: 18 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 d044 | 134 a478 (0) a75d (0) a6bd (0) a3f2 (0)\n001 3 3ff8 1d5b 10b1 | 72 24f8 (0) 2737 (0) 208e (0) 2224 (0)\n002 2 7e45 7810 | 19 7239 (0) 7299 (0) 71bf (0) 715b (0)\n003 3 4bf8 44c8 41b2 | 16 4c97 (0) 4dc4 (0) 48df (0) 48ec (0)\n004 3 5a67 5cae 5e3e | 6 581a (0) 5b30 (0) 5a67 (0) 5c9b (0)\n005 3 5070 510c 5399 | 5 510c (0) 5062 (0) 5070 (0) 5237 (0)\n006 0 | 0\n007 1 56bb | 1 56bb (0)\n============ DEPTH: 8 ==========================================\n008 1 57ee | 1 57ee (0)\n009 0 | 0\n010 1 5765 | 1 5765 (0)\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"6ab6ec15635b2fda22542c99df0a3313ad4583ba0fb3f31b8f314e3ecad446d3fb0fdfcd2be9b08374b1a7e049fb68e69e8dacdd13f1df5007a656f6b11adc5b","private_key":"aa54e42fb6be9a738ce973816a814b29759c40f5ae5c57ef972c8957be9d1cdf","name":"node_6ab6ec15635b2fda22542c99df0a3313ad4583ba0fb3f31b8f314e3ecad446d3fb0fdfcd2be9b08374b1a7e049fb68e69e8dacdd13f1df5007a656f6b11adc5b","services":["streamer"],"enable_msg_events":true,"port":63343},"up":true}},{"node":{"info":{"id":"74d84cfdaf32cd4cc67771f29878f1365120bd65cc14848008d5386a81f495bf88eb4132fa38a2cc109ae1e7f02c9b97597ab9d1a9c19c945e710ab9df07cdcd","name":"node_74d84cfdaf32cd4cc67771f29878f1365120bd65cc14848008d5386a81f495bf88eb4132fa38a2cc109ae1e7f02c9b97597ab9d1a9c19c945e710ab9df07cdcd","enode":"enode://74d84cfdaf32cd4cc67771f29878f1365120bd65cc14848008d5386a81f495bf88eb4132fa38a2cc109ae1e7f02c9b97597ab9d1a9c19c945e710ab9df07cdcd@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"0EQ/JFI68O7Gwgsh2EstVMsLqNTRogW0Eyi7IujTzWM=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: d0443f\npopulation: 19 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 5741 | 122 24f8 (0) 2737 (0) 208e (0) 2224 (0)\n001 3 9108 92d5 93f8 | 63 a478 (0) a75d (0) a6bd (0) a3f2 (0)\n002 2 e4d6 ee52 | 38 f97e (0) ffb7 (0) fc88 (0) fd44 (0)\n003 2 c911 c3d8 | 14 ce71 (0) cf77 (0) cba4 (0) cbd3 (0)\n004 2 de1d dad3 | 5 de1d (0) df52 (0) d90b (0) d96e (0)\n005 3 d66f d560 d455 | 7 d777 (0) d717 (0) d7c1 (0) d606 (0)\n006 3 d2ac d3bd d35c | 3 d2ac (0) d3bd (0) d35c (0)\n007 1 d1bc | 1 d1bc (0)\n============ DEPTH: 8 ==========================================\n008 1 d0b7 | 1 d0b7 (0)\n009 0 | 0\n010 1 d07c | 1 d07c (0)\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"74d84cfdaf32cd4cc67771f29878f1365120bd65cc14848008d5386a81f495bf88eb4132fa38a2cc109ae1e7f02c9b97597ab9d1a9c19c945e710ab9df07cdcd","private_key":"c0a44ebed32208583420c7444e83ac3526001946e4f7f6b561c24d98f96cc0a6","name":"node_74d84cfdaf32cd4cc67771f29878f1365120bd65cc14848008d5386a81f495bf88eb4132fa38a2cc109ae1e7f02c9b97597ab9d1a9c19c945e710ab9df07cdcd","services":["streamer"],"enable_msg_events":true,"port":63344},"up":true}},{"node":{"info":{"id":"6b4e376e9c94242b6d42688c22aa9ab418cb6dfb1cbca1c69de0feceec8d3af29fb005017aaa6e503cc0c03cf0dc5bcab55e01cd6f64b9efa02ed87c03020003","name":"node_6b4e376e9c94242b6d42688c22aa9ab418cb6dfb1cbca1c69de0feceec8d3af29fb005017aaa6e503cc0c03cf0dc5bcab55e01cd6f64b9efa02ed87c03020003","enode":"enode://6b4e376e9c94242b6d42688c22aa9ab418cb6dfb1cbca1c69de0feceec8d3af29fb005017aaa6e503cc0c03cf0dc5bcab55e01cd6f64b9efa02ed87c03020003@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"k/iL7tzn+VgezAVhW6FfsxMAajKhWa3xafLgLsxpdZg=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 93f88b\npopulation: 22 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 1d5b 4bf8 41b2 | 122 24f8 (0) 2737 (0) 208e (0) 2224 (0)\n001 7 e4d6 ee52 c60e c3d8 | 71 f97e (0) ffb7 (0) fc88 (0) fd44 (0)\n002 4 bd39 beb7 b30e b40d | 30 a478 (0) a75d (0) a6bd (0) a3f2 (0)\n003 1 8ae8 | 15 83d0 (0) 802f (0) 802e (0) 8434 (0)\n004 2 99eb 98bc | 10 9f4c (0) 9a09 (0) 9b87 (0) 9bc3 (0)\n005 2 9493 9641 | 4 9404 (0) 9493 (0) 9747 (0) 9641 (0)\n============ DEPTH: 6 ==========================================\n006 2 910d 9108 | 2 910d (0) 9108 (0)\n007 1 92d5 | 1 92d5 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"6b4e376e9c94242b6d42688c22aa9ab418cb6dfb1cbca1c69de0feceec8d3af29fb005017aaa6e503cc0c03cf0dc5bcab55e01cd6f64b9efa02ed87c03020003","private_key":"d38eae2be9d262c3b37bbd8afb82bc0cd431e4c484ae92747ad064e4138e9f33","name":"node_6b4e376e9c94242b6d42688c22aa9ab418cb6dfb1cbca1c69de0feceec8d3af29fb005017aaa6e503cc0c03cf0dc5bcab55e01cd6f64b9efa02ed87c03020003","services":["streamer"],"enable_msg_events":true,"port":63345},"up":true}},{"node":{"info":{"id":"92d6ef729992f0de886076e5f8cdc42cbbd70b29e79c25e0b3d22b6575d3d2508d47b42f581e335455483d43625bce4e55f88cab9ff2073ee8dab746357864fd","name":"node_92d6ef729992f0de886076e5f8cdc42cbbd70b29e79c25e0b3d22b6575d3d2508d47b42f581e335455483d43625bce4e55f88cab9ff2073ee8dab746357864fd","enode":"enode://92d6ef729992f0de886076e5f8cdc42cbbd70b29e79c25e0b3d22b6575d3d2508d47b42f581e335455483d43625bce4e55f88cab9ff2073ee8dab746357864fd@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"7lJ9/9S64YgOPF3cui4vsXBsTUCAThAsnz1RQTerBz4=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: ee527d\npopulation: 30 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 0536 10b1 1d5b 3227 | 122 60bc (0) 63de (0) 65a6 (0) 67ee (0)\n001 4 beb7 9108 92d5 93f8 | 63 a478 (0) a6bd (0) a75d (0) a317 (0)\n002 5 c95a d455 d66f d35c | 33 ce71 (0) cf77 (0) cba4 (0) cbd3 (0)\n003 2 f293 f1b9 | 13 f97e (0) ffb7 (0) fc88 (0) fd44 (0)\n004 4 e3d8 e255 e4d6 e469 | 13 e190 (0) e31e (0) e3d8 (0) e255 (0)\n005 4 e9fa e850 ebe8 ebc9 | 4 ebc9 (0) ebe8 (0) e9fa (0) e850 (0)\n006 2 ecff ec78 | 2 ecff (0) ec78 (0)\n007 3 efbb efc1 efdd | 3 efbb (0) efc1 (0) efdd (0)\n============ DEPTH: 8 ==========================================\n008 1 eee1 | 1 eee1 (0)\n009 1 ee3f | 1 ee3f (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"92d6ef729992f0de886076e5f8cdc42cbbd70b29e79c25e0b3d22b6575d3d2508d47b42f581e335455483d43625bce4e55f88cab9ff2073ee8dab746357864fd","private_key":"e345c696901db291ce988a19c0ad31ca0a38628ebc03c0bc87307d2c8f031346","name":"node_92d6ef729992f0de886076e5f8cdc42cbbd70b29e79c25e0b3d22b6575d3d2508d47b42f581e335455483d43625bce4e55f88cab9ff2073ee8dab746357864fd","services":["streamer"],"enable_msg_events":true,"port":63346},"up":true}},{"node":{"info":{"id":"57cd4c0048b459192ee46e19ec7df777e600f256e0dc8c3019431eb7bec3c020b9504ec7aea3dba8188658ca5b830ec40af6a8540ce10e04badc6c695d009271","name":"node_57cd4c0048b459192ee46e19ec7df777e600f256e0dc8c3019431eb7bec3c020b9504ec7aea3dba8188658ca5b830ec40af6a8540ce10e04badc6c695d009271","enode":"enode://57cd4c0048b459192ee46e19ec7df777e600f256e0dc8c3019431eb7bec3c020b9504ec7aea3dba8188658ca5b830ec40af6a8540ce10e04badc6c695d009271@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"MicQOJetr75P46rSBrq4JTu4Ar2YCgxhiFAL6J5lbt0=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 322710\npopulation: 30 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 5 9108 92d5 caa3 c3d8 | 134 a9df (0) a936 (0) aa78 (0) ac62 (0)\n001 3 44b7 41b2 76a5 | 50 60bc (0) 63de (0) 65a6 (0) 67ee (0)\n002 6 10b1 17a0 1af6 1d5b | 37 0fa0 (0) 0f65 (0) 0d97 (0) 0daf (0)\n003 5 2220 2737 2940 2cb1 | 15 24f8 (0) 2737 (0) 208e (0) 2224 (0)\n004 4 3ef6 3ff8 3a18 3843 | 10 3c5a (0) 3d17 (0) 3ff8 (0) 3ef6 (0)\n005 3 3607 3799 3734 | 5 34e4 (0) 3658 (0) 3607 (0) 3799 (0)\n============ DEPTH: 6 ==========================================\n006 3 3085 3054 307c | 3 3085 (0) 3054 (0) 307c (0)\n007 1 3388 | 1 3388 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"57cd4c0048b459192ee46e19ec7df777e600f256e0dc8c3019431eb7bec3c020b9504ec7aea3dba8188658ca5b830ec40af6a8540ce10e04badc6c695d009271","private_key":"7149ecac9f7173c182b233a94bfcf854714955592618e1d9500c622a08fc3faf","name":"node_57cd4c0048b459192ee46e19ec7df777e600f256e0dc8c3019431eb7bec3c020b9504ec7aea3dba8188658ca5b830ec40af6a8540ce10e04badc6c695d009271","services":["streamer"],"enable_msg_events":true,"port":63347},"up":true}},{"node":{"info":{"id":"831cde5b651ba327b059da4c7f84b184bdd6bb99c6690ae816affe25d42c6c3dbe5b59e2b6bf23e9d0f6c485bd341ea57ba1a8220d18b0a40e156b77d84f79ef","name":"node_831cde5b651ba327b059da4c7f84b184bdd6bb99c6690ae816affe25d42c6c3dbe5b59e2b6bf23e9d0f6c485bd341ea57ba1a8220d18b0a40e156b77d84f79ef","enode":"enode://831cde5b651ba327b059da4c7f84b184bdd6bb99c6690ae816affe25d42c6c3dbe5b59e2b6bf23e9d0f6c485bd341ea57ba1a8220d18b0a40e156b77d84f79ef@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"BTYIjhS4GJm5FM/OvSo8Pdu775Bf+2k3VhPUhTZnvhg=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 053608\npopulation: 23 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 ee52 c3d8 ce71 c95a | 134 a478 (0) a75d (0) a6bd (0) a3f2 (0)\n001 3 7299 7810 4bf8 | 50 60bc (0) 63de (0) 65a6 (0) 67ee (0)\n002 2 2e3b 3227 | 35 24f8 (0) 2737 (0) 208e (0) 2224 (0)\n003 4 1d5b 1af6 10b1 17a0 | 19 1ea1 (0) 1fab (0) 1dfd (0) 1dfc (0)\n004 7 0ca9 0c72 0c19 0d97 | 11 0fa0 (0) 0f65 (0) 0d97 (0) 0daf (0)\n005 1 00c8 | 4 0305 (0) 020f (0) 0020 (0) 00c8 (0)\n============ DEPTH: 6 ==========================================\n006 1 07a6 | 1 07a6 (0)\n007 0 | 0\n008 1 05a4 | 1 05a4 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"831cde5b651ba327b059da4c7f84b184bdd6bb99c6690ae816affe25d42c6c3dbe5b59e2b6bf23e9d0f6c485bd341ea57ba1a8220d18b0a40e156b77d84f79ef","private_key":"cf6da8ba09884f084c279f1f25340712041f3c36c9b6be1c0fec270bdf17a875","name":"node_831cde5b651ba327b059da4c7f84b184bdd6bb99c6690ae816affe25d42c6c3dbe5b59e2b6bf23e9d0f6c485bd341ea57ba1a8220d18b0a40e156b77d84f79ef","services":["streamer"],"enable_msg_events":true,"port":63348},"up":true}},{"node":{"info":{"id":"71f89efcf939294bb94ac669c8afd00def58c8dfad519c226adfa068692d588ef797116d42aa146b9d34f3be35ec7c014022640ab3c0f1f9034e44ab1a26e246","name":"node_71f89efcf939294bb94ac669c8afd00def58c8dfad519c226adfa068692d588ef797116d42aa146b9d34f3be35ec7c014022640ab3c0f1f9034e44ab1a26e246","enode":"enode://71f89efcf939294bb94ac669c8afd00def58c8dfad519c226adfa068692d588ef797116d42aa146b9d34f3be35ec7c014022640ab3c0f1f9034e44ab1a26e246@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"yVpIGxlYP8hemwefoLXPUetG5xufV/xt8uO3g4nY3i8=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: c95a48\npopulation: 18 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 17a0 0536 | 122 581a (0) 5b30 (0) 5a67 (0) 5c9b (0)\n001 2 92d5 9108 | 63 a478 (0) a75d (0) a6bd (0) a3f2 (0)\n002 2 efdd ee52 | 38 f97e (0) ffb7 (0) fc88 (0) fd44 (0)\n003 3 d35c d66f d455 | 19 de1d (0) df52 (0) d96e (0) d90b (0)\n004 2 c60e c3d8 | 5 c409 (0) c7fa (0) c60e (0) c301 (0)\n005 2 ce71 cf77 | 2 ce71 (0) cf77 (0)\n006 3 caa3 cba4 cbd3 | 4 cba4 (0) cbd3 (0) ca8c (0) caa3 (0)\n007 0 | 0\n008 0 | 0\n============ DEPTH: 9 ==========================================\n009 2 c914 c911 | 2 c914 (0) c911 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"71f89efcf939294bb94ac669c8afd00def58c8dfad519c226adfa068692d588ef797116d42aa146b9d34f3be35ec7c014022640ab3c0f1f9034e44ab1a26e246","private_key":"2acdb11a79e469d5e7e20a391253ad6909ecab541c9931d5f7422de792574b6b","name":"node_71f89efcf939294bb94ac669c8afd00def58c8dfad519c226adfa068692d588ef797116d42aa146b9d34f3be35ec7c014022640ab3c0f1f9034e44ab1a26e246","services":["streamer"],"enable_msg_events":true,"port":63349},"up":true}},{"node":{"info":{"id":"4ff66e9b5d3fd345990bd7605bdc222b78946f0c13b72bf80352812b2426d8f1d36c93e6c8713566004615e8a78ecab12ab0cfba254c0967eeecf8875b25bdae","name":"node_4ff66e9b5d3fd345990bd7605bdc222b78946f0c13b72bf80352812b2426d8f1d36c93e6c8713566004615e8a78ecab12ab0cfba254c0967eeecf8875b25bdae","enode":"enode://4ff66e9b5d3fd345990bd7605bdc222b78946f0c13b72bf80352812b2426d8f1d36c93e6c8713566004615e8a78ecab12ab0cfba254c0967eeecf8875b25bdae@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"kQiOp5zY8n2oh5dg3SHDY6qb4RNUN8K4dGRCaHS1l+U=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 91088e\npopulation: 21 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 76a5 7810 3227 17a0 | 122 581a (0) 5b30 (0) 5a67 (0) 5c9b (0)\n001 7 e4d6 ee52 d455 d35c | 71 f97e (0) ffb7 (0) fc88 (0) fd44 (0)\n002 2 b30e beb7 | 30 a478 (0) a75d (0) a6bd (0) a3f2 (0)\n003 1 8ae8 | 15 83d0 (0) 802f (0) 802e (0) 8434 (0)\n004 2 98bc 99eb | 10 9f4c (0) 9a09 (0) 9b87 (0) 9bc3 (0)\n005 2 9493 9641 | 4 9404 (0) 9493 (0) 9747 (0) 9641 (0)\n============ DEPTH: 6 ==========================================\n006 2 93f8 92d5 | 2 93f8 (0) 92d5 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 1 910d | 1 910d (0)\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"4ff66e9b5d3fd345990bd7605bdc222b78946f0c13b72bf80352812b2426d8f1d36c93e6c8713566004615e8a78ecab12ab0cfba254c0967eeecf8875b25bdae","private_key":"63cfea5298455b0cf7952a47db686e5c91ca2f2e16610167e5c15337e67feeab","name":"node_4ff66e9b5d3fd345990bd7605bdc222b78946f0c13b72bf80352812b2426d8f1d36c93e6c8713566004615e8a78ecab12ab0cfba254c0967eeecf8875b25bdae","services":["streamer"],"enable_msg_events":true,"port":63350},"up":true}},{"node":{"info":{"id":"9bd4f0adb9a966cc5ba632f1b540fe9cd6c8e39fe1a041b315697679cfb04b735952062ce057d456677cc34a84301f26bb727a4ab2646fee734f80a22c620746","name":"node_9bd4f0adb9a966cc5ba632f1b540fe9cd6c8e39fe1a041b315697679cfb04b735952062ce057d456677cc34a84301f26bb727a4ab2646fee734f80a22c620746","enode":"enode://9bd4f0adb9a966cc5ba632f1b540fe9cd6c8e39fe1a041b315697679cfb04b735952062ce057d456677cc34a84301f26bb727a4ab2646fee734f80a22c620746@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"ktVlsTBo6LmvECr0DhESoAuR45jvDEKikuiNQGxVtPI=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 92d565\npopulation: 22 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 7810 17a0 3227 | 122 581a (0) 5b30 (0) 5a67 (0) 5c9b (0)\n001 6 ee52 d35c d044 d455 | 71 f97e (0) ffb7 (0) fc88 (0) fd44 (0)\n002 2 beb7 bd39 | 30 a478 (0) a75d (0) a6bd (0) a3f2 (0)\n003 1 8ae8 | 15 83d0 (0) 802f (0) 802e (0) 8611 (0)\n004 5 98bc 985f 99eb 9a09 | 10 9f4c (0) 9a09 (0) 9b87 (0) 9bc3 (0)\n005 2 9747 9641 | 4 9404 (0) 9493 (0) 9747 (0) 9641 (0)\n============ DEPTH: 6 ==========================================\n006 2 910d 9108 | 2 910d (0) 9108 (0)\n007 1 93f8 | 1 93f8 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"9bd4f0adb9a966cc5ba632f1b540fe9cd6c8e39fe1a041b315697679cfb04b735952062ce057d456677cc34a84301f26bb727a4ab2646fee734f80a22c620746","private_key":"28315ffa74cadce008f22997503621aee7c6df8dd478536421715a17ebb97a74","name":"node_9bd4f0adb9a966cc5ba632f1b540fe9cd6c8e39fe1a041b315697679cfb04b735952062ce057d456677cc34a84301f26bb727a4ab2646fee734f80a22c620746","services":["streamer"],"enable_msg_events":true,"port":63351},"up":true}},{"node":{"info":{"id":"58cfb20d3da3641e0ad529b9edbd4b590a8d1dc9d1ed7b44ed3187dba9260bd7c732fc10981f5b9bffd31d362cb05150173618aa36138984431d94a323a9b313","name":"node_58cfb20d3da3641e0ad529b9edbd4b590a8d1dc9d1ed7b44ed3187dba9260bd7c732fc10981f5b9bffd31d362cb05150173618aa36138984431d94a323a9b313","enode":"enode://58cfb20d3da3641e0ad529b9edbd4b590a8d1dc9d1ed7b44ed3187dba9260bd7c732fc10981f5b9bffd31d362cb05150173618aa36138984431d94a323a9b313@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"w9i07lMvYG5GBmbkVWnH9UuvSsxp4e0CevTX8R4ZTa4=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: c3d8b4\npopulation: 26 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 6 7810 7299 76a5 3227 | 122 581a (0) 5b30 (0) 5a67 (0) 5c9b (0)\n001 5 bd39 beb7 9108 93f8 | 63 a478 (0) a6bd (0) a75d (0) a3f2 (0)\n002 2 e850 efdd | 38 f97e (0) ffb7 (0) fc88 (0) fd44 (0)\n003 2 d044 d66f | 19 de1d (0) df52 (0) d90b (0) d96e (0)\n004 7 cbd3 cba4 caa3 ca8c | 9 ce71 (0) cf77 (0) cba4 (0) cbd3 (0)\n============ DEPTH: 5 ==========================================\n005 3 c409 c7fa c60e | 3 c409 (0) c7fa (0) c60e (0)\n006 0 | 0\n007 0 | 0\n008 1 c301 | 1 c301 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"58cfb20d3da3641e0ad529b9edbd4b590a8d1dc9d1ed7b44ed3187dba9260bd7c732fc10981f5b9bffd31d362cb05150173618aa36138984431d94a323a9b313","private_key":"1177b8e7b7ed31f6a54030f8b4341593d3a1d72aae40f9156861650da1746f2e","name":"node_58cfb20d3da3641e0ad529b9edbd4b590a8d1dc9d1ed7b44ed3187dba9260bd7c732fc10981f5b9bffd31d362cb05150173618aa36138984431d94a323a9b313","services":["streamer"],"enable_msg_events":true,"port":63352},"up":true}},{"node":{"info":{"id":"094f9d0fd3bacb17ac67a2edb8ed394fbbd1c8d478233d3269cf217e7b788e21042374936b885bf23ee4f9e03babbe4e08db283dfc2a6e052a8a5ba133717dd5","name":"node_094f9d0fd3bacb17ac67a2edb8ed394fbbd1c8d478233d3269cf217e7b788e21042374936b885bf23ee4f9e03babbe4e08db283dfc2a6e052a8a5ba133717dd5","enode":"enode://094f9d0fd3bacb17ac67a2edb8ed394fbbd1c8d478233d3269cf217e7b788e21042374936b885bf23ee4f9e03babbe4e08db283dfc2a6e052a8a5ba133717dd5@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"F6ACJqybK7D4PprdnAyhvMgwow42sUYgB/viYQkPepo=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 17a002\npopulation: 23 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 6 bd39 92d5 9108 f1b9 | 134 a478 (0) a75d (0) a6bd (0) a3f2 (0)\n001 2 7810 76a5 | 50 581a (0) 5b30 (0) 5a67 (0) 5c9b (0)\n002 2 2940 3227 | 35 208e (0) 2224 (0) 2220 (0) 24f8 (0)\n003 2 0f65 0536 | 18 0fa0 (0) 0f65 (0) 0d97 (0) 0daf (0)\n004 3 1d5b 1953 1af6 | 10 1ea1 (0) 1fab (0) 1dfd (0) 1dfc (0)\n005 3 1254 11a0 10b1 | 3 1254 (0) 11a0 (0) 10b1 (0)\n006 3 14e4 15ec 1587 | 3 14e4 (0) 15ec (0) 1587 (0)\n============ DEPTH: 7 ==========================================\n007 1 167b | 1 167b (0)\n008 1 1758 | 1 1758 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"094f9d0fd3bacb17ac67a2edb8ed394fbbd1c8d478233d3269cf217e7b788e21042374936b885bf23ee4f9e03babbe4e08db283dfc2a6e052a8a5ba133717dd5","private_key":"d007b46d1a1f6a2d085b54b2073f46bebdad50a651920b7083908d388be5e5ef","name":"node_094f9d0fd3bacb17ac67a2edb8ed394fbbd1c8d478233d3269cf217e7b788e21042374936b885bf23ee4f9e03babbe4e08db283dfc2a6e052a8a5ba133717dd5","services":["streamer"],"enable_msg_events":true,"port":63353},"up":true}},{"node":{"info":{"id":"7646d08b3e24183e3814de130235c41eb88a5a2abff23eaff3c91954ad3ef55fe27da422dac5b894312276bf1a2f1aebb8b636a8d4a0c93d9b016d441df3fa19","name":"node_7646d08b3e24183e3814de130235c41eb88a5a2abff23eaff3c91954ad3ef55fe27da422dac5b894312276bf1a2f1aebb8b636a8d4a0c93d9b016d441df3fa19","enode":"enode://7646d08b3e24183e3814de130235c41eb88a5a2abff23eaff3c91954ad3ef55fe27da422dac5b894312276bf1a2f1aebb8b636a8d4a0c93d9b016d441df3fa19@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"dqXRf95OHGceAzhUhQHaOTMsjvWTKdmZsPtv9wQGBZE=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 76a5d1\npopulation: 24 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 bd39 9108 f1b9 c3d8 | 134 a478 (0) a75d (0) a6bd (0) a3f2 (0)\n001 6 38d7 3ff8 3227 0f65 | 72 24f8 (0) 2737 (0) 208e (0) 2224 (0)\n002 2 41b2 5765 | 31 4c97 (0) 4dc4 (0) 48df (0) 48ec (0)\n003 3 6701 63de 6caa | 9 60bc (0) 63de (0) 65a6 (0) 67ee (0)\n004 4 7ec4 7e45 7aef 7810 | 4 7ec4 (0) 7e45 (0) 7aef (0) 7810 (0)\n============ DEPTH: 5 ==========================================\n005 4 7299 7239 71bf 715b | 4 7239 (0) 7299 (0) 71bf (0) 715b (0)\n006 0 | 0\n007 1 77bc | 1 77bc (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"7646d08b3e24183e3814de130235c41eb88a5a2abff23eaff3c91954ad3ef55fe27da422dac5b894312276bf1a2f1aebb8b636a8d4a0c93d9b016d441df3fa19","private_key":"260581578bd37f4523054c95aee9f6b4beea4ed6b39edfb8b9506264d93337d7","name":"node_7646d08b3e24183e3814de130235c41eb88a5a2abff23eaff3c91954ad3ef55fe27da422dac5b894312276bf1a2f1aebb8b636a8d4a0c93d9b016d441df3fa19","services":["streamer"],"enable_msg_events":true,"port":63354},"up":true}},{"node":{"info":{"id":"9b618ad34d0dfe0fccbd5b8af365cbcdbb43e802df5f23e91c20d21f3ead6169d52bf0db7e5e111abef630c9853419fb33a88cf111d8507b8708208b5d65e35e","name":"node_9b618ad34d0dfe0fccbd5b8af365cbcdbb43e802df5f23e91c20d21f3ead6169d52bf0db7e5e111abef630c9853419fb33a88cf111d8507b8708208b5d65e35e","enode":"enode://9b618ad34d0dfe0fccbd5b8af365cbcdbb43e802df5f23e91c20d21f3ead6169d52bf0db7e5e111abef630c9853419fb33a88cf111d8507b8708208b5d65e35e@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"Gva02bNUVV83xb5i/raR36dqUxQE7U3lrSuQXIT8N/o=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 1af6b4\npopulation: 21 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 efdd f1b9 bd39 | 134 a75d (0) a6bd (0) a478 (0) a3f2 (0)\n001 4 4dc4 6701 7810 76a5 | 50 581a (0) 5a67 (0) 5b30 (0) 5c9b (0)\n002 3 2737 2940 3227 | 35 208e (0) 2224 (0) 2220 (0) 24f8 (0)\n003 2 0f65 0536 | 18 09d1 (0) 0bc3 (0) 0a3f (0) 0ad6 (0)\n004 3 1254 10b1 17a0 | 9 1254 (0) 11a0 (0) 10b1 (0) 14e4 (0)\n005 3 1fab 1dfd 1d5b | 6 1ea1 (0) 1fab (0) 1daa (0) 1dfc (0)\n006 1 1953 | 1 1953 (0)\n007 0 | 0\n008 0 | 0\n============ DEPTH: 9 ==========================================\n009 2 1a8e 1a85 | 2 1a8e (0) 1a85 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"9b618ad34d0dfe0fccbd5b8af365cbcdbb43e802df5f23e91c20d21f3ead6169d52bf0db7e5e111abef630c9853419fb33a88cf111d8507b8708208b5d65e35e","private_key":"49be559b16c8e23e2031acd1d93ffd182c0f09e54f7893335d04febec1b48e99","name":"node_9b618ad34d0dfe0fccbd5b8af365cbcdbb43e802df5f23e91c20d21f3ead6169d52bf0db7e5e111abef630c9853419fb33a88cf111d8507b8708208b5d65e35e","services":["streamer"],"enable_msg_events":true,"port":63355},"up":true}},{"node":{"info":{"id":"4a030ebcb1a59230759d25a3c87daed22906b520d55a78eab2083bb52358ddc3a5d2d7c3265e6c54a990bf32d0dacb85905a4173d72ac18fcd74c43ecb8635c5","name":"node_4a030ebcb1a59230759d25a3c87daed22906b520d55a78eab2083bb52358ddc3a5d2d7c3265e6c54a990bf32d0dacb85905a4173d72ac18fcd74c43ecb8635c5","enode":"enode://4a030ebcb1a59230759d25a3c87daed22906b520d55a78eab2083bb52358ddc3a5d2d7c3265e6c54a990bf32d0dacb85905a4173d72ac18fcd74c43ecb8635c5@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"eBCdVg9SnsJMxptp7vYFVUgiXCll6MI8+MBlDS09/S4=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 78109d\npopulation: 22 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 6 c3d8 efdd f1b9 92d5 | 134 de1d (0) df52 (0) d96e (0) d90b (0)\n001 5 38d7 0f65 0536 17a0 | 72 24f8 (0) 2737 (0) 208e (0) 2224 (0)\n002 2 5765 5741 | 31 581a (0) 5b30 (0) 5a67 (0) 5c9b (0)\n003 2 63de 6caa | 9 60bc (0) 63de (0) 65a6 (0) 67ee (0)\n004 4 715b 7299 77bc 76a5 | 6 7239 (0) 7299 (0) 71bf (0) 715b (0)\n============ DEPTH: 5 ==========================================\n005 2 7ec4 7e45 | 2 7ec4 (0) 7e45 (0)\n006 1 7aef | 1 7aef (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"4a030ebcb1a59230759d25a3c87daed22906b520d55a78eab2083bb52358ddc3a5d2d7c3265e6c54a990bf32d0dacb85905a4173d72ac18fcd74c43ecb8635c5","private_key":"7b742610b213ed9b0492c97d62574eafc92dd73cb24ba74c4f1023fb4d8843ae","name":"node_4a030ebcb1a59230759d25a3c87daed22906b520d55a78eab2083bb52358ddc3a5d2d7c3265e6c54a990bf32d0dacb85905a4173d72ac18fcd74c43ecb8635c5","services":["streamer"],"enable_msg_events":true,"port":63356},"up":true}},{"node":{"info":{"id":"e0f78c59a61f2a953553cd5742c58f4a82e38e35ac7eaa237a6ffc9fb0a3a26a2d1d1afae249e611d1320f2cb25804bdbdfb6d77336449716b0f4beb3298b8aa","name":"node_e0f78c59a61f2a953553cd5742c58f4a82e38e35ac7eaa237a6ffc9fb0a3a26a2d1d1afae249e611d1320f2cb25804bdbdfb6d77336449716b0f4beb3298b8aa","enode":"enode://e0f78c59a61f2a953553cd5742c58f4a82e38e35ac7eaa237a6ffc9fb0a3a26a2d1d1afae249e611d1320f2cb25804bdbdfb6d77336449716b0f4beb3298b8aa@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"vTnNxnPEGEGTNH8O/XS7iU9/NqmUwVT/49rc1Fbv5GA=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: bd39cd\npopulation: 16 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 17a0 1af6 76a5 7810 | 122 208e (0) 2224 (0) 2220 (0) 24f8 (0)\n001 3 c3d8 efdd f1b9 | 71 dad3 (0) d96e (0) d90b (0) de1d (0)\n002 2 93f8 92d5 | 33 83d0 (0) 802f (0) 802e (0) 8611 (0)\n003 1 ac62 | 17 a478 (0) a6bd (0) a75d (0) a3f2 (0)\n004 2 b30e b40d | 6 b049 (0) b391 (0) b30e (0) b7aa (0)\n005 2 baaf b820 | 4 b820 (0) bb31 (0) bbcb (0) baaf (0)\n============ DEPTH: 6 ==========================================\n006 2 bf6b beb7 | 2 bf6b (0) beb7 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"e0f78c59a61f2a953553cd5742c58f4a82e38e35ac7eaa237a6ffc9fb0a3a26a2d1d1afae249e611d1320f2cb25804bdbdfb6d77336449716b0f4beb3298b8aa","private_key":"c90aa4ff988d9d5aa9ed033d3c8076c073ebcdcb0131604299ca721f38d363ad","name":"node_e0f78c59a61f2a953553cd5742c58f4a82e38e35ac7eaa237a6ffc9fb0a3a26a2d1d1afae249e611d1320f2cb25804bdbdfb6d77336449716b0f4beb3298b8aa","services":["streamer"],"enable_msg_events":true,"port":63357},"up":true}},{"node":{"info":{"id":"84dfd4e4d9f1204893f190eacc4c3999e175c433f70de86e335d27477c097a0552f211a21764f01a708da4c9e9e6552191a61d3e48f41d0e84f01e7ae3beb34e","name":"node_84dfd4e4d9f1204893f190eacc4c3999e175c433f70de86e335d27477c097a0552f211a21764f01a708da4c9e9e6552191a61d3e48f41d0e84f01e7ae3beb34e","enode":"enode://84dfd4e4d9f1204893f190eacc4c3999e175c433f70de86e335d27477c097a0552f211a21764f01a708da4c9e9e6552191a61d3e48f41d0e84f01e7ae3beb34e@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"8bl+6ryInNtPZ8aZ/bMK2Jar4I5gOxVKvfXhIrseSc4=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: f1b97e\npopulation: 23 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 5 17a0 1af6 76a5 7e45 | 122 3c5a (0) 3d17 (0) 3ff8 (0) 3ef6 (0)\n001 2 beb7 bd39 | 63 83d0 (0) 802f (0) 802e (0) 8611 (0)\n002 1 d66f | 33 de1d (0) df52 (0) d96e (0) d90b (0)\n003 5 e255 e469 e4d6 ee52 | 25 e190 (0) e31e (0) e3d8 (0) e255 (0)\n004 3 fc88 fd44 fd3f | 5 f97e (0) ffb7 (0) fc88 (0) fd44 (0)\n005 1 f6a6 | 1 f6a6 (0)\n006 3 f293 f2b2 f2f5 | 3 f293 (0) f2b2 (0) f2f5 (0)\n============ DEPTH: 7 ==========================================\n007 2 f0b8 f054 | 2 f0b8 (0) f054 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 1 f1ad | 1 f1ad (0)\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"84dfd4e4d9f1204893f190eacc4c3999e175c433f70de86e335d27477c097a0552f211a21764f01a708da4c9e9e6552191a61d3e48f41d0e84f01e7ae3beb34e","private_key":"77bd908de80bb222465d000554b9467681aef696c9e1a81e51dba688310dc7af","name":"node_84dfd4e4d9f1204893f190eacc4c3999e175c433f70de86e335d27477c097a0552f211a21764f01a708da4c9e9e6552191a61d3e48f41d0e84f01e7ae3beb34e","services":["streamer"],"enable_msg_events":true,"port":63358},"up":true}},{"node":{"info":{"id":"ba21a373781966135d6225adae024a3f3e421b852f72f8b0569cb92fcff87c33f7e5b799a509b8eff6ec6dc46a9b17d5bae1e91ec7c54c0c712d893d54b140fa","name":"node_ba21a373781966135d6225adae024a3f3e421b852f72f8b0569cb92fcff87c33f7e5b799a509b8eff6ec6dc46a9b17d5bae1e91ec7c54c0c712d893d54b140fa","enode":"enode://ba21a373781966135d6225adae024a3f3e421b852f72f8b0569cb92fcff87c33f7e5b799a509b8eff6ec6dc46a9b17d5bae1e91ec7c54c0c712d893d54b140fa@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"79152kdKB4THQh7SRvb423Ib01Ua1uN5MHDEMhgWefM=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: efdd79\npopulation: 26 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 1af6 7810 7e45 | 122 3c5a (0) 3d17 (0) 3ff8 (0) 3ef6 (0)\n001 2 bd39 beb7 | 63 83d0 (0) 802f (0) 802e (0) 8611 (0)\n002 3 c95a c3d8 d66f | 33 ce71 (0) cf77 (0) cba4 (0) cbd3 (0)\n003 2 f293 f1b9 | 13 f97e (0) ffb7 (0) fc88 (0) fd44 (0)\n004 6 e3d8 e255 e54d e469 | 13 e190 (0) e31e (0) e3d8 (0) e255 (0)\n005 3 e850 ebe8 ebc9 | 4 ebc9 (0) ebe8 (0) e9fa (0) e850 (0)\n006 2 ecff ec78 | 2 ecff (0) ec78 (0)\n007 3 eee1 ee3f ee52 | 3 eee1 (0) ee3f (0) ee52 (0)\n008 0 | 0\n============ DEPTH: 9 ==========================================\n009 1 efbb | 1 efbb (0)\n010 0 | 0\n011 1 efc1 | 1 efc1 (0)\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"ba21a373781966135d6225adae024a3f3e421b852f72f8b0569cb92fcff87c33f7e5b799a509b8eff6ec6dc46a9b17d5bae1e91ec7c54c0c712d893d54b140fa","private_key":"529ac85f80c2ef25f0cca3417a1745d3573eef2b8cd611eab45c6bf857c87158","name":"node_ba21a373781966135d6225adae024a3f3e421b852f72f8b0569cb92fcff87c33f7e5b799a509b8eff6ec6dc46a9b17d5bae1e91ec7c54c0c712d893d54b140fa","services":["streamer"],"enable_msg_events":true,"port":63359},"up":true}},{"node":{"info":{"id":"fd4968df03d767a223bf7e4dbe26b5c27048298df40e81cad50b344fb3e6837965f2646dab7ffb2891a5c507343ed84bb8bbe403287b51dae538d58fcb6e7623","name":"node_fd4968df03d767a223bf7e4dbe26b5c27048298df40e81cad50b344fb3e6837965f2646dab7ffb2891a5c507343ed84bb8bbe403287b51dae538d58fcb6e7623","enode":"enode://fd4968df03d767a223bf7e4dbe26b5c27048298df40e81cad50b344fb3e6837965f2646dab7ffb2891a5c507343ed84bb8bbe403287b51dae538d58fcb6e7623@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"vrd3wC3aQg2u7Nn6+6rc0lku1R6ailxd16vkN0OogAE=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: beb777\npopulation: 22 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 2940 7e45 | 122 3c5a (0) 3d17 (0) 3ff8 (0) 3ef6 (0)\n001 7 caa3 c3d8 d66f f1b9 | 71 cf77 (0) ce71 (0) cbd3 (0) cba4 (0)\n002 4 8ae8 92d5 93f8 9108 | 33 83d0 (0) 802f (0) 802e (0) 8611 (0)\n003 2 ac62 aa78 | 17 a478 (0) a6bd (0) a75d (0) a317 (0)\n004 2 b30e b40d | 6 b049 (0) b391 (0) b30e (0) b7aa (0)\n005 3 bbcb bb31 baaf | 4 b820 (0) bb31 (0) bbcb (0) baaf (0)\n============ DEPTH: 6 ==========================================\n006 1 bd39 | 1 bd39 (0)\n007 1 bf6b | 1 bf6b (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"fd4968df03d767a223bf7e4dbe26b5c27048298df40e81cad50b344fb3e6837965f2646dab7ffb2891a5c507343ed84bb8bbe403287b51dae538d58fcb6e7623","private_key":"46d69d2cb90a6ff16facb7994569557da8b0c76f74d238381a2a53cadbd1d8de","name":"node_fd4968df03d767a223bf7e4dbe26b5c27048298df40e81cad50b344fb3e6837965f2646dab7ffb2891a5c507343ed84bb8bbe403287b51dae538d58fcb6e7623","services":["streamer"],"enable_msg_events":true,"port":63360},"up":true}},{"node":{"info":{"id":"07c63ca5d0309e30d1ab12e7fc142e6d37904b552639cfa97850161491f28f20d87e0304be29357bcfc2ff52fc52fd0d4f6e6011ebb239cced8b5c8dad7abf45","name":"node_07c63ca5d0309e30d1ab12e7fc142e6d37904b552639cfa97850161491f28f20d87e0304be29357bcfc2ff52fc52fd0d4f6e6011ebb239cced8b5c8dad7abf45","enode":"enode://07c63ca5d0309e30d1ab12e7fc142e6d37904b552639cfa97850161491f28f20d87e0304be29357bcfc2ff52fc52fd0d4f6e6011ebb239cced8b5c8dad7abf45@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"fkWFtSJU9ggeGRkec3/RiYUooK9349dSoIHSm5KsE6U=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 7e4585\npopulation: 23 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 beb7 f1b9 efdd d66f | 134 83d0 (0) 802f (0) 802e (0) 8434 (0)\n001 3 0f65 2737 2940 | 72 1254 (0) 11a0 (0) 10b1 (0) 15ec (0)\n002 6 5399 5765 5741 5e3e | 31 4c97 (0) 4dc4 (0) 48df (0) 48ec (0)\n003 2 63de 6caa | 9 65a6 (0) 67ee (0) 6701 (0) 60bc (0)\n004 5 7299 71bf 715b 77bc | 6 7299 (0) 7239 (0) 71bf (0) 715b (0)\n============ DEPTH: 5 ==========================================\n005 2 7aef 7810 | 2 7aef (0) 7810 (0)\n006 0 | 0\n007 0 | 0\n008 1 7ec4 | 1 7ec4 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"07c63ca5d0309e30d1ab12e7fc142e6d37904b552639cfa97850161491f28f20d87e0304be29357bcfc2ff52fc52fd0d4f6e6011ebb239cced8b5c8dad7abf45","private_key":"668577a2160c0a19ddd60a032636f42ef4b0f8d7f8b15129b39bc693b04951b3","name":"node_07c63ca5d0309e30d1ab12e7fc142e6d37904b552639cfa97850161491f28f20d87e0304be29357bcfc2ff52fc52fd0d4f6e6011ebb239cced8b5c8dad7abf45","services":["streamer"],"enable_msg_events":true,"port":63361},"up":true}},{"node":{"info":{"id":"920a301186bdf665a721676ece7c180413369ea6eff7537f42049d9eb409f28cc864099590116e885f57368959fb2cff7003697d9b1515e68bf3fa7aee0278ef","name":"node_920a301186bdf665a721676ece7c180413369ea6eff7537f42049d9eb409f28cc864099590116e885f57368959fb2cff7003697d9b1515e68bf3fa7aee0278ef","enode":"enode://920a301186bdf665a721676ece7c180413369ea6eff7537f42049d9eb409f28cc864099590116e885f57368959fb2cff7003697d9b1515e68bf3fa7aee0278ef@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"1m9EDYbkOtfhU+2fEBvRYy5k3dLnV5H80/6Bm9GQ5mU=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: d66f44\npopulation: 23 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 7e45 0f65 2940 | 122 4c97 (0) 4dc4 (0) 4b70 (0) 4bf8 (0)\n001 1 beb7 | 63 83d0 (0) 802e (0) 802f (0) 8611 (0)\n002 4 f1b9 e4d6 ee52 efdd | 38 f97e (0) ffb7 (0) fc88 (0) fd44 (0)\n003 4 caa3 c95a c60e c3d8 | 14 ce71 (0) cf77 (0) cba4 (0) cbd3 (0)\n004 1 dad3 | 5 de1d (0) df52 (0) d96e (0) d90b (0)\n005 4 d07c d044 d2ac d35c | 7 d1bc (0) d0b7 (0) d07c (0) d044 (0)\n006 2 d455 d560 | 2 d560 (0) d455 (0)\n============ DEPTH: 7 ==========================================\n007 3 d7c1 d717 d777 | 3 d7c1 (0) d717 (0) d777 (0)\n008 0 | 0\n009 1 d606 | 1 d606 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"920a301186bdf665a721676ece7c180413369ea6eff7537f42049d9eb409f28cc864099590116e885f57368959fb2cff7003697d9b1515e68bf3fa7aee0278ef","private_key":"ccd33f1981701e030d7880879453393ccb90b02d71fc85a89d82f903d1a81066","name":"node_920a301186bdf665a721676ece7c180413369ea6eff7537f42049d9eb409f28cc864099590116e885f57368959fb2cff7003697d9b1515e68bf3fa7aee0278ef","services":["streamer"],"enable_msg_events":true,"port":63362},"up":true}},{"node":{"info":{"id":"89a5b92a9ca045f12c35a70084e6f41f9775a25d6f105f8c9349c7b5e107179d8a96bdbb113b2680edf5183e9a42fd64bd7b29d0dc7797c583b833f869313699","name":"node_89a5b92a9ca045f12c35a70084e6f41f9775a25d6f105f8c9349c7b5e107179d8a96bdbb113b2680edf5183e9a42fd64bd7b29d0dc7797c583b833f869313699","enode":"enode://89a5b92a9ca045f12c35a70084e6f41f9775a25d6f105f8c9349c7b5e107179d8a96bdbb113b2680edf5183e9a42fd64bd7b29d0dc7797c583b833f869313699@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"KUBmvwVrFTAwjQlocbCKBGCGq8vH7XoKl9n7RszNYAM=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 294066\npopulation: 19 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 beb7 d66f | 134 83d0 (0) 802f (0) 802e (0) 8611 (0)\n001 3 44b7 7ec4 7e45 | 50 4c97 (0) 4dc4 (0) 48df (0) 48ec (0)\n002 3 17a0 1af6 0f65 | 37 1ea1 (0) 1fab (0) 1dfd (0) 1dfc (0)\n003 3 3d17 3227 3734 | 20 3c5a (0) 3d17 (0) 3ff8 (0) 3ef6 (0)\n004 3 2220 2224 2737 | 5 208e (0) 2224 (0) 2220 (0) 24f8 (0)\n005 3 2e3b 2cb1 2cab | 7 2f23 (0) 2f1f (0) 2e3b (0) 2c4e (0)\n============ DEPTH: 6 ==========================================\n006 1 2a7d | 1 2a7d (0)\n007 0 | 0\n008 0 | 0\n009 1 293f | 1 293f (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"89a5b92a9ca045f12c35a70084e6f41f9775a25d6f105f8c9349c7b5e107179d8a96bdbb113b2680edf5183e9a42fd64bd7b29d0dc7797c583b833f869313699","private_key":"1859e8cc62440d9e1d1c35f842b8bab336798e87932bc4f2456c327fdc777a7d","name":"node_89a5b92a9ca045f12c35a70084e6f41f9775a25d6f105f8c9349c7b5e107179d8a96bdbb113b2680edf5183e9a42fd64bd7b29d0dc7797c583b833f869313699","services":["streamer"],"enable_msg_events":true,"port":63363},"up":true}},{"node":{"info":{"id":"beec648d79437a5d7b4140ced45d82d035c6f64f9c67c58386703811d97c3846787eaf274d2298df809475f0b7519df696563cb8e9a5fb0a9cc419ab13fa8d41","name":"node_beec648d79437a5d7b4140ced45d82d035c6f64f9c67c58386703811d97c3846787eaf274d2298df809475f0b7519df696563cb8e9a5fb0a9cc419ab13fa8d41","enode":"enode://beec648d79437a5d7b4140ced45d82d035c6f64f9c67c58386703811d97c3846787eaf274d2298df809475f0b7519df696563cb8e9a5fb0a9cc419ab13fa8d41@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"D2UhDnJ+3gGoVMPI0latzteYZsNo0NUfs63pw5CwIxg=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 0f6521\npopulation: 30 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 caa3 d66f 8ae8 ac62 | 134 f97e (0) ffb7 (0) fc88 (0) fd44 (0)\n001 8 5399 5e3e 6701 63de | 50 42d6 (0) 43fb (0) 413b (0) 41b2 (0)\n002 5 3734 3227 2220 2737 | 35 3baa (0) 3ab2 (0) 3a18 (0) 398b (0)\n003 4 10b1 17a0 1d5b 1af6 | 19 1254 (0) 11a0 (0) 10b1 (0) 14e4 (0)\n004 2 00c8 0536 | 7 0305 (0) 020f (0) 0020 (0) 00c8 (0)\n005 1 0ad6 | 4 09d1 (0) 0bc3 (0) 0a3f (0) 0ad6 (0)\n============ DEPTH: 6 ==========================================\n006 5 0d97 0daf 0ca9 0c72 | 5 0d97 (0) 0daf (0) 0ca9 (0) 0c72 (0)\n007 0 | 0\n008 1 0fa0 | 1 0fa0 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"beec648d79437a5d7b4140ced45d82d035c6f64f9c67c58386703811d97c3846787eaf274d2298df809475f0b7519df696563cb8e9a5fb0a9cc419ab13fa8d41","private_key":"45dad25ea664452913d4fb09debe8987c94b88ef752b058a7bf352f144a9c6ea","name":"node_beec648d79437a5d7b4140ced45d82d035c6f64f9c67c58386703811d97c3846787eaf274d2298df809475f0b7519df696563cb8e9a5fb0a9cc419ab13fa8d41","services":["streamer"],"enable_msg_events":true,"port":63364},"up":true}},{"node":{"info":{"id":"c73d088ade8756c74832c73542bcdb3e52f670f7a74ad3a7eac2a9e3ece6bd081f782a8e1d3f9a40b9aa9201509110f37fc57fcb10ee1ef3ef07b7eab019782e","name":"node_c73d088ade8756c74832c73542bcdb3e52f670f7a74ad3a7eac2a9e3ece6bd081f782a8e1d3f9a40b9aa9201509110f37fc57fcb10ee1ef3ef07b7eab019782e","enode":"enode://c73d088ade8756c74832c73542bcdb3e52f670f7a74ad3a7eac2a9e3ece6bd081f782a8e1d3f9a40b9aa9201509110f37fc57fcb10ee1ef3ef07b7eab019782e@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"rGL7uOGOzEu05vXUqZm8hoFYAxBtRRIARXspcwYZNTo=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: ac62fb\npopulation: 22 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 7ec4 2737 0f65 | 122 42d6 (0) 43fb (0) 41b2 (0) 413b (0)\n001 3 caa3 d0b7 e469 | 71 f97e (0) ffb7 (0) fc88 (0) fd44 (0)\n002 4 985f 86d3 853b 8ae8 | 33 9f4c (0) 9a09 (0) 9b87 (0) 9bc3 (0)\n003 4 beb7 bd39 b40d b30e | 13 b820 (0) bb31 (0) bbcb (0) baaf (0)\n004 4 a6bd a317 a077 a0e4 | 12 a478 (0) a6bd (0) a75d (0) a3f2 (0)\n============ DEPTH: 5 ==========================================\n005 3 a9df a936 aa78 | 3 a9df (0) a936 (0) aa78 (0)\n006 1 af8f | 1 af8f (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"c73d088ade8756c74832c73542bcdb3e52f670f7a74ad3a7eac2a9e3ece6bd081f782a8e1d3f9a40b9aa9201509110f37fc57fcb10ee1ef3ef07b7eab019782e","private_key":"042b5ccd68b8dd6c125ecd889c304299fa18c22841c95b5fae01a22fa98ce96d","name":"node_c73d088ade8756c74832c73542bcdb3e52f670f7a74ad3a7eac2a9e3ece6bd081f782a8e1d3f9a40b9aa9201509110f37fc57fcb10ee1ef3ef07b7eab019782e","services":["streamer"],"enable_msg_events":true,"port":63365},"up":true}},{"node":{"info":{"id":"62dab8b21640e1b44dea452dd7e7de93f27a44840da72d56b11aa96e8463f3a4bb15e75a954d19fc897ae0030b16181d271b79d8198b7cffcddaa9ffcfdcce73","name":"node_62dab8b21640e1b44dea452dd7e7de93f27a44840da72d56b11aa96e8463f3a4bb15e75a954d19fc897ae0030b16181d271b79d8198b7cffcddaa9ffcfdcce73","enode":"enode://62dab8b21640e1b44dea452dd7e7de93f27a44840da72d56b11aa96e8463f3a4bb15e75a954d19fc897ae0030b16181d271b79d8198b7cffcddaa9ffcfdcce73@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"iuieEF8D/xusv1Pkese9mvZuD7wN7LHBG8YHeM+XR2o=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 8ae89e\npopulation: 23 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 0f65 5e3e 7ec4 | 122 3054 (0) 307c (0) 3085 (0) 3388 (0)\n001 3 caa3 ffb7 f97e | 71 f97e (0) ffb7 (0) fc88 (0) fd44 (0)\n002 3 beb7 b40d ac62 | 30 b820 (0) bb31 (0) bbcb (0) baaf (0)\n003 7 98bc 99eb 9747 9641 | 18 9f4c (0) 9a09 (0) 9b87 (0) 9bc3 (0)\n004 2 86d3 853b | 8 83d0 (0) 802f (0) 802e (0) 8611 (0)\n005 3 8ee7 8d85 8d3c | 4 8ea9 (0) 8ee7 (0) 8d3c (0) 8d85 (0)\n============ DEPTH: 6 ==========================================\n006 1 89ef | 1 89ef (0)\n007 0 | 0\n008 1 8a54 | 1 8a54 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"62dab8b21640e1b44dea452dd7e7de93f27a44840da72d56b11aa96e8463f3a4bb15e75a954d19fc897ae0030b16181d271b79d8198b7cffcddaa9ffcfdcce73","private_key":"1a8c7f2f97bcaa5711578ec1de04829d7735f81ba5761087e79a977405ec1801","name":"node_62dab8b21640e1b44dea452dd7e7de93f27a44840da72d56b11aa96e8463f3a4bb15e75a954d19fc897ae0030b16181d271b79d8198b7cffcddaa9ffcfdcce73","services":["streamer"],"enable_msg_events":true,"port":63366},"up":true}},{"node":{"info":{"id":"9e621c3eb534855ca292efa27a3fbc89b4f05c80a4bc65bcff2f14ff28ef43cbe14137d2fddc6fe2658bb06947d918476b479dde71469b8680e5d8a7a01619b5","name":"node_9e621c3eb534855ca292efa27a3fbc89b4f05c80a4bc65bcff2f14ff28ef43cbe14137d2fddc6fe2658bb06947d918476b479dde71469b8680e5d8a7a01619b5","enode":"enode://9e621c3eb534855ca292efa27a3fbc89b4f05c80a4bc65bcff2f14ff28ef43cbe14137d2fddc6fe2658bb06947d918476b479dde71469b8680e5d8a7a01619b5@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"fsQIPspHScqnBqwIr8DJHNzsQvGOTTYPGGlaed42IRU=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 7ec408\npopulation: 18 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 caa3 ac62 8ae8 | 134 f97e (0) ffb7 (0) fc88 (0) fd44 (0)\n001 3 2737 2940 0f65 | 72 3baa (0) 3ab2 (0) 3a18 (0) 398b (0)\n002 1 5e3e | 31 47a8 (0) 464b (0) 44c8 (0) 44b7 (0)\n003 4 6f1c 6caa 6701 63de | 9 6923 (0) 69d8 (0) 6f1c (0) 6caa (0)\n004 4 7299 71bf 715b 76a5 | 6 7299 (0) 7239 (0) 71bf (0) 715b (0)\n============ DEPTH: 5 ==========================================\n005 2 7aef 7810 | 2 7aef (0) 7810 (0)\n006 0 | 0\n007 0 | 0\n008 1 7e45 | 1 7e45 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"9e621c3eb534855ca292efa27a3fbc89b4f05c80a4bc65bcff2f14ff28ef43cbe14137d2fddc6fe2658bb06947d918476b479dde71469b8680e5d8a7a01619b5","private_key":"d7a4980a0fc96842e8e570863a3b8e078baefe4ca8ab2ddf85c7c5d8f541fabb","name":"node_9e621c3eb534855ca292efa27a3fbc89b4f05c80a4bc65bcff2f14ff28ef43cbe14137d2fddc6fe2658bb06947d918476b479dde71469b8680e5d8a7a01619b5","services":["streamer"],"enable_msg_events":true,"port":63367},"up":true}},{"node":{"info":{"id":"afe5b217dc512eee45575c189826ee5640d11a0ac9e8e4b03e9e62e6cf6df9de500bc8a36cb7d82a2280ce184409164f1772cc5c9e59ad04361522d2b8c364e0","name":"node_afe5b217dc512eee45575c189826ee5640d11a0ac9e8e4b03e9e62e6cf6df9de500bc8a36cb7d82a2280ce184409164f1772cc5c9e59ad04361522d2b8c364e0","enode":"enode://afe5b217dc512eee45575c189826ee5640d11a0ac9e8e4b03e9e62e6cf6df9de500bc8a36cb7d82a2280ce184409164f1772cc5c9e59ad04361522d2b8c364e0@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"yqMhpQ6Apas9c/cXAI9GAfV6Ie+oc+TxzE1vNW+6/a4=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: caa321\npopulation: 27 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 6 5e3e 7ec4 0f65 3227 | 122 3ff8 (0) 3ef6 (0) 3c5a (0) 3d17 (0)\n001 4 beb7 b40d ac62 8ae8 | 63 b820 (0) baaf (0) bbcb (0) bb31 (0)\n002 1 e850 | 38 f97e (0) ffb7 (0) fc88 (0) fd44 (0)\n003 6 d35c d560 d455 d777 | 19 dad3 (0) d96e (0) d90b (0) de1d (0)\n004 2 c60e c3d8 | 5 c409 (0) c7fa (0) c60e (0) c301 (0)\n005 2 ce71 cf77 | 2 ce71 (0) cf77 (0)\n006 3 c95a c911 c914 | 3 c914 (0) c911 (0) c95a (0)\n============ DEPTH: 7 ==========================================\n007 2 cbd3 cba4 | 2 cba4 (0) cbd3 (0)\n008 0 | 0\n009 0 | 0\n010 1 ca8c | 1 ca8c (0)\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"afe5b217dc512eee45575c189826ee5640d11a0ac9e8e4b03e9e62e6cf6df9de500bc8a36cb7d82a2280ce184409164f1772cc5c9e59ad04361522d2b8c364e0","private_key":"d2e98b0004a9b7bdb030d5e729716e7065aa1a8c48efacf471718bc5da8ec990","name":"node_afe5b217dc512eee45575c189826ee5640d11a0ac9e8e4b03e9e62e6cf6df9de500bc8a36cb7d82a2280ce184409164f1772cc5c9e59ad04361522d2b8c364e0","services":["streamer"],"enable_msg_events":true,"port":63368},"up":true}},{"node":{"info":{"id":"db8ba71afeaea1f2964e8978a6eceeb9efa3958424424022213c8193443f8d5afd18490afa954c76360c681404809c7cfaf7e4ebd8bd1a42d403f7f1915b0d29","name":"node_db8ba71afeaea1f2964e8978a6eceeb9efa3958424424022213c8193443f8d5afd18490afa954c76360c681404809c7cfaf7e4ebd8bd1a42d403f7f1915b0d29","enode":"enode://db8ba71afeaea1f2964e8978a6eceeb9efa3958424424022213c8193443f8d5afd18490afa954c76360c681404809c7cfaf7e4ebd8bd1a42d403f7f1915b0d29@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"Xj780S11u0f4QiYdJPUJAY36VofjGV4dG7K8YCzJwpE=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 5e3efc\npopulation: 26 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 5 853b 8ae8 e469 caa3 | 134 910d (0) 9108 (0) 92d5 (0) 93f8 (0)\n001 3 0f65 2220 2737 | 72 1fab (0) 1ea1 (0) 1dfc (0) 1dfd (0)\n002 5 6701 63de 715b 7e45 | 19 77bc (0) 76a5 (0) 7299 (0) 7239 (0)\n003 3 41b2 4dc4 4bf8 | 16 47a8 (0) 464b (0) 44c8 (0) 44b7 (0)\n004 5 57ee 5765 5741 5237 | 9 56bb (0) 57ee (0) 5765 (0) 5741 (0)\n005 3 581a 5b30 5a67 | 3 581a (0) 5b30 (0) 5a67 (0)\n============ DEPTH: 6 ==========================================\n006 2 5c9b 5cae | 2 5c9b (0) 5cae (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"db8ba71afeaea1f2964e8978a6eceeb9efa3958424424022213c8193443f8d5afd18490afa954c76360c681404809c7cfaf7e4ebd8bd1a42d403f7f1915b0d29","private_key":"bd3302dac250b294208d6ed14b0a14a6d60d75be1f68ce5cd1e250a47032fb3d","name":"node_db8ba71afeaea1f2964e8978a6eceeb9efa3958424424022213c8193443f8d5afd18490afa954c76360c681404809c7cfaf7e4ebd8bd1a42d403f7f1915b0d29","services":["streamer"],"enable_msg_events":true,"port":63369},"up":true}},{"node":{"info":{"id":"2f1967b4410ea2ea8fbaf46771ba82c2846d00aecdb6f873aceae33ab38f72d0a2c2dc6046d3034f514efd090d42011d48e9ab0cb4e3caa2b49a96ef732215a1","name":"node_2f1967b4410ea2ea8fbaf46771ba82c2846d00aecdb6f873aceae33ab38f72d0a2c2dc6046d3034f514efd090d42011d48e9ab0cb4e3caa2b49a96ef732215a1","enode":"enode://2f1967b4410ea2ea8fbaf46771ba82c2846d00aecdb6f873aceae33ab38f72d0a2c2dc6046d3034f514efd090d42011d48e9ab0cb4e3caa2b49a96ef732215a1@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"1WAluxECECFv3I+GrSBWB8b7R0TT1ESTGqF1EqhUNWo=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: d56025\npopulation: 20 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 63de 5e3e | 122 1953 (0) 1a8e (0) 1a85 (0) 1af6 (0)\n001 2 853b b40d | 63 9f4c (0) 9a09 (0) 9b87 (0) 9bc3 (0)\n002 3 e850 e56c e469 | 38 f97e (0) ffb7 (0) fc88 (0) fd44 (0)\n003 2 caa3 c409 | 14 c409 (0) c7fa (0) c60e (0) c301 (0)\n004 3 dad3 d96e df52 | 5 dad3 (0) d90b (0) d96e (0) de1d (0)\n005 2 d3bd d044 | 7 d2ac (0) d3bd (0) d35c (0) d1bc (0)\n============ DEPTH: 6 ==========================================\n006 5 d606 d66f d717 d777 | 5 d606 (0) d66f (0) d717 (0) d777 (0)\n007 1 d455 | 1 d455 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"2f1967b4410ea2ea8fbaf46771ba82c2846d00aecdb6f873aceae33ab38f72d0a2c2dc6046d3034f514efd090d42011d48e9ab0cb4e3caa2b49a96ef732215a1","private_key":"f5832a55177daebfda3bcaf8b5ebc11eb44f4d5207b8384fd35999944d2fcab0","name":"node_2f1967b4410ea2ea8fbaf46771ba82c2846d00aecdb6f873aceae33ab38f72d0a2c2dc6046d3034f514efd090d42011d48e9ab0cb4e3caa2b49a96ef732215a1","services":["streamer"],"enable_msg_events":true,"port":63370},"up":true}},{"node":{"info":{"id":"a99852c5bf08ea4713af9cade5343d1259bfb90401aca7fcff18c58cd56a98804dd16c61fea71039c0ac31b9bbbb9dc5aeaf0c2f074d3365e88d17031802d636","name":"node_a99852c5bf08ea4713af9cade5343d1259bfb90401aca7fcff18c58cd56a98804dd16c61fea71039c0ac31b9bbbb9dc5aeaf0c2f074d3365e88d17031802d636","enode":"enode://a99852c5bf08ea4713af9cade5343d1259bfb90401aca7fcff18c58cd56a98804dd16c61fea71039c0ac31b9bbbb9dc5aeaf0c2f074d3365e88d17031802d636@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"5GlyAuVj9EfJyT9Jg2X03JXRRjPtQDh7k0xIXcOqxXU=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: e46972\npopulation: 23 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 5e3e 63de 2737 | 122 77bc (0) 76a5 (0) 7299 (0) 7239 (0)\n001 4 853b a75d ac62 b40d | 63 b820 (0) baaf (0) bbcb (0) bb31 (0)\n002 1 d560 | 33 c409 (0) c7fa (0) c60e (0) c301 (0)\n003 2 f293 f1b9 | 13 f97e (0) ffb7 (0) fc88 (0) fd44 (0)\n004 3 e850 efdd ee52 | 12 ecff (0) ec78 (0) eee1 (0) ee3f (0)\n005 2 e190 e31e | 4 e190 (0) e255 (0) e3d8 (0) e31e (0)\n006 2 e6b7 e724 | 2 e6b7 (0) e724 (0)\n007 3 e5d2 e54d e56c | 3 e5d2 (0) e54d (0) e56c (0)\n============ DEPTH: 8 ==========================================\n008 2 e4d6 e4e9 | 2 e4d6 (0) e4e9 (0)\n009 1 e406 | 1 e406 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"a99852c5bf08ea4713af9cade5343d1259bfb90401aca7fcff18c58cd56a98804dd16c61fea71039c0ac31b9bbbb9dc5aeaf0c2f074d3365e88d17031802d636","private_key":"8285330088dc95f441c68f12765ee99f065fc41f665b54a257172d9b4ff6e017","name":"node_a99852c5bf08ea4713af9cade5343d1259bfb90401aca7fcff18c58cd56a98804dd16c61fea71039c0ac31b9bbbb9dc5aeaf0c2f074d3365e88d17031802d636","services":["streamer"],"enable_msg_events":true,"port":63371},"up":true}},{"node":{"info":{"id":"4e68553db7be307b8379e8bec383b5c92e4b23debcefca575d24504e2062618f74c26e60e0d9e47f096997a7f841e2c32c994124f495ef3352ef964b33fd3a51","name":"node_4e68553db7be307b8379e8bec383b5c92e4b23debcefca575d24504e2062618f74c26e60e0d9e47f096997a7f841e2c32c994124f495ef3352ef964b33fd3a51","enode":"enode://4e68553db7be307b8379e8bec383b5c92e4b23debcefca575d24504e2062618f74c26e60e0d9e47f096997a7f841e2c32c994124f495ef3352ef964b33fd3a51@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"JzdWfbyNv6KiP71CZNG/fNEmtU8bw6799BcLuAvExac=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 273756\npopulation: 21 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 5 e4d6 e469 853b ac62 | 134 c409 (0) c7fa (0) c60e (0) c301 (0)\n001 4 5e3e 7e45 7ec4 63de | 50 42d6 (0) 43fb (0) 41b2 (0) 413b (0)\n002 2 1af6 0f65 | 37 1254 (0) 10b1 (0) 11a0 (0) 14e4 (0)\n003 3 398b 3799 3227 | 20 3054 (0) 307c (0) 3085 (0) 3388 (0)\n004 4 2cb1 2cab 2a7d 2940 | 10 2e3b (0) 2f23 (0) 2f1f (0) 2c4e (0)\n============ DEPTH: 5 ==========================================\n005 2 208e 2224 | 3 208e (0) 2224 (0) 2220 (6)\n006 1 24f8 | 1 24f8 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"4e68553db7be307b8379e8bec383b5c92e4b23debcefca575d24504e2062618f74c26e60e0d9e47f096997a7f841e2c32c994124f495ef3352ef964b33fd3a51","private_key":"96a76a56912e05cbd480fde154743a65f4bdaba5395cf685c22681fa403807b3","name":"node_4e68553db7be307b8379e8bec383b5c92e4b23debcefca575d24504e2062618f74c26e60e0d9e47f096997a7f841e2c32c994124f495ef3352ef964b33fd3a51","services":["streamer"],"enable_msg_events":true,"port":63372},"up":true}},{"node":{"info":{"id":"a608a746f46d4b2e9267c65283380d6d6cb8885a64428fb77df9934bcf4dd1723587ee7c8f4a642dce266a12a6a4cf4e5c6db7fa1024158425a6753e7ab7264c","name":"node_a608a746f46d4b2e9267c65283380d6d6cb8885a64428fb77df9934bcf4dd1723587ee7c8f4a642dce266a12a6a4cf4e5c6db7fa1024158425a6753e7ab7264c","enode":"enode://a608a746f46d4b2e9267c65283380d6d6cb8885a64428fb77df9934bcf4dd1723587ee7c8f4a642dce266a12a6a4cf4e5c6db7fa1024158425a6753e7ab7264c@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"tA2ohLXgq0KbNgjOYDDA9/VC0AhxPtGkRMcNnACYns8=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: b40da8\npopulation: 21 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 2737 63de | 122 14e4 (0) 15ec (0) 1587 (0) 167b (0)\n001 3 e469 caa3 d560 | 71 c409 (0) c7fa (0) c60e (0) c301 (0)\n002 4 93f8 8ae8 86d3 853b | 33 9f4c (0) 9a09 (0) 9b87 (0) 9bc3 (0)\n003 4 a6bd a0e4 ac62 aa78 | 17 a478 (0) a75d (0) a6bd (0) a317 (0)\n004 3 bd39 bf6b beb7 | 7 b820 (0) bbcb (0) bb31 (0) baaf (0)\n005 3 b049 b391 b30e | 3 b049 (0) b391 (0) b30e (0)\n============ DEPTH: 6 ==========================================\n006 1 b7aa | 1 b7aa (0)\n007 0 | 0\n008 0 | 0\n009 1 b45f | 1 b45f (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"a608a746f46d4b2e9267c65283380d6d6cb8885a64428fb77df9934bcf4dd1723587ee7c8f4a642dce266a12a6a4cf4e5c6db7fa1024158425a6753e7ab7264c","private_key":"bf0a6c406d390baa5a33fc469dd8b3ec25e406364bafa8ad3d9b422dd58b4a87","name":"node_a608a746f46d4b2e9267c65283380d6d6cb8885a64428fb77df9934bcf4dd1723587ee7c8f4a642dce266a12a6a4cf4e5c6db7fa1024158425a6753e7ab7264c","services":["streamer"],"enable_msg_events":true,"port":63373},"up":true}},{"node":{"info":{"id":"fde7705f5013c3b6b76a35505c1e3d57c033a337f2a71e912ec3a3d2da8e113bd7c36d94908357e9f7654660621f647ad8c66b0126dfe91dbfa3b8c7bd2183d3","name":"node_fde7705f5013c3b6b76a35505c1e3d57c033a337f2a71e912ec3a3d2da8e113bd7c36d94908357e9f7654660621f647ad8c66b0126dfe91dbfa3b8c7bd2183d3","enode":"enode://fde7705f5013c3b6b76a35505c1e3d57c033a337f2a71e912ec3a3d2da8e113bd7c36d94908357e9f7654660621f647ad8c66b0126dfe91dbfa3b8c7bd2183d3@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"Y95M0I4Ao9vAca2v4dHKJVzG1nLjxapllqtg7VzILF4=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 63de4c\npopulation: 22 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 d560 e469 853b b40d | 134 c409 (0) c60e (0) c7fa (0) c301 (0)\n001 3 0f65 2220 2737 | 72 1fab (0) 1ea1 (0) 1dfc (0) 1dfd (0)\n002 3 4dc4 5b30 5e3e | 31 44c8 (0) 44b7 (0) 47a8 (0) 464b (0)\n003 7 7810 7e45 7ec4 76a5 | 10 7aef (0) 7810 (0) 7e45 (0) 7ec4 (0)\n004 1 6caa | 4 6923 (0) 69d8 (0) 6f1c (0) 6caa (0)\n============ DEPTH: 5 ==========================================\n005 3 65a6 67ee 6701 | 3 65a6 (0) 67ee (0) 6701 (0)\n006 1 60bc | 1 60bc (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"fde7705f5013c3b6b76a35505c1e3d57c033a337f2a71e912ec3a3d2da8e113bd7c36d94908357e9f7654660621f647ad8c66b0126dfe91dbfa3b8c7bd2183d3","private_key":"4010f083fe123b4e1e1091a054b7af104d76038c1313c71470b38aa16a05688b","name":"node_fde7705f5013c3b6b76a35505c1e3d57c033a337f2a71e912ec3a3d2da8e113bd7c36d94908357e9f7654660621f647ad8c66b0126dfe91dbfa3b8c7bd2183d3","services":["streamer"],"enable_msg_events":true,"port":63374},"up":true}},{"node":{"info":{"id":"3dfd733dde9414af916625ab981777ff1ad7ca0f6d1e4e7d9e2739969e21182fd13d85e281868653e7325b20069356b11524b54143c47fd3955a911cf7325ad4","name":"node_3dfd733dde9414af916625ab981777ff1ad7ca0f6d1e4e7d9e2739969e21182fd13d85e281868653e7325b20069356b11524b54143c47fd3955a911cf7325ad4","enode":"enode://3dfd733dde9414af916625ab981777ff1ad7ca0f6d1e4e7d9e2739969e21182fd13d85e281868653e7325b20069356b11524b54143c47fd3955a911cf7325ad4@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"hTvIaq1p1rWuJ/J7eXn1BKPRAzAApPoWT1YzV0FPL80=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 853bc8\npopulation: 24 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 7 3d17 2220 2737 5e3e | 122 1ea1 (0) 1fab (0) 1d5b (0) 1dfc (0)\n001 4 e850 e469 d560 d7c1 | 71 f97e (0) ffb7 (0) fc88 (0) fd44 (0)\n002 4 b40d a0e4 ac62 aa78 | 30 bbcb (0) bb31 (0) baaf (0) b820 (0)\n003 2 9747 9929 | 18 9f4c (0) 9a09 (0) 9b87 (0) 9bc3 (0)\n004 1 8ae8 | 7 8ea9 (0) 8ee7 (0) 8d85 (0) 8d3c (0)\n005 2 802e 802f | 3 83d0 (0) 802f (0) 802e (0)\n006 2 8611 86d3 | 2 8611 (0) 86d3 (0)\n============ DEPTH: 7 ==========================================\n007 1 8434 | 1 8434 (0)\n008 0 | 0\n009 1 8564 | 1 8564 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"3dfd733dde9414af916625ab981777ff1ad7ca0f6d1e4e7d9e2739969e21182fd13d85e281868653e7325b20069356b11524b54143c47fd3955a911cf7325ad4","private_key":"e2894e5fef7fae6c4a6969fdf39bb99e8fb16849881a5a7d45cfde92ab16232f","name":"node_3dfd733dde9414af916625ab981777ff1ad7ca0f6d1e4e7d9e2739969e21182fd13d85e281868653e7325b20069356b11524b54143c47fd3955a911cf7325ad4","services":["streamer"],"enable_msg_events":true,"port":63375},"up":true}},{"node":{"info":{"id":"5142eea687de4248b2184e9896b245563117648e7a156255d9a7ae730313d5d383db3be1125b5accd7e743c2a5d8c3289ec559ef7cbb803b9e82cd49bb213d9f","name":"node_5142eea687de4248b2184e9896b245563117648e7a156255d9a7ae730313d5d383db3be1125b5accd7e743c2a5d8c3289ec559ef7cbb803b9e82cd49bb213d9f","enode":"enode://5142eea687de4248b2184e9896b245563117648e7a156255d9a7ae730313d5d383db3be1125b5accd7e743c2a5d8c3289ec559ef7cbb803b9e82cd49bb213d9f@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"18G3R60Bo5ygSJFt4DwCiNgK7eDJaMOSqWVvYWkD/9M=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: d7c1b7\npopulation: 25 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 2220 3d17 71bf | 122 1fab (0) 1ea1 (0) 1dfd (0) 1dfc (0)\n001 4 86d3 853b a0e4 aa78 | 63 9f4c (0) 9a09 (0) 9b87 (0) 9bc3 (0)\n002 3 e850 e4e9 e56c | 38 f97e (0) ffb7 (0) fc88 (0) fd44 (0)\n003 3 cf77 caa3 c914 | 14 c409 (0) c7fa (0) c60e (0) c301 (0)\n004 3 d96e d90b df52 | 5 dad3 (0) d96e (0) d90b (0) de1d (0)\n005 3 d07c d3bd d35c | 7 d1bc (0) d07c (0) d044 (0) d0b7 (0)\n006 2 d455 d560 | 2 d455 (0) d560 (0)\n007 2 d606 d66f | 2 d606 (0) d66f (0)\n============ DEPTH: 8 ==========================================\n008 2 d717 d777 | 2 d717 (0) d777 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"5142eea687de4248b2184e9896b245563117648e7a156255d9a7ae730313d5d383db3be1125b5accd7e743c2a5d8c3289ec559ef7cbb803b9e82cd49bb213d9f","private_key":"1273dc5cdf253e8042d52ca10f80d25481d40b5cc80b37b3e128edafde8fabec","name":"node_5142eea687de4248b2184e9896b245563117648e7a156255d9a7ae730313d5d383db3be1125b5accd7e743c2a5d8c3289ec559ef7cbb803b9e82cd49bb213d9f","services":["streamer"],"enable_msg_events":true,"port":63376},"up":true}},{"node":{"info":{"id":"b597c9ba4da20c49fc4ba019571321d2579588636cdaceb9f225706574970adbf4771dcf186b1decd4e14cd5d257e30a36ca829829598c1775902201ad9793e2","name":"node_b597c9ba4da20c49fc4ba019571321d2579588636cdaceb9f225706574970adbf4771dcf186b1decd4e14cd5d257e30a36ca829829598c1775902201ad9793e2","enode":"enode://b597c9ba4da20c49fc4ba019571321d2579588636cdaceb9f225706574970adbf4771dcf186b1decd4e14cd5d257e30a36ca829829598c1775902201ad9793e2@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"qnh21D3QzkD0IfaMDRPIxxjXp6XnxWfdINh9GZNM3AU=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: aa7876\npopulation: 17 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 715b | 122 1fab (0) 1ea1 (0) 1d5b (0) 1dfc (0)\n001 3 e850 e56c d7c1 | 71 f97e (0) ffb7 (0) fc88 (0) fd44 (0)\n002 2 86d3 853b | 33 9f4c (0) 9a09 (0) 9b87 (0) 9bc3 (0)\n003 3 beb7 b30e b40d | 13 b820 (0) bb31 (0) bbcb (0) baaf (0)\n004 4 a75d a0e4 a077 a011 | 12 a478 (0) a6bd (0) a75d (0) a3f2 (0)\n005 2 af8f ac62 | 2 af8f (0) ac62 (0)\n============ DEPTH: 6 ==========================================\n006 2 a9df a936 | 2 a9df (0) a936 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"b597c9ba4da20c49fc4ba019571321d2579588636cdaceb9f225706574970adbf4771dcf186b1decd4e14cd5d257e30a36ca829829598c1775902201ad9793e2","private_key":"082369e49a61588917d594d0a90c2d53968db7910a1fa9a978da33f53d8f5166","name":"node_b597c9ba4da20c49fc4ba019571321d2579588636cdaceb9f225706574970adbf4771dcf186b1decd4e14cd5d257e30a36ca829829598c1775902201ad9793e2","services":["streamer"],"enable_msg_events":true,"port":63377},"up":true}},{"node":{"info":{"id":"72e30d4562673c5c8fb03709d93f73322747858d723b7eb5ef2fbb88e0331252946b7e93ffe434fcb599c4fff57800afb29e6c60a719f18f49dba541c3591c6e","name":"node_72e30d4562673c5c8fb03709d93f73322747858d723b7eb5ef2fbb88e0331252946b7e93ffe434fcb599c4fff57800afb29e6c60a719f18f49dba541c3591c6e","enode":"enode://72e30d4562673c5c8fb03709d93f73322747858d723b7eb5ef2fbb88e0331252946b7e93ffe434fcb599c4fff57800afb29e6c60a719f18f49dba541c3591c6e@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"cVs47KDGMKrXPl99ZUU8Zmb0WZlOPMS7pYavddeOj+Q=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 715b38\npopulation: 19 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 86d3 853b a0e4 aa78 | 134 f97e (0) ffb7 (0) fc88 (0) fd44 (0)\n001 3 2220 1ea1 1fab | 72 1fab (0) 1ea1 (0) 1dfd (0) 1dfc (0)\n002 2 5e3e 4dc4 | 31 510c (0) 5062 (0) 5070 (0) 5237 (0)\n003 2 63de 6701 | 9 6f1c (0) 6caa (0) 6923 (0) 69d8 (0)\n004 3 7810 7ec4 7e45 | 4 7aef (0) 7810 (0) 7e45 (0) 7ec4 (0)\n005 2 77bc 76a5 | 2 77bc (0) 76a5 (0)\n============ DEPTH: 6 ==========================================\n006 2 7299 7239 | 2 7299 (0) 7239 (0)\n007 0 | 0\n008 1 71bf | 1 71bf (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"72e30d4562673c5c8fb03709d93f73322747858d723b7eb5ef2fbb88e0331252946b7e93ffe434fcb599c4fff57800afb29e6c60a719f18f49dba541c3591c6e","private_key":"5ac4501287d61d0083f3143a6184fca450c07d149279fdb3a19ae3dbcf456732","name":"node_72e30d4562673c5c8fb03709d93f73322747858d723b7eb5ef2fbb88e0331252946b7e93ffe434fcb599c4fff57800afb29e6c60a719f18f49dba541c3591c6e","services":["streamer"],"enable_msg_events":true,"port":63378},"up":true}},{"node":{"info":{"id":"eaca77d20c4ad6b87649eba21b750a4b1a2c575e06bc42679d18fce16fea15212e9a7408c16f3b24d8dfd1e397314637e72e292845d09534a39035bd9203ee9e","name":"node_eaca77d20c4ad6b87649eba21b750a4b1a2c575e06bc42679d18fce16fea15212e9a7408c16f3b24d8dfd1e397314637e72e292845d09534a39035bd9203ee9e","enode":"enode://eaca77d20c4ad6b87649eba21b750a4b1a2c575e06bc42679d18fce16fea15212e9a7408c16f3b24d8dfd1e397314637e72e292845d09534a39035bd9203ee9e@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"IiBrPd/yCiRakAt7+/L0AHCcJnDwxJcTviXrVxNunxs=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 22206b\npopulation: 27 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 d7c1 c60e 853b 86d3 | 134 c409 (0) c7fa (0) c60e (0) c301 (0)\n001 5 4dc4 5e3e 715b 63de | 50 56bb (0) 57ee (0) 5765 (0) 5741 (0)\n002 3 0f65 1dfd 1d5b | 37 1ea1 (0) 1fab (0) 1daa (0) 1dfc (0)\n003 5 3227 3734 3843 3a18 | 20 34e4 (0) 3607 (0) 3658 (0) 3799 (0)\n004 7 2e3b 2c4e 2cb1 2cab | 10 2f23 (0) 2f1f (9) 2e3b (0) 2c16 (4)\n005 1 24f8 | 2 24f8 (0) 2737 (0)\n============ DEPTH: 6 ==========================================\n006 1 208e | 1 208e (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 1 2224 | 1 2224 (0)\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"eaca77d20c4ad6b87649eba21b750a4b1a2c575e06bc42679d18fce16fea15212e9a7408c16f3b24d8dfd1e397314637e72e292845d09534a39035bd9203ee9e","private_key":"cbc289ddf69a20e78f479b1587fe2955c2ee7a0bc7a743ce61c13c07139b33c1","name":"node_eaca77d20c4ad6b87649eba21b750a4b1a2c575e06bc42679d18fce16fea15212e9a7408c16f3b24d8dfd1e397314637e72e292845d09534a39035bd9203ee9e","services":["streamer"],"enable_msg_events":true,"port":63379},"up":true}},{"node":{"info":{"id":"d3105ede6c21bc643d523afcd1309a5dcf03f70797a92f167c3a19f86ae98882fe1a9d4094d7a3dee4a0833b8075b6c3e9aaa7f4879dc47bb388c3ae85522288","name":"node_d3105ede6c21bc643d523afcd1309a5dcf03f70797a92f167c3a19f86ae98882fe1a9d4094d7a3dee4a0833b8075b6c3e9aaa7f4879dc47bb388c3ae85522288","enode":"enode://d3105ede6c21bc643d523afcd1309a5dcf03f70797a92f167c3a19f86ae98882fe1a9d4094d7a3dee4a0833b8075b6c3e9aaa7f4879dc47bb388c3ae85522288@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"htMv4oFvVSNpi4HGOOrsoo77O8R3XN+0Z54Pmb7IpwM=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 86d32f\npopulation: 24 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 5 3d17 2220 4dc4 715b | 122 56bb (0) 57ee (0) 5765 (0) 5741 (0)\n001 3 d7c1 e850 e56c | 71 c409 (0) c7fa (0) c60e (0) c301 (0)\n002 4 b40d a0e4 ac62 aa78 | 30 baaf (0) bb31 (0) bbcb (0) b820 (0)\n003 3 99eb 9929 9747 | 18 9f4c (0) 9a09 (0) 9b87 (0) 9bc3 (0)\n004 2 8d85 8ae8 | 7 8d85 (0) 8d3c (0) 8ea9 (0) 8ee7 (0)\n005 3 802e 802f 83d0 | 3 83d0 (0) 802f (0) 802e (0)\n============ DEPTH: 6 ==========================================\n006 3 8434 8564 853b | 3 8434 (0) 8564 (0) 853b (0)\n007 0 | 0\n008 1 8611 | 1 8611 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"d3105ede6c21bc643d523afcd1309a5dcf03f70797a92f167c3a19f86ae98882fe1a9d4094d7a3dee4a0833b8075b6c3e9aaa7f4879dc47bb388c3ae85522288","private_key":"dce8d0367de94896d0c24049979fda6a48f77b8e98974d66472666a5a4365865","name":"node_d3105ede6c21bc643d523afcd1309a5dcf03f70797a92f167c3a19f86ae98882fe1a9d4094d7a3dee4a0833b8075b6c3e9aaa7f4879dc47bb388c3ae85522288","services":["streamer"],"enable_msg_events":true,"port":63380},"up":true}},{"node":{"info":{"id":"6f60ef501b41f9049419b033ae8d793a18067bdcd60347537b0dc3873bdd9a2d10d24909cca7c39781765746128c2165596f6537a94f58279523faee71f9c51d","name":"node_6f60ef501b41f9049419b033ae8d793a18067bdcd60347537b0dc3873bdd9a2d10d24909cca7c39781765746128c2165596f6537a94f58279523faee71f9c51d","enode":"enode://6f60ef501b41f9049419b033ae8d793a18067bdcd60347537b0dc3873bdd9a2d10d24909cca7c39781765746128c2165596f6537a94f58279523faee71f9c51d@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"6FBTXUvOaQCLGsUr/JWp7XzeBPvoSaWt49u5+hOmfJo=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: e85053\npopulation: 32 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 6701 4dc4 3d17 1daa | 122 1ea1 (0) 1fab (0) 1d5b (0) 1dfd (0)\n001 5 aa78 a478 a0e4 86d3 | 63 9f4c (0) 9a09 (0) 9b87 (0) 9bc3 (0)\n002 6 d7c1 d560 c3d8 c60e | 33 c409 (0) c7fa (0) c60e (0) c301 (0)\n003 2 fd3f f97e | 13 f97e (0) fd44 (0) fd3f (0) fc88 (0)\n004 6 e31e e724 e56c e4d6 | 13 e190 (0) e255 (0) e3d8 (0) e31e (0)\n005 6 ec78 ecff ee52 efbb | 8 ec78 (0) ecff (0) eee1 (0) ee3f (0)\n============ DEPTH: 6 ==========================================\n006 2 ebe8 ebc9 | 2 ebe8 (0) ebc9 (0)\n007 1 e9fa | 1 e9fa (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"6f60ef501b41f9049419b033ae8d793a18067bdcd60347537b0dc3873bdd9a2d10d24909cca7c39781765746128c2165596f6537a94f58279523faee71f9c51d","private_key":"138e8952e22f78dbf4ea1aad84cc393a1553192402f5cb23a8d15459d9254240","name":"node_6f60ef501b41f9049419b033ae8d793a18067bdcd60347537b0dc3873bdd9a2d10d24909cca7c39781765746128c2165596f6537a94f58279523faee71f9c51d","services":["streamer"],"enable_msg_events":true,"port":63381},"up":true}},{"node":{"info":{"id":"453779010ed7c59761da47ccd8869d3fa8349795e57edb9eea416c0712301ea622c7683858e309d19ab137ddb0edef161d0d00a361abeecf0628c3ffabc629ea","name":"node_453779010ed7c59761da47ccd8869d3fa8349795e57edb9eea416c0712301ea622c7683858e309d19ab137ddb0edef161d0d00a361abeecf0628c3ffabc629ea","enode":"enode://453779010ed7c59761da47ccd8869d3fa8349795e57edb9eea416c0712301ea622c7683858e309d19ab137ddb0edef161d0d00a361abeecf0628c3ffabc629ea@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"TcQ8ggpsNHlxUqVYM5v0aKpIxk4eVMYVjV6jM6jz3Og=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 4dc43c\npopulation: 26 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 5 e850 e56c a0e4 853b | 134 c7fa (0) c60e (0) c409 (0) c301 (0)\n001 4 2220 1ea1 1daa 1af6 | 72 1953 (0) 1a8e (0) 1a85 (0) 1af6 (0)\n002 4 71bf 715b 63de 6701 | 19 7aef (0) 7810 (0) 7e45 (0) 7ec4 (0)\n003 2 5237 5e3e | 15 56bb (0) 57ee (0) 5741 (0) 5765 (0)\n004 4 41b2 413b 44c8 464b | 8 42d6 (0) 43fb (0) 41b2 (0) 413b (0)\n============ DEPTH: 5 ==========================================\n005 6 48df 48ec 4b70 4bbc | 6 48df (0) 48ec (0) 4b70 (0) 4bbc (0)\n006 0 | 0\n007 1 4c97 | 1 4c97 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"453779010ed7c59761da47ccd8869d3fa8349795e57edb9eea416c0712301ea622c7683858e309d19ab137ddb0edef161d0d00a361abeecf0628c3ffabc629ea","private_key":"b50b26bf10abf56d51a891c4449915de09ce392d6c5a8170ae5ea5eb3a082d8f","name":"node_453779010ed7c59761da47ccd8869d3fa8349795e57edb9eea416c0712301ea622c7683858e309d19ab137ddb0edef161d0d00a361abeecf0628c3ffabc629ea","services":["streamer"],"enable_msg_events":true,"port":63382},"up":true}},{"node":{"info":{"id":"e2a27dcdee1f89fa362a85c4397840cd8be4ad8d1b9ccb23188c303bcab7619f38772f71385922d090390973b62fb8249efc103f71bc761041bcb3880ec0b935","name":"node_e2a27dcdee1f89fa362a85c4397840cd8be4ad8d1b9ccb23188c303bcab7619f38772f71385922d090390973b62fb8249efc103f71bc761041bcb3880ec0b935","enode":"enode://e2a27dcdee1f89fa362a85c4397840cd8be4ad8d1b9ccb23188c303bcab7619f38772f71385922d090390973b62fb8249efc103f71bc761041bcb3880ec0b935@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"oOTmum3aC3bNQ/k+fHs5I+UiPTyxRHFfLzgEXlkj+Zs=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: a0e4e6\npopulation: 26 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 4dc4 715b 6701 | 122 1953 (0) 1a85 (0) 1a8e (0) 1af6 (0)\n001 4 d7c1 f2f5 e850 e56c | 71 c409 (0) c7fa (0) c60e (0) c301 (0)\n002 3 86d3 853b 9747 | 33 9f4c (0) 9a09 (0) 9b87 (0) 9bc3 (0)\n003 3 bf6b b30e b40d | 13 b820 (0) baaf (0) bbcb (0) bb31 (0)\n004 3 aa78 af8f ac62 | 5 a9df (0) a936 (0) aa78 (0) af8f (0)\n005 2 a75d a478 | 3 a478 (0) a6bd (0) a75d (0)\n006 2 a317 a3f2 | 2 a317 (0) a3f2 (0)\n007 3 a105 a1f1 a1b6 | 3 a105 (0) a1f1 (0) a1b6 (0)\n============ DEPTH: 8 ==========================================\n008 2 a077 a011 | 2 a077 (0) a011 (0)\n009 0 | 0\n010 1 a0c9 | 1 a0c9 (0)\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"e2a27dcdee1f89fa362a85c4397840cd8be4ad8d1b9ccb23188c303bcab7619f38772f71385922d090390973b62fb8249efc103f71bc761041bcb3880ec0b935","private_key":"269797dfe5cc0dab8d44b114878dd8ec081d6551214db901b361817184a58bcc","name":"node_e2a27dcdee1f89fa362a85c4397840cd8be4ad8d1b9ccb23188c303bcab7619f38772f71385922d090390973b62fb8249efc103f71bc761041bcb3880ec0b935","services":["streamer"],"enable_msg_events":true,"port":63383},"up":true}},{"node":{"info":{"id":"97981f4b825620985b746c85824d7a4d307ee25d60a72c2b7de4b1d4f3b1c002652adc3045842d350f849789e410a0357a0b42fa637a1b4fc9d39e44f8a674d7","name":"node_97981f4b825620985b746c85824d7a4d307ee25d60a72c2b7de4b1d4f3b1c002652adc3045842d350f849789e410a0357a0b42fa637a1b4fc9d39e44f8a674d7","enode":"enode://97981f4b825620985b746c85824d7a4d307ee25d60a72c2b7de4b1d4f3b1c002652adc3045842d350f849789e410a0357a0b42fa637a1b4fc9d39e44f8a674d7@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"ZwGzg2DQpy3cNVwXOFrzS37Z7uwAvDhn4WK1Vxr2nj8=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 6701b3\npopulation: 21 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 86d3 a0e4 e850 e56c | 134 9f4c (0) 985f (0) 98aa (0) 98bc (0)\n001 3 2220 1af6 0f65 | 72 0020 (0) 00c8 (0) 020f (0) 0305 (0)\n002 4 5e3e 464b 4c97 4dc4 | 31 56bb (0) 57ee (0) 5741 (0) 5765 (0)\n003 5 7ec4 76a5 7239 71bf | 10 7810 (0) 7aef (0) 7e45 (0) 7ec4 (0)\n004 1 6f1c | 4 6923 (0) 69d8 (0) 6caa (0) 6f1c (0)\n005 2 60bc 63de | 2 60bc (0) 63de (0)\n============ DEPTH: 6 ==========================================\n006 1 65a6 | 1 65a6 (0)\n007 0 | 0\n008 1 67ee | 1 67ee (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"97981f4b825620985b746c85824d7a4d307ee25d60a72c2b7de4b1d4f3b1c002652adc3045842d350f849789e410a0357a0b42fa637a1b4fc9d39e44f8a674d7","private_key":"09082c0128f28346808a35b0b607d4e7d6c9ab7e894b5166958bb2eba5f4c0b3","name":"node_97981f4b825620985b746c85824d7a4d307ee25d60a72c2b7de4b1d4f3b1c002652adc3045842d350f849789e410a0357a0b42fa637a1b4fc9d39e44f8a674d7","services":["streamer"],"enable_msg_events":true,"port":63384},"up":true}},{"node":{"info":{"id":"fe62314839c93d2f6e3aee984d5f0b321897c6f39e66800d3de8b773baf6f19e0a03cae025df512aea8d5f1b667b6dbb15c192a90a76d3031c14e33e5c16c4f7","name":"node_fe62314839c93d2f6e3aee984d5f0b321897c6f39e66800d3de8b773baf6f19e0a03cae025df512aea8d5f1b667b6dbb15c192a90a76d3031c14e33e5c16c4f7","enode":"enode://fe62314839c93d2f6e3aee984d5f0b321897c6f39e66800d3de8b773baf6f19e0a03cae025df512aea8d5f1b667b6dbb15c192a90a76d3031c14e33e5c16c4f7@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"5WzSDX44cGW+LVKlw+oWgnZck3hSFwmIfG4py/JLQ+A=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: e56cd2\npopulation: 27 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 3d17 4dc4 71bf 6701 | 122 0020 (0) 00c8 (0) 0305 (0) 020f (0)\n001 4 aa78 a0e4 86d3 9747 | 63 9f4c (0) 9a09 (0) 9b87 (0) 9bc3 (0)\n002 4 c914 d90b d560 d7c1 | 33 c409 (0) c7fa (0) c60e (0) c301 (0)\n003 1 f6a6 | 13 f97e (0) fc88 (0) fd44 (0) fd3f (0)\n004 3 e850 ecff ec78 | 12 ec78 (0) ecff (0) eee1 (0) ee3f (0)\n005 3 e3d8 e31e e255 | 4 e190 (0) e255 (0) e3d8 (0) e31e (0)\n006 2 e6b7 e724 | 2 e6b7 (0) e724 (0)\n007 4 e406 e469 e4d6 e4e9 | 4 e406 (0) e469 (0) e4d6 (0) e4e9 (0)\n============ DEPTH: 8 ==========================================\n008 1 e5d2 | 1 e5d2 (0)\n009 0 | 0\n010 1 e54d | 1 e54d (0)\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"fe62314839c93d2f6e3aee984d5f0b321897c6f39e66800d3de8b773baf6f19e0a03cae025df512aea8d5f1b667b6dbb15c192a90a76d3031c14e33e5c16c4f7","private_key":"ca130a8083cac47d964d46dbbded845892b326aa4fa12489d21578f9f018d45b","name":"node_fe62314839c93d2f6e3aee984d5f0b321897c6f39e66800d3de8b773baf6f19e0a03cae025df512aea8d5f1b667b6dbb15c192a90a76d3031c14e33e5c16c4f7","services":["streamer"],"enable_msg_events":true,"port":63385},"up":true}},{"node":{"info":{"id":"c903c5ee3d9cd65bea3ea777e39282c33e1349d945411fb2f16321bf582c2f400956a98fbafe5873fc5f6f6a9a051df5da7e94cbd340f935abe80f91e79ef875","name":"node_c903c5ee3d9cd65bea3ea777e39282c33e1349d945411fb2f16321bf582c2f400956a98fbafe5873fc5f6f6a9a051df5da7e94cbd340f935abe80f91e79ef875","enode":"enode://c903c5ee3d9cd65bea3ea777e39282c33e1349d945411fb2f16321bf582c2f400956a98fbafe5873fc5f6f6a9a051df5da7e94cbd340f935abe80f91e79ef875@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"l0dJB6AzRFAyefHYZpUjOWK2025Ze25BsRyUHCyi3EY=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 974749\npopulation: 24 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 71bf 3d17 | 122 581a (0) 5a67 (0) 5b30 (0) 5e3e (0)\n001 4 d90b c914 e4e9 e56c | 71 c409 (0) c7fa (0) c60e (0) c301 (0)\n002 3 bf6b a077 a0e4 | 30 b049 (0) b391 (0) b30e (0) b7aa (0)\n003 8 8ae8 8ee7 8d3c 802f | 15 89ef (0) 8a54 (0) 8ae8 (0) 8ea9 (0)\n004 3 98bc 9929 99eb | 10 9f4c (0) 9bc3 (0) 9b87 (0) 9a09 (0)\n005 1 92d5 | 4 910d (0) 9108 (0) 93f8 (0) 92d5 (0)\n============ DEPTH: 6 ==========================================\n006 2 9493 9404 | 2 9493 (0) 9404 (0)\n007 1 9641 | 1 9641 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"c903c5ee3d9cd65bea3ea777e39282c33e1349d945411fb2f16321bf582c2f400956a98fbafe5873fc5f6f6a9a051df5da7e94cbd340f935abe80f91e79ef875","private_key":"5d649fb189f6b462f678a083e7ad8d874c6bdeaafe0817cf4b361448024d9428","name":"node_c903c5ee3d9cd65bea3ea777e39282c33e1349d945411fb2f16321bf582c2f400956a98fbafe5873fc5f6f6a9a051df5da7e94cbd340f935abe80f91e79ef875","services":["streamer"],"enable_msg_events":true,"port":63386},"up":true}},{"node":{"info":{"id":"5420da16f7ed5de6b498dbc9a83b7e92e1f9900a6d04ef7351a0bfdfd442b98a5634f28fcea32ba3f3166d21c8ff5a39be70895b32acbdf7592d1d616a345a21","name":"node_5420da16f7ed5de6b498dbc9a83b7e92e1f9900a6d04ef7351a0bfdfd442b98a5634f28fcea32ba3f3166d21c8ff5a39be70895b32acbdf7592d1d616a345a21","enode":"enode://5420da16f7ed5de6b498dbc9a83b7e92e1f9900a6d04ef7351a0bfdfd442b98a5634f28fcea32ba3f3166d21c8ff5a39be70895b32acbdf7592d1d616a345a21@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"5Olfg4FWjBy6fo9k3XEFVLkjJBocmI3dtCos2WQ0cF8=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: e4e95f\npopulation: 21 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 3d17 71bf | 122 581a (0) 5a67 (0) 5b30 (0) 5cae (0)\n001 4 a077 af8f 9747 8564 | 63 b049 (0) b391 (0) b30e (0) b7aa (0)\n002 3 c914 d7c1 d90b | 33 c409 (0) c7fa (0) c60e (0) c301 (0)\n003 1 f6a6 | 13 f97e (0) ffb7 (0) fc88 (0) fd44 (0)\n004 2 e850 efdd | 12 ec78 (0) ecff (0) eee1 (0) ee3f (0)\n005 1 e31e | 4 e190 (0) e255 (0) e3d8 (0) e31e (0)\n006 2 e6b7 e724 | 2 e6b7 (0) e724 (0)\n007 3 e5d2 e54d e56c | 3 e5d2 (0) e54d (0) e56c (0)\n============ DEPTH: 8 ==========================================\n008 2 e406 e469 | 2 e406 (0) e469 (0)\n009 0 | 0\n010 1 e4d6 | 1 e4d6 (0)\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"5420da16f7ed5de6b498dbc9a83b7e92e1f9900a6d04ef7351a0bfdfd442b98a5634f28fcea32ba3f3166d21c8ff5a39be70895b32acbdf7592d1d616a345a21","private_key":"74fcb757f856401d62426a3e62cff6870099b0b261afb281d8d9e7dcf355a87b","name":"node_5420da16f7ed5de6b498dbc9a83b7e92e1f9900a6d04ef7351a0bfdfd442b98a5634f28fcea32ba3f3166d21c8ff5a39be70895b32acbdf7592d1d616a345a21","services":["streamer"],"enable_msg_events":true,"port":63387},"up":true}},{"node":{"info":{"id":"f54335964d9b4eb9813eb05f40ef1c523bbf0faac5a04c4737467d590fb6b55c7fa1fc5d4d32c5491d8766b9be6fdfd3ebdb25c5ffe1719f36c86ddf87ae3a85","name":"node_f54335964d9b4eb9813eb05f40ef1c523bbf0faac5a04c4737467d590fb6b55c7fa1fc5d4d32c5491d8766b9be6fdfd3ebdb25c5ffe1719f36c86ddf87ae3a85","enode":"enode://f54335964d9b4eb9813eb05f40ef1c523bbf0faac5a04c4737467d590fb6b55c7fa1fc5d4d32c5491d8766b9be6fdfd3ebdb25c5ffe1719f36c86ddf87ae3a85@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"PReJH1BrTJaHWPHVjrNcqIP91hrprTTsLAdrUGwSQik=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 3d1789\npopulation: 34 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 15 bf6b af8f a077 8564 | 134 89ef (0) 8a54 (0) 8ae8 (0) 8ee7 (0)\n001 2 71bf 60bc | 50 581a (0) 5a67 (0) 5b30 (0) 5e3e (0)\n002 1 11a0 | 37 07a6 (0) 0536 (0) 05a4 (0) 00c8 (0)\n003 4 208e 2c4e 293f 2940 | 15 2a7d (0) 293f (0) 2940 (0) 2c16 (0)\n004 4 3085 307c 3607 3658 | 10 34e4 (0) 3734 (0) 3799 (0) 3607 (0)\n005 5 3a18 3ab2 3843 38d7 | 6 3baa (0) 3ab2 (0) 3a18 (0) 38d7 (0)\n============ DEPTH: 6 ==========================================\n006 2 3ef6 3ff8 | 2 3ef6 (0) 3ff8 (0)\n007 1 3c5a | 1 3c5a (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"f54335964d9b4eb9813eb05f40ef1c523bbf0faac5a04c4737467d590fb6b55c7fa1fc5d4d32c5491d8766b9be6fdfd3ebdb25c5ffe1719f36c86ddf87ae3a85","private_key":"3e1263efdc899dcd32f1fd206de2370195ae82fccb81eb354dd9cb52fc5994e6","name":"node_f54335964d9b4eb9813eb05f40ef1c523bbf0faac5a04c4737467d590fb6b55c7fa1fc5d4d32c5491d8766b9be6fdfd3ebdb25c5ffe1719f36c86ddf87ae3a85","services":["streamer"],"enable_msg_events":true,"port":63388},"up":true}},{"node":{"info":{"id":"40bdac599b00e9c41ad6476ee415c33d9c17c5aa672692c2404e523b29dc315da929a86874bed87fd9009871805d1dbf3098e7a817193e3b08a6eee66346da79","name":"node_40bdac599b00e9c41ad6476ee415c33d9c17c5aa672692c2404e523b29dc315da929a86874bed87fd9009871805d1dbf3098e7a817193e3b08a6eee66346da79","enode":"enode://40bdac599b00e9c41ad6476ee415c33d9c17c5aa672692c2404e523b29dc315da929a86874bed87fd9009871805d1dbf3098e7a817193e3b08a6eee66346da79@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"2Qt1vRHqMkPgl/Ixi9laNVkMnxEzJP+h+UzXAaXT6zI=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: d90b75\npopulation: 23 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 5 413b 464b 7239 71bf | 122 581a (0) 5a67 (0) 5b30 (0) 5cae (0)\n001 5 bf6b a077 af8f 9747 | 63 9f4c (0) 9b87 (0) 9bc3 (0) 9a09 (0)\n002 4 f6a6 e56c e54d e4e9 | 38 f97e (0) ffb7 (0) fd44 (0) fd3f (0)\n003 3 cf77 ca8c c914 | 14 c3d8 (0) c301 (0) c409 (0) c60e (0)\n004 2 d777 d7c1 | 14 d2ac (0) d35c (0) d3bd (0) d1bc (0)\n005 2 de1d df52 | 2 de1d (0) df52 (0)\n============ DEPTH: 6 ==========================================\n006 1 dad3 | 1 dad3 (0)\n007 0 | 0\n008 0 | 0\n009 1 d96e | 1 d96e (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"40bdac599b00e9c41ad6476ee415c33d9c17c5aa672692c2404e523b29dc315da929a86874bed87fd9009871805d1dbf3098e7a817193e3b08a6eee66346da79","private_key":"a7cb8f80391de65478acf12a59fd0a0e9c5f04f0e4bc1da34b9acd35c586fe98","name":"node_40bdac599b00e9c41ad6476ee415c33d9c17c5aa672692c2404e523b29dc315da929a86874bed87fd9009871805d1dbf3098e7a817193e3b08a6eee66346da79","services":["streamer"],"enable_msg_events":true,"port":63389},"up":true}},{"node":{"info":{"id":"b26f7c0113a5ae885f7c0e608aea7022a9c8bfc40c5643e60b2ba7343ff09c5be0bc08be34dde3c6b85fea192a46d4764770c12cbaa233df4231a1b99627ef9d","name":"node_b26f7c0113a5ae885f7c0e608aea7022a9c8bfc40c5643e60b2ba7343ff09c5be0bc08be34dde3c6b85fea192a46d4764770c12cbaa233df4231a1b99627ef9d","enode":"enode://b26f7c0113a5ae885f7c0e608aea7022a9c8bfc40c5643e60b2ba7343ff09c5be0bc08be34dde3c6b85fea192a46d4764770c12cbaa233df4231a1b99627ef9d@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"yRTJb7bA7NUeBD8DlcfGNZXM2ZDJTZ7iQbFNo1Kqh3M=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: c914c9\npopulation: 22 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 3d17 464b 71bf | 122 0020 (0) 00c8 (0) 0305 (0) 020f (0)\n001 4 8564 9747 af8f a077 | 63 9f4c (0) 9b87 (0) 9bc3 (0) 9a09 (0)\n002 5 f6a6 e850 e54d e56c | 38 f97e (0) fd44 (0) fd3f (0) fc88 (0)\n003 2 d7c1 d90b | 19 d2ac (0) d35c (0) d3bd (0) d1bc (0)\n004 1 c3d8 | 5 c409 (0) c60e (0) c7fa (0) c301 (0)\n005 2 ce71 cf77 | 2 ce71 (0) cf77 (0)\n006 3 cba4 caa3 ca8c | 4 cbd3 (0) cba4 (0) caa3 (0) ca8c (0)\n007 0 | 0\n008 0 | 0\n============ DEPTH: 9 ==========================================\n009 1 c95a | 1 c95a (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 1 c911 | 1 c911 (0)\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"b26f7c0113a5ae885f7c0e608aea7022a9c8bfc40c5643e60b2ba7343ff09c5be0bc08be34dde3c6b85fea192a46d4764770c12cbaa233df4231a1b99627ef9d","private_key":"dbbe33233150cc109e4ec1b6d6bf5f14bb573d87551440db2407ec75821b4ee6","name":"node_b26f7c0113a5ae885f7c0e608aea7022a9c8bfc40c5643e60b2ba7343ff09c5be0bc08be34dde3c6b85fea192a46d4764770c12cbaa233df4231a1b99627ef9d","services":["streamer"],"enable_msg_events":true,"port":63390},"up":true}},{"node":{"info":{"id":"829b074b70d757da6aa00f7bace3cf1b5d2d4eeadb7f370c1a85374a01a70b54ac53d747267e386f3b41e6d790fecdd6e74b8f89745501ee82439a66ea54443a","name":"node_829b074b70d757da6aa00f7bace3cf1b5d2d4eeadb7f370c1a85374a01a70b54ac53d747267e386f3b41e6d790fecdd6e74b8f89745501ee82439a66ea54443a","enode":"enode://829b074b70d757da6aa00f7bace3cf1b5d2d4eeadb7f370c1a85374a01a70b54ac53d747267e386f3b41e6d790fecdd6e74b8f89745501ee82439a66ea54443a@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"cb/GfK3H8G5jjyyHsOJaTOw1tmVa2yf3Kzd3QSW9ONM=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 71bfc6\npopulation: 28 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 13 8564 8d3c 9747 bf6b | 134 9f4c (0) 9bc3 (0) 9b87 (0) 9a09 (0)\n001 2 3d17 11a0 | 72 0305 (0) 020f (0) 0020 (0) 00c8 (0)\n002 2 464b 4dc4 | 31 5a67 (0) 5b30 (0) 581a (0) 5cae (0)\n003 3 60bc 63de 6701 | 9 69d8 (0) 6923 (0) 6f1c (0) 6caa (0)\n004 3 7ec4 7e45 7aef | 4 7810 (0) 7aef (0) 7e45 (0) 7ec4 (0)\n005 2 77bc 76a5 | 2 77bc (0) 76a5 (0)\n============ DEPTH: 6 ==========================================\n006 2 7299 7239 | 2 7299 (0) 7239 (0)\n007 0 | 0\n008 1 715b | 1 715b (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"829b074b70d757da6aa00f7bace3cf1b5d2d4eeadb7f370c1a85374a01a70b54ac53d747267e386f3b41e6d790fecdd6e74b8f89745501ee82439a66ea54443a","private_key":"1058ecb8bc4354469a7fbef819dd8efc60c72db3101ff2f4d3d8089876ae94d1","name":"node_829b074b70d757da6aa00f7bace3cf1b5d2d4eeadb7f370c1a85374a01a70b54ac53d747267e386f3b41e6d790fecdd6e74b8f89745501ee82439a66ea54443a","services":["streamer"],"enable_msg_events":true,"port":63391},"up":true}},{"node":{"info":{"id":"302c37f28c69fdcf00b39ce0c0223de0d94cebc2c0b068315b95b76b5432573ead0656569441029ba9054d8d3d959fd8735e73913af5ce3f1132f8271fd437ef","name":"node_302c37f28c69fdcf00b39ce0c0223de0d94cebc2c0b068315b95b76b5432573ead0656569441029ba9054d8d3d959fd8735e73913af5ce3f1132f8271fd437ef","enode":"enode://302c37f28c69fdcf00b39ce0c0223de0d94cebc2c0b068315b95b76b5432573ead0656569441029ba9054d8d3d959fd8735e73913af5ce3f1132f8271fd437ef@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"r4+2EWJwY7QI0rlsGraPr7IjqG2UfePaw6WWSc0T4M8=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: af8fb6\npopulation: 16 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 3d17 11a0 71bf | 122 07a6 (0) 05a4 (0) 0536 (0) 00c8 (0)\n001 4 e4e9 c911 c914 d90b | 71 f97e (0) fd44 (0) fd3f (0) fc88 (0)\n002 1 8564 | 33 9f4c (0) 9b87 (0) 9bc3 (0) 9a09 (0)\n003 1 bf6b | 13 b7aa (0) b45f (0) b40d (0) b049 (0)\n004 3 a317 a0e4 a077 | 12 a478 (0) a6bd (0) a75d (0) a3f2 (0)\n============ DEPTH: 5 ==========================================\n005 3 a9df a936 aa78 | 3 a9df (0) a936 (0) aa78 (0)\n006 1 ac62 | 1 ac62 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"302c37f28c69fdcf00b39ce0c0223de0d94cebc2c0b068315b95b76b5432573ead0656569441029ba9054d8d3d959fd8735e73913af5ce3f1132f8271fd437ef","private_key":"7a22f9270103c5214bec5fccac665913b7e9ba442667ca7ca7f1bead2d44e594","name":"node_302c37f28c69fdcf00b39ce0c0223de0d94cebc2c0b068315b95b76b5432573ead0656569441029ba9054d8d3d959fd8735e73913af5ce3f1132f8271fd437ef","services":["streamer"],"enable_msg_events":true,"port":63392},"up":true}},{"node":{"info":{"id":"4e95fb8943ef6502fa470870a7ace4ca11e18589bd2073167543a922317b35e40b5068934d07e56c8fdd23354dfad51fd2899db854f189841f02b5914cd97749","name":"node_4e95fb8943ef6502fa470870a7ace4ca11e18589bd2073167543a922317b35e40b5068934d07e56c8fdd23354dfad51fd2899db854f189841f02b5914cd97749","enode":"enode://4e95fb8943ef6502fa470870a7ace4ca11e18589bd2073167543a922317b35e40b5068934d07e56c8fdd23354dfad51fd2899db854f189841f02b5914cd97749@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"oHem+IMqXX0hRtmwjeDJ9K41FaP4fydRWS4RWK2wQVU=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: a077a6\npopulation: 28 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 5 3d17 11a0 413b 464b | 122 2e3b (0) 2f23 (0) 2f1f (0) 2c4e (0)\n001 5 f2f5 e4e9 e54d d90b | 71 f97e (0) fc88 (0) fd44 (0) fd3f (0)\n002 2 9747 8564 | 33 9f4c (0) 9a09 (0) 9b87 (0) 9bc3 (0)\n003 2 b30e bf6b | 13 b049 (0) b391 (0) b30e (0) b7aa (0)\n004 3 aa78 ac62 af8f | 5 a9df (0) a936 (0) aa78 (0) ac62 (0)\n005 3 a478 a6bd a75d | 3 a478 (0) a6bd (0) a75d (0)\n006 2 a3f2 a317 | 2 a3f2 (0) a317 (0)\n007 3 a1b6 a1f1 a105 | 3 a105 (0) a1f1 (0) a1b6 (0)\n============ DEPTH: 8 ==========================================\n008 2 a0e4 a0c9 | 2 a0c9 (0) a0e4 (0)\n009 1 a011 | 1 a011 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"4e95fb8943ef6502fa470870a7ace4ca11e18589bd2073167543a922317b35e40b5068934d07e56c8fdd23354dfad51fd2899db854f189841f02b5914cd97749","private_key":"32e05e400e6938d31aa93e7666905a5a12e2b4b706354eae5f34259cf6880e60","name":"node_4e95fb8943ef6502fa470870a7ace4ca11e18589bd2073167543a922317b35e40b5068934d07e56c8fdd23354dfad51fd2899db854f189841f02b5914cd97749","services":["streamer"],"enable_msg_events":true,"port":63393},"up":true}},{"node":{"info":{"id":"807340e5fdf6c21a56ef2fd158c32e92201206ca85fcc147165a408f7a735964afd47c397e663610ac53870ae722c0317291732b0422f8aeedae783d9c730218","name":"node_807340e5fdf6c21a56ef2fd158c32e92201206ca85fcc147165a408f7a735964afd47c397e663610ac53870ae722c0317291732b0422f8aeedae783d9c730218","enode":"enode://807340e5fdf6c21a56ef2fd158c32e92201206ca85fcc147165a408f7a735964afd47c397e663610ac53870ae722c0317291732b0422f8aeedae783d9c730218@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"hWQiGfi7jOBIz85a7N3IrNA1r6A1oBN8NU9bb8PjiJ0=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 856422\npopulation: 20 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 71bf 3d17 11a0 | 122 2c4e (0) 2c16 (0) 2cb1 (0) 2cab (0)\n001 4 f6a6 e4e9 c914 d90b | 71 f97e (0) fd3f (0) fd44 (0) fc88 (0)\n002 3 bf6b af8f a077 | 30 b45f (0) b40d (0) b7aa (0) b049 (0)\n003 2 9929 9747 | 18 9f4c (0) 9b87 (0) 9bc3 (0) 9a09 (0)\n004 1 8d3c | 7 89ef (0) 8ae8 (0) 8a54 (0) 8ea9 (0)\n005 3 83d0 802f 802e | 3 83d0 (0) 802f (0) 802e (0)\n006 2 8611 86d3 | 2 8611 (0) 86d3 (0)\n============ DEPTH: 7 ==========================================\n007 1 8434 | 1 8434 (0)\n008 0 | 0\n009 1 853b | 1 853b (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"807340e5fdf6c21a56ef2fd158c32e92201206ca85fcc147165a408f7a735964afd47c397e663610ac53870ae722c0317291732b0422f8aeedae783d9c730218","private_key":"f6b0641261c3c0741d61572a591e72180deb8ba2c9922ea5db694c5b372aef6f","name":"node_807340e5fdf6c21a56ef2fd158c32e92201206ca85fcc147165a408f7a735964afd47c397e663610ac53870ae722c0317291732b0422f8aeedae783d9c730218","services":["streamer"],"enable_msg_events":true,"port":63394},"up":true}},{"node":{"info":{"id":"c9cd9dfb9f90a7948ac5a42c7bd63263f2eef6e1d85547559f7d2ecbf5f9cd1eab051b8e9e661b573c275d84091a44e73f6fc6bcc91dcdb674bd5d939190fc01","name":"node_c9cd9dfb9f90a7948ac5a42c7bd63263f2eef6e1d85547559f7d2ecbf5f9cd1eab051b8e9e661b573c275d84091a44e73f6fc6bcc91dcdb674bd5d939190fc01","enode":"enode://c9cd9dfb9f90a7948ac5a42c7bd63263f2eef6e1d85547559f7d2ecbf5f9cd1eab051b8e9e661b573c275d84091a44e73f6fc6bcc91dcdb674bd5d939190fc01@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"EaBnZkjK6nFCWueaVazXGg8v3qcLsNr7tTrBuOEkmvA=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 11a067\npopulation: 23 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 f6a6 af8f a077 8564 | 134 f97e (0) fd44 (0) fd3f (0) fc88 (0)\n001 6 71bf 7239 5237 48ec | 50 6caa (0) 6f1c (0) 69d8 (0) 6923 (0)\n002 3 398b 3ef6 3d17 | 35 2a7d (0) 2940 (0) 293f (0) 2e3b (0)\n003 1 09d1 | 18 00c8 (0) 0020 (0) 020f (0) 0305 (0)\n004 2 1dfd 1ea1 | 10 1953 (0) 1af6 (0) 1a8e (0) 1a85 (0)\n005 5 17a0 167b 14e4 15ec | 6 1758 (0) 17a0 (0) 167b (0) 14e4 (0)\n============ DEPTH: 6 ==========================================\n006 1 1254 | 1 1254 (0)\n007 1 10b1 | 1 10b1 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"c9cd9dfb9f90a7948ac5a42c7bd63263f2eef6e1d85547559f7d2ecbf5f9cd1eab051b8e9e661b573c275d84091a44e73f6fc6bcc91dcdb674bd5d939190fc01","private_key":"5809952239bc91701c49a3ca4362fe2f96294405e789a467c4899d1dc94f88ff","name":"node_c9cd9dfb9f90a7948ac5a42c7bd63263f2eef6e1d85547559f7d2ecbf5f9cd1eab051b8e9e661b573c275d84091a44e73f6fc6bcc91dcdb674bd5d939190fc01","services":["streamer"],"enable_msg_events":true,"port":63395},"up":true}},{"node":{"info":{"id":"1bc1d6155ba35d29ea16938994e08df76ebd8f16bd180bd6a9b9d8798d0745889fe72d641dd78bd8ec13526929f7eb5aaa6a388430fa69033d6db581e53c6422","name":"node_1bc1d6155ba35d29ea16938994e08df76ebd8f16bd180bd6a9b9d8798d0745889fe72d641dd78bd8ec13526929f7eb5aaa6a388430fa69033d6db581e53c6422","enode":"enode://1bc1d6155ba35d29ea16938994e08df76ebd8f16bd180bd6a9b9d8798d0745889fe72d641dd78bd8ec13526929f7eb5aaa6a388430fa69033d6db581e53c6422@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"RkuAMFzhsglMEpTEGqhCru4xaArJAjDfzyajYGoH+aY=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 464b80\npopulation: 27 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 7 bf6b a077 e54d f6a6 | 134 c409 (0) c7fa (0) c60e (0) c3d8 (0)\n001 2 11a0 398b | 72 2c16 (0) 2c4e (0) 2cb1 (0) 2cab (0)\n002 4 60bc 6701 71bf 7239 | 19 6923 (0) 69d8 (0) 6f1c (0) 6caa (0)\n003 2 5070 5237 | 15 5b30 (0) 5a67 (0) 581a (0) 5e3e (0)\n004 6 4c97 4dc4 48ec 4b70 | 8 4c97 (0) 4dc4 (0) 4b70 (0) 4bf8 (0)\n005 3 413b 43fb 42d6 | 4 42d6 (0) 43fb (0) 41b2 (0) 413b (0)\n============ DEPTH: 6 ==========================================\n006 2 44c8 44b7 | 2 44c8 (0) 44b7 (0)\n007 1 47a8 | 1 47a8 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"1bc1d6155ba35d29ea16938994e08df76ebd8f16bd180bd6a9b9d8798d0745889fe72d641dd78bd8ec13526929f7eb5aaa6a388430fa69033d6db581e53c6422","private_key":"284f36dbabbb181f068bce762670de591bac534570ddba3da4c91381188cc3a8","name":"node_1bc1d6155ba35d29ea16938994e08df76ebd8f16bd180bd6a9b9d8798d0745889fe72d641dd78bd8ec13526929f7eb5aaa6a388430fa69033d6db581e53c6422","services":["streamer"],"enable_msg_events":true,"port":63396},"up":true}},{"node":{"info":{"id":"e267e71c2dcdbe5a500b23444d2d4037ea15afba8f4f2b1c0e54a274450404fbee6fa5439f7cddf4ba1aa28fa93e434b01c239add58e30a5423ca3a481584d6b","name":"node_e267e71c2dcdbe5a500b23444d2d4037ea15afba8f4f2b1c0e54a274450404fbee6fa5439f7cddf4ba1aa28fa93e434b01c239add58e30a5423ca3a481584d6b","enode":"enode://e267e71c2dcdbe5a500b23444d2d4037ea15afba8f4f2b1c0e54a274450404fbee6fa5439f7cddf4ba1aa28fa93e434b01c239add58e30a5423ca3a481584d6b@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"cjn2/NU3tdWbhQccli1JWIBoAN4SexcsFnwrgUzsTYQ=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 7239f6\npopulation: 23 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 f6a6 e54d ca8c d90b | 134 c3d8 (0) c301 (0) c409 (0) c60e (0)\n001 3 38d7 398b 11a0 | 72 2a7d (0) 2940 (0) 293f (0) 2e3b (0)\n002 7 5070 5237 4b70 4b8a | 31 581a (0) 5a67 (0) 5b30 (0) 5e3e (0)\n003 3 60bc 63de 6701 | 9 6caa (0) 6f1c (0) 69d8 (0) 6923 (0)\n004 1 7aef | 4 7e45 (0) 7ec4 (0) 7810 (0) 7aef (0)\n005 2 77bc 76a5 | 2 77bc (0) 76a5 (0)\n============ DEPTH: 6 ==========================================\n006 2 715b 71bf | 2 715b (0) 71bf (0)\n007 0 | 0\n008 1 7299 | 1 7299 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"e267e71c2dcdbe5a500b23444d2d4037ea15afba8f4f2b1c0e54a274450404fbee6fa5439f7cddf4ba1aa28fa93e434b01c239add58e30a5423ca3a481584d6b","private_key":"c1b4e417ecbce61a39ecf4a30b86e303e82534bd890eea7c30b6ab4d0bdca861","name":"node_e267e71c2dcdbe5a500b23444d2d4037ea15afba8f4f2b1c0e54a274450404fbee6fa5439f7cddf4ba1aa28fa93e434b01c239add58e30a5423ca3a481584d6b","services":["streamer"],"enable_msg_events":true,"port":63397},"up":true}},{"node":{"info":{"id":"e98a08e8e3544727f5ee27f4465375a67ffba490fcdbfe7bfdc909f6b68bd279f776c65d38c2ccfc33079f852f76349c94d68fc6989c0d981f22333f036a4bb5","name":"node_e98a08e8e3544727f5ee27f4465375a67ffba490fcdbfe7bfdc909f6b68bd279f776c65d38c2ccfc33079f852f76349c94d68fc6989c0d981f22333f036a4bb5","enode":"enode://e98a08e8e3544727f5ee27f4465375a67ffba490fcdbfe7bfdc909f6b68bd279f776c65d38c2ccfc33079f852f76349c94d68fc6989c0d981f22333f036a4bb5@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"QTsVrnTji4YQ3V7dUuBWMPis+kE5obNhd1r6jnSOu/w=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 413b15\npopulation: 20 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 5 a077 ca8c d90b f6a6 | 134 89ef (0) 8a54 (0) 8ae8 (0) 8ea9 (0)\n001 2 398b 11a0 | 72 07a6 (0) 05a4 (0) 0536 (0) 00c8 (0)\n002 1 7239 | 19 6f1c (0) 6caa (0) 69d8 (0) 6923 (0)\n003 2 5070 5237 | 15 581a (0) 5a67 (0) 5b30 (0) 5e3e (0)\n004 4 4dc4 4b70 4b8a 48ec | 8 4c97 (0) 4dc4 (0) 4b70 (0) 4bf8 (0)\n005 3 44b7 464b 47a8 | 4 44c8 (0) 44b7 (0) 47a8 (0) 464b (0)\n============ DEPTH: 6 ==========================================\n006 2 42d6 43fb | 2 42d6 (0) 43fb (0)\n007 0 | 0\n008 1 41b2 | 1 41b2 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"e98a08e8e3544727f5ee27f4465375a67ffba490fcdbfe7bfdc909f6b68bd279f776c65d38c2ccfc33079f852f76349c94d68fc6989c0d981f22333f036a4bb5","private_key":"eda1f1637d46610c0a885d4e08d8d4e776868f98be4dca745ebfadda65f2a81b","name":"node_e98a08e8e3544727f5ee27f4465375a67ffba490fcdbfe7bfdc909f6b68bd279f776c65d38c2ccfc33079f852f76349c94d68fc6989c0d981f22333f036a4bb5","services":["streamer"],"enable_msg_events":true,"port":63398},"up":true}},{"node":{"info":{"id":"cb310c0e86aa455d7c9af6394ae38561c901da30a51d7ccb7e66a09d9a8f192ae8caeff106043426d56397088f141c4e01e3b98f1ee583ffc7318b5f730f3ac7","name":"node_cb310c0e86aa455d7c9af6394ae38561c901da30a51d7ccb7e66a09d9a8f192ae8caeff106043426d56397088f141c4e01e3b98f1ee583ffc7318b5f730f3ac7","enode":"enode://cb310c0e86aa455d7c9af6394ae38561c901da30a51d7ccb7e66a09d9a8f192ae8caeff106043426d56397088f141c4e01e3b98f1ee583ffc7318b5f730f3ac7@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"5U1p87sGHGLe3m5ahwRwC/m4Bj7erXx1XJWG9NlnVPE=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: e54d69\npopulation: 19 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 398b 7239 464b 413b | 122 00c8 (0) 0020 (0) 0305 (0) 020f (0)\n001 2 a077 bf6b | 63 89ef (0) 8a54 (0) 8ae8 (0) 8ea9 (0)\n002 2 c914 d90b | 33 c3d8 (0) c301 (0) c409 (0) c60e (0)\n003 1 f6a6 | 13 f97e (0) fd44 (0) fd3f (0) fc88 (0)\n004 1 efdd | 12 ecff (0) ec78 (0) eee1 (0) ee3f (0)\n005 1 e31e | 4 e190 (0) e255 (0) e3d8 (0) e31e (0)\n006 2 e6b7 e724 | 2 e6b7 (0) e724 (0)\n007 4 e469 e406 e4d6 e4e9 | 4 e406 (0) e469 (0) e4d6 (0) e4e9 (0)\n============ DEPTH: 8 ==========================================\n008 1 e5d2 | 1 e5d2 (0)\n009 0 | 0\n010 1 e56c | 1 e56c (0)\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"cb310c0e86aa455d7c9af6394ae38561c901da30a51d7ccb7e66a09d9a8f192ae8caeff106043426d56397088f141c4e01e3b98f1ee583ffc7318b5f730f3ac7","private_key":"51d301cb37e7206eeee2847d753aa67cbf0513b6e7cd41022003c2e7b3ef5581","name":"node_cb310c0e86aa455d7c9af6394ae38561c901da30a51d7ccb7e66a09d9a8f192ae8caeff106043426d56397088f141c4e01e3b98f1ee583ffc7318b5f730f3ac7","services":["streamer"],"enable_msg_events":true,"port":63399},"up":true}},{"node":{"info":{"id":"1090e9d89cb278a30063a5396d9ba795d3bbc237c76915a6fb7d23aa1822c8535d2fccc44cc8cd2acec68444c0bf1bdf5195ebb9f3cad8dac3d94a4d9c0e5309","name":"node_1090e9d89cb278a30063a5396d9ba795d3bbc237c76915a6fb7d23aa1822c8535d2fccc44cc8cd2acec68444c0bf1bdf5195ebb9f3cad8dac3d94a4d9c0e5309","enode":"enode://1090e9d89cb278a30063a5396d9ba795d3bbc237c76915a6fb7d23aa1822c8535d2fccc44cc8cd2acec68444c0bf1bdf5195ebb9f3cad8dac3d94a4d9c0e5309@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"v2tcX42La+qy2CwbqWFjCfp6MFIFDjHl9G7KxGNv0Q4=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: bf6b5c\npopulation: 27 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 71bf 464b 3d17 1587 | 122 0bc3 (0) 0ad6 (0) 0a3f (0) 09d1 (0)\n001 5 d90b ca8c cf77 e54d | 71 d1bc (0) d044 (0) d07c (0) d0b7 (0)\n002 3 9747 8d3c 8564 | 33 9f4c (0) 9b87 (0) 9bc3 (0) 9a09 (0)\n003 6 af8f a75d a6bd a0e4 | 17 a936 (0) a9df (0) aa78 (0) ac62 (0)\n004 3 b049 b7aa b40d | 6 b30e (0) b391 (0) b049 (0) b7aa (0)\n005 4 baaf bbcb bb31 b820 | 4 baaf (0) bbcb (0) bb31 (0) b820 (0)\n============ DEPTH: 6 ==========================================\n006 1 bd39 | 1 bd39 (0)\n007 1 beb7 | 1 beb7 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"1090e9d89cb278a30063a5396d9ba795d3bbc237c76915a6fb7d23aa1822c8535d2fccc44cc8cd2acec68444c0bf1bdf5195ebb9f3cad8dac3d94a4d9c0e5309","private_key":"30d23072d68ccfe357cba2b3294b9584b591e8c7898031f7c4dbaaadfdd05e1b","name":"node_1090e9d89cb278a30063a5396d9ba795d3bbc237c76915a6fb7d23aa1822c8535d2fccc44cc8cd2acec68444c0bf1bdf5195ebb9f3cad8dac3d94a4d9c0e5309","services":["streamer"],"enable_msg_events":true,"port":63400},"up":true}},{"node":{"info":{"id":"4b784f072b7c96c30612767425f552e30e45157e70139dfbe0ae4ff86dc31601adec60f8a3ad9747b02b5219073d8813af9b09d59eaf7ddb7ee24856aff6fa8f","name":"node_4b784f072b7c96c30612767425f552e30e45157e70139dfbe0ae4ff86dc31601adec60f8a3ad9747b02b5219073d8813af9b09d59eaf7ddb7ee24856aff6fa8f","enode":"enode://4b784f072b7c96c30612767425f552e30e45157e70139dfbe0ae4ff86dc31601adec60f8a3ad9747b02b5219073d8813af9b09d59eaf7ddb7ee24856aff6fa8f@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"9qZJQbBWHbv7OHpdRI5A7sBJPxwMH65NzTFKGlH2sC0=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: f6a649\npopulation: 31 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 9 71bf 7239 48ec 464b | 122 6923 (0) 69d8 (0) 6f1c (0) 6caa (0)\n001 2 8564 bf6b | 63 9f4c (0) 9a09 (0) 9b87 (0) 9bc3 (0)\n002 4 d90b c914 ca8c cf77 | 33 d1bc (0) d07c (0) d044 (0) d0b7 (0)\n003 5 e31e e724 e4e9 e56c | 25 ec78 (0) ecff (0) eee1 (0) ee3f (0)\n004 4 fc88 fd44 fd3f ffb7 | 5 f97e (0) fd44 (0) fd3f (0) fc88 (0)\n============ DEPTH: 5 ==========================================\n005 7 f2f5 f293 f2b2 f1b9 | 7 f2f5 (0) f293 (0) f2b2 (0) f1b9 (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"4b784f072b7c96c30612767425f552e30e45157e70139dfbe0ae4ff86dc31601adec60f8a3ad9747b02b5219073d8813af9b09d59eaf7ddb7ee24856aff6fa8f","private_key":"90d8283793c2eb15b76d7d9e492b3c3e7136115c74bf027ad9985179380a82b8","name":"node_4b784f072b7c96c30612767425f552e30e45157e70139dfbe0ae4ff86dc31601adec60f8a3ad9747b02b5219073d8813af9b09d59eaf7ddb7ee24856aff6fa8f","services":["streamer"],"enable_msg_events":true,"port":63401},"up":true}},{"node":{"info":{"id":"22010c9829626a6892258b09cb3f3edc3f21382fb487b5dbf0dd20e198e37e26134aab850e30337f398d1491b5126839aeb1953ec144bc19aeb889c832f67c6a","name":"node_22010c9829626a6892258b09cb3f3edc3f21382fb487b5dbf0dd20e198e37e26134aab850e30337f398d1491b5126839aeb1953ec144bc19aeb889c832f67c6a","enode":"enode://22010c9829626a6892258b09cb3f3edc3f21382fb487b5dbf0dd20e198e37e26134aab850e30337f398d1491b5126839aeb1953ec144bc19aeb889c832f67c6a@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"OYu4pN/L9QqT3pNogzH+1CRU1JQbNnxWnpvFaNGPvAA=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 398bb8\npopulation: 22 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 ca8c e54d f6a6 | 134 9f4c (0) 9a09 (0) 9bc3 (0) 9b87 (0)\n001 5 7239 464b 413b 4b70 | 50 6caa (0) 6f1c (0) 69d8 (0) 6923 (0)\n002 4 1ea1 11a0 14e4 1587 | 37 07a6 (0) 0536 (0) 05a4 (0) 00c8 (0)\n003 2 2737 208e | 15 2a7d (0) 2940 (0) 293f (0) 2e3b (0)\n004 1 3085 | 10 34e4 (0) 3734 (0) 3799 (0) 3658 (0)\n005 2 3ff8 3d17 | 4 3ef6 (0) 3ff8 (0) 3c5a (0) 3d17 (0)\n006 3 3baa 3ab2 3a18 | 3 3baa (0) 3ab2 (0) 3a18 (0)\n============ DEPTH: 7 ==========================================\n007 2 38d7 3843 | 2 38d7 (0) 3843 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"22010c9829626a6892258b09cb3f3edc3f21382fb487b5dbf0dd20e198e37e26134aab850e30337f398d1491b5126839aeb1953ec144bc19aeb889c832f67c6a","private_key":"b9111f0cf5ecf0a5dd7683f07c58f581a175bfbdf307224db008d7792e30c6a3","name":"node_22010c9829626a6892258b09cb3f3edc3f21382fb487b5dbf0dd20e198e37e26134aab850e30337f398d1491b5126839aeb1953ec144bc19aeb889c832f67c6a","services":["streamer"],"enable_msg_events":true,"port":63402},"up":true}},{"node":{"info":{"id":"043fe7085e8c90c18270f84dba5fab138e50216a1cf8d81a3794d156fad7fc81d1422aff169b244b13f91d73eebb5de464f97b1b93b3ad2a58959cff19238842","name":"node_043fe7085e8c90c18270f84dba5fab138e50216a1cf8d81a3794d156fad7fc81d1422aff169b244b13f91d73eebb5de464f97b1b93b3ad2a58959cff19238842","enode":"enode://043fe7085e8c90c18270f84dba5fab138e50216a1cf8d81a3794d156fad7fc81d1422aff169b244b13f91d73eebb5de464f97b1b93b3ad2a58959cff19238842@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"SOyXhXfi2/BEirEZo4Ib5dJdv1opX9T2lbkxFClTiiY=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 48ec97\npopulation: 19 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 f6a6 ca8c | 134 9f4c (0) 9bc3 (0) 9b87 (0) 9a09 (0)\n001 5 1ea1 11a0 1587 3085 | 72 07a6 (0) 05a4 (0) 0536 (0) 0305 (0)\n002 1 7239 | 19 6caa (0) 6f1c (0) 69d8 (0) 6923 (0)\n003 2 5070 5237 | 15 581a (0) 5a67 (0) 5b30 (0) 5e3e (0)\n004 2 464b 413b | 8 42d6 (0) 43fb (0) 41b2 (0) 413b (0)\n005 2 4c97 4dc4 | 2 4c97 (0) 4dc4 (0)\n============ DEPTH: 6 ==========================================\n006 4 4b70 4bf8 4bbc 4b8a | 4 4b70 (0) 4bf8 (0) 4bbc (0) 4b8a (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 1 48df | 1 48df (0)\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"043fe7085e8c90c18270f84dba5fab138e50216a1cf8d81a3794d156fad7fc81d1422aff169b244b13f91d73eebb5de464f97b1b93b3ad2a58959cff19238842","private_key":"7652297b6b2c9a5339f9d375aac2c9b81f0274e3949b4033e513c02802f040bd","name":"node_043fe7085e8c90c18270f84dba5fab138e50216a1cf8d81a3794d156fad7fc81d1422aff169b244b13f91d73eebb5de464f97b1b93b3ad2a58959cff19238842","services":["streamer"],"enable_msg_events":true,"port":63403},"up":true}},{"node":{"info":{"id":"329145e75496cecb5f5c8f00313a52ddd8c0e8cd27ef1b2bc1b2b56e4d4089aaf5a7a3c4d9a40bdb92483fa05bd24d1cd0fd51883e30439dffa0fc855e1a7cd0","name":"node_329145e75496cecb5f5c8f00313a52ddd8c0e8cd27ef1b2bc1b2b56e4d4089aaf5a7a3c4d9a40bdb92483fa05bd24d1cd0fd51883e30439dffa0fc855e1a7cd0","enode":"enode://329145e75496cecb5f5c8f00313a52ddd8c0e8cd27ef1b2bc1b2b56e4d4089aaf5a7a3c4d9a40bdb92483fa05bd24d1cd0fd51883e30439dffa0fc855e1a7cd0@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"yowaNujGmYAot89FCG9keKYi8Ah4vNJkO8sCHvyM9Qs=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: ca8c1a\npopulation: 22 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 7 398b 1587 7239 5237 | 122 2a7d (0) 2940 (0) 293f (0) 2e3b (0)\n001 2 8d3c bf6b | 63 910d (0) 9108 (0) 92d5 (0) 93f8 (0)\n002 3 e724 ffb7 f6a6 | 38 ebc9 (0) ebe8 (0) e9fa (0) e850 (0)\n003 1 d90b | 19 d2ac (0) d3bd (0) d35c (0) d1bc (0)\n004 3 c7fa c3d8 c301 | 5 c409 (0) c60e (0) c7fa (0) c3d8 (0)\n005 2 ce71 cf77 | 2 ce71 (0) cf77 (0)\n006 1 c914 | 3 c95a (0) c911 (0) c914 (0)\n============ DEPTH: 7 ==========================================\n007 2 cbd3 cba4 | 2 cbd3 (0) cba4 (0)\n008 0 | 0\n009 0 | 0\n010 1 caa3 | 1 caa3 (0)\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"329145e75496cecb5f5c8f00313a52ddd8c0e8cd27ef1b2bc1b2b56e4d4089aaf5a7a3c4d9a40bdb92483fa05bd24d1cd0fd51883e30439dffa0fc855e1a7cd0","private_key":"7971b1a36d0caacd64acbd61a149d41c05102d757fc313f2c49c6b2185bc22d9","name":"node_329145e75496cecb5f5c8f00313a52ddd8c0e8cd27ef1b2bc1b2b56e4d4089aaf5a7a3c4d9a40bdb92483fa05bd24d1cd0fd51883e30439dffa0fc855e1a7cd0","services":["streamer"],"enable_msg_events":true,"port":63404},"up":true}},{"node":{"info":{"id":"2a63d875e715c2a43302d32d86d30c7d7faed46c08a67bf488762637216b99dd87333a66df6d9f3a57df863b1f1a219ddbeebb9f3e92e523bd08540a195448ca","name":"node_2a63d875e715c2a43302d32d86d30c7d7faed46c08a67bf488762637216b99dd87333a66df6d9f3a57df863b1f1a219ddbeebb9f3e92e523bd08540a195448ca","enode":"enode://2a63d875e715c2a43302d32d86d30c7d7faed46c08a67bf488762637216b99dd87333a66df6d9f3a57df863b1f1a219ddbeebb9f3e92e523bd08540a195448ca@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"FYftkE3ybtcR4iNf6kHlgSp9M85dqy67TohRWxj0PW4=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 1587ed\npopulation: 15 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 bf6b e724 cf77 ca8c | 134 9f4c (0) 9a09 (0) 9b87 (0) 9bc3 (0)\n001 1 48ec | 50 6f1c (0) 6caa (0) 69d8 (0) 6923 (0)\n002 2 208e 398b | 35 2940 (0) 293f (0) 2a7d (0) 2e3b (0)\n003 1 09d1 | 18 07a6 (0) 05a4 (0) 0536 (0) 0305 (0)\n004 1 1ea1 | 10 1953 (0) 1af6 (0) 1a85 (0) 1a8e (0)\n005 1 11a0 | 3 1254 (0) 10b1 (0) 11a0 (0)\n006 3 167b 1758 17a0 | 3 1758 (0) 17a0 (0) 167b (0)\n============ DEPTH: 7 ==========================================\n007 1 14e4 | 1 14e4 (0)\n008 0 | 0\n009 1 15ec | 1 15ec (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"2a63d875e715c2a43302d32d86d30c7d7faed46c08a67bf488762637216b99dd87333a66df6d9f3a57df863b1f1a219ddbeebb9f3e92e523bd08540a195448ca","private_key":"62692081cdf8e04e73d8942c5fb423f153ea6d32d16fc0e3b05c10927bcc42c3","name":"node_2a63d875e715c2a43302d32d86d30c7d7faed46c08a67bf488762637216b99dd87333a66df6d9f3a57df863b1f1a219ddbeebb9f3e92e523bd08540a195448ca","services":["streamer"],"enable_msg_events":true,"port":63405},"up":true}},{"node":{"info":{"id":"0deda014fa3c0bc8f37d853e1448f95f56f97048c28797d72258fd3ba2f1f776ae11566197466596356cd172847ab02a89f4cf047e58383249fb2a4cd69b6206","name":"node_0deda014fa3c0bc8f37d853e1448f95f56f97048c28797d72258fd3ba2f1f776ae11566197466596356cd172847ab02a89f4cf047e58383249fb2a4cd69b6206","enode":"enode://0deda014fa3c0bc8f37d853e1448f95f56f97048c28797d72258fd3ba2f1f776ae11566197466596356cd172847ab02a89f4cf047e58383249fb2a4cd69b6206@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"z3ce4G9auc+wAISl7okp0V5DTy/7xLpCicskcRBBRvs=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: cf771e\npopulation: 24 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 5070 1ea1 14e4 1587 | 122 65a6 (0) 67ee (0) 6701 (0) 63de (0)\n001 2 8d3c bf6b | 63 a9df (0) a936 (0) aa78 (0) ac62 (0)\n002 3 ffb7 f6a6 e724 | 38 f2f5 (0) f293 (0) f2b2 (0) f1b9 (0)\n003 5 d7c1 d777 d96e d90b | 19 d2ac (0) d35c (0) d3bd (0) d1bc (0)\n004 2 c301 c7fa | 5 c3d8 (0) c301 (0) c409 (0) c60e (0)\n============ DEPTH: 5 ==========================================\n005 7 c95a c911 c914 cbd3 | 7 c95a (0) c911 (0) c914 (0) cbd3 (0)\n006 0 | 0\n007 1 ce71 | 1 ce71 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"0deda014fa3c0bc8f37d853e1448f95f56f97048c28797d72258fd3ba2f1f776ae11566197466596356cd172847ab02a89f4cf047e58383249fb2a4cd69b6206","private_key":"bff5d02d0e187260b2ac19e027a5a8c72d358aa420a1dd22dcc8d34a921a81f7","name":"node_0deda014fa3c0bc8f37d853e1448f95f56f97048c28797d72258fd3ba2f1f776ae11566197466596356cd172847ab02a89f4cf047e58383249fb2a4cd69b6206","services":["streamer"],"enable_msg_events":true,"port":63406},"up":true}},{"node":{"info":{"id":"c332fe1f9b6e25f72c7150631ffa6e0929ff6eeab5d17aa45eaf669bdde869cf404505ae990a529aa3ca797cd0a96f31cc41431a5d4a163132be566f91623c08","name":"node_c332fe1f9b6e25f72c7150631ffa6e0929ff6eeab5d17aa45eaf669bdde869cf404505ae990a529aa3ca797cd0a96f31cc41431a5d4a163132be566f91623c08","enode":"enode://c332fe1f9b6e25f72c7150631ffa6e0929ff6eeab5d17aa45eaf669bdde869cf404505ae990a529aa3ca797cd0a96f31cc41431a5d4a163132be566f91623c08@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"HqFlOgfOLgekABjzpejc4CWBd+lWlqeMV+o+7MJuaUk=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 1ea165\npopulation: 28 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 5 8d3c e724 f6a6 ffb7 | 134 b391 (0) b30e (0) b049 (0) b7aa (0)\n001 7 715b 4dc4 4b70 4b8a | 50 6caa (0) 6f1c (0) 69d8 (0) 6923 (0)\n002 3 208e 3085 398b | 35 2a7d (0) 2940 (0) 293f (0) 2e3b (0)\n003 3 020f 0020 09d1 | 18 07a6 (0) 05a4 (0) 0536 (0) 00c8 (0)\n004 4 11a0 167b 1587 14e4 | 9 1254 (0) 10b1 (0) 11a0 (0) 1758 (0)\n005 1 1a8e | 4 1953 (0) 1af6 (0) 1a85 (0) 1a8e (0)\n============ DEPTH: 6 ==========================================\n006 4 1d5b 1dfc 1dfd 1daa | 4 1d5b (0) 1dfc (0) 1dfd (0) 1daa (0)\n007 1 1fab | 1 1fab (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"c332fe1f9b6e25f72c7150631ffa6e0929ff6eeab5d17aa45eaf669bdde869cf404505ae990a529aa3ca797cd0a96f31cc41431a5d4a163132be566f91623c08","private_key":"e2478cb11c2e4c83e5be5962e0a2e9dd367bc4bed98c7bcd08c211f35010b4f8","name":"node_c332fe1f9b6e25f72c7150631ffa6e0929ff6eeab5d17aa45eaf669bdde869cf404505ae990a529aa3ca797cd0a96f31cc41431a5d4a163132be566f91623c08","services":["streamer"],"enable_msg_events":true,"port":63407},"up":true}},{"node":{"info":{"id":"5566111b7f14d8ec83ba6456488f3fc5c7e2c86bf406dead33b814e1ee9b569d34015a4d88226b7e28fff7784395c086d106287cbbc80acfe75b05cd6e12903d","name":"node_5566111b7f14d8ec83ba6456488f3fc5c7e2c86bf406dead33b814e1ee9b569d34015a4d88226b7e28fff7784395c086d106287cbbc80acfe75b05cd6e12903d","enode":"enode://5566111b7f14d8ec83ba6456488f3fc5c7e2c86bf406dead33b814e1ee9b569d34015a4d88226b7e28fff7784395c086d106287cbbc80acfe75b05cd6e12903d@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"UHBgvgMDRIUN9vx2cZ1QMlSzjZbXfrJfScqdlVlEsQo=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 507060\npopulation: 21 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 cf77 ffb7 e724 | 134 b049 (0) b391 (0) b30e (0) b45f (0)\n001 2 3085 1ea1 | 72 2a7d (0) 2940 (0) 293f (0) 2e3b (0)\n002 1 7239 | 19 6caa (0) 6f1c (0) 69d8 (0) 6923 (0)\n003 5 464b 413b 48ec 4b70 | 16 42d6 (0) 43fb (0) 41b2 (0) 413b (0)\n004 3 5c9b 5a67 581a | 6 581a (0) 5a67 (0) 5b30 (0) 5e3e (0)\n005 3 56bb 5741 5765 | 4 56bb (0) 5765 (0) 5741 (0) 57ee (0)\n006 2 5399 5237 | 2 5399 (0) 5237 (0)\n============ DEPTH: 7 ==========================================\n007 1 510c | 1 510c (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 1 5062 | 1 5062 (0)\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"5566111b7f14d8ec83ba6456488f3fc5c7e2c86bf406dead33b814e1ee9b569d34015a4d88226b7e28fff7784395c086d106287cbbc80acfe75b05cd6e12903d","private_key":"c4dc5aeb69312070307af3c8a24d468a0284733f29b07b5407e0819cb054fbdf","name":"node_5566111b7f14d8ec83ba6456488f3fc5c7e2c86bf406dead33b814e1ee9b569d34015a4d88226b7e28fff7784395c086d106287cbbc80acfe75b05cd6e12903d","services":["streamer"],"enable_msg_events":true,"port":63408},"up":true}},{"node":{"info":{"id":"b4a5efa9028b2d196855393892f79993c2812d02b758f98813ddf82c5d943faf6d66eff811cc5a51936c118f4c768c0d13b54902095e040c602761e63c08655e","name":"node_b4a5efa9028b2d196855393892f79993c2812d02b758f98813ddf82c5d943faf6d66eff811cc5a51936c118f4c768c0d13b54902095e040c602761e63c08655e","enode":"enode://b4a5efa9028b2d196855393892f79993c2812d02b758f98813ddf82c5d943faf6d66eff811cc5a51936c118f4c768c0d13b54902095e040c602761e63c08655e@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"5yQ/SFMMPwQIJ8Av3GdkLHoFaRODN6SYUX1PtNOPEK8=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: e7243f\npopulation: 25 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 5 1ea1 14e4 1587 5070 | 122 2c16 (0) 2c4e (0) 2cb1 (0) 2cab (0)\n001 3 9929 8d3c 802f | 63 b049 (0) b391 (0) b30e (0) b7aa (0)\n002 2 ca8c cf77 | 33 d2ac (0) d35c (0) d3bd (0) d1bc (0)\n003 3 f1ad f6a6 ffb7 | 13 f2f5 (0) f293 (0) f2b2 (0) f0b8 (0)\n004 3 e850 ecff ec78 | 12 ec78 (0) ecff (0) eee1 (0) ee3f (0)\n005 1 e31e | 4 e190 (0) e255 (0) e3d8 (0) e31e (0)\n============ DEPTH: 6 ==========================================\n006 7 e469 e406 e4d6 e4e9 | 7 e469 (0) e406 (0) e4d6 (0) e4e9 (0)\n007 1 e6b7 | 1 e6b7 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"b4a5efa9028b2d196855393892f79993c2812d02b758f98813ddf82c5d943faf6d66eff811cc5a51936c118f4c768c0d13b54902095e040c602761e63c08655e","private_key":"6832f6f7e27fc6e2c9745c44ea7004ffd4f6bd869b779e15ac0a4a2ffade7999","name":"node_b4a5efa9028b2d196855393892f79993c2812d02b758f98813ddf82c5d943faf6d66eff811cc5a51936c118f4c768c0d13b54902095e040c602761e63c08655e","services":["streamer"],"enable_msg_events":true,"port":63409},"up":true}},{"node":{"info":{"id":"adfba6d883cacbb141cd8c59ee04d7e5d520f1ce31a81e5db2d8b2380bf801c1fe4b265a66b71f9643d13a41cb1f6fb4b83399be786da4b6e171b6784bc56e49","name":"node_adfba6d883cacbb141cd8c59ee04d7e5d520f1ce31a81e5db2d8b2380bf801c1fe4b265a66b71f9643d13a41cb1f6fb4b83399be786da4b6e171b6784bc56e49","enode":"enode://adfba6d883cacbb141cd8c59ee04d7e5d520f1ce31a81e5db2d8b2380bf801c1fe4b265a66b71f9643d13a41cb1f6fb4b83399be786da4b6e171b6784bc56e49@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"UjdoQAxQVgePNoqVcjRI+uZ0eRf7OpxkKTDr/ZedngU=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 523768\npopulation: 26 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 6 9929 8d3c 802f ca8c | 134 b049 (0) b30e (0) b391 (0) b7aa (0)\n001 4 3085 1ea1 11a0 14e4 | 72 2a7d (0) 2940 (0) 293f (0) 2e3b (0)\n002 1 7239 | 19 69d8 (0) 6923 (0) 6caa (0) 6f1c (0)\n003 8 464b 413b 4c97 4dc4 | 16 44c8 (0) 44b7 (0) 47a8 (0) 464b (0)\n004 2 5c9b 5e3e | 6 581a (0) 5a67 (0) 5b30 (0) 5e3e (0)\n005 1 56bb | 4 57ee (0) 5765 (0) 5741 (0) 56bb (0)\n============ DEPTH: 6 ==========================================\n006 3 510c 5062 5070 | 3 510c (0) 5062 (0) 5070 (0)\n007 1 5399 | 1 5399 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"adfba6d883cacbb141cd8c59ee04d7e5d520f1ce31a81e5db2d8b2380bf801c1fe4b265a66b71f9643d13a41cb1f6fb4b83399be786da4b6e171b6784bc56e49","private_key":"3362a08daff495b41e00fcb4786a68fff7a58eda86b6f6cb61bef90aaa604daa","name":"node_adfba6d883cacbb141cd8c59ee04d7e5d520f1ce31a81e5db2d8b2380bf801c1fe4b265a66b71f9643d13a41cb1f6fb4b83399be786da4b6e171b6784bc56e49","services":["streamer"],"enable_msg_events":true,"port":63410},"up":true}},{"node":{"info":{"id":"2bfba66ec9d63e928d77d455f2e10a14d6213e515099d5db14fa44a8bfc147eb0fa7afa9aaccdc86453c6903b55556059a2e13dd61fc494127d4a3ec173bf9ea","name":"node_2bfba66ec9d63e928d77d455f2e10a14d6213e515099d5db14fa44a8bfc147eb0fa7afa9aaccdc86453c6903b55556059a2e13dd61fc494127d4a3ec173bf9ea","enode":"enode://2bfba66ec9d63e928d77d455f2e10a14d6213e515099d5db14fa44a8bfc147eb0fa7afa9aaccdc86453c6903b55556059a2e13dd61fc494127d4a3ec173bf9ea@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"/7c8cVSYd176PYLeQXpEacZqFVyhFJ/sehygoifqtPM=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: ffb73c\npopulation: 23 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 3085 1ea1 5070 5237 | 122 2e3b (0) 2f1f (0) 2f23 (0) 2cb1 (0)\n001 5 a011 9929 802f 8ae8 | 63 b30e (0) b391 (0) b049 (0) b45f (0)\n002 3 d0b7 ca8c cf77 | 33 d2ac (0) d35c (0) d3bd (0) d1bc (0)\n003 2 e31e e724 | 25 ec78 (0) ecff (0) ee3f (0) ee52 (0)\n004 5 f6a6 f2b2 f0b8 f054 | 8 f6a6 (0) f2f5 (0) f293 (0) f2b2 (0)\n005 1 f97e | 1 f97e (0)\n============ DEPTH: 6 ==========================================\n006 3 fc88 fd3f fd44 | 3 fd3f (0) fd44 (0) fc88 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"2bfba66ec9d63e928d77d455f2e10a14d6213e515099d5db14fa44a8bfc147eb0fa7afa9aaccdc86453c6903b55556059a2e13dd61fc494127d4a3ec173bf9ea","private_key":"1d18aaec8f9b90606b18283e8527016a8122999804aa11d280ab2bb37f14a948","name":"node_2bfba66ec9d63e928d77d455f2e10a14d6213e515099d5db14fa44a8bfc147eb0fa7afa9aaccdc86453c6903b55556059a2e13dd61fc494127d4a3ec173bf9ea","services":["streamer"],"enable_msg_events":true,"port":63411},"up":true}},{"node":{"info":{"id":"0b7e1e5acabcde503ad827e45724402406114a513f81040a379b0f82df2eab4456b348b27936369c49e3c264d971c6a9e2c2217fdbc5e5b93ac6fc219957834d","name":"node_0b7e1e5acabcde503ad827e45724402406114a513f81040a379b0f82df2eab4456b348b27936369c49e3c264d971c6a9e2c2217fdbc5e5b93ac6fc219957834d","enode":"enode://0b7e1e5acabcde503ad827e45724402406114a513f81040a379b0f82df2eab4456b348b27936369c49e3c264d971c6a9e2c2217fdbc5e5b93ac6fc219957834d@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"jTwMcXourRNcQUtphBrelOEm6wqJEyosb1MXKMYqkYA=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 8d3c0c\npopulation: 26 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 71bf 5237 14e4 1ea1 | 122 6caa (0) 6f1c (0) 69d8 (0) 6923 (0)\n001 8 ca8c cf77 df52 d96e | 71 de1d (0) df52 (0) dad3 (0) d90b (0)\n002 3 bf6b a317 a011 | 30 b30e (0) b391 (0) b049 (0) b45f (0)\n003 2 9747 9929 | 18 93f8 (0) 92d5 (0) 9108 (0) 910d (0)\n004 3 8564 802e 802f | 8 8611 (0) 86d3 (0) 8434 (0) 853b (0)\n005 3 89ef 8ae8 8a54 | 3 89ef (0) 8ae8 (0) 8a54 (0)\n============ DEPTH: 6 ==========================================\n006 2 8ea9 8ee7 | 2 8ea9 (0) 8ee7 (0)\n007 0 | 0\n008 1 8d85 | 1 8d85 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"0b7e1e5acabcde503ad827e45724402406114a513f81040a379b0f82df2eab4456b348b27936369c49e3c264d971c6a9e2c2217fdbc5e5b93ac6fc219957834d","private_key":"757285cfa33b746d1bf24044430d43f5ff7401cef2452217ac9fe5fbce629acb","name":"node_0b7e1e5acabcde503ad827e45724402406114a513f81040a379b0f82df2eab4456b348b27936369c49e3c264d971c6a9e2c2217fdbc5e5b93ac6fc219957834d","services":["streamer"],"enable_msg_events":true,"port":63412},"up":true}},{"node":{"info":{"id":"7554993f6efd8d9016ff525ae73c41ee2e0dbd4970c563ba9b61a99c1c8943b433c4b7d48450f6e0fbc9ac198d907698093de20e6c1f7755520fb1e1cbee4eb4","name":"node_7554993f6efd8d9016ff525ae73c41ee2e0dbd4970c563ba9b61a99c1c8943b433c4b7d48450f6e0fbc9ac198d907698093de20e6c1f7755520fb1e1cbee4eb4","enode":"enode://7554993f6efd8d9016ff525ae73c41ee2e0dbd4970c563ba9b61a99c1c8943b433c4b7d48450f6e0fbc9ac198d907698093de20e6c1f7755520fb1e1cbee4eb4@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"gC+eiFNeQMF5y199KhZQBpbiryEV0/fKDKxcL2NBCcI=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 802f9e\npopulation: 16 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 5237 14e4 | 122 6caa (0) 6f1c (0) 69d8 (0) 6923 (0)\n001 2 e724 ffb7 | 71 de1d (0) df52 (0) dad3 (0) d90b (0)\n002 1 a011 | 30 b30e (0) b391 (0) b049 (0) b45f (0)\n003 2 9747 9929 | 18 93f8 (0) 92d5 (0) 9108 (0) 910d (0)\n004 3 8ee7 8d85 8d3c | 7 89ef (0) 8ae8 (0) 8a54 (0) 8ea9 (0)\n005 4 8611 86d3 853b 8564 | 5 8611 (0) 86d3 (0) 8434 (0) 853b (0)\n============ DEPTH: 6 ==========================================\n006 1 83d0 | 1 83d0 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 1 802e | 1 802e (0)\n========================================================================="}},"config":{"id":"7554993f6efd8d9016ff525ae73c41ee2e0dbd4970c563ba9b61a99c1c8943b433c4b7d48450f6e0fbc9ac198d907698093de20e6c1f7755520fb1e1cbee4eb4","private_key":"cc0bf84e41ddcab9146ec892653a911dce5007786d77ec7a32e490fea0a29687","name":"node_7554993f6efd8d9016ff525ae73c41ee2e0dbd4970c563ba9b61a99c1c8943b433c4b7d48450f6e0fbc9ac198d907698093de20e6c1f7755520fb1e1cbee4eb4","services":["streamer"],"enable_msg_events":true,"port":63413},"up":true}},{"node":{"info":{"id":"4fe37f2dfb03707c90a6fe91dbcfd7497db70ffc20043091d50e1cee573210c144e8749340f2c3cb70fe8fc51b317d49e8734dc51ce64b3cdccdd639ae35d1ae","name":"node_4fe37f2dfb03707c90a6fe91dbcfd7497db70ffc20043091d50e1cee573210c144e8749340f2c3cb70fe8fc51b317d49e8734dc51ce64b3cdccdd639ae35d1ae","enode":"enode://4fe37f2dfb03707c90a6fe91dbcfd7497db70ffc20043091d50e1cee573210c144e8749340f2c3cb70fe8fc51b317d49e8734dc51ce64b3cdccdd639ae35d1ae@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"FOQPmr6LLIRfL8Yqj0NH/zYwkYzWKjOvd4jkv1mc+5Y=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 14e40f\npopulation: 24 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 8 cf77 e724 bb31 a317 | 134 de1d (0) df52 (0) dad3 (0) d90b (0)\n001 2 4b70 5237 | 50 7e45 (0) 7ec4 (0) 7aef (0) 7810 (0)\n002 4 398b 3085 2f1f 208e | 35 2a7d (0) 2940 (0) 293f (0) 2c4e (0)\n003 1 09d1 | 18 07a6 (0) 05a4 (0) 0536 (0) 0305 (0)\n004 3 1daa 1fab 1ea1 | 10 1953 (0) 1af6 (0) 1a85 (0) 1a8e (0)\n005 1 11a0 | 3 1254 (0) 10b1 (0) 11a0 (0)\n006 3 167b 1758 17a0 | 3 1758 (0) 17a0 (0) 167b (0)\n============ DEPTH: 7 ==========================================\n007 2 15ec 1587 | 2 15ec (0) 1587 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"4fe37f2dfb03707c90a6fe91dbcfd7497db70ffc20043091d50e1cee573210c144e8749340f2c3cb70fe8fc51b317d49e8734dc51ce64b3cdccdd639ae35d1ae","private_key":"d1add26924dcfc37eefccd6271759a9b0a2052607f3698be305e1c9bcb47ea66","name":"node_4fe37f2dfb03707c90a6fe91dbcfd7497db70ffc20043091d50e1cee573210c144e8749340f2c3cb70fe8fc51b317d49e8734dc51ce64b3cdccdd639ae35d1ae","services":["streamer"],"enable_msg_events":true,"port":63414},"up":true}},{"node":{"info":{"id":"a7507aa5665e165ab2e2a07def272f0677f9d6d35bb82268a34214384e7d8ef7635a299368752e63cfd02d4e60231076baf23cfa10d17492e55181b391ecf335","name":"node_a7507aa5665e165ab2e2a07def272f0677f9d6d35bb82268a34214384e7d8ef7635a299368752e63cfd02d4e60231076baf23cfa10d17492e55181b391ecf335","enode":"enode://a7507aa5665e165ab2e2a07def272f0677f9d6d35bb82268a34214384e7d8ef7635a299368752e63cfd02d4e60231076baf23cfa10d17492e55181b391ecf335@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"mSlZwdq7ZVpXy63+sYQ28hImpWlo/wyZJqabhmks8ok=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 992959\npopulation: 29 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 5237 14e4 | 122 7e45 (0) 7ec4 (0) 7810 (0) 7aef (0)\n001 4 d96e d777 ffb7 e724 | 71 d1bc (0) d0b7 (0) d044 (0) d07c (0)\n002 2 a317 a011 | 30 b30e (0) b391 (0) b049 (0) b45f (0)\n003 9 8ee7 8d85 8d3c 86d3 | 15 8ae8 (0) 8a54 (0) 89ef (0) 8ea9 (0)\n004 3 910d 9747 9404 | 8 92d5 (0) 93f8 (0) 9108 (0) 910d (0)\n005 1 9f4c | 1 9f4c (0)\n006 3 9b87 9bc3 9a09 | 3 9b87 (0) 9bc3 (0) 9a09 (0)\n007 3 985f 98bc 98aa | 3 985f (0) 98bc (0) 98aa (0)\n============ DEPTH: 8 ==========================================\n008 1 99eb | 1 99eb (0)\n009 0 | 0\n010 1 9918 | 1 9918 (0)\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"a7507aa5665e165ab2e2a07def272f0677f9d6d35bb82268a34214384e7d8ef7635a299368752e63cfd02d4e60231076baf23cfa10d17492e55181b391ecf335","private_key":"fb8563b48e2c07948cc2347d50c953b2b4bcd79a535c2ac597d8f8c7f1ffa8e6","name":"node_a7507aa5665e165ab2e2a07def272f0677f9d6d35bb82268a34214384e7d8ef7635a299368752e63cfd02d4e60231076baf23cfa10d17492e55181b391ecf335","services":["streamer"],"enable_msg_events":true,"port":63415},"up":true}},{"node":{"info":{"id":"7e2b0b4f3b55e97bd7241b984ad117af33bf3baacd22b3ed503a8a59f75828df745fb3ce3be4276d83eb484e64d9aa251103fa994ef119eaddb97a3503b9f292","name":"node_7e2b0b4f3b55e97bd7241b984ad117af33bf3baacd22b3ed503a8a59f75828df745fb3ce3be4276d83eb484e64d9aa251103fa994ef119eaddb97a3503b9f292","enode":"enode://7e2b0b4f3b55e97bd7241b984ad117af33bf3baacd22b3ed503a8a59f75828df745fb3ce3be4276d83eb484e64d9aa251103fa994ef119eaddb97a3503b9f292@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"oBHJJBBOBy7EFc9yJVFnWC5dPxifVBBmuoizrgBBtQg=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: a011c9\npopulation: 19 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 14e4 208e | 122 7810 (0) 7aef (0) 7e45 (0) 7ec4 (0)\n001 2 ffb7 e31e | 71 f6a6 (0) f2f5 (0) f293 (0) f2b2 (0)\n002 4 802f 8d85 8d3c 9929 | 33 8611 (0) 86d3 (0) 8434 (0) 853b (0)\n003 2 bf6b bb31 | 13 b30e (0) b391 (0) b049 (0) b45f (0)\n004 1 aa78 | 5 af8f (0) ac62 (0) a9df (0) a936 (0)\n005 2 a75d a478 | 3 a478 (0) a6bd (0) a75d (0)\n006 2 a3f2 a317 | 2 a3f2 (0) a317 (0)\n007 1 a1f1 | 3 a105 (0) a1b6 (0) a1f1 (0)\n============ DEPTH: 8 ==========================================\n008 2 a0c9 a0e4 | 2 a0c9 (0) a0e4 (0)\n009 1 a077 | 1 a077 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"7e2b0b4f3b55e97bd7241b984ad117af33bf3baacd22b3ed503a8a59f75828df745fb3ce3be4276d83eb484e64d9aa251103fa994ef119eaddb97a3503b9f292","private_key":"f7b5d2c9faba98230f0e0bbd82106d1fb949413a7940eec52e71e9c5c7266d3e","name":"node_7e2b0b4f3b55e97bd7241b984ad117af33bf3baacd22b3ed503a8a59f75828df745fb3ce3be4276d83eb484e64d9aa251103fa994ef119eaddb97a3503b9f292","services":["streamer"],"enable_msg_events":true,"port":63416},"up":true}},{"node":{"info":{"id":"460531928a4b084686343c8464b37c3452bb3566045698d08a4692864de5581a9eb1dc632329e7d3ccb73ec31ee7693787d69df8458efaba9a7105d87ee2e053","name":"node_460531928a4b084686343c8464b37c3452bb3566045698d08a4692864de5581a9eb1dc632329e7d3ccb73ec31ee7693787d69df8458efaba9a7105d87ee2e053","enode":"enode://460531928a4b084686343c8464b37c3452bb3566045698d08a4692864de5581a9eb1dc632329e7d3ccb73ec31ee7693787d69df8458efaba9a7105d87ee2e053@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"II5kijK1m3fCq76sBALI0AlIWhndSgSiFs2R0MZxOSk=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 208e64\npopulation: 17 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 a011 | 134 f6a6 (0) f2f5 (0) f293 (0) f2b2 (0)\n001 2 4b70 4b8a | 50 7e45 (0) 7ec4 (0) 7810 (0) 7aef (0)\n002 3 1587 14e4 1ea1 | 37 00c8 (0) 0020 (0) 0305 (0) 020f (0)\n003 5 3d17 3ff8 3a18 398b | 20 3ef6 (0) 3ff8 (0) 3c5a (0) 3d17 (0)\n004 2 2f1f 2cab | 10 293f (0) 2940 (0) 2a7d (0) 2e3b (0)\n005 2 24f8 2737 | 2 24f8 (0) 2737 (0)\n============ DEPTH: 6 ==========================================\n006 2 2220 2224 | 2 2224 (0) 2220 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"460531928a4b084686343c8464b37c3452bb3566045698d08a4692864de5581a9eb1dc632329e7d3ccb73ec31ee7693787d69df8458efaba9a7105d87ee2e053","private_key":"61a9bec441ae9ada2f3ed71874596db20f2807e921453ec39145770056e3cee5","name":"node_460531928a4b084686343c8464b37c3452bb3566045698d08a4692864de5581a9eb1dc632329e7d3ccb73ec31ee7693787d69df8458efaba9a7105d87ee2e053","services":["streamer"],"enable_msg_events":true,"port":63417},"up":true}},{"node":{"info":{"id":"70ee3c7e02a123f78345d41c386e413f06b51f1ab346c2c472891eed7dd26a1f14e213a0f4f2d872859b9b535936a6d9b072d2604456f76221a422710411822f","name":"node_70ee3c7e02a123f78345d41c386e413f06b51f1ab346c2c472891eed7dd26a1f14e213a0f4f2d872859b9b535936a6d9b072d2604456f76221a422710411822f","enode":"enode://70ee3c7e02a123f78345d41c386e413f06b51f1ab346c2c472891eed7dd26a1f14e213a0f4f2d872859b9b535936a6d9b072d2604456f76221a422710411822f@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"MIUo1EUAfhicMeaV8rx0rz3rq0c/V7/9hmxgEVX/w9M=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 308528\npopulation: 22 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 e31e ffb7 d96e d777 | 134 f2f5 (0) f2b2 (0) f293 (0) f1b9 (0)\n001 5 5237 5070 48ec 4b8a | 50 7e45 (0) 7ec4 (0) 7810 (0) 7aef (0)\n002 3 09d1 14e4 1ea1 | 37 0536 (0) 05a4 (0) 07a6 (0) 020f (0)\n003 2 293f 208e | 15 2c4e (0) 2c16 (0) 2cb1 (0) 2cab (0)\n004 2 3d17 398b | 10 3ef6 (0) 3ff8 (0) 3d17 (0) 3c5a (0)\n005 2 3607 3799 | 5 34e4 (0) 3734 (0) 3799 (0) 3658 (0)\n006 2 3388 3227 | 2 3388 (0) 3227 (0)\n007 0 | 0\n============ DEPTH: 8 ==========================================\n008 2 3054 307c | 2 3054 (0) 307c (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"70ee3c7e02a123f78345d41c386e413f06b51f1ab346c2c472891eed7dd26a1f14e213a0f4f2d872859b9b535936a6d9b072d2604456f76221a422710411822f","private_key":"56e11a31d85d33461e13dd635ea6c0d0be892feb3ccc9dadc327bbd855401d2c","name":"node_70ee3c7e02a123f78345d41c386e413f06b51f1ab346c2c472891eed7dd26a1f14e213a0f4f2d872859b9b535936a6d9b072d2604456f76221a422710411822f","services":["streamer"],"enable_msg_events":true,"port":63418},"up":true}},{"node":{"info":{"id":"049a2b0ab4d49789dbbe1837e2d2ee5220a9401729ea87ab29385b24d79cdce255c3d2b5de6484d49ca6ce07bd41832598260c0a8c290e01d133d77f066f2f99","name":"node_049a2b0ab4d49789dbbe1837e2d2ee5220a9401729ea87ab29385b24d79cdce255c3d2b5de6484d49ca6ce07bd41832598260c0a8c290e01d133d77f066f2f99","enode":"enode://049a2b0ab4d49789dbbe1837e2d2ee5220a9401729ea87ab29385b24d79cdce255c3d2b5de6484d49ca6ce07bd41832598260c0a8c290e01d133d77f066f2f99@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"S3CWTOKRa7BWzsbaMSg/TrPN93S4bzujaxP1b+wYxts=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 4b7096\npopulation: 25 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 e31e d96e df52 | 134 f6a6 (0) f2f5 (0) f293 (0) f2b2 (0)\n001 5 1ea1 14e4 208e 398b | 72 07a6 (0) 05a4 (0) 0536 (0) 00c8 (0)\n002 3 7239 6923 60bc | 19 7e45 (0) 7ec4 (0) 7810 (0) 7aef (0)\n003 5 5c9b 510c 5062 5070 | 15 581a (0) 5a67 (0) 5b30 (0) 5e3e (0)\n004 2 464b 413b | 8 43fb (0) 42d6 (0) 41b2 (0) 413b (0)\n005 2 4dc4 4c97 | 2 4dc4 (0) 4c97 (0)\n006 2 48df 48ec | 2 48df (0) 48ec (0)\n007 0 | 0\n============ DEPTH: 8 ==========================================\n008 3 4bf8 4bbc 4b8a | 3 4bf8 (0) 4bbc (0) 4b8a (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"049a2b0ab4d49789dbbe1837e2d2ee5220a9401729ea87ab29385b24d79cdce255c3d2b5de6484d49ca6ce07bd41832598260c0a8c290e01d133d77f066f2f99","private_key":"6df50913c97d23ce9e4ed894465ae4eb0f562d595e46d694b47e72d31c8bc8fd","name":"node_049a2b0ab4d49789dbbe1837e2d2ee5220a9401729ea87ab29385b24d79cdce255c3d2b5de6484d49ca6ce07bd41832598260c0a8c290e01d133d77f066f2f99","services":["streamer"],"enable_msg_events":true,"port":63419},"up":true}},{"node":{"info":{"id":"1f6d803a4ca186463772850ca0901fb920af7e74fdd2480c3c368fa707838ee91bbcfb57d5e3510c802b9b85f2d954f04c9b675414274bdaebae6488dcf94c10","name":"node_1f6d803a4ca186463772850ca0901fb920af7e74fdd2480c3c368fa707838ee91bbcfb57d5e3510c802b9b85f2d954f04c9b675414274bdaebae6488dcf94c10","enode":"enode://1f6d803a4ca186463772850ca0901fb920af7e74fdd2480c3c368fa707838ee91bbcfb57d5e3510c802b9b85f2d954f04c9b675414274bdaebae6488dcf94c10@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"31LV3g9eaefkyeD/zsH534bTgES7V+Wgyxi941Tstm0=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: df52d5\npopulation: 15 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 4b70 4b8a | 122 1254 (0) 10b1 (0) 11a0 (0) 167b (0)\n001 3 9404 8d3c a317 | 63 b049 (0) b391 (0) b30e (0) b7aa (0)\n002 1 e31e | 38 f6a6 (0) f2f5 (0) f293 (0) f2b2 (0)\n003 1 cf77 | 14 c409 (0) c7fa (0) c60e (0) c301 (0)\n004 4 d0b7 d560 d7c1 d777 | 14 d2ac (0) d3bd (0) d35c (0) d1bc (0)\n============ DEPTH: 5 ==========================================\n005 3 dad3 d90b d96e | 3 dad3 (0) d90b (0) d96e (0)\n006 0 | 0\n007 1 de1d | 1 de1d (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"1f6d803a4ca186463772850ca0901fb920af7e74fdd2480c3c368fa707838ee91bbcfb57d5e3510c802b9b85f2d954f04c9b675414274bdaebae6488dcf94c10","private_key":"164a5b537bdf9173b59b281a68d7da48819c2367e5b5faa1c94c74453a413015","name":"node_1f6d803a4ca186463772850ca0901fb920af7e74fdd2480c3c368fa707838ee91bbcfb57d5e3510c802b9b85f2d954f04c9b675414274bdaebae6488dcf94c10","services":["streamer"],"enable_msg_events":true,"port":63420},"up":true}},{"node":{"info":{"id":"979838eaefcff456cf1cd9c47ea46854704f5757d8d7ab907019bc422b01af4d62252579bf045d143fab491b0bab823190e2782a457fbf51aa99ae17ec9e145f","name":"node_979838eaefcff456cf1cd9c47ea46854704f5757d8d7ab907019bc422b01af4d62252579bf045d143fab491b0bab823190e2782a457fbf51aa99ae17ec9e145f","enode":"enode://979838eaefcff456cf1cd9c47ea46854704f5757d8d7ab907019bc422b01af4d62252579bf045d143fab491b0bab823190e2782a457fbf51aa99ae17ec9e145f@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"S4rMAh3eof/wNrSw5ZOcOFB+95JJBwH3s0Hk/xCnhWc=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 4b8acc\npopulation: 19 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 e31e d96e df52 | 134 8611 (0) 86d3 (0) 8434 (0) 853b (0)\n001 3 1ea1 3085 208e | 72 00c8 (0) 0020 (0) 0305 (0) 020f (0)\n002 2 60bc 7239 | 19 6caa (0) 6f1c (0) 69d8 (0) 6923 (0)\n003 2 5237 5070 | 15 581a (0) 5a67 (0) 5b30 (0) 5e3e (0)\n004 2 464b 413b | 8 42d6 (0) 43fb (0) 41b2 (0) 413b (0)\n005 2 4c97 4dc4 | 2 4c97 (0) 4dc4 (0)\n006 2 48df 48ec | 2 48df (0) 48ec (0)\n007 0 | 0\n008 1 4b70 | 1 4b70 (0)\n============ DEPTH: 9 ==========================================\n009 1 4bf8 | 1 4bf8 (0)\n010 1 4bbc | 1 4bbc (0)\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"979838eaefcff456cf1cd9c47ea46854704f5757d8d7ab907019bc422b01af4d62252579bf045d143fab491b0bab823190e2782a457fbf51aa99ae17ec9e145f","private_key":"0b14673d7790bcbb1b3f0d042dd9b22953002e6dd901486b6f203063bb8b5a79","name":"node_979838eaefcff456cf1cd9c47ea46854704f5757d8d7ab907019bc422b01af4d62252579bf045d143fab491b0bab823190e2782a457fbf51aa99ae17ec9e145f","services":["streamer"],"enable_msg_events":true,"port":63421},"up":true}},{"node":{"info":{"id":"ed6c793eb4565aa9d883a76fad6c97ad0b878b9ef0235e11e89db1af25a9653205f725c6ea258b84bde134f1a6437c6d109b859d17509e5016c4ab98be59032a","name":"node_ed6c793eb4565aa9d883a76fad6c97ad0b878b9ef0235e11e89db1af25a9653205f725c6ea258b84bde134f1a6437c6d109b859d17509e5016c4ab98be59032a","enode":"enode://ed6c793eb4565aa9d883a76fad6c97ad0b878b9ef0235e11e89db1af25a9653205f725c6ea258b84bde134f1a6437c6d109b859d17509e5016c4ab98be59032a@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"4x60TM876yV5rRC6MMCtsS3uzMVPnEd9MP5v2DCMEBA=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: e31eb4\npopulation: 26 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 3085 38d7 4b70 4b8a | 122 0305 (0) 020f (0) 00c8 (0) 0020 (0)\n001 2 8d3c a011 | 63 8611 (0) 86d3 (0) 8434 (0) 853b (0)\n002 3 df52 d96e d777 | 33 c409 (0) c7fa (0) c60e (0) c3d8 (0)\n003 3 f6a6 f1ad ffb7 | 13 f6a6 (0) f2f5 (0) f293 (0) f2b2 (0)\n004 2 e850 efbb | 12 ec78 (0) ecff (0) eee1 (0) ee3f (0)\n005 9 e56c e54d e5d2 e4d6 | 9 e4d6 (0) e4e9 (0) e469 (0) e406 (0)\n006 1 e190 | 1 e190 (0)\n============ DEPTH: 7 ==========================================\n007 1 e255 | 1 e255 (0)\n008 1 e3d8 | 1 e3d8 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"ed6c793eb4565aa9d883a76fad6c97ad0b878b9ef0235e11e89db1af25a9653205f725c6ea258b84bde134f1a6437c6d109b859d17509e5016c4ab98be59032a","private_key":"5d6c015866ee2afba25f1435274fb61e0b11b93829309bccad6cb662e5a4c8fb","name":"node_ed6c793eb4565aa9d883a76fad6c97ad0b878b9ef0235e11e89db1af25a9653205f725c6ea258b84bde134f1a6437c6d109b859d17509e5016c4ab98be59032a","services":["streamer"],"enable_msg_events":true,"port":63422},"up":true}},{"node":{"info":{"id":"6c143960dbe3ba4c95e8debc1fda5f420a2a673eb46f7ff7d9a30f4cd2067e67ef8926bf17f0c99b16c79b6dc066b52409a11d47117d4fda4211636b1b74f96c","name":"node_6c143960dbe3ba4c95e8debc1fda5f420a2a673eb46f7ff7d9a30f4cd2067e67ef8926bf17f0c99b16c79b6dc066b52409a11d47117d4fda4211636b1b74f96c","enode":"enode://6c143960dbe3ba4c95e8debc1fda5f420a2a673eb46f7ff7d9a30f4cd2067e67ef8926bf17f0c99b16c79b6dc066b52409a11d47117d4fda4211636b1b74f96c@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"13fkUjOqTYtyP2pqqcv13kwLGfb9AK9tU4tn7AG3SrU=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: d777e4\npopulation: 19 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 3085 | 122 020f (0) 0305 (0) 0020 (0) 00c8 (0)\n001 3 bb31 9929 8d3c | 63 8611 (0) 86d3 (0) 8434 (0) 853b (0)\n002 1 e31e | 38 f6a6 (0) f2f5 (0) f293 (0) f2b2 (0)\n003 2 caa3 cf77 | 14 c301 (0) c3d8 (0) c409 (0) c7fa (0)\n004 3 df52 d90b d96e | 5 de1d (0) df52 (0) dad3 (0) d90b (0)\n005 3 d1bc d0b7 d3bd | 7 d1bc (0) d07c (0) d044 (0) d0b7 (0)\n006 2 d455 d560 | 2 d455 (0) d560 (0)\n007 2 d606 d66f | 2 d606 (0) d66f (0)\n============ DEPTH: 8 ==========================================\n008 1 d7c1 | 1 d7c1 (0)\n009 1 d717 | 1 d717 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"6c143960dbe3ba4c95e8debc1fda5f420a2a673eb46f7ff7d9a30f4cd2067e67ef8926bf17f0c99b16c79b6dc066b52409a11d47117d4fda4211636b1b74f96c","private_key":"acbf964dfcd41c86715a5ecb9c03818b577cbb0755692cde879ff1e4b09e5df6","name":"node_6c143960dbe3ba4c95e8debc1fda5f420a2a673eb46f7ff7d9a30f4cd2067e67ef8926bf17f0c99b16c79b6dc066b52409a11d47117d4fda4211636b1b74f96c","services":["streamer"],"enable_msg_events":true,"port":63423},"up":true}},{"node":{"info":{"id":"7bbb3f3ed51cf84c077806fbd6d3578e105bc32aa6043da188793f066ad6df383a9f7cc0bd3124f4c887704bd188d480ce264fcdf178905bbda3b270927ea138","name":"node_7bbb3f3ed51cf84c077806fbd6d3578e105bc32aa6043da188793f066ad6df383a9f7cc0bd3124f4c887704bd188d480ce264fcdf178905bbda3b270927ea138","enode":"enode://7bbb3f3ed51cf84c077806fbd6d3578e105bc32aa6043da188793f066ad6df383a9f7cc0bd3124f4c887704bd188d480ce264fcdf178905bbda3b270927ea138@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"2W5DAybH/JH80ZxOhbRypBuiQxf/CeW9jrK9ejBkmb4=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: d96e43\npopulation: 20 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 3085 4b70 4b8a | 122 0020 (0) 00c8 (0) 020f (0) 0305 (0)\n001 4 9929 8d3c bb31 a317 | 63 8611 (0) 86d3 (0) 8434 (0) 853b (0)\n002 3 f1ad e6b7 e31e | 38 f97e (0) fd44 (0) fd3f (0) fc88 (0)\n003 1 cf77 | 14 c409 (0) c60e (0) c7fa (0) c3d8 (0)\n004 5 d0b7 d3bd d560 d7c1 | 14 d1bc (0) d07c (0) d044 (0) d0b7 (0)\n005 2 de1d df52 | 2 de1d (0) df52 (0)\n============ DEPTH: 6 ==========================================\n006 1 dad3 | 1 dad3 (0)\n007 0 | 0\n008 0 | 0\n009 1 d90b | 1 d90b (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"7bbb3f3ed51cf84c077806fbd6d3578e105bc32aa6043da188793f066ad6df383a9f7cc0bd3124f4c887704bd188d480ce264fcdf178905bbda3b270927ea138","private_key":"0b325cafe8524b8c126e860a6295fdeff6cf26da5e8eb426b86b25ba049c942b","name":"node_7bbb3f3ed51cf84c077806fbd6d3578e105bc32aa6043da188793f066ad6df383a9f7cc0bd3124f4c887704bd188d480ce264fcdf178905bbda3b270927ea138","services":["streamer"],"enable_msg_events":true,"port":63424},"up":true}},{"node":{"info":{"id":"2b70e5ffcc0bb1c4f8acc09dd1016e67c9c96c92d091ad481efbb71bd8b2a5a5869c6d668617a9b2cbfe91baf5edfe150c3824c84d90899a974099071d171441","name":"node_2b70e5ffcc0bb1c4f8acc09dd1016e67c9c96c92d091ad481efbb71bd8b2a5a5869c6d668617a9b2cbfe91baf5edfe150c3824c84d90899a974099071d171441","enode":"enode://2b70e5ffcc0bb1c4f8acc09dd1016e67c9c96c92d091ad481efbb71bd8b2a5a5869c6d668617a9b2cbfe91baf5edfe150c3824c84d90899a974099071d171441@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"oxdMsG8O0IxkD8I9KEDgAvU3oHqTrUZL6s2SwUCnip4=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: a3174c\npopulation: 26 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 5 60bc 48df 167b 14e4 | 122 24f8 (0) 2737 (0) 2224 (0) 2220 (0)\n001 4 efbb f1ad df52 d96e | 71 c3d8 (0) c301 (0) c409 (0) c60e (0)\n002 2 9929 8d3c | 33 92d5 (0) 93f8 (0) 9108 (0) 910d (0)\n003 1 bb31 | 13 b049 (0) b391 (0) b30e (0) b40d (0)\n004 3 a9df af8f ac62 | 5 ac62 (0) af8f (0) a9df (0) a936 (0)\n005 3 a6bd a75d a478 | 3 a6bd (0) a75d (0) a478 (0)\n============ DEPTH: 6 ==========================================\n006 7 a105 a1b6 a1f1 a0e4 | 7 a105 (0) a1b6 (0) a1f1 (0) a0c9 (0)\n007 0 | 0\n008 1 a3f2 | 1 a3f2 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"2b70e5ffcc0bb1c4f8acc09dd1016e67c9c96c92d091ad481efbb71bd8b2a5a5869c6d668617a9b2cbfe91baf5edfe150c3824c84d90899a974099071d171441","private_key":"e03e1d397bdd121257b1cd781c14847cf220f23fa837a4ba7b48f7b0b51cdc3c","name":"node_2b70e5ffcc0bb1c4f8acc09dd1016e67c9c96c92d091ad481efbb71bd8b2a5a5869c6d668617a9b2cbfe91baf5edfe150c3824c84d90899a974099071d171441","services":["streamer"],"enable_msg_events":true,"port":63425},"up":true}},{"node":{"info":{"id":"f5c1215a84a56d52f92ca0dc3a32df98c98a9c2ea2e9a34560210c16de1b440d20d043c8c25955dda8c22e55e92ddb49fd82e8b9b84072aabaa755a229bb19f4","name":"node_f5c1215a84a56d52f92ca0dc3a32df98c98a9c2ea2e9a34560210c16de1b440d20d043c8c25955dda8c22e55e92ddb49fd82e8b9b84072aabaa755a229bb19f4","enode":"enode://f5c1215a84a56d52f92ca0dc3a32df98c98a9c2ea2e9a34560210c16de1b440d20d043c8c25955dda8c22e55e92ddb49fd82e8b9b84072aabaa755a229bb19f4@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"uzGYu2Hz3JY2Wpm3FBwLhXIGFN5GQK+nZFjSdIThNTo=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: bb3198\npopulation: 19 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 14e4 2f1f | 122 3c5a (0) 3d17 (0) 3ef6 (0) 3ff8 (0)\n001 5 d96e d777 efbb f0b8 | 71 c3d8 (0) c301 (0) c409 (0) c60e (0)\n002 2 8d85 8ee7 | 33 9493 (0) 9404 (0) 9641 (0) 9747 (0)\n003 4 a75d a1f1 a011 a317 | 17 af8f (0) ac62 (0) a936 (0) a9df (0)\n004 1 b7aa | 6 b30e (0) b391 (0) b049 (0) b40d (0)\n005 2 beb7 bf6b | 3 bd39 (0) beb7 (0) bf6b (0)\n006 1 b820 | 1 b820 (0)\n============ DEPTH: 7 ==========================================\n007 1 baaf | 1 baaf (0)\n008 1 bbcb | 1 bbcb (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"f5c1215a84a56d52f92ca0dc3a32df98c98a9c2ea2e9a34560210c16de1b440d20d043c8c25955dda8c22e55e92ddb49fd82e8b9b84072aabaa755a229bb19f4","private_key":"8e1b0bcbebda90c6f0ba8edadd9133b28b77e49b584580e1219654aeeb9e3a2c","name":"node_f5c1215a84a56d52f92ca0dc3a32df98c98a9c2ea2e9a34560210c16de1b440d20d043c8c25955dda8c22e55e92ddb49fd82e8b9b84072aabaa755a229bb19f4","services":["streamer"],"enable_msg_events":true,"port":63426},"up":true}},{"node":{"info":{"id":"8c6d77833bf1a98beabe7a92d985d13d52fb2e50768719ffbc6fce21ea676802a074b6e620b3ef80e12fad04f94a3c288d91df9716a6cfae09ef073b9dc1f2cb","name":"node_8c6d77833bf1a98beabe7a92d985d13d52fb2e50768719ffbc6fce21ea676802a074b6e620b3ef80e12fad04f94a3c288d91df9716a6cfae09ef073b9dc1f2cb","enode":"enode://8c6d77833bf1a98beabe7a92d985d13d52fb2e50768719ffbc6fce21ea676802a074b6e620b3ef80e12fad04f94a3c288d91df9716a6cfae09ef073b9dc1f2cb@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"8a0YQ1YOrSlOnWDJv8mdioJ/LP5Vfg+f5+v4KuxWkm0=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: f1ad18\npopulation: 20 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 60bc | 122 3ef6 (0) 3ff8 (0) 3c5a (0) 3d17 (0)\n001 3 8d85 a317 bb31 | 63 93f8 (0) 92d5 (0) 9108 (0) 910d (0)\n002 3 d96e d3bd d0b7 | 33 c3d8 (0) c301 (0) c409 (0) c60e (0)\n003 4 e6b7 e724 e31e efbb | 25 e724 (0) e6b7 (0) e4d6 (0) e4e9 (0)\n004 3 f97e fc88 ffb7 | 5 f97e (0) fd44 (0) fd3f (0) fc88 (0)\n005 1 f6a6 | 1 f6a6 (0)\n006 2 f2f5 f2b2 | 3 f2f5 (0) f293 (0) f2b2 (0)\n============ DEPTH: 7 ==========================================\n007 2 f054 f0b8 | 2 f054 (0) f0b8 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 1 f1b9 | 1 f1b9 (0)\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"8c6d77833bf1a98beabe7a92d985d13d52fb2e50768719ffbc6fce21ea676802a074b6e620b3ef80e12fad04f94a3c288d91df9716a6cfae09ef073b9dc1f2cb","private_key":"ec0e383740a40976e4b9195b6a89e9497e9562729d196b3febbfea319be5dbcb","name":"node_8c6d77833bf1a98beabe7a92d985d13d52fb2e50768719ffbc6fce21ea676802a074b6e620b3ef80e12fad04f94a3c288d91df9716a6cfae09ef073b9dc1f2cb","services":["streamer"],"enable_msg_events":true,"port":63427},"up":true}},{"node":{"info":{"id":"b3316f4fd7dec218a52331f25d17a2faf0f2a417808d7dbb80038154abfbcd2d78da074837b648cff28675f4aa0d65ddb7d15abf3d7e0391d401e313a3ef24a2","name":"node_b3316f4fd7dec218a52331f25d17a2faf0f2a417808d7dbb80038154abfbcd2d78da074837b648cff28675f4aa0d65ddb7d15abf3d7e0391d401e313a3ef24a2","enode":"enode://b3316f4fd7dec218a52331f25d17a2faf0f2a417808d7dbb80038154abfbcd2d78da074837b648cff28675f4aa0d65ddb7d15abf3d7e0391d401e313a3ef24a2@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"YLw+AeiqznM416Mm6nlFtbnYKa6DxccNxp/pGbmjFIE=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 60bc3e\npopulation: 27 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 a317 a1f1 f1ad | 134 9108 (0) 910d (0) 92d5 (0) 93f8 (0)\n001 4 3d17 293f 2f1f 09d1 | 72 3ef6 (0) 3ff8 (0) 3d17 (0) 3c5a (0)\n002 10 5c9b 5b30 510c 5062 | 31 581a (0) 5a67 (0) 5b30 (0) 5e3e (0)\n003 4 7aef 71bf 7239 7299 | 10 7e45 (0) 7ec4 (0) 7810 (0) 7aef (0)\n004 2 6f1c 6923 | 4 6caa (0) 6f1c (0) 69d8 (0) 6923 (0)\n============ DEPTH: 5 ==========================================\n005 3 6701 67ee 65a6 | 3 6701 (0) 67ee (0) 65a6 (0)\n006 1 63de | 1 63de (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"b3316f4fd7dec218a52331f25d17a2faf0f2a417808d7dbb80038154abfbcd2d78da074837b648cff28675f4aa0d65ddb7d15abf3d7e0391d401e313a3ef24a2","private_key":"a8c69a5c41f2362bc5de8589f3686f3c59b02b58cb7139ba2325f1a7ff62c39e","name":"node_b3316f4fd7dec218a52331f25d17a2faf0f2a417808d7dbb80038154abfbcd2d78da074837b648cff28675f4aa0d65ddb7d15abf3d7e0391d401e313a3ef24a2","services":["streamer"],"enable_msg_events":true,"port":63428},"up":true}},{"node":{"info":{"id":"60725e8d0e9333636e598dd666f459b4be898d9abc095ee2c1db289673e7e969b50e2093956fef5a2f1d23e2040159bbabaaeab17fc6dbbac3f6acab766e9e60","name":"node_60725e8d0e9333636e598dd666f459b4be898d9abc095ee2c1db289673e7e969b50e2093956fef5a2f1d23e2040159bbabaaeab17fc6dbbac3f6acab766e9e60","enode":"enode://60725e8d0e9333636e598dd666f459b4be898d9abc095ee2c1db289673e7e969b50e2093956fef5a2f1d23e2040159bbabaaeab17fc6dbbac3f6acab766e9e60@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"CdFdfawyy9b5tbKS5ry1CC2V0k7buN3vhxiQQJqrYOc=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 09d15d\npopulation: 23 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 a317 f0b8 efbb | 134 93f8 (0) 92d5 (0) 9108 (0) 910d (0)\n001 2 60bc 6923 | 50 581a (0) 5a67 (0) 5b30 (0) 5e3e (0)\n002 4 38d7 3085 2f1f 293f | 35 3ef6 (0) 3ff8 (0) 3d17 (0) 3c5a (0)\n003 7 11a0 14e4 1587 1dfd | 19 1254 (0) 10b1 (0) 11a0 (0) 1758 (0)\n004 1 0020 | 7 07a6 (0) 05a4 (0) 0536 (0) 0305 (0)\n005 3 0fa0 0d97 0ca9 | 7 0f65 (0) 0fa0 (0) 0daf (0) 0d97 (0)\n============ DEPTH: 6 ==========================================\n006 3 0a3f 0ad6 0bc3 | 3 0ad6 (0) 0a3f (0) 0bc3 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"60725e8d0e9333636e598dd666f459b4be898d9abc095ee2c1db289673e7e969b50e2093956fef5a2f1d23e2040159bbabaaeab17fc6dbbac3f6acab766e9e60","private_key":"65ded6c2ad477ee077e81c1aa90fba5d4e0d794ea8dd5241a1545869c895185e","name":"node_60725e8d0e9333636e598dd666f459b4be898d9abc095ee2c1db289673e7e969b50e2093956fef5a2f1d23e2040159bbabaaeab17fc6dbbac3f6acab766e9e60","services":["streamer"],"enable_msg_events":true,"port":63429},"up":true}},{"node":{"info":{"id":"48a5e01e06e297dc1c640ac9601171495bd70fea461c60e7e6e2532695e45fcf68183c2e58b5e6931a6c1c094f5331efbd7f2d93d5f84efdec5a35afa2124438","name":"node_48a5e01e06e297dc1c640ac9601171495bd70fea461c60e7e6e2532695e45fcf68183c2e58b5e6931a6c1c094f5331efbd7f2d93d5f84efdec5a35afa2124438","enode":"enode://48a5e01e06e297dc1c640ac9601171495bd70fea461c60e7e6e2532695e45fcf68183c2e58b5e6931a6c1c094f5331efbd7f2d93d5f84efdec5a35afa2124438@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"77s907D7Pa9KinCR1ADYNP2VMs4MPb67YNORVZ1krLE=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: efbb3d\npopulation: 26 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 48df 09d1 293f | 122 581a (0) 5a67 (0) 5b30 (0) 5e3e (0)\n001 4 a478 a317 bb31 8d85 | 63 92d5 (0) 93f8 (0) 9108 (0) 910d (0)\n002 1 d0b7 | 33 c95a (0) c911 (0) c914 (0) cbd3 (0)\n003 3 f1ad f054 f0b8 | 13 f97e (0) ffb7 (0) fd44 (0) fd3f (0)\n004 4 e6b7 e5d2 e406 e31e | 13 e190 (0) e255 (0) e3d8 (0) e31e (0)\n005 4 ebe8 ebc9 e850 e9fa | 4 e9fa (0) e850 (0) ebe8 (0) ebc9 (0)\n006 2 ec78 ecff | 2 ec78 (0) ecff (0)\n007 3 ee52 ee3f eee1 | 3 ee52 (0) ee3f (0) eee1 (0)\n008 0 | 0\n============ DEPTH: 9 ==========================================\n009 2 efc1 efdd | 2 efc1 (0) efdd (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"48a5e01e06e297dc1c640ac9601171495bd70fea461c60e7e6e2532695e45fcf68183c2e58b5e6931a6c1c094f5331efbd7f2d93d5f84efdec5a35afa2124438","private_key":"9e522b8e7f94aa50d51d7ac396a12701677f86d0f9ad7111b329ba8229880db1","name":"node_48a5e01e06e297dc1c640ac9601171495bd70fea461c60e7e6e2532695e45fcf68183c2e58b5e6931a6c1c094f5331efbd7f2d93d5f84efdec5a35afa2124438","services":["streamer"],"enable_msg_events":true,"port":63430},"up":true}},{"node":{"info":{"id":"5dc69635f6d573c824ea83b18593a47f9f21a6f91ce18d2bf977c97d21f8d2a8ce88829244d12a07d949bbd52fe8a2035bc89685fe1bdd4ee20d766d75d3deee","name":"node_5dc69635f6d573c824ea83b18593a47f9f21a6f91ce18d2bf977c97d21f8d2a8ce88829244d12a07d949bbd52fe8a2035bc89685fe1bdd4ee20d766d75d3deee","enode":"enode://5dc69635f6d573c824ea83b18593a47f9f21a6f91ce18d2bf977c97d21f8d2a8ce88829244d12a07d949bbd52fe8a2035bc89685fe1bdd4ee20d766d75d3deee@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"KT9uQH+YziQJDl7VP+YGu7Jytho+7DhZID6lTRaZHog=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 293f6e\npopulation: 28 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 6 8d85 a75d f0b8 efbb | 134 af8f (0) ac62 (0) aa78 (0) a9df (0)\n001 5 60bc 6923 5062 42d6 | 50 77bc (0) 76a5 (0) 715b (0) 71bf (0)\n002 3 1daa 1fab 09d1 | 37 1254 (0) 10b1 (0) 11a0 (0) 167b (0)\n003 3 3d17 38d7 3085 | 20 3734 (0) 3799 (0) 3658 (0) 3607 (0)\n004 3 24f8 2220 2224 | 5 208e (0) 2220 (0) 2224 (0) 2737 (0)\n005 6 2cab 2c16 2c4e 2e3b | 7 2cb1 (0) 2cab (0) 2c4e (0) 2c16 (0)\n============ DEPTH: 6 ==========================================\n006 1 2a7d | 1 2a7d (0)\n007 0 | 0\n008 0 | 0\n009 1 2940 | 1 2940 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"5dc69635f6d573c824ea83b18593a47f9f21a6f91ce18d2bf977c97d21f8d2a8ce88829244d12a07d949bbd52fe8a2035bc89685fe1bdd4ee20d766d75d3deee","private_key":"2325b0e86e0abaef149e6063ff789995d1f6d863de595a5abcebffdad494ebb9","name":"node_5dc69635f6d573c824ea83b18593a47f9f21a6f91ce18d2bf977c97d21f8d2a8ce88829244d12a07d949bbd52fe8a2035bc89685fe1bdd4ee20d766d75d3deee","services":["streamer"],"enable_msg_events":true,"port":63431},"up":true}},{"node":{"info":{"id":"ae4e21e1587a8475afd299e00ca7085c7bf2a44c2c64a3068f12223d9202b0125094385319034691ec26b497ec9cf18fe8c0839224bac1b84279410241cef979","name":"node_ae4e21e1587a8475afd299e00ca7085c7bf2a44c2c64a3068f12223d9202b0125094385319034691ec26b497ec9cf18fe8c0839224bac1b84279410241cef979","enode":"enode://ae4e21e1587a8475afd299e00ca7085c7bf2a44c2c64a3068f12223d9202b0125094385319034691ec26b497ec9cf18fe8c0839224bac1b84279410241cef979@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"0LdugmpurqvcBgoFiL0b7MGQG2Co606K2+YRB4g6KYc=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: d0b76e\npopulation: 20 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 48df 293f | 122 7e45 (0) 7ec4 (0) 7810 (0) 7aef (0)\n001 2 8d85 ac62 | 63 af8f (0) ac62 (0) aa78 (0) a9df (0)\n002 6 efbb fc88 ffb7 f1ad | 38 e724 (0) e6b7 (0) e4e9 (0) e4d6 (0)\n003 3 c7fa c301 ce71 | 14 c95a (0) c914 (0) c911 (0) cbd3 (0)\n004 2 df52 d96e | 5 de1d (0) df52 (0) dad3 (0) d90b (0)\n005 1 d777 | 7 d455 (0) d560 (0) d606 (0) d66f (0)\n006 1 d3bd | 3 d2ac (0) d35c (0) d3bd (0)\n007 1 d1bc | 1 d1bc (0)\n============ DEPTH: 8 ==========================================\n008 2 d07c d044 | 2 d07c (0) d044 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"ae4e21e1587a8475afd299e00ca7085c7bf2a44c2c64a3068f12223d9202b0125094385319034691ec26b497ec9cf18fe8c0839224bac1b84279410241cef979","private_key":"dbdf629720f7cd6d4a8e26a5bb6da882212d6cbf43ddcda4712539c3db89bbf5","name":"node_ae4e21e1587a8475afd299e00ca7085c7bf2a44c2c64a3068f12223d9202b0125094385319034691ec26b497ec9cf18fe8c0839224bac1b84279410241cef979","services":["streamer"],"enable_msg_events":true,"port":63432},"up":true}},{"node":{"info":{"id":"0b30b36e155db04c448b662c4df695068b2331cdbe2772aae5fda84159e977515a5ff2e156bc225a9281fef2383926ba8cb11e9c1846fb40db241e524ac14e29","name":"node_0b30b36e155db04c448b662c4df695068b2331cdbe2772aae5fda84159e977515a5ff2e156bc225a9281fef2383926ba8cb11e9c1846fb40db241e524ac14e29","enode":"enode://0b30b36e155db04c448b662c4df695068b2331cdbe2772aae5fda84159e977515a5ff2e156bc225a9281fef2383926ba8cb11e9c1846fb40db241e524ac14e29@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"8LgD3P7Inh1oc5ygXPDJwE6AorHNR0lqgxaKcRhP1M8=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: f0b803\npopulation: 19 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 09d1 293f 48df | 122 1254 (0) 10b1 (0) 11a0 (0) 167b (0)\n001 2 8d85 bb31 | 63 af8f (0) ac62 (0) aa78 (0) a9df (0)\n002 2 d3bd d0b7 | 33 c914 (0) c911 (0) c95a (0) cbd3 (0)\n003 3 e6b7 ebc9 efbb | 25 e190 (0) e255 (0) e3d8 (0) e31e (0)\n004 4 fc88 fd44 ffb7 f97e | 5 f97e (0) ffb7 (0) fd44 (0) fd3f (0)\n005 1 f6a6 | 1 f6a6 (0)\n006 1 f2b2 | 3 f2f5 (0) f293 (0) f2b2 (0)\n============ DEPTH: 7 ==========================================\n007 2 f1b9 f1ad | 2 f1b9 (0) f1ad (0)\n008 1 f054 | 1 f054 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"0b30b36e155db04c448b662c4df695068b2331cdbe2772aae5fda84159e977515a5ff2e156bc225a9281fef2383926ba8cb11e9c1846fb40db241e524ac14e29","private_key":"315e74a348a3f8e172319c29da33577435f6415466e8cc289af2dc7e142987d7","name":"node_0b30b36e155db04c448b662c4df695068b2331cdbe2772aae5fda84159e977515a5ff2e156bc225a9281fef2383926ba8cb11e9c1846fb40db241e524ac14e29","services":["streamer"],"enable_msg_events":true,"port":63433},"up":true}},{"node":{"info":{"id":"17a79cb279306b6bbd35219278f6bba03111079d6c4fadcd3c5e57b09678e111bda5f8e36ca3d223e51e255d6e857363b7741e438b32ec6e6c0dc1b224071081","name":"node_17a79cb279306b6bbd35219278f6bba03111079d6c4fadcd3c5e57b09678e111bda5f8e36ca3d223e51e255d6e857363b7741e438b32ec6e6c0dc1b224071081","enode":"enode://17a79cb279306b6bbd35219278f6bba03111079d6c4fadcd3c5e57b09678e111bda5f8e36ca3d223e51e255d6e857363b7741e438b32ec6e6c0dc1b224071081@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"SN9pMUpXpqsvwxEIEEquIkKtKpQdL4cRmhUSUDRK7gI=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 48df69\npopulation: 20 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 5 8d85 a317 d0b7 efbb | 134 b049 (0) b30e (0) b391 (0) b40d (0)\n001 2 2f1f 293f | 72 1254 (0) 10b1 (0) 11a0 (0) 167b (0)\n002 2 60bc 6923 | 19 7e45 (0) 7ec4 (0) 7810 (0) 7aef (0)\n003 2 5c9b 5062 | 15 581a (0) 5a67 (0) 5b30 (0) 5e3e (0)\n004 2 42d6 47a8 | 8 44c8 (0) 44b7 (0) 464b (0) 47a8 (0)\n005 2 4dc4 4c97 | 2 4dc4 (0) 4c97 (0)\n============ DEPTH: 6 ==========================================\n006 4 4bf8 4bbc 4b8a 4b70 | 4 4bf8 (0) 4b8a (0) 4bbc (0) 4b70 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 1 48ec | 1 48ec (0)\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"17a79cb279306b6bbd35219278f6bba03111079d6c4fadcd3c5e57b09678e111bda5f8e36ca3d223e51e255d6e857363b7741e438b32ec6e6c0dc1b224071081","private_key":"510061145b0b868f1fb7e83b850d0901227724f4559e912c0561ac310308ea80","name":"node_17a79cb279306b6bbd35219278f6bba03111079d6c4fadcd3c5e57b09678e111bda5f8e36ca3d223e51e255d6e857363b7741e438b32ec6e6c0dc1b224071081","services":["streamer"],"enable_msg_events":true,"port":63434},"up":true}},{"node":{"info":{"id":"617595a230e0a74a3db3b47cd27b941e02bdee9a84cdfa8eaa63a55941eb5caa79e20fb69726a4d46a0e5aeed24039f8c5a20679a692df0bc140f42558ca9a2b","name":"node_617595a230e0a74a3db3b47cd27b941e02bdee9a84cdfa8eaa63a55941eb5caa79e20fb69726a4d46a0e5aeed24039f8c5a20679a692df0bc140f42558ca9a2b","enode":"enode://617595a230e0a74a3db3b47cd27b941e02bdee9a84cdfa8eaa63a55941eb5caa79e20fb69726a4d46a0e5aeed24039f8c5a20679a692df0bc140f42558ca9a2b@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"jYU+yki+JXt0RDJ9Yc9YghjaccaIvphH7pmH1U6u0as=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 8d853e\npopulation: 26 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 48df 2f1f 293f | 122 7aef (0) 7810 (0) 7ec4 (0) 7e45 (0)\n001 5 d0b7 d3bd f1ad f0b8 | 71 ca8c (0) caa3 (0) cbd3 (0) cba4 (0)\n002 6 bb31 b820 a75d a478 | 30 af8f (0) ac62 (0) a9df (0) a936 (0)\n003 1 9929 | 18 93f8 (0) 92d5 (0) 9108 (0) 910d (0)\n004 5 86d3 8611 83d0 802e | 8 8611 (0) 86d3 (0) 8434 (0) 853b (0)\n005 3 8a54 8ae8 89ef | 3 89ef (0) 8ae8 (0) 8a54 (0)\n============ DEPTH: 6 ==========================================\n006 2 8ee7 8ea9 | 2 8ea9 (0) 8ee7 (0)\n007 0 | 0\n008 1 8d3c | 1 8d3c (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"617595a230e0a74a3db3b47cd27b941e02bdee9a84cdfa8eaa63a55941eb5caa79e20fb69726a4d46a0e5aeed24039f8c5a20679a692df0bc140f42558ca9a2b","private_key":"b4c3b4d3b3fb735ed7f1b4dbfa53fb08ca505f7570d376ca8ff9ba10c108fea8","name":"node_617595a230e0a74a3db3b47cd27b941e02bdee9a84cdfa8eaa63a55941eb5caa79e20fb69726a4d46a0e5aeed24039f8c5a20679a692df0bc140f42558ca9a2b","services":["streamer"],"enable_msg_events":true,"port":63435},"up":true}},{"node":{"info":{"id":"7808fb798d22e78fb1d39b87ddf99a503f820993bc64149eca9e81d9d58fc1adea60d8de14a4f06cb89f3190c0ef0c5e182621a14c9361ccb7e0cee667599cc3","name":"node_7808fb798d22e78fb1d39b87ddf99a503f820993bc64149eca9e81d9d58fc1adea60d8de14a4f06cb89f3190c0ef0c5e182621a14c9361ccb7e0cee667599cc3","enode":"enode://7808fb798d22e78fb1d39b87ddf99a503f820993bc64149eca9e81d9d58fc1adea60d8de14a4f06cb89f3190c0ef0c5e182621a14c9361ccb7e0cee667599cc3@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"Lx8sTCW5f82PvnlQbnSLfA31s7wVuIRwHfEn5JVIhE4=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 2f1f2c\npopulation: 27 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 d3bd 8d85 bb31 a478 | 134 c95a (0) c911 (0) c914 (0) cba4 (0)\n001 5 60bc 6923 42d6 48df | 50 7ec4 (0) 7e45 (0) 7810 (0) 7aef (0)\n002 4 14e4 1daa 1fab 09d1 | 37 1254 (0) 10b1 (0) 11a0 (0) 167b (0)\n003 4 38d7 3658 3734 3799 | 20 3799 (0) 3734 (0) 3658 (0) 3607 (0)\n004 3 24f8 208e 2224 | 5 208e (0) 2220 (0) 2224 (0) 2737 (0)\n005 1 293f | 3 2a7d (0) 2940 (0) 293f (0)\n006 4 2cab 2cb1 2c16 2c4e | 4 2cab (0) 2cb1 (0) 2c4e (0) 2c16 (0)\n============ DEPTH: 7 ==========================================\n007 1 2e3b | 1 2e3b (0)\n008 0 | 0\n009 0 | 0\n010 1 2f23 | 1 2f23 (0)\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"7808fb798d22e78fb1d39b87ddf99a503f820993bc64149eca9e81d9d58fc1adea60d8de14a4f06cb89f3190c0ef0c5e182621a14c9361ccb7e0cee667599cc3","private_key":"0ceaf25d118fd30dfa73bfe157c4bfdbdd7bcdc44e699e71e2e397eff0988045","name":"node_7808fb798d22e78fb1d39b87ddf99a503f820993bc64149eca9e81d9d58fc1adea60d8de14a4f06cb89f3190c0ef0c5e182621a14c9361ccb7e0cee667599cc3","services":["streamer"],"enable_msg_events":true,"port":63436},"up":true}},{"node":{"info":{"id":"f039df8a3206e6e17eee8e95010038c450cb4cc0b5580ed5795d4c21802e1e9d360f4528bdca794f457932b1d6a818862ec847357a861c488332ef6d9480daa6","name":"node_f039df8a3206e6e17eee8e95010038c450cb4cc0b5580ed5795d4c21802e1e9d360f4528bdca794f457932b1d6a818862ec847357a861c488332ef6d9480daa6","enode":"enode://f039df8a3206e6e17eee8e95010038c450cb4cc0b5580ed5795d4c21802e1e9d360f4528bdca794f457932b1d6a818862ec847357a861c488332ef6d9480daa6@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"UGLXSHb99CWo5XbtXlbZcZouUG9FIZ/BDEjtRNLwNgs=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 5062d7\npopulation: 23 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 5 802e b820 a75d a478 | 134 9493 (0) 9404 (0) 9641 (0) 9747 (0)\n001 3 1fab 293f 2f1f | 72 1254 (0) 10b1 (0) 11a0 (0) 167b (0)\n002 2 60bc 6923 | 19 77bc (0) 76a5 (0) 715b (0) 71bf (0)\n003 5 43fb 42d6 4c97 4b70 | 16 44c8 (0) 44b7 (0) 464b (0) 47a8 (0)\n004 3 5c9b 5a67 581a | 6 581a (0) 5a67 (0) 5b30 (0) 5e3e (0)\n005 1 56bb | 4 57ee (0) 5765 (0) 5741 (0) 56bb (0)\n006 2 5237 5399 | 2 5237 (0) 5399 (0)\n============ DEPTH: 7 ==========================================\n007 1 510c | 1 510c (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 1 5070 | 1 5070 (0)\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"f039df8a3206e6e17eee8e95010038c450cb4cc0b5580ed5795d4c21802e1e9d360f4528bdca794f457932b1d6a818862ec847357a861c488332ef6d9480daa6","private_key":"b8dcd04f9dd7c7d9522112f1d10c32738ce2283cb755c14b83b3e7d8d645c4f1","name":"node_f039df8a3206e6e17eee8e95010038c450cb4cc0b5580ed5795d4c21802e1e9d360f4528bdca794f457932b1d6a818862ec847357a861c488332ef6d9480daa6","services":["streamer"],"enable_msg_events":true,"port":63437},"up":true}},{"node":{"info":{"id":"ce0a09bb6fe4c9c93c3dbd800ca9c9ac0714f26a8f8dac2149b6ce7a9011912a5621ea2e45de35c4d31dfe5add00558fdba5dd21acf2d81ba391e82b5b3a5804","name":"node_ce0a09bb6fe4c9c93c3dbd800ca9c9ac0714f26a8f8dac2149b6ce7a9011912a5621ea2e45de35c4d31dfe5add00558fdba5dd21acf2d81ba391e82b5b3a5804","enode":"enode://ce0a09bb6fe4c9c93c3dbd800ca9c9ac0714f26a8f8dac2149b6ce7a9011912a5621ea2e45de35c4d31dfe5add00558fdba5dd21acf2d81ba391e82b5b3a5804@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"0712+bF4s04Kl70BMMYajfogl/y8Zn9uT063cidCVpM=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: d3bd76\npopulation: 32 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 293f 2f1f 5062 6923 | 122 00c8 (0) 0020 (0) 0305 (0) 020f (0)\n001 6 802e 8d85 8ee7 a75d | 63 93f8 (0) 92d5 (0) 9108 (0) 910d (0)\n002 6 ebc9 e6b7 fc88 f0b8 | 38 f97e (0) ffb7 (0) fd44 (0) fd3f (0)\n003 3 c301 c7fa ce71 | 14 c3d8 (0) c301 (0) c409 (0) c60e (0)\n004 2 de1d d96e | 5 de1d (0) df52 (0) dad3 (0) d90b (0)\n005 5 d455 d560 d606 d7c1 | 7 d560 (0) d455 (0) d66f (0) d606 (0)\n006 4 d1bc d07c d044 d0b7 | 4 d1bc (0) d044 (0) d07c (0) d0b7 (0)\n============ DEPTH: 7 ==========================================\n007 1 d2ac | 1 d2ac (0)\n008 1 d35c | 1 d35c (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"ce0a09bb6fe4c9c93c3dbd800ca9c9ac0714f26a8f8dac2149b6ce7a9011912a5621ea2e45de35c4d31dfe5add00558fdba5dd21acf2d81ba391e82b5b3a5804","private_key":"e0f1d278d1346984b7b19789e39ae0ee607d17f0fc7538e8dc8537b44c09e142","name":"node_ce0a09bb6fe4c9c93c3dbd800ca9c9ac0714f26a8f8dac2149b6ce7a9011912a5621ea2e45de35c4d31dfe5add00558fdba5dd21acf2d81ba391e82b5b3a5804","services":["streamer"],"enable_msg_events":true,"port":63438},"up":true}},{"node":{"info":{"id":"b2538d4edfa736bfe2cc21326a44ce62f716b3480eac93584a2233b69c98883a2bb255f246218a58cecab1d0d176e6d1fbba9782fd70d4603e01742299b9ea9c","name":"node_b2538d4edfa736bfe2cc21326a44ce62f716b3480eac93584a2233b69c98883a2bb255f246218a58cecab1d0d176e6d1fbba9782fd70d4603e01742299b9ea9c","enode":"enode://b2538d4edfa736bfe2cc21326a44ce62f716b3480eac93584a2233b69c98883a2bb255f246218a58cecab1d0d176e6d1fbba9782fd70d4603e01742299b9ea9c@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"aSPXhADyd/4pw1ujikFu3XyWDMddlMNao0RrTV4vbDs=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 6923d7\npopulation: 17 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 a1f1 b820 d3bd | 134 9641 (0) 9747 (0) 9493 (0) 9404 (0)\n001 3 09d1 2f1f 293f | 72 1254 (0) 10b1 (0) 11a0 (0) 167b (0)\n002 6 4c97 4b70 48df 5c9b | 31 44b7 (0) 44c8 (0) 47a8 (0) 464b (0)\n003 1 7299 | 10 7ec4 (0) 7e45 (0) 7810 (0) 7aef (0)\n004 1 60bc | 5 6701 (0) 67ee (0) 65a6 (0) 63de (0)\n============ DEPTH: 5 ==========================================\n005 2 6caa 6f1c | 2 6caa (0) 6f1c (0)\n006 0 | 0\n007 0 | 0\n008 1 69d8 | 1 69d8 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"b2538d4edfa736bfe2cc21326a44ce62f716b3480eac93584a2233b69c98883a2bb255f246218a58cecab1d0d176e6d1fbba9782fd70d4603e01742299b9ea9c","private_key":"6c9376463118cd8a2c68423af478150a6e0a1b811b922aa7d35974ec65943ad1","name":"node_b2538d4edfa736bfe2cc21326a44ce62f716b3480eac93584a2233b69c98883a2bb255f246218a58cecab1d0d176e6d1fbba9782fd70d4603e01742299b9ea9c","services":["streamer"],"enable_msg_events":true,"port":63439},"up":true}},{"node":{"info":{"id":"aa9a94d6e4eaaed20113c21752c224e3a052abd3769bd6e832759dbaf5154a943cf094eacdcb0727c2fe51a11bd7fc0793d7d5e3312b0aba89d428a00e1fde0c","name":"node_aa9a94d6e4eaaed20113c21752c224e3a052abd3769bd6e832759dbaf5154a943cf094eacdcb0727c2fe51a11bd7fc0793d7d5e3312b0aba89d428a00e1fde0c","enode":"enode://aa9a94d6e4eaaed20113c21752c224e3a052abd3769bd6e832759dbaf5154a943cf094eacdcb0727c2fe51a11bd7fc0793d7d5e3312b0aba89d428a00e1fde0c@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"uCCzGKOhKnp/RdBv/39dfjyiyoCXw5bB12xzXhyRXMA=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: b820b3\npopulation: 19 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 5062 6923 | 122 0305 (0) 020f (0) 00c8 (0) 0020 (0)\n001 1 d3bd | 71 f97e (0) ffb7 (0) fd3f (0) fd44 (0)\n002 4 8d85 8ee7 8434 802e | 33 92d5 (0) 93f8 (0) 9108 (0) 910d (0)\n003 4 a478 a75d a6bd a1f1 | 17 af8f (0) ac62 (0) aa78 (0) a9df (0)\n004 3 b391 b45f b7aa | 6 b30e (0) b391 (0) b049 (0) b40d (0)\n005 2 bd39 bf6b | 3 bd39 (0) beb7 (0) bf6b (0)\n============ DEPTH: 6 ==========================================\n006 3 baaf bbcb bb31 | 3 baaf (0) bbcb (0) bb31 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"aa9a94d6e4eaaed20113c21752c224e3a052abd3769bd6e832759dbaf5154a943cf094eacdcb0727c2fe51a11bd7fc0793d7d5e3312b0aba89d428a00e1fde0c","private_key":"d391fbaa56954f68499674edef05d07d58c5512ae18166b141c961a4dea175fa","name":"node_aa9a94d6e4eaaed20113c21752c224e3a052abd3769bd6e832759dbaf5154a943cf094eacdcb0727c2fe51a11bd7fc0793d7d5e3312b0aba89d428a00e1fde0c","services":["streamer"],"enable_msg_events":true,"port":63440},"up":true}},{"node":{"info":{"id":"65e954e60837bda10654480b227fa3bcc6e63356c52079002a27e836cd82ae2934ba77da60080e4b9f2d9324b982b24959bfd9624302e6c330408381054b43e9","name":"node_65e954e60837bda10654480b227fa3bcc6e63356c52079002a27e836cd82ae2934ba77da60080e4b9f2d9324b982b24959bfd9624302e6c330408381054b43e9","enode":"enode://65e954e60837bda10654480b227fa3bcc6e63356c52079002a27e836cd82ae2934ba77da60080e4b9f2d9324b982b24959bfd9624302e6c330408381054b43e9@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"pHj1yqiuRB2Okz9jb/bBFmdTwLRDdC4gQ0YZBEqFCB0=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: a478f5\npopulation: 27 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 5 5c9b 5062 1daa 1fab | 122 07a6 (0) 05a4 (0) 0536 (0) 020f (0)\n001 3 e850 efbb d3bd | 71 e190 (0) e255 (0) e3d8 (0) e31e (0)\n002 4 802e 8ee7 8d85 9404 | 33 93f8 (0) 92d5 (0) 9108 (0) 910d (0)\n003 2 b820 b45f | 13 b391 (0) b30e (0) b049 (0) b40d (0)\n004 2 a936 a9df | 5 ac62 (0) af8f (0) aa78 (0) a936 (0)\n005 9 a3f2 a317 a077 a011 | 9 a3f2 (0) a317 (0) a0c9 (0) a0e4 (0)\n============ DEPTH: 6 ==========================================\n006 2 a6bd a75d | 2 a6bd (0) a75d (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"65e954e60837bda10654480b227fa3bcc6e63356c52079002a27e836cd82ae2934ba77da60080e4b9f2d9324b982b24959bfd9624302e6c330408381054b43e9","private_key":"199542f222419c9f399da0655278169815321c4420c8e39a377faf1446b6da1f","name":"node_65e954e60837bda10654480b227fa3bcc6e63356c52079002a27e836cd82ae2934ba77da60080e4b9f2d9324b982b24959bfd9624302e6c330408381054b43e9","services":["streamer"],"enable_msg_events":true,"port":63441},"up":true}},{"node":{"info":{"id":"8ca3b63cb84f1e9883d82809a9b6777ec1029ecda96fe93b4d494ee9cbefcad13f381b3e480136e542e01054fe1ede66c65db84a0009871ce49383db461c8438","name":"node_8ca3b63cb84f1e9883d82809a9b6777ec1029ecda96fe93b4d494ee9cbefcad13f381b3e480136e542e01054fe1ede66c65db84a0009871ce49383db461c8438","enode":"enode://8ca3b63cb84f1e9883d82809a9b6777ec1029ecda96fe93b4d494ee9cbefcad13f381b3e480136e542e01054fe1ede66c65db84a0009871ce49383db461c8438@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"p13Trwgj550zb3h2K40S5VQpc282PlQMLJmot7vFNdY=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: a75dd3\npopulation: 32 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 7 5062 5c9b 71bf 1daa | 122 7e45 (0) 7ec4 (0) 7810 (0) 7aef (0)\n001 3 d3bd e469 e406 | 71 e469 (0) e406 (0) e4d6 (0) e4e9 (0)\n002 4 8ee7 8d85 802e 9404 | 33 9f4c (0) 9b87 (0) 9bc3 (0) 9a09 (0)\n003 5 bf6b bb31 b820 b45f | 13 bd39 (0) beb7 (0) bf6b (0) baaf (0)\n004 2 a936 aa78 | 5 af8f (0) ac62 (0) aa78 (0) a9df (0)\n005 9 a3f2 a317 a0e4 a0c9 | 9 a3f2 (0) a317 (0) a0c9 (0) a0e4 (0)\n============ DEPTH: 6 ==========================================\n006 1 a478 | 1 a478 (0)\n007 1 a6bd | 1 a6bd (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"8ca3b63cb84f1e9883d82809a9b6777ec1029ecda96fe93b4d494ee9cbefcad13f381b3e480136e542e01054fe1ede66c65db84a0009871ce49383db461c8438","private_key":"ff50f9bc8f6ce42cff12b697c1d4880461773518aaf5f25e5c8a03a8af128fa5","name":"node_8ca3b63cb84f1e9883d82809a9b6777ec1029ecda96fe93b4d494ee9cbefcad13f381b3e480136e542e01054fe1ede66c65db84a0009871ce49383db461c8438","services":["streamer"],"enable_msg_events":true,"port":63442},"up":true}},{"node":{"info":{"id":"caaf695c76cf7c047d3f3bfe019d01618e4871cee8ff3f347913da815bbcde145771486f916a44d03f59ea9bc217f169fd0c0765fda3f9b9b28d02a522e180b4","name":"node_caaf695c76cf7c047d3f3bfe019d01618e4871cee8ff3f347913da815bbcde145771486f916a44d03f59ea9bc217f169fd0c0765fda3f9b9b28d02a522e180b4","enode":"enode://caaf695c76cf7c047d3f3bfe019d01618e4871cee8ff3f347913da815bbcde145771486f916a44d03f59ea9bc217f169fd0c0765fda3f9b9b28d02a522e180b4@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"gC6fpSTxpqJ/3Ov38lqyilwENDm3hEsfw02oJCtgF6A=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 802e9f\npopulation: 22 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 5062 1fab | 122 7ec4 (0) 7e45 (0) 7810 (0) 7aef (0)\n001 1 d3bd | 71 e255 (0) e31e (0) e3d8 (0) e190 (0)\n002 5 b7aa b820 a478 a75d | 30 bd39 (0) beb7 (0) bf6b (0) baaf (0)\n003 3 9747 98aa 9929 | 18 92d5 (0) 93f8 (0) 9108 (0) 910d (0)\n004 4 8a54 8d85 8d3c 8ee7 | 7 89ef (0) 8ae8 (0) 8a54 (0) 8d3c (0)\n005 5 8611 86d3 8434 853b | 5 8611 (0) 86d3 (0) 8434 (0) 853b (0)\n============ DEPTH: 6 ==========================================\n006 1 83d0 | 1 83d0 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 1 802f | 1 802f (0)\n========================================================================="}},"config":{"id":"caaf695c76cf7c047d3f3bfe019d01618e4871cee8ff3f347913da815bbcde145771486f916a44d03f59ea9bc217f169fd0c0765fda3f9b9b28d02a522e180b4","private_key":"2c15cd49d4a7fc8bf1acbb4f86987efe85c77ba2712f82531bf893084ef4654a","name":"node_caaf695c76cf7c047d3f3bfe019d01618e4871cee8ff3f347913da815bbcde145771486f916a44d03f59ea9bc217f169fd0c0765fda3f9b9b28d02a522e180b4","services":["streamer"],"enable_msg_events":true,"port":63443},"up":true}},{"node":{"info":{"id":"b080891d4ba6d3ab224984360597f9c555bd1367630f5420bfaf230419a05b2be58bebf1554e53eb4c0da81cfb66d4f7697dd65143f11841ff62d8a0d82b6b67","name":"node_b080891d4ba6d3ab224984360597f9c555bd1367630f5420bfaf230419a05b2be58bebf1554e53eb4c0da81cfb66d4f7697dd65143f11841ff62d8a0d82b6b67","enode":"enode://b080891d4ba6d3ab224984360597f9c555bd1367630f5420bfaf230419a05b2be58bebf1554e53eb4c0da81cfb66d4f7697dd65143f11841ff62d8a0d82b6b67@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"H6vKGBr/9ZvaFzuN44sEFp+bKZiAv3JnT9yKvR9Ubpw=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 1fabca\npopulation: 25 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 a478 802e | 134 e850 (0) e9fa (0) ebe8 (0) ebc9 (0)\n001 6 715b 4c97 42d6 510c | 50 7ec4 (0) 7e45 (0) 7810 (0) 7aef (0)\n002 4 38d7 293f 2e3b 2f1f | 35 208e (0) 2220 (0) 2224 (0) 2737 (0)\n003 1 09d1 | 18 07a6 (0) 05a4 (0) 0536 (0) 00c8 (0)\n004 3 1758 15ec 14e4 | 9 1254 (0) 10b1 (0) 11a0 (0) 167b (0)\n005 4 1a8e 1a85 1af6 1953 | 4 1953 (0) 1af6 (0) 1a85 (0) 1a8e (0)\n============ DEPTH: 6 ==========================================\n006 4 1d5b 1dfd 1dfc 1daa | 4 1d5b (0) 1dfd (0) 1dfc (0) 1daa (0)\n007 1 1ea1 | 1 1ea1 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"b080891d4ba6d3ab224984360597f9c555bd1367630f5420bfaf230419a05b2be58bebf1554e53eb4c0da81cfb66d4f7697dd65143f11841ff62d8a0d82b6b67","private_key":"4c9c04de05a7a437923df855213efcc8c9489ba08352e267097b6bca9e840fba","name":"node_b080891d4ba6d3ab224984360597f9c555bd1367630f5420bfaf230419a05b2be58bebf1554e53eb4c0da81cfb66d4f7697dd65143f11841ff62d8a0d82b6b67","services":["streamer"],"enable_msg_events":true,"port":63444},"up":true}},{"node":{"info":{"id":"2ca05ffc0ad771e1e045a47f1c0a79ce374a25e3c0e53c2a80d67e7479677003f62880251a83a5074f1c9651d828f1ff7e352935a9df141c1eb75a0c59b00a8b","name":"node_2ca05ffc0ad771e1e045a47f1c0a79ce374a25e3c0e53c2a80d67e7479677003f62880251a83a5074f1c9651d828f1ff7e352935a9df141c1eb75a0c59b00a8b","enode":"enode://2ca05ffc0ad771e1e045a47f1c0a79ce374a25e3c0e53c2a80d67e7479677003f62880251a83a5074f1c9651d828f1ff7e352935a9df141c1eb75a0c59b00a8b@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"HaorJT3JWje8nSOOGscb4hPW9yWzu7hMXJP1EuLuUBo=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 1daa2b\npopulation: 23 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 5 a478 a75d 8ee7 ecff | 134 ebc9 (0) ebe8 (0) e9fa (0) e850 (0)\n001 4 42d6 4dc4 4c97 5c9b | 50 69d8 (0) 6923 (0) 6caa (0) 6f1c (0)\n002 4 38d7 2e3b 2f1f 293f | 35 208e (0) 2220 (0) 2224 (0) 2737 (0)\n003 2 09d1 0ca9 | 18 07a6 (0) 05a4 (0) 0536 (0) 00c8 (0)\n004 1 14e4 | 9 1254 (0) 10b1 (0) 11a0 (0) 167b (0)\n005 2 1953 1a85 | 4 1953 (0) 1af6 (0) 1a85 (0) 1a8e (0)\n006 2 1ea1 1fab | 2 1ea1 (0) 1fab (0)\n007 0 | 0\n008 1 1d5b | 1 1d5b (0)\n============ DEPTH: 9 ==========================================\n009 2 1dfd 1dfc | 2 1dfc (0) 1dfd (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"2ca05ffc0ad771e1e045a47f1c0a79ce374a25e3c0e53c2a80d67e7479677003f62880251a83a5074f1c9651d828f1ff7e352935a9df141c1eb75a0c59b00a8b","private_key":"5b756c056cbcd8e0a9a926f6ebf3360d7587152f836459cd22eafd76c3984af8","name":"node_2ca05ffc0ad771e1e045a47f1c0a79ce374a25e3c0e53c2a80d67e7479677003f62880251a83a5074f1c9651d828f1ff7e352935a9df141c1eb75a0c59b00a8b","services":["streamer"],"enable_msg_events":true,"port":63445},"up":true}},{"node":{"info":{"id":"8d4920d6e3a6717699b5a3af068cbdfc16858d7e393d158d41b1b5f345b47129eef89e1d055386c518f400b134678c21590f0317dea3436d4cef60f45455cf12","name":"node_8d4920d6e3a6717699b5a3af068cbdfc16858d7e393d158d41b1b5f345b47129eef89e1d055386c518f400b134678c21590f0317dea3436d4cef60f45455cf12","enode":"enode://8d4920d6e3a6717699b5a3af068cbdfc16858d7e393d158d41b1b5f345b47129eef89e1d055386c518f400b134678c21590f0317dea3436d4cef60f45455cf12@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"ONcH3P4anQnAO2Bt1NuJ5s7QBMEvYdi1c7XJ90L1Ers=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 38d707\npopulation: 27 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 8ee7 a75d e6b7 e31e | 134 e190 (0) e255 (0) e3d8 (0) e31e (0)\n001 7 5c9b 4c97 42d6 7239 | 50 7e45 (0) 7ec4 (0) 7810 (0) 7aef (0)\n002 3 09d1 1daa 1fab | 37 07a6 (0) 05a4 (0) 0536 (0) 00c8 (0)\n003 3 2f1f 2e3b 293f | 15 208e (0) 2220 (0) 2224 (0) 2737 (0)\n004 2 3734 3607 | 10 3799 (0) 3734 (0) 3658 (0) 3607 (0)\n005 3 3ff8 3c5a 3d17 | 4 3d17 (0) 3c5a (0) 3ef6 (0) 3ff8 (0)\n006 3 3baa 3a18 3ab2 | 3 3baa (0) 3a18 (0) 3ab2 (0)\n============ DEPTH: 7 ==========================================\n007 1 398b | 1 398b (0)\n008 1 3843 | 1 3843 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"8d4920d6e3a6717699b5a3af068cbdfc16858d7e393d158d41b1b5f345b47129eef89e1d055386c518f400b134678c21590f0317dea3436d4cef60f45455cf12","private_key":"fd26d9072de53e5f0a3d88d7c32e80650d289f661906c9837a7a0a003f3520ac","name":"node_8d4920d6e3a6717699b5a3af068cbdfc16858d7e393d158d41b1b5f345b47129eef89e1d055386c518f400b134678c21590f0317dea3436d4cef60f45455cf12","services":["streamer"],"enable_msg_events":true,"port":63446},"up":true}},{"node":{"info":{"id":"b6a998dea59194cc60ce97c7c9702368411889cb6905516b23f41cc5116fba8d0f237d418318eb0c333cad18003c0e9a6bd8c99080520771f2bad640e2e5ec1c","name":"node_b6a998dea59194cc60ce97c7c9702368411889cb6905516b23f41cc5116fba8d0f237d418318eb0c333cad18003c0e9a6bd8c99080520771f2bad640e2e5ec1c","enode":"enode://b6a998dea59194cc60ce97c7c9702368411889cb6905516b23f41cc5116fba8d0f237d418318eb0c333cad18003c0e9a6bd8c99080520771f2bad640e2e5ec1c@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"jufy1cNZvVw37APU4C74CEdo4S0JSnzSfLXe9nOLYcU=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 8ee7f2\npopulation: 26 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 1daa 38d7 2e3b 5c9b | 122 7810 (0) 7aef (0) 7ec4 (0) 7e45 (0)\n001 1 d3bd | 71 e190 (0) e255 (0) e3d8 (0) e31e (0)\n002 8 b45f b7aa bb31 bbcb | 30 bd39 (0) beb7 (0) bf6b (0) baaf (0)\n003 4 9747 9404 9929 98aa | 18 92d5 (0) 93f8 (0) 9108 (0) 910d (0)\n004 3 83d0 802f 802e | 8 8611 (0) 86d3 (0) 8434 (0) 8564 (0)\n005 3 89ef 8ae8 8a54 | 3 89ef (0) 8ae8 (0) 8a54 (0)\n============ DEPTH: 6 ==========================================\n006 2 8d85 8d3c | 2 8d85 (0) 8d3c (0)\n007 0 | 0\n008 0 | 0\n009 1 8ea9 | 1 8ea9 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"b6a998dea59194cc60ce97c7c9702368411889cb6905516b23f41cc5116fba8d0f237d418318eb0c333cad18003c0e9a6bd8c99080520771f2bad640e2e5ec1c","private_key":"3e2d345fa05f2ec2c8c4ae80fa808f0acaa098d08a2a0e7be1a2749f7d01f0e7","name":"node_b6a998dea59194cc60ce97c7c9702368411889cb6905516b23f41cc5116fba8d0f237d418318eb0c333cad18003c0e9a6bd8c99080520771f2bad640e2e5ec1c","services":["streamer"],"enable_msg_events":true,"port":63447},"up":true}},{"node":{"info":{"id":"ff6f94005d1df7677600069764855c1c2aa0543cbe9f480f8feefec76c49d9e2c7bb2d8e38c89e9430f53f8b593d93f143c45985a56a5a32c736128214c95eda","name":"node_ff6f94005d1df7677600069764855c1c2aa0543cbe9f480f8feefec76c49d9e2c7bb2d8e38c89e9430f53f8b593d93f143c45985a56a5a32c736128214c95eda","enode":"enode://ff6f94005d1df7677600069764855c1c2aa0543cbe9f480f8feefec76c49d9e2c7bb2d8e38c89e9430f53f8b593d93f143c45985a56a5a32c736128214c95eda@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"ofH1zgMTs/Y+wQ/VwZqpH8VjCf9ZngjhntFeQ8EVlQ4=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: a1f1f5\npopulation: 27 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 2e3b 6f1c 6923 60bc | 122 65a6 (0) 67ee (0) 6701 (0) 63de (0)\n001 2 c301 f054 | 71 c95a (0) c911 (0) c914 (0) caa3 (0)\n002 5 9404 83d0 802e 8d85 | 33 9f4c (0) 9b87 (0) 9bc3 (0) 9a09 (0)\n003 5 b820 bb31 bbcb b45f | 13 bd39 (0) beb7 (0) bf6b (0) b820 (0)\n004 2 a936 a9df | 5 ac62 (0) af8f (0) aa78 (0) a9df (0)\n005 2 a75d a478 | 3 a478 (0) a6bd (0) a75d (0)\n006 2 a317 a3f2 | 2 a3f2 (0) a317 (0)\n007 3 a0e4 a077 a011 | 4 a0c9 (0) a0e4 (0) a077 (0) a011 (0)\n============ DEPTH: 8 ==========================================\n008 1 a105 | 1 a105 (0)\n009 1 a1b6 | 1 a1b6 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"ff6f94005d1df7677600069764855c1c2aa0543cbe9f480f8feefec76c49d9e2c7bb2d8e38c89e9430f53f8b593d93f143c45985a56a5a32c736128214c95eda","private_key":"69afb2f43d398d53995f3880ed20e91b1d92307e4f7b40cc63a785ebe01f5e9c","name":"node_ff6f94005d1df7677600069764855c1c2aa0543cbe9f480f8feefec76c49d9e2c7bb2d8e38c89e9430f53f8b593d93f143c45985a56a5a32c736128214c95eda","services":["streamer"],"enable_msg_events":true,"port":63448},"up":true}},{"node":{"info":{"id":"315b8a1711f680c2eaa607e35ef7a9e19c2b61721af8a7e08f1325dde1fe33cf1f47b3cc4acf12d541631041cf1b42754875fd1c9b66ee32797b72b9f7711256","name":"node_315b8a1711f680c2eaa607e35ef7a9e19c2b61721af8a7e08f1325dde1fe33cf1f47b3cc4acf12d541631041cf1b42754875fd1c9b66ee32797b72b9f7711256","enode":"enode://315b8a1711f680c2eaa607e35ef7a9e19c2b61721af8a7e08f1325dde1fe33cf1f47b3cc4acf12d541631041cf1b42754875fd1c9b66ee32797b72b9f7711256@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"LjtPtimMNX0qTPzbL8wL4suuChEhnkysLQwB3jkl3VI=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 2e3b4f\npopulation: 30 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 5 8ee7 a1f1 a75d bbcb | 134 dad3 (0) d90b (0) d96e (0) de1d (0)\n001 4 510c 5c9b 42d6 4c97 | 50 7ec4 (0) 7e45 (0) 7810 (0) 7aef (0)\n002 5 1fab 1daa 020f 0020 | 37 07a6 (0) 05a4 (0) 0536 (0) 00c8 (0)\n003 4 38d7 3843 3baa 3ab2 | 20 3799 (0) 3734 (0) 3658 (0) 3607 (0)\n004 3 2220 2224 24f8 | 5 208e (0) 2220 (0) 2224 (0) 2737 (0)\n005 3 2a7d 293f 2940 | 3 2a7d (0) 2940 (0) 293f (0)\n006 4 2c16 2c4e 2cab 2cb1 | 4 2cb1 (0) 2cab (0) 2c4e (0) 2c16 (0)\n============ DEPTH: 7 ==========================================\n007 2 2f1f 2f23 | 2 2f23 (0) 2f1f (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"315b8a1711f680c2eaa607e35ef7a9e19c2b61721af8a7e08f1325dde1fe33cf1f47b3cc4acf12d541631041cf1b42754875fd1c9b66ee32797b72b9f7711256","private_key":"30cd694a144038e53930a6b5e32f95f2c9caa886829d241c282f385107d7b824","name":"node_315b8a1711f680c2eaa607e35ef7a9e19c2b61721af8a7e08f1325dde1fe33cf1f47b3cc4acf12d541631041cf1b42754875fd1c9b66ee32797b72b9f7711256","services":["streamer"],"enable_msg_events":true,"port":63449},"up":true}},{"node":{"info":{"id":"396c703d27bfdddf91761f134cbf665fe61e0b3a5d24036a4105a625f72e8c28b821e9200f20d6e8f8b3ed6b95bda6b8accdd840c2f786720b7431e3af2af981","name":"node_396c703d27bfdddf91761f134cbf665fe61e0b3a5d24036a4105a625f72e8c28b821e9200f20d6e8f8b3ed6b95bda6b8accdd840c2f786720b7431e3af2af981","enode":"enode://396c703d27bfdddf91761f134cbf665fe61e0b3a5d24036a4105a625f72e8c28b821e9200f20d6e8f8b3ed6b95bda6b8accdd840c2f786720b7431e3af2af981@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"XJvnjWmygBP+c6FtByQLVA8zmeBByS/CY6lGMrHtJV0=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 5c9be7\npopulation: 26 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 8ee7 a478 a75d b7aa | 134 e3d8 (0) e31e (0) e255 (0) e190 (0)\n001 4 38d7 2e3b 1daa 1fab | 72 07a6 (0) 05a4 (0) 0536 (0) 00c8 (0)\n002 2 60bc 6923 | 19 7810 (0) 7aef (0) 7e45 (0) 7ec4 (0)\n003 5 47a8 42d6 48df 4b70 | 16 44c8 (0) 44b7 (0) 464b (0) 47a8 (0)\n004 6 5237 510c 5062 5070 | 9 57ee (0) 5765 (0) 5741 (0) 56bb (0)\n005 3 581a 5a67 5b30 | 3 581a (0) 5a67 (0) 5b30 (0)\n============ DEPTH: 6 ==========================================\n006 1 5e3e | 1 5e3e (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 1 5cae | 1 5cae (0)\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"396c703d27bfdddf91761f134cbf665fe61e0b3a5d24036a4105a625f72e8c28b821e9200f20d6e8f8b3ed6b95bda6b8accdd840c2f786720b7431e3af2af981","private_key":"c1480926443179b2e410d0303830b51d36dcce107b45da1494d87d2bcfb4f2dc","name":"node_396c703d27bfdddf91761f134cbf665fe61e0b3a5d24036a4105a625f72e8c28b821e9200f20d6e8f8b3ed6b95bda6b8accdd840c2f786720b7431e3af2af981","services":["streamer"],"enable_msg_events":true,"port":63450},"up":true}},{"node":{"info":{"id":"cd8815d66aee8bd488d4e5e25f0cc9c71cc65349f701ea26b1d6cd9c039d16fcb473dbf270a3b33187720ccf4b0ce4f78a6d6edd05f4fe804772d5b6ec45bbd3","name":"node_cd8815d66aee8bd488d4e5e25f0cc9c71cc65349f701ea26b1d6cd9c039d16fcb473dbf270a3b33187720ccf4b0ce4f78a6d6edd05f4fe804772d5b6ec45bbd3","enode":"enode://cd8815d66aee8bd488d4e5e25f0cc9c71cc65349f701ea26b1d6cd9c039d16fcb473dbf270a3b33187720ccf4b0ce4f78a6d6edd05f4fe804772d5b6ec45bbd3@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"t6ozSkl4hzQGisc+SxG8VUd2IXUAwk63aoX+AvVe8Dc=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: b7aa33\npopulation: 19 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 2e3b 4c97 5c9b | 122 05a4 (0) 0536 (0) 07a6 (0) 00c8 (0)\n001 1 c301 | 71 e255 (0) e3d8 (0) e31e (0) e190 (0)\n002 4 9404 8ee7 802e 83d0 | 33 92d5 (0) 93f8 (0) 9108 (0) 910d (0)\n003 3 a6bd a75d a1f1 | 17 ac62 (0) af8f (0) aa78 (0) a9df (0)\n004 4 bf6b b820 bb31 bbcb | 7 bd39 (0) beb7 (0) bf6b (0) b820 (0)\n005 2 b391 b049 | 3 b30e (0) b391 (0) b049 (0)\n============ DEPTH: 6 ==========================================\n006 2 b40d b45f | 2 b40d (0) b45f (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"cd8815d66aee8bd488d4e5e25f0cc9c71cc65349f701ea26b1d6cd9c039d16fcb473dbf270a3b33187720ccf4b0ce4f78a6d6edd05f4fe804772d5b6ec45bbd3","private_key":"e91e000d37d0a336fb7eaab8ca7baa4db177108f2140ee86f7bef5959b617e13","name":"node_cd8815d66aee8bd488d4e5e25f0cc9c71cc65349f701ea26b1d6cd9c039d16fcb473dbf270a3b33187720ccf4b0ce4f78a6d6edd05f4fe804772d5b6ec45bbd3","services":["streamer"],"enable_msg_events":true,"port":63451},"up":true}},{"node":{"info":{"id":"7174eca109a1f717653918224c8cfe1b7fbd666405196760913593401eb79f2c7e41003b01f5a458940695b27a4673443c7621a169db7fd968994e552995dbbb","name":"node_7174eca109a1f717653918224c8cfe1b7fbd666405196760913593401eb79f2c7e41003b01f5a458940695b27a4673443c7621a169db7fd968994e552995dbbb","enode":"enode://7174eca109a1f717653918224c8cfe1b7fbd666405196760913593401eb79f2c7e41003b01f5a458940695b27a4673443c7621a169db7fd968994e552995dbbb@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"g9D/1D4kabnDSYhi0BhuQTzE0gX3hUv53XPE10N5IXw=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 83d0ff\npopulation: 19 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 4c97 | 122 05a4 (0) 0536 (0) 07a6 (0) 00c8 (0)\n001 1 c301 | 71 e190 (0) e255 (0) e3d8 (0) e31e (0)\n002 4 a1f1 bbcb b45f b7aa | 30 ac62 (0) af8f (0) aa78 (0) a9df (0)\n003 4 9404 9a09 9929 98aa | 18 92d5 (0) 93f8 (0) 9108 (0) 910d (0)\n004 3 8a54 8d85 8ee7 | 7 89ef (0) 8ae8 (0) 8a54 (0) 8d3c (0)\n005 4 86d3 8611 8434 8564 | 5 86d3 (0) 8611 (0) 8434 (0) 853b (0)\n============ DEPTH: 6 ==========================================\n006 2 802f 802e | 2 802f (0) 802e (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"7174eca109a1f717653918224c8cfe1b7fbd666405196760913593401eb79f2c7e41003b01f5a458940695b27a4673443c7621a169db7fd968994e552995dbbb","private_key":"991b1ea8ca82edeaa0c2d410b9cc297064d8d6668b9c8fb3277a6e7a934bbdcc","name":"node_7174eca109a1f717653918224c8cfe1b7fbd666405196760913593401eb79f2c7e41003b01f5a458940695b27a4673443c7621a169db7fd968994e552995dbbb","services":["streamer"],"enable_msg_events":true,"port":63452},"up":true}},{"node":{"info":{"id":"59b53f8a562bee519276e0eeccfcf8c975d3102f5d0cccf5abcce291a8a5bb817c04604f123686177a50a03b9d7559ac469962d0159d1d93e4ce58a304d04b55","name":"node_59b53f8a562bee519276e0eeccfcf8c975d3102f5d0cccf5abcce291a8a5bb817c04604f123686177a50a03b9d7559ac469962d0159d1d93e4ce58a304d04b55","enode":"enode://59b53f8a562bee519276e0eeccfcf8c975d3102f5d0cccf5abcce291a8a5bb817c04604f123686177a50a03b9d7559ac469962d0159d1d93e4ce58a304d04b55@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"wwHf1+dRD6crlFMerWxRzO7qIwoASpH5+0cvsZs5vAY=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: c301df\npopulation: 24 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 1dfd 4c97 | 122 07a6 (0) 0536 (0) 05a4 (0) 00c8 (0)\n001 6 a1f1 bbcb b45f b7aa | 63 ac62 (0) af8f (0) aa78 (0) a9df (0)\n002 5 ecff ebc9 e6b7 fc88 | 38 e255 (0) e3d8 (0) e31e (0) e190 (0)\n003 4 d1bc d0b7 d07c d3bd | 19 de1d (0) df52 (0) dad3 (0) d90b (0)\n004 3 ca8c cf77 ce71 | 9 c95a (0) c914 (0) c911 (0) cbd3 (0)\n============ DEPTH: 5 ==========================================\n005 3 c409 c60e c7fa | 3 c409 (0) c60e (0) c7fa (0)\n006 0 | 0\n007 0 | 0\n008 1 c3d8 | 1 c3d8 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"59b53f8a562bee519276e0eeccfcf8c975d3102f5d0cccf5abcce291a8a5bb817c04604f123686177a50a03b9d7559ac469962d0159d1d93e4ce58a304d04b55","private_key":"0c19513041b301f0745e678aa627a44b7cc58099c6616d5fed0f4e4774c5378e","name":"node_59b53f8a562bee519276e0eeccfcf8c975d3102f5d0cccf5abcce291a8a5bb817c04604f123686177a50a03b9d7559ac469962d0159d1d93e4ce58a304d04b55","services":["streamer"],"enable_msg_events":true,"port":63453},"up":true}},{"node":{"info":{"id":"f915e2398aa5d4370de87504dd76c21a7d0be2581c2ab55b7a47743f1bbaef36384eaacec22760f1e914ceac9d96a10c3d66eb27475ef444e77fee979e6e88cb","name":"node_f915e2398aa5d4370de87504dd76c21a7d0be2581c2ab55b7a47743f1bbaef36384eaacec22760f1e914ceac9d96a10c3d66eb27475ef444e77fee979e6e88cb","enode":"enode://f915e2398aa5d4370de87504dd76c21a7d0be2581c2ab55b7a47743f1bbaef36384eaacec22760f1e914ceac9d96a10c3d66eb27475ef444e77fee979e6e88cb@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"TJe+Btrp1jMiZW/qe/DeJmNGthZ0+V0er/DxRhhiO1s=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 4c97be\npopulation: 34 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 10 b391 b45f b7aa 98aa | 134 89ef (0) 8ae8 (0) 8a54 (0) 8d3c (0)\n001 5 38d7 2e3b 1fab 1dfd | 72 07a6 (0) 05a4 (0) 0536 (0) 00c8 (0)\n002 4 6923 60bc 6701 65a6 | 19 65a6 (0) 6701 (0) 67ee (0) 63de (0)\n003 5 5a67 5c9b 5237 5062 | 15 581a (0) 5a67 (0) 5b30 (0) 5e3e (0)\n004 3 42d6 464b 47a8 | 8 44c8 (0) 44b7 (0) 464b (0) 47a8 (0)\n============ DEPTH: 5 ==========================================\n005 6 4bf8 4bbc 4b8a 4b70 | 6 4bf8 (0) 4bbc (0) 4b8a (0) 4b70 (0)\n006 0 | 0\n007 1 4dc4 | 1 4dc4 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"f915e2398aa5d4370de87504dd76c21a7d0be2581c2ab55b7a47743f1bbaef36384eaacec22760f1e914ceac9d96a10c3d66eb27475ef444e77fee979e6e88cb","private_key":"c4406e8f5a2cc5a62bb4c36a3c52cd7831b3a82f06cc18e2286589a6e76a68eb","name":"node_f915e2398aa5d4370de87504dd76c21a7d0be2581c2ab55b7a47743f1bbaef36384eaacec22760f1e914ceac9d96a10c3d66eb27475ef444e77fee979e6e88cb","services":["streamer"],"enable_msg_events":true,"port":63454},"up":true}},{"node":{"info":{"id":"1b6cad4f9851cc584c5d1405f976bb51a52e27ef4525847df543dcca65ca5eb1ef229dcc68ccbaaf00ab1e044cb5990dd213c805bdb4adcceb6fa70b5c61fdb4","name":"node_1b6cad4f9851cc584c5d1405f976bb51a52e27ef4525847df543dcca65ca5eb1ef229dcc68ccbaaf00ab1e044cb5990dd213c805bdb4adcceb6fa70b5c61fdb4","enode":"enode://1b6cad4f9851cc584c5d1405f976bb51a52e27ef4525847df543dcca65ca5eb1ef229dcc68ccbaaf00ab1e044cb5990dd213c805bdb4adcceb6fa70b5c61fdb4@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"8FTCxmclg3vfHWRgL50WJ9g6PJcNm8q9p/TTkM1ApDg=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: f054c2\npopulation: 26 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 42d6 4c97 | 122 07a6 (0) 05a4 (0) 0536 (0) 00c8 (0)\n001 5 98aa a936 a1f1 bbcb | 63 89ef (0) 8ae8 (0) 8a54 (0) 8d3c (0)\n002 5 d0b7 d3bd ce71 c301 | 33 de1d (0) df52 (0) dad3 (0) d90b (0)\n003 4 e6b7 ebc9 efbb ecff | 25 e190 (0) e255 (0) e3d8 (0) e31e (0)\n004 4 f97e ffb7 fd3f fc88 | 5 f97e (0) ffb7 (0) fd44 (0) fd3f (0)\n005 1 f6a6 | 1 f6a6 (0)\n006 2 f293 f2b2 | 3 f2f5 (0) f293 (0) f2b2 (0)\n============ DEPTH: 7 ==========================================\n007 2 f1b9 f1ad | 2 f1b9 (0) f1ad (0)\n008 1 f0b8 | 1 f0b8 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"1b6cad4f9851cc584c5d1405f976bb51a52e27ef4525847df543dcca65ca5eb1ef229dcc68ccbaaf00ab1e044cb5990dd213c805bdb4adcceb6fa70b5c61fdb4","private_key":"770f973cf2fda14f46f1e91ae608e0b87e0f06b2f8935bba64a43c6998737b9d","name":"node_1b6cad4f9851cc584c5d1405f976bb51a52e27ef4525847df543dcca65ca5eb1ef229dcc68ccbaaf00ab1e044cb5990dd213c805bdb4adcceb6fa70b5c61fdb4","services":["streamer"],"enable_msg_events":true,"port":63455},"up":true}},{"node":{"info":{"id":"ae2a996d3b562cb47a564934037949da83b1bfe194c23754f3dbe2372ec27654f4f3b6cb7f394570f308025589c065870477667e5560dbe5a8ea1625740699cf","name":"node_ae2a996d3b562cb47a564934037949da83b1bfe194c23754f3dbe2372ec27654f4f3b6cb7f394570f308025589c065870477667e5560dbe5a8ea1625740699cf","enode":"enode://ae2a996d3b562cb47a564934037949da83b1bfe194c23754f3dbe2372ec27654f4f3b6cb7f394570f308025589c065870477667e5560dbe5a8ea1625740699cf@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"x/o/XdhWrAzY/D8pMxgM/h5gWzHGMHMfPgoA05L0CXo=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: c7fa3f\npopulation: 19 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 4c97 42d6 | 122 07a6 (0) 05a4 (0) 0536 (0) 00c8 (0)\n001 2 bbcb b45f | 63 89ef (0) 8ae8 (0) 8a54 (0) 8d3c (0)\n002 5 fc88 f054 e6b7 ebc9 | 38 f97e (0) ffb7 (0) fd3f (0) fd44 (0)\n003 3 d0b7 d07c d3bd | 19 de1d (0) df52 (0) dad3 (0) d90b (0)\n004 3 ca8c cf77 ce71 | 9 c95a (0) c914 (0) c911 (0) cbd3 (0)\n005 2 c3d8 c301 | 2 c3d8 (0) c301 (0)\n============ DEPTH: 6 ==========================================\n006 1 c409 | 1 c409 (0)\n007 1 c60e | 1 c60e (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"ae2a996d3b562cb47a564934037949da83b1bfe194c23754f3dbe2372ec27654f4f3b6cb7f394570f308025589c065870477667e5560dbe5a8ea1625740699cf","private_key":"2e741e89b7e631818e4edeaee9d795f912805724f2eaaa83e73a3a9e660da435","name":"node_ae2a996d3b562cb47a564934037949da83b1bfe194c23754f3dbe2372ec27654f4f3b6cb7f394570f308025589c065870477667e5560dbe5a8ea1625740699cf","services":["streamer"],"enable_msg_events":true,"port":63456},"up":true}},{"node":{"info":{"id":"ddaf3f8478501cda872c056c72063eb64d5b871fc5fff70704872802289dd2d348f73bc342b7f148a90cfaae2448ebf16fea196be9df891dc71a57fb410d59dd","name":"node_ddaf3f8478501cda872c056c72063eb64d5b871fc5fff70704872802289dd2d348f73bc342b7f148a90cfaae2448ebf16fea196be9df891dc71a57fb410d59dd","enode":"enode://ddaf3f8478501cda872c056c72063eb64d5b871fc5fff70704872802289dd2d348f73bc342b7f148a90cfaae2448ebf16fea196be9df891dc71a57fb410d59dd@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"7P85RwMlPod4oVAcl7OmoXDj2dKz/YqoNEPewO3xmJY=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: ecff39\npopulation: 27 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 1daa 4c97 510c | 122 0536 (0) 05a4 (0) 07a6 (0) 0305 (0)\n001 3 98aa bbcb b45f | 63 89ef (0) 8ae8 (0) 8a54 (0) 8d85 (0)\n002 3 ce71 c301 c7fa | 33 df52 (0) de1d (0) dad3 (0) d90b (0)\n003 2 fc88 f054 | 13 f97e (0) ffb7 (0) fd3f (0) fd44 (0)\n004 5 e724 e6b7 e406 e56c | 13 e190 (0) e255 (0) e3d8 (0) e31e (0)\n005 4 ebe8 ebc9 e850 e9fa | 4 e850 (0) e9fa (0) ebe8 (0) ebc9 (0)\n============ DEPTH: 6 ==========================================\n006 6 eee1 ee52 ee3f efc1 | 6 eee1 (0) ee52 (0) ee3f (0) efc1 (0)\n007 0 | 0\n008 1 ec78 | 1 ec78 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"ddaf3f8478501cda872c056c72063eb64d5b871fc5fff70704872802289dd2d348f73bc342b7f148a90cfaae2448ebf16fea196be9df891dc71a57fb410d59dd","private_key":"c8d2153c48467773449a0c055a3527062b7ed043e491b6a81c6285b5bea823fe","name":"node_ddaf3f8478501cda872c056c72063eb64d5b871fc5fff70704872802289dd2d348f73bc342b7f148a90cfaae2448ebf16fea196be9df891dc71a57fb410d59dd","services":["streamer"],"enable_msg_events":true,"port":63457},"up":true}},{"node":{"info":{"id":"5eccdbcb15ef42dc96abcbcd8b8db75d9230de10e3c650620737f6cc04ba4fdbf59ded5daa801901c191be186c329ebcd37ba83bcf794064ad4e11bf10d3f775","name":"node_5eccdbcb15ef42dc96abcbcd8b8db75d9230de10e3c650620737f6cc04ba4fdbf59ded5daa801901c191be186c329ebcd37ba83bcf794064ad4e11bf10d3f775","enode":"enode://5eccdbcb15ef42dc96abcbcd8b8db75d9230de10e3c650620737f6cc04ba4fdbf59ded5daa801901c191be186c329ebcd37ba83bcf794064ad4e11bf10d3f775@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"UQxwkWlIgVzTJ1nEUVFbsCTjjg24uxKHEDlpeNxwWmc=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 510c70\npopulation: 19 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 b45f bbcb ecff | 134 89ef (0) 8ae8 (0) 8a54 (0) 8d3c (0)\n001 2 2e3b 1fab | 72 07a6 (0) 05a4 (0) 0536 (0) 00c8 (0)\n002 2 60bc 6923 | 19 7e45 (0) 7ec4 (0) 7810 (0) 7aef (0)\n003 3 42d6 4b70 4c97 | 16 44c8 (0) 44b7 (0) 464b (0) 47a8 (0)\n004 2 5c9b 5b30 | 6 581a (0) 5a67 (0) 5b30 (0) 5e3e (0)\n005 3 5741 5765 56bb | 4 57ee (0) 5765 (0) 5741 (0) 56bb (0)\n006 2 5399 5237 | 2 5237 (0) 5399 (0)\n============ DEPTH: 7 ==========================================\n007 2 5070 5062 | 2 5070 (0) 5062 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"5eccdbcb15ef42dc96abcbcd8b8db75d9230de10e3c650620737f6cc04ba4fdbf59ded5daa801901c191be186c329ebcd37ba83bcf794064ad4e11bf10d3f775","private_key":"784f624bd696dc1d6afb5bb977c5e6e76ab280e55c95949a68349a62fcc32c70","name":"node_5eccdbcb15ef42dc96abcbcd8b8db75d9230de10e3c650620737f6cc04ba4fdbf59ded5daa801901c191be186c329ebcd37ba83bcf794064ad4e11bf10d3f775","services":["streamer"],"enable_msg_events":true,"port":63458},"up":true}},{"node":{"info":{"id":"8dd8ad560af84bec579cadb33d51711aa61b6ed22705010336df5a71a94591173b25e869457429c4a199b205fce8e73530e28203e18b971c2001715e610f152a","name":"node_8dd8ad560af84bec579cadb33d51711aa61b6ed22705010336df5a71a94591173b25e869457429c4a199b205fce8e73530e28203e18b971c2001715e610f152a","enode":"enode://8dd8ad560af84bec579cadb33d51711aa61b6ed22705010336df5a71a94591173b25e869457429c4a199b205fce8e73530e28203e18b971c2001715e610f152a@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"u8uvIzRlrNzOlJIKKmQ8IHcgdK8JSjP/uWzJFeMP/Yo=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: bbcbaf\npopulation: 23 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 2e3b 510c | 122 07a6 (0) 05a4 (0) 0536 (0) 0305 (0)\n001 6 ebc9 ecff f054 c7fa | 71 f97e (0) ffb7 (0) fd3f (0) fd44 (0)\n002 3 8ee7 83d0 98aa | 33 89ef (0) 8ae8 (0) 8a54 (0) 8d3c (0)\n003 3 a9df a105 a1f1 | 17 ac62 (0) af8f (0) aa78 (0) a936 (0)\n004 4 b391 b049 b7aa b45f | 6 b30e (0) b391 (0) b049 (0) b7aa (0)\n005 2 beb7 bf6b | 3 bd39 (0) beb7 (0) bf6b (0)\n006 1 b820 | 1 b820 (0)\n============ DEPTH: 7 ==========================================\n007 1 baaf | 1 baaf (0)\n008 1 bb31 | 1 bb31 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"8dd8ad560af84bec579cadb33d51711aa61b6ed22705010336df5a71a94591173b25e869457429c4a199b205fce8e73530e28203e18b971c2001715e610f152a","private_key":"f4e049b715346f2e7ac1e31341d0df32e7ba9ae1ab6d9165b7407873add289cd","name":"node_8dd8ad560af84bec579cadb33d51711aa61b6ed22705010336df5a71a94591173b25e869457429c4a199b205fce8e73530e28203e18b971c2001715e610f152a","services":["streamer"],"enable_msg_events":true,"port":63459},"up":true}},{"node":{"info":{"id":"28d3232c43de54ffdaf08f97b334c012738648b04e2876c7e751a2e352aaf4d550d6efa976c5a8edbfa8e88b9d04a0fca492b81c3756ef673ab74d34182ca711","name":"node_28d3232c43de54ffdaf08f97b334c012738648b04e2876c7e751a2e352aaf4d550d6efa976c5a8edbfa8e88b9d04a0fca492b81c3756ef673ab74d34182ca711","enode":"enode://28d3232c43de54ffdaf08f97b334c012738648b04e2876c7e751a2e352aaf4d550d6efa976c5a8edbfa8e88b9d04a0fca492b81c3756ef673ab74d34182ca711@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"znEo6gtodVrqbi3V1doRAKHinrwtNM4CwNAlpKcA6hU=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: ce7128\npopulation: 24 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 0536 42d6 | 122 07a6 (0) 05a4 (0) 0536 (0) 0305 (0)\n001 3 98aa b45f bbcb | 63 89ef (0) 8ae8 (0) 8a54 (0) 8d3c (0)\n002 5 e6b7 ebc9 ecff fc88 | 38 f97e (0) ffb7 (0) fd3f (0) fd44 (0)\n003 3 d07c d0b7 d3bd | 19 de1d (0) df52 (0) dad3 (0) d90b (0)\n004 3 c301 c409 c7fa | 5 c3d8 (0) c301 (0) c409 (0) c60e (0)\n============ DEPTH: 5 ==========================================\n005 7 c95a c914 c911 cba4 | 7 c95a (0) c914 (0) c911 (0) cbd3 (0)\n006 0 | 0\n007 1 cf77 | 1 cf77 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"28d3232c43de54ffdaf08f97b334c012738648b04e2876c7e751a2e352aaf4d550d6efa976c5a8edbfa8e88b9d04a0fca492b81c3756ef673ab74d34182ca711","private_key":"98e1264b7003ea79b1e799c87cb3c8e1aab2ea2e68531cf41f093c4b9f6a98a2","name":"node_28d3232c43de54ffdaf08f97b334c012738648b04e2876c7e751a2e352aaf4d550d6efa976c5a8edbfa8e88b9d04a0fca492b81c3756ef673ab74d34182ca711","services":["streamer"],"enable_msg_events":true,"port":63460},"up":true}},{"node":{"info":{"id":"be514f5f17f3177235acb24112b578edf0e373c469073226e547d18080905fd062d572be18e943f13bf9fcf5871e89ceb630a1b848a0e370ef8ef8c6d997a363","name":"node_be514f5f17f3177235acb24112b578edf0e373c469073226e547d18080905fd062d572be18e943f13bf9fcf5871e89ceb630a1b848a0e370ef8ef8c6d997a363","enode":"enode://be514f5f17f3177235acb24112b578edf0e373c469073226e547d18080905fd062d572be18e943f13bf9fcf5871e89ceb630a1b848a0e370ef8ef8c6d997a363@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"Qtav6ud66emca7cnEm3eXhM4tUIcr+J4clG9GdK1TTo=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 42d6af\npopulation: 26 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 5 98aa ebc9 f054 ce71 | 134 af8f (0) ac62 (0) aa78 (0) a9df (0)\n001 8 293f 2e3b 2f1f 38d7 | 72 09d1 (0) 0bc3 (0) 0a3f (0) 0ad6 (0)\n002 1 60bc | 19 7810 (0) 7aef (0) 7e45 (0) 7ec4 (0)\n003 3 5c9b 510c 5062 | 15 581a (0) 5a67 (0) 5b30 (0) 5e3e (0)\n004 3 4c97 4bbc 48df | 8 4b70 (0) 4bf8 (0) 4b8a (0) 4bbc (0)\n005 3 44b7 464b 47a8 | 4 44c8 (0) 44b7 (0) 464b (0) 47a8 (0)\n============ DEPTH: 6 ==========================================\n006 2 41b2 413b | 2 41b2 (0) 413b (0)\n007 1 43fb | 1 43fb (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"be514f5f17f3177235acb24112b578edf0e373c469073226e547d18080905fd062d572be18e943f13bf9fcf5871e89ceb630a1b848a0e370ef8ef8c6d997a363","private_key":"357e1ab3ea555b0928cf10ec54d8842dc9c0b24a90fbe32ad1a819c018b0c26a","name":"node_be514f5f17f3177235acb24112b578edf0e373c469073226e547d18080905fd062d572be18e943f13bf9fcf5871e89ceb630a1b848a0e370ef8ef8c6d997a363","services":["streamer"],"enable_msg_events":true,"port":63461},"up":true}},{"node":{"info":{"id":"66d0c5da973d9dd65350ae1ec63776872cdb7ded6afb6f51ae82259f6fd35e884375d15de290625f02ed2e5cdc3f591decb45e5fc64d5b0f835a216fd196f5a3","name":"node_66d0c5da973d9dd65350ae1ec63776872cdb7ded6afb6f51ae82259f6fd35e884375d15de290625f02ed2e5cdc3f591decb45e5fc64d5b0f835a216fd196f5a3","enode":"enode://66d0c5da973d9dd65350ae1ec63776872cdb7ded6afb6f51ae82259f6fd35e884375d15de290625f02ed2e5cdc3f591decb45e5fc64d5b0f835a216fd196f5a3@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"mKqPnj9DSQUiIJBFPysKl7fWCiUuDs1RlFFkXg5oUxk=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 98aa8f\npopulation: 25 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 4c97 42d6 | 122 05a4 (0) 0536 (0) 07a6 (0) 00c8 (0)\n001 6 ecff ebc9 fc88 f054 | 71 f97e (0) ffb7 (0) fd3f (0) fd44 (0)\n002 3 a936 bbcb b45f | 30 a317 (0) a3f2 (0) a077 (0) a011 (0)\n003 3 8ee7 802e 83d0 | 15 89ef (0) 8ae8 (0) 8a54 (0) 8d85 (0)\n004 2 910d 9404 | 8 92d5 (0) 93f8 (0) 9108 (0) 910d (0)\n005 1 9f4c | 1 9f4c (0)\n006 3 9a09 9bc3 9b87 | 3 9bc3 (0) 9b87 (0) 9a09 (0)\n007 3 99eb 9929 9918 | 3 99eb (0) 9929 (0) 9918 (0)\n============ DEPTH: 8 ==========================================\n008 1 985f | 1 985f (0)\n009 0 | 0\n010 0 | 0\n011 1 98bc | 1 98bc (0)\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"66d0c5da973d9dd65350ae1ec63776872cdb7ded6afb6f51ae82259f6fd35e884375d15de290625f02ed2e5cdc3f591decb45e5fc64d5b0f835a216fd196f5a3","private_key":"ad08dbea349545a36c8160aa460902c7d2744218b8ff5b8af229a17675560755","name":"node_66d0c5da973d9dd65350ae1ec63776872cdb7ded6afb6f51ae82259f6fd35e884375d15de290625f02ed2e5cdc3f591decb45e5fc64d5b0f835a216fd196f5a3","services":["streamer"],"enable_msg_events":true,"port":63462},"up":true}},{"node":{"info":{"id":"2f360209383d6de4ebd3b4abaf77796520b8654270b03f2151eac4a01b4417d7e0668c1f9ad30c20ff49aa8a0ab33dba5e6095619d1cf04b7af841722ab773da","name":"node_2f360209383d6de4ebd3b4abaf77796520b8654270b03f2151eac4a01b4417d7e0668c1f9ad30c20ff49aa8a0ab33dba5e6095619d1cf04b7af841722ab773da","enode":"enode://2f360209383d6de4ebd3b4abaf77796520b8654270b03f2151eac4a01b4417d7e0668c1f9ad30c20ff49aa8a0ab33dba5e6095619d1cf04b7af841722ab773da@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"tF/WtM4lQYFoNAZtzBzuS/s0Psll21PtqYbmsDdRNGA=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: b45fd6\npopulation: 24 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 4c97 510c | 122 05a4 (0) 0536 (0) 07a6 (0) 00c8 (0)\n001 6 ce71 c301 c7fa f054 | 71 de1d (0) df52 (0) dad3 (0) d90b (0)\n002 4 8ee7 83d0 9404 98aa | 33 89ef (0) 8ae8 (0) 8a54 (0) 8d3c (0)\n003 5 a936 a478 a6bd a75d | 17 ac62 (0) af8f (0) aa78 (0) a9df (0)\n004 2 b820 bbcb | 7 bd39 (0) beb7 (0) bf6b (0) b820 (0)\n005 3 b391 b30e b049 | 3 b30e (0) b391 (0) b049 (0)\n============ DEPTH: 6 ==========================================\n006 1 b7aa | 1 b7aa (0)\n007 0 | 0\n008 0 | 0\n009 1 b40d | 1 b40d (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"2f360209383d6de4ebd3b4abaf77796520b8654270b03f2151eac4a01b4417d7e0668c1f9ad30c20ff49aa8a0ab33dba5e6095619d1cf04b7af841722ab773da","private_key":"8e27f11572dc1832939cc80ada2ce9604fb91d0633410f87cd7bf68e4629b32d","name":"node_2f360209383d6de4ebd3b4abaf77796520b8654270b03f2151eac4a01b4417d7e0668c1f9ad30c20ff49aa8a0ab33dba5e6095619d1cf04b7af841722ab773da","services":["streamer"],"enable_msg_events":true,"port":63463},"up":true}},{"node":{"info":{"id":"b35f418c7935cc54278e90978c3ef1521ab91daeaf9f1ebc1cd25211611ade091cac4e1f009d71059279d507322a4536501980ac0dd44caddc52fd4c593879f7","name":"node_b35f418c7935cc54278e90978c3ef1521ab91daeaf9f1ebc1cd25211611ade091cac4e1f009d71059279d507322a4536501980ac0dd44caddc52fd4c593879f7","enode":"enode://b35f418c7935cc54278e90978c3ef1521ab91daeaf9f1ebc1cd25211611ade091cac4e1f009d71059279d507322a4536501980ac0dd44caddc52fd4c593879f7@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"68myiN5VNPdipKsOZSKVWo+DrRW2YkJuRZVqggQB0KA=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: ebc9b2\npopulation: 29 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 6 0ca9 3baa 3c5a 24f8 | 122 2940 (0) 293f (0) 2a7d (0) 2c4e (0)\n001 5 9404 98aa a936 b45f | 63 89ef (0) 8a54 (0) 8ae8 (0) 8ea9 (0)\n002 4 c301 c7fa ce71 d3bd | 33 dad3 (0) d96e (0) d90b (0) df52 (0)\n003 3 fc88 f0b8 f054 | 13 f6a6 (0) f2b2 (0) f293 (0) f2f5 (0)\n004 3 e406 e5d2 e6b7 | 13 e190 (0) e255 (0) e3d8 (0) e31e (0)\n005 5 ecff ee52 efbb efc1 | 8 eee1 (0) ee3f (0) ee52 (0) efc1 (0)\n============ DEPTH: 6 ==========================================\n006 2 e9fa e850 | 2 e9fa (0) e850 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 1 ebe8 | 1 ebe8 (0)\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"b35f418c7935cc54278e90978c3ef1521ab91daeaf9f1ebc1cd25211611ade091cac4e1f009d71059279d507322a4536501980ac0dd44caddc52fd4c593879f7","private_key":"4a7cb437d9c60831cf5e8c6d02e0f62205c1a2de83d9879d1d82ecb6e9b99031","name":"node_b35f418c7935cc54278e90978c3ef1521ab91daeaf9f1ebc1cd25211611ade091cac4e1f009d71059279d507322a4536501980ac0dd44caddc52fd4c593879f7","services":["streamer"],"enable_msg_events":true,"port":63464},"up":true}},{"node":{"info":{"id":"fe8ac5d33cd8ab6a1dad9567cdfb89b431a5c4f4a584fc608b92e7dfd06f70988e71e2f11f9fda9ee797c9ffba83bc085939fdf2522dde39f28202be92650566","name":"node_fe8ac5d33cd8ab6a1dad9567cdfb89b431a5c4f4a584fc608b92e7dfd06f70988e71e2f11f9fda9ee797c9ffba83bc085939fdf2522dde39f28202be92650566","enode":"enode://fe8ac5d33cd8ab6a1dad9567cdfb89b431a5c4f4a584fc608b92e7dfd06f70988e71e2f11f9fda9ee797c9ffba83bc085939fdf2522dde39f28202be92650566@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"/IgaOg2mBcd4G6axIvBQfzA/qZgYWjUZdq6uifTvi4s=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: fc881a\npopulation: 21 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 3baa | 122 7aef (0) 7810 (0) 7e45 (0) 7ec4 (0)\n001 2 98aa a936 | 63 b30e (0) b391 (0) b049 (0) b7aa (0)\n002 5 d0b7 d3bd ce71 c301 | 33 de1d (0) df52 (0) dad3 (0) d90b (0)\n003 3 ebc9 ecff e6b7 | 25 e190 (0) e255 (0) e3d8 (0) e31e (0)\n004 6 f6a6 f2b2 f1ad f1b9 | 8 f6a6 (0) f2f5 (0) f293 (0) f2b2 (0)\n005 1 f97e | 1 f97e (0)\n006 1 ffb7 | 1 ffb7 (0)\n============ DEPTH: 7 ==========================================\n007 2 fd44 fd3f | 2 fd44 (0) fd3f (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"fe8ac5d33cd8ab6a1dad9567cdfb89b431a5c4f4a584fc608b92e7dfd06f70988e71e2f11f9fda9ee797c9ffba83bc085939fdf2522dde39f28202be92650566","private_key":"18216d0babc8a162ed03e1c866e0e90d0ea5fd5c2c2ea3f411886de38bf58640","name":"node_fe8ac5d33cd8ab6a1dad9567cdfb89b431a5c4f4a584fc608b92e7dfd06f70988e71e2f11f9fda9ee797c9ffba83bc085939fdf2522dde39f28202be92650566","services":["streamer"],"enable_msg_events":true,"port":63465},"up":true}},{"node":{"info":{"id":"352407b42726dcd1aacc46a912ed8124b8b6a3da4e33dab742e40aa2452953d35dc8f42eddc76695ae2317e9f15dde2cd21be4ce826934695ad1847455661d1b","name":"node_352407b42726dcd1aacc46a912ed8124b8b6a3da4e33dab742e40aa2452953d35dc8f42eddc76695ae2317e9f15dde2cd21be4ce826934695ad1847455661d1b","enode":"enode://352407b42726dcd1aacc46a912ed8124b8b6a3da4e33dab742e40aa2452953d35dc8f42eddc76695ae2317e9f15dde2cd21be4ce826934695ad1847455661d1b@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"O6pCOJMFZ39YkQeo71jhKasp0OFoIN9M4hlRE+6w8pU=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 3baa42\npopulation: 25 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 9404 fc88 ebc9 e6b7 | 134 b30e (0) b391 (0) b049 (0) b40d (0)\n001 2 42d6 47a8 | 50 7e45 (0) 7ec4 (0) 7810 (0) 7aef (0)\n002 1 0ca9 | 37 1254 (0) 10b1 (0) 11a0 (0) 14e4 (0)\n003 6 24f8 2224 2e3b 2f23 | 15 2a7d (0) 2940 (0) 293f (0) 2e3b (0)\n004 5 3388 3054 307c 34e4 | 10 3734 (0) 3799 (0) 3607 (0) 3658 (0)\n005 2 3ff8 3c5a | 4 3ef6 (0) 3ff8 (0) 3d17 (0) 3c5a (0)\n006 3 398b 38d7 3843 | 3 398b (0) 38d7 (0) 3843 (0)\n============ DEPTH: 7 ==========================================\n007 2 3a18 3ab2 | 2 3a18 (0) 3ab2 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"352407b42726dcd1aacc46a912ed8124b8b6a3da4e33dab742e40aa2452953d35dc8f42eddc76695ae2317e9f15dde2cd21be4ce826934695ad1847455661d1b","private_key":"bb317b572ed4481d33b6a67a267264366929dc0e2c12ade71a203b8b3159be03","name":"node_352407b42726dcd1aacc46a912ed8124b8b6a3da4e33dab742e40aa2452953d35dc8f42eddc76695ae2317e9f15dde2cd21be4ce826934695ad1847455661d1b","services":["streamer"],"enable_msg_events":true,"port":63466},"up":true}},{"node":{"info":{"id":"b137cf2291b530a39516d882200848e7f27a2710e0839b4d25b4f367bea6a0c3aaef8c7c7851c00a2945adcd819ea0508610afc1f453b8bc512b7b4d4faacdf3","name":"node_b137cf2291b530a39516d882200848e7f27a2710e0839b4d25b4f367bea6a0c3aaef8c7c7851c00a2945adcd819ea0508610afc1f453b8bc512b7b4d4faacdf3","enode":"enode://b137cf2291b530a39516d882200848e7f27a2710e0839b4d25b4f367bea6a0c3aaef8c7c7851c00a2945adcd819ea0508610afc1f453b8bc512b7b4d4faacdf3@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"lAQVrQxHNzQWva6lDtNgYqR/6y4JU3QB+GiT8zeCStg=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 940415\npopulation: 23 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 47a8 3baa | 122 7ec4 (0) 7e45 (0) 7aef (0) 7810 (0)\n001 4 ebc9 dad3 de1d df52 | 71 df52 (0) de1d (0) dad3 (0) d90b (0)\n002 6 b7aa b45f a478 a75d | 30 bd39 (0) beb7 (0) bf6b (0) b820 (0)\n003 2 8ee7 83d0 | 15 89ef (0) 8ae8 (0) 8a54 (0) 8d85 (0)\n004 5 9a09 9929 9918 98bc | 10 9f4c (0) 9b87 (0) 9bc3 (0) 9a09 (0)\n005 1 910d | 4 92d5 (0) 93f8 (0) 9108 (0) 910d (0)\n============ DEPTH: 6 ==========================================\n006 2 9641 9747 | 2 9641 (0) 9747 (0)\n007 0 | 0\n008 1 9493 | 1 9493 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"b137cf2291b530a39516d882200848e7f27a2710e0839b4d25b4f367bea6a0c3aaef8c7c7851c00a2945adcd819ea0508610afc1f453b8bc512b7b4d4faacdf3","private_key":"bd9c51ff7ece28d9a9808386358197110aa9a2a7d4715cd033a94c4d1d54ee76","name":"node_b137cf2291b530a39516d882200848e7f27a2710e0839b4d25b4f367bea6a0c3aaef8c7c7851c00a2945adcd819ea0508610afc1f453b8bc512b7b4d4faacdf3","services":["streamer"],"enable_msg_events":true,"port":63467},"up":true}},{"node":{"info":{"id":"1b063741c76fe65e62b4eae42751319d0cce66f22dde9f1cf83d6cca249a0e65bc7f6f22597697362fadd226222fb3847f8e146961969d1b4c9f7e475389cd8e","name":"node_1b063741c76fe65e62b4eae42751319d0cce66f22dde9f1cf83d6cca249a0e65bc7f6f22597697362fadd226222fb3847f8e146961969d1b4c9f7e475389cd8e","enode":"enode://1b063741c76fe65e62b4eae42751319d0cce66f22dde9f1cf83d6cca249a0e65bc7f6f22597697362fadd226222fb3847f8e146961969d1b4c9f7e475389cd8e@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"R6jpkYrTuVeoiFQKSX/kbcS2Sh0fH44brO/faBPZHXA=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 47a8e9\npopulation: 24 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 9404 | 134 df52 (0) de1d (0) dad3 (0) d90b (0)\n001 9 2c16 2224 24f8 3054 | 72 208e (0) 2220 (0) 2224 (0) 2737 (0)\n002 2 7299 6f1c | 19 7ec4 (0) 7e45 (0) 7810 (0) 7aef (0)\n003 3 56bb 5c9b 5b30 | 15 5e3e (0) 5cae (0) 5c9b (0) 581a (0)\n004 3 4bbc 48df 4c97 | 8 4b70 (0) 4bf8 (0) 4b8a (0) 4bbc (0)\n005 3 413b 42d6 43fb | 4 41b2 (0) 413b (0) 43fb (0) 42d6 (0)\n============ DEPTH: 6 ==========================================\n006 2 44c8 44b7 | 2 44c8 (0) 44b7 (0)\n007 1 464b | 1 464b (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"1b063741c76fe65e62b4eae42751319d0cce66f22dde9f1cf83d6cca249a0e65bc7f6f22597697362fadd226222fb3847f8e146961969d1b4c9f7e475389cd8e","private_key":"6113b0494786bde04defd28e36030dad5b4368563b7b6b63c08475c18980a380","name":"node_1b063741c76fe65e62b4eae42751319d0cce66f22dde9f1cf83d6cca249a0e65bc7f6f22597697362fadd226222fb3847f8e146961969d1b4c9f7e475389cd8e","services":["streamer"],"enable_msg_events":true,"port":63468},"up":true}},{"node":{"info":{"id":"657d5370319128d24d925b41065eb619409d63ec6280975d78877a4028287463f6442f5206dd703569a05b2b542ad8bbb99803da265408208d6356a26d283d08","name":"node_657d5370319128d24d925b41065eb619409d63ec6280975d78877a4028287463f6442f5206dd703569a05b2b542ad8bbb99803da265408208d6356a26d283d08","enode":"enode://657d5370319128d24d925b41065eb619409d63ec6280975d78877a4028287463f6442f5206dd703569a05b2b542ad8bbb99803da265408208d6356a26d283d08@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"DKnRmsucRZNY62ndqtmNygtME7FM8WEHFu1PhN2XJWM=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 0ca9d1\npopulation: 26 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 ebc9 a936 | 134 df52 (0) de1d (0) d90b (0) d96e (0)\n001 1 47a8 | 50 76a5 (0) 77bc (0) 715b (0) 71bf (0)\n002 8 2c16 2224 24f8 307c | 35 208e (0) 2220 (0) 2224 (0) 2737 (0)\n003 2 1dfd 1daa | 19 11a0 (0) 10b1 (0) 1254 (0) 14e4 (0)\n004 4 0305 0020 0536 07a6 | 7 05a4 (0) 0536 (0) 07a6 (0) 00c8 (0)\n005 3 09d1 0a3f 0bc3 | 4 09d1 (0) 0a3f (0) 0ad6 (0) 0bc3 (0)\n006 2 0f65 0fa0 | 2 0f65 (0) 0fa0 (0)\n007 2 0d97 0daf | 2 0d97 (0) 0daf (0)\n============ DEPTH: 8 ==========================================\n008 2 0c72 0c19 | 2 0c72 (0) 0c19 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"657d5370319128d24d925b41065eb619409d63ec6280975d78877a4028287463f6442f5206dd703569a05b2b542ad8bbb99803da265408208d6356a26d283d08","private_key":"9875ab2bbcb806524e7fca84b6aba663cbbbec2d533a47e2df6f3fc85e1d8e55","name":"node_657d5370319128d24d925b41065eb619409d63ec6280975d78877a4028287463f6442f5206dd703569a05b2b542ad8bbb99803da265408208d6356a26d283d08","services":["streamer"],"enable_msg_events":true,"port":63469},"up":true}},{"node":{"info":{"id":"a127faa19dcb7da585983d36a8e9d3e9a44a6db68507b60c70da71011f44ce377944802f39cd65f5a705cd8249ac1ef7ed8fd699349098f3f8e23b37592c80ae","name":"node_a127faa19dcb7da585983d36a8e9d3e9a44a6db68507b60c70da71011f44ce377944802f39cd65f5a705cd8249ac1ef7ed8fd699349098f3f8e23b37592c80ae","enode":"enode://a127faa19dcb7da585983d36a8e9d3e9a44a6db68507b60c70da71011f44ce377944802f39cd65f5a705cd8249ac1ef7ed8fd699349098f3f8e23b37592c80ae@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"qTZcTLja+LsBim7JuwPpx16xlVsm2IR7ho244wKnr/U=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: a9365c\npopulation: 24 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 0ca9 3c5a | 122 7e45 (0) 7ec4 (0) 7810 (0) 7aef (0)\n001 5 fc88 f054 ebc9 ebe8 | 71 dad3 (0) d90b (0) d96e (0) df52 (0)\n002 4 985f 98aa 910d 9404 | 33 8d85 (0) 8d3c (0) 8ea9 (0) 8ee7 (0)\n003 2 b391 b45f | 13 bd39 (0) beb7 (0) bf6b (0) b820 (0)\n004 7 a75d a6bd a478 a0c9 | 12 a478 (0) a75d (0) a6bd (0) a317 (0)\n005 2 af8f ac62 | 2 af8f (0) ac62 (0)\n============ DEPTH: 6 ==========================================\n006 1 aa78 | 1 aa78 (0)\n007 0 | 0\n008 1 a9df | 1 a9df (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"a127faa19dcb7da585983d36a8e9d3e9a44a6db68507b60c70da71011f44ce377944802f39cd65f5a705cd8249ac1ef7ed8fd699349098f3f8e23b37592c80ae","private_key":"43de756eb52b963762bf62085de3293461cb2c53dd70baced6e3c86981545add","name":"node_a127faa19dcb7da585983d36a8e9d3e9a44a6db68507b60c70da71011f44ce377944802f39cd65f5a705cd8249ac1ef7ed8fd699349098f3f8e23b37592c80ae","services":["streamer"],"enable_msg_events":true,"port":63470},"up":true}},{"node":{"info":{"id":"2e42f845d0393d1682add54ee30b60a953ed283e75d347bc6719ae0e91f6676282e7960f1fd52e5803d6b341fb3582c724b4f9cfd7bce9ce85f13ca480c7e72e","name":"node_2e42f845d0393d1682add54ee30b60a953ed283e75d347bc6719ae0e91f6676282e7960f1fd52e5803d6b341fb3582c724b4f9cfd7bce9ce85f13ca480c7e72e","enode":"enode://2e42f845d0393d1682add54ee30b60a953ed283e75d347bc6719ae0e91f6676282e7960f1fd52e5803d6b341fb3582c724b4f9cfd7bce9ce85f13ca480c7e72e@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"PFrju0YrEJIitKGsHPmwRQj81TotE3logJZemeAhbug=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 3c5ae3\npopulation: 17 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 ebc9 e6b7 a936 | 134 df52 (0) de1d (0) dad3 (0) d90b (0)\n001 1 47a8 | 50 7e45 (0) 7ec4 (0) 7810 (0) 7aef (0)\n002 2 1dfd 0ca9 | 37 11a0 (0) 10b1 (0) 1254 (0) 167b (0)\n003 1 2c16 | 15 2737 (0) 24f8 (0) 208e (0) 2220 (0)\n004 2 34e4 3054 | 10 3799 (0) 3734 (0) 3607 (0) 3658 (0)\n005 5 38d7 3843 3a18 3ab2 | 6 398b (0) 38d7 (0) 3843 (0) 3a18 (0)\n============ DEPTH: 6 ==========================================\n006 2 3ef6 3ff8 | 2 3ef6 (0) 3ff8 (0)\n007 1 3d17 | 1 3d17 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"2e42f845d0393d1682add54ee30b60a953ed283e75d347bc6719ae0e91f6676282e7960f1fd52e5803d6b341fb3582c724b4f9cfd7bce9ce85f13ca480c7e72e","private_key":"af731618471023aff01cd45c69001d7fa95752c4d42c68df95eab820bb70bff5","name":"node_2e42f845d0393d1682add54ee30b60a953ed283e75d347bc6719ae0e91f6676282e7960f1fd52e5803d6b341fb3582c724b4f9cfd7bce9ce85f13ca480c7e72e","services":["streamer"],"enable_msg_events":true,"port":63471},"up":true}},{"node":{"info":{"id":"6b01079463ec2f649db8634cb7a596261c79a8f714d954c772528e0547b017f8ce405e4a0ea9d32270848180e0f77b8c0b022cf95c85e777626edd4d24ea21d2","name":"node_6b01079463ec2f649db8634cb7a596261c79a8f714d954c772528e0547b017f8ce405e4a0ea9d32270848180e0f77b8c0b022cf95c85e777626edd4d24ea21d2","enode":"enode://6b01079463ec2f649db8634cb7a596261c79a8f714d954c772528e0547b017f8ce405e4a0ea9d32270848180e0f77b8c0b022cf95c85e777626edd4d24ea21d2@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"5reZSRezShp2CkjMp09ZKu+U+K/ZFoa1240Did7QkoE=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: e6b799\npopulation: 35 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 6 1dfd 24f8 3c5a 38d7 | 122 5e3e (0) 5cae (0) 5c9b (0) 581a (0)\n001 4 a6bd a105 a936 910d | 63 b40d (0) b45f (0) b7aa (0) b30e (0)\n002 7 ce71 c7fa c301 d96e | 33 df52 (0) de1d (0) dad3 (0) d90b (0)\n003 5 f1ad f0b8 f054 fc88 | 13 f6a6 (0) f293 (0) f2b2 (0) f2f5 (0)\n004 4 ebe8 ebc9 ecff efbb | 12 ee52 (0) ee3f (0) eee1 (0) efdd (0)\n005 1 e31e | 4 e190 (0) e255 (0) e3d8 (0) e31e (0)\n============ DEPTH: 6 ==========================================\n006 7 e54d e56c e5d2 e4e9 | 7 e54d (0) e56c (0) e5d2 (0) e4e9 (0)\n007 1 e724 | 1 e724 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"6b01079463ec2f649db8634cb7a596261c79a8f714d954c772528e0547b017f8ce405e4a0ea9d32270848180e0f77b8c0b022cf95c85e777626edd4d24ea21d2","private_key":"3444df2021104f7c577b25a23c3fc0231efb2cae1375cbae67db5602cbbe13d9","name":"node_6b01079463ec2f649db8634cb7a596261c79a8f714d954c772528e0547b017f8ce405e4a0ea9d32270848180e0f77b8c0b022cf95c85e777626edd4d24ea21d2","services":["streamer"],"enable_msg_events":true,"port":63472},"up":true}},{"node":{"info":{"id":"2245f3bf1a3b4e92f912affc75f757cf648b20474c11ffe947884f216b8f24f9dcb6e6a0358a4061b8517478ec15027e185b2f05a777573b4940375bf4aaf2be","name":"node_2245f3bf1a3b4e92f912affc75f757cf648b20474c11ffe947884f216b8f24f9dcb6e6a0358a4061b8517478ec15027e185b2f05a777573b4940375bf4aaf2be","enode":"enode://2245f3bf1a3b4e92f912affc75f757cf648b20474c11ffe947884f216b8f24f9dcb6e6a0358a4061b8517478ec15027e185b2f05a777573b4940375bf4aaf2be@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"OrIINviKq0lJHoLP0fHopZtXlM+RZEtmPUDLIsVGC+Q=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 3ab208\npopulation: 19 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 9918 e6b7 | 134 bd39 (0) beb7 (0) bf6b (0) b820 (0)\n001 4 56bb 42d6 47a8 6f1c | 50 48ec (0) 48df (0) 4b70 (0) 4bf8 (0)\n002 2 0ca9 1dfd | 37 05a4 (0) 0536 (0) 07a6 (0) 00c8 (0)\n003 2 2e3b 24f8 | 15 2a7d (0) 2940 (0) 293f (0) 2e3b (0)\n004 1 3054 | 10 3799 (0) 3734 (0) 3607 (0) 3658 (0)\n005 3 3ff8 3d17 3c5a | 4 3ef6 (0) 3ff8 (0) 3d17 (0) 3c5a (0)\n006 3 398b 38d7 3843 | 3 398b (0) 38d7 (0) 3843 (0)\n============ DEPTH: 7 ==========================================\n007 1 3baa | 1 3baa (0)\n008 1 3a18 | 1 3a18 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"2245f3bf1a3b4e92f912affc75f757cf648b20474c11ffe947884f216b8f24f9dcb6e6a0358a4061b8517478ec15027e185b2f05a777573b4940375bf4aaf2be","private_key":"638383a2262ab3e1cb5a1cdf134fb5a0077f21e3bf90118cc03311db43b1cf0a","name":"node_2245f3bf1a3b4e92f912affc75f757cf648b20474c11ffe947884f216b8f24f9dcb6e6a0358a4061b8517478ec15027e185b2f05a777573b4940375bf4aaf2be","services":["streamer"],"enable_msg_events":true,"port":63473},"up":true}},{"node":{"info":{"id":"d4b7c787981abec24353c7d496661692233797e3758189bf909a69fe87935bf6da0940daa4f12e81f20c5e88f70b472113688b71a0ae2f91a73ee0e6ff4c8591","name":"node_d4b7c787981abec24353c7d496661692233797e3758189bf909a69fe87935bf6da0940daa4f12e81f20c5e88f70b472113688b71a0ae2f91a73ee0e6ff4c8591","enode":"enode://d4b7c787981abec24353c7d496661692233797e3758189bf909a69fe87935bf6da0940daa4f12e81f20c5e88f70b472113688b71a0ae2f91a73ee0e6ff4c8591@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"Hf3ofHggwozWc+bab6jJtzVC3mtaz9md0TFqIq9esWM=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 1dfde8\npopulation: 31 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 e6b7 c301 910d | 134 c3d8 (0) c301 (0) c409 (0) c60e (0)\n001 5 47a8 4c97 4bbc 7299 | 50 48df (0) 48ec (0) 4b70 (0) 4bf8 (0)\n002 7 2c16 2220 2224 24f8 | 35 2a7d (0) 2940 (0) 293f (0) 2e3b (0)\n003 2 09d1 0ca9 | 18 05a4 (0) 0536 (0) 07a6 (0) 00c8 (0)\n004 5 1758 15ec 1254 11a0 | 9 11a0 (0) 10b1 (0) 1254 (0) 14e4 (0)\n005 4 1af6 1a8e 1a85 1953 | 4 1953 (0) 1af6 (0) 1a85 (0) 1a8e (0)\n006 2 1fab 1ea1 | 2 1ea1 (0) 1fab (0)\n007 0 | 0\n008 1 1d5b | 1 1d5b (0)\n============ DEPTH: 9 ==========================================\n009 1 1daa | 1 1daa (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 1 1dfc | 1 1dfc (0)\n========================================================================="}},"config":{"id":"d4b7c787981abec24353c7d496661692233797e3758189bf909a69fe87935bf6da0940daa4f12e81f20c5e88f70b472113688b71a0ae2f91a73ee0e6ff4c8591","private_key":"269f2cacd5854ad6634cd178738e910a093dbfb55bcf42ecd1f1d621f5829499","name":"node_d4b7c787981abec24353c7d496661692233797e3758189bf909a69fe87935bf6da0940daa4f12e81f20c5e88f70b472113688b71a0ae2f91a73ee0e6ff4c8591","services":["streamer"],"enable_msg_events":true,"port":63474},"up":true}},{"node":{"info":{"id":"9c30ad8c85adc7bb52ddcfab2e661cc3a854a689eaa59128d35129d02cd5b0f8da4a44cdd33934a8e2c8fab1760c16d6f2e1c5eb227dc819e85624e63343c069","name":"node_9c30ad8c85adc7bb52ddcfab2e661cc3a854a689eaa59128d35129d02cd5b0f8da4a44cdd33934a8e2c8fab1760c16d6f2e1c5eb227dc819e85624e63343c069","enode":"enode://9c30ad8c85adc7bb52ddcfab2e661cc3a854a689eaa59128d35129d02cd5b0f8da4a44cdd33934a8e2c8fab1760c16d6f2e1c5eb227dc819e85624e63343c069@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"kQ2mYtlETxYP9dk072Z/Hzqrofwydea6FS+ap+hbsk0=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 910da6\npopulation: 26 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 1dfd 3607 3799 34e4 | 122 34e4 (0) 3734 (0) 3799 (0) 3607 (0)\n001 3 e6b7 e406 e5d2 | 71 c3d8 (0) c301 (0) c409 (0) c60e (0)\n002 4 a6bd a105 a936 a9df | 30 b7aa (0) b40d (0) b45f (0) b30e (0)\n003 1 8a54 | 15 802e (0) 802f (0) 83d0 (0) 8564 (0)\n004 9 9f4c 9bc3 9b87 9a09 | 10 9f4c (0) 9bc3 (0) 9b87 (0) 9a09 (0)\n005 2 9493 9404 | 4 9641 (0) 9747 (0) 9493 (0) 9404 (0)\n============ DEPTH: 6 ==========================================\n006 2 92d5 93f8 | 2 92d5 (0) 93f8 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 1 9108 | 1 9108 (0)\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"9c30ad8c85adc7bb52ddcfab2e661cc3a854a689eaa59128d35129d02cd5b0f8da4a44cdd33934a8e2c8fab1760c16d6f2e1c5eb227dc819e85624e63343c069","private_key":"1f5c7e0be8cb7bacb5c28bf9283884761fcbe8c6b353b5c821d204938da6aab3","name":"node_9c30ad8c85adc7bb52ddcfab2e661cc3a854a689eaa59128d35129d02cd5b0f8da4a44cdd33934a8e2c8fab1760c16d6f2e1c5eb227dc819e85624e63343c069","services":["streamer"],"enable_msg_events":true,"port":63475},"up":true}},{"node":{"info":{"id":"c8b0dba45104fc7c7dff3ce078a0d3f5ade6198bb4656e2bee8076387929133e5ef2bd293b130a9d4f6a6974ca17e8b4a8f406d1219880f1e0f99c65c63af5a4","name":"node_c8b0dba45104fc7c7dff3ce078a0d3f5ade6198bb4656e2bee8076387929133e5ef2bd293b130a9d4f6a6974ca17e8b4a8f406d1219880f1e0f99c65c63af5a4","enode":"enode://c8b0dba45104fc7c7dff3ce078a0d3f5ade6198bb4656e2bee8076387929133e5ef2bd293b130a9d4f6a6974ca17e8b4a8f406d1219880f1e0f99c65c63af5a4@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"5AaU7fD3DCQq0gWL2U/awGdsGe+TBDgp4D98inoj8Xk=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: e40694\npopulation: 25 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 24f8 6f1c | 122 05a4 (0) 0536 (0) 07a6 (0) 00c8 (0)\n001 6 a75d a6bd a105 a9df | 63 b7aa (0) b40d (0) b45f (0) b30e (0)\n002 2 d1bc d07c | 33 c3d8 (0) c301 (0) c409 (0) c60e (0)\n003 1 f97e | 13 f6a6 (0) f293 (0) f2b2 (0) f2f5 (0)\n004 5 ebe8 ebc9 e9fa ecff | 12 ee3f (0) ee52 (0) eee1 (0) efdd (0)\n005 1 e31e | 4 e190 (0) e255 (0) e3d8 (0) e31e (0)\n006 2 e724 e6b7 | 2 e724 (0) e6b7 (0)\n007 3 e54d e56c e5d2 | 3 e54d (0) e56c (0) e5d2 (0)\n============ DEPTH: 8 ==========================================\n008 2 e4d6 e4e9 | 2 e4d6 (0) e4e9 (0)\n009 1 e469 | 1 e469 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"c8b0dba45104fc7c7dff3ce078a0d3f5ade6198bb4656e2bee8076387929133e5ef2bd293b130a9d4f6a6974ca17e8b4a8f406d1219880f1e0f99c65c63af5a4","private_key":"975ccce3cea6896e2dc7fb2fb8399b56deea3eac98f96dfe331602f06386ebe2","name":"node_c8b0dba45104fc7c7dff3ce078a0d3f5ade6198bb4656e2bee8076387929133e5ef2bd293b130a9d4f6a6974ca17e8b4a8f406d1219880f1e0f99c65c63af5a4","services":["streamer"],"enable_msg_events":true,"port":63476},"up":true}},{"node":{"info":{"id":"ff1e34fd51953ed641b431aa657da21cb4c81d23e4eaa13c9cce526f1f1b34593d41f9b87a0e10387fe400c623638677c0efab15dbd1014a0ccc11f9ec92c417","name":"node_ff1e34fd51953ed641b431aa657da21cb4c81d23e4eaa13c9cce526f1f1b34593d41f9b87a0e10387fe400c623638677c0efab15dbd1014a0ccc11f9ec92c417","enode":"enode://ff1e34fd51953ed641b431aa657da21cb4c81d23e4eaa13c9cce526f1f1b34593d41f9b87a0e10387fe400c623638677c0efab15dbd1014a0ccc11f9ec92c417@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"bxxIRT4b+5xHTX+IjYxDfHXbVp4skAhnxOrz5lBIR6o=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 6f1c48\npopulation: 17 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 a1f1 a9df e406 | 134 b7aa (0) b40d (0) b45f (0) b049 (0)\n001 4 1dfd 3054 3ab2 24f8 | 72 05a4 (0) 0536 (0) 07a6 (0) 00c8 (0)\n002 2 47a8 56bb | 31 48ec (0) 48df (0) 4b70 (0) 4bf8 (0)\n003 2 7299 7ec4 | 10 7ec4 (0) 7e45 (0) 7aef (0) 7810 (0)\n004 3 60bc 6701 67ee | 5 65a6 (0) 6701 (0) 67ee (0) 63de (0)\n============ DEPTH: 5 ==========================================\n005 2 6923 69d8 | 2 6923 (0) 69d8 (0)\n006 1 6caa | 1 6caa (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"ff1e34fd51953ed641b431aa657da21cb4c81d23e4eaa13c9cce526f1f1b34593d41f9b87a0e10387fe400c623638677c0efab15dbd1014a0ccc11f9ec92c417","private_key":"381480a705e57052adb222beb50053c41122d1c2c10b111a16abfc01e2314d28","name":"node_ff1e34fd51953ed641b431aa657da21cb4c81d23e4eaa13c9cce526f1f1b34593d41f9b87a0e10387fe400c623638677c0efab15dbd1014a0ccc11f9ec92c417","services":["streamer"],"enable_msg_events":true,"port":63477},"up":true}},{"node":{"info":{"id":"a78f18691e0dbf3c08fe9d7dec188e6a05a93833432fb99eb2b3924ab0bde7a44db2a102a65544bbdc4fb61bc3a3d569230d9843a335bf619167fb045d78ab3c","name":"node_a78f18691e0dbf3c08fe9d7dec188e6a05a93833432fb99eb2b3924ab0bde7a44db2a102a65544bbdc4fb61bc3a3d569230d9843a335bf619167fb045d78ab3c","enode":"enode://a78f18691e0dbf3c08fe9d7dec188e6a05a93833432fb99eb2b3924ab0bde7a44db2a102a65544bbdc4fb61bc3a3d569230d9843a335bf619167fb045d78ab3c@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"qd/O03uY0d+ruW5caPB0TGFThTKKpGmvFvvPjyjSBi0=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: a9dfce\npopulation: 22 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 56bb 7299 6f1c | 122 0536 (0) 05a4 (0) 07a6 (0) 00c8 (0)\n001 2 e406 e5d2 | 71 c3d8 (0) c301 (0) c409 (0) c60e (0)\n002 2 9918 910d | 33 802e (0) 802f (0) 83d0 (0) 8434 (0)\n003 3 b049 b391 bbcb | 13 b7aa (0) b40d (0) b45f (0) b049 (0)\n004 8 a6bd a478 a317 a3f2 | 12 a478 (0) a75d (0) a6bd (0) a317 (0)\n005 2 af8f ac62 | 2 af8f (0) ac62 (0)\n============ DEPTH: 6 ==========================================\n006 1 aa78 | 1 aa78 (0)\n007 0 | 0\n008 1 a936 | 1 a936 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"a78f18691e0dbf3c08fe9d7dec188e6a05a93833432fb99eb2b3924ab0bde7a44db2a102a65544bbdc4fb61bc3a3d569230d9843a335bf619167fb045d78ab3c","private_key":"22c94340e76bf6f9d70e933f2b3cc96d24f64282bc3d4a61621712e78500fead","name":"node_a78f18691e0dbf3c08fe9d7dec188e6a05a93833432fb99eb2b3924ab0bde7a44db2a102a65544bbdc4fb61bc3a3d569230d9843a335bf619167fb045d78ab3c","services":["streamer"],"enable_msg_events":true,"port":63478},"up":true}},{"node":{"info":{"id":"e67e495385e7cacfe659b40d1ba94d4b1ff55eada70a4d9740a9e452fbf221672bd0a897b940e2a6bed71e2a16867fe45bf0ea0015435ac6d815690e263b1899","name":"node_e67e495385e7cacfe659b40d1ba94d4b1ff55eada70a4d9740a9e452fbf221672bd0a897b940e2a6bed71e2a16867fe45bf0ea0015435ac6d815690e263b1899","enode":"enode://e67e495385e7cacfe659b40d1ba94d4b1ff55eada70a4d9740a9e452fbf221672bd0a897b940e2a6bed71e2a16867fe45bf0ea0015435ac6d815690e263b1899@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"5dIwJK2eXciRX40xQo6bPWLxxIQ+J2RR8X67dm0GtFY=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: e5d230\npopulation: 24 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 24f8 | 122 44c8 (0) 44b7 (0) 464b (0) 47a8 (0)\n001 5 910d 9918 a6bd a105 | 63 802e (0) 802f (0) 83d0 (0) 853b (0)\n002 2 d1bc d07c | 33 c3d8 (0) c301 (0) c409 (0) c60e (0)\n003 1 f97e | 13 f6a6 (0) f2f5 (0) f2b2 (0) f293 (0)\n004 5 ebe8 ebc9 e9fa ecff | 12 eee1 (0) ee3f (0) ee52 (0) efc1 (0)\n005 2 e190 e31e | 4 e190 (0) e255 (0) e3d8 (0) e31e (0)\n006 2 e724 e6b7 | 2 e724 (0) e6b7 (0)\n007 4 e4d6 e4e9 e469 e406 | 4 e4d6 (0) e4e9 (0) e469 (0) e406 (0)\n============ DEPTH: 8 ==========================================\n008 2 e54d e56c | 2 e54d (0) e56c (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"e67e495385e7cacfe659b40d1ba94d4b1ff55eada70a4d9740a9e452fbf221672bd0a897b940e2a6bed71e2a16867fe45bf0ea0015435ac6d815690e263b1899","private_key":"9b0568309c2ef3f512d43d9016f801f55741346b5f56da355dfe5dc54d652821","name":"node_e67e495385e7cacfe659b40d1ba94d4b1ff55eada70a4d9740a9e452fbf221672bd0a897b940e2a6bed71e2a16867fe45bf0ea0015435ac6d815690e263b1899","services":["streamer"],"enable_msg_events":true,"port":63479},"up":true}},{"node":{"info":{"id":"aacff366e601e072a2113add9020e19b6612f3e85b6e607fdc8cc1b6991f43be0b1f835ed3dc41d1f2b3e0caf7fac252c8eb4c150667d48207fa92ea5f0a7455","name":"node_aacff366e601e072a2113add9020e19b6612f3e85b6e607fdc8cc1b6991f43be0b1f835ed3dc41d1f2b3e0caf7fac252c8eb4c150667d48207fa92ea5f0a7455","enode":"enode://aacff366e601e072a2113add9020e19b6612f3e85b6e607fdc8cc1b6991f43be0b1f835ed3dc41d1f2b3e0caf7fac252c8eb4c150667d48207fa92ea5f0a7455@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"JPh/2JqKq67gUDOgo+78Acy7W7xqU9YV7zT2RqRrAVY=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 24f87f\npopulation: 27 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 7 9918 a6bd a105 ebc9 | 134 802e (0) 802f (0) 83d0 (0) 853b (0)\n001 4 47a8 56bb 7299 6f1c | 50 48ec (0) 48df (0) 4b70 (0) 4bf8 (0)\n002 2 1dfd 0ca9 | 37 05a4 (0) 0536 (0) 07a6 (0) 00c8 (0)\n003 4 34e4 3054 3baa 3ab2 | 20 3799 (0) 3734 (0) 3607 (0) 3658 (0)\n004 6 293f 2e3b 2f1f 2f23 | 10 2a7d (0) 2940 (0) 293f (0) 2e3b (0)\n============ DEPTH: 5 ==========================================\n005 3 208e 2220 2224 | 3 208e (0) 2220 (0) 2224 (0)\n006 1 2737 | 1 2737 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"aacff366e601e072a2113add9020e19b6612f3e85b6e607fdc8cc1b6991f43be0b1f835ed3dc41d1f2b3e0caf7fac252c8eb4c150667d48207fa92ea5f0a7455","private_key":"8ee8a33f33bc96603d61297c73e11d545ac229d887345e12f9fe834c7532e648","name":"node_aacff366e601e072a2113add9020e19b6612f3e85b6e607fdc8cc1b6991f43be0b1f835ed3dc41d1f2b3e0caf7fac252c8eb4c150667d48207fa92ea5f0a7455","services":["streamer"],"enable_msg_events":true,"port":63480},"up":true}},{"node":{"info":{"id":"2f903b2fd4f9432b7d91b5c3e4c7ee3cb9c56fe7efc4baff0edd06fc75e4b7492f2c3c929755746df59c9f95d437a12ba40ac138d08f5bc7aa091f49f3b852c2","name":"node_2f903b2fd4f9432b7d91b5c3e4c7ee3cb9c56fe7efc4baff0edd06fc75e4b7492f2c3c929755746df59c9f95d437a12ba40ac138d08f5bc7aa091f49f3b852c2","enode":"enode://2f903b2fd4f9432b7d91b5c3e4c7ee3cb9c56fe7efc4baff0edd06fc75e4b7492f2c3c929755746df59c9f95d437a12ba40ac138d08f5bc7aa091f49f3b852c2@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"oQXJ7BeJ2ZxZ8jJX9j4EjAySPjdI015hCMjAqNEObsE=","hive":"\n=========================================================================\nTue Apr 10 09:58:24 UTC 2018 KΛÐΞMLIΛ hive: queen's address: a105c9\npopulation: 21 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 7299 24f8 | 122 48ec (0) 48df (0) 4b70 (0) 4bf8 (0)\n001 3 e6b7 e406 e5d2 | 71 c3d8 (0) c301 (0) c409 (0) c60e (0)\n002 2 910d 9918 | 33 802f (0) 802e (0) 83d0 (0) 86d3 (0)\n003 2 b049 bbcb | 13 b40d (0) b45f (0) b7aa (0) b30e (0)\n004 2 a936 a9df | 5 af8f (0) ac62 (0) aa78 (0) a936 (0)\n005 3 a478 a6bd a75d | 3 a478 (0) a75d (0) a6bd (0)\n006 2 a317 a3f2 | 2 a317 (0) a3f2 (0)\n007 3 a077 a0e4 a0c9 | 4 a077 (0) a011 (0) a0e4 (0) a0c9 (0)\n============ DEPTH: 8 ==========================================\n008 2 a1b6 a1f1 | 2 a1b6 (0) a1f1 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"2f903b2fd4f9432b7d91b5c3e4c7ee3cb9c56fe7efc4baff0edd06fc75e4b7492f2c3c929755746df59c9f95d437a12ba40ac138d08f5bc7aa091f49f3b852c2","private_key":"105fa3b2d400eefda08235ac7c0db7af48667dd5a51b8d001d39e06753e93872","name":"node_2f903b2fd4f9432b7d91b5c3e4c7ee3cb9c56fe7efc4baff0edd06fc75e4b7492f2c3c929755746df59c9f95d437a12ba40ac138d08f5bc7aa091f49f3b852c2","services":["streamer"],"enable_msg_events":true,"port":63481},"up":true}}],"conns":[{"one":"57fb1bb32bb2b1a87e44c6a7557e9c47c2032d107bcb0e34acd9ffd54d5d3df5701232db16f62f7549ba2721021898b03160b1dc5201e79606648c1dbc4a373b","other":"7f357b8d81bc2e5c6fcb081f23a42b3e2439f050d45c45851994a268d1c71fcb1f39f8c3f75ce921d3fbf80fc0e73f0b9609d72001dc4a6b65b526d312a4f43a","up":false},{"one":"54b3c57a4adf4dbaf31b85ed1b8dccd6249faa16dd96dd230189f47f57970caeed36627cc8e1b0794707418d580f5bd6001c07be6a79216695f1253db24926bb","other":"df4c3505e09e1baa88470117b964e758c94f77a4546489ab5ab7f4aebfdce424729ace8867475715fb68f05c66c9674a5767549e266c4fadd1c703ddd735908f","up":true},{"one":"76cbf9fc0f3517fb615fa96104780218e85d064ee5a1d518f3b78f4dbebf144df38c427445fdd6c9b436489c00ff9497d747a8fd70f380f95601d59e52e021e8","other":"e023a51c5bd26e1754d6461345143e94baeac799947579ec7adeccd105de39f85afbceeb5037cfc0b820b9f4446433f034d9e7de7326d45df5a967a8099dbb10","up":true},{"one":"e023a51c5bd26e1754d6461345143e94baeac799947579ec7adeccd105de39f85afbceeb5037cfc0b820b9f4446433f034d9e7de7326d45df5a967a8099dbb10","other":"68cc8b9a995eef6170abf88bd5fedca06ffcc8d75f247f6041c13e7dfd292727ebda1ff86b776e33b6634355c55e0f8c22fcdb5f9a6e2f22fe1af7854c3b4273","up":true},{"one":"68cc8b9a995eef6170abf88bd5fedca06ffcc8d75f247f6041c13e7dfd292727ebda1ff86b776e33b6634355c55e0f8c22fcdb5f9a6e2f22fe1af7854c3b4273","other":"54b3c57a4adf4dbaf31b85ed1b8dccd6249faa16dd96dd230189f47f57970caeed36627cc8e1b0794707418d580f5bd6001c07be6a79216695f1253db24926bb","up":true},{"one":"7f357b8d81bc2e5c6fcb081f23a42b3e2439f050d45c45851994a268d1c71fcb1f39f8c3f75ce921d3fbf80fc0e73f0b9609d72001dc4a6b65b526d312a4f43a","other":"cb94a8270d0050378116b5815ff17dafbe20f5303839c4fd57b981d4687a4b145e4bccec7e9af9b9475005930148ffbfa97781a0762c8e9f352dc95565fc8732","up":false},{"one":"2f903b2fd4f9432b7d91b5c3e4c7ee3cb9c56fe7efc4baff0edd06fc75e4b7492f2c3c929755746df59c9f95d437a12ba40ac138d08f5bc7aa091f49f3b852c2","other":"57fb1bb32bb2b1a87e44c6a7557e9c47c2032d107bcb0e34acd9ffd54d5d3df5701232db16f62f7549ba2721021898b03160b1dc5201e79606648c1dbc4a373b","up":true},{"one":"df4c3505e09e1baa88470117b964e758c94f77a4546489ab5ab7f4aebfdce424729ace8867475715fb68f05c66c9674a5767549e266c4fadd1c703ddd735908f","other":"24662a43944228e4ff74736bcf0a0a4f79c87ecfdb739225b2fc45110c11bfc38aaf2d09d98e5817477848e553f187ac5408bdb864518dfa7f5df542768828db","up":true},{"one":"24662a43944228e4ff74736bcf0a0a4f79c87ecfdb739225b2fc45110c11bfc38aaf2d09d98e5817477848e553f187ac5408bdb864518dfa7f5df542768828db","other":"27d9048707a89f1a61e44fdae523c0128f2a7050308bd3cfefa6c3e03040a0e22f11ab41275f22b8706e6695ab93320e2af35179d772581db5f49f960750f2f7","up":true},{"one":"27d9048707a89f1a61e44fdae523c0128f2a7050308bd3cfefa6c3e03040a0e22f11ab41275f22b8706e6695ab93320e2af35179d772581db5f49f960750f2f7","other":"ea57884dd42aec5a76eab43483bf7c4ae2c19eebf365013731de64494d10a3b4cfe34c86c79437f9012bc8cf6bd761435eefadec17600f4b9e4bc234532d6282","up":true},{"one":"beec648d79437a5d7b4140ced45d82d035c6f64f9c67c58386703811d97c3846787eaf274d2298df809475f0b7519df696563cb8e9a5fb0a9cc419ab13fa8d41","other":"c73d088ade8756c74832c73542bcdb3e52f670f7a74ad3a7eac2a9e3ece6bd081f782a8e1d3f9a40b9aa9201509110f37fc57fcb10ee1ef3ef07b7eab019782e","up":true},{"one":"c73d088ade8756c74832c73542bcdb3e52f670f7a74ad3a7eac2a9e3ece6bd081f782a8e1d3f9a40b9aa9201509110f37fc57fcb10ee1ef3ef07b7eab019782e","other":"62dab8b21640e1b44dea452dd7e7de93f27a44840da72d56b11aa96e8463f3a4bb15e75a954d19fc897ae0030b16181d271b79d8198b7cffcddaa9ffcfdcce73","up":true},{"one":"62dab8b21640e1b44dea452dd7e7de93f27a44840da72d56b11aa96e8463f3a4bb15e75a954d19fc897ae0030b16181d271b79d8198b7cffcddaa9ffcfdcce73","other":"9e621c3eb534855ca292efa27a3fbc89b4f05c80a4bc65bcff2f14ff28ef43cbe14137d2fddc6fe2658bb06947d918476b479dde71469b8680e5d8a7a01619b5","up":true},{"one":"9e621c3eb534855ca292efa27a3fbc89b4f05c80a4bc65bcff2f14ff28ef43cbe14137d2fddc6fe2658bb06947d918476b479dde71469b8680e5d8a7a01619b5","other":"afe5b217dc512eee45575c189826ee5640d11a0ac9e8e4b03e9e62e6cf6df9de500bc8a36cb7d82a2280ce184409164f1772cc5c9e59ad04361522d2b8c364e0","up":false},{"one":"afe5b217dc512eee45575c189826ee5640d11a0ac9e8e4b03e9e62e6cf6df9de500bc8a36cb7d82a2280ce184409164f1772cc5c9e59ad04361522d2b8c364e0","other":"db8ba71afeaea1f2964e8978a6eceeb9efa3958424424022213c8193443f8d5afd18490afa954c76360c681404809c7cfaf7e4ebd8bd1a42d403f7f1915b0d29","up":true},{"one":"db8ba71afeaea1f2964e8978a6eceeb9efa3958424424022213c8193443f8d5afd18490afa954c76360c681404809c7cfaf7e4ebd8bd1a42d403f7f1915b0d29","other":"2f1967b4410ea2ea8fbaf46771ba82c2846d00aecdb6f873aceae33ab38f72d0a2c2dc6046d3034f514efd090d42011d48e9ab0cb4e3caa2b49a96ef732215a1","up":true},{"one":"2f1967b4410ea2ea8fbaf46771ba82c2846d00aecdb6f873aceae33ab38f72d0a2c2dc6046d3034f514efd090d42011d48e9ab0cb4e3caa2b49a96ef732215a1","other":"a99852c5bf08ea4713af9cade5343d1259bfb90401aca7fcff18c58cd56a98804dd16c61fea71039c0ac31b9bbbb9dc5aeaf0c2f074d3365e88d17031802d636","up":true},{"one":"a99852c5bf08ea4713af9cade5343d1259bfb90401aca7fcff18c58cd56a98804dd16c61fea71039c0ac31b9bbbb9dc5aeaf0c2f074d3365e88d17031802d636","other":"4e68553db7be307b8379e8bec383b5c92e4b23debcefca575d24504e2062618f74c26e60e0d9e47f096997a7f841e2c32c994124f495ef3352ef964b33fd3a51","up":true},{"one":"4e68553db7be307b8379e8bec383b5c92e4b23debcefca575d24504e2062618f74c26e60e0d9e47f096997a7f841e2c32c994124f495ef3352ef964b33fd3a51","other":"a608a746f46d4b2e9267c65283380d6d6cb8885a64428fb77df9934bcf4dd1723587ee7c8f4a642dce266a12a6a4cf4e5c6db7fa1024158425a6753e7ab7264c","up":true},{"one":"a608a746f46d4b2e9267c65283380d6d6cb8885a64428fb77df9934bcf4dd1723587ee7c8f4a642dce266a12a6a4cf4e5c6db7fa1024158425a6753e7ab7264c","other":"fde7705f5013c3b6b76a35505c1e3d57c033a337f2a71e912ec3a3d2da8e113bd7c36d94908357e9f7654660621f647ad8c66b0126dfe91dbfa3b8c7bd2183d3","up":true},{"one":"0cacda5560faff9d20e29a0625d3cd340ec075f198a50ab8b79338cee0e0db84c7c7e71042fd8c8f73e507b570de5d26c39473136b575f0167625a1168309ec5","other":"88d5c5fe61ee1e6fa5878e0eaa13bdabaa0ec3d38a5d25b95a467da7627424f25fb5d30535aa0a5ad01c16fe2598dbf570b78cc152a7f4ef66d46fc9ae43592f","up":true},{"one":"fde7705f5013c3b6b76a35505c1e3d57c033a337f2a71e912ec3a3d2da8e113bd7c36d94908357e9f7654660621f647ad8c66b0126dfe91dbfa3b8c7bd2183d3","other":"3dfd733dde9414af916625ab981777ff1ad7ca0f6d1e4e7d9e2739969e21182fd13d85e281868653e7325b20069356b11524b54143c47fd3955a911cf7325ad4","up":true},{"one":"88d5c5fe61ee1e6fa5878e0eaa13bdabaa0ec3d38a5d25b95a467da7627424f25fb5d30535aa0a5ad01c16fe2598dbf570b78cc152a7f4ef66d46fc9ae43592f","other":"80d997b87856099d844187d3d1fa40846ded652a62c1611b35919c2543915b64ff62476636488556f678e436ea26fcc40db7c6b6bbcb78f590d61c1ff0e424b5","up":true},{"one":"3dfd733dde9414af916625ab981777ff1ad7ca0f6d1e4e7d9e2739969e21182fd13d85e281868653e7325b20069356b11524b54143c47fd3955a911cf7325ad4","other":"5142eea687de4248b2184e9896b245563117648e7a156255d9a7ae730313d5d383db3be1125b5accd7e743c2a5d8c3289ec559ef7cbb803b9e82cd49bb213d9f","up":true},{"one":"80d997b87856099d844187d3d1fa40846ded652a62c1611b35919c2543915b64ff62476636488556f678e436ea26fcc40db7c6b6bbcb78f590d61c1ff0e424b5","other":"6bf9fb6a25521c16c2ebeb6203d046d7dd40f29cc2ddb067c0222ef56d7012d2ee5d037f71f6668ea56767610b2a54c144aed74b7f68d06993cbd52fa1dc7630","up":true},{"one":"5142eea687de4248b2184e9896b245563117648e7a156255d9a7ae730313d5d383db3be1125b5accd7e743c2a5d8c3289ec559ef7cbb803b9e82cd49bb213d9f","other":"b597c9ba4da20c49fc4ba019571321d2579588636cdaceb9f225706574970adbf4771dcf186b1decd4e14cd5d257e30a36ca829829598c1775902201ad9793e2","up":true},{"one":"6bf9fb6a25521c16c2ebeb6203d046d7dd40f29cc2ddb067c0222ef56d7012d2ee5d037f71f6668ea56767610b2a54c144aed74b7f68d06993cbd52fa1dc7630","other":"23f9bdc82efbf57d3d40a1f2617d0311678fb4a3d6a50cb7e608c649bb618124a76c7ffd17387de963e1cd28d2bd5a61c98613f6e009a8a2a90d989827b35de0","up":false},{"one":"b597c9ba4da20c49fc4ba019571321d2579588636cdaceb9f225706574970adbf4771dcf186b1decd4e14cd5d257e30a36ca829829598c1775902201ad9793e2","other":"72e30d4562673c5c8fb03709d93f73322747858d723b7eb5ef2fbb88e0331252946b7e93ffe434fcb599c4fff57800afb29e6c60a719f18f49dba541c3591c6e","up":true},{"one":"23f9bdc82efbf57d3d40a1f2617d0311678fb4a3d6a50cb7e608c649bb618124a76c7ffd17387de963e1cd28d2bd5a61c98613f6e009a8a2a90d989827b35de0","other":"f6ca39b3ad803e99f4e4e9cf759fff6abdf06e6972bdbe524f6eb930c669d6f0e9b91f3de9df394b0d661b068273861391bdbac948ad911351c48cf02f874db6","up":true},{"one":"72e30d4562673c5c8fb03709d93f73322747858d723b7eb5ef2fbb88e0331252946b7e93ffe434fcb599c4fff57800afb29e6c60a719f18f49dba541c3591c6e","other":"eaca77d20c4ad6b87649eba21b750a4b1a2c575e06bc42679d18fce16fea15212e9a7408c16f3b24d8dfd1e397314637e72e292845d09534a39035bd9203ee9e","up":false},{"one":"f6ca39b3ad803e99f4e4e9cf759fff6abdf06e6972bdbe524f6eb930c669d6f0e9b91f3de9df394b0d661b068273861391bdbac948ad911351c48cf02f874db6","other":"385168340139236a0e0f537fa693122db9fa02a377c96f31aae54718e92624fc0288164877e63616651565e055c53f7074ab2fdd18a837da6faf644941305bf0","up":true},{"one":"eaca77d20c4ad6b87649eba21b750a4b1a2c575e06bc42679d18fce16fea15212e9a7408c16f3b24d8dfd1e397314637e72e292845d09534a39035bd9203ee9e","other":"d3105ede6c21bc643d523afcd1309a5dcf03f70797a92f167c3a19f86ae98882fe1a9d4094d7a3dee4a0833b8075b6c3e9aaa7f4879dc47bb388c3ae85522288","up":true},{"one":"385168340139236a0e0f537fa693122db9fa02a377c96f31aae54718e92624fc0288164877e63616651565e055c53f7074ab2fdd18a837da6faf644941305bf0","other":"9194a3a4c8f3235203e48bdb10902d958d26c342805ea6365af9711213536509719d917c694f9a4fbdde6889a4c92299a5301f0275bda4dbcd2541b5bff5b271","up":true},{"one":"9194a3a4c8f3235203e48bdb10902d958d26c342805ea6365af9711213536509719d917c694f9a4fbdde6889a4c92299a5301f0275bda4dbcd2541b5bff5b271","other":"c2705ee7238ef9305e4da196653cde707649435a1e8b5b797d164e5ca06184a77af5bd7fa938c995fdfcbce724fa7eca3d908ee34891ab62cc6dfd411c3fa1da","up":true},{"one":"c2705ee7238ef9305e4da196653cde707649435a1e8b5b797d164e5ca06184a77af5bd7fa938c995fdfcbce724fa7eca3d908ee34891ab62cc6dfd411c3fa1da","other":"bf4ff51cc3d9a9d8cefd7e346ce1384d06450228a6086fe12fb0c60fec54bb6478f090bb638fbdbf8f41f7bc6420cd8a5c8b1b8566229b6851167375ef412f46","up":true},{"one":"d3105ede6c21bc643d523afcd1309a5dcf03f70797a92f167c3a19f86ae98882fe1a9d4094d7a3dee4a0833b8075b6c3e9aaa7f4879dc47bb388c3ae85522288","other":"6f60ef501b41f9049419b033ae8d793a18067bdcd60347537b0dc3873bdd9a2d10d24909cca7c39781765746128c2165596f6537a94f58279523faee71f9c51d","up":false},{"one":"bf4ff51cc3d9a9d8cefd7e346ce1384d06450228a6086fe12fb0c60fec54bb6478f090bb638fbdbf8f41f7bc6420cd8a5c8b1b8566229b6851167375ef412f46","other":"f33d1f3e460574706ac1c7fc9ebb4683b173496ce3e80017d1c3521bca03d5a41a9c7a6cde8347d2238917b7cc58cab000ce7ccf6bb408561015a2ecbe613408","up":true},{"one":"f33d1f3e460574706ac1c7fc9ebb4683b173496ce3e80017d1c3521bca03d5a41a9c7a6cde8347d2238917b7cc58cab000ce7ccf6bb408561015a2ecbe613408","other":"083e67bb19e30d14e4df6d2483367d6659d9b56744d53d9cf7fd15954c327e1bc88a5d0db8833634e1dad7209164451f8934b59f76b5990059261abfd650519a","up":true},{"one":"083e67bb19e30d14e4df6d2483367d6659d9b56744d53d9cf7fd15954c327e1bc88a5d0db8833634e1dad7209164451f8934b59f76b5990059261abfd650519a","other":"0c14dd51a56130c51009e3ce47c96b2afef26b7e86cfca65d8a9bae1abef13b3a7a192b422d894c39e24ab00be412d166a3571cc259ff4462d4ad8925a153766","up":true},{"one":"0c14dd51a56130c51009e3ce47c96b2afef26b7e86cfca65d8a9bae1abef13b3a7a192b422d894c39e24ab00be412d166a3571cc259ff4462d4ad8925a153766","other":"855bdf057f4a6b095e2000ada199447b5b4f2f8d78d2ecbaa0ff1fbf761788870ee999266ad3b26efa02be1a46a4d92ac0debb85a2ceab3442394ee7d99e5355","up":true},{"one":"855bdf057f4a6b095e2000ada199447b5b4f2f8d78d2ecbaa0ff1fbf761788870ee999266ad3b26efa02be1a46a4d92ac0debb85a2ceab3442394ee7d99e5355","other":"b53078000796f1cdb04dfeac424d5e3e37e30f00bd5bebf9a9ea0525c62917612b3a8f508df6bea59e3c7e4cd1aa530841f9a8af54e44f5617a13dee2c6ff007","up":true},{"one":"6f60ef501b41f9049419b033ae8d793a18067bdcd60347537b0dc3873bdd9a2d10d24909cca7c39781765746128c2165596f6537a94f58279523faee71f9c51d","other":"453779010ed7c59761da47ccd8869d3fa8349795e57edb9eea416c0712301ea622c7683858e309d19ab137ddb0edef161d0d00a361abeecf0628c3ffabc629ea","up":false},{"one":"b53078000796f1cdb04dfeac424d5e3e37e30f00bd5bebf9a9ea0525c62917612b3a8f508df6bea59e3c7e4cd1aa530841f9a8af54e44f5617a13dee2c6ff007","other":"5526d86ba9df651091d88460a9bedb9cedb957d452a635e1db46b9fed78082022adec0047cd7485956a4ecbb0e18107595de0de3c35242527cd302bf74a19260","up":true},{"one":"453779010ed7c59761da47ccd8869d3fa8349795e57edb9eea416c0712301ea622c7683858e309d19ab137ddb0edef161d0d00a361abeecf0628c3ffabc629ea","other":"e2a27dcdee1f89fa362a85c4397840cd8be4ad8d1b9ccb23188c303bcab7619f38772f71385922d090390973b62fb8249efc103f71bc761041bcb3880ec0b935","up":true},{"one":"5526d86ba9df651091d88460a9bedb9cedb957d452a635e1db46b9fed78082022adec0047cd7485956a4ecbb0e18107595de0de3c35242527cd302bf74a19260","other":"a7378ee34876af17c6cd94a69b6b741ec7891ff5375bc4241d48608d047455ed48e6baae80ee88d4710c69ae615cf195cee26c94b54de1bb935628ce1e3a723a","up":true},{"one":"e2a27dcdee1f89fa362a85c4397840cd8be4ad8d1b9ccb23188c303bcab7619f38772f71385922d090390973b62fb8249efc103f71bc761041bcb3880ec0b935","other":"97981f4b825620985b746c85824d7a4d307ee25d60a72c2b7de4b1d4f3b1c002652adc3045842d350f849789e410a0357a0b42fa637a1b4fc9d39e44f8a674d7","up":true},{"one":"a7378ee34876af17c6cd94a69b6b741ec7891ff5375bc4241d48608d047455ed48e6baae80ee88d4710c69ae615cf195cee26c94b54de1bb935628ce1e3a723a","other":"3e488a7208ce0e097ce47fc6651a13e95cae137d1a054a09b04d2f59d45faa2594a8c3b395e77ad1a3c2edcd827dda73c0c97dbaa6d9519a79184a0aca01ac4b","up":true},{"one":"97981f4b825620985b746c85824d7a4d307ee25d60a72c2b7de4b1d4f3b1c002652adc3045842d350f849789e410a0357a0b42fa637a1b4fc9d39e44f8a674d7","other":"fe62314839c93d2f6e3aee984d5f0b321897c6f39e66800d3de8b773baf6f19e0a03cae025df512aea8d5f1b667b6dbb15c192a90a76d3031c14e33e5c16c4f7","up":true},{"one":"3e488a7208ce0e097ce47fc6651a13e95cae137d1a054a09b04d2f59d45faa2594a8c3b395e77ad1a3c2edcd827dda73c0c97dbaa6d9519a79184a0aca01ac4b","other":"07f25fdeab2b44b2e92fc80fca7de9e4a8547d27a98a54593b3395c270a9ff3f2a5da62a2e8531ce86359f0cdc5b6513b773dfd64cce1b83e47065d9760a2c7e","up":true},{"one":"fe62314839c93d2f6e3aee984d5f0b321897c6f39e66800d3de8b773baf6f19e0a03cae025df512aea8d5f1b667b6dbb15c192a90a76d3031c14e33e5c16c4f7","other":"c903c5ee3d9cd65bea3ea777e39282c33e1349d945411fb2f16321bf582c2f400956a98fbafe5873fc5f6f6a9a051df5da7e94cbd340f935abe80f91e79ef875","up":true},{"one":"07f25fdeab2b44b2e92fc80fca7de9e4a8547d27a98a54593b3395c270a9ff3f2a5da62a2e8531ce86359f0cdc5b6513b773dfd64cce1b83e47065d9760a2c7e","other":"0f9f7e2dce4ca266c3ac0ec3a8854200b54487f5308e3db418461aeb5f67c81d332619b6441b468e480941e63100ed1b263e7adc20689dc3dcda578bfca538fa","up":true},{"one":"c903c5ee3d9cd65bea3ea777e39282c33e1349d945411fb2f16321bf582c2f400956a98fbafe5873fc5f6f6a9a051df5da7e94cbd340f935abe80f91e79ef875","other":"5420da16f7ed5de6b498dbc9a83b7e92e1f9900a6d04ef7351a0bfdfd442b98a5634f28fcea32ba3f3166d21c8ff5a39be70895b32acbdf7592d1d616a345a21","up":true},{"one":"0f9f7e2dce4ca266c3ac0ec3a8854200b54487f5308e3db418461aeb5f67c81d332619b6441b468e480941e63100ed1b263e7adc20689dc3dcda578bfca538fa","other":"a1560ce7c1f1d5972f027a8e9cff820611d84764aa067434a75b63887bc4268a259101486d34b7fe83dd735e799789986cd3e9b156c86ede598bd86af4454924","up":true},{"one":"b26f7c0113a5ae885f7c0e608aea7022a9c8bfc40c5643e60b2ba7343ff09c5be0bc08be34dde3c6b85fea192a46d4764770c12cbaa233df4231a1b99627ef9d","other":"829b074b70d757da6aa00f7bace3cf1b5d2d4eeadb7f370c1a85374a01a70b54ac53d747267e386f3b41e6d790fecdd6e74b8f89745501ee82439a66ea54443a","up":true},{"one":"829b074b70d757da6aa00f7bace3cf1b5d2d4eeadb7f370c1a85374a01a70b54ac53d747267e386f3b41e6d790fecdd6e74b8f89745501ee82439a66ea54443a","other":"302c37f28c69fdcf00b39ce0c0223de0d94cebc2c0b068315b95b76b5432573ead0656569441029ba9054d8d3d959fd8735e73913af5ce3f1132f8271fd437ef","up":true},{"one":"57b47f692f4d69a5d2c9c193680eb4ccb5a6c574662df0138504a549f3ea74f20c5b866ac4d9e76c4b49c83f5fd692ead928ea20dfcf643a11a1c1e841c0ec42","other":"2ddd49fae11d8bd2e7e75a481be267fa846f51cc1160bc326aeea51c542323ff444909de11e2731e835140bc0b1b32020e1e73fa652511a381222bf0aebc4081","up":true},{"one":"302c37f28c69fdcf00b39ce0c0223de0d94cebc2c0b068315b95b76b5432573ead0656569441029ba9054d8d3d959fd8735e73913af5ce3f1132f8271fd437ef","other":"4e95fb8943ef6502fa470870a7ace4ca11e18589bd2073167543a922317b35e40b5068934d07e56c8fdd23354dfad51fd2899db854f189841f02b5914cd97749","up":true},{"one":"2ddd49fae11d8bd2e7e75a481be267fa846f51cc1160bc326aeea51c542323ff444909de11e2731e835140bc0b1b32020e1e73fa652511a381222bf0aebc4081","other":"420b9c90584651c5a3fe3c16aa377444a321dca934f8a097d01a616554067feabebf2fdc8d2a25797f29a8fef30d5e2c82f8e85b20f509a880367b9b0ccdea47","up":true},{"one":"3d2df188704eeac09c8b291bf275a73888199a231c832c51dbc3d746968d4b51a7d5eae0c7c9b8c8e19f5e28d38c375e01abefa343f31dbe221deb837ab8a0df","other":"8f88c7ec044f758f29bd8d12a5170bd973aec8f6cddbf512b910c4b75a0fec09c5e198bcd65622037f897759db68da2328b4a7ca93585dc9cb62e46d2a6c0864","up":true},{"one":"4e95fb8943ef6502fa470870a7ace4ca11e18589bd2073167543a922317b35e40b5068934d07e56c8fdd23354dfad51fd2899db854f189841f02b5914cd97749","other":"807340e5fdf6c21a56ef2fd158c32e92201206ca85fcc147165a408f7a735964afd47c397e663610ac53870ae722c0317291732b0422f8aeedae783d9c730218","up":true},{"one":"420b9c90584651c5a3fe3c16aa377444a321dca934f8a097d01a616554067feabebf2fdc8d2a25797f29a8fef30d5e2c82f8e85b20f509a880367b9b0ccdea47","other":"5bf29c02f07faf7ae8e46389e1b98df4f5e88c9316b5151685e6ae7b4e622cf171ff09f996aaa8ad846643b3bfcbd1ad96cdc249afccce439bb5c55246b95801","up":true},{"one":"1bc1d6155ba35d29ea16938994e08df76ebd8f16bd180bd6a9b9d8798d0745889fe72d641dd78bd8ec13526929f7eb5aaa6a388430fa69033d6db581e53c6422","other":"e267e71c2dcdbe5a500b23444d2d4037ea15afba8f4f2b1c0e54a274450404fbee6fa5439f7cddf4ba1aa28fa93e434b01c239add58e30a5423ca3a481584d6b","up":true},{"one":"5bf29c02f07faf7ae8e46389e1b98df4f5e88c9316b5151685e6ae7b4e622cf171ff09f996aaa8ad846643b3bfcbd1ad96cdc249afccce439bb5c55246b95801","other":"e3c8a97a2d95dd543f9e2b41d9dce6256e284296f866f4f92e9925f8c7519dea23fd6d1a11153b93c10d6a32295e7b9bcc16024e690e4a0dc84fd25ee0f31b2c","up":true},{"one":"e98a08e8e3544727f5ee27f4465375a67ffba490fcdbfe7bfdc909f6b68bd279f776c65d38c2ccfc33079f852f76349c94d68fc6989c0d981f22333f036a4bb5","other":"cb310c0e86aa455d7c9af6394ae38561c901da30a51d7ccb7e66a09d9a8f192ae8caeff106043426d56397088f141c4e01e3b98f1ee583ffc7318b5f730f3ac7","up":true},{"one":"e3c8a97a2d95dd543f9e2b41d9dce6256e284296f866f4f92e9925f8c7519dea23fd6d1a11153b93c10d6a32295e7b9bcc16024e690e4a0dc84fd25ee0f31b2c","other":"7aaf7817b93aa6d2f50513791f9ad7629a901ed0dcb151189f44763f83423446b20ec79a48fa260cd9bc2907d5f0ad06b2c4c5e6d812f3d8876c8020ebe41019","up":true},{"one":"4b784f072b7c96c30612767425f552e30e45157e70139dfbe0ae4ff86dc31601adec60f8a3ad9747b02b5219073d8813af9b09d59eaf7ddb7ee24856aff6fa8f","other":"22010c9829626a6892258b09cb3f3edc3f21382fb487b5dbf0dd20e198e37e26134aab850e30337f398d1491b5126839aeb1953ec144bc19aeb889c832f67c6a","up":true},{"one":"7aaf7817b93aa6d2f50513791f9ad7629a901ed0dcb151189f44763f83423446b20ec79a48fa260cd9bc2907d5f0ad06b2c4c5e6d812f3d8876c8020ebe41019","other":"062e0ca43a1885c4a7ab2a5169790f9081e3e9a2dfa286b8cc592d5ccbf13d7a82b72d23361a19026d04fcf41b752ea320d98359d770aedfcee626e21c3494b3","up":true},{"one":"22010c9829626a6892258b09cb3f3edc3f21382fb487b5dbf0dd20e198e37e26134aab850e30337f398d1491b5126839aeb1953ec144bc19aeb889c832f67c6a","other":"043fe7085e8c90c18270f84dba5fab138e50216a1cf8d81a3794d156fad7fc81d1422aff169b244b13f91d73eebb5de464f97b1b93b3ad2a58959cff19238842","up":true},{"one":"062e0ca43a1885c4a7ab2a5169790f9081e3e9a2dfa286b8cc592d5ccbf13d7a82b72d23361a19026d04fcf41b752ea320d98359d770aedfcee626e21c3494b3","other":"f9ffe87c52ff4c22bd9696af32e0a9d34bb81fb84d9d8bf5aafe2ef9696e7b3d6460bf2a93aecb066133f53416bde841a02d6967bd06e3d4a714f3b2c123a947","up":true},{"one":"043fe7085e8c90c18270f84dba5fab138e50216a1cf8d81a3794d156fad7fc81d1422aff169b244b13f91d73eebb5de464f97b1b93b3ad2a58959cff19238842","other":"329145e75496cecb5f5c8f00313a52ddd8c0e8cd27ef1b2bc1b2b56e4d4089aaf5a7a3c4d9a40bdb92483fa05bd24d1cd0fd51883e30439dffa0fc855e1a7cd0","up":true},{"one":"8f88c7ec044f758f29bd8d12a5170bd973aec8f6cddbf512b910c4b75a0fec09c5e198bcd65622037f897759db68da2328b4a7ca93585dc9cb62e46d2a6c0864","other":"4314b0b04331973ed29a58843951f144ac3d09bd5d57b6cd9aaff9b73a7b2ec81e344a3e4ece462bd2081b837a06310e787ef3bb889dabad46fe7efd394c8342","up":true},{"one":"f9ffe87c52ff4c22bd9696af32e0a9d34bb81fb84d9d8bf5aafe2ef9696e7b3d6460bf2a93aecb066133f53416bde841a02d6967bd06e3d4a714f3b2c123a947","other":"bcf8e831821a5bca359fb824c7dc4d66906de82f3663a0a853d96880a8ca0bdddcceb1b66dd1f13f75ee20fde50fc9de545bc25767f228baee910e0dbfa8cc27","up":true},{"one":"329145e75496cecb5f5c8f00313a52ddd8c0e8cd27ef1b2bc1b2b56e4d4089aaf5a7a3c4d9a40bdb92483fa05bd24d1cd0fd51883e30439dffa0fc855e1a7cd0","other":"2a63d875e715c2a43302d32d86d30c7d7faed46c08a67bf488762637216b99dd87333a66df6d9f3a57df863b1f1a219ddbeebb9f3e92e523bd08540a195448ca","up":true},{"one":"bcf8e831821a5bca359fb824c7dc4d66906de82f3663a0a853d96880a8ca0bdddcceb1b66dd1f13f75ee20fde50fc9de545bc25767f228baee910e0dbfa8cc27","other":"3d2df188704eeac09c8b291bf275a73888199a231c832c51dbc3d746968d4b51a7d5eae0c7c9b8c8e19f5e28d38c375e01abefa343f31dbe221deb837ab8a0df","up":true},{"one":"cb310c0e86aa455d7c9af6394ae38561c901da30a51d7ccb7e66a09d9a8f192ae8caeff106043426d56397088f141c4e01e3b98f1ee583ffc7318b5f730f3ac7","other":"1090e9d89cb278a30063a5396d9ba795d3bbc237c76915a6fb7d23aa1822c8535d2fccc44cc8cd2acec68444c0bf1bdf5195ebb9f3cad8dac3d94a4d9c0e5309","up":true},{"one":"807340e5fdf6c21a56ef2fd158c32e92201206ca85fcc147165a408f7a735964afd47c397e663610ac53870ae722c0317291732b0422f8aeedae783d9c730218","other":"c9cd9dfb9f90a7948ac5a42c7bd63263f2eef6e1d85547559f7d2ecbf5f9cd1eab051b8e9e661b573c275d84091a44e73f6fc6bcc91dcdb674bd5d939190fc01","up":true},{"one":"e267e71c2dcdbe5a500b23444d2d4037ea15afba8f4f2b1c0e54a274450404fbee6fa5439f7cddf4ba1aa28fa93e434b01c239add58e30a5423ca3a481584d6b","other":"e98a08e8e3544727f5ee27f4465375a67ffba490fcdbfe7bfdc909f6b68bd279f776c65d38c2ccfc33079f852f76349c94d68fc6989c0d981f22333f036a4bb5","up":true},{"one":"a1560ce7c1f1d5972f027a8e9cff820611d84764aa067434a75b63887bc4268a259101486d34b7fe83dd735e799789986cd3e9b156c86ede598bd86af4454924","other":"e06a789a7f6988e1ba5e8358b6cd4292555c7f9f7f0dda6fc01cc26d24e49a8c1ad694423ad74aec6d80f4b99e2bedc49b6a5f2670744cedee3a3e1848e6dd07","up":true},{"one":"5420da16f7ed5de6b498dbc9a83b7e92e1f9900a6d04ef7351a0bfdfd442b98a5634f28fcea32ba3f3166d21c8ff5a39be70895b32acbdf7592d1d616a345a21","other":"f54335964d9b4eb9813eb05f40ef1c523bbf0faac5a04c4737467d590fb6b55c7fa1fc5d4d32c5491d8766b9be6fdfd3ebdb25c5ffe1719f36c86ddf87ae3a85","up":true},{"one":"ea57884dd42aec5a76eab43483bf7c4ae2c19eebf365013731de64494d10a3b4cfe34c86c79437f9012bc8cf6bd761435eefadec17600f4b9e4bc234532d6282","other":"3b570117addeec03c2694baf28e246f91907268fe665c6c90356120332794258ee57a60853c19e9fe25d042ca42a5be7fe0797d84199174de8132f1ef4a9349b","up":true},{"one":"3b570117addeec03c2694baf28e246f91907268fe665c6c90356120332794258ee57a60853c19e9fe25d042ca42a5be7fe0797d84199174de8132f1ef4a9349b","other":"0cacda5560faff9d20e29a0625d3cd340ec075f198a50ab8b79338cee0e0db84c7c7e71042fd8c8f73e507b570de5d26c39473136b575f0167625a1168309ec5","up":true},{"one":"f54335964d9b4eb9813eb05f40ef1c523bbf0faac5a04c4737467d590fb6b55c7fa1fc5d4d32c5491d8766b9be6fdfd3ebdb25c5ffe1719f36c86ddf87ae3a85","other":"40bdac599b00e9c41ad6476ee415c33d9c17c5aa672692c2404e523b29dc315da929a86874bed87fd9009871805d1dbf3098e7a817193e3b08a6eee66346da79","up":true},{"one":"40bdac599b00e9c41ad6476ee415c33d9c17c5aa672692c2404e523b29dc315da929a86874bed87fd9009871805d1dbf3098e7a817193e3b08a6eee66346da79","other":"b26f7c0113a5ae885f7c0e608aea7022a9c8bfc40c5643e60b2ba7343ff09c5be0bc08be34dde3c6b85fea192a46d4764770c12cbaa233df4231a1b99627ef9d","up":true},{"one":"e06a789a7f6988e1ba5e8358b6cd4292555c7f9f7f0dda6fc01cc26d24e49a8c1ad694423ad74aec6d80f4b99e2bedc49b6a5f2670744cedee3a3e1848e6dd07","other":"57b47f692f4d69a5d2c9c193680eb4ccb5a6c574662df0138504a549f3ea74f20c5b866ac4d9e76c4b49c83f5fd692ead928ea20dfcf643a11a1c1e841c0ec42","up":true},{"one":"c9cd9dfb9f90a7948ac5a42c7bd63263f2eef6e1d85547559f7d2ecbf5f9cd1eab051b8e9e661b573c275d84091a44e73f6fc6bcc91dcdb674bd5d939190fc01","other":"1bc1d6155ba35d29ea16938994e08df76ebd8f16bd180bd6a9b9d8798d0745889fe72d641dd78bd8ec13526929f7eb5aaa6a388430fa69033d6db581e53c6422","up":true},{"one":"1090e9d89cb278a30063a5396d9ba795d3bbc237c76915a6fb7d23aa1822c8535d2fccc44cc8cd2acec68444c0bf1bdf5195ebb9f3cad8dac3d94a4d9c0e5309","other":"4b784f072b7c96c30612767425f552e30e45157e70139dfbe0ae4ff86dc31601adec60f8a3ad9747b02b5219073d8813af9b09d59eaf7ddb7ee24856aff6fa8f","up":true},{"one":"2a63d875e715c2a43302d32d86d30c7d7faed46c08a67bf488762637216b99dd87333a66df6d9f3a57df863b1f1a219ddbeebb9f3e92e523bd08540a195448ca","other":"0deda014fa3c0bc8f37d853e1448f95f56f97048c28797d72258fd3ba2f1f776ae11566197466596356cd172847ab02a89f4cf047e58383249fb2a4cd69b6206","up":true},{"one":"0deda014fa3c0bc8f37d853e1448f95f56f97048c28797d72258fd3ba2f1f776ae11566197466596356cd172847ab02a89f4cf047e58383249fb2a4cd69b6206","other":"c332fe1f9b6e25f72c7150631ffa6e0929ff6eeab5d17aa45eaf669bdde869cf404505ae990a529aa3ca797cd0a96f31cc41431a5d4a163132be566f91623c08","up":true},{"one":"c332fe1f9b6e25f72c7150631ffa6e0929ff6eeab5d17aa45eaf669bdde869cf404505ae990a529aa3ca797cd0a96f31cc41431a5d4a163132be566f91623c08","other":"5566111b7f14d8ec83ba6456488f3fc5c7e2c86bf406dead33b814e1ee9b569d34015a4d88226b7e28fff7784395c086d106287cbbc80acfe75b05cd6e12903d","up":true},{"one":"5566111b7f14d8ec83ba6456488f3fc5c7e2c86bf406dead33b814e1ee9b569d34015a4d88226b7e28fff7784395c086d106287cbbc80acfe75b05cd6e12903d","other":"b4a5efa9028b2d196855393892f79993c2812d02b758f98813ddf82c5d943faf6d66eff811cc5a51936c118f4c768c0d13b54902095e040c602761e63c08655e","up":true},{"one":"b4a5efa9028b2d196855393892f79993c2812d02b758f98813ddf82c5d943faf6d66eff811cc5a51936c118f4c768c0d13b54902095e040c602761e63c08655e","other":"adfba6d883cacbb141cd8c59ee04d7e5d520f1ce31a81e5db2d8b2380bf801c1fe4b265a66b71f9643d13a41cb1f6fb4b83399be786da4b6e171b6784bc56e49","up":true},{"one":"adfba6d883cacbb141cd8c59ee04d7e5d520f1ce31a81e5db2d8b2380bf801c1fe4b265a66b71f9643d13a41cb1f6fb4b83399be786da4b6e171b6784bc56e49","other":"2bfba66ec9d63e928d77d455f2e10a14d6213e515099d5db14fa44a8bfc147eb0fa7afa9aaccdc86453c6903b55556059a2e13dd61fc494127d4a3ec173bf9ea","up":true},{"one":"2bfba66ec9d63e928d77d455f2e10a14d6213e515099d5db14fa44a8bfc147eb0fa7afa9aaccdc86453c6903b55556059a2e13dd61fc494127d4a3ec173bf9ea","other":"0b7e1e5acabcde503ad827e45724402406114a513f81040a379b0f82df2eab4456b348b27936369c49e3c264d971c6a9e2c2217fdbc5e5b93ac6fc219957834d","up":true},{"one":"0b7e1e5acabcde503ad827e45724402406114a513f81040a379b0f82df2eab4456b348b27936369c49e3c264d971c6a9e2c2217fdbc5e5b93ac6fc219957834d","other":"7554993f6efd8d9016ff525ae73c41ee2e0dbd4970c563ba9b61a99c1c8943b433c4b7d48450f6e0fbc9ac198d907698093de20e6c1f7755520fb1e1cbee4eb4","up":true},{"one":"7554993f6efd8d9016ff525ae73c41ee2e0dbd4970c563ba9b61a99c1c8943b433c4b7d48450f6e0fbc9ac198d907698093de20e6c1f7755520fb1e1cbee4eb4","other":"4fe37f2dfb03707c90a6fe91dbcfd7497db70ffc20043091d50e1cee573210c144e8749340f2c3cb70fe8fc51b317d49e8734dc51ce64b3cdccdd639ae35d1ae","up":true},{"one":"4fe37f2dfb03707c90a6fe91dbcfd7497db70ffc20043091d50e1cee573210c144e8749340f2c3cb70fe8fc51b317d49e8734dc51ce64b3cdccdd639ae35d1ae","other":"a7507aa5665e165ab2e2a07def272f0677f9d6d35bb82268a34214384e7d8ef7635a299368752e63cfd02d4e60231076baf23cfa10d17492e55181b391ecf335","up":true},{"one":"a7507aa5665e165ab2e2a07def272f0677f9d6d35bb82268a34214384e7d8ef7635a299368752e63cfd02d4e60231076baf23cfa10d17492e55181b391ecf335","other":"7e2b0b4f3b55e97bd7241b984ad117af33bf3baacd22b3ed503a8a59f75828df745fb3ce3be4276d83eb484e64d9aa251103fa994ef119eaddb97a3503b9f292","up":true},{"one":"7e2b0b4f3b55e97bd7241b984ad117af33bf3baacd22b3ed503a8a59f75828df745fb3ce3be4276d83eb484e64d9aa251103fa994ef119eaddb97a3503b9f292","other":"460531928a4b084686343c8464b37c3452bb3566045698d08a4692864de5581a9eb1dc632329e7d3ccb73ec31ee7693787d69df8458efaba9a7105d87ee2e053","up":true},{"one":"460531928a4b084686343c8464b37c3452bb3566045698d08a4692864de5581a9eb1dc632329e7d3ccb73ec31ee7693787d69df8458efaba9a7105d87ee2e053","other":"70ee3c7e02a123f78345d41c386e413f06b51f1ab346c2c472891eed7dd26a1f14e213a0f4f2d872859b9b535936a6d9b072d2604456f76221a422710411822f","up":true},{"one":"70ee3c7e02a123f78345d41c386e413f06b51f1ab346c2c472891eed7dd26a1f14e213a0f4f2d872859b9b535936a6d9b072d2604456f76221a422710411822f","other":"049a2b0ab4d49789dbbe1837e2d2ee5220a9401729ea87ab29385b24d79cdce255c3d2b5de6484d49ca6ce07bd41832598260c0a8c290e01d133d77f066f2f99","up":true},{"one":"049a2b0ab4d49789dbbe1837e2d2ee5220a9401729ea87ab29385b24d79cdce255c3d2b5de6484d49ca6ce07bd41832598260c0a8c290e01d133d77f066f2f99","other":"1f6d803a4ca186463772850ca0901fb920af7e74fdd2480c3c368fa707838ee91bbcfb57d5e3510c802b9b85f2d954f04c9b675414274bdaebae6488dcf94c10","up":true},{"one":"1f6d803a4ca186463772850ca0901fb920af7e74fdd2480c3c368fa707838ee91bbcfb57d5e3510c802b9b85f2d954f04c9b675414274bdaebae6488dcf94c10","other":"979838eaefcff456cf1cd9c47ea46854704f5757d8d7ab907019bc422b01af4d62252579bf045d143fab491b0bab823190e2782a457fbf51aa99ae17ec9e145f","up":true},{"one":"979838eaefcff456cf1cd9c47ea46854704f5757d8d7ab907019bc422b01af4d62252579bf045d143fab491b0bab823190e2782a457fbf51aa99ae17ec9e145f","other":"ed6c793eb4565aa9d883a76fad6c97ad0b878b9ef0235e11e89db1af25a9653205f725c6ea258b84bde134f1a6437c6d109b859d17509e5016c4ab98be59032a","up":true},{"one":"ed6c793eb4565aa9d883a76fad6c97ad0b878b9ef0235e11e89db1af25a9653205f725c6ea258b84bde134f1a6437c6d109b859d17509e5016c4ab98be59032a","other":"6c143960dbe3ba4c95e8debc1fda5f420a2a673eb46f7ff7d9a30f4cd2067e67ef8926bf17f0c99b16c79b6dc066b52409a11d47117d4fda4211636b1b74f96c","up":true},{"one":"6c143960dbe3ba4c95e8debc1fda5f420a2a673eb46f7ff7d9a30f4cd2067e67ef8926bf17f0c99b16c79b6dc066b52409a11d47117d4fda4211636b1b74f96c","other":"7bbb3f3ed51cf84c077806fbd6d3578e105bc32aa6043da188793f066ad6df383a9f7cc0bd3124f4c887704bd188d480ce264fcdf178905bbda3b270927ea138","up":true},{"one":"7bbb3f3ed51cf84c077806fbd6d3578e105bc32aa6043da188793f066ad6df383a9f7cc0bd3124f4c887704bd188d480ce264fcdf178905bbda3b270927ea138","other":"2b70e5ffcc0bb1c4f8acc09dd1016e67c9c96c92d091ad481efbb71bd8b2a5a5869c6d668617a9b2cbfe91baf5edfe150c3824c84d90899a974099071d171441","up":true},{"one":"2b70e5ffcc0bb1c4f8acc09dd1016e67c9c96c92d091ad481efbb71bd8b2a5a5869c6d668617a9b2cbfe91baf5edfe150c3824c84d90899a974099071d171441","other":"f5c1215a84a56d52f92ca0dc3a32df98c98a9c2ea2e9a34560210c16de1b440d20d043c8c25955dda8c22e55e92ddb49fd82e8b9b84072aabaa755a229bb19f4","up":true},{"one":"f5c1215a84a56d52f92ca0dc3a32df98c98a9c2ea2e9a34560210c16de1b440d20d043c8c25955dda8c22e55e92ddb49fd82e8b9b84072aabaa755a229bb19f4","other":"8c6d77833bf1a98beabe7a92d985d13d52fb2e50768719ffbc6fce21ea676802a074b6e620b3ef80e12fad04f94a3c288d91df9716a6cfae09ef073b9dc1f2cb","up":true},{"one":"8c6d77833bf1a98beabe7a92d985d13d52fb2e50768719ffbc6fce21ea676802a074b6e620b3ef80e12fad04f94a3c288d91df9716a6cfae09ef073b9dc1f2cb","other":"b3316f4fd7dec218a52331f25d17a2faf0f2a417808d7dbb80038154abfbcd2d78da074837b648cff28675f4aa0d65ddb7d15abf3d7e0391d401e313a3ef24a2","up":true},{"one":"b3316f4fd7dec218a52331f25d17a2faf0f2a417808d7dbb80038154abfbcd2d78da074837b648cff28675f4aa0d65ddb7d15abf3d7e0391d401e313a3ef24a2","other":"60725e8d0e9333636e598dd666f459b4be898d9abc095ee2c1db289673e7e969b50e2093956fef5a2f1d23e2040159bbabaaeab17fc6dbbac3f6acab766e9e60","up":true},{"one":"60725e8d0e9333636e598dd666f459b4be898d9abc095ee2c1db289673e7e969b50e2093956fef5a2f1d23e2040159bbabaaeab17fc6dbbac3f6acab766e9e60","other":"48a5e01e06e297dc1c640ac9601171495bd70fea461c60e7e6e2532695e45fcf68183c2e58b5e6931a6c1c094f5331efbd7f2d93d5f84efdec5a35afa2124438","up":true},{"one":"48a5e01e06e297dc1c640ac9601171495bd70fea461c60e7e6e2532695e45fcf68183c2e58b5e6931a6c1c094f5331efbd7f2d93d5f84efdec5a35afa2124438","other":"5dc69635f6d573c824ea83b18593a47f9f21a6f91ce18d2bf977c97d21f8d2a8ce88829244d12a07d949bbd52fe8a2035bc89685fe1bdd4ee20d766d75d3deee","up":true},{"one":"5dc69635f6d573c824ea83b18593a47f9f21a6f91ce18d2bf977c97d21f8d2a8ce88829244d12a07d949bbd52fe8a2035bc89685fe1bdd4ee20d766d75d3deee","other":"ae4e21e1587a8475afd299e00ca7085c7bf2a44c2c64a3068f12223d9202b0125094385319034691ec26b497ec9cf18fe8c0839224bac1b84279410241cef979","up":true},{"one":"ae4e21e1587a8475afd299e00ca7085c7bf2a44c2c64a3068f12223d9202b0125094385319034691ec26b497ec9cf18fe8c0839224bac1b84279410241cef979","other":"0b30b36e155db04c448b662c4df695068b2331cdbe2772aae5fda84159e977515a5ff2e156bc225a9281fef2383926ba8cb11e9c1846fb40db241e524ac14e29","up":true},{"one":"0b30b36e155db04c448b662c4df695068b2331cdbe2772aae5fda84159e977515a5ff2e156bc225a9281fef2383926ba8cb11e9c1846fb40db241e524ac14e29","other":"17a79cb279306b6bbd35219278f6bba03111079d6c4fadcd3c5e57b09678e111bda5f8e36ca3d223e51e255d6e857363b7741e438b32ec6e6c0dc1b224071081","up":true},{"one":"17a79cb279306b6bbd35219278f6bba03111079d6c4fadcd3c5e57b09678e111bda5f8e36ca3d223e51e255d6e857363b7741e438b32ec6e6c0dc1b224071081","other":"617595a230e0a74a3db3b47cd27b941e02bdee9a84cdfa8eaa63a55941eb5caa79e20fb69726a4d46a0e5aeed24039f8c5a20679a692df0bc140f42558ca9a2b","up":false},{"one":"617595a230e0a74a3db3b47cd27b941e02bdee9a84cdfa8eaa63a55941eb5caa79e20fb69726a4d46a0e5aeed24039f8c5a20679a692df0bc140f42558ca9a2b","other":"7808fb798d22e78fb1d39b87ddf99a503f820993bc64149eca9e81d9d58fc1adea60d8de14a4f06cb89f3190c0ef0c5e182621a14c9361ccb7e0cee667599cc3","up":true},{"one":"7808fb798d22e78fb1d39b87ddf99a503f820993bc64149eca9e81d9d58fc1adea60d8de14a4f06cb89f3190c0ef0c5e182621a14c9361ccb7e0cee667599cc3","other":"f039df8a3206e6e17eee8e95010038c450cb4cc0b5580ed5795d4c21802e1e9d360f4528bdca794f457932b1d6a818862ec847357a861c488332ef6d9480daa6","up":true},{"one":"f039df8a3206e6e17eee8e95010038c450cb4cc0b5580ed5795d4c21802e1e9d360f4528bdca794f457932b1d6a818862ec847357a861c488332ef6d9480daa6","other":"ce0a09bb6fe4c9c93c3dbd800ca9c9ac0714f26a8f8dac2149b6ce7a9011912a5621ea2e45de35c4d31dfe5add00558fdba5dd21acf2d81ba391e82b5b3a5804","up":true},{"one":"ce0a09bb6fe4c9c93c3dbd800ca9c9ac0714f26a8f8dac2149b6ce7a9011912a5621ea2e45de35c4d31dfe5add00558fdba5dd21acf2d81ba391e82b5b3a5804","other":"b2538d4edfa736bfe2cc21326a44ce62f716b3480eac93584a2233b69c98883a2bb255f246218a58cecab1d0d176e6d1fbba9782fd70d4603e01742299b9ea9c","up":true},{"one":"b2538d4edfa736bfe2cc21326a44ce62f716b3480eac93584a2233b69c98883a2bb255f246218a58cecab1d0d176e6d1fbba9782fd70d4603e01742299b9ea9c","other":"aa9a94d6e4eaaed20113c21752c224e3a052abd3769bd6e832759dbaf5154a943cf094eacdcb0727c2fe51a11bd7fc0793d7d5e3312b0aba89d428a00e1fde0c","up":true},{"one":"aa9a94d6e4eaaed20113c21752c224e3a052abd3769bd6e832759dbaf5154a943cf094eacdcb0727c2fe51a11bd7fc0793d7d5e3312b0aba89d428a00e1fde0c","other":"65e954e60837bda10654480b227fa3bcc6e63356c52079002a27e836cd82ae2934ba77da60080e4b9f2d9324b982b24959bfd9624302e6c330408381054b43e9","up":true},{"one":"65e954e60837bda10654480b227fa3bcc6e63356c52079002a27e836cd82ae2934ba77da60080e4b9f2d9324b982b24959bfd9624302e6c330408381054b43e9","other":"8ca3b63cb84f1e9883d82809a9b6777ec1029ecda96fe93b4d494ee9cbefcad13f381b3e480136e542e01054fe1ede66c65db84a0009871ce49383db461c8438","up":true},{"one":"8ca3b63cb84f1e9883d82809a9b6777ec1029ecda96fe93b4d494ee9cbefcad13f381b3e480136e542e01054fe1ede66c65db84a0009871ce49383db461c8438","other":"caaf695c76cf7c047d3f3bfe019d01618e4871cee8ff3f347913da815bbcde145771486f916a44d03f59ea9bc217f169fd0c0765fda3f9b9b28d02a522e180b4","up":true},{"one":"caaf695c76cf7c047d3f3bfe019d01618e4871cee8ff3f347913da815bbcde145771486f916a44d03f59ea9bc217f169fd0c0765fda3f9b9b28d02a522e180b4","other":"b080891d4ba6d3ab224984360597f9c555bd1367630f5420bfaf230419a05b2be58bebf1554e53eb4c0da81cfb66d4f7697dd65143f11841ff62d8a0d82b6b67","up":true},{"one":"b080891d4ba6d3ab224984360597f9c555bd1367630f5420bfaf230419a05b2be58bebf1554e53eb4c0da81cfb66d4f7697dd65143f11841ff62d8a0d82b6b67","other":"2ca05ffc0ad771e1e045a47f1c0a79ce374a25e3c0e53c2a80d67e7479677003f62880251a83a5074f1c9651d828f1ff7e352935a9df141c1eb75a0c59b00a8b","up":true},{"one":"2ca05ffc0ad771e1e045a47f1c0a79ce374a25e3c0e53c2a80d67e7479677003f62880251a83a5074f1c9651d828f1ff7e352935a9df141c1eb75a0c59b00a8b","other":"8d4920d6e3a6717699b5a3af068cbdfc16858d7e393d158d41b1b5f345b47129eef89e1d055386c518f400b134678c21590f0317dea3436d4cef60f45455cf12","up":false},{"one":"8d4920d6e3a6717699b5a3af068cbdfc16858d7e393d158d41b1b5f345b47129eef89e1d055386c518f400b134678c21590f0317dea3436d4cef60f45455cf12","other":"b6a998dea59194cc60ce97c7c9702368411889cb6905516b23f41cc5116fba8d0f237d418318eb0c333cad18003c0e9a6bd8c99080520771f2bad640e2e5ec1c","up":true},{"one":"b6a998dea59194cc60ce97c7c9702368411889cb6905516b23f41cc5116fba8d0f237d418318eb0c333cad18003c0e9a6bd8c99080520771f2bad640e2e5ec1c","other":"ff6f94005d1df7677600069764855c1c2aa0543cbe9f480f8feefec76c49d9e2c7bb2d8e38c89e9430f53f8b593d93f143c45985a56a5a32c736128214c95eda","up":true},{"one":"ff6f94005d1df7677600069764855c1c2aa0543cbe9f480f8feefec76c49d9e2c7bb2d8e38c89e9430f53f8b593d93f143c45985a56a5a32c736128214c95eda","other":"315b8a1711f680c2eaa607e35ef7a9e19c2b61721af8a7e08f1325dde1fe33cf1f47b3cc4acf12d541631041cf1b42754875fd1c9b66ee32797b72b9f7711256","up":false},{"one":"315b8a1711f680c2eaa607e35ef7a9e19c2b61721af8a7e08f1325dde1fe33cf1f47b3cc4acf12d541631041cf1b42754875fd1c9b66ee32797b72b9f7711256","other":"396c703d27bfdddf91761f134cbf665fe61e0b3a5d24036a4105a625f72e8c28b821e9200f20d6e8f8b3ed6b95bda6b8accdd840c2f786720b7431e3af2af981","up":true},{"one":"396c703d27bfdddf91761f134cbf665fe61e0b3a5d24036a4105a625f72e8c28b821e9200f20d6e8f8b3ed6b95bda6b8accdd840c2f786720b7431e3af2af981","other":"cd8815d66aee8bd488d4e5e25f0cc9c71cc65349f701ea26b1d6cd9c039d16fcb473dbf270a3b33187720ccf4b0ce4f78a6d6edd05f4fe804772d5b6ec45bbd3","up":true},{"one":"cd8815d66aee8bd488d4e5e25f0cc9c71cc65349f701ea26b1d6cd9c039d16fcb473dbf270a3b33187720ccf4b0ce4f78a6d6edd05f4fe804772d5b6ec45bbd3","other":"7174eca109a1f717653918224c8cfe1b7fbd666405196760913593401eb79f2c7e41003b01f5a458940695b27a4673443c7621a169db7fd968994e552995dbbb","up":true},{"one":"7174eca109a1f717653918224c8cfe1b7fbd666405196760913593401eb79f2c7e41003b01f5a458940695b27a4673443c7621a169db7fd968994e552995dbbb","other":"59b53f8a562bee519276e0eeccfcf8c975d3102f5d0cccf5abcce291a8a5bb817c04604f123686177a50a03b9d7559ac469962d0159d1d93e4ce58a304d04b55","up":true},{"one":"59b53f8a562bee519276e0eeccfcf8c975d3102f5d0cccf5abcce291a8a5bb817c04604f123686177a50a03b9d7559ac469962d0159d1d93e4ce58a304d04b55","other":"f915e2398aa5d4370de87504dd76c21a7d0be2581c2ab55b7a47743f1bbaef36384eaacec22760f1e914ceac9d96a10c3d66eb27475ef444e77fee979e6e88cb","up":true},{"one":"f915e2398aa5d4370de87504dd76c21a7d0be2581c2ab55b7a47743f1bbaef36384eaacec22760f1e914ceac9d96a10c3d66eb27475ef444e77fee979e6e88cb","other":"1b6cad4f9851cc584c5d1405f976bb51a52e27ef4525847df543dcca65ca5eb1ef229dcc68ccbaaf00ab1e044cb5990dd213c805bdb4adcceb6fa70b5c61fdb4","up":true},{"one":"1b6cad4f9851cc584c5d1405f976bb51a52e27ef4525847df543dcca65ca5eb1ef229dcc68ccbaaf00ab1e044cb5990dd213c805bdb4adcceb6fa70b5c61fdb4","other":"ae2a996d3b562cb47a564934037949da83b1bfe194c23754f3dbe2372ec27654f4f3b6cb7f394570f308025589c065870477667e5560dbe5a8ea1625740699cf","up":true},{"one":"ae2a996d3b562cb47a564934037949da83b1bfe194c23754f3dbe2372ec27654f4f3b6cb7f394570f308025589c065870477667e5560dbe5a8ea1625740699cf","other":"ddaf3f8478501cda872c056c72063eb64d5b871fc5fff70704872802289dd2d348f73bc342b7f148a90cfaae2448ebf16fea196be9df891dc71a57fb410d59dd","up":true},{"one":"ddaf3f8478501cda872c056c72063eb64d5b871fc5fff70704872802289dd2d348f73bc342b7f148a90cfaae2448ebf16fea196be9df891dc71a57fb410d59dd","other":"5eccdbcb15ef42dc96abcbcd8b8db75d9230de10e3c650620737f6cc04ba4fdbf59ded5daa801901c191be186c329ebcd37ba83bcf794064ad4e11bf10d3f775","up":true},{"one":"5eccdbcb15ef42dc96abcbcd8b8db75d9230de10e3c650620737f6cc04ba4fdbf59ded5daa801901c191be186c329ebcd37ba83bcf794064ad4e11bf10d3f775","other":"8dd8ad560af84bec579cadb33d51711aa61b6ed22705010336df5a71a94591173b25e869457429c4a199b205fce8e73530e28203e18b971c2001715e610f152a","up":true},{"one":"8dd8ad560af84bec579cadb33d51711aa61b6ed22705010336df5a71a94591173b25e869457429c4a199b205fce8e73530e28203e18b971c2001715e610f152a","other":"28d3232c43de54ffdaf08f97b334c012738648b04e2876c7e751a2e352aaf4d550d6efa976c5a8edbfa8e88b9d04a0fca492b81c3756ef673ab74d34182ca711","up":true},{"one":"28d3232c43de54ffdaf08f97b334c012738648b04e2876c7e751a2e352aaf4d550d6efa976c5a8edbfa8e88b9d04a0fca492b81c3756ef673ab74d34182ca711","other":"be514f5f17f3177235acb24112b578edf0e373c469073226e547d18080905fd062d572be18e943f13bf9fcf5871e89ceb630a1b848a0e370ef8ef8c6d997a363","up":false},{"one":"be514f5f17f3177235acb24112b578edf0e373c469073226e547d18080905fd062d572be18e943f13bf9fcf5871e89ceb630a1b848a0e370ef8ef8c6d997a363","other":"66d0c5da973d9dd65350ae1ec63776872cdb7ded6afb6f51ae82259f6fd35e884375d15de290625f02ed2e5cdc3f591decb45e5fc64d5b0f835a216fd196f5a3","up":true},{"one":"66d0c5da973d9dd65350ae1ec63776872cdb7ded6afb6f51ae82259f6fd35e884375d15de290625f02ed2e5cdc3f591decb45e5fc64d5b0f835a216fd196f5a3","other":"2f360209383d6de4ebd3b4abaf77796520b8654270b03f2151eac4a01b4417d7e0668c1f9ad30c20ff49aa8a0ab33dba5e6095619d1cf04b7af841722ab773da","up":true},{"one":"2f360209383d6de4ebd3b4abaf77796520b8654270b03f2151eac4a01b4417d7e0668c1f9ad30c20ff49aa8a0ab33dba5e6095619d1cf04b7af841722ab773da","other":"b35f418c7935cc54278e90978c3ef1521ab91daeaf9f1ebc1cd25211611ade091cac4e1f009d71059279d507322a4536501980ac0dd44caddc52fd4c593879f7","up":false},{"one":"4314b0b04331973ed29a58843951f144ac3d09bd5d57b6cd9aaff9b73a7b2ec81e344a3e4ece462bd2081b837a06310e787ef3bb889dabad46fe7efd394c8342","other":"3612863ce0456c91785a829bf5c9d2b2fb97dda083a1847e5a4ebaa6fce1260faf4d1eb374c2225431a82774163835fb59c8cb0fa9fc0969eab5410c71109cc2","up":true},{"one":"b35f418c7935cc54278e90978c3ef1521ab91daeaf9f1ebc1cd25211611ade091cac4e1f009d71059279d507322a4536501980ac0dd44caddc52fd4c593879f7","other":"fe8ac5d33cd8ab6a1dad9567cdfb89b431a5c4f4a584fc608b92e7dfd06f70988e71e2f11f9fda9ee797c9ffba83bc085939fdf2522dde39f28202be92650566","up":false},{"one":"fe8ac5d33cd8ab6a1dad9567cdfb89b431a5c4f4a584fc608b92e7dfd06f70988e71e2f11f9fda9ee797c9ffba83bc085939fdf2522dde39f28202be92650566","other":"352407b42726dcd1aacc46a912ed8124b8b6a3da4e33dab742e40aa2452953d35dc8f42eddc76695ae2317e9f15dde2cd21be4ce826934695ad1847455661d1b","up":true},{"one":"352407b42726dcd1aacc46a912ed8124b8b6a3da4e33dab742e40aa2452953d35dc8f42eddc76695ae2317e9f15dde2cd21be4ce826934695ad1847455661d1b","other":"b137cf2291b530a39516d882200848e7f27a2710e0839b4d25b4f367bea6a0c3aaef8c7c7851c00a2945adcd819ea0508610afc1f453b8bc512b7b4d4faacdf3","up":true},{"one":"b137cf2291b530a39516d882200848e7f27a2710e0839b4d25b4f367bea6a0c3aaef8c7c7851c00a2945adcd819ea0508610afc1f453b8bc512b7b4d4faacdf3","other":"1b063741c76fe65e62b4eae42751319d0cce66f22dde9f1cf83d6cca249a0e65bc7f6f22597697362fadd226222fb3847f8e146961969d1b4c9f7e475389cd8e","up":true},{"one":"1b063741c76fe65e62b4eae42751319d0cce66f22dde9f1cf83d6cca249a0e65bc7f6f22597697362fadd226222fb3847f8e146961969d1b4c9f7e475389cd8e","other":"657d5370319128d24d925b41065eb619409d63ec6280975d78877a4028287463f6442f5206dd703569a05b2b542ad8bbb99803da265408208d6356a26d283d08","up":true},{"one":"657d5370319128d24d925b41065eb619409d63ec6280975d78877a4028287463f6442f5206dd703569a05b2b542ad8bbb99803da265408208d6356a26d283d08","other":"a127faa19dcb7da585983d36a8e9d3e9a44a6db68507b60c70da71011f44ce377944802f39cd65f5a705cd8249ac1ef7ed8fd699349098f3f8e23b37592c80ae","up":true},{"one":"a127faa19dcb7da585983d36a8e9d3e9a44a6db68507b60c70da71011f44ce377944802f39cd65f5a705cd8249ac1ef7ed8fd699349098f3f8e23b37592c80ae","other":"2e42f845d0393d1682add54ee30b60a953ed283e75d347bc6719ae0e91f6676282e7960f1fd52e5803d6b341fb3582c724b4f9cfd7bce9ce85f13ca480c7e72e","up":true},{"one":"2e42f845d0393d1682add54ee30b60a953ed283e75d347bc6719ae0e91f6676282e7960f1fd52e5803d6b341fb3582c724b4f9cfd7bce9ce85f13ca480c7e72e","other":"6b01079463ec2f649db8634cb7a596261c79a8f714d954c772528e0547b017f8ce405e4a0ea9d32270848180e0f77b8c0b022cf95c85e777626edd4d24ea21d2","up":true},{"one":"6b01079463ec2f649db8634cb7a596261c79a8f714d954c772528e0547b017f8ce405e4a0ea9d32270848180e0f77b8c0b022cf95c85e777626edd4d24ea21d2","other":"2245f3bf1a3b4e92f912affc75f757cf648b20474c11ffe947884f216b8f24f9dcb6e6a0358a4061b8517478ec15027e185b2f05a777573b4940375bf4aaf2be","up":true},{"one":"2245f3bf1a3b4e92f912affc75f757cf648b20474c11ffe947884f216b8f24f9dcb6e6a0358a4061b8517478ec15027e185b2f05a777573b4940375bf4aaf2be","other":"d4b7c787981abec24353c7d496661692233797e3758189bf909a69fe87935bf6da0940daa4f12e81f20c5e88f70b472113688b71a0ae2f91a73ee0e6ff4c8591","up":true},{"one":"d4b7c787981abec24353c7d496661692233797e3758189bf909a69fe87935bf6da0940daa4f12e81f20c5e88f70b472113688b71a0ae2f91a73ee0e6ff4c8591","other":"9c30ad8c85adc7bb52ddcfab2e661cc3a854a689eaa59128d35129d02cd5b0f8da4a44cdd33934a8e2c8fab1760c16d6f2e1c5eb227dc819e85624e63343c069","up":true},{"one":"9c30ad8c85adc7bb52ddcfab2e661cc3a854a689eaa59128d35129d02cd5b0f8da4a44cdd33934a8e2c8fab1760c16d6f2e1c5eb227dc819e85624e63343c069","other":"c8b0dba45104fc7c7dff3ce078a0d3f5ade6198bb4656e2bee8076387929133e5ef2bd293b130a9d4f6a6974ca17e8b4a8f406d1219880f1e0f99c65c63af5a4","up":false},{"one":"c8b0dba45104fc7c7dff3ce078a0d3f5ade6198bb4656e2bee8076387929133e5ef2bd293b130a9d4f6a6974ca17e8b4a8f406d1219880f1e0f99c65c63af5a4","other":"ff1e34fd51953ed641b431aa657da21cb4c81d23e4eaa13c9cce526f1f1b34593d41f9b87a0e10387fe400c623638677c0efab15dbd1014a0ccc11f9ec92c417","up":true},{"one":"ff1e34fd51953ed641b431aa657da21cb4c81d23e4eaa13c9cce526f1f1b34593d41f9b87a0e10387fe400c623638677c0efab15dbd1014a0ccc11f9ec92c417","other":"a78f18691e0dbf3c08fe9d7dec188e6a05a93833432fb99eb2b3924ab0bde7a44db2a102a65544bbdc4fb61bc3a3d569230d9843a335bf619167fb045d78ab3c","up":true},{"one":"a78f18691e0dbf3c08fe9d7dec188e6a05a93833432fb99eb2b3924ab0bde7a44db2a102a65544bbdc4fb61bc3a3d569230d9843a335bf619167fb045d78ab3c","other":"e67e495385e7cacfe659b40d1ba94d4b1ff55eada70a4d9740a9e452fbf221672bd0a897b940e2a6bed71e2a16867fe45bf0ea0015435ac6d815690e263b1899","up":true},{"one":"e67e495385e7cacfe659b40d1ba94d4b1ff55eada70a4d9740a9e452fbf221672bd0a897b940e2a6bed71e2a16867fe45bf0ea0015435ac6d815690e263b1899","other":"aacff366e601e072a2113add9020e19b6612f3e85b6e607fdc8cc1b6991f43be0b1f835ed3dc41d1f2b3e0caf7fac252c8eb4c150667d48207fa92ea5f0a7455","up":true},{"one":"aacff366e601e072a2113add9020e19b6612f3e85b6e607fdc8cc1b6991f43be0b1f835ed3dc41d1f2b3e0caf7fac252c8eb4c150667d48207fa92ea5f0a7455","other":"2f903b2fd4f9432b7d91b5c3e4c7ee3cb9c56fe7efc4baff0edd06fc75e4b7492f2c3c929755746df59c9f95d437a12ba40ac138d08f5bc7aa091f49f3b852c2","up":true},{"one":"3612863ce0456c91785a829bf5c9d2b2fb97dda083a1847e5a4ebaa6fce1260faf4d1eb374c2225431a82774163835fb59c8cb0fa9fc0969eab5410c71109cc2","other":"2ac522ebfa49d37f86c6270ad4cdad0e766493f0e463b18c9906c70fbd2e5c6ff6b0d5879de6e3894418370636963a78b0c0cf087a8684c2ca30c9c736e49228","up":true},{"one":"2ac522ebfa49d37f86c6270ad4cdad0e766493f0e463b18c9906c70fbd2e5c6ff6b0d5879de6e3894418370636963a78b0c0cf087a8684c2ca30c9c736e49228","other":"62666b24d1026345349edb6a878cdc27d6fee8254e83f79a298ce2805260d97aa46423deae440f86ced5cd99b30e970c8e1ea1046752b17d8c80dc68d9a49b60","up":false},{"one":"62666b24d1026345349edb6a878cdc27d6fee8254e83f79a298ce2805260d97aa46423deae440f86ced5cd99b30e970c8e1ea1046752b17d8c80dc68d9a49b60","other":"9ce6b9decb69d66075993e903a0727ec109a04335634616097c0e60b08f94f764634fa00891b1070f6ea1ce896bc7d11d3aea92a00f281f902d960894cef296f","up":true},{"one":"9ce6b9decb69d66075993e903a0727ec109a04335634616097c0e60b08f94f764634fa00891b1070f6ea1ce896bc7d11d3aea92a00f281f902d960894cef296f","other":"b870935867183bbfb84add16b9f56c02c834b7042fc24ce6bcb2a7f174e6d2239357a00be4272c1ef05c7f9baf5a9f16b53bc18328a9b7aca8540c2916805b57","up":true},{"one":"b870935867183bbfb84add16b9f56c02c834b7042fc24ce6bcb2a7f174e6d2239357a00be4272c1ef05c7f9baf5a9f16b53bc18328a9b7aca8540c2916805b57","other":"c83985973a9564ade7d90aa54911ac57077600676a1d27292d98e058bf1315887bad84ccd708cb7f52a695a1405fb7d491d7ca2ae9caa3ff58a5ad78ce4dc9d9","up":true},{"one":"c83985973a9564ade7d90aa54911ac57077600676a1d27292d98e058bf1315887bad84ccd708cb7f52a695a1405fb7d491d7ca2ae9caa3ff58a5ad78ce4dc9d9","other":"acb4088c27ee2ee130ece3506596432afdb9e9757ec11ebdd35c5a6e87239545c48466913a646980104c8fd7a9a335e177f04efffe9dc952dfd7cd5c1bb9aac6","up":true},{"one":"acb4088c27ee2ee130ece3506596432afdb9e9757ec11ebdd35c5a6e87239545c48466913a646980104c8fd7a9a335e177f04efffe9dc952dfd7cd5c1bb9aac6","other":"b4fd11306b1416a9bcf4719578976188e104b8c5028b9abd3214d257446b97b70a22e6c00934d80caddde15e8e4d16af03bb399583047983fba373d8313226b7","up":true},{"one":"b4fd11306b1416a9bcf4719578976188e104b8c5028b9abd3214d257446b97b70a22e6c00934d80caddde15e8e4d16af03bb399583047983fba373d8313226b7","other":"7b35c856916eb3fc1b1f451667e240b95aff8f4731cc0f6743740923081ff1ddf2eec81bdccf4691a7bcc053d23eacfc15809c384a73448f618317bf605bd1cd","up":true},{"one":"7b35c856916eb3fc1b1f451667e240b95aff8f4731cc0f6743740923081ff1ddf2eec81bdccf4691a7bcc053d23eacfc15809c384a73448f618317bf605bd1cd","other":"2ab9513899c3c829b6284e56bf2b9862dd0156ec052b58615dba77d450dac642e534ec36ae5d3234262aff54e19f99856e908b9d8c1da660a7834a445610715b","up":true},{"one":"2ab9513899c3c829b6284e56bf2b9862dd0156ec052b58615dba77d450dac642e534ec36ae5d3234262aff54e19f99856e908b9d8c1da660a7834a445610715b","other":"e087230634f556b818a416b66ba3f1d1dbe3e0dd0698bbb26fa86a2499acd169466f564dc18adf2f9be4d1ada0e86c11549754097601e10aff4f3a57ddffa24a","up":true},{"one":"e087230634f556b818a416b66ba3f1d1dbe3e0dd0698bbb26fa86a2499acd169466f564dc18adf2f9be4d1ada0e86c11549754097601e10aff4f3a57ddffa24a","other":"66beee3968dbcf3addc6feaf070a4e3e82b5bb164fb72f40add89f732c12e8d0a31a7ee1f1e24a4674e4dfc9a4912b02c17ce3c224d257d78b7156544d6507dc","up":true},{"one":"66beee3968dbcf3addc6feaf070a4e3e82b5bb164fb72f40add89f732c12e8d0a31a7ee1f1e24a4674e4dfc9a4912b02c17ce3c224d257d78b7156544d6507dc","other":"a08e47137bf611dfbd20308a22bdd3ca00121386f121d6d712ade86e9a1601a4237766887cd91c8516e20b6e323d2ef49c1c7e177a0afb4c813f0f344daf779b","up":true},{"one":"a08e47137bf611dfbd20308a22bdd3ca00121386f121d6d712ade86e9a1601a4237766887cd91c8516e20b6e323d2ef49c1c7e177a0afb4c813f0f344daf779b","other":"990b1db3ab1390219e8866d39fa4441bb5bb89ad786b3e255771869fcd08906dcf63f34007481769c7462edbcc665acc0a552e3733360b8d8c310c9321a5550f","up":true},{"one":"990b1db3ab1390219e8866d39fa4441bb5bb89ad786b3e255771869fcd08906dcf63f34007481769c7462edbcc665acc0a552e3733360b8d8c310c9321a5550f","other":"7865b82e44add2cea6ebcbaba9c152184331a2940fe73f6f9bb940bda8a59ab4cf4760894b9cadcaa54e36fbb712ad619346a49a85e32cdf2b53cda1ac1e0658","up":false},{"one":"7865b82e44add2cea6ebcbaba9c152184331a2940fe73f6f9bb940bda8a59ab4cf4760894b9cadcaa54e36fbb712ad619346a49a85e32cdf2b53cda1ac1e0658","other":"292c78c8e41606e98428096bc6f4609a7aa48e5c4d17eecc64d65faae4a7270b0c15f0cd74274015688ea0a9aff34f215c29118222e362a29c8d637963973a55","up":false},{"one":"292c78c8e41606e98428096bc6f4609a7aa48e5c4d17eecc64d65faae4a7270b0c15f0cd74274015688ea0a9aff34f215c29118222e362a29c8d637963973a55","other":"ee36d1d5dd69fd30242d7da2e941b34ade5581c7164fcc43288ecfc52937a98f1b31ade5d1e4dbf611cbe1c7875b2840c89435081cde471c271d7bc60e9ef211","up":false},{"one":"ee36d1d5dd69fd30242d7da2e941b34ade5581c7164fcc43288ecfc52937a98f1b31ade5d1e4dbf611cbe1c7875b2840c89435081cde471c271d7bc60e9ef211","other":"bd1a7c63fca9e1fcc67d7fd62670beefe2bce483cf1dc1233ee85eb90db607917cd9a5d7170b10e80b925a20e2af2c54d286b01805ac34967410859f4f03da09","up":true},{"one":"bd1a7c63fca9e1fcc67d7fd62670beefe2bce483cf1dc1233ee85eb90db607917cd9a5d7170b10e80b925a20e2af2c54d286b01805ac34967410859f4f03da09","other":"9db1f94d74a00d1e5e2a391f1bcddf16b6d0670a2c6d91d946d38112c58634444b6fea8e8c05ab4b73bacdd62a0b575f6fb8729978edc216c7842b177b9f9cd9","up":true},{"one":"9db1f94d74a00d1e5e2a391f1bcddf16b6d0670a2c6d91d946d38112c58634444b6fea8e8c05ab4b73bacdd62a0b575f6fb8729978edc216c7842b177b9f9cd9","other":"934a5fe1b91c1891ef4df7f67c027e0eb115d4c2ca4a1b76a135ebd4315c4fb835d6625223194e6a134407b38b0d3928fbc7bc924a3c6a538989a6cf200bf4bd","up":true},{"one":"934a5fe1b91c1891ef4df7f67c027e0eb115d4c2ca4a1b76a135ebd4315c4fb835d6625223194e6a134407b38b0d3928fbc7bc924a3c6a538989a6cf200bf4bd","other":"485825745d97654cbb92a14e0cd1078691d3c28f4d82b1046284b676a42b44ca58eb43474e45e415d3bd3f3c383f9a1a3365821ed7ba6a9f2603b29d58031dc7","up":true},{"one":"485825745d97654cbb92a14e0cd1078691d3c28f4d82b1046284b676a42b44ca58eb43474e45e415d3bd3f3c383f9a1a3365821ed7ba6a9f2603b29d58031dc7","other":"5bae82d4832092c17bd11474f7748015b8b69b896ab8f683a7c0024fc98740cecbb9e31c6275269f9000e5bfe51d7f45cd5dcd4433e0c87b5741685b40fe3983","up":true},{"one":"5bae82d4832092c17bd11474f7748015b8b69b896ab8f683a7c0024fc98740cecbb9e31c6275269f9000e5bfe51d7f45cd5dcd4433e0c87b5741685b40fe3983","other":"732393b99c490c76fa45e3e404ee095f2fa445fcc123af7ac8ab1d2fdd7cf2483f5b82bb818bd8a82b1a3b73e63bcc2c83d8f24d9aad9afe36503735e7967be7","up":true},{"one":"732393b99c490c76fa45e3e404ee095f2fa445fcc123af7ac8ab1d2fdd7cf2483f5b82bb818bd8a82b1a3b73e63bcc2c83d8f24d9aad9afe36503735e7967be7","other":"4de378164d77a28c90cf162dd1b465e0282ee17aa7d3bb3179252466f72da33a36c9f298f7c9498e38dba4018e7ce3e5fe631c83842cd9059e23a7fece366d87","up":true},{"one":"4de378164d77a28c90cf162dd1b465e0282ee17aa7d3bb3179252466f72da33a36c9f298f7c9498e38dba4018e7ce3e5fe631c83842cd9059e23a7fece366d87","other":"155e4879643a472420012e040a87dbff776fc1976814c0c6cd0d5e157f0d0baac04aa7f2535786c09acc2700547383d2119b64a6f62115f1aff1708738844d8c","up":true},{"one":"155e4879643a472420012e040a87dbff776fc1976814c0c6cd0d5e157f0d0baac04aa7f2535786c09acc2700547383d2119b64a6f62115f1aff1708738844d8c","other":"81288bb0584b7ffc1546043e052e1df10fd5371b35dedd0bb42ec5b30ce69b741b2f7857af5984d4754b39d7253575fde9298504999b78380ef602d391c4bb1d","up":true},{"one":"81288bb0584b7ffc1546043e052e1df10fd5371b35dedd0bb42ec5b30ce69b741b2f7857af5984d4754b39d7253575fde9298504999b78380ef602d391c4bb1d","other":"109556abac422a912ecffec0d8796f8f16e92e8f95cecf72dc89e97a8bf1fd37aad3c66aa3cf134acade6d065c31821f977171d5c5463305b57ce3eee99a7ab4","up":true},{"one":"109556abac422a912ecffec0d8796f8f16e92e8f95cecf72dc89e97a8bf1fd37aad3c66aa3cf134acade6d065c31821f977171d5c5463305b57ce3eee99a7ab4","other":"759f46661056bcbb30c7706c9fb87e22a30feb523bd53ae5d18db043efa45b49a2b8982abebdd598fe0912a05896390ec2eabe5e160cbafc0771990708ad8c28","up":true},{"one":"759f46661056bcbb30c7706c9fb87e22a30feb523bd53ae5d18db043efa45b49a2b8982abebdd598fe0912a05896390ec2eabe5e160cbafc0771990708ad8c28","other":"baa5924e1547c177011285d292aa161a15e5ff282da2cd0afb83c9caffb07bdbb3662c227fa7b26e6dc8be9b8863e647eb5f8ce81640532f8f5c9a7f36557e63","up":true},{"one":"baa5924e1547c177011285d292aa161a15e5ff282da2cd0afb83c9caffb07bdbb3662c227fa7b26e6dc8be9b8863e647eb5f8ce81640532f8f5c9a7f36557e63","other":"deb7af800cd20a647335f0feff5bfb3e182f99f4c2d1ade10da36ecfdbac3b5fba4e8f0a4595443fe395b44af3a95617669850944655def85d57cc81c5682a3b","up":true},{"one":"deb7af800cd20a647335f0feff5bfb3e182f99f4c2d1ade10da36ecfdbac3b5fba4e8f0a4595443fe395b44af3a95617669850944655def85d57cc81c5682a3b","other":"17917fa4da06068b587c17899569dcc768b9cd2c27117a4ed67aab26a7e70cf8d32b881db258061ffd89a332a3b29bfd963d8e171a06c3e208ba0de1c42a2b39","up":true},{"one":"17917fa4da06068b587c17899569dcc768b9cd2c27117a4ed67aab26a7e70cf8d32b881db258061ffd89a332a3b29bfd963d8e171a06c3e208ba0de1c42a2b39","other":"032b9bf2f59f15571821611d3ee541aa748c86d47fbe5f049fd0069be53e5d7c41991d82957e9c727654c3aa73ec94997c03d8a6c1d2007c9bb1a703f6215158","up":true},{"one":"032b9bf2f59f15571821611d3ee541aa748c86d47fbe5f049fd0069be53e5d7c41991d82957e9c727654c3aa73ec94997c03d8a6c1d2007c9bb1a703f6215158","other":"be026dfb24847cac2d00f483104edad06ca8ecb9e1229c479ef5650c7b427cd5dc34a1cf06172c17c9d0406ce17009712e82446394743d4cd9bbc41c537ebc14","up":true},{"one":"be026dfb24847cac2d00f483104edad06ca8ecb9e1229c479ef5650c7b427cd5dc34a1cf06172c17c9d0406ce17009712e82446394743d4cd9bbc41c537ebc14","other":"389b5c1a805f87427e6d647ec5488342a3f7d700615943d5ad98ca5c111f33c7ee007970b4d3e475892095c0d5a79b7ed52d12598398818159000d4b9b719126","up":true},{"one":"389b5c1a805f87427e6d647ec5488342a3f7d700615943d5ad98ca5c111f33c7ee007970b4d3e475892095c0d5a79b7ed52d12598398818159000d4b9b719126","other":"c57ea182bdb42ba9b0870b5c870e467f52693e5c0df752fb6eb0dfbacce7763f73caee10db40f4fd90f19f504ee586eaf9da41f5ee93ee515d885fec99374116","up":true},{"one":"c57ea182bdb42ba9b0870b5c870e467f52693e5c0df752fb6eb0dfbacce7763f73caee10db40f4fd90f19f504ee586eaf9da41f5ee93ee515d885fec99374116","other":"2ac93c31937ca205d61cc5c2a1b9037871cac55e9b306b999b28e19566b3316f6539455e014840ea50c2db8a7c97d78804d3a2dcd7cd9c1f32ace0d36e5dd339","up":true},{"one":"2ac93c31937ca205d61cc5c2a1b9037871cac55e9b306b999b28e19566b3316f6539455e014840ea50c2db8a7c97d78804d3a2dcd7cd9c1f32ace0d36e5dd339","other":"ca1aff0d847c6fdacb623ad9078a0885b3208614fea20d5ff11779779b486bf5e9c794aacf848d3c2d58cfcc1eda8356df82f5fbdd0a5236beffe8e6042848c4","up":true},{"one":"ca1aff0d847c6fdacb623ad9078a0885b3208614fea20d5ff11779779b486bf5e9c794aacf848d3c2d58cfcc1eda8356df82f5fbdd0a5236beffe8e6042848c4","other":"2e409baefbd821485a151993356730e5989810d581e68190fbaa142799c9335bcf98310ad188fed10ae6eb6e2e789730393e509962ec5c0fef0342d72ed088d9","up":true},{"one":"2e409baefbd821485a151993356730e5989810d581e68190fbaa142799c9335bcf98310ad188fed10ae6eb6e2e789730393e509962ec5c0fef0342d72ed088d9","other":"7b5c0e81c7f4e3ae29d745f6028cfa10b29a16a9c261b65fb8dd05d6eccc634612ad5d3029c8e9f39863a2cdb2682c25f090139bf5c4950e25647e39dcb40e63","up":true},{"one":"7b5c0e81c7f4e3ae29d745f6028cfa10b29a16a9c261b65fb8dd05d6eccc634612ad5d3029c8e9f39863a2cdb2682c25f090139bf5c4950e25647e39dcb40e63","other":"663535b22018a4ef0b151572ef286fa66c22c6e9b2913a69c4a735d4b0149bdf6c84bd83d710f8aa2627e8993b7f020750fbc6f56a3365ce4c840e2b3de1a6c1","up":true},{"one":"663535b22018a4ef0b151572ef286fa66c22c6e9b2913a69c4a735d4b0149bdf6c84bd83d710f8aa2627e8993b7f020750fbc6f56a3365ce4c840e2b3de1a6c1","other":"7b1e20217f594f87350542df31ff5ae8a635679bac7962d49c97e02190c644b673d03e7eba2626b45ca7ebf98d8a972dadbba02c18a8d2cbfc3e7a4cced5b4b7","up":true},{"one":"7b1e20217f594f87350542df31ff5ae8a635679bac7962d49c97e02190c644b673d03e7eba2626b45ca7ebf98d8a972dadbba02c18a8d2cbfc3e7a4cced5b4b7","other":"84abcbc7b5598ecfd91ceace0927921a5a3404fdb274fc2a2549abbede5f8e4f62c15688a4dc9a2d80262c45970c88898da245c6eb779f327a81d53a17bbc74c","up":true},{"one":"84abcbc7b5598ecfd91ceace0927921a5a3404fdb274fc2a2549abbede5f8e4f62c15688a4dc9a2d80262c45970c88898da245c6eb779f327a81d53a17bbc74c","other":"eab86c521f8f1ac67c015ab713f1236a08b0200757a96bf87ab8301e7967ae62361f0e14da14ca294fc8cb3b4726b52f4773101e21b032977c6a647241b59c73","up":true},{"one":"eab86c521f8f1ac67c015ab713f1236a08b0200757a96bf87ab8301e7967ae62361f0e14da14ca294fc8cb3b4726b52f4773101e21b032977c6a647241b59c73","other":"e6779e3bbecf81dde8b27d652ed2726c45c205db0d0405c4580014a4c91d739830276f77079108c98ac516ffa00194e77a0795f7140bdf36069b6475e58213f9","up":true},{"one":"e6779e3bbecf81dde8b27d652ed2726c45c205db0d0405c4580014a4c91d739830276f77079108c98ac516ffa00194e77a0795f7140bdf36069b6475e58213f9","other":"9133b0b3c8f680286eae90c3beebc3099a13de38775a3ff2abdeced62d05eb2ced5ac85eac0870156be03101024da5e1d9fbf3e1066ddb3f088221e64149acec","up":true},{"one":"9133b0b3c8f680286eae90c3beebc3099a13de38775a3ff2abdeced62d05eb2ced5ac85eac0870156be03101024da5e1d9fbf3e1066ddb3f088221e64149acec","other":"e1ecad3beeb6c19dce551e4a603c7b440b4498c44e298dc67bfaf4ed2c75bbea95df48b1cd1318e2ccb962cbae7c30ff258e73f8c3fc6b7e9ae7a47f7cf8e53c","up":true},{"one":"e1ecad3beeb6c19dce551e4a603c7b440b4498c44e298dc67bfaf4ed2c75bbea95df48b1cd1318e2ccb962cbae7c30ff258e73f8c3fc6b7e9ae7a47f7cf8e53c","other":"1d0244a13affe60996fe3cf51ba624adc746de0c7ea68ec5a31311a36077c5b5495e3d95c9642875db44c7ecae6ffed22e45f2e2d024d486760be2af9f4cf2cd","up":true},{"one":"1d0244a13affe60996fe3cf51ba624adc746de0c7ea68ec5a31311a36077c5b5495e3d95c9642875db44c7ecae6ffed22e45f2e2d024d486760be2af9f4cf2cd","other":"d9bbcdfd949010e6b2cbf6d0f34b27593ae410bdc1838876aeca35679571fe431d040a5ab085c0a77f111688bebed891da3587277cd794702437cb20d6aa4256","up":true},{"one":"d9bbcdfd949010e6b2cbf6d0f34b27593ae410bdc1838876aeca35679571fe431d040a5ab085c0a77f111688bebed891da3587277cd794702437cb20d6aa4256","other":"0a4eec7b0e05da799aca5b36d9e2530f2a89d1426b1fcb7d8f9a662df8a8b5b763767a20db3c9c63e0bd13c2a6e16d3ba8f03baf84f5e5d24917b3f211d9bcfc","up":true},{"one":"0a4eec7b0e05da799aca5b36d9e2530f2a89d1426b1fcb7d8f9a662df8a8b5b763767a20db3c9c63e0bd13c2a6e16d3ba8f03baf84f5e5d24917b3f211d9bcfc","other":"9bbbfac8be4a000f51a4ce8d024d2595b5d491afec0138922dddfde5ef62c664040c2e9304cc6b7bc688233b5d0c4644b8c8793227c078285a3ab894ef0497a3","up":true},{"one":"9bbbfac8be4a000f51a4ce8d024d2595b5d491afec0138922dddfde5ef62c664040c2e9304cc6b7bc688233b5d0c4644b8c8793227c078285a3ab894ef0497a3","other":"016f8f4619a16a07fbde5a18e362158d696e4d9f104a77787f26e32a25cd7d278256f8e0db865c488a99511ec27a5eddd5ebbd1c1397fa7f8db111062e5fe959","up":true},{"one":"016f8f4619a16a07fbde5a18e362158d696e4d9f104a77787f26e32a25cd7d278256f8e0db865c488a99511ec27a5eddd5ebbd1c1397fa7f8db111062e5fe959","other":"7acddc7fb6ac587b7e343804c768e4291cd28dd2b2b9207dea6ee82360d848a52d84f94e4c49e9c421f4f90e2d24f6291e2358783ab0230e6ecde82e69b4ac52","up":true},{"one":"df54af3bae257d437c5657905484e0d72e9560c46f8ba6b3437730234e05259b404cca40b0831e911605ff8a68a19e8fd7e958069ec8b40595928892f4fa220c","other":"4ee37acec2178ef120166265aaa2b64b09b315fb53861405ef46f2503c273eb9692e9cb4c2e67a8652254d430fd6e02dd3fe4cded20bb231a9fb834d292b0b24","up":true},{"one":"7acddc7fb6ac587b7e343804c768e4291cd28dd2b2b9207dea6ee82360d848a52d84f94e4c49e9c421f4f90e2d24f6291e2358783ab0230e6ecde82e69b4ac52","other":"9b59b76dc61223c7b37083b0ebdda22d3599563b3e3986f5db9d5b12f8c806cbdeb2345454efe957cbfa11eea9c7896aefd9a461210524805452ca100a9ea431","up":true},{"one":"9b59b76dc61223c7b37083b0ebdda22d3599563b3e3986f5db9d5b12f8c806cbdeb2345454efe957cbfa11eea9c7896aefd9a461210524805452ca100a9ea431","other":"e2e0419a41bdfc5bd76deae2ddce6ac865f886d764c9bd18799b79fa3b2b6ba66d765d26da2037e98317e1d7e8232a61e63c1d0cfa98c9137424151b46e07171","up":true},{"one":"e2e0419a41bdfc5bd76deae2ddce6ac865f886d764c9bd18799b79fa3b2b6ba66d765d26da2037e98317e1d7e8232a61e63c1d0cfa98c9137424151b46e07171","other":"5df58ba12334a1b4f983d642fe435901261767cd81f8f37c43e359f5584664e4d287e8c2275995604a3b3a4823418e35cd899a3db2a7db31570e19512f375481","up":true},{"one":"5df58ba12334a1b4f983d642fe435901261767cd81f8f37c43e359f5584664e4d287e8c2275995604a3b3a4823418e35cd899a3db2a7db31570e19512f375481","other":"5e86f39cf8338ba098a85d41e601a303fde311662b216ad32a2b7bfaf2b2b6dd1af3775784b39f2d85ac5fac96f05f3abdd8a2bd28ba16d939725fd6a33ae1b6","up":true},{"one":"5e86f39cf8338ba098a85d41e601a303fde311662b216ad32a2b7bfaf2b2b6dd1af3775784b39f2d85ac5fac96f05f3abdd8a2bd28ba16d939725fd6a33ae1b6","other":"df54af3bae257d437c5657905484e0d72e9560c46f8ba6b3437730234e05259b404cca40b0831e911605ff8a68a19e8fd7e958069ec8b40595928892f4fa220c","up":true},{"one":"4ee37acec2178ef120166265aaa2b64b09b315fb53861405ef46f2503c273eb9692e9cb4c2e67a8652254d430fd6e02dd3fe4cded20bb231a9fb834d292b0b24","other":"abd8f5a4d700c06ec00684b23d2d25c4df1a9554fcfc57b0ddc3fa476e6a699ba75e1213449f900803f83ab8194c6746664b547202047f35b8b3e216c7147bf8","up":true},{"one":"abd8f5a4d700c06ec00684b23d2d25c4df1a9554fcfc57b0ddc3fa476e6a699ba75e1213449f900803f83ab8194c6746664b547202047f35b8b3e216c7147bf8","other":"cb321c9b0fe2eb3617b8e2461aab170a9dad2c9b04a10eead4e37e551197ea0a7500eb1cb7b155efe1886486ef3d252d8ff0d309f2906a1126ca011d037da70a","up":true},{"one":"cb321c9b0fe2eb3617b8e2461aab170a9dad2c9b04a10eead4e37e551197ea0a7500eb1cb7b155efe1886486ef3d252d8ff0d309f2906a1126ca011d037da70a","other":"c665a6b1b7ad39b86bd4b1fe38b7ee95a0fbb1db15e91381ec9e5a235e33b69ffdc92c60dafd74b7b4dafca1b000e9274bf045abe5b93b1a9c2b31ae071a9898","up":true},{"one":"c665a6b1b7ad39b86bd4b1fe38b7ee95a0fbb1db15e91381ec9e5a235e33b69ffdc92c60dafd74b7b4dafca1b000e9274bf045abe5b93b1a9c2b31ae071a9898","other":"53df9cce9b0169e58ced53a123d1d8f6e8fdcfb4c2d781ecbb91bb7c8eba36946dd9d21c749259769825d8a6b3faa6bb87c8c6085a522f8a3e376061f59144d9","up":true},{"one":"53df9cce9b0169e58ced53a123d1d8f6e8fdcfb4c2d781ecbb91bb7c8eba36946dd9d21c749259769825d8a6b3faa6bb87c8c6085a522f8a3e376061f59144d9","other":"d7a319f69013b8375e64d19f015547462c84565b882337998f9e669c5fadd3d2ecf6374109903003e09f5d453424b5c7fdf52163d2cc8084cf81f94844946b63","up":true},{"one":"d7a319f69013b8375e64d19f015547462c84565b882337998f9e669c5fadd3d2ecf6374109903003e09f5d453424b5c7fdf52163d2cc8084cf81f94844946b63","other":"f38a9d792173a29c61389f5d84c005d78eac6e750659aad42e2d6df883f04eb3126b2c38fac95076eeed455b2031aaf694143922aa93a2d50412a2454dc56e28","up":true},{"one":"f38a9d792173a29c61389f5d84c005d78eac6e750659aad42e2d6df883f04eb3126b2c38fac95076eeed455b2031aaf694143922aa93a2d50412a2454dc56e28","other":"4f5ab12b9c5127c16739ad0d4f51adce90ba6736cd096eb185ea632789f4b26f1ebabdea4fd3b39dda5409ece6c2d92fd469cf4aecf9d29453e3e042c19b893b","up":true},{"one":"4f5ab12b9c5127c16739ad0d4f51adce90ba6736cd096eb185ea632789f4b26f1ebabdea4fd3b39dda5409ece6c2d92fd469cf4aecf9d29453e3e042c19b893b","other":"11d560045536e9d1b0b1b9e8944e00f0ca7f1e6788c9fdb51061820bbb3008ead92bb7836621bf58da7035c87a28328faecb4cb2e3cdb9d7fa4f45790e6bf352","up":true},{"one":"11d560045536e9d1b0b1b9e8944e00f0ca7f1e6788c9fdb51061820bbb3008ead92bb7836621bf58da7035c87a28328faecb4cb2e3cdb9d7fa4f45790e6bf352","other":"94088fe273f76e62ca4e43c095ad12215b4ae4c59942328b3985416fb19bbda0cacc143a49eff3fb644ad53a19d3f043260e43dbb70a0aa9c15829c21cecd3c7","up":true},{"one":"94088fe273f76e62ca4e43c095ad12215b4ae4c59942328b3985416fb19bbda0cacc143a49eff3fb644ad53a19d3f043260e43dbb70a0aa9c15829c21cecd3c7","other":"535f93057d46c4aae0902546550880be0b5ba67dca12350117d471d67f4f2b3f7bdff29bdc918767974c465df8fa1afa6bd6c29c0a36d51f71c4183673d906f3","up":true},{"one":"535f93057d46c4aae0902546550880be0b5ba67dca12350117d471d67f4f2b3f7bdff29bdc918767974c465df8fa1afa6bd6c29c0a36d51f71c4183673d906f3","other":"7ac5b07eb555af3bb4ca3f0f4b45204d43cc3798c244435909b97d9a32fc3abf0b50666e260e046bce826a7a102a92d389f8f39c5311e83bb34beddac29d50e3","up":true},{"one":"7ac5b07eb555af3bb4ca3f0f4b45204d43cc3798c244435909b97d9a32fc3abf0b50666e260e046bce826a7a102a92d389f8f39c5311e83bb34beddac29d50e3","other":"1944f98d4db32c56a5efda5a79aa5f276bfab1e084d6611fec0e735b8bc0f45b457cdb74a23fc83b2377821fa8316123c9877acd6db7c41058ca5d3cfedaecf9","up":true},{"one":"1944f98d4db32c56a5efda5a79aa5f276bfab1e084d6611fec0e735b8bc0f45b457cdb74a23fc83b2377821fa8316123c9877acd6db7c41058ca5d3cfedaecf9","other":"1c2f7ce55a6e38487f3b3fe6083a79f914cd6d7e4aee8f5d56b4a61b3eb584e128c56998db0e13e775edee3adacf54f09960a041dab3daa80a4f8a3b42760c1c","up":true},{"one":"1c2f7ce55a6e38487f3b3fe6083a79f914cd6d7e4aee8f5d56b4a61b3eb584e128c56998db0e13e775edee3adacf54f09960a041dab3daa80a4f8a3b42760c1c","other":"6ab6ec15635b2fda22542c99df0a3313ad4583ba0fb3f31b8f314e3ecad446d3fb0fdfcd2be9b08374b1a7e049fb68e69e8dacdd13f1df5007a656f6b11adc5b","up":true},{"one":"6ab6ec15635b2fda22542c99df0a3313ad4583ba0fb3f31b8f314e3ecad446d3fb0fdfcd2be9b08374b1a7e049fb68e69e8dacdd13f1df5007a656f6b11adc5b","other":"74d84cfdaf32cd4cc67771f29878f1365120bd65cc14848008d5386a81f495bf88eb4132fa38a2cc109ae1e7f02c9b97597ab9d1a9c19c945e710ab9df07cdcd","up":true},{"one":"74d84cfdaf32cd4cc67771f29878f1365120bd65cc14848008d5386a81f495bf88eb4132fa38a2cc109ae1e7f02c9b97597ab9d1a9c19c945e710ab9df07cdcd","other":"6b4e376e9c94242b6d42688c22aa9ab418cb6dfb1cbca1c69de0feceec8d3af29fb005017aaa6e503cc0c03cf0dc5bcab55e01cd6f64b9efa02ed87c03020003","up":true},{"one":"6b4e376e9c94242b6d42688c22aa9ab418cb6dfb1cbca1c69de0feceec8d3af29fb005017aaa6e503cc0c03cf0dc5bcab55e01cd6f64b9efa02ed87c03020003","other":"92d6ef729992f0de886076e5f8cdc42cbbd70b29e79c25e0b3d22b6575d3d2508d47b42f581e335455483d43625bce4e55f88cab9ff2073ee8dab746357864fd","up":true},{"one":"92d6ef729992f0de886076e5f8cdc42cbbd70b29e79c25e0b3d22b6575d3d2508d47b42f581e335455483d43625bce4e55f88cab9ff2073ee8dab746357864fd","other":"57cd4c0048b459192ee46e19ec7df777e600f256e0dc8c3019431eb7bec3c020b9504ec7aea3dba8188658ca5b830ec40af6a8540ce10e04badc6c695d009271","up":true},{"one":"57cd4c0048b459192ee46e19ec7df777e600f256e0dc8c3019431eb7bec3c020b9504ec7aea3dba8188658ca5b830ec40af6a8540ce10e04badc6c695d009271","other":"831cde5b651ba327b059da4c7f84b184bdd6bb99c6690ae816affe25d42c6c3dbe5b59e2b6bf23e9d0f6c485bd341ea57ba1a8220d18b0a40e156b77d84f79ef","up":true},{"one":"831cde5b651ba327b059da4c7f84b184bdd6bb99c6690ae816affe25d42c6c3dbe5b59e2b6bf23e9d0f6c485bd341ea57ba1a8220d18b0a40e156b77d84f79ef","other":"71f89efcf939294bb94ac669c8afd00def58c8dfad519c226adfa068692d588ef797116d42aa146b9d34f3be35ec7c014022640ab3c0f1f9034e44ab1a26e246","up":true},{"one":"71f89efcf939294bb94ac669c8afd00def58c8dfad519c226adfa068692d588ef797116d42aa146b9d34f3be35ec7c014022640ab3c0f1f9034e44ab1a26e246","other":"4ff66e9b5d3fd345990bd7605bdc222b78946f0c13b72bf80352812b2426d8f1d36c93e6c8713566004615e8a78ecab12ab0cfba254c0967eeecf8875b25bdae","up":true},{"one":"4ff66e9b5d3fd345990bd7605bdc222b78946f0c13b72bf80352812b2426d8f1d36c93e6c8713566004615e8a78ecab12ab0cfba254c0967eeecf8875b25bdae","other":"9bd4f0adb9a966cc5ba632f1b540fe9cd6c8e39fe1a041b315697679cfb04b735952062ce057d456677cc34a84301f26bb727a4ab2646fee734f80a22c620746","up":true},{"one":"9bd4f0adb9a966cc5ba632f1b540fe9cd6c8e39fe1a041b315697679cfb04b735952062ce057d456677cc34a84301f26bb727a4ab2646fee734f80a22c620746","other":"58cfb20d3da3641e0ad529b9edbd4b590a8d1dc9d1ed7b44ed3187dba9260bd7c732fc10981f5b9bffd31d362cb05150173618aa36138984431d94a323a9b313","up":true},{"one":"58cfb20d3da3641e0ad529b9edbd4b590a8d1dc9d1ed7b44ed3187dba9260bd7c732fc10981f5b9bffd31d362cb05150173618aa36138984431d94a323a9b313","other":"094f9d0fd3bacb17ac67a2edb8ed394fbbd1c8d478233d3269cf217e7b788e21042374936b885bf23ee4f9e03babbe4e08db283dfc2a6e052a8a5ba133717dd5","up":true},{"one":"094f9d0fd3bacb17ac67a2edb8ed394fbbd1c8d478233d3269cf217e7b788e21042374936b885bf23ee4f9e03babbe4e08db283dfc2a6e052a8a5ba133717dd5","other":"7646d08b3e24183e3814de130235c41eb88a5a2abff23eaff3c91954ad3ef55fe27da422dac5b894312276bf1a2f1aebb8b636a8d4a0c93d9b016d441df3fa19","up":true},{"one":"7646d08b3e24183e3814de130235c41eb88a5a2abff23eaff3c91954ad3ef55fe27da422dac5b894312276bf1a2f1aebb8b636a8d4a0c93d9b016d441df3fa19","other":"9b618ad34d0dfe0fccbd5b8af365cbcdbb43e802df5f23e91c20d21f3ead6169d52bf0db7e5e111abef630c9853419fb33a88cf111d8507b8708208b5d65e35e","up":true},{"one":"9b618ad34d0dfe0fccbd5b8af365cbcdbb43e802df5f23e91c20d21f3ead6169d52bf0db7e5e111abef630c9853419fb33a88cf111d8507b8708208b5d65e35e","other":"4a030ebcb1a59230759d25a3c87daed22906b520d55a78eab2083bb52358ddc3a5d2d7c3265e6c54a990bf32d0dacb85905a4173d72ac18fcd74c43ecb8635c5","up":true},{"one":"4a030ebcb1a59230759d25a3c87daed22906b520d55a78eab2083bb52358ddc3a5d2d7c3265e6c54a990bf32d0dacb85905a4173d72ac18fcd74c43ecb8635c5","other":"e0f78c59a61f2a953553cd5742c58f4a82e38e35ac7eaa237a6ffc9fb0a3a26a2d1d1afae249e611d1320f2cb25804bdbdfb6d77336449716b0f4beb3298b8aa","up":true},{"one":"e0f78c59a61f2a953553cd5742c58f4a82e38e35ac7eaa237a6ffc9fb0a3a26a2d1d1afae249e611d1320f2cb25804bdbdfb6d77336449716b0f4beb3298b8aa","other":"84dfd4e4d9f1204893f190eacc4c3999e175c433f70de86e335d27477c097a0552f211a21764f01a708da4c9e9e6552191a61d3e48f41d0e84f01e7ae3beb34e","up":true},{"one":"84dfd4e4d9f1204893f190eacc4c3999e175c433f70de86e335d27477c097a0552f211a21764f01a708da4c9e9e6552191a61d3e48f41d0e84f01e7ae3beb34e","other":"ba21a373781966135d6225adae024a3f3e421b852f72f8b0569cb92fcff87c33f7e5b799a509b8eff6ec6dc46a9b17d5bae1e91ec7c54c0c712d893d54b140fa","up":true},{"one":"ba21a373781966135d6225adae024a3f3e421b852f72f8b0569cb92fcff87c33f7e5b799a509b8eff6ec6dc46a9b17d5bae1e91ec7c54c0c712d893d54b140fa","other":"fd4968df03d767a223bf7e4dbe26b5c27048298df40e81cad50b344fb3e6837965f2646dab7ffb2891a5c507343ed84bb8bbe403287b51dae538d58fcb6e7623","up":true},{"one":"fd4968df03d767a223bf7e4dbe26b5c27048298df40e81cad50b344fb3e6837965f2646dab7ffb2891a5c507343ed84bb8bbe403287b51dae538d58fcb6e7623","other":"07c63ca5d0309e30d1ab12e7fc142e6d37904b552639cfa97850161491f28f20d87e0304be29357bcfc2ff52fc52fd0d4f6e6011ebb239cced8b5c8dad7abf45","up":true},{"one":"07c63ca5d0309e30d1ab12e7fc142e6d37904b552639cfa97850161491f28f20d87e0304be29357bcfc2ff52fc52fd0d4f6e6011ebb239cced8b5c8dad7abf45","other":"920a301186bdf665a721676ece7c180413369ea6eff7537f42049d9eb409f28cc864099590116e885f57368959fb2cff7003697d9b1515e68bf3fa7aee0278ef","up":true},{"one":"920a301186bdf665a721676ece7c180413369ea6eff7537f42049d9eb409f28cc864099590116e885f57368959fb2cff7003697d9b1515e68bf3fa7aee0278ef","other":"89a5b92a9ca045f12c35a70084e6f41f9775a25d6f105f8c9349c7b5e107179d8a96bdbb113b2680edf5183e9a42fd64bd7b29d0dc7797c583b833f869313699","up":true},{"one":"89a5b92a9ca045f12c35a70084e6f41f9775a25d6f105f8c9349c7b5e107179d8a96bdbb113b2680edf5183e9a42fd64bd7b29d0dc7797c583b833f869313699","other":"beec648d79437a5d7b4140ced45d82d035c6f64f9c67c58386703811d97c3846787eaf274d2298df809475f0b7519df696563cb8e9a5fb0a9cc419ab13fa8d41","up":true},{"one":"cb94a8270d0050378116b5815ff17dafbe20f5303839c4fd57b981d4687a4b145e4bccec7e9af9b9475005930148ffbfa97781a0762c8e9f352dc95565fc8732","other":"76cbf9fc0f3517fb615fa96104780218e85d064ee5a1d518f3b78f4dbebf144df38c427445fdd6c9b436489c00ff9497d747a8fd70f380f95601d59e52e021e8","up":true},{"one":"b597c9ba4da20c49fc4ba019571321d2579588636cdaceb9f225706574970adbf4771dcf186b1decd4e14cd5d257e30a36ca829829598c1775902201ad9793e2","other":"3dfd733dde9414af916625ab981777ff1ad7ca0f6d1e4e7d9e2739969e21182fd13d85e281868653e7325b20069356b11524b54143c47fd3955a911cf7325ad4","up":true},{"one":"302c37f28c69fdcf00b39ce0c0223de0d94cebc2c0b068315b95b76b5432573ead0656569441029ba9054d8d3d959fd8735e73913af5ce3f1132f8271fd437ef","other":"807340e5fdf6c21a56ef2fd158c32e92201206ca85fcc147165a408f7a735964afd47c397e663610ac53870ae722c0317291732b0422f8aeedae783d9c730218","up":true},{"one":"ea57884dd42aec5a76eab43483bf7c4ae2c19eebf365013731de64494d10a3b4cfe34c86c79437f9012bc8cf6bd761435eefadec17600f4b9e4bc234532d6282","other":"24662a43944228e4ff74736bcf0a0a4f79c87ecfdb739225b2fc45110c11bfc38aaf2d09d98e5817477848e553f187ac5408bdb864518dfa7f5df542768828db","up":true},{"one":"4e95fb8943ef6502fa470870a7ace4ca11e18589bd2073167543a922317b35e40b5068934d07e56c8fdd23354dfad51fd2899db854f189841f02b5914cd97749","other":"829b074b70d757da6aa00f7bace3cf1b5d2d4eeadb7f370c1a85374a01a70b54ac53d747267e386f3b41e6d790fecdd6e74b8f89745501ee82439a66ea54443a","up":true},{"one":"3b570117addeec03c2694baf28e246f91907268fe665c6c90356120332794258ee57a60853c19e9fe25d042ca42a5be7fe0797d84199174de8132f1ef4a9349b","other":"24662a43944228e4ff74736bcf0a0a4f79c87ecfdb739225b2fc45110c11bfc38aaf2d09d98e5817477848e553f187ac5408bdb864518dfa7f5df542768828db","up":true},{"one":"27d9048707a89f1a61e44fdae523c0128f2a7050308bd3cfefa6c3e03040a0e22f11ab41275f22b8706e6695ab93320e2af35179d772581db5f49f960750f2f7","other":"3b570117addeec03c2694baf28e246f91907268fe665c6c90356120332794258ee57a60853c19e9fe25d042ca42a5be7fe0797d84199174de8132f1ef4a9349b","up":true},{"one":"cb310c0e86aa455d7c9af6394ae38561c901da30a51d7ccb7e66a09d9a8f192ae8caeff106043426d56397088f141c4e01e3b98f1ee583ffc7318b5f730f3ac7","other":"4b784f072b7c96c30612767425f552e30e45157e70139dfbe0ae4ff86dc31601adec60f8a3ad9747b02b5219073d8813af9b09d59eaf7ddb7ee24856aff6fa8f","up":true},{"one":"2f903b2fd4f9432b7d91b5c3e4c7ee3cb9c56fe7efc4baff0edd06fc75e4b7492f2c3c929755746df59c9f95d437a12ba40ac138d08f5bc7aa091f49f3b852c2","other":"7f357b8d81bc2e5c6fcb081f23a42b3e2439f050d45c45851994a268d1c71fcb1f39f8c3f75ce921d3fbf80fc0e73f0b9609d72001dc4a6b65b526d312a4f43a","up":false},{"one":"385168340139236a0e0f537fa693122db9fa02a377c96f31aae54718e92624fc0288164877e63616651565e055c53f7074ab2fdd18a837da6faf644941305bf0","other":"c2705ee7238ef9305e4da196653cde707649435a1e8b5b797d164e5ca06184a77af5bd7fa938c995fdfcbce724fa7eca3d908ee34891ab62cc6dfd411c3fa1da","up":true},{"one":"9194a3a4c8f3235203e48bdb10902d958d26c342805ea6365af9711213536509719d917c694f9a4fbdde6889a4c92299a5301f0275bda4dbcd2541b5bff5b271","other":"f6ca39b3ad803e99f4e4e9cf759fff6abdf06e6972bdbe524f6eb930c669d6f0e9b91f3de9df394b0d661b068273861391bdbac948ad911351c48cf02f874db6","up":true},{"one":"bf4ff51cc3d9a9d8cefd7e346ce1384d06450228a6086fe12fb0c60fec54bb6478f090bb638fbdbf8f41f7bc6420cd8a5c8b1b8566229b6851167375ef412f46","other":"083e67bb19e30d14e4df6d2483367d6659d9b56744d53d9cf7fd15954c327e1bc88a5d0db8833634e1dad7209164451f8934b59f76b5990059261abfd650519a","up":true},{"one":"cb94a8270d0050378116b5815ff17dafbe20f5303839c4fd57b981d4687a4b145e4bccec7e9af9b9475005930148ffbfa97781a0762c8e9f352dc95565fc8732","other":"2f903b2fd4f9432b7d91b5c3e4c7ee3cb9c56fe7efc4baff0edd06fc75e4b7492f2c3c929755746df59c9f95d437a12ba40ac138d08f5bc7aa091f49f3b852c2","up":true},{"one":"a7378ee34876af17c6cd94a69b6b741ec7891ff5375bc4241d48608d047455ed48e6baae80ee88d4710c69ae615cf195cee26c94b54de1bb935628ce1e3a723a","other":"0f9f7e2dce4ca266c3ac0ec3a8854200b54487f5308e3db418461aeb5f67c81d332619b6441b468e480941e63100ed1b263e7adc20689dc3dcda578bfca538fa","up":true},{"one":"2a63d875e715c2a43302d32d86d30c7d7faed46c08a67bf488762637216b99dd87333a66df6d9f3a57df863b1f1a219ddbeebb9f3e92e523bd08540a195448ca","other":"043fe7085e8c90c18270f84dba5fab138e50216a1cf8d81a3794d156fad7fc81d1422aff169b244b13f91d73eebb5de464f97b1b93b3ad2a58959cff19238842","up":true},{"one":"617595a230e0a74a3db3b47cd27b941e02bdee9a84cdfa8eaa63a55941eb5caa79e20fb69726a4d46a0e5aeed24039f8c5a20679a692df0bc140f42558ca9a2b","other":"0b30b36e155db04c448b662c4df695068b2331cdbe2772aae5fda84159e977515a5ff2e156bc225a9281fef2383926ba8cb11e9c1846fb40db241e524ac14e29","up":true},{"one":"3e488a7208ce0e097ce47fc6651a13e95cae137d1a054a09b04d2f59d45faa2594a8c3b395e77ad1a3c2edcd827dda73c0c97dbaa6d9519a79184a0aca01ac4b","other":"0f9f7e2dce4ca266c3ac0ec3a8854200b54487f5308e3db418461aeb5f67c81d332619b6441b468e480941e63100ed1b263e7adc20689dc3dcda578bfca538fa","up":true},{"one":"f9ffe87c52ff4c22bd9696af32e0a9d34bb81fb84d9d8bf5aafe2ef9696e7b3d6460bf2a93aecb066133f53416bde841a02d6967bd06e3d4a714f3b2c123a947","other":"3d2df188704eeac09c8b291bf275a73888199a231c832c51dbc3d746968d4b51a7d5eae0c7c9b8c8e19f5e28d38c375e01abefa343f31dbe221deb837ab8a0df","up":true},{"one":"07f25fdeab2b44b2e92fc80fca7de9e4a8547d27a98a54593b3395c270a9ff3f2a5da62a2e8531ce86359f0cdc5b6513b773dfd64cce1b83e47065d9760a2c7e","other":"a1560ce7c1f1d5972f027a8e9cff820611d84764aa067434a75b63887bc4268a259101486d34b7fe83dd735e799789986cd3e9b156c86ede598bd86af4454924","up":true},{"one":"a7507aa5665e165ab2e2a07def272f0677f9d6d35bb82268a34214384e7d8ef7635a299368752e63cfd02d4e60231076baf23cfa10d17492e55181b391ecf335","other":"7554993f6efd8d9016ff525ae73c41ee2e0dbd4970c563ba9b61a99c1c8943b433c4b7d48450f6e0fbc9ac198d907698093de20e6c1f7755520fb1e1cbee4eb4","up":true},{"one":"2ddd49fae11d8bd2e7e75a481be267fa846f51cc1160bc326aeea51c542323ff444909de11e2731e835140bc0b1b32020e1e73fa652511a381222bf0aebc4081","other":"e06a789a7f6988e1ba5e8358b6cd4292555c7f9f7f0dda6fc01cc26d24e49a8c1ad694423ad74aec6d80f4b99e2bedc49b6a5f2670744cedee3a3e1848e6dd07","up":true},{"one":"5bf29c02f07faf7ae8e46389e1b98df4f5e88c9316b5151685e6ae7b4e622cf171ff09f996aaa8ad846643b3bfcbd1ad96cdc249afccce439bb5c55246b95801","other":"7aaf7817b93aa6d2f50513791f9ad7629a901ed0dcb151189f44763f83423446b20ec79a48fa260cd9bc2907d5f0ad06b2c4c5e6d812f3d8876c8020ebe41019","up":true},{"one":"e3c8a97a2d95dd543f9e2b41d9dce6256e284296f866f4f92e9925f8c7519dea23fd6d1a11153b93c10d6a32295e7b9bcc16024e690e4a0dc84fd25ee0f31b2c","other":"062e0ca43a1885c4a7ab2a5169790f9081e3e9a2dfa286b8cc592d5ccbf13d7a82b72d23361a19026d04fcf41b752ea320d98359d770aedfcee626e21c3494b3","up":true},{"one":"57b47f692f4d69a5d2c9c193680eb4ccb5a6c574662df0138504a549f3ea74f20c5b866ac4d9e76c4b49c83f5fd692ead928ea20dfcf643a11a1c1e841c0ec42","other":"420b9c90584651c5a3fe3c16aa377444a321dca934f8a097d01a616554067feabebf2fdc8d2a25797f29a8fef30d5e2c82f8e85b20f509a880367b9b0ccdea47","up":true},{"one":"e06a789a7f6988e1ba5e8358b6cd4292555c7f9f7f0dda6fc01cc26d24e49a8c1ad694423ad74aec6d80f4b99e2bedc49b6a5f2670744cedee3a3e1848e6dd07","other":"420b9c90584651c5a3fe3c16aa377444a321dca934f8a097d01a616554067feabebf2fdc8d2a25797f29a8fef30d5e2c82f8e85b20f509a880367b9b0ccdea47","up":true},{"one":"4314b0b04331973ed29a58843951f144ac3d09bd5d57b6cd9aaff9b73a7b2ec81e344a3e4ece462bd2081b837a06310e787ef3bb889dabad46fe7efd394c8342","other":"bcf8e831821a5bca359fb824c7dc4d66906de82f3663a0a853d96880a8ca0bdddcceb1b66dd1f13f75ee20fde50fc9de545bc25767f228baee910e0dbfa8cc27","up":true},{"one":"4e68553db7be307b8379e8bec383b5c92e4b23debcefca575d24504e2062618f74c26e60e0d9e47f096997a7f841e2c32c994124f495ef3352ef964b33fd3a51","other":"fde7705f5013c3b6b76a35505c1e3d57c033a337f2a71e912ec3a3d2da8e113bd7c36d94908357e9f7654660621f647ad8c66b0126dfe91dbfa3b8c7bd2183d3","up":true},{"one":"bcf8e831821a5bca359fb824c7dc4d66906de82f3663a0a853d96880a8ca0bdddcceb1b66dd1f13f75ee20fde50fc9de545bc25767f228baee910e0dbfa8cc27","other":"7aaf7817b93aa6d2f50513791f9ad7629a901ed0dcb151189f44763f83423446b20ec79a48fa260cd9bc2907d5f0ad06b2c4c5e6d812f3d8876c8020ebe41019","up":true},{"one":"3d2df188704eeac09c8b291bf275a73888199a231c832c51dbc3d746968d4b51a7d5eae0c7c9b8c8e19f5e28d38c375e01abefa343f31dbe221deb837ab8a0df","other":"4314b0b04331973ed29a58843951f144ac3d09bd5d57b6cd9aaff9b73a7b2ec81e344a3e4ece462bd2081b837a06310e787ef3bb889dabad46fe7efd394c8342","up":true},{"one":"beec648d79437a5d7b4140ced45d82d035c6f64f9c67c58386703811d97c3846787eaf274d2298df809475f0b7519df696563cb8e9a5fb0a9cc419ab13fa8d41","other":"62dab8b21640e1b44dea452dd7e7de93f27a44840da72d56b11aa96e8463f3a4bb15e75a954d19fc897ae0030b16181d271b79d8198b7cffcddaa9ffcfdcce73","up":true},{"one":"e98a08e8e3544727f5ee27f4465375a67ffba490fcdbfe7bfdc909f6b68bd279f776c65d38c2ccfc33079f852f76349c94d68fc6989c0d981f22333f036a4bb5","other":"4b784f072b7c96c30612767425f552e30e45157e70139dfbe0ae4ff86dc31601adec60f8a3ad9747b02b5219073d8813af9b09d59eaf7ddb7ee24856aff6fa8f","up":true},{"one":"afe5b217dc512eee45575c189826ee5640d11a0ac9e8e4b03e9e62e6cf6df9de500bc8a36cb7d82a2280ce184409164f1772cc5c9e59ad04361522d2b8c364e0","other":"62dab8b21640e1b44dea452dd7e7de93f27a44840da72d56b11aa96e8463f3a4bb15e75a954d19fc897ae0030b16181d271b79d8198b7cffcddaa9ffcfdcce73","up":true},{"one":"ce0a09bb6fe4c9c93c3dbd800ca9c9ac0714f26a8f8dac2149b6ce7a9011912a5621ea2e45de35c4d31dfe5add00558fdba5dd21acf2d81ba391e82b5b3a5804","other":"7808fb798d22e78fb1d39b87ddf99a503f820993bc64149eca9e81d9d58fc1adea60d8de14a4f06cb89f3190c0ef0c5e182621a14c9361ccb7e0cee667599cc3","up":true},{"one":"5dc69635f6d573c824ea83b18593a47f9f21a6f91ce18d2bf977c97d21f8d2a8ce88829244d12a07d949bbd52fe8a2035bc89685fe1bdd4ee20d766d75d3deee","other":"17a79cb279306b6bbd35219278f6bba03111079d6c4fadcd3c5e57b09678e111bda5f8e36ca3d223e51e255d6e857363b7741e438b32ec6e6c0dc1b224071081","up":true},{"one":"5526d86ba9df651091d88460a9bedb9cedb957d452a635e1db46b9fed78082022adec0047cd7485956a4ecbb0e18107595de0de3c35242527cd302bf74a19260","other":"3e488a7208ce0e097ce47fc6651a13e95cae137d1a054a09b04d2f59d45faa2594a8c3b395e77ad1a3c2edcd827dda73c0c97dbaa6d9519a79184a0aca01ac4b","up":true},{"one":"c332fe1f9b6e25f72c7150631ffa6e0929ff6eeab5d17aa45eaf669bdde869cf404505ae990a529aa3ca797cd0a96f31cc41431a5d4a163132be566f91623c08","other":"b4a5efa9028b2d196855393892f79993c2812d02b758f98813ddf82c5d943faf6d66eff811cc5a51936c118f4c768c0d13b54902095e040c602761e63c08655e","up":true},{"one":"aa9a94d6e4eaaed20113c21752c224e3a052abd3769bd6e832759dbaf5154a943cf094eacdcb0727c2fe51a11bd7fc0793d7d5e3312b0aba89d428a00e1fde0c","other":"ce0a09bb6fe4c9c93c3dbd800ca9c9ac0714f26a8f8dac2149b6ce7a9011912a5621ea2e45de35c4d31dfe5add00558fdba5dd21acf2d81ba391e82b5b3a5804","up":true},{"one":"f54335964d9b4eb9813eb05f40ef1c523bbf0faac5a04c4737467d590fb6b55c7fa1fc5d4d32c5491d8766b9be6fdfd3ebdb25c5ffe1719f36c86ddf87ae3a85","other":"b26f7c0113a5ae885f7c0e608aea7022a9c8bfc40c5643e60b2ba7343ff09c5be0bc08be34dde3c6b85fea192a46d4764770c12cbaa233df4231a1b99627ef9d","up":true},{"one":"e2a27dcdee1f89fa362a85c4397840cd8be4ad8d1b9ccb23188c303bcab7619f38772f71385922d090390973b62fb8249efc103f71bc761041bcb3880ec0b935","other":"fe62314839c93d2f6e3aee984d5f0b321897c6f39e66800d3de8b773baf6f19e0a03cae025df512aea8d5f1b667b6dbb15c192a90a76d3031c14e33e5c16c4f7","up":true},{"one":"2b70e5ffcc0bb1c4f8acc09dd1016e67c9c96c92d091ad481efbb71bd8b2a5a5869c6d668617a9b2cbfe91baf5edfe150c3824c84d90899a974099071d171441","other":"8c6d77833bf1a98beabe7a92d985d13d52fb2e50768719ffbc6fce21ea676802a074b6e620b3ef80e12fad04f94a3c288d91df9716a6cfae09ef073b9dc1f2cb","up":true},{"one":"f915e2398aa5d4370de87504dd76c21a7d0be2581c2ab55b7a47743f1bbaef36384eaacec22760f1e914ceac9d96a10c3d66eb27475ef444e77fee979e6e88cb","other":"5eccdbcb15ef42dc96abcbcd8b8db75d9230de10e3c650620737f6cc04ba4fdbf59ded5daa801901c191be186c329ebcd37ba83bcf794064ad4e11bf10d3f775","up":true},{"one":"eaca77d20c4ad6b87649eba21b750a4b1a2c575e06bc42679d18fce16fea15212e9a7408c16f3b24d8dfd1e397314637e72e292845d09534a39035bd9203ee9e","other":"97981f4b825620985b746c85824d7a4d307ee25d60a72c2b7de4b1d4f3b1c002652adc3045842d350f849789e410a0357a0b42fa637a1b4fc9d39e44f8a674d7","up":false},{"one":"d3105ede6c21bc643d523afcd1309a5dcf03f70797a92f167c3a19f86ae98882fe1a9d4094d7a3dee4a0833b8075b6c3e9aaa7f4879dc47bb388c3ae85522288","other":"97981f4b825620985b746c85824d7a4d307ee25d60a72c2b7de4b1d4f3b1c002652adc3045842d350f849789e410a0357a0b42fa637a1b4fc9d39e44f8a674d7","up":true},{"one":"6f60ef501b41f9049419b033ae8d793a18067bdcd60347537b0dc3873bdd9a2d10d24909cca7c39781765746128c2165596f6537a94f58279523faee71f9c51d","other":"fe62314839c93d2f6e3aee984d5f0b321897c6f39e66800d3de8b773baf6f19e0a03cae025df512aea8d5f1b667b6dbb15c192a90a76d3031c14e33e5c16c4f7","up":false},{"one":"17a79cb279306b6bbd35219278f6bba03111079d6c4fadcd3c5e57b09678e111bda5f8e36ca3d223e51e255d6e857363b7741e438b32ec6e6c0dc1b224071081","other":"7808fb798d22e78fb1d39b87ddf99a503f820993bc64149eca9e81d9d58fc1adea60d8de14a4f06cb89f3190c0ef0c5e182621a14c9361ccb7e0cee667599cc3","up":true},{"one":"cd8815d66aee8bd488d4e5e25f0cc9c71cc65349f701ea26b1d6cd9c039d16fcb473dbf270a3b33187720ccf4b0ce4f78a6d6edd05f4fe804772d5b6ec45bbd3","other":"59b53f8a562bee519276e0eeccfcf8c975d3102f5d0cccf5abcce291a8a5bb817c04604f123686177a50a03b9d7559ac469962d0159d1d93e4ce58a304d04b55","up":true},{"one":"97981f4b825620985b746c85824d7a4d307ee25d60a72c2b7de4b1d4f3b1c002652adc3045842d350f849789e410a0357a0b42fa637a1b4fc9d39e44f8a674d7","other":"453779010ed7c59761da47ccd8869d3fa8349795e57edb9eea416c0712301ea622c7683858e309d19ab137ddb0edef161d0d00a361abeecf0628c3ffabc629ea","up":true},{"one":"b080891d4ba6d3ab224984360597f9c555bd1367630f5420bfaf230419a05b2be58bebf1554e53eb4c0da81cfb66d4f7697dd65143f11841ff62d8a0d82b6b67","other":"8d4920d6e3a6717699b5a3af068cbdfc16858d7e393d158d41b1b5f345b47129eef89e1d055386c518f400b134678c21590f0317dea3436d4cef60f45455cf12","up":true},{"one":"b6a998dea59194cc60ce97c7c9702368411889cb6905516b23f41cc5116fba8d0f237d418318eb0c333cad18003c0e9a6bd8c99080520771f2bad640e2e5ec1c","other":"8ca3b63cb84f1e9883d82809a9b6777ec1029ecda96fe93b4d494ee9cbefcad13f381b3e480136e542e01054fe1ede66c65db84a0009871ce49383db461c8438","up":true},{"one":"8dd8ad560af84bec579cadb33d51711aa61b6ed22705010336df5a71a94591173b25e869457429c4a199b205fce8e73530e28203e18b971c2001715e610f152a","other":"2f360209383d6de4ebd3b4abaf77796520b8654270b03f2151eac4a01b4417d7e0668c1f9ad30c20ff49aa8a0ab33dba5e6095619d1cf04b7af841722ab773da","up":true},{"one":"be514f5f17f3177235acb24112b578edf0e373c469073226e547d18080905fd062d572be18e943f13bf9fcf5871e89ceb630a1b848a0e370ef8ef8c6d997a363","other":"5eccdbcb15ef42dc96abcbcd8b8db75d9230de10e3c650620737f6cc04ba4fdbf59ded5daa801901c191be186c329ebcd37ba83bcf794064ad4e11bf10d3f775","up":true},{"one":"829b074b70d757da6aa00f7bace3cf1b5d2d4eeadb7f370c1a85374a01a70b54ac53d747267e386f3b41e6d790fecdd6e74b8f89745501ee82439a66ea54443a","other":"40bdac599b00e9c41ad6476ee415c33d9c17c5aa672692c2404e523b29dc315da929a86874bed87fd9009871805d1dbf3098e7a817193e3b08a6eee66346da79","up":true},{"one":"40bdac599b00e9c41ad6476ee415c33d9c17c5aa672692c2404e523b29dc315da929a86874bed87fd9009871805d1dbf3098e7a817193e3b08a6eee66346da79","other":"5420da16f7ed5de6b498dbc9a83b7e92e1f9900a6d04ef7351a0bfdfd442b98a5634f28fcea32ba3f3166d21c8ff5a39be70895b32acbdf7592d1d616a345a21","up":true},{"one":"68cc8b9a995eef6170abf88bd5fedca06ffcc8d75f247f6041c13e7dfd292727ebda1ff86b776e33b6634355c55e0f8c22fcdb5f9a6e2f22fe1af7854c3b4273","other":"df4c3505e09e1baa88470117b964e758c94f77a4546489ab5ab7f4aebfdce424729ace8867475715fb68f05c66c9674a5767549e266c4fadd1c703ddd735908f","up":true},{"one":"76cbf9fc0f3517fb615fa96104780218e85d064ee5a1d518f3b78f4dbebf144df38c427445fdd6c9b436489c00ff9497d747a8fd70f380f95601d59e52e021e8","other":"df4c3505e09e1baa88470117b964e758c94f77a4546489ab5ab7f4aebfdce424729ace8867475715fb68f05c66c9674a5767549e266c4fadd1c703ddd735908f","up":true},{"one":"e023a51c5bd26e1754d6461345143e94baeac799947579ec7adeccd105de39f85afbceeb5037cfc0b820b9f4446433f034d9e7de7326d45df5a967a8099dbb10","other":"df4c3505e09e1baa88470117b964e758c94f77a4546489ab5ab7f4aebfdce424729ace8867475715fb68f05c66c9674a5767549e266c4fadd1c703ddd735908f","up":true},{"one":"54b3c57a4adf4dbaf31b85ed1b8dccd6249faa16dd96dd230189f47f57970caeed36627cc8e1b0794707418d580f5bd6001c07be6a79216695f1253db24926bb","other":"e023a51c5bd26e1754d6461345143e94baeac799947579ec7adeccd105de39f85afbceeb5037cfc0b820b9f4446433f034d9e7de7326d45df5a967a8099dbb10","up":true},{"one":"2f360209383d6de4ebd3b4abaf77796520b8654270b03f2151eac4a01b4417d7e0668c1f9ad30c20ff49aa8a0ab33dba5e6095619d1cf04b7af841722ab773da","other":"ae2a996d3b562cb47a564934037949da83b1bfe194c23754f3dbe2372ec27654f4f3b6cb7f394570f308025589c065870477667e5560dbe5a8ea1625740699cf","up":true},{"one":"855bdf057f4a6b095e2000ada199447b5b4f2f8d78d2ecbaa0ff1fbf761788870ee999266ad3b26efa02be1a46a4d92ac0debb85a2ceab3442394ee7d99e5355","other":"5526d86ba9df651091d88460a9bedb9cedb957d452a635e1db46b9fed78082022adec0047cd7485956a4ecbb0e18107595de0de3c35242527cd302bf74a19260","up":true},{"one":"5420da16f7ed5de6b498dbc9a83b7e92e1f9900a6d04ef7351a0bfdfd442b98a5634f28fcea32ba3f3166d21c8ff5a39be70895b32acbdf7592d1d616a345a21","other":"fe62314839c93d2f6e3aee984d5f0b321897c6f39e66800d3de8b773baf6f19e0a03cae025df512aea8d5f1b667b6dbb15c192a90a76d3031c14e33e5c16c4f7","up":true},{"one":"ae4e21e1587a8475afd299e00ca7085c7bf2a44c2c64a3068f12223d9202b0125094385319034691ec26b497ec9cf18fe8c0839224bac1b84279410241cef979","other":"617595a230e0a74a3db3b47cd27b941e02bdee9a84cdfa8eaa63a55941eb5caa79e20fb69726a4d46a0e5aeed24039f8c5a20679a692df0bc140f42558ca9a2b","up":false},{"one":"8f88c7ec044f758f29bd8d12a5170bd973aec8f6cddbf512b910c4b75a0fec09c5e198bcd65622037f897759db68da2328b4a7ca93585dc9cb62e46d2a6c0864","other":"bcf8e831821a5bca359fb824c7dc4d66906de82f3663a0a853d96880a8ca0bdddcceb1b66dd1f13f75ee20fde50fc9de545bc25767f228baee910e0dbfa8cc27","up":true},{"one":"352407b42726dcd1aacc46a912ed8124b8b6a3da4e33dab742e40aa2452953d35dc8f42eddc76695ae2317e9f15dde2cd21be4ce826934695ad1847455661d1b","other":"2e42f845d0393d1682add54ee30b60a953ed283e75d347bc6719ae0e91f6676282e7960f1fd52e5803d6b341fb3582c724b4f9cfd7bce9ce85f13ca480c7e72e","up":true},{"one":"1bc1d6155ba35d29ea16938994e08df76ebd8f16bd180bd6a9b9d8798d0745889fe72d641dd78bd8ec13526929f7eb5aaa6a388430fa69033d6db581e53c6422","other":"e98a08e8e3544727f5ee27f4465375a67ffba490fcdbfe7bfdc909f6b68bd279f776c65d38c2ccfc33079f852f76349c94d68fc6989c0d981f22333f036a4bb5","up":true},{"one":"1b063741c76fe65e62b4eae42751319d0cce66f22dde9f1cf83d6cca249a0e65bc7f6f22597697362fadd226222fb3847f8e146961969d1b4c9f7e475389cd8e","other":"2e42f845d0393d1682add54ee30b60a953ed283e75d347bc6719ae0e91f6676282e7960f1fd52e5803d6b341fb3582c724b4f9cfd7bce9ce85f13ca480c7e72e","up":true},{"one":"6b01079463ec2f649db8634cb7a596261c79a8f714d954c772528e0547b017f8ce405e4a0ea9d32270848180e0f77b8c0b022cf95c85e777626edd4d24ea21d2","other":"9c30ad8c85adc7bb52ddcfab2e661cc3a854a689eaa59128d35129d02cd5b0f8da4a44cdd33934a8e2c8fab1760c16d6f2e1c5eb227dc819e85624e63343c069","up":true},{"one":"5142eea687de4248b2184e9896b245563117648e7a156255d9a7ae730313d5d383db3be1125b5accd7e743c2a5d8c3289ec559ef7cbb803b9e82cd49bb213d9f","other":"eaca77d20c4ad6b87649eba21b750a4b1a2c575e06bc42679d18fce16fea15212e9a7408c16f3b24d8dfd1e397314637e72e292845d09534a39035bd9203ee9e","up":false},{"one":"0cacda5560faff9d20e29a0625d3cd340ec075f198a50ab8b79338cee0e0db84c7c7e71042fd8c8f73e507b570de5d26c39473136b575f0167625a1168309ec5","other":"6bf9fb6a25521c16c2ebeb6203d046d7dd40f29cc2ddb067c0222ef56d7012d2ee5d037f71f6668ea56767610b2a54c144aed74b7f68d06993cbd52fa1dc7630","up":true},{"one":"66d0c5da973d9dd65350ae1ec63776872cdb7ded6afb6f51ae82259f6fd35e884375d15de290625f02ed2e5cdc3f591decb45e5fc64d5b0f835a216fd196f5a3","other":"8dd8ad560af84bec579cadb33d51711aa61b6ed22705010336df5a71a94591173b25e869457429c4a199b205fce8e73530e28203e18b971c2001715e610f152a","up":true},{"one":"80d997b87856099d844187d3d1fa40846ded652a62c1611b35919c2543915b64ff62476636488556f678e436ea26fcc40db7c6b6bbcb78f590d61c1ff0e424b5","other":"9194a3a4c8f3235203e48bdb10902d958d26c342805ea6365af9711213536509719d917c694f9a4fbdde6889a4c92299a5301f0275bda4dbcd2541b5bff5b271","up":true},{"one":"88d5c5fe61ee1e6fa5878e0eaa13bdabaa0ec3d38a5d25b95a467da7627424f25fb5d30535aa0a5ad01c16fe2598dbf570b78cc152a7f4ef66d46fc9ae43592f","other":"9194a3a4c8f3235203e48bdb10902d958d26c342805ea6365af9711213536509719d917c694f9a4fbdde6889a4c92299a5301f0275bda4dbcd2541b5bff5b271","up":true},{"one":"6bf9fb6a25521c16c2ebeb6203d046d7dd40f29cc2ddb067c0222ef56d7012d2ee5d037f71f6668ea56767610b2a54c144aed74b7f68d06993cbd52fa1dc7630","other":"f6ca39b3ad803e99f4e4e9cf759fff6abdf06e6972bdbe524f6eb930c669d6f0e9b91f3de9df394b0d661b068273861391bdbac948ad911351c48cf02f874db6","up":true},{"one":"23f9bdc82efbf57d3d40a1f2617d0311678fb4a3d6a50cb7e608c649bb618124a76c7ffd17387de963e1cd28d2bd5a61c98613f6e009a8a2a90d989827b35de0","other":"c2705ee7238ef9305e4da196653cde707649435a1e8b5b797d164e5ca06184a77af5bd7fa938c995fdfcbce724fa7eca3d908ee34891ab62cc6dfd411c3fa1da","up":true},{"one":"329145e75496cecb5f5c8f00313a52ddd8c0e8cd27ef1b2bc1b2b56e4d4089aaf5a7a3c4d9a40bdb92483fa05bd24d1cd0fd51883e30439dffa0fc855e1a7cd0","other":"0deda014fa3c0bc8f37d853e1448f95f56f97048c28797d72258fd3ba2f1f776ae11566197466596356cd172847ab02a89f4cf047e58383249fb2a4cd69b6206","up":true},{"one":"c2705ee7238ef9305e4da196653cde707649435a1e8b5b797d164e5ca06184a77af5bd7fa938c995fdfcbce724fa7eca3d908ee34891ab62cc6dfd411c3fa1da","other":"0c14dd51a56130c51009e3ce47c96b2afef26b7e86cfca65d8a9bae1abef13b3a7a192b422d894c39e24ab00be412d166a3571cc259ff4462d4ad8925a153766","up":true},{"one":"f33d1f3e460574706ac1c7fc9ebb4683b173496ce3e80017d1c3521bca03d5a41a9c7a6cde8347d2238917b7cc58cab000ce7ccf6bb408561015a2ecbe613408","other":"5526d86ba9df651091d88460a9bedb9cedb957d452a635e1db46b9fed78082022adec0047cd7485956a4ecbb0e18107595de0de3c35242527cd302bf74a19260","up":true},{"one":"7e2b0b4f3b55e97bd7241b984ad117af33bf3baacd22b3ed503a8a59f75828df745fb3ce3be4276d83eb484e64d9aa251103fa994ef119eaddb97a3503b9f292","other":"ed6c793eb4565aa9d883a76fad6c97ad0b878b9ef0235e11e89db1af25a9653205f725c6ea258b84bde134f1a6437c6d109b859d17509e5016c4ab98be59032a","up":true},{"one":"b53078000796f1cdb04dfeac424d5e3e37e30f00bd5bebf9a9ea0525c62917612b3a8f508df6bea59e3c7e4cd1aa530841f9a8af54e44f5617a13dee2c6ff007","other":"083e67bb19e30d14e4df6d2483367d6659d9b56744d53d9cf7fd15954c327e1bc88a5d0db8833634e1dad7209164451f8934b59f76b5990059261abfd650519a","up":true},{"one":"0c14dd51a56130c51009e3ce47c96b2afef26b7e86cfca65d8a9bae1abef13b3a7a192b422d894c39e24ab00be412d166a3571cc259ff4462d4ad8925a153766","other":"5526d86ba9df651091d88460a9bedb9cedb957d452a635e1db46b9fed78082022adec0047cd7485956a4ecbb0e18107595de0de3c35242527cd302bf74a19260","up":true},{"one":"b4a5efa9028b2d196855393892f79993c2812d02b758f98813ddf82c5d943faf6d66eff811cc5a51936c118f4c768c0d13b54902095e040c602761e63c08655e","other":"2bfba66ec9d63e928d77d455f2e10a14d6213e515099d5db14fa44a8bfc147eb0fa7afa9aaccdc86453c6903b55556059a2e13dd61fc494127d4a3ec173bf9ea","up":true},{"one":"083e67bb19e30d14e4df6d2483367d6659d9b56744d53d9cf7fd15954c327e1bc88a5d0db8833634e1dad7209164451f8934b59f76b5990059261abfd650519a","other":"5526d86ba9df651091d88460a9bedb9cedb957d452a635e1db46b9fed78082022adec0047cd7485956a4ecbb0e18107595de0de3c35242527cd302bf74a19260","up":true},{"one":"e67e495385e7cacfe659b40d1ba94d4b1ff55eada70a4d9740a9e452fbf221672bd0a897b940e2a6bed71e2a16867fe45bf0ea0015435ac6d815690e263b1899","other":"2f903b2fd4f9432b7d91b5c3e4c7ee3cb9c56fe7efc4baff0edd06fc75e4b7492f2c3c929755746df59c9f95d437a12ba40ac138d08f5bc7aa091f49f3b852c2","up":true},{"one":"7174eca109a1f717653918224c8cfe1b7fbd666405196760913593401eb79f2c7e41003b01f5a458940695b27a4673443c7621a169db7fd968994e552995dbbb","other":"f915e2398aa5d4370de87504dd76c21a7d0be2581c2ab55b7a47743f1bbaef36384eaacec22760f1e914ceac9d96a10c3d66eb27475ef444e77fee979e6e88cb","up":true},{"one":"fe8ac5d33cd8ab6a1dad9567cdfb89b431a5c4f4a584fc608b92e7dfd06f70988e71e2f11f9fda9ee797c9ffba83bc085939fdf2522dde39f28202be92650566","other":"6b01079463ec2f649db8634cb7a596261c79a8f714d954c772528e0547b017f8ce405e4a0ea9d32270848180e0f77b8c0b022cf95c85e777626edd4d24ea21d2","up":true},{"one":"b870935867183bbfb84add16b9f56c02c834b7042fc24ce6bcb2a7f174e6d2239357a00be4272c1ef05c7f9baf5a9f16b53bc18328a9b7aca8540c2916805b57","other":"acb4088c27ee2ee130ece3506596432afdb9e9757ec11ebdd35c5a6e87239545c48466913a646980104c8fd7a9a335e177f04efffe9dc952dfd7cd5c1bb9aac6","up":true},{"one":"4fe37f2dfb03707c90a6fe91dbcfd7497db70ffc20043091d50e1cee573210c144e8749340f2c3cb70fe8fc51b317d49e8734dc51ce64b3cdccdd639ae35d1ae","other":"c332fe1f9b6e25f72c7150631ffa6e0929ff6eeab5d17aa45eaf669bdde869cf404505ae990a529aa3ca797cd0a96f31cc41431a5d4a163132be566f91623c08","up":true},{"one":"1f6d803a4ca186463772850ca0901fb920af7e74fdd2480c3c368fa707838ee91bbcfb57d5e3510c802b9b85f2d954f04c9b675414274bdaebae6488dcf94c10","other":"7bbb3f3ed51cf84c077806fbd6d3578e105bc32aa6043da188793f066ad6df383a9f7cc0bd3124f4c887704bd188d480ce264fcdf178905bbda3b270927ea138","up":true},{"one":"acb4088c27ee2ee130ece3506596432afdb9e9757ec11ebdd35c5a6e87239545c48466913a646980104c8fd7a9a335e177f04efffe9dc952dfd7cd5c1bb9aac6","other":"2ab9513899c3c829b6284e56bf2b9862dd0156ec052b58615dba77d450dac642e534ec36ae5d3234262aff54e19f99856e908b9d8c1da660a7834a445610715b","up":true},{"one":"e267e71c2dcdbe5a500b23444d2d4037ea15afba8f4f2b1c0e54a274450404fbee6fa5439f7cddf4ba1aa28fa93e434b01c239add58e30a5423ca3a481584d6b","other":"40bdac599b00e9c41ad6476ee415c33d9c17c5aa672692c2404e523b29dc315da929a86874bed87fd9009871805d1dbf3098e7a817193e3b08a6eee66346da79","up":true},{"one":"22010c9829626a6892258b09cb3f3edc3f21382fb487b5dbf0dd20e198e37e26134aab850e30337f398d1491b5126839aeb1953ec144bc19aeb889c832f67c6a","other":"2a63d875e715c2a43302d32d86d30c7d7faed46c08a67bf488762637216b99dd87333a66df6d9f3a57df863b1f1a219ddbeebb9f3e92e523bd08540a195448ca","up":true},{"one":"2ac522ebfa49d37f86c6270ad4cdad0e766493f0e463b18c9906c70fbd2e5c6ff6b0d5879de6e3894418370636963a78b0c0cf087a8684c2ca30c9c736e49228","other":"4314b0b04331973ed29a58843951f144ac3d09bd5d57b6cd9aaff9b73a7b2ec81e344a3e4ece462bd2081b837a06310e787ef3bb889dabad46fe7efd394c8342","up":true},{"one":"2ab9513899c3c829b6284e56bf2b9862dd0156ec052b58615dba77d450dac642e534ec36ae5d3234262aff54e19f99856e908b9d8c1da660a7834a445610715b","other":"9ce6b9decb69d66075993e903a0727ec109a04335634616097c0e60b08f94f764634fa00891b1070f6ea1ce896bc7d11d3aea92a00f281f902d960894cef296f","up":true},{"one":"b4fd11306b1416a9bcf4719578976188e104b8c5028b9abd3214d257446b97b70a22e6c00934d80caddde15e8e4d16af03bb399583047983fba373d8313226b7","other":"2ab9513899c3c829b6284e56bf2b9862dd0156ec052b58615dba77d450dac642e534ec36ae5d3234262aff54e19f99856e908b9d8c1da660a7834a445610715b","up":true},{"one":"ae2a996d3b562cb47a564934037949da83b1bfe194c23754f3dbe2372ec27654f4f3b6cb7f394570f308025589c065870477667e5560dbe5a8ea1625740699cf","other":"28d3232c43de54ffdaf08f97b334c012738648b04e2876c7e751a2e352aaf4d550d6efa976c5a8edbfa8e88b9d04a0fca492b81c3756ef673ab74d34182ca711","up":true},{"one":"60725e8d0e9333636e598dd666f459b4be898d9abc095ee2c1db289673e7e969b50e2093956fef5a2f1d23e2040159bbabaaeab17fc6dbbac3f6acab766e9e60","other":"5dc69635f6d573c824ea83b18593a47f9f21a6f91ce18d2bf977c97d21f8d2a8ce88829244d12a07d949bbd52fe8a2035bc89685fe1bdd4ee20d766d75d3deee","up":true},{"one":"460531928a4b084686343c8464b37c3452bb3566045698d08a4692864de5581a9eb1dc632329e7d3ccb73ec31ee7693787d69df8458efaba9a7105d87ee2e053","other":"979838eaefcff456cf1cd9c47ea46854704f5757d8d7ab907019bc422b01af4d62252579bf045d143fab491b0bab823190e2782a457fbf51aa99ae17ec9e145f","up":true},{"one":"3612863ce0456c91785a829bf5c9d2b2fb97dda083a1847e5a4ebaa6fce1260faf4d1eb374c2225431a82774163835fb59c8cb0fa9fc0969eab5410c71109cc2","other":"9ce6b9decb69d66075993e903a0727ec109a04335634616097c0e60b08f94f764634fa00891b1070f6ea1ce896bc7d11d3aea92a00f281f902d960894cef296f","up":true},{"one":"62666b24d1026345349edb6a878cdc27d6fee8254e83f79a298ce2805260d97aa46423deae440f86ced5cd99b30e970c8e1ea1046752b17d8c80dc68d9a49b60","other":"3612863ce0456c91785a829bf5c9d2b2fb97dda083a1847e5a4ebaa6fce1260faf4d1eb374c2225431a82774163835fb59c8cb0fa9fc0969eab5410c71109cc2","up":true},{"one":"9ce6b9decb69d66075993e903a0727ec109a04335634616097c0e60b08f94f764634fa00891b1070f6ea1ce896bc7d11d3aea92a00f281f902d960894cef296f","other":"c83985973a9564ade7d90aa54911ac57077600676a1d27292d98e058bf1315887bad84ccd708cb7f52a695a1405fb7d491d7ca2ae9caa3ff58a5ad78ce4dc9d9","up":true},{"one":"7b35c856916eb3fc1b1f451667e240b95aff8f4731cc0f6743740923081ff1ddf2eec81bdccf4691a7bcc053d23eacfc15809c384a73448f618317bf605bd1cd","other":"b870935867183bbfb84add16b9f56c02c834b7042fc24ce6bcb2a7f174e6d2239357a00be4272c1ef05c7f9baf5a9f16b53bc18328a9b7aca8540c2916805b57","up":true},{"one":"e087230634f556b818a416b66ba3f1d1dbe3e0dd0698bbb26fa86a2499acd169466f564dc18adf2f9be4d1ada0e86c11549754097601e10aff4f3a57ddffa24a","other":"9ce6b9decb69d66075993e903a0727ec109a04335634616097c0e60b08f94f764634fa00891b1070f6ea1ce896bc7d11d3aea92a00f281f902d960894cef296f","up":true},{"one":"66beee3968dbcf3addc6feaf070a4e3e82b5bb164fb72f40add89f732c12e8d0a31a7ee1f1e24a4674e4dfc9a4912b02c17ce3c224d257d78b7156544d6507dc","other":"990b1db3ab1390219e8866d39fa4441bb5bb89ad786b3e255771869fcd08906dcf63f34007481769c7462edbcc665acc0a552e3733360b8d8c310c9321a5550f","up":true},{"one":"a127faa19dcb7da585983d36a8e9d3e9a44a6db68507b60c70da71011f44ce377944802f39cd65f5a705cd8249ac1ef7ed8fd699349098f3f8e23b37592c80ae","other":"6b01079463ec2f649db8634cb7a596261c79a8f714d954c772528e0547b017f8ce405e4a0ea9d32270848180e0f77b8c0b022cf95c85e777626edd4d24ea21d2","up":true},{"one":"9e621c3eb534855ca292efa27a3fbc89b4f05c80a4bc65bcff2f14ff28ef43cbe14137d2fddc6fe2658bb06947d918476b479dde71469b8680e5d8a7a01619b5","other":"db8ba71afeaea1f2964e8978a6eceeb9efa3958424424022213c8193443f8d5afd18490afa954c76360c681404809c7cfaf7e4ebd8bd1a42d403f7f1915b0d29","up":true},{"one":"5566111b7f14d8ec83ba6456488f3fc5c7e2c86bf406dead33b814e1ee9b569d34015a4d88226b7e28fff7784395c086d106287cbbc80acfe75b05cd6e12903d","other":"adfba6d883cacbb141cd8c59ee04d7e5d520f1ce31a81e5db2d8b2380bf801c1fe4b265a66b71f9643d13a41cb1f6fb4b83399be786da4b6e171b6784bc56e49","up":true},{"one":"f5c1215a84a56d52f92ca0dc3a32df98c98a9c2ea2e9a34560210c16de1b440d20d043c8c25955dda8c22e55e92ddb49fd82e8b9b84072aabaa755a229bb19f4","other":"617595a230e0a74a3db3b47cd27b941e02bdee9a84cdfa8eaa63a55941eb5caa79e20fb69726a4d46a0e5aeed24039f8c5a20679a692df0bc140f42558ca9a2b","up":false},{"one":"2f1967b4410ea2ea8fbaf46771ba82c2846d00aecdb6f873aceae33ab38f72d0a2c2dc6046d3034f514efd090d42011d48e9ab0cb4e3caa2b49a96ef732215a1","other":"afe5b217dc512eee45575c189826ee5640d11a0ac9e8e4b03e9e62e6cf6df9de500bc8a36cb7d82a2280ce184409164f1772cc5c9e59ad04361522d2b8c364e0","up":false},{"one":"db8ba71afeaea1f2964e8978a6eceeb9efa3958424424022213c8193443f8d5afd18490afa954c76360c681404809c7cfaf7e4ebd8bd1a42d403f7f1915b0d29","other":"fde7705f5013c3b6b76a35505c1e3d57c033a337f2a71e912ec3a3d2da8e113bd7c36d94908357e9f7654660621f647ad8c66b0126dfe91dbfa3b8c7bd2183d3","up":true},{"one":"ee36d1d5dd69fd30242d7da2e941b34ade5581c7164fcc43288ecfc52937a98f1b31ade5d1e4dbf611cbe1c7875b2840c89435081cde471c271d7bc60e9ef211","other":"990b1db3ab1390219e8866d39fa4441bb5bb89ad786b3e255771869fcd08906dcf63f34007481769c7462edbcc665acc0a552e3733360b8d8c310c9321a5550f","up":true},{"one":"292c78c8e41606e98428096bc6f4609a7aa48e5c4d17eecc64d65faae4a7270b0c15f0cd74274015688ea0a9aff34f215c29118222e362a29c8d637963973a55","other":"990b1db3ab1390219e8866d39fa4441bb5bb89ad786b3e255771869fcd08906dcf63f34007481769c7462edbcc665acc0a552e3733360b8d8c310c9321a5550f","up":true},{"one":"d4b7c787981abec24353c7d496661692233797e3758189bf909a69fe87935bf6da0940daa4f12e81f20c5e88f70b472113688b71a0ae2f91a73ee0e6ff4c8591","other":"aacff366e601e072a2113add9020e19b6612f3e85b6e607fdc8cc1b6991f43be0b1f835ed3dc41d1f2b3e0caf7fac252c8eb4c150667d48207fa92ea5f0a7455","up":true},{"one":"a78f18691e0dbf3c08fe9d7dec188e6a05a93833432fb99eb2b3924ab0bde7a44db2a102a65544bbdc4fb61bc3a3d569230d9843a335bf619167fb045d78ab3c","other":"2f903b2fd4f9432b7d91b5c3e4c7ee3cb9c56fe7efc4baff0edd06fc75e4b7492f2c3c929755746df59c9f95d437a12ba40ac138d08f5bc7aa091f49f3b852c2","up":true},{"one":"8ca3b63cb84f1e9883d82809a9b6777ec1029ecda96fe93b4d494ee9cbefcad13f381b3e480136e542e01054fe1ede66c65db84a0009871ce49383db461c8438","other":"ff6f94005d1df7677600069764855c1c2aa0543cbe9f480f8feefec76c49d9e2c7bb2d8e38c89e9430f53f8b593d93f143c45985a56a5a32c736128214c95eda","up":true},{"one":"c903c5ee3d9cd65bea3ea777e39282c33e1349d945411fb2f16321bf582c2f400956a98fbafe5873fc5f6f6a9a051df5da7e94cbd340f935abe80f91e79ef875","other":"40bdac599b00e9c41ad6476ee415c33d9c17c5aa672692c2404e523b29dc315da929a86874bed87fd9009871805d1dbf3098e7a817193e3b08a6eee66346da79","up":true},{"one":"a608a746f46d4b2e9267c65283380d6d6cb8885a64428fb77df9934bcf4dd1723587ee7c8f4a642dce266a12a6a4cf4e5c6db7fa1024158425a6753e7ab7264c","other":"3dfd733dde9414af916625ab981777ff1ad7ca0f6d1e4e7d9e2739969e21182fd13d85e281868653e7325b20069356b11524b54143c47fd3955a911cf7325ad4","up":true},{"one":"f039df8a3206e6e17eee8e95010038c450cb4cc0b5580ed5795d4c21802e1e9d360f4528bdca794f457932b1d6a818862ec847357a861c488332ef6d9480daa6","other":"b2538d4edfa736bfe2cc21326a44ce62f716b3480eac93584a2233b69c98883a2bb255f246218a58cecab1d0d176e6d1fbba9782fd70d4603e01742299b9ea9c","up":true},{"one":"5bae82d4832092c17bd11474f7748015b8b69b896ab8f683a7c0024fc98740cecbb9e31c6275269f9000e5bfe51d7f45cd5dcd4433e0c87b5741685b40fe3983","other":"934a5fe1b91c1891ef4df7f67c027e0eb115d4c2ca4a1b76a135ebd4315c4fb835d6625223194e6a134407b38b0d3928fbc7bc924a3c6a538989a6cf200bf4bd","up":true},{"one":"b137cf2291b530a39516d882200848e7f27a2710e0839b4d25b4f367bea6a0c3aaef8c7c7851c00a2945adcd819ea0508610afc1f453b8bc512b7b4d4faacdf3","other":"a127faa19dcb7da585983d36a8e9d3e9a44a6db68507b60c70da71011f44ce377944802f39cd65f5a705cd8249ac1ef7ed8fd699349098f3f8e23b37592c80ae","up":true},{"one":"732393b99c490c76fa45e3e404ee095f2fa445fcc123af7ac8ab1d2fdd7cf2483f5b82bb818bd8a82b1a3b73e63bcc2c83d8f24d9aad9afe36503735e7967be7","other":"485825745d97654cbb92a14e0cd1078691d3c28f4d82b1046284b676a42b44ca58eb43474e45e415d3bd3f3c383f9a1a3365821ed7ba6a9f2603b29d58031dc7","up":true},{"one":"0a4eec7b0e05da799aca5b36d9e2530f2a89d1426b1fcb7d8f9a662df8a8b5b763767a20db3c9c63e0bd13c2a6e16d3ba8f03baf84f5e5d24917b3f211d9bcfc","other":"7acddc7fb6ac587b7e343804c768e4291cd28dd2b2b9207dea6ee82360d848a52d84f94e4c49e9c421f4f90e2d24f6291e2358783ab0230e6ecde82e69b4ac52","up":true},{"one":"109556abac422a912ecffec0d8796f8f16e92e8f95cecf72dc89e97a8bf1fd37aad3c66aa3cf134acade6d065c31821f977171d5c5463305b57ce3eee99a7ab4","other":"17917fa4da06068b587c17899569dcc768b9cd2c27117a4ed67aab26a7e70cf8d32b881db258061ffd89a332a3b29bfd963d8e171a06c3e208ba0de1c42a2b39","up":true},{"one":"baa5924e1547c177011285d292aa161a15e5ff282da2cd0afb83c9caffb07bdbb3662c227fa7b26e6dc8be9b8863e647eb5f8ce81640532f8f5c9a7f36557e63","other":"17917fa4da06068b587c17899569dcc768b9cd2c27117a4ed67aab26a7e70cf8d32b881db258061ffd89a332a3b29bfd963d8e171a06c3e208ba0de1c42a2b39","up":true},{"one":"759f46661056bcbb30c7706c9fb87e22a30feb523bd53ae5d18db043efa45b49a2b8982abebdd598fe0912a05896390ec2eabe5e160cbafc0771990708ad8c28","other":"deb7af800cd20a647335f0feff5bfb3e182f99f4c2d1ade10da36ecfdbac3b5fba4e8f0a4595443fe395b44af3a95617669850944655def85d57cc81c5682a3b","up":true},{"one":"6c143960dbe3ba4c95e8debc1fda5f420a2a673eb46f7ff7d9a30f4cd2067e67ef8926bf17f0c99b16c79b6dc066b52409a11d47117d4fda4211636b1b74f96c","other":"1f6d803a4ca186463772850ca0901fb920af7e74fdd2480c3c368fa707838ee91bbcfb57d5e3510c802b9b85f2d954f04c9b675414274bdaebae6488dcf94c10","up":true},{"one":"396c703d27bfdddf91761f134cbf665fe61e0b3a5d24036a4105a625f72e8c28b821e9200f20d6e8f8b3ed6b95bda6b8accdd840c2f786720b7431e3af2af981","other":"b6a998dea59194cc60ce97c7c9702368411889cb6905516b23f41cc5116fba8d0f237d418318eb0c333cad18003c0e9a6bd8c99080520771f2bad640e2e5ec1c","up":true},{"one":"6b4e376e9c94242b6d42688c22aa9ab418cb6dfb1cbca1c69de0feceec8d3af29fb005017aaa6e503cc0c03cf0dc5bcab55e01cd6f64b9efa02ed87c03020003","other":"1c2f7ce55a6e38487f3b3fe6083a79f914cd6d7e4aee8f5d56b4a61b3eb584e128c56998db0e13e775edee3adacf54f09960a041dab3daa80a4f8a3b42760c1c","up":true},{"one":"be026dfb24847cac2d00f483104edad06ca8ecb9e1229c479ef5650c7b427cd5dc34a1cf06172c17c9d0406ce17009712e82446394743d4cd9bbc41c537ebc14","other":"2ac93c31937ca205d61cc5c2a1b9037871cac55e9b306b999b28e19566b3316f6539455e014840ea50c2db8a7c97d78804d3a2dcd7cd9c1f32ace0d36e5dd339","up":true},{"one":"032b9bf2f59f15571821611d3ee541aa748c86d47fbe5f049fd0069be53e5d7c41991d82957e9c727654c3aa73ec94997c03d8a6c1d2007c9bb1a703f6215158","other":"2ac93c31937ca205d61cc5c2a1b9037871cac55e9b306b999b28e19566b3316f6539455e014840ea50c2db8a7c97d78804d3a2dcd7cd9c1f32ace0d36e5dd339","up":true},{"one":"17917fa4da06068b587c17899569dcc768b9cd2c27117a4ed67aab26a7e70cf8d32b881db258061ffd89a332a3b29bfd963d8e171a06c3e208ba0de1c42a2b39","other":"ca1aff0d847c6fdacb623ad9078a0885b3208614fea20d5ff11779779b486bf5e9c794aacf848d3c2d58cfcc1eda8356df82f5fbdd0a5236beffe8e6042848c4","up":true},{"one":"9c30ad8c85adc7bb52ddcfab2e661cc3a854a689eaa59128d35129d02cd5b0f8da4a44cdd33934a8e2c8fab1760c16d6f2e1c5eb227dc819e85624e63343c069","other":"a78f18691e0dbf3c08fe9d7dec188e6a05a93833432fb99eb2b3924ab0bde7a44db2a102a65544bbdc4fb61bc3a3d569230d9843a335bf619167fb045d78ab3c","up":true},{"one":"3dfd733dde9414af916625ab981777ff1ad7ca0f6d1e4e7d9e2739969e21182fd13d85e281868653e7325b20069356b11524b54143c47fd3955a911cf7325ad4","other":"72e30d4562673c5c8fb03709d93f73322747858d723b7eb5ef2fbb88e0331252946b7e93ffe434fcb599c4fff57800afb29e6c60a719f18f49dba541c3591c6e","up":true},{"one":"a99852c5bf08ea4713af9cade5343d1259bfb90401aca7fcff18c58cd56a98804dd16c61fea71039c0ac31b9bbbb9dc5aeaf0c2f074d3365e88d17031802d636","other":"afe5b217dc512eee45575c189826ee5640d11a0ac9e8e4b03e9e62e6cf6df9de500bc8a36cb7d82a2280ce184409164f1772cc5c9e59ad04361522d2b8c364e0","up":false},{"one":"ddaf3f8478501cda872c056c72063eb64d5b871fc5fff70704872802289dd2d348f73bc342b7f148a90cfaae2448ebf16fea196be9df891dc71a57fb410d59dd","other":"1b6cad4f9851cc584c5d1405f976bb51a52e27ef4525847df543dcca65ca5eb1ef229dcc68ccbaaf00ab1e044cb5990dd213c805bdb4adcceb6fa70b5c61fdb4","up":true},{"one":"c57ea182bdb42ba9b0870b5c870e467f52693e5c0df752fb6eb0dfbacce7763f73caee10db40f4fd90f19f504ee586eaf9da41f5ee93ee515d885fec99374116","other":"deb7af800cd20a647335f0feff5bfb3e182f99f4c2d1ade10da36ecfdbac3b5fba4e8f0a4595443fe395b44af3a95617669850944655def85d57cc81c5682a3b","up":true},{"one":"ed6c793eb4565aa9d883a76fad6c97ad0b878b9ef0235e11e89db1af25a9653205f725c6ea258b84bde134f1a6437c6d109b859d17509e5016c4ab98be59032a","other":"7bbb3f3ed51cf84c077806fbd6d3578e105bc32aa6043da188793f066ad6df383a9f7cc0bd3124f4c887704bd188d480ce264fcdf178905bbda3b270927ea138","up":true},{"one":"7b5c0e81c7f4e3ae29d745f6028cfa10b29a16a9c261b65fb8dd05d6eccc634612ad5d3029c8e9f39863a2cdb2682c25f090139bf5c4950e25647e39dcb40e63","other":"ca1aff0d847c6fdacb623ad9078a0885b3208614fea20d5ff11779779b486bf5e9c794aacf848d3c2d58cfcc1eda8356df82f5fbdd0a5236beffe8e6042848c4","up":true},{"one":"84dfd4e4d9f1204893f190eacc4c3999e175c433f70de86e335d27477c097a0552f211a21764f01a708da4c9e9e6552191a61d3e48f41d0e84f01e7ae3beb34e","other":"4a030ebcb1a59230759d25a3c87daed22906b520d55a78eab2083bb52358ddc3a5d2d7c3265e6c54a990bf32d0dacb85905a4173d72ac18fcd74c43ecb8635c5","up":true},{"one":"2e409baefbd821485a151993356730e5989810d581e68190fbaa142799c9335bcf98310ad188fed10ae6eb6e2e789730393e509962ec5c0fef0342d72ed088d9","other":"2ac93c31937ca205d61cc5c2a1b9037871cac55e9b306b999b28e19566b3316f6539455e014840ea50c2db8a7c97d78804d3a2dcd7cd9c1f32ace0d36e5dd339","up":true},{"one":"663535b22018a4ef0b151572ef286fa66c22c6e9b2913a69c4a735d4b0149bdf6c84bd83d710f8aa2627e8993b7f020750fbc6f56a3365ce4c840e2b3de1a6c1","other":"2e409baefbd821485a151993356730e5989810d581e68190fbaa142799c9335bcf98310ad188fed10ae6eb6e2e789730393e509962ec5c0fef0342d72ed088d9","up":true},{"one":"d9bbcdfd949010e6b2cbf6d0f34b27593ae410bdc1838876aeca35679571fe431d040a5ab085c0a77f111688bebed891da3587277cd794702437cb20d6aa4256","other":"7acddc7fb6ac587b7e343804c768e4291cd28dd2b2b9207dea6ee82360d848a52d84f94e4c49e9c421f4f90e2d24f6291e2358783ab0230e6ecde82e69b4ac52","up":true},{"one":"84abcbc7b5598ecfd91ceace0927921a5a3404fdb274fc2a2549abbede5f8e4f62c15688a4dc9a2d80262c45970c88898da245c6eb779f327a81d53a17bbc74c","other":"e6779e3bbecf81dde8b27d652ed2726c45c205db0d0405c4580014a4c91d739830276f77079108c98ac516ffa00194e77a0795f7140bdf36069b6475e58213f9","up":true},{"one":"2ca05ffc0ad771e1e045a47f1c0a79ce374a25e3c0e53c2a80d67e7479677003f62880251a83a5074f1c9651d828f1ff7e352935a9df141c1eb75a0c59b00a8b","other":"65e954e60837bda10654480b227fa3bcc6e63356c52079002a27e836cd82ae2934ba77da60080e4b9f2d9324b982b24959bfd9624302e6c330408381054b43e9","up":false},{"one":"c73d088ade8756c74832c73542bcdb3e52f670f7a74ad3a7eac2a9e3ece6bd081f782a8e1d3f9a40b9aa9201509110f37fc57fcb10ee1ef3ef07b7eab019782e","other":"afe5b217dc512eee45575c189826ee5640d11a0ac9e8e4b03e9e62e6cf6df9de500bc8a36cb7d82a2280ce184409164f1772cc5c9e59ad04361522d2b8c364e0","up":false},{"one":"c665a6b1b7ad39b86bd4b1fe38b7ee95a0fbb1db15e91381ec9e5a235e33b69ffdc92c60dafd74b7b4dafca1b000e9274bf045abe5b93b1a9c2b31ae071a9898","other":"abd8f5a4d700c06ec00684b23d2d25c4df1a9554fcfc57b0ddc3fa476e6a699ba75e1213449f900803f83ab8194c6746664b547202047f35b8b3e216c7147bf8","up":true},{"one":"b26f7c0113a5ae885f7c0e608aea7022a9c8bfc40c5643e60b2ba7343ff09c5be0bc08be34dde3c6b85fea192a46d4764770c12cbaa233df4231a1b99627ef9d","other":"5420da16f7ed5de6b498dbc9a83b7e92e1f9900a6d04ef7351a0bfdfd442b98a5634f28fcea32ba3f3166d21c8ff5a39be70895b32acbdf7592d1d616a345a21","up":true},{"one":"4f5ab12b9c5127c16739ad0d4f51adce90ba6736cd096eb185ea632789f4b26f1ebabdea4fd3b39dda5409ece6c2d92fd469cf4aecf9d29453e3e042c19b893b","other":"535f93057d46c4aae0902546550880be0b5ba67dca12350117d471d67f4f2b3f7bdff29bdc918767974c465df8fa1afa6bd6c29c0a36d51f71c4183673d906f3","up":true},{"one":"1944f98d4db32c56a5efda5a79aa5f276bfab1e084d6611fec0e735b8bc0f45b457cdb74a23fc83b2377821fa8316123c9877acd6db7c41058ca5d3cfedaecf9","other":"6ab6ec15635b2fda22542c99df0a3313ad4583ba0fb3f31b8f314e3ecad446d3fb0fdfcd2be9b08374b1a7e049fb68e69e8dacdd13f1df5007a656f6b11adc5b","up":true},{"one":"74d84cfdaf32cd4cc67771f29878f1365120bd65cc14848008d5386a81f495bf88eb4132fa38a2cc109ae1e7f02c9b97597ab9d1a9c19c945e710ab9df07cdcd","other":"92d6ef729992f0de886076e5f8cdc42cbbd70b29e79c25e0b3d22b6575d3d2508d47b42f581e335455483d43625bce4e55f88cab9ff2073ee8dab746357864fd","up":true},{"one":"979838eaefcff456cf1cd9c47ea46854704f5757d8d7ab907019bc422b01af4d62252579bf045d143fab491b0bab823190e2782a457fbf51aa99ae17ec9e145f","other":"049a2b0ab4d49789dbbe1837e2d2ee5220a9401729ea87ab29385b24d79cdce255c3d2b5de6484d49ca6ce07bd41832598260c0a8c290e01d133d77f066f2f99","up":true},{"one":"cb321c9b0fe2eb3617b8e2461aab170a9dad2c9b04a10eead4e37e551197ea0a7500eb1cb7b155efe1886486ef3d252d8ff0d309f2906a1126ca011d037da70a","other":"53df9cce9b0169e58ced53a123d1d8f6e8fdcfb4c2d781ecbb91bb7c8eba36946dd9d21c749259769825d8a6b3faa6bb87c8c6085a522f8a3e376061f59144d9","up":true},{"one":"df54af3bae257d437c5657905484e0d72e9560c46f8ba6b3437730234e05259b404cca40b0831e911605ff8a68a19e8fd7e958069ec8b40595928892f4fa220c","other":"d9bbcdfd949010e6b2cbf6d0f34b27593ae410bdc1838876aeca35679571fe431d040a5ab085c0a77f111688bebed891da3587277cd794702437cb20d6aa4256","up":true},{"one":"e2e0419a41bdfc5bd76deae2ddce6ac865f886d764c9bd18799b79fa3b2b6ba66d765d26da2037e98317e1d7e8232a61e63c1d0cfa98c9137424151b46e07171","other":"5e86f39cf8338ba098a85d41e601a303fde311662b216ad32a2b7bfaf2b2b6dd1af3775784b39f2d85ac5fac96f05f3abdd8a2bd28ba16d939725fd6a33ae1b6","up":true},{"one":"5e86f39cf8338ba098a85d41e601a303fde311662b216ad32a2b7bfaf2b2b6dd1af3775784b39f2d85ac5fac96f05f3abdd8a2bd28ba16d939725fd6a33ae1b6","other":"9b59b76dc61223c7b37083b0ebdda22d3599563b3e3986f5db9d5b12f8c806cbdeb2345454efe957cbfa11eea9c7896aefd9a461210524805452ca100a9ea431","up":true},{"one":"385168340139236a0e0f537fa693122db9fa02a377c96f31aae54718e92624fc0288164877e63616651565e055c53f7074ab2fdd18a837da6faf644941305bf0","other":"23f9bdc82efbf57d3d40a1f2617d0311678fb4a3d6a50cb7e608c649bb618124a76c7ffd17387de963e1cd28d2bd5a61c98613f6e009a8a2a90d989827b35de0","up":false},{"one":"7b1e20217f594f87350542df31ff5ae8a635679bac7962d49c97e02190c644b673d03e7eba2626b45ca7ebf98d8a972dadbba02c18a8d2cbfc3e7a4cced5b4b7","other":"e6779e3bbecf81dde8b27d652ed2726c45c205db0d0405c4580014a4c91d739830276f77079108c98ac516ffa00194e77a0795f7140bdf36069b6475e58213f9","up":true},{"one":"016f8f4619a16a07fbde5a18e362158d696e4d9f104a77787f26e32a25cd7d278256f8e0db865c488a99511ec27a5eddd5ebbd1c1397fa7f8db111062e5fe959","other":"d9bbcdfd949010e6b2cbf6d0f34b27593ae410bdc1838876aeca35679571fe431d040a5ab085c0a77f111688bebed891da3587277cd794702437cb20d6aa4256","up":true},{"one":"5df58ba12334a1b4f983d642fe435901261767cd81f8f37c43e359f5584664e4d287e8c2275995604a3b3a4823418e35cd899a3db2a7db31570e19512f375481","other":"9b59b76dc61223c7b37083b0ebdda22d3599563b3e3986f5db9d5b12f8c806cbdeb2345454efe957cbfa11eea9c7896aefd9a461210524805452ca100a9ea431","up":true},{"one":"2e42f845d0393d1682add54ee30b60a953ed283e75d347bc6719ae0e91f6676282e7960f1fd52e5803d6b341fb3582c724b4f9cfd7bce9ce85f13ca480c7e72e","other":"657d5370319128d24d925b41065eb619409d63ec6280975d78877a4028287463f6442f5206dd703569a05b2b542ad8bbb99803da265408208d6356a26d283d08","up":true},{"one":"d7a319f69013b8375e64d19f015547462c84565b882337998f9e669c5fadd3d2ecf6374109903003e09f5d453424b5c7fdf52163d2cc8084cf81f94844946b63","other":"11d560045536e9d1b0b1b9e8944e00f0ca7f1e6788c9fdb51061820bbb3008ead92bb7836621bf58da7035c87a28328faecb4cb2e3cdb9d7fa4f45790e6bf352","up":true},{"one":"9bbbfac8be4a000f51a4ce8d024d2595b5d491afec0138922dddfde5ef62c664040c2e9304cc6b7bc688233b5d0c4644b8c8793227c078285a3ab894ef0497a3","other":"9b59b76dc61223c7b37083b0ebdda22d3599563b3e3986f5db9d5b12f8c806cbdeb2345454efe957cbfa11eea9c7896aefd9a461210524805452ca100a9ea431","up":true},{"one":"94088fe273f76e62ca4e43c095ad12215b4ae4c59942328b3985416fb19bbda0cacc143a49eff3fb644ad53a19d3f043260e43dbb70a0aa9c15829c21cecd3c7","other":"53df9cce9b0169e58ced53a123d1d8f6e8fdcfb4c2d781ecbb91bb7c8eba36946dd9d21c749259769825d8a6b3faa6bb87c8c6085a522f8a3e376061f59144d9","up":true},{"one":"2245f3bf1a3b4e92f912affc75f757cf648b20474c11ffe947884f216b8f24f9dcb6e6a0358a4061b8517478ec15027e185b2f05a777573b4940375bf4aaf2be","other":"aacff366e601e072a2113add9020e19b6612f3e85b6e607fdc8cc1b6991f43be0b1f835ed3dc41d1f2b3e0caf7fac252c8eb4c150667d48207fa92ea5f0a7455","up":true},{"one":"57cd4c0048b459192ee46e19ec7df777e600f256e0dc8c3019431eb7bec3c020b9504ec7aea3dba8188658ca5b830ec40af6a8540ce10e04badc6c695d009271","other":"7ac5b07eb555af3bb4ca3f0f4b45204d43cc3798c244435909b97d9a32fc3abf0b50666e260e046bce826a7a102a92d389f8f39c5311e83bb34beddac29d50e3","up":true},{"one":"abd8f5a4d700c06ec00684b23d2d25c4df1a9554fcfc57b0ddc3fa476e6a699ba75e1213449f900803f83ab8194c6746664b547202047f35b8b3e216c7147bf8","other":"53df9cce9b0169e58ced53a123d1d8f6e8fdcfb4c2d781ecbb91bb7c8eba36946dd9d21c749259769825d8a6b3faa6bb87c8c6085a522f8a3e376061f59144d9","up":false},{"one":"e1ecad3beeb6c19dce551e4a603c7b440b4498c44e298dc67bfaf4ed2c75bbea95df48b1cd1318e2ccb962cbae7c30ff258e73f8c3fc6b7e9ae7a47f7cf8e53c","other":"e6779e3bbecf81dde8b27d652ed2726c45c205db0d0405c4580014a4c91d739830276f77079108c98ac516ffa00194e77a0795f7140bdf36069b6475e58213f9","up":true},{"one":"1c2f7ce55a6e38487f3b3fe6083a79f914cd6d7e4aee8f5d56b4a61b3eb584e128c56998db0e13e775edee3adacf54f09960a041dab3daa80a4f8a3b42760c1c","other":"7ac5b07eb555af3bb4ca3f0f4b45204d43cc3798c244435909b97d9a32fc3abf0b50666e260e046bce826a7a102a92d389f8f39c5311e83bb34beddac29d50e3","up":true},{"one":"4ee37acec2178ef120166265aaa2b64b09b315fb53861405ef46f2503c273eb9692e9cb4c2e67a8652254d430fd6e02dd3fe4cded20bb231a9fb834d292b0b24","other":"5df58ba12334a1b4f983d642fe435901261767cd81f8f37c43e359f5584664e4d287e8c2275995604a3b3a4823418e35cd899a3db2a7db31570e19512f375481","up":true},{"one":"71f89efcf939294bb94ac669c8afd00def58c8dfad519c226adfa068692d588ef797116d42aa146b9d34f3be35ec7c014022640ab3c0f1f9034e44ab1a26e246","other":"9bd4f0adb9a966cc5ba632f1b540fe9cd6c8e39fe1a041b315697679cfb04b735952062ce057d456677cc34a84301f26bb727a4ab2646fee734f80a22c620746","up":true},{"one":"65e954e60837bda10654480b227fa3bcc6e63356c52079002a27e836cd82ae2934ba77da60080e4b9f2d9324b982b24959bfd9624302e6c330408381054b43e9","other":"7808fb798d22e78fb1d39b87ddf99a503f820993bc64149eca9e81d9d58fc1adea60d8de14a4f06cb89f3190c0ef0c5e182621a14c9361ccb7e0cee667599cc3","up":true},{"one":"389b5c1a805f87427e6d647ec5488342a3f7d700615943d5ad98ca5c111f33c7ee007970b4d3e475892095c0d5a79b7ed52d12598398818159000d4b9b719126","other":"deb7af800cd20a647335f0feff5bfb3e182f99f4c2d1ade10da36ecfdbac3b5fba4e8f0a4595443fe395b44af3a95617669850944655def85d57cc81c5682a3b","up":true},{"one":"72e30d4562673c5c8fb03709d93f73322747858d723b7eb5ef2fbb88e0331252946b7e93ffe434fcb599c4fff57800afb29e6c60a719f18f49dba541c3591c6e","other":"97981f4b825620985b746c85824d7a4d307ee25d60a72c2b7de4b1d4f3b1c002652adc3045842d350f849789e410a0357a0b42fa637a1b4fc9d39e44f8a674d7","up":true},{"one":"1d0244a13affe60996fe3cf51ba624adc746de0c7ea68ec5a31311a36077c5b5495e3d95c9642875db44c7ecae6ffed22e45f2e2d024d486760be2af9f4cf2cd","other":"9133b0b3c8f680286eae90c3beebc3099a13de38775a3ff2abdeced62d05eb2ced5ac85eac0870156be03101024da5e1d9fbf3e1066ddb3f088221e64149acec","up":true},{"one":"fd4968df03d767a223bf7e4dbe26b5c27048298df40e81cad50b344fb3e6837965f2646dab7ffb2891a5c507343ed84bb8bbe403287b51dae538d58fcb6e7623","other":"84dfd4e4d9f1204893f190eacc4c3999e175c433f70de86e335d27477c097a0552f211a21764f01a708da4c9e9e6552191a61d3e48f41d0e84f01e7ae3beb34e","up":true},{"one":"11d560045536e9d1b0b1b9e8944e00f0ca7f1e6788c9fdb51061820bbb3008ead92bb7836621bf58da7035c87a28328faecb4cb2e3cdb9d7fa4f45790e6bf352","other":"53df9cce9b0169e58ced53a123d1d8f6e8fdcfb4c2d781ecbb91bb7c8eba36946dd9d21c749259769825d8a6b3faa6bb87c8c6085a522f8a3e376061f59144d9","up":true},{"one":"6ab6ec15635b2fda22542c99df0a3313ad4583ba0fb3f31b8f314e3ecad446d3fb0fdfcd2be9b08374b1a7e049fb68e69e8dacdd13f1df5007a656f6b11adc5b","other":"7ac5b07eb555af3bb4ca3f0f4b45204d43cc3798c244435909b97d9a32fc3abf0b50666e260e046bce826a7a102a92d389f8f39c5311e83bb34beddac29d50e3","up":true},{"one":"f38a9d792173a29c61389f5d84c005d78eac6e750659aad42e2d6df883f04eb3126b2c38fac95076eeed455b2031aaf694143922aa93a2d50412a2454dc56e28","other":"535f93057d46c4aae0902546550880be0b5ba67dca12350117d471d67f4f2b3f7bdff29bdc918767974c465df8fa1afa6bd6c29c0a36d51f71c4183673d906f3","up":true},{"one":"70ee3c7e02a123f78345d41c386e413f06b51f1ab346c2c472891eed7dd26a1f14e213a0f4f2d872859b9b535936a6d9b072d2604456f76221a422710411822f","other":"979838eaefcff456cf1cd9c47ea46854704f5757d8d7ab907019bc422b01af4d62252579bf045d143fab491b0bab823190e2782a457fbf51aa99ae17ec9e145f","up":true},{"one":"07c63ca5d0309e30d1ab12e7fc142e6d37904b552639cfa97850161491f28f20d87e0304be29357bcfc2ff52fc52fd0d4f6e6011ebb239cced8b5c8dad7abf45","other":"89a5b92a9ca045f12c35a70084e6f41f9775a25d6f105f8c9349c7b5e107179d8a96bdbb113b2680edf5183e9a42fd64bd7b29d0dc7797c583b833f869313699","up":true},{"one":"ba21a373781966135d6225adae024a3f3e421b852f72f8b0569cb92fcff87c33f7e5b799a509b8eff6ec6dc46a9b17d5bae1e91ec7c54c0c712d893d54b140fa","other":"07c63ca5d0309e30d1ab12e7fc142e6d37904b552639cfa97850161491f28f20d87e0304be29357bcfc2ff52fc52fd0d4f6e6011ebb239cced8b5c8dad7abf45","up":true},{"one":"920a301186bdf665a721676ece7c180413369ea6eff7537f42049d9eb409f28cc864099590116e885f57368959fb2cff7003697d9b1515e68bf3fa7aee0278ef","other":"beec648d79437a5d7b4140ced45d82d035c6f64f9c67c58386703811d97c3846787eaf274d2298df809475f0b7519df696563cb8e9a5fb0a9cc419ab13fa8d41","up":true},{"one":"9194a3a4c8f3235203e48bdb10902d958d26c342805ea6365af9711213536509719d917c694f9a4fbdde6889a4c92299a5301f0275bda4dbcd2541b5bff5b271","other":"bf4ff51cc3d9a9d8cefd7e346ce1384d06450228a6086fe12fb0c60fec54bb6478f090bb638fbdbf8f41f7bc6420cd8a5c8b1b8566229b6851167375ef412f46","up":true},{"one":"bf4ff51cc3d9a9d8cefd7e346ce1384d06450228a6086fe12fb0c60fec54bb6478f090bb638fbdbf8f41f7bc6420cd8a5c8b1b8566229b6851167375ef412f46","other":"0c14dd51a56130c51009e3ce47c96b2afef26b7e86cfca65d8a9bae1abef13b3a7a192b422d894c39e24ab00be412d166a3571cc259ff4462d4ad8925a153766","up":true},{"one":"1090e9d89cb278a30063a5396d9ba795d3bbc237c76915a6fb7d23aa1822c8535d2fccc44cc8cd2acec68444c0bf1bdf5195ebb9f3cad8dac3d94a4d9c0e5309","other":"2a63d875e715c2a43302d32d86d30c7d7faed46c08a67bf488762637216b99dd87333a66df6d9f3a57df863b1f1a219ddbeebb9f3e92e523bd08540a195448ca","up":true},{"one":"ff1e34fd51953ed641b431aa657da21cb4c81d23e4eaa13c9cce526f1f1b34593d41f9b87a0e10387fe400c623638677c0efab15dbd1014a0ccc11f9ec92c417","other":"aacff366e601e072a2113add9020e19b6612f3e85b6e607fdc8cc1b6991f43be0b1f835ed3dc41d1f2b3e0caf7fac252c8eb4c150667d48207fa92ea5f0a7455","up":true},{"one":"0f9f7e2dce4ca266c3ac0ec3a8854200b54487f5308e3db418461aeb5f67c81d332619b6441b468e480941e63100ed1b263e7adc20689dc3dcda578bfca538fa","other":"5526d86ba9df651091d88460a9bedb9cedb957d452a635e1db46b9fed78082022adec0047cd7485956a4ecbb0e18107595de0de3c35242527cd302bf74a19260","up":true},{"one":"7aaf7817b93aa6d2f50513791f9ad7629a901ed0dcb151189f44763f83423446b20ec79a48fa260cd9bc2907d5f0ad06b2c4c5e6d812f3d8876c8020ebe41019","other":"3d2df188704eeac09c8b291bf275a73888199a231c832c51dbc3d746968d4b51a7d5eae0c7c9b8c8e19f5e28d38c375e01abefa343f31dbe221deb837ab8a0df","up":true},{"one":"062e0ca43a1885c4a7ab2a5169790f9081e3e9a2dfa286b8cc592d5ccbf13d7a82b72d23361a19026d04fcf41b752ea320d98359d770aedfcee626e21c3494b3","other":"5bf29c02f07faf7ae8e46389e1b98df4f5e88c9316b5151685e6ae7b4e622cf171ff09f996aaa8ad846643b3bfcbd1ad96cdc249afccce439bb5c55246b95801","up":true},{"one":"57b47f692f4d69a5d2c9c193680eb4ccb5a6c574662df0138504a549f3ea74f20c5b866ac4d9e76c4b49c83f5fd692ead928ea20dfcf643a11a1c1e841c0ec42","other":"5bf29c02f07faf7ae8e46389e1b98df4f5e88c9316b5151685e6ae7b4e622cf171ff09f996aaa8ad846643b3bfcbd1ad96cdc249afccce439bb5c55246b95801","up":true},{"one":"2ddd49fae11d8bd2e7e75a481be267fa846f51cc1160bc326aeea51c542323ff444909de11e2731e835140bc0b1b32020e1e73fa652511a381222bf0aebc4081","other":"5bf29c02f07faf7ae8e46389e1b98df4f5e88c9316b5151685e6ae7b4e622cf171ff09f996aaa8ad846643b3bfcbd1ad96cdc249afccce439bb5c55246b95801","up":true},{"one":"0b7e1e5acabcde503ad827e45724402406114a513f81040a379b0f82df2eab4456b348b27936369c49e3c264d971c6a9e2c2217fdbc5e5b93ac6fc219957834d","other":"c332fe1f9b6e25f72c7150631ffa6e0929ff6eeab5d17aa45eaf669bdde869cf404505ae990a529aa3ca797cd0a96f31cc41431a5d4a163132be566f91623c08","up":true},{"one":"a08e47137bf611dfbd20308a22bdd3ca00121386f121d6d712ade86e9a1601a4237766887cd91c8516e20b6e323d2ef49c1c7e177a0afb4c813f0f344daf779b","other":"292c78c8e41606e98428096bc6f4609a7aa48e5c4d17eecc64d65faae4a7270b0c15f0cd74274015688ea0a9aff34f215c29118222e362a29c8d637963973a55","up":true},{"one":"3d2df188704eeac09c8b291bf275a73888199a231c832c51dbc3d746968d4b51a7d5eae0c7c9b8c8e19f5e28d38c375e01abefa343f31dbe221deb837ab8a0df","other":"062e0ca43a1885c4a7ab2a5169790f9081e3e9a2dfa286b8cc592d5ccbf13d7a82b72d23361a19026d04fcf41b752ea320d98359d770aedfcee626e21c3494b3","up":true},{"one":"beec648d79437a5d7b4140ced45d82d035c6f64f9c67c58386703811d97c3846787eaf274d2298df809475f0b7519df696563cb8e9a5fb0a9cc419ab13fa8d41","other":"9e621c3eb534855ca292efa27a3fbc89b4f05c80a4bc65bcff2f14ff28ef43cbe14137d2fddc6fe2658bb06947d918476b479dde71469b8680e5d8a7a01619b5","up":true},{"one":"bd1a7c63fca9e1fcc67d7fd62670beefe2bce483cf1dc1233ee85eb90db607917cd9a5d7170b10e80b925a20e2af2c54d286b01805ac34967410859f4f03da09","other":"934a5fe1b91c1891ef4df7f67c027e0eb115d4c2ca4a1b76a135ebd4315c4fb835d6625223194e6a134407b38b0d3928fbc7bc924a3c6a538989a6cf200bf4bd","up":true},{"one":"9db1f94d74a00d1e5e2a391f1bcddf16b6d0670a2c6d91d946d38112c58634444b6fea8e8c05ab4b73bacdd62a0b575f6fb8729978edc216c7842b177b9f9cd9","other":"292c78c8e41606e98428096bc6f4609a7aa48e5c4d17eecc64d65faae4a7270b0c15f0cd74274015688ea0a9aff34f215c29118222e362a29c8d637963973a55","up":false},{"one":"7865b82e44add2cea6ebcbaba9c152184331a2940fe73f6f9bb940bda8a59ab4cf4760894b9cadcaa54e36fbb712ad619346a49a85e32cdf2b53cda1ac1e0658","other":"a08e47137bf611dfbd20308a22bdd3ca00121386f121d6d712ade86e9a1601a4237766887cd91c8516e20b6e323d2ef49c1c7e177a0afb4c813f0f344daf779b","up":false},{"one":"b3316f4fd7dec218a52331f25d17a2faf0f2a417808d7dbb80038154abfbcd2d78da074837b648cff28675f4aa0d65ddb7d15abf3d7e0391d401e313a3ef24a2","other":"17a79cb279306b6bbd35219278f6bba03111079d6c4fadcd3c5e57b09678e111bda5f8e36ca3d223e51e255d6e857363b7741e438b32ec6e6c0dc1b224071081","up":true},{"one":"485825745d97654cbb92a14e0cd1078691d3c28f4d82b1046284b676a42b44ca58eb43474e45e415d3bd3f3c383f9a1a3365821ed7ba6a9f2603b29d58031dc7","other":"bd1a7c63fca9e1fcc67d7fd62670beefe2bce483cf1dc1233ee85eb90db607917cd9a5d7170b10e80b925a20e2af2c54d286b01805ac34967410859f4f03da09","up":true},{"one":"4de378164d77a28c90cf162dd1b465e0282ee17aa7d3bb3179252466f72da33a36c9f298f7c9498e38dba4018e7ce3e5fe631c83842cd9059e23a7fece366d87","other":"81288bb0584b7ffc1546043e052e1df10fd5371b35dedd0bb42ec5b30ce69b741b2f7857af5984d4754b39d7253575fde9298504999b78380ef602d391c4bb1d","up":true},{"one":"155e4879643a472420012e040a87dbff776fc1976814c0c6cd0d5e157f0d0baac04aa7f2535786c09acc2700547383d2119b64a6f62115f1aff1708738844d8c","other":"109556abac422a912ecffec0d8796f8f16e92e8f95cecf72dc89e97a8bf1fd37aad3c66aa3cf134acade6d065c31821f977171d5c5463305b57ce3eee99a7ab4","up":true},{"one":"c332fe1f9b6e25f72c7150631ffa6e0929ff6eeab5d17aa45eaf669bdde869cf404505ae990a529aa3ca797cd0a96f31cc41431a5d4a163132be566f91623c08","other":"adfba6d883cacbb141cd8c59ee04d7e5d520f1ce31a81e5db2d8b2380bf801c1fe4b265a66b71f9643d13a41cb1f6fb4b83399be786da4b6e171b6784bc56e49","up":true},{"one":"657d5370319128d24d925b41065eb619409d63ec6280975d78877a4028287463f6442f5206dd703569a05b2b542ad8bbb99803da265408208d6356a26d283d08","other":"352407b42726dcd1aacc46a912ed8124b8b6a3da4e33dab742e40aa2452953d35dc8f42eddc76695ae2317e9f15dde2cd21be4ce826934695ad1847455661d1b","up":true},{"one":"aa9a94d6e4eaaed20113c21752c224e3a052abd3769bd6e832759dbaf5154a943cf094eacdcb0727c2fe51a11bd7fc0793d7d5e3312b0aba89d428a00e1fde0c","other":"8ca3b63cb84f1e9883d82809a9b6777ec1029ecda96fe93b4d494ee9cbefcad13f381b3e480136e542e01054fe1ede66c65db84a0009871ce49383db461c8438","up":true},{"one":"e2a27dcdee1f89fa362a85c4397840cd8be4ad8d1b9ccb23188c303bcab7619f38772f71385922d090390973b62fb8249efc103f71bc761041bcb3880ec0b935","other":"d3105ede6c21bc643d523afcd1309a5dcf03f70797a92f167c3a19f86ae98882fe1a9d4094d7a3dee4a0833b8075b6c3e9aaa7f4879dc47bb388c3ae85522288","up":true},{"one":"fde7705f5013c3b6b76a35505c1e3d57c033a337f2a71e912ec3a3d2da8e113bd7c36d94908357e9f7654660621f647ad8c66b0126dfe91dbfa3b8c7bd2183d3","other":"a99852c5bf08ea4713af9cade5343d1259bfb90401aca7fcff18c58cd56a98804dd16c61fea71039c0ac31b9bbbb9dc5aeaf0c2f074d3365e88d17031802d636","up":true},{"one":"d3105ede6c21bc643d523afcd1309a5dcf03f70797a92f167c3a19f86ae98882fe1a9d4094d7a3dee4a0833b8075b6c3e9aaa7f4879dc47bb388c3ae85522288","other":"fe62314839c93d2f6e3aee984d5f0b321897c6f39e66800d3de8b773baf6f19e0a03cae025df512aea8d5f1b667b6dbb15c192a90a76d3031c14e33e5c16c4f7","up":true},{"one":"315b8a1711f680c2eaa607e35ef7a9e19c2b61721af8a7e08f1325dde1fe33cf1f47b3cc4acf12d541631041cf1b42754875fd1c9b66ee32797b72b9f7711256","other":"b6a998dea59194cc60ce97c7c9702368411889cb6905516b23f41cc5116fba8d0f237d418318eb0c333cad18003c0e9a6bd8c99080520771f2bad640e2e5ec1c","up":true},{"one":"17a79cb279306b6bbd35219278f6bba03111079d6c4fadcd3c5e57b09678e111bda5f8e36ca3d223e51e255d6e857363b7741e438b32ec6e6c0dc1b224071081","other":"f039df8a3206e6e17eee8e95010038c450cb4cc0b5580ed5795d4c21802e1e9d360f4528bdca794f457932b1d6a818862ec847357a861c488332ef6d9480daa6","up":true},{"one":"fe62314839c93d2f6e3aee984d5f0b321897c6f39e66800d3de8b773baf6f19e0a03cae025df512aea8d5f1b667b6dbb15c192a90a76d3031c14e33e5c16c4f7","other":"453779010ed7c59761da47ccd8869d3fa8349795e57edb9eea416c0712301ea622c7683858e309d19ab137ddb0edef161d0d00a361abeecf0628c3ffabc629ea","up":true},{"one":"b6a998dea59194cc60ce97c7c9702368411889cb6905516b23f41cc5116fba8d0f237d418318eb0c333cad18003c0e9a6bd8c99080520771f2bad640e2e5ec1c","other":"65e954e60837bda10654480b227fa3bcc6e63356c52079002a27e836cd82ae2934ba77da60080e4b9f2d9324b982b24959bfd9624302e6c330408381054b43e9","up":false},{"one":"57fb1bb32bb2b1a87e44c6a7557e9c47c2032d107bcb0e34acd9ffd54d5d3df5701232db16f62f7549ba2721021898b03160b1dc5201e79606648c1dbc4a373b","other":"a78f18691e0dbf3c08fe9d7dec188e6a05a93833432fb99eb2b3924ab0bde7a44db2a102a65544bbdc4fb61bc3a3d569230d9843a335bf619167fb045d78ab3c","up":true},{"one":"54b3c57a4adf4dbaf31b85ed1b8dccd6249faa16dd96dd230189f47f57970caeed36627cc8e1b0794707418d580f5bd6001c07be6a79216695f1253db24926bb","other":"24662a43944228e4ff74736bcf0a0a4f79c87ecfdb739225b2fc45110c11bfc38aaf2d09d98e5817477848e553f187ac5408bdb864518dfa7f5df542768828db","up":true},{"one":"0b30b36e155db04c448b662c4df695068b2331cdbe2772aae5fda84159e977515a5ff2e156bc225a9281fef2383926ba8cb11e9c1846fb40db241e524ac14e29","other":"5dc69635f6d573c824ea83b18593a47f9f21a6f91ce18d2bf977c97d21f8d2a8ce88829244d12a07d949bbd52fe8a2035bc89685fe1bdd4ee20d766d75d3deee","up":true},{"one":"ae4e21e1587a8475afd299e00ca7085c7bf2a44c2c64a3068f12223d9202b0125094385319034691ec26b497ec9cf18fe8c0839224bac1b84279410241cef979","other":"48a5e01e06e297dc1c640ac9601171495bd70fea461c60e7e6e2532695e45fcf68183c2e58b5e6931a6c1c094f5331efbd7f2d93d5f84efdec5a35afa2124438","up":true},{"one":"c9cd9dfb9f90a7948ac5a42c7bd63263f2eef6e1d85547559f7d2ecbf5f9cd1eab051b8e9e661b573c275d84091a44e73f6fc6bcc91dcdb674bd5d939190fc01","other":"e98a08e8e3544727f5ee27f4465375a67ffba490fcdbfe7bfdc909f6b68bd279f776c65d38c2ccfc33079f852f76349c94d68fc6989c0d981f22333f036a4bb5","up":true},{"one":"caaf695c76cf7c047d3f3bfe019d01618e4871cee8ff3f347913da815bbcde145771486f916a44d03f59ea9bc217f169fd0c0765fda3f9b9b28d02a522e180b4","other":"b6a998dea59194cc60ce97c7c9702368411889cb6905516b23f41cc5116fba8d0f237d418318eb0c333cad18003c0e9a6bd8c99080520771f2bad640e2e5ec1c","up":true},{"one":"eab86c521f8f1ac67c015ab713f1236a08b0200757a96bf87ab8301e7967ae62361f0e14da14ca294fc8cb3b4726b52f4773101e21b032977c6a647241b59c73","other":"e1ecad3beeb6c19dce551e4a603c7b440b4498c44e298dc67bfaf4ed2c75bbea95df48b1cd1318e2ccb962cbae7c30ff258e73f8c3fc6b7e9ae7a47f7cf8e53c","up":true},{"one":"48a5e01e06e297dc1c640ac9601171495bd70fea461c60e7e6e2532695e45fcf68183c2e58b5e6931a6c1c094f5331efbd7f2d93d5f84efdec5a35afa2124438","other":"8c6d77833bf1a98beabe7a92d985d13d52fb2e50768719ffbc6fce21ea676802a074b6e620b3ef80e12fad04f94a3c288d91df9716a6cfae09ef073b9dc1f2cb","up":true},{"one":"7808fb798d22e78fb1d39b87ddf99a503f820993bc64149eca9e81d9d58fc1adea60d8de14a4f06cb89f3190c0ef0c5e182621a14c9361ccb7e0cee667599cc3","other":"5dc69635f6d573c824ea83b18593a47f9f21a6f91ce18d2bf977c97d21f8d2a8ce88829244d12a07d949bbd52fe8a2035bc89685fe1bdd4ee20d766d75d3deee","up":true},{"one":"c8b0dba45104fc7c7dff3ce078a0d3f5ade6198bb4656e2bee8076387929133e5ef2bd293b130a9d4f6a6974ca17e8b4a8f406d1219880f1e0f99c65c63af5a4","other":"e67e495385e7cacfe659b40d1ba94d4b1ff55eada70a4d9740a9e452fbf221672bd0a897b940e2a6bed71e2a16867fe45bf0ea0015435ac6d815690e263b1899","up":true},{"one":"5142eea687de4248b2184e9896b245563117648e7a156255d9a7ae730313d5d383db3be1125b5accd7e743c2a5d8c3289ec559ef7cbb803b9e82cd49bb213d9f","other":"6f60ef501b41f9049419b033ae8d793a18067bdcd60347537b0dc3873bdd9a2d10d24909cca7c39781765746128c2165596f6537a94f58279523faee71f9c51d","up":true},{"one":"6b01079463ec2f649db8634cb7a596261c79a8f714d954c772528e0547b017f8ce405e4a0ea9d32270848180e0f77b8c0b022cf95c85e777626edd4d24ea21d2","other":"c8b0dba45104fc7c7dff3ce078a0d3f5ade6198bb4656e2bee8076387929133e5ef2bd293b130a9d4f6a6974ca17e8b4a8f406d1219880f1e0f99c65c63af5a4","up":true},{"one":"80d997b87856099d844187d3d1fa40846ded652a62c1611b35919c2543915b64ff62476636488556f678e436ea26fcc40db7c6b6bbcb78f590d61c1ff0e424b5","other":"54b3c57a4adf4dbaf31b85ed1b8dccd6249faa16dd96dd230189f47f57970caeed36627cc8e1b0794707418d580f5bd6001c07be6a79216695f1253db24926bb","up":true},{"one":"88d5c5fe61ee1e6fa5878e0eaa13bdabaa0ec3d38a5d25b95a467da7627424f25fb5d30535aa0a5ad01c16fe2598dbf570b78cc152a7f4ef66d46fc9ae43592f","other":"54b3c57a4adf4dbaf31b85ed1b8dccd6249faa16dd96dd230189f47f57970caeed36627cc8e1b0794707418d580f5bd6001c07be6a79216695f1253db24926bb","up":true},{"one":"f6ca39b3ad803e99f4e4e9cf759fff6abdf06e6972bdbe524f6eb930c669d6f0e9b91f3de9df394b0d661b068273861391bdbac948ad911351c48cf02f874db6","other":"3b570117addeec03c2694baf28e246f91907268fe665c6c90356120332794258ee57a60853c19e9fe25d042ca42a5be7fe0797d84199174de8132f1ef4a9349b","up":true},{"one":"0deda014fa3c0bc8f37d853e1448f95f56f97048c28797d72258fd3ba2f1f776ae11566197466596356cd172847ab02a89f4cf047e58383249fb2a4cd69b6206","other":"b4a5efa9028b2d196855393892f79993c2812d02b758f98813ddf82c5d943faf6d66eff811cc5a51936c118f4c768c0d13b54902095e040c602761e63c08655e","up":true},{"one":"7e2b0b4f3b55e97bd7241b984ad117af33bf3baacd22b3ed503a8a59f75828df745fb3ce3be4276d83eb484e64d9aa251103fa994ef119eaddb97a3503b9f292","other":"2b70e5ffcc0bb1c4f8acc09dd1016e67c9c96c92d091ad481efbb71bd8b2a5a5869c6d668617a9b2cbfe91baf5edfe150c3824c84d90899a974099071d171441","up":true},{"one":"7554993f6efd8d9016ff525ae73c41ee2e0dbd4970c563ba9b61a99c1c8943b433c4b7d48450f6e0fbc9ac198d907698093de20e6c1f7755520fb1e1cbee4eb4","other":"2bfba66ec9d63e928d77d455f2e10a14d6213e515099d5db14fa44a8bfc147eb0fa7afa9aaccdc86453c6903b55556059a2e13dd61fc494127d4a3ec173bf9ea","up":true},{"one":"7174eca109a1f717653918224c8cfe1b7fbd666405196760913593401eb79f2c7e41003b01f5a458940695b27a4673443c7621a169db7fd968994e552995dbbb","other":"8dd8ad560af84bec579cadb33d51711aa61b6ed22705010336df5a71a94591173b25e869457429c4a199b205fce8e73530e28203e18b971c2001715e610f152a","up":true},{"one":"a1560ce7c1f1d5972f027a8e9cff820611d84764aa067434a75b63887bc4268a259101486d34b7fe83dd735e799789986cd3e9b156c86ede598bd86af4454924","other":"3e488a7208ce0e097ce47fc6651a13e95cae137d1a054a09b04d2f59d45faa2594a8c3b395e77ad1a3c2edcd827dda73c0c97dbaa6d9519a79184a0aca01ac4b","up":true},{"one":"2ac522ebfa49d37f86c6270ad4cdad0e766493f0e463b18c9906c70fbd2e5c6ff6b0d5879de6e3894418370636963a78b0c0cf087a8684c2ca30c9c736e49228","other":"062e0ca43a1885c4a7ab2a5169790f9081e3e9a2dfa286b8cc592d5ccbf13d7a82b72d23361a19026d04fcf41b752ea320d98359d770aedfcee626e21c3494b3","up":true},{"one":"8c6d77833bf1a98beabe7a92d985d13d52fb2e50768719ffbc6fce21ea676802a074b6e620b3ef80e12fad04f94a3c288d91df9716a6cfae09ef073b9dc1f2cb","other":"617595a230e0a74a3db3b47cd27b941e02bdee9a84cdfa8eaa63a55941eb5caa79e20fb69726a4d46a0e5aeed24039f8c5a20679a692df0bc140f42558ca9a2b","up":false},{"one":"535f93057d46c4aae0902546550880be0b5ba67dca12350117d471d67f4f2b3f7bdff29bdc918767974c465df8fa1afa6bd6c29c0a36d51f71c4183673d906f3","other":"11d560045536e9d1b0b1b9e8944e00f0ca7f1e6788c9fdb51061820bbb3008ead92bb7836621bf58da7035c87a28328faecb4cb2e3cdb9d7fa4f45790e6bf352","up":true},{"one":"7ac5b07eb555af3bb4ca3f0f4b45204d43cc3798c244435909b97d9a32fc3abf0b50666e260e046bce826a7a102a92d389f8f39c5311e83bb34beddac29d50e3","other":"94088fe273f76e62ca4e43c095ad12215b4ae4c59942328b3985416fb19bbda0cacc143a49eff3fb644ad53a19d3f043260e43dbb70a0aa9c15829c21cecd3c7","up":true},{"one":"c83985973a9564ade7d90aa54911ac57077600676a1d27292d98e058bf1315887bad84ccd708cb7f52a695a1405fb7d491d7ca2ae9caa3ff58a5ad78ce4dc9d9","other":"2ab9513899c3c829b6284e56bf2b9862dd0156ec052b58615dba77d450dac642e534ec36ae5d3234262aff54e19f99856e908b9d8c1da660a7834a445610715b","up":true},{"one":"e087230634f556b818a416b66ba3f1d1dbe3e0dd0698bbb26fa86a2499acd169466f564dc18adf2f9be4d1ada0e86c11549754097601e10aff4f3a57ddffa24a","other":"7865b82e44add2cea6ebcbaba9c152184331a2940fe73f6f9bb940bda8a59ab4cf4760894b9cadcaa54e36fbb712ad619346a49a85e32cdf2b53cda1ac1e0658","up":false},{"one":"c903c5ee3d9cd65bea3ea777e39282c33e1349d945411fb2f16321bf582c2f400956a98fbafe5873fc5f6f6a9a051df5da7e94cbd340f935abe80f91e79ef875","other":"807340e5fdf6c21a56ef2fd158c32e92201206ca85fcc147165a408f7a735964afd47c397e663610ac53870ae722c0317291732b0422f8aeedae783d9c730218","up":true},{"one":"4ff66e9b5d3fd345990bd7605bdc222b78946f0c13b72bf80352812b2426d8f1d36c93e6c8713566004615e8a78ecab12ab0cfba254c0967eeecf8875b25bdae","other":"58cfb20d3da3641e0ad529b9edbd4b590a8d1dc9d1ed7b44ed3187dba9260bd7c732fc10981f5b9bffd31d362cb05150173618aa36138984431d94a323a9b313","up":true},{"one":"831cde5b651ba327b059da4c7f84b184bdd6bb99c6690ae816affe25d42c6c3dbe5b59e2b6bf23e9d0f6c485bd341ea57ba1a8220d18b0a40e156b77d84f79ef","other":"58cfb20d3da3641e0ad529b9edbd4b590a8d1dc9d1ed7b44ed3187dba9260bd7c732fc10981f5b9bffd31d362cb05150173618aa36138984431d94a323a9b313","up":true},{"one":"7646d08b3e24183e3814de130235c41eb88a5a2abff23eaff3c91954ad3ef55fe27da422dac5b894312276bf1a2f1aebb8b636a8d4a0c93d9b016d441df3fa19","other":"4a030ebcb1a59230759d25a3c87daed22906b520d55a78eab2083bb52358ddc3a5d2d7c3265e6c54a990bf32d0dacb85905a4173d72ac18fcd74c43ecb8635c5","up":true},{"one":"094f9d0fd3bacb17ac67a2edb8ed394fbbd1c8d478233d3269cf217e7b788e21042374936b885bf23ee4f9e03babbe4e08db283dfc2a6e052a8a5ba133717dd5","other":"9b618ad34d0dfe0fccbd5b8af365cbcdbb43e802df5f23e91c20d21f3ead6169d52bf0db7e5e111abef630c9853419fb33a88cf111d8507b8708208b5d65e35e","up":true},{"one":"e0f78c59a61f2a953553cd5742c58f4a82e38e35ac7eaa237a6ffc9fb0a3a26a2d1d1afae249e611d1320f2cb25804bdbdfb6d77336449716b0f4beb3298b8aa","other":"9b618ad34d0dfe0fccbd5b8af365cbcdbb43e802df5f23e91c20d21f3ead6169d52bf0db7e5e111abef630c9853419fb33a88cf111d8507b8708208b5d65e35e","up":true},{"one":"baa5924e1547c177011285d292aa161a15e5ff282da2cd0afb83c9caffb07bdbb3662c227fa7b26e6dc8be9b8863e647eb5f8ce81640532f8f5c9a7f36557e63","other":"ca1aff0d847c6fdacb623ad9078a0885b3208614fea20d5ff11779779b486bf5e9c794aacf848d3c2d58cfcc1eda8356df82f5fbdd0a5236beffe8e6042848c4","up":true},{"one":"deb7af800cd20a647335f0feff5bfb3e182f99f4c2d1ade10da36ecfdbac3b5fba4e8f0a4595443fe395b44af3a95617669850944655def85d57cc81c5682a3b","other":"ca1aff0d847c6fdacb623ad9078a0885b3208614fea20d5ff11779779b486bf5e9c794aacf848d3c2d58cfcc1eda8356df82f5fbdd0a5236beffe8e6042848c4","up":true},{"one":"396c703d27bfdddf91761f134cbf665fe61e0b3a5d24036a4105a625f72e8c28b821e9200f20d6e8f8b3ed6b95bda6b8accdd840c2f786720b7431e3af2af981","other":"f915e2398aa5d4370de87504dd76c21a7d0be2581c2ab55b7a47743f1bbaef36384eaacec22760f1e914ceac9d96a10c3d66eb27475ef444e77fee979e6e88cb","up":true},{"one":"6b4e376e9c94242b6d42688c22aa9ab418cb6dfb1cbca1c69de0feceec8d3af29fb005017aaa6e503cc0c03cf0dc5bcab55e01cd6f64b9efa02ed87c03020003","other":"7ac5b07eb555af3bb4ca3f0f4b45204d43cc3798c244435909b97d9a32fc3abf0b50666e260e046bce826a7a102a92d389f8f39c5311e83bb34beddac29d50e3","up":true},{"one":"453779010ed7c59761da47ccd8869d3fa8349795e57edb9eea416c0712301ea622c7683858e309d19ab137ddb0edef161d0d00a361abeecf0628c3ffabc629ea","other":"72e30d4562673c5c8fb03709d93f73322747858d723b7eb5ef2fbb88e0331252946b7e93ffe434fcb599c4fff57800afb29e6c60a719f18f49dba541c3591c6e","up":true},{"one":"9c30ad8c85adc7bb52ddcfab2e661cc3a854a689eaa59128d35129d02cd5b0f8da4a44cdd33934a8e2c8fab1760c16d6f2e1c5eb227dc819e85624e63343c069","other":"57fb1bb32bb2b1a87e44c6a7557e9c47c2032d107bcb0e34acd9ffd54d5d3df5701232db16f62f7549ba2721021898b03160b1dc5201e79606648c1dbc4a373b","up":true},{"one":"302c37f28c69fdcf00b39ce0c0223de0d94cebc2c0b068315b95b76b5432573ead0656569441029ba9054d8d3d959fd8735e73913af5ce3f1132f8271fd437ef","other":"40bdac599b00e9c41ad6476ee415c33d9c17c5aa672692c2404e523b29dc315da929a86874bed87fd9009871805d1dbf3098e7a817193e3b08a6eee66346da79","up":true},{"one":"ea57884dd42aec5a76eab43483bf7c4ae2c19eebf365013731de64494d10a3b4cfe34c86c79437f9012bc8cf6bd761435eefadec17600f4b9e4bc234532d6282","other":"54b3c57a4adf4dbaf31b85ed1b8dccd6249faa16dd96dd230189f47f57970caeed36627cc8e1b0794707418d580f5bd6001c07be6a79216695f1253db24926bb","up":true},{"one":"ca1aff0d847c6fdacb623ad9078a0885b3208614fea20d5ff11779779b486bf5e9c794aacf848d3c2d58cfcc1eda8356df82f5fbdd0a5236beffe8e6042848c4","other":"84abcbc7b5598ecfd91ceace0927921a5a3404fdb274fc2a2549abbede5f8e4f62c15688a4dc9a2d80262c45970c88898da245c6eb779f327a81d53a17bbc74c","up":true},{"one":"27d9048707a89f1a61e44fdae523c0128f2a7050308bd3cfefa6c3e03040a0e22f11ab41275f22b8706e6695ab93320e2af35179d772581db5f49f960750f2f7","other":"54b3c57a4adf4dbaf31b85ed1b8dccd6249faa16dd96dd230189f47f57970caeed36627cc8e1b0794707418d580f5bd6001c07be6a79216695f1253db24926bb","up":true},{"one":"b35f418c7935cc54278e90978c3ef1521ab91daeaf9f1ebc1cd25211611ade091cac4e1f009d71059279d507322a4536501980ac0dd44caddc52fd4c593879f7","other":"6b01079463ec2f649db8634cb7a596261c79a8f714d954c772528e0547b017f8ce405e4a0ea9d32270848180e0f77b8c0b022cf95c85e777626edd4d24ea21d2","up":true},{"one":"59b53f8a562bee519276e0eeccfcf8c975d3102f5d0cccf5abcce291a8a5bb817c04604f123686177a50a03b9d7559ac469962d0159d1d93e4ce58a304d04b55","other":"8dd8ad560af84bec579cadb33d51711aa61b6ed22705010336df5a71a94591173b25e869457429c4a199b205fce8e73530e28203e18b971c2001715e610f152a","up":true},{"one":"2ca05ffc0ad771e1e045a47f1c0a79ce374a25e3c0e53c2a80d67e7479677003f62880251a83a5074f1c9651d828f1ff7e352935a9df141c1eb75a0c59b00a8b","other":"315b8a1711f680c2eaa607e35ef7a9e19c2b61721af8a7e08f1325dde1fe33cf1f47b3cc4acf12d541631041cf1b42754875fd1c9b66ee32797b72b9f7711256","up":false},{"one":"cb310c0e86aa455d7c9af6394ae38561c901da30a51d7ccb7e66a09d9a8f192ae8caeff106043426d56397088f141c4e01e3b98f1ee583ffc7318b5f730f3ac7","other":"e267e71c2dcdbe5a500b23444d2d4037ea15afba8f4f2b1c0e54a274450404fbee6fa5439f7cddf4ba1aa28fa93e434b01c239add58e30a5423ca3a481584d6b","up":true},{"one":"c665a6b1b7ad39b86bd4b1fe38b7ee95a0fbb1db15e91381ec9e5a235e33b69ffdc92c60dafd74b7b4dafca1b000e9274bf045abe5b93b1a9c2b31ae071a9898","other":"4ee37acec2178ef120166265aaa2b64b09b315fb53861405ef46f2503c273eb9692e9cb4c2e67a8652254d430fd6e02dd3fe4cded20bb231a9fb834d292b0b24","up":true},{"one":"28d3232c43de54ffdaf08f97b334c012738648b04e2876c7e751a2e352aaf4d550d6efa976c5a8edbfa8e88b9d04a0fca492b81c3756ef673ab74d34182ca711","other":"ddaf3f8478501cda872c056c72063eb64d5b871fc5fff70704872802289dd2d348f73bc342b7f148a90cfaae2448ebf16fea196be9df891dc71a57fb410d59dd","up":true},{"one":"1944f98d4db32c56a5efda5a79aa5f276bfab1e084d6611fec0e735b8bc0f45b457cdb74a23fc83b2377821fa8316123c9877acd6db7c41058ca5d3cfedaecf9","other":"11d560045536e9d1b0b1b9e8944e00f0ca7f1e6788c9fdb51061820bbb3008ead92bb7836621bf58da7035c87a28328faecb4cb2e3cdb9d7fa4f45790e6bf352","up":true},{"one":"1b6cad4f9851cc584c5d1405f976bb51a52e27ef4525847df543dcca65ca5eb1ef229dcc68ccbaaf00ab1e044cb5990dd213c805bdb4adcceb6fa70b5c61fdb4","other":"28d3232c43de54ffdaf08f97b334c012738648b04e2876c7e751a2e352aaf4d550d6efa976c5a8edbfa8e88b9d04a0fca492b81c3756ef673ab74d34182ca711","up":true},{"one":"385168340139236a0e0f537fa693122db9fa02a377c96f31aae54718e92624fc0288164877e63616651565e055c53f7074ab2fdd18a837da6faf644941305bf0","other":"6bf9fb6a25521c16c2ebeb6203d046d7dd40f29cc2ddb067c0222ef56d7012d2ee5d037f71f6668ea56767610b2a54c144aed74b7f68d06993cbd52fa1dc7630","up":true},{"one":"d7a319f69013b8375e64d19f015547462c84565b882337998f9e669c5fadd3d2ecf6374109903003e09f5d453424b5c7fdf52163d2cc8084cf81f94844946b63","other":"94088fe273f76e62ca4e43c095ad12215b4ae4c59942328b3985416fb19bbda0cacc143a49eff3fb644ad53a19d3f043260e43dbb70a0aa9c15829c21cecd3c7","up":true},{"one":"8d4920d6e3a6717699b5a3af068cbdfc16858d7e393d158d41b1b5f345b47129eef89e1d055386c518f400b134678c21590f0317dea3436d4cef60f45455cf12","other":"315b8a1711f680c2eaa607e35ef7a9e19c2b61721af8a7e08f1325dde1fe33cf1f47b3cc4acf12d541631041cf1b42754875fd1c9b66ee32797b72b9f7711256","up":true},{"one":"92d6ef729992f0de886076e5f8cdc42cbbd70b29e79c25e0b3d22b6575d3d2508d47b42f581e335455483d43625bce4e55f88cab9ff2073ee8dab746357864fd","other":"7ac5b07eb555af3bb4ca3f0f4b45204d43cc3798c244435909b97d9a32fc3abf0b50666e260e046bce826a7a102a92d389f8f39c5311e83bb34beddac29d50e3","up":true},{"one":"1c2f7ce55a6e38487f3b3fe6083a79f914cd6d7e4aee8f5d56b4a61b3eb584e128c56998db0e13e775edee3adacf54f09960a041dab3daa80a4f8a3b42760c1c","other":"11d560045536e9d1b0b1b9e8944e00f0ca7f1e6788c9fdb51061820bbb3008ead92bb7836621bf58da7035c87a28328faecb4cb2e3cdb9d7fa4f45790e6bf352","up":true},{"one":"9bd4f0adb9a966cc5ba632f1b540fe9cd6c8e39fe1a041b315697679cfb04b735952062ce057d456677cc34a84301f26bb727a4ab2646fee734f80a22c620746","other":"57cd4c0048b459192ee46e19ec7df777e600f256e0dc8c3019431eb7bec3c020b9504ec7aea3dba8188658ca5b830ec40af6a8540ce10e04badc6c695d009271","up":true},{"one":"71f89efcf939294bb94ac669c8afd00def58c8dfad519c226adfa068692d588ef797116d42aa146b9d34f3be35ec7c014022640ab3c0f1f9034e44ab1a26e246","other":"58cfb20d3da3641e0ad529b9edbd4b590a8d1dc9d1ed7b44ed3187dba9260bd7c732fc10981f5b9bffd31d362cb05150173618aa36138984431d94a323a9b313","up":true},{"one":"65e954e60837bda10654480b227fa3bcc6e63356c52079002a27e836cd82ae2934ba77da60080e4b9f2d9324b982b24959bfd9624302e6c330408381054b43e9","other":"ff6f94005d1df7677600069764855c1c2aa0543cbe9f480f8feefec76c49d9e2c7bb2d8e38c89e9430f53f8b593d93f143c45985a56a5a32c736128214c95eda","up":true},{"one":"11d560045536e9d1b0b1b9e8944e00f0ca7f1e6788c9fdb51061820bbb3008ead92bb7836621bf58da7035c87a28328faecb4cb2e3cdb9d7fa4f45790e6bf352","other":"7ac5b07eb555af3bb4ca3f0f4b45204d43cc3798c244435909b97d9a32fc3abf0b50666e260e046bce826a7a102a92d389f8f39c5311e83bb34beddac29d50e3","up":true},{"one":"6ab6ec15635b2fda22542c99df0a3313ad4583ba0fb3f31b8f314e3ecad446d3fb0fdfcd2be9b08374b1a7e049fb68e69e8dacdd13f1df5007a656f6b11adc5b","other":"11d560045536e9d1b0b1b9e8944e00f0ca7f1e6788c9fdb51061820bbb3008ead92bb7836621bf58da7035c87a28328faecb4cb2e3cdb9d7fa4f45790e6bf352","up":true},{"one":"ba21a373781966135d6225adae024a3f3e421b852f72f8b0569cb92fcff87c33f7e5b799a509b8eff6ec6dc46a9b17d5bae1e91ec7c54c0c712d893d54b140fa","other":"9b618ad34d0dfe0fccbd5b8af365cbcdbb43e802df5f23e91c20d21f3ead6169d52bf0db7e5e111abef630c9853419fb33a88cf111d8507b8708208b5d65e35e","up":true},{"one":"bf4ff51cc3d9a9d8cefd7e346ce1384d06450228a6086fe12fb0c60fec54bb6478f090bb638fbdbf8f41f7bc6420cd8a5c8b1b8566229b6851167375ef412f46","other":"b53078000796f1cdb04dfeac424d5e3e37e30f00bd5bebf9a9ea0525c62917612b3a8f508df6bea59e3c7e4cd1aa530841f9a8af54e44f5617a13dee2c6ff007","up":true},{"one":"1090e9d89cb278a30063a5396d9ba795d3bbc237c76915a6fb7d23aa1822c8535d2fccc44cc8cd2acec68444c0bf1bdf5195ebb9f3cad8dac3d94a4d9c0e5309","other":"0deda014fa3c0bc8f37d853e1448f95f56f97048c28797d72258fd3ba2f1f776ae11566197466596356cd172847ab02a89f4cf047e58383249fb2a4cd69b6206","up":true},{"one":"f9ffe87c52ff4c22bd9696af32e0a9d34bb81fb84d9d8bf5aafe2ef9696e7b3d6460bf2a93aecb066133f53416bde841a02d6967bd06e3d4a714f3b2c123a947","other":"7aaf7817b93aa6d2f50513791f9ad7629a901ed0dcb151189f44763f83423446b20ec79a48fa260cd9bc2907d5f0ad06b2c4c5e6d812f3d8876c8020ebe41019","up":true},{"one":"7f357b8d81bc2e5c6fcb081f23a42b3e2439f050d45c45851994a268d1c71fcb1f39f8c3f75ce921d3fbf80fc0e73f0b9609d72001dc4a6b65b526d312a4f43a","other":"a78f18691e0dbf3c08fe9d7dec188e6a05a93833432fb99eb2b3924ab0bde7a44db2a102a65544bbdc4fb61bc3a3d569230d9843a335bf619167fb045d78ab3c","up":true},{"one":"57b47f692f4d69a5d2c9c193680eb4ccb5a6c574662df0138504a549f3ea74f20c5b866ac4d9e76c4b49c83f5fd692ead928ea20dfcf643a11a1c1e841c0ec42","other":"062e0ca43a1885c4a7ab2a5169790f9081e3e9a2dfa286b8cc592d5ccbf13d7a82b72d23361a19026d04fcf41b752ea320d98359d770aedfcee626e21c3494b3","up":true},{"one":"2ddd49fae11d8bd2e7e75a481be267fa846f51cc1160bc326aeea51c542323ff444909de11e2731e835140bc0b1b32020e1e73fa652511a381222bf0aebc4081","other":"062e0ca43a1885c4a7ab2a5169790f9081e3e9a2dfa286b8cc592d5ccbf13d7a82b72d23361a19026d04fcf41b752ea320d98359d770aedfcee626e21c3494b3","up":true},{"one":"0b7e1e5acabcde503ad827e45724402406114a513f81040a379b0f82df2eab4456b348b27936369c49e3c264d971c6a9e2c2217fdbc5e5b93ac6fc219957834d","other":"a7507aa5665e165ab2e2a07def272f0677f9d6d35bb82268a34214384e7d8ef7635a299368752e63cfd02d4e60231076baf23cfa10d17492e55181b391ecf335","up":true},{"one":"a08e47137bf611dfbd20308a22bdd3ca00121386f121d6d712ade86e9a1601a4237766887cd91c8516e20b6e323d2ef49c1c7e177a0afb4c813f0f344daf779b","other":"ee36d1d5dd69fd30242d7da2e941b34ade5581c7164fcc43288ecfc52937a98f1b31ade5d1e4dbf611cbe1c7875b2840c89435081cde471c271d7bc60e9ef211","up":true},{"one":"4314b0b04331973ed29a58843951f144ac3d09bd5d57b6cd9aaff9b73a7b2ec81e344a3e4ece462bd2081b837a06310e787ef3bb889dabad46fe7efd394c8342","other":"062e0ca43a1885c4a7ab2a5169790f9081e3e9a2dfa286b8cc592d5ccbf13d7a82b72d23361a19026d04fcf41b752ea320d98359d770aedfcee626e21c3494b3","up":true},{"one":"934a5fe1b91c1891ef4df7f67c027e0eb115d4c2ca4a1b76a135ebd4315c4fb835d6625223194e6a134407b38b0d3928fbc7bc924a3c6a538989a6cf200bf4bd","other":"732393b99c490c76fa45e3e404ee095f2fa445fcc123af7ac8ab1d2fdd7cf2483f5b82bb818bd8a82b1a3b73e63bcc2c83d8f24d9aad9afe36503735e7967be7","up":true},{"one":"9db1f94d74a00d1e5e2a391f1bcddf16b6d0670a2c6d91d946d38112c58634444b6fea8e8c05ab4b73bacdd62a0b575f6fb8729978edc216c7842b177b9f9cd9","other":"7865b82e44add2cea6ebcbaba9c152184331a2940fe73f6f9bb940bda8a59ab4cf4760894b9cadcaa54e36fbb712ad619346a49a85e32cdf2b53cda1ac1e0658","up":false},{"one":"7865b82e44add2cea6ebcbaba9c152184331a2940fe73f6f9bb940bda8a59ab4cf4760894b9cadcaa54e36fbb712ad619346a49a85e32cdf2b53cda1ac1e0658","other":"bd1a7c63fca9e1fcc67d7fd62670beefe2bce483cf1dc1233ee85eb90db607917cd9a5d7170b10e80b925a20e2af2c54d286b01805ac34967410859f4f03da09","up":false},{"one":"81288bb0584b7ffc1546043e052e1df10fd5371b35dedd0bb42ec5b30ce69b741b2f7857af5984d4754b39d7253575fde9298504999b78380ef602d391c4bb1d","other":"732393b99c490c76fa45e3e404ee095f2fa445fcc123af7ac8ab1d2fdd7cf2483f5b82bb818bd8a82b1a3b73e63bcc2c83d8f24d9aad9afe36503735e7967be7","up":true},{"one":"315b8a1711f680c2eaa607e35ef7a9e19c2b61721af8a7e08f1325dde1fe33cf1f47b3cc4acf12d541631041cf1b42754875fd1c9b66ee32797b72b9f7711256","other":"f915e2398aa5d4370de87504dd76c21a7d0be2581c2ab55b7a47743f1bbaef36384eaacec22760f1e914ceac9d96a10c3d66eb27475ef444e77fee979e6e88cb","up":true},{"one":"6f60ef501b41f9049419b033ae8d793a18067bdcd60347537b0dc3873bdd9a2d10d24909cca7c39781765746128c2165596f6537a94f58279523faee71f9c51d","other":"e2a27dcdee1f89fa362a85c4397840cd8be4ad8d1b9ccb23188c303bcab7619f38772f71385922d090390973b62fb8249efc103f71bc761041bcb3880ec0b935","up":false},{"one":"b080891d4ba6d3ab224984360597f9c555bd1367630f5420bfaf230419a05b2be58bebf1554e53eb4c0da81cfb66d4f7697dd65143f11841ff62d8a0d82b6b67","other":"65e954e60837bda10654480b227fa3bcc6e63356c52079002a27e836cd82ae2934ba77da60080e4b9f2d9324b982b24959bfd9624302e6c330408381054b43e9","up":false},{"one":"be514f5f17f3177235acb24112b578edf0e373c469073226e547d18080905fd062d572be18e943f13bf9fcf5871e89ceb630a1b848a0e370ef8ef8c6d997a363","other":"f915e2398aa5d4370de87504dd76c21a7d0be2581c2ab55b7a47743f1bbaef36384eaacec22760f1e914ceac9d96a10c3d66eb27475ef444e77fee979e6e88cb","up":true},{"one":"829b074b70d757da6aa00f7bace3cf1b5d2d4eeadb7f370c1a85374a01a70b54ac53d747267e386f3b41e6d790fecdd6e74b8f89745501ee82439a66ea54443a","other":"5420da16f7ed5de6b498dbc9a83b7e92e1f9900a6d04ef7351a0bfdfd442b98a5634f28fcea32ba3f3166d21c8ff5a39be70895b32acbdf7592d1d616a345a21","up":true},{"one":"2ac93c31937ca205d61cc5c2a1b9037871cac55e9b306b999b28e19566b3316f6539455e014840ea50c2db8a7c97d78804d3a2dcd7cd9c1f32ace0d36e5dd339","other":"baa5924e1547c177011285d292aa161a15e5ff282da2cd0afb83c9caffb07bdbb3662c227fa7b26e6dc8be9b8863e647eb5f8ce81640532f8f5c9a7f36557e63","up":true},{"one":"855bdf057f4a6b095e2000ada199447b5b4f2f8d78d2ecbaa0ff1fbf761788870ee999266ad3b26efa02be1a46a4d92ac0debb85a2ceab3442394ee7d99e5355","other":"083e67bb19e30d14e4df6d2483367d6659d9b56744d53d9cf7fd15954c327e1bc88a5d0db8833634e1dad7209164451f8934b59f76b5990059261abfd650519a","up":true},{"one":"df4c3505e09e1baa88470117b964e758c94f77a4546489ab5ab7f4aebfdce424729ace8867475715fb68f05c66c9674a5767549e266c4fadd1c703ddd735908f","other":"27d9048707a89f1a61e44fdae523c0128f2a7050308bd3cfefa6c3e03040a0e22f11ab41275f22b8706e6695ab93320e2af35179d772581db5f49f960750f2f7","up":true},{"one":"0b30b36e155db04c448b662c4df695068b2331cdbe2772aae5fda84159e977515a5ff2e156bc225a9281fef2383926ba8cb11e9c1846fb40db241e524ac14e29","other":"48a5e01e06e297dc1c640ac9601171495bd70fea461c60e7e6e2532695e45fcf68183c2e58b5e6931a6c1c094f5331efbd7f2d93d5f84efdec5a35afa2124438","up":true},{"one":"049a2b0ab4d49789dbbe1837e2d2ee5220a9401729ea87ab29385b24d79cdce255c3d2b5de6484d49ca6ce07bd41832598260c0a8c290e01d133d77f066f2f99","other":"460531928a4b084686343c8464b37c3452bb3566045698d08a4692864de5581a9eb1dc632329e7d3ccb73ec31ee7693787d69df8458efaba9a7105d87ee2e053","up":true},{"one":"1bc1d6155ba35d29ea16938994e08df76ebd8f16bd180bd6a9b9d8798d0745889fe72d641dd78bd8ec13526929f7eb5aaa6a388430fa69033d6db581e53c6422","other":"40bdac599b00e9c41ad6476ee415c33d9c17c5aa672692c2404e523b29dc315da929a86874bed87fd9009871805d1dbf3098e7a817193e3b08a6eee66346da79","up":true},{"one":"b2538d4edfa736bfe2cc21326a44ce62f716b3480eac93584a2233b69c98883a2bb255f246218a58cecab1d0d176e6d1fbba9782fd70d4603e01742299b9ea9c","other":"5dc69635f6d573c824ea83b18593a47f9f21a6f91ce18d2bf977c97d21f8d2a8ce88829244d12a07d949bbd52fe8a2035bc89685fe1bdd4ee20d766d75d3deee","up":true},{"one":"0cacda5560faff9d20e29a0625d3cd340ec075f198a50ab8b79338cee0e0db84c7c7e71042fd8c8f73e507b570de5d26c39473136b575f0167625a1168309ec5","other":"385168340139236a0e0f537fa693122db9fa02a377c96f31aae54718e92624fc0288164877e63616651565e055c53f7074ab2fdd18a837da6faf644941305bf0","up":true},{"one":"043fe7085e8c90c18270f84dba5fab138e50216a1cf8d81a3794d156fad7fc81d1422aff169b244b13f91d73eebb5de464f97b1b93b3ad2a58959cff19238842","other":"c332fe1f9b6e25f72c7150631ffa6e0929ff6eeab5d17aa45eaf669bdde869cf404505ae990a529aa3ca797cd0a96f31cc41431a5d4a163132be566f91623c08","up":true},{"one":"23f9bdc82efbf57d3d40a1f2617d0311678fb4a3d6a50cb7e608c649bb618124a76c7ffd17387de963e1cd28d2bd5a61c98613f6e009a8a2a90d989827b35de0","other":"80d997b87856099d844187d3d1fa40846ded652a62c1611b35919c2543915b64ff62476636488556f678e436ea26fcc40db7c6b6bbcb78f590d61c1ff0e424b5","up":true},{"one":"329145e75496cecb5f5c8f00313a52ddd8c0e8cd27ef1b2bc1b2b56e4d4089aaf5a7a3c4d9a40bdb92483fa05bd24d1cd0fd51883e30439dffa0fc855e1a7cd0","other":"22010c9829626a6892258b09cb3f3edc3f21382fb487b5dbf0dd20e198e37e26134aab850e30337f398d1491b5126839aeb1953ec144bc19aeb889c832f67c6a","up":true},{"one":"b53078000796f1cdb04dfeac424d5e3e37e30f00bd5bebf9a9ea0525c62917612b3a8f508df6bea59e3c7e4cd1aa530841f9a8af54e44f5617a13dee2c6ff007","other":"c2705ee7238ef9305e4da196653cde707649435a1e8b5b797d164e5ca06184a77af5bd7fa938c995fdfcbce724fa7eca3d908ee34891ab62cc6dfd411c3fa1da","up":true},{"one":"7554993f6efd8d9016ff525ae73c41ee2e0dbd4970c563ba9b61a99c1c8943b433c4b7d48450f6e0fbc9ac198d907698093de20e6c1f7755520fb1e1cbee4eb4","other":"7e2b0b4f3b55e97bd7241b984ad117af33bf3baacd22b3ed503a8a59f75828df745fb3ce3be4276d83eb484e64d9aa251103fa994ef119eaddb97a3503b9f292","up":true},{"one":"7e2b0b4f3b55e97bd7241b984ad117af33bf3baacd22b3ed503a8a59f75828df745fb3ce3be4276d83eb484e64d9aa251103fa994ef119eaddb97a3503b9f292","other":"0b7e1e5acabcde503ad827e45724402406114a513f81040a379b0f82df2eab4456b348b27936369c49e3c264d971c6a9e2c2217fdbc5e5b93ac6fc219957834d","up":true},{"one":"0c14dd51a56130c51009e3ce47c96b2afef26b7e86cfca65d8a9bae1abef13b3a7a192b422d894c39e24ab00be412d166a3571cc259ff4462d4ad8925a153766","other":"b53078000796f1cdb04dfeac424d5e3e37e30f00bd5bebf9a9ea0525c62917612b3a8f508df6bea59e3c7e4cd1aa530841f9a8af54e44f5617a13dee2c6ff007","up":true},{"one":"083e67bb19e30d14e4df6d2483367d6659d9b56744d53d9cf7fd15954c327e1bc88a5d0db8833634e1dad7209164451f8934b59f76b5990059261abfd650519a","other":"c2705ee7238ef9305e4da196653cde707649435a1e8b5b797d164e5ca06184a77af5bd7fa938c995fdfcbce724fa7eca3d908ee34891ab62cc6dfd411c3fa1da","up":true},{"one":"7e2b0b4f3b55e97bd7241b984ad117af33bf3baacd22b3ed503a8a59f75828df745fb3ce3be4276d83eb484e64d9aa251103fa994ef119eaddb97a3503b9f292","other":"2bfba66ec9d63e928d77d455f2e10a14d6213e515099d5db14fa44a8bfc147eb0fa7afa9aaccdc86453c6903b55556059a2e13dd61fc494127d4a3ec173bf9ea","up":true},{"one":"b4a5efa9028b2d196855393892f79993c2812d02b758f98813ddf82c5d943faf6d66eff811cc5a51936c118f4c768c0d13b54902095e040c602761e63c08655e","other":"7554993f6efd8d9016ff525ae73c41ee2e0dbd4970c563ba9b61a99c1c8943b433c4b7d48450f6e0fbc9ac198d907698093de20e6c1f7755520fb1e1cbee4eb4","up":true},{"one":"80d997b87856099d844187d3d1fa40846ded652a62c1611b35919c2543915b64ff62476636488556f678e436ea26fcc40db7c6b6bbcb78f590d61c1ff0e424b5","other":"c2705ee7238ef9305e4da196653cde707649435a1e8b5b797d164e5ca06184a77af5bd7fa938c995fdfcbce724fa7eca3d908ee34891ab62cc6dfd411c3fa1da","up":true},{"one":"b53078000796f1cdb04dfeac424d5e3e37e30f00bd5bebf9a9ea0525c62917612b3a8f508df6bea59e3c7e4cd1aa530841f9a8af54e44f5617a13dee2c6ff007","other":"e06a789a7f6988e1ba5e8358b6cd4292555c7f9f7f0dda6fc01cc26d24e49a8c1ad694423ad74aec6d80f4b99e2bedc49b6a5f2670744cedee3a3e1848e6dd07","up":true},{"one":"e67e495385e7cacfe659b40d1ba94d4b1ff55eada70a4d9740a9e452fbf221672bd0a897b940e2a6bed71e2a16867fe45bf0ea0015435ac6d815690e263b1899","other":"57fb1bb32bb2b1a87e44c6a7557e9c47c2032d107bcb0e34acd9ffd54d5d3df5701232db16f62f7549ba2721021898b03160b1dc5201e79606648c1dbc4a373b","up":true},{"one":"4fe37f2dfb03707c90a6fe91dbcfd7497db70ffc20043091d50e1cee573210c144e8749340f2c3cb70fe8fc51b317d49e8734dc51ce64b3cdccdd639ae35d1ae","other":"0b7e1e5acabcde503ad827e45724402406114a513f81040a379b0f82df2eab4456b348b27936369c49e3c264d971c6a9e2c2217fdbc5e5b93ac6fc219957834d","up":true},{"one":"a1560ce7c1f1d5972f027a8e9cff820611d84764aa067434a75b63887bc4268a259101486d34b7fe83dd735e799789986cd3e9b156c86ede598bd86af4454924","other":"5526d86ba9df651091d88460a9bedb9cedb957d452a635e1db46b9fed78082022adec0047cd7485956a4ecbb0e18107595de0de3c35242527cd302bf74a19260","up":true},{"one":"fe8ac5d33cd8ab6a1dad9567cdfb89b431a5c4f4a584fc608b92e7dfd06f70988e71e2f11f9fda9ee797c9ffba83bc085939fdf2522dde39f28202be92650566","other":"1b6cad4f9851cc584c5d1405f976bb51a52e27ef4525847df543dcca65ca5eb1ef229dcc68ccbaaf00ab1e044cb5990dd213c805bdb4adcceb6fa70b5c61fdb4","up":true},{"one":"e267e71c2dcdbe5a500b23444d2d4037ea15afba8f4f2b1c0e54a274450404fbee6fa5439f7cddf4ba1aa28fa93e434b01c239add58e30a5423ca3a481584d6b","other":"c9cd9dfb9f90a7948ac5a42c7bd63263f2eef6e1d85547559f7d2ecbf5f9cd1eab051b8e9e661b573c275d84091a44e73f6fc6bcc91dcdb674bd5d939190fc01","up":true},{"one":"b4fd11306b1416a9bcf4719578976188e104b8c5028b9abd3214d257446b97b70a22e6c00934d80caddde15e8e4d16af03bb399583047983fba373d8313226b7","other":"9ce6b9decb69d66075993e903a0727ec109a04335634616097c0e60b08f94f764634fa00891b1070f6ea1ce896bc7d11d3aea92a00f281f902d960894cef296f","up":true},{"one":"60725e8d0e9333636e598dd666f459b4be898d9abc095ee2c1db289673e7e969b50e2093956fef5a2f1d23e2040159bbabaaeab17fc6dbbac3f6acab766e9e60","other":"7808fb798d22e78fb1d39b87ddf99a503f820993bc64149eca9e81d9d58fc1adea60d8de14a4f06cb89f3190c0ef0c5e182621a14c9361ccb7e0cee667599cc3","up":true},{"one":"3612863ce0456c91785a829bf5c9d2b2fb97dda083a1847e5a4ebaa6fce1260faf4d1eb374c2225431a82774163835fb59c8cb0fa9fc0969eab5410c71109cc2","other":"2ab9513899c3c829b6284e56bf2b9862dd0156ec052b58615dba77d450dac642e534ec36ae5d3234262aff54e19f99856e908b9d8c1da660a7834a445610715b","up":true},{"one":"7b35c856916eb3fc1b1f451667e240b95aff8f4731cc0f6743740923081ff1ddf2eec81bdccf4691a7bcc053d23eacfc15809c384a73448f618317bf605bd1cd","other":"990b1db3ab1390219e8866d39fa4441bb5bb89ad786b3e255771869fcd08906dcf63f34007481769c7462edbcc665acc0a552e3733360b8d8c310c9321a5550f","up":true},{"one":"e087230634f556b818a416b66ba3f1d1dbe3e0dd0698bbb26fa86a2499acd169466f564dc18adf2f9be4d1ada0e86c11549754097601e10aff4f3a57ddffa24a","other":"292c78c8e41606e98428096bc6f4609a7aa48e5c4d17eecc64d65faae4a7270b0c15f0cd74274015688ea0a9aff34f215c29118222e362a29c8d637963973a55","up":true},{"one":"a127faa19dcb7da585983d36a8e9d3e9a44a6db68507b60c70da71011f44ce377944802f39cd65f5a705cd8249ac1ef7ed8fd699349098f3f8e23b37592c80ae","other":"b35f418c7935cc54278e90978c3ef1521ab91daeaf9f1ebc1cd25211611ade091cac4e1f009d71059279d507322a4536501980ac0dd44caddc52fd4c593879f7","up":false},{"one":"807340e5fdf6c21a56ef2fd158c32e92201206ca85fcc147165a408f7a735964afd47c397e663610ac53870ae722c0317291732b0422f8aeedae783d9c730218","other":"1090e9d89cb278a30063a5396d9ba795d3bbc237c76915a6fb7d23aa1822c8535d2fccc44cc8cd2acec68444c0bf1bdf5195ebb9f3cad8dac3d94a4d9c0e5309","up":true},{"one":"f5c1215a84a56d52f92ca0dc3a32df98c98a9c2ea2e9a34560210c16de1b440d20d043c8c25955dda8c22e55e92ddb49fd82e8b9b84072aabaa755a229bb19f4","other":"7808fb798d22e78fb1d39b87ddf99a503f820993bc64149eca9e81d9d58fc1adea60d8de14a4f06cb89f3190c0ef0c5e182621a14c9361ccb7e0cee667599cc3","up":true},{"one":"f039df8a3206e6e17eee8e95010038c450cb4cc0b5580ed5795d4c21802e1e9d360f4528bdca794f457932b1d6a818862ec847357a861c488332ef6d9480daa6","other":"5dc69635f6d573c824ea83b18593a47f9f21a6f91ce18d2bf977c97d21f8d2a8ce88829244d12a07d949bbd52fe8a2035bc89685fe1bdd4ee20d766d75d3deee","up":true},{"one":"a608a746f46d4b2e9267c65283380d6d6cb8885a64428fb77df9934bcf4dd1723587ee7c8f4a642dce266a12a6a4cf4e5c6db7fa1024158425a6753e7ab7264c","other":"2f1967b4410ea2ea8fbaf46771ba82c2846d00aecdb6f873aceae33ab38f72d0a2c2dc6046d3034f514efd090d42011d48e9ab0cb4e3caa2b49a96ef732215a1","up":true},{"one":"b137cf2291b530a39516d882200848e7f27a2710e0839b4d25b4f367bea6a0c3aaef8c7c7851c00a2945adcd819ea0508610afc1f453b8bc512b7b4d4faacdf3","other":"fe8ac5d33cd8ab6a1dad9567cdfb89b431a5c4f4a584fc608b92e7dfd06f70988e71e2f11f9fda9ee797c9ffba83bc085939fdf2522dde39f28202be92650566","up":false},{"one":"5bae82d4832092c17bd11474f7748015b8b69b896ab8f683a7c0024fc98740cecbb9e31c6275269f9000e5bfe51d7f45cd5dcd4433e0c87b5741685b40fe3983","other":"bd1a7c63fca9e1fcc67d7fd62670beefe2bce483cf1dc1233ee85eb90db607917cd9a5d7170b10e80b925a20e2af2c54d286b01805ac34967410859f4f03da09","up":true},{"one":"831cde5b651ba327b059da4c7f84b184bdd6bb99c6690ae816affe25d42c6c3dbe5b59e2b6bf23e9d0f6c485bd341ea57ba1a8220d18b0a40e156b77d84f79ef","other":"094f9d0fd3bacb17ac67a2edb8ed394fbbd1c8d478233d3269cf217e7b788e21042374936b885bf23ee4f9e03babbe4e08db283dfc2a6e052a8a5ba133717dd5","up":true},{"one":"58cfb20d3da3641e0ad529b9edbd4b590a8d1dc9d1ed7b44ed3187dba9260bd7c732fc10981f5b9bffd31d362cb05150173618aa36138984431d94a323a9b313","other":"7646d08b3e24183e3814de130235c41eb88a5a2abff23eaff3c91954ad3ef55fe27da422dac5b894312276bf1a2f1aebb8b636a8d4a0c93d9b016d441df3fa19","up":true},{"one":"adfba6d883cacbb141cd8c59ee04d7e5d520f1ce31a81e5db2d8b2380bf801c1fe4b265a66b71f9643d13a41cb1f6fb4b83399be786da4b6e171b6784bc56e49","other":"7554993f6efd8d9016ff525ae73c41ee2e0dbd4970c563ba9b61a99c1c8943b433c4b7d48450f6e0fbc9ac198d907698093de20e6c1f7755520fb1e1cbee4eb4","up":true},{"one":"0a4eec7b0e05da799aca5b36d9e2530f2a89d1426b1fcb7d8f9a662df8a8b5b763767a20db3c9c63e0bd13c2a6e16d3ba8f03baf84f5e5d24917b3f211d9bcfc","other":"9b59b76dc61223c7b37083b0ebdda22d3599563b3e3986f5db9d5b12f8c806cbdeb2345454efe957cbfa11eea9c7896aefd9a461210524805452ca100a9ea431","up":true},{"one":"9b618ad34d0dfe0fccbd5b8af365cbcdbb43e802df5f23e91c20d21f3ead6169d52bf0db7e5e111abef630c9853419fb33a88cf111d8507b8708208b5d65e35e","other":"57cd4c0048b459192ee46e19ec7df777e600f256e0dc8c3019431eb7bec3c020b9504ec7aea3dba8188658ca5b830ec40af6a8540ce10e04badc6c695d009271","up":true},{"one":"109556abac422a912ecffec0d8796f8f16e92e8f95cecf72dc89e97a8bf1fd37aad3c66aa3cf134acade6d065c31821f977171d5c5463305b57ce3eee99a7ab4","other":"ca1aff0d847c6fdacb623ad9078a0885b3208614fea20d5ff11779779b486bf5e9c794aacf848d3c2d58cfcc1eda8356df82f5fbdd0a5236beffe8e6042848c4","up":true},{"one":"e0f78c59a61f2a953553cd5742c58f4a82e38e35ac7eaa237a6ffc9fb0a3a26a2d1d1afae249e611d1320f2cb25804bdbdfb6d77336449716b0f4beb3298b8aa","other":"ba21a373781966135d6225adae024a3f3e421b852f72f8b0569cb92fcff87c33f7e5b799a509b8eff6ec6dc46a9b17d5bae1e91ec7c54c0c712d893d54b140fa","up":true},{"one":"759f46661056bcbb30c7706c9fb87e22a30feb523bd53ae5d18db043efa45b49a2b8982abebdd598fe0912a05896390ec2eabe5e160cbafc0771990708ad8c28","other":"ca1aff0d847c6fdacb623ad9078a0885b3208614fea20d5ff11779779b486bf5e9c794aacf848d3c2d58cfcc1eda8356df82f5fbdd0a5236beffe8e6042848c4","up":true},{"one":"6c143960dbe3ba4c95e8debc1fda5f420a2a673eb46f7ff7d9a30f4cd2067e67ef8926bf17f0c99b16c79b6dc066b52409a11d47117d4fda4211636b1b74f96c","other":"70ee3c7e02a123f78345d41c386e413f06b51f1ab346c2c472891eed7dd26a1f14e213a0f4f2d872859b9b535936a6d9b072d2604456f76221a422710411822f","up":true},{"one":"be026dfb24847cac2d00f483104edad06ca8ecb9e1229c479ef5650c7b427cd5dc34a1cf06172c17c9d0406ce17009712e82446394743d4cd9bbc41c537ebc14","other":"759f46661056bcbb30c7706c9fb87e22a30feb523bd53ae5d18db043efa45b49a2b8982abebdd598fe0912a05896390ec2eabe5e160cbafc0771990708ad8c28","up":true},{"one":"032b9bf2f59f15571821611d3ee541aa748c86d47fbe5f049fd0069be53e5d7c41991d82957e9c727654c3aa73ec94997c03d8a6c1d2007c9bb1a703f6215158","other":"759f46661056bcbb30c7706c9fb87e22a30feb523bd53ae5d18db043efa45b49a2b8982abebdd598fe0912a05896390ec2eabe5e160cbafc0771990708ad8c28","up":true},{"one":"ed6c793eb4565aa9d883a76fad6c97ad0b878b9ef0235e11e89db1af25a9653205f725c6ea258b84bde134f1a6437c6d109b859d17509e5016c4ab98be59032a","other":"1f6d803a4ca186463772850ca0901fb920af7e74fdd2480c3c368fa707838ee91bbcfb57d5e3510c802b9b85f2d954f04c9b675414274bdaebae6488dcf94c10","up":true},{"one":"4e95fb8943ef6502fa470870a7ace4ca11e18589bd2073167543a922317b35e40b5068934d07e56c8fdd23354dfad51fd2899db854f189841f02b5914cd97749","other":"b26f7c0113a5ae885f7c0e608aea7022a9c8bfc40c5643e60b2ba7343ff09c5be0bc08be34dde3c6b85fea192a46d4764770c12cbaa233df4231a1b99627ef9d","up":true},{"one":"84dfd4e4d9f1204893f190eacc4c3999e175c433f70de86e335d27477c097a0552f211a21764f01a708da4c9e9e6552191a61d3e48f41d0e84f01e7ae3beb34e","other":"9b618ad34d0dfe0fccbd5b8af365cbcdbb43e802df5f23e91c20d21f3ead6169d52bf0db7e5e111abef630c9853419fb33a88cf111d8507b8708208b5d65e35e","up":true},{"one":"3b570117addeec03c2694baf28e246f91907268fe665c6c90356120332794258ee57a60853c19e9fe25d042ca42a5be7fe0797d84199174de8132f1ef4a9349b","other":"54b3c57a4adf4dbaf31b85ed1b8dccd6249faa16dd96dd230189f47f57970caeed36627cc8e1b0794707418d580f5bd6001c07be6a79216695f1253db24926bb","up":true},{"one":"d9bbcdfd949010e6b2cbf6d0f34b27593ae410bdc1838876aeca35679571fe431d040a5ab085c0a77f111688bebed891da3587277cd794702437cb20d6aa4256","other":"9b59b76dc61223c7b37083b0ebdda22d3599563b3e3986f5db9d5b12f8c806cbdeb2345454efe957cbfa11eea9c7896aefd9a461210524805452ca100a9ea431","up":true},{"one":"59b53f8a562bee519276e0eeccfcf8c975d3102f5d0cccf5abcce291a8a5bb817c04604f123686177a50a03b9d7559ac469962d0159d1d93e4ce58a304d04b55","other":"66d0c5da973d9dd65350ae1ec63776872cdb7ded6afb6f51ae82259f6fd35e884375d15de290625f02ed2e5cdc3f591decb45e5fc64d5b0f835a216fd196f5a3","up":true},{"one":"84abcbc7b5598ecfd91ceace0927921a5a3404fdb274fc2a2549abbede5f8e4f62c15688a4dc9a2d80262c45970c88898da245c6eb779f327a81d53a17bbc74c","other":"2ac93c31937ca205d61cc5c2a1b9037871cac55e9b306b999b28e19566b3316f6539455e014840ea50c2db8a7c97d78804d3a2dcd7cd9c1f32ace0d36e5dd339","up":true},{"one":"df54af3bae257d437c5657905484e0d72e9560c46f8ba6b3437730234e05259b404cca40b0831e911605ff8a68a19e8fd7e958069ec8b40595928892f4fa220c","other":"7acddc7fb6ac587b7e343804c768e4291cd28dd2b2b9207dea6ee82360d848a52d84f94e4c49e9c421f4f90e2d24f6291e2358783ab0230e6ecde82e69b4ac52","up":true},{"one":"e2e0419a41bdfc5bd76deae2ddce6ac865f886d764c9bd18799b79fa3b2b6ba66d765d26da2037e98317e1d7e8232a61e63c1d0cfa98c9137424151b46e07171","other":"d9bbcdfd949010e6b2cbf6d0f34b27593ae410bdc1838876aeca35679571fe431d040a5ab085c0a77f111688bebed891da3587277cd794702437cb20d6aa4256","up":true},{"one":"016f8f4619a16a07fbde5a18e362158d696e4d9f104a77787f26e32a25cd7d278256f8e0db865c488a99511ec27a5eddd5ebbd1c1397fa7f8db111062e5fe959","other":"9b59b76dc61223c7b37083b0ebdda22d3599563b3e3986f5db9d5b12f8c806cbdeb2345454efe957cbfa11eea9c7896aefd9a461210524805452ca100a9ea431","up":true},{"one":"9bbbfac8be4a000f51a4ce8d024d2595b5d491afec0138922dddfde5ef62c664040c2e9304cc6b7bc688233b5d0c4644b8c8793227c078285a3ab894ef0497a3","other":"d9bbcdfd949010e6b2cbf6d0f34b27593ae410bdc1838876aeca35679571fe431d040a5ab085c0a77f111688bebed891da3587277cd794702437cb20d6aa4256","up":true},{"one":"2bfba66ec9d63e928d77d455f2e10a14d6213e515099d5db14fa44a8bfc147eb0fa7afa9aaccdc86453c6903b55556059a2e13dd61fc494127d4a3ec173bf9ea","other":"5566111b7f14d8ec83ba6456488f3fc5c7e2c86bf406dead33b814e1ee9b569d34015a4d88226b7e28fff7784395c086d106287cbbc80acfe75b05cd6e12903d","up":true},{"one":"abd8f5a4d700c06ec00684b23d2d25c4df1a9554fcfc57b0ddc3fa476e6a699ba75e1213449f900803f83ab8194c6746664b547202047f35b8b3e216c7147bf8","other":"d7a319f69013b8375e64d19f015547462c84565b882337998f9e669c5fadd3d2ecf6374109903003e09f5d453424b5c7fdf52163d2cc8084cf81f94844946b63","up":true},{"one":"4ee37acec2178ef120166265aaa2b64b09b315fb53861405ef46f2503c273eb9692e9cb4c2e67a8652254d430fd6e02dd3fe4cded20bb231a9fb834d292b0b24","other":"7acddc7fb6ac587b7e343804c768e4291cd28dd2b2b9207dea6ee82360d848a52d84f94e4c49e9c421f4f90e2d24f6291e2358783ab0230e6ecde82e69b4ac52","up":true},{"one":"9133b0b3c8f680286eae90c3beebc3099a13de38775a3ff2abdeced62d05eb2ced5ac85eac0870156be03101024da5e1d9fbf3e1066ddb3f088221e64149acec","other":"eab86c521f8f1ac67c015ab713f1236a08b0200757a96bf87ab8301e7967ae62361f0e14da14ca294fc8cb3b4726b52f4773101e21b032977c6a647241b59c73","up":true},{"one":"6ab6ec15635b2fda22542c99df0a3313ad4583ba0fb3f31b8f314e3ecad446d3fb0fdfcd2be9b08374b1a7e049fb68e69e8dacdd13f1df5007a656f6b11adc5b","other":"94088fe273f76e62ca4e43c095ad12215b4ae4c59942328b3985416fb19bbda0cacc143a49eff3fb644ad53a19d3f043260e43dbb70a0aa9c15829c21cecd3c7","up":true},{"one":"cb94a8270d0050378116b5815ff17dafbe20f5303839c4fd57b981d4687a4b145e4bccec7e9af9b9475005930148ffbfa97781a0762c8e9f352dc95565fc8732","other":"a78f18691e0dbf3c08fe9d7dec188e6a05a93833432fb99eb2b3924ab0bde7a44db2a102a65544bbdc4fb61bc3a3d569230d9843a335bf619167fb045d78ab3c","up":true},{"one":"70ee3c7e02a123f78345d41c386e413f06b51f1ab346c2c472891eed7dd26a1f14e213a0f4f2d872859b9b535936a6d9b072d2604456f76221a422710411822f","other":"ed6c793eb4565aa9d883a76fad6c97ad0b878b9ef0235e11e89db1af25a9653205f725c6ea258b84bde134f1a6437c6d109b859d17509e5016c4ab98be59032a","up":true},{"one":"920a301186bdf665a721676ece7c180413369ea6eff7537f42049d9eb409f28cc864099590116e885f57368959fb2cff7003697d9b1515e68bf3fa7aee0278ef","other":"fd4968df03d767a223bf7e4dbe26b5c27048298df40e81cad50b344fb3e6837965f2646dab7ffb2891a5c507343ed84bb8bbe403287b51dae538d58fcb6e7623","up":true},{"one":"ba21a373781966135d6225adae024a3f3e421b852f72f8b0569cb92fcff87c33f7e5b799a509b8eff6ec6dc46a9b17d5bae1e91ec7c54c0c712d893d54b140fa","other":"920a301186bdf665a721676ece7c180413369ea6eff7537f42049d9eb409f28cc864099590116e885f57368959fb2cff7003697d9b1515e68bf3fa7aee0278ef","up":true},{"one":"2a63d875e715c2a43302d32d86d30c7d7faed46c08a67bf488762637216b99dd87333a66df6d9f3a57df863b1f1a219ddbeebb9f3e92e523bd08540a195448ca","other":"c332fe1f9b6e25f72c7150631ffa6e0929ff6eeab5d17aa45eaf669bdde869cf404505ae990a529aa3ca797cd0a96f31cc41431a5d4a163132be566f91623c08","up":true},{"one":"89a5b92a9ca045f12c35a70084e6f41f9775a25d6f105f8c9349c7b5e107179d8a96bdbb113b2680edf5183e9a42fd64bd7b29d0dc7797c583b833f869313699","other":"fd4968df03d767a223bf7e4dbe26b5c27048298df40e81cad50b344fb3e6837965f2646dab7ffb2891a5c507343ed84bb8bbe403287b51dae538d58fcb6e7623","up":true},{"one":"a7378ee34876af17c6cd94a69b6b741ec7891ff5375bc4241d48608d047455ed48e6baae80ee88d4710c69ae615cf195cee26c94b54de1bb935628ce1e3a723a","other":"a1560ce7c1f1d5972f027a8e9cff820611d84764aa067434a75b63887bc4268a259101486d34b7fe83dd735e799789986cd3e9b156c86ede598bd86af4454924","up":true},{"one":"617595a230e0a74a3db3b47cd27b941e02bdee9a84cdfa8eaa63a55941eb5caa79e20fb69726a4d46a0e5aeed24039f8c5a20679a692df0bc140f42558ca9a2b","other":"48a5e01e06e297dc1c640ac9601171495bd70fea461c60e7e6e2532695e45fcf68183c2e58b5e6931a6c1c094f5331efbd7f2d93d5f84efdec5a35afa2124438","up":true},{"one":"3e488a7208ce0e097ce47fc6651a13e95cae137d1a054a09b04d2f59d45faa2594a8c3b395e77ad1a3c2edcd827dda73c0c97dbaa6d9519a79184a0aca01ac4b","other":"e06a789a7f6988e1ba5e8358b6cd4292555c7f9f7f0dda6fc01cc26d24e49a8c1ad694423ad74aec6d80f4b99e2bedc49b6a5f2670744cedee3a3e1848e6dd07","up":true},{"one":"0f9f7e2dce4ca266c3ac0ec3a8854200b54487f5308e3db418461aeb5f67c81d332619b6441b468e480941e63100ed1b263e7adc20689dc3dcda578bfca538fa","other":"e06a789a7f6988e1ba5e8358b6cd4292555c7f9f7f0dda6fc01cc26d24e49a8c1ad694423ad74aec6d80f4b99e2bedc49b6a5f2670744cedee3a3e1848e6dd07","up":true},{"one":"ff1e34fd51953ed641b431aa657da21cb4c81d23e4eaa13c9cce526f1f1b34593d41f9b87a0e10387fe400c623638677c0efab15dbd1014a0ccc11f9ec92c417","other":"2245f3bf1a3b4e92f912affc75f757cf648b20474c11ffe947884f216b8f24f9dcb6e6a0358a4061b8517478ec15027e185b2f05a777573b4940375bf4aaf2be","up":true},{"one":"07f25fdeab2b44b2e92fc80fca7de9e4a8547d27a98a54593b3395c270a9ff3f2a5da62a2e8531ce86359f0cdc5b6513b773dfd64cce1b83e47065d9760a2c7e","other":"e06a789a7f6988e1ba5e8358b6cd4292555c7f9f7f0dda6fc01cc26d24e49a8c1ad694423ad74aec6d80f4b99e2bedc49b6a5f2670744cedee3a3e1848e6dd07","up":true},{"one":"7aaf7817b93aa6d2f50513791f9ad7629a901ed0dcb151189f44763f83423446b20ec79a48fa260cd9bc2907d5f0ad06b2c4c5e6d812f3d8876c8020ebe41019","other":"4314b0b04331973ed29a58843951f144ac3d09bd5d57b6cd9aaff9b73a7b2ec81e344a3e4ece462bd2081b837a06310e787ef3bb889dabad46fe7efd394c8342","up":true},{"one":"e3c8a97a2d95dd543f9e2b41d9dce6256e284296f866f4f92e9925f8c7519dea23fd6d1a11153b93c10d6a32295e7b9bcc16024e690e4a0dc84fd25ee0f31b2c","other":"4314b0b04331973ed29a58843951f144ac3d09bd5d57b6cd9aaff9b73a7b2ec81e344a3e4ece462bd2081b837a06310e787ef3bb889dabad46fe7efd394c8342","up":true},{"one":"e06a789a7f6988e1ba5e8358b6cd4292555c7f9f7f0dda6fc01cc26d24e49a8c1ad694423ad74aec6d80f4b99e2bedc49b6a5f2670744cedee3a3e1848e6dd07","other":"062e0ca43a1885c4a7ab2a5169790f9081e3e9a2dfa286b8cc592d5ccbf13d7a82b72d23361a19026d04fcf41b752ea320d98359d770aedfcee626e21c3494b3","up":true},{"one":"4e68553db7be307b8379e8bec383b5c92e4b23debcefca575d24504e2062618f74c26e60e0d9e47f096997a7f841e2c32c994124f495ef3352ef964b33fd3a51","other":"db8ba71afeaea1f2964e8978a6eceeb9efa3958424424022213c8193443f8d5afd18490afa954c76360c681404809c7cfaf7e4ebd8bd1a42d403f7f1915b0d29","up":true},{"one":"ce0a09bb6fe4c9c93c3dbd800ca9c9ac0714f26a8f8dac2149b6ce7a9011912a5621ea2e45de35c4d31dfe5add00558fdba5dd21acf2d81ba391e82b5b3a5804","other":"65e954e60837bda10654480b227fa3bcc6e63356c52079002a27e836cd82ae2934ba77da60080e4b9f2d9324b982b24959bfd9624302e6c330408381054b43e9","up":true},{"one":"b3316f4fd7dec218a52331f25d17a2faf0f2a417808d7dbb80038154abfbcd2d78da074837b648cff28675f4aa0d65ddb7d15abf3d7e0391d401e313a3ef24a2","other":"7808fb798d22e78fb1d39b87ddf99a503f820993bc64149eca9e81d9d58fc1adea60d8de14a4f06cb89f3190c0ef0c5e182621a14c9361ccb7e0cee667599cc3","up":true},{"one":"155e4879643a472420012e040a87dbff776fc1976814c0c6cd0d5e157f0d0baac04aa7f2535786c09acc2700547383d2119b64a6f62115f1aff1708738844d8c","other":"732393b99c490c76fa45e3e404ee095f2fa445fcc123af7ac8ab1d2fdd7cf2483f5b82bb818bd8a82b1a3b73e63bcc2c83d8f24d9aad9afe36503735e7967be7","up":true},{"one":"4de378164d77a28c90cf162dd1b465e0282ee17aa7d3bb3179252466f72da33a36c9f298f7c9498e38dba4018e7ce3e5fe631c83842cd9059e23a7fece366d87","other":"9db1f94d74a00d1e5e2a391f1bcddf16b6d0670a2c6d91d946d38112c58634444b6fea8e8c05ab4b73bacdd62a0b575f6fb8729978edc216c7842b177b9f9cd9","up":true},{"one":"c332fe1f9b6e25f72c7150631ffa6e0929ff6eeab5d17aa45eaf669bdde869cf404505ae990a529aa3ca797cd0a96f31cc41431a5d4a163132be566f91623c08","other":"2bfba66ec9d63e928d77d455f2e10a14d6213e515099d5db14fa44a8bfc147eb0fa7afa9aaccdc86453c6903b55556059a2e13dd61fc494127d4a3ec173bf9ea","up":true},{"one":"aacff366e601e072a2113add9020e19b6612f3e85b6e607fdc8cc1b6991f43be0b1f835ed3dc41d1f2b3e0caf7fac252c8eb4c150667d48207fa92ea5f0a7455","other":"57fb1bb32bb2b1a87e44c6a7557e9c47c2032d107bcb0e34acd9ffd54d5d3df5701232db16f62f7549ba2721021898b03160b1dc5201e79606648c1dbc4a373b","up":true},{"one":"f54335964d9b4eb9813eb05f40ef1c523bbf0faac5a04c4737467d590fb6b55c7fa1fc5d4d32c5491d8766b9be6fdfd3ebdb25c5ffe1719f36c86ddf87ae3a85","other":"fe62314839c93d2f6e3aee984d5f0b321897c6f39e66800d3de8b773baf6f19e0a03cae025df512aea8d5f1b667b6dbb15c192a90a76d3031c14e33e5c16c4f7","up":true},{"one":"aa9a94d6e4eaaed20113c21752c224e3a052abd3769bd6e832759dbaf5154a943cf094eacdcb0727c2fe51a11bd7fc0793d7d5e3312b0aba89d428a00e1fde0c","other":"caaf695c76cf7c047d3f3bfe019d01618e4871cee8ff3f347913da815bbcde145771486f916a44d03f59ea9bc217f169fd0c0765fda3f9b9b28d02a522e180b4","up":true},{"one":"fde7705f5013c3b6b76a35505c1e3d57c033a337f2a71e912ec3a3d2da8e113bd7c36d94908357e9f7654660621f647ad8c66b0126dfe91dbfa3b8c7bd2183d3","other":"2f1967b4410ea2ea8fbaf46771ba82c2846d00aecdb6f873aceae33ab38f72d0a2c2dc6046d3034f514efd090d42011d48e9ab0cb4e3caa2b49a96ef732215a1","up":true},{"one":"2b70e5ffcc0bb1c4f8acc09dd1016e67c9c96c92d091ad481efbb71bd8b2a5a5869c6d668617a9b2cbfe91baf5edfe150c3824c84d90899a974099071d171441","other":"60725e8d0e9333636e598dd666f459b4be898d9abc095ee2c1db289673e7e969b50e2093956fef5a2f1d23e2040159bbabaaeab17fc6dbbac3f6acab766e9e60","up":true},{"one":"f915e2398aa5d4370de87504dd76c21a7d0be2581c2ab55b7a47743f1bbaef36384eaacec22760f1e914ceac9d96a10c3d66eb27475ef444e77fee979e6e88cb","other":"ddaf3f8478501cda872c056c72063eb64d5b871fc5fff70704872802289dd2d348f73bc342b7f148a90cfaae2448ebf16fea196be9df891dc71a57fb410d59dd","up":true},{"one":"d3105ede6c21bc643d523afcd1309a5dcf03f70797a92f167c3a19f86ae98882fe1a9d4094d7a3dee4a0833b8075b6c3e9aaa7f4879dc47bb388c3ae85522288","other":"72e30d4562673c5c8fb03709d93f73322747858d723b7eb5ef2fbb88e0331252946b7e93ffe434fcb599c4fff57800afb29e6c60a719f18f49dba541c3591c6e","up":true},{"one":"cd8815d66aee8bd488d4e5e25f0cc9c71cc65349f701ea26b1d6cd9c039d16fcb473dbf270a3b33187720ccf4b0ce4f78a6d6edd05f4fe804772d5b6ec45bbd3","other":"f915e2398aa5d4370de87504dd76c21a7d0be2581c2ab55b7a47743f1bbaef36384eaacec22760f1e914ceac9d96a10c3d66eb27475ef444e77fee979e6e88cb","up":true},{"one":"b080891d4ba6d3ab224984360597f9c555bd1367630f5420bfaf230419a05b2be58bebf1554e53eb4c0da81cfb66d4f7697dd65143f11841ff62d8a0d82b6b67","other":"315b8a1711f680c2eaa607e35ef7a9e19c2b61721af8a7e08f1325dde1fe33cf1f47b3cc4acf12d541631041cf1b42754875fd1c9b66ee32797b72b9f7711256","up":false},{"one":"40bdac599b00e9c41ad6476ee415c33d9c17c5aa672692c2404e523b29dc315da929a86874bed87fd9009871805d1dbf3098e7a817193e3b08a6eee66346da79","other":"807340e5fdf6c21a56ef2fd158c32e92201206ca85fcc147165a408f7a735964afd47c397e663610ac53870ae722c0317291732b0422f8aeedae783d9c730218","up":true},{"one":"68cc8b9a995eef6170abf88bd5fedca06ffcc8d75f247f6041c13e7dfd292727ebda1ff86b776e33b6634355c55e0f8c22fcdb5f9a6e2f22fe1af7854c3b4273","other":"27d9048707a89f1a61e44fdae523c0128f2a7050308bd3cfefa6c3e03040a0e22f11ab41275f22b8706e6695ab93320e2af35179d772581db5f49f960750f2f7","up":true},{"one":"57fb1bb32bb2b1a87e44c6a7557e9c47c2032d107bcb0e34acd9ffd54d5d3df5701232db16f62f7549ba2721021898b03160b1dc5201e79606648c1dbc4a373b","other":"d4b7c787981abec24353c7d496661692233797e3758189bf909a69fe87935bf6da0940daa4f12e81f20c5e88f70b472113688b71a0ae2f91a73ee0e6ff4c8591","up":true},{"one":"e023a51c5bd26e1754d6461345143e94baeac799947579ec7adeccd105de39f85afbceeb5037cfc0b820b9f4446433f034d9e7de7326d45df5a967a8099dbb10","other":"27d9048707a89f1a61e44fdae523c0128f2a7050308bd3cfefa6c3e03040a0e22f11ab41275f22b8706e6695ab93320e2af35179d772581db5f49f960750f2f7","up":true},{"one":"76cbf9fc0f3517fb615fa96104780218e85d064ee5a1d518f3b78f4dbebf144df38c427445fdd6c9b436489c00ff9497d747a8fd70f380f95601d59e52e021e8","other":"68cc8b9a995eef6170abf88bd5fedca06ffcc8d75f247f6041c13e7dfd292727ebda1ff86b776e33b6634355c55e0f8c22fcdb5f9a6e2f22fe1af7854c3b4273","up":true},{"one":"2f360209383d6de4ebd3b4abaf77796520b8654270b03f2151eac4a01b4417d7e0668c1f9ad30c20ff49aa8a0ab33dba5e6095619d1cf04b7af841722ab773da","other":"1b6cad4f9851cc584c5d1405f976bb51a52e27ef4525847df543dcca65ca5eb1ef229dcc68ccbaaf00ab1e044cb5990dd213c805bdb4adcceb6fa70b5c61fdb4","up":true},{"one":"5420da16f7ed5de6b498dbc9a83b7e92e1f9900a6d04ef7351a0bfdfd442b98a5634f28fcea32ba3f3166d21c8ff5a39be70895b32acbdf7592d1d616a345a21","other":"807340e5fdf6c21a56ef2fd158c32e92201206ca85fcc147165a408f7a735964afd47c397e663610ac53870ae722c0317291732b0422f8aeedae783d9c730218","up":true},{"one":"829b074b70d757da6aa00f7bace3cf1b5d2d4eeadb7f370c1a85374a01a70b54ac53d747267e386f3b41e6d790fecdd6e74b8f89745501ee82439a66ea54443a","other":"f54335964d9b4eb9813eb05f40ef1c523bbf0faac5a04c4737467d590fb6b55c7fa1fc5d4d32c5491d8766b9be6fdfd3ebdb25c5ffe1719f36c86ddf87ae3a85","up":true},{"one":"caaf695c76cf7c047d3f3bfe019d01618e4871cee8ff3f347913da815bbcde145771486f916a44d03f59ea9bc217f169fd0c0765fda3f9b9b28d02a522e180b4","other":"65e954e60837bda10654480b227fa3bcc6e63356c52079002a27e836cd82ae2934ba77da60080e4b9f2d9324b982b24959bfd9624302e6c330408381054b43e9","up":false},{"one":"eab86c521f8f1ac67c015ab713f1236a08b0200757a96bf87ab8301e7967ae62361f0e14da14ca294fc8cb3b4726b52f4773101e21b032977c6a647241b59c73","other":"1d0244a13affe60996fe3cf51ba624adc746de0c7ea68ec5a31311a36077c5b5495e3d95c9642875db44c7ecae6ffed22e45f2e2d024d486760be2af9f4cf2cd","up":true},{"one":"ff6f94005d1df7677600069764855c1c2aa0543cbe9f480f8feefec76c49d9e2c7bb2d8e38c89e9430f53f8b593d93f143c45985a56a5a32c736128214c95eda","other":"cd8815d66aee8bd488d4e5e25f0cc9c71cc65349f701ea26b1d6cd9c039d16fcb473dbf270a3b33187720ccf4b0ce4f78a6d6edd05f4fe804772d5b6ec45bbd3","up":true},{"one":"c8b0dba45104fc7c7dff3ce078a0d3f5ade6198bb4656e2bee8076387929133e5ef2bd293b130a9d4f6a6974ca17e8b4a8f406d1219880f1e0f99c65c63af5a4","other":"57fb1bb32bb2b1a87e44c6a7557e9c47c2032d107bcb0e34acd9ffd54d5d3df5701232db16f62f7549ba2721021898b03160b1dc5201e79606648c1dbc4a373b","up":true},{"one":"8f88c7ec044f758f29bd8d12a5170bd973aec8f6cddbf512b910c4b75a0fec09c5e198bcd65622037f897759db68da2328b4a7ca93585dc9cb62e46d2a6c0864","other":"7aaf7817b93aa6d2f50513791f9ad7629a901ed0dcb151189f44763f83423446b20ec79a48fa260cd9bc2907d5f0ad06b2c4c5e6d812f3d8876c8020ebe41019","up":true},{"one":"7808fb798d22e78fb1d39b87ddf99a503f820993bc64149eca9e81d9d58fc1adea60d8de14a4f06cb89f3190c0ef0c5e182621a14c9361ccb7e0cee667599cc3","other":"b2538d4edfa736bfe2cc21326a44ce62f716b3480eac93584a2233b69c98883a2bb255f246218a58cecab1d0d176e6d1fbba9782fd70d4603e01742299b9ea9c","up":true},{"one":"1b063741c76fe65e62b4eae42751319d0cce66f22dde9f1cf83d6cca249a0e65bc7f6f22597697362fadd226222fb3847f8e146961969d1b4c9f7e475389cd8e","other":"352407b42726dcd1aacc46a912ed8124b8b6a3da4e33dab742e40aa2452953d35dc8f42eddc76695ae2317e9f15dde2cd21be4ce826934695ad1847455661d1b","up":true},{"one":"4b784f072b7c96c30612767425f552e30e45157e70139dfbe0ae4ff86dc31601adec60f8a3ad9747b02b5219073d8813af9b09d59eaf7ddb7ee24856aff6fa8f","other":"0deda014fa3c0bc8f37d853e1448f95f56f97048c28797d72258fd3ba2f1f776ae11566197466596356cd172847ab02a89f4cf047e58383249fb2a4cd69b6206","up":true},{"one":"88d5c5fe61ee1e6fa5878e0eaa13bdabaa0ec3d38a5d25b95a467da7627424f25fb5d30535aa0a5ad01c16fe2598dbf570b78cc152a7f4ef66d46fc9ae43592f","other":"c2705ee7238ef9305e4da196653cde707649435a1e8b5b797d164e5ca06184a77af5bd7fa938c995fdfcbce724fa7eca3d908ee34891ab62cc6dfd411c3fa1da","up":true},{"one":"66d0c5da973d9dd65350ae1ec63776872cdb7ded6afb6f51ae82259f6fd35e884375d15de290625f02ed2e5cdc3f591decb45e5fc64d5b0f835a216fd196f5a3","other":"1b6cad4f9851cc584c5d1405f976bb51a52e27ef4525847df543dcca65ca5eb1ef229dcc68ccbaaf00ab1e044cb5990dd213c805bdb4adcceb6fa70b5c61fdb4","up":true},{"one":"f33d1f3e460574706ac1c7fc9ebb4683b173496ce3e80017d1c3521bca03d5a41a9c7a6cde8347d2238917b7cc58cab000ce7ccf6bb408561015a2ecbe613408","other":"0c14dd51a56130c51009e3ce47c96b2afef26b7e86cfca65d8a9bae1abef13b3a7a192b422d894c39e24ab00be412d166a3571cc259ff4462d4ad8925a153766","up":true},{"one":"329145e75496cecb5f5c8f00313a52ddd8c0e8cd27ef1b2bc1b2b56e4d4089aaf5a7a3c4d9a40bdb92483fa05bd24d1cd0fd51883e30439dffa0fc855e1a7cd0","other":"4b784f072b7c96c30612767425f552e30e45157e70139dfbe0ae4ff86dc31601adec60f8a3ad9747b02b5219073d8813af9b09d59eaf7ddb7ee24856aff6fa8f","up":true},{"one":"0deda014fa3c0bc8f37d853e1448f95f56f97048c28797d72258fd3ba2f1f776ae11566197466596356cd172847ab02a89f4cf047e58383249fb2a4cd69b6206","other":"2bfba66ec9d63e928d77d455f2e10a14d6213e515099d5db14fa44a8bfc147eb0fa7afa9aaccdc86453c6903b55556059a2e13dd61fc494127d4a3ec173bf9ea","up":true},{"one":"7174eca109a1f717653918224c8cfe1b7fbd666405196760913593401eb79f2c7e41003b01f5a458940695b27a4673443c7621a169db7fd968994e552995dbbb","other":"66d0c5da973d9dd65350ae1ec63776872cdb7ded6afb6f51ae82259f6fd35e884375d15de290625f02ed2e5cdc3f591decb45e5fc64d5b0f835a216fd196f5a3","up":true},{"one":"b870935867183bbfb84add16b9f56c02c834b7042fc24ce6bcb2a7f174e6d2239357a00be4272c1ef05c7f9baf5a9f16b53bc18328a9b7aca8540c2916805b57","other":"2ab9513899c3c829b6284e56bf2b9862dd0156ec052b58615dba77d450dac642e534ec36ae5d3234262aff54e19f99856e908b9d8c1da660a7834a445610715b","up":true},{"one":"a1560ce7c1f1d5972f027a8e9cff820611d84764aa067434a75b63887bc4268a259101486d34b7fe83dd735e799789986cd3e9b156c86ede598bd86af4454924","other":"b53078000796f1cdb04dfeac424d5e3e37e30f00bd5bebf9a9ea0525c62917612b3a8f508df6bea59e3c7e4cd1aa530841f9a8af54e44f5617a13dee2c6ff007","up":true},{"one":"acb4088c27ee2ee130ece3506596432afdb9e9757ec11ebdd35c5a6e87239545c48466913a646980104c8fd7a9a335e177f04efffe9dc952dfd7cd5c1bb9aac6","other":"9ce6b9decb69d66075993e903a0727ec109a04335634616097c0e60b08f94f764634fa00891b1070f6ea1ce896bc7d11d3aea92a00f281f902d960894cef296f","up":true},{"one":"22010c9829626a6892258b09cb3f3edc3f21382fb487b5dbf0dd20e198e37e26134aab850e30337f398d1491b5126839aeb1953ec144bc19aeb889c832f67c6a","other":"c332fe1f9b6e25f72c7150631ffa6e0929ff6eeab5d17aa45eaf669bdde869cf404505ae990a529aa3ca797cd0a96f31cc41431a5d4a163132be566f91623c08","up":true},{"one":"62dab8b21640e1b44dea452dd7e7de93f27a44840da72d56b11aa96e8463f3a4bb15e75a954d19fc897ae0030b16181d271b79d8198b7cffcddaa9ffcfdcce73","other":"db8ba71afeaea1f2964e8978a6eceeb9efa3958424424022213c8193443f8d5afd18490afa954c76360c681404809c7cfaf7e4ebd8bd1a42d403f7f1915b0d29","up":true},{"one":"535f93057d46c4aae0902546550880be0b5ba67dca12350117d471d67f4f2b3f7bdff29bdc918767974c465df8fa1afa6bd6c29c0a36d51f71c4183673d906f3","other":"1944f98d4db32c56a5efda5a79aa5f276bfab1e084d6611fec0e735b8bc0f45b457cdb74a23fc83b2377821fa8316123c9877acd6db7c41058ca5d3cfedaecf9","up":true},{"one":"420b9c90584651c5a3fe3c16aa377444a321dca934f8a097d01a616554067feabebf2fdc8d2a25797f29a8fef30d5e2c82f8e85b20f509a880367b9b0ccdea47","other":"062e0ca43a1885c4a7ab2a5169790f9081e3e9a2dfa286b8cc592d5ccbf13d7a82b72d23361a19026d04fcf41b752ea320d98359d770aedfcee626e21c3494b3","up":true},{"one":"ae2a996d3b562cb47a564934037949da83b1bfe194c23754f3dbe2372ec27654f4f3b6cb7f394570f308025589c065870477667e5560dbe5a8ea1625740699cf","other":"be514f5f17f3177235acb24112b578edf0e373c469073226e547d18080905fd062d572be18e943f13bf9fcf5871e89ceb630a1b848a0e370ef8ef8c6d997a363","up":true},{"one":"62666b24d1026345349edb6a878cdc27d6fee8254e83f79a298ce2805260d97aa46423deae440f86ced5cd99b30e970c8e1ea1046752b17d8c80dc68d9a49b60","other":"2ab9513899c3c829b6284e56bf2b9862dd0156ec052b58615dba77d450dac642e534ec36ae5d3234262aff54e19f99856e908b9d8c1da660a7834a445610715b","up":true},{"one":"66beee3968dbcf3addc6feaf070a4e3e82b5bb164fb72f40add89f732c12e8d0a31a7ee1f1e24a4674e4dfc9a4912b02c17ce3c224d257d78b7156544d6507dc","other":"b870935867183bbfb84add16b9f56c02c834b7042fc24ce6bcb2a7f174e6d2239357a00be4272c1ef05c7f9baf5a9f16b53bc18328a9b7aca8540c2916805b57","up":true},{"one":"eaca77d20c4ad6b87649eba21b750a4b1a2c575e06bc42679d18fce16fea15212e9a7408c16f3b24d8dfd1e397314637e72e292845d09534a39035bd9203ee9e","other":"453779010ed7c59761da47ccd8869d3fa8349795e57edb9eea416c0712301ea622c7683858e309d19ab137ddb0edef161d0d00a361abeecf0628c3ffabc629ea","up":true},{"one":"2f1967b4410ea2ea8fbaf46771ba82c2846d00aecdb6f873aceae33ab38f72d0a2c2dc6046d3034f514efd090d42011d48e9ab0cb4e3caa2b49a96ef732215a1","other":"3dfd733dde9414af916625ab981777ff1ad7ca0f6d1e4e7d9e2739969e21182fd13d85e281868653e7325b20069356b11524b54143c47fd3955a911cf7325ad4","up":true},{"one":"292c78c8e41606e98428096bc6f4609a7aa48e5c4d17eecc64d65faae4a7270b0c15f0cd74274015688ea0a9aff34f215c29118222e362a29c8d637963973a55","other":"bd1a7c63fca9e1fcc67d7fd62670beefe2bce483cf1dc1233ee85eb90db607917cd9a5d7170b10e80b925a20e2af2c54d286b01805ac34967410859f4f03da09","up":true},{"one":"ee36d1d5dd69fd30242d7da2e941b34ade5581c7164fcc43288ecfc52937a98f1b31ade5d1e4dbf611cbe1c7875b2840c89435081cde471c271d7bc60e9ef211","other":"9db1f94d74a00d1e5e2a391f1bcddf16b6d0670a2c6d91d946d38112c58634444b6fea8e8c05ab4b73bacdd62a0b575f6fb8729978edc216c7842b177b9f9cd9","up":true},{"one":"a78f18691e0dbf3c08fe9d7dec188e6a05a93833432fb99eb2b3924ab0bde7a44db2a102a65544bbdc4fb61bc3a3d569230d9843a335bf619167fb045d78ab3c","other":"c8b0dba45104fc7c7dff3ce078a0d3f5ade6198bb4656e2bee8076387929133e5ef2bd293b130a9d4f6a6974ca17e8b4a8f406d1219880f1e0f99c65c63af5a4","up":true},{"one":"8ca3b63cb84f1e9883d82809a9b6777ec1029ecda96fe93b4d494ee9cbefcad13f381b3e480136e542e01054fe1ede66c65db84a0009871ce49383db461c8438","other":"315b8a1711f680c2eaa607e35ef7a9e19c2b61721af8a7e08f1325dde1fe33cf1f47b3cc4acf12d541631041cf1b42754875fd1c9b66ee32797b72b9f7711256","up":false},{"one":"c903c5ee3d9cd65bea3ea777e39282c33e1349d945411fb2f16321bf582c2f400956a98fbafe5873fc5f6f6a9a051df5da7e94cbd340f935abe80f91e79ef875","other":"f54335964d9b4eb9813eb05f40ef1c523bbf0faac5a04c4737467d590fb6b55c7fa1fc5d4d32c5491d8766b9be6fdfd3ebdb25c5ffe1719f36c86ddf87ae3a85","up":true},{"one":"4ff66e9b5d3fd345990bd7605bdc222b78946f0c13b72bf80352812b2426d8f1d36c93e6c8713566004615e8a78ecab12ab0cfba254c0967eeecf8875b25bdae","other":"094f9d0fd3bacb17ac67a2edb8ed394fbbd1c8d478233d3269cf217e7b788e21042374936b885bf23ee4f9e03babbe4e08db283dfc2a6e052a8a5ba133717dd5","up":true},{"one":"a608a746f46d4b2e9267c65283380d6d6cb8885a64428fb77df9934bcf4dd1723587ee7c8f4a642dce266a12a6a4cf4e5c6db7fa1024158425a6753e7ab7264c","other":"c73d088ade8756c74832c73542bcdb3e52f670f7a74ad3a7eac2a9e3ece6bd081f782a8e1d3f9a40b9aa9201509110f37fc57fcb10ee1ef3ef07b7eab019782e","up":true},{"one":"b137cf2291b530a39516d882200848e7f27a2710e0839b4d25b4f367bea6a0c3aaef8c7c7851c00a2945adcd819ea0508610afc1f453b8bc512b7b4d4faacdf3","other":"66d0c5da973d9dd65350ae1ec63776872cdb7ded6afb6f51ae82259f6fd35e884375d15de290625f02ed2e5cdc3f591decb45e5fc64d5b0f835a216fd196f5a3","up":true},{"one":"58cfb20d3da3641e0ad529b9edbd4b590a8d1dc9d1ed7b44ed3187dba9260bd7c732fc10981f5b9bffd31d362cb05150173618aa36138984431d94a323a9b313","other":"ba21a373781966135d6225adae024a3f3e421b852f72f8b0569cb92fcff87c33f7e5b799a509b8eff6ec6dc46a9b17d5bae1e91ec7c54c0c712d893d54b140fa","up":true},{"one":"7646d08b3e24183e3814de130235c41eb88a5a2abff23eaff3c91954ad3ef55fe27da422dac5b894312276bf1a2f1aebb8b636a8d4a0c93d9b016d441df3fa19","other":"57cd4c0048b459192ee46e19ec7df777e600f256e0dc8c3019431eb7bec3c020b9504ec7aea3dba8188658ca5b830ec40af6a8540ce10e04badc6c695d009271","up":true},{"one":"094f9d0fd3bacb17ac67a2edb8ed394fbbd1c8d478233d3269cf217e7b788e21042374936b885bf23ee4f9e03babbe4e08db283dfc2a6e052a8a5ba133717dd5","other":"57cd4c0048b459192ee46e19ec7df777e600f256e0dc8c3019431eb7bec3c020b9504ec7aea3dba8188658ca5b830ec40af6a8540ce10e04badc6c695d009271","up":true},{"one":"baa5924e1547c177011285d292aa161a15e5ff282da2cd0afb83c9caffb07bdbb3662c227fa7b26e6dc8be9b8863e647eb5f8ce81640532f8f5c9a7f36557e63","other":"109556abac422a912ecffec0d8796f8f16e92e8f95cecf72dc89e97a8bf1fd37aad3c66aa3cf134acade6d065c31821f977171d5c5463305b57ce3eee99a7ab4","up":true},{"one":"759f46661056bcbb30c7706c9fb87e22a30feb523bd53ae5d18db043efa45b49a2b8982abebdd598fe0912a05896390ec2eabe5e160cbafc0771990708ad8c28","other":"81288bb0584b7ffc1546043e052e1df10fd5371b35dedd0bb42ec5b30ce69b741b2f7857af5984d4754b39d7253575fde9298504999b78380ef602d391c4bb1d","up":true},{"one":"396c703d27bfdddf91761f134cbf665fe61e0b3a5d24036a4105a625f72e8c28b821e9200f20d6e8f8b3ed6b95bda6b8accdd840c2f786720b7431e3af2af981","other":"65e954e60837bda10654480b227fa3bcc6e63356c52079002a27e836cd82ae2934ba77da60080e4b9f2d9324b982b24959bfd9624302e6c330408381054b43e9","up":false},{"one":"6b4e376e9c94242b6d42688c22aa9ab418cb6dfb1cbca1c69de0feceec8d3af29fb005017aaa6e503cc0c03cf0dc5bcab55e01cd6f64b9efa02ed87c03020003","other":"11d560045536e9d1b0b1b9e8944e00f0ca7f1e6788c9fdb51061820bbb3008ead92bb7836621bf58da7035c87a28328faecb4cb2e3cdb9d7fa4f45790e6bf352","up":true},{"one":"453779010ed7c59761da47ccd8869d3fa8349795e57edb9eea416c0712301ea622c7683858e309d19ab137ddb0edef161d0d00a361abeecf0628c3ffabc629ea","other":"d3105ede6c21bc643d523afcd1309a5dcf03f70797a92f167c3a19f86ae98882fe1a9d4094d7a3dee4a0833b8075b6c3e9aaa7f4879dc47bb388c3ae85522288","up":true},{"one":"17917fa4da06068b587c17899569dcc768b9cd2c27117a4ed67aab26a7e70cf8d32b881db258061ffd89a332a3b29bfd963d8e171a06c3e208ba0de1c42a2b39","other":"c57ea182bdb42ba9b0870b5c870e467f52693e5c0df752fb6eb0dfbacce7763f73caee10db40f4fd90f19f504ee586eaf9da41f5ee93ee515d885fec99374116","up":true},{"one":"be026dfb24847cac2d00f483104edad06ca8ecb9e1229c479ef5650c7b427cd5dc34a1cf06172c17c9d0406ce17009712e82446394743d4cd9bbc41c537ebc14","other":"2e409baefbd821485a151993356730e5989810d581e68190fbaa142799c9335bcf98310ad188fed10ae6eb6e2e789730393e509962ec5c0fef0342d72ed088d9","up":true},{"one":"b597c9ba4da20c49fc4ba019571321d2579588636cdaceb9f225706574970adbf4771dcf186b1decd4e14cd5d257e30a36ca829829598c1775902201ad9793e2","other":"6f60ef501b41f9049419b033ae8d793a18067bdcd60347537b0dc3873bdd9a2d10d24909cca7c39781765746128c2165596f6537a94f58279523faee71f9c51d","up":false},{"one":"032b9bf2f59f15571821611d3ee541aa748c86d47fbe5f049fd0069be53e5d7c41991d82957e9c727654c3aa73ec94997c03d8a6c1d2007c9bb1a703f6215158","other":"2e409baefbd821485a151993356730e5989810d581e68190fbaa142799c9335bcf98310ad188fed10ae6eb6e2e789730393e509962ec5c0fef0342d72ed088d9","up":true},{"one":"302c37f28c69fdcf00b39ce0c0223de0d94cebc2c0b068315b95b76b5432573ead0656569441029ba9054d8d3d959fd8735e73913af5ce3f1132f8271fd437ef","other":"b26f7c0113a5ae885f7c0e608aea7022a9c8bfc40c5643e60b2ba7343ff09c5be0bc08be34dde3c6b85fea192a46d4764770c12cbaa233df4231a1b99627ef9d","up":true},{"one":"a99852c5bf08ea4713af9cade5343d1259bfb90401aca7fcff18c58cd56a98804dd16c61fea71039c0ac31b9bbbb9dc5aeaf0c2f074d3365e88d17031802d636","other":"a608a746f46d4b2e9267c65283380d6d6cb8885a64428fb77df9934bcf4dd1723587ee7c8f4a642dce266a12a6a4cf4e5c6db7fa1024158425a6753e7ab7264c","up":true},{"one":"ddaf3f8478501cda872c056c72063eb64d5b871fc5fff70704872802289dd2d348f73bc342b7f148a90cfaae2448ebf16fea196be9df891dc71a57fb410d59dd","other":"66d0c5da973d9dd65350ae1ec63776872cdb7ded6afb6f51ae82259f6fd35e884375d15de290625f02ed2e5cdc3f591decb45e5fc64d5b0f835a216fd196f5a3","up":true},{"one":"7b5c0e81c7f4e3ae29d745f6028cfa10b29a16a9c261b65fb8dd05d6eccc634612ad5d3029c8e9f39863a2cdb2682c25f090139bf5c4950e25647e39dcb40e63","other":"c57ea182bdb42ba9b0870b5c870e467f52693e5c0df752fb6eb0dfbacce7763f73caee10db40f4fd90f19f504ee586eaf9da41f5ee93ee515d885fec99374116","up":true},{"one":"c57ea182bdb42ba9b0870b5c870e467f52693e5c0df752fb6eb0dfbacce7763f73caee10db40f4fd90f19f504ee586eaf9da41f5ee93ee515d885fec99374116","other":"ca1aff0d847c6fdacb623ad9078a0885b3208614fea20d5ff11779779b486bf5e9c794aacf848d3c2d58cfcc1eda8356df82f5fbdd0a5236beffe8e6042848c4","up":true},{"one":"4e95fb8943ef6502fa470870a7ace4ca11e18589bd2073167543a922317b35e40b5068934d07e56c8fdd23354dfad51fd2899db854f189841f02b5914cd97749","other":"c9cd9dfb9f90a7948ac5a42c7bd63263f2eef6e1d85547559f7d2ecbf5f9cd1eab051b8e9e661b573c275d84091a44e73f6fc6bcc91dcdb674bd5d939190fc01","up":true},{"one":"2e409baefbd821485a151993356730e5989810d581e68190fbaa142799c9335bcf98310ad188fed10ae6eb6e2e789730393e509962ec5c0fef0342d72ed088d9","other":"c57ea182bdb42ba9b0870b5c870e467f52693e5c0df752fb6eb0dfbacce7763f73caee10db40f4fd90f19f504ee586eaf9da41f5ee93ee515d885fec99374116","up":true},{"one":"b35f418c7935cc54278e90978c3ef1521ab91daeaf9f1ebc1cd25211611ade091cac4e1f009d71059279d507322a4536501980ac0dd44caddc52fd4c593879f7","other":"1b6cad4f9851cc584c5d1405f976bb51a52e27ef4525847df543dcca65ca5eb1ef229dcc68ccbaaf00ab1e044cb5990dd213c805bdb4adcceb6fa70b5c61fdb4","up":false},{"one":"e6779e3bbecf81dde8b27d652ed2726c45c205db0d0405c4580014a4c91d739830276f77079108c98ac516ffa00194e77a0795f7140bdf36069b6475e58213f9","other":"c57ea182bdb42ba9b0870b5c870e467f52693e5c0df752fb6eb0dfbacce7763f73caee10db40f4fd90f19f504ee586eaf9da41f5ee93ee515d885fec99374116","up":true},{"one":"663535b22018a4ef0b151572ef286fa66c22c6e9b2913a69c4a735d4b0149bdf6c84bd83d710f8aa2627e8993b7f020750fbc6f56a3365ce4c840e2b3de1a6c1","other":"2ac93c31937ca205d61cc5c2a1b9037871cac55e9b306b999b28e19566b3316f6539455e014840ea50c2db8a7c97d78804d3a2dcd7cd9c1f32ace0d36e5dd339","up":true},{"one":"3b570117addeec03c2694baf28e246f91907268fe665c6c90356120332794258ee57a60853c19e9fe25d042ca42a5be7fe0797d84199174de8132f1ef4a9349b","other":"385168340139236a0e0f537fa693122db9fa02a377c96f31aae54718e92624fc0288164877e63616651565e055c53f7074ab2fdd18a837da6faf644941305bf0","up":true},{"one":"d9bbcdfd949010e6b2cbf6d0f34b27593ae410bdc1838876aeca35679571fe431d040a5ab085c0a77f111688bebed891da3587277cd794702437cb20d6aa4256","other":"e1ecad3beeb6c19dce551e4a603c7b440b4498c44e298dc67bfaf4ed2c75bbea95df48b1cd1318e2ccb962cbae7c30ff258e73f8c3fc6b7e9ae7a47f7cf8e53c","up":true},{"one":"cb310c0e86aa455d7c9af6394ae38561c901da30a51d7ccb7e66a09d9a8f192ae8caeff106043426d56397088f141c4e01e3b98f1ee583ffc7318b5f730f3ac7","other":"1bc1d6155ba35d29ea16938994e08df76ebd8f16bd180bd6a9b9d8798d0745889fe72d641dd78bd8ec13526929f7eb5aaa6a388430fa69033d6db581e53c6422","up":true},{"one":"84abcbc7b5598ecfd91ceace0927921a5a3404fdb274fc2a2549abbede5f8e4f62c15688a4dc9a2d80262c45970c88898da245c6eb779f327a81d53a17bbc74c","other":"c57ea182bdb42ba9b0870b5c870e467f52693e5c0df752fb6eb0dfbacce7763f73caee10db40f4fd90f19f504ee586eaf9da41f5ee93ee515d885fec99374116","up":true},{"one":"c665a6b1b7ad39b86bd4b1fe38b7ee95a0fbb1db15e91381ec9e5a235e33b69ffdc92c60dafd74b7b4dafca1b000e9274bf045abe5b93b1a9c2b31ae071a9898","other":"d7a319f69013b8375e64d19f015547462c84565b882337998f9e669c5fadd3d2ecf6374109903003e09f5d453424b5c7fdf52163d2cc8084cf81f94844946b63","up":true},{"one":"b26f7c0113a5ae885f7c0e608aea7022a9c8bfc40c5643e60b2ba7343ff09c5be0bc08be34dde3c6b85fea192a46d4764770c12cbaa233df4231a1b99627ef9d","other":"c903c5ee3d9cd65bea3ea777e39282c33e1349d945411fb2f16321bf582c2f400956a98fbafe5873fc5f6f6a9a051df5da7e94cbd340f935abe80f91e79ef875","up":true},{"one":"1944f98d4db32c56a5efda5a79aa5f276bfab1e084d6611fec0e735b8bc0f45b457cdb74a23fc83b2377821fa8316123c9877acd6db7c41058ca5d3cfedaecf9","other":"94088fe273f76e62ca4e43c095ad12215b4ae4c59942328b3985416fb19bbda0cacc143a49eff3fb644ad53a19d3f043260e43dbb70a0aa9c15829c21cecd3c7","up":true},{"one":"df54af3bae257d437c5657905484e0d72e9560c46f8ba6b3437730234e05259b404cca40b0831e911605ff8a68a19e8fd7e958069ec8b40595928892f4fa220c","other":"e2e0419a41bdfc5bd76deae2ddce6ac865f886d764c9bd18799b79fa3b2b6ba66d765d26da2037e98317e1d7e8232a61e63c1d0cfa98c9137424151b46e07171","up":true},{"one":"5e86f39cf8338ba098a85d41e601a303fde311662b216ad32a2b7bfaf2b2b6dd1af3775784b39f2d85ac5fac96f05f3abdd8a2bd28ba16d939725fd6a33ae1b6","other":"d9bbcdfd949010e6b2cbf6d0f34b27593ae410bdc1838876aeca35679571fe431d040a5ab085c0a77f111688bebed891da3587277cd794702437cb20d6aa4256","up":true},{"one":"cb321c9b0fe2eb3617b8e2461aab170a9dad2c9b04a10eead4e37e551197ea0a7500eb1cb7b155efe1886486ef3d252d8ff0d309f2906a1126ca011d037da70a","other":"d7a319f69013b8375e64d19f015547462c84565b882337998f9e669c5fadd3d2ecf6374109903003e09f5d453424b5c7fdf52163d2cc8084cf81f94844946b63","up":true},{"one":"5df58ba12334a1b4f983d642fe435901261767cd81f8f37c43e359f5584664e4d287e8c2275995604a3b3a4823418e35cd899a3db2a7db31570e19512f375481","other":"df54af3bae257d437c5657905484e0d72e9560c46f8ba6b3437730234e05259b404cca40b0831e911605ff8a68a19e8fd7e958069ec8b40595928892f4fa220c","up":true},{"one":"7b1e20217f594f87350542df31ff5ae8a635679bac7962d49c97e02190c644b673d03e7eba2626b45ca7ebf98d8a972dadbba02c18a8d2cbfc3e7a4cced5b4b7","other":"7b5c0e81c7f4e3ae29d745f6028cfa10b29a16a9c261b65fb8dd05d6eccc634612ad5d3029c8e9f39863a2cdb2682c25f090139bf5c4950e25647e39dcb40e63","up":true},{"one":"94088fe273f76e62ca4e43c095ad12215b4ae4c59942328b3985416fb19bbda0cacc143a49eff3fb644ad53a19d3f043260e43dbb70a0aa9c15829c21cecd3c7","other":"f38a9d792173a29c61389f5d84c005d78eac6e750659aad42e2d6df883f04eb3126b2c38fac95076eeed455b2031aaf694143922aa93a2d50412a2454dc56e28","up":true},{"one":"57cd4c0048b459192ee46e19ec7df777e600f256e0dc8c3019431eb7bec3c020b9504ec7aea3dba8188658ca5b830ec40af6a8540ce10e04badc6c695d009271","other":"1c2f7ce55a6e38487f3b3fe6083a79f914cd6d7e4aee8f5d56b4a61b3eb584e128c56998db0e13e775edee3adacf54f09960a041dab3daa80a4f8a3b42760c1c","up":true},{"one":"043fe7085e8c90c18270f84dba5fab138e50216a1cf8d81a3794d156fad7fc81d1422aff169b244b13f91d73eebb5de464f97b1b93b3ad2a58959cff19238842","other":"1bc1d6155ba35d29ea16938994e08df76ebd8f16bd180bd6a9b9d8798d0745889fe72d641dd78bd8ec13526929f7eb5aaa6a388430fa69033d6db581e53c6422","up":true},{"one":"92d6ef729992f0de886076e5f8cdc42cbbd70b29e79c25e0b3d22b6575d3d2508d47b42f581e335455483d43625bce4e55f88cab9ff2073ee8dab746357864fd","other":"831cde5b651ba327b059da4c7f84b184bdd6bb99c6690ae816affe25d42c6c3dbe5b59e2b6bf23e9d0f6c485bd341ea57ba1a8220d18b0a40e156b77d84f79ef","up":true},{"one":"1c2f7ce55a6e38487f3b3fe6083a79f914cd6d7e4aee8f5d56b4a61b3eb584e128c56998db0e13e775edee3adacf54f09960a041dab3daa80a4f8a3b42760c1c","other":"94088fe273f76e62ca4e43c095ad12215b4ae4c59942328b3985416fb19bbda0cacc143a49eff3fb644ad53a19d3f043260e43dbb70a0aa9c15829c21cecd3c7","up":true},{"one":"9bd4f0adb9a966cc5ba632f1b540fe9cd6c8e39fe1a041b315697679cfb04b735952062ce057d456677cc34a84301f26bb727a4ab2646fee734f80a22c620746","other":"094f9d0fd3bacb17ac67a2edb8ed394fbbd1c8d478233d3269cf217e7b788e21042374936b885bf23ee4f9e03babbe4e08db283dfc2a6e052a8a5ba133717dd5","up":true},{"one":"389b5c1a805f87427e6d647ec5488342a3f7d700615943d5ad98ca5c111f33c7ee007970b4d3e475892095c0d5a79b7ed52d12598398818159000d4b9b719126","other":"ca1aff0d847c6fdacb623ad9078a0885b3208614fea20d5ff11779779b486bf5e9c794aacf848d3c2d58cfcc1eda8356df82f5fbdd0a5236beffe8e6042848c4","up":true},{"one":"9b59b76dc61223c7b37083b0ebdda22d3599563b3e3986f5db9d5b12f8c806cbdeb2345454efe957cbfa11eea9c7896aefd9a461210524805452ca100a9ea431","other":"4ee37acec2178ef120166265aaa2b64b09b315fb53861405ef46f2503c273eb9692e9cb4c2e67a8652254d430fd6e02dd3fe4cded20bb231a9fb834d292b0b24","up":true},{"one":"9bbbfac8be4a000f51a4ce8d024d2595b5d491afec0138922dddfde5ef62c664040c2e9304cc6b7bc688233b5d0c4644b8c8793227c078285a3ab894ef0497a3","other":"1d0244a13affe60996fe3cf51ba624adc746de0c7ea68ec5a31311a36077c5b5495e3d95c9642875db44c7ecae6ffed22e45f2e2d024d486760be2af9f4cf2cd","up":true},{"one":"4ee37acec2178ef120166265aaa2b64b09b315fb53861405ef46f2503c273eb9692e9cb4c2e67a8652254d430fd6e02dd3fe4cded20bb231a9fb834d292b0b24","other":"d9bbcdfd949010e6b2cbf6d0f34b27593ae410bdc1838876aeca35679571fe431d040a5ab085c0a77f111688bebed891da3587277cd794702437cb20d6aa4256","up":true},{"one":"7acddc7fb6ac587b7e343804c768e4291cd28dd2b2b9207dea6ee82360d848a52d84f94e4c49e9c421f4f90e2d24f6291e2358783ab0230e6ecde82e69b4ac52","other":"e1ecad3beeb6c19dce551e4a603c7b440b4498c44e298dc67bfaf4ed2c75bbea95df48b1cd1318e2ccb962cbae7c30ff258e73f8c3fc6b7e9ae7a47f7cf8e53c","up":true},{"one":"9133b0b3c8f680286eae90c3beebc3099a13de38775a3ff2abdeced62d05eb2ced5ac85eac0870156be03101024da5e1d9fbf3e1066ddb3f088221e64149acec","other":"2ac93c31937ca205d61cc5c2a1b9037871cac55e9b306b999b28e19566b3316f6539455e014840ea50c2db8a7c97d78804d3a2dcd7cd9c1f32ace0d36e5dd339","up":true},{"one":"cb94a8270d0050378116b5815ff17dafbe20f5303839c4fd57b981d4687a4b145e4bccec7e9af9b9475005930148ffbfa97781a0762c8e9f352dc95565fc8732","other":"aacff366e601e072a2113add9020e19b6612f3e85b6e607fdc8cc1b6991f43be0b1f835ed3dc41d1f2b3e0caf7fac252c8eb4c150667d48207fa92ea5f0a7455","up":true},{"one":"07c63ca5d0309e30d1ab12e7fc142e6d37904b552639cfa97850161491f28f20d87e0304be29357bcfc2ff52fc52fd0d4f6e6011ebb239cced8b5c8dad7abf45","other":"beec648d79437a5d7b4140ced45d82d035c6f64f9c67c58386703811d97c3846787eaf274d2298df809475f0b7519df696563cb8e9a5fb0a9cc419ab13fa8d41","up":true},{"one":"70ee3c7e02a123f78345d41c386e413f06b51f1ab346c2c472891eed7dd26a1f14e213a0f4f2d872859b9b535936a6d9b072d2604456f76221a422710411822f","other":"2bfba66ec9d63e928d77d455f2e10a14d6213e515099d5db14fa44a8bfc147eb0fa7afa9aaccdc86453c6903b55556059a2e13dd61fc494127d4a3ec173bf9ea","up":true},{"one":"016f8f4619a16a07fbde5a18e362158d696e4d9f104a77787f26e32a25cd7d278256f8e0db865c488a99511ec27a5eddd5ebbd1c1397fa7f8db111062e5fe959","other":"e1ecad3beeb6c19dce551e4a603c7b440b4498c44e298dc67bfaf4ed2c75bbea95df48b1cd1318e2ccb962cbae7c30ff258e73f8c3fc6b7e9ae7a47f7cf8e53c","up":true},{"one":"9194a3a4c8f3235203e48bdb10902d958d26c342805ea6365af9711213536509719d917c694f9a4fbdde6889a4c92299a5301f0275bda4dbcd2541b5bff5b271","other":"0c14dd51a56130c51009e3ce47c96b2afef26b7e86cfca65d8a9bae1abef13b3a7a192b422d894c39e24ab00be412d166a3571cc259ff4462d4ad8925a153766","up":true},{"one":"bf4ff51cc3d9a9d8cefd7e346ce1384d06450228a6086fe12fb0c60fec54bb6478f090bb638fbdbf8f41f7bc6420cd8a5c8b1b8566229b6851167375ef412f46","other":"5526d86ba9df651091d88460a9bedb9cedb957d452a635e1db46b9fed78082022adec0047cd7485956a4ecbb0e18107595de0de3c35242527cd302bf74a19260","up":true},{"one":"f9ffe87c52ff4c22bd9696af32e0a9d34bb81fb84d9d8bf5aafe2ef9696e7b3d6460bf2a93aecb066133f53416bde841a02d6967bd06e3d4a714f3b2c123a947","other":"4314b0b04331973ed29a58843951f144ac3d09bd5d57b6cd9aaff9b73a7b2ec81e344a3e4ece462bd2081b837a06310e787ef3bb889dabad46fe7efd394c8342","up":true},{"one":"e3c8a97a2d95dd543f9e2b41d9dce6256e284296f866f4f92e9925f8c7519dea23fd6d1a11153b93c10d6a32295e7b9bcc16024e690e4a0dc84fd25ee0f31b2c","other":"3d2df188704eeac09c8b291bf275a73888199a231c832c51dbc3d746968d4b51a7d5eae0c7c9b8c8e19f5e28d38c375e01abefa343f31dbe221deb837ab8a0df","up":true},{"one":"bcf8e831821a5bca359fb824c7dc4d66906de82f3663a0a853d96880a8ca0bdddcceb1b66dd1f13f75ee20fde50fc9de545bc25767f228baee910e0dbfa8cc27","other":"e3c8a97a2d95dd543f9e2b41d9dce6256e284296f866f4f92e9925f8c7519dea23fd6d1a11153b93c10d6a32295e7b9bcc16024e690e4a0dc84fd25ee0f31b2c","up":true},{"one":"beec648d79437a5d7b4140ced45d82d035c6f64f9c67c58386703811d97c3846787eaf274d2298df809475f0b7519df696563cb8e9a5fb0a9cc419ab13fa8d41","other":"afe5b217dc512eee45575c189826ee5640d11a0ac9e8e4b03e9e62e6cf6df9de500bc8a36cb7d82a2280ce184409164f1772cc5c9e59ad04361522d2b8c364e0","up":false},{"one":"e98a08e8e3544727f5ee27f4465375a67ffba490fcdbfe7bfdc909f6b68bd279f776c65d38c2ccfc33079f852f76349c94d68fc6989c0d981f22333f036a4bb5","other":"40bdac599b00e9c41ad6476ee415c33d9c17c5aa672692c2404e523b29dc315da929a86874bed87fd9009871805d1dbf3098e7a817193e3b08a6eee66346da79","up":true},{"one":"9db1f94d74a00d1e5e2a391f1bcddf16b6d0670a2c6d91d946d38112c58634444b6fea8e8c05ab4b73bacdd62a0b575f6fb8729978edc216c7842b177b9f9cd9","other":"485825745d97654cbb92a14e0cd1078691d3c28f4d82b1046284b676a42b44ca58eb43474e45e415d3bd3f3c383f9a1a3365821ed7ba6a9f2603b29d58031dc7","up":true},{"one":"485825745d97654cbb92a14e0cd1078691d3c28f4d82b1046284b676a42b44ca58eb43474e45e415d3bd3f3c383f9a1a3365821ed7ba6a9f2603b29d58031dc7","other":"292c78c8e41606e98428096bc6f4609a7aa48e5c4d17eecc64d65faae4a7270b0c15f0cd74274015688ea0a9aff34f215c29118222e362a29c8d637963973a55","up":false},{"one":"5dc69635f6d573c824ea83b18593a47f9f21a6f91ce18d2bf977c97d21f8d2a8ce88829244d12a07d949bbd52fe8a2035bc89685fe1bdd4ee20d766d75d3deee","other":"617595a230e0a74a3db3b47cd27b941e02bdee9a84cdfa8eaa63a55941eb5caa79e20fb69726a4d46a0e5aeed24039f8c5a20679a692df0bc140f42558ca9a2b","up":true},{"one":"7865b82e44add2cea6ebcbaba9c152184331a2940fe73f6f9bb940bda8a59ab4cf4760894b9cadcaa54e36fbb712ad619346a49a85e32cdf2b53cda1ac1e0658","other":"ee36d1d5dd69fd30242d7da2e941b34ade5581c7164fcc43288ecfc52937a98f1b31ade5d1e4dbf611cbe1c7875b2840c89435081cde471c271d7bc60e9ef211","up":false},{"one":"657d5370319128d24d925b41065eb619409d63ec6280975d78877a4028287463f6442f5206dd703569a05b2b542ad8bbb99803da265408208d6356a26d283d08","other":"b35f418c7935cc54278e90978c3ef1521ab91daeaf9f1ebc1cd25211611ade091cac4e1f009d71059279d507322a4536501980ac0dd44caddc52fd4c593879f7","up":false},{"one":"81288bb0584b7ffc1546043e052e1df10fd5371b35dedd0bb42ec5b30ce69b741b2f7857af5984d4754b39d7253575fde9298504999b78380ef602d391c4bb1d","other":"ca1aff0d847c6fdacb623ad9078a0885b3208614fea20d5ff11779779b486bf5e9c794aacf848d3c2d58cfcc1eda8356df82f5fbdd0a5236beffe8e6042848c4","up":true},{"one":"315b8a1711f680c2eaa607e35ef7a9e19c2b61721af8a7e08f1325dde1fe33cf1f47b3cc4acf12d541631041cf1b42754875fd1c9b66ee32797b72b9f7711256","other":"cd8815d66aee8bd488d4e5e25f0cc9c71cc65349f701ea26b1d6cd9c039d16fcb473dbf270a3b33187720ccf4b0ce4f78a6d6edd05f4fe804772d5b6ec45bbd3","up":true},{"one":"17a79cb279306b6bbd35219278f6bba03111079d6c4fadcd3c5e57b09678e111bda5f8e36ca3d223e51e255d6e857363b7741e438b32ec6e6c0dc1b224071081","other":"48a5e01e06e297dc1c640ac9601171495bd70fea461c60e7e6e2532695e45fcf68183c2e58b5e6931a6c1c094f5331efbd7f2d93d5f84efdec5a35afa2124438","up":true},{"one":"97981f4b825620985b746c85824d7a4d307ee25d60a72c2b7de4b1d4f3b1c002652adc3045842d350f849789e410a0357a0b42fa637a1b4fc9d39e44f8a674d7","other":"6f60ef501b41f9049419b033ae8d793a18067bdcd60347537b0dc3873bdd9a2d10d24909cca7c39781765746128c2165596f6537a94f58279523faee71f9c51d","up":false},{"one":"d3105ede6c21bc643d523afcd1309a5dcf03f70797a92f167c3a19f86ae98882fe1a9d4094d7a3dee4a0833b8075b6c3e9aaa7f4879dc47bb388c3ae85522288","other":"3dfd733dde9414af916625ab981777ff1ad7ca0f6d1e4e7d9e2739969e21182fd13d85e281868653e7325b20069356b11524b54143c47fd3955a911cf7325ad4","up":true},{"one":"460531928a4b084686343c8464b37c3452bb3566045698d08a4692864de5581a9eb1dc632329e7d3ccb73ec31ee7693787d69df8458efaba9a7105d87ee2e053","other":"c332fe1f9b6e25f72c7150631ffa6e0929ff6eeab5d17aa45eaf669bdde869cf404505ae990a529aa3ca797cd0a96f31cc41431a5d4a163132be566f91623c08","up":true},{"one":"b6a998dea59194cc60ce97c7c9702368411889cb6905516b23f41cc5116fba8d0f237d418318eb0c333cad18003c0e9a6bd8c99080520771f2bad640e2e5ec1c","other":"2ca05ffc0ad771e1e045a47f1c0a79ce374a25e3c0e53c2a80d67e7479677003f62880251a83a5074f1c9651d828f1ff7e352935a9df141c1eb75a0c59b00a8b","up":false},{"one":"cd8815d66aee8bd488d4e5e25f0cc9c71cc65349f701ea26b1d6cd9c039d16fcb473dbf270a3b33187720ccf4b0ce4f78a6d6edd05f4fe804772d5b6ec45bbd3","other":"8dd8ad560af84bec579cadb33d51711aa61b6ed22705010336df5a71a94591173b25e869457429c4a199b205fce8e73530e28203e18b971c2001715e610f152a","up":true},{"one":"8dd8ad560af84bec579cadb33d51711aa61b6ed22705010336df5a71a94591173b25e869457429c4a199b205fce8e73530e28203e18b971c2001715e610f152a","other":"ae2a996d3b562cb47a564934037949da83b1bfe194c23754f3dbe2372ec27654f4f3b6cb7f394570f308025589c065870477667e5560dbe5a8ea1625740699cf","up":true},{"one":"6f60ef501b41f9049419b033ae8d793a18067bdcd60347537b0dc3873bdd9a2d10d24909cca7c39781765746128c2165596f6537a94f58279523faee71f9c51d","other":"3dfd733dde9414af916625ab981777ff1ad7ca0f6d1e4e7d9e2739969e21182fd13d85e281868653e7325b20069356b11524b54143c47fd3955a911cf7325ad4","up":true},{"one":"855bdf057f4a6b095e2000ada199447b5b4f2f8d78d2ecbaa0ff1fbf761788870ee999266ad3b26efa02be1a46a4d92ac0debb85a2ceab3442394ee7d99e5355","other":"bf4ff51cc3d9a9d8cefd7e346ce1384d06450228a6086fe12fb0c60fec54bb6478f090bb638fbdbf8f41f7bc6420cd8a5c8b1b8566229b6851167375ef412f46","up":true},{"one":"c9cd9dfb9f90a7948ac5a42c7bd63263f2eef6e1d85547559f7d2ecbf5f9cd1eab051b8e9e661b573c275d84091a44e73f6fc6bcc91dcdb674bd5d939190fc01","other":"4b784f072b7c96c30612767425f552e30e45157e70139dfbe0ae4ff86dc31601adec60f8a3ad9747b02b5219073d8813af9b09d59eaf7ddb7ee24856aff6fa8f","up":true},{"one":"ae4e21e1587a8475afd299e00ca7085c7bf2a44c2c64a3068f12223d9202b0125094385319034691ec26b497ec9cf18fe8c0839224bac1b84279410241cef979","other":"17a79cb279306b6bbd35219278f6bba03111079d6c4fadcd3c5e57b09678e111bda5f8e36ca3d223e51e255d6e857363b7741e438b32ec6e6c0dc1b224071081","up":true},{"one":"2f360209383d6de4ebd3b4abaf77796520b8654270b03f2151eac4a01b4417d7e0668c1f9ad30c20ff49aa8a0ab33dba5e6095619d1cf04b7af841722ab773da","other":"5eccdbcb15ef42dc96abcbcd8b8db75d9230de10e3c650620737f6cc04ba4fdbf59ded5daa801901c191be186c329ebcd37ba83bcf794064ad4e11bf10d3f775","up":true},{"one":"6b01079463ec2f649db8634cb7a596261c79a8f714d954c772528e0547b017f8ce405e4a0ea9d32270848180e0f77b8c0b022cf95c85e777626edd4d24ea21d2","other":"2f903b2fd4f9432b7d91b5c3e4c7ee3cb9c56fe7efc4baff0edd06fc75e4b7492f2c3c929755746df59c9f95d437a12ba40ac138d08f5bc7aa091f49f3b852c2","up":true},{"one":"5142eea687de4248b2184e9896b245563117648e7a156255d9a7ae730313d5d383db3be1125b5accd7e743c2a5d8c3289ec559ef7cbb803b9e82cd49bb213d9f","other":"fe62314839c93d2f6e3aee984d5f0b321897c6f39e66800d3de8b773baf6f19e0a03cae025df512aea8d5f1b667b6dbb15c192a90a76d3031c14e33e5c16c4f7","up":true},{"one":"6bf9fb6a25521c16c2ebeb6203d046d7dd40f29cc2ddb067c0222ef56d7012d2ee5d037f71f6668ea56767610b2a54c144aed74b7f68d06993cbd52fa1dc7630","other":"3b570117addeec03c2694baf28e246f91907268fe665c6c90356120332794258ee57a60853c19e9fe25d042ca42a5be7fe0797d84199174de8132f1ef4a9349b","up":true},{"one":"c2705ee7238ef9305e4da196653cde707649435a1e8b5b797d164e5ca06184a77af5bd7fa938c995fdfcbce724fa7eca3d908ee34891ab62cc6dfd411c3fa1da","other":"f33d1f3e460574706ac1c7fc9ebb4683b173496ce3e80017d1c3521bca03d5a41a9c7a6cde8347d2238917b7cc58cab000ce7ccf6bb408561015a2ecbe613408","up":true},{"one":"b4a5efa9028b2d196855393892f79993c2812d02b758f98813ddf82c5d943faf6d66eff811cc5a51936c118f4c768c0d13b54902095e040c602761e63c08655e","other":"a7507aa5665e165ab2e2a07def272f0677f9d6d35bb82268a34214384e7d8ef7635a299368752e63cfd02d4e60231076baf23cfa10d17492e55181b391ecf335","up":true},{"one":"eab86c521f8f1ac67c015ab713f1236a08b0200757a96bf87ab8301e7967ae62361f0e14da14ca294fc8cb3b4726b52f4773101e21b032977c6a647241b59c73","other":"c57ea182bdb42ba9b0870b5c870e467f52693e5c0df752fb6eb0dfbacce7763f73caee10db40f4fd90f19f504ee586eaf9da41f5ee93ee515d885fec99374116","up":true},{"one":"329145e75496cecb5f5c8f00313a52ddd8c0e8cd27ef1b2bc1b2b56e4d4089aaf5a7a3c4d9a40bdb92483fa05bd24d1cd0fd51883e30439dffa0fc855e1a7cd0","other":"b4a5efa9028b2d196855393892f79993c2812d02b758f98813ddf82c5d943faf6d66eff811cc5a51936c118f4c768c0d13b54902095e040c602761e63c08655e","up":true},{"one":"d4b7c787981abec24353c7d496661692233797e3758189bf909a69fe87935bf6da0940daa4f12e81f20c5e88f70b472113688b71a0ae2f91a73ee0e6ff4c8591","other":"ff1e34fd51953ed641b431aa657da21cb4c81d23e4eaa13c9cce526f1f1b34593d41f9b87a0e10387fe400c623638677c0efab15dbd1014a0ccc11f9ec92c417","up":true},{"one":"0cacda5560faff9d20e29a0625d3cd340ec075f198a50ab8b79338cee0e0db84c7c7e71042fd8c8f73e507b570de5d26c39473136b575f0167625a1168309ec5","other":"f6ca39b3ad803e99f4e4e9cf759fff6abdf06e6972bdbe524f6eb930c669d6f0e9b91f3de9df394b0d661b068273861391bdbac948ad911351c48cf02f874db6","up":true},{"one":"1f6d803a4ca186463772850ca0901fb920af7e74fdd2480c3c368fa707838ee91bbcfb57d5e3510c802b9b85f2d954f04c9b675414274bdaebae6488dcf94c10","other":"2b70e5ffcc0bb1c4f8acc09dd1016e67c9c96c92d091ad481efbb71bd8b2a5a5869c6d668617a9b2cbfe91baf5edfe150c3824c84d90899a974099071d171441","up":true},{"one":"2ac522ebfa49d37f86c6270ad4cdad0e766493f0e463b18c9906c70fbd2e5c6ff6b0d5879de6e3894418370636963a78b0c0cf087a8684c2ca30c9c736e49228","other":"7b35c856916eb3fc1b1f451667e240b95aff8f4731cc0f6743740923081ff1ddf2eec81bdccf4691a7bcc053d23eacfc15809c384a73448f618317bf605bd1cd","up":true},{"one":"7bbb3f3ed51cf84c077806fbd6d3578e105bc32aa6043da188793f066ad6df383a9f7cc0bd3124f4c887704bd188d480ce264fcdf178905bbda3b270927ea138","other":"0b7e1e5acabcde503ad827e45724402406114a513f81040a379b0f82df2eab4456b348b27936369c49e3c264d971c6a9e2c2217fdbc5e5b93ac6fc219957834d","up":true},{"one":"c83985973a9564ade7d90aa54911ac57077600676a1d27292d98e058bf1315887bad84ccd708cb7f52a695a1405fb7d491d7ca2ae9caa3ff58a5ad78ce4dc9d9","other":"b4fd11306b1416a9bcf4719578976188e104b8c5028b9abd3214d257446b97b70a22e6c00934d80caddde15e8e4d16af03bb399583047983fba373d8313226b7","up":true},{"one":"66beee3968dbcf3addc6feaf070a4e3e82b5bb164fb72f40add89f732c12e8d0a31a7ee1f1e24a4674e4dfc9a4912b02c17ce3c224d257d78b7156544d6507dc","other":"ee36d1d5dd69fd30242d7da2e941b34ade5581c7164fcc43288ecfc52937a98f1b31ade5d1e4dbf611cbe1c7875b2840c89435081cde471c271d7bc60e9ef211","up":true},{"one":"9e621c3eb534855ca292efa27a3fbc89b4f05c80a4bc65bcff2f14ff28ef43cbe14137d2fddc6fe2658bb06947d918476b479dde71469b8680e5d8a7a01619b5","other":"c73d088ade8756c74832c73542bcdb3e52f670f7a74ad3a7eac2a9e3ece6bd081f782a8e1d3f9a40b9aa9201509110f37fc57fcb10ee1ef3ef07b7eab019782e","up":true},{"one":"807340e5fdf6c21a56ef2fd158c32e92201206ca85fcc147165a408f7a735964afd47c397e663610ac53870ae722c0317291732b0422f8aeedae783d9c730218","other":"4b784f072b7c96c30612767425f552e30e45157e70139dfbe0ae4ff86dc31601adec60f8a3ad9747b02b5219073d8813af9b09d59eaf7ddb7ee24856aff6fa8f","up":true},{"one":"b53078000796f1cdb04dfeac424d5e3e37e30f00bd5bebf9a9ea0525c62917612b3a8f508df6bea59e3c7e4cd1aa530841f9a8af54e44f5617a13dee2c6ff007","other":"f33d1f3e460574706ac1c7fc9ebb4683b173496ce3e80017d1c3521bca03d5a41a9c7a6cde8347d2238917b7cc58cab000ce7ccf6bb408561015a2ecbe613408","up":true},{"one":"732393b99c490c76fa45e3e404ee095f2fa445fcc123af7ac8ab1d2fdd7cf2483f5b82bb818bd8a82b1a3b73e63bcc2c83d8f24d9aad9afe36503735e7967be7","other":"9db1f94d74a00d1e5e2a391f1bcddf16b6d0670a2c6d91d946d38112c58634444b6fea8e8c05ab4b73bacdd62a0b575f6fb8729978edc216c7842b177b9f9cd9","up":true},{"one":"baa5924e1547c177011285d292aa161a15e5ff282da2cd0afb83c9caffb07bdbb3662c227fa7b26e6dc8be9b8863e647eb5f8ce81640532f8f5c9a7f36557e63","other":"81288bb0584b7ffc1546043e052e1df10fd5371b35dedd0bb42ec5b30ce69b741b2f7857af5984d4754b39d7253575fde9298504999b78380ef602d391c4bb1d","up":true},{"one":"6c143960dbe3ba4c95e8debc1fda5f420a2a673eb46f7ff7d9a30f4cd2067e67ef8926bf17f0c99b16c79b6dc066b52409a11d47117d4fda4211636b1b74f96c","other":"0b7e1e5acabcde503ad827e45724402406114a513f81040a379b0f82df2eab4456b348b27936369c49e3c264d971c6a9e2c2217fdbc5e5b93ac6fc219957834d","up":true},{"one":"9c30ad8c85adc7bb52ddcfab2e661cc3a854a689eaa59128d35129d02cd5b0f8da4a44cdd33934a8e2c8fab1760c16d6f2e1c5eb227dc819e85624e63343c069","other":"2f903b2fd4f9432b7d91b5c3e4c7ee3cb9c56fe7efc4baff0edd06fc75e4b7492f2c3c929755746df59c9f95d437a12ba40ac138d08f5bc7aa091f49f3b852c2","up":true},{"one":"3dfd733dde9414af916625ab981777ff1ad7ca0f6d1e4e7d9e2739969e21182fd13d85e281868653e7325b20069356b11524b54143c47fd3955a911cf7325ad4","other":"eaca77d20c4ad6b87649eba21b750a4b1a2c575e06bc42679d18fce16fea15212e9a7408c16f3b24d8dfd1e397314637e72e292845d09534a39035bd9203ee9e","up":false},{"one":"e67e495385e7cacfe659b40d1ba94d4b1ff55eada70a4d9740a9e452fbf221672bd0a897b940e2a6bed71e2a16867fe45bf0ea0015435ac6d815690e263b1899","other":"6b01079463ec2f649db8634cb7a596261c79a8f714d954c772528e0547b017f8ce405e4a0ea9d32270848180e0f77b8c0b022cf95c85e777626edd4d24ea21d2","up":true},{"one":"0a4eec7b0e05da799aca5b36d9e2530f2a89d1426b1fcb7d8f9a662df8a8b5b763767a20db3c9c63e0bd13c2a6e16d3ba8f03baf84f5e5d24917b3f211d9bcfc","other":"e1ecad3beeb6c19dce551e4a603c7b440b4498c44e298dc67bfaf4ed2c75bbea95df48b1cd1318e2ccb962cbae7c30ff258e73f8c3fc6b7e9ae7a47f7cf8e53c","up":true},{"one":"ed6c793eb4565aa9d883a76fad6c97ad0b878b9ef0235e11e89db1af25a9653205f725c6ea258b84bde134f1a6437c6d109b859d17509e5016c4ab98be59032a","other":"0b7e1e5acabcde503ad827e45724402406114a513f81040a379b0f82df2eab4456b348b27936369c49e3c264d971c6a9e2c2217fdbc5e5b93ac6fc219957834d","up":true},{"one":"84dfd4e4d9f1204893f190eacc4c3999e175c433f70de86e335d27477c097a0552f211a21764f01a708da4c9e9e6552191a61d3e48f41d0e84f01e7ae3beb34e","other":"094f9d0fd3bacb17ac67a2edb8ed394fbbd1c8d478233d3269cf217e7b788e21042374936b885bf23ee4f9e03babbe4e08db283dfc2a6e052a8a5ba133717dd5","up":true},{"one":"74d84cfdaf32cd4cc67771f29878f1365120bd65cc14848008d5386a81f495bf88eb4132fa38a2cc109ae1e7f02c9b97597ab9d1a9c19c945e710ab9df07cdcd","other":"4ff66e9b5d3fd345990bd7605bdc222b78946f0c13b72bf80352812b2426d8f1d36c93e6c8713566004615e8a78ecab12ab0cfba254c0967eeecf8875b25bdae","up":true},{"one":"c665a6b1b7ad39b86bd4b1fe38b7ee95a0fbb1db15e91381ec9e5a235e33b69ffdc92c60dafd74b7b4dafca1b000e9274bf045abe5b93b1a9c2b31ae071a9898","other":"f38a9d792173a29c61389f5d84c005d78eac6e750659aad42e2d6df883f04eb3126b2c38fac95076eeed455b2031aaf694143922aa93a2d50412a2454dc56e28","up":true},{"one":"979838eaefcff456cf1cd9c47ea46854704f5757d8d7ab907019bc422b01af4d62252579bf045d143fab491b0bab823190e2782a457fbf51aa99ae17ec9e145f","other":"7bbb3f3ed51cf84c077806fbd6d3578e105bc32aa6043da188793f066ad6df383a9f7cc0bd3124f4c887704bd188d480ce264fcdf178905bbda3b270927ea138","up":true},{"one":"6b4e376e9c94242b6d42688c22aa9ab418cb6dfb1cbca1c69de0feceec8d3af29fb005017aaa6e503cc0c03cf0dc5bcab55e01cd6f64b9efa02ed87c03020003","other":"4ff66e9b5d3fd345990bd7605bdc222b78946f0c13b72bf80352812b2426d8f1d36c93e6c8713566004615e8a78ecab12ab0cfba254c0967eeecf8875b25bdae","up":true},{"one":"df54af3bae257d437c5657905484e0d72e9560c46f8ba6b3437730234e05259b404cca40b0831e911605ff8a68a19e8fd7e958069ec8b40595928892f4fa220c","other":"abd8f5a4d700c06ec00684b23d2d25c4df1a9554fcfc57b0ddc3fa476e6a699ba75e1213449f900803f83ab8194c6746664b547202047f35b8b3e216c7147bf8","up":true},{"one":"5df58ba12334a1b4f983d642fe435901261767cd81f8f37c43e359f5584664e4d287e8c2275995604a3b3a4823418e35cd899a3db2a7db31570e19512f375481","other":"d9bbcdfd949010e6b2cbf6d0f34b27593ae410bdc1838876aeca35679571fe431d040a5ab085c0a77f111688bebed891da3587277cd794702437cb20d6aa4256","up":true},{"one":"e2e0419a41bdfc5bd76deae2ddce6ac865f886d764c9bd18799b79fa3b2b6ba66d765d26da2037e98317e1d7e8232a61e63c1d0cfa98c9137424151b46e07171","other":"7acddc7fb6ac587b7e343804c768e4291cd28dd2b2b9207dea6ee82360d848a52d84f94e4c49e9c421f4f90e2d24f6291e2358783ab0230e6ecde82e69b4ac52","up":true},{"one":"2e42f845d0393d1682add54ee30b60a953ed283e75d347bc6719ae0e91f6676282e7960f1fd52e5803d6b341fb3582c724b4f9cfd7bce9ce85f13ca480c7e72e","other":"b35f418c7935cc54278e90978c3ef1521ab91daeaf9f1ebc1cd25211611ade091cac4e1f009d71059279d507322a4536501980ac0dd44caddc52fd4c593879f7","up":false},{"one":"d7a319f69013b8375e64d19f015547462c84565b882337998f9e669c5fadd3d2ecf6374109903003e09f5d453424b5c7fdf52163d2cc8084cf81f94844946b63","other":"4f5ab12b9c5127c16739ad0d4f51adce90ba6736cd096eb185ea632789f4b26f1ebabdea4fd3b39dda5409ece6c2d92fd469cf4aecf9d29453e3e042c19b893b","up":true},{"one":"2bfba66ec9d63e928d77d455f2e10a14d6213e515099d5db14fa44a8bfc147eb0fa7afa9aaccdc86453c6903b55556059a2e13dd61fc494127d4a3ec173bf9ea","other":"a7507aa5665e165ab2e2a07def272f0677f9d6d35bb82268a34214384e7d8ef7635a299368752e63cfd02d4e60231076baf23cfa10d17492e55181b391ecf335","up":true},{"one":"4a030ebcb1a59230759d25a3c87daed22906b520d55a78eab2083bb52358ddc3a5d2d7c3265e6c54a990bf32d0dacb85905a4173d72ac18fcd74c43ecb8635c5","other":"094f9d0fd3bacb17ac67a2edb8ed394fbbd1c8d478233d3269cf217e7b788e21042374936b885bf23ee4f9e03babbe4e08db283dfc2a6e052a8a5ba133717dd5","up":true},{"one":"e1ecad3beeb6c19dce551e4a603c7b440b4498c44e298dc67bfaf4ed2c75bbea95df48b1cd1318e2ccb962cbae7c30ff258e73f8c3fc6b7e9ae7a47f7cf8e53c","other":"2ac93c31937ca205d61cc5c2a1b9037871cac55e9b306b999b28e19566b3316f6539455e014840ea50c2db8a7c97d78804d3a2dcd7cd9c1f32ace0d36e5dd339","up":true},{"one":"831cde5b651ba327b059da4c7f84b184bdd6bb99c6690ae816affe25d42c6c3dbe5b59e2b6bf23e9d0f6c485bd341ea57ba1a8220d18b0a40e156b77d84f79ef","other":"11d560045536e9d1b0b1b9e8944e00f0ca7f1e6788c9fdb51061820bbb3008ead92bb7836621bf58da7035c87a28328faecb4cb2e3cdb9d7fa4f45790e6bf352","up":true},{"one":"71f89efcf939294bb94ac669c8afd00def58c8dfad519c226adfa068692d588ef797116d42aa146b9d34f3be35ec7c014022640ab3c0f1f9034e44ab1a26e246","other":"094f9d0fd3bacb17ac67a2edb8ed394fbbd1c8d478233d3269cf217e7b788e21042374936b885bf23ee4f9e03babbe4e08db283dfc2a6e052a8a5ba133717dd5","up":true},{"one":"1d0244a13affe60996fe3cf51ba624adc746de0c7ea68ec5a31311a36077c5b5495e3d95c9642875db44c7ecae6ffed22e45f2e2d024d486760be2af9f4cf2cd","other":"e6779e3bbecf81dde8b27d652ed2726c45c205db0d0405c4580014a4c91d739830276f77079108c98ac516ffa00194e77a0795f7140bdf36069b6475e58213f9","up":true},{"one":"9194a3a4c8f3235203e48bdb10902d958d26c342805ea6365af9711213536509719d917c694f9a4fbdde6889a4c92299a5301f0275bda4dbcd2541b5bff5b271","other":"23f9bdc82efbf57d3d40a1f2617d0311678fb4a3d6a50cb7e608c649bb618124a76c7ffd17387de963e1cd28d2bd5a61c98613f6e009a8a2a90d989827b35de0","up":false},{"one":"1090e9d89cb278a30063a5396d9ba795d3bbc237c76915a6fb7d23aa1822c8535d2fccc44cc8cd2acec68444c0bf1bdf5195ebb9f3cad8dac3d94a4d9c0e5309","other":"40bdac599b00e9c41ad6476ee415c33d9c17c5aa672692c2404e523b29dc315da929a86874bed87fd9009871805d1dbf3098e7a817193e3b08a6eee66346da79","up":true},{"one":"e3c8a97a2d95dd543f9e2b41d9dce6256e284296f866f4f92e9925f8c7519dea23fd6d1a11153b93c10d6a32295e7b9bcc16024e690e4a0dc84fd25ee0f31b2c","other":"420b9c90584651c5a3fe3c16aa377444a321dca934f8a097d01a616554067feabebf2fdc8d2a25797f29a8fef30d5e2c82f8e85b20f509a880367b9b0ccdea47","up":true},{"one":"2ddd49fae11d8bd2e7e75a481be267fa846f51cc1160bc326aeea51c542323ff444909de11e2731e835140bc0b1b32020e1e73fa652511a381222bf0aebc4081","other":"bcf8e831821a5bca359fb824c7dc4d66906de82f3663a0a853d96880a8ca0bdddcceb1b66dd1f13f75ee20fde50fc9de545bc25767f228baee910e0dbfa8cc27","up":true},{"one":"7f357b8d81bc2e5c6fcb081f23a42b3e2439f050d45c45851994a268d1c71fcb1f39f8c3f75ce921d3fbf80fc0e73f0b9609d72001dc4a6b65b526d312a4f43a","other":"aacff366e601e072a2113add9020e19b6612f3e85b6e607fdc8cc1b6991f43be0b1f835ed3dc41d1f2b3e0caf7fac252c8eb4c150667d48207fa92ea5f0a7455","up":true},{"one":"934a5fe1b91c1891ef4df7f67c027e0eb115d4c2ca4a1b76a135ebd4315c4fb835d6625223194e6a134407b38b0d3928fbc7bc924a3c6a538989a6cf200bf4bd","other":"292c78c8e41606e98428096bc6f4609a7aa48e5c4d17eecc64d65faae4a7270b0c15f0cd74274015688ea0a9aff34f215c29118222e362a29c8d637963973a55","up":true},{"one":"ce0a09bb6fe4c9c93c3dbd800ca9c9ac0714f26a8f8dac2149b6ce7a9011912a5621ea2e45de35c4d31dfe5add00558fdba5dd21acf2d81ba391e82b5b3a5804","other":"8ca3b63cb84f1e9883d82809a9b6777ec1029ecda96fe93b4d494ee9cbefcad13f381b3e480136e542e01054fe1ede66c65db84a0009871ce49383db461c8438","up":true},{"one":"155e4879643a472420012e040a87dbff776fc1976814c0c6cd0d5e157f0d0baac04aa7f2535786c09acc2700547383d2119b64a6f62115f1aff1708738844d8c","other":"ca1aff0d847c6fdacb623ad9078a0885b3208614fea20d5ff11779779b486bf5e9c794aacf848d3c2d58cfcc1eda8356df82f5fbdd0a5236beffe8e6042848c4","up":true},{"one":"4de378164d77a28c90cf162dd1b465e0282ee17aa7d3bb3179252466f72da33a36c9f298f7c9498e38dba4018e7ce3e5fe631c83842cd9059e23a7fece366d87","other":"ca1aff0d847c6fdacb623ad9078a0885b3208614fea20d5ff11779779b486bf5e9c794aacf848d3c2d58cfcc1eda8356df82f5fbdd0a5236beffe8e6042848c4","up":true},{"one":"62dab8b21640e1b44dea452dd7e7de93f27a44840da72d56b11aa96e8463f3a4bb15e75a954d19fc897ae0030b16181d271b79d8198b7cffcddaa9ffcfdcce73","other":"a608a746f46d4b2e9267c65283380d6d6cb8885a64428fb77df9934bcf4dd1723587ee7c8f4a642dce266a12a6a4cf4e5c6db7fa1024158425a6753e7ab7264c","up":true},{"one":"e2a27dcdee1f89fa362a85c4397840cd8be4ad8d1b9ccb23188c303bcab7619f38772f71385922d090390973b62fb8249efc103f71bc761041bcb3880ec0b935","other":"72e30d4562673c5c8fb03709d93f73322747858d723b7eb5ef2fbb88e0331252946b7e93ffe434fcb599c4fff57800afb29e6c60a719f18f49dba541c3591c6e","up":true},{"one":"aa9a94d6e4eaaed20113c21752c224e3a052abd3769bd6e832759dbaf5154a943cf094eacdcb0727c2fe51a11bd7fc0793d7d5e3312b0aba89d428a00e1fde0c","other":"b6a998dea59194cc60ce97c7c9702368411889cb6905516b23f41cc5116fba8d0f237d418318eb0c333cad18003c0e9a6bd8c99080520771f2bad640e2e5ec1c","up":true},{"one":"68cc8b9a995eef6170abf88bd5fedca06ffcc8d75f247f6041c13e7dfd292727ebda1ff86b776e33b6634355c55e0f8c22fcdb5f9a6e2f22fe1af7854c3b4273","other":"f6ca39b3ad803e99f4e4e9cf759fff6abdf06e6972bdbe524f6eb930c669d6f0e9b91f3de9df394b0d661b068273861391bdbac948ad911351c48cf02f874db6","up":true},{"one":"be514f5f17f3177235acb24112b578edf0e373c469073226e547d18080905fd062d572be18e943f13bf9fcf5871e89ceb630a1b848a0e370ef8ef8c6d997a363","other":"1b6cad4f9851cc584c5d1405f976bb51a52e27ef4525847df543dcca65ca5eb1ef229dcc68ccbaaf00ab1e044cb5990dd213c805bdb4adcceb6fa70b5c61fdb4","up":true},{"one":"df4c3505e09e1baa88470117b964e758c94f77a4546489ab5ab7f4aebfdce424729ace8867475715fb68f05c66c9674a5767549e266c4fadd1c703ddd735908f","other":"ea57884dd42aec5a76eab43483bf7c4ae2c19eebf365013731de64494d10a3b4cfe34c86c79437f9012bc8cf6bd761435eefadec17600f4b9e4bc234532d6282","up":true},{"one":"049a2b0ab4d49789dbbe1837e2d2ee5220a9401729ea87ab29385b24d79cdce255c3d2b5de6484d49ca6ce07bd41832598260c0a8c290e01d133d77f066f2f99","other":"ed6c793eb4565aa9d883a76fad6c97ad0b878b9ef0235e11e89db1af25a9653205f725c6ea258b84bde134f1a6437c6d109b859d17509e5016c4ab98be59032a","up":true},{"one":"ff6f94005d1df7677600069764855c1c2aa0543cbe9f480f8feefec76c49d9e2c7bb2d8e38c89e9430f53f8b593d93f143c45985a56a5a32c736128214c95eda","other":"8dd8ad560af84bec579cadb33d51711aa61b6ed22705010336df5a71a94591173b25e869457429c4a199b205fce8e73530e28203e18b971c2001715e610f152a","up":true},{"one":"1bc1d6155ba35d29ea16938994e08df76ebd8f16bd180bd6a9b9d8798d0745889fe72d641dd78bd8ec13526929f7eb5aaa6a388430fa69033d6db581e53c6422","other":"4b784f072b7c96c30612767425f552e30e45157e70139dfbe0ae4ff86dc31601adec60f8a3ad9747b02b5219073d8813af9b09d59eaf7ddb7ee24856aff6fa8f","up":true},{"one":"88d5c5fe61ee1e6fa5878e0eaa13bdabaa0ec3d38a5d25b95a467da7627424f25fb5d30535aa0a5ad01c16fe2598dbf570b78cc152a7f4ef66d46fc9ae43592f","other":"24662a43944228e4ff74736bcf0a0a4f79c87ecfdb739225b2fc45110c11bfc38aaf2d09d98e5817477848e553f187ac5408bdb864518dfa7f5df542768828db","up":true},{"one":"23f9bdc82efbf57d3d40a1f2617d0311678fb4a3d6a50cb7e608c649bb618124a76c7ffd17387de963e1cd28d2bd5a61c98613f6e009a8a2a90d989827b35de0","other":"88d5c5fe61ee1e6fa5878e0eaa13bdabaa0ec3d38a5d25b95a467da7627424f25fb5d30535aa0a5ad01c16fe2598dbf570b78cc152a7f4ef66d46fc9ae43592f","up":true},{"one":"083e67bb19e30d14e4df6d2483367d6659d9b56744d53d9cf7fd15954c327e1bc88a5d0db8833634e1dad7209164451f8934b59f76b5990059261abfd650519a","other":"9194a3a4c8f3235203e48bdb10902d958d26c342805ea6365af9711213536509719d917c694f9a4fbdde6889a4c92299a5301f0275bda4dbcd2541b5bff5b271","up":true},{"one":"53df9cce9b0169e58ced53a123d1d8f6e8fdcfb4c2d781ecbb91bb7c8eba36946dd9d21c749259769825d8a6b3faa6bb87c8c6085a522f8a3e376061f59144d9","other":"4ee37acec2178ef120166265aaa2b64b09b315fb53861405ef46f2503c273eb9692e9cb4c2e67a8652254d430fd6e02dd3fe4cded20bb231a9fb834d292b0b24","up":true},{"one":"4fe37f2dfb03707c90a6fe91dbcfd7497db70ffc20043091d50e1cee573210c144e8749340f2c3cb70fe8fc51b317d49e8734dc51ce64b3cdccdd639ae35d1ae","other":"7e2b0b4f3b55e97bd7241b984ad117af33bf3baacd22b3ed503a8a59f75828df745fb3ce3be4276d83eb484e64d9aa251103fa994ef119eaddb97a3503b9f292","up":true},{"one":"acb4088c27ee2ee130ece3506596432afdb9e9757ec11ebdd35c5a6e87239545c48466913a646980104c8fd7a9a335e177f04efffe9dc952dfd7cd5c1bb9aac6","other":"62666b24d1026345349edb6a878cdc27d6fee8254e83f79a298ce2805260d97aa46423deae440f86ced5cd99b30e970c8e1ea1046752b17d8c80dc68d9a49b60","up":true},{"one":"2ab9513899c3c829b6284e56bf2b9862dd0156ec052b58615dba77d450dac642e534ec36ae5d3234262aff54e19f99856e908b9d8c1da660a7834a445610715b","other":"7865b82e44add2cea6ebcbaba9c152184331a2940fe73f6f9bb940bda8a59ab4cf4760894b9cadcaa54e36fbb712ad619346a49a85e32cdf2b53cda1ac1e0658","up":false},{"one":"8c6d77833bf1a98beabe7a92d985d13d52fb2e50768719ffbc6fce21ea676802a074b6e620b3ef80e12fad04f94a3c288d91df9716a6cfae09ef073b9dc1f2cb","other":"0b30b36e155db04c448b662c4df695068b2331cdbe2772aae5fda84159e977515a5ff2e156bc225a9281fef2383926ba8cb11e9c1846fb40db241e524ac14e29","up":true},{"one":"fe8ac5d33cd8ab6a1dad9567cdfb89b431a5c4f4a584fc608b92e7dfd06f70988e71e2f11f9fda9ee797c9ffba83bc085939fdf2522dde39f28202be92650566","other":"a127faa19dcb7da585983d36a8e9d3e9a44a6db68507b60c70da71011f44ce377944802f39cd65f5a705cd8249ac1ef7ed8fd699349098f3f8e23b37592c80ae","up":true},{"one":"420b9c90584651c5a3fe3c16aa377444a321dca934f8a097d01a616554067feabebf2fdc8d2a25797f29a8fef30d5e2c82f8e85b20f509a880367b9b0ccdea47","other":"bcf8e831821a5bca359fb824c7dc4d66906de82f3663a0a853d96880a8ca0bdddcceb1b66dd1f13f75ee20fde50fc9de545bc25767f228baee910e0dbfa8cc27","up":true},{"one":"ae2a996d3b562cb47a564934037949da83b1bfe194c23754f3dbe2372ec27654f4f3b6cb7f394570f308025589c065870477667e5560dbe5a8ea1625740699cf","other":"59b53f8a562bee519276e0eeccfcf8c975d3102f5d0cccf5abcce291a8a5bb817c04604f123686177a50a03b9d7559ac469962d0159d1d93e4ce58a304d04b55","up":true},{"one":"62666b24d1026345349edb6a878cdc27d6fee8254e83f79a298ce2805260d97aa46423deae440f86ced5cd99b30e970c8e1ea1046752b17d8c80dc68d9a49b60","other":"c83985973a9564ade7d90aa54911ac57077600676a1d27292d98e058bf1315887bad84ccd708cb7f52a695a1405fb7d491d7ca2ae9caa3ff58a5ad78ce4dc9d9","up":true},{"one":"3612863ce0456c91785a829bf5c9d2b2fb97dda083a1847e5a4ebaa6fce1260faf4d1eb374c2225431a82774163835fb59c8cb0fa9fc0969eab5410c71109cc2","other":"c83985973a9564ade7d90aa54911ac57077600676a1d27292d98e058bf1315887bad84ccd708cb7f52a695a1405fb7d491d7ca2ae9caa3ff58a5ad78ce4dc9d9","up":true},{"one":"b4fd11306b1416a9bcf4719578976188e104b8c5028b9abd3214d257446b97b70a22e6c00934d80caddde15e8e4d16af03bb399583047983fba373d8313226b7","other":"7865b82e44add2cea6ebcbaba9c152184331a2940fe73f6f9bb940bda8a59ab4cf4760894b9cadcaa54e36fbb712ad619346a49a85e32cdf2b53cda1ac1e0658","up":true},{"one":"7bbb3f3ed51cf84c077806fbd6d3578e105bc32aa6043da188793f066ad6df383a9f7cc0bd3124f4c887704bd188d480ce264fcdf178905bbda3b270927ea138","other":"70ee3c7e02a123f78345d41c386e413f06b51f1ab346c2c472891eed7dd26a1f14e213a0f4f2d872859b9b535936a6d9b072d2604456f76221a422710411822f","up":true},{"one":"7b35c856916eb3fc1b1f451667e240b95aff8f4731cc0f6743740923081ff1ddf2eec81bdccf4691a7bcc053d23eacfc15809c384a73448f618317bf605bd1cd","other":"a08e47137bf611dfbd20308a22bdd3ca00121386f121d6d712ade86e9a1601a4237766887cd91c8516e20b6e323d2ef49c1c7e177a0afb4c813f0f344daf779b","up":true},{"one":"db8ba71afeaea1f2964e8978a6eceeb9efa3958424424022213c8193443f8d5afd18490afa954c76360c681404809c7cfaf7e4ebd8bd1a42d403f7f1915b0d29","other":"beec648d79437a5d7b4140ced45d82d035c6f64f9c67c58386703811d97c3846787eaf274d2298df809475f0b7519df696563cb8e9a5fb0a9cc419ab13fa8d41","up":true},{"one":"f039df8a3206e6e17eee8e95010038c450cb4cc0b5580ed5795d4c21802e1e9d360f4528bdca794f457932b1d6a818862ec847357a861c488332ef6d9480daa6","other":"65e954e60837bda10654480b227fa3bcc6e63356c52079002a27e836cd82ae2934ba77da60080e4b9f2d9324b982b24959bfd9624302e6c330408381054b43e9","up":true},{"one":"c903c5ee3d9cd65bea3ea777e39282c33e1349d945411fb2f16321bf582c2f400956a98fbafe5873fc5f6f6a9a051df5da7e94cbd340f935abe80f91e79ef875","other":"4e95fb8943ef6502fa470870a7ace4ca11e18589bd2073167543a922317b35e40b5068934d07e56c8fdd23354dfad51fd2899db854f189841f02b5914cd97749","up":false},{"one":"b137cf2291b530a39516d882200848e7f27a2710e0839b4d25b4f367bea6a0c3aaef8c7c7851c00a2945adcd819ea0508610afc1f453b8bc512b7b4d4faacdf3","other":"b35f418c7935cc54278e90978c3ef1521ab91daeaf9f1ebc1cd25211611ade091cac4e1f009d71059279d507322a4536501980ac0dd44caddc52fd4c593879f7","up":false},{"one":"5bae82d4832092c17bd11474f7748015b8b69b896ab8f683a7c0024fc98740cecbb9e31c6275269f9000e5bfe51d7f45cd5dcd4433e0c87b5741685b40fe3983","other":"292c78c8e41606e98428096bc6f4609a7aa48e5c4d17eecc64d65faae4a7270b0c15f0cd74274015688ea0a9aff34f215c29118222e362a29c8d637963973a55","up":false},{"one":"4ff66e9b5d3fd345990bd7605bdc222b78946f0c13b72bf80352812b2426d8f1d36c93e6c8713566004615e8a78ecab12ab0cfba254c0967eeecf8875b25bdae","other":"4a030ebcb1a59230759d25a3c87daed22906b520d55a78eab2083bb52358ddc3a5d2d7c3265e6c54a990bf32d0dacb85905a4173d72ac18fcd74c43ecb8635c5","up":true},{"one":"adfba6d883cacbb141cd8c59ee04d7e5d520f1ce31a81e5db2d8b2380bf801c1fe4b265a66b71f9643d13a41cb1f6fb4b83399be786da4b6e171b6784bc56e49","other":"a7507aa5665e165ab2e2a07def272f0677f9d6d35bb82268a34214384e7d8ef7635a299368752e63cfd02d4e60231076baf23cfa10d17492e55181b391ecf335","up":true},{"one":"7646d08b3e24183e3814de130235c41eb88a5a2abff23eaff3c91954ad3ef55fe27da422dac5b894312276bf1a2f1aebb8b636a8d4a0c93d9b016d441df3fa19","other":"4ff66e9b5d3fd345990bd7605bdc222b78946f0c13b72bf80352812b2426d8f1d36c93e6c8713566004615e8a78ecab12ab0cfba254c0967eeecf8875b25bdae","up":true},{"one":"109556abac422a912ecffec0d8796f8f16e92e8f95cecf72dc89e97a8bf1fd37aad3c66aa3cf134acade6d065c31821f977171d5c5463305b57ce3eee99a7ab4","other":"deb7af800cd20a647335f0feff5bfb3e182f99f4c2d1ade10da36ecfdbac3b5fba4e8f0a4595443fe395b44af3a95617669850944655def85d57cc81c5682a3b","up":true},{"one":"759f46661056bcbb30c7706c9fb87e22a30feb523bd53ae5d18db043efa45b49a2b8982abebdd598fe0912a05896390ec2eabe5e160cbafc0771990708ad8c28","other":"c57ea182bdb42ba9b0870b5c870e467f52693e5c0df752fb6eb0dfbacce7763f73caee10db40f4fd90f19f504ee586eaf9da41f5ee93ee515d885fec99374116","up":false},{"one":"e0f78c59a61f2a953553cd5742c58f4a82e38e35ac7eaa237a6ffc9fb0a3a26a2d1d1afae249e611d1320f2cb25804bdbdfb6d77336449716b0f4beb3298b8aa","other":"094f9d0fd3bacb17ac67a2edb8ed394fbbd1c8d478233d3269cf217e7b788e21042374936b885bf23ee4f9e03babbe4e08db283dfc2a6e052a8a5ba133717dd5","up":true},{"one":"deb7af800cd20a647335f0feff5bfb3e182f99f4c2d1ade10da36ecfdbac3b5fba4e8f0a4595443fe395b44af3a95617669850944655def85d57cc81c5682a3b","other":"155e4879643a472420012e040a87dbff776fc1976814c0c6cd0d5e157f0d0baac04aa7f2535786c09acc2700547383d2119b64a6f62115f1aff1708738844d8c","up":true},{"one":"453779010ed7c59761da47ccd8869d3fa8349795e57edb9eea416c0712301ea622c7683858e309d19ab137ddb0edef161d0d00a361abeecf0628c3ffabc629ea","other":"3dfd733dde9414af916625ab981777ff1ad7ca0f6d1e4e7d9e2739969e21182fd13d85e281868653e7325b20069356b11524b54143c47fd3955a911cf7325ad4","up":true},{"one":"b597c9ba4da20c49fc4ba019571321d2579588636cdaceb9f225706574970adbf4771dcf186b1decd4e14cd5d257e30a36ca829829598c1775902201ad9793e2","other":"fe62314839c93d2f6e3aee984d5f0b321897c6f39e66800d3de8b773baf6f19e0a03cae025df512aea8d5f1b667b6dbb15c192a90a76d3031c14e33e5c16c4f7","up":true},{"one":"302c37f28c69fdcf00b39ce0c0223de0d94cebc2c0b068315b95b76b5432573ead0656569441029ba9054d8d3d959fd8735e73913af5ce3f1132f8271fd437ef","other":"5420da16f7ed5de6b498dbc9a83b7e92e1f9900a6d04ef7351a0bfdfd442b98a5634f28fcea32ba3f3166d21c8ff5a39be70895b32acbdf7592d1d616a345a21","up":true},{"one":"a99852c5bf08ea4713af9cade5343d1259bfb90401aca7fcff18c58cd56a98804dd16c61fea71039c0ac31b9bbbb9dc5aeaf0c2f074d3365e88d17031802d636","other":"c73d088ade8756c74832c73542bcdb3e52f670f7a74ad3a7eac2a9e3ece6bd081f782a8e1d3f9a40b9aa9201509110f37fc57fcb10ee1ef3ef07b7eab019782e","up":true},{"one":"ddaf3f8478501cda872c056c72063eb64d5b871fc5fff70704872802289dd2d348f73bc342b7f148a90cfaae2448ebf16fea196be9df891dc71a57fb410d59dd","other":"2f360209383d6de4ebd3b4abaf77796520b8654270b03f2151eac4a01b4417d7e0668c1f9ad30c20ff49aa8a0ab33dba5e6095619d1cf04b7af841722ab773da","up":true},{"one":"7b5c0e81c7f4e3ae29d745f6028cfa10b29a16a9c261b65fb8dd05d6eccc634612ad5d3029c8e9f39863a2cdb2682c25f090139bf5c4950e25647e39dcb40e63","other":"eab86c521f8f1ac67c015ab713f1236a08b0200757a96bf87ab8301e7967ae62361f0e14da14ca294fc8cb3b4726b52f4773101e21b032977c6a647241b59c73","up":true},{"one":"ca1aff0d847c6fdacb623ad9078a0885b3208614fea20d5ff11779779b486bf5e9c794aacf848d3c2d58cfcc1eda8356df82f5fbdd0a5236beffe8e6042848c4","other":"7b1e20217f594f87350542df31ff5ae8a635679bac7962d49c97e02190c644b673d03e7eba2626b45ca7ebf98d8a972dadbba02c18a8d2cbfc3e7a4cced5b4b7","up":true},{"one":"b35f418c7935cc54278e90978c3ef1521ab91daeaf9f1ebc1cd25211611ade091cac4e1f009d71059279d507322a4536501980ac0dd44caddc52fd4c593879f7","other":"f915e2398aa5d4370de87504dd76c21a7d0be2581c2ab55b7a47743f1bbaef36384eaacec22760f1e914ceac9d96a10c3d66eb27475ef444e77fee979e6e88cb","up":true},{"one":"4e95fb8943ef6502fa470870a7ace4ca11e18589bd2073167543a922317b35e40b5068934d07e56c8fdd23354dfad51fd2899db854f189841f02b5914cd97749","other":"1bc1d6155ba35d29ea16938994e08df76ebd8f16bd180bd6a9b9d8798d0745889fe72d641dd78bd8ec13526929f7eb5aaa6a388430fa69033d6db581e53c6422","up":true},{"one":"663535b22018a4ef0b151572ef286fa66c22c6e9b2913a69c4a735d4b0149bdf6c84bd83d710f8aa2627e8993b7f020750fbc6f56a3365ce4c840e2b3de1a6c1","other":"e6779e3bbecf81dde8b27d652ed2726c45c205db0d0405c4580014a4c91d739830276f77079108c98ac516ffa00194e77a0795f7140bdf36069b6475e58213f9","up":true},{"one":"cb310c0e86aa455d7c9af6394ae38561c901da30a51d7ccb7e66a09d9a8f192ae8caeff106043426d56397088f141c4e01e3b98f1ee583ffc7318b5f730f3ac7","other":"40bdac599b00e9c41ad6476ee415c33d9c17c5aa672692c2404e523b29dc315da929a86874bed87fd9009871805d1dbf3098e7a817193e3b08a6eee66346da79","up":true},{"one":"28d3232c43de54ffdaf08f97b334c012738648b04e2876c7e751a2e352aaf4d550d6efa976c5a8edbfa8e88b9d04a0fca492b81c3756ef673ab74d34182ca711","other":"2f360209383d6de4ebd3b4abaf77796520b8654270b03f2151eac4a01b4417d7e0668c1f9ad30c20ff49aa8a0ab33dba5e6095619d1cf04b7af841722ab773da","up":true},{"one":"2f903b2fd4f9432b7d91b5c3e4c7ee3cb9c56fe7efc4baff0edd06fc75e4b7492f2c3c929755746df59c9f95d437a12ba40ac138d08f5bc7aa091f49f3b852c2","other":"d4b7c787981abec24353c7d496661692233797e3758189bf909a69fe87935bf6da0940daa4f12e81f20c5e88f70b472113688b71a0ae2f91a73ee0e6ff4c8591","up":true},{"one":"28d3232c43de54ffdaf08f97b334c012738648b04e2876c7e751a2e352aaf4d550d6efa976c5a8edbfa8e88b9d04a0fca492b81c3756ef673ab74d34182ca711","other":"66d0c5da973d9dd65350ae1ec63776872cdb7ded6afb6f51ae82259f6fd35e884375d15de290625f02ed2e5cdc3f591decb45e5fc64d5b0f835a216fd196f5a3","up":true},{"one":"1b6cad4f9851cc584c5d1405f976bb51a52e27ef4525847df543dcca65ca5eb1ef229dcc68ccbaaf00ab1e044cb5990dd213c805bdb4adcceb6fa70b5c61fdb4","other":"59b53f8a562bee519276e0eeccfcf8c975d3102f5d0cccf5abcce291a8a5bb817c04604f123686177a50a03b9d7559ac469962d0159d1d93e4ce58a304d04b55","up":true},{"one":"b26f7c0113a5ae885f7c0e608aea7022a9c8bfc40c5643e60b2ba7343ff09c5be0bc08be34dde3c6b85fea192a46d4764770c12cbaa233df4231a1b99627ef9d","other":"807340e5fdf6c21a56ef2fd158c32e92201206ca85fcc147165a408f7a735964afd47c397e663610ac53870ae722c0317291732b0422f8aeedae783d9c730218","up":true},{"one":"1944f98d4db32c56a5efda5a79aa5f276bfab1e084d6611fec0e735b8bc0f45b457cdb74a23fc83b2377821fa8316123c9877acd6db7c41058ca5d3cfedaecf9","other":"92d6ef729992f0de886076e5f8cdc42cbbd70b29e79c25e0b3d22b6575d3d2508d47b42f581e335455483d43625bce4e55f88cab9ff2073ee8dab746357864fd","up":true},{"one":"5e86f39cf8338ba098a85d41e601a303fde311662b216ad32a2b7bfaf2b2b6dd1af3775784b39f2d85ac5fac96f05f3abdd8a2bd28ba16d939725fd6a33ae1b6","other":"7acddc7fb6ac587b7e343804c768e4291cd28dd2b2b9207dea6ee82360d848a52d84f94e4c49e9c421f4f90e2d24f6291e2358783ab0230e6ecde82e69b4ac52","up":true},{"one":"1b6cad4f9851cc584c5d1405f976bb51a52e27ef4525847df543dcca65ca5eb1ef229dcc68ccbaaf00ab1e044cb5990dd213c805bdb4adcceb6fa70b5c61fdb4","other":"8dd8ad560af84bec579cadb33d51711aa61b6ed22705010336df5a71a94591173b25e869457429c4a199b205fce8e73530e28203e18b971c2001715e610f152a","up":true},{"one":"5df58ba12334a1b4f983d642fe435901261767cd81f8f37c43e359f5584664e4d287e8c2275995604a3b3a4823418e35cd899a3db2a7db31570e19512f375481","other":"abd8f5a4d700c06ec00684b23d2d25c4df1a9554fcfc57b0ddc3fa476e6a699ba75e1213449f900803f83ab8194c6746664b547202047f35b8b3e216c7147bf8","up":true},{"one":"5e86f39cf8338ba098a85d41e601a303fde311662b216ad32a2b7bfaf2b2b6dd1af3775784b39f2d85ac5fac96f05f3abdd8a2bd28ba16d939725fd6a33ae1b6","other":"abd8f5a4d700c06ec00684b23d2d25c4df1a9554fcfc57b0ddc3fa476e6a699ba75e1213449f900803f83ab8194c6746664b547202047f35b8b3e216c7147bf8","up":true},{"one":"1944f98d4db32c56a5efda5a79aa5f276bfab1e084d6611fec0e735b8bc0f45b457cdb74a23fc83b2377821fa8316123c9877acd6db7c41058ca5d3cfedaecf9","other":"57cd4c0048b459192ee46e19ec7df777e600f256e0dc8c3019431eb7bec3c020b9504ec7aea3dba8188658ca5b830ec40af6a8540ce10e04badc6c695d009271","up":true},{"one":"7b1e20217f594f87350542df31ff5ae8a635679bac7962d49c97e02190c644b673d03e7eba2626b45ca7ebf98d8a972dadbba02c18a8d2cbfc3e7a4cced5b4b7","other":"c57ea182bdb42ba9b0870b5c870e467f52693e5c0df752fb6eb0dfbacce7763f73caee10db40f4fd90f19f504ee586eaf9da41f5ee93ee515d885fec99374116","up":true},{"one":"e06a789a7f6988e1ba5e8358b6cd4292555c7f9f7f0dda6fc01cc26d24e49a8c1ad694423ad74aec6d80f4b99e2bedc49b6a5f2670744cedee3a3e1848e6dd07","other":"a7378ee34876af17c6cd94a69b6b741ec7891ff5375bc4241d48608d047455ed48e6baae80ee88d4710c69ae615cf195cee26c94b54de1bb935628ce1e3a723a","up":true},{"one":"7b1e20217f594f87350542df31ff5ae8a635679bac7962d49c97e02190c644b673d03e7eba2626b45ca7ebf98d8a972dadbba02c18a8d2cbfc3e7a4cced5b4b7","other":"eab86c521f8f1ac67c015ab713f1236a08b0200757a96bf87ab8301e7967ae62361f0e14da14ca294fc8cb3b4726b52f4773101e21b032977c6a647241b59c73","up":true},{"one":"a1560ce7c1f1d5972f027a8e9cff820611d84764aa067434a75b63887bc4268a259101486d34b7fe83dd735e799789986cd3e9b156c86ede598bd86af4454924","other":"420b9c90584651c5a3fe3c16aa377444a321dca934f8a097d01a616554067feabebf2fdc8d2a25797f29a8fef30d5e2c82f8e85b20f509a880367b9b0ccdea47","up":true},{"one":"df54af3bae257d437c5657905484e0d72e9560c46f8ba6b3437730234e05259b404cca40b0831e911605ff8a68a19e8fd7e958069ec8b40595928892f4fa220c","other":"0a4eec7b0e05da799aca5b36d9e2530f2a89d1426b1fcb7d8f9a662df8a8b5b763767a20db3c9c63e0bd13c2a6e16d3ba8f03baf84f5e5d24917b3f211d9bcfc","up":true},{"one":"e2e0419a41bdfc5bd76deae2ddce6ac865f886d764c9bd18799b79fa3b2b6ba66d765d26da2037e98317e1d7e8232a61e63c1d0cfa98c9137424151b46e07171","other":"cb321c9b0fe2eb3617b8e2461aab170a9dad2c9b04a10eead4e37e551197ea0a7500eb1cb7b155efe1886486ef3d252d8ff0d309f2906a1126ca011d037da70a","up":true},{"one":"d7a319f69013b8375e64d19f015547462c84565b882337998f9e669c5fadd3d2ecf6374109903003e09f5d453424b5c7fdf52163d2cc8084cf81f94844946b63","other":"7ac5b07eb555af3bb4ca3f0f4b45204d43cc3798c244435909b97d9a32fc3abf0b50666e260e046bce826a7a102a92d389f8f39c5311e83bb34beddac29d50e3","up":true},{"one":"df54af3bae257d437c5657905484e0d72e9560c46f8ba6b3437730234e05259b404cca40b0831e911605ff8a68a19e8fd7e958069ec8b40595928892f4fa220c","other":"9bbbfac8be4a000f51a4ce8d024d2595b5d491afec0138922dddfde5ef62c664040c2e9304cc6b7bc688233b5d0c4644b8c8793227c078285a3ab894ef0497a3","up":true},{"one":"94088fe273f76e62ca4e43c095ad12215b4ae4c59942328b3985416fb19bbda0cacc143a49eff3fb644ad53a19d3f043260e43dbb70a0aa9c15829c21cecd3c7","other":"4f5ab12b9c5127c16739ad0d4f51adce90ba6736cd096eb185ea632789f4b26f1ebabdea4fd3b39dda5409ece6c2d92fd469cf4aecf9d29453e3e042c19b893b","up":true},{"one":"043fe7085e8c90c18270f84dba5fab138e50216a1cf8d81a3794d156fad7fc81d1422aff169b244b13f91d73eebb5de464f97b1b93b3ad2a58959cff19238842","other":"adfba6d883cacbb141cd8c59ee04d7e5d520f1ce31a81e5db2d8b2380bf801c1fe4b265a66b71f9643d13a41cb1f6fb4b83399be786da4b6e171b6784bc56e49","up":true},{"one":"57cd4c0048b459192ee46e19ec7df777e600f256e0dc8c3019431eb7bec3c020b9504ec7aea3dba8188658ca5b830ec40af6a8540ce10e04badc6c695d009271","other":"58cfb20d3da3641e0ad529b9edbd4b590a8d1dc9d1ed7b44ed3187dba9260bd7c732fc10981f5b9bffd31d362cb05150173618aa36138984431d94a323a9b313","up":true},{"one":"92d6ef729992f0de886076e5f8cdc42cbbd70b29e79c25e0b3d22b6575d3d2508d47b42f581e335455483d43625bce4e55f88cab9ff2073ee8dab746357864fd","other":"4ff66e9b5d3fd345990bd7605bdc222b78946f0c13b72bf80352812b2426d8f1d36c93e6c8713566004615e8a78ecab12ab0cfba254c0967eeecf8875b25bdae","up":true},{"one":"043fe7085e8c90c18270f84dba5fab138e50216a1cf8d81a3794d156fad7fc81d1422aff169b244b13f91d73eebb5de464f97b1b93b3ad2a58959cff19238842","other":"e267e71c2dcdbe5a500b23444d2d4037ea15afba8f4f2b1c0e54a274450404fbee6fa5439f7cddf4ba1aa28fa93e434b01c239add58e30a5423ca3a481584d6b","up":true},{"one":"979838eaefcff456cf1cd9c47ea46854704f5757d8d7ab907019bc422b01af4d62252579bf045d143fab491b0bab823190e2782a457fbf51aa99ae17ec9e145f","other":"c332fe1f9b6e25f72c7150631ffa6e0929ff6eeab5d17aa45eaf669bdde869cf404505ae990a529aa3ca797cd0a96f31cc41431a5d4a163132be566f91623c08","up":true},{"one":"ed6c793eb4565aa9d883a76fad6c97ad0b878b9ef0235e11e89db1af25a9653205f725c6ea258b84bde134f1a6437c6d109b859d17509e5016c4ab98be59032a","other":"b4a5efa9028b2d196855393892f79993c2812d02b758f98813ddf82c5d943faf6d66eff811cc5a51936c118f4c768c0d13b54902095e040c602761e63c08655e","up":true},{"one":"9bd4f0adb9a966cc5ba632f1b540fe9cd6c8e39fe1a041b315697679cfb04b735952062ce057d456677cc34a84301f26bb727a4ab2646fee734f80a22c620746","other":"4a030ebcb1a59230759d25a3c87daed22906b520d55a78eab2083bb52358ddc3a5d2d7c3265e6c54a990bf32d0dacb85905a4173d72ac18fcd74c43ecb8635c5","up":true},{"one":"4a030ebcb1a59230759d25a3c87daed22906b520d55a78eab2083bb52358ddc3a5d2d7c3265e6c54a990bf32d0dacb85905a4173d72ac18fcd74c43ecb8635c5","other":"58cfb20d3da3641e0ad529b9edbd4b590a8d1dc9d1ed7b44ed3187dba9260bd7c732fc10981f5b9bffd31d362cb05150173618aa36138984431d94a323a9b313","up":true},{"one":"4a030ebcb1a59230759d25a3c87daed22906b520d55a78eab2083bb52358ddc3a5d2d7c3265e6c54a990bf32d0dacb85905a4173d72ac18fcd74c43ecb8635c5","other":"ba21a373781966135d6225adae024a3f3e421b852f72f8b0569cb92fcff87c33f7e5b799a509b8eff6ec6dc46a9b17d5bae1e91ec7c54c0c712d893d54b140fa","up":true},{"one":"92d6ef729992f0de886076e5f8cdc42cbbd70b29e79c25e0b3d22b6575d3d2508d47b42f581e335455483d43625bce4e55f88cab9ff2073ee8dab746357864fd","other":"9bd4f0adb9a966cc5ba632f1b540fe9cd6c8e39fe1a041b315697679cfb04b735952062ce057d456677cc34a84301f26bb727a4ab2646fee734f80a22c620746","up":true},{"one":"9b59b76dc61223c7b37083b0ebdda22d3599563b3e3986f5db9d5b12f8c806cbdeb2345454efe957cbfa11eea9c7896aefd9a461210524805452ca100a9ea431","other":"e1ecad3beeb6c19dce551e4a603c7b440b4498c44e298dc67bfaf4ed2c75bbea95df48b1cd1318e2ccb962cbae7c30ff258e73f8c3fc6b7e9ae7a47f7cf8e53c","up":true},{"one":"389b5c1a805f87427e6d647ec5488342a3f7d700615943d5ad98ca5c111f33c7ee007970b4d3e475892095c0d5a79b7ed52d12598398818159000d4b9b719126","other":"eab86c521f8f1ac67c015ab713f1236a08b0200757a96bf87ab8301e7967ae62361f0e14da14ca294fc8cb3b4726b52f4773101e21b032977c6a647241b59c73","up":true},{"one":"28d3232c43de54ffdaf08f97b334c012738648b04e2876c7e751a2e352aaf4d550d6efa976c5a8edbfa8e88b9d04a0fca492b81c3756ef673ab74d34182ca711","other":"59b53f8a562bee519276e0eeccfcf8c975d3102f5d0cccf5abcce291a8a5bb817c04604f123686177a50a03b9d7559ac469962d0159d1d93e4ce58a304d04b55","up":true},{"one":"7b1e20217f594f87350542df31ff5ae8a635679bac7962d49c97e02190c644b673d03e7eba2626b45ca7ebf98d8a972dadbba02c18a8d2cbfc3e7a4cced5b4b7","other":"389b5c1a805f87427e6d647ec5488342a3f7d700615943d5ad98ca5c111f33c7ee007970b4d3e475892095c0d5a79b7ed52d12598398818159000d4b9b719126","up":true},{"one":"11d560045536e9d1b0b1b9e8944e00f0ca7f1e6788c9fdb51061820bbb3008ead92bb7836621bf58da7035c87a28328faecb4cb2e3cdb9d7fa4f45790e6bf352","other":"f38a9d792173a29c61389f5d84c005d78eac6e750659aad42e2d6df883f04eb3126b2c38fac95076eeed455b2031aaf694143922aa93a2d50412a2454dc56e28","up":true},{"one":"9bbbfac8be4a000f51a4ce8d024d2595b5d491afec0138922dddfde5ef62c664040c2e9304cc6b7bc688233b5d0c4644b8c8793227c078285a3ab894ef0497a3","other":"e1ecad3beeb6c19dce551e4a603c7b440b4498c44e298dc67bfaf4ed2c75bbea95df48b1cd1318e2ccb962cbae7c30ff258e73f8c3fc6b7e9ae7a47f7cf8e53c","up":true},{"one":"1d0244a13affe60996fe3cf51ba624adc746de0c7ea68ec5a31311a36077c5b5495e3d95c9642875db44c7ecae6ffed22e45f2e2d024d486760be2af9f4cf2cd","other":"2ac93c31937ca205d61cc5c2a1b9037871cac55e9b306b999b28e19566b3316f6539455e014840ea50c2db8a7c97d78804d3a2dcd7cd9c1f32ace0d36e5dd339","up":true},{"one":"7acddc7fb6ac587b7e343804c768e4291cd28dd2b2b9207dea6ee82360d848a52d84f94e4c49e9c421f4f90e2d24f6291e2358783ab0230e6ecde82e69b4ac52","other":"1d0244a13affe60996fe3cf51ba624adc746de0c7ea68ec5a31311a36077c5b5495e3d95c9642875db44c7ecae6ffed22e45f2e2d024d486760be2af9f4cf2cd","up":true},{"one":"389b5c1a805f87427e6d647ec5488342a3f7d700615943d5ad98ca5c111f33c7ee007970b4d3e475892095c0d5a79b7ed52d12598398818159000d4b9b719126","other":"109556abac422a912ecffec0d8796f8f16e92e8f95cecf72dc89e97a8bf1fd37aad3c66aa3cf134acade6d065c31821f977171d5c5463305b57ce3eee99a7ab4","up":true},{"one":"9bbbfac8be4a000f51a4ce8d024d2595b5d491afec0138922dddfde5ef62c664040c2e9304cc6b7bc688233b5d0c4644b8c8793227c078285a3ab894ef0497a3","other":"7acddc7fb6ac587b7e343804c768e4291cd28dd2b2b9207dea6ee82360d848a52d84f94e4c49e9c421f4f90e2d24f6291e2358783ab0230e6ecde82e69b4ac52","up":true},{"one":"4ee37acec2178ef120166265aaa2b64b09b315fb53861405ef46f2503c273eb9692e9cb4c2e67a8652254d430fd6e02dd3fe4cded20bb231a9fb834d292b0b24","other":"5e86f39cf8338ba098a85d41e601a303fde311662b216ad32a2b7bfaf2b2b6dd1af3775784b39f2d85ac5fac96f05f3abdd8a2bd28ba16d939725fd6a33ae1b6","up":true},{"one":"9133b0b3c8f680286eae90c3beebc3099a13de38775a3ff2abdeced62d05eb2ced5ac85eac0870156be03101024da5e1d9fbf3e1066ddb3f088221e64149acec","other":"84abcbc7b5598ecfd91ceace0927921a5a3404fdb274fc2a2549abbede5f8e4f62c15688a4dc9a2d80262c45970c88898da245c6eb779f327a81d53a17bbc74c","up":true},{"one":"e2e0419a41bdfc5bd76deae2ddce6ac865f886d764c9bd18799b79fa3b2b6ba66d765d26da2037e98317e1d7e8232a61e63c1d0cfa98c9137424151b46e07171","other":"1d0244a13affe60996fe3cf51ba624adc746de0c7ea68ec5a31311a36077c5b5495e3d95c9642875db44c7ecae6ffed22e45f2e2d024d486760be2af9f4cf2cd","up":true},{"one":"9b59b76dc61223c7b37083b0ebdda22d3599563b3e3986f5db9d5b12f8c806cbdeb2345454efe957cbfa11eea9c7896aefd9a461210524805452ca100a9ea431","other":"cb321c9b0fe2eb3617b8e2461aab170a9dad2c9b04a10eead4e37e551197ea0a7500eb1cb7b155efe1886486ef3d252d8ff0d309f2906a1126ca011d037da70a","up":true},{"one":"5df58ba12334a1b4f983d642fe435901261767cd81f8f37c43e359f5584664e4d287e8c2275995604a3b3a4823418e35cd899a3db2a7db31570e19512f375481","other":"cb321c9b0fe2eb3617b8e2461aab170a9dad2c9b04a10eead4e37e551197ea0a7500eb1cb7b155efe1886486ef3d252d8ff0d309f2906a1126ca011d037da70a","up":true},{"one":"5e86f39cf8338ba098a85d41e601a303fde311662b216ad32a2b7bfaf2b2b6dd1af3775784b39f2d85ac5fac96f05f3abdd8a2bd28ba16d939725fd6a33ae1b6","other":"cb321c9b0fe2eb3617b8e2461aab170a9dad2c9b04a10eead4e37e551197ea0a7500eb1cb7b155efe1886486ef3d252d8ff0d309f2906a1126ca011d037da70a","up":true},{"one":"cb94a8270d0050378116b5815ff17dafbe20f5303839c4fd57b981d4687a4b145e4bccec7e9af9b9475005930148ffbfa97781a0762c8e9f352dc95565fc8732","other":"57fb1bb32bb2b1a87e44c6a7557e9c47c2032d107bcb0e34acd9ffd54d5d3df5701232db16f62f7549ba2721021898b03160b1dc5201e79606648c1dbc4a373b","up":true},{"one":"9133b0b3c8f680286eae90c3beebc3099a13de38775a3ff2abdeced62d05eb2ced5ac85eac0870156be03101024da5e1d9fbf3e1066ddb3f088221e64149acec","other":"d9bbcdfd949010e6b2cbf6d0f34b27593ae410bdc1838876aeca35679571fe431d040a5ab085c0a77f111688bebed891da3587277cd794702437cb20d6aa4256","up":true},{"one":"4ee37acec2178ef120166265aaa2b64b09b315fb53861405ef46f2503c273eb9692e9cb4c2e67a8652254d430fd6e02dd3fe4cded20bb231a9fb834d292b0b24","other":"e2e0419a41bdfc5bd76deae2ddce6ac865f886d764c9bd18799b79fa3b2b6ba66d765d26da2037e98317e1d7e8232a61e63c1d0cfa98c9137424151b46e07171","up":true},{"one":"2bfba66ec9d63e928d77d455f2e10a14d6213e515099d5db14fa44a8bfc147eb0fa7afa9aaccdc86453c6903b55556059a2e13dd61fc494127d4a3ec173bf9ea","other":"ed6c793eb4565aa9d883a76fad6c97ad0b878b9ef0235e11e89db1af25a9653205f725c6ea258b84bde134f1a6437c6d109b859d17509e5016c4ab98be59032a","up":true},{"one":"07c63ca5d0309e30d1ab12e7fc142e6d37904b552639cfa97850161491f28f20d87e0304be29357bcfc2ff52fc52fd0d4f6e6011ebb239cced8b5c8dad7abf45","other":"84dfd4e4d9f1204893f190eacc4c3999e175c433f70de86e335d27477c097a0552f211a21764f01a708da4c9e9e6552191a61d3e48f41d0e84f01e7ae3beb34e","up":true},{"one":"016f8f4619a16a07fbde5a18e362158d696e4d9f104a77787f26e32a25cd7d278256f8e0db865c488a99511ec27a5eddd5ebbd1c1397fa7f8db111062e5fe959","other":"1d0244a13affe60996fe3cf51ba624adc746de0c7ea68ec5a31311a36077c5b5495e3d95c9642875db44c7ecae6ffed22e45f2e2d024d486760be2af9f4cf2cd","up":true},{"one":"d7a319f69013b8375e64d19f015547462c84565b882337998f9e669c5fadd3d2ecf6374109903003e09f5d453424b5c7fdf52163d2cc8084cf81f94844946b63","other":"6ab6ec15635b2fda22542c99df0a3313ad4583ba0fb3f31b8f314e3ecad446d3fb0fdfcd2be9b08374b1a7e049fb68e69e8dacdd13f1df5007a656f6b11adc5b","up":true},{"one":"9bbbfac8be4a000f51a4ce8d024d2595b5d491afec0138922dddfde5ef62c664040c2e9304cc6b7bc688233b5d0c4644b8c8793227c078285a3ab894ef0497a3","other":"4ee37acec2178ef120166265aaa2b64b09b315fb53861405ef46f2503c273eb9692e9cb4c2e67a8652254d430fd6e02dd3fe4cded20bb231a9fb834d292b0b24","up":true},{"one":"920a301186bdf665a721676ece7c180413369ea6eff7537f42049d9eb409f28cc864099590116e885f57368959fb2cff7003697d9b1515e68bf3fa7aee0278ef","other":"84dfd4e4d9f1204893f190eacc4c3999e175c433f70de86e335d27477c097a0552f211a21764f01a708da4c9e9e6552191a61d3e48f41d0e84f01e7ae3beb34e","up":true},{"one":"016f8f4619a16a07fbde5a18e362158d696e4d9f104a77787f26e32a25cd7d278256f8e0db865c488a99511ec27a5eddd5ebbd1c1397fa7f8db111062e5fe959","other":"abd8f5a4d700c06ec00684b23d2d25c4df1a9554fcfc57b0ddc3fa476e6a699ba75e1213449f900803f83ab8194c6746664b547202047f35b8b3e216c7147bf8","up":true},{"one":"2a63d875e715c2a43302d32d86d30c7d7faed46c08a67bf488762637216b99dd87333a66df6d9f3a57df863b1f1a219ddbeebb9f3e92e523bd08540a195448ca","other":"b4a5efa9028b2d196855393892f79993c2812d02b758f98813ddf82c5d943faf6d66eff811cc5a51936c118f4c768c0d13b54902095e040c602761e63c08655e","up":true},{"one":"94088fe273f76e62ca4e43c095ad12215b4ae4c59942328b3985416fb19bbda0cacc143a49eff3fb644ad53a19d3f043260e43dbb70a0aa9c15829c21cecd3c7","other":"7646d08b3e24183e3814de130235c41eb88a5a2abff23eaff3c91954ad3ef55fe27da422dac5b894312276bf1a2f1aebb8b636a8d4a0c93d9b016d441df3fa19","up":true},{"one":"11d560045536e9d1b0b1b9e8944e00f0ca7f1e6788c9fdb51061820bbb3008ead92bb7836621bf58da7035c87a28328faecb4cb2e3cdb9d7fa4f45790e6bf352","other":"abd8f5a4d700c06ec00684b23d2d25c4df1a9554fcfc57b0ddc3fa476e6a699ba75e1213449f900803f83ab8194c6746664b547202047f35b8b3e216c7147bf8","up":true},{"one":"a7378ee34876af17c6cd94a69b6b741ec7891ff5375bc4241d48608d047455ed48e6baae80ee88d4710c69ae615cf195cee26c94b54de1bb935628ce1e3a723a","other":"07f25fdeab2b44b2e92fc80fca7de9e4a8547d27a98a54593b3395c270a9ff3f2a5da62a2e8531ce86359f0cdc5b6513b773dfd64cce1b83e47065d9760a2c7e","up":true},{"one":"92d6ef729992f0de886076e5f8cdc42cbbd70b29e79c25e0b3d22b6575d3d2508d47b42f581e335455483d43625bce4e55f88cab9ff2073ee8dab746357864fd","other":"ba21a373781966135d6225adae024a3f3e421b852f72f8b0569cb92fcff87c33f7e5b799a509b8eff6ec6dc46a9b17d5bae1e91ec7c54c0c712d893d54b140fa","up":true},{"one":"3e488a7208ce0e097ce47fc6651a13e95cae137d1a054a09b04d2f59d45faa2594a8c3b395e77ad1a3c2edcd827dda73c0c97dbaa6d9519a79184a0aca01ac4b","other":"b53078000796f1cdb04dfeac424d5e3e37e30f00bd5bebf9a9ea0525c62917612b3a8f508df6bea59e3c7e4cd1aa530841f9a8af54e44f5617a13dee2c6ff007","up":true},{"one":"57cd4c0048b459192ee46e19ec7df777e600f256e0dc8c3019431eb7bec3c020b9504ec7aea3dba8188658ca5b830ec40af6a8540ce10e04badc6c695d009271","other":"c665a6b1b7ad39b86bd4b1fe38b7ee95a0fbb1db15e91381ec9e5a235e33b69ffdc92c60dafd74b7b4dafca1b000e9274bf045abe5b93b1a9c2b31ae071a9898","up":true},{"one":"1944f98d4db32c56a5efda5a79aa5f276bfab1e084d6611fec0e735b8bc0f45b457cdb74a23fc83b2377821fa8316123c9877acd6db7c41058ca5d3cfedaecf9","other":"c665a6b1b7ad39b86bd4b1fe38b7ee95a0fbb1db15e91381ec9e5a235e33b69ffdc92c60dafd74b7b4dafca1b000e9274bf045abe5b93b1a9c2b31ae071a9898","up":true},{"one":"a7378ee34876af17c6cd94a69b6b741ec7891ff5375bc4241d48608d047455ed48e6baae80ee88d4710c69ae615cf195cee26c94b54de1bb935628ce1e3a723a","other":"855bdf057f4a6b095e2000ada199447b5b4f2f8d78d2ecbaa0ff1fbf761788870ee999266ad3b26efa02be1a46a4d92ac0debb85a2ceab3442394ee7d99e5355","up":true},{"one":"1c2f7ce55a6e38487f3b3fe6083a79f914cd6d7e4aee8f5d56b4a61b3eb584e128c56998db0e13e775edee3adacf54f09960a041dab3daa80a4f8a3b42760c1c","other":"d7a319f69013b8375e64d19f015547462c84565b882337998f9e669c5fadd3d2ecf6374109903003e09f5d453424b5c7fdf52163d2cc8084cf81f94844946b63","up":true},{"one":"617595a230e0a74a3db3b47cd27b941e02bdee9a84cdfa8eaa63a55941eb5caa79e20fb69726a4d46a0e5aeed24039f8c5a20679a692df0bc140f42558ca9a2b","other":"ce0a09bb6fe4c9c93c3dbd800ca9c9ac0714f26a8f8dac2149b6ce7a9011912a5621ea2e45de35c4d31dfe5add00558fdba5dd21acf2d81ba391e82b5b3a5804","up":true},{"one":"71f89efcf939294bb94ac669c8afd00def58c8dfad519c226adfa068692d588ef797116d42aa146b9d34f3be35ec7c014022640ab3c0f1f9034e44ab1a26e246","other":"92d6ef729992f0de886076e5f8cdc42cbbd70b29e79c25e0b3d22b6575d3d2508d47b42f581e335455483d43625bce4e55f88cab9ff2073ee8dab746357864fd","up":true},{"one":"3e488a7208ce0e097ce47fc6651a13e95cae137d1a054a09b04d2f59d45faa2594a8c3b395e77ad1a3c2edcd827dda73c0c97dbaa6d9519a79184a0aca01ac4b","other":"083e67bb19e30d14e4df6d2483367d6659d9b56744d53d9cf7fd15954c327e1bc88a5d0db8833634e1dad7209164451f8934b59f76b5990059261abfd650519a","up":true},{"one":"9bd4f0adb9a966cc5ba632f1b540fe9cd6c8e39fe1a041b315697679cfb04b735952062ce057d456677cc34a84301f26bb727a4ab2646fee734f80a22c620746","other":"6b4e376e9c94242b6d42688c22aa9ab418cb6dfb1cbca1c69de0feceec8d3af29fb005017aaa6e503cc0c03cf0dc5bcab55e01cd6f64b9efa02ed87c03020003","up":true},{"one":"0f9f7e2dce4ca266c3ac0ec3a8854200b54487f5308e3db418461aeb5f67c81d332619b6441b468e480941e63100ed1b263e7adc20689dc3dcda578bfca538fa","other":"bcf8e831821a5bca359fb824c7dc4d66906de82f3663a0a853d96880a8ca0bdddcceb1b66dd1f13f75ee20fde50fc9de545bc25767f228baee910e0dbfa8cc27","up":true},{"one":"1090e9d89cb278a30063a5396d9ba795d3bbc237c76915a6fb7d23aa1822c8535d2fccc44cc8cd2acec68444c0bf1bdf5195ebb9f3cad8dac3d94a4d9c0e5309","other":"4e95fb8943ef6502fa470870a7ace4ca11e18589bd2073167543a922317b35e40b5068934d07e56c8fdd23354dfad51fd2899db854f189841f02b5914cd97749","up":true},{"one":"bf4ff51cc3d9a9d8cefd7e346ce1384d06450228a6086fe12fb0c60fec54bb6478f090bb638fbdbf8f41f7bc6420cd8a5c8b1b8566229b6851167375ef412f46","other":"23f9bdc82efbf57d3d40a1f2617d0311678fb4a3d6a50cb7e608c649bb618124a76c7ffd17387de963e1cd28d2bd5a61c98613f6e009a8a2a90d989827b35de0","up":false},{"one":"4a030ebcb1a59230759d25a3c87daed22906b520d55a78eab2083bb52358ddc3a5d2d7c3265e6c54a990bf32d0dacb85905a4173d72ac18fcd74c43ecb8635c5","other":"6ab6ec15635b2fda22542c99df0a3313ad4583ba0fb3f31b8f314e3ecad446d3fb0fdfcd2be9b08374b1a7e049fb68e69e8dacdd13f1df5007a656f6b11adc5b","up":true},{"one":"fd4968df03d767a223bf7e4dbe26b5c27048298df40e81cad50b344fb3e6837965f2646dab7ffb2891a5c507343ed84bb8bbe403287b51dae538d58fcb6e7623","other":"58cfb20d3da3641e0ad529b9edbd4b590a8d1dc9d1ed7b44ed3187dba9260bd7c732fc10981f5b9bffd31d362cb05150173618aa36138984431d94a323a9b313","up":true},{"one":"920a301186bdf665a721676ece7c180413369ea6eff7537f42049d9eb409f28cc864099590116e885f57368959fb2cff7003697d9b1515e68bf3fa7aee0278ef","other":"58cfb20d3da3641e0ad529b9edbd4b590a8d1dc9d1ed7b44ed3187dba9260bd7c732fc10981f5b9bffd31d362cb05150173618aa36138984431d94a323a9b313","up":true},{"one":"f9ffe87c52ff4c22bd9696af32e0a9d34bb81fb84d9d8bf5aafe2ef9696e7b3d6460bf2a93aecb066133f53416bde841a02d6967bd06e3d4a714f3b2c123a947","other":"5bf29c02f07faf7ae8e46389e1b98df4f5e88c9316b5151685e6ae7b4e622cf171ff09f996aaa8ad846643b3bfcbd1ad96cdc249afccce439bb5c55246b95801","up":true},{"one":"07c63ca5d0309e30d1ab12e7fc142e6d37904b552639cfa97850161491f28f20d87e0304be29357bcfc2ff52fc52fd0d4f6e6011ebb239cced8b5c8dad7abf45","other":"7646d08b3e24183e3814de130235c41eb88a5a2abff23eaff3c91954ad3ef55fe27da422dac5b894312276bf1a2f1aebb8b636a8d4a0c93d9b016d441df3fa19","up":true},{"one":"89a5b92a9ca045f12c35a70084e6f41f9775a25d6f105f8c9349c7b5e107179d8a96bdbb113b2680edf5183e9a42fd64bd7b29d0dc7797c583b833f869313699","other":"9b618ad34d0dfe0fccbd5b8af365cbcdbb43e802df5f23e91c20d21f3ead6169d52bf0db7e5e111abef630c9853419fb33a88cf111d8507b8708208b5d65e35e","up":true},{"one":"5bf29c02f07faf7ae8e46389e1b98df4f5e88c9316b5151685e6ae7b4e622cf171ff09f996aaa8ad846643b3bfcbd1ad96cdc249afccce439bb5c55246b95801","other":"bcf8e831821a5bca359fb824c7dc4d66906de82f3663a0a853d96880a8ca0bdddcceb1b66dd1f13f75ee20fde50fc9de545bc25767f228baee910e0dbfa8cc27","up":true},{"one":"f9ffe87c52ff4c22bd9696af32e0a9d34bb81fb84d9d8bf5aafe2ef9696e7b3d6460bf2a93aecb066133f53416bde841a02d6967bd06e3d4a714f3b2c123a947","other":"8f88c7ec044f758f29bd8d12a5170bd973aec8f6cddbf512b910c4b75a0fec09c5e198bcd65622037f897759db68da2328b4a7ca93585dc9cb62e46d2a6c0864","up":true},{"one":"062e0ca43a1885c4a7ab2a5169790f9081e3e9a2dfa286b8cc592d5ccbf13d7a82b72d23361a19026d04fcf41b752ea320d98359d770aedfcee626e21c3494b3","other":"bcf8e831821a5bca359fb824c7dc4d66906de82f3663a0a853d96880a8ca0bdddcceb1b66dd1f13f75ee20fde50fc9de545bc25767f228baee910e0dbfa8cc27","up":true},{"one":"07f25fdeab2b44b2e92fc80fca7de9e4a8547d27a98a54593b3395c270a9ff3f2a5da62a2e8531ce86359f0cdc5b6513b773dfd64cce1b83e47065d9760a2c7e","other":"b53078000796f1cdb04dfeac424d5e3e37e30f00bd5bebf9a9ea0525c62917612b3a8f508df6bea59e3c7e4cd1aa530841f9a8af54e44f5617a13dee2c6ff007","up":true},{"one":"389b5c1a805f87427e6d647ec5488342a3f7d700615943d5ad98ca5c111f33c7ee007970b4d3e475892095c0d5a79b7ed52d12598398818159000d4b9b719126","other":"e6779e3bbecf81dde8b27d652ed2726c45c205db0d0405c4580014a4c91d739830276f77079108c98ac516ffa00194e77a0795f7140bdf36069b6475e58213f9","up":true},{"one":"9133b0b3c8f680286eae90c3beebc3099a13de38775a3ff2abdeced62d05eb2ced5ac85eac0870156be03101024da5e1d9fbf3e1066ddb3f088221e64149acec","other":"7acddc7fb6ac587b7e343804c768e4291cd28dd2b2b9207dea6ee82360d848a52d84f94e4c49e9c421f4f90e2d24f6291e2358783ab0230e6ecde82e69b4ac52","up":true},{"one":"e2e0419a41bdfc5bd76deae2ddce6ac865f886d764c9bd18799b79fa3b2b6ba66d765d26da2037e98317e1d7e8232a61e63c1d0cfa98c9137424151b46e07171","other":"2ac93c31937ca205d61cc5c2a1b9037871cac55e9b306b999b28e19566b3316f6539455e014840ea50c2db8a7c97d78804d3a2dcd7cd9c1f32ace0d36e5dd339","up":true},{"one":"7aaf7817b93aa6d2f50513791f9ad7629a901ed0dcb151189f44763f83423446b20ec79a48fa260cd9bc2907d5f0ad06b2c4c5e6d812f3d8876c8020ebe41019","other":"420b9c90584651c5a3fe3c16aa377444a321dca934f8a097d01a616554067feabebf2fdc8d2a25797f29a8fef30d5e2c82f8e85b20f509a880367b9b0ccdea47","up":true},{"one":"cb94a8270d0050378116b5815ff17dafbe20f5303839c4fd57b981d4687a4b145e4bccec7e9af9b9475005930148ffbfa97781a0762c8e9f352dc95565fc8732","other":"d4b7c787981abec24353c7d496661692233797e3758189bf909a69fe87935bf6da0940daa4f12e81f20c5e88f70b472113688b71a0ae2f91a73ee0e6ff4c8591","up":false},{"one":"016f8f4619a16a07fbde5a18e362158d696e4d9f104a77787f26e32a25cd7d278256f8e0db865c488a99511ec27a5eddd5ebbd1c1397fa7f8db111062e5fe959","other":"cb321c9b0fe2eb3617b8e2461aab170a9dad2c9b04a10eead4e37e551197ea0a7500eb1cb7b155efe1886486ef3d252d8ff0d309f2906a1126ca011d037da70a","up":true},{"one":"07f25fdeab2b44b2e92fc80fca7de9e4a8547d27a98a54593b3395c270a9ff3f2a5da62a2e8531ce86359f0cdc5b6513b773dfd64cce1b83e47065d9760a2c7e","other":"083e67bb19e30d14e4df6d2483367d6659d9b56744d53d9cf7fd15954c327e1bc88a5d0db8833634e1dad7209164451f8934b59f76b5990059261abfd650519a","up":true},{"one":"e267e71c2dcdbe5a500b23444d2d4037ea15afba8f4f2b1c0e54a274450404fbee6fa5439f7cddf4ba1aa28fa93e434b01c239add58e30a5423ca3a481584d6b","other":"adfba6d883cacbb141cd8c59ee04d7e5d520f1ce31a81e5db2d8b2380bf801c1fe4b265a66b71f9643d13a41cb1f6fb4b83399be786da4b6e171b6784bc56e49","up":true},{"one":"c9cd9dfb9f90a7948ac5a42c7bd63263f2eef6e1d85547559f7d2ecbf5f9cd1eab051b8e9e661b573c275d84091a44e73f6fc6bcc91dcdb674bd5d939190fc01","other":"c332fe1f9b6e25f72c7150631ffa6e0929ff6eeab5d17aa45eaf669bdde869cf404505ae990a529aa3ca797cd0a96f31cc41431a5d4a163132be566f91623c08","up":true},{"one":"1d0244a13affe60996fe3cf51ba624adc746de0c7ea68ec5a31311a36077c5b5495e3d95c9642875db44c7ecae6ffed22e45f2e2d024d486760be2af9f4cf2cd","other":"c665a6b1b7ad39b86bd4b1fe38b7ee95a0fbb1db15e91381ec9e5a235e33b69ffdc92c60dafd74b7b4dafca1b000e9274bf045abe5b93b1a9c2b31ae071a9898","up":true},{"one":"4e68553db7be307b8379e8bec383b5c92e4b23debcefca575d24504e2062618f74c26e60e0d9e47f096997a7f841e2c32c994124f495ef3352ef964b33fd3a51","other":"c73d088ade8756c74832c73542bcdb3e52f670f7a74ad3a7eac2a9e3ece6bd081f782a8e1d3f9a40b9aa9201509110f37fc57fcb10ee1ef3ef07b7eab019782e","up":true},{"one":"043fe7085e8c90c18270f84dba5fab138e50216a1cf8d81a3794d156fad7fc81d1422aff169b244b13f91d73eebb5de464f97b1b93b3ad2a58959cff19238842","other":"e98a08e8e3544727f5ee27f4465375a67ffba490fcdbfe7bfdc909f6b68bd279f776c65d38c2ccfc33079f852f76349c94d68fc6989c0d981f22333f036a4bb5","up":true},{"one":"9bbbfac8be4a000f51a4ce8d024d2595b5d491afec0138922dddfde5ef62c664040c2e9304cc6b7bc688233b5d0c4644b8c8793227c078285a3ab894ef0497a3","other":"eab86c521f8f1ac67c015ab713f1236a08b0200757a96bf87ab8301e7967ae62361f0e14da14ca294fc8cb3b4726b52f4773101e21b032977c6a647241b59c73","up":true},{"one":"df54af3bae257d437c5657905484e0d72e9560c46f8ba6b3437730234e05259b404cca40b0831e911605ff8a68a19e8fd7e958069ec8b40595928892f4fa220c","other":"e6779e3bbecf81dde8b27d652ed2726c45c205db0d0405c4580014a4c91d739830276f77079108c98ac516ffa00194e77a0795f7140bdf36069b6475e58213f9","up":true},{"one":"2f903b2fd4f9432b7d91b5c3e4c7ee3cb9c56fe7efc4baff0edd06fc75e4b7492f2c3c929755746df59c9f95d437a12ba40ac138d08f5bc7aa091f49f3b852c2","other":"27d9048707a89f1a61e44fdae523c0128f2a7050308bd3cfefa6c3e03040a0e22f11ab41275f22b8706e6695ab93320e2af35179d772581db5f49f960750f2f7","up":true},{"one":"07f25fdeab2b44b2e92fc80fca7de9e4a8547d27a98a54593b3395c270a9ff3f2a5da62a2e8531ce86359f0cdc5b6513b773dfd64cce1b83e47065d9760a2c7e","other":"bcf8e831821a5bca359fb824c7dc4d66906de82f3663a0a853d96880a8ca0bdddcceb1b66dd1f13f75ee20fde50fc9de545bc25767f228baee910e0dbfa8cc27","up":true},{"one":"bf4ff51cc3d9a9d8cefd7e346ce1384d06450228a6086fe12fb0c60fec54bb6478f090bb638fbdbf8f41f7bc6420cd8a5c8b1b8566229b6851167375ef412f46","other":"385168340139236a0e0f537fa693122db9fa02a377c96f31aae54718e92624fc0288164877e63616651565e055c53f7074ab2fdd18a837da6faf644941305bf0","up":true},{"one":"1944f98d4db32c56a5efda5a79aa5f276bfab1e084d6611fec0e735b8bc0f45b457cdb74a23fc83b2377821fa8316123c9877acd6db7c41058ca5d3cfedaecf9","other":"094f9d0fd3bacb17ac67a2edb8ed394fbbd1c8d478233d3269cf217e7b788e21042374936b885bf23ee4f9e03babbe4e08db283dfc2a6e052a8a5ba133717dd5","up":true},{"one":"1c2f7ce55a6e38487f3b3fe6083a79f914cd6d7e4aee8f5d56b4a61b3eb584e128c56998db0e13e775edee3adacf54f09960a041dab3daa80a4f8a3b42760c1c","other":"7646d08b3e24183e3814de130235c41eb88a5a2abff23eaff3c91954ad3ef55fe27da422dac5b894312276bf1a2f1aebb8b636a8d4a0c93d9b016d441df3fa19","up":true},{"one":"92d6ef729992f0de886076e5f8cdc42cbbd70b29e79c25e0b3d22b6575d3d2508d47b42f581e335455483d43625bce4e55f88cab9ff2073ee8dab746357864fd","other":"535f93057d46c4aae0902546550880be0b5ba67dca12350117d471d67f4f2b3f7bdff29bdc918767974c465df8fa1afa6bd6c29c0a36d51f71c4183673d906f3","up":true},{"one":"a78f18691e0dbf3c08fe9d7dec188e6a05a93833432fb99eb2b3924ab0bde7a44db2a102a65544bbdc4fb61bc3a3d569230d9843a335bf619167fb045d78ab3c","other":"27d9048707a89f1a61e44fdae523c0128f2a7050308bd3cfefa6c3e03040a0e22f11ab41275f22b8706e6695ab93320e2af35179d772581db5f49f960750f2f7","up":true},{"one":"4e68553db7be307b8379e8bec383b5c92e4b23debcefca575d24504e2062618f74c26e60e0d9e47f096997a7f841e2c32c994124f495ef3352ef964b33fd3a51","other":"3dfd733dde9414af916625ab981777ff1ad7ca0f6d1e4e7d9e2739969e21182fd13d85e281868653e7325b20069356b11524b54143c47fd3955a911cf7325ad4","up":true},{"one":"57cd4c0048b459192ee46e19ec7df777e600f256e0dc8c3019431eb7bec3c020b9504ec7aea3dba8188658ca5b830ec40af6a8540ce10e04badc6c695d009271","other":"e2e0419a41bdfc5bd76deae2ddce6ac865f886d764c9bd18799b79fa3b2b6ba66d765d26da2037e98317e1d7e8232a61e63c1d0cfa98c9137424151b46e07171","up":true},{"one":"a7378ee34876af17c6cd94a69b6b741ec7891ff5375bc4241d48608d047455ed48e6baae80ee88d4710c69ae615cf195cee26c94b54de1bb935628ce1e3a723a","other":"c2705ee7238ef9305e4da196653cde707649435a1e8b5b797d164e5ca06184a77af5bd7fa938c995fdfcbce724fa7eca3d908ee34891ab62cc6dfd411c3fa1da","up":true},{"one":"7e2b0b4f3b55e97bd7241b984ad117af33bf3baacd22b3ed503a8a59f75828df745fb3ce3be4276d83eb484e64d9aa251103fa994ef119eaddb97a3503b9f292","other":"f5c1215a84a56d52f92ca0dc3a32df98c98a9c2ea2e9a34560210c16de1b440d20d043c8c25955dda8c22e55e92ddb49fd82e8b9b84072aabaa755a229bb19f4","up":true},{"one":"0f9f7e2dce4ca266c3ac0ec3a8854200b54487f5308e3db418461aeb5f67c81d332619b6441b468e480941e63100ed1b263e7adc20689dc3dcda578bfca538fa","other":"420b9c90584651c5a3fe3c16aa377444a321dca934f8a097d01a616554067feabebf2fdc8d2a25797f29a8fef30d5e2c82f8e85b20f509a880367b9b0ccdea47","up":true},{"one":"f9ffe87c52ff4c22bd9696af32e0a9d34bb81fb84d9d8bf5aafe2ef9696e7b3d6460bf2a93aecb066133f53416bde841a02d6967bd06e3d4a714f3b2c123a947","other":"420b9c90584651c5a3fe3c16aa377444a321dca934f8a097d01a616554067feabebf2fdc8d2a25797f29a8fef30d5e2c82f8e85b20f509a880367b9b0ccdea47","up":true},{"one":"3e488a7208ce0e097ce47fc6651a13e95cae137d1a054a09b04d2f59d45faa2594a8c3b395e77ad1a3c2edcd827dda73c0c97dbaa6d9519a79184a0aca01ac4b","other":"c2705ee7238ef9305e4da196653cde707649435a1e8b5b797d164e5ca06184a77af5bd7fa938c995fdfcbce724fa7eca3d908ee34891ab62cc6dfd411c3fa1da","up":true},{"one":"71f89efcf939294bb94ac669c8afd00def58c8dfad519c226adfa068692d588ef797116d42aa146b9d34f3be35ec7c014022640ab3c0f1f9034e44ab1a26e246","other":"ba21a373781966135d6225adae024a3f3e421b852f72f8b0569cb92fcff87c33f7e5b799a509b8eff6ec6dc46a9b17d5bae1e91ec7c54c0c712d893d54b140fa","up":true},{"one":"9bd4f0adb9a966cc5ba632f1b540fe9cd6c8e39fe1a041b315697679cfb04b735952062ce057d456677cc34a84301f26bb727a4ab2646fee734f80a22c620746","other":"e0f78c59a61f2a953553cd5742c58f4a82e38e35ac7eaa237a6ffc9fb0a3a26a2d1d1afae249e611d1320f2cb25804bdbdfb6d77336449716b0f4beb3298b8aa","up":true},{"one":"7ac5b07eb555af3bb4ca3f0f4b45204d43cc3798c244435909b97d9a32fc3abf0b50666e260e046bce826a7a102a92d389f8f39c5311e83bb34beddac29d50e3","other":"c665a6b1b7ad39b86bd4b1fe38b7ee95a0fbb1db15e91381ec9e5a235e33b69ffdc92c60dafd74b7b4dafca1b000e9274bf045abe5b93b1a9c2b31ae071a9898","up":true},{"one":"4a030ebcb1a59230759d25a3c87daed22906b520d55a78eab2083bb52358ddc3a5d2d7c3265e6c54a990bf32d0dacb85905a4173d72ac18fcd74c43ecb8635c5","other":"94088fe273f76e62ca4e43c095ad12215b4ae4c59942328b3985416fb19bbda0cacc143a49eff3fb644ad53a19d3f043260e43dbb70a0aa9c15829c21cecd3c7","up":true},{"one":"fd4968df03d767a223bf7e4dbe26b5c27048298df40e81cad50b344fb3e6837965f2646dab7ffb2891a5c507343ed84bb8bbe403287b51dae538d58fcb6e7623","other":"e0f78c59a61f2a953553cd5742c58f4a82e38e35ac7eaa237a6ffc9fb0a3a26a2d1d1afae249e611d1320f2cb25804bdbdfb6d77336449716b0f4beb3298b8aa","up":true},{"one":"07c63ca5d0309e30d1ab12e7fc142e6d37904b552639cfa97850161491f28f20d87e0304be29357bcfc2ff52fc52fd0d4f6e6011ebb239cced8b5c8dad7abf45","other":"4a030ebcb1a59230759d25a3c87daed22906b520d55a78eab2083bb52358ddc3a5d2d7c3265e6c54a990bf32d0dacb85905a4173d72ac18fcd74c43ecb8635c5","up":true},{"one":"89a5b92a9ca045f12c35a70084e6f41f9775a25d6f105f8c9349c7b5e107179d8a96bdbb113b2680edf5183e9a42fd64bd7b29d0dc7797c583b833f869313699","other":"094f9d0fd3bacb17ac67a2edb8ed394fbbd1c8d478233d3269cf217e7b788e21042374936b885bf23ee4f9e03babbe4e08db283dfc2a6e052a8a5ba133717dd5","up":true},{"one":"70ee3c7e02a123f78345d41c386e413f06b51f1ab346c2c472891eed7dd26a1f14e213a0f4f2d872859b9b535936a6d9b072d2604456f76221a422710411822f","other":"c332fe1f9b6e25f72c7150631ffa6e0929ff6eeab5d17aa45eaf669bdde869cf404505ae990a529aa3ca797cd0a96f31cc41431a5d4a163132be566f91623c08","up":true},{"one":"f5c1215a84a56d52f92ca0dc3a32df98c98a9c2ea2e9a34560210c16de1b440d20d043c8c25955dda8c22e55e92ddb49fd82e8b9b84072aabaa755a229bb19f4","other":"aa9a94d6e4eaaed20113c21752c224e3a052abd3769bd6e832759dbaf5154a943cf094eacdcb0727c2fe51a11bd7fc0793d7d5e3312b0aba89d428a00e1fde0c","up":true},{"one":"920a301186bdf665a721676ece7c180413369ea6eff7537f42049d9eb409f28cc864099590116e885f57368959fb2cff7003697d9b1515e68bf3fa7aee0278ef","other":"92d6ef729992f0de886076e5f8cdc42cbbd70b29e79c25e0b3d22b6575d3d2508d47b42f581e335455483d43625bce4e55f88cab9ff2073ee8dab746357864fd","up":true},{"one":"e98a08e8e3544727f5ee27f4465375a67ffba490fcdbfe7bfdc909f6b68bd279f776c65d38c2ccfc33079f852f76349c94d68fc6989c0d981f22333f036a4bb5","other":"4e95fb8943ef6502fa470870a7ace4ca11e18589bd2073167543a922317b35e40b5068934d07e56c8fdd23354dfad51fd2899db854f189841f02b5914cd97749","up":true},{"one":"617595a230e0a74a3db3b47cd27b941e02bdee9a84cdfa8eaa63a55941eb5caa79e20fb69726a4d46a0e5aeed24039f8c5a20679a692df0bc140f42558ca9a2b","other":"aa9a94d6e4eaaed20113c21752c224e3a052abd3769bd6e832759dbaf5154a943cf094eacdcb0727c2fe51a11bd7fc0793d7d5e3312b0aba89d428a00e1fde0c","up":true},{"one":"e98a08e8e3544727f5ee27f4465375a67ffba490fcdbfe7bfdc909f6b68bd279f776c65d38c2ccfc33079f852f76349c94d68fc6989c0d981f22333f036a4bb5","other":"22010c9829626a6892258b09cb3f3edc3f21382fb487b5dbf0dd20e198e37e26134aab850e30337f398d1491b5126839aeb1953ec144bc19aeb889c832f67c6a","up":true},{"one":"cb94a8270d0050378116b5815ff17dafbe20f5303839c4fd57b981d4687a4b145e4bccec7e9af9b9475005930148ffbfa97781a0762c8e9f352dc95565fc8732","other":"ff1e34fd51953ed641b431aa657da21cb4c81d23e4eaa13c9cce526f1f1b34593d41f9b87a0e10387fe400c623638677c0efab15dbd1014a0ccc11f9ec92c417","up":true},{"one":"4e68553db7be307b8379e8bec383b5c92e4b23debcefca575d24504e2062618f74c26e60e0d9e47f096997a7f841e2c32c994124f495ef3352ef964b33fd3a51","other":"eaca77d20c4ad6b87649eba21b750a4b1a2c575e06bc42679d18fce16fea15212e9a7408c16f3b24d8dfd1e397314637e72e292845d09534a39035bd9203ee9e","up":false},{"one":"b3316f4fd7dec218a52331f25d17a2faf0f2a417808d7dbb80038154abfbcd2d78da074837b648cff28675f4aa0d65ddb7d15abf3d7e0391d401e313a3ef24a2","other":"5dc69635f6d573c824ea83b18593a47f9f21a6f91ce18d2bf977c97d21f8d2a8ce88829244d12a07d949bbd52fe8a2035bc89685fe1bdd4ee20d766d75d3deee","up":true},{"one":"5526d86ba9df651091d88460a9bedb9cedb957d452a635e1db46b9fed78082022adec0047cd7485956a4ecbb0e18107595de0de3c35242527cd302bf74a19260","other":"07f25fdeab2b44b2e92fc80fca7de9e4a8547d27a98a54593b3395c270a9ff3f2a5da62a2e8531ce86359f0cdc5b6513b773dfd64cce1b83e47065d9760a2c7e","up":true},{"one":"831cde5b651ba327b059da4c7f84b184bdd6bb99c6690ae816affe25d42c6c3dbe5b59e2b6bf23e9d0f6c485bd341ea57ba1a8220d18b0a40e156b77d84f79ef","other":"4a030ebcb1a59230759d25a3c87daed22906b520d55a78eab2083bb52358ddc3a5d2d7c3265e6c54a990bf32d0dacb85905a4173d72ac18fcd74c43ecb8635c5","up":true},{"one":"1d0244a13affe60996fe3cf51ba624adc746de0c7ea68ec5a31311a36077c5b5495e3d95c9642875db44c7ecae6ffed22e45f2e2d024d486760be2af9f4cf2cd","other":"57cd4c0048b459192ee46e19ec7df777e600f256e0dc8c3019431eb7bec3c020b9504ec7aea3dba8188658ca5b830ec40af6a8540ce10e04badc6c695d009271","up":true},{"one":"4f5ab12b9c5127c16739ad0d4f51adce90ba6736cd096eb185ea632789f4b26f1ebabdea4fd3b39dda5409ece6c2d92fd469cf4aecf9d29453e3e042c19b893b","other":"74d84cfdaf32cd4cc67771f29878f1365120bd65cc14848008d5386a81f495bf88eb4132fa38a2cc109ae1e7f02c9b97597ab9d1a9c19c945e710ab9df07cdcd","up":true},{"one":"5526d86ba9df651091d88460a9bedb9cedb957d452a635e1db46b9fed78082022adec0047cd7485956a4ecbb0e18107595de0de3c35242527cd302bf74a19260","other":"c2705ee7238ef9305e4da196653cde707649435a1e8b5b797d164e5ca06184a77af5bd7fa938c995fdfcbce724fa7eca3d908ee34891ab62cc6dfd411c3fa1da","up":true},{"one":"9bbbfac8be4a000f51a4ce8d024d2595b5d491afec0138922dddfde5ef62c664040c2e9304cc6b7bc688233b5d0c4644b8c8793227c078285a3ab894ef0497a3","other":"c57ea182bdb42ba9b0870b5c870e467f52693e5c0df752fb6eb0dfbacce7763f73caee10db40f4fd90f19f504ee586eaf9da41f5ee93ee515d885fec99374116","up":true},{"one":"831cde5b651ba327b059da4c7f84b184bdd6bb99c6690ae816affe25d42c6c3dbe5b59e2b6bf23e9d0f6c485bd341ea57ba1a8220d18b0a40e156b77d84f79ef","other":"9b618ad34d0dfe0fccbd5b8af365cbcdbb43e802df5f23e91c20d21f3ead6169d52bf0db7e5e111abef630c9853419fb33a88cf111d8507b8708208b5d65e35e","up":true},{"one":"016f8f4619a16a07fbde5a18e362158d696e4d9f104a77787f26e32a25cd7d278256f8e0db865c488a99511ec27a5eddd5ebbd1c1397fa7f8db111062e5fe959","other":"5df58ba12334a1b4f983d642fe435901261767cd81f8f37c43e359f5584664e4d287e8c2275995604a3b3a4823418e35cd899a3db2a7db31570e19512f375481","up":true},{"one":"bf4ff51cc3d9a9d8cefd7e346ce1384d06450228a6086fe12fb0c60fec54bb6478f090bb638fbdbf8f41f7bc6420cd8a5c8b1b8566229b6851167375ef412f46","other":"062e0ca43a1885c4a7ab2a5169790f9081e3e9a2dfa286b8cc592d5ccbf13d7a82b72d23361a19026d04fcf41b752ea320d98359d770aedfcee626e21c3494b3","up":true},{"one":"4f5ab12b9c5127c16739ad0d4f51adce90ba6736cd096eb185ea632789f4b26f1ebabdea4fd3b39dda5409ece6c2d92fd469cf4aecf9d29453e3e042c19b893b","other":"4ee37acec2178ef120166265aaa2b64b09b315fb53861405ef46f2503c273eb9692e9cb4c2e67a8652254d430fd6e02dd3fe4cded20bb231a9fb834d292b0b24","up":true},{"one":"e2e0419a41bdfc5bd76deae2ddce6ac865f886d764c9bd18799b79fa3b2b6ba66d765d26da2037e98317e1d7e8232a61e63c1d0cfa98c9137424151b46e07171","other":"c665a6b1b7ad39b86bd4b1fe38b7ee95a0fbb1db15e91381ec9e5a235e33b69ffdc92c60dafd74b7b4dafca1b000e9274bf045abe5b93b1a9c2b31ae071a9898","up":true},{"one":"7acddc7fb6ac587b7e343804c768e4291cd28dd2b2b9207dea6ee82360d848a52d84f94e4c49e9c421f4f90e2d24f6291e2358783ab0230e6ecde82e69b4ac52","other":"53df9cce9b0169e58ced53a123d1d8f6e8fdcfb4c2d781ecbb91bb7c8eba36946dd9d21c749259769825d8a6b3faa6bb87c8c6085a522f8a3e376061f59144d9","up":true},{"one":"485825745d97654cbb92a14e0cd1078691d3c28f4d82b1046284b676a42b44ca58eb43474e45e415d3bd3f3c383f9a1a3365821ed7ba6a9f2603b29d58031dc7","other":"7865b82e44add2cea6ebcbaba9c152184331a2940fe73f6f9bb940bda8a59ab4cf4760894b9cadcaa54e36fbb712ad619346a49a85e32cdf2b53cda1ac1e0658","up":true},{"one":"df54af3bae257d437c5657905484e0d72e9560c46f8ba6b3437730234e05259b404cca40b0831e911605ff8a68a19e8fd7e958069ec8b40595928892f4fa220c","other":"7b1e20217f594f87350542df31ff5ae8a635679bac7962d49c97e02190c644b673d03e7eba2626b45ca7ebf98d8a972dadbba02c18a8d2cbfc3e7a4cced5b4b7","up":true},{"one":"3e488a7208ce0e097ce47fc6651a13e95cae137d1a054a09b04d2f59d45faa2594a8c3b395e77ad1a3c2edcd827dda73c0c97dbaa6d9519a79184a0aca01ac4b","other":"420b9c90584651c5a3fe3c16aa377444a321dca934f8a097d01a616554067feabebf2fdc8d2a25797f29a8fef30d5e2c82f8e85b20f509a880367b9b0ccdea47","up":true},{"one":"4de378164d77a28c90cf162dd1b465e0282ee17aa7d3bb3179252466f72da33a36c9f298f7c9498e38dba4018e7ce3e5fe631c83842cd9059e23a7fece366d87","other":"759f46661056bcbb30c7706c9fb87e22a30feb523bd53ae5d18db043efa45b49a2b8982abebdd598fe0912a05896390ec2eabe5e160cbafc0771990708ad8c28","up":true},{"one":"155e4879643a472420012e040a87dbff776fc1976814c0c6cd0d5e157f0d0baac04aa7f2535786c09acc2700547383d2119b64a6f62115f1aff1708738844d8c","other":"9db1f94d74a00d1e5e2a391f1bcddf16b6d0670a2c6d91d946d38112c58634444b6fea8e8c05ab4b73bacdd62a0b575f6fb8729978edc216c7842b177b9f9cd9","up":true},{"one":"4ee37acec2178ef120166265aaa2b64b09b315fb53861405ef46f2503c273eb9692e9cb4c2e67a8652254d430fd6e02dd3fe4cded20bb231a9fb834d292b0b24","other":"0a4eec7b0e05da799aca5b36d9e2530f2a89d1426b1fcb7d8f9a662df8a8b5b763767a20db3c9c63e0bd13c2a6e16d3ba8f03baf84f5e5d24917b3f211d9bcfc","up":true},{"one":"5526d86ba9df651091d88460a9bedb9cedb957d452a635e1db46b9fed78082022adec0047cd7485956a4ecbb0e18107595de0de3c35242527cd302bf74a19260","other":"bcf8e831821a5bca359fb824c7dc4d66906de82f3663a0a853d96880a8ca0bdddcceb1b66dd1f13f75ee20fde50fc9de545bc25767f228baee910e0dbfa8cc27","up":true},{"one":"4de378164d77a28c90cf162dd1b465e0282ee17aa7d3bb3179252466f72da33a36c9f298f7c9498e38dba4018e7ce3e5fe631c83842cd9059e23a7fece366d87","other":"bd1a7c63fca9e1fcc67d7fd62670beefe2bce483cf1dc1233ee85eb90db607917cd9a5d7170b10e80b925a20e2af2c54d286b01805ac34967410859f4f03da09","up":true},{"one":"f54335964d9b4eb9813eb05f40ef1c523bbf0faac5a04c4737467d590fb6b55c7fa1fc5d4d32c5491d8766b9be6fdfd3ebdb25c5ffe1719f36c86ddf87ae3a85","other":"807340e5fdf6c21a56ef2fd158c32e92201206ca85fcc147165a408f7a735964afd47c397e663610ac53870ae722c0317291732b0422f8aeedae783d9c730218","up":true},{"one":"a7378ee34876af17c6cd94a69b6b741ec7891ff5375bc4241d48608d047455ed48e6baae80ee88d4710c69ae615cf195cee26c94b54de1bb935628ce1e3a723a","other":"420b9c90584651c5a3fe3c16aa377444a321dca934f8a097d01a616554067feabebf2fdc8d2a25797f29a8fef30d5e2c82f8e85b20f509a880367b9b0ccdea47","up":true},{"one":"aacff366e601e072a2113add9020e19b6612f3e85b6e607fdc8cc1b6991f43be0b1f835ed3dc41d1f2b3e0caf7fac252c8eb4c150667d48207fa92ea5f0a7455","other":"c8b0dba45104fc7c7dff3ce078a0d3f5ade6198bb4656e2bee8076387929133e5ef2bd293b130a9d4f6a6974ca17e8b4a8f406d1219880f1e0f99c65c63af5a4","up":true},{"one":"f54335964d9b4eb9813eb05f40ef1c523bbf0faac5a04c4737467d590fb6b55c7fa1fc5d4d32c5491d8766b9be6fdfd3ebdb25c5ffe1719f36c86ddf87ae3a85","other":"4e95fb8943ef6502fa470870a7ace4ca11e18589bd2073167543a922317b35e40b5068934d07e56c8fdd23354dfad51fd2899db854f189841f02b5914cd97749","up":true},{"one":"4f5ab12b9c5127c16739ad0d4f51adce90ba6736cd096eb185ea632789f4b26f1ebabdea4fd3b39dda5409ece6c2d92fd469cf4aecf9d29453e3e042c19b893b","other":"4ff66e9b5d3fd345990bd7605bdc222b78946f0c13b72bf80352812b2426d8f1d36c93e6c8713566004615e8a78ecab12ab0cfba254c0967eeecf8875b25bdae","up":true},{"one":"07f25fdeab2b44b2e92fc80fca7de9e4a8547d27a98a54593b3395c270a9ff3f2a5da62a2e8531ce86359f0cdc5b6513b773dfd64cce1b83e47065d9760a2c7e","other":"420b9c90584651c5a3fe3c16aa377444a321dca934f8a097d01a616554067feabebf2fdc8d2a25797f29a8fef30d5e2c82f8e85b20f509a880367b9b0ccdea47","up":true},{"one":"f915e2398aa5d4370de87504dd76c21a7d0be2581c2ab55b7a47743f1bbaef36384eaacec22760f1e914ceac9d96a10c3d66eb27475ef444e77fee979e6e88cb","other":"ae2a996d3b562cb47a564934037949da83b1bfe194c23754f3dbe2372ec27654f4f3b6cb7f394570f308025589c065870477667e5560dbe5a8ea1625740699cf","up":true},{"one":"0f9f7e2dce4ca266c3ac0ec3a8854200b54487f5308e3db418461aeb5f67c81d332619b6441b468e480941e63100ed1b263e7adc20689dc3dcda578bfca538fa","other":"c2705ee7238ef9305e4da196653cde707649435a1e8b5b797d164e5ca06184a77af5bd7fa938c995fdfcbce724fa7eca3d908ee34891ab62cc6dfd411c3fa1da","up":true},{"one":"7e2b0b4f3b55e97bd7241b984ad117af33bf3baacd22b3ed503a8a59f75828df745fb3ce3be4276d83eb484e64d9aa251103fa994ef119eaddb97a3503b9f292","other":"8ca3b63cb84f1e9883d82809a9b6777ec1029ecda96fe93b4d494ee9cbefcad13f381b3e480136e542e01054fe1ede66c65db84a0009871ce49383db461c8438","up":true},{"one":"1944f98d4db32c56a5efda5a79aa5f276bfab1e084d6611fec0e735b8bc0f45b457cdb74a23fc83b2377821fa8316123c9877acd6db7c41058ca5d3cfedaecf9","other":"cb321c9b0fe2eb3617b8e2461aab170a9dad2c9b04a10eead4e37e551197ea0a7500eb1cb7b155efe1886486ef3d252d8ff0d309f2906a1126ca011d037da70a","up":true},{"one":"7ac5b07eb555af3bb4ca3f0f4b45204d43cc3798c244435909b97d9a32fc3abf0b50666e260e046bce826a7a102a92d389f8f39c5311e83bb34beddac29d50e3","other":"cb321c9b0fe2eb3617b8e2461aab170a9dad2c9b04a10eead4e37e551197ea0a7500eb1cb7b155efe1886486ef3d252d8ff0d309f2906a1126ca011d037da70a","up":true},{"one":"460531928a4b084686343c8464b37c3452bb3566045698d08a4692864de5581a9eb1dc632329e7d3ccb73ec31ee7693787d69df8458efaba9a7105d87ee2e053","other":"4fe37f2dfb03707c90a6fe91dbcfd7497db70ffc20043091d50e1cee573210c144e8749340f2c3cb70fe8fc51b317d49e8734dc51ce64b3cdccdd639ae35d1ae","up":true},{"one":"f915e2398aa5d4370de87504dd76c21a7d0be2581c2ab55b7a47743f1bbaef36384eaacec22760f1e914ceac9d96a10c3d66eb27475ef444e77fee979e6e88cb","other":"66d0c5da973d9dd65350ae1ec63776872cdb7ded6afb6f51ae82259f6fd35e884375d15de290625f02ed2e5cdc3f591decb45e5fc64d5b0f835a216fd196f5a3","up":true},{"one":"57cd4c0048b459192ee46e19ec7df777e600f256e0dc8c3019431eb7bec3c020b9504ec7aea3dba8188658ca5b830ec40af6a8540ce10e04badc6c695d009271","other":"89a5b92a9ca045f12c35a70084e6f41f9775a25d6f105f8c9349c7b5e107179d8a96bdbb113b2680edf5183e9a42fd64bd7b29d0dc7797c583b833f869313699","up":true},{"one":"70ee3c7e02a123f78345d41c386e413f06b51f1ab346c2c472891eed7dd26a1f14e213a0f4f2d872859b9b535936a6d9b072d2604456f76221a422710411822f","other":"4fe37f2dfb03707c90a6fe91dbcfd7497db70ffc20043091d50e1cee573210c144e8749340f2c3cb70fe8fc51b317d49e8734dc51ce64b3cdccdd639ae35d1ae","up":true},{"one":"2b70e5ffcc0bb1c4f8acc09dd1016e67c9c96c92d091ad481efbb71bd8b2a5a5869c6d668617a9b2cbfe91baf5edfe150c3824c84d90899a974099071d171441","other":"b3316f4fd7dec218a52331f25d17a2faf0f2a417808d7dbb80038154abfbcd2d78da074837b648cff28675f4aa0d65ddb7d15abf3d7e0391d401e313a3ef24a2","up":false},{"one":"e2a27dcdee1f89fa362a85c4397840cd8be4ad8d1b9ccb23188c303bcab7619f38772f71385922d090390973b62fb8249efc103f71bc761041bcb3880ec0b935","other":"3dfd733dde9414af916625ab981777ff1ad7ca0f6d1e4e7d9e2739969e21182fd13d85e281868653e7325b20069356b11524b54143c47fd3955a911cf7325ad4","up":true},{"one":"7aaf7817b93aa6d2f50513791f9ad7629a901ed0dcb151189f44763f83423446b20ec79a48fa260cd9bc2907d5f0ad06b2c4c5e6d812f3d8876c8020ebe41019","other":"57b47f692f4d69a5d2c9c193680eb4ccb5a6c574662df0138504a549f3ea74f20c5b866ac4d9e76c4b49c83f5fd692ead928ea20dfcf643a11a1c1e841c0ec42","up":true},{"one":"f9ffe87c52ff4c22bd9696af32e0a9d34bb81fb84d9d8bf5aafe2ef9696e7b3d6460bf2a93aecb066133f53416bde841a02d6967bd06e3d4a714f3b2c123a947","other":"3e488a7208ce0e097ce47fc6651a13e95cae137d1a054a09b04d2f59d45faa2594a8c3b395e77ad1a3c2edcd827dda73c0c97dbaa6d9519a79184a0aca01ac4b","up":true},{"one":"831cde5b651ba327b059da4c7f84b184bdd6bb99c6690ae816affe25d42c6c3dbe5b59e2b6bf23e9d0f6c485bd341ea57ba1a8220d18b0a40e156b77d84f79ef","other":"53df9cce9b0169e58ced53a123d1d8f6e8fdcfb4c2d781ecbb91bb7c8eba36946dd9d21c749259769825d8a6b3faa6bb87c8c6085a522f8a3e376061f59144d9","up":true},{"one":"92d6ef729992f0de886076e5f8cdc42cbbd70b29e79c25e0b3d22b6575d3d2508d47b42f581e335455483d43625bce4e55f88cab9ff2073ee8dab746357864fd","other":"84dfd4e4d9f1204893f190eacc4c3999e175c433f70de86e335d27477c097a0552f211a21764f01a708da4c9e9e6552191a61d3e48f41d0e84f01e7ae3beb34e","up":true},{"one":"3d2df188704eeac09c8b291bf275a73888199a231c832c51dbc3d746968d4b51a7d5eae0c7c9b8c8e19f5e28d38c375e01abefa343f31dbe221deb837ab8a0df","other":"2ddd49fae11d8bd2e7e75a481be267fa846f51cc1160bc326aeea51c542323ff444909de11e2731e835140bc0b1b32020e1e73fa652511a381222bf0aebc4081","up":true},{"one":"5bf29c02f07faf7ae8e46389e1b98df4f5e88c9316b5151685e6ae7b4e622cf171ff09f996aaa8ad846643b3bfcbd1ad96cdc249afccce439bb5c55246b95801","other":"b53078000796f1cdb04dfeac424d5e3e37e30f00bd5bebf9a9ea0525c62917612b3a8f508df6bea59e3c7e4cd1aa530841f9a8af54e44f5617a13dee2c6ff007","up":true},{"one":"e3c8a97a2d95dd543f9e2b41d9dce6256e284296f866f4f92e9925f8c7519dea23fd6d1a11153b93c10d6a32295e7b9bcc16024e690e4a0dc84fd25ee0f31b2c","other":"57b47f692f4d69a5d2c9c193680eb4ccb5a6c574662df0138504a549f3ea74f20c5b866ac4d9e76c4b49c83f5fd692ead928ea20dfcf643a11a1c1e841c0ec42","up":true},{"one":"71f89efcf939294bb94ac669c8afd00def58c8dfad519c226adfa068692d588ef797116d42aa146b9d34f3be35ec7c014022640ab3c0f1f9034e44ab1a26e246","other":"4ee37acec2178ef120166265aaa2b64b09b315fb53861405ef46f2503c273eb9692e9cb4c2e67a8652254d430fd6e02dd3fe4cded20bb231a9fb834d292b0b24","up":true},{"one":"979838eaefcff456cf1cd9c47ea46854704f5757d8d7ab907019bc422b01af4d62252579bf045d143fab491b0bab823190e2782a457fbf51aa99ae17ec9e145f","other":"5566111b7f14d8ec83ba6456488f3fc5c7e2c86bf406dead33b814e1ee9b569d34015a4d88226b7e28fff7784395c086d106287cbbc80acfe75b05cd6e12903d","up":true},{"one":"4a030ebcb1a59230759d25a3c87daed22906b520d55a78eab2083bb52358ddc3a5d2d7c3265e6c54a990bf32d0dacb85905a4173d72ac18fcd74c43ecb8635c5","other":"9e621c3eb534855ca292efa27a3fbc89b4f05c80a4bc65bcff2f14ff28ef43cbe14137d2fddc6fe2658bb06947d918476b479dde71469b8680e5d8a7a01619b5","up":true},{"one":"ba21a373781966135d6225adae024a3f3e421b852f72f8b0569cb92fcff87c33f7e5b799a509b8eff6ec6dc46a9b17d5bae1e91ec7c54c0c712d893d54b140fa","other":"535f93057d46c4aae0902546550880be0b5ba67dca12350117d471d67f4f2b3f7bdff29bdc918767974c465df8fa1afa6bd6c29c0a36d51f71c4183673d906f3","up":true},{"one":"2b70e5ffcc0bb1c4f8acc09dd1016e67c9c96c92d091ad481efbb71bd8b2a5a5869c6d668617a9b2cbfe91baf5edfe150c3824c84d90899a974099071d171441","other":"17a79cb279306b6bbd35219278f6bba03111079d6c4fadcd3c5e57b09678e111bda5f8e36ca3d223e51e255d6e857363b7741e438b32ec6e6c0dc1b224071081","up":true},{"one":"f5c1215a84a56d52f92ca0dc3a32df98c98a9c2ea2e9a34560210c16de1b440d20d043c8c25955dda8c22e55e92ddb49fd82e8b9b84072aabaa755a229bb19f4","other":"8ca3b63cb84f1e9883d82809a9b6777ec1029ecda96fe93b4d494ee9cbefcad13f381b3e480136e542e01054fe1ede66c65db84a0009871ce49383db461c8438","up":true},{"one":"fd4968df03d767a223bf7e4dbe26b5c27048298df40e81cad50b344fb3e6837965f2646dab7ffb2891a5c507343ed84bb8bbe403287b51dae538d58fcb6e7623","other":"a608a746f46d4b2e9267c65283380d6d6cb8885a64428fb77df9934bcf4dd1723587ee7c8f4a642dce266a12a6a4cf4e5c6db7fa1024158425a6753e7ab7264c","up":true},{"one":"920a301186bdf665a721676ece7c180413369ea6eff7537f42049d9eb409f28cc864099590116e885f57368959fb2cff7003697d9b1515e68bf3fa7aee0278ef","other":"f38a9d792173a29c61389f5d84c005d78eac6e750659aad42e2d6df883f04eb3126b2c38fac95076eeed455b2031aaf694143922aa93a2d50412a2454dc56e28","up":true},{"one":"07c63ca5d0309e30d1ab12e7fc142e6d37904b552639cfa97850161491f28f20d87e0304be29357bcfc2ff52fc52fd0d4f6e6011ebb239cced8b5c8dad7abf45","other":"9e621c3eb534855ca292efa27a3fbc89b4f05c80a4bc65bcff2f14ff28ef43cbe14137d2fddc6fe2658bb06947d918476b479dde71469b8680e5d8a7a01619b5","up":true},{"one":"57b47f692f4d69a5d2c9c193680eb4ccb5a6c574662df0138504a549f3ea74f20c5b866ac4d9e76c4b49c83f5fd692ead928ea20dfcf643a11a1c1e841c0ec42","other":"b53078000796f1cdb04dfeac424d5e3e37e30f00bd5bebf9a9ea0525c62917612b3a8f508df6bea59e3c7e4cd1aa530841f9a8af54e44f5617a13dee2c6ff007","up":true},{"one":"89a5b92a9ca045f12c35a70084e6f41f9775a25d6f105f8c9349c7b5e107179d8a96bdbb113b2680edf5183e9a42fd64bd7b29d0dc7797c583b833f869313699","other":"c665a6b1b7ad39b86bd4b1fe38b7ee95a0fbb1db15e91381ec9e5a235e33b69ffdc92c60dafd74b7b4dafca1b000e9274bf045abe5b93b1a9c2b31ae071a9898","up":true},{"one":"f38a9d792173a29c61389f5d84c005d78eac6e750659aad42e2d6df883f04eb3126b2c38fac95076eeed455b2031aaf694143922aa93a2d50412a2454dc56e28","other":"74d84cfdaf32cd4cc67771f29878f1365120bd65cc14848008d5386a81f495bf88eb4132fa38a2cc109ae1e7f02c9b97597ab9d1a9c19c945e710ab9df07cdcd","up":true},{"one":"8dd8ad560af84bec579cadb33d51711aa61b6ed22705010336df5a71a94591173b25e869457429c4a199b205fce8e73530e28203e18b971c2001715e610f152a","other":"ddaf3f8478501cda872c056c72063eb64d5b871fc5fff70704872802289dd2d348f73bc342b7f148a90cfaae2448ebf16fea196be9df891dc71a57fb410d59dd","up":true},{"one":"315b8a1711f680c2eaa607e35ef7a9e19c2b61721af8a7e08f1325dde1fe33cf1f47b3cc4acf12d541631041cf1b42754875fd1c9b66ee32797b72b9f7711256","other":"8dd8ad560af84bec579cadb33d51711aa61b6ed22705010336df5a71a94591173b25e869457429c4a199b205fce8e73530e28203e18b971c2001715e610f152a","up":true},{"one":"b6a998dea59194cc60ce97c7c9702368411889cb6905516b23f41cc5116fba8d0f237d418318eb0c333cad18003c0e9a6bd8c99080520771f2bad640e2e5ec1c","other":"cd8815d66aee8bd488d4e5e25f0cc9c71cc65349f701ea26b1d6cd9c039d16fcb473dbf270a3b33187720ccf4b0ce4f78a6d6edd05f4fe804772d5b6ec45bbd3","up":true},{"one":"62dab8b21640e1b44dea452dd7e7de93f27a44840da72d56b11aa96e8463f3a4bb15e75a954d19fc897ae0030b16181d271b79d8198b7cffcddaa9ffcfdcce73","other":"3dfd733dde9414af916625ab981777ff1ad7ca0f6d1e4e7d9e2739969e21182fd13d85e281868653e7325b20069356b11524b54143c47fd3955a911cf7325ad4","up":true},{"one":"0a4eec7b0e05da799aca5b36d9e2530f2a89d1426b1fcb7d8f9a662df8a8b5b763767a20db3c9c63e0bd13c2a6e16d3ba8f03baf84f5e5d24917b3f211d9bcfc","other":"eab86c521f8f1ac67c015ab713f1236a08b0200757a96bf87ab8301e7967ae62361f0e14da14ca294fc8cb3b4726b52f4773101e21b032977c6a647241b59c73","up":true},{"one":"b53078000796f1cdb04dfeac424d5e3e37e30f00bd5bebf9a9ea0525c62917612b3a8f508df6bea59e3c7e4cd1aa530841f9a8af54e44f5617a13dee2c6ff007","other":"062e0ca43a1885c4a7ab2a5169790f9081e3e9a2dfa286b8cc592d5ccbf13d7a82b72d23361a19026d04fcf41b752ea320d98359d770aedfcee626e21c3494b3","up":true},{"one":"c73d088ade8756c74832c73542bcdb3e52f670f7a74ad3a7eac2a9e3ece6bd081f782a8e1d3f9a40b9aa9201509110f37fc57fcb10ee1ef3ef07b7eab019782e","other":"3dfd733dde9414af916625ab981777ff1ad7ca0f6d1e4e7d9e2739969e21182fd13d85e281868653e7325b20069356b11524b54143c47fd3955a911cf7325ad4","up":true},{"one":"9194a3a4c8f3235203e48bdb10902d958d26c342805ea6365af9711213536509719d917c694f9a4fbdde6889a4c92299a5301f0275bda4dbcd2541b5bff5b271","other":"54b3c57a4adf4dbaf31b85ed1b8dccd6249faa16dd96dd230189f47f57970caeed36627cc8e1b0794707418d580f5bd6001c07be6a79216695f1253db24926bb","up":true},{"one":"f38a9d792173a29c61389f5d84c005d78eac6e750659aad42e2d6df883f04eb3126b2c38fac95076eeed455b2031aaf694143922aa93a2d50412a2454dc56e28","other":"4ee37acec2178ef120166265aaa2b64b09b315fb53861405ef46f2503c273eb9692e9cb4c2e67a8652254d430fd6e02dd3fe4cded20bb231a9fb834d292b0b24","up":true},{"one":"535f93057d46c4aae0902546550880be0b5ba67dca12350117d471d67f4f2b3f7bdff29bdc918767974c465df8fa1afa6bd6c29c0a36d51f71c4183673d906f3","other":"74d84cfdaf32cd4cc67771f29878f1365120bd65cc14848008d5386a81f495bf88eb4132fa38a2cc109ae1e7f02c9b97597ab9d1a9c19c945e710ab9df07cdcd","up":true},{"one":"40bdac599b00e9c41ad6476ee415c33d9c17c5aa672692c2404e523b29dc315da929a86874bed87fd9009871805d1dbf3098e7a817193e3b08a6eee66346da79","other":"4e95fb8943ef6502fa470870a7ace4ca11e18589bd2073167543a922317b35e40b5068934d07e56c8fdd23354dfad51fd2899db854f189841f02b5914cd97749","up":true},{"one":"4de378164d77a28c90cf162dd1b465e0282ee17aa7d3bb3179252466f72da33a36c9f298f7c9498e38dba4018e7ce3e5fe631c83842cd9059e23a7fece366d87","other":"5bae82d4832092c17bd11474f7748015b8b69b896ab8f683a7c0024fc98740cecbb9e31c6275269f9000e5bfe51d7f45cd5dcd4433e0c87b5741685b40fe3983","up":true},{"one":"7f357b8d81bc2e5c6fcb081f23a42b3e2439f050d45c45851994a268d1c71fcb1f39f8c3f75ce921d3fbf80fc0e73f0b9609d72001dc4a6b65b526d312a4f43a","other":"27d9048707a89f1a61e44fdae523c0128f2a7050308bd3cfefa6c3e03040a0e22f11ab41275f22b8706e6695ab93320e2af35179d772581db5f49f960750f2f7","up":true},{"one":"389b5c1a805f87427e6d647ec5488342a3f7d700615943d5ad98ca5c111f33c7ee007970b4d3e475892095c0d5a79b7ed52d12598398818159000d4b9b719126","other":"df54af3bae257d437c5657905484e0d72e9560c46f8ba6b3437730234e05259b404cca40b0831e911605ff8a68a19e8fd7e958069ec8b40595928892f4fa220c","up":true},{"one":"4e68553db7be307b8379e8bec383b5c92e4b23debcefca575d24504e2062618f74c26e60e0d9e47f096997a7f841e2c32c994124f495ef3352ef964b33fd3a51","other":"89a5b92a9ca045f12c35a70084e6f41f9775a25d6f105f8c9349c7b5e107179d8a96bdbb113b2680edf5183e9a42fd64bd7b29d0dc7797c583b833f869313699","up":true},{"one":"be514f5f17f3177235acb24112b578edf0e373c469073226e547d18080905fd062d572be18e943f13bf9fcf5871e89ceb630a1b848a0e370ef8ef8c6d997a363","other":"b35f418c7935cc54278e90978c3ef1521ab91daeaf9f1ebc1cd25211611ade091cac4e1f009d71059279d507322a4536501980ac0dd44caddc52fd4c593879f7","up":false},{"one":"e2a27dcdee1f89fa362a85c4397840cd8be4ad8d1b9ccb23188c303bcab7619f38772f71385922d090390973b62fb8249efc103f71bc761041bcb3880ec0b935","other":"5142eea687de4248b2184e9896b245563117648e7a156255d9a7ae730313d5d383db3be1125b5accd7e743c2a5d8c3289ec559ef7cbb803b9e82cd49bb213d9f","up":true},{"one":"fde7705f5013c3b6b76a35505c1e3d57c033a337f2a71e912ec3a3d2da8e113bd7c36d94908357e9f7654660621f647ad8c66b0126dfe91dbfa3b8c7bd2183d3","other":"eaca77d20c4ad6b87649eba21b750a4b1a2c575e06bc42679d18fce16fea15212e9a7408c16f3b24d8dfd1e397314637e72e292845d09534a39035bd9203ee9e","up":true},{"one":"57fb1bb32bb2b1a87e44c6a7557e9c47c2032d107bcb0e34acd9ffd54d5d3df5701232db16f62f7549ba2721021898b03160b1dc5201e79606648c1dbc4a373b","other":"2245f3bf1a3b4e92f912affc75f757cf648b20474c11ffe947884f216b8f24f9dcb6e6a0358a4061b8517478ec15027e185b2f05a777573b4940375bf4aaf2be","up":true},{"one":"155e4879643a472420012e040a87dbff776fc1976814c0c6cd0d5e157f0d0baac04aa7f2535786c09acc2700547383d2119b64a6f62115f1aff1708738844d8c","other":"17917fa4da06068b587c17899569dcc768b9cd2c27117a4ed67aab26a7e70cf8d32b881db258061ffd89a332a3b29bfd963d8e171a06c3e208ba0de1c42a2b39","up":true},{"one":"2ac93c31937ca205d61cc5c2a1b9037871cac55e9b306b999b28e19566b3316f6539455e014840ea50c2db8a7c97d78804d3a2dcd7cd9c1f32ace0d36e5dd339","other":"759f46661056bcbb30c7706c9fb87e22a30feb523bd53ae5d18db043efa45b49a2b8982abebdd598fe0912a05896390ec2eabe5e160cbafc0771990708ad8c28","up":false},{"one":"be514f5f17f3177235acb24112b578edf0e373c469073226e547d18080905fd062d572be18e943f13bf9fcf5871e89ceb630a1b848a0e370ef8ef8c6d997a363","other":"fe8ac5d33cd8ab6a1dad9567cdfb89b431a5c4f4a584fc608b92e7dfd06f70988e71e2f11f9fda9ee797c9ffba83bc085939fdf2522dde39f28202be92650566","up":false},{"one":"617595a230e0a74a3db3b47cd27b941e02bdee9a84cdfa8eaa63a55941eb5caa79e20fb69726a4d46a0e5aeed24039f8c5a20679a692df0bc140f42558ca9a2b","other":"a7507aa5665e165ab2e2a07def272f0677f9d6d35bb82268a34214384e7d8ef7635a299368752e63cfd02d4e60231076baf23cfa10d17492e55181b391ecf335","up":true},{"one":"9e621c3eb534855ca292efa27a3fbc89b4f05c80a4bc65bcff2f14ff28ef43cbe14137d2fddc6fe2658bb06947d918476b479dde71469b8680e5d8a7a01619b5","other":"89a5b92a9ca045f12c35a70084e6f41f9775a25d6f105f8c9349c7b5e107179d8a96bdbb113b2680edf5183e9a42fd64bd7b29d0dc7797c583b833f869313699","up":true},{"one":"e023a51c5bd26e1754d6461345143e94baeac799947579ec7adeccd105de39f85afbceeb5037cfc0b820b9f4446433f034d9e7de7326d45df5a967a8099dbb10","other":"24662a43944228e4ff74736bcf0a0a4f79c87ecfdb739225b2fc45110c11bfc38aaf2d09d98e5817477848e553f187ac5408bdb864518dfa7f5df542768828db","up":true},{"one":"f54335964d9b4eb9813eb05f40ef1c523bbf0faac5a04c4737467d590fb6b55c7fa1fc5d4d32c5491d8766b9be6fdfd3ebdb25c5ffe1719f36c86ddf87ae3a85","other":"302c37f28c69fdcf00b39ce0c0223de0d94cebc2c0b068315b95b76b5432573ead0656569441029ba9054d8d3d959fd8735e73913af5ce3f1132f8271fd437ef","up":true},{"one":"9e621c3eb534855ca292efa27a3fbc89b4f05c80a4bc65bcff2f14ff28ef43cbe14137d2fddc6fe2658bb06947d918476b479dde71469b8680e5d8a7a01619b5","other":"eaca77d20c4ad6b87649eba21b750a4b1a2c575e06bc42679d18fce16fea15212e9a7408c16f3b24d8dfd1e397314637e72e292845d09534a39035bd9203ee9e","up":true},{"one":"76cbf9fc0f3517fb615fa96104780218e85d064ee5a1d518f3b78f4dbebf144df38c427445fdd6c9b436489c00ff9497d747a8fd70f380f95601d59e52e021e8","other":"27d9048707a89f1a61e44fdae523c0128f2a7050308bd3cfefa6c3e03040a0e22f11ab41275f22b8706e6695ab93320e2af35179d772581db5f49f960750f2f7","up":true},{"one":"2f1967b4410ea2ea8fbaf46771ba82c2846d00aecdb6f873aceae33ab38f72d0a2c2dc6046d3034f514efd090d42011d48e9ab0cb4e3caa2b49a96ef732215a1","other":"5142eea687de4248b2184e9896b245563117648e7a156255d9a7ae730313d5d383db3be1125b5accd7e743c2a5d8c3289ec559ef7cbb803b9e82cd49bb213d9f","up":true},{"one":"aa9a94d6e4eaaed20113c21752c224e3a052abd3769bd6e832759dbaf5154a943cf094eacdcb0727c2fe51a11bd7fc0793d7d5e3312b0aba89d428a00e1fde0c","other":"ff6f94005d1df7677600069764855c1c2aa0543cbe9f480f8feefec76c49d9e2c7bb2d8e38c89e9430f53f8b593d93f143c45985a56a5a32c736128214c95eda","up":true},{"one":"855bdf057f4a6b095e2000ada199447b5b4f2f8d78d2ecbaa0ff1fbf761788870ee999266ad3b26efa02be1a46a4d92ac0debb85a2ceab3442394ee7d99e5355","other":"9194a3a4c8f3235203e48bdb10902d958d26c342805ea6365af9711213536509719d917c694f9a4fbdde6889a4c92299a5301f0275bda4dbcd2541b5bff5b271","up":true},{"one":"829b074b70d757da6aa00f7bace3cf1b5d2d4eeadb7f370c1a85374a01a70b54ac53d747267e386f3b41e6d790fecdd6e74b8f89745501ee82439a66ea54443a","other":"c9cd9dfb9f90a7948ac5a42c7bd63263f2eef6e1d85547559f7d2ecbf5f9cd1eab051b8e9e661b573c275d84091a44e73f6fc6bcc91dcdb674bd5d939190fc01","up":true},{"one":"2f1967b4410ea2ea8fbaf46771ba82c2846d00aecdb6f873aceae33ab38f72d0a2c2dc6046d3034f514efd090d42011d48e9ab0cb4e3caa2b49a96ef732215a1","other":"fe62314839c93d2f6e3aee984d5f0b321897c6f39e66800d3de8b773baf6f19e0a03cae025df512aea8d5f1b667b6dbb15c192a90a76d3031c14e33e5c16c4f7","up":true},{"one":"76cbf9fc0f3517fb615fa96104780218e85d064ee5a1d518f3b78f4dbebf144df38c427445fdd6c9b436489c00ff9497d747a8fd70f380f95601d59e52e021e8","other":"24662a43944228e4ff74736bcf0a0a4f79c87ecfdb739225b2fc45110c11bfc38aaf2d09d98e5817477848e553f187ac5408bdb864518dfa7f5df542768828db","up":true},{"one":"df4c3505e09e1baa88470117b964e758c94f77a4546489ab5ab7f4aebfdce424729ace8867475715fb68f05c66c9674a5767549e266c4fadd1c703ddd735908f","other":"3b570117addeec03c2694baf28e246f91907268fe665c6c90356120332794258ee57a60853c19e9fe25d042ca42a5be7fe0797d84199174de8132f1ef4a9349b","up":true},{"one":"caaf695c76cf7c047d3f3bfe019d01618e4871cee8ff3f347913da815bbcde145771486f916a44d03f59ea9bc217f169fd0c0765fda3f9b9b28d02a522e180b4","other":"ff6f94005d1df7677600069764855c1c2aa0543cbe9f480f8feefec76c49d9e2c7bb2d8e38c89e9430f53f8b593d93f143c45985a56a5a32c736128214c95eda","up":true},{"one":"b53078000796f1cdb04dfeac424d5e3e37e30f00bd5bebf9a9ea0525c62917612b3a8f508df6bea59e3c7e4cd1aa530841f9a8af54e44f5617a13dee2c6ff007","other":"385168340139236a0e0f537fa693122db9fa02a377c96f31aae54718e92624fc0288164877e63616651565e055c53f7074ab2fdd18a837da6faf644941305bf0","up":true},{"one":"855bdf057f4a6b095e2000ada199447b5b4f2f8d78d2ecbaa0ff1fbf761788870ee999266ad3b26efa02be1a46a4d92ac0debb85a2ceab3442394ee7d99e5355","other":"f33d1f3e460574706ac1c7fc9ebb4683b173496ce3e80017d1c3521bca03d5a41a9c7a6cde8347d2238917b7cc58cab000ce7ccf6bb408561015a2ecbe613408","up":true},{"one":"48a5e01e06e297dc1c640ac9601171495bd70fea461c60e7e6e2532695e45fcf68183c2e58b5e6931a6c1c094f5331efbd7f2d93d5f84efdec5a35afa2124438","other":"f5c1215a84a56d52f92ca0dc3a32df98c98a9c2ea2e9a34560210c16de1b440d20d043c8c25955dda8c22e55e92ddb49fd82e8b9b84072aabaa755a229bb19f4","up":true},{"one":"b080891d4ba6d3ab224984360597f9c555bd1367630f5420bfaf230419a05b2be58bebf1554e53eb4c0da81cfb66d4f7697dd65143f11841ff62d8a0d82b6b67","other":"5dc69635f6d573c824ea83b18593a47f9f21a6f91ce18d2bf977c97d21f8d2a8ce88829244d12a07d949bbd52fe8a2035bc89685fe1bdd4ee20d766d75d3deee","up":true},{"one":"0b30b36e155db04c448b662c4df695068b2331cdbe2772aae5fda84159e977515a5ff2e156bc225a9281fef2383926ba8cb11e9c1846fb40db241e524ac14e29","other":"60725e8d0e9333636e598dd666f459b4be898d9abc095ee2c1db289673e7e969b50e2093956fef5a2f1d23e2040159bbabaaeab17fc6dbbac3f6acab766e9e60","up":true},{"one":"df54af3bae257d437c5657905484e0d72e9560c46f8ba6b3437730234e05259b404cca40b0831e911605ff8a68a19e8fd7e958069ec8b40595928892f4fa220c","other":"ca1aff0d847c6fdacb623ad9078a0885b3208614fea20d5ff11779779b486bf5e9c794aacf848d3c2d58cfcc1eda8356df82f5fbdd0a5236beffe8e6042848c4","up":true},{"one":"016f8f4619a16a07fbde5a18e362158d696e4d9f104a77787f26e32a25cd7d278256f8e0db865c488a99511ec27a5eddd5ebbd1c1397fa7f8db111062e5fe959","other":"9133b0b3c8f680286eae90c3beebc3099a13de38775a3ff2abdeced62d05eb2ced5ac85eac0870156be03101024da5e1d9fbf3e1066ddb3f088221e64149acec","up":true},{"one":"e2e0419a41bdfc5bd76deae2ddce6ac865f886d764c9bd18799b79fa3b2b6ba66d765d26da2037e98317e1d7e8232a61e63c1d0cfa98c9137424151b46e07171","other":"d7a319f69013b8375e64d19f015547462c84565b882337998f9e669c5fadd3d2ecf6374109903003e09f5d453424b5c7fdf52163d2cc8084cf81f94844946b63","up":true},{"one":"829b074b70d757da6aa00f7bace3cf1b5d2d4eeadb7f370c1a85374a01a70b54ac53d747267e386f3b41e6d790fecdd6e74b8f89745501ee82439a66ea54443a","other":"c903c5ee3d9cd65bea3ea777e39282c33e1349d945411fb2f16321bf582c2f400956a98fbafe5873fc5f6f6a9a051df5da7e94cbd340f935abe80f91e79ef875","up":true},{"one":"0a4eec7b0e05da799aca5b36d9e2530f2a89d1426b1fcb7d8f9a662df8a8b5b763767a20db3c9c63e0bd13c2a6e16d3ba8f03baf84f5e5d24917b3f211d9bcfc","other":"ca1aff0d847c6fdacb623ad9078a0885b3208614fea20d5ff11779779b486bf5e9c794aacf848d3c2d58cfcc1eda8356df82f5fbdd0a5236beffe8e6042848c4","up":true},{"one":"b080891d4ba6d3ab224984360597f9c555bd1367630f5420bfaf230419a05b2be58bebf1554e53eb4c0da81cfb66d4f7697dd65143f11841ff62d8a0d82b6b67","other":"396c703d27bfdddf91761f134cbf665fe61e0b3a5d24036a4105a625f72e8c28b821e9200f20d6e8f8b3ed6b95bda6b8accdd840c2f786720b7431e3af2af981","up":true},{"one":"2a63d875e715c2a43302d32d86d30c7d7faed46c08a67bf488762637216b99dd87333a66df6d9f3a57df863b1f1a219ddbeebb9f3e92e523bd08540a195448ca","other":"c9cd9dfb9f90a7948ac5a42c7bd63263f2eef6e1d85547559f7d2ecbf5f9cd1eab051b8e9e661b573c275d84091a44e73f6fc6bcc91dcdb674bd5d939190fc01","up":true},{"one":"807340e5fdf6c21a56ef2fd158c32e92201206ca85fcc147165a408f7a735964afd47c397e663610ac53870ae722c0317291732b0422f8aeedae783d9c730218","other":"0b7e1e5acabcde503ad827e45724402406114a513f81040a379b0f82df2eab4456b348b27936369c49e3c264d971c6a9e2c2217fdbc5e5b93ac6fc219957834d","up":true},{"one":"e1ecad3beeb6c19dce551e4a603c7b440b4498c44e298dc67bfaf4ed2c75bbea95df48b1cd1318e2ccb962cbae7c30ff258e73f8c3fc6b7e9ae7a47f7cf8e53c","other":"53df9cce9b0169e58ced53a123d1d8f6e8fdcfb4c2d781ecbb91bb7c8eba36946dd9d21c749259769825d8a6b3faa6bb87c8c6085a522f8a3e376061f59144d9","up":true},{"one":"4f5ab12b9c5127c16739ad0d4f51adce90ba6736cd096eb185ea632789f4b26f1ebabdea4fd3b39dda5409ece6c2d92fd469cf4aecf9d29453e3e042c19b893b","other":"9bd4f0adb9a966cc5ba632f1b540fe9cd6c8e39fe1a041b315697679cfb04b735952062ce057d456677cc34a84301f26bb727a4ab2646fee734f80a22c620746","up":true},{"one":"e267e71c2dcdbe5a500b23444d2d4037ea15afba8f4f2b1c0e54a274450404fbee6fa5439f7cddf4ba1aa28fa93e434b01c239add58e30a5423ca3a481584d6b","other":"5566111b7f14d8ec83ba6456488f3fc5c7e2c86bf406dead33b814e1ee9b569d34015a4d88226b7e28fff7784395c086d106287cbbc80acfe75b05cd6e12903d","up":true},{"one":"855bdf057f4a6b095e2000ada199447b5b4f2f8d78d2ecbaa0ff1fbf761788870ee999266ad3b26efa02be1a46a4d92ac0debb85a2ceab3442394ee7d99e5355","other":"e06a789a7f6988e1ba5e8358b6cd4292555c7f9f7f0dda6fc01cc26d24e49a8c1ad694423ad74aec6d80f4b99e2bedc49b6a5f2670744cedee3a3e1848e6dd07","up":true},{"one":"7ac5b07eb555af3bb4ca3f0f4b45204d43cc3798c244435909b97d9a32fc3abf0b50666e260e046bce826a7a102a92d389f8f39c5311e83bb34beddac29d50e3","other":"094f9d0fd3bacb17ac67a2edb8ed394fbbd1c8d478233d3269cf217e7b788e21042374936b885bf23ee4f9e03babbe4e08db283dfc2a6e052a8a5ba133717dd5","up":true},{"one":"b53078000796f1cdb04dfeac424d5e3e37e30f00bd5bebf9a9ea0525c62917612b3a8f508df6bea59e3c7e4cd1aa530841f9a8af54e44f5617a13dee2c6ff007","other":"bcf8e831821a5bca359fb824c7dc4d66906de82f3663a0a853d96880a8ca0bdddcceb1b66dd1f13f75ee20fde50fc9de545bc25767f228baee910e0dbfa8cc27","up":true},{"one":"5526d86ba9df651091d88460a9bedb9cedb957d452a635e1db46b9fed78082022adec0047cd7485956a4ecbb0e18107595de0de3c35242527cd302bf74a19260","other":"2ddd49fae11d8bd2e7e75a481be267fa846f51cc1160bc326aeea51c542323ff444909de11e2731e835140bc0b1b32020e1e73fa652511a381222bf0aebc4081","up":true},{"one":"8f88c7ec044f758f29bd8d12a5170bd973aec8f6cddbf512b910c4b75a0fec09c5e198bcd65622037f897759db68da2328b4a7ca93585dc9cb62e46d2a6c0864","other":"e3c8a97a2d95dd543f9e2b41d9dce6256e284296f866f4f92e9925f8c7519dea23fd6d1a11153b93c10d6a32295e7b9bcc16024e690e4a0dc84fd25ee0f31b2c","up":true},{"one":"1944f98d4db32c56a5efda5a79aa5f276bfab1e084d6611fec0e735b8bc0f45b457cdb74a23fc83b2377821fa8316123c9877acd6db7c41058ca5d3cfedaecf9","other":"9b618ad34d0dfe0fccbd5b8af365cbcdbb43e802df5f23e91c20d21f3ead6169d52bf0db7e5e111abef630c9853419fb33a88cf111d8507b8708208b5d65e35e","up":true},{"one":"f38a9d792173a29c61389f5d84c005d78eac6e750659aad42e2d6df883f04eb3126b2c38fac95076eeed455b2031aaf694143922aa93a2d50412a2454dc56e28","other":"92d6ef729992f0de886076e5f8cdc42cbbd70b29e79c25e0b3d22b6575d3d2508d47b42f581e335455483d43625bce4e55f88cab9ff2073ee8dab746357864fd","up":true},{"one":"e3c8a97a2d95dd543f9e2b41d9dce6256e284296f866f4f92e9925f8c7519dea23fd6d1a11153b93c10d6a32295e7b9bcc16024e690e4a0dc84fd25ee0f31b2c","other":"2ac522ebfa49d37f86c6270ad4cdad0e766493f0e463b18c9906c70fbd2e5c6ff6b0d5879de6e3894418370636963a78b0c0cf087a8684c2ca30c9c736e49228","up":false},{"one":"48a5e01e06e297dc1c640ac9601171495bd70fea461c60e7e6e2532695e45fcf68183c2e58b5e6931a6c1c094f5331efbd7f2d93d5f84efdec5a35afa2124438","other":"2b70e5ffcc0bb1c4f8acc09dd1016e67c9c96c92d091ad481efbb71bd8b2a5a5869c6d668617a9b2cbfe91baf5edfe150c3824c84d90899a974099071d171441","up":true},{"one":"a7378ee34876af17c6cd94a69b6b741ec7891ff5375bc4241d48608d047455ed48e6baae80ee88d4710c69ae615cf195cee26c94b54de1bb935628ce1e3a723a","other":"3612863ce0456c91785a829bf5c9d2b2fb97dda083a1847e5a4ebaa6fce1260faf4d1eb374c2225431a82774163835fb59c8cb0fa9fc0969eab5410c71109cc2","up":true},{"one":"352407b42726dcd1aacc46a912ed8124b8b6a3da4e33dab742e40aa2452953d35dc8f42eddc76695ae2317e9f15dde2cd21be4ce826934695ad1847455661d1b","other":"b35f418c7935cc54278e90978c3ef1521ab91daeaf9f1ebc1cd25211611ade091cac4e1f009d71059279d507322a4536501980ac0dd44caddc52fd4c593879f7","up":false},{"one":"5bf29c02f07faf7ae8e46389e1b98df4f5e88c9316b5151685e6ae7b4e622cf171ff09f996aaa8ad846643b3bfcbd1ad96cdc249afccce439bb5c55246b95801","other":"4314b0b04331973ed29a58843951f144ac3d09bd5d57b6cd9aaff9b73a7b2ec81e344a3e4ece462bd2081b837a06310e787ef3bb889dabad46fe7efd394c8342","up":true},{"one":"7aaf7817b93aa6d2f50513791f9ad7629a901ed0dcb151189f44763f83423446b20ec79a48fa260cd9bc2907d5f0ad06b2c4c5e6d812f3d8876c8020ebe41019","other":"2ac522ebfa49d37f86c6270ad4cdad0e766493f0e463b18c9906c70fbd2e5c6ff6b0d5879de6e3894418370636963a78b0c0cf087a8684c2ca30c9c736e49228","up":true},{"one":"1bc1d6155ba35d29ea16938994e08df76ebd8f16bd180bd6a9b9d8798d0745889fe72d641dd78bd8ec13526929f7eb5aaa6a388430fa69033d6db581e53c6422","other":"b26f7c0113a5ae885f7c0e608aea7022a9c8bfc40c5643e60b2ba7343ff09c5be0bc08be34dde3c6b85fea192a46d4764770c12cbaa233df4231a1b99627ef9d","up":true},{"one":"2ca05ffc0ad771e1e045a47f1c0a79ce374a25e3c0e53c2a80d67e7479677003f62880251a83a5074f1c9651d828f1ff7e352935a9df141c1eb75a0c59b00a8b","other":"5dc69635f6d573c824ea83b18593a47f9f21a6f91ce18d2bf977c97d21f8d2a8ce88829244d12a07d949bbd52fe8a2035bc89685fe1bdd4ee20d766d75d3deee","up":true},{"one":"8d4920d6e3a6717699b5a3af068cbdfc16858d7e393d158d41b1b5f345b47129eef89e1d055386c518f400b134678c21590f0317dea3436d4cef60f45455cf12","other":"5dc69635f6d573c824ea83b18593a47f9f21a6f91ce18d2bf977c97d21f8d2a8ce88829244d12a07d949bbd52fe8a2035bc89685fe1bdd4ee20d766d75d3deee","up":true},{"one":"c8b0dba45104fc7c7dff3ce078a0d3f5ade6198bb4656e2bee8076387929133e5ef2bd293b130a9d4f6a6974ca17e8b4a8f406d1219880f1e0f99c65c63af5a4","other":"2f903b2fd4f9432b7d91b5c3e4c7ee3cb9c56fe7efc4baff0edd06fc75e4b7492f2c3c929755746df59c9f95d437a12ba40ac138d08f5bc7aa091f49f3b852c2","up":true},{"one":"8d4920d6e3a6717699b5a3af068cbdfc16858d7e393d158d41b1b5f345b47129eef89e1d055386c518f400b134678c21590f0317dea3436d4cef60f45455cf12","other":"396c703d27bfdddf91761f134cbf665fe61e0b3a5d24036a4105a625f72e8c28b821e9200f20d6e8f8b3ed6b95bda6b8accdd840c2f786720b7431e3af2af981","up":true},{"one":"caaf695c76cf7c047d3f3bfe019d01618e4871cee8ff3f347913da815bbcde145771486f916a44d03f59ea9bc217f169fd0c0765fda3f9b9b28d02a522e180b4","other":"cd8815d66aee8bd488d4e5e25f0cc9c71cc65349f701ea26b1d6cd9c039d16fcb473dbf270a3b33187720ccf4b0ce4f78a6d6edd05f4fe804772d5b6ec45bbd3","up":true},{"one":"4b784f072b7c96c30612767425f552e30e45157e70139dfbe0ae4ff86dc31601adec60f8a3ad9747b02b5219073d8813af9b09d59eaf7ddb7ee24856aff6fa8f","other":"e267e71c2dcdbe5a500b23444d2d4037ea15afba8f4f2b1c0e54a274450404fbee6fa5439f7cddf4ba1aa28fa93e434b01c239add58e30a5423ca3a481584d6b","up":true},{"one":"6b01079463ec2f649db8634cb7a596261c79a8f714d954c772528e0547b017f8ce405e4a0ea9d32270848180e0f77b8c0b022cf95c85e777626edd4d24ea21d2","other":"aacff366e601e072a2113add9020e19b6612f3e85b6e607fdc8cc1b6991f43be0b1f835ed3dc41d1f2b3e0caf7fac252c8eb4c150667d48207fa92ea5f0a7455","up":true},{"one":"8f88c7ec044f758f29bd8d12a5170bd973aec8f6cddbf512b910c4b75a0fec09c5e198bcd65622037f897759db68da2328b4a7ca93585dc9cb62e46d2a6c0864","other":"062e0ca43a1885c4a7ab2a5169790f9081e3e9a2dfa286b8cc592d5ccbf13d7a82b72d23361a19026d04fcf41b752ea320d98359d770aedfcee626e21c3494b3","up":true},{"one":"66d0c5da973d9dd65350ae1ec63776872cdb7ded6afb6f51ae82259f6fd35e884375d15de290625f02ed2e5cdc3f591decb45e5fc64d5b0f835a216fd196f5a3","other":"b35f418c7935cc54278e90978c3ef1521ab91daeaf9f1ebc1cd25211611ade091cac4e1f009d71059279d507322a4536501980ac0dd44caddc52fd4c593879f7","up":true},{"one":"6bf9fb6a25521c16c2ebeb6203d046d7dd40f29cc2ddb067c0222ef56d7012d2ee5d037f71f6668ea56767610b2a54c144aed74b7f68d06993cbd52fa1dc7630","other":"bf4ff51cc3d9a9d8cefd7e346ce1384d06450228a6086fe12fb0c60fec54bb6478f090bb638fbdbf8f41f7bc6420cd8a5c8b1b8566229b6851167375ef412f46","up":true},{"one":"f33d1f3e460574706ac1c7fc9ebb4683b173496ce3e80017d1c3521bca03d5a41a9c7a6cde8347d2238917b7cc58cab000ce7ccf6bb408561015a2ecbe613408","other":"e06a789a7f6988e1ba5e8358b6cd4292555c7f9f7f0dda6fc01cc26d24e49a8c1ad694423ad74aec6d80f4b99e2bedc49b6a5f2670744cedee3a3e1848e6dd07","up":true},{"one":"ff6f94005d1df7677600069764855c1c2aa0543cbe9f480f8feefec76c49d9e2c7bb2d8e38c89e9430f53f8b593d93f143c45985a56a5a32c736128214c95eda","other":"1b6cad4f9851cc584c5d1405f976bb51a52e27ef4525847df543dcca65ca5eb1ef229dcc68ccbaaf00ab1e044cb5990dd213c805bdb4adcceb6fa70b5c61fdb4","up":true},{"one":"72e30d4562673c5c8fb03709d93f73322747858d723b7eb5ef2fbb88e0331252946b7e93ffe434fcb599c4fff57800afb29e6c60a719f18f49dba541c3591c6e","other":"fde7705f5013c3b6b76a35505c1e3d57c033a337f2a71e912ec3a3d2da8e113bd7c36d94908357e9f7654660621f647ad8c66b0126dfe91dbfa3b8c7bd2183d3","up":true},{"one":"0cacda5560faff9d20e29a0625d3cd340ec075f198a50ab8b79338cee0e0db84c7c7e71042fd8c8f73e507b570de5d26c39473136b575f0167625a1168309ec5","other":"bf4ff51cc3d9a9d8cefd7e346ce1384d06450228a6086fe12fb0c60fec54bb6478f090bb638fbdbf8f41f7bc6420cd8a5c8b1b8566229b6851167375ef412f46","up":true},{"one":"1f6d803a4ca186463772850ca0901fb920af7e74fdd2480c3c368fa707838ee91bbcfb57d5e3510c802b9b85f2d954f04c9b675414274bdaebae6488dcf94c10","other":"0b7e1e5acabcde503ad827e45724402406114a513f81040a379b0f82df2eab4456b348b27936369c49e3c264d971c6a9e2c2217fdbc5e5b93ac6fc219957834d","up":true},{"one":"cd8815d66aee8bd488d4e5e25f0cc9c71cc65349f701ea26b1d6cd9c039d16fcb473dbf270a3b33187720ccf4b0ce4f78a6d6edd05f4fe804772d5b6ec45bbd3","other":"2f360209383d6de4ebd3b4abaf77796520b8654270b03f2151eac4a01b4417d7e0668c1f9ad30c20ff49aa8a0ab33dba5e6095619d1cf04b7af841722ab773da","up":true},{"one":"7174eca109a1f717653918224c8cfe1b7fbd666405196760913593401eb79f2c7e41003b01f5a458940695b27a4673443c7621a169db7fd968994e552995dbbb","other":"b6a998dea59194cc60ce97c7c9702368411889cb6905516b23f41cc5116fba8d0f237d418318eb0c333cad18003c0e9a6bd8c99080520771f2bad640e2e5ec1c","up":true},{"one":"22010c9829626a6892258b09cb3f3edc3f21382fb487b5dbf0dd20e198e37e26134aab850e30337f398d1491b5126839aeb1953ec144bc19aeb889c832f67c6a","other":"1bc1d6155ba35d29ea16938994e08df76ebd8f16bd180bd6a9b9d8798d0745889fe72d641dd78bd8ec13526929f7eb5aaa6a388430fa69033d6db581e53c6422","up":true},{"one":"6f60ef501b41f9049419b033ae8d793a18067bdcd60347537b0dc3873bdd9a2d10d24909cca7c39781765746128c2165596f6537a94f58279523faee71f9c51d","other":"a99852c5bf08ea4713af9cade5343d1259bfb90401aca7fcff18c58cd56a98804dd16c61fea71039c0ac31b9bbbb9dc5aeaf0c2f074d3365e88d17031802d636","up":true},{"one":"5420da16f7ed5de6b498dbc9a83b7e92e1f9900a6d04ef7351a0bfdfd442b98a5634f28fcea32ba3f3166d21c8ff5a39be70895b32acbdf7592d1d616a345a21","other":"4b784f072b7c96c30612767425f552e30e45157e70139dfbe0ae4ff86dc31601adec60f8a3ad9747b02b5219073d8813af9b09d59eaf7ddb7ee24856aff6fa8f","up":true},{"one":"e087230634f556b818a416b66ba3f1d1dbe3e0dd0698bbb26fa86a2499acd169466f564dc18adf2f9be4d1ada0e86c11549754097601e10aff4f3a57ddffa24a","other":"c83985973a9564ade7d90aa54911ac57077600676a1d27292d98e058bf1315887bad84ccd708cb7f52a695a1405fb7d491d7ca2ae9caa3ff58a5ad78ce4dc9d9","up":true},{"one":"5566111b7f14d8ec83ba6456488f3fc5c7e2c86bf406dead33b814e1ee9b569d34015a4d88226b7e28fff7784395c086d106287cbbc80acfe75b05cd6e12903d","other":"0deda014fa3c0bc8f37d853e1448f95f56f97048c28797d72258fd3ba2f1f776ae11566197466596356cd172847ab02a89f4cf047e58383249fb2a4cd69b6206","up":true},{"one":"ee36d1d5dd69fd30242d7da2e941b34ade5581c7164fcc43288ecfc52937a98f1b31ade5d1e4dbf611cbe1c7875b2840c89435081cde471c271d7bc60e9ef211","other":"485825745d97654cbb92a14e0cd1078691d3c28f4d82b1046284b676a42b44ca58eb43474e45e415d3bd3f3c383f9a1a3365821ed7ba6a9f2603b29d58031dc7","up":true},{"one":"8ca3b63cb84f1e9883d82809a9b6777ec1029ecda96fe93b4d494ee9cbefcad13f381b3e480136e542e01054fe1ede66c65db84a0009871ce49383db461c8438","other":"8d4920d6e3a6717699b5a3af068cbdfc16858d7e393d158d41b1b5f345b47129eef89e1d055386c518f400b134678c21590f0317dea3436d4cef60f45455cf12","up":true},{"one":"68cc8b9a995eef6170abf88bd5fedca06ffcc8d75f247f6041c13e7dfd292727ebda1ff86b776e33b6634355c55e0f8c22fcdb5f9a6e2f22fe1af7854c3b4273","other":"0cacda5560faff9d20e29a0625d3cd340ec075f198a50ab8b79338cee0e0db84c7c7e71042fd8c8f73e507b570de5d26c39473136b575f0167625a1168309ec5","up":true},{"one":"24662a43944228e4ff74736bcf0a0a4f79c87ecfdb739225b2fc45110c11bfc38aaf2d09d98e5817477848e553f187ac5408bdb864518dfa7f5df542768828db","other":"c2705ee7238ef9305e4da196653cde707649435a1e8b5b797d164e5ca06184a77af5bd7fa938c995fdfcbce724fa7eca3d908ee34891ab62cc6dfd411c3fa1da","up":true},{"one":"27d9048707a89f1a61e44fdae523c0128f2a7050308bd3cfefa6c3e03040a0e22f11ab41275f22b8706e6695ab93320e2af35179d772581db5f49f960750f2f7","other":"c2705ee7238ef9305e4da196653cde707649435a1e8b5b797d164e5ca06184a77af5bd7fa938c995fdfcbce724fa7eca3d908ee34891ab62cc6dfd411c3fa1da","up":true},{"one":"ea57884dd42aec5a76eab43483bf7c4ae2c19eebf365013731de64494d10a3b4cfe34c86c79437f9012bc8cf6bd761435eefadec17600f4b9e4bc234532d6282","other":"c2705ee7238ef9305e4da196653cde707649435a1e8b5b797d164e5ca06184a77af5bd7fa938c995fdfcbce724fa7eca3d908ee34891ab62cc6dfd411c3fa1da","up":true},{"one":"a127faa19dcb7da585983d36a8e9d3e9a44a6db68507b60c70da71011f44ce377944802f39cd65f5a705cd8249ac1ef7ed8fd699349098f3f8e23b37592c80ae","other":"66d0c5da973d9dd65350ae1ec63776872cdb7ded6afb6f51ae82259f6fd35e884375d15de290625f02ed2e5cdc3f591decb45e5fc64d5b0f835a216fd196f5a3","up":true},{"one":"732393b99c490c76fa45e3e404ee095f2fa445fcc123af7ac8ab1d2fdd7cf2483f5b82bb818bd8a82b1a3b73e63bcc2c83d8f24d9aad9afe36503735e7967be7","other":"bd1a7c63fca9e1fcc67d7fd62670beefe2bce483cf1dc1233ee85eb90db607917cd9a5d7170b10e80b925a20e2af2c54d286b01805ac34967410859f4f03da09","up":true},{"one":"baa5924e1547c177011285d292aa161a15e5ff282da2cd0afb83c9caffb07bdbb3662c227fa7b26e6dc8be9b8863e647eb5f8ce81640532f8f5c9a7f36557e63","other":"c57ea182bdb42ba9b0870b5c870e467f52693e5c0df752fb6eb0dfbacce7763f73caee10db40f4fd90f19f504ee586eaf9da41f5ee93ee515d885fec99374116","up":true},{"one":"6c143960dbe3ba4c95e8debc1fda5f420a2a673eb46f7ff7d9a30f4cd2067e67ef8926bf17f0c99b16c79b6dc066b52409a11d47117d4fda4211636b1b74f96c","other":"a7507aa5665e165ab2e2a07def272f0677f9d6d35bb82268a34214384e7d8ef7635a299368752e63cfd02d4e60231076baf23cfa10d17492e55181b391ecf335","up":true},{"one":"be026dfb24847cac2d00f483104edad06ca8ecb9e1229c479ef5650c7b427cd5dc34a1cf06172c17c9d0406ce17009712e82446394743d4cd9bbc41c537ebc14","other":"baa5924e1547c177011285d292aa161a15e5ff282da2cd0afb83c9caffb07bdbb3662c227fa7b26e6dc8be9b8863e647eb5f8ce81640532f8f5c9a7f36557e63","up":true},{"one":"032b9bf2f59f15571821611d3ee541aa748c86d47fbe5f049fd0069be53e5d7c41991d82957e9c727654c3aa73ec94997c03d8a6c1d2007c9bb1a703f6215158","other":"baa5924e1547c177011285d292aa161a15e5ff282da2cd0afb83c9caffb07bdbb3662c227fa7b26e6dc8be9b8863e647eb5f8ce81640532f8f5c9a7f36557e63","up":true},{"one":"b597c9ba4da20c49fc4ba019571321d2579588636cdaceb9f225706574970adbf4771dcf186b1decd4e14cd5d257e30a36ca829829598c1775902201ad9793e2","other":"d3105ede6c21bc643d523afcd1309a5dcf03f70797a92f167c3a19f86ae98882fe1a9d4094d7a3dee4a0833b8075b6c3e9aaa7f4879dc47bb388c3ae85522288","up":true},{"one":"ddaf3f8478501cda872c056c72063eb64d5b871fc5fff70704872802289dd2d348f73bc342b7f148a90cfaae2448ebf16fea196be9df891dc71a57fb410d59dd","other":"59b53f8a562bee519276e0eeccfcf8c975d3102f5d0cccf5abcce291a8a5bb817c04604f123686177a50a03b9d7559ac469962d0159d1d93e4ce58a304d04b55","up":true},{"one":"0c14dd51a56130c51009e3ce47c96b2afef26b7e86cfca65d8a9bae1abef13b3a7a192b422d894c39e24ab00be412d166a3571cc259ff4462d4ad8925a153766","other":"062e0ca43a1885c4a7ab2a5169790f9081e3e9a2dfa286b8cc592d5ccbf13d7a82b72d23361a19026d04fcf41b752ea320d98359d770aedfcee626e21c3494b3","up":true},{"one":"2e409baefbd821485a151993356730e5989810d581e68190fbaa142799c9335bcf98310ad188fed10ae6eb6e2e789730393e509962ec5c0fef0342d72ed088d9","other":"eab86c521f8f1ac67c015ab713f1236a08b0200757a96bf87ab8301e7967ae62361f0e14da14ca294fc8cb3b4726b52f4773101e21b032977c6a647241b59c73","up":true},{"one":"84abcbc7b5598ecfd91ceace0927921a5a3404fdb274fc2a2549abbede5f8e4f62c15688a4dc9a2d80262c45970c88898da245c6eb779f327a81d53a17bbc74c","other":"2e409baefbd821485a151993356730e5989810d581e68190fbaa142799c9335bcf98310ad188fed10ae6eb6e2e789730393e509962ec5c0fef0342d72ed088d9","up":true},{"one":"59b53f8a562bee519276e0eeccfcf8c975d3102f5d0cccf5abcce291a8a5bb817c04604f123686177a50a03b9d7559ac469962d0159d1d93e4ce58a304d04b55","other":"2f360209383d6de4ebd3b4abaf77796520b8654270b03f2151eac4a01b4417d7e0668c1f9ad30c20ff49aa8a0ab33dba5e6095619d1cf04b7af841722ab773da","up":true},{"one":"cb321c9b0fe2eb3617b8e2461aab170a9dad2c9b04a10eead4e37e551197ea0a7500eb1cb7b155efe1886486ef3d252d8ff0d309f2906a1126ca011d037da70a","other":"f38a9d792173a29c61389f5d84c005d78eac6e750659aad42e2d6df883f04eb3126b2c38fac95076eeed455b2031aaf694143922aa93a2d50412a2454dc56e28","up":true},{"one":"385168340139236a0e0f537fa693122db9fa02a377c96f31aae54718e92624fc0288164877e63616651565e055c53f7074ab2fdd18a837da6faf644941305bf0","other":"80d997b87856099d844187d3d1fa40846ded652a62c1611b35919c2543915b64ff62476636488556f678e436ea26fcc40db7c6b6bbcb78f590d61c1ff0e424b5","up":true},{"one":"b26f7c0113a5ae885f7c0e608aea7022a9c8bfc40c5643e60b2ba7343ff09c5be0bc08be34dde3c6b85fea192a46d4764770c12cbaa233df4231a1b99627ef9d","other":"4b784f072b7c96c30612767425f552e30e45157e70139dfbe0ae4ff86dc31601adec60f8a3ad9747b02b5219073d8813af9b09d59eaf7ddb7ee24856aff6fa8f","up":true},{"one":"17a79cb279306b6bbd35219278f6bba03111079d6c4fadcd3c5e57b09678e111bda5f8e36ca3d223e51e255d6e857363b7741e438b32ec6e6c0dc1b224071081","other":"b2538d4edfa736bfe2cc21326a44ce62f716b3480eac93584a2233b69c98883a2bb255f246218a58cecab1d0d176e6d1fbba9782fd70d4603e01742299b9ea9c","up":true},{"one":"c9cd9dfb9f90a7948ac5a42c7bd63263f2eef6e1d85547559f7d2ecbf5f9cd1eab051b8e9e661b573c275d84091a44e73f6fc6bcc91dcdb674bd5d939190fc01","other":"043fe7085e8c90c18270f84dba5fab138e50216a1cf8d81a3794d156fad7fc81d1422aff169b244b13f91d73eebb5de464f97b1b93b3ad2a58959cff19238842","up":true},{"one":"1090e9d89cb278a30063a5396d9ba795d3bbc237c76915a6fb7d23aa1822c8535d2fccc44cc8cd2acec68444c0bf1bdf5195ebb9f3cad8dac3d94a4d9c0e5309","other":"302c37f28c69fdcf00b39ce0c0223de0d94cebc2c0b068315b95b76b5432573ead0656569441029ba9054d8d3d959fd8735e73913af5ce3f1132f8271fd437ef","up":true},{"one":"d4b7c787981abec24353c7d496661692233797e3758189bf909a69fe87935bf6da0940daa4f12e81f20c5e88f70b472113688b71a0ae2f91a73ee0e6ff4c8591","other":"df4c3505e09e1baa88470117b964e758c94f77a4546489ab5ab7f4aebfdce424729ace8867475715fb68f05c66c9674a5767549e266c4fadd1c703ddd735908f","up":true},{"one":"2245f3bf1a3b4e92f912affc75f757cf648b20474c11ffe947884f216b8f24f9dcb6e6a0358a4061b8517478ec15027e185b2f05a777573b4940375bf4aaf2be","other":"df4c3505e09e1baa88470117b964e758c94f77a4546489ab5ab7f4aebfdce424729ace8867475715fb68f05c66c9674a5767549e266c4fadd1c703ddd735908f","up":true},{"one":"abd8f5a4d700c06ec00684b23d2d25c4df1a9554fcfc57b0ddc3fa476e6a699ba75e1213449f900803f83ab8194c6746664b547202047f35b8b3e216c7147bf8","other":"94088fe273f76e62ca4e43c095ad12215b4ae4c59942328b3985416fb19bbda0cacc143a49eff3fb644ad53a19d3f043260e43dbb70a0aa9c15829c21cecd3c7","up":true},{"one":"1bc1d6155ba35d29ea16938994e08df76ebd8f16bd180bd6a9b9d8798d0745889fe72d641dd78bd8ec13526929f7eb5aaa6a388430fa69033d6db581e53c6422","other":"1090e9d89cb278a30063a5396d9ba795d3bbc237c76915a6fb7d23aa1822c8535d2fccc44cc8cd2acec68444c0bf1bdf5195ebb9f3cad8dac3d94a4d9c0e5309","up":true},{"one":"f6ca39b3ad803e99f4e4e9cf759fff6abdf06e6972bdbe524f6eb930c669d6f0e9b91f3de9df394b0d661b068273861391bdbac948ad911351c48cf02f874db6","other":"88d5c5fe61ee1e6fa5878e0eaa13bdabaa0ec3d38a5d25b95a467da7627424f25fb5d30535aa0a5ad01c16fe2598dbf570b78cc152a7f4ef66d46fc9ae43592f","up":true},{"one":"831cde5b651ba327b059da4c7f84b184bdd6bb99c6690ae816affe25d42c6c3dbe5b59e2b6bf23e9d0f6c485bd341ea57ba1a8220d18b0a40e156b77d84f79ef","other":"beec648d79437a5d7b4140ced45d82d035c6f64f9c67c58386703811d97c3846787eaf274d2298df809475f0b7519df696563cb8e9a5fb0a9cc419ab13fa8d41","up":true},{"one":"2f360209383d6de4ebd3b4abaf77796520b8654270b03f2151eac4a01b4417d7e0668c1f9ad30c20ff49aa8a0ab33dba5e6095619d1cf04b7af841722ab773da","other":"f915e2398aa5d4370de87504dd76c21a7d0be2581c2ab55b7a47743f1bbaef36384eaacec22760f1e914ceac9d96a10c3d66eb27475ef444e77fee979e6e88cb","up":true},{"one":"4a030ebcb1a59230759d25a3c87daed22906b520d55a78eab2083bb52358ddc3a5d2d7c3265e6c54a990bf32d0dacb85905a4173d72ac18fcd74c43ecb8635c5","other":"abd8f5a4d700c06ec00684b23d2d25c4df1a9554fcfc57b0ddc3fa476e6a699ba75e1213449f900803f83ab8194c6746664b547202047f35b8b3e216c7147bf8","up":true},{"one":"329145e75496cecb5f5c8f00313a52ddd8c0e8cd27ef1b2bc1b2b56e4d4089aaf5a7a3c4d9a40bdb92483fa05bd24d1cd0fd51883e30439dffa0fc855e1a7cd0","other":"adfba6d883cacbb141cd8c59ee04d7e5d520f1ce31a81e5db2d8b2380bf801c1fe4b265a66b71f9643d13a41cb1f6fb4b83399be786da4b6e171b6784bc56e49","up":true},{"one":"53df9cce9b0169e58ced53a123d1d8f6e8fdcfb4c2d781ecbb91bb7c8eba36946dd9d21c749259769825d8a6b3faa6bb87c8c6085a522f8a3e376061f59144d9","other":"535f93057d46c4aae0902546550880be0b5ba67dca12350117d471d67f4f2b3f7bdff29bdc918767974c465df8fa1afa6bd6c29c0a36d51f71c4183673d906f3","up":true},{"one":"b870935867183bbfb84add16b9f56c02c834b7042fc24ce6bcb2a7f174e6d2239357a00be4272c1ef05c7f9baf5a9f16b53bc18328a9b7aca8540c2916805b57","other":"b4fd11306b1416a9bcf4719578976188e104b8c5028b9abd3214d257446b97b70a22e6c00934d80caddde15e8e4d16af03bb399583047983fba373d8313226b7","up":true},{"one":"4fe37f2dfb03707c90a6fe91dbcfd7497db70ffc20043091d50e1cee573210c144e8749340f2c3cb70fe8fc51b317d49e8734dc51ce64b3cdccdd639ae35d1ae","other":"b4a5efa9028b2d196855393892f79993c2812d02b758f98813ddf82c5d943faf6d66eff811cc5a51936c118f4c768c0d13b54902095e040c602761e63c08655e","up":true},{"one":"eaca77d20c4ad6b87649eba21b750a4b1a2c575e06bc42679d18fce16fea15212e9a7408c16f3b24d8dfd1e397314637e72e292845d09534a39035bd9203ee9e","other":"db8ba71afeaea1f2964e8978a6eceeb9efa3958424424022213c8193443f8d5afd18490afa954c76360c681404809c7cfaf7e4ebd8bd1a42d403f7f1915b0d29","up":true},{"one":"2ac522ebfa49d37f86c6270ad4cdad0e766493f0e463b18c9906c70fbd2e5c6ff6b0d5879de6e3894418370636963a78b0c0cf087a8684c2ca30c9c736e49228","other":"b870935867183bbfb84add16b9f56c02c834b7042fc24ce6bcb2a7f174e6d2239357a00be4272c1ef05c7f9baf5a9f16b53bc18328a9b7aca8540c2916805b57","up":true},{"one":"07c63ca5d0309e30d1ab12e7fc142e6d37904b552639cfa97850161491f28f20d87e0304be29357bcfc2ff52fc52fd0d4f6e6011ebb239cced8b5c8dad7abf45","other":"11d560045536e9d1b0b1b9e8944e00f0ca7f1e6788c9fdb51061820bbb3008ead92bb7836621bf58da7035c87a28328faecb4cb2e3cdb9d7fa4f45790e6bf352","up":true},{"one":"62666b24d1026345349edb6a878cdc27d6fee8254e83f79a298ce2805260d97aa46423deae440f86ced5cd99b30e970c8e1ea1046752b17d8c80dc68d9a49b60","other":"e087230634f556b818a416b66ba3f1d1dbe3e0dd0698bbb26fa86a2499acd169466f564dc18adf2f9be4d1ada0e86c11549754097601e10aff4f3a57ddffa24a","up":true},{"one":"7bbb3f3ed51cf84c077806fbd6d3578e105bc32aa6043da188793f066ad6df383a9f7cc0bd3124f4c887704bd188d480ce264fcdf178905bbda3b270927ea138","other":"049a2b0ab4d49789dbbe1837e2d2ee5220a9401729ea87ab29385b24d79cdce255c3d2b5de6484d49ca6ce07bd41832598260c0a8c290e01d133d77f066f2f99","up":true},{"one":"617595a230e0a74a3db3b47cd27b941e02bdee9a84cdfa8eaa63a55941eb5caa79e20fb69726a4d46a0e5aeed24039f8c5a20679a692df0bc140f42558ca9a2b","other":"caaf695c76cf7c047d3f3bfe019d01618e4871cee8ff3f347913da815bbcde145771486f916a44d03f59ea9bc217f169fd0c0765fda3f9b9b28d02a522e180b4","up":true},{"one":"9bd4f0adb9a966cc5ba632f1b540fe9cd6c8e39fe1a041b315697679cfb04b735952062ce057d456677cc34a84301f26bb727a4ab2646fee734f80a22c620746","other":"62dab8b21640e1b44dea452dd7e7de93f27a44840da72d56b11aa96e8463f3a4bb15e75a954d19fc897ae0030b16181d271b79d8198b7cffcddaa9ffcfdcce73","up":true},{"one":"bd1a7c63fca9e1fcc67d7fd62670beefe2bce483cf1dc1233ee85eb90db607917cd9a5d7170b10e80b925a20e2af2c54d286b01805ac34967410859f4f03da09","other":"2ab9513899c3c829b6284e56bf2b9862dd0156ec052b58615dba77d450dac642e534ec36ae5d3234262aff54e19f99856e908b9d8c1da660a7834a445610715b","up":true},{"one":"979838eaefcff456cf1cd9c47ea46854704f5757d8d7ab907019bc422b01af4d62252579bf045d143fab491b0bab823190e2782a457fbf51aa99ae17ec9e145f","other":"043fe7085e8c90c18270f84dba5fab138e50216a1cf8d81a3794d156fad7fc81d1422aff169b244b13f91d73eebb5de464f97b1b93b3ad2a58959cff19238842","up":true},{"one":"2b70e5ffcc0bb1c4f8acc09dd1016e67c9c96c92d091ad481efbb71bd8b2a5a5869c6d668617a9b2cbfe91baf5edfe150c3824c84d90899a974099071d171441","other":"617595a230e0a74a3db3b47cd27b941e02bdee9a84cdfa8eaa63a55941eb5caa79e20fb69726a4d46a0e5aeed24039f8c5a20679a692df0bc140f42558ca9a2b","up":true},{"one":"f5c1215a84a56d52f92ca0dc3a32df98c98a9c2ea2e9a34560210c16de1b440d20d043c8c25955dda8c22e55e92ddb49fd82e8b9b84072aabaa755a229bb19f4","other":"65e954e60837bda10654480b227fa3bcc6e63356c52079002a27e836cd82ae2934ba77da60080e4b9f2d9324b982b24959bfd9624302e6c330408381054b43e9","up":false},{"one":"ae4e21e1587a8475afd299e00ca7085c7bf2a44c2c64a3068f12223d9202b0125094385319034691ec26b497ec9cf18fe8c0839224bac1b84279410241cef979","other":"8c6d77833bf1a98beabe7a92d985d13d52fb2e50768719ffbc6fce21ea676802a074b6e620b3ef80e12fad04f94a3c288d91df9716a6cfae09ef073b9dc1f2cb","up":true},{"one":"9e621c3eb534855ca292efa27a3fbc89b4f05c80a4bc65bcff2f14ff28ef43cbe14137d2fddc6fe2658bb06947d918476b479dde71469b8680e5d8a7a01619b5","other":"fde7705f5013c3b6b76a35505c1e3d57c033a337f2a71e912ec3a3d2da8e113bd7c36d94908357e9f7654660621f647ad8c66b0126dfe91dbfa3b8c7bd2183d3","up":true},{"one":"f54335964d9b4eb9813eb05f40ef1c523bbf0faac5a04c4737467d590fb6b55c7fa1fc5d4d32c5491d8766b9be6fdfd3ebdb25c5ffe1719f36c86ddf87ae3a85","other":"c9cd9dfb9f90a7948ac5a42c7bd63263f2eef6e1d85547559f7d2ecbf5f9cd1eab051b8e9e661b573c275d84091a44e73f6fc6bcc91dcdb674bd5d939190fc01","up":true},{"one":"7f357b8d81bc2e5c6fcb081f23a42b3e2439f050d45c45851994a268d1c71fcb1f39f8c3f75ce921d3fbf80fc0e73f0b9609d72001dc4a6b65b526d312a4f43a","other":"6b01079463ec2f649db8634cb7a596261c79a8f714d954c772528e0547b017f8ce405e4a0ea9d32270848180e0f77b8c0b022cf95c85e777626edd4d24ea21d2","up":true},{"one":"40bdac599b00e9c41ad6476ee415c33d9c17c5aa672692c2404e523b29dc315da929a86874bed87fd9009871805d1dbf3098e7a817193e3b08a6eee66346da79","other":"fe62314839c93d2f6e3aee984d5f0b321897c6f39e66800d3de8b773baf6f19e0a03cae025df512aea8d5f1b667b6dbb15c192a90a76d3031c14e33e5c16c4f7","up":true},{"one":"fe8ac5d33cd8ab6a1dad9567cdfb89b431a5c4f4a584fc608b92e7dfd06f70988e71e2f11f9fda9ee797c9ffba83bc085939fdf2522dde39f28202be92650566","other":"28d3232c43de54ffdaf08f97b334c012738648b04e2876c7e751a2e352aaf4d550d6efa976c5a8edbfa8e88b9d04a0fca492b81c3756ef673ab74d34182ca711","up":false},{"one":"e267e71c2dcdbe5a500b23444d2d4037ea15afba8f4f2b1c0e54a274450404fbee6fa5439f7cddf4ba1aa28fa93e434b01c239add58e30a5423ca3a481584d6b","other":"829b074b70d757da6aa00f7bace3cf1b5d2d4eeadb7f370c1a85374a01a70b54ac53d747267e386f3b41e6d790fecdd6e74b8f89745501ee82439a66ea54443a","up":true},{"one":"df4c3505e09e1baa88470117b964e758c94f77a4546489ab5ab7f4aebfdce424729ace8867475715fb68f05c66c9674a5767549e266c4fadd1c703ddd735908f","other":"0cacda5560faff9d20e29a0625d3cd340ec075f198a50ab8b79338cee0e0db84c7c7e71042fd8c8f73e507b570de5d26c39473136b575f0167625a1168309ec5","up":true},{"one":"1b063741c76fe65e62b4eae42751319d0cce66f22dde9f1cf83d6cca249a0e65bc7f6f22597697362fadd226222fb3847f8e146961969d1b4c9f7e475389cd8e","other":"2245f3bf1a3b4e92f912affc75f757cf648b20474c11ffe947884f216b8f24f9dcb6e6a0358a4061b8517478ec15027e185b2f05a777573b4940375bf4aaf2be","up":true},{"one":"657d5370319128d24d925b41065eb619409d63ec6280975d78877a4028287463f6442f5206dd703569a05b2b542ad8bbb99803da265408208d6356a26d283d08","other":"2245f3bf1a3b4e92f912affc75f757cf648b20474c11ffe947884f216b8f24f9dcb6e6a0358a4061b8517478ec15027e185b2f05a777573b4940375bf4aaf2be","up":true},{"one":"2e42f845d0393d1682add54ee30b60a953ed283e75d347bc6719ae0e91f6676282e7960f1fd52e5803d6b341fb3582c724b4f9cfd7bce9ce85f13ca480c7e72e","other":"2245f3bf1a3b4e92f912affc75f757cf648b20474c11ffe947884f216b8f24f9dcb6e6a0358a4061b8517478ec15027e185b2f05a777573b4940375bf4aaf2be","up":true},{"one":"a608a746f46d4b2e9267c65283380d6d6cb8885a64428fb77df9934bcf4dd1723587ee7c8f4a642dce266a12a6a4cf4e5c6db7fa1024158425a6753e7ab7264c","other":"afe5b217dc512eee45575c189826ee5640d11a0ac9e8e4b03e9e62e6cf6df9de500bc8a36cb7d82a2280ce184409164f1772cc5c9e59ad04361522d2b8c364e0","up":false},{"one":"2a63d875e715c2a43302d32d86d30c7d7faed46c08a67bf488762637216b99dd87333a66df6d9f3a57df863b1f1a219ddbeebb9f3e92e523bd08540a195448ca","other":"4fe37f2dfb03707c90a6fe91dbcfd7497db70ffc20043091d50e1cee573210c144e8749340f2c3cb70fe8fc51b317d49e8734dc51ce64b3cdccdd639ae35d1ae","up":true},{"one":"5eccdbcb15ef42dc96abcbcd8b8db75d9230de10e3c650620737f6cc04ba4fdbf59ded5daa801901c191be186c329ebcd37ba83bcf794064ad4e11bf10d3f775","other":"396c703d27bfdddf91761f134cbf665fe61e0b3a5d24036a4105a625f72e8c28b821e9200f20d6e8f8b3ed6b95bda6b8accdd840c2f786720b7431e3af2af981","up":true},{"one":"e98a08e8e3544727f5ee27f4465375a67ffba490fcdbfe7bfdc909f6b68bd279f776c65d38c2ccfc33079f852f76349c94d68fc6989c0d981f22333f036a4bb5","other":"adfba6d883cacbb141cd8c59ee04d7e5d520f1ce31a81e5db2d8b2380bf801c1fe4b265a66b71f9643d13a41cb1f6fb4b83399be786da4b6e171b6784bc56e49","up":true},{"one":"bf4ff51cc3d9a9d8cefd7e346ce1384d06450228a6086fe12fb0c60fec54bb6478f090bb638fbdbf8f41f7bc6420cd8a5c8b1b8566229b6851167375ef412f46","other":"2ac522ebfa49d37f86c6270ad4cdad0e766493f0e463b18c9906c70fbd2e5c6ff6b0d5879de6e3894418370636963a78b0c0cf087a8684c2ca30c9c736e49228","up":false},{"one":"aacff366e601e072a2113add9020e19b6612f3e85b6e607fdc8cc1b6991f43be0b1f835ed3dc41d1f2b3e0caf7fac252c8eb4c150667d48207fa92ea5f0a7455","other":"df4c3505e09e1baa88470117b964e758c94f77a4546489ab5ab7f4aebfdce424729ace8867475715fb68f05c66c9674a5767549e266c4fadd1c703ddd735908f","up":true},{"one":"016f8f4619a16a07fbde5a18e362158d696e4d9f104a77787f26e32a25cd7d278256f8e0db865c488a99511ec27a5eddd5ebbd1c1397fa7f8db111062e5fe959","other":"11d560045536e9d1b0b1b9e8944e00f0ca7f1e6788c9fdb51061820bbb3008ead92bb7836621bf58da7035c87a28328faecb4cb2e3cdb9d7fa4f45790e6bf352","up":true},{"one":"e2e0419a41bdfc5bd76deae2ddce6ac865f886d764c9bd18799b79fa3b2b6ba66d765d26da2037e98317e1d7e8232a61e63c1d0cfa98c9137424151b46e07171","other":"89a5b92a9ca045f12c35a70084e6f41f9775a25d6f105f8c9349c7b5e107179d8a96bdbb113b2680edf5183e9a42fd64bd7b29d0dc7797c583b833f869313699","up":true},{"one":"a7507aa5665e165ab2e2a07def272f0677f9d6d35bb82268a34214384e7d8ef7635a299368752e63cfd02d4e60231076baf23cfa10d17492e55181b391ecf335","other":"caaf695c76cf7c047d3f3bfe019d01618e4871cee8ff3f347913da815bbcde145771486f916a44d03f59ea9bc217f169fd0c0765fda3f9b9b28d02a522e180b4","up":true},{"one":"0b7e1e5acabcde503ad827e45724402406114a513f81040a379b0f82df2eab4456b348b27936369c49e3c264d971c6a9e2c2217fdbc5e5b93ac6fc219957834d","other":"617595a230e0a74a3db3b47cd27b941e02bdee9a84cdfa8eaa63a55941eb5caa79e20fb69726a4d46a0e5aeed24039f8c5a20679a692df0bc140f42558ca9a2b","up":false},{"one":"1944f98d4db32c56a5efda5a79aa5f276bfab1e084d6611fec0e735b8bc0f45b457cdb74a23fc83b2377821fa8316123c9877acd6db7c41058ca5d3cfedaecf9","other":"e1ecad3beeb6c19dce551e4a603c7b440b4498c44e298dc67bfaf4ed2c75bbea95df48b1cd1318e2ccb962cbae7c30ff258e73f8c3fc6b7e9ae7a47f7cf8e53c","up":true},{"one":"460531928a4b084686343c8464b37c3452bb3566045698d08a4692864de5581a9eb1dc632329e7d3ccb73ec31ee7693787d69df8458efaba9a7105d87ee2e053","other":"22010c9829626a6892258b09cb3f3edc3f21382fb487b5dbf0dd20e198e37e26134aab850e30337f398d1491b5126839aeb1953ec144bc19aeb889c832f67c6a","up":true},{"one":"5bf29c02f07faf7ae8e46389e1b98df4f5e88c9316b5151685e6ae7b4e622cf171ff09f996aaa8ad846643b3bfcbd1ad96cdc249afccce439bb5c55246b95801","other":"2ac522ebfa49d37f86c6270ad4cdad0e766493f0e463b18c9906c70fbd2e5c6ff6b0d5879de6e3894418370636963a78b0c0cf087a8684c2ca30c9c736e49228","up":false},{"one":"7aaf7817b93aa6d2f50513791f9ad7629a901ed0dcb151189f44763f83423446b20ec79a48fa260cd9bc2907d5f0ad06b2c4c5e6d812f3d8876c8020ebe41019","other":"b870935867183bbfb84add16b9f56c02c834b7042fc24ce6bcb2a7f174e6d2239357a00be4272c1ef05c7f9baf5a9f16b53bc18328a9b7aca8540c2916805b57","up":true},{"one":"049a2b0ab4d49789dbbe1837e2d2ee5220a9401729ea87ab29385b24d79cdce255c3d2b5de6484d49ca6ce07bd41832598260c0a8c290e01d133d77f066f2f99","other":"043fe7085e8c90c18270f84dba5fab138e50216a1cf8d81a3794d156fad7fc81d1422aff169b244b13f91d73eebb5de464f97b1b93b3ad2a58959cff19238842","up":true},{"one":"60725e8d0e9333636e598dd666f459b4be898d9abc095ee2c1db289673e7e969b50e2093956fef5a2f1d23e2040159bbabaaeab17fc6dbbac3f6acab766e9e60","other":"b080891d4ba6d3ab224984360597f9c555bd1367630f5420bfaf230419a05b2be58bebf1554e53eb4c0da81cfb66d4f7697dd65143f11841ff62d8a0d82b6b67","up":true},{"one":"5dc69635f6d573c824ea83b18593a47f9f21a6f91ce18d2bf977c97d21f8d2a8ce88829244d12a07d949bbd52fe8a2035bc89685fe1bdd4ee20d766d75d3deee","other":"70ee3c7e02a123f78345d41c386e413f06b51f1ab346c2c472891eed7dd26a1f14e213a0f4f2d872859b9b535936a6d9b072d2604456f76221a422710411822f","up":true},{"one":"7865b82e44add2cea6ebcbaba9c152184331a2940fe73f6f9bb940bda8a59ab4cf4760894b9cadcaa54e36fbb712ad619346a49a85e32cdf2b53cda1ac1e0658","other":"62666b24d1026345349edb6a878cdc27d6fee8254e83f79a298ce2805260d97aa46423deae440f86ced5cd99b30e970c8e1ea1046752b17d8c80dc68d9a49b60","up":false},{"one":"9db1f94d74a00d1e5e2a391f1bcddf16b6d0670a2c6d91d946d38112c58634444b6fea8e8c05ab4b73bacdd62a0b575f6fb8729978edc216c7842b177b9f9cd9","other":"e087230634f556b818a416b66ba3f1d1dbe3e0dd0698bbb26fa86a2499acd169466f564dc18adf2f9be4d1ada0e86c11549754097601e10aff4f3a57ddffa24a","up":true},{"one":"afe5b217dc512eee45575c189826ee5640d11a0ac9e8e4b03e9e62e6cf6df9de500bc8a36cb7d82a2280ce184409164f1772cc5c9e59ad04361522d2b8c364e0","other":"920a301186bdf665a721676ece7c180413369ea6eff7537f42049d9eb409f28cc864099590116e885f57368959fb2cff7003697d9b1515e68bf3fa7aee0278ef","up":true},{"one":"109556abac422a912ecffec0d8796f8f16e92e8f95cecf72dc89e97a8bf1fd37aad3c66aa3cf134acade6d065c31821f977171d5c5463305b57ce3eee99a7ab4","other":"732393b99c490c76fa45e3e404ee095f2fa445fcc123af7ac8ab1d2fdd7cf2483f5b82bb818bd8a82b1a3b73e63bcc2c83d8f24d9aad9afe36503735e7967be7","up":true},{"one":"315b8a1711f680c2eaa607e35ef7a9e19c2b61721af8a7e08f1325dde1fe33cf1f47b3cc4acf12d541631041cf1b42754875fd1c9b66ee32797b72b9f7711256","other":"5dc69635f6d573c824ea83b18593a47f9f21a6f91ce18d2bf977c97d21f8d2a8ce88829244d12a07d949bbd52fe8a2035bc89685fe1bdd4ee20d766d75d3deee","up":true},{"one":"e0f78c59a61f2a953553cd5742c58f4a82e38e35ac7eaa237a6ffc9fb0a3a26a2d1d1afae249e611d1320f2cb25804bdbdfb6d77336449716b0f4beb3298b8aa","other":"58cfb20d3da3641e0ad529b9edbd4b590a8d1dc9d1ed7b44ed3187dba9260bd7c732fc10981f5b9bffd31d362cb05150173618aa36138984431d94a323a9b313","up":true},{"one":"2ac93c31937ca205d61cc5c2a1b9037871cac55e9b306b999b28e19566b3316f6539455e014840ea50c2db8a7c97d78804d3a2dcd7cd9c1f32ace0d36e5dd339","other":"4de378164d77a28c90cf162dd1b465e0282ee17aa7d3bb3179252466f72da33a36c9f298f7c9498e38dba4018e7ce3e5fe631c83842cd9059e23a7fece366d87","up":true},{"one":"807340e5fdf6c21a56ef2fd158c32e92201206ca85fcc147165a408f7a735964afd47c397e663610ac53870ae722c0317291732b0422f8aeedae783d9c730218","other":"caaf695c76cf7c047d3f3bfe019d01618e4871cee8ff3f347913da815bbcde145771486f916a44d03f59ea9bc217f169fd0c0765fda3f9b9b28d02a522e180b4","up":true},{"one":"9c30ad8c85adc7bb52ddcfab2e661cc3a854a689eaa59128d35129d02cd5b0f8da4a44cdd33934a8e2c8fab1760c16d6f2e1c5eb227dc819e85624e63343c069","other":"e67e495385e7cacfe659b40d1ba94d4b1ff55eada70a4d9740a9e452fbf221672bd0a897b940e2a6bed71e2a16867fe45bf0ea0015435ac6d815690e263b1899","up":true},{"one":"e023a51c5bd26e1754d6461345143e94baeac799947579ec7adeccd105de39f85afbceeb5037cfc0b820b9f4446433f034d9e7de7326d45df5a967a8099dbb10","other":"aacff366e601e072a2113add9020e19b6612f3e85b6e607fdc8cc1b6991f43be0b1f835ed3dc41d1f2b3e0caf7fac252c8eb4c150667d48207fa92ea5f0a7455","up":true},{"one":"81288bb0584b7ffc1546043e052e1df10fd5371b35dedd0bb42ec5b30ce69b741b2f7857af5984d4754b39d7253575fde9298504999b78380ef602d391c4bb1d","other":"2e409baefbd821485a151993356730e5989810d581e68190fbaa142799c9335bcf98310ad188fed10ae6eb6e2e789730393e509962ec5c0fef0342d72ed088d9","up":true},{"one":"c8b0dba45104fc7c7dff3ce078a0d3f5ade6198bb4656e2bee8076387929133e5ef2bd293b130a9d4f6a6974ca17e8b4a8f406d1219880f1e0f99c65c63af5a4","other":"54b3c57a4adf4dbaf31b85ed1b8dccd6249faa16dd96dd230189f47f57970caeed36627cc8e1b0794707418d580f5bd6001c07be6a79216695f1253db24926bb","up":true},{"one":"5566111b7f14d8ec83ba6456488f3fc5c7e2c86bf406dead33b814e1ee9b569d34015a4d88226b7e28fff7784395c086d106287cbbc80acfe75b05cd6e12903d","other":"e98a08e8e3544727f5ee27f4465375a67ffba490fcdbfe7bfdc909f6b68bd279f776c65d38c2ccfc33079f852f76349c94d68fc6989c0d981f22333f036a4bb5","up":true},{"one":"e67e495385e7cacfe659b40d1ba94d4b1ff55eada70a4d9740a9e452fbf221672bd0a897b940e2a6bed71e2a16867fe45bf0ea0015435ac6d815690e263b1899","other":"54b3c57a4adf4dbaf31b85ed1b8dccd6249faa16dd96dd230189f47f57970caeed36627cc8e1b0794707418d580f5bd6001c07be6a79216695f1253db24926bb","up":true},{"one":"0f9f7e2dce4ca266c3ac0ec3a8854200b54487f5308e3db418461aeb5f67c81d332619b6441b468e480941e63100ed1b263e7adc20689dc3dcda578bfca538fa","other":"f9ffe87c52ff4c22bd9696af32e0a9d34bb81fb84d9d8bf5aafe2ef9696e7b3d6460bf2a93aecb066133f53416bde841a02d6967bd06e3d4a714f3b2c123a947","up":true},{"one":"3e488a7208ce0e097ce47fc6651a13e95cae137d1a054a09b04d2f59d45faa2594a8c3b395e77ad1a3c2edcd827dda73c0c97dbaa6d9519a79184a0aca01ac4b","other":"23f9bdc82efbf57d3d40a1f2617d0311678fb4a3d6a50cb7e608c649bb618124a76c7ffd17387de963e1cd28d2bd5a61c98613f6e009a8a2a90d989827b35de0","up":false},{"one":"beec648d79437a5d7b4140ced45d82d035c6f64f9c67c58386703811d97c3846787eaf274d2298df809475f0b7519df696563cb8e9a5fb0a9cc419ab13fa8d41","other":"9b618ad34d0dfe0fccbd5b8af365cbcdbb43e802df5f23e91c20d21f3ead6169d52bf0db7e5e111abef630c9853419fb33a88cf111d8507b8708208b5d65e35e","up":true},{"one":"2bfba66ec9d63e928d77d455f2e10a14d6213e515099d5db14fa44a8bfc147eb0fa7afa9aaccdc86453c6903b55556059a2e13dd61fc494127d4a3ec173bf9ea","other":"8c6d77833bf1a98beabe7a92d985d13d52fb2e50768719ffbc6fce21ea676802a074b6e620b3ef80e12fad04f94a3c288d91df9716a6cfae09ef073b9dc1f2cb","up":true},{"one":"e06a789a7f6988e1ba5e8358b6cd4292555c7f9f7f0dda6fc01cc26d24e49a8c1ad694423ad74aec6d80f4b99e2bedc49b6a5f2670744cedee3a3e1848e6dd07","other":"24662a43944228e4ff74736bcf0a0a4f79c87ecfdb739225b2fc45110c11bfc38aaf2d09d98e5817477848e553f187ac5408bdb864518dfa7f5df542768828db","up":true},{"one":"7554993f6efd8d9016ff525ae73c41ee2e0dbd4970c563ba9b61a99c1c8943b433c4b7d48450f6e0fbc9ac198d907698093de20e6c1f7755520fb1e1cbee4eb4","other":"caaf695c76cf7c047d3f3bfe019d01618e4871cee8ff3f347913da815bbcde145771486f916a44d03f59ea9bc217f169fd0c0765fda3f9b9b28d02a522e180b4","up":true},{"one":"28d3232c43de54ffdaf08f97b334c012738648b04e2876c7e751a2e352aaf4d550d6efa976c5a8edbfa8e88b9d04a0fca492b81c3756ef673ab74d34182ca711","other":"ce0a09bb6fe4c9c93c3dbd800ca9c9ac0714f26a8f8dac2149b6ce7a9011912a5621ea2e45de35c4d31dfe5add00558fdba5dd21acf2d81ba391e82b5b3a5804","up":true},{"one":"57fb1bb32bb2b1a87e44c6a7557e9c47c2032d107bcb0e34acd9ffd54d5d3df5701232db16f62f7549ba2721021898b03160b1dc5201e79606648c1dbc4a373b","other":"27d9048707a89f1a61e44fdae523c0128f2a7050308bd3cfefa6c3e03040a0e22f11ab41275f22b8706e6695ab93320e2af35179d772581db5f49f960750f2f7","up":true},{"one":"8dd8ad560af84bec579cadb33d51711aa61b6ed22705010336df5a71a94591173b25e869457429c4a199b205fce8e73530e28203e18b971c2001715e610f152a","other":"aa9a94d6e4eaaed20113c21752c224e3a052abd3769bd6e832759dbaf5154a943cf094eacdcb0727c2fe51a11bd7fc0793d7d5e3312b0aba89d428a00e1fde0c","up":true},{"one":"0c14dd51a56130c51009e3ce47c96b2afef26b7e86cfca65d8a9bae1abef13b3a7a192b422d894c39e24ab00be412d166a3571cc259ff4462d4ad8925a153766","other":"6bf9fb6a25521c16c2ebeb6203d046d7dd40f29cc2ddb067c0222ef56d7012d2ee5d037f71f6668ea56767610b2a54c144aed74b7f68d06993cbd52fa1dc7630","up":true},{"one":"ae2a996d3b562cb47a564934037949da83b1bfe194c23754f3dbe2372ec27654f4f3b6cb7f394570f308025589c065870477667e5560dbe5a8ea1625740699cf","other":"ce0a09bb6fe4c9c93c3dbd800ca9c9ac0714f26a8f8dac2149b6ce7a9011912a5621ea2e45de35c4d31dfe5add00558fdba5dd21acf2d81ba391e82b5b3a5804","up":true},{"one":"07f25fdeab2b44b2e92fc80fca7de9e4a8547d27a98a54593b3395c270a9ff3f2a5da62a2e8531ce86359f0cdc5b6513b773dfd64cce1b83e47065d9760a2c7e","other":"24662a43944228e4ff74736bcf0a0a4f79c87ecfdb739225b2fc45110c11bfc38aaf2d09d98e5817477848e553f187ac5408bdb864518dfa7f5df542768828db","up":true},{"one":"a1560ce7c1f1d5972f027a8e9cff820611d84764aa067434a75b63887bc4268a259101486d34b7fe83dd735e799789986cd3e9b156c86ede598bd86af4454924","other":"24662a43944228e4ff74736bcf0a0a4f79c87ecfdb739225b2fc45110c11bfc38aaf2d09d98e5817477848e553f187ac5408bdb864518dfa7f5df542768828db","up":true},{"one":"57cd4c0048b459192ee46e19ec7df777e600f256e0dc8c3019431eb7bec3c020b9504ec7aea3dba8188658ca5b830ec40af6a8540ce10e04badc6c695d009271","other":"4de378164d77a28c90cf162dd1b465e0282ee17aa7d3bb3179252466f72da33a36c9f298f7c9498e38dba4018e7ce3e5fe631c83842cd9059e23a7fece366d87","up":true},{"one":"1f6d803a4ca186463772850ca0901fb920af7e74fdd2480c3c368fa707838ee91bbcfb57d5e3510c802b9b85f2d954f04c9b675414274bdaebae6488dcf94c10","other":"5142eea687de4248b2184e9896b245563117648e7a156255d9a7ae730313d5d383db3be1125b5accd7e743c2a5d8c3289ec559ef7cbb803b9e82cd49bb213d9f","up":true},{"one":"ed6c793eb4565aa9d883a76fad6c97ad0b878b9ef0235e11e89db1af25a9653205f725c6ea258b84bde134f1a6437c6d109b859d17509e5016c4ab98be59032a","other":"8c6d77833bf1a98beabe7a92d985d13d52fb2e50768719ffbc6fce21ea676802a074b6e620b3ef80e12fad04f94a3c288d91df9716a6cfae09ef073b9dc1f2cb","up":true},{"one":"c665a6b1b7ad39b86bd4b1fe38b7ee95a0fbb1db15e91381ec9e5a235e33b69ffdc92c60dafd74b7b4dafca1b000e9274bf045abe5b93b1a9c2b31ae071a9898","other":"d9bbcdfd949010e6b2cbf6d0f34b27593ae410bdc1838876aeca35679571fe431d040a5ab085c0a77f111688bebed891da3587277cd794702437cb20d6aa4256","up":true},{"one":"6b4e376e9c94242b6d42688c22aa9ab418cb6dfb1cbca1c69de0feceec8d3af29fb005017aaa6e503cc0c03cf0dc5bcab55e01cd6f64b9efa02ed87c03020003","other":"535f93057d46c4aae0902546550880be0b5ba67dca12350117d471d67f4f2b3f7bdff29bdc918767974c465df8fa1afa6bd6c29c0a36d51f71c4183673d906f3","up":true},{"one":"66d0c5da973d9dd65350ae1ec63776872cdb7ded6afb6f51ae82259f6fd35e884375d15de290625f02ed2e5cdc3f591decb45e5fc64d5b0f835a216fd196f5a3","other":"fe8ac5d33cd8ab6a1dad9567cdfb89b431a5c4f4a584fc608b92e7dfd06f70988e71e2f11f9fda9ee797c9ffba83bc085939fdf2522dde39f28202be92650566","up":false},{"one":"831cde5b651ba327b059da4c7f84b184bdd6bb99c6690ae816affe25d42c6c3dbe5b59e2b6bf23e9d0f6c485bd341ea57ba1a8220d18b0a40e156b77d84f79ef","other":"e1ecad3beeb6c19dce551e4a603c7b440b4498c44e298dc67bfaf4ed2c75bbea95df48b1cd1318e2ccb962cbae7c30ff258e73f8c3fc6b7e9ae7a47f7cf8e53c","up":true},{"one":"5142eea687de4248b2184e9896b245563117648e7a156255d9a7ae730313d5d383db3be1125b5accd7e743c2a5d8c3289ec559ef7cbb803b9e82cd49bb213d9f","other":"d3105ede6c21bc643d523afcd1309a5dcf03f70797a92f167c3a19f86ae98882fe1a9d4094d7a3dee4a0833b8075b6c3e9aaa7f4879dc47bb388c3ae85522288","up":true},{"one":"2ca05ffc0ad771e1e045a47f1c0a79ce374a25e3c0e53c2a80d67e7479677003f62880251a83a5074f1c9651d828f1ff7e352935a9df141c1eb75a0c59b00a8b","other":"396c703d27bfdddf91761f134cbf665fe61e0b3a5d24036a4105a625f72e8c28b821e9200f20d6e8f8b3ed6b95bda6b8accdd840c2f786720b7431e3af2af981","up":true},{"one":"8f88c7ec044f758f29bd8d12a5170bd973aec8f6cddbf512b910c4b75a0fec09c5e198bcd65622037f897759db68da2328b4a7ca93585dc9cb62e46d2a6c0864","other":"3612863ce0456c91785a829bf5c9d2b2fb97dda083a1847e5a4ebaa6fce1260faf4d1eb374c2225431a82774163835fb59c8cb0fa9fc0969eab5410c71109cc2","up":true},{"one":"7808fb798d22e78fb1d39b87ddf99a503f820993bc64149eca9e81d9d58fc1adea60d8de14a4f06cb89f3190c0ef0c5e182621a14c9361ccb7e0cee667599cc3","other":"8d4920d6e3a6717699b5a3af068cbdfc16858d7e393d158d41b1b5f345b47129eef89e1d055386c518f400b134678c21590f0317dea3436d4cef60f45455cf12","up":false},{"one":"f33d1f3e460574706ac1c7fc9ebb4683b173496ce3e80017d1c3521bca03d5a41a9c7a6cde8347d2238917b7cc58cab000ce7ccf6bb408561015a2ecbe613408","other":"9194a3a4c8f3235203e48bdb10902d958d26c342805ea6365af9711213536509719d917c694f9a4fbdde6889a4c92299a5301f0275bda4dbcd2541b5bff5b271","up":true},{"one":"0deda014fa3c0bc8f37d853e1448f95f56f97048c28797d72258fd3ba2f1f776ae11566197466596356cd172847ab02a89f4cf047e58383249fb2a4cd69b6206","other":"0b7e1e5acabcde503ad827e45724402406114a513f81040a379b0f82df2eab4456b348b27936369c49e3c264d971c6a9e2c2217fdbc5e5b93ac6fc219957834d","up":true},{"one":"934a5fe1b91c1891ef4df7f67c027e0eb115d4c2ca4a1b76a135ebd4315c4fb835d6625223194e6a134407b38b0d3928fbc7bc924a3c6a538989a6cf200bf4bd","other":"2ab9513899c3c829b6284e56bf2b9862dd0156ec052b58615dba77d450dac642e534ec36ae5d3234262aff54e19f99856e908b9d8c1da660a7834a445610715b","up":true},{"one":"083e67bb19e30d14e4df6d2483367d6659d9b56744d53d9cf7fd15954c327e1bc88a5d0db8833634e1dad7209164451f8934b59f76b5990059261abfd650519a","other":"e06a789a7f6988e1ba5e8358b6cd4292555c7f9f7f0dda6fc01cc26d24e49a8c1ad694423ad74aec6d80f4b99e2bedc49b6a5f2670744cedee3a3e1848e6dd07","up":true},{"one":"eab86c521f8f1ac67c015ab713f1236a08b0200757a96bf87ab8301e7967ae62361f0e14da14ca294fc8cb3b4726b52f4773101e21b032977c6a647241b59c73","other":"ca1aff0d847c6fdacb623ad9078a0885b3208614fea20d5ff11779779b486bf5e9c794aacf848d3c2d58cfcc1eda8356df82f5fbdd0a5236beffe8e6042848c4","up":true},{"one":"65e954e60837bda10654480b227fa3bcc6e63356c52079002a27e836cd82ae2934ba77da60080e4b9f2d9324b982b24959bfd9624302e6c330408381054b43e9","other":"2b70e5ffcc0bb1c4f8acc09dd1016e67c9c96c92d091ad481efbb71bd8b2a5a5869c6d668617a9b2cbfe91baf5edfe150c3824c84d90899a974099071d171441","up":true},{"one":"485825745d97654cbb92a14e0cd1078691d3c28f4d82b1046284b676a42b44ca58eb43474e45e415d3bd3f3c383f9a1a3365821ed7ba6a9f2603b29d58031dc7","other":"2ab9513899c3c829b6284e56bf2b9862dd0156ec052b58615dba77d450dac642e534ec36ae5d3234262aff54e19f99856e908b9d8c1da660a7834a445610715b","up":true},{"one":"4fe37f2dfb03707c90a6fe91dbcfd7497db70ffc20043091d50e1cee573210c144e8749340f2c3cb70fe8fc51b317d49e8734dc51ce64b3cdccdd639ae35d1ae","other":"2b70e5ffcc0bb1c4f8acc09dd1016e67c9c96c92d091ad481efbb71bd8b2a5a5869c6d668617a9b2cbfe91baf5edfe150c3824c84d90899a974099071d171441","up":true},{"one":"acb4088c27ee2ee130ece3506596432afdb9e9757ec11ebdd35c5a6e87239545c48466913a646980104c8fd7a9a335e177f04efffe9dc952dfd7cd5c1bb9aac6","other":"7865b82e44add2cea6ebcbaba9c152184331a2940fe73f6f9bb940bda8a59ab4cf4760894b9cadcaa54e36fbb712ad619346a49a85e32cdf2b53cda1ac1e0658","up":true},{"one":"3612863ce0456c91785a829bf5c9d2b2fb97dda083a1847e5a4ebaa6fce1260faf4d1eb374c2225431a82774163835fb59c8cb0fa9fc0969eab5410c71109cc2","other":"acb4088c27ee2ee130ece3506596432afdb9e9757ec11ebdd35c5a6e87239545c48466913a646980104c8fd7a9a335e177f04efffe9dc952dfd7cd5c1bb9aac6","up":true},{"one":"b4fd11306b1416a9bcf4719578976188e104b8c5028b9abd3214d257446b97b70a22e6c00934d80caddde15e8e4d16af03bb399583047983fba373d8313226b7","other":"292c78c8e41606e98428096bc6f4609a7aa48e5c4d17eecc64d65faae4a7270b0c15f0cd74274015688ea0a9aff34f215c29118222e362a29c8d637963973a55","up":false},{"one":"990b1db3ab1390219e8866d39fa4441bb5bb89ad786b3e255771869fcd08906dcf63f34007481769c7462edbcc665acc0a552e3733360b8d8c310c9321a5550f","other":"bd1a7c63fca9e1fcc67d7fd62670beefe2bce483cf1dc1233ee85eb90db607917cd9a5d7170b10e80b925a20e2af2c54d286b01805ac34967410859f4f03da09","up":true},{"one":"fe62314839c93d2f6e3aee984d5f0b321897c6f39e66800d3de8b773baf6f19e0a03cae025df512aea8d5f1b667b6dbb15c192a90a76d3031c14e33e5c16c4f7","other":"a99852c5bf08ea4713af9cade5343d1259bfb90401aca7fcff18c58cd56a98804dd16c61fea71039c0ac31b9bbbb9dc5aeaf0c2f074d3365e88d17031802d636","up":true},{"one":"1b6cad4f9851cc584c5d1405f976bb51a52e27ef4525847df543dcca65ca5eb1ef229dcc68ccbaaf00ab1e044cb5990dd213c805bdb4adcceb6fa70b5c61fdb4","other":"6b01079463ec2f649db8634cb7a596261c79a8f714d954c772528e0547b017f8ce405e4a0ea9d32270848180e0f77b8c0b022cf95c85e777626edd4d24ea21d2","up":true},{"one":"97981f4b825620985b746c85824d7a4d307ee25d60a72c2b7de4b1d4f3b1c002652adc3045842d350f849789e410a0357a0b42fa637a1b4fc9d39e44f8a674d7","other":"fde7705f5013c3b6b76a35505c1e3d57c033a337f2a71e912ec3a3d2da8e113bd7c36d94908357e9f7654660621f647ad8c66b0126dfe91dbfa3b8c7bd2183d3","up":true},{"one":"b2538d4edfa736bfe2cc21326a44ce62f716b3480eac93584a2233b69c98883a2bb255f246218a58cecab1d0d176e6d1fbba9782fd70d4603e01742299b9ea9c","other":"b3316f4fd7dec218a52331f25d17a2faf0f2a417808d7dbb80038154abfbcd2d78da074837b648cff28675f4aa0d65ddb7d15abf3d7e0391d401e313a3ef24a2","up":true},{"one":"be514f5f17f3177235acb24112b578edf0e373c469073226e547d18080905fd062d572be18e943f13bf9fcf5871e89ceb630a1b848a0e370ef8ef8c6d997a363","other":"396c703d27bfdddf91761f134cbf665fe61e0b3a5d24036a4105a625f72e8c28b821e9200f20d6e8f8b3ed6b95bda6b8accdd840c2f786720b7431e3af2af981","up":true},{"one":"2e409baefbd821485a151993356730e5989810d581e68190fbaa142799c9335bcf98310ad188fed10ae6eb6e2e789730393e509962ec5c0fef0342d72ed088d9","other":"9133b0b3c8f680286eae90c3beebc3099a13de38775a3ff2abdeced62d05eb2ced5ac85eac0870156be03101024da5e1d9fbf3e1066ddb3f088221e64149acec","up":true},{"one":"7b35c856916eb3fc1b1f451667e240b95aff8f4731cc0f6743740923081ff1ddf2eec81bdccf4691a7bcc053d23eacfc15809c384a73448f618317bf605bd1cd","other":"66beee3968dbcf3addc6feaf070a4e3e82b5bb164fb72f40add89f732c12e8d0a31a7ee1f1e24a4674e4dfc9a4912b02c17ce3c224d257d78b7156544d6507dc","up":true},{"one":"1bc1d6155ba35d29ea16938994e08df76ebd8f16bd180bd6a9b9d8798d0745889fe72d641dd78bd8ec13526929f7eb5aaa6a388430fa69033d6db581e53c6422","other":"049a2b0ab4d49789dbbe1837e2d2ee5220a9401729ea87ab29385b24d79cdce255c3d2b5de6484d49ca6ce07bd41832598260c0a8c290e01d133d77f066f2f99","up":true},{"one":"e2a27dcdee1f89fa362a85c4397840cd8be4ad8d1b9ccb23188c303bcab7619f38772f71385922d090390973b62fb8249efc103f71bc761041bcb3880ec0b935","other":"c903c5ee3d9cd65bea3ea777e39282c33e1349d945411fb2f16321bf582c2f400956a98fbafe5873fc5f6f6a9a051df5da7e94cbd340f935abe80f91e79ef875","up":true},{"one":"fe8ac5d33cd8ab6a1dad9567cdfb89b431a5c4f4a584fc608b92e7dfd06f70988e71e2f11f9fda9ee797c9ffba83bc085939fdf2522dde39f28202be92650566","other":"59b53f8a562bee519276e0eeccfcf8c975d3102f5d0cccf5abcce291a8a5bb817c04604f123686177a50a03b9d7559ac469962d0159d1d93e4ce58a304d04b55","up":true},{"one":"76cbf9fc0f3517fb615fa96104780218e85d064ee5a1d518f3b78f4dbebf144df38c427445fdd6c9b436489c00ff9497d747a8fd70f380f95601d59e52e021e8","other":"aacff366e601e072a2113add9020e19b6612f3e85b6e607fdc8cc1b6991f43be0b1f835ed3dc41d1f2b3e0caf7fac252c8eb4c150667d48207fa92ea5f0a7455","up":true},{"one":"1d0244a13affe60996fe3cf51ba624adc746de0c7ea68ec5a31311a36077c5b5495e3d95c9642875db44c7ecae6ffed22e45f2e2d024d486760be2af9f4cf2cd","other":"4de378164d77a28c90cf162dd1b465e0282ee17aa7d3bb3179252466f72da33a36c9f298f7c9498e38dba4018e7ce3e5fe631c83842cd9059e23a7fece366d87","up":true},{"one":"9b59b76dc61223c7b37083b0ebdda22d3599563b3e3986f5db9d5b12f8c806cbdeb2345454efe957cbfa11eea9c7896aefd9a461210524805452ca100a9ea431","other":"032b9bf2f59f15571821611d3ee541aa748c86d47fbe5f049fd0069be53e5d7c41991d82957e9c727654c3aa73ec94997c03d8a6c1d2007c9bb1a703f6215158","up":true},{"one":"5df58ba12334a1b4f983d642fe435901261767cd81f8f37c43e359f5584664e4d287e8c2275995604a3b3a4823418e35cd899a3db2a7db31570e19512f375481","other":"032b9bf2f59f15571821611d3ee541aa748c86d47fbe5f049fd0069be53e5d7c41991d82957e9c727654c3aa73ec94997c03d8a6c1d2007c9bb1a703f6215158","up":true},{"one":"f039df8a3206e6e17eee8e95010038c450cb4cc0b5580ed5795d4c21802e1e9d360f4528bdca794f457932b1d6a818862ec847357a861c488332ef6d9480daa6","other":"8ca3b63cb84f1e9883d82809a9b6777ec1029ecda96fe93b4d494ee9cbefcad13f381b3e480136e542e01054fe1ede66c65db84a0009871ce49383db461c8438","up":true},{"one":"5e86f39cf8338ba098a85d41e601a303fde311662b216ad32a2b7bfaf2b2b6dd1af3775784b39f2d85ac5fac96f05f3abdd8a2bd28ba16d939725fd6a33ae1b6","other":"032b9bf2f59f15571821611d3ee541aa748c86d47fbe5f049fd0069be53e5d7c41991d82957e9c727654c3aa73ec94997c03d8a6c1d2007c9bb1a703f6215158","up":true},{"one":"d7a319f69013b8375e64d19f015547462c84565b882337998f9e669c5fadd3d2ecf6374109903003e09f5d453424b5c7fdf52163d2cc8084cf81f94844946b63","other":"db8ba71afeaea1f2964e8978a6eceeb9efa3958424424022213c8193443f8d5afd18490afa954c76360c681404809c7cfaf7e4ebd8bd1a42d403f7f1915b0d29","up":true},{"one":"11d560045536e9d1b0b1b9e8944e00f0ca7f1e6788c9fdb51061820bbb3008ead92bb7836621bf58da7035c87a28328faecb4cb2e3cdb9d7fa4f45790e6bf352","other":"db8ba71afeaea1f2964e8978a6eceeb9efa3958424424022213c8193443f8d5afd18490afa954c76360c681404809c7cfaf7e4ebd8bd1a42d403f7f1915b0d29","up":true},{"one":"8ca3b63cb84f1e9883d82809a9b6777ec1029ecda96fe93b4d494ee9cbefcad13f381b3e480136e542e01054fe1ede66c65db84a0009871ce49383db461c8438","other":"5dc69635f6d573c824ea83b18593a47f9f21a6f91ce18d2bf977c97d21f8d2a8ce88829244d12a07d949bbd52fe8a2035bc89685fe1bdd4ee20d766d75d3deee","up":true},{"one":"94088fe273f76e62ca4e43c095ad12215b4ae4c59942328b3985416fb19bbda0cacc143a49eff3fb644ad53a19d3f043260e43dbb70a0aa9c15829c21cecd3c7","other":"db8ba71afeaea1f2964e8978a6eceeb9efa3958424424022213c8193443f8d5afd18490afa954c76360c681404809c7cfaf7e4ebd8bd1a42d403f7f1915b0d29","up":true},{"one":"6ab6ec15635b2fda22542c99df0a3313ad4583ba0fb3f31b8f314e3ecad446d3fb0fdfcd2be9b08374b1a7e049fb68e69e8dacdd13f1df5007a656f6b11adc5b","other":"db8ba71afeaea1f2964e8978a6eceeb9efa3958424424022213c8193443f8d5afd18490afa954c76360c681404809c7cfaf7e4ebd8bd1a42d403f7f1915b0d29","up":true},{"one":"1c2f7ce55a6e38487f3b3fe6083a79f914cd6d7e4aee8f5d56b4a61b3eb584e128c56998db0e13e775edee3adacf54f09960a041dab3daa80a4f8a3b42760c1c","other":"db8ba71afeaea1f2964e8978a6eceeb9efa3958424424022213c8193443f8d5afd18490afa954c76360c681404809c7cfaf7e4ebd8bd1a42d403f7f1915b0d29","up":true},{"one":"0a4eec7b0e05da799aca5b36d9e2530f2a89d1426b1fcb7d8f9a662df8a8b5b763767a20db3c9c63e0bd13c2a6e16d3ba8f03baf84f5e5d24917b3f211d9bcfc","other":"c57ea182bdb42ba9b0870b5c870e467f52693e5c0df752fb6eb0dfbacce7763f73caee10db40f4fd90f19f504ee586eaf9da41f5ee93ee515d885fec99374116","up":true},{"one":"7646d08b3e24183e3814de130235c41eb88a5a2abff23eaff3c91954ad3ef55fe27da422dac5b894312276bf1a2f1aebb8b636a8d4a0c93d9b016d441df3fa19","other":"9e621c3eb534855ca292efa27a3fbc89b4f05c80a4bc65bcff2f14ff28ef43cbe14137d2fddc6fe2658bb06947d918476b479dde71469b8680e5d8a7a01619b5","up":true},{"one":"0a4eec7b0e05da799aca5b36d9e2530f2a89d1426b1fcb7d8f9a662df8a8b5b763767a20db3c9c63e0bd13c2a6e16d3ba8f03baf84f5e5d24917b3f211d9bcfc","other":"84abcbc7b5598ecfd91ceace0927921a5a3404fdb274fc2a2549abbede5f8e4f62c15688a4dc9a2d80262c45970c88898da245c6eb779f327a81d53a17bbc74c","up":true},{"one":"5bae82d4832092c17bd11474f7748015b8b69b896ab8f683a7c0024fc98740cecbb9e31c6275269f9000e5bfe51d7f45cd5dcd4433e0c87b5741685b40fe3983","other":"7865b82e44add2cea6ebcbaba9c152184331a2940fe73f6f9bb940bda8a59ab4cf4760894b9cadcaa54e36fbb712ad619346a49a85e32cdf2b53cda1ac1e0658","up":false},{"one":"4ff66e9b5d3fd345990bd7605bdc222b78946f0c13b72bf80352812b2426d8f1d36c93e6c8713566004615e8a78ecab12ab0cfba254c0967eeecf8875b25bdae","other":"57cd4c0048b459192ee46e19ec7df777e600f256e0dc8c3019431eb7bec3c020b9504ec7aea3dba8188658ca5b830ec40af6a8540ce10e04badc6c695d009271","up":true},{"one":"7ac5b07eb555af3bb4ca3f0f4b45204d43cc3798c244435909b97d9a32fc3abf0b50666e260e046bce826a7a102a92d389f8f39c5311e83bb34beddac29d50e3","other":"9b618ad34d0dfe0fccbd5b8af365cbcdbb43e802df5f23e91c20d21f3ead6169d52bf0db7e5e111abef630c9853419fb33a88cf111d8507b8708208b5d65e35e","up":true},{"one":"a608a746f46d4b2e9267c65283380d6d6cb8885a64428fb77df9934bcf4dd1723587ee7c8f4a642dce266a12a6a4cf4e5c6db7fa1024158425a6753e7ab7264c","other":"b597c9ba4da20c49fc4ba019571321d2579588636cdaceb9f225706574970adbf4771dcf186b1decd4e14cd5d257e30a36ca829829598c1775902201ad9793e2","up":true},{"one":"a99852c5bf08ea4713af9cade5343d1259bfb90401aca7fcff18c58cd56a98804dd16c61fea71039c0ac31b9bbbb9dc5aeaf0c2f074d3365e88d17031802d636","other":"3dfd733dde9414af916625ab981777ff1ad7ca0f6d1e4e7d9e2739969e21182fd13d85e281868653e7325b20069356b11524b54143c47fd3955a911cf7325ad4","up":true},{"one":"032b9bf2f59f15571821611d3ee541aa748c86d47fbe5f049fd0069be53e5d7c41991d82957e9c727654c3aa73ec94997c03d8a6c1d2007c9bb1a703f6215158","other":"4de378164d77a28c90cf162dd1b465e0282ee17aa7d3bb3179252466f72da33a36c9f298f7c9498e38dba4018e7ce3e5fe631c83842cd9059e23a7fece366d87","up":true},{"one":"7b5c0e81c7f4e3ae29d745f6028cfa10b29a16a9c261b65fb8dd05d6eccc634612ad5d3029c8e9f39863a2cdb2682c25f090139bf5c4950e25647e39dcb40e63","other":"84abcbc7b5598ecfd91ceace0927921a5a3404fdb274fc2a2549abbede5f8e4f62c15688a4dc9a2d80262c45970c88898da245c6eb779f327a81d53a17bbc74c","up":true},{"one":"cb94a8270d0050378116b5815ff17dafbe20f5303839c4fd57b981d4687a4b145e4bccec7e9af9b9475005930148ffbfa97781a0762c8e9f352dc95565fc8732","other":"3b570117addeec03c2694baf28e246f91907268fe665c6c90356120332794258ee57a60853c19e9fe25d042ca42a5be7fe0797d84199174de8132f1ef4a9349b","up":true},{"one":"ff1e34fd51953ed641b431aa657da21cb4c81d23e4eaa13c9cce526f1f1b34593d41f9b87a0e10387fe400c623638677c0efab15dbd1014a0ccc11f9ec92c417","other":"76cbf9fc0f3517fb615fa96104780218e85d064ee5a1d518f3b78f4dbebf144df38c427445fdd6c9b436489c00ff9497d747a8fd70f380f95601d59e52e021e8","up":true},{"one":"84dfd4e4d9f1204893f190eacc4c3999e175c433f70de86e335d27477c097a0552f211a21764f01a708da4c9e9e6552191a61d3e48f41d0e84f01e7ae3beb34e","other":"7646d08b3e24183e3814de130235c41eb88a5a2abff23eaff3c91954ad3ef55fe27da422dac5b894312276bf1a2f1aebb8b636a8d4a0c93d9b016d441df3fa19","up":true},{"one":"e6779e3bbecf81dde8b27d652ed2726c45c205db0d0405c4580014a4c91d739830276f77079108c98ac516ffa00194e77a0795f7140bdf36069b6475e58213f9","other":"ca1aff0d847c6fdacb623ad9078a0885b3208614fea20d5ff11779779b486bf5e9c794aacf848d3c2d58cfcc1eda8356df82f5fbdd0a5236beffe8e6042848c4","up":true},{"one":"663535b22018a4ef0b151572ef286fa66c22c6e9b2913a69c4a735d4b0149bdf6c84bd83d710f8aa2627e8993b7f020750fbc6f56a3365ce4c840e2b3de1a6c1","other":"c57ea182bdb42ba9b0870b5c870e467f52693e5c0df752fb6eb0dfbacce7763f73caee10db40f4fd90f19f504ee586eaf9da41f5ee93ee515d885fec99374116","up":true},{"one":"cb321c9b0fe2eb3617b8e2461aab170a9dad2c9b04a10eead4e37e551197ea0a7500eb1cb7b155efe1886486ef3d252d8ff0d309f2906a1126ca011d037da70a","other":"4f5ab12b9c5127c16739ad0d4f51adce90ba6736cd096eb185ea632789f4b26f1ebabdea4fd3b39dda5409ece6c2d92fd469cf4aecf9d29453e3e042c19b893b","up":true},{"one":"535f93057d46c4aae0902546550880be0b5ba67dca12350117d471d67f4f2b3f7bdff29bdc918767974c465df8fa1afa6bd6c29c0a36d51f71c4183673d906f3","other":"4ee37acec2178ef120166265aaa2b64b09b315fb53861405ef46f2503c273eb9692e9cb4c2e67a8652254d430fd6e02dd3fe4cded20bb231a9fb834d292b0b24","up":true},{"one":"80d997b87856099d844187d3d1fa40846ded652a62c1611b35919c2543915b64ff62476636488556f678e436ea26fcc40db7c6b6bbcb78f590d61c1ff0e424b5","other":"e67e495385e7cacfe659b40d1ba94d4b1ff55eada70a4d9740a9e452fbf221672bd0a897b940e2a6bed71e2a16867fe45bf0ea0015435ac6d815690e263b1899","up":true},{"one":"2ddd49fae11d8bd2e7e75a481be267fa846f51cc1160bc326aeea51c542323ff444909de11e2731e835140bc0b1b32020e1e73fa652511a381222bf0aebc4081","other":"b53078000796f1cdb04dfeac424d5e3e37e30f00bd5bebf9a9ea0525c62917612b3a8f508df6bea59e3c7e4cd1aa530841f9a8af54e44f5617a13dee2c6ff007","up":true},{"one":"80d997b87856099d844187d3d1fa40846ded652a62c1611b35919c2543915b64ff62476636488556f678e436ea26fcc40db7c6b6bbcb78f590d61c1ff0e424b5","other":"a7378ee34876af17c6cd94a69b6b741ec7891ff5375bc4241d48608d047455ed48e6baae80ee88d4710c69ae615cf195cee26c94b54de1bb935628ce1e3a723a","up":true},{"one":"74d84cfdaf32cd4cc67771f29878f1365120bd65cc14848008d5386a81f495bf88eb4132fa38a2cc109ae1e7f02c9b97597ab9d1a9c19c945e710ab9df07cdcd","other":"9bd4f0adb9a966cc5ba632f1b540fe9cd6c8e39fe1a041b315697679cfb04b735952062ce057d456677cc34a84301f26bb727a4ab2646fee734f80a22c620746","up":true},{"one":"4b784f072b7c96c30612767425f552e30e45157e70139dfbe0ae4ff86dc31601adec60f8a3ad9747b02b5219073d8813af9b09d59eaf7ddb7ee24856aff6fa8f","other":"043fe7085e8c90c18270f84dba5fab138e50216a1cf8d81a3794d156fad7fc81d1422aff169b244b13f91d73eebb5de464f97b1b93b3ad2a58959cff19238842","up":true},{"one":"71f89efcf939294bb94ac669c8afd00def58c8dfad519c226adfa068692d588ef797116d42aa146b9d34f3be35ec7c014022640ab3c0f1f9034e44ab1a26e246","other":"4f5ab12b9c5127c16739ad0d4f51adce90ba6736cd096eb185ea632789f4b26f1ebabdea4fd3b39dda5409ece6c2d92fd469cf4aecf9d29453e3e042c19b893b","up":true},{"one":"535f93057d46c4aae0902546550880be0b5ba67dca12350117d471d67f4f2b3f7bdff29bdc918767974c465df8fa1afa6bd6c29c0a36d51f71c4183673d906f3","other":"4ff66e9b5d3fd345990bd7605bdc222b78946f0c13b72bf80352812b2426d8f1d36c93e6c8713566004615e8a78ecab12ab0cfba254c0967eeecf8875b25bdae","up":true},{"one":"6b4e376e9c94242b6d42688c22aa9ab418cb6dfb1cbca1c69de0feceec8d3af29fb005017aaa6e503cc0c03cf0dc5bcab55e01cd6f64b9efa02ed87c03020003","other":"58cfb20d3da3641e0ad529b9edbd4b590a8d1dc9d1ed7b44ed3187dba9260bd7c732fc10981f5b9bffd31d362cb05150173618aa36138984431d94a323a9b313","up":true},{"one":"71f89efcf939294bb94ac669c8afd00def58c8dfad519c226adfa068692d588ef797116d42aa146b9d34f3be35ec7c014022640ab3c0f1f9034e44ab1a26e246","other":"920a301186bdf665a721676ece7c180413369ea6eff7537f42049d9eb409f28cc864099590116e885f57368959fb2cff7003697d9b1515e68bf3fa7aee0278ef","up":true},{"one":"74d84cfdaf32cd4cc67771f29878f1365120bd65cc14848008d5386a81f495bf88eb4132fa38a2cc109ae1e7f02c9b97597ab9d1a9c19c945e710ab9df07cdcd","other":"58cfb20d3da3641e0ad529b9edbd4b590a8d1dc9d1ed7b44ed3187dba9260bd7c732fc10981f5b9bffd31d362cb05150173618aa36138984431d94a323a9b313","up":true},{"one":"4ff66e9b5d3fd345990bd7605bdc222b78946f0c13b72bf80352812b2426d8f1d36c93e6c8713566004615e8a78ecab12ab0cfba254c0967eeecf8875b25bdae","other":"fd4968df03d767a223bf7e4dbe26b5c27048298df40e81cad50b344fb3e6837965f2646dab7ffb2891a5c507343ed84bb8bbe403287b51dae538d58fcb6e7623","up":true},{"one":"abd8f5a4d700c06ec00684b23d2d25c4df1a9554fcfc57b0ddc3fa476e6a699ba75e1213449f900803f83ab8194c6746664b547202047f35b8b3e216c7147bf8","other":"d9bbcdfd949010e6b2cbf6d0f34b27593ae410bdc1838876aeca35679571fe431d040a5ab085c0a77f111688bebed891da3587277cd794702437cb20d6aa4256","up":true},{"one":"0b30b36e155db04c448b662c4df695068b2331cdbe2772aae5fda84159e977515a5ff2e156bc225a9281fef2383926ba8cb11e9c1846fb40db241e524ac14e29","other":"f5c1215a84a56d52f92ca0dc3a32df98c98a9c2ea2e9a34560210c16de1b440d20d043c8c25955dda8c22e55e92ddb49fd82e8b9b84072aabaa755a229bb19f4","up":true},{"one":"58cfb20d3da3641e0ad529b9edbd4b590a8d1dc9d1ed7b44ed3187dba9260bd7c732fc10981f5b9bffd31d362cb05150173618aa36138984431d94a323a9b313","other":"4ee37acec2178ef120166265aaa2b64b09b315fb53861405ef46f2503c273eb9692e9cb4c2e67a8652254d430fd6e02dd3fe4cded20bb231a9fb834d292b0b24","up":true},{"one":"6b4e376e9c94242b6d42688c22aa9ab418cb6dfb1cbca1c69de0feceec8d3af29fb005017aaa6e503cc0c03cf0dc5bcab55e01cd6f64b9efa02ed87c03020003","other":"4ee37acec2178ef120166265aaa2b64b09b315fb53861405ef46f2503c273eb9692e9cb4c2e67a8652254d430fd6e02dd3fe4cded20bb231a9fb834d292b0b24","up":true},{"one":"f9ffe87c52ff4c22bd9696af32e0a9d34bb81fb84d9d8bf5aafe2ef9696e7b3d6460bf2a93aecb066133f53416bde841a02d6967bd06e3d4a714f3b2c123a947","other":"62666b24d1026345349edb6a878cdc27d6fee8254e83f79a298ce2805260d97aa46423deae440f86ced5cd99b30e970c8e1ea1046752b17d8c80dc68d9a49b60","up":false},{"one":"4b784f072b7c96c30612767425f552e30e45157e70139dfbe0ae4ff86dc31601adec60f8a3ad9747b02b5219073d8813af9b09d59eaf7ddb7ee24856aff6fa8f","other":"c332fe1f9b6e25f72c7150631ffa6e0929ff6eeab5d17aa45eaf669bdde869cf404505ae990a529aa3ca797cd0a96f31cc41431a5d4a163132be566f91623c08","up":true},{"one":"71f89efcf939294bb94ac669c8afd00def58c8dfad519c226adfa068692d588ef797116d42aa146b9d34f3be35ec7c014022640ab3c0f1f9034e44ab1a26e246","other":"f38a9d792173a29c61389f5d84c005d78eac6e750659aad42e2d6df883f04eb3126b2c38fac95076eeed455b2031aaf694143922aa93a2d50412a2454dc56e28","up":true},{"one":"352407b42726dcd1aacc46a912ed8124b8b6a3da4e33dab742e40aa2452953d35dc8f42eddc76695ae2317e9f15dde2cd21be4ce826934695ad1847455661d1b","other":"6b01079463ec2f649db8634cb7a596261c79a8f714d954c772528e0547b017f8ce405e4a0ea9d32270848180e0f77b8c0b022cf95c85e777626edd4d24ea21d2","up":true},{"one":"831cde5b651ba327b059da4c7f84b184bdd6bb99c6690ae816affe25d42c6c3dbe5b59e2b6bf23e9d0f6c485bd341ea57ba1a8220d18b0a40e156b77d84f79ef","other":"d9bbcdfd949010e6b2cbf6d0f34b27593ae410bdc1838876aeca35679571fe431d040a5ab085c0a77f111688bebed891da3587277cd794702437cb20d6aa4256","up":true},{"one":"f6ca39b3ad803e99f4e4e9cf759fff6abdf06e6972bdbe524f6eb930c669d6f0e9b91f3de9df394b0d661b068273861391bdbac948ad911351c48cf02f874db6","other":"bf4ff51cc3d9a9d8cefd7e346ce1384d06450228a6086fe12fb0c60fec54bb6478f090bb638fbdbf8f41f7bc6420cd8a5c8b1b8566229b6851167375ef412f46","up":true},{"one":"acb4088c27ee2ee130ece3506596432afdb9e9757ec11ebdd35c5a6e87239545c48466913a646980104c8fd7a9a335e177f04efffe9dc952dfd7cd5c1bb9aac6","other":"155e4879643a472420012e040a87dbff776fc1976814c0c6cd0d5e157f0d0baac04aa7f2535786c09acc2700547383d2119b64a6f62115f1aff1708738844d8c","up":true},{"one":"fd4968df03d767a223bf7e4dbe26b5c27048298df40e81cad50b344fb3e6837965f2646dab7ffb2891a5c507343ed84bb8bbe403287b51dae538d58fcb6e7623","other":"62dab8b21640e1b44dea452dd7e7de93f27a44840da72d56b11aa96e8463f3a4bb15e75a954d19fc897ae0030b16181d271b79d8198b7cffcddaa9ffcfdcce73","up":true},{"one":"b4a5efa9028b2d196855393892f79993c2812d02b758f98813ddf82c5d943faf6d66eff811cc5a51936c118f4c768c0d13b54902095e040c602761e63c08655e","other":"0b7e1e5acabcde503ad827e45724402406114a513f81040a379b0f82df2eab4456b348b27936369c49e3c264d971c6a9e2c2217fdbc5e5b93ac6fc219957834d","up":true},{"one":"ff6f94005d1df7677600069764855c1c2aa0543cbe9f480f8feefec76c49d9e2c7bb2d8e38c89e9430f53f8b593d93f143c45985a56a5a32c736128214c95eda","other":"7174eca109a1f717653918224c8cfe1b7fbd666405196760913593401eb79f2c7e41003b01f5a458940695b27a4673443c7621a169db7fd968994e552995dbbb","up":true},{"one":"23f9bdc82efbf57d3d40a1f2617d0311678fb4a3d6a50cb7e608c649bb618124a76c7ffd17387de963e1cd28d2bd5a61c98613f6e009a8a2a90d989827b35de0","other":"54b3c57a4adf4dbaf31b85ed1b8dccd6249faa16dd96dd230189f47f57970caeed36627cc8e1b0794707418d580f5bd6001c07be6a79216695f1253db24926bb","up":true},{"one":"2ab9513899c3c829b6284e56bf2b9862dd0156ec052b58615dba77d450dac642e534ec36ae5d3234262aff54e19f99856e908b9d8c1da660a7834a445610715b","other":"292c78c8e41606e98428096bc6f4609a7aa48e5c4d17eecc64d65faae4a7270b0c15f0cd74274015688ea0a9aff34f215c29118222e362a29c8d637963973a55","up":false},{"one":"72e30d4562673c5c8fb03709d93f73322747858d723b7eb5ef2fbb88e0331252946b7e93ffe434fcb599c4fff57800afb29e6c60a719f18f49dba541c3591c6e","other":"db8ba71afeaea1f2964e8978a6eceeb9efa3958424424022213c8193443f8d5afd18490afa954c76360c681404809c7cfaf7e4ebd8bd1a42d403f7f1915b0d29","up":true},{"one":"4fe37f2dfb03707c90a6fe91dbcfd7497db70ffc20043091d50e1cee573210c144e8749340f2c3cb70fe8fc51b317d49e8734dc51ce64b3cdccdd639ae35d1ae","other":"adfba6d883cacbb141cd8c59ee04d7e5d520f1ce31a81e5db2d8b2380bf801c1fe4b265a66b71f9643d13a41cb1f6fb4b83399be786da4b6e171b6784bc56e49","up":true},{"one":"22010c9829626a6892258b09cb3f3edc3f21382fb487b5dbf0dd20e198e37e26134aab850e30337f398d1491b5126839aeb1953ec144bc19aeb889c832f67c6a","other":"e267e71c2dcdbe5a500b23444d2d4037ea15afba8f4f2b1c0e54a274450404fbee6fa5439f7cddf4ba1aa28fa93e434b01c239add58e30a5423ca3a481584d6b","up":true},{"one":"7174eca109a1f717653918224c8cfe1b7fbd666405196760913593401eb79f2c7e41003b01f5a458940695b27a4673443c7621a169db7fd968994e552995dbbb","other":"2f360209383d6de4ebd3b4abaf77796520b8654270b03f2151eac4a01b4417d7e0668c1f9ad30c20ff49aa8a0ab33dba5e6095619d1cf04b7af841722ab773da","up":true},{"one":"8c6d77833bf1a98beabe7a92d985d13d52fb2e50768719ffbc6fce21ea676802a074b6e620b3ef80e12fad04f94a3c288d91df9716a6cfae09ef073b9dc1f2cb","other":"7bbb3f3ed51cf84c077806fbd6d3578e105bc32aa6043da188793f066ad6df383a9f7cc0bd3124f4c887704bd188d480ce264fcdf178905bbda3b270927ea138","up":true},{"one":"6f60ef501b41f9049419b033ae8d793a18067bdcd60347537b0dc3873bdd9a2d10d24909cca7c39781765746128c2165596f6537a94f58279523faee71f9c51d","other":"afe5b217dc512eee45575c189826ee5640d11a0ac9e8e4b03e9e62e6cf6df9de500bc8a36cb7d82a2280ce184409164f1772cc5c9e59ad04361522d2b8c364e0","up":false},{"one":"c83985973a9564ade7d90aa54911ac57077600676a1d27292d98e058bf1315887bad84ccd708cb7f52a695a1405fb7d491d7ca2ae9caa3ff58a5ad78ce4dc9d9","other":"7865b82e44add2cea6ebcbaba9c152184331a2940fe73f6f9bb940bda8a59ab4cf4760894b9cadcaa54e36fbb712ad619346a49a85e32cdf2b53cda1ac1e0658","up":true},{"one":"920a301186bdf665a721676ece7c180413369ea6eff7537f42049d9eb409f28cc864099590116e885f57368959fb2cff7003697d9b1515e68bf3fa7aee0278ef","other":"74d84cfdaf32cd4cc67771f29878f1365120bd65cc14848008d5386a81f495bf88eb4132fa38a2cc109ae1e7f02c9b97597ab9d1a9c19c945e710ab9df07cdcd","up":true},{"one":"2b70e5ffcc0bb1c4f8acc09dd1016e67c9c96c92d091ad481efbb71bd8b2a5a5869c6d668617a9b2cbfe91baf5edfe150c3824c84d90899a974099071d171441","other":"a7507aa5665e165ab2e2a07def272f0677f9d6d35bb82268a34214384e7d8ef7635a299368752e63cfd02d4e60231076baf23cfa10d17492e55181b391ecf335","up":true},{"one":"aa9a94d6e4eaaed20113c21752c224e3a052abd3769bd6e832759dbaf5154a943cf094eacdcb0727c2fe51a11bd7fc0793d7d5e3312b0aba89d428a00e1fde0c","other":"cd8815d66aee8bd488d4e5e25f0cc9c71cc65349f701ea26b1d6cd9c039d16fcb473dbf270a3b33187720ccf4b0ce4f78a6d6edd05f4fe804772d5b6ec45bbd3","up":true},{"one":"caaf695c76cf7c047d3f3bfe019d01618e4871cee8ff3f347913da815bbcde145771486f916a44d03f59ea9bc217f169fd0c0765fda3f9b9b28d02a522e180b4","other":"ce0a09bb6fe4c9c93c3dbd800ca9c9ac0714f26a8f8dac2149b6ce7a9011912a5621ea2e45de35c4d31dfe5add00558fdba5dd21acf2d81ba391e82b5b3a5804","up":true},{"one":"db8ba71afeaea1f2964e8978a6eceeb9efa3958424424022213c8193443f8d5afd18490afa954c76360c681404809c7cfaf7e4ebd8bd1a42d403f7f1915b0d29","other":"a99852c5bf08ea4713af9cade5343d1259bfb90401aca7fcff18c58cd56a98804dd16c61fea71039c0ac31b9bbbb9dc5aeaf0c2f074d3365e88d17031802d636","up":true},{"one":"155e4879643a472420012e040a87dbff776fc1976814c0c6cd0d5e157f0d0baac04aa7f2535786c09acc2700547383d2119b64a6f62115f1aff1708738844d8c","other":"292c78c8e41606e98428096bc6f4609a7aa48e5c4d17eecc64d65faae4a7270b0c15f0cd74274015688ea0a9aff34f215c29118222e362a29c8d637963973a55","up":false},{"one":"4e68553db7be307b8379e8bec383b5c92e4b23debcefca575d24504e2062618f74c26e60e0d9e47f096997a7f841e2c32c994124f495ef3352ef964b33fd3a51","other":"beec648d79437a5d7b4140ced45d82d035c6f64f9c67c58386703811d97c3846787eaf274d2298df809475f0b7519df696563cb8e9a5fb0a9cc419ab13fa8d41","up":true},{"one":"7e2b0b4f3b55e97bd7241b984ad117af33bf3baacd22b3ed503a8a59f75828df745fb3ce3be4276d83eb484e64d9aa251103fa994ef119eaddb97a3503b9f292","other":"ff6f94005d1df7677600069764855c1c2aa0543cbe9f480f8feefec76c49d9e2c7bb2d8e38c89e9430f53f8b593d93f143c45985a56a5a32c736128214c95eda","up":true},{"one":"7f357b8d81bc2e5c6fcb081f23a42b3e2439f050d45c45851994a268d1c71fcb1f39f8c3f75ce921d3fbf80fc0e73f0b9609d72001dc4a6b65b526d312a4f43a","other":"54b3c57a4adf4dbaf31b85ed1b8dccd6249faa16dd96dd230189f47f57970caeed36627cc8e1b0794707418d580f5bd6001c07be6a79216695f1253db24926bb","up":true},{"one":"40bdac599b00e9c41ad6476ee415c33d9c17c5aa672692c2404e523b29dc315da929a86874bed87fd9009871805d1dbf3098e7a817193e3b08a6eee66346da79","other":"5142eea687de4248b2184e9896b245563117648e7a156255d9a7ae730313d5d383db3be1125b5accd7e743c2a5d8c3289ec559ef7cbb803b9e82cd49bb213d9f","up":true},{"one":"fe8ac5d33cd8ab6a1dad9567cdfb89b431a5c4f4a584fc608b92e7dfd06f70988e71e2f11f9fda9ee797c9ffba83bc085939fdf2522dde39f28202be92650566","other":"ddaf3f8478501cda872c056c72063eb64d5b871fc5fff70704872802289dd2d348f73bc342b7f148a90cfaae2448ebf16fea196be9df891dc71a57fb410d59dd","up":true},{"one":"829b074b70d757da6aa00f7bace3cf1b5d2d4eeadb7f370c1a85374a01a70b54ac53d747267e386f3b41e6d790fecdd6e74b8f89745501ee82439a66ea54443a","other":"4b784f072b7c96c30612767425f552e30e45157e70139dfbe0ae4ff86dc31601adec60f8a3ad9747b02b5219073d8813af9b09d59eaf7ddb7ee24856aff6fa8f","up":true},{"one":"9bbbfac8be4a000f51a4ce8d024d2595b5d491afec0138922dddfde5ef62c664040c2e9304cc6b7bc688233b5d0c4644b8c8793227c078285a3ab894ef0497a3","other":"84abcbc7b5598ecfd91ceace0927921a5a3404fdb274fc2a2549abbede5f8e4f62c15688a4dc9a2d80262c45970c88898da245c6eb779f327a81d53a17bbc74c","up":true},{"one":"4f5ab12b9c5127c16739ad0d4f51adce90ba6736cd096eb185ea632789f4b26f1ebabdea4fd3b39dda5409ece6c2d92fd469cf4aecf9d29453e3e042c19b893b","other":"6b4e376e9c94242b6d42688c22aa9ab418cb6dfb1cbca1c69de0feceec8d3af29fb005017aaa6e503cc0c03cf0dc5bcab55e01cd6f64b9efa02ed87c03020003","up":true},{"one":"016f8f4619a16a07fbde5a18e362158d696e4d9f104a77787f26e32a25cd7d278256f8e0db865c488a99511ec27a5eddd5ebbd1c1397fa7f8db111062e5fe959","other":"d7a319f69013b8375e64d19f015547462c84565b882337998f9e669c5fadd3d2ecf6374109903003e09f5d453424b5c7fdf52163d2cc8084cf81f94844946b63","up":true},{"one":"7acddc7fb6ac587b7e343804c768e4291cd28dd2b2b9207dea6ee82360d848a52d84f94e4c49e9c421f4f90e2d24f6291e2358783ab0230e6ecde82e69b4ac52","other":"beec648d79437a5d7b4140ced45d82d035c6f64f9c67c58386703811d97c3846787eaf274d2298df809475f0b7519df696563cb8e9a5fb0a9cc419ab13fa8d41","up":true},{"one":"0b7e1e5acabcde503ad827e45724402406114a513f81040a379b0f82df2eab4456b348b27936369c49e3c264d971c6a9e2c2217fdbc5e5b93ac6fc219957834d","other":"caaf695c76cf7c047d3f3bfe019d01618e4871cee8ff3f347913da815bbcde145771486f916a44d03f59ea9bc217f169fd0c0765fda3f9b9b28d02a522e180b4","up":true},{"one":"a7507aa5665e165ab2e2a07def272f0677f9d6d35bb82268a34214384e7d8ef7635a299368752e63cfd02d4e60231076baf23cfa10d17492e55181b391ecf335","other":"807340e5fdf6c21a56ef2fd158c32e92201206ca85fcc147165a408f7a735964afd47c397e663610ac53870ae722c0317291732b0422f8aeedae783d9c730218","up":true},{"one":"adfba6d883cacbb141cd8c59ee04d7e5d520f1ce31a81e5db2d8b2380bf801c1fe4b265a66b71f9643d13a41cb1f6fb4b83399be786da4b6e171b6784bc56e49","other":"0b7e1e5acabcde503ad827e45724402406114a513f81040a379b0f82df2eab4456b348b27936369c49e3c264d971c6a9e2c2217fdbc5e5b93ac6fc219957834d","up":true},{"one":"1944f98d4db32c56a5efda5a79aa5f276bfab1e084d6611fec0e735b8bc0f45b457cdb74a23fc83b2377821fa8316123c9877acd6db7c41058ca5d3cfedaecf9","other":"831cde5b651ba327b059da4c7f84b184bdd6bb99c6690ae816affe25d42c6c3dbe5b59e2b6bf23e9d0f6c485bd341ea57ba1a8220d18b0a40e156b77d84f79ef","up":true},{"one":"049a2b0ab4d49789dbbe1837e2d2ee5220a9401729ea87ab29385b24d79cdce255c3d2b5de6484d49ca6ce07bd41832598260c0a8c290e01d133d77f066f2f99","other":"adfba6d883cacbb141cd8c59ee04d7e5d520f1ce31a81e5db2d8b2380bf801c1fe4b265a66b71f9643d13a41cb1f6fb4b83399be786da4b6e171b6784bc56e49","up":true},{"one":"7aaf7817b93aa6d2f50513791f9ad7629a901ed0dcb151189f44763f83423446b20ec79a48fa260cd9bc2907d5f0ad06b2c4c5e6d812f3d8876c8020ebe41019","other":"083e67bb19e30d14e4df6d2483367d6659d9b56744d53d9cf7fd15954c327e1bc88a5d0db8833634e1dad7209164451f8934b59f76b5990059261abfd650519a","up":true},{"one":"a127faa19dcb7da585983d36a8e9d3e9a44a6db68507b60c70da71011f44ce377944802f39cd65f5a705cd8249ac1ef7ed8fd699349098f3f8e23b37592c80ae","other":"1b6cad4f9851cc584c5d1405f976bb51a52e27ef4525847df543dcca65ca5eb1ef229dcc68ccbaaf00ab1e044cb5990dd213c805bdb4adcceb6fa70b5c61fdb4","up":true},{"one":"7646d08b3e24183e3814de130235c41eb88a5a2abff23eaff3c91954ad3ef55fe27da422dac5b894312276bf1a2f1aebb8b636a8d4a0c93d9b016d441df3fa19","other":"abd8f5a4d700c06ec00684b23d2d25c4df1a9554fcfc57b0ddc3fa476e6a699ba75e1213449f900803f83ab8194c6746664b547202047f35b8b3e216c7147bf8","up":true},{"one":"094f9d0fd3bacb17ac67a2edb8ed394fbbd1c8d478233d3269cf217e7b788e21042374936b885bf23ee4f9e03babbe4e08db283dfc2a6e052a8a5ba133717dd5","other":"cb321c9b0fe2eb3617b8e2461aab170a9dad2c9b04a10eead4e37e551197ea0a7500eb1cb7b155efe1886486ef3d252d8ff0d309f2906a1126ca011d037da70a","up":true},{"one":"60725e8d0e9333636e598dd666f459b4be898d9abc095ee2c1db289673e7e969b50e2093956fef5a2f1d23e2040159bbabaaeab17fc6dbbac3f6acab766e9e60","other":"2ca05ffc0ad771e1e045a47f1c0a79ce374a25e3c0e53c2a80d67e7479677003f62880251a83a5074f1c9651d828f1ff7e352935a9df141c1eb75a0c59b00a8b","up":true},{"one":"7b35c856916eb3fc1b1f451667e240b95aff8f4731cc0f6743740923081ff1ddf2eec81bdccf4691a7bcc053d23eacfc15809c384a73448f618317bf605bd1cd","other":"4de378164d77a28c90cf162dd1b465e0282ee17aa7d3bb3179252466f72da33a36c9f298f7c9498e38dba4018e7ce3e5fe631c83842cd9059e23a7fece366d87","up":true},{"one":"807340e5fdf6c21a56ef2fd158c32e92201206ca85fcc147165a408f7a735964afd47c397e663610ac53870ae722c0317291732b0422f8aeedae783d9c730218","other":"7554993f6efd8d9016ff525ae73c41ee2e0dbd4970c563ba9b61a99c1c8943b433c4b7d48450f6e0fbc9ac198d907698093de20e6c1f7755520fb1e1cbee4eb4","up":true},{"one":"6c143960dbe3ba4c95e8debc1fda5f420a2a673eb46f7ff7d9a30f4cd2067e67ef8926bf17f0c99b16c79b6dc066b52409a11d47117d4fda4211636b1b74f96c","other":"f5c1215a84a56d52f92ca0dc3a32df98c98a9c2ea2e9a34560210c16de1b440d20d043c8c25955dda8c22e55e92ddb49fd82e8b9b84072aabaa755a229bb19f4","up":true},{"one":"e023a51c5bd26e1754d6461345143e94baeac799947579ec7adeccd105de39f85afbceeb5037cfc0b820b9f4446433f034d9e7de7326d45df5a967a8099dbb10","other":"0cacda5560faff9d20e29a0625d3cd340ec075f198a50ab8b79338cee0e0db84c7c7e71042fd8c8f73e507b570de5d26c39473136b575f0167625a1168309ec5","up":true},{"one":"81288bb0584b7ffc1546043e052e1df10fd5371b35dedd0bb42ec5b30ce69b741b2f7857af5984d4754b39d7253575fde9298504999b78380ef602d391c4bb1d","other":"5bae82d4832092c17bd11474f7748015b8b69b896ab8f683a7c0024fc98740cecbb9e31c6275269f9000e5bfe51d7f45cd5dcd4433e0c87b5741685b40fe3983","up":true},{"one":"5566111b7f14d8ec83ba6456488f3fc5c7e2c86bf406dead33b814e1ee9b569d34015a4d88226b7e28fff7784395c086d106287cbbc80acfe75b05cd6e12903d","other":"1bc1d6155ba35d29ea16938994e08df76ebd8f16bd180bd6a9b9d8798d0745889fe72d641dd78bd8ec13526929f7eb5aaa6a388430fa69033d6db581e53c6422","up":true},{"one":"0f9f7e2dce4ca266c3ac0ec3a8854200b54487f5308e3db418461aeb5f67c81d332619b6441b468e480941e63100ed1b263e7adc20689dc3dcda578bfca538fa","other":"23f9bdc82efbf57d3d40a1f2617d0311678fb4a3d6a50cb7e608c649bb618124a76c7ffd17387de963e1cd28d2bd5a61c98613f6e009a8a2a90d989827b35de0","up":false},{"one":"beec648d79437a5d7b4140ced45d82d035c6f64f9c67c58386703811d97c3846787eaf274d2298df809475f0b7519df696563cb8e9a5fb0a9cc419ab13fa8d41","other":"094f9d0fd3bacb17ac67a2edb8ed394fbbd1c8d478233d3269cf217e7b788e21042374936b885bf23ee4f9e03babbe4e08db283dfc2a6e052a8a5ba133717dd5","up":true},{"one":"9db1f94d74a00d1e5e2a391f1bcddf16b6d0670a2c6d91d946d38112c58634444b6fea8e8c05ab4b73bacdd62a0b575f6fb8729978edc216c7842b177b9f9cd9","other":"62666b24d1026345349edb6a878cdc27d6fee8254e83f79a298ce2805260d97aa46423deae440f86ced5cd99b30e970c8e1ea1046752b17d8c80dc68d9a49b60","up":false},{"one":"a608a746f46d4b2e9267c65283380d6d6cb8885a64428fb77df9934bcf4dd1723587ee7c8f4a642dce266a12a6a4cf4e5c6db7fa1024158425a6753e7ab7264c","other":"e2a27dcdee1f89fa362a85c4397840cd8be4ad8d1b9ccb23188c303bcab7619f38772f71385922d090390973b62fb8249efc103f71bc761041bcb3880ec0b935","up":true},{"one":"2f360209383d6de4ebd3b4abaf77796520b8654270b03f2151eac4a01b4417d7e0668c1f9ad30c20ff49aa8a0ab33dba5e6095619d1cf04b7af841722ab773da","other":"aa9a94d6e4eaaed20113c21752c224e3a052abd3769bd6e832759dbaf5154a943cf094eacdcb0727c2fe51a11bd7fc0793d7d5e3312b0aba89d428a00e1fde0c","up":true},{"one":"ddaf3f8478501cda872c056c72063eb64d5b871fc5fff70704872802289dd2d348f73bc342b7f148a90cfaae2448ebf16fea196be9df891dc71a57fb410d59dd","other":"b35f418c7935cc54278e90978c3ef1521ab91daeaf9f1ebc1cd25211611ade091cac4e1f009d71059279d507322a4536501980ac0dd44caddc52fd4c593879f7","up":true},{"one":"cb321c9b0fe2eb3617b8e2461aab170a9dad2c9b04a10eead4e37e551197ea0a7500eb1cb7b155efe1886486ef3d252d8ff0d309f2906a1126ca011d037da70a","other":"7acddc7fb6ac587b7e343804c768e4291cd28dd2b2b9207dea6ee82360d848a52d84f94e4c49e9c421f4f90e2d24f6291e2358783ab0230e6ecde82e69b4ac52","up":true},{"one":"ce0a09bb6fe4c9c93c3dbd800ca9c9ac0714f26a8f8dac2149b6ce7a9011912a5621ea2e45de35c4d31dfe5add00558fdba5dd21acf2d81ba391e82b5b3a5804","other":"5dc69635f6d573c824ea83b18593a47f9f21a6f91ce18d2bf977c97d21f8d2a8ce88829244d12a07d949bbd52fe8a2035bc89685fe1bdd4ee20d766d75d3deee","up":true},{"one":"b26f7c0113a5ae885f7c0e608aea7022a9c8bfc40c5643e60b2ba7343ff09c5be0bc08be34dde3c6b85fea192a46d4764770c12cbaa233df4231a1b99627ef9d","other":"fe62314839c93d2f6e3aee984d5f0b321897c6f39e66800d3de8b773baf6f19e0a03cae025df512aea8d5f1b667b6dbb15c192a90a76d3031c14e33e5c16c4f7","up":true},{"one":"b3316f4fd7dec218a52331f25d17a2faf0f2a417808d7dbb80038154abfbcd2d78da074837b648cff28675f4aa0d65ddb7d15abf3d7e0391d401e313a3ef24a2","other":"f039df8a3206e6e17eee8e95010038c450cb4cc0b5580ed5795d4c21802e1e9d360f4528bdca794f457932b1d6a818862ec847357a861c488332ef6d9480daa6","up":true},{"one":"c9cd9dfb9f90a7948ac5a42c7bd63263f2eef6e1d85547559f7d2ecbf5f9cd1eab051b8e9e661b573c275d84091a44e73f6fc6bcc91dcdb674bd5d939190fc01","other":"adfba6d883cacbb141cd8c59ee04d7e5d520f1ce31a81e5db2d8b2380bf801c1fe4b265a66b71f9643d13a41cb1f6fb4b83399be786da4b6e171b6784bc56e49","up":true},{"one":"cb321c9b0fe2eb3617b8e2461aab170a9dad2c9b04a10eead4e37e551197ea0a7500eb1cb7b155efe1886486ef3d252d8ff0d309f2906a1126ca011d037da70a","other":"4ee37acec2178ef120166265aaa2b64b09b315fb53861405ef46f2503c273eb9692e9cb4c2e67a8652254d430fd6e02dd3fe4cded20bb231a9fb834d292b0b24","up":true},{"one":"1090e9d89cb278a30063a5396d9ba795d3bbc237c76915a6fb7d23aa1822c8535d2fccc44cc8cd2acec68444c0bf1bdf5195ebb9f3cad8dac3d94a4d9c0e5309","other":"c903c5ee3d9cd65bea3ea777e39282c33e1349d945411fb2f16321bf582c2f400956a98fbafe5873fc5f6f6a9a051df5da7e94cbd340f935abe80f91e79ef875","up":true},{"one":"d4b7c787981abec24353c7d496661692233797e3758189bf909a69fe87935bf6da0940daa4f12e81f20c5e88f70b472113688b71a0ae2f91a73ee0e6ff4c8591","other":"68cc8b9a995eef6170abf88bd5fedca06ffcc8d75f247f6041c13e7dfd292727ebda1ff86b776e33b6634355c55e0f8c22fcdb5f9a6e2f22fe1af7854c3b4273","up":true},{"one":"1090e9d89cb278a30063a5396d9ba795d3bbc237c76915a6fb7d23aa1822c8535d2fccc44cc8cd2acec68444c0bf1bdf5195ebb9f3cad8dac3d94a4d9c0e5309","other":"0b7e1e5acabcde503ad827e45724402406114a513f81040a379b0f82df2eab4456b348b27936369c49e3c264d971c6a9e2c2217fdbc5e5b93ac6fc219957834d","up":true},{"one":"c665a6b1b7ad39b86bd4b1fe38b7ee95a0fbb1db15e91381ec9e5a235e33b69ffdc92c60dafd74b7b4dafca1b000e9274bf045abe5b93b1a9c2b31ae071a9898","other":"7acddc7fb6ac587b7e343804c768e4291cd28dd2b2b9207dea6ee82360d848a52d84f94e4c49e9c421f4f90e2d24f6291e2358783ab0230e6ecde82e69b4ac52","up":true},{"one":"abd8f5a4d700c06ec00684b23d2d25c4df1a9554fcfc57b0ddc3fa476e6a699ba75e1213449f900803f83ab8194c6746664b547202047f35b8b3e216c7147bf8","other":"7acddc7fb6ac587b7e343804c768e4291cd28dd2b2b9207dea6ee82360d848a52d84f94e4c49e9c421f4f90e2d24f6291e2358783ab0230e6ecde82e69b4ac52","up":true},{"one":"6c143960dbe3ba4c95e8debc1fda5f420a2a673eb46f7ff7d9a30f4cd2067e67ef8926bf17f0c99b16c79b6dc066b52409a11d47117d4fda4211636b1b74f96c","other":"5142eea687de4248b2184e9896b245563117648e7a156255d9a7ae730313d5d383db3be1125b5accd7e743c2a5d8c3289ec559ef7cbb803b9e82cd49bb213d9f","up":true},{"one":"6b01079463ec2f649db8634cb7a596261c79a8f714d954c772528e0547b017f8ce405e4a0ea9d32270848180e0f77b8c0b022cf95c85e777626edd4d24ea21d2","other":"d4b7c787981abec24353c7d496661692233797e3758189bf909a69fe87935bf6da0940daa4f12e81f20c5e88f70b472113688b71a0ae2f91a73ee0e6ff4c8591","up":true},{"one":"ed6c793eb4565aa9d883a76fad6c97ad0b878b9ef0235e11e89db1af25a9653205f725c6ea258b84bde134f1a6437c6d109b859d17509e5016c4ab98be59032a","other":"4b784f072b7c96c30612767425f552e30e45157e70139dfbe0ae4ff86dc31601adec60f8a3ad9747b02b5219073d8813af9b09d59eaf7ddb7ee24856aff6fa8f","up":true},{"one":"f9ffe87c52ff4c22bd9696af32e0a9d34bb81fb84d9d8bf5aafe2ef9696e7b3d6460bf2a93aecb066133f53416bde841a02d6967bd06e3d4a714f3b2c123a947","other":"07f25fdeab2b44b2e92fc80fca7de9e4a8547d27a98a54593b3395c270a9ff3f2a5da62a2e8531ce86359f0cdc5b6513b773dfd64cce1b83e47065d9760a2c7e","up":true},{"one":"b3316f4fd7dec218a52331f25d17a2faf0f2a417808d7dbb80038154abfbcd2d78da074837b648cff28675f4aa0d65ddb7d15abf3d7e0391d401e313a3ef24a2","other":"049a2b0ab4d49789dbbe1837e2d2ee5220a9401729ea87ab29385b24d79cdce255c3d2b5de6484d49ca6ce07bd41832598260c0a8c290e01d133d77f066f2f99","up":true},{"one":"831cde5b651ba327b059da4c7f84b184bdd6bb99c6690ae816affe25d42c6c3dbe5b59e2b6bf23e9d0f6c485bd341ea57ba1a8220d18b0a40e156b77d84f79ef","other":"7acddc7fb6ac587b7e343804c768e4291cd28dd2b2b9207dea6ee82360d848a52d84f94e4c49e9c421f4f90e2d24f6291e2358783ab0230e6ecde82e69b4ac52","up":true},{"one":"48a5e01e06e297dc1c640ac9601171495bd70fea461c60e7e6e2532695e45fcf68183c2e58b5e6931a6c1c094f5331efbd7f2d93d5f84efdec5a35afa2124438","other":"1b6cad4f9851cc584c5d1405f976bb51a52e27ef4525847df543dcca65ca5eb1ef229dcc68ccbaaf00ab1e044cb5990dd213c805bdb4adcceb6fa70b5c61fdb4","up":true},{"one":"c73d088ade8756c74832c73542bcdb3e52f670f7a74ad3a7eac2a9e3ece6bd081f782a8e1d3f9a40b9aa9201509110f37fc57fcb10ee1ef3ef07b7eab019782e","other":"b597c9ba4da20c49fc4ba019571321d2579588636cdaceb9f225706574970adbf4771dcf186b1decd4e14cd5d257e30a36ca829829598c1775902201ad9793e2","up":true},{"one":"2ca05ffc0ad771e1e045a47f1c0a79ce374a25e3c0e53c2a80d67e7479677003f62880251a83a5074f1c9651d828f1ff7e352935a9df141c1eb75a0c59b00a8b","other":"f915e2398aa5d4370de87504dd76c21a7d0be2581c2ab55b7a47743f1bbaef36384eaacec22760f1e914ceac9d96a10c3d66eb27475ef444e77fee979e6e88cb","up":true},{"one":"66beee3968dbcf3addc6feaf070a4e3e82b5bb164fb72f40add89f732c12e8d0a31a7ee1f1e24a4674e4dfc9a4912b02c17ce3c224d257d78b7156544d6507dc","other":"5bae82d4832092c17bd11474f7748015b8b69b896ab8f683a7c0024fc98740cecbb9e31c6275269f9000e5bfe51d7f45cd5dcd4433e0c87b5741685b40fe3983","up":true},{"one":"0b30b36e155db04c448b662c4df695068b2331cdbe2772aae5fda84159e977515a5ff2e156bc225a9281fef2383926ba8cb11e9c1846fb40db241e524ac14e29","other":"1b6cad4f9851cc584c5d1405f976bb51a52e27ef4525847df543dcca65ca5eb1ef229dcc68ccbaaf00ab1e044cb5990dd213c805bdb4adcceb6fa70b5c61fdb4","up":true},{"one":"17a79cb279306b6bbd35219278f6bba03111079d6c4fadcd3c5e57b09678e111bda5f8e36ca3d223e51e255d6e857363b7741e438b32ec6e6c0dc1b224071081","other":"049a2b0ab4d49789dbbe1837e2d2ee5220a9401729ea87ab29385b24d79cdce255c3d2b5de6484d49ca6ce07bd41832598260c0a8c290e01d133d77f066f2f99","up":true},{"one":"afe5b217dc512eee45575c189826ee5640d11a0ac9e8e4b03e9e62e6cf6df9de500bc8a36cb7d82a2280ce184409164f1772cc5c9e59ad04361522d2b8c364e0","other":"58cfb20d3da3641e0ad529b9edbd4b590a8d1dc9d1ed7b44ed3187dba9260bd7c732fc10981f5b9bffd31d362cb05150173618aa36138984431d94a323a9b313","up":true},{"one":"ce0a09bb6fe4c9c93c3dbd800ca9c9ac0714f26a8f8dac2149b6ce7a9011912a5621ea2e45de35c4d31dfe5add00558fdba5dd21acf2d81ba391e82b5b3a5804","other":"ae4e21e1587a8475afd299e00ca7085c7bf2a44c2c64a3068f12223d9202b0125094385319034691ec26b497ec9cf18fe8c0839224bac1b84279410241cef979","up":true},{"one":"7808fb798d22e78fb1d39b87ddf99a503f820993bc64149eca9e81d9d58fc1adea60d8de14a4f06cb89f3190c0ef0c5e182621a14c9361ccb7e0cee667599cc3","other":"b080891d4ba6d3ab224984360597f9c555bd1367630f5420bfaf230419a05b2be58bebf1554e53eb4c0da81cfb66d4f7697dd65143f11841ff62d8a0d82b6b67","up":true},{"one":"b6a998dea59194cc60ce97c7c9702368411889cb6905516b23f41cc5116fba8d0f237d418318eb0c333cad18003c0e9a6bd8c99080520771f2bad640e2e5ec1c","other":"8dd8ad560af84bec579cadb33d51711aa61b6ed22705010336df5a71a94591173b25e869457429c4a199b205fce8e73530e28203e18b971c2001715e610f152a","up":true},{"one":"afe5b217dc512eee45575c189826ee5640d11a0ac9e8e4b03e9e62e6cf6df9de500bc8a36cb7d82a2280ce184409164f1772cc5c9e59ad04361522d2b8c364e0","other":"5142eea687de4248b2184e9896b245563117648e7a156255d9a7ae730313d5d383db3be1125b5accd7e743c2a5d8c3289ec559ef7cbb803b9e82cd49bb213d9f","up":true},{"one":"453779010ed7c59761da47ccd8869d3fa8349795e57edb9eea416c0712301ea622c7683858e309d19ab137ddb0edef161d0d00a361abeecf0628c3ffabc629ea","other":"db8ba71afeaea1f2964e8978a6eceeb9efa3958424424022213c8193443f8d5afd18490afa954c76360c681404809c7cfaf7e4ebd8bd1a42d403f7f1915b0d29","up":true},{"one":"b137cf2291b530a39516d882200848e7f27a2710e0839b4d25b4f367bea6a0c3aaef8c7c7851c00a2945adcd819ea0508610afc1f453b8bc512b7b4d4faacdf3","other":"7174eca109a1f717653918224c8cfe1b7fbd666405196760913593401eb79f2c7e41003b01f5a458940695b27a4673443c7621a169db7fd968994e552995dbbb","up":true},{"one":"88d5c5fe61ee1e6fa5878e0eaa13bdabaa0ec3d38a5d25b95a467da7627424f25fb5d30535aa0a5ad01c16fe2598dbf570b78cc152a7f4ef66d46fc9ae43592f","other":"a7378ee34876af17c6cd94a69b6b741ec7891ff5375bc4241d48608d047455ed48e6baae80ee88d4710c69ae615cf195cee26c94b54de1bb935628ce1e3a723a","up":true},{"one":"4b784f072b7c96c30612767425f552e30e45157e70139dfbe0ae4ff86dc31601adec60f8a3ad9747b02b5219073d8813af9b09d59eaf7ddb7ee24856aff6fa8f","other":"b4a5efa9028b2d196855393892f79993c2812d02b758f98813ddf82c5d943faf6d66eff811cc5a51936c118f4c768c0d13b54902095e040c602761e63c08655e","up":true},{"one":"535f93057d46c4aae0902546550880be0b5ba67dca12350117d471d67f4f2b3f7bdff29bdc918767974c465df8fa1afa6bd6c29c0a36d51f71c4183673d906f3","other":"84dfd4e4d9f1204893f190eacc4c3999e175c433f70de86e335d27477c097a0552f211a21764f01a708da4c9e9e6552191a61d3e48f41d0e84f01e7ae3beb34e","up":true},{"one":"2ddd49fae11d8bd2e7e75a481be267fa846f51cc1160bc326aeea51c542323ff444909de11e2731e835140bc0b1b32020e1e73fa652511a381222bf0aebc4081","other":"8f88c7ec044f758f29bd8d12a5170bd973aec8f6cddbf512b910c4b75a0fec09c5e198bcd65622037f897759db68da2328b4a7ca93585dc9cb62e46d2a6c0864","up":true},{"one":"6b4e376e9c94242b6d42688c22aa9ab418cb6dfb1cbca1c69de0feceec8d3af29fb005017aaa6e503cc0c03cf0dc5bcab55e01cd6f64b9efa02ed87c03020003","other":"a608a746f46d4b2e9267c65283380d6d6cb8885a64428fb77df9934bcf4dd1723587ee7c8f4a642dce266a12a6a4cf4e5c6db7fa1024158425a6753e7ab7264c","up":true},{"one":"4ff66e9b5d3fd345990bd7605bdc222b78946f0c13b72bf80352812b2426d8f1d36c93e6c8713566004615e8a78ecab12ab0cfba254c0967eeecf8875b25bdae","other":"62dab8b21640e1b44dea452dd7e7de93f27a44840da72d56b11aa96e8463f3a4bb15e75a954d19fc897ae0030b16181d271b79d8198b7cffcddaa9ffcfdcce73","up":true},{"one":"71f89efcf939294bb94ac669c8afd00def58c8dfad519c226adfa068692d588ef797116d42aa146b9d34f3be35ec7c014022640ab3c0f1f9034e44ab1a26e246","other":"afe5b217dc512eee45575c189826ee5640d11a0ac9e8e4b03e9e62e6cf6df9de500bc8a36cb7d82a2280ce184409164f1772cc5c9e59ad04361522d2b8c364e0","up":false},{"one":"acb4088c27ee2ee130ece3506596432afdb9e9757ec11ebdd35c5a6e87239545c48466913a646980104c8fd7a9a335e177f04efffe9dc952dfd7cd5c1bb9aac6","other":"ca1aff0d847c6fdacb623ad9078a0885b3208614fea20d5ff11779779b486bf5e9c794aacf848d3c2d58cfcc1eda8356df82f5fbdd0a5236beffe8e6042848c4","up":true},{"one":"cd8815d66aee8bd488d4e5e25f0cc9c71cc65349f701ea26b1d6cd9c039d16fcb473dbf270a3b33187720ccf4b0ce4f78a6d6edd05f4fe804772d5b6ec45bbd3","other":"8ca3b63cb84f1e9883d82809a9b6777ec1029ecda96fe93b4d494ee9cbefcad13f381b3e480136e542e01054fe1ede66c65db84a0009871ce49383db461c8438","up":true},{"one":"7174eca109a1f717653918224c8cfe1b7fbd666405196760913593401eb79f2c7e41003b01f5a458940695b27a4673443c7621a169db7fd968994e552995dbbb","other":"caaf695c76cf7c047d3f3bfe019d01618e4871cee8ff3f347913da815bbcde145771486f916a44d03f59ea9bc217f169fd0c0765fda3f9b9b28d02a522e180b4","up":true},{"one":"07c63ca5d0309e30d1ab12e7fc142e6d37904b552639cfa97850161491f28f20d87e0304be29357bcfc2ff52fc52fd0d4f6e6011ebb239cced8b5c8dad7abf45","other":"1c2f7ce55a6e38487f3b3fe6083a79f914cd6d7e4aee8f5d56b4a61b3eb584e128c56998db0e13e775edee3adacf54f09960a041dab3daa80a4f8a3b42760c1c","up":true},{"one":"5420da16f7ed5de6b498dbc9a83b7e92e1f9900a6d04ef7351a0bfdfd442b98a5634f28fcea32ba3f3166d21c8ff5a39be70895b32acbdf7592d1d616a345a21","other":"5142eea687de4248b2184e9896b245563117648e7a156255d9a7ae730313d5d383db3be1125b5accd7e743c2a5d8c3289ec559ef7cbb803b9e82cd49bb213d9f","up":true},{"one":"b4fd11306b1416a9bcf4719578976188e104b8c5028b9abd3214d257446b97b70a22e6c00934d80caddde15e8e4d16af03bb399583047983fba373d8313226b7","other":"62666b24d1026345349edb6a878cdc27d6fee8254e83f79a298ce2805260d97aa46423deae440f86ced5cd99b30e970c8e1ea1046752b17d8c80dc68d9a49b60","up":true},{"one":"9bd4f0adb9a966cc5ba632f1b540fe9cd6c8e39fe1a041b315697679cfb04b735952062ce057d456677cc34a84301f26bb727a4ab2646fee734f80a22c620746","other":"df54af3bae257d437c5657905484e0d72e9560c46f8ba6b3437730234e05259b404cca40b0831e911605ff8a68a19e8fd7e958069ec8b40595928892f4fa220c","up":true},{"one":"979838eaefcff456cf1cd9c47ea46854704f5757d8d7ab907019bc422b01af4d62252579bf045d143fab491b0bab823190e2782a457fbf51aa99ae17ec9e145f","other":"adfba6d883cacbb141cd8c59ee04d7e5d520f1ce31a81e5db2d8b2380bf801c1fe4b265a66b71f9643d13a41cb1f6fb4b83399be786da4b6e171b6784bc56e49","up":true},{"one":"2f1967b4410ea2ea8fbaf46771ba82c2846d00aecdb6f873aceae33ab38f72d0a2c2dc6046d3034f514efd090d42011d48e9ab0cb4e3caa2b49a96ef732215a1","other":"6f60ef501b41f9049419b033ae8d793a18067bdcd60347537b0dc3873bdd9a2d10d24909cca7c39781765746128c2165596f6537a94f58279523faee71f9c51d","up":false},{"one":"66d0c5da973d9dd65350ae1ec63776872cdb7ded6afb6f51ae82259f6fd35e884375d15de290625f02ed2e5cdc3f591decb45e5fc64d5b0f835a216fd196f5a3","other":"caaf695c76cf7c047d3f3bfe019d01618e4871cee8ff3f347913da815bbcde145771486f916a44d03f59ea9bc217f169fd0c0765fda3f9b9b28d02a522e180b4","up":true},{"one":"be514f5f17f3177235acb24112b578edf0e373c469073226e547d18080905fd062d572be18e943f13bf9fcf5871e89ceb630a1b848a0e370ef8ef8c6d997a363","other":"2ca05ffc0ad771e1e045a47f1c0a79ce374a25e3c0e53c2a80d67e7479677003f62880251a83a5074f1c9651d828f1ff7e352935a9df141c1eb75a0c59b00a8b","up":false},{"one":"2e409baefbd821485a151993356730e5989810d581e68190fbaa142799c9335bcf98310ad188fed10ae6eb6e2e789730393e509962ec5c0fef0342d72ed088d9","other":"e1ecad3beeb6c19dce551e4a603c7b440b4498c44e298dc67bfaf4ed2c75bbea95df48b1cd1318e2ccb962cbae7c30ff258e73f8c3fc6b7e9ae7a47f7cf8e53c","up":true},{"one":"2e42f845d0393d1682add54ee30b60a953ed283e75d347bc6719ae0e91f6676282e7960f1fd52e5803d6b341fb3582c724b4f9cfd7bce9ce85f13ca480c7e72e","other":"df4c3505e09e1baa88470117b964e758c94f77a4546489ab5ab7f4aebfdce424729ace8867475715fb68f05c66c9674a5767549e266c4fadd1c703ddd735908f","up":true},{"one":"2245f3bf1a3b4e92f912affc75f757cf648b20474c11ffe947884f216b8f24f9dcb6e6a0358a4061b8517478ec15027e185b2f05a777573b4940375bf4aaf2be","other":"352407b42726dcd1aacc46a912ed8124b8b6a3da4e33dab742e40aa2452953d35dc8f42eddc76695ae2317e9f15dde2cd21be4ce826934695ad1847455661d1b","up":true},{"one":"22010c9829626a6892258b09cb3f3edc3f21382fb487b5dbf0dd20e198e37e26134aab850e30337f398d1491b5126839aeb1953ec144bc19aeb889c832f67c6a","other":"f54335964d9b4eb9813eb05f40ef1c523bbf0faac5a04c4737467d590fb6b55c7fa1fc5d4d32c5491d8766b9be6fdfd3ebdb25c5ffe1719f36c86ddf87ae3a85","up":true},{"one":"df54af3bae257d437c5657905484e0d72e9560c46f8ba6b3437730234e05259b404cca40b0831e911605ff8a68a19e8fd7e958069ec8b40595928892f4fa220c","other":"84abcbc7b5598ecfd91ceace0927921a5a3404fdb274fc2a2549abbede5f8e4f62c15688a4dc9a2d80262c45970c88898da245c6eb779f327a81d53a17bbc74c","up":true},{"one":"bf4ff51cc3d9a9d8cefd7e346ce1384d06450228a6086fe12fb0c60fec54bb6478f090bb638fbdbf8f41f7bc6420cd8a5c8b1b8566229b6851167375ef412f46","other":"2ddd49fae11d8bd2e7e75a481be267fa846f51cc1160bc326aeea51c542323ff444909de11e2731e835140bc0b1b32020e1e73fa652511a381222bf0aebc4081","up":true},{"one":"f6ca39b3ad803e99f4e4e9cf759fff6abdf06e6972bdbe524f6eb930c669d6f0e9b91f3de9df394b0d661b068273861391bdbac948ad911351c48cf02f874db6","other":"f33d1f3e460574706ac1c7fc9ebb4683b173496ce3e80017d1c3521bca03d5a41a9c7a6cde8347d2238917b7cc58cab000ce7ccf6bb408561015a2ecbe613408","up":true},{"one":"e2e0419a41bdfc5bd76deae2ddce6ac865f886d764c9bd18799b79fa3b2b6ba66d765d26da2037e98317e1d7e8232a61e63c1d0cfa98c9137424151b46e07171","other":"11d560045536e9d1b0b1b9e8944e00f0ca7f1e6788c9fdb51061820bbb3008ead92bb7836621bf58da7035c87a28328faecb4cb2e3cdb9d7fa4f45790e6bf352","up":true},{"one":"c2705ee7238ef9305e4da196653cde707649435a1e8b5b797d164e5ca06184a77af5bd7fa938c995fdfcbce724fa7eca3d908ee34891ab62cc6dfd411c3fa1da","other":"f9ffe87c52ff4c22bd9696af32e0a9d34bb81fb84d9d8bf5aafe2ef9696e7b3d6460bf2a93aecb066133f53416bde841a02d6967bd06e3d4a714f3b2c123a947","up":true},{"one":"70ee3c7e02a123f78345d41c386e413f06b51f1ab346c2c472891eed7dd26a1f14e213a0f4f2d872859b9b535936a6d9b072d2604456f76221a422710411822f","other":"5566111b7f14d8ec83ba6456488f3fc5c7e2c86bf406dead33b814e1ee9b569d34015a4d88226b7e28fff7784395c086d106287cbbc80acfe75b05cd6e12903d","up":true},{"one":"baa5924e1547c177011285d292aa161a15e5ff282da2cd0afb83c9caffb07bdbb3662c227fa7b26e6dc8be9b8863e647eb5f8ce81640532f8f5c9a7f36557e63","other":"155e4879643a472420012e040a87dbff776fc1976814c0c6cd0d5e157f0d0baac04aa7f2535786c09acc2700547383d2119b64a6f62115f1aff1708738844d8c","up":true},{"one":"759f46661056bcbb30c7706c9fb87e22a30feb523bd53ae5d18db043efa45b49a2b8982abebdd598fe0912a05896390ec2eabe5e160cbafc0771990708ad8c28","other":"17917fa4da06068b587c17899569dcc768b9cd2c27117a4ed67aab26a7e70cf8d32b881db258061ffd89a332a3b29bfd963d8e171a06c3e208ba0de1c42a2b39","up":true},{"one":"2ac93c31937ca205d61cc5c2a1b9037871cac55e9b306b999b28e19566b3316f6539455e014840ea50c2db8a7c97d78804d3a2dcd7cd9c1f32ace0d36e5dd339","other":"81288bb0584b7ffc1546043e052e1df10fd5371b35dedd0bb42ec5b30ce69b741b2f7857af5984d4754b39d7253575fde9298504999b78380ef602d391c4bb1d","up":true},{"one":"cb310c0e86aa455d7c9af6394ae38561c901da30a51d7ccb7e66a09d9a8f192ae8caeff106043426d56397088f141c4e01e3b98f1ee583ffc7318b5f730f3ac7","other":"22010c9829626a6892258b09cb3f3edc3f21382fb487b5dbf0dd20e198e37e26134aab850e30337f398d1491b5126839aeb1953ec144bc19aeb889c832f67c6a","up":true},{"one":"17a79cb279306b6bbd35219278f6bba03111079d6c4fadcd3c5e57b09678e111bda5f8e36ca3d223e51e255d6e857363b7741e438b32ec6e6c0dc1b224071081","other":"f915e2398aa5d4370de87504dd76c21a7d0be2581c2ab55b7a47743f1bbaef36384eaacec22760f1e914ceac9d96a10c3d66eb27475ef444e77fee979e6e88cb","up":true},{"one":"2ca05ffc0ad771e1e045a47f1c0a79ce374a25e3c0e53c2a80d67e7479677003f62880251a83a5074f1c9651d828f1ff7e352935a9df141c1eb75a0c59b00a8b","other":"7808fb798d22e78fb1d39b87ddf99a503f820993bc64149eca9e81d9d58fc1adea60d8de14a4f06cb89f3190c0ef0c5e182621a14c9361ccb7e0cee667599cc3","up":true},{"one":"329145e75496cecb5f5c8f00313a52ddd8c0e8cd27ef1b2bc1b2b56e4d4089aaf5a7a3c4d9a40bdb92483fa05bd24d1cd0fd51883e30439dffa0fc855e1a7cd0","other":"1090e9d89cb278a30063a5396d9ba795d3bbc237c76915a6fb7d23aa1822c8535d2fccc44cc8cd2acec68444c0bf1bdf5195ebb9f3cad8dac3d94a4d9c0e5309","up":true},{"one":"b26f7c0113a5ae885f7c0e608aea7022a9c8bfc40c5643e60b2ba7343ff09c5be0bc08be34dde3c6b85fea192a46d4764770c12cbaa233df4231a1b99627ef9d","other":"329145e75496cecb5f5c8f00313a52ddd8c0e8cd27ef1b2bc1b2b56e4d4089aaf5a7a3c4d9a40bdb92483fa05bd24d1cd0fd51883e30439dffa0fc855e1a7cd0","up":true},{"one":"9133b0b3c8f680286eae90c3beebc3099a13de38775a3ff2abdeced62d05eb2ced5ac85eac0870156be03101024da5e1d9fbf3e1066ddb3f088221e64149acec","other":"5df58ba12334a1b4f983d642fe435901261767cd81f8f37c43e359f5584664e4d287e8c2275995604a3b3a4823418e35cd899a3db2a7db31570e19512f375481","up":true},{"one":"c9cd9dfb9f90a7948ac5a42c7bd63263f2eef6e1d85547559f7d2ecbf5f9cd1eab051b8e9e661b573c275d84091a44e73f6fc6bcc91dcdb674bd5d939190fc01","other":"4fe37f2dfb03707c90a6fe91dbcfd7497db70ffc20043091d50e1cee573210c144e8749340f2c3cb70fe8fc51b317d49e8734dc51ce64b3cdccdd639ae35d1ae","up":true},{"one":"17917fa4da06068b587c17899569dcc768b9cd2c27117a4ed67aab26a7e70cf8d32b881db258061ffd89a332a3b29bfd963d8e171a06c3e208ba0de1c42a2b39","other":"9db1f94d74a00d1e5e2a391f1bcddf16b6d0670a2c6d91d946d38112c58634444b6fea8e8c05ab4b73bacdd62a0b575f6fb8729978edc216c7842b177b9f9cd9","up":true},{"one":"1090e9d89cb278a30063a5396d9ba795d3bbc237c76915a6fb7d23aa1822c8535d2fccc44cc8cd2acec68444c0bf1bdf5195ebb9f3cad8dac3d94a4d9c0e5309","other":"aa9a94d6e4eaaed20113c21752c224e3a052abd3769bd6e832759dbaf5154a943cf094eacdcb0727c2fe51a11bd7fc0793d7d5e3312b0aba89d428a00e1fde0c","up":true},{"one":"d4b7c787981abec24353c7d496661692233797e3758189bf909a69fe87935bf6da0940daa4f12e81f20c5e88f70b472113688b71a0ae2f91a73ee0e6ff4c8591","other":"2e42f845d0393d1682add54ee30b60a953ed283e75d347bc6719ae0e91f6676282e7960f1fd52e5803d6b341fb3582c724b4f9cfd7bce9ce85f13ca480c7e72e","up":true},{"one":"6bf9fb6a25521c16c2ebeb6203d046d7dd40f29cc2ddb067c0222ef56d7012d2ee5d037f71f6668ea56767610b2a54c144aed74b7f68d06993cbd52fa1dc7630","other":"083e67bb19e30d14e4df6d2483367d6659d9b56744d53d9cf7fd15954c327e1bc88a5d0db8833634e1dad7209164451f8934b59f76b5990059261abfd650519a","up":true},{"one":"53df9cce9b0169e58ced53a123d1d8f6e8fdcfb4c2d781ecbb91bb7c8eba36946dd9d21c749259769825d8a6b3faa6bb87c8c6085a522f8a3e376061f59144d9","other":"4f5ab12b9c5127c16739ad0d4f51adce90ba6736cd096eb185ea632789f4b26f1ebabdea4fd3b39dda5409ece6c2d92fd469cf4aecf9d29453e3e042c19b893b","up":true},{"one":"80d997b87856099d844187d3d1fa40846ded652a62c1611b35919c2543915b64ff62476636488556f678e436ea26fcc40db7c6b6bbcb78f590d61c1ff0e424b5","other":"c8b0dba45104fc7c7dff3ce078a0d3f5ade6198bb4656e2bee8076387929133e5ef2bd293b130a9d4f6a6974ca17e8b4a8f406d1219880f1e0f99c65c63af5a4","up":true},{"one":"934a5fe1b91c1891ef4df7f67c027e0eb115d4c2ca4a1b76a135ebd4315c4fb835d6625223194e6a134407b38b0d3928fbc7bc924a3c6a538989a6cf200bf4bd","other":"ca1aff0d847c6fdacb623ad9078a0885b3208614fea20d5ff11779779b486bf5e9c794aacf848d3c2d58cfcc1eda8356df82f5fbdd0a5236beffe8e6042848c4","up":true},{"one":"485825745d97654cbb92a14e0cd1078691d3c28f4d82b1046284b676a42b44ca58eb43474e45e415d3bd3f3c383f9a1a3365821ed7ba6a9f2603b29d58031dc7","other":"b4fd11306b1416a9bcf4719578976188e104b8c5028b9abd3214d257446b97b70a22e6c00934d80caddde15e8e4d16af03bb399583047983fba373d8313226b7","up":true},{"one":"831cde5b651ba327b059da4c7f84b184bdd6bb99c6690ae816affe25d42c6c3dbe5b59e2b6bf23e9d0f6c485bd341ea57ba1a8220d18b0a40e156b77d84f79ef","other":"9133b0b3c8f680286eae90c3beebc3099a13de38775a3ff2abdeced62d05eb2ced5ac85eac0870156be03101024da5e1d9fbf3e1066ddb3f088221e64149acec","up":true},{"one":"f9ffe87c52ff4c22bd9696af32e0a9d34bb81fb84d9d8bf5aafe2ef9696e7b3d6460bf2a93aecb066133f53416bde841a02d6967bd06e3d4a714f3b2c123a947","other":"54b3c57a4adf4dbaf31b85ed1b8dccd6249faa16dd96dd230189f47f57970caeed36627cc8e1b0794707418d580f5bd6001c07be6a79216695f1253db24926bb","up":true},{"one":"4314b0b04331973ed29a58843951f144ac3d09bd5d57b6cd9aaff9b73a7b2ec81e344a3e4ece462bd2081b837a06310e787ef3bb889dabad46fe7efd394c8342","other":"b53078000796f1cdb04dfeac424d5e3e37e30f00bd5bebf9a9ea0525c62917612b3a8f508df6bea59e3c7e4cd1aa530841f9a8af54e44f5617a13dee2c6ff007","up":true},{"one":"ed6c793eb4565aa9d883a76fad6c97ad0b878b9ef0235e11e89db1af25a9653205f725c6ea258b84bde134f1a6437c6d109b859d17509e5016c4ab98be59032a","other":"6f60ef501b41f9049419b033ae8d793a18067bdcd60347537b0dc3873bdd9a2d10d24909cca7c39781765746128c2165596f6537a94f58279523faee71f9c51d","up":false},{"one":"6c143960dbe3ba4c95e8debc1fda5f420a2a673eb46f7ff7d9a30f4cd2067e67ef8926bf17f0c99b16c79b6dc066b52409a11d47117d4fda4211636b1b74f96c","other":"920a301186bdf665a721676ece7c180413369ea6eff7537f42049d9eb409f28cc864099590116e885f57368959fb2cff7003697d9b1515e68bf3fa7aee0278ef","up":true},{"one":"420b9c90584651c5a3fe3c16aa377444a321dca934f8a097d01a616554067feabebf2fdc8d2a25797f29a8fef30d5e2c82f8e85b20f509a880367b9b0ccdea47","other":"3d2df188704eeac09c8b291bf275a73888199a231c832c51dbc3d746968d4b51a7d5eae0c7c9b8c8e19f5e28d38c375e01abefa343f31dbe221deb837ab8a0df","up":true},{"one":"b3316f4fd7dec218a52331f25d17a2faf0f2a417808d7dbb80038154abfbcd2d78da074837b648cff28675f4aa0d65ddb7d15abf3d7e0391d401e313a3ef24a2","other":"f915e2398aa5d4370de87504dd76c21a7d0be2581c2ab55b7a47743f1bbaef36384eaacec22760f1e914ceac9d96a10c3d66eb27475ef444e77fee979e6e88cb","up":true},{"one":"7bbb3f3ed51cf84c077806fbd6d3578e105bc32aa6043da188793f066ad6df383a9f7cc0bd3124f4c887704bd188d480ce264fcdf178905bbda3b270927ea138","other":"a7507aa5665e165ab2e2a07def272f0677f9d6d35bb82268a34214384e7d8ef7635a299368752e63cfd02d4e60231076baf23cfa10d17492e55181b391ecf335","up":true},{"one":"c73d088ade8756c74832c73542bcdb3e52f670f7a74ad3a7eac2a9e3ece6bd081f782a8e1d3f9a40b9aa9201509110f37fc57fcb10ee1ef3ef07b7eab019782e","other":"e2a27dcdee1f89fa362a85c4397840cd8be4ad8d1b9ccb23188c303bcab7619f38772f71385922d090390973b62fb8249efc103f71bc761041bcb3880ec0b935","up":true},{"one":"617595a230e0a74a3db3b47cd27b941e02bdee9a84cdfa8eaa63a55941eb5caa79e20fb69726a4d46a0e5aeed24039f8c5a20679a692df0bc140f42558ca9a2b","other":"ff6f94005d1df7677600069764855c1c2aa0543cbe9f480f8feefec76c49d9e2c7bb2d8e38c89e9430f53f8b593d93f143c45985a56a5a32c736128214c95eda","up":true},{"one":"bd1a7c63fca9e1fcc67d7fd62670beefe2bce483cf1dc1233ee85eb90db607917cd9a5d7170b10e80b925a20e2af2c54d286b01805ac34967410859f4f03da09","other":"b4fd11306b1416a9bcf4719578976188e104b8c5028b9abd3214d257446b97b70a22e6c00934d80caddde15e8e4d16af03bb399583047983fba373d8313226b7","up":true},{"one":"97981f4b825620985b746c85824d7a4d307ee25d60a72c2b7de4b1d4f3b1c002652adc3045842d350f849789e410a0357a0b42fa637a1b4fc9d39e44f8a674d7","other":"829b074b70d757da6aa00f7bace3cf1b5d2d4eeadb7f370c1a85374a01a70b54ac53d747267e386f3b41e6d790fecdd6e74b8f89745501ee82439a66ea54443a","up":true},{"one":"fe62314839c93d2f6e3aee984d5f0b321897c6f39e66800d3de8b773baf6f19e0a03cae025df512aea8d5f1b667b6dbb15c192a90a76d3031c14e33e5c16c4f7","other":"4b784f072b7c96c30612767425f552e30e45157e70139dfbe0ae4ff86dc31601adec60f8a3ad9747b02b5219073d8813af9b09d59eaf7ddb7ee24856aff6fa8f","up":true},{"one":"ce0a09bb6fe4c9c93c3dbd800ca9c9ac0714f26a8f8dac2149b6ce7a9011912a5621ea2e45de35c4d31dfe5add00558fdba5dd21acf2d81ba391e82b5b3a5804","other":"6c143960dbe3ba4c95e8debc1fda5f420a2a673eb46f7ff7d9a30f4cd2067e67ef8926bf17f0c99b16c79b6dc066b52409a11d47117d4fda4211636b1b74f96c","up":true},{"one":"8d4920d6e3a6717699b5a3af068cbdfc16858d7e393d158d41b1b5f345b47129eef89e1d055386c518f400b134678c21590f0317dea3436d4cef60f45455cf12","other":"f915e2398aa5d4370de87504dd76c21a7d0be2581c2ab55b7a47743f1bbaef36384eaacec22760f1e914ceac9d96a10c3d66eb27475ef444e77fee979e6e88cb","up":true},{"one":"4de378164d77a28c90cf162dd1b465e0282ee17aa7d3bb3179252466f72da33a36c9f298f7c9498e38dba4018e7ce3e5fe631c83842cd9059e23a7fece366d87","other":"109556abac422a912ecffec0d8796f8f16e92e8f95cecf72dc89e97a8bf1fd37aad3c66aa3cf134acade6d065c31821f977171d5c5463305b57ce3eee99a7ab4","up":true},{"one":"ee36d1d5dd69fd30242d7da2e941b34ade5581c7164fcc43288ecfc52937a98f1b31ade5d1e4dbf611cbe1c7875b2840c89435081cde471c271d7bc60e9ef211","other":"934a5fe1b91c1891ef4df7f67c027e0eb115d4c2ca4a1b76a135ebd4315c4fb835d6625223194e6a134407b38b0d3928fbc7bc924a3c6a538989a6cf200bf4bd","up":true},{"one":"68cc8b9a995eef6170abf88bd5fedca06ffcc8d75f247f6041c13e7dfd292727ebda1ff86b776e33b6634355c55e0f8c22fcdb5f9a6e2f22fe1af7854c3b4273","other":"aacff366e601e072a2113add9020e19b6612f3e85b6e607fdc8cc1b6991f43be0b1f835ed3dc41d1f2b3e0caf7fac252c8eb4c150667d48207fa92ea5f0a7455","up":true},{"one":"2e42f845d0393d1682add54ee30b60a953ed283e75d347bc6719ae0e91f6676282e7960f1fd52e5803d6b341fb3582c724b4f9cfd7bce9ce85f13ca480c7e72e","other":"0cacda5560faff9d20e29a0625d3cd340ec075f198a50ab8b79338cee0e0db84c7c7e71042fd8c8f73e507b570de5d26c39473136b575f0167625a1168309ec5","up":true},{"one":"9194a3a4c8f3235203e48bdb10902d958d26c342805ea6365af9711213536509719d917c694f9a4fbdde6889a4c92299a5301f0275bda4dbcd2541b5bff5b271","other":"a7378ee34876af17c6cd94a69b6b741ec7891ff5375bc4241d48608d047455ed48e6baae80ee88d4710c69ae615cf195cee26c94b54de1bb935628ce1e3a723a","up":true},{"one":"f54335964d9b4eb9813eb05f40ef1c523bbf0faac5a04c4737467d590fb6b55c7fa1fc5d4d32c5491d8766b9be6fdfd3ebdb25c5ffe1719f36c86ddf87ae3a85","other":"5142eea687de4248b2184e9896b245563117648e7a156255d9a7ae730313d5d383db3be1125b5accd7e743c2a5d8c3289ec559ef7cbb803b9e82cd49bb213d9f","up":true},{"one":"1bc1d6155ba35d29ea16938994e08df76ebd8f16bd180bd6a9b9d8798d0745889fe72d641dd78bd8ec13526929f7eb5aaa6a388430fa69033d6db581e53c6422","other":"979838eaefcff456cf1cd9c47ea46854704f5757d8d7ab907019bc422b01af4d62252579bf045d143fab491b0bab823190e2782a457fbf51aa99ae17ec9e145f","up":true},{"one":"d3105ede6c21bc643d523afcd1309a5dcf03f70797a92f167c3a19f86ae98882fe1a9d4094d7a3dee4a0833b8075b6c3e9aaa7f4879dc47bb388c3ae85522288","other":"a608a746f46d4b2e9267c65283380d6d6cb8885a64428fb77df9934bcf4dd1723587ee7c8f4a642dce266a12a6a4cf4e5c6db7fa1024158425a6753e7ab7264c","up":true},{"one":"df4c3505e09e1baa88470117b964e758c94f77a4546489ab5ab7f4aebfdce424729ace8867475715fb68f05c66c9674a5767549e266c4fadd1c703ddd735908f","other":"385168340139236a0e0f537fa693122db9fa02a377c96f31aae54718e92624fc0288164877e63616651565e055c53f7074ab2fdd18a837da6faf644941305bf0","up":true},{"one":"76cbf9fc0f3517fb615fa96104780218e85d064ee5a1d518f3b78f4dbebf144df38c427445fdd6c9b436489c00ff9497d747a8fd70f380f95601d59e52e021e8","other":"a78f18691e0dbf3c08fe9d7dec188e6a05a93833432fb99eb2b3924ab0bde7a44db2a102a65544bbdc4fb61bc3a3d569230d9843a335bf619167fb045d78ab3c","up":true},{"one":"f039df8a3206e6e17eee8e95010038c450cb4cc0b5580ed5795d4c21802e1e9d360f4528bdca794f457932b1d6a818862ec847357a861c488332ef6d9480daa6","other":"caaf695c76cf7c047d3f3bfe019d01618e4871cee8ff3f347913da815bbcde145771486f916a44d03f59ea9bc217f169fd0c0765fda3f9b9b28d02a522e180b4","up":true},{"one":"5142eea687de4248b2184e9896b245563117648e7a156255d9a7ae730313d5d383db3be1125b5accd7e743c2a5d8c3289ec559ef7cbb803b9e82cd49bb213d9f","other":"920a301186bdf665a721676ece7c180413369ea6eff7537f42049d9eb409f28cc864099590116e885f57368959fb2cff7003697d9b1515e68bf3fa7aee0278ef","up":true},{"one":"f915e2398aa5d4370de87504dd76c21a7d0be2581c2ab55b7a47743f1bbaef36384eaacec22760f1e914ceac9d96a10c3d66eb27475ef444e77fee979e6e88cb","other":"1b063741c76fe65e62b4eae42751319d0cce66f22dde9f1cf83d6cca249a0e65bc7f6f22597697362fadd226222fb3847f8e146961969d1b4c9f7e475389cd8e","up":true},{"one":"1b6cad4f9851cc584c5d1405f976bb51a52e27ef4525847df543dcca65ca5eb1ef229dcc68ccbaaf00ab1e044cb5990dd213c805bdb4adcceb6fa70b5c61fdb4","other":"8c6d77833bf1a98beabe7a92d985d13d52fb2e50768719ffbc6fce21ea676802a074b6e620b3ef80e12fad04f94a3c288d91df9716a6cfae09ef073b9dc1f2cb","up":true},{"one":"5420da16f7ed5de6b498dbc9a83b7e92e1f9900a6d04ef7351a0bfdfd442b98a5634f28fcea32ba3f3166d21c8ff5a39be70895b32acbdf7592d1d616a345a21","other":"a99852c5bf08ea4713af9cade5343d1259bfb90401aca7fcff18c58cd56a98804dd16c61fea71039c0ac31b9bbbb9dc5aeaf0c2f074d3365e88d17031802d636","up":true},{"one":"7b1e20217f594f87350542df31ff5ae8a635679bac7962d49c97e02190c644b673d03e7eba2626b45ca7ebf98d8a972dadbba02c18a8d2cbfc3e7a4cced5b4b7","other":"9bd4f0adb9a966cc5ba632f1b540fe9cd6c8e39fe1a041b315697679cfb04b735952062ce057d456677cc34a84301f26bb727a4ab2646fee734f80a22c620746","up":true},{"one":"657d5370319128d24d925b41065eb619409d63ec6280975d78877a4028287463f6442f5206dd703569a05b2b542ad8bbb99803da265408208d6356a26d283d08","other":"d4b7c787981abec24353c7d496661692233797e3758189bf909a69fe87935bf6da0940daa4f12e81f20c5e88f70b472113688b71a0ae2f91a73ee0e6ff4c8591","up":true},{"one":"0cacda5560faff9d20e29a0625d3cd340ec075f198a50ab8b79338cee0e0db84c7c7e71042fd8c8f73e507b570de5d26c39473136b575f0167625a1168309ec5","other":"f33d1f3e460574706ac1c7fc9ebb4683b173496ce3e80017d1c3521bca03d5a41a9c7a6cde8347d2238917b7cc58cab000ce7ccf6bb408561015a2ecbe613408","up":true},{"one":"6b01079463ec2f649db8634cb7a596261c79a8f714d954c772528e0547b017f8ce405e4a0ea9d32270848180e0f77b8c0b022cf95c85e777626edd4d24ea21d2","other":"80d997b87856099d844187d3d1fa40846ded652a62c1611b35919c2543915b64ff62476636488556f678e436ea26fcc40db7c6b6bbcb78f590d61c1ff0e424b5","up":true},{"one":"0a4eec7b0e05da799aca5b36d9e2530f2a89d1426b1fcb7d8f9a662df8a8b5b763767a20db3c9c63e0bd13c2a6e16d3ba8f03baf84f5e5d24917b3f211d9bcfc","other":"f38a9d792173a29c61389f5d84c005d78eac6e750659aad42e2d6df883f04eb3126b2c38fac95076eeed455b2031aaf694143922aa93a2d50412a2454dc56e28","up":true},{"one":"a78f18691e0dbf3c08fe9d7dec188e6a05a93833432fb99eb2b3924ab0bde7a44db2a102a65544bbdc4fb61bc3a3d569230d9843a335bf619167fb045d78ab3c","other":"a127faa19dcb7da585983d36a8e9d3e9a44a6db68507b60c70da71011f44ce377944802f39cd65f5a705cd8249ac1ef7ed8fd699349098f3f8e23b37592c80ae","up":true},{"one":"315b8a1711f680c2eaa607e35ef7a9e19c2b61721af8a7e08f1325dde1fe33cf1f47b3cc4acf12d541631041cf1b42754875fd1c9b66ee32797b72b9f7711256","other":"7808fb798d22e78fb1d39b87ddf99a503f820993bc64149eca9e81d9d58fc1adea60d8de14a4f06cb89f3190c0ef0c5e182621a14c9361ccb7e0cee667599cc3","up":true},{"one":"2f903b2fd4f9432b7d91b5c3e4c7ee3cb9c56fe7efc4baff0edd06fc75e4b7492f2c3c929755746df59c9f95d437a12ba40ac138d08f5bc7aa091f49f3b852c2","other":"8dd8ad560af84bec579cadb33d51711aa61b6ed22705010336df5a71a94591173b25e869457429c4a199b205fce8e73530e28203e18b971c2001715e610f152a","up":true},{"one":"c665a6b1b7ad39b86bd4b1fe38b7ee95a0fbb1db15e91381ec9e5a235e33b69ffdc92c60dafd74b7b4dafca1b000e9274bf045abe5b93b1a9c2b31ae071a9898","other":"4de378164d77a28c90cf162dd1b465e0282ee17aa7d3bb3179252466f72da33a36c9f298f7c9498e38dba4018e7ce3e5fe631c83842cd9059e23a7fece366d87","up":true},{"one":"abd8f5a4d700c06ec00684b23d2d25c4df1a9554fcfc57b0ddc3fa476e6a699ba75e1213449f900803f83ab8194c6746664b547202047f35b8b3e216c7147bf8","other":"663535b22018a4ef0b151572ef286fa66c22c6e9b2913a69c4a735d4b0149bdf6c84bd83d710f8aa2627e8993b7f020750fbc6f56a3365ce4c840e2b3de1a6c1","up":true},{"one":"48a5e01e06e297dc1c640ac9601171495bd70fea461c60e7e6e2532695e45fcf68183c2e58b5e6931a6c1c094f5331efbd7f2d93d5f84efdec5a35afa2124438","other":"ddaf3f8478501cda872c056c72063eb64d5b871fc5fff70704872802289dd2d348f73bc342b7f148a90cfaae2448ebf16fea196be9df891dc71a57fb410d59dd","up":true},{"one":"0b30b36e155db04c448b662c4df695068b2331cdbe2772aae5fda84159e977515a5ff2e156bc225a9281fef2383926ba8cb11e9c1846fb40db241e524ac14e29","other":"54b3c57a4adf4dbaf31b85ed1b8dccd6249faa16dd96dd230189f47f57970caeed36627cc8e1b0794707418d580f5bd6001c07be6a79216695f1253db24926bb","up":true},{"one":"2bfba66ec9d63e928d77d455f2e10a14d6213e515099d5db14fa44a8bfc147eb0fa7afa9aaccdc86453c6903b55556059a2e13dd61fc494127d4a3ec173bf9ea","other":"4b784f072b7c96c30612767425f552e30e45157e70139dfbe0ae4ff86dc31601adec60f8a3ad9747b02b5219073d8813af9b09d59eaf7ddb7ee24856aff6fa8f","up":true},{"one":"292c78c8e41606e98428096bc6f4609a7aa48e5c4d17eecc64d65faae4a7270b0c15f0cd74274015688ea0a9aff34f215c29118222e362a29c8d637963973a55","other":"62666b24d1026345349edb6a878cdc27d6fee8254e83f79a298ce2805260d97aa46423deae440f86ced5cd99b30e970c8e1ea1046752b17d8c80dc68d9a49b60","up":false},{"one":"7b5c0e81c7f4e3ae29d745f6028cfa10b29a16a9c261b65fb8dd05d6eccc634612ad5d3029c8e9f39863a2cdb2682c25f090139bf5c4950e25647e39dcb40e63","other":"389b5c1a805f87427e6d647ec5488342a3f7d700615943d5ad98ca5c111f33c7ee007970b4d3e475892095c0d5a79b7ed52d12598398818159000d4b9b719126","up":true},{"one":"7554993f6efd8d9016ff525ae73c41ee2e0dbd4970c563ba9b61a99c1c8943b433c4b7d48450f6e0fbc9ac198d907698093de20e6c1f7755520fb1e1cbee4eb4","other":"617595a230e0a74a3db3b47cd27b941e02bdee9a84cdfa8eaa63a55941eb5caa79e20fb69726a4d46a0e5aeed24039f8c5a20679a692df0bc140f42558ca9a2b","up":true},{"one":"0c14dd51a56130c51009e3ce47c96b2afef26b7e86cfca65d8a9bae1abef13b3a7a192b422d894c39e24ab00be412d166a3571cc259ff4462d4ad8925a153766","other":"385168340139236a0e0f537fa693122db9fa02a377c96f31aae54718e92624fc0288164877e63616651565e055c53f7074ab2fdd18a837da6faf644941305bf0","up":true},{"one":"ca1aff0d847c6fdacb623ad9078a0885b3208614fea20d5ff11779779b486bf5e9c794aacf848d3c2d58cfcc1eda8356df82f5fbdd0a5236beffe8e6042848c4","other":"663535b22018a4ef0b151572ef286fa66c22c6e9b2913a69c4a735d4b0149bdf6c84bd83d710f8aa2627e8993b7f020750fbc6f56a3365ce4c840e2b3de1a6c1","up":true},{"one":"663535b22018a4ef0b151572ef286fa66c22c6e9b2913a69c4a735d4b0149bdf6c84bd83d710f8aa2627e8993b7f020750fbc6f56a3365ce4c840e2b3de1a6c1","other":"389b5c1a805f87427e6d647ec5488342a3f7d700615943d5ad98ca5c111f33c7ee007970b4d3e475892095c0d5a79b7ed52d12598398818159000d4b9b719126","up":true},{"one":"1f6d803a4ca186463772850ca0901fb920af7e74fdd2480c3c368fa707838ee91bbcfb57d5e3510c802b9b85f2d954f04c9b675414274bdaebae6488dcf94c10","other":"0deda014fa3c0bc8f37d853e1448f95f56f97048c28797d72258fd3ba2f1f776ae11566197466596356cd172847ab02a89f4cf047e58383249fb2a4cd69b6206","up":true},{"one":"ff6f94005d1df7677600069764855c1c2aa0543cbe9f480f8feefec76c49d9e2c7bb2d8e38c89e9430f53f8b593d93f143c45985a56a5a32c736128214c95eda","other":"2f360209383d6de4ebd3b4abaf77796520b8654270b03f2151eac4a01b4417d7e0668c1f9ad30c20ff49aa8a0ab33dba5e6095619d1cf04b7af841722ab773da","up":true},{"one":"23f9bdc82efbf57d3d40a1f2617d0311678fb4a3d6a50cb7e608c649bb618124a76c7ffd17387de963e1cd28d2bd5a61c98613f6e009a8a2a90d989827b35de0","other":"24662a43944228e4ff74736bcf0a0a4f79c87ecfdb739225b2fc45110c11bfc38aaf2d09d98e5817477848e553f187ac5408bdb864518dfa7f5df542768828db","up":true},{"one":"c903c5ee3d9cd65bea3ea777e39282c33e1349d945411fb2f16321bf582c2f400956a98fbafe5873fc5f6f6a9a051df5da7e94cbd340f935abe80f91e79ef875","other":"3dfd733dde9414af916625ab981777ff1ad7ca0f6d1e4e7d9e2739969e21182fd13d85e281868653e7325b20069356b11524b54143c47fd3955a911cf7325ad4","up":true},{"one":"74d84cfdaf32cd4cc67771f29878f1365120bd65cc14848008d5386a81f495bf88eb4132fa38a2cc109ae1e7f02c9b97597ab9d1a9c19c945e710ab9df07cdcd","other":"2f1967b4410ea2ea8fbaf46771ba82c2846d00aecdb6f873aceae33ab38f72d0a2c2dc6046d3034f514efd090d42011d48e9ab0cb4e3caa2b49a96ef732215a1","up":true},{"one":"389b5c1a805f87427e6d647ec5488342a3f7d700615943d5ad98ca5c111f33c7ee007970b4d3e475892095c0d5a79b7ed52d12598398818159000d4b9b719126","other":"fd4968df03d767a223bf7e4dbe26b5c27048298df40e81cad50b344fb3e6837965f2646dab7ffb2891a5c507343ed84bb8bbe403287b51dae538d58fcb6e7623","up":true},{"one":"54b3c57a4adf4dbaf31b85ed1b8dccd6249faa16dd96dd230189f47f57970caeed36627cc8e1b0794707418d580f5bd6001c07be6a79216695f1253db24926bb","other":"3612863ce0456c91785a829bf5c9d2b2fb97dda083a1847e5a4ebaa6fce1260faf4d1eb374c2225431a82774163835fb59c8cb0fa9fc0969eab5410c71109cc2","up":true},{"one":"2ac522ebfa49d37f86c6270ad4cdad0e766493f0e463b18c9906c70fbd2e5c6ff6b0d5879de6e3894418370636963a78b0c0cf087a8684c2ca30c9c736e49228","other":"2ab9513899c3c829b6284e56bf2b9862dd0156ec052b58615dba77d450dac642e534ec36ae5d3234262aff54e19f99856e908b9d8c1da660a7834a445610715b","up":true},{"one":"3612863ce0456c91785a829bf5c9d2b2fb97dda083a1847e5a4ebaa6fce1260faf4d1eb374c2225431a82774163835fb59c8cb0fa9fc0969eab5410c71109cc2","other":"b4fd11306b1416a9bcf4719578976188e104b8c5028b9abd3214d257446b97b70a22e6c00934d80caddde15e8e4d16af03bb399583047983fba373d8313226b7","up":true},{"one":"920a301186bdf665a721676ece7c180413369ea6eff7537f42049d9eb409f28cc864099590116e885f57368959fb2cff7003697d9b1515e68bf3fa7aee0278ef","other":"4ee37acec2178ef120166265aaa2b64b09b315fb53861405ef46f2503c273eb9692e9cb4c2e67a8652254d430fd6e02dd3fe4cded20bb231a9fb834d292b0b24","up":true},{"one":"2f1967b4410ea2ea8fbaf46771ba82c2846d00aecdb6f873aceae33ab38f72d0a2c2dc6046d3034f514efd090d42011d48e9ab0cb4e3caa2b49a96ef732215a1","other":"920a301186bdf665a721676ece7c180413369ea6eff7537f42049d9eb409f28cc864099590116e885f57368959fb2cff7003697d9b1515e68bf3fa7aee0278ef","up":true},{"one":"f5c1215a84a56d52f92ca0dc3a32df98c98a9c2ea2e9a34560210c16de1b440d20d043c8c25955dda8c22e55e92ddb49fd82e8b9b84072aabaa755a229bb19f4","other":"cd8815d66aee8bd488d4e5e25f0cc9c71cc65349f701ea26b1d6cd9c039d16fcb473dbf270a3b33187720ccf4b0ce4f78a6d6edd05f4fe804772d5b6ec45bbd3","up":true},{"one":"9e621c3eb534855ca292efa27a3fbc89b4f05c80a4bc65bcff2f14ff28ef43cbe14137d2fddc6fe2658bb06947d918476b479dde71469b8680e5d8a7a01619b5","other":"4e68553db7be307b8379e8bec383b5c92e4b23debcefca575d24504e2062618f74c26e60e0d9e47f096997a7f841e2c32c994124f495ef3352ef964b33fd3a51","up":true},{"one":"4e68553db7be307b8379e8bec383b5c92e4b23debcefca575d24504e2062618f74c26e60e0d9e47f096997a7f841e2c32c994124f495ef3352ef964b33fd3a51","other":"07c63ca5d0309e30d1ab12e7fc142e6d37904b552639cfa97850161491f28f20d87e0304be29357bcfc2ff52fc52fd0d4f6e6011ebb239cced8b5c8dad7abf45","up":true},{"one":"df4c3505e09e1baa88470117b964e758c94f77a4546489ab5ab7f4aebfdce424729ace8867475715fb68f05c66c9674a5767549e266c4fadd1c703ddd735908f","other":"f6ca39b3ad803e99f4e4e9cf759fff6abdf06e6972bdbe524f6eb930c669d6f0e9b91f3de9df394b0d661b068273861391bdbac948ad911351c48cf02f874db6","up":true},{"one":"d3105ede6c21bc643d523afcd1309a5dcf03f70797a92f167c3a19f86ae98882fe1a9d4094d7a3dee4a0833b8075b6c3e9aaa7f4879dc47bb388c3ae85522288","other":"c903c5ee3d9cd65bea3ea777e39282c33e1349d945411fb2f16321bf582c2f400956a98fbafe5873fc5f6f6a9a051df5da7e94cbd340f935abe80f91e79ef875","up":true},{"one":"fe8ac5d33cd8ab6a1dad9567cdfb89b431a5c4f4a584fc608b92e7dfd06f70988e71e2f11f9fda9ee797c9ffba83bc085939fdf2522dde39f28202be92650566","other":"ce0a09bb6fe4c9c93c3dbd800ca9c9ac0714f26a8f8dac2149b6ce7a9011912a5621ea2e45de35c4d31dfe5add00558fdba5dd21acf2d81ba391e82b5b3a5804","up":true},{"one":"76cbf9fc0f3517fb615fa96104780218e85d064ee5a1d518f3b78f4dbebf144df38c427445fdd6c9b436489c00ff9497d747a8fd70f380f95601d59e52e021e8","other":"2245f3bf1a3b4e92f912affc75f757cf648b20474c11ffe947884f216b8f24f9dcb6e6a0358a4061b8517478ec15027e185b2f05a777573b4940375bf4aaf2be","up":true},{"one":"40bdac599b00e9c41ad6476ee415c33d9c17c5aa672692c2404e523b29dc315da929a86874bed87fd9009871805d1dbf3098e7a817193e3b08a6eee66346da79","other":"4b784f072b7c96c30612767425f552e30e45157e70139dfbe0ae4ff86dc31601adec60f8a3ad9747b02b5219073d8813af9b09d59eaf7ddb7ee24856aff6fa8f","up":true},{"one":"829b074b70d757da6aa00f7bace3cf1b5d2d4eeadb7f370c1a85374a01a70b54ac53d747267e386f3b41e6d790fecdd6e74b8f89745501ee82439a66ea54443a","other":"fe62314839c93d2f6e3aee984d5f0b321897c6f39e66800d3de8b773baf6f19e0a03cae025df512aea8d5f1b667b6dbb15c192a90a76d3031c14e33e5c16c4f7","up":true},{"one":"9bbbfac8be4a000f51a4ce8d024d2595b5d491afec0138922dddfde5ef62c664040c2e9304cc6b7bc688233b5d0c4644b8c8793227c078285a3ab894ef0497a3","other":"ca1aff0d847c6fdacb623ad9078a0885b3208614fea20d5ff11779779b486bf5e9c794aacf848d3c2d58cfcc1eda8356df82f5fbdd0a5236beffe8e6042848c4","up":true},{"one":"1c2f7ce55a6e38487f3b3fe6083a79f914cd6d7e4aee8f5d56b4a61b3eb584e128c56998db0e13e775edee3adacf54f09960a041dab3daa80a4f8a3b42760c1c","other":"016f8f4619a16a07fbde5a18e362158d696e4d9f104a77787f26e32a25cd7d278256f8e0db865c488a99511ec27a5eddd5ebbd1c1397fa7f8db111062e5fe959","up":true},{"one":"855bdf057f4a6b095e2000ada199447b5b4f2f8d78d2ecbaa0ff1fbf761788870ee999266ad3b26efa02be1a46a4d92ac0debb85a2ceab3442394ee7d99e5355","other":"f6ca39b3ad803e99f4e4e9cf759fff6abdf06e6972bdbe524f6eb930c669d6f0e9b91f3de9df394b0d661b068273861391bdbac948ad911351c48cf02f874db6","up":true},{"one":"5526d86ba9df651091d88460a9bedb9cedb957d452a635e1db46b9fed78082022adec0047cd7485956a4ecbb0e18107595de0de3c35242527cd302bf74a19260","other":"6bf9fb6a25521c16c2ebeb6203d046d7dd40f29cc2ddb067c0222ef56d7012d2ee5d037f71f6668ea56767610b2a54c144aed74b7f68d06993cbd52fa1dc7630","up":true},{"one":"df54af3bae257d437c5657905484e0d72e9560c46f8ba6b3437730234e05259b404cca40b0831e911605ff8a68a19e8fd7e958069ec8b40595928892f4fa220c","other":"4ff66e9b5d3fd345990bd7605bdc222b78946f0c13b72bf80352812b2426d8f1d36c93e6c8713566004615e8a78ecab12ab0cfba254c0967eeecf8875b25bdae","up":true},{"one":"f38a9d792173a29c61389f5d84c005d78eac6e750659aad42e2d6df883f04eb3126b2c38fac95076eeed455b2031aaf694143922aa93a2d50412a2454dc56e28","other":"4ff66e9b5d3fd345990bd7605bdc222b78946f0c13b72bf80352812b2426d8f1d36c93e6c8713566004615e8a78ecab12ab0cfba254c0967eeecf8875b25bdae","up":true},{"one":"016f8f4619a16a07fbde5a18e362158d696e4d9f104a77787f26e32a25cd7d278256f8e0db865c488a99511ec27a5eddd5ebbd1c1397fa7f8db111062e5fe959","other":"53df9cce9b0169e58ced53a123d1d8f6e8fdcfb4c2d781ecbb91bb7c8eba36946dd9d21c749259769825d8a6b3faa6bb87c8c6085a522f8a3e376061f59144d9","up":true},{"one":"7ac5b07eb555af3bb4ca3f0f4b45204d43cc3798c244435909b97d9a32fc3abf0b50666e260e046bce826a7a102a92d389f8f39c5311e83bb34beddac29d50e3","other":"53df9cce9b0169e58ced53a123d1d8f6e8fdcfb4c2d781ecbb91bb7c8eba36946dd9d21c749259769825d8a6b3faa6bb87c8c6085a522f8a3e376061f59144d9","up":true},{"one":"1944f98d4db32c56a5efda5a79aa5f276bfab1e084d6611fec0e735b8bc0f45b457cdb74a23fc83b2377821fa8316123c9877acd6db7c41058ca5d3cfedaecf9","other":"beec648d79437a5d7b4140ced45d82d035c6f64f9c67c58386703811d97c3846787eaf274d2298df809475f0b7519df696563cb8e9a5fb0a9cc419ab13fa8d41","up":true},{"one":"049a2b0ab4d49789dbbe1837e2d2ee5220a9401729ea87ab29385b24d79cdce255c3d2b5de6484d49ca6ce07bd41832598260c0a8c290e01d133d77f066f2f99","other":"5566111b7f14d8ec83ba6456488f3fc5c7e2c86bf406dead33b814e1ee9b569d34015a4d88226b7e28fff7784395c086d106287cbbc80acfe75b05cd6e12903d","up":true},{"one":"7aaf7817b93aa6d2f50513791f9ad7629a901ed0dcb151189f44763f83423446b20ec79a48fa260cd9bc2907d5f0ad06b2c4c5e6d812f3d8876c8020ebe41019","other":"f6ca39b3ad803e99f4e4e9cf759fff6abdf06e6972bdbe524f6eb930c669d6f0e9b91f3de9df394b0d661b068273861391bdbac948ad911351c48cf02f874db6","up":true},{"one":"a127faa19dcb7da585983d36a8e9d3e9a44a6db68507b60c70da71011f44ce377944802f39cd65f5a705cd8249ac1ef7ed8fd699349098f3f8e23b37592c80ae","other":"9c30ad8c85adc7bb52ddcfab2e661cc3a854a689eaa59128d35129d02cd5b0f8da4a44cdd33934a8e2c8fab1760c16d6f2e1c5eb227dc819e85624e63343c069","up":true},{"one":"1b063741c76fe65e62b4eae42751319d0cce66f22dde9f1cf83d6cca249a0e65bc7f6f22597697362fadd226222fb3847f8e146961969d1b4c9f7e475389cd8e","other":"ff1e34fd51953ed641b431aa657da21cb4c81d23e4eaa13c9cce526f1f1b34593d41f9b87a0e10387fe400c623638677c0efab15dbd1014a0ccc11f9ec92c417","up":true},{"one":"109556abac422a912ecffec0d8796f8f16e92e8f95cecf72dc89e97a8bf1fd37aad3c66aa3cf134acade6d065c31821f977171d5c5463305b57ce3eee99a7ab4","other":"9db1f94d74a00d1e5e2a391f1bcddf16b6d0670a2c6d91d946d38112c58634444b6fea8e8c05ab4b73bacdd62a0b575f6fb8729978edc216c7842b177b9f9cd9","up":true},{"one":"f33d1f3e460574706ac1c7fc9ebb4683b173496ce3e80017d1c3521bca03d5a41a9c7a6cde8347d2238917b7cc58cab000ce7ccf6bb408561015a2ecbe613408","other":"7aaf7817b93aa6d2f50513791f9ad7629a901ed0dcb151189f44763f83423446b20ec79a48fa260cd9bc2907d5f0ad06b2c4c5e6d812f3d8876c8020ebe41019","up":true},{"one":"0a4eec7b0e05da799aca5b36d9e2530f2a89d1426b1fcb7d8f9a662df8a8b5b763767a20db3c9c63e0bd13c2a6e16d3ba8f03baf84f5e5d24917b3f211d9bcfc","other":"58cfb20d3da3641e0ad529b9edbd4b590a8d1dc9d1ed7b44ed3187dba9260bd7c732fc10981f5b9bffd31d362cb05150173618aa36138984431d94a323a9b313","up":true},{"one":"e0f78c59a61f2a953553cd5742c58f4a82e38e35ac7eaa237a6ffc9fb0a3a26a2d1d1afae249e611d1320f2cb25804bdbdfb6d77336449716b0f4beb3298b8aa","other":"7646d08b3e24183e3814de130235c41eb88a5a2abff23eaff3c91954ad3ef55fe27da422dac5b894312276bf1a2f1aebb8b636a8d4a0c93d9b016d441df3fa19","up":true},{"one":"60725e8d0e9333636e598dd666f459b4be898d9abc095ee2c1db289673e7e969b50e2093956fef5a2f1d23e2040159bbabaaeab17fc6dbbac3f6acab766e9e60","other":"8d4920d6e3a6717699b5a3af068cbdfc16858d7e393d158d41b1b5f345b47129eef89e1d055386c518f400b134678c21590f0317dea3436d4cef60f45455cf12","up":false},{"one":"094f9d0fd3bacb17ac67a2edb8ed394fbbd1c8d478233d3269cf217e7b788e21042374936b885bf23ee4f9e03babbe4e08db283dfc2a6e052a8a5ba133717dd5","other":"9b59b76dc61223c7b37083b0ebdda22d3599563b3e3986f5db9d5b12f8c806cbdeb2345454efe957cbfa11eea9c7896aefd9a461210524805452ca100a9ea431","up":true},{"one":"e023a51c5bd26e1754d6461345143e94baeac799947579ec7adeccd105de39f85afbceeb5037cfc0b820b9f4446433f034d9e7de7326d45df5a967a8099dbb10","other":"f6ca39b3ad803e99f4e4e9cf759fff6abdf06e6972bdbe524f6eb930c669d6f0e9b91f3de9df394b0d661b068273861391bdbac948ad911351c48cf02f874db6","up":true},{"one":"5566111b7f14d8ec83ba6456488f3fc5c7e2c86bf406dead33b814e1ee9b569d34015a4d88226b7e28fff7784395c086d106287cbbc80acfe75b05cd6e12903d","other":"043fe7085e8c90c18270f84dba5fab138e50216a1cf8d81a3794d156fad7fc81d1422aff169b244b13f91d73eebb5de464f97b1b93b3ad2a58959cff19238842","up":true},{"one":"2f360209383d6de4ebd3b4abaf77796520b8654270b03f2151eac4a01b4417d7e0668c1f9ad30c20ff49aa8a0ab33dba5e6095619d1cf04b7af841722ab773da","other":"a127faa19dcb7da585983d36a8e9d3e9a44a6db68507b60c70da71011f44ce377944802f39cd65f5a705cd8249ac1ef7ed8fd699349098f3f8e23b37592c80ae","up":true},{"one":"9b618ad34d0dfe0fccbd5b8af365cbcdbb43e802df5f23e91c20d21f3ead6169d52bf0db7e5e111abef630c9853419fb33a88cf111d8507b8708208b5d65e35e","other":"5e86f39cf8338ba098a85d41e601a303fde311662b216ad32a2b7bfaf2b2b6dd1af3775784b39f2d85ac5fac96f05f3abdd8a2bd28ba16d939725fd6a33ae1b6","up":true},{"one":"84abcbc7b5598ecfd91ceace0927921a5a3404fdb274fc2a2549abbede5f8e4f62c15688a4dc9a2d80262c45970c88898da245c6eb779f327a81d53a17bbc74c","other":"e1ecad3beeb6c19dce551e4a603c7b440b4498c44e298dc67bfaf4ed2c75bbea95df48b1cd1318e2ccb962cbae7c30ff258e73f8c3fc6b7e9ae7a47f7cf8e53c","up":true},{"one":"b26f7c0113a5ae885f7c0e608aea7022a9c8bfc40c5643e60b2ba7343ff09c5be0bc08be34dde3c6b85fea192a46d4764770c12cbaa233df4231a1b99627ef9d","other":"5142eea687de4248b2184e9896b245563117648e7a156255d9a7ae730313d5d383db3be1125b5accd7e743c2a5d8c3289ec559ef7cbb803b9e82cd49bb213d9f","up":true},{"one":"9133b0b3c8f680286eae90c3beebc3099a13de38775a3ff2abdeced62d05eb2ced5ac85eac0870156be03101024da5e1d9fbf3e1066ddb3f088221e64149acec","other":"cb321c9b0fe2eb3617b8e2461aab170a9dad2c9b04a10eead4e37e551197ea0a7500eb1cb7b155efe1886486ef3d252d8ff0d309f2906a1126ca011d037da70a","up":true},{"one":"1090e9d89cb278a30063a5396d9ba795d3bbc237c76915a6fb7d23aa1822c8535d2fccc44cc8cd2acec68444c0bf1bdf5195ebb9f3cad8dac3d94a4d9c0e5309","other":"7e2b0b4f3b55e97bd7241b984ad117af33bf3baacd22b3ed503a8a59f75828df745fb3ce3be4276d83eb484e64d9aa251103fa994ef119eaddb97a3503b9f292","up":true},{"one":"17917fa4da06068b587c17899569dcc768b9cd2c27117a4ed67aab26a7e70cf8d32b881db258061ffd89a332a3b29bfd963d8e171a06c3e208ba0de1c42a2b39","other":"732393b99c490c76fa45e3e404ee095f2fa445fcc123af7ac8ab1d2fdd7cf2483f5b82bb818bd8a82b1a3b73e63bcc2c83d8f24d9aad9afe36503735e7967be7","up":true},{"one":"453779010ed7c59761da47ccd8869d3fa8349795e57edb9eea416c0712301ea622c7683858e309d19ab137ddb0edef161d0d00a361abeecf0628c3ffabc629ea","other":"fde7705f5013c3b6b76a35505c1e3d57c033a337f2a71e912ec3a3d2da8e113bd7c36d94908357e9f7654660621f647ad8c66b0126dfe91dbfa3b8c7bd2183d3","up":true},{"one":"6bf9fb6a25521c16c2ebeb6203d046d7dd40f29cc2ddb067c0222ef56d7012d2ee5d037f71f6668ea56767610b2a54c144aed74b7f68d06993cbd52fa1dc7630","other":"68cc8b9a995eef6170abf88bd5fedca06ffcc8d75f247f6041c13e7dfd292727ebda1ff86b776e33b6634355c55e0f8c22fcdb5f9a6e2f22fe1af7854c3b4273","up":true},{"one":"d4b7c787981abec24353c7d496661692233797e3758189bf909a69fe87935bf6da0940daa4f12e81f20c5e88f70b472113688b71a0ae2f91a73ee0e6ff4c8591","other":"0cacda5560faff9d20e29a0625d3cd340ec075f198a50ab8b79338cee0e0db84c7c7e71042fd8c8f73e507b570de5d26c39473136b575f0167625a1168309ec5","up":true},{"one":"b137cf2291b530a39516d882200848e7f27a2710e0839b4d25b4f367bea6a0c3aaef8c7c7851c00a2945adcd819ea0508610afc1f453b8bc512b7b4d4faacdf3","other":"ff6f94005d1df7677600069764855c1c2aa0543cbe9f480f8feefec76c49d9e2c7bb2d8e38c89e9430f53f8b593d93f143c45985a56a5a32c736128214c95eda","up":true},{"one":"b870935867183bbfb84add16b9f56c02c834b7042fc24ce6bcb2a7f174e6d2239357a00be4272c1ef05c7f9baf5a9f16b53bc18328a9b7aca8540c2916805b57","other":"e087230634f556b818a416b66ba3f1d1dbe3e0dd0698bbb26fa86a2499acd169466f564dc18adf2f9be4d1ada0e86c11549754097601e10aff4f3a57ddffa24a","up":true},{"one":"53df9cce9b0169e58ced53a123d1d8f6e8fdcfb4c2d781ecbb91bb7c8eba36946dd9d21c749259769825d8a6b3faa6bb87c8c6085a522f8a3e376061f59144d9","other":"d9bbcdfd949010e6b2cbf6d0f34b27593ae410bdc1838876aeca35679571fe431d040a5ab085c0a77f111688bebed891da3587277cd794702437cb20d6aa4256","up":true},{"one":"88d5c5fe61ee1e6fa5878e0eaa13bdabaa0ec3d38a5d25b95a467da7627424f25fb5d30535aa0a5ad01c16fe2598dbf570b78cc152a7f4ef66d46fc9ae43592f","other":"e67e495385e7cacfe659b40d1ba94d4b1ff55eada70a4d9740a9e452fbf221672bd0a897b940e2a6bed71e2a16867fe45bf0ea0015435ac6d815690e263b1899","up":true},{"one":"48a5e01e06e297dc1c640ac9601171495bd70fea461c60e7e6e2532695e45fcf68183c2e58b5e6931a6c1c094f5331efbd7f2d93d5f84efdec5a35afa2124438","other":"b35f418c7935cc54278e90978c3ef1521ab91daeaf9f1ebc1cd25211611ade091cac4e1f009d71059279d507322a4536501980ac0dd44caddc52fd4c593879f7","up":false},{"one":"f9ffe87c52ff4c22bd9696af32e0a9d34bb81fb84d9d8bf5aafe2ef9696e7b3d6460bf2a93aecb066133f53416bde841a02d6967bd06e3d4a714f3b2c123a947","other":"9ce6b9decb69d66075993e903a0727ec109a04335634616097c0e60b08f94f764634fa00891b1070f6ea1ce896bc7d11d3aea92a00f281f902d960894cef296f","up":true},{"one":"4314b0b04331973ed29a58843951f144ac3d09bd5d57b6cd9aaff9b73a7b2ec81e344a3e4ece462bd2081b837a06310e787ef3bb889dabad46fe7efd394c8342","other":"855bdf057f4a6b095e2000ada199447b5b4f2f8d78d2ecbaa0ff1fbf761788870ee999266ad3b26efa02be1a46a4d92ac0debb85a2ceab3442394ee7d99e5355","up":true},{"one":"6b4e376e9c94242b6d42688c22aa9ab418cb6dfb1cbca1c69de0feceec8d3af29fb005017aaa6e503cc0c03cf0dc5bcab55e01cd6f64b9efa02ed87c03020003","other":"fd4968df03d767a223bf7e4dbe26b5c27048298df40e81cad50b344fb3e6837965f2646dab7ffb2891a5c507343ed84bb8bbe403287b51dae538d58fcb6e7623","up":true},{"one":"5dc69635f6d573c824ea83b18593a47f9f21a6f91ce18d2bf977c97d21f8d2a8ce88829244d12a07d949bbd52fe8a2035bc89685fe1bdd4ee20d766d75d3deee","other":"f6ca39b3ad803e99f4e4e9cf759fff6abdf06e6972bdbe524f6eb930c669d6f0e9b91f3de9df394b0d661b068273861391bdbac948ad911351c48cf02f874db6","up":true},{"one":"6c143960dbe3ba4c95e8debc1fda5f420a2a673eb46f7ff7d9a30f4cd2067e67ef8926bf17f0c99b16c79b6dc066b52409a11d47117d4fda4211636b1b74f96c","other":"2f1967b4410ea2ea8fbaf46771ba82c2846d00aecdb6f873aceae33ab38f72d0a2c2dc6046d3034f514efd090d42011d48e9ab0cb4e3caa2b49a96ef732215a1","up":true},{"one":"acb4088c27ee2ee130ece3506596432afdb9e9757ec11ebdd35c5a6e87239545c48466913a646980104c8fd7a9a335e177f04efffe9dc952dfd7cd5c1bb9aac6","other":"109556abac422a912ecffec0d8796f8f16e92e8f95cecf72dc89e97a8bf1fd37aad3c66aa3cf134acade6d065c31821f977171d5c5463305b57ce3eee99a7ab4","up":true},{"one":"b3316f4fd7dec218a52331f25d17a2faf0f2a417808d7dbb80038154abfbcd2d78da074837b648cff28675f4aa0d65ddb7d15abf3d7e0391d401e313a3ef24a2","other":"396c703d27bfdddf91761f134cbf665fe61e0b3a5d24036a4105a625f72e8c28b821e9200f20d6e8f8b3ed6b95bda6b8accdd840c2f786720b7431e3af2af981","up":true},{"one":"c73d088ade8756c74832c73542bcdb3e52f670f7a74ad3a7eac2a9e3ece6bd081f782a8e1d3f9a40b9aa9201509110f37fc57fcb10ee1ef3ef07b7eab019782e","other":"e0f78c59a61f2a953553cd5742c58f4a82e38e35ac7eaa237a6ffc9fb0a3a26a2d1d1afae249e611d1320f2cb25804bdbdfb6d77336449716b0f4beb3298b8aa","up":true},{"one":"07c63ca5d0309e30d1ab12e7fc142e6d37904b552639cfa97850161491f28f20d87e0304be29357bcfc2ff52fc52fd0d4f6e6011ebb239cced8b5c8dad7abf45","other":"db8ba71afeaea1f2964e8978a6eceeb9efa3958424424022213c8193443f8d5afd18490afa954c76360c681404809c7cfaf7e4ebd8bd1a42d403f7f1915b0d29","up":true},{"one":"bd1a7c63fca9e1fcc67d7fd62670beefe2bce483cf1dc1233ee85eb90db607917cd9a5d7170b10e80b925a20e2af2c54d286b01805ac34967410859f4f03da09","other":"acb4088c27ee2ee130ece3506596432afdb9e9757ec11ebdd35c5a6e87239545c48466913a646980104c8fd7a9a335e177f04efffe9dc952dfd7cd5c1bb9aac6","up":true},{"one":"57b47f692f4d69a5d2c9c193680eb4ccb5a6c574662df0138504a549f3ea74f20c5b866ac4d9e76c4b49c83f5fd692ead928ea20dfcf643a11a1c1e841c0ec42","other":"4314b0b04331973ed29a58843951f144ac3d09bd5d57b6cd9aaff9b73a7b2ec81e344a3e4ece462bd2081b837a06310e787ef3bb889dabad46fe7efd394c8342","up":true},{"one":"a99852c5bf08ea4713af9cade5343d1259bfb90401aca7fcff18c58cd56a98804dd16c61fea71039c0ac31b9bbbb9dc5aeaf0c2f074d3365e88d17031802d636","other":"84dfd4e4d9f1204893f190eacc4c3999e175c433f70de86e335d27477c097a0552f211a21764f01a708da4c9e9e6552191a61d3e48f41d0e84f01e7ae3beb34e","up":true},{"one":"65e954e60837bda10654480b227fa3bcc6e63356c52079002a27e836cd82ae2934ba77da60080e4b9f2d9324b982b24959bfd9624302e6c330408381054b43e9","other":"7e2b0b4f3b55e97bd7241b984ad117af33bf3baacd22b3ed503a8a59f75828df745fb3ce3be4276d83eb484e64d9aa251103fa994ef119eaddb97a3503b9f292","up":true},{"one":"2b70e5ffcc0bb1c4f8acc09dd1016e67c9c96c92d091ad481efbb71bd8b2a5a5869c6d668617a9b2cbfe91baf5edfe150c3824c84d90899a974099071d171441","other":"0b7e1e5acabcde503ad827e45724402406114a513f81040a379b0f82df2eab4456b348b27936369c49e3c264d971c6a9e2c2217fdbc5e5b93ac6fc219957834d","up":true},{"one":"be514f5f17f3177235acb24112b578edf0e373c469073226e547d18080905fd062d572be18e943f13bf9fcf5871e89ceb630a1b848a0e370ef8ef8c6d997a363","other":"b080891d4ba6d3ab224984360597f9c555bd1367630f5420bfaf230419a05b2be58bebf1554e53eb4c0da81cfb66d4f7697dd65143f11841ff62d8a0d82b6b67","up":true},{"one":"66d0c5da973d9dd65350ae1ec63776872cdb7ded6afb6f51ae82259f6fd35e884375d15de290625f02ed2e5cdc3f591decb45e5fc64d5b0f835a216fd196f5a3","other":"b6a998dea59194cc60ce97c7c9702368411889cb6905516b23f41cc5116fba8d0f237d418318eb0c333cad18003c0e9a6bd8c99080520771f2bad640e2e5ec1c","up":true},{"one":"ce0a09bb6fe4c9c93c3dbd800ca9c9ac0714f26a8f8dac2149b6ce7a9011912a5621ea2e45de35c4d31dfe5add00558fdba5dd21acf2d81ba391e82b5b3a5804","other":"7bbb3f3ed51cf84c077806fbd6d3578e105bc32aa6043da188793f066ad6df383a9f7cc0bd3124f4c887704bd188d480ce264fcdf178905bbda3b270927ea138","up":true},{"one":"2ca05ffc0ad771e1e045a47f1c0a79ce374a25e3c0e53c2a80d67e7479677003f62880251a83a5074f1c9651d828f1ff7e352935a9df141c1eb75a0c59b00a8b","other":"d4b7c787981abec24353c7d496661692233797e3758189bf909a69fe87935bf6da0940daa4f12e81f20c5e88f70b472113688b71a0ae2f91a73ee0e6ff4c8591","up":false},{"one":"72e30d4562673c5c8fb03709d93f73322747858d723b7eb5ef2fbb88e0331252946b7e93ffe434fcb599c4fff57800afb29e6c60a719f18f49dba541c3591c6e","other":"829b074b70d757da6aa00f7bace3cf1b5d2d4eeadb7f370c1a85374a01a70b54ac53d747267e386f3b41e6d790fecdd6e74b8f89745501ee82439a66ea54443a","up":true},{"one":"389b5c1a805f87427e6d647ec5488342a3f7d700615943d5ad98ca5c111f33c7ee007970b4d3e475892095c0d5a79b7ed52d12598398818159000d4b9b719126","other":"a608a746f46d4b2e9267c65283380d6d6cb8885a64428fb77df9934bcf4dd1723587ee7c8f4a642dce266a12a6a4cf4e5c6db7fa1024158425a6753e7ab7264c","up":true},{"one":"54b3c57a4adf4dbaf31b85ed1b8dccd6249faa16dd96dd230189f47f57970caeed36627cc8e1b0794707418d580f5bd6001c07be6a79216695f1253db24926bb","other":"1b6cad4f9851cc584c5d1405f976bb51a52e27ef4525847df543dcca65ca5eb1ef229dcc68ccbaaf00ab1e044cb5990dd213c805bdb4adcceb6fa70b5c61fdb4","up":true},{"one":"7f357b8d81bc2e5c6fcb081f23a42b3e2439f050d45c45851994a268d1c71fcb1f39f8c3f75ce921d3fbf80fc0e73f0b9609d72001dc4a6b65b526d312a4f43a","other":"c8b0dba45104fc7c7dff3ce078a0d3f5ade6198bb4656e2bee8076387929133e5ef2bd293b130a9d4f6a6974ca17e8b4a8f406d1219880f1e0f99c65c63af5a4","up":true},{"one":"27d9048707a89f1a61e44fdae523c0128f2a7050308bd3cfefa6c3e03040a0e22f11ab41275f22b8706e6695ab93320e2af35179d772581db5f49f960750f2f7","other":"3e488a7208ce0e097ce47fc6651a13e95cae137d1a054a09b04d2f59d45faa2594a8c3b395e77ad1a3c2edcd827dda73c0c97dbaa6d9519a79184a0aca01ac4b","up":true},{"one":"663535b22018a4ef0b151572ef286fa66c22c6e9b2913a69c4a735d4b0149bdf6c84bd83d710f8aa2627e8993b7f020750fbc6f56a3365ce4c840e2b3de1a6c1","other":"759f46661056bcbb30c7706c9fb87e22a30feb523bd53ae5d18db043efa45b49a2b8982abebdd598fe0912a05896390ec2eabe5e160cbafc0771990708ad8c28","up":true},{"one":"ea57884dd42aec5a76eab43483bf7c4ae2c19eebf365013731de64494d10a3b4cfe34c86c79437f9012bc8cf6bd761435eefadec17600f4b9e4bc234532d6282","other":"07f25fdeab2b44b2e92fc80fca7de9e4a8547d27a98a54593b3395c270a9ff3f2a5da62a2e8531ce86359f0cdc5b6513b773dfd64cce1b83e47065d9760a2c7e","up":true},{"one":"e1ecad3beeb6c19dce551e4a603c7b440b4498c44e298dc67bfaf4ed2c75bbea95df48b1cd1318e2ccb962cbae7c30ff258e73f8c3fc6b7e9ae7a47f7cf8e53c","other":"beec648d79437a5d7b4140ced45d82d035c6f64f9c67c58386703811d97c3846787eaf274d2298df809475f0b7519df696563cb8e9a5fb0a9cc419ab13fa8d41","up":true},{"one":"9c30ad8c85adc7bb52ddcfab2e661cc3a854a689eaa59128d35129d02cd5b0f8da4a44cdd33934a8e2c8fab1760c16d6f2e1c5eb227dc819e85624e63343c069","other":"b137cf2291b530a39516d882200848e7f27a2710e0839b4d25b4f367bea6a0c3aaef8c7c7851c00a2945adcd819ea0508610afc1f453b8bc512b7b4d4faacdf3","up":true},{"one":"c2705ee7238ef9305e4da196653cde707649435a1e8b5b797d164e5ca06184a77af5bd7fa938c995fdfcbce724fa7eca3d908ee34891ab62cc6dfd411c3fa1da","other":"8dd8ad560af84bec579cadb33d51711aa61b6ed22705010336df5a71a94591173b25e869457429c4a199b205fce8e73530e28203e18b971c2001715e610f152a","up":true},{"one":"76cbf9fc0f3517fb615fa96104780218e85d064ee5a1d518f3b78f4dbebf144df38c427445fdd6c9b436489c00ff9497d747a8fd70f380f95601d59e52e021e8","other":"3b570117addeec03c2694baf28e246f91907268fe665c6c90356120332794258ee57a60853c19e9fe25d042ca42a5be7fe0797d84199174de8132f1ef4a9349b","up":true},{"one":"22010c9829626a6892258b09cb3f3edc3f21382fb487b5dbf0dd20e198e37e26134aab850e30337f398d1491b5126839aeb1953ec144bc19aeb889c832f67c6a","other":"70ee3c7e02a123f78345d41c386e413f06b51f1ab346c2c472891eed7dd26a1f14e213a0f4f2d872859b9b535936a6d9b072d2604456f76221a422710411822f","up":true},{"one":"5eccdbcb15ef42dc96abcbcd8b8db75d9230de10e3c650620737f6cc04ba4fdbf59ded5daa801901c191be186c329ebcd37ba83bcf794064ad4e11bf10d3f775","other":"315b8a1711f680c2eaa607e35ef7a9e19c2b61721af8a7e08f1325dde1fe33cf1f47b3cc4acf12d541631041cf1b42754875fd1c9b66ee32797b72b9f7711256","up":false},{"one":"5bae82d4832092c17bd11474f7748015b8b69b896ab8f683a7c0024fc98740cecbb9e31c6275269f9000e5bfe51d7f45cd5dcd4433e0c87b5741685b40fe3983","other":"9db1f94d74a00d1e5e2a391f1bcddf16b6d0670a2c6d91d946d38112c58634444b6fea8e8c05ab4b73bacdd62a0b575f6fb8729978edc216c7842b177b9f9cd9","up":true},{"one":"6ab6ec15635b2fda22542c99df0a3313ad4583ba0fb3f31b8f314e3ecad446d3fb0fdfcd2be9b08374b1a7e049fb68e69e8dacdd13f1df5007a656f6b11adc5b","other":"baa5924e1547c177011285d292aa161a15e5ff282da2cd0afb83c9caffb07bdbb3662c227fa7b26e6dc8be9b8863e647eb5f8ce81640532f8f5c9a7f36557e63","up":true},{"one":"bf4ff51cc3d9a9d8cefd7e346ce1384d06450228a6086fe12fb0c60fec54bb6478f090bb638fbdbf8f41f7bc6420cd8a5c8b1b8566229b6851167375ef412f46","other":"bcf8e831821a5bca359fb824c7dc4d66906de82f3663a0a853d96880a8ca0bdddcceb1b66dd1f13f75ee20fde50fc9de545bc25767f228baee910e0dbfa8cc27","up":true},{"one":"f6ca39b3ad803e99f4e4e9cf759fff6abdf06e6972bdbe524f6eb930c669d6f0e9b91f3de9df394b0d661b068273861391bdbac948ad911351c48cf02f874db6","other":"aacff366e601e072a2113add9020e19b6612f3e85b6e607fdc8cc1b6991f43be0b1f835ed3dc41d1f2b3e0caf7fac252c8eb4c150667d48207fa92ea5f0a7455","up":true},{"one":"4f5ab12b9c5127c16739ad0d4f51adce90ba6736cd096eb185ea632789f4b26f1ebabdea4fd3b39dda5409ece6c2d92fd469cf4aecf9d29453e3e042c19b893b","other":"92d6ef729992f0de886076e5f8cdc42cbbd70b29e79c25e0b3d22b6575d3d2508d47b42f581e335455483d43625bce4e55f88cab9ff2073ee8dab746357864fd","up":true},{"one":"7aaf7817b93aa6d2f50513791f9ad7629a901ed0dcb151189f44763f83423446b20ec79a48fa260cd9bc2907d5f0ad06b2c4c5e6d812f3d8876c8020ebe41019","other":"5526d86ba9df651091d88460a9bedb9cedb957d452a635e1db46b9fed78082022adec0047cd7485956a4ecbb0e18107595de0de3c35242527cd302bf74a19260","up":true},{"one":"032b9bf2f59f15571821611d3ee541aa748c86d47fbe5f049fd0069be53e5d7c41991d82957e9c727654c3aa73ec94997c03d8a6c1d2007c9bb1a703f6215158","other":"81288bb0584b7ffc1546043e052e1df10fd5371b35dedd0bb42ec5b30ce69b741b2f7857af5984d4754b39d7253575fde9298504999b78380ef602d391c4bb1d","up":true},{"one":"7b5c0e81c7f4e3ae29d745f6028cfa10b29a16a9c261b65fb8dd05d6eccc634612ad5d3029c8e9f39863a2cdb2682c25f090139bf5c4950e25647e39dcb40e63","other":"deb7af800cd20a647335f0feff5bfb3e182f99f4c2d1ade10da36ecfdbac3b5fba4e8f0a4595443fe395b44af3a95617669850944655def85d57cc81c5682a3b","up":true},{"one":"a608a746f46d4b2e9267c65283380d6d6cb8885a64428fb77df9934bcf4dd1723587ee7c8f4a642dce266a12a6a4cf4e5c6db7fa1024158425a6753e7ab7264c","other":"e0f78c59a61f2a953553cd5742c58f4a82e38e35ac7eaa237a6ffc9fb0a3a26a2d1d1afae249e611d1320f2cb25804bdbdfb6d77336449716b0f4beb3298b8aa","up":true},{"one":"ff1e34fd51953ed641b431aa657da21cb4c81d23e4eaa13c9cce526f1f1b34593d41f9b87a0e10387fe400c623638677c0efab15dbd1014a0ccc11f9ec92c417","other":"df4c3505e09e1baa88470117b964e758c94f77a4546489ab5ab7f4aebfdce424729ace8867475715fb68f05c66c9674a5767549e266c4fadd1c703ddd735908f","up":true},{"one":"b35f418c7935cc54278e90978c3ef1521ab91daeaf9f1ebc1cd25211611ade091cac4e1f009d71059279d507322a4536501980ac0dd44caddc52fd4c593879f7","other":"8dd8ad560af84bec579cadb33d51711aa61b6ed22705010336df5a71a94591173b25e869457429c4a199b205fce8e73530e28203e18b971c2001715e610f152a","up":true},{"one":"59b53f8a562bee519276e0eeccfcf8c975d3102f5d0cccf5abcce291a8a5bb817c04604f123686177a50a03b9d7559ac469962d0159d1d93e4ce58a304d04b55","other":"ff6f94005d1df7677600069764855c1c2aa0543cbe9f480f8feefec76c49d9e2c7bb2d8e38c89e9430f53f8b593d93f143c45985a56a5a32c736128214c95eda","up":true},{"one":"9133b0b3c8f680286eae90c3beebc3099a13de38775a3ff2abdeced62d05eb2ced5ac85eac0870156be03101024da5e1d9fbf3e1066ddb3f088221e64149acec","other":"53df9cce9b0169e58ced53a123d1d8f6e8fdcfb4c2d781ecbb91bb7c8eba36946dd9d21c749259769825d8a6b3faa6bb87c8c6085a522f8a3e376061f59144d9","up":true},{"one":"6bf9fb6a25521c16c2ebeb6203d046d7dd40f29cc2ddb067c0222ef56d7012d2ee5d037f71f6668ea56767610b2a54c144aed74b7f68d06993cbd52fa1dc7630","other":"df4c3505e09e1baa88470117b964e758c94f77a4546489ab5ab7f4aebfdce424729ace8867475715fb68f05c66c9674a5767549e266c4fadd1c703ddd735908f","up":true},{"one":"934a5fe1b91c1891ef4df7f67c027e0eb115d4c2ca4a1b76a135ebd4315c4fb835d6625223194e6a134407b38b0d3928fbc7bc924a3c6a538989a6cf200bf4bd","other":"b4fd11306b1416a9bcf4719578976188e104b8c5028b9abd3214d257446b97b70a22e6c00934d80caddde15e8e4d16af03bb399583047983fba373d8313226b7","up":true},{"one":"485825745d97654cbb92a14e0cd1078691d3c28f4d82b1046284b676a42b44ca58eb43474e45e415d3bd3f3c383f9a1a3365821ed7ba6a9f2603b29d58031dc7","other":"acb4088c27ee2ee130ece3506596432afdb9e9757ec11ebdd35c5a6e87239545c48466913a646980104c8fd7a9a335e177f04efffe9dc952dfd7cd5c1bb9aac6","up":true},{"one":"4fe37f2dfb03707c90a6fe91dbcfd7497db70ffc20043091d50e1cee573210c144e8749340f2c3cb70fe8fc51b317d49e8734dc51ce64b3cdccdd639ae35d1ae","other":"f5c1215a84a56d52f92ca0dc3a32df98c98a9c2ea2e9a34560210c16de1b440d20d043c8c25955dda8c22e55e92ddb49fd82e8b9b84072aabaa755a229bb19f4","up":true},{"one":"7174eca109a1f717653918224c8cfe1b7fbd666405196760913593401eb79f2c7e41003b01f5a458940695b27a4673443c7621a169db7fd968994e552995dbbb","other":"617595a230e0a74a3db3b47cd27b941e02bdee9a84cdfa8eaa63a55941eb5caa79e20fb69726a4d46a0e5aeed24039f8c5a20679a692df0bc140f42558ca9a2b","up":true},{"one":"b4fd11306b1416a9bcf4719578976188e104b8c5028b9abd3214d257446b97b70a22e6c00934d80caddde15e8e4d16af03bb399583047983fba373d8313226b7","other":"e087230634f556b818a416b66ba3f1d1dbe3e0dd0698bbb26fa86a2499acd169466f564dc18adf2f9be4d1ada0e86c11549754097601e10aff4f3a57ddffa24a","up":true},{"one":"617595a230e0a74a3db3b47cd27b941e02bdee9a84cdfa8eaa63a55941eb5caa79e20fb69726a4d46a0e5aeed24039f8c5a20679a692df0bc140f42558ca9a2b","other":"7e2b0b4f3b55e97bd7241b984ad117af33bf3baacd22b3ed503a8a59f75828df745fb3ce3be4276d83eb484e64d9aa251103fa994ef119eaddb97a3503b9f292","up":true},{"one":"97981f4b825620985b746c85824d7a4d307ee25d60a72c2b7de4b1d4f3b1c002652adc3045842d350f849789e410a0357a0b42fa637a1b4fc9d39e44f8a674d7","other":"db8ba71afeaea1f2964e8978a6eceeb9efa3958424424022213c8193443f8d5afd18490afa954c76360c681404809c7cfaf7e4ebd8bd1a42d403f7f1915b0d29","up":true},{"one":"b2538d4edfa736bfe2cc21326a44ce62f716b3480eac93584a2233b69c98883a2bb255f246218a58cecab1d0d176e6d1fbba9782fd70d4603e01742299b9ea9c","other":"60725e8d0e9333636e598dd666f459b4be898d9abc095ee2c1db289673e7e969b50e2093956fef5a2f1d23e2040159bbabaaeab17fc6dbbac3f6acab766e9e60","up":true},{"one":"4e68553db7be307b8379e8bec383b5c92e4b23debcefca575d24504e2062618f74c26e60e0d9e47f096997a7f841e2c32c994124f495ef3352ef964b33fd3a51","other":"9b618ad34d0dfe0fccbd5b8af365cbcdbb43e802df5f23e91c20d21f3ead6169d52bf0db7e5e111abef630c9853419fb33a88cf111d8507b8708208b5d65e35e","up":true},{"one":"155e4879643a472420012e040a87dbff776fc1976814c0c6cd0d5e157f0d0baac04aa7f2535786c09acc2700547383d2119b64a6f62115f1aff1708738844d8c","other":"bd1a7c63fca9e1fcc67d7fd62670beefe2bce483cf1dc1233ee85eb90db607917cd9a5d7170b10e80b925a20e2af2c54d286b01805ac34967410859f4f03da09","up":true},{"one":"c903c5ee3d9cd65bea3ea777e39282c33e1349d945411fb2f16321bf582c2f400956a98fbafe5873fc5f6f6a9a051df5da7e94cbd340f935abe80f91e79ef875","other":"caaf695c76cf7c047d3f3bfe019d01618e4871cee8ff3f347913da815bbcde145771486f916a44d03f59ea9bc217f169fd0c0765fda3f9b9b28d02a522e180b4","up":true},{"one":"f54335964d9b4eb9813eb05f40ef1c523bbf0faac5a04c4737467d590fb6b55c7fa1fc5d4d32c5491d8766b9be6fdfd3ebdb25c5ffe1719f36c86ddf87ae3a85","other":"4b784f072b7c96c30612767425f552e30e45157e70139dfbe0ae4ff86dc31601adec60f8a3ad9747b02b5219073d8813af9b09d59eaf7ddb7ee24856aff6fa8f","up":true},{"one":"7e2b0b4f3b55e97bd7241b984ad117af33bf3baacd22b3ed503a8a59f75828df745fb3ce3be4276d83eb484e64d9aa251103fa994ef119eaddb97a3503b9f292","other":"e2a27dcdee1f89fa362a85c4397840cd8be4ad8d1b9ccb23188c303bcab7619f38772f71385922d090390973b62fb8249efc103f71bc761041bcb3880ec0b935","up":true},{"one":"e267e71c2dcdbe5a500b23444d2d4037ea15afba8f4f2b1c0e54a274450404fbee6fa5439f7cddf4ba1aa28fa93e434b01c239add58e30a5423ca3a481584d6b","other":"979838eaefcff456cf1cd9c47ea46854704f5757d8d7ab907019bc422b01af4d62252579bf045d143fab491b0bab823190e2782a457fbf51aa99ae17ec9e145f","up":true},{"one":"8ca3b63cb84f1e9883d82809a9b6777ec1029ecda96fe93b4d494ee9cbefcad13f381b3e480136e542e01054fe1ede66c65db84a0009871ce49383db461c8438","other":"2ca05ffc0ad771e1e045a47f1c0a79ce374a25e3c0e53c2a80d67e7479677003f62880251a83a5074f1c9651d828f1ff7e352935a9df141c1eb75a0c59b00a8b","up":false},{"one":"27d9048707a89f1a61e44fdae523c0128f2a7050308bd3cfefa6c3e03040a0e22f11ab41275f22b8706e6695ab93320e2af35179d772581db5f49f960750f2f7","other":"0f9f7e2dce4ca266c3ac0ec3a8854200b54487f5308e3db418461aeb5f67c81d332619b6441b468e480941e63100ed1b263e7adc20689dc3dcda578bfca538fa","up":true},{"one":"663535b22018a4ef0b151572ef286fa66c22c6e9b2913a69c4a735d4b0149bdf6c84bd83d710f8aa2627e8993b7f020750fbc6f56a3365ce4c840e2b3de1a6c1","other":"baa5924e1547c177011285d292aa161a15e5ff282da2cd0afb83c9caffb07bdbb3662c227fa7b26e6dc8be9b8863e647eb5f8ce81640532f8f5c9a7f36557e63","up":true},{"one":"e98a08e8e3544727f5ee27f4465375a67ffba490fcdbfe7bfdc909f6b68bd279f776c65d38c2ccfc33079f852f76349c94d68fc6989c0d981f22333f036a4bb5","other":"979838eaefcff456cf1cd9c47ea46854704f5757d8d7ab907019bc422b01af4d62252579bf045d143fab491b0bab823190e2782a457fbf51aa99ae17ec9e145f","up":true},{"one":"5df58ba12334a1b4f983d642fe435901261767cd81f8f37c43e359f5584664e4d287e8c2275995604a3b3a4823418e35cd899a3db2a7db31570e19512f375481","other":"1944f98d4db32c56a5efda5a79aa5f276bfab1e084d6611fec0e735b8bc0f45b457cdb74a23fc83b2377821fa8316123c9877acd6db7c41058ca5d3cfedaecf9","up":true},{"one":"5e86f39cf8338ba098a85d41e601a303fde311662b216ad32a2b7bfaf2b2b6dd1af3775784b39f2d85ac5fac96f05f3abdd8a2bd28ba16d939725fd6a33ae1b6","other":"7ac5b07eb555af3bb4ca3f0f4b45204d43cc3798c244435909b97d9a32fc3abf0b50666e260e046bce826a7a102a92d389f8f39c5311e83bb34beddac29d50e3","up":true},{"one":"e67e495385e7cacfe659b40d1ba94d4b1ff55eada70a4d9740a9e452fbf221672bd0a897b940e2a6bed71e2a16867fe45bf0ea0015435ac6d815690e263b1899","other":"48a5e01e06e297dc1c640ac9601171495bd70fea461c60e7e6e2532695e45fcf68183c2e58b5e6931a6c1c094f5331efbd7f2d93d5f84efdec5a35afa2124438","up":true},{"one":"df54af3bae257d437c5657905484e0d72e9560c46f8ba6b3437730234e05259b404cca40b0831e911605ff8a68a19e8fd7e958069ec8b40595928892f4fa220c","other":"6b4e376e9c94242b6d42688c22aa9ab418cb6dfb1cbca1c69de0feceec8d3af29fb005017aaa6e503cc0c03cf0dc5bcab55e01cd6f64b9efa02ed87c03020003","up":true},{"one":"5420da16f7ed5de6b498dbc9a83b7e92e1f9900a6d04ef7351a0bfdfd442b98a5634f28fcea32ba3f3166d21c8ff5a39be70895b32acbdf7592d1d616a345a21","other":"cb310c0e86aa455d7c9af6394ae38561c901da30a51d7ccb7e66a09d9a8f192ae8caeff106043426d56397088f141c4e01e3b98f1ee583ffc7318b5f730f3ac7","up":true},{"one":"e2e0419a41bdfc5bd76deae2ddce6ac865f886d764c9bd18799b79fa3b2b6ba66d765d26da2037e98317e1d7e8232a61e63c1d0cfa98c9137424151b46e07171","other":"016f8f4619a16a07fbde5a18e362158d696e4d9f104a77787f26e32a25cd7d278256f8e0db865c488a99511ec27a5eddd5ebbd1c1397fa7f8db111062e5fe959","up":true},{"one":"7b1e20217f594f87350542df31ff5ae8a635679bac7962d49c97e02190c644b673d03e7eba2626b45ca7ebf98d8a972dadbba02c18a8d2cbfc3e7a4cced5b4b7","other":"6b4e376e9c94242b6d42688c22aa9ab418cb6dfb1cbca1c69de0feceec8d3af29fb005017aaa6e503cc0c03cf0dc5bcab55e01cd6f64b9efa02ed87c03020003","up":true},{"one":"6b01079463ec2f649db8634cb7a596261c79a8f714d954c772528e0547b017f8ce405e4a0ea9d32270848180e0f77b8c0b022cf95c85e777626edd4d24ea21d2","other":"88d5c5fe61ee1e6fa5878e0eaa13bdabaa0ec3d38a5d25b95a467da7627424f25fb5d30535aa0a5ad01c16fe2598dbf570b78cc152a7f4ef66d46fc9ae43592f","up":true},{"one":"0cacda5560faff9d20e29a0625d3cd340ec075f198a50ab8b79338cee0e0db84c7c7e71042fd8c8f73e507b570de5d26c39473136b575f0167625a1168309ec5","other":"aacff366e601e072a2113add9020e19b6612f3e85b6e607fdc8cc1b6991f43be0b1f835ed3dc41d1f2b3e0caf7fac252c8eb4c150667d48207fa92ea5f0a7455","up":true},{"one":"657d5370319128d24d925b41065eb619409d63ec6280975d78877a4028287463f6442f5206dd703569a05b2b542ad8bbb99803da265408208d6356a26d283d08","other":"df4c3505e09e1baa88470117b964e758c94f77a4546489ab5ab7f4aebfdce424729ace8867475715fb68f05c66c9674a5767549e266c4fadd1c703ddd735908f","up":true},{"one":"0a4eec7b0e05da799aca5b36d9e2530f2a89d1426b1fcb7d8f9a662df8a8b5b763767a20db3c9c63e0bd13c2a6e16d3ba8f03baf84f5e5d24917b3f211d9bcfc","other":"74d84cfdaf32cd4cc67771f29878f1365120bd65cc14848008d5386a81f495bf88eb4132fa38a2cc109ae1e7f02c9b97597ab9d1a9c19c945e710ab9df07cdcd","up":true},{"one":"a78f18691e0dbf3c08fe9d7dec188e6a05a93833432fb99eb2b3924ab0bde7a44db2a102a65544bbdc4fb61bc3a3d569230d9843a335bf619167fb045d78ab3c","other":"8dd8ad560af84bec579cadb33d51711aa61b6ed22705010336df5a71a94591173b25e869457429c4a199b205fce8e73530e28203e18b971c2001715e610f152a","up":true},{"one":"2f903b2fd4f9432b7d91b5c3e4c7ee3cb9c56fe7efc4baff0edd06fc75e4b7492f2c3c929755746df59c9f95d437a12ba40ac138d08f5bc7aa091f49f3b852c2","other":"a127faa19dcb7da585983d36a8e9d3e9a44a6db68507b60c70da71011f44ce377944802f39cd65f5a705cd8249ac1ef7ed8fd699349098f3f8e23b37592c80ae","up":true},{"one":"abd8f5a4d700c06ec00684b23d2d25c4df1a9554fcfc57b0ddc3fa476e6a699ba75e1213449f900803f83ab8194c6746664b547202047f35b8b3e216c7147bf8","other":"9e621c3eb534855ca292efa27a3fbc89b4f05c80a4bc65bcff2f14ff28ef43cbe14137d2fddc6fe2658bb06947d918476b479dde71469b8680e5d8a7a01619b5","up":true},{"one":"e06a789a7f6988e1ba5e8358b6cd4292555c7f9f7f0dda6fc01cc26d24e49a8c1ad694423ad74aec6d80f4b99e2bedc49b6a5f2670744cedee3a3e1848e6dd07","other":"62666b24d1026345349edb6a878cdc27d6fee8254e83f79a298ce2805260d97aa46423deae440f86ced5cd99b30e970c8e1ea1046752b17d8c80dc68d9a49b60","up":false},{"one":"92d6ef729992f0de886076e5f8cdc42cbbd70b29e79c25e0b3d22b6575d3d2508d47b42f581e335455483d43625bce4e55f88cab9ff2073ee8dab746357864fd","other":"a99852c5bf08ea4713af9cade5343d1259bfb90401aca7fcff18c58cd56a98804dd16c61fea71039c0ac31b9bbbb9dc5aeaf0c2f074d3365e88d17031802d636","up":true},{"one":"7aaf7817b93aa6d2f50513791f9ad7629a901ed0dcb151189f44763f83423446b20ec79a48fa260cd9bc2907d5f0ad06b2c4c5e6d812f3d8876c8020ebe41019","other":"0c14dd51a56130c51009e3ce47c96b2afef26b7e86cfca65d8a9bae1abef13b3a7a192b422d894c39e24ab00be412d166a3571cc259ff4462d4ad8925a153766","up":true},{"one":"460531928a4b084686343c8464b37c3452bb3566045698d08a4692864de5581a9eb1dc632329e7d3ccb73ec31ee7693787d69df8458efaba9a7105d87ee2e053","other":"f54335964d9b4eb9813eb05f40ef1c523bbf0faac5a04c4737467d590fb6b55c7fa1fc5d4d32c5491d8766b9be6fdfd3ebdb25c5ffe1719f36c86ddf87ae3a85","up":true},{"one":"9b618ad34d0dfe0fccbd5b8af365cbcdbb43e802df5f23e91c20d21f3ead6169d52bf0db7e5e111abef630c9853419fb33a88cf111d8507b8708208b5d65e35e","other":"032b9bf2f59f15571821611d3ee541aa748c86d47fbe5f049fd0069be53e5d7c41991d82957e9c727654c3aa73ec94997c03d8a6c1d2007c9bb1a703f6215158","up":true},{"one":"a1560ce7c1f1d5972f027a8e9cff820611d84764aa067434a75b63887bc4268a259101486d34b7fe83dd735e799789986cd3e9b156c86ede598bd86af4454924","other":"62666b24d1026345349edb6a878cdc27d6fee8254e83f79a298ce2805260d97aa46423deae440f86ced5cd99b30e970c8e1ea1046752b17d8c80dc68d9a49b60","up":false},{"one":"fd4968df03d767a223bf7e4dbe26b5c27048298df40e81cad50b344fb3e6837965f2646dab7ffb2891a5c507343ed84bb8bbe403287b51dae538d58fcb6e7623","other":"9bd4f0adb9a966cc5ba632f1b540fe9cd6c8e39fe1a041b315697679cfb04b735952062ce057d456677cc34a84301f26bb727a4ab2646fee734f80a22c620746","up":true},{"one":"cb310c0e86aa455d7c9af6394ae38561c901da30a51d7ccb7e66a09d9a8f192ae8caeff106043426d56397088f141c4e01e3b98f1ee583ffc7318b5f730f3ac7","other":"4e95fb8943ef6502fa470870a7ace4ca11e18589bd2073167543a922317b35e40b5068934d07e56c8fdd23354dfad51fd2899db854f189841f02b5914cd97749","up":true},{"one":"ba21a373781966135d6225adae024a3f3e421b852f72f8b0569cb92fcff87c33f7e5b799a509b8eff6ec6dc46a9b17d5bae1e91ec7c54c0c712d893d54b140fa","other":"a99852c5bf08ea4713af9cade5343d1259bfb90401aca7fcff18c58cd56a98804dd16c61fea71039c0ac31b9bbbb9dc5aeaf0c2f074d3365e88d17031802d636","up":true},{"one":"5dc69635f6d573c824ea83b18593a47f9f21a6f91ce18d2bf977c97d21f8d2a8ce88829244d12a07d949bbd52fe8a2035bc89685fe1bdd4ee20d766d75d3deee","other":"0cacda5560faff9d20e29a0625d3cd340ec075f198a50ab8b79338cee0e0db84c7c7e71042fd8c8f73e507b570de5d26c39473136b575f0167625a1168309ec5","up":true},{"one":"7bbb3f3ed51cf84c077806fbd6d3578e105bc32aa6043da188793f066ad6df383a9f7cc0bd3124f4c887704bd188d480ce264fcdf178905bbda3b270927ea138","other":"f5c1215a84a56d52f92ca0dc3a32df98c98a9c2ea2e9a34560210c16de1b440d20d043c8c25955dda8c22e55e92ddb49fd82e8b9b84072aabaa755a229bb19f4","up":true},{"one":"7865b82e44add2cea6ebcbaba9c152184331a2940fe73f6f9bb940bda8a59ab4cf4760894b9cadcaa54e36fbb712ad619346a49a85e32cdf2b53cda1ac1e0658","other":"f9ffe87c52ff4c22bd9696af32e0a9d34bb81fb84d9d8bf5aafe2ef9696e7b3d6460bf2a93aecb066133f53416bde841a02d6967bd06e3d4a714f3b2c123a947","up":true},{"one":"292c78c8e41606e98428096bc6f4609a7aa48e5c4d17eecc64d65faae4a7270b0c15f0cd74274015688ea0a9aff34f215c29118222e362a29c8d637963973a55","other":"f9ffe87c52ff4c22bd9696af32e0a9d34bb81fb84d9d8bf5aafe2ef9696e7b3d6460bf2a93aecb066133f53416bde841a02d6967bd06e3d4a714f3b2c123a947","up":true},{"one":"9db1f94d74a00d1e5e2a391f1bcddf16b6d0670a2c6d91d946d38112c58634444b6fea8e8c05ab4b73bacdd62a0b575f6fb8729978edc216c7842b177b9f9cd9","other":"f9ffe87c52ff4c22bd9696af32e0a9d34bb81fb84d9d8bf5aafe2ef9696e7b3d6460bf2a93aecb066133f53416bde841a02d6967bd06e3d4a714f3b2c123a947","up":true},{"one":"759f46661056bcbb30c7706c9fb87e22a30feb523bd53ae5d18db043efa45b49a2b8982abebdd598fe0912a05896390ec2eabe5e160cbafc0771990708ad8c28","other":"5bae82d4832092c17bd11474f7748015b8b69b896ab8f683a7c0024fc98740cecbb9e31c6275269f9000e5bfe51d7f45cd5dcd4433e0c87b5741685b40fe3983","up":true},{"one":"7174eca109a1f717653918224c8cfe1b7fbd666405196760913593401eb79f2c7e41003b01f5a458940695b27a4673443c7621a169db7fd968994e552995dbbb","other":"24662a43944228e4ff74736bcf0a0a4f79c87ecfdb739225b2fc45110c11bfc38aaf2d09d98e5817477848e553f187ac5408bdb864518dfa7f5df542768828db","up":true},{"one":"2ca05ffc0ad771e1e045a47f1c0a79ce374a25e3c0e53c2a80d67e7479677003f62880251a83a5074f1c9651d828f1ff7e352935a9df141c1eb75a0c59b00a8b","other":"4fe37f2dfb03707c90a6fe91dbcfd7497db70ffc20043091d50e1cee573210c144e8749340f2c3cb70fe8fc51b317d49e8734dc51ce64b3cdccdd639ae35d1ae","up":true},{"one":"b080891d4ba6d3ab224984360597f9c555bd1367630f5420bfaf230419a05b2be58bebf1554e53eb4c0da81cfb66d4f7697dd65143f11841ff62d8a0d82b6b67","other":"f039df8a3206e6e17eee8e95010038c450cb4cc0b5580ed5795d4c21802e1e9d360f4528bdca794f457932b1d6a818862ec847357a861c488332ef6d9480daa6","up":true},{"one":"db8ba71afeaea1f2964e8978a6eceeb9efa3958424424022213c8193443f8d5afd18490afa954c76360c681404809c7cfaf7e4ebd8bd1a42d403f7f1915b0d29","other":"3dfd733dde9414af916625ab981777ff1ad7ca0f6d1e4e7d9e2739969e21182fd13d85e281868653e7325b20069356b11524b54143c47fd3955a911cf7325ad4","up":true},{"one":"2e409baefbd821485a151993356730e5989810d581e68190fbaa142799c9335bcf98310ad188fed10ae6eb6e2e789730393e509962ec5c0fef0342d72ed088d9","other":"cb321c9b0fe2eb3617b8e2461aab170a9dad2c9b04a10eead4e37e551197ea0a7500eb1cb7b155efe1886486ef3d252d8ff0d309f2906a1126ca011d037da70a","up":true},{"one":"b35f418c7935cc54278e90978c3ef1521ab91daeaf9f1ebc1cd25211611ade091cac4e1f009d71059279d507322a4536501980ac0dd44caddc52fd4c593879f7","other":"ce0a09bb6fe4c9c93c3dbd800ca9c9ac0714f26a8f8dac2149b6ce7a9011912a5621ea2e45de35c4d31dfe5add00558fdba5dd21acf2d81ba391e82b5b3a5804","up":true},{"one":"0deda014fa3c0bc8f37d853e1448f95f56f97048c28797d72258fd3ba2f1f776ae11566197466596356cd172847ab02a89f4cf047e58383249fb2a4cd69b6206","other":"b26f7c0113a5ae885f7c0e608aea7022a9c8bfc40c5643e60b2ba7343ff09c5be0bc08be34dde3c6b85fea192a46d4764770c12cbaa233df4231a1b99627ef9d","up":true},{"one":"9b59b76dc61223c7b37083b0ebdda22d3599563b3e3986f5db9d5b12f8c806cbdeb2345454efe957cbfa11eea9c7896aefd9a461210524805452ca100a9ea431","other":"9b618ad34d0dfe0fccbd5b8af365cbcdbb43e802df5f23e91c20d21f3ead6169d52bf0db7e5e111abef630c9853419fb33a88cf111d8507b8708208b5d65e35e","up":true},{"one":"ed6c793eb4565aa9d883a76fad6c97ad0b878b9ef0235e11e89db1af25a9653205f725c6ea258b84bde134f1a6437c6d109b859d17509e5016c4ab98be59032a","other":"48a5e01e06e297dc1c640ac9601171495bd70fea461c60e7e6e2532695e45fcf68183c2e58b5e6931a6c1c094f5331efbd7f2d93d5f84efdec5a35afa2124438","up":true},{"one":"84dfd4e4d9f1204893f190eacc4c3999e175c433f70de86e335d27477c097a0552f211a21764f01a708da4c9e9e6552191a61d3e48f41d0e84f01e7ae3beb34e","other":"9bbbfac8be4a000f51a4ce8d024d2595b5d491afec0138922dddfde5ef62c664040c2e9304cc6b7bc688233b5d0c4644b8c8793227c078285a3ab894ef0497a3","up":true},{"one":"1bc1d6155ba35d29ea16938994e08df76ebd8f16bd180bd6a9b9d8798d0745889fe72d641dd78bd8ec13526929f7eb5aaa6a388430fa69033d6db581e53c6422","other":"adfba6d883cacbb141cd8c59ee04d7e5d520f1ce31a81e5db2d8b2380bf801c1fe4b265a66b71f9643d13a41cb1f6fb4b83399be786da4b6e171b6784bc56e49","up":true},{"one":"ea57884dd42aec5a76eab43483bf7c4ae2c19eebf365013731de64494d10a3b4cfe34c86c79437f9012bc8cf6bd761435eefadec17600f4b9e4bc234532d6282","other":"57fb1bb32bb2b1a87e44c6a7557e9c47c2032d107bcb0e34acd9ffd54d5d3df5701232db16f62f7549ba2721021898b03160b1dc5201e79606648c1dbc4a373b","up":true},{"one":"c73d088ade8756c74832c73542bcdb3e52f670f7a74ad3a7eac2a9e3ece6bd081f782a8e1d3f9a40b9aa9201509110f37fc57fcb10ee1ef3ef07b7eab019782e","other":"302c37f28c69fdcf00b39ce0c0223de0d94cebc2c0b068315b95b76b5432573ead0656569441029ba9054d8d3d959fd8735e73913af5ce3f1132f8271fd437ef","up":true},{"one":"fe8ac5d33cd8ab6a1dad9567cdfb89b431a5c4f4a584fc608b92e7dfd06f70988e71e2f11f9fda9ee797c9ffba83bc085939fdf2522dde39f28202be92650566","other":"ae2a996d3b562cb47a564934037949da83b1bfe194c23754f3dbe2372ec27654f4f3b6cb7f394570f308025589c065870477667e5560dbe5a8ea1625740699cf","up":true},{"one":"e087230634f556b818a416b66ba3f1d1dbe3e0dd0698bbb26fa86a2499acd169466f564dc18adf2f9be4d1ada0e86c11549754097601e10aff4f3a57ddffa24a","other":"a1560ce7c1f1d5972f027a8e9cff820611d84764aa067434a75b63887bc4268a259101486d34b7fe83dd735e799789986cd3e9b156c86ede598bd86af4454924","up":true},{"one":"2a63d875e715c2a43302d32d86d30c7d7faed46c08a67bf488762637216b99dd87333a66df6d9f3a57df863b1f1a219ddbeebb9f3e92e523bd08540a195448ca","other":"460531928a4b084686343c8464b37c3452bb3566045698d08a4692864de5581a9eb1dc632329e7d3ccb73ec31ee7693787d69df8458efaba9a7105d87ee2e053","up":true},{"one":"0b30b36e155db04c448b662c4df695068b2331cdbe2772aae5fda84159e977515a5ff2e156bc225a9281fef2383926ba8cb11e9c1846fb40db241e524ac14e29","other":"4b784f072b7c96c30612767425f552e30e45157e70139dfbe0ae4ff86dc31601adec60f8a3ad9747b02b5219073d8813af9b09d59eaf7ddb7ee24856aff6fa8f","up":true},{"one":"4ee37acec2178ef120166265aaa2b64b09b315fb53861405ef46f2503c273eb9692e9cb4c2e67a8652254d430fd6e02dd3fe4cded20bb231a9fb834d292b0b24","other":"ca1aff0d847c6fdacb623ad9078a0885b3208614fea20d5ff11779779b486bf5e9c794aacf848d3c2d58cfcc1eda8356df82f5fbdd0a5236beffe8e6042848c4","up":true},{"one":"732393b99c490c76fa45e3e404ee095f2fa445fcc123af7ac8ab1d2fdd7cf2483f5b82bb818bd8a82b1a3b73e63bcc2c83d8f24d9aad9afe36503735e7967be7","other":"292c78c8e41606e98428096bc6f4609a7aa48e5c4d17eecc64d65faae4a7270b0c15f0cd74274015688ea0a9aff34f215c29118222e362a29c8d637963973a55","up":false},{"one":"109556abac422a912ecffec0d8796f8f16e92e8f95cecf72dc89e97a8bf1fd37aad3c66aa3cf134acade6d065c31821f977171d5c5463305b57ce3eee99a7ab4","other":"c57ea182bdb42ba9b0870b5c870e467f52693e5c0df752fb6eb0dfbacce7763f73caee10db40f4fd90f19f504ee586eaf9da41f5ee93ee515d885fec99374116","up":true},{"one":"1b063741c76fe65e62b4eae42751319d0cce66f22dde9f1cf83d6cca249a0e65bc7f6f22597697362fadd226222fb3847f8e146961969d1b4c9f7e475389cd8e","other":"d4b7c787981abec24353c7d496661692233797e3758189bf909a69fe87935bf6da0940daa4f12e81f20c5e88f70b472113688b71a0ae2f91a73ee0e6ff4c8591","up":true},{"one":"f33d1f3e460574706ac1c7fc9ebb4683b173496ce3e80017d1c3521bca03d5a41a9c7a6cde8347d2238917b7cc58cab000ce7ccf6bb408561015a2ecbe613408","other":"df4c3505e09e1baa88470117b964e758c94f77a4546489ab5ab7f4aebfdce424729ace8867475715fb68f05c66c9674a5767549e266c4fadd1c703ddd735908f","up":true},{"one":"155e4879643a472420012e040a87dbff776fc1976814c0c6cd0d5e157f0d0baac04aa7f2535786c09acc2700547383d2119b64a6f62115f1aff1708738844d8c","other":"920a301186bdf665a721676ece7c180413369ea6eff7537f42049d9eb409f28cc864099590116e885f57368959fb2cff7003697d9b1515e68bf3fa7aee0278ef","up":true},{"one":"2f903b2fd4f9432b7d91b5c3e4c7ee3cb9c56fe7efc4baff0edd06fc75e4b7492f2c3c929755746df59c9f95d437a12ba40ac138d08f5bc7aa091f49f3b852c2","other":"c2705ee7238ef9305e4da196653cde707649435a1e8b5b797d164e5ca06184a77af5bd7fa938c995fdfcbce724fa7eca3d908ee34891ab62cc6dfd411c3fa1da","up":true},{"one":"4e68553db7be307b8379e8bec383b5c92e4b23debcefca575d24504e2062618f74c26e60e0d9e47f096997a7f841e2c32c994124f495ef3352ef964b33fd3a51","other":"57cd4c0048b459192ee46e19ec7df777e600f256e0dc8c3019431eb7bec3c020b9504ec7aea3dba8188658ca5b830ec40af6a8540ce10e04badc6c695d009271","up":true},{"one":"302c37f28c69fdcf00b39ce0c0223de0d94cebc2c0b068315b95b76b5432573ead0656569441029ba9054d8d3d959fd8735e73913af5ce3f1132f8271fd437ef","other":"c9cd9dfb9f90a7948ac5a42c7bd63263f2eef6e1d85547559f7d2ecbf5f9cd1eab051b8e9e661b573c275d84091a44e73f6fc6bcc91dcdb674bd5d939190fc01","up":true},{"one":"beec648d79437a5d7b4140ced45d82d035c6f64f9c67c58386703811d97c3846787eaf274d2298df809475f0b7519df696563cb8e9a5fb0a9cc419ab13fa8d41","other":"eaca77d20c4ad6b87649eba21b750a4b1a2c575e06bc42679d18fce16fea15212e9a7408c16f3b24d8dfd1e397314637e72e292845d09534a39035bd9203ee9e","up":false},{"one":"7554993f6efd8d9016ff525ae73c41ee2e0dbd4970c563ba9b61a99c1c8943b433c4b7d48450f6e0fbc9ac198d907698093de20e6c1f7755520fb1e1cbee4eb4","other":"b6a998dea59194cc60ce97c7c9702368411889cb6905516b23f41cc5116fba8d0f237d418318eb0c333cad18003c0e9a6bd8c99080520771f2bad640e2e5ec1c","up":true},{"one":"3dfd733dde9414af916625ab981777ff1ad7ca0f6d1e4e7d9e2739969e21182fd13d85e281868653e7325b20069356b11524b54143c47fd3955a911cf7325ad4","other":"807340e5fdf6c21a56ef2fd158c32e92201206ca85fcc147165a408f7a735964afd47c397e663610ac53870ae722c0317291732b0422f8aeedae783d9c730218","up":true},{"one":"5142eea687de4248b2184e9896b245563117648e7a156255d9a7ae730313d5d383db3be1125b5accd7e743c2a5d8c3289ec559ef7cbb803b9e82cd49bb213d9f","other":"f38a9d792173a29c61389f5d84c005d78eac6e750659aad42e2d6df883f04eb3126b2c38fac95076eeed455b2031aaf694143922aa93a2d50412a2454dc56e28","up":true},{"one":"cb94a8270d0050378116b5815ff17dafbe20f5303839c4fd57b981d4687a4b145e4bccec7e9af9b9475005930148ffbfa97781a0762c8e9f352dc95565fc8732","other":"1b063741c76fe65e62b4eae42751319d0cce66f22dde9f1cf83d6cca249a0e65bc7f6f22597697362fadd226222fb3847f8e146961969d1b4c9f7e475389cd8e","up":true},{"one":"deb7af800cd20a647335f0feff5bfb3e182f99f4c2d1ade10da36ecfdbac3b5fba4e8f0a4595443fe395b44af3a95617669850944655def85d57cc81c5682a3b","other":"bd1a7c63fca9e1fcc67d7fd62670beefe2bce483cf1dc1233ee85eb90db607917cd9a5d7170b10e80b925a20e2af2c54d286b01805ac34967410859f4f03da09","up":true},{"one":"0c14dd51a56130c51009e3ce47c96b2afef26b7e86cfca65d8a9bae1abef13b3a7a192b422d894c39e24ab00be412d166a3571cc259ff4462d4ad8925a153766","other":"0cacda5560faff9d20e29a0625d3cd340ec075f198a50ab8b79338cee0e0db84c7c7e71042fd8c8f73e507b570de5d26c39473136b575f0167625a1168309ec5","up":true},{"one":"b26f7c0113a5ae885f7c0e608aea7022a9c8bfc40c5643e60b2ba7343ff09c5be0bc08be34dde3c6b85fea192a46d4764770c12cbaa233df4231a1b99627ef9d","other":"cb310c0e86aa455d7c9af6394ae38561c901da30a51d7ccb7e66a09d9a8f192ae8caeff106043426d56397088f141c4e01e3b98f1ee583ffc7318b5f730f3ac7","up":true},{"one":"329145e75496cecb5f5c8f00313a52ddd8c0e8cd27ef1b2bc1b2b56e4d4089aaf5a7a3c4d9a40bdb92483fa05bd24d1cd0fd51883e30439dffa0fc855e1a7cd0","other":"e267e71c2dcdbe5a500b23444d2d4037ea15afba8f4f2b1c0e54a274450404fbee6fa5439f7cddf4ba1aa28fa93e434b01c239add58e30a5423ca3a481584d6b","up":true},{"one":"b6a998dea59194cc60ce97c7c9702368411889cb6905516b23f41cc5116fba8d0f237d418318eb0c333cad18003c0e9a6bd8c99080520771f2bad640e2e5ec1c","other":"2f360209383d6de4ebd3b4abaf77796520b8654270b03f2151eac4a01b4417d7e0668c1f9ad30c20ff49aa8a0ab33dba5e6095619d1cf04b7af841722ab773da","up":true},{"one":"1090e9d89cb278a30063a5396d9ba795d3bbc237c76915a6fb7d23aa1822c8535d2fccc44cc8cd2acec68444c0bf1bdf5195ebb9f3cad8dac3d94a4d9c0e5309","other":"e2a27dcdee1f89fa362a85c4397840cd8be4ad8d1b9ccb23188c303bcab7619f38772f71385922d090390973b62fb8249efc103f71bc761041bcb3880ec0b935","up":true},{"one":"17917fa4da06068b587c17899569dcc768b9cd2c27117a4ed67aab26a7e70cf8d32b881db258061ffd89a332a3b29bfd963d8e171a06c3e208ba0de1c42a2b39","other":"eab86c521f8f1ac67c015ab713f1236a08b0200757a96bf87ab8301e7967ae62361f0e14da14ca294fc8cb3b4726b52f4773101e21b032977c6a647241b59c73","up":true},{"one":"453779010ed7c59761da47ccd8869d3fa8349795e57edb9eea416c0712301ea622c7683858e309d19ab137ddb0edef161d0d00a361abeecf0628c3ffabc629ea","other":"829b074b70d757da6aa00f7bace3cf1b5d2d4eeadb7f370c1a85374a01a70b54ac53d747267e386f3b41e6d790fecdd6e74b8f89745501ee82439a66ea54443a","up":true},{"one":"b137cf2291b530a39516d882200848e7f27a2710e0839b4d25b4f367bea6a0c3aaef8c7c7851c00a2945adcd819ea0508610afc1f453b8bc512b7b4d4faacdf3","other":"65e954e60837bda10654480b227fa3bcc6e63356c52079002a27e836cd82ae2934ba77da60080e4b9f2d9324b982b24959bfd9624302e6c330408381054b43e9","up":true},{"one":"88d5c5fe61ee1e6fa5878e0eaa13bdabaa0ec3d38a5d25b95a467da7627424f25fb5d30535aa0a5ad01c16fe2598dbf570b78cc152a7f4ef66d46fc9ae43592f","other":"c8b0dba45104fc7c7dff3ce078a0d3f5ade6198bb4656e2bee8076387929133e5ef2bd293b130a9d4f6a6974ca17e8b4a8f406d1219880f1e0f99c65c63af5a4","up":true},{"one":"48a5e01e06e297dc1c640ac9601171495bd70fea461c60e7e6e2532695e45fcf68183c2e58b5e6931a6c1c094f5331efbd7f2d93d5f84efdec5a35afa2124438","other":"c8b0dba45104fc7c7dff3ce078a0d3f5ade6198bb4656e2bee8076387929133e5ef2bd293b130a9d4f6a6974ca17e8b4a8f406d1219880f1e0f99c65c63af5a4","up":true},{"one":"f9ffe87c52ff4c22bd9696af32e0a9d34bb81fb84d9d8bf5aafe2ef9696e7b3d6460bf2a93aecb066133f53416bde841a02d6967bd06e3d4a714f3b2c123a947","other":"3612863ce0456c91785a829bf5c9d2b2fb97dda083a1847e5a4ebaa6fce1260faf4d1eb374c2225431a82774163835fb59c8cb0fa9fc0969eab5410c71109cc2","up":true},{"one":"6b4e376e9c94242b6d42688c22aa9ab418cb6dfb1cbca1c69de0feceec8d3af29fb005017aaa6e503cc0c03cf0dc5bcab55e01cd6f64b9efa02ed87c03020003","other":"e0f78c59a61f2a953553cd5742c58f4a82e38e35ac7eaa237a6ffc9fb0a3a26a2d1d1afae249e611d1320f2cb25804bdbdfb6d77336449716b0f4beb3298b8aa","up":true},{"one":"6f60ef501b41f9049419b033ae8d793a18067bdcd60347537b0dc3873bdd9a2d10d24909cca7c39781765746128c2165596f6537a94f58279523faee71f9c51d","other":"5420da16f7ed5de6b498dbc9a83b7e92e1f9900a6d04ef7351a0bfdfd442b98a5634f28fcea32ba3f3166d21c8ff5a39be70895b32acbdf7592d1d616a345a21","up":false},{"one":"6c143960dbe3ba4c95e8debc1fda5f420a2a673eb46f7ff7d9a30f4cd2067e67ef8926bf17f0c99b16c79b6dc066b52409a11d47117d4fda4211636b1b74f96c","other":"40bdac599b00e9c41ad6476ee415c33d9c17c5aa672692c2404e523b29dc315da929a86874bed87fd9009871805d1dbf3098e7a817193e3b08a6eee66346da79","up":true},{"one":"b3316f4fd7dec218a52331f25d17a2faf0f2a417808d7dbb80038154abfbcd2d78da074837b648cff28675f4aa0d65ddb7d15abf3d7e0391d401e313a3ef24a2","other":"5eccdbcb15ef42dc96abcbcd8b8db75d9230de10e3c650620737f6cc04ba4fdbf59ded5daa801901c191be186c329ebcd37ba83bcf794064ad4e11bf10d3f775","up":true},{"one":"1d0244a13affe60996fe3cf51ba624adc746de0c7ea68ec5a31311a36077c5b5495e3d95c9642875db44c7ecae6ffed22e45f2e2d024d486760be2af9f4cf2cd","other":"7b35c856916eb3fc1b1f451667e240b95aff8f4731cc0f6743740923081ff1ddf2eec81bdccf4691a7bcc053d23eacfc15809c384a73448f618317bf605bd1cd","up":true},{"one":"7174eca109a1f717653918224c8cfe1b7fbd666405196760913593401eb79f2c7e41003b01f5a458940695b27a4673443c7621a169db7fd968994e552995dbbb","other":"807340e5fdf6c21a56ef2fd158c32e92201206ca85fcc147165a408f7a735964afd47c397e663610ac53870ae722c0317291732b0422f8aeedae783d9c730218","up":true},{"one":"fe62314839c93d2f6e3aee984d5f0b321897c6f39e66800d3de8b773baf6f19e0a03cae025df512aea8d5f1b667b6dbb15c192a90a76d3031c14e33e5c16c4f7","other":"cb310c0e86aa455d7c9af6394ae38561c901da30a51d7ccb7e66a09d9a8f192ae8caeff106043426d56397088f141c4e01e3b98f1ee583ffc7318b5f730f3ac7","up":true},{"one":"ce0a09bb6fe4c9c93c3dbd800ca9c9ac0714f26a8f8dac2149b6ce7a9011912a5621ea2e45de35c4d31dfe5add00558fdba5dd21acf2d81ba391e82b5b3a5804","other":"59b53f8a562bee519276e0eeccfcf8c975d3102f5d0cccf5abcce291a8a5bb817c04604f123686177a50a03b9d7559ac469962d0159d1d93e4ce58a304d04b55","up":true},{"one":"8d4920d6e3a6717699b5a3af068cbdfc16858d7e393d158d41b1b5f345b47129eef89e1d055386c518f400b134678c21590f0317dea3436d4cef60f45455cf12","other":"be514f5f17f3177235acb24112b578edf0e373c469073226e547d18080905fd062d572be18e943f13bf9fcf5871e89ceb630a1b848a0e370ef8ef8c6d997a363","up":true},{"one":"c903c5ee3d9cd65bea3ea777e39282c33e1349d945411fb2f16321bf582c2f400956a98fbafe5873fc5f6f6a9a051df5da7e94cbd340f935abe80f91e79ef875","other":"7554993f6efd8d9016ff525ae73c41ee2e0dbd4970c563ba9b61a99c1c8943b433c4b7d48450f6e0fbc9ac198d907698093de20e6c1f7755520fb1e1cbee4eb4","up":true},{"one":"389b5c1a805f87427e6d647ec5488342a3f7d700615943d5ad98ca5c111f33c7ee007970b4d3e475892095c0d5a79b7ed52d12598398818159000d4b9b719126","other":"e0f78c59a61f2a953553cd5742c58f4a82e38e35ac7eaa237a6ffc9fb0a3a26a2d1d1afae249e611d1320f2cb25804bdbdfb6d77336449716b0f4beb3298b8aa","up":true},{"one":"c665a6b1b7ad39b86bd4b1fe38b7ee95a0fbb1db15e91381ec9e5a235e33b69ffdc92c60dafd74b7b4dafca1b000e9274bf045abe5b93b1a9c2b31ae071a9898","other":"b870935867183bbfb84add16b9f56c02c834b7042fc24ce6bcb2a7f174e6d2239357a00be4272c1ef05c7f9baf5a9f16b53bc18328a9b7aca8540c2916805b57","up":true},{"one":"22010c9829626a6892258b09cb3f3edc3f21382fb487b5dbf0dd20e198e37e26134aab850e30337f398d1491b5126839aeb1953ec144bc19aeb889c832f67c6a","other":"4fe37f2dfb03707c90a6fe91dbcfd7497db70ffc20043091d50e1cee573210c144e8749340f2c3cb70fe8fc51b317d49e8734dc51ce64b3cdccdd639ae35d1ae","up":true},{"one":"54b3c57a4adf4dbaf31b85ed1b8dccd6249faa16dd96dd230189f47f57970caeed36627cc8e1b0794707418d580f5bd6001c07be6a79216695f1253db24926bb","other":"8c6d77833bf1a98beabe7a92d985d13d52fb2e50768719ffbc6fce21ea676802a074b6e620b3ef80e12fad04f94a3c288d91df9716a6cfae09ef073b9dc1f2cb","up":true},{"one":"9c30ad8c85adc7bb52ddcfab2e661cc3a854a689eaa59128d35129d02cd5b0f8da4a44cdd33934a8e2c8fab1760c16d6f2e1c5eb227dc819e85624e63343c069","other":"66d0c5da973d9dd65350ae1ec63776872cdb7ded6afb6f51ae82259f6fd35e884375d15de290625f02ed2e5cdc3f591decb45e5fc64d5b0f835a216fd196f5a3","up":true},{"one":"b53078000796f1cdb04dfeac424d5e3e37e30f00bd5bebf9a9ea0525c62917612b3a8f508df6bea59e3c7e4cd1aa530841f9a8af54e44f5617a13dee2c6ff007","other":"0cacda5560faff9d20e29a0625d3cd340ec075f198a50ab8b79338cee0e0db84c7c7e71042fd8c8f73e507b570de5d26c39473136b575f0167625a1168309ec5","up":true},{"one":"5df58ba12334a1b4f983d642fe435901261767cd81f8f37c43e359f5584664e4d287e8c2275995604a3b3a4823418e35cd899a3db2a7db31570e19512f375481","other":"094f9d0fd3bacb17ac67a2edb8ed394fbbd1c8d478233d3269cf217e7b788e21042374936b885bf23ee4f9e03babbe4e08db283dfc2a6e052a8a5ba133717dd5","up":true},{"one":"e67e495385e7cacfe659b40d1ba94d4b1ff55eada70a4d9740a9e452fbf221672bd0a897b940e2a6bed71e2a16867fe45bf0ea0015435ac6d815690e263b1899","other":"ddaf3f8478501cda872c056c72063eb64d5b871fc5fff70704872802289dd2d348f73bc342b7f148a90cfaae2448ebf16fea196be9df891dc71a57fb410d59dd","up":true},{"one":"5526d86ba9df651091d88460a9bedb9cedb957d452a635e1db46b9fed78082022adec0047cd7485956a4ecbb0e18107595de0de3c35242527cd302bf74a19260","other":"062e0ca43a1885c4a7ab2a5169790f9081e3e9a2dfa286b8cc592d5ccbf13d7a82b72d23361a19026d04fcf41b752ea320d98359d770aedfcee626e21c3494b3","up":true},{"one":"df54af3bae257d437c5657905484e0d72e9560c46f8ba6b3437730234e05259b404cca40b0831e911605ff8a68a19e8fd7e958069ec8b40595928892f4fa220c","other":"62dab8b21640e1b44dea452dd7e7de93f27a44840da72d56b11aa96e8463f3a4bb15e75a954d19fc897ae0030b16181d271b79d8198b7cffcddaa9ffcfdcce73","up":true},{"one":"016f8f4619a16a07fbde5a18e362158d696e4d9f104a77787f26e32a25cd7d278256f8e0db865c488a99511ec27a5eddd5ebbd1c1397fa7f8db111062e5fe959","other":"5e86f39cf8338ba098a85d41e601a303fde311662b216ad32a2b7bfaf2b2b6dd1af3775784b39f2d85ac5fac96f05f3abdd8a2bd28ba16d939725fd6a33ae1b6","up":true},{"one":"57cd4c0048b459192ee46e19ec7df777e600f256e0dc8c3019431eb7bec3c020b9504ec7aea3dba8188658ca5b830ec40af6a8540ce10e04badc6c695d009271","other":"b870935867183bbfb84add16b9f56c02c834b7042fc24ce6bcb2a7f174e6d2239357a00be4272c1ef05c7f9baf5a9f16b53bc18328a9b7aca8540c2916805b57","up":true},{"one":"1944f98d4db32c56a5efda5a79aa5f276bfab1e084d6611fec0e735b8bc0f45b457cdb74a23fc83b2377821fa8316123c9877acd6db7c41058ca5d3cfedaecf9","other":"d9bbcdfd949010e6b2cbf6d0f34b27593ae410bdc1838876aeca35679571fe431d040a5ab085c0a77f111688bebed891da3587277cd794702437cb20d6aa4256","up":true},{"one":"70ee3c7e02a123f78345d41c386e413f06b51f1ab346c2c472891eed7dd26a1f14e213a0f4f2d872859b9b535936a6d9b072d2604456f76221a422710411822f","other":"adfba6d883cacbb141cd8c59ee04d7e5d520f1ce31a81e5db2d8b2380bf801c1fe4b265a66b71f9643d13a41cb1f6fb4b83399be786da4b6e171b6784bc56e49","up":true},{"one":"0a4eec7b0e05da799aca5b36d9e2530f2a89d1426b1fcb7d8f9a662df8a8b5b763767a20db3c9c63e0bd13c2a6e16d3ba8f03baf84f5e5d24917b3f211d9bcfc","other":"4f5ab12b9c5127c16739ad0d4f51adce90ba6736cd096eb185ea632789f4b26f1ebabdea4fd3b39dda5409ece6c2d92fd469cf4aecf9d29453e3e042c19b893b","up":true},{"one":"60725e8d0e9333636e598dd666f459b4be898d9abc095ee2c1db289673e7e969b50e2093956fef5a2f1d23e2040159bbabaaeab17fc6dbbac3f6acab766e9e60","other":"70ee3c7e02a123f78345d41c386e413f06b51f1ab346c2c472891eed7dd26a1f14e213a0f4f2d872859b9b535936a6d9b072d2604456f76221a422710411822f","up":true},{"one":"ed6c793eb4565aa9d883a76fad6c97ad0b878b9ef0235e11e89db1af25a9653205f725c6ea258b84bde134f1a6437c6d109b859d17509e5016c4ab98be59032a","other":"6b01079463ec2f649db8634cb7a596261c79a8f714d954c772528e0547b017f8ce405e4a0ea9d32270848180e0f77b8c0b022cf95c85e777626edd4d24ea21d2","up":true},{"one":"7bbb3f3ed51cf84c077806fbd6d3578e105bc32aa6043da188793f066ad6df383a9f7cc0bd3124f4c887704bd188d480ce264fcdf178905bbda3b270927ea138","other":"5142eea687de4248b2184e9896b245563117648e7a156255d9a7ae730313d5d383db3be1125b5accd7e743c2a5d8c3289ec559ef7cbb803b9e82cd49bb213d9f","up":true},{"one":"62666b24d1026345349edb6a878cdc27d6fee8254e83f79a298ce2805260d97aa46423deae440f86ced5cd99b30e970c8e1ea1046752b17d8c80dc68d9a49b60","other":"07f25fdeab2b44b2e92fc80fca7de9e4a8547d27a98a54593b3395c270a9ff3f2a5da62a2e8531ce86359f0cdc5b6513b773dfd64cce1b83e47065d9760a2c7e","up":true},{"one":"84dfd4e4d9f1204893f190eacc4c3999e175c433f70de86e335d27477c097a0552f211a21764f01a708da4c9e9e6552191a61d3e48f41d0e84f01e7ae3beb34e","other":"eab86c521f8f1ac67c015ab713f1236a08b0200757a96bf87ab8301e7967ae62361f0e14da14ca294fc8cb3b4726b52f4773101e21b032977c6a647241b59c73","up":true},{"one":"8c6d77833bf1a98beabe7a92d985d13d52fb2e50768719ffbc6fce21ea676802a074b6e620b3ef80e12fad04f94a3c288d91df9716a6cfae09ef073b9dc1f2cb","other":"4b784f072b7c96c30612767425f552e30e45157e70139dfbe0ae4ff86dc31601adec60f8a3ad9747b02b5219073d8813af9b09d59eaf7ddb7ee24856aff6fa8f","up":true},{"one":"7b35c856916eb3fc1b1f451667e240b95aff8f4731cc0f6743740923081ff1ddf2eec81bdccf4691a7bcc053d23eacfc15809c384a73448f618317bf605bd1cd","other":"083e67bb19e30d14e4df6d2483367d6659d9b56744d53d9cf7fd15954c327e1bc88a5d0db8833634e1dad7209164451f8934b59f76b5990059261abfd650519a","up":true},{"one":"e087230634f556b818a416b66ba3f1d1dbe3e0dd0698bbb26fa86a2499acd169466f564dc18adf2f9be4d1ada0e86c11549754097601e10aff4f3a57ddffa24a","other":"e06a789a7f6988e1ba5e8358b6cd4292555c7f9f7f0dda6fc01cc26d24e49a8c1ad694423ad74aec6d80f4b99e2bedc49b6a5f2670744cedee3a3e1848e6dd07","up":true},{"one":"66beee3968dbcf3addc6feaf070a4e3e82b5bb164fb72f40add89f732c12e8d0a31a7ee1f1e24a4674e4dfc9a4912b02c17ce3c224d257d78b7156544d6507dc","other":"759f46661056bcbb30c7706c9fb87e22a30feb523bd53ae5d18db043efa45b49a2b8982abebdd598fe0912a05896390ec2eabe5e160cbafc0771990708ad8c28","up":false},{"one":"2f360209383d6de4ebd3b4abaf77796520b8654270b03f2151eac4a01b4417d7e0668c1f9ad30c20ff49aa8a0ab33dba5e6095619d1cf04b7af841722ab773da","other":"65e954e60837bda10654480b227fa3bcc6e63356c52079002a27e836cd82ae2934ba77da60080e4b9f2d9324b982b24959bfd9624302e6c330408381054b43e9","up":true},{"one":"ee36d1d5dd69fd30242d7da2e941b34ade5581c7164fcc43288ecfc52937a98f1b31ade5d1e4dbf611cbe1c7875b2840c89435081cde471c271d7bc60e9ef211","other":"2ac522ebfa49d37f86c6270ad4cdad0e766493f0e463b18c9906c70fbd2e5c6ff6b0d5879de6e3894418370636963a78b0c0cf087a8684c2ca30c9c736e49228","up":true},{"one":"4e95fb8943ef6502fa470870a7ace4ca11e18589bd2073167543a922317b35e40b5068934d07e56c8fdd23354dfad51fd2899db854f189841f02b5914cd97749","other":"5420da16f7ed5de6b498dbc9a83b7e92e1f9900a6d04ef7351a0bfdfd442b98a5634f28fcea32ba3f3166d21c8ff5a39be70895b32acbdf7592d1d616a345a21","up":true},{"one":"4de378164d77a28c90cf162dd1b465e0282ee17aa7d3bb3179252466f72da33a36c9f298f7c9498e38dba4018e7ce3e5fe631c83842cd9059e23a7fece366d87","other":"083e67bb19e30d14e4df6d2483367d6659d9b56744d53d9cf7fd15954c327e1bc88a5d0db8833634e1dad7209164451f8934b59f76b5990059261abfd650519a","up":true},{"one":"155e4879643a472420012e040a87dbff776fc1976814c0c6cd0d5e157f0d0baac04aa7f2535786c09acc2700547383d2119b64a6f62115f1aff1708738844d8c","other":"7b5c0e81c7f4e3ae29d745f6028cfa10b29a16a9c261b65fb8dd05d6eccc634612ad5d3029c8e9f39863a2cdb2682c25f090139bf5c4950e25647e39dcb40e63","up":true},{"one":"81288bb0584b7ffc1546043e052e1df10fd5371b35dedd0bb42ec5b30ce69b741b2f7857af5984d4754b39d7253575fde9298504999b78380ef602d391c4bb1d","other":"e2e0419a41bdfc5bd76deae2ddce6ac865f886d764c9bd18799b79fa3b2b6ba66d765d26da2037e98317e1d7e8232a61e63c1d0cfa98c9137424151b46e07171","up":true},{"one":"ff6f94005d1df7677600069764855c1c2aa0543cbe9f480f8feefec76c49d9e2c7bb2d8e38c89e9430f53f8b593d93f143c45985a56a5a32c736128214c95eda","other":"2f903b2fd4f9432b7d91b5c3e4c7ee3cb9c56fe7efc4baff0edd06fc75e4b7492f2c3c929755746df59c9f95d437a12ba40ac138d08f5bc7aa091f49f3b852c2","up":true},{"one":"3dfd733dde9414af916625ab981777ff1ad7ca0f6d1e4e7d9e2739969e21182fd13d85e281868653e7325b20069356b11524b54143c47fd3955a911cf7325ad4","other":"7554993f6efd8d9016ff525ae73c41ee2e0dbd4970c563ba9b61a99c1c8943b433c4b7d48450f6e0fbc9ac198d907698093de20e6c1f7755520fb1e1cbee4eb4","up":true},{"one":"deb7af800cd20a647335f0feff5bfb3e182f99f4c2d1ade10da36ecfdbac3b5fba4e8f0a4595443fe395b44af3a95617669850944655def85d57cc81c5682a3b","other":"9ce6b9decb69d66075993e903a0727ec109a04335634616097c0e60b08f94f764634fa00891b1070f6ea1ce896bc7d11d3aea92a00f281f902d960894cef296f","up":true},{"one":"9133b0b3c8f680286eae90c3beebc3099a13de38775a3ff2abdeced62d05eb2ced5ac85eac0870156be03101024da5e1d9fbf3e1066ddb3f088221e64149acec","other":"beec648d79437a5d7b4140ced45d82d035c6f64f9c67c58386703811d97c3846787eaf274d2298df809475f0b7519df696563cb8e9a5fb0a9cc419ab13fa8d41","up":true},{"one":"17917fa4da06068b587c17899569dcc768b9cd2c27117a4ed67aab26a7e70cf8d32b881db258061ffd89a332a3b29bfd963d8e171a06c3e208ba0de1c42a2b39","other":"7b1e20217f594f87350542df31ff5ae8a635679bac7962d49c97e02190c644b673d03e7eba2626b45ca7ebf98d8a972dadbba02c18a8d2cbfc3e7a4cced5b4b7","up":true},{"one":"84abcbc7b5598ecfd91ceace0927921a5a3404fdb274fc2a2549abbede5f8e4f62c15688a4dc9a2d80262c45970c88898da245c6eb779f327a81d53a17bbc74c","other":"deb7af800cd20a647335f0feff5bfb3e182f99f4c2d1ade10da36ecfdbac3b5fba4e8f0a4595443fe395b44af3a95617669850944655def85d57cc81c5682a3b","up":true},{"one":"3e488a7208ce0e097ce47fc6651a13e95cae137d1a054a09b04d2f59d45faa2594a8c3b395e77ad1a3c2edcd827dda73c0c97dbaa6d9519a79184a0aca01ac4b","other":"2f903b2fd4f9432b7d91b5c3e4c7ee3cb9c56fe7efc4baff0edd06fc75e4b7492f2c3c929755746df59c9f95d437a12ba40ac138d08f5bc7aa091f49f3b852c2","up":true},{"one":"4314b0b04331973ed29a58843951f144ac3d09bd5d57b6cd9aaff9b73a7b2ec81e344a3e4ece462bd2081b837a06310e787ef3bb889dabad46fe7efd394c8342","other":"385168340139236a0e0f537fa693122db9fa02a377c96f31aae54718e92624fc0288164877e63616651565e055c53f7074ab2fdd18a837da6faf644941305bf0","up":true},{"one":"6b4e376e9c94242b6d42688c22aa9ab418cb6dfb1cbca1c69de0feceec8d3af29fb005017aaa6e503cc0c03cf0dc5bcab55e01cd6f64b9efa02ed87c03020003","other":"62dab8b21640e1b44dea452dd7e7de93f27a44840da72d56b11aa96e8463f3a4bb15e75a954d19fc897ae0030b16181d271b79d8198b7cffcddaa9ffcfdcce73","up":true},{"one":"07c63ca5d0309e30d1ab12e7fc142e6d37904b552639cfa97850161491f28f20d87e0304be29357bcfc2ff52fc52fd0d4f6e6011ebb239cced8b5c8dad7abf45","other":"6ab6ec15635b2fda22542c99df0a3313ad4583ba0fb3f31b8f314e3ecad446d3fb0fdfcd2be9b08374b1a7e049fb68e69e8dacdd13f1df5007a656f6b11adc5b","up":true},{"one":"6c143960dbe3ba4c95e8debc1fda5f420a2a673eb46f7ff7d9a30f4cd2067e67ef8926bf17f0c99b16c79b6dc066b52409a11d47117d4fda4211636b1b74f96c","other":"0deda014fa3c0bc8f37d853e1448f95f56f97048c28797d72258fd3ba2f1f776ae11566197466596356cd172847ab02a89f4cf047e58383249fb2a4cd69b6206","up":true},{"one":"7865b82e44add2cea6ebcbaba9c152184331a2940fe73f6f9bb940bda8a59ab4cf4760894b9cadcaa54e36fbb712ad619346a49a85e32cdf2b53cda1ac1e0658","other":"3e488a7208ce0e097ce47fc6651a13e95cae137d1a054a09b04d2f59d45faa2594a8c3b395e77ad1a3c2edcd827dda73c0c97dbaa6d9519a79184a0aca01ac4b","up":false},{"one":"c8b0dba45104fc7c7dff3ce078a0d3f5ade6198bb4656e2bee8076387929133e5ef2bd293b130a9d4f6a6974ca17e8b4a8f406d1219880f1e0f99c65c63af5a4","other":"ddaf3f8478501cda872c056c72063eb64d5b871fc5fff70704872802289dd2d348f73bc342b7f148a90cfaae2448ebf16fea196be9df891dc71a57fb410d59dd","up":true},{"one":"292c78c8e41606e98428096bc6f4609a7aa48e5c4d17eecc64d65faae4a7270b0c15f0cd74274015688ea0a9aff34f215c29118222e362a29c8d637963973a55","other":"3e488a7208ce0e097ce47fc6651a13e95cae137d1a054a09b04d2f59d45faa2594a8c3b395e77ad1a3c2edcd827dda73c0c97dbaa6d9519a79184a0aca01ac4b","up":false},{"one":"9db1f94d74a00d1e5e2a391f1bcddf16b6d0670a2c6d91d946d38112c58634444b6fea8e8c05ab4b73bacdd62a0b575f6fb8729978edc216c7842b177b9f9cd9","other":"3e488a7208ce0e097ce47fc6651a13e95cae137d1a054a09b04d2f59d45faa2594a8c3b395e77ad1a3c2edcd827dda73c0c97dbaa6d9519a79184a0aca01ac4b","up":true},{"one":"be514f5f17f3177235acb24112b578edf0e373c469073226e547d18080905fd062d572be18e943f13bf9fcf5871e89ceb630a1b848a0e370ef8ef8c6d997a363","other":"2245f3bf1a3b4e92f912affc75f757cf648b20474c11ffe947884f216b8f24f9dcb6e6a0358a4061b8517478ec15027e185b2f05a777573b4940375bf4aaf2be","up":false},{"one":"65e954e60837bda10654480b227fa3bcc6e63356c52079002a27e836cd82ae2934ba77da60080e4b9f2d9324b982b24959bfd9624302e6c330408381054b43e9","other":"2f903b2fd4f9432b7d91b5c3e4c7ee3cb9c56fe7efc4baff0edd06fc75e4b7492f2c3c929755746df59c9f95d437a12ba40ac138d08f5bc7aa091f49f3b852c2","up":true},{"one":"2e409baefbd821485a151993356730e5989810d581e68190fbaa142799c9335bcf98310ad188fed10ae6eb6e2e789730393e509962ec5c0fef0342d72ed088d9","other":"7acddc7fb6ac587b7e343804c768e4291cd28dd2b2b9207dea6ee82360d848a52d84f94e4c49e9c421f4f90e2d24f6291e2358783ab0230e6ecde82e69b4ac52","up":true},{"one":"0deda014fa3c0bc8f37d853e1448f95f56f97048c28797d72258fd3ba2f1f776ae11566197466596356cd172847ab02a89f4cf047e58383249fb2a4cd69b6206","other":"40bdac599b00e9c41ad6476ee415c33d9c17c5aa672692c2404e523b29dc315da929a86874bed87fd9009871805d1dbf3098e7a817193e3b08a6eee66346da79","up":true},{"one":"7f357b8d81bc2e5c6fcb081f23a42b3e2439f050d45c45851994a268d1c71fcb1f39f8c3f75ce921d3fbf80fc0e73f0b9609d72001dc4a6b65b526d312a4f43a","other":"e67e495385e7cacfe659b40d1ba94d4b1ff55eada70a4d9740a9e452fbf221672bd0a897b940e2a6bed71e2a16867fe45bf0ea0015435ac6d815690e263b1899","up":true},{"one":"829b074b70d757da6aa00f7bace3cf1b5d2d4eeadb7f370c1a85374a01a70b54ac53d747267e386f3b41e6d790fecdd6e74b8f89745501ee82439a66ea54443a","other":"0b7e1e5acabcde503ad827e45724402406114a513f81040a379b0f82df2eab4456b348b27936369c49e3c264d971c6a9e2c2217fdbc5e5b93ac6fc219957834d","up":true},{"one":"76cbf9fc0f3517fb615fa96104780218e85d064ee5a1d518f3b78f4dbebf144df38c427445fdd6c9b436489c00ff9497d747a8fd70f380f95601d59e52e021e8","other":"f6ca39b3ad803e99f4e4e9cf759fff6abdf06e6972bdbe524f6eb930c669d6f0e9b91f3de9df394b0d661b068273861391bdbac948ad911351c48cf02f874db6","up":true},{"one":"f38a9d792173a29c61389f5d84c005d78eac6e750659aad42e2d6df883f04eb3126b2c38fac95076eeed455b2031aaf694143922aa93a2d50412a2454dc56e28","other":"9bd4f0adb9a966cc5ba632f1b540fe9cd6c8e39fe1a041b315697679cfb04b735952062ce057d456677cc34a84301f26bb727a4ab2646fee734f80a22c620746","up":true},{"one":"7ac5b07eb555af3bb4ca3f0f4b45204d43cc3798c244435909b97d9a32fc3abf0b50666e260e046bce826a7a102a92d389f8f39c5311e83bb34beddac29d50e3","other":"831cde5b651ba327b059da4c7f84b184bdd6bb99c6690ae816affe25d42c6c3dbe5b59e2b6bf23e9d0f6c485bd341ea57ba1a8220d18b0a40e156b77d84f79ef","up":true},{"one":"049a2b0ab4d49789dbbe1837e2d2ee5220a9401729ea87ab29385b24d79cdce255c3d2b5de6484d49ca6ce07bd41832598260c0a8c290e01d133d77f066f2f99","other":"22010c9829626a6892258b09cb3f3edc3f21382fb487b5dbf0dd20e198e37e26134aab850e30337f398d1491b5126839aeb1953ec144bc19aeb889c832f67c6a","up":true},{"one":"7b1e20217f594f87350542df31ff5ae8a635679bac7962d49c97e02190c644b673d03e7eba2626b45ca7ebf98d8a972dadbba02c18a8d2cbfc3e7a4cced5b4b7","other":"4ff66e9b5d3fd345990bd7605bdc222b78946f0c13b72bf80352812b2426d8f1d36c93e6c8713566004615e8a78ecab12ab0cfba254c0967eeecf8875b25bdae","up":true},{"one":"6b01079463ec2f649db8634cb7a596261c79a8f714d954c772528e0547b017f8ce405e4a0ea9d32270848180e0f77b8c0b022cf95c85e777626edd4d24ea21d2","other":"ce0a09bb6fe4c9c93c3dbd800ca9c9ac0714f26a8f8dac2149b6ce7a9011912a5621ea2e45de35c4d31dfe5add00558fdba5dd21acf2d81ba391e82b5b3a5804","up":true},{"one":"657d5370319128d24d925b41065eb619409d63ec6280975d78877a4028287463f6442f5206dd703569a05b2b542ad8bbb99803da265408208d6356a26d283d08","other":"aacff366e601e072a2113add9020e19b6612f3e85b6e607fdc8cc1b6991f43be0b1f835ed3dc41d1f2b3e0caf7fac252c8eb4c150667d48207fa92ea5f0a7455","up":true},{"one":"a608a746f46d4b2e9267c65283380d6d6cb8885a64428fb77df9934bcf4dd1723587ee7c8f4a642dce266a12a6a4cf4e5c6db7fa1024158425a6753e7ab7264c","other":"1090e9d89cb278a30063a5396d9ba795d3bbc237c76915a6fb7d23aa1822c8535d2fccc44cc8cd2acec68444c0bf1bdf5195ebb9f3cad8dac3d94a4d9c0e5309","up":true},{"one":"abd8f5a4d700c06ec00684b23d2d25c4df1a9554fcfc57b0ddc3fa476e6a699ba75e1213449f900803f83ab8194c6746664b547202047f35b8b3e216c7147bf8","other":"07c63ca5d0309e30d1ab12e7fc142e6d37904b552639cfa97850161491f28f20d87e0304be29357bcfc2ff52fc52fd0d4f6e6011ebb239cced8b5c8dad7abf45","up":true},{"one":"be026dfb24847cac2d00f483104edad06ca8ecb9e1229c479ef5650c7b427cd5dc34a1cf06172c17c9d0406ce17009712e82446394743d4cd9bbc41c537ebc14","other":"e1ecad3beeb6c19dce551e4a603c7b440b4498c44e298dc67bfaf4ed2c75bbea95df48b1cd1318e2ccb962cbae7c30ff258e73f8c3fc6b7e9ae7a47f7cf8e53c","up":true},{"one":"e2a27dcdee1f89fa362a85c4397840cd8be4ad8d1b9ccb23188c303bcab7619f38772f71385922d090390973b62fb8249efc103f71bc761041bcb3880ec0b935","other":"4e95fb8943ef6502fa470870a7ace4ca11e18589bd2073167543a922317b35e40b5068934d07e56c8fdd23354dfad51fd2899db854f189841f02b5914cd97749","up":true},{"one":"ee36d1d5dd69fd30242d7da2e941b34ade5581c7164fcc43288ecfc52937a98f1b31ade5d1e4dbf611cbe1c7875b2840c89435081cde471c271d7bc60e9ef211","other":"e3c8a97a2d95dd543f9e2b41d9dce6256e284296f866f4f92e9925f8c7519dea23fd6d1a11153b93c10d6a32295e7b9bcc16024e690e4a0dc84fd25ee0f31b2c","up":true},{"one":"24662a43944228e4ff74736bcf0a0a4f79c87ecfdb739225b2fc45110c11bfc38aaf2d09d98e5817477848e553f187ac5408bdb864518dfa7f5df542768828db","other":"e087230634f556b818a416b66ba3f1d1dbe3e0dd0698bbb26fa86a2499acd169466f564dc18adf2f9be4d1ada0e86c11549754097601e10aff4f3a57ddffa24a","up":true},{"one":"afe5b217dc512eee45575c189826ee5640d11a0ac9e8e4b03e9e62e6cf6df9de500bc8a36cb7d82a2280ce184409164f1772cc5c9e59ad04361522d2b8c364e0","other":"f38a9d792173a29c61389f5d84c005d78eac6e750659aad42e2d6df883f04eb3126b2c38fac95076eeed455b2031aaf694143922aa93a2d50412a2454dc56e28","up":true},{"one":"e06a789a7f6988e1ba5e8358b6cd4292555c7f9f7f0dda6fc01cc26d24e49a8c1ad694423ad74aec6d80f4b99e2bedc49b6a5f2670744cedee3a3e1848e6dd07","other":"7174eca109a1f717653918224c8cfe1b7fbd666405196760913593401eb79f2c7e41003b01f5a458940695b27a4673443c7621a169db7fd968994e552995dbbb","up":true},{"one":"1f6d803a4ca186463772850ca0901fb920af7e74fdd2480c3c368fa707838ee91bbcfb57d5e3510c802b9b85f2d954f04c9b675414274bdaebae6488dcf94c10","other":"2f1967b4410ea2ea8fbaf46771ba82c2846d00aecdb6f873aceae33ab38f72d0a2c2dc6046d3034f514efd090d42011d48e9ab0cb4e3caa2b49a96ef732215a1","up":true},{"one":"53df9cce9b0169e58ced53a123d1d8f6e8fdcfb4c2d781ecbb91bb7c8eba36946dd9d21c749259769825d8a6b3faa6bb87c8c6085a522f8a3e376061f59144d9","other":"e2e0419a41bdfc5bd76deae2ddce6ac865f886d764c9bd18799b79fa3b2b6ba66d765d26da2037e98317e1d7e8232a61e63c1d0cfa98c9137424151b46e07171","up":true},{"one":"934a5fe1b91c1891ef4df7f67c027e0eb115d4c2ca4a1b76a135ebd4315c4fb835d6625223194e6a134407b38b0d3928fbc7bc924a3c6a538989a6cf200bf4bd","other":"155e4879643a472420012e040a87dbff776fc1976814c0c6cd0d5e157f0d0baac04aa7f2535786c09acc2700547383d2119b64a6f62115f1aff1708738844d8c","up":true},{"one":"485825745d97654cbb92a14e0cd1078691d3c28f4d82b1046284b676a42b44ca58eb43474e45e415d3bd3f3c383f9a1a3365821ed7ba6a9f2603b29d58031dc7","other":"155e4879643a472420012e040a87dbff776fc1976814c0c6cd0d5e157f0d0baac04aa7f2535786c09acc2700547383d2119b64a6f62115f1aff1708738844d8c","up":true},{"one":"5dc69635f6d573c824ea83b18593a47f9f21a6f91ce18d2bf977c97d21f8d2a8ce88829244d12a07d949bbd52fe8a2035bc89685fe1bdd4ee20d766d75d3deee","other":"68cc8b9a995eef6170abf88bd5fedca06ffcc8d75f247f6041c13e7dfd292727ebda1ff86b776e33b6634355c55e0f8c22fcdb5f9a6e2f22fe1af7854c3b4273","up":true},{"one":"1d0244a13affe60996fe3cf51ba624adc746de0c7ea68ec5a31311a36077c5b5495e3d95c9642875db44c7ecae6ffed22e45f2e2d024d486760be2af9f4cf2cd","other":"083e67bb19e30d14e4df6d2483367d6659d9b56744d53d9cf7fd15954c327e1bc88a5d0db8833634e1dad7209164451f8934b59f76b5990059261abfd650519a","up":true},{"one":"920a301186bdf665a721676ece7c180413369ea6eff7537f42049d9eb409f28cc864099590116e885f57368959fb2cff7003697d9b1515e68bf3fa7aee0278ef","other":"535f93057d46c4aae0902546550880be0b5ba67dca12350117d471d67f4f2b3f7bdff29bdc918767974c465df8fa1afa6bd6c29c0a36d51f71c4183673d906f3","up":true},{"one":"759f46661056bcbb30c7706c9fb87e22a30feb523bd53ae5d18db043efa45b49a2b8982abebdd598fe0912a05896390ec2eabe5e160cbafc0771990708ad8c28","other":"ee36d1d5dd69fd30242d7da2e941b34ade5581c7164fcc43288ecfc52937a98f1b31ade5d1e4dbf611cbe1c7875b2840c89435081cde471c271d7bc60e9ef211","up":true},{"one":"2ca05ffc0ad771e1e045a47f1c0a79ce374a25e3c0e53c2a80d67e7479677003f62880251a83a5074f1c9651d828f1ff7e352935a9df141c1eb75a0c59b00a8b","other":"657d5370319128d24d925b41065eb619409d63ec6280975d78877a4028287463f6442f5206dd703569a05b2b542ad8bbb99803da265408208d6356a26d283d08","up":false},{"one":"b35f418c7935cc54278e90978c3ef1521ab91daeaf9f1ebc1cd25211611ade091cac4e1f009d71059279d507322a4536501980ac0dd44caddc52fd4c593879f7","other":"28d3232c43de54ffdaf08f97b334c012738648b04e2876c7e751a2e352aaf4d550d6efa976c5a8edbfa8e88b9d04a0fca492b81c3756ef673ab74d34182ca711","up":true},{"one":"b597c9ba4da20c49fc4ba019571321d2579588636cdaceb9f225706574970adbf4771dcf186b1decd4e14cd5d257e30a36ca829829598c1775902201ad9793e2","other":"302c37f28c69fdcf00b39ce0c0223de0d94cebc2c0b068315b95b76b5432573ead0656569441029ba9054d8d3d959fd8735e73913af5ce3f1132f8271fd437ef","up":true},{"one":"9b59b76dc61223c7b37083b0ebdda22d3599563b3e3986f5db9d5b12f8c806cbdeb2345454efe957cbfa11eea9c7896aefd9a461210524805452ca100a9ea431","other":"7ac5b07eb555af3bb4ca3f0f4b45204d43cc3798c244435909b97d9a32fc3abf0b50666e260e046bce826a7a102a92d389f8f39c5311e83bb34beddac29d50e3","up":true},{"one":"f54335964d9b4eb9813eb05f40ef1c523bbf0faac5a04c4737467d590fb6b55c7fa1fc5d4d32c5491d8766b9be6fdfd3ebdb25c5ffe1719f36c86ddf87ae3a85","other":"6f60ef501b41f9049419b033ae8d793a18067bdcd60347537b0dc3873bdd9a2d10d24909cca7c39781765746128c2165596f6537a94f58279523faee71f9c51d","up":false},{"one":"032b9bf2f59f15571821611d3ee541aa748c86d47fbe5f049fd0069be53e5d7c41991d82957e9c727654c3aa73ec94997c03d8a6c1d2007c9bb1a703f6215158","other":"7ac5b07eb555af3bb4ca3f0f4b45204d43cc3798c244435909b97d9a32fc3abf0b50666e260e046bce826a7a102a92d389f8f39c5311e83bb34beddac29d50e3","up":true},{"one":"ea57884dd42aec5a76eab43483bf7c4ae2c19eebf365013731de64494d10a3b4cfe34c86c79437f9012bc8cf6bd761435eefadec17600f4b9e4bc234532d6282","other":"62666b24d1026345349edb6a878cdc27d6fee8254e83f79a298ce2805260d97aa46423deae440f86ced5cd99b30e970c8e1ea1046752b17d8c80dc68d9a49b60","up":false},{"one":"829b074b70d757da6aa00f7bace3cf1b5d2d4eeadb7f370c1a85374a01a70b54ac53d747267e386f3b41e6d790fecdd6e74b8f89745501ee82439a66ea54443a","other":"1bc1d6155ba35d29ea16938994e08df76ebd8f16bd180bd6a9b9d8798d0745889fe72d641dd78bd8ec13526929f7eb5aaa6a388430fa69033d6db581e53c6422","up":true},{"one":"e6779e3bbecf81dde8b27d652ed2726c45c205db0d0405c4580014a4c91d739830276f77079108c98ac516ffa00194e77a0795f7140bdf36069b6475e58213f9","other":"4ff66e9b5d3fd345990bd7605bdc222b78946f0c13b72bf80352812b2426d8f1d36c93e6c8713566004615e8a78ecab12ab0cfba254c0967eeecf8875b25bdae","up":true},{"one":"f039df8a3206e6e17eee8e95010038c450cb4cc0b5580ed5795d4c21802e1e9d360f4528bdca794f457932b1d6a818862ec847357a861c488332ef6d9480daa6","other":"aa9a94d6e4eaaed20113c21752c224e3a052abd3769bd6e832759dbaf5154a943cf094eacdcb0727c2fe51a11bd7fc0793d7d5e3312b0aba89d428a00e1fde0c","up":true},{"one":"5eccdbcb15ef42dc96abcbcd8b8db75d9230de10e3c650620737f6cc04ba4fdbf59ded5daa801901c191be186c329ebcd37ba83bcf794064ad4e11bf10d3f775","other":"b080891d4ba6d3ab224984360597f9c555bd1367630f5420bfaf230419a05b2be58bebf1554e53eb4c0da81cfb66d4f7697dd65143f11841ff62d8a0d82b6b67","up":true},{"one":"d9bbcdfd949010e6b2cbf6d0f34b27593ae410bdc1838876aeca35679571fe431d040a5ab085c0a77f111688bebed891da3587277cd794702437cb20d6aa4256","other":"2e409baefbd821485a151993356730e5989810d581e68190fbaa142799c9335bcf98310ad188fed10ae6eb6e2e789730393e509962ec5c0fef0342d72ed088d9","up":true},{"one":"b4a5efa9028b2d196855393892f79993c2812d02b758f98813ddf82c5d943faf6d66eff811cc5a51936c118f4c768c0d13b54902095e040c602761e63c08655e","other":"cb310c0e86aa455d7c9af6394ae38561c901da30a51d7ccb7e66a09d9a8f192ae8caeff106043426d56397088f141c4e01e3b98f1ee583ffc7318b5f730f3ac7","up":true},{"one":"460531928a4b084686343c8464b37c3452bb3566045698d08a4692864de5581a9eb1dc632329e7d3ccb73ec31ee7693787d69df8458efaba9a7105d87ee2e053","other":"4e68553db7be307b8379e8bec383b5c92e4b23debcefca575d24504e2062618f74c26e60e0d9e47f096997a7f841e2c32c994124f495ef3352ef964b33fd3a51","up":true},{"one":"3612863ce0456c91785a829bf5c9d2b2fb97dda083a1847e5a4ebaa6fce1260faf4d1eb374c2225431a82774163835fb59c8cb0fa9fc0969eab5410c71109cc2","other":"9194a3a4c8f3235203e48bdb10902d958d26c342805ea6365af9711213536509719d917c694f9a4fbdde6889a4c92299a5301f0275bda4dbcd2541b5bff5b271","up":true},{"one":"1b063741c76fe65e62b4eae42751319d0cce66f22dde9f1cf83d6cca249a0e65bc7f6f22597697362fadd226222fb3847f8e146961969d1b4c9f7e475389cd8e","other":"aacff366e601e072a2113add9020e19b6612f3e85b6e607fdc8cc1b6991f43be0b1f835ed3dc41d1f2b3e0caf7fac252c8eb4c150667d48207fa92ea5f0a7455","up":true},{"one":"cd8815d66aee8bd488d4e5e25f0cc9c71cc65349f701ea26b1d6cd9c039d16fcb473dbf270a3b33187720ccf4b0ce4f78a6d6edd05f4fe804772d5b6ec45bbd3","other":"1090e9d89cb278a30063a5396d9ba795d3bbc237c76915a6fb7d23aa1822c8535d2fccc44cc8cd2acec68444c0bf1bdf5195ebb9f3cad8dac3d94a4d9c0e5309","up":true},{"one":"fde7705f5013c3b6b76a35505c1e3d57c033a337f2a71e912ec3a3d2da8e113bd7c36d94908357e9f7654660621f647ad8c66b0126dfe91dbfa3b8c7bd2183d3","other":"829b074b70d757da6aa00f7bace3cf1b5d2d4eeadb7f370c1a85374a01a70b54ac53d747267e386f3b41e6d790fecdd6e74b8f89745501ee82439a66ea54443a","up":true},{"one":"4e68553db7be307b8379e8bec383b5c92e4b23debcefca575d24504e2062618f74c26e60e0d9e47f096997a7f841e2c32c994124f495ef3352ef964b33fd3a51","other":"e2e0419a41bdfc5bd76deae2ddce6ac865f886d764c9bd18799b79fa3b2b6ba66d765d26da2037e98317e1d7e8232a61e63c1d0cfa98c9137424151b46e07171","up":true},{"one":"62666b24d1026345349edb6a878cdc27d6fee8254e83f79a298ce2805260d97aa46423deae440f86ced5cd99b30e970c8e1ea1046752b17d8c80dc68d9a49b60","other":"420b9c90584651c5a3fe3c16aa377444a321dca934f8a097d01a616554067feabebf2fdc8d2a25797f29a8fef30d5e2c82f8e85b20f509a880367b9b0ccdea47","up":true},{"one":"ed6c793eb4565aa9d883a76fad6c97ad0b878b9ef0235e11e89db1af25a9653205f725c6ea258b84bde134f1a6437c6d109b859d17509e5016c4ab98be59032a","other":"c8b0dba45104fc7c7dff3ce078a0d3f5ade6198bb4656e2bee8076387929133e5ef2bd293b130a9d4f6a6974ca17e8b4a8f406d1219880f1e0f99c65c63af5a4","up":true},{"one":"84dfd4e4d9f1204893f190eacc4c3999e175c433f70de86e335d27477c097a0552f211a21764f01a708da4c9e9e6552191a61d3e48f41d0e84f01e7ae3beb34e","other":"c57ea182bdb42ba9b0870b5c870e467f52693e5c0df752fb6eb0dfbacce7763f73caee10db40f4fd90f19f504ee586eaf9da41f5ee93ee515d885fec99374116","up":true},{"one":"9b618ad34d0dfe0fccbd5b8af365cbcdbb43e802df5f23e91c20d21f3ead6169d52bf0db7e5e111abef630c9853419fb33a88cf111d8507b8708208b5d65e35e","other":"cb321c9b0fe2eb3617b8e2461aab170a9dad2c9b04a10eead4e37e551197ea0a7500eb1cb7b155efe1886486ef3d252d8ff0d309f2906a1126ca011d037da70a","up":true},{"one":"385168340139236a0e0f537fa693122db9fa02a377c96f31aae54718e92624fc0288164877e63616651565e055c53f7074ab2fdd18a837da6faf644941305bf0","other":"88d5c5fe61ee1e6fa5878e0eaa13bdabaa0ec3d38a5d25b95a467da7627424f25fb5d30535aa0a5ad01c16fe2598dbf570b78cc152a7f4ef66d46fc9ae43592f","up":true},{"one":"b870935867183bbfb84add16b9f56c02c834b7042fc24ce6bcb2a7f174e6d2239357a00be4272c1ef05c7f9baf5a9f16b53bc18328a9b7aca8540c2916805b57","other":"62666b24d1026345349edb6a878cdc27d6fee8254e83f79a298ce2805260d97aa46423deae440f86ced5cd99b30e970c8e1ea1046752b17d8c80dc68d9a49b60","up":false},{"one":"1f6d803a4ca186463772850ca0901fb920af7e74fdd2480c3c368fa707838ee91bbcfb57d5e3510c802b9b85f2d954f04c9b675414274bdaebae6488dcf94c10","other":"40bdac599b00e9c41ad6476ee415c33d9c17c5aa672692c2404e523b29dc315da929a86874bed87fd9009871805d1dbf3098e7a817193e3b08a6eee66346da79","up":true},{"one":"ba21a373781966135d6225adae024a3f3e421b852f72f8b0569cb92fcff87c33f7e5b799a509b8eff6ec6dc46a9b17d5bae1e91ec7c54c0c712d893d54b140fa","other":"84abcbc7b5598ecfd91ceace0927921a5a3404fdb274fc2a2549abbede5f8e4f62c15688a4dc9a2d80262c45970c88898da245c6eb779f327a81d53a17bbc74c","up":true},{"one":"617595a230e0a74a3db3b47cd27b941e02bdee9a84cdfa8eaa63a55941eb5caa79e20fb69726a4d46a0e5aeed24039f8c5a20679a692df0bc140f42558ca9a2b","other":"8ca3b63cb84f1e9883d82809a9b6777ec1029ecda96fe93b4d494ee9cbefcad13f381b3e480136e542e01054fe1ede66c65db84a0009871ce49383db461c8438","up":false},{"one":"292c78c8e41606e98428096bc6f4609a7aa48e5c4d17eecc64d65faae4a7270b0c15f0cd74274015688ea0a9aff34f215c29118222e362a29c8d637963973a55","other":"a1560ce7c1f1d5972f027a8e9cff820611d84764aa067434a75b63887bc4268a259101486d34b7fe83dd735e799789986cd3e9b156c86ede598bd86af4454924","up":true},{"one":"f5c1215a84a56d52f92ca0dc3a32df98c98a9c2ea2e9a34560210c16de1b440d20d043c8c25955dda8c22e55e92ddb49fd82e8b9b84072aabaa755a229bb19f4","other":"1090e9d89cb278a30063a5396d9ba795d3bbc237c76915a6fb7d23aa1822c8535d2fccc44cc8cd2acec68444c0bf1bdf5195ebb9f3cad8dac3d94a4d9c0e5309","up":true},{"one":"c903c5ee3d9cd65bea3ea777e39282c33e1349d945411fb2f16321bf582c2f400956a98fbafe5873fc5f6f6a9a051df5da7e94cbd340f935abe80f91e79ef875","other":"617595a230e0a74a3db3b47cd27b941e02bdee9a84cdfa8eaa63a55941eb5caa79e20fb69726a4d46a0e5aeed24039f8c5a20679a692df0bc140f42558ca9a2b","up":false},{"one":"389b5c1a805f87427e6d647ec5488342a3f7d700615943d5ad98ca5c111f33c7ee007970b4d3e475892095c0d5a79b7ed52d12598398818159000d4b9b719126","other":"4ff66e9b5d3fd345990bd7605bdc222b78946f0c13b72bf80352812b2426d8f1d36c93e6c8713566004615e8a78ecab12ab0cfba254c0967eeecf8875b25bdae","up":true},{"one":"c665a6b1b7ad39b86bd4b1fe38b7ee95a0fbb1db15e91381ec9e5a235e33b69ffdc92c60dafd74b7b4dafca1b000e9274bf045abe5b93b1a9c2b31ae071a9898","other":"7aaf7817b93aa6d2f50513791f9ad7629a901ed0dcb151189f44763f83423446b20ec79a48fa260cd9bc2907d5f0ad06b2c4c5e6d812f3d8876c8020ebe41019","up":true},{"one":"d3105ede6c21bc643d523afcd1309a5dcf03f70797a92f167c3a19f86ae98882fe1a9d4094d7a3dee4a0833b8075b6c3e9aaa7f4879dc47bb388c3ae85522288","other":"c73d088ade8756c74832c73542bcdb3e52f670f7a74ad3a7eac2a9e3ece6bd081f782a8e1d3f9a40b9aa9201509110f37fc57fcb10ee1ef3ef07b7eab019782e","up":true},{"one":"54b3c57a4adf4dbaf31b85ed1b8dccd6249faa16dd96dd230189f47f57970caeed36627cc8e1b0794707418d580f5bd6001c07be6a79216695f1253db24926bb","other":"6b01079463ec2f649db8634cb7a596261c79a8f714d954c772528e0547b017f8ce405e4a0ea9d32270848180e0f77b8c0b022cf95c85e777626edd4d24ea21d2","up":true},{"one":"a08e47137bf611dfbd20308a22bdd3ca00121386f121d6d712ade86e9a1601a4237766887cd91c8516e20b6e323d2ef49c1c7e177a0afb4c813f0f344daf779b","other":"8f88c7ec044f758f29bd8d12a5170bd973aec8f6cddbf512b910c4b75a0fec09c5e198bcd65622037f897759db68da2328b4a7ca93585dc9cb62e46d2a6c0864","up":true},{"one":"9c30ad8c85adc7bb52ddcfab2e661cc3a854a689eaa59128d35129d02cd5b0f8da4a44cdd33934a8e2c8fab1760c16d6f2e1c5eb227dc819e85624e63343c069","other":"ea57884dd42aec5a76eab43483bf7c4ae2c19eebf365013731de64494d10a3b4cfe34c86c79437f9012bc8cf6bd761435eefadec17600f4b9e4bc234532d6282","up":true},{"one":"990b1db3ab1390219e8866d39fa4441bb5bb89ad786b3e255771869fcd08906dcf63f34007481769c7462edbcc665acc0a552e3733360b8d8c310c9321a5550f","other":"8f88c7ec044f758f29bd8d12a5170bd973aec8f6cddbf512b910c4b75a0fec09c5e198bcd65622037f897759db68da2328b4a7ca93585dc9cb62e46d2a6c0864","up":true},{"one":"5df58ba12334a1b4f983d642fe435901261767cd81f8f37c43e359f5584664e4d287e8c2275995604a3b3a4823418e35cd899a3db2a7db31570e19512f375481","other":"9b618ad34d0dfe0fccbd5b8af365cbcdbb43e802df5f23e91c20d21f3ead6169d52bf0db7e5e111abef630c9853419fb33a88cf111d8507b8708208b5d65e35e","up":true},{"one":"e67e495385e7cacfe659b40d1ba94d4b1ff55eada70a4d9740a9e452fbf221672bd0a897b940e2a6bed71e2a16867fe45bf0ea0015435ac6d815690e263b1899","other":"9194a3a4c8f3235203e48bdb10902d958d26c342805ea6365af9711213536509719d917c694f9a4fbdde6889a4c92299a5301f0275bda4dbcd2541b5bff5b271","up":true},{"one":"732393b99c490c76fa45e3e404ee095f2fa445fcc123af7ac8ab1d2fdd7cf2483f5b82bb818bd8a82b1a3b73e63bcc2c83d8f24d9aad9afe36503735e7967be7","other":"eab86c521f8f1ac67c015ab713f1236a08b0200757a96bf87ab8301e7967ae62361f0e14da14ca294fc8cb3b4726b52f4773101e21b032977c6a647241b59c73","up":true},{"one":"e2e0419a41bdfc5bd76deae2ddce6ac865f886d764c9bd18799b79fa3b2b6ba66d765d26da2037e98317e1d7e8232a61e63c1d0cfa98c9137424151b46e07171","other":"abd8f5a4d700c06ec00684b23d2d25c4df1a9554fcfc57b0ddc3fa476e6a699ba75e1213449f900803f83ab8194c6746664b547202047f35b8b3e216c7147bf8","up":true},{"one":"0b7e1e5acabcde503ad827e45724402406114a513f81040a379b0f82df2eab4456b348b27936369c49e3c264d971c6a9e2c2217fdbc5e5b93ac6fc219957834d","other":"b6a998dea59194cc60ce97c7c9702368411889cb6905516b23f41cc5116fba8d0f237d418318eb0c333cad18003c0e9a6bd8c99080520771f2bad640e2e5ec1c","up":true},{"one":"57cd4c0048b459192ee46e19ec7df777e600f256e0dc8c3019431eb7bec3c020b9504ec7aea3dba8188658ca5b830ec40af6a8540ce10e04badc6c695d009271","other":"7aaf7817b93aa6d2f50513791f9ad7629a901ed0dcb151189f44763f83423446b20ec79a48fa260cd9bc2907d5f0ad06b2c4c5e6d812f3d8876c8020ebe41019","up":true},{"one":"70ee3c7e02a123f78345d41c386e413f06b51f1ab346c2c472891eed7dd26a1f14e213a0f4f2d872859b9b535936a6d9b072d2604456f76221a422710411822f","other":"043fe7085e8c90c18270f84dba5fab138e50216a1cf8d81a3794d156fad7fc81d1422aff169b244b13f91d73eebb5de464f97b1b93b3ad2a58959cff19238842","up":true},{"one":"396c703d27bfdddf91761f134cbf665fe61e0b3a5d24036a4105a625f72e8c28b821e9200f20d6e8f8b3ed6b95bda6b8accdd840c2f786720b7431e3af2af981","other":"3b570117addeec03c2694baf28e246f91907268fe665c6c90356120332794258ee57a60853c19e9fe25d042ca42a5be7fe0797d84199174de8132f1ef4a9349b","up":true},{"one":"5eccdbcb15ef42dc96abcbcd8b8db75d9230de10e3c650620737f6cc04ba4fdbf59ded5daa801901c191be186c329ebcd37ba83bcf794064ad4e11bf10d3f775","other":"f039df8a3206e6e17eee8e95010038c450cb4cc0b5580ed5795d4c21802e1e9d360f4528bdca794f457932b1d6a818862ec847357a861c488332ef6d9480daa6","up":true},{"one":"f33d1f3e460574706ac1c7fc9ebb4683b173496ce3e80017d1c3521bca03d5a41a9c7a6cde8347d2238917b7cc58cab000ce7ccf6bb408561015a2ecbe613408","other":"6bf9fb6a25521c16c2ebeb6203d046d7dd40f29cc2ddb067c0222ef56d7012d2ee5d037f71f6668ea56767610b2a54c144aed74b7f68d06993cbd52fa1dc7630","up":true},{"one":"4e95fb8943ef6502fa470870a7ace4ca11e18589bd2073167543a922317b35e40b5068934d07e56c8fdd23354dfad51fd2899db854f189841f02b5914cd97749","other":"7e2b0b4f3b55e97bd7241b984ad117af33bf3baacd22b3ed503a8a59f75828df745fb3ce3be4276d83eb484e64d9aa251103fa994ef119eaddb97a3503b9f292","up":true},{"one":"352407b42726dcd1aacc46a912ed8124b8b6a3da4e33dab742e40aa2452953d35dc8f42eddc76695ae2317e9f15dde2cd21be4ce826934695ad1847455661d1b","other":"f6ca39b3ad803e99f4e4e9cf759fff6abdf06e6972bdbe524f6eb930c669d6f0e9b91f3de9df394b0d661b068273861391bdbac948ad911351c48cf02f874db6","up":true},{"one":"7bbb3f3ed51cf84c077806fbd6d3578e105bc32aa6043da188793f066ad6df383a9f7cc0bd3124f4c887704bd188d480ce264fcdf178905bbda3b270927ea138","other":"2f1967b4410ea2ea8fbaf46771ba82c2846d00aecdb6f873aceae33ab38f72d0a2c2dc6046d3034f514efd090d42011d48e9ab0cb4e3caa2b49a96ef732215a1","up":true},{"one":"e087230634f556b818a416b66ba3f1d1dbe3e0dd0698bbb26fa86a2499acd169466f564dc18adf2f9be4d1ada0e86c11549754097601e10aff4f3a57ddffa24a","other":"0f9f7e2dce4ca266c3ac0ec3a8854200b54487f5308e3db418461aeb5f67c81d332619b6441b468e480941e63100ed1b263e7adc20689dc3dcda578bfca538fa","up":true},{"one":"92d6ef729992f0de886076e5f8cdc42cbbd70b29e79c25e0b3d22b6575d3d2508d47b42f581e335455483d43625bce4e55f88cab9ff2073ee8dab746357864fd","other":"84abcbc7b5598ecfd91ceace0927921a5a3404fdb274fc2a2549abbede5f8e4f62c15688a4dc9a2d80262c45970c88898da245c6eb779f327a81d53a17bbc74c","up":true},{"one":"ee36d1d5dd69fd30242d7da2e941b34ade5581c7164fcc43288ecfc52937a98f1b31ade5d1e4dbf611cbe1c7875b2840c89435081cde471c271d7bc60e9ef211","other":"062e0ca43a1885c4a7ab2a5169790f9081e3e9a2dfa286b8cc592d5ccbf13d7a82b72d23361a19026d04fcf41b752ea320d98359d770aedfcee626e21c3494b3","up":true},{"one":"155e4879643a472420012e040a87dbff776fc1976814c0c6cd0d5e157f0d0baac04aa7f2535786c09acc2700547383d2119b64a6f62115f1aff1708738844d8c","other":"4f5ab12b9c5127c16739ad0d4f51adce90ba6736cd096eb185ea632789f4b26f1ebabdea4fd3b39dda5409ece6c2d92fd469cf4aecf9d29453e3e042c19b893b","up":true},{"one":"81288bb0584b7ffc1546043e052e1df10fd5371b35dedd0bb42ec5b30ce69b741b2f7857af5984d4754b39d7253575fde9298504999b78380ef602d391c4bb1d","other":"1d0244a13affe60996fe3cf51ba624adc746de0c7ea68ec5a31311a36077c5b5495e3d95c9642875db44c7ecae6ffed22e45f2e2d024d486760be2af9f4cf2cd","up":true},{"one":"d7a319f69013b8375e64d19f015547462c84565b882337998f9e669c5fadd3d2ecf6374109903003e09f5d453424b5c7fdf52163d2cc8084cf81f94844946b63","other":"5bae82d4832092c17bd11474f7748015b8b69b896ab8f683a7c0024fc98740cecbb9e31c6275269f9000e5bfe51d7f45cd5dcd4433e0c87b5741685b40fe3983","up":true},{"one":"329145e75496cecb5f5c8f00313a52ddd8c0e8cd27ef1b2bc1b2b56e4d4089aaf5a7a3c4d9a40bdb92483fa05bd24d1cd0fd51883e30439dffa0fc855e1a7cd0","other":"1bc1d6155ba35d29ea16938994e08df76ebd8f16bd180bd6a9b9d8798d0745889fe72d641dd78bd8ec13526929f7eb5aaa6a388430fa69033d6db581e53c6422","up":true},{"one":"ff6f94005d1df7677600069764855c1c2aa0543cbe9f480f8feefec76c49d9e2c7bb2d8e38c89e9430f53f8b593d93f143c45985a56a5a32c736128214c95eda","other":"27d9048707a89f1a61e44fdae523c0128f2a7050308bd3cfefa6c3e03040a0e22f11ab41275f22b8706e6695ab93320e2af35179d772581db5f49f960750f2f7","up":true},{"one":"11d560045536e9d1b0b1b9e8944e00f0ca7f1e6788c9fdb51061820bbb3008ead92bb7836621bf58da7035c87a28328faecb4cb2e3cdb9d7fa4f45790e6bf352","other":"453779010ed7c59761da47ccd8869d3fa8349795e57edb9eea416c0712301ea622c7683858e309d19ab137ddb0edef161d0d00a361abeecf0628c3ffabc629ea","up":true},{"one":"3dfd733dde9414af916625ab981777ff1ad7ca0f6d1e4e7d9e2739969e21182fd13d85e281868653e7325b20069356b11524b54143c47fd3955a911cf7325ad4","other":"caaf695c76cf7c047d3f3bfe019d01618e4871cee8ff3f347913da815bbcde145771486f916a44d03f59ea9bc217f169fd0c0765fda3f9b9b28d02a522e180b4","up":true},{"one":"deb7af800cd20a647335f0feff5bfb3e182f99f4c2d1ade10da36ecfdbac3b5fba4e8f0a4595443fe395b44af3a95617669850944655def85d57cc81c5682a3b","other":"2ab9513899c3c829b6284e56bf2b9862dd0156ec052b58615dba77d450dac642e534ec36ae5d3234262aff54e19f99856e908b9d8c1da660a7834a445610715b","up":true},{"one":"1090e9d89cb278a30063a5396d9ba795d3bbc237c76915a6fb7d23aa1822c8535d2fccc44cc8cd2acec68444c0bf1bdf5195ebb9f3cad8dac3d94a4d9c0e5309","other":"8ca3b63cb84f1e9883d82809a9b6777ec1029ecda96fe93b4d494ee9cbefcad13f381b3e480136e542e01054fe1ede66c65db84a0009871ce49383db461c8438","up":true},{"one":"94088fe273f76e62ca4e43c095ad12215b4ae4c59942328b3985416fb19bbda0cacc143a49eff3fb644ad53a19d3f043260e43dbb70a0aa9c15829c21cecd3c7","other":"5bae82d4832092c17bd11474f7748015b8b69b896ab8f683a7c0024fc98740cecbb9e31c6275269f9000e5bfe51d7f45cd5dcd4433e0c87b5741685b40fe3983","up":true},{"one":"6ab6ec15635b2fda22542c99df0a3313ad4583ba0fb3f31b8f314e3ecad446d3fb0fdfcd2be9b08374b1a7e049fb68e69e8dacdd13f1df5007a656f6b11adc5b","other":"5bae82d4832092c17bd11474f7748015b8b69b896ab8f683a7c0024fc98740cecbb9e31c6275269f9000e5bfe51d7f45cd5dcd4433e0c87b5741685b40fe3983","up":true},{"one":"71f89efcf939294bb94ac669c8afd00def58c8dfad519c226adfa068692d588ef797116d42aa146b9d34f3be35ec7c014022640ab3c0f1f9034e44ab1a26e246","other":"0a4eec7b0e05da799aca5b36d9e2530f2a89d1426b1fcb7d8f9a662df8a8b5b763767a20db3c9c63e0bd13c2a6e16d3ba8f03baf84f5e5d24917b3f211d9bcfc","up":true},{"one":"84abcbc7b5598ecfd91ceace0927921a5a3404fdb274fc2a2549abbede5f8e4f62c15688a4dc9a2d80262c45970c88898da245c6eb779f327a81d53a17bbc74c","other":"535f93057d46c4aae0902546550880be0b5ba67dca12350117d471d67f4f2b3f7bdff29bdc918767974c465df8fa1afa6bd6c29c0a36d51f71c4183673d906f3","up":true},{"one":"7646d08b3e24183e3814de130235c41eb88a5a2abff23eaff3c91954ad3ef55fe27da422dac5b894312276bf1a2f1aebb8b636a8d4a0c93d9b016d441df3fa19","other":"72e30d4562673c5c8fb03709d93f73322747858d723b7eb5ef2fbb88e0331252946b7e93ffe434fcb599c4fff57800afb29e6c60a719f18f49dba541c3591c6e","up":true},{"one":"b137cf2291b530a39516d882200848e7f27a2710e0839b4d25b4f367bea6a0c3aaef8c7c7851c00a2945adcd819ea0508610afc1f453b8bc512b7b4d4faacdf3","other":"8ca3b63cb84f1e9883d82809a9b6777ec1029ecda96fe93b4d494ee9cbefcad13f381b3e480136e542e01054fe1ede66c65db84a0009871ce49383db461c8438","up":true},{"one":"db8ba71afeaea1f2964e8978a6eceeb9efa3958424424022213c8193443f8d5afd18490afa954c76360c681404809c7cfaf7e4ebd8bd1a42d403f7f1915b0d29","other":"baa5924e1547c177011285d292aa161a15e5ff282da2cd0afb83c9caffb07bdbb3662c227fa7b26e6dc8be9b8863e647eb5f8ce81640532f8f5c9a7f36557e63","up":true},{"one":"baa5924e1547c177011285d292aa161a15e5ff282da2cd0afb83c9caffb07bdbb3662c227fa7b26e6dc8be9b8863e647eb5f8ce81640532f8f5c9a7f36557e63","other":"5bae82d4832092c17bd11474f7748015b8b69b896ab8f683a7c0024fc98740cecbb9e31c6275269f9000e5bfe51d7f45cd5dcd4433e0c87b5741685b40fe3983","up":true},{"one":"ba21a373781966135d6225adae024a3f3e421b852f72f8b0569cb92fcff87c33f7e5b799a509b8eff6ec6dc46a9b17d5bae1e91ec7c54c0c712d893d54b140fa","other":"deb7af800cd20a647335f0feff5bfb3e182f99f4c2d1ade10da36ecfdbac3b5fba4e8f0a4595443fe395b44af3a95617669850944655def85d57cc81c5682a3b","up":true},{"one":"48a5e01e06e297dc1c640ac9601171495bd70fea461c60e7e6e2532695e45fcf68183c2e58b5e6931a6c1c094f5331efbd7f2d93d5f84efdec5a35afa2124438","other":"6b01079463ec2f649db8634cb7a596261c79a8f714d954c772528e0547b017f8ce405e4a0ea9d32270848180e0f77b8c0b022cf95c85e777626edd4d24ea21d2","up":true},{"one":"57fb1bb32bb2b1a87e44c6a7557e9c47c2032d107bcb0e34acd9ffd54d5d3df5701232db16f62f7549ba2721021898b03160b1dc5201e79606648c1dbc4a373b","other":"24662a43944228e4ff74736bcf0a0a4f79c87ecfdb739225b2fc45110c11bfc38aaf2d09d98e5817477848e553f187ac5408bdb864518dfa7f5df542768828db","up":true},{"one":"f9ffe87c52ff4c22bd9696af32e0a9d34bb81fb84d9d8bf5aafe2ef9696e7b3d6460bf2a93aecb066133f53416bde841a02d6967bd06e3d4a714f3b2c123a947","other":"e06a789a7f6988e1ba5e8358b6cd4292555c7f9f7f0dda6fc01cc26d24e49a8c1ad694423ad74aec6d80f4b99e2bedc49b6a5f2670744cedee3a3e1848e6dd07","up":true},{"one":"3e488a7208ce0e097ce47fc6651a13e95cae137d1a054a09b04d2f59d45faa2594a8c3b395e77ad1a3c2edcd827dda73c0c97dbaa6d9519a79184a0aca01ac4b","other":"a127faa19dcb7da585983d36a8e9d3e9a44a6db68507b60c70da71011f44ce377944802f39cd65f5a705cd8249ac1ef7ed8fd699349098f3f8e23b37592c80ae","up":true},{"one":"c2705ee7238ef9305e4da196653cde707649435a1e8b5b797d164e5ca06184a77af5bd7fa938c995fdfcbce724fa7eca3d908ee34891ab62cc6dfd411c3fa1da","other":"2f360209383d6de4ebd3b4abaf77796520b8654270b03f2151eac4a01b4417d7e0668c1f9ad30c20ff49aa8a0ab33dba5e6095619d1cf04b7af841722ab773da","up":true},{"one":"4fe37f2dfb03707c90a6fe91dbcfd7497db70ffc20043091d50e1cee573210c144e8749340f2c3cb70fe8fc51b317d49e8734dc51ce64b3cdccdd639ae35d1ae","other":"0deda014fa3c0bc8f37d853e1448f95f56f97048c28797d72258fd3ba2f1f776ae11566197466596356cd172847ab02a89f4cf047e58383249fb2a4cd69b6206","up":true},{"one":"c8b0dba45104fc7c7dff3ce078a0d3f5ade6198bb4656e2bee8076387929133e5ef2bd293b130a9d4f6a6974ca17e8b4a8f406d1219880f1e0f99c65c63af5a4","other":"9194a3a4c8f3235203e48bdb10902d958d26c342805ea6365af9711213536509719d917c694f9a4fbdde6889a4c92299a5301f0275bda4dbcd2541b5bff5b271","up":true},{"one":"65e954e60837bda10654480b227fa3bcc6e63356c52079002a27e836cd82ae2934ba77da60080e4b9f2d9324b982b24959bfd9624302e6c330408381054b43e9","other":"7f357b8d81bc2e5c6fcb081f23a42b3e2439f050d45c45851994a268d1c71fcb1f39f8c3f75ce921d3fbf80fc0e73f0b9609d72001dc4a6b65b526d312a4f43a","up":false},{"one":"7174eca109a1f717653918224c8cfe1b7fbd666405196760913593401eb79f2c7e41003b01f5a458940695b27a4673443c7621a169db7fd968994e552995dbbb","other":"7554993f6efd8d9016ff525ae73c41ee2e0dbd4970c563ba9b61a99c1c8943b433c4b7d48450f6e0fbc9ac198d907698093de20e6c1f7755520fb1e1cbee4eb4","up":true},{"one":"b080891d4ba6d3ab224984360597f9c555bd1367630f5420bfaf230419a05b2be58bebf1554e53eb4c0da81cfb66d4f7697dd65143f11841ff62d8a0d82b6b67","other":"f915e2398aa5d4370de87504dd76c21a7d0be2581c2ab55b7a47743f1bbaef36384eaacec22760f1e914ceac9d96a10c3d66eb27475ef444e77fee979e6e88cb","up":true},{"one":"cb310c0e86aa455d7c9af6394ae38561c901da30a51d7ccb7e66a09d9a8f192ae8caeff106043426d56397088f141c4e01e3b98f1ee583ffc7318b5f730f3ac7","other":"a99852c5bf08ea4713af9cade5343d1259bfb90401aca7fcff18c58cd56a98804dd16c61fea71039c0ac31b9bbbb9dc5aeaf0c2f074d3365e88d17031802d636","up":false},{"one":"b597c9ba4da20c49fc4ba019571321d2579588636cdaceb9f225706574970adbf4771dcf186b1decd4e14cd5d257e30a36ca829829598c1775902201ad9793e2","other":"7e2b0b4f3b55e97bd7241b984ad117af33bf3baacd22b3ed503a8a59f75828df745fb3ce3be4276d83eb484e64d9aa251103fa994ef119eaddb97a3503b9f292","up":true},{"one":"22010c9829626a6892258b09cb3f3edc3f21382fb487b5dbf0dd20e198e37e26134aab850e30337f398d1491b5126839aeb1953ec144bc19aeb889c832f67c6a","other":"c9cd9dfb9f90a7948ac5a42c7bd63263f2eef6e1d85547559f7d2ecbf5f9cd1eab051b8e9e661b573c275d84091a44e73f6fc6bcc91dcdb674bd5d939190fc01","up":true},{"one":"76cbf9fc0f3517fb615fa96104780218e85d064ee5a1d518f3b78f4dbebf144df38c427445fdd6c9b436489c00ff9497d747a8fd70f380f95601d59e52e021e8","other":"0cacda5560faff9d20e29a0625d3cd340ec075f198a50ab8b79338cee0e0db84c7c7e71042fd8c8f73e507b570de5d26c39473136b575f0167625a1168309ec5","up":true},{"one":"1c2f7ce55a6e38487f3b3fe6083a79f914cd6d7e4aee8f5d56b4a61b3eb584e128c56998db0e13e775edee3adacf54f09960a041dab3daa80a4f8a3b42760c1c","other":"baa5924e1547c177011285d292aa161a15e5ff282da2cd0afb83c9caffb07bdbb3662c227fa7b26e6dc8be9b8863e647eb5f8ce81640532f8f5c9a7f36557e63","up":true},{"one":"1b6cad4f9851cc584c5d1405f976bb51a52e27ef4525847df543dcca65ca5eb1ef229dcc68ccbaaf00ab1e044cb5990dd213c805bdb4adcceb6fa70b5c61fdb4","other":"2bfba66ec9d63e928d77d455f2e10a14d6213e515099d5db14fa44a8bfc147eb0fa7afa9aaccdc86453c6903b55556059a2e13dd61fc494127d4a3ec173bf9ea","up":true},{"one":"adfba6d883cacbb141cd8c59ee04d7e5d520f1ce31a81e5db2d8b2380bf801c1fe4b265a66b71f9643d13a41cb1f6fb4b83399be786da4b6e171b6784bc56e49","other":"453779010ed7c59761da47ccd8869d3fa8349795e57edb9eea416c0712301ea622c7683858e309d19ab137ddb0edef161d0d00a361abeecf0628c3ffabc629ea","up":true},{"one":"460531928a4b084686343c8464b37c3452bb3566045698d08a4692864de5581a9eb1dc632329e7d3ccb73ec31ee7693787d69df8458efaba9a7105d87ee2e053","other":"083e67bb19e30d14e4df6d2483367d6659d9b56744d53d9cf7fd15954c327e1bc88a5d0db8833634e1dad7209164451f8934b59f76b5990059261abfd650519a","up":true},{"one":"58cfb20d3da3641e0ad529b9edbd4b590a8d1dc9d1ed7b44ed3187dba9260bd7c732fc10981f5b9bffd31d362cb05150173618aa36138984431d94a323a9b313","other":"ca1aff0d847c6fdacb623ad9078a0885b3208614fea20d5ff11779779b486bf5e9c794aacf848d3c2d58cfcc1eda8356df82f5fbdd0a5236beffe8e6042848c4","up":true},{"one":"657d5370319128d24d925b41065eb619409d63ec6280975d78877a4028287463f6442f5206dd703569a05b2b542ad8bbb99803da265408208d6356a26d283d08","other":"68cc8b9a995eef6170abf88bd5fedca06ffcc8d75f247f6041c13e7dfd292727ebda1ff86b776e33b6634355c55e0f8c22fcdb5f9a6e2f22fe1af7854c3b4273","up":true},{"one":"62dab8b21640e1b44dea452dd7e7de93f27a44840da72d56b11aa96e8463f3a4bb15e75a954d19fc897ae0030b16181d271b79d8198b7cffcddaa9ffcfdcce73","other":"d3105ede6c21bc643d523afcd1309a5dcf03f70797a92f167c3a19f86ae98882fe1a9d4094d7a3dee4a0833b8075b6c3e9aaa7f4879dc47bb388c3ae85522288","up":true},{"one":"beec648d79437a5d7b4140ced45d82d035c6f64f9c67c58386703811d97c3846787eaf274d2298df809475f0b7519df696563cb8e9a5fb0a9cc419ab13fa8d41","other":"57cd4c0048b459192ee46e19ec7df777e600f256e0dc8c3019431eb7bec3c020b9504ec7aea3dba8188658ca5b830ec40af6a8540ce10e04badc6c695d009271","up":true},{"one":"7b35c856916eb3fc1b1f451667e240b95aff8f4731cc0f6743740923081ff1ddf2eec81bdccf4691a7bcc053d23eacfc15809c384a73448f618317bf605bd1cd","other":"c665a6b1b7ad39b86bd4b1fe38b7ee95a0fbb1db15e91381ec9e5a235e33b69ffdc92c60dafd74b7b4dafca1b000e9274bf045abe5b93b1a9c2b31ae071a9898","up":true},{"one":"66beee3968dbcf3addc6feaf070a4e3e82b5bb164fb72f40add89f732c12e8d0a31a7ee1f1e24a4674e4dfc9a4912b02c17ce3c224d257d78b7156544d6507dc","other":"663535b22018a4ef0b151572ef286fa66c22c6e9b2913a69c4a735d4b0149bdf6c84bd83d710f8aa2627e8993b7f020750fbc6f56a3365ce4c840e2b3de1a6c1","up":true},{"one":"be026dfb24847cac2d00f483104edad06ca8ecb9e1229c479ef5650c7b427cd5dc34a1cf06172c17c9d0406ce17009712e82446394743d4cd9bbc41c537ebc14","other":"7acddc7fb6ac587b7e343804c768e4291cd28dd2b2b9207dea6ee82360d848a52d84f94e4c49e9c421f4f90e2d24f6291e2358783ab0230e6ecde82e69b4ac52","up":true},{"one":"0c14dd51a56130c51009e3ce47c96b2afef26b7e86cfca65d8a9bae1abef13b3a7a192b422d894c39e24ab00be412d166a3571cc259ff4462d4ad8925a153766","other":"f6ca39b3ad803e99f4e4e9cf759fff6abdf06e6972bdbe524f6eb930c669d6f0e9b91f3de9df394b0d661b068273861391bdbac948ad911351c48cf02f874db6","up":true},{"one":"e2a27dcdee1f89fa362a85c4397840cd8be4ad8d1b9ccb23188c303bcab7619f38772f71385922d090390973b62fb8249efc103f71bc761041bcb3880ec0b935","other":"302c37f28c69fdcf00b39ce0c0223de0d94cebc2c0b068315b95b76b5432573ead0656569441029ba9054d8d3d959fd8735e73913af5ce3f1132f8271fd437ef","up":true},{"one":"aa9a94d6e4eaaed20113c21752c224e3a052abd3769bd6e832759dbaf5154a943cf094eacdcb0727c2fe51a11bd7fc0793d7d5e3312b0aba89d428a00e1fde0c","other":"f9ffe87c52ff4c22bd9696af32e0a9d34bb81fb84d9d8bf5aafe2ef9696e7b3d6460bf2a93aecb066133f53416bde841a02d6967bd06e3d4a714f3b2c123a947","up":true},{"one":"fd4968df03d767a223bf7e4dbe26b5c27048298df40e81cad50b344fb3e6837965f2646dab7ffb2891a5c507343ed84bb8bbe403287b51dae538d58fcb6e7623","other":"92d6ef729992f0de886076e5f8cdc42cbbd70b29e79c25e0b3d22b6575d3d2508d47b42f581e335455483d43625bce4e55f88cab9ff2073ee8dab746357864fd","up":true},{"one":"f915e2398aa5d4370de87504dd76c21a7d0be2581c2ab55b7a47743f1bbaef36384eaacec22760f1e914ceac9d96a10c3d66eb27475ef444e77fee979e6e88cb","other":"049a2b0ab4d49789dbbe1837e2d2ee5220a9401729ea87ab29385b24d79cdce255c3d2b5de6484d49ca6ce07bd41832598260c0a8c290e01d133d77f066f2f99","up":true},{"one":"17917fa4da06068b587c17899569dcc768b9cd2c27117a4ed67aab26a7e70cf8d32b881db258061ffd89a332a3b29bfd963d8e171a06c3e208ba0de1c42a2b39","other":"bd1a7c63fca9e1fcc67d7fd62670beefe2bce483cf1dc1233ee85eb90db607917cd9a5d7170b10e80b925a20e2af2c54d286b01805ac34967410859f4f03da09","up":true},{"one":"e06a789a7f6988e1ba5e8358b6cd4292555c7f9f7f0dda6fc01cc26d24e49a8c1ad694423ad74aec6d80f4b99e2bedc49b6a5f2670744cedee3a3e1848e6dd07","other":"292c78c8e41606e98428096bc6f4609a7aa48e5c4d17eecc64d65faae4a7270b0c15f0cd74274015688ea0a9aff34f215c29118222e362a29c8d637963973a55","up":true},{"one":"f9ffe87c52ff4c22bd9696af32e0a9d34bb81fb84d9d8bf5aafe2ef9696e7b3d6460bf2a93aecb066133f53416bde841a02d6967bd06e3d4a714f3b2c123a947","other":"c83985973a9564ade7d90aa54911ac57077600676a1d27292d98e058bf1315887bad84ccd708cb7f52a695a1405fb7d491d7ca2ae9caa3ff58a5ad78ce4dc9d9","up":true},{"one":"c83985973a9564ade7d90aa54911ac57077600676a1d27292d98e058bf1315887bad84ccd708cb7f52a695a1405fb7d491d7ca2ae9caa3ff58a5ad78ce4dc9d9","other":"292c78c8e41606e98428096bc6f4609a7aa48e5c4d17eecc64d65faae4a7270b0c15f0cd74274015688ea0a9aff34f215c29118222e362a29c8d637963973a55","up":false},{"one":"2245f3bf1a3b4e92f912affc75f757cf648b20474c11ffe947884f216b8f24f9dcb6e6a0358a4061b8517478ec15027e185b2f05a777573b4940375bf4aaf2be","other":"083e67bb19e30d14e4df6d2483367d6659d9b56744d53d9cf7fd15954c327e1bc88a5d0db8833634e1dad7209164451f8934b59f76b5990059261abfd650519a","up":true},{"one":"8dd8ad560af84bec579cadb33d51711aa61b6ed22705010336df5a71a94591173b25e869457429c4a199b205fce8e73530e28203e18b971c2001715e610f152a","other":"f5c1215a84a56d52f92ca0dc3a32df98c98a9c2ea2e9a34560210c16de1b440d20d043c8c25955dda8c22e55e92ddb49fd82e8b9b84072aabaa755a229bb19f4","up":true},{"one":"9db1f94d74a00d1e5e2a391f1bcddf16b6d0670a2c6d91d946d38112c58634444b6fea8e8c05ab4b73bacdd62a0b575f6fb8729978edc216c7842b177b9f9cd9","other":"a1560ce7c1f1d5972f027a8e9cff820611d84764aa067434a75b63887bc4268a259101486d34b7fe83dd735e799789986cd3e9b156c86ede598bd86af4454924","up":true},{"one":"be514f5f17f3177235acb24112b578edf0e373c469073226e547d18080905fd062d572be18e943f13bf9fcf5871e89ceb630a1b848a0e370ef8ef8c6d997a363","other":"352407b42726dcd1aacc46a912ed8124b8b6a3da4e33dab742e40aa2452953d35dc8f42eddc76695ae2317e9f15dde2cd21be4ce826934695ad1847455661d1b","up":true},{"one":"759f46661056bcbb30c7706c9fb87e22a30feb523bd53ae5d18db043efa45b49a2b8982abebdd598fe0912a05896390ec2eabe5e160cbafc0771990708ad8c28","other":"abd8f5a4d700c06ec00684b23d2d25c4df1a9554fcfc57b0ddc3fa476e6a699ba75e1213449f900803f83ab8194c6746664b547202047f35b8b3e216c7147bf8","up":true},{"one":"535f93057d46c4aae0902546550880be0b5ba67dca12350117d471d67f4f2b3f7bdff29bdc918767974c465df8fa1afa6bd6c29c0a36d51f71c4183673d906f3","other":"a99852c5bf08ea4713af9cade5343d1259bfb90401aca7fcff18c58cd56a98804dd16c61fea71039c0ac31b9bbbb9dc5aeaf0c2f074d3365e88d17031802d636","up":true},{"one":"ce0a09bb6fe4c9c93c3dbd800ca9c9ac0714f26a8f8dac2149b6ce7a9011912a5621ea2e45de35c4d31dfe5add00558fdba5dd21acf2d81ba391e82b5b3a5804","other":"8c6d77833bf1a98beabe7a92d985d13d52fb2e50768719ffbc6fce21ea676802a074b6e620b3ef80e12fad04f94a3c288d91df9716a6cfae09ef073b9dc1f2cb","up":true},{"one":"2ddd49fae11d8bd2e7e75a481be267fa846f51cc1160bc326aeea51c542323ff444909de11e2731e835140bc0b1b32020e1e73fa652511a381222bf0aebc4081","other":"76cbf9fc0f3517fb615fa96104780218e85d064ee5a1d518f3b78f4dbebf144df38c427445fdd6c9b436489c00ff9497d747a8fd70f380f95601d59e52e021e8","up":true},{"one":"b35f418c7935cc54278e90978c3ef1521ab91daeaf9f1ebc1cd25211611ade091cac4e1f009d71059279d507322a4536501980ac0dd44caddc52fd4c593879f7","other":"59b53f8a562bee519276e0eeccfcf8c975d3102f5d0cccf5abcce291a8a5bb817c04604f123686177a50a03b9d7559ac469962d0159d1d93e4ce58a304d04b55","up":true},{"one":"aacff366e601e072a2113add9020e19b6612f3e85b6e607fdc8cc1b6991f43be0b1f835ed3dc41d1f2b3e0caf7fac252c8eb4c150667d48207fa92ea5f0a7455","other":"f33d1f3e460574706ac1c7fc9ebb4683b173496ce3e80017d1c3521bca03d5a41a9c7a6cde8347d2238917b7cc58cab000ce7ccf6bb408561015a2ecbe613408","up":true},{"one":"bcf8e831821a5bca359fb824c7dc4d66906de82f3663a0a853d96880a8ca0bdddcceb1b66dd1f13f75ee20fde50fc9de545bc25767f228baee910e0dbfa8cc27","other":"76cbf9fc0f3517fb615fa96104780218e85d064ee5a1d518f3b78f4dbebf144df38c427445fdd6c9b436489c00ff9497d747a8fd70f380f95601d59e52e021e8","up":true},{"one":"3d2df188704eeac09c8b291bf275a73888199a231c832c51dbc3d746968d4b51a7d5eae0c7c9b8c8e19f5e28d38c375e01abefa343f31dbe221deb837ab8a0df","other":"76cbf9fc0f3517fb615fa96104780218e85d064ee5a1d518f3b78f4dbebf144df38c427445fdd6c9b436489c00ff9497d747a8fd70f380f95601d59e52e021e8","up":true},{"one":"ea57884dd42aec5a76eab43483bf7c4ae2c19eebf365013731de64494d10a3b4cfe34c86c79437f9012bc8cf6bd761435eefadec17600f4b9e4bc234532d6282","other":"420b9c90584651c5a3fe3c16aa377444a321dca934f8a097d01a616554067feabebf2fdc8d2a25797f29a8fef30d5e2c82f8e85b20f509a880367b9b0ccdea47","up":true},{"one":"89a5b92a9ca045f12c35a70084e6f41f9775a25d6f105f8c9349c7b5e107179d8a96bdbb113b2680edf5183e9a42fd64bd7b29d0dc7797c583b833f869313699","other":"2ac93c31937ca205d61cc5c2a1b9037871cac55e9b306b999b28e19566b3316f6539455e014840ea50c2db8a7c97d78804d3a2dcd7cd9c1f32ace0d36e5dd339","up":true},{"one":"e6779e3bbecf81dde8b27d652ed2726c45c205db0d0405c4580014a4c91d739830276f77079108c98ac516ffa00194e77a0795f7140bdf36069b6475e58213f9","other":"6b4e376e9c94242b6d42688c22aa9ab418cb6dfb1cbca1c69de0feceec8d3af29fb005017aaa6e503cc0c03cf0dc5bcab55e01cd6f64b9efa02ed87c03020003","up":true},{"one":"acb4088c27ee2ee130ece3506596432afdb9e9757ec11ebdd35c5a6e87239545c48466913a646980104c8fd7a9a335e177f04efffe9dc952dfd7cd5c1bb9aac6","other":"f38a9d792173a29c61389f5d84c005d78eac6e750659aad42e2d6df883f04eb3126b2c38fac95076eeed455b2031aaf694143922aa93a2d50412a2454dc56e28","up":true},{"one":"a08e47137bf611dfbd20308a22bdd3ca00121386f121d6d712ade86e9a1601a4237766887cd91c8516e20b6e323d2ef49c1c7e177a0afb4c813f0f344daf779b","other":"663535b22018a4ef0b151572ef286fa66c22c6e9b2913a69c4a735d4b0149bdf6c84bd83d710f8aa2627e8993b7f020750fbc6f56a3365ce4c840e2b3de1a6c1","up":true},{"one":"b53078000796f1cdb04dfeac424d5e3e37e30f00bd5bebf9a9ea0525c62917612b3a8f508df6bea59e3c7e4cd1aa530841f9a8af54e44f5617a13dee2c6ff007","other":"f6ca39b3ad803e99f4e4e9cf759fff6abdf06e6972bdbe524f6eb930c669d6f0e9b91f3de9df394b0d661b068273861391bdbac948ad911351c48cf02f874db6","up":true},{"one":"9c30ad8c85adc7bb52ddcfab2e661cc3a854a689eaa59128d35129d02cd5b0f8da4a44cdd33934a8e2c8fab1760c16d6f2e1c5eb227dc819e85624e63343c069","other":"24662a43944228e4ff74736bcf0a0a4f79c87ecfdb739225b2fc45110c11bfc38aaf2d09d98e5817477848e553f187ac5408bdb864518dfa7f5df542768828db","up":true},{"one":"d9bbcdfd949010e6b2cbf6d0f34b27593ae410bdc1838876aeca35679571fe431d040a5ab085c0a77f111688bebed891da3587277cd794702437cb20d6aa4256","other":"beec648d79437a5d7b4140ced45d82d035c6f64f9c67c58386703811d97c3846787eaf274d2298df809475f0b7519df696563cb8e9a5fb0a9cc419ab13fa8d41","up":true},{"one":"990b1db3ab1390219e8866d39fa4441bb5bb89ad786b3e255771869fcd08906dcf63f34007481769c7462edbcc665acc0a552e3733360b8d8c310c9321a5550f","other":"663535b22018a4ef0b151572ef286fa66c22c6e9b2913a69c4a735d4b0149bdf6c84bd83d710f8aa2627e8993b7f020750fbc6f56a3365ce4c840e2b3de1a6c1","up":true},{"one":"5df58ba12334a1b4f983d642fe435901261767cd81f8f37c43e359f5584664e4d287e8c2275995604a3b3a4823418e35cd899a3db2a7db31570e19512f375481","other":"7ac5b07eb555af3bb4ca3f0f4b45204d43cc3798c244435909b97d9a32fc3abf0b50666e260e046bce826a7a102a92d389f8f39c5311e83bb34beddac29d50e3","up":true},{"one":"e67e495385e7cacfe659b40d1ba94d4b1ff55eada70a4d9740a9e452fbf221672bd0a897b940e2a6bed71e2a16867fe45bf0ea0015435ac6d815690e263b1899","other":"3612863ce0456c91785a829bf5c9d2b2fb97dda083a1847e5a4ebaa6fce1260faf4d1eb374c2225431a82774163835fb59c8cb0fa9fc0969eab5410c71109cc2","up":true},{"one":"b53078000796f1cdb04dfeac424d5e3e37e30f00bd5bebf9a9ea0525c62917612b3a8f508df6bea59e3c7e4cd1aa530841f9a8af54e44f5617a13dee2c6ff007","other":"6bf9fb6a25521c16c2ebeb6203d046d7dd40f29cc2ddb067c0222ef56d7012d2ee5d037f71f6668ea56767610b2a54c144aed74b7f68d06993cbd52fa1dc7630","up":true},{"one":"5526d86ba9df651091d88460a9bedb9cedb957d452a635e1db46b9fed78082022adec0047cd7485956a4ecbb0e18107595de0de3c35242527cd302bf74a19260","other":"385168340139236a0e0f537fa693122db9fa02a377c96f31aae54718e92624fc0288164877e63616651565e055c53f7074ab2fdd18a837da6faf644941305bf0","up":true},{"one":"e67e495385e7cacfe659b40d1ba94d4b1ff55eada70a4d9740a9e452fbf221672bd0a897b940e2a6bed71e2a16867fe45bf0ea0015435ac6d815690e263b1899","other":"b35f418c7935cc54278e90978c3ef1521ab91daeaf9f1ebc1cd25211611ade091cac4e1f009d71059279d507322a4536501980ac0dd44caddc52fd4c593879f7","up":false},{"one":"b4a5efa9028b2d196855393892f79993c2812d02b758f98813ddf82c5d943faf6d66eff811cc5a51936c118f4c768c0d13b54902095e040c602761e63c08655e","other":"fe62314839c93d2f6e3aee984d5f0b321897c6f39e66800d3de8b773baf6f19e0a03cae025df512aea8d5f1b667b6dbb15c192a90a76d3031c14e33e5c16c4f7","up":true},{"one":"ae4e21e1587a8475afd299e00ca7085c7bf2a44c2c64a3068f12223d9202b0125094385319034691ec26b497ec9cf18fe8c0839224bac1b84279410241cef979","other":"6c143960dbe3ba4c95e8debc1fda5f420a2a673eb46f7ff7d9a30f4cd2067e67ef8926bf17f0c99b16c79b6dc066b52409a11d47117d4fda4211636b1b74f96c","up":true},{"one":"016f8f4619a16a07fbde5a18e362158d696e4d9f104a77787f26e32a25cd7d278256f8e0db865c488a99511ec27a5eddd5ebbd1c1397fa7f8db111062e5fe959","other":"2ac93c31937ca205d61cc5c2a1b9037871cac55e9b306b999b28e19566b3316f6539455e014840ea50c2db8a7c97d78804d3a2dcd7cd9c1f32ace0d36e5dd339","up":true},{"one":"1944f98d4db32c56a5efda5a79aa5f276bfab1e084d6611fec0e735b8bc0f45b457cdb74a23fc83b2377821fa8316123c9877acd6db7c41058ca5d3cfedaecf9","other":"7acddc7fb6ac587b7e343804c768e4291cd28dd2b2b9207dea6ee82360d848a52d84f94e4c49e9c421f4f90e2d24f6291e2358783ab0230e6ecde82e69b4ac52","up":true},{"one":"732393b99c490c76fa45e3e404ee095f2fa445fcc123af7ac8ab1d2fdd7cf2483f5b82bb818bd8a82b1a3b73e63bcc2c83d8f24d9aad9afe36503735e7967be7","other":"84dfd4e4d9f1204893f190eacc4c3999e175c433f70de86e335d27477c097a0552f211a21764f01a708da4c9e9e6552191a61d3e48f41d0e84f01e7ae3beb34e","up":true},{"one":"3612863ce0456c91785a829bf5c9d2b2fb97dda083a1847e5a4ebaa6fce1260faf4d1eb374c2225431a82774163835fb59c8cb0fa9fc0969eab5410c71109cc2","other":"bd1a7c63fca9e1fcc67d7fd62670beefe2bce483cf1dc1233ee85eb90db607917cd9a5d7170b10e80b925a20e2af2c54d286b01805ac34967410859f4f03da09","up":true},{"one":"a7507aa5665e165ab2e2a07def272f0677f9d6d35bb82268a34214384e7d8ef7635a299368752e63cfd02d4e60231076baf23cfa10d17492e55181b391ecf335","other":"b6a998dea59194cc60ce97c7c9702368411889cb6905516b23f41cc5116fba8d0f237d418318eb0c333cad18003c0e9a6bd8c99080520771f2bad640e2e5ec1c","up":true},{"one":"7b1e20217f594f87350542df31ff5ae8a635679bac7962d49c97e02190c644b673d03e7eba2626b45ca7ebf98d8a972dadbba02c18a8d2cbfc3e7a4cced5b4b7","other":"62dab8b21640e1b44dea452dd7e7de93f27a44840da72d56b11aa96e8463f3a4bb15e75a954d19fc897ae0030b16181d271b79d8198b7cffcddaa9ffcfdcce73","up":true},{"one":"6b01079463ec2f649db8634cb7a596261c79a8f714d954c772528e0547b017f8ce405e4a0ea9d32270848180e0f77b8c0b022cf95c85e777626edd4d24ea21d2","other":"59b53f8a562bee519276e0eeccfcf8c975d3102f5d0cccf5abcce291a8a5bb817c04604f123686177a50a03b9d7559ac469962d0159d1d93e4ce58a304d04b55","up":true},{"one":"fde7705f5013c3b6b76a35505c1e3d57c033a337f2a71e912ec3a3d2da8e113bd7c36d94908357e9f7654660621f647ad8c66b0126dfe91dbfa3b8c7bd2183d3","other":"07c63ca5d0309e30d1ab12e7fc142e6d37904b552639cfa97850161491f28f20d87e0304be29357bcfc2ff52fc52fd0d4f6e6011ebb239cced8b5c8dad7abf45","up":true},{"one":"807340e5fdf6c21a56ef2fd158c32e92201206ca85fcc147165a408f7a735964afd47c397e663610ac53870ae722c0317291732b0422f8aeedae783d9c730218","other":"617595a230e0a74a3db3b47cd27b941e02bdee9a84cdfa8eaa63a55941eb5caa79e20fb69726a4d46a0e5aeed24039f8c5a20679a692df0bc140f42558ca9a2b","up":true},{"one":"ed6c793eb4565aa9d883a76fad6c97ad0b878b9ef0235e11e89db1af25a9653205f725c6ea258b84bde134f1a6437c6d109b859d17509e5016c4ab98be59032a","other":"e67e495385e7cacfe659b40d1ba94d4b1ff55eada70a4d9740a9e452fbf221672bd0a897b940e2a6bed71e2a16867fe45bf0ea0015435ac6d815690e263b1899","up":true},{"one":"72e30d4562673c5c8fb03709d93f73322747858d723b7eb5ef2fbb88e0331252946b7e93ffe434fcb599c4fff57800afb29e6c60a719f18f49dba541c3591c6e","other":"e267e71c2dcdbe5a500b23444d2d4037ea15afba8f4f2b1c0e54a274450404fbee6fa5439f7cddf4ba1aa28fa93e434b01c239add58e30a5423ca3a481584d6b","up":true},{"one":"2f360209383d6de4ebd3b4abaf77796520b8654270b03f2151eac4a01b4417d7e0668c1f9ad30c20ff49aa8a0ab33dba5e6095619d1cf04b7af841722ab773da","other":"8ca3b63cb84f1e9883d82809a9b6777ec1029ecda96fe93b4d494ee9cbefcad13f381b3e480136e542e01054fe1ede66c65db84a0009871ce49383db461c8438","up":true},{"one":"92d6ef729992f0de886076e5f8cdc42cbbd70b29e79c25e0b3d22b6575d3d2508d47b42f581e335455483d43625bce4e55f88cab9ff2073ee8dab746357864fd","other":"deb7af800cd20a647335f0feff5bfb3e182f99f4c2d1ade10da36ecfdbac3b5fba4e8f0a4595443fe395b44af3a95617669850944655def85d57cc81c5682a3b","up":true},{"one":"24662a43944228e4ff74736bcf0a0a4f79c87ecfdb739225b2fc45110c11bfc38aaf2d09d98e5817477848e553f187ac5408bdb864518dfa7f5df542768828db","other":"292c78c8e41606e98428096bc6f4609a7aa48e5c4d17eecc64d65faae4a7270b0c15f0cd74274015688ea0a9aff34f215c29118222e362a29c8d637963973a55","up":true},{"one":"329145e75496cecb5f5c8f00313a52ddd8c0e8cd27ef1b2bc1b2b56e4d4089aaf5a7a3c4d9a40bdb92483fa05bd24d1cd0fd51883e30439dffa0fc855e1a7cd0","other":"2bfba66ec9d63e928d77d455f2e10a14d6213e515099d5db14fa44a8bfc147eb0fa7afa9aaccdc86453c6903b55556059a2e13dd61fc494127d4a3ec173bf9ea","up":true},{"one":"043fe7085e8c90c18270f84dba5fab138e50216a1cf8d81a3794d156fad7fc81d1422aff169b244b13f91d73eebb5de464f97b1b93b3ad2a58959cff19238842","other":"453779010ed7c59761da47ccd8869d3fa8349795e57edb9eea416c0712301ea622c7683858e309d19ab137ddb0edef161d0d00a361abeecf0628c3ffabc629ea","up":true},{"one":"934a5fe1b91c1891ef4df7f67c027e0eb115d4c2ca4a1b76a135ebd4315c4fb835d6625223194e6a134407b38b0d3928fbc7bc924a3c6a538989a6cf200bf4bd","other":"109556abac422a912ecffec0d8796f8f16e92e8f95cecf72dc89e97a8bf1fd37aad3c66aa3cf134acade6d065c31821f977171d5c5463305b57ce3eee99a7ab4","up":true},{"one":"4314b0b04331973ed29a58843951f144ac3d09bd5d57b6cd9aaff9b73a7b2ec81e344a3e4ece462bd2081b837a06310e787ef3bb889dabad46fe7efd394c8342","other":"bf4ff51cc3d9a9d8cefd7e346ce1384d06450228a6086fe12fb0c60fec54bb6478f090bb638fbdbf8f41f7bc6420cd8a5c8b1b8566229b6851167375ef412f46","up":true},{"one":"5dc69635f6d573c824ea83b18593a47f9f21a6f91ce18d2bf977c97d21f8d2a8ce88829244d12a07d949bbd52fe8a2035bc89685fe1bdd4ee20d766d75d3deee","other":"aacff366e601e072a2113add9020e19b6612f3e85b6e607fdc8cc1b6991f43be0b1f835ed3dc41d1f2b3e0caf7fac252c8eb4c150667d48207fa92ea5f0a7455","up":true},{"one":"07c63ca5d0309e30d1ab12e7fc142e6d37904b552639cfa97850161491f28f20d87e0304be29357bcfc2ff52fc52fd0d4f6e6011ebb239cced8b5c8dad7abf45","other":"94088fe273f76e62ca4e43c095ad12215b4ae4c59942328b3985416fb19bbda0cacc143a49eff3fb644ad53a19d3f043260e43dbb70a0aa9c15829c21cecd3c7","up":true},{"one":"1d0244a13affe60996fe3cf51ba624adc746de0c7ea68ec5a31311a36077c5b5495e3d95c9642875db44c7ecae6ffed22e45f2e2d024d486760be2af9f4cf2cd","other":"b870935867183bbfb84add16b9f56c02c834b7042fc24ce6bcb2a7f174e6d2239357a00be4272c1ef05c7f9baf5a9f16b53bc18328a9b7aca8540c2916805b57","up":true},{"one":"420b9c90584651c5a3fe3c16aa377444a321dca934f8a097d01a616554067feabebf2fdc8d2a25797f29a8fef30d5e2c82f8e85b20f509a880367b9b0ccdea47","other":"9db1f94d74a00d1e5e2a391f1bcddf16b6d0670a2c6d91d946d38112c58634444b6fea8e8c05ab4b73bacdd62a0b575f6fb8729978edc216c7842b177b9f9cd9","up":true},{"one":"831cde5b651ba327b059da4c7f84b184bdd6bb99c6690ae816affe25d42c6c3dbe5b59e2b6bf23e9d0f6c485bd341ea57ba1a8220d18b0a40e156b77d84f79ef","other":"2e409baefbd821485a151993356730e5989810d581e68190fbaa142799c9335bcf98310ad188fed10ae6eb6e2e789730393e509962ec5c0fef0342d72ed088d9","up":true},{"one":"8f88c7ec044f758f29bd8d12a5170bd973aec8f6cddbf512b910c4b75a0fec09c5e198bcd65622037f897759db68da2328b4a7ca93585dc9cb62e46d2a6c0864","other":"ee36d1d5dd69fd30242d7da2e941b34ade5581c7164fcc43288ecfc52937a98f1b31ade5d1e4dbf611cbe1c7875b2840c89435081cde471c271d7bc60e9ef211","up":true},{"one":"292c78c8e41606e98428096bc6f4609a7aa48e5c4d17eecc64d65faae4a7270b0c15f0cd74274015688ea0a9aff34f215c29118222e362a29c8d637963973a55","other":"0f9f7e2dce4ca266c3ac0ec3a8854200b54487f5308e3db418461aeb5f67c81d332619b6441b468e480941e63100ed1b263e7adc20689dc3dcda578bfca538fa","up":true},{"one":"2ac522ebfa49d37f86c6270ad4cdad0e766493f0e463b18c9906c70fbd2e5c6ff6b0d5879de6e3894418370636963a78b0c0cf087a8684c2ca30c9c736e49228","other":"385168340139236a0e0f537fa693122db9fa02a377c96f31aae54718e92624fc0288164877e63616651565e055c53f7074ab2fdd18a837da6faf644941305bf0","up":true},{"one":"17917fa4da06068b587c17899569dcc768b9cd2c27117a4ed67aab26a7e70cf8d32b881db258061ffd89a332a3b29bfd963d8e171a06c3e208ba0de1c42a2b39","other":"b4fd11306b1416a9bcf4719578976188e104b8c5028b9abd3214d257446b97b70a22e6c00934d80caddde15e8e4d16af03bb399583047983fba373d8313226b7","up":true},{"one":"f039df8a3206e6e17eee8e95010038c450cb4cc0b5580ed5795d4c21802e1e9d360f4528bdca794f457932b1d6a818862ec847357a861c488332ef6d9480daa6","other":"396c703d27bfdddf91761f134cbf665fe61e0b3a5d24036a4105a625f72e8c28b821e9200f20d6e8f8b3ed6b95bda6b8accdd840c2f786720b7431e3af2af981","up":true},{"one":"cb94a8270d0050378116b5815ff17dafbe20f5303839c4fd57b981d4687a4b145e4bccec7e9af9b9475005930148ffbfa97781a0762c8e9f352dc95565fc8732","other":"8f88c7ec044f758f29bd8d12a5170bd973aec8f6cddbf512b910c4b75a0fec09c5e198bcd65622037f897759db68da2328b4a7ca93585dc9cb62e46d2a6c0864","up":true},{"one":"cb310c0e86aa455d7c9af6394ae38561c901da30a51d7ccb7e66a09d9a8f192ae8caeff106043426d56397088f141c4e01e3b98f1ee583ffc7318b5f730f3ac7","other":"ba21a373781966135d6225adae024a3f3e421b852f72f8b0569cb92fcff87c33f7e5b799a509b8eff6ec6dc46a9b17d5bae1e91ec7c54c0c712d893d54b140fa","up":true},{"one":"b2538d4edfa736bfe2cc21326a44ce62f716b3480eac93584a2233b69c98883a2bb255f246218a58cecab1d0d176e6d1fbba9782fd70d4603e01742299b9ea9c","other":"5eccdbcb15ef42dc96abcbcd8b8db75d9230de10e3c650620737f6cc04ba4fdbf59ded5daa801901c191be186c329ebcd37ba83bcf794064ad4e11bf10d3f775","up":true},{"one":"7f357b8d81bc2e5c6fcb081f23a42b3e2439f050d45c45851994a268d1c71fcb1f39f8c3f75ce921d3fbf80fc0e73f0b9609d72001dc4a6b65b526d312a4f43a","other":"24662a43944228e4ff74736bcf0a0a4f79c87ecfdb739225b2fc45110c11bfc38aaf2d09d98e5817477848e553f187ac5408bdb864518dfa7f5df542768828db","up":true},{"one":"759f46661056bcbb30c7706c9fb87e22a30feb523bd53ae5d18db043efa45b49a2b8982abebdd598fe0912a05896390ec2eabe5e160cbafc0771990708ad8c28","other":"11d560045536e9d1b0b1b9e8944e00f0ca7f1e6788c9fdb51061820bbb3008ead92bb7836621bf58da7035c87a28328faecb4cb2e3cdb9d7fa4f45790e6bf352","up":true},{"one":"829b074b70d757da6aa00f7bace3cf1b5d2d4eeadb7f370c1a85374a01a70b54ac53d747267e386f3b41e6d790fecdd6e74b8f89745501ee82439a66ea54443a","other":"5142eea687de4248b2184e9896b245563117648e7a156255d9a7ae730313d5d383db3be1125b5accd7e743c2a5d8c3289ec559ef7cbb803b9e82cd49bb213d9f","up":true},{"one":"a08e47137bf611dfbd20308a22bdd3ca00121386f121d6d712ade86e9a1601a4237766887cd91c8516e20b6e323d2ef49c1c7e177a0afb4c813f0f344daf779b","other":"cb94a8270d0050378116b5815ff17dafbe20f5303839c4fd57b981d4687a4b145e4bccec7e9af9b9475005930148ffbfa97781a0762c8e9f352dc95565fc8732","up":false},{"one":"990b1db3ab1390219e8866d39fa4441bb5bb89ad786b3e255771869fcd08906dcf63f34007481769c7462edbcc665acc0a552e3733360b8d8c310c9321a5550f","other":"cb94a8270d0050378116b5815ff17dafbe20f5303839c4fd57b981d4687a4b145e4bccec7e9af9b9475005930148ffbfa97781a0762c8e9f352dc95565fc8732","up":false},{"one":"57cd4c0048b459192ee46e19ec7df777e600f256e0dc8c3019431eb7bec3c020b9504ec7aea3dba8188658ca5b830ec40af6a8540ce10e04badc6c695d009271","other":"083e67bb19e30d14e4df6d2483367d6659d9b56744d53d9cf7fd15954c327e1bc88a5d0db8833634e1dad7209164451f8934b59f76b5990059261abfd650519a","up":true},{"one":"1b063741c76fe65e62b4eae42751319d0cce66f22dde9f1cf83d6cca249a0e65bc7f6f22597697362fadd226222fb3847f8e146961969d1b4c9f7e475389cd8e","other":"0cacda5560faff9d20e29a0625d3cd340ec075f198a50ab8b79338cee0e0db84c7c7e71042fd8c8f73e507b570de5d26c39473136b575f0167625a1168309ec5","up":true},{"one":"5eccdbcb15ef42dc96abcbcd8b8db75d9230de10e3c650620737f6cc04ba4fdbf59ded5daa801901c191be186c329ebcd37ba83bcf794064ad4e11bf10d3f775","other":"76cbf9fc0f3517fb615fa96104780218e85d064ee5a1d518f3b78f4dbebf144df38c427445fdd6c9b436489c00ff9497d747a8fd70f380f95601d59e52e021e8","up":true},{"one":"4e95fb8943ef6502fa470870a7ace4ca11e18589bd2073167543a922317b35e40b5068934d07e56c8fdd23354dfad51fd2899db854f189841f02b5914cd97749","other":"8ca3b63cb84f1e9883d82809a9b6777ec1029ecda96fe93b4d494ee9cbefcad13f381b3e480136e542e01054fe1ede66c65db84a0009871ce49383db461c8438","up":true},{"one":"a78f18691e0dbf3c08fe9d7dec188e6a05a93833432fb99eb2b3924ab0bde7a44db2a102a65544bbdc4fb61bc3a3d569230d9843a335bf619167fb045d78ab3c","other":"23f9bdc82efbf57d3d40a1f2617d0311678fb4a3d6a50cb7e608c649bb618124a76c7ffd17387de963e1cd28d2bd5a61c98613f6e009a8a2a90d989827b35de0","up":true},{"one":"58cfb20d3da3641e0ad529b9edbd4b590a8d1dc9d1ed7b44ed3187dba9260bd7c732fc10981f5b9bffd31d362cb05150173618aa36138984431d94a323a9b313","other":"17917fa4da06068b587c17899569dcc768b9cd2c27117a4ed67aab26a7e70cf8d32b881db258061ffd89a332a3b29bfd963d8e171a06c3e208ba0de1c42a2b39","up":true},{"one":"315b8a1711f680c2eaa607e35ef7a9e19c2b61721af8a7e08f1325dde1fe33cf1f47b3cc4acf12d541631041cf1b42754875fd1c9b66ee32797b72b9f7711256","other":"2245f3bf1a3b4e92f912affc75f757cf648b20474c11ffe947884f216b8f24f9dcb6e6a0358a4061b8517478ec15027e185b2f05a777573b4940375bf4aaf2be","up":false},{"one":"352407b42726dcd1aacc46a912ed8124b8b6a3da4e33dab742e40aa2452953d35dc8f42eddc76695ae2317e9f15dde2cd21be4ce826934695ad1847455661d1b","other":"0cacda5560faff9d20e29a0625d3cd340ec075f198a50ab8b79338cee0e0db84c7c7e71042fd8c8f73e507b570de5d26c39473136b575f0167625a1168309ec5","up":true},{"one":"663535b22018a4ef0b151572ef286fa66c22c6e9b2913a69c4a735d4b0149bdf6c84bd83d710f8aa2627e8993b7f020750fbc6f56a3365ce4c840e2b3de1a6c1","other":"8f88c7ec044f758f29bd8d12a5170bd973aec8f6cddbf512b910c4b75a0fec09c5e198bcd65622037f897759db68da2328b4a7ca93585dc9cb62e46d2a6c0864","up":true},{"one":"7bbb3f3ed51cf84c077806fbd6d3578e105bc32aa6043da188793f066ad6df383a9f7cc0bd3124f4c887704bd188d480ce264fcdf178905bbda3b270927ea138","other":"ae4e21e1587a8475afd299e00ca7085c7bf2a44c2c64a3068f12223d9202b0125094385319034691ec26b497ec9cf18fe8c0839224bac1b84279410241cef979","up":true},{"one":"9c30ad8c85adc7bb52ddcfab2e661cc3a854a689eaa59128d35129d02cd5b0f8da4a44cdd33934a8e2c8fab1760c16d6f2e1c5eb227dc819e85624e63343c069","other":"62666b24d1026345349edb6a878cdc27d6fee8254e83f79a298ce2805260d97aa46423deae440f86ced5cd99b30e970c8e1ea1046752b17d8c80dc68d9a49b60","up":false},{"one":"855bdf057f4a6b095e2000ada199447b5b4f2f8d78d2ecbaa0ff1fbf761788870ee999266ad3b26efa02be1a46a4d92ac0debb85a2ceab3442394ee7d99e5355","other":"d4b7c787981abec24353c7d496661692233797e3758189bf909a69fe87935bf6da0940daa4f12e81f20c5e88f70b472113688b71a0ae2f91a73ee0e6ff4c8591","up":true},{"one":"a7378ee34876af17c6cd94a69b6b741ec7891ff5375bc4241d48608d047455ed48e6baae80ee88d4710c69ae615cf195cee26c94b54de1bb935628ce1e3a723a","other":"acb4088c27ee2ee130ece3506596432afdb9e9757ec11ebdd35c5a6e87239545c48466913a646980104c8fd7a9a335e177f04efffe9dc952dfd7cd5c1bb9aac6","up":true},{"one":"e087230634f556b818a416b66ba3f1d1dbe3e0dd0698bbb26fa86a2499acd169466f564dc18adf2f9be4d1ada0e86c11549754097601e10aff4f3a57ddffa24a","other":"3e488a7208ce0e097ce47fc6651a13e95cae137d1a054a09b04d2f59d45faa2594a8c3b395e77ad1a3c2edcd827dda73c0c97dbaa6d9519a79184a0aca01ac4b","up":true},{"one":"81288bb0584b7ffc1546043e052e1df10fd5371b35dedd0bb42ec5b30ce69b741b2f7857af5984d4754b39d7253575fde9298504999b78380ef602d391c4bb1d","other":"7b35c856916eb3fc1b1f451667e240b95aff8f4731cc0f6743740923081ff1ddf2eec81bdccf4691a7bcc053d23eacfc15809c384a73448f618317bf605bd1cd","up":true},{"one":"155e4879643a472420012e040a87dbff776fc1976814c0c6cd0d5e157f0d0baac04aa7f2535786c09acc2700547383d2119b64a6f62115f1aff1708738844d8c","other":"2f1967b4410ea2ea8fbaf46771ba82c2846d00aecdb6f873aceae33ab38f72d0a2c2dc6046d3034f514efd090d42011d48e9ab0cb4e3caa2b49a96ef732215a1","up":true},{"one":"ff6f94005d1df7677600069764855c1c2aa0543cbe9f480f8feefec76c49d9e2c7bb2d8e38c89e9430f53f8b593d93f143c45985a56a5a32c736128214c95eda","other":"2b70e5ffcc0bb1c4f8acc09dd1016e67c9c96c92d091ad481efbb71bd8b2a5a5869c6d668617a9b2cbfe91baf5edfe150c3824c84d90899a974099071d171441","up":true},{"one":"329145e75496cecb5f5c8f00313a52ddd8c0e8cd27ef1b2bc1b2b56e4d4089aaf5a7a3c4d9a40bdb92483fa05bd24d1cd0fd51883e30439dffa0fc855e1a7cd0","other":"40bdac599b00e9c41ad6476ee415c33d9c17c5aa672692c2404e523b29dc315da929a86874bed87fd9009871805d1dbf3098e7a817193e3b08a6eee66346da79","up":true},{"one":"deb7af800cd20a647335f0feff5bfb3e182f99f4c2d1ade10da36ecfdbac3b5fba4e8f0a4595443fe395b44af3a95617669850944655def85d57cc81c5682a3b","other":"934a5fe1b91c1891ef4df7f67c027e0eb115d4c2ca4a1b76a135ebd4315c4fb835d6625223194e6a134407b38b0d3928fbc7bc924a3c6a538989a6cf200bf4bd","up":true},{"one":"53df9cce9b0169e58ced53a123d1d8f6e8fdcfb4c2d781ecbb91bb7c8eba36946dd9d21c749259769825d8a6b3faa6bb87c8c6085a522f8a3e376061f59144d9","other":"df54af3bae257d437c5657905484e0d72e9560c46f8ba6b3437730234e05259b404cca40b0831e911605ff8a68a19e8fd7e958069ec8b40595928892f4fa220c","up":true},{"one":"485825745d97654cbb92a14e0cd1078691d3c28f4d82b1046284b676a42b44ca58eb43474e45e415d3bd3f3c383f9a1a3365821ed7ba6a9f2603b29d58031dc7","other":"3612863ce0456c91785a829bf5c9d2b2fb97dda083a1847e5a4ebaa6fce1260faf4d1eb374c2225431a82774163835fb59c8cb0fa9fc0969eab5410c71109cc2","up":true},{"one":"db8ba71afeaea1f2964e8978a6eceeb9efa3958424424022213c8193443f8d5afd18490afa954c76360c681404809c7cfaf7e4ebd8bd1a42d403f7f1915b0d29","other":"5bae82d4832092c17bd11474f7748015b8b69b896ab8f683a7c0024fc98740cecbb9e31c6275269f9000e5bfe51d7f45cd5dcd4433e0c87b5741685b40fe3983","up":true},{"one":"3e488a7208ce0e097ce47fc6651a13e95cae137d1a054a09b04d2f59d45faa2594a8c3b395e77ad1a3c2edcd827dda73c0c97dbaa6d9519a79184a0aca01ac4b","other":"a78f18691e0dbf3c08fe9d7dec188e6a05a93833432fb99eb2b3924ab0bde7a44db2a102a65544bbdc4fb61bc3a3d569230d9843a335bf619167fb045d78ab3c","up":true},{"one":"c2705ee7238ef9305e4da196653cde707649435a1e8b5b797d164e5ca06184a77af5bd7fa938c995fdfcbce724fa7eca3d908ee34891ab62cc6dfd411c3fa1da","other":"cd8815d66aee8bd488d4e5e25f0cc9c71cc65349f701ea26b1d6cd9c039d16fcb473dbf270a3b33187720ccf4b0ce4f78a6d6edd05f4fe804772d5b6ec45bbd3","up":true},{"one":"c57ea182bdb42ba9b0870b5c870e467f52693e5c0df752fb6eb0dfbacce7763f73caee10db40f4fd90f19f504ee586eaf9da41f5ee93ee515d885fec99374116","other":"732393b99c490c76fa45e3e404ee095f2fa445fcc123af7ac8ab1d2fdd7cf2483f5b82bb818bd8a82b1a3b73e63bcc2c83d8f24d9aad9afe36503735e7967be7","up":true},{"one":"23f9bdc82efbf57d3d40a1f2617d0311678fb4a3d6a50cb7e608c649bb618124a76c7ffd17387de963e1cd28d2bd5a61c98613f6e009a8a2a90d989827b35de0","other":"aa9a94d6e4eaaed20113c21752c224e3a052abd3769bd6e832759dbaf5154a943cf094eacdcb0727c2fe51a11bd7fc0793d7d5e3312b0aba89d428a00e1fde0c","up":true},{"one":"f5c1215a84a56d52f92ca0dc3a32df98c98a9c2ea2e9a34560210c16de1b440d20d043c8c25955dda8c22e55e92ddb49fd82e8b9b84072aabaa755a229bb19f4","other":"ff6f94005d1df7677600069764855c1c2aa0543cbe9f480f8feefec76c49d9e2c7bb2d8e38c89e9430f53f8b593d93f143c45985a56a5a32c736128214c95eda","up":true},{"one":"0deda014fa3c0bc8f37d853e1448f95f56f97048c28797d72258fd3ba2f1f776ae11566197466596356cd172847ab02a89f4cf047e58383249fb2a4cd69b6206","other":"5142eea687de4248b2184e9896b245563117648e7a156255d9a7ae730313d5d383db3be1125b5accd7e743c2a5d8c3289ec559ef7cbb803b9e82cd49bb213d9f","up":true},{"one":"b597c9ba4da20c49fc4ba019571321d2579588636cdaceb9f225706574970adbf4771dcf186b1decd4e14cd5d257e30a36ca829829598c1775902201ad9793e2","other":"4e95fb8943ef6502fa470870a7ace4ca11e18589bd2073167543a922317b35e40b5068934d07e56c8fdd23354dfad51fd2899db854f189841f02b5914cd97749","up":true},{"one":"f54335964d9b4eb9813eb05f40ef1c523bbf0faac5a04c4737467d590fb6b55c7fa1fc5d4d32c5491d8766b9be6fdfd3ebdb25c5ffe1719f36c86ddf87ae3a85","other":"d3105ede6c21bc643d523afcd1309a5dcf03f70797a92f167c3a19f86ae98882fe1a9d4094d7a3dee4a0833b8075b6c3e9aaa7f4879dc47bb388c3ae85522288","up":true},{"one":"c903c5ee3d9cd65bea3ea777e39282c33e1349d945411fb2f16321bf582c2f400956a98fbafe5873fc5f6f6a9a051df5da7e94cbd340f935abe80f91e79ef875","other":"0b7e1e5acabcde503ad827e45724402406114a513f81040a379b0f82df2eab4456b348b27936369c49e3c264d971c6a9e2c2217fdbc5e5b93ac6fc219957834d","up":true},{"one":"389b5c1a805f87427e6d647ec5488342a3f7d700615943d5ad98ca5c111f33c7ee007970b4d3e475892095c0d5a79b7ed52d12598398818159000d4b9b719126","other":"6b4e376e9c94242b6d42688c22aa9ab418cb6dfb1cbca1c69de0feceec8d3af29fb005017aaa6e503cc0c03cf0dc5bcab55e01cd6f64b9efa02ed87c03020003","up":true},{"one":"bf4ff51cc3d9a9d8cefd7e346ce1384d06450228a6086fe12fb0c60fec54bb6478f090bb638fbdbf8f41f7bc6420cd8a5c8b1b8566229b6851167375ef412f46","other":"60725e8d0e9333636e598dd666f459b4be898d9abc095ee2c1db289673e7e969b50e2093956fef5a2f1d23e2040159bbabaaeab17fc6dbbac3f6acab766e9e60","up":true},{"one":"acb4088c27ee2ee130ece3506596432afdb9e9757ec11ebdd35c5a6e87239545c48466913a646980104c8fd7a9a335e177f04efffe9dc952dfd7cd5c1bb9aac6","other":"74d84cfdaf32cd4cc67771f29878f1365120bd65cc14848008d5386a81f495bf88eb4132fa38a2cc109ae1e7f02c9b97597ab9d1a9c19c945e710ab9df07cdcd","up":true},{"one":"5bae82d4832092c17bd11474f7748015b8b69b896ab8f683a7c0024fc98740cecbb9e31c6275269f9000e5bfe51d7f45cd5dcd4433e0c87b5741685b40fe3983","other":"155e4879643a472420012e040a87dbff776fc1976814c0c6cd0d5e157f0d0baac04aa7f2535786c09acc2700547383d2119b64a6f62115f1aff1708738844d8c","up":true},{"one":"f38a9d792173a29c61389f5d84c005d78eac6e750659aad42e2d6df883f04eb3126b2c38fac95076eeed455b2031aaf694143922aa93a2d50412a2454dc56e28","other":"6b4e376e9c94242b6d42688c22aa9ab418cb6dfb1cbca1c69de0feceec8d3af29fb005017aaa6e503cc0c03cf0dc5bcab55e01cd6f64b9efa02ed87c03020003","up":true},{"one":"990b1db3ab1390219e8866d39fa4441bb5bb89ad786b3e255771869fcd08906dcf63f34007481769c7462edbcc665acc0a552e3733360b8d8c310c9321a5550f","other":"4a030ebcb1a59230759d25a3c87daed22906b520d55a78eab2083bb52358ddc3a5d2d7c3265e6c54a990bf32d0dacb85905a4173d72ac18fcd74c43ecb8635c5","up":true},{"one":"049a2b0ab4d49789dbbe1837e2d2ee5220a9401729ea87ab29385b24d79cdce255c3d2b5de6484d49ca6ce07bd41832598260c0a8c290e01d133d77f066f2f99","other":"4fe37f2dfb03707c90a6fe91dbcfd7497db70ffc20043091d50e1cee573210c144e8749340f2c3cb70fe8fc51b317d49e8734dc51ce64b3cdccdd639ae35d1ae","up":true},{"one":"460531928a4b084686343c8464b37c3452bb3566045698d08a4692864de5581a9eb1dc632329e7d3ccb73ec31ee7693787d69df8458efaba9a7105d87ee2e053","other":"e2e0419a41bdfc5bd76deae2ddce6ac865f886d764c9bd18799b79fa3b2b6ba66d765d26da2037e98317e1d7e8232a61e63c1d0cfa98c9137424151b46e07171","up":true},{"one":"396c703d27bfdddf91761f134cbf665fe61e0b3a5d24036a4105a625f72e8c28b821e9200f20d6e8f8b3ed6b95bda6b8accdd840c2f786720b7431e3af2af981","other":"76cbf9fc0f3517fb615fa96104780218e85d064ee5a1d518f3b78f4dbebf144df38c427445fdd6c9b436489c00ff9497d747a8fd70f380f95601d59e52e021e8","up":true},{"one":"a08e47137bf611dfbd20308a22bdd3ca00121386f121d6d712ade86e9a1601a4237766887cd91c8516e20b6e323d2ef49c1c7e177a0afb4c813f0f344daf779b","other":"abd8f5a4d700c06ec00684b23d2d25c4df1a9554fcfc57b0ddc3fa476e6a699ba75e1213449f900803f83ab8194c6746664b547202047f35b8b3e216c7147bf8","up":true},{"one":"62dab8b21640e1b44dea452dd7e7de93f27a44840da72d56b11aa96e8463f3a4bb15e75a954d19fc897ae0030b16181d271b79d8198b7cffcddaa9ffcfdcce73","other":"c903c5ee3d9cd65bea3ea777e39282c33e1349d945411fb2f16321bf582c2f400956a98fbafe5873fc5f6f6a9a051df5da7e94cbd340f935abe80f91e79ef875","up":true},{"one":"352407b42726dcd1aacc46a912ed8124b8b6a3da4e33dab742e40aa2452953d35dc8f42eddc76695ae2317e9f15dde2cd21be4ce826934695ad1847455661d1b","other":"083e67bb19e30d14e4df6d2483367d6659d9b56744d53d9cf7fd15954c327e1bc88a5d0db8833634e1dad7209164451f8934b59f76b5990059261abfd650519a","up":true},{"one":"be026dfb24847cac2d00f483104edad06ca8ecb9e1229c479ef5650c7b427cd5dc34a1cf06172c17c9d0406ce17009712e82446394743d4cd9bbc41c537ebc14","other":"9133b0b3c8f680286eae90c3beebc3099a13de38775a3ff2abdeced62d05eb2ced5ac85eac0870156be03101024da5e1d9fbf3e1066ddb3f088221e64149acec","up":true},{"one":"e2a27dcdee1f89fa362a85c4397840cd8be4ad8d1b9ccb23188c303bcab7619f38772f71385922d090390973b62fb8249efc103f71bc761041bcb3880ec0b935","other":"b597c9ba4da20c49fc4ba019571321d2579588636cdaceb9f225706574970adbf4771dcf186b1decd4e14cd5d257e30a36ca829829598c1775902201ad9793e2","up":true},{"one":"7808fb798d22e78fb1d39b87ddf99a503f820993bc64149eca9e81d9d58fc1adea60d8de14a4f06cb89f3190c0ef0c5e182621a14c9361ccb7e0cee667599cc3","other":"4fe37f2dfb03707c90a6fe91dbcfd7497db70ffc20043091d50e1cee573210c144e8749340f2c3cb70fe8fc51b317d49e8734dc51ce64b3cdccdd639ae35d1ae","up":true},{"one":"7b5c0e81c7f4e3ae29d745f6028cfa10b29a16a9c261b65fb8dd05d6eccc634612ad5d3029c8e9f39863a2cdb2682c25f090139bf5c4950e25647e39dcb40e63","other":"109556abac422a912ecffec0d8796f8f16e92e8f95cecf72dc89e97a8bf1fd37aad3c66aa3cf134acade6d065c31821f977171d5c5463305b57ce3eee99a7ab4","up":true},{"one":"2e42f845d0393d1682add54ee30b60a953ed283e75d347bc6719ae0e91f6676282e7960f1fd52e5803d6b341fb3582c724b4f9cfd7bce9ce85f13ca480c7e72e","other":"083e67bb19e30d14e4df6d2483367d6659d9b56744d53d9cf7fd15954c327e1bc88a5d0db8833634e1dad7209164451f8934b59f76b5990059261abfd650519a","up":true},{"one":"71f89efcf939294bb94ac669c8afd00def58c8dfad519c226adfa068692d588ef797116d42aa146b9d34f3be35ec7c014022640ab3c0f1f9034e44ab1a26e246","other":"17917fa4da06068b587c17899569dcc768b9cd2c27117a4ed67aab26a7e70cf8d32b881db258061ffd89a332a3b29bfd963d8e171a06c3e208ba0de1c42a2b39","up":true},{"one":"b53078000796f1cdb04dfeac424d5e3e37e30f00bd5bebf9a9ea0525c62917612b3a8f508df6bea59e3c7e4cd1aa530841f9a8af54e44f5617a13dee2c6ff007","other":"b080891d4ba6d3ab224984360597f9c555bd1367630f5420bfaf230419a05b2be58bebf1554e53eb4c0da81cfb66d4f7697dd65143f11841ff62d8a0d82b6b67","up":true},{"one":"baa5924e1547c177011285d292aa161a15e5ff282da2cd0afb83c9caffb07bdbb3662c227fa7b26e6dc8be9b8863e647eb5f8ce81640532f8f5c9a7f36557e63","other":"d7a319f69013b8375e64d19f015547462c84565b882337998f9e669c5fadd3d2ecf6374109903003e09f5d453424b5c7fdf52163d2cc8084cf81f94844946b63","up":true},{"one":"baa5924e1547c177011285d292aa161a15e5ff282da2cd0afb83c9caffb07bdbb3662c227fa7b26e6dc8be9b8863e647eb5f8ce81640532f8f5c9a7f36557e63","other":"11d560045536e9d1b0b1b9e8944e00f0ca7f1e6788c9fdb51061820bbb3008ead92bb7836621bf58da7035c87a28328faecb4cb2e3cdb9d7fa4f45790e6bf352","up":true},{"one":"f9ffe87c52ff4c22bd9696af32e0a9d34bb81fb84d9d8bf5aafe2ef9696e7b3d6460bf2a93aecb066133f53416bde841a02d6967bd06e3d4a714f3b2c123a947","other":"a1560ce7c1f1d5972f027a8e9cff820611d84764aa067434a75b63887bc4268a259101486d34b7fe83dd735e799789986cd3e9b156c86ede598bd86af4454924","up":true},{"one":"cb94a8270d0050378116b5815ff17dafbe20f5303839c4fd57b981d4687a4b145e4bccec7e9af9b9475005930148ffbfa97781a0762c8e9f352dc95565fc8732","other":"7646d08b3e24183e3814de130235c41eb88a5a2abff23eaff3c91954ad3ef55fe27da422dac5b894312276bf1a2f1aebb8b636a8d4a0c93d9b016d441df3fa19","up":true},{"one":"c9cd9dfb9f90a7948ac5a42c7bd63263f2eef6e1d85547559f7d2ecbf5f9cd1eab051b8e9e661b573c275d84091a44e73f6fc6bcc91dcdb674bd5d939190fc01","other":"60725e8d0e9333636e598dd666f459b4be898d9abc095ee2c1db289673e7e969b50e2093956fef5a2f1d23e2040159bbabaaeab17fc6dbbac3f6acab766e9e60","up":true},{"one":"3e488a7208ce0e097ce47fc6651a13e95cae137d1a054a09b04d2f59d45faa2594a8c3b395e77ad1a3c2edcd827dda73c0c97dbaa6d9519a79184a0aca01ac4b","other":"7f357b8d81bc2e5c6fcb081f23a42b3e2439f050d45c45851994a268d1c71fcb1f39f8c3f75ce921d3fbf80fc0e73f0b9609d72001dc4a6b65b526d312a4f43a","up":false},{"one":"07c63ca5d0309e30d1ab12e7fc142e6d37904b552639cfa97850161491f28f20d87e0304be29357bcfc2ff52fc52fd0d4f6e6011ebb239cced8b5c8dad7abf45","other":"d7a319f69013b8375e64d19f015547462c84565b882337998f9e669c5fadd3d2ecf6374109903003e09f5d453424b5c7fdf52163d2cc8084cf81f94844946b63","up":true},{"one":"cb310c0e86aa455d7c9af6394ae38561c901da30a51d7ccb7e66a09d9a8f192ae8caeff106043426d56397088f141c4e01e3b98f1ee583ffc7318b5f730f3ac7","other":"ed6c793eb4565aa9d883a76fad6c97ad0b878b9ef0235e11e89db1af25a9653205f725c6ea258b84bde134f1a6437c6d109b859d17509e5016c4ab98be59032a","up":true},{"one":"f9ffe87c52ff4c22bd9696af32e0a9d34bb81fb84d9d8bf5aafe2ef9696e7b3d6460bf2a93aecb066133f53416bde841a02d6967bd06e3d4a714f3b2c123a947","other":"a7378ee34876af17c6cd94a69b6b741ec7891ff5375bc4241d48608d047455ed48e6baae80ee88d4710c69ae615cf195cee26c94b54de1bb935628ce1e3a723a","up":true},{"one":"2a63d875e715c2a43302d32d86d30c7d7faed46c08a67bf488762637216b99dd87333a66df6d9f3a57df863b1f1a219ddbeebb9f3e92e523bd08540a195448ca","other":"60725e8d0e9333636e598dd666f459b4be898d9abc095ee2c1db289673e7e969b50e2093956fef5a2f1d23e2040159bbabaaeab17fc6dbbac3f6acab766e9e60","up":true},{"one":"c8b0dba45104fc7c7dff3ce078a0d3f5ade6198bb4656e2bee8076387929133e5ef2bd293b130a9d4f6a6974ca17e8b4a8f406d1219880f1e0f99c65c63af5a4","other":"3612863ce0456c91785a829bf5c9d2b2fb97dda083a1847e5a4ebaa6fce1260faf4d1eb374c2225431a82774163835fb59c8cb0fa9fc0969eab5410c71109cc2","up":true},{"one":"c332fe1f9b6e25f72c7150631ffa6e0929ff6eeab5d17aa45eaf669bdde869cf404505ae990a529aa3ca797cd0a96f31cc41431a5d4a163132be566f91623c08","other":"60725e8d0e9333636e598dd666f459b4be898d9abc095ee2c1db289673e7e969b50e2093956fef5a2f1d23e2040159bbabaaeab17fc6dbbac3f6acab766e9e60","up":true},{"one":"e67e495385e7cacfe659b40d1ba94d4b1ff55eada70a4d9740a9e452fbf221672bd0a897b940e2a6bed71e2a16867fe45bf0ea0015435ac6d815690e263b1899","other":"b4a5efa9028b2d196855393892f79993c2812d02b758f98813ddf82c5d943faf6d66eff811cc5a51936c118f4c768c0d13b54902095e040c602761e63c08655e","up":true},{"one":"f6ca39b3ad803e99f4e4e9cf759fff6abdf06e6972bdbe524f6eb930c669d6f0e9b91f3de9df394b0d661b068273861391bdbac948ad911351c48cf02f874db6","other":"e2e0419a41bdfc5bd76deae2ddce6ac865f886d764c9bd18799b79fa3b2b6ba66d765d26da2037e98317e1d7e8232a61e63c1d0cfa98c9137424151b46e07171","up":true},{"one":"aacff366e601e072a2113add9020e19b6612f3e85b6e607fdc8cc1b6991f43be0b1f835ed3dc41d1f2b3e0caf7fac252c8eb4c150667d48207fa92ea5f0a7455","other":"eaca77d20c4ad6b87649eba21b750a4b1a2c575e06bc42679d18fce16fea15212e9a7408c16f3b24d8dfd1e397314637e72e292845d09534a39035bd9203ee9e","up":false},{"one":"df54af3bae257d437c5657905484e0d72e9560c46f8ba6b3437730234e05259b404cca40b0831e911605ff8a68a19e8fd7e958069ec8b40595928892f4fa220c","other":"c903c5ee3d9cd65bea3ea777e39282c33e1349d945411fb2f16321bf582c2f400956a98fbafe5873fc5f6f6a9a051df5da7e94cbd340f935abe80f91e79ef875","up":false},{"one":"c2705ee7238ef9305e4da196653cde707649435a1e8b5b797d164e5ca06184a77af5bd7fa938c995fdfcbce724fa7eca3d908ee34891ab62cc6dfd411c3fa1da","other":"1090e9d89cb278a30063a5396d9ba795d3bbc237c76915a6fb7d23aa1822c8535d2fccc44cc8cd2acec68444c0bf1bdf5195ebb9f3cad8dac3d94a4d9c0e5309","up":true},{"one":"c8b0dba45104fc7c7dff3ce078a0d3f5ade6198bb4656e2bee8076387929133e5ef2bd293b130a9d4f6a6974ca17e8b4a8f406d1219880f1e0f99c65c63af5a4","other":"b35f418c7935cc54278e90978c3ef1521ab91daeaf9f1ebc1cd25211611ade091cac4e1f009d71059279d507322a4536501980ac0dd44caddc52fd4c593879f7","up":false},{"one":"617595a230e0a74a3db3b47cd27b941e02bdee9a84cdfa8eaa63a55941eb5caa79e20fb69726a4d46a0e5aeed24039f8c5a20679a692df0bc140f42558ca9a2b","other":"65e954e60837bda10654480b227fa3bcc6e63356c52079002a27e836cd82ae2934ba77da60080e4b9f2d9324b982b24959bfd9624302e6c330408381054b43e9","up":false},{"one":"3b570117addeec03c2694baf28e246f91907268fe665c6c90356120332794258ee57a60853c19e9fe25d042ca42a5be7fe0797d84199174de8132f1ef4a9349b","other":"1b063741c76fe65e62b4eae42751319d0cce66f22dde9f1cf83d6cca249a0e65bc7f6f22597697362fadd226222fb3847f8e146961969d1b4c9f7e475389cd8e","up":true},{"one":"617595a230e0a74a3db3b47cd27b941e02bdee9a84cdfa8eaa63a55941eb5caa79e20fb69726a4d46a0e5aeed24039f8c5a20679a692df0bc140f42558ca9a2b","other":"b6a998dea59194cc60ce97c7c9702368411889cb6905516b23f41cc5116fba8d0f237d418318eb0c333cad18003c0e9a6bd8c99080520771f2bad640e2e5ec1c","up":false},{"one":"1d0244a13affe60996fe3cf51ba624adc746de0c7ea68ec5a31311a36077c5b5495e3d95c9642875db44c7ecae6ffed22e45f2e2d024d486760be2af9f4cf2cd","other":"7aaf7817b93aa6d2f50513791f9ad7629a901ed0dcb151189f44763f83423446b20ec79a48fa260cd9bc2907d5f0ad06b2c4c5e6d812f3d8876c8020ebe41019","up":true},{"one":"8dd8ad560af84bec579cadb33d51711aa61b6ed22705010336df5a71a94591173b25e869457429c4a199b205fce8e73530e28203e18b971c2001715e610f152a","other":"f9ffe87c52ff4c22bd9696af32e0a9d34bb81fb84d9d8bf5aafe2ef9696e7b3d6460bf2a93aecb066133f53416bde841a02d6967bd06e3d4a714f3b2c123a947","up":true},{"one":"385168340139236a0e0f537fa693122db9fa02a377c96f31aae54718e92624fc0288164877e63616651565e055c53f7074ab2fdd18a837da6faf644941305bf0","other":"57b47f692f4d69a5d2c9c193680eb4ccb5a6c574662df0138504a549f3ea74f20c5b866ac4d9e76c4b49c83f5fd692ead928ea20dfcf643a11a1c1e841c0ec42","up":true},{"one":"8dd8ad560af84bec579cadb33d51711aa61b6ed22705010336df5a71a94591173b25e869457429c4a199b205fce8e73530e28203e18b971c2001715e610f152a","other":"1090e9d89cb278a30063a5396d9ba795d3bbc237c76915a6fb7d23aa1822c8535d2fccc44cc8cd2acec68444c0bf1bdf5195ebb9f3cad8dac3d94a4d9c0e5309","up":true},{"one":"292c78c8e41606e98428096bc6f4609a7aa48e5c4d17eecc64d65faae4a7270b0c15f0cd74274015688ea0a9aff34f215c29118222e362a29c8d637963973a55","other":"07f25fdeab2b44b2e92fc80fca7de9e4a8547d27a98a54593b3395c270a9ff3f2a5da62a2e8531ce86359f0cdc5b6513b773dfd64cce1b83e47065d9760a2c7e","up":true},{"one":"be514f5f17f3177235acb24112b578edf0e373c469073226e547d18080905fd062d572be18e943f13bf9fcf5871e89ceb630a1b848a0e370ef8ef8c6d997a363","other":"5dc69635f6d573c824ea83b18593a47f9f21a6f91ce18d2bf977c97d21f8d2a8ce88829244d12a07d949bbd52fe8a2035bc89685fe1bdd4ee20d766d75d3deee","up":false},{"one":"2ac522ebfa49d37f86c6270ad4cdad0e766493f0e463b18c9906c70fbd2e5c6ff6b0d5879de6e3894418370636963a78b0c0cf087a8684c2ca30c9c736e49228","other":"57b47f692f4d69a5d2c9c193680eb4ccb5a6c574662df0138504a549f3ea74f20c5b866ac4d9e76c4b49c83f5fd692ead928ea20dfcf643a11a1c1e841c0ec42","up":true},{"one":"385168340139236a0e0f537fa693122db9fa02a377c96f31aae54718e92624fc0288164877e63616651565e055c53f7074ab2fdd18a837da6faf644941305bf0","other":"062e0ca43a1885c4a7ab2a5169790f9081e3e9a2dfa286b8cc592d5ccbf13d7a82b72d23361a19026d04fcf41b752ea320d98359d770aedfcee626e21c3494b3","up":true},{"one":"17917fa4da06068b587c17899569dcc768b9cd2c27117a4ed67aab26a7e70cf8d32b881db258061ffd89a332a3b29bfd963d8e171a06c3e208ba0de1c42a2b39","other":"acb4088c27ee2ee130ece3506596432afdb9e9757ec11ebdd35c5a6e87239545c48466913a646980104c8fd7a9a335e177f04efffe9dc952dfd7cd5c1bb9aac6","up":true},{"one":"535f93057d46c4aae0902546550880be0b5ba67dca12350117d471d67f4f2b3f7bdff29bdc918767974c465df8fa1afa6bd6c29c0a36d51f71c4183673d906f3","other":"deb7af800cd20a647335f0feff5bfb3e182f99f4c2d1ade10da36ecfdbac3b5fba4e8f0a4595443fe395b44af3a95617669850944655def85d57cc81c5682a3b","up":true},{"one":"920a301186bdf665a721676ece7c180413369ea6eff7537f42049d9eb409f28cc864099590116e885f57368959fb2cff7003697d9b1515e68bf3fa7aee0278ef","other":"4f5ab12b9c5127c16739ad0d4f51adce90ba6736cd096eb185ea632789f4b26f1ebabdea4fd3b39dda5409ece6c2d92fd469cf4aecf9d29453e3e042c19b893b","up":true},{"one":"48a5e01e06e297dc1c640ac9601171495bd70fea461c60e7e6e2532695e45fcf68183c2e58b5e6931a6c1c094f5331efbd7f2d93d5f84efdec5a35afa2124438","other":"9194a3a4c8f3235203e48bdb10902d958d26c342805ea6365af9711213536509719d917c694f9a4fbdde6889a4c92299a5301f0275bda4dbcd2541b5bff5b271","up":true},{"one":"b3316f4fd7dec218a52331f25d17a2faf0f2a417808d7dbb80038154abfbcd2d78da074837b648cff28675f4aa0d65ddb7d15abf3d7e0391d401e313a3ef24a2","other":"be514f5f17f3177235acb24112b578edf0e373c469073226e547d18080905fd062d572be18e943f13bf9fcf5871e89ceb630a1b848a0e370ef8ef8c6d997a363","up":true},{"one":"f039df8a3206e6e17eee8e95010038c450cb4cc0b5580ed5795d4c21802e1e9d360f4528bdca794f457932b1d6a818862ec847357a861c488332ef6d9480daa6","other":"049a2b0ab4d49789dbbe1837e2d2ee5220a9401729ea87ab29385b24d79cdce255c3d2b5de6484d49ca6ce07bd41832598260c0a8c290e01d133d77f066f2f99","up":true},{"one":"89a5b92a9ca045f12c35a70084e6f41f9775a25d6f105f8c9349c7b5e107179d8a96bdbb113b2680edf5183e9a42fd64bd7b29d0dc7797c583b833f869313699","other":"eaca77d20c4ad6b87649eba21b750a4b1a2c575e06bc42679d18fce16fea15212e9a7408c16f3b24d8dfd1e397314637e72e292845d09534a39035bd9203ee9e","up":false},{"one":"e6779e3bbecf81dde8b27d652ed2726c45c205db0d0405c4580014a4c91d739830276f77079108c98ac516ffa00194e77a0795f7140bdf36069b6475e58213f9","other":"9bd4f0adb9a966cc5ba632f1b540fe9cd6c8e39fe1a041b315697679cfb04b735952062ce057d456677cc34a84301f26bb727a4ab2646fee734f80a22c620746","up":true},{"one":"b4a5efa9028b2d196855393892f79993c2812d02b758f98813ddf82c5d943faf6d66eff811cc5a51936c118f4c768c0d13b54902095e040c602761e63c08655e","other":"5420da16f7ed5de6b498dbc9a83b7e92e1f9900a6d04ef7351a0bfdfd442b98a5634f28fcea32ba3f3166d21c8ff5a39be70895b32acbdf7592d1d616a345a21","up":true},{"one":"ae4e21e1587a8475afd299e00ca7085c7bf2a44c2c64a3068f12223d9202b0125094385319034691ec26b497ec9cf18fe8c0839224bac1b84279410241cef979","other":"1f6d803a4ca186463772850ca0901fb920af7e74fdd2480c3c368fa707838ee91bbcfb57d5e3510c802b9b85f2d954f04c9b675414274bdaebae6488dcf94c10","up":true},{"one":"3612863ce0456c91785a829bf5c9d2b2fb97dda083a1847e5a4ebaa6fce1260faf4d1eb374c2225431a82774163835fb59c8cb0fa9fc0969eab5410c71109cc2","other":"934a5fe1b91c1891ef4df7f67c027e0eb115d4c2ca4a1b76a135ebd4315c4fb835d6625223194e6a134407b38b0d3928fbc7bc924a3c6a538989a6cf200bf4bd","up":true},{"one":"f33d1f3e460574706ac1c7fc9ebb4683b173496ce3e80017d1c3521bca03d5a41a9c7a6cde8347d2238917b7cc58cab000ce7ccf6bb408561015a2ecbe613408","other":"8f88c7ec044f758f29bd8d12a5170bd973aec8f6cddbf512b910c4b75a0fec09c5e198bcd65622037f897759db68da2328b4a7ca93585dc9cb62e46d2a6c0864","up":true},{"one":"9c30ad8c85adc7bb52ddcfab2e661cc3a854a689eaa59128d35129d02cd5b0f8da4a44cdd33934a8e2c8fab1760c16d6f2e1c5eb227dc819e85624e63343c069","other":"07f25fdeab2b44b2e92fc80fca7de9e4a8547d27a98a54593b3395c270a9ff3f2a5da62a2e8531ce86359f0cdc5b6513b773dfd64cce1b83e47065d9760a2c7e","up":true},{"one":"7b35c856916eb3fc1b1f451667e240b95aff8f4731cc0f6743740923081ff1ddf2eec81bdccf4691a7bcc053d23eacfc15809c384a73448f618317bf605bd1cd","other":"7aaf7817b93aa6d2f50513791f9ad7629a901ed0dcb151189f44763f83423446b20ec79a48fa260cd9bc2907d5f0ad06b2c4c5e6d812f3d8876c8020ebe41019","up":true},{"one":"72e30d4562673c5c8fb03709d93f73322747858d723b7eb5ef2fbb88e0331252946b7e93ffe434fcb599c4fff57800afb29e6c60a719f18f49dba541c3591c6e","other":"07c63ca5d0309e30d1ab12e7fc142e6d37904b552639cfa97850161491f28f20d87e0304be29357bcfc2ff52fc52fd0d4f6e6011ebb239cced8b5c8dad7abf45","up":true},{"one":"66beee3968dbcf3addc6feaf070a4e3e82b5bb164fb72f40add89f732c12e8d0a31a7ee1f1e24a4674e4dfc9a4912b02c17ce3c224d257d78b7156544d6507dc","other":"8f88c7ec044f758f29bd8d12a5170bd973aec8f6cddbf512b910c4b75a0fec09c5e198bcd65622037f897759db68da2328b4a7ca93585dc9cb62e46d2a6c0864","up":true},{"one":"ee36d1d5dd69fd30242d7da2e941b34ade5581c7164fcc43288ecfc52937a98f1b31ade5d1e4dbf611cbe1c7875b2840c89435081cde471c271d7bc60e9ef211","other":"81288bb0584b7ffc1546043e052e1df10fd5371b35dedd0bb42ec5b30ce69b741b2f7857af5984d4754b39d7253575fde9298504999b78380ef602d391c4bb1d","up":false},{"one":"84abcbc7b5598ecfd91ceace0927921a5a3404fdb274fc2a2549abbede5f8e4f62c15688a4dc9a2d80262c45970c88898da245c6eb779f327a81d53a17bbc74c","other":"84dfd4e4d9f1204893f190eacc4c3999e175c433f70de86e335d27477c097a0552f211a21764f01a708da4c9e9e6552191a61d3e48f41d0e84f01e7ae3beb34e","up":true},{"one":"b137cf2291b530a39516d882200848e7f27a2710e0839b4d25b4f367bea6a0c3aaef8c7c7851c00a2945adcd819ea0508610afc1f453b8bc512b7b4d4faacdf3","other":"2f360209383d6de4ebd3b4abaf77796520b8654270b03f2151eac4a01b4417d7e0668c1f9ad30c20ff49aa8a0ab33dba5e6095619d1cf04b7af841722ab773da","up":true},{"one":"eaca77d20c4ad6b87649eba21b750a4b1a2c575e06bc42679d18fce16fea15212e9a7408c16f3b24d8dfd1e397314637e72e292845d09534a39035bd9203ee9e","other":"e2e0419a41bdfc5bd76deae2ddce6ac865f886d764c9bd18799b79fa3b2b6ba66d765d26da2037e98317e1d7e8232a61e63c1d0cfa98c9137424151b46e07171","up":true},{"one":"ce0a09bb6fe4c9c93c3dbd800ca9c9ac0714f26a8f8dac2149b6ce7a9011912a5621ea2e45de35c4d31dfe5add00558fdba5dd21acf2d81ba391e82b5b3a5804","other":"1b6cad4f9851cc584c5d1405f976bb51a52e27ef4525847df543dcca65ca5eb1ef229dcc68ccbaaf00ab1e044cb5990dd213c805bdb4adcceb6fa70b5c61fdb4","up":true},{"one":"b35f418c7935cc54278e90978c3ef1521ab91daeaf9f1ebc1cd25211611ade091cac4e1f009d71059279d507322a4536501980ac0dd44caddc52fd4c593879f7","other":"ae2a996d3b562cb47a564934037949da83b1bfe194c23754f3dbe2372ec27654f4f3b6cb7f394570f308025589c065870477667e5560dbe5a8ea1625740699cf","up":true},{"one":"97981f4b825620985b746c85824d7a4d307ee25d60a72c2b7de4b1d4f3b1c002652adc3045842d350f849789e410a0357a0b42fa637a1b4fc9d39e44f8a674d7","other":"9e621c3eb534855ca292efa27a3fbc89b4f05c80a4bc65bcff2f14ff28ef43cbe14137d2fddc6fe2658bb06947d918476b479dde71469b8680e5d8a7a01619b5","up":true},{"one":"6f60ef501b41f9049419b033ae8d793a18067bdcd60347537b0dc3873bdd9a2d10d24909cca7c39781765746128c2165596f6537a94f58279523faee71f9c51d","other":"ba21a373781966135d6225adae024a3f3e421b852f72f8b0569cb92fcff87c33f7e5b799a509b8eff6ec6dc46a9b17d5bae1e91ec7c54c0c712d893d54b140fa","up":false},{"one":"baa5924e1547c177011285d292aa161a15e5ff282da2cd0afb83c9caffb07bdbb3662c227fa7b26e6dc8be9b8863e647eb5f8ce81640532f8f5c9a7f36557e63","other":"94088fe273f76e62ca4e43c095ad12215b4ae4c59942328b3985416fb19bbda0cacc143a49eff3fb644ad53a19d3f043260e43dbb70a0aa9c15829c21cecd3c7","up":true},{"one":"afe5b217dc512eee45575c189826ee5640d11a0ac9e8e4b03e9e62e6cf6df9de500bc8a36cb7d82a2280ce184409164f1772cc5c9e59ad04361522d2b8c364e0","other":"329145e75496cecb5f5c8f00313a52ddd8c0e8cd27ef1b2bc1b2b56e4d4089aaf5a7a3c4d9a40bdb92483fa05bd24d1cd0fd51883e30439dffa0fc855e1a7cd0","up":true},{"one":"b2538d4edfa736bfe2cc21326a44ce62f716b3480eac93584a2233b69c98883a2bb255f246218a58cecab1d0d176e6d1fbba9782fd70d4603e01742299b9ea9c","other":"396c703d27bfdddf91761f134cbf665fe61e0b3a5d24036a4105a625f72e8c28b821e9200f20d6e8f8b3ed6b95bda6b8accdd840c2f786720b7431e3af2af981","up":true},{"one":"8ca3b63cb84f1e9883d82809a9b6777ec1029ecda96fe93b4d494ee9cbefcad13f381b3e480136e542e01054fe1ede66c65db84a0009871ce49383db461c8438","other":"396c703d27bfdddf91761f134cbf665fe61e0b3a5d24036a4105a625f72e8c28b821e9200f20d6e8f8b3ed6b95bda6b8accdd840c2f786720b7431e3af2af981","up":true},{"one":"c8b0dba45104fc7c7dff3ce078a0d3f5ade6198bb4656e2bee8076387929133e5ef2bd293b130a9d4f6a6974ca17e8b4a8f406d1219880f1e0f99c65c63af5a4","other":"5420da16f7ed5de6b498dbc9a83b7e92e1f9900a6d04ef7351a0bfdfd442b98a5634f28fcea32ba3f3166d21c8ff5a39be70895b32acbdf7592d1d616a345a21","up":true},{"one":"759f46661056bcbb30c7706c9fb87e22a30feb523bd53ae5d18db043efa45b49a2b8982abebdd598fe0912a05896390ec2eabe5e160cbafc0771990708ad8c28","other":"6ab6ec15635b2fda22542c99df0a3313ad4583ba0fb3f31b8f314e3ecad446d3fb0fdfcd2be9b08374b1a7e049fb68e69e8dacdd13f1df5007a656f6b11adc5b","up":true},{"one":"c332fe1f9b6e25f72c7150631ffa6e0929ff6eeab5d17aa45eaf669bdde869cf404505ae990a529aa3ca797cd0a96f31cc41431a5d4a163132be566f91623c08","other":"2ca05ffc0ad771e1e045a47f1c0a79ce374a25e3c0e53c2a80d67e7479677003f62880251a83a5074f1c9651d828f1ff7e352935a9df141c1eb75a0c59b00a8b","up":true},{"one":"e67e495385e7cacfe659b40d1ba94d4b1ff55eada70a4d9740a9e452fbf221672bd0a897b940e2a6bed71e2a16867fe45bf0ea0015435ac6d815690e263b1899","other":"fe62314839c93d2f6e3aee984d5f0b321897c6f39e66800d3de8b773baf6f19e0a03cae025df512aea8d5f1b667b6dbb15c192a90a76d3031c14e33e5c16c4f7","up":true},{"one":"adfba6d883cacbb141cd8c59ee04d7e5d520f1ce31a81e5db2d8b2380bf801c1fe4b265a66b71f9643d13a41cb1f6fb4b83399be786da4b6e171b6784bc56e49","other":"d7a319f69013b8375e64d19f015547462c84565b882337998f9e669c5fadd3d2ecf6374109903003e09f5d453424b5c7fdf52163d2cc8084cf81f94844946b63","up":true},{"one":"5bae82d4832092c17bd11474f7748015b8b69b896ab8f683a7c0024fc98740cecbb9e31c6275269f9000e5bfe51d7f45cd5dcd4433e0c87b5741685b40fe3983","other":"ee36d1d5dd69fd30242d7da2e941b34ade5581c7164fcc43288ecfc52937a98f1b31ade5d1e4dbf611cbe1c7875b2840c89435081cde471c271d7bc60e9ef211","up":true},{"one":"732393b99c490c76fa45e3e404ee095f2fa445fcc123af7ac8ab1d2fdd7cf2483f5b82bb818bd8a82b1a3b73e63bcc2c83d8f24d9aad9afe36503735e7967be7","other":"c83985973a9564ade7d90aa54911ac57077600676a1d27292d98e058bf1315887bad84ccd708cb7f52a695a1405fb7d491d7ca2ae9caa3ff58a5ad78ce4dc9d9","up":true},{"one":"e2e0419a41bdfc5bd76deae2ddce6ac865f886d764c9bd18799b79fa3b2b6ba66d765d26da2037e98317e1d7e8232a61e63c1d0cfa98c9137424151b46e07171","other":"e1ecad3beeb6c19dce551e4a603c7b440b4498c44e298dc67bfaf4ed2c75bbea95df48b1cd1318e2ccb962cbae7c30ff258e73f8c3fc6b7e9ae7a47f7cf8e53c","up":true},{"one":"57b47f692f4d69a5d2c9c193680eb4ccb5a6c574662df0138504a549f3ea74f20c5b866ac4d9e76c4b49c83f5fd692ead928ea20dfcf643a11a1c1e841c0ec42","other":"bf4ff51cc3d9a9d8cefd7e346ce1384d06450228a6086fe12fb0c60fec54bb6478f090bb638fbdbf8f41f7bc6420cd8a5c8b1b8566229b6851167375ef412f46","up":true},{"one":"8f88c7ec044f758f29bd8d12a5170bd973aec8f6cddbf512b910c4b75a0fec09c5e198bcd65622037f897759db68da2328b4a7ca93585dc9cb62e46d2a6c0864","other":"abd8f5a4d700c06ec00684b23d2d25c4df1a9554fcfc57b0ddc3fa476e6a699ba75e1213449f900803f83ab8194c6746664b547202047f35b8b3e216c7147bf8","up":true},{"one":"831cde5b651ba327b059da4c7f84b184bdd6bb99c6690ae816affe25d42c6c3dbe5b59e2b6bf23e9d0f6c485bd341ea57ba1a8220d18b0a40e156b77d84f79ef","other":"be026dfb24847cac2d00f483104edad06ca8ecb9e1229c479ef5650c7b427cd5dc34a1cf06172c17c9d0406ce17009712e82446394743d4cd9bbc41c537ebc14","up":true},{"one":"4314b0b04331973ed29a58843951f144ac3d09bd5d57b6cd9aaff9b73a7b2ec81e344a3e4ece462bd2081b837a06310e787ef3bb889dabad46fe7efd394c8342","other":"d4b7c787981abec24353c7d496661692233797e3758189bf909a69fe87935bf6da0940daa4f12e81f20c5e88f70b472113688b71a0ae2f91a73ee0e6ff4c8591","up":true},{"one":"c83985973a9564ade7d90aa54911ac57077600676a1d27292d98e058bf1315887bad84ccd708cb7f52a695a1405fb7d491d7ca2ae9caa3ff58a5ad78ce4dc9d9","other":"54b3c57a4adf4dbaf31b85ed1b8dccd6249faa16dd96dd230189f47f57970caeed36627cc8e1b0794707418d580f5bd6001c07be6a79216695f1253db24926bb","up":true},{"one":"9ce6b9decb69d66075993e903a0727ec109a04335634616097c0e60b08f94f764634fa00891b1070f6ea1ce896bc7d11d3aea92a00f281f902d960894cef296f","other":"bd1a7c63fca9e1fcc67d7fd62670beefe2bce483cf1dc1233ee85eb90db607917cd9a5d7170b10e80b925a20e2af2c54d286b01805ac34967410859f4f03da09","up":true},{"one":"48a5e01e06e297dc1c640ac9601171495bd70fea461c60e7e6e2532695e45fcf68183c2e58b5e6931a6c1c094f5331efbd7f2d93d5f84efdec5a35afa2124438","other":"6f60ef501b41f9049419b033ae8d793a18067bdcd60347537b0dc3873bdd9a2d10d24909cca7c39781765746128c2165596f6537a94f58279523faee71f9c51d","up":true},{"one":"ba21a373781966135d6225adae024a3f3e421b852f72f8b0569cb92fcff87c33f7e5b799a509b8eff6ec6dc46a9b17d5bae1e91ec7c54c0c712d893d54b140fa","other":"485825745d97654cbb92a14e0cd1078691d3c28f4d82b1046284b676a42b44ca58eb43474e45e415d3bd3f3c383f9a1a3365821ed7ba6a9f2603b29d58031dc7","up":true},{"one":"1b063741c76fe65e62b4eae42751319d0cce66f22dde9f1cf83d6cca249a0e65bc7f6f22597697362fadd226222fb3847f8e146961969d1b4c9f7e475389cd8e","other":"68cc8b9a995eef6170abf88bd5fedca06ffcc8d75f247f6041c13e7dfd292727ebda1ff86b776e33b6634355c55e0f8c22fcdb5f9a6e2f22fe1af7854c3b4273","up":true},{"one":"b4fd11306b1416a9bcf4719578976188e104b8c5028b9abd3214d257446b97b70a22e6c00934d80caddde15e8e4d16af03bb399583047983fba373d8313226b7","other":"ca1aff0d847c6fdacb623ad9078a0885b3208614fea20d5ff11779779b486bf5e9c794aacf848d3c2d58cfcc1eda8356df82f5fbdd0a5236beffe8e6042848c4","up":true},{"one":"a99852c5bf08ea4713af9cade5343d1259bfb90401aca7fcff18c58cd56a98804dd16c61fea71039c0ac31b9bbbb9dc5aeaf0c2f074d3365e88d17031802d636","other":"ed6c793eb4565aa9d883a76fad6c97ad0b878b9ef0235e11e89db1af25a9653205f725c6ea258b84bde134f1a6437c6d109b859d17509e5016c4ab98be59032a","up":true},{"one":"2245f3bf1a3b4e92f912affc75f757cf648b20474c11ffe947884f216b8f24f9dcb6e6a0358a4061b8517478ec15027e185b2f05a777573b4940375bf4aaf2be","other":"4de378164d77a28c90cf162dd1b465e0282ee17aa7d3bb3179252466f72da33a36c9f298f7c9498e38dba4018e7ce3e5fe631c83842cd9059e23a7fece366d87","up":true},{"one":"cb310c0e86aa455d7c9af6394ae38561c901da30a51d7ccb7e66a09d9a8f192ae8caeff106043426d56397088f141c4e01e3b98f1ee583ffc7318b5f730f3ac7","other":"535f93057d46c4aae0902546550880be0b5ba67dca12350117d471d67f4f2b3f7bdff29bdc918767974c465df8fa1afa6bd6c29c0a36d51f71c4183673d906f3","up":true},{"one":"657d5370319128d24d925b41065eb619409d63ec6280975d78877a4028287463f6442f5206dd703569a05b2b542ad8bbb99803da265408208d6356a26d283d08","other":"0cacda5560faff9d20e29a0625d3cd340ec075f198a50ab8b79338cee0e0db84c7c7e71042fd8c8f73e507b570de5d26c39473136b575f0167625a1168309ec5","up":true},{"one":"3e488a7208ce0e097ce47fc6651a13e95cae137d1a054a09b04d2f59d45faa2594a8c3b395e77ad1a3c2edcd827dda73c0c97dbaa6d9519a79184a0aca01ac4b","other":"ff6f94005d1df7677600069764855c1c2aa0543cbe9f480f8feefec76c49d9e2c7bb2d8e38c89e9430f53f8b593d93f143c45985a56a5a32c736128214c95eda","up":true},{"one":"5eccdbcb15ef42dc96abcbcd8b8db75d9230de10e3c650620737f6cc04ba4fdbf59ded5daa801901c191be186c329ebcd37ba83bcf794064ad4e11bf10d3f775","other":"3b570117addeec03c2694baf28e246f91907268fe665c6c90356120332794258ee57a60853c19e9fe25d042ca42a5be7fe0797d84199174de8132f1ef4a9349b","up":true},{"one":"4e95fb8943ef6502fa470870a7ace4ca11e18589bd2073167543a922317b35e40b5068934d07e56c8fdd23354dfad51fd2899db854f189841f02b5914cd97749","other":"c73d088ade8756c74832c73542bcdb3e52f670f7a74ad3a7eac2a9e3ece6bd081f782a8e1d3f9a40b9aa9201509110f37fc57fcb10ee1ef3ef07b7eab019782e","up":true},{"one":"7865b82e44add2cea6ebcbaba9c152184331a2940fe73f6f9bb940bda8a59ab4cf4760894b9cadcaa54e36fbb712ad619346a49a85e32cdf2b53cda1ac1e0658","other":"07f25fdeab2b44b2e92fc80fca7de9e4a8547d27a98a54593b3395c270a9ff3f2a5da62a2e8531ce86359f0cdc5b6513b773dfd64cce1b83e47065d9760a2c7e","up":false},{"one":"57fb1bb32bb2b1a87e44c6a7557e9c47c2032d107bcb0e34acd9ffd54d5d3df5701232db16f62f7549ba2721021898b03160b1dc5201e79606648c1dbc4a373b","other":"66d0c5da973d9dd65350ae1ec63776872cdb7ded6afb6f51ae82259f6fd35e884375d15de290625f02ed2e5cdc3f591decb45e5fc64d5b0f835a216fd196f5a3","up":true},{"one":"855bdf057f4a6b095e2000ada199447b5b4f2f8d78d2ecbaa0ff1fbf761788870ee999266ad3b26efa02be1a46a4d92ac0debb85a2ceab3442394ee7d99e5355","other":"ee36d1d5dd69fd30242d7da2e941b34ade5581c7164fcc43288ecfc52937a98f1b31ade5d1e4dbf611cbe1c7875b2840c89435081cde471c271d7bc60e9ef211","up":true},{"one":"4b784f072b7c96c30612767425f552e30e45157e70139dfbe0ae4ff86dc31601adec60f8a3ad9747b02b5219073d8813af9b09d59eaf7ddb7ee24856aff6fa8f","other":"1b6cad4f9851cc584c5d1405f976bb51a52e27ef4525847df543dcca65ca5eb1ef229dcc68ccbaaf00ab1e044cb5990dd213c805bdb4adcceb6fa70b5c61fdb4","up":true},{"one":"e087230634f556b818a416b66ba3f1d1dbe3e0dd0698bbb26fa86a2499acd169466f564dc18adf2f9be4d1ada0e86c11549754097601e10aff4f3a57ddffa24a","other":"f9ffe87c52ff4c22bd9696af32e0a9d34bb81fb84d9d8bf5aafe2ef9696e7b3d6460bf2a93aecb066133f53416bde841a02d6967bd06e3d4a714f3b2c123a947","up":true},{"one":"a127faa19dcb7da585983d36a8e9d3e9a44a6db68507b60c70da71011f44ce377944802f39cd65f5a705cd8249ac1ef7ed8fd699349098f3f8e23b37592c80ae","other":"7f357b8d81bc2e5c6fcb081f23a42b3e2439f050d45c45851994a268d1c71fcb1f39f8c3f75ce921d3fbf80fc0e73f0b9609d72001dc4a6b65b526d312a4f43a","up":false},{"one":"a7378ee34876af17c6cd94a69b6b741ec7891ff5375bc4241d48608d047455ed48e6baae80ee88d4710c69ae615cf195cee26c94b54de1bb935628ce1e3a723a","other":"b4fd11306b1416a9bcf4719578976188e104b8c5028b9abd3214d257446b97b70a22e6c00934d80caddde15e8e4d16af03bb399583047983fba373d8313226b7","up":true},{"one":"420b9c90584651c5a3fe3c16aa377444a321dca934f8a097d01a616554067feabebf2fdc8d2a25797f29a8fef30d5e2c82f8e85b20f509a880367b9b0ccdea47","other":"7865b82e44add2cea6ebcbaba9c152184331a2940fe73f6f9bb940bda8a59ab4cf4760894b9cadcaa54e36fbb712ad619346a49a85e32cdf2b53cda1ac1e0658","up":false},{"one":"f9ffe87c52ff4c22bd9696af32e0a9d34bb81fb84d9d8bf5aafe2ef9696e7b3d6460bf2a93aecb066133f53416bde841a02d6967bd06e3d4a714f3b2c123a947","other":"f5c1215a84a56d52f92ca0dc3a32df98c98a9c2ea2e9a34560210c16de1b440d20d043c8c25955dda8c22e55e92ddb49fd82e8b9b84072aabaa755a229bb19f4","up":true},{"one":"84dfd4e4d9f1204893f190eacc4c3999e175c433f70de86e335d27477c097a0552f211a21764f01a708da4c9e9e6552191a61d3e48f41d0e84f01e7ae3beb34e","other":"1b6cad4f9851cc584c5d1405f976bb51a52e27ef4525847df543dcca65ca5eb1ef229dcc68ccbaaf00ab1e044cb5990dd213c805bdb4adcceb6fa70b5c61fdb4","up":true},{"one":"2b70e5ffcc0bb1c4f8acc09dd1016e67c9c96c92d091ad481efbb71bd8b2a5a5869c6d668617a9b2cbfe91baf5edfe150c3824c84d90899a974099071d171441","other":"8ca3b63cb84f1e9883d82809a9b6777ec1029ecda96fe93b4d494ee9cbefcad13f381b3e480136e542e01054fe1ede66c65db84a0009871ce49383db461c8438","up":true},{"one":"88d5c5fe61ee1e6fa5878e0eaa13bdabaa0ec3d38a5d25b95a467da7627424f25fb5d30535aa0a5ad01c16fe2598dbf570b78cc152a7f4ef66d46fc9ae43592f","other":"3612863ce0456c91785a829bf5c9d2b2fb97dda083a1847e5a4ebaa6fce1260faf4d1eb374c2225431a82774163835fb59c8cb0fa9fc0969eab5410c71109cc2","up":true},{"one":"5dc69635f6d573c824ea83b18593a47f9f21a6f91ce18d2bf977c97d21f8d2a8ce88829244d12a07d949bbd52fe8a2035bc89685fe1bdd4ee20d766d75d3deee","other":"f33d1f3e460574706ac1c7fc9ebb4683b173496ce3e80017d1c3521bca03d5a41a9c7a6cde8347d2238917b7cc58cab000ce7ccf6bb408561015a2ecbe613408","up":true},{"one":"9e621c3eb534855ca292efa27a3fbc89b4f05c80a4bc65bcff2f14ff28ef43cbe14137d2fddc6fe2658bb06947d918476b479dde71469b8680e5d8a7a01619b5","other":"990b1db3ab1390219e8866d39fa4441bb5bb89ad786b3e255771869fcd08906dcf63f34007481769c7462edbcc665acc0a552e3733360b8d8c310c9321a5550f","up":true},{"one":"9db1f94d74a00d1e5e2a391f1bcddf16b6d0670a2c6d91d946d38112c58634444b6fea8e8c05ab4b73bacdd62a0b575f6fb8729978edc216c7842b177b9f9cd9","other":"07f25fdeab2b44b2e92fc80fca7de9e4a8547d27a98a54593b3395c270a9ff3f2a5da62a2e8531ce86359f0cdc5b6513b773dfd64cce1b83e47065d9760a2c7e","up":true},{"one":"b53078000796f1cdb04dfeac424d5e3e37e30f00bd5bebf9a9ea0525c62917612b3a8f508df6bea59e3c7e4cd1aa530841f9a8af54e44f5617a13dee2c6ff007","other":"d4b7c787981abec24353c7d496661692233797e3758189bf909a69fe87935bf6da0940daa4f12e81f20c5e88f70b472113688b71a0ae2f91a73ee0e6ff4c8591","up":true},{"one":"df4c3505e09e1baa88470117b964e758c94f77a4546489ab5ab7f4aebfdce424729ace8867475715fb68f05c66c9674a5767549e266c4fadd1c703ddd735908f","other":"0c14dd51a56130c51009e3ce47c96b2afef26b7e86cfca65d8a9bae1abef13b3a7a192b422d894c39e24ab00be412d166a3571cc259ff4462d4ad8925a153766","up":true},{"one":"c57ea182bdb42ba9b0870b5c870e467f52693e5c0df752fb6eb0dfbacce7763f73caee10db40f4fd90f19f504ee586eaf9da41f5ee93ee515d885fec99374116","other":"1b6cad4f9851cc584c5d1405f976bb51a52e27ef4525847df543dcca65ca5eb1ef229dcc68ccbaaf00ab1e044cb5990dd213c805bdb4adcceb6fa70b5c61fdb4","up":true},{"one":"eab86c521f8f1ac67c015ab713f1236a08b0200757a96bf87ab8301e7967ae62361f0e14da14ca294fc8cb3b4726b52f4773101e21b032977c6a647241b59c73","other":"1b6cad4f9851cc584c5d1405f976bb51a52e27ef4525847df543dcca65ca5eb1ef229dcc68ccbaaf00ab1e044cb5990dd213c805bdb4adcceb6fa70b5c61fdb4","up":true},{"one":"2e42f845d0393d1682add54ee30b60a953ed283e75d347bc6719ae0e91f6676282e7960f1fd52e5803d6b341fb3582c724b4f9cfd7bce9ce85f13ca480c7e72e","other":"4de378164d77a28c90cf162dd1b465e0282ee17aa7d3bb3179252466f72da33a36c9f298f7c9498e38dba4018e7ce3e5fe631c83842cd9059e23a7fece366d87","up":true},{"one":"23f9bdc82efbf57d3d40a1f2617d0311678fb4a3d6a50cb7e608c649bb618124a76c7ffd17387de963e1cd28d2bd5a61c98613f6e009a8a2a90d989827b35de0","other":"8dd8ad560af84bec579cadb33d51711aa61b6ed22705010336df5a71a94591173b25e869457429c4a199b205fce8e73530e28203e18b971c2001715e610f152a","up":true},{"one":"1d0244a13affe60996fe3cf51ba624adc746de0c7ea68ec5a31311a36077c5b5495e3d95c9642875db44c7ecae6ffed22e45f2e2d024d486760be2af9f4cf2cd","other":"f54335964d9b4eb9813eb05f40ef1c523bbf0faac5a04c4737467d590fb6b55c7fa1fc5d4d32c5491d8766b9be6fdfd3ebdb25c5ffe1719f36c86ddf87ae3a85","up":true},{"one":"97981f4b825620985b746c85824d7a4d307ee25d60a72c2b7de4b1d4f3b1c002652adc3045842d350f849789e410a0357a0b42fa637a1b4fc9d39e44f8a674d7","other":"e267e71c2dcdbe5a500b23444d2d4037ea15afba8f4f2b1c0e54a274450404fbee6fa5439f7cddf4ba1aa28fa93e434b01c239add58e30a5423ca3a481584d6b","up":true},{"one":"df54af3bae257d437c5657905484e0d72e9560c46f8ba6b3437730234e05259b404cca40b0831e911605ff8a68a19e8fd7e958069ec8b40595928892f4fa220c","other":"7865b82e44add2cea6ebcbaba9c152184331a2940fe73f6f9bb940bda8a59ab4cf4760894b9cadcaa54e36fbb712ad619346a49a85e32cdf2b53cda1ac1e0658","up":false},{"one":"5df58ba12334a1b4f983d642fe435901261767cd81f8f37c43e359f5584664e4d287e8c2275995604a3b3a4823418e35cd899a3db2a7db31570e19512f375481","other":"c9cd9dfb9f90a7948ac5a42c7bd63263f2eef6e1d85547559f7d2ecbf5f9cd1eab051b8e9e661b573c275d84091a44e73f6fc6bcc91dcdb674bd5d939190fc01","up":true},{"one":"cb321c9b0fe2eb3617b8e2461aab170a9dad2c9b04a10eead4e37e551197ea0a7500eb1cb7b155efe1886486ef3d252d8ff0d309f2906a1126ca011d037da70a","other":"c9cd9dfb9f90a7948ac5a42c7bd63263f2eef6e1d85547559f7d2ecbf5f9cd1eab051b8e9e661b573c275d84091a44e73f6fc6bcc91dcdb674bd5d939190fc01","up":true},{"one":"4fe37f2dfb03707c90a6fe91dbcfd7497db70ffc20043091d50e1cee573210c144e8749340f2c3cb70fe8fc51b317d49e8734dc51ce64b3cdccdd639ae35d1ae","other":"60725e8d0e9333636e598dd666f459b4be898d9abc095ee2c1db289673e7e969b50e2093956fef5a2f1d23e2040159bbabaaeab17fc6dbbac3f6acab766e9e60","up":true},{"one":"bf4ff51cc3d9a9d8cefd7e346ce1384d06450228a6086fe12fb0c60fec54bb6478f090bb638fbdbf8f41f7bc6420cd8a5c8b1b8566229b6851167375ef412f46","other":"657d5370319128d24d925b41065eb619409d63ec6280975d78877a4028287463f6442f5206dd703569a05b2b542ad8bbb99803da265408208d6356a26d283d08","up":true},{"one":"979838eaefcff456cf1cd9c47ea46854704f5757d8d7ab907019bc422b01af4d62252579bf045d143fab491b0bab823190e2782a457fbf51aa99ae17ec9e145f","other":"453779010ed7c59761da47ccd8869d3fa8349795e57edb9eea416c0712301ea622c7683858e309d19ab137ddb0edef161d0d00a361abeecf0628c3ffabc629ea","up":true},{"one":"2ab9513899c3c829b6284e56bf2b9862dd0156ec052b58615dba77d450dac642e534ec36ae5d3234262aff54e19f99856e908b9d8c1da660a7834a445610715b","other":"92d6ef729992f0de886076e5f8cdc42cbbd70b29e79c25e0b3d22b6575d3d2508d47b42f581e335455483d43625bce4e55f88cab9ff2073ee8dab746357864fd","up":true},{"one":"ea57884dd42aec5a76eab43483bf7c4ae2c19eebf365013731de64494d10a3b4cfe34c86c79437f9012bc8cf6bd761435eefadec17600f4b9e4bc234532d6282","other":"a1560ce7c1f1d5972f027a8e9cff820611d84764aa067434a75b63887bc4268a259101486d34b7fe83dd735e799789986cd3e9b156c86ede598bd86af4454924","up":true},{"one":"17a79cb279306b6bbd35219278f6bba03111079d6c4fadcd3c5e57b09678e111bda5f8e36ca3d223e51e255d6e857363b7741e438b32ec6e6c0dc1b224071081","other":"1b063741c76fe65e62b4eae42751319d0cce66f22dde9f1cf83d6cca249a0e65bc7f6f22597697362fadd226222fb3847f8e146961969d1b4c9f7e475389cd8e","up":true},{"one":"e267e71c2dcdbe5a500b23444d2d4037ea15afba8f4f2b1c0e54a274450404fbee6fa5439f7cddf4ba1aa28fa93e434b01c239add58e30a5423ca3a481584d6b","other":"049a2b0ab4d49789dbbe1837e2d2ee5220a9401729ea87ab29385b24d79cdce255c3d2b5de6484d49ca6ce07bd41832598260c0a8c290e01d133d77f066f2f99","up":true},{"one":"db8ba71afeaea1f2964e8978a6eceeb9efa3958424424022213c8193443f8d5afd18490afa954c76360c681404809c7cfaf7e4ebd8bd1a42d403f7f1915b0d29","other":"66beee3968dbcf3addc6feaf070a4e3e82b5bb164fb72f40add89f732c12e8d0a31a7ee1f1e24a4674e4dfc9a4912b02c17ce3c224d257d78b7156544d6507dc","up":true},{"one":"2f1967b4410ea2ea8fbaf46771ba82c2846d00aecdb6f873aceae33ab38f72d0a2c2dc6046d3034f514efd090d42011d48e9ab0cb4e3caa2b49a96ef732215a1","other":"4f5ab12b9c5127c16739ad0d4f51adce90ba6736cd096eb185ea632789f4b26f1ebabdea4fd3b39dda5409ece6c2d92fd469cf4aecf9d29453e3e042c19b893b","up":true},{"one":"bd1a7c63fca9e1fcc67d7fd62670beefe2bce483cf1dc1233ee85eb90db607917cd9a5d7170b10e80b925a20e2af2c54d286b01805ac34967410859f4f03da09","other":"92d6ef729992f0de886076e5f8cdc42cbbd70b29e79c25e0b3d22b6575d3d2508d47b42f581e335455483d43625bce4e55f88cab9ff2073ee8dab746357864fd","up":true},{"one":"4de378164d77a28c90cf162dd1b465e0282ee17aa7d3bb3179252466f72da33a36c9f298f7c9498e38dba4018e7ce3e5fe631c83842cd9059e23a7fece366d87","other":"f54335964d9b4eb9813eb05f40ef1c523bbf0faac5a04c4737467d590fb6b55c7fa1fc5d4d32c5491d8766b9be6fdfd3ebdb25c5ffe1719f36c86ddf87ae3a85","up":true},{"one":"5142eea687de4248b2184e9896b245563117648e7a156255d9a7ae730313d5d383db3be1125b5accd7e743c2a5d8c3289ec559ef7cbb803b9e82cd49bb213d9f","other":"7b5c0e81c7f4e3ae29d745f6028cfa10b29a16a9c261b65fb8dd05d6eccc634612ad5d3029c8e9f39863a2cdb2682c25f090139bf5c4950e25647e39dcb40e63","up":true},{"one":"acb4088c27ee2ee130ece3506596432afdb9e9757ec11ebdd35c5a6e87239545c48466913a646980104c8fd7a9a335e177f04efffe9dc952dfd7cd5c1bb9aac6","other":"80d997b87856099d844187d3d1fa40846ded652a62c1611b35919c2543915b64ff62476636488556f678e436ea26fcc40db7c6b6bbcb78f590d61c1ff0e424b5","up":true},{"one":"57cd4c0048b459192ee46e19ec7df777e600f256e0dc8c3019431eb7bec3c020b9504ec7aea3dba8188658ca5b830ec40af6a8540ce10e04badc6c695d009271","other":"7b35c856916eb3fc1b1f451667e240b95aff8f4731cc0f6743740923081ff1ddf2eec81bdccf4691a7bcc053d23eacfc15809c384a73448f618317bf605bd1cd","up":true},{"one":"e1ecad3beeb6c19dce551e4a603c7b440b4498c44e298dc67bfaf4ed2c75bbea95df48b1cd1318e2ccb962cbae7c30ff258e73f8c3fc6b7e9ae7a47f7cf8e53c","other":"e3c8a97a2d95dd543f9e2b41d9dce6256e284296f866f4f92e9925f8c7519dea23fd6d1a11153b93c10d6a32295e7b9bcc16024e690e4a0dc84fd25ee0f31b2c","up":true},{"one":"6b01079463ec2f649db8634cb7a596261c79a8f714d954c772528e0547b017f8ce405e4a0ea9d32270848180e0f77b8c0b022cf95c85e777626edd4d24ea21d2","other":"ae2a996d3b562cb47a564934037949da83b1bfe194c23754f3dbe2372ec27654f4f3b6cb7f394570f308025589c065870477667e5560dbe5a8ea1625740699cf","up":true},{"one":"6c143960dbe3ba4c95e8debc1fda5f420a2a673eb46f7ff7d9a30f4cd2067e67ef8926bf17f0c99b16c79b6dc066b52409a11d47117d4fda4211636b1b74f96c","other":"109556abac422a912ecffec0d8796f8f16e92e8f95cecf72dc89e97a8bf1fd37aad3c66aa3cf134acade6d065c31821f977171d5c5463305b57ce3eee99a7ab4","up":true},{"one":"920a301186bdf665a721676ece7c180413369ea6eff7537f42049d9eb409f28cc864099590116e885f57368959fb2cff7003697d9b1515e68bf3fa7aee0278ef","other":"7b5c0e81c7f4e3ae29d745f6028cfa10b29a16a9c261b65fb8dd05d6eccc634612ad5d3029c8e9f39863a2cdb2682c25f090139bf5c4950e25647e39dcb40e63","up":true},{"one":"2ac93c31937ca205d61cc5c2a1b9037871cac55e9b306b999b28e19566b3316f6539455e014840ea50c2db8a7c97d78804d3a2dcd7cd9c1f32ace0d36e5dd339","other":"4e68553db7be307b8379e8bec383b5c92e4b23debcefca575d24504e2062618f74c26e60e0d9e47f096997a7f841e2c32c994124f495ef3352ef964b33fd3a51","up":true},{"one":"2f903b2fd4f9432b7d91b5c3e4c7ee3cb9c56fe7efc4baff0edd06fc75e4b7492f2c3c929755746df59c9f95d437a12ba40ac138d08f5bc7aa091f49f3b852c2","other":"23f9bdc82efbf57d3d40a1f2617d0311678fb4a3d6a50cb7e608c649bb618124a76c7ffd17387de963e1cd28d2bd5a61c98613f6e009a8a2a90d989827b35de0","up":false},{"one":"352407b42726dcd1aacc46a912ed8124b8b6a3da4e33dab742e40aa2452953d35dc8f42eddc76695ae2317e9f15dde2cd21be4ce826934695ad1847455661d1b","other":"f33d1f3e460574706ac1c7fc9ebb4683b173496ce3e80017d1c3521bca03d5a41a9c7a6cde8347d2238917b7cc58cab000ce7ccf6bb408561015a2ecbe613408","up":true},{"one":"7bbb3f3ed51cf84c077806fbd6d3578e105bc32aa6043da188793f066ad6df383a9f7cc0bd3124f4c887704bd188d480ce264fcdf178905bbda3b270927ea138","other":"0deda014fa3c0bc8f37d853e1448f95f56f97048c28797d72258fd3ba2f1f776ae11566197466596356cd172847ab02a89f4cf047e58383249fb2a4cd69b6206","up":true},{"one":"beec648d79437a5d7b4140ced45d82d035c6f64f9c67c58386703811d97c3846787eaf274d2298df809475f0b7519df696563cb8e9a5fb0a9cc419ab13fa8d41","other":"c665a6b1b7ad39b86bd4b1fe38b7ee95a0fbb1db15e91381ec9e5a235e33b69ffdc92c60dafd74b7b4dafca1b000e9274bf045abe5b93b1a9c2b31ae071a9898","up":true},{"one":"81288bb0584b7ffc1546043e052e1df10fd5371b35dedd0bb42ec5b30ce69b741b2f7857af5984d4754b39d7253575fde9298504999b78380ef602d391c4bb1d","other":"c665a6b1b7ad39b86bd4b1fe38b7ee95a0fbb1db15e91381ec9e5a235e33b69ffdc92c60dafd74b7b4dafca1b000e9274bf045abe5b93b1a9c2b31ae071a9898","up":true},{"one":"155e4879643a472420012e040a87dbff776fc1976814c0c6cd0d5e157f0d0baac04aa7f2535786c09acc2700547383d2119b64a6f62115f1aff1708738844d8c","other":"74d84cfdaf32cd4cc67771f29878f1365120bd65cc14848008d5386a81f495bf88eb4132fa38a2cc109ae1e7f02c9b97597ab9d1a9c19c945e710ab9df07cdcd","up":true},{"one":"ff6f94005d1df7677600069764855c1c2aa0543cbe9f480f8feefec76c49d9e2c7bb2d8e38c89e9430f53f8b593d93f143c45985a56a5a32c736128214c95eda","other":"7f357b8d81bc2e5c6fcb081f23a42b3e2439f050d45c45851994a268d1c71fcb1f39f8c3f75ce921d3fbf80fc0e73f0b9609d72001dc4a6b65b526d312a4f43a","up":true},{"one":"deb7af800cd20a647335f0feff5bfb3e182f99f4c2d1ade10da36ecfdbac3b5fba4e8f0a4595443fe395b44af3a95617669850944655def85d57cc81c5682a3b","other":"485825745d97654cbb92a14e0cd1078691d3c28f4d82b1046284b676a42b44ca58eb43474e45e415d3bd3f3c383f9a1a3365821ed7ba6a9f2603b29d58031dc7","up":true},{"one":"7b5c0e81c7f4e3ae29d745f6028cfa10b29a16a9c261b65fb8dd05d6eccc634612ad5d3029c8e9f39863a2cdb2682c25f090139bf5c4950e25647e39dcb40e63","other":"17917fa4da06068b587c17899569dcc768b9cd2c27117a4ed67aab26a7e70cf8d32b881db258061ffd89a332a3b29bfd963d8e171a06c3e208ba0de1c42a2b39","up":true},{"one":"f039df8a3206e6e17eee8e95010038c450cb4cc0b5580ed5795d4c21802e1e9d360f4528bdca794f457932b1d6a818862ec847357a861c488332ef6d9480daa6","other":"f915e2398aa5d4370de87504dd76c21a7d0be2581c2ab55b7a47743f1bbaef36384eaacec22760f1e914ceac9d96a10c3d66eb27475ef444e77fee979e6e88cb","up":true},{"one":"23f9bdc82efbf57d3d40a1f2617d0311678fb4a3d6a50cb7e608c649bb618124a76c7ffd17387de963e1cd28d2bd5a61c98613f6e009a8a2a90d989827b35de0","other":"cd8815d66aee8bd488d4e5e25f0cc9c71cc65349f701ea26b1d6cd9c039d16fcb473dbf270a3b33187720ccf4b0ce4f78a6d6edd05f4fe804772d5b6ec45bbd3","up":true},{"one":"c73d088ade8756c74832c73542bcdb3e52f670f7a74ad3a7eac2a9e3ece6bd081f782a8e1d3f9a40b9aa9201509110f37fc57fcb10ee1ef3ef07b7eab019782e","other":"a127faa19dcb7da585983d36a8e9d3e9a44a6db68507b60c70da71011f44ce377944802f39cd65f5a705cd8249ac1ef7ed8fd699349098f3f8e23b37592c80ae","up":true},{"one":"cb94a8270d0050378116b5815ff17dafbe20f5303839c4fd57b981d4687a4b145e4bccec7e9af9b9475005930148ffbfa97781a0762c8e9f352dc95565fc8732","other":"ee36d1d5dd69fd30242d7da2e941b34ade5581c7164fcc43288ecfc52937a98f1b31ade5d1e4dbf611cbe1c7875b2840c89435081cde471c271d7bc60e9ef211","up":true},{"one":"e6779e3bbecf81dde8b27d652ed2726c45c205db0d0405c4580014a4c91d739830276f77079108c98ac516ffa00194e77a0795f7140bdf36069b6475e58213f9","other":"62dab8b21640e1b44dea452dd7e7de93f27a44840da72d56b11aa96e8463f3a4bb15e75a954d19fc897ae0030b16181d271b79d8198b7cffcddaa9ffcfdcce73","up":true},{"one":"5526d86ba9df651091d88460a9bedb9cedb957d452a635e1db46b9fed78082022adec0047cd7485956a4ecbb0e18107595de0de3c35242527cd302bf74a19260","other":"2ac522ebfa49d37f86c6270ad4cdad0e766493f0e463b18c9906c70fbd2e5c6ff6b0d5879de6e3894418370636963a78b0c0cf087a8684c2ca30c9c736e49228","up":false},{"one":"1944f98d4db32c56a5efda5a79aa5f276bfab1e084d6611fec0e735b8bc0f45b457cdb74a23fc83b2377821fa8316123c9877acd6db7c41058ca5d3cfedaecf9","other":"53df9cce9b0169e58ced53a123d1d8f6e8fdcfb4c2d781ecbb91bb7c8eba36946dd9d21c749259769825d8a6b3faa6bb87c8c6085a522f8a3e376061f59144d9","up":true},{"one":"389b5c1a805f87427e6d647ec5488342a3f7d700615943d5ad98ca5c111f33c7ee007970b4d3e475892095c0d5a79b7ed52d12598398818159000d4b9b719126","other":"4e95fb8943ef6502fa470870a7ace4ca11e18589bd2073167543a922317b35e40b5068934d07e56c8fdd23354dfad51fd2899db854f189841f02b5914cd97749","up":true},{"one":"990b1db3ab1390219e8866d39fa4441bb5bb89ad786b3e255771869fcd08906dcf63f34007481769c7462edbcc665acc0a552e3733360b8d8c310c9321a5550f","other":"07c63ca5d0309e30d1ab12e7fc142e6d37904b552639cfa97850161491f28f20d87e0304be29357bcfc2ff52fc52fd0d4f6e6011ebb239cced8b5c8dad7abf45","up":true},{"one":"302c37f28c69fdcf00b39ce0c0223de0d94cebc2c0b068315b95b76b5432573ead0656569441029ba9054d8d3d959fd8735e73913af5ce3f1132f8271fd437ef","other":"a127faa19dcb7da585983d36a8e9d3e9a44a6db68507b60c70da71011f44ce377944802f39cd65f5a705cd8249ac1ef7ed8fd699349098f3f8e23b37592c80ae","up":true},{"one":"68cc8b9a995eef6170abf88bd5fedca06ffcc8d75f247f6041c13e7dfd292727ebda1ff86b776e33b6634355c55e0f8c22fcdb5f9a6e2f22fe1af7854c3b4273","other":"315b8a1711f680c2eaa607e35ef7a9e19c2b61721af8a7e08f1325dde1fe33cf1f47b3cc4acf12d541631041cf1b42754875fd1c9b66ee32797b72b9f7711256","up":false},{"one":"396c703d27bfdddf91761f134cbf665fe61e0b3a5d24036a4105a625f72e8c28b821e9200f20d6e8f8b3ed6b95bda6b8accdd840c2f786720b7431e3af2af981","other":"049a2b0ab4d49789dbbe1837e2d2ee5220a9401729ea87ab29385b24d79cdce255c3d2b5de6484d49ca6ce07bd41832598260c0a8c290e01d133d77f066f2f99","up":true},{"one":"fde7705f5013c3b6b76a35505c1e3d57c033a337f2a71e912ec3a3d2da8e113bd7c36d94908357e9f7654660621f647ad8c66b0126dfe91dbfa3b8c7bd2183d3","other":"7646d08b3e24183e3814de130235c41eb88a5a2abff23eaff3c91954ad3ef55fe27da422dac5b894312276bf1a2f1aebb8b636a8d4a0c93d9b016d441df3fa19","up":true},{"one":"2a63d875e715c2a43302d32d86d30c7d7faed46c08a67bf488762637216b99dd87333a66df6d9f3a57df863b1f1a219ddbeebb9f3e92e523bd08540a195448ca","other":"cb321c9b0fe2eb3617b8e2461aab170a9dad2c9b04a10eead4e37e551197ea0a7500eb1cb7b155efe1886486ef3d252d8ff0d309f2906a1126ca011d037da70a","up":false},{"one":"9c30ad8c85adc7bb52ddcfab2e661cc3a854a689eaa59128d35129d02cd5b0f8da4a44cdd33934a8e2c8fab1760c16d6f2e1c5eb227dc819e85624e63343c069","other":"420b9c90584651c5a3fe3c16aa377444a321dca934f8a097d01a616554067feabebf2fdc8d2a25797f29a8fef30d5e2c82f8e85b20f509a880367b9b0ccdea47","up":true},{"one":"72e30d4562673c5c8fb03709d93f73322747858d723b7eb5ef2fbb88e0331252946b7e93ffe434fcb599c4fff57800afb29e6c60a719f18f49dba541c3591c6e","other":"9e621c3eb534855ca292efa27a3fbc89b4f05c80a4bc65bcff2f14ff28ef43cbe14137d2fddc6fe2658bb06947d918476b479dde71469b8680e5d8a7a01619b5","up":true},{"one":"0c14dd51a56130c51009e3ce47c96b2afef26b7e86cfca65d8a9bae1abef13b3a7a192b422d894c39e24ab00be412d166a3571cc259ff4462d4ad8925a153766","other":"bcf8e831821a5bca359fb824c7dc4d66906de82f3663a0a853d96880a8ca0bdddcceb1b66dd1f13f75ee20fde50fc9de545bc25767f228baee910e0dbfa8cc27","up":true},{"one":"be026dfb24847cac2d00f483104edad06ca8ecb9e1229c479ef5650c7b427cd5dc34a1cf06172c17c9d0406ce17009712e82446394743d4cd9bbc41c537ebc14","other":"5e86f39cf8338ba098a85d41e601a303fde311662b216ad32a2b7bfaf2b2b6dd1af3775784b39f2d85ac5fac96f05f3abdd8a2bd28ba16d939725fd6a33ae1b6","up":true},{"one":"2f903b2fd4f9432b7d91b5c3e4c7ee3cb9c56fe7efc4baff0edd06fc75e4b7492f2c3c929755746df59c9f95d437a12ba40ac138d08f5bc7aa091f49f3b852c2","other":"0f9f7e2dce4ca266c3ac0ec3a8854200b54487f5308e3db418461aeb5f67c81d332619b6441b468e480941e63100ed1b263e7adc20689dc3dcda578bfca538fa","up":true},{"one":"fd4968df03d767a223bf7e4dbe26b5c27048298df40e81cad50b344fb3e6837965f2646dab7ffb2891a5c507343ed84bb8bbe403287b51dae538d58fcb6e7623","other":"535f93057d46c4aae0902546550880be0b5ba67dca12350117d471d67f4f2b3f7bdff29bdc918767974c465df8fa1afa6bd6c29c0a36d51f71c4183673d906f3","up":true},{"one":"5bf29c02f07faf7ae8e46389e1b98df4f5e88c9316b5151685e6ae7b4e622cf171ff09f996aaa8ad846643b3bfcbd1ad96cdc249afccce439bb5c55246b95801","other":"831cde5b651ba327b059da4c7f84b184bdd6bb99c6690ae816affe25d42c6c3dbe5b59e2b6bf23e9d0f6c485bd341ea57ba1a8220d18b0a40e156b77d84f79ef","up":true},{"one":"7aaf7817b93aa6d2f50513791f9ad7629a901ed0dcb151189f44763f83423446b20ec79a48fa260cd9bc2907d5f0ad06b2c4c5e6d812f3d8876c8020ebe41019","other":"e023a51c5bd26e1754d6461345143e94baeac799947579ec7adeccd105de39f85afbceeb5037cfc0b820b9f4446433f034d9e7de7326d45df5a967a8099dbb10","up":true},{"one":"062e0ca43a1885c4a7ab2a5169790f9081e3e9a2dfa286b8cc592d5ccbf13d7a82b72d23361a19026d04fcf41b752ea320d98359d770aedfcee626e21c3494b3","other":"e1ecad3beeb6c19dce551e4a603c7b440b4498c44e298dc67bfaf4ed2c75bbea95df48b1cd1318e2ccb962cbae7c30ff258e73f8c3fc6b7e9ae7a47f7cf8e53c","up":true},{"one":"ed6c793eb4565aa9d883a76fad6c97ad0b878b9ef0235e11e89db1af25a9653205f725c6ea258b84bde134f1a6437c6d109b859d17509e5016c4ab98be59032a","other":"84abcbc7b5598ecfd91ceace0927921a5a3404fdb274fc2a2549abbede5f8e4f62c15688a4dc9a2d80262c45970c88898da245c6eb779f327a81d53a17bbc74c","up":true},{"one":"e0f78c59a61f2a953553cd5742c58f4a82e38e35ac7eaa237a6ffc9fb0a3a26a2d1d1afae249e611d1320f2cb25804bdbdfb6d77336449716b0f4beb3298b8aa","other":"1090e9d89cb278a30063a5396d9ba795d3bbc237c76915a6fb7d23aa1822c8535d2fccc44cc8cd2acec68444c0bf1bdf5195ebb9f3cad8dac3d94a4d9c0e5309","up":true},{"one":"8c6d77833bf1a98beabe7a92d985d13d52fb2e50768719ffbc6fce21ea676802a074b6e620b3ef80e12fad04f94a3c288d91df9716a6cfae09ef073b9dc1f2cb","other":"84dfd4e4d9f1204893f190eacc4c3999e175c433f70de86e335d27477c097a0552f211a21764f01a708da4c9e9e6552191a61d3e48f41d0e84f01e7ae3beb34e","up":true},{"one":"485825745d97654cbb92a14e0cd1078691d3c28f4d82b1046284b676a42b44ca58eb43474e45e415d3bd3f3c383f9a1a3365821ed7ba6a9f2603b29d58031dc7","other":"9ce6b9decb69d66075993e903a0727ec109a04335634616097c0e60b08f94f764634fa00891b1070f6ea1ce896bc7d11d3aea92a00f281f902d960894cef296f","up":true},{"one":"71f89efcf939294bb94ac669c8afd00def58c8dfad519c226adfa068692d588ef797116d42aa146b9d34f3be35ec7c014022640ab3c0f1f9034e44ab1a26e246","other":"ca1aff0d847c6fdacb623ad9078a0885b3208614fea20d5ff11779779b486bf5e9c794aacf848d3c2d58cfcc1eda8356df82f5fbdd0a5236beffe8e6042848c4","up":true},{"one":"0b30b36e155db04c448b662c4df695068b2331cdbe2772aae5fda84159e977515a5ff2e156bc225a9281fef2383926ba8cb11e9c1846fb40db241e524ac14e29","other":"84dfd4e4d9f1204893f190eacc4c3999e175c433f70de86e335d27477c097a0552f211a21764f01a708da4c9e9e6552191a61d3e48f41d0e84f01e7ae3beb34e","up":true},{"one":"a608a746f46d4b2e9267c65283380d6d6cb8885a64428fb77df9934bcf4dd1723587ee7c8f4a642dce266a12a6a4cf4e5c6db7fa1024158425a6753e7ab7264c","other":"cd8815d66aee8bd488d4e5e25f0cc9c71cc65349f701ea26b1d6cd9c039d16fcb473dbf270a3b33187720ccf4b0ce4f78a6d6edd05f4fe804772d5b6ec45bbd3","up":true},{"one":"315b8a1711f680c2eaa607e35ef7a9e19c2b61721af8a7e08f1325dde1fe33cf1f47b3cc4acf12d541631041cf1b42754875fd1c9b66ee32797b72b9f7711256","other":"f33d1f3e460574706ac1c7fc9ebb4683b173496ce3e80017d1c3521bca03d5a41a9c7a6cde8347d2238917b7cc58cab000ce7ccf6bb408561015a2ecbe613408","up":true},{"one":"afe5b217dc512eee45575c189826ee5640d11a0ac9e8e4b03e9e62e6cf6df9de500bc8a36cb7d82a2280ce184409164f1772cc5c9e59ad04361522d2b8c364e0","other":"17917fa4da06068b587c17899569dcc768b9cd2c27117a4ed67aab26a7e70cf8d32b881db258061ffd89a332a3b29bfd963d8e171a06c3e208ba0de1c42a2b39","up":true},{"one":"b2538d4edfa736bfe2cc21326a44ce62f716b3480eac93584a2233b69c98883a2bb255f246218a58cecab1d0d176e6d1fbba9782fd70d4603e01742299b9ea9c","other":"f915e2398aa5d4370de87504dd76c21a7d0be2581c2ab55b7a47743f1bbaef36384eaacec22760f1e914ceac9d96a10c3d66eb27475ef444e77fee979e6e88cb","up":false},{"one":"7f357b8d81bc2e5c6fcb081f23a42b3e2439f050d45c45851994a268d1c71fcb1f39f8c3f75ce921d3fbf80fc0e73f0b9609d72001dc4a6b65b526d312a4f43a","other":"9c30ad8c85adc7bb52ddcfab2e661cc3a854a689eaa59128d35129d02cd5b0f8da4a44cdd33934a8e2c8fab1760c16d6f2e1c5eb227dc819e85624e63343c069","up":false},{"one":"ddaf3f8478501cda872c056c72063eb64d5b871fc5fff70704872802289dd2d348f73bc342b7f148a90cfaae2448ebf16fea196be9df891dc71a57fb410d59dd","other":"3612863ce0456c91785a829bf5c9d2b2fb97dda083a1847e5a4ebaa6fce1260faf4d1eb374c2225431a82774163835fb59c8cb0fa9fc0969eab5410c71109cc2","up":true},{"one":"c8b0dba45104fc7c7dff3ce078a0d3f5ade6198bb4656e2bee8076387929133e5ef2bd293b130a9d4f6a6974ca17e8b4a8f406d1219880f1e0f99c65c63af5a4","other":"fe62314839c93d2f6e3aee984d5f0b321897c6f39e66800d3de8b773baf6f19e0a03cae025df512aea8d5f1b667b6dbb15c192a90a76d3031c14e33e5c16c4f7","up":true},{"one":"e67e495385e7cacfe659b40d1ba94d4b1ff55eada70a4d9740a9e452fbf221672bd0a897b940e2a6bed71e2a16867fe45bf0ea0015435ac6d815690e263b1899","other":"5420da16f7ed5de6b498dbc9a83b7e92e1f9900a6d04ef7351a0bfdfd442b98a5634f28fcea32ba3f3166d21c8ff5a39be70895b32acbdf7592d1d616a345a21","up":true},{"one":"5142eea687de4248b2184e9896b245563117648e7a156255d9a7ae730313d5d383db3be1125b5accd7e743c2a5d8c3289ec559ef7cbb803b9e82cd49bb213d9f","other":"109556abac422a912ecffec0d8796f8f16e92e8f95cecf72dc89e97a8bf1fd37aad3c66aa3cf134acade6d065c31821f977171d5c5463305b57ce3eee99a7ab4","up":true},{"one":"adfba6d883cacbb141cd8c59ee04d7e5d520f1ce31a81e5db2d8b2380bf801c1fe4b265a66b71f9643d13a41cb1f6fb4b83399be786da4b6e171b6784bc56e49","other":"396c703d27bfdddf91761f134cbf665fe61e0b3a5d24036a4105a625f72e8c28b821e9200f20d6e8f8b3ed6b95bda6b8accdd840c2f786720b7431e3af2af981","up":true},{"one":"016f8f4619a16a07fbde5a18e362158d696e4d9f104a77787f26e32a25cd7d278256f8e0db865c488a99511ec27a5eddd5ebbd1c1397fa7f8db111062e5fe959","other":"57cd4c0048b459192ee46e19ec7df777e600f256e0dc8c3019431eb7bec3c020b9504ec7aea3dba8188658ca5b830ec40af6a8540ce10e04badc6c695d009271","up":true},{"one":"b4a5efa9028b2d196855393892f79993c2812d02b758f98813ddf82c5d943faf6d66eff811cc5a51936c118f4c768c0d13b54902095e040c602761e63c08655e","other":"8c6d77833bf1a98beabe7a92d985d13d52fb2e50768719ffbc6fce21ea676802a074b6e620b3ef80e12fad04f94a3c288d91df9716a6cfae09ef073b9dc1f2cb","up":true},{"one":"ae4e21e1587a8475afd299e00ca7085c7bf2a44c2c64a3068f12223d9202b0125094385319034691ec26b497ec9cf18fe8c0839224bac1b84279410241cef979","other":"28d3232c43de54ffdaf08f97b334c012738648b04e2876c7e751a2e352aaf4d550d6efa976c5a8edbfa8e88b9d04a0fca492b81c3756ef673ab74d34182ca711","up":true},{"one":"083e67bb19e30d14e4df6d2483367d6659d9b56744d53d9cf7fd15954c327e1bc88a5d0db8833634e1dad7209164451f8934b59f76b5990059261abfd650519a","other":"7646d08b3e24183e3814de130235c41eb88a5a2abff23eaff3c91954ad3ef55fe27da422dac5b894312276bf1a2f1aebb8b636a8d4a0c93d9b016d441df3fa19","up":true},{"one":"4314b0b04331973ed29a58843951f144ac3d09bd5d57b6cd9aaff9b73a7b2ec81e344a3e4ece462bd2081b837a06310e787ef3bb889dabad46fe7efd394c8342","other":"b080891d4ba6d3ab224984360597f9c555bd1367630f5420bfaf230419a05b2be58bebf1554e53eb4c0da81cfb66d4f7697dd65143f11841ff62d8a0d82b6b67","up":true},{"one":"c83985973a9564ade7d90aa54911ac57077600676a1d27292d98e058bf1315887bad84ccd708cb7f52a695a1405fb7d491d7ca2ae9caa3ff58a5ad78ce4dc9d9","other":"deb7af800cd20a647335f0feff5bfb3e182f99f4c2d1ade10da36ecfdbac3b5fba4e8f0a4595443fe395b44af3a95617669850944655def85d57cc81c5682a3b","up":true},{"one":"e1ecad3beeb6c19dce551e4a603c7b440b4498c44e298dc67bfaf4ed2c75bbea95df48b1cd1318e2ccb962cbae7c30ff258e73f8c3fc6b7e9ae7a47f7cf8e53c","other":"57b47f692f4d69a5d2c9c193680eb4ccb5a6c574662df0138504a549f3ea74f20c5b866ac4d9e76c4b49c83f5fd692ead928ea20dfcf643a11a1c1e841c0ec42","up":true},{"one":"48a5e01e06e297dc1c640ac9601171495bd70fea461c60e7e6e2532695e45fcf68183c2e58b5e6931a6c1c094f5331efbd7f2d93d5f84efdec5a35afa2124438","other":"3612863ce0456c91785a829bf5c9d2b2fb97dda083a1847e5a4ebaa6fce1260faf4d1eb374c2225431a82774163835fb59c8cb0fa9fc0969eab5410c71109cc2","up":true},{"one":"ba21a373781966135d6225adae024a3f3e421b852f72f8b0569cb92fcff87c33f7e5b799a509b8eff6ec6dc46a9b17d5bae1e91ec7c54c0c712d893d54b140fa","other":"5420da16f7ed5de6b498dbc9a83b7e92e1f9900a6d04ef7351a0bfdfd442b98a5634f28fcea32ba3f3166d21c8ff5a39be70895b32acbdf7592d1d616a345a21","up":true},{"one":"2245f3bf1a3b4e92f912affc75f757cf648b20474c11ffe947884f216b8f24f9dcb6e6a0358a4061b8517478ec15027e185b2f05a777573b4940375bf4aaf2be","other":"1d0244a13affe60996fe3cf51ba624adc746de0c7ea68ec5a31311a36077c5b5495e3d95c9642875db44c7ecae6ffed22e45f2e2d024d486760be2af9f4cf2cd","up":true},{"one":"57fb1bb32bb2b1a87e44c6a7557e9c47c2032d107bcb0e34acd9ffd54d5d3df5701232db16f62f7549ba2721021898b03160b1dc5201e79606648c1dbc4a373b","other":"b137cf2291b530a39516d882200848e7f27a2710e0839b4d25b4f367bea6a0c3aaef8c7c7851c00a2945adcd819ea0508610afc1f453b8bc512b7b4d4faacdf3","up":true},{"one":"855bdf057f4a6b095e2000ada199447b5b4f2f8d78d2ecbaa0ff1fbf761788870ee999266ad3b26efa02be1a46a4d92ac0debb85a2ceab3442394ee7d99e5355","other":"cb94a8270d0050378116b5815ff17dafbe20f5303839c4fd57b981d4687a4b145e4bccec7e9af9b9475005930148ffbfa97781a0762c8e9f352dc95565fc8732","up":false},{"one":"7646d08b3e24183e3814de130235c41eb88a5a2abff23eaff3c91954ad3ef55fe27da422dac5b894312276bf1a2f1aebb8b636a8d4a0c93d9b016d441df3fa19","other":"829b074b70d757da6aa00f7bace3cf1b5d2d4eeadb7f370c1a85374a01a70b54ac53d747267e386f3b41e6d790fecdd6e74b8f89745501ee82439a66ea54443a","up":true},{"one":"329145e75496cecb5f5c8f00313a52ddd8c0e8cd27ef1b2bc1b2b56e4d4089aaf5a7a3c4d9a40bdb92483fa05bd24d1cd0fd51883e30439dffa0fc855e1a7cd0","other":"0b7e1e5acabcde503ad827e45724402406114a513f81040a379b0f82df2eab4456b348b27936369c49e3c264d971c6a9e2c2217fdbc5e5b93ac6fc219957834d","up":true},{"one":"2bfba66ec9d63e928d77d455f2e10a14d6213e515099d5db14fa44a8bfc147eb0fa7afa9aaccdc86453c6903b55556059a2e13dd61fc494127d4a3ec173bf9ea","other":"fe8ac5d33cd8ab6a1dad9567cdfb89b431a5c4f4a584fc608b92e7dfd06f70988e71e2f11f9fda9ee797c9ffba83bc085939fdf2522dde39f28202be92650566","up":false},{"one":"0f9f7e2dce4ca266c3ac0ec3a8854200b54487f5308e3db418461aeb5f67c81d332619b6441b468e480941e63100ed1b263e7adc20689dc3dcda578bfca538fa","other":"a127faa19dcb7da585983d36a8e9d3e9a44a6db68507b60c70da71011f44ce377944802f39cd65f5a705cd8249ac1ef7ed8fd699349098f3f8e23b37592c80ae","up":true},{"one":"66beee3968dbcf3addc6feaf070a4e3e82b5bb164fb72f40add89f732c12e8d0a31a7ee1f1e24a4674e4dfc9a4912b02c17ce3c224d257d78b7156544d6507dc","other":"2ddd49fae11d8bd2e7e75a481be267fa846f51cc1160bc326aeea51c542323ff444909de11e2731e835140bc0b1b32020e1e73fa652511a381222bf0aebc4081","up":true},{"one":"ce0a09bb6fe4c9c93c3dbd800ca9c9ac0714f26a8f8dac2149b6ce7a9011912a5621ea2e45de35c4d31dfe5add00558fdba5dd21acf2d81ba391e82b5b3a5804","other":"0b30b36e155db04c448b662c4df695068b2331cdbe2772aae5fda84159e977515a5ff2e156bc225a9281fef2383926ba8cb11e9c1846fb40db241e524ac14e29","up":true},{"one":"eaca77d20c4ad6b87649eba21b750a4b1a2c575e06bc42679d18fce16fea15212e9a7408c16f3b24d8dfd1e397314637e72e292845d09534a39035bd9203ee9e","other":"2ac93c31937ca205d61cc5c2a1b9037871cac55e9b306b999b28e19566b3316f6539455e014840ea50c2db8a7c97d78804d3a2dcd7cd9c1f32ace0d36e5dd339","up":true},{"one":"f54335964d9b4eb9813eb05f40ef1c523bbf0faac5a04c4737467d590fb6b55c7fa1fc5d4d32c5491d8766b9be6fdfd3ebdb25c5ffe1719f36c86ddf87ae3a85","other":"3dfd733dde9414af916625ab981777ff1ad7ca0f6d1e4e7d9e2739969e21182fd13d85e281868653e7325b20069356b11524b54143c47fd3955a911cf7325ad4","up":true},{"one":"df54af3bae257d437c5657905484e0d72e9560c46f8ba6b3437730234e05259b404cca40b0831e911605ff8a68a19e8fd7e958069ec8b40595928892f4fa220c","other":"9db1f94d74a00d1e5e2a391f1bcddf16b6d0670a2c6d91d946d38112c58634444b6fea8e8c05ab4b73bacdd62a0b575f6fb8729978edc216c7842b177b9f9cd9","up":true},{"one":"4fe37f2dfb03707c90a6fe91dbcfd7497db70ffc20043091d50e1cee573210c144e8749340f2c3cb70fe8fc51b317d49e8734dc51ce64b3cdccdd639ae35d1ae","other":"b080891d4ba6d3ab224984360597f9c555bd1367630f5420bfaf230419a05b2be58bebf1554e53eb4c0da81cfb66d4f7697dd65143f11841ff62d8a0d82b6b67","up":true},{"one":"59b53f8a562bee519276e0eeccfcf8c975d3102f5d0cccf5abcce291a8a5bb817c04604f123686177a50a03b9d7559ac469962d0159d1d93e4ce58a304d04b55","other":"b4fd11306b1416a9bcf4719578976188e104b8c5028b9abd3214d257446b97b70a22e6c00934d80caddde15e8e4d16af03bb399583047983fba373d8313226b7","up":true},{"one":"ae2a996d3b562cb47a564934037949da83b1bfe194c23754f3dbe2372ec27654f4f3b6cb7f394570f308025589c065870477667e5560dbe5a8ea1625740699cf","other":"b4fd11306b1416a9bcf4719578976188e104b8c5028b9abd3214d257446b97b70a22e6c00934d80caddde15e8e4d16af03bb399583047983fba373d8313226b7","up":true},{"one":"2ab9513899c3c829b6284e56bf2b9862dd0156ec052b58615dba77d450dac642e534ec36ae5d3234262aff54e19f99856e908b9d8c1da660a7834a445610715b","other":"ba21a373781966135d6225adae024a3f3e421b852f72f8b0569cb92fcff87c33f7e5b799a509b8eff6ec6dc46a9b17d5bae1e91ec7c54c0c712d893d54b140fa","up":true},{"one":"28d3232c43de54ffdaf08f97b334c012738648b04e2876c7e751a2e352aaf4d550d6efa976c5a8edbfa8e88b9d04a0fca492b81c3756ef673ab74d34182ca711","other":"0deda014fa3c0bc8f37d853e1448f95f56f97048c28797d72258fd3ba2f1f776ae11566197466596356cd172847ab02a89f4cf047e58383249fb2a4cd69b6206","up":true},{"one":"17a79cb279306b6bbd35219278f6bba03111079d6c4fadcd3c5e57b09678e111bda5f8e36ca3d223e51e255d6e857363b7741e438b32ec6e6c0dc1b224071081","other":"be514f5f17f3177235acb24112b578edf0e373c469073226e547d18080905fd062d572be18e943f13bf9fcf5871e89ceb630a1b848a0e370ef8ef8c6d997a363","up":true},{"one":"db8ba71afeaea1f2964e8978a6eceeb9efa3958424424022213c8193443f8d5afd18490afa954c76360c681404809c7cfaf7e4ebd8bd1a42d403f7f1915b0d29","other":"adfba6d883cacbb141cd8c59ee04d7e5d520f1ce31a81e5db2d8b2380bf801c1fe4b265a66b71f9643d13a41cb1f6fb4b83399be786da4b6e171b6784bc56e49","up":true},{"one":"bd1a7c63fca9e1fcc67d7fd62670beefe2bce483cf1dc1233ee85eb90db607917cd9a5d7170b10e80b925a20e2af2c54d286b01805ac34967410859f4f03da09","other":"ba21a373781966135d6225adae024a3f3e421b852f72f8b0569cb92fcff87c33f7e5b799a509b8eff6ec6dc46a9b17d5bae1e91ec7c54c0c712d893d54b140fa","up":true},{"one":"e98a08e8e3544727f5ee27f4465375a67ffba490fcdbfe7bfdc909f6b68bd279f776c65d38c2ccfc33079f852f76349c94d68fc6989c0d981f22333f036a4bb5","other":"049a2b0ab4d49789dbbe1837e2d2ee5220a9401729ea87ab29385b24d79cdce255c3d2b5de6484d49ca6ce07bd41832598260c0a8c290e01d133d77f066f2f99","up":true},{"one":"732393b99c490c76fa45e3e404ee095f2fa445fcc123af7ac8ab1d2fdd7cf2483f5b82bb818bd8a82b1a3b73e63bcc2c83d8f24d9aad9afe36503735e7967be7","other":"92d6ef729992f0de886076e5f8cdc42cbbd70b29e79c25e0b3d22b6575d3d2508d47b42f581e335455483d43625bce4e55f88cab9ff2073ee8dab746357864fd","up":true},{"one":"6c143960dbe3ba4c95e8debc1fda5f420a2a673eb46f7ff7d9a30f4cd2067e67ef8926bf17f0c99b16c79b6dc066b52409a11d47117d4fda4211636b1b74f96c","other":"7b5c0e81c7f4e3ae29d745f6028cfa10b29a16a9c261b65fb8dd05d6eccc634612ad5d3029c8e9f39863a2cdb2682c25f090139bf5c4950e25647e39dcb40e63","up":true},{"one":"b4fd11306b1416a9bcf4719578976188e104b8c5028b9abd3214d257446b97b70a22e6c00934d80caddde15e8e4d16af03bb399583047983fba373d8313226b7","other":"155e4879643a472420012e040a87dbff776fc1976814c0c6cd0d5e157f0d0baac04aa7f2535786c09acc2700547383d2119b64a6f62115f1aff1708738844d8c","up":true},{"one":"920a301186bdf665a721676ece7c180413369ea6eff7537f42049d9eb409f28cc864099590116e885f57368959fb2cff7003697d9b1515e68bf3fa7aee0278ef","other":"109556abac422a912ecffec0d8796f8f16e92e8f95cecf72dc89e97a8bf1fd37aad3c66aa3cf134acade6d065c31821f977171d5c5463305b57ce3eee99a7ab4","up":true},{"one":"5eccdbcb15ef42dc96abcbcd8b8db75d9230de10e3c650620737f6cc04ba4fdbf59ded5daa801901c191be186c329ebcd37ba83bcf794064ad4e11bf10d3f775","other":"049a2b0ab4d49789dbbe1837e2d2ee5220a9401729ea87ab29385b24d79cdce255c3d2b5de6484d49ca6ce07bd41832598260c0a8c290e01d133d77f066f2f99","up":true},{"one":"e087230634f556b818a416b66ba3f1d1dbe3e0dd0698bbb26fa86a2499acd169466f564dc18adf2f9be4d1ada0e86c11549754097601e10aff4f3a57ddffa24a","other":"420b9c90584651c5a3fe3c16aa377444a321dca934f8a097d01a616554067feabebf2fdc8d2a25797f29a8fef30d5e2c82f8e85b20f509a880367b9b0ccdea47","up":true},{"one":"ee36d1d5dd69fd30242d7da2e941b34ade5581c7164fcc43288ecfc52937a98f1b31ade5d1e4dbf611cbe1c7875b2840c89435081cde471c271d7bc60e9ef211","other":"7aaf7817b93aa6d2f50513791f9ad7629a901ed0dcb151189f44763f83423446b20ec79a48fa260cd9bc2907d5f0ad06b2c4c5e6d812f3d8876c8020ebe41019","up":true},{"one":"7b5c0e81c7f4e3ae29d745f6028cfa10b29a16a9c261b65fb8dd05d6eccc634612ad5d3029c8e9f39863a2cdb2682c25f090139bf5c4950e25647e39dcb40e63","other":"0a4eec7b0e05da799aca5b36d9e2530f2a89d1426b1fcb7d8f9a662df8a8b5b763767a20db3c9c63e0bd13c2a6e16d3ba8f03baf84f5e5d24917b3f211d9bcfc","up":true},{"one":"485825745d97654cbb92a14e0cd1078691d3c28f4d82b1046284b676a42b44ca58eb43474e45e415d3bd3f3c383f9a1a3365821ed7ba6a9f2603b29d58031dc7","other":"ca1aff0d847c6fdacb623ad9078a0885b3208614fea20d5ff11779779b486bf5e9c794aacf848d3c2d58cfcc1eda8356df82f5fbdd0a5236beffe8e6042848c4","up":true},{"one":"0b30b36e155db04c448b662c4df695068b2331cdbe2772aae5fda84159e977515a5ff2e156bc225a9281fef2383926ba8cb11e9c1846fb40db241e524ac14e29","other":"eab86c521f8f1ac67c015ab713f1236a08b0200757a96bf87ab8301e7967ae62361f0e14da14ca294fc8cb3b4726b52f4773101e21b032977c6a647241b59c73","up":true},{"one":"7f357b8d81bc2e5c6fcb081f23a42b3e2439f050d45c45851994a268d1c71fcb1f39f8c3f75ce921d3fbf80fc0e73f0b9609d72001dc4a6b65b526d312a4f43a","other":"8ca3b63cb84f1e9883d82809a9b6777ec1029ecda96fe93b4d494ee9cbefcad13f381b3e480136e542e01054fe1ede66c65db84a0009871ce49383db461c8438","up":true},{"one":"663535b22018a4ef0b151572ef286fa66c22c6e9b2913a69c4a735d4b0149bdf6c84bd83d710f8aa2627e8993b7f020750fbc6f56a3365ce4c840e2b3de1a6c1","other":"ff1e34fd51953ed641b431aa657da21cb4c81d23e4eaa13c9cce526f1f1b34593d41f9b87a0e10387fe400c623638677c0efab15dbd1014a0ccc11f9ec92c417","up":true},{"one":"6bf9fb6a25521c16c2ebeb6203d046d7dd40f29cc2ddb067c0222ef56d7012d2ee5d037f71f6668ea56767610b2a54c144aed74b7f68d06993cbd52fa1dc7630","other":"57cd4c0048b459192ee46e19ec7df777e600f256e0dc8c3019431eb7bec3c020b9504ec7aea3dba8188658ca5b830ec40af6a8540ce10e04badc6c695d009271","up":true},{"one":"0a4eec7b0e05da799aca5b36d9e2530f2a89d1426b1fcb7d8f9a662df8a8b5b763767a20db3c9c63e0bd13c2a6e16d3ba8f03baf84f5e5d24917b3f211d9bcfc","other":"17917fa4da06068b587c17899569dcc768b9cd2c27117a4ed67aab26a7e70cf8d32b881db258061ffd89a332a3b29bfd963d8e171a06c3e208ba0de1c42a2b39","up":true},{"one":"cb94a8270d0050378116b5815ff17dafbe20f5303839c4fd57b981d4687a4b145e4bccec7e9af9b9475005930148ffbfa97781a0762c8e9f352dc95565fc8732","other":"4a030ebcb1a59230759d25a3c87daed22906b520d55a78eab2083bb52358ddc3a5d2d7c3265e6c54a990bf32d0dacb85905a4173d72ac18fcd74c43ecb8635c5","up":true},{"one":"c2705ee7238ef9305e4da196653cde707649435a1e8b5b797d164e5ca06184a77af5bd7fa938c995fdfcbce724fa7eca3d908ee34891ab62cc6dfd411c3fa1da","other":"a608a746f46d4b2e9267c65283380d6d6cb8885a64428fb77df9934bcf4dd1723587ee7c8f4a642dce266a12a6a4cf4e5c6db7fa1024158425a6753e7ab7264c","up":true},{"one":"c665a6b1b7ad39b86bd4b1fe38b7ee95a0fbb1db15e91381ec9e5a235e33b69ffdc92c60dafd74b7b4dafca1b000e9274bf045abe5b93b1a9c2b31ae071a9898","other":"5526d86ba9df651091d88460a9bedb9cedb957d452a635e1db46b9fed78082022adec0047cd7485956a4ecbb0e18107595de0de3c35242527cd302bf74a19260","up":true},{"one":"829b074b70d757da6aa00f7bace3cf1b5d2d4eeadb7f370c1a85374a01a70b54ac53d747267e386f3b41e6d790fecdd6e74b8f89745501ee82439a66ea54443a","other":"807340e5fdf6c21a56ef2fd158c32e92201206ca85fcc147165a408f7a735964afd47c397e663610ac53870ae722c0317291732b0422f8aeedae783d9c730218","up":true},{"one":"acb4088c27ee2ee130ece3506596432afdb9e9757ec11ebdd35c5a6e87239545c48466913a646980104c8fd7a9a335e177f04efffe9dc952dfd7cd5c1bb9aac6","other":"88d5c5fe61ee1e6fa5878e0eaa13bdabaa0ec3d38a5d25b95a467da7627424f25fb5d30535aa0a5ad01c16fe2598dbf570b78cc152a7f4ef66d46fc9ae43592f","up":true},{"one":"049a2b0ab4d49789dbbe1837e2d2ee5220a9401729ea87ab29385b24d79cdce255c3d2b5de6484d49ca6ce07bd41832598260c0a8c290e01d133d77f066f2f99","other":"c332fe1f9b6e25f72c7150631ffa6e0929ff6eeab5d17aa45eaf669bdde869cf404505ae990a529aa3ca797cd0a96f31cc41431a5d4a163132be566f91623c08","up":true},{"one":"3612863ce0456c91785a829bf5c9d2b2fb97dda083a1847e5a4ebaa6fce1260faf4d1eb374c2225431a82774163835fb59c8cb0fa9fc0969eab5410c71109cc2","other":"6b01079463ec2f649db8634cb7a596261c79a8f714d954c772528e0547b017f8ce405e4a0ea9d32270848180e0f77b8c0b022cf95c85e777626edd4d24ea21d2","up":true},{"one":"389b5c1a805f87427e6d647ec5488342a3f7d700615943d5ad98ca5c111f33c7ee007970b4d3e475892095c0d5a79b7ed52d12598398818159000d4b9b719126","other":"e2a27dcdee1f89fa362a85c4397840cd8be4ad8d1b9ccb23188c303bcab7619f38772f71385922d090390973b62fb8249efc103f71bc761041bcb3880ec0b935","up":true},{"one":"460531928a4b084686343c8464b37c3452bb3566045698d08a4692864de5581a9eb1dc632329e7d3ccb73ec31ee7693787d69df8458efaba9a7105d87ee2e053","other":"4de378164d77a28c90cf162dd1b465e0282ee17aa7d3bb3179252466f72da33a36c9f298f7c9498e38dba4018e7ce3e5fe631c83842cd9059e23a7fece366d87","up":true},{"one":"3d2df188704eeac09c8b291bf275a73888199a231c832c51dbc3d746968d4b51a7d5eae0c7c9b8c8e19f5e28d38c375e01abefa343f31dbe221deb837ab8a0df","other":"5bae82d4832092c17bd11474f7748015b8b69b896ab8f683a7c0024fc98740cecbb9e31c6275269f9000e5bfe51d7f45cd5dcd4433e0c87b5741685b40fe3983","up":true},{"one":"68cc8b9a995eef6170abf88bd5fedca06ffcc8d75f247f6041c13e7dfd292727ebda1ff86b776e33b6634355c55e0f8c22fcdb5f9a6e2f22fe1af7854c3b4273","other":"f33d1f3e460574706ac1c7fc9ebb4683b173496ce3e80017d1c3521bca03d5a41a9c7a6cde8347d2238917b7cc58cab000ce7ccf6bb408561015a2ecbe613408","up":true},{"one":"f33d1f3e460574706ac1c7fc9ebb4683b173496ce3e80017d1c3521bca03d5a41a9c7a6cde8347d2238917b7cc58cab000ce7ccf6bb408561015a2ecbe613408","other":"76cbf9fc0f3517fb615fa96104780218e85d064ee5a1d518f3b78f4dbebf144df38c427445fdd6c9b436489c00ff9497d747a8fd70f380f95601d59e52e021e8","up":true},{"one":"5bf29c02f07faf7ae8e46389e1b98df4f5e88c9316b5151685e6ae7b4e622cf171ff09f996aaa8ad846643b3bfcbd1ad96cdc249afccce439bb5c55246b95801","other":"e1ecad3beeb6c19dce551e4a603c7b440b4498c44e298dc67bfaf4ed2c75bbea95df48b1cd1318e2ccb962cbae7c30ff258e73f8c3fc6b7e9ae7a47f7cf8e53c","up":true},{"one":"b6a998dea59194cc60ce97c7c9702368411889cb6905516b23f41cc5116fba8d0f237d418318eb0c333cad18003c0e9a6bd8c99080520771f2bad640e2e5ec1c","other":"ce0a09bb6fe4c9c93c3dbd800ca9c9ac0714f26a8f8dac2149b6ce7a9011912a5621ea2e45de35c4d31dfe5add00558fdba5dd21acf2d81ba391e82b5b3a5804","up":true},{"one":"ed6c793eb4565aa9d883a76fad6c97ad0b878b9ef0235e11e89db1af25a9653205f725c6ea258b84bde134f1a6437c6d109b859d17509e5016c4ab98be59032a","other":"5420da16f7ed5de6b498dbc9a83b7e92e1f9900a6d04ef7351a0bfdfd442b98a5634f28fcea32ba3f3166d21c8ff5a39be70895b32acbdf7592d1d616a345a21","up":true},{"one":"80d997b87856099d844187d3d1fa40846ded652a62c1611b35919c2543915b64ff62476636488556f678e436ea26fcc40db7c6b6bbcb78f590d61c1ff0e424b5","other":"3612863ce0456c91785a829bf5c9d2b2fb97dda083a1847e5a4ebaa6fce1260faf4d1eb374c2225431a82774163835fb59c8cb0fa9fc0969eab5410c71109cc2","up":true},{"one":"8d4920d6e3a6717699b5a3af068cbdfc16858d7e393d158d41b1b5f345b47129eef89e1d055386c518f400b134678c21590f0317dea3436d4cef60f45455cf12","other":"1d0244a13affe60996fe3cf51ba624adc746de0c7ea68ec5a31311a36077c5b5495e3d95c9642875db44c7ecae6ffed22e45f2e2d024d486760be2af9f4cf2cd","up":true},{"one":"f039df8a3206e6e17eee8e95010038c450cb4cc0b5580ed5795d4c21802e1e9d360f4528bdca794f457932b1d6a818862ec847357a861c488332ef6d9480daa6","other":"be514f5f17f3177235acb24112b578edf0e373c469073226e547d18080905fd062d572be18e943f13bf9fcf5871e89ceb630a1b848a0e370ef8ef8c6d997a363","up":true},{"one":"315b8a1711f680c2eaa607e35ef7a9e19c2b61721af8a7e08f1325dde1fe33cf1f47b3cc4acf12d541631041cf1b42754875fd1c9b66ee32797b72b9f7711256","other":"e2e0419a41bdfc5bd76deae2ddce6ac865f886d764c9bd18799b79fa3b2b6ba66d765d26da2037e98317e1d7e8232a61e63c1d0cfa98c9137424151b46e07171","up":true},{"one":"fe62314839c93d2f6e3aee984d5f0b321897c6f39e66800d3de8b773baf6f19e0a03cae025df512aea8d5f1b667b6dbb15c192a90a76d3031c14e33e5c16c4f7","other":"84abcbc7b5598ecfd91ceace0927921a5a3404fdb274fc2a2549abbede5f8e4f62c15688a4dc9a2d80262c45970c88898da245c6eb779f327a81d53a17bbc74c","up":true},{"one":"afe5b217dc512eee45575c189826ee5640d11a0ac9e8e4b03e9e62e6cf6df9de500bc8a36cb7d82a2280ce184409164f1772cc5c9e59ad04361522d2b8c364e0","other":"ca1aff0d847c6fdacb623ad9078a0885b3208614fea20d5ff11779779b486bf5e9c794aacf848d3c2d58cfcc1eda8356df82f5fbdd0a5236beffe8e6042848c4","up":true},{"one":"59b53f8a562bee519276e0eeccfcf8c975d3102f5d0cccf5abcce291a8a5bb817c04604f123686177a50a03b9d7559ac469962d0159d1d93e4ce58a304d04b55","other":"329145e75496cecb5f5c8f00313a52ddd8c0e8cd27ef1b2bc1b2b56e4d4089aaf5a7a3c4d9a40bdb92483fa05bd24d1cd0fd51883e30439dffa0fc855e1a7cd0","up":true},{"one":"cb310c0e86aa455d7c9af6394ae38561c901da30a51d7ccb7e66a09d9a8f192ae8caeff106043426d56397088f141c4e01e3b98f1ee583ffc7318b5f730f3ac7","other":"e67e495385e7cacfe659b40d1ba94d4b1ff55eada70a4d9740a9e452fbf221672bd0a897b940e2a6bed71e2a16867fe45bf0ea0015435ac6d815690e263b1899","up":true},{"one":"ddaf3f8478501cda872c056c72063eb64d5b871fc5fff70704872802289dd2d348f73bc342b7f148a90cfaae2448ebf16fea196be9df891dc71a57fb410d59dd","other":"9194a3a4c8f3235203e48bdb10902d958d26c342805ea6365af9711213536509719d917c694f9a4fbdde6889a4c92299a5301f0275bda4dbcd2541b5bff5b271","up":true},{"one":"28d3232c43de54ffdaf08f97b334c012738648b04e2876c7e751a2e352aaf4d550d6efa976c5a8edbfa8e88b9d04a0fca492b81c3756ef673ab74d34182ca711","other":"329145e75496cecb5f5c8f00313a52ddd8c0e8cd27ef1b2bc1b2b56e4d4089aaf5a7a3c4d9a40bdb92483fa05bd24d1cd0fd51883e30439dffa0fc855e1a7cd0","up":true},{"one":"c8b0dba45104fc7c7dff3ce078a0d3f5ade6198bb4656e2bee8076387929133e5ef2bd293b130a9d4f6a6974ca17e8b4a8f406d1219880f1e0f99c65c63af5a4","other":"b4a5efa9028b2d196855393892f79993c2812d02b758f98813ddf82c5d943faf6d66eff811cc5a51936c118f4c768c0d13b54902095e040c602761e63c08655e","up":true},{"one":"11d560045536e9d1b0b1b9e8944e00f0ca7f1e6788c9fdb51061820bbb3008ead92bb7836621bf58da7035c87a28328faecb4cb2e3cdb9d7fa4f45790e6bf352","other":"979838eaefcff456cf1cd9c47ea46854704f5757d8d7ab907019bc422b01af4d62252579bf045d143fab491b0bab823190e2782a457fbf51aa99ae17ec9e145f","up":true},{"one":"adfba6d883cacbb141cd8c59ee04d7e5d520f1ce31a81e5db2d8b2380bf801c1fe4b265a66b71f9643d13a41cb1f6fb4b83399be786da4b6e171b6784bc56e49","other":"f915e2398aa5d4370de87504dd76c21a7d0be2581c2ab55b7a47743f1bbaef36384eaacec22760f1e914ceac9d96a10c3d66eb27475ef444e77fee979e6e88cb","up":true},{"one":"74d84cfdaf32cd4cc67771f29878f1365120bd65cc14848008d5386a81f495bf88eb4132fa38a2cc109ae1e7f02c9b97597ab9d1a9c19c945e710ab9df07cdcd","other":"ae4e21e1587a8475afd299e00ca7085c7bf2a44c2c64a3068f12223d9202b0125094385319034691ec26b497ec9cf18fe8c0839224bac1b84279410241cef979","up":true},{"one":"990b1db3ab1390219e8866d39fa4441bb5bb89ad786b3e255771869fcd08906dcf63f34007481769c7462edbcc665acc0a552e3733360b8d8c310c9321a5550f","other":"7646d08b3e24183e3814de130235c41eb88a5a2abff23eaff3c91954ad3ef55fe27da422dac5b894312276bf1a2f1aebb8b636a8d4a0c93d9b016d441df3fa19","up":true},{"one":"c83985973a9564ade7d90aa54911ac57077600676a1d27292d98e058bf1315887bad84ccd708cb7f52a695a1405fb7d491d7ca2ae9caa3ff58a5ad78ce4dc9d9","other":"485825745d97654cbb92a14e0cd1078691d3c28f4d82b1046284b676a42b44ca58eb43474e45e415d3bd3f3c383f9a1a3365821ed7ba6a9f2603b29d58031dc7","up":true},{"one":"083e67bb19e30d14e4df6d2483367d6659d9b56744d53d9cf7fd15954c327e1bc88a5d0db8833634e1dad7209164451f8934b59f76b5990059261abfd650519a","other":"990b1db3ab1390219e8866d39fa4441bb5bb89ad786b3e255771869fcd08906dcf63f34007481769c7462edbcc665acc0a552e3733360b8d8c310c9321a5550f","up":true},{"one":"1b063741c76fe65e62b4eae42751319d0cce66f22dde9f1cf83d6cca249a0e65bc7f6f22597697362fadd226222fb3847f8e146961969d1b4c9f7e475389cd8e","other":"df4c3505e09e1baa88470117b964e758c94f77a4546489ab5ab7f4aebfdce424729ace8867475715fb68f05c66c9674a5767549e266c4fadd1c703ddd735908f","up":true},{"one":"9ce6b9decb69d66075993e903a0727ec109a04335634616097c0e60b08f94f764634fa00891b1070f6ea1ce896bc7d11d3aea92a00f281f902d960894cef296f","other":"934a5fe1b91c1891ef4df7f67c027e0eb115d4c2ca4a1b76a135ebd4315c4fb835d6625223194e6a134407b38b0d3928fbc7bc924a3c6a538989a6cf200bf4bd","up":true},{"one":"e023a51c5bd26e1754d6461345143e94baeac799947579ec7adeccd105de39f85afbceeb5037cfc0b820b9f4446433f034d9e7de7326d45df5a967a8099dbb10","other":"385168340139236a0e0f537fa693122db9fa02a377c96f31aae54718e92624fc0288164877e63616651565e055c53f7074ab2fdd18a837da6faf644941305bf0","up":true},{"one":"352407b42726dcd1aacc46a912ed8124b8b6a3da4e33dab742e40aa2452953d35dc8f42eddc76695ae2317e9f15dde2cd21be4ce826934695ad1847455661d1b","other":"68cc8b9a995eef6170abf88bd5fedca06ffcc8d75f247f6041c13e7dfd292727ebda1ff86b776e33b6634355c55e0f8c22fcdb5f9a6e2f22fe1af7854c3b4273","up":true},{"one":"7bbb3f3ed51cf84c077806fbd6d3578e105bc32aa6043da188793f066ad6df383a9f7cc0bd3124f4c887704bd188d480ce264fcdf178905bbda3b270927ea138","other":"40bdac599b00e9c41ad6476ee415c33d9c17c5aa672692c2404e523b29dc315da929a86874bed87fd9009871805d1dbf3098e7a817193e3b08a6eee66346da79","up":true},{"one":"81288bb0584b7ffc1546043e052e1df10fd5371b35dedd0bb42ec5b30ce69b741b2f7857af5984d4754b39d7253575fde9298504999b78380ef602d391c4bb1d","other":"57cd4c0048b459192ee46e19ec7df777e600f256e0dc8c3019431eb7bec3c020b9504ec7aea3dba8188658ca5b830ec40af6a8540ce10e04badc6c695d009271","up":true},{"one":"155e4879643a472420012e040a87dbff776fc1976814c0c6cd0d5e157f0d0baac04aa7f2535786c09acc2700547383d2119b64a6f62115f1aff1708738844d8c","other":"f38a9d792173a29c61389f5d84c005d78eac6e750659aad42e2d6df883f04eb3126b2c38fac95076eeed455b2031aaf694143922aa93a2d50412a2454dc56e28","up":true},{"one":"ff6f94005d1df7677600069764855c1c2aa0543cbe9f480f8feefec76c49d9e2c7bb2d8e38c89e9430f53f8b593d93f143c45985a56a5a32c736128214c95eda","other":"a78f18691e0dbf3c08fe9d7dec188e6a05a93833432fb99eb2b3924ab0bde7a44db2a102a65544bbdc4fb61bc3a3d569230d9843a335bf619167fb045d78ab3c","up":true},{"one":"7646d08b3e24183e3814de130235c41eb88a5a2abff23eaff3c91954ad3ef55fe27da422dac5b894312276bf1a2f1aebb8b636a8d4a0c93d9b016d441df3fa19","other":"e267e71c2dcdbe5a500b23444d2d4037ea15afba8f4f2b1c0e54a274450404fbee6fa5439f7cddf4ba1aa28fa93e434b01c239add58e30a5423ca3a481584d6b","up":true},{"one":"2bfba66ec9d63e928d77d455f2e10a14d6213e515099d5db14fa44a8bfc147eb0fa7afa9aaccdc86453c6903b55556059a2e13dd61fc494127d4a3ec173bf9ea","other":"0b30b36e155db04c448b662c4df695068b2331cdbe2772aae5fda84159e977515a5ff2e156bc225a9281fef2383926ba8cb11e9c1846fb40db241e524ac14e29","up":true},{"one":"deb7af800cd20a647335f0feff5bfb3e182f99f4c2d1ade10da36ecfdbac3b5fba4e8f0a4595443fe395b44af3a95617669850944655def85d57cc81c5682a3b","other":"732393b99c490c76fa45e3e404ee095f2fa445fcc123af7ac8ab1d2fdd7cf2483f5b82bb818bd8a82b1a3b73e63bcc2c83d8f24d9aad9afe36503735e7967be7","up":true},{"one":"0f9f7e2dce4ca266c3ac0ec3a8854200b54487f5308e3db418461aeb5f67c81d332619b6441b468e480941e63100ed1b263e7adc20689dc3dcda578bfca538fa","other":"a78f18691e0dbf3c08fe9d7dec188e6a05a93833432fb99eb2b3924ab0bde7a44db2a102a65544bbdc4fb61bc3a3d569230d9843a335bf619167fb045d78ab3c","up":true},{"one":"b137cf2291b530a39516d882200848e7f27a2710e0839b4d25b4f367bea6a0c3aaef8c7c7851c00a2945adcd819ea0508610afc1f453b8bc512b7b4d4faacdf3","other":"cd8815d66aee8bd488d4e5e25f0cc9c71cc65349f701ea26b1d6cd9c039d16fcb473dbf270a3b33187720ccf4b0ce4f78a6d6edd05f4fe804772d5b6ec45bbd3","up":true},{"one":"53df9cce9b0169e58ced53a123d1d8f6e8fdcfb4c2d781ecbb91bb7c8eba36946dd9d21c749259769825d8a6b3faa6bb87c8c6085a522f8a3e376061f59144d9","other":"f38a9d792173a29c61389f5d84c005d78eac6e750659aad42e2d6df883f04eb3126b2c38fac95076eeed455b2031aaf694143922aa93a2d50412a2454dc56e28","up":true},{"one":"66beee3968dbcf3addc6feaf070a4e3e82b5bb164fb72f40add89f732c12e8d0a31a7ee1f1e24a4674e4dfc9a4912b02c17ce3c224d257d78b7156544d6507dc","other":"baa5924e1547c177011285d292aa161a15e5ff282da2cd0afb83c9caffb07bdbb3662c227fa7b26e6dc8be9b8863e647eb5f8ce81640532f8f5c9a7f36557e63","up":true},{"one":"be514f5f17f3177235acb24112b578edf0e373c469073226e547d18080905fd062d572be18e943f13bf9fcf5871e89ceb630a1b848a0e370ef8ef8c6d997a363","other":"7808fb798d22e78fb1d39b87ddf99a503f820993bc64149eca9e81d9d58fc1adea60d8de14a4f06cb89f3190c0ef0c5e182621a14c9361ccb7e0cee667599cc3","up":true},{"one":"6f60ef501b41f9049419b033ae8d793a18067bdcd60347537b0dc3873bdd9a2d10d24909cca7c39781765746128c2165596f6537a94f58279523faee71f9c51d","other":"9194a3a4c8f3235203e48bdb10902d958d26c342805ea6365af9711213536509719d917c694f9a4fbdde6889a4c92299a5301f0275bda4dbcd2541b5bff5b271","up":true},{"one":"23f9bdc82efbf57d3d40a1f2617d0311678fb4a3d6a50cb7e608c649bb618124a76c7ffd17387de963e1cd28d2bd5a61c98613f6e009a8a2a90d989827b35de0","other":"f9ffe87c52ff4c22bd9696af32e0a9d34bb81fb84d9d8bf5aafe2ef9696e7b3d6460bf2a93aecb066133f53416bde841a02d6967bd06e3d4a714f3b2c123a947","up":true},{"one":"3b570117addeec03c2694baf28e246f91907268fe665c6c90356120332794258ee57a60853c19e9fe25d042ca42a5be7fe0797d84199174de8132f1ef4a9349b","other":"2ddd49fae11d8bd2e7e75a481be267fa846f51cc1160bc326aeea51c542323ff444909de11e2731e835140bc0b1b32020e1e73fa652511a381222bf0aebc4081","up":true},{"one":"6bf9fb6a25521c16c2ebeb6203d046d7dd40f29cc2ddb067c0222ef56d7012d2ee5d037f71f6668ea56767610b2a54c144aed74b7f68d06993cbd52fa1dc7630","other":"70ee3c7e02a123f78345d41c386e413f06b51f1ab346c2c472891eed7dd26a1f14e213a0f4f2d872859b9b535936a6d9b072d2604456f76221a422710411822f","up":true},{"one":"ff1e34fd51953ed641b431aa657da21cb4c81d23e4eaa13c9cce526f1f1b34593d41f9b87a0e10387fe400c623638677c0efab15dbd1014a0ccc11f9ec92c417","other":"abd8f5a4d700c06ec00684b23d2d25c4df1a9554fcfc57b0ddc3fa476e6a699ba75e1213449f900803f83ab8194c6746664b547202047f35b8b3e216c7147bf8","up":true},{"one":"62666b24d1026345349edb6a878cdc27d6fee8254e83f79a298ce2805260d97aa46423deae440f86ced5cd99b30e970c8e1ea1046752b17d8c80dc68d9a49b60","other":"df54af3bae257d437c5657905484e0d72e9560c46f8ba6b3437730234e05259b404cca40b0831e911605ff8a68a19e8fd7e958069ec8b40595928892f4fa220c","up":true},{"one":"80d997b87856099d844187d3d1fa40846ded652a62c1611b35919c2543915b64ff62476636488556f678e436ea26fcc40db7c6b6bbcb78f590d61c1ff0e424b5","other":"59b53f8a562bee519276e0eeccfcf8c975d3102f5d0cccf5abcce291a8a5bb817c04604f123686177a50a03b9d7559ac469962d0159d1d93e4ce58a304d04b55","up":true},{"one":"b2538d4edfa736bfe2cc21326a44ce62f716b3480eac93584a2233b69c98883a2bb255f246218a58cecab1d0d176e6d1fbba9782fd70d4603e01742299b9ea9c","other":"049a2b0ab4d49789dbbe1837e2d2ee5220a9401729ea87ab29385b24d79cdce255c3d2b5de6484d49ca6ce07bd41832598260c0a8c290e01d133d77f066f2f99","up":true},{"one":"7f357b8d81bc2e5c6fcb081f23a42b3e2439f050d45c45851994a268d1c71fcb1f39f8c3f75ce921d3fbf80fc0e73f0b9609d72001dc4a6b65b526d312a4f43a","other":"0f9f7e2dce4ca266c3ac0ec3a8854200b54487f5308e3db418461aeb5f67c81d332619b6441b468e480941e63100ed1b263e7adc20689dc3dcda578bfca538fa","up":true},{"one":"0a4eec7b0e05da799aca5b36d9e2530f2a89d1426b1fcb7d8f9a662df8a8b5b763767a20db3c9c63e0bd13c2a6e16d3ba8f03baf84f5e5d24917b3f211d9bcfc","other":"afe5b217dc512eee45575c189826ee5640d11a0ac9e8e4b03e9e62e6cf6df9de500bc8a36cb7d82a2280ce184409164f1772cc5c9e59ad04361522d2b8c364e0","up":false},{"one":"ae2a996d3b562cb47a564934037949da83b1bfe194c23754f3dbe2372ec27654f4f3b6cb7f394570f308025589c065870477667e5560dbe5a8ea1625740699cf","other":"0deda014fa3c0bc8f37d853e1448f95f56f97048c28797d72258fd3ba2f1f776ae11566197466596356cd172847ab02a89f4cf047e58383249fb2a4cd69b6206","up":true},{"one":"ea57884dd42aec5a76eab43483bf7c4ae2c19eebf365013731de64494d10a3b4cfe34c86c79437f9012bc8cf6bd761435eefadec17600f4b9e4bc234532d6282","other":"7174eca109a1f717653918224c8cfe1b7fbd666405196760913593401eb79f2c7e41003b01f5a458940695b27a4673443c7621a169db7fd968994e552995dbbb","up":true},{"one":"c2705ee7238ef9305e4da196653cde707649435a1e8b5b797d164e5ca06184a77af5bd7fa938c995fdfcbce724fa7eca3d908ee34891ab62cc6dfd411c3fa1da","other":"389b5c1a805f87427e6d647ec5488342a3f7d700615943d5ad98ca5c111f33c7ee007970b4d3e475892095c0d5a79b7ed52d12598398818159000d4b9b719126","up":true},{"one":"6b01079463ec2f649db8634cb7a596261c79a8f714d954c772528e0547b017f8ce405e4a0ea9d32270848180e0f77b8c0b022cf95c85e777626edd4d24ea21d2","other":"28d3232c43de54ffdaf08f97b334c012738648b04e2876c7e751a2e352aaf4d550d6efa976c5a8edbfa8e88b9d04a0fca492b81c3756ef673ab74d34182ca711","up":true},{"one":"bcf8e831821a5bca359fb824c7dc4d66906de82f3663a0a853d96880a8ca0bdddcceb1b66dd1f13f75ee20fde50fc9de545bc25767f228baee910e0dbfa8cc27","other":"5bae82d4832092c17bd11474f7748015b8b69b896ab8f683a7c0024fc98740cecbb9e31c6275269f9000e5bfe51d7f45cd5dcd4433e0c87b5741685b40fe3983","up":true},{"one":"1b063741c76fe65e62b4eae42751319d0cce66f22dde9f1cf83d6cca249a0e65bc7f6f22597697362fadd226222fb3847f8e146961969d1b4c9f7e475389cd8e","other":"76cbf9fc0f3517fb615fa96104780218e85d064ee5a1d518f3b78f4dbebf144df38c427445fdd6c9b436489c00ff9497d747a8fd70f380f95601d59e52e021e8","up":true},{"one":"396c703d27bfdddf91761f134cbf665fe61e0b3a5d24036a4105a625f72e8c28b821e9200f20d6e8f8b3ed6b95bda6b8accdd840c2f786720b7431e3af2af981","other":"17a79cb279306b6bbd35219278f6bba03111079d6c4fadcd3c5e57b09678e111bda5f8e36ca3d223e51e255d6e857363b7741e438b32ec6e6c0dc1b224071081","up":true},{"one":"855bdf057f4a6b095e2000ada199447b5b4f2f8d78d2ecbaa0ff1fbf761788870ee999266ad3b26efa02be1a46a4d92ac0debb85a2ceab3442394ee7d99e5355","other":"a08e47137bf611dfbd20308a22bdd3ca00121386f121d6d712ade86e9a1601a4237766887cd91c8516e20b6e323d2ef49c1c7e177a0afb4c813f0f344daf779b","up":true},{"one":"be026dfb24847cac2d00f483104edad06ca8ecb9e1229c479ef5650c7b427cd5dc34a1cf06172c17c9d0406ce17009712e82446394743d4cd9bbc41c537ebc14","other":"9b59b76dc61223c7b37083b0ebdda22d3599563b3e3986f5db9d5b12f8c806cbdeb2345454efe957cbfa11eea9c7896aefd9a461210524805452ca100a9ea431","up":true},{"one":"eaca77d20c4ad6b87649eba21b750a4b1a2c575e06bc42679d18fce16fea15212e9a7408c16f3b24d8dfd1e397314637e72e292845d09534a39035bd9203ee9e","other":"c665a6b1b7ad39b86bd4b1fe38b7ee95a0fbb1db15e91381ec9e5a235e33b69ffdc92c60dafd74b7b4dafca1b000e9274bf045abe5b93b1a9c2b31ae071a9898","up":true},{"one":"109556abac422a912ecffec0d8796f8f16e92e8f95cecf72dc89e97a8bf1fd37aad3c66aa3cf134acade6d065c31821f977171d5c5463305b57ce3eee99a7ab4","other":"4f5ab12b9c5127c16739ad0d4f51adce90ba6736cd096eb185ea632789f4b26f1ebabdea4fd3b39dda5409ece6c2d92fd469cf4aecf9d29453e3e042c19b893b","up":true},{"one":"a608a746f46d4b2e9267c65283380d6d6cb8885a64428fb77df9934bcf4dd1723587ee7c8f4a642dce266a12a6a4cf4e5c6db7fa1024158425a6753e7ab7264c","other":"2f360209383d6de4ebd3b4abaf77796520b8654270b03f2151eac4a01b4417d7e0668c1f9ad30c20ff49aa8a0ab33dba5e6095619d1cf04b7af841722ab773da","up":true},{"one":"f915e2398aa5d4370de87504dd76c21a7d0be2581c2ab55b7a47743f1bbaef36384eaacec22760f1e914ceac9d96a10c3d66eb27475ef444e77fee979e6e88cb","other":"043fe7085e8c90c18270f84dba5fab138e50216a1cf8d81a3794d156fad7fc81d1422aff169b244b13f91d73eebb5de464f97b1b93b3ad2a58959cff19238842","up":true},{"one":"c9cd9dfb9f90a7948ac5a42c7bd63263f2eef6e1d85547559f7d2ecbf5f9cd1eab051b8e9e661b573c275d84091a44e73f6fc6bcc91dcdb674bd5d939190fc01","other":"1944f98d4db32c56a5efda5a79aa5f276bfab1e084d6611fec0e735b8bc0f45b457cdb74a23fc83b2377821fa8316123c9877acd6db7c41058ca5d3cfedaecf9","up":true},{"one":"d9bbcdfd949010e6b2cbf6d0f34b27593ae410bdc1838876aeca35679571fe431d040a5ab085c0a77f111688bebed891da3587277cd794702437cb20d6aa4256","other":"657d5370319128d24d925b41065eb619409d63ec6280975d78877a4028287463f6442f5206dd703569a05b2b542ad8bbb99803da265408208d6356a26d283d08","up":true},{"one":"2a63d875e715c2a43302d32d86d30c7d7faed46c08a67bf488762637216b99dd87333a66df6d9f3a57df863b1f1a219ddbeebb9f3e92e523bd08540a195448ca","other":"094f9d0fd3bacb17ac67a2edb8ed394fbbd1c8d478233d3269cf217e7b788e21042374936b885bf23ee4f9e03babbe4e08db283dfc2a6e052a8a5ba133717dd5","up":true},{"one":"9133b0b3c8f680286eae90c3beebc3099a13de38775a3ff2abdeced62d05eb2ced5ac85eac0870156be03101024da5e1d9fbf3e1066ddb3f088221e64149acec","other":"657d5370319128d24d925b41065eb619409d63ec6280975d78877a4028287463f6442f5206dd703569a05b2b542ad8bbb99803da265408208d6356a26d283d08","up":true},{"one":"7acddc7fb6ac587b7e343804c768e4291cd28dd2b2b9207dea6ee82360d848a52d84f94e4c49e9c421f4f90e2d24f6291e2358783ab0230e6ecde82e69b4ac52","other":"657d5370319128d24d925b41065eb619409d63ec6280975d78877a4028287463f6442f5206dd703569a05b2b542ad8bbb99803da265408208d6356a26d283d08","up":true},{"one":"11d560045536e9d1b0b1b9e8944e00f0ca7f1e6788c9fdb51061820bbb3008ead92bb7836621bf58da7035c87a28328faecb4cb2e3cdb9d7fa4f45790e6bf352","other":"043fe7085e8c90c18270f84dba5fab138e50216a1cf8d81a3794d156fad7fc81d1422aff169b244b13f91d73eebb5de464f97b1b93b3ad2a58959cff19238842","up":true},{"one":"ae4e21e1587a8475afd299e00ca7085c7bf2a44c2c64a3068f12223d9202b0125094385319034691ec26b497ec9cf18fe8c0839224bac1b84279410241cef979","other":"59b53f8a562bee519276e0eeccfcf8c975d3102f5d0cccf5abcce291a8a5bb817c04604f123686177a50a03b9d7559ac469962d0159d1d93e4ce58a304d04b55","up":true},{"one":"389b5c1a805f87427e6d647ec5488342a3f7d700615943d5ad98ca5c111f33c7ee007970b4d3e475892095c0d5a79b7ed52d12598398818159000d4b9b719126","other":"c73d088ade8756c74832c73542bcdb3e52f670f7a74ad3a7eac2a9e3ece6bd081f782a8e1d3f9a40b9aa9201509110f37fc57fcb10ee1ef3ef07b7eab019782e","up":true},{"one":"e2e0419a41bdfc5bd76deae2ddce6ac865f886d764c9bd18799b79fa3b2b6ba66d765d26da2037e98317e1d7e8232a61e63c1d0cfa98c9137424151b46e07171","other":"9133b0b3c8f680286eae90c3beebc3099a13de38775a3ff2abdeced62d05eb2ced5ac85eac0870156be03101024da5e1d9fbf3e1066ddb3f088221e64149acec","up":true},{"one":"74d84cfdaf32cd4cc67771f29878f1365120bd65cc14848008d5386a81f495bf88eb4132fa38a2cc109ae1e7f02c9b97597ab9d1a9c19c945e710ab9df07cdcd","other":"ce0a09bb6fe4c9c93c3dbd800ca9c9ac0714f26a8f8dac2149b6ce7a9011912a5621ea2e45de35c4d31dfe5add00558fdba5dd21acf2d81ba391e82b5b3a5804","up":true},{"one":"a7507aa5665e165ab2e2a07def272f0677f9d6d35bb82268a34214384e7d8ef7635a299368752e63cfd02d4e60231076baf23cfa10d17492e55181b391ecf335","other":"c903c5ee3d9cd65bea3ea777e39282c33e1349d945411fb2f16321bf582c2f400956a98fbafe5873fc5f6f6a9a051df5da7e94cbd340f935abe80f91e79ef875","up":false},{"one":"460531928a4b084686343c8464b37c3452bb3566045698d08a4692864de5581a9eb1dc632329e7d3ccb73ec31ee7693787d69df8458efaba9a7105d87ee2e053","other":"eaca77d20c4ad6b87649eba21b750a4b1a2c575e06bc42679d18fce16fea15212e9a7408c16f3b24d8dfd1e397314637e72e292845d09534a39035bd9203ee9e","up":false},{"one":"3d2df188704eeac09c8b291bf275a73888199a231c832c51dbc3d746968d4b51a7d5eae0c7c9b8c8e19f5e28d38c375e01abefa343f31dbe221deb837ab8a0df","other":"66beee3968dbcf3addc6feaf070a4e3e82b5bb164fb72f40add89f732c12e8d0a31a7ee1f1e24a4674e4dfc9a4912b02c17ce3c224d257d78b7156544d6507dc","up":true},{"one":"094f9d0fd3bacb17ac67a2edb8ed394fbbd1c8d478233d3269cf217e7b788e21042374936b885bf23ee4f9e03babbe4e08db283dfc2a6e052a8a5ba133717dd5","other":"c9cd9dfb9f90a7948ac5a42c7bd63263f2eef6e1d85547559f7d2ecbf5f9cd1eab051b8e9e661b573c275d84091a44e73f6fc6bcc91dcdb674bd5d939190fc01","up":true},{"one":"ce0a09bb6fe4c9c93c3dbd800ca9c9ac0714f26a8f8dac2149b6ce7a9011912a5621ea2e45de35c4d31dfe5add00558fdba5dd21acf2d81ba391e82b5b3a5804","other":"f38a9d792173a29c61389f5d84c005d78eac6e750659aad42e2d6df883f04eb3126b2c38fac95076eeed455b2031aaf694143922aa93a2d50412a2454dc56e28","up":true},{"one":"beec648d79437a5d7b4140ced45d82d035c6f64f9c67c58386703811d97c3846787eaf274d2298df809475f0b7519df696563cb8e9a5fb0a9cc419ab13fa8d41","other":"4a030ebcb1a59230759d25a3c87daed22906b520d55a78eab2083bb52358ddc3a5d2d7c3265e6c54a990bf32d0dacb85905a4173d72ac18fcd74c43ecb8635c5","up":true},{"one":"ed6c793eb4565aa9d883a76fad6c97ad0b878b9ef0235e11e89db1af25a9653205f725c6ea258b84bde134f1a6437c6d109b859d17509e5016c4ab98be59032a","other":"fe62314839c93d2f6e3aee984d5f0b321897c6f39e66800d3de8b773baf6f19e0a03cae025df512aea8d5f1b667b6dbb15c192a90a76d3031c14e33e5c16c4f7","up":true},{"one":"8d4920d6e3a6717699b5a3af068cbdfc16858d7e393d158d41b1b5f345b47129eef89e1d055386c518f400b134678c21590f0317dea3436d4cef60f45455cf12","other":"2245f3bf1a3b4e92f912affc75f757cf648b20474c11ffe947884f216b8f24f9dcb6e6a0358a4061b8517478ec15027e185b2f05a777573b4940375bf4aaf2be","up":true},{"one":"315b8a1711f680c2eaa607e35ef7a9e19c2b61721af8a7e08f1325dde1fe33cf1f47b3cc4acf12d541631041cf1b42754875fd1c9b66ee32797b72b9f7711256","other":"f6ca39b3ad803e99f4e4e9cf759fff6abdf06e6972bdbe524f6eb930c669d6f0e9b91f3de9df394b0d661b068273861391bdbac948ad911351c48cf02f874db6","up":true},{"one":"fe62314839c93d2f6e3aee984d5f0b321897c6f39e66800d3de8b773baf6f19e0a03cae025df512aea8d5f1b667b6dbb15c192a90a76d3031c14e33e5c16c4f7","other":"deb7af800cd20a647335f0feff5bfb3e182f99f4c2d1ade10da36ecfdbac3b5fba4e8f0a4595443fe395b44af3a95617669850944655def85d57cc81c5682a3b","up":true},{"one":"59b53f8a562bee519276e0eeccfcf8c975d3102f5d0cccf5abcce291a8a5bb817c04604f123686177a50a03b9d7559ac469962d0159d1d93e4ce58a304d04b55","other":"0deda014fa3c0bc8f37d853e1448f95f56f97048c28797d72258fd3ba2f1f776ae11566197466596356cd172847ab02a89f4cf047e58383249fb2a4cd69b6206","up":true},{"one":"cb94a8270d0050378116b5815ff17dafbe20f5303839c4fd57b981d4687a4b145e4bccec7e9af9b9475005930148ffbfa97781a0762c8e9f352dc95565fc8732","other":"07c63ca5d0309e30d1ab12e7fc142e6d37904b552639cfa97850161491f28f20d87e0304be29357bcfc2ff52fc52fd0d4f6e6011ebb239cced8b5c8dad7abf45","up":true},{"one":"cb310c0e86aa455d7c9af6394ae38561c901da30a51d7ccb7e66a09d9a8f192ae8caeff106043426d56397088f141c4e01e3b98f1ee583ffc7318b5f730f3ac7","other":"c8b0dba45104fc7c7dff3ce078a0d3f5ade6198bb4656e2bee8076387929133e5ef2bd293b130a9d4f6a6974ca17e8b4a8f406d1219880f1e0f99c65c63af5a4","up":true},{"one":"c665a6b1b7ad39b86bd4b1fe38b7ee95a0fbb1db15e91381ec9e5a235e33b69ffdc92c60dafd74b7b4dafca1b000e9274bf045abe5b93b1a9c2b31ae071a9898","other":"e023a51c5bd26e1754d6461345143e94baeac799947579ec7adeccd105de39f85afbceeb5037cfc0b820b9f4446433f034d9e7de7326d45df5a967a8099dbb10","up":true},{"one":"d7a319f69013b8375e64d19f015547462c84565b882337998f9e669c5fadd3d2ecf6374109903003e09f5d453424b5c7fdf52163d2cc8084cf81f94844946b63","other":"76cbf9fc0f3517fb615fa96104780218e85d064ee5a1d518f3b78f4dbebf144df38c427445fdd6c9b436489c00ff9497d747a8fd70f380f95601d59e52e021e8","up":true},{"one":"94088fe273f76e62ca4e43c095ad12215b4ae4c59942328b3985416fb19bbda0cacc143a49eff3fb644ad53a19d3f043260e43dbb70a0aa9c15829c21cecd3c7","other":"76cbf9fc0f3517fb615fa96104780218e85d064ee5a1d518f3b78f4dbebf144df38c427445fdd6c9b436489c00ff9497d747a8fd70f380f95601d59e52e021e8","up":true},{"one":"28d3232c43de54ffdaf08f97b334c012738648b04e2876c7e751a2e352aaf4d550d6efa976c5a8edbfa8e88b9d04a0fca492b81c3756ef673ab74d34182ca711","other":"b4fd11306b1416a9bcf4719578976188e104b8c5028b9abd3214d257446b97b70a22e6c00934d80caddde15e8e4d16af03bb399583047983fba373d8313226b7","up":true},{"one":"6ab6ec15635b2fda22542c99df0a3313ad4583ba0fb3f31b8f314e3ecad446d3fb0fdfcd2be9b08374b1a7e049fb68e69e8dacdd13f1df5007a656f6b11adc5b","other":"76cbf9fc0f3517fb615fa96104780218e85d064ee5a1d518f3b78f4dbebf144df38c427445fdd6c9b436489c00ff9497d747a8fd70f380f95601d59e52e021e8","up":true},{"one":"5526d86ba9df651091d88460a9bedb9cedb957d452a635e1db46b9fed78082022adec0047cd7485956a4ecbb0e18107595de0de3c35242527cd302bf74a19260","other":"0cacda5560faff9d20e29a0625d3cd340ec075f198a50ab8b79338cee0e0db84c7c7e71042fd8c8f73e507b570de5d26c39473136b575f0167625a1168309ec5","up":true},{"one":"8c6d77833bf1a98beabe7a92d985d13d52fb2e50768719ffbc6fce21ea676802a074b6e620b3ef80e12fad04f94a3c288d91df9716a6cfae09ef073b9dc1f2cb","other":"eab86c521f8f1ac67c015ab713f1236a08b0200757a96bf87ab8301e7967ae62361f0e14da14ca294fc8cb3b4726b52f4773101e21b032977c6a647241b59c73","up":true},{"one":"c332fe1f9b6e25f72c7150631ffa6e0929ff6eeab5d17aa45eaf669bdde869cf404505ae990a529aa3ca797cd0a96f31cc41431a5d4a163132be566f91623c08","other":"b080891d4ba6d3ab224984360597f9c555bd1367630f5420bfaf230419a05b2be58bebf1554e53eb4c0da81cfb66d4f7697dd65143f11841ff62d8a0d82b6b67","up":true},{"one":"1944f98d4db32c56a5efda5a79aa5f276bfab1e084d6611fec0e735b8bc0f45b457cdb74a23fc83b2377821fa8316123c9877acd6db7c41058ca5d3cfedaecf9","other":"9b59b76dc61223c7b37083b0ebdda22d3599563b3e3986f5db9d5b12f8c806cbdeb2345454efe957cbfa11eea9c7896aefd9a461210524805452ca100a9ea431","up":true},{"one":"acb4088c27ee2ee130ece3506596432afdb9e9757ec11ebdd35c5a6e87239545c48466913a646980104c8fd7a9a335e177f04efffe9dc952dfd7cd5c1bb9aac6","other":"7b5c0e81c7f4e3ae29d745f6028cfa10b29a16a9c261b65fb8dd05d6eccc634612ad5d3029c8e9f39863a2cdb2682c25f090139bf5c4950e25647e39dcb40e63","up":true},{"one":"732393b99c490c76fa45e3e404ee095f2fa445fcc123af7ac8ab1d2fdd7cf2483f5b82bb818bd8a82b1a3b73e63bcc2c83d8f24d9aad9afe36503735e7967be7","other":"2ab9513899c3c829b6284e56bf2b9862dd0156ec052b58615dba77d450dac642e534ec36ae5d3234262aff54e19f99856e908b9d8c1da660a7834a445610715b","up":true},{"one":"b080891d4ba6d3ab224984360597f9c555bd1367630f5420bfaf230419a05b2be58bebf1554e53eb4c0da81cfb66d4f7697dd65143f11841ff62d8a0d82b6b67","other":"d4b7c787981abec24353c7d496661692233797e3758189bf909a69fe87935bf6da0940daa4f12e81f20c5e88f70b472113688b71a0ae2f91a73ee0e6ff4c8591","up":true},{"one":"8ca3b63cb84f1e9883d82809a9b6777ec1029ecda96fe93b4d494ee9cbefcad13f381b3e480136e542e01054fe1ede66c65db84a0009871ce49383db461c8438","other":"b597c9ba4da20c49fc4ba019571321d2579588636cdaceb9f225706574970adbf4771dcf186b1decd4e14cd5d257e30a36ca829829598c1775902201ad9793e2","up":true},{"one":"083e67bb19e30d14e4df6d2483367d6659d9b56744d53d9cf7fd15954c327e1bc88a5d0db8833634e1dad7209164451f8934b59f76b5990059261abfd650519a","other":"6ab6ec15635b2fda22542c99df0a3313ad4583ba0fb3f31b8f314e3ecad446d3fb0fdfcd2be9b08374b1a7e049fb68e69e8dacdd13f1df5007a656f6b11adc5b","up":true},{"one":"27d9048707a89f1a61e44fdae523c0128f2a7050308bd3cfefa6c3e03040a0e22f11ab41275f22b8706e6695ab93320e2af35179d772581db5f49f960750f2f7","other":"e2a27dcdee1f89fa362a85c4397840cd8be4ad8d1b9ccb23188c303bcab7619f38772f71385922d090390973b62fb8249efc103f71bc761041bcb3880ec0b935","up":true},{"one":"e087230634f556b818a416b66ba3f1d1dbe3e0dd0698bbb26fa86a2499acd169466f564dc18adf2f9be4d1ada0e86c11549754097601e10aff4f3a57ddffa24a","other":"07f25fdeab2b44b2e92fc80fca7de9e4a8547d27a98a54593b3395c270a9ff3f2a5da62a2e8531ce86359f0cdc5b6513b773dfd64cce1b83e47065d9760a2c7e","up":true},{"one":"1d0244a13affe60996fe3cf51ba624adc746de0c7ea68ec5a31311a36077c5b5495e3d95c9642875db44c7ecae6ffed22e45f2e2d024d486760be2af9f4cf2cd","other":"352407b42726dcd1aacc46a912ed8124b8b6a3da4e33dab742e40aa2452953d35dc8f42eddc76695ae2317e9f15dde2cd21be4ce826934695ad1847455661d1b","up":true},{"one":"ff6f94005d1df7677600069764855c1c2aa0543cbe9f480f8feefec76c49d9e2c7bb2d8e38c89e9430f53f8b593d93f143c45985a56a5a32c736128214c95eda","other":"a127faa19dcb7da585983d36a8e9d3e9a44a6db68507b60c70da71011f44ce377944802f39cd65f5a705cd8249ac1ef7ed8fd699349098f3f8e23b37592c80ae","up":true},{"one":"66beee3968dbcf3addc6feaf070a4e3e82b5bb164fb72f40add89f732c12e8d0a31a7ee1f1e24a4674e4dfc9a4912b02c17ce3c224d257d78b7156544d6507dc","other":"6ab6ec15635b2fda22542c99df0a3313ad4583ba0fb3f31b8f314e3ecad446d3fb0fdfcd2be9b08374b1a7e049fb68e69e8dacdd13f1df5007a656f6b11adc5b","up":true},{"one":"cb321c9b0fe2eb3617b8e2461aab170a9dad2c9b04a10eead4e37e551197ea0a7500eb1cb7b155efe1886486ef3d252d8ff0d309f2906a1126ca011d037da70a","other":"855bdf057f4a6b095e2000ada199447b5b4f2f8d78d2ecbaa0ff1fbf761788870ee999266ad3b26efa02be1a46a4d92ac0debb85a2ceab3442394ee7d99e5355","up":true},{"one":"6f60ef501b41f9049419b033ae8d793a18067bdcd60347537b0dc3873bdd9a2d10d24909cca7c39781765746128c2165596f6537a94f58279523faee71f9c51d","other":"b35f418c7935cc54278e90978c3ef1521ab91daeaf9f1ebc1cd25211611ade091cac4e1f009d71059279d507322a4536501980ac0dd44caddc52fd4c593879f7","up":true},{"one":"62666b24d1026345349edb6a878cdc27d6fee8254e83f79a298ce2805260d97aa46423deae440f86ced5cd99b30e970c8e1ea1046752b17d8c80dc68d9a49b60","other":"66d0c5da973d9dd65350ae1ec63776872cdb7ded6afb6f51ae82259f6fd35e884375d15de290625f02ed2e5cdc3f591decb45e5fc64d5b0f835a216fd196f5a3","up":true},{"one":"a1560ce7c1f1d5972f027a8e9cff820611d84764aa067434a75b63887bc4268a259101486d34b7fe83dd735e799789986cd3e9b156c86ede598bd86af4454924","other":"b6a998dea59194cc60ce97c7c9702368411889cb6905516b23f41cc5116fba8d0f237d418318eb0c333cad18003c0e9a6bd8c99080520771f2bad640e2e5ec1c","up":true},{"one":"80d997b87856099d844187d3d1fa40846ded652a62c1611b35919c2543915b64ff62476636488556f678e436ea26fcc40db7c6b6bbcb78f590d61c1ff0e424b5","other":"ae2a996d3b562cb47a564934037949da83b1bfe194c23754f3dbe2372ec27654f4f3b6cb7f394570f308025589c065870477667e5560dbe5a8ea1625740699cf","up":true},{"one":"afe5b217dc512eee45575c189826ee5640d11a0ac9e8e4b03e9e62e6cf6df9de500bc8a36cb7d82a2280ce184409164f1772cc5c9e59ad04361522d2b8c364e0","other":"b26f7c0113a5ae885f7c0e608aea7022a9c8bfc40c5643e60b2ba7343ff09c5be0bc08be34dde3c6b85fea192a46d4764770c12cbaa233df4231a1b99627ef9d","up":false},{"one":"b870935867183bbfb84add16b9f56c02c834b7042fc24ce6bcb2a7f174e6d2239357a00be4272c1ef05c7f9baf5a9f16b53bc18328a9b7aca8540c2916805b57","other":"4e68553db7be307b8379e8bec383b5c92e4b23debcefca575d24504e2062618f74c26e60e0d9e47f096997a7f841e2c32c994124f495ef3352ef964b33fd3a51","up":true},{"one":"7f357b8d81bc2e5c6fcb081f23a42b3e2439f050d45c45851994a268d1c71fcb1f39f8c3f75ce921d3fbf80fc0e73f0b9609d72001dc4a6b65b526d312a4f43a","other":"a608a746f46d4b2e9267c65283380d6d6cb8885a64428fb77df9934bcf4dd1723587ee7c8f4a642dce266a12a6a4cf4e5c6db7fa1024158425a6753e7ab7264c","up":true},{"one":"b3316f4fd7dec218a52331f25d17a2faf0f2a417808d7dbb80038154abfbcd2d78da074837b648cff28675f4aa0d65ddb7d15abf3d7e0391d401e313a3ef24a2","other":"8f88c7ec044f758f29bd8d12a5170bd973aec8f6cddbf512b910c4b75a0fec09c5e198bcd65622037f897759db68da2328b4a7ca93585dc9cb62e46d2a6c0864","up":true},{"one":"ae2a996d3b562cb47a564934037949da83b1bfe194c23754f3dbe2372ec27654f4f3b6cb7f394570f308025589c065870477667e5560dbe5a8ea1625740699cf","other":"329145e75496cecb5f5c8f00313a52ddd8c0e8cd27ef1b2bc1b2b56e4d4089aaf5a7a3c4d9a40bdb92483fa05bd24d1cd0fd51883e30439dffa0fc855e1a7cd0","up":true},{"one":"a08e47137bf611dfbd20308a22bdd3ca00121386f121d6d712ade86e9a1601a4237766887cd91c8516e20b6e323d2ef49c1c7e177a0afb4c813f0f344daf779b","other":"97981f4b825620985b746c85824d7a4d307ee25d60a72c2b7de4b1d4f3b1c002652adc3045842d350f849789e410a0357a0b42fa637a1b4fc9d39e44f8a674d7","up":true},{"one":"3dfd733dde9414af916625ab981777ff1ad7ca0f6d1e4e7d9e2739969e21182fd13d85e281868653e7325b20069356b11524b54143c47fd3955a911cf7325ad4","other":"292c78c8e41606e98428096bc6f4609a7aa48e5c4d17eecc64d65faae4a7270b0c15f0cd74274015688ea0a9aff34f215c29118222e362a29c8d637963973a55","up":true},{"one":"1bc1d6155ba35d29ea16938994e08df76ebd8f16bd180bd6a9b9d8798d0745889fe72d641dd78bd8ec13526929f7eb5aaa6a388430fa69033d6db581e53c6422","other":"453779010ed7c59761da47ccd8869d3fa8349795e57edb9eea416c0712301ea622c7683858e309d19ab137ddb0edef161d0d00a361abeecf0628c3ffabc629ea","up":true},{"one":"eab86c521f8f1ac67c015ab713f1236a08b0200757a96bf87ab8301e7967ae62361f0e14da14ca294fc8cb3b4726b52f4773101e21b032977c6a647241b59c73","other":"4b784f072b7c96c30612767425f552e30e45157e70139dfbe0ae4ff86dc31601adec60f8a3ad9747b02b5219073d8813af9b09d59eaf7ddb7ee24856aff6fa8f","up":true},{"one":"d7a319f69013b8375e64d19f015547462c84565b882337998f9e669c5fadd3d2ecf6374109903003e09f5d453424b5c7fdf52163d2cc8084cf81f94844946b63","other":"5566111b7f14d8ec83ba6456488f3fc5c7e2c86bf406dead33b814e1ee9b569d34015a4d88226b7e28fff7784395c086d106287cbbc80acfe75b05cd6e12903d","up":true},{"one":"88d5c5fe61ee1e6fa5878e0eaa13bdabaa0ec3d38a5d25b95a467da7627424f25fb5d30535aa0a5ad01c16fe2598dbf570b78cc152a7f4ef66d46fc9ae43592f","other":"59b53f8a562bee519276e0eeccfcf8c975d3102f5d0cccf5abcce291a8a5bb817c04604f123686177a50a03b9d7559ac469962d0159d1d93e4ce58a304d04b55","up":true},{"one":"c83985973a9564ade7d90aa54911ac57077600676a1d27292d98e058bf1315887bad84ccd708cb7f52a695a1405fb7d491d7ca2ae9caa3ff58a5ad78ce4dc9d9","other":"934a5fe1b91c1891ef4df7f67c027e0eb115d4c2ca4a1b76a135ebd4315c4fb835d6625223194e6a134407b38b0d3928fbc7bc924a3c6a538989a6cf200bf4bd","up":true},{"one":"bcf8e831821a5bca359fb824c7dc4d66906de82f3663a0a853d96880a8ca0bdddcceb1b66dd1f13f75ee20fde50fc9de545bc25767f228baee910e0dbfa8cc27","other":"66beee3968dbcf3addc6feaf070a4e3e82b5bb164fb72f40add89f732c12e8d0a31a7ee1f1e24a4674e4dfc9a4912b02c17ce3c224d257d78b7156544d6507dc","up":true},{"one":"ee36d1d5dd69fd30242d7da2e941b34ade5581c7164fcc43288ecfc52937a98f1b31ade5d1e4dbf611cbe1c7875b2840c89435081cde471c271d7bc60e9ef211","other":"b870935867183bbfb84add16b9f56c02c834b7042fc24ce6bcb2a7f174e6d2239357a00be4272c1ef05c7f9baf5a9f16b53bc18328a9b7aca8540c2916805b57","up":true},{"one":"fd4968df03d767a223bf7e4dbe26b5c27048298df40e81cad50b344fb3e6837965f2646dab7ffb2891a5c507343ed84bb8bbe403287b51dae538d58fcb6e7623","other":"afe5b217dc512eee45575c189826ee5640d11a0ac9e8e4b03e9e62e6cf6df9de500bc8a36cb7d82a2280ce184409164f1772cc5c9e59ad04361522d2b8c364e0","up":false},{"one":"a127faa19dcb7da585983d36a8e9d3e9a44a6db68507b60c70da71011f44ce377944802f39cd65f5a705cd8249ac1ef7ed8fd699349098f3f8e23b37592c80ae","other":"8ca3b63cb84f1e9883d82809a9b6777ec1029ecda96fe93b4d494ee9cbefcad13f381b3e480136e542e01054fe1ede66c65db84a0009871ce49383db461c8438","up":true},{"one":"329145e75496cecb5f5c8f00313a52ddd8c0e8cd27ef1b2bc1b2b56e4d4089aaf5a7a3c4d9a40bdb92483fa05bd24d1cd0fd51883e30439dffa0fc855e1a7cd0","other":"e98a08e8e3544727f5ee27f4465375a67ffba490fcdbfe7bfdc909f6b68bd279f776c65d38c2ccfc33079f852f76349c94d68fc6989c0d981f22333f036a4bb5","up":true},{"one":"f54335964d9b4eb9813eb05f40ef1c523bbf0faac5a04c4737467d590fb6b55c7fa1fc5d4d32c5491d8766b9be6fdfd3ebdb25c5ffe1719f36c86ddf87ae3a85","other":"1090e9d89cb278a30063a5396d9ba795d3bbc237c76915a6fb7d23aa1822c8535d2fccc44cc8cd2acec68444c0bf1bdf5195ebb9f3cad8dac3d94a4d9c0e5309","up":true},{"one":"b35f418c7935cc54278e90978c3ef1521ab91daeaf9f1ebc1cd25211611ade091cac4e1f009d71059279d507322a4536501980ac0dd44caddc52fd4c593879f7","other":"0b30b36e155db04c448b662c4df695068b2331cdbe2772aae5fda84159e977515a5ff2e156bc225a9281fef2383926ba8cb11e9c1846fb40db241e524ac14e29","up":true},{"one":"a608a746f46d4b2e9267c65283380d6d6cb8885a64428fb77df9934bcf4dd1723587ee7c8f4a642dce266a12a6a4cf4e5c6db7fa1024158425a6753e7ab7264c","other":"23f9bdc82efbf57d3d40a1f2617d0311678fb4a3d6a50cb7e608c649bb618124a76c7ffd17387de963e1cd28d2bd5a61c98613f6e009a8a2a90d989827b35de0","up":true},{"one":"f915e2398aa5d4370de87504dd76c21a7d0be2581c2ab55b7a47743f1bbaef36384eaacec22760f1e914ceac9d96a10c3d66eb27475ef444e77fee979e6e88cb","other":"979838eaefcff456cf1cd9c47ea46854704f5757d8d7ab907019bc422b01af4d62252579bf045d143fab491b0bab823190e2782a457fbf51aa99ae17ec9e145f","up":true},{"one":"80d997b87856099d844187d3d1fa40846ded652a62c1611b35919c2543915b64ff62476636488556f678e436ea26fcc40db7c6b6bbcb78f590d61c1ff0e424b5","other":"ce0a09bb6fe4c9c93c3dbd800ca9c9ac0714f26a8f8dac2149b6ce7a9011912a5621ea2e45de35c4d31dfe5add00558fdba5dd21acf2d81ba391e82b5b3a5804","up":true},{"one":"016f8f4619a16a07fbde5a18e362158d696e4d9f104a77787f26e32a25cd7d278256f8e0db865c488a99511ec27a5eddd5ebbd1c1397fa7f8db111062e5fe959","other":"c665a6b1b7ad39b86bd4b1fe38b7ee95a0fbb1db15e91381ec9e5a235e33b69ffdc92c60dafd74b7b4dafca1b000e9274bf045abe5b93b1a9c2b31ae071a9898","up":true},{"one":"b4a5efa9028b2d196855393892f79993c2812d02b758f98813ddf82c5d943faf6d66eff811cc5a51936c118f4c768c0d13b54902095e040c602761e63c08655e","other":"6f60ef501b41f9049419b033ae8d793a18067bdcd60347537b0dc3873bdd9a2d10d24909cca7c39781765746128c2165596f6537a94f58279523faee71f9c51d","up":false},{"one":"a7507aa5665e165ab2e2a07def272f0677f9d6d35bb82268a34214384e7d8ef7635a299368752e63cfd02d4e60231076baf23cfa10d17492e55181b391ecf335","other":"7174eca109a1f717653918224c8cfe1b7fbd666405196760913593401eb79f2c7e41003b01f5a458940695b27a4673443c7621a169db7fd968994e552995dbbb","up":true},{"one":"a7507aa5665e165ab2e2a07def272f0677f9d6d35bb82268a34214384e7d8ef7635a299368752e63cfd02d4e60231076baf23cfa10d17492e55181b391ecf335","other":"3dfd733dde9414af916625ab981777ff1ad7ca0f6d1e4e7d9e2739969e21182fd13d85e281868653e7325b20069356b11524b54143c47fd3955a911cf7325ad4","up":true},{"one":"c83985973a9564ade7d90aa54911ac57077600676a1d27292d98e058bf1315887bad84ccd708cb7f52a695a1405fb7d491d7ca2ae9caa3ff58a5ad78ce4dc9d9","other":"bd1a7c63fca9e1fcc67d7fd62670beefe2bce483cf1dc1233ee85eb90db607917cd9a5d7170b10e80b925a20e2af2c54d286b01805ac34967410859f4f03da09","up":true},{"one":"ce0a09bb6fe4c9c93c3dbd800ca9c9ac0714f26a8f8dac2149b6ce7a9011912a5621ea2e45de35c4d31dfe5add00558fdba5dd21acf2d81ba391e82b5b3a5804","other":"acb4088c27ee2ee130ece3506596432afdb9e9757ec11ebdd35c5a6e87239545c48466913a646980104c8fd7a9a335e177f04efffe9dc952dfd7cd5c1bb9aac6","up":true},{"one":"b26f7c0113a5ae885f7c0e608aea7022a9c8bfc40c5643e60b2ba7343ff09c5be0bc08be34dde3c6b85fea192a46d4764770c12cbaa233df4231a1b99627ef9d","other":"6f60ef501b41f9049419b033ae8d793a18067bdcd60347537b0dc3873bdd9a2d10d24909cca7c39781765746128c2165596f6537a94f58279523faee71f9c51d","up":false},{"one":"2ddd49fae11d8bd2e7e75a481be267fa846f51cc1160bc326aeea51c542323ff444909de11e2731e835140bc0b1b32020e1e73fa652511a381222bf0aebc4081","other":"396c703d27bfdddf91761f134cbf665fe61e0b3a5d24036a4105a625f72e8c28b821e9200f20d6e8f8b3ed6b95bda6b8accdd840c2f786720b7431e3af2af981","up":true},{"one":"deb7af800cd20a647335f0feff5bfb3e182f99f4c2d1ade10da36ecfdbac3b5fba4e8f0a4595443fe395b44af3a95617669850944655def85d57cc81c5682a3b","other":"3612863ce0456c91785a829bf5c9d2b2fb97dda083a1847e5a4ebaa6fce1260faf4d1eb374c2225431a82774163835fb59c8cb0fa9fc0969eab5410c71109cc2","up":true},{"one":"58cfb20d3da3641e0ad529b9edbd4b590a8d1dc9d1ed7b44ed3187dba9260bd7c732fc10981f5b9bffd31d362cb05150173618aa36138984431d94a323a9b313","other":"b26f7c0113a5ae885f7c0e608aea7022a9c8bfc40c5643e60b2ba7343ff09c5be0bc08be34dde3c6b85fea192a46d4764770c12cbaa233df4231a1b99627ef9d","up":true},{"one":"84dfd4e4d9f1204893f190eacc4c3999e175c433f70de86e335d27477c097a0552f211a21764f01a708da4c9e9e6552191a61d3e48f41d0e84f01e7ae3beb34e","other":"4b784f072b7c96c30612767425f552e30e45157e70139dfbe0ae4ff86dc31601adec60f8a3ad9747b02b5219073d8813af9b09d59eaf7ddb7ee24856aff6fa8f","up":true},{"one":"617595a230e0a74a3db3b47cd27b941e02bdee9a84cdfa8eaa63a55941eb5caa79e20fb69726a4d46a0e5aeed24039f8c5a20679a692df0bc140f42558ca9a2b","other":"a1560ce7c1f1d5972f027a8e9cff820611d84764aa067434a75b63887bc4268a259101486d34b7fe83dd735e799789986cd3e9b156c86ede598bd86af4454924","up":true},{"one":"23f9bdc82efbf57d3d40a1f2617d0311678fb4a3d6a50cb7e608c649bb618124a76c7ffd17387de963e1cd28d2bd5a61c98613f6e009a8a2a90d989827b35de0","other":"a127faa19dcb7da585983d36a8e9d3e9a44a6db68507b60c70da71011f44ce377944802f39cd65f5a705cd8249ac1ef7ed8fd699349098f3f8e23b37592c80ae","up":true},{"one":"8d4920d6e3a6717699b5a3af068cbdfc16858d7e393d158d41b1b5f345b47129eef89e1d055386c518f400b134678c21590f0317dea3436d4cef60f45455cf12","other":"4de378164d77a28c90cf162dd1b465e0282ee17aa7d3bb3179252466f72da33a36c9f298f7c9498e38dba4018e7ce3e5fe631c83842cd9059e23a7fece366d87","up":true},{"one":"5eccdbcb15ef42dc96abcbcd8b8db75d9230de10e3c650620737f6cc04ba4fdbf59ded5daa801901c191be186c329ebcd37ba83bcf794064ad4e11bf10d3f775","other":"5566111b7f14d8ec83ba6456488f3fc5c7e2c86bf406dead33b814e1ee9b569d34015a4d88226b7e28fff7784395c086d106287cbbc80acfe75b05cd6e12903d","up":true},{"one":"f54335964d9b4eb9813eb05f40ef1c523bbf0faac5a04c4737467d590fb6b55c7fa1fc5d4d32c5491d8766b9be6fdfd3ebdb25c5ffe1719f36c86ddf87ae3a85","other":"2245f3bf1a3b4e92f912affc75f757cf648b20474c11ffe947884f216b8f24f9dcb6e6a0358a4061b8517478ec15027e185b2f05a777573b4940375bf4aaf2be","up":true},{"one":"76cbf9fc0f3517fb615fa96104780218e85d064ee5a1d518f3b78f4dbebf144df38c427445fdd6c9b436489c00ff9497d747a8fd70f380f95601d59e52e021e8","other":"5bae82d4832092c17bd11474f7748015b8b69b896ab8f683a7c0024fc98740cecbb9e31c6275269f9000e5bfe51d7f45cd5dcd4433e0c87b5741685b40fe3983","up":true},{"one":"2a63d875e715c2a43302d32d86d30c7d7faed46c08a67bf488762637216b99dd87333a66df6d9f3a57df863b1f1a219ddbeebb9f3e92e523bd08540a195448ca","other":"b53078000796f1cdb04dfeac424d5e3e37e30f00bd5bebf9a9ea0525c62917612b3a8f508df6bea59e3c7e4cd1aa530841f9a8af54e44f5617a13dee2c6ff007","up":true},{"one":"e267e71c2dcdbe5a500b23444d2d4037ea15afba8f4f2b1c0e54a274450404fbee6fa5439f7cddf4ba1aa28fa93e434b01c239add58e30a5423ca3a481584d6b","other":"990b1db3ab1390219e8866d39fa4441bb5bb89ad786b3e255771869fcd08906dcf63f34007481769c7462edbcc665acc0a552e3733360b8d8c310c9321a5550f","up":true},{"one":"2e42f845d0393d1682add54ee30b60a953ed283e75d347bc6719ae0e91f6676282e7960f1fd52e5803d6b341fb3582c724b4f9cfd7bce9ce85f13ca480c7e72e","other":"7b35c856916eb3fc1b1f451667e240b95aff8f4731cc0f6743740923081ff1ddf2eec81bdccf4691a7bcc053d23eacfc15809c384a73448f618317bf605bd1cd","up":true},{"one":"389b5c1a805f87427e6d647ec5488342a3f7d700615943d5ad98ca5c111f33c7ee007970b4d3e475892095c0d5a79b7ed52d12598398818159000d4b9b719126","other":"b597c9ba4da20c49fc4ba019571321d2579588636cdaceb9f225706574970adbf4771dcf186b1decd4e14cd5d257e30a36ca829829598c1775902201ad9793e2","up":true},{"one":"990b1db3ab1390219e8866d39fa4441bb5bb89ad786b3e255771869fcd08906dcf63f34007481769c7462edbcc665acc0a552e3733360b8d8c310c9321a5550f","other":"abd8f5a4d700c06ec00684b23d2d25c4df1a9554fcfc57b0ddc3fa476e6a699ba75e1213449f900803f83ab8194c6746664b547202047f35b8b3e216c7147bf8","up":true},{"one":"043fe7085e8c90c18270f84dba5fab138e50216a1cf8d81a3794d156fad7fc81d1422aff169b244b13f91d73eebb5de464f97b1b93b3ad2a58959cff19238842","other":"17a79cb279306b6bbd35219278f6bba03111079d6c4fadcd3c5e57b09678e111bda5f8e36ca3d223e51e255d6e857363b7741e438b32ec6e6c0dc1b224071081","up":true},{"one":"f33d1f3e460574706ac1c7fc9ebb4683b173496ce3e80017d1c3521bca03d5a41a9c7a6cde8347d2238917b7cc58cab000ce7ccf6bb408561015a2ecbe613408","other":"2ddd49fae11d8bd2e7e75a481be267fa846f51cc1160bc326aeea51c542323ff444909de11e2731e835140bc0b1b32020e1e73fa652511a381222bf0aebc4081","up":true},{"one":"352407b42726dcd1aacc46a912ed8124b8b6a3da4e33dab742e40aa2452953d35dc8f42eddc76695ae2317e9f15dde2cd21be4ce826934695ad1847455661d1b","other":"aacff366e601e072a2113add9020e19b6612f3e85b6e607fdc8cc1b6991f43be0b1f835ed3dc41d1f2b3e0caf7fac252c8eb4c150667d48207fa92ea5f0a7455","up":true},{"one":"855bdf057f4a6b095e2000ada199447b5b4f2f8d78d2ecbaa0ff1fbf761788870ee999266ad3b26efa02be1a46a4d92ac0debb85a2ceab3442394ee7d99e5355","other":"8f88c7ec044f758f29bd8d12a5170bd973aec8f6cddbf512b910c4b75a0fec09c5e198bcd65622037f897759db68da2328b4a7ca93585dc9cb62e46d2a6c0864","up":true},{"one":"4ee37acec2178ef120166265aaa2b64b09b315fb53861405ef46f2503c273eb9692e9cb4c2e67a8652254d430fd6e02dd3fe4cded20bb231a9fb834d292b0b24","other":"afe5b217dc512eee45575c189826ee5640d11a0ac9e8e4b03e9e62e6cf6df9de500bc8a36cb7d82a2280ce184409164f1772cc5c9e59ad04361522d2b8c364e0","up":false},{"one":"24662a43944228e4ff74736bcf0a0a4f79c87ecfdb739225b2fc45110c11bfc38aaf2d09d98e5817477848e553f187ac5408bdb864518dfa7f5df542768828db","other":"b6a998dea59194cc60ce97c7c9702368411889cb6905516b23f41cc5116fba8d0f237d418318eb0c333cad18003c0e9a6bd8c99080520771f2bad640e2e5ec1c","up":true},{"one":"a7507aa5665e165ab2e2a07def272f0677f9d6d35bb82268a34214384e7d8ef7635a299368752e63cfd02d4e60231076baf23cfa10d17492e55181b391ecf335","other":"66d0c5da973d9dd65350ae1ec63776872cdb7ded6afb6f51ae82259f6fd35e884375d15de290625f02ed2e5cdc3f591decb45e5fc64d5b0f835a216fd196f5a3","up":true},{"one":"3d2df188704eeac09c8b291bf275a73888199a231c832c51dbc3d746968d4b51a7d5eae0c7c9b8c8e19f5e28d38c375e01abefa343f31dbe221deb837ab8a0df","other":"f915e2398aa5d4370de87504dd76c21a7d0be2581c2ab55b7a47743f1bbaef36384eaacec22760f1e914ceac9d96a10c3d66eb27475ef444e77fee979e6e88cb","up":true},{"one":"bcf8e831821a5bca359fb824c7dc4d66906de82f3663a0a853d96880a8ca0bdddcceb1b66dd1f13f75ee20fde50fc9de545bc25767f228baee910e0dbfa8cc27","other":"be514f5f17f3177235acb24112b578edf0e373c469073226e547d18080905fd062d572be18e943f13bf9fcf5871e89ceb630a1b848a0e370ef8ef8c6d997a363","up":true},{"one":"58cfb20d3da3641e0ad529b9edbd4b590a8d1dc9d1ed7b44ed3187dba9260bd7c732fc10981f5b9bffd31d362cb05150173618aa36138984431d94a323a9b313","other":"b4fd11306b1416a9bcf4719578976188e104b8c5028b9abd3214d257446b97b70a22e6c00934d80caddde15e8e4d16af03bb399583047983fba373d8313226b7","up":true},{"one":"ba21a373781966135d6225adae024a3f3e421b852f72f8b0569cb92fcff87c33f7e5b799a509b8eff6ec6dc46a9b17d5bae1e91ec7c54c0c712d893d54b140fa","other":"48a5e01e06e297dc1c640ac9601171495bd70fea461c60e7e6e2532695e45fcf68183c2e58b5e6931a6c1c094f5331efbd7f2d93d5f84efdec5a35afa2124438","up":true},{"one":"60725e8d0e9333636e598dd666f459b4be898d9abc095ee2c1db289673e7e969b50e2093956fef5a2f1d23e2040159bbabaaeab17fc6dbbac3f6acab766e9e60","other":"657d5370319128d24d925b41065eb619409d63ec6280975d78877a4028287463f6442f5206dd703569a05b2b542ad8bbb99803da265408208d6356a26d283d08","up":true},{"one":"cb321c9b0fe2eb3617b8e2461aab170a9dad2c9b04a10eead4e37e551197ea0a7500eb1cb7b155efe1886486ef3d252d8ff0d309f2906a1126ca011d037da70a","other":"4fe37f2dfb03707c90a6fe91dbcfd7497db70ffc20043091d50e1cee573210c144e8749340f2c3cb70fe8fc51b317d49e8734dc51ce64b3cdccdd639ae35d1ae","up":true},{"one":"eaca77d20c4ad6b87649eba21b750a4b1a2c575e06bc42679d18fce16fea15212e9a7408c16f3b24d8dfd1e397314637e72e292845d09534a39035bd9203ee9e","other":"57cd4c0048b459192ee46e19ec7df777e600f256e0dc8c3019431eb7bec3c020b9504ec7aea3dba8188658ca5b830ec40af6a8540ce10e04badc6c695d009271","up":true},{"one":"6f60ef501b41f9049419b033ae8d793a18067bdcd60347537b0dc3873bdd9a2d10d24909cca7c39781765746128c2165596f6537a94f58279523faee71f9c51d","other":"92d6ef729992f0de886076e5f8cdc42cbbd70b29e79c25e0b3d22b6575d3d2508d47b42f581e335455483d43625bce4e55f88cab9ff2073ee8dab746357864fd","up":true},{"one":"62666b24d1026345349edb6a878cdc27d6fee8254e83f79a298ce2805260d97aa46423deae440f86ced5cd99b30e970c8e1ea1046752b17d8c80dc68d9a49b60","other":"57fb1bb32bb2b1a87e44c6a7557e9c47c2032d107bcb0e34acd9ffd54d5d3df5701232db16f62f7549ba2721021898b03160b1dc5201e79606648c1dbc4a373b","up":true},{"one":"315b8a1711f680c2eaa607e35ef7a9e19c2b61721af8a7e08f1325dde1fe33cf1f47b3cc4acf12d541631041cf1b42754875fd1c9b66ee32797b72b9f7711256","other":"0cacda5560faff9d20e29a0625d3cd340ec075f198a50ab8b79338cee0e0db84c7c7e71042fd8c8f73e507b570de5d26c39473136b575f0167625a1168309ec5","up":true},{"one":"fe62314839c93d2f6e3aee984d5f0b321897c6f39e66800d3de8b773baf6f19e0a03cae025df512aea8d5f1b667b6dbb15c192a90a76d3031c14e33e5c16c4f7","other":"6b01079463ec2f649db8634cb7a596261c79a8f714d954c772528e0547b017f8ce405e4a0ea9d32270848180e0f77b8c0b022cf95c85e777626edd4d24ea21d2","up":true},{"one":"68cc8b9a995eef6170abf88bd5fedca06ffcc8d75f247f6041c13e7dfd292727ebda1ff86b776e33b6634355c55e0f8c22fcdb5f9a6e2f22fe1af7854c3b4273","other":"eaca77d20c4ad6b87649eba21b750a4b1a2c575e06bc42679d18fce16fea15212e9a7408c16f3b24d8dfd1e397314637e72e292845d09534a39035bd9203ee9e","up":true},{"one":"b870935867183bbfb84add16b9f56c02c834b7042fc24ce6bcb2a7f174e6d2239357a00be4272c1ef05c7f9baf5a9f16b53bc18328a9b7aca8540c2916805b57","other":"083e67bb19e30d14e4df6d2483367d6659d9b56744d53d9cf7fd15954c327e1bc88a5d0db8833634e1dad7209164451f8934b59f76b5990059261abfd650519a","up":true},{"one":"b3316f4fd7dec218a52331f25d17a2faf0f2a417808d7dbb80038154abfbcd2d78da074837b648cff28675f4aa0d65ddb7d15abf3d7e0391d401e313a3ef24a2","other":"ff1e34fd51953ed641b431aa657da21cb4c81d23e4eaa13c9cce526f1f1b34593d41f9b87a0e10387fe400c623638677c0efab15dbd1014a0ccc11f9ec92c417","up":true},{"one":"a08e47137bf611dfbd20308a22bdd3ca00121386f121d6d712ade86e9a1601a4237766887cd91c8516e20b6e323d2ef49c1c7e177a0afb4c813f0f344daf779b","other":"ff1e34fd51953ed641b431aa657da21cb4c81d23e4eaa13c9cce526f1f1b34593d41f9b87a0e10387fe400c623638677c0efab15dbd1014a0ccc11f9ec92c417","up":true},{"one":"0cacda5560faff9d20e29a0625d3cd340ec075f198a50ab8b79338cee0e0db84c7c7e71042fd8c8f73e507b570de5d26c39473136b575f0167625a1168309ec5","other":"e2e0419a41bdfc5bd76deae2ddce6ac865f886d764c9bd18799b79fa3b2b6ba66d765d26da2037e98317e1d7e8232a61e63c1d0cfa98c9137424151b46e07171","up":true},{"one":"c83985973a9564ade7d90aa54911ac57077600676a1d27292d98e058bf1315887bad84ccd708cb7f52a695a1405fb7d491d7ca2ae9caa3ff58a5ad78ce4dc9d9","other":"c57ea182bdb42ba9b0870b5c870e467f52693e5c0df752fb6eb0dfbacce7763f73caee10db40f4fd90f19f504ee586eaf9da41f5ee93ee515d885fec99374116","up":true},{"one":"8ca3b63cb84f1e9883d82809a9b6777ec1029ecda96fe93b4d494ee9cbefcad13f381b3e480136e542e01054fe1ede66c65db84a0009871ce49383db461c8438","other":"e2a27dcdee1f89fa362a85c4397840cd8be4ad8d1b9ccb23188c303bcab7619f38772f71385922d090390973b62fb8249efc103f71bc761041bcb3880ec0b935","up":true},{"one":"083e67bb19e30d14e4df6d2483367d6659d9b56744d53d9cf7fd15954c327e1bc88a5d0db8833634e1dad7209164451f8934b59f76b5990059261abfd650519a","other":"2ddd49fae11d8bd2e7e75a481be267fa846f51cc1160bc326aeea51c542323ff444909de11e2731e835140bc0b1b32020e1e73fa652511a381222bf0aebc4081","up":true},{"one":"396c703d27bfdddf91761f134cbf665fe61e0b3a5d24036a4105a625f72e8c28b821e9200f20d6e8f8b3ed6b95bda6b8accdd840c2f786720b7431e3af2af981","other":"1b063741c76fe65e62b4eae42751319d0cce66f22dde9f1cf83d6cca249a0e65bc7f6f22597697362fadd226222fb3847f8e146961969d1b4c9f7e475389cd8e","up":true},{"one":"b4fd11306b1416a9bcf4719578976188e104b8c5028b9abd3214d257446b97b70a22e6c00934d80caddde15e8e4d16af03bb399583047983fba373d8313226b7","other":"4ee37acec2178ef120166265aaa2b64b09b315fb53861405ef46f2503c273eb9692e9cb4c2e67a8652254d430fd6e02dd3fe4cded20bb231a9fb834d292b0b24","up":true},{"one":"be026dfb24847cac2d00f483104edad06ca8ecb9e1229c479ef5650c7b427cd5dc34a1cf06172c17c9d0406ce17009712e82446394743d4cd9bbc41c537ebc14","other":"5df58ba12334a1b4f983d642fe435901261767cd81f8f37c43e359f5584664e4d287e8c2275995604a3b3a4823418e35cd899a3db2a7db31570e19512f375481","up":true},{"one":"4e68553db7be307b8379e8bec383b5c92e4b23debcefca575d24504e2062618f74c26e60e0d9e47f096997a7f841e2c32c994124f495ef3352ef964b33fd3a51","other":"68cc8b9a995eef6170abf88bd5fedca06ffcc8d75f247f6041c13e7dfd292727ebda1ff86b776e33b6634355c55e0f8c22fcdb5f9a6e2f22fe1af7854c3b4273","up":true},{"one":"2e409baefbd821485a151993356730e5989810d581e68190fbaa142799c9335bcf98310ad188fed10ae6eb6e2e789730393e509962ec5c0fef0342d72ed088d9","other":"53df9cce9b0169e58ced53a123d1d8f6e8fdcfb4c2d781ecbb91bb7c8eba36946dd9d21c749259769825d8a6b3faa6bb87c8c6085a522f8a3e376061f59144d9","up":true},{"one":"0deda014fa3c0bc8f37d853e1448f95f56f97048c28797d72258fd3ba2f1f776ae11566197466596356cd172847ab02a89f4cf047e58383249fb2a4cd69b6206","other":"afe5b217dc512eee45575c189826ee5640d11a0ac9e8e4b03e9e62e6cf6df9de500bc8a36cb7d82a2280ce184409164f1772cc5c9e59ad04361522d2b8c364e0","up":false},{"one":"460531928a4b084686343c8464b37c3452bb3566045698d08a4692864de5581a9eb1dc632329e7d3ccb73ec31ee7693787d69df8458efaba9a7105d87ee2e053","other":"68cc8b9a995eef6170abf88bd5fedca06ffcc8d75f247f6041c13e7dfd292727ebda1ff86b776e33b6634355c55e0f8c22fcdb5f9a6e2f22fe1af7854c3b4273","up":true},{"one":"094f9d0fd3bacb17ac67a2edb8ed394fbbd1c8d478233d3269cf217e7b788e21042374936b885bf23ee4f9e03babbe4e08db283dfc2a6e052a8a5ba133717dd5","other":"855bdf057f4a6b095e2000ada199447b5b4f2f8d78d2ecbaa0ff1fbf761788870ee999266ad3b26efa02be1a46a4d92ac0debb85a2ceab3442394ee7d99e5355","up":true},{"one":"9c30ad8c85adc7bb52ddcfab2e661cc3a854a689eaa59128d35129d02cd5b0f8da4a44cdd33934a8e2c8fab1760c16d6f2e1c5eb227dc819e85624e63343c069","other":"9db1f94d74a00d1e5e2a391f1bcddf16b6d0670a2c6d91d946d38112c58634444b6fea8e8c05ab4b73bacdd62a0b575f6fb8729978edc216c7842b177b9f9cd9","up":true},{"one":"617595a230e0a74a3db3b47cd27b941e02bdee9a84cdfa8eaa63a55941eb5caa79e20fb69726a4d46a0e5aeed24039f8c5a20679a692df0bc140f42558ca9a2b","other":"e087230634f556b818a416b66ba3f1d1dbe3e0dd0698bbb26fa86a2499acd169466f564dc18adf2f9be4d1ada0e86c11549754097601e10aff4f3a57ddffa24a","up":true},{"one":"cb94a8270d0050378116b5815ff17dafbe20f5303839c4fd57b981d4687a4b145e4bccec7e9af9b9475005930148ffbfa97781a0762c8e9f352dc95565fc8732","other":"abd8f5a4d700c06ec00684b23d2d25c4df1a9554fcfc57b0ddc3fa476e6a699ba75e1213449f900803f83ab8194c6746664b547202047f35b8b3e216c7147bf8","up":true},{"one":"7f357b8d81bc2e5c6fcb081f23a42b3e2439f050d45c45851994a268d1c71fcb1f39f8c3f75ce921d3fbf80fc0e73f0b9609d72001dc4a6b65b526d312a4f43a","other":"2f360209383d6de4ebd3b4abaf77796520b8654270b03f2151eac4a01b4417d7e0668c1f9ad30c20ff49aa8a0ab33dba5e6095619d1cf04b7af841722ab773da","up":true},{"one":"829b074b70d757da6aa00f7bace3cf1b5d2d4eeadb7f370c1a85374a01a70b54ac53d747267e386f3b41e6d790fecdd6e74b8f89745501ee82439a66ea54443a","other":"1090e9d89cb278a30063a5396d9ba795d3bbc237c76915a6fb7d23aa1822c8535d2fccc44cc8cd2acec68444c0bf1bdf5195ebb9f3cad8dac3d94a4d9c0e5309","up":true},{"one":"ae4e21e1587a8475afd299e00ca7085c7bf2a44c2c64a3068f12223d9202b0125094385319034691ec26b497ec9cf18fe8c0839224bac1b84279410241cef979","other":"ae2a996d3b562cb47a564934037949da83b1bfe194c23754f3dbe2372ec27654f4f3b6cb7f394570f308025589c065870477667e5560dbe5a8ea1625740699cf","up":true},{"one":"acb4088c27ee2ee130ece3506596432afdb9e9757ec11ebdd35c5a6e87239545c48466913a646980104c8fd7a9a335e177f04efffe9dc952dfd7cd5c1bb9aac6","other":"920a301186bdf665a721676ece7c180413369ea6eff7537f42049d9eb409f28cc864099590116e885f57368959fb2cff7003697d9b1515e68bf3fa7aee0278ef","up":true},{"one":"6b01079463ec2f649db8634cb7a596261c79a8f714d954c772528e0547b017f8ce405e4a0ea9d32270848180e0f77b8c0b022cf95c85e777626edd4d24ea21d2","other":"8c6d77833bf1a98beabe7a92d985d13d52fb2e50768719ffbc6fce21ea676802a074b6e620b3ef80e12fad04f94a3c288d91df9716a6cfae09ef073b9dc1f2cb","up":true},{"one":"2f1967b4410ea2ea8fbaf46771ba82c2846d00aecdb6f873aceae33ab38f72d0a2c2dc6046d3034f514efd090d42011d48e9ab0cb4e3caa2b49a96ef732215a1","other":"109556abac422a912ecffec0d8796f8f16e92e8f95cecf72dc89e97a8bf1fd37aad3c66aa3cf134acade6d065c31821f977171d5c5463305b57ce3eee99a7ab4","up":true},{"one":"4de378164d77a28c90cf162dd1b465e0282ee17aa7d3bb3179252466f72da33a36c9f298f7c9498e38dba4018e7ce3e5fe631c83842cd9059e23a7fece366d87","other":"352407b42726dcd1aacc46a912ed8124b8b6a3da4e33dab742e40aa2452953d35dc8f42eddc76695ae2317e9f15dde2cd21be4ce826934695ad1847455661d1b","up":true},{"one":"4e68553db7be307b8379e8bec383b5c92e4b23debcefca575d24504e2062618f74c26e60e0d9e47f096997a7f841e2c32c994124f495ef3352ef964b33fd3a51","other":"aacff366e601e072a2113add9020e19b6612f3e85b6e607fdc8cc1b6991f43be0b1f835ed3dc41d1f2b3e0caf7fac252c8eb4c150667d48207fa92ea5f0a7455","up":true},{"one":"b597c9ba4da20c49fc4ba019571321d2579588636cdaceb9f225706574970adbf4771dcf186b1decd4e14cd5d257e30a36ca829829598c1775902201ad9793e2","other":"a127faa19dcb7da585983d36a8e9d3e9a44a6db68507b60c70da71011f44ce377944802f39cd65f5a705cd8249ac1ef7ed8fd699349098f3f8e23b37592c80ae","up":true},{"one":"68cc8b9a995eef6170abf88bd5fedca06ffcc8d75f247f6041c13e7dfd292727ebda1ff86b776e33b6634355c55e0f8c22fcdb5f9a6e2f22fe1af7854c3b4273","other":"e2e0419a41bdfc5bd76deae2ddce6ac865f886d764c9bd18799b79fa3b2b6ba66d765d26da2037e98317e1d7e8232a61e63c1d0cfa98c9137424151b46e07171","up":true},{"one":"5eccdbcb15ef42dc96abcbcd8b8db75d9230de10e3c650620737f6cc04ba4fdbf59ded5daa801901c191be186c329ebcd37ba83bcf794064ad4e11bf10d3f775","other":"adfba6d883cacbb141cd8c59ee04d7e5d520f1ce31a81e5db2d8b2380bf801c1fe4b265a66b71f9643d13a41cb1f6fb4b83399be786da4b6e171b6784bc56e49","up":true},{"one":"7e2b0b4f3b55e97bd7241b984ad117af33bf3baacd22b3ed503a8a59f75828df745fb3ce3be4276d83eb484e64d9aa251103fa994ef119eaddb97a3503b9f292","other":"0f9f7e2dce4ca266c3ac0ec3a8854200b54487f5308e3db418461aeb5f67c81d332619b6441b468e480941e63100ed1b263e7adc20689dc3dcda578bfca538fa","up":true},{"one":"2b70e5ffcc0bb1c4f8acc09dd1016e67c9c96c92d091ad481efbb71bd8b2a5a5869c6d668617a9b2cbfe91baf5edfe150c3824c84d90899a974099071d171441","other":"4e95fb8943ef6502fa470870a7ace4ca11e18589bd2073167543a922317b35e40b5068934d07e56c8fdd23354dfad51fd2899db854f189841f02b5914cd97749","up":true},{"one":"732393b99c490c76fa45e3e404ee095f2fa445fcc123af7ac8ab1d2fdd7cf2483f5b82bb818bd8a82b1a3b73e63bcc2c83d8f24d9aad9afe36503735e7967be7","other":"ba21a373781966135d6225adae024a3f3e421b852f72f8b0569cb92fcff87c33f7e5b799a509b8eff6ec6dc46a9b17d5bae1e91ec7c54c0c712d893d54b140fa","up":true},{"one":"2e42f845d0393d1682add54ee30b60a953ed283e75d347bc6719ae0e91f6676282e7960f1fd52e5803d6b341fb3582c724b4f9cfd7bce9ce85f13ca480c7e72e","other":"1d0244a13affe60996fe3cf51ba624adc746de0c7ea68ec5a31311a36077c5b5495e3d95c9642875db44c7ecae6ffed22e45f2e2d024d486760be2af9f4cf2cd","up":true},{"one":"40bdac599b00e9c41ad6476ee415c33d9c17c5aa672692c2404e523b29dc315da929a86874bed87fd9009871805d1dbf3098e7a817193e3b08a6eee66346da79","other":"155e4879643a472420012e040a87dbff776fc1976814c0c6cd0d5e157f0d0baac04aa7f2535786c09acc2700547383d2119b64a6f62115f1aff1708738844d8c","up":true},{"one":"b26f7c0113a5ae885f7c0e608aea7022a9c8bfc40c5643e60b2ba7343ff09c5be0bc08be34dde3c6b85fea192a46d4764770c12cbaa233df4231a1b99627ef9d","other":"71f89efcf939294bb94ac669c8afd00def58c8dfad519c226adfa068692d588ef797116d42aa146b9d34f3be35ec7c014022640ab3c0f1f9034e44ab1a26e246","up":true},{"one":"ce0a09bb6fe4c9c93c3dbd800ca9c9ac0714f26a8f8dac2149b6ce7a9011912a5621ea2e45de35c4d31dfe5add00558fdba5dd21acf2d81ba391e82b5b3a5804","other":"88d5c5fe61ee1e6fa5878e0eaa13bdabaa0ec3d38a5d25b95a467da7627424f25fb5d30535aa0a5ad01c16fe2598dbf570b78cc152a7f4ef66d46fc9ae43592f","up":true},{"one":"fe8ac5d33cd8ab6a1dad9567cdfb89b431a5c4f4a584fc608b92e7dfd06f70988e71e2f11f9fda9ee797c9ffba83bc085939fdf2522dde39f28202be92650566","other":"c57ea182bdb42ba9b0870b5c870e467f52693e5c0df752fb6eb0dfbacce7763f73caee10db40f4fd90f19f504ee586eaf9da41f5ee93ee515d885fec99374116","up":true},{"one":"24662a43944228e4ff74736bcf0a0a4f79c87ecfdb739225b2fc45110c11bfc38aaf2d09d98e5817477848e553f187ac5408bdb864518dfa7f5df542768828db","other":"617595a230e0a74a3db3b47cd27b941e02bdee9a84cdfa8eaa63a55941eb5caa79e20fb69726a4d46a0e5aeed24039f8c5a20679a692df0bc140f42558ca9a2b","up":false},{"one":"a7507aa5665e165ab2e2a07def272f0677f9d6d35bb82268a34214384e7d8ef7635a299368752e63cfd02d4e60231076baf23cfa10d17492e55181b391ecf335","other":"b137cf2291b530a39516d882200848e7f27a2710e0839b4d25b4f367bea6a0c3aaef8c7c7851c00a2945adcd819ea0508610afc1f453b8bc512b7b4d4faacdf3","up":true},{"one":"3d2df188704eeac09c8b291bf275a73888199a231c832c51dbc3d746968d4b51a7d5eae0c7c9b8c8e19f5e28d38c375e01abefa343f31dbe221deb837ab8a0df","other":"be514f5f17f3177235acb24112b578edf0e373c469073226e547d18080905fd062d572be18e943f13bf9fcf5871e89ceb630a1b848a0e370ef8ef8c6d997a363","up":true},{"one":"bcf8e831821a5bca359fb824c7dc4d66906de82f3663a0a853d96880a8ca0bdddcceb1b66dd1f13f75ee20fde50fc9de545bc25767f228baee910e0dbfa8cc27","other":"016f8f4619a16a07fbde5a18e362158d696e4d9f104a77787f26e32a25cd7d278256f8e0db865c488a99511ec27a5eddd5ebbd1c1397fa7f8db111062e5fe959","up":true},{"one":"934a5fe1b91c1891ef4df7f67c027e0eb115d4c2ca4a1b76a135ebd4315c4fb835d6625223194e6a134407b38b0d3928fbc7bc924a3c6a538989a6cf200bf4bd","other":"acb4088c27ee2ee130ece3506596432afdb9e9757ec11ebdd35c5a6e87239545c48466913a646980104c8fd7a9a335e177f04efffe9dc952dfd7cd5c1bb9aac6","up":true},{"one":"c73d088ade8756c74832c73542bcdb3e52f670f7a74ad3a7eac2a9e3ece6bd081f782a8e1d3f9a40b9aa9201509110f37fc57fcb10ee1ef3ef07b7eab019782e","other":"a78f18691e0dbf3c08fe9d7dec188e6a05a93833432fb99eb2b3924ab0bde7a44db2a102a65544bbdc4fb61bc3a3d569230d9843a335bf619167fb045d78ab3c","up":true},{"one":"be514f5f17f3177235acb24112b578edf0e373c469073226e547d18080905fd062d572be18e943f13bf9fcf5871e89ceb630a1b848a0e370ef8ef8c6d997a363","other":"315b8a1711f680c2eaa607e35ef7a9e19c2b61721af8a7e08f1325dde1fe33cf1f47b3cc4acf12d541631041cf1b42754875fd1c9b66ee32797b72b9f7711256","up":false},{"one":"cb321c9b0fe2eb3617b8e2461aab170a9dad2c9b04a10eead4e37e551197ea0a7500eb1cb7b155efe1886486ef3d252d8ff0d309f2906a1126ca011d037da70a","other":"b53078000796f1cdb04dfeac424d5e3e37e30f00bd5bebf9a9ea0525c62917612b3a8f508df6bea59e3c7e4cd1aa530841f9a8af54e44f5617a13dee2c6ff007","up":true},{"one":"97981f4b825620985b746c85824d7a4d307ee25d60a72c2b7de4b1d4f3b1c002652adc3045842d350f849789e410a0357a0b42fa637a1b4fc9d39e44f8a674d7","other":"7646d08b3e24183e3814de130235c41eb88a5a2abff23eaff3c91954ad3ef55fe27da422dac5b894312276bf1a2f1aebb8b636a8d4a0c93d9b016d441df3fa19","up":true},{"one":"8d4920d6e3a6717699b5a3af068cbdfc16858d7e393d158d41b1b5f345b47129eef89e1d055386c518f400b134678c21590f0317dea3436d4cef60f45455cf12","other":"352407b42726dcd1aacc46a912ed8124b8b6a3da4e33dab742e40aa2452953d35dc8f42eddc76695ae2317e9f15dde2cd21be4ce826934695ad1847455661d1b","up":true},{"one":"80d997b87856099d844187d3d1fa40846ded652a62c1611b35919c2543915b64ff62476636488556f678e436ea26fcc40db7c6b6bbcb78f590d61c1ff0e424b5","other":"28d3232c43de54ffdaf08f97b334c012738648b04e2876c7e751a2e352aaf4d550d6efa976c5a8edbfa8e88b9d04a0fca492b81c3756ef673ab74d34182ca711","up":true},{"one":"b3316f4fd7dec218a52331f25d17a2faf0f2a417808d7dbb80038154abfbcd2d78da074837b648cff28675f4aa0d65ddb7d15abf3d7e0391d401e313a3ef24a2","other":"829b074b70d757da6aa00f7bace3cf1b5d2d4eeadb7f370c1a85374a01a70b54ac53d747267e386f3b41e6d790fecdd6e74b8f89745501ee82439a66ea54443a","up":false},{"one":"302c37f28c69fdcf00b39ce0c0223de0d94cebc2c0b068315b95b76b5432573ead0656569441029ba9054d8d3d959fd8735e73913af5ce3f1132f8271fd437ef","other":"a78f18691e0dbf3c08fe9d7dec188e6a05a93833432fb99eb2b3924ab0bde7a44db2a102a65544bbdc4fb61bc3a3d569230d9843a335bf619167fb045d78ab3c","up":true},{"one":"27d9048707a89f1a61e44fdae523c0128f2a7050308bd3cfefa6c3e03040a0e22f11ab41275f22b8706e6695ab93320e2af35179d772581db5f49f960750f2f7","other":"7e2b0b4f3b55e97bd7241b984ad117af33bf3baacd22b3ed503a8a59f75828df745fb3ce3be4276d83eb484e64d9aa251103fa994ef119eaddb97a3503b9f292","up":true},{"one":"385168340139236a0e0f537fa693122db9fa02a377c96f31aae54718e92624fc0288164877e63616651565e055c53f7074ab2fdd18a837da6faf644941305bf0","other":"657d5370319128d24d925b41065eb619409d63ec6280975d78877a4028287463f6442f5206dd703569a05b2b542ad8bbb99803da265408208d6356a26d283d08","up":true},{"one":"aacff366e601e072a2113add9020e19b6612f3e85b6e607fdc8cc1b6991f43be0b1f835ed3dc41d1f2b3e0caf7fac252c8eb4c150667d48207fa92ea5f0a7455","other":"460531928a4b084686343c8464b37c3452bb3566045698d08a4692864de5581a9eb1dc632329e7d3ccb73ec31ee7693787d69df8458efaba9a7105d87ee2e053","up":true},{"one":"016f8f4619a16a07fbde5a18e362158d696e4d9f104a77787f26e32a25cd7d278256f8e0db865c488a99511ec27a5eddd5ebbd1c1397fa7f8db111062e5fe959","other":"89a5b92a9ca045f12c35a70084e6f41f9775a25d6f105f8c9349c7b5e107179d8a96bdbb113b2680edf5183e9a42fd64bd7b29d0dc7797c583b833f869313699","up":true},{"one":"c83985973a9564ade7d90aa54911ac57077600676a1d27292d98e058bf1315887bad84ccd708cb7f52a695a1405fb7d491d7ca2ae9caa3ff58a5ad78ce4dc9d9","other":"2bfba66ec9d63e928d77d455f2e10a14d6213e515099d5db14fa44a8bfc147eb0fa7afa9aaccdc86453c6903b55556059a2e13dd61fc494127d4a3ec173bf9ea","up":true},{"one":"fd4968df03d767a223bf7e4dbe26b5c27048298df40e81cad50b344fb3e6837965f2646dab7ffb2891a5c507343ed84bb8bbe403287b51dae538d58fcb6e7623","other":"b597c9ba4da20c49fc4ba019571321d2579588636cdaceb9f225706574970adbf4771dcf186b1decd4e14cd5d257e30a36ca829829598c1775902201ad9793e2","up":true},{"one":"5dc69635f6d573c824ea83b18593a47f9f21a6f91ce18d2bf977c97d21f8d2a8ce88829244d12a07d949bbd52fe8a2035bc89685fe1bdd4ee20d766d75d3deee","other":"89a5b92a9ca045f12c35a70084e6f41f9775a25d6f105f8c9349c7b5e107179d8a96bdbb113b2680edf5183e9a42fd64bd7b29d0dc7797c583b833f869313699","up":true},{"one":"a08e47137bf611dfbd20308a22bdd3ca00121386f121d6d712ade86e9a1601a4237766887cd91c8516e20b6e323d2ef49c1c7e177a0afb4c813f0f344daf779b","other":"b3316f4fd7dec218a52331f25d17a2faf0f2a417808d7dbb80038154abfbcd2d78da074837b648cff28675f4aa0d65ddb7d15abf3d7e0391d401e313a3ef24a2","up":false},{"one":"7808fb798d22e78fb1d39b87ddf99a503f820993bc64149eca9e81d9d58fc1adea60d8de14a4f06cb89f3190c0ef0c5e182621a14c9361ccb7e0cee667599cc3","other":"f33d1f3e460574706ac1c7fc9ebb4683b173496ce3e80017d1c3521bca03d5a41a9c7a6cde8347d2238917b7cc58cab000ce7ccf6bb408561015a2ecbe613408","up":true},{"one":"beec648d79437a5d7b4140ced45d82d035c6f64f9c67c58386703811d97c3846787eaf274d2298df809475f0b7519df696563cb8e9a5fb0a9cc419ab13fa8d41","other":"7646d08b3e24183e3814de130235c41eb88a5a2abff23eaff3c91954ad3ef55fe27da422dac5b894312276bf1a2f1aebb8b636a8d4a0c93d9b016d441df3fa19","up":true},{"one":"f6ca39b3ad803e99f4e4e9cf759fff6abdf06e6972bdbe524f6eb930c669d6f0e9b91f3de9df394b0d661b068273861391bdbac948ad911351c48cf02f874db6","other":"81288bb0584b7ffc1546043e052e1df10fd5371b35dedd0bb42ec5b30ce69b741b2f7857af5984d4754b39d7253575fde9298504999b78380ef602d391c4bb1d","up":true},{"one":"0deda014fa3c0bc8f37d853e1448f95f56f97048c28797d72258fd3ba2f1f776ae11566197466596356cd172847ab02a89f4cf047e58383249fb2a4cd69b6206","other":"71f89efcf939294bb94ac669c8afd00def58c8dfad519c226adfa068692d588ef797116d42aa146b9d34f3be35ec7c014022640ab3c0f1f9034e44ab1a26e246","up":true},{"one":"2e409baefbd821485a151993356730e5989810d581e68190fbaa142799c9335bcf98310ad188fed10ae6eb6e2e789730393e509962ec5c0fef0342d72ed088d9","other":"2ac522ebfa49d37f86c6270ad4cdad0e766493f0e463b18c9906c70fbd2e5c6ff6b0d5879de6e3894418370636963a78b0c0cf087a8684c2ca30c9c736e49228","up":false},{"one":"8f88c7ec044f758f29bd8d12a5170bd973aec8f6cddbf512b910c4b75a0fec09c5e198bcd65622037f897759db68da2328b4a7ca93585dc9cb62e46d2a6c0864","other":"97981f4b825620985b746c85824d7a4d307ee25d60a72c2b7de4b1d4f3b1c002652adc3045842d350f849789e410a0357a0b42fa637a1b4fc9d39e44f8a674d7","up":true},{"one":"094f9d0fd3bacb17ac67a2edb8ed394fbbd1c8d478233d3269cf217e7b788e21042374936b885bf23ee4f9e03babbe4e08db283dfc2a6e052a8a5ba133717dd5","other":"4fe37f2dfb03707c90a6fe91dbcfd7497db70ffc20043091d50e1cee573210c144e8749340f2c3cb70fe8fc51b317d49e8734dc51ce64b3cdccdd639ae35d1ae","up":true},{"one":"b137cf2291b530a39516d882200848e7f27a2710e0839b4d25b4f367bea6a0c3aaef8c7c7851c00a2945adcd819ea0508610afc1f453b8bc512b7b4d4faacdf3","other":"b6a998dea59194cc60ce97c7c9702368411889cb6905516b23f41cc5116fba8d0f237d418318eb0c333cad18003c0e9a6bd8c99080520771f2bad640e2e5ec1c","up":true},{"one":"a99852c5bf08ea4713af9cade5343d1259bfb90401aca7fcff18c58cd56a98804dd16c61fea71039c0ac31b9bbbb9dc5aeaf0c2f074d3365e88d17031802d636","other":"c8b0dba45104fc7c7dff3ce078a0d3f5ade6198bb4656e2bee8076387929133e5ef2bd293b130a9d4f6a6974ca17e8b4a8f406d1219880f1e0f99c65c63af5a4","up":true},{"one":"58cfb20d3da3641e0ad529b9edbd4b590a8d1dc9d1ed7b44ed3187dba9260bd7c732fc10981f5b9bffd31d362cb05150173618aa36138984431d94a323a9b313","other":"329145e75496cecb5f5c8f00313a52ddd8c0e8cd27ef1b2bc1b2b56e4d4089aaf5a7a3c4d9a40bdb92483fa05bd24d1cd0fd51883e30439dffa0fc855e1a7cd0","up":true},{"one":"807340e5fdf6c21a56ef2fd158c32e92201206ca85fcc147165a408f7a735964afd47c397e663610ac53870ae722c0317291732b0422f8aeedae783d9c730218","other":"d3105ede6c21bc643d523afcd1309a5dcf03f70797a92f167c3a19f86ae98882fe1a9d4094d7a3dee4a0833b8075b6c3e9aaa7f4879dc47bb388c3ae85522288","up":true},{"one":"9c30ad8c85adc7bb52ddcfab2e661cc3a854a689eaa59128d35129d02cd5b0f8da4a44cdd33934a8e2c8fab1760c16d6f2e1c5eb227dc819e85624e63343c069","other":"df54af3bae257d437c5657905484e0d72e9560c46f8ba6b3437730234e05259b404cca40b0831e911605ff8a68a19e8fd7e958069ec8b40595928892f4fa220c","up":true},{"one":"617595a230e0a74a3db3b47cd27b941e02bdee9a84cdfa8eaa63a55941eb5caa79e20fb69726a4d46a0e5aeed24039f8c5a20679a692df0bc140f42558ca9a2b","other":"62dab8b21640e1b44dea452dd7e7de93f27a44840da72d56b11aa96e8463f3a4bb15e75a954d19fc897ae0030b16181d271b79d8198b7cffcddaa9ffcfdcce73","up":false},{"one":"6f60ef501b41f9049419b033ae8d793a18067bdcd60347537b0dc3873bdd9a2d10d24909cca7c39781765746128c2165596f6537a94f58279523faee71f9c51d","other":"485825745d97654cbb92a14e0cd1078691d3c28f4d82b1046284b676a42b44ca58eb43474e45e415d3bd3f3c383f9a1a3365821ed7ba6a9f2603b29d58031dc7","up":true},{"one":"c57ea182bdb42ba9b0870b5c870e467f52693e5c0df752fb6eb0dfbacce7763f73caee10db40f4fd90f19f504ee586eaf9da41f5ee93ee515d885fec99374116","other":"4b784f072b7c96c30612767425f552e30e45157e70139dfbe0ae4ff86dc31601adec60f8a3ad9747b02b5219073d8813af9b09d59eaf7ddb7ee24856aff6fa8f","up":true},{"one":"5526d86ba9df651091d88460a9bedb9cedb957d452a635e1db46b9fed78082022adec0047cd7485956a4ecbb0e18107595de0de3c35242527cd302bf74a19260","other":"f6ca39b3ad803e99f4e4e9cf759fff6abdf06e6972bdbe524f6eb930c669d6f0e9b91f3de9df394b0d661b068273861391bdbac948ad911351c48cf02f874db6","up":true},{"one":"e98a08e8e3544727f5ee27f4465375a67ffba490fcdbfe7bfdc909f6b68bd279f776c65d38c2ccfc33079f852f76349c94d68fc6989c0d981f22333f036a4bb5","other":"453779010ed7c59761da47ccd8869d3fa8349795e57edb9eea416c0712301ea622c7683858e309d19ab137ddb0edef161d0d00a361abeecf0628c3ffabc629ea","up":true},{"one":"8ca3b63cb84f1e9883d82809a9b6777ec1029ecda96fe93b4d494ee9cbefcad13f381b3e480136e542e01054fe1ede66c65db84a0009871ce49383db461c8438","other":"2f903b2fd4f9432b7d91b5c3e4c7ee3cb9c56fe7efc4baff0edd06fc75e4b7492f2c3c929755746df59c9f95d437a12ba40ac138d08f5bc7aa091f49f3b852c2","up":true},{"one":"9db1f94d74a00d1e5e2a391f1bcddf16b6d0670a2c6d91d946d38112c58634444b6fea8e8c05ab4b73bacdd62a0b575f6fb8729978edc216c7842b177b9f9cd9","other":"7b1e20217f594f87350542df31ff5ae8a635679bac7962d49c97e02190c644b673d03e7eba2626b45ca7ebf98d8a972dadbba02c18a8d2cbfc3e7a4cced5b4b7","up":true},{"one":"2f1967b4410ea2ea8fbaf46771ba82c2846d00aecdb6f873aceae33ab38f72d0a2c2dc6046d3034f514efd090d42011d48e9ab0cb4e3caa2b49a96ef732215a1","other":"7b5c0e81c7f4e3ae29d745f6028cfa10b29a16a9c261b65fb8dd05d6eccc634612ad5d3029c8e9f39863a2cdb2682c25f090139bf5c4950e25647e39dcb40e63","up":true},{"one":"66d0c5da973d9dd65350ae1ec63776872cdb7ded6afb6f51ae82259f6fd35e884375d15de290625f02ed2e5cdc3f591decb45e5fc64d5b0f835a216fd196f5a3","other":"420b9c90584651c5a3fe3c16aa377444a321dca934f8a097d01a616554067feabebf2fdc8d2a25797f29a8fef30d5e2c82f8e85b20f509a880367b9b0ccdea47","up":true},{"one":"ee36d1d5dd69fd30242d7da2e941b34ade5581c7164fcc43288ecfc52937a98f1b31ade5d1e4dbf611cbe1c7875b2840c89435081cde471c271d7bc60e9ef211","other":"7b35c856916eb3fc1b1f451667e240b95aff8f4731cc0f6743740923081ff1ddf2eec81bdccf4691a7bcc053d23eacfc15809c384a73448f618317bf605bd1cd","up":true},{"one":"3b570117addeec03c2694baf28e246f91907268fe665c6c90356120332794258ee57a60853c19e9fe25d042ca42a5be7fe0797d84199174de8132f1ef4a9349b","other":"66beee3968dbcf3addc6feaf070a4e3e82b5bb164fb72f40add89f732c12e8d0a31a7ee1f1e24a4674e4dfc9a4912b02c17ce3c224d257d78b7156544d6507dc","up":true},{"one":"9194a3a4c8f3235203e48bdb10902d958d26c342805ea6365af9711213536509719d917c694f9a4fbdde6889a4c92299a5301f0275bda4dbcd2541b5bff5b271","other":"b35f418c7935cc54278e90978c3ef1521ab91daeaf9f1ebc1cd25211611ade091cac4e1f009d71059279d507322a4536501980ac0dd44caddc52fd4c593879f7","up":true},{"one":"315b8a1711f680c2eaa607e35ef7a9e19c2b61721af8a7e08f1325dde1fe33cf1f47b3cc4acf12d541631041cf1b42754875fd1c9b66ee32797b72b9f7711256","other":"89a5b92a9ca045f12c35a70084e6f41f9775a25d6f105f8c9349c7b5e107179d8a96bdbb113b2680edf5183e9a42fd64bd7b29d0dc7797c583b833f869313699","up":true},{"one":"fe62314839c93d2f6e3aee984d5f0b321897c6f39e66800d3de8b773baf6f19e0a03cae025df512aea8d5f1b667b6dbb15c192a90a76d3031c14e33e5c16c4f7","other":"535f93057d46c4aae0902546550880be0b5ba67dca12350117d471d67f4f2b3f7bdff29bdc918767974c465df8fa1afa6bd6c29c0a36d51f71c4183673d906f3","up":true},{"one":"68cc8b9a995eef6170abf88bd5fedca06ffcc8d75f247f6041c13e7dfd292727ebda1ff86b776e33b6634355c55e0f8c22fcdb5f9a6e2f22fe1af7854c3b4273","other":"7808fb798d22e78fb1d39b87ddf99a503f820993bc64149eca9e81d9d58fc1adea60d8de14a4f06cb89f3190c0ef0c5e182621a14c9361ccb7e0cee667599cc3","up":true},{"one":"5eccdbcb15ef42dc96abcbcd8b8db75d9230de10e3c650620737f6cc04ba4fdbf59ded5daa801901c191be186c329ebcd37ba83bcf794064ad4e11bf10d3f775","other":"d7a319f69013b8375e64d19f015547462c84565b882337998f9e669c5fadd3d2ecf6374109903003e09f5d453424b5c7fdf52163d2cc8084cf81f94844946b63","up":true},{"one":"17a79cb279306b6bbd35219278f6bba03111079d6c4fadcd3c5e57b09678e111bda5f8e36ca3d223e51e255d6e857363b7741e438b32ec6e6c0dc1b224071081","other":"979838eaefcff456cf1cd9c47ea46854704f5757d8d7ab907019bc422b01af4d62252579bf045d143fab491b0bab823190e2782a457fbf51aa99ae17ec9e145f","up":true},{"one":"81288bb0584b7ffc1546043e052e1df10fd5371b35dedd0bb42ec5b30ce69b741b2f7857af5984d4754b39d7253575fde9298504999b78380ef602d391c4bb1d","other":"4e68553db7be307b8379e8bec383b5c92e4b23debcefca575d24504e2062618f74c26e60e0d9e47f096997a7f841e2c32c994124f495ef3352ef964b33fd3a51","up":true},{"one":"2b70e5ffcc0bb1c4f8acc09dd1016e67c9c96c92d091ad481efbb71bd8b2a5a5869c6d668617a9b2cbfe91baf5edfe150c3824c84d90899a974099071d171441","other":"e2a27dcdee1f89fa362a85c4397840cd8be4ad8d1b9ccb23188c303bcab7619f38772f71385922d090390973b62fb8249efc103f71bc761041bcb3880ec0b935","up":true},{"one":"c57ea182bdb42ba9b0870b5c870e467f52693e5c0df752fb6eb0dfbacce7763f73caee10db40f4fd90f19f504ee586eaf9da41f5ee93ee515d885fec99374116","other":"2bfba66ec9d63e928d77d455f2e10a14d6213e515099d5db14fa44a8bfc147eb0fa7afa9aaccdc86453c6903b55556059a2e13dd61fc494127d4a3ec173bf9ea","up":true},{"one":"083e67bb19e30d14e4df6d2483367d6659d9b56744d53d9cf7fd15954c327e1bc88a5d0db8833634e1dad7209164451f8934b59f76b5990059261abfd650519a","other":"baa5924e1547c177011285d292aa161a15e5ff282da2cd0afb83c9caffb07bdbb3662c227fa7b26e6dc8be9b8863e647eb5f8ce81640532f8f5c9a7f36557e63","up":true},{"one":"d4b7c787981abec24353c7d496661692233797e3758189bf909a69fe87935bf6da0940daa4f12e81f20c5e88f70b472113688b71a0ae2f91a73ee0e6ff4c8591","other":"9b59b76dc61223c7b37083b0ebdda22d3599563b3e3986f5db9d5b12f8c806cbdeb2345454efe957cbfa11eea9c7896aefd9a461210524805452ca100a9ea431","up":true},{"one":"855bdf057f4a6b095e2000ada199447b5b4f2f8d78d2ecbaa0ff1fbf761788870ee999266ad3b26efa02be1a46a4d92ac0debb85a2ceab3442394ee7d99e5355","other":"5bae82d4832092c17bd11474f7748015b8b69b896ab8f683a7c0024fc98740cecbb9e31c6275269f9000e5bfe51d7f45cd5dcd4433e0c87b5741685b40fe3983","up":true},{"one":"fe8ac5d33cd8ab6a1dad9567cdfb89b431a5c4f4a584fc608b92e7dfd06f70988e71e2f11f9fda9ee797c9ffba83bc085939fdf2522dde39f28202be92650566","other":"54b3c57a4adf4dbaf31b85ed1b8dccd6249faa16dd96dd230189f47f57970caeed36627cc8e1b0794707418d580f5bd6001c07be6a79216695f1253db24926bb","up":true},{"one":"a7507aa5665e165ab2e2a07def272f0677f9d6d35bb82268a34214384e7d8ef7635a299368752e63cfd02d4e60231076baf23cfa10d17492e55181b391ecf335","other":"d3105ede6c21bc643d523afcd1309a5dcf03f70797a92f167c3a19f86ae98882fe1a9d4094d7a3dee4a0833b8075b6c3e9aaa7f4879dc47bb388c3ae85522288","up":true},{"one":"deb7af800cd20a647335f0feff5bfb3e182f99f4c2d1ade10da36ecfdbac3b5fba4e8f0a4595443fe395b44af3a95617669850944655def85d57cc81c5682a3b","other":"eab86c521f8f1ac67c015ab713f1236a08b0200757a96bf87ab8301e7967ae62361f0e14da14ca294fc8cb3b4726b52f4773101e21b032977c6a647241b59c73","up":true},{"one":"3d2df188704eeac09c8b291bf275a73888199a231c832c51dbc3d746968d4b51a7d5eae0c7c9b8c8e19f5e28d38c375e01abefa343f31dbe221deb837ab8a0df","other":"1b063741c76fe65e62b4eae42751319d0cce66f22dde9f1cf83d6cca249a0e65bc7f6f22597697362fadd226222fb3847f8e146961969d1b4c9f7e475389cd8e","up":true},{"one":"bcf8e831821a5bca359fb824c7dc4d66906de82f3663a0a853d96880a8ca0bdddcceb1b66dd1f13f75ee20fde50fc9de545bc25767f228baee910e0dbfa8cc27","other":"759f46661056bcbb30c7706c9fb87e22a30feb523bd53ae5d18db043efa45b49a2b8982abebdd598fe0912a05896390ec2eabe5e160cbafc0771990708ad8c28","up":true},{"one":"4f5ab12b9c5127c16739ad0d4f51adce90ba6736cd096eb185ea632789f4b26f1ebabdea4fd3b39dda5409ece6c2d92fd469cf4aecf9d29453e3e042c19b893b","other":"6c143960dbe3ba4c95e8debc1fda5f420a2a673eb46f7ff7d9a30f4cd2067e67ef8926bf17f0c99b16c79b6dc066b52409a11d47117d4fda4211636b1b74f96c","up":true},{"one":"535f93057d46c4aae0902546550880be0b5ba67dca12350117d471d67f4f2b3f7bdff29bdc918767974c465df8fa1afa6bd6c29c0a36d51f71c4183673d906f3","other":"5420da16f7ed5de6b498dbc9a83b7e92e1f9900a6d04ef7351a0bfdfd442b98a5634f28fcea32ba3f3166d21c8ff5a39be70895b32acbdf7592d1d616a345a21","up":true},{"one":"92d6ef729992f0de886076e5f8cdc42cbbd70b29e79c25e0b3d22b6575d3d2508d47b42f581e335455483d43625bce4e55f88cab9ff2073ee8dab746357864fd","other":"485825745d97654cbb92a14e0cd1078691d3c28f4d82b1046284b676a42b44ca58eb43474e45e415d3bd3f3c383f9a1a3365821ed7ba6a9f2603b29d58031dc7","up":true},{"one":"eaca77d20c4ad6b87649eba21b750a4b1a2c575e06bc42679d18fce16fea15212e9a7408c16f3b24d8dfd1e397314637e72e292845d09534a39035bd9203ee9e","other":"4de378164d77a28c90cf162dd1b465e0282ee17aa7d3bb3179252466f72da33a36c9f298f7c9498e38dba4018e7ce3e5fe631c83842cd9059e23a7fece366d87","up":true},{"one":"e0f78c59a61f2a953553cd5742c58f4a82e38e35ac7eaa237a6ffc9fb0a3a26a2d1d1afae249e611d1320f2cb25804bdbdfb6d77336449716b0f4beb3298b8aa","other":"aa9a94d6e4eaaed20113c21752c224e3a052abd3769bd6e832759dbaf5154a943cf094eacdcb0727c2fe51a11bd7fc0793d7d5e3312b0aba89d428a00e1fde0c","up":true},{"one":"23f9bdc82efbf57d3d40a1f2617d0311678fb4a3d6a50cb7e608c649bb618124a76c7ffd17387de963e1cd28d2bd5a61c98613f6e009a8a2a90d989827b35de0","other":"7f357b8d81bc2e5c6fcb081f23a42b3e2439f050d45c45851994a268d1c71fcb1f39f8c3f75ce921d3fbf80fc0e73f0b9609d72001dc4a6b65b526d312a4f43a","up":true},{"one":"7f357b8d81bc2e5c6fcb081f23a42b3e2439f050d45c45851994a268d1c71fcb1f39f8c3f75ce921d3fbf80fc0e73f0b9609d72001dc4a6b65b526d312a4f43a","other":"cd8815d66aee8bd488d4e5e25f0cc9c71cc65349f701ea26b1d6cd9c039d16fcb473dbf270a3b33187720ccf4b0ce4f78a6d6edd05f4fe804772d5b6ec45bbd3","up":true},{"one":"27d9048707a89f1a61e44fdae523c0128f2a7050308bd3cfefa6c3e03040a0e22f11ab41275f22b8706e6695ab93320e2af35179d772581db5f49f960750f2f7","other":"4e95fb8943ef6502fa470870a7ace4ca11e18589bd2073167543a922317b35e40b5068934d07e56c8fdd23354dfad51fd2899db854f189841f02b5914cd97749","up":true},{"one":"1bc1d6155ba35d29ea16938994e08df76ebd8f16bd180bd6a9b9d8798d0745889fe72d641dd78bd8ec13526929f7eb5aaa6a388430fa69033d6db581e53c6422","other":"f915e2398aa5d4370de87504dd76c21a7d0be2581c2ab55b7a47743f1bbaef36384eaacec22760f1e914ceac9d96a10c3d66eb27475ef444e77fee979e6e88cb","up":true},{"one":"385168340139236a0e0f537fa693122db9fa02a377c96f31aae54718e92624fc0288164877e63616651565e055c53f7074ab2fdd18a837da6faf644941305bf0","other":"7acddc7fb6ac587b7e343804c768e4291cd28dd2b2b9207dea6ee82360d848a52d84f94e4c49e9c421f4f90e2d24f6291e2358783ab0230e6ecde82e69b4ac52","up":true},{"one":"8c6d77833bf1a98beabe7a92d985d13d52fb2e50768719ffbc6fce21ea676802a074b6e620b3ef80e12fad04f94a3c288d91df9716a6cfae09ef073b9dc1f2cb","other":"9bbbfac8be4a000f51a4ce8d024d2595b5d491afec0138922dddfde5ef62c664040c2e9304cc6b7bc688233b5d0c4644b8c8793227c078285a3ab894ef0497a3","up":true},{"one":"453779010ed7c59761da47ccd8869d3fa8349795e57edb9eea416c0712301ea622c7683858e309d19ab137ddb0edef161d0d00a361abeecf0628c3ffabc629ea","other":"f915e2398aa5d4370de87504dd76c21a7d0be2581c2ab55b7a47743f1bbaef36384eaacec22760f1e914ceac9d96a10c3d66eb27475ef444e77fee979e6e88cb","up":true},{"one":"c83985973a9564ade7d90aa54911ac57077600676a1d27292d98e058bf1315887bad84ccd708cb7f52a695a1405fb7d491d7ca2ae9caa3ff58a5ad78ce4dc9d9","other":"4b784f072b7c96c30612767425f552e30e45157e70139dfbe0ae4ff86dc31601adec60f8a3ad9747b02b5219073d8813af9b09d59eaf7ddb7ee24856aff6fa8f","up":true},{"one":"df4c3505e09e1baa88470117b964e758c94f77a4546489ab5ab7f4aebfdce424729ace8867475715fb68f05c66c9674a5767549e266c4fadd1c703ddd735908f","other":"70ee3c7e02a123f78345d41c386e413f06b51f1ab346c2c472891eed7dd26a1f14e213a0f4f2d872859b9b535936a6d9b072d2604456f76221a422710411822f","up":true},{"one":"fd4968df03d767a223bf7e4dbe26b5c27048298df40e81cad50b344fb3e6837965f2646dab7ffb2891a5c507343ed84bb8bbe403287b51dae538d58fcb6e7623","other":"c73d088ade8756c74832c73542bcdb3e52f670f7a74ad3a7eac2a9e3ece6bd081f782a8e1d3f9a40b9aa9201509110f37fc57fcb10ee1ef3ef07b7eab019782e","up":true},{"one":"5dc69635f6d573c824ea83b18593a47f9f21a6f91ce18d2bf977c97d21f8d2a8ce88829244d12a07d949bbd52fe8a2035bc89685fe1bdd4ee20d766d75d3deee","other":"2ac93c31937ca205d61cc5c2a1b9037871cac55e9b306b999b28e19566b3316f6539455e014840ea50c2db8a7c97d78804d3a2dcd7cd9c1f32ace0d36e5dd339","up":true},{"one":"7808fb798d22e78fb1d39b87ddf99a503f820993bc64149eca9e81d9d58fc1adea60d8de14a4f06cb89f3190c0ef0c5e182621a14c9361ccb7e0cee667599cc3","other":"f6ca39b3ad803e99f4e4e9cf759fff6abdf06e6972bdbe524f6eb930c669d6f0e9b91f3de9df394b0d661b068273861391bdbac948ad911351c48cf02f874db6","up":true},{"one":"352407b42726dcd1aacc46a912ed8124b8b6a3da4e33dab742e40aa2452953d35dc8f42eddc76695ae2317e9f15dde2cd21be4ce826934695ad1847455661d1b","other":"5526d86ba9df651091d88460a9bedb9cedb957d452a635e1db46b9fed78082022adec0047cd7485956a4ecbb0e18107595de0de3c35242527cd302bf74a19260","up":true},{"one":"855bdf057f4a6b095e2000ada199447b5b4f2f8d78d2ecbaa0ff1fbf761788870ee999266ad3b26efa02be1a46a4d92ac0debb85a2ceab3442394ee7d99e5355","other":"b080891d4ba6d3ab224984360597f9c555bd1367630f5420bfaf230419a05b2be58bebf1554e53eb4c0da81cfb66d4f7697dd65143f11841ff62d8a0d82b6b67","up":true},{"one":"1f6d803a4ca186463772850ca0901fb920af7e74fdd2480c3c368fa707838ee91bbcfb57d5e3510c802b9b85f2d954f04c9b675414274bdaebae6488dcf94c10","other":"a7378ee34876af17c6cd94a69b6b741ec7891ff5375bc4241d48608d047455ed48e6baae80ee88d4710c69ae615cf195cee26c94b54de1bb935628ce1e3a723a","up":true},{"one":"0deda014fa3c0bc8f37d853e1448f95f56f97048c28797d72258fd3ba2f1f776ae11566197466596356cd172847ab02a89f4cf047e58383249fb2a4cd69b6206","other":"0a4eec7b0e05da799aca5b36d9e2530f2a89d1426b1fcb7d8f9a662df8a8b5b763767a20db3c9c63e0bd13c2a6e16d3ba8f03baf84f5e5d24917b3f211d9bcfc","up":true},{"one":"2e409baefbd821485a151993356730e5989810d581e68190fbaa142799c9335bcf98310ad188fed10ae6eb6e2e789730393e509962ec5c0fef0342d72ed088d9","other":"beec648d79437a5d7b4140ced45d82d035c6f64f9c67c58386703811d97c3846787eaf274d2298df809475f0b7519df696563cb8e9a5fb0a9cc419ab13fa8d41","up":true},{"one":"094f9d0fd3bacb17ac67a2edb8ed394fbbd1c8d478233d3269cf217e7b788e21042374936b885bf23ee4f9e03babbe4e08db283dfc2a6e052a8a5ba133717dd5","other":"b53078000796f1cdb04dfeac424d5e3e37e30f00bd5bebf9a9ea0525c62917612b3a8f508df6bea59e3c7e4cd1aa530841f9a8af54e44f5617a13dee2c6ff007","up":true},{"one":"ee36d1d5dd69fd30242d7da2e941b34ade5581c7164fcc43288ecfc52937a98f1b31ade5d1e4dbf611cbe1c7875b2840c89435081cde471c271d7bc60e9ef211","other":"72e30d4562673c5c8fb03709d93f73322747858d723b7eb5ef2fbb88e0331252946b7e93ffe434fcb599c4fff57800afb29e6c60a719f18f49dba541c3591c6e","up":true},{"one":"a99852c5bf08ea4713af9cade5343d1259bfb90401aca7fcff18c58cd56a98804dd16c61fea71039c0ac31b9bbbb9dc5aeaf0c2f074d3365e88d17031802d636","other":"b4a5efa9028b2d196855393892f79993c2812d02b758f98813ddf82c5d943faf6d66eff811cc5a51936c118f4c768c0d13b54902095e040c602761e63c08655e","up":true},{"one":"65e954e60837bda10654480b227fa3bcc6e63356c52079002a27e836cd82ae2934ba77da60080e4b9f2d9324b982b24959bfd9624302e6c330408381054b43e9","other":"a78f18691e0dbf3c08fe9d7dec188e6a05a93833432fb99eb2b3924ab0bde7a44db2a102a65544bbdc4fb61bc3a3d569230d9843a335bf619167fb045d78ab3c","up":true},{"one":"396c703d27bfdddf91761f134cbf665fe61e0b3a5d24036a4105a625f72e8c28b821e9200f20d6e8f8b3ed6b95bda6b8accdd840c2f786720b7431e3af2af981","other":"db8ba71afeaea1f2964e8978a6eceeb9efa3958424424022213c8193443f8d5afd18490afa954c76360c681404809c7cfaf7e4ebd8bd1a42d403f7f1915b0d29","up":true},{"one":"9c30ad8c85adc7bb52ddcfab2e661cc3a854a689eaa59128d35129d02cd5b0f8da4a44cdd33934a8e2c8fab1760c16d6f2e1c5eb227dc819e85624e63343c069","other":"7865b82e44add2cea6ebcbaba9c152184331a2940fe73f6f9bb940bda8a59ab4cf4760894b9cadcaa54e36fbb712ad619346a49a85e32cdf2b53cda1ac1e0658","up":true},{"one":"cb94a8270d0050378116b5815ff17dafbe20f5303839c4fd57b981d4687a4b145e4bccec7e9af9b9475005930148ffbfa97781a0762c8e9f352dc95565fc8732","other":"663535b22018a4ef0b151572ef286fa66c22c6e9b2913a69c4a735d4b0149bdf6c84bd83d710f8aa2627e8993b7f020750fbc6f56a3365ce4c840e2b3de1a6c1","up":true},{"one":"b137cf2291b530a39516d882200848e7f27a2710e0839b4d25b4f367bea6a0c3aaef8c7c7851c00a2945adcd819ea0508610afc1f453b8bc512b7b4d4faacdf3","other":"c903c5ee3d9cd65bea3ea777e39282c33e1349d945411fb2f16321bf582c2f400956a98fbafe5873fc5f6f6a9a051df5da7e94cbd340f935abe80f91e79ef875","up":true},{"one":"e267e71c2dcdbe5a500b23444d2d4037ea15afba8f4f2b1c0e54a274450404fbee6fa5439f7cddf4ba1aa28fa93e434b01c239add58e30a5423ca3a481584d6b","other":"cb94a8270d0050378116b5815ff17dafbe20f5303839c4fd57b981d4687a4b145e4bccec7e9af9b9475005930148ffbfa97781a0762c8e9f352dc95565fc8732","up":false},{"one":"b3316f4fd7dec218a52331f25d17a2faf0f2a417808d7dbb80038154abfbcd2d78da074837b648cff28675f4aa0d65ddb7d15abf3d7e0391d401e313a3ef24a2","other":"cb94a8270d0050378116b5815ff17dafbe20f5303839c4fd57b981d4687a4b145e4bccec7e9af9b9475005930148ffbfa97781a0762c8e9f352dc95565fc8732","up":true},{"one":"5566111b7f14d8ec83ba6456488f3fc5c7e2c86bf406dead33b814e1ee9b569d34015a4d88226b7e28fff7784395c086d106287cbbc80acfe75b05cd6e12903d","other":"396c703d27bfdddf91761f134cbf665fe61e0b3a5d24036a4105a625f72e8c28b821e9200f20d6e8f8b3ed6b95bda6b8accdd840c2f786720b7431e3af2af981","up":true},{"one":"27d9048707a89f1a61e44fdae523c0128f2a7050308bd3cfefa6c3e03040a0e22f11ab41275f22b8706e6695ab93320e2af35179d772581db5f49f960750f2f7","other":"2b70e5ffcc0bb1c4f8acc09dd1016e67c9c96c92d091ad481efbb71bd8b2a5a5869c6d668617a9b2cbfe91baf5edfe150c3824c84d90899a974099071d171441","up":true},{"one":"016f8f4619a16a07fbde5a18e362158d696e4d9f104a77787f26e32a25cd7d278256f8e0db865c488a99511ec27a5eddd5ebbd1c1397fa7f8db111062e5fe959","other":"1944f98d4db32c56a5efda5a79aa5f276bfab1e084d6611fec0e735b8bc0f45b457cdb74a23fc83b2377821fa8316123c9877acd6db7c41058ca5d3cfedaecf9","up":true},{"one":"1c2f7ce55a6e38487f3b3fe6083a79f914cd6d7e4aee8f5d56b4a61b3eb584e128c56998db0e13e775edee3adacf54f09960a041dab3daa80a4f8a3b42760c1c","other":"453779010ed7c59761da47ccd8869d3fa8349795e57edb9eea416c0712301ea622c7683858e309d19ab137ddb0edef161d0d00a361abeecf0628c3ffabc629ea","up":true},{"one":"420b9c90584651c5a3fe3c16aa377444a321dca934f8a097d01a616554067feabebf2fdc8d2a25797f29a8fef30d5e2c82f8e85b20f509a880367b9b0ccdea47","other":"57fb1bb32bb2b1a87e44c6a7557e9c47c2032d107bcb0e34acd9ffd54d5d3df5701232db16f62f7549ba2721021898b03160b1dc5201e79606648c1dbc4a373b","up":true},{"one":"9db1f94d74a00d1e5e2a391f1bcddf16b6d0670a2c6d91d946d38112c58634444b6fea8e8c05ab4b73bacdd62a0b575f6fb8729978edc216c7842b177b9f9cd9","other":"4ff66e9b5d3fd345990bd7605bdc222b78946f0c13b72bf80352812b2426d8f1d36c93e6c8713566004615e8a78ecab12ab0cfba254c0967eeecf8875b25bdae","up":true},{"one":"ae2a996d3b562cb47a564934037949da83b1bfe194c23754f3dbe2372ec27654f4f3b6cb7f394570f308025589c065870477667e5560dbe5a8ea1625740699cf","other":"58cfb20d3da3641e0ad529b9edbd4b590a8d1dc9d1ed7b44ed3187dba9260bd7c732fc10981f5b9bffd31d362cb05150173618aa36138984431d94a323a9b313","up":true},{"one":"f33d1f3e460574706ac1c7fc9ebb4683b173496ce3e80017d1c3521bca03d5a41a9c7a6cde8347d2238917b7cc58cab000ce7ccf6bb408561015a2ecbe613408","other":"3d2df188704eeac09c8b291bf275a73888199a231c832c51dbc3d746968d4b51a7d5eae0c7c9b8c8e19f5e28d38c375e01abefa343f31dbe221deb837ab8a0df","up":true},{"one":"e023a51c5bd26e1754d6461345143e94baeac799947579ec7adeccd105de39f85afbceeb5037cfc0b820b9f4446433f034d9e7de7326d45df5a967a8099dbb10","other":"6bf9fb6a25521c16c2ebeb6203d046d7dd40f29cc2ddb067c0222ef56d7012d2ee5d037f71f6668ea56767610b2a54c144aed74b7f68d06993cbd52fa1dc7630","up":true},{"one":"7b1e20217f594f87350542df31ff5ae8a635679bac7962d49c97e02190c644b673d03e7eba2626b45ca7ebf98d8a972dadbba02c18a8d2cbfc3e7a4cced5b4b7","other":"c903c5ee3d9cd65bea3ea777e39282c33e1349d945411fb2f16321bf582c2f400956a98fbafe5873fc5f6f6a9a051df5da7e94cbd340f935abe80f91e79ef875","up":true},{"one":"ce0a09bb6fe4c9c93c3dbd800ca9c9ac0714f26a8f8dac2149b6ce7a9011912a5621ea2e45de35c4d31dfe5add00558fdba5dd21acf2d81ba391e82b5b3a5804","other":"2f1967b4410ea2ea8fbaf46771ba82c2846d00aecdb6f873aceae33ab38f72d0a2c2dc6046d3034f514efd090d42011d48e9ab0cb4e3caa2b49a96ef732215a1","up":true},{"one":"66d0c5da973d9dd65350ae1ec63776872cdb7ded6afb6f51ae82259f6fd35e884375d15de290625f02ed2e5cdc3f591decb45e5fc64d5b0f835a216fd196f5a3","other":"07f25fdeab2b44b2e92fc80fca7de9e4a8547d27a98a54593b3395c270a9ff3f2a5da62a2e8531ce86359f0cdc5b6513b773dfd64cce1b83e47065d9760a2c7e","up":true},{"one":"24662a43944228e4ff74736bcf0a0a4f79c87ecfdb739225b2fc45110c11bfc38aaf2d09d98e5817477848e553f187ac5408bdb864518dfa7f5df542768828db","other":"caaf695c76cf7c047d3f3bfe019d01618e4871cee8ff3f347913da815bbcde145771486f916a44d03f59ea9bc217f169fd0c0765fda3f9b9b28d02a522e180b4","up":true},{"one":"b597c9ba4da20c49fc4ba019571321d2579588636cdaceb9f225706574970adbf4771dcf186b1decd4e14cd5d257e30a36ca829829598c1775902201ad9793e2","other":"a78f18691e0dbf3c08fe9d7dec188e6a05a93833432fb99eb2b3924ab0bde7a44db2a102a65544bbdc4fb61bc3a3d569230d9843a335bf619167fb045d78ab3c","up":true},{"one":"8d4920d6e3a6717699b5a3af068cbdfc16858d7e393d158d41b1b5f345b47129eef89e1d055386c518f400b134678c21590f0317dea3436d4cef60f45455cf12","other":"2e42f845d0393d1682add54ee30b60a953ed283e75d347bc6719ae0e91f6676282e7960f1fd52e5803d6b341fb3582c724b4f9cfd7bce9ce85f13ca480c7e72e","up":true},{"one":"6b4e376e9c94242b6d42688c22aa9ab418cb6dfb1cbca1c69de0feceec8d3af29fb005017aaa6e503cc0c03cf0dc5bcab55e01cd6f64b9efa02ed87c03020003","other":"9c30ad8c85adc7bb52ddcfab2e661cc3a854a689eaa59128d35129d02cd5b0f8da4a44cdd33934a8e2c8fab1760c16d6f2e1c5eb227dc819e85624e63343c069","up":true},{"one":"17a79cb279306b6bbd35219278f6bba03111079d6c4fadcd3c5e57b09678e111bda5f8e36ca3d223e51e255d6e857363b7741e438b32ec6e6c0dc1b224071081","other":"3d2df188704eeac09c8b291bf275a73888199a231c832c51dbc3d746968d4b51a7d5eae0c7c9b8c8e19f5e28d38c375e01abefa343f31dbe221deb837ab8a0df","up":true},{"one":"81288bb0584b7ffc1546043e052e1df10fd5371b35dedd0bb42ec5b30ce69b741b2f7857af5984d4754b39d7253575fde9298504999b78380ef602d391c4bb1d","other":"eaca77d20c4ad6b87649eba21b750a4b1a2c575e06bc42679d18fce16fea15212e9a7408c16f3b24d8dfd1e397314637e72e292845d09534a39035bd9203ee9e","up":false},{"one":"7ac5b07eb555af3bb4ca3f0f4b45204d43cc3798c244435909b97d9a32fc3abf0b50666e260e046bce826a7a102a92d389f8f39c5311e83bb34beddac29d50e3","other":"beec648d79437a5d7b4140ced45d82d035c6f64f9c67c58386703811d97c3846787eaf274d2298df809475f0b7519df696563cb8e9a5fb0a9cc419ab13fa8d41","up":true},{"one":"ae4e21e1587a8475afd299e00ca7085c7bf2a44c2c64a3068f12223d9202b0125094385319034691ec26b497ec9cf18fe8c0839224bac1b84279410241cef979","other":"1b6cad4f9851cc584c5d1405f976bb51a52e27ef4525847df543dcca65ca5eb1ef229dcc68ccbaaf00ab1e044cb5990dd213c805bdb4adcceb6fa70b5c61fdb4","up":true},{"one":"4ff66e9b5d3fd345990bd7605bdc222b78946f0c13b72bf80352812b2426d8f1d36c93e6c8713566004615e8a78ecab12ab0cfba254c0967eeecf8875b25bdae","other":"9c30ad8c85adc7bb52ddcfab2e661cc3a854a689eaa59128d35129d02cd5b0f8da4a44cdd33934a8e2c8fab1760c16d6f2e1c5eb227dc819e85624e63343c069","up":true},{"one":"9bd4f0adb9a966cc5ba632f1b540fe9cd6c8e39fe1a041b315697679cfb04b735952062ce057d456677cc34a84301f26bb727a4ab2646fee734f80a22c620746","other":"9c30ad8c85adc7bb52ddcfab2e661cc3a854a689eaa59128d35129d02cd5b0f8da4a44cdd33934a8e2c8fab1760c16d6f2e1c5eb227dc819e85624e63343c069","up":true},{"one":"2b70e5ffcc0bb1c4f8acc09dd1016e67c9c96c92d091ad481efbb71bd8b2a5a5869c6d668617a9b2cbfe91baf5edfe150c3824c84d90899a974099071d171441","other":"2f903b2fd4f9432b7d91b5c3e4c7ee3cb9c56fe7efc4baff0edd06fc75e4b7492f2c3c929755746df59c9f95d437a12ba40ac138d08f5bc7aa091f49f3b852c2","up":true},{"one":"fde7705f5013c3b6b76a35505c1e3d57c033a337f2a71e912ec3a3d2da8e113bd7c36d94908357e9f7654660621f647ad8c66b0126dfe91dbfa3b8c7bd2183d3","other":"4a030ebcb1a59230759d25a3c87daed22906b520d55a78eab2083bb52358ddc3a5d2d7c3265e6c54a990bf32d0dacb85905a4173d72ac18fcd74c43ecb8635c5","up":true},{"one":"d4b7c787981abec24353c7d496661692233797e3758189bf909a69fe87935bf6da0940daa4f12e81f20c5e88f70b472113688b71a0ae2f91a73ee0e6ff4c8591","other":"9b618ad34d0dfe0fccbd5b8af365cbcdbb43e802df5f23e91c20d21f3ead6169d52bf0db7e5e111abef630c9853419fb33a88cf111d8507b8708208b5d65e35e","up":true},{"one":"fe8ac5d33cd8ab6a1dad9567cdfb89b431a5c4f4a584fc608b92e7dfd06f70988e71e2f11f9fda9ee797c9ffba83bc085939fdf2522dde39f28202be92650566","other":"0b30b36e155db04c448b662c4df695068b2331cdbe2772aae5fda84159e977515a5ff2e156bc225a9281fef2383926ba8cb11e9c1846fb40db241e524ac14e29","up":true},{"one":"663535b22018a4ef0b151572ef286fa66c22c6e9b2913a69c4a735d4b0149bdf6c84bd83d710f8aa2627e8993b7f020750fbc6f56a3365ce4c840e2b3de1a6c1","other":"b2538d4edfa736bfe2cc21326a44ce62f716b3480eac93584a2233b69c98883a2bb255f246218a58cecab1d0d176e6d1fbba9782fd70d4603e01742299b9ea9c","up":true},{"one":"ff1e34fd51953ed641b431aa657da21cb4c81d23e4eaa13c9cce526f1f1b34593d41f9b87a0e10387fe400c623638677c0efab15dbd1014a0ccc11f9ec92c417","other":"b2538d4edfa736bfe2cc21326a44ce62f716b3480eac93584a2233b69c98883a2bb255f246218a58cecab1d0d176e6d1fbba9782fd70d4603e01742299b9ea9c","up":true},{"one":"df54af3bae257d437c5657905484e0d72e9560c46f8ba6b3437730234e05259b404cca40b0831e911605ff8a68a19e8fd7e958069ec8b40595928892f4fa220c","other":"66d0c5da973d9dd65350ae1ec63776872cdb7ded6afb6f51ae82259f6fd35e884375d15de290625f02ed2e5cdc3f591decb45e5fc64d5b0f835a216fd196f5a3","up":true},{"one":"e0f78c59a61f2a953553cd5742c58f4a82e38e35ac7eaa237a6ffc9fb0a3a26a2d1d1afae249e611d1320f2cb25804bdbdfb6d77336449716b0f4beb3298b8aa","other":"f9ffe87c52ff4c22bd9696af32e0a9d34bb81fb84d9d8bf5aafe2ef9696e7b3d6460bf2a93aecb066133f53416bde841a02d6967bd06e3d4a714f3b2c123a947","up":true},{"one":"70ee3c7e02a123f78345d41c386e413f06b51f1ab346c2c472891eed7dd26a1f14e213a0f4f2d872859b9b535936a6d9b072d2604456f76221a422710411822f","other":"b870935867183bbfb84add16b9f56c02c834b7042fc24ce6bcb2a7f174e6d2239357a00be4272c1ef05c7f9baf5a9f16b53bc18328a9b7aca8540c2916805b57","up":true},{"one":"6f60ef501b41f9049419b033ae8d793a18067bdcd60347537b0dc3873bdd9a2d10d24909cca7c39781765746128c2165596f6537a94f58279523faee71f9c51d","other":"ddaf3f8478501cda872c056c72063eb64d5b871fc5fff70704872802289dd2d348f73bc342b7f148a90cfaae2448ebf16fea196be9df891dc71a57fb410d59dd","up":false},{"one":"68cc8b9a995eef6170abf88bd5fedca06ffcc8d75f247f6041c13e7dfd292727ebda1ff86b776e33b6634355c55e0f8c22fcdb5f9a6e2f22fe1af7854c3b4273","other":"2ac93c31937ca205d61cc5c2a1b9037871cac55e9b306b999b28e19566b3316f6539455e014840ea50c2db8a7c97d78804d3a2dcd7cd9c1f32ace0d36e5dd339","up":true},{"one":"5eccdbcb15ef42dc96abcbcd8b8db75d9230de10e3c650620737f6cc04ba4fdbf59ded5daa801901c191be186c329ebcd37ba83bcf794064ad4e11bf10d3f775","other":"94088fe273f76e62ca4e43c095ad12215b4ae4c59942328b3985416fb19bbda0cacc143a49eff3fb644ad53a19d3f043260e43dbb70a0aa9c15829c21cecd3c7","up":true},{"one":"385168340139236a0e0f537fa693122db9fa02a377c96f31aae54718e92624fc0288164877e63616651565e055c53f7074ab2fdd18a837da6faf644941305bf0","other":"60725e8d0e9333636e598dd666f459b4be898d9abc095ee2c1db289673e7e969b50e2093956fef5a2f1d23e2040159bbabaaeab17fc6dbbac3f6acab766e9e60","up":true},{"one":"b080891d4ba6d3ab224984360597f9c555bd1367630f5420bfaf230419a05b2be58bebf1554e53eb4c0da81cfb66d4f7697dd65143f11841ff62d8a0d82b6b67","other":"9b59b76dc61223c7b37083b0ebdda22d3599563b3e3986f5db9d5b12f8c806cbdeb2345454efe957cbfa11eea9c7896aefd9a461210524805452ca100a9ea431","up":true},{"one":"ae2a996d3b562cb47a564934037949da83b1bfe194c23754f3dbe2372ec27654f4f3b6cb7f394570f308025589c065870477667e5560dbe5a8ea1625740699cf","other":"4ee37acec2178ef120166265aaa2b64b09b315fb53861405ef46f2503c273eb9692e9cb4c2e67a8652254d430fd6e02dd3fe4cded20bb231a9fb834d292b0b24","up":true},{"one":"732393b99c490c76fa45e3e404ee095f2fa445fcc123af7ac8ab1d2fdd7cf2483f5b82bb818bd8a82b1a3b73e63bcc2c83d8f24d9aad9afe36503735e7967be7","other":"3612863ce0456c91785a829bf5c9d2b2fb97dda083a1847e5a4ebaa6fce1260faf4d1eb374c2225431a82774163835fb59c8cb0fa9fc0969eab5410c71109cc2","up":true},{"one":"c332fe1f9b6e25f72c7150631ffa6e0929ff6eeab5d17aa45eaf669bdde869cf404505ae990a529aa3ca797cd0a96f31cc41431a5d4a163132be566f91623c08","other":"cb321c9b0fe2eb3617b8e2461aab170a9dad2c9b04a10eead4e37e551197ea0a7500eb1cb7b155efe1886486ef3d252d8ff0d309f2906a1126ca011d037da70a","up":true},{"one":"6b01079463ec2f649db8634cb7a596261c79a8f714d954c772528e0547b017f8ce405e4a0ea9d32270848180e0f77b8c0b022cf95c85e777626edd4d24ea21d2","other":"0b30b36e155db04c448b662c4df695068b2331cdbe2772aae5fda84159e977515a5ff2e156bc225a9281fef2383926ba8cb11e9c1846fb40db241e524ac14e29","up":true},{"one":"e023a51c5bd26e1754d6461345143e94baeac799947579ec7adeccd105de39f85afbceeb5037cfc0b820b9f4446433f034d9e7de7326d45df5a967a8099dbb10","other":"5526d86ba9df651091d88460a9bedb9cedb957d452a635e1db46b9fed78082022adec0047cd7485956a4ecbb0e18107595de0de3c35242527cd302bf74a19260","up":true},{"one":"df4c3505e09e1baa88470117b964e758c94f77a4546489ab5ab7f4aebfdce424729ace8867475715fb68f05c66c9674a5767549e266c4fadd1c703ddd735908f","other":"57cd4c0048b459192ee46e19ec7df777e600f256e0dc8c3019431eb7bec3c020b9504ec7aea3dba8188658ca5b830ec40af6a8540ce10e04badc6c695d009271","up":true},{"one":"5dc69635f6d573c824ea83b18593a47f9f21a6f91ce18d2bf977c97d21f8d2a8ce88829244d12a07d949bbd52fe8a2035bc89685fe1bdd4ee20d766d75d3deee","other":"e2e0419a41bdfc5bd76deae2ddce6ac865f886d764c9bd18799b79fa3b2b6ba66d765d26da2037e98317e1d7e8232a61e63c1d0cfa98c9137424151b46e07171","up":true},{"one":"7808fb798d22e78fb1d39b87ddf99a503f820993bc64149eca9e81d9d58fc1adea60d8de14a4f06cb89f3190c0ef0c5e182621a14c9361ccb7e0cee667599cc3","other":"0cacda5560faff9d20e29a0625d3cd340ec075f198a50ab8b79338cee0e0db84c7c7e71042fd8c8f73e507b570de5d26c39473136b575f0167625a1168309ec5","up":true},{"one":"352407b42726dcd1aacc46a912ed8124b8b6a3da4e33dab742e40aa2452953d35dc8f42eddc76695ae2317e9f15dde2cd21be4ce826934695ad1847455661d1b","other":"e023a51c5bd26e1754d6461345143e94baeac799947579ec7adeccd105de39f85afbceeb5037cfc0b820b9f4446433f034d9e7de7326d45df5a967a8099dbb10","up":true},{"one":"1d0244a13affe60996fe3cf51ba624adc746de0c7ea68ec5a31311a36077c5b5495e3d95c9642875db44c7ecae6ffed22e45f2e2d024d486760be2af9f4cf2cd","other":"22010c9829626a6892258b09cb3f3edc3f21382fb487b5dbf0dd20e198e37e26134aab850e30337f398d1491b5126839aeb1953ec144bc19aeb889c832f67c6a","up":true},{"one":"bf4ff51cc3d9a9d8cefd7e346ce1384d06450228a6086fe12fb0c60fec54bb6478f090bb638fbdbf8f41f7bc6420cd8a5c8b1b8566229b6851167375ef412f46","other":"53df9cce9b0169e58ced53a123d1d8f6e8fdcfb4c2d781ecbb91bb7c8eba36946dd9d21c749259769825d8a6b3faa6bb87c8c6085a522f8a3e376061f59144d9","up":true},{"one":"1f6d803a4ca186463772850ca0901fb920af7e74fdd2480c3c368fa707838ee91bbcfb57d5e3510c802b9b85f2d954f04c9b675414274bdaebae6488dcf94c10","other":"155e4879643a472420012e040a87dbff776fc1976814c0c6cd0d5e157f0d0baac04aa7f2535786c09acc2700547383d2119b64a6f62115f1aff1708738844d8c","up":true},{"one":"3d2df188704eeac09c8b291bf275a73888199a231c832c51dbc3d746968d4b51a7d5eae0c7c9b8c8e19f5e28d38c375e01abefa343f31dbe221deb837ab8a0df","other":"759f46661056bcbb30c7706c9fb87e22a30feb523bd53ae5d18db043efa45b49a2b8982abebdd598fe0912a05896390ec2eabe5e160cbafc0771990708ad8c28","up":true},{"one":"bcf8e831821a5bca359fb824c7dc4d66906de82f3663a0a853d96880a8ca0bdddcceb1b66dd1f13f75ee20fde50fc9de545bc25767f228baee910e0dbfa8cc27","other":"1b063741c76fe65e62b4eae42751319d0cce66f22dde9f1cf83d6cca249a0e65bc7f6f22597697362fadd226222fb3847f8e146961969d1b4c9f7e475389cd8e","up":true},{"one":"535f93057d46c4aae0902546550880be0b5ba67dca12350117d471d67f4f2b3f7bdff29bdc918767974c465df8fa1afa6bd6c29c0a36d51f71c4183673d906f3","other":"b4a5efa9028b2d196855393892f79993c2812d02b758f98813ddf82c5d943faf6d66eff811cc5a51936c118f4c768c0d13b54902095e040c602761e63c08655e","up":true},{"one":"a99852c5bf08ea4713af9cade5343d1259bfb90401aca7fcff18c58cd56a98804dd16c61fea71039c0ac31b9bbbb9dc5aeaf0c2f074d3365e88d17031802d636","other":"e67e495385e7cacfe659b40d1ba94d4b1ff55eada70a4d9740a9e452fbf221672bd0a897b940e2a6bed71e2a16867fe45bf0ea0015435ac6d815690e263b1899","up":true},{"one":"ee36d1d5dd69fd30242d7da2e941b34ade5581c7164fcc43288ecfc52937a98f1b31ade5d1e4dbf611cbe1c7875b2840c89435081cde471c271d7bc60e9ef211","other":"4a030ebcb1a59230759d25a3c87daed22906b520d55a78eab2083bb52358ddc3a5d2d7c3265e6c54a990bf32d0dacb85905a4173d72ac18fcd74c43ecb8635c5","up":true},{"one":"2ac522ebfa49d37f86c6270ad4cdad0e766493f0e463b18c9906c70fbd2e5c6ff6b0d5879de6e3894418370636963a78b0c0cf087a8684c2ca30c9c736e49228","other":"53df9cce9b0169e58ced53a123d1d8f6e8fdcfb4c2d781ecbb91bb7c8eba36946dd9d21c749259769825d8a6b3faa6bb87c8c6085a522f8a3e376061f59144d9","up":true},{"one":"396c703d27bfdddf91761f134cbf665fe61e0b3a5d24036a4105a625f72e8c28b821e9200f20d6e8f8b3ed6b95bda6b8accdd840c2f786720b7431e3af2af981","other":"66beee3968dbcf3addc6feaf070a4e3e82b5bb164fb72f40add89f732c12e8d0a31a7ee1f1e24a4674e4dfc9a4912b02c17ce3c224d257d78b7156544d6507dc","up":true},{"one":"7865b82e44add2cea6ebcbaba9c152184331a2940fe73f6f9bb940bda8a59ab4cf4760894b9cadcaa54e36fbb712ad619346a49a85e32cdf2b53cda1ac1e0658","other":"ea57884dd42aec5a76eab43483bf7c4ae2c19eebf365013731de64494d10a3b4cfe34c86c79437f9012bc8cf6bd761435eefadec17600f4b9e4bc234532d6282","up":false},{"one":"b137cf2291b530a39516d882200848e7f27a2710e0839b4d25b4f367bea6a0c3aaef8c7c7851c00a2945adcd819ea0508610afc1f453b8bc512b7b4d4faacdf3","other":"ea57884dd42aec5a76eab43483bf7c4ae2c19eebf365013731de64494d10a3b4cfe34c86c79437f9012bc8cf6bd761435eefadec17600f4b9e4bc234532d6282","up":true},{"one":"d3105ede6c21bc643d523afcd1309a5dcf03f70797a92f167c3a19f86ae98882fe1a9d4094d7a3dee4a0833b8075b6c3e9aaa7f4879dc47bb388c3ae85522288","other":"292c78c8e41606e98428096bc6f4609a7aa48e5c4d17eecc64d65faae4a7270b0c15f0cd74274015688ea0a9aff34f215c29118222e362a29c8d637963973a55","up":false},{"one":"57fb1bb32bb2b1a87e44c6a7557e9c47c2032d107bcb0e34acd9ffd54d5d3df5701232db16f62f7549ba2721021898b03160b1dc5201e79606648c1dbc4a373b","other":"a7507aa5665e165ab2e2a07def272f0677f9d6d35bb82268a34214384e7d8ef7635a299368752e63cfd02d4e60231076baf23cfa10d17492e55181b391ecf335","up":true},{"one":"6b01079463ec2f649db8634cb7a596261c79a8f714d954c772528e0547b017f8ce405e4a0ea9d32270848180e0f77b8c0b022cf95c85e777626edd4d24ea21d2","other":"7bbb3f3ed51cf84c077806fbd6d3578e105bc32aa6043da188793f066ad6df383a9f7cc0bd3124f4c887704bd188d480ce264fcdf178905bbda3b270927ea138","up":true},{"one":"c83985973a9564ade7d90aa54911ac57077600676a1d27292d98e058bf1315887bad84ccd708cb7f52a695a1405fb7d491d7ca2ae9caa3ff58a5ad78ce4dc9d9","other":"84dfd4e4d9f1204893f190eacc4c3999e175c433f70de86e335d27477c097a0552f211a21764f01a708da4c9e9e6552191a61d3e48f41d0e84f01e7ae3beb34e","up":true},{"one":"657d5370319128d24d925b41065eb619409d63ec6280975d78877a4028287463f6442f5206dd703569a05b2b542ad8bbb99803da265408208d6356a26d283d08","other":"6bf9fb6a25521c16c2ebeb6203d046d7dd40f29cc2ddb067c0222ef56d7012d2ee5d037f71f6668ea56767610b2a54c144aed74b7f68d06993cbd52fa1dc7630","up":true},{"one":"9db1f94d74a00d1e5e2a391f1bcddf16b6d0670a2c6d91d946d38112c58634444b6fea8e8c05ab4b73bacdd62a0b575f6fb8729978edc216c7842b177b9f9cd9","other":"6b4e376e9c94242b6d42688c22aa9ab418cb6dfb1cbca1c69de0feceec8d3af29fb005017aaa6e503cc0c03cf0dc5bcab55e01cd6f64b9efa02ed87c03020003","up":true},{"one":"a7378ee34876af17c6cd94a69b6b741ec7891ff5375bc4241d48608d047455ed48e6baae80ee88d4710c69ae615cf195cee26c94b54de1bb935628ce1e3a723a","other":"155e4879643a472420012e040a87dbff776fc1976814c0c6cd0d5e157f0d0baac04aa7f2535786c09acc2700547383d2119b64a6f62115f1aff1708738844d8c","up":true},{"one":"66d0c5da973d9dd65350ae1ec63776872cdb7ded6afb6f51ae82259f6fd35e884375d15de290625f02ed2e5cdc3f591decb45e5fc64d5b0f835a216fd196f5a3","other":"ea57884dd42aec5a76eab43483bf7c4ae2c19eebf365013731de64494d10a3b4cfe34c86c79437f9012bc8cf6bd761435eefadec17600f4b9e4bc234532d6282","up":true},{"one":"9ce6b9decb69d66075993e903a0727ec109a04335634616097c0e60b08f94f764634fa00891b1070f6ea1ce896bc7d11d3aea92a00f281f902d960894cef296f","other":"9194a3a4c8f3235203e48bdb10902d958d26c342805ea6365af9711213536509719d917c694f9a4fbdde6889a4c92299a5301f0275bda4dbcd2541b5bff5b271","up":true},{"one":"be026dfb24847cac2d00f483104edad06ca8ecb9e1229c479ef5650c7b427cd5dc34a1cf06172c17c9d0406ce17009712e82446394743d4cd9bbc41c537ebc14","other":"5bf29c02f07faf7ae8e46389e1b98df4f5e88c9316b5151685e6ae7b4e622cf171ff09f996aaa8ad846643b3bfcbd1ad96cdc249afccce439bb5c55246b95801","up":true},{"one":"17917fa4da06068b587c17899569dcc768b9cd2c27117a4ed67aab26a7e70cf8d32b881db258061ffd89a332a3b29bfd963d8e171a06c3e208ba0de1c42a2b39","other":"f38a9d792173a29c61389f5d84c005d78eac6e750659aad42e2d6df883f04eb3126b2c38fac95076eeed455b2031aaf694143922aa93a2d50412a2454dc56e28","up":true},{"one":"65e954e60837bda10654480b227fa3bcc6e63356c52079002a27e836cd82ae2934ba77da60080e4b9f2d9324b982b24959bfd9624302e6c330408381054b43e9","other":"e2a27dcdee1f89fa362a85c4397840cd8be4ad8d1b9ccb23188c303bcab7619f38772f71385922d090390973b62fb8249efc103f71bc761041bcb3880ec0b935","up":true},{"one":"315b8a1711f680c2eaa607e35ef7a9e19c2b61721af8a7e08f1325dde1fe33cf1f47b3cc4acf12d541631041cf1b42754875fd1c9b66ee32797b72b9f7711256","other":"2ac93c31937ca205d61cc5c2a1b9037871cac55e9b306b999b28e19566b3316f6539455e014840ea50c2db8a7c97d78804d3a2dcd7cd9c1f32ace0d36e5dd339","up":true},{"one":"88d5c5fe61ee1e6fa5878e0eaa13bdabaa0ec3d38a5d25b95a467da7627424f25fb5d30535aa0a5ad01c16fe2598dbf570b78cc152a7f4ef66d46fc9ae43592f","other":"74d84cfdaf32cd4cc67771f29878f1365120bd65cc14848008d5386a81f495bf88eb4132fa38a2cc109ae1e7f02c9b97597ab9d1a9c19c945e710ab9df07cdcd","up":true},{"one":"4fe37f2dfb03707c90a6fe91dbcfd7497db70ffc20043091d50e1cee573210c144e8749340f2c3cb70fe8fc51b317d49e8734dc51ce64b3cdccdd639ae35d1ae","other":"b53078000796f1cdb04dfeac424d5e3e37e30f00bd5bebf9a9ea0525c62917612b3a8f508df6bea59e3c7e4cd1aa530841f9a8af54e44f5617a13dee2c6ff007","up":true},{"one":"979838eaefcff456cf1cd9c47ea46854704f5757d8d7ab907019bc422b01af4d62252579bf045d143fab491b0bab823190e2782a457fbf51aa99ae17ec9e145f","other":"3d2df188704eeac09c8b291bf275a73888199a231c832c51dbc3d746968d4b51a7d5eae0c7c9b8c8e19f5e28d38c375e01abefa343f31dbe221deb837ab8a0df","up":true},{"one":"81288bb0584b7ffc1546043e052e1df10fd5371b35dedd0bb42ec5b30ce69b741b2f7857af5984d4754b39d7253575fde9298504999b78380ef602d391c4bb1d","other":"89a5b92a9ca045f12c35a70084e6f41f9775a25d6f105f8c9349c7b5e107179d8a96bdbb113b2680edf5183e9a42fd64bd7b29d0dc7797c583b833f869313699","up":true},{"one":"829b074b70d757da6aa00f7bace3cf1b5d2d4eeadb7f370c1a85374a01a70b54ac53d747267e386f3b41e6d790fecdd6e74b8f89745501ee82439a66ea54443a","other":"8ca3b63cb84f1e9883d82809a9b6777ec1029ecda96fe93b4d494ee9cbefcad13f381b3e480136e542e01054fe1ede66c65db84a0009871ce49383db461c8438","up":true},{"one":"f915e2398aa5d4370de87504dd76c21a7d0be2581c2ab55b7a47743f1bbaef36384eaacec22760f1e914ceac9d96a10c3d66eb27475ef444e77fee979e6e88cb","other":"11d560045536e9d1b0b1b9e8944e00f0ca7f1e6788c9fdb51061820bbb3008ead92bb7836621bf58da7035c87a28328faecb4cb2e3cdb9d7fa4f45790e6bf352","up":true},{"one":"083e67bb19e30d14e4df6d2483367d6659d9b56744d53d9cf7fd15954c327e1bc88a5d0db8833634e1dad7209164451f8934b59f76b5990059261abfd650519a","other":"3d2df188704eeac09c8b291bf275a73888199a231c832c51dbc3d746968d4b51a7d5eae0c7c9b8c8e19f5e28d38c375e01abefa343f31dbe221deb837ab8a0df","up":true},{"one":"d4b7c787981abec24353c7d496661692233797e3758189bf909a69fe87935bf6da0940daa4f12e81f20c5e88f70b472113688b71a0ae2f91a73ee0e6ff4c8591","other":"5e86f39cf8338ba098a85d41e601a303fde311662b216ad32a2b7bfaf2b2b6dd1af3775784b39f2d85ac5fac96f05f3abdd8a2bd28ba16d939725fd6a33ae1b6","up":true},{"one":"df54af3bae257d437c5657905484e0d72e9560c46f8ba6b3437730234e05259b404cca40b0831e911605ff8a68a19e8fd7e958069ec8b40595928892f4fa220c","other":"a7507aa5665e165ab2e2a07def272f0677f9d6d35bb82268a34214384e7d8ef7635a299368752e63cfd02d4e60231076baf23cfa10d17492e55181b391ecf335","up":true},{"one":"eaca77d20c4ad6b87649eba21b750a4b1a2c575e06bc42679d18fce16fea15212e9a7408c16f3b24d8dfd1e397314637e72e292845d09534a39035bd9203ee9e","other":"1d0244a13affe60996fe3cf51ba624adc746de0c7ea68ec5a31311a36077c5b5495e3d95c9642875db44c7ecae6ffed22e45f2e2d024d486760be2af9f4cf2cd","up":true},{"one":"60725e8d0e9333636e598dd666f459b4be898d9abc095ee2c1db289673e7e969b50e2093956fef5a2f1d23e2040159bbabaaeab17fc6dbbac3f6acab766e9e60","other":"d4b7c787981abec24353c7d496661692233797e3758189bf909a69fe87935bf6da0940daa4f12e81f20c5e88f70b472113688b71a0ae2f91a73ee0e6ff4c8591","up":true},{"one":"70ee3c7e02a123f78345d41c386e413f06b51f1ab346c2c472891eed7dd26a1f14e213a0f4f2d872859b9b535936a6d9b072d2604456f76221a422710411822f","other":"7aaf7817b93aa6d2f50513791f9ad7629a901ed0dcb151189f44763f83423446b20ec79a48fa260cd9bc2907d5f0ad06b2c4c5e6d812f3d8876c8020ebe41019","up":true},{"one":"043fe7085e8c90c18270f84dba5fab138e50216a1cf8d81a3794d156fad7fc81d1422aff169b244b13f91d73eebb5de464f97b1b93b3ad2a58959cff19238842","other":"3d2df188704eeac09c8b291bf275a73888199a231c832c51dbc3d746968d4b51a7d5eae0c7c9b8c8e19f5e28d38c375e01abefa343f31dbe221deb837ab8a0df","up":true},{"one":"b3316f4fd7dec218a52331f25d17a2faf0f2a417808d7dbb80038154abfbcd2d78da074837b648cff28675f4aa0d65ddb7d15abf3d7e0391d401e313a3ef24a2","other":"e267e71c2dcdbe5a500b23444d2d4037ea15afba8f4f2b1c0e54a274450404fbee6fa5439f7cddf4ba1aa28fa93e434b01c239add58e30a5423ca3a481584d6b","up":false},{"one":"abd8f5a4d700c06ec00684b23d2d25c4df1a9554fcfc57b0ddc3fa476e6a699ba75e1213449f900803f83ab8194c6746664b547202047f35b8b3e216c7147bf8","other":"b2538d4edfa736bfe2cc21326a44ce62f716b3480eac93584a2233b69c98883a2bb255f246218a58cecab1d0d176e6d1fbba9782fd70d4603e01742299b9ea9c","up":true},{"one":"a1560ce7c1f1d5972f027a8e9cff820611d84764aa067434a75b63887bc4268a259101486d34b7fe83dd735e799789986cd3e9b156c86ede598bd86af4454924","other":"0b7e1e5acabcde503ad827e45724402406114a513f81040a379b0f82df2eab4456b348b27936369c49e3c264d971c6a9e2c2217fdbc5e5b93ac6fc219957834d","up":true},{"one":"b080891d4ba6d3ab224984360597f9c555bd1367630f5420bfaf230419a05b2be58bebf1554e53eb4c0da81cfb66d4f7697dd65143f11841ff62d8a0d82b6b67","other":"9b618ad34d0dfe0fccbd5b8af365cbcdbb43e802df5f23e91c20d21f3ead6169d52bf0db7e5e111abef630c9853419fb33a88cf111d8507b8708208b5d65e35e","up":true},{"one":"e2e0419a41bdfc5bd76deae2ddce6ac865f886d764c9bd18799b79fa3b2b6ba66d765d26da2037e98317e1d7e8232a61e63c1d0cfa98c9137424151b46e07171","other":"032b9bf2f59f15571821611d3ee541aa748c86d47fbe5f049fd0069be53e5d7c41991d82957e9c727654c3aa73ec94997c03d8a6c1d2007c9bb1a703f6215158","up":true},{"one":"7646d08b3e24183e3814de130235c41eb88a5a2abff23eaff3c91954ad3ef55fe27da422dac5b894312276bf1a2f1aebb8b636a8d4a0c93d9b016d441df3fa19","other":"ee36d1d5dd69fd30242d7da2e941b34ade5581c7164fcc43288ecfc52937a98f1b31ade5d1e4dbf611cbe1c7875b2840c89435081cde471c271d7bc60e9ef211","up":true},{"one":"2b70e5ffcc0bb1c4f8acc09dd1016e67c9c96c92d091ad481efbb71bd8b2a5a5869c6d668617a9b2cbfe91baf5edfe150c3824c84d90899a974099071d171441","other":"c73d088ade8756c74832c73542bcdb3e52f670f7a74ad3a7eac2a9e3ece6bd081f782a8e1d3f9a40b9aa9201509110f37fc57fcb10ee1ef3ef07b7eab019782e","up":true},{"one":"e023a51c5bd26e1754d6461345143e94baeac799947579ec7adeccd105de39f85afbceeb5037cfc0b820b9f4446433f034d9e7de7326d45df5a967a8099dbb10","other":"b870935867183bbfb84add16b9f56c02c834b7042fc24ce6bcb2a7f174e6d2239357a00be4272c1ef05c7f9baf5a9f16b53bc18328a9b7aca8540c2916805b57","up":true},{"one":"beec648d79437a5d7b4140ced45d82d035c6f64f9c67c58386703811d97c3846787eaf274d2298df809475f0b7519df696563cb8e9a5fb0a9cc419ab13fa8d41","other":"fde7705f5013c3b6b76a35505c1e3d57c033a337f2a71e912ec3a3d2da8e113bd7c36d94908357e9f7654660621f647ad8c66b0126dfe91dbfa3b8c7bd2183d3","up":true},{"one":"2ca05ffc0ad771e1e045a47f1c0a79ce374a25e3c0e53c2a80d67e7479677003f62880251a83a5074f1c9651d828f1ff7e352935a9df141c1eb75a0c59b00a8b","other":"4314b0b04331973ed29a58843951f144ac3d09bd5d57b6cd9aaff9b73a7b2ec81e344a3e4ece462bd2081b837a06310e787ef3bb889dabad46fe7efd394c8342","up":false},{"one":"759f46661056bcbb30c7706c9fb87e22a30feb523bd53ae5d18db043efa45b49a2b8982abebdd598fe0912a05896390ec2eabe5e160cbafc0771990708ad8c28","other":"016f8f4619a16a07fbde5a18e362158d696e4d9f104a77787f26e32a25cd7d278256f8e0db865c488a99511ec27a5eddd5ebbd1c1397fa7f8db111062e5fe959","up":false},{"one":"fe8ac5d33cd8ab6a1dad9567cdfb89b431a5c4f4a584fc608b92e7dfd06f70988e71e2f11f9fda9ee797c9ffba83bc085939fdf2522dde39f28202be92650566","other":"84dfd4e4d9f1204893f190eacc4c3999e175c433f70de86e335d27477c097a0552f211a21764f01a708da4c9e9e6552191a61d3e48f41d0e84f01e7ae3beb34e","up":true},{"one":"ee36d1d5dd69fd30242d7da2e941b34ade5581c7164fcc43288ecfc52937a98f1b31ade5d1e4dbf611cbe1c7875b2840c89435081cde471c271d7bc60e9ef211","other":"07c63ca5d0309e30d1ab12e7fc142e6d37904b552639cfa97850161491f28f20d87e0304be29357bcfc2ff52fc52fd0d4f6e6011ebb239cced8b5c8dad7abf45","up":true},{"one":"b6a998dea59194cc60ce97c7c9702368411889cb6905516b23f41cc5116fba8d0f237d418318eb0c333cad18003c0e9a6bd8c99080520771f2bad640e2e5ec1c","other":"f5c1215a84a56d52f92ca0dc3a32df98c98a9c2ea2e9a34560210c16de1b440d20d043c8c25955dda8c22e55e92ddb49fd82e8b9b84072aabaa755a229bb19f4","up":true},{"one":"2ac522ebfa49d37f86c6270ad4cdad0e766493f0e463b18c9906c70fbd2e5c6ff6b0d5879de6e3894418370636963a78b0c0cf087a8684c2ca30c9c736e49228","other":"60725e8d0e9333636e598dd666f459b4be898d9abc095ee2c1db289673e7e969b50e2093956fef5a2f1d23e2040159bbabaaeab17fc6dbbac3f6acab766e9e60","up":true},{"one":"9bbbfac8be4a000f51a4ce8d024d2595b5d491afec0138922dddfde5ef62c664040c2e9304cc6b7bc688233b5d0c4644b8c8793227c078285a3ab894ef0497a3","other":"732393b99c490c76fa45e3e404ee095f2fa445fcc123af7ac8ab1d2fdd7cf2483f5b82bb818bd8a82b1a3b73e63bcc2c83d8f24d9aad9afe36503735e7967be7","up":true},{"one":"7865b82e44add2cea6ebcbaba9c152184331a2940fe73f6f9bb940bda8a59ab4cf4760894b9cadcaa54e36fbb712ad619346a49a85e32cdf2b53cda1ac1e0658","other":"66d0c5da973d9dd65350ae1ec63776872cdb7ded6afb6f51ae82259f6fd35e884375d15de290625f02ed2e5cdc3f591decb45e5fc64d5b0f835a216fd196f5a3","up":false},{"one":"7f357b8d81bc2e5c6fcb081f23a42b3e2439f050d45c45851994a268d1c71fcb1f39f8c3f75ce921d3fbf80fc0e73f0b9609d72001dc4a6b65b526d312a4f43a","other":"c2705ee7238ef9305e4da196653cde707649435a1e8b5b797d164e5ca06184a77af5bd7fa938c995fdfcbce724fa7eca3d908ee34891ab62cc6dfd411c3fa1da","up":true},{"one":"74d84cfdaf32cd4cc67771f29878f1365120bd65cc14848008d5386a81f495bf88eb4132fa38a2cc109ae1e7f02c9b97597ab9d1a9c19c945e710ab9df07cdcd","other":"80d997b87856099d844187d3d1fa40846ded652a62c1611b35919c2543915b64ff62476636488556f678e436ea26fcc40db7c6b6bbcb78f590d61c1ff0e424b5","up":true},{"one":"d3105ede6c21bc643d523afcd1309a5dcf03f70797a92f167c3a19f86ae98882fe1a9d4094d7a3dee4a0833b8075b6c3e9aaa7f4879dc47bb388c3ae85522288","other":"7174eca109a1f717653918224c8cfe1b7fbd666405196760913593401eb79f2c7e41003b01f5a458940695b27a4673443c7621a169db7fd968994e552995dbbb","up":true},{"one":"62dab8b21640e1b44dea452dd7e7de93f27a44840da72d56b11aa96e8463f3a4bb15e75a954d19fc897ae0030b16181d271b79d8198b7cffcddaa9ffcfdcce73","other":"24662a43944228e4ff74736bcf0a0a4f79c87ecfdb739225b2fc45110c11bfc38aaf2d09d98e5817477848e553f187ac5408bdb864518dfa7f5df542768828db","up":true},{"one":"e087230634f556b818a416b66ba3f1d1dbe3e0dd0698bbb26fa86a2499acd169466f564dc18adf2f9be4d1ada0e86c11549754097601e10aff4f3a57ddffa24a","other":"b6a998dea59194cc60ce97c7c9702368411889cb6905516b23f41cc5116fba8d0f237d418318eb0c333cad18003c0e9a6bd8c99080520771f2bad640e2e5ec1c","up":true},{"one":"7808fb798d22e78fb1d39b87ddf99a503f820993bc64149eca9e81d9d58fc1adea60d8de14a4f06cb89f3190c0ef0c5e182621a14c9361ccb7e0cee667599cc3","other":"460531928a4b084686343c8464b37c3452bb3566045698d08a4692864de5581a9eb1dc632329e7d3ccb73ec31ee7693787d69df8458efaba9a7105d87ee2e053","up":true},{"one":"352407b42726dcd1aacc46a912ed8124b8b6a3da4e33dab742e40aa2452953d35dc8f42eddc76695ae2317e9f15dde2cd21be4ce826934695ad1847455661d1b","other":"6bf9fb6a25521c16c2ebeb6203d046d7dd40f29cc2ddb067c0222ef56d7012d2ee5d037f71f6668ea56767610b2a54c144aed74b7f68d06993cbd52fa1dc7630","up":true},{"one":"ce0a09bb6fe4c9c93c3dbd800ca9c9ac0714f26a8f8dac2149b6ce7a9011912a5621ea2e45de35c4d31dfe5add00558fdba5dd21acf2d81ba391e82b5b3a5804","other":"4f5ab12b9c5127c16739ad0d4f51adce90ba6736cd096eb185ea632789f4b26f1ebabdea4fd3b39dda5409ece6c2d92fd469cf4aecf9d29453e3e042c19b893b","up":true},{"one":"a7378ee34876af17c6cd94a69b6b741ec7891ff5375bc4241d48608d047455ed48e6baae80ee88d4710c69ae615cf195cee26c94b54de1bb935628ce1e3a723a","other":"7bbb3f3ed51cf84c077806fbd6d3578e105bc32aa6043da188793f066ad6df383a9f7cc0bd3124f4c887704bd188d480ce264fcdf178905bbda3b270927ea138","up":true},{"one":"855bdf057f4a6b095e2000ada199447b5b4f2f8d78d2ecbaa0ff1fbf761788870ee999266ad3b26efa02be1a46a4d92ac0debb85a2ceab3442394ee7d99e5355","other":"76cbf9fc0f3517fb615fa96104780218e85d064ee5a1d518f3b78f4dbebf144df38c427445fdd6c9b436489c00ff9497d747a8fd70f380f95601d59e52e021e8","up":true},{"one":"23f9bdc82efbf57d3d40a1f2617d0311678fb4a3d6a50cb7e608c649bb618124a76c7ffd17387de963e1cd28d2bd5a61c98613f6e009a8a2a90d989827b35de0","other":"27d9048707a89f1a61e44fdae523c0128f2a7050308bd3cfefa6c3e03040a0e22f11ab41275f22b8706e6695ab93320e2af35179d772581db5f49f960750f2f7","up":true},{"one":"8d4920d6e3a6717699b5a3af068cbdfc16858d7e393d158d41b1b5f345b47129eef89e1d055386c518f400b134678c21590f0317dea3436d4cef60f45455cf12","other":"083e67bb19e30d14e4df6d2483367d6659d9b56744d53d9cf7fd15954c327e1bc88a5d0db8833634e1dad7209164451f8934b59f76b5990059261abfd650519a","up":true},{"one":"65e954e60837bda10654480b227fa3bcc6e63356c52079002a27e836cd82ae2934ba77da60080e4b9f2d9324b982b24959bfd9624302e6c330408381054b43e9","other":"a127faa19dcb7da585983d36a8e9d3e9a44a6db68507b60c70da71011f44ce377944802f39cd65f5a705cd8249ac1ef7ed8fd699349098f3f8e23b37592c80ae","up":true},{"one":"b53078000796f1cdb04dfeac424d5e3e37e30f00bd5bebf9a9ea0525c62917612b3a8f508df6bea59e3c7e4cd1aa530841f9a8af54e44f5617a13dee2c6ff007","other":"5df58ba12334a1b4f983d642fe435901261767cd81f8f37c43e359f5584664e4d287e8c2275995604a3b3a4823418e35cd899a3db2a7db31570e19512f375481","up":true},{"one":"88d5c5fe61ee1e6fa5878e0eaa13bdabaa0ec3d38a5d25b95a467da7627424f25fb5d30535aa0a5ad01c16fe2598dbf570b78cc152a7f4ef66d46fc9ae43592f","other":"ae4e21e1587a8475afd299e00ca7085c7bf2a44c2c64a3068f12223d9202b0125094385319034691ec26b497ec9cf18fe8c0839224bac1b84279410241cef979","up":true},{"one":"68cc8b9a995eef6170abf88bd5fedca06ffcc8d75f247f6041c13e7dfd292727ebda1ff86b776e33b6634355c55e0f8c22fcdb5f9a6e2f22fe1af7854c3b4273","other":"89a5b92a9ca045f12c35a70084e6f41f9775a25d6f105f8c9349c7b5e107179d8a96bdbb113b2680edf5183e9a42fd64bd7b29d0dc7797c583b833f869313699","up":true},{"one":"5eccdbcb15ef42dc96abcbcd8b8db75d9230de10e3c650620737f6cc04ba4fdbf59ded5daa801901c191be186c329ebcd37ba83bcf794064ad4e11bf10d3f775","other":"6ab6ec15635b2fda22542c99df0a3313ad4583ba0fb3f31b8f314e3ecad446d3fb0fdfcd2be9b08374b1a7e049fb68e69e8dacdd13f1df5007a656f6b11adc5b","up":true},{"one":"e6779e3bbecf81dde8b27d652ed2726c45c205db0d0405c4580014a4c91d739830276f77079108c98ac516ffa00194e77a0795f7140bdf36069b6475e58213f9","other":"d3105ede6c21bc643d523afcd1309a5dcf03f70797a92f167c3a19f86ae98882fe1a9d4094d7a3dee4a0833b8075b6c3e9aaa7f4879dc47bb388c3ae85522288","up":true},{"one":"e087230634f556b818a416b66ba3f1d1dbe3e0dd0698bbb26fa86a2499acd169466f564dc18adf2f9be4d1ada0e86c11549754097601e10aff4f3a57ddffa24a","other":"62dab8b21640e1b44dea452dd7e7de93f27a44840da72d56b11aa96e8463f3a4bb15e75a954d19fc897ae0030b16181d271b79d8198b7cffcddaa9ffcfdcce73","up":true},{"one":"9db1f94d74a00d1e5e2a391f1bcddf16b6d0670a2c6d91d946d38112c58634444b6fea8e8c05ab4b73bacdd62a0b575f6fb8729978edc216c7842b177b9f9cd9","other":"ea57884dd42aec5a76eab43483bf7c4ae2c19eebf365013731de64494d10a3b4cfe34c86c79437f9012bc8cf6bd761435eefadec17600f4b9e4bc234532d6282","up":true},{"one":"e2a27dcdee1f89fa362a85c4397840cd8be4ad8d1b9ccb23188c303bcab7619f38772f71385922d090390973b62fb8249efc103f71bc761041bcb3880ec0b935","other":"0f9f7e2dce4ca266c3ac0ec3a8854200b54487f5308e3db418461aeb5f67c81d332619b6441b468e480941e63100ed1b263e7adc20689dc3dcda578bfca538fa","up":true},{"one":"2bfba66ec9d63e928d77d455f2e10a14d6213e515099d5db14fa44a8bfc147eb0fa7afa9aaccdc86453c6903b55556059a2e13dd61fc494127d4a3ec173bf9ea","other":"eab86c521f8f1ac67c015ab713f1236a08b0200757a96bf87ab8301e7967ae62361f0e14da14ca294fc8cb3b4726b52f4773101e21b032977c6a647241b59c73","up":true},{"one":"3d2df188704eeac09c8b291bf275a73888199a231c832c51dbc3d746968d4b51a7d5eae0c7c9b8c8e19f5e28d38c375e01abefa343f31dbe221deb837ab8a0df","other":"016f8f4619a16a07fbde5a18e362158d696e4d9f104a77787f26e32a25cd7d278256f8e0db865c488a99511ec27a5eddd5ebbd1c1397fa7f8db111062e5fe959","up":true},{"one":"bcf8e831821a5bca359fb824c7dc4d66906de82f3663a0a853d96880a8ca0bdddcceb1b66dd1f13f75ee20fde50fc9de545bc25767f228baee910e0dbfa8cc27","other":"d7a319f69013b8375e64d19f015547462c84565b882337998f9e669c5fadd3d2ecf6374109903003e09f5d453424b5c7fdf52163d2cc8084cf81f94844946b63","up":true},{"one":"df54af3bae257d437c5657905484e0d72e9560c46f8ba6b3437730234e05259b404cca40b0831e911605ff8a68a19e8fd7e958069ec8b40595928892f4fa220c","other":"07f25fdeab2b44b2e92fc80fca7de9e4a8547d27a98a54593b3395c270a9ff3f2a5da62a2e8531ce86359f0cdc5b6513b773dfd64cce1b83e47065d9760a2c7e","up":true},{"one":"934a5fe1b91c1891ef4df7f67c027e0eb115d4c2ca4a1b76a135ebd4315c4fb835d6625223194e6a134407b38b0d3928fbc7bc924a3c6a538989a6cf200bf4bd","other":"ba21a373781966135d6225adae024a3f3e421b852f72f8b0569cb92fcff87c33f7e5b799a509b8eff6ec6dc46a9b17d5bae1e91ec7c54c0c712d893d54b140fa","up":true},{"one":"6f60ef501b41f9049419b033ae8d793a18067bdcd60347537b0dc3873bdd9a2d10d24909cca7c39781765746128c2165596f6537a94f58279523faee71f9c51d","other":"54b3c57a4adf4dbaf31b85ed1b8dccd6249faa16dd96dd230189f47f57970caeed36627cc8e1b0794707418d580f5bd6001c07be6a79216695f1253db24926bb","up":false},{"one":"c332fe1f9b6e25f72c7150631ffa6e0929ff6eeab5d17aa45eaf669bdde869cf404505ae990a529aa3ca797cd0a96f31cc41431a5d4a163132be566f91623c08","other":"d4b7c787981abec24353c7d496661692233797e3758189bf909a69fe87935bf6da0940daa4f12e81f20c5e88f70b472113688b71a0ae2f91a73ee0e6ff4c8591","up":true},{"one":"b53078000796f1cdb04dfeac424d5e3e37e30f00bd5bebf9a9ea0525c62917612b3a8f508df6bea59e3c7e4cd1aa530841f9a8af54e44f5617a13dee2c6ff007","other":"1944f98d4db32c56a5efda5a79aa5f276bfab1e084d6611fec0e735b8bc0f45b457cdb74a23fc83b2377821fa8316123c9877acd6db7c41058ca5d3cfedaecf9","up":true},{"one":"d7a319f69013b8375e64d19f015547462c84565b882337998f9e669c5fadd3d2ecf6374109903003e09f5d453424b5c7fdf52163d2cc8084cf81f94844946b63","other":"f039df8a3206e6e17eee8e95010038c450cb4cc0b5580ed5795d4c21802e1e9d360f4528bdca794f457932b1d6a818862ec847357a861c488332ef6d9480daa6","up":true},{"one":"22010c9829626a6892258b09cb3f3edc3f21382fb487b5dbf0dd20e198e37e26134aab850e30337f398d1491b5126839aeb1953ec144bc19aeb889c832f67c6a","other":"4e68553db7be307b8379e8bec383b5c92e4b23debcefca575d24504e2062618f74c26e60e0d9e47f096997a7f841e2c32c994124f495ef3352ef964b33fd3a51","up":true},{"one":"e06a789a7f6988e1ba5e8358b6cd4292555c7f9f7f0dda6fc01cc26d24e49a8c1ad694423ad74aec6d80f4b99e2bedc49b6a5f2670744cedee3a3e1848e6dd07","other":"7554993f6efd8d9016ff525ae73c41ee2e0dbd4970c563ba9b61a99c1c8943b433c4b7d48450f6e0fbc9ac198d907698093de20e6c1f7755520fb1e1cbee4eb4","up":true},{"one":"54b3c57a4adf4dbaf31b85ed1b8dccd6249faa16dd96dd230189f47f57970caeed36627cc8e1b0794707418d580f5bd6001c07be6a79216695f1253db24926bb","other":"2bfba66ec9d63e928d77d455f2e10a14d6213e515099d5db14fa44a8bfc147eb0fa7afa9aaccdc86453c6903b55556059a2e13dd61fc494127d4a3ec173bf9ea","up":true},{"one":"d3105ede6c21bc643d523afcd1309a5dcf03f70797a92f167c3a19f86ae98882fe1a9d4094d7a3dee4a0833b8075b6c3e9aaa7f4879dc47bb388c3ae85522288","other":"7554993f6efd8d9016ff525ae73c41ee2e0dbd4970c563ba9b61a99c1c8943b433c4b7d48450f6e0fbc9ac198d907698093de20e6c1f7755520fb1e1cbee4eb4","up":true},{"one":"d3105ede6c21bc643d523afcd1309a5dcf03f70797a92f167c3a19f86ae98882fe1a9d4094d7a3dee4a0833b8075b6c3e9aaa7f4879dc47bb388c3ae85522288","other":"caaf695c76cf7c047d3f3bfe019d01618e4871cee8ff3f347913da815bbcde145771486f916a44d03f59ea9bc217f169fd0c0765fda3f9b9b28d02a522e180b4","up":true},{"one":"0b7e1e5acabcde503ad827e45724402406114a513f81040a379b0f82df2eab4456b348b27936369c49e3c264d971c6a9e2c2217fdbc5e5b93ac6fc219957834d","other":"24662a43944228e4ff74736bcf0a0a4f79c87ecfdb739225b2fc45110c11bfc38aaf2d09d98e5817477848e553f187ac5408bdb864518dfa7f5df542768828db","up":true},{"one":"f54335964d9b4eb9813eb05f40ef1c523bbf0faac5a04c4737467d590fb6b55c7fa1fc5d4d32c5491d8766b9be6fdfd3ebdb25c5ffe1719f36c86ddf87ae3a85","other":"083e67bb19e30d14e4df6d2483367d6659d9b56744d53d9cf7fd15954c327e1bc88a5d0db8833634e1dad7209164451f8934b59f76b5990059261abfd650519a","up":true},{"one":"22010c9829626a6892258b09cb3f3edc3f21382fb487b5dbf0dd20e198e37e26134aab850e30337f398d1491b5126839aeb1953ec144bc19aeb889c832f67c6a","other":"083e67bb19e30d14e4df6d2483367d6659d9b56744d53d9cf7fd15954c327e1bc88a5d0db8833634e1dad7209164451f8934b59f76b5990059261abfd650519a","up":true},{"one":"1bc1d6155ba35d29ea16938994e08df76ebd8f16bd180bd6a9b9d8798d0745889fe72d641dd78bd8ec13526929f7eb5aaa6a388430fa69033d6db581e53c6422","other":"016f8f4619a16a07fbde5a18e362158d696e4d9f104a77787f26e32a25cd7d278256f8e0db865c488a99511ec27a5eddd5ebbd1c1397fa7f8db111062e5fe959","up":true},{"one":"ae4e21e1587a8475afd299e00ca7085c7bf2a44c2c64a3068f12223d9202b0125094385319034691ec26b497ec9cf18fe8c0839224bac1b84279410241cef979","other":"fe8ac5d33cd8ab6a1dad9567cdfb89b431a5c4f4a584fc608b92e7dfd06f70988e71e2f11f9fda9ee797c9ffba83bc085939fdf2522dde39f28202be92650566","up":false},{"one":"28d3232c43de54ffdaf08f97b334c012738648b04e2876c7e751a2e352aaf4d550d6efa976c5a8edbfa8e88b9d04a0fca492b81c3756ef673ab74d34182ca711","other":"0a4eec7b0e05da799aca5b36d9e2530f2a89d1426b1fcb7d8f9a662df8a8b5b763767a20db3c9c63e0bd13c2a6e16d3ba8f03baf84f5e5d24917b3f211d9bcfc","up":true},{"one":"385168340139236a0e0f537fa693122db9fa02a377c96f31aae54718e92624fc0288164877e63616651565e055c53f7074ab2fdd18a837da6faf644941305bf0","other":"2e409baefbd821485a151993356730e5989810d581e68190fbaa142799c9335bcf98310ad188fed10ae6eb6e2e789730393e509962ec5c0fef0342d72ed088d9","up":true},{"one":"ae4e21e1587a8475afd299e00ca7085c7bf2a44c2c64a3068f12223d9202b0125094385319034691ec26b497ec9cf18fe8c0839224bac1b84279410241cef979","other":"2bfba66ec9d63e928d77d455f2e10a14d6213e515099d5db14fa44a8bfc147eb0fa7afa9aaccdc86453c6903b55556059a2e13dd61fc494127d4a3ec173bf9ea","up":true},{"one":"b080891d4ba6d3ab224984360597f9c555bd1367630f5420bfaf230419a05b2be58bebf1554e53eb4c0da81cfb66d4f7697dd65143f11841ff62d8a0d82b6b67","other":"5e86f39cf8338ba098a85d41e601a303fde311662b216ad32a2b7bfaf2b2b6dd1af3775784b39f2d85ac5fac96f05f3abdd8a2bd28ba16d939725fd6a33ae1b6","up":true},{"one":"732393b99c490c76fa45e3e404ee095f2fa445fcc123af7ac8ab1d2fdd7cf2483f5b82bb818bd8a82b1a3b73e63bcc2c83d8f24d9aad9afe36503735e7967be7","other":"a99852c5bf08ea4713af9cade5343d1259bfb90401aca7fcff18c58cd56a98804dd16c61fea71039c0ac31b9bbbb9dc5aeaf0c2f074d3365e88d17031802d636","up":true},{"one":"62dab8b21640e1b44dea452dd7e7de93f27a44840da72d56b11aa96e8463f3a4bb15e75a954d19fc897ae0030b16181d271b79d8198b7cffcddaa9ffcfdcce73","other":"0b7e1e5acabcde503ad827e45724402406114a513f81040a379b0f82df2eab4456b348b27936369c49e3c264d971c6a9e2c2217fdbc5e5b93ac6fc219957834d","up":true},{"one":"b080891d4ba6d3ab224984360597f9c555bd1367630f5420bfaf230419a05b2be58bebf1554e53eb4c0da81cfb66d4f7697dd65143f11841ff62d8a0d82b6b67","other":"032b9bf2f59f15571821611d3ee541aa748c86d47fbe5f049fd0069be53e5d7c41991d82957e9c727654c3aa73ec94997c03d8a6c1d2007c9bb1a703f6215158","up":true},{"one":"e087230634f556b818a416b66ba3f1d1dbe3e0dd0698bbb26fa86a2499acd169466f564dc18adf2f9be4d1ada0e86c11549754097601e10aff4f3a57ddffa24a","other":"0b7e1e5acabcde503ad827e45724402406114a513f81040a379b0f82df2eab4456b348b27936369c49e3c264d971c6a9e2c2217fdbc5e5b93ac6fc219957834d","up":true},{"one":"62dab8b21640e1b44dea452dd7e7de93f27a44840da72d56b11aa96e8463f3a4bb15e75a954d19fc897ae0030b16181d271b79d8198b7cffcddaa9ffcfdcce73","other":"b6a998dea59194cc60ce97c7c9702368411889cb6905516b23f41cc5116fba8d0f237d418318eb0c333cad18003c0e9a6bd8c99080520771f2bad640e2e5ec1c","up":true},{"one":"17a79cb279306b6bbd35219278f6bba03111079d6c4fadcd3c5e57b09678e111bda5f8e36ca3d223e51e255d6e857363b7741e438b32ec6e6c0dc1b224071081","other":"11d560045536e9d1b0b1b9e8944e00f0ca7f1e6788c9fdb51061820bbb3008ead92bb7836621bf58da7035c87a28328faecb4cb2e3cdb9d7fa4f45790e6bf352","up":true},{"one":"2b70e5ffcc0bb1c4f8acc09dd1016e67c9c96c92d091ad481efbb71bd8b2a5a5869c6d668617a9b2cbfe91baf5edfe150c3824c84d90899a974099071d171441","other":"302c37f28c69fdcf00b39ce0c0223de0d94cebc2c0b068315b95b76b5432573ead0656569441029ba9054d8d3d959fd8735e73913af5ce3f1132f8271fd437ef","up":true},{"one":"2b70e5ffcc0bb1c4f8acc09dd1016e67c9c96c92d091ad481efbb71bd8b2a5a5869c6d668617a9b2cbfe91baf5edfe150c3824c84d90899a974099071d171441","other":"a78f18691e0dbf3c08fe9d7dec188e6a05a93833432fb99eb2b3924ab0bde7a44db2a102a65544bbdc4fb61bc3a3d569230d9843a335bf619167fb045d78ab3c","up":true},{"one":"e023a51c5bd26e1754d6461345143e94baeac799947579ec7adeccd105de39f85afbceeb5037cfc0b820b9f4446433f034d9e7de7326d45df5a967a8099dbb10","other":"2e42f845d0393d1682add54ee30b60a953ed283e75d347bc6719ae0e91f6676282e7960f1fd52e5803d6b341fb3582c724b4f9cfd7bce9ce85f13ca480c7e72e","up":true},{"one":"28d3232c43de54ffdaf08f97b334c012738648b04e2876c7e751a2e352aaf4d550d6efa976c5a8edbfa8e88b9d04a0fca492b81c3756ef673ab74d34182ca711","other":"afe5b217dc512eee45575c189826ee5640d11a0ac9e8e4b03e9e62e6cf6df9de500bc8a36cb7d82a2280ce184409164f1772cc5c9e59ad04361522d2b8c364e0","up":true},{"one":"1bc1d6155ba35d29ea16938994e08df76ebd8f16bd180bd6a9b9d8798d0745889fe72d641dd78bd8ec13526929f7eb5aaa6a388430fa69033d6db581e53c6422","other":"bcf8e831821a5bca359fb824c7dc4d66906de82f3663a0a853d96880a8ca0bdddcceb1b66dd1f13f75ee20fde50fc9de545bc25767f228baee910e0dbfa8cc27","up":true},{"one":"e023a51c5bd26e1754d6461345143e94baeac799947579ec7adeccd105de39f85afbceeb5037cfc0b820b9f4446433f034d9e7de7326d45df5a967a8099dbb10","other":"7b35c856916eb3fc1b1f451667e240b95aff8f4731cc0f6743740923081ff1ddf2eec81bdccf4691a7bcc053d23eacfc15809c384a73448f618317bf605bd1cd","up":false},{"one":"e023a51c5bd26e1754d6461345143e94baeac799947579ec7adeccd105de39f85afbceeb5037cfc0b820b9f4446433f034d9e7de7326d45df5a967a8099dbb10","other":"083e67bb19e30d14e4df6d2483367d6659d9b56744d53d9cf7fd15954c327e1bc88a5d0db8833634e1dad7209164451f8934b59f76b5990059261abfd650519a","up":true},{"one":"e6779e3bbecf81dde8b27d652ed2726c45c205db0d0405c4580014a4c91d739830276f77079108c98ac516ffa00194e77a0795f7140bdf36069b6475e58213f9","other":"7865b82e44add2cea6ebcbaba9c152184331a2940fe73f6f9bb940bda8a59ab4cf4760894b9cadcaa54e36fbb712ad619346a49a85e32cdf2b53cda1ac1e0658","up":true},{"one":"c83985973a9564ade7d90aa54911ac57077600676a1d27292d98e058bf1315887bad84ccd708cb7f52a695a1405fb7d491d7ca2ae9caa3ff58a5ad78ce4dc9d9","other":"0b30b36e155db04c448b662c4df695068b2331cdbe2772aae5fda84159e977515a5ff2e156bc225a9281fef2383926ba8cb11e9c1846fb40db241e524ac14e29","up":true},{"one":"6b01079463ec2f649db8634cb7a596261c79a8f714d954c772528e0547b017f8ce405e4a0ea9d32270848180e0f77b8c0b022cf95c85e777626edd4d24ea21d2","other":"ddaf3f8478501cda872c056c72063eb64d5b871fc5fff70704872802289dd2d348f73bc342b7f148a90cfaae2448ebf16fea196be9df891dc71a57fb410d59dd","up":true},{"one":"5566111b7f14d8ec83ba6456488f3fc5c7e2c86bf406dead33b814e1ee9b569d34015a4d88226b7e28fff7784395c086d106287cbbc80acfe75b05cd6e12903d","other":"f039df8a3206e6e17eee8e95010038c450cb4cc0b5580ed5795d4c21802e1e9d360f4528bdca794f457932b1d6a818862ec847357a861c488332ef6d9480daa6","up":true},{"one":"22010c9829626a6892258b09cb3f3edc3f21382fb487b5dbf0dd20e198e37e26134aab850e30337f398d1491b5126839aeb1953ec144bc19aeb889c832f67c6a","other":"4de378164d77a28c90cf162dd1b465e0282ee17aa7d3bb3179252466f72da33a36c9f298f7c9498e38dba4018e7ce3e5fe631c83842cd9059e23a7fece366d87","up":true},{"one":"c83985973a9564ade7d90aa54911ac57077600676a1d27292d98e058bf1315887bad84ccd708cb7f52a695a1405fb7d491d7ca2ae9caa3ff58a5ad78ce4dc9d9","other":"eab86c521f8f1ac67c015ab713f1236a08b0200757a96bf87ab8301e7967ae62361f0e14da14ca294fc8cb3b4726b52f4773101e21b032977c6a647241b59c73","up":true},{"one":"11d560045536e9d1b0b1b9e8944e00f0ca7f1e6788c9fdb51061820bbb3008ead92bb7836621bf58da7035c87a28328faecb4cb2e3cdb9d7fa4f45790e6bf352","other":"3d2df188704eeac09c8b291bf275a73888199a231c832c51dbc3d746968d4b51a7d5eae0c7c9b8c8e19f5e28d38c375e01abefa343f31dbe221deb837ab8a0df","up":true},{"one":"083e67bb19e30d14e4df6d2483367d6659d9b56744d53d9cf7fd15954c327e1bc88a5d0db8833634e1dad7209164451f8934b59f76b5990059261abfd650519a","other":"bcf8e831821a5bca359fb824c7dc4d66906de82f3663a0a853d96880a8ca0bdddcceb1b66dd1f13f75ee20fde50fc9de545bc25767f228baee910e0dbfa8cc27","up":true},{"one":"a78f18691e0dbf3c08fe9d7dec188e6a05a93833432fb99eb2b3924ab0bde7a44db2a102a65544bbdc4fb61bc3a3d569230d9843a335bf619167fb045d78ab3c","other":"c2705ee7238ef9305e4da196653cde707649435a1e8b5b797d164e5ca06184a77af5bd7fa938c995fdfcbce724fa7eca3d908ee34891ab62cc6dfd411c3fa1da","up":true},{"one":"1c2f7ce55a6e38487f3b3fe6083a79f914cd6d7e4aee8f5d56b4a61b3eb584e128c56998db0e13e775edee3adacf54f09960a041dab3daa80a4f8a3b42760c1c","other":"759f46661056bcbb30c7706c9fb87e22a30feb523bd53ae5d18db043efa45b49a2b8982abebdd598fe0912a05896390ec2eabe5e160cbafc0771990708ad8c28","up":true},{"one":"3612863ce0456c91785a829bf5c9d2b2fb97dda083a1847e5a4ebaa6fce1260faf4d1eb374c2225431a82774163835fb59c8cb0fa9fc0969eab5410c71109cc2","other":"b35f418c7935cc54278e90978c3ef1521ab91daeaf9f1ebc1cd25211611ade091cac4e1f009d71059279d507322a4536501980ac0dd44caddc52fd4c593879f7","up":true},{"one":"083e67bb19e30d14e4df6d2483367d6659d9b56744d53d9cf7fd15954c327e1bc88a5d0db8833634e1dad7209164451f8934b59f76b5990059261abfd650519a","other":"be026dfb24847cac2d00f483104edad06ca8ecb9e1229c479ef5650c7b427cd5dc34a1cf06172c17c9d0406ce17009712e82446394743d4cd9bbc41c537ebc14","up":true},{"one":"f33d1f3e460574706ac1c7fc9ebb4683b173496ce3e80017d1c3521bca03d5a41a9c7a6cde8347d2238917b7cc58cab000ce7ccf6bb408561015a2ecbe613408","other":"bcf8e831821a5bca359fb824c7dc4d66906de82f3663a0a853d96880a8ca0bdddcceb1b66dd1f13f75ee20fde50fc9de545bc25767f228baee910e0dbfa8cc27","up":true},{"one":"f33d1f3e460574706ac1c7fc9ebb4683b173496ce3e80017d1c3521bca03d5a41a9c7a6cde8347d2238917b7cc58cab000ce7ccf6bb408561015a2ecbe613408","other":"4314b0b04331973ed29a58843951f144ac3d09bd5d57b6cd9aaff9b73a7b2ec81e344a3e4ece462bd2081b837a06310e787ef3bb889dabad46fe7efd394c8342","up":true},{"one":"81288bb0584b7ffc1546043e052e1df10fd5371b35dedd0bb42ec5b30ce69b741b2f7857af5984d4754b39d7253575fde9298504999b78380ef602d391c4bb1d","other":"0cacda5560faff9d20e29a0625d3cd340ec075f198a50ab8b79338cee0e0db84c7c7e71042fd8c8f73e507b570de5d26c39473136b575f0167625a1168309ec5","up":true},{"one":"7808fb798d22e78fb1d39b87ddf99a503f820993bc64149eca9e81d9d58fc1adea60d8de14a4f06cb89f3190c0ef0c5e182621a14c9361ccb7e0cee667599cc3","other":"aacff366e601e072a2113add9020e19b6612f3e85b6e607fdc8cc1b6991f43be0b1f835ed3dc41d1f2b3e0caf7fac252c8eb4c150667d48207fa92ea5f0a7455","up":true},{"one":"c57ea182bdb42ba9b0870b5c870e467f52693e5c0df752fb6eb0dfbacce7763f73caee10db40f4fd90f19f504ee586eaf9da41f5ee93ee515d885fec99374116","other":"54b3c57a4adf4dbaf31b85ed1b8dccd6249faa16dd96dd230189f47f57970caeed36627cc8e1b0794707418d580f5bd6001c07be6a79216695f1253db24926bb","up":false},{"one":"28d3232c43de54ffdaf08f97b334c012738648b04e2876c7e751a2e352aaf4d550d6efa976c5a8edbfa8e88b9d04a0fca492b81c3756ef673ab74d34182ca711","other":"17917fa4da06068b587c17899569dcc768b9cd2c27117a4ed67aab26a7e70cf8d32b881db258061ffd89a332a3b29bfd963d8e171a06c3e208ba0de1c42a2b39","up":true},{"one":"352407b42726dcd1aacc46a912ed8124b8b6a3da4e33dab742e40aa2452953d35dc8f42eddc76695ae2317e9f15dde2cd21be4ce826934695ad1847455661d1b","other":"df4c3505e09e1baa88470117b964e758c94f77a4546489ab5ab7f4aebfdce424729ace8867475715fb68f05c66c9674a5767549e266c4fadd1c703ddd735908f","up":false},{"one":"ce0a09bb6fe4c9c93c3dbd800ca9c9ac0714f26a8f8dac2149b6ce7a9011912a5621ea2e45de35c4d31dfe5add00558fdba5dd21acf2d81ba391e82b5b3a5804","other":"7b5c0e81c7f4e3ae29d745f6028cfa10b29a16a9c261b65fb8dd05d6eccc634612ad5d3029c8e9f39863a2cdb2682c25f090139bf5c4950e25647e39dcb40e63","up":true},{"one":"72e30d4562673c5c8fb03709d93f73322747858d723b7eb5ef2fbb88e0331252946b7e93ffe434fcb599c4fff57800afb29e6c60a719f18f49dba541c3591c6e","other":"4a030ebcb1a59230759d25a3c87daed22906b520d55a78eab2083bb52358ddc3a5d2d7c3265e6c54a990bf32d0dacb85905a4173d72ac18fcd74c43ecb8635c5","up":false},{"one":"2e42f845d0393d1682add54ee30b60a953ed283e75d347bc6719ae0e91f6676282e7960f1fd52e5803d6b341fb3582c724b4f9cfd7bce9ce85f13ca480c7e72e","other":"f54335964d9b4eb9813eb05f40ef1c523bbf0faac5a04c4737467d590fb6b55c7fa1fc5d4d32c5491d8766b9be6fdfd3ebdb25c5ffe1719f36c86ddf87ae3a85","up":true},{"one":"352407b42726dcd1aacc46a912ed8124b8b6a3da4e33dab742e40aa2452953d35dc8f42eddc76695ae2317e9f15dde2cd21be4ce826934695ad1847455661d1b","other":"0c14dd51a56130c51009e3ce47c96b2afef26b7e86cfca65d8a9bae1abef13b3a7a192b422d894c39e24ab00be412d166a3571cc259ff4462d4ad8925a153766","up":false},{"one":"e98a08e8e3544727f5ee27f4465375a67ffba490fcdbfe7bfdc909f6b68bd279f776c65d38c2ccfc33079f852f76349c94d68fc6989c0d981f22333f036a4bb5","other":"1c2f7ce55a6e38487f3b3fe6083a79f914cd6d7e4aee8f5d56b4a61b3eb584e128c56998db0e13e775edee3adacf54f09960a041dab3daa80a4f8a3b42760c1c","up":true},{"one":"1b063741c76fe65e62b4eae42751319d0cce66f22dde9f1cf83d6cca249a0e65bc7f6f22597697362fadd226222fb3847f8e146961969d1b4c9f7e475389cd8e","other":"be514f5f17f3177235acb24112b578edf0e373c469073226e547d18080905fd062d572be18e943f13bf9fcf5871e89ceb630a1b848a0e370ef8ef8c6d997a363","up":true},{"one":"ce0a09bb6fe4c9c93c3dbd800ca9c9ac0714f26a8f8dac2149b6ce7a9011912a5621ea2e45de35c4d31dfe5add00558fdba5dd21acf2d81ba391e82b5b3a5804","other":"5142eea687de4248b2184e9896b245563117648e7a156255d9a7ae730313d5d383db3be1125b5accd7e743c2a5d8c3289ec559ef7cbb803b9e82cd49bb213d9f","up":true},{"one":"beec648d79437a5d7b4140ced45d82d035c6f64f9c67c58386703811d97c3846787eaf274d2298df809475f0b7519df696563cb8e9a5fb0a9cc419ab13fa8d41","other":"d7a319f69013b8375e64d19f015547462c84565b882337998f9e669c5fadd3d2ecf6374109903003e09f5d453424b5c7fdf52163d2cc8084cf81f94844946b63","up":true},{"one":"a7378ee34876af17c6cd94a69b6b741ec7891ff5375bc4241d48608d047455ed48e6baae80ee88d4710c69ae615cf195cee26c94b54de1bb935628ce1e3a723a","other":"74d84cfdaf32cd4cc67771f29878f1365120bd65cc14848008d5386a81f495bf88eb4132fa38a2cc109ae1e7f02c9b97597ab9d1a9c19c945e710ab9df07cdcd","up":true},{"one":"adfba6d883cacbb141cd8c59ee04d7e5d520f1ce31a81e5db2d8b2380bf801c1fe4b265a66b71f9643d13a41cb1f6fb4b83399be786da4b6e171b6784bc56e49","other":"76cbf9fc0f3517fb615fa96104780218e85d064ee5a1d518f3b78f4dbebf144df38c427445fdd6c9b436489c00ff9497d747a8fd70f380f95601d59e52e021e8","up":true},{"one":"a7378ee34876af17c6cd94a69b6b741ec7891ff5375bc4241d48608d047455ed48e6baae80ee88d4710c69ae615cf195cee26c94b54de1bb935628ce1e3a723a","other":"ce0a09bb6fe4c9c93c3dbd800ca9c9ac0714f26a8f8dac2149b6ce7a9011912a5621ea2e45de35c4d31dfe5add00558fdba5dd21acf2d81ba391e82b5b3a5804","up":true},{"one":"a7378ee34876af17c6cd94a69b6b741ec7891ff5375bc4241d48608d047455ed48e6baae80ee88d4710c69ae615cf195cee26c94b54de1bb935628ce1e3a723a","other":"109556abac422a912ecffec0d8796f8f16e92e8f95cecf72dc89e97a8bf1fd37aad3c66aa3cf134acade6d065c31821f977171d5c5463305b57ce3eee99a7ab4","up":true},{"one":"9db1f94d74a00d1e5e2a391f1bcddf16b6d0670a2c6d91d946d38112c58634444b6fea8e8c05ab4b73bacdd62a0b575f6fb8729978edc216c7842b177b9f9cd9","other":"57fb1bb32bb2b1a87e44c6a7557e9c47c2032d107bcb0e34acd9ffd54d5d3df5701232db16f62f7549ba2721021898b03160b1dc5201e79606648c1dbc4a373b","up":true},{"one":"420b9c90584651c5a3fe3c16aa377444a321dca934f8a097d01a616554067feabebf2fdc8d2a25797f29a8fef30d5e2c82f8e85b20f509a880367b9b0ccdea47","other":"df54af3bae257d437c5657905484e0d72e9560c46f8ba6b3437730234e05259b404cca40b0831e911605ff8a68a19e8fd7e958069ec8b40595928892f4fa220c","up":true},{"one":"c83985973a9564ade7d90aa54911ac57077600676a1d27292d98e058bf1315887bad84ccd708cb7f52a695a1405fb7d491d7ca2ae9caa3ff58a5ad78ce4dc9d9","other":"fe8ac5d33cd8ab6a1dad9567cdfb89b431a5c4f4a584fc608b92e7dfd06f70988e71e2f11f9fda9ee797c9ffba83bc085939fdf2522dde39f28202be92650566","up":false},{"one":"e2a27dcdee1f89fa362a85c4397840cd8be4ad8d1b9ccb23188c303bcab7619f38772f71385922d090390973b62fb8249efc103f71bc761041bcb3880ec0b935","other":"2f903b2fd4f9432b7d91b5c3e4c7ee3cb9c56fe7efc4baff0edd06fc75e4b7492f2c3c929755746df59c9f95d437a12ba40ac138d08f5bc7aa091f49f3b852c2","up":true},{"one":"fde7705f5013c3b6b76a35505c1e3d57c033a337f2a71e912ec3a3d2da8e113bd7c36d94908357e9f7654660621f647ad8c66b0126dfe91dbfa3b8c7bd2183d3","other":"e267e71c2dcdbe5a500b23444d2d4037ea15afba8f4f2b1c0e54a274450404fbee6fa5439f7cddf4ba1aa28fa93e434b01c239add58e30a5423ca3a481584d6b","up":true},{"one":"9db1f94d74a00d1e5e2a391f1bcddf16b6d0670a2c6d91d946d38112c58634444b6fea8e8c05ab4b73bacdd62a0b575f6fb8729978edc216c7842b177b9f9cd9","other":"e6779e3bbecf81dde8b27d652ed2726c45c205db0d0405c4580014a4c91d739830276f77079108c98ac516ffa00194e77a0795f7140bdf36069b6475e58213f9","up":true},{"one":"855bdf057f4a6b095e2000ada199447b5b4f2f8d78d2ecbaa0ff1fbf761788870ee999266ad3b26efa02be1a46a4d92ac0debb85a2ceab3442394ee7d99e5355","other":"3b570117addeec03c2694baf28e246f91907268fe665c6c90356120332794258ee57a60853c19e9fe25d042ca42a5be7fe0797d84199174de8132f1ef4a9349b","up":true},{"one":"2ca05ffc0ad771e1e045a47f1c0a79ce374a25e3c0e53c2a80d67e7479677003f62880251a83a5074f1c9651d828f1ff7e352935a9df141c1eb75a0c59b00a8b","other":"9b59b76dc61223c7b37083b0ebdda22d3599563b3e3986f5db9d5b12f8c806cbdeb2345454efe957cbfa11eea9c7896aefd9a461210524805452ca100a9ea431","up":false},{"one":"453779010ed7c59761da47ccd8869d3fa8349795e57edb9eea416c0712301ea622c7683858e309d19ab137ddb0edef161d0d00a361abeecf0628c3ffabc629ea","other":"049a2b0ab4d49789dbbe1837e2d2ee5220a9401729ea87ab29385b24d79cdce255c3d2b5de6484d49ca6ce07bd41832598260c0a8c290e01d133d77f066f2f99","up":true},{"one":"855bdf057f4a6b095e2000ada199447b5b4f2f8d78d2ecbaa0ff1fbf761788870ee999266ad3b26efa02be1a46a4d92ac0debb85a2ceab3442394ee7d99e5355","other":"2ddd49fae11d8bd2e7e75a481be267fa846f51cc1160bc326aeea51c542323ff444909de11e2731e835140bc0b1b32020e1e73fa652511a381222bf0aebc4081","up":true},{"one":"e2a27dcdee1f89fa362a85c4397840cd8be4ad8d1b9ccb23188c303bcab7619f38772f71385922d090390973b62fb8249efc103f71bc761041bcb3880ec0b935","other":"ff6f94005d1df7677600069764855c1c2aa0543cbe9f480f8feefec76c49d9e2c7bb2d8e38c89e9430f53f8b593d93f143c45985a56a5a32c736128214c95eda","up":false},{"one":"759f46661056bcbb30c7706c9fb87e22a30feb523bd53ae5d18db043efa45b49a2b8982abebdd598fe0912a05896390ec2eabe5e160cbafc0771990708ad8c28","other":"453779010ed7c59761da47ccd8869d3fa8349795e57edb9eea416c0712301ea622c7683858e309d19ab137ddb0edef161d0d00a361abeecf0628c3ffabc629ea","up":true},{"one":"a7507aa5665e165ab2e2a07def272f0677f9d6d35bb82268a34214384e7d8ef7635a299368752e63cfd02d4e60231076baf23cfa10d17492e55181b391ecf335","other":"ea57884dd42aec5a76eab43483bf7c4ae2c19eebf365013731de64494d10a3b4cfe34c86c79437f9012bc8cf6bd761435eefadec17600f4b9e4bc234532d6282","up":true},{"one":"a7378ee34876af17c6cd94a69b6b741ec7891ff5375bc4241d48608d047455ed48e6baae80ee88d4710c69ae615cf195cee26c94b54de1bb935628ce1e3a723a","other":"40bdac599b00e9c41ad6476ee415c33d9c17c5aa672692c2404e523b29dc315da929a86874bed87fd9009871805d1dbf3098e7a817193e3b08a6eee66346da79","up":true},{"one":"a7507aa5665e165ab2e2a07def272f0677f9d6d35bb82268a34214384e7d8ef7635a299368752e63cfd02d4e60231076baf23cfa10d17492e55181b391ecf335","other":"9c30ad8c85adc7bb52ddcfab2e661cc3a854a689eaa59128d35129d02cd5b0f8da4a44cdd33934a8e2c8fab1760c16d6f2e1c5eb227dc819e85624e63343c069","up":true},{"one":"4314b0b04331973ed29a58843951f144ac3d09bd5d57b6cd9aaff9b73a7b2ec81e344a3e4ece462bd2081b837a06310e787ef3bb889dabad46fe7efd394c8342","other":"5e86f39cf8338ba098a85d41e601a303fde311662b216ad32a2b7bfaf2b2b6dd1af3775784b39f2d85ac5fac96f05f3abdd8a2bd28ba16d939725fd6a33ae1b6","up":true},{"one":"3d2df188704eeac09c8b291bf275a73888199a231c832c51dbc3d746968d4b51a7d5eae0c7c9b8c8e19f5e28d38c375e01abefa343f31dbe221deb837ab8a0df","other":"adfba6d883cacbb141cd8c59ee04d7e5d520f1ce31a81e5db2d8b2380bf801c1fe4b265a66b71f9643d13a41cb1f6fb4b83399be786da4b6e171b6784bc56e49","up":true},{"one":"9ce6b9decb69d66075993e903a0727ec109a04335634616097c0e60b08f94f764634fa00891b1070f6ea1ce896bc7d11d3aea92a00f281f902d960894cef296f","other":"84abcbc7b5598ecfd91ceace0927921a5a3404fdb274fc2a2549abbede5f8e4f62c15688a4dc9a2d80262c45970c88898da245c6eb779f327a81d53a17bbc74c","up":true},{"one":"ed6c793eb4565aa9d883a76fad6c97ad0b878b9ef0235e11e89db1af25a9653205f725c6ea258b84bde134f1a6437c6d109b859d17509e5016c4ab98be59032a","other":"deb7af800cd20a647335f0feff5bfb3e182f99f4c2d1ade10da36ecfdbac3b5fba4e8f0a4595443fe395b44af3a95617669850944655def85d57cc81c5682a3b","up":true},{"one":"bcf8e831821a5bca359fb824c7dc4d66906de82f3663a0a853d96880a8ca0bdddcceb1b66dd1f13f75ee20fde50fc9de545bc25767f228baee910e0dbfa8cc27","other":"f039df8a3206e6e17eee8e95010038c450cb4cc0b5580ed5795d4c21802e1e9d360f4528bdca794f457932b1d6a818862ec847357a861c488332ef6d9480daa6","up":true},{"one":"2ac522ebfa49d37f86c6270ad4cdad0e766493f0e463b18c9906c70fbd2e5c6ff6b0d5879de6e3894418370636963a78b0c0cf087a8684c2ca30c9c736e49228","other":"657d5370319128d24d925b41065eb619409d63ec6280975d78877a4028287463f6442f5206dd703569a05b2b542ad8bbb99803da265408208d6356a26d283d08","up":true},{"one":"4e95fb8943ef6502fa470870a7ace4ca11e18589bd2073167543a922317b35e40b5068934d07e56c8fdd23354dfad51fd2899db854f189841f02b5914cd97749","other":"0f9f7e2dce4ca266c3ac0ec3a8854200b54487f5308e3db418461aeb5f67c81d332619b6441b468e480941e63100ed1b263e7adc20689dc3dcda578bfca538fa","up":true},{"one":"17917fa4da06068b587c17899569dcc768b9cd2c27117a4ed67aab26a7e70cf8d32b881db258061ffd89a332a3b29bfd963d8e171a06c3e208ba0de1c42a2b39","other":"4ee37acec2178ef120166265aaa2b64b09b315fb53861405ef46f2503c273eb9692e9cb4c2e67a8652254d430fd6e02dd3fe4cded20bb231a9fb834d292b0b24","up":true},{"one":"7865b82e44add2cea6ebcbaba9c152184331a2940fe73f6f9bb940bda8a59ab4cf4760894b9cadcaa54e36fbb712ad619346a49a85e32cdf2b53cda1ac1e0658","other":"57fb1bb32bb2b1a87e44c6a7557e9c47c2032d107bcb0e34acd9ffd54d5d3df5701232db16f62f7549ba2721021898b03160b1dc5201e79606648c1dbc4a373b","up":false},{"one":"d4b7c787981abec24353c7d496661692233797e3758189bf909a69fe87935bf6da0940daa4f12e81f20c5e88f70b472113688b71a0ae2f91a73ee0e6ff4c8591","other":"032b9bf2f59f15571821611d3ee541aa748c86d47fbe5f049fd0069be53e5d7c41991d82957e9c727654c3aa73ec94997c03d8a6c1d2007c9bb1a703f6215158","up":true},{"one":"5566111b7f14d8ec83ba6456488f3fc5c7e2c86bf406dead33b814e1ee9b569d34015a4d88226b7e28fff7784395c086d106287cbbc80acfe75b05cd6e12903d","other":"94088fe273f76e62ca4e43c095ad12215b4ae4c59942328b3985416fb19bbda0cacc143a49eff3fb644ad53a19d3f043260e43dbb70a0aa9c15829c21cecd3c7","up":true},{"one":"1c2f7ce55a6e38487f3b3fe6083a79f914cd6d7e4aee8f5d56b4a61b3eb584e128c56998db0e13e775edee3adacf54f09960a041dab3daa80a4f8a3b42760c1c","other":"bcf8e831821a5bca359fb824c7dc4d66906de82f3663a0a853d96880a8ca0bdddcceb1b66dd1f13f75ee20fde50fc9de545bc25767f228baee910e0dbfa8cc27","up":true},{"one":"ddaf3f8478501cda872c056c72063eb64d5b871fc5fff70704872802289dd2d348f73bc342b7f148a90cfaae2448ebf16fea196be9df891dc71a57fb410d59dd","other":"485825745d97654cbb92a14e0cd1078691d3c28f4d82b1046284b676a42b44ca58eb43474e45e415d3bd3f3c383f9a1a3365821ed7ba6a9f2603b29d58031dc7","up":true},{"one":"b080891d4ba6d3ab224984360597f9c555bd1367630f5420bfaf230419a05b2be58bebf1554e53eb4c0da81cfb66d4f7697dd65143f11841ff62d8a0d82b6b67","other":"7ac5b07eb555af3bb4ca3f0f4b45204d43cc3798c244435909b97d9a32fc3abf0b50666e260e046bce826a7a102a92d389f8f39c5311e83bb34beddac29d50e3","up":true},{"one":"b26f7c0113a5ae885f7c0e608aea7022a9c8bfc40c5643e60b2ba7343ff09c5be0bc08be34dde3c6b85fea192a46d4764770c12cbaa233df4231a1b99627ef9d","other":"0a4eec7b0e05da799aca5b36d9e2530f2a89d1426b1fcb7d8f9a662df8a8b5b763767a20db3c9c63e0bd13c2a6e16d3ba8f03baf84f5e5d24917b3f211d9bcfc","up":true},{"one":"829b074b70d757da6aa00f7bace3cf1b5d2d4eeadb7f370c1a85374a01a70b54ac53d747267e386f3b41e6d790fecdd6e74b8f89745501ee82439a66ea54443a","other":"990b1db3ab1390219e8866d39fa4441bb5bb89ad786b3e255771869fcd08906dcf63f34007481769c7462edbcc665acc0a552e3733360b8d8c310c9321a5550f","up":true},{"one":"57cd4c0048b459192ee46e19ec7df777e600f256e0dc8c3019431eb7bec3c020b9504ec7aea3dba8188658ca5b830ec40af6a8540ce10e04badc6c695d009271","other":"0c14dd51a56130c51009e3ce47c96b2afef26b7e86cfca65d8a9bae1abef13b3a7a192b422d894c39e24ab00be412d166a3571cc259ff4462d4ad8925a153766","up":true},{"one":"88d5c5fe61ee1e6fa5878e0eaa13bdabaa0ec3d38a5d25b95a467da7627424f25fb5d30535aa0a5ad01c16fe2598dbf570b78cc152a7f4ef66d46fc9ae43592f","other":"f38a9d792173a29c61389f5d84c005d78eac6e750659aad42e2d6df883f04eb3126b2c38fac95076eeed455b2031aaf694143922aa93a2d50412a2454dc56e28","up":true},{"one":"2e409baefbd821485a151993356730e5989810d581e68190fbaa142799c9335bcf98310ad188fed10ae6eb6e2e789730393e509962ec5c0fef0342d72ed088d9","other":"657d5370319128d24d925b41065eb619409d63ec6280975d78877a4028287463f6442f5206dd703569a05b2b542ad8bbb99803da265408208d6356a26d283d08","up":true},{"one":"b53078000796f1cdb04dfeac424d5e3e37e30f00bd5bebf9a9ea0525c62917612b3a8f508df6bea59e3c7e4cd1aa530841f9a8af54e44f5617a13dee2c6ff007","other":"c9cd9dfb9f90a7948ac5a42c7bd63263f2eef6e1d85547559f7d2ecbf5f9cd1eab051b8e9e661b573c275d84091a44e73f6fc6bcc91dcdb674bd5d939190fc01","up":true},{"one":"9db1f94d74a00d1e5e2a391f1bcddf16b6d0670a2c6d91d946d38112c58634444b6fea8e8c05ab4b73bacdd62a0b575f6fb8729978edc216c7842b177b9f9cd9","other":"b137cf2291b530a39516d882200848e7f27a2710e0839b4d25b4f367bea6a0c3aaef8c7c7851c00a2945adcd819ea0508610afc1f453b8bc512b7b4d4faacdf3","up":true},{"one":"97981f4b825620985b746c85824d7a4d307ee25d60a72c2b7de4b1d4f3b1c002652adc3045842d350f849789e410a0357a0b42fa637a1b4fc9d39e44f8a674d7","other":"ff1e34fd51953ed641b431aa657da21cb4c81d23e4eaa13c9cce526f1f1b34593d41f9b87a0e10387fe400c623638677c0efab15dbd1014a0ccc11f9ec92c417","up":true},{"one":"385168340139236a0e0f537fa693122db9fa02a377c96f31aae54718e92624fc0288164877e63616651565e055c53f7074ab2fdd18a837da6faf644941305bf0","other":"beec648d79437a5d7b4140ced45d82d035c6f64f9c67c58386703811d97c3846787eaf274d2298df809475f0b7519df696563cb8e9a5fb0a9cc419ab13fa8d41","up":false},{"one":"e06a789a7f6988e1ba5e8358b6cd4292555c7f9f7f0dda6fc01cc26d24e49a8c1ad694423ad74aec6d80f4b99e2bedc49b6a5f2670744cedee3a3e1848e6dd07","other":"caaf695c76cf7c047d3f3bfe019d01618e4871cee8ff3f347913da815bbcde145771486f916a44d03f59ea9bc217f169fd0c0765fda3f9b9b28d02a522e180b4","up":true},{"one":"fe8ac5d33cd8ab6a1dad9567cdfb89b431a5c4f4a584fc608b92e7dfd06f70988e71e2f11f9fda9ee797c9ffba83bc085939fdf2522dde39f28202be92650566","other":"8c6d77833bf1a98beabe7a92d985d13d52fb2e50768719ffbc6fce21ea676802a074b6e620b3ef80e12fad04f94a3c288d91df9716a6cfae09ef073b9dc1f2cb","up":true},{"one":"c8b0dba45104fc7c7dff3ce078a0d3f5ade6198bb4656e2bee8076387929133e5ef2bd293b130a9d4f6a6974ca17e8b4a8f406d1219880f1e0f99c65c63af5a4","other":"535f93057d46c4aae0902546550880be0b5ba67dca12350117d471d67f4f2b3f7bdff29bdc918767974c465df8fa1afa6bd6c29c0a36d51f71c4183673d906f3","up":true},{"one":"934a5fe1b91c1891ef4df7f67c027e0eb115d4c2ca4a1b76a135ebd4315c4fb835d6625223194e6a134407b38b0d3928fbc7bc924a3c6a538989a6cf200bf4bd","other":"92d6ef729992f0de886076e5f8cdc42cbbd70b29e79c25e0b3d22b6575d3d2508d47b42f581e335455483d43625bce4e55f88cab9ff2073ee8dab746357864fd","up":true},{"one":"f039df8a3206e6e17eee8e95010038c450cb4cc0b5580ed5795d4c21802e1e9d360f4528bdca794f457932b1d6a818862ec847357a861c488332ef6d9480daa6","other":"76cbf9fc0f3517fb615fa96104780218e85d064ee5a1d518f3b78f4dbebf144df38c427445fdd6c9b436489c00ff9497d747a8fd70f380f95601d59e52e021e8","up":true},{"one":"7b35c856916eb3fc1b1f451667e240b95aff8f4731cc0f6743740923081ff1ddf2eec81bdccf4691a7bcc053d23eacfc15809c384a73448f618317bf605bd1cd","other":"f54335964d9b4eb9813eb05f40ef1c523bbf0faac5a04c4737467d590fb6b55c7fa1fc5d4d32c5491d8766b9be6fdfd3ebdb25c5ffe1719f36c86ddf87ae3a85","up":true},{"one":"80d997b87856099d844187d3d1fa40846ded652a62c1611b35919c2543915b64ff62476636488556f678e436ea26fcc40db7c6b6bbcb78f590d61c1ff0e424b5","other":"ae4e21e1587a8475afd299e00ca7085c7bf2a44c2c64a3068f12223d9202b0125094385319034691ec26b497ec9cf18fe8c0839224bac1b84279410241cef979","up":true},{"one":"48a5e01e06e297dc1c640ac9601171495bd70fea461c60e7e6e2532695e45fcf68183c2e58b5e6931a6c1c094f5331efbd7f2d93d5f84efdec5a35afa2124438","other":"485825745d97654cbb92a14e0cd1078691d3c28f4d82b1046284b676a42b44ca58eb43474e45e415d3bd3f3c383f9a1a3365821ed7ba6a9f2603b29d58031dc7","up":true},{"one":"7b1e20217f594f87350542df31ff5ae8a635679bac7962d49c97e02190c644b673d03e7eba2626b45ca7ebf98d8a972dadbba02c18a8d2cbfc3e7a4cced5b4b7","other":"b137cf2291b530a39516d882200848e7f27a2710e0839b4d25b4f367bea6a0c3aaef8c7c7851c00a2945adcd819ea0508610afc1f453b8bc512b7b4d4faacdf3","up":true},{"one":"57fb1bb32bb2b1a87e44c6a7557e9c47c2032d107bcb0e34acd9ffd54d5d3df5701232db16f62f7549ba2721021898b03160b1dc5201e79606648c1dbc4a373b","other":"df54af3bae257d437c5657905484e0d72e9560c46f8ba6b3437730234e05259b404cca40b0831e911605ff8a68a19e8fd7e958069ec8b40595928892f4fa220c","up":true},{"one":"0deda014fa3c0bc8f37d853e1448f95f56f97048c28797d72258fd3ba2f1f776ae11566197466596356cd172847ab02a89f4cf047e58383249fb2a4cd69b6206","other":"ca1aff0d847c6fdacb623ad9078a0885b3208614fea20d5ff11779779b486bf5e9c794aacf848d3c2d58cfcc1eda8356df82f5fbdd0a5236beffe8e6042848c4","up":true},{"one":"fd4968df03d767a223bf7e4dbe26b5c27048298df40e81cad50b344fb3e6837965f2646dab7ffb2891a5c507343ed84bb8bbe403287b51dae538d58fcb6e7623","other":"f9ffe87c52ff4c22bd9696af32e0a9d34bb81fb84d9d8bf5aafe2ef9696e7b3d6460bf2a93aecb066133f53416bde841a02d6967bd06e3d4a714f3b2c123a947","up":true},{"one":"155e4879643a472420012e040a87dbff776fc1976814c0c6cd0d5e157f0d0baac04aa7f2535786c09acc2700547383d2119b64a6f62115f1aff1708738844d8c","other":"7bbb3f3ed51cf84c077806fbd6d3578e105bc32aa6043da188793f066ad6df383a9f7cc0bd3124f4c887704bd188d480ce264fcdf178905bbda3b270927ea138","up":true},{"one":"d3105ede6c21bc643d523afcd1309a5dcf03f70797a92f167c3a19f86ae98882fe1a9d4094d7a3dee4a0833b8075b6c3e9aaa7f4879dc47bb388c3ae85522288","other":"e06a789a7f6988e1ba5e8358b6cd4292555c7f9f7f0dda6fc01cc26d24e49a8c1ad694423ad74aec6d80f4b99e2bedc49b6a5f2670744cedee3a3e1848e6dd07","up":false},{"one":"5566111b7f14d8ec83ba6456488f3fc5c7e2c86bf406dead33b814e1ee9b569d34015a4d88226b7e28fff7784395c086d106287cbbc80acfe75b05cd6e12903d","other":"76cbf9fc0f3517fb615fa96104780218e85d064ee5a1d518f3b78f4dbebf144df38c427445fdd6c9b436489c00ff9497d747a8fd70f380f95601d59e52e021e8","up":false},{"one":"eaca77d20c4ad6b87649eba21b750a4b1a2c575e06bc42679d18fce16fea15212e9a7408c16f3b24d8dfd1e397314637e72e292845d09534a39035bd9203ee9e","other":"083e67bb19e30d14e4df6d2483367d6659d9b56744d53d9cf7fd15954c327e1bc88a5d0db8833634e1dad7209164451f8934b59f76b5990059261abfd650519a","up":true},{"one":"beec648d79437a5d7b4140ced45d82d035c6f64f9c67c58386703811d97c3846787eaf274d2298df809475f0b7519df696563cb8e9a5fb0a9cc419ab13fa8d41","other":"53df9cce9b0169e58ced53a123d1d8f6e8fdcfb4c2d781ecbb91bb7c8eba36946dd9d21c749259769825d8a6b3faa6bb87c8c6085a522f8a3e376061f59144d9","up":true},{"one":"1090e9d89cb278a30063a5396d9ba795d3bbc237c76915a6fb7d23aa1822c8535d2fccc44cc8cd2acec68444c0bf1bdf5195ebb9f3cad8dac3d94a4d9c0e5309","other":"f9ffe87c52ff4c22bd9696af32e0a9d34bb81fb84d9d8bf5aafe2ef9696e7b3d6460bf2a93aecb066133f53416bde841a02d6967bd06e3d4a714f3b2c123a947","up":true},{"one":"4b784f072b7c96c30612767425f552e30e45157e70139dfbe0ae4ff86dc31601adec60f8a3ad9747b02b5219073d8813af9b09d59eaf7ddb7ee24856aff6fa8f","other":"9bbbfac8be4a000f51a4ce8d024d2595b5d491afec0138922dddfde5ef62c664040c2e9304cc6b7bc688233b5d0c4644b8c8793227c078285a3ab894ef0497a3","up":true},{"one":"329145e75496cecb5f5c8f00313a52ddd8c0e8cd27ef1b2bc1b2b56e4d4089aaf5a7a3c4d9a40bdb92483fa05bd24d1cd0fd51883e30439dffa0fc855e1a7cd0","other":"ca1aff0d847c6fdacb623ad9078a0885b3208614fea20d5ff11779779b486bf5e9c794aacf848d3c2d58cfcc1eda8356df82f5fbdd0a5236beffe8e6042848c4","up":true},{"one":"315b8a1711f680c2eaa607e35ef7a9e19c2b61721af8a7e08f1325dde1fe33cf1f47b3cc4acf12d541631041cf1b42754875fd1c9b66ee32797b72b9f7711256","other":"aacff366e601e072a2113add9020e19b6612f3e85b6e607fdc8cc1b6991f43be0b1f835ed3dc41d1f2b3e0caf7fac252c8eb4c150667d48207fa92ea5f0a7455","up":true},{"one":"657d5370319128d24d925b41065eb619409d63ec6280975d78877a4028287463f6442f5206dd703569a05b2b542ad8bbb99803da265408208d6356a26d283d08","other":"5bf29c02f07faf7ae8e46389e1b98df4f5e88c9316b5151685e6ae7b4e622cf171ff09f996aaa8ad846643b3bfcbd1ad96cdc249afccce439bb5c55246b95801","up":true},{"one":"b3316f4fd7dec218a52331f25d17a2faf0f2a417808d7dbb80038154abfbcd2d78da074837b648cff28675f4aa0d65ddb7d15abf3d7e0391d401e313a3ef24a2","other":"979838eaefcff456cf1cd9c47ea46854704f5757d8d7ab907019bc422b01af4d62252579bf045d143fab491b0bab823190e2782a457fbf51aa99ae17ec9e145f","up":true},{"one":"60725e8d0e9333636e598dd666f459b4be898d9abc095ee2c1db289673e7e969b50e2093956fef5a2f1d23e2040159bbabaaeab17fc6dbbac3f6acab766e9e60","other":"57b47f692f4d69a5d2c9c193680eb4ccb5a6c574662df0138504a549f3ea74f20c5b866ac4d9e76c4b49c83f5fd692ead928ea20dfcf643a11a1c1e841c0ec42","up":true},{"one":"28d3232c43de54ffdaf08f97b334c012738648b04e2876c7e751a2e352aaf4d550d6efa976c5a8edbfa8e88b9d04a0fca492b81c3756ef673ab74d34182ca711","other":"ca1aff0d847c6fdacb623ad9078a0885b3208614fea20d5ff11779779b486bf5e9c794aacf848d3c2d58cfcc1eda8356df82f5fbdd0a5236beffe8e6042848c4","up":false},{"one":"f54335964d9b4eb9813eb05f40ef1c523bbf0faac5a04c4737467d590fb6b55c7fa1fc5d4d32c5491d8766b9be6fdfd3ebdb25c5ffe1719f36c86ddf87ae3a85","other":"5526d86ba9df651091d88460a9bedb9cedb957d452a635e1db46b9fed78082022adec0047cd7485956a4ecbb0e18107595de0de3c35242527cd302bf74a19260","up":false},{"one":"72e30d4562673c5c8fb03709d93f73322747858d723b7eb5ef2fbb88e0331252946b7e93ffe434fcb599c4fff57800afb29e6c60a719f18f49dba541c3591c6e","other":"cb94a8270d0050378116b5815ff17dafbe20f5303839c4fd57b981d4687a4b145e4bccec7e9af9b9475005930148ffbfa97781a0762c8e9f352dc95565fc8732","up":true},{"one":"e6779e3bbecf81dde8b27d652ed2726c45c205db0d0405c4580014a4c91d739830276f77079108c98ac516ffa00194e77a0795f7140bdf36069b6475e58213f9","other":"c903c5ee3d9cd65bea3ea777e39282c33e1349d945411fb2f16321bf582c2f400956a98fbafe5873fc5f6f6a9a051df5da7e94cbd340f935abe80f91e79ef875","up":true},{"one":"732393b99c490c76fa45e3e404ee095f2fa445fcc123af7ac8ab1d2fdd7cf2483f5b82bb818bd8a82b1a3b73e63bcc2c83d8f24d9aad9afe36503735e7967be7","other":"1b6cad4f9851cc584c5d1405f976bb51a52e27ef4525847df543dcca65ca5eb1ef229dcc68ccbaaf00ab1e044cb5990dd213c805bdb4adcceb6fa70b5c61fdb4","up":true},{"one":"8d4920d6e3a6717699b5a3af068cbdfc16858d7e393d158d41b1b5f345b47129eef89e1d055386c518f400b134678c21590f0317dea3436d4cef60f45455cf12","other":"c665a6b1b7ad39b86bd4b1fe38b7ee95a0fbb1db15e91381ec9e5a235e33b69ffdc92c60dafd74b7b4dafca1b000e9274bf045abe5b93b1a9c2b31ae071a9898","up":true},{"one":"b4a5efa9028b2d196855393892f79993c2812d02b758f98813ddf82c5d943faf6d66eff811cc5a51936c118f4c768c0d13b54902095e040c602761e63c08655e","other":"6b01079463ec2f649db8634cb7a596261c79a8f714d954c772528e0547b017f8ce405e4a0ea9d32270848180e0f77b8c0b022cf95c85e777626edd4d24ea21d2","up":false},{"one":"53df9cce9b0169e58ced53a123d1d8f6e8fdcfb4c2d781ecbb91bb7c8eba36946dd9d21c749259769825d8a6b3faa6bb87c8c6085a522f8a3e376061f59144d9","other":"60725e8d0e9333636e598dd666f459b4be898d9abc095ee2c1db289673e7e969b50e2093956fef5a2f1d23e2040159bbabaaeab17fc6dbbac3f6acab766e9e60","up":true},{"one":"7f357b8d81bc2e5c6fcb081f23a42b3e2439f050d45c45851994a268d1c71fcb1f39f8c3f75ce921d3fbf80fc0e73f0b9609d72001dc4a6b65b526d312a4f43a","other":"1090e9d89cb278a30063a5396d9ba795d3bbc237c76915a6fb7d23aa1822c8535d2fccc44cc8cd2acec68444c0bf1bdf5195ebb9f3cad8dac3d94a4d9c0e5309","up":true},{"one":"2b70e5ffcc0bb1c4f8acc09dd1016e67c9c96c92d091ad481efbb71bd8b2a5a5869c6d668617a9b2cbfe91baf5edfe150c3824c84d90899a974099071d171441","other":"3e488a7208ce0e097ce47fc6651a13e95cae137d1a054a09b04d2f59d45faa2594a8c3b395e77ad1a3c2edcd827dda73c0c97dbaa6d9519a79184a0aca01ac4b","up":true},{"one":"3612863ce0456c91785a829bf5c9d2b2fb97dda083a1847e5a4ebaa6fce1260faf4d1eb374c2225431a82774163835fb59c8cb0fa9fc0969eab5410c71109cc2","other":"92d6ef729992f0de886076e5f8cdc42cbbd70b29e79c25e0b3d22b6575d3d2508d47b42f581e335455483d43625bce4e55f88cab9ff2073ee8dab746357864fd","up":true},{"one":"855bdf057f4a6b095e2000ada199447b5b4f2f8d78d2ecbaa0ff1fbf761788870ee999266ad3b26efa02be1a46a4d92ac0debb85a2ceab3442394ee7d99e5355","other":"4fe37f2dfb03707c90a6fe91dbcfd7497db70ffc20043091d50e1cee573210c144e8749340f2c3cb70fe8fc51b317d49e8734dc51ce64b3cdccdd639ae35d1ae","up":true},{"one":"58cfb20d3da3641e0ad529b9edbd4b590a8d1dc9d1ed7b44ed3187dba9260bd7c732fc10981f5b9bffd31d362cb05150173618aa36138984431d94a323a9b313","other":"59b53f8a562bee519276e0eeccfcf8c975d3102f5d0cccf5abcce291a8a5bb817c04604f123686177a50a03b9d7559ac469962d0159d1d93e4ce58a304d04b55","up":false},{"one":"bcf8e831821a5bca359fb824c7dc4d66906de82f3663a0a853d96880a8ca0bdddcceb1b66dd1f13f75ee20fde50fc9de545bc25767f228baee910e0dbfa8cc27","other":"e98a08e8e3544727f5ee27f4465375a67ffba490fcdbfe7bfdc909f6b68bd279f776c65d38c2ccfc33079f852f76349c94d68fc6989c0d981f22333f036a4bb5","up":false},{"one":"22010c9829626a6892258b09cb3f3edc3f21382fb487b5dbf0dd20e198e37e26134aab850e30337f398d1491b5126839aeb1953ec144bc19aeb889c832f67c6a","other":"8d4920d6e3a6717699b5a3af068cbdfc16858d7e393d158d41b1b5f345b47129eef89e1d055386c518f400b134678c21590f0317dea3436d4cef60f45455cf12","up":true},{"one":"807340e5fdf6c21a56ef2fd158c32e92201206ca85fcc147165a408f7a735964afd47c397e663610ac53870ae722c0317291732b0422f8aeedae783d9c730218","other":"e06a789a7f6988e1ba5e8358b6cd4292555c7f9f7f0dda6fc01cc26d24e49a8c1ad694423ad74aec6d80f4b99e2bedc49b6a5f2670744cedee3a3e1848e6dd07","up":true},{"one":"5526d86ba9df651091d88460a9bedb9cedb957d452a635e1db46b9fed78082022adec0047cd7485956a4ecbb0e18107595de0de3c35242527cd302bf74a19260","other":"b870935867183bbfb84add16b9f56c02c834b7042fc24ce6bcb2a7f174e6d2239357a00be4272c1ef05c7f9baf5a9f16b53bc18328a9b7aca8540c2916805b57","up":true},{"one":"6f60ef501b41f9049419b033ae8d793a18067bdcd60347537b0dc3873bdd9a2d10d24909cca7c39781765746128c2165596f6537a94f58279523faee71f9c51d","other":"c57ea182bdb42ba9b0870b5c870e467f52693e5c0df752fb6eb0dfbacce7763f73caee10db40f4fd90f19f504ee586eaf9da41f5ee93ee515d885fec99374116","up":true},{"one":"049a2b0ab4d49789dbbe1837e2d2ee5220a9401729ea87ab29385b24d79cdce255c3d2b5de6484d49ca6ce07bd41832598260c0a8c290e01d133d77f066f2f99","other":"11d560045536e9d1b0b1b9e8944e00f0ca7f1e6788c9fdb51061820bbb3008ead92bb7836621bf58da7035c87a28328faecb4cb2e3cdb9d7fa4f45790e6bf352","up":true},{"one":"a7507aa5665e165ab2e2a07def272f0677f9d6d35bb82268a34214384e7d8ef7635a299368752e63cfd02d4e60231076baf23cfa10d17492e55181b391ecf335","other":"7865b82e44add2cea6ebcbaba9c152184331a2940fe73f6f9bb940bda8a59ab4cf4760894b9cadcaa54e36fbb712ad619346a49a85e32cdf2b53cda1ac1e0658","up":true},{"one":"fde7705f5013c3b6b76a35505c1e3d57c033a337f2a71e912ec3a3d2da8e113bd7c36d94908357e9f7654660621f647ad8c66b0126dfe91dbfa3b8c7bd2183d3","other":"8f88c7ec044f758f29bd8d12a5170bd973aec8f6cddbf512b910c4b75a0fec09c5e198bcd65622037f897759db68da2328b4a7ca93585dc9cb62e46d2a6c0864","up":true},{"one":"ddaf3f8478501cda872c056c72063eb64d5b871fc5fff70704872802289dd2d348f73bc342b7f148a90cfaae2448ebf16fea196be9df891dc71a57fb410d59dd","other":"2ab9513899c3c829b6284e56bf2b9862dd0156ec052b58615dba77d450dac642e534ec36ae5d3234262aff54e19f99856e908b9d8c1da660a7834a445610715b","up":false},{"one":"016f8f4619a16a07fbde5a18e362158d696e4d9f104a77787f26e32a25cd7d278256f8e0db865c488a99511ec27a5eddd5ebbd1c1397fa7f8db111062e5fe959","other":"1b063741c76fe65e62b4eae42751319d0cce66f22dde9f1cf83d6cca249a0e65bc7f6f22597697362fadd226222fb3847f8e146961969d1b4c9f7e475389cd8e","up":true},{"one":"2f1967b4410ea2ea8fbaf46771ba82c2846d00aecdb6f873aceae33ab38f72d0a2c2dc6046d3034f514efd090d42011d48e9ab0cb4e3caa2b49a96ef732215a1","other":"b4fd11306b1416a9bcf4719578976188e104b8c5028b9abd3214d257446b97b70a22e6c00934d80caddde15e8e4d16af03bb399583047983fba373d8313226b7","up":false},{"one":"81288bb0584b7ffc1546043e052e1df10fd5371b35dedd0bb42ec5b30ce69b741b2f7857af5984d4754b39d7253575fde9298504999b78380ef602d391c4bb1d","other":"315b8a1711f680c2eaa607e35ef7a9e19c2b61721af8a7e08f1325dde1fe33cf1f47b3cc4acf12d541631041cf1b42754875fd1c9b66ee32797b72b9f7711256","up":true},{"one":"baa5924e1547c177011285d292aa161a15e5ff282da2cd0afb83c9caffb07bdbb3662c227fa7b26e6dc8be9b8863e647eb5f8ce81640532f8f5c9a7f36557e63","other":"2ddd49fae11d8bd2e7e75a481be267fa846f51cc1160bc326aeea51c542323ff444909de11e2731e835140bc0b1b32020e1e73fa652511a381222bf0aebc4081","up":true},{"one":"4f5ab12b9c5127c16739ad0d4f51adce90ba6736cd096eb185ea632789f4b26f1ebabdea4fd3b39dda5409ece6c2d92fd469cf4aecf9d29453e3e042c19b893b","other":"7b5c0e81c7f4e3ae29d745f6028cfa10b29a16a9c261b65fb8dd05d6eccc634612ad5d3029c8e9f39863a2cdb2682c25f090139bf5c4950e25647e39dcb40e63","up":true},{"one":"420b9c90584651c5a3fe3c16aa377444a321dca934f8a097d01a616554067feabebf2fdc8d2a25797f29a8fef30d5e2c82f8e85b20f509a880367b9b0ccdea47","other":"e6779e3bbecf81dde8b27d652ed2726c45c205db0d0405c4580014a4c91d739830276f77079108c98ac516ffa00194e77a0795f7140bdf36069b6475e58213f9","up":true},{"one":"c903c5ee3d9cd65bea3ea777e39282c33e1349d945411fb2f16321bf582c2f400956a98fbafe5873fc5f6f6a9a051df5da7e94cbd340f935abe80f91e79ef875","other":"b6a998dea59194cc60ce97c7c9702368411889cb6905516b23f41cc5116fba8d0f237d418318eb0c333cad18003c0e9a6bd8c99080520771f2bad640e2e5ec1c","up":true},{"one":"9ce6b9decb69d66075993e903a0727ec109a04335634616097c0e60b08f94f764634fa00891b1070f6ea1ce896bc7d11d3aea92a00f281f902d960894cef296f","other":"e67e495385e7cacfe659b40d1ba94d4b1ff55eada70a4d9740a9e452fbf221672bd0a897b940e2a6bed71e2a16867fe45bf0ea0015435ac6d815690e263b1899","up":false},{"one":"ed6c793eb4565aa9d883a76fad6c97ad0b878b9ef0235e11e89db1af25a9653205f725c6ea258b84bde134f1a6437c6d109b859d17509e5016c4ab98be59032a","other":"535f93057d46c4aae0902546550880be0b5ba67dca12350117d471d67f4f2b3f7bdff29bdc918767974c465df8fa1afa6bd6c29c0a36d51f71c4183673d906f3","up":true},{"one":"4e95fb8943ef6502fa470870a7ace4ca11e18589bd2073167543a922317b35e40b5068934d07e56c8fdd23354dfad51fd2899db854f189841f02b5914cd97749","other":"2f903b2fd4f9432b7d91b5c3e4c7ee3cb9c56fe7efc4baff0edd06fc75e4b7492f2c3c929755746df59c9f95d437a12ba40ac138d08f5bc7aa091f49f3b852c2","up":false},{"one":"389b5c1a805f87427e6d647ec5488342a3f7d700615943d5ad98ca5c111f33c7ee007970b4d3e475892095c0d5a79b7ed52d12598398818159000d4b9b719126","other":"23f9bdc82efbf57d3d40a1f2617d0311678fb4a3d6a50cb7e608c649bb618124a76c7ffd17387de963e1cd28d2bd5a61c98613f6e009a8a2a90d989827b35de0","up":true},{"one":"3b570117addeec03c2694baf28e246f91907268fe665c6c90356120332794258ee57a60853c19e9fe25d042ca42a5be7fe0797d84199174de8132f1ef4a9349b","other":"fde7705f5013c3b6b76a35505c1e3d57c033a337f2a71e912ec3a3d2da8e113bd7c36d94908357e9f7654660621f647ad8c66b0126dfe91dbfa3b8c7bd2183d3","up":true},{"one":"adfba6d883cacbb141cd8c59ee04d7e5d520f1ce31a81e5db2d8b2380bf801c1fe4b265a66b71f9643d13a41cb1f6fb4b83399be786da4b6e171b6784bc56e49","other":"f039df8a3206e6e17eee8e95010038c450cb4cc0b5580ed5795d4c21802e1e9d360f4528bdca794f457932b1d6a818862ec847357a861c488332ef6d9480daa6","up":false},{"one":"453779010ed7c59761da47ccd8869d3fa8349795e57edb9eea416c0712301ea622c7683858e309d19ab137ddb0edef161d0d00a361abeecf0628c3ffabc629ea","other":"3d2df188704eeac09c8b291bf275a73888199a231c832c51dbc3d746968d4b51a7d5eae0c7c9b8c8e19f5e28d38c375e01abefa343f31dbe221deb837ab8a0df","up":false},{"one":"e2a27dcdee1f89fa362a85c4397840cd8be4ad8d1b9ccb23188c303bcab7619f38772f71385922d090390973b62fb8249efc103f71bc761041bcb3880ec0b935","other":"3e488a7208ce0e097ce47fc6651a13e95cae137d1a054a09b04d2f59d45faa2594a8c3b395e77ad1a3c2edcd827dda73c0c97dbaa6d9519a79184a0aca01ac4b","up":false},{"one":"b26f7c0113a5ae885f7c0e608aea7022a9c8bfc40c5643e60b2ba7343ff09c5be0bc08be34dde3c6b85fea192a46d4764770c12cbaa233df4231a1b99627ef9d","other":"ca1aff0d847c6fdacb623ad9078a0885b3208614fea20d5ff11779779b486bf5e9c794aacf848d3c2d58cfcc1eda8356df82f5fbdd0a5236beffe8e6042848c4","up":true},{"one":"be514f5f17f3177235acb24112b578edf0e373c469073226e547d18080905fd062d572be18e943f13bf9fcf5871e89ceb630a1b848a0e370ef8ef8c6d997a363","other":"016f8f4619a16a07fbde5a18e362158d696e4d9f104a77787f26e32a25cd7d278256f8e0db865c488a99511ec27a5eddd5ebbd1c1397fa7f8db111062e5fe959","up":true},{"one":"829b074b70d757da6aa00f7bace3cf1b5d2d4eeadb7f370c1a85374a01a70b54ac53d747267e386f3b41e6d790fecdd6e74b8f89745501ee82439a66ea54443a","other":"07c63ca5d0309e30d1ab12e7fc142e6d37904b552639cfa97850161491f28f20d87e0304be29357bcfc2ff52fc52fd0d4f6e6011ebb239cced8b5c8dad7abf45","up":false},{"one":"97981f4b825620985b746c85824d7a4d307ee25d60a72c2b7de4b1d4f3b1c002652adc3045842d350f849789e410a0357a0b42fa637a1b4fc9d39e44f8a674d7","other":"beec648d79437a5d7b4140ced45d82d035c6f64f9c67c58386703811d97c3846787eaf274d2298df809475f0b7519df696563cb8e9a5fb0a9cc419ab13fa8d41","up":true},{"one":"385168340139236a0e0f537fa693122db9fa02a377c96f31aae54718e92624fc0288164877e63616651565e055c53f7074ab2fdd18a837da6faf644941305bf0","other":"d9bbcdfd949010e6b2cbf6d0f34b27593ae410bdc1838876aeca35679571fe431d040a5ab085c0a77f111688bebed891da3587277cd794702437cb20d6aa4256","up":false},{"one":"48a5e01e06e297dc1c640ac9601171495bd70fea461c60e7e6e2532695e45fcf68183c2e58b5e6931a6c1c094f5331efbd7f2d93d5f84efdec5a35afa2124438","other":"bd1a7c63fca9e1fcc67d7fd62670beefe2bce483cf1dc1233ee85eb90db607917cd9a5d7170b10e80b925a20e2af2c54d286b01805ac34967410859f4f03da09","up":true},{"one":"80d997b87856099d844187d3d1fa40846ded652a62c1611b35919c2543915b64ff62476636488556f678e436ea26fcc40db7c6b6bbcb78f590d61c1ff0e424b5","other":"5142eea687de4248b2184e9896b245563117648e7a156255d9a7ae730313d5d383db3be1125b5accd7e743c2a5d8c3289ec559ef7cbb803b9e82cd49bb213d9f","up":false},{"one":"0deda014fa3c0bc8f37d853e1448f95f56f97048c28797d72258fd3ba2f1f776ae11566197466596356cd172847ab02a89f4cf047e58383249fb2a4cd69b6206","other":"17917fa4da06068b587c17899569dcc768b9cd2c27117a4ed67aab26a7e70cf8d32b881db258061ffd89a332a3b29bfd963d8e171a06c3e208ba0de1c42a2b39","up":false},{"one":"57cd4c0048b459192ee46e19ec7df777e600f256e0dc8c3019431eb7bec3c020b9504ec7aea3dba8188658ca5b830ec40af6a8540ce10e04badc6c695d009271","other":"70ee3c7e02a123f78345d41c386e413f06b51f1ab346c2c472891eed7dd26a1f14e213a0f4f2d872859b9b535936a6d9b072d2604456f76221a422710411822f","up":true},{"one":"3d2df188704eeac09c8b291bf275a73888199a231c832c51dbc3d746968d4b51a7d5eae0c7c9b8c8e19f5e28d38c375e01abefa343f31dbe221deb837ab8a0df","other":"049a2b0ab4d49789dbbe1837e2d2ee5220a9401729ea87ab29385b24d79cdce255c3d2b5de6484d49ca6ce07bd41832598260c0a8c290e01d133d77f066f2f99","up":false},{"one":"b2538d4edfa736bfe2cc21326a44ce62f716b3480eac93584a2233b69c98883a2bb255f246218a58cecab1d0d176e6d1fbba9782fd70d4603e01742299b9ea9c","other":"cb94a8270d0050378116b5815ff17dafbe20f5303839c4fd57b981d4687a4b145e4bccec7e9af9b9475005930148ffbfa97781a0762c8e9f352dc95565fc8732","up":true},{"one":"ff6f94005d1df7677600069764855c1c2aa0543cbe9f480f8feefec76c49d9e2c7bb2d8e38c89e9430f53f8b593d93f143c45985a56a5a32c736128214c95eda","other":"b3316f4fd7dec218a52331f25d17a2faf0f2a417808d7dbb80038154abfbcd2d78da074837b648cff28675f4aa0d65ddb7d15abf3d7e0391d401e313a3ef24a2","up":true},{"one":"57fb1bb32bb2b1a87e44c6a7557e9c47c2032d107bcb0e34acd9ffd54d5d3df5701232db16f62f7549ba2721021898b03160b1dc5201e79606648c1dbc4a373b","other":"e6779e3bbecf81dde8b27d652ed2726c45c205db0d0405c4580014a4c91d739830276f77079108c98ac516ffa00194e77a0795f7140bdf36069b6475e58213f9","up":true},{"one":"fd4968df03d767a223bf7e4dbe26b5c27048298df40e81cad50b344fb3e6837965f2646dab7ffb2891a5c507343ed84bb8bbe403287b51dae538d58fcb6e7623","other":"f5c1215a84a56d52f92ca0dc3a32df98c98a9c2ea2e9a34560210c16de1b440d20d043c8c25955dda8c22e55e92ddb49fd82e8b9b84072aabaa755a229bb19f4","up":false},{"one":"657d5370319128d24d925b41065eb619409d63ec6280975d78877a4028287463f6442f5206dd703569a05b2b542ad8bbb99803da265408208d6356a26d283d08","other":"57b47f692f4d69a5d2c9c193680eb4ccb5a6c574662df0138504a549f3ea74f20c5b866ac4d9e76c4b49c83f5fd692ead928ea20dfcf643a11a1c1e841c0ec42","up":true},{"one":"e98a08e8e3544727f5ee27f4465375a67ffba490fcdbfe7bfdc909f6b68bd279f776c65d38c2ccfc33079f852f76349c94d68fc6989c0d981f22333f036a4bb5","other":"be514f5f17f3177235acb24112b578edf0e373c469073226e547d18080905fd062d572be18e943f13bf9fcf5871e89ceb630a1b848a0e370ef8ef8c6d997a363","up":false},{"one":"8ca3b63cb84f1e9883d82809a9b6777ec1029ecda96fe93b4d494ee9cbefcad13f381b3e480136e542e01054fe1ede66c65db84a0009871ce49383db461c8438","other":"27d9048707a89f1a61e44fdae523c0128f2a7050308bd3cfefa6c3e03040a0e22f11ab41275f22b8706e6695ab93320e2af35179d772581db5f49f960750f2f7","up":false},{"one":"4b784f072b7c96c30612767425f552e30e45157e70139dfbe0ae4ff86dc31601adec60f8a3ad9747b02b5219073d8813af9b09d59eaf7ddb7ee24856aff6fa8f","other":"732393b99c490c76fa45e3e404ee095f2fa445fcc123af7ac8ab1d2fdd7cf2483f5b82bb818bd8a82b1a3b73e63bcc2c83d8f24d9aad9afe36503735e7967be7","up":false},{"one":"e06a789a7f6988e1ba5e8358b6cd4292555c7f9f7f0dda6fc01cc26d24e49a8c1ad694423ad74aec6d80f4b99e2bedc49b6a5f2670744cedee3a3e1848e6dd07","other":"3dfd733dde9414af916625ab981777ff1ad7ca0f6d1e4e7d9e2739969e21182fd13d85e281868653e7325b20069356b11524b54143c47fd3955a911cf7325ad4","up":false},{"one":"485825745d97654cbb92a14e0cd1078691d3c28f4d82b1046284b676a42b44ca58eb43474e45e415d3bd3f3c383f9a1a3365821ed7ba6a9f2603b29d58031dc7","other":"385168340139236a0e0f537fa693122db9fa02a377c96f31aae54718e92624fc0288164877e63616651565e055c53f7074ab2fdd18a837da6faf644941305bf0","up":true},{"one":"4314b0b04331973ed29a58843951f144ac3d09bd5d57b6cd9aaff9b73a7b2ec81e344a3e4ece462bd2081b837a06310e787ef3bb889dabad46fe7efd394c8342","other":"7ac5b07eb555af3bb4ca3f0f4b45204d43cc3798c244435909b97d9a32fc3abf0b50666e260e046bce826a7a102a92d389f8f39c5311e83bb34beddac29d50e3","up":false},{"one":"ba21a373781966135d6225adae024a3f3e421b852f72f8b0569cb92fcff87c33f7e5b799a509b8eff6ec6dc46a9b17d5bae1e91ec7c54c0c712d893d54b140fa","other":"b35f418c7935cc54278e90978c3ef1521ab91daeaf9f1ebc1cd25211611ade091cac4e1f009d71059279d507322a4536501980ac0dd44caddc52fd4c593879f7","up":true},{"one":"f915e2398aa5d4370de87504dd76c21a7d0be2581c2ab55b7a47743f1bbaef36384eaacec22760f1e914ceac9d96a10c3d66eb27475ef444e77fee979e6e88cb","other":"8f88c7ec044f758f29bd8d12a5170bd973aec8f6cddbf512b910c4b75a0fec09c5e198bcd65622037f897759db68da2328b4a7ca93585dc9cb62e46d2a6c0864","up":false},{"one":"80d997b87856099d844187d3d1fa40846ded652a62c1611b35919c2543915b64ff62476636488556f678e436ea26fcc40db7c6b6bbcb78f590d61c1ff0e424b5","other":"920a301186bdf665a721676ece7c180413369ea6eff7537f42049d9eb409f28cc864099590116e885f57368959fb2cff7003697d9b1515e68bf3fa7aee0278ef","up":false},{"one":"27d9048707a89f1a61e44fdae523c0128f2a7050308bd3cfefa6c3e03040a0e22f11ab41275f22b8706e6695ab93320e2af35179d772581db5f49f960750f2f7","other":"65e954e60837bda10654480b227fa3bcc6e63356c52079002a27e836cd82ae2934ba77da60080e4b9f2d9324b982b24959bfd9624302e6c330408381054b43e9","up":true},{"one":"60725e8d0e9333636e598dd666f459b4be898d9abc095ee2c1db289673e7e969b50e2093956fef5a2f1d23e2040159bbabaaeab17fc6dbbac3f6acab766e9e60","other":"2e409baefbd821485a151993356730e5989810d581e68190fbaa142799c9335bcf98310ad188fed10ae6eb6e2e789730393e509962ec5c0fef0342d72ed088d9","up":true},{"one":"66beee3968dbcf3addc6feaf070a4e3e82b5bb164fb72f40add89f732c12e8d0a31a7ee1f1e24a4674e4dfc9a4912b02c17ce3c224d257d78b7156544d6507dc","other":"11d560045536e9d1b0b1b9e8944e00f0ca7f1e6788c9fdb51061820bbb3008ead92bb7836621bf58da7035c87a28328faecb4cb2e3cdb9d7fa4f45790e6bf352","up":true},{"one":"22010c9829626a6892258b09cb3f3edc3f21382fb487b5dbf0dd20e198e37e26134aab850e30337f398d1491b5126839aeb1953ec144bc19aeb889c832f67c6a","other":"2245f3bf1a3b4e92f912affc75f757cf648b20474c11ffe947884f216b8f24f9dcb6e6a0358a4061b8517478ec15027e185b2f05a777573b4940375bf4aaf2be","up":false},{"one":"62dab8b21640e1b44dea452dd7e7de93f27a44840da72d56b11aa96e8463f3a4bb15e75a954d19fc897ae0030b16181d271b79d8198b7cffcddaa9ffcfdcce73","other":"54b3c57a4adf4dbaf31b85ed1b8dccd6249faa16dd96dd230189f47f57970caeed36627cc8e1b0794707418d580f5bd6001c07be6a79216695f1253db24926bb","up":false},{"one":"7808fb798d22e78fb1d39b87ddf99a503f820993bc64149eca9e81d9d58fc1adea60d8de14a4f06cb89f3190c0ef0c5e182621a14c9361ccb7e0cee667599cc3","other":"b870935867183bbfb84add16b9f56c02c834b7042fc24ce6bcb2a7f174e6d2239357a00be4272c1ef05c7f9baf5a9f16b53bc18328a9b7aca8540c2916805b57","up":false},{"one":"17917fa4da06068b587c17899569dcc768b9cd2c27117a4ed67aab26a7e70cf8d32b881db258061ffd89a332a3b29bfd963d8e171a06c3e208ba0de1c42a2b39","other":"329145e75496cecb5f5c8f00313a52ddd8c0e8cd27ef1b2bc1b2b56e4d4089aaf5a7a3c4d9a40bdb92483fa05bd24d1cd0fd51883e30439dffa0fc855e1a7cd0","up":false},{"one":"ff6f94005d1df7677600069764855c1c2aa0543cbe9f480f8feefec76c49d9e2c7bb2d8e38c89e9430f53f8b593d93f143c45985a56a5a32c736128214c95eda","other":"b2538d4edfa736bfe2cc21326a44ce62f716b3480eac93584a2233b69c98883a2bb255f246218a58cecab1d0d176e6d1fbba9782fd70d4603e01742299b9ea9c","up":true},{"one":"ba21a373781966135d6225adae024a3f3e421b852f72f8b0569cb92fcff87c33f7e5b799a509b8eff6ec6dc46a9b17d5bae1e91ec7c54c0c712d893d54b140fa","other":"3612863ce0456c91785a829bf5c9d2b2fb97dda083a1847e5a4ebaa6fce1260faf4d1eb374c2225431a82774163835fb59c8cb0fa9fc0969eab5410c71109cc2","up":false},{"one":"c332fe1f9b6e25f72c7150631ffa6e0929ff6eeab5d17aa45eaf669bdde869cf404505ae990a529aa3ca797cd0a96f31cc41431a5d4a163132be566f91623c08","other":"032b9bf2f59f15571821611d3ee541aa748c86d47fbe5f049fd0069be53e5d7c41991d82957e9c727654c3aa73ec94997c03d8a6c1d2007c9bb1a703f6215158","up":false},{"one":"4e95fb8943ef6502fa470870a7ace4ca11e18589bd2073167543a922317b35e40b5068934d07e56c8fdd23354dfad51fd2899db854f189841f02b5914cd97749","other":"ff6f94005d1df7677600069764855c1c2aa0543cbe9f480f8feefec76c49d9e2c7bb2d8e38c89e9430f53f8b593d93f143c45985a56a5a32c736128214c95eda","up":false},{"one":"f915e2398aa5d4370de87504dd76c21a7d0be2581c2ab55b7a47743f1bbaef36384eaacec22760f1e914ceac9d96a10c3d66eb27475ef444e77fee979e6e88cb","other":"97981f4b825620985b746c85824d7a4d307ee25d60a72c2b7de4b1d4f3b1c002652adc3045842d350f849789e410a0357a0b42fa637a1b4fc9d39e44f8a674d7","up":false},{"one":"2ca05ffc0ad771e1e045a47f1c0a79ce374a25e3c0e53c2a80d67e7479677003f62880251a83a5074f1c9651d828f1ff7e352935a9df141c1eb75a0c59b00a8b","other":"5e86f39cf8338ba098a85d41e601a303fde311662b216ad32a2b7bfaf2b2b6dd1af3775784b39f2d85ac5fac96f05f3abdd8a2bd28ba16d939725fd6a33ae1b6","up":true},{"one":"28d3232c43de54ffdaf08f97b334c012738648b04e2876c7e751a2e352aaf4d550d6efa976c5a8edbfa8e88b9d04a0fca492b81c3756ef673ab74d34182ca711","other":"71f89efcf939294bb94ac669c8afd00def58c8dfad519c226adfa068692d588ef797116d42aa146b9d34f3be35ec7c014022640ab3c0f1f9034e44ab1a26e246","up":false},{"one":"fd4968df03d767a223bf7e4dbe26b5c27048298df40e81cad50b344fb3e6837965f2646dab7ffb2891a5c507343ed84bb8bbe403287b51dae538d58fcb6e7623","other":"8dd8ad560af84bec579cadb33d51711aa61b6ed22705010336df5a71a94591173b25e869457429c4a199b205fce8e73530e28203e18b971c2001715e610f152a","up":false},{"one":"657d5370319128d24d925b41065eb619409d63ec6280975d78877a4028287463f6442f5206dd703569a05b2b542ad8bbb99803da265408208d6356a26d283d08","other":"062e0ca43a1885c4a7ab2a5169790f9081e3e9a2dfa286b8cc592d5ccbf13d7a82b72d23361a19026d04fcf41b752ea320d98359d770aedfcee626e21c3494b3","up":false},{"one":"389b5c1a805f87427e6d647ec5488342a3f7d700615943d5ad98ca5c111f33c7ee007970b4d3e475892095c0d5a79b7ed52d12598398818159000d4b9b719126","other":"2f360209383d6de4ebd3b4abaf77796520b8654270b03f2151eac4a01b4417d7e0668c1f9ad30c20ff49aa8a0ab33dba5e6095619d1cf04b7af841722ab773da","up":false},{"one":"3b570117addeec03c2694baf28e246f91907268fe665c6c90356120332794258ee57a60853c19e9fe25d042ca42a5be7fe0797d84199174de8132f1ef4a9349b","other":"b3316f4fd7dec218a52331f25d17a2faf0f2a417808d7dbb80038154abfbcd2d78da074837b648cff28675f4aa0d65ddb7d15abf3d7e0391d401e313a3ef24a2","up":true},{"one":"5566111b7f14d8ec83ba6456488f3fc5c7e2c86bf406dead33b814e1ee9b569d34015a4d88226b7e28fff7784395c086d106287cbbc80acfe75b05cd6e12903d","other":"6ab6ec15635b2fda22542c99df0a3313ad4583ba0fb3f31b8f314e3ecad446d3fb0fdfcd2be9b08374b1a7e049fb68e69e8dacdd13f1df5007a656f6b11adc5b","up":false},{"one":"81288bb0584b7ffc1546043e052e1df10fd5371b35dedd0bb42ec5b30ce69b741b2f7857af5984d4754b39d7253575fde9298504999b78380ef602d391c4bb1d","other":"7808fb798d22e78fb1d39b87ddf99a503f820993bc64149eca9e81d9d58fc1adea60d8de14a4f06cb89f3190c0ef0c5e182621a14c9361ccb7e0cee667599cc3","up":false},{"one":"97981f4b825620985b746c85824d7a4d307ee25d60a72c2b7de4b1d4f3b1c002652adc3045842d350f849789e410a0357a0b42fa637a1b4fc9d39e44f8a674d7","other":"9b618ad34d0dfe0fccbd5b8af365cbcdbb43e802df5f23e91c20d21f3ead6169d52bf0db7e5e111abef630c9853419fb33a88cf111d8507b8708208b5d65e35e","up":false},{"one":"4f5ab12b9c5127c16739ad0d4f51adce90ba6736cd096eb185ea632789f4b26f1ebabdea4fd3b39dda5409ece6c2d92fd469cf4aecf9d29453e3e042c19b893b","other":"5142eea687de4248b2184e9896b245563117648e7a156255d9a7ae730313d5d383db3be1125b5accd7e743c2a5d8c3289ec559ef7cbb803b9e82cd49bb213d9f","up":true},{"one":"420b9c90584651c5a3fe3c16aa377444a321dca934f8a097d01a616554067feabebf2fdc8d2a25797f29a8fef30d5e2c82f8e85b20f509a880367b9b0ccdea47","other":"a7507aa5665e165ab2e2a07def272f0677f9d6d35bb82268a34214384e7d8ef7635a299368752e63cfd02d4e60231076baf23cfa10d17492e55181b391ecf335","up":false},{"one":"22010c9829626a6892258b09cb3f3edc3f21382fb487b5dbf0dd20e198e37e26134aab850e30337f398d1491b5126839aeb1953ec144bc19aeb889c832f67c6a","other":"352407b42726dcd1aacc46a912ed8124b8b6a3da4e33dab742e40aa2452953d35dc8f42eddc76695ae2317e9f15dde2cd21be4ce826934695ad1847455661d1b","up":false},{"one":"fde7705f5013c3b6b76a35505c1e3d57c033a337f2a71e912ec3a3d2da8e113bd7c36d94908357e9f7654660621f647ad8c66b0126dfe91dbfa3b8c7bd2183d3","other":"abd8f5a4d700c06ec00684b23d2d25c4df1a9554fcfc57b0ddc3fa476e6a699ba75e1213449f900803f83ab8194c6746664b547202047f35b8b3e216c7147bf8","up":true},{"one":"1090e9d89cb278a30063a5396d9ba795d3bbc237c76915a6fb7d23aa1822c8535d2fccc44cc8cd2acec68444c0bf1bdf5195ebb9f3cad8dac3d94a4d9c0e5309","other":"fd4968df03d767a223bf7e4dbe26b5c27048298df40e81cad50b344fb3e6837965f2646dab7ffb2891a5c507343ed84bb8bbe403287b51dae538d58fcb6e7623","up":false},{"one":"2b70e5ffcc0bb1c4f8acc09dd1016e67c9c96c92d091ad481efbb71bd8b2a5a5869c6d668617a9b2cbfe91baf5edfe150c3824c84d90899a974099071d171441","other":"0f9f7e2dce4ca266c3ac0ec3a8854200b54487f5308e3db418461aeb5f67c81d332619b6441b468e480941e63100ed1b263e7adc20689dc3dcda578bfca538fa","up":false},{"one":"baa5924e1547c177011285d292aa161a15e5ff282da2cd0afb83c9caffb07bdbb3662c227fa7b26e6dc8be9b8863e647eb5f8ce81640532f8f5c9a7f36557e63","other":"3b570117addeec03c2694baf28e246f91907268fe665c6c90356120332794258ee57a60853c19e9fe25d042ca42a5be7fe0797d84199174de8132f1ef4a9349b","up":false},{"one":"88d5c5fe61ee1e6fa5878e0eaa13bdabaa0ec3d38a5d25b95a467da7627424f25fb5d30535aa0a5ad01c16fe2598dbf570b78cc152a7f4ef66d46fc9ae43592f","other":"109556abac422a912ecffec0d8796f8f16e92e8f95cecf72dc89e97a8bf1fd37aad3c66aa3cf134acade6d065c31821f977171d5c5463305b57ce3eee99a7ab4","up":false},{"one":"807340e5fdf6c21a56ef2fd158c32e92201206ca85fcc147165a408f7a735964afd47c397e663610ac53870ae722c0317291732b0422f8aeedae783d9c730218","other":"292c78c8e41606e98428096bc6f4609a7aa48e5c4d17eecc64d65faae4a7270b0c15f0cd74274015688ea0a9aff34f215c29118222e362a29c8d637963973a55","up":true},{"one":"3e488a7208ce0e097ce47fc6651a13e95cae137d1a054a09b04d2f59d45faa2594a8c3b395e77ad1a3c2edcd827dda73c0c97dbaa6d9519a79184a0aca01ac4b","other":"65e954e60837bda10654480b227fa3bcc6e63356c52079002a27e836cd82ae2934ba77da60080e4b9f2d9324b982b24959bfd9624302e6c330408381054b43e9","up":true},{"one":"66d0c5da973d9dd65350ae1ec63776872cdb7ded6afb6f51ae82259f6fd35e884375d15de290625f02ed2e5cdc3f591decb45e5fc64d5b0f835a216fd196f5a3","other":"e6779e3bbecf81dde8b27d652ed2726c45c205db0d0405c4580014a4c91d739830276f77079108c98ac516ffa00194e77a0795f7140bdf36069b6475e58213f9","up":true},{"one":"b137cf2291b530a39516d882200848e7f27a2710e0839b4d25b4f367bea6a0c3aaef8c7c7851c00a2945adcd819ea0508610afc1f453b8bc512b7b4d4faacdf3","other":"1f6d803a4ca186463772850ca0901fb920af7e74fdd2480c3c368fa707838ee91bbcfb57d5e3510c802b9b85f2d954f04c9b675414274bdaebae6488dcf94c10","up":false},{"one":"9ce6b9decb69d66075993e903a0727ec109a04335634616097c0e60b08f94f764634fa00891b1070f6ea1ce896bc7d11d3aea92a00f281f902d960894cef296f","other":"a99852c5bf08ea4713af9cade5343d1259bfb90401aca7fcff18c58cd56a98804dd16c61fea71039c0ac31b9bbbb9dc5aeaf0c2f074d3365e88d17031802d636","up":true},{"one":"453779010ed7c59761da47ccd8869d3fa8349795e57edb9eea416c0712301ea622c7683858e309d19ab137ddb0edef161d0d00a361abeecf0628c3ffabc629ea","other":"9b618ad34d0dfe0fccbd5b8af365cbcdbb43e802df5f23e91c20d21f3ead6169d52bf0db7e5e111abef630c9853419fb33a88cf111d8507b8708208b5d65e35e","up":false},{"one":"c903c5ee3d9cd65bea3ea777e39282c33e1349d945411fb2f16321bf582c2f400956a98fbafe5873fc5f6f6a9a051df5da7e94cbd340f935abe80f91e79ef875","other":"9bd4f0adb9a966cc5ba632f1b540fe9cd6c8e39fe1a041b315697679cfb04b735952062ce057d456677cc34a84301f26bb727a4ab2646fee734f80a22c620746","up":false},{"one":"9c30ad8c85adc7bb52ddcfab2e661cc3a854a689eaa59128d35129d02cd5b0f8da4a44cdd33934a8e2c8fab1760c16d6f2e1c5eb227dc819e85624e63343c069","other":"e023a51c5bd26e1754d6461345143e94baeac799947579ec7adeccd105de39f85afbceeb5037cfc0b820b9f4446433f034d9e7de7326d45df5a967a8099dbb10","up":false},{"one":"385168340139236a0e0f537fa693122db9fa02a377c96f31aae54718e92624fc0288164877e63616651565e055c53f7074ab2fdd18a837da6faf644941305bf0","other":"9133b0b3c8f680286eae90c3beebc3099a13de38775a3ff2abdeced62d05eb2ced5ac85eac0870156be03101024da5e1d9fbf3e1066ddb3f088221e64149acec","up":false},{"one":"855bdf057f4a6b095e2000ada199447b5b4f2f8d78d2ecbaa0ff1fbf761788870ee999266ad3b26efa02be1a46a4d92ac0debb85a2ceab3442394ee7d99e5355","other":"2a63d875e715c2a43302d32d86d30c7d7faed46c08a67bf488762637216b99dd87333a66df6d9f3a57df863b1f1a219ddbeebb9f3e92e523bd08540a195448ca","up":false},{"one":"48a5e01e06e297dc1c640ac9601171495bd70fea461c60e7e6e2532695e45fcf68183c2e58b5e6931a6c1c094f5331efbd7f2d93d5f84efdec5a35afa2124438","other":"934a5fe1b91c1891ef4df7f67c027e0eb115d4c2ca4a1b76a135ebd4315c4fb835d6625223194e6a134407b38b0d3928fbc7bc924a3c6a538989a6cf200bf4bd","up":false},{"one":"829b074b70d757da6aa00f7bace3cf1b5d2d4eeadb7f370c1a85374a01a70b54ac53d747267e386f3b41e6d790fecdd6e74b8f89745501ee82439a66ea54443a","other":"9e621c3eb534855ca292efa27a3fbc89b4f05c80a4bc65bcff2f14ff28ef43cbe14137d2fddc6fe2658bb06947d918476b479dde71469b8680e5d8a7a01619b5","up":false},{"one":"ed6c793eb4565aa9d883a76fad6c97ad0b878b9ef0235e11e89db1af25a9653205f725c6ea258b84bde134f1a6437c6d109b859d17509e5016c4ab98be59032a","other":"9ce6b9decb69d66075993e903a0727ec109a04335634616097c0e60b08f94f764634fa00891b1070f6ea1ce896bc7d11d3aea92a00f281f902d960894cef296f","up":false},{"one":"9db1f94d74a00d1e5e2a391f1bcddf16b6d0670a2c6d91d946d38112c58634444b6fea8e8c05ab4b73bacdd62a0b575f6fb8729978edc216c7842b177b9f9cd9","other":"c903c5ee3d9cd65bea3ea777e39282c33e1349d945411fb2f16321bf582c2f400956a98fbafe5873fc5f6f6a9a051df5da7e94cbd340f935abe80f91e79ef875","up":false},{"one":"6b01079463ec2f649db8634cb7a596261c79a8f714d954c772528e0547b017f8ce405e4a0ea9d32270848180e0f77b8c0b022cf95c85e777626edd4d24ea21d2","other":"535f93057d46c4aae0902546550880be0b5ba67dca12350117d471d67f4f2b3f7bdff29bdc918767974c465df8fa1afa6bd6c29c0a36d51f71c4183673d906f3","up":false},{"one":"1c2f7ce55a6e38487f3b3fe6083a79f914cd6d7e4aee8f5d56b4a61b3eb584e128c56998db0e13e775edee3adacf54f09960a041dab3daa80a4f8a3b42760c1c","other":"be514f5f17f3177235acb24112b578edf0e373c469073226e547d18080905fd062d572be18e943f13bf9fcf5871e89ceb630a1b848a0e370ef8ef8c6d997a363","up":false},{"one":"07f25fdeab2b44b2e92fc80fca7de9e4a8547d27a98a54593b3395c270a9ff3f2a5da62a2e8531ce86359f0cdc5b6513b773dfd64cce1b83e47065d9760a2c7e","other":"e6779e3bbecf81dde8b27d652ed2726c45c205db0d0405c4580014a4c91d739830276f77079108c98ac516ffa00194e77a0795f7140bdf36069b6475e58213f9","up":false},{"one":"1bc1d6155ba35d29ea16938994e08df76ebd8f16bd180bd6a9b9d8798d0745889fe72d641dd78bd8ec13526929f7eb5aaa6a388430fa69033d6db581e53c6422","other":"11d560045536e9d1b0b1b9e8944e00f0ca7f1e6788c9fdb51061820bbb3008ead92bb7836621bf58da7035c87a28328faecb4cb2e3cdb9d7fa4f45790e6bf352","up":false},{"one":"a08e47137bf611dfbd20308a22bdd3ca00121386f121d6d712ade86e9a1601a4237766887cd91c8516e20b6e323d2ef49c1c7e177a0afb4c813f0f344daf779b","other":"fde7705f5013c3b6b76a35505c1e3d57c033a337f2a71e912ec3a3d2da8e113bd7c36d94908357e9f7654660621f647ad8c66b0126dfe91dbfa3b8c7bd2183d3","up":false},{"one":"f54335964d9b4eb9813eb05f40ef1c523bbf0faac5a04c4737467d590fb6b55c7fa1fc5d4d32c5491d8766b9be6fdfd3ebdb25c5ffe1719f36c86ddf87ae3a85","other":"6bf9fb6a25521c16c2ebeb6203d046d7dd40f29cc2ddb067c0222ef56d7012d2ee5d037f71f6668ea56767610b2a54c144aed74b7f68d06993cbd52fa1dc7630","up":false},{"one":"c332fe1f9b6e25f72c7150631ffa6e0929ff6eeab5d17aa45eaf669bdde869cf404505ae990a529aa3ca797cd0a96f31cc41431a5d4a163132be566f91623c08","other":"7ac5b07eb555af3bb4ca3f0f4b45204d43cc3798c244435909b97d9a32fc3abf0b50666e260e046bce826a7a102a92d389f8f39c5311e83bb34beddac29d50e3","up":false},{"one":"ea57884dd42aec5a76eab43483bf7c4ae2c19eebf365013731de64494d10a3b4cfe34c86c79437f9012bc8cf6bd761435eefadec17600f4b9e4bc234532d6282","other":"e6779e3bbecf81dde8b27d652ed2726c45c205db0d0405c4580014a4c91d739830276f77079108c98ac516ffa00194e77a0795f7140bdf36069b6475e58213f9","up":false},{"one":"2ac522ebfa49d37f86c6270ad4cdad0e766493f0e463b18c9906c70fbd2e5c6ff6b0d5879de6e3894418370636963a78b0c0cf087a8684c2ca30c9c736e49228","other":"7acddc7fb6ac587b7e343804c768e4291cd28dd2b2b9207dea6ee82360d848a52d84f94e4c49e9c421f4f90e2d24f6291e2358783ab0230e6ecde82e69b4ac52","up":true},{"one":"292c78c8e41606e98428096bc6f4609a7aa48e5c4d17eecc64d65faae4a7270b0c15f0cd74274015688ea0a9aff34f215c29118222e362a29c8d637963973a55","other":"aa9a94d6e4eaaed20113c21752c224e3a052abd3769bd6e832759dbaf5154a943cf094eacdcb0727c2fe51a11bd7fc0793d7d5e3312b0aba89d428a00e1fde0c","up":true},{"one":"0c14dd51a56130c51009e3ce47c96b2afef26b7e86cfca65d8a9bae1abef13b3a7a192b422d894c39e24ab00be412d166a3571cc259ff4462d4ad8925a153766","other":"70ee3c7e02a123f78345d41c386e413f06b51f1ab346c2c472891eed7dd26a1f14e213a0f4f2d872859b9b535936a6d9b072d2604456f76221a422710411822f","up":false},{"one":"fe62314839c93d2f6e3aee984d5f0b321897c6f39e66800d3de8b773baf6f19e0a03cae025df512aea8d5f1b667b6dbb15c192a90a76d3031c14e33e5c16c4f7","other":"485825745d97654cbb92a14e0cd1078691d3c28f4d82b1046284b676a42b44ca58eb43474e45e415d3bd3f3c383f9a1a3365821ed7ba6a9f2603b29d58031dc7","up":false},{"one":"5566111b7f14d8ec83ba6456488f3fc5c7e2c86bf406dead33b814e1ee9b569d34015a4d88226b7e28fff7784395c086d106287cbbc80acfe75b05cd6e12903d","other":"2ddd49fae11d8bd2e7e75a481be267fa846f51cc1160bc326aeea51c542323ff444909de11e2731e835140bc0b1b32020e1e73fa652511a381222bf0aebc4081","up":false},{"one":"7ac5b07eb555af3bb4ca3f0f4b45204d43cc3798c244435909b97d9a32fc3abf0b50666e260e046bce826a7a102a92d389f8f39c5311e83bb34beddac29d50e3","other":"2ca05ffc0ad771e1e045a47f1c0a79ce374a25e3c0e53c2a80d67e7479677003f62880251a83a5074f1c9651d828f1ff7e352935a9df141c1eb75a0c59b00a8b","up":true},{"one":"ae4e21e1587a8475afd299e00ca7085c7bf2a44c2c64a3068f12223d9202b0125094385319034691ec26b497ec9cf18fe8c0839224bac1b84279410241cef979","other":"c73d088ade8756c74832c73542bcdb3e52f670f7a74ad3a7eac2a9e3ece6bd081f782a8e1d3f9a40b9aa9201509110f37fc57fcb10ee1ef3ef07b7eab019782e","up":false},{"one":"fde7705f5013c3b6b76a35505c1e3d57c033a337f2a71e912ec3a3d2da8e113bd7c36d94908357e9f7654660621f647ad8c66b0126dfe91dbfa3b8c7bd2183d3","other":"b3316f4fd7dec218a52331f25d17a2faf0f2a417808d7dbb80038154abfbcd2d78da074837b648cff28675f4aa0d65ddb7d15abf3d7e0391d401e313a3ef24a2","up":true},{"one":"f54335964d9b4eb9813eb05f40ef1c523bbf0faac5a04c4737467d590fb6b55c7fa1fc5d4d32c5491d8766b9be6fdfd3ebdb25c5ffe1719f36c86ddf87ae3a85","other":"70ee3c7e02a123f78345d41c386e413f06b51f1ab346c2c472891eed7dd26a1f14e213a0f4f2d872859b9b535936a6d9b072d2604456f76221a422710411822f","up":false},{"one":"62dab8b21640e1b44dea452dd7e7de93f27a44840da72d56b11aa96e8463f3a4bb15e75a954d19fc897ae0030b16181d271b79d8198b7cffcddaa9ffcfdcce73","other":"2bfba66ec9d63e928d77d455f2e10a14d6213e515099d5db14fa44a8bfc147eb0fa7afa9aaccdc86453c6903b55556059a2e13dd61fc494127d4a3ec173bf9ea","up":false},{"one":"72e30d4562673c5c8fb03709d93f73322747858d723b7eb5ef2fbb88e0331252946b7e93ffe434fcb599c4fff57800afb29e6c60a719f18f49dba541c3591c6e","other":"b080891d4ba6d3ab224984360597f9c555bd1367630f5420bfaf230419a05b2be58bebf1554e53eb4c0da81cfb66d4f7697dd65143f11841ff62d8a0d82b6b67","up":false},{"one":"beec648d79437a5d7b4140ced45d82d035c6f64f9c67c58386703811d97c3846787eaf274d2298df809475f0b7519df696563cb8e9a5fb0a9cc419ab13fa8d41","other":"657d5370319128d24d925b41065eb619409d63ec6280975d78877a4028287463f6442f5206dd703569a05b2b542ad8bbb99803da265408208d6356a26d283d08","up":false},{"one":"7808fb798d22e78fb1d39b87ddf99a503f820993bc64149eca9e81d9d58fc1adea60d8de14a4f06cb89f3190c0ef0c5e182621a14c9361ccb7e0cee667599cc3","other":"c665a6b1b7ad39b86bd4b1fe38b7ee95a0fbb1db15e91381ec9e5a235e33b69ffdc92c60dafd74b7b4dafca1b000e9274bf045abe5b93b1a9c2b31ae071a9898","up":false},{"one":"657d5370319128d24d925b41065eb619409d63ec6280975d78877a4028287463f6442f5206dd703569a05b2b542ad8bbb99803da265408208d6356a26d283d08","other":"831cde5b651ba327b059da4c7f84b184bdd6bb99c6690ae816affe25d42c6c3dbe5b59e2b6bf23e9d0f6c485bd341ea57ba1a8220d18b0a40e156b77d84f79ef","up":false},{"one":"7b35c856916eb3fc1b1f451667e240b95aff8f4731cc0f6743740923081ff1ddf2eec81bdccf4691a7bcc053d23eacfc15809c384a73448f618317bf605bd1cd","other":"5df58ba12334a1b4f983d642fe435901261767cd81f8f37c43e359f5584664e4d287e8c2275995604a3b3a4823418e35cd899a3db2a7db31570e19512f375481","up":false},{"one":"e2e0419a41bdfc5bd76deae2ddce6ac865f886d764c9bd18799b79fa3b2b6ba66d765d26da2037e98317e1d7e8232a61e63c1d0cfa98c9137424151b46e07171","other":"7808fb798d22e78fb1d39b87ddf99a503f820993bc64149eca9e81d9d58fc1adea60d8de14a4f06cb89f3190c0ef0c5e182621a14c9361ccb7e0cee667599cc3","up":false},{"one":"59b53f8a562bee519276e0eeccfcf8c975d3102f5d0cccf5abcce291a8a5bb817c04604f123686177a50a03b9d7559ac469962d0159d1d93e4ce58a304d04b55","other":"4ee37acec2178ef120166265aaa2b64b09b315fb53861405ef46f2503c273eb9692e9cb4c2e67a8652254d430fd6e02dd3fe4cded20bb231a9fb834d292b0b24","up":false},{"one":"9bd4f0adb9a966cc5ba632f1b540fe9cd6c8e39fe1a041b315697679cfb04b735952062ce057d456677cc34a84301f26bb727a4ab2646fee734f80a22c620746","other":"420b9c90584651c5a3fe3c16aa377444a321dca934f8a097d01a616554067feabebf2fdc8d2a25797f29a8fef30d5e2c82f8e85b20f509a880367b9b0ccdea47","up":false},{"one":"baa5924e1547c177011285d292aa161a15e5ff282da2cd0afb83c9caffb07bdbb3662c227fa7b26e6dc8be9b8863e647eb5f8ce81640532f8f5c9a7f36557e63","other":"396c703d27bfdddf91761f134cbf665fe61e0b3a5d24036a4105a625f72e8c28b821e9200f20d6e8f8b3ed6b95bda6b8accdd840c2f786720b7431e3af2af981","up":false},{"one":"9bbbfac8be4a000f51a4ce8d024d2595b5d491afec0138922dddfde5ef62c664040c2e9304cc6b7bc688233b5d0c4644b8c8793227c078285a3ab894ef0497a3","other":"4e95fb8943ef6502fa470870a7ace4ca11e18589bd2073167543a922317b35e40b5068934d07e56c8fdd23354dfad51fd2899db854f189841f02b5914cd97749","up":false},{"one":"db8ba71afeaea1f2964e8978a6eceeb9efa3958424424022213c8193443f8d5afd18490afa954c76360c681404809c7cfaf7e4ebd8bd1a42d403f7f1915b0d29","other":"2ddd49fae11d8bd2e7e75a481be267fa846f51cc1160bc326aeea51c542323ff444909de11e2731e835140bc0b1b32020e1e73fa652511a381222bf0aebc4081","up":false},{"one":"f33d1f3e460574706ac1c7fc9ebb4683b173496ce3e80017d1c3521bca03d5a41a9c7a6cde8347d2238917b7cc58cab000ce7ccf6bb408561015a2ecbe613408","other":"e2e0419a41bdfc5bd76deae2ddce6ac865f886d764c9bd18799b79fa3b2b6ba66d765d26da2037e98317e1d7e8232a61e63c1d0cfa98c9137424151b46e07171","up":false},{"one":"0f9f7e2dce4ca266c3ac0ec3a8854200b54487f5308e3db418461aeb5f67c81d332619b6441b468e480941e63100ed1b263e7adc20689dc3dcda578bfca538fa","other":"65e954e60837bda10654480b227fa3bcc6e63356c52079002a27e836cd82ae2934ba77da60080e4b9f2d9324b982b24959bfd9624302e6c330408381054b43e9","up":true},{"one":"ddaf3f8478501cda872c056c72063eb64d5b871fc5fff70704872802289dd2d348f73bc342b7f148a90cfaae2448ebf16fea196be9df891dc71a57fb410d59dd","other":"bd1a7c63fca9e1fcc67d7fd62670beefe2bce483cf1dc1233ee85eb90db607917cd9a5d7170b10e80b925a20e2af2c54d286b01805ac34967410859f4f03da09","up":false},{"one":"23f9bdc82efbf57d3d40a1f2617d0311678fb4a3d6a50cb7e608c649bb618124a76c7ffd17387de963e1cd28d2bd5a61c98613f6e009a8a2a90d989827b35de0","other":"2f360209383d6de4ebd3b4abaf77796520b8654270b03f2151eac4a01b4417d7e0668c1f9ad30c20ff49aa8a0ab33dba5e6095619d1cf04b7af841722ab773da","up":true},{"one":"485825745d97654cbb92a14e0cd1078691d3c28f4d82b1046284b676a42b44ca58eb43474e45e415d3bd3f3c383f9a1a3365821ed7ba6a9f2603b29d58031dc7","other":"81288bb0584b7ffc1546043e052e1df10fd5371b35dedd0bb42ec5b30ce69b741b2f7857af5984d4754b39d7253575fde9298504999b78380ef602d391c4bb1d","up":false},{"one":"b4a5efa9028b2d196855393892f79993c2812d02b758f98813ddf82c5d943faf6d66eff811cc5a51936c118f4c768c0d13b54902095e040c602761e63c08655e","other":"485825745d97654cbb92a14e0cd1078691d3c28f4d82b1046284b676a42b44ca58eb43474e45e415d3bd3f3c383f9a1a3365821ed7ba6a9f2603b29d58031dc7","up":false},{"one":"1b063741c76fe65e62b4eae42751319d0cce66f22dde9f1cf83d6cca249a0e65bc7f6f22597697362fadd226222fb3847f8e146961969d1b4c9f7e475389cd8e","other":"e98a08e8e3544727f5ee27f4465375a67ffba490fcdbfe7bfdc909f6b68bd279f776c65d38c2ccfc33079f852f76349c94d68fc6989c0d981f22333f036a4bb5","up":false},{"one":"f039df8a3206e6e17eee8e95010038c450cb4cc0b5580ed5795d4c21802e1e9d360f4528bdca794f457932b1d6a818862ec847357a861c488332ef6d9480daa6","other":"2ddd49fae11d8bd2e7e75a481be267fa846f51cc1160bc326aeea51c542323ff444909de11e2731e835140bc0b1b32020e1e73fa652511a381222bf0aebc4081","up":false},{"one":"b137cf2291b530a39516d882200848e7f27a2710e0839b4d25b4f367bea6a0c3aaef8c7c7851c00a2945adcd819ea0508610afc1f453b8bc512b7b4d4faacdf3","other":"a7378ee34876af17c6cd94a69b6b741ec7891ff5375bc4241d48608d047455ed48e6baae80ee88d4710c69ae615cf195cee26c94b54de1bb935628ce1e3a723a","up":false},{"one":"28d3232c43de54ffdaf08f97b334c012738648b04e2876c7e751a2e352aaf4d550d6efa976c5a8edbfa8e88b9d04a0fca492b81c3756ef673ab74d34182ca711","other":"b26f7c0113a5ae885f7c0e608aea7022a9c8bfc40c5643e60b2ba7343ff09c5be0bc08be34dde3c6b85fea192a46d4764770c12cbaa233df4231a1b99627ef9d","up":false},{"one":"7ac5b07eb555af3bb4ca3f0f4b45204d43cc3798c244435909b97d9a32fc3abf0b50666e260e046bce826a7a102a92d389f8f39c5311e83bb34beddac29d50e3","other":"d4b7c787981abec24353c7d496661692233797e3758189bf909a69fe87935bf6da0940daa4f12e81f20c5e88f70b472113688b71a0ae2f91a73ee0e6ff4c8591","up":false},{"one":"829b074b70d757da6aa00f7bace3cf1b5d2d4eeadb7f370c1a85374a01a70b54ac53d747267e386f3b41e6d790fecdd6e74b8f89745501ee82439a66ea54443a","other":"cb94a8270d0050378116b5815ff17dafbe20f5303839c4fd57b981d4687a4b145e4bccec7e9af9b9475005930148ffbfa97781a0762c8e9f352dc95565fc8732","up":true},{"one":"b3316f4fd7dec218a52331f25d17a2faf0f2a417808d7dbb80038154abfbcd2d78da074837b648cff28675f4aa0d65ddb7d15abf3d7e0391d401e313a3ef24a2","other":"990b1db3ab1390219e8866d39fa4441bb5bb89ad786b3e255771869fcd08906dcf63f34007481769c7462edbcc665acc0a552e3733360b8d8c310c9321a5550f","up":true},{"one":"48a5e01e06e297dc1c640ac9601171495bd70fea461c60e7e6e2532695e45fcf68183c2e58b5e6931a6c1c094f5331efbd7f2d93d5f84efdec5a35afa2124438","other":"2ab9513899c3c829b6284e56bf2b9862dd0156ec052b58615dba77d450dac642e534ec36ae5d3234262aff54e19f99856e908b9d8c1da660a7834a445610715b","up":false},{"one":"855bdf057f4a6b095e2000ada199447b5b4f2f8d78d2ecbaa0ff1fbf761788870ee999266ad3b26efa02be1a46a4d92ac0debb85a2ceab3442394ee7d99e5355","other":"5df58ba12334a1b4f983d642fe435901261767cd81f8f37c43e359f5584664e4d287e8c2275995604a3b3a4823418e35cd899a3db2a7db31570e19512f375481","up":false},{"one":"b53078000796f1cdb04dfeac424d5e3e37e30f00bd5bebf9a9ea0525c62917612b3a8f508df6bea59e3c7e4cd1aa530841f9a8af54e44f5617a13dee2c6ff007","other":"9b59b76dc61223c7b37083b0ebdda22d3599563b3e3986f5db9d5b12f8c806cbdeb2345454efe957cbfa11eea9c7896aefd9a461210524805452ca100a9ea431","up":false},{"one":"88d5c5fe61ee1e6fa5878e0eaa13bdabaa0ec3d38a5d25b95a467da7627424f25fb5d30535aa0a5ad01c16fe2598dbf570b78cc152a7f4ef66d46fc9ae43592f","other":"6c143960dbe3ba4c95e8debc1fda5f420a2a673eb46f7ff7d9a30f4cd2067e67ef8926bf17f0c99b16c79b6dc066b52409a11d47117d4fda4211636b1b74f96c","up":false},{"one":"80d997b87856099d844187d3d1fa40846ded652a62c1611b35919c2543915b64ff62476636488556f678e436ea26fcc40db7c6b6bbcb78f590d61c1ff0e424b5","other":"f38a9d792173a29c61389f5d84c005d78eac6e750659aad42e2d6df883f04eb3126b2c38fac95076eeed455b2031aaf694143922aa93a2d50412a2454dc56e28","up":false},{"one":"cb94a8270d0050378116b5815ff17dafbe20f5303839c4fd57b981d4687a4b145e4bccec7e9af9b9475005930148ffbfa97781a0762c8e9f352dc95565fc8732","other":"9e621c3eb534855ca292efa27a3fbc89b4f05c80a4bc65bcff2f14ff28ef43cbe14137d2fddc6fe2658bb06947d918476b479dde71469b8680e5d8a7a01619b5","up":true},{"one":"396c703d27bfdddf91761f134cbf665fe61e0b3a5d24036a4105a625f72e8c28b821e9200f20d6e8f8b3ed6b95bda6b8accdd840c2f786720b7431e3af2af981","other":"94088fe273f76e62ca4e43c095ad12215b4ae4c59942328b3985416fb19bbda0cacc143a49eff3fb644ad53a19d3f043260e43dbb70a0aa9c15829c21cecd3c7","up":false},{"one":"4e95fb8943ef6502fa470870a7ace4ca11e18589bd2073167543a922317b35e40b5068934d07e56c8fdd23354dfad51fd2899db854f189841f02b5914cd97749","other":"3e488a7208ce0e097ce47fc6651a13e95cae137d1a054a09b04d2f59d45faa2594a8c3b395e77ad1a3c2edcd827dda73c0c97dbaa6d9519a79184a0aca01ac4b","up":false},{"one":"453779010ed7c59761da47ccd8869d3fa8349795e57edb9eea416c0712301ea622c7683858e309d19ab137ddb0edef161d0d00a361abeecf0628c3ffabc629ea","other":"2ca05ffc0ad771e1e045a47f1c0a79ce374a25e3c0e53c2a80d67e7479677003f62880251a83a5074f1c9651d828f1ff7e352935a9df141c1eb75a0c59b00a8b","up":true},{"one":"9c30ad8c85adc7bb52ddcfab2e661cc3a854a689eaa59128d35129d02cd5b0f8da4a44cdd33934a8e2c8fab1760c16d6f2e1c5eb227dc819e85624e63343c069","other":"b870935867183bbfb84add16b9f56c02c834b7042fc24ce6bcb2a7f174e6d2239357a00be4272c1ef05c7f9baf5a9f16b53bc18328a9b7aca8540c2916805b57","up":false},{"one":"9bd4f0adb9a966cc5ba632f1b540fe9cd6c8e39fe1a041b315697679cfb04b735952062ce057d456677cc34a84301f26bb727a4ab2646fee734f80a22c620746","other":"ea57884dd42aec5a76eab43483bf7c4ae2c19eebf365013731de64494d10a3b4cfe34c86c79437f9012bc8cf6bd761435eefadec17600f4b9e4bc234532d6282","up":false},{"one":"9bbbfac8be4a000f51a4ce8d024d2595b5d491afec0138922dddfde5ef62c664040c2e9304cc6b7bc688233b5d0c4644b8c8793227c078285a3ab894ef0497a3","other":"e2a27dcdee1f89fa362a85c4397840cd8be4ad8d1b9ccb23188c303bcab7619f38772f71385922d090390973b62fb8249efc103f71bc761041bcb3880ec0b935","up":false},{"one":"f039df8a3206e6e17eee8e95010038c450cb4cc0b5580ed5795d4c21802e1e9d360f4528bdca794f457932b1d6a818862ec847357a861c488332ef6d9480daa6","other":"66beee3968dbcf3addc6feaf070a4e3e82b5bb164fb72f40add89f732c12e8d0a31a7ee1f1e24a4674e4dfc9a4912b02c17ce3c224d257d78b7156544d6507dc","up":false},{"one":"62666b24d1026345349edb6a878cdc27d6fee8254e83f79a298ce2805260d97aa46423deae440f86ced5cd99b30e970c8e1ea1046752b17d8c80dc68d9a49b60","other":"e6779e3bbecf81dde8b27d652ed2726c45c205db0d0405c4580014a4c91d739830276f77079108c98ac516ffa00194e77a0795f7140bdf36069b6475e58213f9","up":true},{"one":"b3316f4fd7dec218a52331f25d17a2faf0f2a417808d7dbb80038154abfbcd2d78da074837b648cff28675f4aa0d65ddb7d15abf3d7e0391d401e313a3ef24a2","other":"f54335964d9b4eb9813eb05f40ef1c523bbf0faac5a04c4737467d590fb6b55c7fa1fc5d4d32c5491d8766b9be6fdfd3ebdb25c5ffe1719f36c86ddf87ae3a85","up":false},{"one":"b137cf2291b530a39516d882200848e7f27a2710e0839b4d25b4f367bea6a0c3aaef8c7c7851c00a2945adcd819ea0508610afc1f453b8bc512b7b4d4faacdf3","other":"155e4879643a472420012e040a87dbff776fc1976814c0c6cd0d5e157f0d0baac04aa7f2535786c09acc2700547383d2119b64a6f62115f1aff1708738844d8c","up":false},{"one":"485825745d97654cbb92a14e0cd1078691d3c28f4d82b1046284b676a42b44ca58eb43474e45e415d3bd3f3c383f9a1a3365821ed7ba6a9f2603b29d58031dc7","other":"7b35c856916eb3fc1b1f451667e240b95aff8f4731cc0f6743740923081ff1ddf2eec81bdccf4691a7bcc053d23eacfc15809c384a73448f618317bf605bd1cd","up":false},{"one":"b53078000796f1cdb04dfeac424d5e3e37e30f00bd5bebf9a9ea0525c62917612b3a8f508df6bea59e3c7e4cd1aa530841f9a8af54e44f5617a13dee2c6ff007","other":"032b9bf2f59f15571821611d3ee541aa748c86d47fbe5f049fd0069be53e5d7c41991d82957e9c727654c3aa73ec94997c03d8a6c1d2007c9bb1a703f6215158","up":false},{"one":"ff6f94005d1df7677600069764855c1c2aa0543cbe9f480f8feefec76c49d9e2c7bb2d8e38c89e9430f53f8b593d93f143c45985a56a5a32c736128214c95eda","other":"ff1e34fd51953ed641b431aa657da21cb4c81d23e4eaa13c9cce526f1f1b34593d41f9b87a0e10387fe400c623638677c0efab15dbd1014a0ccc11f9ec92c417","up":false},{"one":"0f9f7e2dce4ca266c3ac0ec3a8854200b54487f5308e3db418461aeb5f67c81d332619b6441b468e480941e63100ed1b263e7adc20689dc3dcda578bfca538fa","other":"8ca3b63cb84f1e9883d82809a9b6777ec1029ecda96fe93b4d494ee9cbefcad13f381b3e480136e542e01054fe1ede66c65db84a0009871ce49383db461c8438","up":false},{"one":"72e30d4562673c5c8fb03709d93f73322747858d723b7eb5ef2fbb88e0331252946b7e93ffe434fcb599c4fff57800afb29e6c60a719f18f49dba541c3591c6e","other":"c332fe1f9b6e25f72c7150631ffa6e0929ff6eeab5d17aa45eaf669bdde869cf404505ae990a529aa3ca797cd0a96f31cc41431a5d4a163132be566f91623c08","up":false},{"one":"7808fb798d22e78fb1d39b87ddf99a503f820993bc64149eca9e81d9d58fc1adea60d8de14a4f06cb89f3190c0ef0c5e182621a14c9361ccb7e0cee667599cc3","other":"5526d86ba9df651091d88460a9bedb9cedb957d452a635e1db46b9fed78082022adec0047cd7485956a4ecbb0e18107595de0de3c35242527cd302bf74a19260","up":false},{"one":"7b35c856916eb3fc1b1f451667e240b95aff8f4731cc0f6743740923081ff1ddf2eec81bdccf4691a7bcc053d23eacfc15809c384a73448f618317bf605bd1cd","other":"c9cd9dfb9f90a7948ac5a42c7bd63263f2eef6e1d85547559f7d2ecbf5f9cd1eab051b8e9e661b573c275d84091a44e73f6fc6bcc91dcdb674bd5d939190fc01","up":false},{"one":"fe62314839c93d2f6e3aee984d5f0b321897c6f39e66800d3de8b773baf6f19e0a03cae025df512aea8d5f1b667b6dbb15c192a90a76d3031c14e33e5c16c4f7","other":"ddaf3f8478501cda872c056c72063eb64d5b871fc5fff70704872802289dd2d348f73bc342b7f148a90cfaae2448ebf16fea196be9df891dc71a57fb410d59dd","up":false},{"one":"5566111b7f14d8ec83ba6456488f3fc5c7e2c86bf406dead33b814e1ee9b569d34015a4d88226b7e28fff7784395c086d106287cbbc80acfe75b05cd6e12903d","other":"66beee3968dbcf3addc6feaf070a4e3e82b5bb164fb72f40add89f732c12e8d0a31a7ee1f1e24a4674e4dfc9a4912b02c17ce3c224d257d78b7156544d6507dc","up":false},{"one":"f54335964d9b4eb9813eb05f40ef1c523bbf0faac5a04c4737467d590fb6b55c7fa1fc5d4d32c5491d8766b9be6fdfd3ebdb25c5ffe1719f36c86ddf87ae3a85","other":"7aaf7817b93aa6d2f50513791f9ad7629a901ed0dcb151189f44763f83423446b20ec79a48fa260cd9bc2907d5f0ad06b2c4c5e6d812f3d8876c8020ebe41019","up":false},{"one":"0a4eec7b0e05da799aca5b36d9e2530f2a89d1426b1fcb7d8f9a662df8a8b5b763767a20db3c9c63e0bd13c2a6e16d3ba8f03baf84f5e5d24917b3f211d9bcfc","other":"302c37f28c69fdcf00b39ce0c0223de0d94cebc2c0b068315b95b76b5432573ead0656569441029ba9054d8d3d959fd8735e73913af5ce3f1132f8271fd437ef","up":false},{"one":"934a5fe1b91c1891ef4df7f67c027e0eb115d4c2ca4a1b76a135ebd4315c4fb835d6625223194e6a134407b38b0d3928fbc7bc924a3c6a538989a6cf200bf4bd","other":"6f60ef501b41f9049419b033ae8d793a18067bdcd60347537b0dc3873bdd9a2d10d24909cca7c39781765746128c2165596f6537a94f58279523faee71f9c51d","up":true},{"one":"3612863ce0456c91785a829bf5c9d2b2fb97dda083a1847e5a4ebaa6fce1260faf4d1eb374c2225431a82774163835fb59c8cb0fa9fc0969eab5410c71109cc2","other":"6f60ef501b41f9049419b033ae8d793a18067bdcd60347537b0dc3873bdd9a2d10d24909cca7c39781765746128c2165596f6537a94f58279523faee71f9c51d","up":true},{"one":"66beee3968dbcf3addc6feaf070a4e3e82b5bb164fb72f40add89f732c12e8d0a31a7ee1f1e24a4674e4dfc9a4912b02c17ce3c224d257d78b7156544d6507dc","other":"f915e2398aa5d4370de87504dd76c21a7d0be2581c2ab55b7a47743f1bbaef36384eaacec22760f1e914ceac9d96a10c3d66eb27475ef444e77fee979e6e88cb","up":false},{"one":"2ca05ffc0ad771e1e045a47f1c0a79ce374a25e3c0e53c2a80d67e7479677003f62880251a83a5074f1c9651d828f1ff7e352935a9df141c1eb75a0c59b00a8b","other":"6f60ef501b41f9049419b033ae8d793a18067bdcd60347537b0dc3873bdd9a2d10d24909cca7c39781765746128c2165596f6537a94f58279523faee71f9c51d","up":true},{"one":"535f93057d46c4aae0902546550880be0b5ba67dca12350117d471d67f4f2b3f7bdff29bdc918767974c465df8fa1afa6bd6c29c0a36d51f71c4183673d906f3","other":"e67e495385e7cacfe659b40d1ba94d4b1ff55eada70a4d9740a9e452fbf221672bd0a897b940e2a6bed71e2a16867fe45bf0ea0015435ac6d815690e263b1899","up":false},{"one":"934a5fe1b91c1891ef4df7f67c027e0eb115d4c2ca4a1b76a135ebd4315c4fb835d6625223194e6a134407b38b0d3928fbc7bc924a3c6a538989a6cf200bf4bd","other":"9194a3a4c8f3235203e48bdb10902d958d26c342805ea6365af9711213536509719d917c694f9a4fbdde6889a4c92299a5301f0275bda4dbcd2541b5bff5b271","up":false},{"one":"b3316f4fd7dec218a52331f25d17a2faf0f2a417808d7dbb80038154abfbcd2d78da074837b648cff28675f4aa0d65ddb7d15abf3d7e0391d401e313a3ef24a2","other":"97981f4b825620985b746c85824d7a4d307ee25d60a72c2b7de4b1d4f3b1c002652adc3045842d350f849789e410a0357a0b42fa637a1b4fc9d39e44f8a674d7","up":false},{"one":"f33d1f3e460574706ac1c7fc9ebb4683b173496ce3e80017d1c3521bca03d5a41a9c7a6cde8347d2238917b7cc58cab000ce7ccf6bb408561015a2ecbe613408","other":"81288bb0584b7ffc1546043e052e1df10fd5371b35dedd0bb42ec5b30ce69b741b2f7857af5984d4754b39d7253575fde9298504999b78380ef602d391c4bb1d","up":false},{"one":"ea57884dd42aec5a76eab43483bf7c4ae2c19eebf365013731de64494d10a3b4cfe34c86c79437f9012bc8cf6bd761435eefadec17600f4b9e4bc234532d6282","other":"df54af3bae257d437c5657905484e0d72e9560c46f8ba6b3437730234e05259b404cca40b0831e911605ff8a68a19e8fd7e958069ec8b40595928892f4fa220c","up":false},{"one":"e3c8a97a2d95dd543f9e2b41d9dce6256e284296f866f4f92e9925f8c7519dea23fd6d1a11153b93c10d6a32295e7b9bcc16024e690e4a0dc84fd25ee0f31b2c","other":"d9bbcdfd949010e6b2cbf6d0f34b27593ae410bdc1838876aeca35679571fe431d040a5ab085c0a77f111688bebed891da3587277cd794702437cb20d6aa4256","up":false},{"one":"453779010ed7c59761da47ccd8869d3fa8349795e57edb9eea416c0712301ea622c7683858e309d19ab137ddb0edef161d0d00a361abeecf0628c3ffabc629ea","other":"c332fe1f9b6e25f72c7150631ffa6e0929ff6eeab5d17aa45eaf669bdde869cf404505ae990a529aa3ca797cd0a96f31cc41431a5d4a163132be566f91623c08","up":false},{"one":"9c30ad8c85adc7bb52ddcfab2e661cc3a854a689eaa59128d35129d02cd5b0f8da4a44cdd33934a8e2c8fab1760c16d6f2e1c5eb227dc819e85624e63343c069","other":"7aaf7817b93aa6d2f50513791f9ad7629a901ed0dcb151189f44763f83423446b20ec79a48fa260cd9bc2907d5f0ad06b2c4c5e6d812f3d8876c8020ebe41019","up":false},{"one":"1b063741c76fe65e62b4eae42751319d0cce66f22dde9f1cf83d6cca249a0e65bc7f6f22597697362fadd226222fb3847f8e146961969d1b4c9f7e475389cd8e","other":"759f46661056bcbb30c7706c9fb87e22a30feb523bd53ae5d18db043efa45b49a2b8982abebdd598fe0912a05896390ec2eabe5e160cbafc0771990708ad8c28","up":false},{"one":"48a5e01e06e297dc1c640ac9601171495bd70fea461c60e7e6e2532695e45fcf68183c2e58b5e6931a6c1c094f5331efbd7f2d93d5f84efdec5a35afa2124438","other":"92d6ef729992f0de886076e5f8cdc42cbbd70b29e79c25e0b3d22b6575d3d2508d47b42f581e335455483d43625bce4e55f88cab9ff2073ee8dab746357864fd","up":false},{"one":"e6779e3bbecf81dde8b27d652ed2726c45c205db0d0405c4580014a4c91d739830276f77079108c98ac516ffa00194e77a0795f7140bdf36069b6475e58213f9","other":"a7507aa5665e165ab2e2a07def272f0677f9d6d35bb82268a34214384e7d8ef7635a299368752e63cfd02d4e60231076baf23cfa10d17492e55181b391ecf335","up":false},{"one":"a7507aa5665e165ab2e2a07def272f0677f9d6d35bb82268a34214384e7d8ef7635a299368752e63cfd02d4e60231076baf23cfa10d17492e55181b391ecf335","other":"62666b24d1026345349edb6a878cdc27d6fee8254e83f79a298ce2805260d97aa46423deae440f86ced5cd99b30e970c8e1ea1046752b17d8c80dc68d9a49b60","up":true},{"one":"6b01079463ec2f649db8634cb7a596261c79a8f714d954c772528e0547b017f8ce405e4a0ea9d32270848180e0f77b8c0b022cf95c85e777626edd4d24ea21d2","other":"cb310c0e86aa455d7c9af6394ae38561c901da30a51d7ccb7e66a09d9a8f192ae8caeff106043426d56397088f141c4e01e3b98f1ee583ffc7318b5f730f3ac7","up":false},{"one":"b35f418c7935cc54278e90978c3ef1521ab91daeaf9f1ebc1cd25211611ade091cac4e1f009d71059279d507322a4536501980ac0dd44caddc52fd4c593879f7","other":"aacff366e601e072a2113add9020e19b6612f3e85b6e607fdc8cc1b6991f43be0b1f835ed3dc41d1f2b3e0caf7fac252c8eb4c150667d48207fa92ea5f0a7455","up":true},{"one":"bd1a7c63fca9e1fcc67d7fd62670beefe2bce483cf1dc1233ee85eb90db607917cd9a5d7170b10e80b925a20e2af2c54d286b01805ac34967410859f4f03da09","other":"9194a3a4c8f3235203e48bdb10902d958d26c342805ea6365af9711213536509719d917c694f9a4fbdde6889a4c92299a5301f0275bda4dbcd2541b5bff5b271","up":false},{"one":"66beee3968dbcf3addc6feaf070a4e3e82b5bb164fb72f40add89f732c12e8d0a31a7ee1f1e24a4674e4dfc9a4912b02c17ce3c224d257d78b7156544d6507dc","other":"d7a319f69013b8375e64d19f015547462c84565b882337998f9e669c5fadd3d2ecf6374109903003e09f5d453424b5c7fdf52163d2cc8084cf81f94844946b63","up":false},{"one":"92d6ef729992f0de886076e5f8cdc42cbbd70b29e79c25e0b3d22b6575d3d2508d47b42f581e335455483d43625bce4e55f88cab9ff2073ee8dab746357864fd","other":"b35f418c7935cc54278e90978c3ef1521ab91daeaf9f1ebc1cd25211611ade091cac4e1f009d71059279d507322a4536501980ac0dd44caddc52fd4c593879f7","up":true},{"one":"c332fe1f9b6e25f72c7150631ffa6e0929ff6eeab5d17aa45eaf669bdde869cf404505ae990a529aa3ca797cd0a96f31cc41431a5d4a163132be566f91623c08","other":"4314b0b04331973ed29a58843951f144ac3d09bd5d57b6cd9aaff9b73a7b2ec81e344a3e4ece462bd2081b837a06310e787ef3bb889dabad46fe7efd394c8342","up":false},{"one":"2ac522ebfa49d37f86c6270ad4cdad0e766493f0e463b18c9906c70fbd2e5c6ff6b0d5879de6e3894418370636963a78b0c0cf087a8684c2ca30c9c736e49228","other":"c2705ee7238ef9305e4da196653cde707649435a1e8b5b797d164e5ca06184a77af5bd7fa938c995fdfcbce724fa7eca3d908ee34891ab62cc6dfd411c3fa1da","up":true},{"one":"65e954e60837bda10654480b227fa3bcc6e63356c52079002a27e836cd82ae2934ba77da60080e4b9f2d9324b982b24959bfd9624302e6c330408381054b43e9","other":"48a5e01e06e297dc1c640ac9601171495bd70fea461c60e7e6e2532695e45fcf68183c2e58b5e6931a6c1c094f5331efbd7f2d93d5f84efdec5a35afa2124438","up":true},{"one":"23f9bdc82efbf57d3d40a1f2617d0311678fb4a3d6a50cb7e608c649bb618124a76c7ffd17387de963e1cd28d2bd5a61c98613f6e009a8a2a90d989827b35de0","other":"cb94a8270d0050378116b5815ff17dafbe20f5303839c4fd57b981d4687a4b145e4bccec7e9af9b9475005930148ffbfa97781a0762c8e9f352dc95565fc8732","up":true},{"one":"ff1e34fd51953ed641b431aa657da21cb4c81d23e4eaa13c9cce526f1f1b34593d41f9b87a0e10387fe400c623638677c0efab15dbd1014a0ccc11f9ec92c417","other":"9e621c3eb534855ca292efa27a3fbc89b4f05c80a4bc65bcff2f14ff28ef43cbe14137d2fddc6fe2658bb06947d918476b479dde71469b8680e5d8a7a01619b5","up":false},{"one":"9194a3a4c8f3235203e48bdb10902d958d26c342805ea6365af9711213536509719d917c694f9a4fbdde6889a4c92299a5301f0275bda4dbcd2541b5bff5b271","other":"485825745d97654cbb92a14e0cd1078691d3c28f4d82b1046284b676a42b44ca58eb43474e45e415d3bd3f3c383f9a1a3365821ed7ba6a9f2603b29d58031dc7","up":false},{"one":"eaca77d20c4ad6b87649eba21b750a4b1a2c575e06bc42679d18fce16fea15212e9a7408c16f3b24d8dfd1e397314637e72e292845d09534a39035bd9203ee9e","other":"4ee37acec2178ef120166265aaa2b64b09b315fb53861405ef46f2503c273eb9692e9cb4c2e67a8652254d430fd6e02dd3fe4cded20bb231a9fb834d292b0b24","up":true},{"one":"cb94a8270d0050378116b5815ff17dafbe20f5303839c4fd57b981d4687a4b145e4bccec7e9af9b9475005930148ffbfa97781a0762c8e9f352dc95565fc8732","other":"58cfb20d3da3641e0ad529b9edbd4b590a8d1dc9d1ed7b44ed3187dba9260bd7c732fc10981f5b9bffd31d362cb05150173618aa36138984431d94a323a9b313","up":false},{"one":"453779010ed7c59761da47ccd8869d3fa8349795e57edb9eea416c0712301ea622c7683858e309d19ab137ddb0edef161d0d00a361abeecf0628c3ffabc629ea","other":"17a79cb279306b6bbd35219278f6bba03111079d6c4fadcd3c5e57b09678e111bda5f8e36ca3d223e51e255d6e857363b7741e438b32ec6e6c0dc1b224071081","up":false},{"one":"07f25fdeab2b44b2e92fc80fca7de9e4a8547d27a98a54593b3395c270a9ff3f2a5da62a2e8531ce86359f0cdc5b6513b773dfd64cce1b83e47065d9760a2c7e","other":"a7507aa5665e165ab2e2a07def272f0677f9d6d35bb82268a34214384e7d8ef7635a299368752e63cfd02d4e60231076baf23cfa10d17492e55181b391ecf335","up":false},{"one":"1bc1d6155ba35d29ea16938994e08df76ebd8f16bd180bd6a9b9d8798d0745889fe72d641dd78bd8ec13526929f7eb5aaa6a388430fa69033d6db581e53c6422","other":"be514f5f17f3177235acb24112b578edf0e373c469073226e547d18080905fd062d572be18e943f13bf9fcf5871e89ceb630a1b848a0e370ef8ef8c6d997a363","up":false},{"one":"b4a5efa9028b2d196855393892f79993c2812d02b758f98813ddf82c5d943faf6d66eff811cc5a51936c118f4c768c0d13b54902095e040c602761e63c08655e","other":"ddaf3f8478501cda872c056c72063eb64d5b871fc5fff70704872802289dd2d348f73bc342b7f148a90cfaae2448ebf16fea196be9df891dc71a57fb410d59dd","up":false},{"one":"1b063741c76fe65e62b4eae42751319d0cce66f22dde9f1cf83d6cca249a0e65bc7f6f22597697362fadd226222fb3847f8e146961969d1b4c9f7e475389cd8e","other":"1bc1d6155ba35d29ea16938994e08df76ebd8f16bd180bd6a9b9d8798d0745889fe72d641dd78bd8ec13526929f7eb5aaa6a388430fa69033d6db581e53c6422","up":false},{"one":"ddaf3f8478501cda872c056c72063eb64d5b871fc5fff70704872802289dd2d348f73bc342b7f148a90cfaae2448ebf16fea196be9df891dc71a57fb410d59dd","other":"92d6ef729992f0de886076e5f8cdc42cbbd70b29e79c25e0b3d22b6575d3d2508d47b42f581e335455483d43625bce4e55f88cab9ff2073ee8dab746357864fd","up":false},{"one":"db8ba71afeaea1f2964e8978a6eceeb9efa3958424424022213c8193443f8d5afd18490afa954c76360c681404809c7cfaf7e4ebd8bd1a42d403f7f1915b0d29","other":"3b570117addeec03c2694baf28e246f91907268fe665c6c90356120332794258ee57a60853c19e9fe25d042ca42a5be7fe0797d84199174de8132f1ef4a9349b","up":false},{"one":"3612863ce0456c91785a829bf5c9d2b2fb97dda083a1847e5a4ebaa6fce1260faf4d1eb374c2225431a82774163835fb59c8cb0fa9fc0969eab5410c71109cc2","other":"a127faa19dcb7da585983d36a8e9d3e9a44a6db68507b60c70da71011f44ce377944802f39cd65f5a705cd8249ac1ef7ed8fd699349098f3f8e23b37592c80ae","up":false},{"one":"28d3232c43de54ffdaf08f97b334c012738648b04e2876c7e751a2e352aaf4d550d6efa976c5a8edbfa8e88b9d04a0fca492b81c3756ef673ab74d34182ca711","other":"831cde5b651ba327b059da4c7f84b184bdd6bb99c6690ae816affe25d42c6c3dbe5b59e2b6bf23e9d0f6c485bd341ea57ba1a8220d18b0a40e156b77d84f79ef","up":false},{"one":"6b01079463ec2f649db8634cb7a596261c79a8f714d954c772528e0547b017f8ce405e4a0ea9d32270848180e0f77b8c0b022cf95c85e777626edd4d24ea21d2","other":"a99852c5bf08ea4713af9cade5343d1259bfb90401aca7fcff18c58cd56a98804dd16c61fea71039c0ac31b9bbbb9dc5aeaf0c2f074d3365e88d17031802d636","up":false},{"one":"d4b7c787981abec24353c7d496661692233797e3758189bf909a69fe87935bf6da0940daa4f12e81f20c5e88f70b472113688b71a0ae2f91a73ee0e6ff4c8591","other":"59b53f8a562bee519276e0eeccfcf8c975d3102f5d0cccf5abcce291a8a5bb817c04604f123686177a50a03b9d7559ac469962d0159d1d93e4ce58a304d04b55","up":false},{"one":"934a5fe1b91c1891ef4df7f67c027e0eb115d4c2ca4a1b76a135ebd4315c4fb835d6625223194e6a134407b38b0d3928fbc7bc924a3c6a538989a6cf200bf4bd","other":"b35f418c7935cc54278e90978c3ef1521ab91daeaf9f1ebc1cd25211611ade091cac4e1f009d71059279d507322a4536501980ac0dd44caddc52fd4c593879f7","up":true},{"one":"b53078000796f1cdb04dfeac424d5e3e37e30f00bd5bebf9a9ea0525c62917612b3a8f508df6bea59e3c7e4cd1aa530841f9a8af54e44f5617a13dee2c6ff007","other":"5e86f39cf8338ba098a85d41e601a303fde311662b216ad32a2b7bfaf2b2b6dd1af3775784b39f2d85ac5fac96f05f3abdd8a2bd28ba16d939725fd6a33ae1b6","up":false},{"one":"292c78c8e41606e98428096bc6f4609a7aa48e5c4d17eecc64d65faae4a7270b0c15f0cd74274015688ea0a9aff34f215c29118222e362a29c8d637963973a55","other":"420b9c90584651c5a3fe3c16aa377444a321dca934f8a097d01a616554067feabebf2fdc8d2a25797f29a8fef30d5e2c82f8e85b20f509a880367b9b0ccdea47","up":true},{"one":"eaca77d20c4ad6b87649eba21b750a4b1a2c575e06bc42679d18fce16fea15212e9a7408c16f3b24d8dfd1e397314637e72e292845d09534a39035bd9203ee9e","other":"5dc69635f6d573c824ea83b18593a47f9f21a6f91ce18d2bf977c97d21f8d2a8ce88829244d12a07d949bbd52fe8a2035bc89685fe1bdd4ee20d766d75d3deee","up":true},{"one":"6b01079463ec2f649db8634cb7a596261c79a8f714d954c772528e0547b017f8ce405e4a0ea9d32270848180e0f77b8c0b022cf95c85e777626edd4d24ea21d2","other":"5420da16f7ed5de6b498dbc9a83b7e92e1f9900a6d04ef7351a0bfdfd442b98a5634f28fcea32ba3f3166d21c8ff5a39be70895b32acbdf7592d1d616a345a21","up":false},{"one":"8d4920d6e3a6717699b5a3af068cbdfc16858d7e393d158d41b1b5f345b47129eef89e1d055386c518f400b134678c21590f0317dea3436d4cef60f45455cf12","other":"7aaf7817b93aa6d2f50513791f9ad7629a901ed0dcb151189f44763f83423446b20ec79a48fa260cd9bc2907d5f0ad06b2c4c5e6d812f3d8876c8020ebe41019","up":true},{"one":"7865b82e44add2cea6ebcbaba9c152184331a2940fe73f6f9bb940bda8a59ab4cf4760894b9cadcaa54e36fbb712ad619346a49a85e32cdf2b53cda1ac1e0658","other":"4314b0b04331973ed29a58843951f144ac3d09bd5d57b6cd9aaff9b73a7b2ec81e344a3e4ece462bd2081b837a06310e787ef3bb889dabad46fe7efd394c8342","up":false},{"one":"c332fe1f9b6e25f72c7150631ffa6e0929ff6eeab5d17aa45eaf669bdde869cf404505ae990a529aa3ca797cd0a96f31cc41431a5d4a163132be566f91623c08","other":"57b47f692f4d69a5d2c9c193680eb4ccb5a6c574662df0138504a549f3ea74f20c5b866ac4d9e76c4b49c83f5fd692ead928ea20dfcf643a11a1c1e841c0ec42","up":false},{"one":"65e954e60837bda10654480b227fa3bcc6e63356c52079002a27e836cd82ae2934ba77da60080e4b9f2d9324b982b24959bfd9624302e6c330408381054b43e9","other":"4e95fb8943ef6502fa470870a7ace4ca11e18589bd2073167543a922317b35e40b5068934d07e56c8fdd23354dfad51fd2899db854f189841f02b5914cd97749","up":true},{"one":"016f8f4619a16a07fbde5a18e362158d696e4d9f104a77787f26e32a25cd7d278256f8e0db865c488a99511ec27a5eddd5ebbd1c1397fa7f8db111062e5fe959","other":"e98a08e8e3544727f5ee27f4465375a67ffba490fcdbfe7bfdc909f6b68bd279f776c65d38c2ccfc33079f852f76349c94d68fc6989c0d981f22333f036a4bb5","up":false},{"one":"535f93057d46c4aae0902546550880be0b5ba67dca12350117d471d67f4f2b3f7bdff29bdc918767974c465df8fa1afa6bd6c29c0a36d51f71c4183673d906f3","other":"4e68553db7be307b8379e8bec383b5c92e4b23debcefca575d24504e2062618f74c26e60e0d9e47f096997a7f841e2c32c994124f495ef3352ef964b33fd3a51","up":false},{"one":"ddaf3f8478501cda872c056c72063eb64d5b871fc5fff70704872802289dd2d348f73bc342b7f148a90cfaae2448ebf16fea196be9df891dc71a57fb410d59dd","other":"ba21a373781966135d6225adae024a3f3e421b852f72f8b0569cb92fcff87c33f7e5b799a509b8eff6ec6dc46a9b17d5bae1e91ec7c54c0c712d893d54b140fa","up":false},{"one":"617595a230e0a74a3db3b47cd27b941e02bdee9a84cdfa8eaa63a55941eb5caa79e20fb69726a4d46a0e5aeed24039f8c5a20679a692df0bc140f42558ca9a2b","other":"e06a789a7f6988e1ba5e8358b6cd4292555c7f9f7f0dda6fc01cc26d24e49a8c1ad694423ad74aec6d80f4b99e2bedc49b6a5f2670744cedee3a3e1848e6dd07","up":false},{"one":"7b1e20217f594f87350542df31ff5ae8a635679bac7962d49c97e02190c644b673d03e7eba2626b45ca7ebf98d8a972dadbba02c18a8d2cbfc3e7a4cced5b4b7","other":"420b9c90584651c5a3fe3c16aa377444a321dca934f8a097d01a616554067feabebf2fdc8d2a25797f29a8fef30d5e2c82f8e85b20f509a880367b9b0ccdea47","up":false},{"one":"7f357b8d81bc2e5c6fcb081f23a42b3e2439f050d45c45851994a268d1c71fcb1f39f8c3f75ce921d3fbf80fc0e73f0b9609d72001dc4a6b65b526d312a4f43a","other":"389b5c1a805f87427e6d647ec5488342a3f7d700615943d5ad98ca5c111f33c7ee007970b4d3e475892095c0d5a79b7ed52d12598398818159000d4b9b719126","up":true},{"one":"1bc1d6155ba35d29ea16938994e08df76ebd8f16bd180bd6a9b9d8798d0745889fe72d641dd78bd8ec13526929f7eb5aaa6a388430fa69033d6db581e53c6422","other":"97981f4b825620985b746c85824d7a4d307ee25d60a72c2b7de4b1d4f3b1c002652adc3045842d350f849789e410a0357a0b42fa637a1b4fc9d39e44f8a674d7","up":false},{"one":"535f93057d46c4aae0902546550880be0b5ba67dca12350117d471d67f4f2b3f7bdff29bdc918767974c465df8fa1afa6bd6c29c0a36d51f71c4183673d906f3","other":"3612863ce0456c91785a829bf5c9d2b2fb97dda083a1847e5a4ebaa6fce1260faf4d1eb374c2225431a82774163835fb59c8cb0fa9fc0969eab5410c71109cc2","up":false},{"one":"cb321c9b0fe2eb3617b8e2461aab170a9dad2c9b04a10eead4e37e551197ea0a7500eb1cb7b155efe1886486ef3d252d8ff0d309f2906a1126ca011d037da70a","other":"7f357b8d81bc2e5c6fcb081f23a42b3e2439f050d45c45851994a268d1c71fcb1f39f8c3f75ce921d3fbf80fc0e73f0b9609d72001dc4a6b65b526d312a4f43a","up":true},{"one":"c332fe1f9b6e25f72c7150631ffa6e0929ff6eeab5d17aa45eaf669bdde869cf404505ae990a529aa3ca797cd0a96f31cc41431a5d4a163132be566f91623c08","other":"e3c8a97a2d95dd543f9e2b41d9dce6256e284296f866f4f92e9925f8c7519dea23fd6d1a11153b93c10d6a32295e7b9bcc16024e690e4a0dc84fd25ee0f31b2c","up":false},{"one":"cb94a8270d0050378116b5815ff17dafbe20f5303839c4fd57b981d4687a4b145e4bccec7e9af9b9475005930148ffbfa97781a0762c8e9f352dc95565fc8732","other":"831cde5b651ba327b059da4c7f84b184bdd6bb99c6690ae816affe25d42c6c3dbe5b59e2b6bf23e9d0f6c485bd341ea57ba1a8220d18b0a40e156b77d84f79ef","up":false},{"one":"292c78c8e41606e98428096bc6f4609a7aa48e5c4d17eecc64d65faae4a7270b0c15f0cd74274015688ea0a9aff34f215c29118222e362a29c8d637963973a55","other":"7174eca109a1f717653918224c8cfe1b7fbd666405196760913593401eb79f2c7e41003b01f5a458940695b27a4673443c7621a169db7fd968994e552995dbbb","up":false},{"one":"535f93057d46c4aae0902546550880be0b5ba67dca12350117d471d67f4f2b3f7bdff29bdc918767974c465df8fa1afa6bd6c29c0a36d51f71c4183673d906f3","other":"6f60ef501b41f9049419b033ae8d793a18067bdcd60347537b0dc3873bdd9a2d10d24909cca7c39781765746128c2165596f6537a94f58279523faee71f9c51d","up":false},{"one":"6f60ef501b41f9049419b033ae8d793a18067bdcd60347537b0dc3873bdd9a2d10d24909cca7c39781765746128c2165596f6537a94f58279523faee71f9c51d","other":"4ee37acec2178ef120166265aaa2b64b09b315fb53861405ef46f2503c273eb9692e9cb4c2e67a8652254d430fd6e02dd3fe4cded20bb231a9fb834d292b0b24","up":false},{"one":"afe5b217dc512eee45575c189826ee5640d11a0ac9e8e4b03e9e62e6cf6df9de500bc8a36cb7d82a2280ce184409164f1772cc5c9e59ad04361522d2b8c364e0","other":"4f5ab12b9c5127c16739ad0d4f51adce90ba6736cd096eb185ea632789f4b26f1ebabdea4fd3b39dda5409ece6c2d92fd469cf4aecf9d29453e3e042c19b893b","up":true},{"one":"6f60ef501b41f9049419b033ae8d793a18067bdcd60347537b0dc3873bdd9a2d10d24909cca7c39781765746128c2165596f6537a94f58279523faee71f9c51d","other":"58cfb20d3da3641e0ad529b9edbd4b590a8d1dc9d1ed7b44ed3187dba9260bd7c732fc10981f5b9bffd31d362cb05150173618aa36138984431d94a323a9b313","up":false},{"one":"3612863ce0456c91785a829bf5c9d2b2fb97dda083a1847e5a4ebaa6fce1260faf4d1eb374c2225431a82774163835fb59c8cb0fa9fc0969eab5410c71109cc2","other":"0f9f7e2dce4ca266c3ac0ec3a8854200b54487f5308e3db418461aeb5f67c81d332619b6441b468e480941e63100ed1b263e7adc20689dc3dcda578bfca538fa","up":false},{"one":"23f9bdc82efbf57d3d40a1f2617d0311678fb4a3d6a50cb7e608c649bb618124a76c7ffd17387de963e1cd28d2bd5a61c98613f6e009a8a2a90d989827b35de0","other":"f915e2398aa5d4370de87504dd76c21a7d0be2581c2ab55b7a47743f1bbaef36384eaacec22760f1e914ceac9d96a10c3d66eb27475ef444e77fee979e6e88cb","up":true},{"one":"cb94a8270d0050378116b5815ff17dafbe20f5303839c4fd57b981d4687a4b145e4bccec7e9af9b9475005930148ffbfa97781a0762c8e9f352dc95565fc8732","other":"5bf29c02f07faf7ae8e46389e1b98df4f5e88c9316b5151685e6ae7b4e622cf171ff09f996aaa8ad846643b3bfcbd1ad96cdc249afccce439bb5c55246b95801","up":false},{"one":"ddaf3f8478501cda872c056c72063eb64d5b871fc5fff70704872802289dd2d348f73bc342b7f148a90cfaae2448ebf16fea196be9df891dc71a57fb410d59dd","other":"934a5fe1b91c1891ef4df7f67c027e0eb115d4c2ca4a1b76a135ebd4315c4fb835d6625223194e6a134407b38b0d3928fbc7bc924a3c6a538989a6cf200bf4bd","up":false},{"one":"2ca05ffc0ad771e1e045a47f1c0a79ce374a25e3c0e53c2a80d67e7479677003f62880251a83a5074f1c9651d828f1ff7e352935a9df141c1eb75a0c59b00a8b","other":"ddaf3f8478501cda872c056c72063eb64d5b871fc5fff70704872802289dd2d348f73bc342b7f148a90cfaae2448ebf16fea196be9df891dc71a57fb410d59dd","up":false},{"one":"d4b7c787981abec24353c7d496661692233797e3758189bf909a69fe87935bf6da0940daa4f12e81f20c5e88f70b472113688b71a0ae2f91a73ee0e6ff4c8591","other":"3d2df188704eeac09c8b291bf275a73888199a231c832c51dbc3d746968d4b51a7d5eae0c7c9b8c8e19f5e28d38c375e01abefa343f31dbe221deb837ab8a0df","up":false},{"one":"ee36d1d5dd69fd30242d7da2e941b34ade5581c7164fcc43288ecfc52937a98f1b31ade5d1e4dbf611cbe1c7875b2840c89435081cde471c271d7bc60e9ef211","other":"829b074b70d757da6aa00f7bace3cf1b5d2d4eeadb7f370c1a85374a01a70b54ac53d747267e386f3b41e6d790fecdd6e74b8f89745501ee82439a66ea54443a","up":false},{"one":"f54335964d9b4eb9813eb05f40ef1c523bbf0faac5a04c4737467d590fb6b55c7fa1fc5d4d32c5491d8766b9be6fdfd3ebdb25c5ffe1719f36c86ddf87ae3a85","other":"8d4920d6e3a6717699b5a3af068cbdfc16858d7e393d158d41b1b5f345b47129eef89e1d055386c518f400b134678c21590f0317dea3436d4cef60f45455cf12","up":true},{"one":"07f25fdeab2b44b2e92fc80fca7de9e4a8547d27a98a54593b3395c270a9ff3f2a5da62a2e8531ce86359f0cdc5b6513b773dfd64cce1b83e47065d9760a2c7e","other":"57fb1bb32bb2b1a87e44c6a7557e9c47c2032d107bcb0e34acd9ffd54d5d3df5701232db16f62f7549ba2721021898b03160b1dc5201e79606648c1dbc4a373b","up":false},{"one":"292c78c8e41606e98428096bc6f4609a7aa48e5c4d17eecc64d65faae4a7270b0c15f0cd74274015688ea0a9aff34f215c29118222e362a29c8d637963973a55","other":"caaf695c76cf7c047d3f3bfe019d01618e4871cee8ff3f347913da815bbcde145771486f916a44d03f59ea9bc217f169fd0c0765fda3f9b9b28d02a522e180b4","up":false},{"one":"df54af3bae257d437c5657905484e0d72e9560c46f8ba6b3437730234e05259b404cca40b0831e911605ff8a68a19e8fd7e958069ec8b40595928892f4fa220c","other":"b137cf2291b530a39516d882200848e7f27a2710e0839b4d25b4f367bea6a0c3aaef8c7c7851c00a2945adcd819ea0508610afc1f453b8bc512b7b4d4faacdf3","up":false},{"one":"9194a3a4c8f3235203e48bdb10902d958d26c342805ea6365af9711213536509719d917c694f9a4fbdde6889a4c92299a5301f0275bda4dbcd2541b5bff5b271","other":"2ab9513899c3c829b6284e56bf2b9862dd0156ec052b58615dba77d450dac642e534ec36ae5d3234262aff54e19f99856e908b9d8c1da660a7834a445610715b","up":false},{"one":"617595a230e0a74a3db3b47cd27b941e02bdee9a84cdfa8eaa63a55941eb5caa79e20fb69726a4d46a0e5aeed24039f8c5a20679a692df0bc140f42558ca9a2b","other":"d3105ede6c21bc643d523afcd1309a5dcf03f70797a92f167c3a19f86ae98882fe1a9d4094d7a3dee4a0833b8075b6c3e9aaa7f4879dc47bb388c3ae85522288","up":false},{"one":"9194a3a4c8f3235203e48bdb10902d958d26c342805ea6365af9711213536509719d917c694f9a4fbdde6889a4c92299a5301f0275bda4dbcd2541b5bff5b271","other":"92d6ef729992f0de886076e5f8cdc42cbbd70b29e79c25e0b3d22b6575d3d2508d47b42f581e335455483d43625bce4e55f88cab9ff2073ee8dab746357864fd","up":false},{"one":"cb321c9b0fe2eb3617b8e2461aab170a9dad2c9b04a10eead4e37e551197ea0a7500eb1cb7b155efe1886486ef3d252d8ff0d309f2906a1126ca011d037da70a","other":"27d9048707a89f1a61e44fdae523c0128f2a7050308bd3cfefa6c3e03040a0e22f11ab41275f22b8706e6695ab93320e2af35179d772581db5f49f960750f2f7","up":false},{"one":"315b8a1711f680c2eaa607e35ef7a9e19c2b61721af8a7e08f1325dde1fe33cf1f47b3cc4acf12d541631041cf1b42754875fd1c9b66ee32797b72b9f7711256","other":"1d0244a13affe60996fe3cf51ba624adc746de0c7ea68ec5a31311a36077c5b5495e3d95c9642875db44c7ecae6ffed22e45f2e2d024d486760be2af9f4cf2cd","up":true},{"one":"cb321c9b0fe2eb3617b8e2461aab170a9dad2c9b04a10eead4e37e551197ea0a7500eb1cb7b155efe1886486ef3d252d8ff0d309f2906a1126ca011d037da70a","other":"2b70e5ffcc0bb1c4f8acc09dd1016e67c9c96c92d091ad481efbb71bd8b2a5a5869c6d668617a9b2cbfe91baf5edfe150c3824c84d90899a974099071d171441","up":false},{"one":"fe8ac5d33cd8ab6a1dad9567cdfb89b431a5c4f4a584fc608b92e7dfd06f70988e71e2f11f9fda9ee797c9ffba83bc085939fdf2522dde39f28202be92650566","other":"eab86c521f8f1ac67c015ab713f1236a08b0200757a96bf87ab8301e7967ae62361f0e14da14ca294fc8cb3b4726b52f4773101e21b032977c6a647241b59c73","up":false},{"one":"fe8ac5d33cd8ab6a1dad9567cdfb89b431a5c4f4a584fc608b92e7dfd06f70988e71e2f11f9fda9ee797c9ffba83bc085939fdf2522dde39f28202be92650566","other":"4b784f072b7c96c30612767425f552e30e45157e70139dfbe0ae4ff86dc31601adec60f8a3ad9747b02b5219073d8813af9b09d59eaf7ddb7ee24856aff6fa8f","up":false},{"one":"afe5b217dc512eee45575c189826ee5640d11a0ac9e8e4b03e9e62e6cf6df9de500bc8a36cb7d82a2280ce184409164f1772cc5c9e59ad04361522d2b8c364e0","other":"6c143960dbe3ba4c95e8debc1fda5f420a2a673eb46f7ff7d9a30f4cd2067e67ef8926bf17f0c99b16c79b6dc066b52409a11d47117d4fda4211636b1b74f96c","up":true},{"one":"315b8a1711f680c2eaa607e35ef7a9e19c2b61721af8a7e08f1325dde1fe33cf1f47b3cc4acf12d541631041cf1b42754875fd1c9b66ee32797b72b9f7711256","other":"352407b42726dcd1aacc46a912ed8124b8b6a3da4e33dab742e40aa2452953d35dc8f42eddc76695ae2317e9f15dde2cd21be4ce826934695ad1847455661d1b","up":true},{"one":"7865b82e44add2cea6ebcbaba9c152184331a2940fe73f6f9bb940bda8a59ab4cf4760894b9cadcaa54e36fbb712ad619346a49a85e32cdf2b53cda1ac1e0658","other":"b53078000796f1cdb04dfeac424d5e3e37e30f00bd5bebf9a9ea0525c62917612b3a8f508df6bea59e3c7e4cd1aa530841f9a8af54e44f5617a13dee2c6ff007","up":false},{"one":"1bc1d6155ba35d29ea16938994e08df76ebd8f16bd180bd6a9b9d8798d0745889fe72d641dd78bd8ec13526929f7eb5aaa6a388430fa69033d6db581e53c6422","other":"b3316f4fd7dec218a52331f25d17a2faf0f2a417808d7dbb80038154abfbcd2d78da074837b648cff28675f4aa0d65ddb7d15abf3d7e0391d401e313a3ef24a2","up":false},{"one":"8ca3b63cb84f1e9883d82809a9b6777ec1029ecda96fe93b4d494ee9cbefcad13f381b3e480136e542e01054fe1ede66c65db84a0009871ce49383db461c8438","other":"3e488a7208ce0e097ce47fc6651a13e95cae137d1a054a09b04d2f59d45faa2594a8c3b395e77ad1a3c2edcd827dda73c0c97dbaa6d9519a79184a0aca01ac4b","up":false},{"one":"3612863ce0456c91785a829bf5c9d2b2fb97dda083a1847e5a4ebaa6fce1260faf4d1eb374c2225431a82774163835fb59c8cb0fa9fc0969eab5410c71109cc2","other":"3e488a7208ce0e097ce47fc6651a13e95cae137d1a054a09b04d2f59d45faa2594a8c3b395e77ad1a3c2edcd827dda73c0c97dbaa6d9519a79184a0aca01ac4b","up":false},{"one":"ee36d1d5dd69fd30242d7da2e941b34ade5581c7164fcc43288ecfc52937a98f1b31ade5d1e4dbf611cbe1c7875b2840c89435081cde471c271d7bc60e9ef211","other":"e267e71c2dcdbe5a500b23444d2d4037ea15afba8f4f2b1c0e54a274450404fbee6fa5439f7cddf4ba1aa28fa93e434b01c239add58e30a5423ca3a481584d6b","up":false},{"one":"65e954e60837bda10654480b227fa3bcc6e63356c52079002a27e836cd82ae2934ba77da60080e4b9f2d9324b982b24959bfd9624302e6c330408381054b43e9","other":"6f60ef501b41f9049419b033ae8d793a18067bdcd60347537b0dc3873bdd9a2d10d24909cca7c39781765746128c2165596f6537a94f58279523faee71f9c51d","up":true},{"one":"7f357b8d81bc2e5c6fcb081f23a42b3e2439f050d45c45851994a268d1c71fcb1f39f8c3f75ce921d3fbf80fc0e73f0b9609d72001dc4a6b65b526d312a4f43a","other":"2b70e5ffcc0bb1c4f8acc09dd1016e67c9c96c92d091ad481efbb71bd8b2a5a5869c6d668617a9b2cbfe91baf5edfe150c3824c84d90899a974099071d171441","up":true},{"one":"7f357b8d81bc2e5c6fcb081f23a42b3e2439f050d45c45851994a268d1c71fcb1f39f8c3f75ce921d3fbf80fc0e73f0b9609d72001dc4a6b65b526d312a4f43a","other":"c73d088ade8756c74832c73542bcdb3e52f670f7a74ad3a7eac2a9e3ece6bd081f782a8e1d3f9a40b9aa9201509110f37fc57fcb10ee1ef3ef07b7eab019782e","up":true},{"one":"afe5b217dc512eee45575c189826ee5640d11a0ac9e8e4b03e9e62e6cf6df9de500bc8a36cb7d82a2280ce184409164f1772cc5c9e59ad04361522d2b8c364e0","other":"f54335964d9b4eb9813eb05f40ef1c523bbf0faac5a04c4737467d590fb6b55c7fa1fc5d4d32c5491d8766b9be6fdfd3ebdb25c5ffe1719f36c86ddf87ae3a85","up":true},{"one":"315b8a1711f680c2eaa607e35ef7a9e19c2b61721af8a7e08f1325dde1fe33cf1f47b3cc4acf12d541631041cf1b42754875fd1c9b66ee32797b72b9f7711256","other":"831cde5b651ba327b059da4c7f84b184bdd6bb99c6690ae816affe25d42c6c3dbe5b59e2b6bf23e9d0f6c485bd341ea57ba1a8220d18b0a40e156b77d84f79ef","up":false},{"one":"8d4920d6e3a6717699b5a3af068cbdfc16858d7e393d158d41b1b5f345b47129eef89e1d055386c518f400b134678c21590f0317dea3436d4cef60f45455cf12","other":"ed6c793eb4565aa9d883a76fad6c97ad0b878b9ef0235e11e89db1af25a9653205f725c6ea258b84bde134f1a6437c6d109b859d17509e5016c4ab98be59032a","up":true},{"one":"7865b82e44add2cea6ebcbaba9c152184331a2940fe73f6f9bb940bda8a59ab4cf4760894b9cadcaa54e36fbb712ad619346a49a85e32cdf2b53cda1ac1e0658","other":"855bdf057f4a6b095e2000ada199447b5b4f2f8d78d2ecbaa0ff1fbf761788870ee999266ad3b26efa02be1a46a4d92ac0debb85a2ceab3442394ee7d99e5355","up":false},{"one":"d4b7c787981abec24353c7d496661692233797e3758189bf909a69fe87935bf6da0940daa4f12e81f20c5e88f70b472113688b71a0ae2f91a73ee0e6ff4c8591","other":"f915e2398aa5d4370de87504dd76c21a7d0be2581c2ab55b7a47743f1bbaef36384eaacec22760f1e914ceac9d96a10c3d66eb27475ef444e77fee979e6e88cb","up":false},{"one":"759f46661056bcbb30c7706c9fb87e22a30feb523bd53ae5d18db043efa45b49a2b8982abebdd598fe0912a05896390ec2eabe5e160cbafc0771990708ad8c28","other":"1bc1d6155ba35d29ea16938994e08df76ebd8f16bd180bd6a9b9d8798d0745889fe72d641dd78bd8ec13526929f7eb5aaa6a388430fa69033d6db581e53c6422","up":false},{"one":"f54335964d9b4eb9813eb05f40ef1c523bbf0faac5a04c4737467d590fb6b55c7fa1fc5d4d32c5491d8766b9be6fdfd3ebdb25c5ffe1719f36c86ddf87ae3a85","other":"89a5b92a9ca045f12c35a70084e6f41f9775a25d6f105f8c9349c7b5e107179d8a96bdbb113b2680edf5183e9a42fd64bd7b29d0dc7797c583b833f869313699","up":false},{"one":"7f357b8d81bc2e5c6fcb081f23a42b3e2439f050d45c45851994a268d1c71fcb1f39f8c3f75ce921d3fbf80fc0e73f0b9609d72001dc4a6b65b526d312a4f43a","other":"aa9a94d6e4eaaed20113c21752c224e3a052abd3769bd6e832759dbaf5154a943cf094eacdcb0727c2fe51a11bd7fc0793d7d5e3312b0aba89d428a00e1fde0c","up":true},{"one":"d4b7c787981abec24353c7d496661692233797e3758189bf909a69fe87935bf6da0940daa4f12e81f20c5e88f70b472113688b71a0ae2f91a73ee0e6ff4c8591","other":"c9cd9dfb9f90a7948ac5a42c7bd63263f2eef6e1d85547559f7d2ecbf5f9cd1eab051b8e9e661b573c275d84091a44e73f6fc6bcc91dcdb674bd5d939190fc01","up":false},{"one":"d4b7c787981abec24353c7d496661692233797e3758189bf909a69fe87935bf6da0940daa4f12e81f20c5e88f70b472113688b71a0ae2f91a73ee0e6ff4c8591","other":"1944f98d4db32c56a5efda5a79aa5f276bfab1e084d6611fec0e735b8bc0f45b457cdb74a23fc83b2377821fa8316123c9877acd6db7c41058ca5d3cfedaecf9","up":false},{"one":"eaca77d20c4ad6b87649eba21b750a4b1a2c575e06bc42679d18fce16fea15212e9a7408c16f3b24d8dfd1e397314637e72e292845d09534a39035bd9203ee9e","other":"d4b7c787981abec24353c7d496661692233797e3758189bf909a69fe87935bf6da0940daa4f12e81f20c5e88f70b472113688b71a0ae2f91a73ee0e6ff4c8591","up":false},{"one":"eaca77d20c4ad6b87649eba21b750a4b1a2c575e06bc42679d18fce16fea15212e9a7408c16f3b24d8dfd1e397314637e72e292845d09534a39035bd9203ee9e","other":"7ac5b07eb555af3bb4ca3f0f4b45204d43cc3798c244435909b97d9a32fc3abf0b50666e260e046bce826a7a102a92d389f8f39c5311e83bb34beddac29d50e3","up":false},{"one":"315b8a1711f680c2eaa607e35ef7a9e19c2b61721af8a7e08f1325dde1fe33cf1f47b3cc4acf12d541631041cf1b42754875fd1c9b66ee32797b72b9f7711256","other":"57b47f692f4d69a5d2c9c193680eb4ccb5a6c574662df0138504a549f3ea74f20c5b866ac4d9e76c4b49c83f5fd692ead928ea20dfcf643a11a1c1e841c0ec42","up":false},{"one":"315b8a1711f680c2eaa607e35ef7a9e19c2b61721af8a7e08f1325dde1fe33cf1f47b3cc4acf12d541631041cf1b42754875fd1c9b66ee32797b72b9f7711256","other":"e3c8a97a2d95dd543f9e2b41d9dce6256e284296f866f4f92e9925f8c7519dea23fd6d1a11153b93c10d6a32295e7b9bcc16024e690e4a0dc84fd25ee0f31b2c","up":false},{"one":"8ca3b63cb84f1e9883d82809a9b6777ec1029ecda96fe93b4d494ee9cbefcad13f381b3e480136e542e01054fe1ede66c65db84a0009871ce49383db461c8438","other":"a99852c5bf08ea4713af9cade5343d1259bfb90401aca7fcff18c58cd56a98804dd16c61fea71039c0ac31b9bbbb9dc5aeaf0c2f074d3365e88d17031802d636","up":false},{"one":"afe5b217dc512eee45575c189826ee5640d11a0ac9e8e4b03e9e62e6cf6df9de500bc8a36cb7d82a2280ce184409164f1772cc5c9e59ad04361522d2b8c364e0","other":"4de378164d77a28c90cf162dd1b465e0282ee17aa7d3bb3179252466f72da33a36c9f298f7c9498e38dba4018e7ce3e5fe631c83842cd9059e23a7fece366d87","up":true},{"one":"d4b7c787981abec24353c7d496661692233797e3758189bf909a69fe87935bf6da0940daa4f12e81f20c5e88f70b472113688b71a0ae2f91a73ee0e6ff4c8591","other":"5df58ba12334a1b4f983d642fe435901261767cd81f8f37c43e359f5584664e4d287e8c2275995604a3b3a4823418e35cd899a3db2a7db31570e19512f375481","up":false},{"one":"8ca3b63cb84f1e9883d82809a9b6777ec1029ecda96fe93b4d494ee9cbefcad13f381b3e480136e542e01054fe1ede66c65db84a0009871ce49383db461c8438","other":"c8b0dba45104fc7c7dff3ce078a0d3f5ade6198bb4656e2bee8076387929133e5ef2bd293b130a9d4f6a6974ca17e8b4a8f406d1219880f1e0f99c65c63af5a4","up":false},{"one":"afe5b217dc512eee45575c189826ee5640d11a0ac9e8e4b03e9e62e6cf6df9de500bc8a36cb7d82a2280ce184409164f1772cc5c9e59ad04361522d2b8c364e0","other":"57cd4c0048b459192ee46e19ec7df777e600f256e0dc8c3019431eb7bec3c020b9504ec7aea3dba8188658ca5b830ec40af6a8540ce10e04badc6c695d009271","up":true},{"one":"8d4920d6e3a6717699b5a3af068cbdfc16858d7e393d158d41b1b5f345b47129eef89e1d055386c518f400b134678c21590f0317dea3436d4cef60f45455cf12","other":"6b01079463ec2f649db8634cb7a596261c79a8f714d954c772528e0547b017f8ce405e4a0ea9d32270848180e0f77b8c0b022cf95c85e777626edd4d24ea21d2","up":true},{"one":"f54335964d9b4eb9813eb05f40ef1c523bbf0faac5a04c4737467d590fb6b55c7fa1fc5d4d32c5491d8766b9be6fdfd3ebdb25c5ffe1719f36c86ddf87ae3a85","other":"f6ca39b3ad803e99f4e4e9cf759fff6abdf06e6972bdbe524f6eb930c669d6f0e9b91f3de9df394b0d661b068273861391bdbac948ad911351c48cf02f874db6","up":false},{"one":"8d4920d6e3a6717699b5a3af068cbdfc16858d7e393d158d41b1b5f345b47129eef89e1d055386c518f400b134678c21590f0317dea3436d4cef60f45455cf12","other":"4a030ebcb1a59230759d25a3c87daed22906b520d55a78eab2083bb52358ddc3a5d2d7c3265e6c54a990bf32d0dacb85905a4173d72ac18fcd74c43ecb8635c5","up":false},{"one":"8d4920d6e3a6717699b5a3af068cbdfc16858d7e393d158d41b1b5f345b47129eef89e1d055386c518f400b134678c21590f0317dea3436d4cef60f45455cf12","other":"990b1db3ab1390219e8866d39fa4441bb5bb89ad786b3e255771869fcd08906dcf63f34007481769c7462edbcc665acc0a552e3733360b8d8c310c9321a5550f","up":false},{"one":"62666b24d1026345349edb6a878cdc27d6fee8254e83f79a298ce2805260d97aa46423deae440f86ced5cd99b30e970c8e1ea1046752b17d8c80dc68d9a49b60","other":"990b1db3ab1390219e8866d39fa4441bb5bb89ad786b3e255771869fcd08906dcf63f34007481769c7462edbcc665acc0a552e3733360b8d8c310c9321a5550f","up":true},{"one":"62666b24d1026345349edb6a878cdc27d6fee8254e83f79a298ce2805260d97aa46423deae440f86ced5cd99b30e970c8e1ea1046752b17d8c80dc68d9a49b60","other":"ee36d1d5dd69fd30242d7da2e941b34ade5581c7164fcc43288ecfc52937a98f1b31ade5d1e4dbf611cbe1c7875b2840c89435081cde471c271d7bc60e9ef211","up":true},{"one":"62666b24d1026345349edb6a878cdc27d6fee8254e83f79a298ce2805260d97aa46423deae440f86ced5cd99b30e970c8e1ea1046752b17d8c80dc68d9a49b60","other":"8f88c7ec044f758f29bd8d12a5170bd973aec8f6cddbf512b910c4b75a0fec09c5e198bcd65622037f897759db68da2328b4a7ca93585dc9cb62e46d2a6c0864","up":true},{"one":"eaca77d20c4ad6b87649eba21b750a4b1a2c575e06bc42679d18fce16fea15212e9a7408c16f3b24d8dfd1e397314637e72e292845d09534a39035bd9203ee9e","other":"f6ca39b3ad803e99f4e4e9cf759fff6abdf06e6972bdbe524f6eb930c669d6f0e9b91f3de9df394b0d661b068273861391bdbac948ad911351c48cf02f874db6","up":false},{"one":"eaca77d20c4ad6b87649eba21b750a4b1a2c575e06bc42679d18fce16fea15212e9a7408c16f3b24d8dfd1e397314637e72e292845d09534a39035bd9203ee9e","other":"315b8a1711f680c2eaa607e35ef7a9e19c2b61721af8a7e08f1325dde1fe33cf1f47b3cc4acf12d541631041cf1b42754875fd1c9b66ee32797b72b9f7711256","up":false},{"one":"f54335964d9b4eb9813eb05f40ef1c523bbf0faac5a04c4737467d590fb6b55c7fa1fc5d4d32c5491d8766b9be6fdfd3ebdb25c5ffe1719f36c86ddf87ae3a85","other":"5dc69635f6d573c824ea83b18593a47f9f21a6f91ce18d2bf977c97d21f8d2a8ce88829244d12a07d949bbd52fe8a2035bc89685fe1bdd4ee20d766d75d3deee","up":false},{"one":"eaca77d20c4ad6b87649eba21b750a4b1a2c575e06bc42679d18fce16fea15212e9a7408c16f3b24d8dfd1e397314637e72e292845d09534a39035bd9203ee9e","other":"7808fb798d22e78fb1d39b87ddf99a503f820993bc64149eca9e81d9d58fc1adea60d8de14a4f06cb89f3190c0ef0c5e182621a14c9361ccb7e0cee667599cc3","up":false},{"one":"62666b24d1026345349edb6a878cdc27d6fee8254e83f79a298ce2805260d97aa46423deae440f86ced5cd99b30e970c8e1ea1046752b17d8c80dc68d9a49b60","other":"c73d088ade8756c74832c73542bcdb3e52f670f7a74ad3a7eac2a9e3ece6bd081f782a8e1d3f9a40b9aa9201509110f37fc57fcb10ee1ef3ef07b7eab019782e","up":false},{"one":"62666b24d1026345349edb6a878cdc27d6fee8254e83f79a298ce2805260d97aa46423deae440f86ced5cd99b30e970c8e1ea1046752b17d8c80dc68d9a49b60","other":"a127faa19dcb7da585983d36a8e9d3e9a44a6db68507b60c70da71011f44ce377944802f39cd65f5a705cd8249ac1ef7ed8fd699349098f3f8e23b37592c80ae","up":false},{"one":"eaca77d20c4ad6b87649eba21b750a4b1a2c575e06bc42679d18fce16fea15212e9a7408c16f3b24d8dfd1e397314637e72e292845d09534a39035bd9203ee9e","other":"0cacda5560faff9d20e29a0625d3cd340ec075f198a50ab8b79338cee0e0db84c7c7e71042fd8c8f73e507b570de5d26c39473136b575f0167625a1168309ec5","up":false},{"one":"8d4920d6e3a6717699b5a3af068cbdfc16858d7e393d158d41b1b5f345b47129eef89e1d055386c518f400b134678c21590f0317dea3436d4cef60f45455cf12","other":"7646d08b3e24183e3814de130235c41eb88a5a2abff23eaff3c91954ad3ef55fe27da422dac5b894312276bf1a2f1aebb8b636a8d4a0c93d9b016d441df3fa19","up":false},{"one":"8d4920d6e3a6717699b5a3af068cbdfc16858d7e393d158d41b1b5f345b47129eef89e1d055386c518f400b134678c21590f0317dea3436d4cef60f45455cf12","other":"e267e71c2dcdbe5a500b23444d2d4037ea15afba8f4f2b1c0e54a274450404fbee6fa5439f7cddf4ba1aa28fa93e434b01c239add58e30a5423ca3a481584d6b","up":false},{"one":"7f357b8d81bc2e5c6fcb081f23a42b3e2439f050d45c45851994a268d1c71fcb1f39f8c3f75ce921d3fbf80fc0e73f0b9609d72001dc4a6b65b526d312a4f43a","other":"e2a27dcdee1f89fa362a85c4397840cd8be4ad8d1b9ccb23188c303bcab7619f38772f71385922d090390973b62fb8249efc103f71bc761041bcb3880ec0b935","up":false},{"one":"d4b7c787981abec24353c7d496661692233797e3758189bf909a69fe87935bf6da0940daa4f12e81f20c5e88f70b472113688b71a0ae2f91a73ee0e6ff4c8591","other":"cb321c9b0fe2eb3617b8e2461aab170a9dad2c9b04a10eead4e37e551197ea0a7500eb1cb7b155efe1886486ef3d252d8ff0d309f2906a1126ca011d037da70a","up":false},{"one":"7f357b8d81bc2e5c6fcb081f23a42b3e2439f050d45c45851994a268d1c71fcb1f39f8c3f75ce921d3fbf80fc0e73f0b9609d72001dc4a6b65b526d312a4f43a","other":"7e2b0b4f3b55e97bd7241b984ad117af33bf3baacd22b3ed503a8a59f75828df745fb3ce3be4276d83eb484e64d9aa251103fa994ef119eaddb97a3503b9f292","up":false},{"one":"62666b24d1026345349edb6a878cdc27d6fee8254e83f79a298ce2805260d97aa46423deae440f86ced5cd99b30e970c8e1ea1046752b17d8c80dc68d9a49b60","other":"9bd4f0adb9a966cc5ba632f1b540fe9cd6c8e39fe1a041b315697679cfb04b735952062ce057d456677cc34a84301f26bb727a4ab2646fee734f80a22c620746","up":false},{"one":"62666b24d1026345349edb6a878cdc27d6fee8254e83f79a298ce2805260d97aa46423deae440f86ced5cd99b30e970c8e1ea1046752b17d8c80dc68d9a49b60","other":"6b4e376e9c94242b6d42688c22aa9ab418cb6dfb1cbca1c69de0feceec8d3af29fb005017aaa6e503cc0c03cf0dc5bcab55e01cd6f64b9efa02ed87c03020003","up":false},{"one":"eaca77d20c4ad6b87649eba21b750a4b1a2c575e06bc42679d18fce16fea15212e9a7408c16f3b24d8dfd1e397314637e72e292845d09534a39035bd9203ee9e","other":"f33d1f3e460574706ac1c7fc9ebb4683b173496ce3e80017d1c3521bca03d5a41a9c7a6cde8347d2238917b7cc58cab000ce7ccf6bb408561015a2ecbe613408","up":false},{"one":"7f357b8d81bc2e5c6fcb081f23a42b3e2439f050d45c45851994a268d1c71fcb1f39f8c3f75ce921d3fbf80fc0e73f0b9609d72001dc4a6b65b526d312a4f43a","other":"4e95fb8943ef6502fa470870a7ace4ca11e18589bd2073167543a922317b35e40b5068934d07e56c8fdd23354dfad51fd2899db854f189841f02b5914cd97749","up":false},{"one":"62666b24d1026345349edb6a878cdc27d6fee8254e83f79a298ce2805260d97aa46423deae440f86ced5cd99b30e970c8e1ea1046752b17d8c80dc68d9a49b60","other":"c903c5ee3d9cd65bea3ea777e39282c33e1349d945411fb2f16321bf582c2f400956a98fbafe5873fc5f6f6a9a051df5da7e94cbd340f935abe80f91e79ef875","up":false}]} \ No newline at end of file diff --git a/swarm/network/stream/testing/snapshot_32.json b/swarm/network/stream/testing/snapshot_32.json new file mode 100644 index 0000000000..ac06fba78d --- /dev/null +++ b/swarm/network/stream/testing/snapshot_32.json @@ -0,0 +1 @@ +{"nodes":[{"node":{"info":{"id":"d2a392e9e7383b895587a7d6eea4a157de20caa9e2c62b4da5a8ff3186d129fee1330ddf3d180b1f59e1aa83686cd163222e38c84a84a0f60139968d6a56cbca","name":"node_d2a392e9e7383b895587a7d6eea4a157de20caa9e2c62b4da5a8ff3186d129fee1330ddf3d180b1f59e1aa83686cd163222e38c84a84a0f60139968d6a56cbca","enode":"enode://d2a392e9e7383b895587a7d6eea4a157de20caa9e2c62b4da5a8ff3186d129fee1330ddf3d180b1f59e1aa83686cd163222e38c84a84a0f60139968d6a56cbca@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"e4iex7BnTKj2UIo12SAUnxgm1BC3luUr+nIwax+vuuQ=","hive":"\n=========================================================================\nTue Apr 10 09:40:43 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 7b889e\npopulation: 18 (31), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 11 a0ca b17b 8d09 9756 | 23 bfb0 (0) b17b (0) b412 (0) a829 (0)\n001 3 391e 24a1 231c | 4 391e (0) 35b6 (0) 24a1 (0) 231c (0)\n============ DEPTH: 2 ==========================================\n002 3 59a3 5ec7 4848 | 3 59a3 (0) 5ec7 (0) 4848 (0)\n003 0 | 0\n004 1 7514 | 1 7514 (0)\n005 0 | 0\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"d2a392e9e7383b895587a7d6eea4a157de20caa9e2c62b4da5a8ff3186d129fee1330ddf3d180b1f59e1aa83686cd163222e38c84a84a0f60139968d6a56cbca","private_key":"b571efd8e722db149f98412648275074a828e5137b46722413039489eb617b36","name":"node_d2a392e9e7383b895587a7d6eea4a157de20caa9e2c62b4da5a8ff3186d129fee1330ddf3d180b1f59e1aa83686cd163222e38c84a84a0f60139968d6a56cbca","services":["streamer"],"enable_msg_events":true,"port":61468},"up":true}},{"node":{"info":{"id":"6c0b3b7c1c08bb558d92f0172fb8bfabe52a4bf8348b2f82e50c6d492a595dd0677b4559d7d2cd5a6e51ecdaf9a0f898f154730b87a8d9b265c6a54f9f6802a7","name":"node_6c0b3b7c1c08bb558d92f0172fb8bfabe52a4bf8348b2f82e50c6d492a595dd0677b4559d7d2cd5a6e51ecdaf9a0f898f154730b87a8d9b265c6a54f9f6802a7","enode":"enode://6c0b3b7c1c08bb558d92f0172fb8bfabe52a4bf8348b2f82e50c6d492a595dd0677b4559d7d2cd5a6e51ecdaf9a0f898f154730b87a8d9b265c6a54f9f6802a7@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"kUg57JWxAJIkKaNhZSLa/8UcGkw5spfR2M7FkVZ7TMw=","hive":"\n=========================================================================\nTue Apr 10 09:40:43 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 914839\npopulation: 10 (31), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 7b88 4848 | 9 391e (0) 35b6 (0) 24a1 (0) 231c (0)\n001 1 e7ac | 10 e7ac (0) c719 (0) d19a (0) d668 (0)\n002 4 a4e6 a0ca b412 bfb0 | 7 bfb0 (0) b17b (0) b412 (0) a4e6 (0)\n003 1 8d09 | 3 8d09 (0) 8e5f (0) 8f7d (0)\n004 0 | 0\n============ DEPTH: 5 ==========================================\n005 1 9756 | 1 9756 (0)\n006 1 930d | 1 930d (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"6c0b3b7c1c08bb558d92f0172fb8bfabe52a4bf8348b2f82e50c6d492a595dd0677b4559d7d2cd5a6e51ecdaf9a0f898f154730b87a8d9b265c6a54f9f6802a7","private_key":"fbd2e7bb8b511ed0878fc14a5923105866ab2c3bdf5ee2c52c1a2bc7c00a185e","name":"node_6c0b3b7c1c08bb558d92f0172fb8bfabe52a4bf8348b2f82e50c6d492a595dd0677b4559d7d2cd5a6e51ecdaf9a0f898f154730b87a8d9b265c6a54f9f6802a7","services":["streamer"],"enable_msg_events":true,"port":61469},"up":true}},{"node":{"info":{"id":"dc63b83b488b7b505d5b2a60680b7dc87b1c5b61509e8030ebc67512ba72c0f616c1594946878dfb29e79f351d7134306778a74d5f5b7d5e08dbdb6dd6ade359","name":"node_dc63b83b488b7b505d5b2a60680b7dc87b1c5b61509e8030ebc67512ba72c0f616c1594946878dfb29e79f351d7134306778a74d5f5b7d5e08dbdb6dd6ade359","enode":"enode://dc63b83b488b7b505d5b2a60680b7dc87b1c5b61509e8030ebc67512ba72c0f616c1594946878dfb29e79f351d7134306778a74d5f5b7d5e08dbdb6dd6ade359@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"SEh1KHBY547ZI5bgDzTnX5B6H0LVWXuejDCvy+UMGBA=","hive":"\n=========================================================================\nTue Apr 10 09:40:43 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 484875\npopulation: 7 (31), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 a829 9148 | 23 e7ac (0) c719 (0) d19a (0) d668 (0)\n001 1 391e | 4 391e (0) 35b6 (0) 24a1 (0) 231c (0)\n002 2 7514 7b88 | 2 7514 (0) 7b88 (0)\n============ DEPTH: 3 ==========================================\n003 2 59a3 5ec7 | 2 59a3 (0) 5ec7 (0)\n004 0 | 0\n005 0 | 0\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"dc63b83b488b7b505d5b2a60680b7dc87b1c5b61509e8030ebc67512ba72c0f616c1594946878dfb29e79f351d7134306778a74d5f5b7d5e08dbdb6dd6ade359","private_key":"60a362da222a74d3d81ed679549417d55a92c79b8e0aab1bf05eb2d01f82c0b2","name":"node_dc63b83b488b7b505d5b2a60680b7dc87b1c5b61509e8030ebc67512ba72c0f616c1594946878dfb29e79f351d7134306778a74d5f5b7d5e08dbdb6dd6ade359","services":["streamer"],"enable_msg_events":true,"port":61470},"up":true}},{"node":{"info":{"id":"eaa3ad48682b08d9c91907a79e82938c1b30108745b276788c830dfcb0c0e752134369d751230e95fb7ab9777c38dcd105ad123ec5cc86ef6dbdd11fe31aea93","name":"node_eaa3ad48682b08d9c91907a79e82938c1b30108745b276788c830dfcb0c0e752134369d751230e95fb7ab9777c38dcd105ad123ec5cc86ef6dbdd11fe31aea93","enode":"enode://eaa3ad48682b08d9c91907a79e82938c1b30108745b276788c830dfcb0c0e752134369d751230e95fb7ab9777c38dcd105ad123ec5cc86ef6dbdd11fe31aea93@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"qCk11M4hKJX62XgpzI4EvRrhxTMjr05tjixnO336q7k=","hive":"\n=========================================================================\nTue Apr 10 09:40:43 UTC 2018 KΛÐΞMLIΛ hive: queen's address: a82935\npopulation: 8 (31), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 4848 | 9 391e (0) 35b6 (0) 24a1 (0) 231c (0)\n001 1 d535 | 10 e7ac (0) c719 (0) d19a (0) d668 (0)\n002 2 9756 8d09 | 6 8d09 (0) 8e5f (0) 8f7d (0) 9756 (0)\n003 1 bfb0 | 3 bfb0 (0) b17b (0) b412 (0)\n============ DEPTH: 4 ==========================================\n004 3 a4e6 a1b5 a0ca | 3 a4e6 (0) a1b5 (0) a0ca (0)\n005 0 | 0\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"eaa3ad48682b08d9c91907a79e82938c1b30108745b276788c830dfcb0c0e752134369d751230e95fb7ab9777c38dcd105ad123ec5cc86ef6dbdd11fe31aea93","private_key":"00625fb0f90ed61656987faecdd0690f0a97c88e33f6e339fa3a8f4bfc1e640f","name":"node_eaa3ad48682b08d9c91907a79e82938c1b30108745b276788c830dfcb0c0e752134369d751230e95fb7ab9777c38dcd105ad123ec5cc86ef6dbdd11fe31aea93","services":["streamer"],"enable_msg_events":true,"port":61471},"up":true}},{"node":{"info":{"id":"331084cce2884ad912d5a20467c68fc261a02d6df0b60ff5b1427edc0885eab66a4f0f7e7fc9c676e994842f8126a3b34dbde91243f26bed6a0ba14babed56cc","name":"node_331084cce2884ad912d5a20467c68fc261a02d6df0b60ff5b1427edc0885eab66a4f0f7e7fc9c676e994842f8126a3b34dbde91243f26bed6a0ba14babed56cc","enode":"enode://331084cce2884ad912d5a20467c68fc261a02d6df0b60ff5b1427edc0885eab66a4f0f7e7fc9c676e994842f8126a3b34dbde91243f26bed6a0ba14babed56cc@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"1TVcXs7XygshCTTS5PEa4JvsHGIkZUjqCS3CnpmHFx8=","hive":"\n=========================================================================\nTue Apr 10 09:40:43 UTC 2018 KΛÐΞMLIΛ hive: queen's address: d5355c\npopulation: 8 (31), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 7b88 | 9 7b88 (0) 7514 (0) 4848 (0) 59a3 (0)\n001 1 a829 | 13 9148 (0) 930d (0) 9756 (0) 8d09 (0)\n002 1 e7ac | 1 e7ac (0)\n003 1 c719 | 1 c719 (0)\n004 1 de95 | 4 de95 (0) deee (0) dab5 (0) d812 (0)\n005 1 d19a | 1 d19a (0)\n============ DEPTH: 6 ==========================================\n006 1 d668 | 1 d668 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 1 d514 | 1 d514 (0)\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"331084cce2884ad912d5a20467c68fc261a02d6df0b60ff5b1427edc0885eab66a4f0f7e7fc9c676e994842f8126a3b34dbde91243f26bed6a0ba14babed56cc","private_key":"fbb38d0ed3ef4726052fdec97ddd7eb3a3feb3d2fd5ea6cffe8ff97b621958ce","name":"node_331084cce2884ad912d5a20467c68fc261a02d6df0b60ff5b1427edc0885eab66a4f0f7e7fc9c676e994842f8126a3b34dbde91243f26bed6a0ba14babed56cc","services":["streamer"],"enable_msg_events":true,"port":61472},"up":true}},{"node":{"info":{"id":"e00f9a5611008d54bbbfe6a1cf402e011c92f540b47a82b7795508d1b857eee4a522e26c8351ddf6e303d353ee35afecbf9f54d7aae36e6736174473ac4caf73","name":"node_e00f9a5611008d54bbbfe6a1cf402e011c92f540b47a82b7795508d1b857eee4a522e26c8351ddf6e303d353ee35afecbf9f54d7aae36e6736174473ac4caf73","enode":"enode://e00f9a5611008d54bbbfe6a1cf402e011c92f540b47a82b7795508d1b857eee4a522e26c8351ddf6e303d353ee35afecbf9f54d7aae36e6736174473ac4caf73@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"56ycOoyoBwOzSZo3bVfiqVI7O9PFzzW3pFDwr0RoBoY=","hive":"\n=========================================================================\nTue Apr 10 09:40:43 UTC 2018 KΛÐΞMLIΛ hive: queen's address: e7ac9c\npopulation: 16 (31), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 231c | 9 7b88 (0) 7514 (0) 4848 (0) 59a3 (0)\n001 6 b17b b412 bfb0 9148 | 13 9148 (0) 930d (0) 9756 (0) 8d09 (0)\n============ DEPTH: 2 ==========================================\n002 9 c719 deee de95 d812 | 9 c719 (0) de95 (0) deee (0) dab5 (0)\n003 0 | 0\n004 0 | 0\n005 0 | 0\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"e00f9a5611008d54bbbfe6a1cf402e011c92f540b47a82b7795508d1b857eee4a522e26c8351ddf6e303d353ee35afecbf9f54d7aae36e6736174473ac4caf73","private_key":"b5c12698375aa5215df48003ed13c94e00e6bee1a0b05277237d40f0fcfc625e","name":"node_e00f9a5611008d54bbbfe6a1cf402e011c92f540b47a82b7795508d1b857eee4a522e26c8351ddf6e303d353ee35afecbf9f54d7aae36e6736174473ac4caf73","services":["streamer"],"enable_msg_events":true,"port":61473},"up":true}},{"node":{"info":{"id":"e4b7b3bbeda388842ecb3688c041fe58bbd7e4566818a58b679e96215553dbf8569032a3ae941b3f8bb3e75886852d245bda5abf0c3cf70f532c38235e1a2175","name":"node_e4b7b3bbeda388842ecb3688c041fe58bbd7e4566818a58b679e96215553dbf8569032a3ae941b3f8bb3e75886852d245bda5abf0c3cf70f532c38235e1a2175","enode":"enode://e4b7b3bbeda388842ecb3688c041fe58bbd7e4566818a58b679e96215553dbf8569032a3ae941b3f8bb3e75886852d245bda5abf0c3cf70f532c38235e1a2175@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"Ixz0rWRm7c/4SbpfRAafUSZ9/aU10xpNckH12DwaUho=","hive":"\n=========================================================================\nTue Apr 10 09:40:43 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 231cf4\npopulation: 6 (31), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 e7ac a1b5 | 23 c719 (0) de95 (0) deee (0) dab5 (0)\n001 1 7b88 | 5 7b88 (0) 7514 (0) 4848 (0) 5ec7 (0)\n002 0 | 0\n============ DEPTH: 3 ==========================================\n003 2 391e 35b6 | 2 391e (0) 35b6 (0)\n004 0 | 0\n005 1 24a1 | 1 24a1 (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"e4b7b3bbeda388842ecb3688c041fe58bbd7e4566818a58b679e96215553dbf8569032a3ae941b3f8bb3e75886852d245bda5abf0c3cf70f532c38235e1a2175","private_key":"90e044c682c33ed90f5f5cac9b8181ee978d2cc9d3d3f545140858d324f1d7e1","name":"node_e4b7b3bbeda388842ecb3688c041fe58bbd7e4566818a58b679e96215553dbf8569032a3ae941b3f8bb3e75886852d245bda5abf0c3cf70f532c38235e1a2175","services":["streamer"],"enable_msg_events":true,"port":61474},"up":true}},{"node":{"info":{"id":"0679dbbb51fa0283bcba387daa2180955d402a0ed42155095fcaffb96dbfd6b4b1bb0ed2ccf11cd990dfed4a3b320ee3f64286116a7b617a35989a448c367119","name":"node_0679dbbb51fa0283bcba387daa2180955d402a0ed42155095fcaffb96dbfd6b4b1bb0ed2ccf11cd990dfed4a3b320ee3f64286116a7b617a35989a448c367119","enode":"enode://0679dbbb51fa0283bcba387daa2180955d402a0ed42155095fcaffb96dbfd6b4b1bb0ed2ccf11cd990dfed4a3b320ee3f64286116a7b617a35989a448c367119@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"obWrMBPAAxoWnnKEekUJ6DuZQIb92CsH+2yg18/p1Tc=","hive":"\n=========================================================================\nTue Apr 10 09:40:43 UTC 2018 KΛÐΞMLIΛ hive: queen's address: a1b5ab\npopulation: 9 (31), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 231c | 9 7b88 (0) 7514 (0) 4848 (0) 5ec7 (0)\n001 1 d19a | 10 e7ac (0) c719 (0) deee (0) de95 (0)\n002 1 8e5f | 6 8e5f (0) 8f7d (0) 8d09 (0) 9756 (0)\n003 3 b17b b412 bfb0 | 3 bfb0 (0) b17b (0) b412 (0)\n004 1 a829 | 1 a829 (0)\n============ DEPTH: 5 ==========================================\n005 1 a4e6 | 1 a4e6 (0)\n006 0 | 0\n007 1 a0ca | 1 a0ca (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"0679dbbb51fa0283bcba387daa2180955d402a0ed42155095fcaffb96dbfd6b4b1bb0ed2ccf11cd990dfed4a3b320ee3f64286116a7b617a35989a448c367119","private_key":"2371e6ff2ecc4144ee61efa958488eed6c1f739e81f27bf775db1e9b66e89054","name":"node_0679dbbb51fa0283bcba387daa2180955d402a0ed42155095fcaffb96dbfd6b4b1bb0ed2ccf11cd990dfed4a3b320ee3f64286116a7b617a35989a448c367119","services":["streamer"],"enable_msg_events":true,"port":61475},"up":true}},{"node":{"info":{"id":"a197cd9e7e2d19287745f486582b7242c991f36183e8b2bf4983d7a9b9026e9884e3295183f376cd796b814fdf352b1c8c5c609a0e5f5d5155ab925d4b6fdeb9","name":"node_a197cd9e7e2d19287745f486582b7242c991f36183e8b2bf4983d7a9b9026e9884e3295183f376cd796b814fdf352b1c8c5c609a0e5f5d5155ab925d4b6fdeb9","enode":"enode://a197cd9e7e2d19287745f486582b7242c991f36183e8b2bf4983d7a9b9026e9884e3295183f376cd796b814fdf352b1c8c5c609a0e5f5d5155ab925d4b6fdeb9@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"0ZoMZGEi6NC4FI2h9ks8t4H+l0aHoHHlqFIumiK8ZkY=","hive":"\n=========================================================================\nTue Apr 10 09:40:43 UTC 2018 KΛÐΞMLIΛ hive: queen's address: d19a0c\npopulation: 11 (31), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 7b88 | 9 7b88 (0) 7514 (0) 4848 (0) 5ec7 (0)\n001 2 930d a1b5 | 13 8e5f (0) 8f7d (0) 8d09 (0) 9756 (0)\n002 1 e7ac | 1 e7ac (0)\n003 1 c719 | 1 c719 (0)\n004 3 d812 deee de95 | 4 deee (0) de95 (0) dab5 (0) d812 (0)\n============ DEPTH: 5 ==========================================\n005 3 d668 d535 d514 | 3 d668 (0) d535 (0) d514 (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"a197cd9e7e2d19287745f486582b7242c991f36183e8b2bf4983d7a9b9026e9884e3295183f376cd796b814fdf352b1c8c5c609a0e5f5d5155ab925d4b6fdeb9","private_key":"87a3816c95159c72a7ad1b466ae9a095f12c7db210fcddd8dbaaa697220f88bb","name":"node_a197cd9e7e2d19287745f486582b7242c991f36183e8b2bf4983d7a9b9026e9884e3295183f376cd796b814fdf352b1c8c5c609a0e5f5d5155ab925d4b6fdeb9","services":["streamer"],"enable_msg_events":true,"port":61476},"up":true}},{"node":{"info":{"id":"eb11498b8cebc767d535481938c664359c6c84674da4d8fac729df64e288248bb020477ad4422cf1b7cea844db5ee12bb5cea82ac6e89a338d8ca1073e061f4c","name":"node_eb11498b8cebc767d535481938c664359c6c84674da4d8fac729df64e288248bb020477ad4422cf1b7cea844db5ee12bb5cea82ac6e89a338d8ca1073e061f4c","enode":"enode://eb11498b8cebc767d535481938c664359c6c84674da4d8fac729df64e288248bb020477ad4422cf1b7cea844db5ee12bb5cea82ac6e89a338d8ca1073e061f4c@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"kw3lbB6kShs58vmfZ4DOKEBC1ZI4rbEEcWfGMpvkopE=","hive":"\n=========================================================================\nTue Apr 10 09:40:43 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 930de5\npopulation: 8 (31), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 7b88 | 9 7b88 (0) 7514 (0) 4848 (0) 5ec7 (0)\n001 3 d19a d668 d514 | 10 e7ac (0) c719 (0) deee (0) de95 (0)\n002 1 bfb0 | 7 bfb0 (0) b17b (0) b412 (0) a829 (0)\n003 1 8d09 | 3 8e5f (0) 8f7d (0) 8d09 (0)\n004 0 | 0\n============ DEPTH: 5 ==========================================\n005 1 9756 | 1 9756 (0)\n006 1 9148 | 1 9148 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"eb11498b8cebc767d535481938c664359c6c84674da4d8fac729df64e288248bb020477ad4422cf1b7cea844db5ee12bb5cea82ac6e89a338d8ca1073e061f4c","private_key":"6729988ebc04b9398883c068277630ff0de16f16e3f67114380acfdb0d1b530b","name":"node_eb11498b8cebc767d535481938c664359c6c84674da4d8fac729df64e288248bb020477ad4422cf1b7cea844db5ee12bb5cea82ac6e89a338d8ca1073e061f4c","services":["streamer"],"enable_msg_events":true,"port":61477},"up":true}},{"node":{"info":{"id":"d3b5df108f35a82e569016a06fefadb52797dafb505de1981f6678e2156574893a169b0adcc595377267dec0b7d620b5b50c7e7696c39eecee2c3e5f7bf71d18","name":"node_d3b5df108f35a82e569016a06fefadb52797dafb505de1981f6678e2156574893a169b0adcc595377267dec0b7d620b5b50c7e7696c39eecee2c3e5f7bf71d18","enode":"enode://d3b5df108f35a82e569016a06fefadb52797dafb505de1981f6678e2156574893a169b0adcc595377267dec0b7d620b5b50c7e7696c39eecee2c3e5f7bf71d18@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"1RSGHlc4KGF2BNtbiPQHsVJAkwhldFT5n8KCC0SkUIg=","hive":"\n=========================================================================\nTue Apr 10 09:40:43 UTC 2018 KΛÐΞMLIΛ hive: queen's address: d51486\npopulation: 8 (31), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 7b88 | 9 7b88 (0) 7514 (0) 4848 (0) 5ec7 (0)\n001 1 930d | 13 bfb0 (0) b17b (0) b412 (0) a829 (0)\n002 1 e7ac | 1 e7ac (0)\n003 1 c719 | 1 c719 (0)\n004 1 dab5 | 4 dab5 (0) d812 (0) deee (0) de95 (0)\n005 1 d19a | 1 d19a (0)\n============ DEPTH: 6 ==========================================\n006 1 d668 | 1 d668 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 1 d535 | 1 d535 (0)\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"d3b5df108f35a82e569016a06fefadb52797dafb505de1981f6678e2156574893a169b0adcc595377267dec0b7d620b5b50c7e7696c39eecee2c3e5f7bf71d18","private_key":"208068d7a920e42db04340bf473f822d4d663f5139d664c4375294dd61b1dff3","name":"node_d3b5df108f35a82e569016a06fefadb52797dafb505de1981f6678e2156574893a169b0adcc595377267dec0b7d620b5b50c7e7696c39eecee2c3e5f7bf71d18","services":["streamer"],"enable_msg_events":true,"port":61478},"up":true}},{"node":{"info":{"id":"1be1903b1104bfae07438fb888993cb3e812fc38c8f26af2e68bff9f1758e9a69b29be3636ee24060c09ce900bad2004681e1083792b2a6e532bbfc07a3a0459","name":"node_1be1903b1104bfae07438fb888993cb3e812fc38c8f26af2e68bff9f1758e9a69b29be3636ee24060c09ce900bad2004681e1083792b2a6e532bbfc07a3a0459","enode":"enode://1be1903b1104bfae07438fb888993cb3e812fc38c8f26af2e68bff9f1758e9a69b29be3636ee24060c09ce900bad2004681e1083792b2a6e532bbfc07a3a0459@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"1mi4zCFc28kr5xmjNiNJQJCuD7GoD1O94DFbGo+z0Tk=","hive":"\n=========================================================================\nTue Apr 10 09:40:43 UTC 2018 KΛÐΞMLIΛ hive: queen's address: d668b8\npopulation: 8 (31), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 391e | 9 7b88 (0) 7514 (0) 4848 (0) 5ec7 (0)\n001 1 930d | 13 9148 (0) 930d (0) 9756 (0) 8e5f (0)\n002 1 e7ac | 1 e7ac (0)\n003 1 c719 | 1 c719 (0)\n004 1 dab5 | 4 dab5 (0) d812 (0) deee (0) de95 (0)\n005 1 d19a | 1 d19a (0)\n============ DEPTH: 6 ==========================================\n006 2 d535 d514 | 2 d535 (0) d514 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"1be1903b1104bfae07438fb888993cb3e812fc38c8f26af2e68bff9f1758e9a69b29be3636ee24060c09ce900bad2004681e1083792b2a6e532bbfc07a3a0459","private_key":"b3a7fa29c4cbf15e8fbbf289ab9876b438bc80092284efedde8e8d41ac76ad78","name":"node_1be1903b1104bfae07438fb888993cb3e812fc38c8f26af2e68bff9f1758e9a69b29be3636ee24060c09ce900bad2004681e1083792b2a6e532bbfc07a3a0459","services":["streamer"],"enable_msg_events":true,"port":61479},"up":true}},{"node":{"info":{"id":"26a6b8d30e0a8954bd9a0424b817ff79fec2e0521c1313c8262be9a3b9a0d1ee7f109be78d65ca9eb811a1634a813f4ba609887fd3c0085628b2a8ebd3426031","name":"node_26a6b8d30e0a8954bd9a0424b817ff79fec2e0521c1313c8262be9a3b9a0d1ee7f109be78d65ca9eb811a1634a813f4ba609887fd3c0085628b2a8ebd3426031","enode":"enode://26a6b8d30e0a8954bd9a0424b817ff79fec2e0521c1313c8262be9a3b9a0d1ee7f109be78d65ca9eb811a1634a813f4ba609887fd3c0085628b2a8ebd3426031@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"OR5J7WQUgMLED+vbIyYyZMg7K2zfNAD2Um95OcAkXBc=","hive":"\n=========================================================================\nTue Apr 10 09:40:43 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 391e49\npopulation: 10 (31), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 d812 d668 b412 | 23 e7ac (0) c719 (0) dab5 (0) d812 (0)\n001 4 4848 5ec7 7514 7b88 | 5 7b88 (0) 7514 (0) 4848 (0) 5ec7 (0)\n002 0 | 0\n============ DEPTH: 3 ==========================================\n003 2 24a1 231c | 2 231c (0) 24a1 (0)\n004 1 35b6 | 1 35b6 (0)\n005 0 | 0\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"26a6b8d30e0a8954bd9a0424b817ff79fec2e0521c1313c8262be9a3b9a0d1ee7f109be78d65ca9eb811a1634a813f4ba609887fd3c0085628b2a8ebd3426031","private_key":"91b7188a3178bda6cd2991a615801d744f4963a3de963adb8afb3f12d02cbc0d","name":"node_26a6b8d30e0a8954bd9a0424b817ff79fec2e0521c1313c8262be9a3b9a0d1ee7f109be78d65ca9eb811a1634a813f4ba609887fd3c0085628b2a8ebd3426031","services":["streamer"],"enable_msg_events":true,"port":61480},"up":true}},{"node":{"info":{"id":"255c353a7585ab1bab41bcca409383dcdff5837bdcd7cebece1b6896fc06d0f65346ba618dc057c77734439612cb8cc3fd8aa068eb7569f0ad9e9e172daea678","name":"node_255c353a7585ab1bab41bcca409383dcdff5837bdcd7cebece1b6896fc06d0f65346ba618dc057c77734439612cb8cc3fd8aa068eb7569f0ad9e9e172daea678","enode":"enode://255c353a7585ab1bab41bcca409383dcdff5837bdcd7cebece1b6896fc06d0f65346ba618dc057c77734439612cb8cc3fd8aa068eb7569f0ad9e9e172daea678@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"tBKr7D3VFF2SNkmAVts15Q4OkGlwFsdXckwVoumxh68=","hive":"\n=========================================================================\nTue Apr 10 09:40:43 UTC 2018 KΛÐΞMLIΛ hive: queen's address: b412ab\npopulation: 9 (31), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 391e 59a3 | 9 231c (0) 24a1 (0) 35b6 (0) 391e (0)\n001 1 e7ac | 10 e7ac (0) c719 (0) dab5 (0) d812 (0)\n002 2 8f7d 9148 | 6 9148 (0) 930d (0) 9756 (0) 8e5f (0)\n003 2 a4e6 a1b5 | 4 a1b5 (0) a0ca (0) a4e6 (0) a829 (0)\n============ DEPTH: 4 ==========================================\n004 1 bfb0 | 1 bfb0 (0)\n005 1 b17b | 1 b17b (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"255c353a7585ab1bab41bcca409383dcdff5837bdcd7cebece1b6896fc06d0f65346ba618dc057c77734439612cb8cc3fd8aa068eb7569f0ad9e9e172daea678","private_key":"235b967cd72cdb90b423f2b5604e9157f660b253cd2df62369f204f45c3c4d7e","name":"node_255c353a7585ab1bab41bcca409383dcdff5837bdcd7cebece1b6896fc06d0f65346ba618dc057c77734439612cb8cc3fd8aa068eb7569f0ad9e9e172daea678","services":["streamer"],"enable_msg_events":true,"port":61481},"up":true}},{"node":{"info":{"id":"c88ceea7f4d5148de8e2d71ffefc5c336cc62d322eb4371e457cbb97573b6323d200ff7678f94ef481c7b9daca3a9a7bab1e658d51fa279d433e19305df57814","name":"node_c88ceea7f4d5148de8e2d71ffefc5c336cc62d322eb4371e457cbb97573b6323d200ff7678f94ef481c7b9daca3a9a7bab1e658d51fa279d433e19305df57814","enode":"enode://c88ceea7f4d5148de8e2d71ffefc5c336cc62d322eb4371e457cbb97573b6323d200ff7678f94ef481c7b9daca3a9a7bab1e658d51fa279d433e19305df57814@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"WaPvm6XQoBN+q5RCZXy6quW/zW53+WeLGyYW1E5ELK8=","hive":"\n=========================================================================\nTue Apr 10 09:40:43 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 59a3ef\npopulation: 6 (31), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 b412 | 23 e7ac (0) c719 (0) dab5 (0) d812 (0)\n001 1 35b6 | 4 231c (0) 24a1 (0) 391e (0) 35b6 (0)\n002 2 7b88 7514 | 2 7b88 (0) 7514 (0)\n============ DEPTH: 3 ==========================================\n003 1 4848 | 1 4848 (0)\n004 0 | 0\n005 1 5ec7 | 1 5ec7 (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"c88ceea7f4d5148de8e2d71ffefc5c336cc62d322eb4371e457cbb97573b6323d200ff7678f94ef481c7b9daca3a9a7bab1e658d51fa279d433e19305df57814","private_key":"f97bf73ba53833e4f4c44023e87cef8ef7aeae380553e4a5a4f3215748646a27","name":"node_c88ceea7f4d5148de8e2d71ffefc5c336cc62d322eb4371e457cbb97573b6323d200ff7678f94ef481c7b9daca3a9a7bab1e658d51fa279d433e19305df57814","services":["streamer"],"enable_msg_events":true,"port":61482},"up":true}},{"node":{"info":{"id":"4299205173b81c2822767a53cb4728fd5c0e1602d5976ee5db63b8118e489e4645ccdad399d9367e9b87b0a1f39e7988db86af687fe8cfff35d618b19d64b1a9","name":"node_4299205173b81c2822767a53cb4728fd5c0e1602d5976ee5db63b8118e489e4645ccdad399d9367e9b87b0a1f39e7988db86af687fe8cfff35d618b19d64b1a9","enode":"enode://4299205173b81c2822767a53cb4728fd5c0e1602d5976ee5db63b8118e489e4645ccdad399d9367e9b87b0a1f39e7988db86af687fe8cfff35d618b19d64b1a9@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"NbbjHK7bmWtKh6axK5op6qy0q6TDNFQ7qEsm1ry9ZfA=","hive":"\n=========================================================================\nTue Apr 10 09:40:43 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 35b6e3\npopulation: 5 (31), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 8e5f | 23 e7ac (0) c719 (0) dab5 (0) d812 (0)\n001 1 59a3 | 5 7b88 (0) 7514 (0) 4848 (0) 5ec7 (0)\n002 0 | 0\n============ DEPTH: 3 ==========================================\n003 2 24a1 231c | 2 231c (0) 24a1 (0)\n004 1 391e | 1 391e (0)\n005 0 | 0\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"4299205173b81c2822767a53cb4728fd5c0e1602d5976ee5db63b8118e489e4645ccdad399d9367e9b87b0a1f39e7988db86af687fe8cfff35d618b19d64b1a9","private_key":"c4c2ee3b5792dc5d86b51c4e13c813df452094ff2f6296403d801adb1f75a500","name":"node_4299205173b81c2822767a53cb4728fd5c0e1602d5976ee5db63b8118e489e4645ccdad399d9367e9b87b0a1f39e7988db86af687fe8cfff35d618b19d64b1a9","services":["streamer"],"enable_msg_events":true,"port":61483},"up":true}},{"node":{"info":{"id":"5ed2923d11037da9799d933ea62cd23ce1aacec66a83a6d3a7e420ea0c66ec00af37977a78374df12dc0facb426d0c39cf306bea15abaf40f9072eacc4cf40fe","name":"node_5ed2923d11037da9799d933ea62cd23ce1aacec66a83a6d3a7e420ea0c66ec00af37977a78374df12dc0facb426d0c39cf306bea15abaf40f9072eacc4cf40fe","enode":"enode://5ed2923d11037da9799d933ea62cd23ce1aacec66a83a6d3a7e420ea0c66ec00af37977a78374df12dc0facb426d0c39cf306bea15abaf40f9072eacc4cf40fe@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"jl+TTm0PC/NEJcPbLbQF0jj2USzxMpJuvQtZb8ch++Q=","hive":"\n=========================================================================\nTue Apr 10 09:40:43 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 8e5f93\npopulation: 7 (31), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 35b6 | 9 7b88 (0) 7514 (0) 4848 (0) 5ec7 (0)\n001 1 e7ac | 10 e7ac (0) c719 (0) dab5 (0) d812 (0)\n002 2 a1b5 b17b | 7 a1b5 (0) a0ca (0) a4e6 (0) a829 (0)\n003 1 9756 | 3 9148 (0) 930d (0) 9756 (0)\n004 0 | 0\n005 0 | 0\n============ DEPTH: 6 ==========================================\n006 1 8d09 | 1 8d09 (0)\n007 1 8f7d | 1 8f7d (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"5ed2923d11037da9799d933ea62cd23ce1aacec66a83a6d3a7e420ea0c66ec00af37977a78374df12dc0facb426d0c39cf306bea15abaf40f9072eacc4cf40fe","private_key":"b39dd34865d2f02c1d4c5ef2ca635ef5be43c4b2318b133d281b02dacd8f5420","name":"node_5ed2923d11037da9799d933ea62cd23ce1aacec66a83a6d3a7e420ea0c66ec00af37977a78374df12dc0facb426d0c39cf306bea15abaf40f9072eacc4cf40fe","services":["streamer"],"enable_msg_events":true,"port":61484},"up":true}},{"node":{"info":{"id":"66ce6e2c75f429c4bc7de6f1c785258686cfd66867336a1030830bbcc78bf642f4d1920ab5fc68953b70b7aca02ec518515d48d20397ed207ccbeb88c36e7057","name":"node_66ce6e2c75f429c4bc7de6f1c785258686cfd66867336a1030830bbcc78bf642f4d1920ab5fc68953b70b7aca02ec518515d48d20397ed207ccbeb88c36e7057","enode":"enode://66ce6e2c75f429c4bc7de6f1c785258686cfd66867336a1030830bbcc78bf642f4d1920ab5fc68953b70b7aca02ec518515d48d20397ed207ccbeb88c36e7057@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"sXtWh4CzoCnUKSp0KJDUG+anEDGxXmJ2eSp3qXRvBpk=","hive":"\n=========================================================================\nTue Apr 10 09:40:43 UTC 2018 KΛÐΞMLIΛ hive: queen's address: b17b56\npopulation: 8 (31), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 7b88 | 9 7b88 (0) 7514 (0) 4848 (0) 5ec7 (0)\n001 1 e7ac | 10 e7ac (0) c719 (0) d19a (0) d535 (0)\n002 2 8d09 8e5f | 6 9148 (0) 930d (0) 9756 (0) 8d09 (0)\n003 2 a0ca a1b5 | 4 a1b5 (0) a0ca (0) a4e6 (0) a829 (0)\n============ DEPTH: 4 ==========================================\n004 1 bfb0 | 1 bfb0 (0)\n005 1 b412 | 1 b412 (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"66ce6e2c75f429c4bc7de6f1c785258686cfd66867336a1030830bbcc78bf642f4d1920ab5fc68953b70b7aca02ec518515d48d20397ed207ccbeb88c36e7057","private_key":"a93bc07ea3d259a03c75a6777e9401f062a8064f6837fda8a1abd518774a75ac","name":"node_66ce6e2c75f429c4bc7de6f1c785258686cfd66867336a1030830bbcc78bf642f4d1920ab5fc68953b70b7aca02ec518515d48d20397ed207ccbeb88c36e7057","services":["streamer"],"enable_msg_events":true,"port":61485},"up":true}},{"node":{"info":{"id":"cf7d1a8ec1c3e68e862ef18947098ccbf6238fa7f85ee0018b7ac63b5387d6a9dbf194e3aad7edd1fda63ea63f2f5b8692ff885084adfd1f7b6613593960afc4","name":"node_cf7d1a8ec1c3e68e862ef18947098ccbf6238fa7f85ee0018b7ac63b5387d6a9dbf194e3aad7edd1fda63ea63f2f5b8692ff885084adfd1f7b6613593960afc4","enode":"enode://cf7d1a8ec1c3e68e862ef18947098ccbf6238fa7f85ee0018b7ac63b5387d6a9dbf194e3aad7edd1fda63ea63f2f5b8692ff885084adfd1f7b6613593960afc4@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"jQmEoy1LBEBlWItLvkhTGjCIG7hpOZyBuQs0nlfwf/w=","hive":"\n=========================================================================\nTue Apr 10 09:40:43 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 8d0984\npopulation: 9 (31), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 7b88 | 9 7b88 (0) 7514 (0) 4848 (0) 5ec7 (0)\n001 1 e7ac | 10 e7ac (0) c719 (0) d19a (0) d535 (0)\n002 2 a829 b17b | 7 a1b5 (0) a0ca (0) a4e6 (0) a829 (0)\n003 3 9148 930d 9756 | 3 9148 (0) 930d (0) 9756 (0)\n004 0 | 0\n005 0 | 0\n============ DEPTH: 6 ==========================================\n006 2 8f7d 8e5f | 2 8f7d (0) 8e5f (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"cf7d1a8ec1c3e68e862ef18947098ccbf6238fa7f85ee0018b7ac63b5387d6a9dbf194e3aad7edd1fda63ea63f2f5b8692ff885084adfd1f7b6613593960afc4","private_key":"787adc2aab8500ce6ca1768040b4c81511e7982f525c0280830f8c32486a6fa0","name":"node_cf7d1a8ec1c3e68e862ef18947098ccbf6238fa7f85ee0018b7ac63b5387d6a9dbf194e3aad7edd1fda63ea63f2f5b8692ff885084adfd1f7b6613593960afc4","services":["streamer"],"enable_msg_events":true,"port":61486},"up":true}},{"node":{"info":{"id":"a54b9c0cbc07e65b216f78bc0f56cd7003896641f1aa361fdc11e0bc208ee6bc876a455e89dee8abf67c259c7b6a82e7ac0d6d06cc304ee05fbc26783c09863a","name":"node_a54b9c0cbc07e65b216f78bc0f56cd7003896641f1aa361fdc11e0bc208ee6bc876a455e89dee8abf67c259c7b6a82e7ac0d6d06cc304ee05fbc26783c09863a","enode":"enode://a54b9c0cbc07e65b216f78bc0f56cd7003896641f1aa361fdc11e0bc208ee6bc876a455e89dee8abf67c259c7b6a82e7ac0d6d06cc304ee05fbc26783c09863a@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"l1bNqsYansTTRuNShi3b22J/VrW6sTKjE0g1n2JlKCQ=","hive":"\n=========================================================================\nTue Apr 10 09:40:43 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 9756cd\npopulation: 8 (31), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 7b88 | 9 7b88 (0) 7514 (0) 4848 (0) 59a3 (0)\n001 1 de95 | 10 e7ac (0) c719 (0) d19a (0) d535 (0)\n002 1 a829 | 7 a829 (0) a1b5 (0) a0ca (0) a4e6 (0)\n003 3 8e5f 8f7d 8d09 | 3 8f7d (0) 8e5f (0) 8d09 (0)\n004 0 | 0\n============ DEPTH: 5 ==========================================\n005 2 9148 930d | 2 9148 (0) 930d (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"a54b9c0cbc07e65b216f78bc0f56cd7003896641f1aa361fdc11e0bc208ee6bc876a455e89dee8abf67c259c7b6a82e7ac0d6d06cc304ee05fbc26783c09863a","private_key":"6a830e44eac33e88e29c9119fef789abd89503a44ae8b8dd64c0a26046df4bf7","name":"node_a54b9c0cbc07e65b216f78bc0f56cd7003896641f1aa361fdc11e0bc208ee6bc876a455e89dee8abf67c259c7b6a82e7ac0d6d06cc304ee05fbc26783c09863a","services":["streamer"],"enable_msg_events":true,"port":61487},"up":true}},{"node":{"info":{"id":"82bd5207dec292f911ff7dbcd242bf8962ab256057b1173dba2d71cd8cc77d41f38bf8d9a4eed83edeeb0e6f5bfabe8c7cae9490cc17dca1f454b9ad1b76224b","name":"node_82bd5207dec292f911ff7dbcd242bf8962ab256057b1173dba2d71cd8cc77d41f38bf8d9a4eed83edeeb0e6f5bfabe8c7cae9490cc17dca1f454b9ad1b76224b","enode":"enode://82bd5207dec292f911ff7dbcd242bf8962ab256057b1173dba2d71cd8cc77d41f38bf8d9a4eed83edeeb0e6f5bfabe8c7cae9490cc17dca1f454b9ad1b76224b@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"3pX1pYqIgLnpj3HGh6+kcogiRMASQ5cZtrBmkwNVyZM=","hive":"\n=========================================================================\nTue Apr 10 09:40:43 UTC 2018 KΛÐΞMLIΛ hive: queen's address: de95f5\npopulation: 9 (31), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 24a1 | 9 7b88 (0) 7514 (0) 4848 (0) 59a3 (0)\n001 1 9756 | 13 a829 (0) a0ca (0) a1b5 (0) a4e6 (0)\n002 1 e7ac | 1 e7ac (0)\n003 1 c719 | 1 c719 (0)\n004 2 d535 d19a | 4 d19a (0) d668 (0) d514 (0) d535 (0)\n============ DEPTH: 5 ==========================================\n005 2 dab5 d812 | 2 dab5 (0) d812 (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 1 deee | 1 deee (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"82bd5207dec292f911ff7dbcd242bf8962ab256057b1173dba2d71cd8cc77d41f38bf8d9a4eed83edeeb0e6f5bfabe8c7cae9490cc17dca1f454b9ad1b76224b","private_key":"71341041894a268f86cf62e8e80605911c19f38266bc49358c54f9955b4bd984","name":"node_82bd5207dec292f911ff7dbcd242bf8962ab256057b1173dba2d71cd8cc77d41f38bf8d9a4eed83edeeb0e6f5bfabe8c7cae9490cc17dca1f454b9ad1b76224b","services":["streamer"],"enable_msg_events":true,"port":61488},"up":true}},{"node":{"info":{"id":"61cbdddf6163152f5f8bbe3c710eeb9afb22dbec78d8f7eb3fd45ba44493b9387765527f059a10e694842786959c501303b1e62d3454c84870c14e0f36a58b0a","name":"node_61cbdddf6163152f5f8bbe3c710eeb9afb22dbec78d8f7eb3fd45ba44493b9387765527f059a10e694842786959c501303b1e62d3454c84870c14e0f36a58b0a","enode":"enode://61cbdddf6163152f5f8bbe3c710eeb9afb22dbec78d8f7eb3fd45ba44493b9387765527f059a10e694842786959c501303b1e62d3454c84870c14e0f36a58b0a@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"JKFUmG+8MIxfLj+6mfMmN0O2aa2I/90iUszl/gwCwnk=","hive":"\n=========================================================================\nTue Apr 10 09:40:43 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 24a154\npopulation: 6 (31), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 bfb0 de95 | 23 8e5f (0) 8f7d (0) 8d09 (0) 9148 (0)\n001 1 7b88 | 5 7b88 (0) 7514 (0) 4848 (0) 59a3 (0)\n002 0 | 0\n============ DEPTH: 3 ==========================================\n003 2 391e 35b6 | 2 391e (0) 35b6 (0)\n004 0 | 0\n005 1 231c | 1 231c (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"61cbdddf6163152f5f8bbe3c710eeb9afb22dbec78d8f7eb3fd45ba44493b9387765527f059a10e694842786959c501303b1e62d3454c84870c14e0f36a58b0a","private_key":"1a7bf17688ee55a634ddbf081213180f5a6e171a4b04679f50a949e88287591f","name":"node_61cbdddf6163152f5f8bbe3c710eeb9afb22dbec78d8f7eb3fd45ba44493b9387765527f059a10e694842786959c501303b1e62d3454c84870c14e0f36a58b0a","services":["streamer"],"enable_msg_events":true,"port":61489},"up":true}},{"node":{"info":{"id":"74d5d4ec7fdc749d9148b1a338b643e0a06abe03720b1d20b505da1ff1585b09d2cf7053293544fae1409cf26a27144870125787a473a73a1c4ca98509dc67ca","name":"node_74d5d4ec7fdc749d9148b1a338b643e0a06abe03720b1d20b505da1ff1585b09d2cf7053293544fae1409cf26a27144870125787a473a73a1c4ca98509dc67ca","enode":"enode://74d5d4ec7fdc749d9148b1a338b643e0a06abe03720b1d20b505da1ff1585b09d2cf7053293544fae1409cf26a27144870125787a473a73a1c4ca98509dc67ca@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"v7AkI98GiI+H6PveUsI3MCCJbyo96mns0u+onBqimKw=","hive":"\n=========================================================================\nTue Apr 10 09:40:43 UTC 2018 KΛÐΞMLIΛ hive: queen's address: bfb024\npopulation: 9 (31), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 24a1 7514 | 9 391e (0) 35b6 (0) 231c (0) 24a1 (0)\n001 1 e7ac | 10 e7ac (0) d19a (0) d668 (0) d514 (0)\n002 2 930d 9148 | 6 9148 (0) 930d (0) 9756 (0) 8d09 (0)\n003 2 a1b5 a829 | 4 a829 (0) a0ca (0) a1b5 (0) a4e6 (0)\n============ DEPTH: 4 ==========================================\n004 2 b17b b412 | 2 b412 (0) b17b (0)\n005 0 | 0\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"74d5d4ec7fdc749d9148b1a338b643e0a06abe03720b1d20b505da1ff1585b09d2cf7053293544fae1409cf26a27144870125787a473a73a1c4ca98509dc67ca","private_key":"87d1292398bace7bdd961dc2e1f028d405eeafebf90ef8d8f4b411fdfd74d767","name":"node_74d5d4ec7fdc749d9148b1a338b643e0a06abe03720b1d20b505da1ff1585b09d2cf7053293544fae1409cf26a27144870125787a473a73a1c4ca98509dc67ca","services":["streamer"],"enable_msg_events":true,"port":61490},"up":true}},{"node":{"info":{"id":"12934e06d8821c5e149d944ee7a831428dc6c9eee8705f3b21046fdadc2864a9ffe2bdad60a4ba5a34d7a79c22631d52b62d511e81971b6b98896acae9427e94","name":"node_12934e06d8821c5e149d944ee7a831428dc6c9eee8705f3b21046fdadc2864a9ffe2bdad60a4ba5a34d7a79c22631d52b62d511e81971b6b98896acae9427e94","enode":"enode://12934e06d8821c5e149d944ee7a831428dc6c9eee8705f3b21046fdadc2864a9ffe2bdad60a4ba5a34d7a79c22631d52b62d511e81971b6b98896acae9427e94@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"dRQAGtzetcmg6I+1QILpalwWJDDfxWttqFhgeIA2b/U=","hive":"\n=========================================================================\nTue Apr 10 09:40:43 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 751400\npopulation: 7 (31), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 bfb0 c719 | 23 9148 (0) 930d (0) 9756 (0) 8d09 (0)\n001 1 391e | 4 391e (0) 35b6 (0) 231c (0) 24a1 (0)\n============ DEPTH: 2 ==========================================\n002 3 4848 59a3 5ec7 | 3 4848 (0) 59a3 (0) 5ec7 (0)\n003 0 | 0\n004 1 7b88 | 1 7b88 (0)\n005 0 | 0\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"12934e06d8821c5e149d944ee7a831428dc6c9eee8705f3b21046fdadc2864a9ffe2bdad60a4ba5a34d7a79c22631d52b62d511e81971b6b98896acae9427e94","private_key":"1d65bea3808741aeabc5293fcb863c594c7ec07c955b3f23e28d2ef4b0b6e578","name":"node_12934e06d8821c5e149d944ee7a831428dc6c9eee8705f3b21046fdadc2864a9ffe2bdad60a4ba5a34d7a79c22631d52b62d511e81971b6b98896acae9427e94","services":["streamer"],"enable_msg_events":true,"port":61491},"up":true}},{"node":{"info":{"id":"e0e0e90fa669023a1a9c564727cc657ce564c23e05b1c2b61f6bfbd5eb03feb75d34b029886e3426e1bbe4a49398794dfefa0557b7db57c15700c69c0e038029","name":"node_e0e0e90fa669023a1a9c564727cc657ce564c23e05b1c2b61f6bfbd5eb03feb75d34b029886e3426e1bbe4a49398794dfefa0557b7db57c15700c69c0e038029","enode":"enode://e0e0e90fa669023a1a9c564727cc657ce564c23e05b1c2b61f6bfbd5eb03feb75d34b029886e3426e1bbe4a49398794dfefa0557b7db57c15700c69c0e038029@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"xxmDrtN3kDd1fkM6T5Fr5A9RmeiYYaOZjM3X5edvabQ=","hive":"\n=========================================================================\nTue Apr 10 09:40:43 UTC 2018 KΛÐΞMLIΛ hive: queen's address: c71983\npopulation: 11 (31), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 7514 | 9 391e (0) 35b6 (0) 231c (0) 24a1 (0)\n001 1 a4e6 | 13 9148 (0) 930d (0) 9756 (0) 8d09 (0)\n002 1 e7ac | 1 e7ac (0)\n============ DEPTH: 3 ==========================================\n003 8 d19a d514 d535 d668 | 8 d19a (0) d668 (0) d514 (0) d535 (0)\n004 0 | 0\n005 0 | 0\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"e0e0e90fa669023a1a9c564727cc657ce564c23e05b1c2b61f6bfbd5eb03feb75d34b029886e3426e1bbe4a49398794dfefa0557b7db57c15700c69c0e038029","private_key":"f067299a421cd124f8652427793dc41c8a5e6bf1dc2c4de59ef396ca08e80256","name":"node_e0e0e90fa669023a1a9c564727cc657ce564c23e05b1c2b61f6bfbd5eb03feb75d34b029886e3426e1bbe4a49398794dfefa0557b7db57c15700c69c0e038029","services":["streamer"],"enable_msg_events":true,"port":61492},"up":true}},{"node":{"info":{"id":"1149e4bcd71c75b14ba7492587fa77e4a4de14e5c580a165ad8835258d1afcb15e65d02257ad8884b0e47be061d3129d8e3af90cbe4a1a96f828a1f84e0d72c6","name":"node_1149e4bcd71c75b14ba7492587fa77e4a4de14e5c580a165ad8835258d1afcb15e65d02257ad8884b0e47be061d3129d8e3af90cbe4a1a96f828a1f84e0d72c6","enode":"enode://1149e4bcd71c75b14ba7492587fa77e4a4de14e5c580a165ad8835258d1afcb15e65d02257ad8884b0e47be061d3129d8e3af90cbe4a1a96f828a1f84e0d72c6@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"pOb1Chc0eoR11rcESEsGhp2WJZk3Yay95qCuWsC0B2I=","hive":"\n=========================================================================\nTue Apr 10 09:40:43 UTC 2018 KΛÐΞMLIΛ hive: queen's address: a4e6f5\npopulation: 7 (31), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 5ec7 | 9 391e (0) 35b6 (0) 231c (0) 24a1 (0)\n001 1 c719 | 10 e7ac (0) d19a (0) d668 (0) d514 (0)\n002 1 9148 | 6 9148 (0) 930d (0) 9756 (0) 8d09 (0)\n003 1 b412 | 3 b412 (0) b17b (0) bfb0 (0)\n004 1 a829 | 1 a829 (0)\n============ DEPTH: 5 ==========================================\n005 2 a1b5 a0ca | 2 a0ca (0) a1b5 (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"1149e4bcd71c75b14ba7492587fa77e4a4de14e5c580a165ad8835258d1afcb15e65d02257ad8884b0e47be061d3129d8e3af90cbe4a1a96f828a1f84e0d72c6","private_key":"5f76a5630d4f1979d6d03dfb0c8836de7852e4ad14536f4b999e565b599027b8","name":"node_1149e4bcd71c75b14ba7492587fa77e4a4de14e5c580a165ad8835258d1afcb15e65d02257ad8884b0e47be061d3129d8e3af90cbe4a1a96f828a1f84e0d72c6","services":["streamer"],"enable_msg_events":true,"port":61493},"up":true}},{"node":{"info":{"id":"695e5706cece9d923c19a147283b772dd1ffa79e8d08506d2ed897d89545ffbdac1a130bd7ceeb82a2a57f2b4a613aa6e7264911b909fb9bff27cd435b802687","name":"node_695e5706cece9d923c19a147283b772dd1ffa79e8d08506d2ed897d89545ffbdac1a130bd7ceeb82a2a57f2b4a613aa6e7264911b909fb9bff27cd435b802687","enode":"enode://695e5706cece9d923c19a147283b772dd1ffa79e8d08506d2ed897d89545ffbdac1a130bd7ceeb82a2a57f2b4a613aa6e7264911b909fb9bff27cd435b802687@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"Xsfm/7RPZ+zMNa2/CSN1XNW2qKvN03HbmxvlVXgMpaE=","hive":"\n=========================================================================\nTue Apr 10 09:40:43 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 5ec7e6\npopulation: 7 (31), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 a4e6 8f7d | 23 e7ac (0) d19a (0) d668 (0) d514 (0)\n001 1 391e | 4 391e (0) 35b6 (0) 231c (0) 24a1 (0)\n002 2 7b88 7514 | 2 7b88 (0) 7514 (0)\n============ DEPTH: 3 ==========================================\n003 1 4848 | 1 4848 (0)\n004 0 | 0\n005 1 59a3 | 1 59a3 (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"695e5706cece9d923c19a147283b772dd1ffa79e8d08506d2ed897d89545ffbdac1a130bd7ceeb82a2a57f2b4a613aa6e7264911b909fb9bff27cd435b802687","private_key":"0e4febbd0bb937f5992d0e640d5b599a0dfc3b40740d7a0a5fd16423dfcc87fb","name":"node_695e5706cece9d923c19a147283b772dd1ffa79e8d08506d2ed897d89545ffbdac1a130bd7ceeb82a2a57f2b4a613aa6e7264911b909fb9bff27cd435b802687","services":["streamer"],"enable_msg_events":true,"port":61494},"up":true}},{"node":{"info":{"id":"e28c769630f19e79966bc354bb38313522778e4f06cd0872db8bd3afd7651882eba7b0403d82701cd063cbaee4ba0ba4a97c0c488fb44e8c8b72368d6881fdcf","name":"node_e28c769630f19e79966bc354bb38313522778e4f06cd0872db8bd3afd7651882eba7b0403d82701cd063cbaee4ba0ba4a97c0c488fb44e8c8b72368d6881fdcf","enode":"enode://e28c769630f19e79966bc354bb38313522778e4f06cd0872db8bd3afd7651882eba7b0403d82701cd063cbaee4ba0ba4a97c0c488fb44e8c8b72368d6881fdcf@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"j33ISAG6jagHYf4eDS/nKkjkX6dTzIu+kwv5J3ohlDI=","hive":"\n=========================================================================\nTue Apr 10 09:40:43 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 8f7dc8\npopulation: 6 (31), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 5ec7 | 9 391e (0) 35b6 (0) 231c (0) 24a1 (0)\n001 1 d812 | 10 e7ac (0) c719 (0) d19a (0) d668 (0)\n002 1 b412 | 7 b412 (0) b17b (0) bfb0 (0) a829 (0)\n003 1 9756 | 3 9148 (0) 930d (0) 9756 (0)\n004 0 | 0\n005 0 | 0\n============ DEPTH: 6 ==========================================\n006 1 8d09 | 1 8d09 (0)\n007 1 8e5f | 1 8e5f (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"e28c769630f19e79966bc354bb38313522778e4f06cd0872db8bd3afd7651882eba7b0403d82701cd063cbaee4ba0ba4a97c0c488fb44e8c8b72368d6881fdcf","private_key":"54d714717b902eb733a693d473a4b4b243318a9fd68d1b8abe98eabcbaa8c015","name":"node_e28c769630f19e79966bc354bb38313522778e4f06cd0872db8bd3afd7651882eba7b0403d82701cd063cbaee4ba0ba4a97c0c488fb44e8c8b72368d6881fdcf","services":["streamer"],"enable_msg_events":true,"port":61495},"up":true}},{"node":{"info":{"id":"2b1d1ec3ee35fa63571f46a2781d5fb14379319da2d67e482c24b27bacc2b792cd61a2c1138b8ba27673b1c08588064fdf9c73c80f0278e4f0ba133d78127337","name":"node_2b1d1ec3ee35fa63571f46a2781d5fb14379319da2d67e482c24b27bacc2b792cd61a2c1138b8ba27673b1c08588064fdf9c73c80f0278e4f0ba133d78127337","enode":"enode://2b1d1ec3ee35fa63571f46a2781d5fb14379319da2d67e482c24b27bacc2b792cd61a2c1138b8ba27673b1c08588064fdf9c73c80f0278e4f0ba133d78127337@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"2BJxxkSnXwv514Uxmt7Yt6DpMj+F6B6U75UejGYlHnU=","hive":"\n=========================================================================\nTue Apr 10 09:40:43 UTC 2018 KΛÐΞMLIΛ hive: queen's address: d81271\npopulation: 8 (31), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 391e | 9 391e (0) 35b6 (0) 24a1 (0) 231c (0)\n001 1 8f7d | 13 b17b (0) b412 (0) bfb0 (0) a829 (0)\n002 1 e7ac | 1 e7ac (0)\n003 1 c719 | 1 c719 (0)\n004 1 d19a | 4 d19a (0) d668 (0) d514 (0) d535 (0)\n============ DEPTH: 5 ==========================================\n005 2 de95 deee | 2 de95 (0) deee (0)\n006 1 dab5 | 1 dab5 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"2b1d1ec3ee35fa63571f46a2781d5fb14379319da2d67e482c24b27bacc2b792cd61a2c1138b8ba27673b1c08588064fdf9c73c80f0278e4f0ba133d78127337","private_key":"43e07e3593646f9ec6c3b630daa34ba80dc37bc0f5c57e3f3097f3503de413dc","name":"node_2b1d1ec3ee35fa63571f46a2781d5fb14379319da2d67e482c24b27bacc2b792cd61a2c1138b8ba27673b1c08588064fdf9c73c80f0278e4f0ba133d78127337","services":["streamer"],"enable_msg_events":true,"port":61496},"up":true}},{"node":{"info":{"id":"b5e3b3cc7ac15224ff10cf8974ceaf7ad2ebb18ab9505bbb342c42e6ca65fe3541c14e1ee10ac3a0e7a0d87c29e25114e0c0d957d5dbbadf6136805be3046b4c","name":"node_b5e3b3cc7ac15224ff10cf8974ceaf7ad2ebb18ab9505bbb342c42e6ca65fe3541c14e1ee10ac3a0e7a0d87c29e25114e0c0d957d5dbbadf6136805be3046b4c","enode":"enode://b5e3b3cc7ac15224ff10cf8974ceaf7ad2ebb18ab9505bbb342c42e6ca65fe3541c14e1ee10ac3a0e7a0d87c29e25114e0c0d957d5dbbadf6136805be3046b4c@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"3u75042a+yBu5+ZEfoC++vOHwq9Han4MYMVcc902RQ0=","hive":"\n=========================================================================\nTue Apr 10 09:40:43 UTC 2018 KΛÐΞMLIΛ hive: queen's address: deeef9\npopulation: 8 (31), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 7b88 | 9 7b88 (0) 7514 (0) 4848 (0) 59a3 (0)\n001 1 a0ca | 13 9148 (0) 930d (0) 9756 (0) 8d09 (0)\n002 1 e7ac | 1 e7ac (0)\n003 1 c719 | 1 c719 (0)\n004 1 d19a | 4 d19a (0) d668 (0) d514 (0) d535 (0)\n============ DEPTH: 5 ==========================================\n005 2 dab5 d812 | 2 dab5 (0) d812 (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 1 de95 | 1 de95 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"b5e3b3cc7ac15224ff10cf8974ceaf7ad2ebb18ab9505bbb342c42e6ca65fe3541c14e1ee10ac3a0e7a0d87c29e25114e0c0d957d5dbbadf6136805be3046b4c","private_key":"ef8ebfc1df0b19885db4b08df697c11a86c2442bce48d5f6f807b7e8dec70e04","name":"node_b5e3b3cc7ac15224ff10cf8974ceaf7ad2ebb18ab9505bbb342c42e6ca65fe3541c14e1ee10ac3a0e7a0d87c29e25114e0c0d957d5dbbadf6136805be3046b4c","services":["streamer"],"enable_msg_events":true,"port":61497},"up":true}},{"node":{"info":{"id":"fb6e36b9de5eef05780efcf16113fc9098a699ac525bd970dc5b6a92f596da6ffca044e434b97cd712a4035c38dd3ab08488042519f6269bc5057853b643bbcc","name":"node_fb6e36b9de5eef05780efcf16113fc9098a699ac525bd970dc5b6a92f596da6ffca044e434b97cd712a4035c38dd3ab08488042519f6269bc5057853b643bbcc","enode":"enode://fb6e36b9de5eef05780efcf16113fc9098a699ac525bd970dc5b6a92f596da6ffca044e434b97cd712a4035c38dd3ab08488042519f6269bc5057853b643bbcc@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"oMpwarK6lQ/5u5ISPGbJUTKmO5yTl1ubbg1IWTfdj2U=","hive":"\n=========================================================================\nTue Apr 10 09:40:43 UTC 2018 KΛÐΞMLIΛ hive: queen's address: a0ca70\npopulation: 8 (31), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 7b88 | 9 7b88 (0) 7514 (0) 4848 (0) 59a3 (0)\n001 2 dab5 deee | 10 e7ac (0) c719 (0) d19a (0) d668 (0)\n002 1 9148 | 6 9148 (0) 930d (0) 9756 (0) 8d09 (0)\n003 1 b17b | 3 b17b (0) b412 (0) bfb0 (0)\n004 1 a829 | 1 a829 (0)\n============ DEPTH: 5 ==========================================\n005 1 a4e6 | 1 a4e6 (0)\n006 0 | 0\n007 1 a1b5 | 1 a1b5 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"fb6e36b9de5eef05780efcf16113fc9098a699ac525bd970dc5b6a92f596da6ffca044e434b97cd712a4035c38dd3ab08488042519f6269bc5057853b643bbcc","private_key":"1cb586254c20e9a6f4cc428f878dcfbcc8257f00c21efa88519de7a425cb5e4f","name":"node_fb6e36b9de5eef05780efcf16113fc9098a699ac525bd970dc5b6a92f596da6ffca044e434b97cd712a4035c38dd3ab08488042519f6269bc5057853b643bbcc","services":["streamer"],"enable_msg_events":true,"port":61498},"up":true}},{"node":{"info":{"id":"aca2af376ef1c983514f75cd717c0852e9d4321e705517196fab4fafe109c1f3581866e1865d41977f8c23a31ec7fa218c11db0c87eb4bb96390025a96386f9a","name":"node_aca2af376ef1c983514f75cd717c0852e9d4321e705517196fab4fafe109c1f3581866e1865d41977f8c23a31ec7fa218c11db0c87eb4bb96390025a96386f9a","enode":"enode://aca2af376ef1c983514f75cd717c0852e9d4321e705517196fab4fafe109c1f3581866e1865d41977f8c23a31ec7fa218c11db0c87eb4bb96390025a96386f9a@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"2rUJjPkpV5qH4m0w+aiwAa0xWK/g9iMcUOWPM8bWIgc=","hive":"\n=========================================================================\nTue Apr 10 09:40:43 UTC 2018 KΛÐΞMLIΛ hive: queen's address: dab509\npopulation: 9 (31), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 7b88 | 9 391e (0) 35b6 (0) 24a1 (0) 231c (0)\n001 1 a0ca | 13 b17b (0) b412 (0) bfb0 (0) a829 (0)\n002 1 e7ac | 1 e7ac (0)\n003 1 c719 | 1 c719 (0)\n004 2 d514 d668 | 4 d19a (0) d668 (0) d514 (0) d535 (0)\n============ DEPTH: 5 ==========================================\n005 2 de95 deee | 2 de95 (0) deee (0)\n006 1 d812 | 1 d812 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"aca2af376ef1c983514f75cd717c0852e9d4321e705517196fab4fafe109c1f3581866e1865d41977f8c23a31ec7fa218c11db0c87eb4bb96390025a96386f9a","private_key":"2621e61b3b896a37c2b4ee05a264bb685f4a70c3caf8a162eee28dd6e64fa2fd","name":"node_aca2af376ef1c983514f75cd717c0852e9d4321e705517196fab4fafe109c1f3581866e1865d41977f8c23a31ec7fa218c11db0c87eb4bb96390025a96386f9a","services":["streamer"],"enable_msg_events":true,"port":61499},"up":true}}],"conns":[{"one":"aca2af376ef1c983514f75cd717c0852e9d4321e705517196fab4fafe109c1f3581866e1865d41977f8c23a31ec7fa218c11db0c87eb4bb96390025a96386f9a","other":"d2a392e9e7383b895587a7d6eea4a157de20caa9e2c62b4da5a8ff3186d129fee1330ddf3d180b1f59e1aa83686cd163222e38c84a84a0f60139968d6a56cbca","up":true},{"one":"d2a392e9e7383b895587a7d6eea4a157de20caa9e2c62b4da5a8ff3186d129fee1330ddf3d180b1f59e1aa83686cd163222e38c84a84a0f60139968d6a56cbca","other":"6c0b3b7c1c08bb558d92f0172fb8bfabe52a4bf8348b2f82e50c6d492a595dd0677b4559d7d2cd5a6e51ecdaf9a0f898f154730b87a8d9b265c6a54f9f6802a7","up":true},{"one":"6c0b3b7c1c08bb558d92f0172fb8bfabe52a4bf8348b2f82e50c6d492a595dd0677b4559d7d2cd5a6e51ecdaf9a0f898f154730b87a8d9b265c6a54f9f6802a7","other":"dc63b83b488b7b505d5b2a60680b7dc87b1c5b61509e8030ebc67512ba72c0f616c1594946878dfb29e79f351d7134306778a74d5f5b7d5e08dbdb6dd6ade359","up":true},{"one":"dc63b83b488b7b505d5b2a60680b7dc87b1c5b61509e8030ebc67512ba72c0f616c1594946878dfb29e79f351d7134306778a74d5f5b7d5e08dbdb6dd6ade359","other":"eaa3ad48682b08d9c91907a79e82938c1b30108745b276788c830dfcb0c0e752134369d751230e95fb7ab9777c38dcd105ad123ec5cc86ef6dbdd11fe31aea93","up":true},{"one":"eaa3ad48682b08d9c91907a79e82938c1b30108745b276788c830dfcb0c0e752134369d751230e95fb7ab9777c38dcd105ad123ec5cc86ef6dbdd11fe31aea93","other":"331084cce2884ad912d5a20467c68fc261a02d6df0b60ff5b1427edc0885eab66a4f0f7e7fc9c676e994842f8126a3b34dbde91243f26bed6a0ba14babed56cc","up":true},{"one":"331084cce2884ad912d5a20467c68fc261a02d6df0b60ff5b1427edc0885eab66a4f0f7e7fc9c676e994842f8126a3b34dbde91243f26bed6a0ba14babed56cc","other":"e00f9a5611008d54bbbfe6a1cf402e011c92f540b47a82b7795508d1b857eee4a522e26c8351ddf6e303d353ee35afecbf9f54d7aae36e6736174473ac4caf73","up":true},{"one":"e00f9a5611008d54bbbfe6a1cf402e011c92f540b47a82b7795508d1b857eee4a522e26c8351ddf6e303d353ee35afecbf9f54d7aae36e6736174473ac4caf73","other":"e4b7b3bbeda388842ecb3688c041fe58bbd7e4566818a58b679e96215553dbf8569032a3ae941b3f8bb3e75886852d245bda5abf0c3cf70f532c38235e1a2175","up":true},{"one":"e4b7b3bbeda388842ecb3688c041fe58bbd7e4566818a58b679e96215553dbf8569032a3ae941b3f8bb3e75886852d245bda5abf0c3cf70f532c38235e1a2175","other":"0679dbbb51fa0283bcba387daa2180955d402a0ed42155095fcaffb96dbfd6b4b1bb0ed2ccf11cd990dfed4a3b320ee3f64286116a7b617a35989a448c367119","up":true},{"one":"fb6e36b9de5eef05780efcf16113fc9098a699ac525bd970dc5b6a92f596da6ffca044e434b97cd712a4035c38dd3ab08488042519f6269bc5057853b643bbcc","other":"aca2af376ef1c983514f75cd717c0852e9d4321e705517196fab4fafe109c1f3581866e1865d41977f8c23a31ec7fa218c11db0c87eb4bb96390025a96386f9a","up":true},{"one":"b5e3b3cc7ac15224ff10cf8974ceaf7ad2ebb18ab9505bbb342c42e6ca65fe3541c14e1ee10ac3a0e7a0d87c29e25114e0c0d957d5dbbadf6136805be3046b4c","other":"fb6e36b9de5eef05780efcf16113fc9098a699ac525bd970dc5b6a92f596da6ffca044e434b97cd712a4035c38dd3ab08488042519f6269bc5057853b643bbcc","up":true},{"one":"0679dbbb51fa0283bcba387daa2180955d402a0ed42155095fcaffb96dbfd6b4b1bb0ed2ccf11cd990dfed4a3b320ee3f64286116a7b617a35989a448c367119","other":"a197cd9e7e2d19287745f486582b7242c991f36183e8b2bf4983d7a9b9026e9884e3295183f376cd796b814fdf352b1c8c5c609a0e5f5d5155ab925d4b6fdeb9","up":true},{"one":"a197cd9e7e2d19287745f486582b7242c991f36183e8b2bf4983d7a9b9026e9884e3295183f376cd796b814fdf352b1c8c5c609a0e5f5d5155ab925d4b6fdeb9","other":"eb11498b8cebc767d535481938c664359c6c84674da4d8fac729df64e288248bb020477ad4422cf1b7cea844db5ee12bb5cea82ac6e89a338d8ca1073e061f4c","up":true},{"one":"eb11498b8cebc767d535481938c664359c6c84674da4d8fac729df64e288248bb020477ad4422cf1b7cea844db5ee12bb5cea82ac6e89a338d8ca1073e061f4c","other":"d3b5df108f35a82e569016a06fefadb52797dafb505de1981f6678e2156574893a169b0adcc595377267dec0b7d620b5b50c7e7696c39eecee2c3e5f7bf71d18","up":true},{"one":"d3b5df108f35a82e569016a06fefadb52797dafb505de1981f6678e2156574893a169b0adcc595377267dec0b7d620b5b50c7e7696c39eecee2c3e5f7bf71d18","other":"1be1903b1104bfae07438fb888993cb3e812fc38c8f26af2e68bff9f1758e9a69b29be3636ee24060c09ce900bad2004681e1083792b2a6e532bbfc07a3a0459","up":true},{"one":"1be1903b1104bfae07438fb888993cb3e812fc38c8f26af2e68bff9f1758e9a69b29be3636ee24060c09ce900bad2004681e1083792b2a6e532bbfc07a3a0459","other":"26a6b8d30e0a8954bd9a0424b817ff79fec2e0521c1313c8262be9a3b9a0d1ee7f109be78d65ca9eb811a1634a813f4ba609887fd3c0085628b2a8ebd3426031","up":true},{"one":"26a6b8d30e0a8954bd9a0424b817ff79fec2e0521c1313c8262be9a3b9a0d1ee7f109be78d65ca9eb811a1634a813f4ba609887fd3c0085628b2a8ebd3426031","other":"255c353a7585ab1bab41bcca409383dcdff5837bdcd7cebece1b6896fc06d0f65346ba618dc057c77734439612cb8cc3fd8aa068eb7569f0ad9e9e172daea678","up":true},{"one":"255c353a7585ab1bab41bcca409383dcdff5837bdcd7cebece1b6896fc06d0f65346ba618dc057c77734439612cb8cc3fd8aa068eb7569f0ad9e9e172daea678","other":"c88ceea7f4d5148de8e2d71ffefc5c336cc62d322eb4371e457cbb97573b6323d200ff7678f94ef481c7b9daca3a9a7bab1e658d51fa279d433e19305df57814","up":true},{"one":"c88ceea7f4d5148de8e2d71ffefc5c336cc62d322eb4371e457cbb97573b6323d200ff7678f94ef481c7b9daca3a9a7bab1e658d51fa279d433e19305df57814","other":"4299205173b81c2822767a53cb4728fd5c0e1602d5976ee5db63b8118e489e4645ccdad399d9367e9b87b0a1f39e7988db86af687fe8cfff35d618b19d64b1a9","up":true},{"one":"4299205173b81c2822767a53cb4728fd5c0e1602d5976ee5db63b8118e489e4645ccdad399d9367e9b87b0a1f39e7988db86af687fe8cfff35d618b19d64b1a9","other":"5ed2923d11037da9799d933ea62cd23ce1aacec66a83a6d3a7e420ea0c66ec00af37977a78374df12dc0facb426d0c39cf306bea15abaf40f9072eacc4cf40fe","up":true},{"one":"5ed2923d11037da9799d933ea62cd23ce1aacec66a83a6d3a7e420ea0c66ec00af37977a78374df12dc0facb426d0c39cf306bea15abaf40f9072eacc4cf40fe","other":"66ce6e2c75f429c4bc7de6f1c785258686cfd66867336a1030830bbcc78bf642f4d1920ab5fc68953b70b7aca02ec518515d48d20397ed207ccbeb88c36e7057","up":true},{"one":"66ce6e2c75f429c4bc7de6f1c785258686cfd66867336a1030830bbcc78bf642f4d1920ab5fc68953b70b7aca02ec518515d48d20397ed207ccbeb88c36e7057","other":"cf7d1a8ec1c3e68e862ef18947098ccbf6238fa7f85ee0018b7ac63b5387d6a9dbf194e3aad7edd1fda63ea63f2f5b8692ff885084adfd1f7b6613593960afc4","up":true},{"one":"cf7d1a8ec1c3e68e862ef18947098ccbf6238fa7f85ee0018b7ac63b5387d6a9dbf194e3aad7edd1fda63ea63f2f5b8692ff885084adfd1f7b6613593960afc4","other":"a54b9c0cbc07e65b216f78bc0f56cd7003896641f1aa361fdc11e0bc208ee6bc876a455e89dee8abf67c259c7b6a82e7ac0d6d06cc304ee05fbc26783c09863a","up":true},{"one":"a54b9c0cbc07e65b216f78bc0f56cd7003896641f1aa361fdc11e0bc208ee6bc876a455e89dee8abf67c259c7b6a82e7ac0d6d06cc304ee05fbc26783c09863a","other":"82bd5207dec292f911ff7dbcd242bf8962ab256057b1173dba2d71cd8cc77d41f38bf8d9a4eed83edeeb0e6f5bfabe8c7cae9490cc17dca1f454b9ad1b76224b","up":true},{"one":"82bd5207dec292f911ff7dbcd242bf8962ab256057b1173dba2d71cd8cc77d41f38bf8d9a4eed83edeeb0e6f5bfabe8c7cae9490cc17dca1f454b9ad1b76224b","other":"61cbdddf6163152f5f8bbe3c710eeb9afb22dbec78d8f7eb3fd45ba44493b9387765527f059a10e694842786959c501303b1e62d3454c84870c14e0f36a58b0a","up":true},{"one":"61cbdddf6163152f5f8bbe3c710eeb9afb22dbec78d8f7eb3fd45ba44493b9387765527f059a10e694842786959c501303b1e62d3454c84870c14e0f36a58b0a","other":"74d5d4ec7fdc749d9148b1a338b643e0a06abe03720b1d20b505da1ff1585b09d2cf7053293544fae1409cf26a27144870125787a473a73a1c4ca98509dc67ca","up":true},{"one":"74d5d4ec7fdc749d9148b1a338b643e0a06abe03720b1d20b505da1ff1585b09d2cf7053293544fae1409cf26a27144870125787a473a73a1c4ca98509dc67ca","other":"12934e06d8821c5e149d944ee7a831428dc6c9eee8705f3b21046fdadc2864a9ffe2bdad60a4ba5a34d7a79c22631d52b62d511e81971b6b98896acae9427e94","up":true},{"one":"12934e06d8821c5e149d944ee7a831428dc6c9eee8705f3b21046fdadc2864a9ffe2bdad60a4ba5a34d7a79c22631d52b62d511e81971b6b98896acae9427e94","other":"e0e0e90fa669023a1a9c564727cc657ce564c23e05b1c2b61f6bfbd5eb03feb75d34b029886e3426e1bbe4a49398794dfefa0557b7db57c15700c69c0e038029","up":true},{"one":"e0e0e90fa669023a1a9c564727cc657ce564c23e05b1c2b61f6bfbd5eb03feb75d34b029886e3426e1bbe4a49398794dfefa0557b7db57c15700c69c0e038029","other":"1149e4bcd71c75b14ba7492587fa77e4a4de14e5c580a165ad8835258d1afcb15e65d02257ad8884b0e47be061d3129d8e3af90cbe4a1a96f828a1f84e0d72c6","up":true},{"one":"1149e4bcd71c75b14ba7492587fa77e4a4de14e5c580a165ad8835258d1afcb15e65d02257ad8884b0e47be061d3129d8e3af90cbe4a1a96f828a1f84e0d72c6","other":"695e5706cece9d923c19a147283b772dd1ffa79e8d08506d2ed897d89545ffbdac1a130bd7ceeb82a2a57f2b4a613aa6e7264911b909fb9bff27cd435b802687","up":true},{"one":"695e5706cece9d923c19a147283b772dd1ffa79e8d08506d2ed897d89545ffbdac1a130bd7ceeb82a2a57f2b4a613aa6e7264911b909fb9bff27cd435b802687","other":"e28c769630f19e79966bc354bb38313522778e4f06cd0872db8bd3afd7651882eba7b0403d82701cd063cbaee4ba0ba4a97c0c488fb44e8c8b72368d6881fdcf","up":true},{"one":"e28c769630f19e79966bc354bb38313522778e4f06cd0872db8bd3afd7651882eba7b0403d82701cd063cbaee4ba0ba4a97c0c488fb44e8c8b72368d6881fdcf","other":"2b1d1ec3ee35fa63571f46a2781d5fb14379319da2d67e482c24b27bacc2b792cd61a2c1138b8ba27673b1c08588064fdf9c73c80f0278e4f0ba133d78127337","up":true},{"one":"2b1d1ec3ee35fa63571f46a2781d5fb14379319da2d67e482c24b27bacc2b792cd61a2c1138b8ba27673b1c08588064fdf9c73c80f0278e4f0ba133d78127337","other":"b5e3b3cc7ac15224ff10cf8974ceaf7ad2ebb18ab9505bbb342c42e6ca65fe3541c14e1ee10ac3a0e7a0d87c29e25114e0c0d957d5dbbadf6136805be3046b4c","up":true},{"one":"d2a392e9e7383b895587a7d6eea4a157de20caa9e2c62b4da5a8ff3186d129fee1330ddf3d180b1f59e1aa83686cd163222e38c84a84a0f60139968d6a56cbca","other":"dc63b83b488b7b505d5b2a60680b7dc87b1c5b61509e8030ebc67512ba72c0f616c1594946878dfb29e79f351d7134306778a74d5f5b7d5e08dbdb6dd6ade359","up":true},{"one":"eaa3ad48682b08d9c91907a79e82938c1b30108745b276788c830dfcb0c0e752134369d751230e95fb7ab9777c38dcd105ad123ec5cc86ef6dbdd11fe31aea93","other":"fb6e36b9de5eef05780efcf16113fc9098a699ac525bd970dc5b6a92f596da6ffca044e434b97cd712a4035c38dd3ab08488042519f6269bc5057853b643bbcc","up":true},{"one":"331084cce2884ad912d5a20467c68fc261a02d6df0b60ff5b1427edc0885eab66a4f0f7e7fc9c676e994842f8126a3b34dbde91243f26bed6a0ba14babed56cc","other":"d3b5df108f35a82e569016a06fefadb52797dafb505de1981f6678e2156574893a169b0adcc595377267dec0b7d620b5b50c7e7696c39eecee2c3e5f7bf71d18","up":true},{"one":"26a6b8d30e0a8954bd9a0424b817ff79fec2e0521c1313c8262be9a3b9a0d1ee7f109be78d65ca9eb811a1634a813f4ba609887fd3c0085628b2a8ebd3426031","other":"4299205173b81c2822767a53cb4728fd5c0e1602d5976ee5db63b8118e489e4645ccdad399d9367e9b87b0a1f39e7988db86af687fe8cfff35d618b19d64b1a9","up":true},{"one":"255c353a7585ab1bab41bcca409383dcdff5837bdcd7cebece1b6896fc06d0f65346ba618dc057c77734439612cb8cc3fd8aa068eb7569f0ad9e9e172daea678","other":"66ce6e2c75f429c4bc7de6f1c785258686cfd66867336a1030830bbcc78bf642f4d1920ab5fc68953b70b7aca02ec518515d48d20397ed207ccbeb88c36e7057","up":true},{"one":"a54b9c0cbc07e65b216f78bc0f56cd7003896641f1aa361fdc11e0bc208ee6bc876a455e89dee8abf67c259c7b6a82e7ac0d6d06cc304ee05fbc26783c09863a","other":"e28c769630f19e79966bc354bb38313522778e4f06cd0872db8bd3afd7651882eba7b0403d82701cd063cbaee4ba0ba4a97c0c488fb44e8c8b72368d6881fdcf","up":true},{"one":"e0e0e90fa669023a1a9c564727cc657ce564c23e05b1c2b61f6bfbd5eb03feb75d34b029886e3426e1bbe4a49398794dfefa0557b7db57c15700c69c0e038029","other":"2b1d1ec3ee35fa63571f46a2781d5fb14379319da2d67e482c24b27bacc2b792cd61a2c1138b8ba27673b1c08588064fdf9c73c80f0278e4f0ba133d78127337","up":true},{"one":"5ed2923d11037da9799d933ea62cd23ce1aacec66a83a6d3a7e420ea0c66ec00af37977a78374df12dc0facb426d0c39cf306bea15abaf40f9072eacc4cf40fe","other":"e28c769630f19e79966bc354bb38313522778e4f06cd0872db8bd3afd7651882eba7b0403d82701cd063cbaee4ba0ba4a97c0c488fb44e8c8b72368d6881fdcf","up":true},{"one":"b5e3b3cc7ac15224ff10cf8974ceaf7ad2ebb18ab9505bbb342c42e6ca65fe3541c14e1ee10ac3a0e7a0d87c29e25114e0c0d957d5dbbadf6136805be3046b4c","other":"82bd5207dec292f911ff7dbcd242bf8962ab256057b1173dba2d71cd8cc77d41f38bf8d9a4eed83edeeb0e6f5bfabe8c7cae9490cc17dca1f454b9ad1b76224b","up":true},{"one":"cf7d1a8ec1c3e68e862ef18947098ccbf6238fa7f85ee0018b7ac63b5387d6a9dbf194e3aad7edd1fda63ea63f2f5b8692ff885084adfd1f7b6613593960afc4","other":"5ed2923d11037da9799d933ea62cd23ce1aacec66a83a6d3a7e420ea0c66ec00af37977a78374df12dc0facb426d0c39cf306bea15abaf40f9072eacc4cf40fe","up":true},{"one":"12934e06d8821c5e149d944ee7a831428dc6c9eee8705f3b21046fdadc2864a9ffe2bdad60a4ba5a34d7a79c22631d52b62d511e81971b6b98896acae9427e94","other":"695e5706cece9d923c19a147283b772dd1ffa79e8d08506d2ed897d89545ffbdac1a130bd7ceeb82a2a57f2b4a613aa6e7264911b909fb9bff27cd435b802687","up":true},{"one":"4299205173b81c2822767a53cb4728fd5c0e1602d5976ee5db63b8118e489e4645ccdad399d9367e9b87b0a1f39e7988db86af687fe8cfff35d618b19d64b1a9","other":"e4b7b3bbeda388842ecb3688c041fe58bbd7e4566818a58b679e96215553dbf8569032a3ae941b3f8bb3e75886852d245bda5abf0c3cf70f532c38235e1a2175","up":true},{"one":"eb11498b8cebc767d535481938c664359c6c84674da4d8fac729df64e288248bb020477ad4422cf1b7cea844db5ee12bb5cea82ac6e89a338d8ca1073e061f4c","other":"a54b9c0cbc07e65b216f78bc0f56cd7003896641f1aa361fdc11e0bc208ee6bc876a455e89dee8abf67c259c7b6a82e7ac0d6d06cc304ee05fbc26783c09863a","up":true},{"one":"e00f9a5611008d54bbbfe6a1cf402e011c92f540b47a82b7795508d1b857eee4a522e26c8351ddf6e303d353ee35afecbf9f54d7aae36e6736174473ac4caf73","other":"d3b5df108f35a82e569016a06fefadb52797dafb505de1981f6678e2156574893a169b0adcc595377267dec0b7d620b5b50c7e7696c39eecee2c3e5f7bf71d18","up":true},{"one":"695e5706cece9d923c19a147283b772dd1ffa79e8d08506d2ed897d89545ffbdac1a130bd7ceeb82a2a57f2b4a613aa6e7264911b909fb9bff27cd435b802687","other":"c88ceea7f4d5148de8e2d71ffefc5c336cc62d322eb4371e457cbb97573b6323d200ff7678f94ef481c7b9daca3a9a7bab1e658d51fa279d433e19305df57814","up":true},{"one":"d2a392e9e7383b895587a7d6eea4a157de20caa9e2c62b4da5a8ff3186d129fee1330ddf3d180b1f59e1aa83686cd163222e38c84a84a0f60139968d6a56cbca","other":"12934e06d8821c5e149d944ee7a831428dc6c9eee8705f3b21046fdadc2864a9ffe2bdad60a4ba5a34d7a79c22631d52b62d511e81971b6b98896acae9427e94","up":true},{"one":"eaa3ad48682b08d9c91907a79e82938c1b30108745b276788c830dfcb0c0e752134369d751230e95fb7ab9777c38dcd105ad123ec5cc86ef6dbdd11fe31aea93","other":"0679dbbb51fa0283bcba387daa2180955d402a0ed42155095fcaffb96dbfd6b4b1bb0ed2ccf11cd990dfed4a3b320ee3f64286116a7b617a35989a448c367119","up":true},{"one":"e00f9a5611008d54bbbfe6a1cf402e011c92f540b47a82b7795508d1b857eee4a522e26c8351ddf6e303d353ee35afecbf9f54d7aae36e6736174473ac4caf73","other":"1be1903b1104bfae07438fb888993cb3e812fc38c8f26af2e68bff9f1758e9a69b29be3636ee24060c09ce900bad2004681e1083792b2a6e532bbfc07a3a0459","up":true},{"one":"331084cce2884ad912d5a20467c68fc261a02d6df0b60ff5b1427edc0885eab66a4f0f7e7fc9c676e994842f8126a3b34dbde91243f26bed6a0ba14babed56cc","other":"1be1903b1104bfae07438fb888993cb3e812fc38c8f26af2e68bff9f1758e9a69b29be3636ee24060c09ce900bad2004681e1083792b2a6e532bbfc07a3a0459","up":true},{"one":"eb11498b8cebc767d535481938c664359c6c84674da4d8fac729df64e288248bb020477ad4422cf1b7cea844db5ee12bb5cea82ac6e89a338d8ca1073e061f4c","other":"cf7d1a8ec1c3e68e862ef18947098ccbf6238fa7f85ee0018b7ac63b5387d6a9dbf194e3aad7edd1fda63ea63f2f5b8692ff885084adfd1f7b6613593960afc4","up":true},{"one":"26a6b8d30e0a8954bd9a0424b817ff79fec2e0521c1313c8262be9a3b9a0d1ee7f109be78d65ca9eb811a1634a813f4ba609887fd3c0085628b2a8ebd3426031","other":"e4b7b3bbeda388842ecb3688c041fe58bbd7e4566818a58b679e96215553dbf8569032a3ae941b3f8bb3e75886852d245bda5abf0c3cf70f532c38235e1a2175","up":true},{"one":"255c353a7585ab1bab41bcca409383dcdff5837bdcd7cebece1b6896fc06d0f65346ba618dc057c77734439612cb8cc3fd8aa068eb7569f0ad9e9e172daea678","other":"74d5d4ec7fdc749d9148b1a338b643e0a06abe03720b1d20b505da1ff1585b09d2cf7053293544fae1409cf26a27144870125787a473a73a1c4ca98509dc67ca","up":true},{"one":"4299205173b81c2822767a53cb4728fd5c0e1602d5976ee5db63b8118e489e4645ccdad399d9367e9b87b0a1f39e7988db86af687fe8cfff35d618b19d64b1a9","other":"61cbdddf6163152f5f8bbe3c710eeb9afb22dbec78d8f7eb3fd45ba44493b9387765527f059a10e694842786959c501303b1e62d3454c84870c14e0f36a58b0a","up":true},{"one":"5ed2923d11037da9799d933ea62cd23ce1aacec66a83a6d3a7e420ea0c66ec00af37977a78374df12dc0facb426d0c39cf306bea15abaf40f9072eacc4cf40fe","other":"e00f9a5611008d54bbbfe6a1cf402e011c92f540b47a82b7795508d1b857eee4a522e26c8351ddf6e303d353ee35afecbf9f54d7aae36e6736174473ac4caf73","up":true},{"one":"cf7d1a8ec1c3e68e862ef18947098ccbf6238fa7f85ee0018b7ac63b5387d6a9dbf194e3aad7edd1fda63ea63f2f5b8692ff885084adfd1f7b6613593960afc4","other":"e28c769630f19e79966bc354bb38313522778e4f06cd0872db8bd3afd7651882eba7b0403d82701cd063cbaee4ba0ba4a97c0c488fb44e8c8b72368d6881fdcf","up":true},{"one":"e4b7b3bbeda388842ecb3688c041fe58bbd7e4566818a58b679e96215553dbf8569032a3ae941b3f8bb3e75886852d245bda5abf0c3cf70f532c38235e1a2175","other":"61cbdddf6163152f5f8bbe3c710eeb9afb22dbec78d8f7eb3fd45ba44493b9387765527f059a10e694842786959c501303b1e62d3454c84870c14e0f36a58b0a","up":true},{"one":"a54b9c0cbc07e65b216f78bc0f56cd7003896641f1aa361fdc11e0bc208ee6bc876a455e89dee8abf67c259c7b6a82e7ac0d6d06cc304ee05fbc26783c09863a","other":"5ed2923d11037da9799d933ea62cd23ce1aacec66a83a6d3a7e420ea0c66ec00af37977a78374df12dc0facb426d0c39cf306bea15abaf40f9072eacc4cf40fe","up":true},{"one":"12934e06d8821c5e149d944ee7a831428dc6c9eee8705f3b21046fdadc2864a9ffe2bdad60a4ba5a34d7a79c22631d52b62d511e81971b6b98896acae9427e94","other":"c88ceea7f4d5148de8e2d71ffefc5c336cc62d322eb4371e457cbb97573b6323d200ff7678f94ef481c7b9daca3a9a7bab1e658d51fa279d433e19305df57814","up":true},{"one":"e0e0e90fa669023a1a9c564727cc657ce564c23e05b1c2b61f6bfbd5eb03feb75d34b029886e3426e1bbe4a49398794dfefa0557b7db57c15700c69c0e038029","other":"82bd5207dec292f911ff7dbcd242bf8962ab256057b1173dba2d71cd8cc77d41f38bf8d9a4eed83edeeb0e6f5bfabe8c7cae9490cc17dca1f454b9ad1b76224b","up":true},{"one":"695e5706cece9d923c19a147283b772dd1ffa79e8d08506d2ed897d89545ffbdac1a130bd7ceeb82a2a57f2b4a613aa6e7264911b909fb9bff27cd435b802687","other":"d2a392e9e7383b895587a7d6eea4a157de20caa9e2c62b4da5a8ff3186d129fee1330ddf3d180b1f59e1aa83686cd163222e38c84a84a0f60139968d6a56cbca","up":true},{"one":"b5e3b3cc7ac15224ff10cf8974ceaf7ad2ebb18ab9505bbb342c42e6ca65fe3541c14e1ee10ac3a0e7a0d87c29e25114e0c0d957d5dbbadf6136805be3046b4c","other":"aca2af376ef1c983514f75cd717c0852e9d4321e705517196fab4fafe109c1f3581866e1865d41977f8c23a31ec7fa218c11db0c87eb4bb96390025a96386f9a","up":true},{"one":"aca2af376ef1c983514f75cd717c0852e9d4321e705517196fab4fafe109c1f3581866e1865d41977f8c23a31ec7fa218c11db0c87eb4bb96390025a96386f9a","other":"2b1d1ec3ee35fa63571f46a2781d5fb14379319da2d67e482c24b27bacc2b792cd61a2c1138b8ba27673b1c08588064fdf9c73c80f0278e4f0ba133d78127337","up":true},{"one":"a197cd9e7e2d19287745f486582b7242c991f36183e8b2bf4983d7a9b9026e9884e3295183f376cd796b814fdf352b1c8c5c609a0e5f5d5155ab925d4b6fdeb9","other":"d3b5df108f35a82e569016a06fefadb52797dafb505de1981f6678e2156574893a169b0adcc595377267dec0b7d620b5b50c7e7696c39eecee2c3e5f7bf71d18","up":true},{"one":"66ce6e2c75f429c4bc7de6f1c785258686cfd66867336a1030830bbcc78bf642f4d1920ab5fc68953b70b7aca02ec518515d48d20397ed207ccbeb88c36e7057","other":"74d5d4ec7fdc749d9148b1a338b643e0a06abe03720b1d20b505da1ff1585b09d2cf7053293544fae1409cf26a27144870125787a473a73a1c4ca98509dc67ca","up":true},{"one":"61cbdddf6163152f5f8bbe3c710eeb9afb22dbec78d8f7eb3fd45ba44493b9387765527f059a10e694842786959c501303b1e62d3454c84870c14e0f36a58b0a","other":"26a6b8d30e0a8954bd9a0424b817ff79fec2e0521c1313c8262be9a3b9a0d1ee7f109be78d65ca9eb811a1634a813f4ba609887fd3c0085628b2a8ebd3426031","up":true},{"one":"82bd5207dec292f911ff7dbcd242bf8962ab256057b1173dba2d71cd8cc77d41f38bf8d9a4eed83edeeb0e6f5bfabe8c7cae9490cc17dca1f454b9ad1b76224b","other":"2b1d1ec3ee35fa63571f46a2781d5fb14379319da2d67e482c24b27bacc2b792cd61a2c1138b8ba27673b1c08588064fdf9c73c80f0278e4f0ba133d78127337","up":true},{"one":"1be1903b1104bfae07438fb888993cb3e812fc38c8f26af2e68bff9f1758e9a69b29be3636ee24060c09ce900bad2004681e1083792b2a6e532bbfc07a3a0459","other":"eb11498b8cebc767d535481938c664359c6c84674da4d8fac729df64e288248bb020477ad4422cf1b7cea844db5ee12bb5cea82ac6e89a338d8ca1073e061f4c","up":true},{"one":"0679dbbb51fa0283bcba387daa2180955d402a0ed42155095fcaffb96dbfd6b4b1bb0ed2ccf11cd990dfed4a3b320ee3f64286116a7b617a35989a448c367119","other":"fb6e36b9de5eef05780efcf16113fc9098a699ac525bd970dc5b6a92f596da6ffca044e434b97cd712a4035c38dd3ab08488042519f6269bc5057853b643bbcc","up":true},{"one":"74d5d4ec7fdc749d9148b1a338b643e0a06abe03720b1d20b505da1ff1585b09d2cf7053293544fae1409cf26a27144870125787a473a73a1c4ca98509dc67ca","other":"e00f9a5611008d54bbbfe6a1cf402e011c92f540b47a82b7795508d1b857eee4a522e26c8351ddf6e303d353ee35afecbf9f54d7aae36e6736174473ac4caf73","up":true},{"one":"d2a392e9e7383b895587a7d6eea4a157de20caa9e2c62b4da5a8ff3186d129fee1330ddf3d180b1f59e1aa83686cd163222e38c84a84a0f60139968d6a56cbca","other":"c88ceea7f4d5148de8e2d71ffefc5c336cc62d322eb4371e457cbb97573b6323d200ff7678f94ef481c7b9daca3a9a7bab1e658d51fa279d433e19305df57814","up":true},{"one":"fb6e36b9de5eef05780efcf16113fc9098a699ac525bd970dc5b6a92f596da6ffca044e434b97cd712a4035c38dd3ab08488042519f6269bc5057853b643bbcc","other":"1149e4bcd71c75b14ba7492587fa77e4a4de14e5c580a165ad8835258d1afcb15e65d02257ad8884b0e47be061d3129d8e3af90cbe4a1a96f828a1f84e0d72c6","up":true},{"one":"eaa3ad48682b08d9c91907a79e82938c1b30108745b276788c830dfcb0c0e752134369d751230e95fb7ab9777c38dcd105ad123ec5cc86ef6dbdd11fe31aea93","other":"1149e4bcd71c75b14ba7492587fa77e4a4de14e5c580a165ad8835258d1afcb15e65d02257ad8884b0e47be061d3129d8e3af90cbe4a1a96f828a1f84e0d72c6","up":true},{"one":"331084cce2884ad912d5a20467c68fc261a02d6df0b60ff5b1427edc0885eab66a4f0f7e7fc9c676e994842f8126a3b34dbde91243f26bed6a0ba14babed56cc","other":"d2a392e9e7383b895587a7d6eea4a157de20caa9e2c62b4da5a8ff3186d129fee1330ddf3d180b1f59e1aa83686cd163222e38c84a84a0f60139968d6a56cbca","up":true},{"one":"e00f9a5611008d54bbbfe6a1cf402e011c92f540b47a82b7795508d1b857eee4a522e26c8351ddf6e303d353ee35afecbf9f54d7aae36e6736174473ac4caf73","other":"a197cd9e7e2d19287745f486582b7242c991f36183e8b2bf4983d7a9b9026e9884e3295183f376cd796b814fdf352b1c8c5c609a0e5f5d5155ab925d4b6fdeb9","up":true},{"one":"0679dbbb51fa0283bcba387daa2180955d402a0ed42155095fcaffb96dbfd6b4b1bb0ed2ccf11cd990dfed4a3b320ee3f64286116a7b617a35989a448c367119","other":"1149e4bcd71c75b14ba7492587fa77e4a4de14e5c580a165ad8835258d1afcb15e65d02257ad8884b0e47be061d3129d8e3af90cbe4a1a96f828a1f84e0d72c6","up":true},{"one":"e4b7b3bbeda388842ecb3688c041fe58bbd7e4566818a58b679e96215553dbf8569032a3ae941b3f8bb3e75886852d245bda5abf0c3cf70f532c38235e1a2175","other":"d2a392e9e7383b895587a7d6eea4a157de20caa9e2c62b4da5a8ff3186d129fee1330ddf3d180b1f59e1aa83686cd163222e38c84a84a0f60139968d6a56cbca","up":true},{"one":"a197cd9e7e2d19287745f486582b7242c991f36183e8b2bf4983d7a9b9026e9884e3295183f376cd796b814fdf352b1c8c5c609a0e5f5d5155ab925d4b6fdeb9","other":"331084cce2884ad912d5a20467c68fc261a02d6df0b60ff5b1427edc0885eab66a4f0f7e7fc9c676e994842f8126a3b34dbde91243f26bed6a0ba14babed56cc","up":true},{"one":"eb11498b8cebc767d535481938c664359c6c84674da4d8fac729df64e288248bb020477ad4422cf1b7cea844db5ee12bb5cea82ac6e89a338d8ca1073e061f4c","other":"6c0b3b7c1c08bb558d92f0172fb8bfabe52a4bf8348b2f82e50c6d492a595dd0677b4559d7d2cd5a6e51ecdaf9a0f898f154730b87a8d9b265c6a54f9f6802a7","up":true},{"one":"1be1903b1104bfae07438fb888993cb3e812fc38c8f26af2e68bff9f1758e9a69b29be3636ee24060c09ce900bad2004681e1083792b2a6e532bbfc07a3a0459","other":"e0e0e90fa669023a1a9c564727cc657ce564c23e05b1c2b61f6bfbd5eb03feb75d34b029886e3426e1bbe4a49398794dfefa0557b7db57c15700c69c0e038029","up":true},{"one":"255c353a7585ab1bab41bcca409383dcdff5837bdcd7cebece1b6896fc06d0f65346ba618dc057c77734439612cb8cc3fd8aa068eb7569f0ad9e9e172daea678","other":"e00f9a5611008d54bbbfe6a1cf402e011c92f540b47a82b7795508d1b857eee4a522e26c8351ddf6e303d353ee35afecbf9f54d7aae36e6736174473ac4caf73","up":true},{"one":"26a6b8d30e0a8954bd9a0424b817ff79fec2e0521c1313c8262be9a3b9a0d1ee7f109be78d65ca9eb811a1634a813f4ba609887fd3c0085628b2a8ebd3426031","other":"d2a392e9e7383b895587a7d6eea4a157de20caa9e2c62b4da5a8ff3186d129fee1330ddf3d180b1f59e1aa83686cd163222e38c84a84a0f60139968d6a56cbca","up":true},{"one":"a54b9c0cbc07e65b216f78bc0f56cd7003896641f1aa361fdc11e0bc208ee6bc876a455e89dee8abf67c259c7b6a82e7ac0d6d06cc304ee05fbc26783c09863a","other":"6c0b3b7c1c08bb558d92f0172fb8bfabe52a4bf8348b2f82e50c6d492a595dd0677b4559d7d2cd5a6e51ecdaf9a0f898f154730b87a8d9b265c6a54f9f6802a7","up":true},{"one":"cf7d1a8ec1c3e68e862ef18947098ccbf6238fa7f85ee0018b7ac63b5387d6a9dbf194e3aad7edd1fda63ea63f2f5b8692ff885084adfd1f7b6613593960afc4","other":"d2a392e9e7383b895587a7d6eea4a157de20caa9e2c62b4da5a8ff3186d129fee1330ddf3d180b1f59e1aa83686cd163222e38c84a84a0f60139968d6a56cbca","up":true},{"one":"66ce6e2c75f429c4bc7de6f1c785258686cfd66867336a1030830bbcc78bf642f4d1920ab5fc68953b70b7aca02ec518515d48d20397ed207ccbeb88c36e7057","other":"d2a392e9e7383b895587a7d6eea4a157de20caa9e2c62b4da5a8ff3186d129fee1330ddf3d180b1f59e1aa83686cd163222e38c84a84a0f60139968d6a56cbca","up":true},{"one":"82bd5207dec292f911ff7dbcd242bf8962ab256057b1173dba2d71cd8cc77d41f38bf8d9a4eed83edeeb0e6f5bfabe8c7cae9490cc17dca1f454b9ad1b76224b","other":"aca2af376ef1c983514f75cd717c0852e9d4321e705517196fab4fafe109c1f3581866e1865d41977f8c23a31ec7fa218c11db0c87eb4bb96390025a96386f9a","up":true},{"one":"61cbdddf6163152f5f8bbe3c710eeb9afb22dbec78d8f7eb3fd45ba44493b9387765527f059a10e694842786959c501303b1e62d3454c84870c14e0f36a58b0a","other":"d2a392e9e7383b895587a7d6eea4a157de20caa9e2c62b4da5a8ff3186d129fee1330ddf3d180b1f59e1aa83686cd163222e38c84a84a0f60139968d6a56cbca","up":true},{"one":"74d5d4ec7fdc749d9148b1a338b643e0a06abe03720b1d20b505da1ff1585b09d2cf7053293544fae1409cf26a27144870125787a473a73a1c4ca98509dc67ca","other":"6c0b3b7c1c08bb558d92f0172fb8bfabe52a4bf8348b2f82e50c6d492a595dd0677b4559d7d2cd5a6e51ecdaf9a0f898f154730b87a8d9b265c6a54f9f6802a7","up":true},{"one":"e0e0e90fa669023a1a9c564727cc657ce564c23e05b1c2b61f6bfbd5eb03feb75d34b029886e3426e1bbe4a49398794dfefa0557b7db57c15700c69c0e038029","other":"aca2af376ef1c983514f75cd717c0852e9d4321e705517196fab4fafe109c1f3581866e1865d41977f8c23a31ec7fa218c11db0c87eb4bb96390025a96386f9a","up":true},{"one":"12934e06d8821c5e149d944ee7a831428dc6c9eee8705f3b21046fdadc2864a9ffe2bdad60a4ba5a34d7a79c22631d52b62d511e81971b6b98896acae9427e94","other":"dc63b83b488b7b505d5b2a60680b7dc87b1c5b61509e8030ebc67512ba72c0f616c1594946878dfb29e79f351d7134306778a74d5f5b7d5e08dbdb6dd6ade359","up":true},{"one":"695e5706cece9d923c19a147283b772dd1ffa79e8d08506d2ed897d89545ffbdac1a130bd7ceeb82a2a57f2b4a613aa6e7264911b909fb9bff27cd435b802687","other":"dc63b83b488b7b505d5b2a60680b7dc87b1c5b61509e8030ebc67512ba72c0f616c1594946878dfb29e79f351d7134306778a74d5f5b7d5e08dbdb6dd6ade359","up":true},{"one":"b5e3b3cc7ac15224ff10cf8974ceaf7ad2ebb18ab9505bbb342c42e6ca65fe3541c14e1ee10ac3a0e7a0d87c29e25114e0c0d957d5dbbadf6136805be3046b4c","other":"d2a392e9e7383b895587a7d6eea4a157de20caa9e2c62b4da5a8ff3186d129fee1330ddf3d180b1f59e1aa83686cd163222e38c84a84a0f60139968d6a56cbca","up":true},{"one":"aca2af376ef1c983514f75cd717c0852e9d4321e705517196fab4fafe109c1f3581866e1865d41977f8c23a31ec7fa218c11db0c87eb4bb96390025a96386f9a","other":"e00f9a5611008d54bbbfe6a1cf402e011c92f540b47a82b7795508d1b857eee4a522e26c8351ddf6e303d353ee35afecbf9f54d7aae36e6736174473ac4caf73","up":true},{"one":"fb6e36b9de5eef05780efcf16113fc9098a699ac525bd970dc5b6a92f596da6ffca044e434b97cd712a4035c38dd3ab08488042519f6269bc5057853b643bbcc","other":"d2a392e9e7383b895587a7d6eea4a157de20caa9e2c62b4da5a8ff3186d129fee1330ddf3d180b1f59e1aa83686cd163222e38c84a84a0f60139968d6a56cbca","up":true},{"one":"d3b5df108f35a82e569016a06fefadb52797dafb505de1981f6678e2156574893a169b0adcc595377267dec0b7d620b5b50c7e7696c39eecee2c3e5f7bf71d18","other":"d2a392e9e7383b895587a7d6eea4a157de20caa9e2c62b4da5a8ff3186d129fee1330ddf3d180b1f59e1aa83686cd163222e38c84a84a0f60139968d6a56cbca","up":true},{"one":"c88ceea7f4d5148de8e2d71ffefc5c336cc62d322eb4371e457cbb97573b6323d200ff7678f94ef481c7b9daca3a9a7bab1e658d51fa279d433e19305df57814","other":"dc63b83b488b7b505d5b2a60680b7dc87b1c5b61509e8030ebc67512ba72c0f616c1594946878dfb29e79f351d7134306778a74d5f5b7d5e08dbdb6dd6ade359","up":true},{"one":"eaa3ad48682b08d9c91907a79e82938c1b30108745b276788c830dfcb0c0e752134369d751230e95fb7ab9777c38dcd105ad123ec5cc86ef6dbdd11fe31aea93","other":"cf7d1a8ec1c3e68e862ef18947098ccbf6238fa7f85ee0018b7ac63b5387d6a9dbf194e3aad7edd1fda63ea63f2f5b8692ff885084adfd1f7b6613593960afc4","up":true},{"one":"331084cce2884ad912d5a20467c68fc261a02d6df0b60ff5b1427edc0885eab66a4f0f7e7fc9c676e994842f8126a3b34dbde91243f26bed6a0ba14babed56cc","other":"e0e0e90fa669023a1a9c564727cc657ce564c23e05b1c2b61f6bfbd5eb03feb75d34b029886e3426e1bbe4a49398794dfefa0557b7db57c15700c69c0e038029","up":true},{"one":"e00f9a5611008d54bbbfe6a1cf402e011c92f540b47a82b7795508d1b857eee4a522e26c8351ddf6e303d353ee35afecbf9f54d7aae36e6736174473ac4caf73","other":"82bd5207dec292f911ff7dbcd242bf8962ab256057b1173dba2d71cd8cc77d41f38bf8d9a4eed83edeeb0e6f5bfabe8c7cae9490cc17dca1f454b9ad1b76224b","up":true},{"one":"a197cd9e7e2d19287745f486582b7242c991f36183e8b2bf4983d7a9b9026e9884e3295183f376cd796b814fdf352b1c8c5c609a0e5f5d5155ab925d4b6fdeb9","other":"1be1903b1104bfae07438fb888993cb3e812fc38c8f26af2e68bff9f1758e9a69b29be3636ee24060c09ce900bad2004681e1083792b2a6e532bbfc07a3a0459","up":true},{"one":"0679dbbb51fa0283bcba387daa2180955d402a0ed42155095fcaffb96dbfd6b4b1bb0ed2ccf11cd990dfed4a3b320ee3f64286116a7b617a35989a448c367119","other":"5ed2923d11037da9799d933ea62cd23ce1aacec66a83a6d3a7e420ea0c66ec00af37977a78374df12dc0facb426d0c39cf306bea15abaf40f9072eacc4cf40fe","up":true},{"one":"1be1903b1104bfae07438fb888993cb3e812fc38c8f26af2e68bff9f1758e9a69b29be3636ee24060c09ce900bad2004681e1083792b2a6e532bbfc07a3a0459","other":"aca2af376ef1c983514f75cd717c0852e9d4321e705517196fab4fafe109c1f3581866e1865d41977f8c23a31ec7fa218c11db0c87eb4bb96390025a96386f9a","up":true},{"one":"eb11498b8cebc767d535481938c664359c6c84674da4d8fac729df64e288248bb020477ad4422cf1b7cea844db5ee12bb5cea82ac6e89a338d8ca1073e061f4c","other":"d2a392e9e7383b895587a7d6eea4a157de20caa9e2c62b4da5a8ff3186d129fee1330ddf3d180b1f59e1aa83686cd163222e38c84a84a0f60139968d6a56cbca","up":true},{"one":"d3b5df108f35a82e569016a06fefadb52797dafb505de1981f6678e2156574893a169b0adcc595377267dec0b7d620b5b50c7e7696c39eecee2c3e5f7bf71d18","other":"e0e0e90fa669023a1a9c564727cc657ce564c23e05b1c2b61f6bfbd5eb03feb75d34b029886e3426e1bbe4a49398794dfefa0557b7db57c15700c69c0e038029","up":true},{"one":"255c353a7585ab1bab41bcca409383dcdff5837bdcd7cebece1b6896fc06d0f65346ba618dc057c77734439612cb8cc3fd8aa068eb7569f0ad9e9e172daea678","other":"6c0b3b7c1c08bb558d92f0172fb8bfabe52a4bf8348b2f82e50c6d492a595dd0677b4559d7d2cd5a6e51ecdaf9a0f898f154730b87a8d9b265c6a54f9f6802a7","up":true},{"one":"66ce6e2c75f429c4bc7de6f1c785258686cfd66867336a1030830bbcc78bf642f4d1920ab5fc68953b70b7aca02ec518515d48d20397ed207ccbeb88c36e7057","other":"e00f9a5611008d54bbbfe6a1cf402e011c92f540b47a82b7795508d1b857eee4a522e26c8351ddf6e303d353ee35afecbf9f54d7aae36e6736174473ac4caf73","up":true},{"one":"cf7d1a8ec1c3e68e862ef18947098ccbf6238fa7f85ee0018b7ac63b5387d6a9dbf194e3aad7edd1fda63ea63f2f5b8692ff885084adfd1f7b6613593960afc4","other":"e00f9a5611008d54bbbfe6a1cf402e011c92f540b47a82b7795508d1b857eee4a522e26c8351ddf6e303d353ee35afecbf9f54d7aae36e6736174473ac4caf73","up":true},{"one":"a54b9c0cbc07e65b216f78bc0f56cd7003896641f1aa361fdc11e0bc208ee6bc876a455e89dee8abf67c259c7b6a82e7ac0d6d06cc304ee05fbc26783c09863a","other":"d2a392e9e7383b895587a7d6eea4a157de20caa9e2c62b4da5a8ff3186d129fee1330ddf3d180b1f59e1aa83686cd163222e38c84a84a0f60139968d6a56cbca","up":true},{"one":"82bd5207dec292f911ff7dbcd242bf8962ab256057b1173dba2d71cd8cc77d41f38bf8d9a4eed83edeeb0e6f5bfabe8c7cae9490cc17dca1f454b9ad1b76224b","other":"a197cd9e7e2d19287745f486582b7242c991f36183e8b2bf4983d7a9b9026e9884e3295183f376cd796b814fdf352b1c8c5c609a0e5f5d5155ab925d4b6fdeb9","up":true},{"one":"2b1d1ec3ee35fa63571f46a2781d5fb14379319da2d67e482c24b27bacc2b792cd61a2c1138b8ba27673b1c08588064fdf9c73c80f0278e4f0ba133d78127337","other":"26a6b8d30e0a8954bd9a0424b817ff79fec2e0521c1313c8262be9a3b9a0d1ee7f109be78d65ca9eb811a1634a813f4ba609887fd3c0085628b2a8ebd3426031","up":true},{"one":"e0e0e90fa669023a1a9c564727cc657ce564c23e05b1c2b61f6bfbd5eb03feb75d34b029886e3426e1bbe4a49398794dfefa0557b7db57c15700c69c0e038029","other":"b5e3b3cc7ac15224ff10cf8974ceaf7ad2ebb18ab9505bbb342c42e6ca65fe3541c14e1ee10ac3a0e7a0d87c29e25114e0c0d957d5dbbadf6136805be3046b4c","up":true},{"one":"74d5d4ec7fdc749d9148b1a338b643e0a06abe03720b1d20b505da1ff1585b09d2cf7053293544fae1409cf26a27144870125787a473a73a1c4ca98509dc67ca","other":"eaa3ad48682b08d9c91907a79e82938c1b30108745b276788c830dfcb0c0e752134369d751230e95fb7ab9777c38dcd105ad123ec5cc86ef6dbdd11fe31aea93","up":true},{"one":"12934e06d8821c5e149d944ee7a831428dc6c9eee8705f3b21046fdadc2864a9ffe2bdad60a4ba5a34d7a79c22631d52b62d511e81971b6b98896acae9427e94","other":"26a6b8d30e0a8954bd9a0424b817ff79fec2e0521c1313c8262be9a3b9a0d1ee7f109be78d65ca9eb811a1634a813f4ba609887fd3c0085628b2a8ebd3426031","up":true},{"one":"dc63b83b488b7b505d5b2a60680b7dc87b1c5b61509e8030ebc67512ba72c0f616c1594946878dfb29e79f351d7134306778a74d5f5b7d5e08dbdb6dd6ade359","other":"26a6b8d30e0a8954bd9a0424b817ff79fec2e0521c1313c8262be9a3b9a0d1ee7f109be78d65ca9eb811a1634a813f4ba609887fd3c0085628b2a8ebd3426031","up":true},{"one":"695e5706cece9d923c19a147283b772dd1ffa79e8d08506d2ed897d89545ffbdac1a130bd7ceeb82a2a57f2b4a613aa6e7264911b909fb9bff27cd435b802687","other":"26a6b8d30e0a8954bd9a0424b817ff79fec2e0521c1313c8262be9a3b9a0d1ee7f109be78d65ca9eb811a1634a813f4ba609887fd3c0085628b2a8ebd3426031","up":true},{"one":"2b1d1ec3ee35fa63571f46a2781d5fb14379319da2d67e482c24b27bacc2b792cd61a2c1138b8ba27673b1c08588064fdf9c73c80f0278e4f0ba133d78127337","other":"e00f9a5611008d54bbbfe6a1cf402e011c92f540b47a82b7795508d1b857eee4a522e26c8351ddf6e303d353ee35afecbf9f54d7aae36e6736174473ac4caf73","up":true},{"one":"fb6e36b9de5eef05780efcf16113fc9098a699ac525bd970dc5b6a92f596da6ffca044e434b97cd712a4035c38dd3ab08488042519f6269bc5057853b643bbcc","other":"6c0b3b7c1c08bb558d92f0172fb8bfabe52a4bf8348b2f82e50c6d492a595dd0677b4559d7d2cd5a6e51ecdaf9a0f898f154730b87a8d9b265c6a54f9f6802a7","up":true},{"one":"b5e3b3cc7ac15224ff10cf8974ceaf7ad2ebb18ab9505bbb342c42e6ca65fe3541c14e1ee10ac3a0e7a0d87c29e25114e0c0d957d5dbbadf6136805be3046b4c","other":"e00f9a5611008d54bbbfe6a1cf402e011c92f540b47a82b7795508d1b857eee4a522e26c8351ddf6e303d353ee35afecbf9f54d7aae36e6736174473ac4caf73","up":true},{"one":"6c0b3b7c1c08bb558d92f0172fb8bfabe52a4bf8348b2f82e50c6d492a595dd0677b4559d7d2cd5a6e51ecdaf9a0f898f154730b87a8d9b265c6a54f9f6802a7","other":"e00f9a5611008d54bbbfe6a1cf402e011c92f540b47a82b7795508d1b857eee4a522e26c8351ddf6e303d353ee35afecbf9f54d7aae36e6736174473ac4caf73","up":true},{"one":"e28c769630f19e79966bc354bb38313522778e4f06cd0872db8bd3afd7651882eba7b0403d82701cd063cbaee4ba0ba4a97c0c488fb44e8c8b72368d6881fdcf","other":"255c353a7585ab1bab41bcca409383dcdff5837bdcd7cebece1b6896fc06d0f65346ba618dc057c77734439612cb8cc3fd8aa068eb7569f0ad9e9e172daea678","up":true},{"one":"1149e4bcd71c75b14ba7492587fa77e4a4de14e5c580a165ad8835258d1afcb15e65d02257ad8884b0e47be061d3129d8e3af90cbe4a1a96f828a1f84e0d72c6","other":"6c0b3b7c1c08bb558d92f0172fb8bfabe52a4bf8348b2f82e50c6d492a595dd0677b4559d7d2cd5a6e51ecdaf9a0f898f154730b87a8d9b265c6a54f9f6802a7","up":true},{"one":"6c0b3b7c1c08bb558d92f0172fb8bfabe52a4bf8348b2f82e50c6d492a595dd0677b4559d7d2cd5a6e51ecdaf9a0f898f154730b87a8d9b265c6a54f9f6802a7","other":"cf7d1a8ec1c3e68e862ef18947098ccbf6238fa7f85ee0018b7ac63b5387d6a9dbf194e3aad7edd1fda63ea63f2f5b8692ff885084adfd1f7b6613593960afc4","up":true},{"one":"331084cce2884ad912d5a20467c68fc261a02d6df0b60ff5b1427edc0885eab66a4f0f7e7fc9c676e994842f8126a3b34dbde91243f26bed6a0ba14babed56cc","other":"82bd5207dec292f911ff7dbcd242bf8962ab256057b1173dba2d71cd8cc77d41f38bf8d9a4eed83edeeb0e6f5bfabe8c7cae9490cc17dca1f454b9ad1b76224b","up":true},{"one":"e00f9a5611008d54bbbfe6a1cf402e011c92f540b47a82b7795508d1b857eee4a522e26c8351ddf6e303d353ee35afecbf9f54d7aae36e6736174473ac4caf73","other":"e0e0e90fa669023a1a9c564727cc657ce564c23e05b1c2b61f6bfbd5eb03feb75d34b029886e3426e1bbe4a49398794dfefa0557b7db57c15700c69c0e038029","up":true},{"one":"0679dbbb51fa0283bcba387daa2180955d402a0ed42155095fcaffb96dbfd6b4b1bb0ed2ccf11cd990dfed4a3b320ee3f64286116a7b617a35989a448c367119","other":"74d5d4ec7fdc749d9148b1a338b643e0a06abe03720b1d20b505da1ff1585b09d2cf7053293544fae1409cf26a27144870125787a473a73a1c4ca98509dc67ca","up":true},{"one":"a197cd9e7e2d19287745f486582b7242c991f36183e8b2bf4983d7a9b9026e9884e3295183f376cd796b814fdf352b1c8c5c609a0e5f5d5155ab925d4b6fdeb9","other":"d2a392e9e7383b895587a7d6eea4a157de20caa9e2c62b4da5a8ff3186d129fee1330ddf3d180b1f59e1aa83686cd163222e38c84a84a0f60139968d6a56cbca","up":true},{"one":"d3b5df108f35a82e569016a06fefadb52797dafb505de1981f6678e2156574893a169b0adcc595377267dec0b7d620b5b50c7e7696c39eecee2c3e5f7bf71d18","other":"aca2af376ef1c983514f75cd717c0852e9d4321e705517196fab4fafe109c1f3581866e1865d41977f8c23a31ec7fa218c11db0c87eb4bb96390025a96386f9a","up":true},{"one":"eb11498b8cebc767d535481938c664359c6c84674da4d8fac729df64e288248bb020477ad4422cf1b7cea844db5ee12bb5cea82ac6e89a338d8ca1073e061f4c","other":"74d5d4ec7fdc749d9148b1a338b643e0a06abe03720b1d20b505da1ff1585b09d2cf7053293544fae1409cf26a27144870125787a473a73a1c4ca98509dc67ca","up":true},{"one":"255c353a7585ab1bab41bcca409383dcdff5837bdcd7cebece1b6896fc06d0f65346ba618dc057c77734439612cb8cc3fd8aa068eb7569f0ad9e9e172daea678","other":"0679dbbb51fa0283bcba387daa2180955d402a0ed42155095fcaffb96dbfd6b4b1bb0ed2ccf11cd990dfed4a3b320ee3f64286116a7b617a35989a448c367119","up":true},{"one":"66ce6e2c75f429c4bc7de6f1c785258686cfd66867336a1030830bbcc78bf642f4d1920ab5fc68953b70b7aca02ec518515d48d20397ed207ccbeb88c36e7057","other":"0679dbbb51fa0283bcba387daa2180955d402a0ed42155095fcaffb96dbfd6b4b1bb0ed2ccf11cd990dfed4a3b320ee3f64286116a7b617a35989a448c367119","up":true},{"one":"a54b9c0cbc07e65b216f78bc0f56cd7003896641f1aa361fdc11e0bc208ee6bc876a455e89dee8abf67c259c7b6a82e7ac0d6d06cc304ee05fbc26783c09863a","other":"eaa3ad48682b08d9c91907a79e82938c1b30108745b276788c830dfcb0c0e752134369d751230e95fb7ab9777c38dcd105ad123ec5cc86ef6dbdd11fe31aea93","up":true},{"one":"e0e0e90fa669023a1a9c564727cc657ce564c23e05b1c2b61f6bfbd5eb03feb75d34b029886e3426e1bbe4a49398794dfefa0557b7db57c15700c69c0e038029","other":"a197cd9e7e2d19287745f486582b7242c991f36183e8b2bf4983d7a9b9026e9884e3295183f376cd796b814fdf352b1c8c5c609a0e5f5d5155ab925d4b6fdeb9","up":true},{"one":"1149e4bcd71c75b14ba7492587fa77e4a4de14e5c580a165ad8835258d1afcb15e65d02257ad8884b0e47be061d3129d8e3af90cbe4a1a96f828a1f84e0d72c6","other":"255c353a7585ab1bab41bcca409383dcdff5837bdcd7cebece1b6896fc06d0f65346ba618dc057c77734439612cb8cc3fd8aa068eb7569f0ad9e9e172daea678","up":true},{"one":"2b1d1ec3ee35fa63571f46a2781d5fb14379319da2d67e482c24b27bacc2b792cd61a2c1138b8ba27673b1c08588064fdf9c73c80f0278e4f0ba133d78127337","other":"a197cd9e7e2d19287745f486582b7242c991f36183e8b2bf4983d7a9b9026e9884e3295183f376cd796b814fdf352b1c8c5c609a0e5f5d5155ab925d4b6fdeb9","up":true},{"one":"b5e3b3cc7ac15224ff10cf8974ceaf7ad2ebb18ab9505bbb342c42e6ca65fe3541c14e1ee10ac3a0e7a0d87c29e25114e0c0d957d5dbbadf6136805be3046b4c","other":"a197cd9e7e2d19287745f486582b7242c991f36183e8b2bf4983d7a9b9026e9884e3295183f376cd796b814fdf352b1c8c5c609a0e5f5d5155ab925d4b6fdeb9","up":true},{"one":"fb6e36b9de5eef05780efcf16113fc9098a699ac525bd970dc5b6a92f596da6ffca044e434b97cd712a4035c38dd3ab08488042519f6269bc5057853b643bbcc","other":"66ce6e2c75f429c4bc7de6f1c785258686cfd66867336a1030830bbcc78bf642f4d1920ab5fc68953b70b7aca02ec518515d48d20397ed207ccbeb88c36e7057","up":true}]} \ No newline at end of file diff --git a/swarm/network/stream/testing/snapshot_64.json b/swarm/network/stream/testing/snapshot_64.json new file mode 100644 index 0000000000..997659c44f --- /dev/null +++ b/swarm/network/stream/testing/snapshot_64.json @@ -0,0 +1 @@ +{"nodes":[{"node":{"info":{"id":"a48a667469a1344cb70f269b21fb3ca9e83823226749fd9c232be1b86ab9427888f2ecb20ddfa56da361463a061e192570f2f8da3fa967c473320ca85e382c53","name":"node_a48a667469a1344cb70f269b21fb3ca9e83823226749fd9c232be1b86ab9427888f2ecb20ddfa56da361463a061e192570f2f8da3fa967c473320ca85e382c53","enode":"enode://a48a667469a1344cb70f269b21fb3ca9e83823226749fd9c232be1b86ab9427888f2ecb20ddfa56da361463a061e192570f2f8da3fa967c473320ca85e382c53@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"3p7/e3uAMj9UR0a5WW59prQ7kebG0GYK043x6Herj5k=","hive":"\n=========================================================================\nTue Apr 10 09:55:59 UTC 2018 KΛÐΞMLIΛ hive: queen's address: de9eff\npopulation: 12 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 37de 6623 | 37 0d48 (0) 1087 (0) 1464 (0) 1be4 (0)\n001 3 8387 9dc2 9ecf | 10 8387 (0) 9f2d (0) 9ecf (0) 9dc2 (0)\n002 1 fbbe | 6 fbbe (0) f0ee (0) f066 (0) f03f (0)\n003 1 cfa6 | 5 ce61 (0) cfa6 (0) c0f0 (0) c678 (0)\n004 1 d10e | 1 d10e (0)\n005 2 dbc5 d8d8 | 2 d8d8 (0) dbc5 (0)\n006 0 | 0\n============ DEPTH: 7 ==========================================\n007 2 dfe3 df9a | 2 dfe3 (0) df9a (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"a48a667469a1344cb70f269b21fb3ca9e83823226749fd9c232be1b86ab9427888f2ecb20ddfa56da361463a061e192570f2f8da3fa967c473320ca85e382c53","private_key":"0736b1ccd6a1d7c513e312d29a8afa6e1231954e17a66886d0bbcf0dc191b170","name":"node_a48a667469a1344cb70f269b21fb3ca9e83823226749fd9c232be1b86ab9427888f2ecb20ddfa56da361463a061e192570f2f8da3fa967c473320ca85e382c53","services":["streamer"],"enable_msg_events":true,"port":62976},"up":true}},{"node":{"info":{"id":"8f6fb4a5baf715e001b060ce72378829279ce06a3247bd4a6faa3c725ee1b949570373e4231de82981020563e704297e77172506101b1444fcacfcc5f211827e","name":"node_8f6fb4a5baf715e001b060ce72378829279ce06a3247bd4a6faa3c725ee1b949570373e4231de82981020563e704297e77172506101b1444fcacfcc5f211827e","enode":"enode://8f6fb4a5baf715e001b060ce72378829279ce06a3247bd4a6faa3c725ee1b949570373e4231de82981020563e704297e77172506101b1444fcacfcc5f211827e@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"ZiMOC+xBz882Z9fdxzEoiK5Ih+hDDFfe2vzbrbbBI2Q=","hive":"\n=========================================================================\nTue Apr 10 09:55:59 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 66230e\npopulation: 16 (61), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 5 ada8 be9f be69 d10e | 27 8387 (0) 9ecf (0) 9f2d (0) 9dc2 (0)\n001 1 37de | 16 0d48 (0) 1087 (0) 1464 (0) 1be4 (0)\n002 3 44b1 5c3c 56ac | 9 4390 (0) 44b1 (0) 577b (0) 56ac (0)\n003 3 72f7 7693 7a56 | 5 72f7 (0) 7768 (0) 7693 (0) 7a1f (0)\n004 2 6c4b 68d4 | 2 6c4b (0) 68d4 (0)\n============ DEPTH: 5 ==========================================\n005 2 61c2 634c | 2 61c2 (0) 634c (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"8f6fb4a5baf715e001b060ce72378829279ce06a3247bd4a6faa3c725ee1b949570373e4231de82981020563e704297e77172506101b1444fcacfcc5f211827e","private_key":"edcc0061564101058d0caf2a7dd7cd178a2fd7f5de93263f1b2abac25ce28360","name":"node_8f6fb4a5baf715e001b060ce72378829279ce06a3247bd4a6faa3c725ee1b949570373e4231de82981020563e704297e77172506101b1444fcacfcc5f211827e","services":["streamer"],"enable_msg_events":true,"port":62977},"up":true}},{"node":{"info":{"id":"e7b1563d6e089e030983b075b590abb8a3205e9bce953f562b755ba150a3edc2dc3377259d96c05cc7363a23aed613711ca049e26253fd9273ac4c0483087015","name":"node_e7b1563d6e089e030983b075b590abb8a3205e9bce953f562b755ba150a3edc2dc3377259d96c05cc7363a23aed613711ca049e26253fd9273ac4c0483087015","enode":"enode://e7b1563d6e089e030983b075b590abb8a3205e9bce953f562b755ba150a3edc2dc3377259d96c05cc7363a23aed613711ca049e26253fd9273ac4c0483087015@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"0Q5YkH+E7vDfz9PIFFe2Du+bHqW5pGLiLwxOZDpucUA=","hive":"\n=========================================================================\nTue Apr 10 09:55:59 UTC 2018 KΛÐΞMLIΛ hive: queen's address: d10e58\npopulation: 13 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 6623 | 37 0d48 (0) 1087 (0) 1464 (0) 1be4 (0)\n001 1 be69 | 10 8387 (0) 9f2d (0) 9ecf (0) 9dc2 (0)\n002 2 f066 f03f | 6 fbbe (0) f0ee (0) f066 (0) f03f (0)\n003 4 ce61 c0f0 c6c4 c678 | 5 cfa6 (0) ce61 (0) c0f0 (0) c678 (0)\n============ DEPTH: 4 ==========================================\n004 5 d8d8 dbc5 dfe3 df9a | 5 d8d8 (0) dbc5 (0) dfe3 (0) df9a (0)\n005 0 | 0\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"e7b1563d6e089e030983b075b590abb8a3205e9bce953f562b755ba150a3edc2dc3377259d96c05cc7363a23aed613711ca049e26253fd9273ac4c0483087015","private_key":"911635b150029a2a56d4a5b647162774df1ff5e6946c727ba21e3e8cad2c41ce","name":"node_e7b1563d6e089e030983b075b590abb8a3205e9bce953f562b755ba150a3edc2dc3377259d96c05cc7363a23aed613711ca049e26253fd9273ac4c0483087015","services":["streamer"],"enable_msg_events":true,"port":62978},"up":true}},{"node":{"info":{"id":"d0718ce0dafea66ee16c79626e020355273cdd062c0fceb122e391c4ca6e4e408a1b0e8230c4ade5bc95803916bdd6d98c99d2b6ea70c32e17fa1f2c98741a90","name":"node_d0718ce0dafea66ee16c79626e020355273cdd062c0fceb122e391c4ca6e4e408a1b0e8230c4ade5bc95803916bdd6d98c99d2b6ea70c32e17fa1f2c98741a90","enode":"enode://d0718ce0dafea66ee16c79626e020355273cdd062c0fceb122e391c4ca6e4e408a1b0e8230c4ade5bc95803916bdd6d98c99d2b6ea70c32e17fa1f2c98741a90@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"vmkGJUui03SP+M4uu6uqA7rRyS0urcGrZHBUjLjXxSQ=","hive":"\n=========================================================================\nTue Apr 10 09:55:59 UTC 2018 KΛÐΞMLIΛ hive: queen's address: be6906\npopulation: 11 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 6623 | 37 4390 (0) 44b1 (0) 51db (0) 577b (0)\n001 3 cfa6 d10e dbc5 | 17 fbbe (0) f0ee (0) f066 (0) f03f (0)\n002 2 9ecf 9dc2 | 4 8387 (0) 9f2d (0) 9ecf (0) 9dc2 (0)\n003 2 a070 ada8 | 2 a070 (0) ada8 (0)\n004 1 b4be | 1 b4be (0)\n005 0 | 0\n006 0 | 0\n============ DEPTH: 7 ==========================================\n007 1 bfa0 | 1 bfa0 (0)\n008 1 be9f | 1 be9f (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"d0718ce0dafea66ee16c79626e020355273cdd062c0fceb122e391c4ca6e4e408a1b0e8230c4ade5bc95803916bdd6d98c99d2b6ea70c32e17fa1f2c98741a90","private_key":"4bd5083735663222c8e8948125c8f606952ef887a4a07888d39d8aa6af0568e8","name":"node_d0718ce0dafea66ee16c79626e020355273cdd062c0fceb122e391c4ca6e4e408a1b0e8230c4ade5bc95803916bdd6d98c99d2b6ea70c32e17fa1f2c98741a90","services":["streamer"],"enable_msg_events":true,"port":62979},"up":true}},{"node":{"info":{"id":"af3f9dc00ce3cc156000f16a06c55c123ccdfabed89c9aee4478ff439b6f52a89d0501cff626d36b7f1852737955f7a036b25cf259580e8f46a3e0e44340b539","name":"node_af3f9dc00ce3cc156000f16a06c55c123ccdfabed89c9aee4478ff439b6f52a89d0501cff626d36b7f1852737955f7a036b25cf259580e8f46a3e0e44340b539","enode":"enode://af3f9dc00ce3cc156000f16a06c55c123ccdfabed89c9aee4478ff439b6f52a89d0501cff626d36b7f1852737955f7a036b25cf259580e8f46a3e0e44340b539@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"28U24R03F4a/jGHux1XSyyIkLCfo7deYXa5hKp0srAU=","hive":"\n=========================================================================\nTue Apr 10 09:55:59 UTC 2018 KΛÐΞMLIΛ hive: queen's address: dbc536\npopulation: 10 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 3ff4 | 37 7693 (0) 7768 (0) 72f7 (0) 7a56 (0)\n001 1 be69 | 10 9f2d (0) 9ecf (0) 9dc2 (0) 8387 (0)\n002 2 f03f e5ee | 6 fbbe (0) f0ee (0) f066 (0) f03f (0)\n003 1 c0f0 | 5 c0f0 (0) c678 (0) c6c4 (0) cfa6 (0)\n004 1 d10e | 1 d10e (0)\n============ DEPTH: 5 ==========================================\n005 3 de9e df9a dfe3 | 3 de9e (0) dfe3 (0) df9a (0)\n006 1 d8d8 | 1 d8d8 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"af3f9dc00ce3cc156000f16a06c55c123ccdfabed89c9aee4478ff439b6f52a89d0501cff626d36b7f1852737955f7a036b25cf259580e8f46a3e0e44340b539","private_key":"8cb2a950934e687c8aea0a72114b26989bccfcdf508f584a549d05091aef2c3f","name":"node_af3f9dc00ce3cc156000f16a06c55c123ccdfabed89c9aee4478ff439b6f52a89d0501cff626d36b7f1852737955f7a036b25cf259580e8f46a3e0e44340b539","services":["streamer"],"enable_msg_events":true,"port":62980},"up":true}},{"node":{"info":{"id":"95c3ca2362de2eb0ac8efdd243918ed216f5d124bc6f5b9d83a6ee1aaf8a0fbdbd70ca1710d1ed825d6871f13a15954725f1aa1b27b48307844c0bc27baec0db","name":"node_95c3ca2362de2eb0ac8efdd243918ed216f5d124bc6f5b9d83a6ee1aaf8a0fbdbd70ca1710d1ed825d6871f13a15954725f1aa1b27b48307844c0bc27baec0db","enode":"enode://95c3ca2362de2eb0ac8efdd243918ed216f5d124bc6f5b9d83a6ee1aaf8a0fbdbd70ca1710d1ed825d6871f13a15954725f1aa1b27b48307844c0bc27baec0db@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"P/Q9E7buhLEo20IVxHxzkJ9mFgObh8pwq90hCOKd3fs=","hive":"\n=========================================================================\nTue Apr 10 09:55:59 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 3ff43d\npopulation: 13 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 e5ee dbc5 | 27 9f2d (0) 9ecf (0) 9dc2 (0) 8387 (0)\n001 2 7a1f 72f7 | 19 7693 (0) 7768 (0) 72f7 (0) 7a56 (0)\n002 1 1abc | 5 0d48 (0) 1464 (0) 1087 (0) 1be4 (0)\n003 2 2907 23e4 | 4 2d83 (0) 2f44 (0) 2907 (0) 23e4 (0)\n004 3 332f 30d8 36c2 | 5 332f (0) 30d8 (0) 358e (0) 36c2 (0)\n005 0 | 0\n============ DEPTH: 6 ==========================================\n006 2 3c38 3c93 | 2 3c38 (0) 3c93 (0)\n007 1 3ea2 | 1 3ea2 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"95c3ca2362de2eb0ac8efdd243918ed216f5d124bc6f5b9d83a6ee1aaf8a0fbdbd70ca1710d1ed825d6871f13a15954725f1aa1b27b48307844c0bc27baec0db","private_key":"3c147cdf4e85087a9c0e37ff5d96de7d977ce3d3711090f64d2c3bea39790167","name":"node_95c3ca2362de2eb0ac8efdd243918ed216f5d124bc6f5b9d83a6ee1aaf8a0fbdbd70ca1710d1ed825d6871f13a15954725f1aa1b27b48307844c0bc27baec0db","services":["streamer"],"enable_msg_events":true,"port":62981},"up":true}},{"node":{"info":{"id":"c73f8fe9f54b89634cb0e8e332407a3a90cbbd347c0abc93823db13a7a39c46e7bd30d3f557316d92dd731cfc686afc308448682ff06c77246e3fb02b9a025ba","name":"node_c73f8fe9f54b89634cb0e8e332407a3a90cbbd347c0abc93823db13a7a39c46e7bd30d3f557316d92dd731cfc686afc308448682ff06c77246e3fb02b9a025ba","enode":"enode://c73f8fe9f54b89634cb0e8e332407a3a90cbbd347c0abc93823db13a7a39c46e7bd30d3f557316d92dd731cfc686afc308448682ff06c77246e3fb02b9a025ba@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"5e6ioKwBdaCtQSOdjjblN859Qo1rROI+jjP/C+EbrHI=","hive":"\n=========================================================================\nTue Apr 10 09:55:59 UTC 2018 KΛÐΞMLIΛ hive: queen's address: e5eea2\npopulation: 12 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 5c3c 3ff4 | 37 7693 (0) 7768 (0) 72f7 (0) 7a56 (0)\n001 2 9f2d ada8 | 10 be9f (0) be69 (0) bfa0 (0) b4be (0)\n002 3 c6c4 ce61 dbc5 | 11 c0f0 (0) c678 (0) c6c4 (0) cfa6 (0)\n============ DEPTH: 3 ==========================================\n003 4 fbbe f0ee f066 f03f | 4 fbbe (0) f0ee (0) f066 (0) f03f (0)\n004 0 | 0\n005 1 e3c2 | 1 e3c2 (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"c73f8fe9f54b89634cb0e8e332407a3a90cbbd347c0abc93823db13a7a39c46e7bd30d3f557316d92dd731cfc686afc308448682ff06c77246e3fb02b9a025ba","private_key":"fb505af88aa3fc8134b3ad647d78f182e0aee007261c066024d9fdda0bd9d297","name":"node_c73f8fe9f54b89634cb0e8e332407a3a90cbbd347c0abc93823db13a7a39c46e7bd30d3f557316d92dd731cfc686afc308448682ff06c77246e3fb02b9a025ba","services":["streamer"],"enable_msg_events":true,"port":62982},"up":true}},{"node":{"info":{"id":"9529ff2b0692ad2608b55ec8ec0d1c9ccb8ee300412d99d389009162a76f7eec28d1090cbfb571aa8396b365074770b17106bfa3354857878dff164f42686142","name":"node_9529ff2b0692ad2608b55ec8ec0d1c9ccb8ee300412d99d389009162a76f7eec28d1090cbfb571aa8396b365074770b17106bfa3354857878dff164f42686142","enode":"enode://9529ff2b0692ad2608b55ec8ec0d1c9ccb8ee300412d99d389009162a76f7eec28d1090cbfb571aa8396b365074770b17106bfa3354857878dff164f42686142@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"XDyn+RVRk0u/pAIEM9exnkDQTZKRwrJmhu+FIl+HK78=","hive":"\n=========================================================================\nTue Apr 10 09:55:59 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 5c3ca7\npopulation: 13 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 e5ee | 27 a070 (0) ada8 (0) be9f (0) be69 (0)\n001 1 1abc | 18 2907 (0) 2f44 (0) 2d83 (0) 23e4 (0)\n002 3 6623 72f7 7a1f | 10 7693 (0) 7768 (0) 72f7 (0) 7a56 (0)\n003 2 4390 44b1 | 2 4390 (0) 44b1 (0)\n004 4 51db 577b 56ac 544a | 4 51db (0) 577b (0) 56ac (0) 544a (0)\n005 0 | 0\n006 0 | 0\n============ DEPTH: 7 ==========================================\n007 1 5d05 | 1 5d05 (0)\n008 1 5cdc | 1 5cdc (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"9529ff2b0692ad2608b55ec8ec0d1c9ccb8ee300412d99d389009162a76f7eec28d1090cbfb571aa8396b365074770b17106bfa3354857878dff164f42686142","private_key":"833d044f5a00d0018f8b2a7d4d825831f351dbe3f3e7074d96103c3597bb0a37","name":"node_9529ff2b0692ad2608b55ec8ec0d1c9ccb8ee300412d99d389009162a76f7eec28d1090cbfb571aa8396b365074770b17106bfa3354857878dff164f42686142","services":["streamer"],"enable_msg_events":true,"port":62983},"up":true}},{"node":{"info":{"id":"5b456e429f7adae30366206e681ba46439a3372fec3806f666425cb3f12983c0b427e089fb163b70e6a56220b1529ee392ff701bc2f4621d51e23aa6305150e8","name":"node_5b456e429f7adae30366206e681ba46439a3372fec3806f666425cb3f12983c0b427e089fb163b70e6a56220b1529ee392ff701bc2f4621d51e23aa6305150e8","enode":"enode://5b456e429f7adae30366206e681ba46439a3372fec3806f666425cb3f12983c0b427e089fb163b70e6a56220b1529ee392ff701bc2f4621d51e23aa6305150e8@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"GryrTomJZsQsEdGpKxwZEfx3kInFog6h3fAF92YysXE=","hive":"\n=========================================================================\nTue Apr 10 09:55:59 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 1abcab\npopulation: 14 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 df9a | 27 a070 (0) ada8 (0) bfa0 (0) be9f (0)\n001 1 5c3c | 19 7a56 (0) 7a1f (0) 7693 (0) 7768 (0)\n002 8 358e 36c2 332f 30d8 | 13 2907 (0) 2f44 (0) 2d83 (0) 23e4 (0)\n003 1 0d48 | 1 0d48 (0)\n============ DEPTH: 4 ==========================================\n004 2 1464 1087 | 2 1464 (0) 1087 (0)\n005 0 | 0\n006 0 | 0\n007 1 1be4 | 1 1be4 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"5b456e429f7adae30366206e681ba46439a3372fec3806f666425cb3f12983c0b427e089fb163b70e6a56220b1529ee392ff701bc2f4621d51e23aa6305150e8","private_key":"f08b159c68739d221adc0060225f8feb89dc3aa1f016cef59508d2787a4232a9","name":"node_5b456e429f7adae30366206e681ba46439a3372fec3806f666425cb3f12983c0b427e089fb163b70e6a56220b1529ee392ff701bc2f4621d51e23aa6305150e8","services":["streamer"],"enable_msg_events":true,"port":62984},"up":true}},{"node":{"info":{"id":"5e92b025cc087c8823423c287f274a32a3dc0065afdf189475ba96b0da7b785cd493b7f2a7f3bb8195c73025bfbb402cbb4e0f6ae0d5e0caab223193cf6f2e5c","name":"node_5e92b025cc087c8823423c287f274a32a3dc0065afdf189475ba96b0da7b785cd493b7f2a7f3bb8195c73025bfbb402cbb4e0f6ae0d5e0caab223193cf6f2e5c","enode":"enode://5e92b025cc087c8823423c287f274a32a3dc0065afdf189475ba96b0da7b785cd493b7f2a7f3bb8195c73025bfbb402cbb4e0f6ae0d5e0caab223193cf6f2e5c@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"35rVws0jdaWiJ4QYQaR4dnZfZVKossufqM3trsojce0=","hive":"\n=========================================================================\nTue Apr 10 09:55:59 UTC 2018 KΛÐΞMLIΛ hive: queen's address: df9ad5\npopulation: 11 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 1abc | 37 7a56 (0) 7a1f (0) 7768 (0) 7693 (0)\n001 1 9dc2 | 10 a070 (0) ada8 (0) bfa0 (0) be9f (0)\n002 1 fbbe | 6 e3c2 (0) e5ee (0) fbbe (0) f0ee (0)\n003 3 cfa6 c0f0 c6c4 | 5 ce61 (0) cfa6 (0) c0f0 (0) c678 (0)\n004 1 d10e | 1 d10e (0)\n005 2 dbc5 d8d8 | 2 dbc5 (0) d8d8 (0)\n006 0 | 0\n============ DEPTH: 7 ==========================================\n007 1 de9e | 1 de9e (0)\n008 0 | 0\n009 1 dfe3 | 1 dfe3 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"5e92b025cc087c8823423c287f274a32a3dc0065afdf189475ba96b0da7b785cd493b7f2a7f3bb8195c73025bfbb402cbb4e0f6ae0d5e0caab223193cf6f2e5c","private_key":"bbadcfc9e554aabf08f9cdea8f1174f4f47b85c5a615efa6f0d5a4db7e6e9f67","name":"node_5e92b025cc087c8823423c287f274a32a3dc0065afdf189475ba96b0da7b785cd493b7f2a7f3bb8195c73025bfbb402cbb4e0f6ae0d5e0caab223193cf6f2e5c","services":["streamer"],"enable_msg_events":true,"port":62985},"up":true}},{"node":{"info":{"id":"f6e4b1dc1fa95ceae2b932b178afdc2dd515832a191e0f49c916d5a04548d58ef9f8c1dda3fbc93a45e6d82517e6a573310b7bfb14bc38c57000aec9ff010391","name":"node_f6e4b1dc1fa95ceae2b932b178afdc2dd515832a191e0f49c916d5a04548d58ef9f8c1dda3fbc93a45e6d82517e6a573310b7bfb14bc38c57000aec9ff010391","enode":"enode://f6e4b1dc1fa95ceae2b932b178afdc2dd515832a191e0f49c916d5a04548d58ef9f8c1dda3fbc93a45e6d82517e6a573310b7bfb14bc38c57000aec9ff010391@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"2Nhy71sWMuq8pR8dJ1X6Wj8W3Eh9TYvpYJMO5EYqJjM=","hive":"\n=========================================================================\nTue Apr 10 09:55:59 UTC 2018 KΛÐΞMLIΛ hive: queen's address: d8d872\npopulation: 10 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 7a1f | 37 7a56 (0) 7a1f (0) 7768 (0) 7693 (0)\n001 1 ada8 | 10 a070 (0) ada8 (0) be9f (0) be69 (0)\n002 1 e3c2 | 6 fbbe (0) f0ee (0) f066 (0) f03f (0)\n003 2 c678 c6c4 | 5 cfa6 (0) ce61 (0) c0f0 (0) c678 (0)\n004 1 d10e | 1 d10e (0)\n============ DEPTH: 5 ==========================================\n005 3 de9e dfe3 df9a | 3 de9e (0) dfe3 (0) df9a (0)\n006 1 dbc5 | 1 dbc5 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"f6e4b1dc1fa95ceae2b932b178afdc2dd515832a191e0f49c916d5a04548d58ef9f8c1dda3fbc93a45e6d82517e6a573310b7bfb14bc38c57000aec9ff010391","private_key":"91980cc1a6aa75dabe27a4bed1a4a2299ed286387f066d12c1a05ab514245966","name":"node_f6e4b1dc1fa95ceae2b932b178afdc2dd515832a191e0f49c916d5a04548d58ef9f8c1dda3fbc93a45e6d82517e6a573310b7bfb14bc38c57000aec9ff010391","services":["streamer"],"enable_msg_events":true,"port":62986},"up":true}},{"node":{"info":{"id":"707a9ae4bc8b37fff43dc3ba83ecb735bd428b720a751a11112452eec1ca49c09139bc437666add2823dd205e45cc793f8657c66ccbc6911cc60771d4512e038","name":"node_707a9ae4bc8b37fff43dc3ba83ecb735bd428b720a751a11112452eec1ca49c09139bc437666add2823dd205e45cc793f8657c66ccbc6911cc60771d4512e038","enode":"enode://707a9ae4bc8b37fff43dc3ba83ecb735bd428b720a751a11112452eec1ca49c09139bc437666add2823dd205e45cc793f8657c66ccbc6911cc60771d4512e038@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"48IBF3YeGzw9fD0TPhv2jllO4llQzUMRqNlkkjxBZNo=","hive":"\n=========================================================================\nTue Apr 10 09:55:59 UTC 2018 KΛÐΞMLIΛ hive: queen's address: e3c201\npopulation: 9 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 544a | 37 2907 (0) 2f44 (0) 2d83 (0) 23e4 (0)\n001 1 ada8 | 10 a070 (0) ada8 (0) be9f (0) be69 (0)\n002 2 c6c4 d8d8 | 11 c0f0 (0) c6c4 (0) c678 (0) ce61 (0)\n============ DEPTH: 3 ==========================================\n003 4 f0ee f066 f03f fbbe | 4 fbbe (0) f0ee (0) f066 (0) f03f (0)\n004 0 | 0\n005 1 e5ee | 1 e5ee (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"707a9ae4bc8b37fff43dc3ba83ecb735bd428b720a751a11112452eec1ca49c09139bc437666add2823dd205e45cc793f8657c66ccbc6911cc60771d4512e038","private_key":"9f2513f57cafcbb35e549fae622387037b8da11772eef7bbb45d44f81712155b","name":"node_707a9ae4bc8b37fff43dc3ba83ecb735bd428b720a751a11112452eec1ca49c09139bc437666add2823dd205e45cc793f8657c66ccbc6911cc60771d4512e038","services":["streamer"],"enable_msg_events":true,"port":62987},"up":true}},{"node":{"info":{"id":"78216c6660fff0b96e38084941a2f237996732118033bf842e5f9e533b22b36c2da996df28e866424311b7b6414d4627db1f22a235ae777f7de34d9696043ecb","name":"node_78216c6660fff0b96e38084941a2f237996732118033bf842e5f9e533b22b36c2da996df28e866424311b7b6414d4627db1f22a235ae777f7de34d9696043ecb","enode":"enode://78216c6660fff0b96e38084941a2f237996732118033bf842e5f9e533b22b36c2da996df28e866424311b7b6414d4627db1f22a235ae777f7de34d9696043ecb@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"VErZIeA959HWVgOOI0Ut06nH7wQVIPF/gxgybsxYaDs=","hive":"\n=========================================================================\nTue Apr 10 09:55:59 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 544ad9\npopulation: 11 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 e3c2 | 27 a070 (0) ada8 (0) be9f (0) be69 (0)\n001 2 2f44 3c93 | 18 0d48 (0) 1087 (0) 1464 (0) 1be4 (0)\n002 2 61c2 634c | 10 68d4 (0) 6c4b (0) 61c2 (0) 634c (0)\n003 2 44b1 4390 | 2 4390 (0) 44b1 (0)\n004 1 5c3c | 3 5d05 (0) 5cdc (0) 5c3c (0)\n005 1 51db | 1 51db (0)\n============ DEPTH: 6 ==========================================\n006 2 577b 56ac | 2 577b (0) 56ac (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"78216c6660fff0b96e38084941a2f237996732118033bf842e5f9e533b22b36c2da996df28e866424311b7b6414d4627db1f22a235ae777f7de34d9696043ecb","private_key":"a198f5ac31e6bef23d8f266075f8363ce66698d0f8b1193072f813b2a1717236","name":"node_78216c6660fff0b96e38084941a2f237996732118033bf842e5f9e533b22b36c2da996df28e866424311b7b6414d4627db1f22a235ae777f7de34d9696043ecb","services":["streamer"],"enable_msg_events":true,"port":62988},"up":true}},{"node":{"info":{"id":"d472383c453e6b0f1a632010bdd6c42a9668d328a8f8071e0407069f6fe413e2a0fd0551a09cc56ee5245d472e39a7b6295491dd256ae42e200a257f297743e3","name":"node_d472383c453e6b0f1a632010bdd6c42a9668d328a8f8071e0407069f6fe413e2a0fd0551a09cc56ee5245d472e39a7b6295491dd256ae42e200a257f297743e3","enode":"enode://d472383c453e6b0f1a632010bdd6c42a9668d328a8f8071e0407069f6fe413e2a0fd0551a09cc56ee5245d472e39a7b6295491dd256ae42e200a257f297743e3@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"Vqw6xMwE6UyT2Yag7Z2oto2X8TyLXsNdVnA1kvwFvEM=","hive":"\n=========================================================================\nTue Apr 10 09:55:59 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 56ac3a\npopulation: 10 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 f0ee | 27 a070 (0) ada8 (0) be69 (0) be9f (0)\n001 1 3c93 | 18 0d48 (0) 1087 (0) 1464 (0) 1be4 (0)\n002 2 6623 634c | 10 68d4 (0) 6c4b (0) 6623 (0) 61c2 (0)\n003 2 4390 44b1 | 2 4390 (0) 44b1 (0)\n004 1 5c3c | 3 5d05 (0) 5cdc (0) 5c3c (0)\n005 1 51db | 1 51db (0)\n============ DEPTH: 6 ==========================================\n006 1 544a | 1 544a (0)\n007 1 577b | 1 577b (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"d472383c453e6b0f1a632010bdd6c42a9668d328a8f8071e0407069f6fe413e2a0fd0551a09cc56ee5245d472e39a7b6295491dd256ae42e200a257f297743e3","private_key":"9f8eddf3160bc4b13285e9587f6736c82305632b55fe833a12f1f821c0f311e4","name":"node_d472383c453e6b0f1a632010bdd6c42a9668d328a8f8071e0407069f6fe413e2a0fd0551a09cc56ee5245d472e39a7b6295491dd256ae42e200a257f297743e3","services":["streamer"],"enable_msg_events":true,"port":62989},"up":true}},{"node":{"info":{"id":"351ceaf2e95e098a8e15e81c82073b523f641848326d1bbd379f40f886b50ce2c377c4e3a2dfc2662d6f25ac04dede41063a075cf00be1cf36f95b0267717ab8","name":"node_351ceaf2e95e098a8e15e81c82073b523f641848326d1bbd379f40f886b50ce2c377c4e3a2dfc2662d6f25ac04dede41063a075cf00be1cf36f95b0267717ab8","enode":"enode://351ceaf2e95e098a8e15e81c82073b523f641848326d1bbd379f40f886b50ce2c377c4e3a2dfc2662d6f25ac04dede41063a075cf00be1cf36f95b0267717ab8@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"8O4CdOJKfMPRsNOM1G0gXMv3kdDMA40CLyoMUK5qXNU=","hive":"\n=========================================================================\nTue Apr 10 09:55:59 UTC 2018 KΛÐΞMLIΛ hive: queen's address: f0ee02\npopulation: 10 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 56ac 3c93 | 37 6c4b (0) 68d4 (0) 6623 (0) 61c2 (0)\n001 2 b4be 8387 | 10 ada8 (0) a070 (0) be69 (0) be9f (0)\n002 1 c678 | 11 ce61 (0) cfa6 (0) c0f0 (0) c6c4 (0)\n003 2 e5ee e3c2 | 2 e5ee (0) e3c2 (0)\n004 1 fbbe | 1 fbbe (0)\n005 0 | 0\n006 0 | 0\n007 0 | 0\n============ DEPTH: 8 ==========================================\n008 2 f066 f03f | 2 f066 (0) f03f (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"351ceaf2e95e098a8e15e81c82073b523f641848326d1bbd379f40f886b50ce2c377c4e3a2dfc2662d6f25ac04dede41063a075cf00be1cf36f95b0267717ab8","private_key":"601ed94a775c7129de2ddd82e23249e13176478817e5376a1c18389de0016283","name":"node_351ceaf2e95e098a8e15e81c82073b523f641848326d1bbd379f40f886b50ce2c377c4e3a2dfc2662d6f25ac04dede41063a075cf00be1cf36f95b0267717ab8","services":["streamer"],"enable_msg_events":true,"port":62990},"up":true}},{"node":{"info":{"id":"8da9cdb3c78776ed230497b21d4ac172f0ce73e921dfddd483da7bc6bbcd1951dd78fd5f70a0acbad855b2984e4c4bdb408c4bc25cab40684fe5a4408ec7ab9c","name":"node_8da9cdb3c78776ed230497b21d4ac172f0ce73e921dfddd483da7bc6bbcd1951dd78fd5f70a0acbad855b2984e4c4bdb408c4bc25cab40684fe5a4408ec7ab9c","enode":"enode://8da9cdb3c78776ed230497b21d4ac172f0ce73e921dfddd483da7bc6bbcd1951dd78fd5f70a0acbad855b2984e4c4bdb408c4bc25cab40684fe5a4408ec7ab9c@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"PJO2QUO/G/EwVFgGkXRy88oWrW8iPwOI9EXdw1MUAEI=","hive":"\n=========================================================================\nTue Apr 10 09:55:59 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 3c93b6\npopulation: 16 (61), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 f0ee 8387 | 25 ce61 (0) c0f0 (0) c678 (0) c6c4 (0)\n001 3 72f7 56ac 544a | 19 4390 (0) 44b1 (0) 5d05 (0) 5cdc (0)\n002 1 1abc | 5 0d48 (0) 1087 (0) 1464 (0) 1be4 (0)\n003 3 23e4 2f44 2907 | 4 2907 (0) 2d83 (0) 2f44 (0) 23e4 (0)\n004 4 36c2 37de 332f 30d8 | 5 358e (0) 37de (0) 36c2 (0) 332f (0)\n005 0 | 0\n============ DEPTH: 6 ==========================================\n006 2 3ea2 3ff4 | 2 3ea2 (0) 3ff4 (0)\n007 0 | 0\n008 1 3c38 | 1 3c38 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"8da9cdb3c78776ed230497b21d4ac172f0ce73e921dfddd483da7bc6bbcd1951dd78fd5f70a0acbad855b2984e4c4bdb408c4bc25cab40684fe5a4408ec7ab9c","private_key":"dd64b8659254425a4553501bcc275b1dc0a6c7bc79a538f780716cd64d46a8c2","name":"node_8da9cdb3c78776ed230497b21d4ac172f0ce73e921dfddd483da7bc6bbcd1951dd78fd5f70a0acbad855b2984e4c4bdb408c4bc25cab40684fe5a4408ec7ab9c","services":["streamer"],"enable_msg_events":true,"port":62991},"up":true}},{"node":{"info":{"id":"0a45a0aa4b4eee71b2828c794281d698019667288cf51311ffae7d8ea895f8ae29f7958dbfcda8763d9d8e9c097dccc5f92ac9d09fb4ccbde178d7f5ebda4d35","name":"node_0a45a0aa4b4eee71b2828c794281d698019667288cf51311ffae7d8ea895f8ae29f7958dbfcda8763d9d8e9c097dccc5f92ac9d09fb4ccbde178d7f5ebda4d35","enode":"enode://0a45a0aa4b4eee71b2828c794281d698019667288cf51311ffae7d8ea895f8ae29f7958dbfcda8763d9d8e9c097dccc5f92ac9d09fb4ccbde178d7f5ebda4d35@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"g4cLBIs3TtUn1LJSVpANS1P60R2QC1TjZvnj/nrlAHk=","hive":"\n=========================================================================\nTue Apr 10 09:55:59 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 83870b\npopulation: 11 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 72f7 3c93 | 37 4390 (0) 44b1 (0) 5d05 (0) 5cdc (0)\n001 3 dfe3 de9e f0ee | 17 ce61 (0) cfa6 (0) c0f0 (0) c6c4 (0)\n002 3 be9f bfa0 b4be | 6 ada8 (0) a070 (0) be69 (0) be9f (0)\n============ DEPTH: 3 ==========================================\n003 3 9ecf 9f2d 9dc2 | 3 9f2d (0) 9ecf (0) 9dc2 (0)\n004 0 | 0\n005 0 | 0\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"0a45a0aa4b4eee71b2828c794281d698019667288cf51311ffae7d8ea895f8ae29f7958dbfcda8763d9d8e9c097dccc5f92ac9d09fb4ccbde178d7f5ebda4d35","private_key":"7216dc13943bfd0a8c2e93d621a44a2dd4baab7b68fa87be06f2e649f533f72c","name":"node_0a45a0aa4b4eee71b2828c794281d698019667288cf51311ffae7d8ea895f8ae29f7958dbfcda8763d9d8e9c097dccc5f92ac9d09fb4ccbde178d7f5ebda4d35","services":["streamer"],"enable_msg_events":true,"port":62992},"up":true}},{"node":{"info":{"id":"f70c92be150cb3f65f6bd904c8c161bfb0cea717bab0b24da63714de83e0872c8c369960ada1629607a1e166a19b6cfa887603e4868e7912ae5512744e8cc1c0","name":"node_f70c92be150cb3f65f6bd904c8c161bfb0cea717bab0b24da63714de83e0872c8c369960ada1629607a1e166a19b6cfa887603e4868e7912ae5512744e8cc1c0","enode":"enode://f70c92be150cb3f65f6bd904c8c161bfb0cea717bab0b24da63714de83e0872c8c369960ada1629607a1e166a19b6cfa887603e4868e7912ae5512744e8cc1c0@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"cvd56RRgmQruRembBWUkaiYg1JOcw6sP4CH+/nGq52E=","hive":"\n=========================================================================\nTue Apr 10 09:55:59 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 72f779\npopulation: 12 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 f03f 8387 | 27 ce61 (0) cfa6 (0) c0f0 (0) c6c4 (0)\n001 2 3ff4 3c93 | 18 0d48 (0) 1087 (0) 1464 (0) 1be4 (0)\n002 3 5c3c 44b1 4390 | 9 4390 (0) 44b1 (0) 5d05 (0) 5cdc (0)\n003 1 6623 | 5 6c4b (0) 68d4 (0) 6623 (0) 61c2 (0)\n004 2 7a56 7a1f | 2 7a56 (0) 7a1f (0)\n============ DEPTH: 5 ==========================================\n005 2 7693 7768 | 2 7693 (0) 7768 (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"f70c92be150cb3f65f6bd904c8c161bfb0cea717bab0b24da63714de83e0872c8c369960ada1629607a1e166a19b6cfa887603e4868e7912ae5512744e8cc1c0","private_key":"01a2779483d6e089da8b3943f81cff48c8bfd1bd7d0281bceb152e41a7f5acb7","name":"node_f70c92be150cb3f65f6bd904c8c161bfb0cea717bab0b24da63714de83e0872c8c369960ada1629607a1e166a19b6cfa887603e4868e7912ae5512744e8cc1c0","services":["streamer"],"enable_msg_events":true,"port":62993},"up":true}},{"node":{"info":{"id":"d563716fbe2068cc940f7b12dc2bacb345c95f01e78e3b1f0105a441f300fdb00cc72e677aec102360fb904b63055d8581555f5b74b8f2392706569d8357c53f","name":"node_d563716fbe2068cc940f7b12dc2bacb345c95f01e78e3b1f0105a441f300fdb00cc72e677aec102360fb904b63055d8581555f5b74b8f2392706569d8357c53f","enode":"enode://d563716fbe2068cc940f7b12dc2bacb345c95f01e78e3b1f0105a441f300fdb00cc72e677aec102360fb904b63055d8581555f5b74b8f2392706569d8357c53f@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"8D9Hv49iQcvah48wF4PjDKwzPozqPWv5vCvjt/ws8cM=","hive":"\n=========================================================================\nTue Apr 10 09:55:59 UTC 2018 KΛÐΞMLIΛ hive: queen's address: f03f47\npopulation: 12 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 2f44 5cdc 51db 72f7 | 37 0d48 (0) 1087 (0) 1464 (0) 1be4 (0)\n001 1 b4be | 10 9dc2 (0) 9f2d (0) 9ecf (0) 8387 (0)\n002 2 dbc5 d10e | 11 d10e (0) dbc5 (0) d8d8 (0) de9e (0)\n003 2 e5ee e3c2 | 2 e5ee (0) e3c2 (0)\n004 1 fbbe | 1 fbbe (0)\n005 0 | 0\n006 0 | 0\n007 0 | 0\n============ DEPTH: 8 ==========================================\n008 1 f0ee | 1 f0ee (0)\n009 1 f066 | 1 f066 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"d563716fbe2068cc940f7b12dc2bacb345c95f01e78e3b1f0105a441f300fdb00cc72e677aec102360fb904b63055d8581555f5b74b8f2392706569d8357c53f","private_key":"2954d35fce94938f074043b9f9dd87157a6730bdd8e3a1b6f19b8a55ad1505df","name":"node_d563716fbe2068cc940f7b12dc2bacb345c95f01e78e3b1f0105a441f300fdb00cc72e677aec102360fb904b63055d8581555f5b74b8f2392706569d8357c53f","services":["streamer"],"enable_msg_events":true,"port":62994},"up":true}},{"node":{"info":{"id":"46bb2acc087482d40ab2ccbb387723158411ff4931423414e4d09891be8a31d11929e939e4be94b0cc355c49883e1835785ba1955d865f78748c2a0a2f6eee0a","name":"node_46bb2acc087482d40ab2ccbb387723158411ff4931423414e4d09891be8a31d11929e939e4be94b0cc355c49883e1835785ba1955d865f78748c2a0a2f6eee0a","enode":"enode://46bb2acc087482d40ab2ccbb387723158411ff4931423414e4d09891be8a31d11929e939e4be94b0cc355c49883e1835785ba1955d865f78748c2a0a2f6eee0a@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"tL7oBUs7e8PvB0iTdgJpkXOYOnZIFOhfFzkW/XDx4+0=","hive":"\n=========================================================================\nTue Apr 10 09:55:59 UTC 2018 KΛÐΞMLIΛ hive: queen's address: b4bee8\npopulation: 18 (62), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 7 1087 0d48 36c2 23e4 | 36 0d48 (0) 1464 (0) 1087 (0) 1be4 (0)\n001 4 cfa6 c678 f0ee f03f | 17 d10e (0) dbc5 (0) d8d8 (0) de9e (0)\n002 2 9dc2 8387 | 4 9f2d (0) 9ecf (0) 9dc2 (0) 8387 (0)\n003 2 ada8 a070 | 2 ada8 (0) a070 (0)\n============ DEPTH: 4 ==========================================\n004 3 be9f be69 bfa0 | 3 be69 (0) be9f (0) bfa0 (0)\n005 0 | 0\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"46bb2acc087482d40ab2ccbb387723158411ff4931423414e4d09891be8a31d11929e939e4be94b0cc355c49883e1835785ba1955d865f78748c2a0a2f6eee0a","private_key":"6f87c529d5b17354bd3ba6b59d6ff3a0f71550a41d949d702e27f50957cfc3ba","name":"node_46bb2acc087482d40ab2ccbb387723158411ff4931423414e4d09891be8a31d11929e939e4be94b0cc355c49883e1835785ba1955d865f78748c2a0a2f6eee0a","services":["streamer"],"enable_msg_events":true,"port":62995},"up":true}},{"node":{"info":{"id":"8da75cb4e63d968a7999ca4b49572b5ae592a91fa442d44bb7c42fb4b174a365e1affa1dbc45b2a0406444505f178100768e7783831f2886d53e7d1b8a3a7291","name":"node_8da75cb4e63d968a7999ca4b49572b5ae592a91fa442d44bb7c42fb4b174a365e1affa1dbc45b2a0406444505f178100768e7783831f2886d53e7d1b8a3a7291","enode":"enode://8da75cb4e63d968a7999ca4b49572b5ae592a91fa442d44bb7c42fb4b174a365e1affa1dbc45b2a0406444505f178100768e7783831f2886d53e7d1b8a3a7291@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"xnhkPFJJ65A4Wq0gHWdW+fNkAkk41Mn1n0qlHWTUi9c=","hive":"\n=========================================================================\nTue Apr 10 09:55:59 UTC 2018 KΛÐΞMLIΛ hive: queen's address: c67864\npopulation: 11 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 1be4 0d48 | 37 0d48 (0) 1464 (0) 1087 (0) 1be4 (0)\n001 2 b4be bfa0 | 10 9f2d (0) 9ecf (0) 9dc2 (0) 8387 (0)\n002 1 f0ee | 6 e5ee (0) e3c2 (0) fbbe (0) f0ee (0)\n003 2 d10e d8d8 | 6 d10e (0) dbc5 (0) d8d8 (0) de9e (0)\n004 2 cfa6 ce61 | 2 ce61 (0) cfa6 (0)\n============ DEPTH: 5 ==========================================\n005 1 c0f0 | 1 c0f0 (0)\n006 0 | 0\n007 0 | 0\n008 1 c6c4 | 1 c6c4 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"8da75cb4e63d968a7999ca4b49572b5ae592a91fa442d44bb7c42fb4b174a365e1affa1dbc45b2a0406444505f178100768e7783831f2886d53e7d1b8a3a7291","private_key":"ea386dc625e681a5d5d7c4e8ede4b3ffb8f2f13061c65acdde2750e2a19ef417","name":"node_8da75cb4e63d968a7999ca4b49572b5ae592a91fa442d44bb7c42fb4b174a365e1affa1dbc45b2a0406444505f178100768e7783831f2886d53e7d1b8a3a7291","services":["streamer"],"enable_msg_events":true,"port":62996},"up":true}},{"node":{"info":{"id":"6d1af44ab259cc080a14c07bf5efabfd70cb847fe338f016c00138c84bddf6a6ce94047d1bffcfc7e9bc772dd7a080468a84655d5351d0056f97f13358b91547","name":"node_6d1af44ab259cc080a14c07bf5efabfd70cb847fe338f016c00138c84bddf6a6ce94047d1bffcfc7e9bc772dd7a080468a84655d5351d0056f97f13358b91547","enode":"enode://6d1af44ab259cc080a14c07bf5efabfd70cb847fe338f016c00138c84bddf6a6ce94047d1bffcfc7e9bc772dd7a080468a84655d5351d0056f97f13358b91547@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"v6CgKBbaKbQCFfs8Jt6TYFBeTGn8pVCGMk8ONd50hqU=","hive":"\n=========================================================================\nTue Apr 10 09:55:59 UTC 2018 KΛÐΞMLIΛ hive: queen's address: bfa0a0\npopulation: 13 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 4390 1be4 0d48 | 37 0d48 (0) 1087 (0) 1464 (0) 1be4 (0)\n001 2 c6c4 c678 | 17 e5ee (0) e3c2 (0) fbbe (0) f0ee (0)\n002 3 9ecf 9dc2 8387 | 4 9f2d (0) 9ecf (0) 9dc2 (0) 8387 (0)\n003 2 ada8 a070 | 2 ada8 (0) a070 (0)\n004 1 b4be | 1 b4be (0)\n005 0 | 0\n006 0 | 0\n============ DEPTH: 7 ==========================================\n007 2 be9f be69 | 2 be9f (0) be69 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"6d1af44ab259cc080a14c07bf5efabfd70cb847fe338f016c00138c84bddf6a6ce94047d1bffcfc7e9bc772dd7a080468a84655d5351d0056f97f13358b91547","private_key":"e9b9261c569da5418d3aeabf28dff1faada23ae1a3a1552035aefe56bdf3136d","name":"node_6d1af44ab259cc080a14c07bf5efabfd70cb847fe338f016c00138c84bddf6a6ce94047d1bffcfc7e9bc772dd7a080468a84655d5351d0056f97f13358b91547","services":["streamer"],"enable_msg_events":true,"port":62997},"up":true}},{"node":{"info":{"id":"0dcef49b94fdcff024d706030fd4f513d0c6ad5f00b06a8b67abc454bbe5c2c74e939d491c0700e47ecee5cd7c7084603f62e626c34b454868b8f22d8c2dfb10","name":"node_0dcef49b94fdcff024d706030fd4f513d0c6ad5f00b06a8b67abc454bbe5c2c74e939d491c0700e47ecee5cd7c7084603f62e626c34b454868b8f22d8c2dfb10","enode":"enode://0dcef49b94fdcff024d706030fd4f513d0c6ad5f00b06a8b67abc454bbe5c2c74e939d491c0700e47ecee5cd7c7084603f62e626c34b454868b8f22d8c2dfb10@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"xsR58cg/UVjrd9V+YyHV7QYpZIcHdfUSVEYQEMiILBA=","hive":"\n=========================================================================\nTue Apr 10 09:55:59 UTC 2018 KΛÐΞMLIΛ hive: queen's address: c6c479\npopulation: 11 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 2d83 | 37 44b1 (0) 4390 (0) 5d05 (0) 5cdc (0)\n001 1 bfa0 | 10 9dc2 (0) 9f2d (0) 9ecf (0) 8387 (0)\n002 2 e5ee e3c2 | 6 e5ee (0) e3c2 (0) f0ee (0) f066 (0)\n003 3 d10e df9a d8d8 | 6 d10e (0) dbc5 (0) d8d8 (0) de9e (0)\n004 2 ce61 cfa6 | 2 cfa6 (0) ce61 (0)\n============ DEPTH: 5 ==========================================\n005 1 c0f0 | 1 c0f0 (0)\n006 0 | 0\n007 0 | 0\n008 1 c678 | 1 c678 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"0dcef49b94fdcff024d706030fd4f513d0c6ad5f00b06a8b67abc454bbe5c2c74e939d491c0700e47ecee5cd7c7084603f62e626c34b454868b8f22d8c2dfb10","private_key":"19334395c71250dd3eeeef4eb4032e2769839d57cd6080f2f51e1de3630789fe","name":"node_0dcef49b94fdcff024d706030fd4f513d0c6ad5f00b06a8b67abc454bbe5c2c74e939d491c0700e47ecee5cd7c7084603f62e626c34b454868b8f22d8c2dfb10","services":["streamer"],"enable_msg_events":true,"port":62998},"up":true}},{"node":{"info":{"id":"e7d4478b412ef497741943736946a3b0679d21ae0c4cbdde6809c7236dcf1a40291088d872e469f06da19ed4ef77b9844aee7066c40fcd45b0931aff847de1d7","name":"node_e7d4478b412ef497741943736946a3b0679d21ae0c4cbdde6809c7236dcf1a40291088d872e469f06da19ed4ef77b9844aee7066c40fcd45b0931aff847de1d7","enode":"enode://e7d4478b412ef497741943736946a3b0679d21ae0c4cbdde6809c7236dcf1a40291088d872e469f06da19ed4ef77b9844aee7066c40fcd45b0931aff847de1d7@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"LYMfeMfWcOTh8ZpHyA7C3xRNohD/OqoAymxJkOTaCSI=","hive":"\n=========================================================================\nTue Apr 10 09:55:59 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 2d831f\npopulation: 11 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 fbbe c6c4 | 27 9dc2 (0) 9f2d (0) 9ecf (0) 8387 (0)\n001 1 44b1 | 19 44b1 (0) 4390 (0) 5d05 (0) 5cdc (0)\n002 2 1be4 1464 | 5 1087 (0) 1464 (0) 1be4 (0) 1abc (0)\n003 3 3c38 36c2 30d8 | 9 3ea2 (0) 3ff4 (0) 3c38 (0) 3c93 (0)\n004 1 23e4 | 1 23e4 (0)\n============ DEPTH: 5 ==========================================\n005 1 2907 | 1 2907 (0)\n006 1 2f44 | 1 2f44 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"e7d4478b412ef497741943736946a3b0679d21ae0c4cbdde6809c7236dcf1a40291088d872e469f06da19ed4ef77b9844aee7066c40fcd45b0931aff847de1d7","private_key":"d587a8503da404e7a74e24d731daf63b9585ae41b555035979da013ab723b4b8","name":"node_e7d4478b412ef497741943736946a3b0679d21ae0c4cbdde6809c7236dcf1a40291088d872e469f06da19ed4ef77b9844aee7066c40fcd45b0931aff847de1d7","services":["streamer"],"enable_msg_events":true,"port":62999},"up":true}},{"node":{"info":{"id":"7722d7d06c66afb0642d5f9ae0b22ed812c632f2d62ce64315da40eb003feb3fae1b337c10df21d297beabe51b3879f2c0a725f08ee78a8e09c75f86bd0e2092","name":"node_7722d7d06c66afb0642d5f9ae0b22ed812c632f2d62ce64315da40eb003feb3fae1b337c10df21d297beabe51b3879f2c0a725f08ee78a8e09c75f86bd0e2092","enode":"enode://7722d7d06c66afb0642d5f9ae0b22ed812c632f2d62ce64315da40eb003feb3fae1b337c10df21d297beabe51b3879f2c0a725f08ee78a8e09c75f86bd0e2092@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"+74UEJ3E+oJR6FKhgfNmO0JFyTtzf6nEkhpT7ZlJAZ0=","hive":"\n=========================================================================\nTue Apr 10 09:55:59 UTC 2018 KΛÐΞMLIΛ hive: queen's address: fbbe14\npopulation: 17 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 5cdc 2d83 30d8 | 37 44b1 (0) 4390 (0) 5d05 (0) 5cdc (0)\n001 3 ada8 9f2d 9dc2 | 10 9dc2 (0) 9f2d (0) 9ecf (0) 8387 (0)\n002 6 de9e dfe3 df9a cfa6 | 11 d10e (0) dbc5 (0) d8d8 (0) de9e (0)\n003 2 e5ee e3c2 | 2 e5ee (0) e3c2 (0)\n============ DEPTH: 4 ==========================================\n004 3 f0ee f066 f03f | 3 f0ee (0) f066 (0) f03f (0)\n005 0 | 0\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"7722d7d06c66afb0642d5f9ae0b22ed812c632f2d62ce64315da40eb003feb3fae1b337c10df21d297beabe51b3879f2c0a725f08ee78a8e09c75f86bd0e2092","private_key":"724511e7e57416a6b4627079b0b9079fb4fd5649dd018d7f3a64dbf6a1dd9adc","name":"node_7722d7d06c66afb0642d5f9ae0b22ed812c632f2d62ce64315da40eb003feb3fae1b337c10df21d297beabe51b3879f2c0a725f08ee78a8e09c75f86bd0e2092","services":["streamer"],"enable_msg_events":true,"port":63000},"up":true}},{"node":{"info":{"id":"e479930845e1dac2d5908894548cc06c132fc5820810c6f46d9adc2bc252dd40b64642a3b2005ad3688d2637c43967f570bd153db9ee6742e1b23dbfb72537fa","name":"node_e479930845e1dac2d5908894548cc06c132fc5820810c6f46d9adc2bc252dd40b64642a3b2005ad3688d2637c43967f570bd153db9ee6742e1b23dbfb72537fa","enode":"enode://e479930845e1dac2d5908894548cc06c132fc5820810c6f46d9adc2bc252dd40b64642a3b2005ad3688d2637c43967f570bd153db9ee6742e1b23dbfb72537fa@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"MNgHcq0i14+KTpSKBmd7Vnaq24qcBA8/+1mn5gjgkp4=","hive":"\n=========================================================================\nTue Apr 10 09:55:59 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 30d807\npopulation: 11 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 fbbe | 27 8387 (0) 9dc2 (0) 9f2d (0) 9ecf (0)\n001 1 634c | 19 5d05 (0) 5cdc (0) 5c3c (0) 51db (0)\n002 1 1abc | 5 1087 (0) 1464 (0) 1be4 (0) 1abc (0)\n003 1 2d83 | 4 23e4 (0) 2907 (0) 2f44 (0) 2d83 (0)\n004 3 3ff4 3c38 3c93 | 4 3ea2 (0) 3ff4 (0) 3c38 (0) 3c93 (0)\n============ DEPTH: 5 ==========================================\n005 3 358e 37de 36c2 | 3 358e (0) 37de (0) 36c2 (0)\n006 1 332f | 1 332f (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"e479930845e1dac2d5908894548cc06c132fc5820810c6f46d9adc2bc252dd40b64642a3b2005ad3688d2637c43967f570bd153db9ee6742e1b23dbfb72537fa","private_key":"922f3ca85ccc577429654b566f1561a301bbad054e4f3a8f312db841329899c9","name":"node_e479930845e1dac2d5908894548cc06c132fc5820810c6f46d9adc2bc252dd40b64642a3b2005ad3688d2637c43967f570bd153db9ee6742e1b23dbfb72537fa","services":["streamer"],"enable_msg_events":true,"port":63001},"up":true}},{"node":{"info":{"id":"61b32cded1b5ea3e2ca545a55c84251daaaacf51e6fed98fbdf4c5b6b91a554081e1e577aaaaaa4f911780f92703c1d715695d86c1be641b0bd1794f4107c2be","name":"node_61b32cded1b5ea3e2ca545a55c84251daaaacf51e6fed98fbdf4c5b6b91a554081e1e577aaaaaa4f911780f92703c1d715695d86c1be641b0bd1794f4107c2be","enode":"enode://61b32cded1b5ea3e2ca545a55c84251daaaacf51e6fed98fbdf4c5b6b91a554081e1e577aaaaaa4f911780f92703c1d715695d86c1be641b0bd1794f4107c2be@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"Y0wlYlROCXlTDMTbqRjISfJPhch4E+WSxU4fbY1zu28=","hive":"\n=========================================================================\nTue Apr 10 09:55:59 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 634c25\npopulation: 12 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 9ecf a070 | 27 ada8 (0) a070 (0) be69 (0) be9f (0)\n001 1 30d8 | 18 1087 (0) 1464 (0) 1abc (0) 1be4 (0)\n002 3 56ac 544a 4390 | 9 5d05 (0) 5cdc (0) 5c3c (0) 51db (0)\n003 2 7768 7a1f | 5 7693 (0) 7768 (0) 72f7 (0) 7a56 (0)\n004 2 68d4 6c4b | 2 68d4 (0) 6c4b (0)\n============ DEPTH: 5 ==========================================\n005 1 6623 | 1 6623 (0)\n006 1 61c2 | 1 61c2 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"61b32cded1b5ea3e2ca545a55c84251daaaacf51e6fed98fbdf4c5b6b91a554081e1e577aaaaaa4f911780f92703c1d715695d86c1be641b0bd1794f4107c2be","private_key":"c94a8e8e535d7431b0610ebfaa70d76c37bf6fbcaaa83ec4be0bed5527780670","name":"node_61b32cded1b5ea3e2ca545a55c84251daaaacf51e6fed98fbdf4c5b6b91a554081e1e577aaaaaa4f911780f92703c1d715695d86c1be641b0bd1794f4107c2be","services":["streamer"],"enable_msg_events":true,"port":63002},"up":true}},{"node":{"info":{"id":"9e51eb48f59886e70eb8d02e1c0c4423de3f0ce79c7a62bfd91bc2048cf643f40a91e2d2a1a8a19a9e4ba4a96aed0965aefcd941c068208abe8bf5029eb27d55","name":"node_9e51eb48f59886e70eb8d02e1c0c4423de3f0ce79c7a62bfd91bc2048cf643f40a91e2d2a1a8a19a9e4ba4a96aed0965aefcd941c068208abe8bf5029eb27d55","enode":"enode://9e51eb48f59886e70eb8d02e1c0c4423de3f0ce79c7a62bfd91bc2048cf643f40a91e2d2a1a8a19a9e4ba4a96aed0965aefcd941c068208abe8bf5029eb27d55@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"eh8D3CbvIaW9FnPrhBiveny8sqsWVIguvc2i0eatSDY=","hive":"\n=========================================================================\nTue Apr 10 09:55:59 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 7a1f03\npopulation: 12 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 b4be d8d8 | 27 bfa0 (0) be9f (0) be69 (0) b4be (0)\n001 2 3ff4 36c2 | 18 1087 (0) 1464 (0) 1abc (0) 1be4 (0)\n002 1 5c3c | 9 5d05 (0) 5cdc (0) 5c3c (0) 51db (0)\n003 3 6c4b 61c2 634c | 5 68d4 (0) 6c4b (0) 6623 (0) 61c2 (0)\n============ DEPTH: 4 ==========================================\n004 3 72f7 7693 7768 | 3 72f7 (0) 7693 (0) 7768 (0)\n005 0 | 0\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 1 7a56 | 1 7a56 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"9e51eb48f59886e70eb8d02e1c0c4423de3f0ce79c7a62bfd91bc2048cf643f40a91e2d2a1a8a19a9e4ba4a96aed0965aefcd941c068208abe8bf5029eb27d55","private_key":"7a1378d2cad0ac18e37694b3ec5c08580aa1887916e98030c66accf6197f615b","name":"node_9e51eb48f59886e70eb8d02e1c0c4423de3f0ce79c7a62bfd91bc2048cf643f40a91e2d2a1a8a19a9e4ba4a96aed0965aefcd941c068208abe8bf5029eb27d55","services":["streamer"],"enable_msg_events":true,"port":63003},"up":true}},{"node":{"info":{"id":"7a1f97c41c9efd7a2903af78f72d02cfff3631dc6260d3ceb2364c2a8e06965710e8feae6aa9f99b48b2475da10b2f9581c76d47b4cd2bfee09c43dcb5e3e5d9","name":"node_7a1f97c41c9efd7a2903af78f72d02cfff3631dc6260d3ceb2364c2a8e06965710e8feae6aa9f99b48b2475da10b2f9581c76d47b4cd2bfee09c43dcb5e3e5d9","enode":"enode://7a1f97c41c9efd7a2903af78f72d02cfff3631dc6260d3ceb2364c2a8e06965710e8feae6aa9f99b48b2475da10b2f9581c76d47b4cd2bfee09c43dcb5e3e5d9@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"NsKMAje+ayExKARSwxE6/8rij2xwZoEajh7hoKAd7MM=","hive":"\n=========================================================================\nTue Apr 10 09:55:59 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 36c28c\npopulation: 14 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 b4be be9f | 27 bfa0 (0) be69 (0) be9f (0) b4be (0)\n001 2 7a1f 6c4b | 19 5d05 (0) 5c3c (0) 5cdc (0) 51db (0)\n002 1 1abc | 5 0d48 (0) 1abc (0) 1be4 (0) 1464 (0)\n003 2 2f44 2d83 | 4 2f44 (0) 2d83 (0) 2907 (0) 23e4 (0)\n004 3 3ff4 3c38 3c93 | 4 3ea2 (0) 3ff4 (0) 3c38 (0) 3c93 (0)\n005 2 30d8 332f | 2 30d8 (0) 332f (0)\n============ DEPTH: 6 ==========================================\n006 1 358e | 1 358e (0)\n007 1 37de | 1 37de (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"7a1f97c41c9efd7a2903af78f72d02cfff3631dc6260d3ceb2364c2a8e06965710e8feae6aa9f99b48b2475da10b2f9581c76d47b4cd2bfee09c43dcb5e3e5d9","private_key":"6e834fb9046bc38179a4c8be1cd4c2c540df1f73aa208e9794701234202211ca","name":"node_7a1f97c41c9efd7a2903af78f72d02cfff3631dc6260d3ceb2364c2a8e06965710e8feae6aa9f99b48b2475da10b2f9581c76d47b4cd2bfee09c43dcb5e3e5d9","services":["streamer"],"enable_msg_events":true,"port":63004},"up":true}},{"node":{"info":{"id":"7a45fa46f161fae3ef9013e9ab81145f4a76fa6ae22160424d6dc111acbd477ce43d4c10db89cb7451c97ea1fbd78428997d01fd17e1851f8b559b404ede6da7","name":"node_7a45fa46f161fae3ef9013e9ab81145f4a76fa6ae22160424d6dc111acbd477ce43d4c10db89cb7451c97ea1fbd78428997d01fd17e1851f8b559b404ede6da7","enode":"enode://7a45fa46f161fae3ef9013e9ab81145f4a76fa6ae22160424d6dc111acbd477ce43d4c10db89cb7451c97ea1fbd78428997d01fd17e1851f8b559b404ede6da7@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"bEvf5GUFJdXvwaTKjZLrvqM7GHe/rGllboGtu61PKGo=","hive":"\n=========================================================================\nTue Apr 10 09:55:59 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 6c4bdf\npopulation: 11 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 9ecf be9f b4be | 27 b4be (0) bfa0 (0) be69 (0) be9f (0)\n001 2 1087 36c2 | 18 0d48 (0) 1abc (0) 1be4 (0) 1464 (0)\n002 1 4390 | 9 5d05 (0) 5c3c (0) 5cdc (0) 51db (0)\n003 1 7a1f | 5 72f7 (0) 7693 (0) 7768 (0) 7a56 (0)\n============ DEPTH: 4 ==========================================\n004 3 6623 634c 61c2 | 3 6623 (0) 634c (0) 61c2 (0)\n005 1 68d4 | 1 68d4 (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"7a45fa46f161fae3ef9013e9ab81145f4a76fa6ae22160424d6dc111acbd477ce43d4c10db89cb7451c97ea1fbd78428997d01fd17e1851f8b559b404ede6da7","private_key":"819e80fcd487bf15502fff3d31651efcd9b5e7d5e18ca4d836ce53736bf23d11","name":"node_7a45fa46f161fae3ef9013e9ab81145f4a76fa6ae22160424d6dc111acbd477ce43d4c10db89cb7451c97ea1fbd78428997d01fd17e1851f8b559b404ede6da7","services":["streamer"],"enable_msg_events":true,"port":63005},"up":true}},{"node":{"info":{"id":"07138ce506125910af81bd1bae11c22bfab9a81e1e057cc3d84769475c5da9873eb3f11edc6aca83ef486bfb63eba15a6233676d29d93ac9e774f10cd42c8cbd","name":"node_07138ce506125910af81bd1bae11c22bfab9a81e1e057cc3d84769475c5da9873eb3f11edc6aca83ef486bfb63eba15a6233676d29d93ac9e774f10cd42c8cbd","enode":"enode://07138ce506125910af81bd1bae11c22bfab9a81e1e057cc3d84769475c5da9873eb3f11edc6aca83ef486bfb63eba15a6233676d29d93ac9e774f10cd42c8cbd@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"EIdJW/BOaWclf4S45d4ITiAAuddIIW4xyfM/ycrttxU=","hive":"\n=========================================================================\nTue Apr 10 09:55:59 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 108749\npopulation: 7 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 b4be | 27 b4be (0) bfa0 (0) be69 (0) be9f (0)\n001 1 6c4b | 19 5d05 (0) 5c3c (0) 5cdc (0) 51db (0)\n002 1 23e4 | 13 3ea2 (0) 3ff4 (0) 3c38 (0) 3c93 (0)\n003 1 0d48 | 1 0d48 (0)\n============ DEPTH: 4 ==========================================\n004 2 1abc 1be4 | 2 1abc (0) 1be4 (0)\n005 1 1464 | 1 1464 (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"07138ce506125910af81bd1bae11c22bfab9a81e1e057cc3d84769475c5da9873eb3f11edc6aca83ef486bfb63eba15a6233676d29d93ac9e774f10cd42c8cbd","private_key":"c2fff99bd9d70ab2149a1ace8ad0dc26b4b78cbfd60fe9215e0f69885e0cede6","name":"node_07138ce506125910af81bd1bae11c22bfab9a81e1e057cc3d84769475c5da9873eb3f11edc6aca83ef486bfb63eba15a6233676d29d93ac9e774f10cd42c8cbd","services":["streamer"],"enable_msg_events":true,"port":63006},"up":true}},{"node":{"info":{"id":"f360c6599a0911337c7b96365fda1b2f64890bdb4483bb7e86bca15484f24c4efc0d1f6f56aa0c4fa5c205e6c1dbbf20d2ca3c2f8734f703fe6d672fa76a0d45","name":"node_f360c6599a0911337c7b96365fda1b2f64890bdb4483bb7e86bca15484f24c4efc0d1f6f56aa0c4fa5c205e6c1dbbf20d2ca3c2f8734f703fe6d672fa76a0d45","enode":"enode://f360c6599a0911337c7b96365fda1b2f64890bdb4483bb7e86bca15484f24c4efc0d1f6f56aa0c4fa5c205e6c1dbbf20d2ca3c2f8734f703fe6d672fa76a0d45@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"I+TxjTAralRVMLieygB8FBx1HNzeRxvDN4v3L9aLkcY=","hive":"\n=========================================================================\nTue Apr 10 09:55:59 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 23e4f1\npopulation: 12 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 b4be | 27 b4be (0) bfa0 (0) be69 (0) be9f (0)\n001 1 4390 | 19 72f7 (0) 7693 (0) 7768 (0) 7a56 (0)\n002 1 1087 | 5 0d48 (0) 1abc (0) 1be4 (0) 1464 (0)\n003 6 332f 358e 3ea2 3ff4 | 9 3ea2 (0) 3ff4 (0) 3c38 (0) 3c93 (0)\n============ DEPTH: 4 ==========================================\n004 3 2907 2f44 2d83 | 3 2d83 (0) 2f44 (0) 2907 (0)\n005 0 | 0\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"f360c6599a0911337c7b96365fda1b2f64890bdb4483bb7e86bca15484f24c4efc0d1f6f56aa0c4fa5c205e6c1dbbf20d2ca3c2f8734f703fe6d672fa76a0d45","private_key":"5d8862df181e186646d6fa8accaceed89b18a384ce5e63de34ecd1bd80d7f0c9","name":"node_f360c6599a0911337c7b96365fda1b2f64890bdb4483bb7e86bca15484f24c4efc0d1f6f56aa0c4fa5c205e6c1dbbf20d2ca3c2f8734f703fe6d672fa76a0d45","services":["streamer"],"enable_msg_events":true,"port":63007},"up":true}},{"node":{"info":{"id":"f5272b71c228eb14b9e0e221deefc0a91353a5f17d01475f57fad54bb8e50e375f58019c7200a9ca45b0f1da6538708c61242e478d917499871df7a9d5857f1a","name":"node_f5272b71c228eb14b9e0e221deefc0a91353a5f17d01475f57fad54bb8e50e375f58019c7200a9ca45b0f1da6538708c61242e478d917499871df7a9d5857f1a","enode":"enode://f5272b71c228eb14b9e0e221deefc0a91353a5f17d01475f57fad54bb8e50e375f58019c7200a9ca45b0f1da6538708c61242e478d917499871df7a9d5857f1a@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"Q5ALKghAl6Dd+L9NA3ViT3Mb0UyFMAAHyHJpmGoS6zs=","hive":"\n=========================================================================\nTue Apr 10 09:55:59 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 43900b\npopulation: 16 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 bfa0 | 27 bfa0 (0) be69 (0) be9f (0) b4be (0)\n001 2 0d48 23e4 | 18 0d48 (0) 1abc (0) 1be4 (0) 1464 (0)\n002 5 72f7 61c2 634c 68d4 | 10 7a56 (0) 7a1f (0) 72f7 (0) 7693 (0)\n============ DEPTH: 3 ==========================================\n003 7 5c3c 5cdc 5d05 51db | 7 5d05 (0) 5cdc (0) 5c3c (0) 51db (0)\n004 0 | 0\n005 1 44b1 | 1 44b1 (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"f5272b71c228eb14b9e0e221deefc0a91353a5f17d01475f57fad54bb8e50e375f58019c7200a9ca45b0f1da6538708c61242e478d917499871df7a9d5857f1a","private_key":"411b4485e7f793c1db7387d9e8f179d02d939de2702166248953f8f0813cb5f0","name":"node_f5272b71c228eb14b9e0e221deefc0a91353a5f17d01475f57fad54bb8e50e375f58019c7200a9ca45b0f1da6538708c61242e478d917499871df7a9d5857f1a","services":["streamer"],"enable_msg_events":true,"port":63008},"up":true}},{"node":{"info":{"id":"e53cfad611bc38a1090d28e4cc58e4738ccaa83a00bf5447cd30ec70e492dea5811b67e79b9ca8856e79801741a675c6f54eb7a1c39e95ab735164855eae0fb7","name":"node_e53cfad611bc38a1090d28e4cc58e4738ccaa83a00bf5447cd30ec70e492dea5811b67e79b9ca8856e79801741a675c6f54eb7a1c39e95ab735164855eae0fb7","enode":"enode://e53cfad611bc38a1090d28e4cc58e4738ccaa83a00bf5447cd30ec70e492dea5811b67e79b9ca8856e79801741a675c6f54eb7a1c39e95ab735164855eae0fb7@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"DUhHfjPXz8SnZgBI5LHs6fN+l1npbm8fR6ht4JGw7pc=","hive":"\n=========================================================================\nTue Apr 10 09:55:59 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 0d4847\npopulation: 12 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 b4be bfa0 c678 | 27 b4be (0) bfa0 (0) be69 (0) be9f (0)\n001 3 4390 7a56 7768 | 19 5d05 (0) 5cdc (0) 5c3c (0) 51db (0)\n002 2 332f 2907 | 13 3ea2 (0) 3ff4 (0) 3c38 (0) 3c93 (0)\n============ DEPTH: 3 ==========================================\n003 4 1abc 1be4 1087 1464 | 4 1087 (0) 1464 (0) 1abc (0) 1be4 (0)\n004 0 | 0\n005 0 | 0\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"e53cfad611bc38a1090d28e4cc58e4738ccaa83a00bf5447cd30ec70e492dea5811b67e79b9ca8856e79801741a675c6f54eb7a1c39e95ab735164855eae0fb7","private_key":"9b1297e565c13eeb81e2b19c31f635253081d34a65eb1ebf889f30635e4eccea","name":"node_e53cfad611bc38a1090d28e4cc58e4738ccaa83a00bf5447cd30ec70e492dea5811b67e79b9ca8856e79801741a675c6f54eb7a1c39e95ab735164855eae0fb7","services":["streamer"],"enable_msg_events":true,"port":63009},"up":true}},{"node":{"info":{"id":"4f1a219f31e135208bf4caa314a14d8d48a5682941793431539efb5666b06bb5e3e9cb29b019ca414fb32961460556f2d99a04b12dc8ecbf05f43efe108803f5","name":"node_4f1a219f31e135208bf4caa314a14d8d48a5682941793431539efb5666b06bb5e3e9cb29b019ca414fb32961460556f2d99a04b12dc8ecbf05f43efe108803f5","enode":"enode://4f1a219f31e135208bf4caa314a14d8d48a5682941793431539efb5666b06bb5e3e9cb29b019ca414fb32961460556f2d99a04b12dc8ecbf05f43efe108803f5@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"d2h9nkeKUlVWdPEqplStkxo+6Dkguc3I/swDZT7X44Y=","hive":"\n=========================================================================\nTue Apr 10 09:55:59 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 77687d\npopulation: 10 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 b4be be9f | 27 b4be (0) bfa0 (0) be69 (0) be9f (0)\n001 1 0d48 | 18 3ea2 (0) 3ff4 (0) 3c38 (0) 3c93 (0)\n002 1 5d05 | 9 5d05 (0) 5c3c (0) 5cdc (0) 51db (0)\n003 2 634c 61c2 | 5 68d4 (0) 6c4b (0) 6623 (0) 634c (0)\n004 2 7a56 7a1f | 2 7a56 (0) 7a1f (0)\n============ DEPTH: 5 ==========================================\n005 1 72f7 | 1 72f7 (0)\n006 0 | 0\n007 1 7693 | 1 7693 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"4f1a219f31e135208bf4caa314a14d8d48a5682941793431539efb5666b06bb5e3e9cb29b019ca414fb32961460556f2d99a04b12dc8ecbf05f43efe108803f5","private_key":"eb698ae5696bf1cef4f4e6cb8ef2eb5e79cd298fcb55e0449bbaab6d048e09b6","name":"node_4f1a219f31e135208bf4caa314a14d8d48a5682941793431539efb5666b06bb5e3e9cb29b019ca414fb32961460556f2d99a04b12dc8ecbf05f43efe108803f5","services":["streamer"],"enable_msg_events":true,"port":63010},"up":true}},{"node":{"info":{"id":"25c64a52c298035be2184243082b5eba8a3a5d55c5334cea76e177d722945c8bf014a4ce9ef2ed76dc17a44234c97697337c6e001261533e72cc8266ee0e2fe4","name":"node_25c64a52c298035be2184243082b5eba8a3a5d55c5334cea76e177d722945c8bf014a4ce9ef2ed76dc17a44234c97697337c6e001261533e72cc8266ee0e2fe4","enode":"enode://25c64a52c298035be2184243082b5eba8a3a5d55c5334cea76e177d722945c8bf014a4ce9ef2ed76dc17a44234c97697337c6e001261533e72cc8266ee0e2fe4@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"YcJJgLnvTuf8M8UTEPmBqOdOQnZQmlRaP0cTcAgtq0s=","hive":"\n=========================================================================\nTue Apr 10 09:55:59 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 61c249\npopulation: 12 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 a070 | 27 b4be (0) bfa0 (0) be69 (0) be9f (0)\n001 1 2907 | 18 1087 (0) 1464 (0) 1abc (0) 1be4 (0)\n002 3 44b1 4390 544a | 9 5d05 (0) 5c3c (0) 5cdc (0) 51db (0)\n003 3 7a56 7a1f 7768 | 5 7a56 (0) 7a1f (0) 72f7 (0) 7693 (0)\n004 2 68d4 6c4b | 2 68d4 (0) 6c4b (0)\n============ DEPTH: 5 ==========================================\n005 1 6623 | 1 6623 (0)\n006 1 634c | 1 634c (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"25c64a52c298035be2184243082b5eba8a3a5d55c5334cea76e177d722945c8bf014a4ce9ef2ed76dc17a44234c97697337c6e001261533e72cc8266ee0e2fe4","private_key":"cc474d341e32e674a1c1d607789df8bb6097ab392eace2d366da2496c5413cef","name":"node_25c64a52c298035be2184243082b5eba8a3a5d55c5334cea76e177d722945c8bf014a4ce9ef2ed76dc17a44234c97697337c6e001261533e72cc8266ee0e2fe4","services":["streamer"],"enable_msg_events":true,"port":63011},"up":true}},{"node":{"info":{"id":"1691538e4cc41441c18fc92969c0c59f51da063814e8c45311605405284293503ee1570722cc7ae12f9cd63b899afaf5b3e66ca012115996074e8aaa71fda48c","name":"node_1691538e4cc41441c18fc92969c0c59f51da063814e8c45311605405284293503ee1570722cc7ae12f9cd63b899afaf5b3e66ca012115996074e8aaa71fda48c","enode":"enode://1691538e4cc41441c18fc92969c0c59f51da063814e8c45311605405284293503ee1570722cc7ae12f9cd63b899afaf5b3e66ca012115996074e8aaa71fda48c@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"KQd90vSGm2n/w+1A6C5O8FEpLDRhiItfr3tMSxTUko8=","hive":"\n=========================================================================\nTue Apr 10 09:55:59 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 29077d\npopulation: 9 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 f066 | 27 d10e (0) d8d8 (0) dbc5 (0) de9e (0)\n001 1 61c2 | 19 51db (0) 544a (0) 56ac (0) 577b (0)\n002 2 1464 0d48 | 5 0d48 (0) 1087 (0) 1464 (0) 1abc (0)\n003 2 3ff4 3c93 | 9 3c38 (0) 3c93 (0) 3ff4 (0) 3ea2 (0)\n004 1 23e4 | 1 23e4 (0)\n============ DEPTH: 5 ==========================================\n005 2 2d83 2f44 | 2 2d83 (0) 2f44 (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"1691538e4cc41441c18fc92969c0c59f51da063814e8c45311605405284293503ee1570722cc7ae12f9cd63b899afaf5b3e66ca012115996074e8aaa71fda48c","private_key":"4ec4a7d75323558dd822f09ab9f992afd016604bc77aec05f89cfdae6f50611b","name":"node_1691538e4cc41441c18fc92969c0c59f51da063814e8c45311605405284293503ee1570722cc7ae12f9cd63b899afaf5b3e66ca012115996074e8aaa71fda48c","services":["streamer"],"enable_msg_events":true,"port":63012},"up":true}},{"node":{"info":{"id":"8e1a66c9029330c25b9abe95a11878f41cef1a32b567a931ffa781c2f70a1336efa03ba1a66dac0080304803c1239be443991a251f24d0e9c2e26aebeb5437f8","name":"node_8e1a66c9029330c25b9abe95a11878f41cef1a32b567a931ffa781c2f70a1336efa03ba1a66dac0080304803c1239be443991a251f24d0e9c2e26aebeb5437f8","enode":"enode://8e1a66c9029330c25b9abe95a11878f41cef1a32b567a931ffa781c2f70a1336efa03ba1a66dac0080304803c1239be443991a251f24d0e9c2e26aebeb5437f8@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"L0SSQpqy7NCAo2RRFTmQWH3iRY69lCH7mJ2OJ9SohCI=","hive":"\n=========================================================================\nTue Apr 10 09:55:59 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 2f4492\npopulation: 12 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 f03f f066 | 27 e5ee (0) e3c2 (0) f0ee (0) f03f (0)\n001 2 544a 577b | 19 51db (0) 544a (0) 56ac (0) 577b (0)\n002 2 1464 1be4 | 5 0d48 (0) 1087 (0) 1464 (0) 1abc (0)\n003 3 37de 36c2 3c93 | 9 3c38 (0) 3c93 (0) 3ff4 (0) 3ea2 (0)\n004 1 23e4 | 1 23e4 (0)\n============ DEPTH: 5 ==========================================\n005 1 2907 | 1 2907 (0)\n006 1 2d83 | 1 2d83 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"8e1a66c9029330c25b9abe95a11878f41cef1a32b567a931ffa781c2f70a1336efa03ba1a66dac0080304803c1239be443991a251f24d0e9c2e26aebeb5437f8","private_key":"b049d01349524a669db50fd817ef70811ea5cb5517adaa016f4ae426184188e8","name":"node_8e1a66c9029330c25b9abe95a11878f41cef1a32b567a931ffa781c2f70a1336efa03ba1a66dac0080304803c1239be443991a251f24d0e9c2e26aebeb5437f8","services":["streamer"],"enable_msg_events":true,"port":63013},"up":true}},{"node":{"info":{"id":"c8e9cc707ce2a278371d1b4f64714cdae425b7c3606d18af6588dacaca35c7a171a07629247af351e667d2ddd9e71598f862125c827cc869c463cf87e4daeed0","name":"node_c8e9cc707ce2a278371d1b4f64714cdae425b7c3606d18af6588dacaca35c7a171a07629247af351e667d2ddd9e71598f862125c827cc869c463cf87e4daeed0","enode":"enode://c8e9cc707ce2a278371d1b4f64714cdae425b7c3606d18af6588dacaca35c7a171a07629247af351e667d2ddd9e71598f862125c827cc869c463cf87e4daeed0@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"G+S6LwaOBgoKq6xEUJTx3Isi/h5VdcmN+Nh4OqPZUXc=","hive":"\n=========================================================================\nTue Apr 10 09:55:59 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 1be4ba\npopulation: 14 (61), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 bfa0 c678 f066 | 25 b4be (0) bfa0 (0) be69 (0) be9f (0)\n001 3 7693 5cdc 577b | 19 51db (0) 544a (0) 56ac (0) 577b (0)\n002 4 37de 3ea2 2d83 2f44 | 13 3c38 (0) 3c93 (0) 3ff4 (0) 3ea2 (0)\n003 1 0d48 | 1 0d48 (0)\n============ DEPTH: 4 ==========================================\n004 2 1087 1464 | 2 1087 (0) 1464 (0)\n005 0 | 0\n006 0 | 0\n007 1 1abc | 1 1abc (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"c8e9cc707ce2a278371d1b4f64714cdae425b7c3606d18af6588dacaca35c7a171a07629247af351e667d2ddd9e71598f862125c827cc869c463cf87e4daeed0","private_key":"9eb7b1e41bd77e46a9746723ab4367fcdb9950d5f99c32bb1efddc9b5c60daf7","name":"node_c8e9cc707ce2a278371d1b4f64714cdae425b7c3606d18af6588dacaca35c7a171a07629247af351e667d2ddd9e71598f862125c827cc869c463cf87e4daeed0","services":["streamer"],"enable_msg_events":true,"port":63014},"up":true}},{"node":{"info":{"id":"43b91c24dd7fd217a76f00ab97920e4223bd2ee085abe7ac34e915e8676400e1643d3bbb4a864c8a6df1298bf229cabd1bdc9879eafdcbcab064708e8266e88d","name":"node_43b91c24dd7fd217a76f00ab97920e4223bd2ee085abe7ac34e915e8676400e1643d3bbb4a864c8a6df1298bf229cabd1bdc9879eafdcbcab064708e8266e88d","enode":"enode://43b91c24dd7fd217a76f00ab97920e4223bd2ee085abe7ac34e915e8676400e1643d3bbb4a864c8a6df1298bf229cabd1bdc9879eafdcbcab064708e8266e88d@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"8GbV0xQlOocqsn35DYW6WCTaBgMvks6L8gAgthlx4Zk=","hive":"\n=========================================================================\nTue Apr 10 09:55:59 UTC 2018 KΛÐΞMLIΛ hive: queen's address: f066d5\npopulation: 17 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 7 51db 7a56 7693 2f44 | 37 51db (0) 544a (0) 56ac (0) 577b (0)\n001 2 ada8 be9f | 10 b4be (0) bfa0 (0) be69 (0) be9f (0)\n002 3 d10e cfa6 c0f0 | 11 d10e (0) d8d8 (0) dbc5 (0) de9e (0)\n003 2 e5ee e3c2 | 2 e5ee (0) e3c2 (0)\n004 1 fbbe | 1 fbbe (0)\n005 0 | 0\n006 0 | 0\n007 0 | 0\n============ DEPTH: 8 ==========================================\n008 1 f0ee | 1 f0ee (0)\n009 1 f03f | 1 f03f (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"43b91c24dd7fd217a76f00ab97920e4223bd2ee085abe7ac34e915e8676400e1643d3bbb4a864c8a6df1298bf229cabd1bdc9879eafdcbcab064708e8266e88d","private_key":"229b6c150e858a0e81d1c720a9697bda4c9f26e531d85db8837ca5d1a24ff8dd","name":"node_43b91c24dd7fd217a76f00ab97920e4223bd2ee085abe7ac34e915e8676400e1643d3bbb4a864c8a6df1298bf229cabd1bdc9879eafdcbcab064708e8266e88d","services":["streamer"],"enable_msg_events":true,"port":63015},"up":true}},{"node":{"info":{"id":"14136fa967f2d4825845ba4a43a5921d8fcf03f9c71c5595037e000b2ef6ff0a5eaad0980aea0a170cafda3529f982aea1107f58aa42485550c9480e86f5e9f3","name":"node_14136fa967f2d4825845ba4a43a5921d8fcf03f9c71c5595037e000b2ef6ff0a5eaad0980aea0a170cafda3529f982aea1107f58aa42485550c9480e86f5e9f3","enode":"enode://14136fa967f2d4825845ba4a43a5921d8fcf03f9c71c5595037e000b2ef6ff0a5eaad0980aea0a170cafda3529f982aea1107f58aa42485550c9480e86f5e9f3@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"My97YKH7ts0eJR3GjRCTt/C7BcHu/OXmHxJN/5RF8U0=","hive":"\n=========================================================================\nTue Apr 10 09:55:59 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 332f7b\npopulation: 14 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 f066 a070 | 27 d10e (0) d8d8 (0) dbc5 (0) de9e (0)\n001 1 577b | 19 51db (0) 544a (0) 56ac (0) 577b (0)\n002 3 0d48 1464 1abc | 5 0d48 (0) 1087 (0) 1464 (0) 1abc (0)\n003 1 23e4 | 4 23e4 (0) 2907 (0) 2d83 (0) 2f44 (0)\n004 3 3ff4 3c93 3c38 | 4 3c38 (0) 3c93 (0) 3ff4 (0) 3ea2 (0)\n============ DEPTH: 5 ==========================================\n005 3 37de 36c2 358e | 3 37de (0) 36c2 (0) 358e (0)\n006 1 30d8 | 1 30d8 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"14136fa967f2d4825845ba4a43a5921d8fcf03f9c71c5595037e000b2ef6ff0a5eaad0980aea0a170cafda3529f982aea1107f58aa42485550c9480e86f5e9f3","private_key":"ab42d800bd5b0bcaedd3009d4805e827ca6c41f54fb7fd38cc021f9c72bf3aed","name":"node_14136fa967f2d4825845ba4a43a5921d8fcf03f9c71c5595037e000b2ef6ff0a5eaad0980aea0a170cafda3529f982aea1107f58aa42485550c9480e86f5e9f3","services":["streamer"],"enable_msg_events":true,"port":63016},"up":true}},{"node":{"info":{"id":"39d0aa13a6d7e709c9b914cb16f007c3f16af40532afa47c8cf9abf6d604d4380883103c995ec696ca593c4dc9bf0290979b965c9c6ade7c616d3973c5f0b1f0","name":"node_39d0aa13a6d7e709c9b914cb16f007c3f16af40532afa47c8cf9abf6d604d4380883103c995ec696ca593c4dc9bf0290979b965c9c6ade7c616d3973c5f0b1f0","enode":"enode://39d0aa13a6d7e709c9b914cb16f007c3f16af40532afa47c8cf9abf6d604d4380883103c995ec696ca593c4dc9bf0290979b965c9c6ade7c616d3973c5f0b1f0@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"oHDEKVG1I1MfBly4N264ygxDG0c86evESj/Dg/H4eLM=","hive":"\n=========================================================================\nTue Apr 10 09:55:59 UTC 2018 KΛÐΞMLIΛ hive: queen's address: a070c4\npopulation: 11 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 634c 61c2 332f | 37 51db (0) 544a (0) 56ac (0) 577b (0)\n001 1 c0f0 | 17 d10e (0) d8d8 (0) dbc5 (0) de9e (0)\n002 2 9f2d 9ecf | 4 8387 (0) 9dc2 (0) 9f2d (0) 9ecf (0)\n============ DEPTH: 3 ==========================================\n003 4 b4be bfa0 be69 be9f | 4 b4be (0) bfa0 (0) be69 (0) be9f (0)\n004 1 ada8 | 1 ada8 (0)\n005 0 | 0\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"39d0aa13a6d7e709c9b914cb16f007c3f16af40532afa47c8cf9abf6d604d4380883103c995ec696ca593c4dc9bf0290979b965c9c6ade7c616d3973c5f0b1f0","private_key":"15e0330ce9f82833faa08bbacae92d3eff516eeb4bfd1be0b7d8ecc8a311d8a8","name":"node_39d0aa13a6d7e709c9b914cb16f007c3f16af40532afa47c8cf9abf6d604d4380883103c995ec696ca593c4dc9bf0290979b965c9c6ade7c616d3973c5f0b1f0","services":["streamer"],"enable_msg_events":true,"port":63017},"up":true}},{"node":{"info":{"id":"e73af1e2a834ee132564dd2e983c877b3ae230808d2b42da2ec91472eee6ee6595c439800ce980186b4b0d9a56b96babf747006c07b07513543eead8e102fff7","name":"node_e73af1e2a834ee132564dd2e983c877b3ae230808d2b42da2ec91472eee6ee6595c439800ce980186b4b0d9a56b96babf747006c07b07513543eead8e102fff7","enode":"enode://e73af1e2a834ee132564dd2e983c877b3ae230808d2b42da2ec91472eee6ee6595c439800ce980186b4b0d9a56b96babf747006c07b07513543eead8e102fff7@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"ns8hfiB2win20Vv+Kd+FqhKfH7EtKoMHkHMntf4vgMU=","hive":"\n=========================================================================\nTue Apr 10 09:55:59 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 9ecf21\npopulation: 12 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 634c 6c4b | 37 68d4 (0) 6c4b (0) 6623 (0) 634c (0)\n001 2 de9e c0f0 | 17 e3c2 (0) e5ee (0) fbbe (0) f0ee (0)\n002 5 bfa0 be69 be9f ada8 | 6 b4be (0) bfa0 (0) be69 (0) be9f (0)\n003 1 8387 | 1 8387 (0)\n004 0 | 0\n005 0 | 0\n============ DEPTH: 6 ==========================================\n006 1 9dc2 | 1 9dc2 (0)\n007 1 9f2d | 1 9f2d (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"e73af1e2a834ee132564dd2e983c877b3ae230808d2b42da2ec91472eee6ee6595c439800ce980186b4b0d9a56b96babf747006c07b07513543eead8e102fff7","private_key":"a2ffbdb8b486d91c6d2b579b5ae3f1a8f09feaf0451b375d8985f0ddea952926","name":"node_e73af1e2a834ee132564dd2e983c877b3ae230808d2b42da2ec91472eee6ee6595c439800ce980186b4b0d9a56b96babf747006c07b07513543eead8e102fff7","services":["streamer"],"enable_msg_events":true,"port":63018},"up":true}},{"node":{"info":{"id":"c0f2f1409cf83d7a777f6af95931181eb5a36b14a156f444075071c896fc5b435638ead23c65a242105db527c809e2c46f7805c862c0eb5d444749ddf22a5060","name":"node_c0f2f1409cf83d7a777f6af95931181eb5a36b14a156f444075071c896fc5b435638ead23c65a242105db527c809e2c46f7805c862c0eb5d444749ddf22a5060","enode":"enode://c0f2f1409cf83d7a777f6af95931181eb5a36b14a156f444075071c896fc5b435638ead23c65a242105db527c809e2c46f7805c862c0eb5d444749ddf22a5060@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"wPC+yKNQYoDfWZ1Xq8QU0AdpaWc4G5aQvPY6CTWGMHw=","hive":"\n=========================================================================\nTue Apr 10 09:55:59 UTC 2018 KΛÐΞMLIΛ hive: queen's address: c0f0be\npopulation: 12 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 1464 | 37 68d4 (0) 6c4b (0) 6623 (0) 634c (0)\n001 2 a070 9ecf | 10 b4be (0) bfa0 (0) be69 (0) be9f (0)\n002 2 f066 fbbe | 6 e3c2 (0) e5ee (0) fbbe (0) f0ee (0)\n003 3 df9a dbc5 d10e | 6 d10e (0) d8d8 (0) dbc5 (0) de9e (0)\n004 2 cfa6 ce61 | 2 ce61 (0) cfa6 (0)\n============ DEPTH: 5 ==========================================\n005 2 c6c4 c678 | 2 c6c4 (0) c678 (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"c0f2f1409cf83d7a777f6af95931181eb5a36b14a156f444075071c896fc5b435638ead23c65a242105db527c809e2c46f7805c862c0eb5d444749ddf22a5060","private_key":"48bdb744f1c9b25e7b2170b88fb956619976670186b82382029c84f3ef780930","name":"node_c0f2f1409cf83d7a777f6af95931181eb5a36b14a156f444075071c896fc5b435638ead23c65a242105db527c809e2c46f7805c862c0eb5d444749ddf22a5060","services":["streamer"],"enable_msg_events":true,"port":63019},"up":true}},{"node":{"info":{"id":"e021950ce89ce2bd79649aad2ed504789636b09870d0652fefa5e16631cb32a5d41c6cc4a540b7a0fca6bc3d5adf9b372a22cf714adc7b3e9b968d4c840017d4","name":"node_e021950ce89ce2bd79649aad2ed504789636b09870d0652fefa5e16631cb32a5d41c6cc4a540b7a0fca6bc3d5adf9b372a22cf714adc7b3e9b968d4c840017d4","enode":"enode://e021950ce89ce2bd79649aad2ed504789636b09870d0652fefa5e16631cb32a5d41c6cc4a540b7a0fca6bc3d5adf9b372a22cf714adc7b3e9b968d4c840017d4@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"FGRaubLrv0Q2Rm3wf/KOaLkndMa1oNMRoXR2XjUMcIk=","hive":"\n=========================================================================\nTue Apr 10 09:55:59 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 14645a\npopulation: 12 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 c0f0 | 27 b4be (0) bfa0 (0) be69 (0) be9f (0)\n001 2 5d05 44b1 | 19 68d4 (0) 6c4b (0) 6623 (0) 634c (0)\n002 5 332f 37de 2f44 2d83 | 13 23e4 (0) 2907 (0) 2d83 (0) 2f44 (0)\n003 1 0d48 | 1 0d48 (0)\n============ DEPTH: 4 ==========================================\n004 2 1abc 1be4 | 2 1abc (0) 1be4 (0)\n005 1 1087 | 1 1087 (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"e021950ce89ce2bd79649aad2ed504789636b09870d0652fefa5e16631cb32a5d41c6cc4a540b7a0fca6bc3d5adf9b372a22cf714adc7b3e9b968d4c840017d4","private_key":"49376794edff5cc56583fc3ce9e6987e0210c537f798bfc00cd523927052bbf2","name":"node_e021950ce89ce2bd79649aad2ed504789636b09870d0652fefa5e16631cb32a5d41c6cc4a540b7a0fca6bc3d5adf9b372a22cf714adc7b3e9b968d4c840017d4","services":["streamer"],"enable_msg_events":true,"port":63020},"up":true}},{"node":{"info":{"id":"16bd57b6590df0c69c440d178da8359b0a3e00b9c5362155eae42709bdc4d0488e437fa7e8396d5b429cebe356ebd1407039b21eefa8d9164b357845132edb28","name":"node_16bd57b6590df0c69c440d178da8359b0a3e00b9c5362155eae42709bdc4d0488e437fa7e8396d5b429cebe356ebd1407039b21eefa8d9164b357845132edb28","enode":"enode://16bd57b6590df0c69c440d178da8359b0a3e00b9c5362155eae42709bdc4d0488e437fa7e8396d5b429cebe356ebd1407039b21eefa8d9164b357845132edb28@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"RLFUS1eVocdwlIMrrkfITrOEgrHhqu+67Ky8fvnRDj4=","hive":"\n=========================================================================\nTue Apr 10 09:55:59 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 44b154\npopulation: 15 (52), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 9f2d | 18 e5ee (0) fbbe (0) f03f (0) f066 (0)\n001 2 2d83 1464 | 16 23e4 (0) 2907 (0) 2d83 (0) 2f44 (0)\n002 4 6623 61c2 72f7 7693 | 10 68d4 (0) 6c4b (0) 6623 (0) 634c (0)\n============ DEPTH: 3 ==========================================\n003 7 51db 577b 56ac 544a | 7 51db (0) 544a (0) 56ac (0) 577b (0)\n004 0 | 0\n005 1 4390 | 1 4390 (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"16bd57b6590df0c69c440d178da8359b0a3e00b9c5362155eae42709bdc4d0488e437fa7e8396d5b429cebe356ebd1407039b21eefa8d9164b357845132edb28","private_key":"b59aef84a0b7166aab7dc4edd8bfc66f56b77097cbbb4e937277ecd23c051473","name":"node_16bd57b6590df0c69c440d178da8359b0a3e00b9c5362155eae42709bdc4d0488e437fa7e8396d5b429cebe356ebd1407039b21eefa8d9164b357845132edb28","services":["streamer"],"enable_msg_events":true,"port":63021},"up":true}},{"node":{"info":{"id":"393eb8d2acf9244f1cdc220711c00d8fa7619394893643bc32e1ee0f821e5a2afed07badbdf97d710843c4ea6de3f74c113ad4c548afd23534d6dea5c37c6d9d","name":"node_393eb8d2acf9244f1cdc220711c00d8fa7619394893643bc32e1ee0f821e5a2afed07badbdf97d710843c4ea6de3f74c113ad4c548afd23534d6dea5c37c6d9d","enode":"enode://393eb8d2acf9244f1cdc220711c00d8fa7619394893643bc32e1ee0f821e5a2afed07badbdf97d710843c4ea6de3f74c113ad4c548afd23534d6dea5c37c6d9d@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"ny1yxuMOw2O9z57PKPz1VT+YNXaA2FMFgfzYFTiQBew=","hive":"\n=========================================================================\nTue Apr 10 09:55:59 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 9f2d72\npopulation: 8 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 44b1 | 37 0d48 (0) 1abc (0) 1be4 (0) 1087 (0)\n001 2 fbbe e5ee | 17 e3c2 (0) e5ee (0) fbbe (0) f0ee (0)\n002 2 a070 ada8 | 6 b4be (0) bfa0 (0) be69 (0) be9f (0)\n003 1 8387 | 1 8387 (0)\n004 0 | 0\n005 0 | 0\n============ DEPTH: 6 ==========================================\n006 1 9dc2 | 1 9dc2 (0)\n007 1 9ecf | 1 9ecf (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"393eb8d2acf9244f1cdc220711c00d8fa7619394893643bc32e1ee0f821e5a2afed07badbdf97d710843c4ea6de3f74c113ad4c548afd23534d6dea5c37c6d9d","private_key":"961cb451a05a1f043539e0417e0c612286d8a86116a4bd3ac4f301444bc0abc7","name":"node_393eb8d2acf9244f1cdc220711c00d8fa7619394893643bc32e1ee0f821e5a2afed07badbdf97d710843c4ea6de3f74c113ad4c548afd23534d6dea5c37c6d9d","services":["streamer"],"enable_msg_events":true,"port":63022},"up":true}},{"node":{"info":{"id":"62b8e67a4ca956c1cf2ba7a538d39bfe8bccf747fe65be48c88270ad44ee7711c0e9a43bb3821feffc492dba9b58397768c755810121add9c980c9a2c696feb0","name":"node_62b8e67a4ca956c1cf2ba7a538d39bfe8bccf747fe65be48c88270ad44ee7711c0e9a43bb3821feffc492dba9b58397768c755810121add9c980c9a2c696feb0","enode":"enode://62b8e67a4ca956c1cf2ba7a538d39bfe8bccf747fe65be48c88270ad44ee7711c0e9a43bb3821feffc492dba9b58397768c755810121add9c980c9a2c696feb0@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"rahUDGMGI0fTFihQzypIIKIO2WUU+wG5XZlbv/+XohI=","hive":"\n=========================================================================\nTue Apr 10 09:55:59 UTC 2018 KΛÐΞMLIΛ hive: queen's address: ada854\npopulation: 14 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 6623 | 37 68d4 (0) 6c4b (0) 61c2 (0) 634c (0)\n001 5 d8d8 f066 fbbe e3c2 | 17 e3c2 (0) e5ee (0) fbbe (0) f0ee (0)\n002 3 9dc2 9ecf 9f2d | 4 8387 (0) 9dc2 (0) 9ecf (0) 9f2d (0)\n============ DEPTH: 3 ==========================================\n003 4 b4be bfa0 be69 be9f | 4 b4be (0) bfa0 (0) be69 (0) be9f (0)\n004 1 a070 | 1 a070 (0)\n005 0 | 0\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"62b8e67a4ca956c1cf2ba7a538d39bfe8bccf747fe65be48c88270ad44ee7711c0e9a43bb3821feffc492dba9b58397768c755810121add9c980c9a2c696feb0","private_key":"a56a9d4ff921fba9e03ecffbd71d75f97cc9b7c5f389cf54b9bf66e689bb60b5","name":"node_62b8e67a4ca956c1cf2ba7a538d39bfe8bccf747fe65be48c88270ad44ee7711c0e9a43bb3821feffc492dba9b58397768c755810121add9c980c9a2c696feb0","services":["streamer"],"enable_msg_events":true,"port":63023},"up":true}},{"node":{"info":{"id":"17c7eb5833687a98087daadda564e54b1c770f946efb7efd69370a9caf6e6939e408f04a3fa1aa042d9463992a711786e504072fae56d007d696851696fc5643","name":"node_17c7eb5833687a98087daadda564e54b1c770f946efb7efd69370a9caf6e6939e408f04a3fa1aa042d9463992a711786e504072fae56d007d696851696fc5643","enode":"enode://17c7eb5833687a98087daadda564e54b1c770f946efb7efd69370a9caf6e6939e408f04a3fa1aa042d9463992a711786e504072fae56d007d696851696fc5643@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"vp+IDM/Y3Q9f3lh8Tp+9yy01Ud8MRQTZk41DAaknbnI=","hive":"\n=========================================================================\nTue Apr 10 09:55:59 UTC 2018 KΛÐΞMLIΛ hive: queen's address: be9f88\npopulation: 13 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 36c2 7768 6c4b 6623 | 37 68d4 (0) 6c4b (0) 61c2 (0) 634c (0)\n001 2 f066 ce61 | 17 e3c2 (0) e5ee (0) fbbe (0) f0ee (0)\n002 2 8387 9ecf | 4 8387 (0) 9dc2 (0) 9f2d (0) 9ecf (0)\n003 2 a070 ada8 | 2 a070 (0) ada8 (0)\n004 1 b4be | 1 b4be (0)\n005 0 | 0\n006 0 | 0\n============ DEPTH: 7 ==========================================\n007 1 bfa0 | 1 bfa0 (0)\n008 1 be69 | 1 be69 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"17c7eb5833687a98087daadda564e54b1c770f946efb7efd69370a9caf6e6939e408f04a3fa1aa042d9463992a711786e504072fae56d007d696851696fc5643","private_key":"f80db180b4c58031447688bd4b5f9d32cfee3dc85506153782a0368873110317","name":"node_17c7eb5833687a98087daadda564e54b1c770f946efb7efd69370a9caf6e6939e408f04a3fa1aa042d9463992a711786e504072fae56d007d696851696fc5643","services":["streamer"],"enable_msg_events":true,"port":63024},"up":true}},{"node":{"info":{"id":"f5efffc8e894cecc065f6892ad2a846c8fc4982d1c8c7fc729421d5108d519c501cc9f2f7a0046ec08d47cf2369753aaf287dfc3ef7ecd34d24d294efb933658","name":"node_f5efffc8e894cecc065f6892ad2a846c8fc4982d1c8c7fc729421d5108d519c501cc9f2f7a0046ec08d47cf2369753aaf287dfc3ef7ecd34d24d294efb933658","enode":"enode://f5efffc8e894cecc065f6892ad2a846c8fc4982d1c8c7fc729421d5108d519c501cc9f2f7a0046ec08d47cf2369753aaf287dfc3ef7ecd34d24d294efb933658@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"zmFKL9Mmzlew6tV1DQoI88fdlOHSk1hhaX499GUqIrY=","hive":"\n=========================================================================\nTue Apr 10 09:55:59 UTC 2018 KΛÐΞMLIΛ hive: queen's address: ce614a\npopulation: 9 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 358e | 37 68d4 (0) 6c4b (0) 61c2 (0) 634c (0)\n001 1 be9f | 10 8387 (0) 9dc2 (0) 9f2d (0) 9ecf (0)\n002 2 fbbe e5ee | 6 e3c2 (0) e5ee (0) fbbe (0) f0ee (0)\n003 1 d10e | 6 d10e (0) d8d8 (0) dbc5 (0) de9e (0)\n============ DEPTH: 4 ==========================================\n004 3 c6c4 c678 c0f0 | 3 c6c4 (0) c678 (0) c0f0 (0)\n005 0 | 0\n006 0 | 0\n007 1 cfa6 | 1 cfa6 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"f5efffc8e894cecc065f6892ad2a846c8fc4982d1c8c7fc729421d5108d519c501cc9f2f7a0046ec08d47cf2369753aaf287dfc3ef7ecd34d24d294efb933658","private_key":"5750e8b20da0147e055f965d6ba4ee434812f658663383ebfe7e88f13fdf59ab","name":"node_f5efffc8e894cecc065f6892ad2a846c8fc4982d1c8c7fc729421d5108d519c501cc9f2f7a0046ec08d47cf2369753aaf287dfc3ef7ecd34d24d294efb933658","services":["streamer"],"enable_msg_events":true,"port":63025},"up":true}},{"node":{"info":{"id":"7c273dd4218e9e5b92e19d250832a424ff2ac5482ad70953746de780100669eb143247e15ccfca14cce9a49a003c82be71ca034a2900bed4c89fb10bdbfcc7c3","name":"node_7c273dd4218e9e5b92e19d250832a424ff2ac5482ad70953746de780100669eb143247e15ccfca14cce9a49a003c82be71ca034a2900bed4c89fb10bdbfcc7c3","enode":"enode://7c273dd4218e9e5b92e19d250832a424ff2ac5482ad70953746de780100669eb143247e15ccfca14cce9a49a003c82be71ca034a2900bed4c89fb10bdbfcc7c3@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"NY7vPPmWS/ieBWr+D0tGzoW8sHm6uSKkrp36VVABq/w=","hive":"\n=========================================================================\nTue Apr 10 09:55:59 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 358eef\npopulation: 10 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 ce61 | 27 8387 (0) 9dc2 (0) 9f2d (0) 9ecf (0)\n001 1 5cdc | 19 6c4b (0) 68d4 (0) 634c (0) 61c2 (0)\n002 1 1abc | 5 0d48 (0) 1abc (0) 1be4 (0) 1087 (0)\n003 1 23e4 | 4 23e4 (0) 2907 (0) 2d83 (0) 2f44 (0)\n004 2 3ea2 3c38 | 4 3c93 (0) 3c38 (0) 3ff4 (0) 3ea2 (0)\n005 2 30d8 332f | 2 30d8 (0) 332f (0)\n============ DEPTH: 6 ==========================================\n006 2 37de 36c2 | 2 36c2 (0) 37de (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"7c273dd4218e9e5b92e19d250832a424ff2ac5482ad70953746de780100669eb143247e15ccfca14cce9a49a003c82be71ca034a2900bed4c89fb10bdbfcc7c3","private_key":"f841751579683b856a59eb75f3493a4b3e39183d8818a2638559100bb6f5e66a","name":"node_7c273dd4218e9e5b92e19d250832a424ff2ac5482ad70953746de780100669eb143247e15ccfca14cce9a49a003c82be71ca034a2900bed4c89fb10bdbfcc7c3","services":["streamer"],"enable_msg_events":true,"port":63026},"up":true}},{"node":{"info":{"id":"8959c5cf825ebab14efeacf2807ad9498256a9e89a2ef00690c9ee23a3e934e111c52a5ddcc791b93f49424ac008095d8cb0da6905dfdeb62309fc4f6672e59e","name":"node_8959c5cf825ebab14efeacf2807ad9498256a9e89a2ef00690c9ee23a3e934e111c52a5ddcc791b93f49424ac008095d8cb0da6905dfdeb62309fc4f6672e59e","enode":"enode://8959c5cf825ebab14efeacf2807ad9498256a9e89a2ef00690c9ee23a3e934e111c52a5ddcc791b93f49424ac008095d8cb0da6905dfdeb62309fc4f6672e59e@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"XNxEk/Adbr7DBwsCgnW9lO3mHbIaT107KCo2bR00hLg=","hive":"\n=========================================================================\nTue Apr 10 09:55:59 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 5cdc44\npopulation: 10 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 fbbe f03f | 27 fbbe (0) f0ee (0) f03f (0) f066 (0)\n001 2 1be4 358e | 18 0d48 (0) 1abc (0) 1be4 (0) 1087 (0)\n002 1 7693 | 10 68d4 (0) 6c4b (0) 634c (0) 61c2 (0)\n003 2 4390 44b1 | 2 4390 (0) 44b1 (0)\n004 1 577b | 4 51db (0) 544a (0) 56ac (0) 577b (0)\n005 0 | 0\n006 0 | 0\n============ DEPTH: 7 ==========================================\n007 1 5d05 | 1 5d05 (0)\n008 1 5c3c | 1 5c3c (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"8959c5cf825ebab14efeacf2807ad9498256a9e89a2ef00690c9ee23a3e934e111c52a5ddcc791b93f49424ac008095d8cb0da6905dfdeb62309fc4f6672e59e","private_key":"be9f2207e4e7a93758129c0d6fa34877b685210cf0e8f8d233e5425d8fa461f9","name":"node_8959c5cf825ebab14efeacf2807ad9498256a9e89a2ef00690c9ee23a3e934e111c52a5ddcc791b93f49424ac008095d8cb0da6905dfdeb62309fc4f6672e59e","services":["streamer"],"enable_msg_events":true,"port":63027},"up":true}},{"node":{"info":{"id":"dcf2401cbc26f3db27bb85c24984b1d755b3503fe400c139a0bedbe5de24db3f27c8f4f40adc1880b6142d20e67a40f3d45d36ba7fce122ffa44703e65622198","name":"node_dcf2401cbc26f3db27bb85c24984b1d755b3503fe400c139a0bedbe5de24db3f27c8f4f40adc1880b6142d20e67a40f3d45d36ba7fce122ffa44703e65622198","enode":"enode://dcf2401cbc26f3db27bb85c24984b1d755b3503fe400c139a0bedbe5de24db3f27c8f4f40adc1880b6142d20e67a40f3d45d36ba7fce122ffa44703e65622198@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"dpMyZcPYcrLSDnqWHz9OhYr+Ea7nc7XK9nhVPlatNTc=","hive":"\n=========================================================================\nTue Apr 10 09:55:59 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 769332\npopulation: 11 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 f066 | 27 fbbe (0) f0ee (0) f03f (0) f066 (0)\n001 1 1be4 | 18 0d48 (0) 1be4 (0) 1abc (0) 1087 (0)\n002 3 44b1 5cdc 577b | 9 4390 (0) 44b1 (0) 5d05 (0) 5c3c (0)\n003 2 68d4 6623 | 5 6c4b (0) 68d4 (0) 634c (0) 61c2 (0)\n004 2 7a1f 7a56 | 2 7a1f (0) 7a56 (0)\n============ DEPTH: 5 ==========================================\n005 1 72f7 | 1 72f7 (0)\n006 0 | 0\n007 1 7768 | 1 7768 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"dcf2401cbc26f3db27bb85c24984b1d755b3503fe400c139a0bedbe5de24db3f27c8f4f40adc1880b6142d20e67a40f3d45d36ba7fce122ffa44703e65622198","private_key":"4a245ec64e442d4cad2468d96914df5728633c568ed3d063990ac8932be63222","name":"node_dcf2401cbc26f3db27bb85c24984b1d755b3503fe400c139a0bedbe5de24db3f27c8f4f40adc1880b6142d20e67a40f3d45d36ba7fce122ffa44703e65622198","services":["streamer"],"enable_msg_events":true,"port":63028},"up":true}},{"node":{"info":{"id":"38b3adde25c6407f29c2a721f1f5c082cc94ddad09fc5afda2bbb2309212a9b54b1553731a65ec8b58769fc11d488169c8000ee15fe8966bd44a3879e0c9e534","name":"node_38b3adde25c6407f29c2a721f1f5c082cc94ddad09fc5afda2bbb2309212a9b54b1553731a65ec8b58769fc11d488169c8000ee15fe8966bd44a3879e0c9e534","enode":"enode://38b3adde25c6407f29c2a721f1f5c082cc94ddad09fc5afda2bbb2309212a9b54b1553731a65ec8b58769fc11d488169c8000ee15fe8966bd44a3879e0c9e534@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"V3uepHvADN4lsRygOGHfDM+q2M4oFQDv7eiNJeASseM=","hive":"\n=========================================================================\nTue Apr 10 09:55:59 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 577b9e\npopulation: 12 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 dfe3 | 27 8387 (0) 9dc2 (0) 9f2d (0) 9ecf (0)\n001 3 1be4 2f44 332f | 18 0d48 (0) 1be4 (0) 1abc (0) 1087 (0)\n002 1 7693 | 10 6c4b (0) 68d4 (0) 634c (0) 61c2 (0)\n003 2 44b1 4390 | 2 4390 (0) 44b1 (0)\n004 2 5c3c 5cdc | 3 5d05 (0) 5c3c (0) 5cdc (0)\n005 1 51db | 1 51db (0)\n============ DEPTH: 6 ==========================================\n006 1 544a | 1 544a (0)\n007 1 56ac | 1 56ac (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"38b3adde25c6407f29c2a721f1f5c082cc94ddad09fc5afda2bbb2309212a9b54b1553731a65ec8b58769fc11d488169c8000ee15fe8966bd44a3879e0c9e534","private_key":"1771927f1f06912915f5498e857816fd8f73b2bde10f88ba4a856684bcc2a6fa","name":"node_38b3adde25c6407f29c2a721f1f5c082cc94ddad09fc5afda2bbb2309212a9b54b1553731a65ec8b58769fc11d488169c8000ee15fe8966bd44a3879e0c9e534","services":["streamer"],"enable_msg_events":true,"port":63029},"up":true}},{"node":{"info":{"id":"6593097e880701f3d0573df7bff9ba7af40f4f83b828bfc11bdabea62fb94ed39c8233d8d40275c2af9ceddae44514e029a546fe9df73abbd3821d37933aba49","name":"node_6593097e880701f3d0573df7bff9ba7af40f4f83b828bfc11bdabea62fb94ed39c8233d8d40275c2af9ceddae44514e029a546fe9df73abbd3821d37933aba49","enode":"enode://6593097e880701f3d0573df7bff9ba7af40f4f83b828bfc11bdabea62fb94ed39c8233d8d40275c2af9ceddae44514e029a546fe9df73abbd3821d37933aba49@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"3+OJ7n/gPICdekr6HwTd6auaUNjGylvySJ3rsugylUE=","hive":"\n=========================================================================\nTue Apr 10 09:55:59 UTC 2018 KΛÐΞMLIΛ hive: queen's address: dfe389\npopulation: 11 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 577b 3ea2 | 37 4390 (0) 44b1 (0) 5d05 (0) 5c3c (0)\n001 2 9dc2 8387 | 10 8387 (0) 9dc2 (0) 9f2d (0) 9ecf (0)\n002 1 fbbe | 6 fbbe (0) f0ee (0) f03f (0) f066 (0)\n003 1 cfa6 | 5 c678 (0) c6c4 (0) c0f0 (0) ce61 (0)\n004 1 d10e | 1 d10e (0)\n005 2 d8d8 dbc5 | 2 d8d8 (0) dbc5 (0)\n006 0 | 0\n============ DEPTH: 7 ==========================================\n007 1 de9e | 1 de9e (0)\n008 0 | 0\n009 1 df9a | 1 df9a (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"6593097e880701f3d0573df7bff9ba7af40f4f83b828bfc11bdabea62fb94ed39c8233d8d40275c2af9ceddae44514e029a546fe9df73abbd3821d37933aba49","private_key":"986bc0252067c4c3ace80099cbc843d6f16f7483719e9ecf7a3a0f876a461ee8","name":"node_6593097e880701f3d0573df7bff9ba7af40f4f83b828bfc11bdabea62fb94ed39c8233d8d40275c2af9ceddae44514e029a546fe9df73abbd3821d37933aba49","services":["streamer"],"enable_msg_events":true,"port":63030},"up":true}},{"node":{"info":{"id":"578666c4113e196a7c738fdbae0bd68ade450283eb835efd06591798f1893f7f7d9cde0691faff670b5ae24e58cbc2f549d2196f244dddc00e82852c38e8539e","name":"node_578666c4113e196a7c738fdbae0bd68ade450283eb835efd06591798f1893f7f7d9cde0691faff670b5ae24e58cbc2f549d2196f244dddc00e82852c38e8539e","enode":"enode://578666c4113e196a7c738fdbae0bd68ade450283eb835efd06591798f1893f7f7d9cde0691faff670b5ae24e58cbc2f549d2196f244dddc00e82852c38e8539e@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"PqJVTbAgIfBBNSlCbXp7Csmr6AZDmT9tgP3/+Tp2XEA=","hive":"\n=========================================================================\nTue Apr 10 09:55:59 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 3ea255\npopulation: 9 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 dfe3 | 27 8387 (0) 9f2d (0) 9ecf (0) 9dc2 (0)\n001 1 68d4 | 19 4390 (0) 44b1 (0) 5d05 (0) 5c3c (0)\n002 2 1abc 1be4 | 5 0d48 (0) 1be4 (0) 1abc (0) 1087 (0)\n003 1 23e4 | 4 23e4 (0) 2907 (0) 2d83 (0) 2f44 (0)\n004 1 358e | 5 30d8 (0) 332f (0) 36c2 (0) 37de (0)\n005 0 | 0\n============ DEPTH: 6 ==========================================\n006 2 3c93 3c38 | 2 3c93 (0) 3c38 (0)\n007 1 3ff4 | 1 3ff4 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"578666c4113e196a7c738fdbae0bd68ade450283eb835efd06591798f1893f7f7d9cde0691faff670b5ae24e58cbc2f549d2196f244dddc00e82852c38e8539e","private_key":"39848c3aa21a67751f95ffc8938b36264eeee342816d41b37816f2164e59858e","name":"node_578666c4113e196a7c738fdbae0bd68ade450283eb835efd06591798f1893f7f7d9cde0691faff670b5ae24e58cbc2f549d2196f244dddc00e82852c38e8539e","services":["streamer"],"enable_msg_events":true,"port":63031},"up":true}},{"node":{"info":{"id":"e1082b4577aa370a5171b7602282208697dcead854f0c82acb5628d179fa5990a0fc85c5343a47177aab81c7fa6c1be8a27a3484acddc353582ddeb61892ef94","name":"node_e1082b4577aa370a5171b7602282208697dcead854f0c82acb5628d179fa5990a0fc85c5343a47177aab81c7fa6c1be8a27a3484acddc353582ddeb61892ef94","enode":"enode://e1082b4577aa370a5171b7602282208697dcead854f0c82acb5628d179fa5990a0fc85c5343a47177aab81c7fa6c1be8a27a3484acddc353582ddeb61892ef94@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"aNRe7IlbkfCBAm6G7RZAktrY1Ah5GM1Qxvd3Z9lXf20=","hive":"\n=========================================================================\nTue Apr 10 09:55:59 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 68d45e\npopulation: 9 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 cfa6 | 27 8387 (0) 9f2d (0) 9ecf (0) 9dc2 (0)\n001 1 3ea2 | 18 0d48 (0) 1be4 (0) 1abc (0) 1087 (0)\n002 1 4390 | 9 4390 (0) 44b1 (0) 5d05 (0) 5c3c (0)\n003 2 7693 7a56 | 5 7a1f (0) 7a56 (0) 72f7 (0) 7768 (0)\n============ DEPTH: 4 ==========================================\n004 3 61c2 634c 6623 | 3 634c (0) 61c2 (0) 6623 (0)\n005 1 6c4b | 1 6c4b (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"e1082b4577aa370a5171b7602282208697dcead854f0c82acb5628d179fa5990a0fc85c5343a47177aab81c7fa6c1be8a27a3484acddc353582ddeb61892ef94","private_key":"d5dee04f1435fa7ab6d65e89de8c4c6bf156111bfb9ee5de0ab617cc3be19681","name":"node_e1082b4577aa370a5171b7602282208697dcead854f0c82acb5628d179fa5990a0fc85c5343a47177aab81c7fa6c1be8a27a3484acddc353582ddeb61892ef94","services":["streamer"],"enable_msg_events":true,"port":63032},"up":true}},{"node":{"info":{"id":"a4fbd2ffc25d2c3bd37beecd637dda5983cb5817ecb6da62aec16ea59aaf7e71966649211461564ba808174361898a1d2265f1a42e94434bc00d5d3e04b67a8a","name":"node_a4fbd2ffc25d2c3bd37beecd637dda5983cb5817ecb6da62aec16ea59aaf7e71966649211461564ba808174361898a1d2265f1a42e94434bc00d5d3e04b67a8a","enode":"enode://a4fbd2ffc25d2c3bd37beecd637dda5983cb5817ecb6da62aec16ea59aaf7e71966649211461564ba808174361898a1d2265f1a42e94434bc00d5d3e04b67a8a@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"z6bPwfhW5pQwNw1cUhMFGVAsep5PsUx8jZswlhKjwbs=","hive":"\n=========================================================================\nTue Apr 10 09:55:59 UTC 2018 KΛÐΞMLIΛ hive: queen's address: cfa6cf\npopulation: 13 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 5d05 68d4 | 37 0d48 (0) 1087 (0) 1464 (0) 1be4 (0)\n001 2 be69 b4be | 10 bfa0 (0) be9f (0) be69 (0) b4be (0)\n002 2 f066 fbbe | 6 fbbe (0) f0ee (0) f03f (0) f066 (0)\n003 3 de9e df9a dfe3 | 6 d10e (0) d8d8 (0) dbc5 (0) de9e (0)\n============ DEPTH: 4 ==========================================\n004 3 c678 c6c4 c0f0 | 3 c6c4 (0) c678 (0) c0f0 (0)\n005 0 | 0\n006 0 | 0\n007 1 ce61 | 1 ce61 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"a4fbd2ffc25d2c3bd37beecd637dda5983cb5817ecb6da62aec16ea59aaf7e71966649211461564ba808174361898a1d2265f1a42e94434bc00d5d3e04b67a8a","private_key":"044a1acc0d565f7080db7b625baefe8a5f7aef9009a7bcd338fc31a02d704d8c","name":"node_a4fbd2ffc25d2c3bd37beecd637dda5983cb5817ecb6da62aec16ea59aaf7e71966649211461564ba808174361898a1d2265f1a42e94434bc00d5d3e04b67a8a","services":["streamer"],"enable_msg_events":true,"port":63033},"up":true}},{"node":{"info":{"id":"eb08a7774ca5252237d059a8bbad68044c83b2c332024be98bdc0c58508867a80cd34cb4162bd55a47fecc93301c8b2a7a1edbfd807ebb5623499cac80ea42de","name":"node_eb08a7774ca5252237d059a8bbad68044c83b2c332024be98bdc0c58508867a80cd34cb4162bd55a47fecc93301c8b2a7a1edbfd807ebb5623499cac80ea42de","enode":"enode://eb08a7774ca5252237d059a8bbad68044c83b2c332024be98bdc0c58508867a80cd34cb4162bd55a47fecc93301c8b2a7a1edbfd807ebb5623499cac80ea42de@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"XQVqOMOnw7/NQxt2dmKQNFT0FCnS4DubMCc+WxuOXJc=","hive":"\n=========================================================================\nTue Apr 10 09:55:59 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 5d056a\npopulation: 9 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 cfa6 | 27 b4be (0) bfa0 (0) be9f (0) be69 (0)\n001 1 1464 | 18 0d48 (0) 1087 (0) 1464 (0) 1be4 (0)\n002 2 7768 7a56 | 10 634c (0) 61c2 (0) 6623 (0) 6c4b (0)\n003 2 4390 44b1 | 2 4390 (0) 44b1 (0)\n004 1 51db | 4 577b (0) 56ac (0) 544a (0) 51db (0)\n005 0 | 0\n006 0 | 0\n============ DEPTH: 7 ==========================================\n007 2 5cdc 5c3c | 2 5cdc (0) 5c3c (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"eb08a7774ca5252237d059a8bbad68044c83b2c332024be98bdc0c58508867a80cd34cb4162bd55a47fecc93301c8b2a7a1edbfd807ebb5623499cac80ea42de","private_key":"8be74288552caed392476d39780f806f2c21b50a9990c5a3a5ed37397b218a6d","name":"node_eb08a7774ca5252237d059a8bbad68044c83b2c332024be98bdc0c58508867a80cd34cb4162bd55a47fecc93301c8b2a7a1edbfd807ebb5623499cac80ea42de","services":["streamer"],"enable_msg_events":true,"port":63034},"up":true}},{"node":{"info":{"id":"6eeb951b8f6d5ac519132910222777d5a409325e6c64d89708a00e55cb0fe85889aac1baa724e29fa7f064323b164a9c40c5114a65736e3dd16f0336283d9c7b","name":"node_6eeb951b8f6d5ac519132910222777d5a409325e6c64d89708a00e55cb0fe85889aac1baa724e29fa7f064323b164a9c40c5114a65736e3dd16f0336283d9c7b","enode":"enode://6eeb951b8f6d5ac519132910222777d5a409325e6c64d89708a00e55cb0fe85889aac1baa724e29fa7f064323b164a9c40c5114a65736e3dd16f0336283d9c7b@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"ela0ID7hyteBsj0qeGlPY+t9/m2awk/BgeamNRbJ76U=","hive":"\n=========================================================================\nTue Apr 10 09:55:59 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 7a56b4\npopulation: 11 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 f066 | 27 fbbe (0) f0ee (0) f03f (0) f066 (0)\n001 1 0d48 | 18 0d48 (0) 1087 (0) 1464 (0) 1be4 (0)\n002 2 5d05 51db | 9 4390 (0) 44b1 (0) 5cdc (0) 5c3c (0)\n003 3 68d4 61c2 6623 | 5 634c (0) 61c2 (0) 6623 (0) 6c4b (0)\n============ DEPTH: 4 ==========================================\n004 3 72f7 7768 7693 | 3 72f7 (0) 7768 (0) 7693 (0)\n005 0 | 0\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 1 7a1f | 1 7a1f (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"6eeb951b8f6d5ac519132910222777d5a409325e6c64d89708a00e55cb0fe85889aac1baa724e29fa7f064323b164a9c40c5114a65736e3dd16f0336283d9c7b","private_key":"e644c54ce52ddb2788fc683264f175a24485082eb88ebe0a83c94ecce77d7175","name":"node_6eeb951b8f6d5ac519132910222777d5a409325e6c64d89708a00e55cb0fe85889aac1baa724e29fa7f064323b164a9c40c5114a65736e3dd16f0336283d9c7b","services":["streamer"],"enable_msg_events":true,"port":63035},"up":true}},{"node":{"info":{"id":"6419279b600da3e2ee8d0b2a5b0319bc6cd496086955b49a8d2168fd4c35d5688291bc9313076b1b8e070f25dc593788d72b8f8c1d2ad828741a45deea35e58d","name":"node_6419279b600da3e2ee8d0b2a5b0319bc6cd496086955b49a8d2168fd4c35d5688291bc9313076b1b8e070f25dc593788d72b8f8c1d2ad828741a45deea35e58d","enode":"enode://6419279b600da3e2ee8d0b2a5b0319bc6cd496086955b49a8d2168fd4c35d5688291bc9313076b1b8e070f25dc593788d72b8f8c1d2ad828741a45deea35e58d@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"UdsNj+/u36szlPjzmLbY9FQLJLxsvY5mvFp0gNsCKPU=","hive":"\n=========================================================================\nTue Apr 10 09:55:59 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 51db0d\npopulation: 11 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 f03f f066 | 27 fbbe (0) f0ee (0) f066 (0) f03f (0)\n001 1 3c38 | 18 0d48 (0) 1087 (0) 1464 (0) 1be4 (0)\n002 1 7a56 | 10 634c (0) 61c2 (0) 6623 (0) 6c4b (0)\n003 2 44b1 4390 | 2 4390 (0) 44b1 (0)\n004 2 5d05 5c3c | 3 5cdc (0) 5c3c (0) 5d05 (0)\n============ DEPTH: 5 ==========================================\n005 3 544a 56ac 577b | 3 577b (0) 56ac (0) 544a (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"6419279b600da3e2ee8d0b2a5b0319bc6cd496086955b49a8d2168fd4c35d5688291bc9313076b1b8e070f25dc593788d72b8f8c1d2ad828741a45deea35e58d","private_key":"77445377572b915c2e3802f70fc9eae8d29e767f54f80a29701ae5d1fe0c8677","name":"node_6419279b600da3e2ee8d0b2a5b0319bc6cd496086955b49a8d2168fd4c35d5688291bc9313076b1b8e070f25dc593788d72b8f8c1d2ad828741a45deea35e58d","services":["streamer"],"enable_msg_events":true,"port":63036},"up":true}},{"node":{"info":{"id":"032b1ce6881413b7ade1918e56691c7acd9f24111f47792ca50c33e570afba433caa132ad2326d03f9c0544fdc09fa0ca65f61de9fe61d6dd92c5d25a8df69af","name":"node_032b1ce6881413b7ade1918e56691c7acd9f24111f47792ca50c33e570afba433caa132ad2326d03f9c0544fdc09fa0ca65f61de9fe61d6dd92c5d25a8df69af","enode":"enode://032b1ce6881413b7ade1918e56691c7acd9f24111f47792ca50c33e570afba433caa132ad2326d03f9c0544fdc09fa0ca65f61de9fe61d6dd92c5d25a8df69af@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"PDirpDoVphtoD6dnNTzOfkFly8mWlo+ZAAHXWV/yQ8g=","hive":"\n=========================================================================\nTue Apr 10 09:55:59 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 3c38ab\npopulation: 13 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 9dc2 | 27 fbbe (0) f0ee (0) f066 (0) f03f (0)\n001 1 51db | 19 61c2 (0) 634c (0) 6623 (0) 6c4b (0)\n002 1 1abc | 5 0d48 (0) 1087 (0) 1464 (0) 1be4 (0)\n003 2 2d83 23e4 | 4 2907 (0) 2f44 (0) 2d83 (0) 23e4 (0)\n004 5 30d8 332f 358e 36c2 | 5 332f (0) 30d8 (0) 36c2 (0) 37de (0)\n005 0 | 0\n============ DEPTH: 6 ==========================================\n006 2 3ea2 3ff4 | 2 3ea2 (0) 3ff4 (0)\n007 0 | 0\n008 1 3c93 | 1 3c93 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"032b1ce6881413b7ade1918e56691c7acd9f24111f47792ca50c33e570afba433caa132ad2326d03f9c0544fdc09fa0ca65f61de9fe61d6dd92c5d25a8df69af","private_key":"f6b20f29a1cdcad8f8bd88acc4f6ffba7b3027e46ab60784e2c2b77edb3d3630","name":"node_032b1ce6881413b7ade1918e56691c7acd9f24111f47792ca50c33e570afba433caa132ad2326d03f9c0544fdc09fa0ca65f61de9fe61d6dd92c5d25a8df69af","services":["streamer"],"enable_msg_events":true,"port":63037},"up":true}},{"node":{"info":{"id":"86d55ece15e6bb4da7601f6587654505f760ee2b87abdb115091eefa93f61cf29fd695601bb8c6ae2c76400de24b8bca9ca32b50e4b849ae76f5320b03276bfc","name":"node_86d55ece15e6bb4da7601f6587654505f760ee2b87abdb115091eefa93f61cf29fd695601bb8c6ae2c76400de24b8bca9ca32b50e4b849ae76f5320b03276bfc","enode":"enode://86d55ece15e6bb4da7601f6587654505f760ee2b87abdb115091eefa93f61cf29fd695601bb8c6ae2c76400de24b8bca9ca32b50e4b849ae76f5320b03276bfc@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"ncLEFm+pQQ175ny7WsVyqkKpp4wu/l6mAd3TfDVhlto=","hive":"\n=========================================================================\nTue Apr 10 09:55:59 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 9dc2c4\npopulation: 13 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 3c38 37de | 37 7693 (0) 7768 (0) 72f7 (0) 7a56 (0)\n001 4 fbbe de9e dfe3 df9a | 17 fbbe (0) f0ee (0) f066 (0) f03f (0)\n002 4 ada8 b4be bfa0 be69 | 6 b4be (0) bfa0 (0) be9f (0) be69 (0)\n003 1 8387 | 1 8387 (0)\n004 0 | 0\n005 0 | 0\n============ DEPTH: 6 ==========================================\n006 2 9f2d 9ecf | 2 9f2d (0) 9ecf (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"86d55ece15e6bb4da7601f6587654505f760ee2b87abdb115091eefa93f61cf29fd695601bb8c6ae2c76400de24b8bca9ca32b50e4b849ae76f5320b03276bfc","private_key":"25bb03224302b9c89585681c4bb30dc9d95fe417e5c0f13627154083cda7492b","name":"node_86d55ece15e6bb4da7601f6587654505f760ee2b87abdb115091eefa93f61cf29fd695601bb8c6ae2c76400de24b8bca9ca32b50e4b849ae76f5320b03276bfc","services":["streamer"],"enable_msg_events":true,"port":63038},"up":true}},{"node":{"info":{"id":"31cbd7c029d69715e59f31bccf362cd76e0a87839f1f63c6623be437d2af227a38f12c5fb9c659cc543976833caf22a52f5191c7c465a9ba36ac4235c12add72","name":"node_31cbd7c029d69715e59f31bccf362cd76e0a87839f1f63c6623be437d2af227a38f12c5fb9c659cc543976833caf22a52f5191c7c465a9ba36ac4235c12add72","enode":"enode://31cbd7c029d69715e59f31bccf362cd76e0a87839f1f63c6623be437d2af227a38f12c5fb9c659cc543976833caf22a52f5191c7c465a9ba36ac4235c12add72@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"N9684Mvhmiq4jxXf+jkN85KTjnBglwuT6uloqMJJdlA=","hive":"\n=========================================================================\nTue Apr 10 09:55:59 UTC 2018 KΛÐΞMLIΛ hive: queen's address: 37debc\npopulation: 12 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 9dc2 de9e | 27 b4be (0) bfa0 (0) be9f (0) be69 (0)\n001 1 6623 | 19 4390 (0) 44b1 (0) 577b (0) 56ac (0)\n002 2 1be4 1464 | 5 0d48 (0) 1087 (0) 1464 (0) 1be4 (0)\n003 1 2f44 | 4 2d83 (0) 2f44 (0) 2907 (0) 23e4 (0)\n004 2 3c93 3c38 | 4 3ea2 (0) 3ff4 (0) 3c93 (0) 3c38 (0)\n005 2 30d8 332f | 2 332f (0) 30d8 (0)\n============ DEPTH: 6 ==========================================\n006 1 358e | 1 358e (0)\n007 1 36c2 | 1 36c2 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"31cbd7c029d69715e59f31bccf362cd76e0a87839f1f63c6623be437d2af227a38f12c5fb9c659cc543976833caf22a52f5191c7c465a9ba36ac4235c12add72","private_key":"a4eb160b838f392946a844b9fbc36006c459ff6f9ef46a832d000f17f2aa834c","name":"node_31cbd7c029d69715e59f31bccf362cd76e0a87839f1f63c6623be437d2af227a38f12c5fb9c659cc543976833caf22a52f5191c7c465a9ba36ac4235c12add72","services":["streamer"],"enable_msg_events":true,"port":63039},"up":true}}],"conns":[{"one":"a48a667469a1344cb70f269b21fb3ca9e83823226749fd9c232be1b86ab9427888f2ecb20ddfa56da361463a061e192570f2f8da3fa967c473320ca85e382c53","other":"8f6fb4a5baf715e001b060ce72378829279ce06a3247bd4a6faa3c725ee1b949570373e4231de82981020563e704297e77172506101b1444fcacfcc5f211827e","up":true},{"one":"8f6fb4a5baf715e001b060ce72378829279ce06a3247bd4a6faa3c725ee1b949570373e4231de82981020563e704297e77172506101b1444fcacfcc5f211827e","other":"e7b1563d6e089e030983b075b590abb8a3205e9bce953f562b755ba150a3edc2dc3377259d96c05cc7363a23aed613711ca049e26253fd9273ac4c0483087015","up":true},{"one":"0a45a0aa4b4eee71b2828c794281d698019667288cf51311ffae7d8ea895f8ae29f7958dbfcda8763d9d8e9c097dccc5f92ac9d09fb4ccbde178d7f5ebda4d35","other":"f70c92be150cb3f65f6bd904c8c161bfb0cea717bab0b24da63714de83e0872c8c369960ada1629607a1e166a19b6cfa887603e4868e7912ae5512744e8cc1c0","up":true},{"one":"e7b1563d6e089e030983b075b590abb8a3205e9bce953f562b755ba150a3edc2dc3377259d96c05cc7363a23aed613711ca049e26253fd9273ac4c0483087015","other":"d0718ce0dafea66ee16c79626e020355273cdd062c0fceb122e391c4ca6e4e408a1b0e8230c4ade5bc95803916bdd6d98c99d2b6ea70c32e17fa1f2c98741a90","up":true},{"one":"7722d7d06c66afb0642d5f9ae0b22ed812c632f2d62ce64315da40eb003feb3fae1b337c10df21d297beabe51b3879f2c0a725f08ee78a8e09c75f86bd0e2092","other":"e479930845e1dac2d5908894548cc06c132fc5820810c6f46d9adc2bc252dd40b64642a3b2005ad3688d2637c43967f570bd153db9ee6742e1b23dbfb72537fa","up":true},{"one":"f360c6599a0911337c7b96365fda1b2f64890bdb4483bb7e86bca15484f24c4efc0d1f6f56aa0c4fa5c205e6c1dbbf20d2ca3c2f8734f703fe6d672fa76a0d45","other":"f5272b71c228eb14b9e0e221deefc0a91353a5f17d01475f57fad54bb8e50e375f58019c7200a9ca45b0f1da6538708c61242e478d917499871df7a9d5857f1a","up":true},{"one":"e479930845e1dac2d5908894548cc06c132fc5820810c6f46d9adc2bc252dd40b64642a3b2005ad3688d2637c43967f570bd153db9ee6742e1b23dbfb72537fa","other":"61b32cded1b5ea3e2ca545a55c84251daaaacf51e6fed98fbdf4c5b6b91a554081e1e577aaaaaa4f911780f92703c1d715695d86c1be641b0bd1794f4107c2be","up":true},{"one":"61b32cded1b5ea3e2ca545a55c84251daaaacf51e6fed98fbdf4c5b6b91a554081e1e577aaaaaa4f911780f92703c1d715695d86c1be641b0bd1794f4107c2be","other":"9e51eb48f59886e70eb8d02e1c0c4423de3f0ce79c7a62bfd91bc2048cf643f40a91e2d2a1a8a19a9e4ba4a96aed0965aefcd941c068208abe8bf5029eb27d55","up":true},{"one":"9e51eb48f59886e70eb8d02e1c0c4423de3f0ce79c7a62bfd91bc2048cf643f40a91e2d2a1a8a19a9e4ba4a96aed0965aefcd941c068208abe8bf5029eb27d55","other":"7a1f97c41c9efd7a2903af78f72d02cfff3631dc6260d3ceb2364c2a8e06965710e8feae6aa9f99b48b2475da10b2f9581c76d47b4cd2bfee09c43dcb5e3e5d9","up":true},{"one":"7a1f97c41c9efd7a2903af78f72d02cfff3631dc6260d3ceb2364c2a8e06965710e8feae6aa9f99b48b2475da10b2f9581c76d47b4cd2bfee09c43dcb5e3e5d9","other":"7a45fa46f161fae3ef9013e9ab81145f4a76fa6ae22160424d6dc111acbd477ce43d4c10db89cb7451c97ea1fbd78428997d01fd17e1851f8b559b404ede6da7","up":true},{"one":"af3f9dc00ce3cc156000f16a06c55c123ccdfabed89c9aee4478ff439b6f52a89d0501cff626d36b7f1852737955f7a036b25cf259580e8f46a3e0e44340b539","other":"95c3ca2362de2eb0ac8efdd243918ed216f5d124bc6f5b9d83a6ee1aaf8a0fbdbd70ca1710d1ed825d6871f13a15954725f1aa1b27b48307844c0bc27baec0db","up":true},{"one":"7a45fa46f161fae3ef9013e9ab81145f4a76fa6ae22160424d6dc111acbd477ce43d4c10db89cb7451c97ea1fbd78428997d01fd17e1851f8b559b404ede6da7","other":"07138ce506125910af81bd1bae11c22bfab9a81e1e057cc3d84769475c5da9873eb3f11edc6aca83ef486bfb63eba15a6233676d29d93ac9e774f10cd42c8cbd","up":true},{"one":"95c3ca2362de2eb0ac8efdd243918ed216f5d124bc6f5b9d83a6ee1aaf8a0fbdbd70ca1710d1ed825d6871f13a15954725f1aa1b27b48307844c0bc27baec0db","other":"c73f8fe9f54b89634cb0e8e332407a3a90cbbd347c0abc93823db13a7a39c46e7bd30d3f557316d92dd731cfc686afc308448682ff06c77246e3fb02b9a025ba","up":true},{"one":"07138ce506125910af81bd1bae11c22bfab9a81e1e057cc3d84769475c5da9873eb3f11edc6aca83ef486bfb63eba15a6233676d29d93ac9e774f10cd42c8cbd","other":"f360c6599a0911337c7b96365fda1b2f64890bdb4483bb7e86bca15484f24c4efc0d1f6f56aa0c4fa5c205e6c1dbbf20d2ca3c2f8734f703fe6d672fa76a0d45","up":true},{"one":"d0718ce0dafea66ee16c79626e020355273cdd062c0fceb122e391c4ca6e4e408a1b0e8230c4ade5bc95803916bdd6d98c99d2b6ea70c32e17fa1f2c98741a90","other":"af3f9dc00ce3cc156000f16a06c55c123ccdfabed89c9aee4478ff439b6f52a89d0501cff626d36b7f1852737955f7a036b25cf259580e8f46a3e0e44340b539","up":true},{"one":"f70c92be150cb3f65f6bd904c8c161bfb0cea717bab0b24da63714de83e0872c8c369960ada1629607a1e166a19b6cfa887603e4868e7912ae5512744e8cc1c0","other":"d563716fbe2068cc940f7b12dc2bacb345c95f01e78e3b1f0105a441f300fdb00cc72e677aec102360fb904b63055d8581555f5b74b8f2392706569d8357c53f","up":true},{"one":"d563716fbe2068cc940f7b12dc2bacb345c95f01e78e3b1f0105a441f300fdb00cc72e677aec102360fb904b63055d8581555f5b74b8f2392706569d8357c53f","other":"46bb2acc087482d40ab2ccbb387723158411ff4931423414e4d09891be8a31d11929e939e4be94b0cc355c49883e1835785ba1955d865f78748c2a0a2f6eee0a","up":true},{"one":"46bb2acc087482d40ab2ccbb387723158411ff4931423414e4d09891be8a31d11929e939e4be94b0cc355c49883e1835785ba1955d865f78748c2a0a2f6eee0a","other":"8da75cb4e63d968a7999ca4b49572b5ae592a91fa442d44bb7c42fb4b174a365e1affa1dbc45b2a0406444505f178100768e7783831f2886d53e7d1b8a3a7291","up":true},{"one":"8da75cb4e63d968a7999ca4b49572b5ae592a91fa442d44bb7c42fb4b174a365e1affa1dbc45b2a0406444505f178100768e7783831f2886d53e7d1b8a3a7291","other":"6d1af44ab259cc080a14c07bf5efabfd70cb847fe338f016c00138c84bddf6a6ce94047d1bffcfc7e9bc772dd7a080468a84655d5351d0056f97f13358b91547","up":true},{"one":"5b456e429f7adae30366206e681ba46439a3372fec3806f666425cb3f12983c0b427e089fb163b70e6a56220b1529ee392ff701bc2f4621d51e23aa6305150e8","other":"5e92b025cc087c8823423c287f274a32a3dc0065afdf189475ba96b0da7b785cd493b7f2a7f3bb8195c73025bfbb402cbb4e0f6ae0d5e0caab223193cf6f2e5c","up":true},{"one":"707a9ae4bc8b37fff43dc3ba83ecb735bd428b720a751a11112452eec1ca49c09139bc437666add2823dd205e45cc793f8657c66ccbc6911cc60771d4512e038","other":"78216c6660fff0b96e38084941a2f237996732118033bf842e5f9e533b22b36c2da996df28e866424311b7b6414d4627db1f22a235ae777f7de34d9696043ecb","up":true},{"one":"78216c6660fff0b96e38084941a2f237996732118033bf842e5f9e533b22b36c2da996df28e866424311b7b6414d4627db1f22a235ae777f7de34d9696043ecb","other":"d472383c453e6b0f1a632010bdd6c42a9668d328a8f8071e0407069f6fe413e2a0fd0551a09cc56ee5245d472e39a7b6295491dd256ae42e200a257f297743e3","up":true},{"one":"d472383c453e6b0f1a632010bdd6c42a9668d328a8f8071e0407069f6fe413e2a0fd0551a09cc56ee5245d472e39a7b6295491dd256ae42e200a257f297743e3","other":"351ceaf2e95e098a8e15e81c82073b523f641848326d1bbd379f40f886b50ce2c377c4e3a2dfc2662d6f25ac04dede41063a075cf00be1cf36f95b0267717ab8","up":true},{"one":"351ceaf2e95e098a8e15e81c82073b523f641848326d1bbd379f40f886b50ce2c377c4e3a2dfc2662d6f25ac04dede41063a075cf00be1cf36f95b0267717ab8","other":"8da9cdb3c78776ed230497b21d4ac172f0ce73e921dfddd483da7bc6bbcd1951dd78fd5f70a0acbad855b2984e4c4bdb408c4bc25cab40684fe5a4408ec7ab9c","up":true},{"one":"8da9cdb3c78776ed230497b21d4ac172f0ce73e921dfddd483da7bc6bbcd1951dd78fd5f70a0acbad855b2984e4c4bdb408c4bc25cab40684fe5a4408ec7ab9c","other":"0a45a0aa4b4eee71b2828c794281d698019667288cf51311ffae7d8ea895f8ae29f7958dbfcda8763d9d8e9c097dccc5f92ac9d09fb4ccbde178d7f5ebda4d35","up":true},{"one":"c73f8fe9f54b89634cb0e8e332407a3a90cbbd347c0abc93823db13a7a39c46e7bd30d3f557316d92dd731cfc686afc308448682ff06c77246e3fb02b9a025ba","other":"9529ff2b0692ad2608b55ec8ec0d1c9ccb8ee300412d99d389009162a76f7eec28d1090cbfb571aa8396b365074770b17106bfa3354857878dff164f42686142","up":true},{"one":"6d1af44ab259cc080a14c07bf5efabfd70cb847fe338f016c00138c84bddf6a6ce94047d1bffcfc7e9bc772dd7a080468a84655d5351d0056f97f13358b91547","other":"0dcef49b94fdcff024d706030fd4f513d0c6ad5f00b06a8b67abc454bbe5c2c74e939d491c0700e47ecee5cd7c7084603f62e626c34b454868b8f22d8c2dfb10","up":true},{"one":"0dcef49b94fdcff024d706030fd4f513d0c6ad5f00b06a8b67abc454bbe5c2c74e939d491c0700e47ecee5cd7c7084603f62e626c34b454868b8f22d8c2dfb10","other":"e7d4478b412ef497741943736946a3b0679d21ae0c4cbdde6809c7236dcf1a40291088d872e469f06da19ed4ef77b9844aee7066c40fcd45b0931aff847de1d7","up":true},{"one":"e7d4478b412ef497741943736946a3b0679d21ae0c4cbdde6809c7236dcf1a40291088d872e469f06da19ed4ef77b9844aee7066c40fcd45b0931aff847de1d7","other":"7722d7d06c66afb0642d5f9ae0b22ed812c632f2d62ce64315da40eb003feb3fae1b337c10df21d297beabe51b3879f2c0a725f08ee78a8e09c75f86bd0e2092","up":true},{"one":"5e92b025cc087c8823423c287f274a32a3dc0065afdf189475ba96b0da7b785cd493b7f2a7f3bb8195c73025bfbb402cbb4e0f6ae0d5e0caab223193cf6f2e5c","other":"f6e4b1dc1fa95ceae2b932b178afdc2dd515832a191e0f49c916d5a04548d58ef9f8c1dda3fbc93a45e6d82517e6a573310b7bfb14bc38c57000aec9ff010391","up":true},{"one":"9529ff2b0692ad2608b55ec8ec0d1c9ccb8ee300412d99d389009162a76f7eec28d1090cbfb571aa8396b365074770b17106bfa3354857878dff164f42686142","other":"5b456e429f7adae30366206e681ba46439a3372fec3806f666425cb3f12983c0b427e089fb163b70e6a56220b1529ee392ff701bc2f4621d51e23aa6305150e8","up":true},{"one":"f6e4b1dc1fa95ceae2b932b178afdc2dd515832a191e0f49c916d5a04548d58ef9f8c1dda3fbc93a45e6d82517e6a573310b7bfb14bc38c57000aec9ff010391","other":"707a9ae4bc8b37fff43dc3ba83ecb735bd428b720a751a11112452eec1ca49c09139bc437666add2823dd205e45cc793f8657c66ccbc6911cc60771d4512e038","up":true},{"one":"31cbd7c029d69715e59f31bccf362cd76e0a87839f1f63c6623be437d2af227a38f12c5fb9c659cc543976833caf22a52f5191c7c465a9ba36ac4235c12add72","other":"a48a667469a1344cb70f269b21fb3ca9e83823226749fd9c232be1b86ab9427888f2ecb20ddfa56da361463a061e192570f2f8da3fa967c473320ca85e382c53","up":true},{"one":"f5272b71c228eb14b9e0e221deefc0a91353a5f17d01475f57fad54bb8e50e375f58019c7200a9ca45b0f1da6538708c61242e478d917499871df7a9d5857f1a","other":"e53cfad611bc38a1090d28e4cc58e4738ccaa83a00bf5447cd30ec70e492dea5811b67e79b9ca8856e79801741a675c6f54eb7a1c39e95ab735164855eae0fb7","up":true},{"one":"43b91c24dd7fd217a76f00ab97920e4223bd2ee085abe7ac34e915e8676400e1643d3bbb4a864c8a6df1298bf229cabd1bdc9879eafdcbcab064708e8266e88d","other":"14136fa967f2d4825845ba4a43a5921d8fcf03f9c71c5595037e000b2ef6ff0a5eaad0980aea0a170cafda3529f982aea1107f58aa42485550c9480e86f5e9f3","up":true},{"one":"e53cfad611bc38a1090d28e4cc58e4738ccaa83a00bf5447cd30ec70e492dea5811b67e79b9ca8856e79801741a675c6f54eb7a1c39e95ab735164855eae0fb7","other":"4f1a219f31e135208bf4caa314a14d8d48a5682941793431539efb5666b06bb5e3e9cb29b019ca414fb32961460556f2d99a04b12dc8ecbf05f43efe108803f5","up":true},{"one":"4f1a219f31e135208bf4caa314a14d8d48a5682941793431539efb5666b06bb5e3e9cb29b019ca414fb32961460556f2d99a04b12dc8ecbf05f43efe108803f5","other":"25c64a52c298035be2184243082b5eba8a3a5d55c5334cea76e177d722945c8bf014a4ce9ef2ed76dc17a44234c97697337c6e001261533e72cc8266ee0e2fe4","up":true},{"one":"14136fa967f2d4825845ba4a43a5921d8fcf03f9c71c5595037e000b2ef6ff0a5eaad0980aea0a170cafda3529f982aea1107f58aa42485550c9480e86f5e9f3","other":"39d0aa13a6d7e709c9b914cb16f007c3f16af40532afa47c8cf9abf6d604d4380883103c995ec696ca593c4dc9bf0290979b965c9c6ade7c616d3973c5f0b1f0","up":true},{"one":"25c64a52c298035be2184243082b5eba8a3a5d55c5334cea76e177d722945c8bf014a4ce9ef2ed76dc17a44234c97697337c6e001261533e72cc8266ee0e2fe4","other":"1691538e4cc41441c18fc92969c0c59f51da063814e8c45311605405284293503ee1570722cc7ae12f9cd63b899afaf5b3e66ca012115996074e8aaa71fda48c","up":true},{"one":"39d0aa13a6d7e709c9b914cb16f007c3f16af40532afa47c8cf9abf6d604d4380883103c995ec696ca593c4dc9bf0290979b965c9c6ade7c616d3973c5f0b1f0","other":"e73af1e2a834ee132564dd2e983c877b3ae230808d2b42da2ec91472eee6ee6595c439800ce980186b4b0d9a56b96babf747006c07b07513543eead8e102fff7","up":true},{"one":"1691538e4cc41441c18fc92969c0c59f51da063814e8c45311605405284293503ee1570722cc7ae12f9cd63b899afaf5b3e66ca012115996074e8aaa71fda48c","other":"8e1a66c9029330c25b9abe95a11878f41cef1a32b567a931ffa781c2f70a1336efa03ba1a66dac0080304803c1239be443991a251f24d0e9c2e26aebeb5437f8","up":true},{"one":"e73af1e2a834ee132564dd2e983c877b3ae230808d2b42da2ec91472eee6ee6595c439800ce980186b4b0d9a56b96babf747006c07b07513543eead8e102fff7","other":"c0f2f1409cf83d7a777f6af95931181eb5a36b14a156f444075071c896fc5b435638ead23c65a242105db527c809e2c46f7805c862c0eb5d444749ddf22a5060","up":true},{"one":"8e1a66c9029330c25b9abe95a11878f41cef1a32b567a931ffa781c2f70a1336efa03ba1a66dac0080304803c1239be443991a251f24d0e9c2e26aebeb5437f8","other":"c8e9cc707ce2a278371d1b4f64714cdae425b7c3606d18af6588dacaca35c7a171a07629247af351e667d2ddd9e71598f862125c827cc869c463cf87e4daeed0","up":true},{"one":"c0f2f1409cf83d7a777f6af95931181eb5a36b14a156f444075071c896fc5b435638ead23c65a242105db527c809e2c46f7805c862c0eb5d444749ddf22a5060","other":"e021950ce89ce2bd79649aad2ed504789636b09870d0652fefa5e16631cb32a5d41c6cc4a540b7a0fca6bc3d5adf9b372a22cf714adc7b3e9b968d4c840017d4","up":true},{"one":"c8e9cc707ce2a278371d1b4f64714cdae425b7c3606d18af6588dacaca35c7a171a07629247af351e667d2ddd9e71598f862125c827cc869c463cf87e4daeed0","other":"43b91c24dd7fd217a76f00ab97920e4223bd2ee085abe7ac34e915e8676400e1643d3bbb4a864c8a6df1298bf229cabd1bdc9879eafdcbcab064708e8266e88d","up":true},{"one":"e021950ce89ce2bd79649aad2ed504789636b09870d0652fefa5e16631cb32a5d41c6cc4a540b7a0fca6bc3d5adf9b372a22cf714adc7b3e9b968d4c840017d4","other":"16bd57b6590df0c69c440d178da8359b0a3e00b9c5362155eae42709bdc4d0488e437fa7e8396d5b429cebe356ebd1407039b21eefa8d9164b357845132edb28","up":true},{"one":"16bd57b6590df0c69c440d178da8359b0a3e00b9c5362155eae42709bdc4d0488e437fa7e8396d5b429cebe356ebd1407039b21eefa8d9164b357845132edb28","other":"393eb8d2acf9244f1cdc220711c00d8fa7619394893643bc32e1ee0f821e5a2afed07badbdf97d710843c4ea6de3f74c113ad4c548afd23534d6dea5c37c6d9d","up":true},{"one":"393eb8d2acf9244f1cdc220711c00d8fa7619394893643bc32e1ee0f821e5a2afed07badbdf97d710843c4ea6de3f74c113ad4c548afd23534d6dea5c37c6d9d","other":"62b8e67a4ca956c1cf2ba7a538d39bfe8bccf747fe65be48c88270ad44ee7711c0e9a43bb3821feffc492dba9b58397768c755810121add9c980c9a2c696feb0","up":true},{"one":"62b8e67a4ca956c1cf2ba7a538d39bfe8bccf747fe65be48c88270ad44ee7711c0e9a43bb3821feffc492dba9b58397768c755810121add9c980c9a2c696feb0","other":"17c7eb5833687a98087daadda564e54b1c770f946efb7efd69370a9caf6e6939e408f04a3fa1aa042d9463992a711786e504072fae56d007d696851696fc5643","up":true},{"one":"17c7eb5833687a98087daadda564e54b1c770f946efb7efd69370a9caf6e6939e408f04a3fa1aa042d9463992a711786e504072fae56d007d696851696fc5643","other":"f5efffc8e894cecc065f6892ad2a846c8fc4982d1c8c7fc729421d5108d519c501cc9f2f7a0046ec08d47cf2369753aaf287dfc3ef7ecd34d24d294efb933658","up":true},{"one":"f5efffc8e894cecc065f6892ad2a846c8fc4982d1c8c7fc729421d5108d519c501cc9f2f7a0046ec08d47cf2369753aaf287dfc3ef7ecd34d24d294efb933658","other":"7c273dd4218e9e5b92e19d250832a424ff2ac5482ad70953746de780100669eb143247e15ccfca14cce9a49a003c82be71ca034a2900bed4c89fb10bdbfcc7c3","up":true},{"one":"7c273dd4218e9e5b92e19d250832a424ff2ac5482ad70953746de780100669eb143247e15ccfca14cce9a49a003c82be71ca034a2900bed4c89fb10bdbfcc7c3","other":"8959c5cf825ebab14efeacf2807ad9498256a9e89a2ef00690c9ee23a3e934e111c52a5ddcc791b93f49424ac008095d8cb0da6905dfdeb62309fc4f6672e59e","up":true},{"one":"8959c5cf825ebab14efeacf2807ad9498256a9e89a2ef00690c9ee23a3e934e111c52a5ddcc791b93f49424ac008095d8cb0da6905dfdeb62309fc4f6672e59e","other":"dcf2401cbc26f3db27bb85c24984b1d755b3503fe400c139a0bedbe5de24db3f27c8f4f40adc1880b6142d20e67a40f3d45d36ba7fce122ffa44703e65622198","up":true},{"one":"dcf2401cbc26f3db27bb85c24984b1d755b3503fe400c139a0bedbe5de24db3f27c8f4f40adc1880b6142d20e67a40f3d45d36ba7fce122ffa44703e65622198","other":"38b3adde25c6407f29c2a721f1f5c082cc94ddad09fc5afda2bbb2309212a9b54b1553731a65ec8b58769fc11d488169c8000ee15fe8966bd44a3879e0c9e534","up":true},{"one":"38b3adde25c6407f29c2a721f1f5c082cc94ddad09fc5afda2bbb2309212a9b54b1553731a65ec8b58769fc11d488169c8000ee15fe8966bd44a3879e0c9e534","other":"6593097e880701f3d0573df7bff9ba7af40f4f83b828bfc11bdabea62fb94ed39c8233d8d40275c2af9ceddae44514e029a546fe9df73abbd3821d37933aba49","up":true},{"one":"6593097e880701f3d0573df7bff9ba7af40f4f83b828bfc11bdabea62fb94ed39c8233d8d40275c2af9ceddae44514e029a546fe9df73abbd3821d37933aba49","other":"578666c4113e196a7c738fdbae0bd68ade450283eb835efd06591798f1893f7f7d9cde0691faff670b5ae24e58cbc2f549d2196f244dddc00e82852c38e8539e","up":true},{"one":"578666c4113e196a7c738fdbae0bd68ade450283eb835efd06591798f1893f7f7d9cde0691faff670b5ae24e58cbc2f549d2196f244dddc00e82852c38e8539e","other":"e1082b4577aa370a5171b7602282208697dcead854f0c82acb5628d179fa5990a0fc85c5343a47177aab81c7fa6c1be8a27a3484acddc353582ddeb61892ef94","up":true},{"one":"e1082b4577aa370a5171b7602282208697dcead854f0c82acb5628d179fa5990a0fc85c5343a47177aab81c7fa6c1be8a27a3484acddc353582ddeb61892ef94","other":"a4fbd2ffc25d2c3bd37beecd637dda5983cb5817ecb6da62aec16ea59aaf7e71966649211461564ba808174361898a1d2265f1a42e94434bc00d5d3e04b67a8a","up":true},{"one":"a4fbd2ffc25d2c3bd37beecd637dda5983cb5817ecb6da62aec16ea59aaf7e71966649211461564ba808174361898a1d2265f1a42e94434bc00d5d3e04b67a8a","other":"eb08a7774ca5252237d059a8bbad68044c83b2c332024be98bdc0c58508867a80cd34cb4162bd55a47fecc93301c8b2a7a1edbfd807ebb5623499cac80ea42de","up":true},{"one":"d0718ce0dafea66ee16c79626e020355273cdd062c0fceb122e391c4ca6e4e408a1b0e8230c4ade5bc95803916bdd6d98c99d2b6ea70c32e17fa1f2c98741a90","other":"8f6fb4a5baf715e001b060ce72378829279ce06a3247bd4a6faa3c725ee1b949570373e4231de82981020563e704297e77172506101b1444fcacfcc5f211827e","up":true},{"one":"eb08a7774ca5252237d059a8bbad68044c83b2c332024be98bdc0c58508867a80cd34cb4162bd55a47fecc93301c8b2a7a1edbfd807ebb5623499cac80ea42de","other":"6eeb951b8f6d5ac519132910222777d5a409325e6c64d89708a00e55cb0fe85889aac1baa724e29fa7f064323b164a9c40c5114a65736e3dd16f0336283d9c7b","up":true},{"one":"6eeb951b8f6d5ac519132910222777d5a409325e6c64d89708a00e55cb0fe85889aac1baa724e29fa7f064323b164a9c40c5114a65736e3dd16f0336283d9c7b","other":"6419279b600da3e2ee8d0b2a5b0319bc6cd496086955b49a8d2168fd4c35d5688291bc9313076b1b8e070f25dc593788d72b8f8c1d2ad828741a45deea35e58d","up":true},{"one":"6419279b600da3e2ee8d0b2a5b0319bc6cd496086955b49a8d2168fd4c35d5688291bc9313076b1b8e070f25dc593788d72b8f8c1d2ad828741a45deea35e58d","other":"032b1ce6881413b7ade1918e56691c7acd9f24111f47792ca50c33e570afba433caa132ad2326d03f9c0544fdc09fa0ca65f61de9fe61d6dd92c5d25a8df69af","up":true},{"one":"032b1ce6881413b7ade1918e56691c7acd9f24111f47792ca50c33e570afba433caa132ad2326d03f9c0544fdc09fa0ca65f61de9fe61d6dd92c5d25a8df69af","other":"86d55ece15e6bb4da7601f6587654505f760ee2b87abdb115091eefa93f61cf29fd695601bb8c6ae2c76400de24b8bca9ca32b50e4b849ae76f5320b03276bfc","up":true},{"one":"86d55ece15e6bb4da7601f6587654505f760ee2b87abdb115091eefa93f61cf29fd695601bb8c6ae2c76400de24b8bca9ca32b50e4b849ae76f5320b03276bfc","other":"31cbd7c029d69715e59f31bccf362cd76e0a87839f1f63c6623be437d2af227a38f12c5fb9c659cc543976833caf22a52f5191c7c465a9ba36ac4235c12add72","up":true},{"one":"a48a667469a1344cb70f269b21fb3ca9e83823226749fd9c232be1b86ab9427888f2ecb20ddfa56da361463a061e192570f2f8da3fa967c473320ca85e382c53","other":"e7b1563d6e089e030983b075b590abb8a3205e9bce953f562b755ba150a3edc2dc3377259d96c05cc7363a23aed613711ca049e26253fd9273ac4c0483087015","up":true},{"one":"46bb2acc087482d40ab2ccbb387723158411ff4931423414e4d09891be8a31d11929e939e4be94b0cc355c49883e1835785ba1955d865f78748c2a0a2f6eee0a","other":"6d1af44ab259cc080a14c07bf5efabfd70cb847fe338f016c00138c84bddf6a6ce94047d1bffcfc7e9bc772dd7a080468a84655d5351d0056f97f13358b91547","up":true},{"one":"d472383c453e6b0f1a632010bdd6c42a9668d328a8f8071e0407069f6fe413e2a0fd0551a09cc56ee5245d472e39a7b6295491dd256ae42e200a257f297743e3","other":"8da9cdb3c78776ed230497b21d4ac172f0ce73e921dfddd483da7bc6bbcd1951dd78fd5f70a0acbad855b2984e4c4bdb408c4bc25cab40684fe5a4408ec7ab9c","up":true},{"one":"78216c6660fff0b96e38084941a2f237996732118033bf842e5f9e533b22b36c2da996df28e866424311b7b6414d4627db1f22a235ae777f7de34d9696043ecb","other":"8da9cdb3c78776ed230497b21d4ac172f0ce73e921dfddd483da7bc6bbcd1951dd78fd5f70a0acbad855b2984e4c4bdb408c4bc25cab40684fe5a4408ec7ab9c","up":true},{"one":"7a45fa46f161fae3ef9013e9ab81145f4a76fa6ae22160424d6dc111acbd477ce43d4c10db89cb7451c97ea1fbd78428997d01fd17e1851f8b559b404ede6da7","other":"25c64a52c298035be2184243082b5eba8a3a5d55c5334cea76e177d722945c8bf014a4ce9ef2ed76dc17a44234c97697337c6e001261533e72cc8266ee0e2fe4","up":true},{"one":"0a45a0aa4b4eee71b2828c794281d698019667288cf51311ffae7d8ea895f8ae29f7958dbfcda8763d9d8e9c097dccc5f92ac9d09fb4ccbde178d7f5ebda4d35","other":"351ceaf2e95e098a8e15e81c82073b523f641848326d1bbd379f40f886b50ce2c377c4e3a2dfc2662d6f25ac04dede41063a075cf00be1cf36f95b0267717ab8","up":true},{"one":"43b91c24dd7fd217a76f00ab97920e4223bd2ee085abe7ac34e915e8676400e1643d3bbb4a864c8a6df1298bf229cabd1bdc9879eafdcbcab064708e8266e88d","other":"1691538e4cc41441c18fc92969c0c59f51da063814e8c45311605405284293503ee1570722cc7ae12f9cd63b899afaf5b3e66ca012115996074e8aaa71fda48c","up":true},{"one":"d563716fbe2068cc940f7b12dc2bacb345c95f01e78e3b1f0105a441f300fdb00cc72e677aec102360fb904b63055d8581555f5b74b8f2392706569d8357c53f","other":"7722d7d06c66afb0642d5f9ae0b22ed812c632f2d62ce64315da40eb003feb3fae1b337c10df21d297beabe51b3879f2c0a725f08ee78a8e09c75f86bd0e2092","up":true},{"one":"39d0aa13a6d7e709c9b914cb16f007c3f16af40532afa47c8cf9abf6d604d4380883103c995ec696ca593c4dc9bf0290979b965c9c6ade7c616d3973c5f0b1f0","other":"c0f2f1409cf83d7a777f6af95931181eb5a36b14a156f444075071c896fc5b435638ead23c65a242105db527c809e2c46f7805c862c0eb5d444749ddf22a5060","up":true},{"one":"16bd57b6590df0c69c440d178da8359b0a3e00b9c5362155eae42709bdc4d0488e437fa7e8396d5b429cebe356ebd1407039b21eefa8d9164b357845132edb28","other":"8959c5cf825ebab14efeacf2807ad9498256a9e89a2ef00690c9ee23a3e934e111c52a5ddcc791b93f49424ac008095d8cb0da6905dfdeb62309fc4f6672e59e","up":true},{"one":"393eb8d2acf9244f1cdc220711c00d8fa7619394893643bc32e1ee0f821e5a2afed07badbdf97d710843c4ea6de3f74c113ad4c548afd23534d6dea5c37c6d9d","other":"e73af1e2a834ee132564dd2e983c877b3ae230808d2b42da2ec91472eee6ee6595c439800ce980186b4b0d9a56b96babf747006c07b07513543eead8e102fff7","up":true},{"one":"6593097e880701f3d0573df7bff9ba7af40f4f83b828bfc11bdabea62fb94ed39c8233d8d40275c2af9ceddae44514e029a546fe9df73abbd3821d37933aba49","other":"a4fbd2ffc25d2c3bd37beecd637dda5983cb5817ecb6da62aec16ea59aaf7e71966649211461564ba808174361898a1d2265f1a42e94434bc00d5d3e04b67a8a","up":true},{"one":"17c7eb5833687a98087daadda564e54b1c770f946efb7efd69370a9caf6e6939e408f04a3fa1aa042d9463992a711786e504072fae56d007d696851696fc5643","other":"39d0aa13a6d7e709c9b914cb16f007c3f16af40532afa47c8cf9abf6d604d4380883103c995ec696ca593c4dc9bf0290979b965c9c6ade7c616d3973c5f0b1f0","up":true},{"one":"38b3adde25c6407f29c2a721f1f5c082cc94ddad09fc5afda2bbb2309212a9b54b1553731a65ec8b58769fc11d488169c8000ee15fe8966bd44a3879e0c9e534","other":"8959c5cf825ebab14efeacf2807ad9498256a9e89a2ef00690c9ee23a3e934e111c52a5ddcc791b93f49424ac008095d8cb0da6905dfdeb62309fc4f6672e59e","up":true},{"one":"31cbd7c029d69715e59f31bccf362cd76e0a87839f1f63c6623be437d2af227a38f12c5fb9c659cc543976833caf22a52f5191c7c465a9ba36ac4235c12add72","other":"8f6fb4a5baf715e001b060ce72378829279ce06a3247bd4a6faa3c725ee1b949570373e4231de82981020563e704297e77172506101b1444fcacfcc5f211827e","up":true},{"one":"e7d4478b412ef497741943736946a3b0679d21ae0c4cbdde6809c7236dcf1a40291088d872e469f06da19ed4ef77b9844aee7066c40fcd45b0931aff847de1d7","other":"f360c6599a0911337c7b96365fda1b2f64890bdb4483bb7e86bca15484f24c4efc0d1f6f56aa0c4fa5c205e6c1dbbf20d2ca3c2f8734f703fe6d672fa76a0d45","up":true},{"one":"dcf2401cbc26f3db27bb85c24984b1d755b3503fe400c139a0bedbe5de24db3f27c8f4f40adc1880b6142d20e67a40f3d45d36ba7fce122ffa44703e65622198","other":"16bd57b6590df0c69c440d178da8359b0a3e00b9c5362155eae42709bdc4d0488e437fa7e8396d5b429cebe356ebd1407039b21eefa8d9164b357845132edb28","up":true},{"one":"8da9cdb3c78776ed230497b21d4ac172f0ce73e921dfddd483da7bc6bbcd1951dd78fd5f70a0acbad855b2984e4c4bdb408c4bc25cab40684fe5a4408ec7ab9c","other":"f70c92be150cb3f65f6bd904c8c161bfb0cea717bab0b24da63714de83e0872c8c369960ada1629607a1e166a19b6cfa887603e4868e7912ae5512744e8cc1c0","up":true},{"one":"5e92b025cc087c8823423c287f274a32a3dc0065afdf189475ba96b0da7b785cd493b7f2a7f3bb8195c73025bfbb402cbb4e0f6ae0d5e0caab223193cf6f2e5c","other":"e7b1563d6e089e030983b075b590abb8a3205e9bce953f562b755ba150a3edc2dc3377259d96c05cc7363a23aed613711ca049e26253fd9273ac4c0483087015","up":true},{"one":"95c3ca2362de2eb0ac8efdd243918ed216f5d124bc6f5b9d83a6ee1aaf8a0fbdbd70ca1710d1ed825d6871f13a15954725f1aa1b27b48307844c0bc27baec0db","other":"5b456e429f7adae30366206e681ba46439a3372fec3806f666425cb3f12983c0b427e089fb163b70e6a56220b1529ee392ff701bc2f4621d51e23aa6305150e8","up":true},{"one":"61b32cded1b5ea3e2ca545a55c84251daaaacf51e6fed98fbdf4c5b6b91a554081e1e577aaaaaa4f911780f92703c1d715695d86c1be641b0bd1794f4107c2be","other":"25c64a52c298035be2184243082b5eba8a3a5d55c5334cea76e177d722945c8bf014a4ce9ef2ed76dc17a44234c97697337c6e001261533e72cc8266ee0e2fe4","up":true},{"one":"a48a667469a1344cb70f269b21fb3ca9e83823226749fd9c232be1b86ab9427888f2ecb20ddfa56da361463a061e192570f2f8da3fa967c473320ca85e382c53","other":"5e92b025cc087c8823423c287f274a32a3dc0065afdf189475ba96b0da7b785cd493b7f2a7f3bb8195c73025bfbb402cbb4e0f6ae0d5e0caab223193cf6f2e5c","up":true},{"one":"af3f9dc00ce3cc156000f16a06c55c123ccdfabed89c9aee4478ff439b6f52a89d0501cff626d36b7f1852737955f7a036b25cf259580e8f46a3e0e44340b539","other":"f6e4b1dc1fa95ceae2b932b178afdc2dd515832a191e0f49c916d5a04548d58ef9f8c1dda3fbc93a45e6d82517e6a573310b7bfb14bc38c57000aec9ff010391","up":true},{"one":"d0718ce0dafea66ee16c79626e020355273cdd062c0fceb122e391c4ca6e4e408a1b0e8230c4ade5bc95803916bdd6d98c99d2b6ea70c32e17fa1f2c98741a90","other":"86d55ece15e6bb4da7601f6587654505f760ee2b87abdb115091eefa93f61cf29fd695601bb8c6ae2c76400de24b8bca9ca32b50e4b849ae76f5320b03276bfc","up":true},{"one":"95c3ca2362de2eb0ac8efdd243918ed216f5d124bc6f5b9d83a6ee1aaf8a0fbdbd70ca1710d1ed825d6871f13a15954725f1aa1b27b48307844c0bc27baec0db","other":"8da9cdb3c78776ed230497b21d4ac172f0ce73e921dfddd483da7bc6bbcd1951dd78fd5f70a0acbad855b2984e4c4bdb408c4bc25cab40684fe5a4408ec7ab9c","up":true},{"one":"78216c6660fff0b96e38084941a2f237996732118033bf842e5f9e533b22b36c2da996df28e866424311b7b6414d4627db1f22a235ae777f7de34d9696043ecb","other":"9529ff2b0692ad2608b55ec8ec0d1c9ccb8ee300412d99d389009162a76f7eec28d1090cbfb571aa8396b365074770b17106bfa3354857878dff164f42686142","up":true},{"one":"62b8e67a4ca956c1cf2ba7a538d39bfe8bccf747fe65be48c88270ad44ee7711c0e9a43bb3821feffc492dba9b58397768c755810121add9c980c9a2c696feb0","other":"39d0aa13a6d7e709c9b914cb16f007c3f16af40532afa47c8cf9abf6d604d4380883103c995ec696ca593c4dc9bf0290979b965c9c6ade7c616d3973c5f0b1f0","up":true},{"one":"5e92b025cc087c8823423c287f274a32a3dc0065afdf189475ba96b0da7b785cd493b7f2a7f3bb8195c73025bfbb402cbb4e0f6ae0d5e0caab223193cf6f2e5c","other":"86d55ece15e6bb4da7601f6587654505f760ee2b87abdb115091eefa93f61cf29fd695601bb8c6ae2c76400de24b8bca9ca32b50e4b849ae76f5320b03276bfc","up":true},{"one":"d472383c453e6b0f1a632010bdd6c42a9668d328a8f8071e0407069f6fe413e2a0fd0551a09cc56ee5245d472e39a7b6295491dd256ae42e200a257f297743e3","other":"9529ff2b0692ad2608b55ec8ec0d1c9ccb8ee300412d99d389009162a76f7eec28d1090cbfb571aa8396b365074770b17106bfa3354857878dff164f42686142","up":true},{"one":"8da9cdb3c78776ed230497b21d4ac172f0ce73e921dfddd483da7bc6bbcd1951dd78fd5f70a0acbad855b2984e4c4bdb408c4bc25cab40684fe5a4408ec7ab9c","other":"e479930845e1dac2d5908894548cc06c132fc5820810c6f46d9adc2bc252dd40b64642a3b2005ad3688d2637c43967f570bd153db9ee6742e1b23dbfb72537fa","up":true},{"one":"c73f8fe9f54b89634cb0e8e332407a3a90cbbd347c0abc93823db13a7a39c46e7bd30d3f557316d92dd731cfc686afc308448682ff06c77246e3fb02b9a025ba","other":"af3f9dc00ce3cc156000f16a06c55c123ccdfabed89c9aee4478ff439b6f52a89d0501cff626d36b7f1852737955f7a036b25cf259580e8f46a3e0e44340b539","up":true},{"one":"0a45a0aa4b4eee71b2828c794281d698019667288cf51311ffae7d8ea895f8ae29f7958dbfcda8763d9d8e9c097dccc5f92ac9d09fb4ccbde178d7f5ebda4d35","other":"46bb2acc087482d40ab2ccbb387723158411ff4931423414e4d09891be8a31d11929e939e4be94b0cc355c49883e1835785ba1955d865f78748c2a0a2f6eee0a","up":true},{"one":"d563716fbe2068cc940f7b12dc2bacb345c95f01e78e3b1f0105a441f300fdb00cc72e677aec102360fb904b63055d8581555f5b74b8f2392706569d8357c53f","other":"351ceaf2e95e098a8e15e81c82073b523f641848326d1bbd379f40f886b50ce2c377c4e3a2dfc2662d6f25ac04dede41063a075cf00be1cf36f95b0267717ab8","up":true},{"one":"25c64a52c298035be2184243082b5eba8a3a5d55c5334cea76e177d722945c8bf014a4ce9ef2ed76dc17a44234c97697337c6e001261533e72cc8266ee0e2fe4","other":"9e51eb48f59886e70eb8d02e1c0c4423de3f0ce79c7a62bfd91bc2048cf643f40a91e2d2a1a8a19a9e4ba4a96aed0965aefcd941c068208abe8bf5029eb27d55","up":true},{"one":"e7d4478b412ef497741943736946a3b0679d21ae0c4cbdde6809c7236dcf1a40291088d872e469f06da19ed4ef77b9844aee7066c40fcd45b0931aff847de1d7","other":"e479930845e1dac2d5908894548cc06c132fc5820810c6f46d9adc2bc252dd40b64642a3b2005ad3688d2637c43967f570bd153db9ee6742e1b23dbfb72537fa","up":true},{"one":"7722d7d06c66afb0642d5f9ae0b22ed812c632f2d62ce64315da40eb003feb3fae1b337c10df21d297beabe51b3879f2c0a725f08ee78a8e09c75f86bd0e2092","other":"707a9ae4bc8b37fff43dc3ba83ecb735bd428b720a751a11112452eec1ca49c09139bc437666add2823dd205e45cc793f8657c66ccbc6911cc60771d4512e038","up":true},{"one":"f5efffc8e894cecc065f6892ad2a846c8fc4982d1c8c7fc729421d5108d519c501cc9f2f7a0046ec08d47cf2369753aaf287dfc3ef7ecd34d24d294efb933658","other":"a4fbd2ffc25d2c3bd37beecd637dda5983cb5817ecb6da62aec16ea59aaf7e71966649211461564ba808174361898a1d2265f1a42e94434bc00d5d3e04b67a8a","up":true},{"one":"61b32cded1b5ea3e2ca545a55c84251daaaacf51e6fed98fbdf4c5b6b91a554081e1e577aaaaaa4f911780f92703c1d715695d86c1be641b0bd1794f4107c2be","other":"7a45fa46f161fae3ef9013e9ab81145f4a76fa6ae22160424d6dc111acbd477ce43d4c10db89cb7451c97ea1fbd78428997d01fd17e1851f8b559b404ede6da7","up":true},{"one":"f5272b71c228eb14b9e0e221deefc0a91353a5f17d01475f57fad54bb8e50e375f58019c7200a9ca45b0f1da6538708c61242e478d917499871df7a9d5857f1a","other":"7a45fa46f161fae3ef9013e9ab81145f4a76fa6ae22160424d6dc111acbd477ce43d4c10db89cb7451c97ea1fbd78428997d01fd17e1851f8b559b404ede6da7","up":true},{"one":"7a45fa46f161fae3ef9013e9ab81145f4a76fa6ae22160424d6dc111acbd477ce43d4c10db89cb7451c97ea1fbd78428997d01fd17e1851f8b559b404ede6da7","other":"9e51eb48f59886e70eb8d02e1c0c4423de3f0ce79c7a62bfd91bc2048cf643f40a91e2d2a1a8a19a9e4ba4a96aed0965aefcd941c068208abe8bf5029eb27d55","up":true},{"one":"46bb2acc087482d40ab2ccbb387723158411ff4931423414e4d09891be8a31d11929e939e4be94b0cc355c49883e1835785ba1955d865f78748c2a0a2f6eee0a","other":"351ceaf2e95e098a8e15e81c82073b523f641848326d1bbd379f40f886b50ce2c377c4e3a2dfc2662d6f25ac04dede41063a075cf00be1cf36f95b0267717ab8","up":true},{"one":"6eeb951b8f6d5ac519132910222777d5a409325e6c64d89708a00e55cb0fe85889aac1baa724e29fa7f064323b164a9c40c5114a65736e3dd16f0336283d9c7b","other":"dcf2401cbc26f3db27bb85c24984b1d755b3503fe400c139a0bedbe5de24db3f27c8f4f40adc1880b6142d20e67a40f3d45d36ba7fce122ffa44703e65622198","up":true},{"one":"e73af1e2a834ee132564dd2e983c877b3ae230808d2b42da2ec91472eee6ee6595c439800ce980186b4b0d9a56b96babf747006c07b07513543eead8e102fff7","other":"62b8e67a4ca956c1cf2ba7a538d39bfe8bccf747fe65be48c88270ad44ee7711c0e9a43bb3821feffc492dba9b58397768c755810121add9c980c9a2c696feb0","up":true},{"one":"6593097e880701f3d0573df7bff9ba7af40f4f83b828bfc11bdabea62fb94ed39c8233d8d40275c2af9ceddae44514e029a546fe9df73abbd3821d37933aba49","other":"af3f9dc00ce3cc156000f16a06c55c123ccdfabed89c9aee4478ff439b6f52a89d0501cff626d36b7f1852737955f7a036b25cf259580e8f46a3e0e44340b539","up":true},{"one":"f70c92be150cb3f65f6bd904c8c161bfb0cea717bab0b24da63714de83e0872c8c369960ada1629607a1e166a19b6cfa887603e4868e7912ae5512744e8cc1c0","other":"9e51eb48f59886e70eb8d02e1c0c4423de3f0ce79c7a62bfd91bc2048cf643f40a91e2d2a1a8a19a9e4ba4a96aed0965aefcd941c068208abe8bf5029eb27d55","up":true},{"one":"6eeb951b8f6d5ac519132910222777d5a409325e6c64d89708a00e55cb0fe85889aac1baa724e29fa7f064323b164a9c40c5114a65736e3dd16f0336283d9c7b","other":"8f6fb4a5baf715e001b060ce72378829279ce06a3247bd4a6faa3c725ee1b949570373e4231de82981020563e704297e77172506101b1444fcacfcc5f211827e","up":true},{"one":"31cbd7c029d69715e59f31bccf362cd76e0a87839f1f63c6623be437d2af227a38f12c5fb9c659cc543976833caf22a52f5191c7c465a9ba36ac4235c12add72","other":"032b1ce6881413b7ade1918e56691c7acd9f24111f47792ca50c33e570afba433caa132ad2326d03f9c0544fdc09fa0ca65f61de9fe61d6dd92c5d25a8df69af","up":true},{"one":"393eb8d2acf9244f1cdc220711c00d8fa7619394893643bc32e1ee0f821e5a2afed07badbdf97d710843c4ea6de3f74c113ad4c548afd23534d6dea5c37c6d9d","other":"39d0aa13a6d7e709c9b914cb16f007c3f16af40532afa47c8cf9abf6d604d4380883103c995ec696ca593c4dc9bf0290979b965c9c6ade7c616d3973c5f0b1f0","up":true},{"one":"4f1a219f31e135208bf4caa314a14d8d48a5682941793431539efb5666b06bb5e3e9cb29b019ca414fb32961460556f2d99a04b12dc8ecbf05f43efe108803f5","other":"9e51eb48f59886e70eb8d02e1c0c4423de3f0ce79c7a62bfd91bc2048cf643f40a91e2d2a1a8a19a9e4ba4a96aed0965aefcd941c068208abe8bf5029eb27d55","up":true},{"one":"62b8e67a4ca956c1cf2ba7a538d39bfe8bccf747fe65be48c88270ad44ee7711c0e9a43bb3821feffc492dba9b58397768c755810121add9c980c9a2c696feb0","other":"8f6fb4a5baf715e001b060ce72378829279ce06a3247bd4a6faa3c725ee1b949570373e4231de82981020563e704297e77172506101b1444fcacfcc5f211827e","up":true},{"one":"25c64a52c298035be2184243082b5eba8a3a5d55c5334cea76e177d722945c8bf014a4ce9ef2ed76dc17a44234c97697337c6e001261533e72cc8266ee0e2fe4","other":"39d0aa13a6d7e709c9b914cb16f007c3f16af40532afa47c8cf9abf6d604d4380883103c995ec696ca593c4dc9bf0290979b965c9c6ade7c616d3973c5f0b1f0","up":true},{"one":"38b3adde25c6407f29c2a721f1f5c082cc94ddad09fc5afda2bbb2309212a9b54b1553731a65ec8b58769fc11d488169c8000ee15fe8966bd44a3879e0c9e534","other":"6419279b600da3e2ee8d0b2a5b0319bc6cd496086955b49a8d2168fd4c35d5688291bc9313076b1b8e070f25dc593788d72b8f8c1d2ad828741a45deea35e58d","up":true},{"one":"43b91c24dd7fd217a76f00ab97920e4223bd2ee085abe7ac34e915e8676400e1643d3bbb4a864c8a6df1298bf229cabd1bdc9879eafdcbcab064708e8266e88d","other":"7722d7d06c66afb0642d5f9ae0b22ed812c632f2d62ce64315da40eb003feb3fae1b337c10df21d297beabe51b3879f2c0a725f08ee78a8e09c75f86bd0e2092","up":true},{"one":"16bd57b6590df0c69c440d178da8359b0a3e00b9c5362155eae42709bdc4d0488e437fa7e8396d5b429cebe356ebd1407039b21eefa8d9164b357845132edb28","other":"eb08a7774ca5252237d059a8bbad68044c83b2c332024be98bdc0c58508867a80cd34cb4162bd55a47fecc93301c8b2a7a1edbfd807ebb5623499cac80ea42de","up":true},{"one":"17c7eb5833687a98087daadda564e54b1c770f946efb7efd69370a9caf6e6939e408f04a3fa1aa042d9463992a711786e504072fae56d007d696851696fc5643","other":"8f6fb4a5baf715e001b060ce72378829279ce06a3247bd4a6faa3c725ee1b949570373e4231de82981020563e704297e77172506101b1444fcacfcc5f211827e","up":true},{"one":"f5efffc8e894cecc065f6892ad2a846c8fc4982d1c8c7fc729421d5108d519c501cc9f2f7a0046ec08d47cf2369753aaf287dfc3ef7ecd34d24d294efb933658","other":"c0f2f1409cf83d7a777f6af95931181eb5a36b14a156f444075071c896fc5b435638ead23c65a242105db527c809e2c46f7805c862c0eb5d444749ddf22a5060","up":true},{"one":"14136fa967f2d4825845ba4a43a5921d8fcf03f9c71c5595037e000b2ef6ff0a5eaad0980aea0a170cafda3529f982aea1107f58aa42485550c9480e86f5e9f3","other":"7c273dd4218e9e5b92e19d250832a424ff2ac5482ad70953746de780100669eb143247e15ccfca14cce9a49a003c82be71ca034a2900bed4c89fb10bdbfcc7c3","up":true},{"one":"f360c6599a0911337c7b96365fda1b2f64890bdb4483bb7e86bca15484f24c4efc0d1f6f56aa0c4fa5c205e6c1dbbf20d2ca3c2f8734f703fe6d672fa76a0d45","other":"1691538e4cc41441c18fc92969c0c59f51da063814e8c45311605405284293503ee1570722cc7ae12f9cd63b899afaf5b3e66ca012115996074e8aaa71fda48c","up":true},{"one":"dcf2401cbc26f3db27bb85c24984b1d755b3503fe400c139a0bedbe5de24db3f27c8f4f40adc1880b6142d20e67a40f3d45d36ba7fce122ffa44703e65622198","other":"8f6fb4a5baf715e001b060ce72378829279ce06a3247bd4a6faa3c725ee1b949570373e4231de82981020563e704297e77172506101b1444fcacfcc5f211827e","up":true},{"one":"5b456e429f7adae30366206e681ba46439a3372fec3806f666425cb3f12983c0b427e089fb163b70e6a56220b1529ee392ff701bc2f4621d51e23aa6305150e8","other":"8da9cdb3c78776ed230497b21d4ac172f0ce73e921dfddd483da7bc6bbcd1951dd78fd5f70a0acbad855b2984e4c4bdb408c4bc25cab40684fe5a4408ec7ab9c","up":true},{"one":"f5272b71c228eb14b9e0e221deefc0a91353a5f17d01475f57fad54bb8e50e375f58019c7200a9ca45b0f1da6538708c61242e478d917499871df7a9d5857f1a","other":"61b32cded1b5ea3e2ca545a55c84251daaaacf51e6fed98fbdf4c5b6b91a554081e1e577aaaaaa4f911780f92703c1d715695d86c1be641b0bd1794f4107c2be","up":true},{"one":"6d1af44ab259cc080a14c07bf5efabfd70cb847fe338f016c00138c84bddf6a6ce94047d1bffcfc7e9bc772dd7a080468a84655d5351d0056f97f13358b91547","other":"0a45a0aa4b4eee71b2828c794281d698019667288cf51311ffae7d8ea895f8ae29f7958dbfcda8763d9d8e9c097dccc5f92ac9d09fb4ccbde178d7f5ebda4d35","up":true},{"one":"e021950ce89ce2bd79649aad2ed504789636b09870d0652fefa5e16631cb32a5d41c6cc4a540b7a0fca6bc3d5adf9b372a22cf714adc7b3e9b968d4c840017d4","other":"c8e9cc707ce2a278371d1b4f64714cdae425b7c3606d18af6588dacaca35c7a171a07629247af351e667d2ddd9e71598f862125c827cc869c463cf87e4daeed0","up":true},{"one":"707a9ae4bc8b37fff43dc3ba83ecb735bd428b720a751a11112452eec1ca49c09139bc437666add2823dd205e45cc793f8657c66ccbc6911cc60771d4512e038","other":"d563716fbe2068cc940f7b12dc2bacb345c95f01e78e3b1f0105a441f300fdb00cc72e677aec102360fb904b63055d8581555f5b74b8f2392706569d8357c53f","up":true},{"one":"8da75cb4e63d968a7999ca4b49572b5ae592a91fa442d44bb7c42fb4b174a365e1affa1dbc45b2a0406444505f178100768e7783831f2886d53e7d1b8a3a7291","other":"0dcef49b94fdcff024d706030fd4f513d0c6ad5f00b06a8b67abc454bbe5c2c74e939d491c0700e47ecee5cd7c7084603f62e626c34b454868b8f22d8c2dfb10","up":true},{"one":"9529ff2b0692ad2608b55ec8ec0d1c9ccb8ee300412d99d389009162a76f7eec28d1090cbfb571aa8396b365074770b17106bfa3354857878dff164f42686142","other":"6419279b600da3e2ee8d0b2a5b0319bc6cd496086955b49a8d2168fd4c35d5688291bc9313076b1b8e070f25dc593788d72b8f8c1d2ad828741a45deea35e58d","up":true},{"one":"0dcef49b94fdcff024d706030fd4f513d0c6ad5f00b06a8b67abc454bbe5c2c74e939d491c0700e47ecee5cd7c7084603f62e626c34b454868b8f22d8c2dfb10","other":"f6e4b1dc1fa95ceae2b932b178afdc2dd515832a191e0f49c916d5a04548d58ef9f8c1dda3fbc93a45e6d82517e6a573310b7bfb14bc38c57000aec9ff010391","up":true},{"one":"6419279b600da3e2ee8d0b2a5b0319bc6cd496086955b49a8d2168fd4c35d5688291bc9313076b1b8e070f25dc593788d72b8f8c1d2ad828741a45deea35e58d","other":"78216c6660fff0b96e38084941a2f237996732118033bf842e5f9e533b22b36c2da996df28e866424311b7b6414d4627db1f22a235ae777f7de34d9696043ecb","up":true},{"one":"c8e9cc707ce2a278371d1b4f64714cdae425b7c3606d18af6588dacaca35c7a171a07629247af351e667d2ddd9e71598f862125c827cc869c463cf87e4daeed0","other":"5b456e429f7adae30366206e681ba46439a3372fec3806f666425cb3f12983c0b427e089fb163b70e6a56220b1529ee392ff701bc2f4621d51e23aa6305150e8","up":true},{"one":"a48a667469a1344cb70f269b21fb3ca9e83823226749fd9c232be1b86ab9427888f2ecb20ddfa56da361463a061e192570f2f8da3fa967c473320ca85e382c53","other":"6593097e880701f3d0573df7bff9ba7af40f4f83b828bfc11bdabea62fb94ed39c8233d8d40275c2af9ceddae44514e029a546fe9df73abbd3821d37933aba49","up":true},{"one":"707a9ae4bc8b37fff43dc3ba83ecb735bd428b720a751a11112452eec1ca49c09139bc437666add2823dd205e45cc793f8657c66ccbc6911cc60771d4512e038","other":"43b91c24dd7fd217a76f00ab97920e4223bd2ee085abe7ac34e915e8676400e1643d3bbb4a864c8a6df1298bf229cabd1bdc9879eafdcbcab064708e8266e88d","up":true},{"one":"9529ff2b0692ad2608b55ec8ec0d1c9ccb8ee300412d99d389009162a76f7eec28d1090cbfb571aa8396b365074770b17106bfa3354857878dff164f42686142","other":"9e51eb48f59886e70eb8d02e1c0c4423de3f0ce79c7a62bfd91bc2048cf643f40a91e2d2a1a8a19a9e4ba4a96aed0965aefcd941c068208abe8bf5029eb27d55","up":true},{"one":"d0718ce0dafea66ee16c79626e020355273cdd062c0fceb122e391c4ca6e4e408a1b0e8230c4ade5bc95803916bdd6d98c99d2b6ea70c32e17fa1f2c98741a90","other":"62b8e67a4ca956c1cf2ba7a538d39bfe8bccf747fe65be48c88270ad44ee7711c0e9a43bb3821feffc492dba9b58397768c755810121add9c980c9a2c696feb0","up":true},{"one":"78216c6660fff0b96e38084941a2f237996732118033bf842e5f9e533b22b36c2da996df28e866424311b7b6414d4627db1f22a235ae777f7de34d9696043ecb","other":"61b32cded1b5ea3e2ca545a55c84251daaaacf51e6fed98fbdf4c5b6b91a554081e1e577aaaaaa4f911780f92703c1d715695d86c1be641b0bd1794f4107c2be","up":true},{"one":"af3f9dc00ce3cc156000f16a06c55c123ccdfabed89c9aee4478ff439b6f52a89d0501cff626d36b7f1852737955f7a036b25cf259580e8f46a3e0e44340b539","other":"5e92b025cc087c8823423c287f274a32a3dc0065afdf189475ba96b0da7b785cd493b7f2a7f3bb8195c73025bfbb402cbb4e0f6ae0d5e0caab223193cf6f2e5c","up":true},{"one":"032b1ce6881413b7ade1918e56691c7acd9f24111f47792ca50c33e570afba433caa132ad2326d03f9c0544fdc09fa0ca65f61de9fe61d6dd92c5d25a8df69af","other":"8da9cdb3c78776ed230497b21d4ac172f0ce73e921dfddd483da7bc6bbcd1951dd78fd5f70a0acbad855b2984e4c4bdb408c4bc25cab40684fe5a4408ec7ab9c","up":true},{"one":"5b456e429f7adae30366206e681ba46439a3372fec3806f666425cb3f12983c0b427e089fb163b70e6a56220b1529ee392ff701bc2f4621d51e23aa6305150e8","other":"032b1ce6881413b7ade1918e56691c7acd9f24111f47792ca50c33e570afba433caa132ad2326d03f9c0544fdc09fa0ca65f61de9fe61d6dd92c5d25a8df69af","up":true},{"one":"d472383c453e6b0f1a632010bdd6c42a9668d328a8f8071e0407069f6fe413e2a0fd0551a09cc56ee5245d472e39a7b6295491dd256ae42e200a257f297743e3","other":"8f6fb4a5baf715e001b060ce72378829279ce06a3247bd4a6faa3c725ee1b949570373e4231de82981020563e704297e77172506101b1444fcacfcc5f211827e","up":true},{"one":"e7d4478b412ef497741943736946a3b0679d21ae0c4cbdde6809c7236dcf1a40291088d872e469f06da19ed4ef77b9844aee7066c40fcd45b0931aff847de1d7","other":"8e1a66c9029330c25b9abe95a11878f41cef1a32b567a931ffa781c2f70a1336efa03ba1a66dac0080304803c1239be443991a251f24d0e9c2e26aebeb5437f8","up":true},{"one":"95c3ca2362de2eb0ac8efdd243918ed216f5d124bc6f5b9d83a6ee1aaf8a0fbdbd70ca1710d1ed825d6871f13a15954725f1aa1b27b48307844c0bc27baec0db","other":"032b1ce6881413b7ade1918e56691c7acd9f24111f47792ca50c33e570afba433caa132ad2326d03f9c0544fdc09fa0ca65f61de9fe61d6dd92c5d25a8df69af","up":true},{"one":"c0f2f1409cf83d7a777f6af95931181eb5a36b14a156f444075071c896fc5b435638ead23c65a242105db527c809e2c46f7805c862c0eb5d444749ddf22a5060","other":"a4fbd2ffc25d2c3bd37beecd637dda5983cb5817ecb6da62aec16ea59aaf7e71966649211461564ba808174361898a1d2265f1a42e94434bc00d5d3e04b67a8a","up":true},{"one":"7722d7d06c66afb0642d5f9ae0b22ed812c632f2d62ce64315da40eb003feb3fae1b337c10df21d297beabe51b3879f2c0a725f08ee78a8e09c75f86bd0e2092","other":"351ceaf2e95e098a8e15e81c82073b523f641848326d1bbd379f40f886b50ce2c377c4e3a2dfc2662d6f25ac04dede41063a075cf00be1cf36f95b0267717ab8","up":true},{"one":"07138ce506125910af81bd1bae11c22bfab9a81e1e057cc3d84769475c5da9873eb3f11edc6aca83ef486bfb63eba15a6233676d29d93ac9e774f10cd42c8cbd","other":"e021950ce89ce2bd79649aad2ed504789636b09870d0652fefa5e16631cb32a5d41c6cc4a540b7a0fca6bc3d5adf9b372a22cf714adc7b3e9b968d4c840017d4","up":true},{"one":"f70c92be150cb3f65f6bd904c8c161bfb0cea717bab0b24da63714de83e0872c8c369960ada1629607a1e166a19b6cfa887603e4868e7912ae5512744e8cc1c0","other":"8f6fb4a5baf715e001b060ce72378829279ce06a3247bd4a6faa3c725ee1b949570373e4231de82981020563e704297e77172506101b1444fcacfcc5f211827e","up":true},{"one":"c73f8fe9f54b89634cb0e8e332407a3a90cbbd347c0abc93823db13a7a39c46e7bd30d3f557316d92dd731cfc686afc308448682ff06c77246e3fb02b9a025ba","other":"d563716fbe2068cc940f7b12dc2bacb345c95f01e78e3b1f0105a441f300fdb00cc72e677aec102360fb904b63055d8581555f5b74b8f2392706569d8357c53f","up":true},{"one":"d563716fbe2068cc940f7b12dc2bacb345c95f01e78e3b1f0105a441f300fdb00cc72e677aec102360fb904b63055d8581555f5b74b8f2392706569d8357c53f","other":"43b91c24dd7fd217a76f00ab97920e4223bd2ee085abe7ac34e915e8676400e1643d3bbb4a864c8a6df1298bf229cabd1bdc9879eafdcbcab064708e8266e88d","up":true},{"one":"6d1af44ab259cc080a14c07bf5efabfd70cb847fe338f016c00138c84bddf6a6ce94047d1bffcfc7e9bc772dd7a080468a84655d5351d0056f97f13358b91547","other":"86d55ece15e6bb4da7601f6587654505f760ee2b87abdb115091eefa93f61cf29fd695601bb8c6ae2c76400de24b8bca9ca32b50e4b849ae76f5320b03276bfc","up":true},{"one":"0dcef49b94fdcff024d706030fd4f513d0c6ad5f00b06a8b67abc454bbe5c2c74e939d491c0700e47ecee5cd7c7084603f62e626c34b454868b8f22d8c2dfb10","other":"5e92b025cc087c8823423c287f274a32a3dc0065afdf189475ba96b0da7b785cd493b7f2a7f3bb8195c73025bfbb402cbb4e0f6ae0d5e0caab223193cf6f2e5c","up":true},{"one":"5e92b025cc087c8823423c287f274a32a3dc0065afdf189475ba96b0da7b785cd493b7f2a7f3bb8195c73025bfbb402cbb4e0f6ae0d5e0caab223193cf6f2e5c","other":"6593097e880701f3d0573df7bff9ba7af40f4f83b828bfc11bdabea62fb94ed39c8233d8d40275c2af9ceddae44514e029a546fe9df73abbd3821d37933aba49","up":true},{"one":"0a45a0aa4b4eee71b2828c794281d698019667288cf51311ffae7d8ea895f8ae29f7958dbfcda8763d9d8e9c097dccc5f92ac9d09fb4ccbde178d7f5ebda4d35","other":"86d55ece15e6bb4da7601f6587654505f760ee2b87abdb115091eefa93f61cf29fd695601bb8c6ae2c76400de24b8bca9ca32b50e4b849ae76f5320b03276bfc","up":true},{"one":"8da75cb4e63d968a7999ca4b49572b5ae592a91fa442d44bb7c42fb4b174a365e1affa1dbc45b2a0406444505f178100768e7783831f2886d53e7d1b8a3a7291","other":"f6e4b1dc1fa95ceae2b932b178afdc2dd515832a191e0f49c916d5a04548d58ef9f8c1dda3fbc93a45e6d82517e6a573310b7bfb14bc38c57000aec9ff010391","up":true},{"one":"a4fbd2ffc25d2c3bd37beecd637dda5983cb5817ecb6da62aec16ea59aaf7e71966649211461564ba808174361898a1d2265f1a42e94434bc00d5d3e04b67a8a","other":"5e92b025cc087c8823423c287f274a32a3dc0065afdf189475ba96b0da7b785cd493b7f2a7f3bb8195c73025bfbb402cbb4e0f6ae0d5e0caab223193cf6f2e5c","up":true},{"one":"43b91c24dd7fd217a76f00ab97920e4223bd2ee085abe7ac34e915e8676400e1643d3bbb4a864c8a6df1298bf229cabd1bdc9879eafdcbcab064708e8266e88d","other":"c0f2f1409cf83d7a777f6af95931181eb5a36b14a156f444075071c896fc5b435638ead23c65a242105db527c809e2c46f7805c862c0eb5d444749ddf22a5060","up":true},{"one":"17c7eb5833687a98087daadda564e54b1c770f946efb7efd69370a9caf6e6939e408f04a3fa1aa042d9463992a711786e504072fae56d007d696851696fc5643","other":"0a45a0aa4b4eee71b2828c794281d698019667288cf51311ffae7d8ea895f8ae29f7958dbfcda8763d9d8e9c097dccc5f92ac9d09fb4ccbde178d7f5ebda4d35","up":true},{"one":"46bb2acc087482d40ab2ccbb387723158411ff4931423414e4d09891be8a31d11929e939e4be94b0cc355c49883e1835785ba1955d865f78748c2a0a2f6eee0a","other":"86d55ece15e6bb4da7601f6587654505f760ee2b87abdb115091eefa93f61cf29fd695601bb8c6ae2c76400de24b8bca9ca32b50e4b849ae76f5320b03276bfc","up":true},{"one":"07138ce506125910af81bd1bae11c22bfab9a81e1e057cc3d84769475c5da9873eb3f11edc6aca83ef486bfb63eba15a6233676d29d93ac9e774f10cd42c8cbd","other":"c8e9cc707ce2a278371d1b4f64714cdae425b7c3606d18af6588dacaca35c7a171a07629247af351e667d2ddd9e71598f862125c827cc869c463cf87e4daeed0","up":true},{"one":"7a45fa46f161fae3ef9013e9ab81145f4a76fa6ae22160424d6dc111acbd477ce43d4c10db89cb7451c97ea1fbd78428997d01fd17e1851f8b559b404ede6da7","other":"46bb2acc087482d40ab2ccbb387723158411ff4931423414e4d09891be8a31d11929e939e4be94b0cc355c49883e1835785ba1955d865f78748c2a0a2f6eee0a","up":true},{"one":"14136fa967f2d4825845ba4a43a5921d8fcf03f9c71c5595037e000b2ef6ff0a5eaad0980aea0a170cafda3529f982aea1107f58aa42485550c9480e86f5e9f3","other":"7a1f97c41c9efd7a2903af78f72d02cfff3631dc6260d3ceb2364c2a8e06965710e8feae6aa9f99b48b2475da10b2f9581c76d47b4cd2bfee09c43dcb5e3e5d9","up":true},{"one":"f360c6599a0911337c7b96365fda1b2f64890bdb4483bb7e86bca15484f24c4efc0d1f6f56aa0c4fa5c205e6c1dbbf20d2ca3c2f8734f703fe6d672fa76a0d45","other":"8e1a66c9029330c25b9abe95a11878f41cef1a32b567a931ffa781c2f70a1336efa03ba1a66dac0080304803c1239be443991a251f24d0e9c2e26aebeb5437f8","up":true},{"one":"c0f2f1409cf83d7a777f6af95931181eb5a36b14a156f444075071c896fc5b435638ead23c65a242105db527c809e2c46f7805c862c0eb5d444749ddf22a5060","other":"7722d7d06c66afb0642d5f9ae0b22ed812c632f2d62ce64315da40eb003feb3fae1b337c10df21d297beabe51b3879f2c0a725f08ee78a8e09c75f86bd0e2092","up":true},{"one":"f5272b71c228eb14b9e0e221deefc0a91353a5f17d01475f57fad54bb8e50e375f58019c7200a9ca45b0f1da6538708c61242e478d917499871df7a9d5857f1a","other":"78216c6660fff0b96e38084941a2f237996732118033bf842e5f9e533b22b36c2da996df28e866424311b7b6414d4627db1f22a235ae777f7de34d9696043ecb","up":true},{"one":"e021950ce89ce2bd79649aad2ed504789636b09870d0652fefa5e16631cb32a5d41c6cc4a540b7a0fca6bc3d5adf9b372a22cf714adc7b3e9b968d4c840017d4","other":"e53cfad611bc38a1090d28e4cc58e4738ccaa83a00bf5447cd30ec70e492dea5811b67e79b9ca8856e79801741a675c6f54eb7a1c39e95ab735164855eae0fb7","up":true},{"one":"61b32cded1b5ea3e2ca545a55c84251daaaacf51e6fed98fbdf4c5b6b91a554081e1e577aaaaaa4f911780f92703c1d715695d86c1be641b0bd1794f4107c2be","other":"39d0aa13a6d7e709c9b914cb16f007c3f16af40532afa47c8cf9abf6d604d4380883103c995ec696ca593c4dc9bf0290979b965c9c6ade7c616d3973c5f0b1f0","up":true},{"one":"4f1a219f31e135208bf4caa314a14d8d48a5682941793431539efb5666b06bb5e3e9cb29b019ca414fb32961460556f2d99a04b12dc8ecbf05f43efe108803f5","other":"f70c92be150cb3f65f6bd904c8c161bfb0cea717bab0b24da63714de83e0872c8c369960ada1629607a1e166a19b6cfa887603e4868e7912ae5512744e8cc1c0","up":true},{"one":"25c64a52c298035be2184243082b5eba8a3a5d55c5334cea76e177d722945c8bf014a4ce9ef2ed76dc17a44234c97697337c6e001261533e72cc8266ee0e2fe4","other":"78216c6660fff0b96e38084941a2f237996732118033bf842e5f9e533b22b36c2da996df28e866424311b7b6414d4627db1f22a235ae777f7de34d9696043ecb","up":true},{"one":"393eb8d2acf9244f1cdc220711c00d8fa7619394893643bc32e1ee0f821e5a2afed07badbdf97d710843c4ea6de3f74c113ad4c548afd23534d6dea5c37c6d9d","other":"0a45a0aa4b4eee71b2828c794281d698019667288cf51311ffae7d8ea895f8ae29f7958dbfcda8763d9d8e9c097dccc5f92ac9d09fb4ccbde178d7f5ebda4d35","up":true},{"one":"e73af1e2a834ee132564dd2e983c877b3ae230808d2b42da2ec91472eee6ee6595c439800ce980186b4b0d9a56b96babf747006c07b07513543eead8e102fff7","other":"17c7eb5833687a98087daadda564e54b1c770f946efb7efd69370a9caf6e6939e408f04a3fa1aa042d9463992a711786e504072fae56d007d696851696fc5643","up":true},{"one":"86d55ece15e6bb4da7601f6587654505f760ee2b87abdb115091eefa93f61cf29fd695601bb8c6ae2c76400de24b8bca9ca32b50e4b849ae76f5320b03276bfc","other":"e73af1e2a834ee132564dd2e983c877b3ae230808d2b42da2ec91472eee6ee6595c439800ce980186b4b0d9a56b96babf747006c07b07513543eead8e102fff7","up":true},{"one":"62b8e67a4ca956c1cf2ba7a538d39bfe8bccf747fe65be48c88270ad44ee7711c0e9a43bb3821feffc492dba9b58397768c755810121add9c980c9a2c696feb0","other":"c73f8fe9f54b89634cb0e8e332407a3a90cbbd347c0abc93823db13a7a39c46e7bd30d3f557316d92dd731cfc686afc308448682ff06c77246e3fb02b9a025ba","up":true},{"one":"38b3adde25c6407f29c2a721f1f5c082cc94ddad09fc5afda2bbb2309212a9b54b1553731a65ec8b58769fc11d488169c8000ee15fe8966bd44a3879e0c9e534","other":"9529ff2b0692ad2608b55ec8ec0d1c9ccb8ee300412d99d389009162a76f7eec28d1090cbfb571aa8396b365074770b17106bfa3354857878dff164f42686142","up":true},{"one":"8e1a66c9029330c25b9abe95a11878f41cef1a32b567a931ffa781c2f70a1336efa03ba1a66dac0080304803c1239be443991a251f24d0e9c2e26aebeb5437f8","other":"43b91c24dd7fd217a76f00ab97920e4223bd2ee085abe7ac34e915e8676400e1643d3bbb4a864c8a6df1298bf229cabd1bdc9879eafdcbcab064708e8266e88d","up":true},{"one":"6593097e880701f3d0573df7bff9ba7af40f4f83b828bfc11bdabea62fb94ed39c8233d8d40275c2af9ceddae44514e029a546fe9df73abbd3821d37933aba49","other":"f6e4b1dc1fa95ceae2b932b178afdc2dd515832a191e0f49c916d5a04548d58ef9f8c1dda3fbc93a45e6d82517e6a573310b7bfb14bc38c57000aec9ff010391","up":true},{"one":"a4fbd2ffc25d2c3bd37beecd637dda5983cb5817ecb6da62aec16ea59aaf7e71966649211461564ba808174361898a1d2265f1a42e94434bc00d5d3e04b67a8a","other":"a48a667469a1344cb70f269b21fb3ca9e83823226749fd9c232be1b86ab9427888f2ecb20ddfa56da361463a061e192570f2f8da3fa967c473320ca85e382c53","up":true},{"one":"f6e4b1dc1fa95ceae2b932b178afdc2dd515832a191e0f49c916d5a04548d58ef9f8c1dda3fbc93a45e6d82517e6a573310b7bfb14bc38c57000aec9ff010391","other":"a48a667469a1344cb70f269b21fb3ca9e83823226749fd9c232be1b86ab9427888f2ecb20ddfa56da361463a061e192570f2f8da3fa967c473320ca85e382c53","up":true},{"one":"6eeb951b8f6d5ac519132910222777d5a409325e6c64d89708a00e55cb0fe85889aac1baa724e29fa7f064323b164a9c40c5114a65736e3dd16f0336283d9c7b","other":"e1082b4577aa370a5171b7602282208697dcead854f0c82acb5628d179fa5990a0fc85c5343a47177aab81c7fa6c1be8a27a3484acddc353582ddeb61892ef94","up":true},{"one":"dcf2401cbc26f3db27bb85c24984b1d755b3503fe400c139a0bedbe5de24db3f27c8f4f40adc1880b6142d20e67a40f3d45d36ba7fce122ffa44703e65622198","other":"43b91c24dd7fd217a76f00ab97920e4223bd2ee085abe7ac34e915e8676400e1643d3bbb4a864c8a6df1298bf229cabd1bdc9879eafdcbcab064708e8266e88d","up":true},{"one":"31cbd7c029d69715e59f31bccf362cd76e0a87839f1f63c6623be437d2af227a38f12c5fb9c659cc543976833caf22a52f5191c7c465a9ba36ac4235c12add72","other":"8da9cdb3c78776ed230497b21d4ac172f0ce73e921dfddd483da7bc6bbcd1951dd78fd5f70a0acbad855b2984e4c4bdb408c4bc25cab40684fe5a4408ec7ab9c","up":true},{"one":"86d55ece15e6bb4da7601f6587654505f760ee2b87abdb115091eefa93f61cf29fd695601bb8c6ae2c76400de24b8bca9ca32b50e4b849ae76f5320b03276bfc","other":"62b8e67a4ca956c1cf2ba7a538d39bfe8bccf747fe65be48c88270ad44ee7711c0e9a43bb3821feffc492dba9b58397768c755810121add9c980c9a2c696feb0","up":true},{"one":"6419279b600da3e2ee8d0b2a5b0319bc6cd496086955b49a8d2168fd4c35d5688291bc9313076b1b8e070f25dc593788d72b8f8c1d2ad828741a45deea35e58d","other":"d472383c453e6b0f1a632010bdd6c42a9668d328a8f8071e0407069f6fe413e2a0fd0551a09cc56ee5245d472e39a7b6295491dd256ae42e200a257f297743e3","up":true},{"one":"351ceaf2e95e098a8e15e81c82073b523f641848326d1bbd379f40f886b50ce2c377c4e3a2dfc2662d6f25ac04dede41063a075cf00be1cf36f95b0267717ab8","other":"707a9ae4bc8b37fff43dc3ba83ecb735bd428b720a751a11112452eec1ca49c09139bc437666add2823dd205e45cc793f8657c66ccbc6911cc60771d4512e038","up":true},{"one":"a48a667469a1344cb70f269b21fb3ca9e83823226749fd9c232be1b86ab9427888f2ecb20ddfa56da361463a061e192570f2f8da3fa967c473320ca85e382c53","other":"af3f9dc00ce3cc156000f16a06c55c123ccdfabed89c9aee4478ff439b6f52a89d0501cff626d36b7f1852737955f7a036b25cf259580e8f46a3e0e44340b539","up":true},{"one":"032b1ce6881413b7ade1918e56691c7acd9f24111f47792ca50c33e570afba433caa132ad2326d03f9c0544fdc09fa0ca65f61de9fe61d6dd92c5d25a8df69af","other":"7c273dd4218e9e5b92e19d250832a424ff2ac5482ad70953746de780100669eb143247e15ccfca14cce9a49a003c82be71ca034a2900bed4c89fb10bdbfcc7c3","up":true},{"one":"5b456e429f7adae30366206e681ba46439a3372fec3806f666425cb3f12983c0b427e089fb163b70e6a56220b1529ee392ff701bc2f4621d51e23aa6305150e8","other":"e479930845e1dac2d5908894548cc06c132fc5820810c6f46d9adc2bc252dd40b64642a3b2005ad3688d2637c43967f570bd153db9ee6742e1b23dbfb72537fa","up":true},{"one":"95c3ca2362de2eb0ac8efdd243918ed216f5d124bc6f5b9d83a6ee1aaf8a0fbdbd70ca1710d1ed825d6871f13a15954725f1aa1b27b48307844c0bc27baec0db","other":"e479930845e1dac2d5908894548cc06c132fc5820810c6f46d9adc2bc252dd40b64642a3b2005ad3688d2637c43967f570bd153db9ee6742e1b23dbfb72537fa","up":true},{"one":"8959c5cf825ebab14efeacf2807ad9498256a9e89a2ef00690c9ee23a3e934e111c52a5ddcc791b93f49424ac008095d8cb0da6905dfdeb62309fc4f6672e59e","other":"9529ff2b0692ad2608b55ec8ec0d1c9ccb8ee300412d99d389009162a76f7eec28d1090cbfb571aa8396b365074770b17106bfa3354857878dff164f42686142","up":true},{"one":"d0718ce0dafea66ee16c79626e020355273cdd062c0fceb122e391c4ca6e4e408a1b0e8230c4ade5bc95803916bdd6d98c99d2b6ea70c32e17fa1f2c98741a90","other":"e73af1e2a834ee132564dd2e983c877b3ae230808d2b42da2ec91472eee6ee6595c439800ce980186b4b0d9a56b96babf747006c07b07513543eead8e102fff7","up":true},{"one":"c73f8fe9f54b89634cb0e8e332407a3a90cbbd347c0abc93823db13a7a39c46e7bd30d3f557316d92dd731cfc686afc308448682ff06c77246e3fb02b9a025ba","other":"7722d7d06c66afb0642d5f9ae0b22ed812c632f2d62ce64315da40eb003feb3fae1b337c10df21d297beabe51b3879f2c0a725f08ee78a8e09c75f86bd0e2092","up":true},{"one":"707a9ae4bc8b37fff43dc3ba83ecb735bd428b720a751a11112452eec1ca49c09139bc437666add2823dd205e45cc793f8657c66ccbc6911cc60771d4512e038","other":"62b8e67a4ca956c1cf2ba7a538d39bfe8bccf747fe65be48c88270ad44ee7711c0e9a43bb3821feffc492dba9b58397768c755810121add9c980c9a2c696feb0","up":true},{"one":"f6e4b1dc1fa95ceae2b932b178afdc2dd515832a191e0f49c916d5a04548d58ef9f8c1dda3fbc93a45e6d82517e6a573310b7bfb14bc38c57000aec9ff010391","other":"9e51eb48f59886e70eb8d02e1c0c4423de3f0ce79c7a62bfd91bc2048cf643f40a91e2d2a1a8a19a9e4ba4a96aed0965aefcd941c068208abe8bf5029eb27d55","up":true},{"one":"d472383c453e6b0f1a632010bdd6c42a9668d328a8f8071e0407069f6fe413e2a0fd0551a09cc56ee5245d472e39a7b6295491dd256ae42e200a257f297743e3","other":"61b32cded1b5ea3e2ca545a55c84251daaaacf51e6fed98fbdf4c5b6b91a554081e1e577aaaaaa4f911780f92703c1d715695d86c1be641b0bd1794f4107c2be","up":true},{"one":"af3f9dc00ce3cc156000f16a06c55c123ccdfabed89c9aee4478ff439b6f52a89d0501cff626d36b7f1852737955f7a036b25cf259580e8f46a3e0e44340b539","other":"e7b1563d6e089e030983b075b590abb8a3205e9bce953f562b755ba150a3edc2dc3377259d96c05cc7363a23aed613711ca049e26253fd9273ac4c0483087015","up":true},{"one":"5e92b025cc087c8823423c287f274a32a3dc0065afdf189475ba96b0da7b785cd493b7f2a7f3bb8195c73025bfbb402cbb4e0f6ae0d5e0caab223193cf6f2e5c","other":"7722d7d06c66afb0642d5f9ae0b22ed812c632f2d62ce64315da40eb003feb3fae1b337c10df21d297beabe51b3879f2c0a725f08ee78a8e09c75f86bd0e2092","up":true},{"one":"578666c4113e196a7c738fdbae0bd68ade450283eb835efd06591798f1893f7f7d9cde0691faff670b5ae24e58cbc2f549d2196f244dddc00e82852c38e8539e","other":"032b1ce6881413b7ade1918e56691c7acd9f24111f47792ca50c33e570afba433caa132ad2326d03f9c0544fdc09fa0ca65f61de9fe61d6dd92c5d25a8df69af","up":true},{"one":"1691538e4cc41441c18fc92969c0c59f51da063814e8c45311605405284293503ee1570722cc7ae12f9cd63b899afaf5b3e66ca012115996074e8aaa71fda48c","other":"e7d4478b412ef497741943736946a3b0679d21ae0c4cbdde6809c7236dcf1a40291088d872e469f06da19ed4ef77b9844aee7066c40fcd45b0931aff847de1d7","up":true},{"one":"351ceaf2e95e098a8e15e81c82073b523f641848326d1bbd379f40f886b50ce2c377c4e3a2dfc2662d6f25ac04dede41063a075cf00be1cf36f95b0267717ab8","other":"8da75cb4e63d968a7999ca4b49572b5ae592a91fa442d44bb7c42fb4b174a365e1affa1dbc45b2a0406444505f178100768e7783831f2886d53e7d1b8a3a7291","up":true},{"one":"eb08a7774ca5252237d059a8bbad68044c83b2c332024be98bdc0c58508867a80cd34cb4162bd55a47fecc93301c8b2a7a1edbfd807ebb5623499cac80ea42de","other":"9529ff2b0692ad2608b55ec8ec0d1c9ccb8ee300412d99d389009162a76f7eec28d1090cbfb571aa8396b365074770b17106bfa3354857878dff164f42686142","up":true},{"one":"8da9cdb3c78776ed230497b21d4ac172f0ce73e921dfddd483da7bc6bbcd1951dd78fd5f70a0acbad855b2984e4c4bdb408c4bc25cab40684fe5a4408ec7ab9c","other":"7a1f97c41c9efd7a2903af78f72d02cfff3631dc6260d3ceb2364c2a8e06965710e8feae6aa9f99b48b2475da10b2f9581c76d47b4cd2bfee09c43dcb5e3e5d9","up":true},{"one":"78216c6660fff0b96e38084941a2f237996732118033bf842e5f9e533b22b36c2da996df28e866424311b7b6414d4627db1f22a235ae777f7de34d9696043ecb","other":"16bd57b6590df0c69c440d178da8359b0a3e00b9c5362155eae42709bdc4d0488e437fa7e8396d5b429cebe356ebd1407039b21eefa8d9164b357845132edb28","up":true},{"one":"07138ce506125910af81bd1bae11c22bfab9a81e1e057cc3d84769475c5da9873eb3f11edc6aca83ef486bfb63eba15a6233676d29d93ac9e774f10cd42c8cbd","other":"5b456e429f7adae30366206e681ba46439a3372fec3806f666425cb3f12983c0b427e089fb163b70e6a56220b1529ee392ff701bc2f4621d51e23aa6305150e8","up":true},{"one":"f360c6599a0911337c7b96365fda1b2f64890bdb4483bb7e86bca15484f24c4efc0d1f6f56aa0c4fa5c205e6c1dbbf20d2ca3c2f8734f703fe6d672fa76a0d45","other":"46bb2acc087482d40ab2ccbb387723158411ff4931423414e4d09891be8a31d11929e939e4be94b0cc355c49883e1835785ba1955d865f78748c2a0a2f6eee0a","up":true},{"one":"7a45fa46f161fae3ef9013e9ab81145f4a76fa6ae22160424d6dc111acbd477ce43d4c10db89cb7451c97ea1fbd78428997d01fd17e1851f8b559b404ede6da7","other":"17c7eb5833687a98087daadda564e54b1c770f946efb7efd69370a9caf6e6939e408f04a3fa1aa042d9463992a711786e504072fae56d007d696851696fc5643","up":true},{"one":"0a45a0aa4b4eee71b2828c794281d698019667288cf51311ffae7d8ea895f8ae29f7958dbfcda8763d9d8e9c097dccc5f92ac9d09fb4ccbde178d7f5ebda4d35","other":"e73af1e2a834ee132564dd2e983c877b3ae230808d2b42da2ec91472eee6ee6595c439800ce980186b4b0d9a56b96babf747006c07b07513543eead8e102fff7","up":true},{"one":"6d1af44ab259cc080a14c07bf5efabfd70cb847fe338f016c00138c84bddf6a6ce94047d1bffcfc7e9bc772dd7a080468a84655d5351d0056f97f13358b91547","other":"39d0aa13a6d7e709c9b914cb16f007c3f16af40532afa47c8cf9abf6d604d4380883103c995ec696ca593c4dc9bf0290979b965c9c6ade7c616d3973c5f0b1f0","up":true},{"one":"f5272b71c228eb14b9e0e221deefc0a91353a5f17d01475f57fad54bb8e50e375f58019c7200a9ca45b0f1da6538708c61242e478d917499871df7a9d5857f1a","other":"25c64a52c298035be2184243082b5eba8a3a5d55c5334cea76e177d722945c8bf014a4ce9ef2ed76dc17a44234c97697337c6e001261533e72cc8266ee0e2fe4","up":true},{"one":"7a1f97c41c9efd7a2903af78f72d02cfff3631dc6260d3ceb2364c2a8e06965710e8feae6aa9f99b48b2475da10b2f9581c76d47b4cd2bfee09c43dcb5e3e5d9","other":"95c3ca2362de2eb0ac8efdd243918ed216f5d124bc6f5b9d83a6ee1aaf8a0fbdbd70ca1710d1ed825d6871f13a15954725f1aa1b27b48307844c0bc27baec0db","up":true},{"one":"7722d7d06c66afb0642d5f9ae0b22ed812c632f2d62ce64315da40eb003feb3fae1b337c10df21d297beabe51b3879f2c0a725f08ee78a8e09c75f86bd0e2092","other":"86d55ece15e6bb4da7601f6587654505f760ee2b87abdb115091eefa93f61cf29fd695601bb8c6ae2c76400de24b8bca9ca32b50e4b849ae76f5320b03276bfc","up":true},{"one":"61b32cded1b5ea3e2ca545a55c84251daaaacf51e6fed98fbdf4c5b6b91a554081e1e577aaaaaa4f911780f92703c1d715695d86c1be641b0bd1794f4107c2be","other":"8f6fb4a5baf715e001b060ce72378829279ce06a3247bd4a6faa3c725ee1b949570373e4231de82981020563e704297e77172506101b1444fcacfcc5f211827e","up":true},{"one":"46bb2acc087482d40ab2ccbb387723158411ff4931423414e4d09891be8a31d11929e939e4be94b0cc355c49883e1835785ba1955d865f78748c2a0a2f6eee0a","other":"39d0aa13a6d7e709c9b914cb16f007c3f16af40532afa47c8cf9abf6d604d4380883103c995ec696ca593c4dc9bf0290979b965c9c6ade7c616d3973c5f0b1f0","up":true},{"one":"8da75cb4e63d968a7999ca4b49572b5ae592a91fa442d44bb7c42fb4b174a365e1affa1dbc45b2a0406444505f178100768e7783831f2886d53e7d1b8a3a7291","other":"e7b1563d6e089e030983b075b590abb8a3205e9bce953f562b755ba150a3edc2dc3377259d96c05cc7363a23aed613711ca049e26253fd9273ac4c0483087015","up":true},{"one":"e7d4478b412ef497741943736946a3b0679d21ae0c4cbdde6809c7236dcf1a40291088d872e469f06da19ed4ef77b9844aee7066c40fcd45b0931aff847de1d7","other":"16bd57b6590df0c69c440d178da8359b0a3e00b9c5362155eae42709bdc4d0488e437fa7e8396d5b429cebe356ebd1407039b21eefa8d9164b357845132edb28","up":true},{"one":"e7b1563d6e089e030983b075b590abb8a3205e9bce953f562b755ba150a3edc2dc3377259d96c05cc7363a23aed613711ca049e26253fd9273ac4c0483087015","other":"6593097e880701f3d0573df7bff9ba7af40f4f83b828bfc11bdabea62fb94ed39c8233d8d40275c2af9ceddae44514e029a546fe9df73abbd3821d37933aba49","up":true},{"one":"4f1a219f31e135208bf4caa314a14d8d48a5682941793431539efb5666b06bb5e3e9cb29b019ca414fb32961460556f2d99a04b12dc8ecbf05f43efe108803f5","other":"61b32cded1b5ea3e2ca545a55c84251daaaacf51e6fed98fbdf4c5b6b91a554081e1e577aaaaaa4f911780f92703c1d715695d86c1be641b0bd1794f4107c2be","up":true},{"one":"e73af1e2a834ee132564dd2e983c877b3ae230808d2b42da2ec91472eee6ee6595c439800ce980186b4b0d9a56b96babf747006c07b07513543eead8e102fff7","other":"7a45fa46f161fae3ef9013e9ab81145f4a76fa6ae22160424d6dc111acbd477ce43d4c10db89cb7451c97ea1fbd78428997d01fd17e1851f8b559b404ede6da7","up":true},{"one":"1691538e4cc41441c18fc92969c0c59f51da063814e8c45311605405284293503ee1570722cc7ae12f9cd63b899afaf5b3e66ca012115996074e8aaa71fda48c","other":"e53cfad611bc38a1090d28e4cc58e4738ccaa83a00bf5447cd30ec70e492dea5811b67e79b9ca8856e79801741a675c6f54eb7a1c39e95ab735164855eae0fb7","up":true},{"one":"25c64a52c298035be2184243082b5eba8a3a5d55c5334cea76e177d722945c8bf014a4ce9ef2ed76dc17a44234c97697337c6e001261533e72cc8266ee0e2fe4","other":"16bd57b6590df0c69c440d178da8359b0a3e00b9c5362155eae42709bdc4d0488e437fa7e8396d5b429cebe356ebd1407039b21eefa8d9164b357845132edb28","up":true},{"one":"8e1a66c9029330c25b9abe95a11878f41cef1a32b567a931ffa781c2f70a1336efa03ba1a66dac0080304803c1239be443991a251f24d0e9c2e26aebeb5437f8","other":"d563716fbe2068cc940f7b12dc2bacb345c95f01e78e3b1f0105a441f300fdb00cc72e677aec102360fb904b63055d8581555f5b74b8f2392706569d8357c53f","up":true},{"one":"86d55ece15e6bb4da7601f6587654505f760ee2b87abdb115091eefa93f61cf29fd695601bb8c6ae2c76400de24b8bca9ca32b50e4b849ae76f5320b03276bfc","other":"393eb8d2acf9244f1cdc220711c00d8fa7619394893643bc32e1ee0f821e5a2afed07badbdf97d710843c4ea6de3f74c113ad4c548afd23534d6dea5c37c6d9d","up":true},{"one":"14136fa967f2d4825845ba4a43a5921d8fcf03f9c71c5595037e000b2ef6ff0a5eaad0980aea0a170cafda3529f982aea1107f58aa42485550c9480e86f5e9f3","other":"38b3adde25c6407f29c2a721f1f5c082cc94ddad09fc5afda2bbb2309212a9b54b1553731a65ec8b58769fc11d488169c8000ee15fe8966bd44a3879e0c9e534","up":true},{"one":"e53cfad611bc38a1090d28e4cc58e4738ccaa83a00bf5447cd30ec70e492dea5811b67e79b9ca8856e79801741a675c6f54eb7a1c39e95ab735164855eae0fb7","other":"c8e9cc707ce2a278371d1b4f64714cdae425b7c3606d18af6588dacaca35c7a171a07629247af351e667d2ddd9e71598f862125c827cc869c463cf87e4daeed0","up":true},{"one":"31cbd7c029d69715e59f31bccf362cd76e0a87839f1f63c6623be437d2af227a38f12c5fb9c659cc543976833caf22a52f5191c7c465a9ba36ac4235c12add72","other":"7a1f97c41c9efd7a2903af78f72d02cfff3631dc6260d3ceb2364c2a8e06965710e8feae6aa9f99b48b2475da10b2f9581c76d47b4cd2bfee09c43dcb5e3e5d9","up":true},{"one":"eb08a7774ca5252237d059a8bbad68044c83b2c332024be98bdc0c58508867a80cd34cb4162bd55a47fecc93301c8b2a7a1edbfd807ebb5623499cac80ea42de","other":"6419279b600da3e2ee8d0b2a5b0319bc6cd496086955b49a8d2168fd4c35d5688291bc9313076b1b8e070f25dc593788d72b8f8c1d2ad828741a45deea35e58d","up":true},{"one":"8f6fb4a5baf715e001b060ce72378829279ce06a3247bd4a6faa3c725ee1b949570373e4231de82981020563e704297e77172506101b1444fcacfcc5f211827e","other":"e1082b4577aa370a5171b7602282208697dcead854f0c82acb5628d179fa5990a0fc85c5343a47177aab81c7fa6c1be8a27a3484acddc353582ddeb61892ef94","up":true},{"one":"dcf2401cbc26f3db27bb85c24984b1d755b3503fe400c139a0bedbe5de24db3f27c8f4f40adc1880b6142d20e67a40f3d45d36ba7fce122ffa44703e65622198","other":"f70c92be150cb3f65f6bd904c8c161bfb0cea717bab0b24da63714de83e0872c8c369960ada1629607a1e166a19b6cfa887603e4868e7912ae5512744e8cc1c0","up":true},{"one":"38b3adde25c6407f29c2a721f1f5c082cc94ddad09fc5afda2bbb2309212a9b54b1553731a65ec8b58769fc11d488169c8000ee15fe8966bd44a3879e0c9e534","other":"d472383c453e6b0f1a632010bdd6c42a9668d328a8f8071e0407069f6fe413e2a0fd0551a09cc56ee5245d472e39a7b6295491dd256ae42e200a257f297743e3","up":true},{"one":"578666c4113e196a7c738fdbae0bd68ade450283eb835efd06591798f1893f7f7d9cde0691faff670b5ae24e58cbc2f549d2196f244dddc00e82852c38e8539e","other":"8da9cdb3c78776ed230497b21d4ac172f0ce73e921dfddd483da7bc6bbcd1951dd78fd5f70a0acbad855b2984e4c4bdb408c4bc25cab40684fe5a4408ec7ab9c","up":true},{"one":"6eeb951b8f6d5ac519132910222777d5a409325e6c64d89708a00e55cb0fe85889aac1baa724e29fa7f064323b164a9c40c5114a65736e3dd16f0336283d9c7b","other":"43b91c24dd7fd217a76f00ab97920e4223bd2ee085abe7ac34e915e8676400e1643d3bbb4a864c8a6df1298bf229cabd1bdc9879eafdcbcab064708e8266e88d","up":true},{"one":"a4fbd2ffc25d2c3bd37beecd637dda5983cb5817ecb6da62aec16ea59aaf7e71966649211461564ba808174361898a1d2265f1a42e94434bc00d5d3e04b67a8a","other":"46bb2acc087482d40ab2ccbb387723158411ff4931423414e4d09891be8a31d11929e939e4be94b0cc355c49883e1835785ba1955d865f78748c2a0a2f6eee0a","up":true},{"one":"e021950ce89ce2bd79649aad2ed504789636b09870d0652fefa5e16631cb32a5d41c6cc4a540b7a0fca6bc3d5adf9b372a22cf714adc7b3e9b968d4c840017d4","other":"1691538e4cc41441c18fc92969c0c59f51da063814e8c45311605405284293503ee1570722cc7ae12f9cd63b899afaf5b3e66ca012115996074e8aaa71fda48c","up":true},{"one":"62b8e67a4ca956c1cf2ba7a538d39bfe8bccf747fe65be48c88270ad44ee7711c0e9a43bb3821feffc492dba9b58397768c755810121add9c980c9a2c696feb0","other":"7722d7d06c66afb0642d5f9ae0b22ed812c632f2d62ce64315da40eb003feb3fae1b337c10df21d297beabe51b3879f2c0a725f08ee78a8e09c75f86bd0e2092","up":true},{"one":"9e51eb48f59886e70eb8d02e1c0c4423de3f0ce79c7a62bfd91bc2048cf643f40a91e2d2a1a8a19a9e4ba4a96aed0965aefcd941c068208abe8bf5029eb27d55","other":"46bb2acc087482d40ab2ccbb387723158411ff4931423414e4d09891be8a31d11929e939e4be94b0cc355c49883e1835785ba1955d865f78748c2a0a2f6eee0a","up":true},{"one":"f5efffc8e894cecc065f6892ad2a846c8fc4982d1c8c7fc729421d5108d519c501cc9f2f7a0046ec08d47cf2369753aaf287dfc3ef7ecd34d24d294efb933658","other":"c73f8fe9f54b89634cb0e8e332407a3a90cbbd347c0abc93823db13a7a39c46e7bd30d3f557316d92dd731cfc686afc308448682ff06c77246e3fb02b9a025ba","up":true},{"one":"8959c5cf825ebab14efeacf2807ad9498256a9e89a2ef00690c9ee23a3e934e111c52a5ddcc791b93f49424ac008095d8cb0da6905dfdeb62309fc4f6672e59e","other":"eb08a7774ca5252237d059a8bbad68044c83b2c332024be98bdc0c58508867a80cd34cb4162bd55a47fecc93301c8b2a7a1edbfd807ebb5623499cac80ea42de","up":true},{"one":"e1082b4577aa370a5171b7602282208697dcead854f0c82acb5628d179fa5990a0fc85c5343a47177aab81c7fa6c1be8a27a3484acddc353582ddeb61892ef94","other":"dcf2401cbc26f3db27bb85c24984b1d755b3503fe400c139a0bedbe5de24db3f27c8f4f40adc1880b6142d20e67a40f3d45d36ba7fce122ffa44703e65622198","up":true},{"one":"e7b1563d6e089e030983b075b590abb8a3205e9bce953f562b755ba150a3edc2dc3377259d96c05cc7363a23aed613711ca049e26253fd9273ac4c0483087015","other":"f6e4b1dc1fa95ceae2b932b178afdc2dd515832a191e0f49c916d5a04548d58ef9f8c1dda3fbc93a45e6d82517e6a573310b7bfb14bc38c57000aec9ff010391","up":true},{"one":"e479930845e1dac2d5908894548cc06c132fc5820810c6f46d9adc2bc252dd40b64642a3b2005ad3688d2637c43967f570bd153db9ee6742e1b23dbfb72537fa","other":"14136fa967f2d4825845ba4a43a5921d8fcf03f9c71c5595037e000b2ef6ff0a5eaad0980aea0a170cafda3529f982aea1107f58aa42485550c9480e86f5e9f3","up":true},{"one":"8f6fb4a5baf715e001b060ce72378829279ce06a3247bd4a6faa3c725ee1b949570373e4231de82981020563e704297e77172506101b1444fcacfcc5f211827e","other":"9529ff2b0692ad2608b55ec8ec0d1c9ccb8ee300412d99d389009162a76f7eec28d1090cbfb571aa8396b365074770b17106bfa3354857878dff164f42686142","up":true},{"one":"d0718ce0dafea66ee16c79626e020355273cdd062c0fceb122e391c4ca6e4e408a1b0e8230c4ade5bc95803916bdd6d98c99d2b6ea70c32e17fa1f2c98741a90","other":"46bb2acc087482d40ab2ccbb387723158411ff4931423414e4d09891be8a31d11929e939e4be94b0cc355c49883e1835785ba1955d865f78748c2a0a2f6eee0a","up":true},{"one":"9529ff2b0692ad2608b55ec8ec0d1c9ccb8ee300412d99d389009162a76f7eec28d1090cbfb571aa8396b365074770b17106bfa3354857878dff164f42686142","other":"f70c92be150cb3f65f6bd904c8c161bfb0cea717bab0b24da63714de83e0872c8c369960ada1629607a1e166a19b6cfa887603e4868e7912ae5512744e8cc1c0","up":true},{"one":"5b456e429f7adae30366206e681ba46439a3372fec3806f666425cb3f12983c0b427e089fb163b70e6a56220b1529ee392ff701bc2f4621d51e23aa6305150e8","other":"7a1f97c41c9efd7a2903af78f72d02cfff3631dc6260d3ceb2364c2a8e06965710e8feae6aa9f99b48b2475da10b2f9581c76d47b4cd2bfee09c43dcb5e3e5d9","up":true},{"one":"95c3ca2362de2eb0ac8efdd243918ed216f5d124bc6f5b9d83a6ee1aaf8a0fbdbd70ca1710d1ed825d6871f13a15954725f1aa1b27b48307844c0bc27baec0db","other":"f70c92be150cb3f65f6bd904c8c161bfb0cea717bab0b24da63714de83e0872c8c369960ada1629607a1e166a19b6cfa887603e4868e7912ae5512744e8cc1c0","up":true},{"one":"c73f8fe9f54b89634cb0e8e332407a3a90cbbd347c0abc93823db13a7a39c46e7bd30d3f557316d92dd731cfc686afc308448682ff06c77246e3fb02b9a025ba","other":"43b91c24dd7fd217a76f00ab97920e4223bd2ee085abe7ac34e915e8676400e1643d3bbb4a864c8a6df1298bf229cabd1bdc9879eafdcbcab064708e8266e88d","up":true},{"one":"8da9cdb3c78776ed230497b21d4ac172f0ce73e921dfddd483da7bc6bbcd1951dd78fd5f70a0acbad855b2984e4c4bdb408c4bc25cab40684fe5a4408ec7ab9c","other":"f360c6599a0911337c7b96365fda1b2f64890bdb4483bb7e86bca15484f24c4efc0d1f6f56aa0c4fa5c205e6c1dbbf20d2ca3c2f8734f703fe6d672fa76a0d45","up":true},{"one":"25c64a52c298035be2184243082b5eba8a3a5d55c5334cea76e177d722945c8bf014a4ce9ef2ed76dc17a44234c97697337c6e001261533e72cc8266ee0e2fe4","other":"8f6fb4a5baf715e001b060ce72378829279ce06a3247bd4a6faa3c725ee1b949570373e4231de82981020563e704297e77172506101b1444fcacfcc5f211827e","up":true},{"one":"0dcef49b94fdcff024d706030fd4f513d0c6ad5f00b06a8b67abc454bbe5c2c74e939d491c0700e47ecee5cd7c7084603f62e626c34b454868b8f22d8c2dfb10","other":"e7b1563d6e089e030983b075b590abb8a3205e9bce953f562b755ba150a3edc2dc3377259d96c05cc7363a23aed613711ca049e26253fd9273ac4c0483087015","up":true},{"one":"7c273dd4218e9e5b92e19d250832a424ff2ac5482ad70953746de780100669eb143247e15ccfca14cce9a49a003c82be71ca034a2900bed4c89fb10bdbfcc7c3","other":"31cbd7c029d69715e59f31bccf362cd76e0a87839f1f63c6623be437d2af227a38f12c5fb9c659cc543976833caf22a52f5191c7c465a9ba36ac4235c12add72","up":true},{"one":"46bb2acc087482d40ab2ccbb387723158411ff4931423414e4d09891be8a31d11929e939e4be94b0cc355c49883e1835785ba1955d865f78748c2a0a2f6eee0a","other":"17c7eb5833687a98087daadda564e54b1c770f946efb7efd69370a9caf6e6939e408f04a3fa1aa042d9463992a711786e504072fae56d007d696851696fc5643","up":true},{"one":"7722d7d06c66afb0642d5f9ae0b22ed812c632f2d62ce64315da40eb003feb3fae1b337c10df21d297beabe51b3879f2c0a725f08ee78a8e09c75f86bd0e2092","other":"393eb8d2acf9244f1cdc220711c00d8fa7619394893643bc32e1ee0f821e5a2afed07badbdf97d710843c4ea6de3f74c113ad4c548afd23534d6dea5c37c6d9d","up":true},{"one":"e479930845e1dac2d5908894548cc06c132fc5820810c6f46d9adc2bc252dd40b64642a3b2005ad3688d2637c43967f570bd153db9ee6742e1b23dbfb72537fa","other":"7a1f97c41c9efd7a2903af78f72d02cfff3631dc6260d3ceb2364c2a8e06965710e8feae6aa9f99b48b2475da10b2f9581c76d47b4cd2bfee09c43dcb5e3e5d9","up":true},{"one":"7a1f97c41c9efd7a2903af78f72d02cfff3631dc6260d3ceb2364c2a8e06965710e8feae6aa9f99b48b2475da10b2f9581c76d47b4cd2bfee09c43dcb5e3e5d9","other":"7c273dd4218e9e5b92e19d250832a424ff2ac5482ad70953746de780100669eb143247e15ccfca14cce9a49a003c82be71ca034a2900bed4c89fb10bdbfcc7c3","up":true},{"one":"7a45fa46f161fae3ef9013e9ab81145f4a76fa6ae22160424d6dc111acbd477ce43d4c10db89cb7451c97ea1fbd78428997d01fd17e1851f8b559b404ede6da7","other":"8f6fb4a5baf715e001b060ce72378829279ce06a3247bd4a6faa3c725ee1b949570373e4231de82981020563e704297e77172506101b1444fcacfcc5f211827e","up":true},{"one":"8da75cb4e63d968a7999ca4b49572b5ae592a91fa442d44bb7c42fb4b174a365e1affa1dbc45b2a0406444505f178100768e7783831f2886d53e7d1b8a3a7291","other":"c0f2f1409cf83d7a777f6af95931181eb5a36b14a156f444075071c896fc5b435638ead23c65a242105db527c809e2c46f7805c862c0eb5d444749ddf22a5060","up":true},{"one":"d563716fbe2068cc940f7b12dc2bacb345c95f01e78e3b1f0105a441f300fdb00cc72e677aec102360fb904b63055d8581555f5b74b8f2392706569d8357c53f","other":"e7b1563d6e089e030983b075b590abb8a3205e9bce953f562b755ba150a3edc2dc3377259d96c05cc7363a23aed613711ca049e26253fd9273ac4c0483087015","up":true},{"one":"1691538e4cc41441c18fc92969c0c59f51da063814e8c45311605405284293503ee1570722cc7ae12f9cd63b899afaf5b3e66ca012115996074e8aaa71fda48c","other":"8da9cdb3c78776ed230497b21d4ac172f0ce73e921dfddd483da7bc6bbcd1951dd78fd5f70a0acbad855b2984e4c4bdb408c4bc25cab40684fe5a4408ec7ab9c","up":true},{"one":"17c7eb5833687a98087daadda564e54b1c770f946efb7efd69370a9caf6e6939e408f04a3fa1aa042d9463992a711786e504072fae56d007d696851696fc5643","other":"d0718ce0dafea66ee16c79626e020355273cdd062c0fceb122e391c4ca6e4e408a1b0e8230c4ade5bc95803916bdd6d98c99d2b6ea70c32e17fa1f2c98741a90","up":true},{"one":"e73af1e2a834ee132564dd2e983c877b3ae230808d2b42da2ec91472eee6ee6595c439800ce980186b4b0d9a56b96babf747006c07b07513543eead8e102fff7","other":"61b32cded1b5ea3e2ca545a55c84251daaaacf51e6fed98fbdf4c5b6b91a554081e1e577aaaaaa4f911780f92703c1d715695d86c1be641b0bd1794f4107c2be","up":true},{"one":"e7d4478b412ef497741943736946a3b0679d21ae0c4cbdde6809c7236dcf1a40291088d872e469f06da19ed4ef77b9844aee7066c40fcd45b0931aff847de1d7","other":"e021950ce89ce2bd79649aad2ed504789636b09870d0652fefa5e16631cb32a5d41c6cc4a540b7a0fca6bc3d5adf9b372a22cf714adc7b3e9b968d4c840017d4","up":true},{"one":"e53cfad611bc38a1090d28e4cc58e4738ccaa83a00bf5447cd30ec70e492dea5811b67e79b9ca8856e79801741a675c6f54eb7a1c39e95ab735164855eae0fb7","other":"5b456e429f7adae30366206e681ba46439a3372fec3806f666425cb3f12983c0b427e089fb163b70e6a56220b1529ee392ff701bc2f4621d51e23aa6305150e8","up":true},{"one":"f5272b71c228eb14b9e0e221deefc0a91353a5f17d01475f57fad54bb8e50e375f58019c7200a9ca45b0f1da6538708c61242e478d917499871df7a9d5857f1a","other":"16bd57b6590df0c69c440d178da8359b0a3e00b9c5362155eae42709bdc4d0488e437fa7e8396d5b429cebe356ebd1407039b21eefa8d9164b357845132edb28","up":true},{"one":"43b91c24dd7fd217a76f00ab97920e4223bd2ee085abe7ac34e915e8676400e1643d3bbb4a864c8a6df1298bf229cabd1bdc9879eafdcbcab064708e8266e88d","other":"17c7eb5833687a98087daadda564e54b1c770f946efb7efd69370a9caf6e6939e408f04a3fa1aa042d9463992a711786e504072fae56d007d696851696fc5643","up":true},{"one":"7c273dd4218e9e5b92e19d250832a424ff2ac5482ad70953746de780100669eb143247e15ccfca14cce9a49a003c82be71ca034a2900bed4c89fb10bdbfcc7c3","other":"578666c4113e196a7c738fdbae0bd68ade450283eb835efd06591798f1893f7f7d9cde0691faff670b5ae24e58cbc2f549d2196f244dddc00e82852c38e8539e","up":true},{"one":"4f1a219f31e135208bf4caa314a14d8d48a5682941793431539efb5666b06bb5e3e9cb29b019ca414fb32961460556f2d99a04b12dc8ecbf05f43efe108803f5","other":"17c7eb5833687a98087daadda564e54b1c770f946efb7efd69370a9caf6e6939e408f04a3fa1aa042d9463992a711786e504072fae56d007d696851696fc5643","up":true},{"one":"14136fa967f2d4825845ba4a43a5921d8fcf03f9c71c5595037e000b2ef6ff0a5eaad0980aea0a170cafda3529f982aea1107f58aa42485550c9480e86f5e9f3","other":"31cbd7c029d69715e59f31bccf362cd76e0a87839f1f63c6623be437d2af227a38f12c5fb9c659cc543976833caf22a52f5191c7c465a9ba36ac4235c12add72","up":true},{"one":"c0f2f1409cf83d7a777f6af95931181eb5a36b14a156f444075071c896fc5b435638ead23c65a242105db527c809e2c46f7805c862c0eb5d444749ddf22a5060","other":"e7b1563d6e089e030983b075b590abb8a3205e9bce953f562b755ba150a3edc2dc3377259d96c05cc7363a23aed613711ca049e26253fd9273ac4c0483087015","up":true},{"one":"e021950ce89ce2bd79649aad2ed504789636b09870d0652fefa5e16631cb32a5d41c6cc4a540b7a0fca6bc3d5adf9b372a22cf714adc7b3e9b968d4c840017d4","other":"8e1a66c9029330c25b9abe95a11878f41cef1a32b567a931ffa781c2f70a1336efa03ba1a66dac0080304803c1239be443991a251f24d0e9c2e26aebeb5437f8","up":true},{"one":"16bd57b6590df0c69c440d178da8359b0a3e00b9c5362155eae42709bdc4d0488e437fa7e8396d5b429cebe356ebd1407039b21eefa8d9164b357845132edb28","other":"9529ff2b0692ad2608b55ec8ec0d1c9ccb8ee300412d99d389009162a76f7eec28d1090cbfb571aa8396b365074770b17106bfa3354857878dff164f42686142","up":true},{"one":"393eb8d2acf9244f1cdc220711c00d8fa7619394893643bc32e1ee0f821e5a2afed07badbdf97d710843c4ea6de3f74c113ad4c548afd23534d6dea5c37c6d9d","other":"c73f8fe9f54b89634cb0e8e332407a3a90cbbd347c0abc93823db13a7a39c46e7bd30d3f557316d92dd731cfc686afc308448682ff06c77246e3fb02b9a025ba","up":true},{"one":"eb08a7774ca5252237d059a8bbad68044c83b2c332024be98bdc0c58508867a80cd34cb4162bd55a47fecc93301c8b2a7a1edbfd807ebb5623499cac80ea42de","other":"e021950ce89ce2bd79649aad2ed504789636b09870d0652fefa5e16631cb32a5d41c6cc4a540b7a0fca6bc3d5adf9b372a22cf714adc7b3e9b968d4c840017d4","up":true},{"one":"31cbd7c029d69715e59f31bccf362cd76e0a87839f1f63c6623be437d2af227a38f12c5fb9c659cc543976833caf22a52f5191c7c465a9ba36ac4235c12add72","other":"e479930845e1dac2d5908894548cc06c132fc5820810c6f46d9adc2bc252dd40b64642a3b2005ad3688d2637c43967f570bd153db9ee6742e1b23dbfb72537fa","up":true},{"one":"38b3adde25c6407f29c2a721f1f5c082cc94ddad09fc5afda2bbb2309212a9b54b1553731a65ec8b58769fc11d488169c8000ee15fe8966bd44a3879e0c9e534","other":"78216c6660fff0b96e38084941a2f237996732118033bf842e5f9e533b22b36c2da996df28e866424311b7b6414d4627db1f22a235ae777f7de34d9696043ecb","up":true},{"one":"c8e9cc707ce2a278371d1b4f64714cdae425b7c3606d18af6588dacaca35c7a171a07629247af351e667d2ddd9e71598f862125c827cc869c463cf87e4daeed0","other":"38b3adde25c6407f29c2a721f1f5c082cc94ddad09fc5afda2bbb2309212a9b54b1553731a65ec8b58769fc11d488169c8000ee15fe8966bd44a3879e0c9e534","up":true},{"one":"6419279b600da3e2ee8d0b2a5b0319bc6cd496086955b49a8d2168fd4c35d5688291bc9313076b1b8e070f25dc593788d72b8f8c1d2ad828741a45deea35e58d","other":"43b91c24dd7fd217a76f00ab97920e4223bd2ee085abe7ac34e915e8676400e1643d3bbb4a864c8a6df1298bf229cabd1bdc9879eafdcbcab064708e8266e88d","up":true},{"one":"a4fbd2ffc25d2c3bd37beecd637dda5983cb5817ecb6da62aec16ea59aaf7e71966649211461564ba808174361898a1d2265f1a42e94434bc00d5d3e04b67a8a","other":"d0718ce0dafea66ee16c79626e020355273cdd062c0fceb122e391c4ca6e4e408a1b0e8230c4ade5bc95803916bdd6d98c99d2b6ea70c32e17fa1f2c98741a90","up":true},{"one":"032b1ce6881413b7ade1918e56691c7acd9f24111f47792ca50c33e570afba433caa132ad2326d03f9c0544fdc09fa0ca65f61de9fe61d6dd92c5d25a8df69af","other":"14136fa967f2d4825845ba4a43a5921d8fcf03f9c71c5595037e000b2ef6ff0a5eaad0980aea0a170cafda3529f982aea1107f58aa42485550c9480e86f5e9f3","up":true},{"one":"dcf2401cbc26f3db27bb85c24984b1d755b3503fe400c139a0bedbe5de24db3f27c8f4f40adc1880b6142d20e67a40f3d45d36ba7fce122ffa44703e65622198","other":"4f1a219f31e135208bf4caa314a14d8d48a5682941793431539efb5666b06bb5e3e9cb29b019ca414fb32961460556f2d99a04b12dc8ecbf05f43efe108803f5","up":true},{"one":"6eeb951b8f6d5ac519132910222777d5a409325e6c64d89708a00e55cb0fe85889aac1baa724e29fa7f064323b164a9c40c5114a65736e3dd16f0336283d9c7b","other":"f70c92be150cb3f65f6bd904c8c161bfb0cea717bab0b24da63714de83e0872c8c369960ada1629607a1e166a19b6cfa887603e4868e7912ae5512744e8cc1c0","up":true},{"one":"f70c92be150cb3f65f6bd904c8c161bfb0cea717bab0b24da63714de83e0872c8c369960ada1629607a1e166a19b6cfa887603e4868e7912ae5512744e8cc1c0","other":"f5272b71c228eb14b9e0e221deefc0a91353a5f17d01475f57fad54bb8e50e375f58019c7200a9ca45b0f1da6538708c61242e478d917499871df7a9d5857f1a","up":true},{"one":"e7b1563d6e089e030983b075b590abb8a3205e9bce953f562b755ba150a3edc2dc3377259d96c05cc7363a23aed613711ca049e26253fd9273ac4c0483087015","other":"43b91c24dd7fd217a76f00ab97920e4223bd2ee085abe7ac34e915e8676400e1643d3bbb4a864c8a6df1298bf229cabd1bdc9879eafdcbcab064708e8266e88d","up":true},{"one":"95c3ca2362de2eb0ac8efdd243918ed216f5d124bc6f5b9d83a6ee1aaf8a0fbdbd70ca1710d1ed825d6871f13a15954725f1aa1b27b48307844c0bc27baec0db","other":"9e51eb48f59886e70eb8d02e1c0c4423de3f0ce79c7a62bfd91bc2048cf643f40a91e2d2a1a8a19a9e4ba4a96aed0965aefcd941c068208abe8bf5029eb27d55","up":true},{"one":"d472383c453e6b0f1a632010bdd6c42a9668d328a8f8071e0407069f6fe413e2a0fd0551a09cc56ee5245d472e39a7b6295491dd256ae42e200a257f297743e3","other":"16bd57b6590df0c69c440d178da8359b0a3e00b9c5362155eae42709bdc4d0488e437fa7e8396d5b429cebe356ebd1407039b21eefa8d9164b357845132edb28","up":true},{"one":"8da9cdb3c78776ed230497b21d4ac172f0ce73e921dfddd483da7bc6bbcd1951dd78fd5f70a0acbad855b2984e4c4bdb408c4bc25cab40684fe5a4408ec7ab9c","other":"14136fa967f2d4825845ba4a43a5921d8fcf03f9c71c5595037e000b2ef6ff0a5eaad0980aea0a170cafda3529f982aea1107f58aa42485550c9480e86f5e9f3","up":true},{"one":"8f6fb4a5baf715e001b060ce72378829279ce06a3247bd4a6faa3c725ee1b949570373e4231de82981020563e704297e77172506101b1444fcacfcc5f211827e","other":"16bd57b6590df0c69c440d178da8359b0a3e00b9c5362155eae42709bdc4d0488e437fa7e8396d5b429cebe356ebd1407039b21eefa8d9164b357845132edb28","up":true},{"one":"d0718ce0dafea66ee16c79626e020355273cdd062c0fceb122e391c4ca6e4e408a1b0e8230c4ade5bc95803916bdd6d98c99d2b6ea70c32e17fa1f2c98741a90","other":"6d1af44ab259cc080a14c07bf5efabfd70cb847fe338f016c00138c84bddf6a6ce94047d1bffcfc7e9bc772dd7a080468a84655d5351d0056f97f13358b91547","up":true},{"one":"e53cfad611bc38a1090d28e4cc58e4738ccaa83a00bf5447cd30ec70e492dea5811b67e79b9ca8856e79801741a675c6f54eb7a1c39e95ab735164855eae0fb7","other":"07138ce506125910af81bd1bae11c22bfab9a81e1e057cc3d84769475c5da9873eb3f11edc6aca83ef486bfb63eba15a6233676d29d93ac9e774f10cd42c8cbd","up":true},{"one":"f70c92be150cb3f65f6bd904c8c161bfb0cea717bab0b24da63714de83e0872c8c369960ada1629607a1e166a19b6cfa887603e4868e7912ae5512744e8cc1c0","other":"16bd57b6590df0c69c440d178da8359b0a3e00b9c5362155eae42709bdc4d0488e437fa7e8396d5b429cebe356ebd1407039b21eefa8d9164b357845132edb28","up":true},{"one":"5b456e429f7adae30366206e681ba46439a3372fec3806f666425cb3f12983c0b427e089fb163b70e6a56220b1529ee392ff701bc2f4621d51e23aa6305150e8","other":"14136fa967f2d4825845ba4a43a5921d8fcf03f9c71c5595037e000b2ef6ff0a5eaad0980aea0a170cafda3529f982aea1107f58aa42485550c9480e86f5e9f3","up":true},{"one":"7a1f97c41c9efd7a2903af78f72d02cfff3631dc6260d3ceb2364c2a8e06965710e8feae6aa9f99b48b2475da10b2f9581c76d47b4cd2bfee09c43dcb5e3e5d9","other":"17c7eb5833687a98087daadda564e54b1c770f946efb7efd69370a9caf6e6939e408f04a3fa1aa042d9463992a711786e504072fae56d007d696851696fc5643","up":true},{"one":"38b3adde25c6407f29c2a721f1f5c082cc94ddad09fc5afda2bbb2309212a9b54b1553731a65ec8b58769fc11d488169c8000ee15fe8966bd44a3879e0c9e534","other":"f5272b71c228eb14b9e0e221deefc0a91353a5f17d01475f57fad54bb8e50e375f58019c7200a9ca45b0f1da6538708c61242e478d917499871df7a9d5857f1a","up":true},{"one":"e1082b4577aa370a5171b7602282208697dcead854f0c82acb5628d179fa5990a0fc85c5343a47177aab81c7fa6c1be8a27a3484acddc353582ddeb61892ef94","other":"61b32cded1b5ea3e2ca545a55c84251daaaacf51e6fed98fbdf4c5b6b91a554081e1e577aaaaaa4f911780f92703c1d715695d86c1be641b0bd1794f4107c2be","up":true},{"one":"dcf2401cbc26f3db27bb85c24984b1d755b3503fe400c139a0bedbe5de24db3f27c8f4f40adc1880b6142d20e67a40f3d45d36ba7fce122ffa44703e65622198","other":"c8e9cc707ce2a278371d1b4f64714cdae425b7c3606d18af6588dacaca35c7a171a07629247af351e667d2ddd9e71598f862125c827cc869c463cf87e4daeed0","up":true},{"one":"f5efffc8e894cecc065f6892ad2a846c8fc4982d1c8c7fc729421d5108d519c501cc9f2f7a0046ec08d47cf2369753aaf287dfc3ef7ecd34d24d294efb933658","other":"7722d7d06c66afb0642d5f9ae0b22ed812c632f2d62ce64315da40eb003feb3fae1b337c10df21d297beabe51b3879f2c0a725f08ee78a8e09c75f86bd0e2092","up":true},{"one":"6593097e880701f3d0573df7bff9ba7af40f4f83b828bfc11bdabea62fb94ed39c8233d8d40275c2af9ceddae44514e029a546fe9df73abbd3821d37933aba49","other":"0a45a0aa4b4eee71b2828c794281d698019667288cf51311ffae7d8ea895f8ae29f7958dbfcda8763d9d8e9c097dccc5f92ac9d09fb4ccbde178d7f5ebda4d35","up":true},{"one":"6eeb951b8f6d5ac519132910222777d5a409325e6c64d89708a00e55cb0fe85889aac1baa724e29fa7f064323b164a9c40c5114a65736e3dd16f0336283d9c7b","other":"25c64a52c298035be2184243082b5eba8a3a5d55c5334cea76e177d722945c8bf014a4ce9ef2ed76dc17a44234c97697337c6e001261533e72cc8266ee0e2fe4","up":true},{"one":"578666c4113e196a7c738fdbae0bd68ade450283eb835efd06591798f1893f7f7d9cde0691faff670b5ae24e58cbc2f549d2196f244dddc00e82852c38e8539e","other":"c8e9cc707ce2a278371d1b4f64714cdae425b7c3606d18af6588dacaca35c7a171a07629247af351e667d2ddd9e71598f862125c827cc869c463cf87e4daeed0","up":true},{"one":"6419279b600da3e2ee8d0b2a5b0319bc6cd496086955b49a8d2168fd4c35d5688291bc9313076b1b8e070f25dc593788d72b8f8c1d2ad828741a45deea35e58d","other":"d563716fbe2068cc940f7b12dc2bacb345c95f01e78e3b1f0105a441f300fdb00cc72e677aec102360fb904b63055d8581555f5b74b8f2392706569d8357c53f","up":true},{"one":"032b1ce6881413b7ade1918e56691c7acd9f24111f47792ca50c33e570afba433caa132ad2326d03f9c0544fdc09fa0ca65f61de9fe61d6dd92c5d25a8df69af","other":"e479930845e1dac2d5908894548cc06c132fc5820810c6f46d9adc2bc252dd40b64642a3b2005ad3688d2637c43967f570bd153db9ee6742e1b23dbfb72537fa","up":true},{"one":"351ceaf2e95e098a8e15e81c82073b523f641848326d1bbd379f40f886b50ce2c377c4e3a2dfc2662d6f25ac04dede41063a075cf00be1cf36f95b0267717ab8","other":"43b91c24dd7fd217a76f00ab97920e4223bd2ee085abe7ac34e915e8676400e1643d3bbb4a864c8a6df1298bf229cabd1bdc9879eafdcbcab064708e8266e88d","up":true},{"one":"8e1a66c9029330c25b9abe95a11878f41cef1a32b567a931ffa781c2f70a1336efa03ba1a66dac0080304803c1239be443991a251f24d0e9c2e26aebeb5437f8","other":"38b3adde25c6407f29c2a721f1f5c082cc94ddad09fc5afda2bbb2309212a9b54b1553731a65ec8b58769fc11d488169c8000ee15fe8966bd44a3879e0c9e534","up":true},{"one":"4f1a219f31e135208bf4caa314a14d8d48a5682941793431539efb5666b06bb5e3e9cb29b019ca414fb32961460556f2d99a04b12dc8ecbf05f43efe108803f5","other":"46bb2acc087482d40ab2ccbb387723158411ff4931423414e4d09891be8a31d11929e939e4be94b0cc355c49883e1835785ba1955d865f78748c2a0a2f6eee0a","up":true},{"one":"c8e9cc707ce2a278371d1b4f64714cdae425b7c3606d18af6588dacaca35c7a171a07629247af351e667d2ddd9e71598f862125c827cc869c463cf87e4daeed0","other":"8959c5cf825ebab14efeacf2807ad9498256a9e89a2ef00690c9ee23a3e934e111c52a5ddcc791b93f49424ac008095d8cb0da6905dfdeb62309fc4f6672e59e","up":true},{"one":"a48a667469a1344cb70f269b21fb3ca9e83823226749fd9c232be1b86ab9427888f2ecb20ddfa56da361463a061e192570f2f8da3fa967c473320ca85e382c53","other":"0a45a0aa4b4eee71b2828c794281d698019667288cf51311ffae7d8ea895f8ae29f7958dbfcda8763d9d8e9c097dccc5f92ac9d09fb4ccbde178d7f5ebda4d35","up":true},{"one":"f5272b71c228eb14b9e0e221deefc0a91353a5f17d01475f57fad54bb8e50e375f58019c7200a9ca45b0f1da6538708c61242e478d917499871df7a9d5857f1a","other":"d472383c453e6b0f1a632010bdd6c42a9668d328a8f8071e0407069f6fe413e2a0fd0551a09cc56ee5245d472e39a7b6295491dd256ae42e200a257f297743e3","up":true},{"one":"a48a667469a1344cb70f269b21fb3ca9e83823226749fd9c232be1b86ab9427888f2ecb20ddfa56da361463a061e192570f2f8da3fa967c473320ca85e382c53","other":"e73af1e2a834ee132564dd2e983c877b3ae230808d2b42da2ec91472eee6ee6595c439800ce980186b4b0d9a56b96babf747006c07b07513543eead8e102fff7","up":true},{"one":"f360c6599a0911337c7b96365fda1b2f64890bdb4483bb7e86bca15484f24c4efc0d1f6f56aa0c4fa5c205e6c1dbbf20d2ca3c2f8734f703fe6d672fa76a0d45","other":"578666c4113e196a7c738fdbae0bd68ade450283eb835efd06591798f1893f7f7d9cde0691faff670b5ae24e58cbc2f549d2196f244dddc00e82852c38e8539e","up":true},{"one":"af3f9dc00ce3cc156000f16a06c55c123ccdfabed89c9aee4478ff439b6f52a89d0501cff626d36b7f1852737955f7a036b25cf259580e8f46a3e0e44340b539","other":"c0f2f1409cf83d7a777f6af95931181eb5a36b14a156f444075071c896fc5b435638ead23c65a242105db527c809e2c46f7805c862c0eb5d444749ddf22a5060","up":true},{"one":"f6e4b1dc1fa95ceae2b932b178afdc2dd515832a191e0f49c916d5a04548d58ef9f8c1dda3fbc93a45e6d82517e6a573310b7bfb14bc38c57000aec9ff010391","other":"62b8e67a4ca956c1cf2ba7a538d39bfe8bccf747fe65be48c88270ad44ee7711c0e9a43bb3821feffc492dba9b58397768c755810121add9c980c9a2c696feb0","up":true},{"one":"d563716fbe2068cc940f7b12dc2bacb345c95f01e78e3b1f0105a441f300fdb00cc72e677aec102360fb904b63055d8581555f5b74b8f2392706569d8357c53f","other":"af3f9dc00ce3cc156000f16a06c55c123ccdfabed89c9aee4478ff439b6f52a89d0501cff626d36b7f1852737955f7a036b25cf259580e8f46a3e0e44340b539","up":true},{"one":"0dcef49b94fdcff024d706030fd4f513d0c6ad5f00b06a8b67abc454bbe5c2c74e939d491c0700e47ecee5cd7c7084603f62e626c34b454868b8f22d8c2dfb10","other":"c0f2f1409cf83d7a777f6af95931181eb5a36b14a156f444075071c896fc5b435638ead23c65a242105db527c809e2c46f7805c862c0eb5d444749ddf22a5060","up":true},{"one":"46bb2acc087482d40ab2ccbb387723158411ff4931423414e4d09891be8a31d11929e939e4be94b0cc355c49883e1835785ba1955d865f78748c2a0a2f6eee0a","other":"62b8e67a4ca956c1cf2ba7a538d39bfe8bccf747fe65be48c88270ad44ee7711c0e9a43bb3821feffc492dba9b58397768c755810121add9c980c9a2c696feb0","up":true},{"one":"8da9cdb3c78776ed230497b21d4ac172f0ce73e921dfddd483da7bc6bbcd1951dd78fd5f70a0acbad855b2984e4c4bdb408c4bc25cab40684fe5a4408ec7ab9c","other":"8e1a66c9029330c25b9abe95a11878f41cef1a32b567a931ffa781c2f70a1336efa03ba1a66dac0080304803c1239be443991a251f24d0e9c2e26aebeb5437f8","up":true},{"one":"8da75cb4e63d968a7999ca4b49572b5ae592a91fa442d44bb7c42fb4b174a365e1affa1dbc45b2a0406444505f178100768e7783831f2886d53e7d1b8a3a7291","other":"e53cfad611bc38a1090d28e4cc58e4738ccaa83a00bf5447cd30ec70e492dea5811b67e79b9ca8856e79801741a675c6f54eb7a1c39e95ab735164855eae0fb7","up":true},{"one":"e7d4478b412ef497741943736946a3b0679d21ae0c4cbdde6809c7236dcf1a40291088d872e469f06da19ed4ef77b9844aee7066c40fcd45b0931aff847de1d7","other":"c8e9cc707ce2a278371d1b4f64714cdae425b7c3606d18af6588dacaca35c7a171a07629247af351e667d2ddd9e71598f862125c827cc869c463cf87e4daeed0","up":true},{"one":"f360c6599a0911337c7b96365fda1b2f64890bdb4483bb7e86bca15484f24c4efc0d1f6f56aa0c4fa5c205e6c1dbbf20d2ca3c2f8734f703fe6d672fa76a0d45","other":"95c3ca2362de2eb0ac8efdd243918ed216f5d124bc6f5b9d83a6ee1aaf8a0fbdbd70ca1710d1ed825d6871f13a15954725f1aa1b27b48307844c0bc27baec0db","up":true},{"one":"7a1f97c41c9efd7a2903af78f72d02cfff3631dc6260d3ceb2364c2a8e06965710e8feae6aa9f99b48b2475da10b2f9581c76d47b4cd2bfee09c43dcb5e3e5d9","other":"46bb2acc087482d40ab2ccbb387723158411ff4931423414e4d09891be8a31d11929e939e4be94b0cc355c49883e1835785ba1955d865f78748c2a0a2f6eee0a","up":true},{"one":"07138ce506125910af81bd1bae11c22bfab9a81e1e057cc3d84769475c5da9873eb3f11edc6aca83ef486bfb63eba15a6233676d29d93ac9e774f10cd42c8cbd","other":"46bb2acc087482d40ab2ccbb387723158411ff4931423414e4d09891be8a31d11929e939e4be94b0cc355c49883e1835785ba1955d865f78748c2a0a2f6eee0a","up":true},{"one":"f5272b71c228eb14b9e0e221deefc0a91353a5f17d01475f57fad54bb8e50e375f58019c7200a9ca45b0f1da6538708c61242e478d917499871df7a9d5857f1a","other":"6419279b600da3e2ee8d0b2a5b0319bc6cd496086955b49a8d2168fd4c35d5688291bc9313076b1b8e070f25dc593788d72b8f8c1d2ad828741a45deea35e58d","up":true},{"one":"e53cfad611bc38a1090d28e4cc58e4738ccaa83a00bf5447cd30ec70e492dea5811b67e79b9ca8856e79801741a675c6f54eb7a1c39e95ab735164855eae0fb7","other":"46bb2acc087482d40ab2ccbb387723158411ff4931423414e4d09891be8a31d11929e939e4be94b0cc355c49883e1835785ba1955d865f78748c2a0a2f6eee0a","up":true},{"one":"6d1af44ab259cc080a14c07bf5efabfd70cb847fe338f016c00138c84bddf6a6ce94047d1bffcfc7e9bc772dd7a080468a84655d5351d0056f97f13358b91547","other":"e73af1e2a834ee132564dd2e983c877b3ae230808d2b42da2ec91472eee6ee6595c439800ce980186b4b0d9a56b96babf747006c07b07513543eead8e102fff7","up":true},{"one":"8e1a66c9029330c25b9abe95a11878f41cef1a32b567a931ffa781c2f70a1336efa03ba1a66dac0080304803c1239be443991a251f24d0e9c2e26aebeb5437f8","other":"78216c6660fff0b96e38084941a2f237996732118033bf842e5f9e533b22b36c2da996df28e866424311b7b6414d4627db1f22a235ae777f7de34d9696043ecb","up":true},{"one":"43b91c24dd7fd217a76f00ab97920e4223bd2ee085abe7ac34e915e8676400e1643d3bbb4a864c8a6df1298bf229cabd1bdc9879eafdcbcab064708e8266e88d","other":"62b8e67a4ca956c1cf2ba7a538d39bfe8bccf747fe65be48c88270ad44ee7711c0e9a43bb3821feffc492dba9b58397768c755810121add9c980c9a2c696feb0","up":true},{"one":"1691538e4cc41441c18fc92969c0c59f51da063814e8c45311605405284293503ee1570722cc7ae12f9cd63b899afaf5b3e66ca012115996074e8aaa71fda48c","other":"95c3ca2362de2eb0ac8efdd243918ed216f5d124bc6f5b9d83a6ee1aaf8a0fbdbd70ca1710d1ed825d6871f13a15954725f1aa1b27b48307844c0bc27baec0db","up":true},{"one":"c0f2f1409cf83d7a777f6af95931181eb5a36b14a156f444075071c896fc5b435638ead23c65a242105db527c809e2c46f7805c862c0eb5d444749ddf22a5060","other":"5e92b025cc087c8823423c287f274a32a3dc0065afdf189475ba96b0da7b785cd493b7f2a7f3bb8195c73025bfbb402cbb4e0f6ae0d5e0caab223193cf6f2e5c","up":true},{"one":"39d0aa13a6d7e709c9b914cb16f007c3f16af40532afa47c8cf9abf6d604d4380883103c995ec696ca593c4dc9bf0290979b965c9c6ade7c616d3973c5f0b1f0","other":"d0718ce0dafea66ee16c79626e020355273cdd062c0fceb122e391c4ca6e4e408a1b0e8230c4ade5bc95803916bdd6d98c99d2b6ea70c32e17fa1f2c98741a90","up":true},{"one":"14136fa967f2d4825845ba4a43a5921d8fcf03f9c71c5595037e000b2ef6ff0a5eaad0980aea0a170cafda3529f982aea1107f58aa42485550c9480e86f5e9f3","other":"e53cfad611bc38a1090d28e4cc58e4738ccaa83a00bf5447cd30ec70e492dea5811b67e79b9ca8856e79801741a675c6f54eb7a1c39e95ab735164855eae0fb7","up":true},{"one":"e021950ce89ce2bd79649aad2ed504789636b09870d0652fefa5e16631cb32a5d41c6cc4a540b7a0fca6bc3d5adf9b372a22cf714adc7b3e9b968d4c840017d4","other":"5b456e429f7adae30366206e681ba46439a3372fec3806f666425cb3f12983c0b427e089fb163b70e6a56220b1529ee392ff701bc2f4621d51e23aa6305150e8","up":true},{"one":"f5efffc8e894cecc065f6892ad2a846c8fc4982d1c8c7fc729421d5108d519c501cc9f2f7a0046ec08d47cf2369753aaf287dfc3ef7ecd34d24d294efb933658","other":"e7b1563d6e089e030983b075b590abb8a3205e9bce953f562b755ba150a3edc2dc3377259d96c05cc7363a23aed613711ca049e26253fd9273ac4c0483087015","up":true},{"one":"7c273dd4218e9e5b92e19d250832a424ff2ac5482ad70953746de780100669eb143247e15ccfca14cce9a49a003c82be71ca034a2900bed4c89fb10bdbfcc7c3","other":"5b456e429f7adae30366206e681ba46439a3372fec3806f666425cb3f12983c0b427e089fb163b70e6a56220b1529ee392ff701bc2f4621d51e23aa6305150e8","up":true},{"one":"8959c5cf825ebab14efeacf2807ad9498256a9e89a2ef00690c9ee23a3e934e111c52a5ddcc791b93f49424ac008095d8cb0da6905dfdeb62309fc4f6672e59e","other":"d563716fbe2068cc940f7b12dc2bacb345c95f01e78e3b1f0105a441f300fdb00cc72e677aec102360fb904b63055d8581555f5b74b8f2392706569d8357c53f","up":true},{"one":"e1082b4577aa370a5171b7602282208697dcead854f0c82acb5628d179fa5990a0fc85c5343a47177aab81c7fa6c1be8a27a3484acddc353582ddeb61892ef94","other":"7a45fa46f161fae3ef9013e9ab81145f4a76fa6ae22160424d6dc111acbd477ce43d4c10db89cb7451c97ea1fbd78428997d01fd17e1851f8b559b404ede6da7","up":true},{"one":"31cbd7c029d69715e59f31bccf362cd76e0a87839f1f63c6623be437d2af227a38f12c5fb9c659cc543976833caf22a52f5191c7c465a9ba36ac4235c12add72","other":"e021950ce89ce2bd79649aad2ed504789636b09870d0652fefa5e16631cb32a5d41c6cc4a540b7a0fca6bc3d5adf9b372a22cf714adc7b3e9b968d4c840017d4","up":true},{"one":"a4fbd2ffc25d2c3bd37beecd637dda5983cb5817ecb6da62aec16ea59aaf7e71966649211461564ba808174361898a1d2265f1a42e94434bc00d5d3e04b67a8a","other":"7722d7d06c66afb0642d5f9ae0b22ed812c632f2d62ce64315da40eb003feb3fae1b337c10df21d297beabe51b3879f2c0a725f08ee78a8e09c75f86bd0e2092","up":true},{"one":"a48a667469a1344cb70f269b21fb3ca9e83823226749fd9c232be1b86ab9427888f2ecb20ddfa56da361463a061e192570f2f8da3fa967c473320ca85e382c53","other":"86d55ece15e6bb4da7601f6587654505f760ee2b87abdb115091eefa93f61cf29fd695601bb8c6ae2c76400de24b8bca9ca32b50e4b849ae76f5320b03276bfc","up":true},{"one":"7a1f97c41c9efd7a2903af78f72d02cfff3631dc6260d3ceb2364c2a8e06965710e8feae6aa9f99b48b2475da10b2f9581c76d47b4cd2bfee09c43dcb5e3e5d9","other":"8e1a66c9029330c25b9abe95a11878f41cef1a32b567a931ffa781c2f70a1336efa03ba1a66dac0080304803c1239be443991a251f24d0e9c2e26aebeb5437f8","up":true},{"one":"c73f8fe9f54b89634cb0e8e332407a3a90cbbd347c0abc93823db13a7a39c46e7bd30d3f557316d92dd731cfc686afc308448682ff06c77246e3fb02b9a025ba","other":"707a9ae4bc8b37fff43dc3ba83ecb735bd428b720a751a11112452eec1ca49c09139bc437666add2823dd205e45cc793f8657c66ccbc6911cc60771d4512e038","up":true},{"one":"4f1a219f31e135208bf4caa314a14d8d48a5682941793431539efb5666b06bb5e3e9cb29b019ca414fb32961460556f2d99a04b12dc8ecbf05f43efe108803f5","other":"eb08a7774ca5252237d059a8bbad68044c83b2c332024be98bdc0c58508867a80cd34cb4162bd55a47fecc93301c8b2a7a1edbfd807ebb5623499cac80ea42de","up":true},{"one":"95c3ca2362de2eb0ac8efdd243918ed216f5d124bc6f5b9d83a6ee1aaf8a0fbdbd70ca1710d1ed825d6871f13a15954725f1aa1b27b48307844c0bc27baec0db","other":"14136fa967f2d4825845ba4a43a5921d8fcf03f9c71c5595037e000b2ef6ff0a5eaad0980aea0a170cafda3529f982aea1107f58aa42485550c9480e86f5e9f3","up":true},{"one":"6d1af44ab259cc080a14c07bf5efabfd70cb847fe338f016c00138c84bddf6a6ce94047d1bffcfc7e9bc772dd7a080468a84655d5351d0056f97f13358b91547","other":"e53cfad611bc38a1090d28e4cc58e4738ccaa83a00bf5447cd30ec70e492dea5811b67e79b9ca8856e79801741a675c6f54eb7a1c39e95ab735164855eae0fb7","up":true},{"one":"e479930845e1dac2d5908894548cc06c132fc5820810c6f46d9adc2bc252dd40b64642a3b2005ad3688d2637c43967f570bd153db9ee6742e1b23dbfb72537fa","other":"7c273dd4218e9e5b92e19d250832a424ff2ac5482ad70953746de780100669eb143247e15ccfca14cce9a49a003c82be71ca034a2900bed4c89fb10bdbfcc7c3","up":true},{"one":"e1082b4577aa370a5171b7602282208697dcead854f0c82acb5628d179fa5990a0fc85c5343a47177aab81c7fa6c1be8a27a3484acddc353582ddeb61892ef94","other":"25c64a52c298035be2184243082b5eba8a3a5d55c5334cea76e177d722945c8bf014a4ce9ef2ed76dc17a44234c97697337c6e001261533e72cc8266ee0e2fe4","up":true},{"one":"31cbd7c029d69715e59f31bccf362cd76e0a87839f1f63c6623be437d2af227a38f12c5fb9c659cc543976833caf22a52f5191c7c465a9ba36ac4235c12add72","other":"c8e9cc707ce2a278371d1b4f64714cdae425b7c3606d18af6588dacaca35c7a171a07629247af351e667d2ddd9e71598f862125c827cc869c463cf87e4daeed0","up":true},{"one":"6419279b600da3e2ee8d0b2a5b0319bc6cd496086955b49a8d2168fd4c35d5688291bc9313076b1b8e070f25dc593788d72b8f8c1d2ad828741a45deea35e58d","other":"16bd57b6590df0c69c440d178da8359b0a3e00b9c5362155eae42709bdc4d0488e437fa7e8396d5b429cebe356ebd1407039b21eefa8d9164b357845132edb28","up":true},{"one":"a4fbd2ffc25d2c3bd37beecd637dda5983cb5817ecb6da62aec16ea59aaf7e71966649211461564ba808174361898a1d2265f1a42e94434bc00d5d3e04b67a8a","other":"43b91c24dd7fd217a76f00ab97920e4223bd2ee085abe7ac34e915e8676400e1643d3bbb4a864c8a6df1298bf229cabd1bdc9879eafdcbcab064708e8266e88d","up":true},{"one":"62b8e67a4ca956c1cf2ba7a538d39bfe8bccf747fe65be48c88270ad44ee7711c0e9a43bb3821feffc492dba9b58397768c755810121add9c980c9a2c696feb0","other":"6d1af44ab259cc080a14c07bf5efabfd70cb847fe338f016c00138c84bddf6a6ce94047d1bffcfc7e9bc772dd7a080468a84655d5351d0056f97f13358b91547","up":true},{"one":"17c7eb5833687a98087daadda564e54b1c770f946efb7efd69370a9caf6e6939e408f04a3fa1aa042d9463992a711786e504072fae56d007d696851696fc5643","other":"6d1af44ab259cc080a14c07bf5efabfd70cb847fe338f016c00138c84bddf6a6ce94047d1bffcfc7e9bc772dd7a080468a84655d5351d0056f97f13358b91547","up":true},{"one":"f5efffc8e894cecc065f6892ad2a846c8fc4982d1c8c7fc729421d5108d519c501cc9f2f7a0046ec08d47cf2369753aaf287dfc3ef7ecd34d24d294efb933658","other":"8da75cb4e63d968a7999ca4b49572b5ae592a91fa442d44bb7c42fb4b174a365e1affa1dbc45b2a0406444505f178100768e7783831f2886d53e7d1b8a3a7291","up":true},{"one":"8959c5cf825ebab14efeacf2807ad9498256a9e89a2ef00690c9ee23a3e934e111c52a5ddcc791b93f49424ac008095d8cb0da6905dfdeb62309fc4f6672e59e","other":"7722d7d06c66afb0642d5f9ae0b22ed812c632f2d62ce64315da40eb003feb3fae1b337c10df21d297beabe51b3879f2c0a725f08ee78a8e09c75f86bd0e2092","up":true},{"one":"6593097e880701f3d0573df7bff9ba7af40f4f83b828bfc11bdabea62fb94ed39c8233d8d40275c2af9ceddae44514e029a546fe9df73abbd3821d37933aba49","other":"86d55ece15e6bb4da7601f6587654505f760ee2b87abdb115091eefa93f61cf29fd695601bb8c6ae2c76400de24b8bca9ca32b50e4b849ae76f5320b03276bfc","up":true},{"one":"578666c4113e196a7c738fdbae0bd68ade450283eb835efd06591798f1893f7f7d9cde0691faff670b5ae24e58cbc2f549d2196f244dddc00e82852c38e8539e","other":"5b456e429f7adae30366206e681ba46439a3372fec3806f666425cb3f12983c0b427e089fb163b70e6a56220b1529ee392ff701bc2f4621d51e23aa6305150e8","up":true},{"one":"a48a667469a1344cb70f269b21fb3ca9e83823226749fd9c232be1b86ab9427888f2ecb20ddfa56da361463a061e192570f2f8da3fa967c473320ca85e382c53","other":"7722d7d06c66afb0642d5f9ae0b22ed812c632f2d62ce64315da40eb003feb3fae1b337c10df21d297beabe51b3879f2c0a725f08ee78a8e09c75f86bd0e2092","up":true},{"one":"c73f8fe9f54b89634cb0e8e332407a3a90cbbd347c0abc93823db13a7a39c46e7bd30d3f557316d92dd731cfc686afc308448682ff06c77246e3fb02b9a025ba","other":"351ceaf2e95e098a8e15e81c82073b523f641848326d1bbd379f40f886b50ce2c377c4e3a2dfc2662d6f25ac04dede41063a075cf00be1cf36f95b0267717ab8","up":true},{"one":"6d1af44ab259cc080a14c07bf5efabfd70cb847fe338f016c00138c84bddf6a6ce94047d1bffcfc7e9bc772dd7a080468a84655d5351d0056f97f13358b91547","other":"c8e9cc707ce2a278371d1b4f64714cdae425b7c3606d18af6588dacaca35c7a171a07629247af351e667d2ddd9e71598f862125c827cc869c463cf87e4daeed0","up":true},{"one":"8da75cb4e63d968a7999ca4b49572b5ae592a91fa442d44bb7c42fb4b174a365e1affa1dbc45b2a0406444505f178100768e7783831f2886d53e7d1b8a3a7291","other":"c8e9cc707ce2a278371d1b4f64714cdae425b7c3606d18af6588dacaca35c7a171a07629247af351e667d2ddd9e71598f862125c827cc869c463cf87e4daeed0","up":true},{"one":"0dcef49b94fdcff024d706030fd4f513d0c6ad5f00b06a8b67abc454bbe5c2c74e939d491c0700e47ecee5cd7c7084603f62e626c34b454868b8f22d8c2dfb10","other":"a4fbd2ffc25d2c3bd37beecd637dda5983cb5817ecb6da62aec16ea59aaf7e71966649211461564ba808174361898a1d2265f1a42e94434bc00d5d3e04b67a8a","up":true},{"one":"7a1f97c41c9efd7a2903af78f72d02cfff3631dc6260d3ceb2364c2a8e06965710e8feae6aa9f99b48b2475da10b2f9581c76d47b4cd2bfee09c43dcb5e3e5d9","other":"e7d4478b412ef497741943736946a3b0679d21ae0c4cbdde6809c7236dcf1a40291088d872e469f06da19ed4ef77b9844aee7066c40fcd45b0931aff847de1d7","up":true},{"one":"f5272b71c228eb14b9e0e221deefc0a91353a5f17d01475f57fad54bb8e50e375f58019c7200a9ca45b0f1da6538708c61242e478d917499871df7a9d5857f1a","other":"eb08a7774ca5252237d059a8bbad68044c83b2c332024be98bdc0c58508867a80cd34cb4162bd55a47fecc93301c8b2a7a1edbfd807ebb5623499cac80ea42de","up":true},{"one":"f5efffc8e894cecc065f6892ad2a846c8fc4982d1c8c7fc729421d5108d519c501cc9f2f7a0046ec08d47cf2369753aaf287dfc3ef7ecd34d24d294efb933658","other":"0dcef49b94fdcff024d706030fd4f513d0c6ad5f00b06a8b67abc454bbe5c2c74e939d491c0700e47ecee5cd7c7084603f62e626c34b454868b8f22d8c2dfb10","up":true},{"one":"7c273dd4218e9e5b92e19d250832a424ff2ac5482ad70953746de780100669eb143247e15ccfca14cce9a49a003c82be71ca034a2900bed4c89fb10bdbfcc7c3","other":"f360c6599a0911337c7b96365fda1b2f64890bdb4483bb7e86bca15484f24c4efc0d1f6f56aa0c4fa5c205e6c1dbbf20d2ca3c2f8734f703fe6d672fa76a0d45","up":true},{"one":"14136fa967f2d4825845ba4a43a5921d8fcf03f9c71c5595037e000b2ef6ff0a5eaad0980aea0a170cafda3529f982aea1107f58aa42485550c9480e86f5e9f3","other":"e021950ce89ce2bd79649aad2ed504789636b09870d0652fefa5e16631cb32a5d41c6cc4a540b7a0fca6bc3d5adf9b372a22cf714adc7b3e9b968d4c840017d4","up":true},{"one":"6593097e880701f3d0573df7bff9ba7af40f4f83b828bfc11bdabea62fb94ed39c8233d8d40275c2af9ceddae44514e029a546fe9df73abbd3821d37933aba49","other":"7722d7d06c66afb0642d5f9ae0b22ed812c632f2d62ce64315da40eb003feb3fae1b337c10df21d297beabe51b3879f2c0a725f08ee78a8e09c75f86bd0e2092","up":true},{"one":"6eeb951b8f6d5ac519132910222777d5a409325e6c64d89708a00e55cb0fe85889aac1baa724e29fa7f064323b164a9c40c5114a65736e3dd16f0336283d9c7b","other":"9e51eb48f59886e70eb8d02e1c0c4423de3f0ce79c7a62bfd91bc2048cf643f40a91e2d2a1a8a19a9e4ba4a96aed0965aefcd941c068208abe8bf5029eb27d55","up":true},{"one":"032b1ce6881413b7ade1918e56691c7acd9f24111f47792ca50c33e570afba433caa132ad2326d03f9c0544fdc09fa0ca65f61de9fe61d6dd92c5d25a8df69af","other":"7a1f97c41c9efd7a2903af78f72d02cfff3631dc6260d3ceb2364c2a8e06965710e8feae6aa9f99b48b2475da10b2f9581c76d47b4cd2bfee09c43dcb5e3e5d9","up":true},{"one":"95c3ca2362de2eb0ac8efdd243918ed216f5d124bc6f5b9d83a6ee1aaf8a0fbdbd70ca1710d1ed825d6871f13a15954725f1aa1b27b48307844c0bc27baec0db","other":"578666c4113e196a7c738fdbae0bd68ade450283eb835efd06591798f1893f7f7d9cde0691faff670b5ae24e58cbc2f549d2196f244dddc00e82852c38e8539e","up":true},{"one":"0dcef49b94fdcff024d706030fd4f513d0c6ad5f00b06a8b67abc454bbe5c2c74e939d491c0700e47ecee5cd7c7084603f62e626c34b454868b8f22d8c2dfb10","other":"707a9ae4bc8b37fff43dc3ba83ecb735bd428b720a751a11112452eec1ca49c09139bc437666add2823dd205e45cc793f8657c66ccbc6911cc60771d4512e038","up":true},{"one":"14136fa967f2d4825845ba4a43a5921d8fcf03f9c71c5595037e000b2ef6ff0a5eaad0980aea0a170cafda3529f982aea1107f58aa42485550c9480e86f5e9f3","other":"f360c6599a0911337c7b96365fda1b2f64890bdb4483bb7e86bca15484f24c4efc0d1f6f56aa0c4fa5c205e6c1dbbf20d2ca3c2f8734f703fe6d672fa76a0d45","up":true},{"one":"6eeb951b8f6d5ac519132910222777d5a409325e6c64d89708a00e55cb0fe85889aac1baa724e29fa7f064323b164a9c40c5114a65736e3dd16f0336283d9c7b","other":"4f1a219f31e135208bf4caa314a14d8d48a5682941793431539efb5666b06bb5e3e9cb29b019ca414fb32961460556f2d99a04b12dc8ecbf05f43efe108803f5","up":true},{"one":"e1082b4577aa370a5171b7602282208697dcead854f0c82acb5628d179fa5990a0fc85c5343a47177aab81c7fa6c1be8a27a3484acddc353582ddeb61892ef94","other":"f5272b71c228eb14b9e0e221deefc0a91353a5f17d01475f57fad54bb8e50e375f58019c7200a9ca45b0f1da6538708c61242e478d917499871df7a9d5857f1a","up":true},{"one":"032b1ce6881413b7ade1918e56691c7acd9f24111f47792ca50c33e570afba433caa132ad2326d03f9c0544fdc09fa0ca65f61de9fe61d6dd92c5d25a8df69af","other":"f360c6599a0911337c7b96365fda1b2f64890bdb4483bb7e86bca15484f24c4efc0d1f6f56aa0c4fa5c205e6c1dbbf20d2ca3c2f8734f703fe6d672fa76a0d45","up":true},{"one":"a4fbd2ffc25d2c3bd37beecd637dda5983cb5817ecb6da62aec16ea59aaf7e71966649211461564ba808174361898a1d2265f1a42e94434bc00d5d3e04b67a8a","other":"8da75cb4e63d968a7999ca4b49572b5ae592a91fa442d44bb7c42fb4b174a365e1affa1dbc45b2a0406444505f178100768e7783831f2886d53e7d1b8a3a7291","up":true},{"one":"31cbd7c029d69715e59f31bccf362cd76e0a87839f1f63c6623be437d2af227a38f12c5fb9c659cc543976833caf22a52f5191c7c465a9ba36ac4235c12add72","other":"8e1a66c9029330c25b9abe95a11878f41cef1a32b567a931ffa781c2f70a1336efa03ba1a66dac0080304803c1239be443991a251f24d0e9c2e26aebeb5437f8","up":true},{"one":"0dcef49b94fdcff024d706030fd4f513d0c6ad5f00b06a8b67abc454bbe5c2c74e939d491c0700e47ecee5cd7c7084603f62e626c34b454868b8f22d8c2dfb10","other":"c73f8fe9f54b89634cb0e8e332407a3a90cbbd347c0abc93823db13a7a39c46e7bd30d3f557316d92dd731cfc686afc308448682ff06c77246e3fb02b9a025ba","up":true},{"one":"f5272b71c228eb14b9e0e221deefc0a91353a5f17d01475f57fad54bb8e50e375f58019c7200a9ca45b0f1da6538708c61242e478d917499871df7a9d5857f1a","other":"8959c5cf825ebab14efeacf2807ad9498256a9e89a2ef00690c9ee23a3e934e111c52a5ddcc791b93f49424ac008095d8cb0da6905dfdeb62309fc4f6672e59e","up":true},{"one":"16bd57b6590df0c69c440d178da8359b0a3e00b9c5362155eae42709bdc4d0488e437fa7e8396d5b429cebe356ebd1407039b21eefa8d9164b357845132edb28","other":"38b3adde25c6407f29c2a721f1f5c082cc94ddad09fc5afda2bbb2309212a9b54b1553731a65ec8b58769fc11d488169c8000ee15fe8966bd44a3879e0c9e534","up":true},{"one":"6eeb951b8f6d5ac519132910222777d5a409325e6c64d89708a00e55cb0fe85889aac1baa724e29fa7f064323b164a9c40c5114a65736e3dd16f0336283d9c7b","other":"e53cfad611bc38a1090d28e4cc58e4738ccaa83a00bf5447cd30ec70e492dea5811b67e79b9ca8856e79801741a675c6f54eb7a1c39e95ab735164855eae0fb7","up":true},{"one":"032b1ce6881413b7ade1918e56691c7acd9f24111f47792ca50c33e570afba433caa132ad2326d03f9c0544fdc09fa0ca65f61de9fe61d6dd92c5d25a8df69af","other":"e7d4478b412ef497741943736946a3b0679d21ae0c4cbdde6809c7236dcf1a40291088d872e469f06da19ed4ef77b9844aee7066c40fcd45b0931aff847de1d7","up":true},{"one":"f5272b71c228eb14b9e0e221deefc0a91353a5f17d01475f57fad54bb8e50e375f58019c7200a9ca45b0f1da6538708c61242e478d917499871df7a9d5857f1a","other":"9529ff2b0692ad2608b55ec8ec0d1c9ccb8ee300412d99d389009162a76f7eec28d1090cbfb571aa8396b365074770b17106bfa3354857878dff164f42686142","up":true},{"one":"f5272b71c228eb14b9e0e221deefc0a91353a5f17d01475f57fad54bb8e50e375f58019c7200a9ca45b0f1da6538708c61242e478d917499871df7a9d5857f1a","other":"6d1af44ab259cc080a14c07bf5efabfd70cb847fe338f016c00138c84bddf6a6ce94047d1bffcfc7e9bc772dd7a080468a84655d5351d0056f97f13358b91547","up":false},{"one":"9e51eb48f59886e70eb8d02e1c0c4423de3f0ce79c7a62bfd91bc2048cf643f40a91e2d2a1a8a19a9e4ba4a96aed0965aefcd941c068208abe8bf5029eb27d55","other":"dcf2401cbc26f3db27bb85c24984b1d755b3503fe400c139a0bedbe5de24db3f27c8f4f40adc1880b6142d20e67a40f3d45d36ba7fce122ffa44703e65622198","up":true}]} \ No newline at end of file diff --git a/swarm/network/syncdb.go b/swarm/network/syncdb.go deleted file mode 100644 index 88b4b68dd0..0000000000 --- a/swarm/network/syncdb.go +++ /dev/null @@ -1,389 +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 network - -import ( - "encoding/binary" - "fmt" - - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/swarm/storage" - "github.com/syndtr/goleveldb/leveldb" - "github.com/syndtr/goleveldb/leveldb/iterator" -) - -const counterKeyPrefix = 0x01 - -/* -syncDb is a queueing service for outgoing deliveries. -One instance per priority queue for each peer - -a syncDb instance maintains an in-memory buffer (of capacity bufferSize) -once its in-memory buffer is full it switches to persisting in db -and dbRead iterator iterates through the items keeping their order -once the db read catches up (there is no more items in the db) then -it switches back to in-memory buffer. - -when syncdb is stopped all items in the buffer are saved to the db -*/ -type syncDb struct { - start []byte // this syncdb starting index in requestdb - key storage.Key // remote peers address key - counterKey []byte // db key to persist counter - priority uint // priotity High|Medium|Low - buffer chan interface{} // incoming request channel - db *storage.LDBDatabase // underlying db (TODO should be interface) - done chan bool // chan to signal goroutines finished quitting - quit chan bool // chan to signal quitting to goroutines - total, dbTotal int // counts for one session - batch chan chan int // channel for batch requests - dbBatchSize uint // number of items before batch is saved -} - -// constructor needs a shared request db (leveldb) -// priority is used in the index key -// uses a buffer and a leveldb for persistent storage -// bufferSize, dbBatchSize are config parameters -func newSyncDb(db *storage.LDBDatabase, key storage.Key, priority uint, bufferSize, dbBatchSize uint, deliver func(interface{}, chan bool) bool) *syncDb { - start := make([]byte, 42) - start[1] = byte(priorities - priority) - copy(start[2:34], key) - - counterKey := make([]byte, 34) - counterKey[0] = counterKeyPrefix - copy(counterKey[1:], start[1:34]) - - syncdb := &syncDb{ - start: start, - key: key, - counterKey: counterKey, - priority: priority, - buffer: make(chan interface{}, bufferSize), - db: db, - done: make(chan bool), - quit: make(chan bool), - batch: make(chan chan int), - dbBatchSize: dbBatchSize, - } - log.Trace(fmt.Sprintf("syncDb[peer: %v, priority: %v] - initialised", key.Log(), priority)) - - // starts the main forever loop reading from buffer - go syncdb.bufferRead(deliver) - return syncdb -} - -/* -bufferRead is a forever iterator loop that takes care of delivering -outgoing store requests reads from incoming buffer - -its argument is the deliver function taking the item as first argument -and a quit channel as second. -Closing of this channel is supposed to abort all waiting for delivery -(typically network write) - -The iteration switches between 2 modes, -* buffer mode reads the in-memory buffer and delivers the items directly -* db mode reads from the buffer and writes to the db, parallelly another -routine is started that reads from the db and delivers items - -If there is buffer contention in buffer mode (slow network, high upload volume) -syncdb switches to db mode and starts dbRead -Once db backlog is delivered, it reverts back to in-memory buffer - -It is automatically started when syncdb is initialised. - -It saves the buffer to db upon receiving quit signal. syncDb#stop() -*/ -func (self *syncDb) bufferRead(deliver func(interface{}, chan bool) bool) { - var buffer, db chan interface{} // channels representing the two read modes - var more bool - var req interface{} - var entry *syncDbEntry - var inBatch, inDb int - batch := new(leveldb.Batch) - var dbSize chan int - quit := self.quit - counterValue := make([]byte, 8) - - // counter is used for keeping the items in order, persisted to db - // start counter where db was at, 0 if not found - data, err := self.db.Get(self.counterKey) - var counter uint64 - if err == nil { - counter = binary.BigEndian.Uint64(data) - log.Trace(fmt.Sprintf("syncDb[%v/%v] - counter read from db at %v", self.key.Log(), self.priority, counter)) - } else { - log.Trace(fmt.Sprintf("syncDb[%v/%v] - counter starts at %v", self.key.Log(), self.priority, counter)) - } - -LOOP: - for { - // waiting for item next in the buffer, or quit signal or batch request - select { - // buffer only closes when writing to db - case req = <-buffer: - // deliver request : this is blocking on network write so - // it is passed the quit channel as argument, so that it returns - // if syncdb is stopped. In this case we need to save the item to the db - more = deliver(req, self.quit) - if !more { - log.Debug(fmt.Sprintf("syncDb[%v/%v] quit: switching to db. session tally (db/total): %v/%v", self.key.Log(), self.priority, self.dbTotal, self.total)) - // received quit signal, save request currently waiting delivery - // by switching to db mode and closing the buffer - buffer = nil - db = self.buffer - close(db) - quit = nil // needs to block the quit case in select - break // break from select, this item will be written to the db - } - self.total++ - log.Trace(fmt.Sprintf("syncDb[%v/%v] deliver (db/total): %v/%v", self.key.Log(), self.priority, self.dbTotal, self.total)) - // by the time deliver returns, there were new writes to the buffer - // if buffer contention is detected, switch to db mode which drains - // the buffer so no process will block on pushing store requests - if len(buffer) == cap(buffer) { - log.Debug(fmt.Sprintf("syncDb[%v/%v] buffer full %v: switching to db. session tally (db/total): %v/%v", self.key.Log(), self.priority, cap(buffer), self.dbTotal, self.total)) - buffer = nil - db = self.buffer - } - continue LOOP - - // incoming entry to put into db - case req, more = <-db: - if !more { - // only if quit is called, saved all the buffer - binary.BigEndian.PutUint64(counterValue, counter) - batch.Put(self.counterKey, counterValue) // persist counter in batch - self.writeSyncBatch(batch) // save batch - log.Trace(fmt.Sprintf("syncDb[%v/%v] quitting: save current batch to db", self.key.Log(), self.priority)) - break LOOP - } - self.dbTotal++ - self.total++ - // otherwise break after select - case dbSize = <-self.batch: - // explicit request for batch - if inBatch == 0 && quit != nil { - // there was no writes since the last batch so db depleted - // switch to buffer mode - log.Debug(fmt.Sprintf("syncDb[%v/%v] empty db: switching to buffer", self.key.Log(), self.priority)) - db = nil - buffer = self.buffer - dbSize <- 0 // indicates to 'caller' that batch has been written - inDb = 0 - continue LOOP - } - binary.BigEndian.PutUint64(counterValue, counter) - batch.Put(self.counterKey, counterValue) - log.Debug(fmt.Sprintf("syncDb[%v/%v] write batch %v/%v - %x - %x", self.key.Log(), self.priority, inBatch, counter, self.counterKey, counterValue)) - batch = self.writeSyncBatch(batch) - dbSize <- inBatch // indicates to 'caller' that batch has been written - inBatch = 0 - continue LOOP - - // closing syncDb#quit channel is used to signal to all goroutines to quit - case <-quit: - // need to save backlog, so switch to db mode - db = self.buffer - buffer = nil - quit = nil - log.Trace(fmt.Sprintf("syncDb[%v/%v] quitting: save buffer to db", self.key.Log(), self.priority)) - close(db) - continue LOOP - } - - // only get here if we put req into db - entry, err = self.newSyncDbEntry(req, counter) - if err != nil { - log.Warn(fmt.Sprintf("syncDb[%v/%v] saving request %v (#%v/%v) failed: %v", self.key.Log(), self.priority, req, inBatch, inDb, err)) - continue LOOP - } - batch.Put(entry.key, entry.val) - log.Trace(fmt.Sprintf("syncDb[%v/%v] to batch %v '%v' (#%v/%v/%v)", self.key.Log(), self.priority, req, entry, inBatch, inDb, counter)) - // if just switched to db mode and not quitting, then launch dbRead - // in a parallel go routine to send deliveries from db - if inDb == 0 && quit != nil { - log.Trace(fmt.Sprintf("syncDb[%v/%v] start dbRead", self.key.Log(), self.priority)) - go self.dbRead(true, counter, deliver) - } - inDb++ - inBatch++ - counter++ - // need to save the batch if it gets too large (== dbBatchSize) - if inBatch%int(self.dbBatchSize) == 0 { - batch = self.writeSyncBatch(batch) - } - } - log.Info(fmt.Sprintf("syncDb[%v:%v]: saved %v keys (saved counter at %v)", self.key.Log(), self.priority, inBatch, counter)) - close(self.done) -} - -// writes the batch to the db and returns a new batch object -func (self *syncDb) writeSyncBatch(batch *leveldb.Batch) *leveldb.Batch { - err := self.db.Write(batch) - if err != nil { - log.Warn(fmt.Sprintf("syncDb[%v/%v] saving batch to db failed: %v", self.key.Log(), self.priority, err)) - return batch - } - return new(leveldb.Batch) -} - -// abstract type for db entries (TODO could be a feature of Receipts) -type syncDbEntry struct { - key, val []byte -} - -func (self syncDbEntry) String() string { - return fmt.Sprintf("key: %x, value: %x", self.key, self.val) -} - -/* - dbRead is iterating over store requests to be sent over to the peer - this is mainly to prevent crashes due to network output buffer contention (???) - as well as to make syncronisation resilient to disconnects - the messages are supposed to be sent in the p2p priority queue. - - the request DB is shared between peers, but domains for each syncdb - are disjoint. dbkeys (42 bytes) are structured: - * 0: 0x00 (0x01 reserved for counter key) - * 1: priorities - priority (so that high priority can be replayed first) - * 2-33: peers address - * 34-41: syncdb counter to preserve order (this field is missing for the counter key) - - values (40 bytes) are: - * 0-31: key - * 32-39: request id - -dbRead needs a boolean to indicate if on first round all the historical -record is synced. Second argument to indicate current db counter -The third is the function to apply -*/ -func (self *syncDb) dbRead(useBatches bool, counter uint64, fun func(interface{}, chan bool) bool) { - key := make([]byte, 42) - copy(key, self.start) - binary.BigEndian.PutUint64(key[34:], counter) - var batches, n, cnt, total int - var more bool - var entry *syncDbEntry - var it iterator.Iterator - var del *leveldb.Batch - batchSizes := make(chan int) - - for { - // if useBatches is false, cnt is not set - if useBatches { - // this could be called before all cnt items sent out - // so that loop is not blocking while delivering - // only relevant if cnt is large - select { - case self.batch <- batchSizes: - case <-self.quit: - return - } - // wait for the write to finish and get the item count in the next batch - cnt = <-batchSizes - batches++ - if cnt == 0 { - // empty - return - } - } - it = self.db.NewIterator() - it.Seek(key) - if !it.Valid() { - copy(key, self.start) - useBatches = true - continue - } - del = new(leveldb.Batch) - log.Trace(fmt.Sprintf("syncDb[%v/%v]: new iterator: %x (batch %v, count %v)", self.key.Log(), self.priority, key, batches, cnt)) - - for n = 0; !useBatches || n < cnt; it.Next() { - copy(key, it.Key()) - if len(key) == 0 || key[0] != 0 { - copy(key, self.start) - useBatches = true - break - } - val := make([]byte, 40) - copy(val, it.Value()) - entry = &syncDbEntry{key, val} - // log.Trace(fmt.Sprintf("syncDb[%v/%v] - %v, batches: %v, total: %v, session total from db: %v/%v", self.key.Log(), self.priority, self.key.Log(), batches, total, self.dbTotal, self.total)) - more = fun(entry, self.quit) - if !more { - // quit received when waiting to deliver entry, the entry will not be deleted - log.Trace(fmt.Sprintf("syncDb[%v/%v] batch %v quit after %v/%v items", self.key.Log(), self.priority, batches, n, cnt)) - break - } - // since subsequent batches of the same db session are indexed incrementally - // deleting earlier batches can be delayed and parallelised - // this could be batch delete when db is idle (but added complexity esp when quitting) - del.Delete(key) - n++ - total++ - } - log.Debug(fmt.Sprintf("syncDb[%v/%v] - db session closed, batches: %v, total: %v, session total from db: %v/%v", self.key.Log(), self.priority, batches, total, self.dbTotal, self.total)) - self.db.Write(del) // this could be async called only when db is idle - it.Release() - } -} - -// -func (self *syncDb) stop() { - close(self.quit) - <-self.done -} - -// calculate a dbkey for the request, for the db to work -// see syncdb for db key structure -// polimorphic: accepted types, see syncer#addRequest -func (self *syncDb) newSyncDbEntry(req interface{}, counter uint64) (entry *syncDbEntry, err error) { - var key storage.Key - var chunk *storage.Chunk - var id uint64 - var ok bool - var sreq *storeRequestMsgData - - if key, ok = req.(storage.Key); ok { - id = generateId() - } else if chunk, ok = req.(*storage.Chunk); ok { - key = chunk.Key - id = generateId() - } else if sreq, ok = req.(*storeRequestMsgData); ok { - key = sreq.Key - id = sreq.Id - } else if entry, ok = req.(*syncDbEntry); !ok { - return nil, fmt.Errorf("type not allowed: %v (%T)", req, req) - } - - // order by peer > priority > seqid - // value is request id if exists - if entry == nil { - dbkey := make([]byte, 42) - dbval := make([]byte, 40) - - // encode key - copy(dbkey[:], self.start[:34]) // db peer - binary.BigEndian.PutUint64(dbkey[34:], counter) - // encode value - copy(dbval, key[:]) - binary.BigEndian.PutUint64(dbval[32:], id) - - entry = &syncDbEntry{dbkey, dbval} - } - return -} diff --git a/swarm/network/syncdb_test.go b/swarm/network/syncdb_test.go deleted file mode 100644 index be21d156f9..0000000000 --- a/swarm/network/syncdb_test.go +++ /dev/null @@ -1,222 +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 network - -import ( - "bytes" - "fmt" - "io/ioutil" - "os" - "path/filepath" - "testing" - "time" - - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/swarm/storage" -) - -func init() { - log.Root().SetHandler(log.LvlFilterHandler(log.LvlCrit, log.StreamHandler(os.Stderr, log.TerminalFormat(false)))) -} - -type testSyncDb struct { - *syncDb - c int - t *testing.T - fromDb chan bool - delivered [][]byte - sent []int - dbdir string - at int -} - -func newTestSyncDb(priority, bufferSize, batchSize int, dbdir string, t *testing.T) *testSyncDb { - if len(dbdir) == 0 { - tmp, err := ioutil.TempDir(os.TempDir(), "syncdb-test") - if err != nil { - t.Fatalf("unable to create temporary direcory %v: %v", tmp, err) - } - dbdir = tmp - } - db, err := storage.NewLDBDatabase(filepath.Join(dbdir, "requestdb")) - if err != nil { - t.Fatalf("unable to create db: %v", err) - } - self := &testSyncDb{ - fromDb: make(chan bool), - dbdir: dbdir, - t: t, - } - h := crypto.Keccak256Hash([]byte{0}) - key := storage.Key(h[:]) - self.syncDb = newSyncDb(db, key, uint(priority), uint(bufferSize), uint(batchSize), self.deliver) - // kick off db iterator right away, if no items on db this will allow - // reading from the buffer - return self - -} - -func (self *testSyncDb) close() { - self.db.Close() - os.RemoveAll(self.dbdir) -} - -func (self *testSyncDb) push(n int) { - for i := 0; i < n; i++ { - self.buffer <- storage.Key(crypto.Keccak256([]byte{byte(self.c)})) - self.sent = append(self.sent, self.c) - self.c++ - } - log.Debug(fmt.Sprintf("pushed %v requests", n)) -} - -func (self *testSyncDb) draindb() { - it := self.db.NewIterator() - defer it.Release() - for { - it.Seek(self.start) - if !it.Valid() { - return - } - k := it.Key() - if len(k) == 0 || k[0] == 1 { - return - } - it.Release() - it = self.db.NewIterator() - } -} - -func (self *testSyncDb) deliver(req interface{}, quit chan bool) bool { - _, db := req.(*syncDbEntry) - key, _, _, _, err := parseRequest(req) - if err != nil { - self.t.Fatalf("unexpected error of key %v: %v", key, err) - } - self.delivered = append(self.delivered, key) - select { - case self.fromDb <- db: - return true - case <-quit: - return false - } -} - -func (self *testSyncDb) expect(n int, db bool) { - var ok bool - // for n items - for i := 0; i < n; i++ { - ok = <-self.fromDb - if self.at+1 > len(self.delivered) { - self.t.Fatalf("expected %v, got %v", self.at+1, len(self.delivered)) - } - if len(self.sent) > self.at && !bytes.Equal(crypto.Keccak256([]byte{byte(self.sent[self.at])}), self.delivered[self.at]) { - self.t.Fatalf("expected delivery %v/%v/%v to be hash of %v, from db: %v = %v", i, n, self.at, self.sent[self.at], ok, db) - log.Debug(fmt.Sprintf("%v/%v/%v to be hash of %v, from db: %v = %v", i, n, self.at, self.sent[self.at], ok, db)) - } - if !ok && db { - self.t.Fatalf("expected delivery %v/%v/%v from db", i, n, self.at) - } - if ok && !db { - self.t.Fatalf("expected delivery %v/%v/%v from cache", i, n, self.at) - } - self.at++ - } -} - -func TestSyncDb(t *testing.T) { - t.Skip("fails randomly on all platforms") - - priority := High - bufferSize := 5 - batchSize := 2 * bufferSize - s := newTestSyncDb(priority, bufferSize, batchSize, "", t) - defer s.close() - defer s.stop() - s.dbRead(false, 0, s.deliver) - s.draindb() - - s.push(4) - s.expect(1, false) - // 3 in buffer - time.Sleep(100 * time.Millisecond) - s.push(3) - // push over limit - s.expect(1, false) - // one popped from the buffer, then contention detected - s.expect(4, true) - s.push(4) - s.expect(5, true) - // depleted db, switch back to buffer - s.draindb() - s.push(5) - s.expect(4, false) - s.push(3) - s.expect(4, false) - // buffer depleted - time.Sleep(100 * time.Millisecond) - s.push(6) - s.expect(1, false) - // push into buffer full, switch to db - s.expect(5, true) - s.draindb() - s.push(1) - s.expect(1, false) -} - -func TestSaveSyncDb(t *testing.T) { - amount := 30 - priority := High - bufferSize := amount - batchSize := 10 - s := newTestSyncDb(priority, bufferSize, batchSize, "", t) - go s.dbRead(false, 0, s.deliver) - s.push(amount) - s.stop() - s.db.Close() - - s = newTestSyncDb(priority, bufferSize, batchSize, s.dbdir, t) - go s.dbRead(false, 0, s.deliver) - s.expect(amount, true) - for i, key := range s.delivered { - expKey := crypto.Keccak256([]byte{byte(i)}) - if !bytes.Equal(key, expKey) { - t.Fatalf("delivery %v expected to be key %x, got %x", i, expKey, key) - } - } - s.push(amount) - s.expect(amount, false) - for i := amount; i < 2*amount; i++ { - key := s.delivered[i] - expKey := crypto.Keccak256([]byte{byte(i - amount)}) - if !bytes.Equal(key, expKey) { - t.Fatalf("delivery %v expected to be key %x, got %x", i, expKey, key) - } - } - s.stop() - s.db.Close() - - s = newTestSyncDb(priority, bufferSize, batchSize, s.dbdir, t) - defer s.close() - defer s.stop() - - go s.dbRead(false, 0, s.deliver) - s.push(1) - s.expect(1, false) - -} diff --git a/swarm/network/syncer.go b/swarm/network/syncer.go deleted file mode 100644 index 6d729fcb9e..0000000000 --- a/swarm/network/syncer.go +++ /dev/null @@ -1,781 +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 network - -import ( - "encoding/binary" - "encoding/json" - "fmt" - "path/filepath" - - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/swarm/storage" -) - -// syncer parameters (global, not peer specific) default values -const ( - requestDbBatchSize = 512 // size of batch before written to request db - keyBufferSize = 1024 // size of buffer for unsynced keys - syncBatchSize = 128 // maximum batchsize for outgoing requests - syncBufferSize = 128 // size of buffer for delivery requests - syncCacheSize = 1024 // cache capacity to store request queue in memory -) - -// priorities -const ( - Low = iota // 0 - Medium // 1 - High // 2 - priorities // 3 number of priority levels -) - -// request types -const ( - DeliverReq = iota // 0 - PushReq // 1 - PropagateReq // 2 - HistoryReq // 3 - BacklogReq // 4 -) - -// json serialisable struct to record the syncronisation state between 2 peers -type syncState struct { - *storage.DbSyncState // embeds the following 4 fields: - // Start Key // lower limit of address space - // Stop Key // upper limit of address space - // First uint64 // counter taken from last sync state - // Last uint64 // counter of remote peer dbStore at the time of last connection - SessionAt uint64 // set at the time of connection - LastSeenAt uint64 // set at the time of connection - Latest storage.Key // cursor of dbstore when last (continuously set by syncer) - Synced bool // true iff Sync is done up to the last disconnect - synced chan bool // signal that sync stage finished -} - -// wrapper of db-s to provide mockable custom local chunk store access to syncer -type DbAccess struct { - db *storage.DbStore - loc *storage.LocalStore -} - -func NewDbAccess(loc *storage.LocalStore) *DbAccess { - return &DbAccess{loc.DbStore.(*storage.DbStore), loc} -} - -// to obtain the chunks from key or request db entry only -func (self *DbAccess) get(key storage.Key) (*storage.Chunk, error) { - return self.loc.Get(key) -} - -// current storage counter of chunk db -func (self *DbAccess) counter() uint64 { - return self.db.Counter() -} - -// implemented by dbStoreSyncIterator -type keyIterator interface { - Next() storage.Key -} - -// generator function for iteration by address range and storage counter -func (self *DbAccess) iterator(s *syncState) keyIterator { - it, err := self.db.NewSyncIterator(*(s.DbSyncState)) - if err != nil { - return nil - } - return keyIterator(it) -} - -func (self syncState) String() string { - if self.Synced { - return fmt.Sprintf( - "session started at: %v, last seen at: %v, latest key: %v", - self.SessionAt, self.LastSeenAt, - self.Latest.Log(), - ) - } else { - return fmt.Sprintf( - "address: %v-%v, index: %v-%v, session started at: %v, last seen at: %v, latest key: %v", - self.Start.Log(), self.Stop.Log(), - self.First, self.Last, - self.SessionAt, self.LastSeenAt, - self.Latest.Log(), - ) - } -} - -// syncer parameters (global, not peer specific) -type SyncParams struct { - RequestDbPath string // path for request db (leveldb) - RequestDbBatchSize uint // nuber of items before batch is saved to requestdb - KeyBufferSize uint // size of key buffer - SyncBatchSize uint // maximum batchsize for outgoing requests - SyncBufferSize uint // size of buffer for - SyncCacheSize uint // cache capacity to store request queue in memory - SyncPriorities []uint // list of priority levels for req types 0-3 - SyncModes []bool // list of sync modes for for req types 0-3 -} - -// constructor with default values -func NewDefaultSyncParams() *SyncParams { - return &SyncParams{ - RequestDbBatchSize: requestDbBatchSize, - KeyBufferSize: keyBufferSize, - SyncBufferSize: syncBufferSize, - SyncBatchSize: syncBatchSize, - SyncCacheSize: syncCacheSize, - SyncPriorities: []uint{High, Medium, Medium, Low, Low}, - SyncModes: []bool{true, true, true, true, false}, - } -} - -//this can only finally be set after all config options (file, cmd line, env vars) -//have been evaluated -func (self *SyncParams) Init(path string) { - self.RequestDbPath = filepath.Join(path, "requests") -} - -// syncer is the agent that manages content distribution/storage replication/chunk storeRequest forwarding -type syncer struct { - *SyncParams // sync parameters - syncF func() bool // if syncing is needed - key storage.Key // remote peers address key - state *syncState // sync state for our dbStore - syncStates chan *syncState // different stages of sync - deliveryRequest chan bool // one of two triggers needed to send unsyncedKeys - newUnsyncedKeys chan bool // one of two triggers needed to send unsynced keys - quit chan bool // signal to quit loops - - // DB related fields - dbAccess *DbAccess // access to dbStore - - // native fields - queues [priorities]*syncDb // in-memory cache / queues for sync reqs - keys [priorities]chan interface{} // buffer for unsynced keys - deliveries [priorities]chan *storeRequestMsgData // delivery - - // bzz protocol instance outgoing message callbacks (mockable for testing) - unsyncedKeys func([]*syncRequest, *syncState) error // send unsyncedKeysMsg - store func(*storeRequestMsgData) error // send storeRequestMsg -} - -// a syncer instance is linked to each peer connection -// constructor is called from protocol after successful handshake -// the returned instance is attached to the peer and can be called -// by the forwarder -func newSyncer( - db *storage.LDBDatabase, remotekey storage.Key, - dbAccess *DbAccess, - unsyncedKeys func([]*syncRequest, *syncState) error, - store func(*storeRequestMsgData) error, - params *SyncParams, - state *syncState, - syncF func() bool, -) (*syncer, error) { - - syncBufferSize := params.SyncBufferSize - keyBufferSize := params.KeyBufferSize - dbBatchSize := params.RequestDbBatchSize - - self := &syncer{ - syncF: syncF, - key: remotekey, - dbAccess: dbAccess, - syncStates: make(chan *syncState, 20), - deliveryRequest: make(chan bool, 1), - newUnsyncedKeys: make(chan bool, 1), - SyncParams: params, - state: state, - quit: make(chan bool), - unsyncedKeys: unsyncedKeys, - store: store, - } - - // initialising - for i := 0; i < priorities; i++ { - self.keys[i] = make(chan interface{}, keyBufferSize) - self.deliveries[i] = make(chan *storeRequestMsgData) - // initialise a syncdb instance for each priority queue - self.queues[i] = newSyncDb(db, remotekey, uint(i), syncBufferSize, dbBatchSize, self.deliver(uint(i))) - } - log.Info(fmt.Sprintf("syncer started: %v", state)) - // launch chunk delivery service - go self.syncDeliveries() - // launch sync task manager - if self.syncF() { - go self.sync() - } - // process unsynced keys to broadcast - go self.syncUnsyncedKeys() - - return self, nil -} - -// metadata serialisation -func encodeSync(state *syncState) (*json.RawMessage, error) { - data, err := json.MarshalIndent(state, "", " ") - if err != nil { - return nil, err - } - meta := json.RawMessage(data) - return &meta, nil -} - -func decodeSync(meta *json.RawMessage) (*syncState, error) { - if meta == nil { - return nil, fmt.Errorf("unable to deserialise sync state from ") - } - data := []byte(*(meta)) - if len(data) == 0 { - return nil, fmt.Errorf("unable to deserialise sync state from ") - } - state := &syncState{DbSyncState: &storage.DbSyncState{}} - err := json.Unmarshal(data, state) - return state, err -} - -/* - sync implements the syncing script - * first all items left in the request Db are replayed - * type = StaleSync - * Mode: by default once again via confirmation roundtrip - * Priority: the items are replayed as the proirity specified for StaleSync - * but within the order respects earlier priority level of request - * after all items are consumed for a priority level, the the respective - queue for delivery requests is open (this way new reqs not written to db) - (TODO: this should be checked) - * the sync state provided by the remote peer is used to sync history - * all the backlog from earlier (aborted) syncing is completed starting from latest - * if Last < LastSeenAt then all items in between then process all - backlog from upto last disconnect - * if Last > 0 && - - sync is called from the syncer constructor and is not supposed to be used externally -*/ -func (self *syncer) sync() { - state := self.state - // sync finished - defer close(self.syncStates) - - // 0. first replay stale requests from request db - if state.SessionAt == 0 { - log.Debug(fmt.Sprintf("syncer[%v]: nothing to sync", self.key.Log())) - return - } - log.Debug(fmt.Sprintf("syncer[%v]: start replaying stale requests from request db", self.key.Log())) - for p := priorities - 1; p >= 0; p-- { - self.queues[p].dbRead(false, 0, self.replay()) - } - log.Debug(fmt.Sprintf("syncer[%v]: done replaying stale requests from request db", self.key.Log())) - - // unless peer is synced sync unfinished history beginning on - if !state.Synced { - start := state.Start - - if !storage.IsZeroKey(state.Latest) { - // 1. there is unfinished earlier sync - state.Start = state.Latest - log.Debug(fmt.Sprintf("syncer[%v]: start syncronising backlog (unfinished sync: %v)", self.key.Log(), state)) - // blocks while the entire history upto state is synced - self.syncState(state) - if state.Last < state.SessionAt { - state.First = state.Last + 1 - } - } - state.Latest = storage.ZeroKey - state.Start = start - // 2. sync up to last disconnect1 - if state.First < state.LastSeenAt { - state.Last = state.LastSeenAt - log.Debug(fmt.Sprintf("syncer[%v]: start syncronising history upto last disconnect at %v: %v", self.key.Log(), state.LastSeenAt, state)) - self.syncState(state) - state.First = state.LastSeenAt - } - state.Latest = storage.ZeroKey - - } else { - // synchronisation starts at end of last session - state.First = state.LastSeenAt - } - - // 3. sync up to current session start - // if there have been new chunks since last session - if state.LastSeenAt < state.SessionAt { - state.Last = state.SessionAt - log.Debug(fmt.Sprintf("syncer[%v]: start syncronising history since last disconnect at %v up until session start at %v: %v", self.key.Log(), state.LastSeenAt, state.SessionAt, state)) - // blocks until state syncing is finished - self.syncState(state) - } - log.Info(fmt.Sprintf("syncer[%v]: syncing all history complete", self.key.Log())) - -} - -// wait till syncronised block uptil state is synced -func (self *syncer) syncState(state *syncState) { - self.syncStates <- state - select { - case <-state.synced: - case <-self.quit: - } -} - -// stop quits both request processor and saves the request cache to disk -func (self *syncer) stop() { - close(self.quit) - log.Trace(fmt.Sprintf("syncer[%v]: stop and save sync request db backlog", self.key.Log())) - for _, db := range self.queues { - db.stop() - } -} - -// rlp serialisable sync request -type syncRequest struct { - Key storage.Key - Priority uint -} - -func (self *syncRequest) String() string { - return fmt.Sprintf("", self.Key.Log(), self.Priority) -} - -func (self *syncer) newSyncRequest(req interface{}, p int) (*syncRequest, error) { - key, _, _, _, err := parseRequest(req) - // TODO: if req has chunk, it should be put in a cache - // create - if err != nil { - return nil, err - } - return &syncRequest{key, uint(p)}, nil -} - -// serves historical items from the DB -// * read is on demand, blocking unless history channel is read -// * accepts sync requests (syncStates) to create new db iterator -// * closes the channel one iteration finishes -func (self *syncer) syncHistory(state *syncState) chan interface{} { - var n uint - history := make(chan interface{}) - log.Debug(fmt.Sprintf("syncer[%v]: syncing history between %v - %v for chunk addresses %v - %v", self.key.Log(), state.First, state.Last, state.Start, state.Stop)) - it := self.dbAccess.iterator(state) - if it != nil { - go func() { - // signal end of the iteration ended - defer close(history) - IT: - for { - key := it.Next() - if key == nil { - break IT - } - select { - // blocking until history channel is read from - case history <- key: - n++ - log.Trace(fmt.Sprintf("syncer[%v]: history: %v (%v keys)", self.key.Log(), key.Log(), n)) - state.Latest = key - case <-self.quit: - return - } - } - log.Debug(fmt.Sprintf("syncer[%v]: finished syncing history between %v - %v for chunk addresses %v - %v (at %v) (chunks = %v)", self.key.Log(), state.First, state.Last, state.Start, state.Stop, state.Latest, n)) - }() - } - return history -} - -// triggers key syncronisation -func (self *syncer) sendUnsyncedKeys() { - select { - case self.deliveryRequest <- true: - default: - } -} - -// assembles a new batch of unsynced keys -// * keys are drawn from the key buffers in order of priority queue -// * if the queues of priority for History (HistoryReq) or higher are depleted, -// historical data is used so historical items are lower priority within -// their priority group. -// * Order of historical data is unspecified -func (self *syncer) syncUnsyncedKeys() { - // send out new - var unsynced []*syncRequest - var more, justSynced bool - var keyCount, historyCnt int - var history chan interface{} - - priority := High - keys := self.keys[priority] - var newUnsyncedKeys, deliveryRequest chan bool - keyCounts := make([]int, priorities) - histPrior := self.SyncPriorities[HistoryReq] - syncStates := self.syncStates - state := self.state - -LOOP: - for { - - var req interface{} - // select the highest priority channel to read from - // keys channels are buffered so the highest priority ones - // are checked first - integrity can only be guaranteed if writing - // is locked while selecting - if priority != High || len(keys) == 0 { - // selection is not needed if the High priority queue has items - keys = nil - PRIORITIES: - for priority = High; priority >= 0; priority-- { - // the first priority channel that is non-empty will be assigned to keys - if len(self.keys[priority]) > 0 { - log.Trace(fmt.Sprintf("syncer[%v]: reading request with priority %v", self.key.Log(), priority)) - keys = self.keys[priority] - break PRIORITIES - } - log.Trace(fmt.Sprintf("syncer[%v/%v]: queue: [%v, %v, %v]", self.key.Log(), priority, len(self.keys[High]), len(self.keys[Medium]), len(self.keys[Low]))) - // if the input queue is empty on this level, resort to history if there is any - if uint(priority) == histPrior && history != nil { - log.Trace(fmt.Sprintf("syncer[%v]: reading history for %v", self.key.Log(), self.key)) - keys = history - break PRIORITIES - } - } - } - - // if peer ready to receive but nothing to send - if keys == nil && deliveryRequest == nil { - // if no items left and switch to waiting mode - log.Trace(fmt.Sprintf("syncer[%v]: buffers consumed. Waiting", self.key.Log())) - newUnsyncedKeys = self.newUnsyncedKeys - } - - // send msg iff - // * peer is ready to receive keys AND ( - // * all queues and history are depleted OR - // * batch full OR - // * all history have been consumed, synced) - if deliveryRequest == nil && - (justSynced || - len(unsynced) > 0 && keys == nil || - len(unsynced) == int(self.SyncBatchSize)) { - justSynced = false - // listen to requests - deliveryRequest = self.deliveryRequest - newUnsyncedKeys = nil // not care about data until next req comes in - // set sync to current counter - // (all nonhistorical outgoing traffic sheduled and persisted - state.LastSeenAt = self.dbAccess.counter() - state.Latest = storage.ZeroKey - log.Trace(fmt.Sprintf("syncer[%v]: sending %v", self.key.Log(), unsynced)) - // send the unsynced keys - stateCopy := *state - err := self.unsyncedKeys(unsynced, &stateCopy) - if err != nil { - log.Warn(fmt.Sprintf("syncer[%v]: unable to send unsynced keys: %v", self.key.Log(), err)) - } - self.state = state - log.Debug(fmt.Sprintf("syncer[%v]: --> %v keys sent: (total: %v (%v), history: %v), sent sync state: %v", self.key.Log(), len(unsynced), keyCounts, keyCount, historyCnt, stateCopy)) - unsynced = nil - keys = nil - } - - // process item and add it to the batch - select { - case <-self.quit: - break LOOP - case req, more = <-keys: - if keys == history && !more { - log.Trace(fmt.Sprintf("syncer[%v]: syncing history segment complete", self.key.Log())) - // history channel is closed, waiting for new state (called from sync()) - syncStates = self.syncStates - state.Synced = true // this signals that the current segment is complete - select { - case state.synced <- false: - case <-self.quit: - break LOOP - } - justSynced = true - history = nil - } - case <-deliveryRequest: - log.Trace(fmt.Sprintf("syncer[%v]: peer ready to receive", self.key.Log())) - - // this 1 cap channel can wake up the loop - // signaling that peer is ready to receive unsynced Keys - // the channel is set to nil any further writes will be ignored - deliveryRequest = nil - - case <-newUnsyncedKeys: - log.Trace(fmt.Sprintf("syncer[%v]: new unsynced keys available", self.key.Log())) - // this 1 cap channel can wake up the loop - // signals that data is available to send if peer is ready to receive - newUnsyncedKeys = nil - keys = self.keys[High] - - case state, more = <-syncStates: - // this resets the state - if !more { - state = self.state - log.Trace(fmt.Sprintf("syncer[%v]: (priority %v) syncing complete upto %v)", self.key.Log(), priority, state)) - state.Synced = true - syncStates = nil - } else { - log.Trace(fmt.Sprintf("syncer[%v]: (priority %v) syncing history upto %v priority %v)", self.key.Log(), priority, state, histPrior)) - state.Synced = false - history = self.syncHistory(state) - // only one history at a time, only allow another one once the - // history channel is closed - syncStates = nil - } - } - if req == nil { - continue LOOP - } - - log.Trace(fmt.Sprintf("syncer[%v]: (priority %v) added to unsynced keys: %v", self.key.Log(), priority, req)) - keyCounts[priority]++ - keyCount++ - if keys == history { - log.Trace(fmt.Sprintf("syncer[%v]: (priority %v) history item %v (synced = %v)", self.key.Log(), priority, req, state.Synced)) - historyCnt++ - } - if sreq, err := self.newSyncRequest(req, priority); err == nil { - // extract key from req - log.Trace(fmt.Sprintf("syncer[%v]: (priority %v): request %v (synced = %v)", self.key.Log(), priority, req, state.Synced)) - unsynced = append(unsynced, sreq) - } else { - log.Warn(fmt.Sprintf("syncer[%v]: (priority %v): error creating request for %v: %v)", self.key.Log(), priority, req, err)) - } - - } -} - -// delivery loop -// takes into account priority, send store Requests with chunk (delivery) -// idle blocking if no new deliveries in any of the queues -func (self *syncer) syncDeliveries() { - var req *storeRequestMsgData - p := High - var deliveries chan *storeRequestMsgData - var msg *storeRequestMsgData - var err error - var c = [priorities]int{} - var n = [priorities]int{} - var total, success uint - - for { - deliveries = self.deliveries[p] - select { - case req = <-deliveries: - n[p]++ - c[p]++ - default: - if p == Low { - // blocking, depletion on all channels, no preference for priority - select { - case req = <-self.deliveries[High]: - n[High]++ - case req = <-self.deliveries[Medium]: - n[Medium]++ - case req = <-self.deliveries[Low]: - n[Low]++ - case <-self.quit: - return - } - p = High - } else { - p-- - continue - } - } - total++ - msg, err = self.newStoreRequestMsgData(req) - if err != nil { - log.Warn(fmt.Sprintf("syncer[%v]: failed to create store request for %v: %v", self.key.Log(), req, err)) - } else { - err = self.store(msg) - if err != nil { - log.Warn(fmt.Sprintf("syncer[%v]: failed to deliver %v: %v", self.key.Log(), req, err)) - } else { - success++ - log.Trace(fmt.Sprintf("syncer[%v]: %v successfully delivered", self.key.Log(), req)) - } - } - if total%self.SyncBatchSize == 0 { - log.Debug(fmt.Sprintf("syncer[%v]: deliver Total: %v, Success: %v, High: %v/%v, Medium: %v/%v, Low %v/%v", self.key.Log(), total, success, c[High], n[High], c[Medium], n[Medium], c[Low], n[Low])) - } - } -} - -/* - addRequest handles requests for delivery - it accepts 4 types: - - * storeRequestMsgData: coming from netstore propagate response - * chunk: coming from forwarding (questionable: id?) - * key: from incoming syncRequest - * syncDbEntry: key,id encoded in db - - If sync mode is on for the type of request, then - it sends the request to the keys queue of the correct priority - channel buffered with capacity (SyncBufferSize) - - If sync mode is off then, requests are directly sent to deliveries -*/ -func (self *syncer) addRequest(req interface{}, ty int) { - // retrieve priority for request type name int8 - - priority := self.SyncPriorities[ty] - // sync mode for this type ON - if self.syncF() || ty == DeliverReq { - if self.SyncModes[ty] { - self.addKey(req, priority, self.quit) - } else { - self.addDelivery(req, priority, self.quit) - } - } -} - -// addKey queues sync request for sync confirmation with given priority -// ie the key will go out in an unsyncedKeys message -func (self *syncer) addKey(req interface{}, priority uint, quit chan bool) bool { - select { - case self.keys[priority] <- req: - // this wakes up the unsynced keys loop if idle - select { - case self.newUnsyncedKeys <- true: - default: - } - return true - case <-quit: - return false - } -} - -// addDelivery queues delivery request for with given priority -// ie the chunk will be delivered ASAP mod priority queueing handled by syncdb -// requests are persisted across sessions for correct sync -func (self *syncer) addDelivery(req interface{}, priority uint, quit chan bool) bool { - select { - case self.queues[priority].buffer <- req: - return true - case <-quit: - return false - } -} - -// doDelivery delivers the chunk for the request with given priority -// without queuing -func (self *syncer) doDelivery(req interface{}, priority uint, quit chan bool) bool { - msgdata, err := self.newStoreRequestMsgData(req) - if err != nil { - log.Warn(fmt.Sprintf("unable to deliver request %v: %v", msgdata, err)) - return false - } - select { - case self.deliveries[priority] <- msgdata: - return true - case <-quit: - return false - } -} - -// returns the delivery function for given priority -// passed on to syncDb -func (self *syncer) deliver(priority uint) func(req interface{}, quit chan bool) bool { - return func(req interface{}, quit chan bool) bool { - return self.doDelivery(req, priority, quit) - } -} - -// returns the replay function passed on to syncDb -// depending on sync mode settings for BacklogReq, -// re play of request db backlog sends items via confirmation -// or directly delivers -func (self *syncer) replay() func(req interface{}, quit chan bool) bool { - sync := self.SyncModes[BacklogReq] - priority := self.SyncPriorities[BacklogReq] - // sync mode for this type ON - if sync { - return func(req interface{}, quit chan bool) bool { - return self.addKey(req, priority, quit) - } - } else { - return func(req interface{}, quit chan bool) bool { - return self.doDelivery(req, priority, quit) - } - - } -} - -// given a request, extends it to a full storeRequestMsgData -// polimorphic: see addRequest for the types accepted -func (self *syncer) newStoreRequestMsgData(req interface{}) (*storeRequestMsgData, error) { - - key, id, chunk, sreq, err := parseRequest(req) - if err != nil { - return nil, err - } - - if sreq == nil { - if chunk == nil { - var err error - chunk, err = self.dbAccess.get(key) - if err != nil { - return nil, err - } - } - - sreq = &storeRequestMsgData{ - Id: id, - Key: chunk.Key, - SData: chunk.SData, - } - } - - return sreq, nil -} - -// parse request types and extracts, key, id, chunk, request if available -// does not do chunk lookup ! -func parseRequest(req interface{}) (storage.Key, uint64, *storage.Chunk, *storeRequestMsgData, error) { - var key storage.Key - var entry *syncDbEntry - var chunk *storage.Chunk - var id uint64 - var ok bool - var sreq *storeRequestMsgData - var err error - - if key, ok = req.(storage.Key); ok { - id = generateId() - - } else if entry, ok = req.(*syncDbEntry); ok { - id = binary.BigEndian.Uint64(entry.val[32:]) - key = storage.Key(entry.val[:32]) - - } else if chunk, ok = req.(*storage.Chunk); ok { - key = chunk.Key - id = generateId() - - } else if sreq, ok = req.(*storeRequestMsgData); ok { - key = sreq.Key - } else { - err = fmt.Errorf("type not allowed: %v (%T)", req, req) - } - - return key, id, chunk, sreq, err -} diff --git a/swarm/network_test.go b/swarm/network_test.go new file mode 100644 index 0000000000..d2a0309338 --- /dev/null +++ b/swarm/network_test.go @@ -0,0 +1,530 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package swarm + +import ( + "context" + "flag" + "fmt" + "io/ioutil" + "math/rand" + "os" + "sync" + "sync/atomic" + "testing" + "time" + + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/node" + "github.com/ethereum/go-ethereum/p2p/discover" + "github.com/ethereum/go-ethereum/p2p/simulations/adapters" + "github.com/ethereum/go-ethereum/swarm/api" + "github.com/ethereum/go-ethereum/swarm/network" + "github.com/ethereum/go-ethereum/swarm/network/simulation" + "github.com/ethereum/go-ethereum/swarm/storage" + colorable "github.com/mattn/go-colorable" +) + +var ( + loglevel = flag.Int("loglevel", 2, "verbosity of logs") + longrunning = flag.Bool("longrunning", false, "do run long-running tests") + waitKademlia = flag.Bool("waitkademlia", false, "wait for healthy kademlia before checking files availability") +) + +func init() { + rand.Seed(time.Now().UnixNano()) + + flag.Parse() + + log.Root().SetHandler(log.LvlFilterHandler(log.Lvl(*loglevel), log.StreamHandler(colorable.NewColorableStderr(), log.TerminalFormat(true)))) +} + +// TestSwarmNetwork runs a series of test simulations with +// static and dynamic Swarm nodes in network simulation, by +// uploading files to every node and retrieving them. +func TestSwarmNetwork(t *testing.T) { + for _, tc := range []struct { + name string + steps []testSwarmNetworkStep + options *testSwarmNetworkOptions + disabled bool + }{ + { + name: "10_nodes", + steps: []testSwarmNetworkStep{ + { + nodeCount: 10, + }, + }, + options: &testSwarmNetworkOptions{ + Timeout: 45 * time.Second, + }, + }, + { + name: "10_nodes_skip_check", + steps: []testSwarmNetworkStep{ + { + nodeCount: 10, + }, + }, + options: &testSwarmNetworkOptions{ + Timeout: 45 * time.Second, + SkipCheck: true, + }, + }, + { + name: "100_nodes", + steps: []testSwarmNetworkStep{ + { + nodeCount: 100, + }, + }, + options: &testSwarmNetworkOptions{ + Timeout: 3 * time.Minute, + }, + disabled: !*longrunning, + }, + { + name: "100_nodes_skip_check", + steps: []testSwarmNetworkStep{ + { + nodeCount: 100, + }, + }, + options: &testSwarmNetworkOptions{ + Timeout: 3 * time.Minute, + SkipCheck: true, + }, + disabled: !*longrunning, + }, + { + name: "inc_node_count", + steps: []testSwarmNetworkStep{ + { + nodeCount: 2, + }, + { + nodeCount: 5, + }, + { + nodeCount: 10, + }, + }, + options: &testSwarmNetworkOptions{ + Timeout: 90 * time.Second, + }, + disabled: !*longrunning, + }, + { + name: "dec_node_count", + steps: []testSwarmNetworkStep{ + { + nodeCount: 10, + }, + { + nodeCount: 6, + }, + { + nodeCount: 3, + }, + }, + options: &testSwarmNetworkOptions{ + Timeout: 90 * time.Second, + }, + disabled: !*longrunning, + }, + { + name: "dec_inc_node_count", + steps: []testSwarmNetworkStep{ + { + nodeCount: 5, + }, + { + nodeCount: 3, + }, + { + nodeCount: 10, + }, + }, + options: &testSwarmNetworkOptions{ + Timeout: 90 * time.Second, + }, + }, + { + name: "inc_dec_node_count", + steps: []testSwarmNetworkStep{ + { + nodeCount: 3, + }, + { + nodeCount: 5, + }, + { + nodeCount: 25, + }, + { + nodeCount: 10, + }, + { + nodeCount: 4, + }, + }, + options: &testSwarmNetworkOptions{ + Timeout: 5 * time.Minute, + }, + disabled: !*longrunning, + }, + { + name: "inc_dec_node_count_skip_check", + steps: []testSwarmNetworkStep{ + { + nodeCount: 3, + }, + { + nodeCount: 5, + }, + { + nodeCount: 25, + }, + { + nodeCount: 10, + }, + { + nodeCount: 4, + }, + }, + options: &testSwarmNetworkOptions{ + Timeout: 5 * time.Minute, + SkipCheck: true, + }, + disabled: !*longrunning, + }, + } { + if tc.disabled { + continue + } + t.Run(tc.name, func(t *testing.T) { + testSwarmNetwork(t, tc.options, tc.steps...) + }) + } +} + +// testSwarmNetworkStep is the configuration +// for the state of the simulation network. +type testSwarmNetworkStep struct { + // number of swarm nodes that must be in the Up state + nodeCount int +} + +// file represents the file uploaded on a particular node. +type file struct { + addr storage.Address + data string + nodeID discover.NodeID +} + +// check represents a reference to a file that is retrieved +// from a particular node. +type check struct { + key string + nodeID discover.NodeID +} + +// testSwarmNetworkOptions contains optional parameters for running +// testSwarmNetwork. +type testSwarmNetworkOptions struct { + Timeout time.Duration + SkipCheck bool +} + +// testSwarmNetwork is a helper function used for testing different +// static and dynamic Swarm network simulations. +// It is responsible for: +// - Setting up a Swarm network simulation, and updates the number of nodes within the network on every step according to steps. +// - Uploading a unique file to every node on every step. +// - May wait for Kademlia on every node to be healthy. +// - Checking if a file is retrievable from all nodes. +func testSwarmNetwork(t *testing.T, o *testSwarmNetworkOptions, steps ...testSwarmNetworkStep) { + if o == nil { + o = new(testSwarmNetworkOptions) + } + + sim := simulation.New(map[string]simulation.ServiceFunc{ + "swarm": func(ctx *adapters.ServiceContext, bucket *sync.Map) (s node.Service, cleanup func(), err error) { + config := api.NewConfig() + + dir, err := ioutil.TempDir("", "swarm-network-test-node") + if err != nil { + return nil, nil, err + } + cleanup = func() { + err := os.RemoveAll(dir) + if err != nil { + log.Error("cleaning up swarm temp dir", "err", err) + } + } + + config.Path = dir + + privkey, err := crypto.GenerateKey() + if err != nil { + return nil, cleanup, err + } + + config.Init(privkey) + config.DeliverySkipCheck = o.SkipCheck + + swarm, err := NewSwarm(config, nil) + if err != nil { + return nil, cleanup, err + } + bucket.Store(simulation.BucketKeyKademlia, swarm.bzz.Hive.Overlay.(*network.Kademlia)) + log.Info("new swarm", "bzzKey", config.BzzKey, "baseAddr", fmt.Sprintf("%x", swarm.bzz.BaseAddr())) + return swarm, cleanup, nil + }, + }) + defer sim.Close() + + ctx := context.Background() + if o.Timeout > 0 { + var cancel context.CancelFunc + ctx, cancel = context.WithTimeout(ctx, o.Timeout) + defer cancel() + } + + files := make([]file, 0) + + for i, step := range steps { + log.Debug("test sync step", "n", i+1, "nodes", step.nodeCount) + + change := step.nodeCount - len(sim.UpNodeIDs()) + + if change > 0 { + _, err := sim.AddNodesAndConnectChain(change) + if err != nil { + t.Fatal(err) + } + } else if change < 0 { + _, err := sim.StopRandomNodes(-change) + if err != nil { + t.Fatal(err) + } + } else { + t.Logf("step %v: no change in nodes", i) + continue + } + + var checkStatusM sync.Map + var nodeStatusM sync.Map + var totalFoundCount uint64 + + result := sim.Run(ctx, func(ctx context.Context, sim *simulation.Simulation) error { + nodeIDs := sim.UpNodeIDs() + shuffle(len(nodeIDs), func(i, j int) { + nodeIDs[i], nodeIDs[j] = nodeIDs[j], nodeIDs[i] + }) + for _, id := range nodeIDs { + key, data, err := uploadFile(sim.Service("swarm", id).(*Swarm)) + if err != nil { + return err + } + log.Trace("file uploaded", "node", id, "key", key.String()) + files = append(files, file{ + addr: key, + data: data, + nodeID: id, + }) + } + + if *waitKademlia { + if _, err := sim.WaitTillHealthy(ctx, 2); err != nil { + return err + } + } + + // File retrieval check is repeated until all uploaded files are retrieved from all nodes + // or until the timeout is reached. + for { + if retrieve(sim, files, &checkStatusM, &nodeStatusM, &totalFoundCount) == 0 { + return nil + } + } + }) + + if result.Error != nil { + t.Fatal(result.Error) + } + log.Debug("done: test sync step", "n", i+1, "nodes", step.nodeCount) + } +} + +// uploadFile, uploads a short file to the swarm instance +// using the api.Put method. +func uploadFile(swarm *Swarm) (storage.Address, string, error) { + b := make([]byte, 8) + _, err := rand.Read(b) + if err != nil { + return nil, "", err + } + // File data is very short, but it is ensured that its + // uniqueness is very certain. + data := fmt.Sprintf("test content %s %x", time.Now().Round(0), b) + ctx := context.TODO() + k, wait, err := swarm.api.Put(ctx, data, "text/plain", false) + if err != nil { + return nil, "", err + } + if wait != nil { + err = wait(ctx) + } + return k, data, err +} + +// retrieve is the function that is used for checking the availability of +// uploaded files in testSwarmNetwork test helper function. +func retrieve( + sim *simulation.Simulation, + files []file, + checkStatusM *sync.Map, + nodeStatusM *sync.Map, + totalFoundCount *uint64, +) (missing uint64) { + shuffle(len(files), func(i, j int) { + files[i], files[j] = files[j], files[i] + }) + + var totalWg sync.WaitGroup + errc := make(chan error) + + nodeIDs := sim.UpNodeIDs() + + totalCheckCount := len(nodeIDs) * len(files) + + for _, id := range nodeIDs { + if _, ok := nodeStatusM.Load(id); ok { + continue + } + start := time.Now() + var checkCount uint64 + var foundCount uint64 + + totalWg.Add(1) + + var wg sync.WaitGroup + + swarm := sim.Service("swarm", id).(*Swarm) + for _, f := range files { + + checkKey := check{ + key: f.addr.String(), + nodeID: id, + } + if n, ok := checkStatusM.Load(checkKey); ok && n.(int) == 0 { + continue + } + + checkCount++ + wg.Add(1) + go func(f file, id discover.NodeID) { + defer wg.Done() + + log.Debug("api get: check file", "node", id.String(), "key", f.addr.String(), "total files found", atomic.LoadUint64(totalFoundCount)) + + r, _, _, _, err := swarm.api.Get(context.TODO(), f.addr, "/") + if err != nil { + errc <- fmt.Errorf("api get: node %s, key %s, kademlia %s: %v", id, f.addr, swarm.bzz.Hive, err) + return + } + d, err := ioutil.ReadAll(r) + if err != nil { + errc <- fmt.Errorf("api get: read response: node %s, key %s: kademlia %s: %v", id, f.addr, swarm.bzz.Hive, err) + return + } + data := string(d) + if data != f.data { + errc <- fmt.Errorf("file contend missmatch: node %s, key %s, expected %q, got %q", id, f.addr, f.data, data) + return + } + checkStatusM.Store(checkKey, 0) + atomic.AddUint64(&foundCount, 1) + log.Info("api get: file found", "node", id.String(), "key", f.addr.String(), "content", data, "files found", atomic.LoadUint64(&foundCount)) + }(f, id) + } + + go func(id discover.NodeID) { + defer totalWg.Done() + wg.Wait() + + atomic.AddUint64(totalFoundCount, foundCount) + + if foundCount == checkCount { + log.Info("all files are found for node", "id", id.String(), "duration", time.Since(start)) + nodeStatusM.Store(id, 0) + return + } + log.Debug("files missing for node", "id", id.String(), "check", checkCount, "found", foundCount) + }(id) + + } + + go func() { + totalWg.Wait() + close(errc) + }() + + var errCount int + for err := range errc { + if err != nil { + errCount++ + } + log.Warn(err.Error()) + } + + log.Info("check stats", "total check count", totalCheckCount, "total files found", atomic.LoadUint64(totalFoundCount), "total errors", errCount) + + return uint64(totalCheckCount) - atomic.LoadUint64(totalFoundCount) +} + +// Backported from stdlib https://golang.org/src/math/rand/rand.go?s=11175:11215#L333 +// +// Replace with rand.Shuffle from go 1.10 when go 1.9 support is dropped. +// +// shuffle pseudo-randomizes the order of elements. +// n is the number of elements. Shuffle panics if n < 0. +// swap swaps the elements with indexes i and j. +func shuffle(n int, swap func(i, j int)) { + if n < 0 { + panic("invalid argument to Shuffle") + } + + // Fisher-Yates shuffle: https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle + // Shuffle really ought not be called with n that doesn't fit in 32 bits. + // Not only will it take a very long time, but with 2³¹! possible permutations, + // there's no way that any PRNG can have a big enough internal state to + // generate even a minuscule percentage of the possible permutations. + // Nevertheless, the right API signature accepts an int n, so handle it as best we can. + i := n - 1 + for ; i > 1<<31-1-1; i-- { + j := int(rand.Int63n(int64(i + 1))) + swap(i, j) + } + for ; i > 0; i-- { + j := int(rand.Int31n(int32(i + 1))) + swap(i, j) + } +} diff --git a/swarm/pot/address.go b/swarm/pot/address.go new file mode 100644 index 0000000000..3974ebcaac --- /dev/null +++ b/swarm/pot/address.go @@ -0,0 +1,252 @@ +// 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 pot see doc.go +package pot + +import ( + "encoding/binary" + "fmt" + "math/rand" + "strconv" + "strings" + + "github.com/ethereum/go-ethereum/common" +) + +var ( + zerosBin = Address{}.Bin() +) + +// Address is an alias for common.Hash +type Address common.Hash + +// NewAddressFromBytes constructs an Address from a byte slice +func NewAddressFromBytes(b []byte) Address { + h := common.Hash{} + copy(h[:], b) + return Address(h) +} + +func (a Address) IsZero() bool { + return a.Bin() == zerosBin +} + +func (a Address) String() string { + return fmt.Sprintf("%x", a[:]) +} + +// MarshalJSON Address serialisation +func (a *Address) MarshalJSON() (out []byte, err error) { + return []byte(`"` + a.String() + `"`), nil +} + +// UnmarshalJSON Address deserialisation +func (a *Address) UnmarshalJSON(value []byte) error { + *a = Address(common.HexToHash(string(value[1 : len(value)-1]))) + return nil +} + +// Bin returns the string form of the binary representation of an address (only first 8 bits) +func (a Address) Bin() string { + return ToBin(a[:]) +} + +// ToBin converts a byteslice to the string binary representation +func ToBin(a []byte) string { + var bs []string + for _, b := range a { + bs = append(bs, fmt.Sprintf("%08b", b)) + } + return strings.Join(bs, "") +} + +// Bytes returns the Address as a byte slice +func (a Address) Bytes() []byte { + return a[:] +} + +/* +Proximity(x, y) returns the proximity order of the MSB distance between x and y + +The distance metric MSB(x, y) of two equal length byte sequences x an y is the +value of the binary integer cast of the x^y, ie., x and y bitwise xor-ed. +the binary cast is big endian: most significant bit first (=MSB). + +Proximity(x, y) is a discrete logarithmic scaling of the MSB distance. +It is defined as the reverse rank of the integer part of the base 2 +logarithm of the distance. +It is calculated by counting the number of common leading zeros in the (MSB) +binary representation of the x^y. + +(0 farthest, 255 closest, 256 self) +*/ +func proximity(one, other Address) (ret int, eq bool) { + return posProximity(one, other, 0) +} + +// posProximity(a, b, pos) returns proximity order of b wrt a (symmetric) pretending +// the first pos bits match, checking only bits index >= pos +func posProximity(one, other Address, pos int) (ret int, eq bool) { + for i := pos / 8; i < len(one); i++ { + if one[i] == other[i] { + continue + } + oxo := one[i] ^ other[i] + start := 0 + if i == pos/8 { + start = pos % 8 + } + for j := start; j < 8; j++ { + if (oxo>>uint8(7-j))&0x01 != 0 { + return i*8 + j, false + } + } + } + return len(one) * 8, true +} + +// ProxCmp compares the distances a->target and b->target. +// Returns -1 if a is closer to target, 1 if b is closer to target +// and 0 if they are equal. +func ProxCmp(a, x, y interface{}) int { + return proxCmp(ToBytes(a), ToBytes(x), ToBytes(y)) +} + +func proxCmp(a, x, y []byte) int { + for i := range a { + dx := x[i] ^ a[i] + dy := y[i] ^ a[i] + if dx > dy { + return 1 + } else if dx < dy { + return -1 + } + } + return 0 +} + +// RandomAddressAt (address, prox) generates a random address +// at proximity order prox relative to address +// if prox is negative a random address is generated +func RandomAddressAt(self Address, prox int) (addr Address) { + addr = self + pos := -1 + if prox >= 0 { + pos = prox / 8 + trans := prox % 8 + transbytea := byte(0) + for j := 0; j <= trans; j++ { + transbytea |= 1 << uint8(7-j) + } + flipbyte := byte(1 << uint8(7-trans)) + transbyteb := transbytea ^ byte(255) + randbyte := byte(rand.Intn(255)) + addr[pos] = ((addr[pos] & transbytea) ^ flipbyte) | randbyte&transbyteb + } + for i := pos + 1; i < len(addr); i++ { + addr[i] = byte(rand.Intn(255)) + } + + return +} + +// RandomAddress generates a random address +func RandomAddress() Address { + return RandomAddressAt(Address{}, -1) +} + +// NewAddressFromString creates a byte slice from a string in binary representation +func NewAddressFromString(s string) []byte { + ha := [32]byte{} + + t := s + zerosBin[:len(zerosBin)-len(s)] + for i := 0; i < 4; i++ { + n, err := strconv.ParseUint(t[i*64:(i+1)*64], 2, 64) + if err != nil { + panic("wrong format: " + err.Error()) + } + binary.BigEndian.PutUint64(ha[i*8:(i+1)*8], n) + } + return ha[:] +} + +// BytesAddress is an interface for elements addressable by a byte slice +type BytesAddress interface { + Address() []byte +} + +// ToBytes turns the Val into bytes +func ToBytes(v Val) []byte { + if v == nil { + return nil + } + b, ok := v.([]byte) + if !ok { + ba, ok := v.(BytesAddress) + if !ok { + panic(fmt.Sprintf("unsupported value type %T", v)) + } + b = ba.Address() + } + return b +} + +// DefaultPof returns a proximity order comparison operator function +// where all +func DefaultPof(max int) func(one, other Val, pos int) (int, bool) { + return func(one, other Val, pos int) (int, bool) { + po, eq := proximityOrder(ToBytes(one), ToBytes(other), pos) + if po >= max { + eq = true + po = max + } + return po, eq + } +} + +func proximityOrder(one, other []byte, pos int) (int, bool) { + for i := pos / 8; i < len(one); i++ { + if one[i] == other[i] { + continue + } + oxo := one[i] ^ other[i] + start := 0 + if i == pos/8 { + start = pos % 8 + } + for j := start; j < 8; j++ { + if (oxo>>uint8(7-j))&0x01 != 0 { + return i*8 + j, false + } + } + } + return len(one) * 8, true +} + +// Label displays the node's key in binary format +func Label(v Val) string { + if v == nil { + return "" + } + if s, ok := v.(fmt.Stringer); ok { + return s.String() + } + if b, ok := v.([]byte); ok { + return ToBin(b) + } + panic(fmt.Sprintf("unsupported value type %T", v)) +} diff --git a/swarm/pot/doc.go b/swarm/pot/doc.go new file mode 100644 index 0000000000..4c0a03065d --- /dev/null +++ b/swarm/pot/doc.go @@ -0,0 +1,83 @@ +// 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 pot (proximity order tree) implements a container similar to a binary tree. +The elements are generic Val interface types. + +Each fork in the trie is itself a value. Values of the subtree contained under +a node all share the same order when compared to other elements in the tree. + +Example of proximity order is the length of the common prefix over bitvectors. +(which is equivalent to the reverse rank of order of magnitude of the MSB first X +OR distance over finite set of integers). + +Methods take a comparison operator (pof, proximity order function) to compare two +value types. The default pof assumes Val to be or project to a byte slice using +the reverse rank on the MSB first XOR logarithmic disctance. + +If the address space if limited, equality is defined as the maximum proximity order. + +The container offers applicative (funcional) style methods on PO trees: +* adding/removing en element +* swap (value based add/remove) +* merging two PO trees (union) + +as well as iterator accessors that respect proximity order + +When synchronicity of membership if not 100% requirement (e.g. used as a database +of network connections), applicative structures have the advantage that nodes +are immutable therefore manipulation does not need locking allowing for +concurrent retrievals. +For the use case where the entire container is supposed to allow changes by +concurrent routines, + +Pot +* retrieval, insertion and deletion by key involves log(n) pointer lookups +* for any item retrieval (defined as common prefix on the binary key) +* provide synchronous iterators respecting proximity ordering wrt any item +* provide asynchronous iterator (for parallel execution of operations) over n items +* allows cheap iteration over ranges +* asymmetric concurrent merge (union) + +Note: +* as is, union only makes sense for set representations since which of two values +with equal keys survives is random +* intersection is not implemented +* simple get accessor is not implemented (but derivable from EachNeighbour) + +Pinned value on the node implies no need to copy keys of the item type. + +Note that +* the same set of values allows for a large number of alternative +POT representations. +* values on the top are accessed faster than lower ones and the steps needed to +retrieve items has a logarithmic distribution. + +As a consequence one can organise the tree so that items that need faster access +are torwards the top. In particular for any subset where popularity has a power +distriution that is independent of proximity order (content addressed storage of +chunks), it is in principle possible to create a pot where the steps needed to +access an item is inversely proportional to its popularity. +Such organisation is not implemented as yet. + +TODO: +* overwrite-style merge +* intersection +* access frequency based optimisations + +*/ +package pot diff --git a/swarm/pot/pot.go b/swarm/pot/pot.go new file mode 100644 index 0000000000..dfda84804d --- /dev/null +++ b/swarm/pot/pot.go @@ -0,0 +1,807 @@ +// 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 pot see doc.go +package pot + +import ( + "fmt" + "sync" +) + +const ( + maxkeylen = 256 +) + +// Pot is the node type (same for root, branching node and leaf) +type Pot struct { + pin Val + bins []*Pot + size int + po int +} + +// Val is the element type for Pots +type Val interface{} + +// Pof is the proximity order comparison operator function +type Pof func(Val, Val, int) (int, bool) + +// NewPot constructor. Requires a value of type Val to pin +// and po to point to a span in the Val key +// The pinned item counts towards the size +func NewPot(v Val, po int) *Pot { + var size int + if v != nil { + size++ + } + return &Pot{ + pin: v, + po: po, + size: size, + } +} + +// Pin returns the pinned element (key) of the Pot +func (t *Pot) Pin() Val { + return t.pin +} + +// Size returns the number of values in the Pot +func (t *Pot) Size() int { + if t == nil { + return 0 + } + return t.size +} + +// Add inserts a new value into the Pot and +// returns the proximity order of v and a boolean +// indicating if the item was found +// Add called on (t, v) returns a new Pot that contains all the elements of t +// plus the value v, using the applicative add +// the second return value is the proximity order of the inserted element +// the third is boolean indicating if the item was found +func Add(t *Pot, val Val, pof Pof) (*Pot, int, bool) { + return add(t, val, pof) +} + +func (t *Pot) clone() *Pot { + return &Pot{ + pin: t.pin, + size: t.size, + po: t.po, + bins: t.bins, + } +} + +func add(t *Pot, val Val, pof Pof) (*Pot, int, bool) { + var r *Pot + if t == nil || t.pin == nil { + r = t.clone() + r.pin = val + r.size++ + return r, 0, false + } + po, found := pof(t.pin, val, t.po) + if found { + r = t.clone() + r.pin = val + return r, po, true + } + + var p *Pot + var i, j int + size := t.size + for i < len(t.bins) { + n := t.bins[i] + if n.po == po { + p, _, found = add(n, val, pof) + if !found { + size++ + } + j++ + break + } + if n.po > po { + break + } + i++ + j++ + } + if p == nil { + size++ + p = &Pot{ + pin: val, + size: 1, + po: po, + } + } + + bins := append([]*Pot{}, t.bins[:i]...) + bins = append(bins, p) + bins = append(bins, t.bins[j:]...) + r = &Pot{ + pin: t.pin, + size: size, + po: t.po, + bins: bins, + } + + return r, po, found +} + +// Remove called on (v) deletes v from the Pot and returns +// the proximity order of v and a boolean value indicating +// if the value was found +// Remove called on (t, v) returns a new Pot that contains all the elements of t +// minus the value v, using the applicative remove +// the second return value is the proximity order of the inserted element +// the third is boolean indicating if the item was found +func Remove(t *Pot, v Val, pof Pof) (*Pot, int, bool) { + return remove(t, v, pof) +} + +func remove(t *Pot, val Val, pof Pof) (r *Pot, po int, found bool) { + size := t.size + po, found = pof(t.pin, val, t.po) + if found { + size-- + if size == 0 { + r = &Pot{ + po: t.po, + } + return r, po, true + } + i := len(t.bins) - 1 + last := t.bins[i] + r = &Pot{ + pin: last.pin, + bins: append(t.bins[:i], last.bins...), + size: size, + po: t.po, + } + return r, t.po, true + } + + var p *Pot + var i, j int + for i < len(t.bins) { + n := t.bins[i] + if n.po == po { + p, po, found = remove(n, val, pof) + if found { + size-- + } + j++ + break + } + if n.po > po { + return t, po, false + } + i++ + j++ + } + bins := t.bins[:i] + if p != nil && p.pin != nil { + bins = append(bins, p) + } + bins = append(bins, t.bins[j:]...) + r = &Pot{ + pin: val, + size: size, + po: t.po, + bins: bins, + } + return r, po, found +} + +// Swap called on (k, f) looks up the item at k +// and applies the function f to the value v at k or to nil if the item is not found +// if f(v) returns nil, the element is removed +// if f(v) returns v' <> v then v' is inserted into the Pot +// if (v) == v the Pot is not changed +// it panics if Pof(f(v), k) show that v' and v are not key-equal +func Swap(t *Pot, k Val, pof Pof, f func(v Val) Val) (r *Pot, po int, found bool, change bool) { + var val Val + if t.pin == nil { + val = f(nil) + if val == nil { + return nil, 0, false, false + } + return NewPot(val, t.po), 0, false, true + } + size := t.size + po, found = pof(k, t.pin, t.po) + if found { + val = f(t.pin) + // remove element + if val == nil { + size-- + if size == 0 { + r = &Pot{ + po: t.po, + } + // return empty pot + return r, po, true, true + } + // actually remove pin, by merging last bin + i := len(t.bins) - 1 + last := t.bins[i] + r = &Pot{ + pin: last.pin, + bins: append(t.bins[:i], last.bins...), + size: size, + po: t.po, + } + return r, po, true, true + } + // element found but no change + if val == t.pin { + return t, po, true, false + } + // actually modify the pinned element, but no change in structure + r = t.clone() + r.pin = val + return r, po, true, true + } + + // recursive step + var p *Pot + n, i := t.getPos(po) + if n != nil { + p, po, found, change = Swap(n, k, pof, f) + // recursive no change + if !change { + return t, po, found, false + } + // recursive change + bins := append([]*Pot{}, t.bins[:i]...) + if p.size == 0 { + size-- + } else { + size += p.size - n.size + bins = append(bins, p) + } + i++ + if i < len(t.bins) { + bins = append(bins, t.bins[i:]...) + } + r = t.clone() + r.bins = bins + r.size = size + return r, po, found, true + } + // key does not exist + val = f(nil) + if val == nil { + // and it should not be created + return t, po, false, false + } + // otherwise check val if equal to k + if _, eq := pof(val, k, po); !eq { + panic("invalid value") + } + /// + size++ + p = &Pot{ + pin: val, + size: 1, + po: po, + } + + bins := append([]*Pot{}, t.bins[:i]...) + bins = append(bins, p) + if i < len(t.bins) { + bins = append(bins, t.bins[i:]...) + } + r = t.clone() + r.bins = bins + r.size = size + return r, po, found, true +} + +// Union called on (t0, t1, pof) returns the union of t0 and t1 +// calculates the union using the applicative union +// the second return value is the number of common elements +func Union(t0, t1 *Pot, pof Pof) (*Pot, int) { + return union(t0, t1, pof) +} + +func union(t0, t1 *Pot, pof Pof) (*Pot, int) { + if t0 == nil || t0.size == 0 { + return t1, 0 + } + if t1 == nil || t1.size == 0 { + return t0, 0 + } + var pin Val + var bins []*Pot + var mis []int + wg := &sync.WaitGroup{} + wg.Add(1) + pin0 := t0.pin + pin1 := t1.pin + bins0 := t0.bins + bins1 := t1.bins + var i0, i1 int + var common int + + po, eq := pof(pin0, pin1, 0) + + for { + l0 := len(bins0) + l1 := len(bins1) + var n0, n1 *Pot + var p0, p1 int + var a0, a1 bool + + for { + + if !a0 && i0 < l0 && bins0[i0] != nil && bins0[i0].po <= po { + n0 = bins0[i0] + p0 = n0.po + a0 = p0 == po + } else { + a0 = true + } + + if !a1 && i1 < l1 && bins1[i1] != nil && bins1[i1].po <= po { + n1 = bins1[i1] + p1 = n1.po + a1 = p1 == po + } else { + a1 = true + } + if a0 && a1 { + break + } + + switch { + case (p0 < p1 || a1) && !a0: + bins = append(bins, n0) + i0++ + n0 = nil + case (p1 < p0 || a0) && !a1: + bins = append(bins, n1) + i1++ + n1 = nil + case p1 < po: + bl := len(bins) + bins = append(bins, nil) + ml := len(mis) + mis = append(mis, 0) + // wg.Add(1) + // go func(b, m int, m0, m1 *Pot) { + // defer wg.Done() + // bins[b], mis[m] = union(m0, m1, pof) + // }(bl, ml, n0, n1) + bins[bl], mis[ml] = union(n0, n1, pof) + i0++ + i1++ + n0 = nil + n1 = nil + } + } + + if eq { + common++ + pin = pin1 + break + } + + i := i0 + if len(bins0) > i && bins0[i].po == po { + i++ + } + var size0 int + for _, n := range bins0[i:] { + size0 += n.size + } + np := &Pot{ + pin: pin0, + bins: bins0[i:], + size: size0 + 1, + po: po, + } + + bins2 := []*Pot{np} + if n0 == nil { + pin0 = pin1 + po = maxkeylen + 1 + eq = true + common-- + + } else { + bins2 = append(bins2, n0.bins...) + pin0 = pin1 + pin1 = n0.pin + po, eq = pof(pin0, pin1, n0.po) + + } + bins0 = bins1 + bins1 = bins2 + i0 = i1 + i1 = 0 + + } + + wg.Done() + wg.Wait() + for _, c := range mis { + common += c + } + n := &Pot{ + pin: pin, + bins: bins, + size: t0.size + t1.size - common, + po: t0.po, + } + return n, common +} + +// Each called with (f) is a synchronous iterator over the bins of a node +// respecting an ordering +// proximity > pinnedness +func (t *Pot) Each(f func(Val, int) bool) bool { + return t.each(f) +} + +func (t *Pot) each(f func(Val, int) bool) bool { + var next bool + for _, n := range t.bins { + if n == nil { + return true + } + next = n.each(f) + if !next { + return false + } + } + if t.size == 0 { + return false + } + return f(t.pin, t.po) +} + +// EachFrom called with (f, start) is a synchronous iterator over the elements of a Pot +// within the inclusive range starting from proximity order start +// the function argument is passed the value and the proximity order wrt the root pin +// it does NOT include the pinned item of the root +// respecting an ordering +// proximity > pinnedness +// the iteration ends if the function return false or there are no more elements +// end of a po range can be implemented since po is passed to the function +func (t *Pot) EachFrom(f func(Val, int) bool, po int) bool { + return t.eachFrom(f, po) +} + +func (t *Pot) eachFrom(f func(Val, int) bool, po int) bool { + var next bool + _, lim := t.getPos(po) + for i := lim; i < len(t.bins); i++ { + n := t.bins[i] + next = n.each(f) + if !next { + return false + } + } + return f(t.pin, t.po) +} + +// EachBin iterates over bins of the pivot node and offers iterators to the caller on each +// subtree passing the proximity order and the size +// the iteration continues until the function's return value is false +// or there are no more subtries +func (t *Pot) EachBin(val Val, pof Pof, po int, f func(int, int, func(func(val Val, i int) bool) bool) bool) { + t.eachBin(val, pof, po, f) +} + +func (t *Pot) eachBin(val Val, pof Pof, po int, f func(int, int, func(func(val Val, i int) bool) bool) bool) { + if t == nil || t.size == 0 { + return + } + spr, _ := pof(t.pin, val, t.po) + _, lim := t.getPos(spr) + var size int + var n *Pot + for i := 0; i < lim; i++ { + n = t.bins[i] + size += n.size + if n.po < po { + continue + } + if !f(n.po, n.size, n.each) { + return + } + } + if lim == len(t.bins) { + if spr >= po { + f(spr, 1, func(g func(Val, int) bool) bool { + return g(t.pin, spr) + }) + } + return + } + + n = t.bins[lim] + + spo := spr + if n.po == spr { + spo++ + size += n.size + } + if spr >= po { + if !f(spr, t.size-size, func(g func(Val, int) bool) bool { + return t.eachFrom(func(v Val, j int) bool { + return g(v, spr) + }, spo) + }) { + return + } + } + if n.po == spr { + n.eachBin(val, pof, po, f) + } + +} + +// EachNeighbour is a synchronous iterator over neighbours of any target val +// the order of elements retrieved reflect proximity order to the target +// TODO: add maximum proxbin to start range of iteration +func (t *Pot) EachNeighbour(val Val, pof Pof, f func(Val, int) bool) bool { + return t.eachNeighbour(val, pof, f) +} + +func (t *Pot) eachNeighbour(val Val, pof Pof, f func(Val, int) bool) bool { + if t == nil || t.size == 0 { + return false + } + var next bool + l := len(t.bins) + var n *Pot + ir := l + il := l + po, eq := pof(t.pin, val, t.po) + if !eq { + n, il = t.getPos(po) + if n != nil { + next = n.eachNeighbour(val, pof, f) + if !next { + return false + } + ir = il + } else { + ir = il - 1 + } + } + + next = f(t.pin, po) + if !next { + return false + } + + for i := l - 1; i > ir; i-- { + next = t.bins[i].each(func(v Val, _ int) bool { + return f(v, po) + }) + if !next { + return false + } + } + + for i := il - 1; i >= 0; i-- { + n := t.bins[i] + next = n.each(func(v Val, _ int) bool { + return f(v, n.po) + }) + if !next { + return false + } + } + return true +} + +// EachNeighbourAsync called on (val, max, maxPos, f, wait) is an asynchronous iterator +// over elements not closer than maxPos wrt val. +// val does not need to be match an element of the Pot, but if it does, and +// maxPos is keylength than it is included in the iteration +// Calls to f are parallelised, the order of calls is undefined. +// proximity order is respected in that there is no element in the Pot that +// is not visited if a closer node is visited. +// The iteration is finished when max number of nearest nodes is visited +// or if the entire there are no nodes not closer than maxPos that is not visited +// if wait is true, the iterator returns only if all calls to f are finished +// TODO: implement minPos for proper prox range iteration +func (t *Pot) EachNeighbourAsync(val Val, pof Pof, max int, maxPos int, f func(Val, int), wait bool) { + if max > t.size { + max = t.size + } + var wg *sync.WaitGroup + if wait { + wg = &sync.WaitGroup{} + } + t.eachNeighbourAsync(val, pof, max, maxPos, f, wg) + if wait { + wg.Wait() + } +} + +func (t *Pot) eachNeighbourAsync(val Val, pof Pof, max int, maxPos int, f func(Val, int), wg *sync.WaitGroup) (extra int) { + l := len(t.bins) + + po, eq := pof(t.pin, val, t.po) + + // if po is too close, set the pivot branch (pom) to maxPos + pom := po + if pom > maxPos { + pom = maxPos + } + n, il := t.getPos(pom) + ir := il + // if pivot branch exists and po is not too close, iterate on the pivot branch + if pom == po { + if n != nil { + + m := n.size + if max < m { + m = max + } + max -= m + + extra = n.eachNeighbourAsync(val, pof, m, maxPos, f, wg) + + } else { + if !eq { + ir-- + } + } + } else { + extra++ + max-- + if n != nil { + il++ + } + // before checking max, add up the extra elements + // on the close branches that are skipped (if po is too close) + for i := l - 1; i >= il; i-- { + s := t.bins[i] + m := s.size + if max < m { + m = max + } + max -= m + extra += m + } + } + + var m int + if pom == po { + + m, max, extra = need(1, max, extra) + if m <= 0 { + return + } + + if wg != nil { + wg.Add(1) + } + go func() { + if wg != nil { + defer wg.Done() + } + f(t.pin, po) + }() + + // otherwise iterats + for i := l - 1; i > ir; i-- { + n := t.bins[i] + + m, max, extra = need(n.size, max, extra) + if m <= 0 { + return + } + + if wg != nil { + wg.Add(m) + } + go func(pn *Pot, pm int) { + pn.each(func(v Val, _ int) bool { + if wg != nil { + defer wg.Done() + } + f(v, po) + pm-- + return pm > 0 + }) + }(n, m) + + } + } + + // iterate branches that are farther tham pom with their own po + for i := il - 1; i >= 0; i-- { + n := t.bins[i] + // the first time max is less than the size of the entire branch + // wait for the pivot thread to release extra elements + m, max, extra = need(n.size, max, extra) + if m <= 0 { + return + } + + if wg != nil { + wg.Add(m) + } + go func(pn *Pot, pm int) { + pn.each(func(v Val, _ int) bool { + if wg != nil { + defer wg.Done() + } + f(v, pn.po) + pm-- + return pm > 0 + }) + }(n, m) + + } + return max + extra +} + +// getPos called on (n) returns the forking node at PO n and its index if it exists +// otherwise nil +// caller is supposed to hold the lock +func (t *Pot) getPos(po int) (n *Pot, i int) { + for i, n = range t.bins { + if po > n.po { + continue + } + if po < n.po { + return nil, i + } + return n, i + } + return nil, len(t.bins) +} + +// need called on (m, max, extra) uses max m out of extra, and then max +// if needed, returns the adjusted counts +func need(m, max, extra int) (int, int, int) { + if m <= extra { + return m, max, extra - m + } + max += extra - m + if max <= 0 { + return m + max, 0, 0 + } + return m, max, 0 +} + +func (t *Pot) String() string { + return t.sstring("") +} + +func (t *Pot) sstring(indent string) string { + if t == nil { + return "" + } + var s string + indent += " " + s += fmt.Sprintf("%v%v (%v) %v \n", indent, t.pin, t.po, t.size) + for _, n := range t.bins { + s += fmt.Sprintf("%v%v\n", indent, n.sstring(indent)) + } + return s +} diff --git a/swarm/pot/pot_test.go b/swarm/pot/pot_test.go new file mode 100644 index 0000000000..aeb23dfc6b --- /dev/null +++ b/swarm/pot/pot_test.go @@ -0,0 +1,685 @@ +// 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 pot + +import ( + "errors" + "fmt" + "math/rand" + "runtime" + "sync" + "testing" + "time" + + "github.com/ethereum/go-ethereum/swarm/log" +) + +const ( + maxEachNeighbourTests = 420 + maxEachNeighbour = 420 + maxSwap = 420 + maxSwapTests = 420 +) + +// func init() { +// log.Root().SetHandler(log.LvlFilterHandler(log.LvlTrace, log.StreamHandler(os.Stderr, log.TerminalFormat(false)))) +// } + +type testAddr struct { + a []byte + i int +} + +func newTestAddr(s string, i int) *testAddr { + return &testAddr{NewAddressFromString(s), i} +} + +func (a *testAddr) Address() []byte { + return a.a +} + +func (a *testAddr) String() string { + return Label(a.a) +} + +func randomTestAddr(n int, i int) *testAddr { + v := RandomAddress().Bin()[:n] + return newTestAddr(v, i) +} + +func randomtestAddr(n int, i int) *testAddr { + v := RandomAddress().Bin()[:n] + return newTestAddr(v, i) +} + +func indexes(t *Pot) (i []int, po []int) { + t.Each(func(v Val, p int) bool { + a := v.(*testAddr) + i = append(i, a.i) + po = append(po, p) + return true + }) + return i, po +} + +func testAdd(t *Pot, pof Pof, j int, values ...string) (_ *Pot, n int, f bool) { + for i, val := range values { + t, n, f = Add(t, newTestAddr(val, i+j), pof) + } + return t, n, f +} + +func TestPotAdd(t *testing.T) { + pof := DefaultPof(8) + n := NewPot(newTestAddr("00111100", 0), 0) + // Pin set correctly + exp := "00111100" + got := Label(n.Pin())[:8] + if got != exp { + t.Fatalf("incorrect pinned value. Expected %v, got %v", exp, got) + } + // check size + goti := n.Size() + expi := 1 + if goti != expi { + t.Fatalf("incorrect number of elements in Pot. Expected %v, got %v", expi, goti) + } + + n, _, _ = testAdd(n, pof, 1, "01111100", "00111100", "01111100", "00011100") + // check size + goti = n.Size() + expi = 3 + if goti != expi { + t.Fatalf("incorrect number of elements in Pot. Expected %v, got %v", expi, goti) + } + inds, po := indexes(n) + got = fmt.Sprintf("%v", inds) + exp = "[3 4 2]" + if got != exp { + t.Fatalf("incorrect indexes in iteration over Pot. Expected %v, got %v", exp, got) + } + got = fmt.Sprintf("%v", po) + exp = "[1 2 0]" + if got != exp { + t.Fatalf("incorrect po-s in iteration over Pot. Expected %v, got %v", exp, got) + } +} + +func TestPotRemove(t *testing.T) { + pof := DefaultPof(8) + n := NewPot(newTestAddr("00111100", 0), 0) + n, _, _ = Remove(n, newTestAddr("00111100", 0), pof) + exp := "" + got := Label(n.Pin()) + if got != exp { + t.Fatalf("incorrect pinned value. Expected %v, got %v", exp, got) + } + n, _, _ = testAdd(n, pof, 1, "00000000", "01111100", "00111100", "00011100") + n, _, _ = Remove(n, newTestAddr("00111100", 0), pof) + goti := n.Size() + expi := 3 + if goti != expi { + t.Fatalf("incorrect number of elements in Pot. Expected %v, got %v", expi, goti) + } + inds, po := indexes(n) + got = fmt.Sprintf("%v", inds) + exp = "[2 4 0]" + if got != exp { + t.Fatalf("incorrect indexes in iteration over Pot. Expected %v, got %v", exp, got) + } + got = fmt.Sprintf("%v", po) + exp = "[1 3 0]" + if got != exp { + t.Fatalf("incorrect po-s in iteration over Pot. Expected %v, got %v", exp, got) + } + // remove again + n, _, _ = Remove(n, newTestAddr("00111100", 0), pof) + inds, _ = indexes(n) + got = fmt.Sprintf("%v", inds) + exp = "[2 4]" + if got != exp { + t.Fatalf("incorrect indexes in iteration over Pot. Expected %v, got %v", exp, got) + } + +} + +func TestPotSwap(t *testing.T) { + for i := 0; i < maxSwapTests; i++ { + alen := maxkeylen + pof := DefaultPof(alen) + max := rand.Intn(maxSwap) + + n := NewPot(nil, 0) + var m []*testAddr + var found bool + for j := 0; j < 2*max; { + v := randomtestAddr(alen, j) + n, _, found = Add(n, v, pof) + if !found { + m = append(m, v) + j++ + } + } + k := make(map[string]*testAddr) + for j := 0; j < max; { + v := randomtestAddr(alen, 1) + _, found := k[Label(v)] + if !found { + k[Label(v)] = v + j++ + } + } + for _, v := range k { + m = append(m, v) + } + f := func(v Val) Val { + tv := v.(*testAddr) + if tv.i < max { + return nil + } + tv.i = 0 + return v + } + for _, val := range m { + n, _, _, _ = Swap(n, val, pof, func(v Val) Val { + if v == nil { + return val + } + return f(v) + }) + } + sum := 0 + n.Each(func(v Val, i int) bool { + if v == nil { + return true + } + sum++ + tv := v.(*testAddr) + if tv.i > 1 { + t.Fatalf("item value incorrect, expected 0, got %v", tv.i) + } + return true + }) + if sum != 2*max { + t.Fatalf("incorrect number of elements. expected %v, got %v", 2*max, sum) + } + if sum != n.Size() { + t.Fatalf("incorrect size. expected %v, got %v", sum, n.Size()) + } + } +} + +func checkPo(val Val, pof Pof) func(Val, int) error { + return func(v Val, po int) error { + // check the po + exp, _ := pof(val, v, 0) + if po != exp { + return fmt.Errorf("incorrect prox order for item %v in neighbour iteration for %v. Expected %v, got %v", v, val, exp, po) + } + return nil + } +} + +func checkOrder(val Val) func(Val, int) error { + po := maxkeylen + return func(v Val, p int) error { + if po < p { + return fmt.Errorf("incorrect order for item %v in neighbour iteration for %v. PO %v > %v (previous max)", v, val, p, po) + } + po = p + return nil + } +} + +func checkValues(m map[string]bool, val Val) func(Val, int) error { + return func(v Val, po int) error { + duplicate, ok := m[Label(v)] + if !ok { + return fmt.Errorf("alien value %v", v) + } + if duplicate { + return fmt.Errorf("duplicate value returned: %v", v) + } + m[Label(v)] = true + return nil + } +} + +var errNoCount = errors.New("not count") + +func testPotEachNeighbour(n *Pot, pof Pof, val Val, expCount int, fs ...func(Val, int) error) error { + var err error + var count int + n.EachNeighbour(val, pof, func(v Val, po int) bool { + for _, f := range fs { + err = f(v, po) + if err != nil { + return err.Error() == errNoCount.Error() + } + } + count++ + return count != expCount + }) + if err == nil && count < expCount { + return fmt.Errorf("not enough neighbours returned, expected %v, got %v", expCount, count) + } + return err +} + +const ( + mergeTestCount = 5 + mergeTestChoose = 5 +) + +func TestPotMergeCommon(t *testing.T) { + vs := make([]*testAddr, mergeTestCount) + for i := 0; i < maxEachNeighbourTests; i++ { + alen := maxkeylen + pof := DefaultPof(alen) + + for j := 0; j < len(vs); j++ { + vs[j] = randomtestAddr(alen, j) + } + max0 := rand.Intn(mergeTestChoose) + 1 + max1 := rand.Intn(mergeTestChoose) + 1 + n0 := NewPot(nil, 0) + n1 := NewPot(nil, 0) + log.Trace(fmt.Sprintf("round %v: %v - %v", i, max0, max1)) + m := make(map[string]bool) + var found bool + for j := 0; j < max0; { + r := rand.Intn(max0) + v := vs[r] + n0, _, found = Add(n0, v, pof) + if !found { + m[Label(v)] = false + j++ + } + } + expAdded := 0 + + for j := 0; j < max1; { + r := rand.Intn(max1) + v := vs[r] + n1, _, found = Add(n1, v, pof) + if !found { + j++ + } + _, found = m[Label(v)] + if !found { + expAdded++ + m[Label(v)] = false + } + } + if i < 6 { + continue + } + expSize := len(m) + log.Trace(fmt.Sprintf("%v-0: pin: %v, size: %v", i, n0.Pin(), max0)) + log.Trace(fmt.Sprintf("%v-1: pin: %v, size: %v", i, n1.Pin(), max1)) + log.Trace(fmt.Sprintf("%v: merged tree size: %v, newly added: %v", i, expSize, expAdded)) + n, common := Union(n0, n1, pof) + added := n1.Size() - common + size := n.Size() + + if expSize != size { + t.Fatalf("%v: incorrect number of elements in merged pot, expected %v, got %v\n%v", i, expSize, size, n) + } + if expAdded != added { + t.Fatalf("%v: incorrect number of added elements in merged pot, expected %v, got %v", i, expAdded, added) + } + if !checkDuplicates(n) { + t.Fatalf("%v: merged pot contains duplicates: \n%v", i, n) + } + for k := range m { + _, _, found = Add(n, newTestAddr(k, 0), pof) + if !found { + t.Fatalf("%v: merged pot (size:%v, added: %v) missing element %v", i, size, added, k) + } + } + } +} + +func TestPotMergeScale(t *testing.T) { + for i := 0; i < maxEachNeighbourTests; i++ { + alen := maxkeylen + pof := DefaultPof(alen) + max0 := rand.Intn(maxEachNeighbour) + 1 + max1 := rand.Intn(maxEachNeighbour) + 1 + n0 := NewPot(nil, 0) + n1 := NewPot(nil, 0) + log.Trace(fmt.Sprintf("round %v: %v - %v", i, max0, max1)) + m := make(map[string]bool) + var found bool + for j := 0; j < max0; { + v := randomtestAddr(alen, j) + n0, _, found = Add(n0, v, pof) + if !found { + m[Label(v)] = false + j++ + } + } + expAdded := 0 + + for j := 0; j < max1; { + v := randomtestAddr(alen, j) + n1, _, found = Add(n1, v, pof) + if !found { + j++ + } + _, found = m[Label(v)] + if !found { + expAdded++ + m[Label(v)] = false + } + } + if i < 6 { + continue + } + expSize := len(m) + log.Trace(fmt.Sprintf("%v-0: pin: %v, size: %v", i, n0.Pin(), max0)) + log.Trace(fmt.Sprintf("%v-1: pin: %v, size: %v", i, n1.Pin(), max1)) + log.Trace(fmt.Sprintf("%v: merged tree size: %v, newly added: %v", i, expSize, expAdded)) + n, common := Union(n0, n1, pof) + added := n1.Size() - common + size := n.Size() + + if expSize != size { + t.Fatalf("%v: incorrect number of elements in merged pot, expected %v, got %v", i, expSize, size) + } + if expAdded != added { + t.Fatalf("%v: incorrect number of added elements in merged pot, expected %v, got %v", i, expAdded, added) + } + if !checkDuplicates(n) { + t.Fatalf("%v: merged pot contains duplicates", i) + } + for k := range m { + _, _, found = Add(n, newTestAddr(k, 0), pof) + if !found { + t.Fatalf("%v: merged pot (size:%v, added: %v) missing element %v", i, size, added, k) + } + } + } +} + +func checkDuplicates(t *Pot) bool { + po := -1 + for _, c := range t.bins { + if c == nil { + return false + } + if c.po <= po || !checkDuplicates(c) { + return false + } + po = c.po + } + return true +} + +func TestPotEachNeighbourSync(t *testing.T) { + for i := 0; i < maxEachNeighbourTests; i++ { + alen := maxkeylen + pof := DefaultPof(maxkeylen) + max := rand.Intn(maxEachNeighbour/2) + maxEachNeighbour/2 + pin := randomTestAddr(alen, 0) + n := NewPot(pin, 0) + m := make(map[string]bool) + m[Label(pin)] = false + for j := 1; j <= max; j++ { + v := randomTestAddr(alen, j) + n, _, _ = Add(n, v, pof) + m[Label(v)] = false + } + + size := n.Size() + if size < 2 { + continue + } + count := rand.Intn(size/2) + size/2 + val := randomTestAddr(alen, max+1) + log.Trace(fmt.Sprintf("%v: pin: %v, size: %v, val: %v, count: %v", i, n.Pin(), size, val, count)) + err := testPotEachNeighbour(n, pof, val, count, checkPo(val, pof), checkOrder(val), checkValues(m, val)) + if err != nil { + t.Fatal(err) + } + minPoFound := alen + maxPoNotFound := 0 + for k, found := range m { + po, _ := pof(val, newTestAddr(k, 0), 0) + if found { + if po < minPoFound { + minPoFound = po + } + } else { + if po > maxPoNotFound { + maxPoNotFound = po + } + } + } + if minPoFound < maxPoNotFound { + t.Fatalf("incorrect neighbours returned: found one with PO %v < there was one not found with PO %v", minPoFound, maxPoNotFound) + } + } +} + +func TestPotEachNeighbourAsync(t *testing.T) { + for i := 0; i < maxEachNeighbourTests; i++ { + max := rand.Intn(maxEachNeighbour/2) + maxEachNeighbour/2 + alen := maxkeylen + pof := DefaultPof(alen) + n := NewPot(randomTestAddr(alen, 0), 0) + size := 1 + var found bool + for j := 1; j <= max; j++ { + v := randomTestAddr(alen, j) + n, _, found = Add(n, v, pof) + if !found { + size++ + } + } + if size != n.Size() { + t.Fatal(n) + } + if size < 2 { + continue + } + count := rand.Intn(size/2) + size/2 + val := randomTestAddr(alen, max+1) + + mu := sync.Mutex{} + m := make(map[string]bool) + maxPos := rand.Intn(alen) + log.Trace(fmt.Sprintf("%v: pin: %v, size: %v, val: %v, count: %v, maxPos: %v", i, n.Pin(), size, val, count, maxPos)) + msize := 0 + remember := func(v Val, po int) error { + if po > maxPos { + return errNoCount + } + m[Label(v)] = true + msize++ + return nil + } + if i == 0 { + continue + } + testPotEachNeighbour(n, pof, val, count, remember) + d := 0 + forget := func(v Val, po int) { + mu.Lock() + defer mu.Unlock() + d++ + delete(m, Label(v)) + } + + n.EachNeighbourAsync(val, pof, count, maxPos, forget, true) + if d != msize { + t.Fatalf("incorrect number of neighbour calls in async iterator. expected %v, got %v", msize, d) + } + if len(m) != 0 { + t.Fatalf("incorrect neighbour calls in async iterator. %v items missed:\n%v", len(m), n) + } + } +} + +func benchmarkEachNeighbourSync(t *testing.B, max, count int, d time.Duration) { + t.ReportAllocs() + alen := maxkeylen + pof := DefaultPof(alen) + pin := randomTestAddr(alen, 0) + n := NewPot(pin, 0) + var found bool + for j := 1; j <= max; { + v := randomTestAddr(alen, j) + n, _, found = Add(n, v, pof) + if !found { + j++ + } + } + t.ResetTimer() + for i := 0; i < t.N; i++ { + val := randomTestAddr(alen, max+1) + m := 0 + n.EachNeighbour(val, pof, func(v Val, po int) bool { + time.Sleep(d) + m++ + return m != count + }) + } + t.StopTimer() + stats := new(runtime.MemStats) + runtime.ReadMemStats(stats) +} + +func benchmarkEachNeighbourAsync(t *testing.B, max, count int, d time.Duration) { + t.ReportAllocs() + alen := maxkeylen + pof := DefaultPof(alen) + pin := randomTestAddr(alen, 0) + n := NewPot(pin, 0) + var found bool + for j := 1; j <= max; { + v := randomTestAddr(alen, j) + n, _, found = Add(n, v, pof) + if !found { + j++ + } + } + t.ResetTimer() + for i := 0; i < t.N; i++ { + val := randomTestAddr(alen, max+1) + n.EachNeighbourAsync(val, pof, count, alen, func(v Val, po int) { + time.Sleep(d) + }, true) + } + t.StopTimer() + stats := new(runtime.MemStats) + runtime.ReadMemStats(stats) +} + +func BenchmarkEachNeighbourSync_3_1_0(t *testing.B) { + benchmarkEachNeighbourSync(t, 1000, 10, 1*time.Microsecond) +} +func BenchmarkEachNeighboursAsync_3_1_0(t *testing.B) { + benchmarkEachNeighbourAsync(t, 1000, 10, 1*time.Microsecond) +} +func BenchmarkEachNeighbourSync_3_2_0(t *testing.B) { + benchmarkEachNeighbourSync(t, 1000, 100, 1*time.Microsecond) +} +func BenchmarkEachNeighboursAsync_3_2_0(t *testing.B) { + benchmarkEachNeighbourAsync(t, 1000, 100, 1*time.Microsecond) +} +func BenchmarkEachNeighbourSync_3_3_0(t *testing.B) { + benchmarkEachNeighbourSync(t, 1000, 1000, 1*time.Microsecond) +} +func BenchmarkEachNeighboursAsync_3_3_0(t *testing.B) { + benchmarkEachNeighbourAsync(t, 1000, 1000, 1*time.Microsecond) +} + +func BenchmarkEachNeighbourSync_3_1_1(t *testing.B) { + benchmarkEachNeighbourSync(t, 1000, 10, 2*time.Microsecond) +} +func BenchmarkEachNeighboursAsync_3_1_1(t *testing.B) { + benchmarkEachNeighbourAsync(t, 1000, 10, 2*time.Microsecond) +} +func BenchmarkEachNeighbourSync_3_2_1(t *testing.B) { + benchmarkEachNeighbourSync(t, 1000, 100, 2*time.Microsecond) +} +func BenchmarkEachNeighboursAsync_3_2_1(t *testing.B) { + benchmarkEachNeighbourAsync(t, 1000, 100, 2*time.Microsecond) +} +func BenchmarkEachNeighbourSync_3_3_1(t *testing.B) { + benchmarkEachNeighbourSync(t, 1000, 1000, 2*time.Microsecond) +} +func BenchmarkEachNeighboursAsync_3_3_1(t *testing.B) { + benchmarkEachNeighbourAsync(t, 1000, 1000, 2*time.Microsecond) +} + +func BenchmarkEachNeighbourSync_3_1_2(t *testing.B) { + benchmarkEachNeighbourSync(t, 1000, 10, 4*time.Microsecond) +} +func BenchmarkEachNeighboursAsync_3_1_2(t *testing.B) { + benchmarkEachNeighbourAsync(t, 1000, 10, 4*time.Microsecond) +} +func BenchmarkEachNeighbourSync_3_2_2(t *testing.B) { + benchmarkEachNeighbourSync(t, 1000, 100, 4*time.Microsecond) +} +func BenchmarkEachNeighboursAsync_3_2_2(t *testing.B) { + benchmarkEachNeighbourAsync(t, 1000, 100, 4*time.Microsecond) +} +func BenchmarkEachNeighbourSync_3_3_2(t *testing.B) { + benchmarkEachNeighbourSync(t, 1000, 1000, 4*time.Microsecond) +} +func BenchmarkEachNeighboursAsync_3_3_2(t *testing.B) { + benchmarkEachNeighbourAsync(t, 1000, 1000, 4*time.Microsecond) +} + +func BenchmarkEachNeighbourSync_3_1_3(t *testing.B) { + benchmarkEachNeighbourSync(t, 1000, 10, 8*time.Microsecond) +} +func BenchmarkEachNeighboursAsync_3_1_3(t *testing.B) { + benchmarkEachNeighbourAsync(t, 1000, 10, 8*time.Microsecond) +} +func BenchmarkEachNeighbourSync_3_2_3(t *testing.B) { + benchmarkEachNeighbourSync(t, 1000, 100, 8*time.Microsecond) +} +func BenchmarkEachNeighboursAsync_3_2_3(t *testing.B) { + benchmarkEachNeighbourAsync(t, 1000, 100, 8*time.Microsecond) +} +func BenchmarkEachNeighbourSync_3_3_3(t *testing.B) { + benchmarkEachNeighbourSync(t, 1000, 1000, 8*time.Microsecond) +} +func BenchmarkEachNeighboursAsync_3_3_3(t *testing.B) { + benchmarkEachNeighbourAsync(t, 1000, 1000, 8*time.Microsecond) +} + +func BenchmarkEachNeighbourSync_3_1_4(t *testing.B) { + benchmarkEachNeighbourSync(t, 1000, 10, 16*time.Microsecond) +} +func BenchmarkEachNeighboursAsync_3_1_4(t *testing.B) { + benchmarkEachNeighbourAsync(t, 1000, 10, 16*time.Microsecond) +} +func BenchmarkEachNeighbourSync_3_2_4(t *testing.B) { + benchmarkEachNeighbourSync(t, 1000, 100, 16*time.Microsecond) +} +func BenchmarkEachNeighboursAsync_3_2_4(t *testing.B) { + benchmarkEachNeighbourAsync(t, 1000, 100, 16*time.Microsecond) +} +func BenchmarkEachNeighbourSync_3_3_4(t *testing.B) { + benchmarkEachNeighbourSync(t, 1000, 1000, 16*time.Microsecond) +} +func BenchmarkEachNeighboursAsync_3_3_4(t *testing.B) { + benchmarkEachNeighbourAsync(t, 1000, 1000, 16*time.Microsecond) +} diff --git a/swarm/pss/ARCHITECTURE.md b/swarm/pss/ARCHITECTURE.md new file mode 100644 index 0000000000..279e895ab7 --- /dev/null +++ b/swarm/pss/ARCHITECTURE.md @@ -0,0 +1,144 @@ +# Postal Service over Swarm + +Pss provides devp2p functionality for swarm nodes without the need for a direct tcp connection between them. + +Messages are encapsulated in a devp2p message structure `PssMsg`. These capsules are forwarded from node to node using ordinary tcp devp2p until they reach their destination: The node or nodes who can successfully decrypt the message. + +| Layer | Contents | +|-----------|-----------------| +| PssMsg: | Address, Expiry | +| Envelope: | Topic | +| Payload: | e(data) | + +Routing of messages is done using swarm's own kademlia routing. Optionally routing can be turned off, forcing the message to be sent to all peers, similar to the behavior of the whisper protocol. + +Pss is intended for messages of limited size, typically a couple of Kbytes at most. The messages themselves can be anything at all; complex data structures or non-descript byte sequences. + +For the current state and roadmap of pss development please see https://github.com/ethersphere/swarm/wiki/swarm-dev-progress. + +Please report issues on https://github.com/ethersphere/go-ethereum + +Feel free to ask questions in https://gitter.im/ethersphere/pss + +## STATUS OF THIS DOCUMENT + +`pss` is under active development, and the first implementation is yet to be merged to the Ethereum main branch. Expect things to change. + +## CORE INTERFACES + +The pss core provides low level control of key handling and message exchange. + +### TOPICS + +An encrypted envelope of a pss message always contains a Topic. This is pss' way of determining which message handlers to dispatch messages to. The topic of a message is only visible for the node(s) who can decrypt the message. + +This "topic" is not like the subject of an email message, but a hash-like arbitrary 4 byte value. A valid topic can be generated using the `pss_*ToTopic` API methods. + +### IDENTITY AND ENCRYPTION + +Pss aims to achieve perfect darkness. That means that the minimum requirement for two nodes to communicate using pss is a shared secret. This secret can be an arbitrary byte slice, or a ECDSA keypair. The end recipient of a message is defined as the node that can successfully decrypt that message using stored keys. + +A node's public key is derived from the private key passed to the `pss` constructor. Pss (currently) has no PKI. + +Peer keys can manually be added to the pss node through its API calls `pss_setPeerPublicKey` and `pss_setSymmetricKey`. Keys are always coupled with a topic, and the keys will only be valid for these topics. + +### CONNECTIONS + +A "connection" in pss is a purely virtual construct. There is no mechanisms in place to ensure that the remote peer actually is there. In fact, "adding" a peer involves merely the node's opinion that the peer is there. It may issue messages to that remote peer to a directly connected peer, which in turn passes it on. But if it is not present on the network - or if there is no route to it - the message will never reach its destination through mere forwarding. + +Since pss itself never requires a confirmation from a peer of whether a message is received or not, one could argue that pss shows `UDP`-like behavior. + +It is also important to note that if the wrong (partial) address is set for a particular key/topic combination, the message may never reach that peer. The further left in the address byte slice the error lies, the less likely it is that delivery will occur. + + +### EXCHANGE + +Message exchange in `pss` *requires* end-to-end encryption. + +The API methods `pss_sendSym` and `pss_sendAsym` sends an arbitrary byte slice with a specific topic to a pss peer using the respective encryption scheme. The key passed to the send method must be associated with a topic in the pss key store prior to sending, or the send method will fail. + +Return values from the send methods do *not* indicate whether the message was successfully delivered to the pss peer. It *only* indicates whether or not the message could be passed on to the network. If the message could not be forwarded to any peers, the method will fail. + +Keep in mind that symmetric encryption is less resource-intensive than asymmetric encryption. The former should be used for nodes with high message volumes. + +## EXTENSIONS + +### HANDSHAKE + +Pss offers an optional Diffie-Hellman handshake mechanism. Handshake functionality is activated per topic, and can be deactivated per topic even while the node is running. + +Handshakes are activated in the code implementation of the node by running `SetHandshakeController()` on the pss node instance BEFORE starting the node service. The methods exposed by the HandshakeController's API gives the possibility to initiate, remove and check the state of handshakes and associated keys. + +See the `HandshakeAPI` section in `godoc` for details. + +### DEVP2P PROTOCOLS + +The `Protocol` convenience structure is provided to mimic devp2p-type protocols over pss. In theory this makes it possible to reuse protocol code written for devp2p with a minimum of effort. + +#### OUTGOING CONNECTIONS + +In order to message a peer using this layer, a `Protocol` object must first be instantiated. When this is done, peers can be added using the protocol's `AddPeer()` method. The peer's key/topic combination must be in the pss key store before the peer can be aded. + +Adding a peer in effect "runs" the protocol on that peer, and adds an internal mapping between a topic and that peer, and enables sending and receiving messages using the usual io-construct of devp2p. It does not actually *transmit* anything to the peer, it merely represents the node's opinion that a connection with the peer exists. (See CONNECTION above). + +#### INCOMING CONNECTIONS + +An incoming connection is nothing more than an actual PssMsg appearing with a certain Topic. If a Handler has been registered to that Topic, the message will be passed to it. This constitutes a "new" connection if: + +- The pss node never called AddPeer with this combination of remote peer address and topic, and + +- The pss node never received a PssMsg from this remote peer with this specific Topic before. + +If it is a "new" connection, the protocol will be "run" on the remote peer, as if the peer was added via the API. + +As with the `AddPeer()` method, the key/topic of the originating peer must exist in the pss key store. + +#### TOPICS IN DEVP2P + +The `ProtocolTopic()` method should be used to determine the correct topic to use for a pss `Protocol` instance. + +## EXAMPLES + +Coming. Please refer to the tests for now. + +## PSS INTERNALS + +Pss implements the node.Service interface. It depends on a working kademlia overlay for routing. + +### DECRYPTION + +When processing an incoming message, `pss` detects whether it is encrypted symmetrically or asymmetrically. + +When decrypting symmetrically, `pss` iterates through all stored keys, and attempts to decrypt with each key in order. + +pss keeps a *cache* of these keys. The cache will only store a certain amount of keys, and the iterator will return keys in the order of most recently used key first. Abandoned keys will be garbage collected. + +### ROUTING + +(please refer to swarm kademlia routing for an explanation of the routing algorithm used for pss) + +`pss` uses *address hinting* for routing. The address hint is an arbitrary-length MSB byte slice of the peer's swarm overlay address. It can be the whole address, part of the address, or even an empty byte slice. The slice will be matched to the MSB slice of the same length of all devp2p peers in the routing stage. + +If an empty byte slice is passed, all devp2p peers will match the address hint, and the message will be forwarded to everyone. This is equivalent to `whisper` routing, and makes it difficult to perform traffic analysis based on who messages are forwarded to. + +A node will also forward to everyone if the address hint provided is in its proximity bin, both to provide saturation to increase chances of delivery, and also for recipient obfuscation to thwart traffic analysis attacks. The recipient node(s) will always forward to all its peers. + +### CACHING + +pss implements a simple caching mechanism for messages, using the swarm FileStore for storage of the messages and generation of the digest keys used in the cache table. The caching is intended to alleviate the following: + +- save messages so that they can be delivered later if the recipient was not online at the time of sending. + +- drop an identical message to the same recipient if received within a given time interval + +- prevent backwards routing of messages + +the latter may occur if only one entry is in the receiving node's kademlia, or if the proximity of the current node recipient hinted by the address is so close that the message will be forwarded to everyone. In these cases the forwarder will be provided as the "nearest node" to the final recipient. The cache keeps the address of who the message was forwarded from, and if the cache lookup matches, the message will be dropped. + +### DEVP2P PROTOCOLS + +When implementing devp2p protocols, topics are derived from protocols' name and version. The Protocol provides a generic Handler that be passed to Pss.Register. This makes it possible to use the same message handler code for pss that is used for directly connected peers in devp2p. + +Under the hood, pss implements its own MsgReadWriter, which bridges MsgReadWriter.WriteMsg with Pss.SendRaw, and deftly adds an InjectMsg method which pipes incoming messages to appear on the MsgReadWriter.ReadMsg channel. + + diff --git a/swarm/pss/README.md b/swarm/pss/README.md new file mode 100644 index 0000000000..aea871251f --- /dev/null +++ b/swarm/pss/README.md @@ -0,0 +1,318 @@ +# Postal Services over Swarm + +`pss` enables message relay over swarm. This means nodes can send messages to each other without being directly connected with each other, while taking advantage of the efficient routing algorithms that swarm uses for transporting and storing data. + +### CONTENTS + +* Status of this document +* Core concepts +* Caveat +* Examples +* API + * Retrieve node information + * Receive messages + * Send messages using public key encryption + * Send messages using symmetric encryption + * Querying peer keys + * Handshakes + +### STATUS OF THIS DOCUMENT + +`pss` is under active development, and the first implementation is yet to be merged to the Ethereum main branch. Expect things to change. + +Details on swarm routing and encryption schemes out of scope of this document. + +Please refer to [ARCHITECTURE.md](ARCHITECTURE.md) for in-depth topics concerning `pss`. + +## CORE CONCEPTS + +Three things are required to send a `pss` message: + +1. Encryption key +2. Topic +3. Message payload + +Encryption key can be a public key or a 32 byte symmetric key. It must be coupled with a peer address in the node prior to sending. + +Topic is the initial 4 bytes of a hash value. + +Message payload is an arbitrary byte slice of data. + +Upon sending the message it is encrypted and passed on from peer to peer. Any node along the route that can successfully decrypt the message is regarded as a recipient. Recipients continue to pass on the message to their peers, to make traffic analysis attacks more difficult. + +The Address that is coupled with the encryption keys are used for routing the message. This does *not* need to be a full addresses; the network will route the message to the best of its ability with the information that is available. If *no* address is given (zero-length byte slice), routing is effectively deactivated, and the message is passed to all peers by all peers. + +## CAVEAT + +`pss` connectivity resembles UDP. This means there is no delivery guarantee for a message. Furthermore there is no strict definition of what a connection between two nodes communicating via `pss` is. Reception acknowledgements and keepalive-schemes is the responsibility of the application. + +Due to the inherent properties of the `swarm` routing algorithm, a node may receive the same message more than once. Message deduplication *cannot be guaranteed* by `pss`, and must be handled in the application layer to ensure predictable results. + +## EXAMPLES + +The code tutorial [p2p programming in go-ethereum](https://github.com/nolash/go-ethereum-p2p-demo) by [@nolash](https://github.com/nolash) provides step-by-step code examples for usage of `pss` API with `go-ethereum` nodes. + +A quite unpolished example using `javascript` is available here: [https://github.com/nolash/pss-js/tree/withcrypt](https://github.com/nolash/pss-js/tree/withcrypt) + +## API + +The `pss` API is available through IPC and Websockets. There is currently no `web3.js` implementation, as this does not support message subscription. + +For `golang` clients, please use the `rpc.Client` provided by the `go-ethereum` repository. The return values may have special types in `golang`. Please refer to `godoc` for details. + +### RETRIEVE NODE INFORMATION + +#### pss_getPublicKey + +Retrieves the public key of the node, in hex format + +``` +parameters: +none + +returns: +1. publickey (hex) +``` + +#### pss_baseAddr + +Retrieves the swarm overlay address of the node, in hex format + +``` +parameters: +none + +returns: +1. swarm overlay address (hex) +``` + +#### pss_stringToTopic + +Creates a deterministic 4 byte topic value from input, returned in hex format + +``` +parameters: +1. topic string (string) + +returns: +1. pss topic (hex) +``` + +### RECEIVE MESSAGES + +#### pss_subscribe + +Creates a subscription. Received messages with matching topic will be passed to subscription client. + +``` +parameters: +1. string("receive") +2. topic (4 bytes in hex) + +returns: +1. subscription handle `base64(byte)` `rpc.ClientSubscription` +``` + +In `golang` as special method is used: + +`rpc.Client.Subscribe(context.Context, "pss", chan pss.APIMsg, "receive", pss.Topic)` + +Incoming messages are encapsulated in an object (`pss.APIMsg` in `golang`) with the following members: + +``` +1. Msg (hex) - the message payload +2. Asymmetric (bool) - true if message used public key encryption +3. Key (string) - the encryption key used +``` + +### SEND MESSAGE USING PUBLIC KEY ENCRYPTION + +#### pss_setPeerPublicKey + +Register a peer's public key. This is done once for every topic that will be used with the peer. Address can be anything from 0 to 32 bytes inclusive of the peer's swarm overlay address. + +``` +parameters: +1. public key of peer (hex) +2. topic (4 bytes in hex) +3. address of peer (hex) + +returns: +none +``` + +#### pss_sendAsym + +Encrypts the message using the provided public key, and signs it using the node's private key. It then wraps it in an envelope containing the topic, and sends it to the network. + +``` +parameters: +1. public key of peer (hex) +2. topic (4 bytes in hex) +3. message (hex) + +returns: +none +``` + +### SEND MESSAGE USING SYMMETRIC ENCRYPTION + +#### pss_setSymmetricKey + +Register a symmetric key shared with a peer. This is done once for every topic that will be used with the peer. Address can be anything from 0 to 32 bytes inclusive of the peer's swarm overlay address. + +If the fourth parameter is false, the key will *not* be added to the list of symmetric keys used for decryption attempts. + +``` +parameters: +1. symmetric key (hex) +2. topic (4 bytes in hex) +3. address of peer (hex) +4. use for decryption (bool) + +returns: +1. symmetric key id (string) +``` + +#### pss_sendSym + +Encrypts the message using the provided symmetric key, wraps it in an envelope containing the topic, and sends it to the network. + +``` +parameters: +1. symmetric key id (string) +2. topic (4 bytes in hex) +3. message (hex) + +returns: +none +``` + +### QUERY PEER KEYS + +#### pss_GetSymmetricAddressHint + +Return the swarm overlay address associated with the peer registered with the given symmetric key and topic combination. + +``` +parameters: +1. topic (4 bytes in hex) +2. symmetric key id (string) + +returns: +1. peer address (hex) +``` + +#### pss_GetAsymmetricAddressHint + +Return the swarm overlay address associated with the peer registered with the given symmetric key and topic combination. + +``` +parameters: +1. topic (4 bytes in hex) +2. public key in hex form (string) + +returns: +1. peer address (hex) +``` + +### HANDSHAKES + +Convenience implementation of Diffie-Hellman handshakes using ephemeral symmetric keys. Peers keep separate sets of keys for incoming and outgoing communications. + +*This functionality is an optional feature in `pss`. It is compiled in by default, but can be omitted by providing the `nopsshandshake` build tag.* + +#### pss_addHandshake + +Activate handshake functionality on the specified topic. + +``` +parameters: +1. topic (4 bytes in hex) + +returns: +none +``` + +#### pss_removeHandshake + +Remove handshake functionality on the specified topic. + +``` +parameters: +1. topic (4 bytes in hex) + +returns: +none +``` + +#### pss_handshake + +Instantiate handshake with peer, refreshing symmetric encryption keys. + +If parameter 3 is false, the returned array will be empty. + +``` +parameters: +1. public key of peer in hex format (string) +2. topic (4 bytes in hex) +3. block calls until keys are received (bool) +4. flush existing incoming keys (bool) + +returns: +1. list of symmetric keys (string[]) +``` + +#### pss_getHandshakeKeys + +Get valid symmetric encryption keys for a specified peer and topic. + +parameters: +1. public key of peer in hex format (string) +2. topic (4 bytes in hex) +3. include keys for incoming messages (bool) +4. include keys for outgoing messages (bool) + +returns: +1. list of symmetric keys (string[]) + +#### pss_getHandshakeKeyCapacity + +Get amount of remaining messages the specified key is valid for. + +``` +parameters: +1. symmetric key id (string) + +returns: +1. number of messages (uint16) +``` + +#### pss_getHandshakePublicKey + +Get the peer's public key associated with the specified symmetric key. + +``` +parameters: +1. symmetric key id (string) + +returns: +1. Associated public key in hex format (string) +``` + +#### pss_releaseHandshakeKey + +Invalidate the specified key. + +Normally, the key will be kept for a grace period to allow for decryption of delayed messages. If instant removal is set, this grace period is omitted, and the key removed instantaneously. + +``` +parameters: +1. public key of peer in hex format (string) +2. topic (4 bytes in hex) +3. symmetric key id to release (string) +4. remove keys instantly (bool) + +returns: +1. whether key was successfully removed (bool) +``` diff --git a/swarm/pss/api.go b/swarm/pss/api.go new file mode 100644 index 0000000000..eba7bb722c --- /dev/null +++ b/swarm/pss/api.go @@ -0,0 +1,169 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package pss + +import ( + "context" + "errors" + "fmt" + + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/p2p" + "github.com/ethereum/go-ethereum/rpc" + "github.com/ethereum/go-ethereum/swarm/log" +) + +// Wrapper for receiving pss messages when using the pss API +// providing access to sender of message +type APIMsg struct { + Msg hexutil.Bytes + Asymmetric bool + Key string +} + +// Additional public methods accessible through API for pss +type API struct { + *Pss +} + +func NewAPI(ps *Pss) *API { + return &API{Pss: ps} +} + +// Creates a new subscription for the caller. Enables external handling of incoming messages. +// +// A new handler is registered in pss for the supplied topic +// +// All incoming messages to the node matching this topic will be encapsulated in the APIMsg +// struct and sent to the subscriber +func (pssapi *API) Receive(ctx context.Context, topic Topic) (*rpc.Subscription, error) { + notifier, supported := rpc.NotifierFromContext(ctx) + if !supported { + return nil, fmt.Errorf("Subscribe not supported") + } + + psssub := notifier.CreateSubscription() + + handler := func(msg []byte, p *p2p.Peer, asymmetric bool, keyid string) error { + apimsg := &APIMsg{ + Msg: hexutil.Bytes(msg), + Asymmetric: asymmetric, + Key: keyid, + } + if err := notifier.Notify(psssub.ID, apimsg); err != nil { + log.Warn(fmt.Sprintf("notification on pss sub topic rpc (sub %v) msg %v failed!", psssub.ID, msg)) + } + return nil + } + + deregf := pssapi.Register(&topic, handler) + go func() { + defer deregf() + select { + case err := <-psssub.Err(): + log.Warn(fmt.Sprintf("caught subscription error in pss sub topic %x: %v", topic, err)) + case <-notifier.Closed(): + log.Warn(fmt.Sprintf("rpc sub notifier closed")) + } + }() + + return psssub, nil +} + +func (pssapi *API) GetAddress(topic Topic, asymmetric bool, key string) (PssAddress, error) { + var addr *PssAddress + if asymmetric { + peer, ok := pssapi.Pss.pubKeyPool[key][topic] + if !ok { + return nil, fmt.Errorf("pubkey/topic pair %x/%x doesn't exist", key, topic) + } + addr = peer.address + } else { + peer, ok := pssapi.Pss.symKeyPool[key][topic] + if !ok { + return nil, fmt.Errorf("symkey/topic pair %x/%x doesn't exist", key, topic) + } + addr = peer.address + + } + return *addr, nil +} + +// Retrieves the node's base address in hex form +func (pssapi *API) BaseAddr() (PssAddress, error) { + return PssAddress(pssapi.Pss.BaseAddr()), nil +} + +// Retrieves the node's public key in hex form +func (pssapi *API) GetPublicKey() (keybytes hexutil.Bytes) { + key := pssapi.Pss.PublicKey() + keybytes = crypto.FromECDSAPub(key) + return keybytes +} + +// Set Public key to associate with a particular Pss peer +func (pssapi *API) SetPeerPublicKey(pubkey hexutil.Bytes, topic Topic, addr PssAddress) error { + pk, err := crypto.UnmarshalPubkey(pubkey) + if err != nil { + return fmt.Errorf("Cannot unmarshal pubkey: %x", pubkey) + } + err = pssapi.Pss.SetPeerPublicKey(pk, topic, &addr) + if err != nil { + return fmt.Errorf("Invalid key: %x", pk) + } + return nil +} + +func (pssapi *API) GetSymmetricKey(symkeyid string) (hexutil.Bytes, error) { + symkey, err := pssapi.Pss.GetSymmetricKey(symkeyid) + return hexutil.Bytes(symkey), err +} + +func (pssapi *API) GetSymmetricAddressHint(topic Topic, symkeyid string) (PssAddress, error) { + return *pssapi.Pss.symKeyPool[symkeyid][topic].address, nil +} + +func (pssapi *API) GetAsymmetricAddressHint(topic Topic, pubkeyid string) (PssAddress, error) { + return *pssapi.Pss.pubKeyPool[pubkeyid][topic].address, nil +} + +func (pssapi *API) StringToTopic(topicstring string) (Topic, error) { + topicbytes := BytesToTopic([]byte(topicstring)) + if topicbytes == rawTopic { + return rawTopic, errors.New("Topic string hashes to 0x00000000 and cannot be used") + } + return topicbytes, nil +} + +func (pssapi *API) SendAsym(pubkeyhex string, topic Topic, msg hexutil.Bytes) error { + return pssapi.Pss.SendAsym(pubkeyhex, topic, msg[:]) +} + +func (pssapi *API) SendSym(symkeyhex string, topic Topic, msg hexutil.Bytes) error { + return pssapi.Pss.SendSym(symkeyhex, topic, msg[:]) +} + +func (pssapi *API) GetPeerTopics(pubkeyhex string) ([]Topic, error) { + topics, _, err := pssapi.Pss.GetPublickeyPeers(pubkeyhex) + return topics, err + +} + +func (pssapi *API) GetPeerAddress(pubkeyhex string, topic Topic) (PssAddress, error) { + return pssapi.Pss.getPeerAddress(pubkeyhex, topic) +} diff --git a/swarm/pss/client/client.go b/swarm/pss/client/client.go new file mode 100644 index 0000000000..532a223842 --- /dev/null +++ b/swarm/pss/client/client.go @@ -0,0 +1,354 @@ +// 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 . + +// +build !noclient,!noprotocol + +package client + +import ( + "context" + "errors" + "fmt" + "sync" + "time" + + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/p2p" + "github.com/ethereum/go-ethereum/p2p/discover" + "github.com/ethereum/go-ethereum/p2p/protocols" + "github.com/ethereum/go-ethereum/rlp" + "github.com/ethereum/go-ethereum/rpc" + "github.com/ethereum/go-ethereum/swarm/log" + "github.com/ethereum/go-ethereum/swarm/pss" +) + +const ( + handshakeRetryTimeout = 1000 + handshakeRetryCount = 3 +) + +// The pss client provides devp2p emulation over pss RPC API, +// giving access to pss methods from a different process +type Client struct { + BaseAddrHex string + + // peers + peerPool map[pss.Topic]map[string]*pssRPCRW + protos map[pss.Topic]*p2p.Protocol + + // rpc connections + rpc *rpc.Client + subs []*rpc.ClientSubscription + + // channels + topicsC chan []byte + quitC chan struct{} + + poolMu sync.Mutex +} + +// implements p2p.MsgReadWriter +type pssRPCRW struct { + *Client + topic string + msgC chan []byte + addr pss.PssAddress + pubKeyId string + lastSeen time.Time + closed bool +} + +func (c *Client) newpssRPCRW(pubkeyid string, addr pss.PssAddress, topicobj pss.Topic) (*pssRPCRW, error) { + topic := topicobj.String() + err := c.rpc.Call(nil, "pss_setPeerPublicKey", pubkeyid, topic, hexutil.Encode(addr[:])) + if err != nil { + return nil, fmt.Errorf("setpeer %s %s: %v", topic, pubkeyid, err) + } + return &pssRPCRW{ + Client: c, + topic: topic, + msgC: make(chan []byte), + addr: addr, + pubKeyId: pubkeyid, + }, nil +} + +func (rw *pssRPCRW) ReadMsg() (p2p.Msg, error) { + msg := <-rw.msgC + log.Trace("pssrpcrw read", "msg", msg) + pmsg, err := pss.ToP2pMsg(msg) + if err != nil { + return p2p.Msg{}, err + } + + return pmsg, nil +} + +// If only one message slot left +// then new is requested through handshake +// if buffer is empty, handshake request blocks until return +// after which pointer is changed to first new key in buffer +// will fail if: +// - any api calls fail +// - handshake retries are exhausted without reply, +// - send fails +func (rw *pssRPCRW) WriteMsg(msg p2p.Msg) error { + log.Trace("got writemsg pssclient", "msg", msg) + if rw.closed { + return fmt.Errorf("connection closed") + } + rlpdata := make([]byte, msg.Size) + msg.Payload.Read(rlpdata) + pmsg, err := rlp.EncodeToBytes(pss.ProtocolMsg{ + Code: msg.Code, + Size: msg.Size, + Payload: rlpdata, + }) + if err != nil { + return err + } + + // Get the keys we have + var symkeyids []string + err = rw.Client.rpc.Call(&symkeyids, "pss_getHandshakeKeys", rw.pubKeyId, rw.topic, false, true) + if err != nil { + return err + } + + // Check the capacity of the first key + var symkeycap uint16 + if len(symkeyids) > 0 { + err = rw.Client.rpc.Call(&symkeycap, "pss_getHandshakeKeyCapacity", symkeyids[0]) + if err != nil { + return err + } + } + + err = rw.Client.rpc.Call(nil, "pss_sendSym", symkeyids[0], rw.topic, hexutil.Encode(pmsg)) + if err != nil { + return err + } + + // If this is the last message it is valid for, initiate new handshake + if symkeycap == 1 { + var retries int + var sync bool + // if it's the only remaining key, make sure we don't continue until we have new ones for further writes + if len(symkeyids) == 1 { + sync = true + } + // initiate handshake + _, err := rw.handshake(retries, sync, false) + if err != nil { + log.Warn("failing", "err", err) + return err + } + } + return nil +} + +// retry and synchronicity wrapper for handshake api call +// returns first new symkeyid upon successful execution +func (rw *pssRPCRW) handshake(retries int, sync bool, flush bool) (string, error) { + + var symkeyids []string + var i int + // request new keys + // if the key buffer was depleted, make this as a blocking call and try several times before giving up + for i = 0; i < 1+retries; i++ { + log.Debug("handshake attempt pssrpcrw", "pubkeyid", rw.pubKeyId, "topic", rw.topic, "sync", sync) + err := rw.Client.rpc.Call(&symkeyids, "pss_handshake", rw.pubKeyId, rw.topic, sync, flush) + if err == nil { + var keyid string + if sync { + keyid = symkeyids[0] + } + return keyid, nil + } + if i-1+retries > 1 { + time.Sleep(time.Millisecond * handshakeRetryTimeout) + } + } + + return "", fmt.Errorf("handshake failed after %d attempts", i) +} + +// Custom constructor +// +// Provides direct access to the rpc object +func NewClient(rpcurl string) (*Client, error) { + rpcclient, err := rpc.Dial(rpcurl) + if err != nil { + return nil, err + } + + client, err := NewClientWithRPC(rpcclient) + if err != nil { + return nil, err + } + return client, nil +} + +// Main constructor +// +// The 'rpcclient' parameter allows passing a in-memory rpc client to act as the remote websocket RPC. +func NewClientWithRPC(rpcclient *rpc.Client) (*Client, error) { + client := newClient() + client.rpc = rpcclient + err := client.rpc.Call(&client.BaseAddrHex, "pss_baseAddr") + if err != nil { + return nil, fmt.Errorf("cannot get pss node baseaddress: %v", err) + } + return client, nil +} + +func newClient() (client *Client) { + client = &Client{ + quitC: make(chan struct{}), + peerPool: make(map[pss.Topic]map[string]*pssRPCRW), + protos: make(map[pss.Topic]*p2p.Protocol), + } + return +} + +// Mounts a new devp2p protcool on the pss connection +// +// the protocol is aliased as a "pss topic" +// uses normal devp2p send and incoming message handler routines from the p2p/protocols package +// +// when an incoming message is received from a peer that is not yet known to the client, +// this peer object is instantiated, and the protocol is run on it. +func (c *Client) RunProtocol(ctx context.Context, proto *p2p.Protocol) error { + topicobj := pss.BytesToTopic([]byte(fmt.Sprintf("%s:%d", proto.Name, proto.Version))) + topichex := topicobj.String() + msgC := make(chan pss.APIMsg) + c.peerPool[topicobj] = make(map[string]*pssRPCRW) + sub, err := c.rpc.Subscribe(ctx, "pss", msgC, "receive", topichex) + if err != nil { + return fmt.Errorf("pss event subscription failed: %v", err) + } + c.subs = append(c.subs, sub) + err = c.rpc.Call(nil, "pss_addHandshake", topichex) + if err != nil { + return fmt.Errorf("pss handshake activation failed: %v", err) + } + + // dispatch incoming messages + go func() { + for { + select { + case msg := <-msgC: + // we only allow sym msgs here + if msg.Asymmetric { + continue + } + // we get passed the symkeyid + // need the symkey itself to resolve to peer's pubkey + var pubkeyid string + err = c.rpc.Call(&pubkeyid, "pss_getHandshakePublicKey", msg.Key) + if err != nil || pubkeyid == "" { + log.Trace("proto err or no pubkey", "err", err, "symkeyid", msg.Key) + continue + } + // if we don't have the peer on this protocol already, create it + // this is more or less the same as AddPssPeer, less the handshake initiation + if c.peerPool[topicobj][pubkeyid] == nil { + var addrhex string + err := c.rpc.Call(&addrhex, "pss_getAddress", topichex, false, msg.Key) + if err != nil { + log.Trace(err.Error()) + continue + } + addrbytes, err := hexutil.Decode(addrhex) + if err != nil { + log.Trace(err.Error()) + break + } + addr := pss.PssAddress(addrbytes) + rw, err := c.newpssRPCRW(pubkeyid, addr, topicobj) + if err != nil { + break + } + c.peerPool[topicobj][pubkeyid] = rw + nid, _ := discover.HexID("0x00") + p := p2p.NewPeer(nid, fmt.Sprintf("%v", addr), []p2p.Cap{}) + go proto.Run(p, c.peerPool[topicobj][pubkeyid]) + } + go func() { + c.peerPool[topicobj][pubkeyid].msgC <- msg.Msg + }() + case <-c.quitC: + return + } + } + }() + + c.protos[topicobj] = proto + return nil +} + +// Always call this to ensure that we exit cleanly +func (c *Client) Close() error { + for _, s := range c.subs { + s.Unsubscribe() + } + return nil +} + +// Add a pss peer (public key) and run the protocol on it +// +// client.RunProtocol with matching topic must have been +// run prior to adding the peer, or this method will +// return an error. +// +// The key must exist in the key store of the pss node +// before the peer is added. The method will return an error +// if it is not. +func (c *Client) AddPssPeer(pubkeyid string, addr []byte, spec *protocols.Spec) error { + topic := pss.ProtocolTopic(spec) + if c.peerPool[topic] == nil { + return errors.New("addpeer on unset topic") + } + if c.peerPool[topic][pubkeyid] == nil { + rw, err := c.newpssRPCRW(pubkeyid, addr, topic) + if err != nil { + return err + } + _, err = rw.handshake(handshakeRetryCount, true, true) + if err != nil { + return err + } + c.poolMu.Lock() + c.peerPool[topic][pubkeyid] = rw + c.poolMu.Unlock() + nid, _ := discover.HexID("0x00") + p := p2p.NewPeer(nid, fmt.Sprintf("%v", addr), []p2p.Cap{}) + go c.protos[topic].Run(p, c.peerPool[topic][pubkeyid]) + } + return nil +} + +// Remove a pss peer +// +// TODO: underlying cleanup +func (c *Client) RemovePssPeer(pubkeyid string, spec *protocols.Spec) { + log.Debug("closing pss client peer", "pubkey", pubkeyid, "protoname", spec.Name, "protoversion", spec.Version) + c.poolMu.Lock() + defer c.poolMu.Unlock() + topic := pss.ProtocolTopic(spec) + c.peerPool[topic][pubkeyid].closed = true + delete(c.peerPool[topic], pubkeyid) +} diff --git a/swarm/pss/client/client_test.go b/swarm/pss/client/client_test.go new file mode 100644 index 0000000000..f360698778 --- /dev/null +++ b/swarm/pss/client/client_test.go @@ -0,0 +1,302 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package client + +import ( + "bytes" + "context" + "flag" + "fmt" + "math/rand" + "os" + "sync" + "testing" + "time" + + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/node" + "github.com/ethereum/go-ethereum/p2p" + "github.com/ethereum/go-ethereum/p2p/discover" + "github.com/ethereum/go-ethereum/p2p/simulations" + "github.com/ethereum/go-ethereum/p2p/simulations/adapters" + "github.com/ethereum/go-ethereum/rpc" + "github.com/ethereum/go-ethereum/swarm/network" + "github.com/ethereum/go-ethereum/swarm/pss" + "github.com/ethereum/go-ethereum/swarm/state" + whisper "github.com/ethereum/go-ethereum/whisper/whisperv5" +) + +type protoCtrl struct { + C chan bool + protocol *pss.Protocol + run func(*p2p.Peer, p2p.MsgReadWriter) error +} + +var ( + debugdebugflag = flag.Bool("vv", false, "veryverbose") + debugflag = flag.Bool("v", false, "verbose") + w *whisper.Whisper + wapi *whisper.PublicWhisperAPI + // custom logging + psslogmain log.Logger + pssprotocols map[string]*protoCtrl + sendLimit = uint16(256) +) + +var services = newServices() + +func init() { + flag.Parse() + rand.Seed(time.Now().Unix()) + + adapters.RegisterServices(services) + + loglevel := log.LvlInfo + if *debugflag { + loglevel = log.LvlDebug + } else if *debugdebugflag { + loglevel = log.LvlTrace + } + + psslogmain = log.New("psslog", "*") + hs := log.StreamHandler(os.Stderr, log.TerminalFormat(true)) + hf := log.LvlFilterHandler(loglevel, hs) + h := log.CallerFileHandler(hf) + log.Root().SetHandler(h) + + w = whisper.New(&whisper.DefaultConfig) + wapi = whisper.NewPublicWhisperAPI(w) + + pssprotocols = make(map[string]*protoCtrl) +} + +// ping pong exchange across one expired symkey +func TestClientHandshake(t *testing.T) { + sendLimit = 3 + + clients, err := setupNetwork(2) + if err != nil { + t.Fatal(err) + } + + lpsc, err := NewClientWithRPC(clients[0]) + if err != nil { + t.Fatal(err) + } + rpsc, err := NewClientWithRPC(clients[1]) + if err != nil { + t.Fatal(err) + } + lpssping := &pss.Ping{ + OutC: make(chan bool), + InC: make(chan bool), + Pong: false, + } + rpssping := &pss.Ping{ + OutC: make(chan bool), + InC: make(chan bool), + Pong: false, + } + lproto := pss.NewPingProtocol(lpssping) + rproto := pss.NewPingProtocol(rpssping) + + ctx, cancel := context.WithTimeout(context.Background(), time.Second*10) + defer cancel() + err = lpsc.RunProtocol(ctx, lproto) + if err != nil { + t.Fatal(err) + } + err = rpsc.RunProtocol(ctx, rproto) + if err != nil { + t.Fatal(err) + } + topic := pss.PingTopic.String() + + var loaddr string + err = clients[0].Call(&loaddr, "pss_baseAddr") + if err != nil { + t.Fatalf("rpc get node 1 baseaddr fail: %v", err) + } + var roaddr string + err = clients[1].Call(&roaddr, "pss_baseAddr") + if err != nil { + t.Fatalf("rpc get node 2 baseaddr fail: %v", err) + } + + var lpubkey string + err = clients[0].Call(&lpubkey, "pss_getPublicKey") + if err != nil { + t.Fatalf("rpc get node 1 pubkey fail: %v", err) + } + var rpubkey string + err = clients[1].Call(&rpubkey, "pss_getPublicKey") + if err != nil { + t.Fatalf("rpc get node 2 pubkey fail: %v", err) + } + + err = clients[0].Call(nil, "pss_setPeerPublicKey", rpubkey, topic, roaddr) + if err != nil { + t.Fatal(err) + } + err = clients[1].Call(nil, "pss_setPeerPublicKey", lpubkey, topic, loaddr) + if err != nil { + t.Fatal(err) + } + + time.Sleep(time.Second) + + roaddrbytes, err := hexutil.Decode(roaddr) + if err != nil { + t.Fatal(err) + } + err = lpsc.AddPssPeer(rpubkey, roaddrbytes, pss.PingProtocol) + if err != nil { + t.Fatal(err) + } + + time.Sleep(time.Second) + + for i := uint16(0); i <= sendLimit; i++ { + lpssping.OutC <- false + got := <-rpssping.InC + log.Warn("ok", "idx", i, "got", got) + time.Sleep(time.Second) + } + + rw := lpsc.peerPool[pss.PingTopic][rpubkey] + lpsc.RemovePssPeer(rpubkey, pss.PingProtocol) + if err := rw.WriteMsg(p2p.Msg{ + Size: 3, + Payload: bytes.NewReader([]byte("foo")), + }); err == nil { + t.Fatalf("expected error on write") + } +} + +func setupNetwork(numnodes int) (clients []*rpc.Client, err error) { + nodes := make([]*simulations.Node, numnodes) + clients = make([]*rpc.Client, numnodes) + if numnodes < 2 { + return nil, fmt.Errorf("Minimum two nodes in network") + } + adapter := adapters.NewSimAdapter(services) + net := simulations.NewNetwork(adapter, &simulations.NetworkConfig{ + ID: "0", + DefaultService: "bzz", + }) + for i := 0; i < numnodes; i++ { + nodeconf := adapters.RandomNodeConfig() + nodeconf.Services = []string{"bzz", "pss"} + nodes[i], err = net.NewNodeWithConfig(nodeconf) + if err != nil { + return nil, fmt.Errorf("error creating node 1: %v", err) + } + err = net.Start(nodes[i].ID()) + if err != nil { + return nil, fmt.Errorf("error starting node 1: %v", err) + } + if i > 0 { + err = net.Connect(nodes[i].ID(), nodes[i-1].ID()) + if err != nil { + return nil, fmt.Errorf("error connecting nodes: %v", err) + } + } + clients[i], err = nodes[i].Client() + if err != nil { + return nil, fmt.Errorf("create node 1 rpc client fail: %v", err) + } + } + if numnodes > 2 { + err = net.Connect(nodes[0].ID(), nodes[len(nodes)-1].ID()) + if err != nil { + return nil, fmt.Errorf("error connecting first and last nodes") + } + } + return clients, nil +} + +func newServices() adapters.Services { + stateStore := state.NewInmemoryStore() + kademlias := make(map[discover.NodeID]*network.Kademlia) + kademlia := func(id discover.NodeID) *network.Kademlia { + if k, ok := kademlias[id]; ok { + return k + } + addr := network.NewAddrFromNodeID(id) + params := network.NewKadParams() + params.MinProxBinSize = 2 + params.MaxBinSize = 3 + params.MinBinSize = 1 + params.MaxRetries = 1000 + params.RetryExponent = 2 + params.RetryInterval = 1000000 + kademlias[id] = network.NewKademlia(addr.Over(), params) + return kademlias[id] + } + return adapters.Services{ + "pss": func(ctx *adapters.ServiceContext) (node.Service, error) { + ctxlocal, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + keys, err := wapi.NewKeyPair(ctxlocal) + privkey, err := w.GetPrivateKey(keys) + psparams := pss.NewPssParams().WithPrivateKey(privkey) + pskad := kademlia(ctx.Config.ID) + ps, err := pss.NewPss(pskad, psparams) + if err != nil { + return nil, err + } + pshparams := pss.NewHandshakeParams() + pshparams.SymKeySendLimit = sendLimit + err = pss.SetHandshakeController(ps, pshparams) + if err != nil { + return nil, fmt.Errorf("handshake controller fail: %v", err) + } + return ps, nil + }, + "bzz": func(ctx *adapters.ServiceContext) (node.Service, error) { + addr := network.NewAddrFromNodeID(ctx.Config.ID) + hp := network.NewHiveParams() + hp.Discovery = false + config := &network.BzzConfig{ + OverlayAddr: addr.Over(), + UnderlayAddr: addr.Under(), + HiveParams: hp, + } + return network.NewBzz(config, kademlia(ctx.Config.ID), stateStore, nil, nil), nil + }, + } +} + +// copied from swarm/network/protocol_test_go +type testStore struct { + sync.Mutex + + values map[string][]byte +} + +func newTestStore() *testStore { + return &testStore{values: make(map[string][]byte)} +} + +func (t *testStore) Load(key string) ([]byte, error) { + return nil, nil +} + +func (t *testStore) Save(key string, v []byte) error { + return nil +} diff --git a/swarm/pss/client/doc.go b/swarm/pss/client/doc.go new file mode 100644 index 0000000000..080af45a9a --- /dev/null +++ b/swarm/pss/client/doc.go @@ -0,0 +1,96 @@ +// 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 . + +// simple abstraction for implementing pss functionality +// +// the pss client library aims to simplify usage of the p2p.protocols package over pss +// +// IO is performed using the ordinary p2p.MsgReadWriter interface, which transparently communicates with a pss node via RPC using websockets as transport layer, using methods in the PssAPI class in the swarm/pss package +// +// +// Minimal-ish usage example (requires a running pss node with websocket RPC): +// +// +// import ( +// "context" +// "fmt" +// "os" +// pss "github.com/ethereum/go-ethereum/swarm/pss/client" +// "github.com/ethereum/go-ethereum/p2p/protocols" +// "github.com/ethereum/go-ethereum/p2p" +// "github.com/ethereum/go-ethereum/swarm/pot" +// "github.com/ethereum/go-ethereum/swarm/log" +// ) +// +// type FooMsg struct { +// Bar int +// } +// +// +// func fooHandler (msg interface{}) error { +// foomsg, ok := msg.(*FooMsg) +// if ok { +// log.Debug("Yay, just got a message", "msg", foomsg) +// } +// return errors.New(fmt.Sprintf("Unknown message")) +// } +// +// spec := &protocols.Spec{ +// Name: "foo", +// Version: 1, +// MaxMsgSize: 1024, +// Messages: []interface{}{ +// FooMsg{}, +// }, +// } +// +// proto := &p2p.Protocol{ +// Name: spec.Name, +// Version: spec.Version, +// Length: uint64(len(spec.Messages)), +// Run: func(p *p2p.Peer, rw p2p.MsgReadWriter) error { +// pp := protocols.NewPeer(p, rw, spec) +// return pp.Run(fooHandler) +// }, +// } +// +// func implementation() { +// cfg := pss.NewClientConfig() +// psc := pss.NewClient(context.Background(), nil, cfg) +// err := psc.Start() +// if err != nil { +// log.Crit("can't start pss client") +// os.Exit(1) +// } +// +// log.Debug("connected to pss node", "bzz addr", psc.BaseAddr) +// +// err = psc.RunProtocol(proto) +// if err != nil { +// log.Crit("can't start protocol on pss websocket") +// os.Exit(1) +// } +// +// addr := pot.RandomAddress() // should be a real address, of course +// psc.AddPssPeer(addr, spec) +// +// // use the protocol for something +// +// psc.Stop() +// } +// +// BUG(test): TestIncoming test times out due to deadlock issues in the swarm hive +package client diff --git a/swarm/pss/doc.go b/swarm/pss/doc.go new file mode 100644 index 0000000000..462c82aaad --- /dev/null +++ b/swarm/pss/doc.go @@ -0,0 +1,61 @@ +// 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 . + +// Pss provides devp2p functionality for swarm nodes without the need for a direct tcp connection between them. +// +// Messages are encapsulated in a devp2p message structure `PssMsg`. These capsules are forwarded from node to node using ordinary tcp devp2p until it reaches its destination: The node or nodes who can successfully decrypt the message. +// +// Routing of messages is done using swarm's own kademlia routing. Optionally routing can be turned off, forcing the message to be sent to all peers, similar to the behavior of the whisper protocol. +// +// Pss is intended for messages of limited size, typically a couple of Kbytes at most. The messages themselves can be anything at all; complex data structures or non-descript byte sequences. +// +// Documentation can be found in the README file. +// +// For the current state and roadmap of pss development please see https://github.com/ethersphere/swarm/wiki/swarm-dev-progress. +// +// Please report issues on https://github.com/ethersphere/go-ethereum +// +// Feel free to ask questions in https://gitter.im/ethersphere/pss +// +// TOPICS +// +// An encrypted envelope of a pss messages always contains a Topic. This is pss' way of determining what action to take on the message. The topic is only visible for the node(s) who can decrypt the message. +// +// This "topic" is not like the subject of an email message, but a hash-like arbitrary 4 byte value. A valid topic can be generated using the `pss_*ToTopic` API methods. +// +// IDENTITY IN PSS +// +// Pss aims to achieve perfect darkness. That means that the minimum requirement for two nodes to communicate using pss is a shared secret. This secret can be an arbitrary byte slice, or a ECDSA keypair. +// +// Peer keys can manually be added to the pss node through its API calls `pss_setPeerPublicKey` and `pss_setSymmetricKey`. Keys are always coupled with a topic, and the keys will only be valid for these topics. +// +// CONNECTIONS +// +// A "connection" in pss is a purely virtual construct. There is no mechanisms in place to ensure that the remote peer actually is there. In fact, "adding" a peer involves merely the node's opinion that the peer is there. It may issue messages to that remote peer to a directly connected peer, which in turn passes it on. But if it is not present on the network - or if there is no route to it - the message will never reach its destination through mere forwarding. +// +// When implementing the devp2p protocol stack, the "adding" of a remote peer is a prerequisite for the side actually initiating the protocol communication. Adding a peer in effect "runs" the protocol on that peer, and adds an internal mapping between a topic and that peer. It also enables sending and receiving messages using the main io-construct in devp2p - the p2p.MsgReadWriter. +// +// Under the hood, pss implements its own MsgReadWriter, which bridges MsgReadWriter.WriteMsg with Pss.SendRaw, and deftly adds an InjectMsg method which pipes incoming messages to appear on the MsgReadWriter.ReadMsg channel. +// +// An incoming connection is nothing more than an actual PssMsg appearing with a certain Topic. If a Handler har been registered to that Topic, the message will be passed to it. This constitutes a "new" connection if: +// +// - The pss node never called AddPeer with this combination of remote peer address and topic, and +// +// - The pss node never received a PssMsg from this remote peer with this specific Topic before. +// +// If it is a "new" connection, the protocol will be "run" on the remote peer, in the same manner as if it was pre-emptively added. +// +package pss diff --git a/swarm/pss/handshake.go b/swarm/pss/handshake.go new file mode 100644 index 0000000000..e3ead77d04 --- /dev/null +++ b/swarm/pss/handshake.go @@ -0,0 +1,568 @@ +// 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 . + +// +build !nopsshandshake + +package pss + +import ( + "context" + "errors" + "fmt" + "sync" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/p2p" + "github.com/ethereum/go-ethereum/rlp" + "github.com/ethereum/go-ethereum/rpc" + "github.com/ethereum/go-ethereum/swarm/log" +) + +const ( + IsActiveHandshake = true +) + +var ( + ctrlSingleton *HandshakeController +) + +const ( + defaultSymKeyRequestTimeout = 1000 * 8 // max wait ms to receive a response to a handshake symkey request + defaultSymKeyExpiryTimeout = 1000 * 10 // ms to wait before allowing garbage collection of an expired symkey + defaultSymKeySendLimit = 256 // amount of messages a symkey is valid for + defaultSymKeyCapacity = 4 // max number of symkeys to store/send simultaneously +) + +// symmetric key exchange message payload +type handshakeMsg struct { + From []byte + Limit uint16 + Keys [][]byte + Request uint8 + Topic Topic +} + +// internal representation of an individual symmetric key +type handshakeKey struct { + symKeyID *string + pubKeyID *string + limit uint16 + count uint16 + expiredAt time.Time +} + +// container for all in- and outgoing keys +// for one particular peer (public key) and topic +type handshake struct { + outKeys []handshakeKey + inKeys []handshakeKey +} + +// Initialization parameters for the HandshakeController +// +// SymKeyRequestExpiry: Timeout for waiting for a handshake reply +// (default 8000 ms) +// +// SymKeySendLimit: Amount of messages symmetric keys issues by +// this node is valid for (default 256) +// +// SymKeyCapacity: Ideal (and maximum) amount of symmetric keys +// held per direction per peer (default 4) +type HandshakeParams struct { + SymKeyRequestTimeout time.Duration + SymKeyExpiryTimeout time.Duration + SymKeySendLimit uint16 + SymKeyCapacity uint8 +} + +// Sane defaults for HandshakeController initialization +func NewHandshakeParams() *HandshakeParams { + return &HandshakeParams{ + SymKeyRequestTimeout: defaultSymKeyRequestTimeout * time.Millisecond, + SymKeyExpiryTimeout: defaultSymKeyExpiryTimeout * time.Millisecond, + SymKeySendLimit: defaultSymKeySendLimit, + SymKeyCapacity: defaultSymKeyCapacity, + } +} + +// Singleton object enabling semi-automatic Diffie-Hellman +// exchange of ephemeral symmetric keys +type HandshakeController struct { + pss *Pss + keyC map[string]chan []string // adds a channel to report when a handshake succeeds + lock sync.Mutex + symKeyRequestTimeout time.Duration + symKeyExpiryTimeout time.Duration + symKeySendLimit uint16 + symKeyCapacity uint8 + symKeyIndex map[string]*handshakeKey + handshakes map[string]map[Topic]*handshake + deregisterFuncs map[Topic]func() +} + +// Attach HandshakeController to pss node +// +// Must be called before starting the pss node service +func SetHandshakeController(pss *Pss, params *HandshakeParams) error { + ctrl := &HandshakeController{ + pss: pss, + keyC: make(map[string]chan []string), + symKeyRequestTimeout: params.SymKeyRequestTimeout, + symKeyExpiryTimeout: params.SymKeyExpiryTimeout, + symKeySendLimit: params.SymKeySendLimit, + symKeyCapacity: params.SymKeyCapacity, + symKeyIndex: make(map[string]*handshakeKey), + handshakes: make(map[string]map[Topic]*handshake), + deregisterFuncs: make(map[Topic]func()), + } + api := &HandshakeAPI{ + namespace: "pss", + ctrl: ctrl, + } + pss.addAPI(rpc.API{ + Namespace: api.namespace, + Version: "0.2", + Service: api, + Public: true, + }) + ctrlSingleton = ctrl + return nil +} + +// Return all unexpired symmetric keys from store by +// peer (public key), topic and specified direction +func (ctl *HandshakeController) validKeys(pubkeyid string, topic *Topic, in bool) (validkeys []*string) { + ctl.lock.Lock() + defer ctl.lock.Unlock() + now := time.Now() + if _, ok := ctl.handshakes[pubkeyid]; !ok { + return []*string{} + } else if _, ok := ctl.handshakes[pubkeyid][*topic]; !ok { + return []*string{} + } + var keystore *[]handshakeKey + if in { + keystore = &(ctl.handshakes[pubkeyid][*topic].inKeys) + } else { + keystore = &(ctl.handshakes[pubkeyid][*topic].outKeys) + } + + for _, key := range *keystore { + if key.limit <= key.count { + ctl.releaseKey(*key.symKeyID, topic) + } else if !key.expiredAt.IsZero() && key.expiredAt.Before(now) { + ctl.releaseKey(*key.symKeyID, topic) + } else { + validkeys = append(validkeys, key.symKeyID) + } + } + return +} + +// Add all given symmetric keys with validity limits to store by +// peer (public key), topic and specified direction +func (ctl *HandshakeController) updateKeys(pubkeyid string, topic *Topic, in bool, symkeyids []string, limit uint16) { + ctl.lock.Lock() + defer ctl.lock.Unlock() + if _, ok := ctl.handshakes[pubkeyid]; !ok { + ctl.handshakes[pubkeyid] = make(map[Topic]*handshake) + + } + if ctl.handshakes[pubkeyid][*topic] == nil { + ctl.handshakes[pubkeyid][*topic] = &handshake{} + } + var keystore *[]handshakeKey + expire := time.Now() + if in { + keystore = &(ctl.handshakes[pubkeyid][*topic].inKeys) + } else { + keystore = &(ctl.handshakes[pubkeyid][*topic].outKeys) + expire = expire.Add(time.Millisecond * ctl.symKeyExpiryTimeout) + } + for _, storekey := range *keystore { + storekey.expiredAt = expire + } + for i := 0; i < len(symkeyids); i++ { + storekey := handshakeKey{ + symKeyID: &symkeyids[i], + pubKeyID: &pubkeyid, + limit: limit, + } + *keystore = append(*keystore, storekey) + ctl.pss.symKeyPool[*storekey.symKeyID][*topic].protected = true + } + for i := 0; i < len(*keystore); i++ { + ctl.symKeyIndex[*(*keystore)[i].symKeyID] = &((*keystore)[i]) + } +} + +// Expire a symmetric key, making it elegible for garbage collection +func (ctl *HandshakeController) releaseKey(symkeyid string, topic *Topic) bool { + if ctl.symKeyIndex[symkeyid] == nil { + log.Debug("no symkey", "symkeyid", symkeyid) + return false + } + ctl.symKeyIndex[symkeyid].expiredAt = time.Now() + log.Debug("handshake release", "symkeyid", symkeyid) + return true +} + +// Checks all symmetric keys in given direction(s) by +// specified peer (public key) and topic for expiry. +// Expired means: +// - expiry timestamp is set, and grace period is exceeded +// - message validity limit is reached +func (ctl *HandshakeController) cleanHandshake(pubkeyid string, topic *Topic, in bool, out bool) int { + ctl.lock.Lock() + defer ctl.lock.Unlock() + var deletecount int + var deletes []string + now := time.Now() + handshake := ctl.handshakes[pubkeyid][*topic] + log.Debug("handshake clean", "pubkey", pubkeyid, "topic", topic) + if in { + for i, key := range handshake.inKeys { + if key.expiredAt.Before(now) || (key.expiredAt.IsZero() && key.limit <= key.count) { + log.Trace("handshake in clean remove", "symkeyid", *key.symKeyID) + deletes = append(deletes, *key.symKeyID) + handshake.inKeys[deletecount] = handshake.inKeys[i] + deletecount++ + } + } + handshake.inKeys = handshake.inKeys[:len(handshake.inKeys)-deletecount] + } + if out { + deletecount = 0 + for i, key := range handshake.outKeys { + if key.expiredAt.Before(now) && (key.expiredAt.IsZero() && key.limit <= key.count) { + log.Trace("handshake out clean remove", "symkeyid", *key.symKeyID) + deletes = append(deletes, *key.symKeyID) + handshake.outKeys[deletecount] = handshake.outKeys[i] + deletecount++ + } + } + handshake.outKeys = handshake.outKeys[:len(handshake.outKeys)-deletecount] + } + for _, keyid := range deletes { + delete(ctl.symKeyIndex, keyid) + ctl.pss.symKeyPool[keyid][*topic].protected = false + } + return len(deletes) +} + +// Runs cleanHandshake() on all peers and topics +func (ctl *HandshakeController) clean() { + peerpubkeys := ctl.handshakes + for pubkeyid, peertopics := range peerpubkeys { + for topic := range peertopics { + ctl.cleanHandshake(pubkeyid, &topic, true, true) + } + } +} + +// Passed as a PssMsg handler for the topic handshake is activated on +// Handles incoming key exchange messages and +// ccunts message usage by symmetric key (expiry limit control) +// Only returns error if key handler fails +func (ctl *HandshakeController) handler(msg []byte, p *p2p.Peer, asymmetric bool, symkeyid string) error { + if !asymmetric { + if ctl.symKeyIndex[symkeyid] != nil { + if ctl.symKeyIndex[symkeyid].count >= ctl.symKeyIndex[symkeyid].limit { + return fmt.Errorf("discarding message using expired key: %s", symkeyid) + } + ctl.symKeyIndex[symkeyid].count++ + log.Trace("increment symkey recv use", "symsymkeyid", symkeyid, "count", ctl.symKeyIndex[symkeyid].count, "limit", ctl.symKeyIndex[symkeyid].limit, "receiver", common.ToHex(crypto.FromECDSAPub(ctl.pss.PublicKey()))) + } + return nil + } + keymsg := &handshakeMsg{} + err := rlp.DecodeBytes(msg, keymsg) + if err == nil { + err := ctl.handleKeys(symkeyid, keymsg) + if err != nil { + log.Error("handlekeys fail", "error", err) + } + return err + } + return nil +} + +// Handle incoming key exchange message +// Add keys received from peer to store +// and enerate and send the amount of keys requested by peer +// +// TODO: +// - flood guard +// - keylength check +// - update address hint if: +// 1) leftmost bytes in new address do not match stored +// 2) else, if new address is longer +func (ctl *HandshakeController) handleKeys(pubkeyid string, keymsg *handshakeMsg) error { + // new keys from peer + if len(keymsg.Keys) > 0 { + log.Debug("received handshake keys", "pubkeyid", pubkeyid, "from", keymsg.From, "count", len(keymsg.Keys)) + var sendsymkeyids []string + for _, key := range keymsg.Keys { + sendsymkey := make([]byte, len(key)) + copy(sendsymkey, key) + var address PssAddress + copy(address[:], keymsg.From) + sendsymkeyid, err := ctl.pss.setSymmetricKey(sendsymkey, keymsg.Topic, &address, false, false) + if err != nil { + return err + } + sendsymkeyids = append(sendsymkeyids, sendsymkeyid) + } + if len(sendsymkeyids) > 0 { + ctl.updateKeys(pubkeyid, &keymsg.Topic, false, sendsymkeyids, keymsg.Limit) + + ctl.alertHandshake(pubkeyid, sendsymkeyids) + } + } + + // peer request for keys + if keymsg.Request > 0 { + _, err := ctl.sendKey(pubkeyid, &keymsg.Topic, keymsg.Request) + if err != nil { + return err + } + } + + return nil +} + +// Send key exchange to peer (public key) valid for `topic` +// Will send number of keys specified by `keycount` with +// validity limits specified in `msglimit` +// If number of valid outgoing keys is less than the ideal/max +// amount, a request is sent for the amount of keys to make up +// the difference +func (ctl *HandshakeController) sendKey(pubkeyid string, topic *Topic, keycount uint8) ([]string, error) { + + var requestcount uint8 + to := &PssAddress{} + if _, ok := ctl.pss.pubKeyPool[pubkeyid]; !ok { + return []string{}, errors.New("Invalid public key") + } else if psp, ok := ctl.pss.pubKeyPool[pubkeyid][*topic]; ok { + to = psp.address + } + + recvkeys := make([][]byte, keycount) + recvkeyids := make([]string, keycount) + ctl.lock.Lock() + if _, ok := ctl.handshakes[pubkeyid]; !ok { + ctl.handshakes[pubkeyid] = make(map[Topic]*handshake) + } + ctl.lock.Unlock() + + // check if buffer is not full + outkeys := ctl.validKeys(pubkeyid, topic, false) + if len(outkeys) < int(ctl.symKeyCapacity) { + //requestcount = uint8(self.symKeyCapacity - uint8(len(outkeys))) + requestcount = ctl.symKeyCapacity + } + // return if there's nothing to be accomplished + if requestcount == 0 && keycount == 0 { + return []string{}, nil + } + + // generate new keys to send + for i := 0; i < len(recvkeyids); i++ { + var err error + recvkeyids[i], err = ctl.pss.GenerateSymmetricKey(*topic, to, true) + if err != nil { + return []string{}, fmt.Errorf("set receive symkey fail (pubkey %x topic %x): %v", pubkeyid, topic, err) + } + recvkeys[i], err = ctl.pss.GetSymmetricKey(recvkeyids[i]) + if err != nil { + return []string{}, fmt.Errorf("GET Generated outgoing symkey fail (pubkey %x topic %x): %v", pubkeyid, topic, err) + } + } + ctl.updateKeys(pubkeyid, topic, true, recvkeyids, ctl.symKeySendLimit) + + // encode and send the message + recvkeymsg := &handshakeMsg{ + From: ctl.pss.BaseAddr(), + Keys: recvkeys, + Request: requestcount, + Limit: ctl.symKeySendLimit, + Topic: *topic, + } + log.Debug("sending our symkeys", "pubkey", pubkeyid, "symkeys", recvkeyids, "limit", ctl.symKeySendLimit, "requestcount", requestcount, "keycount", len(recvkeys)) + recvkeybytes, err := rlp.EncodeToBytes(recvkeymsg) + if err != nil { + return []string{}, fmt.Errorf("rlp keymsg encode fail: %v", err) + } + // if the send fails it means this public key is not registered for this particular address AND topic + err = ctl.pss.SendAsym(pubkeyid, *topic, recvkeybytes) + if err != nil { + return []string{}, fmt.Errorf("Send symkey failed: %v", err) + } + return recvkeyids, nil +} + +// Enables callback for keys received from a key exchange request +func (ctl *HandshakeController) alertHandshake(pubkeyid string, symkeys []string) chan []string { + if len(symkeys) > 0 { + if _, ok := ctl.keyC[pubkeyid]; ok { + ctl.keyC[pubkeyid] <- symkeys + close(ctl.keyC[pubkeyid]) + delete(ctl.keyC, pubkeyid) + } + return nil + } + if _, ok := ctl.keyC[pubkeyid]; !ok { + ctl.keyC[pubkeyid] = make(chan []string) + } + return ctl.keyC[pubkeyid] +} + +type HandshakeAPI struct { + namespace string + ctrl *HandshakeController +} + +// Initiate a handshake session for a peer (public key) and topic +// combination. +// +// If `sync` is set, the call will block until keys are received from peer, +// or if the handshake request times out +// +// If `flush` is set, the max amount of keys will be sent to the peer +// regardless of how many valid keys that currently exist in the store. +// +// Returns list of symmetric key ids that can be passed to pss.GetSymmetricKey() +// for retrieval of the symmetric key bytes themselves. +// +// Fails if the incoming symmetric key store is already full (and `flush` is false), +// or if the underlying key dispatcher fails +func (api *HandshakeAPI) Handshake(pubkeyid string, topic Topic, sync bool, flush bool) (keys []string, err error) { + var hsc chan []string + var keycount uint8 + if flush { + keycount = api.ctrl.symKeyCapacity + } else { + validkeys := api.ctrl.validKeys(pubkeyid, &topic, false) + keycount = api.ctrl.symKeyCapacity - uint8(len(validkeys)) + } + if keycount == 0 { + return keys, errors.New("Incoming symmetric key store is already full") + } + if sync { + hsc = api.ctrl.alertHandshake(pubkeyid, []string{}) + } + _, err = api.ctrl.sendKey(pubkeyid, &topic, keycount) + if err != nil { + return keys, err + } + if sync { + ctx, cancel := context.WithTimeout(context.Background(), api.ctrl.symKeyRequestTimeout) + defer cancel() + select { + case keys = <-hsc: + log.Trace("sync handshake response receive", "key", keys) + case <-ctx.Done(): + return []string{}, errors.New("timeout") + } + } + return keys, nil +} + +// Activate handshake functionality on a topic +func (api *HandshakeAPI) AddHandshake(topic Topic) error { + api.ctrl.deregisterFuncs[topic] = api.ctrl.pss.Register(&topic, api.ctrl.handler) + return nil +} + +// Deactivate handshake functionality on a topic +func (api *HandshakeAPI) RemoveHandshake(topic *Topic) error { + if _, ok := api.ctrl.deregisterFuncs[*topic]; ok { + api.ctrl.deregisterFuncs[*topic]() + } + return nil +} + +// Returns all valid symmetric keys in store per peer (public key) +// and topic. +// +// The `in` and `out` parameters indicate for which direction(s) +// symmetric keys will be returned. +// If both are false, no keys (and no error) will be returned. +func (api *HandshakeAPI) GetHandshakeKeys(pubkeyid string, topic Topic, in bool, out bool) (keys []string, err error) { + if in { + for _, inkey := range api.ctrl.validKeys(pubkeyid, &topic, true) { + keys = append(keys, *inkey) + } + } + if out { + for _, outkey := range api.ctrl.validKeys(pubkeyid, &topic, false) { + keys = append(keys, *outkey) + } + } + return keys, nil +} + +// Returns the amount of messages the specified symmetric key +// is still valid for under the handshake scheme +func (api *HandshakeAPI) GetHandshakeKeyCapacity(symkeyid string) (uint16, error) { + storekey := api.ctrl.symKeyIndex[symkeyid] + if storekey == nil { + return 0, fmt.Errorf("invalid symkey id %s", symkeyid) + } + return storekey.limit - storekey.count, nil +} + +// Returns the byte representation of the public key in ascii hex +// associated with the given symmetric key +func (api *HandshakeAPI) GetHandshakePublicKey(symkeyid string) (string, error) { + storekey := api.ctrl.symKeyIndex[symkeyid] + if storekey == nil { + return "", fmt.Errorf("invalid symkey id %s", symkeyid) + } + return *storekey.pubKeyID, nil +} + +// Manually expire the given symkey +// +// If `flush` is set, garbage collection will be performed before returning. +// +// Returns true on successful removal, false otherwise +func (api *HandshakeAPI) ReleaseHandshakeKey(pubkeyid string, topic Topic, symkeyid string, flush bool) (removed bool, err error) { + removed = api.ctrl.releaseKey(symkeyid, &topic) + if removed && flush { + api.ctrl.cleanHandshake(pubkeyid, &topic, true, true) + } + return +} + +// Send symmetric message under the handshake scheme +// +// Overloads the pss.SendSym() API call, adding symmetric key usage count +// for message expiry control +func (api *HandshakeAPI) SendSym(symkeyid string, topic Topic, msg hexutil.Bytes) (err error) { + err = api.ctrl.pss.SendSym(symkeyid, topic, msg[:]) + if api.ctrl.symKeyIndex[symkeyid] != nil { + if api.ctrl.symKeyIndex[symkeyid].count >= api.ctrl.symKeyIndex[symkeyid].limit { + return errors.New("attempted send with expired key") + } + api.ctrl.symKeyIndex[symkeyid].count++ + log.Trace("increment symkey send use", "symkeyid", symkeyid, "count", api.ctrl.symKeyIndex[symkeyid].count, "limit", api.ctrl.symKeyIndex[symkeyid].limit, "receiver", common.ToHex(crypto.FromECDSAPub(api.ctrl.pss.PublicKey()))) + } + return +} diff --git a/swarm/pss/handshake_none.go b/swarm/pss/handshake_none.go new file mode 100644 index 0000000000..a09674be39 --- /dev/null +++ b/swarm/pss/handshake_none.go @@ -0,0 +1,27 @@ +// 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 . + +// +build nopsshandshake + +package pss + +const ( + IsActiveHandshake = false +) + +func NewHandshakeParams() interface{} { + return nil +} diff --git a/swarm/pss/handshake_test.go b/swarm/pss/handshake_test.go new file mode 100644 index 0000000000..0fc7e798ff --- /dev/null +++ b/swarm/pss/handshake_test.go @@ -0,0 +1,266 @@ +// 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 . + +// +build foo + +package pss + +import ( + "strconv" + "strings" + "testing" + "time" + + "github.com/ethereum/go-ethereum/swarm/log" +) + +// asymmetrical key exchange between two directly connected peers +// full address, partial address (8 bytes) and empty address +func TestHandshake(t *testing.T) { + t.Run("32", testHandshake) + t.Run("8", testHandshake) + t.Run("0", testHandshake) +} + +func testHandshake(t *testing.T) { + + // how much of the address we will use + useHandshake = true + var addrsize int64 + var err error + addrsizestring := strings.Split(t.Name(), "/") + addrsize, _ = strconv.ParseInt(addrsizestring[1], 10, 0) + + // set up two nodes directly connected + // (we are not testing pss routing here) + clients, err := setupNetwork(2) + if err != nil { + t.Fatal(err) + } + + var topic string + err = clients[0].Call(&topic, "pss_stringToTopic", "foo:42") + if err != nil { + t.Fatal(err) + } + + var loaddr string + err = clients[0].Call(&loaddr, "pss_baseAddr") + if err != nil { + t.Fatalf("rpc get node 1 baseaddr fail: %v", err) + } + // "0x" = 2 bytes + addrsize address bytes which in hex is 2x length + loaddr = loaddr[:2+(addrsize*2)] + var roaddr string + err = clients[1].Call(&roaddr, "pss_baseAddr") + if err != nil { + t.Fatalf("rpc get node 2 baseaddr fail: %v", err) + } + roaddr = roaddr[:2+(addrsize*2)] + log.Debug("addresses", "left", loaddr, "right", roaddr) + + // retrieve public key from pss instance + // set this public key reciprocally + var lpubkey string + err = clients[0].Call(&lpubkey, "pss_getPublicKey") + if err != nil { + t.Fatalf("rpc get node 1 pubkey fail: %v", err) + } + var rpubkey string + err = clients[1].Call(&rpubkey, "pss_getPublicKey") + if err != nil { + t.Fatalf("rpc get node 2 pubkey fail: %v", err) + } + + time.Sleep(time.Millisecond * 1000) // replace with hive healthy code + + // give each node its peer's public key + err = clients[0].Call(nil, "pss_setPeerPublicKey", rpubkey, topic, roaddr) + if err != nil { + t.Fatal(err) + } + err = clients[1].Call(nil, "pss_setPeerPublicKey", lpubkey, topic, loaddr) + if err != nil { + t.Fatal(err) + } + + // perform the handshake + // after this each side will have defaultSymKeyBufferCapacity symkeys each for in- and outgoing messages: + // L -> request 4 keys -> R + // L <- send 4 keys, request 4 keys <- R + // L -> send 4 keys -> R + // the call will fill the array with symkeys L needs for sending to R + err = clients[0].Call(nil, "pss_addHandshake", topic) + if err != nil { + t.Fatal(err) + } + err = clients[1].Call(nil, "pss_addHandshake", topic) + if err != nil { + t.Fatal(err) + } + + var lhsendsymkeyids []string + err = clients[0].Call(&lhsendsymkeyids, "pss_handshake", rpubkey, topic, true, true) + if err != nil { + t.Fatal(err) + } + + // make sure the r-node gets its keys + time.Sleep(time.Second) + + // check if we have 6 outgoing keys stored, and they match what was received from R + var lsendsymkeyids []string + err = clients[0].Call(&lsendsymkeyids, "pss_getHandshakeKeys", rpubkey, topic, false, true) + if err != nil { + t.Fatal(err) + } + m := 0 + for _, hid := range lhsendsymkeyids { + for _, lid := range lsendsymkeyids { + if lid == hid { + m++ + } + } + } + if m != defaultSymKeyCapacity { + t.Fatalf("buffer size mismatch, expected %d, have %d: %v", defaultSymKeyCapacity, m, lsendsymkeyids) + } + + // check if in- and outgoing keys on l-node and r-node match up and are in opposite categories (l recv = r send, l send = r recv) + var rsendsymkeyids []string + err = clients[1].Call(&rsendsymkeyids, "pss_getHandshakeKeys", lpubkey, topic, false, true) + if err != nil { + t.Fatal(err) + } + var lrecvsymkeyids []string + err = clients[0].Call(&lrecvsymkeyids, "pss_getHandshakeKeys", rpubkey, topic, true, false) + if err != nil { + t.Fatal(err) + } + var rrecvsymkeyids []string + err = clients[1].Call(&rrecvsymkeyids, "pss_getHandshakeKeys", lpubkey, topic, true, false) + if err != nil { + t.Fatal(err) + } + + // get outgoing symkeys in byte form from both sides + var lsendsymkeys []string + for _, id := range lsendsymkeyids { + var key string + err = clients[0].Call(&key, "pss_getSymmetricKey", id) + if err != nil { + t.Fatal(err) + } + lsendsymkeys = append(lsendsymkeys, key) + } + var rsendsymkeys []string + for _, id := range rsendsymkeyids { + var key string + err = clients[1].Call(&key, "pss_getSymmetricKey", id) + if err != nil { + t.Fatal(err) + } + rsendsymkeys = append(rsendsymkeys, key) + } + + // get incoming symkeys in byte form from both sides and compare + var lrecvsymkeys []string + for _, id := range lrecvsymkeyids { + var key string + err = clients[0].Call(&key, "pss_getSymmetricKey", id) + if err != nil { + t.Fatal(err) + } + match := false + for _, otherkey := range rsendsymkeys { + if otherkey == key { + match = true + } + } + if !match { + t.Fatalf("no match right send for left recv key %s", id) + } + lrecvsymkeys = append(lrecvsymkeys, key) + } + var rrecvsymkeys []string + for _, id := range rrecvsymkeyids { + var key string + err = clients[1].Call(&key, "pss_getSymmetricKey", id) + if err != nil { + t.Fatal(err) + } + match := false + for _, otherkey := range lsendsymkeys { + if otherkey == key { + match = true + } + } + if !match { + t.Fatalf("no match left send for right recv key %s", id) + } + rrecvsymkeys = append(rrecvsymkeys, key) + } + + // send new handshake request, should send no keys + err = clients[0].Call(nil, "pss_handshake", rpubkey, topic, false) + if err == nil { + t.Fatal("expected full symkey buffer error") + } + + // expire one key, send new handshake request + err = clients[0].Call(nil, "pss_releaseHandshakeKey", rpubkey, topic, lsendsymkeyids[0], true) + if err != nil { + t.Fatalf("release left send key %s fail: %v", lsendsymkeyids[0], err) + } + + var newlhsendkeyids []string + + // send new handshake request, should now receive one key + // check that it is not in previous right recv key array + err = clients[0].Call(&newlhsendkeyids, "pss_handshake", rpubkey, topic, true, false) + if err != nil { + t.Fatalf("handshake send fail: %v", err) + } else if len(newlhsendkeyids) != defaultSymKeyCapacity { + t.Fatalf("wrong receive count, expected 1, got %d", len(newlhsendkeyids)) + } + + var newlrecvsymkey string + err = clients[0].Call(&newlrecvsymkey, "pss_getSymmetricKey", newlhsendkeyids[0]) + if err != nil { + t.Fatal(err) + } + var rmatchsymkeyid *string + for i, id := range rrecvsymkeyids { + var key string + err = clients[1].Call(&key, "pss_getSymmetricKey", id) + if err != nil { + t.Fatal(err) + } + if newlrecvsymkey == key { + rmatchsymkeyid = &rrecvsymkeyids[i] + } + } + if rmatchsymkeyid != nil { + t.Fatalf("right sent old key id %s in second handshake", *rmatchsymkeyid) + } + + // clean the pss core keystore. Should clean the key released earlier + var cleancount int + clients[0].Call(&cleancount, "psstest_clean") + if cleancount > 1 { + t.Fatalf("pss clean count mismatch; expected 1, got %d", cleancount) + } +} diff --git a/swarm/pss/notify/notify.go b/swarm/pss/notify/notify.go new file mode 100644 index 0000000000..723092c32d --- /dev/null +++ b/swarm/pss/notify/notify.go @@ -0,0 +1,394 @@ +package notify + +import ( + "crypto/ecdsa" + "fmt" + "sync" + + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/p2p" + "github.com/ethereum/go-ethereum/rlp" + "github.com/ethereum/go-ethereum/swarm/log" + "github.com/ethereum/go-ethereum/swarm/pss" +) + +const ( + // sent from requester to updater to request start of notifications + MsgCodeStart = iota + + // sent from updater to requester, contains a notification plus a new symkey to replace the old + MsgCodeNotifyWithKey + + // sent from updater to requester, contains a notification + MsgCodeNotify + + // sent from requester to updater to request stop of notifications (currently unused) + MsgCodeStop + MsgCodeMax +) + +const ( + DefaultAddressLength = 1 + symKeyLength = 32 // this should be gotten from source +) + +var ( + // control topic is used before symmetric key issuance completes + controlTopic = pss.Topic{0x00, 0x00, 0x00, 0x01} +) + +// when code is MsgCodeStart, Payload is address +// when code is MsgCodeNotifyWithKey, Payload is notification | symkey +// when code is MsgCodeNotify, Payload is notification +// when code is MsgCodeStop, Payload is address +type Msg struct { + Code byte + Name []byte + Payload []byte + namestring string +} + +// NewMsg creates a new notification message object +func NewMsg(code byte, name string, payload []byte) *Msg { + return &Msg{ + Code: code, + Name: []byte(name), + Payload: payload, + namestring: name, + } +} + +// NewMsgFromPayload decodes a serialized message payload into a new notification message object +func NewMsgFromPayload(payload []byte) (*Msg, error) { + msg := &Msg{} + err := rlp.DecodeBytes(payload, msg) + if err != nil { + return nil, err + } + msg.namestring = string(msg.Name) + return msg, nil +} + +// a notifier has one sendBin entry for each address space it sends messages to +type sendBin struct { + address pss.PssAddress + symKeyId string + count int +} + +// represents a single notification service +// only subscription address bins that match the address of a notification client have entries. +type notifier struct { + bins map[string]*sendBin + topic pss.Topic // identifies the resource for pss receiver + threshold int // amount of address bytes used in bins + updateC <-chan []byte + quitC chan struct{} +} + +func (n *notifier) removeSubscription() { + n.quitC <- struct{}{} +} + +// represents an individual subscription made by a public key at a specific address/neighborhood +type subscription struct { + pubkeyId string + address pss.PssAddress + handler func(string, []byte) error +} + +// Controller is the interface to control, add and remove notification services and subscriptions +type Controller struct { + pss *pss.Pss + notifiers map[string]*notifier + subscriptions map[string]*subscription + mu sync.Mutex +} + +// NewController creates a new Controller object +func NewController(ps *pss.Pss) *Controller { + ctrl := &Controller{ + pss: ps, + notifiers: make(map[string]*notifier), + subscriptions: make(map[string]*subscription), + } + ctrl.pss.Register(&controlTopic, ctrl.Handler) + return ctrl +} + +// IsActive is used to check if a notification service exists for a specified id string +// Returns true if exists, false if not +func (c *Controller) IsActive(name string) bool { + c.mu.Lock() + defer c.mu.Unlock() + return c.isActive(name) +} + +func (c *Controller) isActive(name string) bool { + _, ok := c.notifiers[name] + return ok +} + +// Subscribe is used by a client to request notifications from a notification service provider +// It will create a MsgCodeStart message and send asymmetrically to the provider using its public key and routing address +// The handler function is a callback that will be called when notifications are received +// Fails if the request pss cannot be sent or if the update message could not be serialized +func (c *Controller) Subscribe(name string, pubkey *ecdsa.PublicKey, address pss.PssAddress, handler func(string, []byte) error) error { + c.mu.Lock() + defer c.mu.Unlock() + msg := NewMsg(MsgCodeStart, name, c.pss.BaseAddr()) + c.pss.SetPeerPublicKey(pubkey, controlTopic, &address) + pubkeyId := hexutil.Encode(crypto.FromECDSAPub(pubkey)) + smsg, err := rlp.EncodeToBytes(msg) + if err != nil { + return err + } + err = c.pss.SendAsym(pubkeyId, controlTopic, smsg) + if err != nil { + return err + } + c.subscriptions[name] = &subscription{ + pubkeyId: pubkeyId, + address: address, + handler: handler, + } + return nil +} + +// Unsubscribe, perhaps unsurprisingly, undoes the effects of Subscribe +// Fails if the subscription does not exist, if the request pss cannot be sent or if the update message could not be serialized +func (c *Controller) Unsubscribe(name string) error { + c.mu.Lock() + defer c.mu.Unlock() + sub, ok := c.subscriptions[name] + if !ok { + return fmt.Errorf("Unknown subscription '%s'", name) + } + msg := NewMsg(MsgCodeStop, name, sub.address) + smsg, err := rlp.EncodeToBytes(msg) + if err != nil { + return err + } + err = c.pss.SendAsym(sub.pubkeyId, controlTopic, smsg) + if err != nil { + return err + } + delete(c.subscriptions, name) + return nil +} + +// NewNotifier is used by a notification service provider to create a new notification service +// It takes a name as identifier for the resource, a threshold indicating the granularity of the subscription address bin +// It then starts an event loop which listens to the supplied update channel and executes notifications on channel receives +// Fails if a notifier already is registered on the name +//func (c *Controller) NewNotifier(name string, threshold int, contentFunc func(string) ([]byte, error)) error { +func (c *Controller) NewNotifier(name string, threshold int, updateC <-chan []byte) (func(), error) { + c.mu.Lock() + if c.isActive(name) { + c.mu.Unlock() + return nil, fmt.Errorf("Notification service %s already exists in controller", name) + } + quitC := make(chan struct{}) + c.notifiers[name] = ¬ifier{ + bins: make(map[string]*sendBin), + topic: pss.BytesToTopic([]byte(name)), + threshold: threshold, + updateC: updateC, + quitC: quitC, + //contentFunc: contentFunc, + } + c.mu.Unlock() + go func() { + for { + select { + case <-quitC: + return + case data := <-updateC: + c.notify(name, data) + } + } + }() + + return c.notifiers[name].removeSubscription, nil +} + +// RemoveNotifier is used to stop a notification service. +// It cancels the event loop listening to the notification provider's update channel +func (c *Controller) RemoveNotifier(name string) error { + c.mu.Lock() + defer c.mu.Unlock() + currentNotifier, ok := c.notifiers[name] + if !ok { + return fmt.Errorf("Unknown notification service %s", name) + } + currentNotifier.removeSubscription() + delete(c.notifiers, name) + return nil +} + +// Notify is called by a notification service provider to issue a new notification +// It takes the name of the notification service and the data to be sent. +// It fails if a notifier with this name does not exist or if data could not be serialized +// Note that it does NOT fail on failure to send a message +func (c *Controller) notify(name string, data []byte) error { + c.mu.Lock() + defer c.mu.Unlock() + if !c.isActive(name) { + return fmt.Errorf("Notification service %s doesn't exist", name) + } + msg := NewMsg(MsgCodeNotify, name, data) + smsg, err := rlp.EncodeToBytes(msg) + if err != nil { + return err + } + for _, m := range c.notifiers[name].bins { + log.Debug("sending pss notify", "name", name, "addr", fmt.Sprintf("%x", m.address), "topic", fmt.Sprintf("%x", c.notifiers[name].topic), "data", data) + go func(m *sendBin) { + err = c.pss.SendSym(m.symKeyId, c.notifiers[name].topic, smsg) + if err != nil { + log.Warn("Failed to send notify to addr %x: %v", m.address, err) + } + }(m) + } + return nil +} + +// check if we already have the bin +// if we do, retrieve the symkey from it and increment the count +// if we dont make a new symkey and a new bin entry +func (c *Controller) addToBin(ntfr *notifier, address []byte) (symKeyId string, pssAddress pss.PssAddress, err error) { + + // parse the address from the message and truncate if longer than our bins threshold + if len(address) > ntfr.threshold { + address = address[:ntfr.threshold] + } + + pssAddress = pss.PssAddress(address) + hexAddress := fmt.Sprintf("%x", address) + currentBin, ok := ntfr.bins[hexAddress] + if ok { + currentBin.count++ + symKeyId = currentBin.symKeyId + } else { + symKeyId, err = c.pss.GenerateSymmetricKey(ntfr.topic, &pssAddress, false) + if err != nil { + return "", nil, err + } + ntfr.bins[hexAddress] = &sendBin{ + address: address, + symKeyId: symKeyId, + count: 1, + } + } + return symKeyId, pssAddress, nil +} + +func (c *Controller) handleStartMsg(msg *Msg, keyid string) (err error) { + + keyidbytes, err := hexutil.Decode(keyid) + if err != nil { + return err + } + pubkey, err := crypto.UnmarshalPubkey(keyidbytes) + if err != nil { + return err + } + + // if name is not registered for notifications we will not react + currentNotifier, ok := c.notifiers[msg.namestring] + if !ok { + return fmt.Errorf("Subscribe attempted on unknown resource '%s'", msg.namestring) + } + + // add to or open new bin + symKeyId, pssAddress, err := c.addToBin(currentNotifier, msg.Payload) + if err != nil { + return err + } + + // add to address book for send initial notify + symkey, err := c.pss.GetSymmetricKey(symKeyId) + if err != nil { + return err + } + err = c.pss.SetPeerPublicKey(pubkey, controlTopic, &pssAddress) + if err != nil { + return err + } + + // TODO this is set to zero-length byte pending decision on protocol for initial message, whether it should include message or not, and how to trigger the initial message so that current state of MRU is sent upon subscription + notify := []byte{} + replyMsg := NewMsg(MsgCodeNotifyWithKey, msg.namestring, make([]byte, len(notify)+symKeyLength)) + copy(replyMsg.Payload, notify) + copy(replyMsg.Payload[len(notify):], symkey) + sReplyMsg, err := rlp.EncodeToBytes(replyMsg) + if err != nil { + return err + } + return c.pss.SendAsym(keyid, controlTopic, sReplyMsg) +} + +func (c *Controller) handleNotifyWithKeyMsg(msg *Msg) error { + symkey := msg.Payload[len(msg.Payload)-symKeyLength:] + topic := pss.BytesToTopic(msg.Name) + + // \TODO keep track of and add actual address + updaterAddr := pss.PssAddress([]byte{}) + c.pss.SetSymmetricKey(symkey, topic, &updaterAddr, true) + c.pss.Register(&topic, c.Handler) + return c.subscriptions[msg.namestring].handler(msg.namestring, msg.Payload[:len(msg.Payload)-symKeyLength]) +} + +func (c *Controller) handleStopMsg(msg *Msg) error { + // if name is not registered for notifications we will not react + currentNotifier, ok := c.notifiers[msg.namestring] + if !ok { + return fmt.Errorf("Unsubscribe attempted on unknown resource '%s'", msg.namestring) + } + + // parse the address from the message and truncate if longer than our bins' address length threshold + address := msg.Payload + if len(msg.Payload) > currentNotifier.threshold { + address = address[:currentNotifier.threshold] + } + + // remove the entry from the bin if it exists, and remove the bin if it's the last remaining one + hexAddress := fmt.Sprintf("%x", address) + currentBin, ok := currentNotifier.bins[hexAddress] + if !ok { + return fmt.Errorf("found no active bin for address %s", hexAddress) + } + currentBin.count-- + if currentBin.count == 0 { // if no more clients in this bin, remove it + delete(currentNotifier.bins, hexAddress) + } + return nil +} + +// Handler is the pss topic handler to be used to process notification service messages +// It should be registered in the pss of both to any notification service provides and clients using the service +func (c *Controller) Handler(smsg []byte, p *p2p.Peer, asymmetric bool, keyid string) error { + c.mu.Lock() + defer c.mu.Unlock() + log.Debug("notify controller handler", "keyid", keyid) + + // see if the message is valid + msg, err := NewMsgFromPayload(smsg) + if err != nil { + return err + } + + switch msg.Code { + case MsgCodeStart: + return c.handleStartMsg(msg, keyid) + case MsgCodeNotifyWithKey: + return c.handleNotifyWithKeyMsg(msg) + case MsgCodeNotify: + return c.subscriptions[msg.namestring].handler(msg.namestring, msg.Payload) + case MsgCodeStop: + return c.handleStopMsg(msg) + } + + return fmt.Errorf("Invalid message code: %d", msg.Code) +} diff --git a/swarm/pss/notify/notify_test.go b/swarm/pss/notify/notify_test.go new file mode 100644 index 0000000000..3c655f215c --- /dev/null +++ b/swarm/pss/notify/notify_test.go @@ -0,0 +1,252 @@ +package notify + +import ( + "bytes" + "context" + "flag" + "fmt" + "os" + "testing" + "time" + + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/node" + "github.com/ethereum/go-ethereum/p2p/discover" + "github.com/ethereum/go-ethereum/p2p/simulations" + "github.com/ethereum/go-ethereum/p2p/simulations/adapters" + "github.com/ethereum/go-ethereum/swarm/network" + "github.com/ethereum/go-ethereum/swarm/pss" + "github.com/ethereum/go-ethereum/swarm/state" + whisper "github.com/ethereum/go-ethereum/whisper/whisperv5" +) + +var ( + loglevel = flag.Int("l", 3, "loglevel") + psses map[string]*pss.Pss + w *whisper.Whisper + wapi *whisper.PublicWhisperAPI +) + +func init() { + flag.Parse() + hs := log.StreamHandler(os.Stderr, log.TerminalFormat(true)) + hf := log.LvlFilterHandler(log.Lvl(*loglevel), hs) + h := log.CallerFileHandler(hf) + log.Root().SetHandler(h) + + w = whisper.New(&whisper.DefaultConfig) + wapi = whisper.NewPublicWhisperAPI(w) + psses = make(map[string]*pss.Pss) +} + +// Creates a client node and notifier node +// Client sends pss notifications requests +// notifier sends initial notification with symmetric key, and +// second notification symmetrically encrypted +func TestStart(t *testing.T) { + adapter := adapters.NewSimAdapter(newServices(false)) + net := simulations.NewNetwork(adapter, &simulations.NetworkConfig{ + ID: "0", + DefaultService: "bzz", + }) + leftNodeConf := adapters.RandomNodeConfig() + leftNodeConf.Services = []string{"bzz", "pss"} + leftNode, err := net.NewNodeWithConfig(leftNodeConf) + if err != nil { + t.Fatal(err) + } + err = net.Start(leftNode.ID()) + if err != nil { + t.Fatal(err) + } + + rightNodeConf := adapters.RandomNodeConfig() + rightNodeConf.Services = []string{"bzz", "pss"} + rightNode, err := net.NewNodeWithConfig(rightNodeConf) + if err != nil { + t.Fatal(err) + } + err = net.Start(rightNode.ID()) + if err != nil { + t.Fatal(err) + } + + err = net.Connect(rightNode.ID(), leftNode.ID()) + if err != nil { + t.Fatal(err) + } + + leftRpc, err := leftNode.Client() + if err != nil { + t.Fatal(err) + } + + rightRpc, err := rightNode.Client() + if err != nil { + t.Fatal(err) + } + + var leftAddr string + err = leftRpc.Call(&leftAddr, "pss_baseAddr") + if err != nil { + t.Fatal(err) + } + + var rightAddr string + err = rightRpc.Call(&rightAddr, "pss_baseAddr") + if err != nil { + t.Fatal(err) + } + + var leftPub string + err = leftRpc.Call(&leftPub, "pss_getPublicKey") + if err != nil { + t.Fatal(err) + } + + var rightPub string + err = rightRpc.Call(&rightPub, "pss_getPublicKey") + if err != nil { + t.Fatal(err) + } + + rsrcName := "foo.eth" + rsrcTopic := pss.BytesToTopic([]byte(rsrcName)) + + // wait for kademlia table to populate + time.Sleep(time.Second) + + ctx, cancel := context.WithTimeout(context.Background(), time.Second*2) + defer cancel() + rmsgC := make(chan *pss.APIMsg) + rightSub, err := rightRpc.Subscribe(ctx, "pss", rmsgC, "receive", controlTopic) + if err != nil { + t.Fatal(err) + } + defer rightSub.Unsubscribe() + + updateC := make(chan []byte) + updateMsg := []byte{} + ctrlClient := NewController(psses[rightPub]) + ctrlNotifier := NewController(psses[leftPub]) + ctrlNotifier.NewNotifier("foo.eth", 2, updateC) + + pubkeybytes, err := hexutil.Decode(leftPub) + if err != nil { + t.Fatal(err) + } + pubkey, err := crypto.UnmarshalPubkey(pubkeybytes) + if err != nil { + t.Fatal(err) + } + addrbytes, err := hexutil.Decode(leftAddr) + if err != nil { + t.Fatal(err) + } + ctrlClient.Subscribe(rsrcName, pubkey, addrbytes, func(s string, b []byte) error { + if s != "foo.eth" || !bytes.Equal(updateMsg, b) { + t.Fatalf("unexpected result in client handler: '%s':'%x'", s, b) + } + log.Info("client handler receive", "s", s, "b", b) + return nil + }) + + var inMsg *pss.APIMsg + select { + case inMsg = <-rmsgC: + case <-ctx.Done(): + t.Fatal(ctx.Err()) + } + + dMsg, err := NewMsgFromPayload(inMsg.Msg) + if err != nil { + t.Fatal(err) + } + if dMsg.namestring != rsrcName { + t.Fatalf("expected name '%s', got '%s'", rsrcName, dMsg.namestring) + } + if !bytes.Equal(dMsg.Payload[:len(updateMsg)], updateMsg) { + t.Fatalf("expected payload first %d bytes '%x', got '%x'", len(updateMsg), updateMsg, dMsg.Payload[:len(updateMsg)]) + } + if len(updateMsg)+symKeyLength != len(dMsg.Payload) { + t.Fatalf("expected payload length %d, have %d", len(updateMsg)+symKeyLength, len(dMsg.Payload)) + } + + rightSubUpdate, err := rightRpc.Subscribe(ctx, "pss", rmsgC, "receive", rsrcTopic) + if err != nil { + t.Fatal(err) + } + defer rightSubUpdate.Unsubscribe() + + updateMsg = []byte("plugh") + updateC <- updateMsg + select { + case inMsg = <-rmsgC: + case <-ctx.Done(): + log.Error("timed out waiting for msg", "topic", fmt.Sprintf("%x", rsrcTopic)) + t.Fatal(ctx.Err()) + } + dMsg, err = NewMsgFromPayload(inMsg.Msg) + if err != nil { + t.Fatal(err) + } + if dMsg.namestring != rsrcName { + t.Fatalf("expected name %s, got %s", rsrcName, dMsg.namestring) + } + if !bytes.Equal(dMsg.Payload, updateMsg) { + t.Fatalf("expected payload '%x', got '%x'", updateMsg, dMsg.Payload) + } + +} + +func newServices(allowRaw bool) adapters.Services { + stateStore := state.NewInmemoryStore() + kademlias := make(map[discover.NodeID]*network.Kademlia) + kademlia := func(id discover.NodeID) *network.Kademlia { + if k, ok := kademlias[id]; ok { + return k + } + addr := network.NewAddrFromNodeID(id) + params := network.NewKadParams() + params.MinProxBinSize = 2 + params.MaxBinSize = 3 + params.MinBinSize = 1 + params.MaxRetries = 1000 + params.RetryExponent = 2 + params.RetryInterval = 1000000 + kademlias[id] = network.NewKademlia(addr.Over(), params) + return kademlias[id] + } + return adapters.Services{ + "pss": func(ctx *adapters.ServiceContext) (node.Service, error) { + ctxlocal, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + keys, err := wapi.NewKeyPair(ctxlocal) + privkey, err := w.GetPrivateKey(keys) + pssp := pss.NewPssParams().WithPrivateKey(privkey) + pssp.MsgTTL = time.Second * 30 + pssp.AllowRaw = allowRaw + pskad := kademlia(ctx.Config.ID) + ps, err := pss.NewPss(pskad, pssp) + if err != nil { + return nil, err + } + //psses[common.ToHex(crypto.FromECDSAPub(&privkey.PublicKey))] = ps + psses[hexutil.Encode(crypto.FromECDSAPub(&privkey.PublicKey))] = ps + return ps, nil + }, + "bzz": func(ctx *adapters.ServiceContext) (node.Service, error) { + addr := network.NewAddrFromNodeID(ctx.Config.ID) + hp := network.NewHiveParams() + hp.Discovery = false + config := &network.BzzConfig{ + OverlayAddr: addr.Over(), + UnderlayAddr: addr.Under(), + HiveParams: hp, + } + return network.NewBzz(config, kademlia(ctx.Config.ID), stateStore, nil, nil), nil + }, + } +} diff --git a/swarm/pss/ping.go b/swarm/pss/ping.go new file mode 100644 index 0000000000..ff635f40a4 --- /dev/null +++ b/swarm/pss/ping.go @@ -0,0 +1,97 @@ +// 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 . + +// +build !nopssprotocol,!nopssping + +package pss + +import ( + "context" + "errors" + "time" + + "github.com/ethereum/go-ethereum/p2p" + "github.com/ethereum/go-ethereum/p2p/protocols" + "github.com/ethereum/go-ethereum/swarm/log" +) + +// Generic ping protocol implementation for +// pss devp2p protocol emulation +type PingMsg struct { + Created time.Time + Pong bool // set if message is pong reply +} + +type Ping struct { + Pong bool // toggle pong reply upon ping receive + OutC chan bool // trigger ping + InC chan bool // optional, report back to calling code +} + +func (p *Ping) pingHandler(ctx context.Context, msg interface{}) error { + var pingmsg *PingMsg + var ok bool + if pingmsg, ok = msg.(*PingMsg); !ok { + return errors.New("invalid msg") + } + log.Debug("ping handler", "msg", pingmsg, "outc", p.OutC) + if p.InC != nil { + p.InC <- pingmsg.Pong + } + if p.Pong && !pingmsg.Pong { + p.OutC <- true + } + return nil +} + +var PingProtocol = &protocols.Spec{ + Name: "psstest", + Version: 1, + MaxMsgSize: 1024, + Messages: []interface{}{ + PingMsg{}, + }, +} + +var PingTopic = ProtocolTopic(PingProtocol) + +func NewPingProtocol(ping *Ping) *p2p.Protocol { + return &p2p.Protocol{ + Name: PingProtocol.Name, + Version: PingProtocol.Version, + Length: uint64(PingProtocol.MaxMsgSize), + Run: func(p *p2p.Peer, rw p2p.MsgReadWriter) error { + quitC := make(chan struct{}) + pp := protocols.NewPeer(p, rw, PingProtocol) + log.Trace("running pss vprotocol", "peer", p, "outc", ping.OutC) + go func() { + for { + select { + case ispong := <-ping.OutC: + pp.Send(context.TODO(), &PingMsg{ + Created: time.Now(), + Pong: ispong, + }) + case <-quitC: + } + } + }() + err := pp.Run(ping.pingHandler) + quitC <- struct{}{} + return err + }, + } +} diff --git a/swarm/pss/protocol.go b/swarm/pss/protocol.go new file mode 100644 index 0000000000..5fcae090ef --- /dev/null +++ b/swarm/pss/protocol.go @@ -0,0 +1,287 @@ +// 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 . + +// +build !nopssprotocol + +package pss + +import ( + "bytes" + "fmt" + "sync" + "time" + + "github.com/ethereum/go-ethereum/p2p" + "github.com/ethereum/go-ethereum/p2p/protocols" + "github.com/ethereum/go-ethereum/rlp" + "github.com/ethereum/go-ethereum/swarm/log" +) + +const ( + IsActiveProtocol = true +) + +// Convenience wrapper for devp2p protocol messages for transport over pss +type ProtocolMsg struct { + Code uint64 + Size uint32 + Payload []byte + ReceivedAt time.Time +} + +// Creates a ProtocolMsg +func NewProtocolMsg(code uint64, msg interface{}) ([]byte, error) { + + rlpdata, err := rlp.EncodeToBytes(msg) + if err != nil { + return nil, err + } + + // TODO verify that nested structs cannot be used in rlp + smsg := &ProtocolMsg{ + Code: code, + Size: uint32(len(rlpdata)), + Payload: rlpdata, + } + + return rlp.EncodeToBytes(smsg) +} + +// Protocol options to be passed to a new Protocol instance +// +// The parameters specify which encryption schemes to allow +type ProtocolParams struct { + Asymmetric bool + Symmetric bool +} + +// PssReadWriter bridges pss send/receive with devp2p protocol send/receive +// +// Implements p2p.MsgReadWriter +type PssReadWriter struct { + *Pss + LastActive time.Time + rw chan p2p.Msg + spec *protocols.Spec + topic *Topic + sendFunc func(string, Topic, []byte) error + key string + closed bool +} + +// Implements p2p.MsgReader +func (prw *PssReadWriter) ReadMsg() (p2p.Msg, error) { + msg := <-prw.rw + log.Trace(fmt.Sprintf("pssrw readmsg: %v", msg)) + return msg, nil +} + +// Implements p2p.MsgWriter +func (prw *PssReadWriter) WriteMsg(msg p2p.Msg) error { + log.Trace("pssrw writemsg", "msg", msg) + if prw.closed { + return fmt.Errorf("connection closed") + } + rlpdata := make([]byte, msg.Size) + msg.Payload.Read(rlpdata) + pmsg, err := rlp.EncodeToBytes(ProtocolMsg{ + Code: msg.Code, + Size: msg.Size, + Payload: rlpdata, + }) + if err != nil { + return err + } + return prw.sendFunc(prw.key, *prw.topic, pmsg) +} + +// Injects a p2p.Msg into the MsgReadWriter, so that it appears on the associated p2p.MsgReader +func (prw *PssReadWriter) injectMsg(msg p2p.Msg) error { + log.Trace(fmt.Sprintf("pssrw injectmsg: %v", msg)) + prw.rw <- msg + return nil +} + +// Convenience object for emulation devp2p over pss +type Protocol struct { + *Pss + proto *p2p.Protocol + topic *Topic + spec *protocols.Spec + pubKeyRWPool map[string]p2p.MsgReadWriter + symKeyRWPool map[string]p2p.MsgReadWriter + Asymmetric bool + Symmetric bool + RWPoolMu sync.Mutex +} + +// Activates devp2p emulation over a specific pss topic +// +// One or both encryption schemes must be specified. If +// only one is specified, the protocol will not be valid +// for the other, and will make the message handler +// return errors +func RegisterProtocol(ps *Pss, topic *Topic, spec *protocols.Spec, targetprotocol *p2p.Protocol, options *ProtocolParams) (*Protocol, error) { + if !options.Asymmetric && !options.Symmetric { + return nil, fmt.Errorf("specify at least one of asymmetric or symmetric messaging mode") + } + pp := &Protocol{ + Pss: ps, + proto: targetprotocol, + topic: topic, + spec: spec, + pubKeyRWPool: make(map[string]p2p.MsgReadWriter), + symKeyRWPool: make(map[string]p2p.MsgReadWriter), + Asymmetric: options.Asymmetric, + Symmetric: options.Symmetric, + } + return pp, nil +} + +// Generic handler for incoming messages over devp2p emulation +// +// To be passed to pss.Register() +// +// Will run the protocol on a new incoming peer, provided that +// the encryption key of the message has a match in the internal +// pss keypool +// +// Fails if protocol is not valid for the message encryption scheme, +// if adding a new peer fails, or if the message is not a serialized +// p2p.Msg (which it always will be if it is sent from this object). +func (p *Protocol) Handle(msg []byte, peer *p2p.Peer, asymmetric bool, keyid string) error { + var vrw *PssReadWriter + if p.Asymmetric != asymmetric && p.Symmetric == !asymmetric { + return fmt.Errorf("invalid protocol encryption") + } else if (!p.isActiveSymKey(keyid, *p.topic) && !asymmetric) || + (!p.isActiveAsymKey(keyid, *p.topic) && asymmetric) { + + rw, err := p.AddPeer(peer, *p.topic, asymmetric, keyid) + if err != nil { + return err + } else if rw == nil { + return fmt.Errorf("handle called on nil MsgReadWriter for new key " + keyid) + } + vrw = rw.(*PssReadWriter) + } + + pmsg, err := ToP2pMsg(msg) + if err != nil { + return fmt.Errorf("could not decode pssmsg") + } + if asymmetric { + if p.pubKeyRWPool[keyid] == nil { + return fmt.Errorf("handle called on nil MsgReadWriter for key " + keyid) + } + vrw = p.pubKeyRWPool[keyid].(*PssReadWriter) + } else { + if p.symKeyRWPool[keyid] == nil { + return fmt.Errorf("handle called on nil MsgReadWriter for key " + keyid) + } + vrw = p.symKeyRWPool[keyid].(*PssReadWriter) + } + vrw.injectMsg(pmsg) + return nil +} + +// check if (peer) symmetric key is currently registered with this topic +func (p *Protocol) isActiveSymKey(key string, topic Topic) bool { + return p.symKeyRWPool[key] != nil +} + +// check if (peer) asymmetric key is currently registered with this topic +func (p *Protocol) isActiveAsymKey(key string, topic Topic) bool { + return p.pubKeyRWPool[key] != nil +} + +// Creates a serialized (non-buffered) version of a p2p.Msg, used in the specialized internal p2p.MsgReadwriter implementations +func ToP2pMsg(msg []byte) (p2p.Msg, error) { + payload := &ProtocolMsg{} + if err := rlp.DecodeBytes(msg, payload); err != nil { + return p2p.Msg{}, fmt.Errorf("pss protocol handler unable to decode payload as p2p message: %v", err) + } + + return p2p.Msg{ + Code: payload.Code, + Size: uint32(len(payload.Payload)), + ReceivedAt: time.Now(), + Payload: bytes.NewBuffer(payload.Payload), + }, nil +} + +// Runs an emulated pss Protocol on the specified peer, +// linked to a specific topic +// `key` and `asymmetric` specifies what encryption key +// to link the peer to. +// The key must exist in the pss store prior to adding the peer. +func (p *Protocol) AddPeer(peer *p2p.Peer, topic Topic, asymmetric bool, key string) (p2p.MsgReadWriter, error) { + rw := &PssReadWriter{ + Pss: p.Pss, + rw: make(chan p2p.Msg), + spec: p.spec, + topic: p.topic, + key: key, + } + if asymmetric { + rw.sendFunc = p.Pss.SendAsym + } else { + rw.sendFunc = p.Pss.SendSym + } + if asymmetric { + p.Pss.pubKeyPoolMu.Lock() + if _, ok := p.Pss.pubKeyPool[key]; !ok { + return nil, fmt.Errorf("asym key does not exist: %s", key) + } + p.Pss.pubKeyPoolMu.Unlock() + p.RWPoolMu.Lock() + p.pubKeyRWPool[key] = rw + p.RWPoolMu.Unlock() + } else { + p.Pss.symKeyPoolMu.Lock() + if _, ok := p.Pss.symKeyPool[key]; !ok { + return nil, fmt.Errorf("symkey does not exist: %s", key) + } + p.Pss.symKeyPoolMu.Unlock() + p.RWPoolMu.Lock() + p.symKeyRWPool[key] = rw + p.RWPoolMu.Unlock() + } + go func() { + err := p.proto.Run(peer, rw) + log.Warn(fmt.Sprintf("pss vprotocol quit on %v topic %v: %v", peer, topic, err)) + }() + return rw, nil +} + +func (p *Protocol) RemovePeer(asymmetric bool, key string) { + log.Debug("closing pss peer", "asym", asymmetric, "key", key) + p.RWPoolMu.Lock() + defer p.RWPoolMu.Unlock() + if asymmetric { + rw := p.pubKeyRWPool[key].(*PssReadWriter) + rw.closed = true + delete(p.pubKeyRWPool, key) + } else { + rw := p.symKeyRWPool[key].(*PssReadWriter) + rw.closed = true + delete(p.symKeyRWPool, key) + } +} + +// Uniform translation of protocol specifiers to topic +func ProtocolTopic(spec *protocols.Spec) Topic { + return BytesToTopic([]byte(fmt.Sprintf("%s:%d", spec.Name, spec.Version))) +} diff --git a/swarm/pss/protocol_none.go b/swarm/pss/protocol_none.go new file mode 100644 index 0000000000..c92be3f902 --- /dev/null +++ b/swarm/pss/protocol_none.go @@ -0,0 +1,23 @@ +// 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 . + +// +build nopssprotocol + +package pss + +const ( + IsActiveProtocol = false +) diff --git a/swarm/pss/protocol_test.go b/swarm/pss/protocol_test.go new file mode 100644 index 0000000000..0b6ea33cae --- /dev/null +++ b/swarm/pss/protocol_test.go @@ -0,0 +1,158 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package pss + +import ( + "bytes" + "context" + "fmt" + "strconv" + "strings" + "testing" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/p2p" + "github.com/ethereum/go-ethereum/p2p/discover" + "github.com/ethereum/go-ethereum/swarm/log" +) + +type protoCtrl struct { + C chan bool + protocol *Protocol + run func(*p2p.Peer, p2p.MsgReadWriter) error +} + +// simple ping pong protocol test for the pss devp2p emulation +func TestProtocol(t *testing.T) { + t.Run("32", testProtocol) + t.Run("8", testProtocol) + t.Run("0", testProtocol) +} + +func testProtocol(t *testing.T) { + + // address hint size + var addrsize int64 + paramstring := strings.Split(t.Name(), "/") + addrsize, _ = strconv.ParseInt(paramstring[1], 10, 0) + log.Info("protocol test", "addrsize", addrsize) + + topic := PingTopic.String() + + clients, err := setupNetwork(2, false) + if err != nil { + t.Fatal(err) + } + var loaddrhex string + err = clients[0].Call(&loaddrhex, "pss_baseAddr") + if err != nil { + t.Fatalf("rpc get node 1 baseaddr fail: %v", err) + } + loaddrhex = loaddrhex[:2+(addrsize*2)] + var roaddrhex string + err = clients[1].Call(&roaddrhex, "pss_baseAddr") + if err != nil { + t.Fatalf("rpc get node 2 baseaddr fail: %v", err) + } + roaddrhex = roaddrhex[:2+(addrsize*2)] + lnodeinfo := &p2p.NodeInfo{} + err = clients[0].Call(&lnodeinfo, "admin_nodeInfo") + if err != nil { + t.Fatalf("rpc nodeinfo node 11 fail: %v", err) + } + + var lpubkey string + err = clients[0].Call(&lpubkey, "pss_getPublicKey") + if err != nil { + t.Fatalf("rpc get node 1 pubkey fail: %v", err) + } + var rpubkey string + err = clients[1].Call(&rpubkey, "pss_getPublicKey") + if err != nil { + t.Fatalf("rpc get node 2 pubkey fail: %v", err) + } + + time.Sleep(time.Millisecond * 1000) // replace with hive healthy code + + lmsgC := make(chan APIMsg) + lctx, cancel := context.WithTimeout(context.Background(), time.Second*10) + defer cancel() + lsub, err := clients[0].Subscribe(lctx, "pss", lmsgC, "receive", topic) + defer lsub.Unsubscribe() + rmsgC := make(chan APIMsg) + rctx, cancel := context.WithTimeout(context.Background(), time.Second*10) + defer cancel() + rsub, err := clients[1].Subscribe(rctx, "pss", rmsgC, "receive", topic) + defer rsub.Unsubscribe() + + // set reciprocal public keys + err = clients[0].Call(nil, "pss_setPeerPublicKey", rpubkey, topic, roaddrhex) + if err != nil { + t.Fatal(err) + } + err = clients[1].Call(nil, "pss_setPeerPublicKey", lpubkey, topic, loaddrhex) + if err != nil { + t.Fatal(err) + } + + // add right peer's public key as protocol peer on left + nid, _ := discover.HexID("0x00") // this hack is needed to satisfy the p2p method + p := p2p.NewPeer(nid, fmt.Sprintf("%x", common.FromHex(loaddrhex)), []p2p.Cap{}) + _, err = pssprotocols[lnodeinfo.ID].protocol.AddPeer(p, PingTopic, true, rpubkey) + if err != nil { + t.Fatal(err) + } + + // sends ping asym, checks delivery + pssprotocols[lnodeinfo.ID].C <- false + select { + case <-lmsgC: + log.Debug("lnode ok") + case cerr := <-lctx.Done(): + t.Fatalf("test message timed out: %v", cerr) + } + select { + case <-rmsgC: + log.Debug("rnode ok") + case cerr := <-lctx.Done(): + t.Fatalf("test message timed out: %v", cerr) + } + + // sends ping asym, checks delivery + pssprotocols[lnodeinfo.ID].C <- false + select { + case <-lmsgC: + log.Debug("lnode ok") + case cerr := <-lctx.Done(): + t.Fatalf("test message timed out: %v", cerr) + } + select { + case <-rmsgC: + log.Debug("rnode ok") + case cerr := <-lctx.Done(): + t.Fatalf("test message timed out: %v", cerr) + } + rw := pssprotocols[lnodeinfo.ID].protocol.pubKeyRWPool[rpubkey] + pssprotocols[lnodeinfo.ID].protocol.RemovePeer(true, rpubkey) + if err := rw.WriteMsg(p2p.Msg{ + Size: 3, + Payload: bytes.NewReader([]byte("foo")), + }); err == nil { + t.Fatalf("expected error on write") + } +} diff --git a/swarm/pss/pss.go b/swarm/pss/pss.go new file mode 100644 index 0000000000..5c060b2486 --- /dev/null +++ b/swarm/pss/pss.go @@ -0,0 +1,952 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package pss + +import ( + "bytes" + "context" + "crypto/ecdsa" + "crypto/rand" + "errors" + "fmt" + "sync" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/metrics" + "github.com/ethereum/go-ethereum/p2p" + "github.com/ethereum/go-ethereum/p2p/discover" + "github.com/ethereum/go-ethereum/p2p/protocols" + "github.com/ethereum/go-ethereum/rpc" + "github.com/ethereum/go-ethereum/swarm/log" + "github.com/ethereum/go-ethereum/swarm/network" + "github.com/ethereum/go-ethereum/swarm/pot" + "github.com/ethereum/go-ethereum/swarm/storage" + whisper "github.com/ethereum/go-ethereum/whisper/whisperv5" +) + +const ( + defaultPaddingByteSize = 16 + DefaultMsgTTL = time.Second * 120 + defaultDigestCacheTTL = time.Second * 10 + defaultSymKeyCacheCapacity = 512 + digestLength = 32 // byte length of digest used for pss cache (currently same as swarm chunk hash) + defaultWhisperWorkTime = 3 + defaultWhisperPoW = 0.0000000001 + defaultMaxMsgSize = 1024 * 1024 + defaultCleanInterval = time.Second * 60 * 10 + defaultOutboxCapacity = 100000 + pssProtocolName = "pss" + pssVersion = 2 + hasherCount = 8 +) + +var ( + addressLength = len(pot.Address{}) +) + +// cache is used for preventing backwards routing +// will also be instrumental in flood guard mechanism +// and mailbox implementation +type pssCacheEntry struct { + expiresAt time.Time +} + +// abstraction to enable access to p2p.protocols.Peer.Send +type senderPeer interface { + Info() *p2p.PeerInfo + ID() discover.NodeID + Address() []byte + Send(context.Context, interface{}) error +} + +// per-key peer related information +// member `protected` prevents garbage collection of the instance +type pssPeer struct { + lastSeen time.Time + address *PssAddress + protected bool +} + +// Pss configuration parameters +type PssParams struct { + MsgTTL time.Duration + CacheTTL time.Duration + privateKey *ecdsa.PrivateKey + SymKeyCacheCapacity int + AllowRaw bool // If true, enables sending and receiving messages without builtin pss encryption +} + +// Sane defaults for Pss +func NewPssParams() *PssParams { + return &PssParams{ + MsgTTL: DefaultMsgTTL, + CacheTTL: defaultDigestCacheTTL, + SymKeyCacheCapacity: defaultSymKeyCacheCapacity, + } +} + +func (params *PssParams) WithPrivateKey(privatekey *ecdsa.PrivateKey) *PssParams { + params.privateKey = privatekey + return params +} + +// Toplevel pss object, takes care of message sending, receiving, decryption and encryption, message handler dispatchers and message forwarding. +// +// Implements node.Service +type Pss struct { + network.Overlay // we can get the overlayaddress from this + privateKey *ecdsa.PrivateKey // pss can have it's own independent key + w *whisper.Whisper // key and encryption backend + auxAPIs []rpc.API // builtins (handshake, test) can add APIs + + // sending and forwarding + fwdPool map[string]*protocols.Peer // keep track of all peers sitting on the pssmsg routing layer + fwdPoolMu sync.RWMutex + fwdCache map[pssDigest]pssCacheEntry // checksum of unique fields from pssmsg mapped to expiry, cache to determine whether to drop msg + fwdCacheMu sync.RWMutex + cacheTTL time.Duration // how long to keep messages in fwdCache (not implemented) + msgTTL time.Duration + paddingByteSize int + capstring string + outbox chan *PssMsg + + // keys and peers + pubKeyPool map[string]map[Topic]*pssPeer // mapping of hex public keys to peer address by topic. + pubKeyPoolMu sync.RWMutex + symKeyPool map[string]map[Topic]*pssPeer // mapping of symkeyids to peer address by topic. + symKeyPoolMu sync.RWMutex + symKeyDecryptCache []*string // fast lookup of symkeys recently used for decryption; last used is on top of stack + symKeyDecryptCacheCursor int // modular cursor pointing to last used, wraps on symKeyDecryptCache array + symKeyDecryptCacheCapacity int // max amount of symkeys to keep. + + // message handling + handlers map[Topic]map[*Handler]bool // topic and version based pss payload handlers. See pss.Handle() + handlersMu sync.RWMutex + allowRaw bool + hashPool sync.Pool + + // process + quitC chan struct{} +} + +func (p *Pss) String() string { + return fmt.Sprintf("pss: addr %x, pubkey %v", p.BaseAddr(), common.ToHex(crypto.FromECDSAPub(&p.privateKey.PublicKey))) +} + +// Creates a new Pss instance. +// +// In addition to params, it takes a swarm network overlay +// and a FileStore storage for message cache storage. +func NewPss(k network.Overlay, params *PssParams) (*Pss, error) { + if params.privateKey == nil { + return nil, errors.New("missing private key for pss") + } + cap := p2p.Cap{ + Name: pssProtocolName, + Version: pssVersion, + } + ps := &Pss{ + Overlay: k, + privateKey: params.privateKey, + w: whisper.New(&whisper.DefaultConfig), + quitC: make(chan struct{}), + + fwdPool: make(map[string]*protocols.Peer), + fwdCache: make(map[pssDigest]pssCacheEntry), + cacheTTL: params.CacheTTL, + msgTTL: params.MsgTTL, + paddingByteSize: defaultPaddingByteSize, + capstring: cap.String(), + outbox: make(chan *PssMsg, defaultOutboxCapacity), + + pubKeyPool: make(map[string]map[Topic]*pssPeer), + symKeyPool: make(map[string]map[Topic]*pssPeer), + symKeyDecryptCache: make([]*string, params.SymKeyCacheCapacity), + symKeyDecryptCacheCapacity: params.SymKeyCacheCapacity, + + handlers: make(map[Topic]map[*Handler]bool), + allowRaw: params.AllowRaw, + hashPool: sync.Pool{ + New: func() interface{} { + return storage.MakeHashFunc(storage.DefaultHash)() + }, + }, + } + + for i := 0; i < hasherCount; i++ { + hashfunc := storage.MakeHashFunc(storage.DefaultHash)() + ps.hashPool.Put(hashfunc) + } + + return ps, nil +} + +///////////////////////////////////////////////////////////////////// +// SECTION: node.Service interface +///////////////////////////////////////////////////////////////////// + +func (p *Pss) Start(srv *p2p.Server) error { + go func() { + ticker := time.NewTicker(defaultCleanInterval) + cacheTicker := time.NewTicker(p.cacheTTL) + defer ticker.Stop() + defer cacheTicker.Stop() + for { + select { + case <-cacheTicker.C: + p.cleanFwdCache() + case <-ticker.C: + p.cleanKeys() + case <-p.quitC: + return + } + } + }() + go func() { + for { + select { + case msg := <-p.outbox: + err := p.forward(msg) + if err != nil { + log.Error(err.Error()) + metrics.GetOrRegisterCounter("pss.forward.err", nil).Inc(1) + } + case <-p.quitC: + return + } + } + }() + log.Debug("Started pss", "public key", common.ToHex(crypto.FromECDSAPub(p.PublicKey()))) + return nil +} + +func (p *Pss) Stop() error { + log.Info("pss shutting down") + close(p.quitC) + return nil +} + +var pssSpec = &protocols.Spec{ + Name: pssProtocolName, + Version: pssVersion, + MaxMsgSize: defaultMaxMsgSize, + Messages: []interface{}{ + PssMsg{}, + }, +} + +func (p *Pss) Protocols() []p2p.Protocol { + return []p2p.Protocol{ + { + Name: pssSpec.Name, + Version: pssSpec.Version, + Length: pssSpec.Length(), + Run: p.Run, + }, + } +} + +func (p *Pss) Run(peer *p2p.Peer, rw p2p.MsgReadWriter) error { + pp := protocols.NewPeer(peer, rw, pssSpec) + p.fwdPoolMu.Lock() + p.fwdPool[peer.Info().ID] = pp + p.fwdPoolMu.Unlock() + return pp.Run(p.handlePssMsg) +} + +func (p *Pss) APIs() []rpc.API { + apis := []rpc.API{ + { + Namespace: "pss", + Version: "1.0", + Service: NewAPI(p), + Public: true, + }, + } + apis = append(apis, p.auxAPIs...) + return apis +} + +// add API methods to the pss API +// must be run before node is started +func (p *Pss) addAPI(api rpc.API) { + p.auxAPIs = append(p.auxAPIs, api) +} + +// Returns the swarm overlay address of the pss node +func (p *Pss) BaseAddr() []byte { + return p.Overlay.BaseAddr() +} + +// Returns the pss node's public key +func (p *Pss) PublicKey() *ecdsa.PublicKey { + return &p.privateKey.PublicKey +} + +///////////////////////////////////////////////////////////////////// +// SECTION: Message handling +///////////////////////////////////////////////////////////////////// + +// Links a handler function to a Topic +// +// All incoming messages with an envelope Topic matching the +// topic specified will be passed to the given Handler function. +// +// There may be an arbitrary number of handler functions per topic. +// +// Returns a deregister function which needs to be called to +// deregister the handler, +func (p *Pss) Register(topic *Topic, handler Handler) func() { + p.handlersMu.Lock() + defer p.handlersMu.Unlock() + handlers := p.handlers[*topic] + if handlers == nil { + handlers = make(map[*Handler]bool) + p.handlers[*topic] = handlers + } + handlers[&handler] = true + return func() { p.deregister(topic, &handler) } +} +func (p *Pss) deregister(topic *Topic, h *Handler) { + p.handlersMu.Lock() + defer p.handlersMu.Unlock() + handlers := p.handlers[*topic] + if len(handlers) == 1 { + delete(p.handlers, *topic) + return + } + delete(handlers, h) +} + +// get all registered handlers for respective topics +func (p *Pss) getHandlers(topic Topic) map[*Handler]bool { + p.handlersMu.RLock() + defer p.handlersMu.RUnlock() + return p.handlers[topic] +} + +// Filters incoming messages for processing or forwarding. +// Check if address partially matches +// If yes, it CAN be for us, and we process it +// Only passes error to pss protocol handler if payload is not valid pssmsg +func (p *Pss) handlePssMsg(ctx context.Context, msg interface{}) error { + metrics.GetOrRegisterCounter("pss.handlepssmsg", nil).Inc(1) + + pssmsg, ok := msg.(*PssMsg) + + if !ok { + return fmt.Errorf("invalid message type. Expected *PssMsg, got %T ", msg) + } + if int64(pssmsg.Expire) < time.Now().Unix() { + metrics.GetOrRegisterCounter("pss.expire", nil).Inc(1) + log.Warn("pss filtered expired message", "from", common.ToHex(p.Overlay.BaseAddr()), "to", common.ToHex(pssmsg.To)) + return nil + } + if p.checkFwdCache(pssmsg) { + log.Trace("pss relay block-cache match (process)", "from", common.ToHex(p.Overlay.BaseAddr()), "to", (common.ToHex(pssmsg.To))) + return nil + } + p.addFwdCache(pssmsg) + + if !p.isSelfPossibleRecipient(pssmsg) { + log.Trace("pss was for someone else :'( ... forwarding", "pss", common.ToHex(p.BaseAddr())) + return p.enqueue(pssmsg) + } + + log.Trace("pss for us, yay! ... let's process!", "pss", common.ToHex(p.BaseAddr())) + if err := p.process(pssmsg); err != nil { + qerr := p.enqueue(pssmsg) + if qerr != nil { + return fmt.Errorf("process fail: processerr %v, queueerr: %v", err, qerr) + } + } + return nil + +} + +// Entry point to processing a message for which the current node can be the intended recipient. +// Attempts symmetric and asymmetric decryption with stored keys. +// Dispatches message to all handlers matching the message topic +func (p *Pss) process(pssmsg *PssMsg) error { + metrics.GetOrRegisterCounter("pss.process", nil).Inc(1) + + var err error + var recvmsg *whisper.ReceivedMessage + var payload []byte + var from *PssAddress + var asymmetric bool + var keyid string + var keyFunc func(envelope *whisper.Envelope) (*whisper.ReceivedMessage, string, *PssAddress, error) + + envelope := pssmsg.Payload + psstopic := Topic(envelope.Topic) + if pssmsg.isRaw() { + if !p.allowRaw { + return errors.New("raw message support disabled") + } + payload = pssmsg.Payload.Data + } else { + if pssmsg.isSym() { + keyFunc = p.processSym + } else { + asymmetric = true + keyFunc = p.processAsym + } + + recvmsg, keyid, from, err = keyFunc(envelope) + if err != nil { + return errors.New("Decryption failed") + } + payload = recvmsg.Payload + } + + if len(pssmsg.To) < addressLength { + if err := p.enqueue(pssmsg); err != nil { + return err + } + } + p.executeHandlers(psstopic, payload, from, asymmetric, keyid) + + return nil + +} + +func (p *Pss) executeHandlers(topic Topic, payload []byte, from *PssAddress, asymmetric bool, keyid string) { + handlers := p.getHandlers(topic) + nid, _ := discover.HexID("0x00") // this hack is needed to satisfy the p2p method + peer := p2p.NewPeer(nid, fmt.Sprintf("%x", from), []p2p.Cap{}) + for f := range handlers { + err := (*f)(payload, peer, asymmetric, keyid) + if err != nil { + log.Warn("Pss handler %p failed: %v", f, err) + } + } +} + +// will return false if using partial address +func (p *Pss) isSelfRecipient(msg *PssMsg) bool { + return bytes.Equal(msg.To, p.Overlay.BaseAddr()) +} + +// test match of leftmost bytes in given message to node's overlay address +func (p *Pss) isSelfPossibleRecipient(msg *PssMsg) bool { + local := p.Overlay.BaseAddr() + return bytes.Equal(msg.To[:], local[:len(msg.To)]) +} + +///////////////////////////////////////////////////////////////////// +// SECTION: Encryption +///////////////////////////////////////////////////////////////////// + +// Links a peer ECDSA public key to a topic +// +// This is required for asymmetric message exchange +// on the given topic +// +// The value in `address` will be used as a routing hint for the +// public key / topic association +func (p *Pss) SetPeerPublicKey(pubkey *ecdsa.PublicKey, topic Topic, address *PssAddress) error { + pubkeybytes := crypto.FromECDSAPub(pubkey) + if len(pubkeybytes) == 0 { + return fmt.Errorf("invalid public key: %v", pubkey) + } + pubkeyid := common.ToHex(pubkeybytes) + psp := &pssPeer{ + address: address, + } + p.pubKeyPoolMu.Lock() + if _, ok := p.pubKeyPool[pubkeyid]; !ok { + p.pubKeyPool[pubkeyid] = make(map[Topic]*pssPeer) + } + p.pubKeyPool[pubkeyid][topic] = psp + p.pubKeyPoolMu.Unlock() + log.Trace("added pubkey", "pubkeyid", pubkeyid, "topic", topic, "address", common.ToHex(*address)) + return nil +} + +// Automatically generate a new symkey for a topic and address hint +func (p *Pss) GenerateSymmetricKey(topic Topic, address *PssAddress, addToCache bool) (string, error) { + keyid, err := p.w.GenerateSymKey() + if err != nil { + return "", err + } + p.addSymmetricKeyToPool(keyid, topic, address, addToCache, false) + return keyid, nil +} + +// Links a peer symmetric key (arbitrary byte sequence) to a topic +// +// This is required for symmetrically encrypted message exchange +// on the given topic +// +// The key is stored in the whisper backend. +// +// If addtocache is set to true, the key will be added to the cache of keys +// used to attempt symmetric decryption of incoming messages. +// +// Returns a string id that can be used to retrieve the key bytes +// from the whisper backend (see pss.GetSymmetricKey()) +func (p *Pss) SetSymmetricKey(key []byte, topic Topic, address *PssAddress, addtocache bool) (string, error) { + return p.setSymmetricKey(key, topic, address, addtocache, true) +} + +func (p *Pss) setSymmetricKey(key []byte, topic Topic, address *PssAddress, addtocache bool, protected bool) (string, error) { + keyid, err := p.w.AddSymKeyDirect(key) + if err != nil { + return "", err + } + p.addSymmetricKeyToPool(keyid, topic, address, addtocache, protected) + return keyid, nil +} + +// adds a symmetric key to the pss key pool, and optionally adds the key +// to the collection of keys used to attempt symmetric decryption of +// incoming messages +func (p *Pss) addSymmetricKeyToPool(keyid string, topic Topic, address *PssAddress, addtocache bool, protected bool) { + psp := &pssPeer{ + address: address, + protected: protected, + } + p.symKeyPoolMu.Lock() + if _, ok := p.symKeyPool[keyid]; !ok { + p.symKeyPool[keyid] = make(map[Topic]*pssPeer) + } + p.symKeyPool[keyid][topic] = psp + p.symKeyPoolMu.Unlock() + if addtocache { + p.symKeyDecryptCacheCursor++ + p.symKeyDecryptCache[p.symKeyDecryptCacheCursor%cap(p.symKeyDecryptCache)] = &keyid + } + key, _ := p.GetSymmetricKey(keyid) + log.Trace("added symkey", "symkeyid", keyid, "symkey", common.ToHex(key), "topic", topic, "address", fmt.Sprintf("%p", address), "cache", addtocache) +} + +// Returns a symmetric key byte seqyence stored in the whisper backend +// by its unique id +// +// Passes on the error value from the whisper backend +func (p *Pss) GetSymmetricKey(symkeyid string) ([]byte, error) { + symkey, err := p.w.GetSymKey(symkeyid) + if err != nil { + return nil, err + } + return symkey, nil +} + +// Returns all recorded topic and address combination for a specific public key +func (p *Pss) GetPublickeyPeers(keyid string) (topic []Topic, address []PssAddress, err error) { + p.pubKeyPoolMu.RLock() + defer p.pubKeyPoolMu.RUnlock() + for t, peer := range p.pubKeyPool[keyid] { + topic = append(topic, t) + address = append(address, *peer.address) + } + + return topic, address, nil +} + +func (p *Pss) getPeerAddress(keyid string, topic Topic) (PssAddress, error) { + p.pubKeyPoolMu.RLock() + defer p.pubKeyPoolMu.RUnlock() + if peers, ok := p.pubKeyPool[keyid]; ok { + if t, ok := peers[topic]; ok { + return *t.address, nil + } + } + return nil, fmt.Errorf("peer with pubkey %s, topic %x not found", keyid, topic) +} + +// Attempt to decrypt, validate and unpack a +// symmetrically encrypted message +// If successful, returns the unpacked whisper ReceivedMessage struct +// encapsulating the decrypted message, and the whisper backend id +// of the symmetric key used to decrypt the message. +// It fails if decryption of the message fails or if the message is corrupted +func (p *Pss) processSym(envelope *whisper.Envelope) (*whisper.ReceivedMessage, string, *PssAddress, error) { + metrics.GetOrRegisterCounter("pss.process.sym", nil).Inc(1) + + for i := p.symKeyDecryptCacheCursor; i > p.symKeyDecryptCacheCursor-cap(p.symKeyDecryptCache) && i > 0; i-- { + symkeyid := p.symKeyDecryptCache[i%cap(p.symKeyDecryptCache)] + symkey, err := p.w.GetSymKey(*symkeyid) + if err != nil { + continue + } + recvmsg, err := envelope.OpenSymmetric(symkey) + if err != nil { + continue + } + if !recvmsg.Validate() { + return nil, "", nil, fmt.Errorf("symmetrically encrypted message has invalid signature or is corrupt") + } + p.symKeyPoolMu.Lock() + from := p.symKeyPool[*symkeyid][Topic(envelope.Topic)].address + p.symKeyPoolMu.Unlock() + p.symKeyDecryptCacheCursor++ + p.symKeyDecryptCache[p.symKeyDecryptCacheCursor%cap(p.symKeyDecryptCache)] = symkeyid + return recvmsg, *symkeyid, from, nil + } + return nil, "", nil, fmt.Errorf("could not decrypt message") +} + +// Attempt to decrypt, validate and unpack an +// asymmetrically encrypted message +// If successful, returns the unpacked whisper ReceivedMessage struct +// encapsulating the decrypted message, and the byte representation of +// the public key used to decrypt the message. +// It fails if decryption of message fails, or if the message is corrupted +func (p *Pss) processAsym(envelope *whisper.Envelope) (*whisper.ReceivedMessage, string, *PssAddress, error) { + metrics.GetOrRegisterCounter("pss.process.asym", nil).Inc(1) + + recvmsg, err := envelope.OpenAsymmetric(p.privateKey) + if err != nil { + return nil, "", nil, fmt.Errorf("could not decrypt message: %s", err) + } + // check signature (if signed), strip padding + if !recvmsg.Validate() { + return nil, "", nil, fmt.Errorf("invalid message") + } + pubkeyid := common.ToHex(crypto.FromECDSAPub(recvmsg.Src)) + var from *PssAddress + p.pubKeyPoolMu.Lock() + if p.pubKeyPool[pubkeyid][Topic(envelope.Topic)] != nil { + from = p.pubKeyPool[pubkeyid][Topic(envelope.Topic)].address + } + p.pubKeyPoolMu.Unlock() + return recvmsg, pubkeyid, from, nil +} + +// Symkey garbage collection +// a key is removed if: +// - it is not marked as protected +// - it is not in the incoming decryption cache +func (p *Pss) cleanKeys() (count int) { + for keyid, peertopics := range p.symKeyPool { + var expiredtopics []Topic + for topic, psp := range peertopics { + if psp.protected { + continue + } + + var match bool + for i := p.symKeyDecryptCacheCursor; i > p.symKeyDecryptCacheCursor-cap(p.symKeyDecryptCache) && i > 0; i-- { + cacheid := p.symKeyDecryptCache[i%cap(p.symKeyDecryptCache)] + if *cacheid == keyid { + match = true + } + } + if !match { + expiredtopics = append(expiredtopics, topic) + } + } + for _, topic := range expiredtopics { + p.symKeyPoolMu.Lock() + delete(p.symKeyPool[keyid], topic) + log.Trace("symkey cleanup deletion", "symkeyid", keyid, "topic", topic, "val", p.symKeyPool[keyid]) + p.symKeyPoolMu.Unlock() + count++ + } + } + return +} + +///////////////////////////////////////////////////////////////////// +// SECTION: Message sending +///////////////////////////////////////////////////////////////////// + +func (p *Pss) enqueue(msg *PssMsg) error { + select { + case p.outbox <- msg: + return nil + default: + } + + metrics.GetOrRegisterCounter("pss.enqueue.outbox.full", nil).Inc(1) + return errors.New("outbox full") +} + +// Send a raw message (any encryption is responsibility of calling client) +// +// Will fail if raw messages are disallowed +func (p *Pss) SendRaw(address PssAddress, topic Topic, msg []byte) error { + if !p.allowRaw { + return errors.New("Raw messages not enabled") + } + pssMsgParams := &msgParams{ + raw: true, + } + payload := &whisper.Envelope{ + Data: msg, + Topic: whisper.TopicType(topic), + } + pssMsg := newPssMsg(pssMsgParams) + pssMsg.To = address + pssMsg.Expire = uint32(time.Now().Add(p.msgTTL).Unix()) + pssMsg.Payload = payload + p.addFwdCache(pssMsg) + return p.enqueue(pssMsg) +} + +// Send a message using symmetric encryption +// +// Fails if the key id does not match any of the stored symmetric keys +func (p *Pss) SendSym(symkeyid string, topic Topic, msg []byte) error { + symkey, err := p.GetSymmetricKey(symkeyid) + if err != nil { + return fmt.Errorf("missing valid send symkey %s: %v", symkeyid, err) + } + p.symKeyPoolMu.Lock() + psp, ok := p.symKeyPool[symkeyid][topic] + p.symKeyPoolMu.Unlock() + if !ok { + return fmt.Errorf("invalid topic '%s' for symkey '%s'", topic.String(), symkeyid) + } else if psp.address == nil { + return fmt.Errorf("no address hint for topic '%s' symkey '%s'", topic.String(), symkeyid) + } + err = p.send(*psp.address, topic, msg, false, symkey) + return err +} + +// Send a message using asymmetric encryption +// +// Fails if the key id does not match any in of the stored public keys +func (p *Pss) SendAsym(pubkeyid string, topic Topic, msg []byte) error { + if _, err := crypto.UnmarshalPubkey(common.FromHex(pubkeyid)); err != nil { + return fmt.Errorf("Cannot unmarshal pubkey: %x", pubkeyid) + } + p.pubKeyPoolMu.Lock() + psp, ok := p.pubKeyPool[pubkeyid][topic] + p.pubKeyPoolMu.Unlock() + if !ok { + return fmt.Errorf("invalid topic '%s' for pubkey '%s'", topic.String(), pubkeyid) + } else if psp.address == nil { + return fmt.Errorf("no address hint for topic '%s' pubkey '%s'", topic.String(), pubkeyid) + } + go func() { + p.send(*psp.address, topic, msg, true, common.FromHex(pubkeyid)) + }() + return nil +} + +// Send is payload agnostic, and will accept any byte slice as payload +// It generates an whisper envelope for the specified recipient and topic, +// and wraps the message payload in it. +// TODO: Implement proper message padding +func (p *Pss) send(to []byte, topic Topic, msg []byte, asymmetric bool, key []byte) error { + metrics.GetOrRegisterCounter("pss.send", nil).Inc(1) + + if key == nil || bytes.Equal(key, []byte{}) { + return fmt.Errorf("Zero length key passed to pss send") + } + padding := make([]byte, p.paddingByteSize) + c, err := rand.Read(padding) + if err != nil { + return err + } else if c < p.paddingByteSize { + return fmt.Errorf("invalid padding length: %d", c) + } + wparams := &whisper.MessageParams{ + TTL: defaultWhisperTTL, + Src: p.privateKey, + Topic: whisper.TopicType(topic), + WorkTime: defaultWhisperWorkTime, + PoW: defaultWhisperPoW, + Payload: msg, + Padding: padding, + } + if asymmetric { + pk, err := crypto.UnmarshalPubkey(key) + if err != nil { + return fmt.Errorf("Cannot unmarshal pubkey: %x", key) + } + wparams.Dst = pk + } else { + wparams.KeySym = key + } + // set up outgoing message container, which does encryption and envelope wrapping + woutmsg, err := whisper.NewSentMessage(wparams) + if err != nil { + return fmt.Errorf("failed to generate whisper message encapsulation: %v", err) + } + // performs encryption. + // Does NOT perform / performs negligible PoW due to very low difficulty setting + // after this the message is ready for sending + envelope, err := woutmsg.Wrap(wparams) + if err != nil { + return fmt.Errorf("failed to perform whisper encryption: %v", err) + } + log.Trace("pssmsg whisper done", "env", envelope, "wparams payload", common.ToHex(wparams.Payload), "to", common.ToHex(to), "asym", asymmetric, "key", common.ToHex(key)) + + // prepare for devp2p transport + pssMsgParams := &msgParams{ + sym: !asymmetric, + } + pssMsg := newPssMsg(pssMsgParams) + pssMsg.To = to + pssMsg.Expire = uint32(time.Now().Add(p.msgTTL).Unix()) + pssMsg.Payload = envelope + return p.enqueue(pssMsg) +} + +// Forwards a pss message to the peer(s) closest to the to recipient address in the PssMsg struct +// The recipient address can be of any length, and the byte slice will be matched to the MSB slice +// of the peer address of the equivalent length. +func (p *Pss) forward(msg *PssMsg) error { + metrics.GetOrRegisterCounter("pss.forward", nil).Inc(1) + + to := make([]byte, addressLength) + copy(to[:len(msg.To)], msg.To) + + // send with kademlia + // find the closest peer to the recipient and attempt to send + sent := 0 + p.Overlay.EachConn(to, 256, func(op network.OverlayConn, po int, isproxbin bool) bool { + // we need p2p.protocols.Peer.Send + // cast and resolve + sp, ok := op.(senderPeer) + if !ok { + log.Crit("Pss cannot use kademlia peer type") + return false + } + info := sp.Info() + + // check if the peer is running pss + var ispss bool + for _, cap := range info.Caps { + if cap == p.capstring { + ispss = true + break + } + } + if !ispss { + log.Trace("peer doesn't have matching pss capabilities, skipping", "peer", info.Name, "caps", info.Caps) + return true + } + + // get the protocol peer from the forwarding peer cache + sendMsg := fmt.Sprintf("MSG TO %x FROM %x VIA %x", to, p.BaseAddr(), op.Address()) + p.fwdPoolMu.RLock() + pp := p.fwdPool[sp.Info().ID] + p.fwdPoolMu.RUnlock() + + // attempt to send the message + err := pp.Send(context.TODO(), msg) + if err != nil { + metrics.GetOrRegisterCounter("pss.pp.send.error", nil).Inc(1) + log.Error(err.Error()) + return true + } + sent++ + log.Trace(fmt.Sprintf("%v: successfully forwarded", sendMsg)) + + // continue forwarding if: + // - if the peer is end recipient but the full address has not been disclosed + // - if the peer address matches the partial address fully + // - if the peer is in proxbin + if len(msg.To) < addressLength && bytes.Equal(msg.To, op.Address()[:len(msg.To)]) { + log.Trace(fmt.Sprintf("Pss keep forwarding: Partial address + full partial match")) + return true + } else if isproxbin { + log.Trace(fmt.Sprintf("%x is in proxbin, keep forwarding", common.ToHex(op.Address()))) + return true + } + // at this point we stop forwarding, and the state is as follows: + // - the peer is end recipient and we have full address + // - we are not in proxbin (directed routing) + // - partial addresses don't fully match + return false + }) + + if sent == 0 { + log.Debug("unable to forward to any peers") + if err := p.enqueue(msg); err != nil { + metrics.GetOrRegisterCounter("pss.forward.enqueue.error", nil).Inc(1) + log.Error(err.Error()) + return err + } + } + + // cache the message + p.addFwdCache(msg) + return nil +} + +///////////////////////////////////////////////////////////////////// +// SECTION: Caching +///////////////////////////////////////////////////////////////////// + +// cleanFwdCache is used to periodically remove expired entries from the forward cache +func (p *Pss) cleanFwdCache() { + metrics.GetOrRegisterCounter("pss.cleanfwdcache", nil).Inc(1) + p.fwdCacheMu.Lock() + defer p.fwdCacheMu.Unlock() + for k, v := range p.fwdCache { + if v.expiresAt.Before(time.Now()) { + delete(p.fwdCache, k) + } + } +} + +// add a message to the cache +func (p *Pss) addFwdCache(msg *PssMsg) error { + metrics.GetOrRegisterCounter("pss.addfwdcache", nil).Inc(1) + + var entry pssCacheEntry + var ok bool + + p.fwdCacheMu.Lock() + defer p.fwdCacheMu.Unlock() + + digest := p.digest(msg) + if entry, ok = p.fwdCache[digest]; !ok { + entry = pssCacheEntry{} + } + entry.expiresAt = time.Now().Add(p.cacheTTL) + p.fwdCache[digest] = entry + return nil +} + +// check if message is in the cache +func (p *Pss) checkFwdCache(msg *PssMsg) bool { + p.fwdCacheMu.Lock() + defer p.fwdCacheMu.Unlock() + + digest := p.digest(msg) + entry, ok := p.fwdCache[digest] + if ok { + if entry.expiresAt.After(time.Now()) { + log.Trace("unexpired cache", "digest", fmt.Sprintf("%x", digest)) + metrics.GetOrRegisterCounter("pss.checkfwdcache.unexpired", nil).Inc(1) + return true + } + metrics.GetOrRegisterCounter("pss.checkfwdcache.expired", nil).Inc(1) + } + return false +} + +// Digest of message +func (p *Pss) digest(msg *PssMsg) pssDigest { + hasher := p.hashPool.Get().(storage.SwarmHash) + defer p.hashPool.Put(hasher) + hasher.Reset() + hasher.Write(msg.serialize()) + digest := pssDigest{} + key := hasher.Sum(nil) + copy(digest[:], key[:digestLength]) + return digest +} diff --git a/swarm/pss/pss_test.go b/swarm/pss/pss_test.go new file mode 100644 index 0000000000..41b03db286 --- /dev/null +++ b/swarm/pss/pss_test.go @@ -0,0 +1,1697 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package pss + +import ( + "bytes" + "context" + "crypto/ecdsa" + "encoding/binary" + "encoding/hex" + "encoding/json" + "flag" + "fmt" + "io/ioutil" + "math/rand" + "os" + "strconv" + "strings" + "sync" + "testing" + "time" + + "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/metrics" + "github.com/ethereum/go-ethereum/metrics/influxdb" + "github.com/ethereum/go-ethereum/node" + "github.com/ethereum/go-ethereum/p2p" + "github.com/ethereum/go-ethereum/p2p/discover" + "github.com/ethereum/go-ethereum/p2p/protocols" + "github.com/ethereum/go-ethereum/p2p/simulations" + "github.com/ethereum/go-ethereum/p2p/simulations/adapters" + "github.com/ethereum/go-ethereum/rpc" + "github.com/ethereum/go-ethereum/swarm/network" + "github.com/ethereum/go-ethereum/swarm/state" + whisper "github.com/ethereum/go-ethereum/whisper/whisperv5" +) + +var ( + initOnce = sync.Once{} + debugdebugflag = flag.Bool("vv", false, "veryverbose") + debugflag = flag.Bool("v", false, "verbose") + longrunning = flag.Bool("longrunning", false, "do run long-running tests") + w *whisper.Whisper + wapi *whisper.PublicWhisperAPI + psslogmain log.Logger + pssprotocols map[string]*protoCtrl + useHandshake bool +) + +func init() { + flag.Parse() + rand.Seed(time.Now().Unix()) + + adapters.RegisterServices(newServices(false)) + initTest() +} + +func initTest() { + initOnce.Do( + func() { + loglevel := log.LvlInfo + if *debugflag { + loglevel = log.LvlDebug + } else if *debugdebugflag { + loglevel = log.LvlTrace + } + + psslogmain = log.New("psslog", "*") + hs := log.StreamHandler(os.Stderr, log.TerminalFormat(true)) + hf := log.LvlFilterHandler(loglevel, hs) + h := log.CallerFileHandler(hf) + log.Root().SetHandler(h) + + w = whisper.New(&whisper.DefaultConfig) + wapi = whisper.NewPublicWhisperAPI(w) + + pssprotocols = make(map[string]*protoCtrl) + }, + ) +} + +// test that topic conversion functions give predictable results +func TestTopic(t *testing.T) { + + api := &API{} + + topicstr := strings.Join([]string{PingProtocol.Name, strconv.Itoa(int(PingProtocol.Version))}, ":") + + // bytestotopic is the authoritative topic conversion source + topicobj := BytesToTopic([]byte(topicstr)) + + // string to topic and bytes to topic must match + topicapiobj, _ := api.StringToTopic(topicstr) + if topicobj != topicapiobj { + t.Fatalf("bytes and string topic conversion mismatch; %s != %s", topicobj, topicapiobj) + } + + // string representation of topichex + topichex := topicobj.String() + + // protocoltopic wrapper on pingtopic should be same as topicstring + // check that it matches + pingtopichex := PingTopic.String() + if topichex != pingtopichex { + t.Fatalf("protocol topic conversion mismatch; %s != %s", topichex, pingtopichex) + } + + // json marshal of topic + topicjsonout, err := topicobj.MarshalJSON() + if err != nil { + t.Fatal(err) + } + if string(topicjsonout)[1:len(topicjsonout)-1] != topichex { + t.Fatalf("topic json marshal mismatch; %s != \"%s\"", topicjsonout, topichex) + } + + // json unmarshal of topic + var topicjsonin Topic + topicjsonin.UnmarshalJSON(topicjsonout) + if topicjsonin != topicobj { + t.Fatalf("topic json unmarshal mismatch: %x != %x", topicjsonin, topicobj) + } +} + +// test bit packing of message control flags +func TestMsgParams(t *testing.T) { + var ctrl byte + ctrl |= pssControlRaw + p := newMsgParamsFromBytes([]byte{ctrl}) + m := newPssMsg(p) + if !m.isRaw() || m.isSym() { + t.Fatal("expected raw=true and sym=false") + } + ctrl |= pssControlSym + p = newMsgParamsFromBytes([]byte{ctrl}) + m = newPssMsg(p) + if !m.isRaw() || !m.isSym() { + t.Fatal("expected raw=true and sym=true") + } + ctrl &= 0xff &^ pssControlRaw + p = newMsgParamsFromBytes([]byte{ctrl}) + m = newPssMsg(p) + if m.isRaw() || !m.isSym() { + t.Fatal("expected raw=false and sym=true") + } +} + +// test if we can insert into cache, match items with cache and cache expiry +func TestCache(t *testing.T) { + var err error + to, _ := hex.DecodeString("08090a0b0c0d0e0f1011121314150001020304050607161718191a1b1c1d1e1f") + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + keys, err := wapi.NewKeyPair(ctx) + privkey, err := w.GetPrivateKey(keys) + if err != nil { + t.Fatal(err) + } + ps := newTestPss(privkey, nil, nil) + pp := NewPssParams().WithPrivateKey(privkey) + data := []byte("foo") + datatwo := []byte("bar") + datathree := []byte("baz") + wparams := &whisper.MessageParams{ + TTL: defaultWhisperTTL, + Src: privkey, + Dst: &privkey.PublicKey, + Topic: whisper.TopicType(PingTopic), + WorkTime: defaultWhisperWorkTime, + PoW: defaultWhisperPoW, + Payload: data, + } + woutmsg, err := whisper.NewSentMessage(wparams) + env, err := woutmsg.Wrap(wparams) + msg := &PssMsg{ + Payload: env, + To: to, + } + wparams.Payload = datatwo + woutmsg, err = whisper.NewSentMessage(wparams) + envtwo, err := woutmsg.Wrap(wparams) + msgtwo := &PssMsg{ + Payload: envtwo, + To: to, + } + wparams.Payload = datathree + woutmsg, err = whisper.NewSentMessage(wparams) + envthree, err := woutmsg.Wrap(wparams) + msgthree := &PssMsg{ + Payload: envthree, + To: to, + } + + digest := ps.digest(msg) + if err != nil { + t.Fatalf("could not store cache msgone: %v", err) + } + digesttwo := ps.digest(msgtwo) + if err != nil { + t.Fatalf("could not store cache msgtwo: %v", err) + } + digestthree := ps.digest(msgthree) + if err != nil { + t.Fatalf("could not store cache msgthree: %v", err) + } + + if digest == digesttwo { + t.Fatalf("different msgs return same hash: %d", digesttwo) + } + + // check the cache + err = ps.addFwdCache(msg) + if err != nil { + t.Fatalf("write to pss expire cache failed: %v", err) + } + + if !ps.checkFwdCache(msg) { + t.Fatalf("message %v should have EXPIRE record in cache but checkCache returned false", msg) + } + + if ps.checkFwdCache(msgtwo) { + t.Fatalf("message %v should NOT have EXPIRE record in cache but checkCache returned true", msgtwo) + } + + time.Sleep(pp.CacheTTL + 1*time.Second) + err = ps.addFwdCache(msgthree) + if err != nil { + t.Fatalf("write to pss expire cache failed: %v", err) + } + + if ps.checkFwdCache(msg) { + t.Fatalf("message %v should have expired from cache but checkCache returned true", msg) + } + + if _, ok := ps.fwdCache[digestthree]; !ok { + t.Fatalf("unexpired message should be in the cache: %v", digestthree) + } + + if _, ok := ps.fwdCache[digesttwo]; ok { + t.Fatalf("expired message should have been cleared from the cache: %v", digesttwo) + } +} + +// matching of address hints; whether a message could be or is for the node +func TestAddressMatch(t *testing.T) { + + localaddr := network.RandomAddr().Over() + copy(localaddr[:8], []byte("deadbeef")) + remoteaddr := []byte("feedbeef") + kadparams := network.NewKadParams() + kad := network.NewKademlia(localaddr, kadparams) + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + keys, err := wapi.NewKeyPair(ctx) + if err != nil { + t.Fatalf("Could not generate private key: %v", err) + } + privkey, err := w.GetPrivateKey(keys) + pssp := NewPssParams().WithPrivateKey(privkey) + ps, err := NewPss(kad, pssp) + if err != nil { + t.Fatal(err.Error()) + } + + pssmsg := &PssMsg{ + To: remoteaddr, + Payload: &whisper.Envelope{}, + } + + // differ from first byte + if ps.isSelfRecipient(pssmsg) { + t.Fatalf("isSelfRecipient true but %x != %x", remoteaddr, localaddr) + } + if ps.isSelfPossibleRecipient(pssmsg) { + t.Fatalf("isSelfPossibleRecipient true but %x != %x", remoteaddr[:8], localaddr[:8]) + } + + // 8 first bytes same + copy(remoteaddr[:4], localaddr[:4]) + if ps.isSelfRecipient(pssmsg) { + t.Fatalf("isSelfRecipient true but %x != %x", remoteaddr, localaddr) + } + if !ps.isSelfPossibleRecipient(pssmsg) { + t.Fatalf("isSelfPossibleRecipient false but %x == %x", remoteaddr[:8], localaddr[:8]) + } + + // all bytes same + pssmsg.To = localaddr + if !ps.isSelfRecipient(pssmsg) { + t.Fatalf("isSelfRecipient false but %x == %x", remoteaddr, localaddr) + } + if !ps.isSelfPossibleRecipient(pssmsg) { + t.Fatalf("isSelfPossibleRecipient false but %x == %x", remoteaddr[:8], localaddr[:8]) + } +} + +// +func TestHandlerConditions(t *testing.T) { + + t.Skip("Disabled due to probable faulty logic for outbox expectations") + // setup + privkey, err := crypto.GenerateKey() + if err != nil { + t.Fatal(err.Error()) + } + + addr := make([]byte, 32) + addr[0] = 0x01 + ps := newTestPss(privkey, network.NewKademlia(addr, network.NewKadParams()), NewPssParams()) + + // message should pass + msg := &PssMsg{ + To: addr, + Expire: uint32(time.Now().Add(time.Second * 60).Unix()), + Payload: &whisper.Envelope{ + Topic: [4]byte{}, + Data: []byte{0x66, 0x6f, 0x6f}, + }, + } + if err := ps.handlePssMsg(context.TODO(), msg); err != nil { + t.Fatal(err.Error()) + } + tmr := time.NewTimer(time.Millisecond * 100) + var outmsg *PssMsg + select { + case outmsg = <-ps.outbox: + case <-tmr.C: + default: + } + if outmsg != nil { + t.Fatalf("expected outbox empty after full address on msg, but had message %s", msg) + } + + // message should pass and queue due to partial length + msg.To = addr[0:1] + msg.Payload.Data = []byte{0x78, 0x79, 0x80, 0x80, 0x79} + if err := ps.handlePssMsg(context.TODO(), msg); err != nil { + t.Fatal(err.Error()) + } + tmr.Reset(time.Millisecond * 100) + outmsg = nil + select { + case outmsg = <-ps.outbox: + case <-tmr.C: + } + if outmsg == nil { + t.Fatal("expected message in outbox on encrypt fail, but empty") + } + outmsg = nil + select { + case outmsg = <-ps.outbox: + default: + } + if outmsg != nil { + t.Fatalf("expected only one queued message but also had message %v", msg) + } + + // full address mismatch should put message in queue + msg.To[0] = 0xff + if err := ps.handlePssMsg(context.TODO(), msg); err != nil { + t.Fatal(err.Error()) + } + tmr.Reset(time.Millisecond * 10) + outmsg = nil + select { + case outmsg = <-ps.outbox: + case <-tmr.C: + } + if outmsg == nil { + t.Fatal("expected message in outbox on address mismatch, but empty") + } + outmsg = nil + select { + case outmsg = <-ps.outbox: + default: + } + if outmsg != nil { + t.Fatalf("expected only one queued message but also had message %v", msg) + } + + // expired message should be dropped + msg.Expire = uint32(time.Now().Add(-time.Second).Unix()) + if err := ps.handlePssMsg(context.TODO(), msg); err != nil { + t.Fatal(err.Error()) + } + tmr.Reset(time.Millisecond * 10) + outmsg = nil + select { + case outmsg = <-ps.outbox: + case <-tmr.C: + default: + } + if outmsg != nil { + t.Fatalf("expected empty queue but have message %v", msg) + } + + // invalid message should return error + fckedupmsg := &struct { + pssMsg *PssMsg + }{ + pssMsg: &PssMsg{}, + } + if err := ps.handlePssMsg(context.TODO(), fckedupmsg); err == nil { + t.Fatalf("expected error from processMsg but error nil") + } + + // outbox full should return error + msg.Expire = uint32(time.Now().Add(time.Second * 60).Unix()) + for i := 0; i < defaultOutboxCapacity; i++ { + ps.outbox <- msg + } + msg.Payload.Data = []byte{0x62, 0x61, 0x72} + err = ps.handlePssMsg(context.TODO(), msg) + if err == nil { + t.Fatal("expected error when mailbox full, but was nil") + } +} + +// set and generate pubkeys and symkeys +func TestKeys(t *testing.T) { + // make our key and init pss with it + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + ourkeys, err := wapi.NewKeyPair(ctx) + if err != nil { + t.Fatalf("create 'our' key fail") + } + ctx, cancel2 := context.WithTimeout(context.Background(), time.Second) + defer cancel2() + theirkeys, err := wapi.NewKeyPair(ctx) + if err != nil { + t.Fatalf("create 'their' key fail") + } + ourprivkey, err := w.GetPrivateKey(ourkeys) + if err != nil { + t.Fatalf("failed to retrieve 'our' private key") + } + theirprivkey, err := w.GetPrivateKey(theirkeys) + if err != nil { + t.Fatalf("failed to retrieve 'their' private key") + } + ps := newTestPss(ourprivkey, nil, nil) + + // set up peer with mock address, mapped to mocked publicaddress and with mocked symkey + addr := make(PssAddress, 32) + copy(addr, network.RandomAddr().Over()) + outkey := network.RandomAddr().Over() + topicobj := BytesToTopic([]byte("foo:42")) + ps.SetPeerPublicKey(&theirprivkey.PublicKey, topicobj, &addr) + outkeyid, err := ps.SetSymmetricKey(outkey, topicobj, &addr, false) + if err != nil { + t.Fatalf("failed to set 'our' outgoing symmetric key") + } + + // make a symmetric key that we will send to peer for encrypting messages to us + inkeyid, err := ps.GenerateSymmetricKey(topicobj, &addr, true) + if err != nil { + t.Fatalf("failed to set 'our' incoming symmetric key") + } + + // get the key back from whisper, check that it's still the same + outkeyback, err := ps.w.GetSymKey(outkeyid) + if err != nil { + t.Fatalf(err.Error()) + } + inkey, err := ps.w.GetSymKey(inkeyid) + if err != nil { + t.Fatalf(err.Error()) + } + if !bytes.Equal(outkeyback, outkey) { + t.Fatalf("passed outgoing symkey doesnt equal stored: %x / %x", outkey, outkeyback) + } + + t.Logf("symout: %v", outkeyback) + t.Logf("symin: %v", inkey) + + // check that the key is stored in the peerpool + psp := ps.symKeyPool[inkeyid][topicobj] + if psp.address != &addr { + t.Fatalf("inkey address does not match; %p != %p", psp.address, &addr) + } +} + +func TestGetPublickeyEntries(t *testing.T) { + + privkey, err := crypto.GenerateKey() + if err != nil { + t.Fatal(err) + } + ps := newTestPss(privkey, nil, nil) + + peeraddr := network.RandomAddr().Over() + topicaddr := make(map[Topic]PssAddress) + topicaddr[Topic{0x13}] = peeraddr + topicaddr[Topic{0x2a}] = peeraddr[:16] + topicaddr[Topic{0x02, 0x9a}] = []byte{} + + remoteprivkey, err := crypto.GenerateKey() + if err != nil { + t.Fatal(err) + } + remotepubkeybytes := crypto.FromECDSAPub(&remoteprivkey.PublicKey) + remotepubkeyhex := common.ToHex(remotepubkeybytes) + + pssapi := NewAPI(ps) + + for to, a := range topicaddr { + err = pssapi.SetPeerPublicKey(remotepubkeybytes, to, a) + if err != nil { + t.Fatal(err) + } + } + + intopic, err := pssapi.GetPeerTopics(remotepubkeyhex) + if err != nil { + t.Fatal(err) + } + +OUTER: + for _, tnew := range intopic { + for torig, addr := range topicaddr { + if bytes.Equal(torig[:], tnew[:]) { + inaddr, err := pssapi.GetPeerAddress(remotepubkeyhex, torig) + if err != nil { + t.Fatal(err) + } + if !bytes.Equal(addr, inaddr) { + t.Fatalf("Address mismatch for topic %x; got %x, expected %x", torig, inaddr, addr) + } + delete(topicaddr, torig) + continue OUTER + } + } + t.Fatalf("received topic %x did not match any existing topics", tnew) + } + + if len(topicaddr) != 0 { + t.Fatalf("%d topics were not matched", len(topicaddr)) + } +} + +type pssTestPeer struct { + *protocols.Peer + addr []byte +} + +func (t *pssTestPeer) Address() []byte { + return t.addr +} + +func (t *pssTestPeer) Update(addr network.OverlayAddr) network.OverlayAddr { + return addr +} + +func (t *pssTestPeer) Off() network.OverlayAddr { + return &pssTestPeer{} +} + +// forwarding should skip peers that do not have matching pss capabilities +func TestMismatch(t *testing.T) { + + // create privkey for forwarder node + privkey, err := crypto.GenerateKey() + if err != nil { + t.Fatal(err) + } + + // initialize overlay + baseaddr := network.RandomAddr() + kad := network.NewKademlia((baseaddr).Over(), network.NewKadParams()) + rw := &p2p.MsgPipeRW{} + + // one peer has a mismatching version of pss + wrongpssaddr := network.RandomAddr() + wrongpsscap := p2p.Cap{ + Name: pssProtocolName, + Version: 0, + } + nid, _ := discover.HexID("0x01") + wrongpsspeer := &pssTestPeer{ + Peer: protocols.NewPeer(p2p.NewPeer(nid, common.ToHex(wrongpssaddr.Over()), []p2p.Cap{wrongpsscap}), rw, nil), + addr: wrongpssaddr.Over(), + } + + // one peer doesn't even have pss (boo!) + nopssaddr := network.RandomAddr() + nopsscap := p2p.Cap{ + Name: "nopss", + Version: 1, + } + nid, _ = discover.HexID("0x02") + nopsspeer := &pssTestPeer{ + Peer: protocols.NewPeer(p2p.NewPeer(nid, common.ToHex(nopssaddr.Over()), []p2p.Cap{nopsscap}), rw, nil), + addr: nopssaddr.Over(), + } + + // add peers to kademlia and activate them + // it's safe so don't check errors + kad.Register([]network.OverlayAddr{wrongpsspeer}) + kad.On(wrongpsspeer) + kad.Register([]network.OverlayAddr{nopsspeer}) + kad.On(nopsspeer) + + // create pss + pssmsg := &PssMsg{ + To: []byte{}, + Expire: uint32(time.Now().Add(time.Second).Unix()), + Payload: &whisper.Envelope{}, + } + ps := newTestPss(privkey, kad, nil) + + // run the forward + // it is enough that it completes; trying to send to incapable peers would create segfault + ps.forward(pssmsg) + +} + +func TestSendRaw(t *testing.T) { + t.Run("32", testSendRaw) + t.Run("8", testSendRaw) + t.Run("0", testSendRaw) +} + +func testSendRaw(t *testing.T) { + + var addrsize int64 + var err error + + paramstring := strings.Split(t.Name(), "/") + + addrsize, _ = strconv.ParseInt(paramstring[1], 10, 0) + log.Info("raw send test", "addrsize", addrsize) + + clients, err := setupNetwork(2, true) + if err != nil { + t.Fatal(err) + } + + topic := "0xdeadbeef" + + var loaddrhex string + err = clients[0].Call(&loaddrhex, "pss_baseAddr") + if err != nil { + t.Fatalf("rpc get node 1 baseaddr fail: %v", err) + } + loaddrhex = loaddrhex[:2+(addrsize*2)] + var roaddrhex string + err = clients[1].Call(&roaddrhex, "pss_baseAddr") + if err != nil { + t.Fatalf("rpc get node 2 baseaddr fail: %v", err) + } + roaddrhex = roaddrhex[:2+(addrsize*2)] + + time.Sleep(time.Millisecond * 500) + + // at this point we've verified that symkeys are saved and match on each peer + // now try sending symmetrically encrypted message, both directions + lmsgC := make(chan APIMsg) + lctx, lcancel := context.WithTimeout(context.Background(), time.Second*10) + defer lcancel() + lsub, err := clients[0].Subscribe(lctx, "pss", lmsgC, "receive", topic) + log.Trace("lsub", "id", lsub) + defer lsub.Unsubscribe() + rmsgC := make(chan APIMsg) + rctx, rcancel := context.WithTimeout(context.Background(), time.Second*10) + defer rcancel() + rsub, err := clients[1].Subscribe(rctx, "pss", rmsgC, "receive", topic) + log.Trace("rsub", "id", rsub) + defer rsub.Unsubscribe() + + // send and verify delivery + lmsg := []byte("plugh") + err = clients[1].Call(nil, "pss_sendRaw", loaddrhex, topic, lmsg) + if err != nil { + t.Fatal(err) + } + select { + case recvmsg := <-lmsgC: + if !bytes.Equal(recvmsg.Msg, lmsg) { + t.Fatalf("node 1 received payload mismatch: expected %v, got %v", lmsg, recvmsg) + } + case cerr := <-lctx.Done(): + t.Fatalf("test message (left) timed out: %v", cerr) + } + rmsg := []byte("xyzzy") + err = clients[0].Call(nil, "pss_sendRaw", roaddrhex, topic, rmsg) + if err != nil { + t.Fatal(err) + } + select { + case recvmsg := <-rmsgC: + if !bytes.Equal(recvmsg.Msg, rmsg) { + t.Fatalf("node 2 received payload mismatch: expected %x, got %v", rmsg, recvmsg.Msg) + } + case cerr := <-rctx.Done(): + t.Fatalf("test message (right) timed out: %v", cerr) + } +} + +// send symmetrically encrypted message between two directly connected peers +func TestSendSym(t *testing.T) { + t.Run("32", testSendSym) + t.Run("8", testSendSym) + t.Run("0", testSendSym) +} + +func testSendSym(t *testing.T) { + + // address hint size + var addrsize int64 + var err error + paramstring := strings.Split(t.Name(), "/") + addrsize, _ = strconv.ParseInt(paramstring[1], 10, 0) + log.Info("sym send test", "addrsize", addrsize) + + clients, err := setupNetwork(2, false) + if err != nil { + t.Fatal(err) + } + + var topic string + err = clients[0].Call(&topic, "pss_stringToTopic", "foo:42") + if err != nil { + t.Fatal(err) + } + + var loaddrhex string + err = clients[0].Call(&loaddrhex, "pss_baseAddr") + if err != nil { + t.Fatalf("rpc get node 1 baseaddr fail: %v", err) + } + loaddrhex = loaddrhex[:2+(addrsize*2)] + var roaddrhex string + err = clients[1].Call(&roaddrhex, "pss_baseAddr") + if err != nil { + t.Fatalf("rpc get node 2 baseaddr fail: %v", err) + } + roaddrhex = roaddrhex[:2+(addrsize*2)] + + // retrieve public key from pss instance + // set this public key reciprocally + var lpubkeyhex string + err = clients[0].Call(&lpubkeyhex, "pss_getPublicKey") + if err != nil { + t.Fatalf("rpc get node 1 pubkey fail: %v", err) + } + var rpubkeyhex string + err = clients[1].Call(&rpubkeyhex, "pss_getPublicKey") + if err != nil { + t.Fatalf("rpc get node 2 pubkey fail: %v", err) + } + + time.Sleep(time.Millisecond * 500) + + // at this point we've verified that symkeys are saved and match on each peer + // now try sending symmetrically encrypted message, both directions + lmsgC := make(chan APIMsg) + lctx, lcancel := context.WithTimeout(context.Background(), time.Second*10) + defer lcancel() + lsub, err := clients[0].Subscribe(lctx, "pss", lmsgC, "receive", topic) + log.Trace("lsub", "id", lsub) + defer lsub.Unsubscribe() + rmsgC := make(chan APIMsg) + rctx, rcancel := context.WithTimeout(context.Background(), time.Second*10) + defer rcancel() + rsub, err := clients[1].Subscribe(rctx, "pss", rmsgC, "receive", topic) + log.Trace("rsub", "id", rsub) + defer rsub.Unsubscribe() + + lrecvkey := network.RandomAddr().Over() + rrecvkey := network.RandomAddr().Over() + + var lkeyids [2]string + var rkeyids [2]string + + // manually set reciprocal symkeys + err = clients[0].Call(&lkeyids, "psstest_setSymKeys", rpubkeyhex, lrecvkey, rrecvkey, defaultSymKeySendLimit, topic, roaddrhex) + if err != nil { + t.Fatal(err) + } + err = clients[1].Call(&rkeyids, "psstest_setSymKeys", lpubkeyhex, rrecvkey, lrecvkey, defaultSymKeySendLimit, topic, loaddrhex) + if err != nil { + t.Fatal(err) + } + + // send and verify delivery + lmsg := []byte("plugh") + err = clients[1].Call(nil, "pss_sendSym", rkeyids[1], topic, hexutil.Encode(lmsg)) + if err != nil { + t.Fatal(err) + } + select { + case recvmsg := <-lmsgC: + if !bytes.Equal(recvmsg.Msg, lmsg) { + t.Fatalf("node 1 received payload mismatch: expected %v, got %v", lmsg, recvmsg) + } + case cerr := <-lctx.Done(): + t.Fatalf("test message timed out: %v", cerr) + } + rmsg := []byte("xyzzy") + err = clients[0].Call(nil, "pss_sendSym", lkeyids[1], topic, hexutil.Encode(rmsg)) + if err != nil { + t.Fatal(err) + } + select { + case recvmsg := <-rmsgC: + if !bytes.Equal(recvmsg.Msg, rmsg) { + t.Fatalf("node 2 received payload mismatch: expected %x, got %v", rmsg, recvmsg.Msg) + } + case cerr := <-rctx.Done(): + t.Fatalf("test message timed out: %v", cerr) + } +} + +// send asymmetrically encrypted message between two directly connected peers +func TestSendAsym(t *testing.T) { + t.Run("32", testSendAsym) + t.Run("8", testSendAsym) + t.Run("0", testSendAsym) +} + +func testSendAsym(t *testing.T) { + + // address hint size + var addrsize int64 + var err error + paramstring := strings.Split(t.Name(), "/") + addrsize, _ = strconv.ParseInt(paramstring[1], 10, 0) + log.Info("asym send test", "addrsize", addrsize) + + clients, err := setupNetwork(2, false) + if err != nil { + t.Fatal(err) + } + + var topic string + err = clients[0].Call(&topic, "pss_stringToTopic", "foo:42") + if err != nil { + t.Fatal(err) + } + + time.Sleep(time.Millisecond * 250) + + var loaddrhex string + err = clients[0].Call(&loaddrhex, "pss_baseAddr") + if err != nil { + t.Fatalf("rpc get node 1 baseaddr fail: %v", err) + } + loaddrhex = loaddrhex[:2+(addrsize*2)] + var roaddrhex string + err = clients[1].Call(&roaddrhex, "pss_baseAddr") + if err != nil { + t.Fatalf("rpc get node 2 baseaddr fail: %v", err) + } + roaddrhex = roaddrhex[:2+(addrsize*2)] + + // retrieve public key from pss instance + // set this public key reciprocally + var lpubkey string + err = clients[0].Call(&lpubkey, "pss_getPublicKey") + if err != nil { + t.Fatalf("rpc get node 1 pubkey fail: %v", err) + } + var rpubkey string + err = clients[1].Call(&rpubkey, "pss_getPublicKey") + if err != nil { + t.Fatalf("rpc get node 2 pubkey fail: %v", err) + } + + time.Sleep(time.Millisecond * 500) // replace with hive healthy code + + lmsgC := make(chan APIMsg) + lctx, lcancel := context.WithTimeout(context.Background(), time.Second*10) + defer lcancel() + lsub, err := clients[0].Subscribe(lctx, "pss", lmsgC, "receive", topic) + log.Trace("lsub", "id", lsub) + defer lsub.Unsubscribe() + rmsgC := make(chan APIMsg) + rctx, rcancel := context.WithTimeout(context.Background(), time.Second*10) + defer rcancel() + rsub, err := clients[1].Subscribe(rctx, "pss", rmsgC, "receive", topic) + log.Trace("rsub", "id", rsub) + defer rsub.Unsubscribe() + + // store reciprocal public keys + err = clients[0].Call(nil, "pss_setPeerPublicKey", rpubkey, topic, roaddrhex) + if err != nil { + t.Fatal(err) + } + err = clients[1].Call(nil, "pss_setPeerPublicKey", lpubkey, topic, loaddrhex) + if err != nil { + t.Fatal(err) + } + + // send and verify delivery + rmsg := []byte("xyzzy") + err = clients[0].Call(nil, "pss_sendAsym", rpubkey, topic, hexutil.Encode(rmsg)) + if err != nil { + t.Fatal(err) + } + select { + case recvmsg := <-rmsgC: + if !bytes.Equal(recvmsg.Msg, rmsg) { + t.Fatalf("node 2 received payload mismatch: expected %v, got %v", rmsg, recvmsg.Msg) + } + case cerr := <-rctx.Done(): + t.Fatalf("test message timed out: %v", cerr) + } + lmsg := []byte("plugh") + err = clients[1].Call(nil, "pss_sendAsym", lpubkey, topic, hexutil.Encode(lmsg)) + if err != nil { + t.Fatal(err) + } + select { + case recvmsg := <-lmsgC: + if !bytes.Equal(recvmsg.Msg, lmsg) { + t.Fatalf("node 1 received payload mismatch: expected %v, got %v", lmsg, recvmsg.Msg) + } + case cerr := <-lctx.Done(): + t.Fatalf("test message timed out: %v", cerr) + } +} + +type Job struct { + Msg []byte + SendNode discover.NodeID + RecvNode discover.NodeID +} + +func worker(id int, jobs <-chan Job, rpcs map[discover.NodeID]*rpc.Client, pubkeys map[discover.NodeID]string, topic string) { + for j := range jobs { + rpcs[j.SendNode].Call(nil, "pss_sendAsym", pubkeys[j.RecvNode], topic, hexutil.Encode(j.Msg)) + } +} + +func TestNetwork(t *testing.T) { + t.Run("16/1000/4/sim", testNetwork) +} + +// params in run name: +// nodes/msgs/addrbytes/adaptertype +// if adaptertype is exec uses execadapter, simadapter otherwise +func TestNetwork2000(t *testing.T) { + //enableMetrics() + + if !*longrunning { + t.Skip("run with --longrunning flag to run extensive network tests") + } + t.Run("3/2000/4/sim", testNetwork) + t.Run("4/2000/4/sim", testNetwork) + t.Run("8/2000/4/sim", testNetwork) + t.Run("16/2000/4/sim", testNetwork) +} + +func TestNetwork5000(t *testing.T) { + //enableMetrics() + + if !*longrunning { + t.Skip("run with --longrunning flag to run extensive network tests") + } + t.Run("3/5000/4/sim", testNetwork) + t.Run("4/5000/4/sim", testNetwork) + t.Run("8/5000/4/sim", testNetwork) + t.Run("16/5000/4/sim", testNetwork) +} + +func TestNetwork10000(t *testing.T) { + //enableMetrics() + + if !*longrunning { + t.Skip("run with --longrunning flag to run extensive network tests") + } + t.Run("3/10000/4/sim", testNetwork) + t.Run("4/10000/4/sim", testNetwork) + t.Run("8/10000/4/sim", testNetwork) +} + +func testNetwork(t *testing.T) { + type msgnotifyC struct { + id discover.NodeID + msgIdx int + } + + paramstring := strings.Split(t.Name(), "/") + nodecount, _ := strconv.ParseInt(paramstring[1], 10, 0) + msgcount, _ := strconv.ParseInt(paramstring[2], 10, 0) + addrsize, _ := strconv.ParseInt(paramstring[3], 10, 0) + adapter := paramstring[4] + + log.Info("network test", "nodecount", nodecount, "msgcount", msgcount, "addrhintsize", addrsize) + + nodes := make([]discover.NodeID, nodecount) + bzzaddrs := make(map[discover.NodeID]string, nodecount) + rpcs := make(map[discover.NodeID]*rpc.Client, nodecount) + pubkeys := make(map[discover.NodeID]string, nodecount) + + sentmsgs := make([][]byte, msgcount) + recvmsgs := make([]bool, msgcount) + nodemsgcount := make(map[discover.NodeID]int, nodecount) + + trigger := make(chan discover.NodeID) + + var a adapters.NodeAdapter + if adapter == "exec" { + dirname, err := ioutil.TempDir(".", "") + if err != nil { + t.Fatal(err) + } + a = adapters.NewExecAdapter(dirname) + } else if adapter == "tcp" { + a = adapters.NewTCPAdapter(newServices(false)) + } else if adapter == "sim" { + a = adapters.NewSimAdapter(newServices(false)) + } + net := simulations.NewNetwork(a, &simulations.NetworkConfig{ + ID: "0", + }) + defer net.Shutdown() + + f, err := os.Open(fmt.Sprintf("testdata/snapshot_%d.json", nodecount)) + if err != nil { + t.Fatal(err) + } + jsonbyte, err := ioutil.ReadAll(f) + if err != nil { + t.Fatal(err) + } + var snap simulations.Snapshot + err = json.Unmarshal(jsonbyte, &snap) + if err != nil { + t.Fatal(err) + } + err = net.Load(&snap) + if err != nil { + //TODO: Fix p2p simulation framework to not crash when loading 32-nodes + //t.Fatal(err) + } + + time.Sleep(1 * time.Second) + + triggerChecks := func(trigger chan discover.NodeID, id discover.NodeID, rpcclient *rpc.Client, topic string) error { + msgC := make(chan APIMsg) + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + sub, err := rpcclient.Subscribe(ctx, "pss", msgC, "receive", topic) + if err != nil { + t.Fatal(err) + } + go func() { + defer sub.Unsubscribe() + for { + select { + case recvmsg := <-msgC: + idx, _ := binary.Uvarint(recvmsg.Msg) + if !recvmsgs[idx] { + log.Debug("msg recv", "idx", idx, "id", id) + recvmsgs[idx] = true + trigger <- id + } + case <-sub.Err(): + return + } + } + }() + return nil + } + + var topic string + for i, nod := range net.GetNodes() { + nodes[i] = nod.ID() + rpcs[nodes[i]], err = nod.Client() + if err != nil { + t.Fatal(err) + } + if topic == "" { + err = rpcs[nodes[i]].Call(&topic, "pss_stringToTopic", "foo:42") + if err != nil { + t.Fatal(err) + } + } + var pubkey string + err = rpcs[nodes[i]].Call(&pubkey, "pss_getPublicKey") + if err != nil { + t.Fatal(err) + } + pubkeys[nod.ID()] = pubkey + var addrhex string + err = rpcs[nodes[i]].Call(&addrhex, "pss_baseAddr") + if err != nil { + t.Fatal(err) + } + bzzaddrs[nodes[i]] = addrhex + err = triggerChecks(trigger, nodes[i], rpcs[nodes[i]], topic) + if err != nil { + t.Fatal(err) + } + } + + time.Sleep(1 * time.Second) + + // setup workers + jobs := make(chan Job, 10) + for w := 1; w <= 10; w++ { + go worker(w, jobs, rpcs, pubkeys, topic) + } + + time.Sleep(1 * time.Second) + + for i := 0; i < int(msgcount); i++ { + sendnodeidx := rand.Intn(int(nodecount)) + recvnodeidx := rand.Intn(int(nodecount - 1)) + if recvnodeidx >= sendnodeidx { + recvnodeidx++ + } + nodemsgcount[nodes[recvnodeidx]]++ + sentmsgs[i] = make([]byte, 8) + c := binary.PutUvarint(sentmsgs[i], uint64(i)) + if c == 0 { + t.Fatal("0 byte message") + } + if err != nil { + t.Fatal(err) + } + err = rpcs[nodes[sendnodeidx]].Call(nil, "pss_setPeerPublicKey", pubkeys[nodes[recvnodeidx]], topic, bzzaddrs[nodes[recvnodeidx]]) + if err != nil { + t.Fatal(err) + } + + jobs <- Job{ + Msg: sentmsgs[i], + SendNode: nodes[sendnodeidx], + RecvNode: nodes[recvnodeidx], + } + } + + finalmsgcount := 0 + ctx, cancel := context.WithTimeout(context.Background(), 120*time.Second) + defer cancel() +outer: + for i := 0; i < int(msgcount); i++ { + select { + case id := <-trigger: + nodemsgcount[id]-- + finalmsgcount++ + case <-ctx.Done(): + log.Warn("timeout") + break outer + } + } + + for i, msg := range recvmsgs { + if !msg { + log.Debug("missing message", "idx", i) + } + } + t.Logf("%d of %d messages received", finalmsgcount, msgcount) + + if finalmsgcount != int(msgcount) { + t.Fatalf("%d messages were not received", int(msgcount)-finalmsgcount) + } + +} + +// check that in a network of a -> b -> c -> a +// a doesn't receive a sent message twice +func TestDeduplication(t *testing.T) { + var err error + + clients, err := setupNetwork(3, false) + if err != nil { + t.Fatal(err) + } + + var addrsize = 32 + var loaddrhex string + err = clients[0].Call(&loaddrhex, "pss_baseAddr") + if err != nil { + t.Fatalf("rpc get node 1 baseaddr fail: %v", err) + } + loaddrhex = loaddrhex[:2+(addrsize*2)] + var roaddrhex string + err = clients[1].Call(&roaddrhex, "pss_baseAddr") + if err != nil { + t.Fatalf("rpc get node 2 baseaddr fail: %v", err) + } + roaddrhex = roaddrhex[:2+(addrsize*2)] + var xoaddrhex string + err = clients[2].Call(&xoaddrhex, "pss_baseAddr") + if err != nil { + t.Fatalf("rpc get node 3 baseaddr fail: %v", err) + } + xoaddrhex = xoaddrhex[:2+(addrsize*2)] + + log.Info("peer", "l", loaddrhex, "r", roaddrhex, "x", xoaddrhex) + + var topic string + err = clients[0].Call(&topic, "pss_stringToTopic", "foo:42") + if err != nil { + t.Fatal(err) + } + + time.Sleep(time.Millisecond * 250) + + // retrieve public key from pss instance + // set this public key reciprocally + var rpubkey string + err = clients[1].Call(&rpubkey, "pss_getPublicKey") + if err != nil { + t.Fatalf("rpc get receivenode pubkey fail: %v", err) + } + + time.Sleep(time.Millisecond * 500) // replace with hive healthy code + + rmsgC := make(chan APIMsg) + rctx, cancel := context.WithTimeout(context.Background(), time.Second*1) + defer cancel() + rsub, err := clients[1].Subscribe(rctx, "pss", rmsgC, "receive", topic) + log.Trace("rsub", "id", rsub) + defer rsub.Unsubscribe() + + // store public key for recipient + // zero-length address means forward to all + // we have just two peers, they will be in proxbin, and will both receive + err = clients[0].Call(nil, "pss_setPeerPublicKey", rpubkey, topic, "0x") + if err != nil { + t.Fatal(err) + } + + // send and verify delivery + rmsg := []byte("xyzzy") + err = clients[0].Call(nil, "pss_sendAsym", rpubkey, topic, hexutil.Encode(rmsg)) + if err != nil { + t.Fatal(err) + } + + var receivedok bool +OUTER: + for { + select { + case <-rmsgC: + if receivedok { + t.Fatalf("duplicate message received") + } + receivedok = true + case <-rctx.Done(): + break OUTER + } + } + if !receivedok { + t.Fatalf("message did not arrive") + } +} + +// symmetric send performance with varying message sizes +func BenchmarkSymkeySend(b *testing.B) { + b.Run(fmt.Sprintf("%d", 256), benchmarkSymKeySend) + b.Run(fmt.Sprintf("%d", 1024), benchmarkSymKeySend) + b.Run(fmt.Sprintf("%d", 1024*1024), benchmarkSymKeySend) + b.Run(fmt.Sprintf("%d", 1024*1024*10), benchmarkSymKeySend) + b.Run(fmt.Sprintf("%d", 1024*1024*100), benchmarkSymKeySend) +} + +func benchmarkSymKeySend(b *testing.B) { + msgsizestring := strings.Split(b.Name(), "/") + if len(msgsizestring) != 2 { + b.Fatalf("benchmark called without msgsize param") + } + msgsize, err := strconv.ParseInt(msgsizestring[1], 10, 0) + if err != nil { + b.Fatalf("benchmark called with invalid msgsize param '%s': %v", msgsizestring[1], err) + } + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + keys, err := wapi.NewKeyPair(ctx) + privkey, err := w.GetPrivateKey(keys) + ps := newTestPss(privkey, nil, nil) + msg := make([]byte, msgsize) + rand.Read(msg) + topic := BytesToTopic([]byte("foo")) + to := make(PssAddress, 32) + copy(to[:], network.RandomAddr().Over()) + symkeyid, err := ps.GenerateSymmetricKey(topic, &to, true) + if err != nil { + b.Fatalf("could not generate symkey: %v", err) + } + symkey, err := ps.w.GetSymKey(symkeyid) + if err != nil { + b.Fatalf("could not retrieve symkey: %v", err) + } + ps.SetSymmetricKey(symkey, topic, &to, false) + + b.ResetTimer() + for i := 0; i < b.N; i++ { + ps.SendSym(symkeyid, topic, msg) + } +} + +// asymmetric send performance with varying message sizes +func BenchmarkAsymkeySend(b *testing.B) { + b.Run(fmt.Sprintf("%d", 256), benchmarkAsymKeySend) + b.Run(fmt.Sprintf("%d", 1024), benchmarkAsymKeySend) + b.Run(fmt.Sprintf("%d", 1024*1024), benchmarkAsymKeySend) + b.Run(fmt.Sprintf("%d", 1024*1024*10), benchmarkAsymKeySend) + b.Run(fmt.Sprintf("%d", 1024*1024*100), benchmarkAsymKeySend) +} + +func benchmarkAsymKeySend(b *testing.B) { + msgsizestring := strings.Split(b.Name(), "/") + if len(msgsizestring) != 2 { + b.Fatalf("benchmark called without msgsize param") + } + msgsize, err := strconv.ParseInt(msgsizestring[1], 10, 0) + if err != nil { + b.Fatalf("benchmark called with invalid msgsize param '%s': %v", msgsizestring[1], err) + } + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + keys, err := wapi.NewKeyPair(ctx) + privkey, err := w.GetPrivateKey(keys) + ps := newTestPss(privkey, nil, nil) + msg := make([]byte, msgsize) + rand.Read(msg) + topic := BytesToTopic([]byte("foo")) + to := make(PssAddress, 32) + copy(to[:], network.RandomAddr().Over()) + ps.SetPeerPublicKey(&privkey.PublicKey, topic, &to) + b.ResetTimer() + for i := 0; i < b.N; i++ { + ps.SendAsym(common.ToHex(crypto.FromECDSAPub(&privkey.PublicKey)), topic, msg) + } +} +func BenchmarkSymkeyBruteforceChangeaddr(b *testing.B) { + for i := 100; i < 100000; i = i * 10 { + for j := 32; j < 10000; j = j * 8 { + b.Run(fmt.Sprintf("%d/%d", i, j), benchmarkSymkeyBruteforceChangeaddr) + } + //b.Run(fmt.Sprintf("%d", i), benchmarkSymkeyBruteforceChangeaddr) + } +} + +// decrypt performance using symkey cache, worst case +// (decrypt key always last in cache) +func benchmarkSymkeyBruteforceChangeaddr(b *testing.B) { + keycountstring := strings.Split(b.Name(), "/") + cachesize := int64(0) + var ps *Pss + if len(keycountstring) < 2 { + b.Fatalf("benchmark called without count param") + } + keycount, err := strconv.ParseInt(keycountstring[1], 10, 0) + if err != nil { + b.Fatalf("benchmark called with invalid count param '%s': %v", keycountstring[1], err) + } + if len(keycountstring) == 3 { + cachesize, err = strconv.ParseInt(keycountstring[2], 10, 0) + if err != nil { + b.Fatalf("benchmark called with invalid cachesize '%s': %v", keycountstring[2], err) + } + } + pssmsgs := make([]*PssMsg, 0, keycount) + var keyid string + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + keys, err := wapi.NewKeyPair(ctx) + privkey, err := w.GetPrivateKey(keys) + if cachesize > 0 { + ps = newTestPss(privkey, nil, &PssParams{SymKeyCacheCapacity: int(cachesize)}) + } else { + ps = newTestPss(privkey, nil, nil) + } + topic := BytesToTopic([]byte("foo")) + for i := 0; i < int(keycount); i++ { + to := make(PssAddress, 32) + copy(to[:], network.RandomAddr().Over()) + keyid, err = ps.GenerateSymmetricKey(topic, &to, true) + if err != nil { + b.Fatalf("cant generate symkey #%d: %v", i, err) + } + symkey, err := ps.w.GetSymKey(keyid) + if err != nil { + b.Fatalf("could not retrieve symkey %s: %v", keyid, err) + } + wparams := &whisper.MessageParams{ + TTL: defaultWhisperTTL, + KeySym: symkey, + Topic: whisper.TopicType(topic), + WorkTime: defaultWhisperWorkTime, + PoW: defaultWhisperPoW, + Payload: []byte("xyzzy"), + Padding: []byte("1234567890abcdef"), + } + woutmsg, err := whisper.NewSentMessage(wparams) + if err != nil { + b.Fatalf("could not create whisper message: %v", err) + } + env, err := woutmsg.Wrap(wparams) + if err != nil { + b.Fatalf("could not generate whisper envelope: %v", err) + } + ps.Register(&topic, func(msg []byte, p *p2p.Peer, asymmetric bool, keyid string) error { + return nil + }) + pssmsgs = append(pssmsgs, &PssMsg{ + To: to, + Payload: env, + }) + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + if err := ps.process(pssmsgs[len(pssmsgs)-(i%len(pssmsgs))-1]); err != nil { + b.Fatalf("pss processing failed: %v", err) + } + } +} + +func BenchmarkSymkeyBruteforceSameaddr(b *testing.B) { + for i := 100; i < 100000; i = i * 10 { + for j := 32; j < 10000; j = j * 8 { + b.Run(fmt.Sprintf("%d/%d", i, j), benchmarkSymkeyBruteforceSameaddr) + } + } +} + +// decrypt performance using symkey cache, best case +// (decrypt key always first in cache) +func benchmarkSymkeyBruteforceSameaddr(b *testing.B) { + var keyid string + var ps *Pss + cachesize := int64(0) + keycountstring := strings.Split(b.Name(), "/") + if len(keycountstring) < 2 { + b.Fatalf("benchmark called without count param") + } + keycount, err := strconv.ParseInt(keycountstring[1], 10, 0) + if err != nil { + b.Fatalf("benchmark called with invalid count param '%s': %v", keycountstring[1], err) + } + if len(keycountstring) == 3 { + cachesize, err = strconv.ParseInt(keycountstring[2], 10, 0) + if err != nil { + b.Fatalf("benchmark called with invalid cachesize '%s': %v", keycountstring[2], err) + } + } + addr := make([]PssAddress, keycount) + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + keys, err := wapi.NewKeyPair(ctx) + privkey, err := w.GetPrivateKey(keys) + if cachesize > 0 { + ps = newTestPss(privkey, nil, &PssParams{SymKeyCacheCapacity: int(cachesize)}) + } else { + ps = newTestPss(privkey, nil, nil) + } + topic := BytesToTopic([]byte("foo")) + for i := 0; i < int(keycount); i++ { + copy(addr[i], network.RandomAddr().Over()) + keyid, err = ps.GenerateSymmetricKey(topic, &addr[i], true) + if err != nil { + b.Fatalf("cant generate symkey #%d: %v", i, err) + } + + } + symkey, err := ps.w.GetSymKey(keyid) + if err != nil { + b.Fatalf("could not retrieve symkey %s: %v", keyid, err) + } + wparams := &whisper.MessageParams{ + TTL: defaultWhisperTTL, + KeySym: symkey, + Topic: whisper.TopicType(topic), + WorkTime: defaultWhisperWorkTime, + PoW: defaultWhisperPoW, + Payload: []byte("xyzzy"), + Padding: []byte("1234567890abcdef"), + } + woutmsg, err := whisper.NewSentMessage(wparams) + if err != nil { + b.Fatalf("could not create whisper message: %v", err) + } + env, err := woutmsg.Wrap(wparams) + if err != nil { + b.Fatalf("could not generate whisper envelope: %v", err) + } + ps.Register(&topic, func(msg []byte, p *p2p.Peer, asymmetric bool, keyid string) error { + return nil + }) + pssmsg := &PssMsg{ + To: addr[len(addr)-1][:], + Payload: env, + } + for i := 0; i < b.N; i++ { + if err := ps.process(pssmsg); err != nil { + b.Fatalf("pss processing failed: %v", err) + } + } +} + +// setup simulated network with bzz/discovery and pss services. +// connects nodes in a circle +// if allowRaw is set, omission of builtin pss encryption is enabled (see PssParams) +func setupNetwork(numnodes int, allowRaw bool) (clients []*rpc.Client, err error) { + nodes := make([]*simulations.Node, numnodes) + clients = make([]*rpc.Client, numnodes) + if numnodes < 2 { + return nil, fmt.Errorf("Minimum two nodes in network") + } + adapter := adapters.NewSimAdapter(newServices(allowRaw)) + net := simulations.NewNetwork(adapter, &simulations.NetworkConfig{ + ID: "0", + DefaultService: "bzz", + }) + for i := 0; i < numnodes; i++ { + nodeconf := adapters.RandomNodeConfig() + nodeconf.Services = []string{"bzz", pssProtocolName} + nodes[i], err = net.NewNodeWithConfig(nodeconf) + if err != nil { + return nil, fmt.Errorf("error creating node 1: %v", err) + } + err = net.Start(nodes[i].ID()) + if err != nil { + return nil, fmt.Errorf("error starting node 1: %v", err) + } + if i > 0 { + err = net.Connect(nodes[i].ID(), nodes[i-1].ID()) + if err != nil { + return nil, fmt.Errorf("error connecting nodes: %v", err) + } + } + clients[i], err = nodes[i].Client() + if err != nil { + return nil, fmt.Errorf("create node 1 rpc client fail: %v", err) + } + } + if numnodes > 2 { + err = net.Connect(nodes[0].ID(), nodes[len(nodes)-1].ID()) + if err != nil { + return nil, fmt.Errorf("error connecting first and last nodes") + } + } + return clients, nil +} + +func newServices(allowRaw bool) adapters.Services { + stateStore := state.NewInmemoryStore() + kademlias := make(map[discover.NodeID]*network.Kademlia) + kademlia := func(id discover.NodeID) *network.Kademlia { + if k, ok := kademlias[id]; ok { + return k + } + addr := network.NewAddrFromNodeID(id) + params := network.NewKadParams() + params.MinProxBinSize = 2 + params.MaxBinSize = 3 + params.MinBinSize = 1 + params.MaxRetries = 1000 + params.RetryExponent = 2 + params.RetryInterval = 1000000 + kademlias[id] = network.NewKademlia(addr.Over(), params) + return kademlias[id] + } + return adapters.Services{ + pssProtocolName: func(ctx *adapters.ServiceContext) (node.Service, error) { + // execadapter does not exec init() + initTest() + + ctxlocal, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + keys, err := wapi.NewKeyPair(ctxlocal) + privkey, err := w.GetPrivateKey(keys) + pssp := NewPssParams().WithPrivateKey(privkey) + pssp.AllowRaw = allowRaw + pskad := kademlia(ctx.Config.ID) + ps, err := NewPss(pskad, pssp) + if err != nil { + return nil, err + } + + ping := &Ping{ + OutC: make(chan bool), + Pong: true, + } + p2pp := NewPingProtocol(ping) + pp, err := RegisterProtocol(ps, &PingTopic, PingProtocol, p2pp, &ProtocolParams{Asymmetric: true}) + if err != nil { + return nil, err + } + if useHandshake { + SetHandshakeController(ps, NewHandshakeParams()) + } + ps.Register(&PingTopic, pp.Handle) + ps.addAPI(rpc.API{ + Namespace: "psstest", + Version: "0.3", + Service: NewAPITest(ps), + Public: false, + }) + if err != nil { + log.Error("Couldnt register pss protocol", "err", err) + os.Exit(1) + } + pssprotocols[ctx.Config.ID.String()] = &protoCtrl{ + C: ping.OutC, + protocol: pp, + run: p2pp.Run, + } + return ps, nil + }, + "bzz": func(ctx *adapters.ServiceContext) (node.Service, error) { + addr := network.NewAddrFromNodeID(ctx.Config.ID) + hp := network.NewHiveParams() + hp.Discovery = false + config := &network.BzzConfig{ + OverlayAddr: addr.Over(), + UnderlayAddr: addr.Under(), + HiveParams: hp, + } + return network.NewBzz(config, kademlia(ctx.Config.ID), stateStore, nil, nil), nil + }, + } +} + +func newTestPss(privkey *ecdsa.PrivateKey, overlay network.Overlay, ppextra *PssParams) *Pss { + + var nid discover.NodeID + copy(nid[:], crypto.FromECDSAPub(&privkey.PublicKey)) + addr := network.NewAddrFromNodeID(nid) + + // set up routing if kademlia is not passed to us + if overlay == nil { + kp := network.NewKadParams() + kp.MinProxBinSize = 3 + overlay = network.NewKademlia(addr.Over(), kp) + } + + // create pss + pp := NewPssParams().WithPrivateKey(privkey) + if ppextra != nil { + pp.SymKeyCacheCapacity = ppextra.SymKeyCacheCapacity + } + ps, err := NewPss(overlay, pp) + if err != nil { + return nil + } + ps.Start(nil) + + return ps +} + +// API calls for test/development use +type APITest struct { + *Pss +} + +func NewAPITest(ps *Pss) *APITest { + return &APITest{Pss: ps} +} + +func (apitest *APITest) SetSymKeys(pubkeyid string, recvsymkey []byte, sendsymkey []byte, limit uint16, topic Topic, to PssAddress) ([2]string, error) { + recvsymkeyid, err := apitest.SetSymmetricKey(recvsymkey, topic, &to, true) + if err != nil { + return [2]string{}, err + } + sendsymkeyid, err := apitest.SetSymmetricKey(sendsymkey, topic, &to, false) + if err != nil { + return [2]string{}, err + } + return [2]string{recvsymkeyid, sendsymkeyid}, nil +} + +func (apitest *APITest) Clean() (int, error) { + return apitest.Pss.cleanKeys(), nil +} + +// enableMetrics is starting InfluxDB reporter so that we collect stats when running tests locally +func enableMetrics() { + metrics.Enabled = true + go influxdb.InfluxDBWithTags(metrics.DefaultRegistry, 1*time.Second, "http://localhost:8086", "metrics", "admin", "admin", "swarm.", map[string]string{ + "host": "test", + }) +} diff --git a/swarm/pss/testdata/addpsstodiscoverytestsnapshot.pl b/swarm/pss/testdata/addpsstodiscoverytestsnapshot.pl new file mode 100644 index 0000000000..b75cc9894a --- /dev/null +++ b/swarm/pss/testdata/addpsstodiscoverytestsnapshot.pl @@ -0,0 +1,28 @@ +#!/usr/bin/perl + +use JSON; + +my $f; +my $jsontext; +my $nodelist; +my $network; + +open($f, "<", $ARGV[0]) || die "cant open " . $ARGV[0]; +while (<$f>) { + $jsontext .= $_; +} +close($f); + +$network = decode_json($jsontext); +$nodelist = $network->{'nodes'}; + +for ($i = 0; $i < 0+@$nodelist; $i++) { + #my $protocollist = $$nodelist[$i]{'node'}{'info'}{'protocols'}; + #$$protocollist{'pss'} = "pss"; + my $svc = $$nodelist[$i]{'node'}{'config'}{'services'}; + pop(@$svc); + push(@$svc, "pss"); + push(@$svc, "bzz"); +} + +print encode_json($network); diff --git a/swarm/pss/testdata/addpsstodiscoverytestsnapshot.sh b/swarm/pss/testdata/addpsstodiscoverytestsnapshot.sh new file mode 100644 index 0000000000..7d3c284916 --- /dev/null +++ b/swarm/pss/testdata/addpsstodiscoverytestsnapshot.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +sed -e 's/\(\"services\"\):\["discovery\"]/\1:["pss","bzz"]/' diff --git a/swarm/pss/testdata/snapshot_128.json b/swarm/pss/testdata/snapshot_128.json new file mode 100644 index 0000000000..552535d50e --- /dev/null +++ b/swarm/pss/testdata/snapshot_128.json @@ -0,0 +1 @@ +{"nodes":[{"node":{"info":{"ip":"0.0.0.0","ports":{"listener":0,"discovery":0},"listenAddr":"","name":"node01","enode":"enode://d2cf35afdb846755290a7c3a1a36758e735a4eeed57b1af66595c55ab45c52cf2c478de3f395b38513cdc9e49568892cce490de93074fa45b640628f0fe40719@0.0.0.0:0","id":"d2cf35afdb846755290a7c3a1a36758e735a4eeed57b1af66595c55ab45c52cf2c478de3f395b38513cdc9e49568892cce490de93074fa45b640628f0fe40719","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: c42f36\npopulation: 11 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 776f 11b5 | 74 5958 (0) 5820 (0) 580a (0) 5f1c (0)\n001 1 a20d | 30 960e (0) 944e (0) 958e (0) 9265 (0)\n002 2 f7cd f843 | 14 e22c (0) e8d0 (0) e884 (0) ede2 (0)\n003 1 d24a | 4 d24a (0) d6a2 (0) d6e3 (0) d486 (0)\n004 3 ce12 cd94 cb70 | 3 ce12 (0) cd94 (0) cb70 (0)\n============ DEPTH: 5 ==========================================\n005 1 c1c1 | 1 c1c1 (0)\n006 1 c6ed | 1 c6ed (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"xC82v2coskchzlrBJyoQWOICojbSdq8SZaHqpnX4/YU="}},"up":true,"config":{"id":"d2cf35afdb846755290a7c3a1a36758e735a4eeed57b1af66595c55ab45c52cf2c478de3f395b38513cdc9e49568892cce490de93074fa45b640628f0fe40719","private_key":"79eaaa1c3a9339a90cf54c511649caf683f2910588a872d2c12919355b7d5d28","services":["pss","bzz"],"name":"node01"}}},{"node":{"info":{"name":"node02","listenAddr":"","enode":"enode://8b8c15c6329096267a25d4060ee19963afb6e776fea60d9d566d4e1f9b087581b36e33fc533d7f133668a7a6a22f81a1234ed9fbce26eff1d5e5691a6148d540@0.0.0.0:0","ports":{"discovery":0,"listener":0},"ip":"0.0.0.0","protocols":{"bzz":"EbU/pAkmrITXXZ1pj0a5YRuQGUhXwTl+EXkxqJBEcHg=","hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 11b53f\npopulation: 13 (125), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 c42f | 52 960e (0) 944e (0) 958e (0) 9265 (0)\n001 1 60cb | 38 5f1c (0) 5f8e (0) 5958 (0) 5820 (0)\n002 1 2124 | 11 39b5 (0) 30c0 (0) 3547 (0) 351d (0)\n003 3 07c7 0066 0d90 | 11 051c (0) 0561 (0) 07c7 (0) 016e (0)\n004 1 1b61 | 6 1f15 (0) 1d53 (0) 18b0 (0) 1a16 (0)\n005 2 165d 171f | 3 160c (0) 165d (0) 171f (0)\n============ DEPTH: 6 ==========================================\n006 3 1316 1263 12df | 3 1316 (0) 12df (0) 1263 (0)\n007 1 1030 | 1 1030 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"id":"8b8c15c6329096267a25d4060ee19963afb6e776fea60d9d566d4e1f9b087581b36e33fc533d7f133668a7a6a22f81a1234ed9fbce26eff1d5e5691a6148d540"},"up":true,"config":{"name":"node02","services":["pss","bzz"],"private_key":"b067839f81534251ade8651e682dbd8324dfb83c7034aff4a48909e9310c990a","id":"8b8c15c6329096267a25d4060ee19963afb6e776fea60d9d566d4e1f9b087581b36e33fc533d7f133668a7a6a22f81a1234ed9fbce26eff1d5e5691a6148d540"}}},{"node":{"config":{"name":"node03","services":["pss","bzz"],"private_key":"4233e4c480ae197c265975cc7c83cc7b0cf1a8d67e4728bac4bcecaee63ad935","id":"1545795dca07ecd09c5b16b3bbdddf3dba92e27b532c18a3bc63bc007761ac1b1ebc7ffb4f0a401d5376a4c67923c7949edaebd8f65fff52d6677bb1d6a72f43"},"up":true,"info":{"protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 60cbf5\npopulation: 9 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 869f | 54 e22c (0) e884 (0) e8d0 (0) ede2 (0)\n001 1 11b5 | 36 39b5 (0) 30c0 (0) 3547 (0) 351d (0)\n002 1 5f1c | 18 5f1c (0) 5f8e (0) 5958 (0) 5820 (0)\n003 1 74a4 | 9 7a46 (0) 795d (0) 78db (0) 7d14 (0)\n004 2 6b1f 6b7d | 7 6d30 (0) 6c29 (0) 6c2f (0) 69ba (0)\n============ DEPTH: 5 ==========================================\n005 2 66f6 6421 | 2 66f6 (0) 6421 (0)\n006 1 62d5 | 1 62d5 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"YMv1EzZto/buKI01ctw5ca4lawLlSSWV5jwxp7Gw1ag="},"id":"1545795dca07ecd09c5b16b3bbdddf3dba92e27b532c18a3bc63bc007761ac1b1ebc7ffb4f0a401d5376a4c67923c7949edaebd8f65fff52d6677bb1d6a72f43","listenAddr":"","name":"node03","enode":"enode://1545795dca07ecd09c5b16b3bbdddf3dba92e27b532c18a3bc63bc007761ac1b1ebc7ffb4f0a401d5376a4c67923c7949edaebd8f65fff52d6677bb1d6a72f43@0.0.0.0:0","ports":{"listener":0,"discovery":0},"ip":"0.0.0.0"}}},{"node":{"up":true,"config":{"private_key":"ca0c9f1baad4f60ddeaafe287d43b4ef8ec4b96c4ef12da194074325ca6cc4ef","id":"071c094246a0ca4b5d169e43a20ce5da508e579a6e2e822462bd8948ab357d46ab477bcff0c80eba2e01f0c100690b307af40d47c52ebad06783e9e77466cbd6","name":"node04","services":["pss","bzz"]},"info":{"protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 869fc2\npopulation: 17 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 7c99 66f6 60cb | 74 39b5 (0) 3547 (0) 351d (0) 30c0 (0)\n001 4 f843 fb21 f7cd c6ed | 24 e22c (0) e884 (0) e8d0 (0) ede2 (0)\n002 3 b87c bb9c a20d | 12 b778 (0) b270 (0) b26e (0) b87c (0)\n003 2 9265 9d60 | 9 944e (0) 958e (0) 960e (0) 9265 (0)\n004 1 8ff6 | 4 88dc (0) 88a9 (0) 8937 (0) 8ff6 (0)\n============ DEPTH: 5 ==========================================\n005 3 8357 8166 8174 | 3 8357 (0) 8166 (0) 8174 (0)\n006 1 8584 | 1 8584 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"hp/CH/8VDOnhvEUSsYNVlDN2fPwct7a6rm0qExMkWug="},"id":"071c094246a0ca4b5d169e43a20ce5da508e579a6e2e822462bd8948ab357d46ab477bcff0c80eba2e01f0c100690b307af40d47c52ebad06783e9e77466cbd6","listenAddr":"","name":"node04","enode":"enode://071c094246a0ca4b5d169e43a20ce5da508e579a6e2e822462bd8948ab357d46ab477bcff0c80eba2e01f0c100690b307af40d47c52ebad06783e9e77466cbd6@0.0.0.0:0","ports":{"discovery":0,"listener":0},"ip":"0.0.0.0"}}},{"node":{"info":{"id":"f4ae36400caeddcbcf0fb1abd5b9611c37bac683645d10c69a1ac54d366f730c59917c95e990a0fa6bb2679c98fb62bf0e29bd7812ab57375de35f469dab98a0","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: a20d59\npopulation: 14 (117), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 2124 18b0 | 64 5f1c (0) 5f8e (0) 5958 (0) 580a (0)\n001 4 f7cd cb70 c6ed c42f | 24 e22c (0) e8d0 (0) e884 (0) ede2 (0)\n002 3 9d60 8584 869f | 18 960e (0) 944e (0) 958e (0) 9265 (0)\n003 1 bb9c | 5 b778 (0) b270 (0) b26e (0) b87c (0)\n004 2 ac38 adfd | 4 a93b (0) aff7 (0) ac38 (0) adfd (0)\n============ DEPTH: 5 ==========================================\n005 1 a6ca | 1 a6ca (0)\n006 0 | 0\n007 1 a3e8 | 1 a3e8 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"og1ZHqFXInEug/zGwXcy8jcANO+HAjSg+gsvSupXL9U="},"ports":{"listener":0,"discovery":0},"ip":"0.0.0.0","enode":"enode://f4ae36400caeddcbcf0fb1abd5b9611c37bac683645d10c69a1ac54d366f730c59917c95e990a0fa6bb2679c98fb62bf0e29bd7812ab57375de35f469dab98a0@0.0.0.0:0","listenAddr":"","name":"node05"},"config":{"services":["pss","bzz"],"name":"node05","id":"f4ae36400caeddcbcf0fb1abd5b9611c37bac683645d10c69a1ac54d366f730c59917c95e990a0fa6bb2679c98fb62bf0e29bd7812ab57375de35f469dab98a0","private_key":"b6c09a581c2a6d85a63c11e586391346fe9d9d24292de15333ae230a33c52c1e"},"up":true}},{"node":{"config":{"name":"node06","services":["pss","bzz"],"private_key":"378e3e11e738557d2eea27e070d52c8355f8abe0c5f8607ac0792455a1d50bae","id":"a13086041114db2be31038987ac3fdcaeb99489f1b6ee9b22998b9e66dc2f2f024307d9474811e7e8be1b1acf5a55305d5cce27d87fb834ed1e1d2e17319bb85"},"up":true,"info":{"ip":"0.0.0.0","ports":{"listener":0,"discovery":0},"listenAddr":"","name":"node06","enode":"enode://a13086041114db2be31038987ac3fdcaeb99489f1b6ee9b22998b9e66dc2f2f024307d9474811e7e8be1b1acf5a55305d5cce27d87fb834ed1e1d2e17319bb85@0.0.0.0:0","id":"a13086041114db2be31038987ac3fdcaeb99489f1b6ee9b22998b9e66dc2f2f024307d9474811e7e8be1b1acf5a55305d5cce27d87fb834ed1e1d2e17319bb85","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 18b0fc\npopulation: 15 (115), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 a20d f843 | 45 9265 (0) 960e (0) 958e (0) 9835 (0)\n001 1 5f8e | 35 5f1c (0) 5f8e (0) 5958 (0) 580a (0)\n002 2 3547 30c0 | 11 39b5 (0) 30c0 (0) 351d (0) 3547 (0)\n003 2 051c 0f19 | 11 0066 (0) 00b9 (0) 016e (0) 0104 (0)\n004 3 1263 165d 171f | 8 11b5 (0) 1030 (0) 1316 (0) 1263 (0)\n005 2 1d53 1f15 | 2 1f15 (0) 1d53 (0)\n============ DEPTH: 6 ==========================================\n006 3 1b61 1a16 1a69 | 3 1b61 (0) 1a16 (0) 1a69 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"GLD8u6I1AkEIgSno9qB3QoV8Ptqs1u8ewIYcyOSEks4="}}}},{"node":{"config":{"id":"b949f482891fff7d7d1f0d84112db7080fa1df07cd4e52ee0fadb707a4b7903fc0da9fe45b7ceee37948856687f8e7768945295de15691a99c879f1816899d98","private_key":"e6710b29bb9b7f00ee1e921bd548fc7622d73a0aae3f25de7a3f3650191147a8","services":["pss","bzz"],"name":"node07"},"up":true,"info":{"ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"name":"node07","listenAddr":"","enode":"enode://b949f482891fff7d7d1f0d84112db7080fa1df07cd4e52ee0fadb707a4b7903fc0da9fe45b7ceee37948856687f8e7768945295de15691a99c879f1816899d98@0.0.0.0:0","id":"b949f482891fff7d7d1f0d84112db7080fa1df07cd4e52ee0fadb707a4b7903fc0da9fe45b7ceee37948856687f8e7768945295de15691a99c879f1816899d98","protocols":{"bzz":"+EMX70iNjBSVtCm3ofoh6lOnPnN7PBqokMIOOGWKsUg=","hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: f84317\npopulation: 18 (122), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 0f19 18b0 | 69 5f1c (0) 5f8e (0) 5958 (0) 5820 (0)\n001 5 bb9c 9a8c 9d60 8ff6 | 30 9265 (0) 958e (0) 944e (0) 960e (0)\n002 3 cd94 c42f c6ed | 10 d24a (0) d6a2 (0) d6e3 (0) d486 (0)\n003 2 e22c efde | 6 e22c (0) e884 (0) e8d0 (0) ede2 (0)\n004 1 f7cd | 1 f7cd (0)\n005 2 fe9d fd54 | 3 fe9d (0) fcf3 (0) fd54 (0)\n006 1 fb21 | 1 fb21 (0)\n============ DEPTH: 7 ==========================================\n007 2 f926 f9e4 | 2 f926 (0) f9e4 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}}}},{"node":{"config":{"name":"node08","services":["pss","bzz"],"private_key":"2bed1cf9737dbf8239f560ab8b4e57dc47cf57a28ebd203e6fb159093fbe52c0","id":"c796d4917dd22d9836a9d7d24ba6f89e1a0e8a78a207bd930991e44e9c80ac1de8e4e1a023d550a6dfa60270fbb3935a7e03ef389c1ccda957a4a6a75ef6819b"},"up":true,"info":{"enode":"enode://c796d4917dd22d9836a9d7d24ba6f89e1a0e8a78a207bd930991e44e9c80ac1de8e4e1a023d550a6dfa60270fbb3935a7e03ef389c1ccda957a4a6a75ef6819b@0.0.0.0:0","name":"node08","listenAddr":"","ports":{"listener":0,"discovery":0},"ip":"0.0.0.0","protocols":{"bzz":"Dxn7TQxs/jb39ZyP5U0uFpaHYD4b3g/ms6XoZPpR8vA=","hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 0f19fb\npopulation: 12 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 f843 | 54 9265 (0) 958e (0) 944e (0) 960e (0)\n001 1 7c99 | 38 5f1c (0) 5f8e (0) 5958 (0) 5820 (0)\n002 2 2c3d 3547 | 11 39b5 (0) 30c0 (0) 351d (0) 3547 (0)\n003 2 165d 18b0 | 14 1f15 (0) 1d53 (0) 1b61 (0) 1a16 (0)\n004 3 016e 0104 051c | 7 00b9 (0) 0066 (0) 016e (0) 0104 (0)\n005 1 089f | 1 089f (0)\n============ DEPTH: 6 ==========================================\n006 1 0d90 | 1 0d90 (0)\n007 1 0ef0 | 1 0ef0 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"id":"c796d4917dd22d9836a9d7d24ba6f89e1a0e8a78a207bd930991e44e9c80ac1de8e4e1a023d550a6dfa60270fbb3935a7e03ef389c1ccda957a4a6a75ef6819b"}}},{"node":{"up":true,"config":{"services":["pss","bzz"],"name":"node09","id":"f3bf16c7156ce55af92b2fc21826bdfd3e1f245c6087e76f5eb23cc8bbd88b25515a32029d3e6e2b4a27354606e9e3bdfe78788e326c4349d63416894fcfbaf4","private_key":"3f63c3dd3bf2b5be6e9af3ce596eb65cb58a36749d0baff1759d8dc6f4da8993"},"info":{"id":"f3bf16c7156ce55af92b2fc21826bdfd3e1f245c6087e76f5eb23cc8bbd88b25515a32029d3e6e2b4a27354606e9e3bdfe78788e326c4349d63416894fcfbaf4","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 7c992c\npopulation: 14 (99), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 869f | 28 9835 (0) 9265 (0) 8ff6 (0) 88a9 (0)\n001 1 0f19 | 36 39b5 (0) 30c0 (0) 351d (0) 3547 (0)\n002 4 5f8e 580a 5820 5958 | 16 5f1c (0) 5f8e (0) 5958 (0) 5820 (0)\n003 2 6b1f 66f6 | 11 6d30 (0) 6c29 (0) 6c2f (0) 69ba (0)\n004 2 7468 74a4 | 4 766b (0) 776f (0) 7468 (0) 74a4 (0)\n============ DEPTH: 5 ==========================================\n005 3 795d 78db 7a46 | 3 795d (0) 78db (0) 7a46 (0)\n006 0 | 0\n007 1 7d14 | 1 7d14 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"fJks7v4DGHvOHtv4+AzNHKuAs5COYlph/vIextNdBKM="},"ip":"0.0.0.0","ports":{"listener":0,"discovery":0},"name":"node09","listenAddr":"","enode":"enode://f3bf16c7156ce55af92b2fc21826bdfd3e1f245c6087e76f5eb23cc8bbd88b25515a32029d3e6e2b4a27354606e9e3bdfe78788e326c4349d63416894fcfbaf4@0.0.0.0:0"}}},{"node":{"info":{"id":"fb20c708420e60c48fa65980ae11adc8cdf9b56ab93044a9aee9b5196d52f29e6cb2c218f73fefbdaecf8177bae1d9d13dd64bbe06e631555715b93f58f47137","protocols":{"bzz":"Zvb/X7wlJsHbXbSR5JE4NivvIwMsY0TtTq19y1i9Hmw=","hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 66f6ff\npopulation: 16 (126), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 f7cd 869f 8166 | 53 b778 (0) b270 (0) b26e (0) b87c (0)\n001 2 3547 171f | 36 39b5 (0) 30c0 (0) 351d (0) 3547 (0)\n002 4 41f4 5f1c 5f8e 5958 | 18 5f1c (0) 5f8e (0) 5958 (0) 5820 (0)\n003 1 7c99 | 9 766b (0) 776f (0) 7468 (0) 74a4 (0)\n004 3 6c2f 6b1f 6b7d | 7 6d30 (0) 6c29 (0) 6c2f (0) 69ba (0)\n============ DEPTH: 5 ==========================================\n005 2 60cb 62d5 | 2 60cb (0) 62d5 (0)\n006 1 6421 | 1 6421 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ip":"0.0.0.0","ports":{"listener":0,"discovery":0},"enode":"enode://fb20c708420e60c48fa65980ae11adc8cdf9b56ab93044a9aee9b5196d52f29e6cb2c218f73fefbdaecf8177bae1d9d13dd64bbe06e631555715b93f58f47137@0.0.0.0:0","listenAddr":"","name":"node10"},"config":{"services":["pss","bzz"],"name":"node10","id":"fb20c708420e60c48fa65980ae11adc8cdf9b56ab93044a9aee9b5196d52f29e6cb2c218f73fefbdaecf8177bae1d9d13dd64bbe06e631555715b93f58f47137","private_key":"38ffbfff1b5ab2f905daabcbbc12a5e28aad826a80d0a40988a04d6653942a50"},"up":true}},{"node":{"config":{"name":"node11","services":["pss","bzz"],"private_key":"aa2cc30f2f6e589ca122890fc95845f4a81ad7e57f2661343ff6af3d401c46f3","id":"f8fd12d8b5872b74e2cfa60d6a3a25b568a1fb4be3a8d06faac02a38321f419c443e517c0e2989001635f827add1859a2dc9589a9c0f5bf3804d46f43f799116"},"up":true,"info":{"protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 171f8d\npopulation: 24 (107), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 bb9c fb21 | 35 b26e (0) bb9c (0) a20d (0) a3e8 (0)\n001 5 5f1c 5958 74a4 6d30 | 37 5f8e (0) 5f1c (0) 5958 (0) 5820 (0)\n002 2 30c0 20c4 | 11 39b5 (0) 351d (0) 3547 (0) 30c0 (0)\n003 3 016e 0104 051c | 11 089f (0) 0d90 (0) 0ef0 (0) 0f19 (0)\n004 5 1f15 1d53 1b61 1a69 | 6 1f15 (0) 1d53 (0) 1b61 (0) 1a16 (0)\n005 5 11b5 1030 1316 12df | 5 11b5 (0) 1030 (0) 1316 (0) 1263 (0)\n006 0 | 0\n============ DEPTH: 7 ==========================================\n007 2 160c 165d | 2 160c (0) 165d (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"Fx+NMnGcHDozDN7ELkfwpYdrsswcrI8TV5+c0ZiHxTE="},"id":"f8fd12d8b5872b74e2cfa60d6a3a25b568a1fb4be3a8d06faac02a38321f419c443e517c0e2989001635f827add1859a2dc9589a9c0f5bf3804d46f43f799116","listenAddr":"","name":"node11","enode":"enode://f8fd12d8b5872b74e2cfa60d6a3a25b568a1fb4be3a8d06faac02a38321f419c443e517c0e2989001635f827add1859a2dc9589a9c0f5bf3804d46f43f799116@0.0.0.0:0","ip":"0.0.0.0","ports":{"listener":0,"discovery":0}}}},{"node":{"up":true,"config":{"id":"193ca2ef8a4ac98c0300d7e48421ba3fe5d4789a0c2b476499bd093808c3988b4a55742ff3f607429cafda08cbbb5fba68da8869747b1b5169f3e4545497de3a","private_key":"5b4a4da121c72f3d0d453394e6f09fc9ddaa5a13e44acb1ef6684867b4cac14c","services":["pss","bzz"],"name":"node12"},"info":{"ports":{"listener":0,"discovery":0},"ip":"0.0.0.0","enode":"enode://193ca2ef8a4ac98c0300d7e48421ba3fe5d4789a0c2b476499bd093808c3988b4a55742ff3f607429cafda08cbbb5fba68da8869747b1b5169f3e4545497de3a@0.0.0.0:0","name":"node12","listenAddr":"","id":"193ca2ef8a4ac98c0300d7e48421ba3fe5d4789a0c2b476499bd093808c3988b4a55742ff3f607429cafda08cbbb5fba68da8869747b1b5169f3e4545497de3a","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 74a4ff\npopulation: 14 (115), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 f9e4 fb21 | 42 a6ca (0) a3e8 (0) a20d (0) adfd (0)\n001 3 1f15 171f 20c4 | 36 089f (0) 0ef0 (0) 0f19 (0) 0d90 (0)\n002 1 4a2d | 18 5958 (0) 5820 (0) 580a (0) 5f8e (0)\n003 2 6421 60cb | 11 60cb (0) 62d5 (0) 66f6 (0) 6421 (0)\n004 3 7d14 7c99 7a46 | 5 795d (0) 78db (0) 7a46 (0) 7d14 (0)\n005 0 | 0\n============ DEPTH: 6 ==========================================\n006 2 766b 776f | 2 766b (0) 776f (0)\n007 0 | 0\n008 1 7468 | 1 7468 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"dKT/sNcXpSPscuB8xe/j6Y1Vky1uBZLvRf5Us3jk6VI="}}}},{"node":{"up":true,"config":{"name":"node13","services":["pss","bzz"],"private_key":"98f5b9f4be5d997b66834ae619c58f54d941623dfcb9a6783bfce77fdb3f3d4b","id":"f87c2dea026ba5e6cda9a446821bf057d3453fa8c9b38fd882a09979ff3cfe2b8adfcbd5cf28d268776414bd12a9aba385d5c97c76a29c1b0625b101faac761d"},"info":{"id":"f87c2dea026ba5e6cda9a446821bf057d3453fa8c9b38fd882a09979ff3cfe2b8adfcbd5cf28d268776414bd12a9aba385d5c97c76a29c1b0625b101faac761d","protocols":{"bzz":"IMTDo1I5YK10U45ybhyq7amHy8FtzTvutj/KbuvTFAU=","hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 20c4c3\npopulation: 18 (119), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 a6ca bb9c e884 | 46 8ff6 (0) 8937 (0) 8357 (0) 8174 (0)\n001 4 45cd 6c29 6b7d 74a4 | 38 5f8e (0) 5f1c (0) 5958 (0) 5820 (0)\n002 2 165d 171f | 25 089f (0) 0d90 (0) 0ef0 (0) 0f19 (0)\n003 3 351d 3547 30c0 | 4 39b5 (0) 351d (0) 3547 (0) 30c0 (0)\n004 1 2c3d | 1 2c3d (0)\n005 3 2426 247d 2742 | 3 2742 (0) 2426 (0) 247d (0)\n============ DEPTH: 6 ==========================================\n006 1 22b8 | 1 22b8 (0)\n007 1 2124 | 1 2124 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ip":"0.0.0.0","ports":{"listener":0,"discovery":0},"name":"node13","listenAddr":"","enode":"enode://f87c2dea026ba5e6cda9a446821bf057d3453fa8c9b38fd882a09979ff3cfe2b8adfcbd5cf28d268776414bd12a9aba385d5c97c76a29c1b0625b101faac761d@0.0.0.0:0"}}},{"node":{"up":true,"config":{"id":"d6c3095290d455c3855cfa88ee5f10d1975fdb0cc7ebc9aaa2330658e4229b9850f70f17798e530b50907d3d0d27fa49c0ed7dd4a7913d53c6881c5c86f380b8","private_key":"cbbe3c5ab5aafd2dae03deda6db9a3e7e58ffaad5c1edd37d7a13951aa733590","services":["pss","bzz"],"name":"node14"},"info":{"id":"d6c3095290d455c3855cfa88ee5f10d1975fdb0cc7ebc9aaa2330658e4229b9850f70f17798e530b50907d3d0d27fa49c0ed7dd4a7913d53c6881c5c86f380b8","protocols":{"bzz":"Rc2qxMCH5rc3UH+imTbQny++oU9J7wzpHBgIBFanRZs=","hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 45cdaa\npopulation: 9 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 efde 8174 | 54 e22c (0) e884 (0) e8d0 (0) ede2 (0)\n001 1 20c4 | 36 089f (0) 0ef0 (0) 0f19 (0) 0d90 (0)\n002 1 6b7d | 20 766b (0) 776f (0) 7468 (0) 74a4 (0)\n003 1 580a | 8 5f1c (0) 5f8e (0) 5958 (0) 5820 (0)\n004 1 4a2d | 3 4e6e (0) 4f7a (0) 4a2d (0)\n005 1 41f4 | 4 43d7 (0) 4067 (0) 41cd (0) 41f4 (0)\n============ DEPTH: 6 ==========================================\n006 1 4610 | 1 4610 (0)\n007 0 | 0\n008 0 | 0\n009 1 459a | 1 459a (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"listener":0,"discovery":0},"ip":"0.0.0.0","enode":"enode://d6c3095290d455c3855cfa88ee5f10d1975fdb0cc7ebc9aaa2330658e4229b9850f70f17798e530b50907d3d0d27fa49c0ed7dd4a7913d53c6881c5c86f380b8@0.0.0.0:0","name":"node14","listenAddr":""}}},{"node":{"up":true,"config":{"name":"node15","services":["pss","bzz"],"private_key":"62a83d45655860933bf8a2348695dd695176f3225f4ba72e70284b648130d330","id":"bebbde654a4f3e3e65f63d10cbcc89dfd46ce75945c19be33bfe4d954c8ed375981e21a8376ad10e402dddbcf3b657e6786c0820e599a0d1fe03f8d35294d7c7"},"info":{"protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 81748a\npopulation: 12 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 45cd | 74 089f (0) 0ef0 (0) 0f19 (0) 0d90 (0)\n001 1 cd94 | 24 e22c (0) e884 (0) e8d0 (0) ede2 (0)\n002 3 b87c b270 b778 | 12 b778 (0) b270 (0) b26e (0) b87c (0)\n003 1 9dc8 | 9 9265 (0) 944e (0) 958e (0) 960e (0)\n004 2 88dc 8937 | 4 8937 (0) 88dc (0) 88a9 (0) 8ff6 (0)\n005 2 869f 8584 | 2 869f (0) 8584 (0)\n============ DEPTH: 6 ==========================================\n006 1 8357 | 1 8357 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 1 8166 | 1 8166 (0)\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"gXSKGjgWL56GE/+lYq3Rt1iTtmGZhA50wHdNuSv9fKA="},"id":"bebbde654a4f3e3e65f63d10cbcc89dfd46ce75945c19be33bfe4d954c8ed375981e21a8376ad10e402dddbcf3b657e6786c0820e599a0d1fe03f8d35294d7c7","name":"node15","listenAddr":"","enode":"enode://bebbde654a4f3e3e65f63d10cbcc89dfd46ce75945c19be33bfe4d954c8ed375981e21a8376ad10e402dddbcf3b657e6786c0820e599a0d1fe03f8d35294d7c7@0.0.0.0:0","ports":{"discovery":0,"listener":0},"ip":"0.0.0.0"}}},{"node":{"up":true,"config":{"id":"0d85f39dca79f99b277ad5cedfcd3fb1eccc7862c95c215ba0d5a2ec1c4fa80244393d0934cf59fe988f7716bf15cb8e79f4ee03fbe4a48a10cac6e0610f9d55","private_key":"8c72a0c564073065c5300e822a476fe3dd8b373cfd0dabaf0cdb056ca0ece2f9","services":["pss","bzz"],"name":"node16"},"info":{"enode":"enode://0d85f39dca79f99b277ad5cedfcd3fb1eccc7862c95c215ba0d5a2ec1c4fa80244393d0934cf59fe988f7716bf15cb8e79f4ee03fbe4a48a10cac6e0610f9d55@0.0.0.0:0","name":"node16","listenAddr":"","ports":{"listener":0,"discovery":0},"ip":"0.0.0.0","protocols":{"bzz":"zZRK1MUMQ1cAX/Ju8mNpujN1oSBe7FMrblGyK/JVELw=","hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: cd944a\npopulation: 18 (122), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 22b8 1263 580a 6b7d | 69 4f7a (0) 4a2d (0) 43d7 (0) 41f4 (0)\n001 3 9a8c 8ff6 8174 | 30 b270 (0) b26e (0) b778 (0) b87c (0)\n002 5 efde f7cd fb21 f843 | 14 e884 (0) e8d0 (0) ede2 (0) ef40 (0)\n003 1 d24a | 4 d6e3 (0) d6a2 (0) d486 (0) d24a (0)\n004 3 c1c1 c42f c6ed | 3 c1c1 (0) c6ed (0) c42f (0)\n============ DEPTH: 5 ==========================================\n005 1 cb70 | 1 cb70 (0)\n006 1 ce12 | 1 ce12 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"id":"0d85f39dca79f99b277ad5cedfcd3fb1eccc7862c95c215ba0d5a2ec1c4fa80244393d0934cf59fe988f7716bf15cb8e79f4ee03fbe4a48a10cac6e0610f9d55"}}},{"node":{"info":{"ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","name":"node17","enode":"enode://64a39acfb1accea032dfc4d1530b5cdbdc8c1b609a442b68a9b534a539062d051b750a4512b0a9d504fdffa2a5bc8d4fcb6ca59f4ddb1c59ce62e8913644499b@0.0.0.0:0","id":"64a39acfb1accea032dfc4d1530b5cdbdc8c1b609a442b68a9b534a539062d051b750a4512b0a9d504fdffa2a5bc8d4fcb6ca59f4ddb1c59ce62e8913644499b","protocols":{"bzz":"a32mNujsysZYwKv2qo3ddL5tTPnF4DM70o2abR/kOrM=","hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 6b7da6\npopulation: 16 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 cd94 | 54 9265 (0) 944e (0) 958e (0) 960e (0)\n001 2 1a69 20c4 | 36 39b5 (0) 30c0 (0) 351d (0) 3547 (0)\n002 3 5f8e 45cd 459a | 18 5258 (0) 5672 (0) 57d3 (0) 5f1c (0)\n003 2 7468 776f | 9 7468 (0) 74a4 (0) 766b (0) 776f (0)\n004 3 60cb 66f6 6421 | 4 60cb (0) 62d5 (0) 66f6 (0) 6421 (0)\n005 2 6d30 6c2f | 3 6d30 (0) 6c29 (0) 6c2f (0)\n006 1 69ba | 1 69ba (0)\n============ DEPTH: 7 ==========================================\n007 1 6ad6 | 1 6ad6 (0)\n008 0 | 0\n009 1 6b1f | 1 6b1f (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"services":["pss","bzz"],"name":"node17","id":"64a39acfb1accea032dfc4d1530b5cdbdc8c1b609a442b68a9b534a539062d051b750a4512b0a9d504fdffa2a5bc8d4fcb6ca59f4ddb1c59ce62e8913644499b","private_key":"b6eb72555f9952a32406b7576ac85ead5cbe9004f37b6ebe8f7c3b6e17973104"},"up":true}},{"node":{"up":true,"config":{"name":"node18","services":["pss","bzz"],"private_key":"e9bdb2a275f0f2fd6ef4266bca55fad475c5d9e4ee0db2951ae91fd629cb2029","id":"236266f9f5a28148d11bed1195a91cd1d30231b082697ee1940a85abca98d2ff0767be9128c23375caa0444bcf51d8501879200ea0f27f13d0ede37f97241325"},"info":{"enode":"enode://236266f9f5a28148d11bed1195a91cd1d30231b082697ee1940a85abca98d2ff0767be9128c23375caa0444bcf51d8501879200ea0f27f13d0ede37f97241325@0.0.0.0:0","listenAddr":"","name":"node18","ports":{"listener":0,"discovery":0},"ip":"0.0.0.0","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 642189\npopulation: 19 (122), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 9dc8 9835 | 49 9265 (0) 958e (0) 944e (0) 960e (0)\n001 4 2742 3547 1a69 051c | 36 39b5 (0) 30c0 (0) 3547 (0) 351d (0)\n002 2 5820 5f8e | 18 5258 (0) 5672 (0) 57d3 (0) 5f1c (0)\n003 3 7a46 74a4 776f | 9 766b (0) 776f (0) 7468 (0) 74a4 (0)\n004 5 6c2f 69ba 6ad6 6b1f | 7 6d30 (0) 6c29 (0) 6c2f (0) 69ba (0)\n============ DEPTH: 5 ==========================================\n005 2 60cb 62d5 | 2 60cb (0) 62d5 (0)\n006 1 66f6 | 1 66f6 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"ZCGJTiXkIdFuzNiFiu0zVPzi0EydXEbUAF7h8WlEzP0="},"id":"236266f9f5a28148d11bed1195a91cd1d30231b082697ee1940a85abca98d2ff0767be9128c23375caa0444bcf51d8501879200ea0f27f13d0ede37f97241325"}}},{"node":{"up":true,"config":{"id":"fa4174ca214905c4136e891e64349f664f166aeeacead6f6e84892ebcadd2c7fbff07052ea4913a9465999f5494962ec29f7f7a3e6cbb993e00d1b881fb31eb1","private_key":"d9a2bcdb02288fd5844d0be689ea4286f27991bfc82c76f6050a3e3d2f0858a1","services":["pss","bzz"],"name":"node19"},"info":{"protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 051c8d\npopulation: 14 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 8357 bb9c adfd a6ca | 54 b270 (0) b26e (0) b778 (0) b87c (0)\n001 2 459a 6421 | 38 5258 (0) 5672 (0) 57d3 (0) 5f1c (0)\n002 1 22b8 | 11 39b5 (0) 30c0 (0) 3547 (0) 351d (0)\n003 2 18b0 171f | 14 1f15 (0) 1d53 (0) 1b61 (0) 1a16 (0)\n004 1 0f19 | 4 089f (0) 0d90 (0) 0ef0 (0) 0f19 (0)\n005 2 0104 00b9 | 4 00b9 (0) 0066 (0) 016e (0) 0104 (0)\n============ DEPTH: 6 ==========================================\n006 1 07c7 | 1 07c7 (0)\n007 0 | 0\n008 0 | 0\n009 1 0561 | 1 0561 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"BRyNQwtU2EP+syXCtW42UkVm1k9I9sdwc5dIQJr0Q2Q="},"id":"fa4174ca214905c4136e891e64349f664f166aeeacead6f6e84892ebcadd2c7fbff07052ea4913a9465999f5494962ec29f7f7a3e6cbb993e00d1b881fb31eb1","enode":"enode://fa4174ca214905c4136e891e64349f664f166aeeacead6f6e84892ebcadd2c7fbff07052ea4913a9465999f5494962ec29f7f7a3e6cbb993e00d1b881fb31eb1@0.0.0.0:0","listenAddr":"","name":"node19","ip":"0.0.0.0","ports":{"discovery":0,"listener":0}}}},{"node":{"info":{"protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 459a94\npopulation: 18 (102), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 f926 9a8c | 36 efde (0) e22c (0) f7cd (0) fd54 (0)\n001 1 051c | 29 30c0 (0) 3547 (0) 351d (0) 2c3d (0)\n002 3 78db 6b7d 6b1f | 20 74a4 (0) 7468 (0) 766b (0) 776f (0)\n003 4 5672 5f8e 5958 580a | 8 5258 (0) 5672 (0) 57d3 (0) 5f1c (0)\n004 2 4f7a 4a2d | 3 4e6e (0) 4f7a (0) 4a2d (0)\n005 4 43d7 4067 41cd 41f4 | 4 43d7 (0) 4067 (0) 41cd (0) 41f4 (0)\n============ DEPTH: 6 ==========================================\n006 1 4610 | 1 4610 (0)\n007 0 | 0\n008 0 | 0\n009 1 45cd | 1 45cd (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"RZqUXI1uZ0N736DgZ5YrNZHfoKp8EXf4MnuhVXu/FWk="},"id":"45c635c4080d47e2f932c27472e487ec95b7644c3d94d8627166a33dca2e3cbaa3305ae2d42e1510bfb0f8329b90e5a31883b399a469ad548fcae3040a8833a0","name":"node20","listenAddr":"","enode":"enode://45c635c4080d47e2f932c27472e487ec95b7644c3d94d8627166a33dca2e3cbaa3305ae2d42e1510bfb0f8329b90e5a31883b399a469ad548fcae3040a8833a0@0.0.0.0:0","ports":{"listener":0,"discovery":0},"ip":"0.0.0.0"},"config":{"private_key":"8ee0c4634570903c3d7383adb12cd35a82bb1c9be593755bd77c90a1bd6bbdfe","id":"45c635c4080d47e2f932c27472e487ec95b7644c3d94d8627166a33dca2e3cbaa3305ae2d42e1510bfb0f8329b90e5a31883b399a469ad548fcae3040a8833a0","name":"node20","services":["pss","bzz"]},"up":true}},{"node":{"info":{"id":"850e729f9bbb5ef6e12baf7d3dced180839e88e0845baa7aa8fb87dcb417aa74af5999bda81723aabbef5eda842fa4b5fae107fcff9f6bd50597e8ba6a849dff","protocols":{"bzz":"moxgcy/w0LdAOxgc3Fu55tsKpM9ccVjEDlSPy3Zyb4c=","hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 9a8c60\npopulation: 17 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 22b8 6b1f 459a | 74 39b5 (0) 30c0 (0) 3547 (0) 351d (0)\n001 5 f843 efde d6a2 d24a | 24 d6a2 (0) d6e3 (0) d486 (0) d24a (0)\n002 1 a93b | 12 b270 (0) b26e (0) b778 (0) b87c (0)\n003 2 8584 8166 | 9 8ff6 (0) 8937 (0) 88dc (0) 88a9 (0)\n004 2 960e 9265 | 4 944e (0) 958e (0) 960e (0) 9265 (0)\n005 2 9d60 9dc8 | 2 9d60 (0) 9dc8 (0)\n============ DEPTH: 6 ==========================================\n006 1 9835 | 1 9835 (0)\n007 1 9b24 | 1 9b24 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"enode":"enode://850e729f9bbb5ef6e12baf7d3dced180839e88e0845baa7aa8fb87dcb417aa74af5999bda81723aabbef5eda842fa4b5fae107fcff9f6bd50597e8ba6a849dff@0.0.0.0:0","listenAddr":"","name":"node21"},"config":{"id":"850e729f9bbb5ef6e12baf7d3dced180839e88e0845baa7aa8fb87dcb417aa74af5999bda81723aabbef5eda842fa4b5fae107fcff9f6bd50597e8ba6a849dff","private_key":"16df12116ebc93bdc671ba1351bf03b763d3e67b2c9c468e56177c80b0dcbf84","services":["pss","bzz"],"name":"node21"},"up":true}},{"node":{"info":{"ip":"0.0.0.0","ports":{"listener":0,"discovery":0},"name":"node22","listenAddr":"","enode":"enode://6ba8900830489793a22bf5023cde4ab849dee525d1ca5b95e21040a8e8be5b295317b1c76e09beb7d17a9512137c487b99f16933622b5f2b0e10da3233086bbf@0.0.0.0:0","id":"6ba8900830489793a22bf5023cde4ab849dee525d1ca5b95e21040a8e8be5b295317b1c76e09beb7d17a9512137c487b99f16933622b5f2b0e10da3233086bbf","protocols":{"bzz":"ax86m2XOOhaPyY3uKxSx3mkS/QLuJgmwR7LFb2w7U+k=","hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 6b1f3a\npopulation: 19 (84), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 9a8c | 25 d6e3 (0) d486 (0) d24a (0) c42f (0)\n001 2 1a69 1263 | 25 3547 (0) 351d (0) 2c3d (0) 22b8 (0)\n002 2 459a 580a | 15 4a2d (0) 43d7 (0) 4067 (0) 41cd (0)\n003 6 7d14 7c99 795d 7a46 | 9 74a4 (0) 7468 (0) 766b (0) 776f (0)\n004 3 60cb 66f6 6421 | 4 60cb (0) 62d5 (0) 66f6 (0) 6421 (0)\n005 2 6d30 6c2f | 3 6d30 (0) 6c29 (0) 6c2f (0)\n006 1 69ba | 1 69ba (0)\n============ DEPTH: 7 ==========================================\n007 1 6ad6 | 1 6ad6 (0)\n008 0 | 0\n009 1 6b7d | 1 6b7d (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"up":true,"config":{"services":["pss","bzz"],"name":"node22","id":"6ba8900830489793a22bf5023cde4ab849dee525d1ca5b95e21040a8e8be5b295317b1c76e09beb7d17a9512137c487b99f16933622b5f2b0e10da3233086bbf","private_key":"1a78b7fedaab9310b17675717481b1331eed3fa3c77cd96addf6bf9abd778aae"}}},{"node":{"config":{"id":"54b79d3662ba486bbd120313d59ef101acf963eb3d6112a9dda121bc0b52f4b1fbcb13406705cdd8c2d3990ad296171c7972211467cc0d44cbe9ca16fbc82e3e","private_key":"3d37e996f181b4f57d5c5a61a07f86f1869c760604dfe9166d5b3552acf1a43b","services":["pss","bzz"],"name":"node23"},"up":true,"info":{"enode":"enode://54b79d3662ba486bbd120313d59ef101acf963eb3d6112a9dda121bc0b52f4b1fbcb13406705cdd8c2d3990ad296171c7972211467cc0d44cbe9ca16fbc82e3e@0.0.0.0:0","listenAddr":"","name":"node23","ip":"0.0.0.0","ports":{"listener":0,"discovery":0},"protocols":{"bzz":"EmPxi/jLT1ozNfVFzdXULxuE2p7fT6c0ZXLCvDjIfrM=","hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 1263f1\npopulation: 15 (120), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 cd94 efde | 47 d24a (0) d6e3 (0) d486 (0) c1c1 (0)\n001 2 6b1f 580a | 38 766b (0) 776f (0) 74a4 (0) 7468 (0)\n002 3 30c0 3547 351d | 11 39b5 (0) 351d (0) 3547 (0) 30c0 (0)\n003 1 089f | 11 089f (0) 0d90 (0) 0ef0 (0) 0f19 (0)\n004 1 18b0 | 6 1f15 (0) 1d53 (0) 1b61 (0) 1a16 (0)\n005 2 165d 171f | 3 160c (0) 165d (0) 171f (0)\n006 2 1030 11b5 | 2 11b5 (0) 1030 (0)\n============ DEPTH: 7 ==========================================\n007 1 1316 | 1 1316 (0)\n008 1 12df | 1 12df (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"id":"54b79d3662ba486bbd120313d59ef101acf963eb3d6112a9dda121bc0b52f4b1fbcb13406705cdd8c2d3990ad296171c7972211467cc0d44cbe9ca16fbc82e3e"}}},{"node":{"info":{"protocols":{"bzz":"WAplDCw+ldNeZiZN9vSOKKCRus0g3CyYKKW1YzU9IFI=","hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 580a65\npopulation: 18 (124), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 efde cd94 d486 | 51 d24a (0) d6a2 (0) d6e3 (0) d486 (0)\n001 1 1263 | 36 39b5 (0) 30c0 (0) 351d (0) 3547 (0)\n002 5 7c99 7a46 69ba 6b1f | 20 74a4 (0) 7468 (0) 766b (0) 776f (0)\n003 3 459a 45cd 4a2d | 10 4e6e (0) 4f7a (0) 4a2d (0) 43d7 (0)\n004 2 5672 57d3 | 3 5258 (0) 5672 (0) 57d3 (0)\n005 2 5f1c 5f8e | 2 5f1c (0) 5f8e (0)\n006 0 | 0\n============ DEPTH: 7 ==========================================\n007 1 5958 | 1 5958 (0)\n008 0 | 0\n009 0 | 0\n010 1 5820 | 1 5820 (0)\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"id":"b737c81fe6bc50d977231a5fc8856f064ba58190c5ab5615d3cf634aea8c15a308f3a667aad2e69d5c1438549cd41c863fd40f643b70caf3e0c934276ef2a84f","listenAddr":"","name":"node24","enode":"enode://b737c81fe6bc50d977231a5fc8856f064ba58190c5ab5615d3cf634aea8c15a308f3a667aad2e69d5c1438549cd41c863fd40f643b70caf3e0c934276ef2a84f@0.0.0.0:0","ports":{"discovery":0,"listener":0},"ip":"0.0.0.0"},"up":true,"config":{"name":"node24","services":["pss","bzz"],"private_key":"5895ce723440eaa77daf0a8779cc52992427524e420e3ce71ce1b24f3bd4658c","id":"b737c81fe6bc50d977231a5fc8856f064ba58190c5ab5615d3cf634aea8c15a308f3a667aad2e69d5c1438549cd41c863fd40f643b70caf3e0c934276ef2a84f"}}},{"node":{"info":{"id":"09fa1e69f37cb14db3dd721a9c4b9c884f6fe519d850f7af3643ecd536d4b3e995f99acf569e23b7864996c750115ff0ca0bd446ebfd76a026da71da0b95fd97","protocols":{"bzz":"bC/RKchJPOp2NKkarlWc62TwHOvEXsWa69fnCbZZQb4=","hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 6c2fd1\npopulation: 12 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 f7cd | 54 b270 (0) b26e (0) b778 (0) b87c (0)\n001 1 165d | 36 39b5 (0) 30c0 (0) 351d (0) 3547 (0)\n002 2 5820 580a | 18 5258 (0) 5672 (0) 57d3 (0) 5f1c (0)\n003 1 776f | 9 74a4 (0) 7468 (0) 766b (0) 776f (0)\n004 2 6421 66f6 | 4 60cb (0) 62d5 (0) 66f6 (0) 6421 (0)\n005 3 69ba 6b7d 6b1f | 4 69ba (0) 6ad6 (0) 6b7d (0) 6b1f (0)\n006 0 | 0\n============ DEPTH: 7 ==========================================\n007 1 6d30 | 1 6d30 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 1 6c29 | 1 6c29 (0)\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"discovery":0,"listener":0},"ip":"0.0.0.0","listenAddr":"","name":"node25","enode":"enode://09fa1e69f37cb14db3dd721a9c4b9c884f6fe519d850f7af3643ecd536d4b3e995f99acf569e23b7864996c750115ff0ca0bd446ebfd76a026da71da0b95fd97@0.0.0.0:0"},"config":{"services":["pss","bzz"],"name":"node25","id":"09fa1e69f37cb14db3dd721a9c4b9c884f6fe519d850f7af3643ecd536d4b3e995f99acf569e23b7864996c750115ff0ca0bd446ebfd76a026da71da0b95fd97","private_key":"cf20ef905d7d3d1141c472afefd12332bff10edecc695e409af38086c7a1a5d1"},"up":true}},{"node":{"up":true,"config":{"private_key":"1a7c744024c7baee8c43425861a5a4ff2ea80533fe6549a58e61b50c93059fed","id":"123633b35f455fc3240d99929dc3130bb018545672be151ba973915f2ab6e6c862748f60d917e48ccbf28620c4e58b888867cb51e12ec0d2e5c61cef82258719","name":"node26","services":["pss","bzz"]},"info":{"name":"node26","listenAddr":"","enode":"enode://123633b35f455fc3240d99929dc3130bb018545672be151ba973915f2ab6e6c862748f60d917e48ccbf28620c4e58b888867cb51e12ec0d2e5c61cef82258719@0.0.0.0:0","ip":"0.0.0.0","ports":{"listener":0,"discovery":0},"protocols":{"bzz":"980cwXSiHxkKcV2thIV/VjkI25YPKllD7wFcr2IgqNM=","hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: f7cd1c\npopulation: 26 (107), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 1316 4a2d 66f6 6c2f | 57 30c0 (0) 3547 (0) 39b5 (0) 2c3d (0)\n001 7 b26e b778 a20d 960e | 28 b270 (0) b26e (0) b778 (0) b87c (0)\n002 6 d24a c1c1 c42f c6ed | 10 d486 (0) d6a2 (0) d6e3 (0) d24a (0)\n003 2 e22c efde | 5 e884 (0) ede2 (0) ef40 (0) efde (0)\n============ DEPTH: 4 ==========================================\n004 7 fe9d fcf3 fd54 fb21 | 7 fe9d (0) fcf3 (0) fd54 (0) fb21 (0)\n005 0 | 0\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"id":"123633b35f455fc3240d99929dc3130bb018545672be151ba973915f2ab6e6c862748f60d917e48ccbf28620c4e58b888867cb51e12ec0d2e5c61cef82258719"}}},{"node":{"info":{"listenAddr":"","name":"node27","enode":"enode://7625a1a0a0f5bf78e2b9fe43a1215ea882318458b886ec767ccbc35e76b543f96820b364342b28ff600302af7716280497141dc2fc84e83cb15f5eb3d268d73e@0.0.0.0:0","ip":"0.0.0.0","ports":{"listener":0,"discovery":0},"protocols":{"bzz":"Si0VuGemIGU/CZ1mg5uAwt0yrslcr5BvDVyBRhku32I=","hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 4a2d15\npopulation: 16 (104), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 fb21 f9e4 f7cd | 39 b778 (0) b26e (0) bb9c (0) a20d (0)\n001 1 2c3d | 29 30c0 (0) 351d (0) 3547 (0) 2c3d (0)\n002 2 74a4 7468 | 19 766b (0) 776f (0) 74a4 (0) 7468 (0)\n003 2 5958 580a | 8 5258 (0) 5672 (0) 57d3 (0) 5f1c (0)\n004 6 43d7 4067 41f4 4610 | 7 43d7 (0) 4067 (0) 41cd (0) 41f4 (0)\n============ DEPTH: 5 ==========================================\n005 2 4e6e 4f7a | 2 4e6e (0) 4f7a (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"id":"7625a1a0a0f5bf78e2b9fe43a1215ea882318458b886ec767ccbc35e76b543f96820b364342b28ff600302af7716280497141dc2fc84e83cb15f5eb3d268d73e"},"up":true,"config":{"name":"node27","services":["pss","bzz"],"private_key":"7399aa5562abb3ca2add08c810d607ad6fed7a036622eaea561da8a5aa51c0af","id":"7625a1a0a0f5bf78e2b9fe43a1215ea882318458b886ec767ccbc35e76b543f96820b364342b28ff600302af7716280497141dc2fc84e83cb15f5eb3d268d73e"}}},{"node":{"info":{"enode":"enode://4903cd53b3ffc4328547e03dec8f7992edbfb1e1697e53772ef79887984b11595167eb84015ff3dfb26ac0d7b2e98b7a0792bef843d2bdff3a76889fc4a6c60a@0.0.0.0:0","listenAddr":"","name":"node28","ports":{"listener":0,"discovery":0},"ip":"0.0.0.0","protocols":{"bzz":"+eTbsoCZr4yl8oxkGlFnL0xqtUtwN/dlpxcqOZrLjtw=","hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: f9e4db\npopulation: 11 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 74a4 4a2d | 74 39b5 (0) 30c0 (0) 3547 (0) 351d (0)\n001 1 9265 | 30 b778 (0) b270 (0) b26e (0) b87c (0)\n002 1 cd94 | 10 d6a2 (0) d6e3 (0) d486 (0) d24a (0)\n003 2 efde e22c | 6 e884 (0) e8d0 (0) ede2 (0) ef40 (0)\n004 1 f7cd | 1 f7cd (0)\n005 1 fe9d | 3 fd54 (0) fcf3 (0) fe9d (0)\n006 1 fb21 | 1 fb21 (0)\n============ DEPTH: 7 ==========================================\n007 1 f843 | 1 f843 (0)\n008 1 f926 | 1 f926 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"id":"4903cd53b3ffc4328547e03dec8f7992edbfb1e1697e53772ef79887984b11595167eb84015ff3dfb26ac0d7b2e98b7a0792bef843d2bdff3a76889fc4a6c60a"},"config":{"name":"node28","services":["pss","bzz"],"private_key":"ded7b34b0c8218bfba59e8d061b50cea365a9f137b9a66064e2287ef660dc789","id":"4903cd53b3ffc4328547e03dec8f7992edbfb1e1697e53772ef79887984b11595167eb84015ff3dfb26ac0d7b2e98b7a0792bef843d2bdff3a76889fc4a6c60a"},"up":true}},{"node":{"config":{"services":["pss","bzz"],"name":"node29","id":"d6794744c5f941cb6dbac4adbbbf11ce83c9224c8a34b9c787ed5975bf0af13e095a7db1c86fcbb7b134ae6dc67467d3ffaf191f4a4d9218779c4d0cf86876ca","private_key":"39ac5498c92329fc18c4eb0ec36cca3c5270f322084a1fc42fad1be0b5f32081"},"up":true,"info":{"id":"d6794744c5f941cb6dbac4adbbbf11ce83c9224c8a34b9c787ed5975bf0af13e095a7db1c86fcbb7b134ae6dc67467d3ffaf191f4a4d9218779c4d0cf86876ca","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 926538\npopulation: 14 (114), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 3547 2c3d | 61 30c0 (0) 351d (0) 3547 (0) 2c3d (0)\n001 2 fb21 f9e4 | 24 d6a2 (0) d6e3 (0) d486 (0) d24a (0)\n002 2 b270 b778 | 12 b778 (0) b270 (0) b26e (0) b87c (0)\n003 1 869f | 9 8ff6 (0) 88dc (0) 88a9 (0) 8937 (0)\n004 4 9d60 9dc8 9b24 9a8c | 5 9d60 (0) 9dc8 (0) 9835 (0) 9b24 (0)\n============ DEPTH: 5 ==========================================\n005 3 958e 944e 960e | 3 944e (0) 958e (0) 960e (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"kmU4Ps93bOHaZumeXwqcGvWT2OVs7vIfQqrUvn40vEU="},"ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"enode":"enode://d6794744c5f941cb6dbac4adbbbf11ce83c9224c8a34b9c787ed5975bf0af13e095a7db1c86fcbb7b134ae6dc67467d3ffaf191f4a4d9218779c4d0cf86876ca@0.0.0.0:0","name":"node29","listenAddr":""}}},{"node":{"info":{"protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: fb211f\npopulation: 19 (123), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 5 2124 171f 4a2d 74a4 | 70 351d (0) 3547 (0) 30c0 (0) 2c3d (0)\n001 2 869f 9265 | 30 b778 (0) b270 (0) b26e (0) b87c (0)\n002 3 c1c1 ce12 cd94 | 10 d6a2 (0) d6e3 (0) d486 (0) d24a (0)\n003 2 ede2 efde | 6 e884 (0) e8d0 (0) ede2 (0) ef40 (0)\n004 1 f7cd | 1 f7cd (0)\n005 3 fe9d fd54 fcf3 | 3 fd54 (0) fcf3 (0) fe9d (0)\n============ DEPTH: 6 ==========================================\n006 3 f843 f926 f9e4 | 3 f843 (0) f926 (0) f9e4 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"+yEfQFp9w6B7bU8YUixic/+k4YMllY7qFZ4z92jq6EY="},"id":"a5990a680e1f01dcd71a178a239880c5ce24418748c368b8e3c8a1175cfd744d16973cba03e5e756820950920a6d9fa5d5dd53829a1d1d508371cb1042e9453e","listenAddr":"","name":"node30","enode":"enode://a5990a680e1f01dcd71a178a239880c5ce24418748c368b8e3c8a1175cfd744d16973cba03e5e756820950920a6d9fa5d5dd53829a1d1d508371cb1042e9453e@0.0.0.0:0","ports":{"listener":0,"discovery":0},"ip":"0.0.0.0"},"config":{"name":"node30","services":["pss","bzz"],"private_key":"add3ad2926ebf0b30f111796475cf160bcd1f1756866dfaa19e048c6954975c9","id":"a5990a680e1f01dcd71a178a239880c5ce24418748c368b8e3c8a1175cfd744d16973cba03e5e756820950920a6d9fa5d5dd53829a1d1d508371cb1042e9453e"},"up":true}},{"node":{"config":{"name":"node31","services":["pss","bzz"],"private_key":"d5290ae40b68ae7b51fe7ce7d83ab96841aa97a3457fc1bcf70065a2d2b60c20","id":"4f4201d959e4add3a4bcf3cbaab29d8abcc7530a9834e3cde45c4459ea92fba869e65156037a8fae02eac05f6174a7f2c1d825418f2207caa2284bcc9d9b84d1"},"up":true,"info":{"protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 7d14fd\npopulation: 15 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 8166 fb21 | 54 b778 (0) b270 (0) b26e (0) b87c (0)\n001 1 2c3d | 36 39b5 (0) 30c0 (0) 351d (0) 3547 (0)\n002 3 5820 5958 5f8e | 18 5f1c (0) 5f8e (0) 5958 (0) 5820 (0)\n003 2 62d5 6b1f | 11 60cb (0) 62d5 (0) 66f6 (0) 6421 (0)\n004 3 776f 7468 74a4 | 4 766b (0) 776f (0) 74a4 (0) 7468 (0)\n============ DEPTH: 5 ==========================================\n005 3 795d 78db 7a46 | 3 795d (0) 78db (0) 7a46 (0)\n006 0 | 0\n007 1 7c99 | 1 7c99 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"fRT9C2xVTyGCSf7XcJ31GUa6+RowRe2Z+2YsMsyXVBs="},"id":"4f4201d959e4add3a4bcf3cbaab29d8abcc7530a9834e3cde45c4459ea92fba869e65156037a8fae02eac05f6174a7f2c1d825418f2207caa2284bcc9d9b84d1","name":"node31","listenAddr":"","enode":"enode://4f4201d959e4add3a4bcf3cbaab29d8abcc7530a9834e3cde45c4459ea92fba869e65156037a8fae02eac05f6174a7f2c1d825418f2207caa2284bcc9d9b84d1@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0}}}},{"node":{"config":{"services":["pss","bzz"],"name":"node32","id":"ef3016ea5a7b1b57388904d5c80fd05780d23acec8cf73e8add28ea99c6222fa84e89a1752186a2ef41dd0ec828405e61a1e8fd67d9496d75525ed860b12e2e8","private_key":"ba7abd532b10496c6363f35e231ff80aef25246315302fd138dd977d5ece20e5"},"up":true,"info":{"name":"node32","listenAddr":"","enode":"enode://ef3016ea5a7b1b57388904d5c80fd05780d23acec8cf73e8add28ea99c6222fa84e89a1752186a2ef41dd0ec828405e61a1e8fd67d9496d75525ed860b12e2e8@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"protocols":{"bzz":"gWYJ1bm9sMe61svpQA/VBt+GYrFK0OCmG8e0lIJUjjk=","hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 816609\npopulation: 19 (92), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 165d 66f6 7d14 | 51 39b5 (0) 30c0 (0) 247d (0) 2426 (0)\n001 2 f926 efde | 18 e8d0 (0) efde (0) e22c (0) fe9d (0)\n002 4 a3e8 bb9c b26e b778 | 7 b778 (0) b26e (0) bb9c (0) a3e8 (0)\n003 3 9dc8 9835 9a8c | 8 9265 (0) 958e (0) 960e (0) 9d60 (0)\n004 3 88dc 88a9 8937 | 4 8ff6 (0) 88dc (0) 88a9 (0) 8937 (0)\n005 2 869f 8584 | 2 869f (0) 8584 (0)\n============ DEPTH: 6 ==========================================\n006 1 8357 | 1 8357 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 1 8174 | 1 8174 (0)\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"id":"ef3016ea5a7b1b57388904d5c80fd05780d23acec8cf73e8add28ea99c6222fa84e89a1752186a2ef41dd0ec828405e61a1e8fd67d9496d75525ed860b12e2e8"}}},{"node":{"info":{"id":"f78ecf420b73cd0245807157c0cbaaa568c60c80965413e187b084fb26041761d12790c0cb6a39bc8997fd2b3d3f52c831e601f1f1846945fba1808b0e1cdf25","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 165d67\npopulation: 25 (103), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 8166 8ff6 | 37 d24a (0) d486 (0) c1c1 (0) c6ed (0)\n001 5 6d30 6c2f 4610 5958 | 32 78db (0) 7a46 (0) 7d14 (0) 7c99 (0)\n002 2 30c0 20c4 | 10 39b5 (0) 351d (0) 30c0 (0) 2742 (0)\n003 5 00b9 016e 0d90 0f19 | 11 0d90 (0) 0ef0 (0) 0f19 (0) 089f (0)\n004 5 18b0 1b61 1a69 1f15 | 6 18b0 (0) 1b61 (0) 1a16 (0) 1a69 (0)\n005 4 1263 12df 11b5 1030 | 5 1316 (0) 1263 (0) 12df (0) 11b5 (0)\n006 0 | 0\n============ DEPTH: 7 ==========================================\n007 1 171f | 1 171f (0)\n008 0 | 0\n009 1 160c | 1 160c (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"Fl1nCtIJIiJuHzJ1q9FTtv6Nn/4+RebB/K4/Wj0uw1o="},"ip":"0.0.0.0","ports":{"listener":0,"discovery":0},"enode":"enode://f78ecf420b73cd0245807157c0cbaaa568c60c80965413e187b084fb26041761d12790c0cb6a39bc8997fd2b3d3f52c831e601f1f1846945fba1808b0e1cdf25@0.0.0.0:0","listenAddr":"","name":"node33"},"config":{"name":"node33","services":["pss","bzz"],"private_key":"e58bb287592c2b89814ed3475004f5c9b2eb226483fcb8235619b6b42747d10c","id":"f78ecf420b73cd0245807157c0cbaaa568c60c80965413e187b084fb26041761d12790c0cb6a39bc8997fd2b3d3f52c831e601f1f1846945fba1808b0e1cdf25"},"up":true}},{"node":{"info":{"ports":{"discovery":0,"listener":0},"ip":"0.0.0.0","enode":"enode://3e65bbf7103b3307bd9b8a65168c7c87c3f5283c7c52edefabf4193a1f04ac10216cc485a1dae17cff9ccea41bcf9a0b41de001c6142f30701443dc1735f25c0@0.0.0.0:0","name":"node34","listenAddr":"","id":"3e65bbf7103b3307bd9b8a65168c7c87c3f5283c7c52edefabf4193a1f04ac10216cc485a1dae17cff9ccea41bcf9a0b41de001c6142f30701443dc1735f25c0","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 8ff601\npopulation: 14 (123), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 5f8e 165d | 72 60cb (0) 62d5 (0) 66f6 (0) 6421 (0)\n001 3 f843 cd94 d486 | 22 d24a (0) d6e3 (0) d486 (0) c1c1 (0)\n002 2 b270 b778 | 12 b778 (0) b270 (0) b26e (0) b87c (0)\n003 2 9b24 958e | 9 9265 (0) 960e (0) 944e (0) 958e (0)\n004 2 869f 8584 | 5 8357 (0) 8174 (0) 8166 (0) 869f (0)\n============ DEPTH: 5 ==========================================\n005 3 8937 88dc 88a9 | 3 8937 (0) 88dc (0) 88a9 (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"j/YB3pU3yeXXmjcHoxL+iTODvvAA0ArO49RVIGjvYDA="}},"up":true,"config":{"id":"3e65bbf7103b3307bd9b8a65168c7c87c3f5283c7c52edefabf4193a1f04ac10216cc485a1dae17cff9ccea41bcf9a0b41de001c6142f30701443dc1735f25c0","private_key":"53e9afc6c039fee226bd9a0b537355f23e93457dc0eabbdce75e4d1ad7a473e6","services":["pss","bzz"],"name":"node34"}}},{"node":{"info":{"listenAddr":"","name":"node35","enode":"enode://eeb9d718ef61c14e10ab2fb3a90b039368acd17a59f70628deb39515c227bd0916c796cd7767b1a9d4f38e04f1013173b21c1fa2e0206ecdc72df6c2621380a2@0.0.0.0:0","ports":{"listener":0,"discovery":0},"ip":"0.0.0.0","protocols":{"bzz":"X462/w9u1yDqroY5B1eDP0uc36UlZEV+2Qw94mCrbDA=","hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 5f8eb6\npopulation: 17 (96), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 8584 8ff6 | 33 d486 (0) c6ed (0) cb70 (0) cd94 (0)\n001 2 18b0 165d | 30 12df (0) 1030 (0) 171f (0) 160c (0)\n002 5 7c99 7d14 6b7d 66f6 | 19 60cb (0) 62d5 (0) 66f6 (0) 6421 (0)\n003 2 459a 4610 | 7 4067 (0) 41f4 (0) 43d7 (0) 4610 (0)\n004 2 5672 57d3 | 3 5258 (0) 5672 (0) 57d3 (0)\n============ DEPTH: 5 ==========================================\n005 3 5958 5820 580a | 3 5958 (0) 5820 (0) 580a (0)\n006 0 | 0\n007 0 | 0\n008 1 5f1c | 1 5f1c (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"id":"eeb9d718ef61c14e10ab2fb3a90b039368acd17a59f70628deb39515c227bd0916c796cd7767b1a9d4f38e04f1013173b21c1fa2e0206ecdc72df6c2621380a2"},"up":true,"config":{"id":"eeb9d718ef61c14e10ab2fb3a90b039368acd17a59f70628deb39515c227bd0916c796cd7767b1a9d4f38e04f1013173b21c1fa2e0206ecdc72df6c2621380a2","private_key":"079cf6730627562bbbff031d22ab1ae9e65b7747497adc327830e5d6768d6b04","services":["pss","bzz"],"name":"node35"}}},{"node":{"up":true,"config":{"name":"node36","services":["pss","bzz"],"private_key":"c3157fe034d3a477f697b756cd9ae1de532b0ae42bb5039f6d2bf399bb2ddbbd","id":"57fb9e7f287fe67500b8b560475c0d0d6eae9d623d5a8c85eb5459f209904a839a0b24ff99a1643a4196a71d45f2ed1bd5e08f9a13cdd9749a907a024ff984dc"},"info":{"ports":{"discovery":0,"listener":0},"ip":"0.0.0.0","listenAddr":"","name":"node36","enode":"enode://57fb9e7f287fe67500b8b560475c0d0d6eae9d623d5a8c85eb5459f209904a839a0b24ff99a1643a4196a71d45f2ed1bd5e08f9a13cdd9749a907a024ff984dc@0.0.0.0:0","id":"57fb9e7f287fe67500b8b560475c0d0d6eae9d623d5a8c85eb5459f209904a839a0b24ff99a1643a4196a71d45f2ed1bd5e08f9a13cdd9749a907a024ff984dc","protocols":{"bzz":"hYRUE4UPXjjM5pVI4gF5tHe/OD3SsiQoNYcV2dckIaw=","hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 858454\npopulation: 15 (124), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 57d3 5f8e | 71 11b5 (0) 1030 (0) 1316 (0) 12df (0)\n001 2 ce12 d486 | 24 d24a (0) d6e3 (0) d6a2 (0) d486 (0)\n002 4 a20d b87c b26e b778 | 12 b778 (0) b270 (0) b26e (0) b87c (0)\n003 2 9dc8 9a8c | 9 9265 (0) 944e (0) 958e (0) 960e (0)\n004 1 8ff6 | 4 8ff6 (0) 8937 (0) 88dc (0) 88a9 (0)\n============ DEPTH: 5 ==========================================\n005 3 8357 8174 8166 | 3 8357 (0) 8174 (0) 8166 (0)\n006 1 869f | 1 869f (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}}}},{"node":{"info":{"ports":{"listener":0,"discovery":0},"ip":"0.0.0.0","listenAddr":"","name":"node37","enode":"enode://af6cb988ddb16202459735b8489c02b3bf829ca301513a0d3e18bbb03d43c8de3cda767c7b5c984a6dce3f118c8089e06b08ed3bd0c922dde9cfe775609df3b2@0.0.0.0:0","id":"af6cb988ddb16202459735b8489c02b3bf829ca301513a0d3e18bbb03d43c8de3cda767c7b5c984a6dce3f118c8089e06b08ed3bd0c922dde9cfe775609df3b2","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 57d336\npopulation: 13 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 efde 8584 | 54 d24a (0) d6a2 (0) d6e3 (0) d486 (0)\n001 1 2c3d | 36 11b5 (0) 1030 (0) 1316 (0) 1263 (0)\n002 2 7468 776f | 20 60cb (0) 62d5 (0) 66f6 (0) 6421 (0)\n003 1 4610 | 10 4067 (0) 41cd (0) 41f4 (0) 43d7 (0)\n004 5 5f1c 5f8e 5820 580a | 5 5f1c (0) 5f8e (0) 5958 (0) 5820 (0)\n============ DEPTH: 5 ==========================================\n005 1 5258 | 1 5258 (0)\n006 0 | 0\n007 1 5672 | 1 5672 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"V9M2HuWdAG4duj4a6epiRETuCfcEEN/0ktYk1+d4bS0="}},"config":{"private_key":"d4472d7bc821536231d70dbdb3f0a5e3fdd104dcbf5a97c9521b0778d9491680","id":"af6cb988ddb16202459735b8489c02b3bf829ca301513a0d3e18bbb03d43c8de3cda767c7b5c984a6dce3f118c8089e06b08ed3bd0c922dde9cfe775609df3b2","name":"node37","services":["pss","bzz"]},"up":true}},{"node":{"up":true,"config":{"services":["pss","bzz"],"name":"node38","id":"55beb7853107501c013283d0114f9812c2e97b292f90ae9bdd5aa8189d0379a758cbf19c5fa62436bc75a6e30d935a3bd52025b06efd167fa2fb8a1caead2f83","private_key":"23c79a6a5af06f9e9cdb6f4b4e40e25eca8793ac91db22cde17e0a3851c1f48e"},"info":{"ip":"0.0.0.0","ports":{"listener":0,"discovery":0},"enode":"enode://55beb7853107501c013283d0114f9812c2e97b292f90ae9bdd5aa8189d0379a758cbf19c5fa62436bc75a6e30d935a3bd52025b06efd167fa2fb8a1caead2f83@0.0.0.0:0","listenAddr":"","name":"node38","id":"55beb7853107501c013283d0114f9812c2e97b292f90ae9bdd5aa8189d0379a758cbf19c5fa62436bc75a6e30d935a3bd52025b06efd167fa2fb8a1caead2f83","protocols":{"bzz":"d2/bq7ykLstJzFRRuGAwXsMCCIm0etqirdbqNZr+N58=","hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 776fdb\npopulation: 15 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 c42f d486 | 54 d24a (0) d6e3 (0) d6a2 (0) d486 (0)\n001 1 22b8 | 36 11b5 (0) 1030 (0) 1316 (0) 1263 (0)\n002 1 57d3 | 18 43d7 (0) 41cd (0) 41f4 (0) 4067 (0)\n003 5 6421 6c2f 6d30 6b1f | 11 60cb (0) 62d5 (0) 6421 (0) 66f6 (0)\n004 3 7d14 7a46 78db | 5 7a46 (0) 795d (0) 78db (0) 7d14 (0)\n005 0 | 0\n============ DEPTH: 6 ==========================================\n006 2 74a4 7468 | 2 74a4 (0) 7468 (0)\n007 1 766b | 1 766b (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}}}},{"node":{"info":{"ip":"0.0.0.0","ports":{"listener":0,"discovery":0},"enode":"enode://41ded7596eac3eddfd1f7656ef23adabe1d18027f6159e45867e935d1ab742ec298ba2b23df522f79f59c7805510d8c995837380432dee37912d6ede1196caa2@0.0.0.0:0","name":"node39","listenAddr":"","id":"41ded7596eac3eddfd1f7656ef23adabe1d18027f6159e45867e935d1ab742ec298ba2b23df522f79f59c7805510d8c995837380432dee37912d6ede1196caa2","protocols":{"bzz":"IrhN9zBZySv1n9rVH+V04CfHzFVd3b82PXRcHEIqif0=","hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 22b84d\npopulation: 13 (121), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 9a8c e22c cd94 | 48 d24a (0) d486 (0) d6e3 (0) d6a2 (0)\n001 1 776f | 38 43d7 (0) 41cd (0) 41f4 (0) 4067 (0)\n002 2 051c 1d53 | 25 11b5 (0) 1030 (0) 1316 (0) 1263 (0)\n003 1 3547 | 4 39b5 (0) 30c0 (0) 3547 (0) 351d (0)\n004 1 2c3d | 1 2c3d (0)\n005 3 2742 247d 2426 | 3 2742 (0) 247d (0) 2426 (0)\n============ DEPTH: 6 ==========================================\n006 2 2124 20c4 | 2 2124 (0) 20c4 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"private_key":"0295fa1706ccdcbdc8d7943b8d2011c6f46225d85b574d2d02b4a8dec66f9a29","id":"41ded7596eac3eddfd1f7656ef23adabe1d18027f6159e45867e935d1ab742ec298ba2b23df522f79f59c7805510d8c995837380432dee37912d6ede1196caa2","name":"node39","services":["pss","bzz"]},"up":true}},{"node":{"info":{"id":"464cf4c4203246240a63965062b9e5a7e5fa903f127b1f5ea5b37a27d33d8b12768fc2d8f257e67418f1e5765e627ca8f8cd5ba6b15b8a047490d26ce43e6291","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 2c3d7e\npopulation: 20 (119), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 5 9265 9dc8 e22c d486 | 46 d24a (0) d6e3 (0) d6a2 (0) d486 (0)\n001 4 4a2d 57d3 7d14 7468 | 38 43d7 (0) 4067 (0) 41cd (0) 41f4 (0)\n002 4 00b9 0f19 1030 1d53 | 25 11b5 (0) 1030 (0) 1316 (0) 1263 (0)\n003 1 351d | 4 39b5 (0) 30c0 (0) 3547 (0) 351d (0)\n============ DEPTH: 4 ==========================================\n004 6 2742 2426 247d 2124 | 6 2742 (0) 247d (0) 2426 (0) 2124 (0)\n005 0 | 0\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"LD1+BW+H2vVAghox6o/pN30A7TpV/7pnuLtxbN2bcwM="},"ports":{"listener":0,"discovery":0},"ip":"0.0.0.0","name":"node40","listenAddr":"","enode":"enode://464cf4c4203246240a63965062b9e5a7e5fa903f127b1f5ea5b37a27d33d8b12768fc2d8f257e67418f1e5765e627ca8f8cd5ba6b15b8a047490d26ce43e6291@0.0.0.0:0"},"up":true,"config":{"private_key":"34d1685a48b56e62b30247fffb44ba2b41f2d806344fe52f7dc9049a778c667f","id":"464cf4c4203246240a63965062b9e5a7e5fa903f127b1f5ea5b37a27d33d8b12768fc2d8f257e67418f1e5765e627ca8f8cd5ba6b15b8a047490d26ce43e6291","name":"node40","services":["pss","bzz"]}}},{"node":{"up":true,"config":{"private_key":"b6273af6a94c07db54566d0d2f93121d0ddf239921e8e46af19babd2fa9930a7","id":"de7ab7b9a2ba4ed523b84233fae11d93815579976ea78b385c658a4c156622747051f91342f9ac3610e22ee259b65e02b5af0ab67a9ee04ab6958a9d0d8acdf1","name":"node41","services":["pss","bzz"]},"info":{"ip":"0.0.0.0","ports":{"listener":0,"discovery":0},"enode":"enode://de7ab7b9a2ba4ed523b84233fae11d93815579976ea78b385c658a4c156622747051f91342f9ac3610e22ee259b65e02b5af0ab67a9ee04ab6958a9d0d8acdf1@0.0.0.0:0","name":"node41","listenAddr":"","id":"de7ab7b9a2ba4ed523b84233fae11d93815579976ea78b385c658a4c156622747051f91342f9ac3610e22ee259b65e02b5af0ab67a9ee04ab6958a9d0d8acdf1","protocols":{"bzz":"dGiY0ZeTTRfNk7lYqyCqqF26mQV0lQSNLKvIqZaSbgU=","hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 746898\npopulation: 13 (120), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 a93b | 48 c42f (0) c6ed (0) cb70 (0) cd94 (0)\n001 3 1f15 1d53 2c3d | 35 11b5 (0) 1030 (0) 1316 (0) 12df (0)\n002 2 4a2d 57d3 | 18 43d7 (0) 41cd (0) 41f4 (0) 4067 (0)\n003 1 6b7d | 11 60cb (0) 62d5 (0) 6421 (0) 66f6 (0)\n004 3 7d14 7c99 78db | 5 7d14 (0) 7c99 (0) 7a46 (0) 795d (0)\n005 0 | 0\n============ DEPTH: 6 ==========================================\n006 2 766b 776f | 2 766b (0) 776f (0)\n007 0 | 0\n008 1 74a4 | 1 74a4 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}}}},{"node":{"config":{"id":"69f3f9fafff951dca2fe98baa178e53f2779311a93fdc364cf4c2477700c8dbce7e4201c3aa6d840b5ae65e8fc9d6603cbc41dbdf601f1998caedee1b542d72b","private_key":"362244251a7f1bf4bc855ff3b272b1c7c7fe5d8338af0c581fee2f49e2939ed8","services":["pss","bzz"],"name":"node42"},"up":true,"info":{"protocols":{"bzz":"qTsjYLh0JYYBhVNayo+/MiXgwUHSdpDWAURomuDyhTQ=","hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: a93b23\npopulation: 14 (107), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 7468 1d53 | 60 4610 (0) 459a (0) 4f7a (0) 4e6e (0)\n001 2 d6e3 d24a | 18 c1c1 (0) c6ed (0) c42f (0) cd94 (0)\n002 2 9a8c 9dc8 | 18 8ff6 (0) 8937 (0) 88dc (0) 88a9 (0)\n003 3 b26e b87c bb9c | 5 b778 (0) b270 (0) b26e (0) b87c (0)\n004 2 a6ca a3e8 | 3 a6ca (0) a20d (0) a3e8 (0)\n============ DEPTH: 5 ==========================================\n005 3 aff7 adfd ac38 | 3 aff7 (0) adfd (0) ac38 (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"id":"69f3f9fafff951dca2fe98baa178e53f2779311a93fdc364cf4c2477700c8dbce7e4201c3aa6d840b5ae65e8fc9d6603cbc41dbdf601f1998caedee1b542d72b","listenAddr":"","name":"node42","enode":"enode://69f3f9fafff951dca2fe98baa178e53f2779311a93fdc364cf4c2477700c8dbce7e4201c3aa6d840b5ae65e8fc9d6603cbc41dbdf601f1998caedee1b542d72b@0.0.0.0:0","ip":"0.0.0.0","ports":{"listener":0,"discovery":0}}}},{"node":{"info":{"protocols":{"bzz":"HVMbXI3Xu7v4wtuPaYTSybI9X+4zh2N56dPmKpIOBLk=","hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 1d531b\npopulation: 19 (115), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 fe9d bb9c a93b | 42 ce12 (0) cd94 (0) d486 (0) d6e3 (0)\n001 3 5958 7468 78db | 38 41cd (0) 41f4 (0) 4067 (0) 43d7 (0)\n002 2 2c3d 22b8 | 11 39b5 (0) 30c0 (0) 3547 (0) 351d (0)\n003 1 0561 | 11 0ef0 (0) 0f19 (0) 0d90 (0) 089f (0)\n004 5 1030 12df 171f 160c | 8 11b5 (0) 1030 (0) 1316 (0) 1263 (0)\n============ DEPTH: 5 ==========================================\n005 4 18b0 1b61 1a16 1a69 | 4 18b0 (0) 1b61 (0) 1a16 (0) 1a69 (0)\n006 1 1f15 | 1 1f15 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"id":"dee5fb5ccdfe3803cab3e0041c5c4879001bf2c2233446f47245d8234642046269bfe50e414cd2d89341e338597f2ecbb7b2912c20558a85041b757a24490805","enode":"enode://dee5fb5ccdfe3803cab3e0041c5c4879001bf2c2233446f47245d8234642046269bfe50e414cd2d89341e338597f2ecbb7b2912c20558a85041b757a24490805@0.0.0.0:0","listenAddr":"","name":"node43","ip":"0.0.0.0","ports":{"discovery":0,"listener":0}},"config":{"id":"dee5fb5ccdfe3803cab3e0041c5c4879001bf2c2233446f47245d8234642046269bfe50e414cd2d89341e338597f2ecbb7b2912c20558a85041b757a24490805","private_key":"bf6cd10025d018c0abfae2c88aa7c46c3d12d612580e6b4aacdc51fd52476270","services":["pss","bzz"],"name":"node43"},"up":true}},{"node":{"info":{"protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 78db86\npopulation: 13 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 e22c | 54 8ff6 (0) 8937 (0) 88dc (0) 88a9 (0)\n001 2 0561 1d53 | 36 39b5 (0) 30c0 (0) 3547 (0) 351d (0)\n002 2 459a 4610 | 18 43d7 (0) 41cd (0) 41f4 (0) 4067 (0)\n003 1 6d30 | 11 6421 (0) 66f6 (0) 60cb (0) 62d5 (0)\n004 3 766b 776f 7468 | 4 766b (0) 776f (0) 74a4 (0) 7468 (0)\n005 2 7d14 7c99 | 2 7d14 (0) 7c99 (0)\n============ DEPTH: 6 ==========================================\n006 1 7a46 | 1 7a46 (0)\n007 1 795d | 1 795d (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"eNuGPX9g7aaidcyfTRaWyzL11G3nR9J4qhfs0Gx5ETU="},"id":"3dcf5ec3ebb3b7de61dfaef4ee397a4a13a96ee40673be2eaadfcadd11f139c594c74237b40dd9c10f059f40d325c014f5b02b3a8eb7f0dc7d66ced7fea9f17f","name":"node44","listenAddr":"","enode":"enode://3dcf5ec3ebb3b7de61dfaef4ee397a4a13a96ee40673be2eaadfcadd11f139c594c74237b40dd9c10f059f40d325c014f5b02b3a8eb7f0dc7d66ced7fea9f17f@0.0.0.0:0","ports":{"listener":0,"discovery":0},"ip":"0.0.0.0"},"config":{"id":"3dcf5ec3ebb3b7de61dfaef4ee397a4a13a96ee40673be2eaadfcadd11f139c594c74237b40dd9c10f059f40d325c014f5b02b3a8eb7f0dc7d66ced7fea9f17f","private_key":"0659e3a41adc716b493c6ad765c5b26d35c95a1edb254efc8ab967e71e3e0a16","services":["pss","bzz"],"name":"node44"},"up":true}},{"node":{"config":{"services":["pss","bzz"],"name":"node45","id":"c708e3584cd9450b30d8cdd960a676884f64364c2aec985eebb4a0d745f6c73b6b0cb16f330bf090320bc48a5a67e8519b3c2c4a64cf2eff9aa4f1fc0b274a00","private_key":"f6d48b4c10f3257bba2f626d48192d94a1b1de3ab1480b618a0bff07eb20396e"},"up":true,"info":{"id":"c708e3584cd9450b30d8cdd960a676884f64364c2aec985eebb4a0d745f6c73b6b0cb16f330bf090320bc48a5a67e8519b3c2c4a64cf2eff9aa4f1fc0b274a00","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: e22c1f\npopulation: 21 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 1316 22b8 2c3d 78db | 74 18b0 (0) 1b61 (0) 1a16 (0) 1a69 (0)\n001 3 9dc8 b87c aff7 | 30 8ff6 (0) 8937 (0) 88dc (0) 88a9 (0)\n002 2 d24a d6a2 | 10 c1c1 (0) c6ed (0) c42f (0) cb70 (0)\n003 7 f7cd f843 f926 f9e4 | 8 f7cd (0) fb21 (0) f843 (0) f9e4 (0)\n============ DEPTH: 4 ==========================================\n004 5 ede2 efde ef40 e884 | 5 ede2 (0) ef40 (0) efde (0) e884 (0)\n005 0 | 0\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"4iwfdMS0gP3S++hK0yGpgjDvuY+xzexPeeTlCysNXMQ="},"ip":"0.0.0.0","ports":{"listener":0,"discovery":0},"name":"node45","listenAddr":"","enode":"enode://c708e3584cd9450b30d8cdd960a676884f64364c2aec985eebb4a0d745f6c73b6b0cb16f330bf090320bc48a5a67e8519b3c2c4a64cf2eff9aa4f1fc0b274a00@0.0.0.0:0"}}},{"node":{"up":true,"config":{"name":"node46","services":["pss","bzz"],"private_key":"4a487eb7a3b924414d988104fce6f87a70502db2d5d71dcbc1a115b37212cb06","id":"a302bebe4590b3f6d2c511919ceef4a5a80d431f53f8f3483c4b833a6a3b5f79b4c66c0ce2c0e5bc696534067ea5cd07772a9844ee0ba9d37a2e6f5d4bfb05cd"},"info":{"ports":{"listener":0,"discovery":0},"ip":"0.0.0.0","enode":"enode://a302bebe4590b3f6d2c511919ceef4a5a80d431f53f8f3483c4b833a6a3b5f79b4c66c0ce2c0e5bc696534067ea5cd07772a9844ee0ba9d37a2e6f5d4bfb05cd@0.0.0.0:0","name":"node46","listenAddr":"","id":"a302bebe4590b3f6d2c511919ceef4a5a80d431f53f8f3483c4b833a6a3b5f79b4c66c0ce2c0e5bc696534067ea5cd07772a9844ee0ba9d37a2e6f5d4bfb05cd","protocols":{"bzz":"r/d11H6+NfuqrSbGJ0cKu4SBVYy1oIxCpEWXqYQIqRk=","hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: aff775\npopulation: 11 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 5958 | 74 1263 (0) 12df (0) 1316 (0) 11b5 (0)\n001 1 e22c | 24 c1c1 (0) c6ed (0) c42f (0) cb70 (0)\n002 1 8937 | 18 8ff6 (0) 8937 (0) 88dc (0) 88a9 (0)\n003 3 b26e bb9c b87c | 5 b778 (0) b270 (0) b26e (0) b87c (0)\n004 2 a6ca a3e8 | 3 a6ca (0) a20d (0) a3e8 (0)\n005 1 a93b | 1 a93b (0)\n============ DEPTH: 6 ==========================================\n006 2 adfd ac38 | 2 adfd (0) ac38 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}}}},{"node":{"config":{"private_key":"9e2309fa485ace73ce907035f5113e7b13e5719c819479b10fd9386a3ad5236f","id":"a4dd67ab4fff1a50968c7ab59c304eb0083b072fc13dff599eeadac4e0e75099f7c825f91dd1bb770f3ae6f3d1d82ad574d6ecb117adf1ca9ccbccd01303ec7c","name":"node47","services":["pss","bzz"]},"up":true,"info":{"protocols":{"bzz":"WVikzNUzPov+1fGMeNNlsgH/wrmvOv0xdIrbjk+BGLw=","hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 5958a4\npopulation: 19 (120), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 d24a fd54 aff7 | 52 c1c1 (0) c6ed (0) c42f (0) cb70 (0)\n001 5 00b9 089f 1d53 171f | 31 1263 (0) 1316 (0) 1030 (0) 11b5 (0)\n002 3 66f6 7d14 7c99 | 20 6421 (0) 66f6 (0) 60cb (0) 62d5 (0)\n003 2 459a 4a2d | 10 43d7 (0) 4067 (0) 41cd (0) 41f4 (0)\n004 2 5672 57d3 | 3 5258 (0) 5672 (0) 57d3 (0)\n005 2 5f1c 5f8e | 2 5f1c (0) 5f8e (0)\n006 0 | 0\n============ DEPTH: 7 ==========================================\n007 2 5820 580a | 2 5820 (0) 580a (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"id":"a4dd67ab4fff1a50968c7ab59c304eb0083b072fc13dff599eeadac4e0e75099f7c825f91dd1bb770f3ae6f3d1d82ad574d6ecb117adf1ca9ccbccd01303ec7c","name":"node47","listenAddr":"","enode":"enode://a4dd67ab4fff1a50968c7ab59c304eb0083b072fc13dff599eeadac4e0e75099f7c825f91dd1bb770f3ae6f3d1d82ad574d6ecb117adf1ca9ccbccd01303ec7c@0.0.0.0:0","ports":{"listener":0,"discovery":0},"ip":"0.0.0.0"}}},{"node":{"up":true,"config":{"services":["pss","bzz"],"name":"node48","id":"604a11bd1d969886953398ecc1fdf5847a946a8118014d0cb8daff9943f4f78c4bdbad3ee4152959c8265d0588dea658c262fe2f99a55a0b32321b81c8eec473","private_key":"e511c730e803371042c631512a12d74b1c31a53caab237719b8fa007e4cef9ea"},"info":{"protocols":{"bzz":"/VTzTR3urTMwFMRyGCv1yy2x0bGrVcqnD13HAQhiLxc=","hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: fd54f3\npopulation: 21 (117), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 016e 0104 5958 | 64 1030 (0) 12df (0) 1263 (0) 1316 (0)\n001 5 960e 8937 b778 adfd | 30 8ff6 (0) 8937 (0) 88dc (0) 88a9 (0)\n002 3 d6e3 d6a2 d24a | 10 c6ed (0) c42f (0) c1c1 (0) cb70 (0)\n003 4 ef40 e884 e8d0 e22c | 6 e22c (0) e884 (0) e8d0 (0) ede2 (0)\n004 1 f7cd | 1 f7cd (0)\n005 3 fb21 f843 f926 | 4 fb21 (0) f843 (0) f9e4 (0) f926 (0)\n============ DEPTH: 6 ==========================================\n006 1 fe9d | 1 fe9d (0)\n007 1 fcf3 | 1 fcf3 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"id":"604a11bd1d969886953398ecc1fdf5847a946a8118014d0cb8daff9943f4f78c4bdbad3ee4152959c8265d0588dea658c262fe2f99a55a0b32321b81c8eec473","name":"node48","listenAddr":"","enode":"enode://604a11bd1d969886953398ecc1fdf5847a946a8118014d0cb8daff9943f4f78c4bdbad3ee4152959c8265d0588dea658c262fe2f99a55a0b32321b81c8eec473@0.0.0.0:0","ports":{"listener":0,"discovery":0},"ip":"0.0.0.0"}}},{"node":{"info":{"ip":"0.0.0.0","ports":{"listener":0,"discovery":0},"enode":"enode://946b3f821a4b61661e8ace52f4ade415042fddf058d97a16f08d9eff7a0be633de47c27fa9760ff38d583b2405163d4a27d3a7949d4015271396c014043a34e3@0.0.0.0:0","listenAddr":"","name":"node49","id":"946b3f821a4b61661e8ace52f4ade415042fddf058d97a16f08d9eff7a0be633de47c27fa9760ff38d583b2405163d4a27d3a7949d4015271396c014043a34e3","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: ac3887\npopulation: 11 (125), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 0561 | 72 18b0 (0) 1a69 (0) 1a16 (0) 1b61 (0)\n001 1 fd54 | 24 c6ed (0) c42f (0) c1c1 (0) cb70 (0)\n002 1 88a9 | 18 8584 (0) 869f (0) 8166 (0) 8174 (0)\n003 2 bb9c b87c | 5 b778 (0) b270 (0) b26e (0) bb9c (0)\n004 3 a6ca a3e8 a20d | 3 a6ca (0) a20d (0) a3e8 (0)\n005 1 a93b | 1 a93b (0)\n============ DEPTH: 6 ==========================================\n006 1 aff7 | 1 aff7 (0)\n007 1 adfd | 1 adfd (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"rDiHMIpMNZEpPEP11fMSh0sw4NwZ+qV2Jv3GuDDT5DM="}},"config":{"private_key":"bb4c6b3c0931311ef5e31087f74a1a95aa39da470737c4c1a2a730ea2cac1c76","id":"946b3f821a4b61661e8ace52f4ade415042fddf058d97a16f08d9eff7a0be633de47c27fa9760ff38d583b2405163d4a27d3a7949d4015271396c014043a34e3","name":"node49","services":["pss","bzz"]},"up":true}},{"node":{"config":{"services":["pss","bzz"],"name":"node50","id":"c677530a47ef470ae0811127b91c231ec8889588bd096c24a54cc48099e8edde811f4a72eedc79118acb494ef031d6adcef1595d1a17df71b25b468478e931ff","private_key":"88c0abdb64c6dee8117b7b720d5782321ce583fcc76e6eed2ee1f6279a82ea39"},"up":true,"info":{"enode":"enode://c677530a47ef470ae0811127b91c231ec8889588bd096c24a54cc48099e8edde811f4a72eedc79118acb494ef031d6adcef1595d1a17df71b25b468478e931ff@0.0.0.0:0","listenAddr":"","name":"node50","ports":{"discovery":0,"listener":0},"ip":"0.0.0.0","protocols":{"bzz":"uHwO5xnQZWzTJTALdW8gMxBnUCHzxQizBULesRFOx6w=","hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: b87c0e\npopulation: 14 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 6d30 | 74 1030 (0) 11b5 (0) 1316 (0) 1263 (0)\n001 2 e8d0 e22c | 24 e22c (0) e884 (0) e8d0 (0) ede2 (0)\n002 3 869f 8584 8174 | 18 869f (0) 8584 (0) 8174 (0) 8166 (0)\n003 4 a3e8 a93b aff7 ac38 | 7 a6ca (0) a20d (0) a3e8 (0) a93b (0)\n============ DEPTH: 4 ==========================================\n004 3 b778 b270 b26e | 3 b778 (0) b270 (0) b26e (0)\n005 0 | 0\n006 1 bb9c | 1 bb9c (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"id":"c677530a47ef470ae0811127b91c231ec8889588bd096c24a54cc48099e8edde811f4a72eedc79118acb494ef031d6adcef1595d1a17df71b25b468478e931ff"}}},{"node":{"up":true,"config":{"services":["pss","bzz"],"name":"node51","id":"5a27b90639d515cad7794dae78bf9a9866cca23c5e3e18870524d148797ba1bdfd631151f23062d4dcf0961a7dba709431a44e39da29ed5ea4b0b6987514e433","private_key":"e6eef1e846329e10e247843f7cee455af8ad3579e5a1e6360aea0ecc51982759"},"info":{"enode":"enode://5a27b90639d515cad7794dae78bf9a9866cca23c5e3e18870524d148797ba1bdfd631151f23062d4dcf0961a7dba709431a44e39da29ed5ea4b0b6987514e433@0.0.0.0:0","listenAddr":"","name":"node51","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 6d307f\npopulation: 18 (117), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 fe9d 9dc8 bb9c b87c | 47 e22c (0) e884 (0) e8d0 (0) ede2 (0)\n001 3 12df 165d 171f | 33 11b5 (0) 1030 (0) 1316 (0) 1263 (0)\n002 3 5f1c 43d7 4610 | 18 4f7a (0) 4e6e (0) 4a2d (0) 41f4 (0)\n003 2 776f 78db | 9 766b (0) 776f (0) 74a4 (0) 7468 (0)\n004 1 62d5 | 4 62d5 (0) 60cb (0) 6421 (0) 66f6 (0)\n005 3 6b7d 6b1f 6ad6 | 4 69ba (0) 6ad6 (0) 6b1f (0) 6b7d (0)\n006 0 | 0\n============ DEPTH: 7 ==========================================\n007 2 6c29 6c2f | 2 6c2f (0) 6c29 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"bTB/NIzHHopHG6ZiwbW9nW5pMMIgJPNQRlzMx/Igilk="},"id":"5a27b90639d515cad7794dae78bf9a9866cca23c5e3e18870524d148797ba1bdfd631151f23062d4dcf0961a7dba709431a44e39da29ed5ea4b0b6987514e433"}}},{"node":{"up":true,"config":{"name":"node52","services":["pss","bzz"],"private_key":"ffd961376b67cbfafd47d89610291ec8fc2af2c16bc31e6851f804e15b2e9cd7","id":"0c000879be78fc867857011e396e2dd77bc2a0c6c2c3624d98b102737aa8d998ca9081653c0c8285117a5288b1bfeed06c54b2f6e39225aca4a21ff2a72116e1"},"info":{"enode":"enode://0c000879be78fc867857011e396e2dd77bc2a0c6c2c3624d98b102737aa8d998ca9081653c0c8285117a5288b1bfeed06c54b2f6e39225aca4a21ff2a72116e1@0.0.0.0:0","name":"node52","listenAddr":"","ports":{"listener":0,"discovery":0},"ip":"0.0.0.0","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 9dc8a0\npopulation: 24 (122), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 5 2124 2c3d 6421 6d30 | 70 1263 (0) 12df (0) 1030 (0) 171f (0)\n001 4 d6a2 e22c fcf3 fe9d | 23 e22c (0) e884 (0) e8d0 (0) ede2 (0)\n002 2 adfd a93b | 12 b778 (0) b270 (0) b26e (0) b87c (0)\n003 5 8584 8174 8166 8937 | 9 869f (0) 8584 (0) 8174 (0) 8166 (0)\n004 4 9265 944e 958e 960e | 4 9265 (0) 944e (0) 958e (0) 960e (0)\n============ DEPTH: 5 ==========================================\n005 3 9835 9b24 9a8c | 3 9835 (0) 9b24 (0) 9a8c (0)\n006 0 | 0\n007 0 | 0\n008 1 9d60 | 1 9d60 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"ncigVFrP3RLLmFUyuWJdiGC4yHqocfB/nJHxWZhggx4="},"id":"0c000879be78fc867857011e396e2dd77bc2a0c6c2c3624d98b102737aa8d998ca9081653c0c8285117a5288b1bfeed06c54b2f6e39225aca4a21ff2a72116e1"}}},{"node":{"config":{"private_key":"db9ca337fd3ecf30fa6c217606072c214028b8d723ce82de57cfb4f0266a653d","id":"223d79f656e3f124ee1238ca46e42c2a0d8500ee58a37312c6b72657a11ad9ebce3be4c061611b913a22863f6e7936ff37602dedc7856baea27e8201db44bbf4","name":"node53","services":["pss","bzz"]},"up":true,"info":{"enode":"enode://223d79f656e3f124ee1238ca46e42c2a0d8500ee58a37312c6b72657a11ad9ebce3be4c061611b913a22863f6e7936ff37602dedc7856baea27e8201db44bbf4@0.0.0.0:0","listenAddr":"","name":"node53","ip":"0.0.0.0","ports":{"listener":0,"discovery":0},"protocols":{"bzz":"RhDAbI9eHiSnXZ5GpDL0waa52mw9vRItPTiBdS2TBzY=","hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 4610c0\npopulation: 14 (126), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 9dc8 ef40 | 54 869f (0) 8584 (0) 8174 (0) 8166 (0)\n001 2 1030 165d | 35 1316 (0) 12df (0) 1263 (0) 1030 (0)\n002 2 78db 6d30 | 20 7d14 (0) 7c99 (0) 7a46 (0) 795d (0)\n003 3 5f8e 5672 57d3 | 8 5f1c (0) 5f8e (0) 5958 (0) 5820 (0)\n004 1 4a2d | 3 4f7a (0) 4e6e (0) 4a2d (0)\n005 2 41cd 41f4 | 4 4067 (0) 41cd (0) 41f4 (0) 43d7 (0)\n============ DEPTH: 6 ==========================================\n006 2 45cd 459a | 2 45cd (0) 459a (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"id":"223d79f656e3f124ee1238ca46e42c2a0d8500ee58a37312c6b72657a11ad9ebce3be4c061611b913a22863f6e7936ff37602dedc7856baea27e8201db44bbf4"}}},{"node":{"info":{"protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: ef40fd\npopulation: 11 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 4610 | 74 11b5 (0) 1030 (0) 1263 (0) 12df (0)\n001 2 8937 bb9c | 30 869f (0) 8584 (0) 8174 (0) 8166 (0)\n002 1 d24a | 10 c6ed (0) c42f (0) c1c1 (0) cb70 (0)\n003 2 fd54 f926 | 8 f7cd (0) fd54 (0) fcf3 (0) fe9d (0)\n004 1 e22c | 1 e22c (0)\n005 2 e884 e8d0 | 2 e884 (0) e8d0 (0)\n============ DEPTH: 6 ==========================================\n006 1 ede2 | 1 ede2 (0)\n007 0 | 0\n008 1 efde | 1 efde (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"70D9s38viex3gz5Isb0hCyJBlJue+Pbcpr9hiVA6uyw="},"id":"972b7f6c5b926b93a9b005bb8a891c29e535a465c586bcd4258d4094e320925a179e8f63478917f8a88d1911fe8f868013abeb34817832ed4b0b209ce392f20b","name":"node54","listenAddr":"","enode":"enode://972b7f6c5b926b93a9b005bb8a891c29e535a465c586bcd4258d4094e320925a179e8f63478917f8a88d1911fe8f868013abeb34817832ed4b0b209ce392f20b@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0}},"config":{"id":"972b7f6c5b926b93a9b005bb8a891c29e535a465c586bcd4258d4094e320925a179e8f63478917f8a88d1911fe8f868013abeb34817832ed4b0b209ce392f20b","private_key":"40e9de0543bd2c35509ebfcf51aa5a543d9616831505b5644e982144f4971f3a","services":["pss","bzz"],"name":"node54"},"up":true}},{"node":{"config":{"private_key":"f2806927e5ba924b002b05116a66bdd62d4eed7900e91f3e31892288bd06ebd1","id":"c49e963a92b93a1c48fd3e38c127bfc88fbcb15b57bfdf8615c0e591b24276d4fe153a811932aefdcf3dee494d53ce354ba052c24313a725d562c6e807ab9133","name":"node55","services":["pss","bzz"]},"up":true,"info":{"id":"c49e963a92b93a1c48fd3e38c127bfc88fbcb15b57bfdf8615c0e591b24276d4fe153a811932aefdcf3dee494d53ce354ba052c24313a725d562c6e807ab9133","protocols":{"bzz":"u5yfB+4vi8K7DwETCfgxTefBd3pvaD+QUGsYDvb1qrQ=","hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: bb9c9f\npopulation: 21 (107), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 6 6d30 051c 171f 1f15 | 57 5258 (0) 5672 (0) 5f8e (0) 5f1c (0)\n001 3 ce12 f843 ef40 | 22 c6ed (0) cb70 (0) ce12 (0) cd94 (0)\n002 4 8166 869f 9d60 960e | 17 8584 (0) 869f (0) 8174 (0) 8166 (0)\n003 4 a20d aff7 ac38 a93b | 7 a6ca (0) a20d (0) a3e8 (0) aff7 (0)\n============ DEPTH: 4 ==========================================\n004 3 b270 b26e b778 | 3 b778 (0) b270 (0) b26e (0)\n005 0 | 0\n006 1 b87c | 1 b87c (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"enode":"enode://c49e963a92b93a1c48fd3e38c127bfc88fbcb15b57bfdf8615c0e591b24276d4fe153a811932aefdcf3dee494d53ce354ba052c24313a725d562c6e807ab9133@0.0.0.0:0","listenAddr":"","name":"node55"}}},{"node":{"up":true,"config":{"services":["pss","bzz"],"name":"node56","id":"a16326a0c540731e0964c4bc10c1342346fcfee70c7d1d8d333cbb774cb9f49dbf92585595654c99253eac21373706247bf5ef1ba40ac03e62da00821991cf7d","private_key":"f38a84e8d30f9c12d52071b696ff7fbd355dc875cbf937d2f491f4f3e193fc8e"},"info":{"id":"a16326a0c540731e0964c4bc10c1342346fcfee70c7d1d8d333cbb774cb9f49dbf92585595654c99253eac21373706247bf5ef1ba40ac03e62da00821991cf7d","protocols":{"bzz":"lg6290WWb0eq2xPUiK7hGHSGyZ5rx4xnmm2bPUIdjrA=","hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 960eb6\npopulation: 14 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 160c | 74 5f8e (0) 5f1c (0) 580a (0) 5820 (0)\n001 3 f7cd fcf3 fd54 | 24 f7cd (0) fd54 (0) fcf3 (0) fe9d (0)\n002 2 a3e8 bb9c | 12 a6ca (0) a20d (0) a3e8 (0) aff7 (0)\n003 2 8937 88a9 | 9 8357 (0) 8174 (0) 8166 (0) 869f (0)\n004 3 9835 9a8c 9dc8 | 5 9835 (0) 9b24 (0) 9a8c (0) 9d60 (0)\n005 1 9265 | 1 9265 (0)\n============ DEPTH: 6 ==========================================\n006 2 944e 958e | 2 944e (0) 958e (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"listener":0,"discovery":0},"ip":"0.0.0.0","enode":"enode://a16326a0c540731e0964c4bc10c1342346fcfee70c7d1d8d333cbb774cb9f49dbf92585595654c99253eac21373706247bf5ef1ba40ac03e62da00821991cf7d@0.0.0.0:0","listenAddr":"","name":"node56"}}},{"node":{"up":true,"config":{"id":"c7566a0efd78ba35ad27a51a7ec8fcd55944ae12f9933573e71e2ad7404d48037dad9063c10ce5af636d7641a03899333d01aa9be94716d2179fdb2af33f36c4","private_key":"a3895eb5276ca39ba15c02895c3537a6c3a7be75de7b2ee2bee1fc5b9a313240","services":["pss","bzz"],"name":"node57"},"info":{"ports":{"listener":0,"discovery":0},"ip":"0.0.0.0","enode":"enode://c7566a0efd78ba35ad27a51a7ec8fcd55944ae12f9933573e71e2ad7404d48037dad9063c10ce5af636d7641a03899333d01aa9be94716d2179fdb2af33f36c4@0.0.0.0:0","listenAddr":"","name":"node57","id":"c7566a0efd78ba35ad27a51a7ec8fcd55944ae12f9933573e71e2ad7404d48037dad9063c10ce5af636d7641a03899333d01aa9be94716d2179fdb2af33f36c4","protocols":{"bzz":"FgwEAbzRs423tK6CRwJErJqZI3VfxHWqZ+tt7ccDwiM=","hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 160c04\npopulation: 12 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 960e b778 | 54 f7cd (0) fd54 (0) fcf3 (0) fe9d (0)\n001 1 4e6e | 38 5258 (0) 5672 (0) 57d3 (0) 5f8e (0)\n002 1 2426 | 11 2742 (0) 247d (0) 2426 (0) 22b8 (0)\n003 1 00b9 | 11 0ef0 (0) 0f19 (0) 0d90 (0) 089f (0)\n004 2 1d53 1f15 | 6 18b0 (0) 1b61 (0) 1a16 (0) 1a69 (0)\n005 3 12df 1316 1030 | 5 1316 (0) 1263 (0) 12df (0) 11b5 (0)\n006 0 | 0\n============ DEPTH: 7 ==========================================\n007 1 171f | 1 171f (0)\n008 0 | 0\n009 1 165d | 1 165d (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}}}},{"node":{"info":{"name":"node58","listenAddr":"","enode":"enode://334b59c2767fc786551dfdc0a9fcd6f5b53cbe48ddc1ca61b84f8155a15de7e8cd44cbb3a537e1aa7f11416eb710c5de916a5e8ce24e83bfa570b7344c5873ea@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"protocols":{"bzz":"t3gy8/JjI/CbN/MdIINh13ygjOw/+Cm5RR+j8A/2H9A=","hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: b77832\npopulation: 15 (124), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 351d 160c | 72 5672 (0) 57d3 (0) 5258 (0) 5f8e (0)\n001 2 fd54 f7cd | 23 f7cd (0) fd54 (0) fcf3 (0) fe9d (0)\n002 6 9265 8ff6 8357 8166 | 18 8357 (0) 8174 (0) 8166 (0) 869f (0)\n003 1 a3e8 | 7 a6ca (0) a20d (0) a3e8 (0) aff7 (0)\n004 2 b87c bb9c | 2 b87c (0) bb9c (0)\n============ DEPTH: 5 ==========================================\n005 2 b270 b26e | 2 b270 (0) b26e (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"id":"334b59c2767fc786551dfdc0a9fcd6f5b53cbe48ddc1ca61b84f8155a15de7e8cd44cbb3a537e1aa7f11416eb710c5de916a5e8ce24e83bfa570b7344c5873ea"},"config":{"id":"334b59c2767fc786551dfdc0a9fcd6f5b53cbe48ddc1ca61b84f8155a15de7e8cd44cbb3a537e1aa7f11416eb710c5de916a5e8ce24e83bfa570b7344c5873ea","private_key":"8135cdd3f1b3d517b1f4a11407dfcdf6a31b3dc087ddfe2224999f16ee7ca9de","services":["pss","bzz"],"name":"node58"},"up":true}},{"node":{"config":{"private_key":"29e270aecc8603f2224bee7f11039231b7a28efc5b29deeb9d98d0af388a87d0","id":"66652e041752f4acb27bc45c9c8b58f4f4ea904345a887a49ae831bef3bb1ad26cff7fd0f66ef3c28d6c41e039e39ff983710fdd5384f849595a66e5509e0d10","name":"node59","services":["pss","bzz"]},"up":true,"info":{"ip":"0.0.0.0","ports":{"listener":0,"discovery":0},"enode":"enode://66652e041752f4acb27bc45c9c8b58f4f4ea904345a887a49ae831bef3bb1ad26cff7fd0f66ef3c28d6c41e039e39ff983710fdd5384f849595a66e5509e0d10@0.0.0.0:0","listenAddr":"","name":"node59","id":"66652e041752f4acb27bc45c9c8b58f4f4ea904345a887a49ae831bef3bb1ad26cff7fd0f66ef3c28d6c41e039e39ff983710fdd5384f849595a66e5509e0d10","protocols":{"bzz":"NR0e1cQBL4hw7yrK3HwP6iy2l/Voi5LgFQxfZwZhxhc=","hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 351d1e\npopulation: 11 (126), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 b778 fcf3 | 54 8357 (0) 8174 (0) 8166 (0) 869f (0)\n001 1 5258 | 37 5672 (0) 5258 (0) 5f8e (0) 5f1c (0)\n002 3 0561 1263 1f15 | 25 171f (0) 160c (0) 165d (0) 1316 (0)\n003 2 20c4 2c3d | 7 2742 (0) 247d (0) 2426 (0) 22b8 (0)\n004 1 39b5 | 1 39b5 (0)\n============ DEPTH: 5 ==========================================\n005 1 30c0 | 1 30c0 (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 1 3547 | 1 3547 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}}}},{"node":{"info":{"ports":{"discovery":0,"listener":0},"ip":"0.0.0.0","enode":"enode://9158b9eb87bf7d011f83febca8f9d6575dd05be1f7e7bc18336f802651a379dd181a0503b5a8e46a580c59889998b16275f1e0ce4dce965cdbe72265ad2be283@0.0.0.0:0","listenAddr":"","name":"node60","id":"9158b9eb87bf7d011f83febca8f9d6575dd05be1f7e7bc18336f802651a379dd181a0503b5a8e46a580c59889998b16275f1e0ce4dce965cdbe72265ad2be283","protocols":{"bzz":"/PPM92xGmXUmcBA+nLmKwSlDOaNXh2xxZz9+SG0C8Is=","hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: fcf3cc\npopulation: 11 (126), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 351d | 73 5f1c (0) 5f8e (0) 5820 (0) 580a (0)\n001 3 960e 9dc8 88a9 | 30 869f (0) 8584 (0) 8174 (0) 8166 (0)\n002 1 d24a | 10 c1c1 (0) c6ed (0) c42f (0) cb70 (0)\n003 1 e22c | 6 e22c (0) e884 (0) e8d0 (0) ede2 (0)\n004 1 f7cd | 1 f7cd (0)\n005 2 fb21 f926 | 4 fb21 (0) f843 (0) f9e4 (0) f926 (0)\n============ DEPTH: 6 ==========================================\n006 1 fe9d | 1 fe9d (0)\n007 1 fd54 | 1 fd54 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"id":"9158b9eb87bf7d011f83febca8f9d6575dd05be1f7e7bc18336f802651a379dd181a0503b5a8e46a580c59889998b16275f1e0ce4dce965cdbe72265ad2be283","private_key":"04d1ab0b03908f14773c60464c51526f925e192645efc3781a7117f22bdc4835","services":["pss","bzz"],"name":"node60"},"up":true}},{"node":{"config":{"name":"node61","services":["pss","bzz"],"private_key":"f7320ebd494ac4fd8d6871123b7531dee97fba428ff30994f4d3ecc3f9312001","id":"9ad5ec0e729f9db10b7028788b58ef13d54bd11529b494a549d0415b90777b63fe78a752356315f5abbd24d849edc0c8bfe9d82c05460c30f4dad860ff5fea48"},"up":true,"info":{"id":"9ad5ec0e729f9db10b7028788b58ef13d54bd11529b494a549d0415b90777b63fe78a752356315f5abbd24d849edc0c8bfe9d82c05460c30f4dad860ff5fea48","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: fe9d68\npopulation: 13 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 1d53 6d30 | 74 580a (0) 5820 (0) 5958 (0) 5f1c (0)\n001 1 9dc8 | 30 8ff6 (0) 8937 (0) 88dc (0) 88a9 (0)\n002 2 d6a2 d24a | 10 c6ed (0) c42f (0) c1c1 (0) cb70 (0)\n003 1 e22c | 6 e22c (0) e884 (0) e8d0 (0) ede2 (0)\n004 1 f7cd | 1 f7cd (0)\n005 4 fb21 f843 f9e4 f926 | 4 fb21 (0) f843 (0) f9e4 (0) f926 (0)\n============ DEPTH: 6 ==========================================\n006 2 fd54 fcf3 | 2 fd54 (0) fcf3 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"/p1otvDQrdEG1KnhMjCM9cqoZ2JHhNZS8HH10f6H/4s="},"ip":"0.0.0.0","ports":{"listener":0,"discovery":0},"enode":"enode://9ad5ec0e729f9db10b7028788b58ef13d54bd11529b494a549d0415b90777b63fe78a752356315f5abbd24d849edc0c8bfe9d82c05460c30f4dad860ff5fea48@0.0.0.0:0","name":"node61","listenAddr":""}}},{"node":{"info":{"protocols":{"bzz":"0kqHga8Mj/GeymY4jjCFabzOSBROVZ3ExUP1oqsP58M=","hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: d24a87\npopulation: 23 (96), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 5958 5258 39b5 | 51 5258 (0) 5f1c (0) 5958 (0) 41f4 (0)\n001 2 9a8c a93b | 22 869f (0) 8584 (0) 8174 (0) 8166 (0)\n002 9 e22c e8d0 ede2 ef40 | 14 e22c (0) e884 (0) e8d0 (0) ede2 (0)\n003 6 cb70 ce12 cd94 c6ed | 6 c6ed (0) c42f (0) c1c1 (0) cb70 (0)\n004 0 | 0\n============ DEPTH: 5 ==========================================\n005 3 d486 d6e3 d6a2 | 3 d486 (0) d6e3 (0) d6a2 (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"id":"cf03d32d3cca446e7016e7f41267a257bef7142c4f1e4ce2e17678856d75e9889e21972fd21583297a47a156543af15400444dcf37aca64543f97f73734f7f0f","enode":"enode://cf03d32d3cca446e7016e7f41267a257bef7142c4f1e4ce2e17678856d75e9889e21972fd21583297a47a156543af15400444dcf37aca64543f97f73734f7f0f@0.0.0.0:0","listenAddr":"","name":"node62","ports":{"discovery":0,"listener":0},"ip":"0.0.0.0"},"up":true,"config":{"name":"node62","services":["pss","bzz"],"private_key":"b71a899f42faf2bdf9824d145f6f5959178f61f05e460e888c862ba8b03b5448","id":"cf03d32d3cca446e7016e7f41267a257bef7142c4f1e4ce2e17678856d75e9889e21972fd21583297a47a156543af15400444dcf37aca64543f97f73734f7f0f"}}},{"node":{"up":true,"config":{"id":"aa108a30f86b8296b416ea9fd6bc7a21c65c7cd3911ca3d4ee79325912d80db7150c02d304e49c5d0feafbd222edd6d522661a0983f1d427981760712f31e6f1","private_key":"43ea846524b82ef37cdaa1546b555e1a8d7510fc0cc7f11a6e040b79a5fcf054","services":["pss","bzz"],"name":"node63"},"info":{"name":"node63","listenAddr":"","enode":"enode://aa108a30f86b8296b416ea9fd6bc7a21c65c7cd3911ca3d4ee79325912d80db7150c02d304e49c5d0feafbd222edd6d522661a0983f1d427981760712f31e6f1@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: f9265e\npopulation: 19 (107), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 39b5 459a 5258 | 57 4e6e (0) 4f7a (0) 43d7 (0) 41f4 (0)\n001 4 b26e 8166 8357 88a9 | 27 869f (0) 8584 (0) 8174 (0) 8166 (0)\n002 3 d6e3 d6a2 d24a | 10 c6ed (0) c42f (0) c1c1 (0) cb70 (0)\n003 2 e22c ef40 | 6 e22c (0) e884 (0) e8d0 (0) ede2 (0)\n004 1 f7cd | 1 f7cd (0)\n005 3 fe9d fd54 fcf3 | 3 fd54 (0) fcf3 (0) fe9d (0)\n006 1 fb21 | 1 fb21 (0)\n============ DEPTH: 7 ==========================================\n007 1 f843 | 1 f843 (0)\n008 1 f9e4 | 1 f9e4 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"+SZePCPNkxrVH67BQmNqaoyL2Qoj539TJ4Ycgc9N/hc="},"id":"aa108a30f86b8296b416ea9fd6bc7a21c65c7cd3911ca3d4ee79325912d80db7150c02d304e49c5d0feafbd222edd6d522661a0983f1d427981760712f31e6f1"}}},{"node":{"config":{"services":["pss","bzz"],"name":"node64","id":"540598224dccc717053f94e915652df499f513dc0c8874ce999040e1aa829c33ede284c72ddd0b24a319821102fa42aaaaa87380e777b5878455de61f5fc2ac9","private_key":"0f863dee7eca46274fc2ec03645bf96424ffebbe6f5c26631051127cf730e223"},"up":true,"info":{"id":"540598224dccc717053f94e915652df499f513dc0c8874ce999040e1aa829c33ede284c72ddd0b24a319821102fa42aaaaa87380e777b5878455de61f5fc2ac9","protocols":{"bzz":"1qIDw0G2GMR65TszlWOyLDHfwS2J3qe6DDPhgSgpaEw=","hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: d6a203\npopulation: 19 (111), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 2426 0104 0561 | 60 43d7 (0) 41cd (0) 41f4 (0) 4610 (0)\n001 6 adfd 9dc8 9a8c 9b24 | 28 869f (0) 8584 (0) 8174 (0) 8166 (0)\n002 6 ede2 e8d0 e22c fd54 | 14 e22c (0) e884 (0) e8d0 (0) ede2 (0)\n003 1 c1c1 | 6 c6ed (0) c42f (0) c1c1 (0) cb70 (0)\n004 0 | 0\n005 1 d24a | 1 d24a (0)\n============ DEPTH: 6 ==========================================\n006 1 d486 | 1 d486 (0)\n007 0 | 0\n008 0 | 0\n009 1 d6e3 | 1 d6e3 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"enode":"enode://540598224dccc717053f94e915652df499f513dc0c8874ce999040e1aa829c33ede284c72ddd0b24a319821102fa42aaaaa87380e777b5878455de61f5fc2ac9@0.0.0.0:0","name":"node64","listenAddr":""}}},{"node":{"info":{"ip":"0.0.0.0","ports":{"listener":0,"discovery":0},"listenAddr":"","name":"node65","enode":"enode://826500ca53a2aed90da0cc3778cbc41af3de0139b246f30c3be65582b1f152928dfa3280760da4dcd8098f41f529a088dba24bc5d0c71322ef69f4b101f0224a@0.0.0.0:0","id":"826500ca53a2aed90da0cc3778cbc41af3de0139b246f30c3be65582b1f152928dfa3280760da4dcd8098f41f529a088dba24bc5d0c71322ef69f4b101f0224a","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 0561b4\npopulation: 13 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 ac38 d6a2 | 54 8584 (0) 869f (0) 8166 (0) 8174 (0)\n001 2 62d5 78db | 38 7468 (0) 74a4 (0) 776f (0) 766b (0)\n002 1 351d | 11 2742 (0) 2426 (0) 247d (0) 22b8 (0)\n003 3 1d53 1f15 1030 | 14 18b0 (0) 1a69 (0) 1a16 (0) 1b61 (0)\n004 1 0d90 | 4 0ef0 (0) 0f19 (0) 0d90 (0) 089f (0)\n005 2 00b9 0066 | 4 0104 (0) 016e (0) 00b9 (0) 0066 (0)\n============ DEPTH: 6 ==========================================\n006 1 07c7 | 1 07c7 (0)\n007 0 | 0\n008 0 | 0\n009 1 051c | 1 051c (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"BWG0CIbtyESXcxx7ZKzau2OiKr5XOEe3j3SIev2G1x4="}},"config":{"services":["pss","bzz"],"name":"node65","id":"826500ca53a2aed90da0cc3778cbc41af3de0139b246f30c3be65582b1f152928dfa3280760da4dcd8098f41f529a088dba24bc5d0c71322ef69f4b101f0224a","private_key":"a70d3a2696371a3cdee8702bbc4b008a564f36a8570b3bef778d00e5c4bc7da6"},"up":true}},{"node":{"config":{"private_key":"24cc61b4c4e59317c2927bd635bd3ad2863c0598321f0e5d60c3b534ed151558","id":"cc94ed069ddcc24dc2733eed5ba8367a2521a5955c7287c5280c71675b9965ee8499454b227a4ddc64a14d74b39916211763ddf0b7ad80a52381cc61dcb6c72c","name":"node66","services":["pss","bzz"]},"up":true,"info":{"protocols":{"bzz":"EDCl0npQKuuGjnFYNzxIr2qF6CnuOoT0oLePmjC9Wmo=","hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 1030a5\npopulation: 15 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 d6e3 | 54 9265 (0) 960e (0) 944e (0) 958e (0)\n001 2 4610 766b | 38 7468 (0) 74a4 (0) 776f (0) 766b (0)\n002 1 2c3d | 11 2c3d (0) 22b8 (0) 2124 (0) 20c4 (0)\n003 1 0561 | 11 0ef0 (0) 0f19 (0) 0d90 (0) 089f (0)\n004 3 1b61 1d53 1f15 | 6 18b0 (0) 1a69 (0) 1a16 (0) 1b61 (0)\n005 3 160c 165d 171f | 3 160c (0) 165d (0) 171f (0)\n============ DEPTH: 6 ==========================================\n006 3 1316 12df 1263 | 3 1316 (0) 12df (0) 1263 (0)\n007 1 11b5 | 1 11b5 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"id":"cc94ed069ddcc24dc2733eed5ba8367a2521a5955c7287c5280c71675b9965ee8499454b227a4ddc64a14d74b39916211763ddf0b7ad80a52381cc61dcb6c72c","name":"node66","listenAddr":"","enode":"enode://cc94ed069ddcc24dc2733eed5ba8367a2521a5955c7287c5280c71675b9965ee8499454b227a4ddc64a14d74b39916211763ddf0b7ad80a52381cc61dcb6c72c@0.0.0.0:0","ports":{"listener":0,"discovery":0},"ip":"0.0.0.0"}}},{"node":{"info":{"id":"df7decc6bb0d51afdc0c445a15be31b0e89c79a52b8a2cc789b585d94db63f064eccc1d8340d13d5e43ed7cbe95db8ad10ee7294dbd4c7629686564bb3a603b2","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: d6e3d3\npopulation: 9 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 43d7 1030 | 74 7468 (0) 74a4 (0) 776f (0) 766b (0)\n001 1 a93b | 30 a6ca (0) a20d (0) a3e8 (0) aff7 (0)\n002 2 fd54 f926 | 14 f7cd (0) fb21 (0) f843 (0) f9e4 (0)\n003 1 c1c1 | 6 cb70 (0) ce12 (0) cd94 (0) c6ed (0)\n004 0 | 0\n005 1 d24a | 1 d24a (0)\n============ DEPTH: 6 ==========================================\n006 1 d486 | 1 d486 (0)\n007 0 | 0\n008 0 | 0\n009 1 d6a2 | 1 d6a2 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"1uPT/9OFi4KEvJSVstkLSxEkAJpKfXOUGCl3qK4531U="},"ports":{"listener":0,"discovery":0},"ip":"0.0.0.0","listenAddr":"","name":"node67","enode":"enode://df7decc6bb0d51afdc0c445a15be31b0e89c79a52b8a2cc789b585d94db63f064eccc1d8340d13d5e43ed7cbe95db8ad10ee7294dbd4c7629686564bb3a603b2@0.0.0.0:0"},"up":true,"config":{"id":"df7decc6bb0d51afdc0c445a15be31b0e89c79a52b8a2cc789b585d94db63f064eccc1d8340d13d5e43ed7cbe95db8ad10ee7294dbd4c7629686564bb3a603b2","private_key":"36459a9e26fc4c00dd4c89bdf4c86c717b9701169ad7154228b8fbfff55661d9","services":["pss","bzz"],"name":"node67"}}},{"node":{"info":{"id":"2396833be485e50b230a07fddff7f24e11e3fdee3f08f11a287faa2b03b26451b9f4fd24ddefdec62917ae59b6fa56a75e7d6e078b411d624704b88f841b9960","protocols":{"bzz":"Q9eXy3/O143XFB70Uuo2fXSE1cD+wkMcrr4TF8SqY0A=","hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 43d797\npopulation: 14 (123), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 d6e3 a3e8 | 50 f7cd (0) fb21 (0) f843 (0) f9e4 (0)\n001 1 0066 | 36 2c3d (0) 22b8 (0) 20c4 (0) 2124 (0)\n002 2 6d30 62d5 | 20 7468 (0) 74a4 (0) 776f (0) 766b (0)\n003 2 5f1c 5258 | 8 580a (0) 5820 (0) 5958 (0) 5f8e (0)\n004 3 4a2d 4f7a 4e6e | 3 4a2d (0) 4f7a (0) 4e6e (0)\n005 1 459a | 3 4610 (0) 45cd (0) 459a (0)\n============ DEPTH: 6 ==========================================\n006 3 41f4 41cd 4067 | 3 41f4 (0) 41cd (0) 4067 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"listener":0,"discovery":0},"ip":"0.0.0.0","enode":"enode://2396833be485e50b230a07fddff7f24e11e3fdee3f08f11a287faa2b03b26451b9f4fd24ddefdec62917ae59b6fa56a75e7d6e078b411d624704b88f841b9960@0.0.0.0:0","listenAddr":"","name":"node68"},"config":{"name":"node68","services":["pss","bzz"],"private_key":"b947082437b645032dfff6e9d20e2eed52aace2d5e29cc268b06898cededdabd","id":"2396833be485e50b230a07fddff7f24e11e3fdee3f08f11a287faa2b03b26451b9f4fd24ddefdec62917ae59b6fa56a75e7d6e078b411d624704b88f841b9960"},"up":true}},{"node":{"info":{"id":"5c1e9692b731421d6eaca488e8ba4cfdda1933ac5f1504ece684fadbea07a7c8053feb73be7ce20aedeaecc84f14d836b5ed2a657df6ca04f4fc82c2da0c0d46","protocols":{"bzz":"o+h7CDd2400QlBgy7AeP6ae4uujO/m/s3VVhVJVhp/M=","hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: a3e87b\npopulation: 13 (126), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 43d7 | 73 2c3d (0) 22b8 (0) 20c4 (0) 2124 (0)\n001 1 c1c1 | 24 f7cd (0) fb21 (0) f843 (0) f9e4 (0)\n002 3 8166 958e 960e | 18 9265 (0) 960e (0) 944e (0) 958e (0)\n003 2 b87c b778 | 5 b87c (0) bb9c (0) b270 (0) b26e (0)\n004 4 ac38 adfd aff7 a93b | 4 aff7 (0) adfd (0) ac38 (0) a93b (0)\n============ DEPTH: 5 ==========================================\n005 1 a6ca | 1 a6ca (0)\n006 0 | 0\n007 1 a20d | 1 a20d (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"listener":0,"discovery":0},"ip":"0.0.0.0","enode":"enode://5c1e9692b731421d6eaca488e8ba4cfdda1933ac5f1504ece684fadbea07a7c8053feb73be7ce20aedeaecc84f14d836b5ed2a657df6ca04f4fc82c2da0c0d46@0.0.0.0:0","listenAddr":"","name":"node69"},"up":true,"config":{"id":"5c1e9692b731421d6eaca488e8ba4cfdda1933ac5f1504ece684fadbea07a7c8053feb73be7ce20aedeaecc84f14d836b5ed2a657df6ca04f4fc82c2da0c0d46","private_key":"5ac248334fa8c619d900ac284274784dc99fe0ae517e749c989a15bad1652ccf","services":["pss","bzz"],"name":"node69"}}},{"node":{"config":{"id":"a1b07c24605e258db7b8fb15db227596b08dc69bb234c0a48c312eb6eb1fb08553f8c8a6da7175eea258e2d3f2625a540c1466e6c31315aa1484fa173b7a8cfc","private_key":"7c46fa70253c48efad70d0b3da97e5c5680b1fb430147ac6f821729a836c667d","services":["pss","bzz"],"name":"node70"},"up":true,"info":{"enode":"enode://a1b07c24605e258db7b8fb15db227596b08dc69bb234c0a48c312eb6eb1fb08553f8c8a6da7175eea258e2d3f2625a540c1466e6c31315aa1484fa173b7a8cfc@0.0.0.0:0","listenAddr":"","name":"node70","ip":"0.0.0.0","ports":{"listener":0,"discovery":0},"protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: c1c138\npopulation: 13 (124), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 1f15 | 71 2c3d (0) 22b8 (0) 2124 (0) 20c4 (0)\n001 2 a6ca a3e8 | 30 9265 (0) 960e (0) 944e (0) 958e (0)\n002 2 f7cd fb21 | 14 f7cd (0) fb21 (0) f843 (0) f9e4 (0)\n003 4 d24a d486 d6a2 d6e3 | 4 d24a (0) d486 (0) d6a2 (0) d6e3 (0)\n004 2 ce12 cd94 | 3 cb70 (0) ce12 (0) cd94 (0)\n============ DEPTH: 5 ==========================================\n005 2 c6ed c42f | 2 c6ed (0) c42f (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"wcE4heP1Q4BOYuOzTA2XYneIZuW4/p2d8Mqmpk7EFCg="},"id":"a1b07c24605e258db7b8fb15db227596b08dc69bb234c0a48c312eb6eb1fb08553f8c8a6da7175eea258e2d3f2625a540c1466e6c31315aa1484fa173b7a8cfc"}}},{"node":{"info":{"id":"af761f8d13059f1e49d2f5c0b7a76a5eb5bcaab1e7ff01673dff3967d81bd7aebf74afef3934328034c82f131fa066de71816cff8f720e0c56d5e85b233a8a44","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 1f1580\npopulation: 16 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 bb9c 88a9 c1c1 | 54 a6ca (0) a20d (0) a3e8 (0) aff7 (0)\n001 2 7468 74a4 | 38 74a4 (0) 7468 (0) 776f (0) 766b (0)\n002 1 351d | 11 2c3d (0) 22b8 (0) 2124 (0) 20c4 (0)\n003 1 0561 | 11 0f19 (0) 0ef0 (0) 0d90 (0) 089f (0)\n004 4 1030 171f 165d 160c | 8 1316 (0) 1263 (0) 12df (0) 11b5 (0)\n============ DEPTH: 5 ==========================================\n005 4 18b0 1b61 1a16 1a69 | 4 18b0 (0) 1b61 (0) 1a69 (0) 1a16 (0)\n006 1 1d53 | 1 1d53 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"HxWA9r898s56UOxTviUR0iFJ/t6ZymGUthFHGtq/r6o="},"ip":"0.0.0.0","ports":{"listener":0,"discovery":0},"name":"node71","listenAddr":"","enode":"enode://af761f8d13059f1e49d2f5c0b7a76a5eb5bcaab1e7ff01673dff3967d81bd7aebf74afef3934328034c82f131fa066de71816cff8f720e0c56d5e85b233a8a44@0.0.0.0:0"},"config":{"name":"node71","services":["pss","bzz"],"private_key":"2d39f1bc0c0b3b7bdd1b9ef4fdfd54dd5b7db9743a16baa7c5f8b50948062e8d","id":"af761f8d13059f1e49d2f5c0b7a76a5eb5bcaab1e7ff01673dff3967d81bd7aebf74afef3934328034c82f131fa066de71816cff8f720e0c56d5e85b233a8a44"},"up":true}},{"node":{"info":{"protocols":{"bzz":"iKm4CMq/rbMcGgG1oJ603Gy34BE0jwlZIN0S4zC6nAo=","hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 88a9b8\npopulation: 14 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 1f15 | 74 74a4 (0) 7468 (0) 776f (0) 766b (0)\n001 4 d6a2 f7cd f926 fcf3 | 24 f7cd (0) fb21 (0) f843 (0) f9e4 (0)\n002 2 ac38 b26e | 12 a20d (0) a3e8 (0) a6ca (0) aff7 (0)\n003 2 960e 9dc8 | 9 9835 (0) 9b24 (0) 9a8c (0) 9d60 (0)\n004 2 8166 8357 | 5 869f (0) 8584 (0) 8174 (0) 8166 (0)\n005 1 8ff6 | 1 8ff6 (0)\n006 0 | 0\n============ DEPTH: 7 ==========================================\n007 1 8937 | 1 8937 (0)\n008 0 | 0\n009 1 88dc | 1 88dc (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"id":"0e07d2eb15905a583532383cef08b0881878c5043c4d7bae2cf1cace9954bfbbfbe0c1e8322eabbc84bc94cda08ae9b70cbdc56a1b8a19f807bcd5ca7939669d","name":"node72","listenAddr":"","enode":"enode://0e07d2eb15905a583532383cef08b0881878c5043c4d7bae2cf1cace9954bfbbfbe0c1e8322eabbc84bc94cda08ae9b70cbdc56a1b8a19f807bcd5ca7939669d@0.0.0.0:0","ports":{"listener":0,"discovery":0},"ip":"0.0.0.0"},"config":{"id":"0e07d2eb15905a583532383cef08b0881878c5043c4d7bae2cf1cace9954bfbbfbe0c1e8322eabbc84bc94cda08ae9b70cbdc56a1b8a19f807bcd5ca7939669d","private_key":"d4e45cb0946161c0f4333c4db19bdeabceb81b4db44982a776556e8da0bf3928","services":["pss","bzz"],"name":"node72"},"up":true}},{"node":{"info":{"protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: b26eff\npopulation: 19 (125), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 62d5 5258 | 72 74a4 (0) 7468 (0) 776f (0) 766b (0)\n001 2 f926 f7cd | 24 f7cd (0) fb21 (0) f843 (0) f9e4 (0)\n002 7 958e 8584 8166 8357 | 18 9835 (0) 9b24 (0) 9a8c (0) 9d60 (0)\n003 4 a6ca a93b adfd aff7 | 7 a20d (0) a3e8 (0) a6ca (0) ac38 (0)\n004 2 b87c bb9c | 2 b87c (0) bb9c (0)\n============ DEPTH: 5 ==========================================\n005 1 b778 | 1 b778 (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 1 b270 | 1 b270 (0)\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"sm7/DYgpGKQLkJsvx5SJpnGp+ZDMDdPYNUk7y1KkaOo="},"id":"53031cddf4390ba176d638456016028bd4538879c7eaba672c3ef70208319a14e6a41dea8ff003b6f7e9b4a83ca12dab50d4f44f079153bec7c24221e311573e","name":"node73","listenAddr":"","enode":"enode://53031cddf4390ba176d638456016028bd4538879c7eaba672c3ef70208319a14e6a41dea8ff003b6f7e9b4a83ca12dab50d4f44f079153bec7c24221e311573e@0.0.0.0:0","ip":"0.0.0.0","ports":{"listener":0,"discovery":0}},"config":{"private_key":"df8fd4bcf5cb62281500f76bc0b09d7ac1576ffd0edadbb8d39301406ac8e0fd","id":"53031cddf4390ba176d638456016028bd4538879c7eaba672c3ef70208319a14e6a41dea8ff003b6f7e9b4a83ca12dab50d4f44f079153bec7c24221e311573e","name":"node73","services":["pss","bzz"]},"up":true}},{"node":{"info":{"ip":"0.0.0.0","ports":{"listener":0,"discovery":0},"enode":"enode://2a0fa7932768f0c316b478d15db556626def18462c3bee9446ff16c48fc43b6be1694a5783602b60250e33adc705b86fae7baa6b829146251995fd47980ce422@0.0.0.0:0","listenAddr":"","name":"node74","id":"2a0fa7932768f0c316b478d15db556626def18462c3bee9446ff16c48fc43b6be1694a5783602b60250e33adc705b86fae7baa6b829146251995fd47980ce422","protocols":{"bzz":"iTdzyqjhJkMPGJGGlW8+gLSRB85Sd3ly9ejBECfActY=","hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 893773\npopulation: 17 (107), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 4e6e | 59 165d (0) 171f (0) 1030 (0) 1316 (0)\n001 4 ce12 d6a2 ef40 fd54 | 19 f7cd (0) f926 (0) f9e4 (0) fe9d (0)\n002 2 aff7 b26e | 12 a6ca (0) a20d (0) a3e8 (0) ac38 (0)\n003 4 9b24 9dc8 960e 958e | 9 9835 (0) 9b24 (0) 9a8c (0) 9d60 (0)\n004 3 8174 8166 8357 | 5 869f (0) 8584 (0) 8174 (0) 8166 (0)\n005 1 8ff6 | 1 8ff6 (0)\n006 0 | 0\n============ DEPTH: 7 ==========================================\n007 2 88dc 88a9 | 2 88dc (0) 88a9 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"up":true,"config":{"private_key":"5ec7e6e237997309e30846fed2a2074e5a150ae82804f581cb4a69ea69fe0118","id":"2a0fa7932768f0c316b478d15db556626def18462c3bee9446ff16c48fc43b6be1694a5783602b60250e33adc705b86fae7baa6b829146251995fd47980ce422","name":"node74","services":["pss","bzz"]}}},{"node":{"info":{"listenAddr":"","name":"node75","enode":"enode://7e9a81d06e997a691cc7790d358868b8657db608795ef6b85bb194db7f56ab5c76cac3be0b40d847ce873aeef4bdad40b725d69f4c42755b9d5aab4fe7aecb34@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 4e6eab\npopulation: 12 (111), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 8937 | 41 f843 (0) f926 (0) fb21 (0) fcf3 (0)\n001 3 247d 160c 1316 | 34 351d (0) 3547 (0) 30c0 (0) 39b5 (0)\n002 2 62d5 795d | 19 7468 (0) 74a4 (0) 776f (0) 766b (0)\n003 1 5258 | 8 580a (0) 5820 (0) 5958 (0) 5f8e (0)\n004 3 4067 41cd 43d7 | 7 4610 (0) 45cd (0) 459a (0) 4067 (0)\n============ DEPTH: 5 ==========================================\n005 1 4a2d | 1 4a2d (0)\n006 0 | 0\n007 1 4f7a | 1 4f7a (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"Tm6rbrPUmyDi897hadRkfr8m0HBEaY/5PVHF/DD7SuA="},"id":"7e9a81d06e997a691cc7790d358868b8657db608795ef6b85bb194db7f56ab5c76cac3be0b40d847ce873aeef4bdad40b725d69f4c42755b9d5aab4fe7aecb34"},"config":{"name":"node75","services":["pss","bzz"],"private_key":"06d5dc287feafe3797b6302002258d7ea058679dc501e7a05f64fabd41b1b701","id":"7e9a81d06e997a691cc7790d358868b8657db608795ef6b85bb194db7f56ab5c76cac3be0b40d847ce873aeef4bdad40b725d69f4c42755b9d5aab4fe7aecb34"},"up":true}},{"node":{"up":true,"config":{"private_key":"a06a77e7469d86991954524d4a1495b5aeb80bb413c0b1293479dcc8ce511108","id":"e20a90f36eca4329d3d2dbadf530949889dc20b0ae5d96b935af9b60d26ec507e9eb1b73fd2b4dc88057c20e4ef6e7039cc49652d35c563db64f06f979e28540","name":"node76","services":["pss","bzz"]},"info":{"enode":"enode://e20a90f36eca4329d3d2dbadf530949889dc20b0ae5d96b935af9b60d26ec507e9eb1b73fd2b4dc88057c20e4ef6e7039cc49652d35c563db64f06f979e28540@0.0.0.0:0","name":"node76","listenAddr":"","ports":{"listener":0,"discovery":0},"ip":"0.0.0.0","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 13165f\npopulation: 15 (113), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 e22c f7cd | 42 fe9d (0) fd54 (0) fcf3 (0) f926 (0)\n001 2 795d 4e6e | 36 7468 (0) 74a4 (0) 776f (0) 766b (0)\n002 2 2426 39b5 | 11 2c3d (0) 22b8 (0) 2124 (0) 20c4 (0)\n003 1 0ef0 | 11 089f (0) 0ef0 (0) 0f19 (0) 0d90 (0)\n004 2 1b61 1a16 | 6 1d53 (0) 1f15 (0) 18b0 (0) 1b61 (0)\n005 2 160c 171f | 3 160c (0) 165d (0) 171f (0)\n006 2 11b5 1030 | 2 11b5 (0) 1030 (0)\n============ DEPTH: 7 ==========================================\n007 2 1263 12df | 2 1263 (0) 12df (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"ExZf/8MY3V8YJgE4ThrGndWRI2oD6I39HGN+ohoBst0="},"id":"e20a90f36eca4329d3d2dbadf530949889dc20b0ae5d96b935af9b60d26ec507e9eb1b73fd2b4dc88057c20e4ef6e7039cc49652d35c563db64f06f979e28540"}}},{"node":{"info":{"name":"node77","listenAddr":"","enode":"enode://1cc62520c0d9c6a47d96e485bdc6a5d0f7319477ad6d177663f7b49217f5a8e56e4717f36fb5aa11c5270d4383cab460219821bcc6c9cbcccc4a97446b406d96@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 39b5d0\npopulation: 11 (124), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 d24a f926 e8d0 | 54 f7cd (0) fe9d (0) fd54 (0) fcf3 (0)\n001 1 5258 | 35 776f (0) 766b (0) 74a4 (0) 7468 (0)\n002 3 00b9 0ef0 1316 | 25 089f (0) 0ef0 (0) 0f19 (0) 0d90 (0)\n003 1 2426 | 7 2c3d (0) 22b8 (0) 20c4 (0) 2124 (0)\n============ DEPTH: 4 ==========================================\n004 3 351d 3547 30c0 | 3 351d (0) 3547 (0) 30c0 (0)\n005 0 | 0\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"ObXQnRInp3b41ltyOc0D4ESZ59UZ5dH/TEhwoalJ3ZE="},"id":"1cc62520c0d9c6a47d96e485bdc6a5d0f7319477ad6d177663f7b49217f5a8e56e4717f36fb5aa11c5270d4383cab460219821bcc6c9cbcccc4a97446b406d96"},"config":{"private_key":"9e6c3d21c05d371fd69225b2eef1d1eabedad577ae026b6d8ad8f728a53d657b","id":"1cc62520c0d9c6a47d96e485bdc6a5d0f7319477ad6d177663f7b49217f5a8e56e4717f36fb5aa11c5270d4383cab460219821bcc6c9cbcccc4a97446b406d96","name":"node77","services":["pss","bzz"]},"up":true}},{"node":{"info":{"ports":{"discovery":0,"listener":0},"ip":"0.0.0.0","name":"node78","listenAddr":"","enode":"enode://c133cd3ee228f427410357f46752d33ecf302475314411772df3532669a8b220136c09f00717460c39bcea1058cb988dd223875ec991612876b400556f5937dd@0.0.0.0:0","id":"c133cd3ee228f427410357f46752d33ecf302475314411772df3532669a8b220136c09f00717460c39bcea1058cb988dd223875ec991612876b400556f5937dd","protocols":{"bzz":"Ulj9yU14u0XWY08mcrwurNvIlvxaOXhOzJ2KfdUssec=","hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 5258fd\npopulation: 20 (91), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 d24a f926 b26e | 35 c1c1 (0) cd94 (0) d24a (0) d486 (0)\n001 5 00b9 247d 2426 351d | 32 1d53 (0) 1f15 (0) 1b61 (0) 1a69 (0)\n002 3 7a46 795d 62d5 | 11 776f (0) 766b (0) 7a46 (0) 78db (0)\n003 5 4f7a 4e6e 41cd 4067 | 6 4a2d (0) 4f7a (0) 4e6e (0) 41cd (0)\n004 2 5820 5f1c | 5 5958 (0) 5820 (0) 580a (0) 5f8e (0)\n============ DEPTH: 5 ==========================================\n005 2 5672 57d3 | 2 5672 (0) 57d3 (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"up":true,"config":{"name":"node78","services":["pss","bzz"],"private_key":"cd8b5f4a6c0d361bc118318b1f1c5e69ef7b546e5ded44742e97124cfb80c52e","id":"c133cd3ee228f427410357f46752d33ecf302475314411772df3532669a8b220136c09f00717460c39bcea1058cb988dd223875ec991612876b400556f5937dd"}}},{"node":{"info":{"name":"node79","listenAddr":"","enode":"enode://c4dfcf348694971fb36ed91e9024302bec8df3891540cbe1f5df26eee9c1f81a95295f05b90ec30dd044a0355dcaa805b9f50e95f38e5588a929cfe10e8cd73d@0.0.0.0:0","ports":{"discovery":0,"listener":0},"ip":"0.0.0.0","protocols":{"bzz":"JCY+xLkvOQ4HGT0A5aAy6iZJ9WACe+AoeNplbjfUobE=","hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 24263e\npopulation: 16 (102), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 e8d0 d6a2 | 37 c1c1 (0) c42f (0) c6ed (0) cd94 (0)\n001 2 62d5 5258 | 30 74a4 (0) 7468 (0) 766b (0) 7a46 (0)\n002 4 0104 07c7 160c 1316 | 25 1f15 (0) 1d53 (0) 18b0 (0) 1b61 (0)\n003 2 39b5 30c0 | 4 351d (0) 3547 (0) 30c0 (0) 39b5 (0)\n004 1 2c3d | 1 2c3d (0)\n005 3 22b8 2124 20c4 | 3 22b8 (0) 2124 (0) 20c4 (0)\n============ DEPTH: 6 ==========================================\n006 1 2742 | 1 2742 (0)\n007 0 | 0\n008 0 | 0\n009 1 247d | 1 247d (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"id":"c4dfcf348694971fb36ed91e9024302bec8df3891540cbe1f5df26eee9c1f81a95295f05b90ec30dd044a0355dcaa805b9f50e95f38e5588a929cfe10e8cd73d"},"config":{"services":["pss","bzz"],"name":"node79","id":"c4dfcf348694971fb36ed91e9024302bec8df3891540cbe1f5df26eee9c1f81a95295f05b90ec30dd044a0355dcaa805b9f50e95f38e5588a929cfe10e8cd73d","private_key":"04ed808eb12d991a68104f16e8965f3e6d60ba0b0dabff4fe33b3878c63d25f7"},"up":true}},{"node":{"up":true,"config":{"id":"e2956a828cb1ff85ab55bdbe329f530662558cb8013ffddacac8ba36096abea07ecb15b54896dd9b4bb0b15155654dbda0c031f69290f2314ac0e376bebbd864","private_key":"175d97bb42b8f0effb21274a929a499f0e49e8e6ecad97b853a164464ad20bde","services":["pss","bzz"],"name":"node80"},"info":{"ports":{"discovery":0,"listener":0},"ip":"0.0.0.0","name":"node80","listenAddr":"","enode":"enode://e2956a828cb1ff85ab55bdbe329f530662558cb8013ffddacac8ba36096abea07ecb15b54896dd9b4bb0b15155654dbda0c031f69290f2314ac0e376bebbd864@0.0.0.0:0","id":"e2956a828cb1ff85ab55bdbe329f530662558cb8013ffddacac8ba36096abea07ecb15b54896dd9b4bb0b15155654dbda0c031f69290f2314ac0e376bebbd864","protocols":{"bzz":"YtUWIAElOzlk5nctNbwxqjcqQuh85FDUjbuE9dPJ6PI=","hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 62d516\npopulation: 23 (118), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 b26e b270 adfd | 45 a6ca (0) a3e8 (0) a20d (0) a93b (0)\n001 4 2426 0561 089f 1a16 | 36 351d (0) 3547 (0) 30c0 (0) 39b5 (0)\n002 6 5f1c 5258 4e6e 41f4 | 18 580a (0) 5820 (0) 5958 (0) 5f8e (0)\n003 3 766b 7d14 795d | 9 7468 (0) 74a4 (0) 776f (0) 766b (0)\n004 4 69ba 6ad6 6d30 6c29 | 7 69ba (0) 6b7d (0) 6b1f (0) 6ad6 (0)\n============ DEPTH: 5 ==========================================\n005 2 6421 66f6 | 2 6421 (0) 66f6 (0)\n006 1 60cb | 1 60cb (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}}}},{"node":{"up":true,"config":{"services":["pss","bzz"],"name":"node81","id":"854ff45571c01cd49d0932bcb361eef13202ababf48f0b8e5d8143dc41e01609aa1539e926bad9b4ca8add023fd259eb70239103d75b0a404bb338f3e4bf9577","private_key":"34dbf4adc051f2ab18ea18c1faaec6726857cc5e0fcb3181fb296a723d2971c7"},"info":{"protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 1a16e1\npopulation: 16 (110), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 adfd | 39 a20d (0) a3e8 (0) a6ca (0) a93b (0)\n001 3 6c29 62d5 4f7a | 36 7468 (0) 74a4 (0) 776f (0) 766b (0)\n002 3 2742 30c0 3547 | 11 351d (0) 3547 (0) 30c0 (0) 39b5 (0)\n003 2 0066 07c7 | 11 089f (0) 0ef0 (0) 0f19 (0) 0d90 (0)\n004 2 12df 1316 | 8 160c (0) 165d (0) 171f (0) 11b5 (0)\n005 2 1d53 1f15 | 2 1d53 (0) 1f15 (0)\n006 1 18b0 | 1 18b0 (0)\n============ DEPTH: 7 ==========================================\n007 1 1b61 | 1 1b61 (0)\n008 0 | 0\n009 1 1a69 | 1 1a69 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"GhbhWPHTXyVz0gsFulGiycwZZUcDjjt76X3cdZjoElc="},"id":"854ff45571c01cd49d0932bcb361eef13202ababf48f0b8e5d8143dc41e01609aa1539e926bad9b4ca8add023fd259eb70239103d75b0a404bb338f3e4bf9577","listenAddr":"","name":"node81","enode":"enode://854ff45571c01cd49d0932bcb361eef13202ababf48f0b8e5d8143dc41e01609aa1539e926bad9b4ca8add023fd259eb70239103d75b0a404bb338f3e4bf9577@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0}}}},{"node":{"info":{"ports":{"discovery":0,"listener":0},"ip":"0.0.0.0","listenAddr":"","name":"node82","enode":"enode://b440e8bc7d39b8cf9cca03b343c83ba8dd673062cead7bbfce6ed77ea16fa61f0b81df31fc418f4c133d1bb104939ac1b6e5f5a76fbcf50141a1ea33dfeb86e5@0.0.0.0:0","id":"b440e8bc7d39b8cf9cca03b343c83ba8dd673062cead7bbfce6ed77ea16fa61f0b81df31fc418f4c133d1bb104939ac1b6e5f5a76fbcf50141a1ea33dfeb86e5","protocols":{"bzz":"T3q7xRJl3+ItWPOsXN4sBexWBT7+eePrtuzpYYPcwXo=","hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 4f7abb\npopulation: 11 (126), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 a6ca | 53 a3e8 (0) a20d (0) a6ca (0) a93b (0)\n001 2 07c7 1a16 | 36 351d (0) 3547 (0) 30c0 (0) 39b5 (0)\n002 1 766b | 20 74a4 (0) 7468 (0) 776f (0) 766b (0)\n003 1 5258 | 8 57d3 (0) 5672 (0) 5258 (0) 580a (0)\n004 4 459a 43d7 41cd 4067 | 7 4610 (0) 45cd (0) 459a (0) 43d7 (0)\n============ DEPTH: 5 ==========================================\n005 1 4a2d | 1 4a2d (0)\n006 0 | 0\n007 1 4e6e | 1 4e6e (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"private_key":"21c776bf36961c727b36ff521a7527764077944b7932dfb901ca6489b2e123e7","id":"b440e8bc7d39b8cf9cca03b343c83ba8dd673062cead7bbfce6ed77ea16fa61f0b81df31fc418f4c133d1bb104939ac1b6e5f5a76fbcf50141a1ea33dfeb86e5","name":"node82","services":["pss","bzz"]},"up":true}},{"node":{"info":{"ip":"0.0.0.0","ports":{"listener":0,"discovery":0},"listenAddr":"","name":"node83","enode":"enode://e0cacf6abdbfd9a25b9f974600662d4eae484efcdefd0a2a8fbc799127b6fabf2f471aff89c3a08e93ea20be1c304320598ba20a13697a356bf065292ba16bc1@0.0.0.0:0","id":"e0cacf6abdbfd9a25b9f974600662d4eae484efcdefd0a2a8fbc799127b6fabf2f471aff89c3a08e93ea20be1c304320598ba20a13697a356bf065292ba16bc1","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 07c79a\npopulation: 12 (122), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 e8d0 | 49 a3e8 (0) a6ca (0) a93b (0) aff7 (0)\n001 1 4f7a | 38 74a4 (0) 7468 (0) 776f (0) 766b (0)\n002 1 2426 | 11 351d (0) 3547 (0) 30c0 (0) 39b5 (0)\n003 2 11b5 1a16 | 14 1f15 (0) 1d53 (0) 18b0 (0) 1b61 (0)\n004 2 0d90 0ef0 | 4 089f (0) 0f19 (0) 0ef0 (0) 0d90 (0)\n005 3 016e 00b9 0066 | 4 0104 (0) 016e (0) 00b9 (0) 0066 (0)\n============ DEPTH: 6 ==========================================\n006 2 051c 0561 | 2 051c (0) 0561 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"B8eaqn+nWfeXuI2MSVxb+qEvFSicalZ7vDY/0HAieDA="}},"up":true,"config":{"id":"e0cacf6abdbfd9a25b9f974600662d4eae484efcdefd0a2a8fbc799127b6fabf2f471aff89c3a08e93ea20be1c304320598ba20a13697a356bf065292ba16bc1","private_key":"db4ace065dad27967a83ad918dedd4b4d7b1aaa331057ca1a2033fcba3e16df6","services":["pss","bzz"],"name":"node83"}}},{"node":{"info":{"id":"82f0cbb87a76dea7947c2c1b6506d05390e5c5e969e5e91651ca10d36cd6aaea72967435ea7e5222d28f1d5e64cc526075d264712e55593bc3b609c93d4fe1eb","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: e8d0bd\npopulation: 16 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 39b5 2426 07c7 0066 | 74 57d3 (0) 5672 (0) 5258 (0) 5958 (0)\n001 3 b87c b270 958e | 30 a20d (0) a3e8 (0) a6ca (0) a93b (0)\n002 3 d24a d6a2 d486 | 10 cb70 (0) ce12 (0) cd94 (0) c6ed (0)\n003 1 fd54 | 8 f7cd (0) fb21 (0) f843 (0) f9e4 (0)\n004 1 e22c | 1 e22c (0)\n============ DEPTH: 5 ==========================================\n005 3 ede2 efde ef40 | 3 efde (0) ef40 (0) ede2 (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 1 e884 | 1 e884 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"6NC9BPpbVvzVDLSx1VCFXCEZLxKU8pVEATSMiii0Vas="},"ports":{"listener":0,"discovery":0},"ip":"0.0.0.0","enode":"enode://82f0cbb87a76dea7947c2c1b6506d05390e5c5e969e5e91651ca10d36cd6aaea72967435ea7e5222d28f1d5e64cc526075d264712e55593bc3b609c93d4fe1eb@0.0.0.0:0","name":"node84","listenAddr":""},"config":{"id":"82f0cbb87a76dea7947c2c1b6506d05390e5c5e969e5e91651ca10d36cd6aaea72967435ea7e5222d28f1d5e64cc526075d264712e55593bc3b609c93d4fe1eb","private_key":"2642ed9d36375a48a74d6aee878a935a15e7bd219d39bbdf455b0a168c98a8b5","services":["pss","bzz"],"name":"node84"},"up":true}},{"node":{"config":{"services":["pss","bzz"],"name":"node85","id":"57533c56642895edba91473a966b6abf765725a721dec947e4bac4728dfbed265435aefca55fff69cae48c9d506064fbb890665a0acd87c466707d08d1e6e1f4","private_key":"c1c1f7cd104f6f7163fe144041570269558b335ae6ddbdb80c79687faf55f5bb"},"up":true,"info":{"id":"57533c56642895edba91473a966b6abf765725a721dec947e4bac4728dfbed265435aefca55fff69cae48c9d506064fbb890665a0acd87c466707d08d1e6e1f4","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 006635\npopulation: 14 (121), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 e8d0 d486 | 49 a3e8 (0) a6ca (0) a93b (0) aff7 (0)\n001 1 43d7 | 38 5672 (0) 57d3 (0) 5258 (0) 5958 (0)\n002 1 3547 | 11 351d (0) 3547 (0) 30c0 (0) 39b5 (0)\n003 3 11b5 1a16 1b61 | 13 1d53 (0) 18b0 (0) 1b61 (0) 1a69 (0)\n004 2 089f 0d90 | 4 0f19 (0) 0ef0 (0) 0d90 (0) 089f (0)\n005 2 0561 07c7 | 3 051c (0) 0561 (0) 07c7 (0)\n006 0 | 0\n============ DEPTH: 7 ==========================================\n007 2 0104 016e | 2 0104 (0) 016e (0)\n008 1 00b9 | 1 00b9 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"AGY1IXfWwiWEI2KrQkpjL1aZgLAqxVoTpxWTr5TLjC0="},"ip":"0.0.0.0","ports":{"listener":0,"discovery":0},"enode":"enode://57533c56642895edba91473a966b6abf765725a721dec947e4bac4728dfbed265435aefca55fff69cae48c9d506064fbb890665a0acd87c466707d08d1e6e1f4@0.0.0.0:0","listenAddr":"","name":"node85"}}},{"node":{"config":{"id":"9b3fecfc63256a9d69e75ccb5119b2866e30fa4516b3a3bf5b2f03f04f1d20de786ddb90fa2acadb2a0509503b21fc9d16238c57f9b102ceedb6b27ee1b2c4ea","private_key":"89501ac0b58fa2ee82ba6ef2b45a3c0ab6d8f54f4b92da1111d97ecfedbf5fc3","services":["pss","bzz"],"name":"node86"},"up":true,"info":{"ip":"0.0.0.0","ports":{"listener":0,"discovery":0},"enode":"enode://9b3fecfc63256a9d69e75ccb5119b2866e30fa4516b3a3bf5b2f03f04f1d20de786ddb90fa2acadb2a0509503b21fc9d16238c57f9b102ceedb6b27ee1b2c4ea@0.0.0.0:0","name":"node86","listenAddr":"","id":"9b3fecfc63256a9d69e75ccb5119b2866e30fa4516b3a3bf5b2f03f04f1d20de786ddb90fa2acadb2a0509503b21fc9d16238c57f9b102ceedb6b27ee1b2c4ea","protocols":{"bzz":"1IZC+ACOiqeRuonJs6W40teut+kHjK7ogTd3Z5YIB1w=","hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: d48642\npopulation: 20 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 5 776f 580a 4067 2c3d | 74 5672 (0) 57d3 (0) 5258 (0) 5958 (0)\n001 6 adfd b270 8ff6 8584 | 30 a20d (0) a3e8 (0) a6ca (0) a93b (0)\n002 3 ede2 e884 e8d0 | 14 f7cd (0) fb21 (0) f843 (0) f9e4 (0)\n003 3 cb70 ce12 c1c1 | 6 cb70 (0) ce12 (0) cd94 (0) c6ed (0)\n004 0 | 0\n005 1 d24a | 1 d24a (0)\n============ DEPTH: 6 ==========================================\n006 2 d6e3 d6a2 | 2 d6e3 (0) d6a2 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}}}},{"node":{"config":{"name":"node87","services":["pss","bzz"],"private_key":"cf649d632a25375b28cc6f7821de3e0df16b52ad9e0ff8978b231e20d6ed37ee","id":"932e926c54a4127210a15731fa4ad6bbfd0d69183b894b676920843f154ad1e4148b674d234f070e9dc07547394a5af973befe0fc170bbe44346d69e135e0157"},"up":true,"info":{"listenAddr":"","name":"node87","enode":"enode://932e926c54a4127210a15731fa4ad6bbfd0d69183b894b676920843f154ad1e4148b674d234f070e9dc07547394a5af973befe0fc170bbe44346d69e135e0157@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 944e82\npopulation: 11 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 795d | 74 351d (0) 3547 (0) 30c0 (0) 39b5 (0)\n001 1 d486 | 24 f7cd (0) fb21 (0) f843 (0) f9e4 (0)\n002 1 b270 | 12 a3e8 (0) a20d (0) a6ca (0) a93b (0)\n003 2 8357 88dc | 9 869f (0) 8584 (0) 8174 (0) 8166 (0)\n004 3 9dc8 9835 9b24 | 5 9d60 (0) 9dc8 (0) 9835 (0) 9a8c (0)\n005 1 9265 | 1 9265 (0)\n============ DEPTH: 6 ==========================================\n006 1 960e | 1 960e (0)\n007 1 958e | 1 958e (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"lE6CMfn2YUNfH5Sr+qF4YqAFh3SH31xdOlZsTb5Gvj8="},"id":"932e926c54a4127210a15731fa4ad6bbfd0d69183b894b676920843f154ad1e4148b674d234f070e9dc07547394a5af973befe0fc170bbe44346d69e135e0157"}}},{"node":{"config":{"id":"3bf838b4d29d9388a24d160eee6bf8ea017af6cd9e5f7d88b4cae71ebfbc304666d3d634a05e0a75570dafe8f41871090fcff8b651a9130d013786dfcca3da14","private_key":"bceddc4ac81042ad71089e4c861518f8d018601263d1faa17238f1c326e4b317","services":["pss","bzz"],"name":"node88"},"up":true,"info":{"listenAddr":"","name":"node88","enode":"enode://3bf838b4d29d9388a24d160eee6bf8ea017af6cd9e5f7d88b4cae71ebfbc304666d3d634a05e0a75570dafe8f41871090fcff8b651a9130d013786dfcca3da14@0.0.0.0:0","ports":{"discovery":0,"listener":0},"ip":"0.0.0.0","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 795d81\npopulation: 14 (102), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 944e | 38 c1c1 (0) ce12 (0) d486 (0) d6e3 (0)\n001 1 1316 | 32 160c (0) 165d (0) 171f (0) 11b5 (0)\n002 3 5258 41cd 4e6e | 13 5258 (0) 5820 (0) 5958 (0) 5f1c (0)\n003 4 6c29 6b1f 6ad6 62d5 | 11 69ba (0) 6b7d (0) 6b1f (0) 6ad6 (0)\n004 1 766b | 4 7468 (0) 74a4 (0) 776f (0) 766b (0)\n005 2 7c99 7d14 | 2 7c99 (0) 7d14 (0)\n============ DEPTH: 6 ==========================================\n006 1 7a46 | 1 7a46 (0)\n007 1 78db | 1 78db (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"eV2BPKtnMAuMWceLa5lAPIERkgykfB5W7ftRO8SZnz8="},"id":"3bf838b4d29d9388a24d160eee6bf8ea017af6cd9e5f7d88b4cae71ebfbc304666d3d634a05e0a75570dafe8f41871090fcff8b651a9130d013786dfcca3da14"}}},{"node":{"info":{"id":"6d3bd11f2f7fe855188423bc49be111cd13defeb78a76eb26d415bfc0c86b89e90724db54a12ae7e0c76b9eb12eb456fc50668697245fca00f9ec3c6fb9c8588","protocols":{"bzz":"dmtht3OtNMbP0wucLpSEDRUcMauMvPVGlD61gh1ajzY=","hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 766b61\npopulation: 14 (93), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 958e | 31 c42f (0) d486 (0) d6e3 (0) d6a2 (0)\n001 2 1030 12df | 30 160c (0) 165d (0) 11b5 (0) 1030 (0)\n002 2 4f7a 4067 | 13 5258 (0) 5820 (0) 5958 (0) 5f8e (0)\n003 4 62d5 6c29 6b1f 6ad6 | 11 69ba (0) 6b7d (0) 6b1f (0) 6ad6 (0)\n004 2 78db 795d | 5 7c99 (0) 7d14 (0) 7a46 (0) 78db (0)\n005 0 | 0\n============ DEPTH: 6 ==========================================\n006 2 7468 74a4 | 2 7468 (0) 74a4 (0)\n007 1 776f | 1 776f (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"listener":0,"discovery":0},"ip":"0.0.0.0","listenAddr":"","name":"node89","enode":"enode://6d3bd11f2f7fe855188423bc49be111cd13defeb78a76eb26d415bfc0c86b89e90724db54a12ae7e0c76b9eb12eb456fc50668697245fca00f9ec3c6fb9c8588@0.0.0.0:0"},"up":true,"config":{"name":"node89","services":["pss","bzz"],"private_key":"a870aecb16e345ef241f69348d08489eb250b113f2072ab6371dda815d799f3f","id":"6d3bd11f2f7fe855188423bc49be111cd13defeb78a76eb26d415bfc0c86b89e90724db54a12ae7e0c76b9eb12eb456fc50668697245fca00f9ec3c6fb9c8588"}}},{"node":{"config":{"services":["pss","bzz"],"name":"node90","id":"faa3c31521c8f7b9d15838750e7e311eb0f01db5ef22cd1bf62a7d72e7efdf5a575550c930d96230edc892d107d4551e95b099d3c952a7f1c0ad3b5967c7831b","private_key":"07af0af8e7e43f2822c2c0c3d34a1742faf6e11328b6194a760e9acefb5dedc8"},"up":true,"info":{"ip":"0.0.0.0","ports":{"listener":0,"discovery":0},"name":"node90","listenAddr":"","enode":"enode://faa3c31521c8f7b9d15838750e7e311eb0f01db5ef22cd1bf62a7d72e7efdf5a575550c930d96230edc892d107d4551e95b099d3c952a7f1c0ad3b5967c7831b@0.0.0.0:0","id":"faa3c31521c8f7b9d15838750e7e311eb0f01db5ef22cd1bf62a7d72e7efdf5a575550c930d96230edc892d107d4551e95b099d3c952a7f1c0ad3b5967c7831b","protocols":{"bzz":"lY4HWn8iwJI2DTJd0MBEnpRCw5iyiCAJxcNyDLzTWE8=","hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 958e07\npopulation: 16 (120), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 766b 0ef0 | 67 5672 (0) 5258 (0) 5820 (0) 580a (0)\n001 1 e8d0 | 24 c6ed (0) c42f (0) c1c1 (0) cb70 (0)\n002 4 b270 b26e a3e8 a6ca | 12 a93b (0) aff7 (0) ac38 (0) adfd (0)\n003 3 8ff6 8937 8357 | 9 869f (0) 8584 (0) 8174 (0) 8166 (0)\n004 3 9dc8 9835 9b24 | 5 9d60 (0) 9dc8 (0) 9835 (0) 9a8c (0)\n005 1 9265 | 1 9265 (0)\n============ DEPTH: 6 ==========================================\n006 1 960e | 1 960e (0)\n007 1 944e | 1 944e (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}}}},{"node":{"up":true,"config":{"name":"node91","services":["pss","bzz"],"private_key":"683b9cd98aab26ece4c2e53dd44a1fde3ae2303f80f99dc7e7e5d4b80e5a40e2","id":"467a76ed18ca4f195c6a5b0ac277dfd0916657e047fea073db8e28bb59098bd8960c90efe8f59d6c275ff72d18b217d225f6698e56c05e33734a0fd6ea570589"},"info":{"id":"467a76ed18ca4f195c6a5b0ac277dfd0916657e047fea073db8e28bb59098bd8960c90efe8f59d6c275ff72d18b217d225f6698e56c05e33734a0fd6ea570589","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 0ef0bf\npopulation: 10 (125), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 958e | 52 c42f (0) c1c1 (0) ce12 (0) cd94 (0)\n001 1 4067 | 38 69ba (0) 6b7d (0) 6b1f (0) 6ad6 (0)\n002 1 39b5 | 11 39b5 (0) 351d (0) 3547 (0) 30c0 (0)\n003 2 165d 1316 | 14 160c (0) 165d (0) 171f (0) 1030 (0)\n004 2 00b9 07c7 | 7 00b9 (0) 0066 (0) 0104 (0) 016e (0)\n005 1 089f | 1 089f (0)\n============ DEPTH: 6 ==========================================\n006 1 0d90 | 1 0d90 (0)\n007 1 0f19 | 1 0f19 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"DvC/U92t0slC8h5+CdWpAtFm8TkgqrsqpmUrcMQj9XU="},"ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"enode":"enode://467a76ed18ca4f195c6a5b0ac277dfd0916657e047fea073db8e28bb59098bd8960c90efe8f59d6c275ff72d18b217d225f6698e56c05e33734a0fd6ea570589@0.0.0.0:0","listenAddr":"","name":"node91"}}},{"node":{"info":{"id":"f2ac738fa932c90a45d1a64e4a52fd9c4037e2d89ceef1584efef04689bc7aff3a9635fb78dfdf3480d003daf14359190b1cfa8335db438a54107d4060ed58f9","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 406799\npopulation: 14 (120), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 d486 e884 | 47 ce12 (0) cd94 (0) c42f (0) c6ed (0)\n001 2 0ef0 1b61 | 36 39b5 (0) 351d (0) 3547 (0) 30c0 (0)\n002 1 766b | 20 69ba (0) 6b7d (0) 6b1f (0) 6ad6 (0)\n003 2 5258 5f1c | 8 5672 (0) 57d3 (0) 5258 (0) 580a (0)\n004 3 4a2d 4f7a 4e6e | 3 4a2d (0) 4e6e (0) 4f7a (0)\n005 1 459a | 3 4610 (0) 45cd (0) 459a (0)\n006 1 43d7 | 1 43d7 (0)\n============ DEPTH: 7 ==========================================\n007 2 41f4 41cd | 2 41f4 (0) 41cd (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"QGeZfCYEJ0nBbxcWnKrGbmR7ceNVf3WB2+xznQuqLvA="},"ports":{"listener":0,"discovery":0},"ip":"0.0.0.0","enode":"enode://f2ac738fa932c90a45d1a64e4a52fd9c4037e2d89ceef1584efef04689bc7aff3a9635fb78dfdf3480d003daf14359190b1cfa8335db438a54107d4060ed58f9@0.0.0.0:0","listenAddr":"","name":"node92"},"config":{"private_key":"31b3da34d338fb902b718378f7b5ebbdcdff30e4e3d3deff8b021e3979a7c6de","id":"f2ac738fa932c90a45d1a64e4a52fd9c4037e2d89ceef1584efef04689bc7aff3a9635fb78dfdf3480d003daf14359190b1cfa8335db438a54107d4060ed58f9","name":"node92","services":["pss","bzz"]},"up":true}},{"node":{"info":{"protocols":{"bzz":"G2Fo1qNpApaQ6DbSb/4BfiZ2nOUEwUKr8qSmV3Tstm0=","hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 1b6168\npopulation: 18 (104), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 e884 | 35 c1c1 (0) c42f (0) c6ed (0) ce12 (0)\n001 2 6c29 4067 | 34 69ba (0) 6b7d (0) 6b1f (0) 6ad6 (0)\n002 3 30c0 2742 247d | 11 39b5 (0) 351d (0) 3547 (0) 30c0 (0)\n003 1 0066 | 11 0066 (0) 00b9 (0) 0104 (0) 016e (0)\n004 6 165d 171f 1030 11b5 | 8 160c (0) 165d (0) 171f (0) 11b5 (0)\n005 2 1f15 1d53 | 2 1f15 (0) 1d53 (0)\n006 1 18b0 | 1 18b0 (0)\n============ DEPTH: 7 ==========================================\n007 2 1a69 1a16 | 2 1a69 (0) 1a16 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"id":"5a59a44ba2bf5e77f921216ac467733c8529b06790efb05a63c410060edaf65547a2dbb37333073e3bcf68d422ba4b135432307f90394c6edd6dd33dd6ff2152","name":"node93","listenAddr":"","enode":"enode://5a59a44ba2bf5e77f921216ac467733c8529b06790efb05a63c410060edaf65547a2dbb37333073e3bcf68d422ba4b135432307f90394c6edd6dd33dd6ff2152@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0}},"up":true,"config":{"id":"5a59a44ba2bf5e77f921216ac467733c8529b06790efb05a63c410060edaf65547a2dbb37333073e3bcf68d422ba4b135432307f90394c6edd6dd33dd6ff2152","private_key":"997bcdc19c47350a268aa991a33d767bb6fc29de16593e0b099e793aa1db638d","services":["pss","bzz"],"name":"node93"}}},{"node":{"config":{"services":["pss","bzz"],"name":"node94","id":"ac6057677fdfc132ea2418ff877357962771db049d169ba2c1923b15820385c6bf2f5846943d44a73bfdeb44a1e0d68307003a06cb0f694705879f8a720c3296","private_key":"393e54787cdfec2d8d987f785700170fbcb31fd541c9c05199cd77d3a16a6dc4"},"up":true,"info":{"protocols":{"bzz":"JH3LLHh6v6hFs5y51/mm1Z6pFQBvJQpNdgzdjhazpaY=","hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 247dcb\npopulation: 16 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 a6ca 9835 9b24 | 54 cb70 (0) ce12 (0) cd94 (0) c1c1 (0)\n001 3 6c29 5258 4e6e | 38 4a2d (0) 4f7a (0) 4e6e (0) 4610 (0)\n002 2 016e 1b61 | 25 0066 (0) 00b9 (0) 0104 (0) 016e (0)\n003 2 3547 30c0 | 4 39b5 (0) 351d (0) 3547 (0) 30c0 (0)\n004 1 2c3d | 1 2c3d (0)\n005 3 22b8 2124 20c4 | 3 22b8 (0) 2124 (0) 20c4 (0)\n============ DEPTH: 6 ==========================================\n006 1 2742 | 1 2742 (0)\n007 0 | 0\n008 0 | 0\n009 1 2426 | 1 2426 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"id":"ac6057677fdfc132ea2418ff877357962771db049d169ba2c1923b15820385c6bf2f5846943d44a73bfdeb44a1e0d68307003a06cb0f694705879f8a720c3296","listenAddr":"","name":"node94","enode":"enode://ac6057677fdfc132ea2418ff877357962771db049d169ba2c1923b15820385c6bf2f5846943d44a73bfdeb44a1e0d68307003a06cb0f694705879f8a720c3296@0.0.0.0:0","ports":{"listener":0,"discovery":0},"ip":"0.0.0.0"}}},{"node":{"info":{"id":"ed3a5d7602b59bd8709ef10cb84e4b5644a69490d1173a8b9135adba04b36c1fcd0f16543de39deff0e76d8314e6884ba939213f77abb8d50a68d030352cb495","protocols":{"bzz":"myQPvxLZ3nl1gDsJqs26uUzZeBMN5ivIlJe7EFbkYsA=","hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 9b240f\npopulation: 15 (126), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 247d 5f1c | 73 160c (0) 165d (0) 171f (0) 11b5 (0)\n001 2 d6a2 d486 | 24 c1c1 (0) c6ed (0) c42f (0) cb70 (0)\n002 1 adfd | 12 a93b (0) aff7 (0) ac38 (0) adfd (0)\n003 3 8357 8ff6 8937 | 9 869f (0) 8584 (0) 8174 (0) 8166 (0)\n004 3 9265 944e 958e | 4 9265 (0) 960e (0) 958e (0) 944e (0)\n005 2 9d60 9dc8 | 2 9d60 (0) 9dc8 (0)\n============ DEPTH: 6 ==========================================\n006 1 9835 | 1 9835 (0)\n007 1 9a8c | 1 9a8c (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ip":"0.0.0.0","ports":{"listener":0,"discovery":0},"enode":"enode://ed3a5d7602b59bd8709ef10cb84e4b5644a69490d1173a8b9135adba04b36c1fcd0f16543de39deff0e76d8314e6884ba939213f77abb8d50a68d030352cb495@0.0.0.0:0","name":"node95","listenAddr":""},"config":{"name":"node95","services":["pss","bzz"],"private_key":"0cd4a911f2b1193b22efc0823fc2ed9beddafb7705f5597ce6d7335aadae0e1a","id":"ed3a5d7602b59bd8709ef10cb84e4b5644a69490d1173a8b9135adba04b36c1fcd0f16543de39deff0e76d8314e6884ba939213f77abb8d50a68d030352cb495"},"up":true}},{"node":{"up":true,"config":{"name":"node96","services":["pss","bzz"],"private_key":"fb0590eb4eb2624363f0740cbc794f9adb8356ccbaf6650c8baca183edfde3b8","id":"255939ef32bd3e5e76181763c11707b9ff4ab26d3ffb10f06fa7249b06721fa3decfa9eee3eeb8b12d6218af5f9ed8872d62c42a90cd46dcbef3d89a8163ae07"},"info":{"enode":"enode://255939ef32bd3e5e76181763c11707b9ff4ab26d3ffb10f06fa7249b06721fa3decfa9eee3eeb8b12d6218af5f9ed8872d62c42a90cd46dcbef3d89a8163ae07@0.0.0.0:0","name":"node96","listenAddr":"","ip":"0.0.0.0","ports":{"listener":0,"discovery":0},"protocols":{"bzz":"Xxx1FkHhcnhxxE8NV3myeIccd/XgUyTckahiC+1y5ic=","hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 5f1c75\npopulation: 20 (115), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 9b24 | 43 c42f (0) c6ed (0) ce12 (0) cd94 (0)\n001 2 171f 12df | 35 160c (0) 165d (0) 171f (0) 11b5 (0)\n002 7 7a46 66f6 60cb 62d5 | 20 7d14 (0) 7c99 (0) 7a46 (0) 78db (0)\n003 3 43d7 41cd 4067 | 10 4a2d (0) 4e6e (0) 4f7a (0) 4610 (0)\n004 3 5672 57d3 5258 | 3 5672 (0) 57d3 (0) 5258 (0)\n============ DEPTH: 5 ==========================================\n005 3 5958 580a 5820 | 3 5958 (0) 580a (0) 5820 (0)\n006 0 | 0\n007 0 | 0\n008 1 5f8e | 1 5f8e (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"id":"255939ef32bd3e5e76181763c11707b9ff4ab26d3ffb10f06fa7249b06721fa3decfa9eee3eeb8b12d6218af5f9ed8872d62c42a90cd46dcbef3d89a8163ae07"}}},{"node":{"info":{"id":"a8b619f75e0e4cf7bc5e425ff9b03e55b7301fec4fb58f321bf89811678268d9f738bbf22ee36c2d14ff71a08d6f7dca28249ff6f943cc5a77653f482254d150","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 6ad608\npopulation: 13 (122), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 ede2 | 50 9a8c (0) 9b24 (0) 9835 (0) 9dc8 (0)\n001 1 12df | 35 165d (0) 171f (0) 11b5 (0) 1030 (0)\n002 2 41cd 5f1c | 18 4a2d (0) 4f7a (0) 4e6e (0) 45cd (0)\n003 2 766b 795d | 9 7d14 (0) 7c99 (0) 7a46 (0) 78db (0)\n004 2 6421 62d5 | 4 66f6 (0) 6421 (0) 60cb (0) 62d5 (0)\n005 2 6d30 6c29 | 3 6d30 (0) 6c2f (0) 6c29 (0)\n006 1 69ba | 1 69ba (0)\n============ DEPTH: 7 ==========================================\n007 2 6b1f 6b7d | 2 6b7d (0) 6b1f (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"atYI8Qh7ivQDWdtF59eOQ8NGX9rlzAGpqatsFJy2/fM="},"ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"enode":"enode://a8b619f75e0e4cf7bc5e425ff9b03e55b7301fec4fb58f321bf89811678268d9f738bbf22ee36c2d14ff71a08d6f7dca28249ff6f943cc5a77653f482254d150@0.0.0.0:0","listenAddr":"","name":"node97"},"config":{"name":"node97","services":["pss","bzz"],"private_key":"40d4caee240073f0bfc9307eed26d4286f944f467837b7250ee206f40d2880d4","id":"a8b619f75e0e4cf7bc5e425ff9b03e55b7301fec4fb58f321bf89811678268d9f738bbf22ee36c2d14ff71a08d6f7dca28249ff6f943cc5a77653f482254d150"},"up":true}},{"node":{"config":{"name":"node98","services":["pss","bzz"],"private_key":"207c5a4e99506c7afdfff66611cf0baefe929f7c8a1a7a802cb44df3fa650618","id":"eb6fa7d39fcee5a7081813169ae24ee6d355cfe717dcb2fa500a07c935ffbe1b12378ea13454742bf7c2df10ad2fd4e53476068eaef4669381c8cd060c199e11"},"up":true,"info":{"protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: ede256\npopulation: 14 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 30c0 7a46 6ad6 | 74 160c (0) 165d (0) 171f (0) 11b5 (0)\n001 2 9835 b270 | 30 9a8c (0) 9b24 (0) 9835 (0) 9d60 (0)\n002 3 d24a d486 d6a2 | 10 cb70 (0) ce12 (0) cd94 (0) c6ed (0)\n003 1 fb21 | 8 fe9d (0) fcf3 (0) fd54 (0) f843 (0)\n004 1 e22c | 1 e22c (0)\n005 2 e8d0 e884 | 2 e8d0 (0) e884 (0)\n============ DEPTH: 6 ==========================================\n006 2 ef40 efde | 2 ef40 (0) efde (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"7eJWjWDOehK0OAgYox0olfy5uBXPtVJtKLKoL/YuA4E="},"id":"eb6fa7d39fcee5a7081813169ae24ee6d355cfe717dcb2fa500a07c935ffbe1b12378ea13454742bf7c2df10ad2fd4e53476068eaef4669381c8cd060c199e11","name":"node98","listenAddr":"","enode":"enode://eb6fa7d39fcee5a7081813169ae24ee6d355cfe717dcb2fa500a07c935ffbe1b12378ea13454742bf7c2df10ad2fd4e53476068eaef4669381c8cd060c199e11@0.0.0.0:0","ports":{"discovery":0,"listener":0},"ip":"0.0.0.0"}}},{"node":{"up":true,"config":{"private_key":"fa964e311f099e564ffa3ff9820a9ad3a8723f738fce6da11be604636f275831","id":"49bd2289f479c9ad7e0d13319271b9be1e1dcbee28313513a124dec55f9842db639e62a74a83040930c537739ab7fa1e50bb05b9ab0f588d6da7b64a6451f466","name":"node99","services":["pss","bzz"]},"info":{"protocols":{"bzz":"MMAi35IJtFFSE/4/pnE1wF2WCvvXb4RVyqnIOrXkk7Y=","hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 30c022\npopulation: 19 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 ede2 | 54 9a8c (0) 9b24 (0) 9835 (0) 9d60 (0)\n001 2 5672 41cd | 38 7c99 (0) 7d14 (0) 7a46 (0) 78db (0)\n002 10 00b9 0104 1263 12df | 25 1f15 (0) 1d53 (0) 18b0 (0) 1b61 (0)\n003 3 20c4 2426 247d | 7 2c3d (0) 22b8 (0) 2124 (0) 20c4 (0)\n004 1 39b5 | 1 39b5 (0)\n============ DEPTH: 5 ==========================================\n005 2 351d 3547 | 2 351d (0) 3547 (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"id":"49bd2289f479c9ad7e0d13319271b9be1e1dcbee28313513a124dec55f9842db639e62a74a83040930c537739ab7fa1e50bb05b9ab0f588d6da7b64a6451f466","enode":"enode://49bd2289f479c9ad7e0d13319271b9be1e1dcbee28313513a124dec55f9842db639e62a74a83040930c537739ab7fa1e50bb05b9ab0f588d6da7b64a6451f466@0.0.0.0:0","listenAddr":"","name":"node99","ports":{"listener":0,"discovery":0},"ip":"0.0.0.0"}}},{"node":{"info":{"protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 41cd90\npopulation: 15 (112), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 b270 | 42 ce12 (0) cd94 (0) c1c1 (0) d6e3 (0)\n001 1 30c0 | 34 1d53 (0) 1f15 (0) 18b0 (0) 1b61 (0)\n002 4 795d 62d5 6ad6 6c29 | 20 7c99 (0) 7d14 (0) 7a46 (0) 78db (0)\n003 2 5258 5f1c | 7 5672 (0) 5258 (0) 5958 (0) 580a (0)\n004 2 4f7a 4e6e | 3 4a2d (0) 4e6e (0) 4f7a (0)\n005 2 4610 459a | 3 4610 (0) 45cd (0) 459a (0)\n006 1 43d7 | 1 43d7 (0)\n============ DEPTH: 7 ==========================================\n007 1 4067 | 1 4067 (0)\n008 0 | 0\n009 0 | 0\n010 1 41f4 | 1 41f4 (0)\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"Qc2QOr2vRFv7zD1fKMEKukc76KPdxhTH8SSw7X+R/R0="},"id":"06a8a25c6dd90e230237b06c086f14e539b31b8e3705752d0ad8faf1bd7239547332604b79b6124cbd0cee495b99a80f147983142b7271841d8d9fa85d559301","enode":"enode://06a8a25c6dd90e230237b06c086f14e539b31b8e3705752d0ad8faf1bd7239547332604b79b6124cbd0cee495b99a80f147983142b7271841d8d9fa85d559301@0.0.0.0:0","listenAddr":"","name":"node100","ports":{"listener":0,"discovery":0},"ip":"0.0.0.0"},"up":true,"config":{"private_key":"23f2913103e5295ddfdc6485c2ea3c33bfda3e0ceea62cac5401ceabdda0668a","id":"06a8a25c6dd90e230237b06c086f14e539b31b8e3705752d0ad8faf1bd7239547332604b79b6124cbd0cee495b99a80f147983142b7271841d8d9fa85d559301","name":"node100","services":["pss","bzz"]}}},{"node":{"info":{"ports":{"listener":0,"discovery":0},"ip":"0.0.0.0","listenAddr":"","name":"node101","enode":"enode://fd321c630fadcc8d6b00589323f7313ac1e94effbe8192955da5f88dcf419ef28820075e0e81c595561ff6ee58cfce23079407edf8b1611cb994946bcbd26364@0.0.0.0:0","id":"fd321c630fadcc8d6b00589323f7313ac1e94effbe8192955da5f88dcf419ef28820075e0e81c595561ff6ee58cfce23079407edf8b1611cb994946bcbd26364","protocols":{"bzz":"snDg0hoXP0cXiCscbclC1wP+Ec1q35l7Ps0JRPzqbHs=","hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: b270e0\npopulation: 17 (107), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 62d5 41cd | 60 39b5 (0) 30c0 (0) 351d (0) 3547 (0)\n001 3 d486 e8d0 ede2 | 18 c1c1 (0) c6ed (0) cd94 (0) ce12 (0)\n002 6 8174 8ff6 88dc 9265 | 18 9a8c (0) 9b24 (0) 9835 (0) 9d60 (0)\n003 2 adfd a6ca | 7 a93b (0) aff7 (0) ac38 (0) adfd (0)\n004 2 bb9c b87c | 2 bb9c (0) b87c (0)\n============ DEPTH: 5 ==========================================\n005 1 b778 | 1 b778 (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 1 b26e | 1 b26e (0)\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"up":true,"config":{"services":["pss","bzz"],"name":"node101","id":"fd321c630fadcc8d6b00589323f7313ac1e94effbe8192955da5f88dcf419ef28820075e0e81c595561ff6ee58cfce23079407edf8b1611cb994946bcbd26364","private_key":"f3c37d7a8e80e1e71fba834055bf934536fd9e117f496b156d46bca96632ba5c"}}},{"node":{"config":{"services":["pss","bzz"],"name":"node102","id":"7172a86afb608acd9a3e1e5c0472489ebecb516cad6796fa9a06ab47cc8e8cce12dddce72f0ac3b0927602bd22ed5872c3b5ce9b6af96f8e9d1d75078cc9bb55","private_key":"f4151729479b0ae76a7b853aa9d3460ee67adcedc364ac97248fb383478ba113"},"up":true,"info":{"id":"7172a86afb608acd9a3e1e5c0472489ebecb516cad6796fa9a06ab47cc8e8cce12dddce72f0ac3b0927602bd22ed5872c3b5ce9b6af96f8e9d1d75078cc9bb55","protocols":{"bzz":"psrY2mp5SddiS36mNv0tct5qmxT4md9iY8y0s+U1HGo=","hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: a6cad8\npopulation: 17 (126), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 5 4f7a 051c 12df 20c4 | 74 39b5 (0) 351d (0) 3547 (0) 30c0 (0)\n001 1 c1c1 | 23 cb70 (0) cd94 (0) ce12 (0) c6ed (0)\n002 3 8357 958e 9835 | 18 869f (0) 8584 (0) 8174 (0) 8166 (0)\n003 2 b26e b270 | 5 bb9c (0) b87c (0) b778 (0) b26e (0)\n004 4 a93b aff7 ac38 adfd | 4 a93b (0) aff7 (0) ac38 (0) adfd (0)\n============ DEPTH: 5 ==========================================\n005 2 a20d a3e8 | 2 a20d (0) a3e8 (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","name":"node102","enode":"enode://7172a86afb608acd9a3e1e5c0472489ebecb516cad6796fa9a06ab47cc8e8cce12dddce72f0ac3b0927602bd22ed5872c3b5ce9b6af96f8e9d1d75078cc9bb55@0.0.0.0:0"}}},{"node":{"config":{"name":"node103","services":["pss","bzz"],"private_key":"482aa546e8e665988c7329424342961c10084e439d562aed129d21a8c212d007","id":"a2719942ffb6e99bda131cdedb612785dafdf72f5f35824343ad39d8568d6cd25e44b585a915c8e9ea2b02e6fd38c105bb17ed27c8fa320f18c83e0ace78feb5"},"up":true,"info":{"ip":"0.0.0.0","ports":{"listener":0,"discovery":0},"name":"node103","listenAddr":"","enode":"enode://a2719942ffb6e99bda131cdedb612785dafdf72f5f35824343ad39d8568d6cd25e44b585a915c8e9ea2b02e6fd38c105bb17ed27c8fa320f18c83e0ace78feb5@0.0.0.0:0","id":"a2719942ffb6e99bda131cdedb612785dafdf72f5f35824343ad39d8568d6cd25e44b585a915c8e9ea2b02e6fd38c105bb17ed27c8fa320f18c83e0ace78feb5","protocols":{"bzz":"mDX6nbHOU60qUm02BQ7v0sWTEh30A2wmnNCeG+R0ahU=","hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 9835fa\npopulation: 16 (104), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 5 6421 0d90 12df 2124 | 56 39b5 (0) 30c0 (0) 3547 (0) 2c3d (0)\n001 1 ede2 | 19 cd94 (0) ce12 (0) c42f (0) c1c1 (0)\n002 2 a6ca adfd | 12 b87c (0) bb9c (0) b778 (0) b26e (0)\n003 1 8166 | 9 8584 (0) 869f (0) 8174 (0) 8166 (0)\n004 3 960e 958e 944e | 4 9265 (0) 960e (0) 958e (0) 944e (0)\n005 2 9d60 9dc8 | 2 9d60 (0) 9dc8 (0)\n============ DEPTH: 6 ==========================================\n006 2 9a8c 9b24 | 2 9a8c (0) 9b24 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}}}},{"node":{"info":{"protocols":{"bzz":"rf3mm3YzGI18WkTlHoVtAjyUbUzY/Ra/U55tF2TdfgQ=","hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: adfde6\npopulation: 20 (119), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 051c 1a16 62d5 6c29 | 68 39b5 (0) 30c0 (0) 351d (0) 3547 (0)\n001 3 fd54 d486 d6a2 | 22 c1c1 (0) c6ed (0) c42f (0) ce12 (0)\n002 5 8357 88dc 9dc8 9b24 | 18 869f (0) 8584 (0) 8174 (0) 8166 (0)\n003 2 b270 b26e | 5 bb9c (0) b87c (0) b778 (0) b26e (0)\n004 3 a20d a3e8 a6ca | 3 a20d (0) a3e8 (0) a6ca (0)\n005 1 a93b | 1 a93b (0)\n============ DEPTH: 6 ==========================================\n006 1 aff7 | 1 aff7 (0)\n007 1 ac38 | 1 ac38 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"id":"e706876f36646bfb2dfbd11669a4907432660023a13be9de329a03f6c6e88e3788002b83d0cb4617e6c4096998783925be5b1de4f0edd8128e7d71312fb1091d","enode":"enode://e706876f36646bfb2dfbd11669a4907432660023a13be9de329a03f6c6e88e3788002b83d0cb4617e6c4096998783925be5b1de4f0edd8128e7d71312fb1091d@0.0.0.0:0","name":"node104","listenAddr":"","ports":{"listener":0,"discovery":0},"ip":"0.0.0.0"},"up":true,"config":{"private_key":"2641708c3c6101db41db1a7eba5ed6b54e7ebc3014cb575ed71d291a6aacfc28","id":"e706876f36646bfb2dfbd11669a4907432660023a13be9de329a03f6c6e88e3788002b83d0cb4617e6c4096998783925be5b1de4f0edd8128e7d71312fb1091d","name":"node104","services":["pss","bzz"]}}},{"node":{"config":{"id":"cc0d13dba120558dc8e2d0e5ac755a712e7e7e6dab6edcaf658faf02537b1efe3d6c54d6e67566eb4a3a8f8a019702aa7ee2b33ee3f0316a01e7b17845032e70","private_key":"9b9c1c2253292c4de58f82fd6bba15922acfa246fa0717a869c0d651ce19e826","services":["pss","bzz"],"name":"node105"},"up":true,"info":{"name":"node105","listenAddr":"","enode":"enode://cc0d13dba120558dc8e2d0e5ac755a712e7e7e6dab6edcaf658faf02537b1efe3d6c54d6e67566eb4a3a8f8a019702aa7ee2b33ee3f0316a01e7b17845032e70@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 6c29a1\npopulation: 15 (126), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 88dc adfd | 53 c6ed (0) c42f (0) c1c1 (0) ce12 (0)\n001 5 12df 1b61 1a16 247d | 36 39b5 (0) 351d (0) 3547 (0) 30c0 (0)\n002 2 41cd 5f1c | 18 5672 (0) 57d3 (0) 5258 (0) 5958 (0)\n003 2 766b 795d | 9 7d14 (0) 7c99 (0) 7a46 (0) 78db (0)\n004 1 62d5 | 4 66f6 (0) 6421 (0) 60cb (0) 62d5 (0)\n005 1 6ad6 | 4 69ba (0) 6b7d (0) 6b1f (0) 6ad6 (0)\n006 0 | 0\n============ DEPTH: 7 ==========================================\n007 1 6d30 | 1 6d30 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 1 6c2f | 1 6c2f (0)\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"bCmhvA8QJSB7RST63XyM092VaBb9/Fe7UlxK07zKkWk="},"id":"cc0d13dba120558dc8e2d0e5ac755a712e7e7e6dab6edcaf658faf02537b1efe3d6c54d6e67566eb4a3a8f8a019702aa7ee2b33ee3f0316a01e7b17845032e70"}}},{"node":{"info":{"ip":"0.0.0.0","ports":{"listener":0,"discovery":0},"listenAddr":"","name":"node106","enode":"enode://e3779b202b9cfe7b2f2cc9e95974ac77bf51ba951f775acc10f07249ee6b3b260f2b012bb010a7f9794c5562e9b00f18b52c25c1e350ab70afc6bf9e210e4969@0.0.0.0:0","id":"e3779b202b9cfe7b2f2cc9e95974ac77bf51ba951f775acc10f07249ee6b3b260f2b012bb010a7f9794c5562e9b00f18b52c25c1e350ab70afc6bf9e210e4969","protocols":{"bzz":"iNxfMaKylei0O8bnq6rhMAYcLUTEnJW8yj2d0KJoMkw=","hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 88dc5f\npopulation: 12 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 6c29 | 74 39b5 (0) 351d (0) 3547 (0) 30c0 (0)\n001 1 e884 | 24 cb70 (0) ce12 (0) cd94 (0) c6ed (0)\n002 3 adfd b270 b26e | 12 bb9c (0) b87c (0) b778 (0) b26e (0)\n003 1 944e | 9 9a8c (0) 9b24 (0) 9835 (0) 9d60 (0)\n004 3 8174 8166 8357 | 5 869f (0) 8584 (0) 8174 (0) 8166 (0)\n005 1 8ff6 | 1 8ff6 (0)\n006 0 | 0\n============ DEPTH: 7 ==========================================\n007 1 8937 | 1 8937 (0)\n008 0 | 0\n009 1 88a9 | 1 88a9 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"up":true,"config":{"name":"node106","services":["pss","bzz"],"private_key":"7cc79c34ac4847aaba7f1e2de8d23910301dbfe606d052cce33ad0340a1f82fb","id":"e3779b202b9cfe7b2f2cc9e95974ac77bf51ba951f775acc10f07249ee6b3b260f2b012bb010a7f9794c5562e9b00f18b52c25c1e350ab70afc6bf9e210e4969"}}},{"node":{"config":{"private_key":"4047502d07951bf2380ef595036f9e99db3b0f7e1229040e21da5fbc49e7d820","id":"f394aaa6d14c6ed95e2ad4651b5103bb1ab9f3a61839936cc1f08d6a6e53504e5d15dfc5211539ffdbdc64912ded5c2272d4af52ed8d7fe5a3c228eb12f0c68b","name":"node107","services":["pss","bzz"]},"up":true,"info":{"protocols":{"bzz":"6IS9ZmsCFc/ojuGUV8Z8dH+xxoFYVRYPHCQ8FJsk6SM=","hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: e884bd\npopulation: 13 (126), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 4067 016e 1b61 20c4 | 73 39b5 (0) 351d (0) 3547 (0) 30c0 (0)\n001 2 88dc 8357 | 30 a3e8 (0) a20d (0) a6ca (0) a93b (0)\n002 1 d486 | 10 cb70 (0) ce12 (0) cd94 (0) c6ed (0)\n003 1 fd54 | 8 f7cd (0) fb21 (0) f843 (0) f926 (0)\n004 1 e22c | 1 e22c (0)\n============ DEPTH: 5 ==========================================\n005 3 ef40 efde ede2 | 3 efde (0) ef40 (0) ede2 (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 1 e8d0 | 1 e8d0 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"id":"f394aaa6d14c6ed95e2ad4651b5103bb1ab9f3a61839936cc1f08d6a6e53504e5d15dfc5211539ffdbdc64912ded5c2272d4af52ed8d7fe5a3c228eb12f0c68b","listenAddr":"","name":"node107","enode":"enode://f394aaa6d14c6ed95e2ad4651b5103bb1ab9f3a61839936cc1f08d6a6e53504e5d15dfc5211539ffdbdc64912ded5c2272d4af52ed8d7fe5a3c228eb12f0c68b@0.0.0.0:0","ip":"0.0.0.0","ports":{"discovery":0,"listener":0}}}},{"node":{"info":{"ports":{"listener":0,"discovery":0},"ip":"0.0.0.0","enode":"enode://38469be067f9bba869fdfcc950843e00b5ff950778c11445787501d47cbaf60e9940735a5b8b71d48a0aaee75c8263137169d51944638dc5d1cad398d22439ed@0.0.0.0:0","name":"node108","listenAddr":"","id":"38469be067f9bba869fdfcc950843e00b5ff950778c11445787501d47cbaf60e9940735a5b8b71d48a0aaee75c8263137169d51944638dc5d1cad398d22439ed","protocols":{"bzz":"g1fuqmWAjwm5qDNiywdQiHi+zun4Q6Xh5w0CUWexmOo=","hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 8357ee\npopulation: 19 (123), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 051c 69ba | 70 39b5 (0) 351d (0) 3547 (0) 30c0 (0)\n001 2 f926 e884 | 24 cb70 (0) ce12 (0) cd94 (0) c6ed (0)\n002 4 b778 b26e adfd a6ca | 12 a20d (0) a3e8 (0) a6ca (0) a93b (0)\n003 4 9b24 9d60 958e 944e | 9 9a8c (0) 9b24 (0) 9835 (0) 9d60 (0)\n004 3 8937 88a9 88dc | 4 8ff6 (0) 8937 (0) 88a9 (0) 88dc (0)\n005 2 869f 8584 | 2 869f (0) 8584 (0)\n============ DEPTH: 6 ==========================================\n006 2 8166 8174 | 2 8174 (0) 8166 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"up":true,"config":{"id":"38469be067f9bba869fdfcc950843e00b5ff950778c11445787501d47cbaf60e9940735a5b8b71d48a0aaee75c8263137169d51944638dc5d1cad398d22439ed","private_key":"02a6713184cf6e413a6ed6a6839150cad9c72d40951b265a754e56b5bdb74cbf","services":["pss","bzz"],"name":"node108"}}},{"node":{"up":true,"config":{"id":"81df6add458aaaaf51a3ad8826250f3498f06586264f95cd7fce642ac08bd583f463a7531e292175f90887013ba39f8757c21eb5524ec62ec413b82badae935a","private_key":"12d74d71de5166524deeed2ba475f9ad46c296668af272f0ade12162bed0f50f","services":["pss","bzz"],"name":"node109"},"info":{"ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"enode":"enode://81df6add458aaaaf51a3ad8826250f3498f06586264f95cd7fce642ac08bd583f463a7531e292175f90887013ba39f8757c21eb5524ec62ec413b82badae935a@0.0.0.0:0","name":"node109","listenAddr":"","id":"81df6add458aaaaf51a3ad8826250f3498f06586264f95cd7fce642ac08bd583f463a7531e292175f90887013ba39f8757c21eb5524ec62ec413b82badae935a","protocols":{"bzz":"abr37kOzYKMjitOxdeCtnCSWfa5gx+kdHKfuVRZ7K9s=","hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 69baf7\npopulation: 11 (123), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 8357 | 50 c42f (0) c1c1 (0) cb70 (0) cd94 (0)\n001 1 0104 | 36 39b5 (0) 351d (0) 3547 (0) 30c0 (0)\n002 2 580a 5672 | 18 5258 (0) 57d3 (0) 5672 (0) 5958 (0)\n003 1 7a46 | 9 78db (0) 795d (0) 7a46 (0) 7c99 (0)\n004 2 6421 62d5 | 4 6421 (0) 66f6 (0) 60cb (0) 62d5 (0)\n005 1 6c2f | 3 6d30 (0) 6c29 (0) 6c2f (0)\n============ DEPTH: 6 ==========================================\n006 3 6ad6 6b1f 6b7d | 3 6ad6 (0) 6b7d (0) 6b1f (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}}}},{"node":{"up":true,"config":{"name":"node110","services":["pss","bzz"],"private_key":"4fff513c0f905a42d6d18a90ae6a78c60757490480579162c9e0760361baf184","id":"e90ca22b959d482861c52e9e51fd2d63557453dce64dab9f66fcf323273c12e7189358f85d500f5200ff7c7b2d57afe72577ed9aa2adb36fc0c8e5504588fe94"},"info":{"id":"e90ca22b959d482861c52e9e51fd2d63557453dce64dab9f66fcf323273c12e7189358f85d500f5200ff7c7b2d57afe72577ed9aa2adb36fc0c8e5504588fe94","protocols":{"bzz":"AQTD+j9rkjdWV1nevtPx/Ov6de+6fwHoHwalMnTN9hk=","hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 0104c3\npopulation: 14 (124), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 d6a2 fd54 | 51 c6ed (0) c42f (0) c1c1 (0) ce12 (0)\n001 2 69ba 7a46 | 38 5258 (0) 57d3 (0) 5672 (0) 5958 (0)\n002 3 2426 30c0 3547 | 11 39b5 (0) 351d (0) 3547 (0) 30c0 (0)\n003 1 171f | 14 160c (0) 165d (0) 171f (0) 11b5 (0)\n004 2 0f19 089f | 4 0ef0 (0) 0f19 (0) 0d90 (0) 089f (0)\n005 1 051c | 3 07c7 (0) 0561 (0) 051c (0)\n006 0 | 0\n============ DEPTH: 7 ==========================================\n007 2 00b9 0066 | 2 0066 (0) 00b9 (0)\n008 0 | 0\n009 1 016e | 1 016e (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"listener":0,"discovery":0},"ip":"0.0.0.0","name":"node110","listenAddr":"","enode":"enode://e90ca22b959d482861c52e9e51fd2d63557453dce64dab9f66fcf323273c12e7189358f85d500f5200ff7c7b2d57afe72577ed9aa2adb36fc0c8e5504588fe94@0.0.0.0:0"}}},{"node":{"up":true,"config":{"services":["pss","bzz"],"name":"node111","id":"84379884f012e2cfc1f9838312640576c9ded01ca53cf8451f94915e6949f0084047a2555a5fef4d1b0eef62ad5504a34ff631fbb658b011a07a82a53173f5c1","private_key":"5db638bd9bfaf4c2e1af1f3f1dc1e89382a6a2982f303fc80504b44aac1a6264"},"info":{"id":"84379884f012e2cfc1f9838312640576c9ded01ca53cf8451f94915e6949f0084047a2555a5fef4d1b0eef62ad5504a34ff631fbb658b011a07a82a53173f5c1","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 7a46bf\npopulation: 16 (104), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 ede2 | 33 cd94 (0) d486 (0) d6e3 (0) d24a (0)\n001 2 016e 0104 | 35 39b5 (0) 351d (0) 3547 (0) 30c0 (0)\n002 4 5f1c 580a 5258 5672 | 17 5258 (0) 57d3 (0) 5672 (0) 5958 (0)\n003 3 6421 6b1f 69ba | 11 6421 (0) 66f6 (0) 60cb (0) 62d5 (0)\n004 2 776f 74a4 | 4 766b (0) 776f (0) 7468 (0) 74a4 (0)\n005 2 7d14 7c99 | 2 7c99 (0) 7d14 (0)\n============ DEPTH: 6 ==========================================\n006 2 795d 78db | 2 795d (0) 78db (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"eka/A/MnsQDcABQMl4KKO2BygLbNVyIHA745OuT93bw="},"ports":{"discovery":0,"listener":0},"ip":"0.0.0.0","enode":"enode://84379884f012e2cfc1f9838312640576c9ded01ca53cf8451f94915e6949f0084047a2555a5fef4d1b0eef62ad5504a34ff631fbb658b011a07a82a53173f5c1@0.0.0.0:0","name":"node111","listenAddr":""}}},{"node":{"config":{"private_key":"6caa9dcb10b84a658d4ef791909b6532395f0793f9f8bce99a3a1b985ce619b9","id":"11170a0fb9f6b037f8ee4494e935a84b06816ff5c44ef9d613920f9c58f8b25611b2093da3fb51a59687db6a9b0a070386cac09757a27f75754cbdcb9afc2225","name":"node112","services":["pss","bzz"]},"up":true,"info":{"id":"11170a0fb9f6b037f8ee4494e935a84b06816ff5c44ef9d613920f9c58f8b25611b2093da3fb51a59687db6a9b0a070386cac09757a27f75754cbdcb9afc2225","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 016e17\npopulation: 13 (124), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 e884 fd54 ce12 | 51 ac38 (0) adfd (0) aff7 (0) a93b (0)\n001 1 7a46 | 38 57d3 (0) 5672 (0) 5258 (0) 5958 (0)\n002 1 247d | 11 39b5 (0) 351d (0) 3547 (0) 30c0 (0)\n003 3 165d 171f 12df | 14 160c (0) 165d (0) 171f (0) 11b5 (0)\n004 1 0f19 | 4 0ef0 (0) 0f19 (0) 0d90 (0) 089f (0)\n005 1 07c7 | 3 07c7 (0) 0561 (0) 051c (0)\n006 0 | 0\n============ DEPTH: 7 ==========================================\n007 2 0066 00b9 | 2 0066 (0) 00b9 (0)\n008 0 | 0\n009 1 0104 | 1 0104 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"AW4XSincGIVxB/vryHZom0AcEXSWSsbKyzGky4R6TTA="},"ports":{"listener":0,"discovery":0},"ip":"0.0.0.0","enode":"enode://11170a0fb9f6b037f8ee4494e935a84b06816ff5c44ef9d613920f9c58f8b25611b2093da3fb51a59687db6a9b0a070386cac09757a27f75754cbdcb9afc2225@0.0.0.0:0","name":"node112","listenAddr":""}}},{"node":{"info":{"ip":"0.0.0.0","ports":{"listener":0,"discovery":0},"listenAddr":"","name":"node113","enode":"enode://ab3a3ad0481a80b91132cc6afeaab9c9f5e931885d979176e8e6c181d997c38b488e5eca475b0f8e949a8cf128695e18a5851091394d0a33cf834ce7e3537ac2@0.0.0.0:0","id":"ab3a3ad0481a80b91132cc6afeaab9c9f5e931885d979176e8e6c181d997c38b488e5eca475b0f8e949a8cf128695e18a5851091394d0a33cf834ce7e3537ac2","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 00b98e\npopulation: 18 (125), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 ce12 | 52 a93b (0) aff7 (0) ac38 (0) adfd (0)\n001 3 5958 5258 5672 | 38 57d3 (0) 5672 (0) 5258 (0) 5958 (0)\n002 4 39b5 3547 30c0 2c3d | 11 39b5 (0) 351d (0) 3547 (0) 30c0 (0)\n003 2 165d 160c | 14 160c (0) 165d (0) 171f (0) 11b5 (0)\n004 2 0ef0 089f | 4 0ef0 (0) 0f19 (0) 0d90 (0) 089f (0)\n005 3 0561 051c 07c7 | 3 07c7 (0) 0561 (0) 051c (0)\n006 0 | 0\n============ DEPTH: 7 ==========================================\n007 2 0104 016e | 2 0104 (0) 016e (0)\n008 1 0066 | 1 0066 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"ALmOeQ+5VJdYN/+Vq7G9wmc92KDOMVmGzA3aWwzvsF0="}},"up":true,"config":{"id":"ab3a3ad0481a80b91132cc6afeaab9c9f5e931885d979176e8e6c181d997c38b488e5eca475b0f8e949a8cf128695e18a5851091394d0a33cf834ce7e3537ac2","private_key":"63375740be7dc5d3a76a7b3249786a4c7382eaf8b648e5a39a7a850722bad29a","services":["pss","bzz"],"name":"node113"}}},{"node":{"info":{"id":"6070dc131e9721a4a496b3ed6ff5c9db1a5351e942ed424b86fe6be940d1012df766afb4b0112452dfd63e0fcfea13658324a9ef4a94b5754ec9f6219e4b0d67","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: ce12d7\npopulation: 15 (122), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 016e 00b9 3547 | 72 6421 (0) 66f6 (0) 60cb (0) 62d5 (0)\n001 3 bb9c 8584 8937 | 29 a3e8 (0) a20d (0) a6ca (0) a93b (0)\n002 2 efde fb21 | 12 f7cd (0) fe9d (0) fd54 (0) f843 (0)\n003 2 d486 d24a | 4 d6a2 (0) d6e3 (0) d486 (0) d24a (0)\n004 3 c1c1 c42f c6ed | 3 c1c1 (0) c42f (0) c6ed (0)\n============ DEPTH: 5 ==========================================\n005 1 cb70 | 1 cb70 (0)\n006 1 cd94 | 1 cd94 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"zhLXsmc20I6qQkpflypaH9UNBaqzMDQPNgXbq4AHvyg="},"ports":{"listener":0,"discovery":0},"ip":"0.0.0.0","listenAddr":"","name":"node114","enode":"enode://6070dc131e9721a4a496b3ed6ff5c9db1a5351e942ed424b86fe6be940d1012df766afb4b0112452dfd63e0fcfea13658324a9ef4a94b5754ec9f6219e4b0d67@0.0.0.0:0"},"up":true,"config":{"name":"node114","services":["pss","bzz"],"private_key":"110a610c6c2f1720584929baf4ab9c8490923fc7b421bd251e444b752f8f8957","id":"6070dc131e9721a4a496b3ed6ff5c9db1a5351e942ed424b86fe6be940d1012df766afb4b0112452dfd63e0fcfea13658324a9ef4a94b5754ec9f6219e4b0d67"}}},{"node":{"up":true,"config":{"name":"node115","services":["pss","bzz"],"private_key":"7a8380aa7312fe4859408a51876e9f44b56151086e4bc36569a8f55bfb3a007b","id":"0bf28b481d71062ee100d6cb04c8b4234a574f8657e2d3c49b60a9ecdbf486d0ec38b33bce745c8efe820145d5c53ea802aa64b4f9bce19b029ee5b2f9de43f1"},"info":{"ip":"0.0.0.0","ports":{"listener":0,"discovery":0},"enode":"enode://0bf28b481d71062ee100d6cb04c8b4234a574f8657e2d3c49b60a9ecdbf486d0ec38b33bce745c8efe820145d5c53ea802aa64b4f9bce19b029ee5b2f9de43f1@0.0.0.0:0","listenAddr":"","name":"node115","id":"0bf28b481d71062ee100d6cb04c8b4234a574f8657e2d3c49b60a9ecdbf486d0ec38b33bce745c8efe820145d5c53ea802aa64b4f9bce19b029ee5b2f9de43f1","protocols":{"bzz":"NUeHHfVB0HNMN05MQvYQ8jXwySPYsr3IjBf62yyOJeo=","hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 354787\npopulation: 22 (126), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 9265 ce12 | 53 a93b (0) aff7 (0) adfd (0) ac38 (0)\n001 2 66f6 6421 | 38 6421 (0) 66f6 (0) 60cb (0) 62d5 (0)\n002 10 1263 12df 18b0 1a69 | 25 160c (0) 165d (0) 171f (0) 11b5 (0)\n003 5 2742 247d 22b8 20c4 | 7 2c3d (0) 2742 (0) 2426 (0) 247d (0)\n004 1 39b5 | 1 39b5 (0)\n============ DEPTH: 5 ==========================================\n005 1 30c0 | 1 30c0 (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 1 351d | 1 351d (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}}}},{"node":{"config":{"services":["pss","bzz"],"name":"node116","id":"d33f82b6a46535e798b78ebb28047ece1ef3b696ab29726d283161c377ed17a735a0948b99d83dee2af71704001e2e13813854a1b0ef4fcefd3c0e5c5f6e720d","private_key":"1e498dce32dcdfdf4b6c691fa203e3809fddf1b19b1b1da0b1162b9037ecc303"},"up":true,"info":{"id":"d33f82b6a46535e798b78ebb28047ece1ef3b696ab29726d283161c377ed17a735a0948b99d83dee2af71704001e2e13813854a1b0ef4fcefd3c0e5c5f6e720d","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 089fe2\npopulation: 15 (124), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 c6ed efde | 51 b778 (0) b270 (0) b26e (0) b87c (0)\n001 2 62d5 5958 | 38 60cb (0) 62d5 (0) 66f6 (0) 6421 (0)\n002 2 2124 3547 | 11 2c3d (0) 2742 (0) 2426 (0) 247d (0)\n003 3 1263 12df 1a69 | 14 160c (0) 165d (0) 171f (0) 11b5 (0)\n004 3 00b9 0066 0104 | 7 07c7 (0) 0561 (0) 051c (0) 00b9 (0)\n============ DEPTH: 5 ==========================================\n005 3 0ef0 0f19 0d90 | 3 0ef0 (0) 0f19 (0) 0d90 (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"CJ/iKgvUjTEgzIFx651phTLBfzZ2jbwl9VTyxT3hGrA="},"ports":{"discovery":0,"listener":0},"ip":"0.0.0.0","enode":"enode://d33f82b6a46535e798b78ebb28047ece1ef3b696ab29726d283161c377ed17a735a0948b99d83dee2af71704001e2e13813854a1b0ef4fcefd3c0e5c5f6e720d@0.0.0.0:0","name":"node116","listenAddr":""}}},{"node":{"up":true,"config":{"name":"node117","services":["pss","bzz"],"private_key":"03de0803048f078de61e3eef039a9ecb0e761216573392a6692630f3f291cc25","id":"519ce8f43529d0c703ef4faf50450877dc2818fd6fd6b7faaa9bbbaeac373e499d1b4a17b387b1a8d35e8042e18a9d3d365c97254b4d24352b10e8de9219a5cd"},"info":{"id":"519ce8f43529d0c703ef4faf50450877dc2818fd6fd6b7faaa9bbbaeac373e499d1b4a17b387b1a8d35e8042e18a9d3d365c97254b4d24352b10e8de9219a5cd","protocols":{"bzz":"GmlkYt49g/8nHzD21m3paDJeN6Nod91ntF2c3X5kS1s=","hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 1a6964\npopulation: 15 (109), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 efde | 39 b778 (0) b270 (0) bb9c (0) b87c (0)\n001 3 6b7d 6b1f 6421 | 35 60cb (0) 62d5 (0) 66f6 (0) 6421 (0)\n002 2 30c0 3547 | 11 39b5 (0) 351d (0) 3547 (0) 30c0 (0)\n003 1 089f | 11 07c7 (0) 0561 (0) 051c (0) 00b9 (0)\n004 3 165d 171f 12df | 8 160c (0) 165d (0) 171f (0) 1030 (0)\n005 2 1f15 1d53 | 2 1f15 (0) 1d53 (0)\n006 1 18b0 | 1 18b0 (0)\n============ DEPTH: 7 ==========================================\n007 1 1b61 | 1 1b61 (0)\n008 0 | 0\n009 1 1a16 | 1 1a16 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","name":"node117","enode":"enode://519ce8f43529d0c703ef4faf50450877dc2818fd6fd6b7faaa9bbbaeac373e499d1b4a17b387b1a8d35e8042e18a9d3d365c97254b4d24352b10e8de9219a5cd@0.0.0.0:0"}}},{"node":{"info":{"ip":"0.0.0.0","ports":{"listener":0,"discovery":0},"enode":"enode://59fe05843cc637adac3728acb8ca9650f49050095cf5d32241366f54d4ac7179b16dcb009e2fb9fa9499cc6f8b865b6c4d6fe6e35500df10ba5daa719d57976e@0.0.0.0:0","name":"node118","listenAddr":"","id":"59fe05843cc637adac3728acb8ca9650f49050095cf5d32241366f54d4ac7179b16dcb009e2fb9fa9499cc6f8b865b6c4d6fe6e35500df10ba5daa719d57976e","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 12df49\npopulation: 23 (88), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 9835 a6ca efde | 20 9dc8 (0) 9b24 (0) 9a8c (0) 9835 (0)\n001 5 5f1c 766b 6d30 6c29 | 34 60cb (0) 62d5 (0) 66f6 (0) 6421 (0)\n002 2 3547 30c0 | 10 39b5 (0) 30c0 (0) 3547 (0) 2c3d (0)\n003 2 016e 089f | 11 07c7 (0) 0561 (0) 051c (0) 00b9 (0)\n004 4 1d53 1b61 1a16 1a69 | 6 1f15 (0) 1d53 (0) 18b0 (0) 1b61 (0)\n005 3 160c 165d 171f | 3 160c (0) 165d (0) 171f (0)\n006 2 11b5 1030 | 2 11b5 (0) 1030 (0)\n============ DEPTH: 7 ==========================================\n007 1 1316 | 1 1316 (0)\n008 1 1263 | 1 1263 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"Et9JJ/90PU3Z37Cn0T05ASsXL2o1khqu8VR9XQKtOP4="}},"config":{"id":"59fe05843cc637adac3728acb8ca9650f49050095cf5d32241366f54d4ac7179b16dcb009e2fb9fa9499cc6f8b865b6c4d6fe6e35500df10ba5daa719d57976e","private_key":"934aa39349989614a1b0a71785880e61c60bb2579a9d52b832887849de94ec24","services":["pss","bzz"],"name":"node118"},"up":true}},{"node":{"config":{"name":"node119","services":["pss","bzz"],"private_key":"011d6fce7eed10fc8c5a7a9ca21769efc6581023c2c857c28d97a6ebb1c43a53","id":"3db9984cb1e25bdc30c483f3d4c036fb1728bafffecd2b965af7e701569c28116dbed2e5892504ea9927c14570351b03cb99112a5924a27e6e03289422785c7b"},"up":true,"info":{"id":"3db9984cb1e25bdc30c483f3d4c036fb1728bafffecd2b965af7e701569c28116dbed2e5892504ea9927c14570351b03cb99112a5924a27e6e03289422785c7b","protocols":{"bzz":"797nybq3XoUwLjyslcokNK9jzLcx7STgvaQZ56Rxzd4=","hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: efdee7\npopulation: 22 (97), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 9 089f 1a69 1263 12df | 59 39b5 (0) 30c0 (0) 351d (0) 3547 (0)\n001 2 8166 9a8c | 18 b26e (0) bb9c (0) b87c (0) a3e8 (0)\n002 2 cd94 ce12 | 7 d6e3 (0) d24a (0) c42f (0) c6ed (0)\n003 4 fb21 f843 f9e4 f7cd | 8 fe9d (0) fd54 (0) fcf3 (0) fb21 (0)\n004 1 e22c | 1 e22c (0)\n005 2 e884 e8d0 | 2 e884 (0) e8d0 (0)\n============ DEPTH: 6 ==========================================\n006 1 ede2 | 1 ede2 (0)\n007 0 | 0\n008 1 ef40 | 1 ef40 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ip":"0.0.0.0","ports":{"listener":0,"discovery":0},"listenAddr":"","name":"node119","enode":"enode://3db9984cb1e25bdc30c483f3d4c036fb1728bafffecd2b965af7e701569c28116dbed2e5892504ea9927c14570351b03cb99112a5924a27e6e03289422785c7b@0.0.0.0:0"}}},{"node":{"config":{"services":["pss","bzz"],"name":"node120","id":"af0050715bfa25b4ce3a7593c61578898be22801a9118064250c330c6b2a1416b3bc6d90b074d7d700e07574a274d861f9c6d8e3e5924c281502f699ad62465b","private_key":"76d98f9c684d01fe8121cf715f01457e9fc38146a717958c8bb325a3b4ea44ce"},"up":true,"info":{"ports":{"discovery":0,"listener":0},"ip":"0.0.0.0","enode":"enode://af0050715bfa25b4ce3a7593c61578898be22801a9118064250c330c6b2a1416b3bc6d90b074d7d700e07574a274d861f9c6d8e3e5924c281502f699ad62465b@0.0.0.0:0","listenAddr":"","name":"node120","id":"af0050715bfa25b4ce3a7593c61578898be22801a9118064250c330c6b2a1416b3bc6d90b074d7d700e07574a274d861f9c6d8e3e5924c281502f699ad62465b","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 58207f\npopulation: 14 (122), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 efde | 49 958e (0) 960e (0) 9265 (0) 9dc8 (0)\n001 1 2124 | 36 07c7 (0) 0561 (0) 051c (0) 0066 (0)\n002 4 7d14 7c99 6c2f 6421 | 20 60cb (0) 62d5 (0) 66f6 (0) 6421 (0)\n003 1 41f4 | 10 4e6e (0) 4f7a (0) 4a2d (0) 4610 (0)\n004 3 5258 57d3 5672 | 3 5258 (0) 57d3 (0) 5672 (0)\n005 2 5f1c 5f8e | 2 5f1c (0) 5f8e (0)\n006 0 | 0\n============ DEPTH: 7 ==========================================\n007 1 5958 | 1 5958 (0)\n008 0 | 0\n009 0 | 0\n010 1 580a | 1 580a (0)\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"WCB/yNkuRKgnQ5jWEFuQ12OYGvunAhtXvphZHntzknI="}}}},{"node":{"config":{"id":"35ac328e13ea4fc6c333591633455cb6a2dff124528a17668770e231582ea31ab95e083cd191d8c45369d88366e9df0d2417cd26efbf2f616139c92fd497cd48","private_key":"7aa614585809bea3b748e6df2e1a8da2b201a9ae84f11c819b5669234a10f76d","services":["pss","bzz"],"name":"node121"},"up":true,"info":{"ports":{"discovery":0,"listener":0},"ip":"0.0.0.0","enode":"enode://35ac328e13ea4fc6c333591633455cb6a2dff124528a17668770e231582ea31ab95e083cd191d8c45369d88366e9df0d2417cd26efbf2f616139c92fd497cd48@0.0.0.0:0","listenAddr":"","name":"node121","id":"35ac328e13ea4fc6c333591633455cb6a2dff124528a17668770e231582ea31ab95e083cd191d8c45369d88366e9df0d2417cd26efbf2f616139c92fd497cd48","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 212479\npopulation: 16 (122), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 5 fb21 c6ed 9835 9dc8 | 49 e22c (0) e8d0 (0) e884 (0) ede2 (0)\n001 1 5820 | 38 60cb (0) 62d5 (0) 66f6 (0) 6421 (0)\n002 3 11b5 089f 0d90 | 25 1f15 (0) 1d53 (0) 18b0 (0) 1b61 (0)\n003 1 3547 | 4 39b5 (0) 30c0 (0) 351d (0) 3547 (0)\n004 1 2c3d | 1 2c3d (0)\n005 3 2426 247d 2742 | 3 2426 (0) 247d (0) 2742 (0)\n============ DEPTH: 6 ==========================================\n006 1 22b8 | 1 22b8 (0)\n007 1 20c4 | 1 20c4 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"ISR50auBOVF4CvK8CagRnb9i5gPAXA6iYyliUDb2cIo="}}}},{"node":{"info":{"ip":"0.0.0.0","ports":{"listener":0,"discovery":0},"enode":"enode://a089758c25ca0730f13cd18c10aeea62488c1c2651eef53a8ad11cfdfa61ce8f7354a53bd6902da26b79dfbedc78d315b1d4239eb62cbca59215727b2ac35213@0.0.0.0:0","name":"node122","listenAddr":"","id":"a089758c25ca0730f13cd18c10aeea62488c1c2651eef53a8ad11cfdfa61ce8f7354a53bd6902da26b79dfbedc78d315b1d4239eb62cbca59215727b2ac35213","protocols":{"bzz":"DZAEC50M10IUllQmIZiqjcT8ls/fm4TP6DMnfD4jgx8=","hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 0d9004\npopulation: 12 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 9835 c6ed | 54 b778 (0) b270 (0) b26e (0) b87c (0)\n001 1 41f4 | 38 60cb (0) 62d5 (0) 66f6 (0) 6421 (0)\n002 1 2124 | 11 39b5 (0) 30c0 (0) 351d (0) 3547 (0)\n003 2 165d 11b5 | 14 1f15 (0) 1d53 (0) 18b0 (0) 1b61 (0)\n004 3 0561 07c7 0066 | 7 0066 (0) 00b9 (0) 016e (0) 0104 (0)\n005 1 089f | 1 089f (0)\n============ DEPTH: 6 ==========================================\n006 2 0ef0 0f19 | 2 0ef0 (0) 0f19 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"up":true,"config":{"private_key":"71857ed16ee507ae0dd576370348a196d43274a3895f26fb8659ec79c1ecb79c","id":"a089758c25ca0730f13cd18c10aeea62488c1c2651eef53a8ad11cfdfa61ce8f7354a53bd6902da26b79dfbedc78d315b1d4239eb62cbca59215727b2ac35213","name":"node122","services":["pss","bzz"]}}},{"node":{"config":{"services":["pss","bzz"],"name":"node123","id":"4228ad29aa22f1fa078c7e09f44f85c05d5b797072c10ade24dcbff95c01e554511fe10273a5f25a25ca06ff97bca28c241610f7145983f72ed44969ead4596a","private_key":"3e5c543d406054ba1338ea28c37198eb8153a157eb5a0aecc186dceb04e10632"},"up":true,"info":{"id":"4228ad29aa22f1fa078c7e09f44f85c05d5b797072c10ade24dcbff95c01e554511fe10273a5f25a25ca06ff97bca28c241610f7145983f72ed44969ead4596a","protocols":{"bzz":"QfQHuSsUYrk0AIGaaviBV5e528UFr68BYruup5UgVxY=","hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 41f407\npopulation: 13 (124), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 9d60 | 51 d24a (0) d6e3 (0) d486 (0) cb70 (0)\n001 1 0d90 | 36 39b5 (0) 30c0 (0) 351d (0) 3547 (0)\n002 2 62d5 66f6 | 20 60cb (0) 62d5 (0) 66f6 (0) 6421 (0)\n003 2 5820 5672 | 8 5f1c (0) 5f8e (0) 5958 (0) 580a (0)\n004 1 4a2d | 3 4f7a (0) 4e6e (0) 4a2d (0)\n005 3 4610 459a 45cd | 3 4610 (0) 459a (0) 45cd (0)\n006 1 43d7 | 1 43d7 (0)\n============ DEPTH: 7 ==========================================\n007 1 4067 | 1 4067 (0)\n008 0 | 0\n009 0 | 0\n010 1 41cd | 1 41cd (0)\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","name":"node123","enode":"enode://4228ad29aa22f1fa078c7e09f44f85c05d5b797072c10ade24dcbff95c01e554511fe10273a5f25a25ca06ff97bca28c241610f7145983f72ed44969ead4596a@0.0.0.0:0"}}},{"node":{"info":{"protocols":{"bzz":"VnIG1wvFiZOwhxmv2cAHxWKq2ZQ3WZNWdjt0zUcHCDw=","hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 567206\npopulation: 16 (114), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 efde 9d60 | 43 e22c (0) ede2 (0) ef40 (0) efde (0)\n001 2 30c0 00b9 | 34 39b5 (0) 30c0 (0) 351d (0) 3547 (0)\n002 2 69ba 7a46 | 20 60cb (0) 62d5 (0) 66f6 (0) 6421 (0)\n003 3 4610 459a 41f4 | 10 4f7a (0) 4e6e (0) 4a2d (0) 4610 (0)\n004 5 5f1c 5f8e 5958 580a | 5 5f1c (0) 5f8e (0) 5958 (0) 580a (0)\n============ DEPTH: 5 ==========================================\n005 1 5258 | 1 5258 (0)\n006 0 | 0\n007 1 57d3 | 1 57d3 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"id":"b1bef03357528618be6936a7edae5e3d4ecc942d43bd301642d321a73a07f3327d413f923c3fdd49d04f311e18709a4dde7519722d7a4912f181aa4df2e60173","enode":"enode://b1bef03357528618be6936a7edae5e3d4ecc942d43bd301642d321a73a07f3327d413f923c3fdd49d04f311e18709a4dde7519722d7a4912f181aa4df2e60173@0.0.0.0:0","listenAddr":"","name":"node124","ports":{"listener":0,"discovery":0},"ip":"0.0.0.0"},"config":{"private_key":"3771d716bd74a4be3b8e154d3aa3b2302700b5ca1607923f7414c147a7cf67b7","id":"b1bef03357528618be6936a7edae5e3d4ecc942d43bd301642d321a73a07f3327d413f923c3fdd49d04f311e18709a4dde7519722d7a4912f181aa4df2e60173","name":"node124","services":["pss","bzz"]},"up":true}},{"node":{"config":{"private_key":"25dc939bff90ac541a61b59e0d2b4d3b9891379de3893645f06891c5be0d5695","id":"7ca32d24c001557a81af351ac71322543154eeedbb6ccdd8b8b142f19215aa712218babe9701e73a6441784375a511c1f16a70569b73416f9708409564d18485","name":"node125","services":["pss","bzz"]},"up":true,"info":{"id":"7ca32d24c001557a81af351ac71322543154eeedbb6ccdd8b8b142f19215aa712218babe9701e73a6441784375a511c1f16a70569b73416f9708409564d18485","protocols":{"bzz":"nWC2fXMa7i5qyG0Xyeamqlqu7GtoA7rlxfvAJkP3NYw=","hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 9d60b6\npopulation: 16 (125), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 41f4 5672 2742 | 72 60cb (0) 62d5 (0) 66f6 (0) 6421 (0)\n001 4 f7cd f843 cb70 c6ed | 24 e22c (0) e8d0 (0) e884 (0) ede2 (0)\n002 2 bb9c a20d | 12 b778 (0) b26e (0) b270 (0) b87c (0)\n003 2 8357 869f | 9 88a9 (0) 88dc (0) 8937 (0) 8ff6 (0)\n004 1 9265 | 4 958e (0) 944e (0) 960e (0) 9265 (0)\n============ DEPTH: 5 ==========================================\n005 3 9835 9b24 9a8c | 3 9835 (0) 9b24 (0) 9a8c (0)\n006 0 | 0\n007 0 | 0\n008 1 9dc8 | 1 9dc8 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"enode":"enode://7ca32d24c001557a81af351ac71322543154eeedbb6ccdd8b8b142f19215aa712218babe9701e73a6441784375a511c1f16a70569b73416f9708409564d18485@0.0.0.0:0","name":"node125","listenAddr":""}}},{"node":{"info":{"enode":"enode://ad177f2702ed11d531b11fd0250f2dab2364624680cfb6ff1fba5b27dcd8334269a5bc9093401389044c0b00ed0cbf6f166aba81a58cadd34b25355839fff6ac@0.0.0.0:0","listenAddr":"","name":"node126","ports":{"discovery":0,"listener":0},"ip":"0.0.0.0","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 274211\npopulation: 12 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 9d60 cb70 | 54 b778 (0) b270 (0) b26e (0) b87c (0)\n001 1 6421 | 38 60cb (0) 62d5 (0) 66f6 (0) 6421 (0)\n002 2 1a16 1b61 | 25 1f15 (0) 1d53 (0) 18b0 (0) 1b61 (0)\n003 1 3547 | 4 39b5 (0) 30c0 (0) 351d (0) 3547 (0)\n004 1 2c3d | 1 2c3d (0)\n005 3 22b8 20c4 2124 | 3 22b8 (0) 20c4 (0) 2124 (0)\n============ DEPTH: 6 ==========================================\n006 2 2426 247d | 2 2426 (0) 247d (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"J0IRCZfctpCUaIXlpKqgOfcsn5ICXmLx03GSKs9eJ6c="},"id":"ad177f2702ed11d531b11fd0250f2dab2364624680cfb6ff1fba5b27dcd8334269a5bc9093401389044c0b00ed0cbf6f166aba81a58cadd34b25355839fff6ac"},"up":true,"config":{"name":"node126","services":["pss","bzz"],"private_key":"e6ad803abcef9554bdff08a4f4b6a7a65dc574bf92d32ee882413c9269fd31f3","id":"ad177f2702ed11d531b11fd0250f2dab2364624680cfb6ff1fba5b27dcd8334269a5bc9093401389044c0b00ed0cbf6f166aba81a58cadd34b25355839fff6ac"}}},{"node":{"info":{"protocols":{"bzz":"y3BOJs7/W2E9ghFCM3X+De1NhnvIkolKcNcSifGpwcE=","hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: cb704e\npopulation: 10 (122), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 2742 | 72 60cb (0) 62d5 (0) 66f6 (0) 6421 (0)\n001 2 9d60 a20d | 29 b270 (0) b26e (0) b778 (0) b87c (0)\n002 1 f7cd | 12 e22c (0) e884 (0) ede2 (0) ef40 (0)\n003 2 d24a d486 | 4 d24a (0) d6a2 (0) d6e3 (0) d486 (0)\n004 2 c42f c6ed | 3 c1c1 (0) c42f (0) c6ed (0)\n============ DEPTH: 5 ==========================================\n005 2 ce12 cd94 | 2 ce12 (0) cd94 (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"id":"96f3194c9ef17f60c318be14dd72c51af0aebc19f7a574b769d18b1fda6791409c827892bae3a061800e3d78af88a97635a0a892c54d7ebb38342ab1ba99c3ad","enode":"enode://96f3194c9ef17f60c318be14dd72c51af0aebc19f7a574b769d18b1fda6791409c827892bae3a061800e3d78af88a97635a0a892c54d7ebb38342ab1ba99c3ad@0.0.0.0:0","name":"node127","listenAddr":"","ip":"0.0.0.0","ports":{"discovery":0,"listener":0}},"up":true,"config":{"private_key":"a482a87960aae2e446cd2aeb304e7baeff9a24d2bace4d5f919b5bda00a5f0eb","id":"96f3194c9ef17f60c318be14dd72c51af0aebc19f7a574b769d18b1fda6791409c827892bae3a061800e3d78af88a97635a0a892c54d7ebb38342ab1ba99c3ad","name":"node127","services":["pss","bzz"]}}},{"node":{"info":{"ip":"0.0.0.0","ports":{"listener":0,"discovery":0},"enode":"enode://d6f274a2f20831a1b2281d889f46ad44f1bc5a07bb2152c89e129afb1c1e643b608621791a9d15a28da022d57b8bc3c05a7da0b5a93201dd714179e4a6a29a8b@0.0.0.0:0","name":"node128","listenAddr":"","id":"d6f274a2f20831a1b2281d889f46ad44f1bc5a07bb2152c89e129afb1c1e643b608621791a9d15a28da022d57b8bc3c05a7da0b5a93201dd714179e4a6a29a8b","protocols":{"bzz":"xu39YT8hb0ih6gW+hPqluaad2XxuXXLgvTOepiwbGeE=","hive":"\n=========================================================================\nSat Sep 30 16:27:15 UTC 2017 KΛÐΞMLIΛ hive: queen's address: c6edfd\npopulation: 15 (127), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 2c3d 2124 089f 0d90 | 74 39b5 (0) 30c0 (0) 351d (0) 3547 (0)\n001 3 a20d 9d60 869f | 30 b778 (0) b270 (0) b26e (0) b87c (0)\n002 2 f7cd f843 | 14 e22c (0) e884 (0) e8d0 (0) ede2 (0)\n003 1 d24a | 4 d24a (0) d6a2 (0) d6e3 (0) d486 (0)\n004 3 cd94 ce12 cb70 | 3 ce12 (0) cd94 (0) cb70 (0)\n============ DEPTH: 5 ==========================================\n005 1 c1c1 | 1 c1c1 (0)\n006 1 c42f | 1 c42f (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"up":true,"config":{"name":"node128","services":["pss","bzz"],"private_key":"214126811a121d6fc0443ce66e59372bc72dea9e220ab6e7d6da961741590d47","id":"d6f274a2f20831a1b2281d889f46ad44f1bc5a07bb2152c89e129afb1c1e643b608621791a9d15a28da022d57b8bc3c05a7da0b5a93201dd714179e4a6a29a8b"}}}],"conns":[{"other":"071c094246a0ca4b5d169e43a20ce5da508e579a6e2e822462bd8948ab357d46ab477bcff0c80eba2e01f0c100690b307af40d47c52ebad06783e9e77466cbd6","one":"1545795dca07ecd09c5b16b3bbdddf3dba92e27b532c18a3bc63bc007761ac1b1ebc7ffb4f0a401d5376a4c67923c7949edaebd8f65fff52d6677bb1d6a72f43","up":true},{"up":true,"one":"d2cf35afdb846755290a7c3a1a36758e735a4eeed57b1af66595c55ab45c52cf2c478de3f395b38513cdc9e49568892cce490de93074fa45b640628f0fe40719","other":"8b8c15c6329096267a25d4060ee19963afb6e776fea60d9d566d4e1f9b087581b36e33fc533d7f133668a7a6a22f81a1234ed9fbce26eff1d5e5691a6148d540"},{"other":"f3bf16c7156ce55af92b2fc21826bdfd3e1f245c6087e76f5eb23cc8bbd88b25515a32029d3e6e2b4a27354606e9e3bdfe78788e326c4349d63416894fcfbaf4","one":"c796d4917dd22d9836a9d7d24ba6f89e1a0e8a78a207bd930991e44e9c80ac1de8e4e1a023d550a6dfa60270fbb3935a7e03ef389c1ccda957a4a6a75ef6819b","up":true},{"other":"f8fd12d8b5872b74e2cfa60d6a3a25b568a1fb4be3a8d06faac02a38321f419c443e517c0e2989001635f827add1859a2dc9589a9c0f5bf3804d46f43f799116","up":true,"one":"fb20c708420e60c48fa65980ae11adc8cdf9b56ab93044a9aee9b5196d52f29e6cb2c218f73fefbdaecf8177bae1d9d13dd64bbe06e631555715b93f58f47137"},{"one":"d6794744c5f941cb6dbac4adbbbf11ce83c9224c8a34b9c787ed5975bf0af13e095a7db1c86fcbb7b134ae6dc67467d3ffaf191f4a4d9218779c4d0cf86876ca","up":true,"other":"a5990a680e1f01dcd71a178a239880c5ce24418748c368b8e3c8a1175cfd744d16973cba03e5e756820950920a6d9fa5d5dd53829a1d1d508371cb1042e9453e"},{"one":"bebbde654a4f3e3e65f63d10cbcc89dfd46ce75945c19be33bfe4d954c8ed375981e21a8376ad10e402dddbcf3b657e6786c0820e599a0d1fe03f8d35294d7c7","up":true,"other":"0d85f39dca79f99b277ad5cedfcd3fb1eccc7862c95c215ba0d5a2ec1c4fa80244393d0934cf59fe988f7716bf15cb8e79f4ee03fbe4a48a10cac6e0610f9d55"},{"one":"b949f482891fff7d7d1f0d84112db7080fa1df07cd4e52ee0fadb707a4b7903fc0da9fe45b7ceee37948856687f8e7768945295de15691a99c879f1816899d98","up":true,"other":"c796d4917dd22d9836a9d7d24ba6f89e1a0e8a78a207bd930991e44e9c80ac1de8e4e1a023d550a6dfa60270fbb3935a7e03ef389c1ccda957a4a6a75ef6819b"},{"other":"54b79d3662ba486bbd120313d59ef101acf963eb3d6112a9dda121bc0b52f4b1fbcb13406705cdd8c2d3990ad296171c7972211467cc0d44cbe9ca16fbc82e3e","up":true,"one":"6ba8900830489793a22bf5023cde4ab849dee525d1ca5b95e21040a8e8be5b295317b1c76e09beb7d17a9512137c487b99f16933622b5f2b0e10da3233086bbf"},{"one":"64a39acfb1accea032dfc4d1530b5cdbdc8c1b609a442b68a9b534a539062d051b750a4512b0a9d504fdffa2a5bc8d4fcb6ca59f4ddb1c59ce62e8913644499b","up":true,"other":"236266f9f5a28148d11bed1195a91cd1d30231b082697ee1940a85abca98d2ff0767be9128c23375caa0444bcf51d8501879200ea0f27f13d0ede37f97241325"},{"one":"d6f274a2f20831a1b2281d889f46ad44f1bc5a07bb2152c89e129afb1c1e643b608621791a9d15a28da022d57b8bc3c05a7da0b5a93201dd714179e4a6a29a8b","up":true,"other":"d2cf35afdb846755290a7c3a1a36758e735a4eeed57b1af66595c55ab45c52cf2c478de3f395b38513cdc9e49568892cce490de93074fa45b640628f0fe40719"},{"up":true,"one":"54b79d3662ba486bbd120313d59ef101acf963eb3d6112a9dda121bc0b52f4b1fbcb13406705cdd8c2d3990ad296171c7972211467cc0d44cbe9ca16fbc82e3e","other":"b737c81fe6bc50d977231a5fc8856f064ba58190c5ab5615d3cf634aea8c15a308f3a667aad2e69d5c1438549cd41c863fd40f643b70caf3e0c934276ef2a84f"},{"other":"fa4174ca214905c4136e891e64349f664f166aeeacead6f6e84892ebcadd2c7fbff07052ea4913a9465999f5494962ec29f7f7a3e6cbb993e00d1b881fb31eb1","up":true,"one":"236266f9f5a28148d11bed1195a91cd1d30231b082697ee1940a85abca98d2ff0767be9128c23375caa0444bcf51d8501879200ea0f27f13d0ede37f97241325"},{"other":"4f4201d959e4add3a4bcf3cbaab29d8abcc7530a9834e3cde45c4459ea92fba869e65156037a8fae02eac05f6174a7f2c1d825418f2207caa2284bcc9d9b84d1","one":"a5990a680e1f01dcd71a178a239880c5ce24418748c368b8e3c8a1175cfd744d16973cba03e5e756820950920a6d9fa5d5dd53829a1d1d508371cb1042e9453e","up":true},{"other":"123633b35f455fc3240d99929dc3130bb018545672be151ba973915f2ab6e6c862748f60d917e48ccbf28620c4e58b888867cb51e12ec0d2e5c61cef82258719","one":"09fa1e69f37cb14db3dd721a9c4b9c884f6fe519d850f7af3643ecd536d4b3e995f99acf569e23b7864996c750115ff0ca0bd446ebfd76a026da71da0b95fd97","up":true},{"other":"850e729f9bbb5ef6e12baf7d3dced180839e88e0845baa7aa8fb87dcb417aa74af5999bda81723aabbef5eda842fa4b5fae107fcff9f6bd50597e8ba6a849dff","one":"45c635c4080d47e2f932c27472e487ec95b7644c3d94d8627166a33dca2e3cbaa3305ae2d42e1510bfb0f8329b90e5a31883b399a469ad548fcae3040a8833a0","up":true},{"up":true,"one":"4f4201d959e4add3a4bcf3cbaab29d8abcc7530a9834e3cde45c4459ea92fba869e65156037a8fae02eac05f6174a7f2c1d825418f2207caa2284bcc9d9b84d1","other":"ef3016ea5a7b1b57388904d5c80fd05780d23acec8cf73e8add28ea99c6222fa84e89a1752186a2ef41dd0ec828405e61a1e8fd67d9496d75525ed860b12e2e8"},{"other":"7625a1a0a0f5bf78e2b9fe43a1215ea882318458b886ec767ccbc35e76b543f96820b364342b28ff600302af7716280497141dc2fc84e83cb15f5eb3d268d73e","up":true,"one":"123633b35f455fc3240d99929dc3130bb018545672be151ba973915f2ab6e6c862748f60d917e48ccbf28620c4e58b888867cb51e12ec0d2e5c61cef82258719"},{"one":"f8fd12d8b5872b74e2cfa60d6a3a25b568a1fb4be3a8d06faac02a38321f419c443e517c0e2989001635f827add1859a2dc9589a9c0f5bf3804d46f43f799116","up":true,"other":"193ca2ef8a4ac98c0300d7e48421ba3fe5d4789a0c2b476499bd093808c3988b4a55742ff3f607429cafda08cbbb5fba68da8869747b1b5169f3e4545497de3a"},{"one":"ef3016ea5a7b1b57388904d5c80fd05780d23acec8cf73e8add28ea99c6222fa84e89a1752186a2ef41dd0ec828405e61a1e8fd67d9496d75525ed860b12e2e8","up":true,"other":"f78ecf420b73cd0245807157c0cbaaa568c60c80965413e187b084fb26041761d12790c0cb6a39bc8997fd2b3d3f52c831e601f1f1846945fba1808b0e1cdf25"},{"other":"d6794744c5f941cb6dbac4adbbbf11ce83c9224c8a34b9c787ed5975bf0af13e095a7db1c86fcbb7b134ae6dc67467d3ffaf191f4a4d9218779c4d0cf86876ca","up":true,"one":"4903cd53b3ffc4328547e03dec8f7992edbfb1e1697e53772ef79887984b11595167eb84015ff3dfb26ac0d7b2e98b7a0792bef843d2bdff3a76889fc4a6c60a"},{"other":"3e65bbf7103b3307bd9b8a65168c7c87c3f5283c7c52edefabf4193a1f04ac10216cc485a1dae17cff9ccea41bcf9a0b41de001c6142f30701443dc1735f25c0","up":true,"one":"f78ecf420b73cd0245807157c0cbaaa568c60c80965413e187b084fb26041761d12790c0cb6a39bc8997fd2b3d3f52c831e601f1f1846945fba1808b0e1cdf25"},{"other":"a13086041114db2be31038987ac3fdcaeb99489f1b6ee9b22998b9e66dc2f2f024307d9474811e7e8be1b1acf5a55305d5cce27d87fb834ed1e1d2e17319bb85","one":"f4ae36400caeddcbcf0fb1abd5b9611c37bac683645d10c69a1ac54d366f730c59917c95e990a0fa6bb2679c98fb62bf0e29bd7812ab57375de35f469dab98a0","up":true},{"one":"3e65bbf7103b3307bd9b8a65168c7c87c3f5283c7c52edefabf4193a1f04ac10216cc485a1dae17cff9ccea41bcf9a0b41de001c6142f30701443dc1735f25c0","up":true,"other":"eeb9d718ef61c14e10ab2fb3a90b039368acd17a59f70628deb39515c227bd0916c796cd7767b1a9d4f38e04f1013173b21c1fa2e0206ecdc72df6c2621380a2"},{"other":"57fb9e7f287fe67500b8b560475c0d0d6eae9d623d5a8c85eb5459f209904a839a0b24ff99a1643a4196a71d45f2ed1bd5e08f9a13cdd9749a907a024ff984dc","up":true,"one":"eeb9d718ef61c14e10ab2fb3a90b039368acd17a59f70628deb39515c227bd0916c796cd7767b1a9d4f38e04f1013173b21c1fa2e0206ecdc72df6c2621380a2"},{"up":true,"one":"57fb9e7f287fe67500b8b560475c0d0d6eae9d623d5a8c85eb5459f209904a839a0b24ff99a1643a4196a71d45f2ed1bd5e08f9a13cdd9749a907a024ff984dc","other":"af6cb988ddb16202459735b8489c02b3bf829ca301513a0d3e18bbb03d43c8de3cda767c7b5c984a6dce3f118c8089e06b08ed3bd0c922dde9cfe775609df3b2"},{"one":"af6cb988ddb16202459735b8489c02b3bf829ca301513a0d3e18bbb03d43c8de3cda767c7b5c984a6dce3f118c8089e06b08ed3bd0c922dde9cfe775609df3b2","up":true,"other":"55beb7853107501c013283d0114f9812c2e97b292f90ae9bdd5aa8189d0379a758cbf19c5fa62436bc75a6e30d935a3bd52025b06efd167fa2fb8a1caead2f83"},{"other":"41ded7596eac3eddfd1f7656ef23adabe1d18027f6159e45867e935d1ab742ec298ba2b23df522f79f59c7805510d8c995837380432dee37912d6ede1196caa2","one":"55beb7853107501c013283d0114f9812c2e97b292f90ae9bdd5aa8189d0379a758cbf19c5fa62436bc75a6e30d935a3bd52025b06efd167fa2fb8a1caead2f83","up":true},{"other":"464cf4c4203246240a63965062b9e5a7e5fa903f127b1f5ea5b37a27d33d8b12768fc2d8f257e67418f1e5765e627ca8f8cd5ba6b15b8a047490d26ce43e6291","up":true,"one":"41ded7596eac3eddfd1f7656ef23adabe1d18027f6159e45867e935d1ab742ec298ba2b23df522f79f59c7805510d8c995837380432dee37912d6ede1196caa2"},{"one":"464cf4c4203246240a63965062b9e5a7e5fa903f127b1f5ea5b37a27d33d8b12768fc2d8f257e67418f1e5765e627ca8f8cd5ba6b15b8a047490d26ce43e6291","up":true,"other":"de7ab7b9a2ba4ed523b84233fae11d93815579976ea78b385c658a4c156622747051f91342f9ac3610e22ee259b65e02b5af0ab67a9ee04ab6958a9d0d8acdf1"},{"one":"de7ab7b9a2ba4ed523b84233fae11d93815579976ea78b385c658a4c156622747051f91342f9ac3610e22ee259b65e02b5af0ab67a9ee04ab6958a9d0d8acdf1","up":true,"other":"69f3f9fafff951dca2fe98baa178e53f2779311a93fdc364cf4c2477700c8dbce7e4201c3aa6d840b5ae65e8fc9d6603cbc41dbdf601f1998caedee1b542d72b"},{"one":"69f3f9fafff951dca2fe98baa178e53f2779311a93fdc364cf4c2477700c8dbce7e4201c3aa6d840b5ae65e8fc9d6603cbc41dbdf601f1998caedee1b542d72b","up":true,"other":"dee5fb5ccdfe3803cab3e0041c5c4879001bf2c2233446f47245d8234642046269bfe50e414cd2d89341e338597f2ecbb7b2912c20558a85041b757a24490805"},{"up":true,"one":"dee5fb5ccdfe3803cab3e0041c5c4879001bf2c2233446f47245d8234642046269bfe50e414cd2d89341e338597f2ecbb7b2912c20558a85041b757a24490805","other":"3dcf5ec3ebb3b7de61dfaef4ee397a4a13a96ee40673be2eaadfcadd11f139c594c74237b40dd9c10f059f40d325c014f5b02b3a8eb7f0dc7d66ced7fea9f17f"},{"other":"c708e3584cd9450b30d8cdd960a676884f64364c2aec985eebb4a0d745f6c73b6b0cb16f330bf090320bc48a5a67e8519b3c2c4a64cf2eff9aa4f1fc0b274a00","one":"3dcf5ec3ebb3b7de61dfaef4ee397a4a13a96ee40673be2eaadfcadd11f139c594c74237b40dd9c10f059f40d325c014f5b02b3a8eb7f0dc7d66ced7fea9f17f","up":true},{"up":true,"one":"c708e3584cd9450b30d8cdd960a676884f64364c2aec985eebb4a0d745f6c73b6b0cb16f330bf090320bc48a5a67e8519b3c2c4a64cf2eff9aa4f1fc0b274a00","other":"a302bebe4590b3f6d2c511919ceef4a5a80d431f53f8f3483c4b833a6a3b5f79b4c66c0ce2c0e5bc696534067ea5cd07772a9844ee0ba9d37a2e6f5d4bfb05cd"},{"other":"a4dd67ab4fff1a50968c7ab59c304eb0083b072fc13dff599eeadac4e0e75099f7c825f91dd1bb770f3ae6f3d1d82ad574d6ecb117adf1ca9ccbccd01303ec7c","one":"a302bebe4590b3f6d2c511919ceef4a5a80d431f53f8f3483c4b833a6a3b5f79b4c66c0ce2c0e5bc696534067ea5cd07772a9844ee0ba9d37a2e6f5d4bfb05cd","up":true},{"one":"a4dd67ab4fff1a50968c7ab59c304eb0083b072fc13dff599eeadac4e0e75099f7c825f91dd1bb770f3ae6f3d1d82ad574d6ecb117adf1ca9ccbccd01303ec7c","up":true,"other":"604a11bd1d969886953398ecc1fdf5847a946a8118014d0cb8daff9943f4f78c4bdbad3ee4152959c8265d0588dea658c262fe2f99a55a0b32321b81c8eec473"},{"other":"946b3f821a4b61661e8ace52f4ade415042fddf058d97a16f08d9eff7a0be633de47c27fa9760ff38d583b2405163d4a27d3a7949d4015271396c014043a34e3","up":true,"one":"604a11bd1d969886953398ecc1fdf5847a946a8118014d0cb8daff9943f4f78c4bdbad3ee4152959c8265d0588dea658c262fe2f99a55a0b32321b81c8eec473"},{"up":true,"one":"946b3f821a4b61661e8ace52f4ade415042fddf058d97a16f08d9eff7a0be633de47c27fa9760ff38d583b2405163d4a27d3a7949d4015271396c014043a34e3","other":"c677530a47ef470ae0811127b91c231ec8889588bd096c24a54cc48099e8edde811f4a72eedc79118acb494ef031d6adcef1595d1a17df71b25b468478e931ff"},{"other":"5a27b90639d515cad7794dae78bf9a9866cca23c5e3e18870524d148797ba1bdfd631151f23062d4dcf0961a7dba709431a44e39da29ed5ea4b0b6987514e433","up":true,"one":"c677530a47ef470ae0811127b91c231ec8889588bd096c24a54cc48099e8edde811f4a72eedc79118acb494ef031d6adcef1595d1a17df71b25b468478e931ff"},{"up":true,"one":"5a27b90639d515cad7794dae78bf9a9866cca23c5e3e18870524d148797ba1bdfd631151f23062d4dcf0961a7dba709431a44e39da29ed5ea4b0b6987514e433","other":"0c000879be78fc867857011e396e2dd77bc2a0c6c2c3624d98b102737aa8d998ca9081653c0c8285117a5288b1bfeed06c54b2f6e39225aca4a21ff2a72116e1"},{"one":"0c000879be78fc867857011e396e2dd77bc2a0c6c2c3624d98b102737aa8d998ca9081653c0c8285117a5288b1bfeed06c54b2f6e39225aca4a21ff2a72116e1","up":true,"other":"223d79f656e3f124ee1238ca46e42c2a0d8500ee58a37312c6b72657a11ad9ebce3be4c061611b913a22863f6e7936ff37602dedc7856baea27e8201db44bbf4"},{"up":true,"one":"223d79f656e3f124ee1238ca46e42c2a0d8500ee58a37312c6b72657a11ad9ebce3be4c061611b913a22863f6e7936ff37602dedc7856baea27e8201db44bbf4","other":"972b7f6c5b926b93a9b005bb8a891c29e535a465c586bcd4258d4094e320925a179e8f63478917f8a88d1911fe8f868013abeb34817832ed4b0b209ce392f20b"},{"other":"c49e963a92b93a1c48fd3e38c127bfc88fbcb15b57bfdf8615c0e591b24276d4fe153a811932aefdcf3dee494d53ce354ba052c24313a725d562c6e807ab9133","up":true,"one":"972b7f6c5b926b93a9b005bb8a891c29e535a465c586bcd4258d4094e320925a179e8f63478917f8a88d1911fe8f868013abeb34817832ed4b0b209ce392f20b"},{"up":true,"one":"c49e963a92b93a1c48fd3e38c127bfc88fbcb15b57bfdf8615c0e591b24276d4fe153a811932aefdcf3dee494d53ce354ba052c24313a725d562c6e807ab9133","other":"a16326a0c540731e0964c4bc10c1342346fcfee70c7d1d8d333cbb774cb9f49dbf92585595654c99253eac21373706247bf5ef1ba40ac03e62da00821991cf7d"},{"one":"a16326a0c540731e0964c4bc10c1342346fcfee70c7d1d8d333cbb774cb9f49dbf92585595654c99253eac21373706247bf5ef1ba40ac03e62da00821991cf7d","up":true,"other":"c7566a0efd78ba35ad27a51a7ec8fcd55944ae12f9933573e71e2ad7404d48037dad9063c10ce5af636d7641a03899333d01aa9be94716d2179fdb2af33f36c4"},{"up":true,"one":"c7566a0efd78ba35ad27a51a7ec8fcd55944ae12f9933573e71e2ad7404d48037dad9063c10ce5af636d7641a03899333d01aa9be94716d2179fdb2af33f36c4","other":"334b59c2767fc786551dfdc0a9fcd6f5b53cbe48ddc1ca61b84f8155a15de7e8cd44cbb3a537e1aa7f11416eb710c5de916a5e8ce24e83bfa570b7344c5873ea"},{"other":"66652e041752f4acb27bc45c9c8b58f4f4ea904345a887a49ae831bef3bb1ad26cff7fd0f66ef3c28d6c41e039e39ff983710fdd5384f849595a66e5509e0d10","up":true,"one":"334b59c2767fc786551dfdc0a9fcd6f5b53cbe48ddc1ca61b84f8155a15de7e8cd44cbb3a537e1aa7f11416eb710c5de916a5e8ce24e83bfa570b7344c5873ea"},{"other":"9158b9eb87bf7d011f83febca8f9d6575dd05be1f7e7bc18336f802651a379dd181a0503b5a8e46a580c59889998b16275f1e0ce4dce965cdbe72265ad2be283","one":"66652e041752f4acb27bc45c9c8b58f4f4ea904345a887a49ae831bef3bb1ad26cff7fd0f66ef3c28d6c41e039e39ff983710fdd5384f849595a66e5509e0d10","up":true},{"other":"fb20c708420e60c48fa65980ae11adc8cdf9b56ab93044a9aee9b5196d52f29e6cb2c218f73fefbdaecf8177bae1d9d13dd64bbe06e631555715b93f58f47137","up":true,"one":"f3bf16c7156ce55af92b2fc21826bdfd3e1f245c6087e76f5eb23cc8bbd88b25515a32029d3e6e2b4a27354606e9e3bdfe78788e326c4349d63416894fcfbaf4"},{"other":"9ad5ec0e729f9db10b7028788b58ef13d54bd11529b494a549d0415b90777b63fe78a752356315f5abbd24d849edc0c8bfe9d82c05460c30f4dad860ff5fea48","one":"9158b9eb87bf7d011f83febca8f9d6575dd05be1f7e7bc18336f802651a379dd181a0503b5a8e46a580c59889998b16275f1e0ce4dce965cdbe72265ad2be283","up":true},{"up":true,"one":"9ad5ec0e729f9db10b7028788b58ef13d54bd11529b494a549d0415b90777b63fe78a752356315f5abbd24d849edc0c8bfe9d82c05460c30f4dad860ff5fea48","other":"cf03d32d3cca446e7016e7f41267a257bef7142c4f1e4ce2e17678856d75e9889e21972fd21583297a47a156543af15400444dcf37aca64543f97f73734f7f0f"},{"other":"aa108a30f86b8296b416ea9fd6bc7a21c65c7cd3911ca3d4ee79325912d80db7150c02d304e49c5d0feafbd222edd6d522661a0983f1d427981760712f31e6f1","up":true,"one":"cf03d32d3cca446e7016e7f41267a257bef7142c4f1e4ce2e17678856d75e9889e21972fd21583297a47a156543af15400444dcf37aca64543f97f73734f7f0f"},{"other":"540598224dccc717053f94e915652df499f513dc0c8874ce999040e1aa829c33ede284c72ddd0b24a319821102fa42aaaaa87380e777b5878455de61f5fc2ac9","up":true,"one":"aa108a30f86b8296b416ea9fd6bc7a21c65c7cd3911ca3d4ee79325912d80db7150c02d304e49c5d0feafbd222edd6d522661a0983f1d427981760712f31e6f1"},{"other":"cc94ed069ddcc24dc2733eed5ba8367a2521a5955c7287c5280c71675b9965ee8499454b227a4ddc64a14d74b39916211763ddf0b7ad80a52381cc61dcb6c72c","one":"826500ca53a2aed90da0cc3778cbc41af3de0139b246f30c3be65582b1f152928dfa3280760da4dcd8098f41f529a088dba24bc5d0c71322ef69f4b101f0224a","up":true},{"other":"f87c2dea026ba5e6cda9a446821bf057d3453fa8c9b38fd882a09979ff3cfe2b8adfcbd5cf28d268776414bd12a9aba385d5c97c76a29c1b0625b101faac761d","up":true,"one":"193ca2ef8a4ac98c0300d7e48421ba3fe5d4789a0c2b476499bd093808c3988b4a55742ff3f607429cafda08cbbb5fba68da8869747b1b5169f3e4545497de3a"},{"other":"a1b07c24605e258db7b8fb15db227596b08dc69bb234c0a48c312eb6eb1fb08553f8c8a6da7175eea258e2d3f2625a540c1466e6c31315aa1484fa173b7a8cfc","up":true,"one":"5c1e9692b731421d6eaca488e8ba4cfdda1933ac5f1504ece684fadbea07a7c8053feb73be7ce20aedeaecc84f14d836b5ed2a657df6ca04f4fc82c2da0c0d46"},{"one":"a1b07c24605e258db7b8fb15db227596b08dc69bb234c0a48c312eb6eb1fb08553f8c8a6da7175eea258e2d3f2625a540c1466e6c31315aa1484fa173b7a8cfc","up":true,"other":"af761f8d13059f1e49d2f5c0b7a76a5eb5bcaab1e7ff01673dff3967d81bd7aebf74afef3934328034c82f131fa066de71816cff8f720e0c56d5e85b233a8a44"},{"up":true,"one":"af761f8d13059f1e49d2f5c0b7a76a5eb5bcaab1e7ff01673dff3967d81bd7aebf74afef3934328034c82f131fa066de71816cff8f720e0c56d5e85b233a8a44","other":"0e07d2eb15905a583532383cef08b0881878c5043c4d7bae2cf1cace9954bfbbfbe0c1e8322eabbc84bc94cda08ae9b70cbdc56a1b8a19f807bcd5ca7939669d"},{"other":"53031cddf4390ba176d638456016028bd4538879c7eaba672c3ef70208319a14e6a41dea8ff003b6f7e9b4a83ca12dab50d4f44f079153bec7c24221e311573e","one":"0e07d2eb15905a583532383cef08b0881878c5043c4d7bae2cf1cace9954bfbbfbe0c1e8322eabbc84bc94cda08ae9b70cbdc56a1b8a19f807bcd5ca7939669d","up":true},{"other":"2a0fa7932768f0c316b478d15db556626def18462c3bee9446ff16c48fc43b6be1694a5783602b60250e33adc705b86fae7baa6b829146251995fd47980ce422","up":true,"one":"53031cddf4390ba176d638456016028bd4538879c7eaba672c3ef70208319a14e6a41dea8ff003b6f7e9b4a83ca12dab50d4f44f079153bec7c24221e311573e"},{"one":"2a0fa7932768f0c316b478d15db556626def18462c3bee9446ff16c48fc43b6be1694a5783602b60250e33adc705b86fae7baa6b829146251995fd47980ce422","up":true,"other":"7e9a81d06e997a691cc7790d358868b8657db608795ef6b85bb194db7f56ab5c76cac3be0b40d847ce873aeef4bdad40b725d69f4c42755b9d5aab4fe7aecb34"},{"one":"7e9a81d06e997a691cc7790d358868b8657db608795ef6b85bb194db7f56ab5c76cac3be0b40d847ce873aeef4bdad40b725d69f4c42755b9d5aab4fe7aecb34","up":true,"other":"e20a90f36eca4329d3d2dbadf530949889dc20b0ae5d96b935af9b60d26ec507e9eb1b73fd2b4dc88057c20e4ef6e7039cc49652d35c563db64f06f979e28540"},{"up":true,"one":"e20a90f36eca4329d3d2dbadf530949889dc20b0ae5d96b935af9b60d26ec507e9eb1b73fd2b4dc88057c20e4ef6e7039cc49652d35c563db64f06f979e28540","other":"1cc62520c0d9c6a47d96e485bdc6a5d0f7319477ad6d177663f7b49217f5a8e56e4717f36fb5aa11c5270d4383cab460219821bcc6c9cbcccc4a97446b406d96"},{"up":true,"one":"1cc62520c0d9c6a47d96e485bdc6a5d0f7319477ad6d177663f7b49217f5a8e56e4717f36fb5aa11c5270d4383cab460219821bcc6c9cbcccc4a97446b406d96","other":"c133cd3ee228f427410357f46752d33ecf302475314411772df3532669a8b220136c09f00717460c39bcea1058cb988dd223875ec991612876b400556f5937dd"},{"one":"c133cd3ee228f427410357f46752d33ecf302475314411772df3532669a8b220136c09f00717460c39bcea1058cb988dd223875ec991612876b400556f5937dd","up":true,"other":"c4dfcf348694971fb36ed91e9024302bec8df3891540cbe1f5df26eee9c1f81a95295f05b90ec30dd044a0355dcaa805b9f50e95f38e5588a929cfe10e8cd73d"},{"up":true,"one":"c4dfcf348694971fb36ed91e9024302bec8df3891540cbe1f5df26eee9c1f81a95295f05b90ec30dd044a0355dcaa805b9f50e95f38e5588a929cfe10e8cd73d","other":"e2956a828cb1ff85ab55bdbe329f530662558cb8013ffddacac8ba36096abea07ecb15b54896dd9b4bb0b15155654dbda0c031f69290f2314ac0e376bebbd864"},{"one":"e2956a828cb1ff85ab55bdbe329f530662558cb8013ffddacac8ba36096abea07ecb15b54896dd9b4bb0b15155654dbda0c031f69290f2314ac0e376bebbd864","up":true,"other":"854ff45571c01cd49d0932bcb361eef13202ababf48f0b8e5d8143dc41e01609aa1539e926bad9b4ca8add023fd259eb70239103d75b0a404bb338f3e4bf9577"},{"other":"b440e8bc7d39b8cf9cca03b343c83ba8dd673062cead7bbfce6ed77ea16fa61f0b81df31fc418f4c133d1bb104939ac1b6e5f5a76fbcf50141a1ea33dfeb86e5","up":true,"one":"854ff45571c01cd49d0932bcb361eef13202ababf48f0b8e5d8143dc41e01609aa1539e926bad9b4ca8add023fd259eb70239103d75b0a404bb338f3e4bf9577"},{"other":"e0cacf6abdbfd9a25b9f974600662d4eae484efcdefd0a2a8fbc799127b6fabf2f471aff89c3a08e93ea20be1c304320598ba20a13697a356bf065292ba16bc1","up":true,"one":"b440e8bc7d39b8cf9cca03b343c83ba8dd673062cead7bbfce6ed77ea16fa61f0b81df31fc418f4c133d1bb104939ac1b6e5f5a76fbcf50141a1ea33dfeb86e5"},{"other":"82f0cbb87a76dea7947c2c1b6506d05390e5c5e969e5e91651ca10d36cd6aaea72967435ea7e5222d28f1d5e64cc526075d264712e55593bc3b609c93d4fe1eb","one":"e0cacf6abdbfd9a25b9f974600662d4eae484efcdefd0a2a8fbc799127b6fabf2f471aff89c3a08e93ea20be1c304320598ba20a13697a356bf065292ba16bc1","up":true},{"one":"82f0cbb87a76dea7947c2c1b6506d05390e5c5e969e5e91651ca10d36cd6aaea72967435ea7e5222d28f1d5e64cc526075d264712e55593bc3b609c93d4fe1eb","up":true,"other":"57533c56642895edba91473a966b6abf765725a721dec947e4bac4728dfbed265435aefca55fff69cae48c9d506064fbb890665a0acd87c466707d08d1e6e1f4"},{"one":"57533c56642895edba91473a966b6abf765725a721dec947e4bac4728dfbed265435aefca55fff69cae48c9d506064fbb890665a0acd87c466707d08d1e6e1f4","up":true,"other":"9b3fecfc63256a9d69e75ccb5119b2866e30fa4516b3a3bf5b2f03f04f1d20de786ddb90fa2acadb2a0509503b21fc9d16238c57f9b102ceedb6b27ee1b2c4ea"},{"other":"932e926c54a4127210a15731fa4ad6bbfd0d69183b894b676920843f154ad1e4148b674d234f070e9dc07547394a5af973befe0fc170bbe44346d69e135e0157","up":true,"one":"9b3fecfc63256a9d69e75ccb5119b2866e30fa4516b3a3bf5b2f03f04f1d20de786ddb90fa2acadb2a0509503b21fc9d16238c57f9b102ceedb6b27ee1b2c4ea"},{"other":"3bf838b4d29d9388a24d160eee6bf8ea017af6cd9e5f7d88b4cae71ebfbc304666d3d634a05e0a75570dafe8f41871090fcff8b651a9130d013786dfcca3da14","up":true,"one":"932e926c54a4127210a15731fa4ad6bbfd0d69183b894b676920843f154ad1e4148b674d234f070e9dc07547394a5af973befe0fc170bbe44346d69e135e0157"},{"other":"6d3bd11f2f7fe855188423bc49be111cd13defeb78a76eb26d415bfc0c86b89e90724db54a12ae7e0c76b9eb12eb456fc50668697245fca00f9ec3c6fb9c8588","one":"3bf838b4d29d9388a24d160eee6bf8ea017af6cd9e5f7d88b4cae71ebfbc304666d3d634a05e0a75570dafe8f41871090fcff8b651a9130d013786dfcca3da14","up":true},{"up":true,"one":"6d3bd11f2f7fe855188423bc49be111cd13defeb78a76eb26d415bfc0c86b89e90724db54a12ae7e0c76b9eb12eb456fc50668697245fca00f9ec3c6fb9c8588","other":"faa3c31521c8f7b9d15838750e7e311eb0f01db5ef22cd1bf62a7d72e7efdf5a575550c930d96230edc892d107d4551e95b099d3c952a7f1c0ad3b5967c7831b"},{"other":"467a76ed18ca4f195c6a5b0ac277dfd0916657e047fea073db8e28bb59098bd8960c90efe8f59d6c275ff72d18b217d225f6698e56c05e33734a0fd6ea570589","up":true,"one":"faa3c31521c8f7b9d15838750e7e311eb0f01db5ef22cd1bf62a7d72e7efdf5a575550c930d96230edc892d107d4551e95b099d3c952a7f1c0ad3b5967c7831b"},{"other":"f2ac738fa932c90a45d1a64e4a52fd9c4037e2d89ceef1584efef04689bc7aff3a9635fb78dfdf3480d003daf14359190b1cfa8335db438a54107d4060ed58f9","up":true,"one":"467a76ed18ca4f195c6a5b0ac277dfd0916657e047fea073db8e28bb59098bd8960c90efe8f59d6c275ff72d18b217d225f6698e56c05e33734a0fd6ea570589"},{"other":"5a59a44ba2bf5e77f921216ac467733c8529b06790efb05a63c410060edaf65547a2dbb37333073e3bcf68d422ba4b135432307f90394c6edd6dd33dd6ff2152","one":"f2ac738fa932c90a45d1a64e4a52fd9c4037e2d89ceef1584efef04689bc7aff3a9635fb78dfdf3480d003daf14359190b1cfa8335db438a54107d4060ed58f9","up":true},{"other":"ac6057677fdfc132ea2418ff877357962771db049d169ba2c1923b15820385c6bf2f5846943d44a73bfdeb44a1e0d68307003a06cb0f694705879f8a720c3296","one":"5a59a44ba2bf5e77f921216ac467733c8529b06790efb05a63c410060edaf65547a2dbb37333073e3bcf68d422ba4b135432307f90394c6edd6dd33dd6ff2152","up":true},{"other":"ed3a5d7602b59bd8709ef10cb84e4b5644a69490d1173a8b9135adba04b36c1fcd0f16543de39deff0e76d8314e6884ba939213f77abb8d50a68d030352cb495","up":true,"one":"ac6057677fdfc132ea2418ff877357962771db049d169ba2c1923b15820385c6bf2f5846943d44a73bfdeb44a1e0d68307003a06cb0f694705879f8a720c3296"},{"other":"255939ef32bd3e5e76181763c11707b9ff4ab26d3ffb10f06fa7249b06721fa3decfa9eee3eeb8b12d6218af5f9ed8872d62c42a90cd46dcbef3d89a8163ae07","one":"ed3a5d7602b59bd8709ef10cb84e4b5644a69490d1173a8b9135adba04b36c1fcd0f16543de39deff0e76d8314e6884ba939213f77abb8d50a68d030352cb495","up":true},{"other":"a8b619f75e0e4cf7bc5e425ff9b03e55b7301fec4fb58f321bf89811678268d9f738bbf22ee36c2d14ff71a08d6f7dca28249ff6f943cc5a77653f482254d150","up":true,"one":"255939ef32bd3e5e76181763c11707b9ff4ab26d3ffb10f06fa7249b06721fa3decfa9eee3eeb8b12d6218af5f9ed8872d62c42a90cd46dcbef3d89a8163ae07"},{"other":"eb6fa7d39fcee5a7081813169ae24ee6d355cfe717dcb2fa500a07c935ffbe1b12378ea13454742bf7c2df10ad2fd4e53476068eaef4669381c8cd060c199e11","one":"a8b619f75e0e4cf7bc5e425ff9b03e55b7301fec4fb58f321bf89811678268d9f738bbf22ee36c2d14ff71a08d6f7dca28249ff6f943cc5a77653f482254d150","up":true},{"one":"eb6fa7d39fcee5a7081813169ae24ee6d355cfe717dcb2fa500a07c935ffbe1b12378ea13454742bf7c2df10ad2fd4e53476068eaef4669381c8cd060c199e11","up":true,"other":"49bd2289f479c9ad7e0d13319271b9be1e1dcbee28313513a124dec55f9842db639e62a74a83040930c537739ab7fa1e50bb05b9ab0f588d6da7b64a6451f466"},{"other":"06a8a25c6dd90e230237b06c086f14e539b31b8e3705752d0ad8faf1bd7239547332604b79b6124cbd0cee495b99a80f147983142b7271841d8d9fa85d559301","up":true,"one":"49bd2289f479c9ad7e0d13319271b9be1e1dcbee28313513a124dec55f9842db639e62a74a83040930c537739ab7fa1e50bb05b9ab0f588d6da7b64a6451f466"},{"up":true,"one":"06a8a25c6dd90e230237b06c086f14e539b31b8e3705752d0ad8faf1bd7239547332604b79b6124cbd0cee495b99a80f147983142b7271841d8d9fa85d559301","other":"fd321c630fadcc8d6b00589323f7313ac1e94effbe8192955da5f88dcf419ef28820075e0e81c595561ff6ee58cfce23079407edf8b1611cb994946bcbd26364"},{"other":"7172a86afb608acd9a3e1e5c0472489ebecb516cad6796fa9a06ab47cc8e8cce12dddce72f0ac3b0927602bd22ed5872c3b5ce9b6af96f8e9d1d75078cc9bb55","one":"fd321c630fadcc8d6b00589323f7313ac1e94effbe8192955da5f88dcf419ef28820075e0e81c595561ff6ee58cfce23079407edf8b1611cb994946bcbd26364","up":true},{"other":"a2719942ffb6e99bda131cdedb612785dafdf72f5f35824343ad39d8568d6cd25e44b585a915c8e9ea2b02e6fd38c105bb17ed27c8fa320f18c83e0ace78feb5","up":true,"one":"7172a86afb608acd9a3e1e5c0472489ebecb516cad6796fa9a06ab47cc8e8cce12dddce72f0ac3b0927602bd22ed5872c3b5ce9b6af96f8e9d1d75078cc9bb55"},{"other":"e706876f36646bfb2dfbd11669a4907432660023a13be9de329a03f6c6e88e3788002b83d0cb4617e6c4096998783925be5b1de4f0edd8128e7d71312fb1091d","one":"a2719942ffb6e99bda131cdedb612785dafdf72f5f35824343ad39d8568d6cd25e44b585a915c8e9ea2b02e6fd38c105bb17ed27c8fa320f18c83e0ace78feb5","up":true},{"other":"cc0d13dba120558dc8e2d0e5ac755a712e7e7e6dab6edcaf658faf02537b1efe3d6c54d6e67566eb4a3a8f8a019702aa7ee2b33ee3f0316a01e7b17845032e70","up":true,"one":"e706876f36646bfb2dfbd11669a4907432660023a13be9de329a03f6c6e88e3788002b83d0cb4617e6c4096998783925be5b1de4f0edd8128e7d71312fb1091d"},{"up":true,"one":"cc0d13dba120558dc8e2d0e5ac755a712e7e7e6dab6edcaf658faf02537b1efe3d6c54d6e67566eb4a3a8f8a019702aa7ee2b33ee3f0316a01e7b17845032e70","other":"e3779b202b9cfe7b2f2cc9e95974ac77bf51ba951f775acc10f07249ee6b3b260f2b012bb010a7f9794c5562e9b00f18b52c25c1e350ab70afc6bf9e210e4969"},{"up":true,"one":"e3779b202b9cfe7b2f2cc9e95974ac77bf51ba951f775acc10f07249ee6b3b260f2b012bb010a7f9794c5562e9b00f18b52c25c1e350ab70afc6bf9e210e4969","other":"f394aaa6d14c6ed95e2ad4651b5103bb1ab9f3a61839936cc1f08d6a6e53504e5d15dfc5211539ffdbdc64912ded5c2272d4af52ed8d7fe5a3c228eb12f0c68b"},{"other":"38469be067f9bba869fdfcc950843e00b5ff950778c11445787501d47cbaf60e9940735a5b8b71d48a0aaee75c8263137169d51944638dc5d1cad398d22439ed","one":"f394aaa6d14c6ed95e2ad4651b5103bb1ab9f3a61839936cc1f08d6a6e53504e5d15dfc5211539ffdbdc64912ded5c2272d4af52ed8d7fe5a3c228eb12f0c68b","up":true},{"other":"81df6add458aaaaf51a3ad8826250f3498f06586264f95cd7fce642ac08bd583f463a7531e292175f90887013ba39f8757c21eb5524ec62ec413b82badae935a","one":"38469be067f9bba869fdfcc950843e00b5ff950778c11445787501d47cbaf60e9940735a5b8b71d48a0aaee75c8263137169d51944638dc5d1cad398d22439ed","up":true},{"up":true,"one":"81df6add458aaaaf51a3ad8826250f3498f06586264f95cd7fce642ac08bd583f463a7531e292175f90887013ba39f8757c21eb5524ec62ec413b82badae935a","other":"e90ca22b959d482861c52e9e51fd2d63557453dce64dab9f66fcf323273c12e7189358f85d500f5200ff7c7b2d57afe72577ed9aa2adb36fc0c8e5504588fe94"},{"other":"84379884f012e2cfc1f9838312640576c9ded01ca53cf8451f94915e6949f0084047a2555a5fef4d1b0eef62ad5504a34ff631fbb658b011a07a82a53173f5c1","one":"e90ca22b959d482861c52e9e51fd2d63557453dce64dab9f66fcf323273c12e7189358f85d500f5200ff7c7b2d57afe72577ed9aa2adb36fc0c8e5504588fe94","up":true},{"other":"11170a0fb9f6b037f8ee4494e935a84b06816ff5c44ef9d613920f9c58f8b25611b2093da3fb51a59687db6a9b0a070386cac09757a27f75754cbdcb9afc2225","up":true,"one":"84379884f012e2cfc1f9838312640576c9ded01ca53cf8451f94915e6949f0084047a2555a5fef4d1b0eef62ad5504a34ff631fbb658b011a07a82a53173f5c1"},{"up":true,"one":"11170a0fb9f6b037f8ee4494e935a84b06816ff5c44ef9d613920f9c58f8b25611b2093da3fb51a59687db6a9b0a070386cac09757a27f75754cbdcb9afc2225","other":"ab3a3ad0481a80b91132cc6afeaab9c9f5e931885d979176e8e6c181d997c38b488e5eca475b0f8e949a8cf128695e18a5851091394d0a33cf834ce7e3537ac2"},{"other":"6070dc131e9721a4a496b3ed6ff5c9db1a5351e942ed424b86fe6be940d1012df766afb4b0112452dfd63e0fcfea13658324a9ef4a94b5754ec9f6219e4b0d67","up":true,"one":"ab3a3ad0481a80b91132cc6afeaab9c9f5e931885d979176e8e6c181d997c38b488e5eca475b0f8e949a8cf128695e18a5851091394d0a33cf834ce7e3537ac2"},{"other":"0bf28b481d71062ee100d6cb04c8b4234a574f8657e2d3c49b60a9ecdbf486d0ec38b33bce745c8efe820145d5c53ea802aa64b4f9bce19b029ee5b2f9de43f1","up":true,"one":"6070dc131e9721a4a496b3ed6ff5c9db1a5351e942ed424b86fe6be940d1012df766afb4b0112452dfd63e0fcfea13658324a9ef4a94b5754ec9f6219e4b0d67"},{"other":"09fa1e69f37cb14db3dd721a9c4b9c884f6fe519d850f7af3643ecd536d4b3e995f99acf569e23b7864996c750115ff0ca0bd446ebfd76a026da71da0b95fd97","one":"b737c81fe6bc50d977231a5fc8856f064ba58190c5ab5615d3cf634aea8c15a308f3a667aad2e69d5c1438549cd41c863fd40f643b70caf3e0c934276ef2a84f","up":true},{"one":"0bf28b481d71062ee100d6cb04c8b4234a574f8657e2d3c49b60a9ecdbf486d0ec38b33bce745c8efe820145d5c53ea802aa64b4f9bce19b029ee5b2f9de43f1","up":true,"other":"d33f82b6a46535e798b78ebb28047ece1ef3b696ab29726d283161c377ed17a735a0948b99d83dee2af71704001e2e13813854a1b0ef4fcefd3c0e5c5f6e720d"},{"one":"d33f82b6a46535e798b78ebb28047ece1ef3b696ab29726d283161c377ed17a735a0948b99d83dee2af71704001e2e13813854a1b0ef4fcefd3c0e5c5f6e720d","up":true,"other":"519ce8f43529d0c703ef4faf50450877dc2818fd6fd6b7faaa9bbbaeac373e499d1b4a17b387b1a8d35e8042e18a9d3d365c97254b4d24352b10e8de9219a5cd"},{"other":"59fe05843cc637adac3728acb8ca9650f49050095cf5d32241366f54d4ac7179b16dcb009e2fb9fa9499cc6f8b865b6c4d6fe6e35500df10ba5daa719d57976e","one":"519ce8f43529d0c703ef4faf50450877dc2818fd6fd6b7faaa9bbbaeac373e499d1b4a17b387b1a8d35e8042e18a9d3d365c97254b4d24352b10e8de9219a5cd","up":true},{"up":true,"one":"59fe05843cc637adac3728acb8ca9650f49050095cf5d32241366f54d4ac7179b16dcb009e2fb9fa9499cc6f8b865b6c4d6fe6e35500df10ba5daa719d57976e","other":"3db9984cb1e25bdc30c483f3d4c036fb1728bafffecd2b965af7e701569c28116dbed2e5892504ea9927c14570351b03cb99112a5924a27e6e03289422785c7b"},{"other":"af0050715bfa25b4ce3a7593c61578898be22801a9118064250c330c6b2a1416b3bc6d90b074d7d700e07574a274d861f9c6d8e3e5924c281502f699ad62465b","one":"3db9984cb1e25bdc30c483f3d4c036fb1728bafffecd2b965af7e701569c28116dbed2e5892504ea9927c14570351b03cb99112a5924a27e6e03289422785c7b","up":true},{"one":"af0050715bfa25b4ce3a7593c61578898be22801a9118064250c330c6b2a1416b3bc6d90b074d7d700e07574a274d861f9c6d8e3e5924c281502f699ad62465b","up":true,"other":"35ac328e13ea4fc6c333591633455cb6a2dff124528a17668770e231582ea31ab95e083cd191d8c45369d88366e9df0d2417cd26efbf2f616139c92fd497cd48"},{"one":"35ac328e13ea4fc6c333591633455cb6a2dff124528a17668770e231582ea31ab95e083cd191d8c45369d88366e9df0d2417cd26efbf2f616139c92fd497cd48","up":true,"other":"a089758c25ca0730f13cd18c10aeea62488c1c2651eef53a8ad11cfdfa61ce8f7354a53bd6902da26b79dfbedc78d315b1d4239eb62cbca59215727b2ac35213"},{"up":true,"one":"cc94ed069ddcc24dc2733eed5ba8367a2521a5955c7287c5280c71675b9965ee8499454b227a4ddc64a14d74b39916211763ddf0b7ad80a52381cc61dcb6c72c","other":"df7decc6bb0d51afdc0c445a15be31b0e89c79a52b8a2cc789b585d94db63f064eccc1d8340d13d5e43ed7cbe95db8ad10ee7294dbd4c7629686564bb3a603b2"},{"other":"4228ad29aa22f1fa078c7e09f44f85c05d5b797072c10ade24dcbff95c01e554511fe10273a5f25a25ca06ff97bca28c241610f7145983f72ed44969ead4596a","up":true,"one":"a089758c25ca0730f13cd18c10aeea62488c1c2651eef53a8ad11cfdfa61ce8f7354a53bd6902da26b79dfbedc78d315b1d4239eb62cbca59215727b2ac35213"},{"up":true,"one":"4228ad29aa22f1fa078c7e09f44f85c05d5b797072c10ade24dcbff95c01e554511fe10273a5f25a25ca06ff97bca28c241610f7145983f72ed44969ead4596a","other":"b1bef03357528618be6936a7edae5e3d4ecc942d43bd301642d321a73a07f3327d413f923c3fdd49d04f311e18709a4dde7519722d7a4912f181aa4df2e60173"},{"other":"7ca32d24c001557a81af351ac71322543154eeedbb6ccdd8b8b142f19215aa712218babe9701e73a6441784375a511c1f16a70569b73416f9708409564d18485","one":"b1bef03357528618be6936a7edae5e3d4ecc942d43bd301642d321a73a07f3327d413f923c3fdd49d04f311e18709a4dde7519722d7a4912f181aa4df2e60173","up":true},{"other":"b949f482891fff7d7d1f0d84112db7080fa1df07cd4e52ee0fadb707a4b7903fc0da9fe45b7ceee37948856687f8e7768945295de15691a99c879f1816899d98","one":"a13086041114db2be31038987ac3fdcaeb99489f1b6ee9b22998b9e66dc2f2f024307d9474811e7e8be1b1acf5a55305d5cce27d87fb834ed1e1d2e17319bb85","up":true},{"up":true,"one":"f87c2dea026ba5e6cda9a446821bf057d3453fa8c9b38fd882a09979ff3cfe2b8adfcbd5cf28d268776414bd12a9aba385d5c97c76a29c1b0625b101faac761d","other":"d6c3095290d455c3855cfa88ee5f10d1975fdb0cc7ebc9aaa2330658e4229b9850f70f17798e530b50907d3d0d27fa49c0ed7dd4a7913d53c6881c5c86f380b8"},{"other":"2396833be485e50b230a07fddff7f24e11e3fdee3f08f11a287faa2b03b26451b9f4fd24ddefdec62917ae59b6fa56a75e7d6e078b411d624704b88f841b9960","one":"df7decc6bb0d51afdc0c445a15be31b0e89c79a52b8a2cc789b585d94db63f064eccc1d8340d13d5e43ed7cbe95db8ad10ee7294dbd4c7629686564bb3a603b2","up":true},{"up":true,"one":"2396833be485e50b230a07fddff7f24e11e3fdee3f08f11a287faa2b03b26451b9f4fd24ddefdec62917ae59b6fa56a75e7d6e078b411d624704b88f841b9960","other":"5c1e9692b731421d6eaca488e8ba4cfdda1933ac5f1504ece684fadbea07a7c8053feb73be7ce20aedeaecc84f14d836b5ed2a657df6ca04f4fc82c2da0c0d46"},{"one":"8b8c15c6329096267a25d4060ee19963afb6e776fea60d9d566d4e1f9b087581b36e33fc533d7f133668a7a6a22f81a1234ed9fbce26eff1d5e5691a6148d540","up":true,"other":"1545795dca07ecd09c5b16b3bbdddf3dba92e27b532c18a3bc63bc007761ac1b1ebc7ffb4f0a401d5376a4c67923c7949edaebd8f65fff52d6677bb1d6a72f43"},{"up":true,"one":"071c094246a0ca4b5d169e43a20ce5da508e579a6e2e822462bd8948ab357d46ab477bcff0c80eba2e01f0c100690b307af40d47c52ebad06783e9e77466cbd6","other":"f4ae36400caeddcbcf0fb1abd5b9611c37bac683645d10c69a1ac54d366f730c59917c95e990a0fa6bb2679c98fb62bf0e29bd7812ab57375de35f469dab98a0"},{"other":"6ba8900830489793a22bf5023cde4ab849dee525d1ca5b95e21040a8e8be5b295317b1c76e09beb7d17a9512137c487b99f16933622b5f2b0e10da3233086bbf","up":true,"one":"850e729f9bbb5ef6e12baf7d3dced180839e88e0845baa7aa8fb87dcb417aa74af5999bda81723aabbef5eda842fa4b5fae107fcff9f6bd50597e8ba6a849dff"},{"other":"bebbde654a4f3e3e65f63d10cbcc89dfd46ce75945c19be33bfe4d954c8ed375981e21a8376ad10e402dddbcf3b657e6786c0820e599a0d1fe03f8d35294d7c7","one":"d6c3095290d455c3855cfa88ee5f10d1975fdb0cc7ebc9aaa2330658e4229b9850f70f17798e530b50907d3d0d27fa49c0ed7dd4a7913d53c6881c5c86f380b8","up":true},{"one":"ad177f2702ed11d531b11fd0250f2dab2364624680cfb6ff1fba5b27dcd8334269a5bc9093401389044c0b00ed0cbf6f166aba81a58cadd34b25355839fff6ac","up":true,"other":"96f3194c9ef17f60c318be14dd72c51af0aebc19f7a574b769d18b1fda6791409c827892bae3a061800e3d78af88a97635a0a892c54d7ebb38342ab1ba99c3ad"},{"one":"7ca32d24c001557a81af351ac71322543154eeedbb6ccdd8b8b142f19215aa712218babe9701e73a6441784375a511c1f16a70569b73416f9708409564d18485","up":true,"other":"ad177f2702ed11d531b11fd0250f2dab2364624680cfb6ff1fba5b27dcd8334269a5bc9093401389044c0b00ed0cbf6f166aba81a58cadd34b25355839fff6ac"},{"other":"4903cd53b3ffc4328547e03dec8f7992edbfb1e1697e53772ef79887984b11595167eb84015ff3dfb26ac0d7b2e98b7a0792bef843d2bdff3a76889fc4a6c60a","one":"7625a1a0a0f5bf78e2b9fe43a1215ea882318458b886ec767ccbc35e76b543f96820b364342b28ff600302af7716280497141dc2fc84e83cb15f5eb3d268d73e","up":true},{"other":"64a39acfb1accea032dfc4d1530b5cdbdc8c1b609a442b68a9b534a539062d051b750a4512b0a9d504fdffa2a5bc8d4fcb6ca59f4ddb1c59ce62e8913644499b","one":"0d85f39dca79f99b277ad5cedfcd3fb1eccc7862c95c215ba0d5a2ec1c4fa80244393d0934cf59fe988f7716bf15cb8e79f4ee03fbe4a48a10cac6e0610f9d55","up":true},{"other":"45c635c4080d47e2f932c27472e487ec95b7644c3d94d8627166a33dca2e3cbaa3305ae2d42e1510bfb0f8329b90e5a31883b399a469ad548fcae3040a8833a0","up":true,"one":"fa4174ca214905c4136e891e64349f664f166aeeacead6f6e84892ebcadd2c7fbff07052ea4913a9465999f5494962ec29f7f7a3e6cbb993e00d1b881fb31eb1"},{"other":"826500ca53a2aed90da0cc3778cbc41af3de0139b246f30c3be65582b1f152928dfa3280760da4dcd8098f41f529a088dba24bc5d0c71322ef69f4b101f0224a","one":"540598224dccc717053f94e915652df499f513dc0c8874ce999040e1aa829c33ede284c72ddd0b24a319821102fa42aaaaa87380e777b5878455de61f5fc2ac9","up":true},{"up":true,"one":"96f3194c9ef17f60c318be14dd72c51af0aebc19f7a574b769d18b1fda6791409c827892bae3a061800e3d78af88a97635a0a892c54d7ebb38342ab1ba99c3ad","other":"d6f274a2f20831a1b2281d889f46ad44f1bc5a07bb2152c89e129afb1c1e643b608621791a9d15a28da022d57b8bc3c05a7da0b5a93201dd714179e4a6a29a8b"},{"up":true,"one":"071c094246a0ca4b5d169e43a20ce5da508e579a6e2e822462bd8948ab357d46ab477bcff0c80eba2e01f0c100690b307af40d47c52ebad06783e9e77466cbd6","other":"d6f274a2f20831a1b2281d889f46ad44f1bc5a07bb2152c89e129afb1c1e643b608621791a9d15a28da022d57b8bc3c05a7da0b5a93201dd714179e4a6a29a8b"},{"one":"f4ae36400caeddcbcf0fb1abd5b9611c37bac683645d10c69a1ac54d366f730c59917c95e990a0fa6bb2679c98fb62bf0e29bd7812ab57375de35f469dab98a0","up":true,"other":"d6f274a2f20831a1b2281d889f46ad44f1bc5a07bb2152c89e129afb1c1e643b608621791a9d15a28da022d57b8bc3c05a7da0b5a93201dd714179e4a6a29a8b"},{"other":"f4ae36400caeddcbcf0fb1abd5b9611c37bac683645d10c69a1ac54d366f730c59917c95e990a0fa6bb2679c98fb62bf0e29bd7812ab57375de35f469dab98a0","one":"d2cf35afdb846755290a7c3a1a36758e735a4eeed57b1af66595c55ab45c52cf2c478de3f395b38513cdc9e49568892cce490de93074fa45b640628f0fe40719","up":true},{"one":"64a39acfb1accea032dfc4d1530b5cdbdc8c1b609a442b68a9b534a539062d051b750a4512b0a9d504fdffa2a5bc8d4fcb6ca59f4ddb1c59ce62e8913644499b","up":true,"other":"45c635c4080d47e2f932c27472e487ec95b7644c3d94d8627166a33dca2e3cbaa3305ae2d42e1510bfb0f8329b90e5a31883b399a469ad548fcae3040a8833a0"},{"up":true,"one":"a5990a680e1f01dcd71a178a239880c5ce24418748c368b8e3c8a1175cfd744d16973cba03e5e756820950920a6d9fa5d5dd53829a1d1d508371cb1042e9453e","other":"7625a1a0a0f5bf78e2b9fe43a1215ea882318458b886ec767ccbc35e76b543f96820b364342b28ff600302af7716280497141dc2fc84e83cb15f5eb3d268d73e"},{"other":"f8fd12d8b5872b74e2cfa60d6a3a25b568a1fb4be3a8d06faac02a38321f419c443e517c0e2989001635f827add1859a2dc9589a9c0f5bf3804d46f43f799116","one":"f87c2dea026ba5e6cda9a446821bf057d3453fa8c9b38fd882a09979ff3cfe2b8adfcbd5cf28d268776414bd12a9aba385d5c97c76a29c1b0625b101faac761d","up":true},{"up":true,"one":"b737c81fe6bc50d977231a5fc8856f064ba58190c5ab5615d3cf634aea8c15a308f3a667aad2e69d5c1438549cd41c863fd40f643b70caf3e0c934276ef2a84f","other":"6ba8900830489793a22bf5023cde4ab849dee525d1ca5b95e21040a8e8be5b295317b1c76e09beb7d17a9512137c487b99f16933622b5f2b0e10da3233086bbf"},{"up":true,"one":"464cf4c4203246240a63965062b9e5a7e5fa903f127b1f5ea5b37a27d33d8b12768fc2d8f257e67418f1e5765e627ca8f8cd5ba6b15b8a047490d26ce43e6291","other":"af6cb988ddb16202459735b8489c02b3bf829ca301513a0d3e18bbb03d43c8de3cda767c7b5c984a6dce3f118c8089e06b08ed3bd0c922dde9cfe775609df3b2"},{"other":"64a39acfb1accea032dfc4d1530b5cdbdc8c1b609a442b68a9b534a539062d051b750a4512b0a9d504fdffa2a5bc8d4fcb6ca59f4ddb1c59ce62e8913644499b","up":true,"one":"d6c3095290d455c3855cfa88ee5f10d1975fdb0cc7ebc9aaa2330658e4229b9850f70f17798e530b50907d3d0d27fa49c0ed7dd4a7913d53c6881c5c86f380b8"},{"other":"0c000879be78fc867857011e396e2dd77bc2a0c6c2c3624d98b102737aa8d998ca9081653c0c8285117a5288b1bfeed06c54b2f6e39225aca4a21ff2a72116e1","one":"69f3f9fafff951dca2fe98baa178e53f2779311a93fdc364cf4c2477700c8dbce7e4201c3aa6d840b5ae65e8fc9d6603cbc41dbdf601f1998caedee1b542d72b","up":true},{"other":"de7ab7b9a2ba4ed523b84233fae11d93815579976ea78b385c658a4c156622747051f91342f9ac3610e22ee259b65e02b5af0ab67a9ee04ab6958a9d0d8acdf1","one":"dee5fb5ccdfe3803cab3e0041c5c4879001bf2c2233446f47245d8234642046269bfe50e414cd2d89341e338597f2ecbb7b2912c20558a85041b757a24490805","up":true},{"one":"fa4174ca214905c4136e891e64349f664f166aeeacead6f6e84892ebcadd2c7fbff07052ea4913a9465999f5494962ec29f7f7a3e6cbb993e00d1b881fb31eb1","up":true,"other":"f8fd12d8b5872b74e2cfa60d6a3a25b568a1fb4be3a8d06faac02a38321f419c443e517c0e2989001635f827add1859a2dc9589a9c0f5bf3804d46f43f799116"},{"other":"6ba8900830489793a22bf5023cde4ab849dee525d1ca5b95e21040a8e8be5b295317b1c76e09beb7d17a9512137c487b99f16933622b5f2b0e10da3233086bbf","one":"45c635c4080d47e2f932c27472e487ec95b7644c3d94d8627166a33dca2e3cbaa3305ae2d42e1510bfb0f8329b90e5a31883b399a469ad548fcae3040a8833a0","up":true},{"other":"69f3f9fafff951dca2fe98baa178e53f2779311a93fdc364cf4c2477700c8dbce7e4201c3aa6d840b5ae65e8fc9d6603cbc41dbdf601f1998caedee1b542d72b","one":"946b3f821a4b61661e8ace52f4ade415042fddf058d97a16f08d9eff7a0be633de47c27fa9760ff38d583b2405163d4a27d3a7949d4015271396c014043a34e3","up":true},{"other":"69f3f9fafff951dca2fe98baa178e53f2779311a93fdc364cf4c2477700c8dbce7e4201c3aa6d840b5ae65e8fc9d6603cbc41dbdf601f1998caedee1b542d72b","one":"c49e963a92b93a1c48fd3e38c127bfc88fbcb15b57bfdf8615c0e591b24276d4fe153a811932aefdcf3dee494d53ce354ba052c24313a725d562c6e807ab9133","up":true},{"one":"09fa1e69f37cb14db3dd721a9c4b9c884f6fe519d850f7af3643ecd536d4b3e995f99acf569e23b7864996c750115ff0ca0bd446ebfd76a026da71da0b95fd97","up":true,"other":"6ba8900830489793a22bf5023cde4ab849dee525d1ca5b95e21040a8e8be5b295317b1c76e09beb7d17a9512137c487b99f16933622b5f2b0e10da3233086bbf"},{"up":true,"one":"a302bebe4590b3f6d2c511919ceef4a5a80d431f53f8f3483c4b833a6a3b5f79b4c66c0ce2c0e5bc696534067ea5cd07772a9844ee0ba9d37a2e6f5d4bfb05cd","other":"69f3f9fafff951dca2fe98baa178e53f2779311a93fdc364cf4c2477700c8dbce7e4201c3aa6d840b5ae65e8fc9d6603cbc41dbdf601f1998caedee1b542d72b"},{"one":"223d79f656e3f124ee1238ca46e42c2a0d8500ee58a37312c6b72657a11ad9ebce3be4c061611b913a22863f6e7936ff37602dedc7856baea27e8201db44bbf4","up":true,"other":"5a27b90639d515cad7794dae78bf9a9866cca23c5e3e18870524d148797ba1bdfd631151f23062d4dcf0961a7dba709431a44e39da29ed5ea4b0b6987514e433"},{"other":"cf03d32d3cca446e7016e7f41267a257bef7142c4f1e4ce2e17678856d75e9889e21972fd21583297a47a156543af15400444dcf37aca64543f97f73734f7f0f","one":"972b7f6c5b926b93a9b005bb8a891c29e535a465c586bcd4258d4094e320925a179e8f63478917f8a88d1911fe8f868013abeb34817832ed4b0b209ce392f20b","up":true},{"up":true,"one":"a4dd67ab4fff1a50968c7ab59c304eb0083b072fc13dff599eeadac4e0e75099f7c825f91dd1bb770f3ae6f3d1d82ad574d6ecb117adf1ca9ccbccd01303ec7c","other":"af6cb988ddb16202459735b8489c02b3bf829ca301513a0d3e18bbb03d43c8de3cda767c7b5c984a6dce3f118c8089e06b08ed3bd0c922dde9cfe775609df3b2"},{"one":"0d85f39dca79f99b277ad5cedfcd3fb1eccc7862c95c215ba0d5a2ec1c4fa80244393d0934cf59fe988f7716bf15cb8e79f4ee03fbe4a48a10cac6e0610f9d55","up":true,"other":"4903cd53b3ffc4328547e03dec8f7992edbfb1e1697e53772ef79887984b11595167eb84015ff3dfb26ac0d7b2e98b7a0792bef843d2bdff3a76889fc4a6c60a"},{"one":"fb20c708420e60c48fa65980ae11adc8cdf9b56ab93044a9aee9b5196d52f29e6cb2c218f73fefbdaecf8177bae1d9d13dd64bbe06e631555715b93f58f47137","up":true,"other":"64a39acfb1accea032dfc4d1530b5cdbdc8c1b609a442b68a9b534a539062d051b750a4512b0a9d504fdffa2a5bc8d4fcb6ca59f4ddb1c59ce62e8913644499b"},{"one":"e20a90f36eca4329d3d2dbadf530949889dc20b0ae5d96b935af9b60d26ec507e9eb1b73fd2b4dc88057c20e4ef6e7039cc49652d35c563db64f06f979e28540","up":true,"other":"c4dfcf348694971fb36ed91e9024302bec8df3891540cbe1f5df26eee9c1f81a95295f05b90ec30dd044a0355dcaa805b9f50e95f38e5588a929cfe10e8cd73d"},{"one":"540598224dccc717053f94e915652df499f513dc0c8874ce999040e1aa829c33ede284c72ddd0b24a319821102fa42aaaaa87380e777b5878455de61f5fc2ac9","up":true,"other":"9ad5ec0e729f9db10b7028788b58ef13d54bd11529b494a549d0415b90777b63fe78a752356315f5abbd24d849edc0c8bfe9d82c05460c30f4dad860ff5fea48"},{"one":"7625a1a0a0f5bf78e2b9fe43a1215ea882318458b886ec767ccbc35e76b543f96820b364342b28ff600302af7716280497141dc2fc84e83cb15f5eb3d268d73e","up":true,"other":"b737c81fe6bc50d977231a5fc8856f064ba58190c5ab5615d3cf634aea8c15a308f3a667aad2e69d5c1438549cd41c863fd40f643b70caf3e0c934276ef2a84f"},{"other":"c133cd3ee228f427410357f46752d33ecf302475314411772df3532669a8b220136c09f00717460c39bcea1058cb988dd223875ec991612876b400556f5937dd","one":"53031cddf4390ba176d638456016028bd4538879c7eaba672c3ef70208319a14e6a41dea8ff003b6f7e9b4a83ca12dab50d4f44f079153bec7c24221e311573e","up":true},{"up":true,"one":"826500ca53a2aed90da0cc3778cbc41af3de0139b246f30c3be65582b1f152928dfa3280760da4dcd8098f41f529a088dba24bc5d0c71322ef69f4b101f0224a","other":"af761f8d13059f1e49d2f5c0b7a76a5eb5bcaab1e7ff01673dff3967d81bd7aebf74afef3934328034c82f131fa066de71816cff8f720e0c56d5e85b233a8a44"},{"other":"c133cd3ee228f427410357f46752d33ecf302475314411772df3532669a8b220136c09f00717460c39bcea1058cb988dd223875ec991612876b400556f5937dd","one":"2396833be485e50b230a07fddff7f24e11e3fdee3f08f11a287faa2b03b26451b9f4fd24ddefdec62917ae59b6fa56a75e7d6e078b411d624704b88f841b9960","up":true},{"one":"e0cacf6abdbfd9a25b9f974600662d4eae484efcdefd0a2a8fbc799127b6fabf2f471aff89c3a08e93ea20be1c304320598ba20a13697a356bf065292ba16bc1","up":true,"other":"c4dfcf348694971fb36ed91e9024302bec8df3891540cbe1f5df26eee9c1f81a95295f05b90ec30dd044a0355dcaa805b9f50e95f38e5588a929cfe10e8cd73d"},{"other":"11170a0fb9f6b037f8ee4494e935a84b06816ff5c44ef9d613920f9c58f8b25611b2093da3fb51a59687db6a9b0a070386cac09757a27f75754cbdcb9afc2225","one":"ac6057677fdfc132ea2418ff877357962771db049d169ba2c1923b15820385c6bf2f5846943d44a73bfdeb44a1e0d68307003a06cb0f694705879f8a720c3296","up":true},{"up":true,"one":"82f0cbb87a76dea7947c2c1b6506d05390e5c5e969e5e91651ca10d36cd6aaea72967435ea7e5222d28f1d5e64cc526075d264712e55593bc3b609c93d4fe1eb","other":"faa3c31521c8f7b9d15838750e7e311eb0f01db5ef22cd1bf62a7d72e7efdf5a575550c930d96230edc892d107d4551e95b099d3c952a7f1c0ad3b5967c7831b"},{"other":"82f0cbb87a76dea7947c2c1b6506d05390e5c5e969e5e91651ca10d36cd6aaea72967435ea7e5222d28f1d5e64cc526075d264712e55593bc3b609c93d4fe1eb","up":true,"one":"9b3fecfc63256a9d69e75ccb5119b2866e30fa4516b3a3bf5b2f03f04f1d20de786ddb90fa2acadb2a0509503b21fc9d16238c57f9b102ceedb6b27ee1b2c4ea"},{"other":"faa3c31521c8f7b9d15838750e7e311eb0f01db5ef22cd1bf62a7d72e7efdf5a575550c930d96230edc892d107d4551e95b099d3c952a7f1c0ad3b5967c7831b","one":"932e926c54a4127210a15731fa4ad6bbfd0d69183b894b676920843f154ad1e4148b674d234f070e9dc07547394a5af973befe0fc170bbe44346d69e135e0157","up":true},{"up":true,"one":"59fe05843cc637adac3728acb8ca9650f49050095cf5d32241366f54d4ac7179b16dcb009e2fb9fa9499cc6f8b865b6c4d6fe6e35500df10ba5daa719d57976e","other":"d33f82b6a46535e798b78ebb28047ece1ef3b696ab29726d283161c377ed17a735a0948b99d83dee2af71704001e2e13813854a1b0ef4fcefd3c0e5c5f6e720d"},{"other":"ed3a5d7602b59bd8709ef10cb84e4b5644a69490d1173a8b9135adba04b36c1fcd0f16543de39deff0e76d8314e6884ba939213f77abb8d50a68d030352cb495","one":"faa3c31521c8f7b9d15838750e7e311eb0f01db5ef22cd1bf62a7d72e7efdf5a575550c930d96230edc892d107d4551e95b099d3c952a7f1c0ad3b5967c7831b","up":true},{"other":"ac6057677fdfc132ea2418ff877357962771db049d169ba2c1923b15820385c6bf2f5846943d44a73bfdeb44a1e0d68307003a06cb0f694705879f8a720c3296","one":"49bd2289f479c9ad7e0d13319271b9be1e1dcbee28313513a124dec55f9842db639e62a74a83040930c537739ab7fa1e50bb05b9ab0f588d6da7b64a6451f466","up":true},{"other":"a089758c25ca0730f13cd18c10aeea62488c1c2651eef53a8ad11cfdfa61ce8f7354a53bd6902da26b79dfbedc78d315b1d4239eb62cbca59215727b2ac35213","up":true,"one":"d6f274a2f20831a1b2281d889f46ad44f1bc5a07bb2152c89e129afb1c1e643b608621791a9d15a28da022d57b8bc3c05a7da0b5a93201dd714179e4a6a29a8b"},{"other":"f8fd12d8b5872b74e2cfa60d6a3a25b568a1fb4be3a8d06faac02a38321f419c443e517c0e2989001635f827add1859a2dc9589a9c0f5bf3804d46f43f799116","one":"a13086041114db2be31038987ac3fdcaeb99489f1b6ee9b22998b9e66dc2f2f024307d9474811e7e8be1b1acf5a55305d5cce27d87fb834ed1e1d2e17319bb85","up":true},{"other":"3db9984cb1e25bdc30c483f3d4c036fb1728bafffecd2b965af7e701569c28116dbed2e5892504ea9927c14570351b03cb99112a5924a27e6e03289422785c7b","one":"519ce8f43529d0c703ef4faf50450877dc2818fd6fd6b7faaa9bbbaeac373e499d1b4a17b387b1a8d35e8042e18a9d3d365c97254b4d24352b10e8de9219a5cd","up":true},{"other":"af0050715bfa25b4ce3a7593c61578898be22801a9118064250c330c6b2a1416b3bc6d90b074d7d700e07574a274d861f9c6d8e3e5924c281502f699ad62465b","one":"b1bef03357528618be6936a7edae5e3d4ecc942d43bd301642d321a73a07f3327d413f923c3fdd49d04f311e18709a4dde7519722d7a4912f181aa4df2e60173","up":true},{"other":"d6f274a2f20831a1b2281d889f46ad44f1bc5a07bb2152c89e129afb1c1e643b608621791a9d15a28da022d57b8bc3c05a7da0b5a93201dd714179e4a6a29a8b","up":true,"one":"7ca32d24c001557a81af351ac71322543154eeedbb6ccdd8b8b142f19215aa712218babe9701e73a6441784375a511c1f16a70569b73416f9708409564d18485"},{"up":true,"one":"e3779b202b9cfe7b2f2cc9e95974ac77bf51ba951f775acc10f07249ee6b3b260f2b012bb010a7f9794c5562e9b00f18b52c25c1e350ab70afc6bf9e210e4969","other":"932e926c54a4127210a15731fa4ad6bbfd0d69183b894b676920843f154ad1e4148b674d234f070e9dc07547394a5af973befe0fc170bbe44346d69e135e0157"},{"other":"e0cacf6abdbfd9a25b9f974600662d4eae484efcdefd0a2a8fbc799127b6fabf2f471aff89c3a08e93ea20be1c304320598ba20a13697a356bf065292ba16bc1","up":true,"one":"57533c56642895edba91473a966b6abf765725a721dec947e4bac4728dfbed265435aefca55fff69cae48c9d506064fbb890665a0acd87c466707d08d1e6e1f4"},{"other":"193ca2ef8a4ac98c0300d7e48421ba3fe5d4789a0c2b476499bd093808c3988b4a55742ff3f607429cafda08cbbb5fba68da8869747b1b5169f3e4545497de3a","up":true,"one":"84379884f012e2cfc1f9838312640576c9ded01ca53cf8451f94915e6949f0084047a2555a5fef4d1b0eef62ad5504a34ff631fbb658b011a07a82a53173f5c1"},{"one":"ad177f2702ed11d531b11fd0250f2dab2364624680cfb6ff1fba5b27dcd8334269a5bc9093401389044c0b00ed0cbf6f166aba81a58cadd34b25355839fff6ac","up":true,"other":"35ac328e13ea4fc6c333591633455cb6a2dff124528a17668770e231582ea31ab95e083cd191d8c45369d88366e9df0d2417cd26efbf2f616139c92fd497cd48"},{"up":true,"one":"3db9984cb1e25bdc30c483f3d4c036fb1728bafffecd2b965af7e701569c28116dbed2e5892504ea9927c14570351b03cb99112a5924a27e6e03289422785c7b","other":"d6c3095290d455c3855cfa88ee5f10d1975fdb0cc7ebc9aaa2330658e4229b9850f70f17798e530b50907d3d0d27fa49c0ed7dd4a7913d53c6881c5c86f380b8"},{"up":true,"one":"604a11bd1d969886953398ecc1fdf5847a946a8118014d0cb8daff9943f4f78c4bdbad3ee4152959c8265d0588dea658c262fe2f99a55a0b32321b81c8eec473","other":"cf03d32d3cca446e7016e7f41267a257bef7142c4f1e4ce2e17678856d75e9889e21972fd21583297a47a156543af15400444dcf37aca64543f97f73734f7f0f"},{"other":"e3779b202b9cfe7b2f2cc9e95974ac77bf51ba951f775acc10f07249ee6b3b260f2b012bb010a7f9794c5562e9b00f18b52c25c1e350ab70afc6bf9e210e4969","up":true,"one":"38469be067f9bba869fdfcc950843e00b5ff950778c11445787501d47cbaf60e9940735a5b8b71d48a0aaee75c8263137169d51944638dc5d1cad398d22439ed"},{"other":"35ac328e13ea4fc6c333591633455cb6a2dff124528a17668770e231582ea31ab95e083cd191d8c45369d88366e9df0d2417cd26efbf2f616139c92fd497cd48","up":true,"one":"d33f82b6a46535e798b78ebb28047ece1ef3b696ab29726d283161c377ed17a735a0948b99d83dee2af71704001e2e13813854a1b0ef4fcefd3c0e5c5f6e720d"},{"up":true,"one":"57fb9e7f287fe67500b8b560475c0d0d6eae9d623d5a8c85eb5459f209904a839a0b24ff99a1643a4196a71d45f2ed1bd5e08f9a13cdd9749a907a024ff984dc","other":"ef3016ea5a7b1b57388904d5c80fd05780d23acec8cf73e8add28ea99c6222fa84e89a1752186a2ef41dd0ec828405e61a1e8fd67d9496d75525ed860b12e2e8"},{"other":"c49e963a92b93a1c48fd3e38c127bfc88fbcb15b57bfdf8615c0e591b24276d4fe153a811932aefdcf3dee494d53ce354ba052c24313a725d562c6e807ab9133","up":true,"one":"c677530a47ef470ae0811127b91c231ec8889588bd096c24a54cc48099e8edde811f4a72eedc79118acb494ef031d6adcef1595d1a17df71b25b468478e931ff"},{"up":true,"one":"f2ac738fa932c90a45d1a64e4a52fd9c4037e2d89ceef1584efef04689bc7aff3a9635fb78dfdf3480d003daf14359190b1cfa8335db438a54107d4060ed58f9","other":"255939ef32bd3e5e76181763c11707b9ff4ab26d3ffb10f06fa7249b06721fa3decfa9eee3eeb8b12d6218af5f9ed8872d62c42a90cd46dcbef3d89a8163ae07"},{"other":"aa108a30f86b8296b416ea9fd6bc7a21c65c7cd3911ca3d4ee79325912d80db7150c02d304e49c5d0feafbd222edd6d522661a0983f1d427981760712f31e6f1","up":true,"one":"9158b9eb87bf7d011f83febca8f9d6575dd05be1f7e7bc18336f802651a379dd181a0503b5a8e46a580c59889998b16275f1e0ce4dce965cdbe72265ad2be283"},{"other":"eeb9d718ef61c14e10ab2fb3a90b039368acd17a59f70628deb39515c227bd0916c796cd7767b1a9d4f38e04f1013173b21c1fa2e0206ecdc72df6c2621380a2","one":"f78ecf420b73cd0245807157c0cbaaa568c60c80965413e187b084fb26041761d12790c0cb6a39bc8997fd2b3d3f52c831e601f1f1846945fba1808b0e1cdf25","up":true},{"other":"faa3c31521c8f7b9d15838750e7e311eb0f01db5ef22cd1bf62a7d72e7efdf5a575550c930d96230edc892d107d4551e95b099d3c952a7f1c0ad3b5967c7831b","up":true,"one":"7172a86afb608acd9a3e1e5c0472489ebecb516cad6796fa9a06ab47cc8e8cce12dddce72f0ac3b0927602bd22ed5872c3b5ce9b6af96f8e9d1d75078cc9bb55"},{"one":"0e07d2eb15905a583532383cef08b0881878c5043c4d7bae2cf1cace9954bfbbfbe0c1e8322eabbc84bc94cda08ae9b70cbdc56a1b8a19f807bcd5ca7939669d","up":true,"other":"2a0fa7932768f0c316b478d15db556626def18462c3bee9446ff16c48fc43b6be1694a5783602b60250e33adc705b86fae7baa6b829146251995fd47980ce422"},{"other":"123633b35f455fc3240d99929dc3130bb018545672be151ba973915f2ab6e6c862748f60d917e48ccbf28620c4e58b888867cb51e12ec0d2e5c61cef82258719","one":"b949f482891fff7d7d1f0d84112db7080fa1df07cd4e52ee0fadb707a4b7903fc0da9fe45b7ceee37948856687f8e7768945295de15691a99c879f1816899d98","up":true},{"other":"af6cb988ddb16202459735b8489c02b3bf829ca301513a0d3e18bbb03d43c8de3cda767c7b5c984a6dce3f118c8089e06b08ed3bd0c922dde9cfe775609df3b2","one":"de7ab7b9a2ba4ed523b84233fae11d93815579976ea78b385c658a4c156622747051f91342f9ac3610e22ee259b65e02b5af0ab67a9ee04ab6958a9d0d8acdf1","up":true},{"up":true,"one":"ef3016ea5a7b1b57388904d5c80fd05780d23acec8cf73e8add28ea99c6222fa84e89a1752186a2ef41dd0ec828405e61a1e8fd67d9496d75525ed860b12e2e8","other":"850e729f9bbb5ef6e12baf7d3dced180839e88e0845baa7aa8fb87dcb417aa74af5999bda81723aabbef5eda842fa4b5fae107fcff9f6bd50597e8ba6a849dff"},{"one":"f3bf16c7156ce55af92b2fc21826bdfd3e1f245c6087e76f5eb23cc8bbd88b25515a32029d3e6e2b4a27354606e9e3bdfe78788e326c4349d63416894fcfbaf4","up":true,"other":"4f4201d959e4add3a4bcf3cbaab29d8abcc7530a9834e3cde45c4459ea92fba869e65156037a8fae02eac05f6174a7f2c1d825418f2207caa2284bcc9d9b84d1"},{"up":true,"one":"eeb9d718ef61c14e10ab2fb3a90b039368acd17a59f70628deb39515c227bd0916c796cd7767b1a9d4f38e04f1013173b21c1fa2e0206ecdc72df6c2621380a2","other":"b737c81fe6bc50d977231a5fc8856f064ba58190c5ab5615d3cf634aea8c15a308f3a667aad2e69d5c1438549cd41c863fd40f643b70caf3e0c934276ef2a84f"},{"other":"fb20c708420e60c48fa65980ae11adc8cdf9b56ab93044a9aee9b5196d52f29e6cb2c218f73fefbdaecf8177bae1d9d13dd64bbe06e631555715b93f58f47137","up":true,"one":"236266f9f5a28148d11bed1195a91cd1d30231b082697ee1940a85abca98d2ff0767be9128c23375caa0444bcf51d8501879200ea0f27f13d0ede37f97241325"},{"other":"49bd2289f479c9ad7e0d13319271b9be1e1dcbee28313513a124dec55f9842db639e62a74a83040930c537739ab7fa1e50bb05b9ab0f588d6da7b64a6451f466","up":true,"one":"0bf28b481d71062ee100d6cb04c8b4234a574f8657e2d3c49b60a9ecdbf486d0ec38b33bce745c8efe820145d5c53ea802aa64b4f9bce19b029ee5b2f9de43f1"},{"one":"6ba8900830489793a22bf5023cde4ab849dee525d1ca5b95e21040a8e8be5b295317b1c76e09beb7d17a9512137c487b99f16933622b5f2b0e10da3233086bbf","up":true,"other":"64a39acfb1accea032dfc4d1530b5cdbdc8c1b609a442b68a9b534a539062d051b750a4512b0a9d504fdffa2a5bc8d4fcb6ca59f4ddb1c59ce62e8913644499b"},{"other":"3bf838b4d29d9388a24d160eee6bf8ea017af6cd9e5f7d88b4cae71ebfbc304666d3d634a05e0a75570dafe8f41871090fcff8b651a9130d013786dfcca3da14","one":"e2956a828cb1ff85ab55bdbe329f530662558cb8013ffddacac8ba36096abea07ecb15b54896dd9b4bb0b15155654dbda0c031f69290f2314ac0e376bebbd864","up":true},{"other":"604a11bd1d969886953398ecc1fdf5847a946a8118014d0cb8daff9943f4f78c4bdbad3ee4152959c8265d0588dea658c262fe2f99a55a0b32321b81c8eec473","up":true,"one":"9ad5ec0e729f9db10b7028788b58ef13d54bd11529b494a549d0415b90777b63fe78a752356315f5abbd24d849edc0c8bfe9d82c05460c30f4dad860ff5fea48"},{"other":"82f0cbb87a76dea7947c2c1b6506d05390e5c5e969e5e91651ca10d36cd6aaea72967435ea7e5222d28f1d5e64cc526075d264712e55593bc3b609c93d4fe1eb","one":"f394aaa6d14c6ed95e2ad4651b5103bb1ab9f3a61839936cc1f08d6a6e53504e5d15dfc5211539ffdbdc64912ded5c2272d4af52ed8d7fe5a3c228eb12f0c68b","up":true},{"up":true,"one":"c708e3584cd9450b30d8cdd960a676884f64364c2aec985eebb4a0d745f6c73b6b0cb16f330bf090320bc48a5a67e8519b3c2c4a64cf2eff9aa4f1fc0b274a00","other":"604a11bd1d969886953398ecc1fdf5847a946a8118014d0cb8daff9943f4f78c4bdbad3ee4152959c8265d0588dea658c262fe2f99a55a0b32321b81c8eec473"},{"up":true,"one":"fd321c630fadcc8d6b00589323f7313ac1e94effbe8192955da5f88dcf419ef28820075e0e81c595561ff6ee58cfce23079407edf8b1611cb994946bcbd26364","other":"faa3c31521c8f7b9d15838750e7e311eb0f01db5ef22cd1bf62a7d72e7efdf5a575550c930d96230edc892d107d4551e95b099d3c952a7f1c0ad3b5967c7831b"},{"other":"123633b35f455fc3240d99929dc3130bb018545672be151ba973915f2ab6e6c862748f60d917e48ccbf28620c4e58b888867cb51e12ec0d2e5c61cef82258719","one":"071c094246a0ca4b5d169e43a20ce5da508e579a6e2e822462bd8948ab357d46ab477bcff0c80eba2e01f0c100690b307af40d47c52ebad06783e9e77466cbd6","up":true},{"one":"d2cf35afdb846755290a7c3a1a36758e735a4eeed57b1af66595c55ab45c52cf2c478de3f395b38513cdc9e49568892cce490de93074fa45b640628f0fe40719","up":true,"other":"96f3194c9ef17f60c318be14dd72c51af0aebc19f7a574b769d18b1fda6791409c827892bae3a061800e3d78af88a97635a0a892c54d7ebb38342ab1ba99c3ad"},{"other":"af6cb988ddb16202459735b8489c02b3bf829ca301513a0d3e18bbb03d43c8de3cda767c7b5c984a6dce3f118c8089e06b08ed3bd0c922dde9cfe775609df3b2","up":true,"one":"b737c81fe6bc50d977231a5fc8856f064ba58190c5ab5615d3cf634aea8c15a308f3a667aad2e69d5c1438549cd41c863fd40f643b70caf3e0c934276ef2a84f"},{"other":"d6f274a2f20831a1b2281d889f46ad44f1bc5a07bb2152c89e129afb1c1e643b608621791a9d15a28da022d57b8bc3c05a7da0b5a93201dd714179e4a6a29a8b","one":"b949f482891fff7d7d1f0d84112db7080fa1df07cd4e52ee0fadb707a4b7903fc0da9fe45b7ceee37948856687f8e7768945295de15691a99c879f1816899d98","up":true},{"one":"193ca2ef8a4ac98c0300d7e48421ba3fe5d4789a0c2b476499bd093808c3988b4a55742ff3f607429cafda08cbbb5fba68da8869747b1b5169f3e4545497de3a","up":true,"other":"f3bf16c7156ce55af92b2fc21826bdfd3e1f245c6087e76f5eb23cc8bbd88b25515a32029d3e6e2b4a27354606e9e3bdfe78788e326c4349d63416894fcfbaf4"},{"other":"c133cd3ee228f427410357f46752d33ecf302475314411772df3532669a8b220136c09f00717460c39bcea1058cb988dd223875ec991612876b400556f5937dd","up":true,"one":"7e9a81d06e997a691cc7790d358868b8657db608795ef6b85bb194db7f56ab5c76cac3be0b40d847ce873aeef4bdad40b725d69f4c42755b9d5aab4fe7aecb34"},{"other":"123633b35f455fc3240d99929dc3130bb018545672be151ba973915f2ab6e6c862748f60d917e48ccbf28620c4e58b888867cb51e12ec0d2e5c61cef82258719","up":true,"one":"f4ae36400caeddcbcf0fb1abd5b9611c37bac683645d10c69a1ac54d366f730c59917c95e990a0fa6bb2679c98fb62bf0e29bd7812ab57375de35f469dab98a0"},{"up":true,"one":"f87c2dea026ba5e6cda9a446821bf057d3453fa8c9b38fd882a09979ff3cfe2b8adfcbd5cf28d268776414bd12a9aba385d5c97c76a29c1b0625b101faac761d","other":"35ac328e13ea4fc6c333591633455cb6a2dff124528a17668770e231582ea31ab95e083cd191d8c45369d88366e9df0d2417cd26efbf2f616139c92fd497cd48"},{"other":"69f3f9fafff951dca2fe98baa178e53f2779311a93fdc364cf4c2477700c8dbce7e4201c3aa6d840b5ae65e8fc9d6603cbc41dbdf601f1998caedee1b542d72b","one":"850e729f9bbb5ef6e12baf7d3dced180839e88e0845baa7aa8fb87dcb417aa74af5999bda81723aabbef5eda842fa4b5fae107fcff9f6bd50597e8ba6a849dff","up":true},{"other":"d6c3095290d455c3855cfa88ee5f10d1975fdb0cc7ebc9aaa2330658e4229b9850f70f17798e530b50907d3d0d27fa49c0ed7dd4a7913d53c6881c5c86f380b8","one":"45c635c4080d47e2f932c27472e487ec95b7644c3d94d8627166a33dca2e3cbaa3305ae2d42e1510bfb0f8329b90e5a31883b399a469ad548fcae3040a8833a0","up":true},{"other":"84379884f012e2cfc1f9838312640576c9ded01ca53cf8451f94915e6949f0084047a2555a5fef4d1b0eef62ad5504a34ff631fbb658b011a07a82a53173f5c1","one":"f3bf16c7156ce55af92b2fc21826bdfd3e1f245c6087e76f5eb23cc8bbd88b25515a32029d3e6e2b4a27354606e9e3bdfe78788e326c4349d63416894fcfbaf4","up":true},{"one":"09fa1e69f37cb14db3dd721a9c4b9c884f6fe519d850f7af3643ecd536d4b3e995f99acf569e23b7864996c750115ff0ca0bd446ebfd76a026da71da0b95fd97","up":true,"other":"64a39acfb1accea032dfc4d1530b5cdbdc8c1b609a442b68a9b534a539062d051b750a4512b0a9d504fdffa2a5bc8d4fcb6ca59f4ddb1c59ce62e8913644499b"},{"other":"fb20c708420e60c48fa65980ae11adc8cdf9b56ab93044a9aee9b5196d52f29e6cb2c218f73fefbdaecf8177bae1d9d13dd64bbe06e631555715b93f58f47137","one":"6ba8900830489793a22bf5023cde4ab849dee525d1ca5b95e21040a8e8be5b295317b1c76e09beb7d17a9512137c487b99f16933622b5f2b0e10da3233086bbf","up":true},{"one":"a13086041114db2be31038987ac3fdcaeb99489f1b6ee9b22998b9e66dc2f2f024307d9474811e7e8be1b1acf5a55305d5cce27d87fb834ed1e1d2e17319bb85","up":true,"other":"c796d4917dd22d9836a9d7d24ba6f89e1a0e8a78a207bd930991e44e9c80ac1de8e4e1a023d550a6dfa60270fbb3935a7e03ef389c1ccda957a4a6a75ef6819b"},{"other":"7625a1a0a0f5bf78e2b9fe43a1215ea882318458b886ec767ccbc35e76b543f96820b364342b28ff600302af7716280497141dc2fc84e83cb15f5eb3d268d73e","up":true,"one":"d6c3095290d455c3855cfa88ee5f10d1975fdb0cc7ebc9aaa2330658e4229b9850f70f17798e530b50907d3d0d27fa49c0ed7dd4a7913d53c6881c5c86f380b8"},{"other":"45c635c4080d47e2f932c27472e487ec95b7644c3d94d8627166a33dca2e3cbaa3305ae2d42e1510bfb0f8329b90e5a31883b399a469ad548fcae3040a8833a0","up":true,"one":"7625a1a0a0f5bf78e2b9fe43a1215ea882318458b886ec767ccbc35e76b543f96820b364342b28ff600302af7716280497141dc2fc84e83cb15f5eb3d268d73e"},{"one":"fa4174ca214905c4136e891e64349f664f166aeeacead6f6e84892ebcadd2c7fbff07052ea4913a9465999f5494962ec29f7f7a3e6cbb993e00d1b881fb31eb1","up":true,"other":"a13086041114db2be31038987ac3fdcaeb99489f1b6ee9b22998b9e66dc2f2f024307d9474811e7e8be1b1acf5a55305d5cce27d87fb834ed1e1d2e17319bb85"},{"other":"09fa1e69f37cb14db3dd721a9c4b9c884f6fe519d850f7af3643ecd536d4b3e995f99acf569e23b7864996c750115ff0ca0bd446ebfd76a026da71da0b95fd97","one":"fb20c708420e60c48fa65980ae11adc8cdf9b56ab93044a9aee9b5196d52f29e6cb2c218f73fefbdaecf8177bae1d9d13dd64bbe06e631555715b93f58f47137","up":true},{"up":true,"one":"0d85f39dca79f99b277ad5cedfcd3fb1eccc7862c95c215ba0d5a2ec1c4fa80244393d0934cf59fe988f7716bf15cb8e79f4ee03fbe4a48a10cac6e0610f9d55","other":"a5990a680e1f01dcd71a178a239880c5ce24418748c368b8e3c8a1175cfd744d16973cba03e5e756820950920a6d9fa5d5dd53829a1d1d508371cb1042e9453e"},{"other":"dee5fb5ccdfe3803cab3e0041c5c4879001bf2c2233446f47245d8234642046269bfe50e414cd2d89341e338597f2ecbb7b2912c20558a85041b757a24490805","one":"41ded7596eac3eddfd1f7656ef23adabe1d18027f6159e45867e935d1ab742ec298ba2b23df522f79f59c7805510d8c995837380432dee37912d6ede1196caa2","up":true},{"other":"f87c2dea026ba5e6cda9a446821bf057d3453fa8c9b38fd882a09979ff3cfe2b8adfcbd5cf28d268776414bd12a9aba385d5c97c76a29c1b0625b101faac761d","one":"64a39acfb1accea032dfc4d1530b5cdbdc8c1b609a442b68a9b534a539062d051b750a4512b0a9d504fdffa2a5bc8d4fcb6ca59f4ddb1c59ce62e8913644499b","up":true},{"up":true,"one":"a4dd67ab4fff1a50968c7ab59c304eb0083b072fc13dff599eeadac4e0e75099f7c825f91dd1bb770f3ae6f3d1d82ad574d6ecb117adf1ca9ccbccd01303ec7c","other":"eeb9d718ef61c14e10ab2fb3a90b039368acd17a59f70628deb39515c227bd0916c796cd7767b1a9d4f38e04f1013173b21c1fa2e0206ecdc72df6c2621380a2"},{"one":"236266f9f5a28148d11bed1195a91cd1d30231b082697ee1940a85abca98d2ff0767be9128c23375caa0444bcf51d8501879200ea0f27f13d0ede37f97241325","up":true,"other":"6ba8900830489793a22bf5023cde4ab849dee525d1ca5b95e21040a8e8be5b295317b1c76e09beb7d17a9512137c487b99f16933622b5f2b0e10da3233086bbf"},{"up":true,"one":"a5990a680e1f01dcd71a178a239880c5ce24418748c368b8e3c8a1175cfd744d16973cba03e5e756820950920a6d9fa5d5dd53829a1d1d508371cb1042e9453e","other":"123633b35f455fc3240d99929dc3130bb018545672be151ba973915f2ab6e6c862748f60d917e48ccbf28620c4e58b888867cb51e12ec0d2e5c61cef82258719"},{"other":"fa4174ca214905c4136e891e64349f664f166aeeacead6f6e84892ebcadd2c7fbff07052ea4913a9465999f5494962ec29f7f7a3e6cbb993e00d1b881fb31eb1","up":true,"one":"41ded7596eac3eddfd1f7656ef23adabe1d18027f6159e45867e935d1ab742ec298ba2b23df522f79f59c7805510d8c995837380432dee37912d6ede1196caa2"},{"other":"826500ca53a2aed90da0cc3778cbc41af3de0139b246f30c3be65582b1f152928dfa3280760da4dcd8098f41f529a088dba24bc5d0c71322ef69f4b101f0224a","one":"dee5fb5ccdfe3803cab3e0041c5c4879001bf2c2233446f47245d8234642046269bfe50e414cd2d89341e338597f2ecbb7b2912c20558a85041b757a24490805","up":true},{"other":"540598224dccc717053f94e915652df499f513dc0c8874ce999040e1aa829c33ede284c72ddd0b24a319821102fa42aaaaa87380e777b5878455de61f5fc2ac9","up":true,"one":"c708e3584cd9450b30d8cdd960a676884f64364c2aec985eebb4a0d745f6c73b6b0cb16f330bf090320bc48a5a67e8519b3c2c4a64cf2eff9aa4f1fc0b274a00"},{"other":"946b3f821a4b61661e8ace52f4ade415042fddf058d97a16f08d9eff7a0be633de47c27fa9760ff38d583b2405163d4a27d3a7949d4015271396c014043a34e3","one":"a302bebe4590b3f6d2c511919ceef4a5a80d431f53f8f3483c4b833a6a3b5f79b4c66c0ce2c0e5bc696534067ea5cd07772a9844ee0ba9d37a2e6f5d4bfb05cd","up":true},{"up":true,"one":"826500ca53a2aed90da0cc3778cbc41af3de0139b246f30c3be65582b1f152928dfa3280760da4dcd8098f41f529a088dba24bc5d0c71322ef69f4b101f0224a","other":"57533c56642895edba91473a966b6abf765725a721dec947e4bac4728dfbed265435aefca55fff69cae48c9d506064fbb890665a0acd87c466707d08d1e6e1f4"},{"other":"540598224dccc717053f94e915652df499f513dc0c8874ce999040e1aa829c33ede284c72ddd0b24a319821102fa42aaaaa87380e777b5878455de61f5fc2ac9","up":true,"one":"604a11bd1d969886953398ecc1fdf5847a946a8118014d0cb8daff9943f4f78c4bdbad3ee4152959c8265d0588dea658c262fe2f99a55a0b32321b81c8eec473"},{"other":"f8fd12d8b5872b74e2cfa60d6a3a25b568a1fb4be3a8d06faac02a38321f419c443e517c0e2989001635f827add1859a2dc9589a9c0f5bf3804d46f43f799116","up":true,"one":"f78ecf420b73cd0245807157c0cbaaa568c60c80965413e187b084fb26041761d12790c0cb6a39bc8997fd2b3d3f52c831e601f1f1846945fba1808b0e1cdf25"},{"other":"c49e963a92b93a1c48fd3e38c127bfc88fbcb15b57bfdf8615c0e591b24276d4fe153a811932aefdcf3dee494d53ce354ba052c24313a725d562c6e807ab9133","up":true,"one":"946b3f821a4b61661e8ace52f4ade415042fddf058d97a16f08d9eff7a0be633de47c27fa9760ff38d583b2405163d4a27d3a7949d4015271396c014043a34e3"},{"other":"dee5fb5ccdfe3803cab3e0041c5c4879001bf2c2233446f47245d8234642046269bfe50e414cd2d89341e338597f2ecbb7b2912c20558a85041b757a24490805","up":true,"one":"464cf4c4203246240a63965062b9e5a7e5fa903f127b1f5ea5b37a27d33d8b12768fc2d8f257e67418f1e5765e627ca8f8cd5ba6b15b8a047490d26ce43e6291"},{"other":"0c000879be78fc867857011e396e2dd77bc2a0c6c2c3624d98b102737aa8d998ca9081653c0c8285117a5288b1bfeed06c54b2f6e39225aca4a21ff2a72116e1","one":"ef3016ea5a7b1b57388904d5c80fd05780d23acec8cf73e8add28ea99c6222fa84e89a1752186a2ef41dd0ec828405e61a1e8fd67d9496d75525ed860b12e2e8","up":true},{"other":"a302bebe4590b3f6d2c511919ceef4a5a80d431f53f8f3483c4b833a6a3b5f79b4c66c0ce2c0e5bc696534067ea5cd07772a9844ee0ba9d37a2e6f5d4bfb05cd","one":"c677530a47ef470ae0811127b91c231ec8889588bd096c24a54cc48099e8edde811f4a72eedc79118acb494ef031d6adcef1595d1a17df71b25b468478e931ff","up":true},{"one":"223d79f656e3f124ee1238ca46e42c2a0d8500ee58a37312c6b72657a11ad9ebce3be4c061611b913a22863f6e7936ff37602dedc7856baea27e8201db44bbf4","up":true,"other":"af6cb988ddb16202459735b8489c02b3bf829ca301513a0d3e18bbb03d43c8de3cda767c7b5c984a6dce3f118c8089e06b08ed3bd0c922dde9cfe775609df3b2"},{"one":"972b7f6c5b926b93a9b005bb8a891c29e535a465c586bcd4258d4094e320925a179e8f63478917f8a88d1911fe8f868013abeb34817832ed4b0b209ce392f20b","up":true,"other":"aa108a30f86b8296b416ea9fd6bc7a21c65c7cd3911ca3d4ee79325912d80db7150c02d304e49c5d0feafbd222edd6d522661a0983f1d427981760712f31e6f1"},{"up":true,"one":"c133cd3ee228f427410357f46752d33ecf302475314411772df3532669a8b220136c09f00717460c39bcea1058cb988dd223875ec991612876b400556f5937dd","other":"f2ac738fa932c90a45d1a64e4a52fd9c4037e2d89ceef1584efef04689bc7aff3a9635fb78dfdf3480d003daf14359190b1cfa8335db438a54107d4060ed58f9"},{"other":"55beb7853107501c013283d0114f9812c2e97b292f90ae9bdd5aa8189d0379a758cbf19c5fa62436bc75a6e30d935a3bd52025b06efd167fa2fb8a1caead2f83","up":true,"one":"de7ab7b9a2ba4ed523b84233fae11d93815579976ea78b385c658a4c156622747051f91342f9ac3610e22ee259b65e02b5af0ab67a9ee04ab6958a9d0d8acdf1"},{"one":"c49e963a92b93a1c48fd3e38c127bfc88fbcb15b57bfdf8615c0e591b24276d4fe153a811932aefdcf3dee494d53ce354ba052c24313a725d562c6e807ab9133","up":true,"other":"a302bebe4590b3f6d2c511919ceef4a5a80d431f53f8f3483c4b833a6a3b5f79b4c66c0ce2c0e5bc696534067ea5cd07772a9844ee0ba9d37a2e6f5d4bfb05cd"},{"other":"f8fd12d8b5872b74e2cfa60d6a3a25b568a1fb4be3a8d06faac02a38321f419c443e517c0e2989001635f827add1859a2dc9589a9c0f5bf3804d46f43f799116","one":"54b79d3662ba486bbd120313d59ef101acf963eb3d6112a9dda121bc0b52f4b1fbcb13406705cdd8c2d3990ad296171c7972211467cc0d44cbe9ca16fbc82e3e","up":true},{"other":"fa4174ca214905c4136e891e64349f664f166aeeacead6f6e84892ebcadd2c7fbff07052ea4913a9465999f5494962ec29f7f7a3e6cbb993e00d1b881fb31eb1","up":true,"one":"c796d4917dd22d9836a9d7d24ba6f89e1a0e8a78a207bd930991e44e9c80ac1de8e4e1a023d550a6dfa60270fbb3935a7e03ef389c1ccda957a4a6a75ef6819b"},{"other":"af6cb988ddb16202459735b8489c02b3bf829ca301513a0d3e18bbb03d43c8de3cda767c7b5c984a6dce3f118c8089e06b08ed3bd0c922dde9cfe775609df3b2","one":"eeb9d718ef61c14e10ab2fb3a90b039368acd17a59f70628deb39515c227bd0916c796cd7767b1a9d4f38e04f1013173b21c1fa2e0206ecdc72df6c2621380a2","up":true},{"one":"69f3f9fafff951dca2fe98baa178e53f2779311a93fdc364cf4c2477700c8dbce7e4201c3aa6d840b5ae65e8fc9d6603cbc41dbdf601f1998caedee1b542d72b","up":true,"other":"cf03d32d3cca446e7016e7f41267a257bef7142c4f1e4ce2e17678856d75e9889e21972fd21583297a47a156543af15400444dcf37aca64543f97f73734f7f0f"},{"other":"604a11bd1d969886953398ecc1fdf5847a946a8118014d0cb8daff9943f4f78c4bdbad3ee4152959c8265d0588dea658c262fe2f99a55a0b32321b81c8eec473","up":true,"one":"9158b9eb87bf7d011f83febca8f9d6575dd05be1f7e7bc18336f802651a379dd181a0503b5a8e46a580c59889998b16275f1e0ce4dce965cdbe72265ad2be283"},{"other":"aa108a30f86b8296b416ea9fd6bc7a21c65c7cd3911ca3d4ee79325912d80db7150c02d304e49c5d0feafbd222edd6d522661a0983f1d427981760712f31e6f1","one":"9ad5ec0e729f9db10b7028788b58ef13d54bd11529b494a549d0415b90777b63fe78a752356315f5abbd24d849edc0c8bfe9d82c05460c30f4dad860ff5fea48","up":true},{"one":"540598224dccc717053f94e915652df499f513dc0c8874ce999040e1aa829c33ede284c72ddd0b24a319821102fa42aaaaa87380e777b5878455de61f5fc2ac9","up":true,"other":"cf03d32d3cca446e7016e7f41267a257bef7142c4f1e4ce2e17678856d75e9889e21972fd21583297a47a156543af15400444dcf37aca64543f97f73734f7f0f"},{"up":true,"one":"57fb9e7f287fe67500b8b560475c0d0d6eae9d623d5a8c85eb5459f209904a839a0b24ff99a1643a4196a71d45f2ed1bd5e08f9a13cdd9749a907a024ff984dc","other":"850e729f9bbb5ef6e12baf7d3dced180839e88e0845baa7aa8fb87dcb417aa74af5999bda81723aabbef5eda842fa4b5fae107fcff9f6bd50597e8ba6a849dff"},{"one":"e2956a828cb1ff85ab55bdbe329f530662558cb8013ffddacac8ba36096abea07ecb15b54896dd9b4bb0b15155654dbda0c031f69290f2314ac0e376bebbd864","up":true,"other":"2396833be485e50b230a07fddff7f24e11e3fdee3f08f11a287faa2b03b26451b9f4fd24ddefdec62917ae59b6fa56a75e7d6e078b411d624704b88f841b9960"},{"up":true,"one":"e0cacf6abdbfd9a25b9f974600662d4eae484efcdefd0a2a8fbc799127b6fabf2f471aff89c3a08e93ea20be1c304320598ba20a13697a356bf065292ba16bc1","other":"ab3a3ad0481a80b91132cc6afeaab9c9f5e931885d979176e8e6c181d997c38b488e5eca475b0f8e949a8cf128695e18a5851091394d0a33cf834ce7e3537ac2"},{"other":"5a27b90639d515cad7794dae78bf9a9866cca23c5e3e18870524d148797ba1bdfd631151f23062d4dcf0961a7dba709431a44e39da29ed5ea4b0b6987514e433","one":"2396833be485e50b230a07fddff7f24e11e3fdee3f08f11a287faa2b03b26451b9f4fd24ddefdec62917ae59b6fa56a75e7d6e078b411d624704b88f841b9960","up":true},{"one":"f2ac738fa932c90a45d1a64e4a52fd9c4037e2d89ceef1584efef04689bc7aff3a9635fb78dfdf3480d003daf14359190b1cfa8335db438a54107d4060ed58f9","up":true,"other":"6d3bd11f2f7fe855188423bc49be111cd13defeb78a76eb26d415bfc0c86b89e90724db54a12ae7e0c76b9eb12eb456fc50668697245fca00f9ec3c6fb9c8588"},{"one":"82f0cbb87a76dea7947c2c1b6506d05390e5c5e969e5e91651ca10d36cd6aaea72967435ea7e5222d28f1d5e64cc526075d264712e55593bc3b609c93d4fe1eb","up":true,"other":"540598224dccc717053f94e915652df499f513dc0c8874ce999040e1aa829c33ede284c72ddd0b24a319821102fa42aaaaa87380e777b5878455de61f5fc2ac9"},{"up":true,"one":"84379884f012e2cfc1f9838312640576c9ded01ca53cf8451f94915e6949f0084047a2555a5fef4d1b0eef62ad5504a34ff631fbb658b011a07a82a53173f5c1","other":"81df6add458aaaaf51a3ad8826250f3498f06586264f95cd7fce642ac08bd583f463a7531e292175f90887013ba39f8757c21eb5524ec62ec413b82badae935a"},{"one":"334b59c2767fc786551dfdc0a9fcd6f5b53cbe48ddc1ca61b84f8155a15de7e8cd44cbb3a537e1aa7f11416eb710c5de916a5e8ce24e83bfa570b7344c5873ea","up":true,"other":"c49e963a92b93a1c48fd3e38c127bfc88fbcb15b57bfdf8615c0e591b24276d4fe153a811932aefdcf3dee494d53ce354ba052c24313a725d562c6e807ab9133"},{"one":"38469be067f9bba869fdfcc950843e00b5ff950778c11445787501d47cbaf60e9940735a5b8b71d48a0aaee75c8263137169d51944638dc5d1cad398d22439ed","up":true,"other":"2a0fa7932768f0c316b478d15db556626def18462c3bee9446ff16c48fc43b6be1694a5783602b60250e33adc705b86fae7baa6b829146251995fd47980ce422"},{"one":"0e07d2eb15905a583532383cef08b0881878c5043c4d7bae2cf1cace9954bfbbfbe0c1e8322eabbc84bc94cda08ae9b70cbdc56a1b8a19f807bcd5ca7939669d","up":true,"other":"0c000879be78fc867857011e396e2dd77bc2a0c6c2c3624d98b102737aa8d998ca9081653c0c8285117a5288b1bfeed06c54b2f6e39225aca4a21ff2a72116e1"},{"up":true,"one":"ac6057677fdfc132ea2418ff877357962771db049d169ba2c1923b15820385c6bf2f5846943d44a73bfdeb44a1e0d68307003a06cb0f694705879f8a720c3296","other":"c4dfcf348694971fb36ed91e9024302bec8df3891540cbe1f5df26eee9c1f81a95295f05b90ec30dd044a0355dcaa805b9f50e95f38e5588a929cfe10e8cd73d"},{"up":true,"one":"53031cddf4390ba176d638456016028bd4538879c7eaba672c3ef70208319a14e6a41dea8ff003b6f7e9b4a83ca12dab50d4f44f079153bec7c24221e311573e","other":"334b59c2767fc786551dfdc0a9fcd6f5b53cbe48ddc1ca61b84f8155a15de7e8cd44cbb3a537e1aa7f11416eb710c5de916a5e8ce24e83bfa570b7344c5873ea"},{"other":"53031cddf4390ba176d638456016028bd4538879c7eaba672c3ef70208319a14e6a41dea8ff003b6f7e9b4a83ca12dab50d4f44f079153bec7c24221e311573e","up":true,"one":"faa3c31521c8f7b9d15838750e7e311eb0f01db5ef22cd1bf62a7d72e7efdf5a575550c930d96230edc892d107d4551e95b099d3c952a7f1c0ad3b5967c7831b"},{"other":"11170a0fb9f6b037f8ee4494e935a84b06816ff5c44ef9d613920f9c58f8b25611b2093da3fb51a59687db6a9b0a070386cac09757a27f75754cbdcb9afc2225","up":true,"one":"57533c56642895edba91473a966b6abf765725a721dec947e4bac4728dfbed265435aefca55fff69cae48c9d506064fbb890665a0acd87c466707d08d1e6e1f4"},{"other":"540598224dccc717053f94e915652df499f513dc0c8874ce999040e1aa829c33ede284c72ddd0b24a319821102fa42aaaaa87380e777b5878455de61f5fc2ac9","one":"9b3fecfc63256a9d69e75ccb5119b2866e30fa4516b3a3bf5b2f03f04f1d20de786ddb90fa2acadb2a0509503b21fc9d16238c57f9b102ceedb6b27ee1b2c4ea","up":true},{"up":true,"one":"932e926c54a4127210a15731fa4ad6bbfd0d69183b894b676920843f154ad1e4148b674d234f070e9dc07547394a5af973befe0fc170bbe44346d69e135e0157","other":"ed3a5d7602b59bd8709ef10cb84e4b5644a69490d1173a8b9135adba04b36c1fcd0f16543de39deff0e76d8314e6884ba939213f77abb8d50a68d030352cb495"},{"other":"c4dfcf348694971fb36ed91e9024302bec8df3891540cbe1f5df26eee9c1f81a95295f05b90ec30dd044a0355dcaa805b9f50e95f38e5588a929cfe10e8cd73d","one":"49bd2289f479c9ad7e0d13319271b9be1e1dcbee28313513a124dec55f9842db639e62a74a83040930c537739ab7fa1e50bb05b9ab0f588d6da7b64a6451f466","up":true},{"one":"cf03d32d3cca446e7016e7f41267a257bef7142c4f1e4ce2e17678856d75e9889e21972fd21583297a47a156543af15400444dcf37aca64543f97f73734f7f0f","up":true,"other":"9158b9eb87bf7d011f83febca8f9d6575dd05be1f7e7bc18336f802651a379dd181a0503b5a8e46a580c59889998b16275f1e0ce4dce965cdbe72265ad2be283"},{"up":true,"one":"fd321c630fadcc8d6b00589323f7313ac1e94effbe8192955da5f88dcf419ef28820075e0e81c595561ff6ee58cfce23079407edf8b1611cb994946bcbd26364","other":"932e926c54a4127210a15731fa4ad6bbfd0d69183b894b676920843f154ad1e4148b674d234f070e9dc07547394a5af973befe0fc170bbe44346d69e135e0157"},{"other":"123633b35f455fc3240d99929dc3130bb018545672be151ba973915f2ab6e6c862748f60d917e48ccbf28620c4e58b888867cb51e12ec0d2e5c61cef82258719","one":"d6f274a2f20831a1b2281d889f46ad44f1bc5a07bb2152c89e129afb1c1e643b608621791a9d15a28da022d57b8bc3c05a7da0b5a93201dd714179e4a6a29a8b","up":true},{"other":"2396833be485e50b230a07fddff7f24e11e3fdee3f08f11a287faa2b03b26451b9f4fd24ddefdec62917ae59b6fa56a75e7d6e078b411d624704b88f841b9960","one":"7e9a81d06e997a691cc7790d358868b8657db608795ef6b85bb194db7f56ab5c76cac3be0b40d847ce873aeef4bdad40b725d69f4c42755b9d5aab4fe7aecb34","up":true},{"up":true,"one":"255939ef32bd3e5e76181763c11707b9ff4ab26d3ffb10f06fa7249b06721fa3decfa9eee3eeb8b12d6218af5f9ed8872d62c42a90cd46dcbef3d89a8163ae07","other":"cc0d13dba120558dc8e2d0e5ac755a712e7e7e6dab6edcaf658faf02537b1efe3d6c54d6e67566eb4a3a8f8a019702aa7ee2b33ee3f0316a01e7b17845032e70"},{"up":true,"one":"7172a86afb608acd9a3e1e5c0472489ebecb516cad6796fa9a06ab47cc8e8cce12dddce72f0ac3b0927602bd22ed5872c3b5ce9b6af96f8e9d1d75078cc9bb55","other":"e706876f36646bfb2dfbd11669a4907432660023a13be9de329a03f6c6e88e3788002b83d0cb4617e6c4096998783925be5b1de4f0edd8128e7d71312fb1091d"},{"other":"854ff45571c01cd49d0932bcb361eef13202ababf48f0b8e5d8143dc41e01609aa1539e926bad9b4ca8add023fd259eb70239103d75b0a404bb338f3e4bf9577","one":"e20a90f36eca4329d3d2dbadf530949889dc20b0ae5d96b935af9b60d26ec507e9eb1b73fd2b4dc88057c20e4ef6e7039cc49652d35c563db64f06f979e28540","up":true},{"other":"35ac328e13ea4fc6c333591633455cb6a2dff124528a17668770e231582ea31ab95e083cd191d8c45369d88366e9df0d2417cd26efbf2f616139c92fd497cd48","one":"0bf28b481d71062ee100d6cb04c8b4234a574f8657e2d3c49b60a9ecdbf486d0ec38b33bce745c8efe820145d5c53ea802aa64b4f9bce19b029ee5b2f9de43f1","up":true},{"up":true,"one":"c133cd3ee228f427410357f46752d33ecf302475314411772df3532669a8b220136c09f00717460c39bcea1058cb988dd223875ec991612876b400556f5937dd","other":"e2956a828cb1ff85ab55bdbe329f530662558cb8013ffddacac8ba36096abea07ecb15b54896dd9b4bb0b15155654dbda0c031f69290f2314ac0e376bebbd864"},{"up":true,"one":"f394aaa6d14c6ed95e2ad4651b5103bb1ab9f3a61839936cc1f08d6a6e53504e5d15dfc5211539ffdbdc64912ded5c2272d4af52ed8d7fe5a3c228eb12f0c68b","other":"eb6fa7d39fcee5a7081813169ae24ee6d355cfe717dcb2fa500a07c935ffbe1b12378ea13454742bf7c2df10ad2fd4e53476068eaef4669381c8cd060c199e11"},{"one":"e3779b202b9cfe7b2f2cc9e95974ac77bf51ba951f775acc10f07249ee6b3b260f2b012bb010a7f9794c5562e9b00f18b52c25c1e350ab70afc6bf9e210e4969","up":true,"other":"2a0fa7932768f0c316b478d15db556626def18462c3bee9446ff16c48fc43b6be1694a5783602b60250e33adc705b86fae7baa6b829146251995fd47980ce422"},{"other":"84379884f012e2cfc1f9838312640576c9ded01ca53cf8451f94915e6949f0084047a2555a5fef4d1b0eef62ad5504a34ff631fbb658b011a07a82a53173f5c1","one":"4f4201d959e4add3a4bcf3cbaab29d8abcc7530a9834e3cde45c4459ea92fba869e65156037a8fae02eac05f6174a7f2c1d825418f2207caa2284bcc9d9b84d1","up":true},{"other":"a089758c25ca0730f13cd18c10aeea62488c1c2651eef53a8ad11cfdfa61ce8f7354a53bd6902da26b79dfbedc78d315b1d4239eb62cbca59215727b2ac35213","one":"d33f82b6a46535e798b78ebb28047ece1ef3b696ab29726d283161c377ed17a735a0948b99d83dee2af71704001e2e13813854a1b0ef4fcefd3c0e5c5f6e720d","up":true},{"other":"f8fd12d8b5872b74e2cfa60d6a3a25b568a1fb4be3a8d06faac02a38321f419c443e517c0e2989001635f827add1859a2dc9589a9c0f5bf3804d46f43f799116","up":true,"one":"519ce8f43529d0c703ef4faf50450877dc2818fd6fd6b7faaa9bbbaeac373e499d1b4a17b387b1a8d35e8042e18a9d3d365c97254b4d24352b10e8de9219a5cd"},{"other":"f8fd12d8b5872b74e2cfa60d6a3a25b568a1fb4be3a8d06faac02a38321f419c443e517c0e2989001635f827add1859a2dc9589a9c0f5bf3804d46f43f799116","one":"59fe05843cc637adac3728acb8ca9650f49050095cf5d32241366f54d4ac7179b16dcb009e2fb9fa9499cc6f8b865b6c4d6fe6e35500df10ba5daa719d57976e","up":true},{"other":"123633b35f455fc3240d99929dc3130bb018545672be151ba973915f2ab6e6c862748f60d917e48ccbf28620c4e58b888867cb51e12ec0d2e5c61cef82258719","up":true,"one":"3db9984cb1e25bdc30c483f3d4c036fb1728bafffecd2b965af7e701569c28116dbed2e5892504ea9927c14570351b03cb99112a5924a27e6e03289422785c7b"},{"up":true,"one":"b1bef03357528618be6936a7edae5e3d4ecc942d43bd301642d321a73a07f3327d413f923c3fdd49d04f311e18709a4dde7519722d7a4912f181aa4df2e60173","other":"af6cb988ddb16202459735b8489c02b3bf829ca301513a0d3e18bbb03d43c8de3cda767c7b5c984a6dce3f118c8089e06b08ed3bd0c922dde9cfe775609df3b2"},{"one":"7ca32d24c001557a81af351ac71322543154eeedbb6ccdd8b8b142f19215aa712218babe9701e73a6441784375a511c1f16a70569b73416f9708409564d18485","up":true,"other":"071c094246a0ca4b5d169e43a20ce5da508e579a6e2e822462bd8948ab357d46ab477bcff0c80eba2e01f0c100690b307af40d47c52ebad06783e9e77466cbd6"},{"one":"a2719942ffb6e99bda131cdedb612785dafdf72f5f35824343ad39d8568d6cd25e44b585a915c8e9ea2b02e6fd38c105bb17ed27c8fa320f18c83e0ace78feb5","up":true,"other":"932e926c54a4127210a15731fa4ad6bbfd0d69183b894b676920843f154ad1e4148b674d234f070e9dc07547394a5af973befe0fc170bbe44346d69e135e0157"},{"other":"de7ab7b9a2ba4ed523b84233fae11d93815579976ea78b385c658a4c156622747051f91342f9ac3610e22ee259b65e02b5af0ab67a9ee04ab6958a9d0d8acdf1","up":true,"one":"3dcf5ec3ebb3b7de61dfaef4ee397a4a13a96ee40673be2eaadfcadd11f139c594c74237b40dd9c10f059f40d325c014f5b02b3a8eb7f0dc7d66ced7fea9f17f"},{"other":"66652e041752f4acb27bc45c9c8b58f4f4ea904345a887a49ae831bef3bb1ad26cff7fd0f66ef3c28d6c41e039e39ff983710fdd5384f849595a66e5509e0d10","one":"af761f8d13059f1e49d2f5c0b7a76a5eb5bcaab1e7ff01673dff3967d81bd7aebf74afef3934328034c82f131fa066de71816cff8f720e0c56d5e85b233a8a44","up":true},{"one":"ad177f2702ed11d531b11fd0250f2dab2364624680cfb6ff1fba5b27dcd8334269a5bc9093401389044c0b00ed0cbf6f166aba81a58cadd34b25355839fff6ac","up":true,"other":"f87c2dea026ba5e6cda9a446821bf057d3453fa8c9b38fd882a09979ff3cfe2b8adfcbd5cf28d268776414bd12a9aba385d5c97c76a29c1b0625b101faac761d"},{"one":"96f3194c9ef17f60c318be14dd72c51af0aebc19f7a574b769d18b1fda6791409c827892bae3a061800e3d78af88a97635a0a892c54d7ebb38342ab1ba99c3ad","up":true,"other":"123633b35f455fc3240d99929dc3130bb018545672be151ba973915f2ab6e6c862748f60d917e48ccbf28620c4e58b888867cb51e12ec0d2e5c61cef82258719"},{"one":"5a59a44ba2bf5e77f921216ac467733c8529b06790efb05a63c410060edaf65547a2dbb37333073e3bcf68d422ba4b135432307f90394c6edd6dd33dd6ff2152","up":true,"other":"854ff45571c01cd49d0932bcb361eef13202ababf48f0b8e5d8143dc41e01609aa1539e926bad9b4ca8add023fd259eb70239103d75b0a404bb338f3e4bf9577"},{"up":true,"one":"df7decc6bb0d51afdc0c445a15be31b0e89c79a52b8a2cc789b585d94db63f064eccc1d8340d13d5e43ed7cbe95db8ad10ee7294dbd4c7629686564bb3a603b2","other":"540598224dccc717053f94e915652df499f513dc0c8874ce999040e1aa829c33ede284c72ddd0b24a319821102fa42aaaaa87380e777b5878455de61f5fc2ac9"},{"other":"cc0d13dba120558dc8e2d0e5ac755a712e7e7e6dab6edcaf658faf02537b1efe3d6c54d6e67566eb4a3a8f8a019702aa7ee2b33ee3f0316a01e7b17845032e70","one":"a8b619f75e0e4cf7bc5e425ff9b03e55b7301fec4fb58f321bf89811678268d9f738bbf22ee36c2d14ff71a08d6f7dca28249ff6f943cc5a77653f482254d150","up":true},{"one":"11170a0fb9f6b037f8ee4494e935a84b06816ff5c44ef9d613920f9c58f8b25611b2093da3fb51a59687db6a9b0a070386cac09757a27f75754cbdcb9afc2225","up":true,"other":"e90ca22b959d482861c52e9e51fd2d63557453dce64dab9f66fcf323273c12e7189358f85d500f5200ff7c7b2d57afe72577ed9aa2adb36fc0c8e5504588fe94"},{"other":"49bd2289f479c9ad7e0d13319271b9be1e1dcbee28313513a124dec55f9842db639e62a74a83040930c537739ab7fa1e50bb05b9ab0f588d6da7b64a6451f466","one":"1cc62520c0d9c6a47d96e485bdc6a5d0f7319477ad6d177663f7b49217f5a8e56e4717f36fb5aa11c5270d4383cab460219821bcc6c9cbcccc4a97446b406d96","up":true},{"other":"604a11bd1d969886953398ecc1fdf5847a946a8118014d0cb8daff9943f4f78c4bdbad3ee4152959c8265d0588dea658c262fe2f99a55a0b32321b81c8eec473","one":"aa108a30f86b8296b416ea9fd6bc7a21c65c7cd3911ca3d4ee79325912d80db7150c02d304e49c5d0feafbd222edd6d522661a0983f1d427981760712f31e6f1","up":true},{"other":"64a39acfb1accea032dfc4d1530b5cdbdc8c1b609a442b68a9b534a539062d051b750a4512b0a9d504fdffa2a5bc8d4fcb6ca59f4ddb1c59ce62e8913644499b","up":true,"one":"55beb7853107501c013283d0114f9812c2e97b292f90ae9bdd5aa8189d0379a758cbf19c5fa62436bc75a6e30d935a3bd52025b06efd167fa2fb8a1caead2f83"},{"up":true,"one":"81df6add458aaaaf51a3ad8826250f3498f06586264f95cd7fce642ac08bd583f463a7531e292175f90887013ba39f8757c21eb5524ec62ec413b82badae935a","other":"09fa1e69f37cb14db3dd721a9c4b9c884f6fe519d850f7af3643ecd536d4b3e995f99acf569e23b7864996c750115ff0ca0bd446ebfd76a026da71da0b95fd97"},{"one":"6070dc131e9721a4a496b3ed6ff5c9db1a5351e942ed424b86fe6be940d1012df766afb4b0112452dfd63e0fcfea13658324a9ef4a94b5754ec9f6219e4b0d67","up":true,"other":"d6f274a2f20831a1b2281d889f46ad44f1bc5a07bb2152c89e129afb1c1e643b608621791a9d15a28da022d57b8bc3c05a7da0b5a93201dd714179e4a6a29a8b"},{"one":"ab3a3ad0481a80b91132cc6afeaab9c9f5e931885d979176e8e6c181d997c38b488e5eca475b0f8e949a8cf128695e18a5851091394d0a33cf834ce7e3537ac2","up":true,"other":"57533c56642895edba91473a966b6abf765725a721dec947e4bac4728dfbed265435aefca55fff69cae48c9d506064fbb890665a0acd87c466707d08d1e6e1f4"},{"other":"e0cacf6abdbfd9a25b9f974600662d4eae484efcdefd0a2a8fbc799127b6fabf2f471aff89c3a08e93ea20be1c304320598ba20a13697a356bf065292ba16bc1","up":true,"one":"854ff45571c01cd49d0932bcb361eef13202ababf48f0b8e5d8143dc41e01609aa1539e926bad9b4ca8add023fd259eb70239103d75b0a404bb338f3e4bf9577"},{"one":"06a8a25c6dd90e230237b06c086f14e539b31b8e3705752d0ad8faf1bd7239547332604b79b6124cbd0cee495b99a80f147983142b7271841d8d9fa85d559301","up":true,"other":"f2ac738fa932c90a45d1a64e4a52fd9c4037e2d89ceef1584efef04689bc7aff3a9635fb78dfdf3480d003daf14359190b1cfa8335db438a54107d4060ed58f9"},{"other":"e90ca22b959d482861c52e9e51fd2d63557453dce64dab9f66fcf323273c12e7189358f85d500f5200ff7c7b2d57afe72577ed9aa2adb36fc0c8e5504588fe94","one":"f8fd12d8b5872b74e2cfa60d6a3a25b568a1fb4be3a8d06faac02a38321f419c443e517c0e2989001635f827add1859a2dc9589a9c0f5bf3804d46f43f799116","up":true},{"other":"a8b619f75e0e4cf7bc5e425ff9b03e55b7301fec4fb58f321bf89811678268d9f738bbf22ee36c2d14ff71a08d6f7dca28249ff6f943cc5a77653f482254d150","one":"3bf838b4d29d9388a24d160eee6bf8ea017af6cd9e5f7d88b4cae71ebfbc304666d3d634a05e0a75570dafe8f41871090fcff8b651a9130d013786dfcca3da14","up":true},{"one":"e90ca22b959d482861c52e9e51fd2d63557453dce64dab9f66fcf323273c12e7189358f85d500f5200ff7c7b2d57afe72577ed9aa2adb36fc0c8e5504588fe94","up":true,"other":"57533c56642895edba91473a966b6abf765725a721dec947e4bac4728dfbed265435aefca55fff69cae48c9d506064fbb890665a0acd87c466707d08d1e6e1f4"},{"other":"57fb9e7f287fe67500b8b560475c0d0d6eae9d623d5a8c85eb5459f209904a839a0b24ff99a1643a4196a71d45f2ed1bd5e08f9a13cdd9749a907a024ff984dc","up":true,"one":"bebbde654a4f3e3e65f63d10cbcc89dfd46ce75945c19be33bfe4d954c8ed375981e21a8376ad10e402dddbcf3b657e6786c0820e599a0d1fe03f8d35294d7c7"},{"other":"a5990a680e1f01dcd71a178a239880c5ce24418748c368b8e3c8a1175cfd744d16973cba03e5e756820950920a6d9fa5d5dd53829a1d1d508371cb1042e9453e","up":true,"one":"071c094246a0ca4b5d169e43a20ce5da508e579a6e2e822462bd8948ab357d46ab477bcff0c80eba2e01f0c100690b307af40d47c52ebad06783e9e77466cbd6"},{"one":"f4ae36400caeddcbcf0fb1abd5b9611c37bac683645d10c69a1ac54d366f730c59917c95e990a0fa6bb2679c98fb62bf0e29bd7812ab57375de35f469dab98a0","up":true,"other":"c49e963a92b93a1c48fd3e38c127bfc88fbcb15b57bfdf8615c0e591b24276d4fe153a811932aefdcf3dee494d53ce354ba052c24313a725d562c6e807ab9133"},{"one":"66652e041752f4acb27bc45c9c8b58f4f4ea904345a887a49ae831bef3bb1ad26cff7fd0f66ef3c28d6c41e039e39ff983710fdd5384f849595a66e5509e0d10","up":true,"other":"464cf4c4203246240a63965062b9e5a7e5fa903f127b1f5ea5b37a27d33d8b12768fc2d8f257e67418f1e5765e627ca8f8cd5ba6b15b8a047490d26ce43e6291"},{"other":"84379884f012e2cfc1f9838312640576c9ded01ca53cf8451f94915e6949f0084047a2555a5fef4d1b0eef62ad5504a34ff631fbb658b011a07a82a53173f5c1","up":true,"one":"6ba8900830489793a22bf5023cde4ab849dee525d1ca5b95e21040a8e8be5b295317b1c76e09beb7d17a9512137c487b99f16933622b5f2b0e10da3233086bbf"},{"other":"464cf4c4203246240a63965062b9e5a7e5fa903f127b1f5ea5b37a27d33d8b12768fc2d8f257e67418f1e5765e627ca8f8cd5ba6b15b8a047490d26ce43e6291","up":true,"one":"7625a1a0a0f5bf78e2b9fe43a1215ea882318458b886ec767ccbc35e76b543f96820b364342b28ff600302af7716280497141dc2fc84e83cb15f5eb3d268d73e"},{"other":"0d85f39dca79f99b277ad5cedfcd3fb1eccc7862c95c215ba0d5a2ec1c4fa80244393d0934cf59fe988f7716bf15cb8e79f4ee03fbe4a48a10cac6e0610f9d55","up":true,"one":"d2cf35afdb846755290a7c3a1a36758e735a4eeed57b1af66595c55ab45c52cf2c478de3f395b38513cdc9e49568892cce490de93074fa45b640628f0fe40719"},{"one":"a13086041114db2be31038987ac3fdcaeb99489f1b6ee9b22998b9e66dc2f2f024307d9474811e7e8be1b1acf5a55305d5cce27d87fb834ed1e1d2e17319bb85","up":true,"other":"519ce8f43529d0c703ef4faf50450877dc2818fd6fd6b7faaa9bbbaeac373e499d1b4a17b387b1a8d35e8042e18a9d3d365c97254b4d24352b10e8de9219a5cd"},{"one":"54b79d3662ba486bbd120313d59ef101acf963eb3d6112a9dda121bc0b52f4b1fbcb13406705cdd8c2d3990ad296171c7972211467cc0d44cbe9ca16fbc82e3e","up":true,"other":"a13086041114db2be31038987ac3fdcaeb99489f1b6ee9b22998b9e66dc2f2f024307d9474811e7e8be1b1acf5a55305d5cce27d87fb834ed1e1d2e17319bb85"},{"other":"d2cf35afdb846755290a7c3a1a36758e735a4eeed57b1af66595c55ab45c52cf2c478de3f395b38513cdc9e49568892cce490de93074fa45b640628f0fe40719","up":true,"one":"b949f482891fff7d7d1f0d84112db7080fa1df07cd4e52ee0fadb707a4b7903fc0da9fe45b7ceee37948856687f8e7768945295de15691a99c879f1816899d98"},{"other":"0c000879be78fc867857011e396e2dd77bc2a0c6c2c3624d98b102737aa8d998ca9081653c0c8285117a5288b1bfeed06c54b2f6e39225aca4a21ff2a72116e1","up":true,"one":"a16326a0c540731e0964c4bc10c1342346fcfee70c7d1d8d333cbb774cb9f49dbf92585595654c99253eac21373706247bf5ef1ba40ac03e62da00821991cf7d"},{"one":"cc0d13dba120558dc8e2d0e5ac755a712e7e7e6dab6edcaf658faf02537b1efe3d6c54d6e67566eb4a3a8f8a019702aa7ee2b33ee3f0316a01e7b17845032e70","up":true,"other":"e2956a828cb1ff85ab55bdbe329f530662558cb8013ffddacac8ba36096abea07ecb15b54896dd9b4bb0b15155654dbda0c031f69290f2314ac0e376bebbd864"},{"one":"2a0fa7932768f0c316b478d15db556626def18462c3bee9446ff16c48fc43b6be1694a5783602b60250e33adc705b86fae7baa6b829146251995fd47980ce422","up":true,"other":"604a11bd1d969886953398ecc1fdf5847a946a8118014d0cb8daff9943f4f78c4bdbad3ee4152959c8265d0588dea658c262fe2f99a55a0b32321b81c8eec473"},{"other":"a089758c25ca0730f13cd18c10aeea62488c1c2651eef53a8ad11cfdfa61ce8f7354a53bd6902da26b79dfbedc78d315b1d4239eb62cbca59215727b2ac35213","one":"c796d4917dd22d9836a9d7d24ba6f89e1a0e8a78a207bd930991e44e9c80ac1de8e4e1a023d550a6dfa60270fbb3935a7e03ef389c1ccda957a4a6a75ef6819b","up":true},{"up":true,"one":"55beb7853107501c013283d0114f9812c2e97b292f90ae9bdd5aa8189d0379a758cbf19c5fa62436bc75a6e30d935a3bd52025b06efd167fa2fb8a1caead2f83","other":"6ba8900830489793a22bf5023cde4ab849dee525d1ca5b95e21040a8e8be5b295317b1c76e09beb7d17a9512137c487b99f16933622b5f2b0e10da3233086bbf"},{"up":true,"one":"b737c81fe6bc50d977231a5fc8856f064ba58190c5ab5615d3cf634aea8c15a308f3a667aad2e69d5c1438549cd41c863fd40f643b70caf3e0c934276ef2a84f","other":"a4dd67ab4fff1a50968c7ab59c304eb0083b072fc13dff599eeadac4e0e75099f7c825f91dd1bb770f3ae6f3d1d82ad574d6ecb117adf1ca9ccbccd01303ec7c"},{"other":"64a39acfb1accea032dfc4d1530b5cdbdc8c1b609a442b68a9b534a539062d051b750a4512b0a9d504fdffa2a5bc8d4fcb6ca59f4ddb1c59ce62e8913644499b","one":"de7ab7b9a2ba4ed523b84233fae11d93815579976ea78b385c658a4c156622747051f91342f9ac3610e22ee259b65e02b5af0ab67a9ee04ab6958a9d0d8acdf1","up":true},{"other":"f87c2dea026ba5e6cda9a446821bf057d3453fa8c9b38fd882a09979ff3cfe2b8adfcbd5cf28d268776414bd12a9aba385d5c97c76a29c1b0625b101faac761d","one":"464cf4c4203246240a63965062b9e5a7e5fa903f127b1f5ea5b37a27d33d8b12768fc2d8f257e67418f1e5765e627ca8f8cd5ba6b15b8a047490d26ce43e6291","up":true},{"up":true,"one":"09fa1e69f37cb14db3dd721a9c4b9c884f6fe519d850f7af3643ecd536d4b3e995f99acf569e23b7864996c750115ff0ca0bd446ebfd76a026da71da0b95fd97","other":"f78ecf420b73cd0245807157c0cbaaa568c60c80965413e187b084fb26041761d12790c0cb6a39bc8997fd2b3d3f52c831e601f1f1846945fba1808b0e1cdf25"},{"one":"f3bf16c7156ce55af92b2fc21826bdfd3e1f245c6087e76f5eb23cc8bbd88b25515a32029d3e6e2b4a27354606e9e3bdfe78788e326c4349d63416894fcfbaf4","up":true,"other":"071c094246a0ca4b5d169e43a20ce5da508e579a6e2e822462bd8948ab357d46ab477bcff0c80eba2e01f0c100690b307af40d47c52ebad06783e9e77466cbd6"},{"other":"e2956a828cb1ff85ab55bdbe329f530662558cb8013ffddacac8ba36096abea07ecb15b54896dd9b4bb0b15155654dbda0c031f69290f2314ac0e376bebbd864","up":true,"one":"fb20c708420e60c48fa65980ae11adc8cdf9b56ab93044a9aee9b5196d52f29e6cb2c218f73fefbdaecf8177bae1d9d13dd64bbe06e631555715b93f58f47137"},{"up":true,"one":"9158b9eb87bf7d011f83febca8f9d6575dd05be1f7e7bc18336f802651a379dd181a0503b5a8e46a580c59889998b16275f1e0ce4dce965cdbe72265ad2be283","other":"0e07d2eb15905a583532383cef08b0881878c5043c4d7bae2cf1cace9954bfbbfbe0c1e8322eabbc84bc94cda08ae9b70cbdc56a1b8a19f807bcd5ca7939669d"},{"one":"a5990a680e1f01dcd71a178a239880c5ce24418748c368b8e3c8a1175cfd744d16973cba03e5e756820950920a6d9fa5d5dd53829a1d1d508371cb1042e9453e","up":true,"other":"4903cd53b3ffc4328547e03dec8f7992edbfb1e1697e53772ef79887984b11595167eb84015ff3dfb26ac0d7b2e98b7a0792bef843d2bdff3a76889fc4a6c60a"},{"one":"f78ecf420b73cd0245807157c0cbaaa568c60c80965413e187b084fb26041761d12790c0cb6a39bc8997fd2b3d3f52c831e601f1f1846945fba1808b0e1cdf25","up":true,"other":"dee5fb5ccdfe3803cab3e0041c5c4879001bf2c2233446f47245d8234642046269bfe50e414cd2d89341e338597f2ecbb7b2912c20558a85041b757a24490805"},{"up":true,"one":"41ded7596eac3eddfd1f7656ef23adabe1d18027f6159e45867e935d1ab742ec298ba2b23df522f79f59c7805510d8c995837380432dee37912d6ede1196caa2","other":"f87c2dea026ba5e6cda9a446821bf057d3453fa8c9b38fd882a09979ff3cfe2b8adfcbd5cf28d268776414bd12a9aba385d5c97c76a29c1b0625b101faac761d"},{"one":"f8fd12d8b5872b74e2cfa60d6a3a25b568a1fb4be3a8d06faac02a38321f419c443e517c0e2989001635f827add1859a2dc9589a9c0f5bf3804d46f43f799116","up":true,"other":"a5990a680e1f01dcd71a178a239880c5ce24418748c368b8e3c8a1175cfd744d16973cba03e5e756820950920a6d9fa5d5dd53829a1d1d508371cb1042e9453e"},{"one":"dee5fb5ccdfe3803cab3e0041c5c4879001bf2c2233446f47245d8234642046269bfe50e414cd2d89341e338597f2ecbb7b2912c20558a85041b757a24490805","up":true,"other":"f8fd12d8b5872b74e2cfa60d6a3a25b568a1fb4be3a8d06faac02a38321f419c443e517c0e2989001635f827add1859a2dc9589a9c0f5bf3804d46f43f799116"},{"other":"464cf4c4203246240a63965062b9e5a7e5fa903f127b1f5ea5b37a27d33d8b12768fc2d8f257e67418f1e5765e627ca8f8cd5ba6b15b8a047490d26ce43e6291","up":true,"one":"4f4201d959e4add3a4bcf3cbaab29d8abcc7530a9834e3cde45c4459ea92fba869e65156037a8fae02eac05f6174a7f2c1d825418f2207caa2284bcc9d9b84d1"},{"up":true,"one":"eeb9d718ef61c14e10ab2fb3a90b039368acd17a59f70628deb39515c227bd0916c796cd7767b1a9d4f38e04f1013173b21c1fa2e0206ecdc72df6c2621380a2","other":"236266f9f5a28148d11bed1195a91cd1d30231b082697ee1940a85abca98d2ff0767be9128c23375caa0444bcf51d8501879200ea0f27f13d0ede37f97241325"},{"other":"9b3fecfc63256a9d69e75ccb5119b2866e30fa4516b3a3bf5b2f03f04f1d20de786ddb90fa2acadb2a0509503b21fc9d16238c57f9b102ceedb6b27ee1b2c4ea","one":"df7decc6bb0d51afdc0c445a15be31b0e89c79a52b8a2cc789b585d94db63f064eccc1d8340d13d5e43ed7cbe95db8ad10ee7294dbd4c7629686564bb3a603b2","up":true},{"other":"4f4201d959e4add3a4bcf3cbaab29d8abcc7530a9834e3cde45c4459ea92fba869e65156037a8fae02eac05f6174a7f2c1d825418f2207caa2284bcc9d9b84d1","up":true,"one":"193ca2ef8a4ac98c0300d7e48421ba3fe5d4789a0c2b476499bd093808c3988b4a55742ff3f607429cafda08cbbb5fba68da8869747b1b5169f3e4545497de3a"},{"other":"55beb7853107501c013283d0114f9812c2e97b292f90ae9bdd5aa8189d0379a758cbf19c5fa62436bc75a6e30d935a3bd52025b06efd167fa2fb8a1caead2f83","one":"3dcf5ec3ebb3b7de61dfaef4ee397a4a13a96ee40673be2eaadfcadd11f139c594c74237b40dd9c10f059f40d325c014f5b02b3a8eb7f0dc7d66ced7fea9f17f","up":true},{"up":true,"one":"ef3016ea5a7b1b57388904d5c80fd05780d23acec8cf73e8add28ea99c6222fa84e89a1752186a2ef41dd0ec828405e61a1e8fd67d9496d75525ed860b12e2e8","other":"2a0fa7932768f0c316b478d15db556626def18462c3bee9446ff16c48fc43b6be1694a5783602b60250e33adc705b86fae7baa6b829146251995fd47980ce422"},{"one":"9ad5ec0e729f9db10b7028788b58ef13d54bd11529b494a549d0415b90777b63fe78a752356315f5abbd24d849edc0c8bfe9d82c05460c30f4dad860ff5fea48","up":true,"other":"5a27b90639d515cad7794dae78bf9a9866cca23c5e3e18870524d148797ba1bdfd631151f23062d4dcf0961a7dba709431a44e39da29ed5ea4b0b6987514e433"},{"other":"df7decc6bb0d51afdc0c445a15be31b0e89c79a52b8a2cc789b585d94db63f064eccc1d8340d13d5e43ed7cbe95db8ad10ee7294dbd4c7629686564bb3a603b2","up":true,"one":"a1b07c24605e258db7b8fb15db227596b08dc69bb234c0a48c312eb6eb1fb08553f8c8a6da7175eea258e2d3f2625a540c1466e6c31315aa1484fa173b7a8cfc"},{"other":"ac6057677fdfc132ea2418ff877357962771db049d169ba2c1923b15820385c6bf2f5846943d44a73bfdeb44a1e0d68307003a06cb0f694705879f8a720c3296","one":"f87c2dea026ba5e6cda9a446821bf057d3453fa8c9b38fd882a09979ff3cfe2b8adfcbd5cf28d268776414bd12a9aba385d5c97c76a29c1b0625b101faac761d","up":true},{"other":"82f0cbb87a76dea7947c2c1b6506d05390e5c5e969e5e91651ca10d36cd6aaea72967435ea7e5222d28f1d5e64cc526075d264712e55593bc3b609c93d4fe1eb","one":"c708e3584cd9450b30d8cdd960a676884f64364c2aec985eebb4a0d745f6c73b6b0cb16f330bf090320bc48a5a67e8519b3c2c4a64cf2eff9aa4f1fc0b274a00","up":true},{"other":"0c000879be78fc867857011e396e2dd77bc2a0c6c2c3624d98b102737aa8d998ca9081653c0c8285117a5288b1bfeed06c54b2f6e39225aca4a21ff2a72116e1","one":"57fb9e7f287fe67500b8b560475c0d0d6eae9d623d5a8c85eb5459f209904a839a0b24ff99a1643a4196a71d45f2ed1bd5e08f9a13cdd9749a907a024ff984dc","up":true},{"other":"9b3fecfc63256a9d69e75ccb5119b2866e30fa4516b3a3bf5b2f03f04f1d20de786ddb90fa2acadb2a0509503b21fc9d16238c57f9b102ceedb6b27ee1b2c4ea","one":"cf03d32d3cca446e7016e7f41267a257bef7142c4f1e4ce2e17678856d75e9889e21972fd21583297a47a156543af15400444dcf37aca64543f97f73734f7f0f","up":true},{"other":"b737c81fe6bc50d977231a5fc8856f064ba58190c5ab5615d3cf634aea8c15a308f3a667aad2e69d5c1438549cd41c863fd40f643b70caf3e0c934276ef2a84f","up":true,"one":"d6c3095290d455c3855cfa88ee5f10d1975fdb0cc7ebc9aaa2330658e4229b9850f70f17798e530b50907d3d0d27fa49c0ed7dd4a7913d53c6881c5c86f380b8"},{"one":"a302bebe4590b3f6d2c511919ceef4a5a80d431f53f8f3483c4b833a6a3b5f79b4c66c0ce2c0e5bc696534067ea5cd07772a9844ee0ba9d37a2e6f5d4bfb05cd","up":true,"other":"53031cddf4390ba176d638456016028bd4538879c7eaba672c3ef70208319a14e6a41dea8ff003b6f7e9b4a83ca12dab50d4f44f079153bec7c24221e311573e"},{"other":"c133cd3ee228f427410357f46752d33ecf302475314411772df3532669a8b220136c09f00717460c39bcea1058cb988dd223875ec991612876b400556f5937dd","one":"aa108a30f86b8296b416ea9fd6bc7a21c65c7cd3911ca3d4ee79325912d80db7150c02d304e49c5d0feafbd222edd6d522661a0983f1d427981760712f31e6f1","up":true},{"other":"b949f482891fff7d7d1f0d84112db7080fa1df07cd4e52ee0fadb707a4b7903fc0da9fe45b7ceee37948856687f8e7768945295de15691a99c879f1816899d98","up":true,"one":"0d85f39dca79f99b277ad5cedfcd3fb1eccc7862c95c215ba0d5a2ec1c4fa80244393d0934cf59fe988f7716bf15cb8e79f4ee03fbe4a48a10cac6e0610f9d55"},{"one":"a4dd67ab4fff1a50968c7ab59c304eb0083b072fc13dff599eeadac4e0e75099f7c825f91dd1bb770f3ae6f3d1d82ad574d6ecb117adf1ca9ccbccd01303ec7c","up":true,"other":"b1bef03357528618be6936a7edae5e3d4ecc942d43bd301642d321a73a07f3327d413f923c3fdd49d04f311e18709a4dde7519722d7a4912f181aa4df2e60173"},{"one":"0c000879be78fc867857011e396e2dd77bc2a0c6c2c3624d98b102737aa8d998ca9081653c0c8285117a5288b1bfeed06c54b2f6e39225aca4a21ff2a72116e1","up":true,"other":"850e729f9bbb5ef6e12baf7d3dced180839e88e0845baa7aa8fb87dcb417aa74af5999bda81723aabbef5eda842fa4b5fae107fcff9f6bd50597e8ba6a849dff"},{"other":"2a0fa7932768f0c316b478d15db556626def18462c3bee9446ff16c48fc43b6be1694a5783602b60250e33adc705b86fae7baa6b829146251995fd47980ce422","up":true,"one":"540598224dccc717053f94e915652df499f513dc0c8874ce999040e1aa829c33ede284c72ddd0b24a319821102fa42aaaaa87380e777b5878455de61f5fc2ac9"},{"one":"946b3f821a4b61661e8ace52f4ade415042fddf058d97a16f08d9eff7a0be633de47c27fa9760ff38d583b2405163d4a27d3a7949d4015271396c014043a34e3","up":true,"other":"826500ca53a2aed90da0cc3778cbc41af3de0139b246f30c3be65582b1f152928dfa3280760da4dcd8098f41f529a088dba24bc5d0c71322ef69f4b101f0224a"},{"up":true,"one":"2396833be485e50b230a07fddff7f24e11e3fdee3f08f11a287faa2b03b26451b9f4fd24ddefdec62917ae59b6fa56a75e7d6e078b411d624704b88f841b9960","other":"f2ac738fa932c90a45d1a64e4a52fd9c4037e2d89ceef1584efef04689bc7aff3a9635fb78dfdf3480d003daf14359190b1cfa8335db438a54107d4060ed58f9"},{"one":"66652e041752f4acb27bc45c9c8b58f4f4ea904345a887a49ae831bef3bb1ad26cff7fd0f66ef3c28d6c41e039e39ff983710fdd5384f849595a66e5509e0d10","up":true,"other":"826500ca53a2aed90da0cc3778cbc41af3de0139b246f30c3be65582b1f152928dfa3280760da4dcd8098f41f529a088dba24bc5d0c71322ef69f4b101f0224a"},{"other":"81df6add458aaaaf51a3ad8826250f3498f06586264f95cd7fce642ac08bd583f463a7531e292175f90887013ba39f8757c21eb5524ec62ec413b82badae935a","one":"64a39acfb1accea032dfc4d1530b5cdbdc8c1b609a442b68a9b534a539062d051b750a4512b0a9d504fdffa2a5bc8d4fcb6ca59f4ddb1c59ce62e8913644499b","up":true},{"one":"826500ca53a2aed90da0cc3778cbc41af3de0139b246f30c3be65582b1f152928dfa3280760da4dcd8098f41f529a088dba24bc5d0c71322ef69f4b101f0224a","up":true,"other":"ab3a3ad0481a80b91132cc6afeaab9c9f5e931885d979176e8e6c181d997c38b488e5eca475b0f8e949a8cf128695e18a5851091394d0a33cf834ce7e3537ac2"},{"other":"540598224dccc717053f94e915652df499f513dc0c8874ce999040e1aa829c33ede284c72ddd0b24a319821102fa42aaaaa87380e777b5878455de61f5fc2ac9","one":"a1b07c24605e258db7b8fb15db227596b08dc69bb234c0a48c312eb6eb1fb08553f8c8a6da7175eea258e2d3f2625a540c1466e6c31315aa1484fa173b7a8cfc","up":true},{"other":"53031cddf4390ba176d638456016028bd4538879c7eaba672c3ef70208319a14e6a41dea8ff003b6f7e9b4a83ca12dab50d4f44f079153bec7c24221e311573e","one":"c677530a47ef470ae0811127b91c231ec8889588bd096c24a54cc48099e8edde811f4a72eedc79118acb494ef031d6adcef1595d1a17df71b25b468478e931ff","up":true},{"other":"dee5fb5ccdfe3803cab3e0041c5c4879001bf2c2233446f47245d8234642046269bfe50e414cd2d89341e338597f2ecbb7b2912c20558a85041b757a24490805","one":"af761f8d13059f1e49d2f5c0b7a76a5eb5bcaab1e7ff01673dff3967d81bd7aebf74afef3934328034c82f131fa066de71816cff8f720e0c56d5e85b233a8a44","up":true},{"up":true,"one":"932e926c54a4127210a15731fa4ad6bbfd0d69183b894b676920843f154ad1e4148b674d234f070e9dc07547394a5af973befe0fc170bbe44346d69e135e0157","other":"38469be067f9bba869fdfcc950843e00b5ff950778c11445787501d47cbaf60e9940735a5b8b71d48a0aaee75c8263137169d51944638dc5d1cad398d22439ed"},{"up":true,"one":"bebbde654a4f3e3e65f63d10cbcc89dfd46ce75945c19be33bfe4d954c8ed375981e21a8376ad10e402dddbcf3b657e6786c0820e599a0d1fe03f8d35294d7c7","other":"071c094246a0ca4b5d169e43a20ce5da508e579a6e2e822462bd8948ab357d46ab477bcff0c80eba2e01f0c100690b307af40d47c52ebad06783e9e77466cbd6"},{"other":"45c635c4080d47e2f932c27472e487ec95b7644c3d94d8627166a33dca2e3cbaa3305ae2d42e1510bfb0f8329b90e5a31883b399a469ad548fcae3040a8833a0","one":"223d79f656e3f124ee1238ca46e42c2a0d8500ee58a37312c6b72657a11ad9ebce3be4c061611b913a22863f6e7936ff37602dedc7856baea27e8201db44bbf4","up":true},{"other":"e3779b202b9cfe7b2f2cc9e95974ac77bf51ba951f775acc10f07249ee6b3b260f2b012bb010a7f9794c5562e9b00f18b52c25c1e350ab70afc6bf9e210e4969","up":true,"one":"0e07d2eb15905a583532383cef08b0881878c5043c4d7bae2cf1cace9954bfbbfbe0c1e8322eabbc84bc94cda08ae9b70cbdc56a1b8a19f807bcd5ca7939669d"},{"other":"82f0cbb87a76dea7947c2c1b6506d05390e5c5e969e5e91651ca10d36cd6aaea72967435ea7e5222d28f1d5e64cc526075d264712e55593bc3b609c93d4fe1eb","up":true,"one":"972b7f6c5b926b93a9b005bb8a891c29e535a465c586bcd4258d4094e320925a179e8f63478917f8a88d1911fe8f868013abeb34817832ed4b0b209ce392f20b"},{"one":"53031cddf4390ba176d638456016028bd4538879c7eaba672c3ef70208319a14e6a41dea8ff003b6f7e9b4a83ca12dab50d4f44f079153bec7c24221e311573e","up":true,"other":"c49e963a92b93a1c48fd3e38c127bfc88fbcb15b57bfdf8615c0e591b24276d4fe153a811932aefdcf3dee494d53ce354ba052c24313a725d562c6e807ab9133"},{"other":"123633b35f455fc3240d99929dc3130bb018545672be151ba973915f2ab6e6c862748f60d917e48ccbf28620c4e58b888867cb51e12ec0d2e5c61cef82258719","one":"604a11bd1d969886953398ecc1fdf5847a946a8118014d0cb8daff9943f4f78c4bdbad3ee4152959c8265d0588dea658c262fe2f99a55a0b32321b81c8eec473","up":true},{"up":true,"one":"236266f9f5a28148d11bed1195a91cd1d30231b082697ee1940a85abca98d2ff0767be9128c23375caa0444bcf51d8501879200ea0f27f13d0ede37f97241325","other":"09fa1e69f37cb14db3dd721a9c4b9c884f6fe519d850f7af3643ecd536d4b3e995f99acf569e23b7864996c750115ff0ca0bd446ebfd76a026da71da0b95fd97"},{"up":true,"one":"38469be067f9bba869fdfcc950843e00b5ff950778c11445787501d47cbaf60e9940735a5b8b71d48a0aaee75c8263137169d51944638dc5d1cad398d22439ed","other":"0e07d2eb15905a583532383cef08b0881878c5043c4d7bae2cf1cace9954bfbbfbe0c1e8322eabbc84bc94cda08ae9b70cbdc56a1b8a19f807bcd5ca7939669d"},{"other":"cc0d13dba120558dc8e2d0e5ac755a712e7e7e6dab6edcaf658faf02537b1efe3d6c54d6e67566eb4a3a8f8a019702aa7ee2b33ee3f0316a01e7b17845032e70","one":"3bf838b4d29d9388a24d160eee6bf8ea017af6cd9e5f7d88b4cae71ebfbc304666d3d634a05e0a75570dafe8f41871090fcff8b651a9130d013786dfcca3da14","up":true},{"other":"3bf838b4d29d9388a24d160eee6bf8ea017af6cd9e5f7d88b4cae71ebfbc304666d3d634a05e0a75570dafe8f41871090fcff8b651a9130d013786dfcca3da14","up":true,"one":"c133cd3ee228f427410357f46752d33ecf302475314411772df3532669a8b220136c09f00717460c39bcea1058cb988dd223875ec991612876b400556f5937dd"},{"one":"3db9984cb1e25bdc30c483f3d4c036fb1728bafffecd2b965af7e701569c28116dbed2e5892504ea9927c14570351b03cb99112a5924a27e6e03289422785c7b","up":true,"other":"c708e3584cd9450b30d8cdd960a676884f64364c2aec985eebb4a0d745f6c73b6b0cb16f330bf090320bc48a5a67e8519b3c2c4a64cf2eff9aa4f1fc0b274a00"},{"other":"e706876f36646bfb2dfbd11669a4907432660023a13be9de329a03f6c6e88e3788002b83d0cb4617e6c4096998783925be5b1de4f0edd8128e7d71312fb1091d","up":true,"one":"854ff45571c01cd49d0932bcb361eef13202ababf48f0b8e5d8143dc41e01609aa1539e926bad9b4ca8add023fd259eb70239103d75b0a404bb338f3e4bf9577"},{"other":"826500ca53a2aed90da0cc3778cbc41af3de0139b246f30c3be65582b1f152928dfa3280760da4dcd8098f41f529a088dba24bc5d0c71322ef69f4b101f0224a","one":"fa4174ca214905c4136e891e64349f664f166aeeacead6f6e84892ebcadd2c7fbff07052ea4913a9465999f5494962ec29f7f7a3e6cbb993e00d1b881fb31eb1","up":true},{"one":"faa3c31521c8f7b9d15838750e7e311eb0f01db5ef22cd1bf62a7d72e7efdf5a575550c930d96230edc892d107d4551e95b099d3c952a7f1c0ad3b5967c7831b","up":true,"other":"38469be067f9bba869fdfcc950843e00b5ff950778c11445787501d47cbaf60e9940735a5b8b71d48a0aaee75c8263137169d51944638dc5d1cad398d22439ed"},{"one":"81df6add458aaaaf51a3ad8826250f3498f06586264f95cd7fce642ac08bd583f463a7531e292175f90887013ba39f8757c21eb5524ec62ec413b82badae935a","up":true,"other":"e2956a828cb1ff85ab55bdbe329f530662558cb8013ffddacac8ba36096abea07ecb15b54896dd9b4bb0b15155654dbda0c031f69290f2314ac0e376bebbd864"},{"other":"a8b619f75e0e4cf7bc5e425ff9b03e55b7301fec4fb58f321bf89811678268d9f738bbf22ee36c2d14ff71a08d6f7dca28249ff6f943cc5a77653f482254d150","one":"e2956a828cb1ff85ab55bdbe329f530662558cb8013ffddacac8ba36096abea07ecb15b54896dd9b4bb0b15155654dbda0c031f69290f2314ac0e376bebbd864","up":true},{"one":"2a0fa7932768f0c316b478d15db556626def18462c3bee9446ff16c48fc43b6be1694a5783602b60250e33adc705b86fae7baa6b829146251995fd47980ce422","up":true,"other":"972b7f6c5b926b93a9b005bb8a891c29e535a465c586bcd4258d4094e320925a179e8f63478917f8a88d1911fe8f868013abeb34817832ed4b0b209ce392f20b"},{"up":true,"one":"45c635c4080d47e2f932c27472e487ec95b7644c3d94d8627166a33dca2e3cbaa3305ae2d42e1510bfb0f8329b90e5a31883b399a469ad548fcae3040a8833a0","other":"b737c81fe6bc50d977231a5fc8856f064ba58190c5ab5615d3cf634aea8c15a308f3a667aad2e69d5c1438549cd41c863fd40f643b70caf3e0c934276ef2a84f"},{"one":"f2ac738fa932c90a45d1a64e4a52fd9c4037e2d89ceef1584efef04689bc7aff3a9635fb78dfdf3480d003daf14359190b1cfa8335db438a54107d4060ed58f9","up":true,"other":"f394aaa6d14c6ed95e2ad4651b5103bb1ab9f3a61839936cc1f08d6a6e53504e5d15dfc5211539ffdbdc64912ded5c2272d4af52ed8d7fe5a3c228eb12f0c68b"},{"other":"0d85f39dca79f99b277ad5cedfcd3fb1eccc7862c95c215ba0d5a2ec1c4fa80244393d0934cf59fe988f7716bf15cb8e79f4ee03fbe4a48a10cac6e0610f9d55","up":true,"one":"850e729f9bbb5ef6e12baf7d3dced180839e88e0845baa7aa8fb87dcb417aa74af5999bda81723aabbef5eda842fa4b5fae107fcff9f6bd50597e8ba6a849dff"},{"up":true,"one":"e90ca22b959d482861c52e9e51fd2d63557453dce64dab9f66fcf323273c12e7189358f85d500f5200ff7c7b2d57afe72577ed9aa2adb36fc0c8e5504588fe94","other":"ab3a3ad0481a80b91132cc6afeaab9c9f5e931885d979176e8e6c181d997c38b488e5eca475b0f8e949a8cf128695e18a5851091394d0a33cf834ce7e3537ac2"},{"other":"ac6057677fdfc132ea2418ff877357962771db049d169ba2c1923b15820385c6bf2f5846943d44a73bfdeb44a1e0d68307003a06cb0f694705879f8a720c3296","up":true,"one":"35ac328e13ea4fc6c333591633455cb6a2dff124528a17668770e231582ea31ab95e083cd191d8c45369d88366e9df0d2417cd26efbf2f616139c92fd497cd48"},{"other":"3bf838b4d29d9388a24d160eee6bf8ea017af6cd9e5f7d88b4cae71ebfbc304666d3d634a05e0a75570dafe8f41871090fcff8b651a9130d013786dfcca3da14","up":true,"one":"7e9a81d06e997a691cc7790d358868b8657db608795ef6b85bb194db7f56ab5c76cac3be0b40d847ce873aeef4bdad40b725d69f4c42755b9d5aab4fe7aecb34"},{"other":"f8fd12d8b5872b74e2cfa60d6a3a25b568a1fb4be3a8d06faac02a38321f419c443e517c0e2989001635f827add1859a2dc9589a9c0f5bf3804d46f43f799116","one":"5a59a44ba2bf5e77f921216ac467733c8529b06790efb05a63c410060edaf65547a2dbb37333073e3bcf68d422ba4b135432307f90394c6edd6dd33dd6ff2152","up":true},{"other":"eb6fa7d39fcee5a7081813169ae24ee6d355cfe717dcb2fa500a07c935ffbe1b12378ea13454742bf7c2df10ad2fd4e53476068eaef4669381c8cd060c199e11","up":true,"one":"84379884f012e2cfc1f9838312640576c9ded01ca53cf8451f94915e6949f0084047a2555a5fef4d1b0eef62ad5504a34ff631fbb658b011a07a82a53173f5c1"},{"up":true,"one":"334b59c2767fc786551dfdc0a9fcd6f5b53cbe48ddc1ca61b84f8155a15de7e8cd44cbb3a537e1aa7f11416eb710c5de916a5e8ce24e83bfa570b7344c5873ea","other":"c677530a47ef470ae0811127b91c231ec8889588bd096c24a54cc48099e8edde811f4a72eedc79118acb494ef031d6adcef1595d1a17df71b25b468478e931ff"},{"up":true,"one":"82f0cbb87a76dea7947c2c1b6506d05390e5c5e969e5e91651ca10d36cd6aaea72967435ea7e5222d28f1d5e64cc526075d264712e55593bc3b609c93d4fe1eb","other":"604a11bd1d969886953398ecc1fdf5847a946a8118014d0cb8daff9943f4f78c4bdbad3ee4152959c8265d0588dea658c262fe2f99a55a0b32321b81c8eec473"},{"other":"850e729f9bbb5ef6e12baf7d3dced180839e88e0845baa7aa8fb87dcb417aa74af5999bda81723aabbef5eda842fa4b5fae107fcff9f6bd50597e8ba6a849dff","up":true,"one":"d6794744c5f941cb6dbac4adbbbf11ce83c9224c8a34b9c787ed5975bf0af13e095a7db1c86fcbb7b134ae6dc67467d3ffaf191f4a4d9218779c4d0cf86876ca"},{"other":"2396833be485e50b230a07fddff7f24e11e3fdee3f08f11a287faa2b03b26451b9f4fd24ddefdec62917ae59b6fa56a75e7d6e078b411d624704b88f841b9960","one":"57533c56642895edba91473a966b6abf765725a721dec947e4bac4728dfbed265435aefca55fff69cae48c9d506064fbb890665a0acd87c466707d08d1e6e1f4","up":true},{"one":"ac6057677fdfc132ea2418ff877357962771db049d169ba2c1923b15820385c6bf2f5846943d44a73bfdeb44a1e0d68307003a06cb0f694705879f8a720c3296","up":true,"other":"0bf28b481d71062ee100d6cb04c8b4234a574f8657e2d3c49b60a9ecdbf486d0ec38b33bce745c8efe820145d5c53ea802aa64b4f9bce19b029ee5b2f9de43f1"},{"one":"11170a0fb9f6b037f8ee4494e935a84b06816ff5c44ef9d613920f9c58f8b25611b2093da3fb51a59687db6a9b0a070386cac09757a27f75754cbdcb9afc2225","up":true,"other":"6070dc131e9721a4a496b3ed6ff5c9db1a5351e942ed424b86fe6be940d1012df766afb4b0112452dfd63e0fcfea13658324a9ef4a94b5754ec9f6219e4b0d67"},{"one":"9b3fecfc63256a9d69e75ccb5119b2866e30fa4516b3a3bf5b2f03f04f1d20de786ddb90fa2acadb2a0509503b21fc9d16238c57f9b102ceedb6b27ee1b2c4ea","up":true,"other":"f394aaa6d14c6ed95e2ad4651b5103bb1ab9f3a61839936cc1f08d6a6e53504e5d15dfc5211539ffdbdc64912ded5c2272d4af52ed8d7fe5a3c228eb12f0c68b"},{"one":"e0cacf6abdbfd9a25b9f974600662d4eae484efcdefd0a2a8fbc799127b6fabf2f471aff89c3a08e93ea20be1c304320598ba20a13697a356bf065292ba16bc1","up":true,"other":"826500ca53a2aed90da0cc3778cbc41af3de0139b246f30c3be65582b1f152928dfa3280760da4dcd8098f41f529a088dba24bc5d0c71322ef69f4b101f0224a"},{"other":"f87c2dea026ba5e6cda9a446821bf057d3453fa8c9b38fd882a09979ff3cfe2b8adfcbd5cf28d268776414bd12a9aba385d5c97c76a29c1b0625b101faac761d","up":true,"one":"f394aaa6d14c6ed95e2ad4651b5103bb1ab9f3a61839936cc1f08d6a6e53504e5d15dfc5211539ffdbdc64912ded5c2272d4af52ed8d7fe5a3c228eb12f0c68b"},{"one":"e20a90f36eca4329d3d2dbadf530949889dc20b0ae5d96b935af9b60d26ec507e9eb1b73fd2b4dc88057c20e4ef6e7039cc49652d35c563db64f06f979e28540","up":true,"other":"5a59a44ba2bf5e77f921216ac467733c8529b06790efb05a63c410060edaf65547a2dbb37333073e3bcf68d422ba4b135432307f90394c6edd6dd33dd6ff2152"},{"up":true,"one":"255939ef32bd3e5e76181763c11707b9ff4ab26d3ffb10f06fa7249b06721fa3decfa9eee3eeb8b12d6218af5f9ed8872d62c42a90cd46dcbef3d89a8163ae07","other":"e2956a828cb1ff85ab55bdbe329f530662558cb8013ffddacac8ba36096abea07ecb15b54896dd9b4bb0b15155654dbda0c031f69290f2314ac0e376bebbd864"},{"other":"fa4174ca214905c4136e891e64349f664f166aeeacead6f6e84892ebcadd2c7fbff07052ea4913a9465999f5494962ec29f7f7a3e6cbb993e00d1b881fb31eb1","one":"ab3a3ad0481a80b91132cc6afeaab9c9f5e931885d979176e8e6c181d997c38b488e5eca475b0f8e949a8cf128695e18a5851091394d0a33cf834ce7e3537ac2","up":true},{"other":"c4dfcf348694971fb36ed91e9024302bec8df3891540cbe1f5df26eee9c1f81a95295f05b90ec30dd044a0355dcaa805b9f50e95f38e5588a929cfe10e8cd73d","one":"1cc62520c0d9c6a47d96e485bdc6a5d0f7319477ad6d177663f7b49217f5a8e56e4717f36fb5aa11c5270d4383cab460219821bcc6c9cbcccc4a97446b406d96","up":true},{"other":"6d3bd11f2f7fe855188423bc49be111cd13defeb78a76eb26d415bfc0c86b89e90724db54a12ae7e0c76b9eb12eb456fc50668697245fca00f9ec3c6fb9c8588","up":true,"one":"a8b619f75e0e4cf7bc5e425ff9b03e55b7301fec4fb58f321bf89811678268d9f738bbf22ee36c2d14ff71a08d6f7dca28249ff6f943cc5a77653f482254d150"},{"up":true,"one":"6070dc131e9721a4a496b3ed6ff5c9db1a5351e942ed424b86fe6be940d1012df766afb4b0112452dfd63e0fcfea13658324a9ef4a94b5754ec9f6219e4b0d67","other":"3db9984cb1e25bdc30c483f3d4c036fb1728bafffecd2b965af7e701569c28116dbed2e5892504ea9927c14570351b03cb99112a5924a27e6e03289422785c7b"},{"up":true,"one":"3e65bbf7103b3307bd9b8a65168c7c87c3f5283c7c52edefabf4193a1f04ac10216cc485a1dae17cff9ccea41bcf9a0b41de001c6142f30701443dc1735f25c0","other":"57fb9e7f287fe67500b8b560475c0d0d6eae9d623d5a8c85eb5459f209904a839a0b24ff99a1643a4196a71d45f2ed1bd5e08f9a13cdd9749a907a024ff984dc"},{"one":"0bf28b481d71062ee100d6cb04c8b4234a574f8657e2d3c49b60a9ecdbf486d0ec38b33bce745c8efe820145d5c53ea802aa64b4f9bce19b029ee5b2f9de43f1","up":true,"other":"f87c2dea026ba5e6cda9a446821bf057d3453fa8c9b38fd882a09979ff3cfe2b8adfcbd5cf28d268776414bd12a9aba385d5c97c76a29c1b0625b101faac761d"},{"up":true,"one":"49bd2289f479c9ad7e0d13319271b9be1e1dcbee28313513a124dec55f9842db639e62a74a83040930c537739ab7fa1e50bb05b9ab0f588d6da7b64a6451f466","other":"f87c2dea026ba5e6cda9a446821bf057d3453fa8c9b38fd882a09979ff3cfe2b8adfcbd5cf28d268776414bd12a9aba385d5c97c76a29c1b0625b101faac761d"},{"up":true,"one":"5c1e9692b731421d6eaca488e8ba4cfdda1933ac5f1504ece684fadbea07a7c8053feb73be7ce20aedeaecc84f14d836b5ed2a657df6ca04f4fc82c2da0c0d46","other":"69f3f9fafff951dca2fe98baa178e53f2779311a93fdc364cf4c2477700c8dbce7e4201c3aa6d840b5ae65e8fc9d6603cbc41dbdf601f1998caedee1b542d72b"},{"up":true,"one":"b1bef03357528618be6936a7edae5e3d4ecc942d43bd301642d321a73a07f3327d413f923c3fdd49d04f311e18709a4dde7519722d7a4912f181aa4df2e60173","other":"b737c81fe6bc50d977231a5fc8856f064ba58190c5ab5615d3cf634aea8c15a308f3a667aad2e69d5c1438549cd41c863fd40f643b70caf3e0c934276ef2a84f"},{"other":"53031cddf4390ba176d638456016028bd4538879c7eaba672c3ef70208319a14e6a41dea8ff003b6f7e9b4a83ca12dab50d4f44f079153bec7c24221e311573e","up":true,"one":"e706876f36646bfb2dfbd11669a4907432660023a13be9de329a03f6c6e88e3788002b83d0cb4617e6c4096998783925be5b1de4f0edd8128e7d71312fb1091d"},{"up":true,"one":"06a8a25c6dd90e230237b06c086f14e539b31b8e3705752d0ad8faf1bd7239547332604b79b6124cbd0cee495b99a80f147983142b7271841d8d9fa85d559301","other":"cc0d13dba120558dc8e2d0e5ac755a712e7e7e6dab6edcaf658faf02537b1efe3d6c54d6e67566eb4a3a8f8a019702aa7ee2b33ee3f0316a01e7b17845032e70"},{"up":true,"one":"519ce8f43529d0c703ef4faf50450877dc2818fd6fd6b7faaa9bbbaeac373e499d1b4a17b387b1a8d35e8042e18a9d3d365c97254b4d24352b10e8de9219a5cd","other":"854ff45571c01cd49d0932bcb361eef13202ababf48f0b8e5d8143dc41e01609aa1539e926bad9b4ca8add023fd259eb70239103d75b0a404bb338f3e4bf9577"},{"other":"53031cddf4390ba176d638456016028bd4538879c7eaba672c3ef70208319a14e6a41dea8ff003b6f7e9b4a83ca12dab50d4f44f079153bec7c24221e311573e","one":"fd321c630fadcc8d6b00589323f7313ac1e94effbe8192955da5f88dcf419ef28820075e0e81c595561ff6ee58cfce23079407edf8b1611cb994946bcbd26364","up":true},{"other":"64a39acfb1accea032dfc4d1530b5cdbdc8c1b609a442b68a9b534a539062d051b750a4512b0a9d504fdffa2a5bc8d4fcb6ca59f4ddb1c59ce62e8913644499b","one":"1545795dca07ecd09c5b16b3bbdddf3dba92e27b532c18a3bc63bc007761ac1b1ebc7ffb4f0a401d5376a4c67923c7949edaebd8f65fff52d6677bb1d6a72f43","up":true},{"other":"53031cddf4390ba176d638456016028bd4538879c7eaba672c3ef70208319a14e6a41dea8ff003b6f7e9b4a83ca12dab50d4f44f079153bec7c24221e311573e","up":true,"one":"7172a86afb608acd9a3e1e5c0472489ebecb516cad6796fa9a06ab47cc8e8cce12dddce72f0ac3b0927602bd22ed5872c3b5ce9b6af96f8e9d1d75078cc9bb55"},{"one":"cc94ed069ddcc24dc2733eed5ba8367a2521a5955c7287c5280c71675b9965ee8499454b227a4ddc64a14d74b39916211763ddf0b7ad80a52381cc61dcb6c72c","up":true,"other":"f8fd12d8b5872b74e2cfa60d6a3a25b568a1fb4be3a8d06faac02a38321f419c443e517c0e2989001635f827add1859a2dc9589a9c0f5bf3804d46f43f799116"},{"other":"5a59a44ba2bf5e77f921216ac467733c8529b06790efb05a63c410060edaf65547a2dbb37333073e3bcf68d422ba4b135432307f90394c6edd6dd33dd6ff2152","up":true,"one":"59fe05843cc637adac3728acb8ca9650f49050095cf5d32241366f54d4ac7179b16dcb009e2fb9fa9499cc6f8b865b6c4d6fe6e35500df10ba5daa719d57976e"},{"up":true,"one":"cc0d13dba120558dc8e2d0e5ac755a712e7e7e6dab6edcaf658faf02537b1efe3d6c54d6e67566eb4a3a8f8a019702aa7ee2b33ee3f0316a01e7b17845032e70","other":"6d3bd11f2f7fe855188423bc49be111cd13defeb78a76eb26d415bfc0c86b89e90724db54a12ae7e0c76b9eb12eb456fc50668697245fca00f9ec3c6fb9c8588"},{"other":"57533c56642895edba91473a966b6abf765725a721dec947e4bac4728dfbed265435aefca55fff69cae48c9d506064fbb890665a0acd87c466707d08d1e6e1f4","up":true,"one":"a089758c25ca0730f13cd18c10aeea62488c1c2651eef53a8ad11cfdfa61ce8f7354a53bd6902da26b79dfbedc78d315b1d4239eb62cbca59215727b2ac35213"},{"one":"8b8c15c6329096267a25d4060ee19963afb6e776fea60d9d566d4e1f9b087581b36e33fc533d7f133668a7a6a22f81a1234ed9fbce26eff1d5e5691a6148d540","up":true,"other":"a089758c25ca0730f13cd18c10aeea62488c1c2651eef53a8ad11cfdfa61ce8f7354a53bd6902da26b79dfbedc78d315b1d4239eb62cbca59215727b2ac35213"},{"one":"e3779b202b9cfe7b2f2cc9e95974ac77bf51ba951f775acc10f07249ee6b3b260f2b012bb010a7f9794c5562e9b00f18b52c25c1e350ab70afc6bf9e210e4969","up":true,"other":"53031cddf4390ba176d638456016028bd4538879c7eaba672c3ef70208319a14e6a41dea8ff003b6f7e9b4a83ca12dab50d4f44f079153bec7c24221e311573e"},{"other":"faa3c31521c8f7b9d15838750e7e311eb0f01db5ef22cd1bf62a7d72e7efdf5a575550c930d96230edc892d107d4551e95b099d3c952a7f1c0ad3b5967c7831b","one":"a2719942ffb6e99bda131cdedb612785dafdf72f5f35824343ad39d8568d6cd25e44b585a915c8e9ea2b02e6fd38c105bb17ed27c8fa320f18c83e0ace78feb5","up":true},{"one":"a16326a0c540731e0964c4bc10c1342346fcfee70c7d1d8d333cbb774cb9f49dbf92585595654c99253eac21373706247bf5ef1ba40ac03e62da00821991cf7d","up":true,"other":"0e07d2eb15905a583532383cef08b0881878c5043c4d7bae2cf1cace9954bfbbfbe0c1e8322eabbc84bc94cda08ae9b70cbdc56a1b8a19f807bcd5ca7939669d"},{"other":"5a27b90639d515cad7794dae78bf9a9866cca23c5e3e18870524d148797ba1bdfd631151f23062d4dcf0961a7dba709431a44e39da29ed5ea4b0b6987514e433","up":true,"one":"c49e963a92b93a1c48fd3e38c127bfc88fbcb15b57bfdf8615c0e591b24276d4fe153a811932aefdcf3dee494d53ce354ba052c24313a725d562c6e807ab9133"},{"up":true,"one":"96f3194c9ef17f60c318be14dd72c51af0aebc19f7a574b769d18b1fda6791409c827892bae3a061800e3d78af88a97635a0a892c54d7ebb38342ab1ba99c3ad","other":"f4ae36400caeddcbcf0fb1abd5b9611c37bac683645d10c69a1ac54d366f730c59917c95e990a0fa6bb2679c98fb62bf0e29bd7812ab57375de35f469dab98a0"},{"one":"d33f82b6a46535e798b78ebb28047ece1ef3b696ab29726d283161c377ed17a735a0948b99d83dee2af71704001e2e13813854a1b0ef4fcefd3c0e5c5f6e720d","up":true,"other":"e90ca22b959d482861c52e9e51fd2d63557453dce64dab9f66fcf323273c12e7189358f85d500f5200ff7c7b2d57afe72577ed9aa2adb36fc0c8e5504588fe94"},{"other":"af761f8d13059f1e49d2f5c0b7a76a5eb5bcaab1e7ff01673dff3967d81bd7aebf74afef3934328034c82f131fa066de71816cff8f720e0c56d5e85b233a8a44","up":true,"one":"c7566a0efd78ba35ad27a51a7ec8fcd55944ae12f9933573e71e2ad7404d48037dad9063c10ce5af636d7641a03899333d01aa9be94716d2179fdb2af33f36c4"},{"other":"82f0cbb87a76dea7947c2c1b6506d05390e5c5e969e5e91651ca10d36cd6aaea72967435ea7e5222d28f1d5e64cc526075d264712e55593bc3b609c93d4fe1eb","up":true,"one":"eb6fa7d39fcee5a7081813169ae24ee6d355cfe717dcb2fa500a07c935ffbe1b12378ea13454742bf7c2df10ad2fd4e53476068eaef4669381c8cd060c199e11"},{"other":"f4ae36400caeddcbcf0fb1abd5b9611c37bac683645d10c69a1ac54d366f730c59917c95e990a0fa6bb2679c98fb62bf0e29bd7812ab57375de35f469dab98a0","up":true,"one":"7ca32d24c001557a81af351ac71322543154eeedbb6ccdd8b8b142f19215aa712218babe9701e73a6441784375a511c1f16a70569b73416f9708409564d18485"},{"one":"ad177f2702ed11d531b11fd0250f2dab2364624680cfb6ff1fba5b27dcd8334269a5bc9093401389044c0b00ed0cbf6f166aba81a58cadd34b25355839fff6ac","up":true,"other":"ac6057677fdfc132ea2418ff877357962771db049d169ba2c1923b15820385c6bf2f5846943d44a73bfdeb44a1e0d68307003a06cb0f694705879f8a720c3296"},{"other":"0d85f39dca79f99b277ad5cedfcd3fb1eccc7862c95c215ba0d5a2ec1c4fa80244393d0934cf59fe988f7716bf15cb8e79f4ee03fbe4a48a10cac6e0610f9d55","up":true,"one":"d6f274a2f20831a1b2281d889f46ad44f1bc5a07bb2152c89e129afb1c1e643b608621791a9d15a28da022d57b8bc3c05a7da0b5a93201dd714179e4a6a29a8b"},{"up":true,"one":"467a76ed18ca4f195c6a5b0ac277dfd0916657e047fea073db8e28bb59098bd8960c90efe8f59d6c275ff72d18b217d225f6698e56c05e33734a0fd6ea570589","other":"a089758c25ca0730f13cd18c10aeea62488c1c2651eef53a8ad11cfdfa61ce8f7354a53bd6902da26b79dfbedc78d315b1d4239eb62cbca59215727b2ac35213"},{"other":"b949f482891fff7d7d1f0d84112db7080fa1df07cd4e52ee0fadb707a4b7903fc0da9fe45b7ceee37948856687f8e7768945295de15691a99c879f1816899d98","one":"4903cd53b3ffc4328547e03dec8f7992edbfb1e1697e53772ef79887984b11595167eb84015ff3dfb26ac0d7b2e98b7a0792bef843d2bdff3a76889fc4a6c60a","up":true},{"one":"123633b35f455fc3240d99929dc3130bb018545672be151ba973915f2ab6e6c862748f60d917e48ccbf28620c4e58b888867cb51e12ec0d2e5c61cef82258719","up":true,"other":"4903cd53b3ffc4328547e03dec8f7992edbfb1e1697e53772ef79887984b11595167eb84015ff3dfb26ac0d7b2e98b7a0792bef843d2bdff3a76889fc4a6c60a"},{"other":"e2956a828cb1ff85ab55bdbe329f530662558cb8013ffddacac8ba36096abea07ecb15b54896dd9b4bb0b15155654dbda0c031f69290f2314ac0e376bebbd864","one":"6d3bd11f2f7fe855188423bc49be111cd13defeb78a76eb26d415bfc0c86b89e90724db54a12ae7e0c76b9eb12eb456fc50668697245fca00f9ec3c6fb9c8588","up":true},{"up":true,"one":"af0050715bfa25b4ce3a7593c61578898be22801a9118064250c330c6b2a1416b3bc6d90b074d7d700e07574a274d861f9c6d8e3e5924c281502f699ad62465b","other":"b737c81fe6bc50d977231a5fc8856f064ba58190c5ab5615d3cf634aea8c15a308f3a667aad2e69d5c1438549cd41c863fd40f643b70caf3e0c934276ef2a84f"},{"other":"3dcf5ec3ebb3b7de61dfaef4ee397a4a13a96ee40673be2eaadfcadd11f139c594c74237b40dd9c10f059f40d325c014f5b02b3a8eb7f0dc7d66ced7fea9f17f","one":"5a27b90639d515cad7794dae78bf9a9866cca23c5e3e18870524d148797ba1bdfd631151f23062d4dcf0961a7dba709431a44e39da29ed5ea4b0b6987514e433","up":true},{"up":true,"one":"8b8c15c6329096267a25d4060ee19963afb6e776fea60d9d566d4e1f9b087581b36e33fc533d7f133668a7a6a22f81a1234ed9fbce26eff1d5e5691a6148d540","other":"35ac328e13ea4fc6c333591633455cb6a2dff124528a17668770e231582ea31ab95e083cd191d8c45369d88366e9df0d2417cd26efbf2f616139c92fd497cd48"},{"other":"123633b35f455fc3240d99929dc3130bb018545672be151ba973915f2ab6e6c862748f60d917e48ccbf28620c4e58b888867cb51e12ec0d2e5c61cef82258719","one":"d2cf35afdb846755290a7c3a1a36758e735a4eeed57b1af66595c55ab45c52cf2c478de3f395b38513cdc9e49568892cce490de93074fa45b640628f0fe40719","up":true},{"other":"b949f482891fff7d7d1f0d84112db7080fa1df07cd4e52ee0fadb707a4b7903fc0da9fe45b7ceee37948856687f8e7768945295de15691a99c879f1816899d98","one":"071c094246a0ca4b5d169e43a20ce5da508e579a6e2e822462bd8948ab357d46ab477bcff0c80eba2e01f0c100690b307af40d47c52ebad06783e9e77466cbd6","up":true},{"one":"1545795dca07ecd09c5b16b3bbdddf3dba92e27b532c18a3bc63bc007761ac1b1ebc7ffb4f0a401d5376a4c67923c7949edaebd8f65fff52d6677bb1d6a72f43","up":true,"other":"193ca2ef8a4ac98c0300d7e48421ba3fe5d4789a0c2b476499bd093808c3988b4a55742ff3f607429cafda08cbbb5fba68da8869747b1b5169f3e4545497de3a"},{"other":"eeb9d718ef61c14e10ab2fb3a90b039368acd17a59f70628deb39515c227bd0916c796cd7767b1a9d4f38e04f1013173b21c1fa2e0206ecdc72df6c2621380a2","one":"4f4201d959e4add3a4bcf3cbaab29d8abcc7530a9834e3cde45c4459ea92fba869e65156037a8fae02eac05f6174a7f2c1d825418f2207caa2284bcc9d9b84d1","up":true},{"other":"b949f482891fff7d7d1f0d84112db7080fa1df07cd4e52ee0fadb707a4b7903fc0da9fe45b7ceee37948856687f8e7768945295de15691a99c879f1816899d98","up":true,"one":"a5990a680e1f01dcd71a178a239880c5ce24418748c368b8e3c8a1175cfd744d16973cba03e5e756820950920a6d9fa5d5dd53829a1d1d508371cb1042e9453e"},{"other":"0e07d2eb15905a583532383cef08b0881878c5043c4d7bae2cf1cace9954bfbbfbe0c1e8322eabbc84bc94cda08ae9b70cbdc56a1b8a19f807bcd5ca7939669d","up":true,"one":"ef3016ea5a7b1b57388904d5c80fd05780d23acec8cf73e8add28ea99c6222fa84e89a1752186a2ef41dd0ec828405e61a1e8fd67d9496d75525ed860b12e2e8"},{"other":"0e07d2eb15905a583532383cef08b0881878c5043c4d7bae2cf1cace9954bfbbfbe0c1e8322eabbc84bc94cda08ae9b70cbdc56a1b8a19f807bcd5ca7939669d","one":"3e65bbf7103b3307bd9b8a65168c7c87c3f5283c7c52edefabf4193a1f04ac10216cc485a1dae17cff9ccea41bcf9a0b41de001c6142f30701443dc1735f25c0","up":true},{"other":"84379884f012e2cfc1f9838312640576c9ded01ca53cf8451f94915e6949f0084047a2555a5fef4d1b0eef62ad5504a34ff631fbb658b011a07a82a53173f5c1","one":"55beb7853107501c013283d0114f9812c2e97b292f90ae9bdd5aa8189d0379a758cbf19c5fa62436bc75a6e30d935a3bd52025b06efd167fa2fb8a1caead2f83","up":true},{"other":"dee5fb5ccdfe3803cab3e0041c5c4879001bf2c2233446f47245d8234642046269bfe50e414cd2d89341e338597f2ecbb7b2912c20558a85041b757a24490805","one":"9ad5ec0e729f9db10b7028788b58ef13d54bd11529b494a549d0415b90777b63fe78a752356315f5abbd24d849edc0c8bfe9d82c05460c30f4dad860ff5fea48","up":true},{"one":"b949f482891fff7d7d1f0d84112db7080fa1df07cd4e52ee0fadb707a4b7903fc0da9fe45b7ceee37948856687f8e7768945295de15691a99c879f1816899d98","up":true,"other":"7ca32d24c001557a81af351ac71322543154eeedbb6ccdd8b8b142f19215aa712218babe9701e73a6441784375a511c1f16a70569b73416f9708409564d18485"},{"up":true,"one":"57fb9e7f287fe67500b8b560475c0d0d6eae9d623d5a8c85eb5459f209904a839a0b24ff99a1643a4196a71d45f2ed1bd5e08f9a13cdd9749a907a024ff984dc","other":"9b3fecfc63256a9d69e75ccb5119b2866e30fa4516b3a3bf5b2f03f04f1d20de786ddb90fa2acadb2a0509503b21fc9d16238c57f9b102ceedb6b27ee1b2c4ea"},{"one":"41ded7596eac3eddfd1f7656ef23adabe1d18027f6159e45867e935d1ab742ec298ba2b23df522f79f59c7805510d8c995837380432dee37912d6ede1196caa2","up":true,"other":"35ac328e13ea4fc6c333591633455cb6a2dff124528a17668770e231582ea31ab95e083cd191d8c45369d88366e9df0d2417cd26efbf2f616139c92fd497cd48"},{"up":true,"one":"c796d4917dd22d9836a9d7d24ba6f89e1a0e8a78a207bd930991e44e9c80ac1de8e4e1a023d550a6dfa60270fbb3935a7e03ef389c1ccda957a4a6a75ef6819b","other":"d33f82b6a46535e798b78ebb28047ece1ef3b696ab29726d283161c377ed17a735a0948b99d83dee2af71704001e2e13813854a1b0ef4fcefd3c0e5c5f6e720d"},{"other":"35ac328e13ea4fc6c333591633455cb6a2dff124528a17668770e231582ea31ab95e083cd191d8c45369d88366e9df0d2417cd26efbf2f616139c92fd497cd48","up":true,"one":"464cf4c4203246240a63965062b9e5a7e5fa903f127b1f5ea5b37a27d33d8b12768fc2d8f257e67418f1e5765e627ca8f8cd5ba6b15b8a047490d26ce43e6291"},{"one":"f3bf16c7156ce55af92b2fc21826bdfd3e1f245c6087e76f5eb23cc8bbd88b25515a32029d3e6e2b4a27354606e9e3bdfe78788e326c4349d63416894fcfbaf4","up":true,"other":"eeb9d718ef61c14e10ab2fb3a90b039368acd17a59f70628deb39515c227bd0916c796cd7767b1a9d4f38e04f1013173b21c1fa2e0206ecdc72df6c2621380a2"},{"one":"de7ab7b9a2ba4ed523b84233fae11d93815579976ea78b385c658a4c156622747051f91342f9ac3610e22ee259b65e02b5af0ab67a9ee04ab6958a9d0d8acdf1","up":true,"other":"f3bf16c7156ce55af92b2fc21826bdfd3e1f245c6087e76f5eb23cc8bbd88b25515a32029d3e6e2b4a27354606e9e3bdfe78788e326c4349d63416894fcfbaf4"},{"other":"ef3016ea5a7b1b57388904d5c80fd05780d23acec8cf73e8add28ea99c6222fa84e89a1752186a2ef41dd0ec828405e61a1e8fd67d9496d75525ed860b12e2e8","up":true,"one":"fb20c708420e60c48fa65980ae11adc8cdf9b56ab93044a9aee9b5196d52f29e6cb2c218f73fefbdaecf8177bae1d9d13dd64bbe06e631555715b93f58f47137"},{"other":"5a27b90639d515cad7794dae78bf9a9866cca23c5e3e18870524d148797ba1bdfd631151f23062d4dcf0961a7dba709431a44e39da29ed5ea4b0b6987514e433","one":"e2956a828cb1ff85ab55bdbe329f530662558cb8013ffddacac8ba36096abea07ecb15b54896dd9b4bb0b15155654dbda0c031f69290f2314ac0e376bebbd864","up":true},{"other":"0bf28b481d71062ee100d6cb04c8b4234a574f8657e2d3c49b60a9ecdbf486d0ec38b33bce745c8efe820145d5c53ea802aa64b4f9bce19b029ee5b2f9de43f1","up":true,"one":"854ff45571c01cd49d0932bcb361eef13202ababf48f0b8e5d8143dc41e01609aa1539e926bad9b4ca8add023fd259eb70239103d75b0a404bb338f3e4bf9577"},{"other":"123633b35f455fc3240d99929dc3130bb018545672be151ba973915f2ab6e6c862748f60d917e48ccbf28620c4e58b888867cb51e12ec0d2e5c61cef82258719","up":true,"one":"cf03d32d3cca446e7016e7f41267a257bef7142c4f1e4ce2e17678856d75e9889e21972fd21583297a47a156543af15400444dcf37aca64543f97f73734f7f0f"},{"other":"69f3f9fafff951dca2fe98baa178e53f2779311a93fdc364cf4c2477700c8dbce7e4201c3aa6d840b5ae65e8fc9d6603cbc41dbdf601f1998caedee1b542d72b","up":true,"one":"df7decc6bb0d51afdc0c445a15be31b0e89c79a52b8a2cc789b585d94db63f064eccc1d8340d13d5e43ed7cbe95db8ad10ee7294dbd4c7629686564bb3a603b2"},{"one":"5c1e9692b731421d6eaca488e8ba4cfdda1933ac5f1504ece684fadbea07a7c8053feb73be7ce20aedeaecc84f14d836b5ed2a657df6ca04f4fc82c2da0c0d46","up":true,"other":"334b59c2767fc786551dfdc0a9fcd6f5b53cbe48ddc1ca61b84f8155a15de7e8cd44cbb3a537e1aa7f11416eb710c5de916a5e8ce24e83bfa570b7344c5873ea"},{"one":"255939ef32bd3e5e76181763c11707b9ff4ab26d3ffb10f06fa7249b06721fa3decfa9eee3eeb8b12d6218af5f9ed8872d62c42a90cd46dcbef3d89a8163ae07","up":true,"other":"c133cd3ee228f427410357f46752d33ecf302475314411772df3532669a8b220136c09f00717460c39bcea1058cb988dd223875ec991612876b400556f5937dd"},{"other":"de7ab7b9a2ba4ed523b84233fae11d93815579976ea78b385c658a4c156622747051f91342f9ac3610e22ee259b65e02b5af0ab67a9ee04ab6958a9d0d8acdf1","one":"193ca2ef8a4ac98c0300d7e48421ba3fe5d4789a0c2b476499bd093808c3988b4a55742ff3f607429cafda08cbbb5fba68da8869747b1b5169f3e4545497de3a","up":true},{"other":"9b3fecfc63256a9d69e75ccb5119b2866e30fa4516b3a3bf5b2f03f04f1d20de786ddb90fa2acadb2a0509503b21fc9d16238c57f9b102ceedb6b27ee1b2c4ea","up":true,"one":"a1b07c24605e258db7b8fb15db227596b08dc69bb234c0a48c312eb6eb1fb08553f8c8a6da7175eea258e2d3f2625a540c1466e6c31315aa1484fa173b7a8cfc"},{"other":"0bf28b481d71062ee100d6cb04c8b4234a574f8657e2d3c49b60a9ecdbf486d0ec38b33bce745c8efe820145d5c53ea802aa64b4f9bce19b029ee5b2f9de43f1","one":"57533c56642895edba91473a966b6abf765725a721dec947e4bac4728dfbed265435aefca55fff69cae48c9d506064fbb890665a0acd87c466707d08d1e6e1f4","up":true},{"other":"c49e963a92b93a1c48fd3e38c127bfc88fbcb15b57bfdf8615c0e591b24276d4fe153a811932aefdcf3dee494d53ce354ba052c24313a725d562c6e807ab9133","up":true,"one":"f87c2dea026ba5e6cda9a446821bf057d3453fa8c9b38fd882a09979ff3cfe2b8adfcbd5cf28d268776414bd12a9aba385d5c97c76a29c1b0625b101faac761d"},{"one":"af761f8d13059f1e49d2f5c0b7a76a5eb5bcaab1e7ff01673dff3967d81bd7aebf74afef3934328034c82f131fa066de71816cff8f720e0c56d5e85b233a8a44","up":true,"other":"cc94ed069ddcc24dc2733eed5ba8367a2521a5955c7287c5280c71675b9965ee8499454b227a4ddc64a14d74b39916211763ddf0b7ad80a52381cc61dcb6c72c"},{"one":"932e926c54a4127210a15731fa4ad6bbfd0d69183b894b676920843f154ad1e4148b674d234f070e9dc07547394a5af973befe0fc170bbe44346d69e135e0157","up":true,"other":"0c000879be78fc867857011e396e2dd77bc2a0c6c2c3624d98b102737aa8d998ca9081653c0c8285117a5288b1bfeed06c54b2f6e39225aca4a21ff2a72116e1"},{"other":"0c000879be78fc867857011e396e2dd77bc2a0c6c2c3624d98b102737aa8d998ca9081653c0c8285117a5288b1bfeed06c54b2f6e39225aca4a21ff2a72116e1","up":true,"one":"bebbde654a4f3e3e65f63d10cbcc89dfd46ce75945c19be33bfe4d954c8ed375981e21a8376ad10e402dddbcf3b657e6786c0820e599a0d1fe03f8d35294d7c7"},{"one":"3bf838b4d29d9388a24d160eee6bf8ea017af6cd9e5f7d88b4cae71ebfbc304666d3d634a05e0a75570dafe8f41871090fcff8b651a9130d013786dfcca3da14","up":true,"other":"e20a90f36eca4329d3d2dbadf530949889dc20b0ae5d96b935af9b60d26ec507e9eb1b73fd2b4dc88057c20e4ef6e7039cc49652d35c563db64f06f979e28540"},{"other":"123633b35f455fc3240d99929dc3130bb018545672be151ba973915f2ab6e6c862748f60d917e48ccbf28620c4e58b888867cb51e12ec0d2e5c61cef82258719","up":true,"one":"0e07d2eb15905a583532383cef08b0881878c5043c4d7bae2cf1cace9954bfbbfbe0c1e8322eabbc84bc94cda08ae9b70cbdc56a1b8a19f807bcd5ca7939669d"},{"other":"123633b35f455fc3240d99929dc3130bb018545672be151ba973915f2ab6e6c862748f60d917e48ccbf28620c4e58b888867cb51e12ec0d2e5c61cef82258719","up":true,"one":"0d85f39dca79f99b277ad5cedfcd3fb1eccc7862c95c215ba0d5a2ec1c4fa80244393d0934cf59fe988f7716bf15cb8e79f4ee03fbe4a48a10cac6e0610f9d55"},{"other":"f78ecf420b73cd0245807157c0cbaaa568c60c80965413e187b084fb26041761d12790c0cb6a39bc8997fd2b3d3f52c831e601f1f1846945fba1808b0e1cdf25","up":true,"one":"cc94ed069ddcc24dc2733eed5ba8367a2521a5955c7287c5280c71675b9965ee8499454b227a4ddc64a14d74b39916211763ddf0b7ad80a52381cc61dcb6c72c"},{"up":true,"one":"6d3bd11f2f7fe855188423bc49be111cd13defeb78a76eb26d415bfc0c86b89e90724db54a12ae7e0c76b9eb12eb456fc50668697245fca00f9ec3c6fb9c8588","other":"59fe05843cc637adac3728acb8ca9650f49050095cf5d32241366f54d4ac7179b16dcb009e2fb9fa9499cc6f8b865b6c4d6fe6e35500df10ba5daa719d57976e"},{"one":"3dcf5ec3ebb3b7de61dfaef4ee397a4a13a96ee40673be2eaadfcadd11f139c594c74237b40dd9c10f059f40d325c014f5b02b3a8eb7f0dc7d66ced7fea9f17f","up":true,"other":"84379884f012e2cfc1f9838312640576c9ded01ca53cf8451f94915e6949f0084047a2555a5fef4d1b0eef62ad5504a34ff631fbb658b011a07a82a53173f5c1"},{"other":"2a0fa7932768f0c316b478d15db556626def18462c3bee9446ff16c48fc43b6be1694a5783602b60250e33adc705b86fae7baa6b829146251995fd47980ce422","one":"faa3c31521c8f7b9d15838750e7e311eb0f01db5ef22cd1bf62a7d72e7efdf5a575550c930d96230edc892d107d4551e95b099d3c952a7f1c0ad3b5967c7831b","up":true},{"other":"123633b35f455fc3240d99929dc3130bb018545672be151ba973915f2ab6e6c862748f60d917e48ccbf28620c4e58b888867cb51e12ec0d2e5c61cef82258719","one":"334b59c2767fc786551dfdc0a9fcd6f5b53cbe48ddc1ca61b84f8155a15de7e8cd44cbb3a537e1aa7f11416eb710c5de916a5e8ce24e83bfa570b7344c5873ea","up":true},{"up":true,"one":"c708e3584cd9450b30d8cdd960a676884f64364c2aec985eebb4a0d745f6c73b6b0cb16f330bf090320bc48a5a67e8519b3c2c4a64cf2eff9aa4f1fc0b274a00","other":"f394aaa6d14c6ed95e2ad4651b5103bb1ab9f3a61839936cc1f08d6a6e53504e5d15dfc5211539ffdbdc64912ded5c2272d4af52ed8d7fe5a3c228eb12f0c68b"},{"other":"2a0fa7932768f0c316b478d15db556626def18462c3bee9446ff16c48fc43b6be1694a5783602b60250e33adc705b86fae7baa6b829146251995fd47980ce422","up":true,"one":"a302bebe4590b3f6d2c511919ceef4a5a80d431f53f8f3483c4b833a6a3b5f79b4c66c0ce2c0e5bc696534067ea5cd07772a9844ee0ba9d37a2e6f5d4bfb05cd"},{"up":true,"one":"a4dd67ab4fff1a50968c7ab59c304eb0083b072fc13dff599eeadac4e0e75099f7c825f91dd1bb770f3ae6f3d1d82ad574d6ecb117adf1ca9ccbccd01303ec7c","other":"f8fd12d8b5872b74e2cfa60d6a3a25b568a1fb4be3a8d06faac02a38321f419c443e517c0e2989001635f827add1859a2dc9589a9c0f5bf3804d46f43f799116"},{"other":"f87c2dea026ba5e6cda9a446821bf057d3453fa8c9b38fd882a09979ff3cfe2b8adfcbd5cf28d268776414bd12a9aba385d5c97c76a29c1b0625b101faac761d","one":"66652e041752f4acb27bc45c9c8b58f4f4ea904345a887a49ae831bef3bb1ad26cff7fd0f66ef3c28d6c41e039e39ff983710fdd5384f849595a66e5509e0d10","up":true},{"up":true,"one":"53031cddf4390ba176d638456016028bd4538879c7eaba672c3ef70208319a14e6a41dea8ff003b6f7e9b4a83ca12dab50d4f44f079153bec7c24221e311573e","other":"69f3f9fafff951dca2fe98baa178e53f2779311a93fdc364cf4c2477700c8dbce7e4201c3aa6d840b5ae65e8fc9d6603cbc41dbdf601f1998caedee1b542d72b"},{"other":"e0cacf6abdbfd9a25b9f974600662d4eae484efcdefd0a2a8fbc799127b6fabf2f471aff89c3a08e93ea20be1c304320598ba20a13697a356bf065292ba16bc1","up":true,"one":"fa4174ca214905c4136e891e64349f664f166aeeacead6f6e84892ebcadd2c7fbff07052ea4913a9465999f5494962ec29f7f7a3e6cbb993e00d1b881fb31eb1"},{"other":"0c000879be78fc867857011e396e2dd77bc2a0c6c2c3624d98b102737aa8d998ca9081653c0c8285117a5288b1bfeed06c54b2f6e39225aca4a21ff2a72116e1","up":true,"one":"2a0fa7932768f0c316b478d15db556626def18462c3bee9446ff16c48fc43b6be1694a5783602b60250e33adc705b86fae7baa6b829146251995fd47980ce422"},{"up":true,"one":"f2ac738fa932c90a45d1a64e4a52fd9c4037e2d89ceef1584efef04689bc7aff3a9635fb78dfdf3480d003daf14359190b1cfa8335db438a54107d4060ed58f9","other":"9b3fecfc63256a9d69e75ccb5119b2866e30fa4516b3a3bf5b2f03f04f1d20de786ddb90fa2acadb2a0509503b21fc9d16238c57f9b102ceedb6b27ee1b2c4ea"},{"other":"f87c2dea026ba5e6cda9a446821bf057d3453fa8c9b38fd882a09979ff3cfe2b8adfcbd5cf28d268776414bd12a9aba385d5c97c76a29c1b0625b101faac761d","one":"c4dfcf348694971fb36ed91e9024302bec8df3891540cbe1f5df26eee9c1f81a95295f05b90ec30dd044a0355dcaa805b9f50e95f38e5588a929cfe10e8cd73d","up":true},{"other":"0e07d2eb15905a583532383cef08b0881878c5043c4d7bae2cf1cace9954bfbbfbe0c1e8322eabbc84bc94cda08ae9b70cbdc56a1b8a19f807bcd5ca7939669d","up":true,"one":"946b3f821a4b61661e8ace52f4ade415042fddf058d97a16f08d9eff7a0be633de47c27fa9760ff38d583b2405163d4a27d3a7949d4015271396c014043a34e3"},{"other":"b1bef03357528618be6936a7edae5e3d4ecc942d43bd301642d321a73a07f3327d413f923c3fdd49d04f311e18709a4dde7519722d7a4912f181aa4df2e60173","one":"45c635c4080d47e2f932c27472e487ec95b7644c3d94d8627166a33dca2e3cbaa3305ae2d42e1510bfb0f8329b90e5a31883b399a469ad548fcae3040a8833a0","up":true},{"one":"c677530a47ef470ae0811127b91c231ec8889588bd096c24a54cc48099e8edde811f4a72eedc79118acb494ef031d6adcef1595d1a17df71b25b468478e931ff","up":true,"other":"69f3f9fafff951dca2fe98baa178e53f2779311a93fdc364cf4c2477700c8dbce7e4201c3aa6d840b5ae65e8fc9d6603cbc41dbdf601f1998caedee1b542d72b"},{"other":"f394aaa6d14c6ed95e2ad4651b5103bb1ab9f3a61839936cc1f08d6a6e53504e5d15dfc5211539ffdbdc64912ded5c2272d4af52ed8d7fe5a3c228eb12f0c68b","up":true,"one":"5a59a44ba2bf5e77f921216ac467733c8529b06790efb05a63c410060edaf65547a2dbb37333073e3bcf68d422ba4b135432307f90394c6edd6dd33dd6ff2152"},{"one":"0c000879be78fc867857011e396e2dd77bc2a0c6c2c3624d98b102737aa8d998ca9081653c0c8285117a5288b1bfeed06c54b2f6e39225aca4a21ff2a72116e1","up":true,"other":"faa3c31521c8f7b9d15838750e7e311eb0f01db5ef22cd1bf62a7d72e7efdf5a575550c930d96230edc892d107d4551e95b099d3c952a7f1c0ad3b5967c7831b"},{"one":"5a27b90639d515cad7794dae78bf9a9866cca23c5e3e18870524d148797ba1bdfd631151f23062d4dcf0961a7dba709431a44e39da29ed5ea4b0b6987514e433","up":true,"other":"55beb7853107501c013283d0114f9812c2e97b292f90ae9bdd5aa8189d0379a758cbf19c5fa62436bc75a6e30d935a3bd52025b06efd167fa2fb8a1caead2f83"},{"up":true,"one":"850e729f9bbb5ef6e12baf7d3dced180839e88e0845baa7aa8fb87dcb417aa74af5999bda81723aabbef5eda842fa4b5fae107fcff9f6bd50597e8ba6a849dff","other":"cf03d32d3cca446e7016e7f41267a257bef7142c4f1e4ce2e17678856d75e9889e21972fd21583297a47a156543af15400444dcf37aca64543f97f73734f7f0f"},{"other":"b1bef03357528618be6936a7edae5e3d4ecc942d43bd301642d321a73a07f3327d413f923c3fdd49d04f311e18709a4dde7519722d7a4912f181aa4df2e60173","one":"223d79f656e3f124ee1238ca46e42c2a0d8500ee58a37312c6b72657a11ad9ebce3be4c061611b913a22863f6e7936ff37602dedc7856baea27e8201db44bbf4","up":true},{"up":true,"one":"ac6057677fdfc132ea2418ff877357962771db049d169ba2c1923b15820385c6bf2f5846943d44a73bfdeb44a1e0d68307003a06cb0f694705879f8a720c3296","other":"7e9a81d06e997a691cc7790d358868b8657db608795ef6b85bb194db7f56ab5c76cac3be0b40d847ce873aeef4bdad40b725d69f4c42755b9d5aab4fe7aecb34"},{"other":"c708e3584cd9450b30d8cdd960a676884f64364c2aec985eebb4a0d745f6c73b6b0cb16f330bf090320bc48a5a67e8519b3c2c4a64cf2eff9aa4f1fc0b274a00","one":"972b7f6c5b926b93a9b005bb8a891c29e535a465c586bcd4258d4094e320925a179e8f63478917f8a88d1911fe8f868013abeb34817832ed4b0b209ce392f20b","up":true},{"up":true,"one":"c49e963a92b93a1c48fd3e38c127bfc88fbcb15b57bfdf8615c0e591b24276d4fe153a811932aefdcf3dee494d53ce354ba052c24313a725d562c6e807ab9133","other":"dee5fb5ccdfe3803cab3e0041c5c4879001bf2c2233446f47245d8234642046269bfe50e414cd2d89341e338597f2ecbb7b2912c20558a85041b757a24490805"},{"one":"ed3a5d7602b59bd8709ef10cb84e4b5644a69490d1173a8b9135adba04b36c1fcd0f16543de39deff0e76d8314e6884ba939213f77abb8d50a68d030352cb495","up":true,"other":"a2719942ffb6e99bda131cdedb612785dafdf72f5f35824343ad39d8568d6cd25e44b585a915c8e9ea2b02e6fd38c105bb17ed27c8fa320f18c83e0ace78feb5"},{"other":"faa3c31521c8f7b9d15838750e7e311eb0f01db5ef22cd1bf62a7d72e7efdf5a575550c930d96230edc892d107d4551e95b099d3c952a7f1c0ad3b5967c7831b","up":true,"one":"a16326a0c540731e0964c4bc10c1342346fcfee70c7d1d8d333cbb774cb9f49dbf92585595654c99253eac21373706247bf5ef1ba40ac03e62da00821991cf7d"},{"other":"f78ecf420b73cd0245807157c0cbaaa568c60c80965413e187b084fb26041761d12790c0cb6a39bc8997fd2b3d3f52c831e601f1f1846945fba1808b0e1cdf25","up":true,"one":"c7566a0efd78ba35ad27a51a7ec8fcd55944ae12f9933573e71e2ad7404d48037dad9063c10ce5af636d7641a03899333d01aa9be94716d2179fdb2af33f36c4"},{"other":"f3bf16c7156ce55af92b2fc21826bdfd3e1f245c6087e76f5eb23cc8bbd88b25515a32029d3e6e2b4a27354606e9e3bdfe78788e326c4349d63416894fcfbaf4","one":"6ba8900830489793a22bf5023cde4ab849dee525d1ca5b95e21040a8e8be5b295317b1c76e09beb7d17a9512137c487b99f16933622b5f2b0e10da3233086bbf","up":true},{"one":"4228ad29aa22f1fa078c7e09f44f85c05d5b797072c10ade24dcbff95c01e554511fe10273a5f25a25ca06ff97bca28c241610f7145983f72ed44969ead4596a","up":true,"other":"d6c3095290d455c3855cfa88ee5f10d1975fdb0cc7ebc9aaa2330658e4229b9850f70f17798e530b50907d3d0d27fa49c0ed7dd4a7913d53c6881c5c86f380b8"},{"one":"54b79d3662ba486bbd120313d59ef101acf963eb3d6112a9dda121bc0b52f4b1fbcb13406705cdd8c2d3990ad296171c7972211467cc0d44cbe9ca16fbc82e3e","up":true,"other":"59fe05843cc637adac3728acb8ca9650f49050095cf5d32241366f54d4ac7179b16dcb009e2fb9fa9499cc6f8b865b6c4d6fe6e35500df10ba5daa719d57976e"},{"other":"f8fd12d8b5872b74e2cfa60d6a3a25b568a1fb4be3a8d06faac02a38321f419c443e517c0e2989001635f827add1859a2dc9589a9c0f5bf3804d46f43f799116","up":true,"one":"e20a90f36eca4329d3d2dbadf530949889dc20b0ae5d96b935af9b60d26ec507e9eb1b73fd2b4dc88057c20e4ef6e7039cc49652d35c563db64f06f979e28540"},{"other":"45c635c4080d47e2f932c27472e487ec95b7644c3d94d8627166a33dca2e3cbaa3305ae2d42e1510bfb0f8329b90e5a31883b399a469ad548fcae3040a8833a0","up":true,"one":"4228ad29aa22f1fa078c7e09f44f85c05d5b797072c10ade24dcbff95c01e554511fe10273a5f25a25ca06ff97bca28c241610f7145983f72ed44969ead4596a"},{"other":"9b3fecfc63256a9d69e75ccb5119b2866e30fa4516b3a3bf5b2f03f04f1d20de786ddb90fa2acadb2a0509503b21fc9d16238c57f9b102ceedb6b27ee1b2c4ea","one":"b737c81fe6bc50d977231a5fc8856f064ba58190c5ab5615d3cf634aea8c15a308f3a667aad2e69d5c1438549cd41c863fd40f643b70caf3e0c934276ef2a84f","up":true},{"up":true,"one":"1cc62520c0d9c6a47d96e485bdc6a5d0f7319477ad6d177663f7b49217f5a8e56e4717f36fb5aa11c5270d4383cab460219821bcc6c9cbcccc4a97446b406d96","other":"0bf28b481d71062ee100d6cb04c8b4234a574f8657e2d3c49b60a9ecdbf486d0ec38b33bce745c8efe820145d5c53ea802aa64b4f9bce19b029ee5b2f9de43f1"},{"one":"09fa1e69f37cb14db3dd721a9c4b9c884f6fe519d850f7af3643ecd536d4b3e995f99acf569e23b7864996c750115ff0ca0bd446ebfd76a026da71da0b95fd97","up":true,"other":"55beb7853107501c013283d0114f9812c2e97b292f90ae9bdd5aa8189d0379a758cbf19c5fa62436bc75a6e30d935a3bd52025b06efd167fa2fb8a1caead2f83"},{"other":"ac6057677fdfc132ea2418ff877357962771db049d169ba2c1923b15820385c6bf2f5846943d44a73bfdeb44a1e0d68307003a06cb0f694705879f8a720c3296","one":"c133cd3ee228f427410357f46752d33ecf302475314411772df3532669a8b220136c09f00717460c39bcea1058cb988dd223875ec991612876b400556f5937dd","up":true},{"one":"7625a1a0a0f5bf78e2b9fe43a1215ea882318458b886ec767ccbc35e76b543f96820b364342b28ff600302af7716280497141dc2fc84e83cb15f5eb3d268d73e","up":true,"other":"223d79f656e3f124ee1238ca46e42c2a0d8500ee58a37312c6b72657a11ad9ebce3be4c061611b913a22863f6e7936ff37602dedc7856baea27e8201db44bbf4"},{"up":true,"one":"4903cd53b3ffc4328547e03dec8f7992edbfb1e1697e53772ef79887984b11595167eb84015ff3dfb26ac0d7b2e98b7a0792bef843d2bdff3a76889fc4a6c60a","other":"3db9984cb1e25bdc30c483f3d4c036fb1728bafffecd2b965af7e701569c28116dbed2e5892504ea9927c14570351b03cb99112a5924a27e6e03289422785c7b"},{"up":true,"one":"193ca2ef8a4ac98c0300d7e48421ba3fe5d4789a0c2b476499bd093808c3988b4a55742ff3f607429cafda08cbbb5fba68da8869747b1b5169f3e4545497de3a","other":"55beb7853107501c013283d0114f9812c2e97b292f90ae9bdd5aa8189d0379a758cbf19c5fa62436bc75a6e30d935a3bd52025b06efd167fa2fb8a1caead2f83"},{"up":true,"one":"d2cf35afdb846755290a7c3a1a36758e735a4eeed57b1af66595c55ab45c52cf2c478de3f395b38513cdc9e49568892cce490de93074fa45b640628f0fe40719","other":"6070dc131e9721a4a496b3ed6ff5c9db1a5351e942ed424b86fe6be940d1012df766afb4b0112452dfd63e0fcfea13658324a9ef4a94b5754ec9f6219e4b0d67"},{"other":"0c000879be78fc867857011e396e2dd77bc2a0c6c2c3624d98b102737aa8d998ca9081653c0c8285117a5288b1bfeed06c54b2f6e39225aca4a21ff2a72116e1","up":true,"one":"d6794744c5f941cb6dbac4adbbbf11ce83c9224c8a34b9c787ed5975bf0af13e095a7db1c86fcbb7b134ae6dc67467d3ffaf191f4a4d9218779c4d0cf86876ca"},{"other":"5a59a44ba2bf5e77f921216ac467733c8529b06790efb05a63c410060edaf65547a2dbb37333073e3bcf68d422ba4b135432307f90394c6edd6dd33dd6ff2152","up":true,"one":"8b8c15c6329096267a25d4060ee19963afb6e776fea60d9d566d4e1f9b087581b36e33fc533d7f133668a7a6a22f81a1234ed9fbce26eff1d5e5691a6148d540"},{"other":"7e9a81d06e997a691cc7790d358868b8657db608795ef6b85bb194db7f56ab5c76cac3be0b40d847ce873aeef4bdad40b725d69f4c42755b9d5aab4fe7aecb34","one":"b440e8bc7d39b8cf9cca03b343c83ba8dd673062cead7bbfce6ed77ea16fa61f0b81df31fc418f4c133d1bb104939ac1b6e5f5a76fbcf50141a1ea33dfeb86e5","up":true},{"other":"236266f9f5a28148d11bed1195a91cd1d30231b082697ee1940a85abca98d2ff0767be9128c23375caa0444bcf51d8501879200ea0f27f13d0ede37f97241325","up":true,"one":"1545795dca07ecd09c5b16b3bbdddf3dba92e27b532c18a3bc63bc007761ac1b1ebc7ffb4f0a401d5376a4c67923c7949edaebd8f65fff52d6677bb1d6a72f43"},{"one":"071c094246a0ca4b5d169e43a20ce5da508e579a6e2e822462bd8948ab357d46ab477bcff0c80eba2e01f0c100690b307af40d47c52ebad06783e9e77466cbd6","up":true,"other":"c49e963a92b93a1c48fd3e38c127bfc88fbcb15b57bfdf8615c0e591b24276d4fe153a811932aefdcf3dee494d53ce354ba052c24313a725d562c6e807ab9133"},{"one":"f4ae36400caeddcbcf0fb1abd5b9611c37bac683645d10c69a1ac54d366f730c59917c95e990a0fa6bb2679c98fb62bf0e29bd7812ab57375de35f469dab98a0","up":true,"other":"e706876f36646bfb2dfbd11669a4907432660023a13be9de329a03f6c6e88e3788002b83d0cb4617e6c4096998783925be5b1de4f0edd8128e7d71312fb1091d"},{"other":"f78ecf420b73cd0245807157c0cbaaa568c60c80965413e187b084fb26041761d12790c0cb6a39bc8997fd2b3d3f52c831e601f1f1846945fba1808b0e1cdf25","up":true,"one":"a13086041114db2be31038987ac3fdcaeb99489f1b6ee9b22998b9e66dc2f2f024307d9474811e7e8be1b1acf5a55305d5cce27d87fb834ed1e1d2e17319bb85"},{"other":"5a27b90639d515cad7794dae78bf9a9866cca23c5e3e18870524d148797ba1bdfd631151f23062d4dcf0961a7dba709431a44e39da29ed5ea4b0b6987514e433","one":"a8b619f75e0e4cf7bc5e425ff9b03e55b7301fec4fb58f321bf89811678268d9f738bbf22ee36c2d14ff71a08d6f7dca28249ff6f943cc5a77653f482254d150","up":true},{"one":"66652e041752f4acb27bc45c9c8b58f4f4ea904345a887a49ae831bef3bb1ad26cff7fd0f66ef3c28d6c41e039e39ff983710fdd5384f849595a66e5509e0d10","up":true,"other":"0bf28b481d71062ee100d6cb04c8b4234a574f8657e2d3c49b60a9ecdbf486d0ec38b33bce745c8efe820145d5c53ea802aa64b4f9bce19b029ee5b2f9de43f1"},{"one":"d6c3095290d455c3855cfa88ee5f10d1975fdb0cc7ebc9aaa2330658e4229b9850f70f17798e530b50907d3d0d27fa49c0ed7dd4a7913d53c6881c5c86f380b8","up":true,"other":"223d79f656e3f124ee1238ca46e42c2a0d8500ee58a37312c6b72657a11ad9ebce3be4c061611b913a22863f6e7936ff37602dedc7856baea27e8201db44bbf4"},{"up":true,"one":"bebbde654a4f3e3e65f63d10cbcc89dfd46ce75945c19be33bfe4d954c8ed375981e21a8376ad10e402dddbcf3b657e6786c0820e599a0d1fe03f8d35294d7c7","other":"ef3016ea5a7b1b57388904d5c80fd05780d23acec8cf73e8add28ea99c6222fa84e89a1752186a2ef41dd0ec828405e61a1e8fd67d9496d75525ed860b12e2e8"},{"one":"236266f9f5a28148d11bed1195a91cd1d30231b082697ee1940a85abca98d2ff0767be9128c23375caa0444bcf51d8501879200ea0f27f13d0ede37f97241325","up":true,"other":"e2956a828cb1ff85ab55bdbe329f530662558cb8013ffddacac8ba36096abea07ecb15b54896dd9b4bb0b15155654dbda0c031f69290f2314ac0e376bebbd864"},{"other":"e90ca22b959d482861c52e9e51fd2d63557453dce64dab9f66fcf323273c12e7189358f85d500f5200ff7c7b2d57afe72577ed9aa2adb36fc0c8e5504588fe94","up":true,"one":"fa4174ca214905c4136e891e64349f664f166aeeacead6f6e84892ebcadd2c7fbff07052ea4913a9465999f5494962ec29f7f7a3e6cbb993e00d1b881fb31eb1"},{"up":true,"one":"aa108a30f86b8296b416ea9fd6bc7a21c65c7cd3911ca3d4ee79325912d80db7150c02d304e49c5d0feafbd222edd6d522661a0983f1d427981760712f31e6f1","other":"45c635c4080d47e2f932c27472e487ec95b7644c3d94d8627166a33dca2e3cbaa3305ae2d42e1510bfb0f8329b90e5a31883b399a469ad548fcae3040a8833a0"},{"up":true,"one":"850e729f9bbb5ef6e12baf7d3dced180839e88e0845baa7aa8fb87dcb417aa74af5999bda81723aabbef5eda842fa4b5fae107fcff9f6bd50597e8ba6a849dff","other":"3db9984cb1e25bdc30c483f3d4c036fb1728bafffecd2b965af7e701569c28116dbed2e5892504ea9927c14570351b03cb99112a5924a27e6e03289422785c7b"},{"up":true,"one":"6ba8900830489793a22bf5023cde4ab849dee525d1ca5b95e21040a8e8be5b295317b1c76e09beb7d17a9512137c487b99f16933622b5f2b0e10da3233086bbf","other":"4f4201d959e4add3a4bcf3cbaab29d8abcc7530a9834e3cde45c4459ea92fba869e65156037a8fae02eac05f6174a7f2c1d825418f2207caa2284bcc9d9b84d1"},{"up":true,"one":"54b79d3662ba486bbd120313d59ef101acf963eb3d6112a9dda121bc0b52f4b1fbcb13406705cdd8c2d3990ad296171c7972211467cc0d44cbe9ca16fbc82e3e","other":"cc94ed069ddcc24dc2733eed5ba8367a2521a5955c7287c5280c71675b9965ee8499454b227a4ddc64a14d74b39916211763ddf0b7ad80a52381cc61dcb6c72c"},{"other":"0d85f39dca79f99b277ad5cedfcd3fb1eccc7862c95c215ba0d5a2ec1c4fa80244393d0934cf59fe988f7716bf15cb8e79f4ee03fbe4a48a10cac6e0610f9d55","up":true,"one":"b737c81fe6bc50d977231a5fc8856f064ba58190c5ab5615d3cf634aea8c15a308f3a667aad2e69d5c1438549cd41c863fd40f643b70caf3e0c934276ef2a84f"},{"other":"5a27b90639d515cad7794dae78bf9a9866cca23c5e3e18870524d148797ba1bdfd631151f23062d4dcf0961a7dba709431a44e39da29ed5ea4b0b6987514e433","one":"09fa1e69f37cb14db3dd721a9c4b9c884f6fe519d850f7af3643ecd536d4b3e995f99acf569e23b7864996c750115ff0ca0bd446ebfd76a026da71da0b95fd97","up":true},{"other":"c708e3584cd9450b30d8cdd960a676884f64364c2aec985eebb4a0d745f6c73b6b0cb16f330bf090320bc48a5a67e8519b3c2c4a64cf2eff9aa4f1fc0b274a00","one":"123633b35f455fc3240d99929dc3130bb018545672be151ba973915f2ab6e6c862748f60d917e48ccbf28620c4e58b888867cb51e12ec0d2e5c61cef82258719","up":true},{"other":"de7ab7b9a2ba4ed523b84233fae11d93815579976ea78b385c658a4c156622747051f91342f9ac3610e22ee259b65e02b5af0ab67a9ee04ab6958a9d0d8acdf1","up":true,"one":"7625a1a0a0f5bf78e2b9fe43a1215ea882318458b886ec767ccbc35e76b543f96820b364342b28ff600302af7716280497141dc2fc84e83cb15f5eb3d268d73e"},{"up":true,"one":"eb6fa7d39fcee5a7081813169ae24ee6d355cfe717dcb2fa500a07c935ffbe1b12378ea13454742bf7c2df10ad2fd4e53476068eaef4669381c8cd060c199e11","other":"fd321c630fadcc8d6b00589323f7313ac1e94effbe8192955da5f88dcf419ef28820075e0e81c595561ff6ee58cfce23079407edf8b1611cb994946bcbd26364"},{"other":"c708e3584cd9450b30d8cdd960a676884f64364c2aec985eebb4a0d745f6c73b6b0cb16f330bf090320bc48a5a67e8519b3c2c4a64cf2eff9aa4f1fc0b274a00","one":"4903cd53b3ffc4328547e03dec8f7992edbfb1e1697e53772ef79887984b11595167eb84015ff3dfb26ac0d7b2e98b7a0792bef843d2bdff3a76889fc4a6c60a","up":true},{"one":"d6794744c5f941cb6dbac4adbbbf11ce83c9224c8a34b9c787ed5975bf0af13e095a7db1c86fcbb7b134ae6dc67467d3ffaf191f4a4d9218779c4d0cf86876ca","up":true,"other":"071c094246a0ca4b5d169e43a20ce5da508e579a6e2e822462bd8948ab357d46ab477bcff0c80eba2e01f0c100690b307af40d47c52ebad06783e9e77466cbd6"},{"other":"519ce8f43529d0c703ef4faf50450877dc2818fd6fd6b7faaa9bbbaeac373e499d1b4a17b387b1a8d35e8042e18a9d3d365c97254b4d24352b10e8de9219a5cd","one":"f78ecf420b73cd0245807157c0cbaaa568c60c80965413e187b084fb26041761d12790c0cb6a39bc8997fd2b3d3f52c831e601f1f1846945fba1808b0e1cdf25","up":true},{"other":"3db9984cb1e25bdc30c483f3d4c036fb1728bafffecd2b965af7e701569c28116dbed2e5892504ea9927c14570351b03cb99112a5924a27e6e03289422785c7b","up":true,"one":"ef3016ea5a7b1b57388904d5c80fd05780d23acec8cf73e8add28ea99c6222fa84e89a1752186a2ef41dd0ec828405e61a1e8fd67d9496d75525ed860b12e2e8"},{"other":"e3779b202b9cfe7b2f2cc9e95974ac77bf51ba951f775acc10f07249ee6b3b260f2b012bb010a7f9794c5562e9b00f18b52c25c1e350ab70afc6bf9e210e4969","up":true,"one":"3e65bbf7103b3307bd9b8a65168c7c87c3f5283c7c52edefabf4193a1f04ac10216cc485a1dae17cff9ccea41bcf9a0b41de001c6142f30701443dc1735f25c0"},{"other":"af0050715bfa25b4ce3a7593c61578898be22801a9118064250c330c6b2a1416b3bc6d90b074d7d700e07574a274d861f9c6d8e3e5924c281502f699ad62465b","up":true,"one":"eeb9d718ef61c14e10ab2fb3a90b039368acd17a59f70628deb39515c227bd0916c796cd7767b1a9d4f38e04f1013173b21c1fa2e0206ecdc72df6c2621380a2"},{"other":"071c094246a0ca4b5d169e43a20ce5da508e579a6e2e822462bd8948ab357d46ab477bcff0c80eba2e01f0c100690b307af40d47c52ebad06783e9e77466cbd6","up":true,"one":"57fb9e7f287fe67500b8b560475c0d0d6eae9d623d5a8c85eb5459f209904a839a0b24ff99a1643a4196a71d45f2ed1bd5e08f9a13cdd9749a907a024ff984dc"},{"one":"af6cb988ddb16202459735b8489c02b3bf829ca301513a0d3e18bbb03d43c8de3cda767c7b5c984a6dce3f118c8089e06b08ed3bd0c922dde9cfe775609df3b2","up":true,"other":"af0050715bfa25b4ce3a7593c61578898be22801a9118064250c330c6b2a1416b3bc6d90b074d7d700e07574a274d861f9c6d8e3e5924c281502f699ad62465b"},{"other":"4f4201d959e4add3a4bcf3cbaab29d8abcc7530a9834e3cde45c4459ea92fba869e65156037a8fae02eac05f6174a7f2c1d825418f2207caa2284bcc9d9b84d1","one":"55beb7853107501c013283d0114f9812c2e97b292f90ae9bdd5aa8189d0379a758cbf19c5fa62436bc75a6e30d935a3bd52025b06efd167fa2fb8a1caead2f83","up":true},{"one":"49bd2289f479c9ad7e0d13319271b9be1e1dcbee28313513a124dec55f9842db639e62a74a83040930c537739ab7fa1e50bb05b9ab0f588d6da7b64a6451f466","up":true,"other":"5a59a44ba2bf5e77f921216ac467733c8529b06790efb05a63c410060edaf65547a2dbb37333073e3bcf68d422ba4b135432307f90394c6edd6dd33dd6ff2152"},{"up":true,"one":"de7ab7b9a2ba4ed523b84233fae11d93815579976ea78b385c658a4c156622747051f91342f9ac3610e22ee259b65e02b5af0ab67a9ee04ab6958a9d0d8acdf1","other":"4f4201d959e4add3a4bcf3cbaab29d8abcc7530a9834e3cde45c4459ea92fba869e65156037a8fae02eac05f6174a7f2c1d825418f2207caa2284bcc9d9b84d1"},{"up":true,"one":"dee5fb5ccdfe3803cab3e0041c5c4879001bf2c2233446f47245d8234642046269bfe50e414cd2d89341e338597f2ecbb7b2912c20558a85041b757a24490805","other":"59fe05843cc637adac3728acb8ca9650f49050095cf5d32241366f54d4ac7179b16dcb009e2fb9fa9499cc6f8b865b6c4d6fe6e35500df10ba5daa719d57976e"},{"other":"f3bf16c7156ce55af92b2fc21826bdfd3e1f245c6087e76f5eb23cc8bbd88b25515a32029d3e6e2b4a27354606e9e3bdfe78788e326c4349d63416894fcfbaf4","one":"3dcf5ec3ebb3b7de61dfaef4ee397a4a13a96ee40673be2eaadfcadd11f139c594c74237b40dd9c10f059f40d325c014f5b02b3a8eb7f0dc7d66ced7fea9f17f","up":true},{"other":"eeb9d718ef61c14e10ab2fb3a90b039368acd17a59f70628deb39515c227bd0916c796cd7767b1a9d4f38e04f1013173b21c1fa2e0206ecdc72df6c2621380a2","one":"b1bef03357528618be6936a7edae5e3d4ecc942d43bd301642d321a73a07f3327d413f923c3fdd49d04f311e18709a4dde7519722d7a4912f181aa4df2e60173","up":true},{"up":true,"one":"a302bebe4590b3f6d2c511919ceef4a5a80d431f53f8f3483c4b833a6a3b5f79b4c66c0ce2c0e5bc696534067ea5cd07772a9844ee0ba9d37a2e6f5d4bfb05cd","other":"e706876f36646bfb2dfbd11669a4907432660023a13be9de329a03f6c6e88e3788002b83d0cb4617e6c4096998783925be5b1de4f0edd8128e7d71312fb1091d"},{"one":"a4dd67ab4fff1a50968c7ab59c304eb0083b072fc13dff599eeadac4e0e75099f7c825f91dd1bb770f3ae6f3d1d82ad574d6ecb117adf1ca9ccbccd01303ec7c","up":true,"other":"af0050715bfa25b4ce3a7593c61578898be22801a9118064250c330c6b2a1416b3bc6d90b074d7d700e07574a274d861f9c6d8e3e5924c281502f699ad62465b"},{"other":"e706876f36646bfb2dfbd11669a4907432660023a13be9de329a03f6c6e88e3788002b83d0cb4617e6c4096998783925be5b1de4f0edd8128e7d71312fb1091d","up":true,"one":"946b3f821a4b61661e8ace52f4ade415042fddf058d97a16f08d9eff7a0be633de47c27fa9760ff38d583b2405163d4a27d3a7949d4015271396c014043a34e3"},{"other":"7e9a81d06e997a691cc7790d358868b8657db608795ef6b85bb194db7f56ab5c76cac3be0b40d847ce873aeef4bdad40b725d69f4c42755b9d5aab4fe7aecb34","up":true,"one":"06a8a25c6dd90e230237b06c086f14e539b31b8e3705752d0ad8faf1bd7239547332604b79b6124cbd0cee495b99a80f147983142b7271841d8d9fa85d559301"},{"other":"5c1e9692b731421d6eaca488e8ba4cfdda1933ac5f1504ece684fadbea07a7c8053feb73be7ce20aedeaecc84f14d836b5ed2a657df6ca04f4fc82c2da0c0d46","up":true,"one":"c677530a47ef470ae0811127b91c231ec8889588bd096c24a54cc48099e8edde811f4a72eedc79118acb494ef031d6adcef1595d1a17df71b25b468478e931ff"},{"other":"cc0d13dba120558dc8e2d0e5ac755a712e7e7e6dab6edcaf658faf02537b1efe3d6c54d6e67566eb4a3a8f8a019702aa7ee2b33ee3f0316a01e7b17845032e70","up":true,"one":"5a27b90639d515cad7794dae78bf9a9866cca23c5e3e18870524d148797ba1bdfd631151f23062d4dcf0961a7dba709431a44e39da29ed5ea4b0b6987514e433"},{"up":true,"one":"0c000879be78fc867857011e396e2dd77bc2a0c6c2c3624d98b102737aa8d998ca9081653c0c8285117a5288b1bfeed06c54b2f6e39225aca4a21ff2a72116e1","other":"c708e3584cd9450b30d8cdd960a676884f64364c2aec985eebb4a0d745f6c73b6b0cb16f330bf090320bc48a5a67e8519b3c2c4a64cf2eff9aa4f1fc0b274a00"},{"one":"223d79f656e3f124ee1238ca46e42c2a0d8500ee58a37312c6b72657a11ad9ebce3be4c061611b913a22863f6e7936ff37602dedc7856baea27e8201db44bbf4","up":true,"other":"4228ad29aa22f1fa078c7e09f44f85c05d5b797072c10ade24dcbff95c01e554511fe10273a5f25a25ca06ff97bca28c241610f7145983f72ed44969ead4596a"},{"other":"604a11bd1d969886953398ecc1fdf5847a946a8118014d0cb8daff9943f4f78c4bdbad3ee4152959c8265d0588dea658c262fe2f99a55a0b32321b81c8eec473","up":true,"one":"972b7f6c5b926b93a9b005bb8a891c29e535a465c586bcd4258d4094e320925a179e8f63478917f8a88d1911fe8f868013abeb34817832ed4b0b209ce392f20b"},{"one":"fd321c630fadcc8d6b00589323f7313ac1e94effbe8192955da5f88dcf419ef28820075e0e81c595561ff6ee58cfce23079407edf8b1611cb994946bcbd26364","up":true,"other":"e706876f36646bfb2dfbd11669a4907432660023a13be9de329a03f6c6e88e3788002b83d0cb4617e6c4096998783925be5b1de4f0edd8128e7d71312fb1091d"},{"one":"c49e963a92b93a1c48fd3e38c127bfc88fbcb15b57bfdf8615c0e591b24276d4fe153a811932aefdcf3dee494d53ce354ba052c24313a725d562c6e807ab9133","up":true,"other":"af761f8d13059f1e49d2f5c0b7a76a5eb5bcaab1e7ff01673dff3967d81bd7aebf74afef3934328034c82f131fa066de71816cff8f720e0c56d5e85b233a8a44"},{"other":"850e729f9bbb5ef6e12baf7d3dced180839e88e0845baa7aa8fb87dcb417aa74af5999bda81723aabbef5eda842fa4b5fae107fcff9f6bd50597e8ba6a849dff","up":true,"one":"a16326a0c540731e0964c4bc10c1342346fcfee70c7d1d8d333cbb774cb9f49dbf92585595654c99253eac21373706247bf5ef1ba40ac03e62da00821991cf7d"},{"one":"e90ca22b959d482861c52e9e51fd2d63557453dce64dab9f66fcf323273c12e7189358f85d500f5200ff7c7b2d57afe72577ed9aa2adb36fc0c8e5504588fe94","up":true,"other":"540598224dccc717053f94e915652df499f513dc0c8874ce999040e1aa829c33ede284c72ddd0b24a319821102fa42aaaaa87380e777b5878455de61f5fc2ac9"},{"other":"cc94ed069ddcc24dc2733eed5ba8367a2521a5955c7287c5280c71675b9965ee8499454b227a4ddc64a14d74b39916211763ddf0b7ad80a52381cc61dcb6c72c","up":true,"one":"c7566a0efd78ba35ad27a51a7ec8fcd55944ae12f9933573e71e2ad7404d48037dad9063c10ce5af636d7641a03899333d01aa9be94716d2179fdb2af33f36c4"},{"up":true,"one":"334b59c2767fc786551dfdc0a9fcd6f5b53cbe48ddc1ca61b84f8155a15de7e8cd44cbb3a537e1aa7f11416eb710c5de916a5e8ce24e83bfa570b7344c5873ea","other":"fd321c630fadcc8d6b00589323f7313ac1e94effbe8192955da5f88dcf419ef28820075e0e81c595561ff6ee58cfce23079407edf8b1611cb994946bcbd26364"},{"up":true,"one":"84379884f012e2cfc1f9838312640576c9ded01ca53cf8451f94915e6949f0084047a2555a5fef4d1b0eef62ad5504a34ff631fbb658b011a07a82a53173f5c1","other":"b1bef03357528618be6936a7edae5e3d4ecc942d43bd301642d321a73a07f3327d413f923c3fdd49d04f311e18709a4dde7519722d7a4912f181aa4df2e60173"},{"other":"f87c2dea026ba5e6cda9a446821bf057d3453fa8c9b38fd882a09979ff3cfe2b8adfcbd5cf28d268776414bd12a9aba385d5c97c76a29c1b0625b101faac761d","up":true,"one":"7172a86afb608acd9a3e1e5c0472489ebecb516cad6796fa9a06ab47cc8e8cce12dddce72f0ac3b0927602bd22ed5872c3b5ce9b6af96f8e9d1d75078cc9bb55"},{"one":"11170a0fb9f6b037f8ee4494e935a84b06816ff5c44ef9d613920f9c58f8b25611b2093da3fb51a59687db6a9b0a070386cac09757a27f75754cbdcb9afc2225","up":true,"other":"604a11bd1d969886953398ecc1fdf5847a946a8118014d0cb8daff9943f4f78c4bdbad3ee4152959c8265d0588dea658c262fe2f99a55a0b32321b81c8eec473"},{"up":true,"one":"eb6fa7d39fcee5a7081813169ae24ee6d355cfe717dcb2fa500a07c935ffbe1b12378ea13454742bf7c2df10ad2fd4e53476068eaef4669381c8cd060c199e11","other":"a2719942ffb6e99bda131cdedb612785dafdf72f5f35824343ad39d8568d6cd25e44b585a915c8e9ea2b02e6fd38c105bb17ed27c8fa320f18c83e0ace78feb5"},{"up":true,"one":"0e07d2eb15905a583532383cef08b0881878c5043c4d7bae2cf1cace9954bfbbfbe0c1e8322eabbc84bc94cda08ae9b70cbdc56a1b8a19f807bcd5ca7939669d","other":"aa108a30f86b8296b416ea9fd6bc7a21c65c7cd3911ca3d4ee79325912d80db7150c02d304e49c5d0feafbd222edd6d522661a0983f1d427981760712f31e6f1"},{"one":"9158b9eb87bf7d011f83febca8f9d6575dd05be1f7e7bc18336f802651a379dd181a0503b5a8e46a580c59889998b16275f1e0ce4dce965cdbe72265ad2be283","up":true,"other":"0c000879be78fc867857011e396e2dd77bc2a0c6c2c3624d98b102737aa8d998ca9081653c0c8285117a5288b1bfeed06c54b2f6e39225aca4a21ff2a72116e1"},{"one":"5c1e9692b731421d6eaca488e8ba4cfdda1933ac5f1504ece684fadbea07a7c8053feb73be7ce20aedeaecc84f14d836b5ed2a657df6ca04f4fc82c2da0c0d46","up":true,"other":"a302bebe4590b3f6d2c511919ceef4a5a80d431f53f8f3483c4b833a6a3b5f79b4c66c0ce2c0e5bc696534067ea5cd07772a9844ee0ba9d37a2e6f5d4bfb05cd"},{"other":"cf03d32d3cca446e7016e7f41267a257bef7142c4f1e4ce2e17678856d75e9889e21972fd21583297a47a156543af15400444dcf37aca64543f97f73734f7f0f","up":true,"one":"a1b07c24605e258db7b8fb15db227596b08dc69bb234c0a48c312eb6eb1fb08553f8c8a6da7175eea258e2d3f2625a540c1466e6c31315aa1484fa173b7a8cfc"},{"up":true,"one":"af761f8d13059f1e49d2f5c0b7a76a5eb5bcaab1e7ff01673dff3967d81bd7aebf74afef3934328034c82f131fa066de71816cff8f720e0c56d5e85b233a8a44","other":"f78ecf420b73cd0245807157c0cbaaa568c60c80965413e187b084fb26041761d12790c0cb6a39bc8997fd2b3d3f52c831e601f1f1846945fba1808b0e1cdf25"},{"other":"0c000879be78fc867857011e396e2dd77bc2a0c6c2c3624d98b102737aa8d998ca9081653c0c8285117a5288b1bfeed06c54b2f6e39225aca4a21ff2a72116e1","one":"a2719942ffb6e99bda131cdedb612785dafdf72f5f35824343ad39d8568d6cd25e44b585a915c8e9ea2b02e6fd38c105bb17ed27c8fa320f18c83e0ace78feb5","up":true},{"other":"0c000879be78fc867857011e396e2dd77bc2a0c6c2c3624d98b102737aa8d998ca9081653c0c8285117a5288b1bfeed06c54b2f6e39225aca4a21ff2a72116e1","one":"9ad5ec0e729f9db10b7028788b58ef13d54bd11529b494a549d0415b90777b63fe78a752356315f5abbd24d849edc0c8bfe9d82c05460c30f4dad860ff5fea48","up":true},{"other":"c708e3584cd9450b30d8cdd960a676884f64364c2aec985eebb4a0d745f6c73b6b0cb16f330bf090320bc48a5a67e8519b3c2c4a64cf2eff9aa4f1fc0b274a00","one":"cf03d32d3cca446e7016e7f41267a257bef7142c4f1e4ce2e17678856d75e9889e21972fd21583297a47a156543af15400444dcf37aca64543f97f73734f7f0f","up":true},{"other":"ed3a5d7602b59bd8709ef10cb84e4b5644a69490d1173a8b9135adba04b36c1fcd0f16543de39deff0e76d8314e6884ba939213f77abb8d50a68d030352cb495","one":"e706876f36646bfb2dfbd11669a4907432660023a13be9de329a03f6c6e88e3788002b83d0cb4617e6c4096998783925be5b1de4f0edd8128e7d71312fb1091d","up":true},{"one":"aa108a30f86b8296b416ea9fd6bc7a21c65c7cd3911ca3d4ee79325912d80db7150c02d304e49c5d0feafbd222edd6d522661a0983f1d427981760712f31e6f1","up":true,"other":"ef3016ea5a7b1b57388904d5c80fd05780d23acec8cf73e8add28ea99c6222fa84e89a1752186a2ef41dd0ec828405e61a1e8fd67d9496d75525ed860b12e2e8"},{"one":"53031cddf4390ba176d638456016028bd4538879c7eaba672c3ef70208319a14e6a41dea8ff003b6f7e9b4a83ca12dab50d4f44f079153bec7c24221e311573e","up":true,"other":"123633b35f455fc3240d99929dc3130bb018545672be151ba973915f2ab6e6c862748f60d917e48ccbf28620c4e58b888867cb51e12ec0d2e5c61cef82258719"},{"one":"7ca32d24c001557a81af351ac71322543154eeedbb6ccdd8b8b142f19215aa712218babe9701e73a6441784375a511c1f16a70569b73416f9708409564d18485","up":true,"other":"96f3194c9ef17f60c318be14dd72c51af0aebc19f7a574b769d18b1fda6791409c827892bae3a061800e3d78af88a97635a0a892c54d7ebb38342ab1ba99c3ad"},{"up":true,"one":"cc94ed069ddcc24dc2733eed5ba8367a2521a5955c7287c5280c71675b9965ee8499454b227a4ddc64a14d74b39916211763ddf0b7ad80a52381cc61dcb6c72c","other":"dee5fb5ccdfe3803cab3e0041c5c4879001bf2c2233446f47245d8234642046269bfe50e414cd2d89341e338597f2ecbb7b2912c20558a85041b757a24490805"},{"other":"59fe05843cc637adac3728acb8ca9650f49050095cf5d32241366f54d4ac7179b16dcb009e2fb9fa9499cc6f8b865b6c4d6fe6e35500df10ba5daa719d57976e","one":"e20a90f36eca4329d3d2dbadf530949889dc20b0ae5d96b935af9b60d26ec507e9eb1b73fd2b4dc88057c20e4ef6e7039cc49652d35c563db64f06f979e28540","up":true},{"other":"ac6057677fdfc132ea2418ff877357962771db049d169ba2c1923b15820385c6bf2f5846943d44a73bfdeb44a1e0d68307003a06cb0f694705879f8a720c3296","up":true,"one":"a2719942ffb6e99bda131cdedb612785dafdf72f5f35824343ad39d8568d6cd25e44b585a915c8e9ea2b02e6fd38c105bb17ed27c8fa320f18c83e0ace78feb5"},{"other":"aa108a30f86b8296b416ea9fd6bc7a21c65c7cd3911ca3d4ee79325912d80db7150c02d304e49c5d0feafbd222edd6d522661a0983f1d427981760712f31e6f1","one":"df7decc6bb0d51afdc0c445a15be31b0e89c79a52b8a2cc789b585d94db63f064eccc1d8340d13d5e43ed7cbe95db8ad10ee7294dbd4c7629686564bb3a603b2","up":true},{"one":"e90ca22b959d482861c52e9e51fd2d63557453dce64dab9f66fcf323273c12e7189358f85d500f5200ff7c7b2d57afe72577ed9aa2adb36fc0c8e5504588fe94","up":true,"other":"604a11bd1d969886953398ecc1fdf5847a946a8118014d0cb8daff9943f4f78c4bdbad3ee4152959c8265d0588dea658c262fe2f99a55a0b32321b81c8eec473"},{"other":"0d85f39dca79f99b277ad5cedfcd3fb1eccc7862c95c215ba0d5a2ec1c4fa80244393d0934cf59fe988f7716bf15cb8e79f4ee03fbe4a48a10cac6e0610f9d55","one":"6070dc131e9721a4a496b3ed6ff5c9db1a5351e942ed424b86fe6be940d1012df766afb4b0112452dfd63e0fcfea13658324a9ef4a94b5754ec9f6219e4b0d67","up":true},{"up":true,"one":"84379884f012e2cfc1f9838312640576c9ded01ca53cf8451f94915e6949f0084047a2555a5fef4d1b0eef62ad5504a34ff631fbb658b011a07a82a53173f5c1","other":"b737c81fe6bc50d977231a5fc8856f064ba58190c5ab5615d3cf634aea8c15a308f3a667aad2e69d5c1438549cd41c863fd40f643b70caf3e0c934276ef2a84f"},{"other":"0c000879be78fc867857011e396e2dd77bc2a0c6c2c3624d98b102737aa8d998ca9081653c0c8285117a5288b1bfeed06c54b2f6e39225aca4a21ff2a72116e1","one":"e706876f36646bfb2dfbd11669a4907432660023a13be9de329a03f6c6e88e3788002b83d0cb4617e6c4096998783925be5b1de4f0edd8128e7d71312fb1091d","up":true},{"other":"f87c2dea026ba5e6cda9a446821bf057d3453fa8c9b38fd882a09979ff3cfe2b8adfcbd5cf28d268776414bd12a9aba385d5c97c76a29c1b0625b101faac761d","up":true,"one":"cc0d13dba120558dc8e2d0e5ac755a712e7e7e6dab6edcaf658faf02537b1efe3d6c54d6e67566eb4a3a8f8a019702aa7ee2b33ee3f0316a01e7b17845032e70"},{"other":"123633b35f455fc3240d99929dc3130bb018545672be151ba973915f2ab6e6c862748f60d917e48ccbf28620c4e58b888867cb51e12ec0d2e5c61cef82258719","up":true,"one":"7ca32d24c001557a81af351ac71322543154eeedbb6ccdd8b8b142f19215aa712218babe9701e73a6441784375a511c1f16a70569b73416f9708409564d18485"},{"other":"41ded7596eac3eddfd1f7656ef23adabe1d18027f6159e45867e935d1ab742ec298ba2b23df522f79f59c7805510d8c995837380432dee37912d6ede1196caa2","one":"0bf28b481d71062ee100d6cb04c8b4234a574f8657e2d3c49b60a9ecdbf486d0ec38b33bce745c8efe820145d5c53ea802aa64b4f9bce19b029ee5b2f9de43f1","up":true},{"up":true,"one":"6070dc131e9721a4a496b3ed6ff5c9db1a5351e942ed424b86fe6be940d1012df766afb4b0112452dfd63e0fcfea13658324a9ef4a94b5754ec9f6219e4b0d67","other":"a5990a680e1f01dcd71a178a239880c5ce24418748c368b8e3c8a1175cfd744d16973cba03e5e756820950920a6d9fa5d5dd53829a1d1d508371cb1042e9453e"},{"one":"e3779b202b9cfe7b2f2cc9e95974ac77bf51ba951f775acc10f07249ee6b3b260f2b012bb010a7f9794c5562e9b00f18b52c25c1e350ab70afc6bf9e210e4969","up":true,"other":"fd321c630fadcc8d6b00589323f7313ac1e94effbe8192955da5f88dcf419ef28820075e0e81c595561ff6ee58cfce23079407edf8b1611cb994946bcbd26364"},{"other":"ac6057677fdfc132ea2418ff877357962771db049d169ba2c1923b15820385c6bf2f5846943d44a73bfdeb44a1e0d68307003a06cb0f694705879f8a720c3296","one":"cc0d13dba120558dc8e2d0e5ac755a712e7e7e6dab6edcaf658faf02537b1efe3d6c54d6e67566eb4a3a8f8a019702aa7ee2b33ee3f0316a01e7b17845032e70","up":true},{"other":"ab3a3ad0481a80b91132cc6afeaab9c9f5e931885d979176e8e6c181d997c38b488e5eca475b0f8e949a8cf128695e18a5851091394d0a33cf834ce7e3537ac2","one":"d33f82b6a46535e798b78ebb28047ece1ef3b696ab29726d283161c377ed17a735a0948b99d83dee2af71704001e2e13813854a1b0ef4fcefd3c0e5c5f6e720d","up":true},{"one":"519ce8f43529d0c703ef4faf50450877dc2818fd6fd6b7faaa9bbbaeac373e499d1b4a17b387b1a8d35e8042e18a9d3d365c97254b4d24352b10e8de9219a5cd","up":true,"other":"5a59a44ba2bf5e77f921216ac467733c8529b06790efb05a63c410060edaf65547a2dbb37333073e3bcf68d422ba4b135432307f90394c6edd6dd33dd6ff2152"},{"one":"f394aaa6d14c6ed95e2ad4651b5103bb1ab9f3a61839936cc1f08d6a6e53504e5d15dfc5211539ffdbdc64912ded5c2272d4af52ed8d7fe5a3c228eb12f0c68b","up":true,"other":"604a11bd1d969886953398ecc1fdf5847a946a8118014d0cb8daff9943f4f78c4bdbad3ee4152959c8265d0588dea658c262fe2f99a55a0b32321b81c8eec473"},{"one":"0bf28b481d71062ee100d6cb04c8b4234a574f8657e2d3c49b60a9ecdbf486d0ec38b33bce745c8efe820145d5c53ea802aa64b4f9bce19b029ee5b2f9de43f1","up":true,"other":"ad177f2702ed11d531b11fd0250f2dab2364624680cfb6ff1fba5b27dcd8334269a5bc9093401389044c0b00ed0cbf6f166aba81a58cadd34b25355839fff6ac"},{"one":"38469be067f9bba869fdfcc950843e00b5ff950778c11445787501d47cbaf60e9940735a5b8b71d48a0aaee75c8263137169d51944638dc5d1cad398d22439ed","up":true,"other":"ef3016ea5a7b1b57388904d5c80fd05780d23acec8cf73e8add28ea99c6222fa84e89a1752186a2ef41dd0ec828405e61a1e8fd67d9496d75525ed860b12e2e8"},{"up":true,"one":"f4ae36400caeddcbcf0fb1abd5b9611c37bac683645d10c69a1ac54d366f730c59917c95e990a0fa6bb2679c98fb62bf0e29bd7812ab57375de35f469dab98a0","other":"57fb9e7f287fe67500b8b560475c0d0d6eae9d623d5a8c85eb5459f209904a839a0b24ff99a1643a4196a71d45f2ed1bd5e08f9a13cdd9749a907a024ff984dc"},{"other":"57533c56642895edba91473a966b6abf765725a721dec947e4bac4728dfbed265435aefca55fff69cae48c9d506064fbb890665a0acd87c466707d08d1e6e1f4","up":true,"one":"d33f82b6a46535e798b78ebb28047ece1ef3b696ab29726d283161c377ed17a735a0948b99d83dee2af71704001e2e13813854a1b0ef4fcefd3c0e5c5f6e720d"},{"other":"6ba8900830489793a22bf5023cde4ab849dee525d1ca5b95e21040a8e8be5b295317b1c76e09beb7d17a9512137c487b99f16933622b5f2b0e10da3233086bbf","one":"81df6add458aaaaf51a3ad8826250f3498f06586264f95cd7fce642ac08bd583f463a7531e292175f90887013ba39f8757c21eb5524ec62ec413b82badae935a","up":true},{"one":"519ce8f43529d0c703ef4faf50450877dc2818fd6fd6b7faaa9bbbaeac373e499d1b4a17b387b1a8d35e8042e18a9d3d365c97254b4d24352b10e8de9219a5cd","up":true,"other":"236266f9f5a28148d11bed1195a91cd1d30231b082697ee1940a85abca98d2ff0767be9128c23375caa0444bcf51d8501879200ea0f27f13d0ede37f97241325"},{"up":true,"one":"071c094246a0ca4b5d169e43a20ce5da508e579a6e2e822462bd8948ab357d46ab477bcff0c80eba2e01f0c100690b307af40d47c52ebad06783e9e77466cbd6","other":"ef3016ea5a7b1b57388904d5c80fd05780d23acec8cf73e8add28ea99c6222fa84e89a1752186a2ef41dd0ec828405e61a1e8fd67d9496d75525ed860b12e2e8"},{"one":"38469be067f9bba869fdfcc950843e00b5ff950778c11445787501d47cbaf60e9940735a5b8b71d48a0aaee75c8263137169d51944638dc5d1cad398d22439ed","up":true,"other":"7172a86afb608acd9a3e1e5c0472489ebecb516cad6796fa9a06ab47cc8e8cce12dddce72f0ac3b0927602bd22ed5872c3b5ce9b6af96f8e9d1d75078cc9bb55"},{"up":true,"one":"3db9984cb1e25bdc30c483f3d4c036fb1728bafffecd2b965af7e701569c28116dbed2e5892504ea9927c14570351b03cb99112a5924a27e6e03289422785c7b","other":"b737c81fe6bc50d977231a5fc8856f064ba58190c5ab5615d3cf634aea8c15a308f3a667aad2e69d5c1438549cd41c863fd40f643b70caf3e0c934276ef2a84f"},{"one":"57fb9e7f287fe67500b8b560475c0d0d6eae9d623d5a8c85eb5459f209904a839a0b24ff99a1643a4196a71d45f2ed1bd5e08f9a13cdd9749a907a024ff984dc","up":true,"other":"38469be067f9bba869fdfcc950843e00b5ff950778c11445787501d47cbaf60e9940735a5b8b71d48a0aaee75c8263137169d51944638dc5d1cad398d22439ed"},{"other":"c133cd3ee228f427410357f46752d33ecf302475314411772df3532669a8b220136c09f00717460c39bcea1058cb988dd223875ec991612876b400556f5937dd","up":true,"one":"af6cb988ddb16202459735b8489c02b3bf829ca301513a0d3e18bbb03d43c8de3cda767c7b5c984a6dce3f118c8089e06b08ed3bd0c922dde9cfe775609df3b2"},{"other":"4228ad29aa22f1fa078c7e09f44f85c05d5b797072c10ade24dcbff95c01e554511fe10273a5f25a25ca06ff97bca28c241610f7145983f72ed44969ead4596a","up":true,"one":"af0050715bfa25b4ce3a7593c61578898be22801a9118064250c330c6b2a1416b3bc6d90b074d7d700e07574a274d861f9c6d8e3e5924c281502f699ad62465b"},{"other":"6d3bd11f2f7fe855188423bc49be111cd13defeb78a76eb26d415bfc0c86b89e90724db54a12ae7e0c76b9eb12eb456fc50668697245fca00f9ec3c6fb9c8588","up":true,"one":"193ca2ef8a4ac98c0300d7e48421ba3fe5d4789a0c2b476499bd093808c3988b4a55742ff3f607429cafda08cbbb5fba68da8869747b1b5169f3e4545497de3a"},{"other":"236266f9f5a28148d11bed1195a91cd1d30231b082697ee1940a85abca98d2ff0767be9128c23375caa0444bcf51d8501879200ea0f27f13d0ede37f97241325","one":"81df6add458aaaaf51a3ad8826250f3498f06586264f95cd7fce642ac08bd583f463a7531e292175f90887013ba39f8757c21eb5524ec62ec413b82badae935a","up":true},{"other":"a16326a0c540731e0964c4bc10c1342346fcfee70c7d1d8d333cbb774cb9f49dbf92585595654c99253eac21373706247bf5ef1ba40ac03e62da00821991cf7d","one":"d6794744c5f941cb6dbac4adbbbf11ce83c9224c8a34b9c787ed5975bf0af13e095a7db1c86fcbb7b134ae6dc67467d3ffaf191f4a4d9218779c4d0cf86876ca","up":true},{"other":"38469be067f9bba869fdfcc950843e00b5ff950778c11445787501d47cbaf60e9940735a5b8b71d48a0aaee75c8263137169d51944638dc5d1cad398d22439ed","one":"bebbde654a4f3e3e65f63d10cbcc89dfd46ce75945c19be33bfe4d954c8ed375981e21a8376ad10e402dddbcf3b657e6786c0820e599a0d1fe03f8d35294d7c7","up":true},{"other":"3db9984cb1e25bdc30c483f3d4c036fb1728bafffecd2b965af7e701569c28116dbed2e5892504ea9927c14570351b03cb99112a5924a27e6e03289422785c7b","up":true,"one":"a5990a680e1f01dcd71a178a239880c5ce24418748c368b8e3c8a1175cfd744d16973cba03e5e756820950920a6d9fa5d5dd53829a1d1d508371cb1042e9453e"},{"other":"d6f274a2f20831a1b2281d889f46ad44f1bc5a07bb2152c89e129afb1c1e643b608621791a9d15a28da022d57b8bc3c05a7da0b5a93201dd714179e4a6a29a8b","one":"35ac328e13ea4fc6c333591633455cb6a2dff124528a17668770e231582ea31ab95e083cd191d8c45369d88366e9df0d2417cd26efbf2f616139c92fd497cd48","up":true},{"other":"3db9984cb1e25bdc30c483f3d4c036fb1728bafffecd2b965af7e701569c28116dbed2e5892504ea9927c14570351b03cb99112a5924a27e6e03289422785c7b","up":true,"one":"0d85f39dca79f99b277ad5cedfcd3fb1eccc7862c95c215ba0d5a2ec1c4fa80244393d0934cf59fe988f7716bf15cb8e79f4ee03fbe4a48a10cac6e0610f9d55"},{"one":"3db9984cb1e25bdc30c483f3d4c036fb1728bafffecd2b965af7e701569c28116dbed2e5892504ea9927c14570351b03cb99112a5924a27e6e03289422785c7b","up":true,"other":"af6cb988ddb16202459735b8489c02b3bf829ca301513a0d3e18bbb03d43c8de3cda767c7b5c984a6dce3f118c8089e06b08ed3bd0c922dde9cfe775609df3b2"},{"other":"a8b619f75e0e4cf7bc5e425ff9b03e55b7301fec4fb58f321bf89811678268d9f738bbf22ee36c2d14ff71a08d6f7dca28249ff6f943cc5a77653f482254d150","one":"64a39acfb1accea032dfc4d1530b5cdbdc8c1b609a442b68a9b534a539062d051b750a4512b0a9d504fdffa2a5bc8d4fcb6ca59f4ddb1c59ce62e8913644499b","up":true},{"up":true,"one":"9158b9eb87bf7d011f83febca8f9d6575dd05be1f7e7bc18336f802651a379dd181a0503b5a8e46a580c59889998b16275f1e0ce4dce965cdbe72265ad2be283","other":"c708e3584cd9450b30d8cdd960a676884f64364c2aec985eebb4a0d745f6c73b6b0cb16f330bf090320bc48a5a67e8519b3c2c4a64cf2eff9aa4f1fc0b274a00"},{"one":"ad177f2702ed11d531b11fd0250f2dab2364624680cfb6ff1fba5b27dcd8334269a5bc9093401389044c0b00ed0cbf6f166aba81a58cadd34b25355839fff6ac","up":true,"other":"c4dfcf348694971fb36ed91e9024302bec8df3891540cbe1f5df26eee9c1f81a95295f05b90ec30dd044a0355dcaa805b9f50e95f38e5588a929cfe10e8cd73d"},{"one":"cf03d32d3cca446e7016e7f41267a257bef7142c4f1e4ce2e17678856d75e9889e21972fd21583297a47a156543af15400444dcf37aca64543f97f73734f7f0f","up":true,"other":"82f0cbb87a76dea7947c2c1b6506d05390e5c5e969e5e91651ca10d36cd6aaea72967435ea7e5222d28f1d5e64cc526075d264712e55593bc3b609c93d4fe1eb"},{"one":"3e65bbf7103b3307bd9b8a65168c7c87c3f5283c7c52edefabf4193a1f04ac10216cc485a1dae17cff9ccea41bcf9a0b41de001c6142f30701443dc1735f25c0","up":true,"other":"071c094246a0ca4b5d169e43a20ce5da508e579a6e2e822462bd8948ab357d46ab477bcff0c80eba2e01f0c100690b307af40d47c52ebad06783e9e77466cbd6"},{"one":"aa108a30f86b8296b416ea9fd6bc7a21c65c7cd3911ca3d4ee79325912d80db7150c02d304e49c5d0feafbd222edd6d522661a0983f1d427981760712f31e6f1","up":true,"other":"38469be067f9bba869fdfcc950843e00b5ff950778c11445787501d47cbaf60e9940735a5b8b71d48a0aaee75c8263137169d51944638dc5d1cad398d22439ed"},{"one":"236266f9f5a28148d11bed1195a91cd1d30231b082697ee1940a85abca98d2ff0767be9128c23375caa0444bcf51d8501879200ea0f27f13d0ede37f97241325","up":true,"other":"a2719942ffb6e99bda131cdedb612785dafdf72f5f35824343ad39d8568d6cd25e44b585a915c8e9ea2b02e6fd38c105bb17ed27c8fa320f18c83e0ace78feb5"},{"one":"af0050715bfa25b4ce3a7593c61578898be22801a9118064250c330c6b2a1416b3bc6d90b074d7d700e07574a274d861f9c6d8e3e5924c281502f699ad62465b","up":true,"other":"236266f9f5a28148d11bed1195a91cd1d30231b082697ee1940a85abca98d2ff0767be9128c23375caa0444bcf51d8501879200ea0f27f13d0ede37f97241325"},{"one":"eeb9d718ef61c14e10ab2fb3a90b039368acd17a59f70628deb39515c227bd0916c796cd7767b1a9d4f38e04f1013173b21c1fa2e0206ecdc72df6c2621380a2","up":true,"other":"64a39acfb1accea032dfc4d1530b5cdbdc8c1b609a442b68a9b534a539062d051b750a4512b0a9d504fdffa2a5bc8d4fcb6ca59f4ddb1c59ce62e8913644499b"},{"other":"6d3bd11f2f7fe855188423bc49be111cd13defeb78a76eb26d415bfc0c86b89e90724db54a12ae7e0c76b9eb12eb456fc50668697245fca00f9ec3c6fb9c8588","one":"cc94ed069ddcc24dc2733eed5ba8367a2521a5955c7287c5280c71675b9965ee8499454b227a4ddc64a14d74b39916211763ddf0b7ad80a52381cc61dcb6c72c","up":true},{"one":"5c1e9692b731421d6eaca488e8ba4cfdda1933ac5f1504ece684fadbea07a7c8053feb73be7ce20aedeaecc84f14d836b5ed2a657df6ca04f4fc82c2da0c0d46","up":true,"other":"e706876f36646bfb2dfbd11669a4907432660023a13be9de329a03f6c6e88e3788002b83d0cb4617e6c4096998783925be5b1de4f0edd8128e7d71312fb1091d"},{"up":true,"one":"fa4174ca214905c4136e891e64349f664f166aeeacead6f6e84892ebcadd2c7fbff07052ea4913a9465999f5494962ec29f7f7a3e6cbb993e00d1b881fb31eb1","other":"7172a86afb608acd9a3e1e5c0472489ebecb516cad6796fa9a06ab47cc8e8cce12dddce72f0ac3b0927602bd22ed5872c3b5ce9b6af96f8e9d1d75078cc9bb55"},{"one":"464cf4c4203246240a63965062b9e5a7e5fa903f127b1f5ea5b37a27d33d8b12768fc2d8f257e67418f1e5765e627ca8f8cd5ba6b15b8a047490d26ce43e6291","up":true,"other":"c4dfcf348694971fb36ed91e9024302bec8df3891540cbe1f5df26eee9c1f81a95295f05b90ec30dd044a0355dcaa805b9f50e95f38e5588a929cfe10e8cd73d"},{"up":true,"one":"a1b07c24605e258db7b8fb15db227596b08dc69bb234c0a48c312eb6eb1fb08553f8c8a6da7175eea258e2d3f2625a540c1466e6c31315aa1484fa173b7a8cfc","other":"0d85f39dca79f99b277ad5cedfcd3fb1eccc7862c95c215ba0d5a2ec1c4fa80244393d0934cf59fe988f7716bf15cb8e79f4ee03fbe4a48a10cac6e0610f9d55"},{"other":"f8fd12d8b5872b74e2cfa60d6a3a25b568a1fb4be3a8d06faac02a38321f419c443e517c0e2989001635f827add1859a2dc9589a9c0f5bf3804d46f43f799116","up":true,"one":"af761f8d13059f1e49d2f5c0b7a76a5eb5bcaab1e7ff01673dff3967d81bd7aebf74afef3934328034c82f131fa066de71816cff8f720e0c56d5e85b233a8a44"},{"up":true,"one":"9ad5ec0e729f9db10b7028788b58ef13d54bd11529b494a549d0415b90777b63fe78a752356315f5abbd24d849edc0c8bfe9d82c05460c30f4dad860ff5fea48","other":"c708e3584cd9450b30d8cdd960a676884f64364c2aec985eebb4a0d745f6c73b6b0cb16f330bf090320bc48a5a67e8519b3c2c4a64cf2eff9aa4f1fc0b274a00"},{"other":"604a11bd1d969886953398ecc1fdf5847a946a8118014d0cb8daff9943f4f78c4bdbad3ee4152959c8265d0588dea658c262fe2f99a55a0b32321b81c8eec473","up":true,"one":"334b59c2767fc786551dfdc0a9fcd6f5b53cbe48ddc1ca61b84f8155a15de7e8cd44cbb3a537e1aa7f11416eb710c5de916a5e8ce24e83bfa570b7344c5873ea"},{"other":"49bd2289f479c9ad7e0d13319271b9be1e1dcbee28313513a124dec55f9842db639e62a74a83040930c537739ab7fa1e50bb05b9ab0f588d6da7b64a6451f466","up":true,"one":"66652e041752f4acb27bc45c9c8b58f4f4ea904345a887a49ae831bef3bb1ad26cff7fd0f66ef3c28d6c41e039e39ff983710fdd5384f849595a66e5509e0d10"},{"one":"826500ca53a2aed90da0cc3778cbc41af3de0139b246f30c3be65582b1f152928dfa3280760da4dcd8098f41f529a088dba24bc5d0c71322ef69f4b101f0224a","up":true,"other":"3dcf5ec3ebb3b7de61dfaef4ee397a4a13a96ee40673be2eaadfcadd11f139c594c74237b40dd9c10f059f40d325c014f5b02b3a8eb7f0dc7d66ced7fea9f17f"},{"one":"09fa1e69f37cb14db3dd721a9c4b9c884f6fe519d850f7af3643ecd536d4b3e995f99acf569e23b7864996c750115ff0ca0bd446ebfd76a026da71da0b95fd97","up":true,"other":"cc0d13dba120558dc8e2d0e5ac755a712e7e7e6dab6edcaf658faf02537b1efe3d6c54d6e67566eb4a3a8f8a019702aa7ee2b33ee3f0316a01e7b17845032e70"},{"other":"cc94ed069ddcc24dc2733eed5ba8367a2521a5955c7287c5280c71675b9965ee8499454b227a4ddc64a14d74b39916211763ddf0b7ad80a52381cc61dcb6c72c","one":"e20a90f36eca4329d3d2dbadf530949889dc20b0ae5d96b935af9b60d26ec507e9eb1b73fd2b4dc88057c20e4ef6e7039cc49652d35c563db64f06f979e28540","up":true},{"one":"df7decc6bb0d51afdc0c445a15be31b0e89c79a52b8a2cc789b585d94db63f064eccc1d8340d13d5e43ed7cbe95db8ad10ee7294dbd4c7629686564bb3a603b2","up":true,"other":"604a11bd1d969886953398ecc1fdf5847a946a8118014d0cb8daff9943f4f78c4bdbad3ee4152959c8265d0588dea658c262fe2f99a55a0b32321b81c8eec473"},{"other":"e706876f36646bfb2dfbd11669a4907432660023a13be9de329a03f6c6e88e3788002b83d0cb4617e6c4096998783925be5b1de4f0edd8128e7d71312fb1091d","up":true,"one":"69f3f9fafff951dca2fe98baa178e53f2779311a93fdc364cf4c2477700c8dbce7e4201c3aa6d840b5ae65e8fc9d6603cbc41dbdf601f1998caedee1b542d72b"},{"one":"467a76ed18ca4f195c6a5b0ac277dfd0916657e047fea073db8e28bb59098bd8960c90efe8f59d6c275ff72d18b217d225f6698e56c05e33734a0fd6ea570589","up":true,"other":"e0cacf6abdbfd9a25b9f974600662d4eae484efcdefd0a2a8fbc799127b6fabf2f471aff89c3a08e93ea20be1c304320598ba20a13697a356bf065292ba16bc1"},{"other":"aa108a30f86b8296b416ea9fd6bc7a21c65c7cd3911ca3d4ee79325912d80db7150c02d304e49c5d0feafbd222edd6d522661a0983f1d427981760712f31e6f1","one":"53031cddf4390ba176d638456016028bd4538879c7eaba672c3ef70208319a14e6a41dea8ff003b6f7e9b4a83ca12dab50d4f44f079153bec7c24221e311573e","up":true},{"up":true,"one":"35ac328e13ea4fc6c333591633455cb6a2dff124528a17668770e231582ea31ab95e083cd191d8c45369d88366e9df0d2417cd26efbf2f616139c92fd497cd48","other":"c4dfcf348694971fb36ed91e9024302bec8df3891540cbe1f5df26eee9c1f81a95295f05b90ec30dd044a0355dcaa805b9f50e95f38e5588a929cfe10e8cd73d"},{"other":"0e07d2eb15905a583532383cef08b0881878c5043c4d7bae2cf1cace9954bfbbfbe0c1e8322eabbc84bc94cda08ae9b70cbdc56a1b8a19f807bcd5ca7939669d","one":"540598224dccc717053f94e915652df499f513dc0c8874ce999040e1aa829c33ede284c72ddd0b24a319821102fa42aaaaa87380e777b5878455de61f5fc2ac9","up":true},{"other":"519ce8f43529d0c703ef4faf50450877dc2818fd6fd6b7faaa9bbbaeac373e499d1b4a17b387b1a8d35e8042e18a9d3d365c97254b4d24352b10e8de9219a5cd","up":true,"one":"dee5fb5ccdfe3803cab3e0041c5c4879001bf2c2233446f47245d8234642046269bfe50e414cd2d89341e338597f2ecbb7b2912c20558a85041b757a24490805"},{"other":"4f4201d959e4add3a4bcf3cbaab29d8abcc7530a9834e3cde45c4459ea92fba869e65156037a8fae02eac05f6174a7f2c1d825418f2207caa2284bcc9d9b84d1","one":"3dcf5ec3ebb3b7de61dfaef4ee397a4a13a96ee40673be2eaadfcadd11f139c594c74237b40dd9c10f059f40d325c014f5b02b3a8eb7f0dc7d66ced7fea9f17f","up":true},{"one":"a302bebe4590b3f6d2c511919ceef4a5a80d431f53f8f3483c4b833a6a3b5f79b4c66c0ce2c0e5bc696534067ea5cd07772a9844ee0ba9d37a2e6f5d4bfb05cd","up":true,"other":"7172a86afb608acd9a3e1e5c0472489ebecb516cad6796fa9a06ab47cc8e8cce12dddce72f0ac3b0927602bd22ed5872c3b5ce9b6af96f8e9d1d75078cc9bb55"},{"other":"aa108a30f86b8296b416ea9fd6bc7a21c65c7cd3911ca3d4ee79325912d80db7150c02d304e49c5d0feafbd222edd6d522661a0983f1d427981760712f31e6f1","up":true,"one":"c708e3584cd9450b30d8cdd960a676884f64364c2aec985eebb4a0d745f6c73b6b0cb16f330bf090320bc48a5a67e8519b3c2c4a64cf2eff9aa4f1fc0b274a00"},{"one":"a4dd67ab4fff1a50968c7ab59c304eb0083b072fc13dff599eeadac4e0e75099f7c825f91dd1bb770f3ae6f3d1d82ad574d6ecb117adf1ca9ccbccd01303ec7c","up":true,"other":"f78ecf420b73cd0245807157c0cbaaa568c60c80965413e187b084fb26041761d12790c0cb6a39bc8997fd2b3d3f52c831e601f1f1846945fba1808b0e1cdf25"},{"other":"7172a86afb608acd9a3e1e5c0472489ebecb516cad6796fa9a06ab47cc8e8cce12dddce72f0ac3b0927602bd22ed5872c3b5ce9b6af96f8e9d1d75078cc9bb55","up":true,"one":"946b3f821a4b61661e8ace52f4ade415042fddf058d97a16f08d9eff7a0be633de47c27fa9760ff38d583b2405163d4a27d3a7949d4015271396c014043a34e3"},{"one":"f3bf16c7156ce55af92b2fc21826bdfd3e1f245c6087e76f5eb23cc8bbd88b25515a32029d3e6e2b4a27354606e9e3bdfe78788e326c4349d63416894fcfbaf4","up":true,"other":"a4dd67ab4fff1a50968c7ab59c304eb0083b072fc13dff599eeadac4e0e75099f7c825f91dd1bb770f3ae6f3d1d82ad574d6ecb117adf1ca9ccbccd01303ec7c"},{"one":"5a27b90639d515cad7794dae78bf9a9866cca23c5e3e18870524d148797ba1bdfd631151f23062d4dcf0961a7dba709431a44e39da29ed5ea4b0b6987514e433","up":true,"other":"6ba8900830489793a22bf5023cde4ab849dee525d1ca5b95e21040a8e8be5b295317b1c76e09beb7d17a9512137c487b99f16933622b5f2b0e10da3233086bbf"},{"up":true,"one":"7e9a81d06e997a691cc7790d358868b8657db608795ef6b85bb194db7f56ab5c76cac3be0b40d847ce873aeef4bdad40b725d69f4c42755b9d5aab4fe7aecb34","other":"e2956a828cb1ff85ab55bdbe329f530662558cb8013ffddacac8ba36096abea07ecb15b54896dd9b4bb0b15155654dbda0c031f69290f2314ac0e376bebbd864"},{"other":"f4ae36400caeddcbcf0fb1abd5b9611c37bac683645d10c69a1ac54d366f730c59917c95e990a0fa6bb2679c98fb62bf0e29bd7812ab57375de35f469dab98a0","one":"35ac328e13ea4fc6c333591633455cb6a2dff124528a17668770e231582ea31ab95e083cd191d8c45369d88366e9df0d2417cd26efbf2f616139c92fd497cd48","up":true},{"other":"e90ca22b959d482861c52e9e51fd2d63557453dce64dab9f66fcf323273c12e7189358f85d500f5200ff7c7b2d57afe72577ed9aa2adb36fc0c8e5504588fe94","one":"c796d4917dd22d9836a9d7d24ba6f89e1a0e8a78a207bd930991e44e9c80ac1de8e4e1a023d550a6dfa60270fbb3935a7e03ef389c1ccda957a4a6a75ef6819b","up":true},{"other":"071c094246a0ca4b5d169e43a20ce5da508e579a6e2e822462bd8948ab357d46ab477bcff0c80eba2e01f0c100690b307af40d47c52ebad06783e9e77466cbd6","up":true,"one":"fb20c708420e60c48fa65980ae11adc8cdf9b56ab93044a9aee9b5196d52f29e6cb2c218f73fefbdaecf8177bae1d9d13dd64bbe06e631555715b93f58f47137"},{"one":"c796d4917dd22d9836a9d7d24ba6f89e1a0e8a78a207bd930991e44e9c80ac1de8e4e1a023d550a6dfa60270fbb3935a7e03ef389c1ccda957a4a6a75ef6819b","up":true,"other":"0bf28b481d71062ee100d6cb04c8b4234a574f8657e2d3c49b60a9ecdbf486d0ec38b33bce745c8efe820145d5c53ea802aa64b4f9bce19b029ee5b2f9de43f1"},{"other":"255939ef32bd3e5e76181763c11707b9ff4ab26d3ffb10f06fa7249b06721fa3decfa9eee3eeb8b12d6218af5f9ed8872d62c42a90cd46dcbef3d89a8163ae07","one":"af0050715bfa25b4ce3a7593c61578898be22801a9118064250c330c6b2a1416b3bc6d90b074d7d700e07574a274d861f9c6d8e3e5924c281502f699ad62465b","up":true},{"one":"fb20c708420e60c48fa65980ae11adc8cdf9b56ab93044a9aee9b5196d52f29e6cb2c218f73fefbdaecf8177bae1d9d13dd64bbe06e631555715b93f58f47137","up":true,"other":"123633b35f455fc3240d99929dc3130bb018545672be151ba973915f2ab6e6c862748f60d917e48ccbf28620c4e58b888867cb51e12ec0d2e5c61cef82258719"},{"one":"41ded7596eac3eddfd1f7656ef23adabe1d18027f6159e45867e935d1ab742ec298ba2b23df522f79f59c7805510d8c995837380432dee37912d6ede1196caa2","up":true,"other":"ac6057677fdfc132ea2418ff877357962771db049d169ba2c1923b15820385c6bf2f5846943d44a73bfdeb44a1e0d68307003a06cb0f694705879f8a720c3296"},{"other":"7ca32d24c001557a81af351ac71322543154eeedbb6ccdd8b8b142f19215aa712218babe9701e73a6441784375a511c1f16a70569b73416f9708409564d18485","up":true,"one":"0c000879be78fc867857011e396e2dd77bc2a0c6c2c3624d98b102737aa8d998ca9081653c0c8285117a5288b1bfeed06c54b2f6e39225aca4a21ff2a72116e1"},{"up":true,"one":"223d79f656e3f124ee1238ca46e42c2a0d8500ee58a37312c6b72657a11ad9ebce3be4c061611b913a22863f6e7936ff37602dedc7856baea27e8201db44bbf4","other":"f78ecf420b73cd0245807157c0cbaaa568c60c80965413e187b084fb26041761d12790c0cb6a39bc8997fd2b3d3f52c831e601f1f1846945fba1808b0e1cdf25"},{"other":"f8fd12d8b5872b74e2cfa60d6a3a25b568a1fb4be3a8d06faac02a38321f419c443e517c0e2989001635f827add1859a2dc9589a9c0f5bf3804d46f43f799116","up":true,"one":"c49e963a92b93a1c48fd3e38c127bfc88fbcb15b57bfdf8615c0e591b24276d4fe153a811932aefdcf3dee494d53ce354ba052c24313a725d562c6e807ab9133"},{"one":"ab3a3ad0481a80b91132cc6afeaab9c9f5e931885d979176e8e6c181d997c38b488e5eca475b0f8e949a8cf128695e18a5851091394d0a33cf834ce7e3537ac2","up":true,"other":"b1bef03357528618be6936a7edae5e3d4ecc942d43bd301642d321a73a07f3327d413f923c3fdd49d04f311e18709a4dde7519722d7a4912f181aa4df2e60173"},{"other":"ac6057677fdfc132ea2418ff877357962771db049d169ba2c1923b15820385c6bf2f5846943d44a73bfdeb44a1e0d68307003a06cb0f694705879f8a720c3296","up":true,"one":"7172a86afb608acd9a3e1e5c0472489ebecb516cad6796fa9a06ab47cc8e8cce12dddce72f0ac3b0927602bd22ed5872c3b5ce9b6af96f8e9d1d75078cc9bb55"},{"other":"3dcf5ec3ebb3b7de61dfaef4ee397a4a13a96ee40673be2eaadfcadd11f139c594c74237b40dd9c10f059f40d325c014f5b02b3a8eb7f0dc7d66ced7fea9f17f","one":"3bf838b4d29d9388a24d160eee6bf8ea017af6cd9e5f7d88b4cae71ebfbc304666d3d634a05e0a75570dafe8f41871090fcff8b651a9130d013786dfcca3da14","up":true},{"other":"c4dfcf348694971fb36ed91e9024302bec8df3891540cbe1f5df26eee9c1f81a95295f05b90ec30dd044a0355dcaa805b9f50e95f38e5588a929cfe10e8cd73d","up":true,"one":"41ded7596eac3eddfd1f7656ef23adabe1d18027f6159e45867e935d1ab742ec298ba2b23df522f79f59c7805510d8c995837380432dee37912d6ede1196caa2"},{"other":"3dcf5ec3ebb3b7de61dfaef4ee397a4a13a96ee40673be2eaadfcadd11f139c594c74237b40dd9c10f059f40d325c014f5b02b3a8eb7f0dc7d66ced7fea9f17f","up":true,"one":"6d3bd11f2f7fe855188423bc49be111cd13defeb78a76eb26d415bfc0c86b89e90724db54a12ae7e0c76b9eb12eb456fc50668697245fca00f9ec3c6fb9c8588"},{"one":"7172a86afb608acd9a3e1e5c0472489ebecb516cad6796fa9a06ab47cc8e8cce12dddce72f0ac3b0927602bd22ed5872c3b5ce9b6af96f8e9d1d75078cc9bb55","up":true,"other":"59fe05843cc637adac3728acb8ca9650f49050095cf5d32241366f54d4ac7179b16dcb009e2fb9fa9499cc6f8b865b6c4d6fe6e35500df10ba5daa719d57976e"},{"other":"c133cd3ee228f427410357f46752d33ecf302475314411772df3532669a8b220136c09f00717460c39bcea1058cb988dd223875ec991612876b400556f5937dd","up":true,"one":"ab3a3ad0481a80b91132cc6afeaab9c9f5e931885d979176e8e6c181d997c38b488e5eca475b0f8e949a8cf128695e18a5851091394d0a33cf834ce7e3537ac2"},{"other":"7ca32d24c001557a81af351ac71322543154eeedbb6ccdd8b8b142f19215aa712218babe9701e73a6441784375a511c1f16a70569b73416f9708409564d18485","up":true,"one":"4228ad29aa22f1fa078c7e09f44f85c05d5b797072c10ade24dcbff95c01e554511fe10273a5f25a25ca06ff97bca28c241610f7145983f72ed44969ead4596a"},{"other":"6ba8900830489793a22bf5023cde4ab849dee525d1ca5b95e21040a8e8be5b295317b1c76e09beb7d17a9512137c487b99f16933622b5f2b0e10da3233086bbf","up":true,"one":"3bf838b4d29d9388a24d160eee6bf8ea017af6cd9e5f7d88b4cae71ebfbc304666d3d634a05e0a75570dafe8f41871090fcff8b651a9130d013786dfcca3da14"},{"other":"7e9a81d06e997a691cc7790d358868b8657db608795ef6b85bb194db7f56ab5c76cac3be0b40d847ce873aeef4bdad40b725d69f4c42755b9d5aab4fe7aecb34","up":true,"one":"f2ac738fa932c90a45d1a64e4a52fd9c4037e2d89ceef1584efef04689bc7aff3a9635fb78dfdf3480d003daf14359190b1cfa8335db438a54107d4060ed58f9"},{"other":"6ba8900830489793a22bf5023cde4ab849dee525d1ca5b95e21040a8e8be5b295317b1c76e09beb7d17a9512137c487b99f16933622b5f2b0e10da3233086bbf","one":"6d3bd11f2f7fe855188423bc49be111cd13defeb78a76eb26d415bfc0c86b89e90724db54a12ae7e0c76b9eb12eb456fc50668697245fca00f9ec3c6fb9c8588","up":true},{"other":"464cf4c4203246240a63965062b9e5a7e5fa903f127b1f5ea5b37a27d33d8b12768fc2d8f257e67418f1e5765e627ca8f8cd5ba6b15b8a047490d26ce43e6291","up":true,"one":"ac6057677fdfc132ea2418ff877357962771db049d169ba2c1923b15820385c6bf2f5846943d44a73bfdeb44a1e0d68307003a06cb0f694705879f8a720c3296"},{"other":"b440e8bc7d39b8cf9cca03b343c83ba8dd673062cead7bbfce6ed77ea16fa61f0b81df31fc418f4c133d1bb104939ac1b6e5f5a76fbcf50141a1ea33dfeb86e5","one":"f2ac738fa932c90a45d1a64e4a52fd9c4037e2d89ceef1584efef04689bc7aff3a9635fb78dfdf3480d003daf14359190b1cfa8335db438a54107d4060ed58f9","up":true},{"other":"e706876f36646bfb2dfbd11669a4907432660023a13be9de329a03f6c6e88e3788002b83d0cb4617e6c4096998783925be5b1de4f0edd8128e7d71312fb1091d","up":true,"one":"e2956a828cb1ff85ab55bdbe329f530662558cb8013ffddacac8ba36096abea07ecb15b54896dd9b4bb0b15155654dbda0c031f69290f2314ac0e376bebbd864"},{"up":true,"one":"ed3a5d7602b59bd8709ef10cb84e4b5644a69490d1173a8b9135adba04b36c1fcd0f16543de39deff0e76d8314e6884ba939213f77abb8d50a68d030352cb495","other":"0c000879be78fc867857011e396e2dd77bc2a0c6c2c3624d98b102737aa8d998ca9081653c0c8285117a5288b1bfeed06c54b2f6e39225aca4a21ff2a72116e1"},{"up":true,"one":"b440e8bc7d39b8cf9cca03b343c83ba8dd673062cead7bbfce6ed77ea16fa61f0b81df31fc418f4c133d1bb104939ac1b6e5f5a76fbcf50141a1ea33dfeb86e5","other":"06a8a25c6dd90e230237b06c086f14e539b31b8e3705752d0ad8faf1bd7239547332604b79b6124cbd0cee495b99a80f147983142b7271841d8d9fa85d559301"},{"up":true,"one":"e0cacf6abdbfd9a25b9f974600662d4eae484efcdefd0a2a8fbc799127b6fabf2f471aff89c3a08e93ea20be1c304320598ba20a13697a356bf065292ba16bc1","other":"11170a0fb9f6b037f8ee4494e935a84b06816ff5c44ef9d613920f9c58f8b25611b2093da3fb51a59687db6a9b0a070386cac09757a27f75754cbdcb9afc2225"},{"up":true,"one":"ed3a5d7602b59bd8709ef10cb84e4b5644a69490d1173a8b9135adba04b36c1fcd0f16543de39deff0e76d8314e6884ba939213f77abb8d50a68d030352cb495","other":"9b3fecfc63256a9d69e75ccb5119b2866e30fa4516b3a3bf5b2f03f04f1d20de786ddb90fa2acadb2a0509503b21fc9d16238c57f9b102ceedb6b27ee1b2c4ea"},{"other":"06a8a25c6dd90e230237b06c086f14e539b31b8e3705752d0ad8faf1bd7239547332604b79b6124cbd0cee495b99a80f147983142b7271841d8d9fa85d559301","one":"255939ef32bd3e5e76181763c11707b9ff4ab26d3ffb10f06fa7249b06721fa3decfa9eee3eeb8b12d6218af5f9ed8872d62c42a90cd46dcbef3d89a8163ae07","up":true},{"one":"82f0cbb87a76dea7947c2c1b6506d05390e5c5e969e5e91651ca10d36cd6aaea72967435ea7e5222d28f1d5e64cc526075d264712e55593bc3b609c93d4fe1eb","up":true,"other":"3db9984cb1e25bdc30c483f3d4c036fb1728bafffecd2b965af7e701569c28116dbed2e5892504ea9927c14570351b03cb99112a5924a27e6e03289422785c7b"},{"up":true,"one":"a8b619f75e0e4cf7bc5e425ff9b03e55b7301fec4fb58f321bf89811678268d9f738bbf22ee36c2d14ff71a08d6f7dca28249ff6f943cc5a77653f482254d150","other":"59fe05843cc637adac3728acb8ca9650f49050095cf5d32241366f54d4ac7179b16dcb009e2fb9fa9499cc6f8b865b6c4d6fe6e35500df10ba5daa719d57976e"},{"up":true,"one":"255939ef32bd3e5e76181763c11707b9ff4ab26d3ffb10f06fa7249b06721fa3decfa9eee3eeb8b12d6218af5f9ed8872d62c42a90cd46dcbef3d89a8163ae07","other":"5a27b90639d515cad7794dae78bf9a9866cca23c5e3e18870524d148797ba1bdfd631151f23062d4dcf0961a7dba709431a44e39da29ed5ea4b0b6987514e433"},{"other":"fd321c630fadcc8d6b00589323f7313ac1e94effbe8192955da5f88dcf419ef28820075e0e81c595561ff6ee58cfce23079407edf8b1611cb994946bcbd26364","up":true,"one":"e2956a828cb1ff85ab55bdbe329f530662558cb8013ffddacac8ba36096abea07ecb15b54896dd9b4bb0b15155654dbda0c031f69290f2314ac0e376bebbd864"},{"other":"854ff45571c01cd49d0932bcb361eef13202ababf48f0b8e5d8143dc41e01609aa1539e926bad9b4ca8add023fd259eb70239103d75b0a404bb338f3e4bf9577","up":true,"one":"49bd2289f479c9ad7e0d13319271b9be1e1dcbee28313513a124dec55f9842db639e62a74a83040930c537739ab7fa1e50bb05b9ab0f588d6da7b64a6451f466"},{"other":"a089758c25ca0730f13cd18c10aeea62488c1c2651eef53a8ad11cfdfa61ce8f7354a53bd6902da26b79dfbedc78d315b1d4239eb62cbca59215727b2ac35213","one":"e0cacf6abdbfd9a25b9f974600662d4eae484efcdefd0a2a8fbc799127b6fabf2f471aff89c3a08e93ea20be1c304320598ba20a13697a356bf065292ba16bc1","up":true},{"one":"06a8a25c6dd90e230237b06c086f14e539b31b8e3705752d0ad8faf1bd7239547332604b79b6124cbd0cee495b99a80f147983142b7271841d8d9fa85d559301","up":true,"other":"c133cd3ee228f427410357f46752d33ecf302475314411772df3532669a8b220136c09f00717460c39bcea1058cb988dd223875ec991612876b400556f5937dd"},{"one":"a8b619f75e0e4cf7bc5e425ff9b03e55b7301fec4fb58f321bf89811678268d9f738bbf22ee36c2d14ff71a08d6f7dca28249ff6f943cc5a77653f482254d150","up":true,"other":"236266f9f5a28148d11bed1195a91cd1d30231b082697ee1940a85abca98d2ff0767be9128c23375caa0444bcf51d8501879200ea0f27f13d0ede37f97241325"},{"one":"57533c56642895edba91473a966b6abf765725a721dec947e4bac4728dfbed265435aefca55fff69cae48c9d506064fbb890665a0acd87c466707d08d1e6e1f4","up":true,"other":"5a59a44ba2bf5e77f921216ac467733c8529b06790efb05a63c410060edaf65547a2dbb37333073e3bcf68d422ba4b135432307f90394c6edd6dd33dd6ff2152"},{"one":"66652e041752f4acb27bc45c9c8b58f4f4ea904345a887a49ae831bef3bb1ad26cff7fd0f66ef3c28d6c41e039e39ff983710fdd5384f849595a66e5509e0d10","up":true,"other":"c133cd3ee228f427410357f46752d33ecf302475314411772df3532669a8b220136c09f00717460c39bcea1058cb988dd223875ec991612876b400556f5937dd"},{"up":true,"one":"49bd2289f479c9ad7e0d13319271b9be1e1dcbee28313513a124dec55f9842db639e62a74a83040930c537739ab7fa1e50bb05b9ab0f588d6da7b64a6451f466","other":"f8fd12d8b5872b74e2cfa60d6a3a25b568a1fb4be3a8d06faac02a38321f419c443e517c0e2989001635f827add1859a2dc9589a9c0f5bf3804d46f43f799116"},{"up":true,"one":"7625a1a0a0f5bf78e2b9fe43a1215ea882318458b886ec767ccbc35e76b543f96820b364342b28ff600302af7716280497141dc2fc84e83cb15f5eb3d268d73e","other":"193ca2ef8a4ac98c0300d7e48421ba3fe5d4789a0c2b476499bd093808c3988b4a55742ff3f607429cafda08cbbb5fba68da8869747b1b5169f3e4545497de3a"},{"one":"cf03d32d3cca446e7016e7f41267a257bef7142c4f1e4ce2e17678856d75e9889e21972fd21583297a47a156543af15400444dcf37aca64543f97f73734f7f0f","up":true,"other":"0d85f39dca79f99b277ad5cedfcd3fb1eccc7862c95c215ba0d5a2ec1c4fa80244393d0934cf59fe988f7716bf15cb8e79f4ee03fbe4a48a10cac6e0610f9d55"},{"other":"f4ae36400caeddcbcf0fb1abd5b9611c37bac683645d10c69a1ac54d366f730c59917c95e990a0fa6bb2679c98fb62bf0e29bd7812ab57375de35f469dab98a0","one":"5c1e9692b731421d6eaca488e8ba4cfdda1933ac5f1504ece684fadbea07a7c8053feb73be7ce20aedeaecc84f14d836b5ed2a657df6ca04f4fc82c2da0c0d46","up":true},{"up":true,"one":"4903cd53b3ffc4328547e03dec8f7992edbfb1e1697e53772ef79887984b11595167eb84015ff3dfb26ac0d7b2e98b7a0792bef843d2bdff3a76889fc4a6c60a","other":"9ad5ec0e729f9db10b7028788b58ef13d54bd11529b494a549d0415b90777b63fe78a752356315f5abbd24d849edc0c8bfe9d82c05460c30f4dad860ff5fea48"},{"up":true,"one":"fd321c630fadcc8d6b00589323f7313ac1e94effbe8192955da5f88dcf419ef28820075e0e81c595561ff6ee58cfce23079407edf8b1611cb994946bcbd26364","other":"9b3fecfc63256a9d69e75ccb5119b2866e30fa4516b3a3bf5b2f03f04f1d20de786ddb90fa2acadb2a0509503b21fc9d16238c57f9b102ceedb6b27ee1b2c4ea"},{"one":"cc94ed069ddcc24dc2733eed5ba8367a2521a5955c7287c5280c71675b9965ee8499454b227a4ddc64a14d74b39916211763ddf0b7ad80a52381cc61dcb6c72c","up":true,"other":"464cf4c4203246240a63965062b9e5a7e5fa903f127b1f5ea5b37a27d33d8b12768fc2d8f257e67418f1e5765e627ca8f8cd5ba6b15b8a047490d26ce43e6291"},{"one":"2a0fa7932768f0c316b478d15db556626def18462c3bee9446ff16c48fc43b6be1694a5783602b60250e33adc705b86fae7baa6b829146251995fd47980ce422","up":true,"other":"a16326a0c540731e0964c4bc10c1342346fcfee70c7d1d8d333cbb774cb9f49dbf92585595654c99253eac21373706247bf5ef1ba40ac03e62da00821991cf7d"},{"up":true,"one":"06a8a25c6dd90e230237b06c086f14e539b31b8e3705752d0ad8faf1bd7239547332604b79b6124cbd0cee495b99a80f147983142b7271841d8d9fa85d559301","other":"a8b619f75e0e4cf7bc5e425ff9b03e55b7301fec4fb58f321bf89811678268d9f738bbf22ee36c2d14ff71a08d6f7dca28249ff6f943cc5a77653f482254d150"},{"other":"519ce8f43529d0c703ef4faf50450877dc2818fd6fd6b7faaa9bbbaeac373e499d1b4a17b387b1a8d35e8042e18a9d3d365c97254b4d24352b10e8de9219a5cd","up":true,"one":"af761f8d13059f1e49d2f5c0b7a76a5eb5bcaab1e7ff01673dff3967d81bd7aebf74afef3934328034c82f131fa066de71816cff8f720e0c56d5e85b233a8a44"},{"up":true,"one":"df7decc6bb0d51afdc0c445a15be31b0e89c79a52b8a2cc789b585d94db63f064eccc1d8340d13d5e43ed7cbe95db8ad10ee7294dbd4c7629686564bb3a603b2","other":"cf03d32d3cca446e7016e7f41267a257bef7142c4f1e4ce2e17678856d75e9889e21972fd21583297a47a156543af15400444dcf37aca64543f97f73734f7f0f"},{"other":"eb6fa7d39fcee5a7081813169ae24ee6d355cfe717dcb2fa500a07c935ffbe1b12378ea13454742bf7c2df10ad2fd4e53476068eaef4669381c8cd060c199e11","up":true,"one":"a5990a680e1f01dcd71a178a239880c5ce24418748c368b8e3c8a1175cfd744d16973cba03e5e756820950920a6d9fa5d5dd53829a1d1d508371cb1042e9453e"},{"one":"ef3016ea5a7b1b57388904d5c80fd05780d23acec8cf73e8add28ea99c6222fa84e89a1752186a2ef41dd0ec828405e61a1e8fd67d9496d75525ed860b12e2e8","up":true,"other":"e3779b202b9cfe7b2f2cc9e95974ac77bf51ba951f775acc10f07249ee6b3b260f2b012bb010a7f9794c5562e9b00f18b52c25c1e350ab70afc6bf9e210e4969"},{"other":"c133cd3ee228f427410357f46752d33ecf302475314411772df3532669a8b220136c09f00717460c39bcea1058cb988dd223875ec991612876b400556f5937dd","one":"b1bef03357528618be6936a7edae5e3d4ecc942d43bd301642d321a73a07f3327d413f923c3fdd49d04f311e18709a4dde7519722d7a4912f181aa4df2e60173","up":true},{"other":"53031cddf4390ba176d638456016028bd4538879c7eaba672c3ef70208319a14e6a41dea8ff003b6f7e9b4a83ca12dab50d4f44f079153bec7c24221e311573e","up":false,"one":"e2956a828cb1ff85ab55bdbe329f530662558cb8013ffddacac8ba36096abea07ecb15b54896dd9b4bb0b15155654dbda0c031f69290f2314ac0e376bebbd864"},{"up":false,"one":"f78ecf420b73cd0245807157c0cbaaa568c60c80965413e187b084fb26041761d12790c0cb6a39bc8997fd2b3d3f52c831e601f1f1846945fba1808b0e1cdf25","other":"f87c2dea026ba5e6cda9a446821bf057d3453fa8c9b38fd882a09979ff3cfe2b8adfcbd5cf28d268776414bd12a9aba385d5c97c76a29c1b0625b101faac761d"},{"other":"854ff45571c01cd49d0932bcb361eef13202ababf48f0b8e5d8143dc41e01609aa1539e926bad9b4ca8add023fd259eb70239103d75b0a404bb338f3e4bf9577","one":"57533c56642895edba91473a966b6abf765725a721dec947e4bac4728dfbed265435aefca55fff69cae48c9d506064fbb890665a0acd87c466707d08d1e6e1f4","up":true},{"one":"3e65bbf7103b3307bd9b8a65168c7c87c3f5283c7c52edefabf4193a1f04ac10216cc485a1dae17cff9ccea41bcf9a0b41de001c6142f30701443dc1735f25c0","up":true,"other":"9b3fecfc63256a9d69e75ccb5119b2866e30fa4516b3a3bf5b2f03f04f1d20de786ddb90fa2acadb2a0509503b21fc9d16238c57f9b102ceedb6b27ee1b2c4ea"},{"up":true,"one":"57fb9e7f287fe67500b8b560475c0d0d6eae9d623d5a8c85eb5459f209904a839a0b24ff99a1643a4196a71d45f2ed1bd5e08f9a13cdd9749a907a024ff984dc","other":"334b59c2767fc786551dfdc0a9fcd6f5b53cbe48ddc1ca61b84f8155a15de7e8cd44cbb3a537e1aa7f11416eb710c5de916a5e8ce24e83bfa570b7344c5873ea"},{"other":"fb20c708420e60c48fa65980ae11adc8cdf9b56ab93044a9aee9b5196d52f29e6cb2c218f73fefbdaecf8177bae1d9d13dd64bbe06e631555715b93f58f47137","up":true,"one":"1545795dca07ecd09c5b16b3bbdddf3dba92e27b532c18a3bc63bc007761ac1b1ebc7ffb4f0a401d5376a4c67923c7949edaebd8f65fff52d6677bb1d6a72f43"},{"up":true,"one":"8b8c15c6329096267a25d4060ee19963afb6e776fea60d9d566d4e1f9b087581b36e33fc533d7f133668a7a6a22f81a1234ed9fbce26eff1d5e5691a6148d540","other":"e0cacf6abdbfd9a25b9f974600662d4eae484efcdefd0a2a8fbc799127b6fabf2f471aff89c3a08e93ea20be1c304320598ba20a13697a356bf065292ba16bc1"},{"up":true,"one":"59fe05843cc637adac3728acb8ca9650f49050095cf5d32241366f54d4ac7179b16dcb009e2fb9fa9499cc6f8b865b6c4d6fe6e35500df10ba5daa719d57976e","other":"854ff45571c01cd49d0932bcb361eef13202ababf48f0b8e5d8143dc41e01609aa1539e926bad9b4ca8add023fd259eb70239103d75b0a404bb338f3e4bf9577"},{"up":true,"one":"1545795dca07ecd09c5b16b3bbdddf3dba92e27b532c18a3bc63bc007761ac1b1ebc7ffb4f0a401d5376a4c67923c7949edaebd8f65fff52d6677bb1d6a72f43","other":"6ba8900830489793a22bf5023cde4ab849dee525d1ca5b95e21040a8e8be5b295317b1c76e09beb7d17a9512137c487b99f16933622b5f2b0e10da3233086bbf"},{"one":"e3779b202b9cfe7b2f2cc9e95974ac77bf51ba951f775acc10f07249ee6b3b260f2b012bb010a7f9794c5562e9b00f18b52c25c1e350ab70afc6bf9e210e4969","up":true,"other":"e706876f36646bfb2dfbd11669a4907432660023a13be9de329a03f6c6e88e3788002b83d0cb4617e6c4096998783925be5b1de4f0edd8128e7d71312fb1091d"},{"other":"57533c56642895edba91473a966b6abf765725a721dec947e4bac4728dfbed265435aefca55fff69cae48c9d506064fbb890665a0acd87c466707d08d1e6e1f4","one":"8b8c15c6329096267a25d4060ee19963afb6e776fea60d9d566d4e1f9b087581b36e33fc533d7f133668a7a6a22f81a1234ed9fbce26eff1d5e5691a6148d540","up":true},{"other":"f78ecf420b73cd0245807157c0cbaaa568c60c80965413e187b084fb26041761d12790c0cb6a39bc8997fd2b3d3f52c831e601f1f1846945fba1808b0e1cdf25","up":true,"one":"59fe05843cc637adac3728acb8ca9650f49050095cf5d32241366f54d4ac7179b16dcb009e2fb9fa9499cc6f8b865b6c4d6fe6e35500df10ba5daa719d57976e"},{"one":"4f4201d959e4add3a4bcf3cbaab29d8abcc7530a9834e3cde45c4459ea92fba869e65156037a8fae02eac05f6174a7f2c1d825418f2207caa2284bcc9d9b84d1","up":true,"other":"a4dd67ab4fff1a50968c7ab59c304eb0083b072fc13dff599eeadac4e0e75099f7c825f91dd1bb770f3ae6f3d1d82ad574d6ecb117adf1ca9ccbccd01303ec7c"},{"up":true,"one":"a16326a0c540731e0964c4bc10c1342346fcfee70c7d1d8d333cbb774cb9f49dbf92585595654c99253eac21373706247bf5ef1ba40ac03e62da00821991cf7d","other":"123633b35f455fc3240d99929dc3130bb018545672be151ba973915f2ab6e6c862748f60d917e48ccbf28620c4e58b888867cb51e12ec0d2e5c61cef82258719"},{"other":"604a11bd1d969886953398ecc1fdf5847a946a8118014d0cb8daff9943f4f78c4bdbad3ee4152959c8265d0588dea658c262fe2f99a55a0b32321b81c8eec473","one":"a16326a0c540731e0964c4bc10c1342346fcfee70c7d1d8d333cbb774cb9f49dbf92585595654c99253eac21373706247bf5ef1ba40ac03e62da00821991cf7d","up":true},{"other":"af0050715bfa25b4ce3a7593c61578898be22801a9118064250c330c6b2a1416b3bc6d90b074d7d700e07574a274d861f9c6d8e3e5924c281502f699ad62465b","up":true,"one":"4f4201d959e4add3a4bcf3cbaab29d8abcc7530a9834e3cde45c4459ea92fba869e65156037a8fae02eac05f6174a7f2c1d825418f2207caa2284bcc9d9b84d1"},{"other":"0d85f39dca79f99b277ad5cedfcd3fb1eccc7862c95c215ba0d5a2ec1c4fa80244393d0934cf59fe988f7716bf15cb8e79f4ee03fbe4a48a10cac6e0610f9d55","one":"96f3194c9ef17f60c318be14dd72c51af0aebc19f7a574b769d18b1fda6791409c827892bae3a061800e3d78af88a97635a0a892c54d7ebb38342ab1ba99c3ad","up":true},{"up":true,"one":"b949f482891fff7d7d1f0d84112db7080fa1df07cd4e52ee0fadb707a4b7903fc0da9fe45b7ceee37948856687f8e7768945295de15691a99c879f1816899d98","other":"c49e963a92b93a1c48fd3e38c127bfc88fbcb15b57bfdf8615c0e591b24276d4fe153a811932aefdcf3dee494d53ce354ba052c24313a725d562c6e807ab9133"},{"other":"850e729f9bbb5ef6e12baf7d3dced180839e88e0845baa7aa8fb87dcb417aa74af5999bda81723aabbef5eda842fa4b5fae107fcff9f6bd50597e8ba6a849dff","up":true,"one":"b949f482891fff7d7d1f0d84112db7080fa1df07cd4e52ee0fadb707a4b7903fc0da9fe45b7ceee37948856687f8e7768945295de15691a99c879f1816899d98"},{"other":"af0050715bfa25b4ce3a7593c61578898be22801a9118064250c330c6b2a1416b3bc6d90b074d7d700e07574a274d861f9c6d8e3e5924c281502f699ad62465b","up":true,"one":"f3bf16c7156ce55af92b2fc21826bdfd3e1f245c6087e76f5eb23cc8bbd88b25515a32029d3e6e2b4a27354606e9e3bdfe78788e326c4349d63416894fcfbaf4"},{"other":"54b79d3662ba486bbd120313d59ef101acf963eb3d6112a9dda121bc0b52f4b1fbcb13406705cdd8c2d3990ad296171c7972211467cc0d44cbe9ca16fbc82e3e","one":"8b8c15c6329096267a25d4060ee19963afb6e776fea60d9d566d4e1f9b087581b36e33fc533d7f133668a7a6a22f81a1234ed9fbce26eff1d5e5691a6148d540","up":true},{"up":false,"one":"1545795dca07ecd09c5b16b3bbdddf3dba92e27b532c18a3bc63bc007761ac1b1ebc7ffb4f0a401d5376a4c67923c7949edaebd8f65fff52d6677bb1d6a72f43","other":"e2956a828cb1ff85ab55bdbe329f530662558cb8013ffddacac8ba36096abea07ecb15b54896dd9b4bb0b15155654dbda0c031f69290f2314ac0e376bebbd864"},{"other":"946b3f821a4b61661e8ace52f4ade415042fddf058d97a16f08d9eff7a0be633de47c27fa9760ff38d583b2405163d4a27d3a7949d4015271396c014043a34e3","one":"f4ae36400caeddcbcf0fb1abd5b9611c37bac683645d10c69a1ac54d366f730c59917c95e990a0fa6bb2679c98fb62bf0e29bd7812ab57375de35f469dab98a0","up":true},{"other":"38469be067f9bba869fdfcc950843e00b5ff950778c11445787501d47cbaf60e9940735a5b8b71d48a0aaee75c8263137169d51944638dc5d1cad398d22439ed","up":true,"one":"7ca32d24c001557a81af351ac71322543154eeedbb6ccdd8b8b142f19215aa712218babe9701e73a6441784375a511c1f16a70569b73416f9708409564d18485"},{"one":"c7566a0efd78ba35ad27a51a7ec8fcd55944ae12f9933573e71e2ad7404d48037dad9063c10ce5af636d7641a03899333d01aa9be94716d2179fdb2af33f36c4","up":true,"other":"dee5fb5ccdfe3803cab3e0041c5c4879001bf2c2233446f47245d8234642046269bfe50e414cd2d89341e338597f2ecbb7b2912c20558a85041b757a24490805"},{"up":false,"one":"eb6fa7d39fcee5a7081813169ae24ee6d355cfe717dcb2fa500a07c935ffbe1b12378ea13454742bf7c2df10ad2fd4e53476068eaef4669381c8cd060c199e11","other":"cf03d32d3cca446e7016e7f41267a257bef7142c4f1e4ce2e17678856d75e9889e21972fd21583297a47a156543af15400444dcf37aca64543f97f73734f7f0f"},{"other":"b737c81fe6bc50d977231a5fc8856f064ba58190c5ab5615d3cf634aea8c15a308f3a667aad2e69d5c1438549cd41c863fd40f643b70caf3e0c934276ef2a84f","one":"f3bf16c7156ce55af92b2fc21826bdfd3e1f245c6087e76f5eb23cc8bbd88b25515a32029d3e6e2b4a27354606e9e3bdfe78788e326c4349d63416894fcfbaf4","up":true},{"up":true,"one":"a2719942ffb6e99bda131cdedb612785dafdf72f5f35824343ad39d8568d6cd25e44b585a915c8e9ea2b02e6fd38c105bb17ed27c8fa320f18c83e0ace78feb5","other":"59fe05843cc637adac3728acb8ca9650f49050095cf5d32241366f54d4ac7179b16dcb009e2fb9fa9499cc6f8b865b6c4d6fe6e35500df10ba5daa719d57976e"},{"up":true,"one":"af761f8d13059f1e49d2f5c0b7a76a5eb5bcaab1e7ff01673dff3967d81bd7aebf74afef3934328034c82f131fa066de71816cff8f720e0c56d5e85b233a8a44","other":"a13086041114db2be31038987ac3fdcaeb99489f1b6ee9b22998b9e66dc2f2f024307d9474811e7e8be1b1acf5a55305d5cce27d87fb834ed1e1d2e17319bb85"},{"other":"c49e963a92b93a1c48fd3e38c127bfc88fbcb15b57bfdf8615c0e591b24276d4fe153a811932aefdcf3dee494d53ce354ba052c24313a725d562c6e807ab9133","one":"7ca32d24c001557a81af351ac71322543154eeedbb6ccdd8b8b142f19215aa712218babe9701e73a6441784375a511c1f16a70569b73416f9708409564d18485","up":true},{"other":"9158b9eb87bf7d011f83febca8f9d6575dd05be1f7e7bc18336f802651a379dd181a0503b5a8e46a580c59889998b16275f1e0ce4dce965cdbe72265ad2be283","one":"a16326a0c540731e0964c4bc10c1342346fcfee70c7d1d8d333cbb774cb9f49dbf92585595654c99253eac21373706247bf5ef1ba40ac03e62da00821991cf7d","up":true},{"other":"9b3fecfc63256a9d69e75ccb5119b2866e30fa4516b3a3bf5b2f03f04f1d20de786ddb90fa2acadb2a0509503b21fc9d16238c57f9b102ceedb6b27ee1b2c4ea","up":false,"one":"e706876f36646bfb2dfbd11669a4907432660023a13be9de329a03f6c6e88e3788002b83d0cb4617e6c4096998783925be5b1de4f0edd8128e7d71312fb1091d"},{"one":"c7566a0efd78ba35ad27a51a7ec8fcd55944ae12f9933573e71e2ad7404d48037dad9063c10ce5af636d7641a03899333d01aa9be94716d2179fdb2af33f36c4","up":true,"other":"7e9a81d06e997a691cc7790d358868b8657db608795ef6b85bb194db7f56ab5c76cac3be0b40d847ce873aeef4bdad40b725d69f4c42755b9d5aab4fe7aecb34"},{"other":"540598224dccc717053f94e915652df499f513dc0c8874ce999040e1aa829c33ede284c72ddd0b24a319821102fa42aaaaa87380e777b5878455de61f5fc2ac9","up":true,"one":"eb6fa7d39fcee5a7081813169ae24ee6d355cfe717dcb2fa500a07c935ffbe1b12378ea13454742bf7c2df10ad2fd4e53476068eaef4669381c8cd060c199e11"},{"other":"123633b35f455fc3240d99929dc3130bb018545672be151ba973915f2ab6e6c862748f60d917e48ccbf28620c4e58b888867cb51e12ec0d2e5c61cef82258719","up":false,"one":"9158b9eb87bf7d011f83febca8f9d6575dd05be1f7e7bc18336f802651a379dd181a0503b5a8e46a580c59889998b16275f1e0ce4dce965cdbe72265ad2be283"},{"other":"3e65bbf7103b3307bd9b8a65168c7c87c3f5283c7c52edefabf4193a1f04ac10216cc485a1dae17cff9ccea41bcf9a0b41de001c6142f30701443dc1735f25c0","one":"2a0fa7932768f0c316b478d15db556626def18462c3bee9446ff16c48fc43b6be1694a5783602b60250e33adc705b86fae7baa6b829146251995fd47980ce422","up":true},{"other":"854ff45571c01cd49d0932bcb361eef13202ababf48f0b8e5d8143dc41e01609aa1539e926bad9b4ca8add023fd259eb70239103d75b0a404bb338f3e4bf9577","one":"cc0d13dba120558dc8e2d0e5ac755a712e7e7e6dab6edcaf658faf02537b1efe3d6c54d6e67566eb4a3a8f8a019702aa7ee2b33ee3f0316a01e7b17845032e70","up":true},{"one":"e20a90f36eca4329d3d2dbadf530949889dc20b0ae5d96b935af9b60d26ec507e9eb1b73fd2b4dc88057c20e4ef6e7039cc49652d35c563db64f06f979e28540","up":true,"other":"54b79d3662ba486bbd120313d59ef101acf963eb3d6112a9dda121bc0b52f4b1fbcb13406705cdd8c2d3990ad296171c7972211467cc0d44cbe9ca16fbc82e3e"},{"other":"0bf28b481d71062ee100d6cb04c8b4234a574f8657e2d3c49b60a9ecdbf486d0ec38b33bce745c8efe820145d5c53ea802aa64b4f9bce19b029ee5b2f9de43f1","one":"e90ca22b959d482861c52e9e51fd2d63557453dce64dab9f66fcf323273c12e7189358f85d500f5200ff7c7b2d57afe72577ed9aa2adb36fc0c8e5504588fe94","up":true},{"up":true,"one":"aa108a30f86b8296b416ea9fd6bc7a21c65c7cd3911ca3d4ee79325912d80db7150c02d304e49c5d0feafbd222edd6d522661a0983f1d427981760712f31e6f1","other":"123633b35f455fc3240d99929dc3130bb018545672be151ba973915f2ab6e6c862748f60d917e48ccbf28620c4e58b888867cb51e12ec0d2e5c61cef82258719"},{"other":"a089758c25ca0730f13cd18c10aeea62488c1c2651eef53a8ad11cfdfa61ce8f7354a53bd6902da26b79dfbedc78d315b1d4239eb62cbca59215727b2ac35213","up":true,"one":"a2719942ffb6e99bda131cdedb612785dafdf72f5f35824343ad39d8568d6cd25e44b585a915c8e9ea2b02e6fd38c105bb17ed27c8fa320f18c83e0ace78feb5"},{"other":"c796d4917dd22d9836a9d7d24ba6f89e1a0e8a78a207bd930991e44e9c80ac1de8e4e1a023d550a6dfa60270fbb3935a7e03ef389c1ccda957a4a6a75ef6819b","one":"467a76ed18ca4f195c6a5b0ac277dfd0916657e047fea073db8e28bb59098bd8960c90efe8f59d6c275ff72d18b217d225f6698e56c05e33734a0fd6ea570589","up":true},{"up":true,"one":"cc94ed069ddcc24dc2733eed5ba8367a2521a5955c7287c5280c71675b9965ee8499454b227a4ddc64a14d74b39916211763ddf0b7ad80a52381cc61dcb6c72c","other":"59fe05843cc637adac3728acb8ca9650f49050095cf5d32241366f54d4ac7179b16dcb009e2fb9fa9499cc6f8b865b6c4d6fe6e35500df10ba5daa719d57976e"},{"up":true,"one":"932e926c54a4127210a15731fa4ad6bbfd0d69183b894b676920843f154ad1e4148b674d234f070e9dc07547394a5af973befe0fc170bbe44346d69e135e0157","other":"a16326a0c540731e0964c4bc10c1342346fcfee70c7d1d8d333cbb774cb9f49dbf92585595654c99253eac21373706247bf5ef1ba40ac03e62da00821991cf7d"},{"one":"38469be067f9bba869fdfcc950843e00b5ff950778c11445787501d47cbaf60e9940735a5b8b71d48a0aaee75c8263137169d51944638dc5d1cad398d22439ed","up":true,"other":"e706876f36646bfb2dfbd11669a4907432660023a13be9de329a03f6c6e88e3788002b83d0cb4617e6c4096998783925be5b1de4f0edd8128e7d71312fb1091d"},{"up":true,"one":"84379884f012e2cfc1f9838312640576c9ded01ca53cf8451f94915e6949f0084047a2555a5fef4d1b0eef62ad5504a34ff631fbb658b011a07a82a53173f5c1","other":"c133cd3ee228f427410357f46752d33ecf302475314411772df3532669a8b220136c09f00717460c39bcea1058cb988dd223875ec991612876b400556f5937dd"},{"other":"7172a86afb608acd9a3e1e5c0472489ebecb516cad6796fa9a06ab47cc8e8cce12dddce72f0ac3b0927602bd22ed5872c3b5ce9b6af96f8e9d1d75078cc9bb55","up":false,"one":"5c1e9692b731421d6eaca488e8ba4cfdda1933ac5f1504ece684fadbea07a7c8053feb73be7ce20aedeaecc84f14d836b5ed2a657df6ca04f4fc82c2da0c0d46"},{"other":"49bd2289f479c9ad7e0d13319271b9be1e1dcbee28313513a124dec55f9842db639e62a74a83040930c537739ab7fa1e50bb05b9ab0f588d6da7b64a6451f466","one":"e90ca22b959d482861c52e9e51fd2d63557453dce64dab9f66fcf323273c12e7189358f85d500f5200ff7c7b2d57afe72577ed9aa2adb36fc0c8e5504588fe94","up":true},{"other":"c49e963a92b93a1c48fd3e38c127bfc88fbcb15b57bfdf8615c0e591b24276d4fe153a811932aefdcf3dee494d53ce354ba052c24313a725d562c6e807ab9133","up":true,"one":"6070dc131e9721a4a496b3ed6ff5c9db1a5351e942ed424b86fe6be940d1012df766afb4b0112452dfd63e0fcfea13658324a9ef4a94b5754ec9f6219e4b0d67"},{"other":"540598224dccc717053f94e915652df499f513dc0c8874ce999040e1aa829c33ede284c72ddd0b24a319821102fa42aaaaa87380e777b5878455de61f5fc2ac9","up":true,"one":"e706876f36646bfb2dfbd11669a4907432660023a13be9de329a03f6c6e88e3788002b83d0cb4617e6c4096998783925be5b1de4f0edd8128e7d71312fb1091d"},{"other":"ab3a3ad0481a80b91132cc6afeaab9c9f5e931885d979176e8e6c181d997c38b488e5eca475b0f8e949a8cf128695e18a5851091394d0a33cf834ce7e3537ac2","one":"467a76ed18ca4f195c6a5b0ac277dfd0916657e047fea073db8e28bb59098bd8960c90efe8f59d6c275ff72d18b217d225f6698e56c05e33734a0fd6ea570589","up":true},{"up":false,"one":"eb6fa7d39fcee5a7081813169ae24ee6d355cfe717dcb2fa500a07c935ffbe1b12378ea13454742bf7c2df10ad2fd4e53476068eaef4669381c8cd060c199e11","other":"9b3fecfc63256a9d69e75ccb5119b2866e30fa4516b3a3bf5b2f03f04f1d20de786ddb90fa2acadb2a0509503b21fc9d16238c57f9b102ceedb6b27ee1b2c4ea"},{"other":"3db9984cb1e25bdc30c483f3d4c036fb1728bafffecd2b965af7e701569c28116dbed2e5892504ea9927c14570351b03cb99112a5924a27e6e03289422785c7b","one":"f394aaa6d14c6ed95e2ad4651b5103bb1ab9f3a61839936cc1f08d6a6e53504e5d15dfc5211539ffdbdc64912ded5c2272d4af52ed8d7fe5a3c228eb12f0c68b","up":true},{"other":"255939ef32bd3e5e76181763c11707b9ff4ab26d3ffb10f06fa7249b06721fa3decfa9eee3eeb8b12d6218af5f9ed8872d62c42a90cd46dcbef3d89a8163ae07","one":"84379884f012e2cfc1f9838312640576c9ded01ca53cf8451f94915e6949f0084047a2555a5fef4d1b0eef62ad5504a34ff631fbb658b011a07a82a53173f5c1","up":true},{"other":"236266f9f5a28148d11bed1195a91cd1d30231b082697ee1940a85abca98d2ff0767be9128c23375caa0444bcf51d8501879200ea0f27f13d0ede37f97241325","one":"0bf28b481d71062ee100d6cb04c8b4234a574f8657e2d3c49b60a9ecdbf486d0ec38b33bce745c8efe820145d5c53ea802aa64b4f9bce19b029ee5b2f9de43f1","up":true},{"up":true,"one":"e90ca22b959d482861c52e9e51fd2d63557453dce64dab9f66fcf323273c12e7189358f85d500f5200ff7c7b2d57afe72577ed9aa2adb36fc0c8e5504588fe94","other":"c4dfcf348694971fb36ed91e9024302bec8df3891540cbe1f5df26eee9c1f81a95295f05b90ec30dd044a0355dcaa805b9f50e95f38e5588a929cfe10e8cd73d"},{"up":true,"one":"11170a0fb9f6b037f8ee4494e935a84b06816ff5c44ef9d613920f9c58f8b25611b2093da3fb51a59687db6a9b0a070386cac09757a27f75754cbdcb9afc2225","other":"f394aaa6d14c6ed95e2ad4651b5103bb1ab9f3a61839936cc1f08d6a6e53504e5d15dfc5211539ffdbdc64912ded5c2272d4af52ed8d7fe5a3c228eb12f0c68b"},{"other":"49bd2289f479c9ad7e0d13319271b9be1e1dcbee28313513a124dec55f9842db639e62a74a83040930c537739ab7fa1e50bb05b9ab0f588d6da7b64a6451f466","one":"59fe05843cc637adac3728acb8ca9650f49050095cf5d32241366f54d4ac7179b16dcb009e2fb9fa9499cc6f8b865b6c4d6fe6e35500df10ba5daa719d57976e","up":true},{"other":"d6f274a2f20831a1b2281d889f46ad44f1bc5a07bb2152c89e129afb1c1e643b608621791a9d15a28da022d57b8bc3c05a7da0b5a93201dd714179e4a6a29a8b","one":"d33f82b6a46535e798b78ebb28047ece1ef3b696ab29726d283161c377ed17a735a0948b99d83dee2af71704001e2e13813854a1b0ef4fcefd3c0e5c5f6e720d","up":true},{"other":"a1b07c24605e258db7b8fb15db227596b08dc69bb234c0a48c312eb6eb1fb08553f8c8a6da7175eea258e2d3f2625a540c1466e6c31315aa1484fa173b7a8cfc","up":true,"one":"d6f274a2f20831a1b2281d889f46ad44f1bc5a07bb2152c89e129afb1c1e643b608621791a9d15a28da022d57b8bc3c05a7da0b5a93201dd714179e4a6a29a8b"},{"other":"6ba8900830489793a22bf5023cde4ab849dee525d1ca5b95e21040a8e8be5b295317b1c76e09beb7d17a9512137c487b99f16933622b5f2b0e10da3233086bbf","up":true,"one":"519ce8f43529d0c703ef4faf50450877dc2818fd6fd6b7faaa9bbbaeac373e499d1b4a17b387b1a8d35e8042e18a9d3d365c97254b4d24352b10e8de9219a5cd"},{"up":true,"one":"d33f82b6a46535e798b78ebb28047ece1ef3b696ab29726d283161c377ed17a735a0948b99d83dee2af71704001e2e13813854a1b0ef4fcefd3c0e5c5f6e720d","other":"3db9984cb1e25bdc30c483f3d4c036fb1728bafffecd2b965af7e701569c28116dbed2e5892504ea9927c14570351b03cb99112a5924a27e6e03289422785c7b"},{"other":"53031cddf4390ba176d638456016028bd4538879c7eaba672c3ef70208319a14e6a41dea8ff003b6f7e9b4a83ca12dab50d4f44f079153bec7c24221e311573e","one":"38469be067f9bba869fdfcc950843e00b5ff950778c11445787501d47cbaf60e9940735a5b8b71d48a0aaee75c8263137169d51944638dc5d1cad398d22439ed","up":true},{"up":true,"one":"ad177f2702ed11d531b11fd0250f2dab2364624680cfb6ff1fba5b27dcd8334269a5bc9093401389044c0b00ed0cbf6f166aba81a58cadd34b25355839fff6ac","other":"41ded7596eac3eddfd1f7656ef23adabe1d18027f6159e45867e935d1ab742ec298ba2b23df522f79f59c7805510d8c995837380432dee37912d6ede1196caa2"},{"other":"604a11bd1d969886953398ecc1fdf5847a946a8118014d0cb8daff9943f4f78c4bdbad3ee4152959c8265d0588dea658c262fe2f99a55a0b32321b81c8eec473","one":"e706876f36646bfb2dfbd11669a4907432660023a13be9de329a03f6c6e88e3788002b83d0cb4617e6c4096998783925be5b1de4f0edd8128e7d71312fb1091d","up":false},{"other":"5a59a44ba2bf5e77f921216ac467733c8529b06790efb05a63c410060edaf65547a2dbb37333073e3bcf68d422ba4b135432307f90394c6edd6dd33dd6ff2152","up":true,"one":"cc0d13dba120558dc8e2d0e5ac755a712e7e7e6dab6edcaf658faf02537b1efe3d6c54d6e67566eb4a3a8f8a019702aa7ee2b33ee3f0316a01e7b17845032e70"},{"up":true,"one":"0bf28b481d71062ee100d6cb04c8b4234a574f8657e2d3c49b60a9ecdbf486d0ec38b33bce745c8efe820145d5c53ea802aa64b4f9bce19b029ee5b2f9de43f1","other":"fb20c708420e60c48fa65980ae11adc8cdf9b56ab93044a9aee9b5196d52f29e6cb2c218f73fefbdaecf8177bae1d9d13dd64bbe06e631555715b93f58f47137"},{"up":true,"one":"81df6add458aaaaf51a3ad8826250f3498f06586264f95cd7fce642ac08bd583f463a7531e292175f90887013ba39f8757c21eb5524ec62ec413b82badae935a","other":"b1bef03357528618be6936a7edae5e3d4ecc942d43bd301642d321a73a07f3327d413f923c3fdd49d04f311e18709a4dde7519722d7a4912f181aa4df2e60173"},{"one":"c4dfcf348694971fb36ed91e9024302bec8df3891540cbe1f5df26eee9c1f81a95295f05b90ec30dd044a0355dcaa805b9f50e95f38e5588a929cfe10e8cd73d","up":true,"other":"540598224dccc717053f94e915652df499f513dc0c8874ce999040e1aa829c33ede284c72ddd0b24a319821102fa42aaaaa87380e777b5878455de61f5fc2ac9"},{"one":"cc0d13dba120558dc8e2d0e5ac755a712e7e7e6dab6edcaf658faf02537b1efe3d6c54d6e67566eb4a3a8f8a019702aa7ee2b33ee3f0316a01e7b17845032e70","up":true,"other":"59fe05843cc637adac3728acb8ca9650f49050095cf5d32241366f54d4ac7179b16dcb009e2fb9fa9499cc6f8b865b6c4d6fe6e35500df10ba5daa719d57976e"},{"other":"f78ecf420b73cd0245807157c0cbaaa568c60c80965413e187b084fb26041761d12790c0cb6a39bc8997fd2b3d3f52c831e601f1f1846945fba1808b0e1cdf25","up":true,"one":"5a59a44ba2bf5e77f921216ac467733c8529b06790efb05a63c410060edaf65547a2dbb37333073e3bcf68d422ba4b135432307f90394c6edd6dd33dd6ff2152"},{"other":"64a39acfb1accea032dfc4d1530b5cdbdc8c1b609a442b68a9b534a539062d051b750a4512b0a9d504fdffa2a5bc8d4fcb6ca59f4ddb1c59ce62e8913644499b","one":"519ce8f43529d0c703ef4faf50450877dc2818fd6fd6b7faaa9bbbaeac373e499d1b4a17b387b1a8d35e8042e18a9d3d365c97254b4d24352b10e8de9219a5cd","up":true},{"up":true,"one":"a13086041114db2be31038987ac3fdcaeb99489f1b6ee9b22998b9e66dc2f2f024307d9474811e7e8be1b1acf5a55305d5cce27d87fb834ed1e1d2e17319bb85","other":"854ff45571c01cd49d0932bcb361eef13202ababf48f0b8e5d8143dc41e01609aa1539e926bad9b4ca8add023fd259eb70239103d75b0a404bb338f3e4bf9577"},{"other":"b737c81fe6bc50d977231a5fc8856f064ba58190c5ab5615d3cf634aea8c15a308f3a667aad2e69d5c1438549cd41c863fd40f643b70caf3e0c934276ef2a84f","up":true,"one":"81df6add458aaaaf51a3ad8826250f3498f06586264f95cd7fce642ac08bd583f463a7531e292175f90887013ba39f8757c21eb5524ec62ec413b82badae935a"},{"one":"193ca2ef8a4ac98c0300d7e48421ba3fe5d4789a0c2b476499bd093808c3988b4a55742ff3f607429cafda08cbbb5fba68da8869747b1b5169f3e4545497de3a","up":true,"other":"a5990a680e1f01dcd71a178a239880c5ce24418748c368b8e3c8a1175cfd744d16973cba03e5e756820950920a6d9fa5d5dd53829a1d1d508371cb1042e9453e"},{"up":true,"one":"c4dfcf348694971fb36ed91e9024302bec8df3891540cbe1f5df26eee9c1f81a95295f05b90ec30dd044a0355dcaa805b9f50e95f38e5588a929cfe10e8cd73d","other":"82f0cbb87a76dea7947c2c1b6506d05390e5c5e969e5e91651ca10d36cd6aaea72967435ea7e5222d28f1d5e64cc526075d264712e55593bc3b609c93d4fe1eb"},{"one":"6070dc131e9721a4a496b3ed6ff5c9db1a5351e942ed424b86fe6be940d1012df766afb4b0112452dfd63e0fcfea13658324a9ef4a94b5754ec9f6219e4b0d67","up":true,"other":"2a0fa7932768f0c316b478d15db556626def18462c3bee9446ff16c48fc43b6be1694a5783602b60250e33adc705b86fae7baa6b829146251995fd47980ce422"},{"up":true,"one":"ad177f2702ed11d531b11fd0250f2dab2364624680cfb6ff1fba5b27dcd8334269a5bc9093401389044c0b00ed0cbf6f166aba81a58cadd34b25355839fff6ac","other":"236266f9f5a28148d11bed1195a91cd1d30231b082697ee1940a85abca98d2ff0767be9128c23375caa0444bcf51d8501879200ea0f27f13d0ede37f97241325"},{"other":"38469be067f9bba869fdfcc950843e00b5ff950778c11445787501d47cbaf60e9940735a5b8b71d48a0aaee75c8263137169d51944638dc5d1cad398d22439ed","one":"071c094246a0ca4b5d169e43a20ce5da508e579a6e2e822462bd8948ab357d46ab477bcff0c80eba2e01f0c100690b307af40d47c52ebad06783e9e77466cbd6","up":false},{"up":true,"one":"a13086041114db2be31038987ac3fdcaeb99489f1b6ee9b22998b9e66dc2f2f024307d9474811e7e8be1b1acf5a55305d5cce27d87fb834ed1e1d2e17319bb85","other":"dee5fb5ccdfe3803cab3e0041c5c4879001bf2c2233446f47245d8234642046269bfe50e414cd2d89341e338597f2ecbb7b2912c20558a85041b757a24490805"},{"other":"2396833be485e50b230a07fddff7f24e11e3fdee3f08f11a287faa2b03b26451b9f4fd24ddefdec62917ae59b6fa56a75e7d6e078b411d624704b88f841b9960","up":true,"one":"b440e8bc7d39b8cf9cca03b343c83ba8dd673062cead7bbfce6ed77ea16fa61f0b81df31fc418f4c133d1bb104939ac1b6e5f5a76fbcf50141a1ea33dfeb86e5"},{"up":true,"one":"5a59a44ba2bf5e77f921216ac467733c8529b06790efb05a63c410060edaf65547a2dbb37333073e3bcf68d422ba4b135432307f90394c6edd6dd33dd6ff2152","other":"cc94ed069ddcc24dc2733eed5ba8367a2521a5955c7287c5280c71675b9965ee8499454b227a4ddc64a14d74b39916211763ddf0b7ad80a52381cc61dcb6c72c"},{"up":false,"one":"fa4174ca214905c4136e891e64349f664f166aeeacead6f6e84892ebcadd2c7fbff07052ea4913a9465999f5494962ec29f7f7a3e6cbb993e00d1b881fb31eb1","other":"c49e963a92b93a1c48fd3e38c127bfc88fbcb15b57bfdf8615c0e591b24276d4fe153a811932aefdcf3dee494d53ce354ba052c24313a725d562c6e807ab9133"},{"other":"eeb9d718ef61c14e10ab2fb3a90b039368acd17a59f70628deb39515c227bd0916c796cd7767b1a9d4f38e04f1013173b21c1fa2e0206ecdc72df6c2621380a2","up":true,"one":"fb20c708420e60c48fa65980ae11adc8cdf9b56ab93044a9aee9b5196d52f29e6cb2c218f73fefbdaecf8177bae1d9d13dd64bbe06e631555715b93f58f47137"},{"one":"54b79d3662ba486bbd120313d59ef101acf963eb3d6112a9dda121bc0b52f4b1fbcb13406705cdd8c2d3990ad296171c7972211467cc0d44cbe9ca16fbc82e3e","up":true,"other":"f78ecf420b73cd0245807157c0cbaaa568c60c80965413e187b084fb26041761d12790c0cb6a39bc8997fd2b3d3f52c831e601f1f1846945fba1808b0e1cdf25"},{"up":true,"one":"c796d4917dd22d9836a9d7d24ba6f89e1a0e8a78a207bd930991e44e9c80ac1de8e4e1a023d550a6dfa60270fbb3935a7e03ef389c1ccda957a4a6a75ef6819b","other":"464cf4c4203246240a63965062b9e5a7e5fa903f127b1f5ea5b37a27d33d8b12768fc2d8f257e67418f1e5765e627ca8f8cd5ba6b15b8a047490d26ce43e6291"},{"one":"193ca2ef8a4ac98c0300d7e48421ba3fe5d4789a0c2b476499bd093808c3988b4a55742ff3f607429cafda08cbbb5fba68da8869747b1b5169f3e4545497de3a","up":true,"other":"4903cd53b3ffc4328547e03dec8f7992edbfb1e1697e53772ef79887984b11595167eb84015ff3dfb26ac0d7b2e98b7a0792bef843d2bdff3a76889fc4a6c60a"},{"up":true,"one":"55beb7853107501c013283d0114f9812c2e97b292f90ae9bdd5aa8189d0379a758cbf19c5fa62436bc75a6e30d935a3bd52025b06efd167fa2fb8a1caead2f83","other":"6d3bd11f2f7fe855188423bc49be111cd13defeb78a76eb26d415bfc0c86b89e90724db54a12ae7e0c76b9eb12eb456fc50668697245fca00f9ec3c6fb9c8588"},{"other":"0c000879be78fc867857011e396e2dd77bc2a0c6c2c3624d98b102737aa8d998ca9081653c0c8285117a5288b1bfeed06c54b2f6e39225aca4a21ff2a72116e1","up":false,"one":"236266f9f5a28148d11bed1195a91cd1d30231b082697ee1940a85abca98d2ff0767be9128c23375caa0444bcf51d8501879200ea0f27f13d0ede37f97241325"},{"other":"af761f8d13059f1e49d2f5c0b7a76a5eb5bcaab1e7ff01673dff3967d81bd7aebf74afef3934328034c82f131fa066de71816cff8f720e0c56d5e85b233a8a44","one":"854ff45571c01cd49d0932bcb361eef13202ababf48f0b8e5d8143dc41e01609aa1539e926bad9b4ca8add023fd259eb70239103d75b0a404bb338f3e4bf9577","up":false},{"up":true,"one":"41ded7596eac3eddfd1f7656ef23adabe1d18027f6159e45867e935d1ab742ec298ba2b23df522f79f59c7805510d8c995837380432dee37912d6ede1196caa2","other":"0d85f39dca79f99b277ad5cedfcd3fb1eccc7862c95c215ba0d5a2ec1c4fa80244393d0934cf59fe988f7716bf15cb8e79f4ee03fbe4a48a10cac6e0610f9d55"},{"other":"334b59c2767fc786551dfdc0a9fcd6f5b53cbe48ddc1ca61b84f8155a15de7e8cd44cbb3a537e1aa7f11416eb710c5de916a5e8ce24e83bfa570b7344c5873ea","up":false,"one":"bebbde654a4f3e3e65f63d10cbcc89dfd46ce75945c19be33bfe4d954c8ed375981e21a8376ad10e402dddbcf3b657e6786c0820e599a0d1fe03f8d35294d7c7"},{"other":"d6f274a2f20831a1b2281d889f46ad44f1bc5a07bb2152c89e129afb1c1e643b608621791a9d15a28da022d57b8bc3c05a7da0b5a93201dd714179e4a6a29a8b","up":true,"one":"464cf4c4203246240a63965062b9e5a7e5fa903f127b1f5ea5b37a27d33d8b12768fc2d8f257e67418f1e5765e627ca8f8cd5ba6b15b8a047490d26ce43e6291"},{"other":"0d85f39dca79f99b277ad5cedfcd3fb1eccc7862c95c215ba0d5a2ec1c4fa80244393d0934cf59fe988f7716bf15cb8e79f4ee03fbe4a48a10cac6e0610f9d55","up":true,"one":"54b79d3662ba486bbd120313d59ef101acf963eb3d6112a9dda121bc0b52f4b1fbcb13406705cdd8c2d3990ad296171c7972211467cc0d44cbe9ca16fbc82e3e"},{"other":"59fe05843cc637adac3728acb8ca9650f49050095cf5d32241366f54d4ac7179b16dcb009e2fb9fa9499cc6f8b865b6c4d6fe6e35500df10ba5daa719d57976e","up":false,"one":"8b8c15c6329096267a25d4060ee19963afb6e776fea60d9d566d4e1f9b087581b36e33fc533d7f133668a7a6a22f81a1234ed9fbce26eff1d5e5691a6148d540"},{"other":"e706876f36646bfb2dfbd11669a4907432660023a13be9de329a03f6c6e88e3788002b83d0cb4617e6c4096998783925be5b1de4f0edd8128e7d71312fb1091d","up":false,"one":"fa4174ca214905c4136e891e64349f664f166aeeacead6f6e84892ebcadd2c7fbff07052ea4913a9465999f5494962ec29f7f7a3e6cbb993e00d1b881fb31eb1"},{"other":"9b3fecfc63256a9d69e75ccb5119b2866e30fa4516b3a3bf5b2f03f04f1d20de786ddb90fa2acadb2a0509503b21fc9d16238c57f9b102ceedb6b27ee1b2c4ea","one":"55beb7853107501c013283d0114f9812c2e97b292f90ae9bdd5aa8189d0379a758cbf19c5fa62436bc75a6e30d935a3bd52025b06efd167fa2fb8a1caead2f83","up":true},{"up":false,"one":"41ded7596eac3eddfd1f7656ef23adabe1d18027f6159e45867e935d1ab742ec298ba2b23df522f79f59c7805510d8c995837380432dee37912d6ede1196caa2","other":"c708e3584cd9450b30d8cdd960a676884f64364c2aec985eebb4a0d745f6c73b6b0cb16f330bf090320bc48a5a67e8519b3c2c4a64cf2eff9aa4f1fc0b274a00"},{"other":"38469be067f9bba869fdfcc950843e00b5ff950778c11445787501d47cbaf60e9940735a5b8b71d48a0aaee75c8263137169d51944638dc5d1cad398d22439ed","one":"fa4174ca214905c4136e891e64349f664f166aeeacead6f6e84892ebcadd2c7fbff07052ea4913a9465999f5494962ec29f7f7a3e6cbb993e00d1b881fb31eb1","up":false},{"other":"c708e3584cd9450b30d8cdd960a676884f64364c2aec985eebb4a0d745f6c73b6b0cb16f330bf090320bc48a5a67e8519b3c2c4a64cf2eff9aa4f1fc0b274a00","one":"464cf4c4203246240a63965062b9e5a7e5fa903f127b1f5ea5b37a27d33d8b12768fc2d8f257e67418f1e5765e627ca8f8cd5ba6b15b8a047490d26ce43e6291","up":false},{"one":"55beb7853107501c013283d0114f9812c2e97b292f90ae9bdd5aa8189d0379a758cbf19c5fa62436bc75a6e30d935a3bd52025b06efd167fa2fb8a1caead2f83","up":true,"other":"d2cf35afdb846755290a7c3a1a36758e735a4eeed57b1af66595c55ab45c52cf2c478de3f395b38513cdc9e49568892cce490de93074fa45b640628f0fe40719"},{"up":false,"one":"c708e3584cd9450b30d8cdd960a676884f64364c2aec985eebb4a0d745f6c73b6b0cb16f330bf090320bc48a5a67e8519b3c2c4a64cf2eff9aa4f1fc0b274a00","other":"eb6fa7d39fcee5a7081813169ae24ee6d355cfe717dcb2fa500a07c935ffbe1b12378ea13454742bf7c2df10ad2fd4e53476068eaef4669381c8cd060c199e11"},{"up":true,"one":"b949f482891fff7d7d1f0d84112db7080fa1df07cd4e52ee0fadb707a4b7903fc0da9fe45b7ceee37948856687f8e7768945295de15691a99c879f1816899d98","other":"3db9984cb1e25bdc30c483f3d4c036fb1728bafffecd2b965af7e701569c28116dbed2e5892504ea9927c14570351b03cb99112a5924a27e6e03289422785c7b"},{"one":"41ded7596eac3eddfd1f7656ef23adabe1d18027f6159e45867e935d1ab742ec298ba2b23df522f79f59c7805510d8c995837380432dee37912d6ede1196caa2","up":false,"other":"850e729f9bbb5ef6e12baf7d3dced180839e88e0845baa7aa8fb87dcb417aa74af5999bda81723aabbef5eda842fa4b5fae107fcff9f6bd50597e8ba6a849dff"},{"other":"0c000879be78fc867857011e396e2dd77bc2a0c6c2c3624d98b102737aa8d998ca9081653c0c8285117a5288b1bfeed06c54b2f6e39225aca4a21ff2a72116e1","one":"464cf4c4203246240a63965062b9e5a7e5fa903f127b1f5ea5b37a27d33d8b12768fc2d8f257e67418f1e5765e627ca8f8cd5ba6b15b8a047490d26ce43e6291","up":false},{"other":"eeb9d718ef61c14e10ab2fb3a90b039368acd17a59f70628deb39515c227bd0916c796cd7767b1a9d4f38e04f1013173b21c1fa2e0206ecdc72df6c2621380a2","up":true,"one":"a13086041114db2be31038987ac3fdcaeb99489f1b6ee9b22998b9e66dc2f2f024307d9474811e7e8be1b1acf5a55305d5cce27d87fb834ed1e1d2e17319bb85"},{"other":"dee5fb5ccdfe3803cab3e0041c5c4879001bf2c2233446f47245d8234642046269bfe50e414cd2d89341e338597f2ecbb7b2912c20558a85041b757a24490805","up":true,"one":"a4dd67ab4fff1a50968c7ab59c304eb0083b072fc13dff599eeadac4e0e75099f7c825f91dd1bb770f3ae6f3d1d82ad574d6ecb117adf1ca9ccbccd01303ec7c"},{"other":"a4dd67ab4fff1a50968c7ab59c304eb0083b072fc13dff599eeadac4e0e75099f7c825f91dd1bb770f3ae6f3d1d82ad574d6ecb117adf1ca9ccbccd01303ec7c","one":"fb20c708420e60c48fa65980ae11adc8cdf9b56ab93044a9aee9b5196d52f29e6cb2c218f73fefbdaecf8177bae1d9d13dd64bbe06e631555715b93f58f47137","up":true},{"one":"3dcf5ec3ebb3b7de61dfaef4ee397a4a13a96ee40673be2eaadfcadd11f139c594c74237b40dd9c10f059f40d325c014f5b02b3a8eb7f0dc7d66ced7fea9f17f","up":true,"other":"223d79f656e3f124ee1238ca46e42c2a0d8500ee58a37312c6b72657a11ad9ebce3be4c061611b913a22863f6e7936ff37602dedc7856baea27e8201db44bbf4"},{"one":"bebbde654a4f3e3e65f63d10cbcc89dfd46ce75945c19be33bfe4d954c8ed375981e21a8376ad10e402dddbcf3b657e6786c0820e599a0d1fe03f8d35294d7c7","up":true,"other":"fd321c630fadcc8d6b00589323f7313ac1e94effbe8192955da5f88dcf419ef28820075e0e81c595561ff6ee58cfce23079407edf8b1611cb994946bcbd26364"},{"other":"5c1e9692b731421d6eaca488e8ba4cfdda1933ac5f1504ece684fadbea07a7c8053feb73be7ce20aedeaecc84f14d836b5ed2a657df6ca04f4fc82c2da0c0d46","up":true,"one":"946b3f821a4b61661e8ace52f4ade415042fddf058d97a16f08d9eff7a0be633de47c27fa9760ff38d583b2405163d4a27d3a7949d4015271396c014043a34e3"},{"other":"55beb7853107501c013283d0114f9812c2e97b292f90ae9bdd5aa8189d0379a758cbf19c5fa62436bc75a6e30d935a3bd52025b06efd167fa2fb8a1caead2f83","up":false,"one":"236266f9f5a28148d11bed1195a91cd1d30231b082697ee1940a85abca98d2ff0767be9128c23375caa0444bcf51d8501879200ea0f27f13d0ede37f97241325"},{"other":"a1b07c24605e258db7b8fb15db227596b08dc69bb234c0a48c312eb6eb1fb08553f8c8a6da7175eea258e2d3f2625a540c1466e6c31315aa1484fa173b7a8cfc","one":"d2cf35afdb846755290a7c3a1a36758e735a4eeed57b1af66595c55ab45c52cf2c478de3f395b38513cdc9e49568892cce490de93074fa45b640628f0fe40719","up":false},{"up":true,"one":"c677530a47ef470ae0811127b91c231ec8889588bd096c24a54cc48099e8edde811f4a72eedc79118acb494ef031d6adcef1595d1a17df71b25b468478e931ff","other":"fd321c630fadcc8d6b00589323f7313ac1e94effbe8192955da5f88dcf419ef28820075e0e81c595561ff6ee58cfce23079407edf8b1611cb994946bcbd26364"},{"other":"7172a86afb608acd9a3e1e5c0472489ebecb516cad6796fa9a06ab47cc8e8cce12dddce72f0ac3b0927602bd22ed5872c3b5ce9b6af96f8e9d1d75078cc9bb55","one":"b440e8bc7d39b8cf9cca03b343c83ba8dd673062cead7bbfce6ed77ea16fa61f0b81df31fc418f4c133d1bb104939ac1b6e5f5a76fbcf50141a1ea33dfeb86e5","up":true},{"other":"3db9984cb1e25bdc30c483f3d4c036fb1728bafffecd2b965af7e701569c28116dbed2e5892504ea9927c14570351b03cb99112a5924a27e6e03289422785c7b","one":"54b79d3662ba486bbd120313d59ef101acf963eb3d6112a9dda121bc0b52f4b1fbcb13406705cdd8c2d3990ad296171c7972211467cc0d44cbe9ca16fbc82e3e","up":true},{"up":false,"one":"dee5fb5ccdfe3803cab3e0041c5c4879001bf2c2233446f47245d8234642046269bfe50e414cd2d89341e338597f2ecbb7b2912c20558a85041b757a24490805","other":"854ff45571c01cd49d0932bcb361eef13202ababf48f0b8e5d8143dc41e01609aa1539e926bad9b4ca8add023fd259eb70239103d75b0a404bb338f3e4bf9577"},{"other":"d33f82b6a46535e798b78ebb28047ece1ef3b696ab29726d283161c377ed17a735a0948b99d83dee2af71704001e2e13813854a1b0ef4fcefd3c0e5c5f6e720d","one":"a4dd67ab4fff1a50968c7ab59c304eb0083b072fc13dff599eeadac4e0e75099f7c825f91dd1bb770f3ae6f3d1d82ad574d6ecb117adf1ca9ccbccd01303ec7c","up":true},{"other":"45c635c4080d47e2f932c27472e487ec95b7644c3d94d8627166a33dca2e3cbaa3305ae2d42e1510bfb0f8329b90e5a31883b399a469ad548fcae3040a8833a0","up":false,"one":"3dcf5ec3ebb3b7de61dfaef4ee397a4a13a96ee40673be2eaadfcadd11f139c594c74237b40dd9c10f059f40d325c014f5b02b3a8eb7f0dc7d66ced7fea9f17f"},{"up":true,"one":"223d79f656e3f124ee1238ca46e42c2a0d8500ee58a37312c6b72657a11ad9ebce3be4c061611b913a22863f6e7936ff37602dedc7856baea27e8201db44bbf4","other":"cc94ed069ddcc24dc2733eed5ba8367a2521a5955c7287c5280c71675b9965ee8499454b227a4ddc64a14d74b39916211763ddf0b7ad80a52381cc61dcb6c72c"},{"other":"5a59a44ba2bf5e77f921216ac467733c8529b06790efb05a63c410060edaf65547a2dbb37333073e3bcf68d422ba4b135432307f90394c6edd6dd33dd6ff2152","one":"dee5fb5ccdfe3803cab3e0041c5c4879001bf2c2233446f47245d8234642046269bfe50e414cd2d89341e338597f2ecbb7b2912c20558a85041b757a24490805","up":true},{"one":"a16326a0c540731e0964c4bc10c1342346fcfee70c7d1d8d333cbb774cb9f49dbf92585595654c99253eac21373706247bf5ef1ba40ac03e62da00821991cf7d","up":true,"other":"a2719942ffb6e99bda131cdedb612785dafdf72f5f35824343ad39d8568d6cd25e44b585a915c8e9ea2b02e6fd38c105bb17ed27c8fa320f18c83e0ace78feb5"},{"other":"f394aaa6d14c6ed95e2ad4651b5103bb1ab9f3a61839936cc1f08d6a6e53504e5d15dfc5211539ffdbdc64912ded5c2272d4af52ed8d7fe5a3c228eb12f0c68b","up":false,"one":"972b7f6c5b926b93a9b005bb8a891c29e535a465c586bcd4258d4094e320925a179e8f63478917f8a88d1911fe8f868013abeb34817832ed4b0b209ce392f20b"},{"other":"f8fd12d8b5872b74e2cfa60d6a3a25b568a1fb4be3a8d06faac02a38321f419c443e517c0e2989001635f827add1859a2dc9589a9c0f5bf3804d46f43f799116","up":false,"one":"c7566a0efd78ba35ad27a51a7ec8fcd55944ae12f9933573e71e2ad7404d48037dad9063c10ce5af636d7641a03899333d01aa9be94716d2179fdb2af33f36c4"},{"one":"c49e963a92b93a1c48fd3e38c127bfc88fbcb15b57bfdf8615c0e591b24276d4fe153a811932aefdcf3dee494d53ce354ba052c24313a725d562c6e807ab9133","up":true,"other":"fd321c630fadcc8d6b00589323f7313ac1e94effbe8192955da5f88dcf419ef28820075e0e81c595561ff6ee58cfce23079407edf8b1611cb994946bcbd26364"},{"one":"66652e041752f4acb27bc45c9c8b58f4f4ea904345a887a49ae831bef3bb1ad26cff7fd0f66ef3c28d6c41e039e39ff983710fdd5384f849595a66e5509e0d10","up":true,"other":"1cc62520c0d9c6a47d96e485bdc6a5d0f7319477ad6d177663f7b49217f5a8e56e4717f36fb5aa11c5270d4383cab460219821bcc6c9cbcccc4a97446b406d96"},{"other":"64a39acfb1accea032dfc4d1530b5cdbdc8c1b609a442b68a9b534a539062d051b750a4512b0a9d504fdffa2a5bc8d4fcb6ca59f4ddb1c59ce62e8913644499b","one":"5a27b90639d515cad7794dae78bf9a9866cca23c5e3e18870524d148797ba1bdfd631151f23062d4dcf0961a7dba709431a44e39da29ed5ea4b0b6987514e433","up":false},{"up":false,"one":"334b59c2767fc786551dfdc0a9fcd6f5b53cbe48ddc1ca61b84f8155a15de7e8cd44cbb3a537e1aa7f11416eb710c5de916a5e8ce24e83bfa570b7344c5873ea","other":"38469be067f9bba869fdfcc950843e00b5ff950778c11445787501d47cbaf60e9940735a5b8b71d48a0aaee75c8263137169d51944638dc5d1cad398d22439ed"},{"one":"9ad5ec0e729f9db10b7028788b58ef13d54bd11529b494a549d0415b90777b63fe78a752356315f5abbd24d849edc0c8bfe9d82c05460c30f4dad860ff5fea48","up":true,"other":"123633b35f455fc3240d99929dc3130bb018545672be151ba973915f2ab6e6c862748f60d917e48ccbf28620c4e58b888867cb51e12ec0d2e5c61cef82258719"},{"other":"d6794744c5f941cb6dbac4adbbbf11ce83c9224c8a34b9c787ed5975bf0af13e095a7db1c86fcbb7b134ae6dc67467d3ffaf191f4a4d9218779c4d0cf86876ca","one":"7ca32d24c001557a81af351ac71322543154eeedbb6ccdd8b8b142f19215aa712218babe9701e73a6441784375a511c1f16a70569b73416f9708409564d18485","up":true},{"up":false,"one":"c677530a47ef470ae0811127b91c231ec8889588bd096c24a54cc48099e8edde811f4a72eedc79118acb494ef031d6adcef1595d1a17df71b25b468478e931ff","other":"c708e3584cd9450b30d8cdd960a676884f64364c2aec985eebb4a0d745f6c73b6b0cb16f330bf090320bc48a5a67e8519b3c2c4a64cf2eff9aa4f1fc0b274a00"},{"other":"a13086041114db2be31038987ac3fdcaeb99489f1b6ee9b22998b9e66dc2f2f024307d9474811e7e8be1b1acf5a55305d5cce27d87fb834ed1e1d2e17319bb85","one":"5a59a44ba2bf5e77f921216ac467733c8529b06790efb05a63c410060edaf65547a2dbb37333073e3bcf68d422ba4b135432307f90394c6edd6dd33dd6ff2152","up":false},{"other":"3db9984cb1e25bdc30c483f3d4c036fb1728bafffecd2b965af7e701569c28116dbed2e5892504ea9927c14570351b03cb99112a5924a27e6e03289422785c7b","one":"eb6fa7d39fcee5a7081813169ae24ee6d355cfe717dcb2fa500a07c935ffbe1b12378ea13454742bf7c2df10ad2fd4e53476068eaef4669381c8cd060c199e11","up":true},{"one":"2396833be485e50b230a07fddff7f24e11e3fdee3f08f11a287faa2b03b26451b9f4fd24ddefdec62917ae59b6fa56a75e7d6e078b411d624704b88f841b9960","up":true,"other":"06a8a25c6dd90e230237b06c086f14e539b31b8e3705752d0ad8faf1bd7239547332604b79b6124cbd0cee495b99a80f147983142b7271841d8d9fa85d559301"},{"other":"de7ab7b9a2ba4ed523b84233fae11d93815579976ea78b385c658a4c156622747051f91342f9ac3610e22ee259b65e02b5af0ab67a9ee04ab6958a9d0d8acdf1","one":"6d3bd11f2f7fe855188423bc49be111cd13defeb78a76eb26d415bfc0c86b89e90724db54a12ae7e0c76b9eb12eb456fc50668697245fca00f9ec3c6fb9c8588","up":true},{"other":"69f3f9fafff951dca2fe98baa178e53f2779311a93fdc364cf4c2477700c8dbce7e4201c3aa6d840b5ae65e8fc9d6603cbc41dbdf601f1998caedee1b542d72b","up":false,"one":"7172a86afb608acd9a3e1e5c0472489ebecb516cad6796fa9a06ab47cc8e8cce12dddce72f0ac3b0927602bd22ed5872c3b5ce9b6af96f8e9d1d75078cc9bb55"},{"one":"a4dd67ab4fff1a50968c7ab59c304eb0083b072fc13dff599eeadac4e0e75099f7c825f91dd1bb770f3ae6f3d1d82ad574d6ecb117adf1ca9ccbccd01303ec7c","up":false,"other":"ab3a3ad0481a80b91132cc6afeaab9c9f5e931885d979176e8e6c181d997c38b488e5eca475b0f8e949a8cf128695e18a5851091394d0a33cf834ce7e3537ac2"},{"other":"82f0cbb87a76dea7947c2c1b6506d05390e5c5e969e5e91651ca10d36cd6aaea72967435ea7e5222d28f1d5e64cc526075d264712e55593bc3b609c93d4fe1eb","one":"c677530a47ef470ae0811127b91c231ec8889588bd096c24a54cc48099e8edde811f4a72eedc79118acb494ef031d6adcef1595d1a17df71b25b468478e931ff","up":false},{"one":"5a27b90639d515cad7794dae78bf9a9866cca23c5e3e18870524d148797ba1bdfd631151f23062d4dcf0961a7dba709431a44e39da29ed5ea4b0b6987514e433","up":false,"other":"f8fd12d8b5872b74e2cfa60d6a3a25b568a1fb4be3a8d06faac02a38321f419c443e517c0e2989001635f827add1859a2dc9589a9c0f5bf3804d46f43f799116"},{"other":"2396833be485e50b230a07fddff7f24e11e3fdee3f08f11a287faa2b03b26451b9f4fd24ddefdec62917ae59b6fa56a75e7d6e078b411d624704b88f841b9960","up":false,"one":"255939ef32bd3e5e76181763c11707b9ff4ab26d3ffb10f06fa7249b06721fa3decfa9eee3eeb8b12d6218af5f9ed8872d62c42a90cd46dcbef3d89a8163ae07"},{"one":"5c1e9692b731421d6eaca488e8ba4cfdda1933ac5f1504ece684fadbea07a7c8053feb73be7ce20aedeaecc84f14d836b5ed2a657df6ca04f4fc82c2da0c0d46","up":false,"other":"a16326a0c540731e0964c4bc10c1342346fcfee70c7d1d8d333cbb774cb9f49dbf92585595654c99253eac21373706247bf5ef1ba40ac03e62da00821991cf7d"},{"one":"a1b07c24605e258db7b8fb15db227596b08dc69bb234c0a48c312eb6eb1fb08553f8c8a6da7175eea258e2d3f2625a540c1466e6c31315aa1484fa173b7a8cfc","up":false,"other":"6070dc131e9721a4a496b3ed6ff5c9db1a5351e942ed424b86fe6be940d1012df766afb4b0112452dfd63e0fcfea13658324a9ef4a94b5754ec9f6219e4b0d67"},{"other":"5a59a44ba2bf5e77f921216ac467733c8529b06790efb05a63c410060edaf65547a2dbb37333073e3bcf68d422ba4b135432307f90394c6edd6dd33dd6ff2152","up":false,"one":"af761f8d13059f1e49d2f5c0b7a76a5eb5bcaab1e7ff01673dff3967d81bd7aebf74afef3934328034c82f131fa066de71816cff8f720e0c56d5e85b233a8a44"},{"up":false,"one":"7172a86afb608acd9a3e1e5c0472489ebecb516cad6796fa9a06ab47cc8e8cce12dddce72f0ac3b0927602bd22ed5872c3b5ce9b6af96f8e9d1d75078cc9bb55","other":"a1b07c24605e258db7b8fb15db227596b08dc69bb234c0a48c312eb6eb1fb08553f8c8a6da7175eea258e2d3f2625a540c1466e6c31315aa1484fa173b7a8cfc"},{"other":"123633b35f455fc3240d99929dc3130bb018545672be151ba973915f2ab6e6c862748f60d917e48ccbf28620c4e58b888867cb51e12ec0d2e5c61cef82258719","one":"e20a90f36eca4329d3d2dbadf530949889dc20b0ae5d96b935af9b60d26ec507e9eb1b73fd2b4dc88057c20e4ef6e7039cc49652d35c563db64f06f979e28540","up":false},{"one":"a8b619f75e0e4cf7bc5e425ff9b03e55b7301fec4fb58f321bf89811678268d9f738bbf22ee36c2d14ff71a08d6f7dca28249ff6f943cc5a77653f482254d150","up":true,"other":"6ba8900830489793a22bf5023cde4ab849dee525d1ca5b95e21040a8e8be5b295317b1c76e09beb7d17a9512137c487b99f16933622b5f2b0e10da3233086bbf"},{"other":"ef3016ea5a7b1b57388904d5c80fd05780d23acec8cf73e8add28ea99c6222fa84e89a1752186a2ef41dd0ec828405e61a1e8fd67d9496d75525ed860b12e2e8","one":"334b59c2767fc786551dfdc0a9fcd6f5b53cbe48ddc1ca61b84f8155a15de7e8cd44cbb3a537e1aa7f11416eb710c5de916a5e8ce24e83bfa570b7344c5873ea","up":false},{"other":"540598224dccc717053f94e915652df499f513dc0c8874ce999040e1aa829c33ede284c72ddd0b24a319821102fa42aaaaa87380e777b5878455de61f5fc2ac9","one":"ed3a5d7602b59bd8709ef10cb84e4b5644a69490d1173a8b9135adba04b36c1fcd0f16543de39deff0e76d8314e6884ba939213f77abb8d50a68d030352cb495","up":true},{"other":"467a76ed18ca4f195c6a5b0ac277dfd0916657e047fea073db8e28bb59098bd8960c90efe8f59d6c275ff72d18b217d225f6698e56c05e33734a0fd6ea570589","one":"d33f82b6a46535e798b78ebb28047ece1ef3b696ab29726d283161c377ed17a735a0948b99d83dee2af71704001e2e13813854a1b0ef4fcefd3c0e5c5f6e720d","up":true},{"other":"aa108a30f86b8296b416ea9fd6bc7a21c65c7cd3911ca3d4ee79325912d80db7150c02d304e49c5d0feafbd222edd6d522661a0983f1d427981760712f31e6f1","one":"1cc62520c0d9c6a47d96e485bdc6a5d0f7319477ad6d177663f7b49217f5a8e56e4717f36fb5aa11c5270d4383cab460219821bcc6c9cbcccc4a97446b406d96","up":true},{"one":"519ce8f43529d0c703ef4faf50450877dc2818fd6fd6b7faaa9bbbaeac373e499d1b4a17b387b1a8d35e8042e18a9d3d365c97254b4d24352b10e8de9219a5cd","up":false,"other":"0bf28b481d71062ee100d6cb04c8b4234a574f8657e2d3c49b60a9ecdbf486d0ec38b33bce745c8efe820145d5c53ea802aa64b4f9bce19b029ee5b2f9de43f1"},{"other":"f8fd12d8b5872b74e2cfa60d6a3a25b568a1fb4be3a8d06faac02a38321f419c443e517c0e2989001635f827add1859a2dc9589a9c0f5bf3804d46f43f799116","one":"255939ef32bd3e5e76181763c11707b9ff4ab26d3ffb10f06fa7249b06721fa3decfa9eee3eeb8b12d6218af5f9ed8872d62c42a90cd46dcbef3d89a8163ae07","up":true},{"other":"e2956a828cb1ff85ab55bdbe329f530662558cb8013ffddacac8ba36096abea07ecb15b54896dd9b4bb0b15155654dbda0c031f69290f2314ac0e376bebbd864","one":"06a8a25c6dd90e230237b06c086f14e539b31b8e3705752d0ad8faf1bd7239547332604b79b6124cbd0cee495b99a80f147983142b7271841d8d9fa85d559301","up":true},{"up":true,"one":"a8b619f75e0e4cf7bc5e425ff9b03e55b7301fec4fb58f321bf89811678268d9f738bbf22ee36c2d14ff71a08d6f7dca28249ff6f943cc5a77653f482254d150","other":"81df6add458aaaaf51a3ad8826250f3498f06586264f95cd7fce642ac08bd583f463a7531e292175f90887013ba39f8757c21eb5524ec62ec413b82badae935a"},{"up":true,"one":"1cc62520c0d9c6a47d96e485bdc6a5d0f7319477ad6d177663f7b49217f5a8e56e4717f36fb5aa11c5270d4383cab460219821bcc6c9cbcccc4a97446b406d96","other":"82f0cbb87a76dea7947c2c1b6506d05390e5c5e969e5e91651ca10d36cd6aaea72967435ea7e5222d28f1d5e64cc526075d264712e55593bc3b609c93d4fe1eb"},{"other":"3bf838b4d29d9388a24d160eee6bf8ea017af6cd9e5f7d88b4cae71ebfbc304666d3d634a05e0a75570dafe8f41871090fcff8b651a9130d013786dfcca3da14","up":true,"one":"06a8a25c6dd90e230237b06c086f14e539b31b8e3705752d0ad8faf1bd7239547332604b79b6124cbd0cee495b99a80f147983142b7271841d8d9fa85d559301"},{"one":"fd321c630fadcc8d6b00589323f7313ac1e94effbe8192955da5f88dcf419ef28820075e0e81c595561ff6ee58cfce23079407edf8b1611cb994946bcbd26364","up":true,"other":"82f0cbb87a76dea7947c2c1b6506d05390e5c5e969e5e91651ca10d36cd6aaea72967435ea7e5222d28f1d5e64cc526075d264712e55593bc3b609c93d4fe1eb"},{"other":"255939ef32bd3e5e76181763c11707b9ff4ab26d3ffb10f06fa7249b06721fa3decfa9eee3eeb8b12d6218af5f9ed8872d62c42a90cd46dcbef3d89a8163ae07","up":false,"one":"1545795dca07ecd09c5b16b3bbdddf3dba92e27b532c18a3bc63bc007761ac1b1ebc7ffb4f0a401d5376a4c67923c7949edaebd8f65fff52d6677bb1d6a72f43"},{"other":"cf03d32d3cca446e7016e7f41267a257bef7142c4f1e4ce2e17678856d75e9889e21972fd21583297a47a156543af15400444dcf37aca64543f97f73734f7f0f","up":false,"one":"d2cf35afdb846755290a7c3a1a36758e735a4eeed57b1af66595c55ab45c52cf2c478de3f395b38513cdc9e49568892cce490de93074fa45b640628f0fe40719"},{"other":"7172a86afb608acd9a3e1e5c0472489ebecb516cad6796fa9a06ab47cc8e8cce12dddce72f0ac3b0927602bd22ed5872c3b5ce9b6af96f8e9d1d75078cc9bb55","up":false,"one":"f4ae36400caeddcbcf0fb1abd5b9611c37bac683645d10c69a1ac54d366f730c59917c95e990a0fa6bb2679c98fb62bf0e29bd7812ab57375de35f469dab98a0"},{"other":"2a0fa7932768f0c316b478d15db556626def18462c3bee9446ff16c48fc43b6be1694a5783602b60250e33adc705b86fae7baa6b829146251995fd47980ce422","up":false,"one":"bebbde654a4f3e3e65f63d10cbcc89dfd46ce75945c19be33bfe4d954c8ed375981e21a8376ad10e402dddbcf3b657e6786c0820e599a0d1fe03f8d35294d7c7"},{"one":"ab3a3ad0481a80b91132cc6afeaab9c9f5e931885d979176e8e6c181d997c38b488e5eca475b0f8e949a8cf128695e18a5851091394d0a33cf834ce7e3537ac2","up":false,"other":"0bf28b481d71062ee100d6cb04c8b4234a574f8657e2d3c49b60a9ecdbf486d0ec38b33bce745c8efe820145d5c53ea802aa64b4f9bce19b029ee5b2f9de43f1"},{"up":false,"one":"35ac328e13ea4fc6c333591633455cb6a2dff124528a17668770e231582ea31ab95e083cd191d8c45369d88366e9df0d2417cd26efbf2f616139c92fd497cd48","other":"a5990a680e1f01dcd71a178a239880c5ce24418748c368b8e3c8a1175cfd744d16973cba03e5e756820950920a6d9fa5d5dd53829a1d1d508371cb1042e9453e"},{"up":false,"one":"ab3a3ad0481a80b91132cc6afeaab9c9f5e931885d979176e8e6c181d997c38b488e5eca475b0f8e949a8cf128695e18a5851091394d0a33cf834ce7e3537ac2","other":"49bd2289f479c9ad7e0d13319271b9be1e1dcbee28313513a124dec55f9842db639e62a74a83040930c537739ab7fa1e50bb05b9ab0f588d6da7b64a6451f466"},{"other":"f2ac738fa932c90a45d1a64e4a52fd9c4037e2d89ceef1584efef04689bc7aff3a9635fb78dfdf3480d003daf14359190b1cfa8335db438a54107d4060ed58f9","up":true,"one":"4228ad29aa22f1fa078c7e09f44f85c05d5b797072c10ade24dcbff95c01e554511fe10273a5f25a25ca06ff97bca28c241610f7145983f72ed44969ead4596a"},{"one":"af0050715bfa25b4ce3a7593c61578898be22801a9118064250c330c6b2a1416b3bc6d90b074d7d700e07574a274d861f9c6d8e3e5924c281502f699ad62465b","up":false,"other":"c133cd3ee228f427410357f46752d33ecf302475314411772df3532669a8b220136c09f00717460c39bcea1058cb988dd223875ec991612876b400556f5937dd"},{"other":"a2719942ffb6e99bda131cdedb612785dafdf72f5f35824343ad39d8568d6cd25e44b585a915c8e9ea2b02e6fd38c105bb17ed27c8fa320f18c83e0ace78feb5","up":true,"one":"850e729f9bbb5ef6e12baf7d3dced180839e88e0845baa7aa8fb87dcb417aa74af5999bda81723aabbef5eda842fa4b5fae107fcff9f6bd50597e8ba6a849dff"},{"other":"223d79f656e3f124ee1238ca46e42c2a0d8500ee58a37312c6b72657a11ad9ebce3be4c061611b913a22863f6e7936ff37602dedc7856baea27e8201db44bbf4","up":true,"one":"eeb9d718ef61c14e10ab2fb3a90b039368acd17a59f70628deb39515c227bd0916c796cd7767b1a9d4f38e04f1013173b21c1fa2e0206ecdc72df6c2621380a2"},{"one":"54b79d3662ba486bbd120313d59ef101acf963eb3d6112a9dda121bc0b52f4b1fbcb13406705cdd8c2d3990ad296171c7972211467cc0d44cbe9ca16fbc82e3e","up":false,"other":"66652e041752f4acb27bc45c9c8b58f4f4ea904345a887a49ae831bef3bb1ad26cff7fd0f66ef3c28d6c41e039e39ff983710fdd5384f849595a66e5509e0d10"},{"one":"464cf4c4203246240a63965062b9e5a7e5fa903f127b1f5ea5b37a27d33d8b12768fc2d8f257e67418f1e5765e627ca8f8cd5ba6b15b8a047490d26ce43e6291","up":false,"other":"9b3fecfc63256a9d69e75ccb5119b2866e30fa4516b3a3bf5b2f03f04f1d20de786ddb90fa2acadb2a0509503b21fc9d16238c57f9b102ceedb6b27ee1b2c4ea"},{"up":false,"one":"a4dd67ab4fff1a50968c7ab59c304eb0083b072fc13dff599eeadac4e0e75099f7c825f91dd1bb770f3ae6f3d1d82ad574d6ecb117adf1ca9ccbccd01303ec7c","other":"7625a1a0a0f5bf78e2b9fe43a1215ea882318458b886ec767ccbc35e76b543f96820b364342b28ff600302af7716280497141dc2fc84e83cb15f5eb3d268d73e"},{"up":false,"one":"5a27b90639d515cad7794dae78bf9a9866cca23c5e3e18870524d148797ba1bdfd631151f23062d4dcf0961a7dba709431a44e39da29ed5ea4b0b6987514e433","other":"59fe05843cc637adac3728acb8ca9650f49050095cf5d32241366f54d4ac7179b16dcb009e2fb9fa9499cc6f8b865b6c4d6fe6e35500df10ba5daa719d57976e"},{"one":"4228ad29aa22f1fa078c7e09f44f85c05d5b797072c10ade24dcbff95c01e554511fe10273a5f25a25ca06ff97bca28c241610f7145983f72ed44969ead4596a","up":true,"other":"e2956a828cb1ff85ab55bdbe329f530662558cb8013ffddacac8ba36096abea07ecb15b54896dd9b4bb0b15155654dbda0c031f69290f2314ac0e376bebbd864"},{"other":"57fb9e7f287fe67500b8b560475c0d0d6eae9d623d5a8c85eb5459f209904a839a0b24ff99a1643a4196a71d45f2ed1bd5e08f9a13cdd9749a907a024ff984dc","one":"6070dc131e9721a4a496b3ed6ff5c9db1a5351e942ed424b86fe6be940d1012df766afb4b0112452dfd63e0fcfea13658324a9ef4a94b5754ec9f6219e4b0d67","up":false},{"one":"d33f82b6a46535e798b78ebb28047ece1ef3b696ab29726d283161c377ed17a735a0948b99d83dee2af71704001e2e13813854a1b0ef4fcefd3c0e5c5f6e720d","up":false,"other":"e2956a828cb1ff85ab55bdbe329f530662558cb8013ffddacac8ba36096abea07ecb15b54896dd9b4bb0b15155654dbda0c031f69290f2314ac0e376bebbd864"},{"other":"0bf28b481d71062ee100d6cb04c8b4234a574f8657e2d3c49b60a9ecdbf486d0ec38b33bce745c8efe820145d5c53ea802aa64b4f9bce19b029ee5b2f9de43f1","one":"59fe05843cc637adac3728acb8ca9650f49050095cf5d32241366f54d4ac7179b16dcb009e2fb9fa9499cc6f8b865b6c4d6fe6e35500df10ba5daa719d57976e","up":false},{"up":false,"one":"ab3a3ad0481a80b91132cc6afeaab9c9f5e931885d979176e8e6c181d997c38b488e5eca475b0f8e949a8cf128695e18a5851091394d0a33cf834ce7e3537ac2","other":"464cf4c4203246240a63965062b9e5a7e5fa903f127b1f5ea5b37a27d33d8b12768fc2d8f257e67418f1e5765e627ca8f8cd5ba6b15b8a047490d26ce43e6291"},{"one":"af0050715bfa25b4ce3a7593c61578898be22801a9118064250c330c6b2a1416b3bc6d90b074d7d700e07574a274d861f9c6d8e3e5924c281502f699ad62465b","up":true,"other":"09fa1e69f37cb14db3dd721a9c4b9c884f6fe519d850f7af3643ecd536d4b3e995f99acf569e23b7864996c750115ff0ca0bd446ebfd76a026da71da0b95fd97"},{"other":"8b8c15c6329096267a25d4060ee19963afb6e776fea60d9d566d4e1f9b087581b36e33fc533d7f133668a7a6a22f81a1234ed9fbce26eff1d5e5691a6148d540","one":"cc94ed069ddcc24dc2733eed5ba8367a2521a5955c7287c5280c71675b9965ee8499454b227a4ddc64a14d74b39916211763ddf0b7ad80a52381cc61dcb6c72c","up":false},{"one":"2396833be485e50b230a07fddff7f24e11e3fdee3f08f11a287faa2b03b26451b9f4fd24ddefdec62917ae59b6fa56a75e7d6e078b411d624704b88f841b9960","up":false,"other":"45c635c4080d47e2f932c27472e487ec95b7644c3d94d8627166a33dca2e3cbaa3305ae2d42e1510bfb0f8329b90e5a31883b399a469ad548fcae3040a8833a0"},{"one":"eeb9d718ef61c14e10ab2fb3a90b039368acd17a59f70628deb39515c227bd0916c796cd7767b1a9d4f38e04f1013173b21c1fa2e0206ecdc72df6c2621380a2","up":true,"other":"45c635c4080d47e2f932c27472e487ec95b7644c3d94d8627166a33dca2e3cbaa3305ae2d42e1510bfb0f8329b90e5a31883b399a469ad548fcae3040a8833a0"},{"up":false,"one":"5c1e9692b731421d6eaca488e8ba4cfdda1933ac5f1504ece684fadbea07a7c8053feb73be7ce20aedeaecc84f14d836b5ed2a657df6ca04f4fc82c2da0c0d46","other":"faa3c31521c8f7b9d15838750e7e311eb0f01db5ef22cd1bf62a7d72e7efdf5a575550c930d96230edc892d107d4551e95b099d3c952a7f1c0ad3b5967c7831b"},{"one":"4228ad29aa22f1fa078c7e09f44f85c05d5b797072c10ade24dcbff95c01e554511fe10273a5f25a25ca06ff97bca28c241610f7145983f72ed44969ead4596a","up":true,"other":"fb20c708420e60c48fa65980ae11adc8cdf9b56ab93044a9aee9b5196d52f29e6cb2c218f73fefbdaecf8177bae1d9d13dd64bbe06e631555715b93f58f47137"},{"up":false,"one":"e20a90f36eca4329d3d2dbadf530949889dc20b0ae5d96b935af9b60d26ec507e9eb1b73fd2b4dc88057c20e4ef6e7039cc49652d35c563db64f06f979e28540","other":"c708e3584cd9450b30d8cdd960a676884f64364c2aec985eebb4a0d745f6c73b6b0cb16f330bf090320bc48a5a67e8519b3c2c4a64cf2eff9aa4f1fc0b274a00"},{"one":"519ce8f43529d0c703ef4faf50450877dc2818fd6fd6b7faaa9bbbaeac373e499d1b4a17b387b1a8d35e8042e18a9d3d365c97254b4d24352b10e8de9219a5cd","up":false,"other":"49bd2289f479c9ad7e0d13319271b9be1e1dcbee28313513a124dec55f9842db639e62a74a83040930c537739ab7fa1e50bb05b9ab0f588d6da7b64a6451f466"},{"other":"cf03d32d3cca446e7016e7f41267a257bef7142c4f1e4ce2e17678856d75e9889e21972fd21583297a47a156543af15400444dcf37aca64543f97f73734f7f0f","up":true,"one":"1cc62520c0d9c6a47d96e485bdc6a5d0f7319477ad6d177663f7b49217f5a8e56e4717f36fb5aa11c5270d4383cab460219821bcc6c9cbcccc4a97446b406d96"},{"other":"0c000879be78fc867857011e396e2dd77bc2a0c6c2c3624d98b102737aa8d998ca9081653c0c8285117a5288b1bfeed06c54b2f6e39225aca4a21ff2a72116e1","one":"35ac328e13ea4fc6c333591633455cb6a2dff124528a17668770e231582ea31ab95e083cd191d8c45369d88366e9df0d2417cd26efbf2f616139c92fd497cd48","up":false},{"other":"4228ad29aa22f1fa078c7e09f44f85c05d5b797072c10ade24dcbff95c01e554511fe10273a5f25a25ca06ff97bca28c241610f7145983f72ed44969ead4596a","one":"7625a1a0a0f5bf78e2b9fe43a1215ea882318458b886ec767ccbc35e76b543f96820b364342b28ff600302af7716280497141dc2fc84e83cb15f5eb3d268d73e","up":true},{"up":true,"one":"4903cd53b3ffc4328547e03dec8f7992edbfb1e1697e53772ef79887984b11595167eb84015ff3dfb26ac0d7b2e98b7a0792bef843d2bdff3a76889fc4a6c60a","other":"aa108a30f86b8296b416ea9fd6bc7a21c65c7cd3911ca3d4ee79325912d80db7150c02d304e49c5d0feafbd222edd6d522661a0983f1d427981760712f31e6f1"},{"other":"6d3bd11f2f7fe855188423bc49be111cd13defeb78a76eb26d415bfc0c86b89e90724db54a12ae7e0c76b9eb12eb456fc50668697245fca00f9ec3c6fb9c8588","one":"b440e8bc7d39b8cf9cca03b343c83ba8dd673062cead7bbfce6ed77ea16fa61f0b81df31fc418f4c133d1bb104939ac1b6e5f5a76fbcf50141a1ea33dfeb86e5","up":false},{"one":"d6794744c5f941cb6dbac4adbbbf11ce83c9224c8a34b9c787ed5975bf0af13e095a7db1c86fcbb7b134ae6dc67467d3ffaf191f4a4d9218779c4d0cf86876ca","up":true,"other":"932e926c54a4127210a15731fa4ad6bbfd0d69183b894b676920843f154ad1e4148b674d234f070e9dc07547394a5af973befe0fc170bbe44346d69e135e0157"},{"other":"1cc62520c0d9c6a47d96e485bdc6a5d0f7319477ad6d177663f7b49217f5a8e56e4717f36fb5aa11c5270d4383cab460219821bcc6c9cbcccc4a97446b406d96","one":"467a76ed18ca4f195c6a5b0ac277dfd0916657e047fea073db8e28bb59098bd8960c90efe8f59d6c275ff72d18b217d225f6698e56c05e33734a0fd6ea570589","up":true},{"up":false,"one":"ef3016ea5a7b1b57388904d5c80fd05780d23acec8cf73e8add28ea99c6222fa84e89a1752186a2ef41dd0ec828405e61a1e8fd67d9496d75525ed860b12e2e8","other":"53031cddf4390ba176d638456016028bd4538879c7eaba672c3ef70208319a14e6a41dea8ff003b6f7e9b4a83ca12dab50d4f44f079153bec7c24221e311573e"},{"up":false,"one":"255939ef32bd3e5e76181763c11707b9ff4ab26d3ffb10f06fa7249b06721fa3decfa9eee3eeb8b12d6218af5f9ed8872d62c42a90cd46dcbef3d89a8163ae07","other":"59fe05843cc637adac3728acb8ca9650f49050095cf5d32241366f54d4ac7179b16dcb009e2fb9fa9499cc6f8b865b6c4d6fe6e35500df10ba5daa719d57976e"},{"up":false,"one":"d6f274a2f20831a1b2281d889f46ad44f1bc5a07bb2152c89e129afb1c1e643b608621791a9d15a28da022d57b8bc3c05a7da0b5a93201dd714179e4a6a29a8b","other":"cf03d32d3cca446e7016e7f41267a257bef7142c4f1e4ce2e17678856d75e9889e21972fd21583297a47a156543af15400444dcf37aca64543f97f73734f7f0f"},{"one":"f78ecf420b73cd0245807157c0cbaaa568c60c80965413e187b084fb26041761d12790c0cb6a39bc8997fd2b3d3f52c831e601f1f1846945fba1808b0e1cdf25","up":false,"other":"49bd2289f479c9ad7e0d13319271b9be1e1dcbee28313513a124dec55f9842db639e62a74a83040930c537739ab7fa1e50bb05b9ab0f588d6da7b64a6451f466"},{"one":"a5990a680e1f01dcd71a178a239880c5ce24418748c368b8e3c8a1175cfd744d16973cba03e5e756820950920a6d9fa5d5dd53829a1d1d508371cb1042e9453e","up":true,"other":"aa108a30f86b8296b416ea9fd6bc7a21c65c7cd3911ca3d4ee79325912d80db7150c02d304e49c5d0feafbd222edd6d522661a0983f1d427981760712f31e6f1"},{"other":"e2956a828cb1ff85ab55bdbe329f530662558cb8013ffddacac8ba36096abea07ecb15b54896dd9b4bb0b15155654dbda0c031f69290f2314ac0e376bebbd864","up":false,"one":"4f4201d959e4add3a4bcf3cbaab29d8abcc7530a9834e3cde45c4459ea92fba869e65156037a8fae02eac05f6174a7f2c1d825418f2207caa2284bcc9d9b84d1"},{"one":"540598224dccc717053f94e915652df499f513dc0c8874ce999040e1aa829c33ede284c72ddd0b24a319821102fa42aaaaa87380e777b5878455de61f5fc2ac9","up":true,"other":"0c000879be78fc867857011e396e2dd77bc2a0c6c2c3624d98b102737aa8d998ca9081653c0c8285117a5288b1bfeed06c54b2f6e39225aca4a21ff2a72116e1"},{"other":"c133cd3ee228f427410357f46752d33ecf302475314411772df3532669a8b220136c09f00717460c39bcea1058cb988dd223875ec991612876b400556f5937dd","one":"cf03d32d3cca446e7016e7f41267a257bef7142c4f1e4ce2e17678856d75e9889e21972fd21583297a47a156543af15400444dcf37aca64543f97f73734f7f0f","up":false},{"other":"a4dd67ab4fff1a50968c7ab59c304eb0083b072fc13dff599eeadac4e0e75099f7c825f91dd1bb770f3ae6f3d1d82ad574d6ecb117adf1ca9ccbccd01303ec7c","up":false,"one":"cf03d32d3cca446e7016e7f41267a257bef7142c4f1e4ce2e17678856d75e9889e21972fd21583297a47a156543af15400444dcf37aca64543f97f73734f7f0f"},{"other":"850e729f9bbb5ef6e12baf7d3dced180839e88e0845baa7aa8fb87dcb417aa74af5999bda81723aabbef5eda842fa4b5fae107fcff9f6bd50597e8ba6a849dff","one":"540598224dccc717053f94e915652df499f513dc0c8874ce999040e1aa829c33ede284c72ddd0b24a319821102fa42aaaaa87380e777b5878455de61f5fc2ac9","up":false},{"other":"b440e8bc7d39b8cf9cca03b343c83ba8dd673062cead7bbfce6ed77ea16fa61f0b81df31fc418f4c133d1bb104939ac1b6e5f5a76fbcf50141a1ea33dfeb86e5","up":false,"one":"7625a1a0a0f5bf78e2b9fe43a1215ea882318458b886ec767ccbc35e76b543f96820b364342b28ff600302af7716280497141dc2fc84e83cb15f5eb3d268d73e"},{"other":"3bf838b4d29d9388a24d160eee6bf8ea017af6cd9e5f7d88b4cae71ebfbc304666d3d634a05e0a75570dafe8f41871090fcff8b651a9130d013786dfcca3da14","one":"4f4201d959e4add3a4bcf3cbaab29d8abcc7530a9834e3cde45c4459ea92fba869e65156037a8fae02eac05f6174a7f2c1d825418f2207caa2284bcc9d9b84d1","up":false},{"up":false,"one":"eeb9d718ef61c14e10ab2fb3a90b039368acd17a59f70628deb39515c227bd0916c796cd7767b1a9d4f38e04f1013173b21c1fa2e0206ecdc72df6c2621380a2","other":"255939ef32bd3e5e76181763c11707b9ff4ab26d3ffb10f06fa7249b06721fa3decfa9eee3eeb8b12d6218af5f9ed8872d62c42a90cd46dcbef3d89a8163ae07"},{"one":"464cf4c4203246240a63965062b9e5a7e5fa903f127b1f5ea5b37a27d33d8b12768fc2d8f257e67418f1e5765e627ca8f8cd5ba6b15b8a047490d26ce43e6291","up":true,"other":"ad177f2702ed11d531b11fd0250f2dab2364624680cfb6ff1fba5b27dcd8334269a5bc9093401389044c0b00ed0cbf6f166aba81a58cadd34b25355839fff6ac"},{"one":"826500ca53a2aed90da0cc3778cbc41af3de0139b246f30c3be65582b1f152928dfa3280760da4dcd8098f41f529a088dba24bc5d0c71322ef69f4b101f0224a","up":false,"other":"e2956a828cb1ff85ab55bdbe329f530662558cb8013ffddacac8ba36096abea07ecb15b54896dd9b4bb0b15155654dbda0c031f69290f2314ac0e376bebbd864"},{"up":false,"one":"a4dd67ab4fff1a50968c7ab59c304eb0083b072fc13dff599eeadac4e0e75099f7c825f91dd1bb770f3ae6f3d1d82ad574d6ecb117adf1ca9ccbccd01303ec7c","other":"45c635c4080d47e2f932c27472e487ec95b7644c3d94d8627166a33dca2e3cbaa3305ae2d42e1510bfb0f8329b90e5a31883b399a469ad548fcae3040a8833a0"},{"other":"35ac328e13ea4fc6c333591633455cb6a2dff124528a17668770e231582ea31ab95e083cd191d8c45369d88366e9df0d2417cd26efbf2f616139c92fd497cd48","up":false,"one":"a2719942ffb6e99bda131cdedb612785dafdf72f5f35824343ad39d8568d6cd25e44b585a915c8e9ea2b02e6fd38c105bb17ed27c8fa320f18c83e0ace78feb5"},{"up":true,"one":"96f3194c9ef17f60c318be14dd72c51af0aebc19f7a574b769d18b1fda6791409c827892bae3a061800e3d78af88a97635a0a892c54d7ebb38342ab1ba99c3ad","other":"6070dc131e9721a4a496b3ed6ff5c9db1a5351e942ed424b86fe6be940d1012df766afb4b0112452dfd63e0fcfea13658324a9ef4a94b5754ec9f6219e4b0d67"},{"up":false,"one":"b440e8bc7d39b8cf9cca03b343c83ba8dd673062cead7bbfce6ed77ea16fa61f0b81df31fc418f4c133d1bb104939ac1b6e5f5a76fbcf50141a1ea33dfeb86e5","other":"45c635c4080d47e2f932c27472e487ec95b7644c3d94d8627166a33dca2e3cbaa3305ae2d42e1510bfb0f8329b90e5a31883b399a469ad548fcae3040a8833a0"},{"one":"f2ac738fa932c90a45d1a64e4a52fd9c4037e2d89ceef1584efef04689bc7aff3a9635fb78dfdf3480d003daf14359190b1cfa8335db438a54107d4060ed58f9","up":false,"other":"45c635c4080d47e2f932c27472e487ec95b7644c3d94d8627166a33dca2e3cbaa3305ae2d42e1510bfb0f8329b90e5a31883b399a469ad548fcae3040a8833a0"},{"other":"f8fd12d8b5872b74e2cfa60d6a3a25b568a1fb4be3a8d06faac02a38321f419c443e517c0e2989001635f827add1859a2dc9589a9c0f5bf3804d46f43f799116","one":"11170a0fb9f6b037f8ee4494e935a84b06816ff5c44ef9d613920f9c58f8b25611b2093da3fb51a59687db6a9b0a070386cac09757a27f75754cbdcb9afc2225","up":false},{"up":false,"one":"ab3a3ad0481a80b91132cc6afeaab9c9f5e931885d979176e8e6c181d997c38b488e5eca475b0f8e949a8cf128695e18a5851091394d0a33cf834ce7e3537ac2","other":"1cc62520c0d9c6a47d96e485bdc6a5d0f7319477ad6d177663f7b49217f5a8e56e4717f36fb5aa11c5270d4383cab460219821bcc6c9cbcccc4a97446b406d96"},{"other":"cf03d32d3cca446e7016e7f41267a257bef7142c4f1e4ce2e17678856d75e9889e21972fd21583297a47a156543af15400444dcf37aca64543f97f73734f7f0f","up":false,"one":"6070dc131e9721a4a496b3ed6ff5c9db1a5351e942ed424b86fe6be940d1012df766afb4b0112452dfd63e0fcfea13658324a9ef4a94b5754ec9f6219e4b0d67"},{"other":"972b7f6c5b926b93a9b005bb8a891c29e535a465c586bcd4258d4094e320925a179e8f63478917f8a88d1911fe8f868013abeb34817832ed4b0b209ce392f20b","up":false,"one":"eb6fa7d39fcee5a7081813169ae24ee6d355cfe717dcb2fa500a07c935ffbe1b12378ea13454742bf7c2df10ad2fd4e53476068eaef4669381c8cd060c199e11"},{"other":"59fe05843cc637adac3728acb8ca9650f49050095cf5d32241366f54d4ac7179b16dcb009e2fb9fa9499cc6f8b865b6c4d6fe6e35500df10ba5daa719d57976e","one":"11170a0fb9f6b037f8ee4494e935a84b06816ff5c44ef9d613920f9c58f8b25611b2093da3fb51a59687db6a9b0a070386cac09757a27f75754cbdcb9afc2225","up":false},{"up":false,"one":"4228ad29aa22f1fa078c7e09f44f85c05d5b797072c10ade24dcbff95c01e554511fe10273a5f25a25ca06ff97bca28c241610f7145983f72ed44969ead4596a","other":"06a8a25c6dd90e230237b06c086f14e539b31b8e3705752d0ad8faf1bd7239547332604b79b6124cbd0cee495b99a80f147983142b7271841d8d9fa85d559301"},{"up":true,"one":"af6cb988ddb16202459735b8489c02b3bf829ca301513a0d3e18bbb03d43c8de3cda767c7b5c984a6dce3f118c8089e06b08ed3bd0c922dde9cfe775609df3b2","other":"255939ef32bd3e5e76181763c11707b9ff4ab26d3ffb10f06fa7249b06721fa3decfa9eee3eeb8b12d6218af5f9ed8872d62c42a90cd46dcbef3d89a8163ae07"},{"other":"255939ef32bd3e5e76181763c11707b9ff4ab26d3ffb10f06fa7249b06721fa3decfa9eee3eeb8b12d6218af5f9ed8872d62c42a90cd46dcbef3d89a8163ae07","one":"b1bef03357528618be6936a7edae5e3d4ecc942d43bd301642d321a73a07f3327d413f923c3fdd49d04f311e18709a4dde7519722d7a4912f181aa4df2e60173","up":false},{"up":false,"one":"f3bf16c7156ce55af92b2fc21826bdfd3e1f245c6087e76f5eb23cc8bbd88b25515a32029d3e6e2b4a27354606e9e3bdfe78788e326c4349d63416894fcfbaf4","other":"3bf838b4d29d9388a24d160eee6bf8ea017af6cd9e5f7d88b4cae71ebfbc304666d3d634a05e0a75570dafe8f41871090fcff8b651a9130d013786dfcca3da14"},{"one":"850e729f9bbb5ef6e12baf7d3dced180839e88e0845baa7aa8fb87dcb417aa74af5999bda81723aabbef5eda842fa4b5fae107fcff9f6bd50597e8ba6a849dff","up":false,"other":"ed3a5d7602b59bd8709ef10cb84e4b5644a69490d1173a8b9135adba04b36c1fcd0f16543de39deff0e76d8314e6884ba939213f77abb8d50a68d030352cb495"},{"up":false,"one":"7625a1a0a0f5bf78e2b9fe43a1215ea882318458b886ec767ccbc35e76b543f96820b364342b28ff600302af7716280497141dc2fc84e83cb15f5eb3d268d73e","other":"7e9a81d06e997a691cc7790d358868b8657db608795ef6b85bb194db7f56ab5c76cac3be0b40d847ce873aeef4bdad40b725d69f4c42755b9d5aab4fe7aecb34"},{"other":"d6794744c5f941cb6dbac4adbbbf11ce83c9224c8a34b9c787ed5975bf0af13e095a7db1c86fcbb7b134ae6dc67467d3ffaf191f4a4d9218779c4d0cf86876ca","up":false,"one":"faa3c31521c8f7b9d15838750e7e311eb0f01db5ef22cd1bf62a7d72e7efdf5a575550c930d96230edc892d107d4551e95b099d3c952a7f1c0ad3b5967c7831b"},{"other":"f78ecf420b73cd0245807157c0cbaaa568c60c80965413e187b084fb26041761d12790c0cb6a39bc8997fd2b3d3f52c831e601f1f1846945fba1808b0e1cdf25","one":"467a76ed18ca4f195c6a5b0ac277dfd0916657e047fea073db8e28bb59098bd8960c90efe8f59d6c275ff72d18b217d225f6698e56c05e33734a0fd6ea570589","up":false},{"other":"38469be067f9bba869fdfcc950843e00b5ff950778c11445787501d47cbaf60e9940735a5b8b71d48a0aaee75c8263137169d51944638dc5d1cad398d22439ed","up":false,"one":"ed3a5d7602b59bd8709ef10cb84e4b5644a69490d1173a8b9135adba04b36c1fcd0f16543de39deff0e76d8314e6884ba939213f77abb8d50a68d030352cb495"},{"other":"123633b35f455fc3240d99929dc3130bb018545672be151ba973915f2ab6e6c862748f60d917e48ccbf28620c4e58b888867cb51e12ec0d2e5c61cef82258719","one":"a1b07c24605e258db7b8fb15db227596b08dc69bb234c0a48c312eb6eb1fb08553f8c8a6da7175eea258e2d3f2625a540c1466e6c31315aa1484fa173b7a8cfc","up":false},{"other":"a089758c25ca0730f13cd18c10aeea62488c1c2651eef53a8ad11cfdfa61ce8f7354a53bd6902da26b79dfbedc78d315b1d4239eb62cbca59215727b2ac35213","one":"826500ca53a2aed90da0cc3778cbc41af3de0139b246f30c3be65582b1f152928dfa3280760da4dcd8098f41f529a088dba24bc5d0c71322ef69f4b101f0224a","up":false},{"other":"5a59a44ba2bf5e77f921216ac467733c8529b06790efb05a63c410060edaf65547a2dbb37333073e3bcf68d422ba4b135432307f90394c6edd6dd33dd6ff2152","one":"ad177f2702ed11d531b11fd0250f2dab2364624680cfb6ff1fba5b27dcd8334269a5bc9093401389044c0b00ed0cbf6f166aba81a58cadd34b25355839fff6ac","up":false},{"up":false,"one":"b1bef03357528618be6936a7edae5e3d4ecc942d43bd301642d321a73a07f3327d413f923c3fdd49d04f311e18709a4dde7519722d7a4912f181aa4df2e60173","other":"49bd2289f479c9ad7e0d13319271b9be1e1dcbee28313513a124dec55f9842db639e62a74a83040930c537739ab7fa1e50bb05b9ab0f588d6da7b64a6451f466"},{"up":false,"one":"a2719942ffb6e99bda131cdedb612785dafdf72f5f35824343ad39d8568d6cd25e44b585a915c8e9ea2b02e6fd38c105bb17ed27c8fa320f18c83e0ace78feb5","other":"ef3016ea5a7b1b57388904d5c80fd05780d23acec8cf73e8add28ea99c6222fa84e89a1752186a2ef41dd0ec828405e61a1e8fd67d9496d75525ed860b12e2e8"},{"one":"e20a90f36eca4329d3d2dbadf530949889dc20b0ae5d96b935af9b60d26ec507e9eb1b73fd2b4dc88057c20e4ef6e7039cc49652d35c563db64f06f979e28540","up":false,"other":"467a76ed18ca4f195c6a5b0ac277dfd0916657e047fea073db8e28bb59098bd8960c90efe8f59d6c275ff72d18b217d225f6698e56c05e33734a0fd6ea570589"},{"other":"2a0fa7932768f0c316b478d15db556626def18462c3bee9446ff16c48fc43b6be1694a5783602b60250e33adc705b86fae7baa6b829146251995fd47980ce422","up":false,"one":"ed3a5d7602b59bd8709ef10cb84e4b5644a69490d1173a8b9135adba04b36c1fcd0f16543de39deff0e76d8314e6884ba939213f77abb8d50a68d030352cb495"},{"other":"c133cd3ee228f427410357f46752d33ecf302475314411772df3532669a8b220136c09f00717460c39bcea1058cb988dd223875ec991612876b400556f5937dd","one":"b440e8bc7d39b8cf9cca03b343c83ba8dd673062cead7bbfce6ed77ea16fa61f0b81df31fc418f4c133d1bb104939ac1b6e5f5a76fbcf50141a1ea33dfeb86e5","up":false},{"up":false,"one":"84379884f012e2cfc1f9838312640576c9ded01ca53cf8451f94915e6949f0084047a2555a5fef4d1b0eef62ad5504a34ff631fbb658b011a07a82a53173f5c1","other":"3bf838b4d29d9388a24d160eee6bf8ea017af6cd9e5f7d88b4cae71ebfbc304666d3d634a05e0a75570dafe8f41871090fcff8b651a9130d013786dfcca3da14"},{"other":"193ca2ef8a4ac98c0300d7e48421ba3fe5d4789a0c2b476499bd093808c3988b4a55742ff3f607429cafda08cbbb5fba68da8869747b1b5169f3e4545497de3a","up":false,"one":"af761f8d13059f1e49d2f5c0b7a76a5eb5bcaab1e7ff01673dff3967d81bd7aebf74afef3934328034c82f131fa066de71816cff8f720e0c56d5e85b233a8a44"},{"one":"ad177f2702ed11d531b11fd0250f2dab2364624680cfb6ff1fba5b27dcd8334269a5bc9093401389044c0b00ed0cbf6f166aba81a58cadd34b25355839fff6ac","up":false,"other":"854ff45571c01cd49d0932bcb361eef13202ababf48f0b8e5d8143dc41e01609aa1539e926bad9b4ca8add023fd259eb70239103d75b0a404bb338f3e4bf9577"},{"up":false,"one":"11170a0fb9f6b037f8ee4494e935a84b06816ff5c44ef9d613920f9c58f8b25611b2093da3fb51a59687db6a9b0a070386cac09757a27f75754cbdcb9afc2225","other":"f78ecf420b73cd0245807157c0cbaaa568c60c80965413e187b084fb26041761d12790c0cb6a39bc8997fd2b3d3f52c831e601f1f1846945fba1808b0e1cdf25"},{"one":"ab3a3ad0481a80b91132cc6afeaab9c9f5e931885d979176e8e6c181d997c38b488e5eca475b0f8e949a8cf128695e18a5851091394d0a33cf834ce7e3537ac2","up":false,"other":"c7566a0efd78ba35ad27a51a7ec8fcd55944ae12f9933573e71e2ad7404d48037dad9063c10ce5af636d7641a03899333d01aa9be94716d2179fdb2af33f36c4"},{"other":"de7ab7b9a2ba4ed523b84233fae11d93815579976ea78b385c658a4c156622747051f91342f9ac3610e22ee259b65e02b5af0ab67a9ee04ab6958a9d0d8acdf1","one":"af761f8d13059f1e49d2f5c0b7a76a5eb5bcaab1e7ff01673dff3967d81bd7aebf74afef3934328034c82f131fa066de71816cff8f720e0c56d5e85b233a8a44","up":false},{"other":"9b3fecfc63256a9d69e75ccb5119b2866e30fa4516b3a3bf5b2f03f04f1d20de786ddb90fa2acadb2a0509503b21fc9d16238c57f9b102ceedb6b27ee1b2c4ea","up":false,"one":"6070dc131e9721a4a496b3ed6ff5c9db1a5351e942ed424b86fe6be940d1012df766afb4b0112452dfd63e0fcfea13658324a9ef4a94b5754ec9f6219e4b0d67"},{"up":false,"one":"a1b07c24605e258db7b8fb15db227596b08dc69bb234c0a48c312eb6eb1fb08553f8c8a6da7175eea258e2d3f2625a540c1466e6c31315aa1484fa173b7a8cfc","other":"a5990a680e1f01dcd71a178a239880c5ce24418748c368b8e3c8a1175cfd744d16973cba03e5e756820950920a6d9fa5d5dd53829a1d1d508371cb1042e9453e"},{"one":"57fb9e7f287fe67500b8b560475c0d0d6eae9d623d5a8c85eb5459f209904a839a0b24ff99a1643a4196a71d45f2ed1bd5e08f9a13cdd9749a907a024ff984dc","up":false,"other":"53031cddf4390ba176d638456016028bd4538879c7eaba672c3ef70208319a14e6a41dea8ff003b6f7e9b4a83ca12dab50d4f44f079153bec7c24221e311573e"},{"other":"ed3a5d7602b59bd8709ef10cb84e4b5644a69490d1173a8b9135adba04b36c1fcd0f16543de39deff0e76d8314e6884ba939213f77abb8d50a68d030352cb495","up":false,"one":"d6794744c5f941cb6dbac4adbbbf11ce83c9224c8a34b9c787ed5975bf0af13e095a7db1c86fcbb7b134ae6dc67467d3ffaf191f4a4d9218779c4d0cf86876ca"},{"one":"ef3016ea5a7b1b57388904d5c80fd05780d23acec8cf73e8add28ea99c6222fa84e89a1752186a2ef41dd0ec828405e61a1e8fd67d9496d75525ed860b12e2e8","up":false,"other":"c49e963a92b93a1c48fd3e38c127bfc88fbcb15b57bfdf8615c0e591b24276d4fe153a811932aefdcf3dee494d53ce354ba052c24313a725d562c6e807ab9133"},{"up":false,"one":"a5990a680e1f01dcd71a178a239880c5ce24418748c368b8e3c8a1175cfd744d16973cba03e5e756820950920a6d9fa5d5dd53829a1d1d508371cb1042e9453e","other":"9ad5ec0e729f9db10b7028788b58ef13d54bd11529b494a549d0415b90777b63fe78a752356315f5abbd24d849edc0c8bfe9d82c05460c30f4dad860ff5fea48"},{"up":false,"one":"a5990a680e1f01dcd71a178a239880c5ce24418748c368b8e3c8a1175cfd744d16973cba03e5e756820950920a6d9fa5d5dd53829a1d1d508371cb1042e9453e","other":"9158b9eb87bf7d011f83febca8f9d6575dd05be1f7e7bc18336f802651a379dd181a0503b5a8e46a580c59889998b16275f1e0ce4dce965cdbe72265ad2be283"},{"up":false,"one":"3db9984cb1e25bdc30c483f3d4c036fb1728bafffecd2b965af7e701569c28116dbed2e5892504ea9927c14570351b03cb99112a5924a27e6e03289422785c7b","other":"b1bef03357528618be6936a7edae5e3d4ecc942d43bd301642d321a73a07f3327d413f923c3fdd49d04f311e18709a4dde7519722d7a4912f181aa4df2e60173"},{"one":"8b8c15c6329096267a25d4060ee19963afb6e776fea60d9d566d4e1f9b087581b36e33fc533d7f133668a7a6a22f81a1234ed9fbce26eff1d5e5691a6148d540","up":false,"other":"f8fd12d8b5872b74e2cfa60d6a3a25b568a1fb4be3a8d06faac02a38321f419c443e517c0e2989001635f827add1859a2dc9589a9c0f5bf3804d46f43f799116"},{"other":"5c1e9692b731421d6eaca488e8ba4cfdda1933ac5f1504ece684fadbea07a7c8053feb73be7ce20aedeaecc84f14d836b5ed2a657df6ca04f4fc82c2da0c0d46","one":"ef3016ea5a7b1b57388904d5c80fd05780d23acec8cf73e8add28ea99c6222fa84e89a1752186a2ef41dd0ec828405e61a1e8fd67d9496d75525ed860b12e2e8","up":false},{"one":"b949f482891fff7d7d1f0d84112db7080fa1df07cd4e52ee0fadb707a4b7903fc0da9fe45b7ceee37948856687f8e7768945295de15691a99c879f1816899d98","up":false,"other":"c708e3584cd9450b30d8cdd960a676884f64364c2aec985eebb4a0d745f6c73b6b0cb16f330bf090320bc48a5a67e8519b3c2c4a64cf2eff9aa4f1fc0b274a00"},{"one":"fb20c708420e60c48fa65980ae11adc8cdf9b56ab93044a9aee9b5196d52f29e6cb2c218f73fefbdaecf8177bae1d9d13dd64bbe06e631555715b93f58f47137","up":false,"other":"255939ef32bd3e5e76181763c11707b9ff4ab26d3ffb10f06fa7249b06721fa3decfa9eee3eeb8b12d6218af5f9ed8872d62c42a90cd46dcbef3d89a8163ae07"},{"other":"2396833be485e50b230a07fddff7f24e11e3fdee3f08f11a287faa2b03b26451b9f4fd24ddefdec62917ae59b6fa56a75e7d6e078b411d624704b88f841b9960","one":"4228ad29aa22f1fa078c7e09f44f85c05d5b797072c10ade24dcbff95c01e554511fe10273a5f25a25ca06ff97bca28c241610f7145983f72ed44969ead4596a","up":false},{"other":"604a11bd1d969886953398ecc1fdf5847a946a8118014d0cb8daff9943f4f78c4bdbad3ee4152959c8265d0588dea658c262fe2f99a55a0b32321b81c8eec473","one":"b949f482891fff7d7d1f0d84112db7080fa1df07cd4e52ee0fadb707a4b7903fc0da9fe45b7ceee37948856687f8e7768945295de15691a99c879f1816899d98","up":false},{"one":"11170a0fb9f6b037f8ee4494e935a84b06816ff5c44ef9d613920f9c58f8b25611b2093da3fb51a59687db6a9b0a070386cac09757a27f75754cbdcb9afc2225","up":false,"other":"c796d4917dd22d9836a9d7d24ba6f89e1a0e8a78a207bd930991e44e9c80ac1de8e4e1a023d550a6dfa60270fbb3935a7e03ef389c1ccda957a4a6a75ef6819b"},{"other":"071c094246a0ca4b5d169e43a20ce5da508e579a6e2e822462bd8948ab357d46ab477bcff0c80eba2e01f0c100690b307af40d47c52ebad06783e9e77466cbd6","one":"c677530a47ef470ae0811127b91c231ec8889588bd096c24a54cc48099e8edde811f4a72eedc79118acb494ef031d6adcef1595d1a17df71b25b468478e931ff","up":false},{"one":"bebbde654a4f3e3e65f63d10cbcc89dfd46ce75945c19be33bfe4d954c8ed375981e21a8376ad10e402dddbcf3b657e6786c0820e599a0d1fe03f8d35294d7c7","up":false,"other":"e3779b202b9cfe7b2f2cc9e95974ac77bf51ba951f775acc10f07249ee6b3b260f2b012bb010a7f9794c5562e9b00f18b52c25c1e350ab70afc6bf9e210e4969"},{"other":"57fb9e7f287fe67500b8b560475c0d0d6eae9d623d5a8c85eb5459f209904a839a0b24ff99a1643a4196a71d45f2ed1bd5e08f9a13cdd9749a907a024ff984dc","up":false,"one":"c677530a47ef470ae0811127b91c231ec8889588bd096c24a54cc48099e8edde811f4a72eedc79118acb494ef031d6adcef1595d1a17df71b25b468478e931ff"},{"one":"972b7f6c5b926b93a9b005bb8a891c29e535a465c586bcd4258d4094e320925a179e8f63478917f8a88d1911fe8f868013abeb34817832ed4b0b209ce392f20b","up":false,"other":"3db9984cb1e25bdc30c483f3d4c036fb1728bafffecd2b965af7e701569c28116dbed2e5892504ea9927c14570351b03cb99112a5924a27e6e03289422785c7b"},{"up":false,"one":"236266f9f5a28148d11bed1195a91cd1d30231b082697ee1940a85abca98d2ff0767be9128c23375caa0444bcf51d8501879200ea0f27f13d0ede37f97241325","other":"193ca2ef8a4ac98c0300d7e48421ba3fe5d4789a0c2b476499bd093808c3988b4a55742ff3f607429cafda08cbbb5fba68da8869747b1b5169f3e4545497de3a"},{"other":"464cf4c4203246240a63965062b9e5a7e5fa903f127b1f5ea5b37a27d33d8b12768fc2d8f257e67418f1e5765e627ca8f8cd5ba6b15b8a047490d26ce43e6291","up":false,"one":"d6794744c5f941cb6dbac4adbbbf11ce83c9224c8a34b9c787ed5975bf0af13e095a7db1c86fcbb7b134ae6dc67467d3ffaf191f4a4d9218779c4d0cf86876ca"},{"other":"604a11bd1d969886953398ecc1fdf5847a946a8118014d0cb8daff9943f4f78c4bdbad3ee4152959c8265d0588dea658c262fe2f99a55a0b32321b81c8eec473","up":false,"one":"a5990a680e1f01dcd71a178a239880c5ce24418748c368b8e3c8a1175cfd744d16973cba03e5e756820950920a6d9fa5d5dd53829a1d1d508371cb1042e9453e"},{"other":"f78ecf420b73cd0245807157c0cbaaa568c60c80965413e187b084fb26041761d12790c0cb6a39bc8997fd2b3d3f52c831e601f1f1846945fba1808b0e1cdf25","one":"8b8c15c6329096267a25d4060ee19963afb6e776fea60d9d566d4e1f9b087581b36e33fc533d7f133668a7a6a22f81a1234ed9fbce26eff1d5e5691a6148d540","up":false},{"one":"a13086041114db2be31038987ac3fdcaeb99489f1b6ee9b22998b9e66dc2f2f024307d9474811e7e8be1b1acf5a55305d5cce27d87fb834ed1e1d2e17319bb85","up":false,"other":"49bd2289f479c9ad7e0d13319271b9be1e1dcbee28313513a124dec55f9842db639e62a74a83040930c537739ab7fa1e50bb05b9ab0f588d6da7b64a6451f466"},{"up":false,"one":"b949f482891fff7d7d1f0d84112db7080fa1df07cd4e52ee0fadb707a4b7903fc0da9fe45b7ceee37948856687f8e7768945295de15691a99c879f1816899d98","other":"9ad5ec0e729f9db10b7028788b58ef13d54bd11529b494a549d0415b90777b63fe78a752356315f5abbd24d849edc0c8bfe9d82c05460c30f4dad860ff5fea48"},{"up":false,"one":"54b79d3662ba486bbd120313d59ef101acf963eb3d6112a9dda121bc0b52f4b1fbcb13406705cdd8c2d3990ad296171c7972211467cc0d44cbe9ca16fbc82e3e","other":"0bf28b481d71062ee100d6cb04c8b4234a574f8657e2d3c49b60a9ecdbf486d0ec38b33bce745c8efe820145d5c53ea802aa64b4f9bce19b029ee5b2f9de43f1"},{"other":"84379884f012e2cfc1f9838312640576c9ded01ca53cf8451f94915e6949f0084047a2555a5fef4d1b0eef62ad5504a34ff631fbb658b011a07a82a53173f5c1","one":"236266f9f5a28148d11bed1195a91cd1d30231b082697ee1940a85abca98d2ff0767be9128c23375caa0444bcf51d8501879200ea0f27f13d0ede37f97241325","up":false},{"up":false,"one":"c7566a0efd78ba35ad27a51a7ec8fcd55944ae12f9933573e71e2ad7404d48037dad9063c10ce5af636d7641a03899333d01aa9be94716d2179fdb2af33f36c4","other":"e20a90f36eca4329d3d2dbadf530949889dc20b0ae5d96b935af9b60d26ec507e9eb1b73fd2b4dc88057c20e4ef6e7039cc49652d35c563db64f06f979e28540"},{"one":"c677530a47ef470ae0811127b91c231ec8889588bd096c24a54cc48099e8edde811f4a72eedc79118acb494ef031d6adcef1595d1a17df71b25b468478e931ff","up":false,"other":"bebbde654a4f3e3e65f63d10cbcc89dfd46ce75945c19be33bfe4d954c8ed375981e21a8376ad10e402dddbcf3b657e6786c0820e599a0d1fe03f8d35294d7c7"},{"other":"f78ecf420b73cd0245807157c0cbaaa568c60c80965413e187b084fb26041761d12790c0cb6a39bc8997fd2b3d3f52c831e601f1f1846945fba1808b0e1cdf25","one":"5a27b90639d515cad7794dae78bf9a9866cca23c5e3e18870524d148797ba1bdfd631151f23062d4dcf0961a7dba709431a44e39da29ed5ea4b0b6987514e433","up":false},{"one":"54b79d3662ba486bbd120313d59ef101acf963eb3d6112a9dda121bc0b52f4b1fbcb13406705cdd8c2d3990ad296171c7972211467cc0d44cbe9ca16fbc82e3e","up":false,"other":"49bd2289f479c9ad7e0d13319271b9be1e1dcbee28313513a124dec55f9842db639e62a74a83040930c537739ab7fa1e50bb05b9ab0f588d6da7b64a6451f466"},{"one":"c7566a0efd78ba35ad27a51a7ec8fcd55944ae12f9933573e71e2ad7404d48037dad9063c10ce5af636d7641a03899333d01aa9be94716d2179fdb2af33f36c4","up":false,"other":"59fe05843cc637adac3728acb8ca9650f49050095cf5d32241366f54d4ac7179b16dcb009e2fb9fa9499cc6f8b865b6c4d6fe6e35500df10ba5daa719d57976e"},{"one":"255939ef32bd3e5e76181763c11707b9ff4ab26d3ffb10f06fa7249b06721fa3decfa9eee3eeb8b12d6218af5f9ed8872d62c42a90cd46dcbef3d89a8163ae07","up":false,"other":"b737c81fe6bc50d977231a5fc8856f064ba58190c5ab5615d3cf634aea8c15a308f3a667aad2e69d5c1438549cd41c863fd40f643b70caf3e0c934276ef2a84f"},{"one":"96f3194c9ef17f60c318be14dd72c51af0aebc19f7a574b769d18b1fda6791409c827892bae3a061800e3d78af88a97635a0a892c54d7ebb38342ab1ba99c3ad","up":false,"other":"9b3fecfc63256a9d69e75ccb5119b2866e30fa4516b3a3bf5b2f03f04f1d20de786ddb90fa2acadb2a0509503b21fc9d16238c57f9b102ceedb6b27ee1b2c4ea"},{"other":"0d85f39dca79f99b277ad5cedfcd3fb1eccc7862c95c215ba0d5a2ec1c4fa80244393d0934cf59fe988f7716bf15cb8e79f4ee03fbe4a48a10cac6e0610f9d55","up":false,"one":"3e65bbf7103b3307bd9b8a65168c7c87c3f5283c7c52edefabf4193a1f04ac10216cc485a1dae17cff9ccea41bcf9a0b41de001c6142f30701443dc1735f25c0"},{"up":false,"one":"3e65bbf7103b3307bd9b8a65168c7c87c3f5283c7c52edefabf4193a1f04ac10216cc485a1dae17cff9ccea41bcf9a0b41de001c6142f30701443dc1735f25c0","other":"b949f482891fff7d7d1f0d84112db7080fa1df07cd4e52ee0fadb707a4b7903fc0da9fe45b7ceee37948856687f8e7768945295de15691a99c879f1816899d98"},{"up":false,"one":"f78ecf420b73cd0245807157c0cbaaa568c60c80965413e187b084fb26041761d12790c0cb6a39bc8997fd2b3d3f52c831e601f1f1846945fba1808b0e1cdf25","other":"a089758c25ca0730f13cd18c10aeea62488c1c2651eef53a8ad11cfdfa61ce8f7354a53bd6902da26b79dfbedc78d315b1d4239eb62cbca59215727b2ac35213"},{"other":"d33f82b6a46535e798b78ebb28047ece1ef3b696ab29726d283161c377ed17a735a0948b99d83dee2af71704001e2e13813854a1b0ef4fcefd3c0e5c5f6e720d","one":"54b79d3662ba486bbd120313d59ef101acf963eb3d6112a9dda121bc0b52f4b1fbcb13406705cdd8c2d3990ad296171c7972211467cc0d44cbe9ca16fbc82e3e","up":false},{"one":"2396833be485e50b230a07fddff7f24e11e3fdee3f08f11a287faa2b03b26451b9f4fd24ddefdec62917ae59b6fa56a75e7d6e078b411d624704b88f841b9960","up":false,"other":"7625a1a0a0f5bf78e2b9fe43a1215ea882318458b886ec767ccbc35e76b543f96820b364342b28ff600302af7716280497141dc2fc84e83cb15f5eb3d268d73e"},{"up":false,"one":"7625a1a0a0f5bf78e2b9fe43a1215ea882318458b886ec767ccbc35e76b543f96820b364342b28ff600302af7716280497141dc2fc84e83cb15f5eb3d268d73e","other":"f2ac738fa932c90a45d1a64e4a52fd9c4037e2d89ceef1584efef04689bc7aff3a9635fb78dfdf3480d003daf14359190b1cfa8335db438a54107d4060ed58f9"},{"up":false,"one":"ab3a3ad0481a80b91132cc6afeaab9c9f5e931885d979176e8e6c181d997c38b488e5eca475b0f8e949a8cf128695e18a5851091394d0a33cf834ce7e3537ac2","other":"f78ecf420b73cd0245807157c0cbaaa568c60c80965413e187b084fb26041761d12790c0cb6a39bc8997fd2b3d3f52c831e601f1f1846945fba1808b0e1cdf25"},{"up":false,"one":"f78ecf420b73cd0245807157c0cbaaa568c60c80965413e187b084fb26041761d12790c0cb6a39bc8997fd2b3d3f52c831e601f1f1846945fba1808b0e1cdf25","other":"c796d4917dd22d9836a9d7d24ba6f89e1a0e8a78a207bd930991e44e9c80ac1de8e4e1a023d550a6dfa60270fbb3935a7e03ef389c1ccda957a4a6a75ef6819b"},{"one":"3e65bbf7103b3307bd9b8a65168c7c87c3f5283c7c52edefabf4193a1f04ac10216cc485a1dae17cff9ccea41bcf9a0b41de001c6142f30701443dc1735f25c0","up":false,"other":"334b59c2767fc786551dfdc0a9fcd6f5b53cbe48ddc1ca61b84f8155a15de7e8cd44cbb3a537e1aa7f11416eb710c5de916a5e8ce24e83bfa570b7344c5873ea"},{"other":"c4dfcf348694971fb36ed91e9024302bec8df3891540cbe1f5df26eee9c1f81a95295f05b90ec30dd044a0355dcaa805b9f50e95f38e5588a929cfe10e8cd73d","one":"c7566a0efd78ba35ad27a51a7ec8fcd55944ae12f9933573e71e2ad7404d48037dad9063c10ce5af636d7641a03899333d01aa9be94716d2179fdb2af33f36c4","up":false},{"up":false,"one":"8b8c15c6329096267a25d4060ee19963afb6e776fea60d9d566d4e1f9b087581b36e33fc533d7f133668a7a6a22f81a1234ed9fbce26eff1d5e5691a6148d540","other":"e20a90f36eca4329d3d2dbadf530949889dc20b0ae5d96b935af9b60d26ec507e9eb1b73fd2b4dc88057c20e4ef6e7039cc49652d35c563db64f06f979e28540"},{"other":"0bf28b481d71062ee100d6cb04c8b4234a574f8657e2d3c49b60a9ecdbf486d0ec38b33bce745c8efe820145d5c53ea802aa64b4f9bce19b029ee5b2f9de43f1","one":"a13086041114db2be31038987ac3fdcaeb99489f1b6ee9b22998b9e66dc2f2f024307d9474811e7e8be1b1acf5a55305d5cce27d87fb834ed1e1d2e17319bb85","up":false},{"up":false,"one":"b949f482891fff7d7d1f0d84112db7080fa1df07cd4e52ee0fadb707a4b7903fc0da9fe45b7ceee37948856687f8e7768945295de15691a99c879f1816899d98","other":"aa108a30f86b8296b416ea9fd6bc7a21c65c7cd3911ca3d4ee79325912d80db7150c02d304e49c5d0feafbd222edd6d522661a0983f1d427981760712f31e6f1"},{"other":"0bf28b481d71062ee100d6cb04c8b4234a574f8657e2d3c49b60a9ecdbf486d0ec38b33bce745c8efe820145d5c53ea802aa64b4f9bce19b029ee5b2f9de43f1","up":false,"one":"d6794744c5f941cb6dbac4adbbbf11ce83c9224c8a34b9c787ed5975bf0af13e095a7db1c86fcbb7b134ae6dc67467d3ffaf191f4a4d9218779c4d0cf86876ca"},{"other":"850e729f9bbb5ef6e12baf7d3dced180839e88e0845baa7aa8fb87dcb417aa74af5999bda81723aabbef5eda842fa4b5fae107fcff9f6bd50597e8ba6a849dff","up":false,"one":"7ca32d24c001557a81af351ac71322543154eeedbb6ccdd8b8b142f19215aa712218babe9701e73a6441784375a511c1f16a70569b73416f9708409564d18485"},{"up":false,"one":"06a8a25c6dd90e230237b06c086f14e539b31b8e3705752d0ad8faf1bd7239547332604b79b6124cbd0cee495b99a80f147983142b7271841d8d9fa85d559301","other":"45c635c4080d47e2f932c27472e487ec95b7644c3d94d8627166a33dca2e3cbaa3305ae2d42e1510bfb0f8329b90e5a31883b399a469ad548fcae3040a8833a0"},{"one":"96f3194c9ef17f60c318be14dd72c51af0aebc19f7a574b769d18b1fda6791409c827892bae3a061800e3d78af88a97635a0a892c54d7ebb38342ab1ba99c3ad","up":false,"other":"cf03d32d3cca446e7016e7f41267a257bef7142c4f1e4ce2e17678856d75e9889e21972fd21583297a47a156543af15400444dcf37aca64543f97f73734f7f0f"},{"one":"d6794744c5f941cb6dbac4adbbbf11ce83c9224c8a34b9c787ed5975bf0af13e095a7db1c86fcbb7b134ae6dc67467d3ffaf191f4a4d9218779c4d0cf86876ca","up":false,"other":"334b59c2767fc786551dfdc0a9fcd6f5b53cbe48ddc1ca61b84f8155a15de7e8cd44cbb3a537e1aa7f11416eb710c5de916a5e8ce24e83bfa570b7344c5873ea"},{"one":"3e65bbf7103b3307bd9b8a65168c7c87c3f5283c7c52edefabf4193a1f04ac10216cc485a1dae17cff9ccea41bcf9a0b41de001c6142f30701443dc1735f25c0","up":false,"other":"fd321c630fadcc8d6b00589323f7313ac1e94effbe8192955da5f88dcf419ef28820075e0e81c595561ff6ee58cfce23079407edf8b1611cb994946bcbd26364"},{"other":"a2719942ffb6e99bda131cdedb612785dafdf72f5f35824343ad39d8568d6cd25e44b585a915c8e9ea2b02e6fd38c105bb17ed27c8fa320f18c83e0ace78feb5","one":"7ca32d24c001557a81af351ac71322543154eeedbb6ccdd8b8b142f19215aa712218babe9701e73a6441784375a511c1f16a70569b73416f9708409564d18485","up":false},{"other":"faa3c31521c8f7b9d15838750e7e311eb0f01db5ef22cd1bf62a7d72e7efdf5a575550c930d96230edc892d107d4551e95b099d3c952a7f1c0ad3b5967c7831b","up":false,"one":"3e65bbf7103b3307bd9b8a65168c7c87c3f5283c7c52edefabf4193a1f04ac10216cc485a1dae17cff9ccea41bcf9a0b41de001c6142f30701443dc1735f25c0"},{"other":"a4dd67ab4fff1a50968c7ab59c304eb0083b072fc13dff599eeadac4e0e75099f7c825f91dd1bb770f3ae6f3d1d82ad574d6ecb117adf1ca9ccbccd01303ec7c","up":false,"one":"255939ef32bd3e5e76181763c11707b9ff4ab26d3ffb10f06fa7249b06721fa3decfa9eee3eeb8b12d6218af5f9ed8872d62c42a90cd46dcbef3d89a8163ae07"},{"other":"ed3a5d7602b59bd8709ef10cb84e4b5644a69490d1173a8b9135adba04b36c1fcd0f16543de39deff0e76d8314e6884ba939213f77abb8d50a68d030352cb495","one":"7ca32d24c001557a81af351ac71322543154eeedbb6ccdd8b8b142f19215aa712218babe9701e73a6441784375a511c1f16a70569b73416f9708409564d18485","up":false},{"other":"fd321c630fadcc8d6b00589323f7313ac1e94effbe8192955da5f88dcf419ef28820075e0e81c595561ff6ee58cfce23079407edf8b1611cb994946bcbd26364","up":false,"one":"d6794744c5f941cb6dbac4adbbbf11ce83c9224c8a34b9c787ed5975bf0af13e095a7db1c86fcbb7b134ae6dc67467d3ffaf191f4a4d9218779c4d0cf86876ca"},{"one":"3e65bbf7103b3307bd9b8a65168c7c87c3f5283c7c52edefabf4193a1f04ac10216cc485a1dae17cff9ccea41bcf9a0b41de001c6142f30701443dc1735f25c0","up":false,"other":"ed3a5d7602b59bd8709ef10cb84e4b5644a69490d1173a8b9135adba04b36c1fcd0f16543de39deff0e76d8314e6884ba939213f77abb8d50a68d030352cb495"},{"other":"223d79f656e3f124ee1238ca46e42c2a0d8500ee58a37312c6b72657a11ad9ebce3be4c061611b913a22863f6e7936ff37602dedc7856baea27e8201db44bbf4","one":"06a8a25c6dd90e230237b06c086f14e539b31b8e3705752d0ad8faf1bd7239547332604b79b6124cbd0cee495b99a80f147983142b7271841d8d9fa85d559301","up":false}]} \ No newline at end of file diff --git a/swarm/pss/testdata/snapshot_16.json b/swarm/pss/testdata/snapshot_16.json new file mode 100644 index 0000000000..648323d365 --- /dev/null +++ b/swarm/pss/testdata/snapshot_16.json @@ -0,0 +1 @@ +{"nodes":[{"node":{"info":{"ip":"0.0.0.0","enode":"enode://cb93e548a2e9a8fbc7a1bd50e0b0a3ad76b94265a454cd5c39fe091a55ad18172ef4d0ac2e776410f892cb1f3d9c17f35e01a798095271abd3566ee0fb3fe5ec@0.0.0.0:0","name":"node01","id":"cb93e548a2e9a8fbc7a1bd50e0b0a3ad76b94265a454cd5c39fe091a55ad18172ef4d0ac2e776410f892cb1f3d9c17f35e01a798095271abd3566ee0fb3fe5ec","protocols":{"hive":"\n=========================================================================\nFri Sep 29 14:02:31 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 886216\npopulation: 4 (15), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 55ce | 7 1ffd (0) 6629 (0) 69d3 (0) 6e8c (0)\n001 1 d9b0 | 6 c0f2 (0) c7a2 (0) c651 (0) c553 (0)\n002 0 | 0\n============ DEPTH: 3 ==========================================\n003 1 9cd2 | 1 9cd2 (0)\n004 0 | 0\n005 1 8c92 | 1 8c92 (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"iGIWELX9vz5YRyTiJook3EFWLaXNupI1e5ftxC157E4="},"ports":{"listener":0,"discovery":0},"listenAddr":""},"up":true,"config":{"name":"node01","id":"cb93e548a2e9a8fbc7a1bd50e0b0a3ad76b94265a454cd5c39fe091a55ad18172ef4d0ac2e776410f892cb1f3d9c17f35e01a798095271abd3566ee0fb3fe5ec","private_key":"2c268d9cf0ca43f4b0ad80f8980f4fe019e0294819f881d505e02382b472b98b","services":["pss","bzz"]}}},{"node":{"config":{"services":["pss","bzz"],"name":"node02","private_key":"69ac59cce230e49f10c769fc8f2b717bdadc5ffa5dcf7fae19d8cb15315fa177","id":"4d2e2c62a6b05e450a2b32598b20d906d99ab7ce14c6c005990249de3acd7731ae423c03e8e9326f7a6ea4ba6aa00714dc5d434caa00e8d4b59e1619f54cbeb9"},"up":true,"info":{"name":"node02","id":"4d2e2c62a6b05e450a2b32598b20d906d99ab7ce14c6c005990249de3acd7731ae423c03e8e9326f7a6ea4ba6aa00714dc5d434caa00e8d4b59e1619f54cbeb9","ip":"0.0.0.0","enode":"enode://4d2e2c62a6b05e450a2b32598b20d906d99ab7ce14c6c005990249de3acd7731ae423c03e8e9326f7a6ea4ba6aa00714dc5d434caa00e8d4b59e1619f54cbeb9@0.0.0.0:0","listenAddr":"","ports":{"listener":0,"discovery":0},"protocols":{"bzz":"2bC1eiN6g4bPbPYRd52N8/Ww+cAXGelyMMOyO/CrBK4=","hive":"\n=========================================================================\nFri Sep 29 14:02:31 UTC 2017 KΛÐΞMLIΛ hive: queen's address: d9b0b5\npopulation: 7 (13), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 55ce | 5 55ce (0) 6629 (0) 69d3 (0) 6e8c (0)\n001 1 8862 | 3 9cd2 (0) 8c92 (0) 8862 (0)\n002 0 | 0\n============ DEPTH: 3 ==========================================\n003 4 c0f2 c7a2 c651 c553 | 4 c0f2 (0) c7a2 (0) c651 (0) c553 (0)\n004 1 d33e | 1 d33e (0)\n005 0 | 0\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}}}},{"node":{"config":{"services":["pss","bzz"],"private_key":"b793f9ace49ecce16c0c86b49495093f7f4c5fa0003675c9eb6efa802c8daafe","name":"node03","id":"513402ffa5f5cf96c617821045604efef0a833b99c1a600dad2d88202823bfcd89d65ea143e36e18f41d77d73b3ecc853cbf23e122a85c34bc416b16f3cc6f1d"},"info":{"ports":{"discovery":0,"listener":0},"protocols":{"hive":"\n=========================================================================\nFri Sep 29 14:02:31 UTC 2017 KΛÐΞMLIΛ hive: queen's address: c553ca\npopulation: 7 (14), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 5989 | 7 4b6e (0) 5989 (0) 55ce (0) 6629 (0)\n001 1 9cd2 | 2 8c92 (0) 9cd2 (0)\n002 0 | 0\n003 2 d33e d9b0 | 2 d33e (0) d9b0 (0)\n004 0 | 0\n005 1 c0f2 | 1 c0f2 (0)\n============ DEPTH: 6 ==========================================\n006 2 c7a2 c651 | 2 c7a2 (0) c651 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"xVPKILT38bHjtxsmGCnCfrHP5nEKoJmfZVpCZw5tiBM="},"listenAddr":"","enode":"enode://513402ffa5f5cf96c617821045604efef0a833b99c1a600dad2d88202823bfcd89d65ea143e36e18f41d77d73b3ecc853cbf23e122a85c34bc416b16f3cc6f1d@0.0.0.0:0","ip":"0.0.0.0","id":"513402ffa5f5cf96c617821045604efef0a833b99c1a600dad2d88202823bfcd89d65ea143e36e18f41d77d73b3ecc853cbf23e122a85c34bc416b16f3cc6f1d","name":"node03"},"up":true}},{"node":{"info":{"ip":"0.0.0.0","enode":"enode://98fc9aba8502649019d30ccbc48c23a32b15f04584254c614e37fdc082fb8763727b47d8bb4333d629556698153f482b4ad68447eb08e6808177616071f7c133@0.0.0.0:0","id":"98fc9aba8502649019d30ccbc48c23a32b15f04584254c614e37fdc082fb8763727b47d8bb4333d629556698153f482b4ad68447eb08e6808177616071f7c133","name":"node04","protocols":{"bzz":"xlGgyST8AenWzTCrpoZM2TYx1dTiHO7afbGSLxBcXKg=","hive":"\n=========================================================================\nFri Sep 29 14:02:31 UTC 2017 KΛÐΞMLIΛ hive: queen's address: c651a0\npopulation: 7 (14), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 4b6e | 7 1ffd (0) 6629 (0) 69d3 (0) 6e8c (0)\n001 1 8c92 | 2 8c92 (0) 9cd2 (0)\n002 0 | 0\n003 2 d33e d9b0 | 2 d33e (0) d9b0 (0)\n004 0 | 0\n005 1 c0f2 | 1 c0f2 (0)\n============ DEPTH: 6 ==========================================\n006 1 c553 | 1 c553 (0)\n007 1 c7a2 | 1 c7a2 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"listener":0,"discovery":0},"listenAddr":""},"up":true,"config":{"services":["pss","bzz"],"id":"98fc9aba8502649019d30ccbc48c23a32b15f04584254c614e37fdc082fb8763727b47d8bb4333d629556698153f482b4ad68447eb08e6808177616071f7c133","name":"node04","private_key":"9fecef44b474621ce2ddd57cf67df319bd0e13c27f0f6e9d060c34ef813675ea"}}},{"node":{"config":{"services":["pss","bzz"],"name":"node05","id":"f11f84b0a5f8b98fa63fe142632b030def6aa9aaa456a8b08caf5e43183aeeb793708cea85a61f8107bd1761913232354ab18e5e68ac10ac81c4dd3d45650a0b","private_key":"c8f4336f88c90242744e9c04fba1a55027d9ad4295b7a2b0ad99e8dae12463d3"},"info":{"enode":"enode://f11f84b0a5f8b98fa63fe142632b030def6aa9aaa456a8b08caf5e43183aeeb793708cea85a61f8107bd1761913232354ab18e5e68ac10ac81c4dd3d45650a0b@0.0.0.0:0","ip":"0.0.0.0","id":"f11f84b0a5f8b98fa63fe142632b030def6aa9aaa456a8b08caf5e43183aeeb793708cea85a61f8107bd1761913232354ab18e5e68ac10ac81c4dd3d45650a0b","name":"node05","protocols":{"bzz":"S24GjoT+zeK7akhpgjPwwq5eZrFai60uC11JnDHUi5g=","hive":"\n=========================================================================\nFri Sep 29 14:02:31 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 4b6e06\npopulation: 6 (14), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 c651 | 8 8c92 (0) 9cd2 (0) d33e (0) d9b0 (0)\n001 1 1ffd | 1 1ffd (0)\n002 2 6e8c 6629 | 3 69d3 (0) 6e8c (0) 6629 (0)\n============ DEPTH: 3 ==========================================\n003 2 5989 55ce | 2 5989 (0) 55ce (0)\n004 0 | 0\n005 0 | 0\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"listener":0,"discovery":0},"listenAddr":""},"up":true}},{"node":{"info":{"protocols":{"hive":"\n=========================================================================\nFri Sep 29 14:02:31 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 6629ec\npopulation: 5 (15), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 9cd2 | 9 8862 (0) 8c92 (0) 9cd2 (0) d33e (0)\n001 1 1ffd | 1 1ffd (0)\n002 1 4b6e | 3 5989 (0) 55ce (0) 4b6e (0)\n003 0 | 0\n============ DEPTH: 4 ==========================================\n004 2 69d3 6e8c | 2 69d3 (0) 6e8c (0)\n005 0 | 0\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"ZinshnIpsoIhphGOsOCXhh63hLYkV49Vw4Ec31Amwcc="},"ports":{"listener":0,"discovery":0},"listenAddr":"","ip":"0.0.0.0","enode":"enode://2834f6d1f53d4464db7cd5985cf9a77c041f0a5e4b5b8133edc7a038e24790a6029c581e47378fdd4ea692bb94b6a50a7a1f90b9a7bb5ba2a1ef633666eb518c@0.0.0.0:0","name":"node06","id":"2834f6d1f53d4464db7cd5985cf9a77c041f0a5e4b5b8133edc7a038e24790a6029c581e47378fdd4ea692bb94b6a50a7a1f90b9a7bb5ba2a1ef633666eb518c"},"up":true,"config":{"services":["pss","bzz"],"id":"2834f6d1f53d4464db7cd5985cf9a77c041f0a5e4b5b8133edc7a038e24790a6029c581e47378fdd4ea692bb94b6a50a7a1f90b9a7bb5ba2a1ef633666eb518c","name":"node06","private_key":"0ca52c3e4781fc413a13448abaae042dae52e2bab5772c52440bc4b2c6a5bda3"}}},{"node":{"config":{"private_key":"447c97a6c211160f0fb7990812c637bd346003a484cf05c3d92816007ab3745a","name":"node07","id":"a98d185ced8f60d06a0f9288cbd7704e7a19ce0a874c01c9d7258a7033b3608627e3f9a8e776d8173d9de519fcc476221e14546be8fe385854dfa1158af8e05b","services":["pss","bzz"]},"info":{"listenAddr":"","ports":{"discovery":0,"listener":0},"protocols":{"hive":"\n=========================================================================\nFri Sep 29 14:02:31 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 9cd2b6\npopulation: 7 (15), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 1ffd 6629 | 7 1ffd (0) 5989 (0) 55ce (0) 4b6e (0)\n001 3 c7a2 c553 c0f2 | 6 d9b0 (0) d33e (0) c553 (0) c651 (0)\n002 0 | 0\n============ DEPTH: 3 ==========================================\n003 2 8862 8c92 | 2 8862 (0) 8c92 (0)\n004 0 | 0\n005 0 | 0\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"nNK2sX0pVMCg1KNAcHxxIVoIw8J7W1spTpatICY7pgA="},"id":"a98d185ced8f60d06a0f9288cbd7704e7a19ce0a874c01c9d7258a7033b3608627e3f9a8e776d8173d9de519fcc476221e14546be8fe385854dfa1158af8e05b","name":"node07","enode":"enode://a98d185ced8f60d06a0f9288cbd7704e7a19ce0a874c01c9d7258a7033b3608627e3f9a8e776d8173d9de519fcc476221e14546be8fe385854dfa1158af8e05b@0.0.0.0:0","ip":"0.0.0.0"},"up":true}},{"node":{"up":true,"info":{"ip":"0.0.0.0","enode":"enode://7b6793c9167c491051fb2a64560c57e464cfd8cc76ac31d788a0d4101cafbb0e07b1b373af80a30d11f8fb3d356405b100615c9741b6b210572daacfeb44dce8@0.0.0.0:0","id":"7b6793c9167c491051fb2a64560c57e464cfd8cc76ac31d788a0d4101cafbb0e07b1b373af80a30d11f8fb3d356405b100615c9741b6b210572daacfeb44dce8","name":"node08","ports":{"listener":0,"discovery":0},"protocols":{"hive":"\n=========================================================================\nFri Sep 29 14:02:31 UTC 2017 KΛÐΞMLIΛ hive: queen's address: c0f23d\npopulation: 7 (15), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 69d3 | 7 1ffd (0) 5989 (0) 55ce (0) 4b6e (0)\n001 1 9cd2 | 3 8862 (0) 8c92 (0) 9cd2 (0)\n002 0 | 0\n003 2 d9b0 d33e | 2 d9b0 (0) d33e (0)\n004 0 | 0\n============ DEPTH: 5 ==========================================\n005 3 c553 c651 c7a2 | 3 c553 (0) c651 (0) c7a2 (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"wPI98lAYBF3cQDUmip50aPOG7K0wa57ZBTz2bi8asKI="},"listenAddr":""},"config":{"name":"node08","id":"7b6793c9167c491051fb2a64560c57e464cfd8cc76ac31d788a0d4101cafbb0e07b1b373af80a30d11f8fb3d356405b100615c9741b6b210572daacfeb44dce8","private_key":"8fa6ac35409a6df21ee32da8c36f61cd007a3515d23bb350351c263c241b851a","services":["pss","bzz"]}}},{"node":{"up":true,"info":{"id":"a43f3ae2ce8cf4ef456b4a644e66f76761c80e1174ba2d0551622d148f10389f88ee96375cde424d9c692a5f3d98fa2f534a0fb97265ad96f69b8a0341160a3e","name":"node09","enode":"enode://a43f3ae2ce8cf4ef456b4a644e66f76761c80e1174ba2d0551622d148f10389f88ee96375cde424d9c692a5f3d98fa2f534a0fb97265ad96f69b8a0341160a3e@0.0.0.0:0","ip":"0.0.0.0","listenAddr":"","protocols":{"hive":"\n=========================================================================\nFri Sep 29 14:02:31 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 69d329\npopulation: 6 (15), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 d33e c0f2 | 9 9cd2 (0) 8862 (0) 8c92 (0) d9b0 (0)\n001 1 1ffd | 1 1ffd (0)\n002 1 5989 | 3 5989 (0) 55ce (0) 4b6e (0)\n003 0 | 0\n============ DEPTH: 4 ==========================================\n004 1 6629 | 1 6629 (0)\n005 1 6e8c | 1 6e8c (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"adMphToGJNuhKUnmvn2wkxQ5dtml1RS4DXKpv3+8Vow="},"ports":{"discovery":0,"listener":0}},"config":{"services":["pss","bzz"],"private_key":"e4143bd79f4a55f463b623afc397fe0166a144f45c41fd8b58f816e208212819","name":"node09","id":"a43f3ae2ce8cf4ef456b4a644e66f76761c80e1174ba2d0551622d148f10389f88ee96375cde424d9c692a5f3d98fa2f534a0fb97265ad96f69b8a0341160a3e"}}},{"node":{"up":true,"info":{"enode":"enode://215d8dfa7a91ef2a7aa045a942f2a6b7669cd01c955f51311d120c9f595406506b288870ad526b09520165732585fa534da6564c2dba3920539d9eb9227a17bf@0.0.0.0:0","ip":"0.0.0.0","id":"215d8dfa7a91ef2a7aa045a942f2a6b7669cd01c955f51311d120c9f595406506b288870ad526b09520165732585fa534da6564c2dba3920539d9eb9227a17bf","name":"node10","ports":{"listener":0,"discovery":0},"protocols":{"bzz":"0z5OavW6E65EihakqBg6sQUPo/mDzb8D3sXCGl6d0UY=","hive":"\n=========================================================================\nFri Sep 29 14:02:31 UTC 2017 KΛÐΞMLIΛ hive: queen's address: d33e4e\npopulation: 8 (15), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 6e8c 69d3 | 7 1ffd (0) 5989 (0) 55ce (0) 4b6e (0)\n001 1 8c92 | 3 9cd2 (0) 8862 (0) 8c92 (0)\n002 0 | 0\n============ DEPTH: 3 ==========================================\n003 4 c0f2 c553 c651 c7a2 | 4 c0f2 (0) c553 (0) c651 (0) c7a2 (0)\n004 1 d9b0 | 1 d9b0 (0)\n005 0 | 0\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"listenAddr":""},"config":{"name":"node10","private_key":"6a2a32adb2b5cbc66adf29d5da1123b6e345e73ed42916e9535df3058801cb92","id":"215d8dfa7a91ef2a7aa045a942f2a6b7669cd01c955f51311d120c9f595406506b288870ad526b09520165732585fa534da6564c2dba3920539d9eb9227a17bf","services":["pss","bzz"]}}},{"node":{"config":{"services":["pss","bzz"],"id":"a40b5b386b40d526d936659aecdef3fd6879cba84f2dabdd49a51575ba69e907734b49fa7fb21560211739e6545c47e89de4140be8b5d6d6e4782fdb3b73b2a6","name":"node11","private_key":"ae486490233b1b16e6a35461a3b90573f59362b9bbf0b8c46b65c715b0506bd7"},"info":{"listenAddr":"","ports":{"listener":0,"discovery":0},"protocols":{"hive":"\n=========================================================================\nFri Sep 29 14:02:31 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 8c92cb\npopulation: 5 (15), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 5989 | 7 1ffd (0) 69d3 (0) 6e8c (0) 6629 (0)\n001 2 c651 d33e | 6 c0f2 (0) c553 (0) c651 (0) c7a2 (0)\n002 0 | 0\n============ DEPTH: 3 ==========================================\n003 1 9cd2 | 1 9cd2 (0)\n004 0 | 0\n005 1 8862 | 1 8862 (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"jJLLH82ltnpLkowgDi5eMkWZyZcgLZ6pj3AyOe4/w7E="},"id":"a40b5b386b40d526d936659aecdef3fd6879cba84f2dabdd49a51575ba69e907734b49fa7fb21560211739e6545c47e89de4140be8b5d6d6e4782fdb3b73b2a6","name":"node11","ip":"0.0.0.0","enode":"enode://a40b5b386b40d526d936659aecdef3fd6879cba84f2dabdd49a51575ba69e907734b49fa7fb21560211739e6545c47e89de4140be8b5d6d6e4782fdb3b73b2a6@0.0.0.0:0"},"up":true}},{"node":{"config":{"services":["pss","bzz"],"id":"cf7d4bd60822873944d2e23f5771b09d4af19320ab7595c08c22bf8ace89345e43b3eb39156005f3e6eabdae6187bc5744f44b14733e2340347451ca7debc111","name":"node12","private_key":"cbf9da4b4f44f44c0bcf69bb2134e33ddfdda7742d7f5609db74bdf4fb683cfb"},"up":true,"info":{"ports":{"listener":0,"discovery":0},"protocols":{"hive":"\n=========================================================================\nFri Sep 29 14:02:31 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 598949\npopulation: 8 (15), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 8c92 c553 c7a2 | 9 9cd2 (0) 8862 (0) 8c92 (0) d9b0 (0)\n001 1 1ffd | 1 1ffd (0)\n002 2 69d3 6e8c | 3 69d3 (0) 6e8c (0) 6629 (0)\n============ DEPTH: 3 ==========================================\n003 1 4b6e | 1 4b6e (0)\n004 1 55ce | 1 55ce (0)\n005 0 | 0\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"WYlJKycDM2tC9Zsr4WU6C8526AHvJiEh9iekdlga9eE="},"listenAddr":"","ip":"0.0.0.0","enode":"enode://cf7d4bd60822873944d2e23f5771b09d4af19320ab7595c08c22bf8ace89345e43b3eb39156005f3e6eabdae6187bc5744f44b14733e2340347451ca7debc111@0.0.0.0:0","name":"node12","id":"cf7d4bd60822873944d2e23f5771b09d4af19320ab7595c08c22bf8ace89345e43b3eb39156005f3e6eabdae6187bc5744f44b14733e2340347451ca7debc111"}}},{"node":{"config":{"services":["pss","bzz"],"name":"node13","id":"2b0a4930289eeb197a41ec935744e3c1adb23a9dbba23250750b3a66b53e609c4150227200f466c57c033968d842f23117eaaf3b071e2ba297f622444b2dc33a","private_key":"180ee0110d87d330dd416568e300cacfd4d52f8c08875ada1a6d5b4a11142b1d"},"info":{"ports":{"listener":0,"discovery":0},"protocols":{"bzz":"x6K/ZR9ZFJcWI1+nv7TO6DWqS91ALMq4xSlZqnTcavQ=","hive":"\n=========================================================================\nFri Sep 29 14:02:31 UTC 2017 KΛÐΞMLIΛ hive: queen's address: c7a2bf\npopulation: 8 (15), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 5989 6e8c | 7 1ffd (0) 4b6e (0) 55ce (0) 5989 (0)\n001 1 9cd2 | 3 9cd2 (0) 8862 (0) 8c92 (0)\n002 0 | 0\n003 2 d9b0 d33e | 2 d9b0 (0) d33e (0)\n004 0 | 0\n005 1 c0f2 | 1 c0f2 (0)\n============ DEPTH: 6 ==========================================\n006 1 c553 | 1 c553 (0)\n007 1 c651 | 1 c651 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"listenAddr":"","enode":"enode://2b0a4930289eeb197a41ec935744e3c1adb23a9dbba23250750b3a66b53e609c4150227200f466c57c033968d842f23117eaaf3b071e2ba297f622444b2dc33a@0.0.0.0:0","ip":"0.0.0.0","id":"2b0a4930289eeb197a41ec935744e3c1adb23a9dbba23250750b3a66b53e609c4150227200f466c57c033968d842f23117eaaf3b071e2ba297f622444b2dc33a","name":"node13"},"up":true}},{"node":{"config":{"id":"ad819270bb72e687a895d444374c65f9766e24177fd711de716437e17926dca4f79a9ee37ca3a507e1c28aaf3a90757bb04d956aa2b4e81d1391a73c1096864f","name":"node14","private_key":"d7a364b77d55a53453e94e10d235edf4ceb248653247bded6c1df31fc88ecbca","services":["pss","bzz"]},"info":{"enode":"enode://ad819270bb72e687a895d444374c65f9766e24177fd711de716437e17926dca4f79a9ee37ca3a507e1c28aaf3a90757bb04d956aa2b4e81d1391a73c1096864f@0.0.0.0:0","ip":"0.0.0.0","id":"ad819270bb72e687a895d444374c65f9766e24177fd711de716437e17926dca4f79a9ee37ca3a507e1c28aaf3a90757bb04d956aa2b4e81d1391a73c1096864f","name":"node14","ports":{"listener":0,"discovery":0},"protocols":{"hive":"\n=========================================================================\nFri Sep 29 14:02:31 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 6e8c4a\npopulation: 8 (15), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 d33e c7a2 | 9 9cd2 (0) 8862 (0) 8c92 (0) d9b0 (0)\n001 1 1ffd | 1 1ffd (0)\n002 3 5989 55ce 4b6e | 3 4b6e (0) 55ce (0) 5989 (0)\n003 0 | 0\n============ DEPTH: 4 ==========================================\n004 1 6629 | 1 6629 (0)\n005 1 69d3 | 1 69d3 (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"boxKXW5U3afGM/9Gno+TWTUlD00ANMkFgEjcZDpPgR4="},"listenAddr":""},"up":true}},{"node":{"config":{"name":"node15","id":"37064116d218106446dc7785163f5cc0f47b541b1b5477075bcb7bbb4bcd454281404fc07420c1a703d5e005e4ad406fdc440d8c6da71f22b0a2a49fbbbd2834","private_key":"7eaec2f68f3b0e562a5438324aa30b9c22746af6e8139b05b21e89103f508c5a","services":["pss","bzz"]},"up":true,"info":{"name":"node15","id":"37064116d218106446dc7785163f5cc0f47b541b1b5477075bcb7bbb4bcd454281404fc07420c1a703d5e005e4ad406fdc440d8c6da71f22b0a2a49fbbbd2834","ip":"0.0.0.0","enode":"enode://37064116d218106446dc7785163f5cc0f47b541b1b5477075bcb7bbb4bcd454281404fc07420c1a703d5e005e4ad406fdc440d8c6da71f22b0a2a49fbbbd2834@0.0.0.0:0","listenAddr":"","protocols":{"hive":"\n=========================================================================\nFri Sep 29 14:02:31 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 1ffdd4\npopulation: 7 (14), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 9cd2 | 8 9cd2 (0) 8c92 (0) d33e (0) d9b0 (0)\n============ DEPTH: 1 ==========================================\n001 6 6629 69d3 6e8c 4b6e | 6 6629 (0) 69d3 (0) 6e8c (0) 4b6e (0)\n002 0 | 0\n003 0 | 0\n004 0 | 0\n005 0 | 0\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"H/3UaSvU/ScqxrXC4Dk1SGnfksDUJHq+3NiokysFdXQ="},"ports":{"discovery":0,"listener":0}}}},{"node":{"up":true,"info":{"enode":"enode://44e349f08e54a520a325841b2d256cc6e45ad2d0d5eda4f379056e1f86f065a24ce72f78d78908bc12887f2e3ddcd8cc5441e9151aa074597a9dac4361c554d9@0.0.0.0:0","ip":"0.0.0.0","name":"node16","id":"44e349f08e54a520a325841b2d256cc6e45ad2d0d5eda4f379056e1f86f065a24ce72f78d78908bc12887f2e3ddcd8cc5441e9151aa074597a9dac4361c554d9","protocols":{"bzz":"Vc5epXcsMd4nszfx4s92dmPAOmGy9Htxkh3vHPwycOo=","hive":"\n=========================================================================\nFri Sep 29 14:02:31 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 55ce5e\npopulation: 6 (15), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 d9b0 8862 | 9 c0f2 (0) c7a2 (0) c651 (0) c553 (0)\n001 1 1ffd | 1 1ffd (0)\n002 1 6e8c | 3 6629 (0) 69d3 (0) 6e8c (0)\n============ DEPTH: 3 ==========================================\n003 1 4b6e | 1 4b6e (0)\n004 1 5989 | 1 5989 (0)\n005 0 | 0\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"listener":0,"discovery":0},"listenAddr":""},"config":{"services":["pss","bzz"],"name":"node16","id":"44e349f08e54a520a325841b2d256cc6e45ad2d0d5eda4f379056e1f86f065a24ce72f78d78908bc12887f2e3ddcd8cc5441e9151aa074597a9dac4361c554d9","private_key":"b130fa04ab1f60d0713b9260156457f9139e819cb2f70bd87a2ea409f135f881"}}}],"conns":[{"other":"cb93e548a2e9a8fbc7a1bd50e0b0a3ad76b94265a454cd5c39fe091a55ad18172ef4d0ac2e776410f892cb1f3d9c17f35e01a798095271abd3566ee0fb3fe5ec","one":"44e349f08e54a520a325841b2d256cc6e45ad2d0d5eda4f379056e1f86f065a24ce72f78d78908bc12887f2e3ddcd8cc5441e9151aa074597a9dac4361c554d9","up":true},{"up":true,"other":"4d2e2c62a6b05e450a2b32598b20d906d99ab7ce14c6c005990249de3acd7731ae423c03e8e9326f7a6ea4ba6aa00714dc5d434caa00e8d4b59e1619f54cbeb9","one":"cb93e548a2e9a8fbc7a1bd50e0b0a3ad76b94265a454cd5c39fe091a55ad18172ef4d0ac2e776410f892cb1f3d9c17f35e01a798095271abd3566ee0fb3fe5ec"},{"up":true,"one":"4d2e2c62a6b05e450a2b32598b20d906d99ab7ce14c6c005990249de3acd7731ae423c03e8e9326f7a6ea4ba6aa00714dc5d434caa00e8d4b59e1619f54cbeb9","other":"513402ffa5f5cf96c617821045604efef0a833b99c1a600dad2d88202823bfcd89d65ea143e36e18f41d77d73b3ecc853cbf23e122a85c34bc416b16f3cc6f1d"},{"up":true,"other":"98fc9aba8502649019d30ccbc48c23a32b15f04584254c614e37fdc082fb8763727b47d8bb4333d629556698153f482b4ad68447eb08e6808177616071f7c133","one":"513402ffa5f5cf96c617821045604efef0a833b99c1a600dad2d88202823bfcd89d65ea143e36e18f41d77d73b3ecc853cbf23e122a85c34bc416b16f3cc6f1d"},{"other":"f11f84b0a5f8b98fa63fe142632b030def6aa9aaa456a8b08caf5e43183aeeb793708cea85a61f8107bd1761913232354ab18e5e68ac10ac81c4dd3d45650a0b","one":"98fc9aba8502649019d30ccbc48c23a32b15f04584254c614e37fdc082fb8763727b47d8bb4333d629556698153f482b4ad68447eb08e6808177616071f7c133","up":true},{"other":"2834f6d1f53d4464db7cd5985cf9a77c041f0a5e4b5b8133edc7a038e24790a6029c581e47378fdd4ea692bb94b6a50a7a1f90b9a7bb5ba2a1ef633666eb518c","one":"f11f84b0a5f8b98fa63fe142632b030def6aa9aaa456a8b08caf5e43183aeeb793708cea85a61f8107bd1761913232354ab18e5e68ac10ac81c4dd3d45650a0b","up":true},{"up":true,"other":"a98d185ced8f60d06a0f9288cbd7704e7a19ce0a874c01c9d7258a7033b3608627e3f9a8e776d8173d9de519fcc476221e14546be8fe385854dfa1158af8e05b","one":"2834f6d1f53d4464db7cd5985cf9a77c041f0a5e4b5b8133edc7a038e24790a6029c581e47378fdd4ea692bb94b6a50a7a1f90b9a7bb5ba2a1ef633666eb518c"},{"up":true,"other":"7b6793c9167c491051fb2a64560c57e464cfd8cc76ac31d788a0d4101cafbb0e07b1b373af80a30d11f8fb3d356405b100615c9741b6b210572daacfeb44dce8","one":"a98d185ced8f60d06a0f9288cbd7704e7a19ce0a874c01c9d7258a7033b3608627e3f9a8e776d8173d9de519fcc476221e14546be8fe385854dfa1158af8e05b"},{"up":true,"one":"7b6793c9167c491051fb2a64560c57e464cfd8cc76ac31d788a0d4101cafbb0e07b1b373af80a30d11f8fb3d356405b100615c9741b6b210572daacfeb44dce8","other":"a43f3ae2ce8cf4ef456b4a644e66f76761c80e1174ba2d0551622d148f10389f88ee96375cde424d9c692a5f3d98fa2f534a0fb97265ad96f69b8a0341160a3e"},{"up":true,"one":"a43f3ae2ce8cf4ef456b4a644e66f76761c80e1174ba2d0551622d148f10389f88ee96375cde424d9c692a5f3d98fa2f534a0fb97265ad96f69b8a0341160a3e","other":"215d8dfa7a91ef2a7aa045a942f2a6b7669cd01c955f51311d120c9f595406506b288870ad526b09520165732585fa534da6564c2dba3920539d9eb9227a17bf"},{"other":"a40b5b386b40d526d936659aecdef3fd6879cba84f2dabdd49a51575ba69e907734b49fa7fb21560211739e6545c47e89de4140be8b5d6d6e4782fdb3b73b2a6","one":"215d8dfa7a91ef2a7aa045a942f2a6b7669cd01c955f51311d120c9f595406506b288870ad526b09520165732585fa534da6564c2dba3920539d9eb9227a17bf","up":true},{"one":"a40b5b386b40d526d936659aecdef3fd6879cba84f2dabdd49a51575ba69e907734b49fa7fb21560211739e6545c47e89de4140be8b5d6d6e4782fdb3b73b2a6","other":"cf7d4bd60822873944d2e23f5771b09d4af19320ab7595c08c22bf8ace89345e43b3eb39156005f3e6eabdae6187bc5744f44b14733e2340347451ca7debc111","up":true},{"one":"cf7d4bd60822873944d2e23f5771b09d4af19320ab7595c08c22bf8ace89345e43b3eb39156005f3e6eabdae6187bc5744f44b14733e2340347451ca7debc111","other":"2b0a4930289eeb197a41ec935744e3c1adb23a9dbba23250750b3a66b53e609c4150227200f466c57c033968d842f23117eaaf3b071e2ba297f622444b2dc33a","up":true},{"up":true,"other":"ad819270bb72e687a895d444374c65f9766e24177fd711de716437e17926dca4f79a9ee37ca3a507e1c28aaf3a90757bb04d956aa2b4e81d1391a73c1096864f","one":"2b0a4930289eeb197a41ec935744e3c1adb23a9dbba23250750b3a66b53e609c4150227200f466c57c033968d842f23117eaaf3b071e2ba297f622444b2dc33a"},{"up":true,"one":"ad819270bb72e687a895d444374c65f9766e24177fd711de716437e17926dca4f79a9ee37ca3a507e1c28aaf3a90757bb04d956aa2b4e81d1391a73c1096864f","other":"37064116d218106446dc7785163f5cc0f47b541b1b5477075bcb7bbb4bcd454281404fc07420c1a703d5e005e4ad406fdc440d8c6da71f22b0a2a49fbbbd2834"},{"up":true,"one":"37064116d218106446dc7785163f5cc0f47b541b1b5477075bcb7bbb4bcd454281404fc07420c1a703d5e005e4ad406fdc440d8c6da71f22b0a2a49fbbbd2834","other":"44e349f08e54a520a325841b2d256cc6e45ad2d0d5eda4f379056e1f86f065a24ce72f78d78908bc12887f2e3ddcd8cc5441e9151aa074597a9dac4361c554d9"},{"up":true,"one":"cb93e548a2e9a8fbc7a1bd50e0b0a3ad76b94265a454cd5c39fe091a55ad18172ef4d0ac2e776410f892cb1f3d9c17f35e01a798095271abd3566ee0fb3fe5ec","other":"a40b5b386b40d526d936659aecdef3fd6879cba84f2dabdd49a51575ba69e907734b49fa7fb21560211739e6545c47e89de4140be8b5d6d6e4782fdb3b73b2a6"},{"one":"98fc9aba8502649019d30ccbc48c23a32b15f04584254c614e37fdc082fb8763727b47d8bb4333d629556698153f482b4ad68447eb08e6808177616071f7c133","other":"4d2e2c62a6b05e450a2b32598b20d906d99ab7ce14c6c005990249de3acd7731ae423c03e8e9326f7a6ea4ba6aa00714dc5d434caa00e8d4b59e1619f54cbeb9","up":true},{"up":true,"one":"f11f84b0a5f8b98fa63fe142632b030def6aa9aaa456a8b08caf5e43183aeeb793708cea85a61f8107bd1761913232354ab18e5e68ac10ac81c4dd3d45650a0b","other":"ad819270bb72e687a895d444374c65f9766e24177fd711de716437e17926dca4f79a9ee37ca3a507e1c28aaf3a90757bb04d956aa2b4e81d1391a73c1096864f"},{"other":"a40b5b386b40d526d936659aecdef3fd6879cba84f2dabdd49a51575ba69e907734b49fa7fb21560211739e6545c47e89de4140be8b5d6d6e4782fdb3b73b2a6","one":"a98d185ced8f60d06a0f9288cbd7704e7a19ce0a874c01c9d7258a7033b3608627e3f9a8e776d8173d9de519fcc476221e14546be8fe385854dfa1158af8e05b","up":true},{"up":true,"other":"ad819270bb72e687a895d444374c65f9766e24177fd711de716437e17926dca4f79a9ee37ca3a507e1c28aaf3a90757bb04d956aa2b4e81d1391a73c1096864f","one":"2834f6d1f53d4464db7cd5985cf9a77c041f0a5e4b5b8133edc7a038e24790a6029c581e47378fdd4ea692bb94b6a50a7a1f90b9a7bb5ba2a1ef633666eb518c"},{"other":"cf7d4bd60822873944d2e23f5771b09d4af19320ab7595c08c22bf8ace89345e43b3eb39156005f3e6eabdae6187bc5744f44b14733e2340347451ca7debc111","one":"ad819270bb72e687a895d444374c65f9766e24177fd711de716437e17926dca4f79a9ee37ca3a507e1c28aaf3a90757bb04d956aa2b4e81d1391a73c1096864f","up":true},{"up":true,"one":"a43f3ae2ce8cf4ef456b4a644e66f76761c80e1174ba2d0551622d148f10389f88ee96375cde424d9c692a5f3d98fa2f534a0fb97265ad96f69b8a0341160a3e","other":"ad819270bb72e687a895d444374c65f9766e24177fd711de716437e17926dca4f79a9ee37ca3a507e1c28aaf3a90757bb04d956aa2b4e81d1391a73c1096864f"},{"up":true,"one":"215d8dfa7a91ef2a7aa045a942f2a6b7669cd01c955f51311d120c9f595406506b288870ad526b09520165732585fa534da6564c2dba3920539d9eb9227a17bf","other":"ad819270bb72e687a895d444374c65f9766e24177fd711de716437e17926dca4f79a9ee37ca3a507e1c28aaf3a90757bb04d956aa2b4e81d1391a73c1096864f"},{"up":true,"one":"2b0a4930289eeb197a41ec935744e3c1adb23a9dbba23250750b3a66b53e609c4150227200f466c57c033968d842f23117eaaf3b071e2ba297f622444b2dc33a","other":"215d8dfa7a91ef2a7aa045a942f2a6b7669cd01c955f51311d120c9f595406506b288870ad526b09520165732585fa534da6564c2dba3920539d9eb9227a17bf"},{"up":true,"one":"44e349f08e54a520a325841b2d256cc6e45ad2d0d5eda4f379056e1f86f065a24ce72f78d78908bc12887f2e3ddcd8cc5441e9151aa074597a9dac4361c554d9","other":"ad819270bb72e687a895d444374c65f9766e24177fd711de716437e17926dca4f79a9ee37ca3a507e1c28aaf3a90757bb04d956aa2b4e81d1391a73c1096864f"},{"up":true,"other":"37064116d218106446dc7785163f5cc0f47b541b1b5477075bcb7bbb4bcd454281404fc07420c1a703d5e005e4ad406fdc440d8c6da71f22b0a2a49fbbbd2834","one":"cf7d4bd60822873944d2e23f5771b09d4af19320ab7595c08c22bf8ace89345e43b3eb39156005f3e6eabdae6187bc5744f44b14733e2340347451ca7debc111"},{"one":"7b6793c9167c491051fb2a64560c57e464cfd8cc76ac31d788a0d4101cafbb0e07b1b373af80a30d11f8fb3d356405b100615c9741b6b210572daacfeb44dce8","other":"215d8dfa7a91ef2a7aa045a942f2a6b7669cd01c955f51311d120c9f595406506b288870ad526b09520165732585fa534da6564c2dba3920539d9eb9227a17bf","up":true},{"one":"37064116d218106446dc7785163f5cc0f47b541b1b5477075bcb7bbb4bcd454281404fc07420c1a703d5e005e4ad406fdc440d8c6da71f22b0a2a49fbbbd2834","other":"f11f84b0a5f8b98fa63fe142632b030def6aa9aaa456a8b08caf5e43183aeeb793708cea85a61f8107bd1761913232354ab18e5e68ac10ac81c4dd3d45650a0b","up":true},{"up":true,"other":"2b0a4930289eeb197a41ec935744e3c1adb23a9dbba23250750b3a66b53e609c4150227200f466c57c033968d842f23117eaaf3b071e2ba297f622444b2dc33a","one":"513402ffa5f5cf96c617821045604efef0a833b99c1a600dad2d88202823bfcd89d65ea143e36e18f41d77d73b3ecc853cbf23e122a85c34bc416b16f3cc6f1d"},{"one":"4d2e2c62a6b05e450a2b32598b20d906d99ab7ce14c6c005990249de3acd7731ae423c03e8e9326f7a6ea4ba6aa00714dc5d434caa00e8d4b59e1619f54cbeb9","other":"2b0a4930289eeb197a41ec935744e3c1adb23a9dbba23250750b3a66b53e609c4150227200f466c57c033968d842f23117eaaf3b071e2ba297f622444b2dc33a","up":true},{"up":true,"other":"a98d185ced8f60d06a0f9288cbd7704e7a19ce0a874c01c9d7258a7033b3608627e3f9a8e776d8173d9de519fcc476221e14546be8fe385854dfa1158af8e05b","one":"cb93e548a2e9a8fbc7a1bd50e0b0a3ad76b94265a454cd5c39fe091a55ad18172ef4d0ac2e776410f892cb1f3d9c17f35e01a798095271abd3566ee0fb3fe5ec"},{"one":"4d2e2c62a6b05e450a2b32598b20d906d99ab7ce14c6c005990249de3acd7731ae423c03e8e9326f7a6ea4ba6aa00714dc5d434caa00e8d4b59e1619f54cbeb9","other":"7b6793c9167c491051fb2a64560c57e464cfd8cc76ac31d788a0d4101cafbb0e07b1b373af80a30d11f8fb3d356405b100615c9741b6b210572daacfeb44dce8","up":true},{"one":"513402ffa5f5cf96c617821045604efef0a833b99c1a600dad2d88202823bfcd89d65ea143e36e18f41d77d73b3ecc853cbf23e122a85c34bc416b16f3cc6f1d","other":"cf7d4bd60822873944d2e23f5771b09d4af19320ab7595c08c22bf8ace89345e43b3eb39156005f3e6eabdae6187bc5744f44b14733e2340347451ca7debc111","up":true},{"up":true,"other":"2b0a4930289eeb197a41ec935744e3c1adb23a9dbba23250750b3a66b53e609c4150227200f466c57c033968d842f23117eaaf3b071e2ba297f622444b2dc33a","one":"98fc9aba8502649019d30ccbc48c23a32b15f04584254c614e37fdc082fb8763727b47d8bb4333d629556698153f482b4ad68447eb08e6808177616071f7c133"},{"one":"f11f84b0a5f8b98fa63fe142632b030def6aa9aaa456a8b08caf5e43183aeeb793708cea85a61f8107bd1761913232354ab18e5e68ac10ac81c4dd3d45650a0b","other":"44e349f08e54a520a325841b2d256cc6e45ad2d0d5eda4f379056e1f86f065a24ce72f78d78908bc12887f2e3ddcd8cc5441e9151aa074597a9dac4361c554d9","up":true},{"up":true,"one":"2834f6d1f53d4464db7cd5985cf9a77c041f0a5e4b5b8133edc7a038e24790a6029c581e47378fdd4ea692bb94b6a50a7a1f90b9a7bb5ba2a1ef633666eb518c","other":"a43f3ae2ce8cf4ef456b4a644e66f76761c80e1174ba2d0551622d148f10389f88ee96375cde424d9c692a5f3d98fa2f534a0fb97265ad96f69b8a0341160a3e"},{"one":"a98d185ced8f60d06a0f9288cbd7704e7a19ce0a874c01c9d7258a7033b3608627e3f9a8e776d8173d9de519fcc476221e14546be8fe385854dfa1158af8e05b","other":"513402ffa5f5cf96c617821045604efef0a833b99c1a600dad2d88202823bfcd89d65ea143e36e18f41d77d73b3ecc853cbf23e122a85c34bc416b16f3cc6f1d","up":true},{"other":"2b0a4930289eeb197a41ec935744e3c1adb23a9dbba23250750b3a66b53e609c4150227200f466c57c033968d842f23117eaaf3b071e2ba297f622444b2dc33a","one":"7b6793c9167c491051fb2a64560c57e464cfd8cc76ac31d788a0d4101cafbb0e07b1b373af80a30d11f8fb3d356405b100615c9741b6b210572daacfeb44dce8","up":true},{"up":true,"other":"2834f6d1f53d4464db7cd5985cf9a77c041f0a5e4b5b8133edc7a038e24790a6029c581e47378fdd4ea692bb94b6a50a7a1f90b9a7bb5ba2a1ef633666eb518c","one":"37064116d218106446dc7785163f5cc0f47b541b1b5477075bcb7bbb4bcd454281404fc07420c1a703d5e005e4ad406fdc440d8c6da71f22b0a2a49fbbbd2834"},{"up":true,"one":"44e349f08e54a520a325841b2d256cc6e45ad2d0d5eda4f379056e1f86f065a24ce72f78d78908bc12887f2e3ddcd8cc5441e9151aa074597a9dac4361c554d9","other":"cf7d4bd60822873944d2e23f5771b09d4af19320ab7595c08c22bf8ace89345e43b3eb39156005f3e6eabdae6187bc5744f44b14733e2340347451ca7debc111"},{"other":"4d2e2c62a6b05e450a2b32598b20d906d99ab7ce14c6c005990249de3acd7731ae423c03e8e9326f7a6ea4ba6aa00714dc5d434caa00e8d4b59e1619f54cbeb9","one":"215d8dfa7a91ef2a7aa045a942f2a6b7669cd01c955f51311d120c9f595406506b288870ad526b09520165732585fa534da6564c2dba3920539d9eb9227a17bf","up":true},{"one":"cf7d4bd60822873944d2e23f5771b09d4af19320ab7595c08c22bf8ace89345e43b3eb39156005f3e6eabdae6187bc5744f44b14733e2340347451ca7debc111","other":"f11f84b0a5f8b98fa63fe142632b030def6aa9aaa456a8b08caf5e43183aeeb793708cea85a61f8107bd1761913232354ab18e5e68ac10ac81c4dd3d45650a0b","up":true},{"up":true,"one":"2b0a4930289eeb197a41ec935744e3c1adb23a9dbba23250750b3a66b53e609c4150227200f466c57c033968d842f23117eaaf3b071e2ba297f622444b2dc33a","other":"a98d185ced8f60d06a0f9288cbd7704e7a19ce0a874c01c9d7258a7033b3608627e3f9a8e776d8173d9de519fcc476221e14546be8fe385854dfa1158af8e05b"},{"other":"cf7d4bd60822873944d2e23f5771b09d4af19320ab7595c08c22bf8ace89345e43b3eb39156005f3e6eabdae6187bc5744f44b14733e2340347451ca7debc111","one":"a43f3ae2ce8cf4ef456b4a644e66f76761c80e1174ba2d0551622d148f10389f88ee96375cde424d9c692a5f3d98fa2f534a0fb97265ad96f69b8a0341160a3e","up":true},{"other":"44e349f08e54a520a325841b2d256cc6e45ad2d0d5eda4f379056e1f86f065a24ce72f78d78908bc12887f2e3ddcd8cc5441e9151aa074597a9dac4361c554d9","one":"4d2e2c62a6b05e450a2b32598b20d906d99ab7ce14c6c005990249de3acd7731ae423c03e8e9326f7a6ea4ba6aa00714dc5d434caa00e8d4b59e1619f54cbeb9","up":true},{"one":"513402ffa5f5cf96c617821045604efef0a833b99c1a600dad2d88202823bfcd89d65ea143e36e18f41d77d73b3ecc853cbf23e122a85c34bc416b16f3cc6f1d","other":"215d8dfa7a91ef2a7aa045a942f2a6b7669cd01c955f51311d120c9f595406506b288870ad526b09520165732585fa534da6564c2dba3920539d9eb9227a17bf","up":true},{"one":"98fc9aba8502649019d30ccbc48c23a32b15f04584254c614e37fdc082fb8763727b47d8bb4333d629556698153f482b4ad68447eb08e6808177616071f7c133","other":"a40b5b386b40d526d936659aecdef3fd6879cba84f2dabdd49a51575ba69e907734b49fa7fb21560211739e6545c47e89de4140be8b5d6d6e4782fdb3b73b2a6","up":true},{"one":"7b6793c9167c491051fb2a64560c57e464cfd8cc76ac31d788a0d4101cafbb0e07b1b373af80a30d11f8fb3d356405b100615c9741b6b210572daacfeb44dce8","other":"98fc9aba8502649019d30ccbc48c23a32b15f04584254c614e37fdc082fb8763727b47d8bb4333d629556698153f482b4ad68447eb08e6808177616071f7c133","up":true},{"one":"a43f3ae2ce8cf4ef456b4a644e66f76761c80e1174ba2d0551622d148f10389f88ee96375cde424d9c692a5f3d98fa2f534a0fb97265ad96f69b8a0341160a3e","other":"37064116d218106446dc7785163f5cc0f47b541b1b5477075bcb7bbb4bcd454281404fc07420c1a703d5e005e4ad406fdc440d8c6da71f22b0a2a49fbbbd2834","up":true},{"up":true,"one":"215d8dfa7a91ef2a7aa045a942f2a6b7669cd01c955f51311d120c9f595406506b288870ad526b09520165732585fa534da6564c2dba3920539d9eb9227a17bf","other":"98fc9aba8502649019d30ccbc48c23a32b15f04584254c614e37fdc082fb8763727b47d8bb4333d629556698153f482b4ad68447eb08e6808177616071f7c133"},{"up":true,"other":"a98d185ced8f60d06a0f9288cbd7704e7a19ce0a874c01c9d7258a7033b3608627e3f9a8e776d8173d9de519fcc476221e14546be8fe385854dfa1158af8e05b","one":"37064116d218106446dc7785163f5cc0f47b541b1b5477075bcb7bbb4bcd454281404fc07420c1a703d5e005e4ad406fdc440d8c6da71f22b0a2a49fbbbd2834"},{"up":true,"one":"7b6793c9167c491051fb2a64560c57e464cfd8cc76ac31d788a0d4101cafbb0e07b1b373af80a30d11f8fb3d356405b100615c9741b6b210572daacfeb44dce8","other":"513402ffa5f5cf96c617821045604efef0a833b99c1a600dad2d88202823bfcd89d65ea143e36e18f41d77d73b3ecc853cbf23e122a85c34bc416b16f3cc6f1d"}]} \ No newline at end of file diff --git a/swarm/pss/testdata/snapshot_2.json b/swarm/pss/testdata/snapshot_2.json new file mode 100644 index 0000000000..5704bcf6af --- /dev/null +++ b/swarm/pss/testdata/snapshot_2.json @@ -0,0 +1,67 @@ +{ + "conns":[ + { + "other":"0eec333dd211c2ea81db614fe58bf0300c15e50e1b044e47ef93067a6cdbc3bc666b40bdcc515bbf580355dbef9370294ef1ee92ee0525e78a8beed00c2b99f5", + "one":"7b12f55c7c012104e006775d03b89722b403fb0e1ecb79af8cadfa6947425aedb323fb9416c84b782d35f3216acb5d94a1dd31d60a3eba45f9051bf503de1b66", + "up":true + } + ], + "nodes":[ + { + "node":{ + "config":{ + "private_key":"e567b7d9c554e5102cdc99b6523bace02dbb8951415c8816d82ba2d2e97fa23b", + "name":"node01", + "id":"7b12f55c7c012104e006775d03b89722b403fb0e1ecb79af8cadfa6947425aedb323fb9416c84b782d35f3216acb5d94a1dd31d60a3eba45f9051bf503de1b66", + "services":[ + "pss","bzz" + ] + }, + "info":{ + "ip":"0.0.0.0", + "listenAddr":"", + "protocols":{ + "hive":"\n=========================================================================\nFri Sep 29 21:22:53 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 73d6ad\npopulation: 5 (7), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 dfd4 | 3 8a1e (0) d776 (0) dfd4 (0)\n============ DEPTH: 1 ==========================================\n001 3 05da 159c 3451 | 3 05da (0) 159c (0) 3451 (0)\n002 0 | 0\n003 1 6e8d | 1 6e8d (0)\n004 0 | 0\n005 0 | 0\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================", + "bzz":"c9atSnUGnc7WYPpMuYFD7lVz33yxXZopWs8WVeloM4Q=" + }, + "ports":{ + "listener":0, + "discovery":0 + }, + "name":"node01", + "id":"7b12f55c7c012104e006775d03b89722b403fb0e1ecb79af8cadfa6947425aedb323fb9416c84b782d35f3216acb5d94a1dd31d60a3eba45f9051bf503de1b66", + "enode":"enode://7b12f55c7c012104e006775d03b89722b403fb0e1ecb79af8cadfa6947425aedb323fb9416c84b782d35f3216acb5d94a1dd31d60a3eba45f9051bf503de1b66@0.0.0.0:0" + }, + "up":true + } + }, + { + "node":{ + "info":{ + "listenAddr":"", + "ip":"0.0.0.0", + "ports":{ + "discovery":0, + "listener":0 + }, + "protocols":{ + "hive":"\n=========================================================================\nFri Sep 29 21:22:53 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 6e8da8\npopulation: 5 (7), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 8a1e | 3 8a1e (0) d776 (0) dfd4 (0)\n============ DEPTH: 1 ==========================================\n001 3 3451 159c 05da | 3 05da (0) 159c (0) 3451 (0)\n002 0 | 0\n003 1 73d6 | 1 73d6 (0)\n004 0 | 0\n005 0 | 0\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================", + "bzz":"bo2oaruJSrNQRMjEVRRyJd+WyrSY2gZ6EY8fuaQX+eM=" + }, + "id":"0eec333dd211c2ea81db614fe58bf0300c15e50e1b044e47ef93067a6cdbc3bc666b40bdcc515bbf580355dbef9370294ef1ee92ee0525e78a8beed00c2b99f5", + "name":"node02", + "enode":"enode://0eec333dd211c2ea81db614fe58bf0300c15e50e1b044e47ef93067a6cdbc3bc666b40bdcc515bbf580355dbef9370294ef1ee92ee0525e78a8beed00c2b99f5@0.0.0.0:0" + }, + "config":{ + "name":"node02", + "id":"0eec333dd211c2ea81db614fe58bf0300c15e50e1b044e47ef93067a6cdbc3bc666b40bdcc515bbf580355dbef9370294ef1ee92ee0525e78a8beed00c2b99f5", + "services":[ + "pss","bzz" + ], + "private_key":"c7526db70acd02f36d3b201ef3e1d85e38c52bee6931453213dbc5edec4d0976" + }, + "up":true + } + } + ] +} diff --git a/swarm/pss/testdata/snapshot_256.json b/swarm/pss/testdata/snapshot_256.json new file mode 100644 index 0000000000..f0c402df05 --- /dev/null +++ b/swarm/pss/testdata/snapshot_256.json @@ -0,0 +1 @@ +{"conns":[{"up":true,"other":"6d0a09235ba0b0428938abf0e0782ac0ecf5697ef862888719a34fc956517aeef89d5e5f76d12e10067fee5bac8781dc10400eeb35c2393b9382b2a4f68f7939","one":"545237d8463b75fd2e9bbfbffb35c5b78b4abbc85f6bfbd56976789012dd9a62ca1f866bf37bb33618e026aab764adb9ced5e00cd415562f69992f74c795083f"},{"up":true,"other":"9e21f5d4cfb389ac3ad43497689878bd245a89c587a8637d832b1e355ba244f4c83e6499bc7936e6d35645db25910ecd89b9af9b6b2f0c7cc4d7c6114328d7bf","one":"c6ad9b9de5cdbe28540f4eb7c66fb37f6d4295e6e60c6de54e2a45c1970b8e0047558e986bbd10e9e86c8bb0407846fac4823e4570e8a1486fc4bf55cb4a0986"},{"one":"02fdbcb00f20a3f6e894900d798fcb0aca9e21f5b107924c0999eb396220f16dee99fc80ccba796e66e69dcb9ce278b7e0e4539c7a7cd0fbc1037bf8e56c1e67","other":"f4cdaeb513aa98f8868d8eb3a1d12c07367725928a1bc7d6ca4b583788e111a955463037ec7867260511896d97dfbf096aa77ee8a7d9ea1c06cad4a92c45108d","up":true},{"one":"85b6404a76b4762156c8ddd2f312763dfe19b315d914533844cf229301880c57ffeadc0eb5f4a8d542e1d9fc961dfb5a572d2101172b1a0fc238ced05ba49ec1","up":true,"other":"6c95c653e15bb99d32656f35790400134cd7188e063f878e19cb9118eb469ae0362dc45255f2a1eae31520be01d42b5bc5bbebf03d644c9f206ca79cb33a01ad"},{"one":"77e40e42f570a217f707888c714deb31fd70c856ae4b9a44ec7cee02768185dc4d7ed210429607f06690b32edd9fb06b304aff330a3949cc2fd49db1bc392edb","up":true,"other":"92dbb67da2b99a8fe46b1e510addc2b83e357ac0b5287b7ef5c1b1bc6e252b8dfd605a6896ede65848e429216d1f67d530d9e7b83ff14058aa2e5b6e405d6801"},{"one":"50c79baa3e6781482ccb5e960c699dd9c13f479467c6315c5292a396337cf3619e7faba1971a1f470051cb9042f80ea6750defe3936b72aac4d9bac6f8368c67","other":"51df4f4d4f020f22f55a5fd00c7f9c68c232c167ae4d4e80d7695f8f39c5aa0a7b565c1c55bdd6a21e06fa056549d08fd2e9d76fd79e21295557aa30d1ae022c","up":true},{"one":"b4f300abda4cf6e383f997510eb681e9fa62e23577e3c19bd7447fa1f5702a4e034cea5944248e7c6e6e92b5ae69195c3e8a2c5ca7827b4f4a00cc8546e6695a","up":true,"other":"855667650e96c5ed2d9b0c82532ed1fb92f72b1ae926afafe09cf8f6e90e539aec5c4c2ab108f2c2a1ad7dd8b83ca92a98c550a1c9ed27e6632a7d2f6da4f970"},{"one":"6c95c653e15bb99d32656f35790400134cd7188e063f878e19cb9118eb469ae0362dc45255f2a1eae31520be01d42b5bc5bbebf03d644c9f206ca79cb33a01ad","up":true,"other":"313a131ecb7d68e127d0fec8bb4a2e586886203c3d07857a93e7a39bb831703184d9ae28ba9ef3d986c2dae1a24f4f5bfa47cfc35f74f5512a126836364d7736"},{"up":true,"other":"c206d8689068488179e86ce549de75989e0b17cbe09880d18fcf0fa212e629345f1b899203607a2b083569cb3f8398e501843166f5db23ac7fa7dacfe26dd3f4","one":"92dbb67da2b99a8fe46b1e510addc2b83e357ac0b5287b7ef5c1b1bc6e252b8dfd605a6896ede65848e429216d1f67d530d9e7b83ff14058aa2e5b6e405d6801"},{"one":"313a131ecb7d68e127d0fec8bb4a2e586886203c3d07857a93e7a39bb831703184d9ae28ba9ef3d986c2dae1a24f4f5bfa47cfc35f74f5512a126836364d7736","up":true,"other":"29acdd4c1233441bd40f98e245ecc9de94de6f9d0ab7c1a9923d833a2c8e6c1bd26d792686fec762b31fe28bbdd7aa04c9a594d997d08c133bb24cb2d877595a"},{"one":"57085f756f76644cdd2148524f2334d869ef0ab2fcbe7fb11f5d22bc1f5023165b11526ecc85ff9cbb88877386af9b148d7ef15a825b3a586d16c01bdfc86692","up":true,"other":"ea2921612b827e3c26328368bed9be7cbf1f2b2aecaf31863c9cdccd74c56b651d6eaceb8ac9609a6653488837ded310df91e53a74789ae75cb841e2aeaf96df"},{"one":"29acdd4c1233441bd40f98e245ecc9de94de6f9d0ab7c1a9923d833a2c8e6c1bd26d792686fec762b31fe28bbdd7aa04c9a594d997d08c133bb24cb2d877595a","other":"1e3a2f2491b6acb07a9549d9929d150479a0313c926b0e236237bd541303da4b563a855016a90ab50e59d94803ad566798570fa981464c94c04a4a4a94fbc607","up":true},{"other":"7958d1517de1223e7fb30acf61d8618e49fb95a03bc2f49141f4c7967bc80b90e0dd526c205639de3c060029963d43813293c2556f7b127945c798f3f9f18626","up":true,"one":"c206d8689068488179e86ce549de75989e0b17cbe09880d18fcf0fa212e629345f1b899203607a2b083569cb3f8398e501843166f5db23ac7fa7dacfe26dd3f4"},{"other":"fd0123c7b96004067e98e463e273de5bc5402399ae70a95985b5f682e30d4f35d070deaf8c71d201e98c4324d832b95aab7535ad8a2658f66e3e0bb1202204e1","up":true,"one":"ea2921612b827e3c26328368bed9be7cbf1f2b2aecaf31863c9cdccd74c56b651d6eaceb8ac9609a6653488837ded310df91e53a74789ae75cb841e2aeaf96df"},{"one":"8e8614a4c2ee2b1a3fa5ace0ca353cff36b3de3308ccf53665b8b56f8e2456a8a65f3846d786dccd68b1bfcefdd170ea5f8edb481800b1ce72d9fce2added7f0","up":true,"other":"43086ff7ffd3c7bdec77bd288f41f1ee0ce21bd3f60a5df8931e2af6e7af5ef0fad432d29625491935d11567944351fc7867c807ebd12dd2c21c9e620ae0f85c"},{"up":true,"other":"02fdbcb00f20a3f6e894900d798fcb0aca9e21f5b107924c0999eb396220f16dee99fc80ccba796e66e69dcb9ce278b7e0e4539c7a7cd0fbc1037bf8e56c1e67","one":"1489ad735e1256900e4733707f8b78f1d853742a8f9b2d0c1c89651c60e7ee9d266afba5b4c1ed3f9cee05a1d2b2bba35dadb5b08973a93fd70dfb9e367339bd"},{"up":true,"other":"545237d8463b75fd2e9bbfbffb35c5b78b4abbc85f6bfbd56976789012dd9a62ca1f866bf37bb33618e026aab764adb9ced5e00cd415562f69992f74c795083f","one":"fd0123c7b96004067e98e463e273de5bc5402399ae70a95985b5f682e30d4f35d070deaf8c71d201e98c4324d832b95aab7535ad8a2658f66e3e0bb1202204e1"},{"up":true,"other":"3e2241cdb9f34c1d2c6930e59940e2c4b92b0287579d7263a620a609c5e66dca6d85df48cf1bffd63663a6704c42d0866aae3e484fd9a44b6a012f72dd3cef6e","one":"2abb91884cc3a8fb91b2f2f369f9430f2b3b05c75ce6203aa7a50312c9f141f9d0f615063d3576a5ce8a4be9ecb942aa804a717f76d9e8dca03d115dcc43f775"},{"up":true,"other":"d7af0a0217ff98804aa05f8f926a8b6262363b5391d24cda8048cca5ca5982b407b7b098302d0db6d8dd9ac0883b2025b3de651617ed1a173181148295c6d336","one":"9bea5f82c2a390587de44d620d6637834e6f2329cd83d8df6305b03b75d9b543160b6c6f9f8887e6bc88f1d0726435d6c8ad813aadad0653b0790b8f6388413a"},{"one":"d7af0a0217ff98804aa05f8f926a8b6262363b5391d24cda8048cca5ca5982b407b7b098302d0db6d8dd9ac0883b2025b3de651617ed1a173181148295c6d336","up":true,"other":"bb0749de05a97daa67de889c15831ce39a080d641b3b08e3c248b0b16f4c07943fea8dd054d4a7e3e4af91ecff07053ce90096485a360b6f1d93050d179f30c3"},{"up":true,"other":"7cc9389c8f751465e0b94baed896f6f122631052300b1b5b23d3c7656e4d11014a7a9ae62a1287bb040ca37221871a566cd470e523846df7e3acb5f94c7cde06","one":"ab1a3542d67ef9d1a63653990bf0782f53b0169fe5092adc92fa7aeb38f66c6b62d49e3455cc2ac4994bfcfb03111953acf4cc3099026672cc61f6e24cb3ae00"},{"one":"723f362e98f90d7ef15e24e353759fdbdabb08adab767dba73ab546741fac3dfb457466f1e2c851aa49526da1408f8ddb509e12f7dc0bc1e785c5b72be8a986e","other":"9f3af4577308965aceb7e0101443669496e7ccf1de680629862a7005966c708b6fb52e6dfe62660246b9892adc25838da2873502e0be706bcad8f25b7ceedfa5","up":true},{"other":"9bea5f82c2a390587de44d620d6637834e6f2329cd83d8df6305b03b75d9b543160b6c6f9f8887e6bc88f1d0726435d6c8ad813aadad0653b0790b8f6388413a","up":true,"one":"e1f23e1caba66f5ff821edbc4a3d527539937f73d86dd0df43aa1266a99f51f2480a77961eff177fbbf852fc52cb9317179f80b1580194daaedadc3b00510751"},{"up":true,"other":"c6f38fe8a0f2b3773bae332e0ca7516e944bde186fe99daae10a2b0aecde3ce23c1834eaad97a4e6d2da8cd53a08dbafa72d2b827c851b115b74e8010125dba2","one":"bb0749de05a97daa67de889c15831ce39a080d641b3b08e3c248b0b16f4c07943fea8dd054d4a7e3e4af91ecff07053ce90096485a360b6f1d93050d179f30c3"},{"up":true,"other":"85b6404a76b4762156c8ddd2f312763dfe19b315d914533844cf229301880c57ffeadc0eb5f4a8d542e1d9fc961dfb5a572d2101172b1a0fc238ced05ba49ec1","one":"1c080e90760dfcee08ade6e4ea3b275ff3c6882f3b44b7f3a73d70bcc816fc63ce0b6138f810d17d96ed387076f9bbb6dbb2ef6dc4d6ba6542c1f587b7602a12"},{"one":"c6f38fe8a0f2b3773bae332e0ca7516e944bde186fe99daae10a2b0aecde3ce23c1834eaad97a4e6d2da8cd53a08dbafa72d2b827c851b115b74e8010125dba2","up":true,"other":"9c8f156797deff649d74d56fc42b4bb1a87312089114d4350424c375837d9c8068dd09af01c1c973d12ec5d7e8da600cd685cae70d3116b9dbda823092e03fff"},{"other":"e1f23e1caba66f5ff821edbc4a3d527539937f73d86dd0df43aa1266a99f51f2480a77961eff177fbbf852fc52cb9317179f80b1580194daaedadc3b00510751","up":true,"one":"e903d7aebff96a6afa4b9dd19b0b02e5af18da8e4e89f64247e1a2c2d46637538c741182eac67f45ec61be76aeaccde57f0a0184bd608ea7d92e586d4f827ea7"},{"up":true,"other":"3639f964feba681db9702cac3f02058f2e490fd7bffb217dc3480dc458decafd5955541fea89f0f6f14ee50a745eaf98b21363d6b4fb88c31bd32bf7845d524b","one":"9c8f156797deff649d74d56fc42b4bb1a87312089114d4350424c375837d9c8068dd09af01c1c973d12ec5d7e8da600cd685cae70d3116b9dbda823092e03fff"},{"one":"3639f964feba681db9702cac3f02058f2e490fd7bffb217dc3480dc458decafd5955541fea89f0f6f14ee50a745eaf98b21363d6b4fb88c31bd32bf7845d524b","other":"842ec3faa8b4a4cdec32abfa00ae827277fe2696e1b0c6551154533b16cf75ae69caf834b4f08488fa5c8b322fb633b1fd8a5b7d436e9c589cc9074dc031ae68","up":true},{"up":true,"other":"76643f67075c6e45bd176db19473240cda6f886d1cac25330e2d99c84a429934f4c6a606c9c72574d5eaccd0a3f1770dab05e6ff6a5b5ce4d7258fed2bc13d48","one":"842ec3faa8b4a4cdec32abfa00ae827277fe2696e1b0c6551154533b16cf75ae69caf834b4f08488fa5c8b322fb633b1fd8a5b7d436e9c589cc9074dc031ae68"},{"one":"76643f67075c6e45bd176db19473240cda6f886d1cac25330e2d99c84a429934f4c6a606c9c72574d5eaccd0a3f1770dab05e6ff6a5b5ce4d7258fed2bc13d48","other":"20f6a8be1d2d8b5d6a43d851a2f5475385ef07fab80ac46525d0beccf3e25c01d726cfb3a1179e8343b1e88d21684fb24dd6e6497537d4e7e9edd59cb95d1b8d","up":true},{"other":"c0bec7375c66bec98524ade2245c1d7480516fc5d87a3249e64ec86418e80e202f1e3da76832e97bbc3dcaed8c96ca344e4829347b4428f4b1cb61999e404c05","up":true,"one":"20f6a8be1d2d8b5d6a43d851a2f5475385ef07fab80ac46525d0beccf3e25c01d726cfb3a1179e8343b1e88d21684fb24dd6e6497537d4e7e9edd59cb95d1b8d"},{"up":true,"other":"699c923976c5b8c70c353840d3e384750f466954265f05fbb0d5877a2c0318a041dc57adc12ac6e8fbae7a00d6b6675e1a1be3a8f59dac12727ee3f8ae467a13","one":"c0bec7375c66bec98524ade2245c1d7480516fc5d87a3249e64ec86418e80e202f1e3da76832e97bbc3dcaed8c96ca344e4829347b4428f4b1cb61999e404c05"},{"one":"699c923976c5b8c70c353840d3e384750f466954265f05fbb0d5877a2c0318a041dc57adc12ac6e8fbae7a00d6b6675e1a1be3a8f59dac12727ee3f8ae467a13","other":"10551c0c37abc25457903978868dd4843a52fda5f9b571b05ebd974d8c381fda4349f17c2b986a2e4b8d06b0517422f085d5f6d9cd814efa40e48393d9f71d7e","up":true},{"other":"8fb6838337f832445531764ddafc3c747b2607f2f33e244685d6de621c2b53264270f5504187e43b7fa5cda53e66dd00b16c06879c82fb38a3d9e8aec4060210","up":true,"one":"10551c0c37abc25457903978868dd4843a52fda5f9b571b05ebd974d8c381fda4349f17c2b986a2e4b8d06b0517422f085d5f6d9cd814efa40e48393d9f71d7e"},{"other":"869ca41ea1f82bec5f43807a3aaaabc39b21c62d3c9c8bdc0709683e22dd37cb2f3c313766809076d2c02d0d6171f4f32a1b5080abcb8072d88981042ae6237d","up":true,"one":"8fb6838337f832445531764ddafc3c747b2607f2f33e244685d6de621c2b53264270f5504187e43b7fa5cda53e66dd00b16c06879c82fb38a3d9e8aec4060210"},{"one":"869ca41ea1f82bec5f43807a3aaaabc39b21c62d3c9c8bdc0709683e22dd37cb2f3c313766809076d2c02d0d6171f4f32a1b5080abcb8072d88981042ae6237d","other":"b4557089e4247379e587a087f53b36dd1f86f85d9dcfab5dc562079978cd959adaef5b30d11258d9cb552e7c5abddf5377a71d449febe8f2acb0aec3ebd8ba73","up":true},{"other":"f52297fc51b920d2495ccece290432656d9388e698339c8c1279ceea45de698a4ecbda1d25928c48f1e19e9dacd3147e23ef01acc093872d7300aed187841dcc","up":true,"one":"b4557089e4247379e587a087f53b36dd1f86f85d9dcfab5dc562079978cd959adaef5b30d11258d9cb552e7c5abddf5377a71d449febe8f2acb0aec3ebd8ba73"},{"one":"f52297fc51b920d2495ccece290432656d9388e698339c8c1279ceea45de698a4ecbda1d25928c48f1e19e9dacd3147e23ef01acc093872d7300aed187841dcc","other":"202ae63076a5560418023f00c9965b2a1d12de932b5371ae270d63db88551a7aa1a3c48841f81948fad3435bb4a7e3e165a2eced9fd937444e4502471e23dae8","up":true},{"one":"202ae63076a5560418023f00c9965b2a1d12de932b5371ae270d63db88551a7aa1a3c48841f81948fad3435bb4a7e3e165a2eced9fd937444e4502471e23dae8","other":"99af34b172d319633e07a4e528f416024653a230a9103a4b281171f75bb697dd6be4757558c94e86210b4da8d9fe1229f6a5d8c4174989ea0ce696f8d1a9995d","up":true},{"one":"99af34b172d319633e07a4e528f416024653a230a9103a4b281171f75bb697dd6be4757558c94e86210b4da8d9fe1229f6a5d8c4174989ea0ce696f8d1a9995d","up":true,"other":"362ed9a92b588d5fe315b90a74aa27f7600e4a7d06b27ceb26272340388d916a831df85bf83450ef80bda4e4a21acaac60560c8a42940a26e2ac567519e2a202"},{"one":"baa28b8cb7ec539e0e157d7598cc5a5b0210fd8fb5c9026c3cd612133c5a8ee56997507511928af5683cb620fd85593dd8f6ff882d95fb847870ae4ce7dc503b","up":true,"other":"e0a043f98b462f10f72aa61ceda52f9c27829d086f6f2c5bf4db4fe32759002e5ff9519495d57dbb83d963a1dc991a1defcf5b9ef0d543789f38c68f5d07122b"},{"one":"362ed9a92b588d5fe315b90a74aa27f7600e4a7d06b27ceb26272340388d916a831df85bf83450ef80bda4e4a21acaac60560c8a42940a26e2ac567519e2a202","up":true,"other":"01427ba4d1e2de0b2764515556676a6058f88c16f597780dea3d7f95a6eec9299c3987d99c199d88a0a5e695ee6f0ff7de424e4eb65e54233b956a9634133998"},{"one":"9e21f5d4cfb389ac3ad43497689878bd245a89c587a8637d832b1e355ba244f4c83e6499bc7936e6d35645db25910ecd89b9af9b6b2f0c7cc4d7c6114328d7bf","up":true,"other":"1489ad735e1256900e4733707f8b78f1d853742a8f9b2d0c1c89651c60e7ee9d266afba5b4c1ed3f9cee05a1d2b2bba35dadb5b08973a93fd70dfb9e367339bd"},{"other":"4e88cc60efee147fb72a735775944c7b2ba0790e2b2b935b4b3c2da9a3158a2a7aae411e9204cdbe6b2304d90a3a8278f8bb1a800a409e8500d100d84ba1947f","up":true,"one":"01427ba4d1e2de0b2764515556676a6058f88c16f597780dea3d7f95a6eec9299c3987d99c199d88a0a5e695ee6f0ff7de424e4eb65e54233b956a9634133998"},{"one":"f52281c227aa82a3bd5fabfdcf8bdf1d9ea6739ab9b9075340143d59b4f2f8a79a981609c9f42823a0253c19a7281eed0e912e4054363ab7fe50117563ef14e0","other":"7a8cb96685c1b8fbaeb18c8dc1f9f2631b23bc035e704e2f5df915b8bcabd6e2025ddc30324c69833f86e577b250c0721fee9d294f3e22016ae4c59c5f88845b","up":true},{"up":true,"other":"e323da6ae861cb092543992b8985639f9b3bcaf1c3c68757f4603a67800be62950fe7d8f8ef80eb83a18107b677c7f5047ea89a5790e0ea2a7969f4856d28488","one":"7a8cb96685c1b8fbaeb18c8dc1f9f2631b23bc035e704e2f5df915b8bcabd6e2025ddc30324c69833f86e577b250c0721fee9d294f3e22016ae4c59c5f88845b"},{"up":true,"other":"e7b2adabc2c99ac47b1e94fc0a2c63a00a1d622ea67a4c1858f4cec93fca957d43d8429605761bdf5eed4f733dac1a3d12fb928f22abf248965994acde63864a","one":"e323da6ae861cb092543992b8985639f9b3bcaf1c3c68757f4603a67800be62950fe7d8f8ef80eb83a18107b677c7f5047ea89a5790e0ea2a7969f4856d28488"},{"one":"e7b2adabc2c99ac47b1e94fc0a2c63a00a1d622ea67a4c1858f4cec93fca957d43d8429605761bdf5eed4f733dac1a3d12fb928f22abf248965994acde63864a","up":true,"other":"5114329db828f9568ccb0d7643a10e273aa626177910f55e22a53abf1ce8ec75b95465c983446b20eac0ff9c59c5dc53eca95b24aabcc8dd110e397cd2934047"},{"one":"5114329db828f9568ccb0d7643a10e273aa626177910f55e22a53abf1ce8ec75b95465c983446b20eac0ff9c59c5dc53eca95b24aabcc8dd110e397cd2934047","up":true,"other":"4eab70233789c544bec97040a04099494bf269a819584a5d0b42295c918a52b02f224a8ed127aba3d92c02f567356bea4b95f77230ef548dfa7fe44b643d8704"},{"other":"e0875ed6be1e163b15c13cdf37442f838670d0949349ee9ff119a0451beffb1a302943ee9d7cba48592922f64908aeb0f39f6e2e3725d1e7cdc5db34083b6977","up":true,"one":"4eab70233789c544bec97040a04099494bf269a819584a5d0b42295c918a52b02f224a8ed127aba3d92c02f567356bea4b95f77230ef548dfa7fe44b643d8704"},{"up":true,"other":"58f9139905ae1d005950f110b7ead3355672ecc478e8c66393566c64b935003f6fec3031dc9eb21cda660acb1955cf7bb33a20fdd74d493f29868ace328fcd75","one":"4e88cc60efee147fb72a735775944c7b2ba0790e2b2b935b4b3c2da9a3158a2a7aae411e9204cdbe6b2304d90a3a8278f8bb1a800a409e8500d100d84ba1947f"},{"one":"e0875ed6be1e163b15c13cdf37442f838670d0949349ee9ff119a0451beffb1a302943ee9d7cba48592922f64908aeb0f39f6e2e3725d1e7cdc5db34083b6977","up":true,"other":"c03ef1de42d522b44eef53be11f2c57b8b74fed9e87e6c2928c1feb48ddfecc67e1a3a8c8be1c47b3735a216d7054e2a4dda49fbd9a1ac702146aae5bdeced7c"},{"one":"c03ef1de42d522b44eef53be11f2c57b8b74fed9e87e6c2928c1feb48ddfecc67e1a3a8c8be1c47b3735a216d7054e2a4dda49fbd9a1ac702146aae5bdeced7c","other":"0e164c8692532e59c76ef84319a1093324f46f77618d3a836a279df52edca6c839061c0582dac7481da1bd0f3e2b58fc0dacd6ee5d678ba1406d4a1a25fe761d","up":true},{"one":"0e164c8692532e59c76ef84319a1093324f46f77618d3a836a279df52edca6c839061c0582dac7481da1bd0f3e2b58fc0dacd6ee5d678ba1406d4a1a25fe761d","other":"a1fe0d27f82309911a4b758c4e597bde16adc1e2fdfb07b52dea5092cea40ff212ea2cc831e385094b044f519909cf978f350b16ffd4c70c159cf1372301a3cf","up":true},{"other":"8e89fe4b3fffea8af247d2581aa511056efbeb796058d50a341d57aa0f7ccc2192d90cfb8d18558363df798567faaddb86815e8bd671b36ca37af0651535aabf","up":true,"one":"a1fe0d27f82309911a4b758c4e597bde16adc1e2fdfb07b52dea5092cea40ff212ea2cc831e385094b044f519909cf978f350b16ffd4c70c159cf1372301a3cf"},{"up":true,"other":"df9306a263f40e0e255996500523354de3cc78b68ae560f66d79f6ea28f30f773f1fd6ebc33928723dfde2ee3d4f982b203bee4c3803a5050df83477045bb279","one":"8e89fe4b3fffea8af247d2581aa511056efbeb796058d50a341d57aa0f7ccc2192d90cfb8d18558363df798567faaddb86815e8bd671b36ca37af0651535aabf"},{"one":"df9306a263f40e0e255996500523354de3cc78b68ae560f66d79f6ea28f30f773f1fd6ebc33928723dfde2ee3d4f982b203bee4c3803a5050df83477045bb279","up":true,"other":"b7cc9044d021b19cd8a6d290d21f1c91fd5deec472583d0aeed0a6aacc8efef9968079254132becc5443df14dd3f4feaee56d14b885c078649727b9659139fa6"},{"one":"b7cc9044d021b19cd8a6d290d21f1c91fd5deec472583d0aeed0a6aacc8efef9968079254132becc5443df14dd3f4feaee56d14b885c078649727b9659139fa6","up":true,"other":"842f0ac24370f14edfe72a7d07219de60fc767d2d0356fa6ce9d535a43647ad4bb17d9be75ed83542868ba430ec104ba168f27c16915cdbd6e57ae62d60707cb"},{"one":"842f0ac24370f14edfe72a7d07219de60fc767d2d0356fa6ce9d535a43647ad4bb17d9be75ed83542868ba430ec104ba168f27c16915cdbd6e57ae62d60707cb","up":true,"other":"7d9979c13cd8841e84e5d199fc263962ca6fee12664d8526a581bfcdca2e3427ca169b9a0244dd8292a9a1be2bcedb0e8f626eadd307068c11c03b6df13aee33"},{"one":"7d9979c13cd8841e84e5d199fc263962ca6fee12664d8526a581bfcdca2e3427ca169b9a0244dd8292a9a1be2bcedb0e8f626eadd307068c11c03b6df13aee33","up":true,"other":"5a235aca7005df295d5bd924b1272452e9bdad408ca5223b9eb76800b4bd4e3158a1d663ce5243fee92233227249fe4bb8507e8cb2c3729744b273bf488ba60c"},{"one":"5a235aca7005df295d5bd924b1272452e9bdad408ca5223b9eb76800b4bd4e3158a1d663ce5243fee92233227249fe4bb8507e8cb2c3729744b273bf488ba60c","up":true,"other":"c088bf88f1e152ca3fad17f098a71ca1021d46d8af12d0ee1c587a5e2a430d8e48beaf171fe01ee7680b671c00dd88c90f12a35c328a3f334661fdeee914a4bc"},{"one":"c088bf88f1e152ca3fad17f098a71ca1021d46d8af12d0ee1c587a5e2a430d8e48beaf171fe01ee7680b671c00dd88c90f12a35c328a3f334661fdeee914a4bc","up":true,"other":"77811b007dd1fc1b11e447858df37062e97b6fc14e059399814f3b4736188e3fb28bf7c3958bb8ebc6ae16c36884ba7c98b810fb6f8b358323412123c803abd4"},{"one":"77811b007dd1fc1b11e447858df37062e97b6fc14e059399814f3b4736188e3fb28bf7c3958bb8ebc6ae16c36884ba7c98b810fb6f8b358323412123c803abd4","other":"228b3646b15527f4df07b847a62dbf9620cb068f829e9086b5f437d0b64d8a027cab44f19db5e44189b5099545ecb25d49384c261748f9533cfb0eb11a1eca5f","up":true},{"one":"228b3646b15527f4df07b847a62dbf9620cb068f829e9086b5f437d0b64d8a027cab44f19db5e44189b5099545ecb25d49384c261748f9533cfb0eb11a1eca5f","other":"ecd217e8bdb53c9ef085929b8c2d2b40425a4be617a087b8e7f88e8507b3c981e90fda2119744ca394fe65bd4eb1cdd3fa7258db936048e236d2f15ee91bc3b6","up":true},{"other":"ab13f773f6f2ff73032aa5f79c8897b75dda29bcbb14aa511e9401c2417dc9c510253071e28c7833c8d62fd2aef16fcd0c14ce016fbf4fec1b9a2173c717603f","up":true,"one":"ecd217e8bdb53c9ef085929b8c2d2b40425a4be617a087b8e7f88e8507b3c981e90fda2119744ca394fe65bd4eb1cdd3fa7258db936048e236d2f15ee91bc3b6"},{"one":"ab13f773f6f2ff73032aa5f79c8897b75dda29bcbb14aa511e9401c2417dc9c510253071e28c7833c8d62fd2aef16fcd0c14ce016fbf4fec1b9a2173c717603f","other":"b60def37233dbbc0d5f7fcddb304be1c0b6508e1e3d8a09a8290f7363e9bb84152dcaf70b8f6bb3a882fee77ff03ab796a5c1c3654f251c9f5c746ac5ad88556","up":true},{"one":"b60def37233dbbc0d5f7fcddb304be1c0b6508e1e3d8a09a8290f7363e9bb84152dcaf70b8f6bb3a882fee77ff03ab796a5c1c3654f251c9f5c746ac5ad88556","other":"dd3dccc1758765569905b3b137ef4c7dd31c2dc0dea827bcc4c4e976be94ffbb0f2ef6fe725cf9042063a96d663efea546837f35ca1fc67a854fbc9e27abb754","up":true},{"up":true,"other":"936fad959da2d8b0cfb2bcd78c5da65bcce5e9463be7fc7367f45cdfa20678f4c466fb1e3f600783a270855fd4b9cd6265054f79ecb116141e7c67a492041bed","one":"dd3dccc1758765569905b3b137ef4c7dd31c2dc0dea827bcc4c4e976be94ffbb0f2ef6fe725cf9042063a96d663efea546837f35ca1fc67a854fbc9e27abb754"},{"one":"936fad959da2d8b0cfb2bcd78c5da65bcce5e9463be7fc7367f45cdfa20678f4c466fb1e3f600783a270855fd4b9cd6265054f79ecb116141e7c67a492041bed","up":true,"other":"6a55b94c9990249b24cdbeed96f065137f7b79ea8ee5f58da150d3962dfb62ba401960a53e7e8bd4e2c2908aa1a59b9d5efb4aafb316a9ab4fa67a0d95b58c54"},{"one":"6a55b94c9990249b24cdbeed96f065137f7b79ea8ee5f58da150d3962dfb62ba401960a53e7e8bd4e2c2908aa1a59b9d5efb4aafb316a9ab4fa67a0d95b58c54","up":true,"other":"a25958cf192a4f62301feda5d442535f78b983dd9e4599354f4898c8c1e6ad97ca7112549e1d1a1eacb4682cd1bf8b762368b5905ab33dbdacb585b128514ca1"},{"one":"a25958cf192a4f62301feda5d442535f78b983dd9e4599354f4898c8c1e6ad97ca7112549e1d1a1eacb4682cd1bf8b762368b5905ab33dbdacb585b128514ca1","up":true,"other":"ef7157fdfe62390d8a6d4ef976478d17465b42b63fddb03664973d63efb62318a8f59e412150528a32aa2c028b9de6bc67f05e012b8c43d710032ad871bc27e5"},{"one":"ef7157fdfe62390d8a6d4ef976478d17465b42b63fddb03664973d63efb62318a8f59e412150528a32aa2c028b9de6bc67f05e012b8c43d710032ad871bc27e5","other":"1edeb91789b9aa996fea7a70964e0be33ee50acbe6d8f7d9d9fcf6dcf755dab6402637a610116f0eb716b19259429bdcced8bebc28ffa334387a430efc21b9b0","up":true},{"one":"1edeb91789b9aa996fea7a70964e0be33ee50acbe6d8f7d9d9fcf6dcf755dab6402637a610116f0eb716b19259429bdcced8bebc28ffa334387a430efc21b9b0","up":true,"other":"222d7a2f94dc82a09fda70b8195fc3a60433a90f53998872318c57625c528c90572d78b444ac4901dcfece1a03ef8b6cbe7845366a845a942f341f6db58a9b3b"},{"one":"222d7a2f94dc82a09fda70b8195fc3a60433a90f53998872318c57625c528c90572d78b444ac4901dcfece1a03ef8b6cbe7845366a845a942f341f6db58a9b3b","other":"3948a7a939b9a1f4201953bd9b955ee7be87d09b63c7a45167f556ac06fe3c4c2a75d935bff50668da5e71e46802b55d7a9945a92d7807c00625d129cbb48f82","up":true},{"other":"dd6acfd151220f21b03701ca554a5e134dbd1154dda21d9eec45809e7858fe83eca3953fc688f499030198f22052c3681a9f49207ef9b11a760456ab9637352b","up":true,"one":"3948a7a939b9a1f4201953bd9b955ee7be87d09b63c7a45167f556ac06fe3c4c2a75d935bff50668da5e71e46802b55d7a9945a92d7807c00625d129cbb48f82"},{"up":true,"other":"0c9a05514b96e7c3a0fbca21552e158faa70047246b230addca172a5023fd7439acd1c3a0b4f9191579b308dab38c961734ffdb36fb8e16383e912d070fc0218","one":"58f9139905ae1d005950f110b7ead3355672ecc478e8c66393566c64b935003f6fec3031dc9eb21cda660acb1955cf7bb33a20fdd74d493f29868ace328fcd75"},{"other":"2751df9f64a8f2ff8ea45efc9bd02b281d963ced285260bcda7f9dfaed998fe4386fe65a7265876da6b4fee77ea5c12454869a70ad627da7ca888076fc629665","up":true,"one":"dd6acfd151220f21b03701ca554a5e134dbd1154dda21d9eec45809e7858fe83eca3953fc688f499030198f22052c3681a9f49207ef9b11a760456ab9637352b"},{"up":true,"other":"77e7d427b65b6c29c0d92c51184af73031bfa768a47fc20be6c264f422bf718865259c17c103bf47289b3abe62f93452781c6303d757e76d3d56ceeb26262fab","one":"0c9a05514b96e7c3a0fbca21552e158faa70047246b230addca172a5023fd7439acd1c3a0b4f9191579b308dab38c961734ffdb36fb8e16383e912d070fc0218"},{"one":"bc0df855bdadcde3e447415444f655eb430925a8fa81cdcac75909e7d79750f01827938570e75e388cc7058ba8ebca47afadf8b07172bc078488fb618ba71024","up":true,"other":"884d32d09dfef937f3ef1cd6fb5f530c2c574487c0ffd4185ca405c8b2ac73044a196c34352e850ce15321eec6579da654a696381f3e5830d03c7aa18923da6e"},{"one":"77e7d427b65b6c29c0d92c51184af73031bfa768a47fc20be6c264f422bf718865259c17c103bf47289b3abe62f93452781c6303d757e76d3d56ceeb26262fab","up":true,"other":"fee3fa1ba2a051d40a582908384ee81179db6c2b5f4bfa58c24f8015b794b43a093ed68b69bb209684135f972a055a9845978fa1b7d489e2126c3b514297f1c2"},{"one":"4b332b389f1142c0da42aaeb2e2692081d0002de0eb6741b3269e898a8101571d4556b755f2e8841e7a607bb41e398d2b0577fbe71098e7097f0fe6c720e1526","other":"0c82c4b414375479375703ed9c19fb08c8143229ed4f1dcf448c6cf313810c098905123bec17969276936ae0cc39ed251b2811dbffb551d61159862b0eac0a23","up":true},{"one":"2c976b6007cda135444233c7bd03d22ac9756710b746c36bc032e7fdd42f2ffb89ca5f5e754ff96b8f3cbc474e346287e5b8531d9f98fd63c426c632872220af","other":"c6ad9b9de5cdbe28540f4eb7c66fb37f6d4295e6e60c6de54e2a45c1970b8e0047558e986bbd10e9e86c8bb0407846fac4823e4570e8a1486fc4bf55cb4a0986","up":true},{"one":"4ff2981a47da46c753090e193a8bf43c3372a6b07a37cf0552de2ced455fbb8a76d969cd97b3e4601d8a808bd2a73f7729ed8a61df2f2a0c2cee1425d0bd9ab4","up":true,"other":"6909a0fa47718cfc463b1e96c21734b46bd5b28dd59cd3d66d67990783436b7538ab2659d427029b97c8dddf313b26532518c0c34a2b1fca8cd852b0fdb83ab8"},{"other":"8f3e9102306a13adb91e01f7a847e7880054f1a7df8976d05facb3a8fb37d47cce04f25e18a19713e5c3da7541e96e829fc67c8b924b717d2d9586c9c12d4fcf","up":true,"one":"fee3fa1ba2a051d40a582908384ee81179db6c2b5f4bfa58c24f8015b794b43a093ed68b69bb209684135f972a055a9845978fa1b7d489e2126c3b514297f1c2"},{"up":true,"other":"a8fac88fba179fb9b259d94caac9cbe45d873a0131bef8844ac4383b177daf6f301f8793623fec5876885db1a91e5b3e98e2aafdaa47e03b1f6d9740f48af7ac","one":"877d17ec7e95998ead831606d3363fbff1c8d1fa377b8e621e6a876d2c7776b9af356211a7e4df66adeaf38cf9b49c04871e8804edde4c18435ff45e110ecb04"},{"one":"6909a0fa47718cfc463b1e96c21734b46bd5b28dd59cd3d66d67990783436b7538ab2659d427029b97c8dddf313b26532518c0c34a2b1fca8cd852b0fdb83ab8","up":true,"other":"b9c7b885430b9b1a4425bde30b3629559f5437e0e30a0299fc6f6e097cbcca8af9e285caf5dea685a0237f60e06f490c39a1e3e487f14a2b9f41a5135f2ba994"},{"one":"b183f12f3602bfdab0480cb0b0ba7dc69b267b0dbc7e54c316741cb78b9e99aa69fd321ad7755d095e9be14e6bd90fe14ef8fe9bafc1a0dea10a144795021a08","up":true,"other":"212a8048ab9925171475e81dce047865df186222d673d524c810a9f613e4a21f3b130fa34c5f44974fbeaab1f6028177e71568e00a1184d9fd05443c172f5fcf"},{"other":"2bea7540c99456ea889a8ba2e448c11e6257bf987d01f13eea48128ba58577ab0936855035ee140c9907e382a34ca85a179c74892cbd9eb92fc2b35601addc6b","up":true,"one":"a8fac88fba179fb9b259d94caac9cbe45d873a0131bef8844ac4383b177daf6f301f8793623fec5876885db1a91e5b3e98e2aafdaa47e03b1f6d9740f48af7ac"},{"one":"b9c7b885430b9b1a4425bde30b3629559f5437e0e30a0299fc6f6e097cbcca8af9e285caf5dea685a0237f60e06f490c39a1e3e487f14a2b9f41a5135f2ba994","up":true,"other":"da22fb43c6d230d92f9c09454e282dc45dffc759740566039f1bdfb58171c6801f721841de83217277b3fb70983e7d34da53bbf25d1d45413a78d9afff151826"},{"up":true,"other":"99a7649bdf2ee7f0bc049308b0997e33abb68481c05a573df9aea30da5a1f267df07b2c584e3e985baf31704f04ad2a2c4876e0f8555333be6d09f5080b583f1","one":"af9b80f6836113aeda897d6903e9ffb4f7f1a706a7f821d0d40f03a0d83c18d6a19795ee4bfc1093ada04014415b1f230db1d2f056df3f5027cce71611588046"},{"up":true,"other":"81dc656de121016bcde81d5bf7919839acfc180dfbf1a6de2cadf704ff13af98aa5715a4168832ca6f651b2ea7ad9e6ca5f1c1cb7e885dbc2eb23d4aefb87bd6","one":"be93fafaf43f6bb3efd2667d1468a8636cb752b245328eaa01468c0606d790322a7cd8e47857068e60118e28b8dd8aa1d2d4977c5b3d28d4b47f4c0658f05e90"},{"one":"da22fb43c6d230d92f9c09454e282dc45dffc759740566039f1bdfb58171c6801f721841de83217277b3fb70983e7d34da53bbf25d1d45413a78d9afff151826","up":true,"other":"588df3185f63a5443d8c6b972f67805f0557184d916005f537a4b27cd02bd6a12e432a2b34b234a34f22e923c6f116da85be20bad77a2bf69913684e9d0732ba"},{"one":"b1dd1b08975319030626aab821032a0c687a103ee8942e8a2e2cf029dd72832a49630e78d2d8b184579f22178aca0e875f9fad701fb81afd2ac110ab2b417376","up":true,"other":"93073da602d6326a48464a8b6890220b3aae0abf5b6961180f3aff2a14573c43411bd519d3e0012a646ec2977be18915d95a36d935a69f93985f5307ea4e3ebe"},{"one":"a48cd04cdc66e1bb182529a789e1417d60d5e7d0f73068c1b17c6f231defeb943357789123e8d89cad90d1dd1726c48b808300d213bc1ddf7ae43cd58527f1f3","up":true,"other":"e8a679f627d03347a4fcec0a0940f7ffa90ce3fefea290db3af4f3a32d27965bfb51832b6a6de2495c8a8cc026bcf993b84a0cced778e158bb81c034f5e4bd76"},{"one":"588df3185f63a5443d8c6b972f67805f0557184d916005f537a4b27cd02bd6a12e432a2b34b234a34f22e923c6f116da85be20bad77a2bf69913684e9d0732ba","up":true,"other":"c29e80096fbe7bc9fcbfdbe3cf6c06449192a3ed280e46a1fa5d424428d893c3456c985c1352c119236cf783834365439751cc87e7ed196614705dd3db6674cf"},{"one":"93073da602d6326a48464a8b6890220b3aae0abf5b6961180f3aff2a14573c43411bd519d3e0012a646ec2977be18915d95a36d935a69f93985f5307ea4e3ebe","other":"431644cf162bc267237c4e798288888dd835c1b0546b0cc679782e33568988d75b4294f4aa08359a6b152ed9a0fbd13133681156bcf09a871c4f362615ea6dae","up":true},{"up":true,"other":"d43bd6d3ae39a04e4e144a8a6f80b2d54472b5b9b6491dccf44b1716a63d24c56e3a871b3b8fe983d992988dc07ace06736ead3b1287914b629fcfe17e81f36f","one":"d3cd2f34f67830ccdc295b7537a6d27c02b44503808ca666124f52ecc3d6c35b7d3f14343997006aef2cfbefc8d27809d389477e99c236b9f8a897a4bc406a43"},{"other":"8ee65c0937cdf860d5329132c34bf28b5dc4d2593986fae80e4b35efb54ec24cdbf294223515363a917a22dbc6db463c10c7484e22b479b9010059c2521b6317","up":true,"one":"c29e80096fbe7bc9fcbfdbe3cf6c06449192a3ed280e46a1fa5d424428d893c3456c985c1352c119236cf783834365439751cc87e7ed196614705dd3db6674cf"},{"one":"431644cf162bc267237c4e798288888dd835c1b0546b0cc679782e33568988d75b4294f4aa08359a6b152ed9a0fbd13133681156bcf09a871c4f362615ea6dae","up":true,"other":"c63b88f494b14d5a7c1da124ffebbd985d19806b91d4b111c83ae129c4ef19614469980a09fbeccebe3b0358dd16194bdb6452d0b3dbb43a5467e23bb13f40d6"},{"up":true,"other":"95ff4dea07303e1ba641a5c510e714ef232f4dbce9ad2e8b2f62644975eae41fc4bb9d1af3fae4d5ea4daeb18f8248e0b3131c7d843d35d33f3afbf7dfa4c2fe","one":"d43bd6d3ae39a04e4e144a8a6f80b2d54472b5b9b6491dccf44b1716a63d24c56e3a871b3b8fe983d992988dc07ace06736ead3b1287914b629fcfe17e81f36f"},{"up":true,"other":"5717a49591a0ecdff3d4449874d5ff9ba016afad5da19712ca0c8ebca8cefd84e6d8c778245f67f68c8dd730ad294fd017b8de279fde4fc919768ce85dba132d","one":"8ee65c0937cdf860d5329132c34bf28b5dc4d2593986fae80e4b35efb54ec24cdbf294223515363a917a22dbc6db463c10c7484e22b479b9010059c2521b6317"},{"one":"c63b88f494b14d5a7c1da124ffebbd985d19806b91d4b111c83ae129c4ef19614469980a09fbeccebe3b0358dd16194bdb6452d0b3dbb43a5467e23bb13f40d6","up":true,"other":"70cce7cb0c18091dbb6d41160ab560935f1759b969bf8118cee030ee707cb15ba407b8c48dcd9fd012cbf778e219f7d16a74064b4983cf098fb118297748edb6"},{"other":"b18c7131a319db61ab84d06e90092d93c91141e9a270630af9c3ab1eaf3bcad09f4d20a1fc845b21c994bf4d9e337d0bd756a75e2198097540355e7ebbb531b2","up":true,"one":"95ff4dea07303e1ba641a5c510e714ef232f4dbce9ad2e8b2f62644975eae41fc4bb9d1af3fae4d5ea4daeb18f8248e0b3131c7d843d35d33f3afbf7dfa4c2fe"},{"one":"5717a49591a0ecdff3d4449874d5ff9ba016afad5da19712ca0c8ebca8cefd84e6d8c778245f67f68c8dd730ad294fd017b8de279fde4fc919768ce85dba132d","up":true,"other":"224c3b969149d50d1bb4f473bb9725223c1dafe152efe1b08e8859213c543a66565b5d68a99cef3d5f4eccad6282a12f78d7b38eec14deebf44ad8dd9cba8680"},{"one":"70cce7cb0c18091dbb6d41160ab560935f1759b969bf8118cee030ee707cb15ba407b8c48dcd9fd012cbf778e219f7d16a74064b4983cf098fb118297748edb6","up":true,"other":"3376cfc924fef1a45aae35d106439b131f363b3a42904b3974cc7cddde325441cce8551729dd62f1119120b0d452e78f063e8e711ecacdc27d9087aac5ab09b5"},{"one":"b18c7131a319db61ab84d06e90092d93c91141e9a270630af9c3ab1eaf3bcad09f4d20a1fc845b21c994bf4d9e337d0bd756a75e2198097540355e7ebbb531b2","up":true,"other":"06aab75fed9a03f5525e3f1d8f8997fefaefd5b16e8f485d571beda00b1741efbb61a8a74fa12c2f6de66227c3fabb4d411659cd9c7b1ef32e171e6bf517cc39"},{"one":"224c3b969149d50d1bb4f473bb9725223c1dafe152efe1b08e8859213c543a66565b5d68a99cef3d5f4eccad6282a12f78d7b38eec14deebf44ad8dd9cba8680","other":"c61ffc88f23f9f536497cc10ffcb7000ec6c4b801998ae7075ddc9079fdc1da8350e68744dc9e95ff892dfc5e52c62a3ad913a87fdacc455aea99b09aa002b57","up":true},{"up":true,"other":"bab07c2e4dc09add884869b31fb474b6d7151f9cc331d831f55c2b088397370fb0a1e1592c8dff9c8bc8e83de9faf6e91683acfb2df1b41856d70e523a99d370","one":"3376cfc924fef1a45aae35d106439b131f363b3a42904b3974cc7cddde325441cce8551729dd62f1119120b0d452e78f063e8e711ecacdc27d9087aac5ab09b5"},{"other":"e5cb29b25debcfaaacc0b04e708c8c1cb9d2dee29e82596a1c72a934032cf738800b9525cc277d0c5f5dacf2f278329b54da161b4bafa285243fa0e9fd7b2f3a","up":true,"one":"06aab75fed9a03f5525e3f1d8f8997fefaefd5b16e8f485d571beda00b1741efbb61a8a74fa12c2f6de66227c3fabb4d411659cd9c7b1ef32e171e6bf517cc39"},{"one":"c61ffc88f23f9f536497cc10ffcb7000ec6c4b801998ae7075ddc9079fdc1da8350e68744dc9e95ff892dfc5e52c62a3ad913a87fdacc455aea99b09aa002b57","other":"c402495c2110a6531a530ebdcd9ab1b883f1c707fe25aa13a255a0a9edb4113669b4aee9eadf803f9fe4c2ef66d5e4dff7064549f672598410f2d9794747a600","up":true},{"up":true,"other":"52cf04f88d8b00214f11f329ebacca69291958372aa8ccfbe3cfdbc03d51d90389f3c307b82c108f0c074d78aeac0b48e8b8c8f3bf3b20b21d9747f284075de2","one":"ecb93d8eba17afe92979e8154252a08dd58de6ff3188b6829e3e25967846686f54199ab2b081e77b0048dcab204f05aa2c5cbd0efae4bc43a612d471d4e1197b"},{"one":"e5cb29b25debcfaaacc0b04e708c8c1cb9d2dee29e82596a1c72a934032cf738800b9525cc277d0c5f5dacf2f278329b54da161b4bafa285243fa0e9fd7b2f3a","other":"6c40910f0556f892a7542989fa01d7e3682fca89aeefb5ed885808f88ff17b6d13862f461c10d629a005ae67abef542d75e5b20816891b6944f71560f5c2dfa8","up":true},{"up":true,"other":"6ad4ea3730ddec500e56248d1025aea79ec10f0d6a9720ee48026df10e219b41965d7a611fd99ee765f6afbc8c977db7e67c3a340881904acb983d1e2fb016cc","one":"c402495c2110a6531a530ebdcd9ab1b883f1c707fe25aa13a255a0a9edb4113669b4aee9eadf803f9fe4c2ef66d5e4dff7064549f672598410f2d9794747a600"},{"other":"d6747e1f8594f7449fc6d7c0e63ee843480567d498db096ff04229420861c83bca5215fc19d8fede0c54484f111f1f2581e189e638c21c5d9e1fd3174bbb3e98","up":true,"one":"6c40910f0556f892a7542989fa01d7e3682fca89aeefb5ed885808f88ff17b6d13862f461c10d629a005ae67abef542d75e5b20816891b6944f71560f5c2dfa8"},{"up":true,"other":"a48cd04cdc66e1bb182529a789e1417d60d5e7d0f73068c1b17c6f231defeb943357789123e8d89cad90d1dd1726c48b808300d213bc1ddf7ae43cd58527f1f3","one":"6ad4ea3730ddec500e56248d1025aea79ec10f0d6a9720ee48026df10e219b41965d7a611fd99ee765f6afbc8c977db7e67c3a340881904acb983d1e2fb016cc"},{"other":"49256eccce3e036928a4b6b346126c6777dca5ea0134de85efca340f97ad0f827f3094f1562e3e186d35b8292a50c20ffae01409890bbb78598494285e14dc2c","up":true,"one":"d6747e1f8594f7449fc6d7c0e63ee843480567d498db096ff04229420861c83bca5215fc19d8fede0c54484f111f1f2581e189e638c21c5d9e1fd3174bbb3e98"},{"other":"37399617d62153bc471f3bf21c92385bc8602c80ffa0c71da8aebae595a9859cfd56257aae60ad30ef3ec4d07dee90623cce63749c8c3233c0aa0d17f9e89afe","up":true,"one":"6d0a09235ba0b0428938abf0e0782ac0ecf5697ef862888719a34fc956517aeef89d5e5f76d12e10067fee5bac8781dc10400eeb35c2393b9382b2a4f68f7939"},{"one":"49256eccce3e036928a4b6b346126c6777dca5ea0134de85efca340f97ad0f827f3094f1562e3e186d35b8292a50c20ffae01409890bbb78598494285e14dc2c","other":"869cae165389e7dee7b7df4e012ee1a39737366c306d8f4b0db4510b2236e0bd3a4d1d4af00b1a8c1d360e23da47de52fc1632edb03c7f1429aacc8aa4994750","up":true},{"one":"869cae165389e7dee7b7df4e012ee1a39737366c306d8f4b0db4510b2236e0bd3a4d1d4af00b1a8c1d360e23da47de52fc1632edb03c7f1429aacc8aa4994750","up":true,"other":"1b3107d9a96cfd11f4cd0ed8baeb7b23db1406c9c4a9dac76c772f49c0fc9404f6a4adae11120aa821757173f0cc1cb00e6ab555b5abffaae9001c0557cb75c9"},{"up":true,"other":"ee0b09ee6a1057c47102e582e2fdec7b9212802e59f062a9360da0db535d4987126ab24848c0d76fa8485431a5140307e2b0c0d9f37cbdb35756e6cc1bdb3bc0","one":"1b3107d9a96cfd11f4cd0ed8baeb7b23db1406c9c4a9dac76c772f49c0fc9404f6a4adae11120aa821757173f0cc1cb00e6ab555b5abffaae9001c0557cb75c9"},{"one":"ee0b09ee6a1057c47102e582e2fdec7b9212802e59f062a9360da0db535d4987126ab24848c0d76fa8485431a5140307e2b0c0d9f37cbdb35756e6cc1bdb3bc0","other":"243164c4dd583f80c50813f43e5c27c894463400cd3afd776b36e79e7123d9261f01f06f92914aab83096b9a43fb655e79687590599284640a3a7d2c25454597","up":true},{"one":"243164c4dd583f80c50813f43e5c27c894463400cd3afd776b36e79e7123d9261f01f06f92914aab83096b9a43fb655e79687590599284640a3a7d2c25454597","other":"e33a1476fcb8d2a1b9ee15871a960ce7a3337c93f5956a2825b1f8b2885dbdc0ed652b1eba549523866632b5b6898310bc638d946a9fcce27d65117eb44c25f3","up":true},{"other":"2b0a1f3a6466c6be1d7e84120db384fa37f7c73a01e9a105ae90e7d2203212ec974f016d3012afd26bc0f9a8411d0716cc59b6ecc9f665db12e306af8b34cb63","up":true,"one":"e33a1476fcb8d2a1b9ee15871a960ce7a3337c93f5956a2825b1f8b2885dbdc0ed652b1eba549523866632b5b6898310bc638d946a9fcce27d65117eb44c25f3"},{"one":"2b0a1f3a6466c6be1d7e84120db384fa37f7c73a01e9a105ae90e7d2203212ec974f016d3012afd26bc0f9a8411d0716cc59b6ecc9f665db12e306af8b34cb63","other":"7db14fde1da8794ae7ab5de37c9e2537e1024bc830c176c0d01635cafed47773d3a28e156db81ecdb95903222b900c3ebd4c4b3db2971dc0ef6a1e386027ffaa","up":true},{"one":"7db14fde1da8794ae7ab5de37c9e2537e1024bc830c176c0d01635cafed47773d3a28e156db81ecdb95903222b900c3ebd4c4b3db2971dc0ef6a1e386027ffaa","up":true,"other":"865dbf61d8511603fe0d9ebfb10792b9f6b798187c0909039bd9b2492c41e428876f386beeac86d0dea871f4fc24ba435f0fbd9a11e74c044024934592af14ee"},{"one":"865dbf61d8511603fe0d9ebfb10792b9f6b798187c0909039bd9b2492c41e428876f386beeac86d0dea871f4fc24ba435f0fbd9a11e74c044024934592af14ee","up":true,"other":"c0f233e79d0a8d4af01f54c40640975bc113f464271ba8922fca0c28acc60367af0db06629e701977e86cb5917c891e39c21418cab459fe49132b680aa31600b"},{"up":true,"other":"b8e0a56df21baae43058f575b714ae9a33c097d18f1a628b3b6ae5e86dd46a06e44c0dc272baacb5be0f7bf57fd6ddce107544eb3b94dca1aeae9f5773496a72","one":"c0f233e79d0a8d4af01f54c40640975bc113f464271ba8922fca0c28acc60367af0db06629e701977e86cb5917c891e39c21418cab459fe49132b680aa31600b"},{"one":"b8e0a56df21baae43058f575b714ae9a33c097d18f1a628b3b6ae5e86dd46a06e44c0dc272baacb5be0f7bf57fd6ddce107544eb3b94dca1aeae9f5773496a72","other":"b58b3e200f6072ddb38130944a01d2829c755b8bd1a08abd010d1bbf86dabd851b2c1ab4cb961451bd7e8499f6c7378830bcd27cde825846654853c172597bf3","up":true},{"other":"9309549fc50173d6826fe63cf18699f49199c3789616b843042fe1a6adab6ed4bdd7a7a06acd276e0398cf8bffb26c12a4227725d7bbd386a9a55fc601c21405","up":true,"one":"b58b3e200f6072ddb38130944a01d2829c755b8bd1a08abd010d1bbf86dabd851b2c1ab4cb961451bd7e8499f6c7378830bcd27cde825846654853c172597bf3"},{"other":"81901d9f043b4b1649ade3b5d22ae5f8bb42dd6db1eb37b836b99dd1c0388509ed4b54cc5638c9d4a6c5ae6c6913bbfffb303d7d94bf4ed50e871cf95459e2c3","up":true,"one":"9309549fc50173d6826fe63cf18699f49199c3789616b843042fe1a6adab6ed4bdd7a7a06acd276e0398cf8bffb26c12a4227725d7bbd386a9a55fc601c21405"},{"one":"81901d9f043b4b1649ade3b5d22ae5f8bb42dd6db1eb37b836b99dd1c0388509ed4b54cc5638c9d4a6c5ae6c6913bbfffb303d7d94bf4ed50e871cf95459e2c3","other":"2abb91884cc3a8fb91b2f2f369f9430f2b3b05c75ce6203aa7a50312c9f141f9d0f615063d3576a5ce8a4be9ecb942aa804a717f76d9e8dca03d115dcc43f775","up":true},{"up":true,"other":"ab1a3542d67ef9d1a63653990bf0782f53b0169fe5092adc92fa7aeb38f66c6b62d49e3455cc2ac4994bfcfb03111953acf4cc3099026672cc61f6e24cb3ae00","one":"9f3af4577308965aceb7e0101443669496e7ccf1de680629862a7005966c708b6fb52e6dfe62660246b9892adc25838da2873502e0be706bcad8f25b7ceedfa5"},{"other":"535287ca3d41fc1cdf20a964749a849c51d0aba285f41f447cc2b1dd6f5845b6b98e0241dbda0718b234ea850081bfbf9df01d1aa636d7dcbd99ef3c0a773aff","up":true,"one":"e8a679f627d03347a4fcec0a0940f7ffa90ce3fefea290db3af4f3a32d27965bfb51832b6a6de2495c8a8cc026bcf993b84a0cced778e158bb81c034f5e4bd76"},{"other":"29619924833116cb1160bf7a8066a528b7182794368bfae62b5bacbae680d9161a479f217e30c3b4f19a250b1b59e08f86c94726117dc3bc94ff9ceac6bee6e4","up":true,"one":"535287ca3d41fc1cdf20a964749a849c51d0aba285f41f447cc2b1dd6f5845b6b98e0241dbda0718b234ea850081bfbf9df01d1aa636d7dcbd99ef3c0a773aff"},{"one":"d09104c44648391693ca64a57baa5ef54ed717e19c65ad0a0921d08cbaca8877d0190795d15f75f3b6ce6e676d6b0e55d5ee8fec3310c68b7060a32f7ff649cb","other":"49215dfa786bfaa52b1e7aa6899392711a770b2504c82f536381fb1f18df16960257d75530efabf6dbd2b1361decc29758f870b318f777decf51f4833a9c1f00","up":true},{"one":"43086ff7ffd3c7bdec77bd288f41f1ee0ce21bd3f60a5df8931e2af6e7af5ef0fad432d29625491935d11567944351fc7867c807ebd12dd2c21c9e620ae0f85c","other":"f98c0f4444a1ec80773454ddb691c226b81d8e2f79ed40c45a422d3359565edf7bd635d3eb7bd6c9e0870746849fb86f0b1b34cd56ec8d3ad969812e080f4983","up":true},{"one":"29619924833116cb1160bf7a8066a528b7182794368bfae62b5bacbae680d9161a479f217e30c3b4f19a250b1b59e08f86c94726117dc3bc94ff9ceac6bee6e4","other":"624248a794fd62248024360f128b2e503c752340694a316bed420e5ed2cebeb5bf970df95a2806732237a26de3778222b0454e2e7d2875129b193e7890fd5b95","up":true},{"one":"855667650e96c5ed2d9b0c82532ed1fb92f72b1ae926afafe09cf8f6e90e539aec5c4c2ab108f2c2a1ad7dd8b83ca92a98c550a1c9ed27e6632a7d2f6da4f970","other":"57085f756f76644cdd2148524f2334d869ef0ab2fcbe7fb11f5d22bc1f5023165b11526ecc85ff9cbb88877386af9b148d7ef15a825b3a586d16c01bdfc86692","up":true},{"other":"2c976b6007cda135444233c7bd03d22ac9756710b746c36bc032e7fdd42f2ffb89ca5f5e754ff96b8f3cbc474e346287e5b8531d9f98fd63c426c632872220af","up":true,"one":"37adbfdf66163e45f433d78f63210163fdacf4688ad90d73bed07975be017c43cddf2a26a0dee8b11d78f294b63d4875b6be15f42f10817bd3d77b342919a11e"},{"up":true,"other":"50c79baa3e6781482ccb5e960c699dd9c13f479467c6315c5292a396337cf3619e7faba1971a1f470051cb9042f80ea6750defe3936b72aac4d9bac6f8368c67","one":"3e2241cdb9f34c1d2c6930e59940e2c4b92b0287579d7263a620a609c5e66dca6d85df48cf1bffd63663a6704c42d0866aae3e484fd9a44b6a012f72dd3cef6e"},{"up":true,"other":"48e35d67e14ee2f329c0275bc965829b761885dbc3671f4673d84d76d18a5b6415e619e219b5d90761a5c6bd2f43c6a58708286a063daf46b502944f8ef9230b","one":"52cf04f88d8b00214f11f329ebacca69291958372aa8ccfbe3cfdbc03d51d90389f3c307b82c108f0c074d78aeac0b48e8b8c8f3bf3b20b21d9747f284075de2"},{"one":"8f3e9102306a13adb91e01f7a847e7880054f1a7df8976d05facb3a8fb37d47cce04f25e18a19713e5c3da7541e96e829fc67c8b924b717d2d9586c9c12d4fcf","up":true,"other":"b183f12f3602bfdab0480cb0b0ba7dc69b267b0dbc7e54c316741cb78b9e99aa69fd321ad7755d095e9be14e6bd90fe14ef8fe9bafc1a0dea10a144795021a08"},{"other":"af9b80f6836113aeda897d6903e9ffb4f7f1a706a7f821d0d40f03a0d83c18d6a19795ee4bfc1093ada04014415b1f230db1d2f056df3f5027cce71611588046","up":true,"one":"212a8048ab9925171475e81dce047865df186222d673d524c810a9f613e4a21f3b130fa34c5f44974fbeaab1f6028177e71568e00a1184d9fd05443c172f5fcf"},{"other":"37adbfdf66163e45f433d78f63210163fdacf4688ad90d73bed07975be017c43cddf2a26a0dee8b11d78f294b63d4875b6be15f42f10817bd3d77b342919a11e","up":true,"one":"37399617d62153bc471f3bf21c92385bc8602c80ffa0c71da8aebae595a9859cfd56257aae60ad30ef3ec4d07dee90623cce63749c8c3233c0aa0d17f9e89afe"},{"up":true,"other":"d09104c44648391693ca64a57baa5ef54ed717e19c65ad0a0921d08cbaca8877d0190795d15f75f3b6ce6e676d6b0e55d5ee8fec3310c68b7060a32f7ff649cb","one":"7958d1517de1223e7fb30acf61d8618e49fb95a03bc2f49141f4c7967bc80b90e0dd526c205639de3c060029963d43813293c2556f7b127945c798f3f9f18626"},{"other":"be93fafaf43f6bb3efd2667d1468a8636cb752b245328eaa01468c0606d790322a7cd8e47857068e60118e28b8dd8aa1d2d4977c5b3d28d4b47f4c0658f05e90","up":true,"one":"2bea7540c99456ea889a8ba2e448c11e6257bf987d01f13eea48128ba58577ab0936855035ee140c9907e382a34ca85a179c74892cbd9eb92fc2b35601addc6b"},{"one":"0c82c4b414375479375703ed9c19fb08c8143229ed4f1dcf448c6cf313810c098905123bec17969276936ae0cc39ed251b2811dbffb551d61159862b0eac0a23","other":"877d17ec7e95998ead831606d3363fbff1c8d1fa377b8e621e6a876d2c7776b9af356211a7e4df66adeaf38cf9b49c04871e8804edde4c18435ff45e110ecb04","up":true},{"one":"99a7649bdf2ee7f0bc049308b0997e33abb68481c05a573df9aea30da5a1f267df07b2c584e3e985baf31704f04ad2a2c4876e0f8555333be6d09f5080b583f1","up":true,"other":"b1dd1b08975319030626aab821032a0c687a103ee8942e8a2e2cf029dd72832a49630e78d2d8b184579f22178aca0e875f9fad701fb81afd2ac110ab2b417376"},{"one":"f98c0f4444a1ec80773454ddb691c226b81d8e2f79ed40c45a422d3359565edf7bd635d3eb7bd6c9e0870746849fb86f0b1b34cd56ec8d3ad969812e080f4983","up":true,"other":"baa28b8cb7ec539e0e157d7598cc5a5b0210fd8fb5c9026c3cd612133c5a8ee56997507511928af5683cb620fd85593dd8f6ff882d95fb847870ae4ce7dc503b"},{"up":true,"other":"a58a4db7a96b1578935b222c78b7b4dd8b3519d2995c3616e5a154c5175242a503097771332504638a0b321b9574110207f9a7d77b109d1de3d66a12ec6498e5","one":"7cc9389c8f751465e0b94baed896f6f122631052300b1b5b23d3c7656e4d11014a7a9ae62a1287bb040ca37221871a566cd470e523846df7e3acb5f94c7cde06"},{"up":true,"other":"723f362e98f90d7ef15e24e353759fdbdabb08adab767dba73ab546741fac3dfb457466f1e2c851aa49526da1408f8ddb509e12f7dc0bc1e785c5b72be8a986e","one":"49215dfa786bfaa52b1e7aa6899392711a770b2504c82f536381fb1f18df16960257d75530efabf6dbd2b1361decc29758f870b318f777decf51f4833a9c1f00"},{"one":"f4cdaeb513aa98f8868d8eb3a1d12c07367725928a1bc7d6ca4b583788e111a955463037ec7867260511896d97dfbf096aa77ee8a7d9ea1c06cad4a92c45108d","other":"1c080e90760dfcee08ade6e4ea3b275ff3c6882f3b44b7f3a73d70bcc816fc63ce0b6138f810d17d96ed387076f9bbb6dbb2ef6dc4d6ba6542c1f587b7602a12","up":true},{"one":"8c459100df488b992fdad207a096a434d67cb733619adfd09a311095568d4c9db293d9a892675551805559456d49a3fdb19c2cc698b14552bf0ace584d4d90dc","up":true,"other":"c2a9c77247871cfa4d3c2d1b47619df91ed5b331a44c8e21f7c9ce431a4db9dfb87713558cc8a37911393907b4cc60be9445bad18adcea1bc5f318256e71be14"},{"one":"5a6318af8b4615cf30610a05ade7704182fefd0a3fb3d76c47cb392e114d8d30004f0ec214326b11532fd1e928e66f632bbcde126a94c87774063853a9518dc5","up":true,"other":"7dd2801259c071a6e1dcc01d1cb74775fdec92da1da0b1eaf5f893cd5ed118894493ca5284c12bbd6cf7959449bc610d26ac6c9ef2845d1645d425f56ac003fd"},{"other":"a47697063a2fb973449bdabd0925e10944ba1f6d8b2cc5c38b295f611eea3402b5cf3ae857716a34d84194955f5ed61350affe56223349124c8233852141f9a2","up":true,"one":"7dd2801259c071a6e1dcc01d1cb74775fdec92da1da0b1eaf5f893cd5ed118894493ca5284c12bbd6cf7959449bc610d26ac6c9ef2845d1645d425f56ac003fd"},{"other":"28cdd55fc871ffd8d63d05994be706959c9780dbfc859070a41047a1b40dd5fd7adb53919400a4c6f4d06c69bc1ecccc0e230e5b702598a7fe8003a282479872","up":true,"one":"fc9b1b2bbd5e682eb350d23f3ee33b245495daedae9370de7b1f55f91cd45db831d196c17615e11decf6b67696a268ac788130e3de38c7f6aeae811f3ec8c8ee"},{"other":"9d372d73848389cfa1676f0cdb030950980ed5b68d5b2ef8a058f1d2095b26ff0fafab5fd3c243296ee2620edc67752970ab47370270856287f8612d1b190a19","up":true,"one":"c0a2c08fa8b70ecbf1932254945d5f689b0da7a287019d384152f383f6229acd4d82eef26205bc12e062dae4569814bd1c996ee4fe5886bd6bdd93c4f0ac113a"},{"one":"51df4f4d4f020f22f55a5fd00c7f9c68c232c167ae4d4e80d7695f8f39c5aa0a7b565c1c55bdd6a21e06fa056549d08fd2e9d76fd79e21295557aa30d1ae022c","other":"b4f300abda4cf6e383f997510eb681e9fa62e23577e3c19bd7447fa1f5702a4e034cea5944248e7c6e6e92b5ae69195c3e8a2c5ca7827b4f4a00cc8546e6695a","up":true},{"other":"4b332b389f1142c0da42aaeb2e2692081d0002de0eb6741b3269e898a8101571d4556b755f2e8841e7a607bb41e398d2b0577fbe71098e7097f0fe6c720e1526","up":true,"one":"2880e0defd1bf2665bdd20dfb46bc0a9ad707f495211fc78e611ab479d78398db7daff7d3f4b6bf81fd13bf766ecc8271e0ea99a2d74abd2f9ddf98835ffdcf1"},{"one":"28cdd55fc871ffd8d63d05994be706959c9780dbfc859070a41047a1b40dd5fd7adb53919400a4c6f4d06c69bc1ecccc0e230e5b702598a7fe8003a282479872","up":true,"other":"d7e3661c0af6754c875217f93d34b254f1f45fc1359a4c6146cd0efa4c6e12aed9a4fb0a21a136f73af4fc2c6d0a63cb809d81855bbc9f51e29d23d90f77b326"},{"one":"9d372d73848389cfa1676f0cdb030950980ed5b68d5b2ef8a058f1d2095b26ff0fafab5fd3c243296ee2620edc67752970ab47370270856287f8612d1b190a19","other":"b152eb30c9f46ec39166016f03d289f98cc285ac62d204da32e5a003da14e4f02c64df8ae1d0c8a2a902adc5f7dd7604081a0b140c9b64052082f0861945f5a4","up":true},{"up":true,"other":"e993be8034861aebc9bbd11115f25d9c719d43fcdefc323599616cc26240cee38dfc27bb7f339149a54a3c9ad13b2d6ca4f0ae690e4355605eda6b789c4a431e","one":"b152eb30c9f46ec39166016f03d289f98cc285ac62d204da32e5a003da14e4f02c64df8ae1d0c8a2a902adc5f7dd7604081a0b140c9b64052082f0861945f5a4"},{"one":"d7e3661c0af6754c875217f93d34b254f1f45fc1359a4c6146cd0efa4c6e12aed9a4fb0a21a136f73af4fc2c6d0a63cb809d81855bbc9f51e29d23d90f77b326","other":"3f322f9b1f1f0692663bc3be11cf11386f4a14696aab610916cfcadf0234cce0c86b51c85ce2108e9bc21d50ad71cc10a6eeaec3fc7732908f3a8b193465a0ac","up":true},{"one":"7c6e6a49429a4e24aa4aa5c7ba19684f77cd67d3744688baff6e7f1d74b7e9d2df85f3e57e0df0a9b960b5bf982a610c5639c3e7a6935ba13fbc77243b2dad19","up":true,"other":"9ea856ea440c776b9ffaad1237ec11d570a1f912a908b8363ff97cf7947d2523e3c73663240d8fac988698cdd81e877ddd4a609485fe9f26494136fae14212df"},{"one":"3f322f9b1f1f0692663bc3be11cf11386f4a14696aab610916cfcadf0234cce0c86b51c85ce2108e9bc21d50ad71cc10a6eeaec3fc7732908f3a8b193465a0ac","other":"7c6e6a49429a4e24aa4aa5c7ba19684f77cd67d3744688baff6e7f1d74b7e9d2df85f3e57e0df0a9b960b5bf982a610c5639c3e7a6935ba13fbc77243b2dad19","up":true},{"up":true,"other":"c9d705012a06d82c4d44db95b4f1c63ddd33ad64d732e96b1d878caa0caac433d4096f01495a6f0e8a56af122b0470fd745db6d906353b590a4710472b93f5b2","one":"a070b5cff5eff533a2267ceb0d88e221088038af773e18f80110c8a2c329f0543b8d43c4e6132e9416723e3e94c87f0053456760ced4426767b95cee36ed93f8"},{"one":"2cb076669efbaf2ff0b181a1b454061a31ef23937a40405022b126f0eb4bfba60c9e3397009d8c0ff0cabb603692532d0072c18c6838f43397c98483306f62db","other":"643da2591098f9698f27cccf7c17832e0717ee6a1276398a1a29edc947125585dcfab9417c2721a8a55d4dfc75b826be7581b6e30b020f6341ac549877c9f122","up":true},{"up":true,"other":"a070b5cff5eff533a2267ceb0d88e221088038af773e18f80110c8a2c329f0543b8d43c4e6132e9416723e3e94c87f0053456760ced4426767b95cee36ed93f8","one":"740919ebae9b4fe646ca716ebb8923bf2a1b1963767d86f55ea95911d88d163cc2e07b1420669e64b62cb267b625413444b783b8e4a7bd6a0f481f4d84e984b1"},{"one":"5d002c37b74a6656db86f102b0cec82bc35a819a480e5a2952db0140ebab65dffeb1a79f04d53ff61447b5fad7c58cb75ea1c91ea47fcb9e024f27b92c6c874d","other":"6a37e63feed9e68c52cb8b385d5e8d8dbd2b211c57ded0d3b01fe8b306af5c0e5a7405d0d9a942648f0131926240d53450bc43f922a053528e5830d918313c3d","up":true},{"up":true,"other":"f5d95e0c5a873ff5a95e1eb34f1ed258d77adf98ee0886d93c4a24b1feaf6955e6e4c4ea0eccb2b9723870bae61e693643d6ad96dd8da01672542611f7c49069","one":"6a37e63feed9e68c52cb8b385d5e8d8dbd2b211c57ded0d3b01fe8b306af5c0e5a7405d0d9a942648f0131926240d53450bc43f922a053528e5830d918313c3d"},{"one":"15ceb62ee0f53379aa202950634ed881ba3b7bd4b46c80723ee48190079311e24ffaacb167a126a40bd6732c384f3c26163aa043edca03cb52a97b6da189aec7","other":"154d5ddb15ec12dc65362039d801383c189b5bcf6688883f2d7e3d0e8dc78e45f9f58d5dabc79a8798a243ce59abb95c77525db14f050fd8cb37d04b7276557c","up":true},{"one":"f5d95e0c5a873ff5a95e1eb34f1ed258d77adf98ee0886d93c4a24b1feaf6955e6e4c4ea0eccb2b9723870bae61e693643d6ad96dd8da01672542611f7c49069","other":"bac3fd2ea491d8e4ce1e5d469ec73f3d537d61279ae66e7a394b20a188244a886d3059ef0d304c0801878f9640374f7c8aaf56558c41f12296d3fc7f911ed66c","up":true},{"up":true,"other":"c2568576c2c9ef47aca0baca52709a4fa44b2ed478a062f7b161fac2bdba68568df371ac7754255fd07d79bb9918249a914946a6c318d579730bee9bc609922a","one":"46717bc5fb7fcbcdc961e7ef091020f9f222858cf3d4afcc0b0bb1b782b7055d9eb833e0a04cb32d80406133ac77162521c43edf9f9690872222760e31462ccc"},{"one":"f056acbdf491d1bb091937335c10096ea44b7034e994d134bc16d55212ff049bb097424de96c615ea699359a7ef77b3b54def2b3a5f43d735ffda65f73d61f7f","up":true,"other":"b87e7f36ed6bf142d48545024d2fd6e120c44511701e7c0b7d7fc786f4f29d3357024b15f70b78215d8a4c2b7572d608c11b31612743e23db4fa673f0cd6519b"},{"up":true,"other":"740919ebae9b4fe646ca716ebb8923bf2a1b1963767d86f55ea95911d88d163cc2e07b1420669e64b62cb267b625413444b783b8e4a7bd6a0f481f4d84e984b1","one":"154d5ddb15ec12dc65362039d801383c189b5bcf6688883f2d7e3d0e8dc78e45f9f58d5dabc79a8798a243ce59abb95c77525db14f050fd8cb37d04b7276557c"},{"up":true,"other":"15ceb62ee0f53379aa202950634ed881ba3b7bd4b46c80723ee48190079311e24ffaacb167a126a40bd6732c384f3c26163aa043edca03cb52a97b6da189aec7","one":"643da2591098f9698f27cccf7c17832e0717ee6a1276398a1a29edc947125585dcfab9417c2721a8a55d4dfc75b826be7581b6e30b020f6341ac549877c9f122"},{"other":"33cac8f621b9122e118036154778d27dc419b6b58ea2e89b833f3932f411dbc3511d92b55ae4cf80632142bc8e67994899aaa30c499d0289fae85b12564cf01f","up":true,"one":"bac3fd2ea491d8e4ce1e5d469ec73f3d537d61279ae66e7a394b20a188244a886d3059ef0d304c0801878f9640374f7c8aaf56558c41f12296d3fc7f911ed66c"},{"up":true,"other":"2880e0defd1bf2665bdd20dfb46bc0a9ad707f495211fc78e611ab479d78398db7daff7d3f4b6bf81fd13bf766ecc8271e0ea99a2d74abd2f9ddf98835ffdcf1","one":"884d32d09dfef937f3ef1cd6fb5f530c2c574487c0ffd4185ca405c8b2ac73044a196c34352e850ce15321eec6579da654a696381f3e5830d03c7aa18923da6e"},{"one":"c2568576c2c9ef47aca0baca52709a4fa44b2ed478a062f7b161fac2bdba68568df371ac7754255fd07d79bb9918249a914946a6c318d579730bee9bc609922a","up":true,"other":"6b104eff1dcf58d11a7f707bbd41a910b2735b262c29e0f4e4127fda1b67def4e89b6ebc1b3cc1e06c3968d0898e1085badc7da24d3cd6624cb100e85863cc97"},{"one":"6b104eff1dcf58d11a7f707bbd41a910b2735b262c29e0f4e4127fda1b67def4e89b6ebc1b3cc1e06c3968d0898e1085badc7da24d3cd6624cb100e85863cc97","up":true,"other":"3e7aef8260c0d9717aa59b65ce7c554e53b81f19f5b9400321704a7ddf5041b0fe31b5634e90b93e6984060defee0e153997bbfe196166cc8d83165fd5eaf41f"},{"one":"33cac8f621b9122e118036154778d27dc419b6b58ea2e89b833f3932f411dbc3511d92b55ae4cf80632142bc8e67994899aaa30c499d0289fae85b12564cf01f","other":"f056acbdf491d1bb091937335c10096ea44b7034e994d134bc16d55212ff049bb097424de96c615ea699359a7ef77b3b54def2b3a5f43d735ffda65f73d61f7f","up":true},{"up":true,"other":"488854534ec5a3479d8ee13d9b7daf07479f6b5505f319eced44dad8c316f6ff241ce2101e95608ba635067f5e5741481b78f419c4bbd465bf7e837dc4e54d64","one":"5319bc9864d87eb33f26ff9732824d21a0a5ab70b254bc70a47554ffc763ae1559000d07e3eac9f883bd9e7f249d80edf14ab39c89c375bfcc5ec9e840ec9673"},{"one":"3b71a324bd7b1a8fb19d8206eea1ca8190cb1faf5fcd1bfc52cef6b52296fe1db3e54d70180133fad1fa1188499d0dd73d2d075fdc6b3ffd9042d690e7d88e02","other":"45d3827eb5c3b906fc61aaad79c5968f3dcf7b1ecc1e3be63e827ad6fb9291542686f42b3e142f43cc0437a2177b7362727842ea1d6c33bc795d936bba3ae457","up":true},{"one":"10551c0c37abc25457903978868dd4843a52fda5f9b571b05ebd974d8c381fda4349f17c2b986a2e4b8d06b0517422f085d5f6d9cd814efa40e48393d9f71d7e","up":true,"other":"c0bec7375c66bec98524ade2245c1d7480516fc5d87a3249e64ec86418e80e202f1e3da76832e97bbc3dcaed8c96ca344e4829347b4428f4b1cb61999e404c05"},{"one":"4ff2981a47da46c753090e193a8bf43c3372a6b07a37cf0552de2ced455fbb8a76d969cd97b3e4601d8a808bd2a73f7729ed8a61df2f2a0c2cee1425d0bd9ab4","other":"b9c7b885430b9b1a4425bde30b3629559f5437e0e30a0299fc6f6e097cbcca8af9e285caf5dea685a0237f60e06f490c39a1e3e487f14a2b9f41a5135f2ba994","up":true},{"one":"fee3fa1ba2a051d40a582908384ee81179db6c2b5f4bfa58c24f8015b794b43a093ed68b69bb209684135f972a055a9845978fa1b7d489e2126c3b514297f1c2","up":true,"other":"b183f12f3602bfdab0480cb0b0ba7dc69b267b0dbc7e54c316741cb78b9e99aa69fd321ad7755d095e9be14e6bd90fe14ef8fe9bafc1a0dea10a144795021a08"},{"up":true,"other":"fd0123c7b96004067e98e463e273de5bc5402399ae70a95985b5f682e30d4f35d070deaf8c71d201e98c4324d832b95aab7535ad8a2658f66e3e0bb1202204e1","one":"57085f756f76644cdd2148524f2334d869ef0ab2fcbe7fb11f5d22bc1f5023165b11526ecc85ff9cbb88877386af9b148d7ef15a825b3a586d16c01bdfc86692"},{"one":"45d3827eb5c3b906fc61aaad79c5968f3dcf7b1ecc1e3be63e827ad6fb9291542686f42b3e142f43cc0437a2177b7362727842ea1d6c33bc795d936bba3ae457","up":true,"other":"e9cd25d1ef3fef22160bce7f7badd7646ac58ee40da6a438f61a067c51bc51d6087ed950ec9e909bc438ebe62e316cbd9489f3c9bfa2898615632414e04f1dcd"},{"up":true,"other":"5319bc9864d87eb33f26ff9732824d21a0a5ab70b254bc70a47554ffc763ae1559000d07e3eac9f883bd9e7f249d80edf14ab39c89c375bfcc5ec9e840ec9673","one":"89d46e664ac471c7150fbfe43a49c98750fc64d5ca22fdc2a040c7ab78c25c48c1e9c2f0e5130d6b8eb7f0760fe962759d83f68cc08ffaac3520499b0ce694de"},{"up":true,"other":"37adbfdf66163e45f433d78f63210163fdacf4688ad90d73bed07975be017c43cddf2a26a0dee8b11d78f294b63d4875b6be15f42f10817bd3d77b342919a11e","one":"6d0a09235ba0b0428938abf0e0782ac0ecf5697ef862888719a34fc956517aeef89d5e5f76d12e10067fee5bac8781dc10400eeb35c2393b9382b2a4f68f7939"},{"one":"58f9139905ae1d005950f110b7ead3355672ecc478e8c66393566c64b935003f6fec3031dc9eb21cda660acb1955cf7bb33a20fdd74d493f29868ace328fcd75","up":true,"other":"01427ba4d1e2de0b2764515556676a6058f88c16f597780dea3d7f95a6eec9299c3987d99c199d88a0a5e695ee6f0ff7de424e4eb65e54233b956a9634133998"},{"up":true,"other":"3dcf18c35593b47bc463688493b792d6b9d13eabe05396e491953608f20cf55f770fc21be32b00335fcb2f0ba02735b92569b2b64a44c344ac348042876e8f15","one":"e9cd25d1ef3fef22160bce7f7badd7646ac58ee40da6a438f61a067c51bc51d6087ed950ec9e909bc438ebe62e316cbd9489f3c9bfa2898615632414e04f1dcd"},{"one":"b9c7b885430b9b1a4425bde30b3629559f5437e0e30a0299fc6f6e097cbcca8af9e285caf5dea685a0237f60e06f490c39a1e3e487f14a2b9f41a5135f2ba994","up":true,"other":"c29e80096fbe7bc9fcbfdbe3cf6c06449192a3ed280e46a1fa5d424428d893c3456c985c1352c119236cf783834365439751cc87e7ed196614705dd3db6674cf"},{"other":"ee3471e1d835c4294f7ba642103039ccc548fe4edc177c79b63433ebbb0dc9d06600844f1fed76c7096ee9538e49e4e86fb8cffe9095dbdcde27695ff28ad395","up":true,"one":"3dcf18c35593b47bc463688493b792d6b9d13eabe05396e491953608f20cf55f770fc21be32b00335fcb2f0ba02735b92569b2b64a44c344ac348042876e8f15"},{"one":"ee3471e1d835c4294f7ba642103039ccc548fe4edc177c79b63433ebbb0dc9d06600844f1fed76c7096ee9538e49e4e86fb8cffe9095dbdcde27695ff28ad395","other":"aa53ca208cc0c9e544fd9d52cab44b5e2887256bb006037b855b5c94d7f79c9388fdbb23c0bf1d2eee12d67125e082fa7ecb34c1129ca8eaecfd85772b009435","up":true},{"one":"8e5e8366251e33277e7db6f6c04629b2ce3eee217e973acb97c83773671b0160c40732794584db741a29a763672b90f3bdf34151fd4a6986b9d0956dc61d9723","up":true,"other":"002cb6ffa63ad71ee6ebc1df4c41f7a97c51f274b1d3b22420c87b73136be5169b9670508061d8261e20055fefce3b855388994672aa9a0f1475c43839aae4fa"},{"up":true,"other":"876618c8ba66c1b91b473a154be3e10ded3590ba83d620d30e0ff1fbac2f31f258b1299a3da5b56aa03269a80c119b7fc41dfd87d5bd996359e4ad8dd0ab2a6a","one":"a5f7163586fce1750fd9a6e5c418af1c18ca6983069dcf1738fc9106ebf542a86e4ccfc50b45a0d97ca8681af8207128877f930f945e59ee262aa7f4014a01f3"},{"one":"ab8eda9b360d3e0b002ba31d48311057880844b828ad9817a2ad19736860d0114d4a17e9e9427c842d52e7ff61a09c2cad9b70f506e338909535542dae38ede0","other":"1cdef98d7b4de45c902c725384bd14c66084fe4159b26a0f9a24f432e1f561d035ca41e1c60fe64f3213b4f91a1afb953193dca1a7d535be0602b5d046bcbab8","up":true},{"other":"7465fe601a9ad8e640069e6e07d56afabd3d4f008f3084f944d869b47fda3f511f191062802a53da511f60891dd0bcc5fac60254ef9db7aa3b41f5791b0b6975","up":true,"one":"002cb6ffa63ad71ee6ebc1df4c41f7a97c51f274b1d3b22420c87b73136be5169b9670508061d8261e20055fefce3b855388994672aa9a0f1475c43839aae4fa"},{"up":true,"other":"c29e80096fbe7bc9fcbfdbe3cf6c06449192a3ed280e46a1fa5d424428d893c3456c985c1352c119236cf783834365439751cc87e7ed196614705dd3db6674cf","one":"da22fb43c6d230d92f9c09454e282dc45dffc759740566039f1bdfb58171c6801f721841de83217277b3fb70983e7d34da53bbf25d1d45413a78d9afff151826"},{"up":true,"other":"ab8eda9b360d3e0b002ba31d48311057880844b828ad9817a2ad19736860d0114d4a17e9e9427c842d52e7ff61a09c2cad9b70f506e338909535542dae38ede0","one":"9c8fca41b833e88110559b9258653160f5fb236bd637272ac58fe1adf333f4df75b94a805eaebb9f10a8c1a26d357dd75140560551d3fc4da79da2c4fc9479c3"},{"one":"8ee65c0937cdf860d5329132c34bf28b5dc4d2593986fae80e4b35efb54ec24cdbf294223515363a917a22dbc6db463c10c7484e22b479b9010059c2521b6317","other":"588df3185f63a5443d8c6b972f67805f0557184d916005f537a4b27cd02bd6a12e432a2b34b234a34f22e923c6f116da85be20bad77a2bf69913684e9d0732ba","up":true},{"up":true,"other":"f8a5ae50e5b2d84096c10a6a8493a9eb8113df64c4f1336c0cf4649302649b158fa4cb7941591e55356891bcc1008a535df427546af19988a241c5f466467963","one":"1cdef98d7b4de45c902c725384bd14c66084fe4159b26a0f9a24f432e1f561d035ca41e1c60fe64f3213b4f91a1afb953193dca1a7d535be0602b5d046bcbab8"},{"up":true,"other":"6b082a09e343a160b60a01f74641c1d707b2fa8fee5f6f5a8b9e4a203bd86434227d2df982b246a752f843483cdf517e85fe3bd65453354232a6eb38dedbf314","one":"e0f13606a7f35b9ad8a9c4e70336c4c554ac718720a451a349eb4e1a4b055079483cac040ec64e0ed3d8bdb336618a5ae6ef74e31642fae4d7ed9949858eb361"},{"one":"f8a5ae50e5b2d84096c10a6a8493a9eb8113df64c4f1336c0cf4649302649b158fa4cb7941591e55356891bcc1008a535df427546af19988a241c5f466467963","other":"d6a7257771baa4d9944592ead46b8ab700dbf91ebd4dc0ec7e5fb41cbda0622944269172fcec8352b89ef2c186d4c787af2b45a50533f627a97818477de034b4","up":true},{"other":"e0f13606a7f35b9ad8a9c4e70336c4c554ac718720a451a349eb4e1a4b055079483cac040ec64e0ed3d8bdb336618a5ae6ef74e31642fae4d7ed9949858eb361","up":true,"one":"7465fe601a9ad8e640069e6e07d56afabd3d4f008f3084f944d869b47fda3f511f191062802a53da511f60891dd0bcc5fac60254ef9db7aa3b41f5791b0b6975"},{"other":"eb6d41d8d96f1933dff017d5fa0c46c6d0bad5d273b7c321a12858ac90ec00fca6191d29419897d2e25ec2d8ebd8c6a81bbde2d3f266f842e64b2b822161f1ea","up":true,"one":"4116fbb7d55bfd4bd8db9cbfa570ac361bb88605b6aacbf84e245893cf3fa599ecc086688a4c534c81f61a90fa344ca37e4d4013ddc03f7f08218724a55f66b1"},{"other":"24047e1a816cbf9b7a90e6c78dc896a3b624047ef5cfd3aa495132d57b1074aa129ea6eff171f5cca91d0f4793a07c9672b0a55232f2415c6220e443ebd0791d","up":true,"one":"ec19efa1d488e74da6bf239825b24678f549c377326c5d33d100b708a9a28a3fe129d542d7ba71e0ade46c15c6e9b38f09422560444388e609a8a66ceb8e0ae8"},{"other":"c69b9b181b2756a1345b73a97afb3dca909c253188c3b905f0b414465b750d2ffccb4c8e8eb5e3809549af55db473f3b12682f9bd97c5c75d68f23d67d91b866","up":true,"one":"6b7c94db790a2c1b903208904c4c75b66b17e7a00404727dbc7aeff404ac1118dc78ce4ca443f6b5245236f9e358c09b6da027ae1144e1a6682edca301176330"},{"one":"eb6d41d8d96f1933dff017d5fa0c46c6d0bad5d273b7c321a12858ac90ec00fca6191d29419897d2e25ec2d8ebd8c6a81bbde2d3f266f842e64b2b822161f1ea","other":"11e9729700f5046b47d5e4521630cb57408f59a3337ca7db7984477a16c1f3b90c1d8d1f8d6a3f2a72e35f373fa73ec47a5636b36e40b2fb83756622a08896b8","up":true},{"one":"24047e1a816cbf9b7a90e6c78dc896a3b624047ef5cfd3aa495132d57b1074aa129ea6eff171f5cca91d0f4793a07c9672b0a55232f2415c6220e443ebd0791d","up":true,"other":"60995852a2385ce8d7d24dc94b85a2f0dab6e5c32e910dfe367ea9c6ccb7b0b2eb611fdf120f8c697097e2f137cefff42e8d9db16b664a857a38c5ace837ffa4"},{"one":"11e9729700f5046b47d5e4521630cb57408f59a3337ca7db7984477a16c1f3b90c1d8d1f8d6a3f2a72e35f373fa73ec47a5636b36e40b2fb83756622a08896b8","up":true,"other":"51a570637394e9ab61fe95b3a608cc4e9dc8ceb63efe717938ccd4260a962d52e01b30e7034fbfdabd9a3c9616ee569550b38a6d6b4b19847f523254069a9f27"},{"up":true,"other":"510536aba28aa635d8a1098a6dbd2070748ce1eb0e14b54b93a21196543a60df546ff6a2b3b5b9f32a5c2a37f5aba77d0b74f28b2dabeeebf3fe5afc20a3209c","one":"682288e4dae2374c4784acd0b285508920ce39a6b72cc0e30a3dbb7972e0394a2bddd5ee5f22a1dbf80f284dde4d9f8ede7847318d5353566b35a83e212477e7"},{"up":true,"other":"6c40910f0556f892a7542989fa01d7e3682fca89aeefb5ed885808f88ff17b6d13862f461c10d629a005ae67abef542d75e5b20816891b6944f71560f5c2dfa8","one":"06aab75fed9a03f5525e3f1d8f8997fefaefd5b16e8f485d571beda00b1741efbb61a8a74fa12c2f6de66227c3fabb4d411659cd9c7b1ef32e171e6bf517cc39"},{"up":true,"other":"9bdacc256acef0433805477d38f32be849a8846d88cb883b19d290454639b42c6ab6c5c52d4f83453e8a156af7d85f606458aa9c0977c67282f56f34ff0acbfb","one":"60995852a2385ce8d7d24dc94b85a2f0dab6e5c32e910dfe367ea9c6ccb7b0b2eb611fdf120f8c697097e2f137cefff42e8d9db16b664a857a38c5ace837ffa4"},{"one":"c69b9b181b2756a1345b73a97afb3dca909c253188c3b905f0b414465b750d2ffccb4c8e8eb5e3809549af55db473f3b12682f9bd97c5c75d68f23d67d91b866","other":"f6a12b23423c047927a3024a6dba7ce88927cb21d4df3778bc5ebb262cc403261c79ba6d9bda07f1852c009d803a77f429e9e48ec1d63cae98256e529d45b276","up":true},{"up":true,"other":"89d46e664ac471c7150fbfe43a49c98750fc64d5ca22fdc2a040c7ab78c25c48c1e9c2f0e5130d6b8eb7f0760fe962759d83f68cc08ffaac3520499b0ce694de","one":"488854534ec5a3479d8ee13d9b7daf07479f6b5505f319eced44dad8c316f6ff241ce2101e95608ba635067f5e5741481b78f419c4bbd465bf7e837dc4e54d64"},{"up":true,"other":"9309549fc50173d6826fe63cf18699f49199c3789616b843042fe1a6adab6ed4bdd7a7a06acd276e0398cf8bffb26c12a4227725d7bbd386a9a55fc601c21405","one":"ea2921612b827e3c26328368bed9be7cbf1f2b2aecaf31863c9cdccd74c56b651d6eaceb8ac9609a6653488837ded310df91e53a74789ae75cb841e2aeaf96df"},{"up":true,"other":"7958d1517de1223e7fb30acf61d8618e49fb95a03bc2f49141f4c7967bc80b90e0dd526c205639de3c060029963d43813293c2556f7b127945c798f3f9f18626","one":"92dbb67da2b99a8fe46b1e510addc2b83e357ac0b5287b7ef5c1b1bc6e252b8dfd605a6896ede65848e429216d1f67d530d9e7b83ff14058aa2e5b6e405d6801"},{"up":true,"other":"aa2028d356a88eca8e0fcaf218d62ace099c3f72dfd95bb28f30ac9a926034cf1d60a40511f7495652745de80d71c0f6830019e206c88e2b6ef0cf4f05d7fe9e","one":"c2a9c77247871cfa4d3c2d1b47619df91ed5b331a44c8e21f7c9ce431a4db9dfb87713558cc8a37911393907b4cc60be9445bad18adcea1bc5f318256e71be14"},{"one":"d3cd2f34f67830ccdc295b7537a6d27c02b44503808ca666124f52ecc3d6c35b7d3f14343997006aef2cfbefc8d27809d389477e99c236b9f8a897a4bc406a43","other":"95ff4dea07303e1ba641a5c510e714ef232f4dbce9ad2e8b2f62644975eae41fc4bb9d1af3fae4d5ea4daeb18f8248e0b3131c7d843d35d33f3afbf7dfa4c2fe","up":true},{"one":"d09104c44648391693ca64a57baa5ef54ed717e19c65ad0a0921d08cbaca8877d0190795d15f75f3b6ce6e676d6b0e55d5ee8fec3310c68b7060a32f7ff649cb","up":true,"other":"723f362e98f90d7ef15e24e353759fdbdabb08adab767dba73ab546741fac3dfb457466f1e2c851aa49526da1408f8ddb509e12f7dc0bc1e785c5b72be8a986e"},{"one":"a47697063a2fb973449bdabd0925e10944ba1f6d8b2cc5c38b295f611eea3402b5cf3ae857716a34d84194955f5ed61350affe56223349124c8233852141f9a2","other":"8e65496318637446a51f0dc87d0a5cf82655866cd1579db1e381af52e12545172b9c88119999ccac3b8b8644efc9675ff183ebe7584c16eb40792cc21f7e9b76","up":true},{"other":"6c40910f0556f892a7542989fa01d7e3682fca89aeefb5ed885808f88ff17b6d13862f461c10d629a005ae67abef542d75e5b20816891b6944f71560f5c2dfa8","up":true,"one":"95ff4dea07303e1ba641a5c510e714ef232f4dbce9ad2e8b2f62644975eae41fc4bb9d1af3fae4d5ea4daeb18f8248e0b3131c7d843d35d33f3afbf7dfa4c2fe"},{"up":true,"other":"865dbf61d8511603fe0d9ebfb10792b9f6b798187c0909039bd9b2492c41e428876f386beeac86d0dea871f4fc24ba435f0fbd9a11e74c044024934592af14ee","one":"869cae165389e7dee7b7df4e012ee1a39737366c306d8f4b0db4510b2236e0bd3a4d1d4af00b1a8c1d360e23da47de52fc1632edb03c7f1429aacc8aa4994750"},{"up":true,"other":"ec19efa1d488e74da6bf239825b24678f549c377326c5d33d100b708a9a28a3fe129d542d7ba71e0ade46c15c6e9b38f09422560444388e609a8a66ceb8e0ae8","one":"51a570637394e9ab61fe95b3a608cc4e9dc8ceb63efe717938ccd4260a962d52e01b30e7034fbfdabd9a3c9616ee569550b38a6d6b4b19847f523254069a9f27"},{"other":"8ec699020ab5e7719fe23b80268b5d1d37052bb71f5d81200ae805cf27825823733206165f0a7507c2595853361dd122e9ec1b2deb543591e22b71ec0b873b5b","up":true,"one":"aa2028d356a88eca8e0fcaf218d62ace099c3f72dfd95bb28f30ac9a926034cf1d60a40511f7495652745de80d71c0f6830019e206c88e2b6ef0cf4f05d7fe9e"},{"one":"8e65496318637446a51f0dc87d0a5cf82655866cd1579db1e381af52e12545172b9c88119999ccac3b8b8644efc9675ff183ebe7584c16eb40792cc21f7e9b76","up":true,"other":"207764262a208c17db61fda4208d4664bf74010e0ad051a863e131e748c9304e11ccf007c925488ea86b974ee61cdac3dca4d4b3f4043524e03c194ab3c8eb5a"},{"up":true,"other":"c0164fb4a1acfb4f3b1a09f9f3ab226c382529a73891937c6f3c91798098cf10b909eb92e5f8acfe0e8f3aee0b71cb23ee2d9e6ad1e0f4492a0272c52d529849","one":"8ec699020ab5e7719fe23b80268b5d1d37052bb71f5d81200ae805cf27825823733206165f0a7507c2595853361dd122e9ec1b2deb543591e22b71ec0b873b5b"},{"other":"865dbf61d8511603fe0d9ebfb10792b9f6b798187c0909039bd9b2492c41e428876f386beeac86d0dea871f4fc24ba435f0fbd9a11e74c044024934592af14ee","up":true,"one":"e33a1476fcb8d2a1b9ee15871a960ce7a3337c93f5956a2825b1f8b2885dbdc0ed652b1eba549523866632b5b6898310bc638d946a9fcce27d65117eb44c25f3"},{"one":"545237d8463b75fd2e9bbfbffb35c5b78b4abbc85f6bfbd56976789012dd9a62ca1f866bf37bb33618e026aab764adb9ced5e00cd415562f69992f74c795083f","other":"51df4f4d4f020f22f55a5fd00c7f9c68c232c167ae4d4e80d7695f8f39c5aa0a7b565c1c55bdd6a21e06fa056549d08fd2e9d76fd79e21295557aa30d1ae022c","up":true},{"one":"f4cdaeb513aa98f8868d8eb3a1d12c07367725928a1bc7d6ca4b583788e111a955463037ec7867260511896d97dfbf096aa77ee8a7d9ea1c06cad4a92c45108d","other":"37adbfdf66163e45f433d78f63210163fdacf4688ad90d73bed07975be017c43cddf2a26a0dee8b11d78f294b63d4875b6be15f42f10817bd3d77b342919a11e","up":true},{"other":"90b8e73916046b5433dce049bfe125ca2bf2fb390ff7301f9bc5d8d0183988577aa2a7392aaa28091aa81c8ac23942b5751420b9ee48e488a68411f9d2b1e5d5","up":true,"one":"33e9d4674b5b9b23e838583f01b429abca1330393dfc100b19ede6090a53df213011fae53169a66aa05d18e4cb497a17aa81eaedf1fe2e4348f9825c309438b5"},{"up":true,"other":"33e9d4674b5b9b23e838583f01b429abca1330393dfc100b19ede6090a53df213011fae53169a66aa05d18e4cb497a17aa81eaedf1fe2e4348f9825c309438b5","one":"207764262a208c17db61fda4208d4664bf74010e0ad051a863e131e748c9304e11ccf007c925488ea86b974ee61cdac3dca4d4b3f4043524e03c194ab3c8eb5a"},{"other":"b3b4b203395bb6655d79ecdcee11638dd9a16baccfcc1f6fcc8b31832c8ca35650eb6c2802104eeec6d96ea80404381a2bd9b01dcadc748a4666b761d9ce64f8","up":true,"one":"f60755ee9464c7db769bb7237016fa165441d18ac3bfed7cd2a220a9bcbead202dd34eaf2f9398a3d36bdfc2671bbd46ac25ebe264a8118afe1b7d0bd38710f4"},{"one":"be93fafaf43f6bb3efd2667d1468a8636cb752b245328eaa01468c0606d790322a7cd8e47857068e60118e28b8dd8aa1d2d4977c5b3d28d4b47f4c0658f05e90","other":"a8fac88fba179fb9b259d94caac9cbe45d873a0131bef8844ac4383b177daf6f301f8793623fec5876885db1a91e5b3e98e2aafdaa47e03b1f6d9740f48af7ac","up":true},{"other":"eb58e478b16056e0af344397cf5f078a3312a6db2189ec2042ec06ab6550e3ee71ebcfeff1814332c552c12a5a488f96b3f2935e90a189d238da19d30a2c9874","up":true,"one":"90b8e73916046b5433dce049bfe125ca2bf2fb390ff7301f9bc5d8d0183988577aa2a7392aaa28091aa81c8ac23942b5751420b9ee48e488a68411f9d2b1e5d5"},{"one":"228b3646b15527f4df07b847a62dbf9620cb068f829e9086b5f437d0b64d8a027cab44f19db5e44189b5099545ecb25d49384c261748f9533cfb0eb11a1eca5f","other":"b60def37233dbbc0d5f7fcddb304be1c0b6508e1e3d8a09a8290f7363e9bb84152dcaf70b8f6bb3a882fee77ff03ab796a5c1c3654f251c9f5c746ac5ad88556","up":true},{"one":"af9b80f6836113aeda897d6903e9ffb4f7f1a706a7f821d0d40f03a0d83c18d6a19795ee4bfc1093ada04014415b1f230db1d2f056df3f5027cce71611588046","up":true,"other":"bab07c2e4dc09add884869b31fb474b6d7151f9cc331d831f55c2b088397370fb0a1e1592c8dff9c8bc8e83de9faf6e91683acfb2df1b41856d70e523a99d370"},{"one":"c0164fb4a1acfb4f3b1a09f9f3ab226c382529a73891937c6f3c91798098cf10b909eb92e5f8acfe0e8f3aee0b71cb23ee2d9e6ad1e0f4492a0272c52d529849","other":"f60755ee9464c7db769bb7237016fa165441d18ac3bfed7cd2a220a9bcbead202dd34eaf2f9398a3d36bdfc2671bbd46ac25ebe264a8118afe1b7d0bd38710f4","up":true},{"other":"3a2cacc430f13f31c52b7205455420cf0fb9ed9e28b0898b69ef97951bf295b29118e573a42dd97abe38fee5ab4c03dad9ff6dc448126cefc1da12b6c8e8d915","up":true,"one":"eb58e478b16056e0af344397cf5f078a3312a6db2189ec2042ec06ab6550e3ee71ebcfeff1814332c552c12a5a488f96b3f2935e90a189d238da19d30a2c9874"},{"one":"a58a4db7a96b1578935b222c78b7b4dd8b3519d2995c3616e5a154c5175242a503097771332504638a0b321b9574110207f9a7d77b109d1de3d66a12ec6498e5","up":true,"other":"9f3af4577308965aceb7e0101443669496e7ccf1de680629862a7005966c708b6fb52e6dfe62660246b9892adc25838da2873502e0be706bcad8f25b7ceedfa5"},{"one":"b3b4b203395bb6655d79ecdcee11638dd9a16baccfcc1f6fcc8b31832c8ca35650eb6c2802104eeec6d96ea80404381a2bd9b01dcadc748a4666b761d9ce64f8","up":true,"other":"96cd4caa32c0b3a3493e24e13fad1ef75c621005d74154c3fc8a73cca4c0120452b6432334d94849c63f75d56a2943a453c86d2a14ad1fb61ae6833e58451187"},{"other":"97b1eaf8274ece76d75e7f60126f1b351ed5fe55088b9fcbb825a3a8d8f84f61bc72469916b280497dabf01345057525cae89da73c9a1a8a8cd19367d44dede1","up":true,"one":"96cd4caa32c0b3a3493e24e13fad1ef75c621005d74154c3fc8a73cca4c0120452b6432334d94849c63f75d56a2943a453c86d2a14ad1fb61ae6833e58451187"},{"one":"3a2cacc430f13f31c52b7205455420cf0fb9ed9e28b0898b69ef97951bf295b29118e573a42dd97abe38fee5ab4c03dad9ff6dc448126cefc1da12b6c8e8d915","other":"ba430731fc2082f4217ebd859c2865c28bf50a39674ca8615dd89f608ae434a09657e24644ac32807634aad7857547118c9228460195e50ec58b34789d4ad151","up":true},{"one":"ba430731fc2082f4217ebd859c2865c28bf50a39674ca8615dd89f608ae434a09657e24644ac32807634aad7857547118c9228460195e50ec58b34789d4ad151","other":"8d3ad57509b36c4ca5c4663f3d1977a3125e069078842634e6cfeb22c044281e3d02f06eafc6d2a60089f03d70f5134a6635c35563c9f911fd845a6ef9bc8952","up":true},{"other":"fd0123c7b96004067e98e463e273de5bc5402399ae70a95985b5f682e30d4f35d070deaf8c71d201e98c4324d832b95aab7535ad8a2658f66e3e0bb1202204e1","up":true,"one":"9309549fc50173d6826fe63cf18699f49199c3789616b843042fe1a6adab6ed4bdd7a7a06acd276e0398cf8bffb26c12a4227725d7bbd386a9a55fc601c21405"},{"other":"17ae0b24297a3e6e027884e5e4529b6646ae340f5736eebc6187a9b59832a445f3644172d92438351e3803e56a67472b29f3e1d48844ae2e11e5e6670eed1436","up":true,"one":"8d3ad57509b36c4ca5c4663f3d1977a3125e069078842634e6cfeb22c044281e3d02f06eafc6d2a60089f03d70f5134a6635c35563c9f911fd845a6ef9bc8952"},{"one":"bdd17545242bedba1e4c36fadea95db655f8f220f10ae143084690a3c8d4e7ffb79a64af9f1bc8514addbd63695b2f20857e8d162f25318faac885f77b385138","other":"c0a2c08fa8b70ecbf1932254945d5f689b0da7a287019d384152f383f6229acd4d82eef26205bc12e062dae4569814bd1c996ee4fe5886bd6bdd93c4f0ac113a","up":true},{"one":"97b1eaf8274ece76d75e7f60126f1b351ed5fe55088b9fcbb825a3a8d8f84f61bc72469916b280497dabf01345057525cae89da73c9a1a8a8cd19367d44dede1","up":true,"other":"bdd17545242bedba1e4c36fadea95db655f8f220f10ae143084690a3c8d4e7ffb79a64af9f1bc8514addbd63695b2f20857e8d162f25318faac885f77b385138"},{"one":"85c0b055439f114dee5eb0961013c117a48d62b0f17c61a7fd92a84092ef09bb3bbce686aa96e14528d5663565c57d657fa9813b1f38e268caeb1cb0842ef232","up":true,"other":"7b4585f8a4e4904239994a1b8bdc76299da8e46a8a632fabc6c33dd4170f8f3715e4c4f526ea5dd14093b150855960e432b1b140594aca21995f9e0722fb57f1"},{"up":true,"other":"8c459100df488b992fdad207a096a434d67cb733619adfd09a311095568d4c9db293d9a892675551805559456d49a3fdb19c2cc698b14552bf0ace584d4d90dc","one":"17ae0b24297a3e6e027884e5e4529b6646ae340f5736eebc6187a9b59832a445f3644172d92438351e3803e56a67472b29f3e1d48844ae2e11e5e6670eed1436"},{"one":"313a131ecb7d68e127d0fec8bb4a2e586886203c3d07857a93e7a39bb831703184d9ae28ba9ef3d986c2dae1a24f4f5bfa47cfc35f74f5512a126836364d7736","other":"1c080e90760dfcee08ade6e4ea3b275ff3c6882f3b44b7f3a73d70bcc816fc63ce0b6138f810d17d96ed387076f9bbb6dbb2ef6dc4d6ba6542c1f587b7602a12","up":true},{"one":"bab07c2e4dc09add884869b31fb474b6d7151f9cc331d831f55c2b088397370fb0a1e1592c8dff9c8bc8e83de9faf6e91683acfb2df1b41856d70e523a99d370","up":true,"other":"c63b88f494b14d5a7c1da124ffebbd985d19806b91d4b111c83ae129c4ef19614469980a09fbeccebe3b0358dd16194bdb6452d0b3dbb43a5467e23bb13f40d6"},{"other":"6b082a09e343a160b60a01f74641c1d707b2fa8fee5f6f5a8b9e4a203bd86434227d2df982b246a752f843483cdf517e85fe3bd65453354232a6eb38dedbf314","up":true,"one":"8e5e8366251e33277e7db6f6c04629b2ce3eee217e973acb97c83773671b0160c40732794584db741a29a763672b90f3bdf34151fd4a6986b9d0956dc61d9723"},{"one":"c9d705012a06d82c4d44db95b4f1c63ddd33ad64d732e96b1d878caa0caac433d4096f01495a6f0e8a56af122b0470fd745db6d906353b590a4710472b93f5b2","up":true,"other":"15ceb62ee0f53379aa202950634ed881ba3b7bd4b46c80723ee48190079311e24ffaacb167a126a40bd6732c384f3c26163aa043edca03cb52a97b6da189aec7"},{"one":"3e2241cdb9f34c1d2c6930e59940e2c4b92b0287579d7263a620a609c5e66dca6d85df48cf1bffd63663a6704c42d0866aae3e484fd9a44b6a012f72dd3cef6e","up":true,"other":"b4f300abda4cf6e383f997510eb681e9fa62e23577e3c19bd7447fa1f5702a4e034cea5944248e7c6e6e92b5ae69195c3e8a2c5ca7827b4f4a00cc8546e6695a"},{"other":"4116fbb7d55bfd4bd8db9cbfa570ac361bb88605b6aacbf84e245893cf3fa599ecc086688a4c534c81f61a90fa344ca37e4d4013ddc03f7f08218724a55f66b1","up":true,"one":"f6a12b23423c047927a3024a6dba7ce88927cb21d4df3778bc5ebb262cc403261c79ba6d9bda07f1852c009d803a77f429e9e48ec1d63cae98256e529d45b276"},{"one":"ea2921612b827e3c26328368bed9be7cbf1f2b2aecaf31863c9cdccd74c56b651d6eaceb8ac9609a6653488837ded310df91e53a74789ae75cb841e2aeaf96df","other":"37adbfdf66163e45f433d78f63210163fdacf4688ad90d73bed07975be017c43cddf2a26a0dee8b11d78f294b63d4875b6be15f42f10817bd3d77b342919a11e","up":true},{"other":"9309549fc50173d6826fe63cf18699f49199c3789616b843042fe1a6adab6ed4bdd7a7a06acd276e0398cf8bffb26c12a4227725d7bbd386a9a55fc601c21405","up":true,"one":"57085f756f76644cdd2148524f2334d869ef0ab2fcbe7fb11f5d22bc1f5023165b11526ecc85ff9cbb88877386af9b148d7ef15a825b3a586d16c01bdfc86692"},{"up":true,"other":"aa90454031068598ee39af5f1429c7a72277946d50ec2004f340406dbcc9f80cac505c9d9b071f85e2ccfd4b13bcf943f3cb9dd9f96f62d41352af9d8fffe7e4","one":"510536aba28aa635d8a1098a6dbd2070748ce1eb0e14b54b93a21196543a60df546ff6a2b3b5b9f32a5c2a37f5aba77d0b74f28b2dabeeebf3fe5afc20a3209c"},{"one":"aa90454031068598ee39af5f1429c7a72277946d50ec2004f340406dbcc9f80cac505c9d9b071f85e2ccfd4b13bcf943f3cb9dd9f96f62d41352af9d8fffe7e4","other":"85c0b055439f114dee5eb0961013c117a48d62b0f17c61a7fd92a84092ef09bb3bbce686aa96e14528d5663565c57d657fa9813b1f38e268caeb1cb0842ef232","up":true},{"up":true,"other":"1e3a2f2491b6acb07a9549d9929d150479a0313c926b0e236237bd541303da4b563a855016a90ab50e59d94803ad566798570fa981464c94c04a4a4a94fbc607","one":"545237d8463b75fd2e9bbfbffb35c5b78b4abbc85f6bfbd56976789012dd9a62ca1f866bf37bb33618e026aab764adb9ced5e00cd415562f69992f74c795083f"},{"one":"b4f300abda4cf6e383f997510eb681e9fa62e23577e3c19bd7447fa1f5702a4e034cea5944248e7c6e6e92b5ae69195c3e8a2c5ca7827b4f4a00cc8546e6695a","up":true,"other":"37adbfdf66163e45f433d78f63210163fdacf4688ad90d73bed07975be017c43cddf2a26a0dee8b11d78f294b63d4875b6be15f42f10817bd3d77b342919a11e"},{"other":"fc9b1b2bbd5e682eb350d23f3ee33b245495daedae9370de7b1f55f91cd45db831d196c17615e11decf6b67696a268ac788130e3de38c7f6aeae811f3ec8c8ee","up":true,"one":"e993be8034861aebc9bbd11115f25d9c719d43fcdefc323599616cc26240cee38dfc27bb7f339149a54a3c9ad13b2d6ca4f0ae690e4355605eda6b789c4a431e"},{"one":"6d0a09235ba0b0428938abf0e0782ac0ecf5697ef862888719a34fc956517aeef89d5e5f76d12e10067fee5bac8781dc10400eeb35c2393b9382b2a4f68f7939","other":"fd0123c7b96004067e98e463e273de5bc5402399ae70a95985b5f682e30d4f35d070deaf8c71d201e98c4324d832b95aab7535ad8a2658f66e3e0bb1202204e1","up":true},{"other":"ea2921612b827e3c26328368bed9be7cbf1f2b2aecaf31863c9cdccd74c56b651d6eaceb8ac9609a6653488837ded310df91e53a74789ae75cb841e2aeaf96df","up":true,"one":"855667650e96c5ed2d9b0c82532ed1fb92f72b1ae926afafe09cf8f6e90e539aec5c4c2ab108f2c2a1ad7dd8b83ca92a98c550a1c9ed27e6632a7d2f6da4f970"},{"up":true,"other":"1c080e90760dfcee08ade6e4ea3b275ff3c6882f3b44b7f3a73d70bcc816fc63ce0b6138f810d17d96ed387076f9bbb6dbb2ef6dc4d6ba6542c1f587b7602a12","one":"2c976b6007cda135444233c7bd03d22ac9756710b746c36bc032e7fdd42f2ffb89ca5f5e754ff96b8f3cbc474e346287e5b8531d9f98fd63c426c632872220af"},{"one":"99af34b172d319633e07a4e528f416024653a230a9103a4b281171f75bb697dd6be4757558c94e86210b4da8d9fe1229f6a5d8c4174989ea0ce696f8d1a9995d","other":"58f9139905ae1d005950f110b7ead3355672ecc478e8c66393566c64b935003f6fec3031dc9eb21cda660acb1955cf7bb33a20fdd74d493f29868ace328fcd75","up":true},{"up":true,"other":"77e40e42f570a217f707888c714deb31fd70c856ae4b9a44ec7cee02768185dc4d7ed210429607f06690b32edd9fb06b304aff330a3949cc2fd49db1bc392edb","one":"e0a043f98b462f10f72aa61ceda52f9c27829d086f6f2c5bf4db4fe32759002e5ff9519495d57dbb83d963a1dc991a1defcf5b9ef0d543789f38c68f5d07122b"},{"one":"c6ad9b9de5cdbe28540f4eb7c66fb37f6d4295e6e60c6de54e2a45c1970b8e0047558e986bbd10e9e86c8bb0407846fac4823e4570e8a1486fc4bf55cb4a0986","up":true,"other":"02fdbcb00f20a3f6e894900d798fcb0aca9e21f5b107924c0999eb396220f16dee99fc80ccba796e66e69dcb9ce278b7e0e4539c7a7cd0fbc1037bf8e56c1e67"},{"up":true,"other":"3b71a324bd7b1a8fb19d8206eea1ca8190cb1faf5fcd1bfc52cef6b52296fe1db3e54d70180133fad1fa1188499d0dd73d2d075fdc6b3ffd9042d690e7d88e02","one":"488854534ec5a3479d8ee13d9b7daf07479f6b5505f319eced44dad8c316f6ff241ce2101e95608ba635067f5e5741481b78f419c4bbd465bf7e837dc4e54d64"},{"up":true,"other":"842ec3faa8b4a4cdec32abfa00ae827277fe2696e1b0c6551154533b16cf75ae69caf834b4f08488fa5c8b322fb633b1fd8a5b7d436e9c589cc9074dc031ae68","one":"bb0749de05a97daa67de889c15831ce39a080d641b3b08e3c248b0b16f4c07943fea8dd054d4a7e3e4af91ecff07053ce90096485a360b6f1d93050d179f30c3"},{"one":"c6f38fe8a0f2b3773bae332e0ca7516e944bde186fe99daae10a2b0aecde3ce23c1834eaad97a4e6d2da8cd53a08dbafa72d2b827c851b115b74e8010125dba2","up":true,"other":"842ec3faa8b4a4cdec32abfa00ae827277fe2696e1b0c6551154533b16cf75ae69caf834b4f08488fa5c8b322fb633b1fd8a5b7d436e9c589cc9074dc031ae68"},{"other":"9c8f156797deff649d74d56fc42b4bb1a87312089114d4350424c375837d9c8068dd09af01c1c973d12ec5d7e8da600cd685cae70d3116b9dbda823092e03fff","up":true,"one":"e1f23e1caba66f5ff821edbc4a3d527539937f73d86dd0df43aa1266a99f51f2480a77961eff177fbbf852fc52cb9317179f80b1580194daaedadc3b00510751"},{"up":true,"other":"8f3e9102306a13adb91e01f7a847e7880054f1a7df8976d05facb3a8fb37d47cce04f25e18a19713e5c3da7541e96e829fc67c8b924b717d2d9586c9c12d4fcf","one":"70cce7cb0c18091dbb6d41160ab560935f1759b969bf8118cee030ee707cb15ba407b8c48dcd9fd012cbf778e219f7d16a74064b4983cf098fb118297748edb6"},{"other":"5a6318af8b4615cf30610a05ade7704182fefd0a3fb3d76c47cb392e114d8d30004f0ec214326b11532fd1e928e66f632bbcde126a94c87774063853a9518dc5","up":true,"one":"624248a794fd62248024360f128b2e503c752340694a316bed420e5ed2cebeb5bf970df95a2806732237a26de3778222b0454e2e7d2875129b193e7890fd5b95"},{"one":"a58a4db7a96b1578935b222c78b7b4dd8b3519d2995c3616e5a154c5175242a503097771332504638a0b321b9574110207f9a7d77b109d1de3d66a12ec6498e5","up":true,"other":"49215dfa786bfaa52b1e7aa6899392711a770b2504c82f536381fb1f18df16960257d75530efabf6dbd2b1361decc29758f870b318f777decf51f4833a9c1f00"},{"other":"9c8f156797deff649d74d56fc42b4bb1a87312089114d4350424c375837d9c8068dd09af01c1c973d12ec5d7e8da600cd685cae70d3116b9dbda823092e03fff","up":true,"one":"d7af0a0217ff98804aa05f8f926a8b6262363b5391d24cda8048cca5ca5982b407b7b098302d0db6d8dd9ac0883b2025b3de651617ed1a173181148295c6d336"},{"other":"bc0df855bdadcde3e447415444f655eb430925a8fa81cdcac75909e7d79750f01827938570e75e388cc7058ba8ebca47afadf8b07172bc078488fb618ba71024","up":true,"one":"2751df9f64a8f2ff8ea45efc9bd02b281d963ced285260bcda7f9dfaed998fe4386fe65a7265876da6b4fee77ea5c12454869a70ad627da7ca888076fc629665"},{"one":"48e35d67e14ee2f329c0275bc965829b761885dbc3671f4673d84d76d18a5b6415e619e219b5d90761a5c6bd2f43c6a58708286a063daf46b502944f8ef9230b","other":"4ff2981a47da46c753090e193a8bf43c3372a6b07a37cf0552de2ced455fbb8a76d969cd97b3e4601d8a808bd2a73f7729ed8a61df2f2a0c2cee1425d0bd9ab4","up":true},{"up":true,"other":"d3cd2f34f67830ccdc295b7537a6d27c02b44503808ca666124f52ecc3d6c35b7d3f14343997006aef2cfbefc8d27809d389477e99c236b9f8a897a4bc406a43","one":"81dc656de121016bcde81d5bf7919839acfc180dfbf1a6de2cadf704ff13af98aa5715a4168832ca6f651b2ea7ad9e6ca5f1c1cb7e885dbc2eb23d4aefb87bd6"},{"one":"bab07c2e4dc09add884869b31fb474b6d7151f9cc331d831f55c2b088397370fb0a1e1592c8dff9c8bc8e83de9faf6e91683acfb2df1b41856d70e523a99d370","other":"ecb93d8eba17afe92979e8154252a08dd58de6ff3188b6829e3e25967846686f54199ab2b081e77b0048dcab204f05aa2c5cbd0efae4bc43a612d471d4e1197b","up":true},{"one":"5982e7dfd39c527851f6ea6430b70e654d95df5ec4401ca1d8dbd1034cf7a65d1126d60b36ebbd396c9ca32e6e8515f34f9dc0a8d2980afe4aa181c8bf68437e","other":"8e8614a4c2ee2b1a3fa5ace0ca353cff36b3de3308ccf53665b8b56f8e2456a8a65f3846d786dccd68b1bfcefdd170ea5f8edb481800b1ce72d9fce2added7f0","up":true},{"one":"1e3a2f2491b6acb07a9549d9929d150479a0313c926b0e236237bd541303da4b563a855016a90ab50e59d94803ad566798570fa981464c94c04a4a4a94fbc607","other":"5982e7dfd39c527851f6ea6430b70e654d95df5ec4401ca1d8dbd1034cf7a65d1126d60b36ebbd396c9ca32e6e8515f34f9dc0a8d2980afe4aa181c8bf68437e","up":true},{"other":"e903d7aebff96a6afa4b9dd19b0b02e5af18da8e4e89f64247e1a2c2d46637538c741182eac67f45ec61be76aeaccde57f0a0184bd608ea7d92e586d4f827ea7","up":true,"one":"a58a4db7a96b1578935b222c78b7b4dd8b3519d2995c3616e5a154c5175242a503097771332504638a0b321b9574110207f9a7d77b109d1de3d66a12ec6498e5"},{"other":"2cb076669efbaf2ff0b181a1b454061a31ef23937a40405022b126f0eb4bfba60c9e3397009d8c0ff0cabb603692532d0072c18c6838f43397c98483306f62db","up":true,"one":"9ea856ea440c776b9ffaad1237ec11d570a1f912a908b8363ff97cf7947d2523e3c73663240d8fac988698cdd81e877ddd4a609485fe9f26494136fae14212df"},{"one":"c9d705012a06d82c4d44db95b4f1c63ddd33ad64d732e96b1d878caa0caac433d4096f01495a6f0e8a56af122b0470fd745db6d906353b590a4710472b93f5b2","up":true,"other":"5d002c37b74a6656db86f102b0cec82bc35a819a480e5a2952db0140ebab65dffeb1a79f04d53ff61447b5fad7c58cb75ea1c91ea47fcb9e024f27b92c6c874d"},{"one":"b87e7f36ed6bf142d48545024d2fd6e120c44511701e7c0b7d7fc786f4f29d3357024b15f70b78215d8a4c2b7572d608c11b31612743e23db4fa673f0cd6519b","other":"46717bc5fb7fcbcdc961e7ef091020f9f222858cf3d4afcc0b0bb1b782b7055d9eb833e0a04cb32d80406133ac77162521c43edf9f9690872222760e31462ccc","up":true},{"other":"9c8fca41b833e88110559b9258653160f5fb236bd637272ac58fe1adf333f4df75b94a805eaebb9f10a8c1a26d357dd75140560551d3fc4da79da2c4fc9479c3","up":true,"one":"aa53ca208cc0c9e544fd9d52cab44b5e2887256bb006037b855b5c94d7f79c9388fdbb23c0bf1d2eee12d67125e082fa7ecb34c1129ca8eaecfd85772b009435"},{"one":"dbb6621460b054f584f1c6157b4020f3c58d84c3a12b57436e10525ae60ab27036bf3edd68b92f2b13674877d01c2871dc67a9031c3d0470985f4b071696346e","other":"6c2788dec7ae7a77134065afc1174bb92b87833e87acaa72fe9e62c92d2017f217f9fbc5884cdfb7236a7bb75e463e49ecceb1641a8629516211d9699587046e","up":true},{"up":true,"other":"89d46e664ac471c7150fbfe43a49c98750fc64d5ca22fdc2a040c7ab78c25c48c1e9c2f0e5130d6b8eb7f0760fe962759d83f68cc08ffaac3520499b0ce694de","one":"6c2788dec7ae7a77134065afc1174bb92b87833e87acaa72fe9e62c92d2017f217f9fbc5884cdfb7236a7bb75e463e49ecceb1641a8629516211d9699587046e"},{"other":"dbb6621460b054f584f1c6157b4020f3c58d84c3a12b57436e10525ae60ab27036bf3edd68b92f2b13674877d01c2871dc67a9031c3d0470985f4b071696346e","up":true,"one":"3e7aef8260c0d9717aa59b65ce7c554e53b81f19f5b9400321704a7ddf5041b0fe31b5634e90b93e6984060defee0e153997bbfe196166cc8d83165fd5eaf41f"},{"one":"99a7649bdf2ee7f0bc049308b0997e33abb68481c05a573df9aea30da5a1f267df07b2c584e3e985baf31704f04ad2a2c4876e0f8555333be6d09f5080b583f1","up":true,"other":"bab07c2e4dc09add884869b31fb474b6d7151f9cc331d831f55c2b088397370fb0a1e1592c8dff9c8bc8e83de9faf6e91683acfb2df1b41856d70e523a99d370"},{"one":"431644cf162bc267237c4e798288888dd835c1b0546b0cc679782e33568988d75b4294f4aa08359a6b152ed9a0fbd13133681156bcf09a871c4f362615ea6dae","other":"70cce7cb0c18091dbb6d41160ab560935f1759b969bf8118cee030ee707cb15ba407b8c48dcd9fd012cbf778e219f7d16a74064b4983cf098fb118297748edb6","up":true},{"one":"e903d7aebff96a6afa4b9dd19b0b02e5af18da8e4e89f64247e1a2c2d46637538c741182eac67f45ec61be76aeaccde57f0a0184bd608ea7d92e586d4f827ea7","up":true,"other":"9c8f156797deff649d74d56fc42b4bb1a87312089114d4350424c375837d9c8068dd09af01c1c973d12ec5d7e8da600cd685cae70d3116b9dbda823092e03fff"},{"up":true,"other":"01427ba4d1e2de0b2764515556676a6058f88c16f597780dea3d7f95a6eec9299c3987d99c199d88a0a5e695ee6f0ff7de424e4eb65e54233b956a9634133998","one":"99af34b172d319633e07a4e528f416024653a230a9103a4b281171f75bb697dd6be4757558c94e86210b4da8d9fe1229f6a5d8c4174989ea0ce696f8d1a9995d"},{"one":"4e88cc60efee147fb72a735775944c7b2ba0790e2b2b935b4b3c2da9a3158a2a7aae411e9204cdbe6b2304d90a3a8278f8bb1a800a409e8500d100d84ba1947f","other":"0c9a05514b96e7c3a0fbca21552e158faa70047246b230addca172a5023fd7439acd1c3a0b4f9191579b308dab38c961734ffdb36fb8e16383e912d070fc0218","up":true},{"one":"9c8f156797deff649d74d56fc42b4bb1a87312089114d4350424c375837d9c8068dd09af01c1c973d12ec5d7e8da600cd685cae70d3116b9dbda823092e03fff","up":true,"other":"01427ba4d1e2de0b2764515556676a6058f88c16f597780dea3d7f95a6eec9299c3987d99c199d88a0a5e695ee6f0ff7de424e4eb65e54233b956a9634133998"},{"one":"c0bec7375c66bec98524ade2245c1d7480516fc5d87a3249e64ec86418e80e202f1e3da76832e97bbc3dcaed8c96ca344e4829347b4428f4b1cb61999e404c05","up":true,"other":"01427ba4d1e2de0b2764515556676a6058f88c16f597780dea3d7f95a6eec9299c3987d99c199d88a0a5e695ee6f0ff7de424e4eb65e54233b956a9634133998"},{"up":true,"other":"01427ba4d1e2de0b2764515556676a6058f88c16f597780dea3d7f95a6eec9299c3987d99c199d88a0a5e695ee6f0ff7de424e4eb65e54233b956a9634133998","one":"fee3fa1ba2a051d40a582908384ee81179db6c2b5f4bfa58c24f8015b794b43a093ed68b69bb209684135f972a055a9845978fa1b7d489e2126c3b514297f1c2"},{"one":"58f9139905ae1d005950f110b7ead3355672ecc478e8c66393566c64b935003f6fec3031dc9eb21cda660acb1955cf7bb33a20fdd74d493f29868ace328fcd75","other":"70cce7cb0c18091dbb6d41160ab560935f1759b969bf8118cee030ee707cb15ba407b8c48dcd9fd012cbf778e219f7d16a74064b4983cf098fb118297748edb6","up":true},{"up":true,"other":"1c080e90760dfcee08ade6e4ea3b275ff3c6882f3b44b7f3a73d70bcc816fc63ce0b6138f810d17d96ed387076f9bbb6dbb2ef6dc4d6ba6542c1f587b7602a12","one":"29acdd4c1233441bd40f98e245ecc9de94de6f9d0ab7c1a9923d833a2c8e6c1bd26d792686fec762b31fe28bbdd7aa04c9a594d997d08c133bb24cb2d877595a"},{"other":"01427ba4d1e2de0b2764515556676a6058f88c16f597780dea3d7f95a6eec9299c3987d99c199d88a0a5e695ee6f0ff7de424e4eb65e54233b956a9634133998","up":true,"one":"699c923976c5b8c70c353840d3e384750f466954265f05fbb0d5877a2c0318a041dc57adc12ac6e8fbae7a00d6b6675e1a1be3a8f59dac12727ee3f8ae467a13"},{"one":"876618c8ba66c1b91b473a154be3e10ded3590ba83d620d30e0ff1fbac2f31f258b1299a3da5b56aa03269a80c119b7fc41dfd87d5bd996359e4ad8dd0ab2a6a","other":"6b7c94db790a2c1b903208904c4c75b66b17e7a00404727dbc7aeff404ac1118dc78ce4ca443f6b5245236f9e358c09b6da027ae1144e1a6682edca301176330","up":true},{"one":"d6a7257771baa4d9944592ead46b8ab700dbf91ebd4dc0ec7e5fb41cbda0622944269172fcec8352b89ef2c186d4c787af2b45a50533f627a97818477de034b4","other":"8e5e8366251e33277e7db6f6c04629b2ce3eee217e973acb97c83773671b0160c40732794584db741a29a763672b90f3bdf34151fd4a6986b9d0956dc61d9723","up":true},{"one":"69f999937943be00e5fca5c7cc942ce13b6752a72813368da2fbfcf74ad807bc6edd85537e087b6f73c0469c7b76a5d8f7d883bd315f3b35af32b8da293ed243","other":"a5f7163586fce1750fd9a6e5c418af1c18ca6983069dcf1738fc9106ebf542a86e4ccfc50b45a0d97ca8681af8207128877f930f945e59ee262aa7f4014a01f3","up":true},{"other":"69f999937943be00e5fca5c7cc942ce13b6752a72813368da2fbfcf74ad807bc6edd85537e087b6f73c0469c7b76a5d8f7d883bd315f3b35af32b8da293ed243","up":true,"one":"6b082a09e343a160b60a01f74641c1d707b2fa8fee5f6f5a8b9e4a203bd86434227d2df982b246a752f843483cdf517e85fe3bd65453354232a6eb38dedbf314"},{"one":"4116fbb7d55bfd4bd8db9cbfa570ac361bb88605b6aacbf84e245893cf3fa599ecc086688a4c534c81f61a90fa344ca37e4d4013ddc03f7f08218724a55f66b1","up":true,"other":"11e9729700f5046b47d5e4521630cb57408f59a3337ca7db7984477a16c1f3b90c1d8d1f8d6a3f2a72e35f373fa73ec47a5636b36e40b2fb83756622a08896b8"},{"up":true,"other":"d7af0a0217ff98804aa05f8f926a8b6262363b5391d24cda8048cca5ca5982b407b7b098302d0db6d8dd9ac0883b2025b3de651617ed1a173181148295c6d336","one":"3639f964feba681db9702cac3f02058f2e490fd7bffb217dc3480dc458decafd5955541fea89f0f6f14ee50a745eaf98b21363d6b4fb88c31bd32bf7845d524b"},{"up":true,"other":"f6a12b23423c047927a3024a6dba7ce88927cb21d4df3778bc5ebb262cc403261c79ba6d9bda07f1852c009d803a77f429e9e48ec1d63cae98256e529d45b276","one":"51a570637394e9ab61fe95b3a608cc4e9dc8ceb63efe717938ccd4260a962d52e01b30e7034fbfdabd9a3c9616ee569550b38a6d6b4b19847f523254069a9f27"},{"one":"70cce7cb0c18091dbb6d41160ab560935f1759b969bf8118cee030ee707cb15ba407b8c48dcd9fd012cbf778e219f7d16a74064b4983cf098fb118297748edb6","other":"b183f12f3602bfdab0480cb0b0ba7dc69b267b0dbc7e54c316741cb78b9e99aa69fd321ad7755d095e9be14e6bd90fe14ef8fe9bafc1a0dea10a144795021a08","up":true},{"up":true,"other":"20f6a8be1d2d8b5d6a43d851a2f5475385ef07fab80ac46525d0beccf3e25c01d726cfb3a1179e8343b1e88d21684fb24dd6e6497537d4e7e9edd59cb95d1b8d","one":"10551c0c37abc25457903978868dd4843a52fda5f9b571b05ebd974d8c381fda4349f17c2b986a2e4b8d06b0517422f085d5f6d9cd814efa40e48393d9f71d7e"},{"up":true,"other":"10551c0c37abc25457903978868dd4843a52fda5f9b571b05ebd974d8c381fda4349f17c2b986a2e4b8d06b0517422f085d5f6d9cd814efa40e48393d9f71d7e","one":"842ec3faa8b4a4cdec32abfa00ae827277fe2696e1b0c6551154533b16cf75ae69caf834b4f08488fa5c8b322fb633b1fd8a5b7d436e9c589cc9074dc031ae68"},{"one":"77e40e42f570a217f707888c714deb31fd70c856ae4b9a44ec7cee02768185dc4d7ed210429607f06690b32edd9fb06b304aff330a3949cc2fd49db1bc392edb","other":"c206d8689068488179e86ce549de75989e0b17cbe09880d18fcf0fa212e629345f1b899203607a2b083569cb3f8398e501843166f5db23ac7fa7dacfe26dd3f4","up":true},{"up":true,"other":"869cae165389e7dee7b7df4e012ee1a39737366c306d8f4b0db4510b2236e0bd3a4d1d4af00b1a8c1d360e23da47de52fc1632edb03c7f1429aacc8aa4994750","one":"fd0123c7b96004067e98e463e273de5bc5402399ae70a95985b5f682e30d4f35d070deaf8c71d201e98c4324d832b95aab7535ad8a2658f66e3e0bb1202204e1"},{"one":"202ae63076a5560418023f00c9965b2a1d12de932b5371ae270d63db88551a7aa1a3c48841f81948fad3435bb4a7e3e165a2eced9fd937444e4502471e23dae8","up":true,"other":"b4557089e4247379e587a087f53b36dd1f86f85d9dcfab5dc562079978cd959adaef5b30d11258d9cb552e7c5abddf5377a71d449febe8f2acb0aec3ebd8ba73"},{"up":true,"other":"c63b88f494b14d5a7c1da124ffebbd985d19806b91d4b111c83ae129c4ef19614469980a09fbeccebe3b0358dd16194bdb6452d0b3dbb43a5467e23bb13f40d6","one":"af9b80f6836113aeda897d6903e9ffb4f7f1a706a7f821d0d40f03a0d83c18d6a19795ee4bfc1093ada04014415b1f230db1d2f056df3f5027cce71611588046"},{"one":"877d17ec7e95998ead831606d3363fbff1c8d1fa377b8e621e6a876d2c7776b9af356211a7e4df66adeaf38cf9b49c04871e8804edde4c18435ff45e110ecb04","other":"2880e0defd1bf2665bdd20dfb46bc0a9ad707f495211fc78e611ab479d78398db7daff7d3f4b6bf81fd13bf766ecc8271e0ea99a2d74abd2f9ddf98835ffdcf1","up":true},{"other":"49215dfa786bfaa52b1e7aa6899392711a770b2504c82f536381fb1f18df16960257d75530efabf6dbd2b1361decc29758f870b318f777decf51f4833a9c1f00","up":true,"one":"c206d8689068488179e86ce549de75989e0b17cbe09880d18fcf0fa212e629345f1b899203607a2b083569cb3f8398e501843166f5db23ac7fa7dacfe26dd3f4"},{"one":"c402495c2110a6531a530ebdcd9ab1b883f1c707fe25aa13a255a0a9edb4113669b4aee9eadf803f9fe4c2ef66d5e4dff7064549f672598410f2d9794747a600","up":true,"other":"4ff2981a47da46c753090e193a8bf43c3372a6b07a37cf0552de2ced455fbb8a76d969cd97b3e4601d8a808bd2a73f7729ed8a61df2f2a0c2cee1425d0bd9ab4"},{"other":"77811b007dd1fc1b11e447858df37062e97b6fc14e059399814f3b4736188e3fb28bf7c3958bb8ebc6ae16c36884ba7c98b810fb6f8b358323412123c803abd4","up":true,"one":"5a235aca7005df295d5bd924b1272452e9bdad408ca5223b9eb76800b4bd4e3158a1d663ce5243fee92233227249fe4bb8507e8cb2c3729744b273bf488ba60c"},{"one":"99a7649bdf2ee7f0bc049308b0997e33abb68481c05a573df9aea30da5a1f267df07b2c584e3e985baf31704f04ad2a2c4876e0f8555333be6d09f5080b583f1","up":true,"other":"8f3e9102306a13adb91e01f7a847e7880054f1a7df8976d05facb3a8fb37d47cce04f25e18a19713e5c3da7541e96e829fc67c8b924b717d2d9586c9c12d4fcf"},{"other":"b183f12f3602bfdab0480cb0b0ba7dc69b267b0dbc7e54c316741cb78b9e99aa69fd321ad7755d095e9be14e6bd90fe14ef8fe9bafc1a0dea10a144795021a08","up":true,"one":"431644cf162bc267237c4e798288888dd835c1b0546b0cc679782e33568988d75b4294f4aa08359a6b152ed9a0fbd13133681156bcf09a871c4f362615ea6dae"},{"one":"202ae63076a5560418023f00c9965b2a1d12de932b5371ae270d63db88551a7aa1a3c48841f81948fad3435bb4a7e3e165a2eced9fd937444e4502471e23dae8","up":true,"other":"01427ba4d1e2de0b2764515556676a6058f88c16f597780dea3d7f95a6eec9299c3987d99c199d88a0a5e695ee6f0ff7de424e4eb65e54233b956a9634133998"},{"other":"bab07c2e4dc09add884869b31fb474b6d7151f9cc331d831f55c2b088397370fb0a1e1592c8dff9c8bc8e83de9faf6e91683acfb2df1b41856d70e523a99d370","up":true,"one":"362ed9a92b588d5fe315b90a74aa27f7600e4a7d06b27ceb26272340388d916a831df85bf83450ef80bda4e4a21acaac60560c8a42940a26e2ac567519e2a202"},{"up":true,"other":"99af34b172d319633e07a4e528f416024653a230a9103a4b281171f75bb697dd6be4757558c94e86210b4da8d9fe1229f6a5d8c4174989ea0ce696f8d1a9995d","one":"bab07c2e4dc09add884869b31fb474b6d7151f9cc331d831f55c2b088397370fb0a1e1592c8dff9c8bc8e83de9faf6e91683acfb2df1b41856d70e523a99d370"},{"one":"a48cd04cdc66e1bb182529a789e1417d60d5e7d0f73068c1b17c6f231defeb943357789123e8d89cad90d1dd1726c48b808300d213bc1ddf7ae43cd58527f1f3","up":true,"other":"8ee65c0937cdf860d5329132c34bf28b5dc4d2593986fae80e4b35efb54ec24cdbf294223515363a917a22dbc6db463c10c7484e22b479b9010059c2521b6317"},{"up":true,"other":"207764262a208c17db61fda4208d4664bf74010e0ad051a863e131e748c9304e11ccf007c925488ea86b974ee61cdac3dca4d4b3f4043524e03c194ab3c8eb5a","one":"7dd2801259c071a6e1dcc01d1cb74775fdec92da1da0b1eaf5f893cd5ed118894493ca5284c12bbd6cf7959449bc610d26ac6c9ef2845d1645d425f56ac003fd"},{"up":true,"other":"c0bec7375c66bec98524ade2245c1d7480516fc5d87a3249e64ec86418e80e202f1e3da76832e97bbc3dcaed8c96ca344e4829347b4428f4b1cb61999e404c05","one":"b4557089e4247379e587a087f53b36dd1f86f85d9dcfab5dc562079978cd959adaef5b30d11258d9cb552e7c5abddf5377a71d449febe8f2acb0aec3ebd8ba73"},{"one":"b60def37233dbbc0d5f7fcddb304be1c0b6508e1e3d8a09a8290f7363e9bb84152dcaf70b8f6bb3a882fee77ff03ab796a5c1c3654f251c9f5c746ac5ad88556","up":true,"other":"77811b007dd1fc1b11e447858df37062e97b6fc14e059399814f3b4736188e3fb28bf7c3958bb8ebc6ae16c36884ba7c98b810fb6f8b358323412123c803abd4"},{"one":"eb58e478b16056e0af344397cf5f078a3312a6db2189ec2042ec06ab6550e3ee71ebcfeff1814332c552c12a5a488f96b3f2935e90a189d238da19d30a2c9874","up":true,"other":"8d3ad57509b36c4ca5c4663f3d1977a3125e069078842634e6cfeb22c044281e3d02f06eafc6d2a60089f03d70f5134a6635c35563c9f911fd845a6ef9bc8952"},{"up":true,"other":"bc0df855bdadcde3e447415444f655eb430925a8fa81cdcac75909e7d79750f01827938570e75e388cc7058ba8ebca47afadf8b07172bc078488fb618ba71024","one":"2880e0defd1bf2665bdd20dfb46bc0a9ad707f495211fc78e611ab479d78398db7daff7d3f4b6bf81fd13bf766ecc8271e0ea99a2d74abd2f9ddf98835ffdcf1"},{"one":"1edeb91789b9aa996fea7a70964e0be33ee50acbe6d8f7d9d9fcf6dcf755dab6402637a610116f0eb716b19259429bdcced8bebc28ffa334387a430efc21b9b0","other":"a25958cf192a4f62301feda5d442535f78b983dd9e4599354f4898c8c1e6ad97ca7112549e1d1a1eacb4682cd1bf8b762368b5905ab33dbdacb585b128514ca1","up":true},{"other":"723f362e98f90d7ef15e24e353759fdbdabb08adab767dba73ab546741fac3dfb457466f1e2c851aa49526da1408f8ddb509e12f7dc0bc1e785c5b72be8a986e","up":true,"one":"c206d8689068488179e86ce549de75989e0b17cbe09880d18fcf0fa212e629345f1b899203607a2b083569cb3f8398e501843166f5db23ac7fa7dacfe26dd3f4"},{"other":"e8a679f627d03347a4fcec0a0940f7ffa90ce3fefea290db3af4f3a32d27965bfb51832b6a6de2495c8a8cc026bcf993b84a0cced778e158bb81c034f5e4bd76","up":true,"one":"29619924833116cb1160bf7a8066a528b7182794368bfae62b5bacbae680d9161a479f217e30c3b4f19a250b1b59e08f86c94726117dc3bc94ff9ceac6bee6e4"},{"one":"4ff2981a47da46c753090e193a8bf43c3372a6b07a37cf0552de2ced455fbb8a76d969cd97b3e4601d8a808bd2a73f7729ed8a61df2f2a0c2cee1425d0bd9ab4","up":true,"other":"a48cd04cdc66e1bb182529a789e1417d60d5e7d0f73068c1b17c6f231defeb943357789123e8d89cad90d1dd1726c48b808300d213bc1ddf7ae43cd58527f1f3"},{"one":"6909a0fa47718cfc463b1e96c21734b46bd5b28dd59cd3d66d67990783436b7538ab2659d427029b97c8dddf313b26532518c0c34a2b1fca8cd852b0fdb83ab8","up":true,"other":"8ee65c0937cdf860d5329132c34bf28b5dc4d2593986fae80e4b35efb54ec24cdbf294223515363a917a22dbc6db463c10c7484e22b479b9010059c2521b6317"},{"up":true,"other":"5717a49591a0ecdff3d4449874d5ff9ba016afad5da19712ca0c8ebca8cefd84e6d8c778245f67f68c8dd730ad294fd017b8de279fde4fc919768ce85dba132d","one":"b9c7b885430b9b1a4425bde30b3629559f5437e0e30a0299fc6f6e097cbcca8af9e285caf5dea685a0237f60e06f490c39a1e3e487f14a2b9f41a5135f2ba994"},{"one":"9bdacc256acef0433805477d38f32be849a8846d88cb883b19d290454639b42c6ab6c5c52d4f83453e8a156af7d85f606458aa9c0977c67282f56f34ff0acbfb","other":"682288e4dae2374c4784acd0b285508920ce39a6b72cc0e30a3dbb7972e0394a2bddd5ee5f22a1dbf80f284dde4d9f8ede7847318d5353566b35a83e212477e7","up":true},{"other":"f52281c227aa82a3bd5fabfdcf8bdf1d9ea6739ab9b9075340143d59b4f2f8a79a981609c9f42823a0253c19a7281eed0e912e4054363ab7fe50117563ef14e0","up":true,"one":"c674c405068bb908312917a319e24ddf90e814ee8ef54bbf740f176b2a7eda6950e3e1ed69484ebcc27b13d82c7f0b20daba71a17700018e769ca612ca8d2208"},{"one":"7d9979c13cd8841e84e5d199fc263962ca6fee12664d8526a581bfcdca2e3427ca169b9a0244dd8292a9a1be2bcedb0e8f626eadd307068c11c03b6df13aee33","up":true,"other":"df9306a263f40e0e255996500523354de3cc78b68ae560f66d79f6ea28f30f773f1fd6ebc33928723dfde2ee3d4f982b203bee4c3803a5050df83477045bb279"},{"one":"9ea856ea440c776b9ffaad1237ec11d570a1f912a908b8363ff97cf7947d2523e3c73663240d8fac988698cdd81e877ddd4a609485fe9f26494136fae14212df","other":"bdd17545242bedba1e4c36fadea95db655f8f220f10ae143084690a3c8d4e7ffb79a64af9f1bc8514addbd63695b2f20857e8d162f25318faac885f77b385138","up":true},{"other":"b4f300abda4cf6e383f997510eb681e9fa62e23577e3c19bd7447fa1f5702a4e034cea5944248e7c6e6e92b5ae69195c3e8a2c5ca7827b4f4a00cc8546e6695a","up":true,"one":"2abb91884cc3a8fb91b2f2f369f9430f2b3b05c75ce6203aa7a50312c9f141f9d0f615063d3576a5ce8a4be9ecb942aa804a717f76d9e8dca03d115dcc43f775"},{"one":"936fad959da2d8b0cfb2bcd78c5da65bcce5e9463be7fc7367f45cdfa20678f4c466fb1e3f600783a270855fd4b9cd6265054f79ecb116141e7c67a492041bed","up":true,"other":"ab13f773f6f2ff73032aa5f79c8897b75dda29bcbb14aa511e9401c2417dc9c510253071e28c7833c8d62fd2aef16fcd0c14ce016fbf4fec1b9a2173c717603f"},{"one":"7b4585f8a4e4904239994a1b8bdc76299da8e46a8a632fabc6c33dd4170f8f3715e4c4f526ea5dd14093b150855960e432b1b140594aca21995f9e0722fb57f1","up":true,"other":"c674c405068bb908312917a319e24ddf90e814ee8ef54bbf740f176b2a7eda6950e3e1ed69484ebcc27b13d82c7f0b20daba71a17700018e769ca612ca8d2208"},{"one":"7cc9389c8f751465e0b94baed896f6f122631052300b1b5b23d3c7656e4d11014a7a9ae62a1287bb040ca37221871a566cd470e523846df7e3acb5f94c7cde06","other":"49215dfa786bfaa52b1e7aa6899392711a770b2504c82f536381fb1f18df16960257d75530efabf6dbd2b1361decc29758f870b318f777decf51f4833a9c1f00","up":true},{"one":"5a6318af8b4615cf30610a05ade7704182fefd0a3fb3d76c47cb392e114d8d30004f0ec214326b11532fd1e928e66f632bbcde126a94c87774063853a9518dc5","other":"207764262a208c17db61fda4208d4664bf74010e0ad051a863e131e748c9304e11ccf007c925488ea86b974ee61cdac3dca4d4b3f4043524e03c194ab3c8eb5a","up":true},{"other":"8e65496318637446a51f0dc87d0a5cf82655866cd1579db1e381af52e12545172b9c88119999ccac3b8b8644efc9675ff183ebe7584c16eb40792cc21f7e9b76","up":true,"one":"5a6318af8b4615cf30610a05ade7704182fefd0a3fb3d76c47cb392e114d8d30004f0ec214326b11532fd1e928e66f632bbcde126a94c87774063853a9518dc5"},{"one":"6c95c653e15bb99d32656f35790400134cd7188e063f878e19cb9118eb469ae0362dc45255f2a1eae31520be01d42b5bc5bbebf03d644c9f206ca79cb33a01ad","other":"545237d8463b75fd2e9bbfbffb35c5b78b4abbc85f6bfbd56976789012dd9a62ca1f866bf37bb33618e026aab764adb9ced5e00cd415562f69992f74c795083f","up":true},{"up":true,"other":"877d17ec7e95998ead831606d3363fbff1c8d1fa377b8e621e6a876d2c7776b9af356211a7e4df66adeaf38cf9b49c04871e8804edde4c18435ff45e110ecb04","one":"884d32d09dfef937f3ef1cd6fb5f530c2c574487c0ffd4185ca405c8b2ac73044a196c34352e850ce15321eec6579da654a696381f3e5830d03c7aa18923da6e"},{"one":"02fdbcb00f20a3f6e894900d798fcb0aca9e21f5b107924c0999eb396220f16dee99fc80ccba796e66e69dcb9ce278b7e0e4539c7a7cd0fbc1037bf8e56c1e67","up":true,"other":"1e3a2f2491b6acb07a9549d9929d150479a0313c926b0e236237bd541303da4b563a855016a90ab50e59d94803ad566798570fa981464c94c04a4a4a94fbc607"},{"other":"17ae0b24297a3e6e027884e5e4529b6646ae340f5736eebc6187a9b59832a445f3644172d92438351e3803e56a67472b29f3e1d48844ae2e11e5e6670eed1436","up":true,"one":"aa2028d356a88eca8e0fcaf218d62ace099c3f72dfd95bb28f30ac9a926034cf1d60a40511f7495652745de80d71c0f6830019e206c88e2b6ef0cf4f05d7fe9e"},{"one":"1489ad735e1256900e4733707f8b78f1d853742a8f9b2d0c1c89651c60e7ee9d266afba5b4c1ed3f9cee05a1d2b2bba35dadb5b08973a93fd70dfb9e367339bd","other":"855667650e96c5ed2d9b0c82532ed1fb92f72b1ae926afafe09cf8f6e90e539aec5c4c2ab108f2c2a1ad7dd8b83ca92a98c550a1c9ed27e6632a7d2f6da4f970","up":true},{"one":"fc9b1b2bbd5e682eb350d23f3ee33b245495daedae9370de7b1f55f91cd45db831d196c17615e11decf6b67696a268ac788130e3de38c7f6aeae811f3ec8c8ee","other":"3f322f9b1f1f0692663bc3be11cf11386f4a14696aab610916cfcadf0234cce0c86b51c85ce2108e9bc21d50ad71cc10a6eeaec3fc7732908f3a8b193465a0ac","up":true},{"up":true,"other":"49215dfa786bfaa52b1e7aa6899392711a770b2504c82f536381fb1f18df16960257d75530efabf6dbd2b1361decc29758f870b318f777decf51f4833a9c1f00","one":"ab1a3542d67ef9d1a63653990bf0782f53b0169fe5092adc92fa7aeb38f66c6b62d49e3455cc2ac4994bfcfb03111953acf4cc3099026672cc61f6e24cb3ae00"},{"other":"9ea856ea440c776b9ffaad1237ec11d570a1f912a908b8363ff97cf7947d2523e3c73663240d8fac988698cdd81e877ddd4a609485fe9f26494136fae14212df","up":true,"one":"c9d705012a06d82c4d44db95b4f1c63ddd33ad64d732e96b1d878caa0caac433d4096f01495a6f0e8a56af122b0470fd745db6d906353b590a4710472b93f5b2"},{"one":"8ec699020ab5e7719fe23b80268b5d1d37052bb71f5d81200ae805cf27825823733206165f0a7507c2595853361dd122e9ec1b2deb543591e22b71ec0b873b5b","up":true,"other":"17ae0b24297a3e6e027884e5e4529b6646ae340f5736eebc6187a9b59832a445f3644172d92438351e3803e56a67472b29f3e1d48844ae2e11e5e6670eed1436"},{"other":"70cce7cb0c18091dbb6d41160ab560935f1759b969bf8118cee030ee707cb15ba407b8c48dcd9fd012cbf778e219f7d16a74064b4983cf098fb118297748edb6","up":true,"one":"93073da602d6326a48464a8b6890220b3aae0abf5b6961180f3aff2a14573c43411bd519d3e0012a646ec2977be18915d95a36d935a69f93985f5307ea4e3ebe"},{"other":"ea2921612b827e3c26328368bed9be7cbf1f2b2aecaf31863c9cdccd74c56b651d6eaceb8ac9609a6653488837ded310df91e53a74789ae75cb841e2aeaf96df","up":true,"one":"6c95c653e15bb99d32656f35790400134cd7188e063f878e19cb9118eb469ae0362dc45255f2a1eae31520be01d42b5bc5bbebf03d644c9f206ca79cb33a01ad"},{"other":"e0875ed6be1e163b15c13cdf37442f838670d0949349ee9ff119a0451beffb1a302943ee9d7cba48592922f64908aeb0f39f6e2e3725d1e7cdc5db34083b6977","up":true,"one":"0e164c8692532e59c76ef84319a1093324f46f77618d3a836a279df52edca6c839061c0582dac7481da1bd0f3e2b58fc0dacd6ee5d678ba1406d4a1a25fe761d"},{"one":"9bea5f82c2a390587de44d620d6637834e6f2329cd83d8df6305b03b75d9b543160b6c6f9f8887e6bc88f1d0726435d6c8ad813aadad0653b0790b8f6388413a","other":"bb0749de05a97daa67de889c15831ce39a080d641b3b08e3c248b0b16f4c07943fea8dd054d4a7e3e4af91ecff07053ce90096485a360b6f1d93050d179f30c3","up":true},{"one":"1c080e90760dfcee08ade6e4ea3b275ff3c6882f3b44b7f3a73d70bcc816fc63ce0b6138f810d17d96ed387076f9bbb6dbb2ef6dc4d6ba6542c1f587b7602a12","other":"1e3a2f2491b6acb07a9549d9929d150479a0313c926b0e236237bd541303da4b563a855016a90ab50e59d94803ad566798570fa981464c94c04a4a4a94fbc607","up":true},{"one":"6a37e63feed9e68c52cb8b385d5e8d8dbd2b211c57ded0d3b01fe8b306af5c0e5a7405d0d9a942648f0131926240d53450bc43f922a053528e5830d918313c3d","other":"f056acbdf491d1bb091937335c10096ea44b7034e994d134bc16d55212ff049bb097424de96c615ea699359a7ef77b3b54def2b3a5f43d735ffda65f73d61f7f","up":true},{"one":"c0164fb4a1acfb4f3b1a09f9f3ab226c382529a73891937c6f3c91798098cf10b909eb92e5f8acfe0e8f3aee0b71cb23ee2d9e6ad1e0f4492a0272c52d529849","up":true,"other":"ba430731fc2082f4217ebd859c2865c28bf50a39674ca8615dd89f608ae434a09657e24644ac32807634aad7857547118c9228460195e50ec58b34789d4ad151"},{"one":"77811b007dd1fc1b11e447858df37062e97b6fc14e059399814f3b4736188e3fb28bf7c3958bb8ebc6ae16c36884ba7c98b810fb6f8b358323412123c803abd4","other":"8e89fe4b3fffea8af247d2581aa511056efbeb796058d50a341d57aa0f7ccc2192d90cfb8d18558363df798567faaddb86815e8bd671b36ca37af0651535aabf","up":true},{"other":"97b1eaf8274ece76d75e7f60126f1b351ed5fe55088b9fcbb825a3a8d8f84f61bc72469916b280497dabf01345057525cae89da73c9a1a8a8cd19367d44dede1","up":true,"one":"f60755ee9464c7db769bb7237016fa165441d18ac3bfed7cd2a220a9bcbead202dd34eaf2f9398a3d36bdfc2671bbd46ac25ebe264a8118afe1b7d0bd38710f4"},{"other":"1e3a2f2491b6acb07a9549d9929d150479a0313c926b0e236237bd541303da4b563a855016a90ab50e59d94803ad566798570fa981464c94c04a4a4a94fbc607","up":true,"one":"313a131ecb7d68e127d0fec8bb4a2e586886203c3d07857a93e7a39bb831703184d9ae28ba9ef3d986c2dae1a24f4f5bfa47cfc35f74f5512a126836364d7736"},{"one":"002cb6ffa63ad71ee6ebc1df4c41f7a97c51f274b1d3b22420c87b73136be5169b9670508061d8261e20055fefce3b855388994672aa9a0f1475c43839aae4fa","up":true,"other":"6b082a09e343a160b60a01f74641c1d707b2fa8fee5f6f5a8b9e4a203bd86434227d2df982b246a752f843483cdf517e85fe3bd65453354232a6eb38dedbf314"},{"other":"70cce7cb0c18091dbb6d41160ab560935f1759b969bf8118cee030ee707cb15ba407b8c48dcd9fd012cbf778e219f7d16a74064b4983cf098fb118297748edb6","up":true,"one":"01427ba4d1e2de0b2764515556676a6058f88c16f597780dea3d7f95a6eec9299c3987d99c199d88a0a5e695ee6f0ff7de424e4eb65e54233b956a9634133998"},{"one":"93073da602d6326a48464a8b6890220b3aae0abf5b6961180f3aff2a14573c43411bd519d3e0012a646ec2977be18915d95a36d935a69f93985f5307ea4e3ebe","other":"af9b80f6836113aeda897d6903e9ffb4f7f1a706a7f821d0d40f03a0d83c18d6a19795ee4bfc1093ada04014415b1f230db1d2f056df3f5027cce71611588046","up":true},{"one":"37adbfdf66163e45f433d78f63210163fdacf4688ad90d73bed07975be017c43cddf2a26a0dee8b11d78f294b63d4875b6be15f42f10817bd3d77b342919a11e","other":"545237d8463b75fd2e9bbfbffb35c5b78b4abbc85f6bfbd56976789012dd9a62ca1f866bf37bb33618e026aab764adb9ced5e00cd415562f69992f74c795083f","up":true},{"one":"d09104c44648391693ca64a57baa5ef54ed717e19c65ad0a0921d08cbaca8877d0190795d15f75f3b6ce6e676d6b0e55d5ee8fec3310c68b7060a32f7ff649cb","other":"c206d8689068488179e86ce549de75989e0b17cbe09880d18fcf0fa212e629345f1b899203607a2b083569cb3f8398e501843166f5db23ac7fa7dacfe26dd3f4","up":true},{"up":true,"other":"f056acbdf491d1bb091937335c10096ea44b7034e994d134bc16d55212ff049bb097424de96c615ea699359a7ef77b3b54def2b3a5f43d735ffda65f73d61f7f","one":"f5d95e0c5a873ff5a95e1eb34f1ed258d77adf98ee0886d93c4a24b1feaf6955e6e4c4ea0eccb2b9723870bae61e693643d6ad96dd8da01672542611f7c49069"},{"one":"e7b2adabc2c99ac47b1e94fc0a2c63a00a1d622ea67a4c1858f4cec93fca957d43d8429605761bdf5eed4f733dac1a3d12fb928f22abf248965994acde63864a","up":true,"other":"e0875ed6be1e163b15c13cdf37442f838670d0949349ee9ff119a0451beffb1a302943ee9d7cba48592922f64908aeb0f39f6e2e3725d1e7cdc5db34083b6977"},{"one":"e0a043f98b462f10f72aa61ceda52f9c27829d086f6f2c5bf4db4fe32759002e5ff9519495d57dbb83d963a1dc991a1defcf5b9ef0d543789f38c68f5d07122b","other":"f98c0f4444a1ec80773454ddb691c226b81d8e2f79ed40c45a422d3359565edf7bd635d3eb7bd6c9e0870746849fb86f0b1b34cd56ec8d3ad969812e080f4983","up":true},{"one":"9d372d73848389cfa1676f0cdb030950980ed5b68d5b2ef8a058f1d2095b26ff0fafab5fd3c243296ee2620edc67752970ab47370270856287f8612d1b190a19","up":true,"other":"fc9b1b2bbd5e682eb350d23f3ee33b245495daedae9370de7b1f55f91cd45db831d196c17615e11decf6b67696a268ac788130e3de38c7f6aeae811f3ec8c8ee"},{"one":"33cac8f621b9122e118036154778d27dc419b6b58ea2e89b833f3932f411dbc3511d92b55ae4cf80632142bc8e67994899aaa30c499d0289fae85b12564cf01f","other":"6a37e63feed9e68c52cb8b385d5e8d8dbd2b211c57ded0d3b01fe8b306af5c0e5a7405d0d9a942648f0131926240d53450bc43f922a053528e5830d918313c3d","up":true},{"other":"97b1eaf8274ece76d75e7f60126f1b351ed5fe55088b9fcbb825a3a8d8f84f61bc72469916b280497dabf01345057525cae89da73c9a1a8a8cd19367d44dede1","up":true,"one":"b3b4b203395bb6655d79ecdcee11638dd9a16baccfcc1f6fcc8b31832c8ca35650eb6c2802104eeec6d96ea80404381a2bd9b01dcadc748a4666b761d9ce64f8"},{"up":true,"other":"fc9b1b2bbd5e682eb350d23f3ee33b245495daedae9370de7b1f55f91cd45db831d196c17615e11decf6b67696a268ac788130e3de38c7f6aeae811f3ec8c8ee","one":"b152eb30c9f46ec39166016f03d289f98cc285ac62d204da32e5a003da14e4f02c64df8ae1d0c8a2a902adc5f7dd7604081a0b140c9b64052082f0861945f5a4"},{"other":"bdd17545242bedba1e4c36fadea95db655f8f220f10ae143084690a3c8d4e7ffb79a64af9f1bc8514addbd63695b2f20857e8d162f25318faac885f77b385138","up":true,"one":"e993be8034861aebc9bbd11115f25d9c719d43fcdefc323599616cc26240cee38dfc27bb7f339149a54a3c9ad13b2d6ca4f0ae690e4355605eda6b789c4a431e"},{"up":true,"other":"be93fafaf43f6bb3efd2667d1468a8636cb752b245328eaa01468c0606d790322a7cd8e47857068e60118e28b8dd8aa1d2d4977c5b3d28d4b47f4c0658f05e90","one":"4b332b389f1142c0da42aaeb2e2692081d0002de0eb6741b3269e898a8101571d4556b755f2e8841e7a607bb41e398d2b0577fbe71098e7097f0fe6c720e1526"},{"other":"2bea7540c99456ea889a8ba2e448c11e6257bf987d01f13eea48128ba58577ab0936855035ee140c9907e382a34ca85a179c74892cbd9eb92fc2b35601addc6b","up":true,"one":"4b332b389f1142c0da42aaeb2e2692081d0002de0eb6741b3269e898a8101571d4556b755f2e8841e7a607bb41e398d2b0577fbe71098e7097f0fe6c720e1526"},{"other":"207764262a208c17db61fda4208d4664bf74010e0ad051a863e131e748c9304e11ccf007c925488ea86b974ee61cdac3dca4d4b3f4043524e03c194ab3c8eb5a","up":true,"one":"a47697063a2fb973449bdabd0925e10944ba1f6d8b2cc5c38b295f611eea3402b5cf3ae857716a34d84194955f5ed61350affe56223349124c8233852141f9a2"},{"one":"da22fb43c6d230d92f9c09454e282dc45dffc759740566039f1bdfb58171c6801f721841de83217277b3fb70983e7d34da53bbf25d1d45413a78d9afff151826","other":"4ff2981a47da46c753090e193a8bf43c3372a6b07a37cf0552de2ced455fbb8a76d969cd97b3e4601d8a808bd2a73f7729ed8a61df2f2a0c2cee1425d0bd9ab4","up":true},{"one":"877d17ec7e95998ead831606d3363fbff1c8d1fa377b8e621e6a876d2c7776b9af356211a7e4df66adeaf38cf9b49c04871e8804edde4c18435ff45e110ecb04","other":"bc0df855bdadcde3e447415444f655eb430925a8fa81cdcac75909e7d79750f01827938570e75e388cc7058ba8ebca47afadf8b07172bc078488fb618ba71024","up":true},{"up":true,"other":"90b8e73916046b5433dce049bfe125ca2bf2fb390ff7301f9bc5d8d0183988577aa2a7392aaa28091aa81c8ac23942b5751420b9ee48e488a68411f9d2b1e5d5","one":"3a2cacc430f13f31c52b7205455420cf0fb9ed9e28b0898b69ef97951bf295b29118e573a42dd97abe38fee5ab4c03dad9ff6dc448126cefc1da12b6c8e8d915"},{"up":true,"other":"d43bd6d3ae39a04e4e144a8a6f80b2d54472b5b9b6491dccf44b1716a63d24c56e3a871b3b8fe983d992988dc07ace06736ead3b1287914b629fcfe17e81f36f","one":"6c40910f0556f892a7542989fa01d7e3682fca89aeefb5ed885808f88ff17b6d13862f461c10d629a005ae67abef542d75e5b20816891b6944f71560f5c2dfa8"},{"other":"c03ef1de42d522b44eef53be11f2c57b8b74fed9e87e6c2928c1feb48ddfecc67e1a3a8c8be1c47b3735a216d7054e2a4dda49fbd9a1ac702146aae5bdeced7c","up":true,"one":"8e89fe4b3fffea8af247d2581aa511056efbeb796058d50a341d57aa0f7ccc2192d90cfb8d18558363df798567faaddb86815e8bd671b36ca37af0651535aabf"},{"one":"b18c7131a319db61ab84d06e90092d93c91141e9a270630af9c3ab1eaf3bcad09f4d20a1fc845b21c994bf4d9e337d0bd756a75e2198097540355e7ebbb531b2","other":"d6747e1f8594f7449fc6d7c0e63ee843480567d498db096ff04229420861c83bca5215fc19d8fede0c54484f111f1f2581e189e638c21c5d9e1fd3174bbb3e98","up":true},{"one":"28cdd55fc871ffd8d63d05994be706959c9780dbfc859070a41047a1b40dd5fd7adb53919400a4c6f4d06c69bc1ecccc0e230e5b702598a7fe8003a282479872","up":true,"other":"bdd17545242bedba1e4c36fadea95db655f8f220f10ae143084690a3c8d4e7ffb79a64af9f1bc8514addbd63695b2f20857e8d162f25318faac885f77b385138"},{"other":"d3cd2f34f67830ccdc295b7537a6d27c02b44503808ca666124f52ecc3d6c35b7d3f14343997006aef2cfbefc8d27809d389477e99c236b9f8a897a4bc406a43","up":true,"one":"be93fafaf43f6bb3efd2667d1468a8636cb752b245328eaa01468c0606d790322a7cd8e47857068e60118e28b8dd8aa1d2d4977c5b3d28d4b47f4c0658f05e90"},{"one":"224c3b969149d50d1bb4f473bb9725223c1dafe152efe1b08e8859213c543a66565b5d68a99cef3d5f4eccad6282a12f78d7b38eec14deebf44ad8dd9cba8680","up":true,"other":"588df3185f63a5443d8c6b972f67805f0557184d916005f537a4b27cd02bd6a12e432a2b34b234a34f22e923c6f116da85be20bad77a2bf69913684e9d0732ba"},{"up":true,"other":"46717bc5fb7fcbcdc961e7ef091020f9f222858cf3d4afcc0b0bb1b782b7055d9eb833e0a04cb32d80406133ac77162521c43edf9f9690872222760e31462ccc","one":"f056acbdf491d1bb091937335c10096ea44b7034e994d134bc16d55212ff049bb097424de96c615ea699359a7ef77b3b54def2b3a5f43d735ffda65f73d61f7f"},{"one":"37399617d62153bc471f3bf21c92385bc8602c80ffa0c71da8aebae595a9859cfd56257aae60ad30ef3ec4d07dee90623cce63749c8c3233c0aa0d17f9e89afe","other":"b8e0a56df21baae43058f575b714ae9a33c097d18f1a628b3b6ae5e86dd46a06e44c0dc272baacb5be0f7bf57fd6ddce107544eb3b94dca1aeae9f5773496a72","up":true},{"one":"7c6e6a49429a4e24aa4aa5c7ba19684f77cd67d3744688baff6e7f1d74b7e9d2df85f3e57e0df0a9b960b5bf982a610c5639c3e7a6935ba13fbc77243b2dad19","up":true,"other":"bdd17545242bedba1e4c36fadea95db655f8f220f10ae143084690a3c8d4e7ffb79a64af9f1bc8514addbd63695b2f20857e8d162f25318faac885f77b385138"},{"other":"f4cdaeb513aa98f8868d8eb3a1d12c07367725928a1bc7d6ca4b583788e111a955463037ec7867260511896d97dfbf096aa77ee8a7d9ea1c06cad4a92c45108d","up":true,"one":"85b6404a76b4762156c8ddd2f312763dfe19b315d914533844cf229301880c57ffeadc0eb5f4a8d542e1d9fc961dfb5a572d2101172b1a0fc238ced05ba49ec1"},{"one":"ee0b09ee6a1057c47102e582e2fdec7b9212802e59f062a9360da0db535d4987126ab24848c0d76fa8485431a5140307e2b0c0d9f37cbdb35756e6cc1bdb3bc0","other":"2b0a1f3a6466c6be1d7e84120db384fa37f7c73a01e9a105ae90e7d2203212ec974f016d3012afd26bc0f9a8411d0716cc59b6ecc9f665db12e306af8b34cb63","up":true},{"one":"588df3185f63a5443d8c6b972f67805f0557184d916005f537a4b27cd02bd6a12e432a2b34b234a34f22e923c6f116da85be20bad77a2bf69913684e9d0732ba","other":"5717a49591a0ecdff3d4449874d5ff9ba016afad5da19712ca0c8ebca8cefd84e6d8c778245f67f68c8dd730ad294fd017b8de279fde4fc919768ce85dba132d","up":true},{"other":"ea2921612b827e3c26328368bed9be7cbf1f2b2aecaf31863c9cdccd74c56b651d6eaceb8ac9609a6653488837ded310df91e53a74789ae75cb841e2aeaf96df","up":true,"one":"f4cdaeb513aa98f8868d8eb3a1d12c07367725928a1bc7d6ca4b583788e111a955463037ec7867260511896d97dfbf096aa77ee8a7d9ea1c06cad4a92c45108d"},{"one":"ba430731fc2082f4217ebd859c2865c28bf50a39674ca8615dd89f608ae434a09657e24644ac32807634aad7857547118c9228460195e50ec58b34789d4ad151","up":true,"other":"90b8e73916046b5433dce049bfe125ca2bf2fb390ff7301f9bc5d8d0183988577aa2a7392aaa28091aa81c8ac23942b5751420b9ee48e488a68411f9d2b1e5d5"},{"other":"243164c4dd583f80c50813f43e5c27c894463400cd3afd776b36e79e7123d9261f01f06f92914aab83096b9a43fb655e79687590599284640a3a7d2c25454597","up":true,"one":"7db14fde1da8794ae7ab5de37c9e2537e1024bc830c176c0d01635cafed47773d3a28e156db81ecdb95903222b900c3ebd4c4b3db2971dc0ef6a1e386027ffaa"},{"one":"bac3fd2ea491d8e4ce1e5d469ec73f3d537d61279ae66e7a394b20a188244a886d3059ef0d304c0801878f9640374f7c8aaf56558c41f12296d3fc7f911ed66c","other":"5d002c37b74a6656db86f102b0cec82bc35a819a480e5a2952db0140ebab65dffeb1a79f04d53ff61447b5fad7c58cb75ea1c91ea47fcb9e024f27b92c6c874d","up":true},{"one":"77e7d427b65b6c29c0d92c51184af73031bfa768a47fc20be6c264f422bf718865259c17c103bf47289b3abe62f93452781c6303d757e76d3d56ceeb26262fab","up":true,"other":"bab07c2e4dc09add884869b31fb474b6d7151f9cc331d831f55c2b088397370fb0a1e1592c8dff9c8bc8e83de9faf6e91683acfb2df1b41856d70e523a99d370"},{"up":true,"other":"488854534ec5a3479d8ee13d9b7daf07479f6b5505f319eced44dad8c316f6ff241ce2101e95608ba635067f5e5741481b78f419c4bbd465bf7e837dc4e54d64","one":"3dcf18c35593b47bc463688493b792d6b9d13eabe05396e491953608f20cf55f770fc21be32b00335fcb2f0ba02735b92569b2b64a44c344ac348042876e8f15"},{"one":"545237d8463b75fd2e9bbfbffb35c5b78b4abbc85f6bfbd56976789012dd9a62ca1f866bf37bb33618e026aab764adb9ced5e00cd415562f69992f74c795083f","up":true,"other":"50c79baa3e6781482ccb5e960c699dd9c13f479467c6315c5292a396337cf3619e7faba1971a1f470051cb9042f80ea6750defe3936b72aac4d9bac6f8368c67"},{"other":"ba430731fc2082f4217ebd859c2865c28bf50a39674ca8615dd89f608ae434a09657e24644ac32807634aad7857547118c9228460195e50ec58b34789d4ad151","up":true,"one":"17ae0b24297a3e6e027884e5e4529b6646ae340f5736eebc6187a9b59832a445f3644172d92438351e3803e56a67472b29f3e1d48844ae2e11e5e6670eed1436"},{"one":"e0a043f98b462f10f72aa61ceda52f9c27829d086f6f2c5bf4db4fe32759002e5ff9519495d57dbb83d963a1dc991a1defcf5b9ef0d543789f38c68f5d07122b","other":"5982e7dfd39c527851f6ea6430b70e654d95df5ec4401ca1d8dbd1034cf7a65d1126d60b36ebbd396c9ca32e6e8515f34f9dc0a8d2980afe4aa181c8bf68437e","up":true},{"up":true,"other":"c2568576c2c9ef47aca0baca52709a4fa44b2ed478a062f7b161fac2bdba68568df371ac7754255fd07d79bb9918249a914946a6c318d579730bee9bc609922a","one":"3e7aef8260c0d9717aa59b65ce7c554e53b81f19f5b9400321704a7ddf5041b0fe31b5634e90b93e6984060defee0e153997bbfe196166cc8d83165fd5eaf41f"},{"up":true,"other":"1e3a2f2491b6acb07a9549d9929d150479a0313c926b0e236237bd541303da4b563a855016a90ab50e59d94803ad566798570fa981464c94c04a4a4a94fbc607","one":"6d0a09235ba0b0428938abf0e0782ac0ecf5697ef862888719a34fc956517aeef89d5e5f76d12e10067fee5bac8781dc10400eeb35c2393b9382b2a4f68f7939"},{"other":"7958d1517de1223e7fb30acf61d8618e49fb95a03bc2f49141f4c7967bc80b90e0dd526c205639de3c060029963d43813293c2556f7b127945c798f3f9f18626","up":true,"one":"77e40e42f570a217f707888c714deb31fd70c856ae4b9a44ec7cee02768185dc4d7ed210429607f06690b32edd9fb06b304aff330a3949cc2fd49db1bc392edb"},{"other":"2b0a1f3a6466c6be1d7e84120db384fa37f7c73a01e9a105ae90e7d2203212ec974f016d3012afd26bc0f9a8411d0716cc59b6ecc9f665db12e306af8b34cb63","up":true,"one":"49256eccce3e036928a4b6b346126c6777dca5ea0134de85efca340f97ad0f827f3094f1562e3e186d35b8292a50c20ffae01409890bbb78598494285e14dc2c"},{"other":"855667650e96c5ed2d9b0c82532ed1fb92f72b1ae926afafe09cf8f6e90e539aec5c4c2ab108f2c2a1ad7dd8b83ca92a98c550a1c9ed27e6632a7d2f6da4f970","up":true,"one":"37399617d62153bc471f3bf21c92385bc8602c80ffa0c71da8aebae595a9859cfd56257aae60ad30ef3ec4d07dee90623cce63749c8c3233c0aa0d17f9e89afe"},{"up":true,"other":"e0a043f98b462f10f72aa61ceda52f9c27829d086f6f2c5bf4db4fe32759002e5ff9519495d57dbb83d963a1dc991a1defcf5b9ef0d543789f38c68f5d07122b","one":"c206d8689068488179e86ce549de75989e0b17cbe09880d18fcf0fa212e629345f1b899203607a2b083569cb3f8398e501843166f5db23ac7fa7dacfe26dd3f4"},{"one":"2c976b6007cda135444233c7bd03d22ac9756710b746c36bc032e7fdd42f2ffb89ca5f5e754ff96b8f3cbc474e346287e5b8531d9f98fd63c426c632872220af","up":true,"other":"9e21f5d4cfb389ac3ad43497689878bd245a89c587a8637d832b1e355ba244f4c83e6499bc7936e6d35645db25910ecd89b9af9b6b2f0c7cc4d7c6114328d7bf"},{"other":"8fb6838337f832445531764ddafc3c747b2607f2f33e244685d6de621c2b53264270f5504187e43b7fa5cda53e66dd00b16c06879c82fb38a3d9e8aec4060210","up":true,"one":"20f6a8be1d2d8b5d6a43d851a2f5475385ef07fab80ac46525d0beccf3e25c01d726cfb3a1179e8343b1e88d21684fb24dd6e6497537d4e7e9edd59cb95d1b8d"},{"up":true,"other":"1c080e90760dfcee08ade6e4ea3b275ff3c6882f3b44b7f3a73d70bcc816fc63ce0b6138f810d17d96ed387076f9bbb6dbb2ef6dc4d6ba6542c1f587b7602a12","one":"9e21f5d4cfb389ac3ad43497689878bd245a89c587a8637d832b1e355ba244f4c83e6499bc7936e6d35645db25910ecd89b9af9b6b2f0c7cc4d7c6114328d7bf"},{"up":true,"other":"1c080e90760dfcee08ade6e4ea3b275ff3c6882f3b44b7f3a73d70bcc816fc63ce0b6138f810d17d96ed387076f9bbb6dbb2ef6dc4d6ba6542c1f587b7602a12","one":"02fdbcb00f20a3f6e894900d798fcb0aca9e21f5b107924c0999eb396220f16dee99fc80ccba796e66e69dcb9ce278b7e0e4539c7a7cd0fbc1037bf8e56c1e67"},{"one":"e1f23e1caba66f5ff821edbc4a3d527539937f73d86dd0df43aa1266a99f51f2480a77961eff177fbbf852fc52cb9317179f80b1580194daaedadc3b00510751","up":true,"other":"20f6a8be1d2d8b5d6a43d851a2f5475385ef07fab80ac46525d0beccf3e25c01d726cfb3a1179e8343b1e88d21684fb24dd6e6497537d4e7e9edd59cb95d1b8d"},{"one":"85b6404a76b4762156c8ddd2f312763dfe19b315d914533844cf229301880c57ffeadc0eb5f4a8d542e1d9fc961dfb5a572d2101172b1a0fc238ced05ba49ec1","up":true,"other":"ea2921612b827e3c26328368bed9be7cbf1f2b2aecaf31863c9cdccd74c56b651d6eaceb8ac9609a6653488837ded310df91e53a74789ae75cb841e2aeaf96df"},{"one":"6c95c653e15bb99d32656f35790400134cd7188e063f878e19cb9118eb469ae0362dc45255f2a1eae31520be01d42b5bc5bbebf03d644c9f206ca79cb33a01ad","up":true,"other":"2abb91884cc3a8fb91b2f2f369f9430f2b3b05c75ce6203aa7a50312c9f141f9d0f615063d3576a5ce8a4be9ecb942aa804a717f76d9e8dca03d115dcc43f775"},{"up":true,"other":"a58a4db7a96b1578935b222c78b7b4dd8b3519d2995c3616e5a154c5175242a503097771332504638a0b321b9574110207f9a7d77b109d1de3d66a12ec6498e5","one":"d09104c44648391693ca64a57baa5ef54ed717e19c65ad0a0921d08cbaca8877d0190795d15f75f3b6ce6e676d6b0e55d5ee8fec3310c68b7060a32f7ff649cb"},{"one":"c6ad9b9de5cdbe28540f4eb7c66fb37f6d4295e6e60c6de54e2a45c1970b8e0047558e986bbd10e9e86c8bb0407846fac4823e4570e8a1486fc4bf55cb4a0986","up":true,"other":"1e3a2f2491b6acb07a9549d9929d150479a0313c926b0e236237bd541303da4b563a855016a90ab50e59d94803ad566798570fa981464c94c04a4a4a94fbc607"},{"other":"77811b007dd1fc1b11e447858df37062e97b6fc14e059399814f3b4736188e3fb28bf7c3958bb8ebc6ae16c36884ba7c98b810fb6f8b358323412123c803abd4","up":true,"one":"b7cc9044d021b19cd8a6d290d21f1c91fd5deec472583d0aeed0a6aacc8efef9968079254132becc5443df14dd3f4feaee56d14b885c078649727b9659139fa6"},{"up":true,"other":"6d0a09235ba0b0428938abf0e0782ac0ecf5697ef862888719a34fc956517aeef89d5e5f76d12e10067fee5bac8781dc10400eeb35c2393b9382b2a4f68f7939","one":"f4cdaeb513aa98f8868d8eb3a1d12c07367725928a1bc7d6ca4b583788e111a955463037ec7867260511896d97dfbf096aa77ee8a7d9ea1c06cad4a92c45108d"},{"other":"ea2921612b827e3c26328368bed9be7cbf1f2b2aecaf31863c9cdccd74c56b651d6eaceb8ac9609a6653488837ded310df91e53a74789ae75cb841e2aeaf96df","up":true,"one":"29acdd4c1233441bd40f98e245ecc9de94de6f9d0ab7c1a9923d833a2c8e6c1bd26d792686fec762b31fe28bbdd7aa04c9a594d997d08c133bb24cb2d877595a"},{"up":true,"other":"92dbb67da2b99a8fe46b1e510addc2b83e357ac0b5287b7ef5c1b1bc6e252b8dfd605a6896ede65848e429216d1f67d530d9e7b83ff14058aa2e5b6e405d6801","one":"49215dfa786bfaa52b1e7aa6899392711a770b2504c82f536381fb1f18df16960257d75530efabf6dbd2b1361decc29758f870b318f777decf51f4833a9c1f00"},{"one":"1489ad735e1256900e4733707f8b78f1d853742a8f9b2d0c1c89651c60e7ee9d266afba5b4c1ed3f9cee05a1d2b2bba35dadb5b08973a93fd70dfb9e367339bd","other":"37adbfdf66163e45f433d78f63210163fdacf4688ad90d73bed07975be017c43cddf2a26a0dee8b11d78f294b63d4875b6be15f42f10817bd3d77b342919a11e","up":true},{"other":"202ae63076a5560418023f00c9965b2a1d12de932b5371ae270d63db88551a7aa1a3c48841f81948fad3435bb4a7e3e165a2eced9fd937444e4502471e23dae8","up":true,"one":"10551c0c37abc25457903978868dd4843a52fda5f9b571b05ebd974d8c381fda4349f17c2b986a2e4b8d06b0517422f085d5f6d9cd814efa40e48393d9f71d7e"},{"one":"3e2241cdb9f34c1d2c6930e59940e2c4b92b0287579d7263a620a609c5e66dca6d85df48cf1bffd63663a6704c42d0866aae3e484fd9a44b6a012f72dd3cef6e","up":true,"other":"855667650e96c5ed2d9b0c82532ed1fb92f72b1ae926afafe09cf8f6e90e539aec5c4c2ab108f2c2a1ad7dd8b83ca92a98c550a1c9ed27e6632a7d2f6da4f970"},{"up":true,"other":"2c976b6007cda135444233c7bd03d22ac9756710b746c36bc032e7fdd42f2ffb89ca5f5e754ff96b8f3cbc474e346287e5b8531d9f98fd63c426c632872220af","one":"ea2921612b827e3c26328368bed9be7cbf1f2b2aecaf31863c9cdccd74c56b651d6eaceb8ac9609a6653488837ded310df91e53a74789ae75cb841e2aeaf96df"},{"up":true,"other":"50c79baa3e6781482ccb5e960c699dd9c13f479467c6315c5292a396337cf3619e7faba1971a1f470051cb9042f80ea6750defe3936b72aac4d9bac6f8368c67","one":"fd0123c7b96004067e98e463e273de5bc5402399ae70a95985b5f682e30d4f35d070deaf8c71d201e98c4324d832b95aab7535ad8a2658f66e3e0bb1202204e1"},{"one":"9f3af4577308965aceb7e0101443669496e7ccf1de680629862a7005966c708b6fb52e6dfe62660246b9892adc25838da2873502e0be706bcad8f25b7ceedfa5","up":true,"other":"d09104c44648391693ca64a57baa5ef54ed717e19c65ad0a0921d08cbaca8877d0190795d15f75f3b6ce6e676d6b0e55d5ee8fec3310c68b7060a32f7ff649cb"},{"one":"3b71a324bd7b1a8fb19d8206eea1ca8190cb1faf5fcd1bfc52cef6b52296fe1db3e54d70180133fad1fa1188499d0dd73d2d075fdc6b3ffd9042d690e7d88e02","up":true,"other":"ee3471e1d835c4294f7ba642103039ccc548fe4edc177c79b63433ebbb0dc9d06600844f1fed76c7096ee9538e49e4e86fb8cffe9095dbdcde27695ff28ad395"},{"other":"869cae165389e7dee7b7df4e012ee1a39737366c306d8f4b0db4510b2236e0bd3a4d1d4af00b1a8c1d360e23da47de52fc1632edb03c7f1429aacc8aa4994750","up":true,"one":"b4f300abda4cf6e383f997510eb681e9fa62e23577e3c19bd7447fa1f5702a4e034cea5944248e7c6e6e92b5ae69195c3e8a2c5ca7827b4f4a00cc8546e6695a"},{"one":"f52297fc51b920d2495ccece290432656d9388e698339c8c1279ceea45de698a4ecbda1d25928c48f1e19e9dacd3147e23ef01acc093872d7300aed187841dcc","other":"699c923976c5b8c70c353840d3e384750f466954265f05fbb0d5877a2c0318a041dc57adc12ac6e8fbae7a00d6b6675e1a1be3a8f59dac12727ee3f8ae467a13","up":true},{"up":true,"other":"77e7d427b65b6c29c0d92c51184af73031bfa768a47fc20be6c264f422bf718865259c17c103bf47289b3abe62f93452781c6303d757e76d3d56ceeb26262fab","one":"362ed9a92b588d5fe315b90a74aa27f7600e4a7d06b27ceb26272340388d916a831df85bf83450ef80bda4e4a21acaac60560c8a42940a26e2ac567519e2a202"},{"one":"723f362e98f90d7ef15e24e353759fdbdabb08adab767dba73ab546741fac3dfb457466f1e2c851aa49526da1408f8ddb509e12f7dc0bc1e785c5b72be8a986e","up":true,"other":"a58a4db7a96b1578935b222c78b7b4dd8b3519d2995c3616e5a154c5175242a503097771332504638a0b321b9574110207f9a7d77b109d1de3d66a12ec6498e5"},{"other":"92dbb67da2b99a8fe46b1e510addc2b83e357ac0b5287b7ef5c1b1bc6e252b8dfd605a6896ede65848e429216d1f67d530d9e7b83ff14058aa2e5b6e405d6801","up":true,"one":"ab1a3542d67ef9d1a63653990bf0782f53b0169fe5092adc92fa7aeb38f66c6b62d49e3455cc2ac4994bfcfb03111953acf4cc3099026672cc61f6e24cb3ae00"},{"up":true,"other":"b8e0a56df21baae43058f575b714ae9a33c097d18f1a628b3b6ae5e86dd46a06e44c0dc272baacb5be0f7bf57fd6ddce107544eb3b94dca1aeae9f5773496a72","one":"865dbf61d8511603fe0d9ebfb10792b9f6b798187c0909039bd9b2492c41e428876f386beeac86d0dea871f4fc24ba435f0fbd9a11e74c044024934592af14ee"},{"one":"855667650e96c5ed2d9b0c82532ed1fb92f72b1ae926afafe09cf8f6e90e539aec5c4c2ab108f2c2a1ad7dd8b83ca92a98c550a1c9ed27e6632a7d2f6da4f970","up":true,"other":"2abb91884cc3a8fb91b2f2f369f9430f2b3b05c75ce6203aa7a50312c9f141f9d0f615063d3576a5ce8a4be9ecb942aa804a717f76d9e8dca03d115dcc43f775"},{"one":"9bea5f82c2a390587de44d620d6637834e6f2329cd83d8df6305b03b75d9b543160b6c6f9f8887e6bc88f1d0726435d6c8ad813aadad0653b0790b8f6388413a","up":true,"other":"842ec3faa8b4a4cdec32abfa00ae827277fe2696e1b0c6551154533b16cf75ae69caf834b4f08488fa5c8b322fb633b1fd8a5b7d436e9c589cc9074dc031ae68"},{"other":"842ec3faa8b4a4cdec32abfa00ae827277fe2696e1b0c6551154533b16cf75ae69caf834b4f08488fa5c8b322fb633b1fd8a5b7d436e9c589cc9074dc031ae68","up":true,"one":"b4557089e4247379e587a087f53b36dd1f86f85d9dcfab5dc562079978cd959adaef5b30d11258d9cb552e7c5abddf5377a71d449febe8f2acb0aec3ebd8ba73"},{"one":"b183f12f3602bfdab0480cb0b0ba7dc69b267b0dbc7e54c316741cb78b9e99aa69fd321ad7755d095e9be14e6bd90fe14ef8fe9bafc1a0dea10a144795021a08","other":"58f9139905ae1d005950f110b7ead3355672ecc478e8c66393566c64b935003f6fec3031dc9eb21cda660acb1955cf7bb33a20fdd74d493f29868ace328fcd75","up":true},{"one":"7cc9389c8f751465e0b94baed896f6f122631052300b1b5b23d3c7656e4d11014a7a9ae62a1287bb040ca37221871a566cd470e523846df7e3acb5f94c7cde06","up":true,"other":"92dbb67da2b99a8fe46b1e510addc2b83e357ac0b5287b7ef5c1b1bc6e252b8dfd605a6896ede65848e429216d1f67d530d9e7b83ff14058aa2e5b6e405d6801"},{"one":"8fb6838337f832445531764ddafc3c747b2607f2f33e244685d6de621c2b53264270f5504187e43b7fa5cda53e66dd00b16c06879c82fb38a3d9e8aec4060210","other":"202ae63076a5560418023f00c9965b2a1d12de932b5371ae270d63db88551a7aa1a3c48841f81948fad3435bb4a7e3e165a2eced9fd937444e4502471e23dae8","up":true},{"other":"488854534ec5a3479d8ee13d9b7daf07479f6b5505f319eced44dad8c316f6ff241ce2101e95608ba635067f5e5741481b78f419c4bbd465bf7e837dc4e54d64","up":true,"one":"e9cd25d1ef3fef22160bce7f7badd7646ac58ee40da6a438f61a067c51bc51d6087ed950ec9e909bc438ebe62e316cbd9489f3c9bfa2898615632414e04f1dcd"},{"other":"49256eccce3e036928a4b6b346126c6777dca5ea0134de85efca340f97ad0f827f3094f1562e3e186d35b8292a50c20ffae01409890bbb78598494285e14dc2c","up":true,"one":"57085f756f76644cdd2148524f2334d869ef0ab2fcbe7fb11f5d22bc1f5023165b11526ecc85ff9cbb88877386af9b148d7ef15a825b3a586d16c01bdfc86692"},{"up":true,"other":"01427ba4d1e2de0b2764515556676a6058f88c16f597780dea3d7f95a6eec9299c3987d99c199d88a0a5e695ee6f0ff7de424e4eb65e54233b956a9634133998","one":"d7af0a0217ff98804aa05f8f926a8b6262363b5391d24cda8048cca5ca5982b407b7b098302d0db6d8dd9ac0883b2025b3de651617ed1a173181148295c6d336"},{"one":"58f9139905ae1d005950f110b7ead3355672ecc478e8c66393566c64b935003f6fec3031dc9eb21cda660acb1955cf7bb33a20fdd74d493f29868ace328fcd75","up":true,"other":"d7af0a0217ff98804aa05f8f926a8b6262363b5391d24cda8048cca5ca5982b407b7b098302d0db6d8dd9ac0883b2025b3de651617ed1a173181148295c6d336"},{"up":true,"other":"5114329db828f9568ccb0d7643a10e273aa626177910f55e22a53abf1ce8ec75b95465c983446b20eac0ff9c59c5dc53eca95b24aabcc8dd110e397cd2934047","one":"e0875ed6be1e163b15c13cdf37442f838670d0949349ee9ff119a0451beffb1a302943ee9d7cba48592922f64908aeb0f39f6e2e3725d1e7cdc5db34083b6977"},{"other":"a25958cf192a4f62301feda5d442535f78b983dd9e4599354f4898c8c1e6ad97ca7112549e1d1a1eacb4682cd1bf8b762368b5905ab33dbdacb585b128514ca1","up":true,"one":"ab13f773f6f2ff73032aa5f79c8897b75dda29bcbb14aa511e9401c2417dc9c510253071e28c7833c8d62fd2aef16fcd0c14ce016fbf4fec1b9a2173c717603f"},{"up":true,"other":"c63b88f494b14d5a7c1da124ffebbd985d19806b91d4b111c83ae129c4ef19614469980a09fbeccebe3b0358dd16194bdb6452d0b3dbb43a5467e23bb13f40d6","one":"99a7649bdf2ee7f0bc049308b0997e33abb68481c05a573df9aea30da5a1f267df07b2c584e3e985baf31704f04ad2a2c4876e0f8555333be6d09f5080b583f1"},{"up":true,"other":"8f3e9102306a13adb91e01f7a847e7880054f1a7df8976d05facb3a8fb37d47cce04f25e18a19713e5c3da7541e96e829fc67c8b924b717d2d9586c9c12d4fcf","one":"b1dd1b08975319030626aab821032a0c687a103ee8942e8a2e2cf029dd72832a49630e78d2d8b184579f22178aca0e875f9fad701fb81afd2ac110ab2b417376"},{"up":true,"other":"f52297fc51b920d2495ccece290432656d9388e698339c8c1279ceea45de698a4ecbda1d25928c48f1e19e9dacd3147e23ef01acc093872d7300aed187841dcc","one":"01427ba4d1e2de0b2764515556676a6058f88c16f597780dea3d7f95a6eec9299c3987d99c199d88a0a5e695ee6f0ff7de424e4eb65e54233b956a9634133998"},{"one":"93073da602d6326a48464a8b6890220b3aae0abf5b6961180f3aff2a14573c43411bd519d3e0012a646ec2977be18915d95a36d935a69f93985f5307ea4e3ebe","up":true,"other":"b183f12f3602bfdab0480cb0b0ba7dc69b267b0dbc7e54c316741cb78b9e99aa69fd321ad7755d095e9be14e6bd90fe14ef8fe9bafc1a0dea10a144795021a08"},{"one":"baa28b8cb7ec539e0e157d7598cc5a5b0210fd8fb5c9026c3cd612133c5a8ee56997507511928af5683cb620fd85593dd8f6ff882d95fb847870ae4ce7dc503b","up":true,"other":"5982e7dfd39c527851f6ea6430b70e654d95df5ec4401ca1d8dbd1034cf7a65d1126d60b36ebbd396c9ca32e6e8515f34f9dc0a8d2980afe4aa181c8bf68437e"},{"one":"f52297fc51b920d2495ccece290432656d9388e698339c8c1279ceea45de698a4ecbda1d25928c48f1e19e9dacd3147e23ef01acc093872d7300aed187841dcc","up":true,"other":"70cce7cb0c18091dbb6d41160ab560935f1759b969bf8118cee030ee707cb15ba407b8c48dcd9fd012cbf778e219f7d16a74064b4983cf098fb118297748edb6"},{"other":"01427ba4d1e2de0b2764515556676a6058f88c16f597780dea3d7f95a6eec9299c3987d99c199d88a0a5e695ee6f0ff7de424e4eb65e54233b956a9634133998","up":true,"one":"e903d7aebff96a6afa4b9dd19b0b02e5af18da8e4e89f64247e1a2c2d46637538c741182eac67f45ec61be76aeaccde57f0a0184bd608ea7d92e586d4f827ea7"},{"one":"3639f964feba681db9702cac3f02058f2e490fd7bffb217dc3480dc458decafd5955541fea89f0f6f14ee50a745eaf98b21363d6b4fb88c31bd32bf7845d524b","up":true,"other":"01427ba4d1e2de0b2764515556676a6058f88c16f597780dea3d7f95a6eec9299c3987d99c199d88a0a5e695ee6f0ff7de424e4eb65e54233b956a9634133998"},{"other":"77e7d427b65b6c29c0d92c51184af73031bfa768a47fc20be6c264f422bf718865259c17c103bf47289b3abe62f93452781c6303d757e76d3d56ceeb26262fab","up":true,"one":"4e88cc60efee147fb72a735775944c7b2ba0790e2b2b935b4b3c2da9a3158a2a7aae411e9204cdbe6b2304d90a3a8278f8bb1a800a409e8500d100d84ba1947f"},{"up":true,"other":"362ed9a92b588d5fe315b90a74aa27f7600e4a7d06b27ceb26272340388d916a831df85bf83450ef80bda4e4a21acaac60560c8a42940a26e2ac567519e2a202","one":"af9b80f6836113aeda897d6903e9ffb4f7f1a706a7f821d0d40f03a0d83c18d6a19795ee4bfc1093ada04014415b1f230db1d2f056df3f5027cce71611588046"},{"one":"77e7d427b65b6c29c0d92c51184af73031bfa768a47fc20be6c264f422bf718865259c17c103bf47289b3abe62f93452781c6303d757e76d3d56ceeb26262fab","other":"c0bec7375c66bec98524ade2245c1d7480516fc5d87a3249e64ec86418e80e202f1e3da76832e97bbc3dcaed8c96ca344e4829347b4428f4b1cb61999e404c05","up":true},{"one":"212a8048ab9925171475e81dce047865df186222d673d524c810a9f613e4a21f3b130fa34c5f44974fbeaab1f6028177e71568e00a1184d9fd05443c172f5fcf","up":true,"other":"99af34b172d319633e07a4e528f416024653a230a9103a4b281171f75bb697dd6be4757558c94e86210b4da8d9fe1229f6a5d8c4174989ea0ce696f8d1a9995d"},{"up":true,"other":"20f6a8be1d2d8b5d6a43d851a2f5475385ef07fab80ac46525d0beccf3e25c01d726cfb3a1179e8343b1e88d21684fb24dd6e6497537d4e7e9edd59cb95d1b8d","one":"202ae63076a5560418023f00c9965b2a1d12de932b5371ae270d63db88551a7aa1a3c48841f81948fad3435bb4a7e3e165a2eced9fd937444e4502471e23dae8"},{"one":"243164c4dd583f80c50813f43e5c27c894463400cd3afd776b36e79e7123d9261f01f06f92914aab83096b9a43fb655e79687590599284640a3a7d2c25454597","other":"6c40910f0556f892a7542989fa01d7e3682fca89aeefb5ed885808f88ff17b6d13862f461c10d629a005ae67abef542d75e5b20816891b6944f71560f5c2dfa8","up":true},{"one":"431644cf162bc267237c4e798288888dd835c1b0546b0cc679782e33568988d75b4294f4aa08359a6b152ed9a0fbd13133681156bcf09a871c4f362615ea6dae","other":"99af34b172d319633e07a4e528f416024653a230a9103a4b281171f75bb697dd6be4757558c94e86210b4da8d9fe1229f6a5d8c4174989ea0ce696f8d1a9995d","up":true},{"other":"ab8eda9b360d3e0b002ba31d48311057880844b828ad9817a2ad19736860d0114d4a17e9e9427c842d52e7ff61a09c2cad9b70f506e338909535542dae38ede0","up":true,"one":"d6a7257771baa4d9944592ead46b8ab700dbf91ebd4dc0ec7e5fb41cbda0622944269172fcec8352b89ef2c186d4c787af2b45a50533f627a97818477de034b4"},{"one":"a8fac88fba179fb9b259d94caac9cbe45d873a0131bef8844ac4383b177daf6f301f8793623fec5876885db1a91e5b3e98e2aafdaa47e03b1f6d9740f48af7ac","other":"d43bd6d3ae39a04e4e144a8a6f80b2d54472b5b9b6491dccf44b1716a63d24c56e3a871b3b8fe983d992988dc07ace06736ead3b1287914b629fcfe17e81f36f","up":true},{"up":true,"other":"d7af0a0217ff98804aa05f8f926a8b6262363b5391d24cda8048cca5ca5982b407b7b098302d0db6d8dd9ac0883b2025b3de651617ed1a173181148295c6d336","one":"99af34b172d319633e07a4e528f416024653a230a9103a4b281171f75bb697dd6be4757558c94e86210b4da8d9fe1229f6a5d8c4174989ea0ce696f8d1a9995d"},{"one":"5319bc9864d87eb33f26ff9732824d21a0a5ab70b254bc70a47554ffc763ae1559000d07e3eac9f883bd9e7f249d80edf14ab39c89c375bfcc5ec9e840ec9673","up":true,"other":"3b71a324bd7b1a8fb19d8206eea1ca8190cb1faf5fcd1bfc52cef6b52296fe1db3e54d70180133fad1fa1188499d0dd73d2d075fdc6b3ffd9042d690e7d88e02"},{"one":"9c8fca41b833e88110559b9258653160f5fb236bd637272ac58fe1adf333f4df75b94a805eaebb9f10a8c1a26d357dd75140560551d3fc4da79da2c4fc9479c3","up":true,"other":"1cdef98d7b4de45c902c725384bd14c66084fe4159b26a0f9a24f432e1f561d035ca41e1c60fe64f3213b4f91a1afb953193dca1a7d535be0602b5d046bcbab8"},{"one":"a1fe0d27f82309911a4b758c4e597bde16adc1e2fdfb07b52dea5092cea40ff212ea2cc831e385094b044f519909cf978f350b16ffd4c70c159cf1372301a3cf","other":"e0875ed6be1e163b15c13cdf37442f838670d0949349ee9ff119a0451beffb1a302943ee9d7cba48592922f64908aeb0f39f6e2e3725d1e7cdc5db34083b6977","up":true},{"other":"b9c7b885430b9b1a4425bde30b3629559f5437e0e30a0299fc6f6e097cbcca8af9e285caf5dea685a0237f60e06f490c39a1e3e487f14a2b9f41a5135f2ba994","up":true,"one":"588df3185f63a5443d8c6b972f67805f0557184d916005f537a4b27cd02bd6a12e432a2b34b234a34f22e923c6f116da85be20bad77a2bf69913684e9d0732ba"},{"one":"fee3fa1ba2a051d40a582908384ee81179db6c2b5f4bfa58c24f8015b794b43a093ed68b69bb209684135f972a055a9845978fa1b7d489e2126c3b514297f1c2","other":"699c923976c5b8c70c353840d3e384750f466954265f05fbb0d5877a2c0318a041dc57adc12ac6e8fbae7a00d6b6675e1a1be3a8f59dac12727ee3f8ae467a13","up":true},{"up":true,"other":"11e9729700f5046b47d5e4521630cb57408f59a3337ca7db7984477a16c1f3b90c1d8d1f8d6a3f2a72e35f373fa73ec47a5636b36e40b2fb83756622a08896b8","one":"f6a12b23423c047927a3024a6dba7ce88927cb21d4df3778bc5ebb262cc403261c79ba6d9bda07f1852c009d803a77f429e9e48ec1d63cae98256e529d45b276"},{"up":true,"other":"ec19efa1d488e74da6bf239825b24678f549c377326c5d33d100b708a9a28a3fe129d542d7ba71e0ade46c15c6e9b38f09422560444388e609a8a66ceb8e0ae8","one":"c69b9b181b2756a1345b73a97afb3dca909c253188c3b905f0b414465b750d2ffccb4c8e8eb5e3809549af55db473f3b12682f9bd97c5c75d68f23d67d91b866"},{"one":"c61ffc88f23f9f536497cc10ffcb7000ec6c4b801998ae7075ddc9079fdc1da8350e68744dc9e95ff892dfc5e52c62a3ad913a87fdacc455aea99b09aa002b57","up":true,"other":"588df3185f63a5443d8c6b972f67805f0557184d916005f537a4b27cd02bd6a12e432a2b34b234a34f22e923c6f116da85be20bad77a2bf69913684e9d0732ba"},{"one":"c0bec7375c66bec98524ade2245c1d7480516fc5d87a3249e64ec86418e80e202f1e3da76832e97bbc3dcaed8c96ca344e4829347b4428f4b1cb61999e404c05","up":true,"other":"842ec3faa8b4a4cdec32abfa00ae827277fe2696e1b0c6551154533b16cf75ae69caf834b4f08488fa5c8b322fb633b1fd8a5b7d436e9c589cc9074dc031ae68"},{"up":true,"other":"699c923976c5b8c70c353840d3e384750f466954265f05fbb0d5877a2c0318a041dc57adc12ac6e8fbae7a00d6b6675e1a1be3a8f59dac12727ee3f8ae467a13","one":"70cce7cb0c18091dbb6d41160ab560935f1759b969bf8118cee030ee707cb15ba407b8c48dcd9fd012cbf778e219f7d16a74064b4983cf098fb118297748edb6"},{"one":"b183f12f3602bfdab0480cb0b0ba7dc69b267b0dbc7e54c316741cb78b9e99aa69fd321ad7755d095e9be14e6bd90fe14ef8fe9bafc1a0dea10a144795021a08","up":true,"other":"99af34b172d319633e07a4e528f416024653a230a9103a4b281171f75bb697dd6be4757558c94e86210b4da8d9fe1229f6a5d8c4174989ea0ce696f8d1a9995d"},{"one":"699c923976c5b8c70c353840d3e384750f466954265f05fbb0d5877a2c0318a041dc57adc12ac6e8fbae7a00d6b6675e1a1be3a8f59dac12727ee3f8ae467a13","other":"d7af0a0217ff98804aa05f8f926a8b6262363b5391d24cda8048cca5ca5982b407b7b098302d0db6d8dd9ac0883b2025b3de651617ed1a173181148295c6d336","up":true},{"up":true,"other":"b9c7b885430b9b1a4425bde30b3629559f5437e0e30a0299fc6f6e097cbcca8af9e285caf5dea685a0237f60e06f490c39a1e3e487f14a2b9f41a5135f2ba994","one":"e8a679f627d03347a4fcec0a0940f7ffa90ce3fefea290db3af4f3a32d27965bfb51832b6a6de2495c8a8cc026bcf993b84a0cced778e158bb81c034f5e4bd76"},{"up":true,"other":"bdd17545242bedba1e4c36fadea95db655f8f220f10ae143084690a3c8d4e7ffb79a64af9f1bc8514addbd63695b2f20857e8d162f25318faac885f77b385138","one":"643da2591098f9698f27cccf7c17832e0717ee6a1276398a1a29edc947125585dcfab9417c2721a8a55d4dfc75b826be7581b6e30b020f6341ac549877c9f122"},{"one":"212a8048ab9925171475e81dce047865df186222d673d524c810a9f613e4a21f3b130fa34c5f44974fbeaab1f6028177e71568e00a1184d9fd05443c172f5fcf","other":"58f9139905ae1d005950f110b7ead3355672ecc478e8c66393566c64b935003f6fec3031dc9eb21cda660acb1955cf7bb33a20fdd74d493f29868ace328fcd75","up":true},{"other":"a25958cf192a4f62301feda5d442535f78b983dd9e4599354f4898c8c1e6ad97ca7112549e1d1a1eacb4682cd1bf8b762368b5905ab33dbdacb585b128514ca1","up":true,"one":"222d7a2f94dc82a09fda70b8195fc3a60433a90f53998872318c57625c528c90572d78b444ac4901dcfece1a03ef8b6cbe7845366a845a942f341f6db58a9b3b"},{"up":true,"other":"ec19efa1d488e74da6bf239825b24678f549c377326c5d33d100b708a9a28a3fe129d542d7ba71e0ade46c15c6e9b38f09422560444388e609a8a66ceb8e0ae8","one":"4116fbb7d55bfd4bd8db9cbfa570ac361bb88605b6aacbf84e245893cf3fa599ecc086688a4c534c81f61a90fa344ca37e4d4013ddc03f7f08218724a55f66b1"},{"one":"da22fb43c6d230d92f9c09454e282dc45dffc759740566039f1bdfb58171c6801f721841de83217277b3fb70983e7d34da53bbf25d1d45413a78d9afff151826","other":"6909a0fa47718cfc463b1e96c21734b46bd5b28dd59cd3d66d67990783436b7538ab2659d427029b97c8dddf313b26532518c0c34a2b1fca8cd852b0fdb83ab8","up":true},{"other":"488854534ec5a3479d8ee13d9b7daf07479f6b5505f319eced44dad8c316f6ff241ce2101e95608ba635067f5e5741481b78f419c4bbd465bf7e837dc4e54d64","up":true,"one":"ee3471e1d835c4294f7ba642103039ccc548fe4edc177c79b63433ebbb0dc9d06600844f1fed76c7096ee9538e49e4e86fb8cffe9095dbdcde27695ff28ad395"},{"other":"24047e1a816cbf9b7a90e6c78dc896a3b624047ef5cfd3aa495132d57b1074aa129ea6eff171f5cca91d0f4793a07c9672b0a55232f2415c6220e443ebd0791d","up":true,"one":"51a570637394e9ab61fe95b3a608cc4e9dc8ceb63efe717938ccd4260a962d52e01b30e7034fbfdabd9a3c9616ee569550b38a6d6b4b19847f523254069a9f27"},{"other":"8f3e9102306a13adb91e01f7a847e7880054f1a7df8976d05facb3a8fb37d47cce04f25e18a19713e5c3da7541e96e829fc67c8b924b717d2d9586c9c12d4fcf","up":true,"one":"bab07c2e4dc09add884869b31fb474b6d7151f9cc331d831f55c2b088397370fb0a1e1592c8dff9c8bc8e83de9faf6e91683acfb2df1b41856d70e523a99d370"},{"other":"643da2591098f9698f27cccf7c17832e0717ee6a1276398a1a29edc947125585dcfab9417c2721a8a55d4dfc75b826be7581b6e30b020f6341ac549877c9f122","up":true,"one":"740919ebae9b4fe646ca716ebb8923bf2a1b1963767d86f55ea95911d88d163cc2e07b1420669e64b62cb267b625413444b783b8e4a7bd6a0f481f4d84e984b1"},{"one":"eb6d41d8d96f1933dff017d5fa0c46c6d0bad5d273b7c321a12858ac90ec00fca6191d29419897d2e25ec2d8ebd8c6a81bbde2d3f266f842e64b2b822161f1ea","up":true,"other":"ec19efa1d488e74da6bf239825b24678f549c377326c5d33d100b708a9a28a3fe129d542d7ba71e0ade46c15c6e9b38f09422560444388e609a8a66ceb8e0ae8"},{"up":true,"other":"a48cd04cdc66e1bb182529a789e1417d60d5e7d0f73068c1b17c6f231defeb943357789123e8d89cad90d1dd1726c48b808300d213bc1ddf7ae43cd58527f1f3","one":"6909a0fa47718cfc463b1e96c21734b46bd5b28dd59cd3d66d67990783436b7538ab2659d427029b97c8dddf313b26532518c0c34a2b1fca8cd852b0fdb83ab8"},{"one":"2b0a1f3a6466c6be1d7e84120db384fa37f7c73a01e9a105ae90e7d2203212ec974f016d3012afd26bc0f9a8411d0716cc59b6ecc9f665db12e306af8b34cb63","up":true,"other":"869cae165389e7dee7b7df4e012ee1a39737366c306d8f4b0db4510b2236e0bd3a4d1d4af00b1a8c1d360e23da47de52fc1632edb03c7f1429aacc8aa4994750"},{"up":true,"other":"c0164fb4a1acfb4f3b1a09f9f3ab226c382529a73891937c6f3c91798098cf10b909eb92e5f8acfe0e8f3aee0b71cb23ee2d9e6ad1e0f4492a0272c52d529849","one":"97b1eaf8274ece76d75e7f60126f1b351ed5fe55088b9fcbb825a3a8d8f84f61bc72469916b280497dabf01345057525cae89da73c9a1a8a8cd19367d44dede1"},{"other":"aa90454031068598ee39af5f1429c7a72277946d50ec2004f340406dbcc9f80cac505c9d9b071f85e2ccfd4b13bcf943f3cb9dd9f96f62d41352af9d8fffe7e4","up":true,"one":"7b4585f8a4e4904239994a1b8bdc76299da8e46a8a632fabc6c33dd4170f8f3715e4c4f526ea5dd14093b150855960e432b1b140594aca21995f9e0722fb57f1"},{"one":"4ff2981a47da46c753090e193a8bf43c3372a6b07a37cf0552de2ced455fbb8a76d969cd97b3e4601d8a808bd2a73f7729ed8a61df2f2a0c2cee1425d0bd9ab4","up":true,"other":"8ee65c0937cdf860d5329132c34bf28b5dc4d2593986fae80e4b35efb54ec24cdbf294223515363a917a22dbc6db463c10c7484e22b479b9010059c2521b6317"},{"up":true,"other":"f6a12b23423c047927a3024a6dba7ce88927cb21d4df3778bc5ebb262cc403261c79ba6d9bda07f1852c009d803a77f429e9e48ec1d63cae98256e529d45b276","one":"60995852a2385ce8d7d24dc94b85a2f0dab6e5c32e910dfe367ea9c6ccb7b0b2eb611fdf120f8c697097e2f137cefff42e8d9db16b664a857a38c5ace837ffa4"},{"other":"ec19efa1d488e74da6bf239825b24678f549c377326c5d33d100b708a9a28a3fe129d542d7ba71e0ade46c15c6e9b38f09422560444388e609a8a66ceb8e0ae8","up":true,"one":"11e9729700f5046b47d5e4521630cb57408f59a3337ca7db7984477a16c1f3b90c1d8d1f8d6a3f2a72e35f373fa73ec47a5636b36e40b2fb83756622a08896b8"},{"other":"77811b007dd1fc1b11e447858df37062e97b6fc14e059399814f3b4736188e3fb28bf7c3958bb8ebc6ae16c36884ba7c98b810fb6f8b358323412123c803abd4","up":true,"one":"f52281c227aa82a3bd5fabfdcf8bdf1d9ea6739ab9b9075340143d59b4f2f8a79a981609c9f42823a0253c19a7281eed0e912e4054363ab7fe50117563ef14e0"},{"up":true,"other":"154d5ddb15ec12dc65362039d801383c189b5bcf6688883f2d7e3d0e8dc78e45f9f58d5dabc79a8798a243ce59abb95c77525db14f050fd8cb37d04b7276557c","one":"c9d705012a06d82c4d44db95b4f1c63ddd33ad64d732e96b1d878caa0caac433d4096f01495a6f0e8a56af122b0470fd745db6d906353b590a4710472b93f5b2"},{"one":"29619924833116cb1160bf7a8066a528b7182794368bfae62b5bacbae680d9161a479f217e30c3b4f19a250b1b59e08f86c94726117dc3bc94ff9ceac6bee6e4","other":"90b8e73916046b5433dce049bfe125ca2bf2fb390ff7301f9bc5d8d0183988577aa2a7392aaa28091aa81c8ac23942b5751420b9ee48e488a68411f9d2b1e5d5","up":true},{"one":"7dd2801259c071a6e1dcc01d1cb74775fdec92da1da0b1eaf5f893cd5ed118894493ca5284c12bbd6cf7959449bc610d26ac6c9ef2845d1645d425f56ac003fd","other":"eb58e478b16056e0af344397cf5f078a3312a6db2189ec2042ec06ab6550e3ee71ebcfeff1814332c552c12a5a488f96b3f2935e90a189d238da19d30a2c9874","up":true},{"other":"b60def37233dbbc0d5f7fcddb304be1c0b6508e1e3d8a09a8290f7363e9bb84152dcaf70b8f6bb3a882fee77ff03ab796a5c1c3654f251c9f5c746ac5ad88556","up":true,"one":"3948a7a939b9a1f4201953bd9b955ee7be87d09b63c7a45167f556ac06fe3c4c2a75d935bff50668da5e71e46802b55d7a9945a92d7807c00625d129cbb48f82"},{"one":"90b8e73916046b5433dce049bfe125ca2bf2fb390ff7301f9bc5d8d0183988577aa2a7392aaa28091aa81c8ac23942b5751420b9ee48e488a68411f9d2b1e5d5","other":"624248a794fd62248024360f128b2e503c752340694a316bed420e5ed2cebeb5bf970df95a2806732237a26de3778222b0454e2e7d2875129b193e7890fd5b95","up":true},{"one":"b152eb30c9f46ec39166016f03d289f98cc285ac62d204da32e5a003da14e4f02c64df8ae1d0c8a2a902adc5f7dd7604081a0b140c9b64052082f0861945f5a4","up":true,"other":"96cd4caa32c0b3a3493e24e13fad1ef75c621005d74154c3fc8a73cca4c0120452b6432334d94849c63f75d56a2943a453c86d2a14ad1fb61ae6833e58451187"},{"up":true,"other":"48e35d67e14ee2f329c0275bc965829b761885dbc3671f4673d84d76d18a5b6415e619e219b5d90761a5c6bd2f43c6a58708286a063daf46b502944f8ef9230b","one":"224c3b969149d50d1bb4f473bb9725223c1dafe152efe1b08e8859213c543a66565b5d68a99cef3d5f4eccad6282a12f78d7b38eec14deebf44ad8dd9cba8680"},{"other":"8c459100df488b992fdad207a096a434d67cb733619adfd09a311095568d4c9db293d9a892675551805559456d49a3fdb19c2cc698b14552bf0ace584d4d90dc","up":true,"one":"eb58e478b16056e0af344397cf5f078a3312a6db2189ec2042ec06ab6550e3ee71ebcfeff1814332c552c12a5a488f96b3f2935e90a189d238da19d30a2c9874"},{"up":true,"other":"eb58e478b16056e0af344397cf5f078a3312a6db2189ec2042ec06ab6550e3ee71ebcfeff1814332c552c12a5a488f96b3f2935e90a189d238da19d30a2c9874","one":"33e9d4674b5b9b23e838583f01b429abca1330393dfc100b19ede6090a53df213011fae53169a66aa05d18e4cb497a17aa81eaedf1fe2e4348f9825c309438b5"},{"up":true,"other":"90b8e73916046b5433dce049bfe125ca2bf2fb390ff7301f9bc5d8d0183988577aa2a7392aaa28091aa81c8ac23942b5751420b9ee48e488a68411f9d2b1e5d5","one":"a47697063a2fb973449bdabd0925e10944ba1f6d8b2cc5c38b295f611eea3402b5cf3ae857716a34d84194955f5ed61350affe56223349124c8233852141f9a2"},{"other":"8ec699020ab5e7719fe23b80268b5d1d37052bb71f5d81200ae805cf27825823733206165f0a7507c2595853361dd122e9ec1b2deb543591e22b71ec0b873b5b","up":true,"one":"3a2cacc430f13f31c52b7205455420cf0fb9ed9e28b0898b69ef97951bf295b29118e573a42dd97abe38fee5ab4c03dad9ff6dc448126cefc1da12b6c8e8d915"},{"other":"9d372d73848389cfa1676f0cdb030950980ed5b68d5b2ef8a058f1d2095b26ff0fafab5fd3c243296ee2620edc67752970ab47370270856287f8612d1b190a19","up":true,"one":"7c6e6a49429a4e24aa4aa5c7ba19684f77cd67d3744688baff6e7f1d74b7e9d2df85f3e57e0df0a9b960b5bf982a610c5639c3e7a6935ba13fbc77243b2dad19"},{"other":"002cb6ffa63ad71ee6ebc1df4c41f7a97c51f274b1d3b22420c87b73136be5169b9670508061d8261e20055fefce3b855388994672aa9a0f1475c43839aae4fa","up":true,"one":"69f999937943be00e5fca5c7cc942ce13b6752a72813368da2fbfcf74ad807bc6edd85537e087b6f73c0469c7b76a5d8f7d883bd315f3b35af32b8da293ed243"},{"one":"c402495c2110a6531a530ebdcd9ab1b883f1c707fe25aa13a255a0a9edb4113669b4aee9eadf803f9fe4c2ef66d5e4dff7064549f672598410f2d9794747a600","other":"b9c7b885430b9b1a4425bde30b3629559f5437e0e30a0299fc6f6e097cbcca8af9e285caf5dea685a0237f60e06f490c39a1e3e487f14a2b9f41a5135f2ba994","up":true},{"other":"3f322f9b1f1f0692663bc3be11cf11386f4a14696aab610916cfcadf0234cce0c86b51c85ce2108e9bc21d50ad71cc10a6eeaec3fc7732908f3a8b193465a0ac","up":true,"one":"9d372d73848389cfa1676f0cdb030950980ed5b68d5b2ef8a058f1d2095b26ff0fafab5fd3c243296ee2620edc67752970ab47370270856287f8612d1b190a19"},{"one":"43086ff7ffd3c7bdec77bd288f41f1ee0ce21bd3f60a5df8931e2af6e7af5ef0fad432d29625491935d11567944351fc7867c807ebd12dd2c21c9e620ae0f85c","up":true,"other":"baa28b8cb7ec539e0e157d7598cc5a5b0210fd8fb5c9026c3cd612133c5a8ee56997507511928af5683cb620fd85593dd8f6ff882d95fb847870ae4ce7dc503b"},{"one":"7958d1517de1223e7fb30acf61d8618e49fb95a03bc2f49141f4c7967bc80b90e0dd526c205639de3c060029963d43813293c2556f7b127945c798f3f9f18626","other":"e0a043f98b462f10f72aa61ceda52f9c27829d086f6f2c5bf4db4fe32759002e5ff9519495d57dbb83d963a1dc991a1defcf5b9ef0d543789f38c68f5d07122b","up":true},{"other":"c0164fb4a1acfb4f3b1a09f9f3ab226c382529a73891937c6f3c91798098cf10b909eb92e5f8acfe0e8f3aee0b71cb23ee2d9e6ad1e0f4492a0272c52d529849","up":true,"one":"b3b4b203395bb6655d79ecdcee11638dd9a16baccfcc1f6fcc8b31832c8ca35650eb6c2802104eeec6d96ea80404381a2bd9b01dcadc748a4666b761d9ce64f8"},{"one":"fc9b1b2bbd5e682eb350d23f3ee33b245495daedae9370de7b1f55f91cd45db831d196c17615e11decf6b67696a268ac788130e3de38c7f6aeae811f3ec8c8ee","other":"2cb076669efbaf2ff0b181a1b454061a31ef23937a40405022b126f0eb4bfba60c9e3397009d8c0ff0cabb603692532d0072c18c6838f43397c98483306f62db","up":true},{"up":true,"other":"b9c7b885430b9b1a4425bde30b3629559f5437e0e30a0299fc6f6e097cbcca8af9e285caf5dea685a0237f60e06f490c39a1e3e487f14a2b9f41a5135f2ba994","one":"a48cd04cdc66e1bb182529a789e1417d60d5e7d0f73068c1b17c6f231defeb943357789123e8d89cad90d1dd1726c48b808300d213bc1ddf7ae43cd58527f1f3"},{"one":"24047e1a816cbf9b7a90e6c78dc896a3b624047ef5cfd3aa495132d57b1074aa129ea6eff171f5cca91d0f4793a07c9672b0a55232f2415c6220e443ebd0791d","up":true,"other":"eb6d41d8d96f1933dff017d5fa0c46c6d0bad5d273b7c321a12858ac90ec00fca6191d29419897d2e25ec2d8ebd8c6a81bbde2d3f266f842e64b2b822161f1ea"},{"one":"7d9979c13cd8841e84e5d199fc263962ca6fee12664d8526a581bfcdca2e3427ca169b9a0244dd8292a9a1be2bcedb0e8f626eadd307068c11c03b6df13aee33","other":"c03ef1de42d522b44eef53be11f2c57b8b74fed9e87e6c2928c1feb48ddfecc67e1a3a8c8be1c47b3735a216d7054e2a4dda49fbd9a1ac702146aae5bdeced7c","up":true},{"up":true,"other":"d7e3661c0af6754c875217f93d34b254f1f45fc1359a4c6146cd0efa4c6e12aed9a4fb0a21a136f73af4fc2c6d0a63cb809d81855bbc9f51e29d23d90f77b326","one":"9ea856ea440c776b9ffaad1237ec11d570a1f912a908b8363ff97cf7947d2523e3c73663240d8fac988698cdd81e877ddd4a609485fe9f26494136fae14212df"},{"other":"e7b2adabc2c99ac47b1e94fc0a2c63a00a1d622ea67a4c1858f4cec93fca957d43d8429605761bdf5eed4f733dac1a3d12fb928f22abf248965994acde63864a","up":true,"one":"4eab70233789c544bec97040a04099494bf269a819584a5d0b42295c918a52b02f224a8ed127aba3d92c02f567356bea4b95f77230ef548dfa7fe44b643d8704"},{"one":"28cdd55fc871ffd8d63d05994be706959c9780dbfc859070a41047a1b40dd5fd7adb53919400a4c6f4d06c69bc1ecccc0e230e5b702598a7fe8003a282479872","other":"e993be8034861aebc9bbd11115f25d9c719d43fcdefc323599616cc26240cee38dfc27bb7f339149a54a3c9ad13b2d6ca4f0ae690e4355605eda6b789c4a431e","up":true},{"up":true,"other":"9ea856ea440c776b9ffaad1237ec11d570a1f912a908b8363ff97cf7947d2523e3c73663240d8fac988698cdd81e877ddd4a609485fe9f26494136fae14212df","one":"643da2591098f9698f27cccf7c17832e0717ee6a1276398a1a29edc947125585dcfab9417c2721a8a55d4dfc75b826be7581b6e30b020f6341ac549877c9f122"},{"other":"0c82c4b414375479375703ed9c19fb08c8143229ed4f1dcf448c6cf313810c098905123bec17969276936ae0cc39ed251b2811dbffb551d61159862b0eac0a23","up":true,"one":"d43bd6d3ae39a04e4e144a8a6f80b2d54472b5b9b6491dccf44b1716a63d24c56e3a871b3b8fe983d992988dc07ace06736ead3b1287914b629fcfe17e81f36f"},{"one":"e8a679f627d03347a4fcec0a0940f7ffa90ce3fefea290db3af4f3a32d27965bfb51832b6a6de2495c8a8cc026bcf993b84a0cced778e158bb81c034f5e4bd76","up":true,"other":"da22fb43c6d230d92f9c09454e282dc45dffc759740566039f1bdfb58171c6801f721841de83217277b3fb70983e7d34da53bbf25d1d45413a78d9afff151826"},{"one":"51df4f4d4f020f22f55a5fd00c7f9c68c232c167ae4d4e80d7695f8f39c5aa0a7b565c1c55bdd6a21e06fa056549d08fd2e9d76fd79e21295557aa30d1ae022c","up":true,"other":"1e3a2f2491b6acb07a9549d9929d150479a0313c926b0e236237bd541303da4b563a855016a90ab50e59d94803ad566798570fa981464c94c04a4a4a94fbc607"},{"other":"c03ef1de42d522b44eef53be11f2c57b8b74fed9e87e6c2928c1feb48ddfecc67e1a3a8c8be1c47b3735a216d7054e2a4dda49fbd9a1ac702146aae5bdeced7c","up":true,"one":"5a235aca7005df295d5bd924b1272452e9bdad408ca5223b9eb76800b4bd4e3158a1d663ce5243fee92233227249fe4bb8507e8cb2c3729744b273bf488ba60c"},{"up":true,"other":"f4cdaeb513aa98f8868d8eb3a1d12c07367725928a1bc7d6ca4b583788e111a955463037ec7867260511896d97dfbf096aa77ee8a7d9ea1c06cad4a92c45108d","one":"1e3a2f2491b6acb07a9549d9929d150479a0313c926b0e236237bd541303da4b563a855016a90ab50e59d94803ad566798570fa981464c94c04a4a4a94fbc607"},{"other":"0e164c8692532e59c76ef84319a1093324f46f77618d3a836a279df52edca6c839061c0582dac7481da1bd0f3e2b58fc0dacd6ee5d678ba1406d4a1a25fe761d","up":true,"one":"c088bf88f1e152ca3fad17f098a71ca1021d46d8af12d0ee1c587a5e2a430d8e48beaf171fe01ee7680b671c00dd88c90f12a35c328a3f334661fdeee914a4bc"},{"other":"7dd2801259c071a6e1dcc01d1cb74775fdec92da1da0b1eaf5f893cd5ed118894493ca5284c12bbd6cf7959449bc610d26ac6c9ef2845d1645d425f56ac003fd","up":true,"one":"8d3ad57509b36c4ca5c4663f3d1977a3125e069078842634e6cfeb22c044281e3d02f06eafc6d2a60089f03d70f5134a6635c35563c9f911fd845a6ef9bc8952"},{"one":"154d5ddb15ec12dc65362039d801383c189b5bcf6688883f2d7e3d0e8dc78e45f9f58d5dabc79a8798a243ce59abb95c77525db14f050fd8cb37d04b7276557c","other":"a070b5cff5eff533a2267ceb0d88e221088038af773e18f80110c8a2c329f0543b8d43c4e6132e9416723e3e94c87f0053456760ced4426767b95cee36ed93f8","up":true},{"one":"8e65496318637446a51f0dc87d0a5cf82655866cd1579db1e381af52e12545172b9c88119999ccac3b8b8644efc9675ff183ebe7584c16eb40792cc21f7e9b76","other":"33e9d4674b5b9b23e838583f01b429abca1330393dfc100b19ede6090a53df213011fae53169a66aa05d18e4cb497a17aa81eaedf1fe2e4348f9825c309438b5","up":true},{"one":"43086ff7ffd3c7bdec77bd288f41f1ee0ce21bd3f60a5df8931e2af6e7af5ef0fad432d29625491935d11567944351fc7867c807ebd12dd2c21c9e620ae0f85c","other":"5982e7dfd39c527851f6ea6430b70e654d95df5ec4401ca1d8dbd1034cf7a65d1126d60b36ebbd396c9ca32e6e8515f34f9dc0a8d2980afe4aa181c8bf68437e","up":true},{"up":true,"other":"a25958cf192a4f62301feda5d442535f78b983dd9e4599354f4898c8c1e6ad97ca7112549e1d1a1eacb4682cd1bf8b762368b5905ab33dbdacb585b128514ca1","one":"b60def37233dbbc0d5f7fcddb304be1c0b6508e1e3d8a09a8290f7363e9bb84152dcaf70b8f6bb3a882fee77ff03ab796a5c1c3654f251c9f5c746ac5ad88556"},{"other":"ba430731fc2082f4217ebd859c2865c28bf50a39674ca8615dd89f608ae434a09657e24644ac32807634aad7857547118c9228460195e50ec58b34789d4ad151","up":true,"one":"8ec699020ab5e7719fe23b80268b5d1d37052bb71f5d81200ae805cf27825823733206165f0a7507c2595853361dd122e9ec1b2deb543591e22b71ec0b873b5b"},{"up":true,"other":"ba430731fc2082f4217ebd859c2865c28bf50a39674ca8615dd89f608ae434a09657e24644ac32807634aad7857547118c9228460195e50ec58b34789d4ad151","one":"aa2028d356a88eca8e0fcaf218d62ace099c3f72dfd95bb28f30ac9a926034cf1d60a40511f7495652745de80d71c0f6830019e206c88e2b6ef0cf4f05d7fe9e"},{"up":true,"other":"f6a12b23423c047927a3024a6dba7ce88927cb21d4df3778bc5ebb262cc403261c79ba6d9bda07f1852c009d803a77f429e9e48ec1d63cae98256e529d45b276","one":"9bdacc256acef0433805477d38f32be849a8846d88cb883b19d290454639b42c6ab6c5c52d4f83453e8a156af7d85f606458aa9c0977c67282f56f34ff0acbfb"},{"up":true,"other":"723f362e98f90d7ef15e24e353759fdbdabb08adab767dba73ab546741fac3dfb457466f1e2c851aa49526da1408f8ddb509e12f7dc0bc1e785c5b72be8a986e","one":"92dbb67da2b99a8fe46b1e510addc2b83e357ac0b5287b7ef5c1b1bc6e252b8dfd605a6896ede65848e429216d1f67d530d9e7b83ff14058aa2e5b6e405d6801"},{"one":"15ceb62ee0f53379aa202950634ed881ba3b7bd4b46c80723ee48190079311e24ffaacb167a126a40bd6732c384f3c26163aa043edca03cb52a97b6da189aec7","up":true,"other":"bdd17545242bedba1e4c36fadea95db655f8f220f10ae143084690a3c8d4e7ffb79a64af9f1bc8514addbd63695b2f20857e8d162f25318faac885f77b385138"},{"up":true,"other":"17ae0b24297a3e6e027884e5e4529b6646ae340f5736eebc6187a9b59832a445f3644172d92438351e3803e56a67472b29f3e1d48844ae2e11e5e6670eed1436","one":"c0164fb4a1acfb4f3b1a09f9f3ab226c382529a73891937c6f3c91798098cf10b909eb92e5f8acfe0e8f3aee0b71cb23ee2d9e6ad1e0f4492a0272c52d529849"},{"one":"77811b007dd1fc1b11e447858df37062e97b6fc14e059399814f3b4736188e3fb28bf7c3958bb8ebc6ae16c36884ba7c98b810fb6f8b358323412123c803abd4","up":true,"other":"c03ef1de42d522b44eef53be11f2c57b8b74fed9e87e6c2928c1feb48ddfecc67e1a3a8c8be1c47b3735a216d7054e2a4dda49fbd9a1ac702146aae5bdeced7c"},{"one":"936fad959da2d8b0cfb2bcd78c5da65bcce5e9463be7fc7367f45cdfa20678f4c466fb1e3f600783a270855fd4b9cd6265054f79ecb116141e7c67a492041bed","other":"a25958cf192a4f62301feda5d442535f78b983dd9e4599354f4898c8c1e6ad97ca7112549e1d1a1eacb4682cd1bf8b762368b5905ab33dbdacb585b128514ca1","up":true},{"one":"8f3e9102306a13adb91e01f7a847e7880054f1a7df8976d05facb3a8fb37d47cce04f25e18a19713e5c3da7541e96e829fc67c8b924b717d2d9586c9c12d4fcf","other":"0c9a05514b96e7c3a0fbca21552e158faa70047246b230addca172a5023fd7439acd1c3a0b4f9191579b308dab38c961734ffdb36fb8e16383e912d070fc0218","up":true},{"other":"eb6d41d8d96f1933dff017d5fa0c46c6d0bad5d273b7c321a12858ac90ec00fca6191d29419897d2e25ec2d8ebd8c6a81bbde2d3f266f842e64b2b822161f1ea","up":true,"one":"9bdacc256acef0433805477d38f32be849a8846d88cb883b19d290454639b42c6ab6c5c52d4f83453e8a156af7d85f606458aa9c0977c67282f56f34ff0acbfb"},{"up":true,"other":"3dcf18c35593b47bc463688493b792d6b9d13eabe05396e491953608f20cf55f770fc21be32b00335fcb2f0ba02735b92569b2b64a44c344ac348042876e8f15","one":"aa53ca208cc0c9e544fd9d52cab44b5e2887256bb006037b855b5c94d7f79c9388fdbb23c0bf1d2eee12d67125e082fa7ecb34c1129ca8eaecfd85772b009435"},{"other":"15ceb62ee0f53379aa202950634ed881ba3b7bd4b46c80723ee48190079311e24ffaacb167a126a40bd6732c384f3c26163aa043edca03cb52a97b6da189aec7","up":true,"one":"740919ebae9b4fe646ca716ebb8923bf2a1b1963767d86f55ea95911d88d163cc2e07b1420669e64b62cb267b625413444b783b8e4a7bd6a0f481f4d84e984b1"},{"other":"6a55b94c9990249b24cdbeed96f065137f7b79ea8ee5f58da150d3962dfb62ba401960a53e7e8bd4e2c2908aa1a59b9d5efb4aafb316a9ab4fa67a0d95b58c54","up":true,"one":"1edeb91789b9aa996fea7a70964e0be33ee50acbe6d8f7d9d9fcf6dcf755dab6402637a610116f0eb716b19259429bdcced8bebc28ffa334387a430efc21b9b0"},{"other":"77811b007dd1fc1b11e447858df37062e97b6fc14e059399814f3b4736188e3fb28bf7c3958bb8ebc6ae16c36884ba7c98b810fb6f8b358323412123c803abd4","up":true,"one":"dd6acfd151220f21b03701ca554a5e134dbd1154dda21d9eec45809e7858fe83eca3953fc688f499030198f22052c3681a9f49207ef9b11a760456ab9637352b"},{"other":"3948a7a939b9a1f4201953bd9b955ee7be87d09b63c7a45167f556ac06fe3c4c2a75d935bff50668da5e71e46802b55d7a9945a92d7807c00625d129cbb48f82","up":true,"one":"a25958cf192a4f62301feda5d442535f78b983dd9e4599354f4898c8c1e6ad97ca7112549e1d1a1eacb4682cd1bf8b762368b5905ab33dbdacb585b128514ca1"},{"one":"228b3646b15527f4df07b847a62dbf9620cb068f829e9086b5f437d0b64d8a027cab44f19db5e44189b5099545ecb25d49384c261748f9533cfb0eb11a1eca5f","up":true,"other":"8e89fe4b3fffea8af247d2581aa511056efbeb796058d50a341d57aa0f7ccc2192d90cfb8d18558363df798567faaddb86815e8bd671b36ca37af0651535aabf"},{"other":"9bdacc256acef0433805477d38f32be849a8846d88cb883b19d290454639b42c6ab6c5c52d4f83453e8a156af7d85f606458aa9c0977c67282f56f34ff0acbfb","up":true,"one":"85c0b055439f114dee5eb0961013c117a48d62b0f17c61a7fd92a84092ef09bb3bbce686aa96e14528d5663565c57d657fa9813b1f38e268caeb1cb0842ef232"},{"other":"0c82c4b414375479375703ed9c19fb08c8143229ed4f1dcf448c6cf313810c098905123bec17969276936ae0cc39ed251b2811dbffb551d61159862b0eac0a23","up":true,"one":"884d32d09dfef937f3ef1cd6fb5f530c2c574487c0ffd4185ca405c8b2ac73044a196c34352e850ce15321eec6579da654a696381f3e5830d03c7aa18923da6e"},{"other":"17ae0b24297a3e6e027884e5e4529b6646ae340f5736eebc6187a9b59832a445f3644172d92438351e3803e56a67472b29f3e1d48844ae2e11e5e6670eed1436","up":true,"one":"c2a9c77247871cfa4d3c2d1b47619df91ed5b331a44c8e21f7c9ce431a4db9dfb87713558cc8a37911393907b4cc60be9445bad18adcea1bc5f318256e71be14"},{"up":true,"other":"e0a043f98b462f10f72aa61ceda52f9c27829d086f6f2c5bf4db4fe32759002e5ff9519495d57dbb83d963a1dc991a1defcf5b9ef0d543789f38c68f5d07122b","one":"92dbb67da2b99a8fe46b1e510addc2b83e357ac0b5287b7ef5c1b1bc6e252b8dfd605a6896ede65848e429216d1f67d530d9e7b83ff14058aa2e5b6e405d6801"},{"one":"8ee65c0937cdf860d5329132c34bf28b5dc4d2593986fae80e4b35efb54ec24cdbf294223515363a917a22dbc6db463c10c7484e22b479b9010059c2521b6317","other":"da22fb43c6d230d92f9c09454e282dc45dffc759740566039f1bdfb58171c6801f721841de83217277b3fb70983e7d34da53bbf25d1d45413a78d9afff151826","up":true},{"up":true,"other":"ea2921612b827e3c26328368bed9be7cbf1f2b2aecaf31863c9cdccd74c56b651d6eaceb8ac9609a6653488837ded310df91e53a74789ae75cb841e2aeaf96df","one":"2abb91884cc3a8fb91b2f2f369f9430f2b3b05c75ce6203aa7a50312c9f141f9d0f615063d3576a5ce8a4be9ecb942aa804a717f76d9e8dca03d115dcc43f775"},{"one":"c2a9c77247871cfa4d3c2d1b47619df91ed5b331a44c8e21f7c9ce431a4db9dfb87713558cc8a37911393907b4cc60be9445bad18adcea1bc5f318256e71be14","other":"ba430731fc2082f4217ebd859c2865c28bf50a39674ca8615dd89f608ae434a09657e24644ac32807634aad7857547118c9228460195e50ec58b34789d4ad151","up":true},{"one":"c03ef1de42d522b44eef53be11f2c57b8b74fed9e87e6c2928c1feb48ddfecc67e1a3a8c8be1c47b3735a216d7054e2a4dda49fbd9a1ac702146aae5bdeced7c","up":true,"other":"e323da6ae861cb092543992b8985639f9b3bcaf1c3c68757f4603a67800be62950fe7d8f8ef80eb83a18107b677c7f5047ea89a5790e0ea2a7969f4856d28488"},{"other":"d3cd2f34f67830ccdc295b7537a6d27c02b44503808ca666124f52ecc3d6c35b7d3f14343997006aef2cfbefc8d27809d389477e99c236b9f8a897a4bc406a43","up":true,"one":"2bea7540c99456ea889a8ba2e448c11e6257bf987d01f13eea48128ba58577ab0936855035ee140c9907e382a34ca85a179c74892cbd9eb92fc2b35601addc6b"},{"up":true,"other":"c9d705012a06d82c4d44db95b4f1c63ddd33ad64d732e96b1d878caa0caac433d4096f01495a6f0e8a56af122b0470fd745db6d906353b590a4710472b93f5b2","one":"6a37e63feed9e68c52cb8b385d5e8d8dbd2b211c57ded0d3b01fe8b306af5c0e5a7405d0d9a942648f0131926240d53450bc43f922a053528e5830d918313c3d"},{"other":"b9c7b885430b9b1a4425bde30b3629559f5437e0e30a0299fc6f6e097cbcca8af9e285caf5dea685a0237f60e06f490c39a1e3e487f14a2b9f41a5135f2ba994","up":true,"one":"8ee65c0937cdf860d5329132c34bf28b5dc4d2593986fae80e4b35efb54ec24cdbf294223515363a917a22dbc6db463c10c7484e22b479b9010059c2521b6317"},{"one":"869cae165389e7dee7b7df4e012ee1a39737366c306d8f4b0db4510b2236e0bd3a4d1d4af00b1a8c1d360e23da47de52fc1632edb03c7f1429aacc8aa4994750","other":"e33a1476fcb8d2a1b9ee15871a960ce7a3337c93f5956a2825b1f8b2885dbdc0ed652b1eba549523866632b5b6898310bc638d946a9fcce27d65117eb44c25f3","up":true},{"one":"ec19efa1d488e74da6bf239825b24678f549c377326c5d33d100b708a9a28a3fe129d542d7ba71e0ade46c15c6e9b38f09422560444388e609a8a66ceb8e0ae8","up":true,"other":"60995852a2385ce8d7d24dc94b85a2f0dab6e5c32e910dfe367ea9c6ccb7b0b2eb611fdf120f8c697097e2f137cefff42e8d9db16b664a857a38c5ace837ffa4"},{"other":"f6a12b23423c047927a3024a6dba7ce88927cb21d4df3778bc5ebb262cc403261c79ba6d9bda07f1852c009d803a77f429e9e48ec1d63cae98256e529d45b276","up":true,"one":"ec19efa1d488e74da6bf239825b24678f549c377326c5d33d100b708a9a28a3fe129d542d7ba71e0ade46c15c6e9b38f09422560444388e609a8a66ceb8e0ae8"},{"one":"f5d95e0c5a873ff5a95e1eb34f1ed258d77adf98ee0886d93c4a24b1feaf6955e6e4c4ea0eccb2b9723870bae61e693643d6ad96dd8da01672542611f7c49069","up":true,"other":"5d002c37b74a6656db86f102b0cec82bc35a819a480e5a2952db0140ebab65dffeb1a79f04d53ff61447b5fad7c58cb75ea1c91ea47fcb9e024f27b92c6c874d"},{"other":"6b104eff1dcf58d11a7f707bbd41a910b2735b262c29e0f4e4127fda1b67def4e89b6ebc1b3cc1e06c3968d0898e1085badc7da24d3cd6624cb100e85863cc97","up":true,"one":"46717bc5fb7fcbcdc961e7ef091020f9f222858cf3d4afcc0b0bb1b782b7055d9eb833e0a04cb32d80406133ac77162521c43edf9f9690872222760e31462ccc"},{"other":"d43bd6d3ae39a04e4e144a8a6f80b2d54472b5b9b6491dccf44b1716a63d24c56e3a871b3b8fe983d992988dc07ace06736ead3b1287914b629fcfe17e81f36f","up":true,"one":"d6747e1f8594f7449fc6d7c0e63ee843480567d498db096ff04229420861c83bca5215fc19d8fede0c54484f111f1f2581e189e638c21c5d9e1fd3174bbb3e98"},{"one":"ecb93d8eba17afe92979e8154252a08dd58de6ff3188b6829e3e25967846686f54199ab2b081e77b0048dcab204f05aa2c5cbd0efae4bc43a612d471d4e1197b","other":"4ff2981a47da46c753090e193a8bf43c3372a6b07a37cf0552de2ced455fbb8a76d969cd97b3e4601d8a808bd2a73f7729ed8a61df2f2a0c2cee1425d0bd9ab4","up":true},{"other":"46717bc5fb7fcbcdc961e7ef091020f9f222858cf3d4afcc0b0bb1b782b7055d9eb833e0a04cb32d80406133ac77162521c43edf9f9690872222760e31462ccc","up":true,"one":"bac3fd2ea491d8e4ce1e5d469ec73f3d537d61279ae66e7a394b20a188244a886d3059ef0d304c0801878f9640374f7c8aaf56558c41f12296d3fc7f911ed66c"},{"one":"9309549fc50173d6826fe63cf18699f49199c3789616b843042fe1a6adab6ed4bdd7a7a06acd276e0398cf8bffb26c12a4227725d7bbd386a9a55fc601c21405","up":true,"other":"49256eccce3e036928a4b6b346126c6777dca5ea0134de85efca340f97ad0f827f3094f1562e3e186d35b8292a50c20ffae01409890bbb78598494285e14dc2c"},{"up":true,"other":"0c82c4b414375479375703ed9c19fb08c8143229ed4f1dcf448c6cf313810c098905123bec17969276936ae0cc39ed251b2811dbffb551d61159862b0eac0a23","one":"95ff4dea07303e1ba641a5c510e714ef232f4dbce9ad2e8b2f62644975eae41fc4bb9d1af3fae4d5ea4daeb18f8248e0b3131c7d843d35d33f3afbf7dfa4c2fe"},{"other":"0c82c4b414375479375703ed9c19fb08c8143229ed4f1dcf448c6cf313810c098905123bec17969276936ae0cc39ed251b2811dbffb551d61159862b0eac0a23","up":true,"one":"6c40910f0556f892a7542989fa01d7e3682fca89aeefb5ed885808f88ff17b6d13862f461c10d629a005ae67abef542d75e5b20816891b6944f71560f5c2dfa8"},{"other":"f5d95e0c5a873ff5a95e1eb34f1ed258d77adf98ee0886d93c4a24b1feaf6955e6e4c4ea0eccb2b9723870bae61e693643d6ad96dd8da01672542611f7c49069","up":true,"one":"46717bc5fb7fcbcdc961e7ef091020f9f222858cf3d4afcc0b0bb1b782b7055d9eb833e0a04cb32d80406133ac77162521c43edf9f9690872222760e31462ccc"},{"up":true,"other":"ea2921612b827e3c26328368bed9be7cbf1f2b2aecaf31863c9cdccd74c56b651d6eaceb8ac9609a6653488837ded310df91e53a74789ae75cb841e2aeaf96df","one":"e33a1476fcb8d2a1b9ee15871a960ce7a3337c93f5956a2825b1f8b2885dbdc0ed652b1eba549523866632b5b6898310bc638d946a9fcce27d65117eb44c25f3"},{"one":"33cac8f621b9122e118036154778d27dc419b6b58ea2e89b833f3932f411dbc3511d92b55ae4cf80632142bc8e67994899aaa30c499d0289fae85b12564cf01f","up":true,"other":"c9d705012a06d82c4d44db95b4f1c63ddd33ad64d732e96b1d878caa0caac433d4096f01495a6f0e8a56af122b0470fd745db6d906353b590a4710472b93f5b2"},{"one":"06aab75fed9a03f5525e3f1d8f8997fefaefd5b16e8f485d571beda00b1741efbb61a8a74fa12c2f6de66227c3fabb4d411659cd9c7b1ef32e171e6bf517cc39","up":true,"other":"869cae165389e7dee7b7df4e012ee1a39737366c306d8f4b0db4510b2236e0bd3a4d1d4af00b1a8c1d360e23da47de52fc1632edb03c7f1429aacc8aa4994750"},{"other":"c0bec7375c66bec98524ade2245c1d7480516fc5d87a3249e64ec86418e80e202f1e3da76832e97bbc3dcaed8c96ca344e4829347b4428f4b1cb61999e404c05","up":true,"one":"869ca41ea1f82bec5f43807a3aaaabc39b21c62d3c9c8bdc0709683e22dd37cb2f3c313766809076d2c02d0d6171f4f32a1b5080abcb8072d88981042ae6237d"},{"up":true,"other":"e8a679f627d03347a4fcec0a0940f7ffa90ce3fefea290db3af4f3a32d27965bfb51832b6a6de2495c8a8cc026bcf993b84a0cced778e158bb81c034f5e4bd76","one":"624248a794fd62248024360f128b2e503c752340694a316bed420e5ed2cebeb5bf970df95a2806732237a26de3778222b0454e2e7d2875129b193e7890fd5b95"},{"one":"6b104eff1dcf58d11a7f707bbd41a910b2735b262c29e0f4e4127fda1b67def4e89b6ebc1b3cc1e06c3968d0898e1085badc7da24d3cd6624cb100e85863cc97","up":true,"other":"dbb6621460b054f584f1c6157b4020f3c58d84c3a12b57436e10525ae60ab27036bf3edd68b92f2b13674877d01c2871dc67a9031c3d0470985f4b071696346e"},{"up":true,"other":"7db14fde1da8794ae7ab5de37c9e2537e1024bc830c176c0d01635cafed47773d3a28e156db81ecdb95903222b900c3ebd4c4b3db2971dc0ef6a1e386027ffaa","one":"b58b3e200f6072ddb38130944a01d2829c755b8bd1a08abd010d1bbf86dabd851b2c1ab4cb961451bd7e8499f6c7378830bcd27cde825846654853c172597bf3"},{"up":true,"other":"d3cd2f34f67830ccdc295b7537a6d27c02b44503808ca666124f52ecc3d6c35b7d3f14343997006aef2cfbefc8d27809d389477e99c236b9f8a897a4bc406a43","one":"b18c7131a319db61ab84d06e90092d93c91141e9a270630af9c3ab1eaf3bcad09f4d20a1fc845b21c994bf4d9e337d0bd756a75e2198097540355e7ebbb531b2"},{"one":"3e7aef8260c0d9717aa59b65ce7c554e53b81f19f5b9400321704a7ddf5041b0fe31b5634e90b93e6984060defee0e153997bbfe196166cc8d83165fd5eaf41f","up":true,"other":"b87e7f36ed6bf142d48545024d2fd6e120c44511701e7c0b7d7fc786f4f29d3357024b15f70b78215d8a4c2b7572d608c11b31612743e23db4fa673f0cd6519b"},{"one":"f52281c227aa82a3bd5fabfdcf8bdf1d9ea6739ab9b9075340143d59b4f2f8a79a981609c9f42823a0253c19a7281eed0e912e4054363ab7fe50117563ef14e0","other":"c03ef1de42d522b44eef53be11f2c57b8b74fed9e87e6c2928c1feb48ddfecc67e1a3a8c8be1c47b3735a216d7054e2a4dda49fbd9a1ac702146aae5bdeced7c","up":true},{"up":true,"other":"b87e7f36ed6bf142d48545024d2fd6e120c44511701e7c0b7d7fc786f4f29d3357024b15f70b78215d8a4c2b7572d608c11b31612743e23db4fa673f0cd6519b","one":"dbb6621460b054f584f1c6157b4020f3c58d84c3a12b57436e10525ae60ab27036bf3edd68b92f2b13674877d01c2871dc67a9031c3d0470985f4b071696346e"},{"up":true,"other":"b9c7b885430b9b1a4425bde30b3629559f5437e0e30a0299fc6f6e097cbcca8af9e285caf5dea685a0237f60e06f490c39a1e3e487f14a2b9f41a5135f2ba994","one":"624248a794fd62248024360f128b2e503c752340694a316bed420e5ed2cebeb5bf970df95a2806732237a26de3778222b0454e2e7d2875129b193e7890fd5b95"},{"one":"ecb93d8eba17afe92979e8154252a08dd58de6ff3188b6829e3e25967846686f54199ab2b081e77b0048dcab204f05aa2c5cbd0efae4bc43a612d471d4e1197b","up":true,"other":"48e35d67e14ee2f329c0275bc965829b761885dbc3671f4673d84d76d18a5b6415e619e219b5d90761a5c6bd2f43c6a58708286a063daf46b502944f8ef9230b"},{"other":"b87e7f36ed6bf142d48545024d2fd6e120c44511701e7c0b7d7fc786f4f29d3357024b15f70b78215d8a4c2b7572d608c11b31612743e23db4fa673f0cd6519b","up":true,"one":"6c2788dec7ae7a77134065afc1174bb92b87833e87acaa72fe9e62c92d2017f217f9fbc5884cdfb7236a7bb75e463e49ecceb1641a8629516211d9699587046e"},{"one":"e7b2adabc2c99ac47b1e94fc0a2c63a00a1d622ea67a4c1858f4cec93fca957d43d8429605761bdf5eed4f733dac1a3d12fb928f22abf248965994acde63864a","other":"0e164c8692532e59c76ef84319a1093324f46f77618d3a836a279df52edca6c839061c0582dac7481da1bd0f3e2b58fc0dacd6ee5d678ba1406d4a1a25fe761d","up":true},{"one":"b18c7131a319db61ab84d06e90092d93c91141e9a270630af9c3ab1eaf3bcad09f4d20a1fc845b21c994bf4d9e337d0bd756a75e2198097540355e7ebbb531b2","other":"d43bd6d3ae39a04e4e144a8a6f80b2d54472b5b9b6491dccf44b1716a63d24c56e3a871b3b8fe983d992988dc07ace06736ead3b1287914b629fcfe17e81f36f","up":true},{"one":"5319bc9864d87eb33f26ff9732824d21a0a5ab70b254bc70a47554ffc763ae1559000d07e3eac9f883bd9e7f249d80edf14ab39c89c375bfcc5ec9e840ec9673","other":"b87e7f36ed6bf142d48545024d2fd6e120c44511701e7c0b7d7fc786f4f29d3357024b15f70b78215d8a4c2b7572d608c11b31612743e23db4fa673f0cd6519b","up":true},{"up":true,"other":"0e164c8692532e59c76ef84319a1093324f46f77618d3a836a279df52edca6c839061c0582dac7481da1bd0f3e2b58fc0dacd6ee5d678ba1406d4a1a25fe761d","one":"4eab70233789c544bec97040a04099494bf269a819584a5d0b42295c918a52b02f224a8ed127aba3d92c02f567356bea4b95f77230ef548dfa7fe44b643d8704"},{"one":"488854534ec5a3479d8ee13d9b7daf07479f6b5505f319eced44dad8c316f6ff241ce2101e95608ba635067f5e5741481b78f419c4bbd465bf7e837dc4e54d64","up":true,"other":"6c2788dec7ae7a77134065afc1174bb92b87833e87acaa72fe9e62c92d2017f217f9fbc5884cdfb7236a7bb75e463e49ecceb1641a8629516211d9699587046e"},{"other":"aa2028d356a88eca8e0fcaf218d62ace099c3f72dfd95bb28f30ac9a926034cf1d60a40511f7495652745de80d71c0f6830019e206c88e2b6ef0cf4f05d7fe9e","up":true,"one":"8c459100df488b992fdad207a096a434d67cb733619adfd09a311095568d4c9db293d9a892675551805559456d49a3fdb19c2cc698b14552bf0ace584d4d90dc"},{"one":"e0875ed6be1e163b15c13cdf37442f838670d0949349ee9ff119a0451beffb1a302943ee9d7cba48592922f64908aeb0f39f6e2e3725d1e7cdc5db34083b6977","other":"7a8cb96685c1b8fbaeb18c8dc1f9f2631b23bc035e704e2f5df915b8bcabd6e2025ddc30324c69833f86e577b250c0721fee9d294f3e22016ae4c59c5f88845b","up":true},{"up":true,"other":"c63b88f494b14d5a7c1da124ffebbd985d19806b91d4b111c83ae129c4ef19614469980a09fbeccebe3b0358dd16194bdb6452d0b3dbb43a5467e23bb13f40d6","one":"b1dd1b08975319030626aab821032a0c687a103ee8942e8a2e2cf029dd72832a49630e78d2d8b184579f22178aca0e875f9fad701fb81afd2ac110ab2b417376"},{"other":"9c8fca41b833e88110559b9258653160f5fb236bd637272ac58fe1adf333f4df75b94a805eaebb9f10a8c1a26d357dd75140560551d3fc4da79da2c4fc9479c3","up":true,"one":"3b71a324bd7b1a8fb19d8206eea1ca8190cb1faf5fcd1bfc52cef6b52296fe1db3e54d70180133fad1fa1188499d0dd73d2d075fdc6b3ffd9042d690e7d88e02"},{"up":true,"other":"c0164fb4a1acfb4f3b1a09f9f3ab226c382529a73891937c6f3c91798098cf10b909eb92e5f8acfe0e8f3aee0b71cb23ee2d9e6ad1e0f4492a0272c52d529849","one":"bdd17545242bedba1e4c36fadea95db655f8f220f10ae143084690a3c8d4e7ffb79a64af9f1bc8514addbd63695b2f20857e8d162f25318faac885f77b385138"},{"one":"ba430731fc2082f4217ebd859c2865c28bf50a39674ca8615dd89f608ae434a09657e24644ac32807634aad7857547118c9228460195e50ec58b34789d4ad151","other":"8c459100df488b992fdad207a096a434d67cb733619adfd09a311095568d4c9db293d9a892675551805559456d49a3fdb19c2cc698b14552bf0ace584d4d90dc","up":true},{"one":"d3cd2f34f67830ccdc295b7537a6d27c02b44503808ca666124f52ecc3d6c35b7d3f14343997006aef2cfbefc8d27809d389477e99c236b9f8a897a4bc406a43","other":"0c82c4b414375479375703ed9c19fb08c8143229ed4f1dcf448c6cf313810c098905123bec17969276936ae0cc39ed251b2811dbffb551d61159862b0eac0a23","up":true},{"up":true,"other":"69f999937943be00e5fca5c7cc942ce13b6752a72813368da2fbfcf74ad807bc6edd85537e087b6f73c0469c7b76a5d8f7d883bd315f3b35af32b8da293ed243","one":"7465fe601a9ad8e640069e6e07d56afabd3d4f008f3084f944d869b47fda3f511f191062802a53da511f60891dd0bcc5fac60254ef9db7aa3b41f5791b0b6975"},{"one":"5114329db828f9568ccb0d7643a10e273aa626177910f55e22a53abf1ce8ec75b95465c983446b20eac0ff9c59c5dc53eca95b24aabcc8dd110e397cd2934047","up":true,"other":"0e164c8692532e59c76ef84319a1093324f46f77618d3a836a279df52edca6c839061c0582dac7481da1bd0f3e2b58fc0dacd6ee5d678ba1406d4a1a25fe761d"},{"one":"20f6a8be1d2d8b5d6a43d851a2f5475385ef07fab80ac46525d0beccf3e25c01d726cfb3a1179e8343b1e88d21684fb24dd6e6497537d4e7e9edd59cb95d1b8d","other":"699c923976c5b8c70c353840d3e384750f466954265f05fbb0d5877a2c0318a041dc57adc12ac6e8fbae7a00d6b6675e1a1be3a8f59dac12727ee3f8ae467a13","up":true},{"one":"c2568576c2c9ef47aca0baca52709a4fa44b2ed478a062f7b161fac2bdba68568df371ac7754255fd07d79bb9918249a914946a6c318d579730bee9bc609922a","other":"dbb6621460b054f584f1c6157b4020f3c58d84c3a12b57436e10525ae60ab27036bf3edd68b92f2b13674877d01c2871dc67a9031c3d0470985f4b071696346e","up":true},{"other":"48e35d67e14ee2f329c0275bc965829b761885dbc3671f4673d84d76d18a5b6415e619e219b5d90761a5c6bd2f43c6a58708286a063daf46b502944f8ef9230b","up":true,"one":"c61ffc88f23f9f536497cc10ffcb7000ec6c4b801998ae7075ddc9079fdc1da8350e68744dc9e95ff892dfc5e52c62a3ad913a87fdacc455aea99b09aa002b57"},{"other":"8f3e9102306a13adb91e01f7a847e7880054f1a7df8976d05facb3a8fb37d47cce04f25e18a19713e5c3da7541e96e829fc67c8b924b717d2d9586c9c12d4fcf","up":true,"one":"c63b88f494b14d5a7c1da124ffebbd985d19806b91d4b111c83ae129c4ef19614469980a09fbeccebe3b0358dd16194bdb6452d0b3dbb43a5467e23bb13f40d6"},{"up":true,"other":"aa53ca208cc0c9e544fd9d52cab44b5e2887256bb006037b855b5c94d7f79c9388fdbb23c0bf1d2eee12d67125e082fa7ecb34c1129ca8eaecfd85772b009435","one":"e9cd25d1ef3fef22160bce7f7badd7646ac58ee40da6a438f61a067c51bc51d6087ed950ec9e909bc438ebe62e316cbd9489f3c9bfa2898615632414e04f1dcd"},{"up":true,"other":"7a8cb96685c1b8fbaeb18c8dc1f9f2631b23bc035e704e2f5df915b8bcabd6e2025ddc30324c69833f86e577b250c0721fee9d294f3e22016ae4c59c5f88845b","one":"c03ef1de42d522b44eef53be11f2c57b8b74fed9e87e6c2928c1feb48ddfecc67e1a3a8c8be1c47b3735a216d7054e2a4dda49fbd9a1ac702146aae5bdeced7c"},{"up":true,"other":"96cd4caa32c0b3a3493e24e13fad1ef75c621005d74154c3fc8a73cca4c0120452b6432334d94849c63f75d56a2943a453c86d2a14ad1fb61ae6833e58451187","one":"e993be8034861aebc9bbd11115f25d9c719d43fcdefc323599616cc26240cee38dfc27bb7f339149a54a3c9ad13b2d6ca4f0ae690e4355605eda6b789c4a431e"},{"one":"8c459100df488b992fdad207a096a434d67cb733619adfd09a311095568d4c9db293d9a892675551805559456d49a3fdb19c2cc698b14552bf0ace584d4d90dc","other":"f60755ee9464c7db769bb7237016fa165441d18ac3bfed7cd2a220a9bcbead202dd34eaf2f9398a3d36bdfc2671bbd46ac25ebe264a8118afe1b7d0bd38710f4","up":true},{"other":"7a8cb96685c1b8fbaeb18c8dc1f9f2631b23bc035e704e2f5df915b8bcabd6e2025ddc30324c69833f86e577b250c0721fee9d294f3e22016ae4c59c5f88845b","up":true,"one":"0e164c8692532e59c76ef84319a1093324f46f77618d3a836a279df52edca6c839061c0582dac7481da1bd0f3e2b58fc0dacd6ee5d678ba1406d4a1a25fe761d"},{"up":true,"other":"69f999937943be00e5fca5c7cc942ce13b6752a72813368da2fbfcf74ad807bc6edd85537e087b6f73c0469c7b76a5d8f7d883bd315f3b35af32b8da293ed243","one":"3dcf18c35593b47bc463688493b792d6b9d13eabe05396e491953608f20cf55f770fc21be32b00335fcb2f0ba02735b92569b2b64a44c344ac348042876e8f15"},{"other":"e5cb29b25debcfaaacc0b04e708c8c1cb9d2dee29e82596a1c72a934032cf738800b9525cc277d0c5f5dacf2f278329b54da161b4bafa285243fa0e9fd7b2f3a","up":true,"one":"d3cd2f34f67830ccdc295b7537a6d27c02b44503808ca666124f52ecc3d6c35b7d3f14343997006aef2cfbefc8d27809d389477e99c236b9f8a897a4bc406a43"},{"other":"b183f12f3602bfdab0480cb0b0ba7dc69b267b0dbc7e54c316741cb78b9e99aa69fd321ad7755d095e9be14e6bd90fe14ef8fe9bafc1a0dea10a144795021a08","up":true,"one":"c63b88f494b14d5a7c1da124ffebbd985d19806b91d4b111c83ae129c4ef19614469980a09fbeccebe3b0358dd16194bdb6452d0b3dbb43a5467e23bb13f40d6"},{"one":"f98c0f4444a1ec80773454ddb691c226b81d8e2f79ed40c45a422d3359565edf7bd635d3eb7bd6c9e0870746849fb86f0b1b34cd56ec8d3ad969812e080f4983","other":"5982e7dfd39c527851f6ea6430b70e654d95df5ec4401ca1d8dbd1034cf7a65d1126d60b36ebbd396c9ca32e6e8515f34f9dc0a8d2980afe4aa181c8bf68437e","up":true},{"one":"ee3471e1d835c4294f7ba642103039ccc548fe4edc177c79b63433ebbb0dc9d06600844f1fed76c7096ee9538e49e4e86fb8cffe9095dbdcde27695ff28ad395","up":true,"other":"69f999937943be00e5fca5c7cc942ce13b6752a72813368da2fbfcf74ad807bc6edd85537e087b6f73c0469c7b76a5d8f7d883bd315f3b35af32b8da293ed243"},{"one":"a1fe0d27f82309911a4b758c4e597bde16adc1e2fdfb07b52dea5092cea40ff212ea2cc831e385094b044f519909cf978f350b16ffd4c70c159cf1372301a3cf","up":true,"other":"b60def37233dbbc0d5f7fcddb304be1c0b6508e1e3d8a09a8290f7363e9bb84152dcaf70b8f6bb3a882fee77ff03ab796a5c1c3654f251c9f5c746ac5ad88556"},{"up":true,"other":"3dcf18c35593b47bc463688493b792d6b9d13eabe05396e491953608f20cf55f770fc21be32b00335fcb2f0ba02735b92569b2b64a44c344ac348042876e8f15","one":"9c8fca41b833e88110559b9258653160f5fb236bd637272ac58fe1adf333f4df75b94a805eaebb9f10a8c1a26d357dd75140560551d3fc4da79da2c4fc9479c3"},{"one":"ee0b09ee6a1057c47102e582e2fdec7b9212802e59f062a9360da0db535d4987126ab24848c0d76fa8485431a5140307e2b0c0d9f37cbdb35756e6cc1bdb3bc0","up":true,"other":"49256eccce3e036928a4b6b346126c6777dca5ea0134de85efca340f97ad0f827f3094f1562e3e186d35b8292a50c20ffae01409890bbb78598494285e14dc2c"},{"other":"e323da6ae861cb092543992b8985639f9b3bcaf1c3c68757f4603a67800be62950fe7d8f8ef80eb83a18107b677c7f5047ea89a5790e0ea2a7969f4856d28488","up":true,"one":"8e89fe4b3fffea8af247d2581aa511056efbeb796058d50a341d57aa0f7ccc2192d90cfb8d18558363df798567faaddb86815e8bd671b36ca37af0651535aabf"},{"one":"ab8eda9b360d3e0b002ba31d48311057880844b828ad9817a2ad19736860d0114d4a17e9e9427c842d52e7ff61a09c2cad9b70f506e338909535542dae38ede0","other":"69f999937943be00e5fca5c7cc942ce13b6752a72813368da2fbfcf74ad807bc6edd85537e087b6f73c0469c7b76a5d8f7d883bd315f3b35af32b8da293ed243","up":true},{"one":"7a8cb96685c1b8fbaeb18c8dc1f9f2631b23bc035e704e2f5df915b8bcabd6e2025ddc30324c69833f86e577b250c0721fee9d294f3e22016ae4c59c5f88845b","other":"e7b2adabc2c99ac47b1e94fc0a2c63a00a1d622ea67a4c1858f4cec93fca957d43d8429605761bdf5eed4f733dac1a3d12fb928f22abf248965994acde63864a","up":true},{"one":"243164c4dd583f80c50813f43e5c27c894463400cd3afd776b36e79e7123d9261f01f06f92914aab83096b9a43fb655e79687590599284640a3a7d2c25454597","up":true,"other":"95ff4dea07303e1ba641a5c510e714ef232f4dbce9ad2e8b2f62644975eae41fc4bb9d1af3fae4d5ea4daeb18f8248e0b3131c7d843d35d33f3afbf7dfa4c2fe"},{"one":"b8e0a56df21baae43058f575b714ae9a33c097d18f1a628b3b6ae5e86dd46a06e44c0dc272baacb5be0f7bf57fd6ddce107544eb3b94dca1aeae9f5773496a72","up":true,"other":"9309549fc50173d6826fe63cf18699f49199c3789616b843042fe1a6adab6ed4bdd7a7a06acd276e0398cf8bffb26c12a4227725d7bbd386a9a55fc601c21405"},{"other":"69f999937943be00e5fca5c7cc942ce13b6752a72813368da2fbfcf74ad807bc6edd85537e087b6f73c0469c7b76a5d8f7d883bd315f3b35af32b8da293ed243","up":true,"one":"1cdef98d7b4de45c902c725384bd14c66084fe4159b26a0f9a24f432e1f561d035ca41e1c60fe64f3213b4f91a1afb953193dca1a7d535be0602b5d046bcbab8"},{"one":"81901d9f043b4b1649ade3b5d22ae5f8bb42dd6db1eb37b836b99dd1c0388509ed4b54cc5638c9d4a6c5ae6c6913bbfffb303d7d94bf4ed50e871cf95459e2c3","up":true,"other":"49256eccce3e036928a4b6b346126c6777dca5ea0134de85efca340f97ad0f827f3094f1562e3e186d35b8292a50c20ffae01409890bbb78598494285e14dc2c"},{"other":"37adbfdf66163e45f433d78f63210163fdacf4688ad90d73bed07975be017c43cddf2a26a0dee8b11d78f294b63d4875b6be15f42f10817bd3d77b342919a11e","up":true,"one":"e33a1476fcb8d2a1b9ee15871a960ce7a3337c93f5956a2825b1f8b2885dbdc0ed652b1eba549523866632b5b6898310bc638d946a9fcce27d65117eb44c25f3"},{"one":"002cb6ffa63ad71ee6ebc1df4c41f7a97c51f274b1d3b22420c87b73136be5169b9670508061d8261e20055fefce3b855388994672aa9a0f1475c43839aae4fa","up":true,"other":"51a570637394e9ab61fe95b3a608cc4e9dc8ceb63efe717938ccd4260a962d52e01b30e7034fbfdabd9a3c9616ee569550b38a6d6b4b19847f523254069a9f27"},{"one":"2b0a1f3a6466c6be1d7e84120db384fa37f7c73a01e9a105ae90e7d2203212ec974f016d3012afd26bc0f9a8411d0716cc59b6ecc9f665db12e306af8b34cb63","other":"865dbf61d8511603fe0d9ebfb10792b9f6b798187c0909039bd9b2492c41e428876f386beeac86d0dea871f4fc24ba435f0fbd9a11e74c044024934592af14ee","up":true},{"up":true,"other":"e323da6ae861cb092543992b8985639f9b3bcaf1c3c68757f4603a67800be62950fe7d8f8ef80eb83a18107b677c7f5047ea89a5790e0ea2a7969f4856d28488","one":"7d9979c13cd8841e84e5d199fc263962ca6fee12664d8526a581bfcdca2e3427ca169b9a0244dd8292a9a1be2bcedb0e8f626eadd307068c11c03b6df13aee33"},{"other":"d6a7257771baa4d9944592ead46b8ab700dbf91ebd4dc0ec7e5fb41cbda0622944269172fcec8352b89ef2c186d4c787af2b45a50533f627a97818477de034b4","up":true,"one":"6b082a09e343a160b60a01f74641c1d707b2fa8fee5f6f5a8b9e4a203bd86434227d2df982b246a752f843483cdf517e85fe3bd65453354232a6eb38dedbf314"},{"one":"7db14fde1da8794ae7ab5de37c9e2537e1024bc830c176c0d01635cafed47773d3a28e156db81ecdb95903222b900c3ebd4c4b3db2971dc0ef6a1e386027ffaa","up":true,"other":"95ff4dea07303e1ba641a5c510e714ef232f4dbce9ad2e8b2f62644975eae41fc4bb9d1af3fae4d5ea4daeb18f8248e0b3131c7d843d35d33f3afbf7dfa4c2fe"},{"one":"5a235aca7005df295d5bd924b1272452e9bdad408ca5223b9eb76800b4bd4e3158a1d663ce5243fee92233227249fe4bb8507e8cb2c3729744b273bf488ba60c","up":true,"other":"e323da6ae861cb092543992b8985639f9b3bcaf1c3c68757f4603a67800be62950fe7d8f8ef80eb83a18107b677c7f5047ea89a5790e0ea2a7969f4856d28488"},{"up":true,"other":"51a570637394e9ab61fe95b3a608cc4e9dc8ceb63efe717938ccd4260a962d52e01b30e7034fbfdabd9a3c9616ee569550b38a6d6b4b19847f523254069a9f27","one":"69f999937943be00e5fca5c7cc942ce13b6752a72813368da2fbfcf74ad807bc6edd85537e087b6f73c0469c7b76a5d8f7d883bd315f3b35af32b8da293ed243"},{"one":"b58b3e200f6072ddb38130944a01d2829c755b8bd1a08abd010d1bbf86dabd851b2c1ab4cb961451bd7e8499f6c7378830bcd27cde825846654853c172597bf3","up":true,"other":"243164c4dd583f80c50813f43e5c27c894463400cd3afd776b36e79e7123d9261f01f06f92914aab83096b9a43fb655e79687590599284640a3a7d2c25454597"},{"one":"c088bf88f1e152ca3fad17f098a71ca1021d46d8af12d0ee1c587a5e2a430d8e48beaf171fe01ee7680b671c00dd88c90f12a35c328a3f334661fdeee914a4bc","up":true,"other":"b60def37233dbbc0d5f7fcddb304be1c0b6508e1e3d8a09a8290f7363e9bb84152dcaf70b8f6bb3a882fee77ff03ab796a5c1c3654f251c9f5c746ac5ad88556"},{"one":"9309549fc50173d6826fe63cf18699f49199c3789616b843042fe1a6adab6ed4bdd7a7a06acd276e0398cf8bffb26c12a4227725d7bbd386a9a55fc601c21405","other":"c0f233e79d0a8d4af01f54c40640975bc113f464271ba8922fca0c28acc60367af0db06629e701977e86cb5917c891e39c21418cab459fe49132b680aa31600b","up":true},{"other":"6b7c94db790a2c1b903208904c4c75b66b17e7a00404727dbc7aeff404ac1118dc78ce4ca443f6b5245236f9e358c09b6da027ae1144e1a6682edca301176330","up":true,"one":"a5f7163586fce1750fd9a6e5c418af1c18ca6983069dcf1738fc9106ebf542a86e4ccfc50b45a0d97ca8681af8207128877f930f945e59ee262aa7f4014a01f3"},{"other":"7d9979c13cd8841e84e5d199fc263962ca6fee12664d8526a581bfcdca2e3427ca169b9a0244dd8292a9a1be2bcedb0e8f626eadd307068c11c03b6df13aee33","up":true,"one":"77811b007dd1fc1b11e447858df37062e97b6fc14e059399814f3b4736188e3fb28bf7c3958bb8ebc6ae16c36884ba7c98b810fb6f8b358323412123c803abd4"},{"one":"1b3107d9a96cfd11f4cd0ed8baeb7b23db1406c9c4a9dac76c772f49c0fc9404f6a4adae11120aa821757173f0cc1cb00e6ab555b5abffaae9001c0557cb75c9","up":true,"other":"865dbf61d8511603fe0d9ebfb10792b9f6b798187c0909039bd9b2492c41e428876f386beeac86d0dea871f4fc24ba435f0fbd9a11e74c044024934592af14ee"},{"up":true,"other":"228b3646b15527f4df07b847a62dbf9620cb068f829e9086b5f437d0b64d8a027cab44f19db5e44189b5099545ecb25d49384c261748f9533cfb0eb11a1eca5f","one":"b7cc9044d021b19cd8a6d290d21f1c91fd5deec472583d0aeed0a6aacc8efef9968079254132becc5443df14dd3f4feaee56d14b885c078649727b9659139fa6"},{"up":true,"other":"c0bec7375c66bec98524ade2245c1d7480516fc5d87a3249e64ec86418e80e202f1e3da76832e97bbc3dcaed8c96ca344e4829347b4428f4b1cb61999e404c05","one":"0c9a05514b96e7c3a0fbca21552e158faa70047246b230addca172a5023fd7439acd1c3a0b4f9191579b308dab38c961734ffdb36fb8e16383e912d070fc0218"},{"other":"b58b3e200f6072ddb38130944a01d2829c755b8bd1a08abd010d1bbf86dabd851b2c1ab4cb961451bd7e8499f6c7378830bcd27cde825846654853c172597bf3","up":true,"one":"51df4f4d4f020f22f55a5fd00c7f9c68c232c167ae4d4e80d7695f8f39c5aa0a7b565c1c55bdd6a21e06fa056549d08fd2e9d76fd79e21295557aa30d1ae022c"},{"one":"d6747e1f8594f7449fc6d7c0e63ee843480567d498db096ff04229420861c83bca5215fc19d8fede0c54484f111f1f2581e189e638c21c5d9e1fd3174bbb3e98","other":"0c82c4b414375479375703ed9c19fb08c8143229ed4f1dcf448c6cf313810c098905123bec17969276936ae0cc39ed251b2811dbffb551d61159862b0eac0a23","up":true},{"one":"fd0123c7b96004067e98e463e273de5bc5402399ae70a95985b5f682e30d4f35d070deaf8c71d201e98c4324d832b95aab7535ad8a2658f66e3e0bb1202204e1","up":true,"other":"51df4f4d4f020f22f55a5fd00c7f9c68c232c167ae4d4e80d7695f8f39c5aa0a7b565c1c55bdd6a21e06fa056549d08fd2e9d76fd79e21295557aa30d1ae022c"},{"one":"1edeb91789b9aa996fea7a70964e0be33ee50acbe6d8f7d9d9fcf6dcf755dab6402637a610116f0eb716b19259429bdcced8bebc28ffa334387a430efc21b9b0","up":true,"other":"bc0df855bdadcde3e447415444f655eb430925a8fa81cdcac75909e7d79750f01827938570e75e388cc7058ba8ebca47afadf8b07172bc078488fb618ba71024"},{"one":"d7e3661c0af6754c875217f93d34b254f1f45fc1359a4c6146cd0efa4c6e12aed9a4fb0a21a136f73af4fc2c6d0a63cb809d81855bbc9f51e29d23d90f77b326","up":true,"other":"e993be8034861aebc9bbd11115f25d9c719d43fcdefc323599616cc26240cee38dfc27bb7f339149a54a3c9ad13b2d6ca4f0ae690e4355605eda6b789c4a431e"},{"one":"95ff4dea07303e1ba641a5c510e714ef232f4dbce9ad2e8b2f62644975eae41fc4bb9d1af3fae4d5ea4daeb18f8248e0b3131c7d843d35d33f3afbf7dfa4c2fe","up":true,"other":"e5cb29b25debcfaaacc0b04e708c8c1cb9d2dee29e82596a1c72a934032cf738800b9525cc277d0c5f5dacf2f278329b54da161b4bafa285243fa0e9fd7b2f3a"},{"other":"7db14fde1da8794ae7ab5de37c9e2537e1024bc830c176c0d01635cafed47773d3a28e156db81ecdb95903222b900c3ebd4c4b3db2971dc0ef6a1e386027ffaa","up":true,"one":"ea2921612b827e3c26328368bed9be7cbf1f2b2aecaf31863c9cdccd74c56b651d6eaceb8ac9609a6653488837ded310df91e53a74789ae75cb841e2aeaf96df"},{"other":"ab13f773f6f2ff73032aa5f79c8897b75dda29bcbb14aa511e9401c2417dc9c510253071e28c7833c8d62fd2aef16fcd0c14ce016fbf4fec1b9a2173c717603f","up":true,"one":"222d7a2f94dc82a09fda70b8195fc3a60433a90f53998872318c57625c528c90572d78b444ac4901dcfece1a03ef8b6cbe7845366a845a942f341f6db58a9b3b"},{"one":"06aab75fed9a03f5525e3f1d8f8997fefaefd5b16e8f485d571beda00b1741efbb61a8a74fa12c2f6de66227c3fabb4d411659cd9c7b1ef32e171e6bf517cc39","up":true,"other":"0c82c4b414375479375703ed9c19fb08c8143229ed4f1dcf448c6cf313810c098905123bec17969276936ae0cc39ed251b2811dbffb551d61159862b0eac0a23"},{"up":true,"other":"8e89fe4b3fffea8af247d2581aa511056efbeb796058d50a341d57aa0f7ccc2192d90cfb8d18558363df798567faaddb86815e8bd671b36ca37af0651535aabf","one":"6a55b94c9990249b24cdbeed96f065137f7b79ea8ee5f58da150d3962dfb62ba401960a53e7e8bd4e2c2908aa1a59b9d5efb4aafb316a9ab4fa67a0d95b58c54"},{"one":"d6a7257771baa4d9944592ead46b8ab700dbf91ebd4dc0ec7e5fb41cbda0622944269172fcec8352b89ef2c186d4c787af2b45a50533f627a97818477de034b4","other":"002cb6ffa63ad71ee6ebc1df4c41f7a97c51f274b1d3b22420c87b73136be5169b9670508061d8261e20055fefce3b855388994672aa9a0f1475c43839aae4fa","up":true},{"one":"a25958cf192a4f62301feda5d442535f78b983dd9e4599354f4898c8c1e6ad97ca7112549e1d1a1eacb4682cd1bf8b762368b5905ab33dbdacb585b128514ca1","other":"77811b007dd1fc1b11e447858df37062e97b6fc14e059399814f3b4736188e3fb28bf7c3958bb8ebc6ae16c36884ba7c98b810fb6f8b358323412123c803abd4","up":true},{"one":"bc0df855bdadcde3e447415444f655eb430925a8fa81cdcac75909e7d79750f01827938570e75e388cc7058ba8ebca47afadf8b07172bc078488fb618ba71024","other":"2bea7540c99456ea889a8ba2e448c11e6257bf987d01f13eea48128ba58577ab0936855035ee140c9907e382a34ca85a179c74892cbd9eb92fc2b35601addc6b","up":true},{"one":"4b332b389f1142c0da42aaeb2e2692081d0002de0eb6741b3269e898a8101571d4556b755f2e8841e7a607bb41e398d2b0577fbe71098e7097f0fe6c720e1526","other":"d3cd2f34f67830ccdc295b7537a6d27c02b44503808ca666124f52ecc3d6c35b7d3f14343997006aef2cfbefc8d27809d389477e99c236b9f8a897a4bc406a43","up":true},{"one":"8e5e8366251e33277e7db6f6c04629b2ce3eee217e973acb97c83773671b0160c40732794584db741a29a763672b90f3bdf34151fd4a6986b9d0956dc61d9723","other":"69f999937943be00e5fca5c7cc942ce13b6752a72813368da2fbfcf74ad807bc6edd85537e087b6f73c0469c7b76a5d8f7d883bd315f3b35af32b8da293ed243","up":true},{"up":true,"other":"ab13f773f6f2ff73032aa5f79c8897b75dda29bcbb14aa511e9401c2417dc9c510253071e28c7833c8d62fd2aef16fcd0c14ce016fbf4fec1b9a2173c717603f","one":"3948a7a939b9a1f4201953bd9b955ee7be87d09b63c7a45167f556ac06fe3c4c2a75d935bff50668da5e71e46802b55d7a9945a92d7807c00625d129cbb48f82"},{"other":"aa90454031068598ee39af5f1429c7a72277946d50ec2004f340406dbcc9f80cac505c9d9b071f85e2ccfd4b13bcf943f3cb9dd9f96f62d41352af9d8fffe7e4","up":true,"one":"682288e4dae2374c4784acd0b285508920ce39a6b72cc0e30a3dbb7972e0394a2bddd5ee5f22a1dbf80f284dde4d9f8ede7847318d5353566b35a83e212477e7"},{"one":"dd6acfd151220f21b03701ca554a5e134dbd1154dda21d9eec45809e7858fe83eca3953fc688f499030198f22052c3681a9f49207ef9b11a760456ab9637352b","other":"bc0df855bdadcde3e447415444f655eb430925a8fa81cdcac75909e7d79750f01827938570e75e388cc7058ba8ebca47afadf8b07172bc078488fb618ba71024","up":true},{"one":"45d3827eb5c3b906fc61aaad79c5968f3dcf7b1ecc1e3be63e827ad6fb9291542686f42b3e142f43cc0437a2177b7362727842ea1d6c33bc795d936bba3ae457","up":true,"other":"9c8fca41b833e88110559b9258653160f5fb236bd637272ac58fe1adf333f4df75b94a805eaebb9f10a8c1a26d357dd75140560551d3fc4da79da2c4fc9479c3"},{"one":"884d32d09dfef937f3ef1cd6fb5f530c2c574487c0ffd4185ca405c8b2ac73044a196c34352e850ce15321eec6579da654a696381f3e5830d03c7aa18923da6e","other":"2751df9f64a8f2ff8ea45efc9bd02b281d963ced285260bcda7f9dfaed998fe4386fe65a7265876da6b4fee77ea5c12454869a70ad627da7ca888076fc629665","up":true},{"other":"c61ffc88f23f9f536497cc10ffcb7000ec6c4b801998ae7075ddc9079fdc1da8350e68744dc9e95ff892dfc5e52c62a3ad913a87fdacc455aea99b09aa002b57","up":true,"one":"5717a49591a0ecdff3d4449874d5ff9ba016afad5da19712ca0c8ebca8cefd84e6d8c778245f67f68c8dd730ad294fd017b8de279fde4fc919768ce85dba132d"},{"one":"545237d8463b75fd2e9bbfbffb35c5b78b4abbc85f6bfbd56976789012dd9a62ca1f866bf37bb33618e026aab764adb9ced5e00cd415562f69992f74c795083f","other":"3e2241cdb9f34c1d2c6930e59940e2c4b92b0287579d7263a620a609c5e66dca6d85df48cf1bffd63663a6704c42d0866aae3e484fd9a44b6a012f72dd3cef6e","up":true},{"one":"89d46e664ac471c7150fbfe43a49c98750fc64d5ca22fdc2a040c7ab78c25c48c1e9c2f0e5130d6b8eb7f0760fe962759d83f68cc08ffaac3520499b0ce694de","other":"dbb6621460b054f584f1c6157b4020f3c58d84c3a12b57436e10525ae60ab27036bf3edd68b92f2b13674877d01c2871dc67a9031c3d0470985f4b071696346e","up":true},{"one":"2880e0defd1bf2665bdd20dfb46bc0a9ad707f495211fc78e611ab479d78398db7daff7d3f4b6bf81fd13bf766ecc8271e0ea99a2d74abd2f9ddf98835ffdcf1","other":"be93fafaf43f6bb3efd2667d1468a8636cb752b245328eaa01468c0606d790322a7cd8e47857068e60118e28b8dd8aa1d2d4977c5b3d28d4b47f4c0658f05e90","up":true},{"one":"535287ca3d41fc1cdf20a964749a849c51d0aba285f41f447cc2b1dd6f5845b6b98e0241dbda0718b234ea850081bfbf9df01d1aa636d7dcbd99ef3c0a773aff","up":true,"other":"90b8e73916046b5433dce049bfe125ca2bf2fb390ff7301f9bc5d8d0183988577aa2a7392aaa28091aa81c8ac23942b5751420b9ee48e488a68411f9d2b1e5d5"},{"one":"b60def37233dbbc0d5f7fcddb304be1c0b6508e1e3d8a09a8290f7363e9bb84152dcaf70b8f6bb3a882fee77ff03ab796a5c1c3654f251c9f5c746ac5ad88556","other":"936fad959da2d8b0cfb2bcd78c5da65bcce5e9463be7fc7367f45cdfa20678f4c466fb1e3f600783a270855fd4b9cd6265054f79ecb116141e7c67a492041bed","up":true},{"one":"c69b9b181b2756a1345b73a97afb3dca909c253188c3b905f0b414465b750d2ffccb4c8e8eb5e3809549af55db473f3b12682f9bd97c5c75d68f23d67d91b866","other":"69f999937943be00e5fca5c7cc942ce13b6752a72813368da2fbfcf74ad807bc6edd85537e087b6f73c0469c7b76a5d8f7d883bd315f3b35af32b8da293ed243","up":true},{"one":"876618c8ba66c1b91b473a154be3e10ded3590ba83d620d30e0ff1fbac2f31f258b1299a3da5b56aa03269a80c119b7fc41dfd87d5bd996359e4ad8dd0ab2a6a","up":true,"other":"51a570637394e9ab61fe95b3a608cc4e9dc8ceb63efe717938ccd4260a962d52e01b30e7034fbfdabd9a3c9616ee569550b38a6d6b4b19847f523254069a9f27"},{"up":true,"other":"50c79baa3e6781482ccb5e960c699dd9c13f479467c6315c5292a396337cf3619e7faba1971a1f470051cb9042f80ea6750defe3936b72aac4d9bac6f8368c67","one":"6d0a09235ba0b0428938abf0e0782ac0ecf5697ef862888719a34fc956517aeef89d5e5f76d12e10067fee5bac8781dc10400eeb35c2393b9382b2a4f68f7939"},{"other":"202ae63076a5560418023f00c9965b2a1d12de932b5371ae270d63db88551a7aa1a3c48841f81948fad3435bb4a7e3e165a2eced9fd937444e4502471e23dae8","up":true,"one":"76643f67075c6e45bd176db19473240cda6f886d1cac25330e2d99c84a429934f4c6a606c9c72574d5eaccd0a3f1770dab05e6ff6a5b5ce4d7258fed2bc13d48"},{"up":true,"other":"29acdd4c1233441bd40f98e245ecc9de94de6f9d0ab7c1a9923d833a2c8e6c1bd26d792686fec762b31fe28bbdd7aa04c9a594d997d08c133bb24cb2d877595a","one":"37399617d62153bc471f3bf21c92385bc8602c80ffa0c71da8aebae595a9859cfd56257aae60ad30ef3ec4d07dee90623cce63749c8c3233c0aa0d17f9e89afe"},{"one":"37adbfdf66163e45f433d78f63210163fdacf4688ad90d73bed07975be017c43cddf2a26a0dee8b11d78f294b63d4875b6be15f42f10817bd3d77b342919a11e","other":"869cae165389e7dee7b7df4e012ee1a39737366c306d8f4b0db4510b2236e0bd3a4d1d4af00b1a8c1d360e23da47de52fc1632edb03c7f1429aacc8aa4994750","up":true},{"one":"2c976b6007cda135444233c7bd03d22ac9756710b746c36bc032e7fdd42f2ffb89ca5f5e754ff96b8f3cbc474e346287e5b8531d9f98fd63c426c632872220af","up":true,"other":"313a131ecb7d68e127d0fec8bb4a2e586886203c3d07857a93e7a39bb831703184d9ae28ba9ef3d986c2dae1a24f4f5bfa47cfc35f74f5512a126836364d7736"},{"up":true,"other":"b4557089e4247379e587a087f53b36dd1f86f85d9dcfab5dc562079978cd959adaef5b30d11258d9cb552e7c5abddf5377a71d449febe8f2acb0aec3ebd8ba73","one":"c6f38fe8a0f2b3773bae332e0ca7516e944bde186fe99daae10a2b0aecde3ce23c1834eaad97a4e6d2da8cd53a08dbafa72d2b827c851b115b74e8010125dba2"},{"other":"9bdacc256acef0433805477d38f32be849a8846d88cb883b19d290454639b42c6ab6c5c52d4f83453e8a156af7d85f606458aa9c0977c67282f56f34ff0acbfb","up":true,"one":"510536aba28aa635d8a1098a6dbd2070748ce1eb0e14b54b93a21196543a60df546ff6a2b3b5b9f32a5c2a37f5aba77d0b74f28b2dabeeebf3fe5afc20a3209c"},{"one":"02fdbcb00f20a3f6e894900d798fcb0aca9e21f5b107924c0999eb396220f16dee99fc80ccba796e66e69dcb9ce278b7e0e4539c7a7cd0fbc1037bf8e56c1e67","up":true,"other":"2c976b6007cda135444233c7bd03d22ac9756710b746c36bc032e7fdd42f2ffb89ca5f5e754ff96b8f3cbc474e346287e5b8531d9f98fd63c426c632872220af"},{"up":true,"other":"699c923976c5b8c70c353840d3e384750f466954265f05fbb0d5877a2c0318a041dc57adc12ac6e8fbae7a00d6b6675e1a1be3a8f59dac12727ee3f8ae467a13","one":"9c8f156797deff649d74d56fc42b4bb1a87312089114d4350424c375837d9c8068dd09af01c1c973d12ec5d7e8da600cd685cae70d3116b9dbda823092e03fff"},{"one":"3639f964feba681db9702cac3f02058f2e490fd7bffb217dc3480dc458decafd5955541fea89f0f6f14ee50a745eaf98b21363d6b4fb88c31bd32bf7845d524b","other":"699c923976c5b8c70c353840d3e384750f466954265f05fbb0d5877a2c0318a041dc57adc12ac6e8fbae7a00d6b6675e1a1be3a8f59dac12727ee3f8ae467a13","up":true},{"other":"c0f233e79d0a8d4af01f54c40640975bc113f464271ba8922fca0c28acc60367af0db06629e701977e86cb5917c891e39c21418cab459fe49132b680aa31600b","up":true,"one":"85b6404a76b4762156c8ddd2f312763dfe19b315d914533844cf229301880c57ffeadc0eb5f4a8d542e1d9fc961dfb5a572d2101172b1a0fc238ced05ba49ec1"},{"one":"6b7c94db790a2c1b903208904c4c75b66b17e7a00404727dbc7aeff404ac1118dc78ce4ca443f6b5245236f9e358c09b6da027ae1144e1a6682edca301176330","up":true,"other":"ec19efa1d488e74da6bf239825b24678f549c377326c5d33d100b708a9a28a3fe129d542d7ba71e0ade46c15c6e9b38f09422560444388e609a8a66ceb8e0ae8"},{"one":"6c95c653e15bb99d32656f35790400134cd7188e063f878e19cb9118eb469ae0362dc45255f2a1eae31520be01d42b5bc5bbebf03d644c9f206ca79cb33a01ad","up":true,"other":"869cae165389e7dee7b7df4e012ee1a39737366c306d8f4b0db4510b2236e0bd3a4d1d4af00b1a8c1d360e23da47de52fc1632edb03c7f1429aacc8aa4994750"},{"up":true,"other":"46717bc5fb7fcbcdc961e7ef091020f9f222858cf3d4afcc0b0bb1b782b7055d9eb833e0a04cb32d80406133ac77162521c43edf9f9690872222760e31462ccc","one":"5d002c37b74a6656db86f102b0cec82bc35a819a480e5a2952db0140ebab65dffeb1a79f04d53ff61447b5fad7c58cb75ea1c91ea47fcb9e024f27b92c6c874d"},{"one":"869ca41ea1f82bec5f43807a3aaaabc39b21c62d3c9c8bdc0709683e22dd37cb2f3c313766809076d2c02d0d6171f4f32a1b5080abcb8072d88981042ae6237d","other":"842ec3faa8b4a4cdec32abfa00ae827277fe2696e1b0c6551154533b16cf75ae69caf834b4f08488fa5c8b322fb633b1fd8a5b7d436e9c589cc9074dc031ae68","up":true},{"up":true,"other":"e0a043f98b462f10f72aa61ceda52f9c27829d086f6f2c5bf4db4fe32759002e5ff9519495d57dbb83d963a1dc991a1defcf5b9ef0d543789f38c68f5d07122b","one":"43086ff7ffd3c7bdec77bd288f41f1ee0ce21bd3f60a5df8931e2af6e7af5ef0fad432d29625491935d11567944351fc7867c807ebd12dd2c21c9e620ae0f85c"},{"up":true,"other":"e1f23e1caba66f5ff821edbc4a3d527539937f73d86dd0df43aa1266a99f51f2480a77961eff177fbbf852fc52cb9317179f80b1580194daaedadc3b00510751","one":"76643f67075c6e45bd176db19473240cda6f886d1cac25330e2d99c84a429934f4c6a606c9c72574d5eaccd0a3f1770dab05e6ff6a5b5ce4d7258fed2bc13d48"},{"up":true,"other":"8e8614a4c2ee2b1a3fa5ace0ca353cff36b3de3308ccf53665b8b56f8e2456a8a65f3846d786dccd68b1bfcefdd170ea5f8edb481800b1ce72d9fce2added7f0","one":"f98c0f4444a1ec80773454ddb691c226b81d8e2f79ed40c45a422d3359565edf7bd635d3eb7bd6c9e0870746849fb86f0b1b34cd56ec8d3ad969812e080f4983"},{"other":"4ff2981a47da46c753090e193a8bf43c3372a6b07a37cf0552de2ced455fbb8a76d969cd97b3e4601d8a808bd2a73f7729ed8a61df2f2a0c2cee1425d0bd9ab4","up":true,"one":"6ad4ea3730ddec500e56248d1025aea79ec10f0d6a9720ee48026df10e219b41965d7a611fd99ee765f6afbc8c977db7e67c3a340881904acb983d1e2fb016cc"},{"up":true,"other":"431644cf162bc267237c4e798288888dd835c1b0546b0cc679782e33568988d75b4294f4aa08359a6b152ed9a0fbd13133681156bcf09a871c4f362615ea6dae","one":"20f6a8be1d2d8b5d6a43d851a2f5475385ef07fab80ac46525d0beccf3e25c01d726cfb3a1179e8343b1e88d21684fb24dd6e6497537d4e7e9edd59cb95d1b8d"},{"one":"c0bec7375c66bec98524ade2245c1d7480516fc5d87a3249e64ec86418e80e202f1e3da76832e97bbc3dcaed8c96ca344e4829347b4428f4b1cb61999e404c05","up":true,"other":"9bea5f82c2a390587de44d620d6637834e6f2329cd83d8df6305b03b75d9b543160b6c6f9f8887e6bc88f1d0726435d6c8ad813aadad0653b0790b8f6388413a"},{"one":"77e40e42f570a217f707888c714deb31fd70c856ae4b9a44ec7cee02768185dc4d7ed210429607f06690b32edd9fb06b304aff330a3949cc2fd49db1bc392edb","up":true,"other":"49215dfa786bfaa52b1e7aa6899392711a770b2504c82f536381fb1f18df16960257d75530efabf6dbd2b1361decc29758f870b318f777decf51f4833a9c1f00"},{"up":true,"other":"b4557089e4247379e587a087f53b36dd1f86f85d9dcfab5dc562079978cd959adaef5b30d11258d9cb552e7c5abddf5377a71d449febe8f2acb0aec3ebd8ba73","one":"362ed9a92b588d5fe315b90a74aa27f7600e4a7d06b27ceb26272340388d916a831df85bf83450ef80bda4e4a21acaac60560c8a42940a26e2ac567519e2a202"},{"up":true,"other":"431644cf162bc267237c4e798288888dd835c1b0546b0cc679782e33568988d75b4294f4aa08359a6b152ed9a0fbd13133681156bcf09a871c4f362615ea6dae","one":"10551c0c37abc25457903978868dd4843a52fda5f9b571b05ebd974d8c381fda4349f17c2b986a2e4b8d06b0517422f085d5f6d9cd814efa40e48393d9f71d7e"},{"up":true,"other":"e0875ed6be1e163b15c13cdf37442f838670d0949349ee9ff119a0451beffb1a302943ee9d7cba48592922f64908aeb0f39f6e2e3725d1e7cdc5db34083b6977","one":"842f0ac24370f14edfe72a7d07219de60fc767d2d0356fa6ce9d535a43647ad4bb17d9be75ed83542868ba430ec104ba168f27c16915cdbd6e57ae62d60707cb"},{"other":"51a570637394e9ab61fe95b3a608cc4e9dc8ceb63efe717938ccd4260a962d52e01b30e7034fbfdabd9a3c9616ee569550b38a6d6b4b19847f523254069a9f27","up":true,"one":"4116fbb7d55bfd4bd8db9cbfa570ac361bb88605b6aacbf84e245893cf3fa599ecc086688a4c534c81f61a90fa344ca37e4d4013ddc03f7f08218724a55f66b1"},{"one":"202ae63076a5560418023f00c9965b2a1d12de932b5371ae270d63db88551a7aa1a3c48841f81948fad3435bb4a7e3e165a2eced9fd937444e4502471e23dae8","up":true,"other":"70cce7cb0c18091dbb6d41160ab560935f1759b969bf8118cee030ee707cb15ba407b8c48dcd9fd012cbf778e219f7d16a74064b4983cf098fb118297748edb6"},{"up":true,"other":"5a235aca7005df295d5bd924b1272452e9bdad408ca5223b9eb76800b4bd4e3158a1d663ce5243fee92233227249fe4bb8507e8cb2c3729744b273bf488ba60c","one":"ecd217e8bdb53c9ef085929b8c2d2b40425a4be617a087b8e7f88e8507b3c981e90fda2119744ca394fe65bd4eb1cdd3fa7258db936048e236d2f15ee91bc3b6"},{"one":"4e88cc60efee147fb72a735775944c7b2ba0790e2b2b935b4b3c2da9a3158a2a7aae411e9204cdbe6b2304d90a3a8278f8bb1a800a409e8500d100d84ba1947f","up":true,"other":"bab07c2e4dc09add884869b31fb474b6d7151f9cc331d831f55c2b088397370fb0a1e1592c8dff9c8bc8e83de9faf6e91683acfb2df1b41856d70e523a99d370"},{"one":"dd3dccc1758765569905b3b137ef4c7dd31c2dc0dea827bcc4c4e976be94ffbb0f2ef6fe725cf9042063a96d663efea546837f35ca1fc67a854fbc9e27abb754","other":"228b3646b15527f4df07b847a62dbf9620cb068f829e9086b5f437d0b64d8a027cab44f19db5e44189b5099545ecb25d49384c261748f9533cfb0eb11a1eca5f","up":true},{"other":"e0a043f98b462f10f72aa61ceda52f9c27829d086f6f2c5bf4db4fe32759002e5ff9519495d57dbb83d963a1dc991a1defcf5b9ef0d543789f38c68f5d07122b","up":true,"one":"8e8614a4c2ee2b1a3fa5ace0ca353cff36b3de3308ccf53665b8b56f8e2456a8a65f3846d786dccd68b1bfcefdd170ea5f8edb481800b1ce72d9fce2added7f0"},{"up":true,"other":"48e35d67e14ee2f329c0275bc965829b761885dbc3671f4673d84d76d18a5b6415e619e219b5d90761a5c6bd2f43c6a58708286a063daf46b502944f8ef9230b","one":"6909a0fa47718cfc463b1e96c21734b46bd5b28dd59cd3d66d67990783436b7538ab2659d427029b97c8dddf313b26532518c0c34a2b1fca8cd852b0fdb83ab8"},{"one":"da22fb43c6d230d92f9c09454e282dc45dffc759740566039f1bdfb58171c6801f721841de83217277b3fb70983e7d34da53bbf25d1d45413a78d9afff151826","other":"fee3fa1ba2a051d40a582908384ee81179db6c2b5f4bfa58c24f8015b794b43a093ed68b69bb209684135f972a055a9845978fa1b7d489e2126c3b514297f1c2","up":true},{"one":"3f322f9b1f1f0692663bc3be11cf11386f4a14696aab610916cfcadf0234cce0c86b51c85ce2108e9bc21d50ad71cc10a6eeaec3fc7732908f3a8b193465a0ac","other":"2cb076669efbaf2ff0b181a1b454061a31ef23937a40405022b126f0eb4bfba60c9e3397009d8c0ff0cabb603692532d0072c18c6838f43397c98483306f62db","up":true},{"one":"212a8048ab9925171475e81dce047865df186222d673d524c810a9f613e4a21f3b130fa34c5f44974fbeaab1f6028177e71568e00a1184d9fd05443c172f5fcf","other":"93073da602d6326a48464a8b6890220b3aae0abf5b6961180f3aff2a14573c43411bd519d3e0012a646ec2977be18915d95a36d935a69f93985f5307ea4e3ebe","up":true},{"one":"588df3185f63a5443d8c6b972f67805f0557184d916005f537a4b27cd02bd6a12e432a2b34b234a34f22e923c6f116da85be20bad77a2bf69913684e9d0732ba","up":true,"other":"4ff2981a47da46c753090e193a8bf43c3372a6b07a37cf0552de2ced455fbb8a76d969cd97b3e4601d8a808bd2a73f7729ed8a61df2f2a0c2cee1425d0bd9ab4"},{"one":"624248a794fd62248024360f128b2e503c752340694a316bed420e5ed2cebeb5bf970df95a2806732237a26de3778222b0454e2e7d2875129b193e7890fd5b95","other":"da22fb43c6d230d92f9c09454e282dc45dffc759740566039f1bdfb58171c6801f721841de83217277b3fb70983e7d34da53bbf25d1d45413a78d9afff151826","up":true},{"other":"c0bec7375c66bec98524ade2245c1d7480516fc5d87a3249e64ec86418e80e202f1e3da76832e97bbc3dcaed8c96ca344e4829347b4428f4b1cb61999e404c05","up":true,"one":"3376cfc924fef1a45aae35d106439b131f363b3a42904b3974cc7cddde325441cce8551729dd62f1119120b0d452e78f063e8e711ecacdc27d9087aac5ab09b5"},{"one":"5717a49591a0ecdff3d4449874d5ff9ba016afad5da19712ca0c8ebca8cefd84e6d8c778245f67f68c8dd730ad294fd017b8de279fde4fc919768ce85dba132d","up":true,"other":"48e35d67e14ee2f329c0275bc965829b761885dbc3671f4673d84d76d18a5b6415e619e219b5d90761a5c6bd2f43c6a58708286a063daf46b502944f8ef9230b"},{"other":"362ed9a92b588d5fe315b90a74aa27f7600e4a7d06b27ceb26272340388d916a831df85bf83450ef80bda4e4a21acaac60560c8a42940a26e2ac567519e2a202","up":true,"one":"99a7649bdf2ee7f0bc049308b0997e33abb68481c05a573df9aea30da5a1f267df07b2c584e3e985baf31704f04ad2a2c4876e0f8555333be6d09f5080b583f1"},{"up":true,"other":"f60755ee9464c7db769bb7237016fa165441d18ac3bfed7cd2a220a9bcbead202dd34eaf2f9398a3d36bdfc2671bbd46ac25ebe264a8118afe1b7d0bd38710f4","one":"aa2028d356a88eca8e0fcaf218d62ace099c3f72dfd95bb28f30ac9a926034cf1d60a40511f7495652745de80d71c0f6830019e206c88e2b6ef0cf4f05d7fe9e"},{"one":"33e9d4674b5b9b23e838583f01b429abca1330393dfc100b19ede6090a53df213011fae53169a66aa05d18e4cb497a17aa81eaedf1fe2e4348f9825c309438b5","up":true,"other":"7dd2801259c071a6e1dcc01d1cb74775fdec92da1da0b1eaf5f893cd5ed118894493ca5284c12bbd6cf7959449bc610d26ac6c9ef2845d1645d425f56ac003fd"},{"up":true,"other":"f52297fc51b920d2495ccece290432656d9388e698339c8c1279ceea45de698a4ecbda1d25928c48f1e19e9dacd3147e23ef01acc093872d7300aed187841dcc","one":"fee3fa1ba2a051d40a582908384ee81179db6c2b5f4bfa58c24f8015b794b43a093ed68b69bb209684135f972a055a9845978fa1b7d489e2126c3b514297f1c2"},{"one":"c63b88f494b14d5a7c1da124ffebbd985d19806b91d4b111c83ae129c4ef19614469980a09fbeccebe3b0358dd16194bdb6452d0b3dbb43a5467e23bb13f40d6","up":true,"other":"362ed9a92b588d5fe315b90a74aa27f7600e4a7d06b27ceb26272340388d916a831df85bf83450ef80bda4e4a21acaac60560c8a42940a26e2ac567519e2a202"},{"other":"624248a794fd62248024360f128b2e503c752340694a316bed420e5ed2cebeb5bf970df95a2806732237a26de3778222b0454e2e7d2875129b193e7890fd5b95","up":true,"one":"eb58e478b16056e0af344397cf5f078a3312a6db2189ec2042ec06ab6550e3ee71ebcfeff1814332c552c12a5a488f96b3f2935e90a189d238da19d30a2c9874"},{"other":"b9c7b885430b9b1a4425bde30b3629559f5437e0e30a0299fc6f6e097cbcca8af9e285caf5dea685a0237f60e06f490c39a1e3e487f14a2b9f41a5135f2ba994","up":true,"one":"ecb93d8eba17afe92979e8154252a08dd58de6ff3188b6829e3e25967846686f54199ab2b081e77b0048dcab204f05aa2c5cbd0efae4bc43a612d471d4e1197b"},{"other":"d09104c44648391693ca64a57baa5ef54ed717e19c65ad0a0921d08cbaca8877d0190795d15f75f3b6ce6e676d6b0e55d5ee8fec3310c68b7060a32f7ff649cb","up":true,"one":"ab1a3542d67ef9d1a63653990bf0782f53b0169fe5092adc92fa7aeb38f66c6b62d49e3455cc2ac4994bfcfb03111953acf4cc3099026672cc61f6e24cb3ae00"},{"one":"2cb076669efbaf2ff0b181a1b454061a31ef23937a40405022b126f0eb4bfba60c9e3397009d8c0ff0cabb603692532d0072c18c6838f43397c98483306f62db","up":true,"other":"5d002c37b74a6656db86f102b0cec82bc35a819a480e5a2952db0140ebab65dffeb1a79f04d53ff61447b5fad7c58cb75ea1c91ea47fcb9e024f27b92c6c874d"},{"other":"2cb076669efbaf2ff0b181a1b454061a31ef23937a40405022b126f0eb4bfba60c9e3397009d8c0ff0cabb603692532d0072c18c6838f43397c98483306f62db","up":true,"one":"f60755ee9464c7db769bb7237016fa165441d18ac3bfed7cd2a220a9bcbead202dd34eaf2f9398a3d36bdfc2671bbd46ac25ebe264a8118afe1b7d0bd38710f4"},{"one":"48e35d67e14ee2f329c0275bc965829b761885dbc3671f4673d84d76d18a5b6415e619e219b5d90761a5c6bd2f43c6a58708286a063daf46b502944f8ef9230b","other":"bab07c2e4dc09add884869b31fb474b6d7151f9cc331d831f55c2b088397370fb0a1e1592c8dff9c8bc8e83de9faf6e91683acfb2df1b41856d70e523a99d370","up":true},{"one":"b87e7f36ed6bf142d48545024d2fd6e120c44511701e7c0b7d7fc786f4f29d3357024b15f70b78215d8a4c2b7572d608c11b31612743e23db4fa673f0cd6519b","up":true,"other":"f5d95e0c5a873ff5a95e1eb34f1ed258d77adf98ee0886d93c4a24b1feaf6955e6e4c4ea0eccb2b9723870bae61e693643d6ad96dd8da01672542611f7c49069"},{"one":"df9306a263f40e0e255996500523354de3cc78b68ae560f66d79f6ea28f30f773f1fd6ebc33928723dfde2ee3d4f982b203bee4c3803a5050df83477045bb279","up":true,"other":"c03ef1de42d522b44eef53be11f2c57b8b74fed9e87e6c2928c1feb48ddfecc67e1a3a8c8be1c47b3735a216d7054e2a4dda49fbd9a1ac702146aae5bdeced7c"},{"other":"9c8f156797deff649d74d56fc42b4bb1a87312089114d4350424c375837d9c8068dd09af01c1c973d12ec5d7e8da600cd685cae70d3116b9dbda823092e03fff","up":true,"one":"9f3af4577308965aceb7e0101443669496e7ccf1de680629862a7005966c708b6fb52e6dfe62660246b9892adc25838da2873502e0be706bcad8f25b7ceedfa5"},{"other":"2b0a1f3a6466c6be1d7e84120db384fa37f7c73a01e9a105ae90e7d2203212ec974f016d3012afd26bc0f9a8411d0716cc59b6ecc9f665db12e306af8b34cb63","up":true,"one":"c0f233e79d0a8d4af01f54c40640975bc113f464271ba8922fca0c28acc60367af0db06629e701977e86cb5917c891e39c21418cab459fe49132b680aa31600b"},{"one":"51a570637394e9ab61fe95b3a608cc4e9dc8ceb63efe717938ccd4260a962d52e01b30e7034fbfdabd9a3c9616ee569550b38a6d6b4b19847f523254069a9f27","up":true,"other":"eb6d41d8d96f1933dff017d5fa0c46c6d0bad5d273b7c321a12858ac90ec00fca6191d29419897d2e25ec2d8ebd8c6a81bbde2d3f266f842e64b2b822161f1ea"},{"up":true,"other":"77e40e42f570a217f707888c714deb31fd70c856ae4b9a44ec7cee02768185dc4d7ed210429607f06690b32edd9fb06b304aff330a3949cc2fd49db1bc392edb","one":"8e8614a4c2ee2b1a3fa5ace0ca353cff36b3de3308ccf53665b8b56f8e2456a8a65f3846d786dccd68b1bfcefdd170ea5f8edb481800b1ce72d9fce2added7f0"},{"one":"6c40910f0556f892a7542989fa01d7e3682fca89aeefb5ed885808f88ff17b6d13862f461c10d629a005ae67abef542d75e5b20816891b6944f71560f5c2dfa8","up":true,"other":"a8fac88fba179fb9b259d94caac9cbe45d873a0131bef8844ac4383b177daf6f301f8793623fec5876885db1a91e5b3e98e2aafdaa47e03b1f6d9740f48af7ac"},{"other":"6909a0fa47718cfc463b1e96c21734b46bd5b28dd59cd3d66d67990783436b7538ab2659d427029b97c8dddf313b26532518c0c34a2b1fca8cd852b0fdb83ab8","up":true,"one":"6ad4ea3730ddec500e56248d1025aea79ec10f0d6a9720ee48026df10e219b41965d7a611fd99ee765f6afbc8c977db7e67c3a340881904acb983d1e2fb016cc"},{"one":"228b3646b15527f4df07b847a62dbf9620cb068f829e9086b5f437d0b64d8a027cab44f19db5e44189b5099545ecb25d49384c261748f9533cfb0eb11a1eca5f","other":"7d9979c13cd8841e84e5d199fc263962ca6fee12664d8526a581bfcdca2e3427ca169b9a0244dd8292a9a1be2bcedb0e8f626eadd307068c11c03b6df13aee33","up":true},{"one":"a58a4db7a96b1578935b222c78b7b4dd8b3519d2995c3616e5a154c5175242a503097771332504638a0b321b9574110207f9a7d77b109d1de3d66a12ec6498e5","other":"9c8f156797deff649d74d56fc42b4bb1a87312089114d4350424c375837d9c8068dd09af01c1c973d12ec5d7e8da600cd685cae70d3116b9dbda823092e03fff","up":true},{"one":"e1f23e1caba66f5ff821edbc4a3d527539937f73d86dd0df43aa1266a99f51f2480a77961eff177fbbf852fc52cb9317179f80b1580194daaedadc3b00510751","other":"10551c0c37abc25457903978868dd4843a52fda5f9b571b05ebd974d8c381fda4349f17c2b986a2e4b8d06b0517422f085d5f6d9cd814efa40e48393d9f71d7e","up":true},{"up":true,"other":"c0f233e79d0a8d4af01f54c40640975bc113f464271ba8922fca0c28acc60367af0db06629e701977e86cb5917c891e39c21418cab459fe49132b680aa31600b","one":"57085f756f76644cdd2148524f2334d869ef0ab2fcbe7fb11f5d22bc1f5023165b11526ecc85ff9cbb88877386af9b148d7ef15a825b3a586d16c01bdfc86692"},{"other":"865dbf61d8511603fe0d9ebfb10792b9f6b798187c0909039bd9b2492c41e428876f386beeac86d0dea871f4fc24ba435f0fbd9a11e74c044024934592af14ee","up":true,"one":"49256eccce3e036928a4b6b346126c6777dca5ea0134de85efca340f97ad0f827f3094f1562e3e186d35b8292a50c20ffae01409890bbb78598494285e14dc2c"},{"other":"0c82c4b414375479375703ed9c19fb08c8143229ed4f1dcf448c6cf313810c098905123bec17969276936ae0cc39ed251b2811dbffb551d61159862b0eac0a23","up":true,"one":"a8fac88fba179fb9b259d94caac9cbe45d873a0131bef8844ac4383b177daf6f301f8793623fec5876885db1a91e5b3e98e2aafdaa47e03b1f6d9740f48af7ac"},{"up":true,"other":"d43bd6d3ae39a04e4e144a8a6f80b2d54472b5b9b6491dccf44b1716a63d24c56e3a871b3b8fe983d992988dc07ace06736ead3b1287914b629fcfe17e81f36f","one":"877d17ec7e95998ead831606d3363fbff1c8d1fa377b8e621e6a876d2c7776b9af356211a7e4df66adeaf38cf9b49c04871e8804edde4c18435ff45e110ecb04"},{"one":"e8a679f627d03347a4fcec0a0940f7ffa90ce3fefea290db3af4f3a32d27965bfb51832b6a6de2495c8a8cc026bcf993b84a0cced778e158bb81c034f5e4bd76","up":true,"other":"6ad4ea3730ddec500e56248d1025aea79ec10f0d6a9720ee48026df10e219b41965d7a611fd99ee765f6afbc8c977db7e67c3a340881904acb983d1e2fb016cc"},{"one":"2751df9f64a8f2ff8ea45efc9bd02b281d963ced285260bcda7f9dfaed998fe4386fe65a7265876da6b4fee77ea5c12454869a70ad627da7ca888076fc629665","other":"3948a7a939b9a1f4201953bd9b955ee7be87d09b63c7a45167f556ac06fe3c4c2a75d935bff50668da5e71e46802b55d7a9945a92d7807c00625d129cbb48f82","up":true},{"up":true,"other":"8ee65c0937cdf860d5329132c34bf28b5dc4d2593986fae80e4b35efb54ec24cdbf294223515363a917a22dbc6db463c10c7484e22b479b9010059c2521b6317","one":"52cf04f88d8b00214f11f329ebacca69291958372aa8ccfbe3cfdbc03d51d90389f3c307b82c108f0c074d78aeac0b48e8b8c8f3bf3b20b21d9747f284075de2"},{"one":"2bea7540c99456ea889a8ba2e448c11e6257bf987d01f13eea48128ba58577ab0936855035ee140c9907e382a34ca85a179c74892cbd9eb92fc2b35601addc6b","other":"95ff4dea07303e1ba641a5c510e714ef232f4dbce9ad2e8b2f62644975eae41fc4bb9d1af3fae4d5ea4daeb18f8248e0b3131c7d843d35d33f3afbf7dfa4c2fe","up":true},{"one":"e5cb29b25debcfaaacc0b04e708c8c1cb9d2dee29e82596a1c72a934032cf738800b9525cc277d0c5f5dacf2f278329b54da161b4bafa285243fa0e9fd7b2f3a","other":"d43bd6d3ae39a04e4e144a8a6f80b2d54472b5b9b6491dccf44b1716a63d24c56e3a871b3b8fe983d992988dc07ace06736ead3b1287914b629fcfe17e81f36f","up":true},{"other":"95ff4dea07303e1ba641a5c510e714ef232f4dbce9ad2e8b2f62644975eae41fc4bb9d1af3fae4d5ea4daeb18f8248e0b3131c7d843d35d33f3afbf7dfa4c2fe","up":true,"one":"be93fafaf43f6bb3efd2667d1468a8636cb752b245328eaa01468c0606d790322a7cd8e47857068e60118e28b8dd8aa1d2d4977c5b3d28d4b47f4c0658f05e90"},{"other":"b4f300abda4cf6e383f997510eb681e9fa62e23577e3c19bd7447fa1f5702a4e034cea5944248e7c6e6e92b5ae69195c3e8a2c5ca7827b4f4a00cc8546e6695a","up":true,"one":"50c79baa3e6781482ccb5e960c699dd9c13f479467c6315c5292a396337cf3619e7faba1971a1f470051cb9042f80ea6750defe3936b72aac4d9bac6f8368c67"},{"one":"96cd4caa32c0b3a3493e24e13fad1ef75c621005d74154c3fc8a73cca4c0120452b6432334d94849c63f75d56a2943a453c86d2a14ad1fb61ae6833e58451187","other":"2cb076669efbaf2ff0b181a1b454061a31ef23937a40405022b126f0eb4bfba60c9e3397009d8c0ff0cabb603692532d0072c18c6838f43397c98483306f62db","up":true},{"up":true,"other":"f60755ee9464c7db769bb7237016fa165441d18ac3bfed7cd2a220a9bcbead202dd34eaf2f9398a3d36bdfc2671bbd46ac25ebe264a8118afe1b7d0bd38710f4","one":"96cd4caa32c0b3a3493e24e13fad1ef75c621005d74154c3fc8a73cca4c0120452b6432334d94849c63f75d56a2943a453c86d2a14ad1fb61ae6833e58451187"},{"one":"ef7157fdfe62390d8a6d4ef976478d17465b42b63fddb03664973d63efb62318a8f59e412150528a32aa2c028b9de6bc67f05e012b8c43d710032ad871bc27e5","up":true,"other":"b60def37233dbbc0d5f7fcddb304be1c0b6508e1e3d8a09a8290f7363e9bb84152dcaf70b8f6bb3a882fee77ff03ab796a5c1c3654f251c9f5c746ac5ad88556"},{"one":"d43bd6d3ae39a04e4e144a8a6f80b2d54472b5b9b6491dccf44b1716a63d24c56e3a871b3b8fe983d992988dc07ace06736ead3b1287914b629fcfe17e81f36f","other":"06aab75fed9a03f5525e3f1d8f8997fefaefd5b16e8f485d571beda00b1741efbb61a8a74fa12c2f6de66227c3fabb4d411659cd9c7b1ef32e171e6bf517cc39","up":true},{"up":true,"other":"4ff2981a47da46c753090e193a8bf43c3372a6b07a37cf0552de2ced455fbb8a76d969cd97b3e4601d8a808bd2a73f7729ed8a61df2f2a0c2cee1425d0bd9ab4","one":"c61ffc88f23f9f536497cc10ffcb7000ec6c4b801998ae7075ddc9079fdc1da8350e68744dc9e95ff892dfc5e52c62a3ad913a87fdacc455aea99b09aa002b57"},{"other":"eb6d41d8d96f1933dff017d5fa0c46c6d0bad5d273b7c321a12858ac90ec00fca6191d29419897d2e25ec2d8ebd8c6a81bbde2d3f266f842e64b2b822161f1ea","up":true,"one":"f6a12b23423c047927a3024a6dba7ce88927cb21d4df3778bc5ebb262cc403261c79ba6d9bda07f1852c009d803a77f429e9e48ec1d63cae98256e529d45b276"},{"one":"936fad959da2d8b0cfb2bcd78c5da65bcce5e9463be7fc7367f45cdfa20678f4c466fb1e3f600783a270855fd4b9cd6265054f79ecb116141e7c67a492041bed","other":"8e89fe4b3fffea8af247d2581aa511056efbeb796058d50a341d57aa0f7ccc2192d90cfb8d18558363df798567faaddb86815e8bd671b36ca37af0651535aabf","up":true},{"one":"a070b5cff5eff533a2267ceb0d88e221088038af773e18f80110c8a2c329f0543b8d43c4e6132e9416723e3e94c87f0053456760ced4426767b95cee36ed93f8","other":"46717bc5fb7fcbcdc961e7ef091020f9f222858cf3d4afcc0b0bb1b782b7055d9eb833e0a04cb32d80406133ac77162521c43edf9f9690872222760e31462ccc","up":true},{"one":"3e2241cdb9f34c1d2c6930e59940e2c4b92b0287579d7263a620a609c5e66dca6d85df48cf1bffd63663a6704c42d0866aae3e484fd9a44b6a012f72dd3cef6e","other":"869cae165389e7dee7b7df4e012ee1a39737366c306d8f4b0db4510b2236e0bd3a4d1d4af00b1a8c1d360e23da47de52fc1632edb03c7f1429aacc8aa4994750","up":true},{"up":true,"other":"5d002c37b74a6656db86f102b0cec82bc35a819a480e5a2952db0140ebab65dffeb1a79f04d53ff61447b5fad7c58cb75ea1c91ea47fcb9e024f27b92c6c874d","one":"a070b5cff5eff533a2267ceb0d88e221088038af773e18f80110c8a2c329f0543b8d43c4e6132e9416723e3e94c87f0053456760ced4426767b95cee36ed93f8"},{"one":"2abb91884cc3a8fb91b2f2f369f9430f2b3b05c75ce6203aa7a50312c9f141f9d0f615063d3576a5ce8a4be9ecb942aa804a717f76d9e8dca03d115dcc43f775","up":true,"other":"869cae165389e7dee7b7df4e012ee1a39737366c306d8f4b0db4510b2236e0bd3a4d1d4af00b1a8c1d360e23da47de52fc1632edb03c7f1429aacc8aa4994750"},{"other":"96cd4caa32c0b3a3493e24e13fad1ef75c621005d74154c3fc8a73cca4c0120452b6432334d94849c63f75d56a2943a453c86d2a14ad1fb61ae6833e58451187","up":true,"one":"bdd17545242bedba1e4c36fadea95db655f8f220f10ae143084690a3c8d4e7ffb79a64af9f1bc8514addbd63695b2f20857e8d162f25318faac885f77b385138"},{"other":"90b8e73916046b5433dce049bfe125ca2bf2fb390ff7301f9bc5d8d0183988577aa2a7392aaa28091aa81c8ac23942b5751420b9ee48e488a68411f9d2b1e5d5","up":true,"one":"17ae0b24297a3e6e027884e5e4529b6646ae340f5736eebc6187a9b59832a445f3644172d92438351e3803e56a67472b29f3e1d48844ae2e11e5e6670eed1436"},{"one":"224c3b969149d50d1bb4f473bb9725223c1dafe152efe1b08e8859213c543a66565b5d68a99cef3d5f4eccad6282a12f78d7b38eec14deebf44ad8dd9cba8680","up":true,"other":"b9c7b885430b9b1a4425bde30b3629559f5437e0e30a0299fc6f6e097cbcca8af9e285caf5dea685a0237f60e06f490c39a1e3e487f14a2b9f41a5135f2ba994"},{"other":"eb6d41d8d96f1933dff017d5fa0c46c6d0bad5d273b7c321a12858ac90ec00fca6191d29419897d2e25ec2d8ebd8c6a81bbde2d3f266f842e64b2b822161f1ea","up":true,"one":"60995852a2385ce8d7d24dc94b85a2f0dab6e5c32e910dfe367ea9c6ccb7b0b2eb611fdf120f8c697097e2f137cefff42e8d9db16b664a857a38c5ace837ffa4"},{"other":"69f999937943be00e5fca5c7cc942ce13b6752a72813368da2fbfcf74ad807bc6edd85537e087b6f73c0469c7b76a5d8f7d883bd315f3b35af32b8da293ed243","up":true,"one":"e0f13606a7f35b9ad8a9c4e70336c4c554ac718720a451a349eb4e1a4b055079483cac040ec64e0ed3d8bdb336618a5ae6ef74e31642fae4d7ed9949858eb361"},{"one":"f6a12b23423c047927a3024a6dba7ce88927cb21d4df3778bc5ebb262cc403261c79ba6d9bda07f1852c009d803a77f429e9e48ec1d63cae98256e529d45b276","up":true,"other":"24047e1a816cbf9b7a90e6c78dc896a3b624047ef5cfd3aa495132d57b1074aa129ea6eff171f5cca91d0f4793a07c9672b0a55232f2415c6220e443ebd0791d"},{"up":true,"other":"624248a794fd62248024360f128b2e503c752340694a316bed420e5ed2cebeb5bf970df95a2806732237a26de3778222b0454e2e7d2875129b193e7890fd5b95","one":"535287ca3d41fc1cdf20a964749a849c51d0aba285f41f447cc2b1dd6f5845b6b98e0241dbda0718b234ea850081bfbf9df01d1aa636d7dcbd99ef3c0a773aff"},{"one":"9d372d73848389cfa1676f0cdb030950980ed5b68d5b2ef8a058f1d2095b26ff0fafab5fd3c243296ee2620edc67752970ab47370270856287f8612d1b190a19","up":true,"other":"2cb076669efbaf2ff0b181a1b454061a31ef23937a40405022b126f0eb4bfba60c9e3397009d8c0ff0cabb603692532d0072c18c6838f43397c98483306f62db"},{"up":true,"other":"b1dd1b08975319030626aab821032a0c687a103ee8942e8a2e2cf029dd72832a49630e78d2d8b184579f22178aca0e875f9fad701fb81afd2ac110ab2b417376","one":"0c9a05514b96e7c3a0fbca21552e158faa70047246b230addca172a5023fd7439acd1c3a0b4f9191579b308dab38c961734ffdb36fb8e16383e912d070fc0218"},{"one":"f8a5ae50e5b2d84096c10a6a8493a9eb8113df64c4f1336c0cf4649302649b158fa4cb7941591e55356891bcc1008a535df427546af19988a241c5f466467963","other":"ab8eda9b360d3e0b002ba31d48311057880844b828ad9817a2ad19736860d0114d4a17e9e9427c842d52e7ff61a09c2cad9b70f506e338909535542dae38ede0","up":true},{"other":"2cb076669efbaf2ff0b181a1b454061a31ef23937a40405022b126f0eb4bfba60c9e3397009d8c0ff0cabb603692532d0072c18c6838f43397c98483306f62db","up":true,"one":"c0a2c08fa8b70ecbf1932254945d5f689b0da7a287019d384152f383f6229acd4d82eef26205bc12e062dae4569814bd1c996ee4fe5886bd6bdd93c4f0ac113a"},{"one":"c0a2c08fa8b70ecbf1932254945d5f689b0da7a287019d384152f383f6229acd4d82eef26205bc12e062dae4569814bd1c996ee4fe5886bd6bdd93c4f0ac113a","up":true,"other":"3f322f9b1f1f0692663bc3be11cf11386f4a14696aab610916cfcadf0234cce0c86b51c85ce2108e9bc21d50ad71cc10a6eeaec3fc7732908f3a8b193465a0ac"},{"up":true,"other":"0c82c4b414375479375703ed9c19fb08c8143229ed4f1dcf448c6cf313810c098905123bec17969276936ae0cc39ed251b2811dbffb551d61159862b0eac0a23","one":"2880e0defd1bf2665bdd20dfb46bc0a9ad707f495211fc78e611ab479d78398db7daff7d3f4b6bf81fd13bf766ecc8271e0ea99a2d74abd2f9ddf98835ffdcf1"},{"one":"fc9b1b2bbd5e682eb350d23f3ee33b245495daedae9370de7b1f55f91cd45db831d196c17615e11decf6b67696a268ac788130e3de38c7f6aeae811f3ec8c8ee","other":"c0a2c08fa8b70ecbf1932254945d5f689b0da7a287019d384152f383f6229acd4d82eef26205bc12e062dae4569814bd1c996ee4fe5886bd6bdd93c4f0ac113a","up":true},{"one":"52cf04f88d8b00214f11f329ebacca69291958372aa8ccfbe3cfdbc03d51d90389f3c307b82c108f0c074d78aeac0b48e8b8c8f3bf3b20b21d9747f284075de2","up":true,"other":"6909a0fa47718cfc463b1e96c21734b46bd5b28dd59cd3d66d67990783436b7538ab2659d427029b97c8dddf313b26532518c0c34a2b1fca8cd852b0fdb83ab8"},{"one":"d09104c44648391693ca64a57baa5ef54ed717e19c65ad0a0921d08cbaca8877d0190795d15f75f3b6ce6e676d6b0e55d5ee8fec3310c68b7060a32f7ff649cb","up":true,"other":"e903d7aebff96a6afa4b9dd19b0b02e5af18da8e4e89f64247e1a2c2d46637538c741182eac67f45ec61be76aeaccde57f0a0184bd608ea7d92e586d4f827ea7"},{"one":"4ff2981a47da46c753090e193a8bf43c3372a6b07a37cf0552de2ced455fbb8a76d969cd97b3e4601d8a808bd2a73f7729ed8a61df2f2a0c2cee1425d0bd9ab4","other":"52cf04f88d8b00214f11f329ebacca69291958372aa8ccfbe3cfdbc03d51d90389f3c307b82c108f0c074d78aeac0b48e8b8c8f3bf3b20b21d9747f284075de2","up":true},{"other":"5d002c37b74a6656db86f102b0cec82bc35a819a480e5a2952db0140ebab65dffeb1a79f04d53ff61447b5fad7c58cb75ea1c91ea47fcb9e024f27b92c6c874d","up":true,"one":"3f322f9b1f1f0692663bc3be11cf11386f4a14696aab610916cfcadf0234cce0c86b51c85ce2108e9bc21d50ad71cc10a6eeaec3fc7732908f3a8b193465a0ac"},{"one":"228b3646b15527f4df07b847a62dbf9620cb068f829e9086b5f437d0b64d8a027cab44f19db5e44189b5099545ecb25d49384c261748f9533cfb0eb11a1eca5f","up":true,"other":"5a235aca7005df295d5bd924b1272452e9bdad408ca5223b9eb76800b4bd4e3158a1d663ce5243fee92233227249fe4bb8507e8cb2c3729744b273bf488ba60c"},{"other":"aa90454031068598ee39af5f1429c7a72277946d50ec2004f340406dbcc9f80cac505c9d9b071f85e2ccfd4b13bcf943f3cb9dd9f96f62d41352af9d8fffe7e4","up":true,"one":"9bdacc256acef0433805477d38f32be849a8846d88cb883b19d290454639b42c6ab6c5c52d4f83453e8a156af7d85f606458aa9c0977c67282f56f34ff0acbfb"},{"other":"7d9979c13cd8841e84e5d199fc263962ca6fee12664d8526a581bfcdca2e3427ca169b9a0244dd8292a9a1be2bcedb0e8f626eadd307068c11c03b6df13aee33","up":true,"one":"ecd217e8bdb53c9ef085929b8c2d2b40425a4be617a087b8e7f88e8507b3c981e90fda2119744ca394fe65bd4eb1cdd3fa7258db936048e236d2f15ee91bc3b6"},{"up":true,"other":"682288e4dae2374c4784acd0b285508920ce39a6b72cc0e30a3dbb7972e0394a2bddd5ee5f22a1dbf80f284dde4d9f8ede7847318d5353566b35a83e212477e7","one":"60995852a2385ce8d7d24dc94b85a2f0dab6e5c32e910dfe367ea9c6ccb7b0b2eb611fdf120f8c697097e2f137cefff42e8d9db16b664a857a38c5ace837ffa4"},{"one":"dd6acfd151220f21b03701ca554a5e134dbd1154dda21d9eec45809e7858fe83eca3953fc688f499030198f22052c3681a9f49207ef9b11a760456ab9637352b","up":true,"other":"228b3646b15527f4df07b847a62dbf9620cb068f829e9086b5f437d0b64d8a027cab44f19db5e44189b5099545ecb25d49384c261748f9533cfb0eb11a1eca5f"},{"up":true,"other":"2880e0defd1bf2665bdd20dfb46bc0a9ad707f495211fc78e611ab479d78398db7daff7d3f4b6bf81fd13bf766ecc8271e0ea99a2d74abd2f9ddf98835ffdcf1","one":"81dc656de121016bcde81d5bf7919839acfc180dfbf1a6de2cadf704ff13af98aa5715a4168832ca6f651b2ea7ad9e6ca5f1c1cb7e885dbc2eb23d4aefb87bd6"},{"other":"877d17ec7e95998ead831606d3363fbff1c8d1fa377b8e621e6a876d2c7776b9af356211a7e4df66adeaf38cf9b49c04871e8804edde4c18435ff45e110ecb04","up":true,"one":"81dc656de121016bcde81d5bf7919839acfc180dfbf1a6de2cadf704ff13af98aa5715a4168832ca6f651b2ea7ad9e6ca5f1c1cb7e885dbc2eb23d4aefb87bd6"},{"one":"682288e4dae2374c4784acd0b285508920ce39a6b72cc0e30a3dbb7972e0394a2bddd5ee5f22a1dbf80f284dde4d9f8ede7847318d5353566b35a83e212477e7","other":"f6a12b23423c047927a3024a6dba7ce88927cb21d4df3778bc5ebb262cc403261c79ba6d9bda07f1852c009d803a77f429e9e48ec1d63cae98256e529d45b276","up":true},{"one":"dd3dccc1758765569905b3b137ef4c7dd31c2dc0dea827bcc4c4e976be94ffbb0f2ef6fe725cf9042063a96d663efea546837f35ca1fc67a854fbc9e27abb754","other":"77811b007dd1fc1b11e447858df37062e97b6fc14e059399814f3b4736188e3fb28bf7c3958bb8ebc6ae16c36884ba7c98b810fb6f8b358323412123c803abd4","up":true},{"other":"dd3dccc1758765569905b3b137ef4c7dd31c2dc0dea827bcc4c4e976be94ffbb0f2ef6fe725cf9042063a96d663efea546837f35ca1fc67a854fbc9e27abb754","up":true,"one":"6a55b94c9990249b24cdbeed96f065137f7b79ea8ee5f58da150d3962dfb62ba401960a53e7e8bd4e2c2908aa1a59b9d5efb4aafb316a9ab4fa67a0d95b58c54"},{"up":true,"other":"3948a7a939b9a1f4201953bd9b955ee7be87d09b63c7a45167f556ac06fe3c4c2a75d935bff50668da5e71e46802b55d7a9945a92d7807c00625d129cbb48f82","one":"ef7157fdfe62390d8a6d4ef976478d17465b42b63fddb03664973d63efb62318a8f59e412150528a32aa2c028b9de6bc67f05e012b8c43d710032ad871bc27e5"},{"one":"7c6e6a49429a4e24aa4aa5c7ba19684f77cd67d3744688baff6e7f1d74b7e9d2df85f3e57e0df0a9b960b5bf982a610c5639c3e7a6935ba13fbc77243b2dad19","other":"5d002c37b74a6656db86f102b0cec82bc35a819a480e5a2952db0140ebab65dffeb1a79f04d53ff61447b5fad7c58cb75ea1c91ea47fcb9e024f27b92c6c874d","up":true},{"one":"4b332b389f1142c0da42aaeb2e2692081d0002de0eb6741b3269e898a8101571d4556b755f2e8841e7a607bb41e398d2b0577fbe71098e7097f0fe6c720e1526","up":true,"other":"95ff4dea07303e1ba641a5c510e714ef232f4dbce9ad2e8b2f62644975eae41fc4bb9d1af3fae4d5ea4daeb18f8248e0b3131c7d843d35d33f3afbf7dfa4c2fe"},{"one":"510536aba28aa635d8a1098a6dbd2070748ce1eb0e14b54b93a21196543a60df546ff6a2b3b5b9f32a5c2a37f5aba77d0b74f28b2dabeeebf3fe5afc20a3209c","up":true,"other":"85c0b055439f114dee5eb0961013c117a48d62b0f17c61a7fd92a84092ef09bb3bbce686aa96e14528d5663565c57d657fa9813b1f38e268caeb1cb0842ef232"},{"one":"a8fac88fba179fb9b259d94caac9cbe45d873a0131bef8844ac4383b177daf6f301f8793623fec5876885db1a91e5b3e98e2aafdaa47e03b1f6d9740f48af7ac","up":true,"other":"d3cd2f34f67830ccdc295b7537a6d27c02b44503808ca666124f52ecc3d6c35b7d3f14343997006aef2cfbefc8d27809d389477e99c236b9f8a897a4bc406a43"},{"one":"85c0b055439f114dee5eb0961013c117a48d62b0f17c61a7fd92a84092ef09bb3bbce686aa96e14528d5663565c57d657fa9813b1f38e268caeb1cb0842ef232","other":"60995852a2385ce8d7d24dc94b85a2f0dab6e5c32e910dfe367ea9c6ccb7b0b2eb611fdf120f8c697097e2f137cefff42e8d9db16b664a857a38c5ace837ffa4","up":true},{"other":"4b332b389f1142c0da42aaeb2e2692081d0002de0eb6741b3269e898a8101571d4556b755f2e8841e7a607bb41e398d2b0577fbe71098e7097f0fe6c720e1526","up":true,"one":"d43bd6d3ae39a04e4e144a8a6f80b2d54472b5b9b6491dccf44b1716a63d24c56e3a871b3b8fe983d992988dc07ace06736ead3b1287914b629fcfe17e81f36f"},{"other":"ef7157fdfe62390d8a6d4ef976478d17465b42b63fddb03664973d63efb62318a8f59e412150528a32aa2c028b9de6bc67f05e012b8c43d710032ad871bc27e5","up":true,"one":"222d7a2f94dc82a09fda70b8195fc3a60433a90f53998872318c57625c528c90572d78b444ac4901dcfece1a03ef8b6cbe7845366a845a942f341f6db58a9b3b"},{"one":"2cb076669efbaf2ff0b181a1b454061a31ef23937a40405022b126f0eb4bfba60c9e3397009d8c0ff0cabb603692532d0072c18c6838f43397c98483306f62db","other":"c9d705012a06d82c4d44db95b4f1c63ddd33ad64d732e96b1d878caa0caac433d4096f01495a6f0e8a56af122b0470fd745db6d906353b590a4710472b93f5b2","up":true},{"one":"95ff4dea07303e1ba641a5c510e714ef232f4dbce9ad2e8b2f62644975eae41fc4bb9d1af3fae4d5ea4daeb18f8248e0b3131c7d843d35d33f3afbf7dfa4c2fe","up":true,"other":"06aab75fed9a03f5525e3f1d8f8997fefaefd5b16e8f485d571beda00b1741efbb61a8a74fa12c2f6de66227c3fabb4d411659cd9c7b1ef32e171e6bf517cc39"},{"up":true,"other":"9bdacc256acef0433805477d38f32be849a8846d88cb883b19d290454639b42c6ab6c5c52d4f83453e8a156af7d85f606458aa9c0977c67282f56f34ff0acbfb","one":"7b4585f8a4e4904239994a1b8bdc76299da8e46a8a632fabc6c33dd4170f8f3715e4c4f526ea5dd14093b150855960e432b1b140594aca21995f9e0722fb57f1"},{"one":"3948a7a939b9a1f4201953bd9b955ee7be87d09b63c7a45167f556ac06fe3c4c2a75d935bff50668da5e71e46802b55d7a9945a92d7807c00625d129cbb48f82","other":"bc0df855bdadcde3e447415444f655eb430925a8fa81cdcac75909e7d79750f01827938570e75e388cc7058ba8ebca47afadf8b07172bc078488fb618ba71024","up":true},{"other":"be93fafaf43f6bb3efd2667d1468a8636cb752b245328eaa01468c0606d790322a7cd8e47857068e60118e28b8dd8aa1d2d4977c5b3d28d4b47f4c0658f05e90","up":true,"one":"0c82c4b414375479375703ed9c19fb08c8143229ed4f1dcf448c6cf313810c098905123bec17969276936ae0cc39ed251b2811dbffb551d61159862b0eac0a23"},{"one":"e5cb29b25debcfaaacc0b04e708c8c1cb9d2dee29e82596a1c72a934032cf738800b9525cc277d0c5f5dacf2f278329b54da161b4bafa285243fa0e9fd7b2f3a","other":"0c82c4b414375479375703ed9c19fb08c8143229ed4f1dcf448c6cf313810c098905123bec17969276936ae0cc39ed251b2811dbffb551d61159862b0eac0a23","up":true},{"one":"be93fafaf43f6bb3efd2667d1468a8636cb752b245328eaa01468c0606d790322a7cd8e47857068e60118e28b8dd8aa1d2d4977c5b3d28d4b47f4c0658f05e90","up":true,"other":"d43bd6d3ae39a04e4e144a8a6f80b2d54472b5b9b6491dccf44b1716a63d24c56e3a871b3b8fe983d992988dc07ace06736ead3b1287914b629fcfe17e81f36f"},{"other":"f52281c227aa82a3bd5fabfdcf8bdf1d9ea6739ab9b9075340143d59b4f2f8a79a981609c9f42823a0253c19a7281eed0e912e4054363ab7fe50117563ef14e0","up":true,"one":"e323da6ae861cb092543992b8985639f9b3bcaf1c3c68757f4603a67800be62950fe7d8f8ef80eb83a18107b677c7f5047ea89a5790e0ea2a7969f4856d28488"},{"one":"24047e1a816cbf9b7a90e6c78dc896a3b624047ef5cfd3aa495132d57b1074aa129ea6eff171f5cca91d0f4793a07c9672b0a55232f2415c6220e443ebd0791d","up":true,"other":"4116fbb7d55bfd4bd8db9cbfa570ac361bb88605b6aacbf84e245893cf3fa599ecc086688a4c534c81f61a90fa344ca37e4d4013ddc03f7f08218724a55f66b1"},{"other":"b60def37233dbbc0d5f7fcddb304be1c0b6508e1e3d8a09a8290f7363e9bb84152dcaf70b8f6bb3a882fee77ff03ab796a5c1c3654f251c9f5c746ac5ad88556","up":true,"one":"2751df9f64a8f2ff8ea45efc9bd02b281d963ced285260bcda7f9dfaed998fe4386fe65a7265876da6b4fee77ea5c12454869a70ad627da7ca888076fc629665"},{"other":"f52281c227aa82a3bd5fabfdcf8bdf1d9ea6739ab9b9075340143d59b4f2f8a79a981609c9f42823a0253c19a7281eed0e912e4054363ab7fe50117563ef14e0","up":true,"one":"8e89fe4b3fffea8af247d2581aa511056efbeb796058d50a341d57aa0f7ccc2192d90cfb8d18558363df798567faaddb86815e8bd671b36ca37af0651535aabf"},{"other":"46717bc5fb7fcbcdc961e7ef091020f9f222858cf3d4afcc0b0bb1b782b7055d9eb833e0a04cb32d80406133ac77162521c43edf9f9690872222760e31462ccc","up":true,"one":"c9d705012a06d82c4d44db95b4f1c63ddd33ad64d732e96b1d878caa0caac433d4096f01495a6f0e8a56af122b0470fd745db6d906353b590a4710472b93f5b2"},{"one":"d7e3661c0af6754c875217f93d34b254f1f45fc1359a4c6146cd0efa4c6e12aed9a4fb0a21a136f73af4fc2c6d0a63cb809d81855bbc9f51e29d23d90f77b326","up":true,"other":"bdd17545242bedba1e4c36fadea95db655f8f220f10ae143084690a3c8d4e7ffb79a64af9f1bc8514addbd63695b2f20857e8d162f25318faac885f77b385138"},{"up":true,"other":"a8fac88fba179fb9b259d94caac9cbe45d873a0131bef8844ac4383b177daf6f301f8793623fec5876885db1a91e5b3e98e2aafdaa47e03b1f6d9740f48af7ac","one":"d6747e1f8594f7449fc6d7c0e63ee843480567d498db096ff04229420861c83bca5215fc19d8fede0c54484f111f1f2581e189e638c21c5d9e1fd3174bbb3e98"},{"other":"5a235aca7005df295d5bd924b1272452e9bdad408ca5223b9eb76800b4bd4e3158a1d663ce5243fee92233227249fe4bb8507e8cb2c3729744b273bf488ba60c","up":true,"one":"df9306a263f40e0e255996500523354de3cc78b68ae560f66d79f6ea28f30f773f1fd6ebc33928723dfde2ee3d4f982b203bee4c3803a5050df83477045bb279"},{"up":true,"other":"33cac8f621b9122e118036154778d27dc419b6b58ea2e89b833f3932f411dbc3511d92b55ae4cf80632142bc8e67994899aaa30c499d0289fae85b12564cf01f","one":"5d002c37b74a6656db86f102b0cec82bc35a819a480e5a2952db0140ebab65dffeb1a79f04d53ff61447b5fad7c58cb75ea1c91ea47fcb9e024f27b92c6c874d"},{"one":"884d32d09dfef937f3ef1cd6fb5f530c2c574487c0ffd4185ca405c8b2ac73044a196c34352e850ce15321eec6579da654a696381f3e5830d03c7aa18923da6e","other":"ab13f773f6f2ff73032aa5f79c8897b75dda29bcbb14aa511e9401c2417dc9c510253071e28c7833c8d62fd2aef16fcd0c14ce016fbf4fec1b9a2173c717603f","up":true},{"up":true,"other":"624248a794fd62248024360f128b2e503c752340694a316bed420e5ed2cebeb5bf970df95a2806732237a26de3778222b0454e2e7d2875129b193e7890fd5b95","one":"a47697063a2fb973449bdabd0925e10944ba1f6d8b2cc5c38b295f611eea3402b5cf3ae857716a34d84194955f5ed61350affe56223349124c8233852141f9a2"},{"up":true,"other":"b60def37233dbbc0d5f7fcddb304be1c0b6508e1e3d8a09a8290f7363e9bb84152dcaf70b8f6bb3a882fee77ff03ab796a5c1c3654f251c9f5c746ac5ad88556","one":"842f0ac24370f14edfe72a7d07219de60fc767d2d0356fa6ce9d535a43647ad4bb17d9be75ed83542868ba430ec104ba168f27c16915cdbd6e57ae62d60707cb"},{"other":"e33a1476fcb8d2a1b9ee15871a960ce7a3337c93f5956a2825b1f8b2885dbdc0ed652b1eba549523866632b5b6898310bc638d946a9fcce27d65117eb44c25f3","up":true,"one":"49256eccce3e036928a4b6b346126c6777dca5ea0134de85efca340f97ad0f827f3094f1562e3e186d35b8292a50c20ffae01409890bbb78598494285e14dc2c"},{"one":"f52297fc51b920d2495ccece290432656d9388e698339c8c1279ceea45de698a4ecbda1d25928c48f1e19e9dacd3147e23ef01acc093872d7300aed187841dcc","up":true,"other":"99af34b172d319633e07a4e528f416024653a230a9103a4b281171f75bb697dd6be4757558c94e86210b4da8d9fe1229f6a5d8c4174989ea0ce696f8d1a9995d"},{"one":"f8a5ae50e5b2d84096c10a6a8493a9eb8113df64c4f1336c0cf4649302649b158fa4cb7941591e55356891bcc1008a535df427546af19988a241c5f466467963","other":"8e5e8366251e33277e7db6f6c04629b2ce3eee217e973acb97c83773671b0160c40732794584db741a29a763672b90f3bdf34151fd4a6986b9d0956dc61d9723","up":true},{"one":"b1dd1b08975319030626aab821032a0c687a103ee8942e8a2e2cf029dd72832a49630e78d2d8b184579f22178aca0e875f9fad701fb81afd2ac110ab2b417376","other":"af9b80f6836113aeda897d6903e9ffb4f7f1a706a7f821d0d40f03a0d83c18d6a19795ee4bfc1093ada04014415b1f230db1d2f056df3f5027cce71611588046","up":true},{"one":"77e40e42f570a217f707888c714deb31fd70c856ae4b9a44ec7cee02768185dc4d7ed210429607f06690b32edd9fb06b304aff330a3949cc2fd49db1bc392edb","up":true,"other":"1e3a2f2491b6acb07a9549d9929d150479a0313c926b0e236237bd541303da4b563a855016a90ab50e59d94803ad566798570fa981464c94c04a4a4a94fbc607"},{"other":"b58b3e200f6072ddb38130944a01d2829c755b8bd1a08abd010d1bbf86dabd851b2c1ab4cb961451bd7e8499f6c7378830bcd27cde825846654853c172597bf3","up":true,"one":"855667650e96c5ed2d9b0c82532ed1fb92f72b1ae926afafe09cf8f6e90e539aec5c4c2ab108f2c2a1ad7dd8b83ca92a98c550a1c9ed27e6632a7d2f6da4f970"},{"other":"2c976b6007cda135444233c7bd03d22ac9756710b746c36bc032e7fdd42f2ffb89ca5f5e754ff96b8f3cbc474e346287e5b8531d9f98fd63c426c632872220af","up":true,"one":"57085f756f76644cdd2148524f2334d869ef0ab2fcbe7fb11f5d22bc1f5023165b11526ecc85ff9cbb88877386af9b148d7ef15a825b3a586d16c01bdfc86692"},{"up":true,"other":"ea2921612b827e3c26328368bed9be7cbf1f2b2aecaf31863c9cdccd74c56b651d6eaceb8ac9609a6653488837ded310df91e53a74789ae75cb841e2aeaf96df","one":"3e2241cdb9f34c1d2c6930e59940e2c4b92b0287579d7263a620a609c5e66dca6d85df48cf1bffd63663a6704c42d0866aae3e484fd9a44b6a012f72dd3cef6e"},{"one":"50c79baa3e6781482ccb5e960c699dd9c13f479467c6315c5292a396337cf3619e7faba1971a1f470051cb9042f80ea6750defe3936b72aac4d9bac6f8368c67","up":true,"other":"869cae165389e7dee7b7df4e012ee1a39737366c306d8f4b0db4510b2236e0bd3a4d1d4af00b1a8c1d360e23da47de52fc1632edb03c7f1429aacc8aa4994750"},{"other":"5d002c37b74a6656db86f102b0cec82bc35a819a480e5a2952db0140ebab65dffeb1a79f04d53ff61447b5fad7c58cb75ea1c91ea47fcb9e024f27b92c6c874d","up":true,"one":"b87e7f36ed6bf142d48545024d2fd6e120c44511701e7c0b7d7fc786f4f29d3357024b15f70b78215d8a4c2b7572d608c11b31612743e23db4fa673f0cd6519b"},{"up":true,"other":"313a131ecb7d68e127d0fec8bb4a2e586886203c3d07857a93e7a39bb831703184d9ae28ba9ef3d986c2dae1a24f4f5bfa47cfc35f74f5512a126836364d7736","one":"9e21f5d4cfb389ac3ad43497689878bd245a89c587a8637d832b1e355ba244f4c83e6499bc7936e6d35645db25910ecd89b9af9b6b2f0c7cc4d7c6114328d7bf"},{"other":"6c95c653e15bb99d32656f35790400134cd7188e063f878e19cb9118eb469ae0362dc45255f2a1eae31520be01d42b5bc5bbebf03d644c9f206ca79cb33a01ad","up":true,"one":"37adbfdf66163e45f433d78f63210163fdacf4688ad90d73bed07975be017c43cddf2a26a0dee8b11d78f294b63d4875b6be15f42f10817bd3d77b342919a11e"},{"one":"6b104eff1dcf58d11a7f707bbd41a910b2735b262c29e0f4e4127fda1b67def4e89b6ebc1b3cc1e06c3968d0898e1085badc7da24d3cd6624cb100e85863cc97","other":"6c2788dec7ae7a77134065afc1174bb92b87833e87acaa72fe9e62c92d2017f217f9fbc5884cdfb7236a7bb75e463e49ecceb1641a8629516211d9699587046e","up":true},{"up":true,"other":"49215dfa786bfaa52b1e7aa6899392711a770b2504c82f536381fb1f18df16960257d75530efabf6dbd2b1361decc29758f870b318f777decf51f4833a9c1f00","one":"7958d1517de1223e7fb30acf61d8618e49fb95a03bc2f49141f4c7967bc80b90e0dd526c205639de3c060029963d43813293c2556f7b127945c798f3f9f18626"},{"up":true,"other":"e0a043f98b462f10f72aa61ceda52f9c27829d086f6f2c5bf4db4fe32759002e5ff9519495d57dbb83d963a1dc991a1defcf5b9ef0d543789f38c68f5d07122b","one":"ab1a3542d67ef9d1a63653990bf0782f53b0169fe5092adc92fa7aeb38f66c6b62d49e3455cc2ac4994bfcfb03111953acf4cc3099026672cc61f6e24cb3ae00"},{"one":"e9cd25d1ef3fef22160bce7f7badd7646ac58ee40da6a438f61a067c51bc51d6087ed950ec9e909bc438ebe62e316cbd9489f3c9bfa2898615632414e04f1dcd","up":true,"other":"69f999937943be00e5fca5c7cc942ce13b6752a72813368da2fbfcf74ad807bc6edd85537e087b6f73c0469c7b76a5d8f7d883bd315f3b35af32b8da293ed243"},{"other":"6c40910f0556f892a7542989fa01d7e3682fca89aeefb5ed885808f88ff17b6d13862f461c10d629a005ae67abef542d75e5b20816891b6944f71560f5c2dfa8","up":true,"one":"7db14fde1da8794ae7ab5de37c9e2537e1024bc830c176c0d01635cafed47773d3a28e156db81ecdb95903222b900c3ebd4c4b3db2971dc0ef6a1e386027ffaa"},{"one":"7cc9389c8f751465e0b94baed896f6f122631052300b1b5b23d3c7656e4d11014a7a9ae62a1287bb040ca37221871a566cd470e523846df7e3acb5f94c7cde06","up":true,"other":"e0a043f98b462f10f72aa61ceda52f9c27829d086f6f2c5bf4db4fe32759002e5ff9519495d57dbb83d963a1dc991a1defcf5b9ef0d543789f38c68f5d07122b"},{"one":"aa53ca208cc0c9e544fd9d52cab44b5e2887256bb006037b855b5c94d7f79c9388fdbb23c0bf1d2eee12d67125e082fa7ecb34c1129ca8eaecfd85772b009435","up":true,"other":"69f999937943be00e5fca5c7cc942ce13b6752a72813368da2fbfcf74ad807bc6edd85537e087b6f73c0469c7b76a5d8f7d883bd315f3b35af32b8da293ed243"},{"up":true,"other":"d7af0a0217ff98804aa05f8f926a8b6262363b5391d24cda8048cca5ca5982b407b7b098302d0db6d8dd9ac0883b2025b3de651617ed1a173181148295c6d336","one":"e903d7aebff96a6afa4b9dd19b0b02e5af18da8e4e89f64247e1a2c2d46637538c741182eac67f45ec61be76aeaccde57f0a0184bd608ea7d92e586d4f827ea7"},{"other":"1e3a2f2491b6acb07a9549d9929d150479a0313c926b0e236237bd541303da4b563a855016a90ab50e59d94803ad566798570fa981464c94c04a4a4a94fbc607","up":true,"one":"c206d8689068488179e86ce549de75989e0b17cbe09880d18fcf0fa212e629345f1b899203607a2b083569cb3f8398e501843166f5db23ac7fa7dacfe26dd3f4"},{"one":"aa90454031068598ee39af5f1429c7a72277946d50ec2004f340406dbcc9f80cac505c9d9b071f85e2ccfd4b13bcf943f3cb9dd9f96f62d41352af9d8fffe7e4","other":"60995852a2385ce8d7d24dc94b85a2f0dab6e5c32e910dfe367ea9c6ccb7b0b2eb611fdf120f8c697097e2f137cefff42e8d9db16b664a857a38c5ace837ffa4","up":true},{"up":true,"other":"431644cf162bc267237c4e798288888dd835c1b0546b0cc679782e33568988d75b4294f4aa08359a6b152ed9a0fbd13133681156bcf09a871c4f362615ea6dae","one":"e1f23e1caba66f5ff821edbc4a3d527539937f73d86dd0df43aa1266a99f51f2480a77961eff177fbbf852fc52cb9317179f80b1580194daaedadc3b00510751"},{"other":"c6f38fe8a0f2b3773bae332e0ca7516e944bde186fe99daae10a2b0aecde3ce23c1834eaad97a4e6d2da8cd53a08dbafa72d2b827c851b115b74e8010125dba2","up":true,"one":"9bea5f82c2a390587de44d620d6637834e6f2329cd83d8df6305b03b75d9b543160b6c6f9f8887e6bc88f1d0726435d6c8ad813aadad0653b0790b8f6388413a"},{"one":"1cdef98d7b4de45c902c725384bd14c66084fe4159b26a0f9a24f432e1f561d035ca41e1c60fe64f3213b4f91a1afb953193dca1a7d535be0602b5d046bcbab8","other":"8e5e8366251e33277e7db6f6c04629b2ce3eee217e973acb97c83773671b0160c40732794584db741a29a763672b90f3bdf34151fd4a6986b9d0956dc61d9723","up":true},{"one":"9c8f156797deff649d74d56fc42b4bb1a87312089114d4350424c375837d9c8068dd09af01c1c973d12ec5d7e8da600cd685cae70d3116b9dbda823092e03fff","other":"fee3fa1ba2a051d40a582908384ee81179db6c2b5f4bfa58c24f8015b794b43a093ed68b69bb209684135f972a055a9845978fa1b7d489e2126c3b514297f1c2","up":true},{"one":"77e7d427b65b6c29c0d92c51184af73031bfa768a47fc20be6c264f422bf718865259c17c103bf47289b3abe62f93452781c6303d757e76d3d56ceeb26262fab","up":true,"other":"99a7649bdf2ee7f0bc049308b0997e33abb68481c05a573df9aea30da5a1f267df07b2c584e3e985baf31704f04ad2a2c4876e0f8555333be6d09f5080b583f1"},{"other":"c0bec7375c66bec98524ade2245c1d7480516fc5d87a3249e64ec86418e80e202f1e3da76832e97bbc3dcaed8c96ca344e4829347b4428f4b1cb61999e404c05","up":true,"one":"af9b80f6836113aeda897d6903e9ffb4f7f1a706a7f821d0d40f03a0d83c18d6a19795ee4bfc1093ada04014415b1f230db1d2f056df3f5027cce71611588046"},{"one":"b1dd1b08975319030626aab821032a0c687a103ee8942e8a2e2cf029dd72832a49630e78d2d8b184579f22178aca0e875f9fad701fb81afd2ac110ab2b417376","other":"362ed9a92b588d5fe315b90a74aa27f7600e4a7d06b27ceb26272340388d916a831df85bf83450ef80bda4e4a21acaac60560c8a42940a26e2ac567519e2a202","up":true},{"one":"6b082a09e343a160b60a01f74641c1d707b2fa8fee5f6f5a8b9e4a203bd86434227d2df982b246a752f843483cdf517e85fe3bd65453354232a6eb38dedbf314","up":true,"other":"51a570637394e9ab61fe95b3a608cc4e9dc8ceb63efe717938ccd4260a962d52e01b30e7034fbfdabd9a3c9616ee569550b38a6d6b4b19847f523254069a9f27"},{"other":"99af34b172d319633e07a4e528f416024653a230a9103a4b281171f75bb697dd6be4757558c94e86210b4da8d9fe1229f6a5d8c4174989ea0ce696f8d1a9995d","up":true,"one":"93073da602d6326a48464a8b6890220b3aae0abf5b6961180f3aff2a14573c43411bd519d3e0012a646ec2977be18915d95a36d935a69f93985f5307ea4e3ebe"},{"up":true,"other":"90b8e73916046b5433dce049bfe125ca2bf2fb390ff7301f9bc5d8d0183988577aa2a7392aaa28091aa81c8ac23942b5751420b9ee48e488a68411f9d2b1e5d5","one":"e8a679f627d03347a4fcec0a0940f7ffa90ce3fefea290db3af4f3a32d27965bfb51832b6a6de2495c8a8cc026bcf993b84a0cced778e158bb81c034f5e4bd76"},{"other":"d6a7257771baa4d9944592ead46b8ab700dbf91ebd4dc0ec7e5fb41cbda0622944269172fcec8352b89ef2c186d4c787af2b45a50533f627a97818477de034b4","up":true,"one":"69f999937943be00e5fca5c7cc942ce13b6752a72813368da2fbfcf74ad807bc6edd85537e087b6f73c0469c7b76a5d8f7d883bd315f3b35af32b8da293ed243"},{"other":"b4557089e4247379e587a087f53b36dd1f86f85d9dcfab5dc562079978cd959adaef5b30d11258d9cb552e7c5abddf5377a71d449febe8f2acb0aec3ebd8ba73","up":true,"one":"3376cfc924fef1a45aae35d106439b131f363b3a42904b3974cc7cddde325441cce8551729dd62f1119120b0d452e78f063e8e711ecacdc27d9087aac5ab09b5"},{"one":"a5f7163586fce1750fd9a6e5c418af1c18ca6983069dcf1738fc9106ebf542a86e4ccfc50b45a0d97ca8681af8207128877f930f945e59ee262aa7f4014a01f3","other":"51a570637394e9ab61fe95b3a608cc4e9dc8ceb63efe717938ccd4260a962d52e01b30e7034fbfdabd9a3c9616ee569550b38a6d6b4b19847f523254069a9f27","up":true},{"one":"eb58e478b16056e0af344397cf5f078a3312a6db2189ec2042ec06ab6550e3ee71ebcfeff1814332c552c12a5a488f96b3f2935e90a189d238da19d30a2c9874","up":true,"other":"5a6318af8b4615cf30610a05ade7704182fefd0a3fb3d76c47cb392e114d8d30004f0ec214326b11532fd1e928e66f632bbcde126a94c87774063853a9518dc5"},{"one":"3a2cacc430f13f31c52b7205455420cf0fb9ed9e28b0898b69ef97951bf295b29118e573a42dd97abe38fee5ab4c03dad9ff6dc448126cefc1da12b6c8e8d915","other":"aa2028d356a88eca8e0fcaf218d62ace099c3f72dfd95bb28f30ac9a926034cf1d60a40511f7495652745de80d71c0f6830019e206c88e2b6ef0cf4f05d7fe9e","up":true},{"one":"876618c8ba66c1b91b473a154be3e10ded3590ba83d620d30e0ff1fbac2f31f258b1299a3da5b56aa03269a80c119b7fc41dfd87d5bd996359e4ad8dd0ab2a6a","other":"6b082a09e343a160b60a01f74641c1d707b2fa8fee5f6f5a8b9e4a203bd86434227d2df982b246a752f843483cdf517e85fe3bd65453354232a6eb38dedbf314","up":true},{"other":"eb58e478b16056e0af344397cf5f078a3312a6db2189ec2042ec06ab6550e3ee71ebcfeff1814332c552c12a5a488f96b3f2935e90a189d238da19d30a2c9874","up":true,"one":"b3b4b203395bb6655d79ecdcee11638dd9a16baccfcc1f6fcc8b31832c8ca35650eb6c2802104eeec6d96ea80404381a2bd9b01dcadc748a4666b761d9ce64f8"},{"one":"a47697063a2fb973449bdabd0925e10944ba1f6d8b2cc5c38b295f611eea3402b5cf3ae857716a34d84194955f5ed61350affe56223349124c8233852141f9a2","up":true,"other":"8d3ad57509b36c4ca5c4663f3d1977a3125e069078842634e6cfeb22c044281e3d02f06eafc6d2a60089f03d70f5134a6635c35563c9f911fd845a6ef9bc8952"},{"one":"8d3ad57509b36c4ca5c4663f3d1977a3125e069078842634e6cfeb22c044281e3d02f06eafc6d2a60089f03d70f5134a6635c35563c9f911fd845a6ef9bc8952","other":"f60755ee9464c7db769bb7237016fa165441d18ac3bfed7cd2a220a9bcbead202dd34eaf2f9398a3d36bdfc2671bbd46ac25ebe264a8118afe1b7d0bd38710f4","up":true},{"one":"b152eb30c9f46ec39166016f03d289f98cc285ac62d204da32e5a003da14e4f02c64df8ae1d0c8a2a902adc5f7dd7604081a0b140c9b64052082f0861945f5a4","up":true,"other":"c0a2c08fa8b70ecbf1932254945d5f689b0da7a287019d384152f383f6229acd4d82eef26205bc12e062dae4569814bd1c996ee4fe5886bd6bdd93c4f0ac113a"},{"other":"2b0a1f3a6466c6be1d7e84120db384fa37f7c73a01e9a105ae90e7d2203212ec974f016d3012afd26bc0f9a8411d0716cc59b6ecc9f665db12e306af8b34cb63","up":true,"one":"85b6404a76b4762156c8ddd2f312763dfe19b315d914533844cf229301880c57ffeadc0eb5f4a8d542e1d9fc961dfb5a572d2101172b1a0fc238ced05ba49ec1"},{"up":true,"other":"81901d9f043b4b1649ade3b5d22ae5f8bb42dd6db1eb37b836b99dd1c0388509ed4b54cc5638c9d4a6c5ae6c6913bbfffb303d7d94bf4ed50e871cf95459e2c3","one":"f4cdaeb513aa98f8868d8eb3a1d12c07367725928a1bc7d6ca4b583788e111a955463037ec7867260511896d97dfbf096aa77ee8a7d9ea1c06cad4a92c45108d"},{"up":true,"other":"eb58e478b16056e0af344397cf5f078a3312a6db2189ec2042ec06ab6550e3ee71ebcfeff1814332c552c12a5a488f96b3f2935e90a189d238da19d30a2c9874","one":"f60755ee9464c7db769bb7237016fa165441d18ac3bfed7cd2a220a9bcbead202dd34eaf2f9398a3d36bdfc2671bbd46ac25ebe264a8118afe1b7d0bd38710f4"},{"other":"b4f300abda4cf6e383f997510eb681e9fa62e23577e3c19bd7447fa1f5702a4e034cea5944248e7c6e6e92b5ae69195c3e8a2c5ca7827b4f4a00cc8546e6695a","up":true,"one":"6c95c653e15bb99d32656f35790400134cd7188e063f878e19cb9118eb469ae0362dc45255f2a1eae31520be01d42b5bc5bbebf03d644c9f206ca79cb33a01ad"},{"one":"e993be8034861aebc9bbd11115f25d9c719d43fcdefc323599616cc26240cee38dfc27bb7f339149a54a3c9ad13b2d6ca4f0ae690e4355605eda6b789c4a431e","up":true,"other":"b3b4b203395bb6655d79ecdcee11638dd9a16baccfcc1f6fcc8b31832c8ca35650eb6c2802104eeec6d96ea80404381a2bd9b01dcadc748a4666b761d9ce64f8"},{"other":"5d002c37b74a6656db86f102b0cec82bc35a819a480e5a2952db0140ebab65dffeb1a79f04d53ff61447b5fad7c58cb75ea1c91ea47fcb9e024f27b92c6c874d","up":true,"one":"fc9b1b2bbd5e682eb350d23f3ee33b245495daedae9370de7b1f55f91cd45db831d196c17615e11decf6b67696a268ac788130e3de38c7f6aeae811f3ec8c8ee"},{"other":"224c3b969149d50d1bb4f473bb9725223c1dafe152efe1b08e8859213c543a66565b5d68a99cef3d5f4eccad6282a12f78d7b38eec14deebf44ad8dd9cba8680","up":true,"one":"6ad4ea3730ddec500e56248d1025aea79ec10f0d6a9720ee48026df10e219b41965d7a611fd99ee765f6afbc8c977db7e67c3a340881904acb983d1e2fb016cc"},{"one":"48e35d67e14ee2f329c0275bc965829b761885dbc3671f4673d84d76d18a5b6415e619e219b5d90761a5c6bd2f43c6a58708286a063daf46b502944f8ef9230b","other":"c0bec7375c66bec98524ade2245c1d7480516fc5d87a3249e64ec86418e80e202f1e3da76832e97bbc3dcaed8c96ca344e4829347b4428f4b1cb61999e404c05","up":true},{"other":"da22fb43c6d230d92f9c09454e282dc45dffc759740566039f1bdfb58171c6801f721841de83217277b3fb70983e7d34da53bbf25d1d45413a78d9afff151826","up":true,"one":"c402495c2110a6531a530ebdcd9ab1b883f1c707fe25aa13a255a0a9edb4113669b4aee9eadf803f9fe4c2ef66d5e4dff7064549f672598410f2d9794747a600"},{"one":"29acdd4c1233441bd40f98e245ecc9de94de6f9d0ab7c1a9923d833a2c8e6c1bd26d792686fec762b31fe28bbdd7aa04c9a594d997d08c133bb24cb2d877595a","other":"02fdbcb00f20a3f6e894900d798fcb0aca9e21f5b107924c0999eb396220f16dee99fc80ccba796e66e69dcb9ce278b7e0e4539c7a7cd0fbc1037bf8e56c1e67","up":true},{"up":true,"other":"ee0b09ee6a1057c47102e582e2fdec7b9212802e59f062a9360da0db535d4987126ab24848c0d76fa8485431a5140307e2b0c0d9f37cbdb35756e6cc1bdb3bc0","one":"865dbf61d8511603fe0d9ebfb10792b9f6b798187c0909039bd9b2492c41e428876f386beeac86d0dea871f4fc24ba435f0fbd9a11e74c044024934592af14ee"},{"other":"b9c7b885430b9b1a4425bde30b3629559f5437e0e30a0299fc6f6e097cbcca8af9e285caf5dea685a0237f60e06f490c39a1e3e487f14a2b9f41a5135f2ba994","up":true,"one":"29619924833116cb1160bf7a8066a528b7182794368bfae62b5bacbae680d9161a479f217e30c3b4f19a250b1b59e08f86c94726117dc3bc94ff9ceac6bee6e4"},{"one":"e0a043f98b462f10f72aa61ceda52f9c27829d086f6f2c5bf4db4fe32759002e5ff9519495d57dbb83d963a1dc991a1defcf5b9ef0d543789f38c68f5d07122b","other":"1e3a2f2491b6acb07a9549d9929d150479a0313c926b0e236237bd541303da4b563a855016a90ab50e59d94803ad566798570fa981464c94c04a4a4a94fbc607","up":true},{"one":"7c6e6a49429a4e24aa4aa5c7ba19684f77cd67d3744688baff6e7f1d74b7e9d2df85f3e57e0df0a9b960b5bf982a610c5639c3e7a6935ba13fbc77243b2dad19","up":true,"other":"c9d705012a06d82c4d44db95b4f1c63ddd33ad64d732e96b1d878caa0caac433d4096f01495a6f0e8a56af122b0470fd745db6d906353b590a4710472b93f5b2"},{"one":"b4f300abda4cf6e383f997510eb681e9fa62e23577e3c19bd7447fa1f5702a4e034cea5944248e7c6e6e92b5ae69195c3e8a2c5ca7827b4f4a00cc8546e6695a","up":true,"other":"ea2921612b827e3c26328368bed9be7cbf1f2b2aecaf31863c9cdccd74c56b651d6eaceb8ac9609a6653488837ded310df91e53a74789ae75cb841e2aeaf96df"},{"up":true,"other":"9c8f156797deff649d74d56fc42b4bb1a87312089114d4350424c375837d9c8068dd09af01c1c973d12ec5d7e8da600cd685cae70d3116b9dbda823092e03fff","one":"d09104c44648391693ca64a57baa5ef54ed717e19c65ad0a0921d08cbaca8877d0190795d15f75f3b6ce6e676d6b0e55d5ee8fec3310c68b7060a32f7ff649cb"},{"one":"15ceb62ee0f53379aa202950634ed881ba3b7bd4b46c80723ee48190079311e24ffaacb167a126a40bd6732c384f3c26163aa043edca03cb52a97b6da189aec7","other":"9ea856ea440c776b9ffaad1237ec11d570a1f912a908b8363ff97cf7947d2523e3c73663240d8fac988698cdd81e877ddd4a609485fe9f26494136fae14212df","up":true},{"one":"ee0b09ee6a1057c47102e582e2fdec7b9212802e59f062a9360da0db535d4987126ab24848c0d76fa8485431a5140307e2b0c0d9f37cbdb35756e6cc1bdb3bc0","up":true,"other":"6d0a09235ba0b0428938abf0e0782ac0ecf5697ef862888719a34fc956517aeef89d5e5f76d12e10067fee5bac8781dc10400eeb35c2393b9382b2a4f68f7939"},{"one":"c0f233e79d0a8d4af01f54c40640975bc113f464271ba8922fca0c28acc60367af0db06629e701977e86cb5917c891e39c21418cab459fe49132b680aa31600b","up":true,"other":"49256eccce3e036928a4b6b346126c6777dca5ea0134de85efca340f97ad0f827f3094f1562e3e186d35b8292a50c20ffae01409890bbb78598494285e14dc2c"},{"up":true,"other":"46717bc5fb7fcbcdc961e7ef091020f9f222858cf3d4afcc0b0bb1b782b7055d9eb833e0a04cb32d80406133ac77162521c43edf9f9690872222760e31462ccc","one":"154d5ddb15ec12dc65362039d801383c189b5bcf6688883f2d7e3d0e8dc78e45f9f58d5dabc79a8798a243ce59abb95c77525db14f050fd8cb37d04b7276557c"},{"one":"243164c4dd583f80c50813f43e5c27c894463400cd3afd776b36e79e7123d9261f01f06f92914aab83096b9a43fb655e79687590599284640a3a7d2c25454597","other":"1b3107d9a96cfd11f4cd0ed8baeb7b23db1406c9c4a9dac76c772f49c0fc9404f6a4adae11120aa821757173f0cc1cb00e6ab555b5abffaae9001c0557cb75c9","up":true},{"one":"b58b3e200f6072ddb38130944a01d2829c755b8bd1a08abd010d1bbf86dabd851b2c1ab4cb961451bd7e8499f6c7378830bcd27cde825846654853c172597bf3","up":true,"other":"37399617d62153bc471f3bf21c92385bc8602c80ffa0c71da8aebae595a9859cfd56257aae60ad30ef3ec4d07dee90623cce63749c8c3233c0aa0d17f9e89afe"},{"up":true,"other":"77811b007dd1fc1b11e447858df37062e97b6fc14e059399814f3b4736188e3fb28bf7c3958bb8ebc6ae16c36884ba7c98b810fb6f8b358323412123c803abd4","one":"c674c405068bb908312917a319e24ddf90e814ee8ef54bbf740f176b2a7eda6950e3e1ed69484ebcc27b13d82c7f0b20daba71a17700018e769ca612ca8d2208"},{"other":"7a8cb96685c1b8fbaeb18c8dc1f9f2631b23bc035e704e2f5df915b8bcabd6e2025ddc30324c69833f86e577b250c0721fee9d294f3e22016ae4c59c5f88845b","up":true,"one":"a1fe0d27f82309911a4b758c4e597bde16adc1e2fdfb07b52dea5092cea40ff212ea2cc831e385094b044f519909cf978f350b16ffd4c70c159cf1372301a3cf"},{"other":"9d372d73848389cfa1676f0cdb030950980ed5b68d5b2ef8a058f1d2095b26ff0fafab5fd3c243296ee2620edc67752970ab47370270856287f8612d1b190a19","up":true,"one":"c9d705012a06d82c4d44db95b4f1c63ddd33ad64d732e96b1d878caa0caac433d4096f01495a6f0e8a56af122b0470fd745db6d906353b590a4710472b93f5b2"},{"other":"e903d7aebff96a6afa4b9dd19b0b02e5af18da8e4e89f64247e1a2c2d46637538c741182eac67f45ec61be76aeaccde57f0a0184bd608ea7d92e586d4f827ea7","up":true,"one":"9f3af4577308965aceb7e0101443669496e7ccf1de680629862a7005966c708b6fb52e6dfe62660246b9892adc25838da2873502e0be706bcad8f25b7ceedfa5"},{"up":true,"other":"49256eccce3e036928a4b6b346126c6777dca5ea0134de85efca340f97ad0f827f3094f1562e3e186d35b8292a50c20ffae01409890bbb78598494285e14dc2c","one":"b8e0a56df21baae43058f575b714ae9a33c097d18f1a628b3b6ae5e86dd46a06e44c0dc272baacb5be0f7bf57fd6ddce107544eb3b94dca1aeae9f5773496a72"},{"up":true,"other":"154d5ddb15ec12dc65362039d801383c189b5bcf6688883f2d7e3d0e8dc78e45f9f58d5dabc79a8798a243ce59abb95c77525db14f050fd8cb37d04b7276557c","one":"6a37e63feed9e68c52cb8b385d5e8d8dbd2b211c57ded0d3b01fe8b306af5c0e5a7405d0d9a942648f0131926240d53450bc43f922a053528e5830d918313c3d"},{"one":"bac3fd2ea491d8e4ce1e5d469ec73f3d537d61279ae66e7a394b20a188244a886d3059ef0d304c0801878f9640374f7c8aaf56558c41f12296d3fc7f911ed66c","other":"3e7aef8260c0d9717aa59b65ce7c554e53b81f19f5b9400321704a7ddf5041b0fe31b5634e90b93e6984060defee0e153997bbfe196166cc8d83165fd5eaf41f","up":true},{"one":"488854534ec5a3479d8ee13d9b7daf07479f6b5505f319eced44dad8c316f6ff241ce2101e95608ba635067f5e5741481b78f419c4bbd465bf7e837dc4e54d64","up":true,"other":"9c8fca41b833e88110559b9258653160f5fb236bd637272ac58fe1adf333f4df75b94a805eaebb9f10a8c1a26d357dd75140560551d3fc4da79da2c4fc9479c3"},{"one":"d6a7257771baa4d9944592ead46b8ab700dbf91ebd4dc0ec7e5fb41cbda0622944269172fcec8352b89ef2c186d4c787af2b45a50533f627a97818477de034b4","up":true,"other":"1cdef98d7b4de45c902c725384bd14c66084fe4159b26a0f9a24f432e1f561d035ca41e1c60fe64f3213b4f91a1afb953193dca1a7d535be0602b5d046bcbab8"},{"up":true,"other":"e903d7aebff96a6afa4b9dd19b0b02e5af18da8e4e89f64247e1a2c2d46637538c741182eac67f45ec61be76aeaccde57f0a0184bd608ea7d92e586d4f827ea7","one":"8fb6838337f832445531764ddafc3c747b2607f2f33e244685d6de621c2b53264270f5504187e43b7fa5cda53e66dd00b16c06879c82fb38a3d9e8aec4060210"},{"up":true,"other":"58f9139905ae1d005950f110b7ead3355672ecc478e8c66393566c64b935003f6fec3031dc9eb21cda660acb1955cf7bb33a20fdd74d493f29868ace328fcd75","one":"f52297fc51b920d2495ccece290432656d9388e698339c8c1279ceea45de698a4ecbda1d25928c48f1e19e9dacd3147e23ef01acc093872d7300aed187841dcc"},{"one":"869ca41ea1f82bec5f43807a3aaaabc39b21c62d3c9c8bdc0709683e22dd37cb2f3c313766809076d2c02d0d6171f4f32a1b5080abcb8072d88981042ae6237d","up":true,"other":"9bea5f82c2a390587de44d620d6637834e6f2329cd83d8df6305b03b75d9b543160b6c6f9f8887e6bc88f1d0726435d6c8ad813aadad0653b0790b8f6388413a"},{"up":true,"other":"a58a4db7a96b1578935b222c78b7b4dd8b3519d2995c3616e5a154c5175242a503097771332504638a0b321b9574110207f9a7d77b109d1de3d66a12ec6498e5","one":"d7af0a0217ff98804aa05f8f926a8b6262363b5391d24cda8048cca5ca5982b407b7b098302d0db6d8dd9ac0883b2025b3de651617ed1a173181148295c6d336"},{"one":"46717bc5fb7fcbcdc961e7ef091020f9f222858cf3d4afcc0b0bb1b782b7055d9eb833e0a04cb32d80406133ac77162521c43edf9f9690872222760e31462ccc","other":"3e7aef8260c0d9717aa59b65ce7c554e53b81f19f5b9400321704a7ddf5041b0fe31b5634e90b93e6984060defee0e153997bbfe196166cc8d83165fd5eaf41f","up":true},{"up":true,"other":"7465fe601a9ad8e640069e6e07d56afabd3d4f008f3084f944d869b47fda3f511f191062802a53da511f60891dd0bcc5fac60254ef9db7aa3b41f5791b0b6975","one":"8e5e8366251e33277e7db6f6c04629b2ce3eee217e973acb97c83773671b0160c40732794584db741a29a763672b90f3bdf34151fd4a6986b9d0956dc61d9723"},{"one":"c2568576c2c9ef47aca0baca52709a4fa44b2ed478a062f7b161fac2bdba68568df371ac7754255fd07d79bb9918249a914946a6c318d579730bee9bc609922a","other":"6c2788dec7ae7a77134065afc1174bb92b87833e87acaa72fe9e62c92d2017f217f9fbc5884cdfb7236a7bb75e463e49ecceb1641a8629516211d9699587046e","up":true},{"other":"9bea5f82c2a390587de44d620d6637834e6f2329cd83d8df6305b03b75d9b543160b6c6f9f8887e6bc88f1d0726435d6c8ad813aadad0653b0790b8f6388413a","up":true,"one":"b4557089e4247379e587a087f53b36dd1f86f85d9dcfab5dc562079978cd959adaef5b30d11258d9cb552e7c5abddf5377a71d449febe8f2acb0aec3ebd8ba73"},{"up":true,"other":"dbb6621460b054f584f1c6157b4020f3c58d84c3a12b57436e10525ae60ab27036bf3edd68b92f2b13674877d01c2871dc67a9031c3d0470985f4b071696346e","one":"488854534ec5a3479d8ee13d9b7daf07479f6b5505f319eced44dad8c316f6ff241ce2101e95608ba635067f5e5741481b78f419c4bbd465bf7e837dc4e54d64"},{"one":"58f9139905ae1d005950f110b7ead3355672ecc478e8c66393566c64b935003f6fec3031dc9eb21cda660acb1955cf7bb33a20fdd74d493f29868ace328fcd75","up":true,"other":"202ae63076a5560418023f00c9965b2a1d12de932b5371ae270d63db88551a7aa1a3c48841f81948fad3435bb4a7e3e165a2eced9fd937444e4502471e23dae8"},{"one":"5982e7dfd39c527851f6ea6430b70e654d95df5ec4401ca1d8dbd1034cf7a65d1126d60b36ebbd396c9ca32e6e8515f34f9dc0a8d2980afe4aa181c8bf68437e","up":true,"other":"2abb91884cc3a8fb91b2f2f369f9430f2b3b05c75ce6203aa7a50312c9f141f9d0f615063d3576a5ce8a4be9ecb942aa804a717f76d9e8dca03d115dcc43f775"},{"one":"3e7aef8260c0d9717aa59b65ce7c554e53b81f19f5b9400321704a7ddf5041b0fe31b5634e90b93e6984060defee0e153997bbfe196166cc8d83165fd5eaf41f","other":"f5d95e0c5a873ff5a95e1eb34f1ed258d77adf98ee0886d93c4a24b1feaf6955e6e4c4ea0eccb2b9723870bae61e693643d6ad96dd8da01672542611f7c49069","up":true},{"one":"43086ff7ffd3c7bdec77bd288f41f1ee0ce21bd3f60a5df8931e2af6e7af5ef0fad432d29625491935d11567944351fc7867c807ebd12dd2c21c9e620ae0f85c","up":true,"other":"313a131ecb7d68e127d0fec8bb4a2e586886203c3d07857a93e7a39bb831703184d9ae28ba9ef3d986c2dae1a24f4f5bfa47cfc35f74f5512a126836364d7736"},{"other":"57085f756f76644cdd2148524f2334d869ef0ab2fcbe7fb11f5d22bc1f5023165b11526ecc85ff9cbb88877386af9b148d7ef15a825b3a586d16c01bdfc86692","up":true,"one":"85b6404a76b4762156c8ddd2f312763dfe19b315d914533844cf229301880c57ffeadc0eb5f4a8d542e1d9fc961dfb5a572d2101172b1a0fc238ced05ba49ec1"},{"one":"ea2921612b827e3c26328368bed9be7cbf1f2b2aecaf31863c9cdccd74c56b651d6eaceb8ac9609a6653488837ded310df91e53a74789ae75cb841e2aeaf96df","other":"02fdbcb00f20a3f6e894900d798fcb0aca9e21f5b107924c0999eb396220f16dee99fc80ccba796e66e69dcb9ce278b7e0e4539c7a7cd0fbc1037bf8e56c1e67","up":true},{"one":"fd0123c7b96004067e98e463e273de5bc5402399ae70a95985b5f682e30d4f35d070deaf8c71d201e98c4324d832b95aab7535ad8a2658f66e3e0bb1202204e1","other":"02fdbcb00f20a3f6e894900d798fcb0aca9e21f5b107924c0999eb396220f16dee99fc80ccba796e66e69dcb9ce278b7e0e4539c7a7cd0fbc1037bf8e56c1e67","up":true},{"one":"6c2788dec7ae7a77134065afc1174bb92b87833e87acaa72fe9e62c92d2017f217f9fbc5884cdfb7236a7bb75e463e49ecceb1641a8629516211d9699587046e","other":"9c8fca41b833e88110559b9258653160f5fb236bd637272ac58fe1adf333f4df75b94a805eaebb9f10a8c1a26d357dd75140560551d3fc4da79da2c4fc9479c3","up":true},{"one":"313a131ecb7d68e127d0fec8bb4a2e586886203c3d07857a93e7a39bb831703184d9ae28ba9ef3d986c2dae1a24f4f5bfa47cfc35f74f5512a126836364d7736","up":true,"other":"e0a043f98b462f10f72aa61ceda52f9c27829d086f6f2c5bf4db4fe32759002e5ff9519495d57dbb83d963a1dc991a1defcf5b9ef0d543789f38c68f5d07122b"},{"one":"5319bc9864d87eb33f26ff9732824d21a0a5ab70b254bc70a47554ffc763ae1559000d07e3eac9f883bd9e7f249d80edf14ab39c89c375bfcc5ec9e840ec9673","up":true,"other":"9c8fca41b833e88110559b9258653160f5fb236bd637272ac58fe1adf333f4df75b94a805eaebb9f10a8c1a26d357dd75140560551d3fc4da79da2c4fc9479c3"},{"one":"51df4f4d4f020f22f55a5fd00c7f9c68c232c167ae4d4e80d7695f8f39c5aa0a7b565c1c55bdd6a21e06fa056549d08fd2e9d76fd79e21295557aa30d1ae022c","other":"2c976b6007cda135444233c7bd03d22ac9756710b746c36bc032e7fdd42f2ffb89ca5f5e754ff96b8f3cbc474e346287e5b8531d9f98fd63c426c632872220af","up":true},{"one":"8ec699020ab5e7719fe23b80268b5d1d37052bb71f5d81200ae805cf27825823733206165f0a7507c2595853361dd122e9ec1b2deb543591e22b71ec0b873b5b","up":true,"other":"90b8e73916046b5433dce049bfe125ca2bf2fb390ff7301f9bc5d8d0183988577aa2a7392aaa28091aa81c8ac23942b5751420b9ee48e488a68411f9d2b1e5d5"},{"other":"da22fb43c6d230d92f9c09454e282dc45dffc759740566039f1bdfb58171c6801f721841de83217277b3fb70983e7d34da53bbf25d1d45413a78d9afff151826","up":true,"one":"a48cd04cdc66e1bb182529a789e1417d60d5e7d0f73068c1b17c6f231defeb943357789123e8d89cad90d1dd1726c48b808300d213bc1ddf7ae43cd58527f1f3"},{"one":"3b71a324bd7b1a8fb19d8206eea1ca8190cb1faf5fcd1bfc52cef6b52296fe1db3e54d70180133fad1fa1188499d0dd73d2d075fdc6b3ffd9042d690e7d88e02","up":true,"other":"dbb6621460b054f584f1c6157b4020f3c58d84c3a12b57436e10525ae60ab27036bf3edd68b92f2b13674877d01c2871dc67a9031c3d0470985f4b071696346e"},{"one":"29acdd4c1233441bd40f98e245ecc9de94de6f9d0ab7c1a9923d833a2c8e6c1bd26d792686fec762b31fe28bbdd7aa04c9a594d997d08c133bb24cb2d877595a","up":true,"other":"2c976b6007cda135444233c7bd03d22ac9756710b746c36bc032e7fdd42f2ffb89ca5f5e754ff96b8f3cbc474e346287e5b8531d9f98fd63c426c632872220af"},{"other":"ab8eda9b360d3e0b002ba31d48311057880844b828ad9817a2ad19736860d0114d4a17e9e9427c842d52e7ff61a09c2cad9b70f506e338909535542dae38ede0","up":true,"one":"45d3827eb5c3b906fc61aaad79c5968f3dcf7b1ecc1e3be63e827ad6fb9291542686f42b3e142f43cc0437a2177b7362727842ea1d6c33bc795d936bba3ae457"},{"other":"96cd4caa32c0b3a3493e24e13fad1ef75c621005d74154c3fc8a73cca4c0120452b6432334d94849c63f75d56a2943a453c86d2a14ad1fb61ae6833e58451187","up":true,"one":"9d372d73848389cfa1676f0cdb030950980ed5b68d5b2ef8a058f1d2095b26ff0fafab5fd3c243296ee2620edc67752970ab47370270856287f8612d1b190a19"},{"other":"ea2921612b827e3c26328368bed9be7cbf1f2b2aecaf31863c9cdccd74c56b651d6eaceb8ac9609a6653488837ded310df91e53a74789ae75cb841e2aeaf96df","up":true,"one":"869cae165389e7dee7b7df4e012ee1a39737366c306d8f4b0db4510b2236e0bd3a4d1d4af00b1a8c1d360e23da47de52fc1632edb03c7f1429aacc8aa4994750"},{"one":"02fdbcb00f20a3f6e894900d798fcb0aca9e21f5b107924c0999eb396220f16dee99fc80ccba796e66e69dcb9ce278b7e0e4539c7a7cd0fbc1037bf8e56c1e67","other":"9e21f5d4cfb389ac3ad43497689878bd245a89c587a8637d832b1e355ba244f4c83e6499bc7936e6d35645db25910ecd89b9af9b6b2f0c7cc4d7c6114328d7bf","up":true},{"one":"37399617d62153bc471f3bf21c92385bc8602c80ffa0c71da8aebae595a9859cfd56257aae60ad30ef3ec4d07dee90623cce63749c8c3233c0aa0d17f9e89afe","other":"3e2241cdb9f34c1d2c6930e59940e2c4b92b0287579d7263a620a609c5e66dca6d85df48cf1bffd63663a6704c42d0866aae3e484fd9a44b6a012f72dd3cef6e","up":true},{"one":"e33a1476fcb8d2a1b9ee15871a960ce7a3337c93f5956a2825b1f8b2885dbdc0ed652b1eba549523866632b5b6898310bc638d946a9fcce27d65117eb44c25f3","up":true,"other":"fd0123c7b96004067e98e463e273de5bc5402399ae70a95985b5f682e30d4f35d070deaf8c71d201e98c4324d832b95aab7535ad8a2658f66e3e0bb1202204e1"},{"other":"51a570637394e9ab61fe95b3a608cc4e9dc8ceb63efe717938ccd4260a962d52e01b30e7034fbfdabd9a3c9616ee569550b38a6d6b4b19847f523254069a9f27","up":true,"one":"7465fe601a9ad8e640069e6e07d56afabd3d4f008f3084f944d869b47fda3f511f191062802a53da511f60891dd0bcc5fac60254ef9db7aa3b41f5791b0b6975"},{"other":"c0f233e79d0a8d4af01f54c40640975bc113f464271ba8922fca0c28acc60367af0db06629e701977e86cb5917c891e39c21418cab459fe49132b680aa31600b","up":true,"one":"f4cdaeb513aa98f8868d8eb3a1d12c07367725928a1bc7d6ca4b583788e111a955463037ec7867260511896d97dfbf096aa77ee8a7d9ea1c06cad4a92c45108d"},{"one":"a8fac88fba179fb9b259d94caac9cbe45d873a0131bef8844ac4383b177daf6f301f8793623fec5876885db1a91e5b3e98e2aafdaa47e03b1f6d9740f48af7ac","up":true,"other":"8e89fe4b3fffea8af247d2581aa511056efbeb796058d50a341d57aa0f7ccc2192d90cfb8d18558363df798567faaddb86815e8bd671b36ca37af0651535aabf"},{"up":true,"other":"7b4585f8a4e4904239994a1b8bdc76299da8e46a8a632fabc6c33dd4170f8f3715e4c4f526ea5dd14093b150855960e432b1b140594aca21995f9e0722fb57f1","one":"7a8cb96685c1b8fbaeb18c8dc1f9f2631b23bc035e704e2f5df915b8bcabd6e2025ddc30324c69833f86e577b250c0721fee9d294f3e22016ae4c59c5f88845b"},{"one":"c6ad9b9de5cdbe28540f4eb7c66fb37f6d4295e6e60c6de54e2a45c1970b8e0047558e986bbd10e9e86c8bb0407846fac4823e4570e8a1486fc4bf55cb4a0986","other":"855667650e96c5ed2d9b0c82532ed1fb92f72b1ae926afafe09cf8f6e90e539aec5c4c2ab108f2c2a1ad7dd8b83ca92a98c550a1c9ed27e6632a7d2f6da4f970","up":true},{"other":"2c976b6007cda135444233c7bd03d22ac9756710b746c36bc032e7fdd42f2ffb89ca5f5e754ff96b8f3cbc474e346287e5b8531d9f98fd63c426c632872220af","up":true,"one":"855667650e96c5ed2d9b0c82532ed1fb92f72b1ae926afafe09cf8f6e90e539aec5c4c2ab108f2c2a1ad7dd8b83ca92a98c550a1c9ed27e6632a7d2f6da4f970"},{"one":"2bea7540c99456ea889a8ba2e448c11e6257bf987d01f13eea48128ba58577ab0936855035ee140c9907e382a34ca85a179c74892cbd9eb92fc2b35601addc6b","up":true,"other":"e5cb29b25debcfaaacc0b04e708c8c1cb9d2dee29e82596a1c72a934032cf738800b9525cc277d0c5f5dacf2f278329b54da161b4bafa285243fa0e9fd7b2f3a"},{"up":true,"other":"1cdef98d7b4de45c902c725384bd14c66084fe4159b26a0f9a24f432e1f561d035ca41e1c60fe64f3213b4f91a1afb953193dca1a7d535be0602b5d046bcbab8","one":"e9cd25d1ef3fef22160bce7f7badd7646ac58ee40da6a438f61a067c51bc51d6087ed950ec9e909bc438ebe62e316cbd9489f3c9bfa2898615632414e04f1dcd"},{"other":"6c95c653e15bb99d32656f35790400134cd7188e063f878e19cb9118eb469ae0362dc45255f2a1eae31520be01d42b5bc5bbebf03d644c9f206ca79cb33a01ad","up":true,"one":"1489ad735e1256900e4733707f8b78f1d853742a8f9b2d0c1c89651c60e7ee9d266afba5b4c1ed3f9cee05a1d2b2bba35dadb5b08973a93fd70dfb9e367339bd"},{"one":"e33a1476fcb8d2a1b9ee15871a960ce7a3337c93f5956a2825b1f8b2885dbdc0ed652b1eba549523866632b5b6898310bc638d946a9fcce27d65117eb44c25f3","other":"06aab75fed9a03f5525e3f1d8f8997fefaefd5b16e8f485d571beda00b1741efbb61a8a74fa12c2f6de66227c3fabb4d411659cd9c7b1ef32e171e6bf517cc39","up":true},{"one":"81dc656de121016bcde81d5bf7919839acfc180dfbf1a6de2cadf704ff13af98aa5715a4168832ca6f651b2ea7ad9e6ca5f1c1cb7e885dbc2eb23d4aefb87bd6","up":true,"other":"4b332b389f1142c0da42aaeb2e2692081d0002de0eb6741b3269e898a8101571d4556b755f2e8841e7a607bb41e398d2b0577fbe71098e7097f0fe6c720e1526"},{"one":"d43bd6d3ae39a04e4e144a8a6f80b2d54472b5b9b6491dccf44b1716a63d24c56e3a871b3b8fe983d992988dc07ace06736ead3b1287914b629fcfe17e81f36f","other":"884d32d09dfef937f3ef1cd6fb5f530c2c574487c0ffd4185ca405c8b2ac73044a196c34352e850ce15321eec6579da654a696381f3e5830d03c7aa18923da6e","up":true},{"up":true,"other":"7a8cb96685c1b8fbaeb18c8dc1f9f2631b23bc035e704e2f5df915b8bcabd6e2025ddc30324c69833f86e577b250c0721fee9d294f3e22016ae4c59c5f88845b","one":"4eab70233789c544bec97040a04099494bf269a819584a5d0b42295c918a52b02f224a8ed127aba3d92c02f567356bea4b95f77230ef548dfa7fe44b643d8704"},{"one":"9c8fca41b833e88110559b9258653160f5fb236bd637272ac58fe1adf333f4df75b94a805eaebb9f10a8c1a26d357dd75140560551d3fc4da79da2c4fc9479c3","other":"e9cd25d1ef3fef22160bce7f7badd7646ac58ee40da6a438f61a067c51bc51d6087ed950ec9e909bc438ebe62e316cbd9489f3c9bfa2898615632414e04f1dcd","up":true},{"one":"dd6acfd151220f21b03701ca554a5e134dbd1154dda21d9eec45809e7858fe83eca3953fc688f499030198f22052c3681a9f49207ef9b11a760456ab9637352b","up":true,"other":"ab13f773f6f2ff73032aa5f79c8897b75dda29bcbb14aa511e9401c2417dc9c510253071e28c7833c8d62fd2aef16fcd0c14ce016fbf4fec1b9a2173c717603f"},{"one":"ab8eda9b360d3e0b002ba31d48311057880844b828ad9817a2ad19736860d0114d4a17e9e9427c842d52e7ff61a09c2cad9b70f506e338909535542dae38ede0","other":"8e5e8366251e33277e7db6f6c04629b2ce3eee217e973acb97c83773671b0160c40732794584db741a29a763672b90f3bdf34151fd4a6986b9d0956dc61d9723","up":true},{"one":"89d46e664ac471c7150fbfe43a49c98750fc64d5ca22fdc2a040c7ab78c25c48c1e9c2f0e5130d6b8eb7f0760fe962759d83f68cc08ffaac3520499b0ce694de","up":true,"other":"3dcf18c35593b47bc463688493b792d6b9d13eabe05396e491953608f20cf55f770fc21be32b00335fcb2f0ba02735b92569b2b64a44c344ac348042876e8f15"},{"one":"c0a2c08fa8b70ecbf1932254945d5f689b0da7a287019d384152f383f6229acd4d82eef26205bc12e062dae4569814bd1c996ee4fe5886bd6bdd93c4f0ac113a","other":"96cd4caa32c0b3a3493e24e13fad1ef75c621005d74154c3fc8a73cca4c0120452b6432334d94849c63f75d56a2943a453c86d2a14ad1fb61ae6833e58451187","up":true},{"other":"aa53ca208cc0c9e544fd9d52cab44b5e2887256bb006037b855b5c94d7f79c9388fdbb23c0bf1d2eee12d67125e082fa7ecb34c1129ca8eaecfd85772b009435","up":true,"one":"1cdef98d7b4de45c902c725384bd14c66084fe4159b26a0f9a24f432e1f561d035ca41e1c60fe64f3213b4f91a1afb953193dca1a7d535be0602b5d046bcbab8"},{"one":"8e5e8366251e33277e7db6f6c04629b2ce3eee217e973acb97c83773671b0160c40732794584db741a29a763672b90f3bdf34151fd4a6986b9d0956dc61d9723","up":true,"other":"a5f7163586fce1750fd9a6e5c418af1c18ca6983069dcf1738fc9106ebf542a86e4ccfc50b45a0d97ca8681af8207128877f930f945e59ee262aa7f4014a01f3"},{"other":"bdd17545242bedba1e4c36fadea95db655f8f220f10ae143084690a3c8d4e7ffb79a64af9f1bc8514addbd63695b2f20857e8d162f25318faac885f77b385138","up":true,"one":"9d372d73848389cfa1676f0cdb030950980ed5b68d5b2ef8a058f1d2095b26ff0fafab5fd3c243296ee2620edc67752970ab47370270856287f8612d1b190a19"},{"one":"5319bc9864d87eb33f26ff9732824d21a0a5ab70b254bc70a47554ffc763ae1559000d07e3eac9f883bd9e7f249d80edf14ab39c89c375bfcc5ec9e840ec9673","up":true,"other":"6c2788dec7ae7a77134065afc1174bb92b87833e87acaa72fe9e62c92d2017f217f9fbc5884cdfb7236a7bb75e463e49ecceb1641a8629516211d9699587046e"},{"up":true,"other":"5319bc9864d87eb33f26ff9732824d21a0a5ab70b254bc70a47554ffc763ae1559000d07e3eac9f883bd9e7f249d80edf14ab39c89c375bfcc5ec9e840ec9673","one":"45d3827eb5c3b906fc61aaad79c5968f3dcf7b1ecc1e3be63e827ad6fb9291542686f42b3e142f43cc0437a2177b7362727842ea1d6c33bc795d936bba3ae457"},{"one":"e9cd25d1ef3fef22160bce7f7badd7646ac58ee40da6a438f61a067c51bc51d6087ed950ec9e909bc438ebe62e316cbd9489f3c9bfa2898615632414e04f1dcd","up":true,"other":"6c2788dec7ae7a77134065afc1174bb92b87833e87acaa72fe9e62c92d2017f217f9fbc5884cdfb7236a7bb75e463e49ecceb1641a8629516211d9699587046e"},{"one":"f8a5ae50e5b2d84096c10a6a8493a9eb8113df64c4f1336c0cf4649302649b158fa4cb7941591e55356891bcc1008a535df427546af19988a241c5f466467963","other":"69f999937943be00e5fca5c7cc942ce13b6752a72813368da2fbfcf74ad807bc6edd85537e087b6f73c0469c7b76a5d8f7d883bd315f3b35af32b8da293ed243","up":true},{"one":"a25958cf192a4f62301feda5d442535f78b983dd9e4599354f4898c8c1e6ad97ca7112549e1d1a1eacb4682cd1bf8b762368b5905ab33dbdacb585b128514ca1","up":true,"other":"884d32d09dfef937f3ef1cd6fb5f530c2c574487c0ffd4185ca405c8b2ac73044a196c34352e850ce15321eec6579da654a696381f3e5830d03c7aa18923da6e"},{"other":"228b3646b15527f4df07b847a62dbf9620cb068f829e9086b5f437d0b64d8a027cab44f19db5e44189b5099545ecb25d49384c261748f9533cfb0eb11a1eca5f","up":true,"one":"f52281c227aa82a3bd5fabfdcf8bdf1d9ea6739ab9b9075340143d59b4f2f8a79a981609c9f42823a0253c19a7281eed0e912e4054363ab7fe50117563ef14e0"},{"one":"4eab70233789c544bec97040a04099494bf269a819584a5d0b42295c918a52b02f224a8ed127aba3d92c02f567356bea4b95f77230ef548dfa7fe44b643d8704","other":"f52281c227aa82a3bd5fabfdcf8bdf1d9ea6739ab9b9075340143d59b4f2f8a79a981609c9f42823a0253c19a7281eed0e912e4054363ab7fe50117563ef14e0","up":true},{"one":"6b082a09e343a160b60a01f74641c1d707b2fa8fee5f6f5a8b9e4a203bd86434227d2df982b246a752f843483cdf517e85fe3bd65453354232a6eb38dedbf314","other":"f8a5ae50e5b2d84096c10a6a8493a9eb8113df64c4f1336c0cf4649302649b158fa4cb7941591e55356891bcc1008a535df427546af19988a241c5f466467963","up":true},{"other":"c674c405068bb908312917a319e24ddf90e814ee8ef54bbf740f176b2a7eda6950e3e1ed69484ebcc27b13d82c7f0b20daba71a17700018e769ca612ca8d2208","up":true,"one":"e323da6ae861cb092543992b8985639f9b3bcaf1c3c68757f4603a67800be62950fe7d8f8ef80eb83a18107b677c7f5047ea89a5790e0ea2a7969f4856d28488"},{"up":true,"other":"bdd17545242bedba1e4c36fadea95db655f8f220f10ae143084690a3c8d4e7ffb79a64af9f1bc8514addbd63695b2f20857e8d162f25318faac885f77b385138","one":"740919ebae9b4fe646ca716ebb8923bf2a1b1963767d86f55ea95911d88d163cc2e07b1420669e64b62cb267b625413444b783b8e4a7bd6a0f481f4d84e984b1"},{"one":"dd3dccc1758765569905b3b137ef4c7dd31c2dc0dea827bcc4c4e976be94ffbb0f2ef6fe725cf9042063a96d663efea546837f35ca1fc67a854fbc9e27abb754","up":true,"other":"8e89fe4b3fffea8af247d2581aa511056efbeb796058d50a341d57aa0f7ccc2192d90cfb8d18558363df798567faaddb86815e8bd671b36ca37af0651535aabf"},{"one":"dd6acfd151220f21b03701ca554a5e134dbd1154dda21d9eec45809e7858fe83eca3953fc688f499030198f22052c3681a9f49207ef9b11a760456ab9637352b","up":true,"other":"884d32d09dfef937f3ef1cd6fb5f530c2c574487c0ffd4185ca405c8b2ac73044a196c34352e850ce15321eec6579da654a696381f3e5830d03c7aa18923da6e"},{"up":true,"other":"06aab75fed9a03f5525e3f1d8f8997fefaefd5b16e8f485d571beda00b1741efbb61a8a74fa12c2f6de66227c3fabb4d411659cd9c7b1ef32e171e6bf517cc39","one":"2751df9f64a8f2ff8ea45efc9bd02b281d963ced285260bcda7f9dfaed998fe4386fe65a7265876da6b4fee77ea5c12454869a70ad627da7ca888076fc629665"},{"other":"e5cb29b25debcfaaacc0b04e708c8c1cb9d2dee29e82596a1c72a934032cf738800b9525cc277d0c5f5dacf2f278329b54da161b4bafa285243fa0e9fd7b2f3a","up":true,"one":"4b332b389f1142c0da42aaeb2e2692081d0002de0eb6741b3269e898a8101571d4556b755f2e8841e7a607bb41e398d2b0577fbe71098e7097f0fe6c720e1526"},{"one":"e0f13606a7f35b9ad8a9c4e70336c4c554ac718720a451a349eb4e1a4b055079483cac040ec64e0ed3d8bdb336618a5ae6ef74e31642fae4d7ed9949858eb361","up":true,"other":"8e5e8366251e33277e7db6f6c04629b2ce3eee217e973acb97c83773671b0160c40732794584db741a29a763672b90f3bdf34151fd4a6986b9d0956dc61d9723"},{"other":"d6747e1f8594f7449fc6d7c0e63ee843480567d498db096ff04229420861c83bca5215fc19d8fede0c54484f111f1f2581e189e638c21c5d9e1fd3174bbb3e98","up":true,"one":"2880e0defd1bf2665bdd20dfb46bc0a9ad707f495211fc78e611ab479d78398db7daff7d3f4b6bf81fd13bf766ecc8271e0ea99a2d74abd2f9ddf98835ffdcf1"},{"one":"2abb91884cc3a8fb91b2f2f369f9430f2b3b05c75ce6203aa7a50312c9f141f9d0f615063d3576a5ce8a4be9ecb942aa804a717f76d9e8dca03d115dcc43f775","other":"e33a1476fcb8d2a1b9ee15871a960ce7a3337c93f5956a2825b1f8b2885dbdc0ed652b1eba549523866632b5b6898310bc638d946a9fcce27d65117eb44c25f3","up":true},{"one":"dd3dccc1758765569905b3b137ef4c7dd31c2dc0dea827bcc4c4e976be94ffbb0f2ef6fe725cf9042063a96d663efea546837f35ca1fc67a854fbc9e27abb754","up":true,"other":"c03ef1de42d522b44eef53be11f2c57b8b74fed9e87e6c2928c1feb48ddfecc67e1a3a8c8be1c47b3735a216d7054e2a4dda49fbd9a1ac702146aae5bdeced7c"},{"other":"d3cd2f34f67830ccdc295b7537a6d27c02b44503808ca666124f52ecc3d6c35b7d3f14343997006aef2cfbefc8d27809d389477e99c236b9f8a897a4bc406a43","up":true,"one":"06aab75fed9a03f5525e3f1d8f8997fefaefd5b16e8f485d571beda00b1741efbb61a8a74fa12c2f6de66227c3fabb4d411659cd9c7b1ef32e171e6bf517cc39"},{"one":"f8a5ae50e5b2d84096c10a6a8493a9eb8113df64c4f1336c0cf4649302649b158fa4cb7941591e55356891bcc1008a535df427546af19988a241c5f466467963","up":true,"other":"51a570637394e9ab61fe95b3a608cc4e9dc8ceb63efe717938ccd4260a962d52e01b30e7034fbfdabd9a3c9616ee569550b38a6d6b4b19847f523254069a9f27"},{"up":true,"other":"d6747e1f8594f7449fc6d7c0e63ee843480567d498db096ff04229420861c83bca5215fc19d8fede0c54484f111f1f2581e189e638c21c5d9e1fd3174bbb3e98","one":"877d17ec7e95998ead831606d3363fbff1c8d1fa377b8e621e6a876d2c7776b9af356211a7e4df66adeaf38cf9b49c04871e8804edde4c18435ff45e110ecb04"},{"one":"a5f7163586fce1750fd9a6e5c418af1c18ca6983069dcf1738fc9106ebf542a86e4ccfc50b45a0d97ca8681af8207128877f930f945e59ee262aa7f4014a01f3","other":"7465fe601a9ad8e640069e6e07d56afabd3d4f008f3084f944d869b47fda3f511f191062802a53da511f60891dd0bcc5fac60254ef9db7aa3b41f5791b0b6975","up":true},{"one":"842f0ac24370f14edfe72a7d07219de60fc767d2d0356fa6ce9d535a43647ad4bb17d9be75ed83542868ba430ec104ba168f27c16915cdbd6e57ae62d60707cb","other":"0e164c8692532e59c76ef84319a1093324f46f77618d3a836a279df52edca6c839061c0582dac7481da1bd0f3e2b58fc0dacd6ee5d678ba1406d4a1a25fe761d","up":true},{"one":"e5cb29b25debcfaaacc0b04e708c8c1cb9d2dee29e82596a1c72a934032cf738800b9525cc277d0c5f5dacf2f278329b54da161b4bafa285243fa0e9fd7b2f3a","other":"77811b007dd1fc1b11e447858df37062e97b6fc14e059399814f3b4736188e3fb28bf7c3958bb8ebc6ae16c36884ba7c98b810fb6f8b358323412123c803abd4","up":true},{"one":"be93fafaf43f6bb3efd2667d1468a8636cb752b245328eaa01468c0606d790322a7cd8e47857068e60118e28b8dd8aa1d2d4977c5b3d28d4b47f4c0658f05e90","other":"884d32d09dfef937f3ef1cd6fb5f530c2c574487c0ffd4185ca405c8b2ac73044a196c34352e850ce15321eec6579da654a696381f3e5830d03c7aa18923da6e","up":true},{"up":true,"other":"8e89fe4b3fffea8af247d2581aa511056efbeb796058d50a341d57aa0f7ccc2192d90cfb8d18558363df798567faaddb86815e8bd671b36ca37af0651535aabf","one":"2bea7540c99456ea889a8ba2e448c11e6257bf987d01f13eea48128ba58577ab0936855035ee140c9907e382a34ca85a179c74892cbd9eb92fc2b35601addc6b"},{"other":"002cb6ffa63ad71ee6ebc1df4c41f7a97c51f274b1d3b22420c87b73136be5169b9670508061d8261e20055fefce3b855388994672aa9a0f1475c43839aae4fa","up":true,"one":"876618c8ba66c1b91b473a154be3e10ded3590ba83d620d30e0ff1fbac2f31f258b1299a3da5b56aa03269a80c119b7fc41dfd87d5bd996359e4ad8dd0ab2a6a"},{"one":"81dc656de121016bcde81d5bf7919839acfc180dfbf1a6de2cadf704ff13af98aa5715a4168832ca6f651b2ea7ad9e6ca5f1c1cb7e885dbc2eb23d4aefb87bd6","other":"95ff4dea07303e1ba641a5c510e714ef232f4dbce9ad2e8b2f62644975eae41fc4bb9d1af3fae4d5ea4daeb18f8248e0b3131c7d843d35d33f3afbf7dfa4c2fe","up":true},{"one":"d43bd6d3ae39a04e4e144a8a6f80b2d54472b5b9b6491dccf44b1716a63d24c56e3a871b3b8fe983d992988dc07ace06736ead3b1287914b629fcfe17e81f36f","up":true,"other":"77811b007dd1fc1b11e447858df37062e97b6fc14e059399814f3b4736188e3fb28bf7c3958bb8ebc6ae16c36884ba7c98b810fb6f8b358323412123c803abd4"},{"other":"a5f7163586fce1750fd9a6e5c418af1c18ca6983069dcf1738fc9106ebf542a86e4ccfc50b45a0d97ca8681af8207128877f930f945e59ee262aa7f4014a01f3","up":true,"one":"e0f13606a7f35b9ad8a9c4e70336c4c554ac718720a451a349eb4e1a4b055079483cac040ec64e0ed3d8bdb336618a5ae6ef74e31642fae4d7ed9949858eb361"},{"one":"869cae165389e7dee7b7df4e012ee1a39737366c306d8f4b0db4510b2236e0bd3a4d1d4af00b1a8c1d360e23da47de52fc1632edb03c7f1429aacc8aa4994750","other":"95ff4dea07303e1ba641a5c510e714ef232f4dbce9ad2e8b2f62644975eae41fc4bb9d1af3fae4d5ea4daeb18f8248e0b3131c7d843d35d33f3afbf7dfa4c2fe","up":true},{"one":"ee0b09ee6a1057c47102e582e2fdec7b9212802e59f062a9360da0db535d4987126ab24848c0d76fa8485431a5140307e2b0c0d9f37cbdb35756e6cc1bdb3bc0","up":true,"other":"57085f756f76644cdd2148524f2334d869ef0ab2fcbe7fb11f5d22bc1f5023165b11526ecc85ff9cbb88877386af9b148d7ef15a825b3a586d16c01bdfc86692"},{"one":"8e89fe4b3fffea8af247d2581aa511056efbeb796058d50a341d57aa0f7ccc2192d90cfb8d18558363df798567faaddb86815e8bd671b36ca37af0651535aabf","up":true,"other":"b7cc9044d021b19cd8a6d290d21f1c91fd5deec472583d0aeed0a6aacc8efef9968079254132becc5443df14dd3f4feaee56d14b885c078649727b9659139fa6"},{"up":true,"other":"4b332b389f1142c0da42aaeb2e2692081d0002de0eb6741b3269e898a8101571d4556b755f2e8841e7a607bb41e398d2b0577fbe71098e7097f0fe6c720e1526","one":"06aab75fed9a03f5525e3f1d8f8997fefaefd5b16e8f485d571beda00b1741efbb61a8a74fa12c2f6de66227c3fabb4d411659cd9c7b1ef32e171e6bf517cc39"},{"one":"4b332b389f1142c0da42aaeb2e2692081d0002de0eb6741b3269e898a8101571d4556b755f2e8841e7a607bb41e398d2b0577fbe71098e7097f0fe6c720e1526","other":"884d32d09dfef937f3ef1cd6fb5f530c2c574487c0ffd4185ca405c8b2ac73044a196c34352e850ce15321eec6579da654a696381f3e5830d03c7aa18923da6e","up":true},{"up":true,"other":"a8fac88fba179fb9b259d94caac9cbe45d873a0131bef8844ac4383b177daf6f301f8793623fec5876885db1a91e5b3e98e2aafdaa47e03b1f6d9740f48af7ac","one":"243164c4dd583f80c50813f43e5c27c894463400cd3afd776b36e79e7123d9261f01f06f92914aab83096b9a43fb655e79687590599284640a3a7d2c25454597"},{"one":"e33a1476fcb8d2a1b9ee15871a960ce7a3337c93f5956a2825b1f8b2885dbdc0ed652b1eba549523866632b5b6898310bc638d946a9fcce27d65117eb44c25f3","other":"1b3107d9a96cfd11f4cd0ed8baeb7b23db1406c9c4a9dac76c772f49c0fc9404f6a4adae11120aa821757173f0cc1cb00e6ab555b5abffaae9001c0557cb75c9","up":true},{"one":"a5f7163586fce1750fd9a6e5c418af1c18ca6983069dcf1738fc9106ebf542a86e4ccfc50b45a0d97ca8681af8207128877f930f945e59ee262aa7f4014a01f3","up":true,"other":"c69b9b181b2756a1345b73a97afb3dca909c253188c3b905f0b414465b750d2ffccb4c8e8eb5e3809549af55db473f3b12682f9bd97c5c75d68f23d67d91b866"},{"one":"936fad959da2d8b0cfb2bcd78c5da65bcce5e9463be7fc7367f45cdfa20678f4c466fb1e3f600783a270855fd4b9cd6265054f79ecb116141e7c67a492041bed","up":true,"other":"3948a7a939b9a1f4201953bd9b955ee7be87d09b63c7a45167f556ac06fe3c4c2a75d935bff50668da5e71e46802b55d7a9945a92d7807c00625d129cbb48f82"},{"one":"876618c8ba66c1b91b473a154be3e10ded3590ba83d620d30e0ff1fbac2f31f258b1299a3da5b56aa03269a80c119b7fc41dfd87d5bd996359e4ad8dd0ab2a6a","other":"d6a7257771baa4d9944592ead46b8ab700dbf91ebd4dc0ec7e5fb41cbda0622944269172fcec8352b89ef2c186d4c787af2b45a50533f627a97818477de034b4","up":true},{"one":"c0f233e79d0a8d4af01f54c40640975bc113f464271ba8922fca0c28acc60367af0db06629e701977e86cb5917c891e39c21418cab459fe49132b680aa31600b","up":true,"other":"6c40910f0556f892a7542989fa01d7e3682fca89aeefb5ed885808f88ff17b6d13862f461c10d629a005ae67abef542d75e5b20816891b6944f71560f5c2dfa8"},{"one":"842f0ac24370f14edfe72a7d07219de60fc767d2d0356fa6ce9d535a43647ad4bb17d9be75ed83542868ba430ec104ba168f27c16915cdbd6e57ae62d60707cb","other":"7a8cb96685c1b8fbaeb18c8dc1f9f2631b23bc035e704e2f5df915b8bcabd6e2025ddc30324c69833f86e577b250c0721fee9d294f3e22016ae4c59c5f88845b","up":true},{"one":"df9306a263f40e0e255996500523354de3cc78b68ae560f66d79f6ea28f30f773f1fd6ebc33928723dfde2ee3d4f982b203bee4c3803a5050df83477045bb279","up":true,"other":"e323da6ae861cb092543992b8985639f9b3bcaf1c3c68757f4603a67800be62950fe7d8f8ef80eb83a18107b677c7f5047ea89a5790e0ea2a7969f4856d28488"},{"one":"b8e0a56df21baae43058f575b714ae9a33c097d18f1a628b3b6ae5e86dd46a06e44c0dc272baacb5be0f7bf57fd6ddce107544eb3b94dca1aeae9f5773496a72","other":"855667650e96c5ed2d9b0c82532ed1fb92f72b1ae926afafe09cf8f6e90e539aec5c4c2ab108f2c2a1ad7dd8b83ca92a98c550a1c9ed27e6632a7d2f6da4f970","up":true},{"up":true,"other":"7d9979c13cd8841e84e5d199fc263962ca6fee12664d8526a581bfcdca2e3427ca169b9a0244dd8292a9a1be2bcedb0e8f626eadd307068c11c03b6df13aee33","one":"b7cc9044d021b19cd8a6d290d21f1c91fd5deec472583d0aeed0a6aacc8efef9968079254132becc5443df14dd3f4feaee56d14b885c078649727b9659139fa6"},{"up":true,"other":"1c080e90760dfcee08ade6e4ea3b275ff3c6882f3b44b7f3a73d70bcc816fc63ce0b6138f810d17d96ed387076f9bbb6dbb2ef6dc4d6ba6542c1f587b7602a12","one":"43086ff7ffd3c7bdec77bd288f41f1ee0ce21bd3f60a5df8931e2af6e7af5ef0fad432d29625491935d11567944351fc7867c807ebd12dd2c21c9e620ae0f85c"},{"other":"222d7a2f94dc82a09fda70b8195fc3a60433a90f53998872318c57625c528c90572d78b444ac4901dcfece1a03ef8b6cbe7845366a845a942f341f6db58a9b3b","up":true,"one":"936fad959da2d8b0cfb2bcd78c5da65bcce5e9463be7fc7367f45cdfa20678f4c466fb1e3f600783a270855fd4b9cd6265054f79ecb116141e7c67a492041bed"},{"up":true,"other":"3e2241cdb9f34c1d2c6930e59940e2c4b92b0287579d7263a620a609c5e66dca6d85df48cf1bffd63663a6704c42d0866aae3e484fd9a44b6a012f72dd3cef6e","one":"baa28b8cb7ec539e0e157d7598cc5a5b0210fd8fb5c9026c3cd612133c5a8ee56997507511928af5683cb620fd85593dd8f6ff882d95fb847870ae4ce7dc503b"},{"one":"50c79baa3e6781482ccb5e960c699dd9c13f479467c6315c5292a396337cf3619e7faba1971a1f470051cb9042f80ea6750defe3936b72aac4d9bac6f8368c67","up":true,"other":"2b0a1f3a6466c6be1d7e84120db384fa37f7c73a01e9a105ae90e7d2203212ec974f016d3012afd26bc0f9a8411d0716cc59b6ecc9f665db12e306af8b34cb63"},{"one":"df9306a263f40e0e255996500523354de3cc78b68ae560f66d79f6ea28f30f773f1fd6ebc33928723dfde2ee3d4f982b203bee4c3803a5050df83477045bb279","up":true,"other":"b60def37233dbbc0d5f7fcddb304be1c0b6508e1e3d8a09a8290f7363e9bb84152dcaf70b8f6bb3a882fee77ff03ab796a5c1c3654f251c9f5c746ac5ad88556"},{"other":"6d0a09235ba0b0428938abf0e0782ac0ecf5697ef862888719a34fc956517aeef89d5e5f76d12e10067fee5bac8781dc10400eeb35c2393b9382b2a4f68f7939","up":true,"one":"51df4f4d4f020f22f55a5fd00c7f9c68c232c167ae4d4e80d7695f8f39c5aa0a7b565c1c55bdd6a21e06fa056549d08fd2e9d76fd79e21295557aa30d1ae022c"},{"one":"b4f300abda4cf6e383f997510eb681e9fa62e23577e3c19bd7447fa1f5702a4e034cea5944248e7c6e6e92b5ae69195c3e8a2c5ca7827b4f4a00cc8546e6695a","other":"5982e7dfd39c527851f6ea6430b70e654d95df5ec4401ca1d8dbd1034cf7a65d1126d60b36ebbd396c9ca32e6e8515f34f9dc0a8d2980afe4aa181c8bf68437e","up":true},{"one":"b7cc9044d021b19cd8a6d290d21f1c91fd5deec472583d0aeed0a6aacc8efef9968079254132becc5443df14dd3f4feaee56d14b885c078649727b9659139fa6","up":true,"other":"f52281c227aa82a3bd5fabfdcf8bdf1d9ea6739ab9b9075340143d59b4f2f8a79a981609c9f42823a0253c19a7281eed0e912e4054363ab7fe50117563ef14e0"},{"other":"ee0b09ee6a1057c47102e582e2fdec7b9212802e59f062a9360da0db535d4987126ab24848c0d76fa8485431a5140307e2b0c0d9f37cbdb35756e6cc1bdb3bc0","up":true,"one":"855667650e96c5ed2d9b0c82532ed1fb92f72b1ae926afafe09cf8f6e90e539aec5c4c2ab108f2c2a1ad7dd8b83ca92a98c550a1c9ed27e6632a7d2f6da4f970"},{"up":true,"other":"f4cdaeb513aa98f8868d8eb3a1d12c07367725928a1bc7d6ca4b583788e111a955463037ec7867260511896d97dfbf096aa77ee8a7d9ea1c06cad4a92c45108d","one":"57085f756f76644cdd2148524f2334d869ef0ab2fcbe7fb11f5d22bc1f5023165b11526ecc85ff9cbb88877386af9b148d7ef15a825b3a586d16c01bdfc86692"},{"up":true,"other":"dd6acfd151220f21b03701ca554a5e134dbd1154dda21d9eec45809e7858fe83eca3953fc688f499030198f22052c3681a9f49207ef9b11a760456ab9637352b","one":"ef7157fdfe62390d8a6d4ef976478d17465b42b63fddb03664973d63efb62318a8f59e412150528a32aa2c028b9de6bc67f05e012b8c43d710032ad871bc27e5"},{"one":"842ec3faa8b4a4cdec32abfa00ae827277fe2696e1b0c6551154533b16cf75ae69caf834b4f08488fa5c8b322fb633b1fd8a5b7d436e9c589cc9074dc031ae68","other":"99a7649bdf2ee7f0bc049308b0997e33abb68481c05a573df9aea30da5a1f267df07b2c584e3e985baf31704f04ad2a2c4876e0f8555333be6d09f5080b583f1","up":true},{"up":true,"other":"b8e0a56df21baae43058f575b714ae9a33c097d18f1a628b3b6ae5e86dd46a06e44c0dc272baacb5be0f7bf57fd6ddce107544eb3b94dca1aeae9f5773496a72","one":"fd0123c7b96004067e98e463e273de5bc5402399ae70a95985b5f682e30d4f35d070deaf8c71d201e98c4324d832b95aab7535ad8a2658f66e3e0bb1202204e1"},{"one":"1edeb91789b9aa996fea7a70964e0be33ee50acbe6d8f7d9d9fcf6dcf755dab6402637a610116f0eb716b19259429bdcced8bebc28ffa334387a430efc21b9b0","up":true,"other":"8e89fe4b3fffea8af247d2581aa511056efbeb796058d50a341d57aa0f7ccc2192d90cfb8d18558363df798567faaddb86815e8bd671b36ca37af0651535aabf"},{"other":"855667650e96c5ed2d9b0c82532ed1fb92f72b1ae926afafe09cf8f6e90e539aec5c4c2ab108f2c2a1ad7dd8b83ca92a98c550a1c9ed27e6632a7d2f6da4f970","up":true,"one":"545237d8463b75fd2e9bbfbffb35c5b78b4abbc85f6bfbd56976789012dd9a62ca1f866bf37bb33618e026aab764adb9ced5e00cd415562f69992f74c795083f"},{"up":true,"other":"99a7649bdf2ee7f0bc049308b0997e33abb68481c05a573df9aea30da5a1f267df07b2c584e3e985baf31704f04ad2a2c4876e0f8555333be6d09f5080b583f1","one":"c6f38fe8a0f2b3773bae332e0ca7516e944bde186fe99daae10a2b0aecde3ce23c1834eaad97a4e6d2da8cd53a08dbafa72d2b827c851b115b74e8010125dba2"},{"one":"ef7157fdfe62390d8a6d4ef976478d17465b42b63fddb03664973d63efb62318a8f59e412150528a32aa2c028b9de6bc67f05e012b8c43d710032ad871bc27e5","up":true,"other":"936fad959da2d8b0cfb2bcd78c5da65bcce5e9463be7fc7367f45cdfa20678f4c466fb1e3f600783a270855fd4b9cd6265054f79ecb116141e7c67a492041bed"},{"one":"29acdd4c1233441bd40f98e245ecc9de94de6f9d0ab7c1a9923d833a2c8e6c1bd26d792686fec762b31fe28bbdd7aa04c9a594d997d08c133bb24cb2d877595a","up":true,"other":"77e40e42f570a217f707888c714deb31fd70c856ae4b9a44ec7cee02768185dc4d7ed210429607f06690b32edd9fb06b304aff330a3949cc2fd49db1bc392edb"},{"up":true,"other":"6d0a09235ba0b0428938abf0e0782ac0ecf5697ef862888719a34fc956517aeef89d5e5f76d12e10067fee5bac8781dc10400eeb35c2393b9382b2a4f68f7939","one":"5982e7dfd39c527851f6ea6430b70e654d95df5ec4401ca1d8dbd1034cf7a65d1126d60b36ebbd396c9ca32e6e8515f34f9dc0a8d2980afe4aa181c8bf68437e"},{"one":"c6ad9b9de5cdbe28540f4eb7c66fb37f6d4295e6e60c6de54e2a45c1970b8e0047558e986bbd10e9e86c8bb0407846fac4823e4570e8a1486fc4bf55cb4a0986","other":"51df4f4d4f020f22f55a5fd00c7f9c68c232c167ae4d4e80d7695f8f39c5aa0a7b565c1c55bdd6a21e06fa056549d08fd2e9d76fd79e21295557aa30d1ae022c","up":true},{"one":"1489ad735e1256900e4733707f8b78f1d853742a8f9b2d0c1c89651c60e7ee9d266afba5b4c1ed3f9cee05a1d2b2bba35dadb5b08973a93fd70dfb9e367339bd","up":true,"other":"3e2241cdb9f34c1d2c6930e59940e2c4b92b0287579d7263a620a609c5e66dca6d85df48cf1bffd63663a6704c42d0866aae3e484fd9a44b6a012f72dd3cef6e"},{"one":"02fdbcb00f20a3f6e894900d798fcb0aca9e21f5b107924c0999eb396220f16dee99fc80ccba796e66e69dcb9ce278b7e0e4539c7a7cd0fbc1037bf8e56c1e67","up":true,"other":"51df4f4d4f020f22f55a5fd00c7f9c68c232c167ae4d4e80d7695f8f39c5aa0a7b565c1c55bdd6a21e06fa056549d08fd2e9d76fd79e21295557aa30d1ae022c"},{"one":"24047e1a816cbf9b7a90e6c78dc896a3b624047ef5cfd3aa495132d57b1074aa129ea6eff171f5cca91d0f4793a07c9672b0a55232f2415c6220e443ebd0791d","up":true,"other":"682288e4dae2374c4784acd0b285508920ce39a6b72cc0e30a3dbb7972e0394a2bddd5ee5f22a1dbf80f284dde4d9f8ede7847318d5353566b35a83e212477e7"},{"up":true,"other":"510536aba28aa635d8a1098a6dbd2070748ce1eb0e14b54b93a21196543a60df546ff6a2b3b5b9f32a5c2a37f5aba77d0b74f28b2dabeeebf3fe5afc20a3209c","one":"60995852a2385ce8d7d24dc94b85a2f0dab6e5c32e910dfe367ea9c6ccb7b0b2eb611fdf120f8c697097e2f137cefff42e8d9db16b664a857a38c5ace837ffa4"},{"one":"b4557089e4247379e587a087f53b36dd1f86f85d9dcfab5dc562079978cd959adaef5b30d11258d9cb552e7c5abddf5377a71d449febe8f2acb0aec3ebd8ba73","up":true,"other":"b1dd1b08975319030626aab821032a0c687a103ee8942e8a2e2cf029dd72832a49630e78d2d8b184579f22178aca0e875f9fad701fb81afd2ac110ab2b417376"},{"up":true,"other":"48e35d67e14ee2f329c0275bc965829b761885dbc3671f4673d84d76d18a5b6415e619e219b5d90761a5c6bd2f43c6a58708286a063daf46b502944f8ef9230b","one":"3376cfc924fef1a45aae35d106439b131f363b3a42904b3974cc7cddde325441cce8551729dd62f1119120b0d452e78f063e8e711ecacdc27d9087aac5ab09b5"},{"up":true,"other":"93073da602d6326a48464a8b6890220b3aae0abf5b6961180f3aff2a14573c43411bd519d3e0012a646ec2977be18915d95a36d935a69f93985f5307ea4e3ebe","one":"b9c7b885430b9b1a4425bde30b3629559f5437e0e30a0299fc6f6e097cbcca8af9e285caf5dea685a0237f60e06f490c39a1e3e487f14a2b9f41a5135f2ba994"},{"one":"e8a679f627d03347a4fcec0a0940f7ffa90ce3fefea290db3af4f3a32d27965bfb51832b6a6de2495c8a8cc026bcf993b84a0cced778e158bb81c034f5e4bd76","other":"a47697063a2fb973449bdabd0925e10944ba1f6d8b2cc5c38b295f611eea3402b5cf3ae857716a34d84194955f5ed61350affe56223349124c8233852141f9a2","up":true},{"other":"5a235aca7005df295d5bd924b1272452e9bdad408ca5223b9eb76800b4bd4e3158a1d663ce5243fee92233227249fe4bb8507e8cb2c3729744b273bf488ba60c","up":true,"one":"1edeb91789b9aa996fea7a70964e0be33ee50acbe6d8f7d9d9fcf6dcf755dab6402637a610116f0eb716b19259429bdcced8bebc28ffa334387a430efc21b9b0"},{"up":true,"other":"46717bc5fb7fcbcdc961e7ef091020f9f222858cf3d4afcc0b0bb1b782b7055d9eb833e0a04cb32d80406133ac77162521c43edf9f9690872222760e31462ccc","one":"dbb6621460b054f584f1c6157b4020f3c58d84c3a12b57436e10525ae60ab27036bf3edd68b92f2b13674877d01c2871dc67a9031c3d0470985f4b071696346e"},{"other":"e5cb29b25debcfaaacc0b04e708c8c1cb9d2dee29e82596a1c72a934032cf738800b9525cc277d0c5f5dacf2f278329b54da161b4bafa285243fa0e9fd7b2f3a","up":true,"one":"d6747e1f8594f7449fc6d7c0e63ee843480567d498db096ff04229420861c83bca5215fc19d8fede0c54484f111f1f2581e189e638c21c5d9e1fd3174bbb3e98"},{"one":"aa2028d356a88eca8e0fcaf218d62ace099c3f72dfd95bb28f30ac9a926034cf1d60a40511f7495652745de80d71c0f6830019e206c88e2b6ef0cf4f05d7fe9e","up":true,"other":"535287ca3d41fc1cdf20a964749a849c51d0aba285f41f447cc2b1dd6f5845b6b98e0241dbda0718b234ea850081bfbf9df01d1aa636d7dcbd99ef3c0a773aff"},{"other":"57085f756f76644cdd2148524f2334d869ef0ab2fcbe7fb11f5d22bc1f5023165b11526ecc85ff9cbb88877386af9b148d7ef15a825b3a586d16c01bdfc86692","up":true,"one":"2b0a1f3a6466c6be1d7e84120db384fa37f7c73a01e9a105ae90e7d2203212ec974f016d3012afd26bc0f9a8411d0716cc59b6ecc9f665db12e306af8b34cb63"},{"other":"8c459100df488b992fdad207a096a434d67cb733619adfd09a311095568d4c9db293d9a892675551805559456d49a3fdb19c2cc698b14552bf0ace584d4d90dc","up":true,"one":"97b1eaf8274ece76d75e7f60126f1b351ed5fe55088b9fcbb825a3a8d8f84f61bc72469916b280497dabf01345057525cae89da73c9a1a8a8cd19367d44dede1"},{"up":true,"other":"b60def37233dbbc0d5f7fcddb304be1c0b6508e1e3d8a09a8290f7363e9bb84152dcaf70b8f6bb3a882fee77ff03ab796a5c1c3654f251c9f5c746ac5ad88556","one":"222d7a2f94dc82a09fda70b8195fc3a60433a90f53998872318c57625c528c90572d78b444ac4901dcfece1a03ef8b6cbe7845366a845a942f341f6db58a9b3b"},{"one":"c0a2c08fa8b70ecbf1932254945d5f689b0da7a287019d384152f383f6229acd4d82eef26205bc12e062dae4569814bd1c996ee4fe5886bd6bdd93c4f0ac113a","other":"90b8e73916046b5433dce049bfe125ca2bf2fb390ff7301f9bc5d8d0183988577aa2a7392aaa28091aa81c8ac23942b5751420b9ee48e488a68411f9d2b1e5d5","up":true},{"other":"6a37e63feed9e68c52cb8b385d5e8d8dbd2b211c57ded0d3b01fe8b306af5c0e5a7405d0d9a942648f0131926240d53450bc43f922a053528e5830d918313c3d","up":true,"one":"9d372d73848389cfa1676f0cdb030950980ed5b68d5b2ef8a058f1d2095b26ff0fafab5fd3c243296ee2620edc67752970ab47370270856287f8612d1b190a19"},{"one":"682288e4dae2374c4784acd0b285508920ce39a6b72cc0e30a3dbb7972e0394a2bddd5ee5f22a1dbf80f284dde4d9f8ede7847318d5353566b35a83e212477e7","other":"85c0b055439f114dee5eb0961013c117a48d62b0f17c61a7fd92a84092ef09bb3bbce686aa96e14528d5663565c57d657fa9813b1f38e268caeb1cb0842ef232","up":true},{"one":"643da2591098f9698f27cccf7c17832e0717ee6a1276398a1a29edc947125585dcfab9417c2721a8a55d4dfc75b826be7581b6e30b020f6341ac549877c9f122","other":"b3b4b203395bb6655d79ecdcee11638dd9a16baccfcc1f6fcc8b31832c8ca35650eb6c2802104eeec6d96ea80404381a2bd9b01dcadc748a4666b761d9ce64f8","up":true},{"one":"d6747e1f8594f7449fc6d7c0e63ee843480567d498db096ff04229420861c83bca5215fc19d8fede0c54484f111f1f2581e189e638c21c5d9e1fd3174bbb3e98","up":true,"other":"d3cd2f34f67830ccdc295b7537a6d27c02b44503808ca666124f52ecc3d6c35b7d3f14343997006aef2cfbefc8d27809d389477e99c236b9f8a897a4bc406a43"},{"other":"ee3471e1d835c4294f7ba642103039ccc548fe4edc177c79b63433ebbb0dc9d06600844f1fed76c7096ee9538e49e4e86fb8cffe9095dbdcde27695ff28ad395","up":true,"one":"89d46e664ac471c7150fbfe43a49c98750fc64d5ca22fdc2a040c7ab78c25c48c1e9c2f0e5130d6b8eb7f0760fe962759d83f68cc08ffaac3520499b0ce694de"},{"one":"4116fbb7d55bfd4bd8db9cbfa570ac361bb88605b6aacbf84e245893cf3fa599ecc086688a4c534c81f61a90fa344ca37e4d4013ddc03f7f08218724a55f66b1","other":"682288e4dae2374c4784acd0b285508920ce39a6b72cc0e30a3dbb7972e0394a2bddd5ee5f22a1dbf80f284dde4d9f8ede7847318d5353566b35a83e212477e7","up":true},{"other":"f5d95e0c5a873ff5a95e1eb34f1ed258d77adf98ee0886d93c4a24b1feaf6955e6e4c4ea0eccb2b9723870bae61e693643d6ad96dd8da01672542611f7c49069","up":true,"one":"5319bc9864d87eb33f26ff9732824d21a0a5ab70b254bc70a47554ffc763ae1559000d07e3eac9f883bd9e7f249d80edf14ab39c89c375bfcc5ec9e840ec9673"},{"up":true,"other":"ab8eda9b360d3e0b002ba31d48311057880844b828ad9817a2ad19736860d0114d4a17e9e9427c842d52e7ff61a09c2cad9b70f506e338909535542dae38ede0","one":"51a570637394e9ab61fe95b3a608cc4e9dc8ceb63efe717938ccd4260a962d52e01b30e7034fbfdabd9a3c9616ee569550b38a6d6b4b19847f523254069a9f27"},{"one":"488854534ec5a3479d8ee13d9b7daf07479f6b5505f319eced44dad8c316f6ff241ce2101e95608ba635067f5e5741481b78f419c4bbd465bf7e837dc4e54d64","other":"6b104eff1dcf58d11a7f707bbd41a910b2735b262c29e0f4e4127fda1b67def4e89b6ebc1b3cc1e06c3968d0898e1085badc7da24d3cd6624cb100e85863cc97","up":true},{"up":true,"other":"c69b9b181b2756a1345b73a97afb3dca909c253188c3b905f0b414465b750d2ffccb4c8e8eb5e3809549af55db473f3b12682f9bd97c5c75d68f23d67d91b866","one":"60995852a2385ce8d7d24dc94b85a2f0dab6e5c32e910dfe367ea9c6ccb7b0b2eb611fdf120f8c697097e2f137cefff42e8d9db16b664a857a38c5ace837ffa4"},{"one":"3b71a324bd7b1a8fb19d8206eea1ca8190cb1faf5fcd1bfc52cef6b52296fe1db3e54d70180133fad1fa1188499d0dd73d2d075fdc6b3ffd9042d690e7d88e02","up":true,"other":"b87e7f36ed6bf142d48545024d2fd6e120c44511701e7c0b7d7fc786f4f29d3357024b15f70b78215d8a4c2b7572d608c11b31612743e23db4fa673f0cd6519b"},{"one":"49256eccce3e036928a4b6b346126c6777dca5ea0134de85efca340f97ad0f827f3094f1562e3e186d35b8292a50c20ffae01409890bbb78598494285e14dc2c","other":"ea2921612b827e3c26328368bed9be7cbf1f2b2aecaf31863c9cdccd74c56b651d6eaceb8ac9609a6653488837ded310df91e53a74789ae75cb841e2aeaf96df","up":true},{"one":"7db14fde1da8794ae7ab5de37c9e2537e1024bc830c176c0d01635cafed47773d3a28e156db81ecdb95903222b900c3ebd4c4b3db2971dc0ef6a1e386027ffaa","up":true,"other":"a8fac88fba179fb9b259d94caac9cbe45d873a0131bef8844ac4383b177daf6f301f8793623fec5876885db1a91e5b3e98e2aafdaa47e03b1f6d9740f48af7ac"},{"up":true,"other":"ea2921612b827e3c26328368bed9be7cbf1f2b2aecaf31863c9cdccd74c56b651d6eaceb8ac9609a6653488837ded310df91e53a74789ae75cb841e2aeaf96df","one":"1b3107d9a96cfd11f4cd0ed8baeb7b23db1406c9c4a9dac76c772f49c0fc9404f6a4adae11120aa821757173f0cc1cb00e6ab555b5abffaae9001c0557cb75c9"},{"other":"dd3dccc1758765569905b3b137ef4c7dd31c2dc0dea827bcc4c4e976be94ffbb0f2ef6fe725cf9042063a96d663efea546837f35ca1fc67a854fbc9e27abb754","up":true,"one":"0c82c4b414375479375703ed9c19fb08c8143229ed4f1dcf448c6cf313810c098905123bec17969276936ae0cc39ed251b2811dbffb551d61159862b0eac0a23"},{"one":"49256eccce3e036928a4b6b346126c6777dca5ea0134de85efca340f97ad0f827f3094f1562e3e186d35b8292a50c20ffae01409890bbb78598494285e14dc2c","other":"37adbfdf66163e45f433d78f63210163fdacf4688ad90d73bed07975be017c43cddf2a26a0dee8b11d78f294b63d4875b6be15f42f10817bd3d77b342919a11e","up":true},{"up":true,"other":"b18c7131a319db61ab84d06e90092d93c91141e9a270630af9c3ab1eaf3bcad09f4d20a1fc845b21c994bf4d9e337d0bd756a75e2198097540355e7ebbb531b2","one":"877d17ec7e95998ead831606d3363fbff1c8d1fa377b8e621e6a876d2c7776b9af356211a7e4df66adeaf38cf9b49c04871e8804edde4c18435ff45e110ecb04"},{"up":true,"other":"682288e4dae2374c4784acd0b285508920ce39a6b72cc0e30a3dbb7972e0394a2bddd5ee5f22a1dbf80f284dde4d9f8ede7847318d5353566b35a83e212477e7","one":"7b4585f8a4e4904239994a1b8bdc76299da8e46a8a632fabc6c33dd4170f8f3715e4c4f526ea5dd14093b150855960e432b1b140594aca21995f9e0722fb57f1"},{"other":"6c40910f0556f892a7542989fa01d7e3682fca89aeefb5ed885808f88ff17b6d13862f461c10d629a005ae67abef542d75e5b20816891b6944f71560f5c2dfa8","up":true,"one":"2bea7540c99456ea889a8ba2e448c11e6257bf987d01f13eea48128ba58577ab0936855035ee140c9907e382a34ca85a179c74892cbd9eb92fc2b35601addc6b"},{"one":"49256eccce3e036928a4b6b346126c6777dca5ea0134de85efca340f97ad0f827f3094f1562e3e186d35b8292a50c20ffae01409890bbb78598494285e14dc2c","up":true,"other":"6c95c653e15bb99d32656f35790400134cd7188e063f878e19cb9118eb469ae0362dc45255f2a1eae31520be01d42b5bc5bbebf03d644c9f206ca79cb33a01ad"},{"one":"81dc656de121016bcde81d5bf7919839acfc180dfbf1a6de2cadf704ff13af98aa5715a4168832ca6f651b2ea7ad9e6ca5f1c1cb7e885dbc2eb23d4aefb87bd6","up":true,"other":"d6747e1f8594f7449fc6d7c0e63ee843480567d498db096ff04229420861c83bca5215fc19d8fede0c54484f111f1f2581e189e638c21c5d9e1fd3174bbb3e98"},{"up":true,"other":"c206d8689068488179e86ce549de75989e0b17cbe09880d18fcf0fa212e629345f1b899203607a2b083569cb3f8398e501843166f5db23ac7fa7dacfe26dd3f4","one":"c6ad9b9de5cdbe28540f4eb7c66fb37f6d4295e6e60c6de54e2a45c1970b8e0047558e986bbd10e9e86c8bb0407846fac4823e4570e8a1486fc4bf55cb4a0986"},{"other":"c9d705012a06d82c4d44db95b4f1c63ddd33ad64d732e96b1d878caa0caac433d4096f01495a6f0e8a56af122b0470fd745db6d906353b590a4710472b93f5b2","up":true,"one":"f5d95e0c5a873ff5a95e1eb34f1ed258d77adf98ee0886d93c4a24b1feaf6955e6e4c4ea0eccb2b9723870bae61e693643d6ad96dd8da01672542611f7c49069"},{"one":"7b4585f8a4e4904239994a1b8bdc76299da8e46a8a632fabc6c33dd4170f8f3715e4c4f526ea5dd14093b150855960e432b1b140594aca21995f9e0722fb57f1","up":true,"other":"77811b007dd1fc1b11e447858df37062e97b6fc14e059399814f3b4736188e3fb28bf7c3958bb8ebc6ae16c36884ba7c98b810fb6f8b358323412123c803abd4"},{"up":true,"other":"5982e7dfd39c527851f6ea6430b70e654d95df5ec4401ca1d8dbd1034cf7a65d1126d60b36ebbd396c9ca32e6e8515f34f9dc0a8d2980afe4aa181c8bf68437e","one":"e33a1476fcb8d2a1b9ee15871a960ce7a3337c93f5956a2825b1f8b2885dbdc0ed652b1eba549523866632b5b6898310bc638d946a9fcce27d65117eb44c25f3"},{"up":true,"other":"c674c405068bb908312917a319e24ddf90e814ee8ef54bbf740f176b2a7eda6950e3e1ed69484ebcc27b13d82c7f0b20daba71a17700018e769ca612ca8d2208","one":"aa90454031068598ee39af5f1429c7a72277946d50ec2004f340406dbcc9f80cac505c9d9b071f85e2ccfd4b13bcf943f3cb9dd9f96f62d41352af9d8fffe7e4"},{"up":true,"other":"6d0a09235ba0b0428938abf0e0782ac0ecf5697ef862888719a34fc956517aeef89d5e5f76d12e10067fee5bac8781dc10400eeb35c2393b9382b2a4f68f7939","one":"865dbf61d8511603fe0d9ebfb10792b9f6b798187c0909039bd9b2492c41e428876f386beeac86d0dea871f4fc24ba435f0fbd9a11e74c044024934592af14ee"},{"one":"5982e7dfd39c527851f6ea6430b70e654d95df5ec4401ca1d8dbd1034cf7a65d1126d60b36ebbd396c9ca32e6e8515f34f9dc0a8d2980afe4aa181c8bf68437e","other":"869cae165389e7dee7b7df4e012ee1a39737366c306d8f4b0db4510b2236e0bd3a4d1d4af00b1a8c1d360e23da47de52fc1632edb03c7f1429aacc8aa4994750","up":true},{"one":"ea2921612b827e3c26328368bed9be7cbf1f2b2aecaf31863c9cdccd74c56b651d6eaceb8ac9609a6653488837ded310df91e53a74789ae75cb841e2aeaf96df","other":"06aab75fed9a03f5525e3f1d8f8997fefaefd5b16e8f485d571beda00b1741efbb61a8a74fa12c2f6de66227c3fabb4d411659cd9c7b1ef32e171e6bf517cc39","up":true},{"one":"1b3107d9a96cfd11f4cd0ed8baeb7b23db1406c9c4a9dac76c772f49c0fc9404f6a4adae11120aa821757173f0cc1cb00e6ab555b5abffaae9001c0557cb75c9","up":true,"other":"37adbfdf66163e45f433d78f63210163fdacf4688ad90d73bed07975be017c43cddf2a26a0dee8b11d78f294b63d4875b6be15f42f10817bd3d77b342919a11e"},{"up":true,"other":"1b3107d9a96cfd11f4cd0ed8baeb7b23db1406c9c4a9dac76c772f49c0fc9404f6a4adae11120aa821757173f0cc1cb00e6ab555b5abffaae9001c0557cb75c9","one":"b8e0a56df21baae43058f575b714ae9a33c097d18f1a628b3b6ae5e86dd46a06e44c0dc272baacb5be0f7bf57fd6ddce107544eb3b94dca1aeae9f5773496a72"},{"one":"545237d8463b75fd2e9bbfbffb35c5b78b4abbc85f6bfbd56976789012dd9a62ca1f866bf37bb33618e026aab764adb9ced5e00cd415562f69992f74c795083f","other":"2b0a1f3a6466c6be1d7e84120db384fa37f7c73a01e9a105ae90e7d2203212ec974f016d3012afd26bc0f9a8411d0716cc59b6ecc9f665db12e306af8b34cb63","up":true},{"up":true,"other":"a5f7163586fce1750fd9a6e5c418af1c18ca6983069dcf1738fc9106ebf542a86e4ccfc50b45a0d97ca8681af8207128877f930f945e59ee262aa7f4014a01f3","one":"002cb6ffa63ad71ee6ebc1df4c41f7a97c51f274b1d3b22420c87b73136be5169b9670508061d8261e20055fefce3b855388994672aa9a0f1475c43839aae4fa"},{"one":"81901d9f043b4b1649ade3b5d22ae5f8bb42dd6db1eb37b836b99dd1c0388509ed4b54cc5638c9d4a6c5ae6c6913bbfffb303d7d94bf4ed50e871cf95459e2c3","other":"57085f756f76644cdd2148524f2334d869ef0ab2fcbe7fb11f5d22bc1f5023165b11526ecc85ff9cbb88877386af9b148d7ef15a825b3a586d16c01bdfc86692","up":true},{"one":"43086ff7ffd3c7bdec77bd288f41f1ee0ce21bd3f60a5df8931e2af6e7af5ef0fad432d29625491935d11567944351fc7867c807ebd12dd2c21c9e620ae0f85c","up":true,"other":"2c976b6007cda135444233c7bd03d22ac9756710b746c36bc032e7fdd42f2ffb89ca5f5e754ff96b8f3cbc474e346287e5b8531d9f98fd63c426c632872220af"},{"one":"f5d95e0c5a873ff5a95e1eb34f1ed258d77adf98ee0886d93c4a24b1feaf6955e6e4c4ea0eccb2b9723870bae61e693643d6ad96dd8da01672542611f7c49069","other":"a070b5cff5eff533a2267ceb0d88e221088038af773e18f80110c8a2c329f0543b8d43c4e6132e9416723e3e94c87f0053456760ced4426767b95cee36ed93f8","up":true},{"one":"baa28b8cb7ec539e0e157d7598cc5a5b0210fd8fb5c9026c3cd612133c5a8ee56997507511928af5683cb620fd85593dd8f6ff882d95fb847870ae4ce7dc503b","other":"57085f756f76644cdd2148524f2334d869ef0ab2fcbe7fb11f5d22bc1f5023165b11526ecc85ff9cbb88877386af9b148d7ef15a825b3a586d16c01bdfc86692","up":true},{"up":true,"other":"431644cf162bc267237c4e798288888dd835c1b0546b0cc679782e33568988d75b4294f4aa08359a6b152ed9a0fbd13133681156bcf09a871c4f362615ea6dae","one":"76643f67075c6e45bd176db19473240cda6f886d1cac25330e2d99c84a429934f4c6a606c9c72574d5eaccd0a3f1770dab05e6ff6a5b5ce4d7258fed2bc13d48"},{"one":"202ae63076a5560418023f00c9965b2a1d12de932b5371ae270d63db88551a7aa1a3c48841f81948fad3435bb4a7e3e165a2eced9fd937444e4502471e23dae8","up":true,"other":"e1f23e1caba66f5ff821edbc4a3d527539937f73d86dd0df43aa1266a99f51f2480a77961eff177fbbf852fc52cb9317179f80b1580194daaedadc3b00510751"},{"one":"81901d9f043b4b1649ade3b5d22ae5f8bb42dd6db1eb37b836b99dd1c0388509ed4b54cc5638c9d4a6c5ae6c6913bbfffb303d7d94bf4ed50e871cf95459e2c3","up":true,"other":"2b0a1f3a6466c6be1d7e84120db384fa37f7c73a01e9a105ae90e7d2203212ec974f016d3012afd26bc0f9a8411d0716cc59b6ecc9f665db12e306af8b34cb63"},{"one":"76643f67075c6e45bd176db19473240cda6f886d1cac25330e2d99c84a429934f4c6a606c9c72574d5eaccd0a3f1770dab05e6ff6a5b5ce4d7258fed2bc13d48","other":"70cce7cb0c18091dbb6d41160ab560935f1759b969bf8118cee030ee707cb15ba407b8c48dcd9fd012cbf778e219f7d16a74064b4983cf098fb118297748edb6","up":true},{"other":"bb0749de05a97daa67de889c15831ce39a080d641b3b08e3c248b0b16f4c07943fea8dd054d4a7e3e4af91ecff07053ce90096485a360b6f1d93050d179f30c3","up":true,"one":"bab07c2e4dc09add884869b31fb474b6d7151f9cc331d831f55c2b088397370fb0a1e1592c8dff9c8bc8e83de9faf6e91683acfb2df1b41856d70e523a99d370"},{"other":"bab07c2e4dc09add884869b31fb474b6d7151f9cc331d831f55c2b088397370fb0a1e1592c8dff9c8bc8e83de9faf6e91683acfb2df1b41856d70e523a99d370","up":true,"one":"0c9a05514b96e7c3a0fbca21552e158faa70047246b230addca172a5023fd7439acd1c3a0b4f9191579b308dab38c961734ffdb36fb8e16383e912d070fc0218"},{"one":"b9c7b885430b9b1a4425bde30b3629559f5437e0e30a0299fc6f6e097cbcca8af9e285caf5dea685a0237f60e06f490c39a1e3e487f14a2b9f41a5135f2ba994","other":"99af34b172d319633e07a4e528f416024653a230a9103a4b281171f75bb697dd6be4757558c94e86210b4da8d9fe1229f6a5d8c4174989ea0ce696f8d1a9995d","up":true},{"up":true,"other":"8ec699020ab5e7719fe23b80268b5d1d37052bb71f5d81200ae805cf27825823733206165f0a7507c2595853361dd122e9ec1b2deb543591e22b71ec0b873b5b","one":"e8a679f627d03347a4fcec0a0940f7ffa90ce3fefea290db3af4f3a32d27965bfb51832b6a6de2495c8a8cc026bcf993b84a0cced778e158bb81c034f5e4bd76"},{"other":"d7e3661c0af6754c875217f93d34b254f1f45fc1359a4c6146cd0efa4c6e12aed9a4fb0a21a136f73af4fc2c6d0a63cb809d81855bbc9f51e29d23d90f77b326","up":true,"one":"643da2591098f9698f27cccf7c17832e0717ee6a1276398a1a29edc947125585dcfab9417c2721a8a55d4dfc75b826be7581b6e30b020f6341ac549877c9f122"},{"one":"b183f12f3602bfdab0480cb0b0ba7dc69b267b0dbc7e54c316741cb78b9e99aa69fd321ad7755d095e9be14e6bd90fe14ef8fe9bafc1a0dea10a144795021a08","up":true,"other":"ecb93d8eba17afe92979e8154252a08dd58de6ff3188b6829e3e25967846686f54199ab2b081e77b0048dcab204f05aa2c5cbd0efae4bc43a612d471d4e1197b"},{"one":"0c9a05514b96e7c3a0fbca21552e158faa70047246b230addca172a5023fd7439acd1c3a0b4f9191579b308dab38c961734ffdb36fb8e16383e912d070fc0218","other":"362ed9a92b588d5fe315b90a74aa27f7600e4a7d06b27ceb26272340388d916a831df85bf83450ef80bda4e4a21acaac60560c8a42940a26e2ac567519e2a202","up":true},{"one":"6b104eff1dcf58d11a7f707bbd41a910b2735b262c29e0f4e4127fda1b67def4e89b6ebc1b3cc1e06c3968d0898e1085badc7da24d3cd6624cb100e85863cc97","up":true,"other":"f056acbdf491d1bb091937335c10096ea44b7034e994d134bc16d55212ff049bb097424de96c615ea699359a7ef77b3b54def2b3a5f43d735ffda65f73d61f7f"},{"other":"d7af0a0217ff98804aa05f8f926a8b6262363b5391d24cda8048cca5ca5982b407b7b098302d0db6d8dd9ac0883b2025b3de651617ed1a173181148295c6d336","up":true,"one":"b183f12f3602bfdab0480cb0b0ba7dc69b267b0dbc7e54c316741cb78b9e99aa69fd321ad7755d095e9be14e6bd90fe14ef8fe9bafc1a0dea10a144795021a08"},{"one":"3e2241cdb9f34c1d2c6930e59940e2c4b92b0287579d7263a620a609c5e66dca6d85df48cf1bffd63663a6704c42d0866aae3e484fd9a44b6a012f72dd3cef6e","up":true,"other":"6c95c653e15bb99d32656f35790400134cd7188e063f878e19cb9118eb469ae0362dc45255f2a1eae31520be01d42b5bc5bbebf03d644c9f206ca79cb33a01ad"},{"up":true,"other":"5982e7dfd39c527851f6ea6430b70e654d95df5ec4401ca1d8dbd1034cf7a65d1126d60b36ebbd396c9ca32e6e8515f34f9dc0a8d2980afe4aa181c8bf68437e","one":"6c95c653e15bb99d32656f35790400134cd7188e063f878e19cb9118eb469ae0362dc45255f2a1eae31520be01d42b5bc5bbebf03d644c9f206ca79cb33a01ad"},{"up":true,"other":"37adbfdf66163e45f433d78f63210163fdacf4688ad90d73bed07975be017c43cddf2a26a0dee8b11d78f294b63d4875b6be15f42f10817bd3d77b342919a11e","one":"3e2241cdb9f34c1d2c6930e59940e2c4b92b0287579d7263a620a609c5e66dca6d85df48cf1bffd63663a6704c42d0866aae3e484fd9a44b6a012f72dd3cef6e"},{"one":"ab13f773f6f2ff73032aa5f79c8897b75dda29bcbb14aa511e9401c2417dc9c510253071e28c7833c8d62fd2aef16fcd0c14ce016fbf4fec1b9a2173c717603f","up":true,"other":"7a8cb96685c1b8fbaeb18c8dc1f9f2631b23bc035e704e2f5df915b8bcabd6e2025ddc30324c69833f86e577b250c0721fee9d294f3e22016ae4c59c5f88845b"},{"other":"c03ef1de42d522b44eef53be11f2c57b8b74fed9e87e6c2928c1feb48ddfecc67e1a3a8c8be1c47b3735a216d7054e2a4dda49fbd9a1ac702146aae5bdeced7c","up":true,"one":"60995852a2385ce8d7d24dc94b85a2f0dab6e5c32e910dfe367ea9c6ccb7b0b2eb611fdf120f8c697097e2f137cefff42e8d9db16b664a857a38c5ace837ffa4"},{"up":true,"other":"ec19efa1d488e74da6bf239825b24678f549c377326c5d33d100b708a9a28a3fe129d542d7ba71e0ade46c15c6e9b38f09422560444388e609a8a66ceb8e0ae8","one":"9bdacc256acef0433805477d38f32be849a8846d88cb883b19d290454639b42c6ab6c5c52d4f83453e8a156af7d85f606458aa9c0977c67282f56f34ff0acbfb"},{"other":"c03ef1de42d522b44eef53be11f2c57b8b74fed9e87e6c2928c1feb48ddfecc67e1a3a8c8be1c47b3735a216d7054e2a4dda49fbd9a1ac702146aae5bdeced7c","up":true,"one":"aa90454031068598ee39af5f1429c7a72277946d50ec2004f340406dbcc9f80cac505c9d9b071f85e2ccfd4b13bcf943f3cb9dd9f96f62d41352af9d8fffe7e4"},{"one":"81dc656de121016bcde81d5bf7919839acfc180dfbf1a6de2cadf704ff13af98aa5715a4168832ca6f651b2ea7ad9e6ca5f1c1cb7e885dbc2eb23d4aefb87bd6","other":"06aab75fed9a03f5525e3f1d8f8997fefaefd5b16e8f485d571beda00b1741efbb61a8a74fa12c2f6de66227c3fabb4d411659cd9c7b1ef32e171e6bf517cc39","up":true},{"other":"e323da6ae861cb092543992b8985639f9b3bcaf1c3c68757f4603a67800be62950fe7d8f8ef80eb83a18107b677c7f5047ea89a5790e0ea2a7969f4856d28488","up":true,"one":"228b3646b15527f4df07b847a62dbf9620cb068f829e9086b5f437d0b64d8a027cab44f19db5e44189b5099545ecb25d49384c261748f9533cfb0eb11a1eca5f"},{"one":"7b4585f8a4e4904239994a1b8bdc76299da8e46a8a632fabc6c33dd4170f8f3715e4c4f526ea5dd14093b150855960e432b1b140594aca21995f9e0722fb57f1","up":true,"other":"f6a12b23423c047927a3024a6dba7ce88927cb21d4df3778bc5ebb262cc403261c79ba6d9bda07f1852c009d803a77f429e9e48ec1d63cae98256e529d45b276"},{"one":"222d7a2f94dc82a09fda70b8195fc3a60433a90f53998872318c57625c528c90572d78b444ac4901dcfece1a03ef8b6cbe7845366a845a942f341f6db58a9b3b","up":true,"other":"884d32d09dfef937f3ef1cd6fb5f530c2c574487c0ffd4185ca405c8b2ac73044a196c34352e850ce15321eec6579da654a696381f3e5830d03c7aa18923da6e"},{"up":true,"other":"3e2241cdb9f34c1d2c6930e59940e2c4b92b0287579d7263a620a609c5e66dca6d85df48cf1bffd63663a6704c42d0866aae3e484fd9a44b6a012f72dd3cef6e","one":"1b3107d9a96cfd11f4cd0ed8baeb7b23db1406c9c4a9dac76c772f49c0fc9404f6a4adae11120aa821757173f0cc1cb00e6ab555b5abffaae9001c0557cb75c9"},{"one":"f52281c227aa82a3bd5fabfdcf8bdf1d9ea6739ab9b9075340143d59b4f2f8a79a981609c9f42823a0253c19a7281eed0e912e4054363ab7fe50117563ef14e0","other":"dd3dccc1758765569905b3b137ef4c7dd31c2dc0dea827bcc4c4e976be94ffbb0f2ef6fe725cf9042063a96d663efea546837f35ca1fc67a854fbc9e27abb754","up":true},{"other":"7a8cb96685c1b8fbaeb18c8dc1f9f2631b23bc035e704e2f5df915b8bcabd6e2025ddc30324c69833f86e577b250c0721fee9d294f3e22016ae4c59c5f88845b","up":true,"one":"5114329db828f9568ccb0d7643a10e273aa626177910f55e22a53abf1ce8ec75b95465c983446b20eac0ff9c59c5dc53eca95b24aabcc8dd110e397cd2934047"},{"one":"e33a1476fcb8d2a1b9ee15871a960ce7a3337c93f5956a2825b1f8b2885dbdc0ed652b1eba549523866632b5b6898310bc638d946a9fcce27d65117eb44c25f3","up":true,"other":"b4f300abda4cf6e383f997510eb681e9fa62e23577e3c19bd7447fa1f5702a4e034cea5944248e7c6e6e92b5ae69195c3e8a2c5ca7827b4f4a00cc8546e6695a"},{"up":true,"other":"869cae165389e7dee7b7df4e012ee1a39737366c306d8f4b0db4510b2236e0bd3a4d1d4af00b1a8c1d360e23da47de52fc1632edb03c7f1429aacc8aa4994750","one":"2751df9f64a8f2ff8ea45efc9bd02b281d963ced285260bcda7f9dfaed998fe4386fe65a7265876da6b4fee77ea5c12454869a70ad627da7ca888076fc629665"},{"one":"3e2241cdb9f34c1d2c6930e59940e2c4b92b0287579d7263a620a609c5e66dca6d85df48cf1bffd63663a6704c42d0866aae3e484fd9a44b6a012f72dd3cef6e","other":"2c976b6007cda135444233c7bd03d22ac9756710b746c36bc032e7fdd42f2ffb89ca5f5e754ff96b8f3cbc474e346287e5b8531d9f98fd63c426c632872220af","up":true},{"one":"9e21f5d4cfb389ac3ad43497689878bd245a89c587a8637d832b1e355ba244f4c83e6499bc7936e6d35645db25910ecd89b9af9b6b2f0c7cc4d7c6114328d7bf","other":"1e3a2f2491b6acb07a9549d9929d150479a0313c926b0e236237bd541303da4b563a855016a90ab50e59d94803ad566798570fa981464c94c04a4a4a94fbc607","up":true},{"up":true,"other":"e0a043f98b462f10f72aa61ceda52f9c27829d086f6f2c5bf4db4fe32759002e5ff9519495d57dbb83d963a1dc991a1defcf5b9ef0d543789f38c68f5d07122b","one":"1c080e90760dfcee08ade6e4ea3b275ff3c6882f3b44b7f3a73d70bcc816fc63ce0b6138f810d17d96ed387076f9bbb6dbb2ef6dc4d6ba6542c1f587b7602a12"},{"up":true,"other":"1b3107d9a96cfd11f4cd0ed8baeb7b23db1406c9c4a9dac76c772f49c0fc9404f6a4adae11120aa821757173f0cc1cb00e6ab555b5abffaae9001c0557cb75c9","one":"37399617d62153bc471f3bf21c92385bc8602c80ffa0c71da8aebae595a9859cfd56257aae60ad30ef3ec4d07dee90623cce63749c8c3233c0aa0d17f9e89afe"},{"other":"e323da6ae861cb092543992b8985639f9b3bcaf1c3c68757f4603a67800be62950fe7d8f8ef80eb83a18107b677c7f5047ea89a5790e0ea2a7969f4856d28488","up":true,"one":"3948a7a939b9a1f4201953bd9b955ee7be87d09b63c7a45167f556ac06fe3c4c2a75d935bff50668da5e71e46802b55d7a9945a92d7807c00625d129cbb48f82"},{"one":"ecd217e8bdb53c9ef085929b8c2d2b40425a4be617a087b8e7f88e8507b3c981e90fda2119744ca394fe65bd4eb1cdd3fa7258db936048e236d2f15ee91bc3b6","other":"e323da6ae861cb092543992b8985639f9b3bcaf1c3c68757f4603a67800be62950fe7d8f8ef80eb83a18107b677c7f5047ea89a5790e0ea2a7969f4856d28488","up":true},{"one":"8e8614a4c2ee2b1a3fa5ace0ca353cff36b3de3308ccf53665b8b56f8e2456a8a65f3846d786dccd68b1bfcefdd170ea5f8edb481800b1ce72d9fce2added7f0","up":true,"other":"313a131ecb7d68e127d0fec8bb4a2e586886203c3d07857a93e7a39bb831703184d9ae28ba9ef3d986c2dae1a24f4f5bfa47cfc35f74f5512a126836364d7736"},{"one":"baa28b8cb7ec539e0e157d7598cc5a5b0210fd8fb5c9026c3cd612133c5a8ee56997507511928af5683cb620fd85593dd8f6ff882d95fb847870ae4ce7dc503b","other":"9309549fc50173d6826fe63cf18699f49199c3789616b843042fe1a6adab6ed4bdd7a7a06acd276e0398cf8bffb26c12a4227725d7bbd386a9a55fc601c21405","up":true},{"one":"c6ad9b9de5cdbe28540f4eb7c66fb37f6d4295e6e60c6de54e2a45c1970b8e0047558e986bbd10e9e86c8bb0407846fac4823e4570e8a1486fc4bf55cb4a0986","other":"7db14fde1da8794ae7ab5de37c9e2537e1024bc830c176c0d01635cafed47773d3a28e156db81ecdb95903222b900c3ebd4c4b3db2971dc0ef6a1e386027ffaa","up":true},{"one":"9e21f5d4cfb389ac3ad43497689878bd245a89c587a8637d832b1e355ba244f4c83e6499bc7936e6d35645db25910ecd89b9af9b6b2f0c7cc4d7c6114328d7bf","other":"e0a043f98b462f10f72aa61ceda52f9c27829d086f6f2c5bf4db4fe32759002e5ff9519495d57dbb83d963a1dc991a1defcf5b9ef0d543789f38c68f5d07122b","up":true},{"other":"6c2788dec7ae7a77134065afc1174bb92b87833e87acaa72fe9e62c92d2017f217f9fbc5884cdfb7236a7bb75e463e49ecceb1641a8629516211d9699587046e","up":true,"one":"aa53ca208cc0c9e544fd9d52cab44b5e2887256bb006037b855b5c94d7f79c9388fdbb23c0bf1d2eee12d67125e082fa7ecb34c1129ca8eaecfd85772b009435"},{"one":"8e8614a4c2ee2b1a3fa5ace0ca353cff36b3de3308ccf53665b8b56f8e2456a8a65f3846d786dccd68b1bfcefdd170ea5f8edb481800b1ce72d9fce2added7f0","other":"7958d1517de1223e7fb30acf61d8618e49fb95a03bc2f49141f4c7967bc80b90e0dd526c205639de3c060029963d43813293c2556f7b127945c798f3f9f18626","up":true},{"one":"ecd217e8bdb53c9ef085929b8c2d2b40425a4be617a087b8e7f88e8507b3c981e90fda2119744ca394fe65bd4eb1cdd3fa7258db936048e236d2f15ee91bc3b6","up":true,"other":"c03ef1de42d522b44eef53be11f2c57b8b74fed9e87e6c2928c1feb48ddfecc67e1a3a8c8be1c47b3735a216d7054e2a4dda49fbd9a1ac702146aae5bdeced7c"},{"one":"77e40e42f570a217f707888c714deb31fd70c856ae4b9a44ec7cee02768185dc4d7ed210429607f06690b32edd9fb06b304aff330a3949cc2fd49db1bc392edb","up":true,"other":"baa28b8cb7ec539e0e157d7598cc5a5b0210fd8fb5c9026c3cd612133c5a8ee56997507511928af5683cb620fd85593dd8f6ff882d95fb847870ae4ce7dc503b"},{"one":"bb0749de05a97daa67de889c15831ce39a080d641b3b08e3c248b0b16f4c07943fea8dd054d4a7e3e4af91ecff07053ce90096485a360b6f1d93050d179f30c3","up":true,"other":"af9b80f6836113aeda897d6903e9ffb4f7f1a706a7f821d0d40f03a0d83c18d6a19795ee4bfc1093ada04014415b1f230db1d2f056df3f5027cce71611588046"},{"up":true,"other":"0c9a05514b96e7c3a0fbca21552e158faa70047246b230addca172a5023fd7439acd1c3a0b4f9191579b308dab38c961734ffdb36fb8e16383e912d070fc0218","one":"842ec3faa8b4a4cdec32abfa00ae827277fe2696e1b0c6551154533b16cf75ae69caf834b4f08488fa5c8b322fb633b1fd8a5b7d436e9c589cc9074dc031ae68"},{"up":true,"other":"4e88cc60efee147fb72a735775944c7b2ba0790e2b2b935b4b3c2da9a3158a2a7aae411e9204cdbe6b2304d90a3a8278f8bb1a800a409e8500d100d84ba1947f","one":"c6f38fe8a0f2b3773bae332e0ca7516e944bde186fe99daae10a2b0aecde3ce23c1834eaad97a4e6d2da8cd53a08dbafa72d2b827c851b115b74e8010125dba2"},{"up":true,"other":"7958d1517de1223e7fb30acf61d8618e49fb95a03bc2f49141f4c7967bc80b90e0dd526c205639de3c060029963d43813293c2556f7b127945c798f3f9f18626","one":"f98c0f4444a1ec80773454ddb691c226b81d8e2f79ed40c45a422d3359565edf7bd635d3eb7bd6c9e0870746849fb86f0b1b34cd56ec8d3ad969812e080f4983"},{"one":"7958d1517de1223e7fb30acf61d8618e49fb95a03bc2f49141f4c7967bc80b90e0dd526c205639de3c060029963d43813293c2556f7b127945c798f3f9f18626","up":true,"other":"7cc9389c8f751465e0b94baed896f6f122631052300b1b5b23d3c7656e4d11014a7a9ae62a1287bb040ca37221871a566cd470e523846df7e3acb5f94c7cde06"},{"up":true,"other":"baa28b8cb7ec539e0e157d7598cc5a5b0210fd8fb5c9026c3cd612133c5a8ee56997507511928af5683cb620fd85593dd8f6ff882d95fb847870ae4ce7dc503b","one":"d09104c44648391693ca64a57baa5ef54ed717e19c65ad0a0921d08cbaca8877d0190795d15f75f3b6ce6e676d6b0e55d5ee8fec3310c68b7060a32f7ff649cb"},{"other":"e0a043f98b462f10f72aa61ceda52f9c27829d086f6f2c5bf4db4fe32759002e5ff9519495d57dbb83d963a1dc991a1defcf5b9ef0d543789f38c68f5d07122b","up":true,"one":"49215dfa786bfaa52b1e7aa6899392711a770b2504c82f536381fb1f18df16960257d75530efabf6dbd2b1361decc29758f870b318f777decf51f4833a9c1f00"},{"one":"77e40e42f570a217f707888c714deb31fd70c856ae4b9a44ec7cee02768185dc4d7ed210429607f06690b32edd9fb06b304aff330a3949cc2fd49db1bc392edb","other":"5982e7dfd39c527851f6ea6430b70e654d95df5ec4401ca1d8dbd1034cf7a65d1126d60b36ebbd396c9ca32e6e8515f34f9dc0a8d2980afe4aa181c8bf68437e","up":true},{"one":"ab1a3542d67ef9d1a63653990bf0782f53b0169fe5092adc92fa7aeb38f66c6b62d49e3455cc2ac4994bfcfb03111953acf4cc3099026672cc61f6e24cb3ae00","other":"7958d1517de1223e7fb30acf61d8618e49fb95a03bc2f49141f4c7967bc80b90e0dd526c205639de3c060029963d43813293c2556f7b127945c798f3f9f18626","up":true},{"up":true,"other":"3639f964feba681db9702cac3f02058f2e490fd7bffb217dc3480dc458decafd5955541fea89f0f6f14ee50a745eaf98b21363d6b4fb88c31bd32bf7845d524b","one":"e903d7aebff96a6afa4b9dd19b0b02e5af18da8e4e89f64247e1a2c2d46637538c741182eac67f45ec61be76aeaccde57f0a0184bd608ea7d92e586d4f827ea7"},{"one":"b183f12f3602bfdab0480cb0b0ba7dc69b267b0dbc7e54c316741cb78b9e99aa69fd321ad7755d095e9be14e6bd90fe14ef8fe9bafc1a0dea10a144795021a08","other":"a58a4db7a96b1578935b222c78b7b4dd8b3519d2995c3616e5a154c5175242a503097771332504638a0b321b9574110207f9a7d77b109d1de3d66a12ec6498e5","up":true},{"up":true,"other":"99a7649bdf2ee7f0bc049308b0997e33abb68481c05a573df9aea30da5a1f267df07b2c584e3e985baf31704f04ad2a2c4876e0f8555333be6d09f5080b583f1","one":"0c9a05514b96e7c3a0fbca21552e158faa70047246b230addca172a5023fd7439acd1c3a0b4f9191579b308dab38c961734ffdb36fb8e16383e912d070fc0218"},{"one":"a58a4db7a96b1578935b222c78b7b4dd8b3519d2995c3616e5a154c5175242a503097771332504638a0b321b9574110207f9a7d77b109d1de3d66a12ec6498e5","up":true,"other":"3639f964feba681db9702cac3f02058f2e490fd7bffb217dc3480dc458decafd5955541fea89f0f6f14ee50a745eaf98b21363d6b4fb88c31bd32bf7845d524b"},{"up":true,"other":"e903d7aebff96a6afa4b9dd19b0b02e5af18da8e4e89f64247e1a2c2d46637538c741182eac67f45ec61be76aeaccde57f0a0184bd608ea7d92e586d4f827ea7","one":"49215dfa786bfaa52b1e7aa6899392711a770b2504c82f536381fb1f18df16960257d75530efabf6dbd2b1361decc29758f870b318f777decf51f4833a9c1f00"},{"other":"58f9139905ae1d005950f110b7ead3355672ecc478e8c66393566c64b935003f6fec3031dc9eb21cda660acb1955cf7bb33a20fdd74d493f29868ace328fcd75","up":true,"one":"3639f964feba681db9702cac3f02058f2e490fd7bffb217dc3480dc458decafd5955541fea89f0f6f14ee50a745eaf98b21363d6b4fb88c31bd32bf7845d524b"},{"other":"e903d7aebff96a6afa4b9dd19b0b02e5af18da8e4e89f64247e1a2c2d46637538c741182eac67f45ec61be76aeaccde57f0a0184bd608ea7d92e586d4f827ea7","up":true,"one":"699c923976c5b8c70c353840d3e384750f466954265f05fbb0d5877a2c0318a041dc57adc12ac6e8fbae7a00d6b6675e1a1be3a8f59dac12727ee3f8ae467a13"},{"other":"f52297fc51b920d2495ccece290432656d9388e698339c8c1279ceea45de698a4ecbda1d25928c48f1e19e9dacd3147e23ef01acc093872d7300aed187841dcc","up":true,"one":"9c8f156797deff649d74d56fc42b4bb1a87312089114d4350424c375837d9c8068dd09af01c1c973d12ec5d7e8da600cd685cae70d3116b9dbda823092e03fff"},{"one":"e903d7aebff96a6afa4b9dd19b0b02e5af18da8e4e89f64247e1a2c2d46637538c741182eac67f45ec61be76aeaccde57f0a0184bd608ea7d92e586d4f827ea7","up":true,"other":"ab1a3542d67ef9d1a63653990bf0782f53b0169fe5092adc92fa7aeb38f66c6b62d49e3455cc2ac4994bfcfb03111953acf4cc3099026672cc61f6e24cb3ae00"},{"one":"d7af0a0217ff98804aa05f8f926a8b6262363b5391d24cda8048cca5ca5982b407b7b098302d0db6d8dd9ac0883b2025b3de651617ed1a173181148295c6d336","up":true,"other":"e1f23e1caba66f5ff821edbc4a3d527539937f73d86dd0df43aa1266a99f51f2480a77961eff177fbbf852fc52cb9317179f80b1580194daaedadc3b00510751"},{"one":"643da2591098f9698f27cccf7c17832e0717ee6a1276398a1a29edc947125585dcfab9417c2721a8a55d4dfc75b826be7581b6e30b020f6341ac549877c9f122","other":"8d3ad57509b36c4ca5c4663f3d1977a3125e069078842634e6cfeb22c044281e3d02f06eafc6d2a60089f03d70f5134a6635c35563c9f911fd845a6ef9bc8952","up":true},{"up":true,"other":"f52297fc51b920d2495ccece290432656d9388e698339c8c1279ceea45de698a4ecbda1d25928c48f1e19e9dacd3147e23ef01acc093872d7300aed187841dcc","one":"3639f964feba681db9702cac3f02058f2e490fd7bffb217dc3480dc458decafd5955541fea89f0f6f14ee50a745eaf98b21363d6b4fb88c31bd32bf7845d524b"},{"other":"bac3fd2ea491d8e4ce1e5d469ec73f3d537d61279ae66e7a394b20a188244a886d3059ef0d304c0801878f9640374f7c8aaf56558c41f12296d3fc7f911ed66c","up":true,"one":"6b104eff1dcf58d11a7f707bbd41a910b2735b262c29e0f4e4127fda1b67def4e89b6ebc1b3cc1e06c3968d0898e1085badc7da24d3cd6624cb100e85863cc97"},{"other":"fee3fa1ba2a051d40a582908384ee81179db6c2b5f4bfa58c24f8015b794b43a093ed68b69bb209684135f972a055a9845978fa1b7d489e2126c3b514297f1c2","up":true,"one":"99af34b172d319633e07a4e528f416024653a230a9103a4b281171f75bb697dd6be4757558c94e86210b4da8d9fe1229f6a5d8c4174989ea0ce696f8d1a9995d"},{"up":true,"other":"699c923976c5b8c70c353840d3e384750f466954265f05fbb0d5877a2c0318a041dc57adc12ac6e8fbae7a00d6b6675e1a1be3a8f59dac12727ee3f8ae467a13","one":"99af34b172d319633e07a4e528f416024653a230a9103a4b281171f75bb697dd6be4757558c94e86210b4da8d9fe1229f6a5d8c4174989ea0ce696f8d1a9995d"},{"one":"4e88cc60efee147fb72a735775944c7b2ba0790e2b2b935b4b3c2da9a3158a2a7aae411e9204cdbe6b2304d90a3a8278f8bb1a800a409e8500d100d84ba1947f","up":true,"other":"362ed9a92b588d5fe315b90a74aa27f7600e4a7d06b27ceb26272340388d916a831df85bf83450ef80bda4e4a21acaac60560c8a42940a26e2ac567519e2a202"},{"one":"e7b2adabc2c99ac47b1e94fc0a2c63a00a1d622ea67a4c1858f4cec93fca957d43d8429605761bdf5eed4f733dac1a3d12fb928f22abf248965994acde63864a","up":true,"other":"a25958cf192a4f62301feda5d442535f78b983dd9e4599354f4898c8c1e6ad97ca7112549e1d1a1eacb4682cd1bf8b762368b5905ab33dbdacb585b128514ca1"},{"up":true,"other":"8fb6838337f832445531764ddafc3c747b2607f2f33e244685d6de621c2b53264270f5504187e43b7fa5cda53e66dd00b16c06879c82fb38a3d9e8aec4060210","one":"58f9139905ae1d005950f110b7ead3355672ecc478e8c66393566c64b935003f6fec3031dc9eb21cda660acb1955cf7bb33a20fdd74d493f29868ace328fcd75"},{"one":"9bdacc256acef0433805477d38f32be849a8846d88cb883b19d290454639b42c6ab6c5c52d4f83453e8a156af7d85f606458aa9c0977c67282f56f34ff0acbfb","up":true,"other":"e323da6ae861cb092543992b8985639f9b3bcaf1c3c68757f4603a67800be62950fe7d8f8ef80eb83a18107b677c7f5047ea89a5790e0ea2a7969f4856d28488"},{"one":"4e88cc60efee147fb72a735775944c7b2ba0790e2b2b935b4b3c2da9a3158a2a7aae411e9204cdbe6b2304d90a3a8278f8bb1a800a409e8500d100d84ba1947f","up":true,"other":"b4557089e4247379e587a087f53b36dd1f86f85d9dcfab5dc562079978cd959adaef5b30d11258d9cb552e7c5abddf5377a71d449febe8f2acb0aec3ebd8ba73"},{"one":"7b4585f8a4e4904239994a1b8bdc76299da8e46a8a632fabc6c33dd4170f8f3715e4c4f526ea5dd14093b150855960e432b1b140594aca21995f9e0722fb57f1","up":true,"other":"a1fe0d27f82309911a4b758c4e597bde16adc1e2fdfb07b52dea5092cea40ff212ea2cc831e385094b044f519909cf978f350b16ffd4c70c159cf1372301a3cf"},{"one":"f52281c227aa82a3bd5fabfdcf8bdf1d9ea6739ab9b9075340143d59b4f2f8a79a981609c9f42823a0253c19a7281eed0e912e4054363ab7fe50117563ef14e0","up":true,"other":"0c82c4b414375479375703ed9c19fb08c8143229ed4f1dcf448c6cf313810c098905123bec17969276936ae0cc39ed251b2811dbffb551d61159862b0eac0a23"},{"other":"e33a1476fcb8d2a1b9ee15871a960ce7a3337c93f5956a2825b1f8b2885dbdc0ed652b1eba549523866632b5b6898310bc638d946a9fcce27d65117eb44c25f3","up":true,"one":"2751df9f64a8f2ff8ea45efc9bd02b281d963ced285260bcda7f9dfaed998fe4386fe65a7265876da6b4fee77ea5c12454869a70ad627da7ca888076fc629665"},{"up":true,"other":"70cce7cb0c18091dbb6d41160ab560935f1759b969bf8118cee030ee707cb15ba407b8c48dcd9fd012cbf778e219f7d16a74064b4983cf098fb118297748edb6","one":"fee3fa1ba2a051d40a582908384ee81179db6c2b5f4bfa58c24f8015b794b43a093ed68b69bb209684135f972a055a9845978fa1b7d489e2126c3b514297f1c2"},{"one":"7d9979c13cd8841e84e5d199fc263962ca6fee12664d8526a581bfcdca2e3427ca169b9a0244dd8292a9a1be2bcedb0e8f626eadd307068c11c03b6df13aee33","up":true,"other":"bc0df855bdadcde3e447415444f655eb430925a8fa81cdcac75909e7d79750f01827938570e75e388cc7058ba8ebca47afadf8b07172bc078488fb618ba71024"},{"other":"a58a4db7a96b1578935b222c78b7b4dd8b3519d2995c3616e5a154c5175242a503097771332504638a0b321b9574110207f9a7d77b109d1de3d66a12ec6498e5","up":true,"one":"58f9139905ae1d005950f110b7ead3355672ecc478e8c66393566c64b935003f6fec3031dc9eb21cda660acb1955cf7bb33a20fdd74d493f29868ace328fcd75"},{"one":"8f3e9102306a13adb91e01f7a847e7880054f1a7df8976d05facb3a8fb37d47cce04f25e18a19713e5c3da7541e96e829fc67c8b924b717d2d9586c9c12d4fcf","other":"4e88cc60efee147fb72a735775944c7b2ba0790e2b2b935b4b3c2da9a3158a2a7aae411e9204cdbe6b2304d90a3a8278f8bb1a800a409e8500d100d84ba1947f","up":true},{"other":"bc0df855bdadcde3e447415444f655eb430925a8fa81cdcac75909e7d79750f01827938570e75e388cc7058ba8ebca47afadf8b07172bc078488fb618ba71024","up":true,"one":"5a235aca7005df295d5bd924b1272452e9bdad408ca5223b9eb76800b4bd4e3158a1d663ce5243fee92233227249fe4bb8507e8cb2c3729744b273bf488ba60c"},{"up":true,"other":"0c82c4b414375479375703ed9c19fb08c8143229ed4f1dcf448c6cf313810c098905123bec17969276936ae0cc39ed251b2811dbffb551d61159862b0eac0a23","one":"228b3646b15527f4df07b847a62dbf9620cb068f829e9086b5f437d0b64d8a027cab44f19db5e44189b5099545ecb25d49384c261748f9533cfb0eb11a1eca5f"},{"one":"81dc656de121016bcde81d5bf7919839acfc180dfbf1a6de2cadf704ff13af98aa5715a4168832ca6f651b2ea7ad9e6ca5f1c1cb7e885dbc2eb23d4aefb87bd6","other":"b18c7131a319db61ab84d06e90092d93c91141e9a270630af9c3ab1eaf3bcad09f4d20a1fc845b21c994bf4d9e337d0bd756a75e2198097540355e7ebbb531b2","up":true},{"one":"d6747e1f8594f7449fc6d7c0e63ee843480567d498db096ff04229420861c83bca5215fc19d8fede0c54484f111f1f2581e189e638c21c5d9e1fd3174bbb3e98","up":true,"other":"243164c4dd583f80c50813f43e5c27c894463400cd3afd776b36e79e7123d9261f01f06f92914aab83096b9a43fb655e79687590599284640a3a7d2c25454597"},{"other":"df9306a263f40e0e255996500523354de3cc78b68ae560f66d79f6ea28f30f773f1fd6ebc33928723dfde2ee3d4f982b203bee4c3803a5050df83477045bb279","up":true,"one":"ecd217e8bdb53c9ef085929b8c2d2b40425a4be617a087b8e7f88e8507b3c981e90fda2119744ca394fe65bd4eb1cdd3fa7258db936048e236d2f15ee91bc3b6"},{"other":"a1fe0d27f82309911a4b758c4e597bde16adc1e2fdfb07b52dea5092cea40ff212ea2cc831e385094b044f519909cf978f350b16ffd4c70c159cf1372301a3cf","up":true,"one":"ab13f773f6f2ff73032aa5f79c8897b75dda29bcbb14aa511e9401c2417dc9c510253071e28c7833c8d62fd2aef16fcd0c14ce016fbf4fec1b9a2173c717603f"},{"up":true,"other":"5114329db828f9568ccb0d7643a10e273aa626177910f55e22a53abf1ce8ec75b95465c983446b20eac0ff9c59c5dc53eca95b24aabcc8dd110e397cd2934047","one":"b60def37233dbbc0d5f7fcddb304be1c0b6508e1e3d8a09a8290f7363e9bb84152dcaf70b8f6bb3a882fee77ff03ab796a5c1c3654f251c9f5c746ac5ad88556"},{"up":true,"other":"c088bf88f1e152ca3fad17f098a71ca1021d46d8af12d0ee1c587a5e2a430d8e48beaf171fe01ee7680b671c00dd88c90f12a35c328a3f334661fdeee914a4bc","one":"a25958cf192a4f62301feda5d442535f78b983dd9e4599354f4898c8c1e6ad97ca7112549e1d1a1eacb4682cd1bf8b762368b5905ab33dbdacb585b128514ca1"},{"one":"222d7a2f94dc82a09fda70b8195fc3a60433a90f53998872318c57625c528c90572d78b444ac4901dcfece1a03ef8b6cbe7845366a845a942f341f6db58a9b3b","other":"c088bf88f1e152ca3fad17f098a71ca1021d46d8af12d0ee1c587a5e2a430d8e48beaf171fe01ee7680b671c00dd88c90f12a35c328a3f334661fdeee914a4bc","up":true},{"one":"af9b80f6836113aeda897d6903e9ffb4f7f1a706a7f821d0d40f03a0d83c18d6a19795ee4bfc1093ada04014415b1f230db1d2f056df3f5027cce71611588046","other":"b4557089e4247379e587a087f53b36dd1f86f85d9dcfab5dc562079978cd959adaef5b30d11258d9cb552e7c5abddf5377a71d449febe8f2acb0aec3ebd8ba73","up":true},{"other":"431644cf162bc267237c4e798288888dd835c1b0546b0cc679782e33568988d75b4294f4aa08359a6b152ed9a0fbd13133681156bcf09a871c4f362615ea6dae","up":true,"one":"99a7649bdf2ee7f0bc049308b0997e33abb68481c05a573df9aea30da5a1f267df07b2c584e3e985baf31704f04ad2a2c4876e0f8555333be6d09f5080b583f1"},{"up":true,"other":"bab07c2e4dc09add884869b31fb474b6d7151f9cc331d831f55c2b088397370fb0a1e1592c8dff9c8bc8e83de9faf6e91683acfb2df1b41856d70e523a99d370","one":"b1dd1b08975319030626aab821032a0c687a103ee8942e8a2e2cf029dd72832a49630e78d2d8b184579f22178aca0e875f9fad701fb81afd2ac110ab2b417376"},{"one":"8f3e9102306a13adb91e01f7a847e7880054f1a7df8976d05facb3a8fb37d47cce04f25e18a19713e5c3da7541e96e829fc67c8b924b717d2d9586c9c12d4fcf","up":true,"other":"77e7d427b65b6c29c0d92c51184af73031bfa768a47fc20be6c264f422bf718865259c17c103bf47289b3abe62f93452781c6303d757e76d3d56ceeb26262fab"},{"one":"93073da602d6326a48464a8b6890220b3aae0abf5b6961180f3aff2a14573c43411bd519d3e0012a646ec2977be18915d95a36d935a69f93985f5307ea4e3ebe","up":true,"other":"3639f964feba681db9702cac3f02058f2e490fd7bffb217dc3480dc458decafd5955541fea89f0f6f14ee50a745eaf98b21363d6b4fb88c31bd32bf7845d524b"},{"one":"99a7649bdf2ee7f0bc049308b0997e33abb68481c05a573df9aea30da5a1f267df07b2c584e3e985baf31704f04ad2a2c4876e0f8555333be6d09f5080b583f1","up":true,"other":"fee3fa1ba2a051d40a582908384ee81179db6c2b5f4bfa58c24f8015b794b43a093ed68b69bb209684135f972a055a9845978fa1b7d489e2126c3b514297f1c2"},{"up":true,"other":"1b3107d9a96cfd11f4cd0ed8baeb7b23db1406c9c4a9dac76c772f49c0fc9404f6a4adae11120aa821757173f0cc1cb00e6ab555b5abffaae9001c0557cb75c9","one":"855667650e96c5ed2d9b0c82532ed1fb92f72b1ae926afafe09cf8f6e90e539aec5c4c2ab108f2c2a1ad7dd8b83ca92a98c550a1c9ed27e6632a7d2f6da4f970"},{"other":"212a8048ab9925171475e81dce047865df186222d673d524c810a9f613e4a21f3b130fa34c5f44974fbeaab1f6028177e71568e00a1184d9fd05443c172f5fcf","up":true,"one":"b1dd1b08975319030626aab821032a0c687a103ee8942e8a2e2cf029dd72832a49630e78d2d8b184579f22178aca0e875f9fad701fb81afd2ac110ab2b417376"},{"up":true,"other":"f98c0f4444a1ec80773454ddb691c226b81d8e2f79ed40c45a422d3359565edf7bd635d3eb7bd6c9e0870746849fb86f0b1b34cd56ec8d3ad969812e080f4983","one":"37399617d62153bc471f3bf21c92385bc8602c80ffa0c71da8aebae595a9859cfd56257aae60ad30ef3ec4d07dee90623cce63749c8c3233c0aa0d17f9e89afe"},{"one":"431644cf162bc267237c4e798288888dd835c1b0546b0cc679782e33568988d75b4294f4aa08359a6b152ed9a0fbd13133681156bcf09a871c4f362615ea6dae","up":true,"other":"699c923976c5b8c70c353840d3e384750f466954265f05fbb0d5877a2c0318a041dc57adc12ac6e8fbae7a00d6b6675e1a1be3a8f59dac12727ee3f8ae467a13"},{"one":"c6ad9b9de5cdbe28540f4eb7c66fb37f6d4295e6e60c6de54e2a45c1970b8e0047558e986bbd10e9e86c8bb0407846fac4823e4570e8a1486fc4bf55cb4a0986","up":true,"other":"243164c4dd583f80c50813f43e5c27c894463400cd3afd776b36e79e7123d9261f01f06f92914aab83096b9a43fb655e79687590599284640a3a7d2c25454597"},{"up":true,"other":"ecb93d8eba17afe92979e8154252a08dd58de6ff3188b6829e3e25967846686f54199ab2b081e77b0048dcab204f05aa2c5cbd0efae4bc43a612d471d4e1197b","one":"93073da602d6326a48464a8b6890220b3aae0abf5b6961180f3aff2a14573c43411bd519d3e0012a646ec2977be18915d95a36d935a69f93985f5307ea4e3ebe"},{"up":true,"other":"a8fac88fba179fb9b259d94caac9cbe45d873a0131bef8844ac4383b177daf6f301f8793623fec5876885db1a91e5b3e98e2aafdaa47e03b1f6d9740f48af7ac","one":"9e21f5d4cfb389ac3ad43497689878bd245a89c587a8637d832b1e355ba244f4c83e6499bc7936e6d35645db25910ecd89b9af9b6b2f0c7cc4d7c6114328d7bf"},{"other":"e903d7aebff96a6afa4b9dd19b0b02e5af18da8e4e89f64247e1a2c2d46637538c741182eac67f45ec61be76aeaccde57f0a0184bd608ea7d92e586d4f827ea7","up":true,"one":"723f362e98f90d7ef15e24e353759fdbdabb08adab767dba73ab546741fac3dfb457466f1e2c851aa49526da1408f8ddb509e12f7dc0bc1e785c5b72be8a986e"},{"one":"362ed9a92b588d5fe315b90a74aa27f7600e4a7d06b27ceb26272340388d916a831df85bf83450ef80bda4e4a21acaac60560c8a42940a26e2ac567519e2a202","other":"bb0749de05a97daa67de889c15831ce39a080d641b3b08e3c248b0b16f4c07943fea8dd054d4a7e3e4af91ecff07053ce90096485a360b6f1d93050d179f30c3","up":true},{"one":"6c95c653e15bb99d32656f35790400134cd7188e063f878e19cb9118eb469ae0362dc45255f2a1eae31520be01d42b5bc5bbebf03d644c9f206ca79cb33a01ad","up":true,"other":"06aab75fed9a03f5525e3f1d8f8997fefaefd5b16e8f485d571beda00b1741efbb61a8a74fa12c2f6de66227c3fabb4d411659cd9c7b1ef32e171e6bf517cc39"},{"one":"c6f38fe8a0f2b3773bae332e0ca7516e944bde186fe99daae10a2b0aecde3ce23c1834eaad97a4e6d2da8cd53a08dbafa72d2b827c851b115b74e8010125dba2","up":true,"other":"0c9a05514b96e7c3a0fbca21552e158faa70047246b230addca172a5023fd7439acd1c3a0b4f9191579b308dab38c961734ffdb36fb8e16383e912d070fc0218"},{"one":"5982e7dfd39c527851f6ea6430b70e654d95df5ec4401ca1d8dbd1034cf7a65d1126d60b36ebbd396c9ca32e6e8515f34f9dc0a8d2980afe4aa181c8bf68437e","up":true,"other":"2751df9f64a8f2ff8ea45efc9bd02b281d963ced285260bcda7f9dfaed998fe4386fe65a7265876da6b4fee77ea5c12454869a70ad627da7ca888076fc629665"},{"up":true,"other":"99af34b172d319633e07a4e528f416024653a230a9103a4b281171f75bb697dd6be4757558c94e86210b4da8d9fe1229f6a5d8c4174989ea0ce696f8d1a9995d","one":"ecb93d8eba17afe92979e8154252a08dd58de6ff3188b6829e3e25967846686f54199ab2b081e77b0048dcab204f05aa2c5cbd0efae4bc43a612d471d4e1197b"},{"one":"9f3af4577308965aceb7e0101443669496e7ccf1de680629862a7005966c708b6fb52e6dfe62660246b9892adc25838da2873502e0be706bcad8f25b7ceedfa5","other":"01427ba4d1e2de0b2764515556676a6058f88c16f597780dea3d7f95a6eec9299c3987d99c199d88a0a5e695ee6f0ff7de424e4eb65e54233b956a9634133998","up":true},{"one":"8e8614a4c2ee2b1a3fa5ace0ca353cff36b3de3308ccf53665b8b56f8e2456a8a65f3846d786dccd68b1bfcefdd170ea5f8edb481800b1ce72d9fce2added7f0","other":"1c080e90760dfcee08ade6e4ea3b275ff3c6882f3b44b7f3a73d70bcc816fc63ce0b6138f810d17d96ed387076f9bbb6dbb2ef6dc4d6ba6542c1f587b7602a12","up":true},{"up":true,"other":"29acdd4c1233441bd40f98e245ecc9de94de6f9d0ab7c1a9923d833a2c8e6c1bd26d792686fec762b31fe28bbdd7aa04c9a594d997d08c133bb24cb2d877595a","one":"43086ff7ffd3c7bdec77bd288f41f1ee0ce21bd3f60a5df8931e2af6e7af5ef0fad432d29625491935d11567944351fc7867c807ebd12dd2c21c9e620ae0f85c"},{"one":"9c8f156797deff649d74d56fc42b4bb1a87312089114d4350424c375837d9c8068dd09af01c1c973d12ec5d7e8da600cd685cae70d3116b9dbda823092e03fff","up":true,"other":"723f362e98f90d7ef15e24e353759fdbdabb08adab767dba73ab546741fac3dfb457466f1e2c851aa49526da1408f8ddb509e12f7dc0bc1e785c5b72be8a986e"},{"one":"52cf04f88d8b00214f11f329ebacca69291958372aa8ccfbe3cfdbc03d51d90389f3c307b82c108f0c074d78aeac0b48e8b8c8f3bf3b20b21d9747f284075de2","up":true,"other":"a48cd04cdc66e1bb182529a789e1417d60d5e7d0f73068c1b17c6f231defeb943357789123e8d89cad90d1dd1726c48b808300d213bc1ddf7ae43cd58527f1f3"},{"other":"9f3af4577308965aceb7e0101443669496e7ccf1de680629862a7005966c708b6fb52e6dfe62660246b9892adc25838da2873502e0be706bcad8f25b7ceedfa5","up":true,"one":"f98c0f4444a1ec80773454ddb691c226b81d8e2f79ed40c45a422d3359565edf7bd635d3eb7bd6c9e0870746849fb86f0b1b34cd56ec8d3ad969812e080f4983"},{"one":"3639f964feba681db9702cac3f02058f2e490fd7bffb217dc3480dc458decafd5955541fea89f0f6f14ee50a745eaf98b21363d6b4fb88c31bd32bf7845d524b","other":"99af34b172d319633e07a4e528f416024653a230a9103a4b281171f75bb697dd6be4757558c94e86210b4da8d9fe1229f6a5d8c4174989ea0ce696f8d1a9995d","up":true},{"up":true,"other":"1e3a2f2491b6acb07a9549d9929d150479a0313c926b0e236237bd541303da4b563a855016a90ab50e59d94803ad566798570fa981464c94c04a4a4a94fbc607","one":"7cc9389c8f751465e0b94baed896f6f122631052300b1b5b23d3c7656e4d11014a7a9ae62a1287bb040ca37221871a566cd470e523846df7e3acb5f94c7cde06"},{"one":"842ec3faa8b4a4cdec32abfa00ae827277fe2696e1b0c6551154533b16cf75ae69caf834b4f08488fa5c8b322fb633b1fd8a5b7d436e9c589cc9074dc031ae68","up":true,"other":"4e88cc60efee147fb72a735775944c7b2ba0790e2b2b935b4b3c2da9a3158a2a7aae411e9204cdbe6b2304d90a3a8278f8bb1a800a409e8500d100d84ba1947f"},{"one":"76643f67075c6e45bd176db19473240cda6f886d1cac25330e2d99c84a429934f4c6a606c9c72574d5eaccd0a3f1770dab05e6ff6a5b5ce4d7258fed2bc13d48","other":"d09104c44648391693ca64a57baa5ef54ed717e19c65ad0a0921d08cbaca8877d0190795d15f75f3b6ce6e676d6b0e55d5ee8fec3310c68b7060a32f7ff649cb","up":true},{"one":"70cce7cb0c18091dbb6d41160ab560935f1759b969bf8118cee030ee707cb15ba407b8c48dcd9fd012cbf778e219f7d16a74064b4983cf098fb118297748edb6","up":true,"other":"9c8f156797deff649d74d56fc42b4bb1a87312089114d4350424c375837d9c8068dd09af01c1c973d12ec5d7e8da600cd685cae70d3116b9dbda823092e03fff"},{"one":"e1f23e1caba66f5ff821edbc4a3d527539937f73d86dd0df43aa1266a99f51f2480a77961eff177fbbf852fc52cb9317179f80b1580194daaedadc3b00510751","up":true,"other":"d09104c44648391693ca64a57baa5ef54ed717e19c65ad0a0921d08cbaca8877d0190795d15f75f3b6ce6e676d6b0e55d5ee8fec3310c68b7060a32f7ff649cb"},{"other":"b1dd1b08975319030626aab821032a0c687a103ee8942e8a2e2cf029dd72832a49630e78d2d8b184579f22178aca0e875f9fad701fb81afd2ac110ab2b417376","up":true,"one":"9bea5f82c2a390587de44d620d6637834e6f2329cd83d8df6305b03b75d9b543160b6c6f9f8887e6bc88f1d0726435d6c8ad813aadad0653b0790b8f6388413a"},{"up":true,"other":"8fb6838337f832445531764ddafc3c747b2607f2f33e244685d6de621c2b53264270f5504187e43b7fa5cda53e66dd00b16c06879c82fb38a3d9e8aec4060210","one":"d09104c44648391693ca64a57baa5ef54ed717e19c65ad0a0921d08cbaca8877d0190795d15f75f3b6ce6e676d6b0e55d5ee8fec3310c68b7060a32f7ff649cb"},{"one":"4ff2981a47da46c753090e193a8bf43c3372a6b07a37cf0552de2ced455fbb8a76d969cd97b3e4601d8a808bd2a73f7729ed8a61df2f2a0c2cee1425d0bd9ab4","up":true,"other":"5a6318af8b4615cf30610a05ade7704182fefd0a3fb3d76c47cb392e114d8d30004f0ec214326b11532fd1e928e66f632bbcde126a94c87774063853a9518dc5"},{"up":true,"other":"224c3b969149d50d1bb4f473bb9725223c1dafe152efe1b08e8859213c543a66565b5d68a99cef3d5f4eccad6282a12f78d7b38eec14deebf44ad8dd9cba8680","one":"b1dd1b08975319030626aab821032a0c687a103ee8942e8a2e2cf029dd72832a49630e78d2d8b184579f22178aca0e875f9fad701fb81afd2ac110ab2b417376"},{"other":"c402495c2110a6531a530ebdcd9ab1b883f1c707fe25aa13a255a0a9edb4113669b4aee9eadf803f9fe4c2ef66d5e4dff7064549f672598410f2d9794747a600","up":true,"one":"6909a0fa47718cfc463b1e96c21734b46bd5b28dd59cd3d66d67990783436b7538ab2659d427029b97c8dddf313b26532518c0c34a2b1fca8cd852b0fdb83ab8"},{"one":"48e35d67e14ee2f329c0275bc965829b761885dbc3671f4673d84d76d18a5b6415e619e219b5d90761a5c6bd2f43c6a58708286a063daf46b502944f8ef9230b","up":true,"other":"588df3185f63a5443d8c6b972f67805f0557184d916005f537a4b27cd02bd6a12e432a2b34b234a34f22e923c6f116da85be20bad77a2bf69913684e9d0732ba"},{"one":"da22fb43c6d230d92f9c09454e282dc45dffc759740566039f1bdfb58171c6801f721841de83217277b3fb70983e7d34da53bbf25d1d45413a78d9afff151826","up":true,"other":"ecb93d8eba17afe92979e8154252a08dd58de6ff3188b6829e3e25967846686f54199ab2b081e77b0048dcab204f05aa2c5cbd0efae4bc43a612d471d4e1197b"},{"one":"ecb93d8eba17afe92979e8154252a08dd58de6ff3188b6829e3e25967846686f54199ab2b081e77b0048dcab204f05aa2c5cbd0efae4bc43a612d471d4e1197b","other":"fee3fa1ba2a051d40a582908384ee81179db6c2b5f4bfa58c24f8015b794b43a093ed68b69bb209684135f972a055a9845978fa1b7d489e2126c3b514297f1c2","up":true},{"one":"baa28b8cb7ec539e0e157d7598cc5a5b0210fd8fb5c9026c3cd612133c5a8ee56997507511928af5683cb620fd85593dd8f6ff882d95fb847870ae4ce7dc503b","other":"49256eccce3e036928a4b6b346126c6777dca5ea0134de85efca340f97ad0f827f3094f1562e3e186d35b8292a50c20ffae01409890bbb78598494285e14dc2c","up":true},{"one":"77e40e42f570a217f707888c714deb31fd70c856ae4b9a44ec7cee02768185dc4d7ed210429607f06690b32edd9fb06b304aff330a3949cc2fd49db1bc392edb","up":true,"other":"02fdbcb00f20a3f6e894900d798fcb0aca9e21f5b107924c0999eb396220f16dee99fc80ccba796e66e69dcb9ce278b7e0e4539c7a7cd0fbc1037bf8e56c1e67"},{"one":"99a7649bdf2ee7f0bc049308b0997e33abb68481c05a573df9aea30da5a1f267df07b2c584e3e985baf31704f04ad2a2c4876e0f8555333be6d09f5080b583f1","other":"699c923976c5b8c70c353840d3e384750f466954265f05fbb0d5877a2c0318a041dc57adc12ac6e8fbae7a00d6b6675e1a1be3a8f59dac12727ee3f8ae467a13","up":true},{"other":"02fdbcb00f20a3f6e894900d798fcb0aca9e21f5b107924c0999eb396220f16dee99fc80ccba796e66e69dcb9ce278b7e0e4539c7a7cd0fbc1037bf8e56c1e67","up":true,"one":"c206d8689068488179e86ce549de75989e0b17cbe09880d18fcf0fa212e629345f1b899203607a2b083569cb3f8398e501843166f5db23ac7fa7dacfe26dd3f4"},{"up":true,"other":"207764262a208c17db61fda4208d4664bf74010e0ad051a863e131e748c9304e11ccf007c925488ea86b974ee61cdac3dca4d4b3f4043524e03c194ab3c8eb5a","one":"4ff2981a47da46c753090e193a8bf43c3372a6b07a37cf0552de2ced455fbb8a76d969cd97b3e4601d8a808bd2a73f7729ed8a61df2f2a0c2cee1425d0bd9ab4"},{"one":"c29e80096fbe7bc9fcbfdbe3cf6c06449192a3ed280e46a1fa5d424428d893c3456c985c1352c119236cf783834365439751cc87e7ed196614705dd3db6674cf","other":"fee3fa1ba2a051d40a582908384ee81179db6c2b5f4bfa58c24f8015b794b43a093ed68b69bb209684135f972a055a9845978fa1b7d489e2126c3b514297f1c2","up":true},{"one":"8ee65c0937cdf860d5329132c34bf28b5dc4d2593986fae80e4b35efb54ec24cdbf294223515363a917a22dbc6db463c10c7484e22b479b9010059c2521b6317","other":"c402495c2110a6531a530ebdcd9ab1b883f1c707fe25aa13a255a0a9edb4113669b4aee9eadf803f9fe4c2ef66d5e4dff7064549f672598410f2d9794747a600","up":true},{"up":true,"other":"5717a49591a0ecdff3d4449874d5ff9ba016afad5da19712ca0c8ebca8cefd84e6d8c778245f67f68c8dd730ad294fd017b8de279fde4fc919768ce85dba132d","one":"6909a0fa47718cfc463b1e96c21734b46bd5b28dd59cd3d66d67990783436b7538ab2659d427029b97c8dddf313b26532518c0c34a2b1fca8cd852b0fdb83ab8"},{"other":"99a7649bdf2ee7f0bc049308b0997e33abb68481c05a573df9aea30da5a1f267df07b2c584e3e985baf31704f04ad2a2c4876e0f8555333be6d09f5080b583f1","up":true,"one":"224c3b969149d50d1bb4f473bb9725223c1dafe152efe1b08e8859213c543a66565b5d68a99cef3d5f4eccad6282a12f78d7b38eec14deebf44ad8dd9cba8680"},{"one":"77811b007dd1fc1b11e447858df37062e97b6fc14e059399814f3b4736188e3fb28bf7c3958bb8ebc6ae16c36884ba7c98b810fb6f8b358323412123c803abd4","other":"0c82c4b414375479375703ed9c19fb08c8143229ed4f1dcf448c6cf313810c098905123bec17969276936ae0cc39ed251b2811dbffb551d61159862b0eac0a23","up":true},{"other":"c0bec7375c66bec98524ade2245c1d7480516fc5d87a3249e64ec86418e80e202f1e3da76832e97bbc3dcaed8c96ca344e4829347b4428f4b1cb61999e404c05","up":true,"one":"c61ffc88f23f9f536497cc10ffcb7000ec6c4b801998ae7075ddc9079fdc1da8350e68744dc9e95ff892dfc5e52c62a3ad913a87fdacc455aea99b09aa002b57"},{"other":"b4f300abda4cf6e383f997510eb681e9fa62e23577e3c19bd7447fa1f5702a4e034cea5944248e7c6e6e92b5ae69195c3e8a2c5ca7827b4f4a00cc8546e6695a","up":true,"one":"2751df9f64a8f2ff8ea45efc9bd02b281d963ced285260bcda7f9dfaed998fe4386fe65a7265876da6b4fee77ea5c12454869a70ad627da7ca888076fc629665"},{"up":true,"other":"699c923976c5b8c70c353840d3e384750f466954265f05fbb0d5877a2c0318a041dc57adc12ac6e8fbae7a00d6b6675e1a1be3a8f59dac12727ee3f8ae467a13","one":"ecb93d8eba17afe92979e8154252a08dd58de6ff3188b6829e3e25967846686f54199ab2b081e77b0048dcab204f05aa2c5cbd0efae4bc43a612d471d4e1197b"},{"up":true,"other":"51df4f4d4f020f22f55a5fd00c7f9c68c232c167ae4d4e80d7695f8f39c5aa0a7b565c1c55bdd6a21e06fa056549d08fd2e9d76fd79e21295557aa30d1ae022c","one":"d6747e1f8594f7449fc6d7c0e63ee843480567d498db096ff04229420861c83bca5215fc19d8fede0c54484f111f1f2581e189e638c21c5d9e1fd3174bbb3e98"},{"one":"6ad4ea3730ddec500e56248d1025aea79ec10f0d6a9720ee48026df10e219b41965d7a611fd99ee765f6afbc8c977db7e67c3a340881904acb983d1e2fb016cc","up":true,"other":"5a6318af8b4615cf30610a05ade7704182fefd0a3fb3d76c47cb392e114d8d30004f0ec214326b11532fd1e928e66f632bbcde126a94c87774063853a9518dc5"},{"other":"5a6318af8b4615cf30610a05ade7704182fefd0a3fb3d76c47cb392e114d8d30004f0ec214326b11532fd1e928e66f632bbcde126a94c87774063853a9518dc5","up":true,"one":"a48cd04cdc66e1bb182529a789e1417d60d5e7d0f73068c1b17c6f231defeb943357789123e8d89cad90d1dd1726c48b808300d213bc1ddf7ae43cd58527f1f3"},{"one":"29619924833116cb1160bf7a8066a528b7182794368bfae62b5bacbae680d9161a479f217e30c3b4f19a250b1b59e08f86c94726117dc3bc94ff9ceac6bee6e4","up":true,"other":"da22fb43c6d230d92f9c09454e282dc45dffc759740566039f1bdfb58171c6801f721841de83217277b3fb70983e7d34da53bbf25d1d45413a78d9afff151826"},{"up":true,"other":"bab07c2e4dc09add884869b31fb474b6d7151f9cc331d831f55c2b088397370fb0a1e1592c8dff9c8bc8e83de9faf6e91683acfb2df1b41856d70e523a99d370","one":"224c3b969149d50d1bb4f473bb9725223c1dafe152efe1b08e8859213c543a66565b5d68a99cef3d5f4eccad6282a12f78d7b38eec14deebf44ad8dd9cba8680"},{"up":true,"other":"5a6318af8b4615cf30610a05ade7704182fefd0a3fb3d76c47cb392e114d8d30004f0ec214326b11532fd1e928e66f632bbcde126a94c87774063853a9518dc5","one":"c402495c2110a6531a530ebdcd9ab1b883f1c707fe25aa13a255a0a9edb4113669b4aee9eadf803f9fe4c2ef66d5e4dff7064549f672598410f2d9794747a600"},{"one":"7dd2801259c071a6e1dcc01d1cb74775fdec92da1da0b1eaf5f893cd5ed118894493ca5284c12bbd6cf7959449bc610d26ac6c9ef2845d1645d425f56ac003fd","other":"8e65496318637446a51f0dc87d0a5cf82655866cd1579db1e381af52e12545172b9c88119999ccac3b8b8644efc9675ff183ebe7584c16eb40792cc21f7e9b76","up":true},{"one":"535287ca3d41fc1cdf20a964749a849c51d0aba285f41f447cc2b1dd6f5845b6b98e0241dbda0718b234ea850081bfbf9df01d1aa636d7dcbd99ef3c0a773aff","up":true,"other":"17ae0b24297a3e6e027884e5e4529b6646ae340f5736eebc6187a9b59832a445f3644172d92438351e3803e56a67472b29f3e1d48844ae2e11e5e6670eed1436"},{"other":"207764262a208c17db61fda4208d4664bf74010e0ad051a863e131e748c9304e11ccf007c925488ea86b974ee61cdac3dca4d4b3f4043524e03c194ab3c8eb5a","up":true,"one":"6ad4ea3730ddec500e56248d1025aea79ec10f0d6a9720ee48026df10e219b41965d7a611fd99ee765f6afbc8c977db7e67c3a340881904acb983d1e2fb016cc"},{"other":"33e9d4674b5b9b23e838583f01b429abca1330393dfc100b19ede6090a53df213011fae53169a66aa05d18e4cb497a17aa81eaedf1fe2e4348f9825c309438b5","up":true,"one":"a47697063a2fb973449bdabd0925e10944ba1f6d8b2cc5c38b295f611eea3402b5cf3ae857716a34d84194955f5ed61350affe56223349124c8233852141f9a2"},{"other":"207764262a208c17db61fda4208d4664bf74010e0ad051a863e131e748c9304e11ccf007c925488ea86b974ee61cdac3dca4d4b3f4043524e03c194ab3c8eb5a","up":true,"one":"624248a794fd62248024360f128b2e503c752340694a316bed420e5ed2cebeb5bf970df95a2806732237a26de3778222b0454e2e7d2875129b193e7890fd5b95"},{"one":"29619924833116cb1160bf7a8066a528b7182794368bfae62b5bacbae680d9161a479f217e30c3b4f19a250b1b59e08f86c94726117dc3bc94ff9ceac6bee6e4","up":true,"other":"207764262a208c17db61fda4208d4664bf74010e0ad051a863e131e748c9304e11ccf007c925488ea86b974ee61cdac3dca4d4b3f4043524e03c194ab3c8eb5a"},{"one":"52cf04f88d8b00214f11f329ebacca69291958372aa8ccfbe3cfdbc03d51d90389f3c307b82c108f0c074d78aeac0b48e8b8c8f3bf3b20b21d9747f284075de2","other":"6ad4ea3730ddec500e56248d1025aea79ec10f0d6a9720ee48026df10e219b41965d7a611fd99ee765f6afbc8c977db7e67c3a340881904acb983d1e2fb016cc","up":true},{"other":"a47697063a2fb973449bdabd0925e10944ba1f6d8b2cc5c38b295f611eea3402b5cf3ae857716a34d84194955f5ed61350affe56223349124c8233852141f9a2","up":true,"one":"eb58e478b16056e0af344397cf5f078a3312a6db2189ec2042ec06ab6550e3ee71ebcfeff1814332c552c12a5a488f96b3f2935e90a189d238da19d30a2c9874"},{"other":"535287ca3d41fc1cdf20a964749a849c51d0aba285f41f447cc2b1dd6f5845b6b98e0241dbda0718b234ea850081bfbf9df01d1aa636d7dcbd99ef3c0a773aff","up":true,"one":"3a2cacc430f13f31c52b7205455420cf0fb9ed9e28b0898b69ef97951bf295b29118e573a42dd97abe38fee5ab4c03dad9ff6dc448126cefc1da12b6c8e8d915"},{"other":"6ad4ea3730ddec500e56248d1025aea79ec10f0d6a9720ee48026df10e219b41965d7a611fd99ee765f6afbc8c977db7e67c3a340881904acb983d1e2fb016cc","up":true,"one":"624248a794fd62248024360f128b2e503c752340694a316bed420e5ed2cebeb5bf970df95a2806732237a26de3778222b0454e2e7d2875129b193e7890fd5b95"},{"other":"8d3ad57509b36c4ca5c4663f3d1977a3125e069078842634e6cfeb22c044281e3d02f06eafc6d2a60089f03d70f5134a6635c35563c9f911fd845a6ef9bc8952","up":true,"one":"33e9d4674b5b9b23e838583f01b429abca1330393dfc100b19ede6090a53df213011fae53169a66aa05d18e4cb497a17aa81eaedf1fe2e4348f9825c309438b5"},{"up":true,"other":"8ec699020ab5e7719fe23b80268b5d1d37052bb71f5d81200ae805cf27825823733206165f0a7507c2595853361dd122e9ec1b2deb543591e22b71ec0b873b5b","one":"a47697063a2fb973449bdabd0925e10944ba1f6d8b2cc5c38b295f611eea3402b5cf3ae857716a34d84194955f5ed61350affe56223349124c8233852141f9a2"},{"one":"8d3ad57509b36c4ca5c4663f3d1977a3125e069078842634e6cfeb22c044281e3d02f06eafc6d2a60089f03d70f5134a6635c35563c9f911fd845a6ef9bc8952","up":true,"other":"8c459100df488b992fdad207a096a434d67cb733619adfd09a311095568d4c9db293d9a892675551805559456d49a3fdb19c2cc698b14552bf0ace584d4d90dc"},{"one":"3a2cacc430f13f31c52b7205455420cf0fb9ed9e28b0898b69ef97951bf295b29118e573a42dd97abe38fee5ab4c03dad9ff6dc448126cefc1da12b6c8e8d915","other":"17ae0b24297a3e6e027884e5e4529b6646ae340f5736eebc6187a9b59832a445f3644172d92438351e3803e56a67472b29f3e1d48844ae2e11e5e6670eed1436","up":true},{"up":true,"other":"8ec699020ab5e7719fe23b80268b5d1d37052bb71f5d81200ae805cf27825823733206165f0a7507c2595853361dd122e9ec1b2deb543591e22b71ec0b873b5b","one":"eb58e478b16056e0af344397cf5f078a3312a6db2189ec2042ec06ab6550e3ee71ebcfeff1814332c552c12a5a488f96b3f2935e90a189d238da19d30a2c9874"},{"one":"c2a9c77247871cfa4d3c2d1b47619df91ed5b331a44c8e21f7c9ce431a4db9dfb87713558cc8a37911393907b4cc60be9445bad18adcea1bc5f318256e71be14","other":"90b8e73916046b5433dce049bfe125ca2bf2fb390ff7301f9bc5d8d0183988577aa2a7392aaa28091aa81c8ac23942b5751420b9ee48e488a68411f9d2b1e5d5","up":true},{"one":"535287ca3d41fc1cdf20a964749a849c51d0aba285f41f447cc2b1dd6f5845b6b98e0241dbda0718b234ea850081bfbf9df01d1aa636d7dcbd99ef3c0a773aff","other":"b9c7b885430b9b1a4425bde30b3629559f5437e0e30a0299fc6f6e097cbcca8af9e285caf5dea685a0237f60e06f490c39a1e3e487f14a2b9f41a5135f2ba994","up":true},{"up":true,"other":"2cb076669efbaf2ff0b181a1b454061a31ef23937a40405022b126f0eb4bfba60c9e3397009d8c0ff0cabb603692532d0072c18c6838f43397c98483306f62db","one":"8ec699020ab5e7719fe23b80268b5d1d37052bb71f5d81200ae805cf27825823733206165f0a7507c2595853361dd122e9ec1b2deb543591e22b71ec0b873b5b"},{"up":true,"other":"7dd2801259c071a6e1dcc01d1cb74775fdec92da1da0b1eaf5f893cd5ed118894493ca5284c12bbd6cf7959449bc610d26ac6c9ef2845d1645d425f56ac003fd","one":"b3b4b203395bb6655d79ecdcee11638dd9a16baccfcc1f6fcc8b31832c8ca35650eb6c2802104eeec6d96ea80404381a2bd9b01dcadc748a4666b761d9ce64f8"},{"one":"8d3ad57509b36c4ca5c4663f3d1977a3125e069078842634e6cfeb22c044281e3d02f06eafc6d2a60089f03d70f5134a6635c35563c9f911fd845a6ef9bc8952","other":"5a6318af8b4615cf30610a05ade7704182fefd0a3fb3d76c47cb392e114d8d30004f0ec214326b11532fd1e928e66f632bbcde126a94c87774063853a9518dc5","up":true},{"up":true,"other":"9309549fc50173d6826fe63cf18699f49199c3789616b843042fe1a6adab6ed4bdd7a7a06acd276e0398cf8bffb26c12a4227725d7bbd386a9a55fc601c21405","one":"d09104c44648391693ca64a57baa5ef54ed717e19c65ad0a0921d08cbaca8877d0190795d15f75f3b6ce6e676d6b0e55d5ee8fec3310c68b7060a32f7ff649cb"},{"up":true,"other":"5d002c37b74a6656db86f102b0cec82bc35a819a480e5a2952db0140ebab65dffeb1a79f04d53ff61447b5fad7c58cb75ea1c91ea47fcb9e024f27b92c6c874d","one":"96cd4caa32c0b3a3493e24e13fad1ef75c621005d74154c3fc8a73cca4c0120452b6432334d94849c63f75d56a2943a453c86d2a14ad1fb61ae6833e58451187"},{"one":"9e21f5d4cfb389ac3ad43497689878bd245a89c587a8637d832b1e355ba244f4c83e6499bc7936e6d35645db25910ecd89b9af9b6b2f0c7cc4d7c6114328d7bf","other":"6c40910f0556f892a7542989fa01d7e3682fca89aeefb5ed885808f88ff17b6d13862f461c10d629a005ae67abef542d75e5b20816891b6944f71560f5c2dfa8","up":true},{"one":"99a7649bdf2ee7f0bc049308b0997e33abb68481c05a573df9aea30da5a1f267df07b2c584e3e985baf31704f04ad2a2c4876e0f8555333be6d09f5080b583f1","other":"20f6a8be1d2d8b5d6a43d851a2f5475385ef07fab80ac46525d0beccf3e25c01d726cfb3a1179e8343b1e88d21684fb24dd6e6497537d4e7e9edd59cb95d1b8d","up":true},{"up":true,"other":"01427ba4d1e2de0b2764515556676a6058f88c16f597780dea3d7f95a6eec9299c3987d99c199d88a0a5e695ee6f0ff7de424e4eb65e54233b956a9634133998","one":"a58a4db7a96b1578935b222c78b7b4dd8b3519d2995c3616e5a154c5175242a503097771332504638a0b321b9574110207f9a7d77b109d1de3d66a12ec6498e5"},{"one":"96cd4caa32c0b3a3493e24e13fad1ef75c621005d74154c3fc8a73cca4c0120452b6432334d94849c63f75d56a2943a453c86d2a14ad1fb61ae6833e58451187","other":"7c6e6a49429a4e24aa4aa5c7ba19684f77cd67d3744688baff6e7f1d74b7e9d2df85f3e57e0df0a9b960b5bf982a610c5639c3e7a6935ba13fbc77243b2dad19","up":true},{"one":"431644cf162bc267237c4e798288888dd835c1b0546b0cc679782e33568988d75b4294f4aa08359a6b152ed9a0fbd13133681156bcf09a871c4f362615ea6dae","other":"8fb6838337f832445531764ddafc3c747b2607f2f33e244685d6de621c2b53264270f5504187e43b7fa5cda53e66dd00b16c06879c82fb38a3d9e8aec4060210","up":true},{"one":"baa28b8cb7ec539e0e157d7598cc5a5b0210fd8fb5c9026c3cd612133c5a8ee56997507511928af5683cb620fd85593dd8f6ff882d95fb847870ae4ce7dc503b","up":true,"other":"2b0a1f3a6466c6be1d7e84120db384fa37f7c73a01e9a105ae90e7d2203212ec974f016d3012afd26bc0f9a8411d0716cc59b6ecc9f665db12e306af8b34cb63"},{"one":"9bea5f82c2a390587de44d620d6637834e6f2329cd83d8df6305b03b75d9b543160b6c6f9f8887e6bc88f1d0726435d6c8ad813aadad0653b0790b8f6388413a","up":true,"other":"1e3a2f2491b6acb07a9549d9929d150479a0313c926b0e236237bd541303da4b563a855016a90ab50e59d94803ad566798570fa981464c94c04a4a4a94fbc607"},{"other":"b9c7b885430b9b1a4425bde30b3629559f5437e0e30a0299fc6f6e097cbcca8af9e285caf5dea685a0237f60e06f490c39a1e3e487f14a2b9f41a5135f2ba994","up":true,"one":"d7af0a0217ff98804aa05f8f926a8b6262363b5391d24cda8048cca5ca5982b407b7b098302d0db6d8dd9ac0883b2025b3de651617ed1a173181148295c6d336"},{"one":"c63b88f494b14d5a7c1da124ffebbd985d19806b91d4b111c83ae129c4ef19614469980a09fbeccebe3b0358dd16194bdb6452d0b3dbb43a5467e23bb13f40d6","up":true,"other":"bb0749de05a97daa67de889c15831ce39a080d641b3b08e3c248b0b16f4c07943fea8dd054d4a7e3e4af91ecff07053ce90096485a360b6f1d93050d179f30c3"},{"one":"842ec3faa8b4a4cdec32abfa00ae827277fe2696e1b0c6551154533b16cf75ae69caf834b4f08488fa5c8b322fb633b1fd8a5b7d436e9c589cc9074dc031ae68","up":true,"other":"77e7d427b65b6c29c0d92c51184af73031bfa768a47fc20be6c264f422bf718865259c17c103bf47289b3abe62f93452781c6303d757e76d3d56ceeb26262fab"},{"up":true,"other":"8ec699020ab5e7719fe23b80268b5d1d37052bb71f5d81200ae805cf27825823733206165f0a7507c2595853361dd122e9ec1b2deb543591e22b71ec0b873b5b","one":"c2a9c77247871cfa4d3c2d1b47619df91ed5b331a44c8e21f7c9ce431a4db9dfb87713558cc8a37911393907b4cc60be9445bad18adcea1bc5f318256e71be14"},{"one":"b3b4b203395bb6655d79ecdcee11638dd9a16baccfcc1f6fcc8b31832c8ca35650eb6c2802104eeec6d96ea80404381a2bd9b01dcadc748a4666b761d9ce64f8","other":"d7e3661c0af6754c875217f93d34b254f1f45fc1359a4c6146cd0efa4c6e12aed9a4fb0a21a136f73af4fc2c6d0a63cb809d81855bbc9f51e29d23d90f77b326","up":true},{"other":"b1dd1b08975319030626aab821032a0c687a103ee8942e8a2e2cf029dd72832a49630e78d2d8b184579f22178aca0e875f9fad701fb81afd2ac110ab2b417376","up":true,"one":"48e35d67e14ee2f329c0275bc965829b761885dbc3671f4673d84d76d18a5b6415e619e219b5d90761a5c6bd2f43c6a58708286a063daf46b502944f8ef9230b"},{"one":"f60755ee9464c7db769bb7237016fa165441d18ac3bfed7cd2a220a9bcbead202dd34eaf2f9398a3d36bdfc2671bbd46ac25ebe264a8118afe1b7d0bd38710f4","other":"e993be8034861aebc9bbd11115f25d9c719d43fcdefc323599616cc26240cee38dfc27bb7f339149a54a3c9ad13b2d6ca4f0ae690e4355605eda6b789c4a431e","up":true},{"one":"c29e80096fbe7bc9fcbfdbe3cf6c06449192a3ed280e46a1fa5d424428d893c3456c985c1352c119236cf783834365439751cc87e7ed196614705dd3db6674cf","other":"9c8f156797deff649d74d56fc42b4bb1a87312089114d4350424c375837d9c8068dd09af01c1c973d12ec5d7e8da600cd685cae70d3116b9dbda823092e03fff","up":true},{"up":true,"other":"8f3e9102306a13adb91e01f7a847e7880054f1a7df8976d05facb3a8fb37d47cce04f25e18a19713e5c3da7541e96e829fc67c8b924b717d2d9586c9c12d4fcf","one":"224c3b969149d50d1bb4f473bb9725223c1dafe152efe1b08e8859213c543a66565b5d68a99cef3d5f4eccad6282a12f78d7b38eec14deebf44ad8dd9cba8680"},{"up":true,"other":"207764262a208c17db61fda4208d4664bf74010e0ad051a863e131e748c9304e11ccf007c925488ea86b974ee61cdac3dca4d4b3f4043524e03c194ab3c8eb5a","one":"c402495c2110a6531a530ebdcd9ab1b883f1c707fe25aa13a255a0a9edb4113669b4aee9eadf803f9fe4c2ef66d5e4dff7064549f672598410f2d9794747a600"},{"up":true,"other":"99af34b172d319633e07a4e528f416024653a230a9103a4b281171f75bb697dd6be4757558c94e86210b4da8d9fe1229f6a5d8c4174989ea0ce696f8d1a9995d","one":"6ad4ea3730ddec500e56248d1025aea79ec10f0d6a9720ee48026df10e219b41965d7a611fd99ee765f6afbc8c977db7e67c3a340881904acb983d1e2fb016cc"},{"other":"8e65496318637446a51f0dc87d0a5cf82655866cd1579db1e381af52e12545172b9c88119999ccac3b8b8644efc9675ff183ebe7584c16eb40792cc21f7e9b76","up":true,"one":"a48cd04cdc66e1bb182529a789e1417d60d5e7d0f73068c1b17c6f231defeb943357789123e8d89cad90d1dd1726c48b808300d213bc1ddf7ae43cd58527f1f3"},{"other":"da22fb43c6d230d92f9c09454e282dc45dffc759740566039f1bdfb58171c6801f721841de83217277b3fb70983e7d34da53bbf25d1d45413a78d9afff151826","up":true,"one":"535287ca3d41fc1cdf20a964749a849c51d0aba285f41f447cc2b1dd6f5845b6b98e0241dbda0718b234ea850081bfbf9df01d1aa636d7dcbd99ef3c0a773aff"},{"one":"a47697063a2fb973449bdabd0925e10944ba1f6d8b2cc5c38b295f611eea3402b5cf3ae857716a34d84194955f5ed61350affe56223349124c8233852141f9a2","up":true,"other":"29619924833116cb1160bf7a8066a528b7182794368bfae62b5bacbae680d9161a479f217e30c3b4f19a250b1b59e08f86c94726117dc3bc94ff9ceac6bee6e4"},{"up":true,"other":"c402495c2110a6531a530ebdcd9ab1b883f1c707fe25aa13a255a0a9edb4113669b4aee9eadf803f9fe4c2ef66d5e4dff7064549f672598410f2d9794747a600","one":"8e65496318637446a51f0dc87d0a5cf82655866cd1579db1e381af52e12545172b9c88119999ccac3b8b8644efc9675ff183ebe7584c16eb40792cc21f7e9b76"},{"one":"8d3ad57509b36c4ca5c4663f3d1977a3125e069078842634e6cfeb22c044281e3d02f06eafc6d2a60089f03d70f5134a6635c35563c9f911fd845a6ef9bc8952","up":true,"other":"d7e3661c0af6754c875217f93d34b254f1f45fc1359a4c6146cd0efa4c6e12aed9a4fb0a21a136f73af4fc2c6d0a63cb809d81855bbc9f51e29d23d90f77b326"},{"other":"3f322f9b1f1f0692663bc3be11cf11386f4a14696aab610916cfcadf0234cce0c86b51c85ce2108e9bc21d50ad71cc10a6eeaec3fc7732908f3a8b193465a0ac","up":true,"one":"96cd4caa32c0b3a3493e24e13fad1ef75c621005d74154c3fc8a73cca4c0120452b6432334d94849c63f75d56a2943a453c86d2a14ad1fb61ae6833e58451187"},{"one":"228b3646b15527f4df07b847a62dbf9620cb068f829e9086b5f437d0b64d8a027cab44f19db5e44189b5099545ecb25d49384c261748f9533cfb0eb11a1eca5f","other":"d43bd6d3ae39a04e4e144a8a6f80b2d54472b5b9b6491dccf44b1716a63d24c56e3a871b3b8fe983d992988dc07ace06736ead3b1287914b629fcfe17e81f36f","up":true},{"up":true,"other":"e5cb29b25debcfaaacc0b04e708c8c1cb9d2dee29e82596a1c72a934032cf738800b9525cc277d0c5f5dacf2f278329b54da161b4bafa285243fa0e9fd7b2f3a","one":"b18c7131a319db61ab84d06e90092d93c91141e9a270630af9c3ab1eaf3bcad09f4d20a1fc845b21c994bf4d9e337d0bd756a75e2198097540355e7ebbb531b2"},{"one":"bc0df855bdadcde3e447415444f655eb430925a8fa81cdcac75909e7d79750f01827938570e75e388cc7058ba8ebca47afadf8b07172bc078488fb618ba71024","other":"8e89fe4b3fffea8af247d2581aa511056efbeb796058d50a341d57aa0f7ccc2192d90cfb8d18558363df798567faaddb86815e8bd671b36ca37af0651535aabf","up":true},{"one":"b18c7131a319db61ab84d06e90092d93c91141e9a270630af9c3ab1eaf3bcad09f4d20a1fc845b21c994bf4d9e337d0bd756a75e2198097540355e7ebbb531b2","up":true,"other":"0c82c4b414375479375703ed9c19fb08c8143229ed4f1dcf448c6cf313810c098905123bec17969276936ae0cc39ed251b2811dbffb551d61159862b0eac0a23"},{"other":"fc9b1b2bbd5e682eb350d23f3ee33b245495daedae9370de7b1f55f91cd45db831d196c17615e11decf6b67696a268ac788130e3de38c7f6aeae811f3ec8c8ee","up":true,"one":"d7e3661c0af6754c875217f93d34b254f1f45fc1359a4c6146cd0efa4c6e12aed9a4fb0a21a136f73af4fc2c6d0a63cb809d81855bbc9f51e29d23d90f77b326"},{"other":"a8fac88fba179fb9b259d94caac9cbe45d873a0131bef8844ac4383b177daf6f301f8793623fec5876885db1a91e5b3e98e2aafdaa47e03b1f6d9740f48af7ac","up":true,"one":"bc0df855bdadcde3e447415444f655eb430925a8fa81cdcac75909e7d79750f01827938570e75e388cc7058ba8ebca47afadf8b07172bc078488fb618ba71024"},{"one":"3f322f9b1f1f0692663bc3be11cf11386f4a14696aab610916cfcadf0234cce0c86b51c85ce2108e9bc21d50ad71cc10a6eeaec3fc7732908f3a8b193465a0ac","up":true,"other":"b152eb30c9f46ec39166016f03d289f98cc285ac62d204da32e5a003da14e4f02c64df8ae1d0c8a2a902adc5f7dd7604081a0b140c9b64052082f0861945f5a4"},{"one":"9c8fca41b833e88110559b9258653160f5fb236bd637272ac58fe1adf333f4df75b94a805eaebb9f10a8c1a26d357dd75140560551d3fc4da79da2c4fc9479c3","other":"8e5e8366251e33277e7db6f6c04629b2ce3eee217e973acb97c83773671b0160c40732794584db741a29a763672b90f3bdf34151fd4a6986b9d0956dc61d9723","up":true},{"one":"d09104c44648391693ca64a57baa5ef54ed717e19c65ad0a0921d08cbaca8877d0190795d15f75f3b6ce6e676d6b0e55d5ee8fec3310c68b7060a32f7ff649cb","up":true,"other":"f4cdaeb513aa98f8868d8eb3a1d12c07367725928a1bc7d6ca4b583788e111a955463037ec7867260511896d97dfbf096aa77ee8a7d9ea1c06cad4a92c45108d"},{"up":true,"other":"723f362e98f90d7ef15e24e353759fdbdabb08adab767dba73ab546741fac3dfb457466f1e2c851aa49526da1408f8ddb509e12f7dc0bc1e785c5b72be8a986e","one":"37399617d62153bc471f3bf21c92385bc8602c80ffa0c71da8aebae595a9859cfd56257aae60ad30ef3ec4d07dee90623cce63749c8c3233c0aa0d17f9e89afe"},{"one":"37adbfdf66163e45f433d78f63210163fdacf4688ad90d73bed07975be017c43cddf2a26a0dee8b11d78f294b63d4875b6be15f42f10817bd3d77b342919a11e","up":true,"other":"06aab75fed9a03f5525e3f1d8f8997fefaefd5b16e8f485d571beda00b1741efbb61a8a74fa12c2f6de66227c3fabb4d411659cd9c7b1ef32e171e6bf517cc39"},{"one":"ab1a3542d67ef9d1a63653990bf0782f53b0169fe5092adc92fa7aeb38f66c6b62d49e3455cc2ac4994bfcfb03111953acf4cc3099026672cc61f6e24cb3ae00","other":"1e3a2f2491b6acb07a9549d9929d150479a0313c926b0e236237bd541303da4b563a855016a90ab50e59d94803ad566798570fa981464c94c04a4a4a94fbc607","up":true},{"one":"7c6e6a49429a4e24aa4aa5c7ba19684f77cd67d3744688baff6e7f1d74b7e9d2df85f3e57e0df0a9b960b5bf982a610c5639c3e7a6935ba13fbc77243b2dad19","other":"fc9b1b2bbd5e682eb350d23f3ee33b245495daedae9370de7b1f55f91cd45db831d196c17615e11decf6b67696a268ac788130e3de38c7f6aeae811f3ec8c8ee","up":true},{"up":true,"other":"d3cd2f34f67830ccdc295b7537a6d27c02b44503808ca666124f52ecc3d6c35b7d3f14343997006aef2cfbefc8d27809d389477e99c236b9f8a897a4bc406a43","one":"313a131ecb7d68e127d0fec8bb4a2e586886203c3d07857a93e7a39bb831703184d9ae28ba9ef3d986c2dae1a24f4f5bfa47cfc35f74f5512a126836364d7736"},{"one":"a58a4db7a96b1578935b222c78b7b4dd8b3519d2995c3616e5a154c5175242a503097771332504638a0b321b9574110207f9a7d77b109d1de3d66a12ec6498e5","up":true,"other":"ee0b09ee6a1057c47102e582e2fdec7b9212802e59f062a9360da0db535d4987126ab24848c0d76fa8485431a5140307e2b0c0d9f37cbdb35756e6cc1bdb3bc0"},{"one":"10551c0c37abc25457903978868dd4843a52fda5f9b571b05ebd974d8c381fda4349f17c2b986a2e4b8d06b0517422f085d5f6d9cd814efa40e48393d9f71d7e","other":"5982e7dfd39c527851f6ea6430b70e654d95df5ec4401ca1d8dbd1034cf7a65d1126d60b36ebbd396c9ca32e6e8515f34f9dc0a8d2980afe4aa181c8bf68437e","up":true},{"one":"e1f23e1caba66f5ff821edbc4a3d527539937f73d86dd0df43aa1266a99f51f2480a77961eff177fbbf852fc52cb9317179f80b1580194daaedadc3b00510751","up":true,"other":"baa28b8cb7ec539e0e157d7598cc5a5b0210fd8fb5c9026c3cd612133c5a8ee56997507511928af5683cb620fd85593dd8f6ff882d95fb847870ae4ce7dc503b"},{"one":"c088bf88f1e152ca3fad17f098a71ca1021d46d8af12d0ee1c587a5e2a430d8e48beaf171fe01ee7680b671c00dd88c90f12a35c328a3f334661fdeee914a4bc","up":true,"other":"7d9979c13cd8841e84e5d199fc263962ca6fee12664d8526a581bfcdca2e3427ca169b9a0244dd8292a9a1be2bcedb0e8f626eadd307068c11c03b6df13aee33"},{"up":true,"other":"77e40e42f570a217f707888c714deb31fd70c856ae4b9a44ec7cee02768185dc4d7ed210429607f06690b32edd9fb06b304aff330a3949cc2fd49db1bc392edb","one":"b1dd1b08975319030626aab821032a0c687a103ee8942e8a2e2cf029dd72832a49630e78d2d8b184579f22178aca0e875f9fad701fb81afd2ac110ab2b417376"},{"other":"154d5ddb15ec12dc65362039d801383c189b5bcf6688883f2d7e3d0e8dc78e45f9f58d5dabc79a8798a243ce59abb95c77525db14f050fd8cb37d04b7276557c","up":true,"one":"5d002c37b74a6656db86f102b0cec82bc35a819a480e5a2952db0140ebab65dffeb1a79f04d53ff61447b5fad7c58cb75ea1c91ea47fcb9e024f27b92c6c874d"},{"one":"b87e7f36ed6bf142d48545024d2fd6e120c44511701e7c0b7d7fc786f4f29d3357024b15f70b78215d8a4c2b7572d608c11b31612743e23db4fa673f0cd6519b","other":"c9d705012a06d82c4d44db95b4f1c63ddd33ad64d732e96b1d878caa0caac433d4096f01495a6f0e8a56af122b0470fd745db6d906353b590a4710472b93f5b2","up":true},{"other":"e323da6ae861cb092543992b8985639f9b3bcaf1c3c68757f4603a67800be62950fe7d8f8ef80eb83a18107b677c7f5047ea89a5790e0ea2a7969f4856d28488","up":true,"one":"c088bf88f1e152ca3fad17f098a71ca1021d46d8af12d0ee1c587a5e2a430d8e48beaf171fe01ee7680b671c00dd88c90f12a35c328a3f334661fdeee914a4bc"},{"one":"a1fe0d27f82309911a4b758c4e597bde16adc1e2fdfb07b52dea5092cea40ff212ea2cc831e385094b044f519909cf978f350b16ffd4c70c159cf1372301a3cf","other":"c088bf88f1e152ca3fad17f098a71ca1021d46d8af12d0ee1c587a5e2a430d8e48beaf171fe01ee7680b671c00dd88c90f12a35c328a3f334661fdeee914a4bc","up":true},{"other":"dd6acfd151220f21b03701ca554a5e134dbd1154dda21d9eec45809e7858fe83eca3953fc688f499030198f22052c3681a9f49207ef9b11a760456ab9637352b","up":true,"one":"e0875ed6be1e163b15c13cdf37442f838670d0949349ee9ff119a0451beffb1a302943ee9d7cba48592922f64908aeb0f39f6e2e3725d1e7cdc5db34083b6977"},{"one":"5d002c37b74a6656db86f102b0cec82bc35a819a480e5a2952db0140ebab65dffeb1a79f04d53ff61447b5fad7c58cb75ea1c91ea47fcb9e024f27b92c6c874d","other":"9d372d73848389cfa1676f0cdb030950980ed5b68d5b2ef8a058f1d2095b26ff0fafab5fd3c243296ee2620edc67752970ab47370270856287f8612d1b190a19","up":true},{"one":"b152eb30c9f46ec39166016f03d289f98cc285ac62d204da32e5a003da14e4f02c64df8ae1d0c8a2a902adc5f7dd7604081a0b140c9b64052082f0861945f5a4","up":true,"other":"5d002c37b74a6656db86f102b0cec82bc35a819a480e5a2952db0140ebab65dffeb1a79f04d53ff61447b5fad7c58cb75ea1c91ea47fcb9e024f27b92c6c874d"},{"one":"b87e7f36ed6bf142d48545024d2fd6e120c44511701e7c0b7d7fc786f4f29d3357024b15f70b78215d8a4c2b7572d608c11b31612743e23db4fa673f0cd6519b","up":true,"other":"6a37e63feed9e68c52cb8b385d5e8d8dbd2b211c57ded0d3b01fe8b306af5c0e5a7405d0d9a942648f0131926240d53450bc43f922a053528e5830d918313c3d"},{"one":"c088bf88f1e152ca3fad17f098a71ca1021d46d8af12d0ee1c587a5e2a430d8e48beaf171fe01ee7680b671c00dd88c90f12a35c328a3f334661fdeee914a4bc","up":true,"other":"4eab70233789c544bec97040a04099494bf269a819584a5d0b42295c918a52b02f224a8ed127aba3d92c02f567356bea4b95f77230ef548dfa7fe44b643d8704"},{"up":true,"other":"e9cd25d1ef3fef22160bce7f7badd7646ac58ee40da6a438f61a067c51bc51d6087ed950ec9e909bc438ebe62e316cbd9489f3c9bfa2898615632414e04f1dcd","one":"ee3471e1d835c4294f7ba642103039ccc548fe4edc177c79b63433ebbb0dc9d06600844f1fed76c7096ee9538e49e4e86fb8cffe9095dbdcde27695ff28ad395"},{"up":true,"other":"0e164c8692532e59c76ef84319a1093324f46f77618d3a836a279df52edca6c839061c0582dac7481da1bd0f3e2b58fc0dacd6ee5d678ba1406d4a1a25fe761d","one":"ab13f773f6f2ff73032aa5f79c8897b75dda29bcbb14aa511e9401c2417dc9c510253071e28c7833c8d62fd2aef16fcd0c14ce016fbf4fec1b9a2173c717603f"},{"one":"a1fe0d27f82309911a4b758c4e597bde16adc1e2fdfb07b52dea5092cea40ff212ea2cc831e385094b044f519909cf978f350b16ffd4c70c159cf1372301a3cf","up":true,"other":"4eab70233789c544bec97040a04099494bf269a819584a5d0b42295c918a52b02f224a8ed127aba3d92c02f567356bea4b95f77230ef548dfa7fe44b643d8704"},{"one":"a1fe0d27f82309911a4b758c4e597bde16adc1e2fdfb07b52dea5092cea40ff212ea2cc831e385094b044f519909cf978f350b16ffd4c70c159cf1372301a3cf","other":"e7b2adabc2c99ac47b1e94fc0a2c63a00a1d622ea67a4c1858f4cec93fca957d43d8429605761bdf5eed4f733dac1a3d12fb928f22abf248965994acde63864a","up":true},{"one":"95ff4dea07303e1ba641a5c510e714ef232f4dbce9ad2e8b2f62644975eae41fc4bb9d1af3fae4d5ea4daeb18f8248e0b3131c7d843d35d33f3afbf7dfa4c2fe","other":"1c080e90760dfcee08ade6e4ea3b275ff3c6882f3b44b7f3a73d70bcc816fc63ce0b6138f810d17d96ed387076f9bbb6dbb2ef6dc4d6ba6542c1f587b7602a12","up":true},{"one":"b152eb30c9f46ec39166016f03d289f98cc285ac62d204da32e5a003da14e4f02c64df8ae1d0c8a2a902adc5f7dd7604081a0b140c9b64052082f0861945f5a4","up":true,"other":"2cb076669efbaf2ff0b181a1b454061a31ef23937a40405022b126f0eb4bfba60c9e3397009d8c0ff0cabb603692532d0072c18c6838f43397c98483306f62db"},{"other":"a070b5cff5eff533a2267ceb0d88e221088038af773e18f80110c8a2c329f0543b8d43c4e6132e9416723e3e94c87f0053456760ced4426767b95cee36ed93f8","up":true,"one":"6a37e63feed9e68c52cb8b385d5e8d8dbd2b211c57ded0d3b01fe8b306af5c0e5a7405d0d9a942648f0131926240d53450bc43f922a053528e5830d918313c3d"},{"one":"ee3471e1d835c4294f7ba642103039ccc548fe4edc177c79b63433ebbb0dc9d06600844f1fed76c7096ee9538e49e4e86fb8cffe9095dbdcde27695ff28ad395","other":"1cdef98d7b4de45c902c725384bd14c66084fe4159b26a0f9a24f432e1f561d035ca41e1c60fe64f3213b4f91a1afb953193dca1a7d535be0602b5d046bcbab8","up":true},{"one":"d6a7257771baa4d9944592ead46b8ab700dbf91ebd4dc0ec7e5fb41cbda0622944269172fcec8352b89ef2c186d4c787af2b45a50533f627a97818477de034b4","other":"51a570637394e9ab61fe95b3a608cc4e9dc8ceb63efe717938ccd4260a962d52e01b30e7034fbfdabd9a3c9616ee569550b38a6d6b4b19847f523254069a9f27","up":true},{"one":"c2568576c2c9ef47aca0baca52709a4fa44b2ed478a062f7b161fac2bdba68568df371ac7754255fd07d79bb9918249a914946a6c318d579730bee9bc609922a","other":"f5d95e0c5a873ff5a95e1eb34f1ed258d77adf98ee0886d93c4a24b1feaf6955e6e4c4ea0eccb2b9723870bae61e693643d6ad96dd8da01672542611f7c49069","up":true},{"up":true,"other":"9c8fca41b833e88110559b9258653160f5fb236bd637272ac58fe1adf333f4df75b94a805eaebb9f10a8c1a26d357dd75140560551d3fc4da79da2c4fc9479c3","one":"3e7aef8260c0d9717aa59b65ce7c554e53b81f19f5b9400321704a7ddf5041b0fe31b5634e90b93e6984060defee0e153997bbfe196166cc8d83165fd5eaf41f"},{"one":"c2568576c2c9ef47aca0baca52709a4fa44b2ed478a062f7b161fac2bdba68568df371ac7754255fd07d79bb9918249a914946a6c318d579730bee9bc609922a","up":true,"other":"b87e7f36ed6bf142d48545024d2fd6e120c44511701e7c0b7d7fc786f4f29d3357024b15f70b78215d8a4c2b7572d608c11b31612743e23db4fa673f0cd6519b"},{"other":"c9d705012a06d82c4d44db95b4f1c63ddd33ad64d732e96b1d878caa0caac433d4096f01495a6f0e8a56af122b0470fd745db6d906353b590a4710472b93f5b2","up":true,"one":"fc9b1b2bbd5e682eb350d23f3ee33b245495daedae9370de7b1f55f91cd45db831d196c17615e11decf6b67696a268ac788130e3de38c7f6aeae811f3ec8c8ee"},{"up":true,"other":"3639f964feba681db9702cac3f02058f2e490fd7bffb217dc3480dc458decafd5955541fea89f0f6f14ee50a745eaf98b21363d6b4fb88c31bd32bf7845d524b","one":"855667650e96c5ed2d9b0c82532ed1fb92f72b1ae926afafe09cf8f6e90e539aec5c4c2ab108f2c2a1ad7dd8b83ca92a98c550a1c9ed27e6632a7d2f6da4f970"},{"one":"e993be8034861aebc9bbd11115f25d9c719d43fcdefc323599616cc26240cee38dfc27bb7f339149a54a3c9ad13b2d6ca4f0ae690e4355605eda6b789c4a431e","up":true,"other":"eb58e478b16056e0af344397cf5f078a3312a6db2189ec2042ec06ab6550e3ee71ebcfeff1814332c552c12a5a488f96b3f2935e90a189d238da19d30a2c9874"},{"up":true,"other":"f60755ee9464c7db769bb7237016fa165441d18ac3bfed7cd2a220a9bcbead202dd34eaf2f9398a3d36bdfc2671bbd46ac25ebe264a8118afe1b7d0bd38710f4","one":"28cdd55fc871ffd8d63d05994be706959c9780dbfc859070a41047a1b40dd5fd7adb53919400a4c6f4d06c69bc1ecccc0e230e5b702598a7fe8003a282479872"},{"up":true,"other":"77e40e42f570a217f707888c714deb31fd70c856ae4b9a44ec7cee02768185dc4d7ed210429607f06690b32edd9fb06b304aff330a3949cc2fd49db1bc392edb","one":"7cc9389c8f751465e0b94baed896f6f122631052300b1b5b23d3c7656e4d11014a7a9ae62a1287bb040ca37221871a566cd470e523846df7e3acb5f94c7cde06"},{"up":true,"other":"8c459100df488b992fdad207a096a434d67cb733619adfd09a311095568d4c9db293d9a892675551805559456d49a3fdb19c2cc698b14552bf0ace584d4d90dc","one":"c0164fb4a1acfb4f3b1a09f9f3ab226c382529a73891937c6f3c91798098cf10b909eb92e5f8acfe0e8f3aee0b71cb23ee2d9e6ad1e0f4492a0272c52d529849"},{"one":"2c976b6007cda135444233c7bd03d22ac9756710b746c36bc032e7fdd42f2ffb89ca5f5e754ff96b8f3cbc474e346287e5b8531d9f98fd63c426c632872220af","up":true,"other":"4b332b389f1142c0da42aaeb2e2692081d0002de0eb6741b3269e898a8101571d4556b755f2e8841e7a607bb41e398d2b0577fbe71098e7097f0fe6c720e1526"},{"one":"bb0749de05a97daa67de889c15831ce39a080d641b3b08e3c248b0b16f4c07943fea8dd054d4a7e3e4af91ecff07053ce90096485a360b6f1d93050d179f30c3","up":true,"other":"43086ff7ffd3c7bdec77bd288f41f1ee0ce21bd3f60a5df8931e2af6e7af5ef0fad432d29625491935d11567944351fc7867c807ebd12dd2c21c9e620ae0f85c"},{"one":"a070b5cff5eff533a2267ceb0d88e221088038af773e18f80110c8a2c329f0543b8d43c4e6132e9416723e3e94c87f0053456760ced4426767b95cee36ed93f8","other":"9d372d73848389cfa1676f0cdb030950980ed5b68d5b2ef8a058f1d2095b26ff0fafab5fd3c243296ee2620edc67752970ab47370270856287f8612d1b190a19","up":true},{"one":"9ea856ea440c776b9ffaad1237ec11d570a1f912a908b8363ff97cf7947d2523e3c73663240d8fac988698cdd81e877ddd4a609485fe9f26494136fae14212df","up":true,"other":"e993be8034861aebc9bbd11115f25d9c719d43fcdefc323599616cc26240cee38dfc27bb7f339149a54a3c9ad13b2d6ca4f0ae690e4355605eda6b789c4a431e"},{"one":"b1dd1b08975319030626aab821032a0c687a103ee8942e8a2e2cf029dd72832a49630e78d2d8b184579f22178aca0e875f9fad701fb81afd2ac110ab2b417376","other":"3376cfc924fef1a45aae35d106439b131f363b3a42904b3974cc7cddde325441cce8551729dd62f1119120b0d452e78f063e8e711ecacdc27d9087aac5ab09b5","up":true},{"one":"3dcf18c35593b47bc463688493b792d6b9d13eabe05396e491953608f20cf55f770fc21be32b00335fcb2f0ba02735b92569b2b64a44c344ac348042876e8f15","other":"1cdef98d7b4de45c902c725384bd14c66084fe4159b26a0f9a24f432e1f561d035ca41e1c60fe64f3213b4f91a1afb953193dca1a7d535be0602b5d046bcbab8","up":true},{"other":"28cdd55fc871ffd8d63d05994be706959c9780dbfc859070a41047a1b40dd5fd7adb53919400a4c6f4d06c69bc1ecccc0e230e5b702598a7fe8003a282479872","up":true,"one":"15ceb62ee0f53379aa202950634ed881ba3b7bd4b46c80723ee48190079311e24ffaacb167a126a40bd6732c384f3c26163aa043edca03cb52a97b6da189aec7"},{"one":"2cb076669efbaf2ff0b181a1b454061a31ef23937a40405022b126f0eb4bfba60c9e3397009d8c0ff0cabb603692532d0072c18c6838f43397c98483306f62db","up":true,"other":"46717bc5fb7fcbcdc961e7ef091020f9f222858cf3d4afcc0b0bb1b782b7055d9eb833e0a04cb32d80406133ac77162521c43edf9f9690872222760e31462ccc"},{"one":"154d5ddb15ec12dc65362039d801383c189b5bcf6688883f2d7e3d0e8dc78e45f9f58d5dabc79a8798a243ce59abb95c77525db14f050fd8cb37d04b7276557c","other":"643da2591098f9698f27cccf7c17832e0717ee6a1276398a1a29edc947125585dcfab9417c2721a8a55d4dfc75b826be7581b6e30b020f6341ac549877c9f122","up":true},{"one":"5a6318af8b4615cf30610a05ade7704182fefd0a3fb3d76c47cb392e114d8d30004f0ec214326b11532fd1e928e66f632bbcde126a94c87774063853a9518dc5","other":"8fb6838337f832445531764ddafc3c747b2607f2f33e244685d6de621c2b53264270f5504187e43b7fa5cda53e66dd00b16c06879c82fb38a3d9e8aec4060210","up":true},{"other":"c0164fb4a1acfb4f3b1a09f9f3ab226c382529a73891937c6f3c91798098cf10b909eb92e5f8acfe0e8f3aee0b71cb23ee2d9e6ad1e0f4492a0272c52d529849","up":true,"one":"15ceb62ee0f53379aa202950634ed881ba3b7bd4b46c80723ee48190079311e24ffaacb167a126a40bd6732c384f3c26163aa043edca03cb52a97b6da189aec7"},{"one":"11e9729700f5046b47d5e4521630cb57408f59a3337ca7db7984477a16c1f3b90c1d8d1f8d6a3f2a72e35f373fa73ec47a5636b36e40b2fb83756622a08896b8","up":true,"other":"6b082a09e343a160b60a01f74641c1d707b2fa8fee5f6f5a8b9e4a203bd86434227d2df982b246a752f843483cdf517e85fe3bd65453354232a6eb38dedbf314"},{"up":true,"other":"17ae0b24297a3e6e027884e5e4529b6646ae340f5736eebc6187a9b59832a445f3644172d92438351e3803e56a67472b29f3e1d48844ae2e11e5e6670eed1436","one":"5717a49591a0ecdff3d4449874d5ff9ba016afad5da19712ca0c8ebca8cefd84e6d8c778245f67f68c8dd730ad294fd017b8de279fde4fc919768ce85dba132d"},{"other":"c674c405068bb908312917a319e24ddf90e814ee8ef54bbf740f176b2a7eda6950e3e1ed69484ebcc27b13d82c7f0b20daba71a17700018e769ca612ca8d2208","up":true,"one":"85c0b055439f114dee5eb0961013c117a48d62b0f17c61a7fd92a84092ef09bb3bbce686aa96e14528d5663565c57d657fa9813b1f38e268caeb1cb0842ef232"},{"one":"9ea856ea440c776b9ffaad1237ec11d570a1f912a908b8363ff97cf7947d2523e3c73663240d8fac988698cdd81e877ddd4a609485fe9f26494136fae14212df","other":"6a37e63feed9e68c52cb8b385d5e8d8dbd2b211c57ded0d3b01fe8b306af5c0e5a7405d0d9a942648f0131926240d53450bc43f922a053528e5830d918313c3d","up":true},{"one":"c0164fb4a1acfb4f3b1a09f9f3ab226c382529a73891937c6f3c91798098cf10b909eb92e5f8acfe0e8f3aee0b71cb23ee2d9e6ad1e0f4492a0272c52d529849","up":true,"other":"5a6318af8b4615cf30610a05ade7704182fefd0a3fb3d76c47cb392e114d8d30004f0ec214326b11532fd1e928e66f632bbcde126a94c87774063853a9518dc5"},{"one":"154d5ddb15ec12dc65362039d801383c189b5bcf6688883f2d7e3d0e8dc78e45f9f58d5dabc79a8798a243ce59abb95c77525db14f050fd8cb37d04b7276557c","up":true,"other":"9ea856ea440c776b9ffaad1237ec11d570a1f912a908b8363ff97cf7947d2523e3c73663240d8fac988698cdd81e877ddd4a609485fe9f26494136fae14212df"},{"up":true,"other":"b60def37233dbbc0d5f7fcddb304be1c0b6508e1e3d8a09a8290f7363e9bb84152dcaf70b8f6bb3a882fee77ff03ab796a5c1c3654f251c9f5c746ac5ad88556","one":"884d32d09dfef937f3ef1cd6fb5f530c2c574487c0ffd4185ca405c8b2ac73044a196c34352e850ce15321eec6579da654a696381f3e5830d03c7aa18923da6e"},{"one":"85c0b055439f114dee5eb0961013c117a48d62b0f17c61a7fd92a84092ef09bb3bbce686aa96e14528d5663565c57d657fa9813b1f38e268caeb1cb0842ef232","up":true,"other":"77811b007dd1fc1b11e447858df37062e97b6fc14e059399814f3b4736188e3fb28bf7c3958bb8ebc6ae16c36884ba7c98b810fb6f8b358323412123c803abd4"},{"one":"11e9729700f5046b47d5e4521630cb57408f59a3337ca7db7984477a16c1f3b90c1d8d1f8d6a3f2a72e35f373fa73ec47a5636b36e40b2fb83756622a08896b8","up":true,"other":"682288e4dae2374c4784acd0b285508920ce39a6b72cc0e30a3dbb7972e0394a2bddd5ee5f22a1dbf80f284dde4d9f8ede7847318d5353566b35a83e212477e7"},{"one":"a8fac88fba179fb9b259d94caac9cbe45d873a0131bef8844ac4383b177daf6f301f8793623fec5876885db1a91e5b3e98e2aafdaa47e03b1f6d9740f48af7ac","other":"06aab75fed9a03f5525e3f1d8f8997fefaefd5b16e8f485d571beda00b1741efbb61a8a74fa12c2f6de66227c3fabb4d411659cd9c7b1ef32e171e6bf517cc39","up":true},{"other":"bdd17545242bedba1e4c36fadea95db655f8f220f10ae143084690a3c8d4e7ffb79a64af9f1bc8514addbd63695b2f20857e8d162f25318faac885f77b385138","up":true,"one":"2cb076669efbaf2ff0b181a1b454061a31ef23937a40405022b126f0eb4bfba60c9e3397009d8c0ff0cabb603692532d0072c18c6838f43397c98483306f62db"},{"one":"6b7c94db790a2c1b903208904c4c75b66b17e7a00404727dbc7aeff404ac1118dc78ce4ca443f6b5245236f9e358c09b6da027ae1144e1a6682edca301176330","other":"69f999937943be00e5fca5c7cc942ce13b6752a72813368da2fbfcf74ad807bc6edd85537e087b6f73c0469c7b76a5d8f7d883bd315f3b35af32b8da293ed243","up":true},{"up":true,"other":"740919ebae9b4fe646ca716ebb8923bf2a1b1963767d86f55ea95911d88d163cc2e07b1420669e64b62cb267b625413444b783b8e4a7bd6a0f481f4d84e984b1","one":"e993be8034861aebc9bbd11115f25d9c719d43fcdefc323599616cc26240cee38dfc27bb7f339149a54a3c9ad13b2d6ca4f0ae690e4355605eda6b789c4a431e"},{"one":"6a55b94c9990249b24cdbeed96f065137f7b79ea8ee5f58da150d3962dfb62ba401960a53e7e8bd4e2c2908aa1a59b9d5efb4aafb316a9ab4fa67a0d95b58c54","up":true,"other":"228b3646b15527f4df07b847a62dbf9620cb068f829e9086b5f437d0b64d8a027cab44f19db5e44189b5099545ecb25d49384c261748f9533cfb0eb11a1eca5f"},{"up":true,"other":"9ea856ea440c776b9ffaad1237ec11d570a1f912a908b8363ff97cf7947d2523e3c73663240d8fac988698cdd81e877ddd4a609485fe9f26494136fae14212df","one":"28cdd55fc871ffd8d63d05994be706959c9780dbfc859070a41047a1b40dd5fd7adb53919400a4c6f4d06c69bc1ecccc0e230e5b702598a7fe8003a282479872"},{"one":"a8fac88fba179fb9b259d94caac9cbe45d873a0131bef8844ac4383b177daf6f301f8793623fec5876885db1a91e5b3e98e2aafdaa47e03b1f6d9740f48af7ac","up":true,"other":"884d32d09dfef937f3ef1cd6fb5f530c2c574487c0ffd4185ca405c8b2ac73044a196c34352e850ce15321eec6579da654a696381f3e5830d03c7aa18923da6e"},{"one":"f6a12b23423c047927a3024a6dba7ce88927cb21d4df3778bc5ebb262cc403261c79ba6d9bda07f1852c009d803a77f429e9e48ec1d63cae98256e529d45b276","up":true,"other":"876618c8ba66c1b91b473a154be3e10ded3590ba83d620d30e0ff1fbac2f31f258b1299a3da5b56aa03269a80c119b7fc41dfd87d5bd996359e4ad8dd0ab2a6a"},{"up":true,"other":"6a37e63feed9e68c52cb8b385d5e8d8dbd2b211c57ded0d3b01fe8b306af5c0e5a7405d0d9a942648f0131926240d53450bc43f922a053528e5830d918313c3d","one":"2cb076669efbaf2ff0b181a1b454061a31ef23937a40405022b126f0eb4bfba60c9e3397009d8c0ff0cabb603692532d0072c18c6838f43397c98483306f62db"},{"up":true,"other":"06aab75fed9a03f5525e3f1d8f8997fefaefd5b16e8f485d571beda00b1741efbb61a8a74fa12c2f6de66227c3fabb4d411659cd9c7b1ef32e171e6bf517cc39","one":"884d32d09dfef937f3ef1cd6fb5f530c2c574487c0ffd4185ca405c8b2ac73044a196c34352e850ce15321eec6579da654a696381f3e5830d03c7aa18923da6e"},{"up":true,"other":"2b0a1f3a6466c6be1d7e84120db384fa37f7c73a01e9a105ae90e7d2203212ec974f016d3012afd26bc0f9a8411d0716cc59b6ecc9f665db12e306af8b34cb63","one":"9309549fc50173d6826fe63cf18699f49199c3789616b843042fe1a6adab6ed4bdd7a7a06acd276e0398cf8bffb26c12a4227725d7bbd386a9a55fc601c21405"},{"other":"f5d95e0c5a873ff5a95e1eb34f1ed258d77adf98ee0886d93c4a24b1feaf6955e6e4c4ea0eccb2b9723870bae61e693643d6ad96dd8da01672542611f7c49069","up":true,"one":"15ceb62ee0f53379aa202950634ed881ba3b7bd4b46c80723ee48190079311e24ffaacb167a126a40bd6732c384f3c26163aa043edca03cb52a97b6da189aec7"},{"other":"a070b5cff5eff533a2267ceb0d88e221088038af773e18f80110c8a2c329f0543b8d43c4e6132e9416723e3e94c87f0053456760ced4426767b95cee36ed93f8","up":true,"one":"c2568576c2c9ef47aca0baca52709a4fa44b2ed478a062f7b161fac2bdba68568df371ac7754255fd07d79bb9918249a914946a6c318d579730bee9bc609922a"},{"one":"154d5ddb15ec12dc65362039d801383c189b5bcf6688883f2d7e3d0e8dc78e45f9f58d5dabc79a8798a243ce59abb95c77525db14f050fd8cb37d04b7276557c","other":"33cac8f621b9122e118036154778d27dc419b6b58ea2e89b833f3932f411dbc3511d92b55ae4cf80632142bc8e67994899aaa30c499d0289fae85b12564cf01f","up":true},{"one":"3dcf18c35593b47bc463688493b792d6b9d13eabe05396e491953608f20cf55f770fc21be32b00335fcb2f0ba02735b92569b2b64a44c344ac348042876e8f15","up":true,"other":"6c2788dec7ae7a77134065afc1174bb92b87833e87acaa72fe9e62c92d2017f217f9fbc5884cdfb7236a7bb75e463e49ecceb1641a8629516211d9699587046e"},{"one":"d6a7257771baa4d9944592ead46b8ab700dbf91ebd4dc0ec7e5fb41cbda0622944269172fcec8352b89ef2c186d4c787af2b45a50533f627a97818477de034b4","up":true,"other":"9c8fca41b833e88110559b9258653160f5fb236bd637272ac58fe1adf333f4df75b94a805eaebb9f10a8c1a26d357dd75140560551d3fc4da79da2c4fc9479c3"},{"one":"85c0b055439f114dee5eb0961013c117a48d62b0f17c61a7fd92a84092ef09bb3bbce686aa96e14528d5663565c57d657fa9813b1f38e268caeb1cb0842ef232","other":"c69b9b181b2756a1345b73a97afb3dca909c253188c3b905f0b414465b750d2ffccb4c8e8eb5e3809549af55db473f3b12682f9bd97c5c75d68f23d67d91b866","up":true},{"other":"f6a12b23423c047927a3024a6dba7ce88927cb21d4df3778bc5ebb262cc403261c79ba6d9bda07f1852c009d803a77f429e9e48ec1d63cae98256e529d45b276","up":true,"one":"7a8cb96685c1b8fbaeb18c8dc1f9f2631b23bc035e704e2f5df915b8bcabd6e2025ddc30324c69833f86e577b250c0721fee9d294f3e22016ae4c59c5f88845b"},{"up":true,"other":"d3cd2f34f67830ccdc295b7537a6d27c02b44503808ca666124f52ecc3d6c35b7d3f14343997006aef2cfbefc8d27809d389477e99c236b9f8a897a4bc406a43","one":"6c40910f0556f892a7542989fa01d7e3682fca89aeefb5ed885808f88ff17b6d13862f461c10d629a005ae67abef542d75e5b20816891b6944f71560f5c2dfa8"},{"one":"a070b5cff5eff533a2267ceb0d88e221088038af773e18f80110c8a2c329f0543b8d43c4e6132e9416723e3e94c87f0053456760ced4426767b95cee36ed93f8","up":true,"other":"33cac8f621b9122e118036154778d27dc419b6b58ea2e89b833f3932f411dbc3511d92b55ae4cf80632142bc8e67994899aaa30c499d0289fae85b12564cf01f"},{"one":"c088bf88f1e152ca3fad17f098a71ca1021d46d8af12d0ee1c587a5e2a430d8e48beaf171fe01ee7680b671c00dd88c90f12a35c328a3f334661fdeee914a4bc","up":true,"other":"884d32d09dfef937f3ef1cd6fb5f530c2c574487c0ffd4185ca405c8b2ac73044a196c34352e850ce15321eec6579da654a696381f3e5830d03c7aa18923da6e"},{"one":"6a55b94c9990249b24cdbeed96f065137f7b79ea8ee5f58da150d3962dfb62ba401960a53e7e8bd4e2c2908aa1a59b9d5efb4aafb316a9ab4fa67a0d95b58c54","up":true,"other":"77811b007dd1fc1b11e447858df37062e97b6fc14e059399814f3b4736188e3fb28bf7c3958bb8ebc6ae16c36884ba7c98b810fb6f8b358323412123c803abd4"},{"other":"51a570637394e9ab61fe95b3a608cc4e9dc8ceb63efe717938ccd4260a962d52e01b30e7034fbfdabd9a3c9616ee569550b38a6d6b4b19847f523254069a9f27","up":true,"one":"c69b9b181b2756a1345b73a97afb3dca909c253188c3b905f0b414465b750d2ffccb4c8e8eb5e3809549af55db473f3b12682f9bd97c5c75d68f23d67d91b866"},{"one":"d3cd2f34f67830ccdc295b7537a6d27c02b44503808ca666124f52ecc3d6c35b7d3f14343997006aef2cfbefc8d27809d389477e99c236b9f8a897a4bc406a43","up":true,"other":"49215dfa786bfaa52b1e7aa6899392711a770b2504c82f536381fb1f18df16960257d75530efabf6dbd2b1361decc29758f870b318f777decf51f4833a9c1f00"},{"other":"ab13f773f6f2ff73032aa5f79c8897b75dda29bcbb14aa511e9401c2417dc9c510253071e28c7833c8d62fd2aef16fcd0c14ce016fbf4fec1b9a2173c717603f","up":true,"one":"1b3107d9a96cfd11f4cd0ed8baeb7b23db1406c9c4a9dac76c772f49c0fc9404f6a4adae11120aa821757173f0cc1cb00e6ab555b5abffaae9001c0557cb75c9"},{"other":"855667650e96c5ed2d9b0c82532ed1fb92f72b1ae926afafe09cf8f6e90e539aec5c4c2ab108f2c2a1ad7dd8b83ca92a98c550a1c9ed27e6632a7d2f6da4f970","up":true,"one":"9309549fc50173d6826fe63cf18699f49199c3789616b843042fe1a6adab6ed4bdd7a7a06acd276e0398cf8bffb26c12a4227725d7bbd386a9a55fc601c21405"},{"one":"f6a12b23423c047927a3024a6dba7ce88927cb21d4df3778bc5ebb262cc403261c79ba6d9bda07f1852c009d803a77f429e9e48ec1d63cae98256e529d45b276","up":true,"other":"6b082a09e343a160b60a01f74641c1d707b2fa8fee5f6f5a8b9e4a203bd86434227d2df982b246a752f843483cdf517e85fe3bd65453354232a6eb38dedbf314"},{"one":"222d7a2f94dc82a09fda70b8195fc3a60433a90f53998872318c57625c528c90572d78b444ac4901dcfece1a03ef8b6cbe7845366a845a942f341f6db58a9b3b","other":"e7b2adabc2c99ac47b1e94fc0a2c63a00a1d622ea67a4c1858f4cec93fca957d43d8429605761bdf5eed4f733dac1a3d12fb928f22abf248965994acde63864a","up":true},{"one":"9309549fc50173d6826fe63cf18699f49199c3789616b843042fe1a6adab6ed4bdd7a7a06acd276e0398cf8bffb26c12a4227725d7bbd386a9a55fc601c21405","up":true,"other":"37399617d62153bc471f3bf21c92385bc8602c80ffa0c71da8aebae595a9859cfd56257aae60ad30ef3ec4d07dee90623cce63749c8c3233c0aa0d17f9e89afe"},{"one":"c69b9b181b2756a1345b73a97afb3dca909c253188c3b905f0b414465b750d2ffccb4c8e8eb5e3809549af55db473f3b12682f9bd97c5c75d68f23d67d91b866","other":"876618c8ba66c1b91b473a154be3e10ded3590ba83d620d30e0ff1fbac2f31f258b1299a3da5b56aa03269a80c119b7fc41dfd87d5bd996359e4ad8dd0ab2a6a","up":true},{"up":true,"other":"49215dfa786bfaa52b1e7aa6899392711a770b2504c82f536381fb1f18df16960257d75530efabf6dbd2b1361decc29758f870b318f777decf51f4833a9c1f00","one":"313a131ecb7d68e127d0fec8bb4a2e586886203c3d07857a93e7a39bb831703184d9ae28ba9ef3d986c2dae1a24f4f5bfa47cfc35f74f5512a126836364d7736"},{"up":true,"other":"3948a7a939b9a1f4201953bd9b955ee7be87d09b63c7a45167f556ac06fe3c4c2a75d935bff50668da5e71e46802b55d7a9945a92d7807c00625d129cbb48f82","one":"fd0123c7b96004067e98e463e273de5bc5402399ae70a95985b5f682e30d4f35d070deaf8c71d201e98c4324d832b95aab7535ad8a2658f66e3e0bb1202204e1"},{"one":"37399617d62153bc471f3bf21c92385bc8602c80ffa0c71da8aebae595a9859cfd56257aae60ad30ef3ec4d07dee90623cce63749c8c3233c0aa0d17f9e89afe","other":"9f3af4577308965aceb7e0101443669496e7ccf1de680629862a7005966c708b6fb52e6dfe62660246b9892adc25838da2873502e0be706bcad8f25b7ceedfa5","up":true},{"up":true,"other":"002cb6ffa63ad71ee6ebc1df4c41f7a97c51f274b1d3b22420c87b73136be5169b9670508061d8261e20055fefce3b855388994672aa9a0f1475c43839aae4fa","one":"f6a12b23423c047927a3024a6dba7ce88927cb21d4df3778bc5ebb262cc403261c79ba6d9bda07f1852c009d803a77f429e9e48ec1d63cae98256e529d45b276"},{"up":true,"other":"be93fafaf43f6bb3efd2667d1468a8636cb752b245328eaa01468c0606d790322a7cd8e47857068e60118e28b8dd8aa1d2d4977c5b3d28d4b47f4c0658f05e90","one":"2c976b6007cda135444233c7bd03d22ac9756710b746c36bc032e7fdd42f2ffb89ca5f5e754ff96b8f3cbc474e346287e5b8531d9f98fd63c426c632872220af"},{"one":"45d3827eb5c3b906fc61aaad79c5968f3dcf7b1ecc1e3be63e827ad6fb9291542686f42b3e142f43cc0437a2177b7362727842ea1d6c33bc795d936bba3ae457","other":"d6a7257771baa4d9944592ead46b8ab700dbf91ebd4dc0ec7e5fb41cbda0622944269172fcec8352b89ef2c186d4c787af2b45a50533f627a97818477de034b4","up":true},{"other":"b18c7131a319db61ab84d06e90092d93c91141e9a270630af9c3ab1eaf3bcad09f4d20a1fc845b21c994bf4d9e337d0bd756a75e2198097540355e7ebbb531b2","up":true,"one":"c6ad9b9de5cdbe28540f4eb7c66fb37f6d4295e6e60c6de54e2a45c1970b8e0047558e986bbd10e9e86c8bb0407846fac4823e4570e8a1486fc4bf55cb4a0986"},{"up":true,"other":"92dbb67da2b99a8fe46b1e510addc2b83e357ac0b5287b7ef5c1b1bc6e252b8dfd605a6896ede65848e429216d1f67d530d9e7b83ff14058aa2e5b6e405d6801","one":"9e21f5d4cfb389ac3ad43497689878bd245a89c587a8637d832b1e355ba244f4c83e6499bc7936e6d35645db25910ecd89b9af9b6b2f0c7cc4d7c6114328d7bf"},{"one":"10551c0c37abc25457903978868dd4843a52fda5f9b571b05ebd974d8c381fda4349f17c2b986a2e4b8d06b0517422f085d5f6d9cd814efa40e48393d9f71d7e","other":"ea2921612b827e3c26328368bed9be7cbf1f2b2aecaf31863c9cdccd74c56b651d6eaceb8ac9609a6653488837ded310df91e53a74789ae75cb841e2aeaf96df","up":true},{"one":"f8a5ae50e5b2d84096c10a6a8493a9eb8113df64c4f1336c0cf4649302649b158fa4cb7941591e55356891bcc1008a535df427546af19988a241c5f466467963","other":"9c8fca41b833e88110559b9258653160f5fb236bd637272ac58fe1adf333f4df75b94a805eaebb9f10a8c1a26d357dd75140560551d3fc4da79da2c4fc9479c3","up":true},{"one":"45d3827eb5c3b906fc61aaad79c5968f3dcf7b1ecc1e3be63e827ad6fb9291542686f42b3e142f43cc0437a2177b7362727842ea1d6c33bc795d936bba3ae457","other":"876618c8ba66c1b91b473a154be3e10ded3590ba83d620d30e0ff1fbac2f31f258b1299a3da5b56aa03269a80c119b7fc41dfd87d5bd996359e4ad8dd0ab2a6a","up":true},{"one":"af9b80f6836113aeda897d6903e9ffb4f7f1a706a7f821d0d40f03a0d83c18d6a19795ee4bfc1093ada04014415b1f230db1d2f056df3f5027cce71611588046","other":"43086ff7ffd3c7bdec77bd288f41f1ee0ce21bd3f60a5df8931e2af6e7af5ef0fad432d29625491935d11567944351fc7867c807ebd12dd2c21c9e620ae0f85c","up":true},{"one":"b1dd1b08975319030626aab821032a0c687a103ee8942e8a2e2cf029dd72832a49630e78d2d8b184579f22178aca0e875f9fad701fb81afd2ac110ab2b417376","other":"869ca41ea1f82bec5f43807a3aaaabc39b21c62d3c9c8bdc0709683e22dd37cb2f3c313766809076d2c02d0d6171f4f32a1b5080abcb8072d88981042ae6237d","up":true},{"other":"624248a794fd62248024360f128b2e503c752340694a316bed420e5ed2cebeb5bf970df95a2806732237a26de3778222b0454e2e7d2875129b193e7890fd5b95","up":true,"one":"bab07c2e4dc09add884869b31fb474b6d7151f9cc331d831f55c2b088397370fb0a1e1592c8dff9c8bc8e83de9faf6e91683acfb2df1b41856d70e523a99d370"},{"other":"8e65496318637446a51f0dc87d0a5cf82655866cd1579db1e381af52e12545172b9c88119999ccac3b8b8644efc9675ff183ebe7584c16eb40792cc21f7e9b76","up":true,"one":"52cf04f88d8b00214f11f329ebacca69291958372aa8ccfbe3cfdbc03d51d90389f3c307b82c108f0c074d78aeac0b48e8b8c8f3bf3b20b21d9747f284075de2"},{"one":"7dd2801259c071a6e1dcc01d1cb74775fdec92da1da0b1eaf5f893cd5ed118894493ca5284c12bbd6cf7959449bc610d26ac6c9ef2845d1645d425f56ac003fd","other":"f60755ee9464c7db769bb7237016fa165441d18ac3bfed7cd2a220a9bcbead202dd34eaf2f9398a3d36bdfc2671bbd46ac25ebe264a8118afe1b7d0bd38710f4","up":true},{"one":"588df3185f63a5443d8c6b972f67805f0557184d916005f537a4b27cd02bd6a12e432a2b34b234a34f22e923c6f116da85be20bad77a2bf69913684e9d0732ba","up":true,"other":"3376cfc924fef1a45aae35d106439b131f363b3a42904b3974cc7cddde325441cce8551729dd62f1119120b0d452e78f063e8e711ecacdc27d9087aac5ab09b5"},{"one":"8ee65c0937cdf860d5329132c34bf28b5dc4d2593986fae80e4b35efb54ec24cdbf294223515363a917a22dbc6db463c10c7484e22b479b9010059c2521b6317","up":true,"other":"76643f67075c6e45bd176db19473240cda6f886d1cac25330e2d99c84a429934f4c6a606c9c72574d5eaccd0a3f1770dab05e6ff6a5b5ce4d7258fed2bc13d48"},{"one":"3dcf18c35593b47bc463688493b792d6b9d13eabe05396e491953608f20cf55f770fc21be32b00335fcb2f0ba02735b92569b2b64a44c344ac348042876e8f15","up":true,"other":"f6a12b23423c047927a3024a6dba7ce88927cb21d4df3778bc5ebb262cc403261c79ba6d9bda07f1852c009d803a77f429e9e48ec1d63cae98256e529d45b276"},{"one":"b152eb30c9f46ec39166016f03d289f98cc285ac62d204da32e5a003da14e4f02c64df8ae1d0c8a2a902adc5f7dd7604081a0b140c9b64052082f0861945f5a4","other":"46717bc5fb7fcbcdc961e7ef091020f9f222858cf3d4afcc0b0bb1b782b7055d9eb833e0a04cb32d80406133ac77162521c43edf9f9690872222760e31462ccc","up":true},{"one":"46717bc5fb7fcbcdc961e7ef091020f9f222858cf3d4afcc0b0bb1b782b7055d9eb833e0a04cb32d80406133ac77162521c43edf9f9690872222760e31462ccc","up":true,"other":"69f999937943be00e5fca5c7cc942ce13b6752a72813368da2fbfcf74ad807bc6edd85537e087b6f73c0469c7b76a5d8f7d883bd315f3b35af32b8da293ed243"},{"other":"936fad959da2d8b0cfb2bcd78c5da65bcce5e9463be7fc7367f45cdfa20678f4c466fb1e3f600783a270855fd4b9cd6265054f79ecb116141e7c67a492041bed","up":true,"one":"7a8cb96685c1b8fbaeb18c8dc1f9f2631b23bc035e704e2f5df915b8bcabd6e2025ddc30324c69833f86e577b250c0721fee9d294f3e22016ae4c59c5f88845b"},{"one":"6b082a09e343a160b60a01f74641c1d707b2fa8fee5f6f5a8b9e4a203bd86434227d2df982b246a752f843483cdf517e85fe3bd65453354232a6eb38dedbf314","other":"ab8eda9b360d3e0b002ba31d48311057880844b828ad9817a2ad19736860d0114d4a17e9e9427c842d52e7ff61a09c2cad9b70f506e338909535542dae38ede0","up":true},{"other":"b60def37233dbbc0d5f7fcddb304be1c0b6508e1e3d8a09a8290f7363e9bb84152dcaf70b8f6bb3a882fee77ff03ab796a5c1c3654f251c9f5c746ac5ad88556","up":true,"one":"e0875ed6be1e163b15c13cdf37442f838670d0949349ee9ff119a0451beffb1a302943ee9d7cba48592922f64908aeb0f39f6e2e3725d1e7cdc5db34083b6977"},{"one":"6b7c94db790a2c1b903208904c4c75b66b17e7a00404727dbc7aeff404ac1118dc78ce4ca443f6b5245236f9e358c09b6da027ae1144e1a6682edca301176330","up":true,"other":"60995852a2385ce8d7d24dc94b85a2f0dab6e5c32e910dfe367ea9c6ccb7b0b2eb611fdf120f8c697097e2f137cefff42e8d9db16b664a857a38c5ace837ffa4"},{"one":"510536aba28aa635d8a1098a6dbd2070748ce1eb0e14b54b93a21196543a60df546ff6a2b3b5b9f32a5c2a37f5aba77d0b74f28b2dabeeebf3fe5afc20a3209c","up":true,"other":"c03ef1de42d522b44eef53be11f2c57b8b74fed9e87e6c2928c1feb48ddfecc67e1a3a8c8be1c47b3735a216d7054e2a4dda49fbd9a1ac702146aae5bdeced7c"},{"one":"6a37e63feed9e68c52cb8b385d5e8d8dbd2b211c57ded0d3b01fe8b306af5c0e5a7405d0d9a942648f0131926240d53450bc43f922a053528e5830d918313c3d","other":"aa2028d356a88eca8e0fcaf218d62ace099c3f72dfd95bb28f30ac9a926034cf1d60a40511f7495652745de80d71c0f6830019e206c88e2b6ef0cf4f05d7fe9e","up":true},{"other":"228b3646b15527f4df07b847a62dbf9620cb068f829e9086b5f437d0b64d8a027cab44f19db5e44189b5099545ecb25d49384c261748f9533cfb0eb11a1eca5f","up":true,"one":"c674c405068bb908312917a319e24ddf90e814ee8ef54bbf740f176b2a7eda6950e3e1ed69484ebcc27b13d82c7f0b20daba71a17700018e769ca612ca8d2208"},{"up":true,"other":"e0875ed6be1e163b15c13cdf37442f838670d0949349ee9ff119a0451beffb1a302943ee9d7cba48592922f64908aeb0f39f6e2e3725d1e7cdc5db34083b6977","one":"df9306a263f40e0e255996500523354de3cc78b68ae560f66d79f6ea28f30f773f1fd6ebc33928723dfde2ee3d4f982b203bee4c3803a5050df83477045bb279"},{"one":"6b082a09e343a160b60a01f74641c1d707b2fa8fee5f6f5a8b9e4a203bd86434227d2df982b246a752f843483cdf517e85fe3bd65453354232a6eb38dedbf314","other":"ee3471e1d835c4294f7ba642103039ccc548fe4edc177c79b63433ebbb0dc9d06600844f1fed76c7096ee9538e49e4e86fb8cffe9095dbdcde27695ff28ad395","up":true},{"one":"c674c405068bb908312917a319e24ddf90e814ee8ef54bbf740f176b2a7eda6950e3e1ed69484ebcc27b13d82c7f0b20daba71a17700018e769ca612ca8d2208","up":true,"other":"8e89fe4b3fffea8af247d2581aa511056efbeb796058d50a341d57aa0f7ccc2192d90cfb8d18558363df798567faaddb86815e8bd671b36ca37af0651535aabf"},{"one":"842f0ac24370f14edfe72a7d07219de60fc767d2d0356fa6ce9d535a43647ad4bb17d9be75ed83542868ba430ec104ba168f27c16915cdbd6e57ae62d60707cb","other":"3948a7a939b9a1f4201953bd9b955ee7be87d09b63c7a45167f556ac06fe3c4c2a75d935bff50668da5e71e46802b55d7a9945a92d7807c00625d129cbb48f82","up":true},{"one":"936fad959da2d8b0cfb2bcd78c5da65bcce5e9463be7fc7367f45cdfa20678f4c466fb1e3f600783a270855fd4b9cd6265054f79ecb116141e7c67a492041bed","other":"884d32d09dfef937f3ef1cd6fb5f530c2c574487c0ffd4185ca405c8b2ac73044a196c34352e850ce15321eec6579da654a696381f3e5830d03c7aa18923da6e","up":true},{"other":"f8a5ae50e5b2d84096c10a6a8493a9eb8113df64c4f1336c0cf4649302649b158fa4cb7941591e55356891bcc1008a535df427546af19988a241c5f466467963","up":true,"one":"45d3827eb5c3b906fc61aaad79c5968f3dcf7b1ecc1e3be63e827ad6fb9291542686f42b3e142f43cc0437a2177b7362727842ea1d6c33bc795d936bba3ae457"},{"other":"3639f964feba681db9702cac3f02058f2e490fd7bffb217dc3480dc458decafd5955541fea89f0f6f14ee50a745eaf98b21363d6b4fb88c31bd32bf7845d524b","up":true,"one":"1b3107d9a96cfd11f4cd0ed8baeb7b23db1406c9c4a9dac76c772f49c0fc9404f6a4adae11120aa821757173f0cc1cb00e6ab555b5abffaae9001c0557cb75c9"},{"up":true,"other":"f6a12b23423c047927a3024a6dba7ce88927cb21d4df3778bc5ebb262cc403261c79ba6d9bda07f1852c009d803a77f429e9e48ec1d63cae98256e529d45b276","one":"0e164c8692532e59c76ef84319a1093324f46f77618d3a836a279df52edca6c839061c0582dac7481da1bd0f3e2b58fc0dacd6ee5d678ba1406d4a1a25fe761d"},{"one":"ef7157fdfe62390d8a6d4ef976478d17465b42b63fddb03664973d63efb62318a8f59e412150528a32aa2c028b9de6bc67f05e012b8c43d710032ad871bc27e5","other":"2751df9f64a8f2ff8ea45efc9bd02b281d963ced285260bcda7f9dfaed998fe4386fe65a7265876da6b4fee77ea5c12454869a70ad627da7ca888076fc629665","up":true},{"one":"2880e0defd1bf2665bdd20dfb46bc0a9ad707f495211fc78e611ab479d78398db7daff7d3f4b6bf81fd13bf766ecc8271e0ea99a2d74abd2f9ddf98835ffdcf1","up":true,"other":"b18c7131a319db61ab84d06e90092d93c91141e9a270630af9c3ab1eaf3bcad09f4d20a1fc845b21c994bf4d9e337d0bd756a75e2198097540355e7ebbb531b2"},{"up":true,"other":"77811b007dd1fc1b11e447858df37062e97b6fc14e059399814f3b4736188e3fb28bf7c3958bb8ebc6ae16c36884ba7c98b810fb6f8b358323412123c803abd4","one":"1edeb91789b9aa996fea7a70964e0be33ee50acbe6d8f7d9d9fcf6dcf755dab6402637a610116f0eb716b19259429bdcced8bebc28ffa334387a430efc21b9b0"},{"one":"876618c8ba66c1b91b473a154be3e10ded3590ba83d620d30e0ff1fbac2f31f258b1299a3da5b56aa03269a80c119b7fc41dfd87d5bd996359e4ad8dd0ab2a6a","other":"ab8eda9b360d3e0b002ba31d48311057880844b828ad9817a2ad19736860d0114d4a17e9e9427c842d52e7ff61a09c2cad9b70f506e338909535542dae38ede0","up":true},{"up":true,"other":"85c0b055439f114dee5eb0961013c117a48d62b0f17c61a7fd92a84092ef09bb3bbce686aa96e14528d5663565c57d657fa9813b1f38e268caeb1cb0842ef232","one":"228b3646b15527f4df07b847a62dbf9620cb068f829e9086b5f437d0b64d8a027cab44f19db5e44189b5099545ecb25d49384c261748f9533cfb0eb11a1eca5f"},{"one":"df9306a263f40e0e255996500523354de3cc78b68ae560f66d79f6ea28f30f773f1fd6ebc33928723dfde2ee3d4f982b203bee4c3803a5050df83477045bb279","other":"7a8cb96685c1b8fbaeb18c8dc1f9f2631b23bc035e704e2f5df915b8bcabd6e2025ddc30324c69833f86e577b250c0721fee9d294f3e22016ae4c59c5f88845b","up":true},{"one":"9309549fc50173d6826fe63cf18699f49199c3789616b843042fe1a6adab6ed4bdd7a7a06acd276e0398cf8bffb26c12a4227725d7bbd386a9a55fc601c21405","other":"202ae63076a5560418023f00c9965b2a1d12de932b5371ae270d63db88551a7aa1a3c48841f81948fad3435bb4a7e3e165a2eced9fd937444e4502471e23dae8","up":true},{"one":"dd6acfd151220f21b03701ca554a5e134dbd1154dda21d9eec45809e7858fe83eca3953fc688f499030198f22052c3681a9f49207ef9b11a760456ab9637352b","other":"06aab75fed9a03f5525e3f1d8f8997fefaefd5b16e8f485d571beda00b1741efbb61a8a74fa12c2f6de66227c3fabb4d411659cd9c7b1ef32e171e6bf517cc39","up":true},{"one":"bc0df855bdadcde3e447415444f655eb430925a8fa81cdcac75909e7d79750f01827938570e75e388cc7058ba8ebca47afadf8b07172bc078488fb618ba71024","other":"9bdacc256acef0433805477d38f32be849a8846d88cb883b19d290454639b42c6ab6c5c52d4f83453e8a156af7d85f606458aa9c0977c67282f56f34ff0acbfb","up":true},{"one":"740919ebae9b4fe646ca716ebb8923bf2a1b1963767d86f55ea95911d88d163cc2e07b1420669e64b62cb267b625413444b783b8e4a7bd6a0f481f4d84e984b1","up":true,"other":"d7e3661c0af6754c875217f93d34b254f1f45fc1359a4c6146cd0efa4c6e12aed9a4fb0a21a136f73af4fc2c6d0a63cb809d81855bbc9f51e29d23d90f77b326"},{"up":true,"other":"b60def37233dbbc0d5f7fcddb304be1c0b6508e1e3d8a09a8290f7363e9bb84152dcaf70b8f6bb3a882fee77ff03ab796a5c1c3654f251c9f5c746ac5ad88556","one":"4b332b389f1142c0da42aaeb2e2692081d0002de0eb6741b3269e898a8101571d4556b755f2e8841e7a607bb41e398d2b0577fbe71098e7097f0fe6c720e1526"},{"other":"6c2788dec7ae7a77134065afc1174bb92b87833e87acaa72fe9e62c92d2017f217f9fbc5884cdfb7236a7bb75e463e49ecceb1641a8629516211d9699587046e","up":true,"one":"f056acbdf491d1bb091937335c10096ea44b7034e994d134bc16d55212ff049bb097424de96c615ea699359a7ef77b3b54def2b3a5f43d735ffda65f73d61f7f"},{"up":true,"other":"ee0b09ee6a1057c47102e582e2fdec7b9212802e59f062a9360da0db535d4987126ab24848c0d76fa8485431a5140307e2b0c0d9f37cbdb35756e6cc1bdb3bc0","one":"1489ad735e1256900e4733707f8b78f1d853742a8f9b2d0c1c89651c60e7ee9d266afba5b4c1ed3f9cee05a1d2b2bba35dadb5b08973a93fd70dfb9e367339bd"},{"one":"876618c8ba66c1b91b473a154be3e10ded3590ba83d620d30e0ff1fbac2f31f258b1299a3da5b56aa03269a80c119b7fc41dfd87d5bd996359e4ad8dd0ab2a6a","up":true,"other":"f8a5ae50e5b2d84096c10a6a8493a9eb8113df64c4f1336c0cf4649302649b158fa4cb7941591e55356891bcc1008a535df427546af19988a241c5f466467963"},{"one":"dd3dccc1758765569905b3b137ef4c7dd31c2dc0dea827bcc4c4e976be94ffbb0f2ef6fe725cf9042063a96d663efea546837f35ca1fc67a854fbc9e27abb754","up":true,"other":"e323da6ae861cb092543992b8985639f9b3bcaf1c3c68757f4603a67800be62950fe7d8f8ef80eb83a18107b677c7f5047ea89a5790e0ea2a7969f4856d28488"},{"other":"dd3dccc1758765569905b3b137ef4c7dd31c2dc0dea827bcc4c4e976be94ffbb0f2ef6fe725cf9042063a96d663efea546837f35ca1fc67a854fbc9e27abb754","up":true,"one":"d43bd6d3ae39a04e4e144a8a6f80b2d54472b5b9b6491dccf44b1716a63d24c56e3a871b3b8fe983d992988dc07ace06736ead3b1287914b629fcfe17e81f36f"},{"other":"02fdbcb00f20a3f6e894900d798fcb0aca9e21f5b107924c0999eb396220f16dee99fc80ccba796e66e69dcb9ce278b7e0e4539c7a7cd0fbc1037bf8e56c1e67","up":true,"one":"b18c7131a319db61ab84d06e90092d93c91141e9a270630af9c3ab1eaf3bcad09f4d20a1fc845b21c994bf4d9e337d0bd756a75e2198097540355e7ebbb531b2"},{"up":true,"other":"228b3646b15527f4df07b847a62dbf9620cb068f829e9086b5f437d0b64d8a027cab44f19db5e44189b5099545ecb25d49384c261748f9533cfb0eb11a1eca5f","one":"1edeb91789b9aa996fea7a70964e0be33ee50acbe6d8f7d9d9fcf6dcf755dab6402637a610116f0eb716b19259429bdcced8bebc28ffa334387a430efc21b9b0"},{"one":"4b332b389f1142c0da42aaeb2e2692081d0002de0eb6741b3269e898a8101571d4556b755f2e8841e7a607bb41e398d2b0577fbe71098e7097f0fe6c720e1526","other":"ab13f773f6f2ff73032aa5f79c8897b75dda29bcbb14aa511e9401c2417dc9c510253071e28c7833c8d62fd2aef16fcd0c14ce016fbf4fec1b9a2173c717603f","up":true},{"one":"df9306a263f40e0e255996500523354de3cc78b68ae560f66d79f6ea28f30f773f1fd6ebc33928723dfde2ee3d4f982b203bee4c3803a5050df83477045bb279","other":"0e164c8692532e59c76ef84319a1093324f46f77618d3a836a279df52edca6c839061c0582dac7481da1bd0f3e2b58fc0dacd6ee5d678ba1406d4a1a25fe761d","up":true},{"other":"37399617d62153bc471f3bf21c92385bc8602c80ffa0c71da8aebae595a9859cfd56257aae60ad30ef3ec4d07dee90623cce63749c8c3233c0aa0d17f9e89afe","up":true,"one":"1489ad735e1256900e4733707f8b78f1d853742a8f9b2d0c1c89651c60e7ee9d266afba5b4c1ed3f9cee05a1d2b2bba35dadb5b08973a93fd70dfb9e367339bd"},{"up":true,"other":"7db14fde1da8794ae7ab5de37c9e2537e1024bc830c176c0d01635cafed47773d3a28e156db81ecdb95903222b900c3ebd4c4b3db2971dc0ef6a1e386027ffaa","one":"29acdd4c1233441bd40f98e245ecc9de94de6f9d0ab7c1a9923d833a2c8e6c1bd26d792686fec762b31fe28bbdd7aa04c9a594d997d08c133bb24cb2d877595a"},{"up":true,"other":"c0f233e79d0a8d4af01f54c40640975bc113f464271ba8922fca0c28acc60367af0db06629e701977e86cb5917c891e39c21418cab459fe49132b680aa31600b","one":"ee0b09ee6a1057c47102e582e2fdec7b9212802e59f062a9360da0db535d4987126ab24848c0d76fa8485431a5140307e2b0c0d9f37cbdb35756e6cc1bdb3bc0"},{"up":true,"other":"49256eccce3e036928a4b6b346126c6777dca5ea0134de85efca340f97ad0f827f3094f1562e3e186d35b8292a50c20ffae01409890bbb78598494285e14dc2c","one":"e1f23e1caba66f5ff821edbc4a3d527539937f73d86dd0df43aa1266a99f51f2480a77961eff177fbbf852fc52cb9317179f80b1580194daaedadc3b00510751"},{"other":"6b082a09e343a160b60a01f74641c1d707b2fa8fee5f6f5a8b9e4a203bd86434227d2df982b246a752f843483cdf517e85fe3bd65453354232a6eb38dedbf314","up":true,"one":"eb6d41d8d96f1933dff017d5fa0c46c6d0bad5d273b7c321a12858ac90ec00fca6191d29419897d2e25ec2d8ebd8c6a81bbde2d3f266f842e64b2b822161f1ea"},{"one":"c6ad9b9de5cdbe28540f4eb7c66fb37f6d4295e6e60c6de54e2a45c1970b8e0047558e986bbd10e9e86c8bb0407846fac4823e4570e8a1486fc4bf55cb4a0986","up":true,"other":"df9306a263f40e0e255996500523354de3cc78b68ae560f66d79f6ea28f30f773f1fd6ebc33928723dfde2ee3d4f982b203bee4c3803a5050df83477045bb279"},{"up":true,"other":"7958d1517de1223e7fb30acf61d8618e49fb95a03bc2f49141f4c7967bc80b90e0dd526c205639de3c060029963d43813293c2556f7b127945c798f3f9f18626","one":"9e21f5d4cfb389ac3ad43497689878bd245a89c587a8637d832b1e355ba244f4c83e6499bc7936e6d35645db25910ecd89b9af9b6b2f0c7cc4d7c6114328d7bf"},{"other":"85b6404a76b4762156c8ddd2f312763dfe19b315d914533844cf229301880c57ffeadc0eb5f4a8d542e1d9fc961dfb5a572d2101172b1a0fc238ced05ba49ec1","up":true,"one":"50c79baa3e6781482ccb5e960c699dd9c13f479467c6315c5292a396337cf3619e7faba1971a1f470051cb9042f80ea6750defe3936b72aac4d9bac6f8368c67"},{"other":"50c79baa3e6781482ccb5e960c699dd9c13f479467c6315c5292a396337cf3619e7faba1971a1f470051cb9042f80ea6750defe3936b72aac4d9bac6f8368c67","up":true,"one":"ee0b09ee6a1057c47102e582e2fdec7b9212802e59f062a9360da0db535d4987126ab24848c0d76fa8485431a5140307e2b0c0d9f37cbdb35756e6cc1bdb3bc0"},{"up":true,"other":"b8e0a56df21baae43058f575b714ae9a33c097d18f1a628b3b6ae5e86dd46a06e44c0dc272baacb5be0f7bf57fd6ddce107544eb3b94dca1aeae9f5773496a72","one":"1489ad735e1256900e4733707f8b78f1d853742a8f9b2d0c1c89651c60e7ee9d266afba5b4c1ed3f9cee05a1d2b2bba35dadb5b08973a93fd70dfb9e367339bd"},{"up":true,"other":"bdd17545242bedba1e4c36fadea95db655f8f220f10ae143084690a3c8d4e7ffb79a64af9f1bc8514addbd63695b2f20857e8d162f25318faac885f77b385138","one":"f5d95e0c5a873ff5a95e1eb34f1ed258d77adf98ee0886d93c4a24b1feaf6955e6e4c4ea0eccb2b9723870bae61e693643d6ad96dd8da01672542611f7c49069"},{"one":"dd3dccc1758765569905b3b137ef4c7dd31c2dc0dea827bcc4c4e976be94ffbb0f2ef6fe725cf9042063a96d663efea546837f35ca1fc67a854fbc9e27abb754","other":"bc0df855bdadcde3e447415444f655eb430925a8fa81cdcac75909e7d79750f01827938570e75e388cc7058ba8ebca47afadf8b07172bc078488fb618ba71024","up":true},{"other":"77e40e42f570a217f707888c714deb31fd70c856ae4b9a44ec7cee02768185dc4d7ed210429607f06690b32edd9fb06b304aff330a3949cc2fd49db1bc392edb","up":true,"one":"ab1a3542d67ef9d1a63653990bf0782f53b0169fe5092adc92fa7aeb38f66c6b62d49e3455cc2ac4994bfcfb03111953acf4cc3099026672cc61f6e24cb3ae00"},{"up":true,"other":"869ca41ea1f82bec5f43807a3aaaabc39b21c62d3c9c8bdc0709683e22dd37cb2f3c313766809076d2c02d0d6171f4f32a1b5080abcb8072d88981042ae6237d","one":"3376cfc924fef1a45aae35d106439b131f363b3a42904b3974cc7cddde325441cce8551729dd62f1119120b0d452e78f063e8e711ecacdc27d9087aac5ab09b5"},{"one":"5319bc9864d87eb33f26ff9732824d21a0a5ab70b254bc70a47554ffc763ae1559000d07e3eac9f883bd9e7f249d80edf14ab39c89c375bfcc5ec9e840ec9673","up":true,"other":"f056acbdf491d1bb091937335c10096ea44b7034e994d134bc16d55212ff049bb097424de96c615ea699359a7ef77b3b54def2b3a5f43d735ffda65f73d61f7f"},{"up":true,"other":"865dbf61d8511603fe0d9ebfb10792b9f6b798187c0909039bd9b2492c41e428876f386beeac86d0dea871f4fc24ba435f0fbd9a11e74c044024934592af14ee","one":"b4f300abda4cf6e383f997510eb681e9fa62e23577e3c19bd7447fa1f5702a4e034cea5944248e7c6e6e92b5ae69195c3e8a2c5ca7827b4f4a00cc8546e6695a"},{"up":true,"other":"c206d8689068488179e86ce549de75989e0b17cbe09880d18fcf0fa212e629345f1b899203607a2b083569cb3f8398e501843166f5db23ac7fa7dacfe26dd3f4","one":"29acdd4c1233441bd40f98e245ecc9de94de6f9d0ab7c1a9923d833a2c8e6c1bd26d792686fec762b31fe28bbdd7aa04c9a594d997d08c133bb24cb2d877595a"},{"up":true,"other":"f056acbdf491d1bb091937335c10096ea44b7034e994d134bc16d55212ff049bb097424de96c615ea699359a7ef77b3b54def2b3a5f43d735ffda65f73d61f7f","one":"3b71a324bd7b1a8fb19d8206eea1ca8190cb1faf5fcd1bfc52cef6b52296fe1db3e54d70180133fad1fa1188499d0dd73d2d075fdc6b3ffd9042d690e7d88e02"},{"up":true,"other":"643da2591098f9698f27cccf7c17832e0717ee6a1276398a1a29edc947125585dcfab9417c2721a8a55d4dfc75b826be7581b6e30b020f6341ac549877c9f122","one":"7dd2801259c071a6e1dcc01d1cb74775fdec92da1da0b1eaf5f893cd5ed118894493ca5284c12bbd6cf7959449bc610d26ac6c9ef2845d1645d425f56ac003fd"},{"one":"29acdd4c1233441bd40f98e245ecc9de94de6f9d0ab7c1a9923d833a2c8e6c1bd26d792686fec762b31fe28bbdd7aa04c9a594d997d08c133bb24cb2d877595a","up":true,"other":"51df4f4d4f020f22f55a5fd00c7f9c68c232c167ae4d4e80d7695f8f39c5aa0a7b565c1c55bdd6a21e06fa056549d08fd2e9d76fd79e21295557aa30d1ae022c"},{"one":"5319bc9864d87eb33f26ff9732824d21a0a5ab70b254bc70a47554ffc763ae1559000d07e3eac9f883bd9e7f249d80edf14ab39c89c375bfcc5ec9e840ec9673","up":true,"other":"69f999937943be00e5fca5c7cc942ce13b6752a72813368da2fbfcf74ad807bc6edd85537e087b6f73c0469c7b76a5d8f7d883bd315f3b35af32b8da293ed243"},{"up":true,"other":"a48cd04cdc66e1bb182529a789e1417d60d5e7d0f73068c1b17c6f231defeb943357789123e8d89cad90d1dd1726c48b808300d213bc1ddf7ae43cd58527f1f3","one":"c0164fb4a1acfb4f3b1a09f9f3ab226c382529a73891937c6f3c91798098cf10b909eb92e5f8acfe0e8f3aee0b71cb23ee2d9e6ad1e0f4492a0272c52d529849"},{"up":true,"other":"69f999937943be00e5fca5c7cc942ce13b6752a72813368da2fbfcf74ad807bc6edd85537e087b6f73c0469c7b76a5d8f7d883bd315f3b35af32b8da293ed243","one":"b152eb30c9f46ec39166016f03d289f98cc285ac62d204da32e5a003da14e4f02c64df8ae1d0c8a2a902adc5f7dd7604081a0b140c9b64052082f0861945f5a4"},{"up":true,"other":"002cb6ffa63ad71ee6ebc1df4c41f7a97c51f274b1d3b22420c87b73136be5169b9670508061d8261e20055fefce3b855388994672aa9a0f1475c43839aae4fa","one":"ab8eda9b360d3e0b002ba31d48311057880844b828ad9817a2ad19736860d0114d4a17e9e9427c842d52e7ff61a09c2cad9b70f506e338909535542dae38ede0"},{"one":"15ceb62ee0f53379aa202950634ed881ba3b7bd4b46c80723ee48190079311e24ffaacb167a126a40bd6732c384f3c26163aa043edca03cb52a97b6da189aec7","up":true,"other":"8e65496318637446a51f0dc87d0a5cf82655866cd1579db1e381af52e12545172b9c88119999ccac3b8b8644efc9675ff183ebe7584c16eb40792cc21f7e9b76"},{"one":"3b71a324bd7b1a8fb19d8206eea1ca8190cb1faf5fcd1bfc52cef6b52296fe1db3e54d70180133fad1fa1188499d0dd73d2d075fdc6b3ffd9042d690e7d88e02","up":true,"other":"f5d95e0c5a873ff5a95e1eb34f1ed258d77adf98ee0886d93c4a24b1feaf6955e6e4c4ea0eccb2b9723870bae61e693643d6ad96dd8da01672542611f7c49069"},{"one":"740919ebae9b4fe646ca716ebb8923bf2a1b1963767d86f55ea95911d88d163cc2e07b1420669e64b62cb267b625413444b783b8e4a7bd6a0f481f4d84e984b1","up":true,"other":"eb58e478b16056e0af344397cf5f078a3312a6db2189ec2042ec06ab6550e3ee71ebcfeff1814332c552c12a5a488f96b3f2935e90a189d238da19d30a2c9874"},{"one":"5319bc9864d87eb33f26ff9732824d21a0a5ab70b254bc70a47554ffc763ae1559000d07e3eac9f883bd9e7f249d80edf14ab39c89c375bfcc5ec9e840ec9673","up":true,"other":"dbb6621460b054f584f1c6157b4020f3c58d84c3a12b57436e10525ae60ab27036bf3edd68b92f2b13674877d01c2871dc67a9031c3d0470985f4b071696346e"},{"one":"a070b5cff5eff533a2267ceb0d88e221088038af773e18f80110c8a2c329f0543b8d43c4e6132e9416723e3e94c87f0053456760ced4426767b95cee36ed93f8","other":"fc9b1b2bbd5e682eb350d23f3ee33b245495daedae9370de7b1f55f91cd45db831d196c17615e11decf6b67696a268ac788130e3de38c7f6aeae811f3ec8c8ee","up":true},{"one":"6a37e63feed9e68c52cb8b385d5e8d8dbd2b211c57ded0d3b01fe8b306af5c0e5a7405d0d9a942648f0131926240d53450bc43f922a053528e5830d918313c3d","other":"c2568576c2c9ef47aca0baca52709a4fa44b2ed478a062f7b161fac2bdba68568df371ac7754255fd07d79bb9918249a914946a6c318d579730bee9bc609922a","up":true},{"one":"002cb6ffa63ad71ee6ebc1df4c41f7a97c51f274b1d3b22420c87b73136be5169b9670508061d8261e20055fefce3b855388994672aa9a0f1475c43839aae4fa","up":true,"other":"f8a5ae50e5b2d84096c10a6a8493a9eb8113df64c4f1336c0cf4649302649b158fa4cb7941591e55356891bcc1008a535df427546af19988a241c5f466467963"},{"one":"f5d95e0c5a873ff5a95e1eb34f1ed258d77adf98ee0886d93c4a24b1feaf6955e6e4c4ea0eccb2b9723870bae61e693643d6ad96dd8da01672542611f7c49069","up":true,"other":"6c2788dec7ae7a77134065afc1174bb92b87833e87acaa72fe9e62c92d2017f217f9fbc5884cdfb7236a7bb75e463e49ecceb1641a8629516211d9699587046e"},{"up":true,"other":"c69b9b181b2756a1345b73a97afb3dca909c253188c3b905f0b414465b750d2ffccb4c8e8eb5e3809549af55db473f3b12682f9bd97c5c75d68f23d67d91b866","one":"e0f13606a7f35b9ad8a9c4e70336c4c554ac718720a451a349eb4e1a4b055079483cac040ec64e0ed3d8bdb336618a5ae6ef74e31642fae4d7ed9949858eb361"},{"one":"488854534ec5a3479d8ee13d9b7daf07479f6b5505f319eced44dad8c316f6ff241ce2101e95608ba635067f5e5741481b78f419c4bbd465bf7e837dc4e54d64","other":"69f999937943be00e5fca5c7cc942ce13b6752a72813368da2fbfcf74ad807bc6edd85537e087b6f73c0469c7b76a5d8f7d883bd315f3b35af32b8da293ed243","up":true},{"one":"6b082a09e343a160b60a01f74641c1d707b2fa8fee5f6f5a8b9e4a203bd86434227d2df982b246a752f843483cdf517e85fe3bd65453354232a6eb38dedbf314","other":"4116fbb7d55bfd4bd8db9cbfa570ac361bb88605b6aacbf84e245893cf3fa599ecc086688a4c534c81f61a90fa344ca37e4d4013ddc03f7f08218724a55f66b1","up":true},{"one":"97b1eaf8274ece76d75e7f60126f1b351ed5fe55088b9fcbb825a3a8d8f84f61bc72469916b280497dabf01345057525cae89da73c9a1a8a8cd19367d44dede1","up":true,"other":"eb58e478b16056e0af344397cf5f078a3312a6db2189ec2042ec06ab6550e3ee71ebcfeff1814332c552c12a5a488f96b3f2935e90a189d238da19d30a2c9874"},{"other":"9bdacc256acef0433805477d38f32be849a8846d88cb883b19d290454639b42c6ab6c5c52d4f83453e8a156af7d85f606458aa9c0977c67282f56f34ff0acbfb","up":true,"one":"6b7c94db790a2c1b903208904c4c75b66b17e7a00404727dbc7aeff404ac1118dc78ce4ca443f6b5245236f9e358c09b6da027ae1144e1a6682edca301176330"},{"one":"c69b9b181b2756a1345b73a97afb3dca909c253188c3b905f0b414465b750d2ffccb4c8e8eb5e3809549af55db473f3b12682f9bd97c5c75d68f23d67d91b866","up":true,"other":"e323da6ae861cb092543992b8985639f9b3bcaf1c3c68757f4603a67800be62950fe7d8f8ef80eb83a18107b677c7f5047ea89a5790e0ea2a7969f4856d28488"},{"up":true,"other":"a1fe0d27f82309911a4b758c4e597bde16adc1e2fdfb07b52dea5092cea40ff212ea2cc831e385094b044f519909cf978f350b16ffd4c70c159cf1372301a3cf","one":"f6a12b23423c047927a3024a6dba7ce88927cb21d4df3778bc5ebb262cc403261c79ba6d9bda07f1852c009d803a77f429e9e48ec1d63cae98256e529d45b276"},{"one":"eb6d41d8d96f1933dff017d5fa0c46c6d0bad5d273b7c321a12858ac90ec00fca6191d29419897d2e25ec2d8ebd8c6a81bbde2d3f266f842e64b2b822161f1ea","other":"682288e4dae2374c4784acd0b285508920ce39a6b72cc0e30a3dbb7972e0394a2bddd5ee5f22a1dbf80f284dde4d9f8ede7847318d5353566b35a83e212477e7","up":true},{"one":"c0a2c08fa8b70ecbf1932254945d5f689b0da7a287019d384152f383f6229acd4d82eef26205bc12e062dae4569814bd1c996ee4fe5886bd6bdd93c4f0ac113a","up":true,"other":"5d002c37b74a6656db86f102b0cec82bc35a819a480e5a2952db0140ebab65dffeb1a79f04d53ff61447b5fad7c58cb75ea1c91ea47fcb9e024f27b92c6c874d"},{"one":"4eab70233789c544bec97040a04099494bf269a819584a5d0b42295c918a52b02f224a8ed127aba3d92c02f567356bea4b95f77230ef548dfa7fe44b643d8704","up":true,"other":"a25958cf192a4f62301feda5d442535f78b983dd9e4599354f4898c8c1e6ad97ca7112549e1d1a1eacb4682cd1bf8b762368b5905ab33dbdacb585b128514ca1"},{"other":"865dbf61d8511603fe0d9ebfb10792b9f6b798187c0909039bd9b2492c41e428876f386beeac86d0dea871f4fc24ba435f0fbd9a11e74c044024934592af14ee","up":true,"one":"2abb91884cc3a8fb91b2f2f369f9430f2b3b05c75ce6203aa7a50312c9f141f9d0f615063d3576a5ce8a4be9ecb942aa804a717f76d9e8dca03d115dcc43f775"},{"other":"dd3dccc1758765569905b3b137ef4c7dd31c2dc0dea827bcc4c4e976be94ffbb0f2ef6fe725cf9042063a96d663efea546837f35ca1fc67a854fbc9e27abb754","up":true,"one":"243164c4dd583f80c50813f43e5c27c894463400cd3afd776b36e79e7123d9261f01f06f92914aab83096b9a43fb655e79687590599284640a3a7d2c25454597"},{"one":"842f0ac24370f14edfe72a7d07219de60fc767d2d0356fa6ce9d535a43647ad4bb17d9be75ed83542868ba430ec104ba168f27c16915cdbd6e57ae62d60707cb","other":"5114329db828f9568ccb0d7643a10e273aa626177910f55e22a53abf1ce8ec75b95465c983446b20eac0ff9c59c5dc53eca95b24aabcc8dd110e397cd2934047","up":true},{"one":"4eab70233789c544bec97040a04099494bf269a819584a5d0b42295c918a52b02f224a8ed127aba3d92c02f567356bea4b95f77230ef548dfa7fe44b643d8704","other":"222d7a2f94dc82a09fda70b8195fc3a60433a90f53998872318c57625c528c90572d78b444ac4901dcfece1a03ef8b6cbe7845366a845a942f341f6db58a9b3b","up":true},{"other":"740919ebae9b4fe646ca716ebb8923bf2a1b1963767d86f55ea95911d88d163cc2e07b1420669e64b62cb267b625413444b783b8e4a7bd6a0f481f4d84e984b1","up":true,"one":"97b1eaf8274ece76d75e7f60126f1b351ed5fe55088b9fcbb825a3a8d8f84f61bc72469916b280497dabf01345057525cae89da73c9a1a8a8cd19367d44dede1"},{"other":"1cdef98d7b4de45c902c725384bd14c66084fe4159b26a0f9a24f432e1f561d035ca41e1c60fe64f3213b4f91a1afb953193dca1a7d535be0602b5d046bcbab8","up":true,"one":"002cb6ffa63ad71ee6ebc1df4c41f7a97c51f274b1d3b22420c87b73136be5169b9670508061d8261e20055fefce3b855388994672aa9a0f1475c43839aae4fa"},{"one":"ecd217e8bdb53c9ef085929b8c2d2b40425a4be617a087b8e7f88e8507b3c981e90fda2119744ca394fe65bd4eb1cdd3fa7258db936048e236d2f15ee91bc3b6","other":"ec19efa1d488e74da6bf239825b24678f549c377326c5d33d100b708a9a28a3fe129d542d7ba71e0ade46c15c6e9b38f09422560444388e609a8a66ceb8e0ae8","up":true},{"one":"2abb91884cc3a8fb91b2f2f369f9430f2b3b05c75ce6203aa7a50312c9f141f9d0f615063d3576a5ce8a4be9ecb942aa804a717f76d9e8dca03d115dcc43f775","up":true,"other":"c206d8689068488179e86ce549de75989e0b17cbe09880d18fcf0fa212e629345f1b899203607a2b083569cb3f8398e501843166f5db23ac7fa7dacfe26dd3f4"},{"other":"50c79baa3e6781482ccb5e960c699dd9c13f479467c6315c5292a396337cf3619e7faba1971a1f470051cb9042f80ea6750defe3936b72aac4d9bac6f8368c67","up":true,"one":"865dbf61d8511603fe0d9ebfb10792b9f6b798187c0909039bd9b2492c41e428876f386beeac86d0dea871f4fc24ba435f0fbd9a11e74c044024934592af14ee"},{"one":"1edeb91789b9aa996fea7a70964e0be33ee50acbe6d8f7d9d9fcf6dcf755dab6402637a610116f0eb716b19259429bdcced8bebc28ffa334387a430efc21b9b0","up":true,"other":"7d9979c13cd8841e84e5d199fc263962ca6fee12664d8526a581bfcdca2e3427ca169b9a0244dd8292a9a1be2bcedb0e8f626eadd307068c11c03b6df13aee33"},{"one":"b8e0a56df21baae43058f575b714ae9a33c097d18f1a628b3b6ae5e86dd46a06e44c0dc272baacb5be0f7bf57fd6ddce107544eb3b94dca1aeae9f5773496a72","up":true,"other":"3e2241cdb9f34c1d2c6930e59940e2c4b92b0287579d7263a620a609c5e66dca6d85df48cf1bffd63663a6704c42d0866aae3e484fd9a44b6a012f72dd3cef6e"},{"one":"02fdbcb00f20a3f6e894900d798fcb0aca9e21f5b107924c0999eb396220f16dee99fc80ccba796e66e69dcb9ce278b7e0e4539c7a7cd0fbc1037bf8e56c1e67","up":true,"other":"2880e0defd1bf2665bdd20dfb46bc0a9ad707f495211fc78e611ab479d78398db7daff7d3f4b6bf81fd13bf766ecc8271e0ea99a2d74abd2f9ddf98835ffdcf1"},{"one":"dd6acfd151220f21b03701ca554a5e134dbd1154dda21d9eec45809e7858fe83eca3953fc688f499030198f22052c3681a9f49207ef9b11a760456ab9637352b","up":true,"other":"e33a1476fcb8d2a1b9ee15871a960ce7a3337c93f5956a2825b1f8b2885dbdc0ed652b1eba549523866632b5b6898310bc638d946a9fcce27d65117eb44c25f3"},{"one":"7db14fde1da8794ae7ab5de37c9e2537e1024bc830c176c0d01635cafed47773d3a28e156db81ecdb95903222b900c3ebd4c4b3db2971dc0ef6a1e386027ffaa","up":true,"other":"77e40e42f570a217f707888c714deb31fd70c856ae4b9a44ec7cee02768185dc4d7ed210429607f06690b32edd9fb06b304aff330a3949cc2fd49db1bc392edb"},{"one":"29acdd4c1233441bd40f98e245ecc9de94de6f9d0ab7c1a9923d833a2c8e6c1bd26d792686fec762b31fe28bbdd7aa04c9a594d997d08c133bb24cb2d877595a","other":"81dc656de121016bcde81d5bf7919839acfc180dfbf1a6de2cadf704ff13af98aa5715a4168832ca6f651b2ea7ad9e6ca5f1c1cb7e885dbc2eb23d4aefb87bd6","up":true},{"up":true,"other":"95ff4dea07303e1ba641a5c510e714ef232f4dbce9ad2e8b2f62644975eae41fc4bb9d1af3fae4d5ea4daeb18f8248e0b3131c7d843d35d33f3afbf7dfa4c2fe","one":"b58b3e200f6072ddb38130944a01d2829c755b8bd1a08abd010d1bbf86dabd851b2c1ab4cb961451bd7e8499f6c7378830bcd27cde825846654853c172597bf3"},{"up":true,"other":"51df4f4d4f020f22f55a5fd00c7f9c68c232c167ae4d4e80d7695f8f39c5aa0a7b565c1c55bdd6a21e06fa056549d08fd2e9d76fd79e21295557aa30d1ae022c","one":"2880e0defd1bf2665bdd20dfb46bc0a9ad707f495211fc78e611ab479d78398db7daff7d3f4b6bf81fd13bf766ecc8271e0ea99a2d74abd2f9ddf98835ffdcf1"},{"other":"9e21f5d4cfb389ac3ad43497689878bd245a89c587a8637d832b1e355ba244f4c83e6499bc7936e6d35645db25910ecd89b9af9b6b2f0c7cc4d7c6114328d7bf","up":true,"one":"ab1a3542d67ef9d1a63653990bf0782f53b0169fe5092adc92fa7aeb38f66c6b62d49e3455cc2ac4994bfcfb03111953acf4cc3099026672cc61f6e24cb3ae00"},{"one":"81dc656de121016bcde81d5bf7919839acfc180dfbf1a6de2cadf704ff13af98aa5715a4168832ca6f651b2ea7ad9e6ca5f1c1cb7e885dbc2eb23d4aefb87bd6","other":"51df4f4d4f020f22f55a5fd00c7f9c68c232c167ae4d4e80d7695f8f39c5aa0a7b565c1c55bdd6a21e06fa056549d08fd2e9d76fd79e21295557aa30d1ae022c","up":true},{"up":true,"other":"b9c7b885430b9b1a4425bde30b3629559f5437e0e30a0299fc6f6e097cbcca8af9e285caf5dea685a0237f60e06f490c39a1e3e487f14a2b9f41a5135f2ba994","one":"b183f12f3602bfdab0480cb0b0ba7dc69b267b0dbc7e54c316741cb78b9e99aa69fd321ad7755d095e9be14e6bd90fe14ef8fe9bafc1a0dea10a144795021a08"},{"other":"77e40e42f570a217f707888c714deb31fd70c856ae4b9a44ec7cee02768185dc4d7ed210429607f06690b32edd9fb06b304aff330a3949cc2fd49db1bc392edb","up":true,"one":"b4557089e4247379e587a087f53b36dd1f86f85d9dcfab5dc562079978cd959adaef5b30d11258d9cb552e7c5abddf5377a71d449febe8f2acb0aec3ebd8ba73"},{"one":"202ae63076a5560418023f00c9965b2a1d12de932b5371ae270d63db88551a7aa1a3c48841f81948fad3435bb4a7e3e165a2eced9fd937444e4502471e23dae8","up":true,"other":"49256eccce3e036928a4b6b346126c6777dca5ea0134de85efca340f97ad0f827f3094f1562e3e186d35b8292a50c20ffae01409890bbb78598494285e14dc2c"},{"one":"6909a0fa47718cfc463b1e96c21734b46bd5b28dd59cd3d66d67990783436b7538ab2659d427029b97c8dddf313b26532518c0c34a2b1fca8cd852b0fdb83ab8","other":"202ae63076a5560418023f00c9965b2a1d12de932b5371ae270d63db88551a7aa1a3c48841f81948fad3435bb4a7e3e165a2eced9fd937444e4502471e23dae8","up":true},{"one":"e5cb29b25debcfaaacc0b04e708c8c1cb9d2dee29e82596a1c72a934032cf738800b9525cc277d0c5f5dacf2f278329b54da161b4bafa285243fa0e9fd7b2f3a","up":true,"other":"dd3dccc1758765569905b3b137ef4c7dd31c2dc0dea827bcc4c4e976be94ffbb0f2ef6fe725cf9042063a96d663efea546837f35ca1fc67a854fbc9e27abb754"},{"up":true,"other":"3e2241cdb9f34c1d2c6930e59940e2c4b92b0287579d7263a620a609c5e66dca6d85df48cf1bffd63663a6704c42d0866aae3e484fd9a44b6a012f72dd3cef6e","one":"ee0b09ee6a1057c47102e582e2fdec7b9212802e59f062a9360da0db535d4987126ab24848c0d76fa8485431a5140307e2b0c0d9f37cbdb35756e6cc1bdb3bc0"},{"up":true,"other":"77811b007dd1fc1b11e447858df37062e97b6fc14e059399814f3b4736188e3fb28bf7c3958bb8ebc6ae16c36884ba7c98b810fb6f8b358323412123c803abd4","one":"5114329db828f9568ccb0d7643a10e273aa626177910f55e22a53abf1ce8ec75b95465c983446b20eac0ff9c59c5dc53eca95b24aabcc8dd110e397cd2934047"},{"up":true,"other":"3948a7a939b9a1f4201953bd9b955ee7be87d09b63c7a45167f556ac06fe3c4c2a75d935bff50668da5e71e46802b55d7a9945a92d7807c00625d129cbb48f82","one":"50c79baa3e6781482ccb5e960c699dd9c13f479467c6315c5292a396337cf3619e7faba1971a1f470051cb9042f80ea6750defe3936b72aac4d9bac6f8368c67"},{"up":true,"other":"c0f233e79d0a8d4af01f54c40640975bc113f464271ba8922fca0c28acc60367af0db06629e701977e86cb5917c891e39c21418cab459fe49132b680aa31600b","one":"2bea7540c99456ea889a8ba2e448c11e6257bf987d01f13eea48128ba58577ab0936855035ee140c9907e382a34ca85a179c74892cbd9eb92fc2b35601addc6b"},{"one":"588df3185f63a5443d8c6b972f67805f0557184d916005f537a4b27cd02bd6a12e432a2b34b234a34f22e923c6f116da85be20bad77a2bf69913684e9d0732ba","up":true,"other":"b1dd1b08975319030626aab821032a0c687a103ee8942e8a2e2cf029dd72832a49630e78d2d8b184579f22178aca0e875f9fad701fb81afd2ac110ab2b417376"},{"one":"3948a7a939b9a1f4201953bd9b955ee7be87d09b63c7a45167f556ac06fe3c4c2a75d935bff50668da5e71e46802b55d7a9945a92d7807c00625d129cbb48f82","other":"77811b007dd1fc1b11e447858df37062e97b6fc14e059399814f3b4736188e3fb28bf7c3958bb8ebc6ae16c36884ba7c98b810fb6f8b358323412123c803abd4","up":true},{"one":"7dd2801259c071a6e1dcc01d1cb74775fdec92da1da0b1eaf5f893cd5ed118894493ca5284c12bbd6cf7959449bc610d26ac6c9ef2845d1645d425f56ac003fd","up":true,"other":"b9c7b885430b9b1a4425bde30b3629559f5437e0e30a0299fc6f6e097cbcca8af9e285caf5dea685a0237f60e06f490c39a1e3e487f14a2b9f41a5135f2ba994"},{"other":"dd6acfd151220f21b03701ca554a5e134dbd1154dda21d9eec45809e7858fe83eca3953fc688f499030198f22052c3681a9f49207ef9b11a760456ab9637352b","up":true,"one":"5114329db828f9568ccb0d7643a10e273aa626177910f55e22a53abf1ce8ec75b95465c983446b20eac0ff9c59c5dc53eca95b24aabcc8dd110e397cd2934047"},{"up":true,"other":"bab07c2e4dc09add884869b31fb474b6d7151f9cc331d831f55c2b088397370fb0a1e1592c8dff9c8bc8e83de9faf6e91683acfb2df1b41856d70e523a99d370","one":"90b8e73916046b5433dce049bfe125ca2bf2fb390ff7301f9bc5d8d0183988577aa2a7392aaa28091aa81c8ac23942b5751420b9ee48e488a68411f9d2b1e5d5"},{"one":"97b1eaf8274ece76d75e7f60126f1b351ed5fe55088b9fcbb825a3a8d8f84f61bc72469916b280497dabf01345057525cae89da73c9a1a8a8cd19367d44dede1","other":"33e9d4674b5b9b23e838583f01b429abca1330393dfc100b19ede6090a53df213011fae53169a66aa05d18e4cb497a17aa81eaedf1fe2e4348f9825c309438b5","up":true},{"other":"b3b4b203395bb6655d79ecdcee11638dd9a16baccfcc1f6fcc8b31832c8ca35650eb6c2802104eeec6d96ea80404381a2bd9b01dcadc748a4666b761d9ce64f8","up":true,"one":"740919ebae9b4fe646ca716ebb8923bf2a1b1963767d86f55ea95911d88d163cc2e07b1420669e64b62cb267b625413444b783b8e4a7bd6a0f481f4d84e984b1"},{"other":"5a6318af8b4615cf30610a05ade7704182fefd0a3fb3d76c47cb392e114d8d30004f0ec214326b11532fd1e928e66f632bbcde126a94c87774063853a9518dc5","up":true,"one":"f5d95e0c5a873ff5a95e1eb34f1ed258d77adf98ee0886d93c4a24b1feaf6955e6e4c4ea0eccb2b9723870bae61e693643d6ad96dd8da01672542611f7c49069"},{"other":"57085f756f76644cdd2148524f2334d869ef0ab2fcbe7fb11f5d22bc1f5023165b11526ecc85ff9cbb88877386af9b148d7ef15a825b3a586d16c01bdfc86692","up":true,"one":"2bea7540c99456ea889a8ba2e448c11e6257bf987d01f13eea48128ba58577ab0936855035ee140c9907e382a34ca85a179c74892cbd9eb92fc2b35601addc6b"},{"up":true,"other":"60995852a2385ce8d7d24dc94b85a2f0dab6e5c32e910dfe367ea9c6ccb7b0b2eb611fdf120f8c697097e2f137cefff42e8d9db16b664a857a38c5ace837ffa4","one":"45d3827eb5c3b906fc61aaad79c5968f3dcf7b1ecc1e3be63e827ad6fb9291542686f42b3e142f43cc0437a2177b7362727842ea1d6c33bc795d936bba3ae457"},{"one":"8fb6838337f832445531764ddafc3c747b2607f2f33e244685d6de621c2b53264270f5504187e43b7fa5cda53e66dd00b16c06879c82fb38a3d9e8aec4060210","other":"70cce7cb0c18091dbb6d41160ab560935f1759b969bf8118cee030ee707cb15ba407b8c48dcd9fd012cbf778e219f7d16a74064b4983cf098fb118297748edb6","up":true},{"one":"f52297fc51b920d2495ccece290432656d9388e698339c8c1279ceea45de698a4ecbda1d25928c48f1e19e9dacd3147e23ef01acc093872d7300aed187841dcc","up":true,"other":"d7af0a0217ff98804aa05f8f926a8b6262363b5391d24cda8048cca5ca5982b407b7b098302d0db6d8dd9ac0883b2025b3de651617ed1a173181148295c6d336"},{"one":"2bea7540c99456ea889a8ba2e448c11e6257bf987d01f13eea48128ba58577ab0936855035ee140c9907e382a34ca85a179c74892cbd9eb92fc2b35601addc6b","other":"545237d8463b75fd2e9bbfbffb35c5b78b4abbc85f6bfbd56976789012dd9a62ca1f866bf37bb33618e026aab764adb9ced5e00cd415562f69992f74c795083f","up":true},{"up":true,"other":"202ae63076a5560418023f00c9965b2a1d12de932b5371ae270d63db88551a7aa1a3c48841f81948fad3435bb4a7e3e165a2eced9fd937444e4502471e23dae8","one":"212a8048ab9925171475e81dce047865df186222d673d524c810a9f613e4a21f3b130fa34c5f44974fbeaab1f6028177e71568e00a1184d9fd05443c172f5fcf"},{"up":true,"other":"d6747e1f8594f7449fc6d7c0e63ee843480567d498db096ff04229420861c83bca5215fc19d8fede0c54484f111f1f2581e189e638c21c5d9e1fd3174bbb3e98","one":"c6ad9b9de5cdbe28540f4eb7c66fb37f6d4295e6e60c6de54e2a45c1970b8e0047558e986bbd10e9e86c8bb0407846fac4823e4570e8a1486fc4bf55cb4a0986"},{"one":"699c923976c5b8c70c353840d3e384750f466954265f05fbb0d5877a2c0318a041dc57adc12ac6e8fbae7a00d6b6675e1a1be3a8f59dac12727ee3f8ae467a13","up":true,"other":"58f9139905ae1d005950f110b7ead3355672ecc478e8c66393566c64b935003f6fec3031dc9eb21cda660acb1955cf7bb33a20fdd74d493f29868ace328fcd75"},{"one":"9e21f5d4cfb389ac3ad43497689878bd245a89c587a8637d832b1e355ba244f4c83e6499bc7936e6d35645db25910ecd89b9af9b6b2f0c7cc4d7c6114328d7bf","up":true,"other":"7cc9389c8f751465e0b94baed896f6f122631052300b1b5b23d3c7656e4d11014a7a9ae62a1287bb040ca37221871a566cd470e523846df7e3acb5f94c7cde06"},{"one":"f52281c227aa82a3bd5fabfdcf8bdf1d9ea6739ab9b9075340143d59b4f2f8a79a981609c9f42823a0253c19a7281eed0e912e4054363ab7fe50117563ef14e0","other":"95ff4dea07303e1ba641a5c510e714ef232f4dbce9ad2e8b2f62644975eae41fc4bb9d1af3fae4d5ea4daeb18f8248e0b3131c7d843d35d33f3afbf7dfa4c2fe","up":true},{"one":"92dbb67da2b99a8fe46b1e510addc2b83e357ac0b5287b7ef5c1b1bc6e252b8dfd605a6896ede65848e429216d1f67d530d9e7b83ff14058aa2e5b6e405d6801","other":"c6f38fe8a0f2b3773bae332e0ca7516e944bde186fe99daae10a2b0aecde3ce23c1834eaad97a4e6d2da8cd53a08dbafa72d2b827c851b115b74e8010125dba2","up":true},{"up":true,"other":"431644cf162bc267237c4e798288888dd835c1b0546b0cc679782e33568988d75b4294f4aa08359a6b152ed9a0fbd13133681156bcf09a871c4f362615ea6dae","one":"212a8048ab9925171475e81dce047865df186222d673d524c810a9f613e4a21f3b130fa34c5f44974fbeaab1f6028177e71568e00a1184d9fd05443c172f5fcf"},{"up":true,"other":"212a8048ab9925171475e81dce047865df186222d673d524c810a9f613e4a21f3b130fa34c5f44974fbeaab1f6028177e71568e00a1184d9fd05443c172f5fcf","one":"699c923976c5b8c70c353840d3e384750f466954265f05fbb0d5877a2c0318a041dc57adc12ac6e8fbae7a00d6b6675e1a1be3a8f59dac12727ee3f8ae467a13"},{"one":"212a8048ab9925171475e81dce047865df186222d673d524c810a9f613e4a21f3b130fa34c5f44974fbeaab1f6028177e71568e00a1184d9fd05443c172f5fcf","other":"20f6a8be1d2d8b5d6a43d851a2f5475385ef07fab80ac46525d0beccf3e25c01d726cfb3a1179e8343b1e88d21684fb24dd6e6497537d4e7e9edd59cb95d1b8d","up":true},{"up":true,"other":"58f9139905ae1d005950f110b7ead3355672ecc478e8c66393566c64b935003f6fec3031dc9eb21cda660acb1955cf7bb33a20fdd74d493f29868ace328fcd75","one":"b9c7b885430b9b1a4425bde30b3629559f5437e0e30a0299fc6f6e097cbcca8af9e285caf5dea685a0237f60e06f490c39a1e3e487f14a2b9f41a5135f2ba994"},{"one":"bab07c2e4dc09add884869b31fb474b6d7151f9cc331d831f55c2b088397370fb0a1e1592c8dff9c8bc8e83de9faf6e91683acfb2df1b41856d70e523a99d370","other":"313a131ecb7d68e127d0fec8bb4a2e586886203c3d07857a93e7a39bb831703184d9ae28ba9ef3d986c2dae1a24f4f5bfa47cfc35f74f5512a126836364d7736","up":true},{"one":"58f9139905ae1d005950f110b7ead3355672ecc478e8c66393566c64b935003f6fec3031dc9eb21cda660acb1955cf7bb33a20fdd74d493f29868ace328fcd75","up":true,"other":"ecb93d8eba17afe92979e8154252a08dd58de6ff3188b6829e3e25967846686f54199ab2b081e77b0048dcab204f05aa2c5cbd0efae4bc43a612d471d4e1197b"},{"one":"6909a0fa47718cfc463b1e96c21734b46bd5b28dd59cd3d66d67990783436b7538ab2659d427029b97c8dddf313b26532518c0c34a2b1fca8cd852b0fdb83ab8","up":true,"other":"c0164fb4a1acfb4f3b1a09f9f3ab226c382529a73891937c6f3c91798098cf10b909eb92e5f8acfe0e8f3aee0b71cb23ee2d9e6ad1e0f4492a0272c52d529849"},{"one":"6b104eff1dcf58d11a7f707bbd41a910b2735b262c29e0f4e4127fda1b67def4e89b6ebc1b3cc1e06c3968d0898e1085badc7da24d3cd6624cb100e85863cc97","other":"5d002c37b74a6656db86f102b0cec82bc35a819a480e5a2952db0140ebab65dffeb1a79f04d53ff61447b5fad7c58cb75ea1c91ea47fcb9e024f27b92c6c874d","up":true},{"up":true,"other":"df9306a263f40e0e255996500523354de3cc78b68ae560f66d79f6ea28f30f773f1fd6ebc33928723dfde2ee3d4f982b203bee4c3803a5050df83477045bb279","one":"60995852a2385ce8d7d24dc94b85a2f0dab6e5c32e910dfe367ea9c6ccb7b0b2eb611fdf120f8c697097e2f137cefff42e8d9db16b664a857a38c5ace837ffa4"},{"up":true,"other":"2cb076669efbaf2ff0b181a1b454061a31ef23937a40405022b126f0eb4bfba60c9e3397009d8c0ff0cabb603692532d0072c18c6838f43397c98483306f62db","one":"6b104eff1dcf58d11a7f707bbd41a910b2735b262c29e0f4e4127fda1b67def4e89b6ebc1b3cc1e06c3968d0898e1085badc7da24d3cd6624cb100e85863cc97"},{"up":true,"other":"d43bd6d3ae39a04e4e144a8a6f80b2d54472b5b9b6491dccf44b1716a63d24c56e3a871b3b8fe983d992988dc07ace06736ead3b1287914b629fcfe17e81f36f","one":"f52281c227aa82a3bd5fabfdcf8bdf1d9ea6739ab9b9075340143d59b4f2f8a79a981609c9f42823a0253c19a7281eed0e912e4054363ab7fe50117563ef14e0"},{"one":"243164c4dd583f80c50813f43e5c27c894463400cd3afd776b36e79e7123d9261f01f06f92914aab83096b9a43fb655e79687590599284640a3a7d2c25454597","up":true,"other":"51df4f4d4f020f22f55a5fd00c7f9c68c232c167ae4d4e80d7695f8f39c5aa0a7b565c1c55bdd6a21e06fa056549d08fd2e9d76fd79e21295557aa30d1ae022c"},{"up":true,"other":"c69b9b181b2756a1345b73a97afb3dca909c253188c3b905f0b414465b750d2ffccb4c8e8eb5e3809549af55db473f3b12682f9bd97c5c75d68f23d67d91b866","one":"9bdacc256acef0433805477d38f32be849a8846d88cb883b19d290454639b42c6ab6c5c52d4f83453e8a156af7d85f606458aa9c0977c67282f56f34ff0acbfb"},{"one":"ba430731fc2082f4217ebd859c2865c28bf50a39674ca8615dd89f608ae434a09657e24644ac32807634aad7857547118c9228460195e50ec58b34789d4ad151","up":true,"other":"624248a794fd62248024360f128b2e503c752340694a316bed420e5ed2cebeb5bf970df95a2806732237a26de3778222b0454e2e7d2875129b193e7890fd5b95"},{"other":"0e164c8692532e59c76ef84319a1093324f46f77618d3a836a279df52edca6c839061c0582dac7481da1bd0f3e2b58fc0dacd6ee5d678ba1406d4a1a25fe761d","up":true,"one":"7b4585f8a4e4904239994a1b8bdc76299da8e46a8a632fabc6c33dd4170f8f3715e4c4f526ea5dd14093b150855960e432b1b140594aca21995f9e0722fb57f1"},{"up":true,"other":"e993be8034861aebc9bbd11115f25d9c719d43fcdefc323599616cc26240cee38dfc27bb7f339149a54a3c9ad13b2d6ca4f0ae690e4355605eda6b789c4a431e","one":"8c459100df488b992fdad207a096a434d67cb733619adfd09a311095568d4c9db293d9a892675551805559456d49a3fdb19c2cc698b14552bf0ace584d4d90dc"},{"other":"ab13f773f6f2ff73032aa5f79c8897b75dda29bcbb14aa511e9401c2417dc9c510253071e28c7833c8d62fd2aef16fcd0c14ce016fbf4fec1b9a2173c717603f","up":true,"one":"855667650e96c5ed2d9b0c82532ed1fb92f72b1ae926afafe09cf8f6e90e539aec5c4c2ab108f2c2a1ad7dd8b83ca92a98c550a1c9ed27e6632a7d2f6da4f970"},{"one":"9bea5f82c2a390587de44d620d6637834e6f2329cd83d8df6305b03b75d9b543160b6c6f9f8887e6bc88f1d0726435d6c8ad813aadad0653b0790b8f6388413a","other":"77e40e42f570a217f707888c714deb31fd70c856ae4b9a44ec7cee02768185dc4d7ed210429607f06690b32edd9fb06b304aff330a3949cc2fd49db1bc392edb","up":true},{"other":"f4cdaeb513aa98f8868d8eb3a1d12c07367725928a1bc7d6ca4b583788e111a955463037ec7867260511896d97dfbf096aa77ee8a7d9ea1c06cad4a92c45108d","up":true,"one":"76643f67075c6e45bd176db19473240cda6f886d1cac25330e2d99c84a429934f4c6a606c9c72574d5eaccd0a3f1770dab05e6ff6a5b5ce4d7258fed2bc13d48"},{"up":true,"other":"49215dfa786bfaa52b1e7aa6899392711a770b2504c82f536381fb1f18df16960257d75530efabf6dbd2b1361decc29758f870b318f777decf51f4833a9c1f00","one":"8e8614a4c2ee2b1a3fa5ace0ca353cff36b3de3308ccf53665b8b56f8e2456a8a65f3846d786dccd68b1bfcefdd170ea5f8edb481800b1ce72d9fce2added7f0"},{"one":"c6f38fe8a0f2b3773bae332e0ca7516e944bde186fe99daae10a2b0aecde3ce23c1834eaad97a4e6d2da8cd53a08dbafa72d2b827c851b115b74e8010125dba2","up":true,"other":"77e7d427b65b6c29c0d92c51184af73031bfa768a47fc20be6c264f422bf718865259c17c103bf47289b3abe62f93452781c6303d757e76d3d56ceeb26262fab"},{"one":"8e8614a4c2ee2b1a3fa5ace0ca353cff36b3de3308ccf53665b8b56f8e2456a8a65f3846d786dccd68b1bfcefdd170ea5f8edb481800b1ce72d9fce2added7f0","up":true,"other":"ab1a3542d67ef9d1a63653990bf0782f53b0169fe5092adc92fa7aeb38f66c6b62d49e3455cc2ac4994bfcfb03111953acf4cc3099026672cc61f6e24cb3ae00"},{"up":true,"other":"624248a794fd62248024360f128b2e503c752340694a316bed420e5ed2cebeb5bf970df95a2806732237a26de3778222b0454e2e7d2875129b193e7890fd5b95","one":"362ed9a92b588d5fe315b90a74aa27f7600e4a7d06b27ceb26272340388d916a831df85bf83450ef80bda4e4a21acaac60560c8a42940a26e2ac567519e2a202"},{"other":"3639f964feba681db9702cac3f02058f2e490fd7bffb217dc3480dc458decafd5955541fea89f0f6f14ee50a745eaf98b21363d6b4fb88c31bd32bf7845d524b","up":true,"one":"1489ad735e1256900e4733707f8b78f1d853742a8f9b2d0c1c89651c60e7ee9d266afba5b4c1ed3f9cee05a1d2b2bba35dadb5b08973a93fd70dfb9e367339bd"},{"one":"92dbb67da2b99a8fe46b1e510addc2b83e357ac0b5287b7ef5c1b1bc6e252b8dfd605a6896ede65848e429216d1f67d530d9e7b83ff14058aa2e5b6e405d6801","other":"99a7649bdf2ee7f0bc049308b0997e33abb68481c05a573df9aea30da5a1f267df07b2c584e3e985baf31704f04ad2a2c4876e0f8555333be6d09f5080b583f1","up":true},{"up":true,"other":"bc0df855bdadcde3e447415444f655eb430925a8fa81cdcac75909e7d79750f01827938570e75e388cc7058ba8ebca47afadf8b07172bc078488fb618ba71024","one":"29acdd4c1233441bd40f98e245ecc9de94de6f9d0ab7c1a9923d833a2c8e6c1bd26d792686fec762b31fe28bbdd7aa04c9a594d997d08c133bb24cb2d877595a"},{"one":"842ec3faa8b4a4cdec32abfa00ae827277fe2696e1b0c6551154533b16cf75ae69caf834b4f08488fa5c8b322fb633b1fd8a5b7d436e9c589cc9074dc031ae68","other":"7cc9389c8f751465e0b94baed896f6f122631052300b1b5b23d3c7656e4d11014a7a9ae62a1287bb040ca37221871a566cd470e523846df7e3acb5f94c7cde06","up":true},{"one":"43086ff7ffd3c7bdec77bd288f41f1ee0ce21bd3f60a5df8931e2af6e7af5ef0fad432d29625491935d11567944351fc7867c807ebd12dd2c21c9e620ae0f85c","up":true,"other":"b58b3e200f6072ddb38130944a01d2829c755b8bd1a08abd010d1bbf86dabd851b2c1ab4cb961451bd7e8499f6c7378830bcd27cde825846654853c172597bf3"},{"one":"e903d7aebff96a6afa4b9dd19b0b02e5af18da8e4e89f64247e1a2c2d46637538c741182eac67f45ec61be76aeaccde57f0a0184bd608ea7d92e586d4f827ea7","other":"842ec3faa8b4a4cdec32abfa00ae827277fe2696e1b0c6551154533b16cf75ae69caf834b4f08488fa5c8b322fb633b1fd8a5b7d436e9c589cc9074dc031ae68","up":true},{"up":true,"other":"c2a9c77247871cfa4d3c2d1b47619df91ed5b331a44c8e21f7c9ce431a4db9dfb87713558cc8a37911393907b4cc60be9445bad18adcea1bc5f318256e71be14","one":"3a2cacc430f13f31c52b7205455420cf0fb9ed9e28b0898b69ef97951bf295b29118e573a42dd97abe38fee5ab4c03dad9ff6dc448126cefc1da12b6c8e8d915"},{"one":"fee3fa1ba2a051d40a582908384ee81179db6c2b5f4bfa58c24f8015b794b43a093ed68b69bb209684135f972a055a9845978fa1b7d489e2126c3b514297f1c2","up":true,"other":"202ae63076a5560418023f00c9965b2a1d12de932b5371ae270d63db88551a7aa1a3c48841f81948fad3435bb4a7e3e165a2eced9fd937444e4502471e23dae8"},{"one":"b183f12f3602bfdab0480cb0b0ba7dc69b267b0dbc7e54c316741cb78b9e99aa69fd321ad7755d095e9be14e6bd90fe14ef8fe9bafc1a0dea10a144795021a08","up":true,"other":"ee0b09ee6a1057c47102e582e2fdec7b9212802e59f062a9360da0db535d4987126ab24848c0d76fa8485431a5140307e2b0c0d9f37cbdb35756e6cc1bdb3bc0"},{"one":"a47697063a2fb973449bdabd0925e10944ba1f6d8b2cc5c38b295f611eea3402b5cf3ae857716a34d84194955f5ed61350affe56223349124c8233852141f9a2","other":"c2a9c77247871cfa4d3c2d1b47619df91ed5b331a44c8e21f7c9ce431a4db9dfb87713558cc8a37911393907b4cc60be9445bad18adcea1bc5f318256e71be14","up":true},{"one":"c9d705012a06d82c4d44db95b4f1c63ddd33ad64d732e96b1d878caa0caac433d4096f01495a6f0e8a56af122b0470fd745db6d906353b590a4710472b93f5b2","other":"dbb6621460b054f584f1c6157b4020f3c58d84c3a12b57436e10525ae60ab27036bf3edd68b92f2b13674877d01c2871dc67a9031c3d0470985f4b071696346e","up":true},{"other":"1b3107d9a96cfd11f4cd0ed8baeb7b23db1406c9c4a9dac76c772f49c0fc9404f6a4adae11120aa821757173f0cc1cb00e6ab555b5abffaae9001c0557cb75c9","up":true,"one":"93073da602d6326a48464a8b6890220b3aae0abf5b6961180f3aff2a14573c43411bd519d3e0012a646ec2977be18915d95a36d935a69f93985f5307ea4e3ebe"},{"one":"362ed9a92b588d5fe315b90a74aa27f7600e4a7d06b27ceb26272340388d916a831df85bf83450ef80bda4e4a21acaac60560c8a42940a26e2ac567519e2a202","up":true,"other":"313a131ecb7d68e127d0fec8bb4a2e586886203c3d07857a93e7a39bb831703184d9ae28ba9ef3d986c2dae1a24f4f5bfa47cfc35f74f5512a126836364d7736"},{"other":"bc0df855bdadcde3e447415444f655eb430925a8fa81cdcac75909e7d79750f01827938570e75e388cc7058ba8ebca47afadf8b07172bc078488fb618ba71024","up":true,"one":"6b7c94db790a2c1b903208904c4c75b66b17e7a00404727dbc7aeff404ac1118dc78ce4ca443f6b5245236f9e358c09b6da027ae1144e1a6682edca301176330"},{"one":"7d9979c13cd8841e84e5d199fc263962ca6fee12664d8526a581bfcdca2e3427ca169b9a0244dd8292a9a1be2bcedb0e8f626eadd307068c11c03b6df13aee33","up":true,"other":"aa90454031068598ee39af5f1429c7a72277946d50ec2004f340406dbcc9f80cac505c9d9b071f85e2ccfd4b13bcf943f3cb9dd9f96f62d41352af9d8fffe7e4"},{"one":"8e89fe4b3fffea8af247d2581aa511056efbeb796058d50a341d57aa0f7ccc2192d90cfb8d18558363df798567faaddb86815e8bd671b36ca37af0651535aabf","up":true,"other":"6c40910f0556f892a7542989fa01d7e3682fca89aeefb5ed885808f88ff17b6d13862f461c10d629a005ae67abef542d75e5b20816891b6944f71560f5c2dfa8"},{"other":"ecd217e8bdb53c9ef085929b8c2d2b40425a4be617a087b8e7f88e8507b3c981e90fda2119744ca394fe65bd4eb1cdd3fa7258db936048e236d2f15ee91bc3b6","up":true,"one":"aa90454031068598ee39af5f1429c7a72277946d50ec2004f340406dbcc9f80cac505c9d9b071f85e2ccfd4b13bcf943f3cb9dd9f96f62d41352af9d8fffe7e4"},{"one":"d7e3661c0af6754c875217f93d34b254f1f45fc1359a4c6146cd0efa4c6e12aed9a4fb0a21a136f73af4fc2c6d0a63cb809d81855bbc9f51e29d23d90f77b326","up":true,"other":"f60755ee9464c7db769bb7237016fa165441d18ac3bfed7cd2a220a9bcbead202dd34eaf2f9398a3d36bdfc2671bbd46ac25ebe264a8118afe1b7d0bd38710f4"},{"one":"a47697063a2fb973449bdabd0925e10944ba1f6d8b2cc5c38b295f611eea3402b5cf3ae857716a34d84194955f5ed61350affe56223349124c8233852141f9a2","up":true,"other":"aa2028d356a88eca8e0fcaf218d62ace099c3f72dfd95bb28f30ac9a926034cf1d60a40511f7495652745de80d71c0f6830019e206c88e2b6ef0cf4f05d7fe9e"},{"other":"9e21f5d4cfb389ac3ad43497689878bd245a89c587a8637d832b1e355ba244f4c83e6499bc7936e6d35645db25910ecd89b9af9b6b2f0c7cc4d7c6114328d7bf","up":true,"one":"842ec3faa8b4a4cdec32abfa00ae827277fe2696e1b0c6551154533b16cf75ae69caf834b4f08488fa5c8b322fb633b1fd8a5b7d436e9c589cc9074dc031ae68"},{"one":"884d32d09dfef937f3ef1cd6fb5f530c2c574487c0ffd4185ca405c8b2ac73044a196c34352e850ce15321eec6579da654a696381f3e5830d03c7aa18923da6e","up":true,"other":"4eab70233789c544bec97040a04099494bf269a819584a5d0b42295c918a52b02f224a8ed127aba3d92c02f567356bea4b95f77230ef548dfa7fe44b643d8704"},{"up":true,"other":"b7cc9044d021b19cd8a6d290d21f1c91fd5deec472583d0aeed0a6aacc8efef9968079254132becc5443df14dd3f4feaee56d14b885c078649727b9659139fa6","one":"be93fafaf43f6bb3efd2667d1468a8636cb752b245328eaa01468c0606d790322a7cd8e47857068e60118e28b8dd8aa1d2d4977c5b3d28d4b47f4c0658f05e90"},{"one":"d43bd6d3ae39a04e4e144a8a6f80b2d54472b5b9b6491dccf44b1716a63d24c56e3a871b3b8fe983d992988dc07ace06736ead3b1287914b629fcfe17e81f36f","up":true,"other":"43086ff7ffd3c7bdec77bd288f41f1ee0ce21bd3f60a5df8931e2af6e7af5ef0fad432d29625491935d11567944351fc7867c807ebd12dd2c21c9e620ae0f85c"},{"one":"d6747e1f8594f7449fc6d7c0e63ee843480567d498db096ff04229420861c83bca5215fc19d8fede0c54484f111f1f2581e189e638c21c5d9e1fd3174bbb3e98","up":true,"other":"1edeb91789b9aa996fea7a70964e0be33ee50acbe6d8f7d9d9fcf6dcf755dab6402637a610116f0eb716b19259429bdcced8bebc28ffa334387a430efc21b9b0"},{"one":"8e65496318637446a51f0dc87d0a5cf82655866cd1579db1e381af52e12545172b9c88119999ccac3b8b8644efc9675ff183ebe7584c16eb40792cc21f7e9b76","up":true,"other":"8ee65c0937cdf860d5329132c34bf28b5dc4d2593986fae80e4b35efb54ec24cdbf294223515363a917a22dbc6db463c10c7484e22b479b9010059c2521b6317"},{"up":true,"other":"9c8f156797deff649d74d56fc42b4bb1a87312089114d4350424c375837d9c8068dd09af01c1c973d12ec5d7e8da600cd685cae70d3116b9dbda823092e03fff","one":"da22fb43c6d230d92f9c09454e282dc45dffc759740566039f1bdfb58171c6801f721841de83217277b3fb70983e7d34da53bbf25d1d45413a78d9afff151826"},{"up":true,"other":"b3b4b203395bb6655d79ecdcee11638dd9a16baccfcc1f6fcc8b31832c8ca35650eb6c2802104eeec6d96ea80404381a2bd9b01dcadc748a4666b761d9ce64f8","one":"da22fb43c6d230d92f9c09454e282dc45dffc759740566039f1bdfb58171c6801f721841de83217277b3fb70983e7d34da53bbf25d1d45413a78d9afff151826"},{"one":"f60755ee9464c7db769bb7237016fa165441d18ac3bfed7cd2a220a9bcbead202dd34eaf2f9398a3d36bdfc2671bbd46ac25ebe264a8118afe1b7d0bd38710f4","up":true,"other":"33e9d4674b5b9b23e838583f01b429abca1330393dfc100b19ede6090a53df213011fae53169a66aa05d18e4cb497a17aa81eaedf1fe2e4348f9825c309438b5"},{"other":"e903d7aebff96a6afa4b9dd19b0b02e5af18da8e4e89f64247e1a2c2d46637538c741182eac67f45ec61be76aeaccde57f0a0184bd608ea7d92e586d4f827ea7","up":true,"one":"f98c0f4444a1ec80773454ddb691c226b81d8e2f79ed40c45a422d3359565edf7bd635d3eb7bd6c9e0870746849fb86f0b1b34cd56ec8d3ad969812e080f4983"},{"one":"c2a9c77247871cfa4d3c2d1b47619df91ed5b331a44c8e21f7c9ce431a4db9dfb87713558cc8a37911393907b4cc60be9445bad18adcea1bc5f318256e71be14","up":true,"other":"535287ca3d41fc1cdf20a964749a849c51d0aba285f41f447cc2b1dd6f5845b6b98e0241dbda0718b234ea850081bfbf9df01d1aa636d7dcbd99ef3c0a773aff"},{"other":"2c976b6007cda135444233c7bd03d22ac9756710b746c36bc032e7fdd42f2ffb89ca5f5e754ff96b8f3cbc474e346287e5b8531d9f98fd63c426c632872220af","up":true,"one":"8e8614a4c2ee2b1a3fa5ace0ca353cff36b3de3308ccf53665b8b56f8e2456a8a65f3846d786dccd68b1bfcefdd170ea5f8edb481800b1ce72d9fce2added7f0"},{"one":"c61ffc88f23f9f536497cc10ffcb7000ec6c4b801998ae7075ddc9079fdc1da8350e68744dc9e95ff892dfc5e52c62a3ad913a87fdacc455aea99b09aa002b57","up":true,"other":"17ae0b24297a3e6e027884e5e4529b6646ae340f5736eebc6187a9b59832a445f3644172d92438351e3803e56a67472b29f3e1d48844ae2e11e5e6670eed1436"},{"up":true,"other":"b3b4b203395bb6655d79ecdcee11638dd9a16baccfcc1f6fcc8b31832c8ca35650eb6c2802104eeec6d96ea80404381a2bd9b01dcadc748a4666b761d9ce64f8","one":"c29e80096fbe7bc9fcbfdbe3cf6c06449192a3ed280e46a1fa5d424428d893c3456c985c1352c119236cf783834365439751cc87e7ed196614705dd3db6674cf"},{"up":true,"other":"a25958cf192a4f62301feda5d442535f78b983dd9e4599354f4898c8c1e6ad97ca7112549e1d1a1eacb4682cd1bf8b762368b5905ab33dbdacb585b128514ca1","one":"488854534ec5a3479d8ee13d9b7daf07479f6b5505f319eced44dad8c316f6ff241ce2101e95608ba635067f5e5741481b78f419c4bbd465bf7e837dc4e54d64"},{"up":true,"other":"224c3b969149d50d1bb4f473bb9725223c1dafe152efe1b08e8859213c543a66565b5d68a99cef3d5f4eccad6282a12f78d7b38eec14deebf44ad8dd9cba8680","one":"624248a794fd62248024360f128b2e503c752340694a316bed420e5ed2cebeb5bf970df95a2806732237a26de3778222b0454e2e7d2875129b193e7890fd5b95"},{"other":"2cb076669efbaf2ff0b181a1b454061a31ef23937a40405022b126f0eb4bfba60c9e3397009d8c0ff0cabb603692532d0072c18c6838f43397c98483306f62db","up":true,"one":"7c6e6a49429a4e24aa4aa5c7ba19684f77cd67d3744688baff6e7f1d74b7e9d2df85f3e57e0df0a9b960b5bf982a610c5639c3e7a6935ba13fbc77243b2dad19"},{"up":true,"other":"6a37e63feed9e68c52cb8b385d5e8d8dbd2b211c57ded0d3b01fe8b306af5c0e5a7405d0d9a942648f0131926240d53450bc43f922a053528e5830d918313c3d","one":"c2a9c77247871cfa4d3c2d1b47619df91ed5b331a44c8e21f7c9ce431a4db9dfb87713558cc8a37911393907b4cc60be9445bad18adcea1bc5f318256e71be14"},{"one":"f98c0f4444a1ec80773454ddb691c226b81d8e2f79ed40c45a422d3359565edf7bd635d3eb7bd6c9e0870746849fb86f0b1b34cd56ec8d3ad969812e080f4983","other":"3e2241cdb9f34c1d2c6930e59940e2c4b92b0287579d7263a620a609c5e66dca6d85df48cf1bffd63663a6704c42d0866aae3e484fd9a44b6a012f72dd3cef6e","up":true},{"one":"d7e3661c0af6754c875217f93d34b254f1f45fc1359a4c6146cd0efa4c6e12aed9a4fb0a21a136f73af4fc2c6d0a63cb809d81855bbc9f51e29d23d90f77b326","up":true,"other":"e9cd25d1ef3fef22160bce7f7badd7646ac58ee40da6a438f61a067c51bc51d6087ed950ec9e909bc438ebe62e316cbd9489f3c9bfa2898615632414e04f1dcd"},{"one":"6ad4ea3730ddec500e56248d1025aea79ec10f0d6a9720ee48026df10e219b41965d7a611fd99ee765f6afbc8c977db7e67c3a340881904acb983d1e2fb016cc","up":true,"other":"431644cf162bc267237c4e798288888dd835c1b0546b0cc679782e33568988d75b4294f4aa08359a6b152ed9a0fbd13133681156bcf09a871c4f362615ea6dae"},{"one":"ba430731fc2082f4217ebd859c2865c28bf50a39674ca8615dd89f608ae434a09657e24644ac32807634aad7857547118c9228460195e50ec58b34789d4ad151","other":"588df3185f63a5443d8c6b972f67805f0557184d916005f537a4b27cd02bd6a12e432a2b34b234a34f22e923c6f116da85be20bad77a2bf69913684e9d0732ba","up":true},{"one":"7c6e6a49429a4e24aa4aa5c7ba19684f77cd67d3744688baff6e7f1d74b7e9d2df85f3e57e0df0a9b960b5bf982a610c5639c3e7a6935ba13fbc77243b2dad19","other":"c0a2c08fa8b70ecbf1932254945d5f689b0da7a287019d384152f383f6229acd4d82eef26205bc12e062dae4569814bd1c996ee4fe5886bd6bdd93c4f0ac113a","up":true},{"one":"224c3b969149d50d1bb4f473bb9725223c1dafe152efe1b08e8859213c543a66565b5d68a99cef3d5f4eccad6282a12f78d7b38eec14deebf44ad8dd9cba8680","other":"29619924833116cb1160bf7a8066a528b7182794368bfae62b5bacbae680d9161a479f217e30c3b4f19a250b1b59e08f86c94726117dc3bc94ff9ceac6bee6e4","up":true},{"up":true,"other":"ee3471e1d835c4294f7ba642103039ccc548fe4edc177c79b63433ebbb0dc9d06600844f1fed76c7096ee9538e49e4e86fb8cffe9095dbdcde27695ff28ad395","one":"6c2788dec7ae7a77134065afc1174bb92b87833e87acaa72fe9e62c92d2017f217f9fbc5884cdfb7236a7bb75e463e49ecceb1641a8629516211d9699587046e"},{"one":"3e7aef8260c0d9717aa59b65ce7c554e53b81f19f5b9400321704a7ddf5041b0fe31b5634e90b93e6984060defee0e153997bbfe196166cc8d83165fd5eaf41f","up":true,"other":"6c2788dec7ae7a77134065afc1174bb92b87833e87acaa72fe9e62c92d2017f217f9fbc5884cdfb7236a7bb75e463e49ecceb1641a8629516211d9699587046e"},{"other":"c674c405068bb908312917a319e24ddf90e814ee8ef54bbf740f176b2a7eda6950e3e1ed69484ebcc27b13d82c7f0b20daba71a17700018e769ca612ca8d2208","up":true,"one":"dd3dccc1758765569905b3b137ef4c7dd31c2dc0dea827bcc4c4e976be94ffbb0f2ef6fe725cf9042063a96d663efea546837f35ca1fc67a854fbc9e27abb754"},{"one":"6ad4ea3730ddec500e56248d1025aea79ec10f0d6a9720ee48026df10e219b41965d7a611fd99ee765f6afbc8c977db7e67c3a340881904acb983d1e2fb016cc","other":"8fb6838337f832445531764ddafc3c747b2607f2f33e244685d6de621c2b53264270f5504187e43b7fa5cda53e66dd00b16c06879c82fb38a3d9e8aec4060210","up":true},{"up":true,"other":"c674c405068bb908312917a319e24ddf90e814ee8ef54bbf740f176b2a7eda6950e3e1ed69484ebcc27b13d82c7f0b20daba71a17700018e769ca612ca8d2208","one":"d43bd6d3ae39a04e4e144a8a6f80b2d54472b5b9b6491dccf44b1716a63d24c56e3a871b3b8fe983d992988dc07ace06736ead3b1287914b629fcfe17e81f36f"},{"up":true,"other":"b9c7b885430b9b1a4425bde30b3629559f5437e0e30a0299fc6f6e097cbcca8af9e285caf5dea685a0237f60e06f490c39a1e3e487f14a2b9f41a5135f2ba994","one":"a58a4db7a96b1578935b222c78b7b4dd8b3519d2995c3616e5a154c5175242a503097771332504638a0b321b9574110207f9a7d77b109d1de3d66a12ec6498e5"},{"other":"ee0b09ee6a1057c47102e582e2fdec7b9212802e59f062a9360da0db535d4987126ab24848c0d76fa8485431a5140307e2b0c0d9f37cbdb35756e6cc1bdb3bc0","up":true,"one":"d7af0a0217ff98804aa05f8f926a8b6262363b5391d24cda8048cca5ca5982b407b7b098302d0db6d8dd9ac0883b2025b3de651617ed1a173181148295c6d336"},{"up":true,"other":"96cd4caa32c0b3a3493e24e13fad1ef75c621005d74154c3fc8a73cca4c0120452b6432334d94849c63f75d56a2943a453c86d2a14ad1fb61ae6833e58451187","one":"fc9b1b2bbd5e682eb350d23f3ee33b245495daedae9370de7b1f55f91cd45db831d196c17615e11decf6b67696a268ac788130e3de38c7f6aeae811f3ec8c8ee"},{"one":"99a7649bdf2ee7f0bc049308b0997e33abb68481c05a573df9aea30da5a1f267df07b2c584e3e985baf31704f04ad2a2c4876e0f8555333be6d09f5080b583f1","up":true,"other":"3639f964feba681db9702cac3f02058f2e490fd7bffb217dc3480dc458decafd5955541fea89f0f6f14ee50a745eaf98b21363d6b4fb88c31bd32bf7845d524b"},{"up":true,"other":"682288e4dae2374c4784acd0b285508920ce39a6b72cc0e30a3dbb7972e0394a2bddd5ee5f22a1dbf80f284dde4d9f8ede7847318d5353566b35a83e212477e7","one":"ec19efa1d488e74da6bf239825b24678f549c377326c5d33d100b708a9a28a3fe129d542d7ba71e0ade46c15c6e9b38f09422560444388e609a8a66ceb8e0ae8"},{"one":"d09104c44648391693ca64a57baa5ef54ed717e19c65ad0a0921d08cbaca8877d0190795d15f75f3b6ce6e676d6b0e55d5ee8fec3310c68b7060a32f7ff649cb","up":true,"other":"202ae63076a5560418023f00c9965b2a1d12de932b5371ae270d63db88551a7aa1a3c48841f81948fad3435bb4a7e3e165a2eced9fd937444e4502471e23dae8"},{"one":"6c40910f0556f892a7542989fa01d7e3682fca89aeefb5ed885808f88ff17b6d13862f461c10d629a005ae67abef542d75e5b20816891b6944f71560f5c2dfa8","up":true,"other":"4b332b389f1142c0da42aaeb2e2692081d0002de0eb6741b3269e898a8101571d4556b755f2e8841e7a607bb41e398d2b0577fbe71098e7097f0fe6c720e1526"},{"one":"c2568576c2c9ef47aca0baca52709a4fa44b2ed478a062f7b161fac2bdba68568df371ac7754255fd07d79bb9918249a914946a6c318d579730bee9bc609922a","up":true,"other":"9d372d73848389cfa1676f0cdb030950980ed5b68d5b2ef8a058f1d2095b26ff0fafab5fd3c243296ee2620edc67752970ab47370270856287f8612d1b190a19"},{"up":true,"other":"c03ef1de42d522b44eef53be11f2c57b8b74fed9e87e6c2928c1feb48ddfecc67e1a3a8c8be1c47b3735a216d7054e2a4dda49fbd9a1ac702146aae5bdeced7c","one":"6a55b94c9990249b24cdbeed96f065137f7b79ea8ee5f58da150d3962dfb62ba401960a53e7e8bd4e2c2908aa1a59b9d5efb4aafb316a9ab4fa67a0d95b58c54"},{"one":"f4cdaeb513aa98f8868d8eb3a1d12c07367725928a1bc7d6ca4b583788e111a955463037ec7867260511896d97dfbf096aa77ee8a7d9ea1c06cad4a92c45108d","other":"2b0a1f3a6466c6be1d7e84120db384fa37f7c73a01e9a105ae90e7d2203212ec974f016d3012afd26bc0f9a8411d0716cc59b6ecc9f665db12e306af8b34cb63","up":true},{"one":"85b6404a76b4762156c8ddd2f312763dfe19b315d914533844cf229301880c57ffeadc0eb5f4a8d542e1d9fc961dfb5a572d2101172b1a0fc238ced05ba49ec1","up":true,"other":"37399617d62153bc471f3bf21c92385bc8602c80ffa0c71da8aebae595a9859cfd56257aae60ad30ef3ec4d07dee90623cce63749c8c3233c0aa0d17f9e89afe"},{"up":true,"other":"69f999937943be00e5fca5c7cc942ce13b6752a72813368da2fbfcf74ad807bc6edd85537e087b6f73c0469c7b76a5d8f7d883bd315f3b35af32b8da293ed243","one":"dbb6621460b054f584f1c6157b4020f3c58d84c3a12b57436e10525ae60ab27036bf3edd68b92f2b13674877d01c2871dc67a9031c3d0470985f4b071696346e"},{"other":"33cac8f621b9122e118036154778d27dc419b6b58ea2e89b833f3932f411dbc3511d92b55ae4cf80632142bc8e67994899aaa30c499d0289fae85b12564cf01f","up":true,"one":"c2568576c2c9ef47aca0baca52709a4fa44b2ed478a062f7b161fac2bdba68568df371ac7754255fd07d79bb9918249a914946a6c318d579730bee9bc609922a"},{"up":true,"other":"3948a7a939b9a1f4201953bd9b955ee7be87d09b63c7a45167f556ac06fe3c4c2a75d935bff50668da5e71e46802b55d7a9945a92d7807c00625d129cbb48f82","one":"545237d8463b75fd2e9bbfbffb35c5b78b4abbc85f6bfbd56976789012dd9a62ca1f866bf37bb33618e026aab764adb9ced5e00cd415562f69992f74c795083f"},{"one":"57085f756f76644cdd2148524f2334d869ef0ab2fcbe7fb11f5d22bc1f5023165b11526ecc85ff9cbb88877386af9b148d7ef15a825b3a586d16c01bdfc86692","other":"5114329db828f9568ccb0d7643a10e273aa626177910f55e22a53abf1ce8ec75b95465c983446b20eac0ff9c59c5dc53eca95b24aabcc8dd110e397cd2934047","up":true},{"up":true,"other":"9309549fc50173d6826fe63cf18699f49199c3789616b843042fe1a6adab6ed4bdd7a7a06acd276e0398cf8bffb26c12a4227725d7bbd386a9a55fc601c21405","one":"f4cdaeb513aa98f8868d8eb3a1d12c07367725928a1bc7d6ca4b583788e111a955463037ec7867260511896d97dfbf096aa77ee8a7d9ea1c06cad4a92c45108d"},{"up":true,"other":"3948a7a939b9a1f4201953bd9b955ee7be87d09b63c7a45167f556ac06fe3c4c2a75d935bff50668da5e71e46802b55d7a9945a92d7807c00625d129cbb48f82","one":"6d0a09235ba0b0428938abf0e0782ac0ecf5697ef862888719a34fc956517aeef89d5e5f76d12e10067fee5bac8781dc10400eeb35c2393b9382b2a4f68f7939"},{"one":"85b6404a76b4762156c8ddd2f312763dfe19b315d914533844cf229301880c57ffeadc0eb5f4a8d542e1d9fc961dfb5a572d2101172b1a0fc238ced05ba49ec1","other":"ee0b09ee6a1057c47102e582e2fdec7b9212802e59f062a9360da0db535d4987126ab24848c0d76fa8485431a5140307e2b0c0d9f37cbdb35756e6cc1bdb3bc0","up":true},{"one":"37399617d62153bc471f3bf21c92385bc8602c80ffa0c71da8aebae595a9859cfd56257aae60ad30ef3ec4d07dee90623cce63749c8c3233c0aa0d17f9e89afe","other":"e903d7aebff96a6afa4b9dd19b0b02e5af18da8e4e89f64247e1a2c2d46637538c741182eac67f45ec61be76aeaccde57f0a0184bd608ea7d92e586d4f827ea7","up":true},{"other":"aa2028d356a88eca8e0fcaf218d62ace099c3f72dfd95bb28f30ac9a926034cf1d60a40511f7495652745de80d71c0f6830019e206c88e2b6ef0cf4f05d7fe9e","up":true,"one":"9d372d73848389cfa1676f0cdb030950980ed5b68d5b2ef8a058f1d2095b26ff0fafab5fd3c243296ee2620edc67752970ab47370270856287f8612d1b190a19"},{"other":"9d372d73848389cfa1676f0cdb030950980ed5b68d5b2ef8a058f1d2095b26ff0fafab5fd3c243296ee2620edc67752970ab47370270856287f8612d1b190a19","up":true,"one":"c2a9c77247871cfa4d3c2d1b47619df91ed5b331a44c8e21f7c9ce431a4db9dfb87713558cc8a37911393907b4cc60be9445bad18adcea1bc5f318256e71be14"},{"one":"b4f300abda4cf6e383f997510eb681e9fa62e23577e3c19bd7447fa1f5702a4e034cea5944248e7c6e6e92b5ae69195c3e8a2c5ca7827b4f4a00cc8546e6695a","other":"f4cdaeb513aa98f8868d8eb3a1d12c07367725928a1bc7d6ca4b583788e111a955463037ec7867260511896d97dfbf096aa77ee8a7d9ea1c06cad4a92c45108d","up":true},{"up":true,"other":"43086ff7ffd3c7bdec77bd288f41f1ee0ce21bd3f60a5df8931e2af6e7af5ef0fad432d29625491935d11567944351fc7867c807ebd12dd2c21c9e620ae0f85c","one":"c63b88f494b14d5a7c1da124ffebbd985d19806b91d4b111c83ae129c4ef19614469980a09fbeccebe3b0358dd16194bdb6452d0b3dbb43a5467e23bb13f40d6"},{"up":true,"other":"e903d7aebff96a6afa4b9dd19b0b02e5af18da8e4e89f64247e1a2c2d46637538c741182eac67f45ec61be76aeaccde57f0a0184bd608ea7d92e586d4f827ea7","one":"70cce7cb0c18091dbb6d41160ab560935f1759b969bf8118cee030ee707cb15ba407b8c48dcd9fd012cbf778e219f7d16a74064b4983cf098fb118297748edb6"},{"one":"37399617d62153bc471f3bf21c92385bc8602c80ffa0c71da8aebae595a9859cfd56257aae60ad30ef3ec4d07dee90623cce63749c8c3233c0aa0d17f9e89afe","other":"01427ba4d1e2de0b2764515556676a6058f88c16f597780dea3d7f95a6eec9299c3987d99c199d88a0a5e695ee6f0ff7de424e4eb65e54233b956a9634133998","up":true},{"one":"1c080e90760dfcee08ade6e4ea3b275ff3c6882f3b44b7f3a73d70bcc816fc63ce0b6138f810d17d96ed387076f9bbb6dbb2ef6dc4d6ba6542c1f587b7602a12","other":"4b332b389f1142c0da42aaeb2e2692081d0002de0eb6741b3269e898a8101571d4556b755f2e8841e7a607bb41e398d2b0577fbe71098e7097f0fe6c720e1526","up":true},{"one":"f4cdaeb513aa98f8868d8eb3a1d12c07367725928a1bc7d6ca4b583788e111a955463037ec7867260511896d97dfbf096aa77ee8a7d9ea1c06cad4a92c45108d","up":true,"other":"37399617d62153bc471f3bf21c92385bc8602c80ffa0c71da8aebae595a9859cfd56257aae60ad30ef3ec4d07dee90623cce63749c8c3233c0aa0d17f9e89afe"},{"other":"81901d9f043b4b1649ade3b5d22ae5f8bb42dd6db1eb37b836b99dd1c0388509ed4b54cc5638c9d4a6c5ae6c6913bbfffb303d7d94bf4ed50e871cf95459e2c3","up":true,"one":"b4f300abda4cf6e383f997510eb681e9fa62e23577e3c19bd7447fa1f5702a4e034cea5944248e7c6e6e92b5ae69195c3e8a2c5ca7827b4f4a00cc8546e6695a"},{"up":true,"other":"1edeb91789b9aa996fea7a70964e0be33ee50acbe6d8f7d9d9fcf6dcf755dab6402637a610116f0eb716b19259429bdcced8bebc28ffa334387a430efc21b9b0","one":"df9306a263f40e0e255996500523354de3cc78b68ae560f66d79f6ea28f30f773f1fd6ebc33928723dfde2ee3d4f982b203bee4c3803a5050df83477045bb279"},{"up":true,"other":"877d17ec7e95998ead831606d3363fbff1c8d1fa377b8e621e6a876d2c7776b9af356211a7e4df66adeaf38cf9b49c04871e8804edde4c18435ff45e110ecb04","one":"7d9979c13cd8841e84e5d199fc263962ca6fee12664d8526a581bfcdca2e3427ca169b9a0244dd8292a9a1be2bcedb0e8f626eadd307068c11c03b6df13aee33"},{"one":"b7cc9044d021b19cd8a6d290d21f1c91fd5deec472583d0aeed0a6aacc8efef9968079254132becc5443df14dd3f4feaee56d14b885c078649727b9659139fa6","up":true,"other":"dd3dccc1758765569905b3b137ef4c7dd31c2dc0dea827bcc4c4e976be94ffbb0f2ef6fe725cf9042063a96d663efea546837f35ca1fc67a854fbc9e27abb754"},{"up":true,"other":"202ae63076a5560418023f00c9965b2a1d12de932b5371ae270d63db88551a7aa1a3c48841f81948fad3435bb4a7e3e165a2eced9fd937444e4502471e23dae8","one":"57085f756f76644cdd2148524f2334d869ef0ab2fcbe7fb11f5d22bc1f5023165b11526ecc85ff9cbb88877386af9b148d7ef15a825b3a586d16c01bdfc86692"},{"other":"95ff4dea07303e1ba641a5c510e714ef232f4dbce9ad2e8b2f62644975eae41fc4bb9d1af3fae4d5ea4daeb18f8248e0b3131c7d843d35d33f3afbf7dfa4c2fe","up":true,"one":"2c976b6007cda135444233c7bd03d22ac9756710b746c36bc032e7fdd42f2ffb89ca5f5e754ff96b8f3cbc474e346287e5b8531d9f98fd63c426c632872220af"},{"other":"1489ad735e1256900e4733707f8b78f1d853742a8f9b2d0c1c89651c60e7ee9d266afba5b4c1ed3f9cee05a1d2b2bba35dadb5b08973a93fd70dfb9e367339bd","up":true,"one":"85b6404a76b4762156c8ddd2f312763dfe19b315d914533844cf229301880c57ffeadc0eb5f4a8d542e1d9fc961dfb5a572d2101172b1a0fc238ced05ba49ec1"},{"one":"ecd217e8bdb53c9ef085929b8c2d2b40425a4be617a087b8e7f88e8507b3c981e90fda2119744ca394fe65bd4eb1cdd3fa7258db936048e236d2f15ee91bc3b6","up":true,"other":"9bdacc256acef0433805477d38f32be849a8846d88cb883b19d290454639b42c6ab6c5c52d4f83453e8a156af7d85f606458aa9c0977c67282f56f34ff0acbfb"},{"other":"e5cb29b25debcfaaacc0b04e708c8c1cb9d2dee29e82596a1c72a934032cf738800b9525cc277d0c5f5dacf2f278329b54da161b4bafa285243fa0e9fd7b2f3a","up":true,"one":"228b3646b15527f4df07b847a62dbf9620cb068f829e9086b5f437d0b64d8a027cab44f19db5e44189b5099545ecb25d49384c261748f9533cfb0eb11a1eca5f"},{"one":"a25958cf192a4f62301feda5d442535f78b983dd9e4599354f4898c8c1e6ad97ca7112549e1d1a1eacb4682cd1bf8b762368b5905ab33dbdacb585b128514ca1","other":"37399617d62153bc471f3bf21c92385bc8602c80ffa0c71da8aebae595a9859cfd56257aae60ad30ef3ec4d07dee90623cce63749c8c3233c0aa0d17f9e89afe","up":true},{"one":"c088bf88f1e152ca3fad17f098a71ca1021d46d8af12d0ee1c587a5e2a430d8e48beaf171fe01ee7680b671c00dd88c90f12a35c328a3f334661fdeee914a4bc","other":"e7b2adabc2c99ac47b1e94fc0a2c63a00a1d622ea67a4c1858f4cec93fca957d43d8429605761bdf5eed4f733dac1a3d12fb928f22abf248965994acde63864a","up":true},{"up":true,"other":"37399617d62153bc471f3bf21c92385bc8602c80ffa0c71da8aebae595a9859cfd56257aae60ad30ef3ec4d07dee90623cce63749c8c3233c0aa0d17f9e89afe","one":"222d7a2f94dc82a09fda70b8195fc3a60433a90f53998872318c57625c528c90572d78b444ac4901dcfece1a03ef8b6cbe7845366a845a942f341f6db58a9b3b"},{"other":"7db14fde1da8794ae7ab5de37c9e2537e1024bc830c176c0d01635cafed47773d3a28e156db81ecdb95903222b900c3ebd4c4b3db2971dc0ef6a1e386027ffaa","up":true,"one":"877d17ec7e95998ead831606d3363fbff1c8d1fa377b8e621e6a876d2c7776b9af356211a7e4df66adeaf38cf9b49c04871e8804edde4c18435ff45e110ecb04"},{"one":"936fad959da2d8b0cfb2bcd78c5da65bcce5e9463be7fc7367f45cdfa20678f4c466fb1e3f600783a270855fd4b9cd6265054f79ecb116141e7c67a492041bed","other":"0e164c8692532e59c76ef84319a1093324f46f77618d3a836a279df52edca6c839061c0582dac7481da1bd0f3e2b58fc0dacd6ee5d678ba1406d4a1a25fe761d","up":true},{"up":true,"other":"7958d1517de1223e7fb30acf61d8618e49fb95a03bc2f49141f4c7967bc80b90e0dd526c205639de3c060029963d43813293c2556f7b127945c798f3f9f18626","one":"6c40910f0556f892a7542989fa01d7e3682fca89aeefb5ed885808f88ff17b6d13862f461c10d629a005ae67abef542d75e5b20816891b6944f71560f5c2dfa8"},{"other":"f6a12b23423c047927a3024a6dba7ce88927cb21d4df3778bc5ebb262cc403261c79ba6d9bda07f1852c009d803a77f429e9e48ec1d63cae98256e529d45b276","up":true,"one":"ab13f773f6f2ff73032aa5f79c8897b75dda29bcbb14aa511e9401c2417dc9c510253071e28c7833c8d62fd2aef16fcd0c14ce016fbf4fec1b9a2173c717603f"},{"other":"01427ba4d1e2de0b2764515556676a6058f88c16f597780dea3d7f95a6eec9299c3987d99c199d88a0a5e695ee6f0ff7de424e4eb65e54233b956a9634133998","up":true,"one":"20f6a8be1d2d8b5d6a43d851a2f5475385ef07fab80ac46525d0beccf3e25c01d726cfb3a1179e8343b1e88d21684fb24dd6e6497537d4e7e9edd59cb95d1b8d"},{"other":"a1fe0d27f82309911a4b758c4e597bde16adc1e2fdfb07b52dea5092cea40ff212ea2cc831e385094b044f519909cf978f350b16ffd4c70c159cf1372301a3cf","up":true,"one":"936fad959da2d8b0cfb2bcd78c5da65bcce5e9463be7fc7367f45cdfa20678f4c466fb1e3f600783a270855fd4b9cd6265054f79ecb116141e7c67a492041bed"},{"up":true,"other":"3639f964feba681db9702cac3f02058f2e490fd7bffb217dc3480dc458decafd5955541fea89f0f6f14ee50a745eaf98b21363d6b4fb88c31bd32bf7845d524b","one":"20f6a8be1d2d8b5d6a43d851a2f5475385ef07fab80ac46525d0beccf3e25c01d726cfb3a1179e8343b1e88d21684fb24dd6e6497537d4e7e9edd59cb95d1b8d"},{"up":true,"other":"1e3a2f2491b6acb07a9549d9929d150479a0313c926b0e236237bd541303da4b563a855016a90ab50e59d94803ad566798570fa981464c94c04a4a4a94fbc607","one":"81dc656de121016bcde81d5bf7919839acfc180dfbf1a6de2cadf704ff13af98aa5715a4168832ca6f651b2ea7ad9e6ca5f1c1cb7e885dbc2eb23d4aefb87bd6"},{"one":"d3cd2f34f67830ccdc295b7537a6d27c02b44503808ca666124f52ecc3d6c35b7d3f14343997006aef2cfbefc8d27809d389477e99c236b9f8a897a4bc406a43","up":true,"other":"1c080e90760dfcee08ade6e4ea3b275ff3c6882f3b44b7f3a73d70bcc816fc63ce0b6138f810d17d96ed387076f9bbb6dbb2ef6dc4d6ba6542c1f587b7602a12"},{"up":true,"other":"0c82c4b414375479375703ed9c19fb08c8143229ed4f1dcf448c6cf313810c098905123bec17969276936ae0cc39ed251b2811dbffb551d61159862b0eac0a23","one":"b58b3e200f6072ddb38130944a01d2829c755b8bd1a08abd010d1bbf86dabd851b2c1ab4cb961451bd7e8499f6c7378830bcd27cde825846654853c172597bf3"},{"one":"85b6404a76b4762156c8ddd2f312763dfe19b315d914533844cf229301880c57ffeadc0eb5f4a8d542e1d9fc961dfb5a572d2101172b1a0fc238ced05ba49ec1","up":true,"other":"b8e0a56df21baae43058f575b714ae9a33c097d18f1a628b3b6ae5e86dd46a06e44c0dc272baacb5be0f7bf57fd6ddce107544eb3b94dca1aeae9f5773496a72"},{"one":"81901d9f043b4b1649ade3b5d22ae5f8bb42dd6db1eb37b836b99dd1c0388509ed4b54cc5638c9d4a6c5ae6c6913bbfffb303d7d94bf4ed50e871cf95459e2c3","other":"85b6404a76b4762156c8ddd2f312763dfe19b315d914533844cf229301880c57ffeadc0eb5f4a8d542e1d9fc961dfb5a572d2101172b1a0fc238ced05ba49ec1","up":true},{"one":"20f6a8be1d2d8b5d6a43d851a2f5475385ef07fab80ac46525d0beccf3e25c01d726cfb3a1179e8343b1e88d21684fb24dd6e6497537d4e7e9edd59cb95d1b8d","other":"5982e7dfd39c527851f6ea6430b70e654d95df5ec4401ca1d8dbd1034cf7a65d1126d60b36ebbd396c9ca32e6e8515f34f9dc0a8d2980afe4aa181c8bf68437e","up":true},{"one":"01427ba4d1e2de0b2764515556676a6058f88c16f597780dea3d7f95a6eec9299c3987d99c199d88a0a5e695ee6f0ff7de424e4eb65e54233b956a9634133998","up":true,"other":"da22fb43c6d230d92f9c09454e282dc45dffc759740566039f1bdfb58171c6801f721841de83217277b3fb70983e7d34da53bbf25d1d45413a78d9afff151826"},{"one":"207764262a208c17db61fda4208d4664bf74010e0ad051a863e131e748c9304e11ccf007c925488ea86b974ee61cdac3dca4d4b3f4043524e03c194ab3c8eb5a","up":true,"other":"10551c0c37abc25457903978868dd4843a52fda5f9b571b05ebd974d8c381fda4349f17c2b986a2e4b8d06b0517422f085d5f6d9cd814efa40e48393d9f71d7e"},{"up":true,"other":"b9c7b885430b9b1a4425bde30b3629559f5437e0e30a0299fc6f6e097cbcca8af9e285caf5dea685a0237f60e06f490c39a1e3e487f14a2b9f41a5135f2ba994","one":"8d3ad57509b36c4ca5c4663f3d1977a3125e069078842634e6cfeb22c044281e3d02f06eafc6d2a60089f03d70f5134a6635c35563c9f911fd845a6ef9bc8952"},{"up":true,"other":"46717bc5fb7fcbcdc961e7ef091020f9f222858cf3d4afcc0b0bb1b782b7055d9eb833e0a04cb32d80406133ac77162521c43edf9f9690872222760e31462ccc","one":"96cd4caa32c0b3a3493e24e13fad1ef75c621005d74154c3fc8a73cca4c0120452b6432334d94849c63f75d56a2943a453c86d2a14ad1fb61ae6833e58451187"},{"one":"81901d9f043b4b1649ade3b5d22ae5f8bb42dd6db1eb37b836b99dd1c0388509ed4b54cc5638c9d4a6c5ae6c6913bbfffb303d7d94bf4ed50e871cf95459e2c3","other":"c0f233e79d0a8d4af01f54c40640975bc113f464271ba8922fca0c28acc60367af0db06629e701977e86cb5917c891e39c21418cab459fe49132b680aa31600b","up":true},{"up":true,"other":"33cac8f621b9122e118036154778d27dc419b6b58ea2e89b833f3932f411dbc3511d92b55ae4cf80632142bc8e67994899aaa30c499d0289fae85b12564cf01f","one":"fc9b1b2bbd5e682eb350d23f3ee33b245495daedae9370de7b1f55f91cd45db831d196c17615e11decf6b67696a268ac788130e3de38c7f6aeae811f3ec8c8ee"},{"one":"15ceb62ee0f53379aa202950634ed881ba3b7bd4b46c80723ee48190079311e24ffaacb167a126a40bd6732c384f3c26163aa043edca03cb52a97b6da189aec7","other":"76643f67075c6e45bd176db19473240cda6f886d1cac25330e2d99c84a429934f4c6a606c9c72574d5eaccd0a3f1770dab05e6ff6a5b5ce4d7258fed2bc13d48","up":true},{"one":"5114329db828f9568ccb0d7643a10e273aa626177910f55e22a53abf1ce8ec75b95465c983446b20eac0ff9c59c5dc53eca95b24aabcc8dd110e397cd2934047","other":"a25958cf192a4f62301feda5d442535f78b983dd9e4599354f4898c8c1e6ad97ca7112549e1d1a1eacb4682cd1bf8b762368b5905ab33dbdacb585b128514ca1","up":true},{"other":"9e21f5d4cfb389ac3ad43497689878bd245a89c587a8637d832b1e355ba244f4c83e6499bc7936e6d35645db25910ecd89b9af9b6b2f0c7cc4d7c6114328d7bf","up":true,"one":"b58b3e200f6072ddb38130944a01d2829c755b8bd1a08abd010d1bbf86dabd851b2c1ab4cb961451bd7e8499f6c7378830bcd27cde825846654853c172597bf3"},{"other":"545237d8463b75fd2e9bbfbffb35c5b78b4abbc85f6bfbd56976789012dd9a62ca1f866bf37bb33618e026aab764adb9ced5e00cd415562f69992f74c795083f","up":true,"one":"865dbf61d8511603fe0d9ebfb10792b9f6b798187c0909039bd9b2492c41e428876f386beeac86d0dea871f4fc24ba435f0fbd9a11e74c044024934592af14ee"},{"one":"ec19efa1d488e74da6bf239825b24678f549c377326c5d33d100b708a9a28a3fe129d542d7ba71e0ade46c15c6e9b38f09422560444388e609a8a66ceb8e0ae8","up":true,"other":"85c0b055439f114dee5eb0961013c117a48d62b0f17c61a7fd92a84092ef09bb3bbce686aa96e14528d5663565c57d657fa9813b1f38e268caeb1cb0842ef232"},{"one":"5114329db828f9568ccb0d7643a10e273aa626177910f55e22a53abf1ce8ec75b95465c983446b20eac0ff9c59c5dc53eca95b24aabcc8dd110e397cd2934047","up":true,"other":"f52281c227aa82a3bd5fabfdcf8bdf1d9ea6739ab9b9075340143d59b4f2f8a79a981609c9f42823a0253c19a7281eed0e912e4054363ab7fe50117563ef14e0"},{"other":"aa53ca208cc0c9e544fd9d52cab44b5e2887256bb006037b855b5c94d7f79c9388fdbb23c0bf1d2eee12d67125e082fa7ecb34c1129ca8eaecfd85772b009435","up":true,"one":"7a8cb96685c1b8fbaeb18c8dc1f9f2631b23bc035e704e2f5df915b8bcabd6e2025ddc30324c69833f86e577b250c0721fee9d294f3e22016ae4c59c5f88845b"},{"one":"e323da6ae861cb092543992b8985639f9b3bcaf1c3c68757f4603a67800be62950fe7d8f8ef80eb83a18107b677c7f5047ea89a5790e0ea2a7969f4856d28488","other":"aa90454031068598ee39af5f1429c7a72277946d50ec2004f340406dbcc9f80cac505c9d9b071f85e2ccfd4b13bcf943f3cb9dd9f96f62d41352af9d8fffe7e4","up":true},{"up":true,"other":"fd0123c7b96004067e98e463e273de5bc5402399ae70a95985b5f682e30d4f35d070deaf8c71d201e98c4324d832b95aab7535ad8a2658f66e3e0bb1202204e1","one":"865dbf61d8511603fe0d9ebfb10792b9f6b798187c0909039bd9b2492c41e428876f386beeac86d0dea871f4fc24ba435f0fbd9a11e74c044024934592af14ee"},{"one":"c03ef1de42d522b44eef53be11f2c57b8b74fed9e87e6c2928c1feb48ddfecc67e1a3a8c8be1c47b3735a216d7054e2a4dda49fbd9a1ac702146aae5bdeced7c","other":"1edeb91789b9aa996fea7a70964e0be33ee50acbe6d8f7d9d9fcf6dcf755dab6402637a610116f0eb716b19259429bdcced8bebc28ffa334387a430efc21b9b0","up":true},{"one":"81901d9f043b4b1649ade3b5d22ae5f8bb42dd6db1eb37b836b99dd1c0388509ed4b54cc5638c9d4a6c5ae6c6913bbfffb303d7d94bf4ed50e871cf95459e2c3","other":"baa28b8cb7ec539e0e157d7598cc5a5b0210fd8fb5c9026c3cd612133c5a8ee56997507511928af5683cb620fd85593dd8f6ff882d95fb847870ae4ce7dc503b","up":true},{"one":"b87e7f36ed6bf142d48545024d2fd6e120c44511701e7c0b7d7fc786f4f29d3357024b15f70b78215d8a4c2b7572d608c11b31612743e23db4fa673f0cd6519b","up":true,"other":"9c8fca41b833e88110559b9258653160f5fb236bd637272ac58fe1adf333f4df75b94a805eaebb9f10a8c1a26d357dd75140560551d3fc4da79da2c4fc9479c3"},{"one":"2abb91884cc3a8fb91b2f2f369f9430f2b3b05c75ce6203aa7a50312c9f141f9d0f615063d3576a5ce8a4be9ecb942aa804a717f76d9e8dca03d115dcc43f775","other":"545237d8463b75fd2e9bbfbffb35c5b78b4abbc85f6bfbd56976789012dd9a62ca1f866bf37bb33618e026aab764adb9ced5e00cd415562f69992f74c795083f","up":true},{"one":"5114329db828f9568ccb0d7643a10e273aa626177910f55e22a53abf1ce8ec75b95465c983446b20eac0ff9c59c5dc53eca95b24aabcc8dd110e397cd2934047","up":true,"other":"c03ef1de42d522b44eef53be11f2c57b8b74fed9e87e6c2928c1feb48ddfecc67e1a3a8c8be1c47b3735a216d7054e2a4dda49fbd9a1ac702146aae5bdeced7c"},{"one":"0e164c8692532e59c76ef84319a1093324f46f77618d3a836a279df52edca6c839061c0582dac7481da1bd0f3e2b58fc0dacd6ee5d678ba1406d4a1a25fe761d","up":true,"other":"1b3107d9a96cfd11f4cd0ed8baeb7b23db1406c9c4a9dac76c772f49c0fc9404f6a4adae11120aa821757173f0cc1cb00e6ab555b5abffaae9001c0557cb75c9"},{"other":"d6747e1f8594f7449fc6d7c0e63ee843480567d498db096ff04229420861c83bca5215fc19d8fede0c54484f111f1f2581e189e638c21c5d9e1fd3174bbb3e98","up":true,"one":"7db14fde1da8794ae7ab5de37c9e2537e1024bc830c176c0d01635cafed47773d3a28e156db81ecdb95903222b900c3ebd4c4b3db2971dc0ef6a1e386027ffaa"},{"up":true,"other":"a25958cf192a4f62301feda5d442535f78b983dd9e4599354f4898c8c1e6ad97ca7112549e1d1a1eacb4682cd1bf8b762368b5905ab33dbdacb585b128514ca1","one":"89d46e664ac471c7150fbfe43a49c98750fc64d5ca22fdc2a040c7ab78c25c48c1e9c2f0e5130d6b8eb7f0760fe962759d83f68cc08ffaac3520499b0ce694de"},{"one":"df9306a263f40e0e255996500523354de3cc78b68ae560f66d79f6ea28f30f773f1fd6ebc33928723dfde2ee3d4f982b203bee4c3803a5050df83477045bb279","other":"2880e0defd1bf2665bdd20dfb46bc0a9ad707f495211fc78e611ab479d78398db7daff7d3f4b6bf81fd13bf766ecc8271e0ea99a2d74abd2f9ddf98835ffdcf1","up":true},{"one":"b87e7f36ed6bf142d48545024d2fd6e120c44511701e7c0b7d7fc786f4f29d3357024b15f70b78215d8a4c2b7572d608c11b31612743e23db4fa673f0cd6519b","up":true,"other":"876618c8ba66c1b91b473a154be3e10ded3590ba83d620d30e0ff1fbac2f31f258b1299a3da5b56aa03269a80c119b7fc41dfd87d5bd996359e4ad8dd0ab2a6a"},{"one":"b7cc9044d021b19cd8a6d290d21f1c91fd5deec472583d0aeed0a6aacc8efef9968079254132becc5443df14dd3f4feaee56d14b885c078649727b9659139fa6","other":"95ff4dea07303e1ba641a5c510e714ef232f4dbce9ad2e8b2f62644975eae41fc4bb9d1af3fae4d5ea4daeb18f8248e0b3131c7d843d35d33f3afbf7dfa4c2fe","up":true},{"one":"3dcf18c35593b47bc463688493b792d6b9d13eabe05396e491953608f20cf55f770fc21be32b00335fcb2f0ba02735b92569b2b64a44c344ac348042876e8f15","up":true,"other":"a1fe0d27f82309911a4b758c4e597bde16adc1e2fdfb07b52dea5092cea40ff212ea2cc831e385094b044f519909cf978f350b16ffd4c70c159cf1372301a3cf"},{"up":true,"other":"aa90454031068598ee39af5f1429c7a72277946d50ec2004f340406dbcc9f80cac505c9d9b071f85e2ccfd4b13bcf943f3cb9dd9f96f62d41352af9d8fffe7e4","one":"5a235aca7005df295d5bd924b1272452e9bdad408ca5223b9eb76800b4bd4e3158a1d663ce5243fee92233227249fe4bb8507e8cb2c3729744b273bf488ba60c"},{"other":"a25958cf192a4f62301feda5d442535f78b983dd9e4599354f4898c8c1e6ad97ca7112549e1d1a1eacb4682cd1bf8b762368b5905ab33dbdacb585b128514ca1","up":true,"one":"ee3471e1d835c4294f7ba642103039ccc548fe4edc177c79b63433ebbb0dc9d06600844f1fed76c7096ee9538e49e4e86fb8cffe9095dbdcde27695ff28ad395"},{"one":"6a55b94c9990249b24cdbeed96f065137f7b79ea8ee5f58da150d3962dfb62ba401960a53e7e8bd4e2c2908aa1a59b9d5efb4aafb316a9ab4fa67a0d95b58c54","other":"a8fac88fba179fb9b259d94caac9cbe45d873a0131bef8844ac4383b177daf6f301f8793623fec5876885db1a91e5b3e98e2aafdaa47e03b1f6d9740f48af7ac","up":true},{"one":"ef7157fdfe62390d8a6d4ef976478d17465b42b63fddb03664973d63efb62318a8f59e412150528a32aa2c028b9de6bc67f05e012b8c43d710032ad871bc27e5","other":"842f0ac24370f14edfe72a7d07219de60fc767d2d0356fa6ce9d535a43647ad4bb17d9be75ed83542868ba430ec104ba168f27c16915cdbd6e57ae62d60707cb","up":true},{"up":true,"other":"2abb91884cc3a8fb91b2f2f369f9430f2b3b05c75ce6203aa7a50312c9f141f9d0f615063d3576a5ce8a4be9ecb942aa804a717f76d9e8dca03d115dcc43f775","one":"dd6acfd151220f21b03701ca554a5e134dbd1154dda21d9eec45809e7858fe83eca3953fc688f499030198f22052c3681a9f49207ef9b11a760456ab9637352b"},{"one":"bc0df855bdadcde3e447415444f655eb430925a8fa81cdcac75909e7d79750f01827938570e75e388cc7058ba8ebca47afadf8b07172bc078488fb618ba71024","up":true,"other":"c69b9b181b2756a1345b73a97afb3dca909c253188c3b905f0b414465b750d2ffccb4c8e8eb5e3809549af55db473f3b12682f9bd97c5c75d68f23d67d91b866"},{"up":true,"other":"c674c405068bb908312917a319e24ddf90e814ee8ef54bbf740f176b2a7eda6950e3e1ed69484ebcc27b13d82c7f0b20daba71a17700018e769ca612ca8d2208","one":"0c82c4b414375479375703ed9c19fb08c8143229ed4f1dcf448c6cf313810c098905123bec17969276936ae0cc39ed251b2811dbffb551d61159862b0eac0a23"},{"one":"002cb6ffa63ad71ee6ebc1df4c41f7a97c51f274b1d3b22420c87b73136be5169b9670508061d8261e20055fefce3b855388994672aa9a0f1475c43839aae4fa","up":true,"other":"4116fbb7d55bfd4bd8db9cbfa570ac361bb88605b6aacbf84e245893cf3fa599ecc086688a4c534c81f61a90fa344ca37e4d4013ddc03f7f08218724a55f66b1"},{"other":"222d7a2f94dc82a09fda70b8195fc3a60433a90f53998872318c57625c528c90572d78b444ac4901dcfece1a03ef8b6cbe7845366a845a942f341f6db58a9b3b","up":true,"one":"ee0b09ee6a1057c47102e582e2fdec7b9212802e59f062a9360da0db535d4987126ab24848c0d76fa8485431a5140307e2b0c0d9f37cbdb35756e6cc1bdb3bc0"},{"one":"e0f13606a7f35b9ad8a9c4e70336c4c554ac718720a451a349eb4e1a4b055079483cac040ec64e0ed3d8bdb336618a5ae6ef74e31642fae4d7ed9949858eb361","up":true,"other":"6b7c94db790a2c1b903208904c4c75b66b17e7a00404727dbc7aeff404ac1118dc78ce4ca443f6b5245236f9e358c09b6da027ae1144e1a6682edca301176330"},{"up":true,"other":"4b332b389f1142c0da42aaeb2e2692081d0002de0eb6741b3269e898a8101571d4556b755f2e8841e7a607bb41e398d2b0577fbe71098e7097f0fe6c720e1526","one":"b7cc9044d021b19cd8a6d290d21f1c91fd5deec472583d0aeed0a6aacc8efef9968079254132becc5443df14dd3f4feaee56d14b885c078649727b9659139fa6"},{"up":true,"other":"9bdacc256acef0433805477d38f32be849a8846d88cb883b19d290454639b42c6ab6c5c52d4f83453e8a156af7d85f606458aa9c0977c67282f56f34ff0acbfb","one":"e0f13606a7f35b9ad8a9c4e70336c4c554ac718720a451a349eb4e1a4b055079483cac040ec64e0ed3d8bdb336618a5ae6ef74e31642fae4d7ed9949858eb361"},{"one":"ef7157fdfe62390d8a6d4ef976478d17465b42b63fddb03664973d63efb62318a8f59e412150528a32aa2c028b9de6bc67f05e012b8c43d710032ad871bc27e5","other":"5114329db828f9568ccb0d7643a10e273aa626177910f55e22a53abf1ce8ec75b95465c983446b20eac0ff9c59c5dc53eca95b24aabcc8dd110e397cd2934047","up":true},{"other":"865dbf61d8511603fe0d9ebfb10792b9f6b798187c0909039bd9b2492c41e428876f386beeac86d0dea871f4fc24ba435f0fbd9a11e74c044024934592af14ee","up":true,"one":"dd6acfd151220f21b03701ca554a5e134dbd1154dda21d9eec45809e7858fe83eca3953fc688f499030198f22052c3681a9f49207ef9b11a760456ab9637352b"},{"other":"e323da6ae861cb092543992b8985639f9b3bcaf1c3c68757f4603a67800be62950fe7d8f8ef80eb83a18107b677c7f5047ea89a5790e0ea2a7969f4856d28488","up":true,"one":"bc0df855bdadcde3e447415444f655eb430925a8fa81cdcac75909e7d79750f01827938570e75e388cc7058ba8ebca47afadf8b07172bc078488fb618ba71024"},{"one":"877d17ec7e95998ead831606d3363fbff1c8d1fa377b8e621e6a876d2c7776b9af356211a7e4df66adeaf38cf9b49c04871e8804edde4c18435ff45e110ecb04","other":"243164c4dd583f80c50813f43e5c27c894463400cd3afd776b36e79e7123d9261f01f06f92914aab83096b9a43fb655e79687590599284640a3a7d2c25454597","up":true},{"up":true,"other":"ee3471e1d835c4294f7ba642103039ccc548fe4edc177c79b63433ebbb0dc9d06600844f1fed76c7096ee9538e49e4e86fb8cffe9095dbdcde27695ff28ad395","one":"876618c8ba66c1b91b473a154be3e10ded3590ba83d620d30e0ff1fbac2f31f258b1299a3da5b56aa03269a80c119b7fc41dfd87d5bd996359e4ad8dd0ab2a6a"},{"up":true,"other":"02fdbcb00f20a3f6e894900d798fcb0aca9e21f5b107924c0999eb396220f16dee99fc80ccba796e66e69dcb9ce278b7e0e4539c7a7cd0fbc1037bf8e56c1e67","one":"81dc656de121016bcde81d5bf7919839acfc180dfbf1a6de2cadf704ff13af98aa5715a4168832ca6f651b2ea7ad9e6ca5f1c1cb7e885dbc2eb23d4aefb87bd6"},{"other":"b58b3e200f6072ddb38130944a01d2829c755b8bd1a08abd010d1bbf86dabd851b2c1ab4cb961451bd7e8499f6c7378830bcd27cde825846654853c172597bf3","up":true,"one":"e5cb29b25debcfaaacc0b04e708c8c1cb9d2dee29e82596a1c72a934032cf738800b9525cc277d0c5f5dacf2f278329b54da161b4bafa285243fa0e9fd7b2f3a"},{"up":true,"other":"002cb6ffa63ad71ee6ebc1df4c41f7a97c51f274b1d3b22420c87b73136be5169b9670508061d8261e20055fefce3b855388994672aa9a0f1475c43839aae4fa","one":"eb6d41d8d96f1933dff017d5fa0c46c6d0bad5d273b7c321a12858ac90ec00fca6191d29419897d2e25ec2d8ebd8c6a81bbde2d3f266f842e64b2b822161f1ea"},{"up":true,"other":"b8e0a56df21baae43058f575b714ae9a33c097d18f1a628b3b6ae5e86dd46a06e44c0dc272baacb5be0f7bf57fd6ddce107544eb3b94dca1aeae9f5773496a72","one":"ee0b09ee6a1057c47102e582e2fdec7b9212802e59f062a9360da0db535d4987126ab24848c0d76fa8485431a5140307e2b0c0d9f37cbdb35756e6cc1bdb3bc0"},{"one":"865dbf61d8511603fe0d9ebfb10792b9f6b798187c0909039bd9b2492c41e428876f386beeac86d0dea871f4fc24ba435f0fbd9a11e74c044024934592af14ee","up":true,"other":"ea2921612b827e3c26328368bed9be7cbf1f2b2aecaf31863c9cdccd74c56b651d6eaceb8ac9609a6653488837ded310df91e53a74789ae75cb841e2aeaf96df"},{"one":"81901d9f043b4b1649ade3b5d22ae5f8bb42dd6db1eb37b836b99dd1c0388509ed4b54cc5638c9d4a6c5ae6c6913bbfffb303d7d94bf4ed50e871cf95459e2c3","up":true,"other":"d09104c44648391693ca64a57baa5ef54ed717e19c65ad0a0921d08cbaca8877d0190795d15f75f3b6ce6e676d6b0e55d5ee8fec3310c68b7060a32f7ff649cb"},{"one":"682288e4dae2374c4784acd0b285508920ce39a6b72cc0e30a3dbb7972e0394a2bddd5ee5f22a1dbf80f284dde4d9f8ede7847318d5353566b35a83e212477e7","other":"51a570637394e9ab61fe95b3a608cc4e9dc8ceb63efe717938ccd4260a962d52e01b30e7034fbfdabd9a3c9616ee569550b38a6d6b4b19847f523254069a9f27","up":true},{"other":"df9306a263f40e0e255996500523354de3cc78b68ae560f66d79f6ea28f30f773f1fd6ebc33928723dfde2ee3d4f982b203bee4c3803a5050df83477045bb279","up":true,"one":"510536aba28aa635d8a1098a6dbd2070748ce1eb0e14b54b93a21196543a60df546ff6a2b3b5b9f32a5c2a37f5aba77d0b74f28b2dabeeebf3fe5afc20a3209c"},{"one":"e0875ed6be1e163b15c13cdf37442f838670d0949349ee9ff119a0451beffb1a302943ee9d7cba48592922f64908aeb0f39f6e2e3725d1e7cdc5db34083b6977","other":"51a570637394e9ab61fe95b3a608cc4e9dc8ceb63efe717938ccd4260a962d52e01b30e7034fbfdabd9a3c9616ee569550b38a6d6b4b19847f523254069a9f27","up":true},{"other":"212a8048ab9925171475e81dce047865df186222d673d524c810a9f613e4a21f3b130fa34c5f44974fbeaab1f6028177e71568e00a1184d9fd05443c172f5fcf","up":true,"one":"b9c7b885430b9b1a4425bde30b3629559f5437e0e30a0299fc6f6e097cbcca8af9e285caf5dea685a0237f60e06f490c39a1e3e487f14a2b9f41a5135f2ba994"},{"other":"e1f23e1caba66f5ff821edbc4a3d527539937f73d86dd0df43aa1266a99f51f2480a77961eff177fbbf852fc52cb9317179f80b1580194daaedadc3b00510751","up":true,"one":"85b6404a76b4762156c8ddd2f312763dfe19b315d914533844cf229301880c57ffeadc0eb5f4a8d542e1d9fc961dfb5a572d2101172b1a0fc238ced05ba49ec1"},{"other":"9d372d73848389cfa1676f0cdb030950980ed5b68d5b2ef8a058f1d2095b26ff0fafab5fd3c243296ee2620edc67752970ab47370270856287f8612d1b190a19","up":true,"one":"154d5ddb15ec12dc65362039d801383c189b5bcf6688883f2d7e3d0e8dc78e45f9f58d5dabc79a8798a243ce59abb95c77525db14f050fd8cb37d04b7276557c"},{"up":true,"other":"33e9d4674b5b9b23e838583f01b429abca1330393dfc100b19ede6090a53df213011fae53169a66aa05d18e4cb497a17aa81eaedf1fe2e4348f9825c309438b5","one":"740919ebae9b4fe646ca716ebb8923bf2a1b1963767d86f55ea95911d88d163cc2e07b1420669e64b62cb267b625413444b783b8e4a7bd6a0f481f4d84e984b1"},{"one":"a070b5cff5eff533a2267ceb0d88e221088038af773e18f80110c8a2c329f0543b8d43c4e6132e9416723e3e94c87f0053456760ced4426767b95cee36ed93f8","other":"aa2028d356a88eca8e0fcaf218d62ace099c3f72dfd95bb28f30ac9a926034cf1d60a40511f7495652745de80d71c0f6830019e206c88e2b6ef0cf4f05d7fe9e","up":true},{"one":"740919ebae9b4fe646ca716ebb8923bf2a1b1963767d86f55ea95911d88d163cc2e07b1420669e64b62cb267b625413444b783b8e4a7bd6a0f481f4d84e984b1","other":"f60755ee9464c7db769bb7237016fa165441d18ac3bfed7cd2a220a9bcbead202dd34eaf2f9398a3d36bdfc2671bbd46ac25ebe264a8118afe1b7d0bd38710f4","up":true},{"one":"f056acbdf491d1bb091937335c10096ea44b7034e994d134bc16d55212ff049bb097424de96c615ea699359a7ef77b3b54def2b3a5f43d735ffda65f73d61f7f","up":true,"other":"15ceb62ee0f53379aa202950634ed881ba3b7bd4b46c80723ee48190079311e24ffaacb167a126a40bd6732c384f3c26163aa043edca03cb52a97b6da189aec7"},{"other":"876618c8ba66c1b91b473a154be3e10ded3590ba83d620d30e0ff1fbac2f31f258b1299a3da5b56aa03269a80c119b7fc41dfd87d5bd996359e4ad8dd0ab2a6a","up":true,"one":"f056acbdf491d1bb091937335c10096ea44b7034e994d134bc16d55212ff049bb097424de96c615ea699359a7ef77b3b54def2b3a5f43d735ffda65f73d61f7f"},{"up":true,"other":"6b082a09e343a160b60a01f74641c1d707b2fa8fee5f6f5a8b9e4a203bd86434227d2df982b246a752f843483cdf517e85fe3bd65453354232a6eb38dedbf314","one":"3b71a324bd7b1a8fb19d8206eea1ca8190cb1faf5fcd1bfc52cef6b52296fe1db3e54d70180133fad1fa1188499d0dd73d2d075fdc6b3ffd9042d690e7d88e02"},{"one":"7dd2801259c071a6e1dcc01d1cb74775fdec92da1da0b1eaf5f893cd5ed118894493ca5284c12bbd6cf7959449bc610d26ac6c9ef2845d1645d425f56ac003fd","up":true,"other":"d7e3661c0af6754c875217f93d34b254f1f45fc1359a4c6146cd0efa4c6e12aed9a4fb0a21a136f73af4fc2c6d0a63cb809d81855bbc9f51e29d23d90f77b326"},{"one":"90b8e73916046b5433dce049bfe125ca2bf2fb390ff7301f9bc5d8d0183988577aa2a7392aaa28091aa81c8ac23942b5751420b9ee48e488a68411f9d2b1e5d5","up":true,"other":"af9b80f6836113aeda897d6903e9ffb4f7f1a706a7f821d0d40f03a0d83c18d6a19795ee4bfc1093ada04014415b1f230db1d2f056df3f5027cce71611588046"},{"up":true,"other":"8e65496318637446a51f0dc87d0a5cf82655866cd1579db1e381af52e12545172b9c88119999ccac3b8b8644efc9675ff183ebe7584c16eb40792cc21f7e9b76","one":"c0164fb4a1acfb4f3b1a09f9f3ab226c382529a73891937c6f3c91798098cf10b909eb92e5f8acfe0e8f3aee0b71cb23ee2d9e6ad1e0f4492a0272c52d529849"},{"one":"bdd17545242bedba1e4c36fadea95db655f8f220f10ae143084690a3c8d4e7ffb79a64af9f1bc8514addbd63695b2f20857e8d162f25318faac885f77b385138","other":"a48cd04cdc66e1bb182529a789e1417d60d5e7d0f73068c1b17c6f231defeb943357789123e8d89cad90d1dd1726c48b808300d213bc1ddf7ae43cd58527f1f3","up":true},{"one":"97b1eaf8274ece76d75e7f60126f1b351ed5fe55088b9fcbb825a3a8d8f84f61bc72469916b280497dabf01345057525cae89da73c9a1a8a8cd19367d44dede1","other":"e993be8034861aebc9bbd11115f25d9c719d43fcdefc323599616cc26240cee38dfc27bb7f339149a54a3c9ad13b2d6ca4f0ae690e4355605eda6b789c4a431e","up":true},{"other":"9e21f5d4cfb389ac3ad43497689878bd245a89c587a8637d832b1e355ba244f4c83e6499bc7936e6d35645db25910ecd89b9af9b6b2f0c7cc4d7c6114328d7bf","up":true,"one":"2bea7540c99456ea889a8ba2e448c11e6257bf987d01f13eea48128ba58577ab0936855035ee140c9907e382a34ca85a179c74892cbd9eb92fc2b35601addc6b"},{"one":"bdd17545242bedba1e4c36fadea95db655f8f220f10ae143084690a3c8d4e7ffb79a64af9f1bc8514addbd63695b2f20857e8d162f25318faac885f77b385138","up":true,"other":"8e65496318637446a51f0dc87d0a5cf82655866cd1579db1e381af52e12545172b9c88119999ccac3b8b8644efc9675ff183ebe7584c16eb40792cc21f7e9b76"},{"up":true,"other":"52cf04f88d8b00214f11f329ebacca69291958372aa8ccfbe3cfdbc03d51d90389f3c307b82c108f0c074d78aeac0b48e8b8c8f3bf3b20b21d9747f284075de2","one":"c0164fb4a1acfb4f3b1a09f9f3ab226c382529a73891937c6f3c91798098cf10b909eb92e5f8acfe0e8f3aee0b71cb23ee2d9e6ad1e0f4492a0272c52d529849"},{"up":true,"other":"ecb93d8eba17afe92979e8154252a08dd58de6ff3188b6829e3e25967846686f54199ab2b081e77b0048dcab204f05aa2c5cbd0efae4bc43a612d471d4e1197b","one":"7dd2801259c071a6e1dcc01d1cb74775fdec92da1da0b1eaf5f893cd5ed118894493ca5284c12bbd6cf7959449bc610d26ac6c9ef2845d1645d425f56ac003fd"},{"one":"90b8e73916046b5433dce049bfe125ca2bf2fb390ff7301f9bc5d8d0183988577aa2a7392aaa28091aa81c8ac23942b5751420b9ee48e488a68411f9d2b1e5d5","other":"3e7aef8260c0d9717aa59b65ce7c554e53b81f19f5b9400321704a7ddf5041b0fe31b5634e90b93e6984060defee0e153997bbfe196166cc8d83165fd5eaf41f","up":true},{"other":"643da2591098f9698f27cccf7c17832e0717ee6a1276398a1a29edc947125585dcfab9417c2721a8a55d4dfc75b826be7581b6e30b020f6341ac549877c9f122","up":true,"one":"97b1eaf8274ece76d75e7f60126f1b351ed5fe55088b9fcbb825a3a8d8f84f61bc72469916b280497dabf01345057525cae89da73c9a1a8a8cd19367d44dede1"},{"one":"aa2028d356a88eca8e0fcaf218d62ace099c3f72dfd95bb28f30ac9a926034cf1d60a40511f7495652745de80d71c0f6830019e206c88e2b6ef0cf4f05d7fe9e","up":true,"other":"c61ffc88f23f9f536497cc10ffcb7000ec6c4b801998ae7075ddc9079fdc1da8350e68744dc9e95ff892dfc5e52c62a3ad913a87fdacc455aea99b09aa002b57"},{"up":true,"other":"76643f67075c6e45bd176db19473240cda6f886d1cac25330e2d99c84a429934f4c6a606c9c72574d5eaccd0a3f1770dab05e6ff6a5b5ce4d7258fed2bc13d48","one":"bdd17545242bedba1e4c36fadea95db655f8f220f10ae143084690a3c8d4e7ffb79a64af9f1bc8514addbd63695b2f20857e8d162f25318faac885f77b385138"},{"one":"c0a2c08fa8b70ecbf1932254945d5f689b0da7a287019d384152f383f6229acd4d82eef26205bc12e062dae4569814bd1c996ee4fe5886bd6bdd93c4f0ac113a","up":true,"other":"624248a794fd62248024360f128b2e503c752340694a316bed420e5ed2cebeb5bf970df95a2806732237a26de3778222b0454e2e7d2875129b193e7890fd5b95"},{"one":"535287ca3d41fc1cdf20a964749a849c51d0aba285f41f447cc2b1dd6f5845b6b98e0241dbda0718b234ea850081bfbf9df01d1aa636d7dcbd99ef3c0a773aff","up":true,"other":"207764262a208c17db61fda4208d4664bf74010e0ad051a863e131e748c9304e11ccf007c925488ea86b974ee61cdac3dca4d4b3f4043524e03c194ab3c8eb5a"},{"one":"f056acbdf491d1bb091937335c10096ea44b7034e994d134bc16d55212ff049bb097424de96c615ea699359a7ef77b3b54def2b3a5f43d735ffda65f73d61f7f","up":true,"other":"5a6318af8b4615cf30610a05ade7704182fefd0a3fb3d76c47cb392e114d8d30004f0ec214326b11532fd1e928e66f632bbcde126a94c87774063853a9518dc5"},{"one":"6c2788dec7ae7a77134065afc1174bb92b87833e87acaa72fe9e62c92d2017f217f9fbc5884cdfb7236a7bb75e463e49ecceb1641a8629516211d9699587046e","other":"1cdef98d7b4de45c902c725384bd14c66084fe4159b26a0f9a24f432e1f561d035ca41e1c60fe64f3213b4f91a1afb953193dca1a7d535be0602b5d046bcbab8","up":true},{"other":"9309549fc50173d6826fe63cf18699f49199c3789616b843042fe1a6adab6ed4bdd7a7a06acd276e0398cf8bffb26c12a4227725d7bbd386a9a55fc601c21405","up":true,"one":"76643f67075c6e45bd176db19473240cda6f886d1cac25330e2d99c84a429934f4c6a606c9c72574d5eaccd0a3f1770dab05e6ff6a5b5ce4d7258fed2bc13d48"},{"up":true,"other":"c402495c2110a6531a530ebdcd9ab1b883f1c707fe25aa13a255a0a9edb4113669b4aee9eadf803f9fe4c2ef66d5e4dff7064549f672598410f2d9794747a600","one":"535287ca3d41fc1cdf20a964749a849c51d0aba285f41f447cc2b1dd6f5845b6b98e0241dbda0718b234ea850081bfbf9df01d1aa636d7dcbd99ef3c0a773aff"},{"one":"ecd217e8bdb53c9ef085929b8c2d2b40425a4be617a087b8e7f88e8507b3c981e90fda2119744ca394fe65bd4eb1cdd3fa7258db936048e236d2f15ee91bc3b6","up":true,"other":"877d17ec7e95998ead831606d3363fbff1c8d1fa377b8e621e6a876d2c7776b9af356211a7e4df66adeaf38cf9b49c04871e8804edde4c18435ff45e110ecb04"},{"other":"5982e7dfd39c527851f6ea6430b70e654d95df5ec4401ca1d8dbd1034cf7a65d1126d60b36ebbd396c9ca32e6e8515f34f9dc0a8d2980afe4aa181c8bf68437e","up":true,"one":"8fb6838337f832445531764ddafc3c747b2607f2f33e244685d6de621c2b53264270f5504187e43b7fa5cda53e66dd00b16c06879c82fb38a3d9e8aec4060210"},{"up":true,"other":"682288e4dae2374c4784acd0b285508920ce39a6b72cc0e30a3dbb7972e0394a2bddd5ee5f22a1dbf80f284dde4d9f8ede7847318d5353566b35a83e212477e7","one":"6b082a09e343a160b60a01f74641c1d707b2fa8fee5f6f5a8b9e4a203bd86434227d2df982b246a752f843483cdf517e85fe3bd65453354232a6eb38dedbf314"},{"one":"2b0a1f3a6466c6be1d7e84120db384fa37f7c73a01e9a105ae90e7d2203212ec974f016d3012afd26bc0f9a8411d0716cc59b6ecc9f665db12e306af8b34cb63","up":true,"other":"e1f23e1caba66f5ff821edbc4a3d527539937f73d86dd0df43aa1266a99f51f2480a77961eff177fbbf852fc52cb9317179f80b1580194daaedadc3b00510751"},{"other":"77e40e42f570a217f707888c714deb31fd70c856ae4b9a44ec7cee02768185dc4d7ed210429607f06690b32edd9fb06b304aff330a3949cc2fd49db1bc392edb","up":true,"one":"869ca41ea1f82bec5f43807a3aaaabc39b21c62d3c9c8bdc0709683e22dd37cb2f3c313766809076d2c02d0d6171f4f32a1b5080abcb8072d88981042ae6237d"},{"up":true,"other":"dd6acfd151220f21b03701ca554a5e134dbd1154dda21d9eec45809e7858fe83eca3953fc688f499030198f22052c3681a9f49207ef9b11a760456ab9637352b","one":"4116fbb7d55bfd4bd8db9cbfa570ac361bb88605b6aacbf84e245893cf3fa599ecc086688a4c534c81f61a90fa344ca37e4d4013ddc03f7f08218724a55f66b1"},{"one":"60995852a2385ce8d7d24dc94b85a2f0dab6e5c32e910dfe367ea9c6ccb7b0b2eb611fdf120f8c697097e2f137cefff42e8d9db16b664a857a38c5ace837ffa4","other":"1edeb91789b9aa996fea7a70964e0be33ee50acbe6d8f7d9d9fcf6dcf755dab6402637a610116f0eb716b19259429bdcced8bebc28ffa334387a430efc21b9b0","up":true},{"up":true,"other":"6c95c653e15bb99d32656f35790400134cd7188e063f878e19cb9118eb469ae0362dc45255f2a1eae31520be01d42b5bc5bbebf03d644c9f206ca79cb33a01ad","one":"10551c0c37abc25457903978868dd4843a52fda5f9b571b05ebd974d8c381fda4349f17c2b986a2e4b8d06b0517422f085d5f6d9cd814efa40e48393d9f71d7e"},{"up":true,"other":"baa28b8cb7ec539e0e157d7598cc5a5b0210fd8fb5c9026c3cd612133c5a8ee56997507511928af5683cb620fd85593dd8f6ff882d95fb847870ae4ce7dc503b","one":"202ae63076a5560418023f00c9965b2a1d12de932b5371ae270d63db88551a7aa1a3c48841f81948fad3435bb4a7e3e165a2eced9fd937444e4502471e23dae8"},{"up":true,"other":"8e65496318637446a51f0dc87d0a5cf82655866cd1579db1e381af52e12545172b9c88119999ccac3b8b8644efc9675ff183ebe7584c16eb40792cc21f7e9b76","one":"76643f67075c6e45bd176db19473240cda6f886d1cac25330e2d99c84a429934f4c6a606c9c72574d5eaccd0a3f1770dab05e6ff6a5b5ce4d7258fed2bc13d48"},{"one":"10551c0c37abc25457903978868dd4843a52fda5f9b571b05ebd974d8c381fda4349f17c2b986a2e4b8d06b0517422f085d5f6d9cd814efa40e48393d9f71d7e","other":"2abb91884cc3a8fb91b2f2f369f9430f2b3b05c75ce6203aa7a50312c9f141f9d0f615063d3576a5ce8a4be9ecb942aa804a717f76d9e8dca03d115dcc43f775","up":true},{"other":"c0a2c08fa8b70ecbf1932254945d5f689b0da7a287019d384152f383f6229acd4d82eef26205bc12e062dae4569814bd1c996ee4fe5886bd6bdd93c4f0ac113a","up":true,"one":"8ec699020ab5e7719fe23b80268b5d1d37052bb71f5d81200ae805cf27825823733206165f0a7507c2595853361dd122e9ec1b2deb543591e22b71ec0b873b5b"},{"other":"9ea856ea440c776b9ffaad1237ec11d570a1f912a908b8363ff97cf7947d2523e3c73663240d8fac988698cdd81e877ddd4a609485fe9f26494136fae14212df","up":true,"one":"5a6318af8b4615cf30610a05ade7704182fefd0a3fb3d76c47cb392e114d8d30004f0ec214326b11532fd1e928e66f632bbcde126a94c87774063853a9518dc5"},{"other":"535287ca3d41fc1cdf20a964749a849c51d0aba285f41f447cc2b1dd6f5845b6b98e0241dbda0718b234ea850081bfbf9df01d1aa636d7dcbd99ef3c0a773aff","up":true,"one":"5717a49591a0ecdff3d4449874d5ff9ba016afad5da19712ca0c8ebca8cefd84e6d8c778245f67f68c8dd730ad294fd017b8de279fde4fc919768ce85dba132d"},{"one":"8ee65c0937cdf860d5329132c34bf28b5dc4d2593986fae80e4b35efb54ec24cdbf294223515363a917a22dbc6db463c10c7484e22b479b9010059c2521b6317","other":"e1f23e1caba66f5ff821edbc4a3d527539937f73d86dd0df43aa1266a99f51f2480a77961eff177fbbf852fc52cb9317179f80b1580194daaedadc3b00510751","up":true},{"one":"bac3fd2ea491d8e4ce1e5d469ec73f3d537d61279ae66e7a394b20a188244a886d3059ef0d304c0801878f9640374f7c8aaf56558c41f12296d3fc7f911ed66c","up":true,"other":"624248a794fd62248024360f128b2e503c752340694a316bed420e5ed2cebeb5bf970df95a2806732237a26de3778222b0454e2e7d2875129b193e7890fd5b95"},{"up":true,"other":"e1f23e1caba66f5ff821edbc4a3d527539937f73d86dd0df43aa1266a99f51f2480a77961eff177fbbf852fc52cb9317179f80b1580194daaedadc3b00510751","one":"a48cd04cdc66e1bb182529a789e1417d60d5e7d0f73068c1b17c6f231defeb943357789123e8d89cad90d1dd1726c48b808300d213bc1ddf7ae43cd58527f1f3"},{"one":"5717a49591a0ecdff3d4449874d5ff9ba016afad5da19712ca0c8ebca8cefd84e6d8c778245f67f68c8dd730ad294fd017b8de279fde4fc919768ce85dba132d","up":true,"other":"c2a9c77247871cfa4d3c2d1b47619df91ed5b331a44c8e21f7c9ce431a4db9dfb87713558cc8a37911393907b4cc60be9445bad18adcea1bc5f318256e71be14"},{"one":"90b8e73916046b5433dce049bfe125ca2bf2fb390ff7301f9bc5d8d0183988577aa2a7392aaa28091aa81c8ac23942b5751420b9ee48e488a68411f9d2b1e5d5","other":"6b104eff1dcf58d11a7f707bbd41a910b2735b262c29e0f4e4127fda1b67def4e89b6ebc1b3cc1e06c3968d0898e1085badc7da24d3cd6624cb100e85863cc97","up":true},{"up":true,"other":"33e9d4674b5b9b23e838583f01b429abca1330393dfc100b19ede6090a53df213011fae53169a66aa05d18e4cb497a17aa81eaedf1fe2e4348f9825c309438b5","one":"b3b4b203395bb6655d79ecdcee11638dd9a16baccfcc1f6fcc8b31832c8ca35650eb6c2802104eeec6d96ea80404381a2bd9b01dcadc748a4666b761d9ce64f8"},{"one":"3a2cacc430f13f31c52b7205455420cf0fb9ed9e28b0898b69ef97951bf295b29118e573a42dd97abe38fee5ab4c03dad9ff6dc448126cefc1da12b6c8e8d915","up":true,"other":"588df3185f63a5443d8c6b972f67805f0557184d916005f537a4b27cd02bd6a12e432a2b34b234a34f22e923c6f116da85be20bad77a2bf69913684e9d0732ba"},{"one":"8ec699020ab5e7719fe23b80268b5d1d37052bb71f5d81200ae805cf27825823733206165f0a7507c2595853361dd122e9ec1b2deb543591e22b71ec0b873b5b","other":"29619924833116cb1160bf7a8066a528b7182794368bfae62b5bacbae680d9161a479f217e30c3b4f19a250b1b59e08f86c94726117dc3bc94ff9ceac6bee6e4","up":true},{"up":true,"other":"f6a12b23423c047927a3024a6dba7ce88927cb21d4df3778bc5ebb262cc403261c79ba6d9bda07f1852c009d803a77f429e9e48ec1d63cae98256e529d45b276","one":"6c2788dec7ae7a77134065afc1174bb92b87833e87acaa72fe9e62c92d2017f217f9fbc5884cdfb7236a7bb75e463e49ecceb1641a8629516211d9699587046e"},{"up":true,"other":"ecb93d8eba17afe92979e8154252a08dd58de6ff3188b6829e3e25967846686f54199ab2b081e77b0048dcab204f05aa2c5cbd0efae4bc43a612d471d4e1197b","one":"3639f964feba681db9702cac3f02058f2e490fd7bffb217dc3480dc458decafd5955541fea89f0f6f14ee50a745eaf98b21363d6b4fb88c31bd32bf7845d524b"},{"up":true,"other":"9c8fca41b833e88110559b9258653160f5fb236bd637272ac58fe1adf333f4df75b94a805eaebb9f10a8c1a26d357dd75140560551d3fc4da79da2c4fc9479c3","one":"bdd17545242bedba1e4c36fadea95db655f8f220f10ae143084690a3c8d4e7ffb79a64af9f1bc8514addbd63695b2f20857e8d162f25318faac885f77b385138"},{"one":"8c459100df488b992fdad207a096a434d67cb733619adfd09a311095568d4c9db293d9a892675551805559456d49a3fdb19c2cc698b14552bf0ace584d4d90dc","other":"b3b4b203395bb6655d79ecdcee11638dd9a16baccfcc1f6fcc8b31832c8ca35650eb6c2802104eeec6d96ea80404381a2bd9b01dcadc748a4666b761d9ce64f8","up":true},{"up":true,"other":"6909a0fa47718cfc463b1e96c21734b46bd5b28dd59cd3d66d67990783436b7538ab2659d427029b97c8dddf313b26532518c0c34a2b1fca8cd852b0fdb83ab8","one":"49256eccce3e036928a4b6b346126c6777dca5ea0134de85efca340f97ad0f827f3094f1562e3e186d35b8292a50c20ffae01409890bbb78598494285e14dc2c"},{"one":"52cf04f88d8b00214f11f329ebacca69291958372aa8ccfbe3cfdbc03d51d90389f3c307b82c108f0c074d78aeac0b48e8b8c8f3bf3b20b21d9747f284075de2","up":true,"other":"e1f23e1caba66f5ff821edbc4a3d527539937f73d86dd0df43aa1266a99f51f2480a77961eff177fbbf852fc52cb9317179f80b1580194daaedadc3b00510751"},{"other":"a8fac88fba179fb9b259d94caac9cbe45d873a0131bef8844ac4383b177daf6f301f8793623fec5876885db1a91e5b3e98e2aafdaa47e03b1f6d9740f48af7ac","up":true,"one":"e0a043f98b462f10f72aa61ceda52f9c27829d086f6f2c5bf4db4fe32759002e5ff9519495d57dbb83d963a1dc991a1defcf5b9ef0d543789f38c68f5d07122b"},{"up":true,"other":"1b3107d9a96cfd11f4cd0ed8baeb7b23db1406c9c4a9dac76c772f49c0fc9404f6a4adae11120aa821757173f0cc1cb00e6ab555b5abffaae9001c0557cb75c9","one":"1489ad735e1256900e4733707f8b78f1d853742a8f9b2d0c1c89651c60e7ee9d266afba5b4c1ed3f9cee05a1d2b2bba35dadb5b08973a93fd70dfb9e367339bd"},{"one":"5717a49591a0ecdff3d4449874d5ff9ba016afad5da19712ca0c8ebca8cefd84e6d8c778245f67f68c8dd730ad294fd017b8de279fde4fc919768ce85dba132d","up":true,"other":"aa2028d356a88eca8e0fcaf218d62ace099c3f72dfd95bb28f30ac9a926034cf1d60a40511f7495652745de80d71c0f6830019e206c88e2b6ef0cf4f05d7fe9e"},{"one":"740919ebae9b4fe646ca716ebb8923bf2a1b1963767d86f55ea95911d88d163cc2e07b1420669e64b62cb267b625413444b783b8e4a7bd6a0f481f4d84e984b1","up":true,"other":"da22fb43c6d230d92f9c09454e282dc45dffc759740566039f1bdfb58171c6801f721841de83217277b3fb70983e7d34da53bbf25d1d45413a78d9afff151826"},{"one":"9bea5f82c2a390587de44d620d6637834e6f2329cd83d8df6305b03b75d9b543160b6c6f9f8887e6bc88f1d0726435d6c8ad813aadad0653b0790b8f6388413a","up":true,"other":"5717a49591a0ecdff3d4449874d5ff9ba016afad5da19712ca0c8ebca8cefd84e6d8c778245f67f68c8dd730ad294fd017b8de279fde4fc919768ce85dba132d"},{"other":"c0a2c08fa8b70ecbf1932254945d5f689b0da7a287019d384152f383f6229acd4d82eef26205bc12e062dae4569814bd1c996ee4fe5886bd6bdd93c4f0ac113a","up":true,"one":"bac3fd2ea491d8e4ce1e5d469ec73f3d537d61279ae66e7a394b20a188244a886d3059ef0d304c0801878f9640374f7c8aaf56558c41f12296d3fc7f911ed66c"},{"one":"8c459100df488b992fdad207a096a434d67cb733619adfd09a311095568d4c9db293d9a892675551805559456d49a3fdb19c2cc698b14552bf0ace584d4d90dc","other":"33e9d4674b5b9b23e838583f01b429abca1330393dfc100b19ede6090a53df213011fae53169a66aa05d18e4cb497a17aa81eaedf1fe2e4348f9825c309438b5","up":true},{"one":"c6f38fe8a0f2b3773bae332e0ca7516e944bde186fe99daae10a2b0aecde3ce23c1834eaad97a4e6d2da8cd53a08dbafa72d2b827c851b115b74e8010125dba2","other":"8f3e9102306a13adb91e01f7a847e7880054f1a7df8976d05facb3a8fb37d47cce04f25e18a19713e5c3da7541e96e829fc67c8b924b717d2d9586c9c12d4fcf","up":true},{"up":true,"other":"b87e7f36ed6bf142d48545024d2fd6e120c44511701e7c0b7d7fc786f4f29d3357024b15f70b78215d8a4c2b7572d608c11b31612743e23db4fa673f0cd6519b","one":"6b082a09e343a160b60a01f74641c1d707b2fa8fee5f6f5a8b9e4a203bd86434227d2df982b246a752f843483cdf517e85fe3bd65453354232a6eb38dedbf314"},{"one":"c0164fb4a1acfb4f3b1a09f9f3ab226c382529a73891937c6f3c91798098cf10b909eb92e5f8acfe0e8f3aee0b71cb23ee2d9e6ad1e0f4492a0272c52d529849","up":true,"other":"9c8fca41b833e88110559b9258653160f5fb236bd637272ac58fe1adf333f4df75b94a805eaebb9f10a8c1a26d357dd75140560551d3fc4da79da2c4fc9479c3"},{"other":"c29e80096fbe7bc9fcbfdbe3cf6c06449192a3ed280e46a1fa5d424428d893c3456c985c1352c119236cf783834365439751cc87e7ed196614705dd3db6674cf","up":true,"one":"97b1eaf8274ece76d75e7f60126f1b351ed5fe55088b9fcbb825a3a8d8f84f61bc72469916b280497dabf01345057525cae89da73c9a1a8a8cd19367d44dede1"},{"one":"4116fbb7d55bfd4bd8db9cbfa570ac361bb88605b6aacbf84e245893cf3fa599ecc086688a4c534c81f61a90fa344ca37e4d4013ddc03f7f08218724a55f66b1","up":true,"other":"f5d95e0c5a873ff5a95e1eb34f1ed258d77adf98ee0886d93c4a24b1feaf6955e6e4c4ea0eccb2b9723870bae61e693643d6ad96dd8da01672542611f7c49069"},{"up":true,"other":"9e21f5d4cfb389ac3ad43497689878bd245a89c587a8637d832b1e355ba244f4c83e6499bc7936e6d35645db25910ecd89b9af9b6b2f0c7cc4d7c6114328d7bf","one":"77e7d427b65b6c29c0d92c51184af73031bfa768a47fc20be6c264f422bf718865259c17c103bf47289b3abe62f93452781c6303d757e76d3d56ceeb26262fab"},{"one":"e903d7aebff96a6afa4b9dd19b0b02e5af18da8e4e89f64247e1a2c2d46637538c741182eac67f45ec61be76aeaccde57f0a0184bd608ea7d92e586d4f827ea7","up":true,"other":"fee3fa1ba2a051d40a582908384ee81179db6c2b5f4bfa58c24f8015b794b43a093ed68b69bb209684135f972a055a9845978fa1b7d489e2126c3b514297f1c2"},{"one":"77e7d427b65b6c29c0d92c51184af73031bfa768a47fc20be6c264f422bf718865259c17c103bf47289b3abe62f93452781c6303d757e76d3d56ceeb26262fab","other":"224c3b969149d50d1bb4f473bb9725223c1dafe152efe1b08e8859213c543a66565b5d68a99cef3d5f4eccad6282a12f78d7b38eec14deebf44ad8dd9cba8680","up":true},{"one":"212a8048ab9925171475e81dce047865df186222d673d524c810a9f613e4a21f3b130fa34c5f44974fbeaab1f6028177e71568e00a1184d9fd05443c172f5fcf","other":"3639f964feba681db9702cac3f02058f2e490fd7bffb217dc3480dc458decafd5955541fea89f0f6f14ee50a745eaf98b21363d6b4fb88c31bd32bf7845d524b","up":true},{"other":"a58a4db7a96b1578935b222c78b7b4dd8b3519d2995c3616e5a154c5175242a503097771332504638a0b321b9574110207f9a7d77b109d1de3d66a12ec6498e5","up":true,"one":"ecb93d8eba17afe92979e8154252a08dd58de6ff3188b6829e3e25967846686f54199ab2b081e77b0048dcab204f05aa2c5cbd0efae4bc43a612d471d4e1197b"},{"one":"fee3fa1ba2a051d40a582908384ee81179db6c2b5f4bfa58c24f8015b794b43a093ed68b69bb209684135f972a055a9845978fa1b7d489e2126c3b514297f1c2","other":"8fb6838337f832445531764ddafc3c747b2607f2f33e244685d6de621c2b53264270f5504187e43b7fa5cda53e66dd00b16c06879c82fb38a3d9e8aec4060210","up":true},{"one":"e0875ed6be1e163b15c13cdf37442f838670d0949349ee9ff119a0451beffb1a302943ee9d7cba48592922f64908aeb0f39f6e2e3725d1e7cdc5db34083b6977","other":"24047e1a816cbf9b7a90e6c78dc896a3b624047ef5cfd3aa495132d57b1074aa129ea6eff171f5cca91d0f4793a07c9672b0a55232f2415c6220e443ebd0791d","up":true},{"one":"8e89fe4b3fffea8af247d2581aa511056efbeb796058d50a341d57aa0f7ccc2192d90cfb8d18558363df798567faaddb86815e8bd671b36ca37af0651535aabf","up":true,"other":"e0a043f98b462f10f72aa61ceda52f9c27829d086f6f2c5bf4db4fe32759002e5ff9519495d57dbb83d963a1dc991a1defcf5b9ef0d543789f38c68f5d07122b"},{"up":true,"other":"f52297fc51b920d2495ccece290432656d9388e698339c8c1279ceea45de698a4ecbda1d25928c48f1e19e9dacd3147e23ef01acc093872d7300aed187841dcc","one":"e903d7aebff96a6afa4b9dd19b0b02e5af18da8e4e89f64247e1a2c2d46637538c741182eac67f45ec61be76aeaccde57f0a0184bd608ea7d92e586d4f827ea7"},{"one":"4ff2981a47da46c753090e193a8bf43c3372a6b07a37cf0552de2ced455fbb8a76d969cd97b3e4601d8a808bd2a73f7729ed8a61df2f2a0c2cee1425d0bd9ab4","up":true,"other":"8fb6838337f832445531764ddafc3c747b2607f2f33e244685d6de621c2b53264270f5504187e43b7fa5cda53e66dd00b16c06879c82fb38a3d9e8aec4060210"},{"up":true,"other":"bdd17545242bedba1e4c36fadea95db655f8f220f10ae143084690a3c8d4e7ffb79a64af9f1bc8514addbd63695b2f20857e8d162f25318faac885f77b385138","one":"6909a0fa47718cfc463b1e96c21734b46bd5b28dd59cd3d66d67990783436b7538ab2659d427029b97c8dddf313b26532518c0c34a2b1fca8cd852b0fdb83ab8"},{"up":true,"other":"3e2241cdb9f34c1d2c6930e59940e2c4b92b0287579d7263a620a609c5e66dca6d85df48cf1bffd63663a6704c42d0866aae3e484fd9a44b6a012f72dd3cef6e","one":"93073da602d6326a48464a8b6890220b3aae0abf5b6961180f3aff2a14573c43411bd519d3e0012a646ec2977be18915d95a36d935a69f93985f5307ea4e3ebe"},{"one":"9ea856ea440c776b9ffaad1237ec11d570a1f912a908b8363ff97cf7947d2523e3c73663240d8fac988698cdd81e877ddd4a609485fe9f26494136fae14212df","other":"c0164fb4a1acfb4f3b1a09f9f3ab226c382529a73891937c6f3c91798098cf10b909eb92e5f8acfe0e8f3aee0b71cb23ee2d9e6ad1e0f4492a0272c52d529849","up":true},{"one":"884d32d09dfef937f3ef1cd6fb5f530c2c574487c0ffd4185ca405c8b2ac73044a196c34352e850ce15321eec6579da654a696381f3e5830d03c7aa18923da6e","up":true,"other":"e903d7aebff96a6afa4b9dd19b0b02e5af18da8e4e89f64247e1a2c2d46637538c741182eac67f45ec61be76aeaccde57f0a0184bd608ea7d92e586d4f827ea7"},{"one":"49256eccce3e036928a4b6b346126c6777dca5ea0134de85efca340f97ad0f827f3094f1562e3e186d35b8292a50c20ffae01409890bbb78598494285e14dc2c","up":true,"other":"b60def37233dbbc0d5f7fcddb304be1c0b6508e1e3d8a09a8290f7363e9bb84152dcaf70b8f6bb3a882fee77ff03ab796a5c1c3654f251c9f5c746ac5ad88556"},{"one":"c9d705012a06d82c4d44db95b4f1c63ddd33ad64d732e96b1d878caa0caac433d4096f01495a6f0e8a56af122b0470fd745db6d906353b590a4710472b93f5b2","other":"c2568576c2c9ef47aca0baca52709a4fa44b2ed478a062f7b161fac2bdba68568df371ac7754255fd07d79bb9918249a914946a6c318d579730bee9bc609922a","up":true},{"other":"ab13f773f6f2ff73032aa5f79c8897b75dda29bcbb14aa511e9401c2417dc9c510253071e28c7833c8d62fd2aef16fcd0c14ce016fbf4fec1b9a2173c717603f","up":true,"one":"7b4585f8a4e4904239994a1b8bdc76299da8e46a8a632fabc6c33dd4170f8f3715e4c4f526ea5dd14093b150855960e432b1b140594aca21995f9e0722fb57f1"},{"other":"877d17ec7e95998ead831606d3363fbff1c8d1fa377b8e621e6a876d2c7776b9af356211a7e4df66adeaf38cf9b49c04871e8804edde4c18435ff45e110ecb04","up":true,"one":"29acdd4c1233441bd40f98e245ecc9de94de6f9d0ab7c1a9923d833a2c8e6c1bd26d792686fec762b31fe28bbdd7aa04c9a594d997d08c133bb24cb2d877595a"},{"one":"aa90454031068598ee39af5f1429c7a72277946d50ec2004f340406dbcc9f80cac505c9d9b071f85e2ccfd4b13bcf943f3cb9dd9f96f62d41352af9d8fffe7e4","other":"e0f13606a7f35b9ad8a9c4e70336c4c554ac718720a451a349eb4e1a4b055079483cac040ec64e0ed3d8bdb336618a5ae6ef74e31642fae4d7ed9949858eb361","up":true},{"one":"b60def37233dbbc0d5f7fcddb304be1c0b6508e1e3d8a09a8290f7363e9bb84152dcaf70b8f6bb3a882fee77ff03ab796a5c1c3654f251c9f5c746ac5ad88556","up":true,"other":"57085f756f76644cdd2148524f2334d869ef0ab2fcbe7fb11f5d22bc1f5023165b11526ecc85ff9cbb88877386af9b148d7ef15a825b3a586d16c01bdfc86692"},{"one":"7b4585f8a4e4904239994a1b8bdc76299da8e46a8a632fabc6c33dd4170f8f3715e4c4f526ea5dd14093b150855960e432b1b140594aca21995f9e0722fb57f1","up":true,"other":"a25958cf192a4f62301feda5d442535f78b983dd9e4599354f4898c8c1e6ad97ca7112549e1d1a1eacb4682cd1bf8b762368b5905ab33dbdacb585b128514ca1"},{"one":"7b4585f8a4e4904239994a1b8bdc76299da8e46a8a632fabc6c33dd4170f8f3715e4c4f526ea5dd14093b150855960e432b1b140594aca21995f9e0722fb57f1","up":true,"other":"4eab70233789c544bec97040a04099494bf269a819584a5d0b42295c918a52b02f224a8ed127aba3d92c02f567356bea4b95f77230ef548dfa7fe44b643d8704"},{"one":"11e9729700f5046b47d5e4521630cb57408f59a3337ca7db7984477a16c1f3b90c1d8d1f8d6a3f2a72e35f373fa73ec47a5636b36e40b2fb83756622a08896b8","up":true,"other":"002cb6ffa63ad71ee6ebc1df4c41f7a97c51f274b1d3b22420c87b73136be5169b9670508061d8261e20055fefce3b855388994672aa9a0f1475c43839aae4fa"},{"up":true,"other":"8e89fe4b3fffea8af247d2581aa511056efbeb796058d50a341d57aa0f7ccc2192d90cfb8d18558363df798567faaddb86815e8bd671b36ca37af0651535aabf","one":"85c0b055439f114dee5eb0961013c117a48d62b0f17c61a7fd92a84092ef09bb3bbce686aa96e14528d5663565c57d657fa9813b1f38e268caeb1cb0842ef232"},{"one":"9f3af4577308965aceb7e0101443669496e7ccf1de680629862a7005966c708b6fb52e6dfe62660246b9892adc25838da2873502e0be706bcad8f25b7ceedfa5","other":"fee3fa1ba2a051d40a582908384ee81179db6c2b5f4bfa58c24f8015b794b43a093ed68b69bb209684135f972a055a9845978fa1b7d489e2126c3b514297f1c2","up":true},{"one":"c674c405068bb908312917a319e24ddf90e814ee8ef54bbf740f176b2a7eda6950e3e1ed69484ebcc27b13d82c7f0b20daba71a17700018e769ca612ca8d2208","other":"6a55b94c9990249b24cdbeed96f065137f7b79ea8ee5f58da150d3962dfb62ba401960a53e7e8bd4e2c2908aa1a59b9d5efb4aafb316a9ab4fa67a0d95b58c54","up":true},{"one":"baa28b8cb7ec539e0e157d7598cc5a5b0210fd8fb5c9026c3cd612133c5a8ee56997507511928af5683cb620fd85593dd8f6ff882d95fb847870ae4ce7dc503b","other":"5114329db828f9568ccb0d7643a10e273aa626177910f55e22a53abf1ce8ec75b95465c983446b20eac0ff9c59c5dc53eca95b24aabcc8dd110e397cd2934047","up":true},{"other":"699c923976c5b8c70c353840d3e384750f466954265f05fbb0d5877a2c0318a041dc57adc12ac6e8fbae7a00d6b6675e1a1be3a8f59dac12727ee3f8ae467a13","up":true,"one":"f98c0f4444a1ec80773454ddb691c226b81d8e2f79ed40c45a422d3359565edf7bd635d3eb7bd6c9e0870746849fb86f0b1b34cd56ec8d3ad969812e080f4983"},{"one":"723f362e98f90d7ef15e24e353759fdbdabb08adab767dba73ab546741fac3dfb457466f1e2c851aa49526da1408f8ddb509e12f7dc0bc1e785c5b72be8a986e","other":"01427ba4d1e2de0b2764515556676a6058f88c16f597780dea3d7f95a6eec9299c3987d99c199d88a0a5e695ee6f0ff7de424e4eb65e54233b956a9634133998","up":true},{"other":"01427ba4d1e2de0b2764515556676a6058f88c16f597780dea3d7f95a6eec9299c3987d99c199d88a0a5e695ee6f0ff7de424e4eb65e54233b956a9634133998","up":true,"one":"f98c0f4444a1ec80773454ddb691c226b81d8e2f79ed40c45a422d3359565edf7bd635d3eb7bd6c9e0870746849fb86f0b1b34cd56ec8d3ad969812e080f4983"},{"up":true,"other":"60995852a2385ce8d7d24dc94b85a2f0dab6e5c32e910dfe367ea9c6ccb7b0b2eb611fdf120f8c697097e2f137cefff42e8d9db16b664a857a38c5ace837ffa4","one":"c6ad9b9de5cdbe28540f4eb7c66fb37f6d4295e6e60c6de54e2a45c1970b8e0047558e986bbd10e9e86c8bb0407846fac4823e4570e8a1486fc4bf55cb4a0986"},{"other":"6a37e63feed9e68c52cb8b385d5e8d8dbd2b211c57ded0d3b01fe8b306af5c0e5a7405d0d9a942648f0131926240d53450bc43f922a053528e5830d918313c3d","up":true,"one":"7c6e6a49429a4e24aa4aa5c7ba19684f77cd67d3744688baff6e7f1d74b7e9d2df85f3e57e0df0a9b960b5bf982a610c5639c3e7a6935ba13fbc77243b2dad19"},{"other":"90b8e73916046b5433dce049bfe125ca2bf2fb390ff7301f9bc5d8d0183988577aa2a7392aaa28091aa81c8ac23942b5751420b9ee48e488a68411f9d2b1e5d5","up":true,"one":"362ed9a92b588d5fe315b90a74aa27f7600e4a7d06b27ceb26272340388d916a831df85bf83450ef80bda4e4a21acaac60560c8a42940a26e2ac567519e2a202"},{"one":"99af34b172d319633e07a4e528f416024653a230a9103a4b281171f75bb697dd6be4757558c94e86210b4da8d9fe1229f6a5d8c4174989ea0ce696f8d1a9995d","up":true,"other":"855667650e96c5ed2d9b0c82532ed1fb92f72b1ae926afafe09cf8f6e90e539aec5c4c2ab108f2c2a1ad7dd8b83ca92a98c550a1c9ed27e6632a7d2f6da4f970"},{"up":true,"other":"9d372d73848389cfa1676f0cdb030950980ed5b68d5b2ef8a058f1d2095b26ff0fafab5fd3c243296ee2620edc67752970ab47370270856287f8612d1b190a19","one":"dbb6621460b054f584f1c6157b4020f3c58d84c3a12b57436e10525ae60ab27036bf3edd68b92f2b13674877d01c2871dc67a9031c3d0470985f4b071696346e"},{"one":"e9cd25d1ef3fef22160bce7f7badd7646ac58ee40da6a438f61a067c51bc51d6087ed950ec9e909bc438ebe62e316cbd9489f3c9bfa2898615632414e04f1dcd","other":"7b4585f8a4e4904239994a1b8bdc76299da8e46a8a632fabc6c33dd4170f8f3715e4c4f526ea5dd14093b150855960e432b1b140594aca21995f9e0722fb57f1","up":true},{"one":"aa53ca208cc0c9e544fd9d52cab44b5e2887256bb006037b855b5c94d7f79c9388fdbb23c0bf1d2eee12d67125e082fa7ecb34c1129ca8eaecfd85772b009435","other":"7b4585f8a4e4904239994a1b8bdc76299da8e46a8a632fabc6c33dd4170f8f3715e4c4f526ea5dd14093b150855960e432b1b140594aca21995f9e0722fb57f1","up":true},{"up":true,"other":"1489ad735e1256900e4733707f8b78f1d853742a8f9b2d0c1c89651c60e7ee9d266afba5b4c1ed3f9cee05a1d2b2bba35dadb5b08973a93fd70dfb9e367339bd","one":"b183f12f3602bfdab0480cb0b0ba7dc69b267b0dbc7e54c316741cb78b9e99aa69fd321ad7755d095e9be14e6bd90fe14ef8fe9bafc1a0dea10a144795021a08"},{"other":"51a570637394e9ab61fe95b3a608cc4e9dc8ceb63efe717938ccd4260a962d52e01b30e7034fbfdabd9a3c9616ee569550b38a6d6b4b19847f523254069a9f27","up":true,"one":"9c8fca41b833e88110559b9258653160f5fb236bd637272ac58fe1adf333f4df75b94a805eaebb9f10a8c1a26d357dd75140560551d3fc4da79da2c4fc9479c3"},{"one":"535287ca3d41fc1cdf20a964749a849c51d0aba285f41f447cc2b1dd6f5845b6b98e0241dbda0718b234ea850081bfbf9df01d1aa636d7dcbd99ef3c0a773aff","other":"c61ffc88f23f9f536497cc10ffcb7000ec6c4b801998ae7075ddc9079fdc1da8350e68744dc9e95ff892dfc5e52c62a3ad913a87fdacc455aea99b09aa002b57","up":true},{"one":"24047e1a816cbf9b7a90e6c78dc896a3b624047ef5cfd3aa495132d57b1074aa129ea6eff171f5cca91d0f4793a07c9672b0a55232f2415c6220e443ebd0791d","other":"876618c8ba66c1b91b473a154be3e10ded3590ba83d620d30e0ff1fbac2f31f258b1299a3da5b56aa03269a80c119b7fc41dfd87d5bd996359e4ad8dd0ab2a6a","up":true},{"one":"99a7649bdf2ee7f0bc049308b0997e33abb68481c05a573df9aea30da5a1f267df07b2c584e3e985baf31704f04ad2a2c4876e0f8555333be6d09f5080b583f1","other":"4e88cc60efee147fb72a735775944c7b2ba0790e2b2b935b4b3c2da9a3158a2a7aae411e9204cdbe6b2304d90a3a8278f8bb1a800a409e8500d100d84ba1947f","up":true},{"one":"c29e80096fbe7bc9fcbfdbe3cf6c06449192a3ed280e46a1fa5d424428d893c3456c985c1352c119236cf783834365439751cc87e7ed196614705dd3db6674cf","up":true,"other":"70cce7cb0c18091dbb6d41160ab560935f1759b969bf8118cee030ee707cb15ba407b8c48dcd9fd012cbf778e219f7d16a74064b4983cf098fb118297748edb6"},{"one":"e993be8034861aebc9bbd11115f25d9c719d43fcdefc323599616cc26240cee38dfc27bb7f339149a54a3c9ad13b2d6ca4f0ae690e4355605eda6b789c4a431e","other":"da22fb43c6d230d92f9c09454e282dc45dffc759740566039f1bdfb58171c6801f721841de83217277b3fb70983e7d34da53bbf25d1d45413a78d9afff151826","up":true},{"up":true,"other":"b9c7b885430b9b1a4425bde30b3629559f5437e0e30a0299fc6f6e097cbcca8af9e285caf5dea685a0237f60e06f490c39a1e3e487f14a2b9f41a5135f2ba994","one":"d7e3661c0af6754c875217f93d34b254f1f45fc1359a4c6146cd0efa4c6e12aed9a4fb0a21a136f73af4fc2c6d0a63cb809d81855bbc9f51e29d23d90f77b326"},{"one":"7c6e6a49429a4e24aa4aa5c7ba19684f77cd67d3744688baff6e7f1d74b7e9d2df85f3e57e0df0a9b960b5bf982a610c5639c3e7a6935ba13fbc77243b2dad19","other":"33cac8f621b9122e118036154778d27dc419b6b58ea2e89b833f3932f411dbc3511d92b55ae4cf80632142bc8e67994899aaa30c499d0289fae85b12564cf01f","up":true},{"other":"9d372d73848389cfa1676f0cdb030950980ed5b68d5b2ef8a058f1d2095b26ff0fafab5fd3c243296ee2620edc67752970ab47370270856287f8612d1b190a19","up":true,"one":"33cac8f621b9122e118036154778d27dc419b6b58ea2e89b833f3932f411dbc3511d92b55ae4cf80632142bc8e67994899aaa30c499d0289fae85b12564cf01f"},{"one":"3e7aef8260c0d9717aa59b65ce7c554e53b81f19f5b9400321704a7ddf5041b0fe31b5634e90b93e6984060defee0e153997bbfe196166cc8d83165fd5eaf41f","other":"5d002c37b74a6656db86f102b0cec82bc35a819a480e5a2952db0140ebab65dffeb1a79f04d53ff61447b5fad7c58cb75ea1c91ea47fcb9e024f27b92c6c874d","up":true},{"up":true,"other":"7c6e6a49429a4e24aa4aa5c7ba19684f77cd67d3744688baff6e7f1d74b7e9d2df85f3e57e0df0a9b960b5bf982a610c5639c3e7a6935ba13fbc77243b2dad19","one":"dbb6621460b054f584f1c6157b4020f3c58d84c3a12b57436e10525ae60ab27036bf3edd68b92f2b13674877d01c2871dc67a9031c3d0470985f4b071696346e"},{"one":"c402495c2110a6531a530ebdcd9ab1b883f1c707fe25aa13a255a0a9edb4113669b4aee9eadf803f9fe4c2ef66d5e4dff7064549f672598410f2d9794747a600","other":"8fb6838337f832445531764ddafc3c747b2607f2f33e244685d6de621c2b53264270f5504187e43b7fa5cda53e66dd00b16c06879c82fb38a3d9e8aec4060210","up":true},{"other":"4e88cc60efee147fb72a735775944c7b2ba0790e2b2b935b4b3c2da9a3158a2a7aae411e9204cdbe6b2304d90a3a8278f8bb1a800a409e8500d100d84ba1947f","up":true,"one":"224c3b969149d50d1bb4f473bb9725223c1dafe152efe1b08e8859213c543a66565b5d68a99cef3d5f4eccad6282a12f78d7b38eec14deebf44ad8dd9cba8680"},{"other":"f52297fc51b920d2495ccece290432656d9388e698339c8c1279ceea45de698a4ecbda1d25928c48f1e19e9dacd3147e23ef01acc093872d7300aed187841dcc","up":true,"one":"c29e80096fbe7bc9fcbfdbe3cf6c06449192a3ed280e46a1fa5d424428d893c3456c985c1352c119236cf783834365439751cc87e7ed196614705dd3db6674cf"},{"up":true,"other":"ee3471e1d835c4294f7ba642103039ccc548fe4edc177c79b63433ebbb0dc9d06600844f1fed76c7096ee9538e49e4e86fb8cffe9095dbdcde27695ff28ad395","one":"4eab70233789c544bec97040a04099494bf269a819584a5d0b42295c918a52b02f224a8ed127aba3d92c02f567356bea4b95f77230ef548dfa7fe44b643d8704"},{"one":"624248a794fd62248024360f128b2e503c752340694a316bed420e5ed2cebeb5bf970df95a2806732237a26de3778222b0454e2e7d2875129b193e7890fd5b95","other":"2cb076669efbaf2ff0b181a1b454061a31ef23937a40405022b126f0eb4bfba60c9e3397009d8c0ff0cabb603692532d0072c18c6838f43397c98483306f62db","up":true},{"other":"ee3471e1d835c4294f7ba642103039ccc548fe4edc177c79b63433ebbb0dc9d06600844f1fed76c7096ee9538e49e4e86fb8cffe9095dbdcde27695ff28ad395","up":true,"one":"c088bf88f1e152ca3fad17f098a71ca1021d46d8af12d0ee1c587a5e2a430d8e48beaf171fe01ee7680b671c00dd88c90f12a35c328a3f334661fdeee914a4bc"},{"one":"e9cd25d1ef3fef22160bce7f7badd7646ac58ee40da6a438f61a067c51bc51d6087ed950ec9e909bc438ebe62e316cbd9489f3c9bfa2898615632414e04f1dcd","up":true,"other":"7a8cb96685c1b8fbaeb18c8dc1f9f2631b23bc035e704e2f5df915b8bcabd6e2025ddc30324c69833f86e577b250c0721fee9d294f3e22016ae4c59c5f88845b"},{"one":"aa53ca208cc0c9e544fd9d52cab44b5e2887256bb006037b855b5c94d7f79c9388fdbb23c0bf1d2eee12d67125e082fa7ecb34c1129ca8eaecfd85772b009435","other":"d7e3661c0af6754c875217f93d34b254f1f45fc1359a4c6146cd0efa4c6e12aed9a4fb0a21a136f73af4fc2c6d0a63cb809d81855bbc9f51e29d23d90f77b326","up":true},{"other":"842f0ac24370f14edfe72a7d07219de60fc767d2d0356fa6ce9d535a43647ad4bb17d9be75ed83542868ba430ec104ba168f27c16915cdbd6e57ae62d60707cb","up":true,"one":"ab8eda9b360d3e0b002ba31d48311057880844b828ad9817a2ad19736860d0114d4a17e9e9427c842d52e7ff61a09c2cad9b70f506e338909535542dae38ede0"},{"one":"51a570637394e9ab61fe95b3a608cc4e9dc8ceb63efe717938ccd4260a962d52e01b30e7034fbfdabd9a3c9616ee569550b38a6d6b4b19847f523254069a9f27","other":"842f0ac24370f14edfe72a7d07219de60fc767d2d0356fa6ce9d535a43647ad4bb17d9be75ed83542868ba430ec104ba168f27c16915cdbd6e57ae62d60707cb","up":true},{"other":"228b3646b15527f4df07b847a62dbf9620cb068f829e9086b5f437d0b64d8a027cab44f19db5e44189b5099545ecb25d49384c261748f9533cfb0eb11a1eca5f","up":true,"one":"3948a7a939b9a1f4201953bd9b955ee7be87d09b63c7a45167f556ac06fe3c4c2a75d935bff50668da5e71e46802b55d7a9945a92d7807c00625d129cbb48f82"},{"one":"06aab75fed9a03f5525e3f1d8f8997fefaefd5b16e8f485d571beda00b1741efbb61a8a74fa12c2f6de66227c3fabb4d411659cd9c7b1ef32e171e6bf517cc39","other":"1b3107d9a96cfd11f4cd0ed8baeb7b23db1406c9c4a9dac76c772f49c0fc9404f6a4adae11120aa821757173f0cc1cb00e6ab555b5abffaae9001c0557cb75c9","up":true},{"other":"1e3a2f2491b6acb07a9549d9929d150479a0313c926b0e236237bd541303da4b563a855016a90ab50e59d94803ad566798570fa981464c94c04a4a4a94fbc607","up":true,"one":"b18c7131a319db61ab84d06e90092d93c91141e9a270630af9c3ab1eaf3bcad09f4d20a1fc845b21c994bf4d9e337d0bd756a75e2198097540355e7ebbb531b2"},{"one":"6c40910f0556f892a7542989fa01d7e3682fca89aeefb5ed885808f88ff17b6d13862f461c10d629a005ae67abef542d75e5b20816891b6944f71560f5c2dfa8","other":"e0a043f98b462f10f72aa61ceda52f9c27829d086f6f2c5bf4db4fe32759002e5ff9519495d57dbb83d963a1dc991a1defcf5b9ef0d543789f38c68f5d07122b","up":true},{"up":true,"other":"20f6a8be1d2d8b5d6a43d851a2f5475385ef07fab80ac46525d0beccf3e25c01d726cfb3a1179e8343b1e88d21684fb24dd6e6497537d4e7e9edd59cb95d1b8d","one":"545237d8463b75fd2e9bbfbffb35c5b78b4abbc85f6bfbd56976789012dd9a62ca1f866bf37bb33618e026aab764adb9ced5e00cd415562f69992f74c795083f"},{"one":"6d0a09235ba0b0428938abf0e0782ac0ecf5697ef862888719a34fc956517aeef89d5e5f76d12e10067fee5bac8781dc10400eeb35c2393b9382b2a4f68f7939","up":true,"other":"20f6a8be1d2d8b5d6a43d851a2f5475385ef07fab80ac46525d0beccf3e25c01d726cfb3a1179e8343b1e88d21684fb24dd6e6497537d4e7e9edd59cb95d1b8d"},{"other":"362ed9a92b588d5fe315b90a74aa27f7600e4a7d06b27ceb26272340388d916a831df85bf83450ef80bda4e4a21acaac60560c8a42940a26e2ac567519e2a202","up":true,"one":"2c976b6007cda135444233c7bd03d22ac9756710b746c36bc032e7fdd42f2ffb89ca5f5e754ff96b8f3cbc474e346287e5b8531d9f98fd63c426c632872220af"},{"one":"5319bc9864d87eb33f26ff9732824d21a0a5ab70b254bc70a47554ffc763ae1559000d07e3eac9f883bd9e7f249d80edf14ab39c89c375bfcc5ec9e840ec9673","up":true,"other":"002cb6ffa63ad71ee6ebc1df4c41f7a97c51f274b1d3b22420c87b73136be5169b9670508061d8261e20055fefce3b855388994672aa9a0f1475c43839aae4fa"},{"up":true,"other":"b1dd1b08975319030626aab821032a0c687a103ee8942e8a2e2cf029dd72832a49630e78d2d8b184579f22178aca0e875f9fad701fb81afd2ac110ab2b417376","one":"29acdd4c1233441bd40f98e245ecc9de94de6f9d0ab7c1a9923d833a2c8e6c1bd26d792686fec762b31fe28bbdd7aa04c9a594d997d08c133bb24cb2d877595a"},{"one":"ab13f773f6f2ff73032aa5f79c8897b75dda29bcbb14aa511e9401c2417dc9c510253071e28c7833c8d62fd2aef16fcd0c14ce016fbf4fec1b9a2173c717603f","up":true,"other":"3639f964feba681db9702cac3f02058f2e490fd7bffb217dc3480dc458decafd5955541fea89f0f6f14ee50a745eaf98b21363d6b4fb88c31bd32bf7845d524b"},{"other":"6b082a09e343a160b60a01f74641c1d707b2fa8fee5f6f5a8b9e4a203bd86434227d2df982b246a752f843483cdf517e85fe3bd65453354232a6eb38dedbf314","up":true,"one":"5319bc9864d87eb33f26ff9732824d21a0a5ab70b254bc70a47554ffc763ae1559000d07e3eac9f883bd9e7f249d80edf14ab39c89c375bfcc5ec9e840ec9673"},{"up":true,"other":"699c923976c5b8c70c353840d3e384750f466954265f05fbb0d5877a2c0318a041dc57adc12ac6e8fbae7a00d6b6675e1a1be3a8f59dac12727ee3f8ae467a13","one":"37399617d62153bc471f3bf21c92385bc8602c80ffa0c71da8aebae595a9859cfd56257aae60ad30ef3ec4d07dee90623cce63749c8c3233c0aa0d17f9e89afe"},{"one":"20f6a8be1d2d8b5d6a43d851a2f5475385ef07fab80ac46525d0beccf3e25c01d726cfb3a1179e8343b1e88d21684fb24dd6e6497537d4e7e9edd59cb95d1b8d","up":true,"other":"5a6318af8b4615cf30610a05ade7704182fefd0a3fb3d76c47cb392e114d8d30004f0ec214326b11532fd1e928e66f632bbcde126a94c87774063853a9518dc5"},{"other":"b58b3e200f6072ddb38130944a01d2829c755b8bd1a08abd010d1bbf86dabd851b2c1ab4cb961451bd7e8499f6c7378830bcd27cde825846654853c172597bf3","up":true,"one":"8e8614a4c2ee2b1a3fa5ace0ca353cff36b3de3308ccf53665b8b56f8e2456a8a65f3846d786dccd68b1bfcefdd170ea5f8edb481800b1ce72d9fce2added7f0"},{"one":"29acdd4c1233441bd40f98e245ecc9de94de6f9d0ab7c1a9923d833a2c8e6c1bd26d792686fec762b31fe28bbdd7aa04c9a594d997d08c133bb24cb2d877595a","other":"b4557089e4247379e587a087f53b36dd1f86f85d9dcfab5dc562079978cd959adaef5b30d11258d9cb552e7c5abddf5377a71d449febe8f2acb0aec3ebd8ba73","up":true},{"one":"842ec3faa8b4a4cdec32abfa00ae827277fe2696e1b0c6551154533b16cf75ae69caf834b4f08488fa5c8b322fb633b1fd8a5b7d436e9c589cc9074dc031ae68","other":"2bea7540c99456ea889a8ba2e448c11e6257bf987d01f13eea48128ba58577ab0936855035ee140c9907e382a34ca85a179c74892cbd9eb92fc2b35601addc6b","up":true},{"one":"20f6a8be1d2d8b5d6a43d851a2f5475385ef07fab80ac46525d0beccf3e25c01d726cfb3a1179e8343b1e88d21684fb24dd6e6497537d4e7e9edd59cb95d1b8d","up":true,"other":"6ad4ea3730ddec500e56248d1025aea79ec10f0d6a9720ee48026df10e219b41965d7a611fd99ee765f6afbc8c977db7e67c3a340881904acb983d1e2fb016cc"},{"up":true,"other":"7db14fde1da8794ae7ab5de37c9e2537e1024bc830c176c0d01635cafed47773d3a28e156db81ecdb95903222b900c3ebd4c4b3db2971dc0ef6a1e386027ffaa","one":"3376cfc924fef1a45aae35d106439b131f363b3a42904b3974cc7cddde325441cce8551729dd62f1119120b0d452e78f063e8e711ecacdc27d9087aac5ab09b5"},{"up":true,"other":"7db14fde1da8794ae7ab5de37c9e2537e1024bc830c176c0d01635cafed47773d3a28e156db81ecdb95903222b900c3ebd4c4b3db2971dc0ef6a1e386027ffaa","one":"48e35d67e14ee2f329c0275bc965829b761885dbc3671f4673d84d76d18a5b6415e619e219b5d90761a5c6bd2f43c6a58708286a063daf46b502944f8ef9230b"},{"one":"8d3ad57509b36c4ca5c4663f3d1977a3125e069078842634e6cfeb22c044281e3d02f06eafc6d2a60089f03d70f5134a6635c35563c9f911fd845a6ef9bc8952","other":"ecb93d8eba17afe92979e8154252a08dd58de6ff3188b6829e3e25967846686f54199ab2b081e77b0048dcab204f05aa2c5cbd0efae4bc43a612d471d4e1197b","up":true},{"one":"bab07c2e4dc09add884869b31fb474b6d7151f9cc331d831f55c2b088397370fb0a1e1592c8dff9c8bc8e83de9faf6e91683acfb2df1b41856d70e523a99d370","up":true,"other":"49215dfa786bfaa52b1e7aa6899392711a770b2504c82f536381fb1f18df16960257d75530efabf6dbd2b1361decc29758f870b318f777decf51f4833a9c1f00"},{"one":"70cce7cb0c18091dbb6d41160ab560935f1759b969bf8118cee030ee707cb15ba407b8c48dcd9fd012cbf778e219f7d16a74064b4983cf098fb118297748edb6","up":true,"other":"723f362e98f90d7ef15e24e353759fdbdabb08adab767dba73ab546741fac3dfb457466f1e2c851aa49526da1408f8ddb509e12f7dc0bc1e785c5b72be8a986e"},{"up":true,"other":"58f9139905ae1d005950f110b7ead3355672ecc478e8c66393566c64b935003f6fec3031dc9eb21cda660acb1955cf7bb33a20fdd74d493f29868ace328fcd75","one":"8d3ad57509b36c4ca5c4663f3d1977a3125e069078842634e6cfeb22c044281e3d02f06eafc6d2a60089f03d70f5134a6635c35563c9f911fd845a6ef9bc8952"},{"one":"ba430731fc2082f4217ebd859c2865c28bf50a39674ca8615dd89f608ae434a09657e24644ac32807634aad7857547118c9228460195e50ec58b34789d4ad151","up":true,"other":"c9d705012a06d82c4d44db95b4f1c63ddd33ad64d732e96b1d878caa0caac433d4096f01495a6f0e8a56af122b0470fd745db6d906353b590a4710472b93f5b2"},{"one":"c2a9c77247871cfa4d3c2d1b47619df91ed5b331a44c8e21f7c9ce431a4db9dfb87713558cc8a37911393907b4cc60be9445bad18adcea1bc5f318256e71be14","other":"33cac8f621b9122e118036154778d27dc419b6b58ea2e89b833f3932f411dbc3511d92b55ae4cf80632142bc8e67994899aaa30c499d0289fae85b12564cf01f","up":true},{"other":"a070b5cff5eff533a2267ceb0d88e221088038af773e18f80110c8a2c329f0543b8d43c4e6132e9416723e3e94c87f0053456760ced4426767b95cee36ed93f8","up":true,"one":"c2a9c77247871cfa4d3c2d1b47619df91ed5b331a44c8e21f7c9ce431a4db9dfb87713558cc8a37911393907b4cc60be9445bad18adcea1bc5f318256e71be14"},{"up":true,"other":"1e3a2f2491b6acb07a9549d9929d150479a0313c926b0e236237bd541303da4b563a855016a90ab50e59d94803ad566798570fa981464c94c04a4a4a94fbc607","one":"aa2028d356a88eca8e0fcaf218d62ace099c3f72dfd95bb28f30ac9a926034cf1d60a40511f7495652745de80d71c0f6830019e206c88e2b6ef0cf4f05d7fe9e"},{"up":true,"other":"c0164fb4a1acfb4f3b1a09f9f3ab226c382529a73891937c6f3c91798098cf10b909eb92e5f8acfe0e8f3aee0b71cb23ee2d9e6ad1e0f4492a0272c52d529849","one":"28cdd55fc871ffd8d63d05994be706959c9780dbfc859070a41047a1b40dd5fd7adb53919400a4c6f4d06c69bc1ecccc0e230e5b702598a7fe8003a282479872"},{"up":true,"other":"682288e4dae2374c4784acd0b285508920ce39a6b72cc0e30a3dbb7972e0394a2bddd5ee5f22a1dbf80f284dde4d9f8ede7847318d5353566b35a83e212477e7","one":"5319bc9864d87eb33f26ff9732824d21a0a5ab70b254bc70a47554ffc763ae1559000d07e3eac9f883bd9e7f249d80edf14ab39c89c375bfcc5ec9e840ec9673"},{"other":"c63b88f494b14d5a7c1da124ffebbd985d19806b91d4b111c83ae129c4ef19614469980a09fbeccebe3b0358dd16194bdb6452d0b3dbb43a5467e23bb13f40d6","up":true,"one":"2cb076669efbaf2ff0b181a1b454061a31ef23937a40405022b126f0eb4bfba60c9e3397009d8c0ff0cabb603692532d0072c18c6838f43397c98483306f62db"},{"one":"51df4f4d4f020f22f55a5fd00c7f9c68c232c167ae4d4e80d7695f8f39c5aa0a7b565c1c55bdd6a21e06fa056549d08fd2e9d76fd79e21295557aa30d1ae022c","up":true,"other":"b18c7131a319db61ab84d06e90092d93c91141e9a270630af9c3ab1eaf3bcad09f4d20a1fc845b21c994bf4d9e337d0bd756a75e2198097540355e7ebbb531b2"},{"one":"57085f756f76644cdd2148524f2334d869ef0ab2fcbe7fb11f5d22bc1f5023165b11526ecc85ff9cbb88877386af9b148d7ef15a825b3a586d16c01bdfc86692","other":"c0164fb4a1acfb4f3b1a09f9f3ab226c382529a73891937c6f3c91798098cf10b909eb92e5f8acfe0e8f3aee0b71cb23ee2d9e6ad1e0f4492a0272c52d529849","up":true},{"one":"2c976b6007cda135444233c7bd03d22ac9756710b746c36bc032e7fdd42f2ffb89ca5f5e754ff96b8f3cbc474e346287e5b8531d9f98fd63c426c632872220af","other":"b7cc9044d021b19cd8a6d290d21f1c91fd5deec472583d0aeed0a6aacc8efef9968079254132becc5443df14dd3f4feaee56d14b885c078649727b9659139fa6","up":true},{"up":true,"other":"e0875ed6be1e163b15c13cdf37442f838670d0949349ee9ff119a0451beffb1a302943ee9d7cba48592922f64908aeb0f39f6e2e3725d1e7cdc5db34083b6977","one":"85b6404a76b4762156c8ddd2f312763dfe19b315d914533844cf229301880c57ffeadc0eb5f4a8d542e1d9fc961dfb5a572d2101172b1a0fc238ced05ba49ec1"},{"up":true,"other":"869ca41ea1f82bec5f43807a3aaaabc39b21c62d3c9c8bdc0709683e22dd37cb2f3c313766809076d2c02d0d6171f4f32a1b5080abcb8072d88981042ae6237d","one":"29acdd4c1233441bd40f98e245ecc9de94de6f9d0ab7c1a9923d833a2c8e6c1bd26d792686fec762b31fe28bbdd7aa04c9a594d997d08c133bb24cb2d877595a"},{"up":true,"other":"af9b80f6836113aeda897d6903e9ffb4f7f1a706a7f821d0d40f03a0d83c18d6a19795ee4bfc1093ada04014415b1f230db1d2f056df3f5027cce71611588046","one":"8e8614a4c2ee2b1a3fa5ace0ca353cff36b3de3308ccf53665b8b56f8e2456a8a65f3846d786dccd68b1bfcefdd170ea5f8edb481800b1ce72d9fce2added7f0"},{"other":"fd0123c7b96004067e98e463e273de5bc5402399ae70a95985b5f682e30d4f35d070deaf8c71d201e98c4324d832b95aab7535ad8a2658f66e3e0bb1202204e1","up":true,"one":"20f6a8be1d2d8b5d6a43d851a2f5475385ef07fab80ac46525d0beccf3e25c01d726cfb3a1179e8343b1e88d21684fb24dd6e6497537d4e7e9edd59cb95d1b8d"},{"up":true,"other":"4ff2981a47da46c753090e193a8bf43c3372a6b07a37cf0552de2ced455fbb8a76d969cd97b3e4601d8a808bd2a73f7729ed8a61df2f2a0c2cee1425d0bd9ab4","one":"431644cf162bc267237c4e798288888dd835c1b0546b0cc679782e33568988d75b4294f4aa08359a6b152ed9a0fbd13133681156bcf09a871c4f362615ea6dae"},{"one":"c63b88f494b14d5a7c1da124ffebbd985d19806b91d4b111c83ae129c4ef19614469980a09fbeccebe3b0358dd16194bdb6452d0b3dbb43a5467e23bb13f40d6","other":"8e8614a4c2ee2b1a3fa5ace0ca353cff36b3de3308ccf53665b8b56f8e2456a8a65f3846d786dccd68b1bfcefdd170ea5f8edb481800b1ce72d9fce2added7f0","up":true},{"up":true,"other":"eb6d41d8d96f1933dff017d5fa0c46c6d0bad5d273b7c321a12858ac90ec00fca6191d29419897d2e25ec2d8ebd8c6a81bbde2d3f266f842e64b2b822161f1ea","one":"5319bc9864d87eb33f26ff9732824d21a0a5ab70b254bc70a47554ffc763ae1559000d07e3eac9f883bd9e7f249d80edf14ab39c89c375bfcc5ec9e840ec9673"},{"one":"70cce7cb0c18091dbb6d41160ab560935f1759b969bf8118cee030ee707cb15ba407b8c48dcd9fd012cbf778e219f7d16a74064b4983cf098fb118297748edb6","other":"8c459100df488b992fdad207a096a434d67cb733619adfd09a311095568d4c9db293d9a892675551805559456d49a3fdb19c2cc698b14552bf0ace584d4d90dc","up":true},{"other":"8e5e8366251e33277e7db6f6c04629b2ce3eee217e973acb97c83773671b0160c40732794584db741a29a763672b90f3bdf34151fd4a6986b9d0956dc61d9723","up":true,"one":"ec19efa1d488e74da6bf239825b24678f549c377326c5d33d100b708a9a28a3fe129d542d7ba71e0ade46c15c6e9b38f09422560444388e609a8a66ceb8e0ae8"},{"other":"15ceb62ee0f53379aa202950634ed881ba3b7bd4b46c80723ee48190079311e24ffaacb167a126a40bd6732c384f3c26163aa043edca03cb52a97b6da189aec7","up":true,"one":"45d3827eb5c3b906fc61aaad79c5968f3dcf7b1ecc1e3be63e827ad6fb9291542686f42b3e142f43cc0437a2177b7362727842ea1d6c33bc795d936bba3ae457"},{"one":"ec19efa1d488e74da6bf239825b24678f549c377326c5d33d100b708a9a28a3fe129d542d7ba71e0ade46c15c6e9b38f09422560444388e609a8a66ceb8e0ae8","other":"7465fe601a9ad8e640069e6e07d56afabd3d4f008f3084f944d869b47fda3f511f191062802a53da511f60891dd0bcc5fac60254ef9db7aa3b41f5791b0b6975","up":true},{"one":"d6a7257771baa4d9944592ead46b8ab700dbf91ebd4dc0ec7e5fb41cbda0622944269172fcec8352b89ef2c186d4c787af2b45a50533f627a97818477de034b4","other":"15ceb62ee0f53379aa202950634ed881ba3b7bd4b46c80723ee48190079311e24ffaacb167a126a40bd6732c384f3c26163aa043edca03cb52a97b6da189aec7","up":true},{"one":"7a8cb96685c1b8fbaeb18c8dc1f9f2631b23bc035e704e2f5df915b8bcabd6e2025ddc30324c69833f86e577b250c0721fee9d294f3e22016ae4c59c5f88845b","other":"1cdef98d7b4de45c902c725384bd14c66084fe4159b26a0f9a24f432e1f561d035ca41e1c60fe64f3213b4f91a1afb953193dca1a7d535be0602b5d046bcbab8","up":true},{"one":"f52281c227aa82a3bd5fabfdcf8bdf1d9ea6739ab9b9075340143d59b4f2f8a79a981609c9f42823a0253c19a7281eed0e912e4054363ab7fe50117563ef14e0","up":true,"other":"e5cb29b25debcfaaacc0b04e708c8c1cb9d2dee29e82596a1c72a934032cf738800b9525cc277d0c5f5dacf2f278329b54da161b4bafa285243fa0e9fd7b2f3a"},{"one":"876618c8ba66c1b91b473a154be3e10ded3590ba83d620d30e0ff1fbac2f31f258b1299a3da5b56aa03269a80c119b7fc41dfd87d5bd996359e4ad8dd0ab2a6a","up":true,"other":"9c8fca41b833e88110559b9258653160f5fb236bd637272ac58fe1adf333f4df75b94a805eaebb9f10a8c1a26d357dd75140560551d3fc4da79da2c4fc9479c3"},{"other":"869cae165389e7dee7b7df4e012ee1a39737366c306d8f4b0db4510b2236e0bd3a4d1d4af00b1a8c1d360e23da47de52fc1632edb03c7f1429aacc8aa4994750","up":true,"one":"dd6acfd151220f21b03701ca554a5e134dbd1154dda21d9eec45809e7858fe83eca3953fc688f499030198f22052c3681a9f49207ef9b11a760456ab9637352b"},{"up":true,"other":"ecd217e8bdb53c9ef085929b8c2d2b40425a4be617a087b8e7f88e8507b3c981e90fda2119744ca394fe65bd4eb1cdd3fa7258db936048e236d2f15ee91bc3b6","one":"c69b9b181b2756a1345b73a97afb3dca909c253188c3b905f0b414465b750d2ffccb4c8e8eb5e3809549af55db473f3b12682f9bd97c5c75d68f23d67d91b866"},{"one":"b7cc9044d021b19cd8a6d290d21f1c91fd5deec472583d0aeed0a6aacc8efef9968079254132becc5443df14dd3f4feaee56d14b885c078649727b9659139fa6","other":"1c080e90760dfcee08ade6e4ea3b275ff3c6882f3b44b7f3a73d70bcc816fc63ce0b6138f810d17d96ed387076f9bbb6dbb2ef6dc4d6ba6542c1f587b7602a12","up":true},{"up":true,"other":"7d9979c13cd8841e84e5d199fc263962ca6fee12664d8526a581bfcdca2e3427ca169b9a0244dd8292a9a1be2bcedb0e8f626eadd307068c11c03b6df13aee33","one":"c69b9b181b2756a1345b73a97afb3dca909c253188c3b905f0b414465b750d2ffccb4c8e8eb5e3809549af55db473f3b12682f9bd97c5c75d68f23d67d91b866"},{"one":"51df4f4d4f020f22f55a5fd00c7f9c68c232c167ae4d4e80d7695f8f39c5aa0a7b565c1c55bdd6a21e06fa056549d08fd2e9d76fd79e21295557aa30d1ae022c","up":true,"other":"c206d8689068488179e86ce549de75989e0b17cbe09880d18fcf0fa212e629345f1b899203607a2b083569cb3f8398e501843166f5db23ac7fa7dacfe26dd3f4"},{"one":"57085f756f76644cdd2148524f2334d869ef0ab2fcbe7fb11f5d22bc1f5023165b11526ecc85ff9cbb88877386af9b148d7ef15a825b3a586d16c01bdfc86692","up":true,"other":"bdd17545242bedba1e4c36fadea95db655f8f220f10ae143084690a3c8d4e7ffb79a64af9f1bc8514addbd63695b2f20857e8d162f25318faac885f77b385138"},{"one":"545237d8463b75fd2e9bbfbffb35c5b78b4abbc85f6bfbd56976789012dd9a62ca1f866bf37bb33618e026aab764adb9ced5e00cd415562f69992f74c795083f","up":true,"other":"6ad4ea3730ddec500e56248d1025aea79ec10f0d6a9720ee48026df10e219b41965d7a611fd99ee765f6afbc8c977db7e67c3a340881904acb983d1e2fb016cc"},{"other":"6ad4ea3730ddec500e56248d1025aea79ec10f0d6a9720ee48026df10e219b41965d7a611fd99ee765f6afbc8c977db7e67c3a340881904acb983d1e2fb016cc","up":true,"one":"6d0a09235ba0b0428938abf0e0782ac0ecf5697ef862888719a34fc956517aeef89d5e5f76d12e10067fee5bac8781dc10400eeb35c2393b9382b2a4f68f7939"},{"other":"7db14fde1da8794ae7ab5de37c9e2537e1024bc830c176c0d01635cafed47773d3a28e156db81ecdb95903222b900c3ebd4c4b3db2971dc0ef6a1e386027ffaa","up":true,"one":"bc0df855bdadcde3e447415444f655eb430925a8fa81cdcac75909e7d79750f01827938570e75e388cc7058ba8ebca47afadf8b07172bc078488fb618ba71024"},{"one":"77e40e42f570a217f707888c714deb31fd70c856ae4b9a44ec7cee02768185dc4d7ed210429607f06690b32edd9fb06b304aff330a3949cc2fd49db1bc392edb","up":true,"other":"bc0df855bdadcde3e447415444f655eb430925a8fa81cdcac75909e7d79750f01827938570e75e388cc7058ba8ebca47afadf8b07172bc078488fb618ba71024"},{"other":"ab1a3542d67ef9d1a63653990bf0782f53b0169fe5092adc92fa7aeb38f66c6b62d49e3455cc2ac4994bfcfb03111953acf4cc3099026672cc61f6e24cb3ae00","up":true,"one":"842ec3faa8b4a4cdec32abfa00ae827277fe2696e1b0c6551154533b16cf75ae69caf834b4f08488fa5c8b322fb633b1fd8a5b7d436e9c589cc9074dc031ae68"},{"one":"207764262a208c17db61fda4208d4664bf74010e0ad051a863e131e748c9304e11ccf007c925488ea86b974ee61cdac3dca4d4b3f4043524e03c194ab3c8eb5a","other":"8fb6838337f832445531764ddafc3c747b2607f2f33e244685d6de621c2b53264270f5504187e43b7fa5cda53e66dd00b16c06879c82fb38a3d9e8aec4060210","up":true},{"other":"4ff2981a47da46c753090e193a8bf43c3372a6b07a37cf0552de2ced455fbb8a76d969cd97b3e4601d8a808bd2a73f7729ed8a61df2f2a0c2cee1425d0bd9ab4","up":true,"one":"20f6a8be1d2d8b5d6a43d851a2f5475385ef07fab80ac46525d0beccf3e25c01d726cfb3a1179e8343b1e88d21684fb24dd6e6497537d4e7e9edd59cb95d1b8d"},{"one":"431644cf162bc267237c4e798288888dd835c1b0546b0cc679782e33568988d75b4294f4aa08359a6b152ed9a0fbd13133681156bcf09a871c4f362615ea6dae","other":"6d0a09235ba0b0428938abf0e0782ac0ecf5697ef862888719a34fc956517aeef89d5e5f76d12e10067fee5bac8781dc10400eeb35c2393b9382b2a4f68f7939","up":true},{"other":"fee3fa1ba2a051d40a582908384ee81179db6c2b5f4bfa58c24f8015b794b43a093ed68b69bb209684135f972a055a9845978fa1b7d489e2126c3b514297f1c2","up":true,"one":"eb58e478b16056e0af344397cf5f078a3312a6db2189ec2042ec06ab6550e3ee71ebcfeff1814332c552c12a5a488f96b3f2935e90a189d238da19d30a2c9874"},{"up":true,"other":"9c8f156797deff649d74d56fc42b4bb1a87312089114d4350424c375837d9c8068dd09af01c1c973d12ec5d7e8da600cd685cae70d3116b9dbda823092e03fff","one":"740919ebae9b4fe646ca716ebb8923bf2a1b1963767d86f55ea95911d88d163cc2e07b1420669e64b62cb267b625413444b783b8e4a7bd6a0f481f4d84e984b1"},{"other":"b8e0a56df21baae43058f575b714ae9a33c097d18f1a628b3b6ae5e86dd46a06e44c0dc272baacb5be0f7bf57fd6ddce107544eb3b94dca1aeae9f5773496a72","up":true,"one":"70cce7cb0c18091dbb6d41160ab560935f1759b969bf8118cee030ee707cb15ba407b8c48dcd9fd012cbf778e219f7d16a74064b4983cf098fb118297748edb6"},{"other":"3a2cacc430f13f31c52b7205455420cf0fb9ed9e28b0898b69ef97951bf295b29118e573a42dd97abe38fee5ab4c03dad9ff6dc448126cefc1da12b6c8e8d915","up":true,"one":"3376cfc924fef1a45aae35d106439b131f363b3a42904b3974cc7cddde325441cce8551729dd62f1119120b0d452e78f063e8e711ecacdc27d9087aac5ab09b5"},{"up":true,"other":"77e7d427b65b6c29c0d92c51184af73031bfa768a47fc20be6c264f422bf718865259c17c103bf47289b3abe62f93452781c6303d757e76d3d56ceeb26262fab","one":"8ec699020ab5e7719fe23b80268b5d1d37052bb71f5d81200ae805cf27825823733206165f0a7507c2595853361dd122e9ec1b2deb543591e22b71ec0b873b5b"},{"other":"fee3fa1ba2a051d40a582908384ee81179db6c2b5f4bfa58c24f8015b794b43a093ed68b69bb209684135f972a055a9845978fa1b7d489e2126c3b514297f1c2","up":true,"one":"f60755ee9464c7db769bb7237016fa165441d18ac3bfed7cd2a220a9bcbead202dd34eaf2f9398a3d36bdfc2671bbd46ac25ebe264a8118afe1b7d0bd38710f4"},{"other":"1e3a2f2491b6acb07a9549d9929d150479a0313c926b0e236237bd541303da4b563a855016a90ab50e59d94803ad566798570fa981464c94c04a4a4a94fbc607","up":true,"one":"2880e0defd1bf2665bdd20dfb46bc0a9ad707f495211fc78e611ab479d78398db7daff7d3f4b6bf81fd13bf766ecc8271e0ea99a2d74abd2f9ddf98835ffdcf1"},{"one":"5a235aca7005df295d5bd924b1272452e9bdad408ca5223b9eb76800b4bd4e3158a1d663ce5243fee92233227249fe4bb8507e8cb2c3729744b273bf488ba60c","up":true,"other":"877d17ec7e95998ead831606d3363fbff1c8d1fa377b8e621e6a876d2c7776b9af356211a7e4df66adeaf38cf9b49c04871e8804edde4c18435ff45e110ecb04"},{"one":"0c82c4b414375479375703ed9c19fb08c8143229ed4f1dcf448c6cf313810c098905123bec17969276936ae0cc39ed251b2811dbffb551d61159862b0eac0a23","up":true,"other":"43086ff7ffd3c7bdec77bd288f41f1ee0ce21bd3f60a5df8931e2af6e7af5ef0fad432d29625491935d11567944351fc7867c807ebd12dd2c21c9e620ae0f85c"},{"one":"154d5ddb15ec12dc65362039d801383c189b5bcf6688883f2d7e3d0e8dc78e45f9f58d5dabc79a8798a243ce59abb95c77525db14f050fd8cb37d04b7276557c","other":"c2568576c2c9ef47aca0baca52709a4fa44b2ed478a062f7b161fac2bdba68568df371ac7754255fd07d79bb9918249a914946a6c318d579730bee9bc609922a","up":true},{"up":true,"other":"e903d7aebff96a6afa4b9dd19b0b02e5af18da8e4e89f64247e1a2c2d46637538c741182eac67f45ec61be76aeaccde57f0a0184bd608ea7d92e586d4f827ea7","one":"488854534ec5a3479d8ee13d9b7daf07479f6b5505f319eced44dad8c316f6ff241ce2101e95608ba635067f5e5741481b78f419c4bbd465bf7e837dc4e54d64"},{"one":"c69b9b181b2756a1345b73a97afb3dca909c253188c3b905f0b414465b750d2ffccb4c8e8eb5e3809549af55db473f3b12682f9bd97c5c75d68f23d67d91b866","other":"877d17ec7e95998ead831606d3363fbff1c8d1fa377b8e621e6a876d2c7776b9af356211a7e4df66adeaf38cf9b49c04871e8804edde4c18435ff45e110ecb04","up":true},{"up":true,"other":"313a131ecb7d68e127d0fec8bb4a2e586886203c3d07857a93e7a39bb831703184d9ae28ba9ef3d986c2dae1a24f4f5bfa47cfc35f74f5512a126836364d7736","one":"f52281c227aa82a3bd5fabfdcf8bdf1d9ea6739ab9b9075340143d59b4f2f8a79a981609c9f42823a0253c19a7281eed0e912e4054363ab7fe50117563ef14e0"},{"one":"df9306a263f40e0e255996500523354de3cc78b68ae560f66d79f6ea28f30f773f1fd6ebc33928723dfde2ee3d4f982b203bee4c3803a5050df83477045bb279","up":true,"other":"d6747e1f8594f7449fc6d7c0e63ee843480567d498db096ff04229420861c83bca5215fc19d8fede0c54484f111f1f2581e189e638c21c5d9e1fd3174bbb3e98"},{"one":"936fad959da2d8b0cfb2bcd78c5da65bcce5e9463be7fc7367f45cdfa20678f4c466fb1e3f600783a270855fd4b9cd6265054f79ecb116141e7c67a492041bed","up":true,"other":"7b4585f8a4e4904239994a1b8bdc76299da8e46a8a632fabc6c33dd4170f8f3715e4c4f526ea5dd14093b150855960e432b1b140594aca21995f9e0722fb57f1"},{"one":"2751df9f64a8f2ff8ea45efc9bd02b281d963ced285260bcda7f9dfaed998fe4386fe65a7265876da6b4fee77ea5c12454869a70ad627da7ca888076fc629665","other":"5a6318af8b4615cf30610a05ade7704182fefd0a3fb3d76c47cb392e114d8d30004f0ec214326b11532fd1e928e66f632bbcde126a94c87774063853a9518dc5","up":true},{"one":"207764262a208c17db61fda4208d4664bf74010e0ad051a863e131e748c9304e11ccf007c925488ea86b974ee61cdac3dca4d4b3f4043524e03c194ab3c8eb5a","other":"ea2921612b827e3c26328368bed9be7cbf1f2b2aecaf31863c9cdccd74c56b651d6eaceb8ac9609a6653488837ded310df91e53a74789ae75cb841e2aeaf96df","up":true},{"up":true,"other":"6c95c653e15bb99d32656f35790400134cd7188e063f878e19cb9118eb469ae0362dc45255f2a1eae31520be01d42b5bc5bbebf03d644c9f206ca79cb33a01ad","one":"865dbf61d8511603fe0d9ebfb10792b9f6b798187c0909039bd9b2492c41e428876f386beeac86d0dea871f4fc24ba435f0fbd9a11e74c044024934592af14ee"},{"up":true,"other":"2bea7540c99456ea889a8ba2e448c11e6257bf987d01f13eea48128ba58577ab0936855035ee140c9907e382a34ca85a179c74892cbd9eb92fc2b35601addc6b","one":"6a55b94c9990249b24cdbeed96f065137f7b79ea8ee5f58da150d3962dfb62ba401960a53e7e8bd4e2c2908aa1a59b9d5efb4aafb316a9ab4fa67a0d95b58c54"},{"one":"b4f300abda4cf6e383f997510eb681e9fa62e23577e3c19bd7447fa1f5702a4e034cea5944248e7c6e6e92b5ae69195c3e8a2c5ca7827b4f4a00cc8546e6695a","up":true,"other":"5a6318af8b4615cf30610a05ade7704182fefd0a3fb3d76c47cb392e114d8d30004f0ec214326b11532fd1e928e66f632bbcde126a94c87774063853a9518dc5"},{"one":"f6a12b23423c047927a3024a6dba7ce88927cb21d4df3778bc5ebb262cc403261c79ba6d9bda07f1852c009d803a77f429e9e48ec1d63cae98256e529d45b276","up":true,"other":"e7b2adabc2c99ac47b1e94fc0a2c63a00a1d622ea67a4c1858f4cec93fca957d43d8429605761bdf5eed4f733dac1a3d12fb928f22abf248965994acde63864a"},{"one":"2abb91884cc3a8fb91b2f2f369f9430f2b3b05c75ce6203aa7a50312c9f141f9d0f615063d3576a5ce8a4be9ecb942aa804a717f76d9e8dca03d115dcc43f775","up":true,"other":"fd0123c7b96004067e98e463e273de5bc5402399ae70a95985b5f682e30d4f35d070deaf8c71d201e98c4324d832b95aab7535ad8a2658f66e3e0bb1202204e1"},{"up":true,"other":"207764262a208c17db61fda4208d4664bf74010e0ad051a863e131e748c9304e11ccf007c925488ea86b974ee61cdac3dca4d4b3f4043524e03c194ab3c8eb5a","one":"6c95c653e15bb99d32656f35790400134cd7188e063f878e19cb9118eb469ae0362dc45255f2a1eae31520be01d42b5bc5bbebf03d644c9f206ca79cb33a01ad"},{"one":"5982e7dfd39c527851f6ea6430b70e654d95df5ec4401ca1d8dbd1034cf7a65d1126d60b36ebbd396c9ca32e6e8515f34f9dc0a8d2980afe4aa181c8bf68437e","up":true,"other":"5a6318af8b4615cf30610a05ade7704182fefd0a3fb3d76c47cb392e114d8d30004f0ec214326b11532fd1e928e66f632bbcde126a94c87774063853a9518dc5"},{"up":true,"other":"3948a7a939b9a1f4201953bd9b955ee7be87d09b63c7a45167f556ac06fe3c4c2a75d935bff50668da5e71e46802b55d7a9945a92d7807c00625d129cbb48f82","one":"5319bc9864d87eb33f26ff9732824d21a0a5ab70b254bc70a47554ffc763ae1559000d07e3eac9f883bd9e7f249d80edf14ab39c89c375bfcc5ec9e840ec9673"},{"one":"1edeb91789b9aa996fea7a70964e0be33ee50acbe6d8f7d9d9fcf6dcf755dab6402637a610116f0eb716b19259429bdcced8bebc28ffa334387a430efc21b9b0","up":true,"other":"2880e0defd1bf2665bdd20dfb46bc0a9ad707f495211fc78e611ab479d78398db7daff7d3f4b6bf81fd13bf766ecc8271e0ea99a2d74abd2f9ddf98835ffdcf1"},{"up":true,"other":"a25958cf192a4f62301feda5d442535f78b983dd9e4599354f4898c8c1e6ad97ca7112549e1d1a1eacb4682cd1bf8b762368b5905ab33dbdacb585b128514ca1","one":"f6a12b23423c047927a3024a6dba7ce88927cb21d4df3778bc5ebb262cc403261c79ba6d9bda07f1852c009d803a77f429e9e48ec1d63cae98256e529d45b276"},{"one":"c69b9b181b2756a1345b73a97afb3dca909c253188c3b905f0b414465b750d2ffccb4c8e8eb5e3809549af55db473f3b12682f9bd97c5c75d68f23d67d91b866","up":true,"other":"5a235aca7005df295d5bd924b1272452e9bdad408ca5223b9eb76800b4bd4e3158a1d663ce5243fee92233227249fe4bb8507e8cb2c3729744b273bf488ba60c"},{"up":true,"other":"d3cd2f34f67830ccdc295b7537a6d27c02b44503808ca666124f52ecc3d6c35b7d3f14343997006aef2cfbefc8d27809d389477e99c236b9f8a897a4bc406a43","one":"f52281c227aa82a3bd5fabfdcf8bdf1d9ea6739ab9b9075340143d59b4f2f8a79a981609c9f42823a0253c19a7281eed0e912e4054363ab7fe50117563ef14e0"},{"up":true,"other":"e1f23e1caba66f5ff821edbc4a3d527539937f73d86dd0df43aa1266a99f51f2480a77961eff177fbbf852fc52cb9317179f80b1580194daaedadc3b00510751","one":"c0f233e79d0a8d4af01f54c40640975bc113f464271ba8922fca0c28acc60367af0db06629e701977e86cb5917c891e39c21418cab459fe49132b680aa31600b"},{"other":"6c2788dec7ae7a77134065afc1174bb92b87833e87acaa72fe9e62c92d2017f217f9fbc5884cdfb7236a7bb75e463e49ecceb1641a8629516211d9699587046e","up":true,"one":"643da2591098f9698f27cccf7c17832e0717ee6a1276398a1a29edc947125585dcfab9417c2721a8a55d4dfc75b826be7581b6e30b020f6341ac549877c9f122"},{"one":"b58b3e200f6072ddb38130944a01d2829c755b8bd1a08abd010d1bbf86dabd851b2c1ab4cb961451bd7e8499f6c7378830bcd27cde825846654853c172597bf3","up":true,"other":"77811b007dd1fc1b11e447858df37062e97b6fc14e059399814f3b4736188e3fb28bf7c3958bb8ebc6ae16c36884ba7c98b810fb6f8b358323412123c803abd4"},{"one":"643da2591098f9698f27cccf7c17832e0717ee6a1276398a1a29edc947125585dcfab9417c2721a8a55d4dfc75b826be7581b6e30b020f6341ac549877c9f122","up":true,"other":"b9c7b885430b9b1a4425bde30b3629559f5437e0e30a0299fc6f6e097cbcca8af9e285caf5dea685a0237f60e06f490c39a1e3e487f14a2b9f41a5135f2ba994"},{"up":true,"other":"362ed9a92b588d5fe315b90a74aa27f7600e4a7d06b27ceb26272340388d916a831df85bf83450ef80bda4e4a21acaac60560c8a42940a26e2ac567519e2a202","one":"b7cc9044d021b19cd8a6d290d21f1c91fd5deec472583d0aeed0a6aacc8efef9968079254132becc5443df14dd3f4feaee56d14b885c078649727b9659139fa6"},{"one":"936fad959da2d8b0cfb2bcd78c5da65bcce5e9463be7fc7367f45cdfa20678f4c466fb1e3f600783a270855fd4b9cd6265054f79ecb116141e7c67a492041bed","other":"f6a12b23423c047927a3024a6dba7ce88927cb21d4df3778bc5ebb262cc403261c79ba6d9bda07f1852c009d803a77f429e9e48ec1d63cae98256e529d45b276","up":true},{"one":"a1fe0d27f82309911a4b758c4e597bde16adc1e2fdfb07b52dea5092cea40ff212ea2cc831e385094b044f519909cf978f350b16ffd4c70c159cf1372301a3cf","other":"1b3107d9a96cfd11f4cd0ed8baeb7b23db1406c9c4a9dac76c772f49c0fc9404f6a4adae11120aa821757173f0cc1cb00e6ab555b5abffaae9001c0557cb75c9","up":true},{"other":"a8fac88fba179fb9b259d94caac9cbe45d873a0131bef8844ac4383b177daf6f301f8793623fec5876885db1a91e5b3e98e2aafdaa47e03b1f6d9740f48af7ac","up":true,"one":"b58b3e200f6072ddb38130944a01d2829c755b8bd1a08abd010d1bbf86dabd851b2c1ab4cb961451bd7e8499f6c7378830bcd27cde825846654853c172597bf3"},{"one":"5114329db828f9568ccb0d7643a10e273aa626177910f55e22a53abf1ce8ec75b95465c983446b20eac0ff9c59c5dc53eca95b24aabcc8dd110e397cd2934047","other":"e323da6ae861cb092543992b8985639f9b3bcaf1c3c68757f4603a67800be62950fe7d8f8ef80eb83a18107b677c7f5047ea89a5790e0ea2a7969f4856d28488","up":true},{"up":true,"other":"37399617d62153bc471f3bf21c92385bc8602c80ffa0c71da8aebae595a9859cfd56257aae60ad30ef3ec4d07dee90623cce63749c8c3233c0aa0d17f9e89afe","one":"e7b2adabc2c99ac47b1e94fc0a2c63a00a1d622ea67a4c1858f4cec93fca957d43d8429605761bdf5eed4f733dac1a3d12fb928f22abf248965994acde63864a"},{"up":true,"other":"243164c4dd583f80c50813f43e5c27c894463400cd3afd776b36e79e7123d9261f01f06f92914aab83096b9a43fb655e79687590599284640a3a7d2c25454597","one":"60995852a2385ce8d7d24dc94b85a2f0dab6e5c32e910dfe367ea9c6ccb7b0b2eb611fdf120f8c697097e2f137cefff42e8d9db16b664a857a38c5ace837ffa4"},{"other":"57085f756f76644cdd2148524f2334d869ef0ab2fcbe7fb11f5d22bc1f5023165b11526ecc85ff9cbb88877386af9b148d7ef15a825b3a586d16c01bdfc86692","up":true,"one":"842f0ac24370f14edfe72a7d07219de60fc767d2d0356fa6ce9d535a43647ad4bb17d9be75ed83542868ba430ec104ba168f27c16915cdbd6e57ae62d60707cb"},{"other":"ab1a3542d67ef9d1a63653990bf0782f53b0169fe5092adc92fa7aeb38f66c6b62d49e3455cc2ac4994bfcfb03111953acf4cc3099026672cc61f6e24cb3ae00","up":true,"one":"2bea7540c99456ea889a8ba2e448c11e6257bf987d01f13eea48128ba58577ab0936855035ee140c9907e382a34ca85a179c74892cbd9eb92fc2b35601addc6b"},{"up":true,"other":"8ec699020ab5e7719fe23b80268b5d1d37052bb71f5d81200ae805cf27825823733206165f0a7507c2595853361dd122e9ec1b2deb543591e22b71ec0b873b5b","one":"b152eb30c9f46ec39166016f03d289f98cc285ac62d204da32e5a003da14e4f02c64df8ae1d0c8a2a902adc5f7dd7604081a0b140c9b64052082f0861945f5a4"},{"one":"ef7157fdfe62390d8a6d4ef976478d17465b42b63fddb03664973d63efb62318a8f59e412150528a32aa2c028b9de6bc67f05e012b8c43d710032ad871bc27e5","other":"e0875ed6be1e163b15c13cdf37442f838670d0949349ee9ff119a0451beffb1a302943ee9d7cba48592922f64908aeb0f39f6e2e3725d1e7cdc5db34083b6977","up":true},{"other":"8fb6838337f832445531764ddafc3c747b2607f2f33e244685d6de621c2b53264270f5504187e43b7fa5cda53e66dd00b16c06879c82fb38a3d9e8aec4060210","up":true,"one":"dd6acfd151220f21b03701ca554a5e134dbd1154dda21d9eec45809e7858fe83eca3953fc688f499030198f22052c3681a9f49207ef9b11a760456ab9637352b"},{"up":true,"other":"b87e7f36ed6bf142d48545024d2fd6e120c44511701e7c0b7d7fc786f4f29d3357024b15f70b78215d8a4c2b7572d608c11b31612743e23db4fa673f0cd6519b","one":"2751df9f64a8f2ff8ea45efc9bd02b281d963ced285260bcda7f9dfaed998fe4386fe65a7265876da6b4fee77ea5c12454869a70ad627da7ca888076fc629665"},{"one":"2880e0defd1bf2665bdd20dfb46bc0a9ad707f495211fc78e611ab479d78398db7daff7d3f4b6bf81fd13bf766ecc8271e0ea99a2d74abd2f9ddf98835ffdcf1","up":true,"other":"c206d8689068488179e86ce549de75989e0b17cbe09880d18fcf0fa212e629345f1b899203607a2b083569cb3f8398e501843166f5db23ac7fa7dacfe26dd3f4"},{"one":"877d17ec7e95998ead831606d3363fbff1c8d1fa377b8e621e6a876d2c7776b9af356211a7e4df66adeaf38cf9b49c04871e8804edde4c18435ff45e110ecb04","up":true,"other":"aa90454031068598ee39af5f1429c7a72277946d50ec2004f340406dbcc9f80cac505c9d9b071f85e2ccfd4b13bcf943f3cb9dd9f96f62d41352af9d8fffe7e4"},{"other":"c206d8689068488179e86ce549de75989e0b17cbe09880d18fcf0fa212e629345f1b899203607a2b083569cb3f8398e501843166f5db23ac7fa7dacfe26dd3f4","up":true,"one":"81dc656de121016bcde81d5bf7919839acfc180dfbf1a6de2cadf704ff13af98aa5715a4168832ca6f651b2ea7ad9e6ca5f1c1cb7e885dbc2eb23d4aefb87bd6"},{"one":"b58b3e200f6072ddb38130944a01d2829c755b8bd1a08abd010d1bbf86dabd851b2c1ab4cb961451bd7e8499f6c7378830bcd27cde825846654853c172597bf3","other":"d43bd6d3ae39a04e4e144a8a6f80b2d54472b5b9b6491dccf44b1716a63d24c56e3a871b3b8fe983d992988dc07ace06736ead3b1287914b629fcfe17e81f36f","up":true},{"up":true,"other":"8fb6838337f832445531764ddafc3c747b2607f2f33e244685d6de621c2b53264270f5504187e43b7fa5cda53e66dd00b16c06879c82fb38a3d9e8aec4060210","one":"2abb91884cc3a8fb91b2f2f369f9430f2b3b05c75ce6203aa7a50312c9f141f9d0f615063d3576a5ce8a4be9ecb942aa804a717f76d9e8dca03d115dcc43f775"},{"one":"8fb6838337f832445531764ddafc3c747b2607f2f33e244685d6de621c2b53264270f5504187e43b7fa5cda53e66dd00b16c06879c82fb38a3d9e8aec4060210","up":true,"other":"865dbf61d8511603fe0d9ebfb10792b9f6b798187c0909039bd9b2492c41e428876f386beeac86d0dea871f4fc24ba435f0fbd9a11e74c044024934592af14ee"},{"up":true,"other":"d43bd6d3ae39a04e4e144a8a6f80b2d54472b5b9b6491dccf44b1716a63d24c56e3a871b3b8fe983d992988dc07ace06736ead3b1287914b629fcfe17e81f36f","one":"bb0749de05a97daa67de889c15831ce39a080d641b3b08e3c248b0b16f4c07943fea8dd054d4a7e3e4af91ecff07053ce90096485a360b6f1d93050d179f30c3"},{"one":"af9b80f6836113aeda897d6903e9ffb4f7f1a706a7f821d0d40f03a0d83c18d6a19795ee4bfc1093ada04014415b1f230db1d2f056df3f5027cce71611588046","up":true,"other":"2cb076669efbaf2ff0b181a1b454061a31ef23937a40405022b126f0eb4bfba60c9e3397009d8c0ff0cabb603692532d0072c18c6838f43397c98483306f62db"},{"one":"81dc656de121016bcde81d5bf7919839acfc180dfbf1a6de2cadf704ff13af98aa5715a4168832ca6f651b2ea7ad9e6ca5f1c1cb7e885dbc2eb23d4aefb87bd6","other":"9bea5f82c2a390587de44d620d6637834e6f2329cd83d8df6305b03b75d9b543160b6c6f9f8887e6bc88f1d0726435d6c8ad813aadad0653b0790b8f6388413a","up":true},{"up":true,"other":"28cdd55fc871ffd8d63d05994be706959c9780dbfc859070a41047a1b40dd5fd7adb53919400a4c6f4d06c69bc1ecccc0e230e5b702598a7fe8003a282479872","one":"76643f67075c6e45bd176db19473240cda6f886d1cac25330e2d99c84a429934f4c6a606c9c72574d5eaccd0a3f1770dab05e6ff6a5b5ce4d7258fed2bc13d48"},{"one":"a5f7163586fce1750fd9a6e5c418af1c18ca6983069dcf1738fc9106ebf542a86e4ccfc50b45a0d97ca8681af8207128877f930f945e59ee262aa7f4014a01f3","other":"228b3646b15527f4df07b847a62dbf9620cb068f829e9086b5f437d0b64d8a027cab44f19db5e44189b5099545ecb25d49384c261748f9533cfb0eb11a1eca5f","up":true},{"one":"bb0749de05a97daa67de889c15831ce39a080d641b3b08e3c248b0b16f4c07943fea8dd054d4a7e3e4af91ecff07053ce90096485a360b6f1d93050d179f30c3","up":true,"other":"b58b3e200f6072ddb38130944a01d2829c755b8bd1a08abd010d1bbf86dabd851b2c1ab4cb961451bd7e8499f6c7378830bcd27cde825846654853c172597bf3"},{"other":"2880e0defd1bf2665bdd20dfb46bc0a9ad707f495211fc78e611ab479d78398db7daff7d3f4b6bf81fd13bf766ecc8271e0ea99a2d74abd2f9ddf98835ffdcf1","up":true,"one":"81901d9f043b4b1649ade3b5d22ae5f8bb42dd6db1eb37b836b99dd1c0388509ed4b54cc5638c9d4a6c5ae6c6913bbfffb303d7d94bf4ed50e871cf95459e2c3"},{"other":"c402495c2110a6531a530ebdcd9ab1b883f1c707fe25aa13a255a0a9edb4113669b4aee9eadf803f9fe4c2ef66d5e4dff7064549f672598410f2d9794747a600","up":true,"one":"2abb91884cc3a8fb91b2f2f369f9430f2b3b05c75ce6203aa7a50312c9f141f9d0f615063d3576a5ce8a4be9ecb942aa804a717f76d9e8dca03d115dcc43f775"},{"one":"3e2241cdb9f34c1d2c6930e59940e2c4b92b0287579d7263a620a609c5e66dca6d85df48cf1bffd63663a6704c42d0866aae3e484fd9a44b6a012f72dd3cef6e","up":true,"other":"3639f964feba681db9702cac3f02058f2e490fd7bffb217dc3480dc458decafd5955541fea89f0f6f14ee50a745eaf98b21363d6b4fb88c31bd32bf7845d524b"},{"up":true,"other":"20f6a8be1d2d8b5d6a43d851a2f5475385ef07fab80ac46525d0beccf3e25c01d726cfb3a1179e8343b1e88d21684fb24dd6e6497537d4e7e9edd59cb95d1b8d","one":"50c79baa3e6781482ccb5e960c699dd9c13f479467c6315c5292a396337cf3619e7faba1971a1f470051cb9042f80ea6750defe3936b72aac4d9bac6f8368c67"},{"one":"ecb93d8eba17afe92979e8154252a08dd58de6ff3188b6829e3e25967846686f54199ab2b081e77b0048dcab204f05aa2c5cbd0efae4bc43a612d471d4e1197b","other":"d7af0a0217ff98804aa05f8f926a8b6262363b5391d24cda8048cca5ca5982b407b7b098302d0db6d8dd9ac0883b2025b3de651617ed1a173181148295c6d336","up":true},{"one":"29acdd4c1233441bd40f98e245ecc9de94de6f9d0ab7c1a9923d833a2c8e6c1bd26d792686fec762b31fe28bbdd7aa04c9a594d997d08c133bb24cb2d877595a","up":true,"other":"6b7c94db790a2c1b903208904c4c75b66b17e7a00404727dbc7aeff404ac1118dc78ce4ca443f6b5245236f9e358c09b6da027ae1144e1a6682edca301176330"},{"one":"6909a0fa47718cfc463b1e96c21734b46bd5b28dd59cd3d66d67990783436b7538ab2659d427029b97c8dddf313b26532518c0c34a2b1fca8cd852b0fdb83ab8","up":true,"other":"28cdd55fc871ffd8d63d05994be706959c9780dbfc859070a41047a1b40dd5fd7adb53919400a4c6f4d06c69bc1ecccc0e230e5b702598a7fe8003a282479872"},{"other":"77e7d427b65b6c29c0d92c51184af73031bfa768a47fc20be6c264f422bf718865259c17c103bf47289b3abe62f93452781c6303d757e76d3d56ceeb26262fab","up":true,"one":"e8a679f627d03347a4fcec0a0940f7ffa90ce3fefea290db3af4f3a32d27965bfb51832b6a6de2495c8a8cc026bcf993b84a0cced778e158bb81c034f5e4bd76"},{"up":true,"other":"b183f12f3602bfdab0480cb0b0ba7dc69b267b0dbc7e54c316741cb78b9e99aa69fd321ad7755d095e9be14e6bd90fe14ef8fe9bafc1a0dea10a144795021a08","one":"7dd2801259c071a6e1dcc01d1cb74775fdec92da1da0b1eaf5f893cd5ed118894493ca5284c12bbd6cf7959449bc610d26ac6c9ef2845d1645d425f56ac003fd"},{"other":"2cb076669efbaf2ff0b181a1b454061a31ef23937a40405022b126f0eb4bfba60c9e3397009d8c0ff0cabb603692532d0072c18c6838f43397c98483306f62db","up":true,"one":"bb0749de05a97daa67de889c15831ce39a080d641b3b08e3c248b0b16f4c07943fea8dd054d4a7e3e4af91ecff07053ce90096485a360b6f1d93050d179f30c3"},{"up":true,"other":"ab13f773f6f2ff73032aa5f79c8897b75dda29bcbb14aa511e9401c2417dc9c510253071e28c7833c8d62fd2aef16fcd0c14ce016fbf4fec1b9a2173c717603f","one":"3e2241cdb9f34c1d2c6930e59940e2c4b92b0287579d7263a620a609c5e66dca6d85df48cf1bffd63663a6704c42d0866aae3e484fd9a44b6a012f72dd3cef6e"},{"other":"1e3a2f2491b6acb07a9549d9929d150479a0313c926b0e236237bd541303da4b563a855016a90ab50e59d94803ad566798570fa981464c94c04a4a4a94fbc607","up":true,"one":"5717a49591a0ecdff3d4449874d5ff9ba016afad5da19712ca0c8ebca8cefd84e6d8c778245f67f68c8dd730ad294fd017b8de279fde4fc919768ce85dba132d"},{"one":"7465fe601a9ad8e640069e6e07d56afabd3d4f008f3084f944d869b47fda3f511f191062802a53da511f60891dd0bcc5fac60254ef9db7aa3b41f5791b0b6975","up":true,"other":"46717bc5fb7fcbcdc961e7ef091020f9f222858cf3d4afcc0b0bb1b782b7055d9eb833e0a04cb32d80406133ac77162521c43edf9f9690872222760e31462ccc"},{"one":"3a2cacc430f13f31c52b7205455420cf0fb9ed9e28b0898b69ef97951bf295b29118e573a42dd97abe38fee5ab4c03dad9ff6dc448126cefc1da12b6c8e8d915","up":true,"other":"5717a49591a0ecdff3d4449874d5ff9ba016afad5da19712ca0c8ebca8cefd84e6d8c778245f67f68c8dd730ad294fd017b8de279fde4fc919768ce85dba132d"},{"one":"313a131ecb7d68e127d0fec8bb4a2e586886203c3d07857a93e7a39bb831703184d9ae28ba9ef3d986c2dae1a24f4f5bfa47cfc35f74f5512a126836364d7736","other":"90b8e73916046b5433dce049bfe125ca2bf2fb390ff7301f9bc5d8d0183988577aa2a7392aaa28091aa81c8ac23942b5751420b9ee48e488a68411f9d2b1e5d5","up":true},{"other":"baa28b8cb7ec539e0e157d7598cc5a5b0210fd8fb5c9026c3cd612133c5a8ee56997507511928af5683cb620fd85593dd8f6ff882d95fb847870ae4ce7dc503b","up":true,"one":"bdd17545242bedba1e4c36fadea95db655f8f220f10ae143084690a3c8d4e7ffb79a64af9f1bc8514addbd63695b2f20857e8d162f25318faac885f77b385138"},{"up":true,"other":"0c9a05514b96e7c3a0fbca21552e158faa70047246b230addca172a5023fd7439acd1c3a0b4f9191579b308dab38c961734ffdb36fb8e16383e912d070fc0218","one":"92dbb67da2b99a8fe46b1e510addc2b83e357ac0b5287b7ef5c1b1bc6e252b8dfd605a6896ede65848e429216d1f67d530d9e7b83ff14058aa2e5b6e405d6801"},{"other":"15ceb62ee0f53379aa202950634ed881ba3b7bd4b46c80723ee48190079311e24ffaacb167a126a40bd6732c384f3c26163aa043edca03cb52a97b6da189aec7","up":true,"one":"6909a0fa47718cfc463b1e96c21734b46bd5b28dd59cd3d66d67990783436b7538ab2659d427029b97c8dddf313b26532518c0c34a2b1fca8cd852b0fdb83ab8"},{"one":"10551c0c37abc25457903978868dd4843a52fda5f9b571b05ebd974d8c381fda4349f17c2b986a2e4b8d06b0517422f085d5f6d9cd814efa40e48393d9f71d7e","other":"682288e4dae2374c4784acd0b285508920ce39a6b72cc0e30a3dbb7972e0394a2bddd5ee5f22a1dbf80f284dde4d9f8ede7847318d5353566b35a83e212477e7","up":true},{"one":"15ceb62ee0f53379aa202950634ed881ba3b7bd4b46c80723ee48190079311e24ffaacb167a126a40bd6732c384f3c26163aa043edca03cb52a97b6da189aec7","up":true,"other":"876618c8ba66c1b91b473a154be3e10ded3590ba83d620d30e0ff1fbac2f31f258b1299a3da5b56aa03269a80c119b7fc41dfd87d5bd996359e4ad8dd0ab2a6a"},{"up":true,"other":"ab13f773f6f2ff73032aa5f79c8897b75dda29bcbb14aa511e9401c2417dc9c510253071e28c7833c8d62fd2aef16fcd0c14ce016fbf4fec1b9a2173c717603f","one":"1489ad735e1256900e4733707f8b78f1d853742a8f9b2d0c1c89651c60e7ee9d266afba5b4c1ed3f9cee05a1d2b2bba35dadb5b08973a93fd70dfb9e367339bd"},{"other":"bc0df855bdadcde3e447415444f655eb430925a8fa81cdcac75909e7d79750f01827938570e75e388cc7058ba8ebca47afadf8b07172bc078488fb618ba71024","up":true,"one":"869ca41ea1f82bec5f43807a3aaaabc39b21c62d3c9c8bdc0709683e22dd37cb2f3c313766809076d2c02d0d6171f4f32a1b5080abcb8072d88981042ae6237d"},{"other":"29619924833116cb1160bf7a8066a528b7182794368bfae62b5bacbae680d9161a479f217e30c3b4f19a250b1b59e08f86c94726117dc3bc94ff9ceac6bee6e4","up":true,"one":"77e7d427b65b6c29c0d92c51184af73031bfa768a47fc20be6c264f422bf718865259c17c103bf47289b3abe62f93452781c6303d757e76d3d56ceeb26262fab"},{"other":"865dbf61d8511603fe0d9ebfb10792b9f6b798187c0909039bd9b2492c41e428876f386beeac86d0dea871f4fc24ba435f0fbd9a11e74c044024934592af14ee","up":true,"one":"5a6318af8b4615cf30610a05ade7704182fefd0a3fb3d76c47cb392e114d8d30004f0ec214326b11532fd1e928e66f632bbcde126a94c87774063853a9518dc5"},{"one":"af9b80f6836113aeda897d6903e9ffb4f7f1a706a7f821d0d40f03a0d83c18d6a19795ee4bfc1093ada04014415b1f230db1d2f056df3f5027cce71611588046","other":"3f322f9b1f1f0692663bc3be11cf11386f4a14696aab610916cfcadf0234cce0c86b51c85ce2108e9bc21d50ad71cc10a6eeaec3fc7732908f3a8b193465a0ac","up":true},{"up":true,"other":"682288e4dae2374c4784acd0b285508920ce39a6b72cc0e30a3dbb7972e0394a2bddd5ee5f22a1dbf80f284dde4d9f8ede7847318d5353566b35a83e212477e7","one":"3b71a324bd7b1a8fb19d8206eea1ca8190cb1faf5fcd1bfc52cef6b52296fe1db3e54d70180133fad1fa1188499d0dd73d2d075fdc6b3ffd9042d690e7d88e02"},{"other":"fee3fa1ba2a051d40a582908384ee81179db6c2b5f4bfa58c24f8015b794b43a093ed68b69bb209684135f972a055a9845978fa1b7d489e2126c3b514297f1c2","up":true,"one":"97b1eaf8274ece76d75e7f60126f1b351ed5fe55088b9fcbb825a3a8d8f84f61bc72469916b280497dabf01345057525cae89da73c9a1a8a8cd19367d44dede1"},{"up":true,"other":"1e3a2f2491b6acb07a9549d9929d150479a0313c926b0e236237bd541303da4b563a855016a90ab50e59d94803ad566798570fa981464c94c04a4a4a94fbc607","one":"c0bec7375c66bec98524ade2245c1d7480516fc5d87a3249e64ec86418e80e202f1e3da76832e97bbc3dcaed8c96ca344e4829347b4428f4b1cb61999e404c05"},{"up":true,"other":"b87e7f36ed6bf142d48545024d2fd6e120c44511701e7c0b7d7fc786f4f29d3357024b15f70b78215d8a4c2b7572d608c11b31612743e23db4fa673f0cd6519b","one":"4116fbb7d55bfd4bd8db9cbfa570ac361bb88605b6aacbf84e245893cf3fa599ecc086688a4c534c81f61a90fa344ca37e4d4013ddc03f7f08218724a55f66b1"},{"one":"e1f23e1caba66f5ff821edbc4a3d527539937f73d86dd0df43aa1266a99f51f2480a77961eff177fbbf852fc52cb9317179f80b1580194daaedadc3b00510751","other":"9309549fc50173d6826fe63cf18699f49199c3789616b843042fe1a6adab6ed4bdd7a7a06acd276e0398cf8bffb26c12a4227725d7bbd386a9a55fc601c21405","up":true},{"one":"c0a2c08fa8b70ecbf1932254945d5f689b0da7a287019d384152f383f6229acd4d82eef26205bc12e062dae4569814bd1c996ee4fe5886bd6bdd93c4f0ac113a","up":true,"other":"6b104eff1dcf58d11a7f707bbd41a910b2735b262c29e0f4e4127fda1b67def4e89b6ebc1b3cc1e06c3968d0898e1085badc7da24d3cd6624cb100e85863cc97"},{"one":"723f362e98f90d7ef15e24e353759fdbdabb08adab767dba73ab546741fac3dfb457466f1e2c851aa49526da1408f8ddb509e12f7dc0bc1e785c5b72be8a986e","up":true,"other":"da22fb43c6d230d92f9c09454e282dc45dffc759740566039f1bdfb58171c6801f721841de83217277b3fb70983e7d34da53bbf25d1d45413a78d9afff151826"},{"up":true,"other":"3b71a324bd7b1a8fb19d8206eea1ca8190cb1faf5fcd1bfc52cef6b52296fe1db3e54d70180133fad1fa1188499d0dd73d2d075fdc6b3ffd9042d690e7d88e02","one":"4116fbb7d55bfd4bd8db9cbfa570ac361bb88605b6aacbf84e245893cf3fa599ecc086688a4c534c81f61a90fa344ca37e4d4013ddc03f7f08218724a55f66b1"},{"up":true,"other":"20f6a8be1d2d8b5d6a43d851a2f5475385ef07fab80ac46525d0beccf3e25c01d726cfb3a1179e8343b1e88d21684fb24dd6e6497537d4e7e9edd59cb95d1b8d","one":"9ea856ea440c776b9ffaad1237ec11d570a1f912a908b8363ff97cf7947d2523e3c73663240d8fac988698cdd81e877ddd4a609485fe9f26494136fae14212df"},{"other":"49256eccce3e036928a4b6b346126c6777dca5ea0134de85efca340f97ad0f827f3094f1562e3e186d35b8292a50c20ffae01409890bbb78598494285e14dc2c","up":true,"one":"bdd17545242bedba1e4c36fadea95db655f8f220f10ae143084690a3c8d4e7ffb79a64af9f1bc8514addbd63695b2f20857e8d162f25318faac885f77b385138"},{"up":true,"other":"77e7d427b65b6c29c0d92c51184af73031bfa768a47fc20be6c264f422bf718865259c17c103bf47289b3abe62f93452781c6303d757e76d3d56ceeb26262fab","one":"7cc9389c8f751465e0b94baed896f6f122631052300b1b5b23d3c7656e4d11014a7a9ae62a1287bb040ca37221871a566cd470e523846df7e3acb5f94c7cde06"},{"one":"7958d1517de1223e7fb30acf61d8618e49fb95a03bc2f49141f4c7967bc80b90e0dd526c205639de3c060029963d43813293c2556f7b127945c798f3f9f18626","other":"77e7d427b65b6c29c0d92c51184af73031bfa768a47fc20be6c264f422bf718865259c17c103bf47289b3abe62f93452781c6303d757e76d3d56ceeb26262fab","up":true},{"one":"c0a2c08fa8b70ecbf1932254945d5f689b0da7a287019d384152f383f6229acd4d82eef26205bc12e062dae4569814bd1c996ee4fe5886bd6bdd93c4f0ac113a","up":true,"other":"3e7aef8260c0d9717aa59b65ce7c554e53b81f19f5b9400321704a7ddf5041b0fe31b5634e90b93e6984060defee0e153997bbfe196166cc8d83165fd5eaf41f"},{"one":"9bea5f82c2a390587de44d620d6637834e6f2329cd83d8df6305b03b75d9b543160b6c6f9f8887e6bc88f1d0726435d6c8ad813aadad0653b0790b8f6388413a","other":"243164c4dd583f80c50813f43e5c27c894463400cd3afd776b36e79e7123d9261f01f06f92914aab83096b9a43fb655e79687590599284640a3a7d2c25454597","up":true},{"one":"33e9d4674b5b9b23e838583f01b429abca1330393dfc100b19ede6090a53df213011fae53169a66aa05d18e4cb497a17aa81eaedf1fe2e4348f9825c309438b5","up":true,"other":"fee3fa1ba2a051d40a582908384ee81179db6c2b5f4bfa58c24f8015b794b43a093ed68b69bb209684135f972a055a9845978fa1b7d489e2126c3b514297f1c2"},{"up":true,"other":"46717bc5fb7fcbcdc961e7ef091020f9f222858cf3d4afcc0b0bb1b782b7055d9eb833e0a04cb32d80406133ac77162521c43edf9f9690872222760e31462ccc","one":"8e5e8366251e33277e7db6f6c04629b2ce3eee217e973acb97c83773671b0160c40732794584db741a29a763672b90f3bdf34151fd4a6986b9d0956dc61d9723"},{"one":"e0875ed6be1e163b15c13cdf37442f838670d0949349ee9ff119a0451beffb1a302943ee9d7cba48592922f64908aeb0f39f6e2e3725d1e7cdc5db34083b6977","other":"57085f756f76644cdd2148524f2334d869ef0ab2fcbe7fb11f5d22bc1f5023165b11526ecc85ff9cbb88877386af9b148d7ef15a825b3a586d16c01bdfc86692","up":true},{"other":"dd6acfd151220f21b03701ca554a5e134dbd1154dda21d9eec45809e7858fe83eca3953fc688f499030198f22052c3681a9f49207ef9b11a760456ab9637352b","up":true,"one":"11e9729700f5046b47d5e4521630cb57408f59a3337ca7db7984477a16c1f3b90c1d8d1f8d6a3f2a72e35f373fa73ec47a5636b36e40b2fb83756622a08896b8"},{"one":"52cf04f88d8b00214f11f329ebacca69291958372aa8ccfbe3cfdbc03d51d90389f3c307b82c108f0c074d78aeac0b48e8b8c8f3bf3b20b21d9747f284075de2","other":"c0f233e79d0a8d4af01f54c40640975bc113f464271ba8922fca0c28acc60367af0db06629e701977e86cb5917c891e39c21418cab459fe49132b680aa31600b","up":true},{"up":true,"other":"c0f233e79d0a8d4af01f54c40640975bc113f464271ba8922fca0c28acc60367af0db06629e701977e86cb5917c891e39c21418cab459fe49132b680aa31600b","one":"8ee65c0937cdf860d5329132c34bf28b5dc4d2593986fae80e4b35efb54ec24cdbf294223515363a917a22dbc6db463c10c7484e22b479b9010059c2521b6317"},{"one":"5717a49591a0ecdff3d4449874d5ff9ba016afad5da19712ca0c8ebca8cefd84e6d8c778245f67f68c8dd730ad294fd017b8de279fde4fc919768ce85dba132d","up":true,"other":"c0bec7375c66bec98524ade2245c1d7480516fc5d87a3249e64ec86418e80e202f1e3da76832e97bbc3dcaed8c96ca344e4829347b4428f4b1cb61999e404c05"},{"other":"1e3a2f2491b6acb07a9549d9929d150479a0313c926b0e236237bd541303da4b563a855016a90ab50e59d94803ad566798570fa981464c94c04a4a4a94fbc607","up":true,"one":"c61ffc88f23f9f536497cc10ffcb7000ec6c4b801998ae7075ddc9079fdc1da8350e68744dc9e95ff892dfc5e52c62a3ad913a87fdacc455aea99b09aa002b57"},{"one":"29619924833116cb1160bf7a8066a528b7182794368bfae62b5bacbae680d9161a479f217e30c3b4f19a250b1b59e08f86c94726117dc3bc94ff9ceac6bee6e4","other":"99a7649bdf2ee7f0bc049308b0997e33abb68481c05a573df9aea30da5a1f267df07b2c584e3e985baf31704f04ad2a2c4876e0f8555333be6d09f5080b583f1","up":true},{"one":"c0164fb4a1acfb4f3b1a09f9f3ab226c382529a73891937c6f3c91798098cf10b909eb92e5f8acfe0e8f3aee0b71cb23ee2d9e6ad1e0f4492a0272c52d529849","other":"baa28b8cb7ec539e0e157d7598cc5a5b0210fd8fb5c9026c3cd612133c5a8ee56997507511928af5683cb620fd85593dd8f6ff882d95fb847870ae4ce7dc503b","up":true},{"one":"2cb076669efbaf2ff0b181a1b454061a31ef23937a40405022b126f0eb4bfba60c9e3397009d8c0ff0cabb603692532d0072c18c6838f43397c98483306f62db","other":"228b3646b15527f4df07b847a62dbf9620cb068f829e9086b5f437d0b64d8a027cab44f19db5e44189b5099545ecb25d49384c261748f9533cfb0eb11a1eca5f","up":true},{"one":"2cb076669efbaf2ff0b181a1b454061a31ef23937a40405022b126f0eb4bfba60c9e3397009d8c0ff0cabb603692532d0072c18c6838f43397c98483306f62db","other":"8e8614a4c2ee2b1a3fa5ace0ca353cff36b3de3308ccf53665b8b56f8e2456a8a65f3846d786dccd68b1bfcefdd170ea5f8edb481800b1ce72d9fce2added7f0","up":true},{"one":"643da2591098f9698f27cccf7c17832e0717ee6a1276398a1a29edc947125585dcfab9417c2721a8a55d4dfc75b826be7581b6e30b020f6341ac549877c9f122","other":"212a8048ab9925171475e81dce047865df186222d673d524c810a9f613e4a21f3b130fa34c5f44974fbeaab1f6028177e71568e00a1184d9fd05443c172f5fcf","up":true},{"other":"c2a9c77247871cfa4d3c2d1b47619df91ed5b331a44c8e21f7c9ce431a4db9dfb87713558cc8a37911393907b4cc60be9445bad18adcea1bc5f318256e71be14","up":true,"one":"154d5ddb15ec12dc65362039d801383c189b5bcf6688883f2d7e3d0e8dc78e45f9f58d5dabc79a8798a243ce59abb95c77525db14f050fd8cb37d04b7276557c"},{"one":"154d5ddb15ec12dc65362039d801383c189b5bcf6688883f2d7e3d0e8dc78e45f9f58d5dabc79a8798a243ce59abb95c77525db14f050fd8cb37d04b7276557c","other":"fc9b1b2bbd5e682eb350d23f3ee33b245495daedae9370de7b1f55f91cd45db831d196c17615e11decf6b67696a268ac788130e3de38c7f6aeae811f3ec8c8ee","up":true},{"up":true,"other":"fc9b1b2bbd5e682eb350d23f3ee33b245495daedae9370de7b1f55f91cd45db831d196c17615e11decf6b67696a268ac788130e3de38c7f6aeae811f3ec8c8ee","one":"6a37e63feed9e68c52cb8b385d5e8d8dbd2b211c57ded0d3b01fe8b306af5c0e5a7405d0d9a942648f0131926240d53450bc43f922a053528e5830d918313c3d"},{"one":"c674c405068bb908312917a319e24ddf90e814ee8ef54bbf740f176b2a7eda6950e3e1ed69484ebcc27b13d82c7f0b20daba71a17700018e769ca612ca8d2208","other":"e5cb29b25debcfaaacc0b04e708c8c1cb9d2dee29e82596a1c72a934032cf738800b9525cc277d0c5f5dacf2f278329b54da161b4bafa285243fa0e9fd7b2f3a","up":true},{"one":"45d3827eb5c3b906fc61aaad79c5968f3dcf7b1ecc1e3be63e827ad6fb9291542686f42b3e142f43cc0437a2177b7362727842ea1d6c33bc795d936bba3ae457","other":"76643f67075c6e45bd176db19473240cda6f886d1cac25330e2d99c84a429934f4c6a606c9c72574d5eaccd0a3f1770dab05e6ff6a5b5ce4d7258fed2bc13d48","up":true},{"up":true,"other":"d7e3661c0af6754c875217f93d34b254f1f45fc1359a4c6146cd0efa4c6e12aed9a4fb0a21a136f73af4fc2c6d0a63cb809d81855bbc9f51e29d23d90f77b326","one":"1cdef98d7b4de45c902c725384bd14c66084fe4159b26a0f9a24f432e1f561d035ca41e1c60fe64f3213b4f91a1afb953193dca1a7d535be0602b5d046bcbab8"},{"up":true,"other":"28cdd55fc871ffd8d63d05994be706959c9780dbfc859070a41047a1b40dd5fd7adb53919400a4c6f4d06c69bc1ecccc0e230e5b702598a7fe8003a282479872","one":"d6a7257771baa4d9944592ead46b8ab700dbf91ebd4dc0ec7e5fb41cbda0622944269172fcec8352b89ef2c186d4c787af2b45a50533f627a97818477de034b4"},{"up":true,"other":"b152eb30c9f46ec39166016f03d289f98cc285ac62d204da32e5a003da14e4f02c64df8ae1d0c8a2a902adc5f7dd7604081a0b140c9b64052082f0861945f5a4","one":"7465fe601a9ad8e640069e6e07d56afabd3d4f008f3084f944d869b47fda3f511f191062802a53da511f60891dd0bcc5fac60254ef9db7aa3b41f5791b0b6975"},{"one":"43086ff7ffd3c7bdec77bd288f41f1ee0ce21bd3f60a5df8931e2af6e7af5ef0fad432d29625491935d11567944351fc7867c807ebd12dd2c21c9e620ae0f85c","other":"77811b007dd1fc1b11e447858df37062e97b6fc14e059399814f3b4736188e3fb28bf7c3958bb8ebc6ae16c36884ba7c98b810fb6f8b358323412123c803abd4","up":true},{"up":true,"other":"c674c405068bb908312917a319e24ddf90e814ee8ef54bbf740f176b2a7eda6950e3e1ed69484ebcc27b13d82c7f0b20daba71a17700018e769ca612ca8d2208","one":"a5f7163586fce1750fd9a6e5c418af1c18ca6983069dcf1738fc9106ebf542a86e4ccfc50b45a0d97ca8681af8207128877f930f945e59ee262aa7f4014a01f3"},{"one":"eb6d41d8d96f1933dff017d5fa0c46c6d0bad5d273b7c321a12858ac90ec00fca6191d29419897d2e25ec2d8ebd8c6a81bbde2d3f266f842e64b2b822161f1ea","up":true,"other":"3948a7a939b9a1f4201953bd9b955ee7be87d09b63c7a45167f556ac06fe3c4c2a75d935bff50668da5e71e46802b55d7a9945a92d7807c00625d129cbb48f82"},{"up":true,"other":"d6747e1f8594f7449fc6d7c0e63ee843480567d498db096ff04229420861c83bca5215fc19d8fede0c54484f111f1f2581e189e638c21c5d9e1fd3174bbb3e98","one":"60995852a2385ce8d7d24dc94b85a2f0dab6e5c32e910dfe367ea9c6ccb7b0b2eb611fdf120f8c697097e2f137cefff42e8d9db16b664a857a38c5ace837ffa4"},{"one":"e7b2adabc2c99ac47b1e94fc0a2c63a00a1d622ea67a4c1858f4cec93fca957d43d8429605761bdf5eed4f733dac1a3d12fb928f22abf248965994acde63864a","other":"89d46e664ac471c7150fbfe43a49c98750fc64d5ca22fdc2a040c7ab78c25c48c1e9c2f0e5130d6b8eb7f0760fe962759d83f68cc08ffaac3520499b0ce694de","up":true},{"one":"ef7157fdfe62390d8a6d4ef976478d17465b42b63fddb03664973d63efb62318a8f59e412150528a32aa2c028b9de6bc67f05e012b8c43d710032ad871bc27e5","up":true,"other":"d09104c44648391693ca64a57baa5ef54ed717e19c65ad0a0921d08cbaca8877d0190795d15f75f3b6ce6e676d6b0e55d5ee8fec3310c68b7060a32f7ff649cb"},{"up":true,"other":"89d46e664ac471c7150fbfe43a49c98750fc64d5ca22fdc2a040c7ab78c25c48c1e9c2f0e5130d6b8eb7f0760fe962759d83f68cc08ffaac3520499b0ce694de","one":"222d7a2f94dc82a09fda70b8195fc3a60433a90f53998872318c57625c528c90572d78b444ac4901dcfece1a03ef8b6cbe7845366a845a942f341f6db58a9b3b"},{"other":"3b71a324bd7b1a8fb19d8206eea1ca8190cb1faf5fcd1bfc52cef6b52296fe1db3e54d70180133fad1fa1188499d0dd73d2d075fdc6b3ffd9042d690e7d88e02","up":true,"one":"dd6acfd151220f21b03701ca554a5e134dbd1154dda21d9eec45809e7858fe83eca3953fc688f499030198f22052c3681a9f49207ef9b11a760456ab9637352b"},{"up":true,"other":"f5d95e0c5a873ff5a95e1eb34f1ed258d77adf98ee0886d93c4a24b1feaf6955e6e4c4ea0eccb2b9723870bae61e693643d6ad96dd8da01672542611f7c49069","one":"2751df9f64a8f2ff8ea45efc9bd02b281d963ced285260bcda7f9dfaed998fe4386fe65a7265876da6b4fee77ea5c12454869a70ad627da7ca888076fc629665"},{"up":true,"other":"52cf04f88d8b00214f11f329ebacca69291958372aa8ccfbe3cfdbc03d51d90389f3c307b82c108f0c074d78aeac0b48e8b8c8f3bf3b20b21d9747f284075de2","one":"2b0a1f3a6466c6be1d7e84120db384fa37f7c73a01e9a105ae90e7d2203212ec974f016d3012afd26bc0f9a8411d0716cc59b6ecc9f665db12e306af8b34cb63"},{"other":"e323da6ae861cb092543992b8985639f9b3bcaf1c3c68757f4603a67800be62950fe7d8f8ef80eb83a18107b677c7f5047ea89a5790e0ea2a7969f4856d28488","up":true,"one":"7db14fde1da8794ae7ab5de37c9e2537e1024bc830c176c0d01635cafed47773d3a28e156db81ecdb95903222b900c3ebd4c4b3db2971dc0ef6a1e386027ffaa"},{"one":"c0f233e79d0a8d4af01f54c40640975bc113f464271ba8922fca0c28acc60367af0db06629e701977e86cb5917c891e39c21418cab459fe49132b680aa31600b","other":"e0875ed6be1e163b15c13cdf37442f838670d0949349ee9ff119a0451beffb1a302943ee9d7cba48592922f64908aeb0f39f6e2e3725d1e7cdc5db34083b6977","up":true},{"up":true,"other":"99af34b172d319633e07a4e528f416024653a230a9103a4b281171f75bb697dd6be4757558c94e86210b4da8d9fe1229f6a5d8c4174989ea0ce696f8d1a9995d","one":"3e2241cdb9f34c1d2c6930e59940e2c4b92b0287579d7263a620a609c5e66dca6d85df48cf1bffd63663a6704c42d0866aae3e484fd9a44b6a012f72dd3cef6e"},{"one":"50c79baa3e6781482ccb5e960c699dd9c13f479467c6315c5292a396337cf3619e7faba1971a1f470051cb9042f80ea6750defe3936b72aac4d9bac6f8368c67","other":"4ff2981a47da46c753090e193a8bf43c3372a6b07a37cf0552de2ced455fbb8a76d969cd97b3e4601d8a808bd2a73f7729ed8a61df2f2a0c2cee1425d0bd9ab4","up":true},{"one":"ea2921612b827e3c26328368bed9be7cbf1f2b2aecaf31863c9cdccd74c56b651d6eaceb8ac9609a6653488837ded310df91e53a74789ae75cb841e2aeaf96df","up":true,"other":"682288e4dae2374c4784acd0b285508920ce39a6b72cc0e30a3dbb7972e0394a2bddd5ee5f22a1dbf80f284dde4d9f8ede7847318d5353566b35a83e212477e7"},{"up":true,"other":"4ff2981a47da46c753090e193a8bf43c3372a6b07a37cf0552de2ced455fbb8a76d969cd97b3e4601d8a808bd2a73f7729ed8a61df2f2a0c2cee1425d0bd9ab4","one":"fd0123c7b96004067e98e463e273de5bc5402399ae70a95985b5f682e30d4f35d070deaf8c71d201e98c4324d832b95aab7535ad8a2658f66e3e0bb1202204e1"},{"one":"1489ad735e1256900e4733707f8b78f1d853742a8f9b2d0c1c89651c60e7ee9d266afba5b4c1ed3f9cee05a1d2b2bba35dadb5b08973a93fd70dfb9e367339bd","up":true,"other":"b9c7b885430b9b1a4425bde30b3629559f5437e0e30a0299fc6f6e097cbcca8af9e285caf5dea685a0237f60e06f490c39a1e3e487f14a2b9f41a5135f2ba994"},{"other":"a8fac88fba179fb9b259d94caac9cbe45d873a0131bef8844ac4383b177daf6f301f8793623fec5876885db1a91e5b3e98e2aafdaa47e03b1f6d9740f48af7ac","up":true,"one":"92dbb67da2b99a8fe46b1e510addc2b83e357ac0b5287b7ef5c1b1bc6e252b8dfd605a6896ede65848e429216d1f67d530d9e7b83ff14058aa2e5b6e405d6801"},{"up":true,"other":"9309549fc50173d6826fe63cf18699f49199c3789616b843042fe1a6adab6ed4bdd7a7a06acd276e0398cf8bffb26c12a4227725d7bbd386a9a55fc601c21405","one":"ef7157fdfe62390d8a6d4ef976478d17465b42b63fddb03664973d63efb62318a8f59e412150528a32aa2c028b9de6bc67f05e012b8c43d710032ad871bc27e5"},{"up":true,"other":"c03ef1de42d522b44eef53be11f2c57b8b74fed9e87e6c2928c1feb48ddfecc67e1a3a8c8be1c47b3735a216d7054e2a4dda49fbd9a1ac702146aae5bdeced7c","one":"d6747e1f8594f7449fc6d7c0e63ee843480567d498db096ff04229420861c83bca5215fc19d8fede0c54484f111f1f2581e189e638c21c5d9e1fd3174bbb3e98"},{"one":"2b0a1f3a6466c6be1d7e84120db384fa37f7c73a01e9a105ae90e7d2203212ec974f016d3012afd26bc0f9a8411d0716cc59b6ecc9f665db12e306af8b34cb63","other":"8ee65c0937cdf860d5329132c34bf28b5dc4d2593986fae80e4b35efb54ec24cdbf294223515363a917a22dbc6db463c10c7484e22b479b9010059c2521b6317","up":true},{"one":"7db14fde1da8794ae7ab5de37c9e2537e1024bc830c176c0d01635cafed47773d3a28e156db81ecdb95903222b900c3ebd4c4b3db2971dc0ef6a1e386027ffaa","up":true,"other":"c69b9b181b2756a1345b73a97afb3dca909c253188c3b905f0b414465b750d2ffccb4c8e8eb5e3809549af55db473f3b12682f9bd97c5c75d68f23d67d91b866"},{"one":"81901d9f043b4b1649ade3b5d22ae5f8bb42dd6db1eb37b836b99dd1c0388509ed4b54cc5638c9d4a6c5ae6c6913bbfffb303d7d94bf4ed50e871cf95459e2c3","up":true,"other":"51df4f4d4f020f22f55a5fd00c7f9c68c232c167ae4d4e80d7695f8f39c5aa0a7b565c1c55bdd6a21e06fa056549d08fd2e9d76fd79e21295557aa30d1ae022c"},{"up":true,"other":"6ad4ea3730ddec500e56248d1025aea79ec10f0d6a9720ee48026df10e219b41965d7a611fd99ee765f6afbc8c977db7e67c3a340881904acb983d1e2fb016cc","one":"fd0123c7b96004067e98e463e273de5bc5402399ae70a95985b5f682e30d4f35d070deaf8c71d201e98c4324d832b95aab7535ad8a2658f66e3e0bb1202204e1"},{"up":true,"other":"6a55b94c9990249b24cdbeed96f065137f7b79ea8ee5f58da150d3962dfb62ba401960a53e7e8bd4e2c2908aa1a59b9d5efb4aafb316a9ab4fa67a0d95b58c54","one":"85c0b055439f114dee5eb0961013c117a48d62b0f17c61a7fd92a84092ef09bb3bbce686aa96e14528d5663565c57d657fa9813b1f38e268caeb1cb0842ef232"},{"up":true,"other":"a58a4db7a96b1578935b222c78b7b4dd8b3519d2995c3616e5a154c5175242a503097771332504638a0b321b9574110207f9a7d77b109d1de3d66a12ec6498e5","one":"1489ad735e1256900e4733707f8b78f1d853742a8f9b2d0c1c89651c60e7ee9d266afba5b4c1ed3f9cee05a1d2b2bba35dadb5b08973a93fd70dfb9e367339bd"},{"up":true,"other":"c03ef1de42d522b44eef53be11f2c57b8b74fed9e87e6c2928c1feb48ddfecc67e1a3a8c8be1c47b3735a216d7054e2a4dda49fbd9a1ac702146aae5bdeced7c","one":"c6ad9b9de5cdbe28540f4eb7c66fb37f6d4295e6e60c6de54e2a45c1970b8e0047558e986bbd10e9e86c8bb0407846fac4823e4570e8a1486fc4bf55cb4a0986"},{"up":true,"other":"69f999937943be00e5fca5c7cc942ce13b6752a72813368da2fbfcf74ad807bc6edd85537e087b6f73c0469c7b76a5d8f7d883bd315f3b35af32b8da293ed243","one":"8e89fe4b3fffea8af247d2581aa511056efbeb796058d50a341d57aa0f7ccc2192d90cfb8d18558363df798567faaddb86815e8bd671b36ca37af0651535aabf"},{"other":"69f999937943be00e5fca5c7cc942ce13b6752a72813368da2fbfcf74ad807bc6edd85537e087b6f73c0469c7b76a5d8f7d883bd315f3b35af32b8da293ed243","up":true,"one":"a8fac88fba179fb9b259d94caac9cbe45d873a0131bef8844ac4383b177daf6f301f8793623fec5876885db1a91e5b3e98e2aafdaa47e03b1f6d9740f48af7ac"},{"one":"3f322f9b1f1f0692663bc3be11cf11386f4a14696aab610916cfcadf0234cce0c86b51c85ce2108e9bc21d50ad71cc10a6eeaec3fc7732908f3a8b193465a0ac","other":"c63b88f494b14d5a7c1da124ffebbd985d19806b91d4b111c83ae129c4ef19614469980a09fbeccebe3b0358dd16194bdb6452d0b3dbb43a5467e23bb13f40d6","up":true},{"one":"c9d705012a06d82c4d44db95b4f1c63ddd33ad64d732e96b1d878caa0caac433d4096f01495a6f0e8a56af122b0470fd745db6d906353b590a4710472b93f5b2","other":"e0f13606a7f35b9ad8a9c4e70336c4c554ac718720a451a349eb4e1a4b055079483cac040ec64e0ed3d8bdb336618a5ae6ef74e31642fae4d7ed9949858eb361","up":true},{"one":"3e7aef8260c0d9717aa59b65ce7c554e53b81f19f5b9400321704a7ddf5041b0fe31b5634e90b93e6984060defee0e153997bbfe196166cc8d83165fd5eaf41f","up":true,"other":"a5f7163586fce1750fd9a6e5c418af1c18ca6983069dcf1738fc9106ebf542a86e4ccfc50b45a0d97ca8681af8207128877f930f945e59ee262aa7f4014a01f3"},{"up":true,"other":"2cb076669efbaf2ff0b181a1b454061a31ef23937a40405022b126f0eb4bfba60c9e3397009d8c0ff0cabb603692532d0072c18c6838f43397c98483306f62db","one":"3e7aef8260c0d9717aa59b65ce7c554e53b81f19f5b9400321704a7ddf5041b0fe31b5634e90b93e6984060defee0e153997bbfe196166cc8d83165fd5eaf41f"},{"one":"dbb6621460b054f584f1c6157b4020f3c58d84c3a12b57436e10525ae60ab27036bf3edd68b92f2b13674877d01c2871dc67a9031c3d0470985f4b071696346e","up":true,"other":"e0f13606a7f35b9ad8a9c4e70336c4c554ac718720a451a349eb4e1a4b055079483cac040ec64e0ed3d8bdb336618a5ae6ef74e31642fae4d7ed9949858eb361"},{"one":"d09104c44648391693ca64a57baa5ef54ed717e19c65ad0a0921d08cbaca8877d0190795d15f75f3b6ce6e676d6b0e55d5ee8fec3310c68b7060a32f7ff649cb","up":true,"other":"8e65496318637446a51f0dc87d0a5cf82655866cd1579db1e381af52e12545172b9c88119999ccac3b8b8644efc9675ff183ebe7584c16eb40792cc21f7e9b76"},{"other":"70cce7cb0c18091dbb6d41160ab560935f1759b969bf8118cee030ee707cb15ba407b8c48dcd9fd012cbf778e219f7d16a74064b4983cf098fb118297748edb6","up":true,"one":"97b1eaf8274ece76d75e7f60126f1b351ed5fe55088b9fcbb825a3a8d8f84f61bc72469916b280497dabf01345057525cae89da73c9a1a8a8cd19367d44dede1"},{"one":"243164c4dd583f80c50813f43e5c27c894463400cd3afd776b36e79e7123d9261f01f06f92914aab83096b9a43fb655e79687590599284640a3a7d2c25454597","up":true,"other":"1edeb91789b9aa996fea7a70964e0be33ee50acbe6d8f7d9d9fcf6dcf755dab6402637a610116f0eb716b19259429bdcced8bebc28ffa334387a430efc21b9b0"},{"one":"85b6404a76b4762156c8ddd2f312763dfe19b315d914533844cf229301880c57ffeadc0eb5f4a8d542e1d9fc961dfb5a572d2101172b1a0fc238ced05ba49ec1","other":"8ee65c0937cdf860d5329132c34bf28b5dc4d2593986fae80e4b35efb54ec24cdbf294223515363a917a22dbc6db463c10c7484e22b479b9010059c2521b6317","up":true},{"other":"aa2028d356a88eca8e0fcaf218d62ace099c3f72dfd95bb28f30ac9a926034cf1d60a40511f7495652745de80d71c0f6830019e206c88e2b6ef0cf4f05d7fe9e","up":true,"one":"02fdbcb00f20a3f6e894900d798fcb0aca9e21f5b107924c0999eb396220f16dee99fc80ccba796e66e69dcb9ce278b7e0e4539c7a7cd0fbc1037bf8e56c1e67"},{"one":"f98c0f4444a1ec80773454ddb691c226b81d8e2f79ed40c45a422d3359565edf7bd635d3eb7bd6c9e0870746849fb86f0b1b34cd56ec8d3ad969812e080f4983","up":true,"other":"fee3fa1ba2a051d40a582908384ee81179db6c2b5f4bfa58c24f8015b794b43a093ed68b69bb209684135f972a055a9845978fa1b7d489e2126c3b514297f1c2"},{"up":true,"other":"d7e3661c0af6754c875217f93d34b254f1f45fc1359a4c6146cd0efa4c6e12aed9a4fb0a21a136f73af4fc2c6d0a63cb809d81855bbc9f51e29d23d90f77b326","one":"a58a4db7a96b1578935b222c78b7b4dd8b3519d2995c3616e5a154c5175242a503097771332504638a0b321b9574110207f9a7d77b109d1de3d66a12ec6498e5"},{"one":"58f9139905ae1d005950f110b7ead3355672ecc478e8c66393566c64b935003f6fec3031dc9eb21cda660acb1955cf7bb33a20fdd74d493f29868ace328fcd75","other":"ee0b09ee6a1057c47102e582e2fdec7b9212802e59f062a9360da0db535d4987126ab24848c0d76fa8485431a5140307e2b0c0d9f37cbdb35756e6cc1bdb3bc0","up":true},{"up":true,"other":"1489ad735e1256900e4733707f8b78f1d853742a8f9b2d0c1c89651c60e7ee9d266afba5b4c1ed3f9cee05a1d2b2bba35dadb5b08973a93fd70dfb9e367339bd","one":"d7af0a0217ff98804aa05f8f926a8b6262363b5391d24cda8048cca5ca5982b407b7b098302d0db6d8dd9ac0883b2025b3de651617ed1a173181148295c6d336"},{"other":"f8a5ae50e5b2d84096c10a6a8493a9eb8113df64c4f1336c0cf4649302649b158fa4cb7941591e55356891bcc1008a535df427546af19988a241c5f466467963","up":true,"one":"842f0ac24370f14edfe72a7d07219de60fc767d2d0356fa6ce9d535a43647ad4bb17d9be75ed83542868ba430ec104ba168f27c16915cdbd6e57ae62d60707cb"},{"other":"95ff4dea07303e1ba641a5c510e714ef232f4dbce9ad2e8b2f62644975eae41fc4bb9d1af3fae4d5ea4daeb18f8248e0b3131c7d843d35d33f3afbf7dfa4c2fe","up":true,"one":"362ed9a92b588d5fe315b90a74aa27f7600e4a7d06b27ceb26272340388d916a831df85bf83450ef80bda4e4a21acaac60560c8a42940a26e2ac567519e2a202"},{"other":"e903d7aebff96a6afa4b9dd19b0b02e5af18da8e4e89f64247e1a2c2d46637538c741182eac67f45ec61be76aeaccde57f0a0184bd608ea7d92e586d4f827ea7","up":true,"one":"c29e80096fbe7bc9fcbfdbe3cf6c06449192a3ed280e46a1fa5d424428d893c3456c985c1352c119236cf783834365439751cc87e7ed196614705dd3db6674cf"},{"one":"865dbf61d8511603fe0d9ebfb10792b9f6b798187c0909039bd9b2492c41e428876f386beeac86d0dea871f4fc24ba435f0fbd9a11e74c044024934592af14ee","up":true,"other":"c402495c2110a6531a530ebdcd9ab1b883f1c707fe25aa13a255a0a9edb4113669b4aee9eadf803f9fe4c2ef66d5e4dff7064549f672598410f2d9794747a600"},{"up":true,"other":"3e2241cdb9f34c1d2c6930e59940e2c4b92b0287579d7263a620a609c5e66dca6d85df48cf1bffd63663a6704c42d0866aae3e484fd9a44b6a012f72dd3cef6e","one":"212a8048ab9925171475e81dce047865df186222d673d524c810a9f613e4a21f3b130fa34c5f44974fbeaab1f6028177e71568e00a1184d9fd05443c172f5fcf"},{"one":"212a8048ab9925171475e81dce047865df186222d673d524c810a9f613e4a21f3b130fa34c5f44974fbeaab1f6028177e71568e00a1184d9fd05443c172f5fcf","up":true,"other":"855667650e96c5ed2d9b0c82532ed1fb92f72b1ae926afafe09cf8f6e90e539aec5c4c2ab108f2c2a1ad7dd8b83ca92a98c550a1c9ed27e6632a7d2f6da4f970"},{"up":true,"other":"dd3dccc1758765569905b3b137ef4c7dd31c2dc0dea827bcc4c4e976be94ffbb0f2ef6fe725cf9042063a96d663efea546837f35ca1fc67a854fbc9e27abb754","one":"3948a7a939b9a1f4201953bd9b955ee7be87d09b63c7a45167f556ac06fe3c4c2a75d935bff50668da5e71e46802b55d7a9945a92d7807c00625d129cbb48f82"},{"one":"202ae63076a5560418023f00c9965b2a1d12de932b5371ae270d63db88551a7aa1a3c48841f81948fad3435bb4a7e3e165a2eced9fd937444e4502471e23dae8","other":"b60def37233dbbc0d5f7fcddb304be1c0b6508e1e3d8a09a8290f7363e9bb84152dcaf70b8f6bb3a882fee77ff03ab796a5c1c3654f251c9f5c746ac5ad88556","up":true},{"up":true,"other":"37399617d62153bc471f3bf21c92385bc8602c80ffa0c71da8aebae595a9859cfd56257aae60ad30ef3ec4d07dee90623cce63749c8c3233c0aa0d17f9e89afe","one":"fee3fa1ba2a051d40a582908384ee81179db6c2b5f4bfa58c24f8015b794b43a093ed68b69bb209684135f972a055a9845978fa1b7d489e2126c3b514297f1c2"},{"one":"57085f756f76644cdd2148524f2334d869ef0ab2fcbe7fb11f5d22bc1f5023165b11526ecc85ff9cbb88877386af9b148d7ef15a825b3a586d16c01bdfc86692","up":true,"other":"9c8fca41b833e88110559b9258653160f5fb236bd637272ac58fe1adf333f4df75b94a805eaebb9f10a8c1a26d357dd75140560551d3fc4da79da2c4fc9479c3"},{"up":true,"other":"e0a043f98b462f10f72aa61ceda52f9c27829d086f6f2c5bf4db4fe32759002e5ff9519495d57dbb83d963a1dc991a1defcf5b9ef0d543789f38c68f5d07122b","one":"224c3b969149d50d1bb4f473bb9725223c1dafe152efe1b08e8859213c543a66565b5d68a99cef3d5f4eccad6282a12f78d7b38eec14deebf44ad8dd9cba8680"},{"one":"a47697063a2fb973449bdabd0925e10944ba1f6d8b2cc5c38b295f611eea3402b5cf3ae857716a34d84194955f5ed61350affe56223349124c8233852141f9a2","up":true,"other":"77e7d427b65b6c29c0d92c51184af73031bfa768a47fc20be6c264f422bf718865259c17c103bf47289b3abe62f93452781c6303d757e76d3d56ceeb26262fab"},{"other":"92dbb67da2b99a8fe46b1e510addc2b83e357ac0b5287b7ef5c1b1bc6e252b8dfd605a6896ede65848e429216d1f67d530d9e7b83ff14058aa2e5b6e405d6801","up":true,"one":"224c3b969149d50d1bb4f473bb9725223c1dafe152efe1b08e8859213c543a66565b5d68a99cef3d5f4eccad6282a12f78d7b38eec14deebf44ad8dd9cba8680"},{"up":true,"other":"b18c7131a319db61ab84d06e90092d93c91141e9a270630af9c3ab1eaf3bcad09f4d20a1fc845b21c994bf4d9e337d0bd756a75e2198097540355e7ebbb531b2","one":"c206d8689068488179e86ce549de75989e0b17cbe09880d18fcf0fa212e629345f1b899203607a2b083569cb3f8398e501843166f5db23ac7fa7dacfe26dd3f4"},{"up":true,"other":"c63b88f494b14d5a7c1da124ffebbd985d19806b91d4b111c83ae129c4ef19614469980a09fbeccebe3b0358dd16194bdb6452d0b3dbb43a5467e23bb13f40d6","one":"5d002c37b74a6656db86f102b0cec82bc35a819a480e5a2952db0140ebab65dffeb1a79f04d53ff61447b5fad7c58cb75ea1c91ea47fcb9e024f27b92c6c874d"},{"up":true,"other":"ef7157fdfe62390d8a6d4ef976478d17465b42b63fddb03664973d63efb62318a8f59e412150528a32aa2c028b9de6bc67f05e012b8c43d710032ad871bc27e5","one":"ab8eda9b360d3e0b002ba31d48311057880844b828ad9817a2ad19736860d0114d4a17e9e9427c842d52e7ff61a09c2cad9b70f506e338909535542dae38ede0"},{"up":true,"other":"8c459100df488b992fdad207a096a434d67cb733619adfd09a311095568d4c9db293d9a892675551805559456d49a3fdb19c2cc698b14552bf0ace584d4d90dc","one":"e903d7aebff96a6afa4b9dd19b0b02e5af18da8e4e89f64247e1a2c2d46637538c741182eac67f45ec61be76aeaccde57f0a0184bd608ea7d92e586d4f827ea7"},{"one":"c2568576c2c9ef47aca0baca52709a4fa44b2ed478a062f7b161fac2bdba68568df371ac7754255fd07d79bb9918249a914946a6c318d579730bee9bc609922a","other":"fc9b1b2bbd5e682eb350d23f3ee33b245495daedae9370de7b1f55f91cd45db831d196c17615e11decf6b67696a268ac788130e3de38c7f6aeae811f3ec8c8ee","up":true},{"one":"51a570637394e9ab61fe95b3a608cc4e9dc8ceb63efe717938ccd4260a962d52e01b30e7034fbfdabd9a3c9616ee569550b38a6d6b4b19847f523254069a9f27","other":"ef7157fdfe62390d8a6d4ef976478d17465b42b63fddb03664973d63efb62318a8f59e412150528a32aa2c028b9de6bc67f05e012b8c43d710032ad871bc27e5","up":true},{"one":"4eab70233789c544bec97040a04099494bf269a819584a5d0b42295c918a52b02f224a8ed127aba3d92c02f567356bea4b95f77230ef548dfa7fe44b643d8704","other":"e903d7aebff96a6afa4b9dd19b0b02e5af18da8e4e89f64247e1a2c2d46637538c741182eac67f45ec61be76aeaccde57f0a0184bd608ea7d92e586d4f827ea7","up":true},{"one":"9c8fca41b833e88110559b9258653160f5fb236bd637272ac58fe1adf333f4df75b94a805eaebb9f10a8c1a26d357dd75140560551d3fc4da79da2c4fc9479c3","other":"5114329db828f9568ccb0d7643a10e273aa626177910f55e22a53abf1ce8ec75b95465c983446b20eac0ff9c59c5dc53eca95b24aabcc8dd110e397cd2934047","up":true},{"other":"15ceb62ee0f53379aa202950634ed881ba3b7bd4b46c80723ee48190079311e24ffaacb167a126a40bd6732c384f3c26163aa043edca03cb52a97b6da189aec7","up":true,"one":"842f0ac24370f14edfe72a7d07219de60fc767d2d0356fa6ce9d535a43647ad4bb17d9be75ed83542868ba430ec104ba168f27c16915cdbd6e57ae62d60707cb"},{"other":"3dcf18c35593b47bc463688493b792d6b9d13eabe05396e491953608f20cf55f770fc21be32b00335fcb2f0ba02735b92569b2b64a44c344ac348042876e8f15","up":true,"one":"ab13f773f6f2ff73032aa5f79c8897b75dda29bcbb14aa511e9401c2417dc9c510253071e28c7833c8d62fd2aef16fcd0c14ce016fbf4fec1b9a2173c717603f"},{"one":"be93fafaf43f6bb3efd2667d1468a8636cb752b245328eaa01468c0606d790322a7cd8e47857068e60118e28b8dd8aa1d2d4977c5b3d28d4b47f4c0658f05e90","other":"362ed9a92b588d5fe315b90a74aa27f7600e4a7d06b27ceb26272340388d916a831df85bf83450ef80bda4e4a21acaac60560c8a42940a26e2ac567519e2a202","up":true},{"one":"1c080e90760dfcee08ade6e4ea3b275ff3c6882f3b44b7f3a73d70bcc816fc63ce0b6138f810d17d96ed387076f9bbb6dbb2ef6dc4d6ba6542c1f587b7602a12","other":"362ed9a92b588d5fe315b90a74aa27f7600e4a7d06b27ceb26272340388d916a831df85bf83450ef80bda4e4a21acaac60560c8a42940a26e2ac567519e2a202","up":true},{"up":true,"other":"1489ad735e1256900e4733707f8b78f1d853742a8f9b2d0c1c89651c60e7ee9d266afba5b4c1ed3f9cee05a1d2b2bba35dadb5b08973a93fd70dfb9e367339bd","one":"f4cdaeb513aa98f8868d8eb3a1d12c07367725928a1bc7d6ca4b583788e111a955463037ec7867260511896d97dfbf096aa77ee8a7d9ea1c06cad4a92c45108d"},{"up":true,"other":"ef7157fdfe62390d8a6d4ef976478d17465b42b63fddb03664973d63efb62318a8f59e412150528a32aa2c028b9de6bc67f05e012b8c43d710032ad871bc27e5","one":"06aab75fed9a03f5525e3f1d8f8997fefaefd5b16e8f485d571beda00b1741efbb61a8a74fa12c2f6de66227c3fabb4d411659cd9c7b1ef32e171e6bf517cc39"},{"up":true,"other":"d7e3661c0af6754c875217f93d34b254f1f45fc1359a4c6146cd0efa4c6e12aed9a4fb0a21a136f73af4fc2c6d0a63cb809d81855bbc9f51e29d23d90f77b326","one":"d7af0a0217ff98804aa05f8f926a8b6262363b5391d24cda8048cca5ca5982b407b7b098302d0db6d8dd9ac0883b2025b3de651617ed1a173181148295c6d336"},{"one":"c088bf88f1e152ca3fad17f098a71ca1021d46d8af12d0ee1c587a5e2a430d8e48beaf171fe01ee7680b671c00dd88c90f12a35c328a3f334661fdeee914a4bc","other":"488854534ec5a3479d8ee13d9b7daf07479f6b5505f319eced44dad8c316f6ff241ce2101e95608ba635067f5e5741481b78f419c4bbd465bf7e837dc4e54d64","up":true},{"one":"b8e0a56df21baae43058f575b714ae9a33c097d18f1a628b3b6ae5e86dd46a06e44c0dc272baacb5be0f7bf57fd6ddce107544eb3b94dca1aeae9f5773496a72","other":"f98c0f4444a1ec80773454ddb691c226b81d8e2f79ed40c45a422d3359565edf7bd635d3eb7bd6c9e0870746849fb86f0b1b34cd56ec8d3ad969812e080f4983","up":true},{"other":"b60def37233dbbc0d5f7fcddb304be1c0b6508e1e3d8a09a8290f7363e9bb84152dcaf70b8f6bb3a882fee77ff03ab796a5c1c3654f251c9f5c746ac5ad88556","up":true,"one":"9309549fc50173d6826fe63cf18699f49199c3789616b843042fe1a6adab6ed4bdd7a7a06acd276e0398cf8bffb26c12a4227725d7bbd386a9a55fc601c21405"},{"one":"06aab75fed9a03f5525e3f1d8f8997fefaefd5b16e8f485d571beda00b1741efbb61a8a74fa12c2f6de66227c3fabb4d411659cd9c7b1ef32e171e6bf517cc39","other":"2b0a1f3a6466c6be1d7e84120db384fa37f7c73a01e9a105ae90e7d2203212ec974f016d3012afd26bc0f9a8411d0716cc59b6ecc9f665db12e306af8b34cb63","up":true},{"other":"92dbb67da2b99a8fe46b1e510addc2b83e357ac0b5287b7ef5c1b1bc6e252b8dfd605a6896ede65848e429216d1f67d530d9e7b83ff14058aa2e5b6e405d6801","up":true,"one":"6c40910f0556f892a7542989fa01d7e3682fca89aeefb5ed885808f88ff17b6d13862f461c10d629a005ae67abef542d75e5b20816891b6944f71560f5c2dfa8"},{"up":true,"other":"212a8048ab9925171475e81dce047865df186222d673d524c810a9f613e4a21f3b130fa34c5f44974fbeaab1f6028177e71568e00a1184d9fd05443c172f5fcf","one":"ab13f773f6f2ff73032aa5f79c8897b75dda29bcbb14aa511e9401c2417dc9c510253071e28c7833c8d62fd2aef16fcd0c14ce016fbf4fec1b9a2173c717603f"},{"one":"06aab75fed9a03f5525e3f1d8f8997fefaefd5b16e8f485d571beda00b1741efbb61a8a74fa12c2f6de66227c3fabb4d411659cd9c7b1ef32e171e6bf517cc39","other":"85b6404a76b4762156c8ddd2f312763dfe19b315d914533844cf229301880c57ffeadc0eb5f4a8d542e1d9fc961dfb5a572d2101172b1a0fc238ced05ba49ec1","up":true},{"up":true,"other":"8ec699020ab5e7719fe23b80268b5d1d37052bb71f5d81200ae805cf27825823733206165f0a7507c2595853361dd122e9ec1b2deb543591e22b71ec0b873b5b","one":"96cd4caa32c0b3a3493e24e13fad1ef75c621005d74154c3fc8a73cca4c0120452b6432334d94849c63f75d56a2943a453c86d2a14ad1fb61ae6833e58451187"},{"one":"3dcf18c35593b47bc463688493b792d6b9d13eabe05396e491953608f20cf55f770fc21be32b00335fcb2f0ba02735b92569b2b64a44c344ac348042876e8f15","other":"0e164c8692532e59c76ef84319a1093324f46f77618d3a836a279df52edca6c839061c0582dac7481da1bd0f3e2b58fc0dacd6ee5d678ba1406d4a1a25fe761d","up":true},{"one":"1c080e90760dfcee08ade6e4ea3b275ff3c6882f3b44b7f3a73d70bcc816fc63ce0b6138f810d17d96ed387076f9bbb6dbb2ef6dc4d6ba6542c1f587b7602a12","up":true,"other":"be93fafaf43f6bb3efd2667d1468a8636cb752b245328eaa01468c0606d790322a7cd8e47857068e60118e28b8dd8aa1d2d4977c5b3d28d4b47f4c0658f05e90"},{"one":"e0a043f98b462f10f72aa61ceda52f9c27829d086f6f2c5bf4db4fe32759002e5ff9519495d57dbb83d963a1dc991a1defcf5b9ef0d543789f38c68f5d07122b","other":"c6f38fe8a0f2b3773bae332e0ca7516e944bde186fe99daae10a2b0aecde3ce23c1834eaad97a4e6d2da8cd53a08dbafa72d2b827c851b115b74e8010125dba2","up":true},{"other":"ab13f773f6f2ff73032aa5f79c8897b75dda29bcbb14aa511e9401c2417dc9c510253071e28c7833c8d62fd2aef16fcd0c14ce016fbf4fec1b9a2173c717603f","up":true,"one":"99af34b172d319633e07a4e528f416024653a230a9103a4b281171f75bb697dd6be4757558c94e86210b4da8d9fe1229f6a5d8c4174989ea0ce696f8d1a9995d"},{"other":"545237d8463b75fd2e9bbfbffb35c5b78b4abbc85f6bfbd56976789012dd9a62ca1f866bf37bb33618e026aab764adb9ced5e00cd415562f69992f74c795083f","up":true,"one":"4ff2981a47da46c753090e193a8bf43c3372a6b07a37cf0552de2ced455fbb8a76d969cd97b3e4601d8a808bd2a73f7729ed8a61df2f2a0c2cee1425d0bd9ab4"},{"up":true,"other":"884d32d09dfef937f3ef1cd6fb5f530c2c574487c0ffd4185ca405c8b2ac73044a196c34352e850ce15321eec6579da654a696381f3e5830d03c7aa18923da6e","one":"c29e80096fbe7bc9fcbfdbe3cf6c06449192a3ed280e46a1fa5d424428d893c3456c985c1352c119236cf783834365439751cc87e7ed196614705dd3db6674cf"},{"up":true,"other":"28cdd55fc871ffd8d63d05994be706959c9780dbfc859070a41047a1b40dd5fd7adb53919400a4c6f4d06c69bc1ecccc0e230e5b702598a7fe8003a282479872","one":"8e65496318637446a51f0dc87d0a5cf82655866cd1579db1e381af52e12545172b9c88119999ccac3b8b8644efc9675ff183ebe7584c16eb40792cc21f7e9b76"},{"up":true,"other":"01427ba4d1e2de0b2764515556676a6058f88c16f597780dea3d7f95a6eec9299c3987d99c199d88a0a5e695ee6f0ff7de424e4eb65e54233b956a9634133998","one":"740919ebae9b4fe646ca716ebb8923bf2a1b1963767d86f55ea95911d88d163cc2e07b1420669e64b62cb267b625413444b783b8e4a7bd6a0f481f4d84e984b1"},{"other":"228b3646b15527f4df07b847a62dbf9620cb068f829e9086b5f437d0b64d8a027cab44f19db5e44189b5099545ecb25d49384c261748f9533cfb0eb11a1eca5f","up":true,"one":"5d002c37b74a6656db86f102b0cec82bc35a819a480e5a2952db0140ebab65dffeb1a79f04d53ff61447b5fad7c58cb75ea1c91ea47fcb9e024f27b92c6c874d"},{"other":"45d3827eb5c3b906fc61aaad79c5968f3dcf7b1ecc1e3be63e827ad6fb9291542686f42b3e142f43cc0437a2177b7362727842ea1d6c33bc795d936bba3ae457","up":true,"one":"b87e7f36ed6bf142d48545024d2fd6e120c44511701e7c0b7d7fc786f4f29d3357024b15f70b78215d8a4c2b7572d608c11b31612743e23db4fa673f0cd6519b"},{"one":"4eab70233789c544bec97040a04099494bf269a819584a5d0b42295c918a52b02f224a8ed127aba3d92c02f567356bea4b95f77230ef548dfa7fe44b643d8704","other":"488854534ec5a3479d8ee13d9b7daf07479f6b5505f319eced44dad8c316f6ff241ce2101e95608ba635067f5e5741481b78f419c4bbd465bf7e837dc4e54d64","up":true},{"up":true,"other":"545237d8463b75fd2e9bbfbffb35c5b78b4abbc85f6bfbd56976789012dd9a62ca1f866bf37bb33618e026aab764adb9ced5e00cd415562f69992f74c795083f","one":"5319bc9864d87eb33f26ff9732824d21a0a5ab70b254bc70a47554ffc763ae1559000d07e3eac9f883bd9e7f249d80edf14ab39c89c375bfcc5ec9e840ec9673"},{"other":"d09104c44648391693ca64a57baa5ef54ed717e19c65ad0a0921d08cbaca8877d0190795d15f75f3b6ce6e676d6b0e55d5ee8fec3310c68b7060a32f7ff649cb","up":true,"one":"ab8eda9b360d3e0b002ba31d48311057880844b828ad9817a2ad19736860d0114d4a17e9e9427c842d52e7ff61a09c2cad9b70f506e338909535542dae38ede0"},{"up":true,"other":"f4cdaeb513aa98f8868d8eb3a1d12c07367725928a1bc7d6ca4b583788e111a955463037ec7867260511896d97dfbf096aa77ee8a7d9ea1c06cad4a92c45108d","one":"842f0ac24370f14edfe72a7d07219de60fc767d2d0356fa6ce9d535a43647ad4bb17d9be75ed83542868ba430ec104ba168f27c16915cdbd6e57ae62d60707cb"},{"up":true,"other":"ef7157fdfe62390d8a6d4ef976478d17465b42b63fddb03664973d63efb62318a8f59e412150528a32aa2c028b9de6bc67f05e012b8c43d710032ad871bc27e5","one":"f8a5ae50e5b2d84096c10a6a8493a9eb8113df64c4f1336c0cf4649302649b158fa4cb7941591e55356891bcc1008a535df427546af19988a241c5f466467963"},{"one":"51a570637394e9ab61fe95b3a608cc4e9dc8ceb63efe717938ccd4260a962d52e01b30e7034fbfdabd9a3c9616ee569550b38a6d6b4b19847f523254069a9f27","other":"d09104c44648391693ca64a57baa5ef54ed717e19c65ad0a0921d08cbaca8877d0190795d15f75f3b6ce6e676d6b0e55d5ee8fec3310c68b7060a32f7ff649cb","up":true},{"one":"0e164c8692532e59c76ef84319a1093324f46f77618d3a836a279df52edca6c839061c0582dac7481da1bd0f3e2b58fc0dacd6ee5d678ba1406d4a1a25fe761d","up":true,"other":"93073da602d6326a48464a8b6890220b3aae0abf5b6961180f3aff2a14573c43411bd519d3e0012a646ec2977be18915d95a36d935a69f93985f5307ea4e3ebe"},{"other":"8e65496318637446a51f0dc87d0a5cf82655866cd1579db1e381af52e12545172b9c88119999ccac3b8b8644efc9675ff183ebe7584c16eb40792cc21f7e9b76","up":true,"one":"f4cdaeb513aa98f8868d8eb3a1d12c07367725928a1bc7d6ca4b583788e111a955463037ec7867260511896d97dfbf096aa77ee8a7d9ea1c06cad4a92c45108d"},{"one":"a25958cf192a4f62301feda5d442535f78b983dd9e4599354f4898c8c1e6ad97ca7112549e1d1a1eacb4682cd1bf8b762368b5905ab33dbdacb585b128514ca1","other":"9f3af4577308965aceb7e0101443669496e7ccf1de680629862a7005966c708b6fb52e6dfe62660246b9892adc25838da2873502e0be706bcad8f25b7ceedfa5","up":true},{"one":"a25958cf192a4f62301feda5d442535f78b983dd9e4599354f4898c8c1e6ad97ca7112549e1d1a1eacb4682cd1bf8b762368b5905ab33dbdacb585b128514ca1","up":true,"other":"01427ba4d1e2de0b2764515556676a6058f88c16f597780dea3d7f95a6eec9299c3987d99c199d88a0a5e695ee6f0ff7de424e4eb65e54233b956a9634133998"},{"other":"362ed9a92b588d5fe315b90a74aa27f7600e4a7d06b27ceb26272340388d916a831df85bf83450ef80bda4e4a21acaac60560c8a42940a26e2ac567519e2a202","up":true,"one":"4b332b389f1142c0da42aaeb2e2692081d0002de0eb6741b3269e898a8101571d4556b755f2e8841e7a607bb41e398d2b0577fbe71098e7097f0fe6c720e1526"},{"one":"a25958cf192a4f62301feda5d442535f78b983dd9e4599354f4898c8c1e6ad97ca7112549e1d1a1eacb4682cd1bf8b762368b5905ab33dbdacb585b128514ca1","other":"9c8f156797deff649d74d56fc42b4bb1a87312089114d4350424c375837d9c8068dd09af01c1c973d12ec5d7e8da600cd685cae70d3116b9dbda823092e03fff","up":true},{"one":"869cae165389e7dee7b7df4e012ee1a39737366c306d8f4b0db4510b2236e0bd3a4d1d4af00b1a8c1d360e23da47de52fc1632edb03c7f1429aacc8aa4994750","up":true,"other":"c402495c2110a6531a530ebdcd9ab1b883f1c707fe25aa13a255a0a9edb4113669b4aee9eadf803f9fe4c2ef66d5e4dff7064549f672598410f2d9794747a600"},{"one":"ee3471e1d835c4294f7ba642103039ccc548fe4edc177c79b63433ebbb0dc9d06600844f1fed76c7096ee9538e49e4e86fb8cffe9095dbdcde27695ff28ad395","up":true,"other":"e903d7aebff96a6afa4b9dd19b0b02e5af18da8e4e89f64247e1a2c2d46637538c741182eac67f45ec61be76aeaccde57f0a0184bd608ea7d92e586d4f827ea7"},{"one":"b8e0a56df21baae43058f575b714ae9a33c097d18f1a628b3b6ae5e86dd46a06e44c0dc272baacb5be0f7bf57fd6ddce107544eb3b94dca1aeae9f5773496a72","other":"e903d7aebff96a6afa4b9dd19b0b02e5af18da8e4e89f64247e1a2c2d46637538c741182eac67f45ec61be76aeaccde57f0a0184bd608ea7d92e586d4f827ea7","up":true},{"up":true,"other":"6909a0fa47718cfc463b1e96c21734b46bd5b28dd59cd3d66d67990783436b7538ab2659d427029b97c8dddf313b26532518c0c34a2b1fca8cd852b0fdb83ab8","one":"9309549fc50173d6826fe63cf18699f49199c3789616b843042fe1a6adab6ed4bdd7a7a06acd276e0398cf8bffb26c12a4227725d7bbd386a9a55fc601c21405"},{"up":true,"other":"c402495c2110a6531a530ebdcd9ab1b883f1c707fe25aa13a255a0a9edb4113669b4aee9eadf803f9fe4c2ef66d5e4dff7064549f672598410f2d9794747a600","one":"e33a1476fcb8d2a1b9ee15871a960ce7a3337c93f5956a2825b1f8b2885dbdc0ed652b1eba549523866632b5b6898310bc638d946a9fcce27d65117eb44c25f3"},{"one":"fc9b1b2bbd5e682eb350d23f3ee33b245495daedae9370de7b1f55f91cd45db831d196c17615e11decf6b67696a268ac788130e3de38c7f6aeae811f3ec8c8ee","other":"17ae0b24297a3e6e027884e5e4529b6646ae340f5736eebc6187a9b59832a445f3644172d92438351e3803e56a67472b29f3e1d48844ae2e11e5e6670eed1436","up":true},{"one":"fc9b1b2bbd5e682eb350d23f3ee33b245495daedae9370de7b1f55f91cd45db831d196c17615e11decf6b67696a268ac788130e3de38c7f6aeae811f3ec8c8ee","up":true,"other":"aa2028d356a88eca8e0fcaf218d62ace099c3f72dfd95bb28f30ac9a926034cf1d60a40511f7495652745de80d71c0f6830019e206c88e2b6ef0cf4f05d7fe9e"},{"one":"9c8f156797deff649d74d56fc42b4bb1a87312089114d4350424c375837d9c8068dd09af01c1c973d12ec5d7e8da600cd685cae70d3116b9dbda823092e03fff","other":"b3b4b203395bb6655d79ecdcee11638dd9a16baccfcc1f6fcc8b31832c8ca35650eb6c2802104eeec6d96ea80404381a2bd9b01dcadc748a4666b761d9ce64f8","up":true},{"up":true,"other":"9c8f156797deff649d74d56fc42b4bb1a87312089114d4350424c375837d9c8068dd09af01c1c973d12ec5d7e8da600cd685cae70d3116b9dbda823092e03fff","one":"37399617d62153bc471f3bf21c92385bc8602c80ffa0c71da8aebae595a9859cfd56257aae60ad30ef3ec4d07dee90623cce63749c8c3233c0aa0d17f9e89afe"},{"other":"eb58e478b16056e0af344397cf5f078a3312a6db2189ec2042ec06ab6550e3ee71ebcfeff1814332c552c12a5a488f96b3f2935e90a189d238da19d30a2c9874","up":true,"one":"699c923976c5b8c70c353840d3e384750f466954265f05fbb0d5877a2c0318a041dc57adc12ac6e8fbae7a00d6b6675e1a1be3a8f59dac12727ee3f8ae467a13"},{"one":"48e35d67e14ee2f329c0275bc965829b761885dbc3671f4673d84d76d18a5b6415e619e219b5d90761a5c6bd2f43c6a58708286a063daf46b502944f8ef9230b","other":"3a2cacc430f13f31c52b7205455420cf0fb9ed9e28b0898b69ef97951bf295b29118e573a42dd97abe38fee5ab4c03dad9ff6dc448126cefc1da12b6c8e8d915","up":true},{"other":"37399617d62153bc471f3bf21c92385bc8602c80ffa0c71da8aebae595a9859cfd56257aae60ad30ef3ec4d07dee90623cce63749c8c3233c0aa0d17f9e89afe","up":true,"one":"eb58e478b16056e0af344397cf5f078a3312a6db2189ec2042ec06ab6550e3ee71ebcfeff1814332c552c12a5a488f96b3f2935e90a189d238da19d30a2c9874"},{"other":"7db14fde1da8794ae7ab5de37c9e2537e1024bc830c176c0d01635cafed47773d3a28e156db81ecdb95903222b900c3ebd4c4b3db2971dc0ef6a1e386027ffaa","up":true,"one":"588df3185f63a5443d8c6b972f67805f0557184d916005f537a4b27cd02bd6a12e432a2b34b234a34f22e923c6f116da85be20bad77a2bf69913684e9d0732ba"},{"up":true,"other":"b18c7131a319db61ab84d06e90092d93c91141e9a270630af9c3ab1eaf3bcad09f4d20a1fc845b21c994bf4d9e337d0bd756a75e2198097540355e7ebbb531b2","one":"aa2028d356a88eca8e0fcaf218d62ace099c3f72dfd95bb28f30ac9a926034cf1d60a40511f7495652745de80d71c0f6830019e206c88e2b6ef0cf4f05d7fe9e"},{"other":"207764262a208c17db61fda4208d4664bf74010e0ad051a863e131e748c9304e11ccf007c925488ea86b974ee61cdac3dca4d4b3f4043524e03c194ab3c8eb5a","up":true,"one":"37adbfdf66163e45f433d78f63210163fdacf4688ad90d73bed07975be017c43cddf2a26a0dee8b11d78f294b63d4875b6be15f42f10817bd3d77b342919a11e"},{"other":"c03ef1de42d522b44eef53be11f2c57b8b74fed9e87e6c2928c1feb48ddfecc67e1a3a8c8be1c47b3735a216d7054e2a4dda49fbd9a1ac702146aae5bdeced7c","up":true,"one":"a070b5cff5eff533a2267ceb0d88e221088038af773e18f80110c8a2c329f0543b8d43c4e6132e9416723e3e94c87f0053456760ced4426767b95cee36ed93f8"},{"up":true,"other":"362ed9a92b588d5fe315b90a74aa27f7600e4a7d06b27ceb26272340388d916a831df85bf83450ef80bda4e4a21acaac60560c8a42940a26e2ac567519e2a202","one":"3e7aef8260c0d9717aa59b65ce7c554e53b81f19f5b9400321704a7ddf5041b0fe31b5634e90b93e6984060defee0e153997bbfe196166cc8d83165fd5eaf41f"},{"one":"89d46e664ac471c7150fbfe43a49c98750fc64d5ca22fdc2a040c7ab78c25c48c1e9c2f0e5130d6b8eb7f0760fe962759d83f68cc08ffaac3520499b0ce694de","other":"b3b4b203395bb6655d79ecdcee11638dd9a16baccfcc1f6fcc8b31832c8ca35650eb6c2802104eeec6d96ea80404381a2bd9b01dcadc748a4666b761d9ce64f8","up":true},{"one":"51a570637394e9ab61fe95b3a608cc4e9dc8ceb63efe717938ccd4260a962d52e01b30e7034fbfdabd9a3c9616ee569550b38a6d6b4b19847f523254069a9f27","up":true,"other":"8e65496318637446a51f0dc87d0a5cf82655866cd1579db1e381af52e12545172b9c88119999ccac3b8b8644efc9675ff183ebe7584c16eb40792cc21f7e9b76"},{"one":"842ec3faa8b4a4cdec32abfa00ae827277fe2696e1b0c6551154533b16cf75ae69caf834b4f08488fa5c8b322fb633b1fd8a5b7d436e9c589cc9074dc031ae68","up":true,"other":"a47697063a2fb973449bdabd0925e10944ba1f6d8b2cc5c38b295f611eea3402b5cf3ae857716a34d84194955f5ed61350affe56223349124c8233852141f9a2"},{"up":true,"other":"228b3646b15527f4df07b847a62dbf9620cb068f829e9086b5f437d0b64d8a027cab44f19db5e44189b5099545ecb25d49384c261748f9533cfb0eb11a1eca5f","one":"c63b88f494b14d5a7c1da124ffebbd985d19806b91d4b111c83ae129c4ef19614469980a09fbeccebe3b0358dd16194bdb6452d0b3dbb43a5467e23bb13f40d6"},{"up":true,"other":"b87e7f36ed6bf142d48545024d2fd6e120c44511701e7c0b7d7fc786f4f29d3357024b15f70b78215d8a4c2b7572d608c11b31612743e23db4fa673f0cd6519b","one":"5982e7dfd39c527851f6ea6430b70e654d95df5ec4401ca1d8dbd1034cf7a65d1126d60b36ebbd396c9ca32e6e8515f34f9dc0a8d2980afe4aa181c8bf68437e"},{"one":"7b4585f8a4e4904239994a1b8bdc76299da8e46a8a632fabc6c33dd4170f8f3715e4c4f526ea5dd14093b150855960e432b1b140594aca21995f9e0722fb57f1","up":true,"other":"ecb93d8eba17afe92979e8154252a08dd58de6ff3188b6829e3e25967846686f54199ab2b081e77b0048dcab204f05aa2c5cbd0efae4bc43a612d471d4e1197b"},{"other":"70cce7cb0c18091dbb6d41160ab560935f1759b969bf8118cee030ee707cb15ba407b8c48dcd9fd012cbf778e219f7d16a74064b4983cf098fb118297748edb6","up":true,"one":"4eab70233789c544bec97040a04099494bf269a819584a5d0b42295c918a52b02f224a8ed127aba3d92c02f567356bea4b95f77230ef548dfa7fe44b643d8704"},{"up":true,"other":"70cce7cb0c18091dbb6d41160ab560935f1759b969bf8118cee030ee707cb15ba407b8c48dcd9fd012cbf778e219f7d16a74064b4983cf098fb118297748edb6","one":"c088bf88f1e152ca3fad17f098a71ca1021d46d8af12d0ee1c587a5e2a430d8e48beaf171fe01ee7680b671c00dd88c90f12a35c328a3f334661fdeee914a4bc"},{"other":"4116fbb7d55bfd4bd8db9cbfa570ac361bb88605b6aacbf84e245893cf3fa599ecc086688a4c534c81f61a90fa344ca37e4d4013ddc03f7f08218724a55f66b1","up":true,"one":"37adbfdf66163e45f433d78f63210163fdacf4688ad90d73bed07975be017c43cddf2a26a0dee8b11d78f294b63d4875b6be15f42f10817bd3d77b342919a11e"},{"one":"f60755ee9464c7db769bb7237016fa165441d18ac3bfed7cd2a220a9bcbead202dd34eaf2f9398a3d36bdfc2671bbd46ac25ebe264a8118afe1b7d0bd38710f4","other":"f52297fc51b920d2495ccece290432656d9388e698339c8c1279ceea45de698a4ecbda1d25928c48f1e19e9dacd3147e23ef01acc093872d7300aed187841dcc","up":true},{"one":"e0f13606a7f35b9ad8a9c4e70336c4c554ac718720a451a349eb4e1a4b055079483cac040ec64e0ed3d8bdb336618a5ae6ef74e31642fae4d7ed9949858eb361","up":true,"other":"ecd217e8bdb53c9ef085929b8c2d2b40425a4be617a087b8e7f88e8507b3c981e90fda2119744ca394fe65bd4eb1cdd3fa7258db936048e236d2f15ee91bc3b6"},{"up":true,"other":"f52297fc51b920d2495ccece290432656d9388e698339c8c1279ceea45de698a4ecbda1d25928c48f1e19e9dacd3147e23ef01acc093872d7300aed187841dcc","one":"37399617d62153bc471f3bf21c92385bc8602c80ffa0c71da8aebae595a9859cfd56257aae60ad30ef3ec4d07dee90623cce63749c8c3233c0aa0d17f9e89afe"},{"up":true,"other":"dd6acfd151220f21b03701ca554a5e134dbd1154dda21d9eec45809e7858fe83eca3953fc688f499030198f22052c3681a9f49207ef9b11a760456ab9637352b","one":"682288e4dae2374c4784acd0b285508920ce39a6b72cc0e30a3dbb7972e0394a2bddd5ee5f22a1dbf80f284dde4d9f8ede7847318d5353566b35a83e212477e7"},{"up":true,"other":"7c6e6a49429a4e24aa4aa5c7ba19684f77cd67d3744688baff6e7f1d74b7e9d2df85f3e57e0df0a9b960b5bf982a610c5639c3e7a6935ba13fbc77243b2dad19","one":"e0f13606a7f35b9ad8a9c4e70336c4c554ac718720a451a349eb4e1a4b055079483cac040ec64e0ed3d8bdb336618a5ae6ef74e31642fae4d7ed9949858eb361"},{"other":"877d17ec7e95998ead831606d3363fbff1c8d1fa377b8e621e6a876d2c7776b9af356211a7e4df66adeaf38cf9b49c04871e8804edde4c18435ff45e110ecb04","up":true,"one":"e323da6ae861cb092543992b8985639f9b3bcaf1c3c68757f4603a67800be62950fe7d8f8ef80eb83a18107b677c7f5047ea89a5790e0ea2a7969f4856d28488"},{"one":"c2a9c77247871cfa4d3c2d1b47619df91ed5b331a44c8e21f7c9ce431a4db9dfb87713558cc8a37911393907b4cc60be9445bad18adcea1bc5f318256e71be14","other":"fc9b1b2bbd5e682eb350d23f3ee33b245495daedae9370de7b1f55f91cd45db831d196c17615e11decf6b67696a268ac788130e3de38c7f6aeae811f3ec8c8ee","up":true},{"one":"b9c7b885430b9b1a4425bde30b3629559f5437e0e30a0299fc6f6e097cbcca8af9e285caf5dea685a0237f60e06f490c39a1e3e487f14a2b9f41a5135f2ba994","other":"ee0b09ee6a1057c47102e582e2fdec7b9212802e59f062a9360da0db535d4987126ab24848c0d76fa8485431a5140307e2b0c0d9f37cbdb35756e6cc1bdb3bc0","up":true},{"up":true,"other":"7a8cb96685c1b8fbaeb18c8dc1f9f2631b23bc035e704e2f5df915b8bcabd6e2025ddc30324c69833f86e577b250c0721fee9d294f3e22016ae4c59c5f88845b","one":"7dd2801259c071a6e1dcc01d1cb74775fdec92da1da0b1eaf5f893cd5ed118894493ca5284c12bbd6cf7959449bc610d26ac6c9ef2845d1645d425f56ac003fd"},{"one":"96cd4caa32c0b3a3493e24e13fad1ef75c621005d74154c3fc8a73cca4c0120452b6432334d94849c63f75d56a2943a453c86d2a14ad1fb61ae6833e58451187","other":"29619924833116cb1160bf7a8066a528b7182794368bfae62b5bacbae680d9161a479f217e30c3b4f19a250b1b59e08f86c94726117dc3bc94ff9ceac6bee6e4","up":true},{"other":"224c3b969149d50d1bb4f473bb9725223c1dafe152efe1b08e8859213c543a66565b5d68a99cef3d5f4eccad6282a12f78d7b38eec14deebf44ad8dd9cba8680","up":true,"one":"b152eb30c9f46ec39166016f03d289f98cc285ac62d204da32e5a003da14e4f02c64df8ae1d0c8a2a902adc5f7dd7604081a0b140c9b64052082f0861945f5a4"},{"up":true,"other":"da22fb43c6d230d92f9c09454e282dc45dffc759740566039f1bdfb58171c6801f721841de83217277b3fb70983e7d34da53bbf25d1d45413a78d9afff151826","one":"9f3af4577308965aceb7e0101443669496e7ccf1de680629862a7005966c708b6fb52e6dfe62660246b9892adc25838da2873502e0be706bcad8f25b7ceedfa5"},{"one":"f5d95e0c5a873ff5a95e1eb34f1ed258d77adf98ee0886d93c4a24b1feaf6955e6e4c4ea0eccb2b9723870bae61e693643d6ad96dd8da01672542611f7c49069","up":true,"other":"6b082a09e343a160b60a01f74641c1d707b2fa8fee5f6f5a8b9e4a203bd86434227d2df982b246a752f843483cdf517e85fe3bd65453354232a6eb38dedbf314"},{"up":true,"other":"9ea856ea440c776b9ffaad1237ec11d570a1f912a908b8363ff97cf7947d2523e3c73663240d8fac988698cdd81e877ddd4a609485fe9f26494136fae14212df","one":"f056acbdf491d1bb091937335c10096ea44b7034e994d134bc16d55212ff049bb097424de96c615ea699359a7ef77b3b54def2b3a5f43d735ffda65f73d61f7f"},{"one":"46717bc5fb7fcbcdc961e7ef091020f9f222858cf3d4afcc0b0bb1b782b7055d9eb833e0a04cb32d80406133ac77162521c43edf9f9690872222760e31462ccc","up":true,"other":"29619924833116cb1160bf7a8066a528b7182794368bfae62b5bacbae680d9161a479f217e30c3b4f19a250b1b59e08f86c94726117dc3bc94ff9ceac6bee6e4"},{"other":"97b1eaf8274ece76d75e7f60126f1b351ed5fe55088b9fcbb825a3a8d8f84f61bc72469916b280497dabf01345057525cae89da73c9a1a8a8cd19367d44dede1","up":true,"one":"488854534ec5a3479d8ee13d9b7daf07479f6b5505f319eced44dad8c316f6ff241ce2101e95608ba635067f5e5741481b78f419c4bbd465bf7e837dc4e54d64"},{"up":true,"other":"855667650e96c5ed2d9b0c82532ed1fb92f72b1ae926afafe09cf8f6e90e539aec5c4c2ab108f2c2a1ad7dd8b83ca92a98c550a1c9ed27e6632a7d2f6da4f970","one":"3dcf18c35593b47bc463688493b792d6b9d13eabe05396e491953608f20cf55f770fc21be32b00335fcb2f0ba02735b92569b2b64a44c344ac348042876e8f15"},{"other":"5a235aca7005df295d5bd924b1272452e9bdad408ca5223b9eb76800b4bd4e3158a1d663ce5243fee92233227249fe4bb8507e8cb2c3729744b273bf488ba60c","up":true,"one":"e0f13606a7f35b9ad8a9c4e70336c4c554ac718720a451a349eb4e1a4b055079483cac040ec64e0ed3d8bdb336618a5ae6ef74e31642fae4d7ed9949858eb361"},{"one":"c69b9b181b2756a1345b73a97afb3dca909c253188c3b905f0b414465b750d2ffccb4c8e8eb5e3809549af55db473f3b12682f9bd97c5c75d68f23d67d91b866","up":true,"other":"c9d705012a06d82c4d44db95b4f1c63ddd33ad64d732e96b1d878caa0caac433d4096f01495a6f0e8a56af122b0470fd745db6d906353b590a4710472b93f5b2"},{"other":"49215dfa786bfaa52b1e7aa6899392711a770b2504c82f536381fb1f18df16960257d75530efabf6dbd2b1361decc29758f870b318f777decf51f4833a9c1f00","up":true,"one":"f52281c227aa82a3bd5fabfdcf8bdf1d9ea6739ab9b9075340143d59b4f2f8a79a981609c9f42823a0253c19a7281eed0e912e4054363ab7fe50117563ef14e0"},{"up":true,"other":"93073da602d6326a48464a8b6890220b3aae0abf5b6961180f3aff2a14573c43411bd519d3e0012a646ec2977be18915d95a36d935a69f93985f5307ea4e3ebe","one":"a1fe0d27f82309911a4b758c4e597bde16adc1e2fdfb07b52dea5092cea40ff212ea2cc831e385094b044f519909cf978f350b16ffd4c70c159cf1372301a3cf"},{"other":"e33a1476fcb8d2a1b9ee15871a960ce7a3337c93f5956a2825b1f8b2885dbdc0ed652b1eba549523866632b5b6898310bc638d946a9fcce27d65117eb44c25f3","up":true,"one":"8fb6838337f832445531764ddafc3c747b2607f2f33e244685d6de621c2b53264270f5504187e43b7fa5cda53e66dd00b16c06879c82fb38a3d9e8aec4060210"},{"up":true,"other":"4116fbb7d55bfd4bd8db9cbfa570ac361bb88605b6aacbf84e245893cf3fa599ecc086688a4c534c81f61a90fa344ca37e4d4013ddc03f7f08218724a55f66b1","one":"6c95c653e15bb99d32656f35790400134cd7188e063f878e19cb9118eb469ae0362dc45255f2a1eae31520be01d42b5bc5bbebf03d644c9f206ca79cb33a01ad"},{"up":true,"other":"90b8e73916046b5433dce049bfe125ca2bf2fb390ff7301f9bc5d8d0183988577aa2a7392aaa28091aa81c8ac23942b5751420b9ee48e488a68411f9d2b1e5d5","one":"bac3fd2ea491d8e4ce1e5d469ec73f3d537d61279ae66e7a394b20a188244a886d3059ef0d304c0801878f9640374f7c8aaf56558c41f12296d3fc7f911ed66c"},{"one":"b1dd1b08975319030626aab821032a0c687a103ee8942e8a2e2cf029dd72832a49630e78d2d8b184579f22178aca0e875f9fad701fb81afd2ac110ab2b417376","other":"bc0df855bdadcde3e447415444f655eb430925a8fa81cdcac75909e7d79750f01827938570e75e388cc7058ba8ebca47afadf8b07172bc078488fb618ba71024","up":true},{"other":"dd3dccc1758765569905b3b137ef4c7dd31c2dc0dea827bcc4c4e976be94ffbb0f2ef6fe725cf9042063a96d663efea546837f35ca1fc67a854fbc9e27abb754","up":true,"one":"c63b88f494b14d5a7c1da124ffebbd985d19806b91d4b111c83ae129c4ef19614469980a09fbeccebe3b0358dd16194bdb6452d0b3dbb43a5467e23bb13f40d6"},{"other":"624248a794fd62248024360f128b2e503c752340694a316bed420e5ed2cebeb5bf970df95a2806732237a26de3778222b0454e2e7d2875129b193e7890fd5b95","up":true,"one":"6b104eff1dcf58d11a7f707bbd41a910b2735b262c29e0f4e4127fda1b67def4e89b6ebc1b3cc1e06c3968d0898e1085badc7da24d3cd6624cb100e85863cc97"},{"one":"e0f13606a7f35b9ad8a9c4e70336c4c554ac718720a451a349eb4e1a4b055079483cac040ec64e0ed3d8bdb336618a5ae6ef74e31642fae4d7ed9949858eb361","other":"510536aba28aa635d8a1098a6dbd2070748ce1eb0e14b54b93a21196543a60df546ff6a2b3b5b9f32a5c2a37f5aba77d0b74f28b2dabeeebf3fe5afc20a3209c","up":true},{"one":"69f999937943be00e5fca5c7cc942ce13b6752a72813368da2fbfcf74ad807bc6edd85537e087b6f73c0469c7b76a5d8f7d883bd315f3b35af32b8da293ed243","up":true,"other":"96cd4caa32c0b3a3493e24e13fad1ef75c621005d74154c3fc8a73cca4c0120452b6432334d94849c63f75d56a2943a453c86d2a14ad1fb61ae6833e58451187"},{"other":"f98c0f4444a1ec80773454ddb691c226b81d8e2f79ed40c45a422d3359565edf7bd635d3eb7bd6c9e0870746849fb86f0b1b34cd56ec8d3ad969812e080f4983","up":true,"one":"f60755ee9464c7db769bb7237016fa165441d18ac3bfed7cd2a220a9bcbead202dd34eaf2f9398a3d36bdfc2671bbd46ac25ebe264a8118afe1b7d0bd38710f4"},{"one":"af9b80f6836113aeda897d6903e9ffb4f7f1a706a7f821d0d40f03a0d83c18d6a19795ee4bfc1093ada04014415b1f230db1d2f056df3f5027cce71611588046","up":true,"other":"228b3646b15527f4df07b847a62dbf9620cb068f829e9086b5f437d0b64d8a027cab44f19db5e44189b5099545ecb25d49384c261748f9533cfb0eb11a1eca5f"},{"one":"b152eb30c9f46ec39166016f03d289f98cc285ac62d204da32e5a003da14e4f02c64df8ae1d0c8a2a902adc5f7dd7604081a0b140c9b64052082f0861945f5a4","other":"29619924833116cb1160bf7a8066a528b7182794368bfae62b5bacbae680d9161a479f217e30c3b4f19a250b1b59e08f86c94726117dc3bc94ff9ceac6bee6e4","up":true},{"up":true,"other":"11e9729700f5046b47d5e4521630cb57408f59a3337ca7db7984477a16c1f3b90c1d8d1f8d6a3f2a72e35f373fa73ec47a5636b36e40b2fb83756622a08896b8","one":"f5d95e0c5a873ff5a95e1eb34f1ed258d77adf98ee0886d93c4a24b1feaf6955e6e4c4ea0eccb2b9723870bae61e693643d6ad96dd8da01672542611f7c49069"},{"other":"2751df9f64a8f2ff8ea45efc9bd02b281d963ced285260bcda7f9dfaed998fe4386fe65a7265876da6b4fee77ea5c12454869a70ad627da7ca888076fc629665","up":true,"one":"f056acbdf491d1bb091937335c10096ea44b7034e994d134bc16d55212ff049bb097424de96c615ea699359a7ef77b3b54def2b3a5f43d735ffda65f73d61f7f"},{"other":"fd0123c7b96004067e98e463e273de5bc5402399ae70a95985b5f682e30d4f35d070deaf8c71d201e98c4324d832b95aab7535ad8a2658f66e3e0bb1202204e1","up":true,"one":"5319bc9864d87eb33f26ff9732824d21a0a5ab70b254bc70a47554ffc763ae1559000d07e3eac9f883bd9e7f249d80edf14ab39c89c375bfcc5ec9e840ec9673"},{"one":"3dcf18c35593b47bc463688493b792d6b9d13eabe05396e491953608f20cf55f770fc21be32b00335fcb2f0ba02735b92569b2b64a44c344ac348042876e8f15","other":"212a8048ab9925171475e81dce047865df186222d673d524c810a9f613e4a21f3b130fa34c5f44974fbeaab1f6028177e71568e00a1184d9fd05443c172f5fcf","up":true},{"one":"49215dfa786bfaa52b1e7aa6899392711a770b2504c82f536381fb1f18df16960257d75530efabf6dbd2b1361decc29758f870b318f777decf51f4833a9c1f00","other":"2c976b6007cda135444233c7bd03d22ac9756710b746c36bc032e7fdd42f2ffb89ca5f5e754ff96b8f3cbc474e346287e5b8531d9f98fd63c426c632872220af","up":true},{"one":"8ec699020ab5e7719fe23b80268b5d1d37052bb71f5d81200ae805cf27825823733206165f0a7507c2595853361dd122e9ec1b2deb543591e22b71ec0b873b5b","up":true,"other":"9e21f5d4cfb389ac3ad43497689878bd245a89c587a8637d832b1e355ba244f4c83e6499bc7936e6d35645db25910ecd89b9af9b6b2f0c7cc4d7c6114328d7bf"},{"up":true,"other":"1c080e90760dfcee08ade6e4ea3b275ff3c6882f3b44b7f3a73d70bcc816fc63ce0b6138f810d17d96ed387076f9bbb6dbb2ef6dc4d6ba6542c1f587b7602a12","one":"49215dfa786bfaa52b1e7aa6899392711a770b2504c82f536381fb1f18df16960257d75530efabf6dbd2b1361decc29758f870b318f777decf51f4833a9c1f00"},{"other":"17ae0b24297a3e6e027884e5e4529b6646ae340f5736eebc6187a9b59832a445f3644172d92438351e3803e56a67472b29f3e1d48844ae2e11e5e6670eed1436","up":true,"one":"154d5ddb15ec12dc65362039d801383c189b5bcf6688883f2d7e3d0e8dc78e45f9f58d5dabc79a8798a243ce59abb95c77525db14f050fd8cb37d04b7276557c"},{"up":true,"other":"58f9139905ae1d005950f110b7ead3355672ecc478e8c66393566c64b935003f6fec3031dc9eb21cda660acb1955cf7bb33a20fdd74d493f29868ace328fcd75","one":"643da2591098f9698f27cccf7c17832e0717ee6a1276398a1a29edc947125585dcfab9417c2721a8a55d4dfc75b826be7581b6e30b020f6341ac549877c9f122"},{"other":"884d32d09dfef937f3ef1cd6fb5f530c2c574487c0ffd4185ca405c8b2ac73044a196c34352e850ce15321eec6579da654a696381f3e5830d03c7aa18923da6e","up":true,"one":"b8e0a56df21baae43058f575b714ae9a33c097d18f1a628b3b6ae5e86dd46a06e44c0dc272baacb5be0f7bf57fd6ddce107544eb3b94dca1aeae9f5773496a72"},{"one":"3b71a324bd7b1a8fb19d8206eea1ca8190cb1faf5fcd1bfc52cef6b52296fe1db3e54d70180133fad1fa1188499d0dd73d2d075fdc6b3ffd9042d690e7d88e02","other":"11e9729700f5046b47d5e4521630cb57408f59a3337ca7db7984477a16c1f3b90c1d8d1f8d6a3f2a72e35f373fa73ec47a5636b36e40b2fb83756622a08896b8","up":true},{"other":"37adbfdf66163e45f433d78f63210163fdacf4688ad90d73bed07975be017c43cddf2a26a0dee8b11d78f294b63d4875b6be15f42f10817bd3d77b342919a11e","up":true,"one":"10551c0c37abc25457903978868dd4843a52fda5f9b571b05ebd974d8c381fda4349f17c2b986a2e4b8d06b0517422f085d5f6d9cd814efa40e48393d9f71d7e"},{"one":"8ec699020ab5e7719fe23b80268b5d1d37052bb71f5d81200ae805cf27825823733206165f0a7507c2595853361dd122e9ec1b2deb543591e22b71ec0b873b5b","other":"7cc9389c8f751465e0b94baed896f6f122631052300b1b5b23d3c7656e4d11014a7a9ae62a1287bb040ca37221871a566cd470e523846df7e3acb5f94c7cde06","up":true},{"other":"76643f67075c6e45bd176db19473240cda6f886d1cac25330e2d99c84a429934f4c6a606c9c72574d5eaccd0a3f1770dab05e6ff6a5b5ce4d7258fed2bc13d48","up":true,"one":"d6a7257771baa4d9944592ead46b8ab700dbf91ebd4dc0ec7e5fb41cbda0622944269172fcec8352b89ef2c186d4c787af2b45a50533f627a97818477de034b4"},{"one":"313a131ecb7d68e127d0fec8bb4a2e586886203c3d07857a93e7a39bb831703184d9ae28ba9ef3d986c2dae1a24f4f5bfa47cfc35f74f5512a126836364d7736","up":true,"other":"624248a794fd62248024360f128b2e503c752340694a316bed420e5ed2cebeb5bf970df95a2806732237a26de3778222b0454e2e7d2875129b193e7890fd5b95"},{"other":"51df4f4d4f020f22f55a5fd00c7f9c68c232c167ae4d4e80d7695f8f39c5aa0a7b565c1c55bdd6a21e06fa056549d08fd2e9d76fd79e21295557aa30d1ae022c","up":true,"one":"9bea5f82c2a390587de44d620d6637834e6f2329cd83d8df6305b03b75d9b543160b6c6f9f8887e6bc88f1d0726435d6c8ad813aadad0653b0790b8f6388413a"},{"up":true,"other":"5d002c37b74a6656db86f102b0cec82bc35a819a480e5a2952db0140ebab65dffeb1a79f04d53ff61447b5fad7c58cb75ea1c91ea47fcb9e024f27b92c6c874d","one":"bb0749de05a97daa67de889c15831ce39a080d641b3b08e3c248b0b16f4c07943fea8dd054d4a7e3e4af91ecff07053ce90096485a360b6f1d93050d179f30c3"},{"other":"dbb6621460b054f584f1c6157b4020f3c58d84c3a12b57436e10525ae60ab27036bf3edd68b92f2b13674877d01c2871dc67a9031c3d0470985f4b071696346e","up":true,"one":"9bdacc256acef0433805477d38f32be849a8846d88cb883b19d290454639b42c6ab6c5c52d4f83453e8a156af7d85f606458aa9c0977c67282f56f34ff0acbfb"},{"up":true,"other":"b87e7f36ed6bf142d48545024d2fd6e120c44511701e7c0b7d7fc786f4f29d3357024b15f70b78215d8a4c2b7572d608c11b31612743e23db4fa673f0cd6519b","one":"11e9729700f5046b47d5e4521630cb57408f59a3337ca7db7984477a16c1f3b90c1d8d1f8d6a3f2a72e35f373fa73ec47a5636b36e40b2fb83756622a08896b8"},{"one":"96cd4caa32c0b3a3493e24e13fad1ef75c621005d74154c3fc8a73cca4c0120452b6432334d94849c63f75d56a2943a453c86d2a14ad1fb61ae6833e58451187","other":"224c3b969149d50d1bb4f473bb9725223c1dafe152efe1b08e8859213c543a66565b5d68a99cef3d5f4eccad6282a12f78d7b38eec14deebf44ad8dd9cba8680","up":true},{"one":"9ea856ea440c776b9ffaad1237ec11d570a1f912a908b8363ff97cf7947d2523e3c73663240d8fac988698cdd81e877ddd4a609485fe9f26494136fae14212df","other":"f5d95e0c5a873ff5a95e1eb34f1ed258d77adf98ee0886d93c4a24b1feaf6955e6e4c4ea0eccb2b9723870bae61e693643d6ad96dd8da01672542611f7c49069","up":true},{"other":"3dcf18c35593b47bc463688493b792d6b9d13eabe05396e491953608f20cf55f770fc21be32b00335fcb2f0ba02735b92569b2b64a44c344ac348042876e8f15","up":true,"one":"643da2591098f9698f27cccf7c17832e0717ee6a1276398a1a29edc947125585dcfab9417c2721a8a55d4dfc75b826be7581b6e30b020f6341ac549877c9f122"},{"other":"c61ffc88f23f9f536497cc10ffcb7000ec6c4b801998ae7075ddc9079fdc1da8350e68744dc9e95ff892dfc5e52c62a3ad913a87fdacc455aea99b09aa002b57","up":true,"one":"154d5ddb15ec12dc65362039d801383c189b5bcf6688883f2d7e3d0e8dc78e45f9f58d5dabc79a8798a243ce59abb95c77525db14f050fd8cb37d04b7276557c"},{"up":true,"other":"5717a49591a0ecdff3d4449874d5ff9ba016afad5da19712ca0c8ebca8cefd84e6d8c778245f67f68c8dd730ad294fd017b8de279fde4fc919768ce85dba132d","one":"6a37e63feed9e68c52cb8b385d5e8d8dbd2b211c57ded0d3b01fe8b306af5c0e5a7405d0d9a942648f0131926240d53450bc43f922a053528e5830d918313c3d"},{"one":"bac3fd2ea491d8e4ce1e5d469ec73f3d537d61279ae66e7a394b20a188244a886d3059ef0d304c0801878f9640374f7c8aaf56558c41f12296d3fc7f911ed66c","up":true,"other":"362ed9a92b588d5fe315b90a74aa27f7600e4a7d06b27ceb26272340388d916a831df85bf83450ef80bda4e4a21acaac60560c8a42940a26e2ac567519e2a202"},{"one":"5319bc9864d87eb33f26ff9732824d21a0a5ab70b254bc70a47554ffc763ae1559000d07e3eac9f883bd9e7f249d80edf14ab39c89c375bfcc5ec9e840ec9673","other":"20f6a8be1d2d8b5d6a43d851a2f5475385ef07fab80ac46525d0beccf3e25c01d726cfb3a1179e8343b1e88d21684fb24dd6e6497537d4e7e9edd59cb95d1b8d","up":true},{"one":"6a55b94c9990249b24cdbeed96f065137f7b79ea8ee5f58da150d3962dfb62ba401960a53e7e8bd4e2c2908aa1a59b9d5efb4aafb316a9ab4fa67a0d95b58c54","up":true,"other":"69f999937943be00e5fca5c7cc942ce13b6752a72813368da2fbfcf74ad807bc6edd85537e087b6f73c0469c7b76a5d8f7d883bd315f3b35af32b8da293ed243"},{"one":"3dcf18c35593b47bc463688493b792d6b9d13eabe05396e491953608f20cf55f770fc21be32b00335fcb2f0ba02735b92569b2b64a44c344ac348042876e8f15","up":true,"other":"3e2241cdb9f34c1d2c6930e59940e2c4b92b0287579d7263a620a609c5e66dca6d85df48cf1bffd63663a6704c42d0866aae3e484fd9a44b6a012f72dd3cef6e"},{"one":"e7b2adabc2c99ac47b1e94fc0a2c63a00a1d622ea67a4c1858f4cec93fca957d43d8429605761bdf5eed4f733dac1a3d12fb928f22abf248965994acde63864a","other":"723f362e98f90d7ef15e24e353759fdbdabb08adab767dba73ab546741fac3dfb457466f1e2c851aa49526da1408f8ddb509e12f7dc0bc1e785c5b72be8a986e","up":true},{"up":true,"other":"29acdd4c1233441bd40f98e245ecc9de94de6f9d0ab7c1a9923d833a2c8e6c1bd26d792686fec762b31fe28bbdd7aa04c9a594d997d08c133bb24cb2d877595a","one":"9bdacc256acef0433805477d38f32be849a8846d88cb883b19d290454639b42c6ab6c5c52d4f83453e8a156af7d85f606458aa9c0977c67282f56f34ff0acbfb"},{"up":true,"other":"1b3107d9a96cfd11f4cd0ed8baeb7b23db1406c9c4a9dac76c772f49c0fc9404f6a4adae11120aa821757173f0cc1cb00e6ab555b5abffaae9001c0557cb75c9","one":"f6a12b23423c047927a3024a6dba7ce88927cb21d4df3778bc5ebb262cc403261c79ba6d9bda07f1852c009d803a77f429e9e48ec1d63cae98256e529d45b276"},{"one":"222d7a2f94dc82a09fda70b8195fc3a60433a90f53998872318c57625c528c90572d78b444ac4901dcfece1a03ef8b6cbe7845366a845a942f341f6db58a9b3b","other":"9f3af4577308965aceb7e0101443669496e7ccf1de680629862a7005966c708b6fb52e6dfe62660246b9892adc25838da2873502e0be706bcad8f25b7ceedfa5","up":true},{"one":"6b7c94db790a2c1b903208904c4c75b66b17e7a00404727dbc7aeff404ac1118dc78ce4ca443f6b5245236f9e358c09b6da027ae1144e1a6682edca301176330","other":"dbb6621460b054f584f1c6157b4020f3c58d84c3a12b57436e10525ae60ab27036bf3edd68b92f2b13674877d01c2871dc67a9031c3d0470985f4b071696346e","up":true},{"one":"2abb91884cc3a8fb91b2f2f369f9430f2b3b05c75ce6203aa7a50312c9f141f9d0f615063d3576a5ce8a4be9ecb942aa804a717f76d9e8dca03d115dcc43f775","other":"f056acbdf491d1bb091937335c10096ea44b7034e994d134bc16d55212ff049bb097424de96c615ea699359a7ef77b3b54def2b3a5f43d735ffda65f73d61f7f","up":true},{"one":"33cac8f621b9122e118036154778d27dc419b6b58ea2e89b833f3932f411dbc3511d92b55ae4cf80632142bc8e67994899aaa30c499d0289fae85b12564cf01f","other":"17ae0b24297a3e6e027884e5e4529b6646ae340f5736eebc6187a9b59832a445f3644172d92438351e3803e56a67472b29f3e1d48844ae2e11e5e6670eed1436","up":true},{"up":true,"other":"45d3827eb5c3b906fc61aaad79c5968f3dcf7b1ecc1e3be63e827ad6fb9291542686f42b3e142f43cc0437a2177b7362727842ea1d6c33bc795d936bba3ae457","one":"ef7157fdfe62390d8a6d4ef976478d17465b42b63fddb03664973d63efb62318a8f59e412150528a32aa2c028b9de6bc67f05e012b8c43d710032ad871bc27e5"},{"other":"01427ba4d1e2de0b2764515556676a6058f88c16f597780dea3d7f95a6eec9299c3987d99c199d88a0a5e695ee6f0ff7de424e4eb65e54233b956a9634133998","up":true,"one":"222d7a2f94dc82a09fda70b8195fc3a60433a90f53998872318c57625c528c90572d78b444ac4901dcfece1a03ef8b6cbe7845366a845a942f341f6db58a9b3b"},{"other":"723f362e98f90d7ef15e24e353759fdbdabb08adab767dba73ab546741fac3dfb457466f1e2c851aa49526da1408f8ddb509e12f7dc0bc1e785c5b72be8a986e","up":true,"one":"222d7a2f94dc82a09fda70b8195fc3a60433a90f53998872318c57625c528c90572d78b444ac4901dcfece1a03ef8b6cbe7845366a845a942f341f6db58a9b3b"},{"one":"884d32d09dfef937f3ef1cd6fb5f530c2c574487c0ffd4185ca405c8b2ac73044a196c34352e850ce15321eec6579da654a696381f3e5830d03c7aa18923da6e","up":true,"other":"488854534ec5a3479d8ee13d9b7daf07479f6b5505f319eced44dad8c316f6ff241ce2101e95608ba635067f5e5741481b78f419c4bbd465bf7e837dc4e54d64"},{"one":"545237d8463b75fd2e9bbfbffb35c5b78b4abbc85f6bfbd56976789012dd9a62ca1f866bf37bb33618e026aab764adb9ced5e00cd415562f69992f74c795083f","other":"eb6d41d8d96f1933dff017d5fa0c46c6d0bad5d273b7c321a12858ac90ec00fca6191d29419897d2e25ec2d8ebd8c6a81bbde2d3f266f842e64b2b822161f1ea","up":true},{"one":"8f3e9102306a13adb91e01f7a847e7880054f1a7df8976d05facb3a8fb37d47cce04f25e18a19713e5c3da7541e96e829fc67c8b924b717d2d9586c9c12d4fcf","up":true,"other":"29619924833116cb1160bf7a8066a528b7182794368bfae62b5bacbae680d9161a479f217e30c3b4f19a250b1b59e08f86c94726117dc3bc94ff9ceac6bee6e4"},{"one":"9f3af4577308965aceb7e0101443669496e7ccf1de680629862a7005966c708b6fb52e6dfe62660246b9892adc25838da2873502e0be706bcad8f25b7ceedfa5","other":"740919ebae9b4fe646ca716ebb8923bf2a1b1963767d86f55ea95911d88d163cc2e07b1420669e64b62cb267b625413444b783b8e4a7bd6a0f481f4d84e984b1","up":true},{"one":"884d32d09dfef937f3ef1cd6fb5f530c2c574487c0ffd4185ca405c8b2ac73044a196c34352e850ce15321eec6579da654a696381f3e5830d03c7aa18923da6e","other":"ee3471e1d835c4294f7ba642103039ccc548fe4edc177c79b63433ebbb0dc9d06600844f1fed76c7096ee9538e49e4e86fb8cffe9095dbdcde27695ff28ad395","up":true},{"up":true,"other":"c674c405068bb908312917a319e24ddf90e814ee8ef54bbf740f176b2a7eda6950e3e1ed69484ebcc27b13d82c7f0b20daba71a17700018e769ca612ca8d2208","one":"bb0749de05a97daa67de889c15831ce39a080d641b3b08e3c248b0b16f4c07943fea8dd054d4a7e3e4af91ecff07053ce90096485a360b6f1d93050d179f30c3"},{"up":true,"other":"510536aba28aa635d8a1098a6dbd2070748ce1eb0e14b54b93a21196543a60df546ff6a2b3b5b9f32a5c2a37f5aba77d0b74f28b2dabeeebf3fe5afc20a3209c","one":"81dc656de121016bcde81d5bf7919839acfc180dfbf1a6de2cadf704ff13af98aa5715a4168832ca6f651b2ea7ad9e6ca5f1c1cb7e885dbc2eb23d4aefb87bd6"},{"one":"b3b4b203395bb6655d79ecdcee11638dd9a16baccfcc1f6fcc8b31832c8ca35650eb6c2802104eeec6d96ea80404381a2bd9b01dcadc748a4666b761d9ce64f8","other":"723f362e98f90d7ef15e24e353759fdbdabb08adab767dba73ab546741fac3dfb457466f1e2c851aa49526da1408f8ddb509e12f7dc0bc1e785c5b72be8a986e","up":true},{"one":"96cd4caa32c0b3a3493e24e13fad1ef75c621005d74154c3fc8a73cca4c0120452b6432334d94849c63f75d56a2943a453c86d2a14ad1fb61ae6833e58451187","other":"7465fe601a9ad8e640069e6e07d56afabd3d4f008f3084f944d869b47fda3f511f191062802a53da511f60891dd0bcc5fac60254ef9db7aa3b41f5791b0b6975","up":true},{"other":"2751df9f64a8f2ff8ea45efc9bd02b281d963ced285260bcda7f9dfaed998fe4386fe65a7265876da6b4fee77ea5c12454869a70ad627da7ca888076fc629665","up":true,"one":"9ea856ea440c776b9ffaad1237ec11d570a1f912a908b8363ff97cf7947d2523e3c73663240d8fac988698cdd81e877ddd4a609485fe9f26494136fae14212df"},{"one":"643da2591098f9698f27cccf7c17832e0717ee6a1276398a1a29edc947125585dcfab9417c2721a8a55d4dfc75b826be7581b6e30b020f6341ac549877c9f122","up":true,"other":"93073da602d6326a48464a8b6890220b3aae0abf5b6961180f3aff2a14573c43411bd519d3e0012a646ec2977be18915d95a36d935a69f93985f5307ea4e3ebe"},{"up":true,"other":"224c3b969149d50d1bb4f473bb9725223c1dafe152efe1b08e8859213c543a66565b5d68a99cef3d5f4eccad6282a12f78d7b38eec14deebf44ad8dd9cba8680","one":"46717bc5fb7fcbcdc961e7ef091020f9f222858cf3d4afcc0b0bb1b782b7055d9eb833e0a04cb32d80406133ac77162521c43edf9f9690872222760e31462ccc"},{"other":"313a131ecb7d68e127d0fec8bb4a2e586886203c3d07857a93e7a39bb831703184d9ae28ba9ef3d986c2dae1a24f4f5bfa47cfc35f74f5512a126836364d7736","up":true,"one":"6b104eff1dcf58d11a7f707bbd41a910b2735b262c29e0f4e4127fda1b67def4e89b6ebc1b3cc1e06c3968d0898e1085badc7da24d3cd6624cb100e85863cc97"},{"other":"6b082a09e343a160b60a01f74641c1d707b2fa8fee5f6f5a8b9e4a203bd86434227d2df982b246a752f843483cdf517e85fe3bd65453354232a6eb38dedbf314","up":true,"one":"2751df9f64a8f2ff8ea45efc9bd02b281d963ced285260bcda7f9dfaed998fe4386fe65a7265876da6b4fee77ea5c12454869a70ad627da7ca888076fc629665"},{"one":"b4f300abda4cf6e383f997510eb681e9fa62e23577e3c19bd7447fa1f5702a4e034cea5944248e7c6e6e92b5ae69195c3e8a2c5ca7827b4f4a00cc8546e6695a","up":true,"other":"f5d95e0c5a873ff5a95e1eb34f1ed258d77adf98ee0886d93c4a24b1feaf6955e6e4c4ea0eccb2b9723870bae61e693643d6ad96dd8da01672542611f7c49069"},{"one":"81901d9f043b4b1649ade3b5d22ae5f8bb42dd6db1eb37b836b99dd1c0388509ed4b54cc5638c9d4a6c5ae6c6913bbfffb303d7d94bf4ed50e871cf95459e2c3","other":"243164c4dd583f80c50813f43e5c27c894463400cd3afd776b36e79e7123d9261f01f06f92914aab83096b9a43fb655e79687590599284640a3a7d2c25454597","up":true},{"one":"8e8614a4c2ee2b1a3fa5ace0ca353cff36b3de3308ccf53665b8b56f8e2456a8a65f3846d786dccd68b1bfcefdd170ea5f8edb481800b1ce72d9fce2added7f0","up":true,"other":"3f322f9b1f1f0692663bc3be11cf11386f4a14696aab610916cfcadf0234cce0c86b51c85ce2108e9bc21d50ad71cc10a6eeaec3fc7732908f3a8b193465a0ac"},{"one":"8e8614a4c2ee2b1a3fa5ace0ca353cff36b3de3308ccf53665b8b56f8e2456a8a65f3846d786dccd68b1bfcefdd170ea5f8edb481800b1ce72d9fce2added7f0","up":true,"other":"dd3dccc1758765569905b3b137ef4c7dd31c2dc0dea827bcc4c4e976be94ffbb0f2ef6fe725cf9042063a96d663efea546837f35ca1fc67a854fbc9e27abb754"},{"other":"431644cf162bc267237c4e798288888dd835c1b0546b0cc679782e33568988d75b4294f4aa08359a6b152ed9a0fbd13133681156bcf09a871c4f362615ea6dae","up":true,"one":"50c79baa3e6781482ccb5e960c699dd9c13f479467c6315c5292a396337cf3619e7faba1971a1f470051cb9042f80ea6750defe3936b72aac4d9bac6f8368c67"},{"one":"43086ff7ffd3c7bdec77bd288f41f1ee0ce21bd3f60a5df8931e2af6e7af5ef0fad432d29625491935d11567944351fc7867c807ebd12dd2c21c9e620ae0f85c","other":"c674c405068bb908312917a319e24ddf90e814ee8ef54bbf740f176b2a7eda6950e3e1ed69484ebcc27b13d82c7f0b20daba71a17700018e769ca612ca8d2208","up":true},{"one":"b4f300abda4cf6e383f997510eb681e9fa62e23577e3c19bd7447fa1f5702a4e034cea5944248e7c6e6e92b5ae69195c3e8a2c5ca7827b4f4a00cc8546e6695a","other":"6b082a09e343a160b60a01f74641c1d707b2fa8fee5f6f5a8b9e4a203bd86434227d2df982b246a752f843483cdf517e85fe3bd65453354232a6eb38dedbf314","up":true},{"up":true,"other":"5319bc9864d87eb33f26ff9732824d21a0a5ab70b254bc70a47554ffc763ae1559000d07e3eac9f883bd9e7f249d80edf14ab39c89c375bfcc5ec9e840ec9673","one":"6d0a09235ba0b0428938abf0e0782ac0ecf5697ef862888719a34fc956517aeef89d5e5f76d12e10067fee5bac8781dc10400eeb35c2393b9382b2a4f68f7939"},{"up":true,"other":"228b3646b15527f4df07b847a62dbf9620cb068f829e9086b5f437d0b64d8a027cab44f19db5e44189b5099545ecb25d49384c261748f9533cfb0eb11a1eca5f","one":"8e8614a4c2ee2b1a3fa5ace0ca353cff36b3de3308ccf53665b8b56f8e2456a8a65f3846d786dccd68b1bfcefdd170ea5f8edb481800b1ce72d9fce2added7f0"},{"one":"7958d1517de1223e7fb30acf61d8618e49fb95a03bc2f49141f4c7967bc80b90e0dd526c205639de3c060029963d43813293c2556f7b127945c798f3f9f18626","up":true,"other":"8ec699020ab5e7719fe23b80268b5d1d37052bb71f5d81200ae805cf27825823733206165f0a7507c2595853361dd122e9ec1b2deb543591e22b71ec0b873b5b"},{"other":"876618c8ba66c1b91b473a154be3e10ded3590ba83d620d30e0ff1fbac2f31f258b1299a3da5b56aa03269a80c119b7fc41dfd87d5bd996359e4ad8dd0ab2a6a","up":true,"one":"76643f67075c6e45bd176db19473240cda6f886d1cac25330e2d99c84a429934f4c6a606c9c72574d5eaccd0a3f1770dab05e6ff6a5b5ce4d7258fed2bc13d48"},{"other":"77e7d427b65b6c29c0d92c51184af73031bfa768a47fc20be6c264f422bf718865259c17c103bf47289b3abe62f93452781c6303d757e76d3d56ceeb26262fab","up":true,"one":"ab1a3542d67ef9d1a63653990bf0782f53b0169fe5092adc92fa7aeb38f66c6b62d49e3455cc2ac4994bfcfb03111953acf4cc3099026672cc61f6e24cb3ae00"},{"one":"c0bec7375c66bec98524ade2245c1d7480516fc5d87a3249e64ec86418e80e202f1e3da76832e97bbc3dcaed8c96ca344e4829347b4428f4b1cb61999e404c05","up":true,"other":"c206d8689068488179e86ce549de75989e0b17cbe09880d18fcf0fa212e629345f1b899203607a2b083569cb3f8398e501843166f5db23ac7fa7dacfe26dd3f4"},{"one":"5a6318af8b4615cf30610a05ade7704182fefd0a3fb3d76c47cb392e114d8d30004f0ec214326b11532fd1e928e66f632bbcde126a94c87774063853a9518dc5","other":"6b082a09e343a160b60a01f74641c1d707b2fa8fee5f6f5a8b9e4a203bd86434227d2df982b246a752f843483cdf517e85fe3bd65453354232a6eb38dedbf314","up":true},{"one":"7dd2801259c071a6e1dcc01d1cb74775fdec92da1da0b1eaf5f893cd5ed118894493ca5284c12bbd6cf7959449bc610d26ac6c9ef2845d1645d425f56ac003fd","up":true,"other":"7b4585f8a4e4904239994a1b8bdc76299da8e46a8a632fabc6c33dd4170f8f3715e4c4f526ea5dd14093b150855960e432b1b140594aca21995f9e0722fb57f1"},{"other":"76643f67075c6e45bd176db19473240cda6f886d1cac25330e2d99c84a429934f4c6a606c9c72574d5eaccd0a3f1770dab05e6ff6a5b5ce4d7258fed2bc13d48","up":true,"one":"6909a0fa47718cfc463b1e96c21734b46bd5b28dd59cd3d66d67990783436b7538ab2659d427029b97c8dddf313b26532518c0c34a2b1fca8cd852b0fdb83ab8"},{"other":"d6747e1f8594f7449fc6d7c0e63ee843480567d498db096ff04229420861c83bca5215fc19d8fede0c54484f111f1f2581e189e638c21c5d9e1fd3174bbb3e98","up":true,"one":"c2a9c77247871cfa4d3c2d1b47619df91ed5b331a44c8e21f7c9ce431a4db9dfb87713558cc8a37911393907b4cc60be9445bad18adcea1bc5f318256e71be14"},{"other":"d6747e1f8594f7449fc6d7c0e63ee843480567d498db096ff04229420861c83bca5215fc19d8fede0c54484f111f1f2581e189e638c21c5d9e1fd3174bbb3e98","up":true,"one":"9d372d73848389cfa1676f0cdb030950980ed5b68d5b2ef8a058f1d2095b26ff0fafab5fd3c243296ee2620edc67752970ab47370270856287f8612d1b190a19"},{"one":"b152eb30c9f46ec39166016f03d289f98cc285ac62d204da32e5a003da14e4f02c64df8ae1d0c8a2a902adc5f7dd7604081a0b140c9b64052082f0861945f5a4","up":true,"other":"8f3e9102306a13adb91e01f7a847e7880054f1a7df8976d05facb3a8fb37d47cce04f25e18a19713e5c3da7541e96e829fc67c8b924b717d2d9586c9c12d4fcf"},{"other":"ab13f773f6f2ff73032aa5f79c8897b75dda29bcbb14aa511e9401c2417dc9c510253071e28c7833c8d62fd2aef16fcd0c14ce016fbf4fec1b9a2173c717603f","up":true,"one":"6c2788dec7ae7a77134065afc1174bb92b87833e87acaa72fe9e62c92d2017f217f9fbc5884cdfb7236a7bb75e463e49ecceb1641a8629516211d9699587046e"},{"other":"c2568576c2c9ef47aca0baca52709a4fa44b2ed478a062f7b161fac2bdba68568df371ac7754255fd07d79bb9918249a914946a6c318d579730bee9bc609922a","up":true,"one":"7c6e6a49429a4e24aa4aa5c7ba19684f77cd67d3744688baff6e7f1d74b7e9d2df85f3e57e0df0a9b960b5bf982a610c5639c3e7a6935ba13fbc77243b2dad19"},{"up":true,"other":"8e5e8366251e33277e7db6f6c04629b2ce3eee217e973acb97c83773671b0160c40732794584db741a29a763672b90f3bdf34151fd4a6986b9d0956dc61d9723","one":"85c0b055439f114dee5eb0961013c117a48d62b0f17c61a7fd92a84092ef09bb3bbce686aa96e14528d5663565c57d657fa9813b1f38e268caeb1cb0842ef232"},{"up":true,"other":"1cdef98d7b4de45c902c725384bd14c66084fe4159b26a0f9a24f432e1f561d035ca41e1c60fe64f3213b4f91a1afb953193dca1a7d535be0602b5d046bcbab8","one":"936fad959da2d8b0cfb2bcd78c5da65bcce5e9463be7fc7367f45cdfa20678f4c466fb1e3f600783a270855fd4b9cd6265054f79ecb116141e7c67a492041bed"},{"one":"d43bd6d3ae39a04e4e144a8a6f80b2d54472b5b9b6491dccf44b1716a63d24c56e3a871b3b8fe983d992988dc07ace06736ead3b1287914b629fcfe17e81f36f","up":true,"other":"5d002c37b74a6656db86f102b0cec82bc35a819a480e5a2952db0140ebab65dffeb1a79f04d53ff61447b5fad7c58cb75ea1c91ea47fcb9e024f27b92c6c874d"},{"one":"b8e0a56df21baae43058f575b714ae9a33c097d18f1a628b3b6ae5e86dd46a06e44c0dc272baacb5be0f7bf57fd6ddce107544eb3b94dca1aeae9f5773496a72","other":"488854534ec5a3479d8ee13d9b7daf07479f6b5505f319eced44dad8c316f6ff241ce2101e95608ba635067f5e5741481b78f419c4bbd465bf7e837dc4e54d64","up":true},{"one":"a48cd04cdc66e1bb182529a789e1417d60d5e7d0f73068c1b17c6f231defeb943357789123e8d89cad90d1dd1726c48b808300d213bc1ddf7ae43cd58527f1f3","up":true,"other":"85b6404a76b4762156c8ddd2f312763dfe19b315d914533844cf229301880c57ffeadc0eb5f4a8d542e1d9fc961dfb5a572d2101172b1a0fc238ced05ba49ec1"},{"up":true,"other":"10551c0c37abc25457903978868dd4843a52fda5f9b571b05ebd974d8c381fda4349f17c2b986a2e4b8d06b0517422f085d5f6d9cd814efa40e48393d9f71d7e","one":"c402495c2110a6531a530ebdcd9ab1b883f1c707fe25aa13a255a0a9edb4113669b4aee9eadf803f9fe4c2ef66d5e4dff7064549f672598410f2d9794747a600"},{"one":"a48cd04cdc66e1bb182529a789e1417d60d5e7d0f73068c1b17c6f231defeb943357789123e8d89cad90d1dd1726c48b808300d213bc1ddf7ae43cd58527f1f3","other":"c0f233e79d0a8d4af01f54c40640975bc113f464271ba8922fca0c28acc60367af0db06629e701977e86cb5917c891e39c21418cab459fe49132b680aa31600b","up":true},{"one":"3a2cacc430f13f31c52b7205455420cf0fb9ed9e28b0898b69ef97951bf295b29118e573a42dd97abe38fee5ab4c03dad9ff6dc448126cefc1da12b6c8e8d915","other":"c9d705012a06d82c4d44db95b4f1c63ddd33ad64d732e96b1d878caa0caac433d4096f01495a6f0e8a56af122b0470fd745db6d906353b590a4710472b93f5b2","up":true},{"other":"bc0df855bdadcde3e447415444f655eb430925a8fa81cdcac75909e7d79750f01827938570e75e388cc7058ba8ebca47afadf8b07172bc078488fb618ba71024","up":true,"one":"ec19efa1d488e74da6bf239825b24678f549c377326c5d33d100b708a9a28a3fe129d542d7ba71e0ade46c15c6e9b38f09422560444388e609a8a66ceb8e0ae8"},{"one":"c6ad9b9de5cdbe28540f4eb7c66fb37f6d4295e6e60c6de54e2a45c1970b8e0047558e986bbd10e9e86c8bb0407846fac4823e4570e8a1486fc4bf55cb4a0986","other":"5717a49591a0ecdff3d4449874d5ff9ba016afad5da19712ca0c8ebca8cefd84e6d8c778245f67f68c8dd730ad294fd017b8de279fde4fc919768ce85dba132d","up":true},{"one":"1489ad735e1256900e4733707f8b78f1d853742a8f9b2d0c1c89651c60e7ee9d266afba5b4c1ed3f9cee05a1d2b2bba35dadb5b08973a93fd70dfb9e367339bd","other":"58f9139905ae1d005950f110b7ead3355672ecc478e8c66393566c64b935003f6fec3031dc9eb21cda660acb1955cf7bb33a20fdd74d493f29868ace328fcd75","up":true},{"one":"876618c8ba66c1b91b473a154be3e10ded3590ba83d620d30e0ff1fbac2f31f258b1299a3da5b56aa03269a80c119b7fc41dfd87d5bd996359e4ad8dd0ab2a6a","other":"28cdd55fc871ffd8d63d05994be706959c9780dbfc859070a41047a1b40dd5fd7adb53919400a4c6f4d06c69bc1ecccc0e230e5b702598a7fe8003a282479872","up":true},{"one":"dd3dccc1758765569905b3b137ef4c7dd31c2dc0dea827bcc4c4e976be94ffbb0f2ef6fe725cf9042063a96d663efea546837f35ca1fc67a854fbc9e27abb754","other":"43086ff7ffd3c7bdec77bd288f41f1ee0ce21bd3f60a5df8931e2af6e7af5ef0fad432d29625491935d11567944351fc7867c807ebd12dd2c21c9e620ae0f85c","up":true},{"other":"69f999937943be00e5fca5c7cc942ce13b6752a72813368da2fbfcf74ad807bc6edd85537e087b6f73c0469c7b76a5d8f7d883bd315f3b35af32b8da293ed243","up":true,"one":"0c9a05514b96e7c3a0fbca21552e158faa70047246b230addca172a5023fd7439acd1c3a0b4f9191579b308dab38c961734ffdb36fb8e16383e912d070fc0218"},{"other":"6a55b94c9990249b24cdbeed96f065137f7b79ea8ee5f58da150d3962dfb62ba401960a53e7e8bd4e2c2908aa1a59b9d5efb4aafb316a9ab4fa67a0d95b58c54","up":true,"one":"ab1a3542d67ef9d1a63653990bf0782f53b0169fe5092adc92fa7aeb38f66c6b62d49e3455cc2ac4994bfcfb03111953acf4cc3099026672cc61f6e24cb3ae00"},{"one":"c6f38fe8a0f2b3773bae332e0ca7516e944bde186fe99daae10a2b0aecde3ce23c1834eaad97a4e6d2da8cd53a08dbafa72d2b827c851b115b74e8010125dba2","other":"46717bc5fb7fcbcdc961e7ef091020f9f222858cf3d4afcc0b0bb1b782b7055d9eb833e0a04cb32d80406133ac77162521c43edf9f9690872222760e31462ccc","up":true},{"up":true,"other":"6b7c94db790a2c1b903208904c4c75b66b17e7a00404727dbc7aeff404ac1118dc78ce4ca443f6b5245236f9e358c09b6da027ae1144e1a6682edca301176330","one":"869ca41ea1f82bec5f43807a3aaaabc39b21c62d3c9c8bdc0709683e22dd37cb2f3c313766809076d2c02d0d6171f4f32a1b5080abcb8072d88981042ae6237d"},{"one":"c402495c2110a6531a530ebdcd9ab1b883f1c707fe25aa13a255a0a9edb4113669b4aee9eadf803f9fe4c2ef66d5e4dff7064549f672598410f2d9794747a600","other":"9ea856ea440c776b9ffaad1237ec11d570a1f912a908b8363ff97cf7947d2523e3c73663240d8fac988698cdd81e877ddd4a609485fe9f26494136fae14212df","up":true},{"up":true,"other":"69f999937943be00e5fca5c7cc942ce13b6752a72813368da2fbfcf74ad807bc6edd85537e087b6f73c0469c7b76a5d8f7d883bd315f3b35af32b8da293ed243","one":"99a7649bdf2ee7f0bc049308b0997e33abb68481c05a573df9aea30da5a1f267df07b2c584e3e985baf31704f04ad2a2c4876e0f8555333be6d09f5080b583f1"},{"up":true,"other":"6b7c94db790a2c1b903208904c4c75b66b17e7a00404727dbc7aeff404ac1118dc78ce4ca443f6b5245236f9e358c09b6da027ae1144e1a6682edca301176330","one":"b1dd1b08975319030626aab821032a0c687a103ee8942e8a2e2cf029dd72832a49630e78d2d8b184579f22178aca0e875f9fad701fb81afd2ac110ab2b417376"},{"other":"c206d8689068488179e86ce549de75989e0b17cbe09880d18fcf0fa212e629345f1b899203607a2b083569cb3f8398e501843166f5db23ac7fa7dacfe26dd3f4","up":true,"one":"c61ffc88f23f9f536497cc10ffcb7000ec6c4b801998ae7075ddc9079fdc1da8350e68744dc9e95ff892dfc5e52c62a3ad913a87fdacc455aea99b09aa002b57"},{"one":"243164c4dd583f80c50813f43e5c27c894463400cd3afd776b36e79e7123d9261f01f06f92914aab83096b9a43fb655e79687590599284640a3a7d2c25454597","up":true,"other":"df9306a263f40e0e255996500523354de3cc78b68ae560f66d79f6ea28f30f773f1fd6ebc33928723dfde2ee3d4f982b203bee4c3803a5050df83477045bb279"},{"one":"2880e0defd1bf2665bdd20dfb46bc0a9ad707f495211fc78e611ab479d78398db7daff7d3f4b6bf81fd13bf766ecc8271e0ea99a2d74abd2f9ddf98835ffdcf1","other":"aa2028d356a88eca8e0fcaf218d62ace099c3f72dfd95bb28f30ac9a926034cf1d60a40511f7495652745de80d71c0f6830019e206c88e2b6ef0cf4f05d7fe9e","up":true},{"up":true,"other":"243164c4dd583f80c50813f43e5c27c894463400cd3afd776b36e79e7123d9261f01f06f92914aab83096b9a43fb655e79687590599284640a3a7d2c25454597","one":"510536aba28aa635d8a1098a6dbd2070748ce1eb0e14b54b93a21196543a60df546ff6a2b3b5b9f32a5c2a37f5aba77d0b74f28b2dabeeebf3fe5afc20a3209c"},{"one":"85c0b055439f114dee5eb0961013c117a48d62b0f17c61a7fd92a84092ef09bb3bbce686aa96e14528d5663565c57d657fa9813b1f38e268caeb1cb0842ef232","up":true,"other":"d43bd6d3ae39a04e4e144a8a6f80b2d54472b5b9b6491dccf44b1716a63d24c56e3a871b3b8fe983d992988dc07ace06736ead3b1287914b629fcfe17e81f36f"},{"one":"b60def37233dbbc0d5f7fcddb304be1c0b6508e1e3d8a09a8290f7363e9bb84152dcaf70b8f6bb3a882fee77ff03ab796a5c1c3654f251c9f5c746ac5ad88556","up":true,"other":"6909a0fa47718cfc463b1e96c21734b46bd5b28dd59cd3d66d67990783436b7538ab2659d427029b97c8dddf313b26532518c0c34a2b1fca8cd852b0fdb83ab8"},{"one":"b8e0a56df21baae43058f575b714ae9a33c097d18f1a628b3b6ae5e86dd46a06e44c0dc272baacb5be0f7bf57fd6ddce107544eb3b94dca1aeae9f5773496a72","up":true,"other":"ee3471e1d835c4294f7ba642103039ccc548fe4edc177c79b63433ebbb0dc9d06600844f1fed76c7096ee9538e49e4e86fb8cffe9095dbdcde27695ff28ad395"},{"other":"c61ffc88f23f9f536497cc10ffcb7000ec6c4b801998ae7075ddc9079fdc1da8350e68744dc9e95ff892dfc5e52c62a3ad913a87fdacc455aea99b09aa002b57","up":true,"one":"2880e0defd1bf2665bdd20dfb46bc0a9ad707f495211fc78e611ab479d78398db7daff7d3f4b6bf81fd13bf766ecc8271e0ea99a2d74abd2f9ddf98835ffdcf1"},{"one":"b8e0a56df21baae43058f575b714ae9a33c097d18f1a628b3b6ae5e86dd46a06e44c0dc272baacb5be0f7bf57fd6ddce107544eb3b94dca1aeae9f5773496a72","up":true,"other":"97b1eaf8274ece76d75e7f60126f1b351ed5fe55088b9fcbb825a3a8d8f84f61bc72469916b280497dabf01345057525cae89da73c9a1a8a8cd19367d44dede1"},{"one":"7a8cb96685c1b8fbaeb18c8dc1f9f2631b23bc035e704e2f5df915b8bcabd6e2025ddc30324c69833f86e577b250c0721fee9d294f3e22016ae4c59c5f88845b","up":true,"other":"b183f12f3602bfdab0480cb0b0ba7dc69b267b0dbc7e54c316741cb78b9e99aa69fd321ad7755d095e9be14e6bd90fe14ef8fe9bafc1a0dea10a144795021a08"},{"other":"1e3a2f2491b6acb07a9549d9929d150479a0313c926b0e236237bd541303da4b563a855016a90ab50e59d94803ad566798570fa981464c94c04a4a4a94fbc607","up":true,"one":"17ae0b24297a3e6e027884e5e4529b6646ae340f5736eebc6187a9b59832a445f3644172d92438351e3803e56a67472b29f3e1d48844ae2e11e5e6670eed1436"},{"up":true,"other":"e0875ed6be1e163b15c13cdf37442f838670d0949349ee9ff119a0451beffb1a302943ee9d7cba48592922f64908aeb0f39f6e2e3725d1e7cdc5db34083b6977","one":"8ee65c0937cdf860d5329132c34bf28b5dc4d2593986fae80e4b35efb54ec24cdbf294223515363a917a22dbc6db463c10c7484e22b479b9010059c2521b6317"},{"one":"ab1a3542d67ef9d1a63653990bf0782f53b0169fe5092adc92fa7aeb38f66c6b62d49e3455cc2ac4994bfcfb03111953acf4cc3099026672cc61f6e24cb3ae00","other":"a47697063a2fb973449bdabd0925e10944ba1f6d8b2cc5c38b295f611eea3402b5cf3ae857716a34d84194955f5ed61350affe56223349124c8233852141f9a2","up":true},{"up":true,"other":"69f999937943be00e5fca5c7cc942ce13b6752a72813368da2fbfcf74ad807bc6edd85537e087b6f73c0469c7b76a5d8f7d883bd315f3b35af32b8da293ed243","one":"c6f38fe8a0f2b3773bae332e0ca7516e944bde186fe99daae10a2b0aecde3ce23c1834eaad97a4e6d2da8cd53a08dbafa72d2b827c851b115b74e8010125dba2"},{"other":"e0875ed6be1e163b15c13cdf37442f838670d0949349ee9ff119a0451beffb1a302943ee9d7cba48592922f64908aeb0f39f6e2e3725d1e7cdc5db34083b6977","up":true,"one":"a48cd04cdc66e1bb182529a789e1417d60d5e7d0f73068c1b17c6f231defeb943357789123e8d89cad90d1dd1726c48b808300d213bc1ddf7ae43cd58527f1f3"},{"one":"e8a679f627d03347a4fcec0a0940f7ffa90ce3fefea290db3af4f3a32d27965bfb51832b6a6de2495c8a8cc026bcf993b84a0cced778e158bb81c034f5e4bd76","up":true,"other":"7cc9389c8f751465e0b94baed896f6f122631052300b1b5b23d3c7656e4d11014a7a9ae62a1287bb040ca37221871a566cd470e523846df7e3acb5f94c7cde06"},{"other":"7958d1517de1223e7fb30acf61d8618e49fb95a03bc2f49141f4c7967bc80b90e0dd526c205639de3c060029963d43813293c2556f7b127945c798f3f9f18626","up":true,"one":"e8a679f627d03347a4fcec0a0940f7ffa90ce3fefea290db3af4f3a32d27965bfb51832b6a6de2495c8a8cc026bcf993b84a0cced778e158bb81c034f5e4bd76"},{"other":"4116fbb7d55bfd4bd8db9cbfa570ac361bb88605b6aacbf84e245893cf3fa599ecc086688a4c534c81f61a90fa344ca37e4d4013ddc03f7f08218724a55f66b1","up":true,"one":"207764262a208c17db61fda4208d4664bf74010e0ad051a863e131e748c9304e11ccf007c925488ea86b974ee61cdac3dca4d4b3f4043524e03c194ab3c8eb5a"},{"one":"3a2cacc430f13f31c52b7205455420cf0fb9ed9e28b0898b69ef97951bf295b29118e573a42dd97abe38fee5ab4c03dad9ff6dc448126cefc1da12b6c8e8d915","other":"dbb6621460b054f584f1c6157b4020f3c58d84c3a12b57436e10525ae60ab27036bf3edd68b92f2b13674877d01c2871dc67a9031c3d0470985f4b071696346e","up":true},{"other":"b1dd1b08975319030626aab821032a0c687a103ee8942e8a2e2cf029dd72832a49630e78d2d8b184579f22178aca0e875f9fad701fb81afd2ac110ab2b417376","up":true,"one":"3a2cacc430f13f31c52b7205455420cf0fb9ed9e28b0898b69ef97951bf295b29118e573a42dd97abe38fee5ab4c03dad9ff6dc448126cefc1da12b6c8e8d915"},{"other":"4eab70233789c544bec97040a04099494bf269a819584a5d0b42295c918a52b02f224a8ed127aba3d92c02f567356bea4b95f77230ef548dfa7fe44b643d8704","up":true,"one":"97b1eaf8274ece76d75e7f60126f1b351ed5fe55088b9fcbb825a3a8d8f84f61bc72469916b280497dabf01345057525cae89da73c9a1a8a8cd19367d44dede1"},{"one":"fc9b1b2bbd5e682eb350d23f3ee33b245495daedae9370de7b1f55f91cd45db831d196c17615e11decf6b67696a268ac788130e3de38c7f6aeae811f3ec8c8ee","up":true,"other":"d6747e1f8594f7449fc6d7c0e63ee843480567d498db096ff04229420861c83bca5215fc19d8fede0c54484f111f1f2581e189e638c21c5d9e1fd3174bbb3e98"},{"other":"228b3646b15527f4df07b847a62dbf9620cb068f829e9086b5f437d0b64d8a027cab44f19db5e44189b5099545ecb25d49384c261748f9533cfb0eb11a1eca5f","up":true,"one":"3f322f9b1f1f0692663bc3be11cf11386f4a14696aab610916cfcadf0234cce0c86b51c85ce2108e9bc21d50ad71cc10a6eeaec3fc7732908f3a8b193465a0ac"},{"other":"ba430731fc2082f4217ebd859c2865c28bf50a39674ca8615dd89f608ae434a09657e24644ac32807634aad7857547118c9228460195e50ec58b34789d4ad151","up":true,"one":"7c6e6a49429a4e24aa4aa5c7ba19684f77cd67d3744688baff6e7f1d74b7e9d2df85f3e57e0df0a9b960b5bf982a610c5639c3e7a6935ba13fbc77243b2dad19"},{"one":"7c6e6a49429a4e24aa4aa5c7ba19684f77cd67d3744688baff6e7f1d74b7e9d2df85f3e57e0df0a9b960b5bf982a610c5639c3e7a6935ba13fbc77243b2dad19","other":"3a2cacc430f13f31c52b7205455420cf0fb9ed9e28b0898b69ef97951bf295b29118e573a42dd97abe38fee5ab4c03dad9ff6dc448126cefc1da12b6c8e8d915","up":true},{"one":"6c2788dec7ae7a77134065afc1174bb92b87833e87acaa72fe9e62c92d2017f217f9fbc5884cdfb7236a7bb75e463e49ecceb1641a8629516211d9699587046e","other":"212a8048ab9925171475e81dce047865df186222d673d524c810a9f613e4a21f3b130fa34c5f44974fbeaab1f6028177e71568e00a1184d9fd05443c172f5fcf","up":true},{"one":"6b082a09e343a160b60a01f74641c1d707b2fa8fee5f6f5a8b9e4a203bd86434227d2df982b246a752f843483cdf517e85fe3bd65453354232a6eb38dedbf314","up":true,"other":"5982e7dfd39c527851f6ea6430b70e654d95df5ec4401ca1d8dbd1034cf7a65d1126d60b36ebbd396c9ca32e6e8515f34f9dc0a8d2980afe4aa181c8bf68437e"},{"one":"b183f12f3602bfdab0480cb0b0ba7dc69b267b0dbc7e54c316741cb78b9e99aa69fd321ad7755d095e9be14e6bd90fe14ef8fe9bafc1a0dea10a144795021a08","other":"8d3ad57509b36c4ca5c4663f3d1977a3125e069078842634e6cfeb22c044281e3d02f06eafc6d2a60089f03d70f5134a6635c35563c9f911fd845a6ef9bc8952","up":true},{"up":true,"other":"bc0df855bdadcde3e447415444f655eb430925a8fa81cdcac75909e7d79750f01827938570e75e388cc7058ba8ebca47afadf8b07172bc078488fb618ba71024","one":"b4557089e4247379e587a087f53b36dd1f86f85d9dcfab5dc562079978cd959adaef5b30d11258d9cb552e7c5abddf5377a71d449febe8f2acb0aec3ebd8ba73"},{"other":"7c6e6a49429a4e24aa4aa5c7ba19684f77cd67d3744688baff6e7f1d74b7e9d2df85f3e57e0df0a9b960b5bf982a610c5639c3e7a6935ba13fbc77243b2dad19","up":true,"one":"ecd217e8bdb53c9ef085929b8c2d2b40425a4be617a087b8e7f88e8507b3c981e90fda2119744ca394fe65bd4eb1cdd3fa7258db936048e236d2f15ee91bc3b6"},{"up":true,"other":"224c3b969149d50d1bb4f473bb9725223c1dafe152efe1b08e8859213c543a66565b5d68a99cef3d5f4eccad6282a12f78d7b38eec14deebf44ad8dd9cba8680","one":"a8fac88fba179fb9b259d94caac9cbe45d873a0131bef8844ac4383b177daf6f301f8793623fec5876885db1a91e5b3e98e2aafdaa47e03b1f6d9740f48af7ac"},{"up":true,"other":"8e5e8366251e33277e7db6f6c04629b2ce3eee217e973acb97c83773671b0160c40732794584db741a29a763672b90f3bdf34151fd4a6986b9d0956dc61d9723","one":"2bea7540c99456ea889a8ba2e448c11e6257bf987d01f13eea48128ba58577ab0936855035ee140c9907e382a34ca85a179c74892cbd9eb92fc2b35601addc6b"},{"up":true,"other":"b8e0a56df21baae43058f575b714ae9a33c097d18f1a628b3b6ae5e86dd46a06e44c0dc272baacb5be0f7bf57fd6ddce107544eb3b94dca1aeae9f5773496a72","one":"8c459100df488b992fdad207a096a434d67cb733619adfd09a311095568d4c9db293d9a892675551805559456d49a3fdb19c2cc698b14552bf0ace584d4d90dc"},{"up":true,"other":"9bea5f82c2a390587de44d620d6637834e6f2329cd83d8df6305b03b75d9b543160b6c6f9f8887e6bc88f1d0726435d6c8ad813aadad0653b0790b8f6388413a","one":"535287ca3d41fc1cdf20a964749a849c51d0aba285f41f447cc2b1dd6f5845b6b98e0241dbda0718b234ea850081bfbf9df01d1aa636d7dcbd99ef3c0a773aff"},{"other":"c29e80096fbe7bc9fcbfdbe3cf6c06449192a3ed280e46a1fa5d424428d893c3456c985c1352c119236cf783834365439751cc87e7ed196614705dd3db6674cf","up":true,"one":"8c459100df488b992fdad207a096a434d67cb733619adfd09a311095568d4c9db293d9a892675551805559456d49a3fdb19c2cc698b14552bf0ace584d4d90dc"},{"one":"e993be8034861aebc9bbd11115f25d9c719d43fcdefc323599616cc26240cee38dfc27bb7f339149a54a3c9ad13b2d6ca4f0ae690e4355605eda6b789c4a431e","up":true,"other":"01427ba4d1e2de0b2764515556676a6058f88c16f597780dea3d7f95a6eec9299c3987d99c199d88a0a5e695ee6f0ff7de424e4eb65e54233b956a9634133998"},{"one":"224c3b969149d50d1bb4f473bb9725223c1dafe152efe1b08e8859213c543a66565b5d68a99cef3d5f4eccad6282a12f78d7b38eec14deebf44ad8dd9cba8680","up":true,"other":"8e89fe4b3fffea8af247d2581aa511056efbeb796058d50a341d57aa0f7ccc2192d90cfb8d18558363df798567faaddb86815e8bd671b36ca37af0651535aabf"},{"other":"58f9139905ae1d005950f110b7ead3355672ecc478e8c66393566c64b935003f6fec3031dc9eb21cda660acb1955cf7bb33a20fdd74d493f29868ace328fcd75","up":true,"one":"d7e3661c0af6754c875217f93d34b254f1f45fc1359a4c6146cd0efa4c6e12aed9a4fb0a21a136f73af4fc2c6d0a63cb809d81855bbc9f51e29d23d90f77b326"},{"one":"535287ca3d41fc1cdf20a964749a849c51d0aba285f41f447cc2b1dd6f5845b6b98e0241dbda0718b234ea850081bfbf9df01d1aa636d7dcbd99ef3c0a773aff","other":"c0bec7375c66bec98524ade2245c1d7480516fc5d87a3249e64ec86418e80e202f1e3da76832e97bbc3dcaed8c96ca344e4829347b4428f4b1cb61999e404c05","up":true},{"up":true,"other":"e0875ed6be1e163b15c13cdf37442f838670d0949349ee9ff119a0451beffb1a302943ee9d7cba48592922f64908aeb0f39f6e2e3725d1e7cdc5db34083b6977","one":"9c8fca41b833e88110559b9258653160f5fb236bd637272ac58fe1adf333f4df75b94a805eaebb9f10a8c1a26d357dd75140560551d3fc4da79da2c4fc9479c3"},{"one":"e993be8034861aebc9bbd11115f25d9c719d43fcdefc323599616cc26240cee38dfc27bb7f339149a54a3c9ad13b2d6ca4f0ae690e4355605eda6b789c4a431e","other":"9c8f156797deff649d74d56fc42b4bb1a87312089114d4350424c375837d9c8068dd09af01c1c973d12ec5d7e8da600cd685cae70d3116b9dbda823092e03fff","up":true},{"one":"9c8fca41b833e88110559b9258653160f5fb236bd637272ac58fe1adf333f4df75b94a805eaebb9f10a8c1a26d357dd75140560551d3fc4da79da2c4fc9479c3","up":true,"other":"24047e1a816cbf9b7a90e6c78dc896a3b624047ef5cfd3aa495132d57b1074aa129ea6eff171f5cca91d0f4793a07c9672b0a55232f2415c6220e443ebd0791d"},{"other":"6c40910f0556f892a7542989fa01d7e3682fca89aeefb5ed885808f88ff17b6d13862f461c10d629a005ae67abef542d75e5b20816891b6944f71560f5c2dfa8","up":true,"one":"224c3b969149d50d1bb4f473bb9725223c1dafe152efe1b08e8859213c543a66565b5d68a99cef3d5f4eccad6282a12f78d7b38eec14deebf44ad8dd9cba8680"},{"one":"c2568576c2c9ef47aca0baca52709a4fa44b2ed478a062f7b161fac2bdba68568df371ac7754255fd07d79bb9918249a914946a6c318d579730bee9bc609922a","up":true,"other":"c2a9c77247871cfa4d3c2d1b47619df91ed5b331a44c8e21f7c9ce431a4db9dfb87713558cc8a37911393907b4cc60be9445bad18adcea1bc5f318256e71be14"},{"one":"ba430731fc2082f4217ebd859c2865c28bf50a39674ca8615dd89f608ae434a09657e24644ac32807634aad7857547118c9228460195e50ec58b34789d4ad151","up":true,"other":"b1dd1b08975319030626aab821032a0c687a103ee8942e8a2e2cf029dd72832a49630e78d2d8b184579f22178aca0e875f9fad701fb81afd2ac110ab2b417376"},{"up":true,"other":"8e65496318637446a51f0dc87d0a5cf82655866cd1579db1e381af52e12545172b9c88119999ccac3b8b8644efc9675ff183ebe7584c16eb40792cc21f7e9b76","one":"ab8eda9b360d3e0b002ba31d48311057880844b828ad9817a2ad19736860d0114d4a17e9e9427c842d52e7ff61a09c2cad9b70f506e338909535542dae38ede0"},{"one":"5d002c37b74a6656db86f102b0cec82bc35a819a480e5a2952db0140ebab65dffeb1a79f04d53ff61447b5fad7c58cb75ea1c91ea47fcb9e024f27b92c6c874d","up":true,"other":"af9b80f6836113aeda897d6903e9ffb4f7f1a706a7f821d0d40f03a0d83c18d6a19795ee4bfc1093ada04014415b1f230db1d2f056df3f5027cce71611588046"},{"other":"3948a7a939b9a1f4201953bd9b955ee7be87d09b63c7a45167f556ac06fe3c4c2a75d935bff50668da5e71e46802b55d7a9945a92d7807c00625d129cbb48f82","up":true,"one":"002cb6ffa63ad71ee6ebc1df4c41f7a97c51f274b1d3b22420c87b73136be5169b9670508061d8261e20055fefce3b855388994672aa9a0f1475c43839aae4fa"},{"one":"b152eb30c9f46ec39166016f03d289f98cc285ac62d204da32e5a003da14e4f02c64df8ae1d0c8a2a902adc5f7dd7604081a0b140c9b64052082f0861945f5a4","up":true,"other":"6c40910f0556f892a7542989fa01d7e3682fca89aeefb5ed885808f88ff17b6d13862f461c10d629a005ae67abef542d75e5b20816891b6944f71560f5c2dfa8"},{"up":true,"other":"17ae0b24297a3e6e027884e5e4529b6646ae340f5736eebc6187a9b59832a445f3644172d92438351e3803e56a67472b29f3e1d48844ae2e11e5e6670eed1436","one":"c2568576c2c9ef47aca0baca52709a4fa44b2ed478a062f7b161fac2bdba68568df371ac7754255fd07d79bb9918249a914946a6c318d579730bee9bc609922a"},{"other":"d09104c44648391693ca64a57baa5ef54ed717e19c65ad0a0921d08cbaca8877d0190795d15f75f3b6ce6e676d6b0e55d5ee8fec3310c68b7060a32f7ff649cb","up":true,"one":"f8a5ae50e5b2d84096c10a6a8493a9eb8113df64c4f1336c0cf4649302649b158fa4cb7941591e55356891bcc1008a535df427546af19988a241c5f466467963"},{"one":"f8a5ae50e5b2d84096c10a6a8493a9eb8113df64c4f1336c0cf4649302649b158fa4cb7941591e55356891bcc1008a535df427546af19988a241c5f466467963","other":"8e65496318637446a51f0dc87d0a5cf82655866cd1579db1e381af52e12545172b9c88119999ccac3b8b8644efc9675ff183ebe7584c16eb40792cc21f7e9b76","up":true},{"one":"431644cf162bc267237c4e798288888dd835c1b0546b0cc679782e33568988d75b4294f4aa08359a6b152ed9a0fbd13133681156bcf09a871c4f362615ea6dae","up":true,"other":"fd0123c7b96004067e98e463e273de5bc5402399ae70a95985b5f682e30d4f35d070deaf8c71d201e98c4324d832b95aab7535ad8a2658f66e3e0bb1202204e1"},{"one":"95ff4dea07303e1ba641a5c510e714ef232f4dbce9ad2e8b2f62644975eae41fc4bb9d1af3fae4d5ea4daeb18f8248e0b3131c7d843d35d33f3afbf7dfa4c2fe","other":"3e7aef8260c0d9717aa59b65ce7c554e53b81f19f5b9400321704a7ddf5041b0fe31b5634e90b93e6984060defee0e153997bbfe196166cc8d83165fd5eaf41f","up":true},{"other":"3e7aef8260c0d9717aa59b65ce7c554e53b81f19f5b9400321704a7ddf5041b0fe31b5634e90b93e6984060defee0e153997bbfe196166cc8d83165fd5eaf41f","up":true,"one":"b7cc9044d021b19cd8a6d290d21f1c91fd5deec472583d0aeed0a6aacc8efef9968079254132becc5443df14dd3f4feaee56d14b885c078649727b9659139fa6"},{"up":true,"other":"3e7aef8260c0d9717aa59b65ce7c554e53b81f19f5b9400321704a7ddf5041b0fe31b5634e90b93e6984060defee0e153997bbfe196166cc8d83165fd5eaf41f","one":"4b332b389f1142c0da42aaeb2e2692081d0002de0eb6741b3269e898a8101571d4556b755f2e8841e7a607bb41e398d2b0577fbe71098e7097f0fe6c720e1526"},{"up":true,"other":"f52297fc51b920d2495ccece290432656d9388e698339c8c1279ceea45de698a4ecbda1d25928c48f1e19e9dacd3147e23ef01acc093872d7300aed187841dcc","one":"eb58e478b16056e0af344397cf5f078a3312a6db2189ec2042ec06ab6550e3ee71ebcfeff1814332c552c12a5a488f96b3f2935e90a189d238da19d30a2c9874"},{"up":true,"other":"99a7649bdf2ee7f0bc049308b0997e33abb68481c05a573df9aea30da5a1f267df07b2c584e3e985baf31704f04ad2a2c4876e0f8555333be6d09f5080b583f1","one":"e0a043f98b462f10f72aa61ceda52f9c27829d086f6f2c5bf4db4fe32759002e5ff9519495d57dbb83d963a1dc991a1defcf5b9ef0d543789f38c68f5d07122b"},{"other":"545237d8463b75fd2e9bbfbffb35c5b78b4abbc85f6bfbd56976789012dd9a62ca1f866bf37bb33618e026aab764adb9ced5e00cd415562f69992f74c795083f","up":true,"one":"431644cf162bc267237c4e798288888dd835c1b0546b0cc679782e33568988d75b4294f4aa08359a6b152ed9a0fbd13133681156bcf09a871c4f362615ea6dae"},{"up":true,"other":"c206d8689068488179e86ce549de75989e0b17cbe09880d18fcf0fa212e629345f1b899203607a2b083569cb3f8398e501843166f5db23ac7fa7dacfe26dd3f4","one":"aa2028d356a88eca8e0fcaf218d62ace099c3f72dfd95bb28f30ac9a926034cf1d60a40511f7495652745de80d71c0f6830019e206c88e2b6ef0cf4f05d7fe9e"},{"other":"0c9a05514b96e7c3a0fbca21552e158faa70047246b230addca172a5023fd7439acd1c3a0b4f9191579b308dab38c961734ffdb36fb8e16383e912d070fc0218","up":true,"one":"e0a043f98b462f10f72aa61ceda52f9c27829d086f6f2c5bf4db4fe32759002e5ff9519495d57dbb83d963a1dc991a1defcf5b9ef0d543789f38c68f5d07122b"},{"other":"81901d9f043b4b1649ade3b5d22ae5f8bb42dd6db1eb37b836b99dd1c0388509ed4b54cc5638c9d4a6c5ae6c6913bbfffb303d7d94bf4ed50e871cf95459e2c3","up":true,"one":"06aab75fed9a03f5525e3f1d8f8997fefaefd5b16e8f485d571beda00b1741efbb61a8a74fa12c2f6de66227c3fabb4d411659cd9c7b1ef32e171e6bf517cc39"},{"up":true,"other":"c9d705012a06d82c4d44db95b4f1c63ddd33ad64d732e96b1d878caa0caac433d4096f01495a6f0e8a56af122b0470fd745db6d906353b590a4710472b93f5b2","one":"588df3185f63a5443d8c6b972f67805f0557184d916005f537a4b27cd02bd6a12e432a2b34b234a34f22e923c6f116da85be20bad77a2bf69913684e9d0732ba"},{"one":"6c40910f0556f892a7542989fa01d7e3682fca89aeefb5ed885808f88ff17b6d13862f461c10d629a005ae67abef542d75e5b20816891b6944f71560f5c2dfa8","other":"69f999937943be00e5fca5c7cc942ce13b6752a72813368da2fbfcf74ad807bc6edd85537e087b6f73c0469c7b76a5d8f7d883bd315f3b35af32b8da293ed243","up":true},{"one":"1c080e90760dfcee08ade6e4ea3b275ff3c6882f3b44b7f3a73d70bcc816fc63ce0b6138f810d17d96ed387076f9bbb6dbb2ef6dc4d6ba6542c1f587b7602a12","up":true,"other":"3e7aef8260c0d9717aa59b65ce7c554e53b81f19f5b9400321704a7ddf5041b0fe31b5634e90b93e6984060defee0e153997bbfe196166cc8d83165fd5eaf41f"},{"other":"a25958cf192a4f62301feda5d442535f78b983dd9e4599354f4898c8c1e6ad97ca7112549e1d1a1eacb4682cd1bf8b762368b5905ab33dbdacb585b128514ca1","up":true,"one":"740919ebae9b4fe646ca716ebb8923bf2a1b1963767d86f55ea95911d88d163cc2e07b1420669e64b62cb267b625413444b783b8e4a7bd6a0f481f4d84e984b1"},{"one":"c69b9b181b2756a1345b73a97afb3dca909c253188c3b905f0b414465b750d2ffccb4c8e8eb5e3809549af55db473f3b12682f9bd97c5c75d68f23d67d91b866","up":true,"other":"3a2cacc430f13f31c52b7205455420cf0fb9ed9e28b0898b69ef97951bf295b29118e573a42dd97abe38fee5ab4c03dad9ff6dc448126cefc1da12b6c8e8d915"},{"other":"9ea856ea440c776b9ffaad1237ec11d570a1f912a908b8363ff97cf7947d2523e3c73663240d8fac988698cdd81e877ddd4a609485fe9f26494136fae14212df","up":true,"one":"869cae165389e7dee7b7df4e012ee1a39737366c306d8f4b0db4510b2236e0bd3a4d1d4af00b1a8c1d360e23da47de52fc1632edb03c7f1429aacc8aa4994750"},{"up":true,"other":"60995852a2385ce8d7d24dc94b85a2f0dab6e5c32e910dfe367ea9c6ccb7b0b2eb611fdf120f8c697097e2f137cefff42e8d9db16b664a857a38c5ace837ffa4","one":"a070b5cff5eff533a2267ceb0d88e221088038af773e18f80110c8a2c329f0543b8d43c4e6132e9416723e3e94c87f0053456760ced4426767b95cee36ed93f8"},{"other":"624248a794fd62248024360f128b2e503c752340694a316bed420e5ed2cebeb5bf970df95a2806732237a26de3778222b0454e2e7d2875129b193e7890fd5b95","up":true,"one":"3e7aef8260c0d9717aa59b65ce7c554e53b81f19f5b9400321704a7ddf5041b0fe31b5634e90b93e6984060defee0e153997bbfe196166cc8d83165fd5eaf41f"},{"other":"e903d7aebff96a6afa4b9dd19b0b02e5af18da8e4e89f64247e1a2c2d46637538c741182eac67f45ec61be76aeaccde57f0a0184bd608ea7d92e586d4f827ea7","up":true,"one":"c088bf88f1e152ca3fad17f098a71ca1021d46d8af12d0ee1c587a5e2a430d8e48beaf171fe01ee7680b671c00dd88c90f12a35c328a3f334661fdeee914a4bc"},{"one":"2c976b6007cda135444233c7bd03d22ac9756710b746c36bc032e7fdd42f2ffb89ca5f5e754ff96b8f3cbc474e346287e5b8531d9f98fd63c426c632872220af","other":"3e7aef8260c0d9717aa59b65ce7c554e53b81f19f5b9400321704a7ddf5041b0fe31b5634e90b93e6984060defee0e153997bbfe196166cc8d83165fd5eaf41f","up":true},{"one":"f4cdaeb513aa98f8868d8eb3a1d12c07367725928a1bc7d6ca4b583788e111a955463037ec7867260511896d97dfbf096aa77ee8a7d9ea1c06cad4a92c45108d","other":"ef7157fdfe62390d8a6d4ef976478d17465b42b63fddb03664973d63efb62318a8f59e412150528a32aa2c028b9de6bc67f05e012b8c43d710032ad871bc27e5","up":true},{"one":"e0a043f98b462f10f72aa61ceda52f9c27829d086f6f2c5bf4db4fe32759002e5ff9519495d57dbb83d963a1dc991a1defcf5b9ef0d543789f38c68f5d07122b","other":"b152eb30c9f46ec39166016f03d289f98cc285ac62d204da32e5a003da14e4f02c64df8ae1d0c8a2a902adc5f7dd7604081a0b140c9b64052082f0861945f5a4","up":true},{"one":"a5f7163586fce1750fd9a6e5c418af1c18ca6983069dcf1738fc9106ebf542a86e4ccfc50b45a0d97ca8681af8207128877f930f945e59ee262aa7f4014a01f3","up":true,"other":"77811b007dd1fc1b11e447858df37062e97b6fc14e059399814f3b4736188e3fb28bf7c3958bb8ebc6ae16c36884ba7c98b810fb6f8b358323412123c803abd4"},{"other":"e8a679f627d03347a4fcec0a0940f7ffa90ce3fefea290db3af4f3a32d27965bfb51832b6a6de2495c8a8cc026bcf993b84a0cced778e158bb81c034f5e4bd76","up":true,"one":"842ec3faa8b4a4cdec32abfa00ae827277fe2696e1b0c6551154533b16cf75ae69caf834b4f08488fa5c8b322fb633b1fd8a5b7d436e9c589cc9074dc031ae68"},{"up":true,"other":"643da2591098f9698f27cccf7c17832e0717ee6a1276398a1a29edc947125585dcfab9417c2721a8a55d4dfc75b826be7581b6e30b020f6341ac549877c9f122","one":"99af34b172d319633e07a4e528f416024653a230a9103a4b281171f75bb697dd6be4757558c94e86210b4da8d9fe1229f6a5d8c4174989ea0ce696f8d1a9995d"},{"other":"488854534ec5a3479d8ee13d9b7daf07479f6b5505f319eced44dad8c316f6ff241ce2101e95608ba635067f5e5741481b78f419c4bbd465bf7e837dc4e54d64","up":true,"one":"70cce7cb0c18091dbb6d41160ab560935f1759b969bf8118cee030ee707cb15ba407b8c48dcd9fd012cbf778e219f7d16a74064b4983cf098fb118297748edb6"},{"up":true,"other":"243164c4dd583f80c50813f43e5c27c894463400cd3afd776b36e79e7123d9261f01f06f92914aab83096b9a43fb655e79687590599284640a3a7d2c25454597","one":"e0f13606a7f35b9ad8a9c4e70336c4c554ac718720a451a349eb4e1a4b055079483cac040ec64e0ed3d8bdb336618a5ae6ef74e31642fae4d7ed9949858eb361"},{"one":"5d002c37b74a6656db86f102b0cec82bc35a819a480e5a2952db0140ebab65dffeb1a79f04d53ff61447b5fad7c58cb75ea1c91ea47fcb9e024f27b92c6c874d","other":"c674c405068bb908312917a319e24ddf90e814ee8ef54bbf740f176b2a7eda6950e3e1ed69484ebcc27b13d82c7f0b20daba71a17700018e769ca612ca8d2208","up":true},{"up":true,"other":"723f362e98f90d7ef15e24e353759fdbdabb08adab767dba73ab546741fac3dfb457466f1e2c851aa49526da1408f8ddb509e12f7dc0bc1e785c5b72be8a986e","one":"89d46e664ac471c7150fbfe43a49c98750fc64d5ca22fdc2a040c7ab78c25c48c1e9c2f0e5130d6b8eb7f0760fe962759d83f68cc08ffaac3520499b0ce694de"},{"one":"51a570637394e9ab61fe95b3a608cc4e9dc8ceb63efe717938ccd4260a962d52e01b30e7034fbfdabd9a3c9616ee569550b38a6d6b4b19847f523254069a9f27","other":"81901d9f043b4b1649ade3b5d22ae5f8bb42dd6db1eb37b836b99dd1c0388509ed4b54cc5638c9d4a6c5ae6c6913bbfffb303d7d94bf4ed50e871cf95459e2c3","up":true},{"one":"e323da6ae861cb092543992b8985639f9b3bcaf1c3c68757f4603a67800be62950fe7d8f8ef80eb83a18107b677c7f5047ea89a5790e0ea2a7969f4856d28488","other":"c9d705012a06d82c4d44db95b4f1c63ddd33ad64d732e96b1d878caa0caac433d4096f01495a6f0e8a56af122b0470fd745db6d906353b590a4710472b93f5b2","up":true},{"one":"69f999937943be00e5fca5c7cc942ce13b6752a72813368da2fbfcf74ad807bc6edd85537e087b6f73c0469c7b76a5d8f7d883bd315f3b35af32b8da293ed243","other":"29619924833116cb1160bf7a8066a528b7182794368bfae62b5bacbae680d9161a479f217e30c3b4f19a250b1b59e08f86c94726117dc3bc94ff9ceac6bee6e4","up":true},{"one":"7465fe601a9ad8e640069e6e07d56afabd3d4f008f3084f944d869b47fda3f511f191062802a53da511f60891dd0bcc5fac60254ef9db7aa3b41f5791b0b6975","other":"224c3b969149d50d1bb4f473bb9725223c1dafe152efe1b08e8859213c543a66565b5d68a99cef3d5f4eccad6282a12f78d7b38eec14deebf44ad8dd9cba8680","up":true},{"other":"06aab75fed9a03f5525e3f1d8f8997fefaefd5b16e8f485d571beda00b1741efbb61a8a74fa12c2f6de66227c3fabb4d411659cd9c7b1ef32e171e6bf517cc39","up":true,"one":"4116fbb7d55bfd4bd8db9cbfa570ac361bb88605b6aacbf84e245893cf3fa599ecc086688a4c534c81f61a90fa344ca37e4d4013ddc03f7f08218724a55f66b1"},{"other":"77e40e42f570a217f707888c714deb31fd70c856ae4b9a44ec7cee02768185dc4d7ed210429607f06690b32edd9fb06b304aff330a3949cc2fd49db1bc392edb","up":true,"one":"9bdacc256acef0433805477d38f32be849a8846d88cb883b19d290454639b42c6ab6c5c52d4f83453e8a156af7d85f606458aa9c0977c67282f56f34ff0acbfb"},{"one":"9bdacc256acef0433805477d38f32be849a8846d88cb883b19d290454639b42c6ab6c5c52d4f83453e8a156af7d85f606458aa9c0977c67282f56f34ff0acbfb","other":"869ca41ea1f82bec5f43807a3aaaabc39b21c62d3c9c8bdc0709683e22dd37cb2f3c313766809076d2c02d0d6171f4f32a1b5080abcb8072d88981042ae6237d","up":true},{"up":true,"other":"92dbb67da2b99a8fe46b1e510addc2b83e357ac0b5287b7ef5c1b1bc6e252b8dfd605a6896ede65848e429216d1f67d530d9e7b83ff14058aa2e5b6e405d6801","one":"6a55b94c9990249b24cdbeed96f065137f7b79ea8ee5f58da150d3962dfb62ba401960a53e7e8bd4e2c2908aa1a59b9d5efb4aafb316a9ab4fa67a0d95b58c54"},{"other":"f056acbdf491d1bb091937335c10096ea44b7034e994d134bc16d55212ff049bb097424de96c615ea699359a7ef77b3b54def2b3a5f43d735ffda65f73d61f7f","up":true,"one":"dd6acfd151220f21b03701ca554a5e134dbd1154dda21d9eec45809e7858fe83eca3953fc688f499030198f22052c3681a9f49207ef9b11a760456ab9637352b"},{"one":"e7b2adabc2c99ac47b1e94fc0a2c63a00a1d622ea67a4c1858f4cec93fca957d43d8429605761bdf5eed4f733dac1a3d12fb928f22abf248965994acde63864a","other":"9c8f156797deff649d74d56fc42b4bb1a87312089114d4350424c375837d9c8068dd09af01c1c973d12ec5d7e8da600cd685cae70d3116b9dbda823092e03fff","up":true},{"one":"af9b80f6836113aeda897d6903e9ffb4f7f1a706a7f821d0d40f03a0d83c18d6a19795ee4bfc1093ada04014415b1f230db1d2f056df3f5027cce71611588046","other":"dd3dccc1758765569905b3b137ef4c7dd31c2dc0dea827bcc4c4e976be94ffbb0f2ef6fe725cf9042063a96d663efea546837f35ca1fc67a854fbc9e27abb754","up":true},{"up":true,"other":"85c0b055439f114dee5eb0961013c117a48d62b0f17c61a7fd92a84092ef09bb3bbce686aa96e14528d5663565c57d657fa9813b1f38e268caeb1cb0842ef232","one":"c63b88f494b14d5a7c1da124ffebbd985d19806b91d4b111c83ae129c4ef19614469980a09fbeccebe3b0358dd16194bdb6452d0b3dbb43a5467e23bb13f40d6"},{"up":true,"other":"313a131ecb7d68e127d0fec8bb4a2e586886203c3d07857a93e7a39bb831703184d9ae28ba9ef3d986c2dae1a24f4f5bfa47cfc35f74f5512a126836364d7736","one":"c0a2c08fa8b70ecbf1932254945d5f689b0da7a287019d384152f383f6229acd4d82eef26205bc12e062dae4569814bd1c996ee4fe5886bd6bdd93c4f0ac113a"},{"one":"d3cd2f34f67830ccdc295b7537a6d27c02b44503808ca666124f52ecc3d6c35b7d3f14343997006aef2cfbefc8d27809d389477e99c236b9f8a897a4bc406a43","other":"624248a794fd62248024360f128b2e503c752340694a316bed420e5ed2cebeb5bf970df95a2806732237a26de3778222b0454e2e7d2875129b193e7890fd5b95","up":true},{"one":"e5cb29b25debcfaaacc0b04e708c8c1cb9d2dee29e82596a1c72a934032cf738800b9525cc277d0c5f5dacf2f278329b54da161b4bafa285243fa0e9fd7b2f3a","up":true,"other":"43086ff7ffd3c7bdec77bd288f41f1ee0ce21bd3f60a5df8931e2af6e7af5ef0fad432d29625491935d11567944351fc7867c807ebd12dd2c21c9e620ae0f85c"},{"one":"7465fe601a9ad8e640069e6e07d56afabd3d4f008f3084f944d869b47fda3f511f191062802a53da511f60891dd0bcc5fac60254ef9db7aa3b41f5791b0b6975","other":"a8fac88fba179fb9b259d94caac9cbe45d873a0131bef8844ac4383b177daf6f301f8793623fec5876885db1a91e5b3e98e2aafdaa47e03b1f6d9740f48af7ac","up":true},{"one":"60995852a2385ce8d7d24dc94b85a2f0dab6e5c32e910dfe367ea9c6ccb7b0b2eb611fdf120f8c697097e2f137cefff42e8d9db16b664a857a38c5ace837ffa4","other":"c2568576c2c9ef47aca0baca52709a4fa44b2ed478a062f7b161fac2bdba68568df371ac7754255fd07d79bb9918249a914946a6c318d579730bee9bc609922a","up":true},{"one":"9bdacc256acef0433805477d38f32be849a8846d88cb883b19d290454639b42c6ab6c5c52d4f83453e8a156af7d85f606458aa9c0977c67282f56f34ff0acbfb","up":true,"other":"b1dd1b08975319030626aab821032a0c687a103ee8942e8a2e2cf029dd72832a49630e78d2d8b184579f22178aca0e875f9fad701fb81afd2ac110ab2b417376"},{"up":true,"other":"624248a794fd62248024360f128b2e503c752340694a316bed420e5ed2cebeb5bf970df95a2806732237a26de3778222b0454e2e7d2875129b193e7890fd5b95","one":"f52281c227aa82a3bd5fabfdcf8bdf1d9ea6739ab9b9075340143d59b4f2f8a79a981609c9f42823a0253c19a7281eed0e912e4054363ab7fe50117563ef14e0"},{"other":"fc9b1b2bbd5e682eb350d23f3ee33b245495daedae9370de7b1f55f91cd45db831d196c17615e11decf6b67696a268ac788130e3de38c7f6aeae811f3ec8c8ee","up":true,"one":"1edeb91789b9aa996fea7a70964e0be33ee50acbe6d8f7d9d9fcf6dcf755dab6402637a610116f0eb716b19259429bdcced8bebc28ffa334387a430efc21b9b0"},{"one":"222d7a2f94dc82a09fda70b8195fc3a60433a90f53998872318c57625c528c90572d78b444ac4901dcfece1a03ef8b6cbe7845366a845a942f341f6db58a9b3b","up":true,"other":"740919ebae9b4fe646ca716ebb8923bf2a1b1963767d86f55ea95911d88d163cc2e07b1420669e64b62cb267b625413444b783b8e4a7bd6a0f481f4d84e984b1"},{"up":true,"other":"9ea856ea440c776b9ffaad1237ec11d570a1f912a908b8363ff97cf7947d2523e3c73663240d8fac988698cdd81e877ddd4a609485fe9f26494136fae14212df","one":"865dbf61d8511603fe0d9ebfb10792b9f6b798187c0909039bd9b2492c41e428876f386beeac86d0dea871f4fc24ba435f0fbd9a11e74c044024934592af14ee"},{"up":true,"other":"510536aba28aa635d8a1098a6dbd2070748ce1eb0e14b54b93a21196543a60df546ff6a2b3b5b9f32a5c2a37f5aba77d0b74f28b2dabeeebf3fe5afc20a3209c","one":"51df4f4d4f020f22f55a5fd00c7f9c68c232c167ae4d4e80d7695f8f39c5aa0a7b565c1c55bdd6a21e06fa056549d08fd2e9d76fd79e21295557aa30d1ae022c"},{"other":"33e9d4674b5b9b23e838583f01b429abca1330393dfc100b19ede6090a53df213011fae53169a66aa05d18e4cb497a17aa81eaedf1fe2e4348f9825c309438b5","up":true,"one":"f98c0f4444a1ec80773454ddb691c226b81d8e2f79ed40c45a422d3359565edf7bd635d3eb7bd6c9e0870746849fb86f0b1b34cd56ec8d3ad969812e080f4983"},{"one":"9c8f156797deff649d74d56fc42b4bb1a87312089114d4350424c375837d9c8068dd09af01c1c973d12ec5d7e8da600cd685cae70d3116b9dbda823092e03fff","other":"89d46e664ac471c7150fbfe43a49c98750fc64d5ca22fdc2a040c7ab78c25c48c1e9c2f0e5130d6b8eb7f0760fe962759d83f68cc08ffaac3520499b0ce694de","up":true},{"other":"92dbb67da2b99a8fe46b1e510addc2b83e357ac0b5287b7ef5c1b1bc6e252b8dfd605a6896ede65848e429216d1f67d530d9e7b83ff14058aa2e5b6e405d6801","up":true,"one":"8f3e9102306a13adb91e01f7a847e7880054f1a7df8976d05facb3a8fb37d47cce04f25e18a19713e5c3da7541e96e829fc67c8b924b717d2d9586c9c12d4fcf"},{"one":"6ad4ea3730ddec500e56248d1025aea79ec10f0d6a9720ee48026df10e219b41965d7a611fd99ee765f6afbc8c977db7e67c3a340881904acb983d1e2fb016cc","other":"002cb6ffa63ad71ee6ebc1df4c41f7a97c51f274b1d3b22420c87b73136be5169b9670508061d8261e20055fefce3b855388994672aa9a0f1475c43839aae4fa","up":true},{"other":"0c82c4b414375479375703ed9c19fb08c8143229ed4f1dcf448c6cf313810c098905123bec17969276936ae0cc39ed251b2811dbffb551d61159862b0eac0a23","up":true,"one":"bb0749de05a97daa67de889c15831ce39a080d641b3b08e3c248b0b16f4c07943fea8dd054d4a7e3e4af91ecff07053ce90096485a360b6f1d93050d179f30c3"},{"one":"29619924833116cb1160bf7a8066a528b7182794368bfae62b5bacbae680d9161a479f217e30c3b4f19a250b1b59e08f86c94726117dc3bc94ff9ceac6bee6e4","other":"a8fac88fba179fb9b259d94caac9cbe45d873a0131bef8844ac4383b177daf6f301f8793623fec5876885db1a91e5b3e98e2aafdaa47e03b1f6d9740f48af7ac","up":true},{"one":"9ea856ea440c776b9ffaad1237ec11d570a1f912a908b8363ff97cf7947d2523e3c73663240d8fac988698cdd81e877ddd4a609485fe9f26494136fae14212df","other":"b87e7f36ed6bf142d48545024d2fd6e120c44511701e7c0b7d7fc786f4f29d3357024b15f70b78215d8a4c2b7572d608c11b31612743e23db4fa673f0cd6519b","up":true},{"one":"11e9729700f5046b47d5e4521630cb57408f59a3337ca7db7984477a16c1f3b90c1d8d1f8d6a3f2a72e35f373fa73ec47a5636b36e40b2fb83756622a08896b8","other":"5a6318af8b4615cf30610a05ade7704182fefd0a3fb3d76c47cb392e114d8d30004f0ec214326b11532fd1e928e66f632bbcde126a94c87774063853a9518dc5","up":true},{"one":"bac3fd2ea491d8e4ce1e5d469ec73f3d537d61279ae66e7a394b20a188244a886d3059ef0d304c0801878f9640374f7c8aaf56558c41f12296d3fc7f911ed66c","up":true,"other":"313a131ecb7d68e127d0fec8bb4a2e586886203c3d07857a93e7a39bb831703184d9ae28ba9ef3d986c2dae1a24f4f5bfa47cfc35f74f5512a126836364d7736"},{"one":"8e5e8366251e33277e7db6f6c04629b2ce3eee217e973acb97c83773671b0160c40732794584db741a29a763672b90f3bdf34151fd4a6986b9d0956dc61d9723","up":true,"other":"b152eb30c9f46ec39166016f03d289f98cc285ac62d204da32e5a003da14e4f02c64df8ae1d0c8a2a902adc5f7dd7604081a0b140c9b64052082f0861945f5a4"},{"up":true,"other":"c03ef1de42d522b44eef53be11f2c57b8b74fed9e87e6c2928c1feb48ddfecc67e1a3a8c8be1c47b3735a216d7054e2a4dda49fbd9a1ac702146aae5bdeced7c","one":"6a37e63feed9e68c52cb8b385d5e8d8dbd2b211c57ded0d3b01fe8b306af5c0e5a7405d0d9a942648f0131926240d53450bc43f922a053528e5830d918313c3d"},{"one":"81901d9f043b4b1649ade3b5d22ae5f8bb42dd6db1eb37b836b99dd1c0388509ed4b54cc5638c9d4a6c5ae6c6913bbfffb303d7d94bf4ed50e871cf95459e2c3","up":true,"other":"58f9139905ae1d005950f110b7ead3355672ecc478e8c66393566c64b935003f6fec3031dc9eb21cda660acb1955cf7bb33a20fdd74d493f29868ace328fcd75"},{"up":true,"other":"69f999937943be00e5fca5c7cc942ce13b6752a72813368da2fbfcf74ad807bc6edd85537e087b6f73c0469c7b76a5d8f7d883bd315f3b35af32b8da293ed243","one":"4e88cc60efee147fb72a735775944c7b2ba0790e2b2b935b4b3c2da9a3158a2a7aae411e9204cdbe6b2304d90a3a8278f8bb1a800a409e8500d100d84ba1947f"},{"other":"d43bd6d3ae39a04e4e144a8a6f80b2d54472b5b9b6491dccf44b1716a63d24c56e3a871b3b8fe983d992988dc07ace06736ead3b1287914b629fcfe17e81f36f","up":true,"one":"2cb076669efbaf2ff0b181a1b454061a31ef23937a40405022b126f0eb4bfba60c9e3397009d8c0ff0cabb603692532d0072c18c6838f43397c98483306f62db"},{"one":"b87e7f36ed6bf142d48545024d2fd6e120c44511701e7c0b7d7fc786f4f29d3357024b15f70b78215d8a4c2b7572d608c11b31612743e23db4fa673f0cd6519b","up":true,"other":"b4f300abda4cf6e383f997510eb681e9fa62e23577e3c19bd7447fa1f5702a4e034cea5944248e7c6e6e92b5ae69195c3e8a2c5ca7827b4f4a00cc8546e6695a"},{"one":"81901d9f043b4b1649ade3b5d22ae5f8bb42dd6db1eb37b836b99dd1c0388509ed4b54cc5638c9d4a6c5ae6c6913bbfffb303d7d94bf4ed50e871cf95459e2c3","other":"1489ad735e1256900e4733707f8b78f1d853742a8f9b2d0c1c89651c60e7ee9d266afba5b4c1ed3f9cee05a1d2b2bba35dadb5b08973a93fd70dfb9e367339bd","up":true},{"one":"bac3fd2ea491d8e4ce1e5d469ec73f3d537d61279ae66e7a394b20a188244a886d3059ef0d304c0801878f9640374f7c8aaf56558c41f12296d3fc7f911ed66c","other":"4b332b389f1142c0da42aaeb2e2692081d0002de0eb6741b3269e898a8101571d4556b755f2e8841e7a607bb41e398d2b0577fbe71098e7097f0fe6c720e1526","up":true},{"one":"2cb076669efbaf2ff0b181a1b454061a31ef23937a40405022b126f0eb4bfba60c9e3397009d8c0ff0cabb603692532d0072c18c6838f43397c98483306f62db","up":true,"other":"43086ff7ffd3c7bdec77bd288f41f1ee0ce21bd3f60a5df8931e2af6e7af5ef0fad432d29625491935d11567944351fc7867c807ebd12dd2c21c9e620ae0f85c"},{"one":"6a37e63feed9e68c52cb8b385d5e8d8dbd2b211c57ded0d3b01fe8b306af5c0e5a7405d0d9a942648f0131926240d53450bc43f922a053528e5830d918313c3d","other":"60995852a2385ce8d7d24dc94b85a2f0dab6e5c32e910dfe367ea9c6ccb7b0b2eb611fdf120f8c697097e2f137cefff42e8d9db16b664a857a38c5ace837ffa4","up":true},{"other":"682288e4dae2374c4784acd0b285508920ce39a6b72cc0e30a3dbb7972e0394a2bddd5ee5f22a1dbf80f284dde4d9f8ede7847318d5353566b35a83e212477e7","up":true,"one":"f056acbdf491d1bb091937335c10096ea44b7034e994d134bc16d55212ff049bb097424de96c615ea699359a7ef77b3b54def2b3a5f43d735ffda65f73d61f7f"},{"one":"2b0a1f3a6466c6be1d7e84120db384fa37f7c73a01e9a105ae90e7d2203212ec974f016d3012afd26bc0f9a8411d0716cc59b6ecc9f665db12e306af8b34cb63","other":"24047e1a816cbf9b7a90e6c78dc896a3b624047ef5cfd3aa495132d57b1074aa129ea6eff171f5cca91d0f4793a07c9672b0a55232f2415c6220e443ebd0791d","up":true},{"other":"0c9a05514b96e7c3a0fbca21552e158faa70047246b230addca172a5023fd7439acd1c3a0b4f9191579b308dab38c961734ffdb36fb8e16383e912d070fc0218","up":true,"one":"46717bc5fb7fcbcdc961e7ef091020f9f222858cf3d4afcc0b0bb1b782b7055d9eb833e0a04cb32d80406133ac77162521c43edf9f9690872222760e31462ccc"},{"one":"2751df9f64a8f2ff8ea45efc9bd02b281d963ced285260bcda7f9dfaed998fe4386fe65a7265876da6b4fee77ea5c12454869a70ad627da7ca888076fc629665","up":true,"other":"11e9729700f5046b47d5e4521630cb57408f59a3337ca7db7984477a16c1f3b90c1d8d1f8d6a3f2a72e35f373fa73ec47a5636b36e40b2fb83756622a08896b8"},{"other":"2cb076669efbaf2ff0b181a1b454061a31ef23937a40405022b126f0eb4bfba60c9e3397009d8c0ff0cabb603692532d0072c18c6838f43397c98483306f62db","up":true,"one":"b58b3e200f6072ddb38130944a01d2829c755b8bd1a08abd010d1bbf86dabd851b2c1ab4cb961451bd7e8499f6c7378830bcd27cde825846654853c172597bf3"},{"other":"5319bc9864d87eb33f26ff9732824d21a0a5ab70b254bc70a47554ffc763ae1559000d07e3eac9f883bd9e7f249d80edf14ab39c89c375bfcc5ec9e840ec9673","up":true,"one":"50c79baa3e6781482ccb5e960c699dd9c13f479467c6315c5292a396337cf3619e7faba1971a1f470051cb9042f80ea6750defe3936b72aac4d9bac6f8368c67"},{"one":"81901d9f043b4b1649ade3b5d22ae5f8bb42dd6db1eb37b836b99dd1c0388509ed4b54cc5638c9d4a6c5ae6c6913bbfffb303d7d94bf4ed50e871cf95459e2c3","up":true,"other":"15ceb62ee0f53379aa202950634ed881ba3b7bd4b46c80723ee48190079311e24ffaacb167a126a40bd6732c384f3c26163aa043edca03cb52a97b6da189aec7"},{"other":"1cdef98d7b4de45c902c725384bd14c66084fe4159b26a0f9a24f432e1f561d035ca41e1c60fe64f3213b4f91a1afb953193dca1a7d535be0602b5d046bcbab8","up":true,"one":"d7af0a0217ff98804aa05f8f926a8b6262363b5391d24cda8048cca5ca5982b407b7b098302d0db6d8dd9ac0883b2025b3de651617ed1a173181148295c6d336"},{"one":"3639f964feba681db9702cac3f02058f2e490fd7bffb217dc3480dc458decafd5955541fea89f0f6f14ee50a745eaf98b21363d6b4fb88c31bd32bf7845d524b","other":"643da2591098f9698f27cccf7c17832e0717ee6a1276398a1a29edc947125585dcfab9417c2721a8a55d4dfc75b826be7581b6e30b020f6341ac549877c9f122","up":true},{"one":"52cf04f88d8b00214f11f329ebacca69291958372aa8ccfbe3cfdbc03d51d90389f3c307b82c108f0c074d78aeac0b48e8b8c8f3bf3b20b21d9747f284075de2","other":"24047e1a816cbf9b7a90e6c78dc896a3b624047ef5cfd3aa495132d57b1074aa129ea6eff171f5cca91d0f4793a07c9672b0a55232f2415c6220e443ebd0791d","up":true},{"one":"5717a49591a0ecdff3d4449874d5ff9ba016afad5da19712ca0c8ebca8cefd84e6d8c778245f67f68c8dd730ad294fd017b8de279fde4fc919768ce85dba132d","up":true,"other":"243164c4dd583f80c50813f43e5c27c894463400cd3afd776b36e79e7123d9261f01f06f92914aab83096b9a43fb655e79687590599284640a3a7d2c25454597"},{"one":"535287ca3d41fc1cdf20a964749a849c51d0aba285f41f447cc2b1dd6f5845b6b98e0241dbda0718b234ea850081bfbf9df01d1aa636d7dcbd99ef3c0a773aff","other":"51df4f4d4f020f22f55a5fd00c7f9c68c232c167ae4d4e80d7695f8f39c5aa0a7b565c1c55bdd6a21e06fa056549d08fd2e9d76fd79e21295557aa30d1ae022c","up":true},{"up":true,"other":"7a8cb96685c1b8fbaeb18c8dc1f9f2631b23bc035e704e2f5df915b8bcabd6e2025ddc30324c69833f86e577b250c0721fee9d294f3e22016ae4c59c5f88845b","one":"8d3ad57509b36c4ca5c4663f3d1977a3125e069078842634e6cfeb22c044281e3d02f06eafc6d2a60089f03d70f5134a6635c35563c9f911fd845a6ef9bc8952"},{"one":"96cd4caa32c0b3a3493e24e13fad1ef75c621005d74154c3fc8a73cca4c0120452b6432334d94849c63f75d56a2943a453c86d2a14ad1fb61ae6833e58451187","other":"8f3e9102306a13adb91e01f7a847e7880054f1a7df8976d05facb3a8fb37d47cce04f25e18a19713e5c3da7541e96e829fc67c8b924b717d2d9586c9c12d4fcf","up":true},{"one":"6a37e63feed9e68c52cb8b385d5e8d8dbd2b211c57ded0d3b01fe8b306af5c0e5a7405d0d9a942648f0131926240d53450bc43f922a053528e5830d918313c3d","other":"c6ad9b9de5cdbe28540f4eb7c66fb37f6d4295e6e60c6de54e2a45c1970b8e0047558e986bbd10e9e86c8bb0407846fac4823e4570e8a1486fc4bf55cb4a0986","up":true},{"one":"bac3fd2ea491d8e4ce1e5d469ec73f3d537d61279ae66e7a394b20a188244a886d3059ef0d304c0801878f9640374f7c8aaf56558c41f12296d3fc7f911ed66c","other":"b7cc9044d021b19cd8a6d290d21f1c91fd5deec472583d0aeed0a6aacc8efef9968079254132becc5443df14dd3f4feaee56d14b885c078649727b9659139fa6","up":true},{"up":true,"other":"8ec699020ab5e7719fe23b80268b5d1d37052bb71f5d81200ae805cf27825823733206165f0a7507c2595853361dd122e9ec1b2deb543591e22b71ec0b873b5b","one":"8e5e8366251e33277e7db6f6c04629b2ce3eee217e973acb97c83773671b0160c40732794584db741a29a763672b90f3bdf34151fd4a6986b9d0956dc61d9723"},{"other":"da22fb43c6d230d92f9c09454e282dc45dffc759740566039f1bdfb58171c6801f721841de83217277b3fb70983e7d34da53bbf25d1d45413a78d9afff151826","up":true,"one":"a25958cf192a4f62301feda5d442535f78b983dd9e4599354f4898c8c1e6ad97ca7112549e1d1a1eacb4682cd1bf8b762368b5905ab33dbdacb585b128514ca1"},{"other":"d3cd2f34f67830ccdc295b7537a6d27c02b44503808ca666124f52ecc3d6c35b7d3f14343997006aef2cfbefc8d27809d389477e99c236b9f8a897a4bc406a43","up":true,"one":"6b104eff1dcf58d11a7f707bbd41a910b2735b262c29e0f4e4127fda1b67def4e89b6ebc1b3cc1e06c3968d0898e1085badc7da24d3cd6624cb100e85863cc97"},{"one":"3b71a324bd7b1a8fb19d8206eea1ca8190cb1faf5fcd1bfc52cef6b52296fe1db3e54d70180133fad1fa1188499d0dd73d2d075fdc6b3ffd9042d690e7d88e02","other":"9ea856ea440c776b9ffaad1237ec11d570a1f912a908b8363ff97cf7947d2523e3c73663240d8fac988698cdd81e877ddd4a609485fe9f26494136fae14212df","up":true},{"one":"81901d9f043b4b1649ade3b5d22ae5f8bb42dd6db1eb37b836b99dd1c0388509ed4b54cc5638c9d4a6c5ae6c6913bbfffb303d7d94bf4ed50e871cf95459e2c3","up":true,"other":"8e65496318637446a51f0dc87d0a5cf82655866cd1579db1e381af52e12545172b9c88119999ccac3b8b8644efc9675ff183ebe7584c16eb40792cc21f7e9b76"},{"one":"92dbb67da2b99a8fe46b1e510addc2b83e357ac0b5287b7ef5c1b1bc6e252b8dfd605a6896ede65848e429216d1f67d530d9e7b83ff14058aa2e5b6e405d6801","other":"29619924833116cb1160bf7a8066a528b7182794368bfae62b5bacbae680d9161a479f217e30c3b4f19a250b1b59e08f86c94726117dc3bc94ff9ceac6bee6e4","up":true},{"one":"b58b3e200f6072ddb38130944a01d2829c755b8bd1a08abd010d1bbf86dabd851b2c1ab4cb961451bd7e8499f6c7378830bcd27cde825846654853c172597bf3","up":true,"other":"c674c405068bb908312917a319e24ddf90e814ee8ef54bbf740f176b2a7eda6950e3e1ed69484ebcc27b13d82c7f0b20daba71a17700018e769ca612ca8d2208"},{"other":"e33a1476fcb8d2a1b9ee15871a960ce7a3337c93f5956a2825b1f8b2885dbdc0ed652b1eba549523866632b5b6898310bc638d946a9fcce27d65117eb44c25f3","up":true,"one":"3b71a324bd7b1a8fb19d8206eea1ca8190cb1faf5fcd1bfc52cef6b52296fe1db3e54d70180133fad1fa1188499d0dd73d2d075fdc6b3ffd9042d690e7d88e02"},{"one":"e1f23e1caba66f5ff821edbc4a3d527539937f73d86dd0df43aa1266a99f51f2480a77961eff177fbbf852fc52cb9317179f80b1580194daaedadc3b00510751","other":"24047e1a816cbf9b7a90e6c78dc896a3b624047ef5cfd3aa495132d57b1074aa129ea6eff171f5cca91d0f4793a07c9672b0a55232f2415c6220e443ebd0791d","up":true},{"one":"c6ad9b9de5cdbe28540f4eb7c66fb37f6d4295e6e60c6de54e2a45c1970b8e0047558e986bbd10e9e86c8bb0407846fac4823e4570e8a1486fc4bf55cb4a0986","up":true,"other":"1edeb91789b9aa996fea7a70964e0be33ee50acbe6d8f7d9d9fcf6dcf755dab6402637a610116f0eb716b19259429bdcced8bebc28ffa334387a430efc21b9b0"},{"one":"fd0123c7b96004067e98e463e273de5bc5402399ae70a95985b5f682e30d4f35d070deaf8c71d201e98c4324d832b95aab7535ad8a2658f66e3e0bb1202204e1","other":"002cb6ffa63ad71ee6ebc1df4c41f7a97c51f274b1d3b22420c87b73136be5169b9670508061d8261e20055fefce3b855388994672aa9a0f1475c43839aae4fa","up":true},{"other":"96cd4caa32c0b3a3493e24e13fad1ef75c621005d74154c3fc8a73cca4c0120452b6432334d94849c63f75d56a2943a453c86d2a14ad1fb61ae6833e58451187","up":true,"one":"92dbb67da2b99a8fe46b1e510addc2b83e357ac0b5287b7ef5c1b1bc6e252b8dfd605a6896ede65848e429216d1f67d530d9e7b83ff14058aa2e5b6e405d6801"},{"other":"6b7c94db790a2c1b903208904c4c75b66b17e7a00404727dbc7aeff404ac1118dc78ce4ca443f6b5245236f9e358c09b6da027ae1144e1a6682edca301176330","up":true,"one":"b4557089e4247379e587a087f53b36dd1f86f85d9dcfab5dc562079978cd959adaef5b30d11258d9cb552e7c5abddf5377a71d449febe8f2acb0aec3ebd8ba73"},{"up":true,"other":"51df4f4d4f020f22f55a5fd00c7f9c68c232c167ae4d4e80d7695f8f39c5aa0a7b565c1c55bdd6a21e06fa056549d08fd2e9d76fd79e21295557aa30d1ae022c","one":"c0bec7375c66bec98524ade2245c1d7480516fc5d87a3249e64ec86418e80e202f1e3da76832e97bbc3dcaed8c96ca344e4829347b4428f4b1cb61999e404c05"},{"one":"431644cf162bc267237c4e798288888dd835c1b0546b0cc679782e33568988d75b4294f4aa08359a6b152ed9a0fbd13133681156bcf09a871c4f362615ea6dae","other":"5319bc9864d87eb33f26ff9732824d21a0a5ab70b254bc70a47554ffc763ae1559000d07e3eac9f883bd9e7f249d80edf14ab39c89c375bfcc5ec9e840ec9673","up":true},{"up":true,"other":"488854534ec5a3479d8ee13d9b7daf07479f6b5505f319eced44dad8c316f6ff241ce2101e95608ba635067f5e5741481b78f419c4bbd465bf7e837dc4e54d64","one":"c29e80096fbe7bc9fcbfdbe3cf6c06449192a3ed280e46a1fa5d424428d893c3456c985c1352c119236cf783834365439751cc87e7ed196614705dd3db6674cf"},{"up":true,"other":"8fb6838337f832445531764ddafc3c747b2607f2f33e244685d6de621c2b53264270f5504187e43b7fa5cda53e66dd00b16c06879c82fb38a3d9e8aec4060210","one":"3b71a324bd7b1a8fb19d8206eea1ca8190cb1faf5fcd1bfc52cef6b52296fe1db3e54d70180133fad1fa1188499d0dd73d2d075fdc6b3ffd9042d690e7d88e02"},{"other":"b4f300abda4cf6e383f997510eb681e9fa62e23577e3c19bd7447fa1f5702a4e034cea5944248e7c6e6e92b5ae69195c3e8a2c5ca7827b4f4a00cc8546e6695a","up":true,"one":"11e9729700f5046b47d5e4521630cb57408f59a3337ca7db7984477a16c1f3b90c1d8d1f8d6a3f2a72e35f373fa73ec47a5636b36e40b2fb83756622a08896b8"},{"one":"ec19efa1d488e74da6bf239825b24678f549c377326c5d33d100b708a9a28a3fe129d542d7ba71e0ade46c15c6e9b38f09422560444388e609a8a66ceb8e0ae8","other":"29acdd4c1233441bd40f98e245ecc9de94de6f9d0ab7c1a9923d833a2c8e6c1bd26d792686fec762b31fe28bbdd7aa04c9a594d997d08c133bb24cb2d877595a","up":true},{"other":"06aab75fed9a03f5525e3f1d8f8997fefaefd5b16e8f485d571beda00b1741efbb61a8a74fa12c2f6de66227c3fabb4d411659cd9c7b1ef32e171e6bf517cc39","up":true,"one":"207764262a208c17db61fda4208d4664bf74010e0ad051a863e131e748c9304e11ccf007c925488ea86b974ee61cdac3dca4d4b3f4043524e03c194ab3c8eb5a"},{"up":true,"other":"ee3471e1d835c4294f7ba642103039ccc548fe4edc177c79b63433ebbb0dc9d06600844f1fed76c7096ee9538e49e4e86fb8cffe9095dbdcde27695ff28ad395","one":"97b1eaf8274ece76d75e7f60126f1b351ed5fe55088b9fcbb825a3a8d8f84f61bc72469916b280497dabf01345057525cae89da73c9a1a8a8cd19367d44dede1"},{"one":"3a2cacc430f13f31c52b7205455420cf0fb9ed9e28b0898b69ef97951bf295b29118e573a42dd97abe38fee5ab4c03dad9ff6dc448126cefc1da12b6c8e8d915","other":"bc0df855bdadcde3e447415444f655eb430925a8fa81cdcac75909e7d79750f01827938570e75e388cc7058ba8ebca47afadf8b07172bc078488fb618ba71024","up":true},{"up":true,"other":"02fdbcb00f20a3f6e894900d798fcb0aca9e21f5b107924c0999eb396220f16dee99fc80ccba796e66e69dcb9ce278b7e0e4539c7a7cd0fbc1037bf8e56c1e67","one":"17ae0b24297a3e6e027884e5e4529b6646ae340f5736eebc6187a9b59832a445f3644172d92438351e3803e56a67472b29f3e1d48844ae2e11e5e6670eed1436"},{"one":"dbb6621460b054f584f1c6157b4020f3c58d84c3a12b57436e10525ae60ab27036bf3edd68b92f2b13674877d01c2871dc67a9031c3d0470985f4b071696346e","other":"869ca41ea1f82bec5f43807a3aaaabc39b21c62d3c9c8bdc0709683e22dd37cb2f3c313766809076d2c02d0d6171f4f32a1b5080abcb8072d88981042ae6237d","up":true},{"one":"3f322f9b1f1f0692663bc3be11cf11386f4a14696aab610916cfcadf0234cce0c86b51c85ce2108e9bc21d50ad71cc10a6eeaec3fc7732908f3a8b193465a0ac","up":true,"other":"dd3dccc1758765569905b3b137ef4c7dd31c2dc0dea827bcc4c4e976be94ffbb0f2ef6fe725cf9042063a96d663efea546837f35ca1fc67a854fbc9e27abb754"},{"other":"e323da6ae861cb092543992b8985639f9b3bcaf1c3c68757f4603a67800be62950fe7d8f8ef80eb83a18107b677c7f5047ea89a5790e0ea2a7969f4856d28488","up":true,"one":"7c6e6a49429a4e24aa4aa5c7ba19684f77cd67d3744688baff6e7f1d74b7e9d2df85f3e57e0df0a9b960b5bf982a610c5639c3e7a6935ba13fbc77243b2dad19"},{"one":"e9cd25d1ef3fef22160bce7f7badd7646ac58ee40da6a438f61a067c51bc51d6087ed950ec9e909bc438ebe62e316cbd9489f3c9bfa2898615632414e04f1dcd","other":"d7af0a0217ff98804aa05f8f926a8b6262363b5391d24cda8048cca5ca5982b407b7b098302d0db6d8dd9ac0883b2025b3de651617ed1a173181148295c6d336","up":true},{"up":true,"other":"d7af0a0217ff98804aa05f8f926a8b6262363b5391d24cda8048cca5ca5982b407b7b098302d0db6d8dd9ac0883b2025b3de651617ed1a173181148295c6d336","one":"aa53ca208cc0c9e544fd9d52cab44b5e2887256bb006037b855b5c94d7f79c9388fdbb23c0bf1d2eee12d67125e082fa7ecb34c1129ca8eaecfd85772b009435"},{"other":"2880e0defd1bf2665bdd20dfb46bc0a9ad707f495211fc78e611ab479d78398db7daff7d3f4b6bf81fd13bf766ecc8271e0ea99a2d74abd2f9ddf98835ffdcf1","up":true,"one":"510536aba28aa635d8a1098a6dbd2070748ce1eb0e14b54b93a21196543a60df546ff6a2b3b5b9f32a5c2a37f5aba77d0b74f28b2dabeeebf3fe5afc20a3209c"},{"up":true,"other":"dd3dccc1758765569905b3b137ef4c7dd31c2dc0dea827bcc4c4e976be94ffbb0f2ef6fe725cf9042063a96d663efea546837f35ca1fc67a854fbc9e27abb754","one":"85c0b055439f114dee5eb0961013c117a48d62b0f17c61a7fd92a84092ef09bb3bbce686aa96e14528d5663565c57d657fa9813b1f38e268caeb1cb0842ef232"},{"up":true,"other":"588df3185f63a5443d8c6b972f67805f0557184d916005f537a4b27cd02bd6a12e432a2b34b234a34f22e923c6f116da85be20bad77a2bf69913684e9d0732ba","one":"877d17ec7e95998ead831606d3363fbff1c8d1fa377b8e621e6a876d2c7776b9af356211a7e4df66adeaf38cf9b49c04871e8804edde4c18435ff45e110ecb04"},{"one":"7a8cb96685c1b8fbaeb18c8dc1f9f2631b23bc035e704e2f5df915b8bcabd6e2025ddc30324c69833f86e577b250c0721fee9d294f3e22016ae4c59c5f88845b","up":false,"other":"ecb93d8eba17afe92979e8154252a08dd58de6ff3188b6829e3e25967846686f54199ab2b081e77b0048dcab204f05aa2c5cbd0efae4bc43a612d471d4e1197b"},{"up":true,"other":"e9cd25d1ef3fef22160bce7f7badd7646ac58ee40da6a438f61a067c51bc51d6087ed950ec9e909bc438ebe62e316cbd9489f3c9bfa2898615632414e04f1dcd","one":"936fad959da2d8b0cfb2bcd78c5da65bcce5e9463be7fc7367f45cdfa20678f4c466fb1e3f600783a270855fd4b9cd6265054f79ecb116141e7c67a492041bed"},{"up":true,"other":"33cac8f621b9122e118036154778d27dc419b6b58ea2e89b833f3932f411dbc3511d92b55ae4cf80632142bc8e67994899aaa30c499d0289fae85b12564cf01f","one":"d6747e1f8594f7449fc6d7c0e63ee843480567d498db096ff04229420861c83bca5215fc19d8fede0c54484f111f1f2581e189e638c21c5d9e1fd3174bbb3e98"},{"up":true,"other":"a5f7163586fce1750fd9a6e5c418af1c18ca6983069dcf1738fc9106ebf542a86e4ccfc50b45a0d97ca8681af8207128877f930f945e59ee262aa7f4014a01f3","one":"b58b3e200f6072ddb38130944a01d2829c755b8bd1a08abd010d1bbf86dabd851b2c1ab4cb961451bd7e8499f6c7378830bcd27cde825846654853c172597bf3"},{"up":true,"other":"bac3fd2ea491d8e4ce1e5d469ec73f3d537d61279ae66e7a394b20a188244a886d3059ef0d304c0801878f9640374f7c8aaf56558c41f12296d3fc7f911ed66c","one":"be93fafaf43f6bb3efd2667d1468a8636cb752b245328eaa01468c0606d790322a7cd8e47857068e60118e28b8dd8aa1d2d4977c5b3d28d4b47f4c0658f05e90"},{"one":"be93fafaf43f6bb3efd2667d1468a8636cb752b245328eaa01468c0606d790322a7cd8e47857068e60118e28b8dd8aa1d2d4977c5b3d28d4b47f4c0658f05e90","other":"3e7aef8260c0d9717aa59b65ce7c554e53b81f19f5b9400321704a7ddf5041b0fe31b5634e90b93e6984060defee0e153997bbfe196166cc8d83165fd5eaf41f","up":false},{"up":true,"other":"c03ef1de42d522b44eef53be11f2c57b8b74fed9e87e6c2928c1feb48ddfecc67e1a3a8c8be1c47b3735a216d7054e2a4dda49fbd9a1ac702146aae5bdeced7c","one":"243164c4dd583f80c50813f43e5c27c894463400cd3afd776b36e79e7123d9261f01f06f92914aab83096b9a43fb655e79687590599284640a3a7d2c25454597"},{"up":true,"other":"6b7c94db790a2c1b903208904c4c75b66b17e7a00404727dbc7aeff404ac1118dc78ce4ca443f6b5245236f9e358c09b6da027ae1144e1a6682edca301176330","one":"77e40e42f570a217f707888c714deb31fd70c856ae4b9a44ec7cee02768185dc4d7ed210429607f06690b32edd9fb06b304aff330a3949cc2fd49db1bc392edb"},{"other":"ee3471e1d835c4294f7ba642103039ccc548fe4edc177c79b63433ebbb0dc9d06600844f1fed76c7096ee9538e49e4e86fb8cffe9095dbdcde27695ff28ad395","up":true,"one":"8c459100df488b992fdad207a096a434d67cb733619adfd09a311095568d4c9db293d9a892675551805559456d49a3fdb19c2cc698b14552bf0ace584d4d90dc"},{"one":"c2568576c2c9ef47aca0baca52709a4fa44b2ed478a062f7b161fac2bdba68568df371ac7754255fd07d79bb9918249a914946a6c318d579730bee9bc609922a","up":true,"other":"aa2028d356a88eca8e0fcaf218d62ace099c3f72dfd95bb28f30ac9a926034cf1d60a40511f7495652745de80d71c0f6830019e206c88e2b6ef0cf4f05d7fe9e"},{"other":"48e35d67e14ee2f329c0275bc965829b761885dbc3671f4673d84d76d18a5b6415e619e219b5d90761a5c6bd2f43c6a58708286a063daf46b502944f8ef9230b","up":true,"one":"c69b9b181b2756a1345b73a97afb3dca909c253188c3b905f0b414465b750d2ffccb4c8e8eb5e3809549af55db473f3b12682f9bd97c5c75d68f23d67d91b866"},{"other":"dbb6621460b054f584f1c6157b4020f3c58d84c3a12b57436e10525ae60ab27036bf3edd68b92f2b13674877d01c2871dc67a9031c3d0470985f4b071696346e","up":true,"one":"77e40e42f570a217f707888c714deb31fd70c856ae4b9a44ec7cee02768185dc4d7ed210429607f06690b32edd9fb06b304aff330a3949cc2fd49db1bc392edb"},{"up":true,"other":"bac3fd2ea491d8e4ce1e5d469ec73f3d537d61279ae66e7a394b20a188244a886d3059ef0d304c0801878f9640374f7c8aaf56558c41f12296d3fc7f911ed66c","one":"95ff4dea07303e1ba641a5c510e714ef232f4dbce9ad2e8b2f62644975eae41fc4bb9d1af3fae4d5ea4daeb18f8248e0b3131c7d843d35d33f3afbf7dfa4c2fe"},{"up":true,"other":"bac3fd2ea491d8e4ce1e5d469ec73f3d537d61279ae66e7a394b20a188244a886d3059ef0d304c0801878f9640374f7c8aaf56558c41f12296d3fc7f911ed66c","one":"1c080e90760dfcee08ade6e4ea3b275ff3c6882f3b44b7f3a73d70bcc816fc63ce0b6138f810d17d96ed387076f9bbb6dbb2ef6dc4d6ba6542c1f587b7602a12"},{"one":"ab1a3542d67ef9d1a63653990bf0782f53b0169fe5092adc92fa7aeb38f66c6b62d49e3455cc2ac4994bfcfb03111953acf4cc3099026672cc61f6e24cb3ae00","other":"e8a679f627d03347a4fcec0a0940f7ffa90ce3fefea290db3af4f3a32d27965bfb51832b6a6de2495c8a8cc026bcf993b84a0cced778e158bb81c034f5e4bd76","up":true},{"other":"e0f13606a7f35b9ad8a9c4e70336c4c554ac718720a451a349eb4e1a4b055079483cac040ec64e0ed3d8bdb336618a5ae6ef74e31642fae4d7ed9949858eb361","up":true,"one":"ba430731fc2082f4217ebd859c2865c28bf50a39674ca8615dd89f608ae434a09657e24644ac32807634aad7857547118c9228460195e50ec58b34789d4ad151"},{"up":true,"other":"dbb6621460b054f584f1c6157b4020f3c58d84c3a12b57436e10525ae60ab27036bf3edd68b92f2b13674877d01c2871dc67a9031c3d0470985f4b071696346e","one":"ba430731fc2082f4217ebd859c2865c28bf50a39674ca8615dd89f608ae434a09657e24644ac32807634aad7857547118c9228460195e50ec58b34789d4ad151"},{"up":true,"other":"17ae0b24297a3e6e027884e5e4529b6646ae340f5736eebc6187a9b59832a445f3644172d92438351e3803e56a67472b29f3e1d48844ae2e11e5e6670eed1436","one":"c206d8689068488179e86ce549de75989e0b17cbe09880d18fcf0fa212e629345f1b899203607a2b083569cb3f8398e501843166f5db23ac7fa7dacfe26dd3f4"},{"other":"8c459100df488b992fdad207a096a434d67cb733619adfd09a311095568d4c9db293d9a892675551805559456d49a3fdb19c2cc698b14552bf0ace584d4d90dc","up":true,"one":"4eab70233789c544bec97040a04099494bf269a819584a5d0b42295c918a52b02f224a8ed127aba3d92c02f567356bea4b95f77230ef548dfa7fe44b643d8704"},{"one":"b183f12f3602bfdab0480cb0b0ba7dc69b267b0dbc7e54c316741cb78b9e99aa69fd321ad7755d095e9be14e6bd90fe14ef8fe9bafc1a0dea10a144795021a08","up":true,"other":"936fad959da2d8b0cfb2bcd78c5da65bcce5e9463be7fc7367f45cdfa20678f4c466fb1e3f600783a270855fd4b9cd6265054f79ecb116141e7c67a492041bed"},{"up":true,"other":"ecd217e8bdb53c9ef085929b8c2d2b40425a4be617a087b8e7f88e8507b3c981e90fda2119744ca394fe65bd4eb1cdd3fa7258db936048e236d2f15ee91bc3b6","one":"ba430731fc2082f4217ebd859c2865c28bf50a39674ca8615dd89f608ae434a09657e24644ac32807634aad7857547118c9228460195e50ec58b34789d4ad151"},{"one":"c088bf88f1e152ca3fad17f098a71ca1021d46d8af12d0ee1c587a5e2a430d8e48beaf171fe01ee7680b671c00dd88c90f12a35c328a3f334661fdeee914a4bc","other":"8c459100df488b992fdad207a096a434d67cb733619adfd09a311095568d4c9db293d9a892675551805559456d49a3fdb19c2cc698b14552bf0ace584d4d90dc","up":true},{"one":"5319bc9864d87eb33f26ff9732824d21a0a5ab70b254bc70a47554ffc763ae1559000d07e3eac9f883bd9e7f249d80edf14ab39c89c375bfcc5ec9e840ec9673","up":true,"other":"4ff2981a47da46c753090e193a8bf43c3372a6b07a37cf0552de2ced455fbb8a76d969cd97b3e4601d8a808bd2a73f7729ed8a61df2f2a0c2cee1425d0bd9ab4"},{"one":"ab13f773f6f2ff73032aa5f79c8897b75dda29bcbb14aa511e9401c2417dc9c510253071e28c7833c8d62fd2aef16fcd0c14ce016fbf4fec1b9a2173c717603f","up":true,"other":"643da2591098f9698f27cccf7c17832e0717ee6a1276398a1a29edc947125585dcfab9417c2721a8a55d4dfc75b826be7581b6e30b020f6341ac549877c9f122"},{"one":"c2568576c2c9ef47aca0baca52709a4fa44b2ed478a062f7b161fac2bdba68568df371ac7754255fd07d79bb9918249a914946a6c318d579730bee9bc609922a","up":true,"other":"c03ef1de42d522b44eef53be11f2c57b8b74fed9e87e6c2928c1feb48ddfecc67e1a3a8c8be1c47b3735a216d7054e2a4dda49fbd9a1ac702146aae5bdeced7c"},{"up":true,"other":"f5d95e0c5a873ff5a95e1eb34f1ed258d77adf98ee0886d93c4a24b1feaf6955e6e4c4ea0eccb2b9723870bae61e693643d6ad96dd8da01672542611f7c49069","one":"5982e7dfd39c527851f6ea6430b70e654d95df5ec4401ca1d8dbd1034cf7a65d1126d60b36ebbd396c9ca32e6e8515f34f9dc0a8d2980afe4aa181c8bf68437e"},{"one":"002cb6ffa63ad71ee6ebc1df4c41f7a97c51f274b1d3b22420c87b73136be5169b9670508061d8261e20055fefce3b855388994672aa9a0f1475c43839aae4fa","up":true,"other":"20f6a8be1d2d8b5d6a43d851a2f5475385ef07fab80ac46525d0beccf3e25c01d726cfb3a1179e8343b1e88d21684fb24dd6e6497537d4e7e9edd59cb95d1b8d"},{"other":"97b1eaf8274ece76d75e7f60126f1b351ed5fe55088b9fcbb825a3a8d8f84f61bc72469916b280497dabf01345057525cae89da73c9a1a8a8cd19367d44dede1","up":true,"one":"c088bf88f1e152ca3fad17f098a71ca1021d46d8af12d0ee1c587a5e2a430d8e48beaf171fe01ee7680b671c00dd88c90f12a35c328a3f334661fdeee914a4bc"},{"other":"6ad4ea3730ddec500e56248d1025aea79ec10f0d6a9720ee48026df10e219b41965d7a611fd99ee765f6afbc8c977db7e67c3a340881904acb983d1e2fb016cc","up":true,"one":"5319bc9864d87eb33f26ff9732824d21a0a5ab70b254bc70a47554ffc763ae1559000d07e3eac9f883bd9e7f249d80edf14ab39c89c375bfcc5ec9e840ec9673"},{"one":"a5f7163586fce1750fd9a6e5c418af1c18ca6983069dcf1738fc9106ebf542a86e4ccfc50b45a0d97ca8681af8207128877f930f945e59ee262aa7f4014a01f3","up":true,"other":"85c0b055439f114dee5eb0961013c117a48d62b0f17c61a7fd92a84092ef09bb3bbce686aa96e14528d5663565c57d657fa9813b1f38e268caeb1cb0842ef232"},{"other":"4ff2981a47da46c753090e193a8bf43c3372a6b07a37cf0552de2ced455fbb8a76d969cd97b3e4601d8a808bd2a73f7729ed8a61df2f2a0c2cee1425d0bd9ab4","up":true,"one":"002cb6ffa63ad71ee6ebc1df4c41f7a97c51f274b1d3b22420c87b73136be5169b9670508061d8261e20055fefce3b855388994672aa9a0f1475c43839aae4fa"},{"one":"c2a9c77247871cfa4d3c2d1b47619df91ed5b331a44c8e21f7c9ce431a4db9dfb87713558cc8a37911393907b4cc60be9445bad18adcea1bc5f318256e71be14","other":"df9306a263f40e0e255996500523354de3cc78b68ae560f66d79f6ea28f30f773f1fd6ebc33928723dfde2ee3d4f982b203bee4c3803a5050df83477045bb279","up":true},{"other":"43086ff7ffd3c7bdec77bd288f41f1ee0ce21bd3f60a5df8931e2af6e7af5ef0fad432d29625491935d11567944351fc7867c807ebd12dd2c21c9e620ae0f85c","up":false,"one":"5d002c37b74a6656db86f102b0cec82bc35a819a480e5a2952db0140ebab65dffeb1a79f04d53ff61447b5fad7c58cb75ea1c91ea47fcb9e024f27b92c6c874d"},{"other":"df9306a263f40e0e255996500523354de3cc78b68ae560f66d79f6ea28f30f773f1fd6ebc33928723dfde2ee3d4f982b203bee4c3803a5050df83477045bb279","up":true,"one":"9d372d73848389cfa1676f0cdb030950980ed5b68d5b2ef8a058f1d2095b26ff0fafab5fd3c243296ee2620edc67752970ab47370270856287f8612d1b190a19"},{"one":"24047e1a816cbf9b7a90e6c78dc896a3b624047ef5cfd3aa495132d57b1074aa129ea6eff171f5cca91d0f4793a07c9672b0a55232f2415c6220e443ebd0791d","other":"85b6404a76b4762156c8ddd2f312763dfe19b315d914533844cf229301880c57ffeadc0eb5f4a8d542e1d9fc961dfb5a572d2101172b1a0fc238ced05ba49ec1","up":true},{"up":true,"other":"e993be8034861aebc9bbd11115f25d9c719d43fcdefc323599616cc26240cee38dfc27bb7f339149a54a3c9ad13b2d6ca4f0ae690e4355605eda6b789c4a431e","one":"89d46e664ac471c7150fbfe43a49c98750fc64d5ca22fdc2a040c7ab78c25c48c1e9c2f0e5130d6b8eb7f0760fe962759d83f68cc08ffaac3520499b0ce694de"},{"other":"b60def37233dbbc0d5f7fcddb304be1c0b6508e1e3d8a09a8290f7363e9bb84152dcaf70b8f6bb3a882fee77ff03ab796a5c1c3654f251c9f5c746ac5ad88556","up":false,"one":"24047e1a816cbf9b7a90e6c78dc896a3b624047ef5cfd3aa495132d57b1074aa129ea6eff171f5cca91d0f4793a07c9672b0a55232f2415c6220e443ebd0791d"},{"one":"5d002c37b74a6656db86f102b0cec82bc35a819a480e5a2952db0140ebab65dffeb1a79f04d53ff61447b5fad7c58cb75ea1c91ea47fcb9e024f27b92c6c874d","up":true,"other":"77811b007dd1fc1b11e447858df37062e97b6fc14e059399814f3b4736188e3fb28bf7c3958bb8ebc6ae16c36884ba7c98b810fb6f8b358323412123c803abd4"},{"one":"7465fe601a9ad8e640069e6e07d56afabd3d4f008f3084f944d869b47fda3f511f191062802a53da511f60891dd0bcc5fac60254ef9db7aa3b41f5791b0b6975","up":true,"other":"29619924833116cb1160bf7a8066a528b7182794368bfae62b5bacbae680d9161a479f217e30c3b4f19a250b1b59e08f86c94726117dc3bc94ff9ceac6bee6e4"},{"one":"a5f7163586fce1750fd9a6e5c418af1c18ca6983069dcf1738fc9106ebf542a86e4ccfc50b45a0d97ca8681af8207128877f930f945e59ee262aa7f4014a01f3","other":"2cb076669efbaf2ff0b181a1b454061a31ef23937a40405022b126f0eb4bfba60c9e3397009d8c0ff0cabb603692532d0072c18c6838f43397c98483306f62db","up":true},{"one":"89d46e664ac471c7150fbfe43a49c98750fc64d5ca22fdc2a040c7ab78c25c48c1e9c2f0e5130d6b8eb7f0760fe962759d83f68cc08ffaac3520499b0ce694de","up":true,"other":"fee3fa1ba2a051d40a582908384ee81179db6c2b5f4bfa58c24f8015b794b43a093ed68b69bb209684135f972a055a9845978fa1b7d489e2126c3b514297f1c2"},{"one":"9bdacc256acef0433805477d38f32be849a8846d88cb883b19d290454639b42c6ab6c5c52d4f83453e8a156af7d85f606458aa9c0977c67282f56f34ff0acbfb","other":"b4557089e4247379e587a087f53b36dd1f86f85d9dcfab5dc562079978cd959adaef5b30d11258d9cb552e7c5abddf5377a71d449febe8f2acb0aec3ebd8ba73","up":true},{"one":"df9306a263f40e0e255996500523354de3cc78b68ae560f66d79f6ea28f30f773f1fd6ebc33928723dfde2ee3d4f982b203bee4c3803a5050df83477045bb279","other":"fc9b1b2bbd5e682eb350d23f3ee33b245495daedae9370de7b1f55f91cd45db831d196c17615e11decf6b67696a268ac788130e3de38c7f6aeae811f3ec8c8ee","up":true},{"one":"ee0b09ee6a1057c47102e582e2fdec7b9212802e59f062a9360da0db535d4987126ab24848c0d76fa8485431a5140307e2b0c0d9f37cbdb35756e6cc1bdb3bc0","up":true,"other":"d7e3661c0af6754c875217f93d34b254f1f45fc1359a4c6146cd0efa4c6e12aed9a4fb0a21a136f73af4fc2c6d0a63cb809d81855bbc9f51e29d23d90f77b326"},{"one":"e5cb29b25debcfaaacc0b04e708c8c1cb9d2dee29e82596a1c72a934032cf738800b9525cc277d0c5f5dacf2f278329b54da161b4bafa285243fa0e9fd7b2f3a","up":true,"other":"a5f7163586fce1750fd9a6e5c418af1c18ca6983069dcf1738fc9106ebf542a86e4ccfc50b45a0d97ca8681af8207128877f930f945e59ee262aa7f4014a01f3"},{"one":"e5cb29b25debcfaaacc0b04e708c8c1cb9d2dee29e82596a1c72a934032cf738800b9525cc277d0c5f5dacf2f278329b54da161b4bafa285243fa0e9fd7b2f3a","up":true,"other":"2cb076669efbaf2ff0b181a1b454061a31ef23937a40405022b126f0eb4bfba60c9e3397009d8c0ff0cabb603692532d0072c18c6838f43397c98483306f62db"},{"other":"588df3185f63a5443d8c6b972f67805f0557184d916005f537a4b27cd02bd6a12e432a2b34b234a34f22e923c6f116da85be20bad77a2bf69913684e9d0732ba","up":true,"one":"aa90454031068598ee39af5f1429c7a72277946d50ec2004f340406dbcc9f80cac505c9d9b071f85e2ccfd4b13bcf943f3cb9dd9f96f62d41352af9d8fffe7e4"},{"one":"7d9979c13cd8841e84e5d199fc263962ca6fee12664d8526a581bfcdca2e3427ca169b9a0244dd8292a9a1be2bcedb0e8f626eadd307068c11c03b6df13aee33","other":"588df3185f63a5443d8c6b972f67805f0557184d916005f537a4b27cd02bd6a12e432a2b34b234a34f22e923c6f116da85be20bad77a2bf69913684e9d0732ba","up":true},{"one":"5a235aca7005df295d5bd924b1272452e9bdad408ca5223b9eb76800b4bd4e3158a1d663ce5243fee92233227249fe4bb8507e8cb2c3729744b273bf488ba60c","up":true,"other":"588df3185f63a5443d8c6b972f67805f0557184d916005f537a4b27cd02bd6a12e432a2b34b234a34f22e923c6f116da85be20bad77a2bf69913684e9d0732ba"},{"one":"6a55b94c9990249b24cdbeed96f065137f7b79ea8ee5f58da150d3962dfb62ba401960a53e7e8bd4e2c2908aa1a59b9d5efb4aafb316a9ab4fa67a0d95b58c54","up":true,"other":"7cc9389c8f751465e0b94baed896f6f122631052300b1b5b23d3c7656e4d11014a7a9ae62a1287bb040ca37221871a566cd470e523846df7e3acb5f94c7cde06"},{"up":true,"other":"a8fac88fba179fb9b259d94caac9cbe45d873a0131bef8844ac4383b177daf6f301f8793623fec5876885db1a91e5b3e98e2aafdaa47e03b1f6d9740f48af7ac","one":"8f3e9102306a13adb91e01f7a847e7880054f1a7df8976d05facb3a8fb37d47cce04f25e18a19713e5c3da7541e96e829fc67c8b924b717d2d9586c9c12d4fcf"},{"up":true,"other":"624248a794fd62248024360f128b2e503c752340694a316bed420e5ed2cebeb5bf970df95a2806732237a26de3778222b0454e2e7d2875129b193e7890fd5b95","one":"49215dfa786bfaa52b1e7aa6899392711a770b2504c82f536381fb1f18df16960257d75530efabf6dbd2b1361decc29758f870b318f777decf51f4833a9c1f00"},{"one":"93073da602d6326a48464a8b6890220b3aae0abf5b6961180f3aff2a14573c43411bd519d3e0012a646ec2977be18915d95a36d935a69f93985f5307ea4e3ebe","other":"f6a12b23423c047927a3024a6dba7ce88927cb21d4df3778bc5ebb262cc403261c79ba6d9bda07f1852c009d803a77f429e9e48ec1d63cae98256e529d45b276","up":true},{"one":"9bea5f82c2a390587de44d620d6637834e6f2329cd83d8df6305b03b75d9b543160b6c6f9f8887e6bc88f1d0726435d6c8ad813aadad0653b0790b8f6388413a","up":true,"other":"510536aba28aa635d8a1098a6dbd2070748ce1eb0e14b54b93a21196543a60df546ff6a2b3b5b9f32a5c2a37f5aba77d0b74f28b2dabeeebf3fe5afc20a3209c"},{"up":true,"other":"2bea7540c99456ea889a8ba2e448c11e6257bf987d01f13eea48128ba58577ab0936855035ee140c9907e382a34ca85a179c74892cbd9eb92fc2b35601addc6b","one":"a47697063a2fb973449bdabd0925e10944ba1f6d8b2cc5c38b295f611eea3402b5cf3ae857716a34d84194955f5ed61350affe56223349124c8233852141f9a2"},{"up":true,"other":"8e5e8366251e33277e7db6f6c04629b2ce3eee217e973acb97c83773671b0160c40732794584db741a29a763672b90f3bdf34151fd4a6986b9d0956dc61d9723","one":"a47697063a2fb973449bdabd0925e10944ba1f6d8b2cc5c38b295f611eea3402b5cf3ae857716a34d84194955f5ed61350affe56223349124c8233852141f9a2"},{"up":true,"other":"e7b2adabc2c99ac47b1e94fc0a2c63a00a1d622ea67a4c1858f4cec93fca957d43d8429605761bdf5eed4f733dac1a3d12fb928f22abf248965994acde63864a","one":"b3b4b203395bb6655d79ecdcee11638dd9a16baccfcc1f6fcc8b31832c8ca35650eb6c2802104eeec6d96ea80404381a2bd9b01dcadc748a4666b761d9ce64f8"},{"other":"4116fbb7d55bfd4bd8db9cbfa570ac361bb88605b6aacbf84e245893cf3fa599ecc086688a4c534c81f61a90fa344ca37e4d4013ddc03f7f08218724a55f66b1","up":false,"one":"f056acbdf491d1bb091937335c10096ea44b7034e994d134bc16d55212ff049bb097424de96c615ea699359a7ef77b3b54def2b3a5f43d735ffda65f73d61f7f"},{"other":"4e88cc60efee147fb72a735775944c7b2ba0790e2b2b935b4b3c2da9a3158a2a7aae411e9204cdbe6b2304d90a3a8278f8bb1a800a409e8500d100d84ba1947f","up":true,"one":"46717bc5fb7fcbcdc961e7ef091020f9f222858cf3d4afcc0b0bb1b782b7055d9eb833e0a04cb32d80406133ac77162521c43edf9f9690872222760e31462ccc"},{"other":"6a55b94c9990249b24cdbeed96f065137f7b79ea8ee5f58da150d3962dfb62ba401960a53e7e8bd4e2c2908aa1a59b9d5efb4aafb316a9ab4fa67a0d95b58c54","up":true,"one":"a47697063a2fb973449bdabd0925e10944ba1f6d8b2cc5c38b295f611eea3402b5cf3ae857716a34d84194955f5ed61350affe56223349124c8233852141f9a2"},{"one":"8d3ad57509b36c4ca5c4663f3d1977a3125e069078842634e6cfeb22c044281e3d02f06eafc6d2a60089f03d70f5134a6635c35563c9f911fd845a6ef9bc8952","other":"7b4585f8a4e4904239994a1b8bdc76299da8e46a8a632fabc6c33dd4170f8f3715e4c4f526ea5dd14093b150855960e432b1b140594aca21995f9e0722fb57f1","up":false},{"up":true,"other":"d3cd2f34f67830ccdc295b7537a6d27c02b44503808ca666124f52ecc3d6c35b7d3f14343997006aef2cfbefc8d27809d389477e99c236b9f8a897a4bc406a43","one":"c0a2c08fa8b70ecbf1932254945d5f689b0da7a287019d384152f383f6229acd4d82eef26205bc12e062dae4569814bd1c996ee4fe5886bd6bdd93c4f0ac113a"},{"one":"6c2788dec7ae7a77134065afc1174bb92b87833e87acaa72fe9e62c92d2017f217f9fbc5884cdfb7236a7bb75e463e49ecceb1641a8629516211d9699587046e","up":true,"other":"3639f964feba681db9702cac3f02058f2e490fd7bffb217dc3480dc458decafd5955541fea89f0f6f14ee50a745eaf98b21363d6b4fb88c31bd32bf7845d524b"},{"up":true,"other":"9e21f5d4cfb389ac3ad43497689878bd245a89c587a8637d832b1e355ba244f4c83e6499bc7936e6d35645db25910ecd89b9af9b6b2f0c7cc4d7c6114328d7bf","one":"6a55b94c9990249b24cdbeed96f065137f7b79ea8ee5f58da150d3962dfb62ba401960a53e7e8bd4e2c2908aa1a59b9d5efb4aafb316a9ab4fa67a0d95b58c54"},{"other":"49215dfa786bfaa52b1e7aa6899392711a770b2504c82f536381fb1f18df16960257d75530efabf6dbd2b1361decc29758f870b318f777decf51f4833a9c1f00","up":true,"one":"90b8e73916046b5433dce049bfe125ca2bf2fb390ff7301f9bc5d8d0183988577aa2a7392aaa28091aa81c8ac23942b5751420b9ee48e488a68411f9d2b1e5d5"},{"one":"e8a679f627d03347a4fcec0a0940f7ffa90ce3fefea290db3af4f3a32d27965bfb51832b6a6de2495c8a8cc026bcf993b84a0cced778e158bb81c034f5e4bd76","up":true,"other":"8e5e8366251e33277e7db6f6c04629b2ce3eee217e973acb97c83773671b0160c40732794584db741a29a763672b90f3bdf34151fd4a6986b9d0956dc61d9723"},{"up":true,"other":"f056acbdf491d1bb091937335c10096ea44b7034e994d134bc16d55212ff049bb097424de96c615ea699359a7ef77b3b54def2b3a5f43d735ffda65f73d61f7f","one":"8fb6838337f832445531764ddafc3c747b2607f2f33e244685d6de621c2b53264270f5504187e43b7fa5cda53e66dd00b16c06879c82fb38a3d9e8aec4060210"},{"up":true,"other":"222d7a2f94dc82a09fda70b8195fc3a60433a90f53998872318c57625c528c90572d78b444ac4901dcfece1a03ef8b6cbe7845366a845a942f341f6db58a9b3b","one":"da22fb43c6d230d92f9c09454e282dc45dffc759740566039f1bdfb58171c6801f721841de83217277b3fb70983e7d34da53bbf25d1d45413a78d9afff151826"},{"one":"b87e7f36ed6bf142d48545024d2fd6e120c44511701e7c0b7d7fc786f4f29d3357024b15f70b78215d8a4c2b7572d608c11b31612743e23db4fa673f0cd6519b","up":true,"other":"5a6318af8b4615cf30610a05ade7704182fefd0a3fb3d76c47cb392e114d8d30004f0ec214326b11532fd1e928e66f632bbcde126a94c87774063853a9518dc5"},{"other":"4eab70233789c544bec97040a04099494bf269a819584a5d0b42295c918a52b02f224a8ed127aba3d92c02f567356bea4b95f77230ef548dfa7fe44b643d8704","up":true,"one":"c29e80096fbe7bc9fcbfdbe3cf6c06449192a3ed280e46a1fa5d424428d893c3456c985c1352c119236cf783834365439751cc87e7ed196614705dd3db6674cf"},{"one":"11e9729700f5046b47d5e4521630cb57408f59a3337ca7db7984477a16c1f3b90c1d8d1f8d6a3f2a72e35f373fa73ec47a5636b36e40b2fb83756622a08896b8","up":true,"other":"5982e7dfd39c527851f6ea6430b70e654d95df5ec4401ca1d8dbd1034cf7a65d1126d60b36ebbd396c9ca32e6e8515f34f9dc0a8d2980afe4aa181c8bf68437e"},{"one":"ec19efa1d488e74da6bf239825b24678f549c377326c5d33d100b708a9a28a3fe129d542d7ba71e0ade46c15c6e9b38f09422560444388e609a8a66ceb8e0ae8","up":true,"other":"dbb6621460b054f584f1c6157b4020f3c58d84c3a12b57436e10525ae60ab27036bf3edd68b92f2b13674877d01c2871dc67a9031c3d0470985f4b071696346e"},{"up":true,"other":"2abb91884cc3a8fb91b2f2f369f9430f2b3b05c75ce6203aa7a50312c9f141f9d0f615063d3576a5ce8a4be9ecb942aa804a717f76d9e8dca03d115dcc43f775","one":"3b71a324bd7b1a8fb19d8206eea1ca8190cb1faf5fcd1bfc52cef6b52296fe1db3e54d70180133fad1fa1188499d0dd73d2d075fdc6b3ffd9042d690e7d88e02"},{"one":"b4557089e4247379e587a087f53b36dd1f86f85d9dcfab5dc562079978cd959adaef5b30d11258d9cb552e7c5abddf5377a71d449febe8f2acb0aec3ebd8ba73","up":true,"other":"ec19efa1d488e74da6bf239825b24678f549c377326c5d33d100b708a9a28a3fe129d542d7ba71e0ade46c15c6e9b38f09422560444388e609a8a66ceb8e0ae8"},{"up":true,"other":"1edeb91789b9aa996fea7a70964e0be33ee50acbe6d8f7d9d9fcf6dcf755dab6402637a610116f0eb716b19259429bdcced8bebc28ffa334387a430efc21b9b0","one":"510536aba28aa635d8a1098a6dbd2070748ce1eb0e14b54b93a21196543a60df546ff6a2b3b5b9f32a5c2a37f5aba77d0b74f28b2dabeeebf3fe5afc20a3209c"},{"other":"e993be8034861aebc9bbd11115f25d9c719d43fcdefc323599616cc26240cee38dfc27bb7f339149a54a3c9ad13b2d6ca4f0ae690e4355605eda6b789c4a431e","up":true,"one":"723f362e98f90d7ef15e24e353759fdbdabb08adab767dba73ab546741fac3dfb457466f1e2c851aa49526da1408f8ddb509e12f7dc0bc1e785c5b72be8a986e"},{"up":true,"other":"2880e0defd1bf2665bdd20dfb46bc0a9ad707f495211fc78e611ab479d78398db7daff7d3f4b6bf81fd13bf766ecc8271e0ea99a2d74abd2f9ddf98835ffdcf1","one":"17ae0b24297a3e6e027884e5e4529b6646ae340f5736eebc6187a9b59832a445f3644172d92438351e3803e56a67472b29f3e1d48844ae2e11e5e6670eed1436"},{"one":"7c6e6a49429a4e24aa4aa5c7ba19684f77cd67d3744688baff6e7f1d74b7e9d2df85f3e57e0df0a9b960b5bf982a610c5639c3e7a6935ba13fbc77243b2dad19","up":true,"other":"aa90454031068598ee39af5f1429c7a72277946d50ec2004f340406dbcc9f80cac505c9d9b071f85e2ccfd4b13bcf943f3cb9dd9f96f62d41352af9d8fffe7e4"},{"one":"17ae0b24297a3e6e027884e5e4529b6646ae340f5736eebc6187a9b59832a445f3644172d92438351e3803e56a67472b29f3e1d48844ae2e11e5e6670eed1436","up":true,"other":"b18c7131a319db61ab84d06e90092d93c91141e9a270630af9c3ab1eaf3bcad09f4d20a1fc845b21c994bf4d9e337d0bd756a75e2198097540355e7ebbb531b2"},{"one":"85c0b055439f114dee5eb0961013c117a48d62b0f17c61a7fd92a84092ef09bb3bbce686aa96e14528d5663565c57d657fa9813b1f38e268caeb1cb0842ef232","up":true,"other":"b7cc9044d021b19cd8a6d290d21f1c91fd5deec472583d0aeed0a6aacc8efef9968079254132becc5443df14dd3f4feaee56d14b885c078649727b9659139fa6"},{"up":true,"other":"4b332b389f1142c0da42aaeb2e2692081d0002de0eb6741b3269e898a8101571d4556b755f2e8841e7a607bb41e398d2b0577fbe71098e7097f0fe6c720e1526","one":"85c0b055439f114dee5eb0961013c117a48d62b0f17c61a7fd92a84092ef09bb3bbce686aa96e14528d5663565c57d657fa9813b1f38e268caeb1cb0842ef232"},{"one":"c9d705012a06d82c4d44db95b4f1c63ddd33ad64d732e96b1d878caa0caac433d4096f01495a6f0e8a56af122b0470fd745db6d906353b590a4710472b93f5b2","up":true,"other":"7db14fde1da8794ae7ab5de37c9e2537e1024bc830c176c0d01635cafed47773d3a28e156db81ecdb95903222b900c3ebd4c4b3db2971dc0ef6a1e386027ffaa"},{"other":"49256eccce3e036928a4b6b346126c6777dca5ea0134de85efca340f97ad0f827f3094f1562e3e186d35b8292a50c20ffae01409890bbb78598494285e14dc2c","up":true,"one":"9c8fca41b833e88110559b9258653160f5fb236bd637272ac58fe1adf333f4df75b94a805eaebb9f10a8c1a26d357dd75140560551d3fc4da79da2c4fc9479c3"},{"one":"9c8fca41b833e88110559b9258653160f5fb236bd637272ac58fe1adf333f4df75b94a805eaebb9f10a8c1a26d357dd75140560551d3fc4da79da2c4fc9479c3","up":false,"other":"6909a0fa47718cfc463b1e96c21734b46bd5b28dd59cd3d66d67990783436b7538ab2659d427029b97c8dddf313b26532518c0c34a2b1fca8cd852b0fdb83ab8"},{"one":"8e89fe4b3fffea8af247d2581aa511056efbeb796058d50a341d57aa0f7ccc2192d90cfb8d18558363df798567faaddb86815e8bd671b36ca37af0651535aabf","up":true,"other":"b152eb30c9f46ec39166016f03d289f98cc285ac62d204da32e5a003da14e4f02c64df8ae1d0c8a2a902adc5f7dd7604081a0b140c9b64052082f0861945f5a4"},{"up":true,"other":"8d3ad57509b36c4ca5c4663f3d1977a3125e069078842634e6cfeb22c044281e3d02f06eafc6d2a60089f03d70f5134a6635c35563c9f911fd845a6ef9bc8952","one":"936fad959da2d8b0cfb2bcd78c5da65bcce5e9463be7fc7367f45cdfa20678f4c466fb1e3f600783a270855fd4b9cd6265054f79ecb116141e7c67a492041bed"},{"one":"b8e0a56df21baae43058f575b714ae9a33c097d18f1a628b3b6ae5e86dd46a06e44c0dc272baacb5be0f7bf57fd6ddce107544eb3b94dca1aeae9f5773496a72","up":true,"other":"4eab70233789c544bec97040a04099494bf269a819584a5d0b42295c918a52b02f224a8ed127aba3d92c02f567356bea4b95f77230ef548dfa7fe44b643d8704"},{"other":"bc0df855bdadcde3e447415444f655eb430925a8fa81cdcac75909e7d79750f01827938570e75e388cc7058ba8ebca47afadf8b07172bc078488fb618ba71024","up":true,"one":"dbb6621460b054f584f1c6157b4020f3c58d84c3a12b57436e10525ae60ab27036bf3edd68b92f2b13674877d01c2871dc67a9031c3d0470985f4b071696346e"},{"other":"f4cdaeb513aa98f8868d8eb3a1d12c07367725928a1bc7d6ca4b583788e111a955463037ec7867260511896d97dfbf096aa77ee8a7d9ea1c06cad4a92c45108d","up":true,"one":"f8a5ae50e5b2d84096c10a6a8493a9eb8113df64c4f1336c0cf4649302649b158fa4cb7941591e55356891bcc1008a535df427546af19988a241c5f466467963"},{"other":"3f322f9b1f1f0692663bc3be11cf11386f4a14696aab610916cfcadf0234cce0c86b51c85ce2108e9bc21d50ad71cc10a6eeaec3fc7732908f3a8b193465a0ac","up":true,"one":"85c0b055439f114dee5eb0961013c117a48d62b0f17c61a7fd92a84092ef09bb3bbce686aa96e14528d5663565c57d657fa9813b1f38e268caeb1cb0842ef232"},{"up":true,"other":"535287ca3d41fc1cdf20a964749a849c51d0aba285f41f447cc2b1dd6f5845b6b98e0241dbda0718b234ea850081bfbf9df01d1aa636d7dcbd99ef3c0a773aff","one":"81dc656de121016bcde81d5bf7919839acfc180dfbf1a6de2cadf704ff13af98aa5715a4168832ca6f651b2ea7ad9e6ca5f1c1cb7e885dbc2eb23d4aefb87bd6"},{"up":true,"other":"fd0123c7b96004067e98e463e273de5bc5402399ae70a95985b5f682e30d4f35d070deaf8c71d201e98c4324d832b95aab7535ad8a2658f66e3e0bb1202204e1","one":"06aab75fed9a03f5525e3f1d8f8997fefaefd5b16e8f485d571beda00b1741efbb61a8a74fa12c2f6de66227c3fabb4d411659cd9c7b1ef32e171e6bf517cc39"},{"up":true,"other":"545237d8463b75fd2e9bbfbffb35c5b78b4abbc85f6bfbd56976789012dd9a62ca1f866bf37bb33618e026aab764adb9ced5e00cd415562f69992f74c795083f","one":"06aab75fed9a03f5525e3f1d8f8997fefaefd5b16e8f485d571beda00b1741efbb61a8a74fa12c2f6de66227c3fabb4d411659cd9c7b1ef32e171e6bf517cc39"},{"other":"50c79baa3e6781482ccb5e960c699dd9c13f479467c6315c5292a396337cf3619e7faba1971a1f470051cb9042f80ea6750defe3936b72aac4d9bac6f8368c67","up":true,"one":"06aab75fed9a03f5525e3f1d8f8997fefaefd5b16e8f485d571beda00b1741efbb61a8a74fa12c2f6de66227c3fabb4d411659cd9c7b1ef32e171e6bf517cc39"},{"one":"2c976b6007cda135444233c7bd03d22ac9756710b746c36bc032e7fdd42f2ffb89ca5f5e754ff96b8f3cbc474e346287e5b8531d9f98fd63c426c632872220af","up":false,"other":"bac3fd2ea491d8e4ce1e5d469ec73f3d537d61279ae66e7a394b20a188244a886d3059ef0d304c0801878f9640374f7c8aaf56558c41f12296d3fc7f911ed66c"},{"up":true,"other":"6a55b94c9990249b24cdbeed96f065137f7b79ea8ee5f58da150d3962dfb62ba401960a53e7e8bd4e2c2908aa1a59b9d5efb4aafb316a9ab4fa67a0d95b58c54","one":"842ec3faa8b4a4cdec32abfa00ae827277fe2696e1b0c6551154533b16cf75ae69caf834b4f08488fa5c8b322fb633b1fd8a5b7d436e9c589cc9074dc031ae68"},{"up":true,"other":"d7e3661c0af6754c875217f93d34b254f1f45fc1359a4c6146cd0efa4c6e12aed9a4fb0a21a136f73af4fc2c6d0a63cb809d81855bbc9f51e29d23d90f77b326","one":"1489ad735e1256900e4733707f8b78f1d853742a8f9b2d0c1c89651c60e7ee9d266afba5b4c1ed3f9cee05a1d2b2bba35dadb5b08973a93fd70dfb9e367339bd"},{"other":"33e9d4674b5b9b23e838583f01b429abca1330393dfc100b19ede6090a53df213011fae53169a66aa05d18e4cb497a17aa81eaedf1fe2e4348f9825c309438b5","up":true,"one":"89d46e664ac471c7150fbfe43a49c98750fc64d5ca22fdc2a040c7ab78c25c48c1e9c2f0e5130d6b8eb7f0760fe962759d83f68cc08ffaac3520499b0ce694de"},{"up":true,"other":"243164c4dd583f80c50813f43e5c27c894463400cd3afd776b36e79e7123d9261f01f06f92914aab83096b9a43fb655e79687590599284640a3a7d2c25454597","one":"6a37e63feed9e68c52cb8b385d5e8d8dbd2b211c57ded0d3b01fe8b306af5c0e5a7405d0d9a942648f0131926240d53450bc43f922a053528e5830d918313c3d"},{"one":"99af34b172d319633e07a4e528f416024653a230a9103a4b281171f75bb697dd6be4757558c94e86210b4da8d9fe1229f6a5d8c4174989ea0ce696f8d1a9995d","other":"6c2788dec7ae7a77134065afc1174bb92b87833e87acaa72fe9e62c92d2017f217f9fbc5884cdfb7236a7bb75e463e49ecceb1641a8629516211d9699587046e","up":true},{"up":true,"other":"3376cfc924fef1a45aae35d106439b131f363b3a42904b3974cc7cddde325441cce8551729dd62f1119120b0d452e78f063e8e711ecacdc27d9087aac5ab09b5","one":"e323da6ae861cb092543992b8985639f9b3bcaf1c3c68757f4603a67800be62950fe7d8f8ef80eb83a18107b677c7f5047ea89a5790e0ea2a7969f4856d28488"},{"up":true,"other":"f98c0f4444a1ec80773454ddb691c226b81d8e2f79ed40c45a422d3359565edf7bd635d3eb7bd6c9e0870746849fb86f0b1b34cd56ec8d3ad969812e080f4983","one":"89d46e664ac471c7150fbfe43a49c98750fc64d5ca22fdc2a040c7ab78c25c48c1e9c2f0e5130d6b8eb7f0760fe962759d83f68cc08ffaac3520499b0ce694de"},{"one":"c2a9c77247871cfa4d3c2d1b47619df91ed5b331a44c8e21f7c9ce431a4db9dfb87713558cc8a37911393907b4cc60be9445bad18adcea1bc5f318256e71be14","other":"1edeb91789b9aa996fea7a70964e0be33ee50acbe6d8f7d9d9fcf6dcf755dab6402637a610116f0eb716b19259429bdcced8bebc28ffa334387a430efc21b9b0","up":true},{"one":"1edeb91789b9aa996fea7a70964e0be33ee50acbe6d8f7d9d9fcf6dcf755dab6402637a610116f0eb716b19259429bdcced8bebc28ffa334387a430efc21b9b0","other":"9d372d73848389cfa1676f0cdb030950980ed5b68d5b2ef8a058f1d2095b26ff0fafab5fd3c243296ee2620edc67752970ab47370270856287f8612d1b190a19","up":true},{"up":true,"other":"9ea856ea440c776b9ffaad1237ec11d570a1f912a908b8363ff97cf7947d2523e3c73663240d8fac988698cdd81e877ddd4a609485fe9f26494136fae14212df","one":"e33a1476fcb8d2a1b9ee15871a960ce7a3337c93f5956a2825b1f8b2885dbdc0ed652b1eba549523866632b5b6898310bc638d946a9fcce27d65117eb44c25f3"},{"one":"49215dfa786bfaa52b1e7aa6899392711a770b2504c82f536381fb1f18df16960257d75530efabf6dbd2b1361decc29758f870b318f777decf51f4833a9c1f00","other":"c0a2c08fa8b70ecbf1932254945d5f689b0da7a287019d384152f383f6229acd4d82eef26205bc12e062dae4569814bd1c996ee4fe5886bd6bdd93c4f0ac113a","up":false},{"other":"7958d1517de1223e7fb30acf61d8618e49fb95a03bc2f49141f4c7967bc80b90e0dd526c205639de3c060029963d43813293c2556f7b127945c798f3f9f18626","up":true,"one":"6a55b94c9990249b24cdbeed96f065137f7b79ea8ee5f58da150d3962dfb62ba401960a53e7e8bd4e2c2908aa1a59b9d5efb4aafb316a9ab4fa67a0d95b58c54"},{"one":"535287ca3d41fc1cdf20a964749a849c51d0aba285f41f447cc2b1dd6f5845b6b98e0241dbda0718b234ea850081bfbf9df01d1aa636d7dcbd99ef3c0a773aff","up":true,"other":"510536aba28aa635d8a1098a6dbd2070748ce1eb0e14b54b93a21196543a60df546ff6a2b3b5b9f32a5c2a37f5aba77d0b74f28b2dabeeebf3fe5afc20a3209c"},{"up":true,"other":"a8fac88fba179fb9b259d94caac9cbe45d873a0131bef8844ac4383b177daf6f301f8793623fec5876885db1a91e5b3e98e2aafdaa47e03b1f6d9740f48af7ac","one":"96cd4caa32c0b3a3493e24e13fad1ef75c621005d74154c3fc8a73cca4c0120452b6432334d94849c63f75d56a2943a453c86d2a14ad1fb61ae6833e58451187"},{"other":"682288e4dae2374c4784acd0b285508920ce39a6b72cc0e30a3dbb7972e0394a2bddd5ee5f22a1dbf80f284dde4d9f8ede7847318d5353566b35a83e212477e7","up":true,"one":"9ea856ea440c776b9ffaad1237ec11d570a1f912a908b8363ff97cf7947d2523e3c73663240d8fac988698cdd81e877ddd4a609485fe9f26494136fae14212df"},{"up":true,"other":"d6747e1f8594f7449fc6d7c0e63ee843480567d498db096ff04229420861c83bca5215fc19d8fede0c54484f111f1f2581e189e638c21c5d9e1fd3174bbb3e98","one":"154d5ddb15ec12dc65362039d801383c189b5bcf6688883f2d7e3d0e8dc78e45f9f58d5dabc79a8798a243ce59abb95c77525db14f050fd8cb37d04b7276557c"},{"up":true,"other":"c0a2c08fa8b70ecbf1932254945d5f689b0da7a287019d384152f383f6229acd4d82eef26205bc12e062dae4569814bd1c996ee4fe5886bd6bdd93c4f0ac113a","one":"f52281c227aa82a3bd5fabfdcf8bdf1d9ea6739ab9b9075340143d59b4f2f8a79a981609c9f42823a0253c19a7281eed0e912e4054363ab7fe50117563ef14e0"},{"up":true,"other":"81dc656de121016bcde81d5bf7919839acfc180dfbf1a6de2cadf704ff13af98aa5715a4168832ca6f651b2ea7ad9e6ca5f1c1cb7e885dbc2eb23d4aefb87bd6","one":"c0bec7375c66bec98524ade2245c1d7480516fc5d87a3249e64ec86418e80e202f1e3da76832e97bbc3dcaed8c96ca344e4829347b4428f4b1cb61999e404c05"},{"one":"b4557089e4247379e587a087f53b36dd1f86f85d9dcfab5dc562079978cd959adaef5b30d11258d9cb552e7c5abddf5377a71d449febe8f2acb0aec3ebd8ba73","up":false,"other":"dbb6621460b054f584f1c6157b4020f3c58d84c3a12b57436e10525ae60ab27036bf3edd68b92f2b13674877d01c2871dc67a9031c3d0470985f4b071696346e"},{"up":true,"other":"e993be8034861aebc9bbd11115f25d9c719d43fcdefc323599616cc26240cee38dfc27bb7f339149a54a3c9ad13b2d6ca4f0ae690e4355605eda6b789c4a431e","one":"e7b2adabc2c99ac47b1e94fc0a2c63a00a1d622ea67a4c1858f4cec93fca957d43d8429605761bdf5eed4f733dac1a3d12fb928f22abf248965994acde63864a"},{"other":"ab8eda9b360d3e0b002ba31d48311057880844b828ad9817a2ad19736860d0114d4a17e9e9427c842d52e7ff61a09c2cad9b70f506e338909535542dae38ede0","up":true,"one":"81901d9f043b4b1649ade3b5d22ae5f8bb42dd6db1eb37b836b99dd1c0388509ed4b54cc5638c9d4a6c5ae6c6913bbfffb303d7d94bf4ed50e871cf95459e2c3"},{"one":"c29e80096fbe7bc9fcbfdbe3cf6c06449192a3ed280e46a1fa5d424428d893c3456c985c1352c119236cf783834365439751cc87e7ed196614705dd3db6674cf","up":true,"other":"b8e0a56df21baae43058f575b714ae9a33c097d18f1a628b3b6ae5e86dd46a06e44c0dc272baacb5be0f7bf57fd6ddce107544eb3b94dca1aeae9f5773496a72"},{"one":"ab1a3542d67ef9d1a63653990bf0782f53b0169fe5092adc92fa7aeb38f66c6b62d49e3455cc2ac4994bfcfb03111953acf4cc3099026672cc61f6e24cb3ae00","other":"8e5e8366251e33277e7db6f6c04629b2ce3eee217e973acb97c83773671b0160c40732794584db741a29a763672b90f3bdf34151fd4a6986b9d0956dc61d9723","up":true},{"one":"c088bf88f1e152ca3fad17f098a71ca1021d46d8af12d0ee1c587a5e2a430d8e48beaf171fe01ee7680b671c00dd88c90f12a35c328a3f334661fdeee914a4bc","other":"b8e0a56df21baae43058f575b714ae9a33c097d18f1a628b3b6ae5e86dd46a06e44c0dc272baacb5be0f7bf57fd6ddce107544eb3b94dca1aeae9f5773496a72","up":false},{"one":"8e5e8366251e33277e7db6f6c04629b2ce3eee217e973acb97c83773671b0160c40732794584db741a29a763672b90f3bdf34151fd4a6986b9d0956dc61d9723","other":"6a55b94c9990249b24cdbeed96f065137f7b79ea8ee5f58da150d3962dfb62ba401960a53e7e8bd4e2c2908aa1a59b9d5efb4aafb316a9ab4fa67a0d95b58c54","up":true},{"other":"0c82c4b414375479375703ed9c19fb08c8143229ed4f1dcf448c6cf313810c098905123bec17969276936ae0cc39ed251b2811dbffb551d61159862b0eac0a23","up":true,"one":"5d002c37b74a6656db86f102b0cec82bc35a819a480e5a2952db0140ebab65dffeb1a79f04d53ff61447b5fad7c58cb75ea1c91ea47fcb9e024f27b92c6c874d"},{"up":true,"other":"99a7649bdf2ee7f0bc049308b0997e33abb68481c05a573df9aea30da5a1f267df07b2c584e3e985baf31704f04ad2a2c4876e0f8555333be6d09f5080b583f1","one":"46717bc5fb7fcbcdc961e7ef091020f9f222858cf3d4afcc0b0bb1b782b7055d9eb833e0a04cb32d80406133ac77162521c43edf9f9690872222760e31462ccc"},{"up":true,"other":"8e5e8366251e33277e7db6f6c04629b2ce3eee217e973acb97c83773671b0160c40732794584db741a29a763672b90f3bdf34151fd4a6986b9d0956dc61d9723","one":"842ec3faa8b4a4cdec32abfa00ae827277fe2696e1b0c6551154533b16cf75ae69caf834b4f08488fa5c8b322fb633b1fd8a5b7d436e9c589cc9074dc031ae68"},{"other":"6a55b94c9990249b24cdbeed96f065137f7b79ea8ee5f58da150d3962dfb62ba401960a53e7e8bd4e2c2908aa1a59b9d5efb4aafb316a9ab4fa67a0d95b58c54","up":true,"one":"e8a679f627d03347a4fcec0a0940f7ffa90ce3fefea290db3af4f3a32d27965bfb51832b6a6de2495c8a8cc026bcf993b84a0cced778e158bb81c034f5e4bd76"},{"one":"e8a679f627d03347a4fcec0a0940f7ffa90ce3fefea290db3af4f3a32d27965bfb51832b6a6de2495c8a8cc026bcf993b84a0cced778e158bb81c034f5e4bd76","up":true,"other":"2bea7540c99456ea889a8ba2e448c11e6257bf987d01f13eea48128ba58577ab0936855035ee140c9907e382a34ca85a179c74892cbd9eb92fc2b35601addc6b"},{"other":"6b104eff1dcf58d11a7f707bbd41a910b2735b262c29e0f4e4127fda1b67def4e89b6ebc1b3cc1e06c3968d0898e1085badc7da24d3cd6624cb100e85863cc97","up":true,"one":"f52281c227aa82a3bd5fabfdcf8bdf1d9ea6739ab9b9075340143d59b4f2f8a79a981609c9f42823a0253c19a7281eed0e912e4054363ab7fe50117563ef14e0"},{"one":"df9306a263f40e0e255996500523354de3cc78b68ae560f66d79f6ea28f30f773f1fd6ebc33928723dfde2ee3d4f982b203bee4c3803a5050df83477045bb279","other":"33cac8f621b9122e118036154778d27dc419b6b58ea2e89b833f3932f411dbc3511d92b55ae4cf80632142bc8e67994899aaa30c499d0289fae85b12564cf01f","up":true},{"other":"0c82c4b414375479375703ed9c19fb08c8143229ed4f1dcf448c6cf313810c098905123bec17969276936ae0cc39ed251b2811dbffb551d61159862b0eac0a23","up":true,"one":"a5f7163586fce1750fd9a6e5c418af1c18ca6983069dcf1738fc9106ebf542a86e4ccfc50b45a0d97ca8681af8207128877f930f945e59ee262aa7f4014a01f3"},{"one":"85c0b055439f114dee5eb0961013c117a48d62b0f17c61a7fd92a84092ef09bb3bbce686aa96e14528d5663565c57d657fa9813b1f38e268caeb1cb0842ef232","up":true,"other":"af9b80f6836113aeda897d6903e9ffb4f7f1a706a7f821d0d40f03a0d83c18d6a19795ee4bfc1093ada04014415b1f230db1d2f056df3f5027cce71611588046"},{"one":"dbb6621460b054f584f1c6157b4020f3c58d84c3a12b57436e10525ae60ab27036bf3edd68b92f2b13674877d01c2871dc67a9031c3d0470985f4b071696346e","other":"b1dd1b08975319030626aab821032a0c687a103ee8942e8a2e2cf029dd72832a49630e78d2d8b184579f22178aca0e875f9fad701fb81afd2ac110ab2b417376","up":true},{"other":"c088bf88f1e152ca3fad17f098a71ca1021d46d8af12d0ee1c587a5e2a430d8e48beaf171fe01ee7680b671c00dd88c90f12a35c328a3f334661fdeee914a4bc","up":true,"one":"c29e80096fbe7bc9fcbfdbe3cf6c06449192a3ed280e46a1fa5d424428d893c3456c985c1352c119236cf783834365439751cc87e7ed196614705dd3db6674cf"},{"up":true,"other":"29acdd4c1233441bd40f98e245ecc9de94de6f9d0ab7c1a9923d833a2c8e6c1bd26d792686fec762b31fe28bbdd7aa04c9a594d997d08c133bb24cb2d877595a","one":"dbb6621460b054f584f1c6157b4020f3c58d84c3a12b57436e10525ae60ab27036bf3edd68b92f2b13674877d01c2871dc67a9031c3d0470985f4b071696346e"},{"one":"85c0b055439f114dee5eb0961013c117a48d62b0f17c61a7fd92a84092ef09bb3bbce686aa96e14528d5663565c57d657fa9813b1f38e268caeb1cb0842ef232","up":true,"other":"8e8614a4c2ee2b1a3fa5ace0ca353cff36b3de3308ccf53665b8b56f8e2456a8a65f3846d786dccd68b1bfcefdd170ea5f8edb481800b1ce72d9fce2added7f0"},{"up":false,"other":"48e35d67e14ee2f329c0275bc965829b761885dbc3671f4673d84d76d18a5b6415e619e219b5d90761a5c6bd2f43c6a58708286a063daf46b502944f8ef9230b","one":"e323da6ae861cb092543992b8985639f9b3bcaf1c3c68757f4603a67800be62950fe7d8f8ef80eb83a18107b677c7f5047ea89a5790e0ea2a7969f4856d28488"},{"up":true,"other":"8f3e9102306a13adb91e01f7a847e7880054f1a7df8976d05facb3a8fb37d47cce04f25e18a19713e5c3da7541e96e829fc67c8b924b717d2d9586c9c12d4fcf","one":"7465fe601a9ad8e640069e6e07d56afabd3d4f008f3084f944d869b47fda3f511f191062802a53da511f60891dd0bcc5fac60254ef9db7aa3b41f5791b0b6975"},{"other":"ee3471e1d835c4294f7ba642103039ccc548fe4edc177c79b63433ebbb0dc9d06600844f1fed76c7096ee9538e49e4e86fb8cffe9095dbdcde27695ff28ad395","up":false,"one":"c29e80096fbe7bc9fcbfdbe3cf6c06449192a3ed280e46a1fa5d424428d893c3456c985c1352c119236cf783834365439751cc87e7ed196614705dd3db6674cf"},{"up":true,"other":"92dbb67da2b99a8fe46b1e510addc2b83e357ac0b5287b7ef5c1b1bc6e252b8dfd605a6896ede65848e429216d1f67d530d9e7b83ff14058aa2e5b6e405d6801","one":"7465fe601a9ad8e640069e6e07d56afabd3d4f008f3084f944d869b47fda3f511f191062802a53da511f60891dd0bcc5fac60254ef9db7aa3b41f5791b0b6975"},{"one":"1edeb91789b9aa996fea7a70964e0be33ee50acbe6d8f7d9d9fcf6dcf755dab6402637a610116f0eb716b19259429bdcced8bebc28ffa334387a430efc21b9b0","up":true,"other":"154d5ddb15ec12dc65362039d801383c189b5bcf6688883f2d7e3d0e8dc78e45f9f58d5dabc79a8798a243ce59abb95c77525db14f050fd8cb37d04b7276557c"},{"up":true,"other":"510536aba28aa635d8a1098a6dbd2070748ce1eb0e14b54b93a21196543a60df546ff6a2b3b5b9f32a5c2a37f5aba77d0b74f28b2dabeeebf3fe5afc20a3209c","one":"c0bec7375c66bec98524ade2245c1d7480516fc5d87a3249e64ec86418e80e202f1e3da76832e97bbc3dcaed8c96ca344e4829347b4428f4b1cb61999e404c05"}],"nodes":[{"node":{"info":{"protocols":{"bzz":"UJMuLB8Dy8QdjZYAziRX8+rNgsNrYfoJvvUSsQTq+Nw=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 50932e\npopulation: 23 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 c8f9 | 121 985c (0) 99aa (0) 99fb (0) 99db (0)\n001 9 290f 03f5 0f81 14c8 | 73 265d (0) 275c (0) 2454 (0) 259d (0)\n002 3 67a2 7471 72fa | 31 6ea5 (0) 6d21 (0) 6dbd (0) 6330 (0)\n003 2 4a81 4a82 | 17 458a (0) 47f9 (0) 46c5 (0) 4019 (0)\n004 2 5fab 5fd0 | 5 5c5d (0) 5f05 (0) 5fa8 (0) 5fab (0)\n005 3 57d5 566e 5695 | 5 5571 (0) 5716 (0) 57d5 (0) 566e (0)\n============ DEPTH: 6 ==========================================\n006 2 5261 5288 | 2 5261 (0) 5288 (0)\n007 1 5110 | 1 5110 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"id":"3e2241cdb9f34c1d2c6930e59940e2c4b92b0287579d7263a620a609c5e66dca6d85df48cf1bffd63663a6704c42d0866aae3e484fd9a44b6a012f72dd3cef6e","enode":"enode://3e2241cdb9f34c1d2c6930e59940e2c4b92b0287579d7263a620a609c5e66dca6d85df48cf1bffd63663a6704c42d0866aae3e484fd9a44b6a012f72dd3cef6e@0.0.0.0:0","name":"node01","listenAddr":""},"up":true,"config":{"services":["pss","bzz"],"name":"node01","id":"3e2241cdb9f34c1d2c6930e59940e2c4b92b0287579d7263a620a609c5e66dca6d85df48cf1bffd63663a6704c42d0866aae3e484fd9a44b6a012f72dd3cef6e","private_key":"c4e98d074abce07e849be2810e5522bdacf2489125ed7577e02b4809f9619700"}}},{"node":{"info":{"protocols":{"bzz":"D4HKun0vdS/GcIKfdFZRFLzxDFuX1/kyUrRn0O7ieLM=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 0f81ca\npopulation: 17 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 b8a7 | 121 fd2d (0) fed1 (0) f915 (0) f924 (0)\n001 2 4a81 5093 | 62 6ea5 (0) 6d21 (0) 6dbd (0) 6330 (0)\n002 2 2374 259d | 35 275c (0) 265d (0) 2454 (0) 259d (0)\n003 4 1566 1d94 193e 194a | 26 13d8 (0) 123f (0) 12b9 (0) 1673 (0)\n004 5 0210 03f5 05e8 05ec | 8 004e (0) 0210 (0) 03f5 (0) 06aa (0)\n005 0 | 0\n006 0 | 0\n============ DEPTH: 7 ==========================================\n007 2 0eee 0ea2 | 2 0eee (0) 0ea2 (0)\n008 1 0f5e | 1 0f5e (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"discovery":0,"listener":0},"ip":"0.0.0.0","id":"50c79baa3e6781482ccb5e960c699dd9c13f479467c6315c5292a396337cf3619e7faba1971a1f470051cb9042f80ea6750defe3936b72aac4d9bac6f8368c67","enode":"enode://50c79baa3e6781482ccb5e960c699dd9c13f479467c6315c5292a396337cf3619e7faba1971a1f470051cb9042f80ea6750defe3936b72aac4d9bac6f8368c67@0.0.0.0:0","name":"node02","listenAddr":""},"config":{"id":"50c79baa3e6781482ccb5e960c699dd9c13f479467c6315c5292a396337cf3619e7faba1971a1f470051cb9042f80ea6750defe3936b72aac4d9bac6f8368c67","private_key":"d607b8638fa33ef417d88597579e00a2f93e76881193a8692b57d03b27a60ba7","services":["pss","bzz"],"name":"node02"},"up":true}},{"node":{"info":{"name":"node03","enode":"enode://51df4f4d4f020f22f55a5fd00c7f9c68c232c167ae4d4e80d7695f8f39c5aa0a7b565c1c55bdd6a21e06fa056549d08fd2e9d76fd79e21295557aa30d1ae022c@0.0.0.0:0","listenAddr":"","ip":"0.0.0.0","protocols":{"bzz":"uKdXiiKh6ZY96ut+QUE3vuD0WQvLk9Mn6VJdbcA7gaI=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: b8a757\npopulation: 22 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 6 3dca 1d94 0592 03f5 | 135 7ffe (0) 7fa4 (0) 7d45 (0) 7d94 (0)\n001 2 c8f9 daa2 | 65 e3c9 (0) e4c3 (0) e44b (0) e649 (0)\n002 1 8ae6 | 26 8163 (0) 8612 (0) 86f7 (0) 8c89 (0)\n003 3 af30 a033 a485 | 16 a80b (0) abfa (0) aa50 (0) aa88 (0)\n004 5 b310 b710 b463 b45d | 8 b310 (0) b60d (0) b79f (0) b710 (0)\n============ DEPTH: 5 ==========================================\n005 4 be0a bfec bf5a bc08 | 4 be0a (0) bfec (0) bf5a (0) bc08 (0)\n006 1 baf3 | 1 baf3 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"listener":0,"discovery":0},"id":"51df4f4d4f020f22f55a5fd00c7f9c68c232c167ae4d4e80d7695f8f39c5aa0a7b565c1c55bdd6a21e06fa056549d08fd2e9d76fd79e21295557aa30d1ae022c"},"up":true,"config":{"private_key":"c4501aa97316685b3e707bd881c1d805e96430723fa88ffc60e1703485eff5b2","id":"51df4f4d4f020f22f55a5fd00c7f9c68c232c167ae4d4e80d7695f8f39c5aa0a7b565c1c55bdd6a21e06fa056549d08fd2e9d76fd79e21295557aa30d1ae022c","name":"node03","services":["pss","bzz"]}}},{"node":{"config":{"name":"node04","services":["pss","bzz"],"private_key":"f1fceda785676921048d116f40e4d331ab32873f4b0343fddbd372c836808f2a","id":"b4f300abda4cf6e383f997510eb681e9fa62e23577e3c19bd7447fa1f5702a4e034cea5944248e7c6e6e92b5ae69195c3e8a2c5ca7827b4f4a00cc8546e6695a"},"up":true,"info":{"listenAddr":"","enode":"enode://b4f300abda4cf6e383f997510eb681e9fa62e23577e3c19bd7447fa1f5702a4e034cea5944248e7c6e6e92b5ae69195c3e8a2c5ca7827b4f4a00cc8546e6695a@0.0.0.0:0","name":"node04","id":"b4f300abda4cf6e383f997510eb681e9fa62e23577e3c19bd7447fa1f5702a4e034cea5944248e7c6e6e92b5ae69195c3e8a2c5ca7827b4f4a00cc8546e6695a","protocols":{"bzz":"HZQshVaPZASXxGqb1amCW8b7BVcSA6Pw8UowMmAtgfw=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 1d942c\npopulation: 20 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 b8a7 | 121 f924 (0) f915 (0) fb93 (0) fa74 (0)\n001 2 5093 5288 | 62 6ea5 (0) 6dbd (0) 6d21 (0) 6330 (0)\n002 2 3dca 3af3 | 35 31ed (0) 32dd (0) 3345 (0) 34fc (0)\n003 1 0f81 | 12 0eee (0) 0ea2 (0) 0f5e (0) 0f81 (0)\n004 3 12b9 15f6 14c8 | 8 13d8 (0) 123f (0) 12b9 (0) 1673 (0)\n005 4 1835 193e 194a 1b86 | 10 18f9 (0) 185a (0) 1835 (0) 193e (0)\n006 2 1e42 1e44 | 2 1e42 (0) 1e44 (0)\n007 1 1c98 | 1 1c98 (0)\n008 2 1d5f 1d07 | 2 1d5f (0) 1d07 (0)\n009 0 | 0\n============ DEPTH: 10 ==========================================\n010 1 1da3 | 1 1da3 (0)\n011 0 | 0\n012 0 | 0\n013 1 1d93 | 1 1d93 (0)\n014 0 | 0\n015 0 | 0\n========================================================================="},"ip":"0.0.0.0","ports":{"discovery":0,"listener":0}}}},{"node":{"config":{"private_key":"a5baeb4f2e35eedde63d573bbec157e61f0c0ba6ecc7b6cb6a42759bbc165e5b","id":"855667650e96c5ed2d9b0c82532ed1fb92f72b1ae926afafe09cf8f6e90e539aec5c4c2ab108f2c2a1ad7dd8b83ca92a98c550a1c9ed27e6632a7d2f6da4f970","name":"node05","services":["pss","bzz"]},"up":true,"info":{"id":"855667650e96c5ed2d9b0c82532ed1fb92f72b1ae926afafe09cf8f6e90e539aec5c4c2ab108f2c2a1ad7dd8b83ca92a98c550a1c9ed27e6632a7d2f6da4f970","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 52881f\npopulation: 20 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 a485 c8f9 daa2 | 121 fd2d (0) fed1 (0) f915 (0) f924 (0)\n001 6 2f9f 2a69 03f5 12b9 | 73 31ed (0) 32dd (0) 3345 (0) 34fc (0)\n002 2 67a2 72fa | 31 6ea5 (0) 6d21 (0) 6dbd (0) 6330 (0)\n003 2 4a81 4a82 | 17 458a (0) 46c5 (0) 47f9 (0) 4019 (0)\n004 1 5fd0 | 5 5c5d (0) 5f05 (0) 5fa8 (0) 5fab (0)\n005 3 57d5 5695 566e | 5 5571 (0) 5716 (0) 57d5 (0) 5695 (0)\n============ DEPTH: 6 ==========================================\n006 2 5110 5093 | 2 5110 (0) 5093 (0)\n007 0 | 0\n008 1 5261 | 1 5261 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"UogfH+C46QRKO8A17bvWNDucQdScDywsp5nC52RIm5E="},"ports":{"listener":0,"discovery":0},"ip":"0.0.0.0","listenAddr":"","name":"node05","enode":"enode://855667650e96c5ed2d9b0c82532ed1fb92f72b1ae926afafe09cf8f6e90e539aec5c4c2ab108f2c2a1ad7dd8b83ca92a98c550a1c9ed27e6632a7d2f6da4f970@0.0.0.0:0"}}},{"node":{"info":{"protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 2a69e3\npopulation: 22 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 e787 c8f9 | 121 e3c9 (0) e44b (0) e4c3 (0) e76a (0)\n001 2 4a81 5288 | 62 6ea5 (0) 6d21 (0) 6dbd (0) 6330 (0)\n002 2 0592 12b9 | 38 0f5e (0) 0f81 (0) 0eee (0) 0ea2 (0)\n003 3 3dca 3a4a 3af3 | 15 32dd (0) 3345 (0) 31ed (0) 34fc (0)\n004 4 259d 2374 2168 2013 | 9 2279 (0) 2374 (0) 211a (0) 2168 (0)\n005 4 2e4c 2f22 2fd8 2f9f | 5 2e9f (0) 2e4c (0) 2f22 (0) 2fd8 (0)\n006 3 29ff 29fd 290f | 3 29fd (0) 29ff (0) 290f (0)\n007 0 | 0\n============ DEPTH: 8 ==========================================\n008 1 2af0 | 1 2af0 (0)\n009 1 2a22 | 1 2a22 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"KmnjiX0w4MvptheaVeMOsTxliyhOHfz+TcoIppQ03zw="},"ports":{"discovery":0,"listener":0},"ip":"0.0.0.0","id":"57085f756f76644cdd2148524f2334d869ef0ab2fcbe7fb11f5d22bc1f5023165b11526ecc85ff9cbb88877386af9b148d7ef15a825b3a586d16c01bdfc86692","name":"node06","enode":"enode://57085f756f76644cdd2148524f2334d869ef0ab2fcbe7fb11f5d22bc1f5023165b11526ecc85ff9cbb88877386af9b148d7ef15a825b3a586d16c01bdfc86692@0.0.0.0:0","listenAddr":""},"up":true,"config":{"id":"57085f756f76644cdd2148524f2334d869ef0ab2fcbe7fb11f5d22bc1f5023165b11526ecc85ff9cbb88877386af9b148d7ef15a825b3a586d16c01bdfc86692","private_key":"1b7e31744236baa89eaadd57ec870b5415111685fda883490b5a0e1dbc321210","services":["pss","bzz"],"name":"node06"}}},{"node":{"info":{"enode":"enode://ea2921612b827e3c26328368bed9be7cbf1f2b2aecaf31863c9cdccd74c56b651d6eaceb8ac9609a6653488837ded310df91e53a74789ae75cb841e2aeaf96df@0.0.0.0:0","name":"node07","listenAddr":"","protocols":{"bzz":"ErmqCt30XHFOyV+pFSlMmX+dc+5NaseDLRjRlVTsSaU=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 12b9aa\npopulation: 24 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 c8f9 b45d 96b6 8ae6 | 121 f924 (0) f915 (0) fb93 (0) fa74 (0)\n001 3 5fd0 5093 5288 | 62 7a41 (0) 79ab (0) 79bd (0) 7829 (0)\n002 5 3af3 2374 2fd8 2f9f | 35 3345 (0) 32dd (0) 31ed (0) 3538 (0)\n003 1 0592 | 12 0f5e (0) 0f81 (0) 0eee (0) 0ea2 (0)\n004 5 1d94 193e 194a 1835 | 18 1a02 (0) 1a83 (0) 1b72 (0) 1b1e (0)\n005 4 1673 1566 15f6 14c8 | 5 1673 (0) 1566 (0) 15f6 (0) 1441 (0)\n006 0 | 0\n============ DEPTH: 7 ==========================================\n007 1 13d8 | 1 13d8 (0)\n008 1 123f | 1 123f (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"listener":0,"discovery":0},"ip":"0.0.0.0","id":"ea2921612b827e3c26328368bed9be7cbf1f2b2aecaf31863c9cdccd74c56b651d6eaceb8ac9609a6653488837ded310df91e53a74789ae75cb841e2aeaf96df"},"config":{"services":["pss","bzz"],"name":"node07","id":"ea2921612b827e3c26328368bed9be7cbf1f2b2aecaf31863c9cdccd74c56b651d6eaceb8ac9609a6653488837ded310df91e53a74789ae75cb841e2aeaf96df","private_key":"344f9ff7d68ca6a04e3141646044db06e5761248c64a01bb6cc2813fb7745ae4"},"up":true}},{"node":{"up":true,"config":{"services":["pss","bzz"],"name":"node08","id":"fd0123c7b96004067e98e463e273de5bc5402399ae70a95985b5f682e30d4f35d070deaf8c71d201e98c4324d832b95aab7535ad8a2658f66e3e0bb1202204e1","private_key":"869c03072d8108be18544c579cca53ffe17682e3898f44baff9cc37507fc62ed"},"info":{"listenAddr":"","name":"node08","enode":"enode://fd0123c7b96004067e98e463e273de5bc5402399ae70a95985b5f682e30d4f35d070deaf8c71d201e98c4324d832b95aab7535ad8a2658f66e3e0bb1202204e1@0.0.0.0:0","id":"fd0123c7b96004067e98e463e273de5bc5402399ae70a95985b5f682e30d4f35d070deaf8c71d201e98c4324d832b95aab7535ad8a2658f66e3e0bb1202204e1","ip":"0.0.0.0","protocols":{"bzz":"BZIEiuTmowAPNujhwOEyjCbA1LtjadbNhnoI2Efay54=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 059204\npopulation: 21 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 b45d b8a7 | 121 8163 (0) 8612 (0) 86f7 (0) 89ee (0)\n001 1 67a2 | 62 7fa4 (0) 7ffe (0) 7d45 (0) 7d94 (0)\n002 2 2f9f 2a69 | 35 3345 (0) 32dd (0) 31ed (0) 3538 (0)\n003 6 1b86 1835 193e 194a | 26 1a02 (0) 1a83 (0) 1b72 (0) 1b1e (0)\n004 4 0f5e 0f81 0eee 0ea2 | 4 0f5e (0) 0f81 (0) 0eee (0) 0ea2 (0)\n005 2 0210 03f5 | 3 004e (0) 0210 (0) 03f5 (0)\n006 1 06aa | 1 06aa (0)\n007 1 043f | 1 043f (0)\n008 0 | 0\n============ DEPTH: 9 ==========================================\n009 2 05ec 05e8 | 2 05ec (0) 05e8 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"discovery":0,"listener":0}}}},{"node":{"info":{"listenAddr":"","name":"node09","enode":"enode://545237d8463b75fd2e9bbfbffb35c5b78b4abbc85f6bfbd56976789012dd9a62ca1f866bf37bb33618e026aab764adb9ced5e00cd415562f69992f74c795083f@0.0.0.0:0","id":"545237d8463b75fd2e9bbfbffb35c5b78b4abbc85f6bfbd56976789012dd9a62ca1f866bf37bb33618e026aab764adb9ced5e00cd415562f69992f74c795083f","protocols":{"bzz":"A/Xxvlwa41RpMzpbCGIjcvZe+PIzdGr95W0mR8UnNjA=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 03f5f1\npopulation: 21 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 e787 b5c7 b8a7 | 121 9c0c (0) 9c01 (0) 9fee (0) 9eec (0)\n001 2 5288 5093 | 62 7ffe (0) 7fa4 (0) 7d45 (0) 7d94 (0)\n002 1 259d | 35 275c (0) 265d (0) 2454 (0) 259d (0)\n003 5 1b86 193e 14c8 1566 | 26 18f9 (0) 185a (0) 1835 (0) 193e (0)\n004 4 0f5e 0f81 0eee 0ea2 | 4 0f5e (0) 0f81 (0) 0eee (0) 0ea2 (0)\n005 4 06aa 05ec 05e8 0592 | 5 06aa (0) 043f (0) 05ec (0) 05e8 (0)\n============ DEPTH: 6 ==========================================\n006 1 004e | 1 004e (0)\n007 1 0210 | 1 0210 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"listener":0,"discovery":0},"ip":"0.0.0.0"},"up":true,"config":{"name":"node09","services":["pss","bzz"],"private_key":"1fe668699f54728124bbf993215de07682f072d145dd8acc428f04abd4a46f08","id":"545237d8463b75fd2e9bbfbffb35c5b78b4abbc85f6bfbd56976789012dd9a62ca1f866bf37bb33618e026aab764adb9ced5e00cd415562f69992f74c795083f"}}},{"node":{"up":true,"config":{"private_key":"a3af1294d727198fb3282659a35ae5b27f4b23b28d76e528809b68a6263fd673","id":"6d0a09235ba0b0428938abf0e0782ac0ecf5697ef862888719a34fc956517aeef89d5e5f76d12e10067fee5bac8781dc10400eeb35c2393b9382b2a4f68f7939","name":"node10","services":["pss","bzz"]},"info":{"name":"node10","enode":"enode://6d0a09235ba0b0428938abf0e0782ac0ecf5697ef862888719a34fc956517aeef89d5e5f76d12e10067fee5bac8781dc10400eeb35c2393b9382b2a4f68f7939@0.0.0.0:0","listenAddr":"","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 0ea201\npopulation: 16 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 b8a7 b5c7 | 121 9c01 (0) 9c0c (0) 9fee (0) 9eec (0)\n001 2 4a81 72fa | 62 458a (0) 47f9 (0) 46c5 (0) 4019 (0)\n002 1 3af3 | 35 275c (0) 265d (0) 2454 (0) 259d (0)\n003 3 193e 1c98 14c8 | 26 1a02 (0) 1a83 (0) 1b72 (0) 1b1e (0)\n004 5 06aa 05e8 0592 0210 | 8 06aa (0) 043f (0) 05ec (0) 05e8 (0)\n005 0 | 0\n006 0 | 0\n============ DEPTH: 7 ==========================================\n007 2 0f5e 0f81 | 2 0f5e (0) 0f81 (0)\n008 0 | 0\n009 1 0eee | 1 0eee (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"DqIBUVhnxnk8vkg1DyCeaazTgpubFrYBbZZdhPtjecU="},"ports":{"listener":0,"discovery":0},"ip":"0.0.0.0","id":"6d0a09235ba0b0428938abf0e0782ac0ecf5697ef862888719a34fc956517aeef89d5e5f76d12e10067fee5bac8781dc10400eeb35c2393b9382b2a4f68f7939"}}},{"node":{"info":{"enode":"enode://37399617d62153bc471f3bf21c92385bc8602c80ffa0c71da8aebae595a9859cfd56257aae60ad30ef3ec4d07dee90623cce63749c8c3233c0aa0d17f9e89afe@0.0.0.0:0","name":"node11","listenAddr":"","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 72fae9\npopulation: 25 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 daa2 8ae6 | 121 9fee (0) 9eec (0) 9c0c (0) 9c01 (0)\n001 5 3af3 2374 2f9f 14c8 | 73 2279 (0) 2374 (0) 211a (0) 2168 (0)\n002 4 4a82 5fd0 5093 5288 | 31 4019 (0) 43af (0) 42c0 (0) 42d4 (0)\n003 2 6143 67a2 | 11 6ea5 (0) 6d21 (0) 6dbd (0) 6330 (0)\n004 7 7fa4 7d94 7de7 7a41 | 12 7a41 (0) 79ab (0) 79bd (0) 7829 (0)\n005 2 759e 7471 | 4 77ec (0) 759e (0) 7406 (0) 7471 (0)\n006 0 | 0\n007 1 7307 | 1 7307 (0)\n008 0 | 0\n============ DEPTH: 9 ==========================================\n009 2 7294 72ac | 2 7294 (0) 72ac (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"cvrpaeKIj3zvpApUTqZrjC/RYbGvPqHwuKcBKjYYiqE="},"ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"id":"37399617d62153bc471f3bf21c92385bc8602c80ffa0c71da8aebae595a9859cfd56257aae60ad30ef3ec4d07dee90623cce63749c8c3233c0aa0d17f9e89afe"},"up":true,"config":{"name":"node11","services":["pss","bzz"],"private_key":"f7ad4635d864376fa4536bf23df764278d30805556cbf13e794e0ebacf389172","id":"37399617d62153bc471f3bf21c92385bc8602c80ffa0c71da8aebae595a9859cfd56257aae60ad30ef3ec4d07dee90623cce63749c8c3233c0aa0d17f9e89afe"}}},{"node":{"config":{"name":"node12","services":["pss","bzz"],"private_key":"237183f9e7834a03859c43be2a49bb8e4f1c9c7a5c334958f74d4ed36dfbd5a7","id":"37adbfdf66163e45f433d78f63210163fdacf4688ad90d73bed07975be017c43cddf2a26a0dee8b11d78f294b63d4875b6be15f42f10817bd3d77b342919a11e"},"up":true,"info":{"protocols":{"bzz":"FMgfsvuPpaa0cog1arSGASBG0JlZue9IFKCdw/rLSFM=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 14c81f\npopulation: 18 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 c8f9 | 121 9c01 (0) 9c0c (0) 9fee (0) 9eec (0)\n001 4 5093 5fd0 4a82 72fa | 62 458a (0) 47f9 (0) 46c5 (0) 43af (0)\n002 2 2fd8 3af3 | 35 2279 (0) 2374 (0) 211a (0) 2168 (0)\n003 2 03f5 0ea2 | 12 0f5e (0) 0f81 (0) 0eee (0) 0ea2 (0)\n004 3 194a 1835 1d94 | 18 18f9 (0) 185a (0) 1835 (0) 193e (0)\n005 2 13d8 12b9 | 3 13d8 (0) 123f (0) 12b9 (0)\n006 1 1673 | 1 1673 (0)\n============ DEPTH: 7 ==========================================\n007 2 1566 15f6 | 2 1566 (0) 15f6 (0)\n008 1 1441 | 1 1441 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"discovery":0,"listener":0},"ip":"0.0.0.0","id":"37adbfdf66163e45f433d78f63210163fdacf4688ad90d73bed07975be017c43cddf2a26a0dee8b11d78f294b63d4875b6be15f42f10817bd3d77b342919a11e","enode":"enode://37adbfdf66163e45f433d78f63210163fdacf4688ad90d73bed07975be017c43cddf2a26a0dee8b11d78f294b63d4875b6be15f42f10817bd3d77b342919a11e@0.0.0.0:0","name":"node12","listenAddr":""}}},{"node":{"up":true,"config":{"name":"node13","services":["pss","bzz"],"private_key":"7f7c361b6989c77419ac69848c9a4b06255aeb0f6115454566cde4ca544af085","id":"2c976b6007cda135444233c7bd03d22ac9756710b746c36bc032e7fdd42f2ffb89ca5f5e754ff96b8f3cbc474e346287e5b8531d9f98fd63c426c632872220af"},"info":{"name":"node13","enode":"enode://2c976b6007cda135444233c7bd03d22ac9756710b746c36bc032e7fdd42f2ffb89ca5f5e754ff96b8f3cbc474e346287e5b8531d9f98fd63c426c632872220af@0.0.0.0:0","listenAddr":"","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: c8f9cc\npopulation: 21 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 5 5093 5288 2a69 12b9 | 135 6ea5 (0) 6d21 (0) 6dbd (0) 6330 (0)\n001 4 8ae6 b8a7 b45d a485 | 56 9c01 (0) 9c0c (0) 9fee (0) 9eec (0)\n002 1 ed13 | 29 fd2d (0) fed1 (0) f915 (0) f924 (0)\n003 2 d6f3 dc3e | 18 d3fd (0) d3d2 (0) d564 (0) d7ab (0)\n004 2 c15d c484 | 9 c3f3 (0) c0d1 (0) c15d (0) c63e (0)\n005 1 ceee | 1 ceee (0)\n006 2 ca81 cb69 | 2 ca81 (0) cb69 (0)\n007 2 c9f3 c98d | 3 c9f3 (0) c99c (1) c98d (0)\n008 0 | 0\n============ DEPTH: 9 ==========================================\n009 1 c883 | 1 c883 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 1 c8fe | 1 c8fe (0)\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"yPnMH7Pshx4s4DFX+Qz+HDsBpQPDCv3HHQ6LJ7o6jhk="},"ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"id":"2c976b6007cda135444233c7bd03d22ac9756710b746c36bc032e7fdd42f2ffb89ca5f5e754ff96b8f3cbc474e346287e5b8531d9f98fd63c426c632872220af"}}},{"node":{"info":{"id":"c6ad9b9de5cdbe28540f4eb7c66fb37f6d4295e6e60c6de54e2a45c1970b8e0047558e986bbd10e9e86c8bb0407846fac4823e4570e8a1486fc4bf55cb4a0986","protocols":{"bzz":"pIXbbsGSmq9pWoQpT1KQWqYCWElU6e9xtOGPe4R9ox0=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: a485db\npopulation: 17 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 5288 | 135 7a41 (0) 79ab (0) 79bd (0) 7829 (0)\n001 2 ed13 c8f9 | 65 fd2d (0) fed1 (0) f924 (0) f915 (0)\n002 1 96b6 | 26 9c0c (0) 9c01 (0) 9fee (0) 9eec (0)\n003 5 b8a7 b310 b5c7 b463 | 14 be0a (0) bfec (0) bf5a (0) bc08 (0)\n004 5 aa88 a80b aca1 af30 | 12 abfa (0) aa50 (0) aa88 (0) a80b (0)\n005 1 a033 | 1 a033 (0)\n============ DEPTH: 6 ==========================================\n006 2 a749 a672 | 2 a672 (0) a749 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","name":"node14","enode":"enode://c6ad9b9de5cdbe28540f4eb7c66fb37f6d4295e6e60c6de54e2a45c1970b8e0047558e986bbd10e9e86c8bb0407846fac4823e4570e8a1486fc4bf55cb4a0986@0.0.0.0:0"},"up":true,"config":{"name":"node14","services":["pss","bzz"],"private_key":"00133d03c85e03bcd54ddefc03d9060009ea78ee5ba1f6f335111f47ab8f433f","id":"c6ad9b9de5cdbe28540f4eb7c66fb37f6d4295e6e60c6de54e2a45c1970b8e0047558e986bbd10e9e86c8bb0407846fac4823e4570e8a1486fc4bf55cb4a0986"}}},{"node":{"info":{"ports":{"listener":0,"discovery":0},"protocols":{"bzz":"7RNItANwBLYb1Nb5vhZIES+DWUOjuZe5GskxMBMR4Ac=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: ed1348\npopulation: 20 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 4a82 | 135 275c (0) 265d (0) 2454 (0) 259d (0)\n001 3 b5c7 b45d a485 | 56 9c0c (0) 9c01 (0) 9fee (0) 9eec (0)\n002 4 daa2 c484 cb69 c8f9 | 36 d822 (0) d8b0 (0) dae3 (0) daa2 (0)\n003 4 f4ee f5cc f048 f156 | 17 fd2d (0) fed1 (0) f924 (0) f915 (0)\n004 4 e649 e67d e787 e44b | 7 e3c9 (0) e4c3 (0) e44b (0) e76a (0)\n005 1 e839 | 1 e839 (0)\n006 0 | 0\n007 1 ecd2 | 1 ecd2 (0)\n============ DEPTH: 8 ==========================================\n008 1 edca | 1 edca (0)\n009 1 ed65 | 1 ed65 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ip":"0.0.0.0","id":"9e21f5d4cfb389ac3ad43497689878bd245a89c587a8637d832b1e355ba244f4c83e6499bc7936e6d35645db25910ecd89b9af9b6b2f0c7cc4d7c6114328d7bf","name":"node15","enode":"enode://9e21f5d4cfb389ac3ad43497689878bd245a89c587a8637d832b1e355ba244f4c83e6499bc7936e6d35645db25910ecd89b9af9b6b2f0c7cc4d7c6114328d7bf@0.0.0.0:0","listenAddr":""},"up":true,"config":{"private_key":"ee3f0e3cca3720aa0727efa92a11ea9252c7fe72fe64c8814de2accbb91d049d","id":"9e21f5d4cfb389ac3ad43497689878bd245a89c587a8637d832b1e355ba244f4c83e6499bc7936e6d35645db25910ecd89b9af9b6b2f0c7cc4d7c6114328d7bf","name":"node15","services":["pss","bzz"]}}},{"node":{"config":{"id":"1489ad735e1256900e4733707f8b78f1d853742a8f9b2d0c1c89651c60e7ee9d266afba5b4c1ed3f9cee05a1d2b2bba35dadb5b08973a93fd70dfb9e367339bd","private_key":"470d12a7459f9fa9f1adf18e94b60340c5c442eadb1329fa871073e64d6bd7aa","services":["pss","bzz"],"name":"node16"},"up":true,"info":{"ip":"0.0.0.0","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 4a8285\npopulation: 21 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 b45d ed13 | 121 9c01 (0) 9c0c (0) 9fee (0) 9eec (0)\n001 5 3dca 3af3 2374 15f6 | 73 275c (0) 265d (0) 2454 (0) 259d (0)\n002 2 67a2 72fa | 31 6ea5 (0) 6d21 (0) 6dbd (0) 6330 (0)\n003 5 5fd0 5695 566e 5093 | 14 5c5d (0) 5f05 (0) 5fa8 (0) 5fab (0)\n004 1 4019 | 7 458a (0) 47f9 (0) 46c5 (0) 43af (0)\n005 1 4cf6 | 4 4fd6 (0) 4f90 (0) 4d44 (0) 4cf6 (0)\n006 1 487e | 1 487e (0)\n007 1 4b00 | 1 4b00 (0)\n008 1 4a67 | 1 4a67 (0)\n============ DEPTH: 9 ==========================================\n009 1 4af7 | 1 4af7 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 1 4a81 | 1 4a81 (0)\n015 0 | 0\n=========================================================================","bzz":"SoKFI3Mcr0f5qi36IPioiV6aZWKzoDRXRjmiKacztKY="},"ports":{"listener":0,"discovery":0},"id":"1489ad735e1256900e4733707f8b78f1d853742a8f9b2d0c1c89651c60e7ee9d266afba5b4c1ed3f9cee05a1d2b2bba35dadb5b08973a93fd70dfb9e367339bd","name":"node16","enode":"enode://1489ad735e1256900e4733707f8b78f1d853742a8f9b2d0c1c89651c60e7ee9d266afba5b4c1ed3f9cee05a1d2b2bba35dadb5b08973a93fd70dfb9e367339bd@0.0.0.0:0","listenAddr":""}}},{"node":{"up":true,"config":{"name":"node17","services":["pss","bzz"],"private_key":"3450c9c68339a76f1f75fb1f770914dac1cfc5e0cb23d6fd703480beb3ddfd4a","id":"02fdbcb00f20a3f6e894900d798fcb0aca9e21f5b107924c0999eb396220f16dee99fc80ccba796e66e69dcb9ce278b7e0e4539c7a7cd0fbc1037bf8e56c1e67"},"info":{"ip":"0.0.0.0","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: b45d1a\npopulation: 18 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 12b9 0592 3af3 4a82 | 135 0f5e (0) 0f81 (0) 0eee (0) 0ea2 (0)\n001 3 ed13 cb69 c8f9 | 65 fd2d (0) fed1 (0) f915 (0) f924 (0)\n002 2 8c61 8ae6 | 26 9c01 (0) 9c0c (0) 9fee (0) 9eec (0)\n003 1 a485 | 16 abfa (0) aa50 (0) aa88 (0) a80b (0)\n004 2 bc08 b8a7 | 6 be0a (0) bfec (0) bf5a (0) bc08 (0)\n005 1 b310 | 1 b310 (0)\n006 2 b60d b710 | 3 b60d (0) b79f (0) b710 (0)\n007 1 b5c7 | 1 b5c7 (0)\n============ DEPTH: 8 ==========================================\n008 1 b4c7 | 1 b4c7 (0)\n009 0 | 0\n010 1 b463 | 1 b463 (0)\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"tF0a7pQOXSxx2yLir76QjVln5Df7tb0FHt6obqSsnTA="},"ports":{"listener":0,"discovery":0},"id":"02fdbcb00f20a3f6e894900d798fcb0aca9e21f5b107924c0999eb396220f16dee99fc80ccba796e66e69dcb9ce278b7e0e4539c7a7cd0fbc1037bf8e56c1e67","enode":"enode://02fdbcb00f20a3f6e894900d798fcb0aca9e21f5b107924c0999eb396220f16dee99fc80ccba796e66e69dcb9ce278b7e0e4539c7a7cd0fbc1037bf8e56c1e67@0.0.0.0:0","name":"node17","listenAddr":""}}},{"node":{"config":{"id":"f4cdaeb513aa98f8868d8eb3a1d12c07367725928a1bc7d6ca4b583788e111a955463037ec7867260511896d97dfbf096aa77ee8a7d9ea1c06cad4a92c45108d","private_key":"1df10df7cb050098e9713c3773a47962a6cfea944b53b12fd84563c98dc46e7a","services":["pss","bzz"],"name":"node18"},"up":true,"info":{"protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 3af3bb\npopulation: 21 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 cb69 b5c7 b45d | 121 fed1 (0) fd2d (0) f924 (0) f915 (0)\n001 2 4a82 72fa | 62 6ea5 (0) 6d21 (0) 6dbd (0) 6544 (0)\n002 4 0ea2 1d94 12b9 14c8 | 38 0f5e (0) 0f81 (0) 0eee (0) 0ea2 (0)\n003 5 2f9f 2a69 259d 2013 | 20 2e9f (0) 2e4c (0) 2f22 (0) 2f9f (0)\n004 1 3648 | 6 3345 (0) 32dd (0) 31ed (0) 34fc (0)\n005 3 3f3e 3e44 3dca | 5 3f3e (0) 3e85 (0) 3e44 (0) 3d6b (0)\n============ DEPTH: 6 ==========================================\n006 2 388d 396b | 2 388d (0) 396b (0)\n007 0 | 0\n008 1 3a4a | 1 3a4a (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"OvO7bENDoZ48D5qJaXzXCjx5xkseQK+lmxiMVVPu1Wc="},"ports":{"listener":0,"discovery":0},"ip":"0.0.0.0","id":"f4cdaeb513aa98f8868d8eb3a1d12c07367725928a1bc7d6ca4b583788e111a955463037ec7867260511896d97dfbf096aa77ee8a7d9ea1c06cad4a92c45108d","enode":"enode://f4cdaeb513aa98f8868d8eb3a1d12c07367725928a1bc7d6ca4b583788e111a955463037ec7867260511896d97dfbf096aa77ee8a7d9ea1c06cad4a92c45108d@0.0.0.0:0","name":"node18","listenAddr":""}}},{"node":{"info":{"name":"node19","enode":"enode://1c080e90760dfcee08ade6e4ea3b275ff3c6882f3b44b7f3a73d70bcc816fc63ce0b6138f810d17d96ed387076f9bbb6dbb2ef6dc4d6ba6542c1f587b7602a12@0.0.0.0:0","listenAddr":"","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: cb69f6\npopulation: 20 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 3af3 2374 | 135 604c (0) 6143 (0) 6330 (0) 6544 (0)\n001 3 b45d b5c7 8ae6 | 56 a80b (0) abfa (0) aa50 (0) aa88 (0)\n002 2 f156 ed13 | 29 e3c9 (0) e4c3 (0) e44b (0) e76a (0)\n003 2 d6f3 dc3e | 18 d3fd (0) d3d2 (0) d564 (0) d7ab (0)\n004 3 c15d c770 c484 | 9 c3f3 (0) c0d1 (0) c15d (0) c63e (0)\n005 1 ceee | 1 ceee (0)\n============ DEPTH: 6 ==========================================\n006 6 c99c c98d c9f3 c883 | 6 c9f3 (0) c99c (0) c98d (0) c883 (0)\n007 1 ca81 | 1 ca81 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"y2n2c6VKdd4wDR0auYnKoEV5UEy8r3jwO8GSyVeOxaA="},"ip":"0.0.0.0","ports":{"listener":0,"discovery":0},"id":"1c080e90760dfcee08ade6e4ea3b275ff3c6882f3b44b7f3a73d70bcc816fc63ce0b6138f810d17d96ed387076f9bbb6dbb2ef6dc4d6ba6542c1f587b7602a12"},"up":true,"config":{"name":"node19","services":["pss","bzz"],"private_key":"e699fe1e14d46a5a72d5696e397df71ac0d17abf136dc84d850b658e56881c75","id":"1c080e90760dfcee08ade6e4ea3b275ff3c6882f3b44b7f3a73d70bcc816fc63ce0b6138f810d17d96ed387076f9bbb6dbb2ef6dc4d6ba6542c1f587b7602a12"}}},{"node":{"info":{"listenAddr":"","enode":"enode://85b6404a76b4762156c8ddd2f312763dfe19b315d914533844cf229301880c57ffeadc0eb5f4a8d542e1d9fc961dfb5a572d2101172b1a0fc238ced05ba49ec1@0.0.0.0:0","name":"node20","id":"85b6404a76b4762156c8ddd2f312763dfe19b315d914533844cf229301880c57ffeadc0eb5f4a8d542e1d9fc961dfb5a572d2101172b1a0fc238ced05ba49ec1","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 237459\npopulation: 19 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 cb69 | 121 a80b (0) abfa (0) aa50 (0) aa88 (0)\n001 4 72fa 67a2 4a82 4a81 | 62 6ea5 (0) 6d21 (0) 6dbd (0) 6330 (0)\n002 4 0f81 12b9 1566 15f6 | 38 0f5e (0) 0f81 (0) 0eee (0) 0ea2 (0)\n003 2 3dca 3af3 | 15 3345 (0) 32dd (0) 31ed (0) 34fc (0)\n004 1 2a69 | 11 2e9f (0) 2e4c (0) 2f22 (0) 2f9f (0)\n005 3 265d 2454 259d | 4 275c (0) 265d (0) 2454 (0) 259d (0)\n============ DEPTH: 6 ==========================================\n006 3 211a 2168 2013 | 3 211a (0) 2168 (0) 2013 (0)\n007 1 2279 | 1 2279 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"I3RZujcUHxizzUD17Jza9nifuHqkUR1In92YqWDvKIM="},"ports":{"discovery":0,"listener":0},"ip":"0.0.0.0"},"config":{"private_key":"0974ab51554372614954b68ffb0fdde4a82efdc0bf4e6f802dbc3728cb4b5e47","id":"85b6404a76b4762156c8ddd2f312763dfe19b315d914533844cf229301880c57ffeadc0eb5f4a8d542e1d9fc961dfb5a572d2101172b1a0fc238ced05ba49ec1","name":"node20","services":["pss","bzz"]},"up":true}},{"node":{"info":{"enode":"enode://6c95c653e15bb99d32656f35790400134cd7188e063f878e19cb9118eb469ae0362dc45255f2a1eae31520be01d42b5bc5bbebf03d644c9f206ca79cb33a01ad@0.0.0.0:0","name":"node21","listenAddr":"","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 15f6bb\npopulation: 17 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 c484 | 121 abfa (0) aa50 (0) aa88 (0) a80b (0)\n001 2 5093 4a82 | 62 6ea5 (0) 6d21 (0) 6dbd (0) 6544 (0)\n002 2 2fd8 2374 | 35 3345 (0) 32dd (0) 31ed (0) 34fc (0)\n003 1 03f5 | 12 0f5e (0) 0f81 (0) 0eee (0) 0ea2 (0)\n004 5 1c98 1d94 193e 194a | 18 1e42 (0) 1e44 (0) 1c98 (0) 1d5f (0)\n005 2 13d8 12b9 | 3 13d8 (0) 123f (0) 12b9 (0)\n006 1 1673 | 1 1673 (0)\n============ DEPTH: 7 ==========================================\n007 2 1441 14c8 | 2 1441 (0) 14c8 (0)\n008 1 1566 | 1 1566 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"Ffa7BkDDrIro7PENDUbMc5u2+GsMDPcGEDqtnzeFIZs="},"ports":{"discovery":0,"listener":0},"ip":"0.0.0.0","id":"6c95c653e15bb99d32656f35790400134cd7188e063f878e19cb9118eb469ae0362dc45255f2a1eae31520be01d42b5bc5bbebf03d644c9f206ca79cb33a01ad"},"config":{"services":["pss","bzz"],"name":"node21","id":"6c95c653e15bb99d32656f35790400134cd7188e063f878e19cb9118eb469ae0362dc45255f2a1eae31520be01d42b5bc5bbebf03d644c9f206ca79cb33a01ad","private_key":"14ce7db5594270c24ed48fd5881d6f02b9cc6267731612c5117e4d273d3920ca"},"up":true}},{"node":{"info":{"enode":"enode://313a131ecb7d68e127d0fec8bb4a2e586886203c3d07857a93e7a39bb831703184d9ae28ba9ef3d986c2dae1a24f4f5bfa47cfc35f74f5512a126836364d7736@0.0.0.0:0","name":"node22","listenAddr":"","ip":"0.0.0.0","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: c4844b\npopulation: 19 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 15f6 | 135 6ea5 (0) 6d21 (0) 6dbd (0) 6544 (0)\n001 2 b5c7 8ae6 | 56 abfa (0) aa50 (0) aa88 (0) a80b (0)\n002 2 f156 ed13 | 29 e3c9 (0) e4c3 (0) e44b (0) e76a (0)\n003 2 d6f3 dc3e | 18 d3fd (0) d3d2 (0) d564 (0) d7ab (0)\n004 4 c99c c9f3 c8f9 cb69 | 9 ceee (0) c9f3 (0) c99c (0) c98d (0)\n005 3 c3f3 c0d1 c15d | 3 c3f3 (0) c0d1 (0) c15d (0)\n============ DEPTH: 6 ==========================================\n006 4 c64f c63e c723 c770 | 4 c63e (0) c64f (0) c723 (0) c770 (0)\n007 0 | 0\n008 1 c463 | 1 c463 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"xIRLgEbRxH9pnuHCMtlFgpEF1Fryb7pyLOTQqTfJljE="},"ports":{"listener":0,"discovery":0},"id":"313a131ecb7d68e127d0fec8bb4a2e586886203c3d07857a93e7a39bb831703184d9ae28ba9ef3d986c2dae1a24f4f5bfa47cfc35f74f5512a126836364d7736"},"up":true,"config":{"private_key":"32fa52ca7b60e6953e97635659e4a5153688636594be7f560fc5f8468fdf7022","id":"313a131ecb7d68e127d0fec8bb4a2e586886203c3d07857a93e7a39bb831703184d9ae28ba9ef3d986c2dae1a24f4f5bfa47cfc35f74f5512a126836364d7736","name":"node22","services":["pss","bzz"]}}},{"node":{"up":true,"config":{"name":"node23","services":["pss","bzz"],"private_key":"d28563bbfb6db23928a66e837cdfa794230537066eeb93063ebeff3f531b12ca","id":"29acdd4c1233441bd40f98e245ecc9de94de6f9d0ab7c1a9923d833a2c8e6c1bd26d792686fec762b31fe28bbdd7aa04c9a594d997d08c133bb24cb2d877595a"},"info":{"id":"29acdd4c1233441bd40f98e245ecc9de94de6f9d0ab7c1a9923d833a2c8e6c1bd26d792686fec762b31fe28bbdd7aa04c9a594d997d08c133bb24cb2d877595a","protocols":{"bzz":"iuaj0MxmVmSu01rNOW7xj2Qq/SseHiOBcXS5a+3yZ5M=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 8ae6a3\npopulation: 22 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 12b9 72fa | 135 458a (0) 47f9 (0) 46c5 (0) 43af (0)\n001 4 dc3e c8f9 cb69 c484 | 65 e3c9 (0) e4c3 (0) e44b (0) e76a (0)\n002 5 bc08 b8a7 b310 b45d | 30 abfa (0) aa50 (0) aa88 (0) a80b (0)\n003 2 9a82 96b6 | 16 9c01 (0) 9c0c (0) 9fee (0) 9eec (0)\n004 3 8612 86f7 8163 | 3 8612 (0) 86f7 (0) 8163 (0)\n005 2 8c89 8c61 | 2 8c89 (0) 8c61 (0)\n============ DEPTH: 6 ==========================================\n006 3 89ee 88da 8874 | 3 89ee (0) 88da (0) 8874 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 1 8ac8 | 1 8ac8 (0)\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"discovery":0,"listener":0},"ip":"0.0.0.0","listenAddr":"","enode":"enode://29acdd4c1233441bd40f98e245ecc9de94de6f9d0ab7c1a9923d833a2c8e6c1bd26d792686fec762b31fe28bbdd7aa04c9a594d997d08c133bb24cb2d877595a@0.0.0.0:0","name":"node23"}}},{"node":{"info":{"id":"1e3a2f2491b6acb07a9549d9929d150479a0313c926b0e236237bd541303da4b563a855016a90ab50e59d94803ad566798570fa981464c94c04a4a4a94fbc607","ip":"0.0.0.0","protocols":{"bzz":"tcdkopzRQqy9g7dJiefSIy7rJBO3TJmtV2no577FaPY=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: b5c764\npopulation: 25 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 3af3 1c98 0ea2 03f5 | 135 6ea5 (0) 6d21 (0) 6dbd (0) 6544 (0)\n001 6 e67d ecd2 ed13 f156 | 65 e3c9 (0) e4c3 (0) e44b (0) e76a (0)\n002 2 8c61 8ae6 | 26 9c01 (0) 9c0c (0) 9fee (0) 9eec (0)\n003 2 a749 a485 | 16 abfa (0) aa50 (0) aa88 (0) a80b (0)\n004 4 bc08 bf5a baf3 b8a7 | 6 be0a (0) bfec (0) bf5a (0) bc08 (0)\n005 1 b310 | 1 b310 (0)\n006 3 b60d b79f b710 | 3 b60d (0) b79f (0) b710 (0)\n============ DEPTH: 7 ==========================================\n007 3 b4c7 b463 b45d | 3 b4c7 (0) b463 (0) b45d (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"listener":0,"discovery":0},"listenAddr":"","enode":"enode://1e3a2f2491b6acb07a9549d9929d150479a0313c926b0e236237bd541303da4b563a855016a90ab50e59d94803ad566798570fa981464c94c04a4a4a94fbc607@0.0.0.0:0","name":"node24"},"config":{"private_key":"137533f5c2f9257d2a60c22d205407f3cc14c52ec60fc34666b05dcb935178c7","id":"1e3a2f2491b6acb07a9549d9929d150479a0313c926b0e236237bd541303da4b563a855016a90ab50e59d94803ad566798570fa981464c94c04a4a4a94fbc607","name":"node24","services":["pss","bzz"]},"up":true}},{"node":{"up":true,"config":{"private_key":"1dbab5393fba98797db2a32f7d2ee6ad019bbd9e26ee051313e566bb1e21a1b4","id":"5982e7dfd39c527851f6ea6430b70e654d95df5ec4401ca1d8dbd1034cf7a65d1126d60b36ebbd396c9ca32e6e8515f34f9dc0a8d2980afe4aa181c8bf68437e","name":"node25","services":["pss","bzz"]},"info":{"name":"node25","enode":"enode://5982e7dfd39c527851f6ea6430b70e654d95df5ec4401ca1d8dbd1034cf7a65d1126d60b36ebbd396c9ca32e6e8515f34f9dc0a8d2980afe4aa181c8bf68437e@0.0.0.0:0","listenAddr":"","ports":{"discovery":0,"listener":0},"protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 1c982d\npopulation: 22 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 5 8c61 b5c7 f156 dc3e | 121 9c0c (0) 9c01 (0) 9eec (0) 9fee (0)\n001 1 7471 | 62 6ea5 (0) 6d21 (0) 6dbd (0) 6544 (0)\n002 1 290f | 35 32dd (0) 3345 (0) 31ed (0) 34fc (0)\n003 2 05e8 0ea2 | 12 06aa (0) 043f (0) 05ec (0) 05e8 (0)\n004 2 13d8 15f6 | 8 13d8 (0) 123f (0) 12b9 (0) 1673 (0)\n005 4 1835 194a 1a83 1b86 | 10 18f9 (0) 185a (0) 1835 (0) 193e (0)\n006 2 1e42 1e44 | 2 1e42 (0) 1e44 (0)\n============ DEPTH: 7 ==========================================\n007 5 1d5f 1d07 1da3 1d93 | 5 1d5f (0) 1d07 (0) 1da3 (0) 1d93 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"HJgtiGy6x+asXnhqJ60vi9QpCPypQ1jNKDisvCC1/TE="},"ip":"0.0.0.0","id":"5982e7dfd39c527851f6ea6430b70e654d95df5ec4401ca1d8dbd1034cf7a65d1126d60b36ebbd396c9ca32e6e8515f34f9dc0a8d2980afe4aa181c8bf68437e"}}},{"node":{"up":true,"config":{"name":"node26","services":["pss","bzz"],"private_key":"87a7b7028ee1140af69055fb641d23473c44f238544e3cc23e2909a959d1e091","id":"8e8614a4c2ee2b1a3fa5ace0ca353cff36b3de3308ccf53665b8b56f8e2456a8a65f3846d786dccd68b1bfcefdd170ea5f8edb481800b1ce72d9fce2added7f0"},"info":{"listenAddr":"","enode":"enode://8e8614a4c2ee2b1a3fa5ace0ca353cff36b3de3308ccf53665b8b56f8e2456a8a65f3846d786dccd68b1bfcefdd170ea5f8edb481800b1ce72d9fce2added7f0@0.0.0.0:0","name":"node26","id":"8e8614a4c2ee2b1a3fa5ace0ca353cff36b3de3308ccf53665b8b56f8e2456a8a65f3846d786dccd68b1bfcefdd170ea5f8edb481800b1ce72d9fce2added7f0","protocols":{"bzz":"1vN1VenzWj7zuLTVwYzwcC7ZnByLWwqFVN7dy+VCuIw=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: d6f375\npopulation: 19 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 7471 1c98 | 135 6ea5 (0) 6d21 (0) 6dbd (0) 6544 (0)\n001 1 8c61 | 56 9c0c (0) 9c01 (0) 9fee (0) 9eec (0)\n002 3 e67d edca f156 | 29 e3c9 (0) e4c3 (0) e44b (0) e76a (0)\n003 4 c15d c484 c8f9 cb69 | 18 ceee (0) c99c (0) c98d (0) c9f3 (0)\n004 3 dae3 daa2 dc3e | 11 d822 (0) d8b0 (0) dae3 (0) daa2 (0)\n005 2 d3fd d3d2 | 2 d3fd (0) d3d2 (0)\n006 1 d564 | 1 d564 (0)\n007 1 d7ab | 1 d7ab (0)\n008 0 | 0\n============ DEPTH: 9 ==========================================\n009 1 d68f | 1 d68f (0)\n010 1 d6d2 | 1 d6d2 (0)\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ip":"0.0.0.0","ports":{"listener":0,"discovery":0}}}},{"node":{"up":true,"config":{"services":["pss","bzz"],"name":"node27","id":"43086ff7ffd3c7bdec77bd288f41f1ee0ce21bd3f60a5df8931e2af6e7af5ef0fad432d29625491935d11567944351fc7867c807ebd12dd2c21c9e620ae0f85c","private_key":"102d3a405cf636abf7d0b4e4a1fc0a698dc0d4033c288762ce9cc975b91db032"},"info":{"protocols":{"bzz":"3D7GUpzsGXCUA+Rz1FRroH96qq7FvnywYYJGpMBFiUQ=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: dc3ec6\npopulation: 20 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 1c98 290f 7471 | 135 06aa (0) 043f (0) 05e8 (0) 05ec (0)\n001 1 8ae6 | 56 9c0c (0) 9c01 (0) 9fee (0) 9eec (0)\n002 1 f156 | 29 e3c9 (0) e4c3 (0) e44b (0) e76a (0)\n003 3 cb69 c8f9 c484 | 18 ceee (0) c9f3 (0) c99c (0) c98d (0)\n004 4 d3d2 d7ab d68f d6f3 | 7 d3fd (0) d3d2 (0) d564 (0) d7ab (0)\n005 3 d8b0 dae3 daa2 | 4 d822 (0) d8b0 (0) dae3 (0) daa2 (0)\n006 3 def4 de82 df5e | 4 def4 (0) de82 (0) df25 (0) df5e (0)\n============ DEPTH: 7 ==========================================\n007 1 ddf8 | 1 ddf8 (0)\n008 1 dc86 | 1 dc86 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ip":"0.0.0.0","ports":{"listener":0,"discovery":0},"id":"43086ff7ffd3c7bdec77bd288f41f1ee0ce21bd3f60a5df8931e2af6e7af5ef0fad432d29625491935d11567944351fc7867c807ebd12dd2c21c9e620ae0f85c","name":"node27","enode":"enode://43086ff7ffd3c7bdec77bd288f41f1ee0ce21bd3f60a5df8931e2af6e7af5ef0fad432d29625491935d11567944351fc7867c807ebd12dd2c21c9e620ae0f85c@0.0.0.0:0","listenAddr":""}}},{"node":{"info":{"id":"f98c0f4444a1ec80773454ddb691c226b81d8e2f79ed40c45a422d3359565edf7bd635d3eb7bd6c9e0870746849fb86f0b1b34cd56ec8d3ad969812e080f4983","protocols":{"bzz":"dHG+VqL2F3g9WhrkOQeUrST0UyWbfB+PZb6Pcci/i/c=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 7471be\npopulation: 17 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 edca f156 d6f3 dc3e | 121 adfc (0) ad36 (0) aca1 (0) ae65 (0)\n001 2 1c98 290f | 73 06aa (0) 043f (0) 0592 (0) 05e8 (0)\n002 1 5093 | 31 42c0 (0) 42d4 (0) 43af (0) 4019 (0)\n003 2 67a2 6143 | 11 6d21 (0) 6dbd (0) 6ea5 (0) 6544 (0)\n004 3 7dc6 79bd 7854 | 12 7d45 (0) 7d94 (0) 7dc6 (0) 7de7 (0)\n005 2 72ac 72fa | 4 7307 (0) 7294 (0) 72ac (0) 72fa (0)\n006 1 77ec | 1 77ec (0)\n============ DEPTH: 7 ==========================================\n007 1 759e | 1 759e (0)\n008 0 | 0\n009 1 7406 | 1 7406 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"discovery":0,"listener":0},"ip":"0.0.0.0","listenAddr":"","enode":"enode://f98c0f4444a1ec80773454ddb691c226b81d8e2f79ed40c45a422d3359565edf7bd635d3eb7bd6c9e0870746849fb86f0b1b34cd56ec8d3ad969812e080f4983@0.0.0.0:0","name":"node28"},"up":true,"config":{"id":"f98c0f4444a1ec80773454ddb691c226b81d8e2f79ed40c45a422d3359565edf7bd635d3eb7bd6c9e0870746849fb86f0b1b34cd56ec8d3ad969812e080f4983","private_key":"d8ecd7e813dbc7683f773cf38cd0e344ee9b4e308f12f557b6642eda2ef88ea1","services":["pss","bzz"],"name":"node28"}}},{"node":{"config":{"private_key":"225f43e03ffb8a97b760538a5cb9cddb61e7a387a3e56e82160300ed8c53e073","id":"baa28b8cb7ec539e0e157d7598cc5a5b0210fd8fb5c9026c3cd612133c5a8ee56997507511928af5683cb620fd85593dd8f6ff882d95fb847870ae4ce7dc503b","name":"node29","services":["pss","bzz"]},"up":true,"info":{"id":"baa28b8cb7ec539e0e157d7598cc5a5b0210fd8fb5c9026c3cd612133c5a8ee56997507511928af5683cb620fd85593dd8f6ff882d95fb847870ae4ce7dc503b","ip":"0.0.0.0","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 290fca\npopulation: 17 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 8c61 dc3e f156 | 121 a80b (0) abfa (0) aa50 (0) aa88 (0)\n001 2 5093 7471 | 62 42d4 (0) 42c0 (0) 43af (0) 4019 (0)\n002 1 1c98 | 38 06aa (0) 043f (0) 05ec (0) 05e8 (0)\n003 2 3dca 3e44 | 15 32dd (0) 3345 (0) 31ed (0) 34fc (0)\n004 2 259d 265d | 9 275c (0) 265d (0) 2454 (0) 259d (0)\n005 3 2f22 2fd8 2f9f | 5 2e9f (0) 2e4c (0) 2f22 (0) 2f9f (0)\n006 2 2af0 2a69 | 3 2af0 (0) 2a22 (0) 2a69 (0)\n007 0 | 0\n============ DEPTH: 8 ==========================================\n008 2 29ff 29fd | 2 29fd (0) 29ff (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"KQ/KdZZ0ASn9GjB1u/VohdjIM4H5ga2w+yg3mTdaO9U="},"ports":{"discovery":0,"listener":0},"listenAddr":"","name":"node29","enode":"enode://baa28b8cb7ec539e0e157d7598cc5a5b0210fd8fb5c9026c3cd612133c5a8ee56997507511928af5683cb620fd85593dd8f6ff882d95fb847870ae4ce7dc503b@0.0.0.0:0"}}},{"node":{"up":true,"config":{"services":["pss","bzz"],"name":"node30","id":"e0a043f98b462f10f72aa61ceda52f9c27829d086f6f2c5bf4db4fe32759002e5ff9519495d57dbb83d963a1dc991a1defcf5b9ef0d543789f38c68f5d07122b","private_key":"75acc8059053d23505c4513dbfd60777918db43c9713b3577c36836f066e31af"},"info":{"listenAddr":"","enode":"enode://e0a043f98b462f10f72aa61ceda52f9c27829d086f6f2c5bf4db4fe32759002e5ff9519495d57dbb83d963a1dc991a1defcf5b9ef0d543789f38c68f5d07122b@0.0.0.0:0","name":"node30","id":"e0a043f98b462f10f72aa61ceda52f9c27829d086f6f2c5bf4db4fe32759002e5ff9519495d57dbb83d963a1dc991a1defcf5b9ef0d543789f38c68f5d07122b","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: f15694\npopulation: 24 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 7471 1c98 290f | 135 458a (0) 47f9 (0) 46c5 (0) 43af (0)\n001 3 b5c7 b310 8c61 | 56 abfa (0) aa50 (0) aa88 (0) a80b (0)\n002 5 cb69 c15d c484 d6f3 | 36 ceee (0) c99c (0) c98d (0) c9f3 (0)\n003 4 e67d ecd2 ed13 edca | 12 e3c9 (0) e4c3 (0) e44b (0) e76a (0)\n004 3 f924 fa74 fed1 | 6 f915 (0) f924 (0) fb93 (0) fa74 (0)\n005 2 f5cc f4ee | 6 f644 (0) f78a (0) f5dd (0) f5cc (0)\n006 1 f3d3 | 1 f3d3 (0)\n============ DEPTH: 7 ==========================================\n007 2 f0e2 f048 | 2 f0e2 (0) f048 (0)\n008 1 f1fc | 1 f1fc (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"8VaULvdHkNGxtVIvg9cJmksWvDP29KsvPh19xbxrBSk="},"ports":{"listener":0,"discovery":0},"ip":"0.0.0.0"}}},{"node":{"info":{"listenAddr":"","enode":"enode://77e40e42f570a217f707888c714deb31fd70c856ae4b9a44ec7cee02768185dc4d7ed210429607f06690b32edd9fb06b304aff330a3949cc2fd49db1bc392edb@0.0.0.0:0","name":"node31","id":"77e40e42f570a217f707888c714deb31fd70c856ae4b9a44ec7cee02768185dc4d7ed210429607f06690b32edd9fb06b304aff330a3949cc2fd49db1bc392edb","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 8c615f\npopulation: 22 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 1c98 290f | 135 31ed (0) 32dd (0) 3345 (0) 34fc (0)\n001 7 c15d d6f3 e67d ecd2 | 65 d822 (0) d8b0 (0) dae3 (0) daa2 (0)\n002 4 bf5a b45d b5c7 b310 | 30 abfa (0) aa50 (0) aa88 (0) a80b (0)\n003 1 96b6 | 16 9c0c (0) 9c01 (0) 9fee (0) 9eec (0)\n004 2 86f7 8163 | 3 8612 (0) 86f7 (0) 8163 (0)\n============ DEPTH: 5 ==========================================\n005 5 89ee 8874 88da 8ac8 | 5 89ee (0) 8874 (0) 88da (0) 8ac8 (0)\n006 0 | 0\n007 0 | 0\n008 1 8c89 | 1 8c89 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"jGFfvOjdk4RtgQhX0DI1KRcy5DB8rQ5m/7I/BT0vDOs="},"ports":{"discovery":0,"listener":0},"ip":"0.0.0.0"},"up":true,"config":{"id":"77e40e42f570a217f707888c714deb31fd70c856ae4b9a44ec7cee02768185dc4d7ed210429607f06690b32edd9fb06b304aff330a3949cc2fd49db1bc392edb","private_key":"d6bd6c72597f6ec178becb6cdf6520d7de3f1278f77aa42095d287f45513b1f2","services":["pss","bzz"],"name":"node31"}}},{"node":{"up":true,"config":{"id":"92dbb67da2b99a8fe46b1e510addc2b83e357ac0b5287b7ef5c1b1bc6e252b8dfd605a6896ede65848e429216d1f67d530d9e7b83ff14058aa2e5b6e405d6801","private_key":"b329bd7d93dbc0fef82737292076fb91e323da4f34d22a5ee6fe311018203992","services":["pss","bzz"],"name":"node32"},"info":{"enode":"enode://92dbb67da2b99a8fe46b1e510addc2b83e357ac0b5287b7ef5c1b1bc6e252b8dfd605a6896ede65848e429216d1f67d530d9e7b83ff14058aa2e5b6e405d6801@0.0.0.0:0","name":"node32","listenAddr":"","ports":{"discovery":0,"listener":0},"protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: f4eee7\npopulation: 20 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 7de7 | 135 1e42 (0) 1e44 (0) 1da3 (0) 1d93 (0)\n001 2 b310 8c61 | 56 af5f (0) af30 (0) af35 (0) ae71 (0)\n002 1 c15d | 36 d822 (0) d8b0 (0) dae3 (0) daa2 (0)\n003 5 e649 e67d ecd2 ed13 | 12 e3c9 (0) e4c3 (0) e44b (0) e76a (0)\n004 3 fed1 f924 fa74 | 6 f915 (0) f924 (0) fb93 (0) fa74 (0)\n005 3 f0e2 f048 f156 | 5 f3d3 (0) f0e2 (0) f048 (0) f1fc (0)\n006 2 f78a f644 | 2 f78a (0) f644 (0)\n============ DEPTH: 7 ==========================================\n007 2 f5dd f5cc | 2 f5dd (0) f5cc (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 1 f4e0 | 1 f4e0 (0)\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"9O7nGhQ3IuqCiCeYdr9Wh8HtZe7eASnph+U/XsdthUM="},"ip":"0.0.0.0","id":"92dbb67da2b99a8fe46b1e510addc2b83e357ac0b5287b7ef5c1b1bc6e252b8dfd605a6896ede65848e429216d1f67d530d9e7b83ff14058aa2e5b6e405d6801"}}},{"node":{"info":{"listenAddr":"","enode":"enode://c206d8689068488179e86ce549de75989e0b17cbe09880d18fcf0fa212e629345f1b899203607a2b083569cb3f8398e501843166f5db23ac7fa7dacfe26dd3f4@0.0.0.0:0","name":"node33","id":"c206d8689068488179e86ce549de75989e0b17cbe09880d18fcf0fa212e629345f1b899203607a2b083569cb3f8398e501843166f5db23ac7fa7dacfe26dd3f4","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: b31029\npopulation: 20 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 7de7 1b86 3e44 | 135 0f81 (0) 0f5e (0) 0eee (0) 0ea2 (0)\n001 4 c15d edca f156 f4ee | 65 d822 (0) d8b0 (0) dae3 (0) daa2 (0)\n002 2 8ae6 8c61 | 26 9390 (0) 9294 (0) 9232 (0) 95e0 (0)\n003 1 a485 | 16 adfc (0) ad36 (0) aca1 (0) af5f (0)\n004 3 baf3 b8a7 bc08 | 6 be0a (0) bfec (0) bf5a (0) bc08 (0)\n============ DEPTH: 5 ==========================================\n005 7 b60d b79f b710 b4c7 | 7 b60d (0) b79f (0) b710 (0) b4c7 (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"sxApm+9PToSh7MlgFD5LG76YzU64NSRYxHdWnKmZTCA="},"ports":{"listener":0,"discovery":0},"ip":"0.0.0.0"},"up":true,"config":{"id":"c206d8689068488179e86ce549de75989e0b17cbe09880d18fcf0fa212e629345f1b899203607a2b083569cb3f8398e501843166f5db23ac7fa7dacfe26dd3f4","private_key":"f62b2e6c0ace2c204b4efdf62d3a9e4e41740aaa2a7aee72aa67272b08f65388","services":["pss","bzz"],"name":"node33"}}},{"node":{"up":true,"config":{"private_key":"5083c0504c95867fc5a924311192eeb35e80105fb25720516a8af8053516b87d","id":"7958d1517de1223e7fb30acf61d8618e49fb95a03bc2f49141f4c7967bc80b90e0dd526c205639de3c060029963d43813293c2556f7b127945c798f3f9f18626","name":"node34","services":["pss","bzz"]},"info":{"ip":"0.0.0.0","protocols":{"bzz":"7cojwPzP0exm9NObsSlGJ3a5CRwjN/avv+hzeg68DX0=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: edca23\npopulation: 16 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 7471 3e44 | 135 5c5d (0) 5f05 (0) 5fa8 (0) 5fab (0)\n001 2 8c61 b310 | 56 9c01 (0) 9c0c (0) 9fee (0) 9eec (0)\n002 2 d6f3 c15d | 36 d822 (0) d8b0 (0) dae3 (0) daa2 (0)\n003 3 f048 f156 f4ee | 17 f915 (0) f924 (0) fb93 (0) fa74 (0)\n004 3 e3c9 e649 e67d | 7 e3c9 (0) e44b (0) e4c3 (0) e76a (0)\n005 1 e839 | 1 e839 (0)\n006 0 | 0\n007 1 ecd2 | 1 ecd2 (0)\n============ DEPTH: 8 ==========================================\n008 2 ed65 ed13 | 2 ed65 (0) ed13 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"discovery":0,"listener":0},"id":"7958d1517de1223e7fb30acf61d8618e49fb95a03bc2f49141f4c7967bc80b90e0dd526c205639de3c060029963d43813293c2556f7b127945c798f3f9f18626","enode":"enode://7958d1517de1223e7fb30acf61d8618e49fb95a03bc2f49141f4c7967bc80b90e0dd526c205639de3c060029963d43813293c2556f7b127945c798f3f9f18626@0.0.0.0:0","name":"node34","listenAddr":""}}},{"node":{"up":true,"config":{"id":"d09104c44648391693ca64a57baa5ef54ed717e19c65ad0a0921d08cbaca8877d0190795d15f75f3b6ce6e676d6b0e55d5ee8fec3310c68b7060a32f7ff649cb","private_key":"52454a2b364cf029dbd0bd0f6880fd3c4a3eea2ef593277ca45c363888b025dc","services":["pss","bzz"],"name":"node35"},"info":{"id":"d09104c44648391693ca64a57baa5ef54ed717e19c65ad0a0921d08cbaca8877d0190795d15f75f3b6ce6e676d6b0e55d5ee8fec3310c68b7060a32f7ff649cb","ports":{"discovery":0,"listener":0},"protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 3e4470\npopulation: 22 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 b310 c15d e67d edca | 121 9c0c (0) 9c01 (0) 9fee (0) 9eec (0)\n001 5 4a67 6143 7854 7fa4 | 62 5c5d (0) 5f05 (0) 5fa8 (0) 5fab (0)\n002 1 1a83 | 38 06aa (0) 043f (0) 0592 (0) 05ec (0)\n003 4 265d 2f22 2f9f 290f | 20 2454 (0) 259d (0) 275c (0) 265d (0)\n004 1 3648 | 6 3345 (0) 32dd (0) 31ed (0) 34fc (0)\n005 3 388d 396b 3af3 | 4 388d (0) 396b (0) 3a4a (0) 3af3 (0)\n006 2 3d6b 3dca | 2 3d6b (0) 3dca (0)\n============ DEPTH: 7 ==========================================\n007 1 3f3e | 1 3f3e (0)\n008 1 3e85 | 1 3e85 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"PkRwwyeLtyPQHh8FjPNVvsjTvsqPWJzKboNdWUN1kaY="},"ip":"0.0.0.0","listenAddr":"","name":"node35","enode":"enode://d09104c44648391693ca64a57baa5ef54ed717e19c65ad0a0921d08cbaca8877d0190795d15f75f3b6ce6e676d6b0e55d5ee8fec3310c68b7060a32f7ff649cb@0.0.0.0:0"}}},{"node":{"config":{"name":"node36","services":["pss","bzz"],"private_key":"822f8bae08da0af5c00b04adc4653e9b425648c538f482224cc7406ed46694b4","id":"49215dfa786bfaa52b1e7aa6899392711a770b2504c82f536381fb1f18df16960257d75530efabf6dbd2b1361decc29758f870b318f777decf51f4833a9c1f00"},"up":true,"info":{"enode":"enode://49215dfa786bfaa52b1e7aa6899392711a770b2504c82f536381fb1f18df16960257d75530efabf6dbd2b1361decc29758f870b318f777decf51f4833a9c1f00@0.0.0.0:0","name":"node36","listenAddr":"","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: c15d13\npopulation: 20 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 4a67 6143 7de7 3e44 | 135 5c5d (0) 5fd0 (0) 5fa8 (0) 5fab (0)\n001 2 b310 8c61 | 56 a80b (0) abfa (0) aa50 (0) aa88 (0)\n002 5 f156 f4ee e67d edca | 29 e3c9 (0) e4c3 (0) e44b (0) e76a (0)\n003 1 d6f3 | 18 df25 (0) df5e (0) def4 (0) de82 (0)\n004 2 cb69 c8f9 | 9 ceee (0) c99c (0) c98d (0) c9f3 (0)\n005 4 c463 c484 c64f c770 | 6 c63e (0) c64f (0) c723 (1) c770 (0)\n============ DEPTH: 6 ==========================================\n006 1 c3f3 | 1 c3f3 (0)\n007 1 c0d1 | 1 c0d1 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"wV0Tr/f1aU+4/CohVIRqxwMGQTP+tjLiiDB3e7/HwBY="},"ports":{"listener":0,"discovery":0},"ip":"0.0.0.0","id":"49215dfa786bfaa52b1e7aa6899392711a770b2504c82f536381fb1f18df16960257d75530efabf6dbd2b1361decc29758f870b318f777decf51f4833a9c1f00"}}},{"node":{"info":{"id":"723f362e98f90d7ef15e24e353759fdbdabb08adab767dba73ab546741fac3dfb457466f1e2c851aa49526da1408f8ddb509e12f7dc0bc1e785c5b72be8a986e","ports":{"discovery":0,"listener":0},"protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 7de7eb\npopulation: 17 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 b310 f4ee c15d | 121 9eec (0) 9fee (0) 9c01 (0) 9c0c (0)\n001 1 3e44 | 73 004e (0) 0210 (0) 03f5 (0) 043f (0)\n002 1 4a67 | 31 5c5d (0) 5f05 (0) 5fd0 (0) 5fa8 (0)\n003 2 6330 6143 | 11 6d21 (0) 6dbd (0) 6ea5 (0) 6544 (0)\n004 1 72fa | 8 77ec (0) 7406 (0) 7471 (0) 759e (0)\n005 4 7a41 79bd 7829 7854 | 6 7a41 (0) 79ab (0) 79bd (0) 7829 (0)\n006 2 7ffe 7fa4 | 2 7ffe (0) 7fa4 (0)\n007 0 | 0\n008 1 7d45 | 1 7d45 (0)\n============ DEPTH: 9 ==========================================\n009 1 7d94 | 1 7d94 (0)\n010 1 7dc6 | 1 7dc6 (0)\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"fefrC3PzsCuZjlkuD8UbJsDDrmaV1BiXh00qPYzjVUs="},"ip":"0.0.0.0","listenAddr":"","name":"node37","enode":"enode://723f362e98f90d7ef15e24e353759fdbdabb08adab767dba73ab546741fac3dfb457466f1e2c851aa49526da1408f8ddb509e12f7dc0bc1e785c5b72be8a986e@0.0.0.0:0"},"config":{"id":"723f362e98f90d7ef15e24e353759fdbdabb08adab767dba73ab546741fac3dfb457466f1e2c851aa49526da1408f8ddb509e12f7dc0bc1e785c5b72be8a986e","private_key":"1e41a399b1b77f559bce8b0db22cabd26152fde5eab7c91576e4a2e00cbf3061","services":["pss","bzz"],"name":"node37"},"up":true}},{"node":{"config":{"services":["pss","bzz"],"name":"node38","id":"9f3af4577308965aceb7e0101443669496e7ccf1de680629862a7005966c708b6fb52e6dfe62660246b9892adc25838da2873502e0be706bcad8f25b7ceedfa5","private_key":"f39163a2c0a70f6eb02436a58c6029082e040ee88271fb27deb0e9c61af2a409"},"up":true,"info":{"ip":"0.0.0.0","protocols":{"bzz":"eFT7nw0vAWZTmUueIwM/J+IaLvGGo1LI0Gi3XqIL7sI=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 7854fb\npopulation: 14 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 e67d | 121 9eec (0) 9fee (0) 9c01 (0) 9c0c (0)\n001 1 3e44 | 73 004e (0) 03f5 (0) 0210 (0) 06aa (0)\n002 1 4a67 | 31 5c5d (0) 5f05 (0) 5fd0 (0) 5fa8 (0)\n003 1 6143 | 11 6d21 (0) 6dbd (0) 6ea5 (0) 6544 (0)\n004 3 72fa 759e 7471 | 8 77ec (0) 7406 (0) 7471 (0) 759e (0)\n005 2 7fa4 7de7 | 6 7ffe (0) 7fa4 (0) 7d45 (0) 7d94 (0)\n006 1 7a41 | 1 7a41 (0)\n007 2 79ab 79bd | 2 79ab (0) 79bd (0)\n008 0 | 0\n============ DEPTH: 9 ==========================================\n009 1 7829 | 1 7829 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 1 7851 | 1 7851 (0)\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"listener":0,"discovery":0},"id":"9f3af4577308965aceb7e0101443669496e7ccf1de680629862a7005966c708b6fb52e6dfe62660246b9892adc25838da2873502e0be706bcad8f25b7ceedfa5","enode":"enode://9f3af4577308965aceb7e0101443669496e7ccf1de680629862a7005966c708b6fb52e6dfe62660246b9892adc25838da2873502e0be706bcad8f25b7ceedfa5@0.0.0.0:0","name":"node38","listenAddr":""}}},{"node":{"info":{"protocols":{"bzz":"5n1yyMcrvHvsHU6TbWWtvqt10bbK/fLDnji/xyPM7r8=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: e67d72\npopulation: 19 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 3e44 6143 7854 | 135 004e (0) 0210 (0) 03f5 (0) 06aa (0)\n001 2 b5c7 8c61 | 56 9c01 (0) 9c0c (0) 9eec (0) 9fee (0)\n002 2 d6f3 c15d | 36 d3fd (0) d3d2 (0) d564 (0) d7ab (0)\n003 2 f156 f4ee | 17 fd2d (0) fed1 (0) f915 (0) f924 (0)\n004 4 e839 ed13 edca ecd2 | 5 e839 (0) ed65 (0) ed13 (0) edca (0)\n005 1 e3c9 | 1 e3c9 (0)\n006 2 e4c3 e44b | 2 e4c3 (0) e44b (0)\n============ DEPTH: 7 ==========================================\n007 2 e76a e787 | 2 e76a (0) e787 (0)\n008 0 | 0\n009 0 | 0\n010 1 e649 | 1 e649 (0)\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"discovery":0,"listener":0},"ip":"0.0.0.0","id":"ab1a3542d67ef9d1a63653990bf0782f53b0169fe5092adc92fa7aeb38f66c6b62d49e3455cc2ac4994bfcfb03111953acf4cc3099026672cc61f6e24cb3ae00","enode":"enode://ab1a3542d67ef9d1a63653990bf0782f53b0169fe5092adc92fa7aeb38f66c6b62d49e3455cc2ac4994bfcfb03111953acf4cc3099026672cc61f6e24cb3ae00@0.0.0.0:0","name":"node39","listenAddr":""},"up":true,"config":{"name":"node39","services":["pss","bzz"],"private_key":"30358622050808cb05e6c497e4ab00bc0baa126282c0f0bd38a279f15161ebfa","id":"ab1a3542d67ef9d1a63653990bf0782f53b0169fe5092adc92fa7aeb38f66c6b62d49e3455cc2ac4994bfcfb03111953acf4cc3099026672cc61f6e24cb3ae00"}}},{"node":{"up":true,"config":{"private_key":"e96ccd329e3ce59cca1c371e0d97e891c8755d8285c414d227fe2d8dde438ada","id":"7cc9389c8f751465e0b94baed896f6f122631052300b1b5b23d3c7656e4d11014a7a9ae62a1287bb040ca37221871a566cd470e523846df7e3acb5f94c7cde06","name":"node40","services":["pss","bzz"]},"info":{"ip":"0.0.0.0","protocols":{"bzz":"7NK1AtTpv3c2nGLRFCqftKsQcedRzGlx6eOB6VOw/BI=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: ecd2b5\npopulation: 14 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 4a67 | 135 004e (0) 0210 (0) 03f5 (0) 06aa (0)\n001 2 8c61 b5c7 | 56 9c01 (0) 9c0c (0) 9fee (0) 9eec (0)\n002 1 c15d | 36 d3fd (0) d3d2 (0) d564 (0) d7ab (0)\n003 2 f156 f4ee | 17 f915 (0) f924 (0) fb93 (0) fa74 (0)\n004 4 e3c9 e44b e649 e67d | 7 e3c9 (0) e4c3 (0) e44b (0) e76a (0)\n005 1 e839 | 1 e839 (0)\n006 0 | 0\n============ DEPTH: 7 ==========================================\n007 3 ed65 ed13 edca | 3 ed65 (0) ed13 (0) edca (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"discovery":0,"listener":0},"id":"7cc9389c8f751465e0b94baed896f6f122631052300b1b5b23d3c7656e4d11014a7a9ae62a1287bb040ca37221871a566cd470e523846df7e3acb5f94c7cde06","enode":"enode://7cc9389c8f751465e0b94baed896f6f122631052300b1b5b23d3c7656e4d11014a7a9ae62a1287bb040ca37221871a566cd470e523846df7e3acb5f94c7cde06@0.0.0.0:0","name":"node40","listenAddr":""}}},{"node":{"info":{"enode":"enode://a58a4db7a96b1578935b222c78b7b4dd8b3519d2995c3616e5a154c5175242a503097771332504638a0b321b9574110207f9a7d77b109d1de3d66a12ec6498e5@0.0.0.0:0","name":"node41","listenAddr":"","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 4a670f\npopulation: 17 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 c15d ecd2 | 121 abfa (0) aa50 (0) aa88 (0) a80b (0)\n001 1 3e44 | 73 004e (0) 0210 (0) 03f5 (0) 06aa (0)\n002 5 6143 7de7 7fa4 79bd | 31 6d21 (0) 6dbd (0) 6ea5 (0) 6544 (0)\n003 1 566e | 14 5c5d (0) 5f05 (0) 5fd0 (0) 5fa8 (0)\n004 2 46c5 4019 | 7 458a (0) 47f9 (0) 46c5 (0) 42c0 (0)\n005 1 4cf6 | 4 4fd6 (0) 4f90 (0) 4d44 (0) 4cf6 (0)\n006 1 487e | 1 487e (0)\n007 1 4b00 | 1 4b00 (0)\n============ DEPTH: 8 ==========================================\n008 3 4af7 4a82 4a81 | 3 4af7 (0) 4a82 (0) 4a81 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"SmcP5hcRMH93gbO1qAFPwOY4Zu/jVqJeYbLnaKc4mYA="},"ports":{"discovery":0,"listener":0},"ip":"0.0.0.0","id":"a58a4db7a96b1578935b222c78b7b4dd8b3519d2995c3616e5a154c5175242a503097771332504638a0b321b9574110207f9a7d77b109d1de3d66a12ec6498e5"},"up":true,"config":{"services":["pss","bzz"],"name":"node41","id":"a58a4db7a96b1578935b222c78b7b4dd8b3519d2995c3616e5a154c5175242a503097771332504638a0b321b9574110207f9a7d77b109d1de3d66a12ec6498e5","private_key":"a8af10b8118821f3f7a1c456f857e4ddf50526337a38eddaffe15bbbb383ac32"}}},{"node":{"info":{"id":"e903d7aebff96a6afa4b9dd19b0b02e5af18da8e4e89f64247e1a2c2d46637538c741182eac67f45ec61be76aeaccde57f0a0184bd608ea7d92e586d4f827ea7","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 61431b\npopulation: 27 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 c15d e44b e67d | 121 f644 (0) f78a (0) f5dd (0) f5cc (0)\n001 3 1a83 3e44 265d | 73 1e42 (0) 1e44 (0) 1c98 (0) 1da3 (0)\n002 3 566e 4cf6 4a67 | 31 5f05 (0) 5fd0 (0) 5fa8 (0) 5fab (0)\n003 9 759e 7471 7307 72fa | 20 77ec (0) 7406 (0) 7471 (0) 759e (0)\n004 3 6ea5 6d21 6dbd | 3 6ea5 (0) 6d21 (0) 6dbd (0)\n005 4 6610 67a2 670d 6544 | 5 6544 (0) 6610 (0) 670d (0) 6783 (0)\n============ DEPTH: 6 ==========================================\n006 1 6330 | 1 6330 (0)\n007 1 604c | 1 604c (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"YUMbNt1eMRR1/SJjZQ+QcxwHtyjBBSrt9buY1BTwfo8="},"ip":"0.0.0.0","ports":{"listener":0,"discovery":0},"listenAddr":"","enode":"enode://e903d7aebff96a6afa4b9dd19b0b02e5af18da8e4e89f64247e1a2c2d46637538c741182eac67f45ec61be76aeaccde57f0a0184bd608ea7d92e586d4f827ea7@0.0.0.0:0","name":"node42"},"up":true,"config":{"private_key":"aea855db0ccd147bccfb6969c37e5ceb12623a95cde33c7725d51418c2a58e56","id":"e903d7aebff96a6afa4b9dd19b0b02e5af18da8e4e89f64247e1a2c2d46637538c741182eac67f45ec61be76aeaccde57f0a0184bd608ea7d92e586d4f827ea7","name":"node42","services":["pss","bzz"]}}},{"node":{"config":{"id":"e1f23e1caba66f5ff821edbc4a3d527539937f73d86dd0df43aa1266a99f51f2480a77961eff177fbbf852fc52cb9317179f80b1580194daaedadc3b00510751","private_key":"14f5b342ec3c67c89537fc4dbaa64da24b8d7d02242eff9642b680d1923a000a","services":["pss","bzz"],"name":"node43"},"up":true,"info":{"listenAddr":"","enode":"enode://e1f23e1caba66f5ff821edbc4a3d527539937f73d86dd0df43aa1266a99f51f2480a77961eff177fbbf852fc52cb9317179f80b1580194daaedadc3b00510751@0.0.0.0:0","name":"node43","id":"e1f23e1caba66f5ff821edbc4a3d527539937f73d86dd0df43aa1266a99f51f2480a77961eff177fbbf852fc52cb9317179f80b1580194daaedadc3b00510751","ip":"0.0.0.0","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 265d7f\npopulation: 20 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 bf5a | 121 f3d3 (0) f156 (0) f1fc (0) f048 (0)\n001 3 4cf6 7fa4 6143 | 62 5c5d (0) 5f05 (0) 5fd0 (0) 5fa8 (0)\n002 3 13d8 0f5e 05e8 | 38 1e42 (0) 1e44 (0) 1da3 (0) 1d93 (0)\n003 2 3e44 3648 | 15 388d (0) 396b (0) 3a4a (0) 3af3 (0)\n004 4 290f 2f9f 2fd8 2f22 | 11 2a22 (0) 2a69 (0) 2af0 (0) 29fd (0)\n005 4 2013 211a 2279 2374 | 5 2013 (0) 2168 (0) 211a (0) 2279 (0)\n============ DEPTH: 6 ==========================================\n006 2 2454 259d | 2 2454 (0) 259d (0)\n007 1 275c | 1 275c (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"Jl1/xVP7jcAW18bMwx/DcpEqEeno2g5YIuNxqR2C6Fc="},"ports":{"listener":0,"discovery":0}}}},{"node":{"info":{"listenAddr":"","enode":"enode://9bea5f82c2a390587de44d620d6637834e6f2329cd83d8df6305b03b75d9b543160b6c6f9f8887e6bc88f1d0726435d6c8ad813aadad0653b0790b8f6388413a@0.0.0.0:0","name":"node44","id":"9bea5f82c2a390587de44d620d6637834e6f2329cd83d8df6305b03b75d9b543160b6c6f9f8887e6bc88f1d0726435d6c8ad813aadad0653b0790b8f6388413a","protocols":{"bzz":"v1rG+bZRiVyNdas655lPkZgdu83OJafNcY/JltqWlG0=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: bf5ac6\npopulation: 17 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 4cf6 265d | 135 6d21 (0) 6dbd (0) 6ea5 (0) 6544 (0)\n001 3 fed1 e44b df5e | 65 f3d3 (0) f1fc (0) f156 (0) f048 (0)\n002 4 8c61 8ac8 88da 8163 | 26 9fee (0) 9eec (0) 9c01 (0) 9c0c (0)\n003 2 a033 a749 | 16 abfa (0) aa50 (0) aa88 (0) a80b (0)\n004 1 b5c7 | 8 b310 (0) b60d (0) b710 (0) b79f (0)\n005 2 b8a7 baf3 | 2 b8a7 (0) baf3 (0)\n006 1 bc08 | 1 bc08 (0)\n============ DEPTH: 7 ==========================================\n007 1 be0a | 1 be0a (0)\n008 1 bfec | 1 bfec (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"listener":0,"discovery":0},"ip":"0.0.0.0"},"up":true,"config":{"private_key":"b56fd7d35ab0d1f76d30c898f6794ff5399b2d6982c4d5afadacaf72aa535bd4","id":"9bea5f82c2a390587de44d620d6637834e6f2329cd83d8df6305b03b75d9b543160b6c6f9f8887e6bc88f1d0726435d6c8ad813aadad0653b0790b8f6388413a","name":"node44","services":["pss","bzz"]}}},{"node":{"config":{"id":"d7af0a0217ff98804aa05f8f926a8b6262363b5391d24cda8048cca5ca5982b407b7b098302d0db6d8dd9ac0883b2025b3de651617ed1a173181148295c6d336","private_key":"59db345b1123f497ab8804ffed255e26dc028f68d9010314f9eebee243ee74cb","services":["pss","bzz"],"name":"node45"},"up":true,"info":{"listenAddr":"","enode":"enode://d7af0a0217ff98804aa05f8f926a8b6262363b5391d24cda8048cca5ca5982b407b7b098302d0db6d8dd9ac0883b2025b3de651617ed1a173181148295c6d336@0.0.0.0:0","name":"node45","id":"d7af0a0217ff98804aa05f8f926a8b6262363b5391d24cda8048cca5ca5982b407b7b098302d0db6d8dd9ac0883b2025b3de651617ed1a173181148295c6d336","ports":{"listener":0,"discovery":0},"protocols":{"bzz":"TPZVsDd4vLQcMmZPExaNwyloNURoyKppneUrQ6Lg3H0=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 4cf655\npopulation: 21 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 df5e bf5a | 121 f78a (0) f644 (0) f5dd (0) f5cc (0)\n001 1 265d | 73 388d (0) 396b (0) 3a4a (0) 3af3 (0)\n002 5 6143 7307 72ac 79bd | 31 6d21 (0) 6dbd (0) 6ea5 (0) 6544 (0)\n003 2 57d5 566e | 14 5c5d (0) 5f05 (0) 5fd0 (0) 5fa8 (0)\n004 2 46c5 4019 | 7 458a (0) 47f9 (0) 46c5 (0) 42c0 (0)\n005 6 487e 4a82 4a81 4af7 | 6 487e (0) 4a82 (0) 4a81 (0) 4af7 (0)\n============ DEPTH: 6 ==========================================\n006 2 4fd6 4f90 | 2 4fd6 (0) 4f90 (0)\n007 1 4d44 | 1 4d44 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ip":"0.0.0.0"}}},{"node":{"info":{"protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: df5ea7\npopulation: 15 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 4cf6 | 135 3af3 (0) 3a4a (0) 388d (0) 396b (0)\n001 1 bf5a | 56 9fee (0) 9eec (0) 9c01 (0) 9c0c (0)\n002 2 e44b fed1 | 29 ecd2 (0) edca (0) ed65 (0) ed13 (0)\n003 2 c9f3 c0d1 | 18 c770 (0) c723 (0) c63e (0) c64f (0)\n004 2 d3d2 d68f | 7 d3fd (0) d3d2 (0) d564 (0) d7ab (0)\n005 2 dae3 daa2 | 4 d822 (0) d8b0 (0) daa2 (0) dae3 (0)\n006 2 dc86 dc3e | 3 ddf8 (0) dc86 (0) dc3e (0)\n============ DEPTH: 7 ==========================================\n007 2 def4 de82 | 2 def4 (0) de82 (0)\n008 0 | 0\n009 1 df25 | 1 df25 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"316nLAwle76ptDkBoeQGv2BVowfQgzZ+fx2UTmXCs80="},"ip":"0.0.0.0","ports":{"listener":0,"discovery":0},"id":"bb0749de05a97daa67de889c15831ce39a080d641b3b08e3c248b0b16f4c07943fea8dd054d4a7e3e4af91ecff07053ce90096485a360b6f1d93050d179f30c3","name":"node46","enode":"enode://bb0749de05a97daa67de889c15831ce39a080d641b3b08e3c248b0b16f4c07943fea8dd054d4a7e3e4af91ecff07053ce90096485a360b6f1d93050d179f30c3@0.0.0.0:0","listenAddr":""},"config":{"private_key":"87b0f18d2c52b3f0f6934c09421248a6d0457eab81b8dbd93840877ba7c25006","id":"bb0749de05a97daa67de889c15831ce39a080d641b3b08e3c248b0b16f4c07943fea8dd054d4a7e3e4af91ecff07053ce90096485a360b6f1d93050d179f30c3","name":"node46","services":["pss","bzz"]},"up":true}},{"node":{"info":{"id":"c6f38fe8a0f2b3773bae332e0ca7516e944bde186fe99daae10a2b0aecde3ce23c1834eaad97a4e6d2da8cd53a08dbafa72d2b827c851b115b74e8010125dba2","ports":{"listener":0,"discovery":0},"protocols":{"bzz":"/tFbV+dJxfj1/bOC65Wr4s4N7hhMgX5VcSIgfzcpsFw=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: fed15b\npopulation: 14 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 7fa4 | 135 396b (0) 388d (0) 3a4a (0) 3af3 (0)\n001 2 bf5a 8163 | 56 9fee (0) 9eec (0) 9c01 (0) 9c0c (0)\n002 1 df5e | 36 c723 (0) c770 (0) c63e (0) c64f (0)\n003 2 e839 e44b | 12 ecd2 (0) edca (0) ed65 (0) ed13 (0)\n004 3 f156 f4e0 f4ee | 11 f3d3 (0) f1fc (0) f156 (0) f048 (0)\n============ DEPTH: 5 ==========================================\n005 4 f915 f924 fb93 fa74 | 4 f915 (0) f924 (0) fb93 (0) fa74 (0)\n006 1 fd2d | 1 fd2d (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ip":"0.0.0.0","listenAddr":"","enode":"enode://c6f38fe8a0f2b3773bae332e0ca7516e944bde186fe99daae10a2b0aecde3ce23c1834eaad97a4e6d2da8cd53a08dbafa72d2b827c851b115b74e8010125dba2@0.0.0.0:0","name":"node47"},"up":true,"config":{"services":["pss","bzz"],"name":"node47","id":"c6f38fe8a0f2b3773bae332e0ca7516e944bde186fe99daae10a2b0aecde3ce23c1834eaad97a4e6d2da8cd53a08dbafa72d2b827c851b115b74e8010125dba2","private_key":"86f6a5532361ee4f4511ef6ced21fe2e8d4e12b10d61b8d16f6805d5d6ff869c"}}},{"node":{"info":{"ports":{"listener":0,"discovery":0},"protocols":{"bzz":"f6Rxkr73DTQiOg2tGB2gm1Xpmh2UDoxIhjrvtjyftzM=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 7fa471\npopulation: 23 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 fed1 | 121 9a82 (0) 99aa (0) 99fb (0) 99db (0)\n001 2 3e44 265d | 73 3345 (0) 32dd (0) 31ed (0) 34fc (0)\n002 3 4a67 4cf6 566e | 31 458a (0) 47f9 (0) 46c5 (0) 42d4 (0)\n003 3 6ea5 6330 6143 | 11 6d21 (0) 6dbd (0) 6ea5 (0) 6544 (0)\n004 4 759e 7307 72fa 72ac | 8 77ec (0) 7406 (0) 7471 (0) 759e (0)\n005 5 7829 7851 7854 79ab | 6 7a41 (0) 7829 (0) 7851 (0) 7854 (0)\n============ DEPTH: 6 ==========================================\n006 4 7d45 7d94 7dc6 7de7 | 4 7d45 (0) 7d94 (0) 7dc6 (0) 7de7 (0)\n007 0 | 0\n008 0 | 0\n009 1 7ffe | 1 7ffe (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ip":"0.0.0.0","id":"9c8f156797deff649d74d56fc42b4bb1a87312089114d4350424c375837d9c8068dd09af01c1c973d12ec5d7e8da600cd685cae70d3116b9dbda823092e03fff","enode":"enode://9c8f156797deff649d74d56fc42b4bb1a87312089114d4350424c375837d9c8068dd09af01c1c973d12ec5d7e8da600cd685cae70d3116b9dbda823092e03fff@0.0.0.0:0","name":"node48","listenAddr":""},"up":true,"config":{"private_key":"604cbd4183a23b452f0c9add6181effac6084e4411051850ed0bc4f1ae9a33d8","id":"9c8f156797deff649d74d56fc42b4bb1a87312089114d4350424c375837d9c8068dd09af01c1c973d12ec5d7e8da600cd685cae70d3116b9dbda823092e03fff","name":"node48","services":["pss","bzz"]}}},{"node":{"up":true,"config":{"private_key":"ada9db22cbb971526fb9a1e050a039ae3bc1b898086642c093f9d2fd1b4a2e30","id":"3639f964feba681db9702cac3f02058f2e490fd7bffb217dc3480dc458decafd5955541fea89f0f6f14ee50a745eaf98b21363d6b4fb88c31bd32bf7845d524b","name":"node49","services":["pss","bzz"]},"info":{"listenAddr":"","name":"node49","enode":"enode://3639f964feba681db9702cac3f02058f2e490fd7bffb217dc3480dc458decafd5955541fea89f0f6f14ee50a745eaf98b21363d6b4fb88c31bd32bf7845d524b@0.0.0.0:0","id":"3639f964feba681db9702cac3f02058f2e490fd7bffb217dc3480dc458decafd5955541fea89f0f6f14ee50a745eaf98b21363d6b4fb88c31bd32bf7845d524b","protocols":{"bzz":"Vm6y4CKoPUk4CpTPF8RZVfR/ru3ksj+X01fm59cVLa4=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 566eb2\npopulation: 22 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 fa74 e44b | 121 9eec (0) 9fee (0) 9c01 (0) 9c0c (0)\n001 1 05e8 | 73 396b (0) 388d (0) 3a4a (0) 3af3 (0)\n002 5 6143 7307 72ac 79bd | 31 6d21 (0) 6dbd (0) 6ea5 (0) 6544 (0)\n003 5 46c5 4b00 4a82 4a67 | 17 458a (0) 47f9 (0) 46c5 (0) 42d4 (0)\n004 2 5fab 5fd0 | 5 5c5d (0) 5f05 (0) 5fd0 (0) 5fa8 (0)\n005 3 5093 5110 5288 | 4 5093 (0) 5110 (0) 5261 (0) 5288 (0)\n006 1 5571 | 1 5571 (0)\n============ DEPTH: 7 ==========================================\n007 2 5716 57d5 | 2 5716 (0) 57d5 (0)\n008 1 5695 | 1 5695 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"listener":0,"discovery":0},"ip":"0.0.0.0"}}},{"node":{"info":{"ports":{"discovery":0,"listener":0},"protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: e44b5f\npopulation: 22 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 6143 566e 13d8 3648 | 135 6d21 (0) 6dbd (0) 6ea5 (0) 6544 (0)\n001 4 bf5a baf3 88da 8163 | 56 9fee (0) 9eec (0) 9c01 (0) 9c0c (0)\n002 1 df5e | 36 c723 (0) c770 (0) c63e (0) c64f (0)\n003 4 f924 fb93 fa74 fed1 | 17 f3d3 (0) f1fc (0) f156 (0) f048 (0)\n004 3 ed13 ecd2 e839 | 5 ecd2 (0) edca (0) ed65 (0) ed13 (0)\n005 1 e3c9 | 1 e3c9 (0)\n============ DEPTH: 6 ==========================================\n006 4 e649 e67d e76a e787 | 4 e649 (0) e67d (0) e76a (0) e787 (0)\n007 0 | 0\n008 1 e4c3 | 1 e4c3 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"5EtfSlY6NuUOVyU9/drEy1qSE39hX0b2OJlbSxiGPzs="},"ip":"0.0.0.0","id":"842ec3faa8b4a4cdec32abfa00ae827277fe2696e1b0c6551154533b16cf75ae69caf834b4f08488fa5c8b322fb633b1fd8a5b7d436e9c589cc9074dc031ae68","name":"node50","enode":"enode://842ec3faa8b4a4cdec32abfa00ae827277fe2696e1b0c6551154533b16cf75ae69caf834b4f08488fa5c8b322fb633b1fd8a5b7d436e9c589cc9074dc031ae68@0.0.0.0:0","listenAddr":""},"config":{"name":"node50","services":["pss","bzz"],"private_key":"c3e1cd6edffbca6121b114763c7cc8d8fce9b4444747af55b56cb111f3803b5e","id":"842ec3faa8b4a4cdec32abfa00ae827277fe2696e1b0c6551154533b16cf75ae69caf834b4f08488fa5c8b322fb633b1fd8a5b7d436e9c589cc9074dc031ae68"},"up":true}},{"node":{"up":true,"config":{"name":"node51","services":["pss","bzz"],"private_key":"e74e4c545f1d04c35176065ee8e6610e9847ba30aa0b4ff9df3d574a9cd04bc5","id":"76643f67075c6e45bd176db19473240cda6f886d1cac25330e2d99c84a429934f4c6a606c9c72574d5eaccd0a3f1770dab05e6ff6a5b5ce4d7258fed2bc13d48"},"info":{"listenAddr":"","name":"node51","enode":"enode://76643f67075c6e45bd176db19473240cda6f886d1cac25330e2d99c84a429934f4c6a606c9c72574d5eaccd0a3f1770dab05e6ff6a5b5ce4d7258fed2bc13d48@0.0.0.0:0","id":"76643f67075c6e45bd176db19473240cda6f886d1cac25330e2d99c84a429934f4c6a606c9c72574d5eaccd0a3f1770dab05e6ff6a5b5ce4d7258fed2bc13d48","protocols":{"bzz":"NkhWFVdsaHAjgvYUBUSUzEpAuQ/WbbhrnYamoTHcxqw=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 364856\npopulation: 18 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 e44b | 121 a033 (0) a485 (0) a672 (0) a749 (0)\n001 1 6330 | 62 6d21 (0) 6dbd (0) 6ea5 (0) 6544 (0)\n002 2 0f5e 05e8 | 38 1e42 (0) 1e44 (0) 1da3 (0) 1d94 (0)\n003 6 29ff 2e9f 2f9f 2f22 | 20 2279 (0) 2374 (0) 2013 (0) 2168 (0)\n004 3 3af3 3f3e 3e44 | 9 388d (0) 396b (0) 3a4a (0) 3af3 (0)\n005 3 3345 32dd 31ed | 3 3345 (0) 32dd (0) 31ed (0)\n============ DEPTH: 6 ==========================================\n006 2 34fc 3538 | 2 34fc (0) 3538 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ip":"0.0.0.0","ports":{"discovery":0,"listener":0}}}},{"node":{"up":true,"config":{"name":"node52","services":["pss","bzz"],"private_key":"d44b65dad6f0fc7d3868207b4d13aa646925f53eef21981d7898ca8eef1f47f3","id":"20f6a8be1d2d8b5d6a43d851a2f5475385ef07fab80ac46525d0beccf3e25c01d726cfb3a1179e8343b1e88d21684fb24dd6e6497537d4e7e9edd59cb95d1b8d"},"info":{"id":"20f6a8be1d2d8b5d6a43d851a2f5475385ef07fab80ac46525d0beccf3e25c01d726cfb3a1179e8343b1e88d21684fb24dd6e6497537d4e7e9edd59cb95d1b8d","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 05e8f8\npopulation: 23 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 fa74 baf3 | 121 d8b0 (0) d822 (0) dae3 (0) daa2 (0)\n001 4 79bd 72ac 566e 5110 | 62 6544 (0) 6610 (0) 670d (0) 6783 (0)\n002 3 2f22 265d 3648 | 35 2013 (0) 2168 (0) 211a (0) 2279 (0)\n003 5 1d07 1c98 185a 1a83 | 26 1e42 (0) 1e44 (0) 1da3 (0) 1d93 (0)\n004 4 0eee 0ea2 0f81 0f5e | 4 0eee (0) 0ea2 (0) 0f81 (0) 0f5e (0)\n005 1 03f5 | 3 004e (0) 0210 (0) 03f5 (0)\n006 1 06aa | 1 06aa (0)\n007 1 043f | 1 043f (0)\n008 0 | 0\n============ DEPTH: 9 ==========================================\n009 1 0592 | 1 0592 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 1 05ec | 1 05ec (0)\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"Bej4JuSXIs4J7doH+QFmiN9QMrwBg1iePJSv2m3WMHQ="},"ports":{"listener":0,"discovery":0},"ip":"0.0.0.0","listenAddr":"","name":"node52","enode":"enode://20f6a8be1d2d8b5d6a43d851a2f5475385ef07fab80ac46525d0beccf3e25c01d726cfb3a1179e8343b1e88d21684fb24dd6e6497537d4e7e9edd59cb95d1b8d@0.0.0.0:0"}}},{"node":{"config":{"private_key":"5c0b688fe7738cf3e06e8f932ca1986d88f6c00a9f705d50335632433ad7d52a","id":"c0bec7375c66bec98524ade2245c1d7480516fc5d87a3249e64ec86418e80e202f1e3da76832e97bbc3dcaed8c96ca344e4829347b4428f4b1cb61999e404c05","name":"node53","services":["pss","bzz"]},"up":true,"info":{"protocols":{"bzz":"uvMs+s6VO9IhQZcLaRVn7TdfBgQ/4x3jVFmPtCMPsKM=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: baf32c\npopulation: 21 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 13d8 05e8 79bd 72ac | 135 2374 (0) 2279 (0) 2013 (0) 2168 (0)\n001 4 d68f f924 e839 e44b | 65 ceee (0) ca81 (0) cb69 (0) c883 (0)\n002 4 9294 9232 88da 8163 | 26 9fee (0) 9eec (0) 9c01 (0) 9c0c (0)\n003 1 a749 | 16 a80b (0) aa88 (0) aa50 (0) abfa (0)\n004 3 b310 b5c7 b79f | 8 b310 (0) b45d (0) b463 (0) b4c7 (0)\n============ DEPTH: 5 ==========================================\n005 4 bc08 be0a bfec bf5a | 4 bc08 (0) be0a (0) bfec (0) bf5a (0)\n006 1 b8a7 | 1 b8a7 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"discovery":0,"listener":0},"ip":"0.0.0.0","id":"c0bec7375c66bec98524ade2245c1d7480516fc5d87a3249e64ec86418e80e202f1e3da76832e97bbc3dcaed8c96ca344e4829347b4428f4b1cb61999e404c05","name":"node53","enode":"enode://c0bec7375c66bec98524ade2245c1d7480516fc5d87a3249e64ec86418e80e202f1e3da76832e97bbc3dcaed8c96ca344e4829347b4428f4b1cb61999e404c05@0.0.0.0:0","listenAddr":""}}},{"node":{"up":true,"config":{"name":"node54","services":["pss","bzz"],"private_key":"8d78762191955f66c6881143b2fbf367eb02b6182eb49c5f11d22381f8e34152","id":"699c923976c5b8c70c353840d3e384750f466954265f05fbb0d5877a2c0318a041dc57adc12ac6e8fbae7a00d6b6675e1a1be3a8f59dac12727ee3f8ae467a13"},"info":{"protocols":{"bzz":"cqz1Orfb2pDqcOeNAB/iHnq4jkBU/wRTIS4zom+79/E=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 72acf5\npopulation: 20 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 fa74 baf3 | 121 ceee (0) cb69 (0) ca81 (0) c883 (0)\n001 3 0f5e 05e8 13d8 | 73 2013 (0) 2168 (0) 211a (0) 2374 (0)\n002 6 5110 57d5 566e 46c5 | 31 5c5d (0) 5f05 (0) 5fd0 (0) 5fa8 (0)\n003 2 6143 6330 | 11 6d21 (0) 6dbd (0) 6ea5 (0) 6544 (0)\n004 2 7fa4 79bd | 12 7d45 (0) 7d94 (0) 7dc6 (0) 7de7 (0)\n005 2 7471 759e | 4 77ec (0) 7406 (0) 7471 (0) 759e (0)\n006 0 | 0\n007 1 7307 | 1 7307 (0)\n008 0 | 0\n============ DEPTH: 9 ==========================================\n009 1 72fa | 1 72fa (0)\n010 1 7294 | 1 7294 (0)\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"listener":0,"discovery":0},"ip":"0.0.0.0","id":"699c923976c5b8c70c353840d3e384750f466954265f05fbb0d5877a2c0318a041dc57adc12ac6e8fbae7a00d6b6675e1a1be3a8f59dac12727ee3f8ae467a13","enode":"enode://699c923976c5b8c70c353840d3e384750f466954265f05fbb0d5877a2c0318a041dc57adc12ac6e8fbae7a00d6b6675e1a1be3a8f59dac12727ee3f8ae467a13@0.0.0.0:0","name":"node54","listenAddr":""}}},{"node":{"config":{"services":["pss","bzz"],"name":"node55","id":"10551c0c37abc25457903978868dd4843a52fda5f9b571b05ebd974d8c381fda4349f17c2b986a2e4b8d06b0517422f085d5f6d9cd814efa40e48393d9f71d7e","private_key":"296788d95df4ddf6af02ab317a50c417d36515453b5cebdae7c71f55a657c7f9"},"up":true,"info":{"id":"10551c0c37abc25457903978868dd4843a52fda5f9b571b05ebd974d8c381fda4349f17c2b986a2e4b8d06b0517422f085d5f6d9cd814efa40e48393d9f71d7e","ports":{"listener":0,"discovery":0},"protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 13d810\npopulation: 16 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 e44b baf3 | 121 ceee (0) ca81 (0) cb69 (0) c883 (0)\n001 1 72ac | 62 5c5d (0) 5f05 (0) 5fd0 (0) 5fa8 (0)\n002 2 2f22 265d | 35 2279 (0) 2374 (0) 2013 (0) 2168 (0)\n003 2 0f5e 05e8 | 12 0eee (0) 0ea2 (0) 0f81 (0) 0f5e (0)\n004 4 1c98 18f9 1b86 1a83 | 18 1e42 (0) 1e44 (0) 1d5f (0) 1d07 (0)\n005 3 14c8 15f6 1673 | 5 1673 (0) 1441 (0) 14c8 (0) 1566 (0)\n006 0 | 0\n============ DEPTH: 7 ==========================================\n007 2 123f 12b9 | 2 123f (0) 12b9 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"E9gQfGacwn9svGTO9rK9EfctspfyhXwt5zI7kmMrgjE="},"ip":"0.0.0.0","listenAddr":"","enode":"enode://10551c0c37abc25457903978868dd4843a52fda5f9b571b05ebd974d8c381fda4349f17c2b986a2e4b8d06b0517422f085d5f6d9cd814efa40e48393d9f71d7e@0.0.0.0:0","name":"node55"}}},{"node":{"info":{"enode":"enode://8fb6838337f832445531764ddafc3c747b2607f2f33e244685d6de621c2b53264270f5504187e43b7fa5cda53e66dd00b16c06879c82fb38a3d9e8aec4060210@0.0.0.0:0","name":"node56","listenAddr":"","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 1a833a\npopulation: 22 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 88da | 121 ceee (0) cb69 (0) ca81 (0) c883 (0)\n001 4 4b00 759e 6330 6143 | 62 6d21 (0) 6dbd (0) 6ea5 (0) 6544 (0)\n002 2 3e44 2f22 | 35 2279 (0) 2374 (0) 2013 (0) 2168 (0)\n003 4 0f5e 06aa 05ec 05e8 | 12 0eee (0) 0ea2 (0) 0f81 (0) 0f5e (0)\n004 2 1673 13d8 | 8 1441 (0) 14c8 (0) 1566 (0) 15f6 (0)\n005 2 1c98 1d07 | 8 1e42 (0) 1e44 (0) 1c98 (0) 1da3 (0)\n006 3 193e 1835 18f9 | 5 185a (0) 1835 (0) 18f9 (0) 194a (0)\n============ DEPTH: 7 ==========================================\n007 3 1b72 1b1e 1b86 | 3 1b72 (0) 1b1e (0) 1b86 (0)\n008 1 1a02 | 1 1a02 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"GoM6SRjW9OvAw5ujv9Tp3ha7cyy6y5Y/9YrT0xmPEzY="},"ports":{"discovery":0,"listener":0},"ip":"0.0.0.0","id":"8fb6838337f832445531764ddafc3c747b2607f2f33e244685d6de621c2b53264270f5504187e43b7fa5cda53e66dd00b16c06879c82fb38a3d9e8aec4060210"},"config":{"name":"node56","services":["pss","bzz"],"private_key":"b229e6aab9cd866a0aecbc7358eeb2986cdf2ff1bcd25ae6d3dc33ad282a03ee","id":"8fb6838337f832445531764ddafc3c747b2607f2f33e244685d6de621c2b53264270f5504187e43b7fa5cda53e66dd00b16c06879c82fb38a3d9e8aec4060210"},"up":true}},{"node":{"info":{"listenAddr":"","enode":"enode://869ca41ea1f82bec5f43807a3aaaabc39b21c62d3c9c8bdc0709683e22dd37cb2f3c313766809076d2c02d0d6171f4f32a1b5080abcb8072d88981042ae6237d@0.0.0.0:0","name":"node57","id":"869ca41ea1f82bec5f43807a3aaaabc39b21c62d3c9c8bdc0709683e22dd37cb2f3c313766809076d2c02d0d6171f4f32a1b5080abcb8072d88981042ae6237d","protocols":{"bzz":"iNqdzNqJwRHd5AMY/R5SOed7Zw9aG4ij6TILc1CIXjE=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 88da9d\npopulation: 13 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 1a83 | 135 5c5d (0) 5f05 (0) 5fd0 (0) 5fa8 (0)\n001 1 e44b | 65 c3f3 (0) c15d (0) c0d1 (0) c463 (0)\n002 2 bf5a baf3 | 30 ae71 (0) ae65 (0) af5f (0) af35 (0)\n003 1 9232 | 16 9fee (0) 9eec (0) 9c01 (0) 9c0c (0)\n004 2 86f7 8163 | 3 8612 (0) 86f7 (0) 8163 (0)\n005 2 8c89 8c61 | 2 8c89 (0) 8c61 (0)\n006 2 8ae6 8ac8 | 2 8ae6 (0) 8ac8 (0)\n============ DEPTH: 7 ==========================================\n007 1 89ee | 1 89ee (0)\n008 1 8874 | 1 8874 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"discovery":0,"listener":0},"ip":"0.0.0.0"},"up":true,"config":{"id":"869ca41ea1f82bec5f43807a3aaaabc39b21c62d3c9c8bdc0709683e22dd37cb2f3c313766809076d2c02d0d6171f4f32a1b5080abcb8072d88981042ae6237d","private_key":"016f837cc16dfa3e8ed3519599b40bf8ee03872dbe01509e3928f5459be708d9","services":["pss","bzz"],"name":"node57"}}},{"node":{"info":{"protocols":{"bzz":"gWPuvmlhI4F6bZmNd4FhKTHfb6L9ApPA0N05XQMcU/Y=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 8163ee\npopulation: 18 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 2f22 7307 | 135 2013 (0) 2168 (0) 211a (0) 2279 (0)\n001 5 d68f c9f3 fb93 fed1 | 65 d3fd (0) d3d2 (0) d564 (0) d7ab (0)\n002 2 bf5a baf3 | 30 abfa (0) aa50 (0) aa88 (0) a80b (0)\n003 1 9232 | 16 9fee (0) 9eec (0) 9c01 (0) 9c0c (0)\n004 6 8c61 8ae6 8ac8 89ee | 7 8c89 (2) 8c61 (0) 8ae6 (0) 8ac8 (0)\n============ DEPTH: 5 ==========================================\n005 2 8612 86f7 | 2 8612 (0) 86f7 (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ip":"0.0.0.0","ports":{"listener":0,"discovery":0},"id":"b4557089e4247379e587a087f53b36dd1f86f85d9dcfab5dc562079978cd959adaef5b30d11258d9cb552e7c5abddf5377a71d449febe8f2acb0aec3ebd8ba73","name":"node58","enode":"enode://b4557089e4247379e587a087f53b36dd1f86f85d9dcfab5dc562079978cd959adaef5b30d11258d9cb552e7c5abddf5377a71d449febe8f2acb0aec3ebd8ba73@0.0.0.0:0","listenAddr":""},"config":{"name":"node58","services":["pss","bzz"],"private_key":"fb9bd6643165414424261aa1dfdab87ad7b83e52d9bfcbaa69e1bb116f84b19a","id":"b4557089e4247379e587a087f53b36dd1f86f85d9dcfab5dc562079978cd959adaef5b30d11258d9cb552e7c5abddf5377a71d449febe8f2acb0aec3ebd8ba73"},"up":true}},{"node":{"info":{"ip":"0.0.0.0","protocols":{"bzz":"cwdJkizj3NjiSbmI2/uVDBVHOi9v1c/iqBJplfsdwYY=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 730749\npopulation: 16 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 8163 | 121 d822 (0) d8b0 (0) daa2 (0) dae3 (0)\n001 1 2f22 | 73 1673 (0) 15f6 (0) 1566 (0) 1441 (0)\n002 4 566e 57d5 4cf6 4b00 | 31 458a (0) 47f9 (0) 46c5 (0) 42d4 (0)\n003 3 6ea5 6143 6330 | 11 6d21 (0) 6dbd (0) 6ea5 (0) 6544 (0)\n004 2 7fa4 79bd | 12 7d45 (0) 7d94 (0) 7dc6 (0) 7de7 (0)\n005 2 7406 759e | 4 77ec (0) 7406 (0) 7471 (0) 759e (0)\n006 0 | 0\n============ DEPTH: 7 ==========================================\n007 3 72fa 7294 72ac | 3 72fa (0) 7294 (0) 72ac (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"discovery":0,"listener":0},"id":"f52297fc51b920d2495ccece290432656d9388e698339c8c1279ceea45de698a4ecbda1d25928c48f1e19e9dacd3147e23ef01acc093872d7300aed187841dcc","name":"node59","enode":"enode://f52297fc51b920d2495ccece290432656d9388e698339c8c1279ceea45de698a4ecbda1d25928c48f1e19e9dacd3147e23ef01acc093872d7300aed187841dcc@0.0.0.0:0","listenAddr":""},"config":{"services":["pss","bzz"],"name":"node59","id":"f52297fc51b920d2495ccece290432656d9388e698339c8c1279ceea45de698a4ecbda1d25928c48f1e19e9dacd3147e23ef01acc093872d7300aed187841dcc","private_key":"c761dd84c3923763ca0acfc07e4939b146d57bd6b42efd6c5e8e5c0b63dc1518"},"up":true}},{"node":{"info":{"listenAddr":"","enode":"enode://202ae63076a5560418023f00c9965b2a1d12de932b5371ae270d63db88551a7aa1a3c48841f81948fad3435bb4a7e3e165a2eced9fd937444e4502471e23dae8@0.0.0.0:0","name":"node60","id":"202ae63076a5560418023f00c9965b2a1d12de932b5371ae270d63db88551a7aa1a3c48841f81948fad3435bb4a7e3e165a2eced9fd937444e4502471e23dae8","protocols":{"bzz":"LyKEU3YpUUg31cIpbShx2MTBR3GfDdwo73xinv1E3WE=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 2f2284\npopulation: 20 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 8163 | 121 d3fd (0) d3d2 (0) d564 (0) d7ab (0)\n001 7 4b00 5110 57d5 6330 | 62 42c0 (0) 42d4 (0) 43af (0) 4019 (0)\n002 3 05e8 13d8 1a83 | 38 1673 (0) 1566 (0) 15f6 (0) 1441 (0)\n003 2 3e44 3648 | 15 388d (0) 396b (0) 3a4a (0) 3af3 (0)\n004 1 265d | 9 2279 (0) 2374 (0) 2013 (0) 2168 (0)\n005 2 290f 2a69 | 6 2af0 (0) 2a22 (0) 2a69 (0) 29fd (0)\n006 0 | 0\n007 2 2e4c 2e9f | 2 2e4c (0) 2e9f (0)\n============ DEPTH: 8 ==========================================\n008 2 2f9f 2fd8 | 2 2f9f (0) 2fd8 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ip":"0.0.0.0","ports":{"listener":0,"discovery":0}},"up":true,"config":{"id":"202ae63076a5560418023f00c9965b2a1d12de932b5371ae270d63db88551a7aa1a3c48841f81948fad3435bb4a7e3e165a2eced9fd937444e4502471e23dae8","private_key":"4503d268231fe7b4f60290da3c7f7f67bc51e123b65b7fb48f8ababc2eccbf6a","services":["pss","bzz"],"name":"node60"}}},{"node":{"info":{"id":"99af34b172d319633e07a4e528f416024653a230a9103a4b281171f75bb697dd6be4757558c94e86210b4da8d9fe1229f6a5d8c4174989ea0ce696f8d1a9995d","ports":{"discovery":0,"listener":0},"protocols":{"bzz":"V9V+oh5GNYVzcL4CYYsViitu0KgjbGfEcHDvQUELPMQ=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 57d57e\npopulation: 22 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 c0d1 c9f3 | 121 9a82 (0) 99aa (0) 99db (0) 99fb (0)\n001 3 06aa 0f5e 2f22 | 73 1673 (0) 1441 (0) 14c8 (0) 1566 (0)\n002 4 759e 72ac 7307 79bd | 31 6d21 (0) 6dbd (0) 6ea5 (0) 6544 (0)\n003 5 46c5 4019 4cf6 4af7 | 17 458a (0) 47f9 (0) 46c5 (0) 42c0 (0)\n004 1 5fab | 5 5c5d (0) 5f05 (0) 5fd0 (0) 5fa8 (0)\n005 3 5288 5093 5110 | 4 5261 (0) 5288 (0) 5093 (0) 5110 (0)\n006 1 5571 | 1 5571 (0)\n============ DEPTH: 7 ==========================================\n007 2 5695 566e | 2 5695 (0) 566e (0)\n008 1 5716 | 1 5716 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ip":"0.0.0.0","listenAddr":"","enode":"enode://99af34b172d319633e07a4e528f416024653a230a9103a4b281171f75bb697dd6be4757558c94e86210b4da8d9fe1229f6a5d8c4174989ea0ce696f8d1a9995d@0.0.0.0:0","name":"node61"},"config":{"id":"99af34b172d319633e07a4e528f416024653a230a9103a4b281171f75bb697dd6be4757558c94e86210b4da8d9fe1229f6a5d8c4174989ea0ce696f8d1a9995d","private_key":"c643d7712e7aeffa425505349e837da25e2cae551f446e56a96e5b2df48f2bfe","services":["pss","bzz"],"name":"node61"},"up":true}},{"node":{"up":true,"config":{"services":["pss","bzz"],"name":"node62","id":"362ed9a92b588d5fe315b90a74aa27f7600e4a7d06b27ceb26272340388d916a831df85bf83450ef80bda4e4a21acaac60560c8a42940a26e2ac567519e2a202","private_key":"cc7a5a2b92089562a184b024a3782da10d925002ca1dac6c95d902ed4df95998"},"info":{"listenAddr":"","name":"node62","enode":"enode://362ed9a92b588d5fe315b90a74aa27f7600e4a7d06b27ceb26272340388d916a831df85bf83450ef80bda4e4a21acaac60560c8a42940a26e2ac567519e2a202@0.0.0.0:0","id":"362ed9a92b588d5fe315b90a74aa27f7600e4a7d06b27ceb26272340388d916a831df85bf83450ef80bda4e4a21acaac60560c8a42940a26e2ac567519e2a202","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: c9f391\npopulation: 23 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 79bd 57d5 | 135 1da3 (0) 1d93 (0) 1d94 (0) 1d5f (0)\n001 2 8ac8 8163 | 56 9a82 (0) 99aa (0) 99db (0) 99fb (0)\n002 4 f924 fb93 fa74 e839 | 29 f78a (0) f644 (0) f5cc (0) f5dd (0)\n003 3 df5e d3d2 d68f | 18 d8b0 (0) d822 (0) daa2 (0) dae3 (0)\n004 4 c64f c484 c3f3 c0d1 | 9 c770 (0) c723 (0) c63e (0) c64f (0)\n005 1 ceee | 1 ceee (0)\n006 2 cb69 ca81 | 2 cb69 (0) ca81 (0)\n007 3 c883 c8fe c8f9 | 3 c883 (0) c8fe (0) c8f9 (0)\n008 0 | 0\n============ DEPTH: 9 ==========================================\n009 2 c99c c98d | 2 c99c (0) c98d (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"yfORscAI+6yJeR1xNdTSPCRe9vKCWNa6T4JmGdqaVNg="},"ports":{"listener":0,"discovery":0},"ip":"0.0.0.0"}}},{"node":{"up":true,"config":{"name":"node63","services":["pss","bzz"],"private_key":"31d2f152a7b173892132dcb790d697cb779cc886a67355b5907e803ec734a1e0","id":"01427ba4d1e2de0b2764515556676a6058f88c16f597780dea3d7f95a6eec9299c3987d99c199d88a0a5e695ee6f0ff7de424e4eb65e54233b956a9634133998"},"info":{"listenAddr":"","name":"node63","enode":"enode://01427ba4d1e2de0b2764515556676a6058f88c16f597780dea3d7f95a6eec9299c3987d99c199d88a0a5e695ee6f0ff7de424e4eb65e54233b956a9634133998@0.0.0.0:0","id":"01427ba4d1e2de0b2764515556676a6058f88c16f597780dea3d7f95a6eec9299c3987d99c199d88a0a5e695ee6f0ff7de424e4eb65e54233b956a9634133998","ports":{"listener":0,"discovery":0},"protocols":{"bzz":"eb145eIZ01uMbxhHxMd8meZIbbgOwZGW45HXt2Iy4MA=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 79bd78\npopulation: 25 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 baf3 c9f3 fb93 | 121 9a82 (0) 99aa (0) 99db (0) 99fb (0)\n001 2 05e8 2f22 | 73 388d (0) 396b (0) 3a4a (0) 3af3 (0)\n002 5 566e 57d5 4cf6 4a67 | 31 5c5d (0) 5f05 (0) 5fd0 (0) 5fa8 (0)\n003 2 6143 6330 | 11 6d21 (0) 6dbd (0) 6ea5 (0) 6544 (0)\n004 5 7307 72fa 72ac 7471 | 8 7307 (0) 72fa (0) 7294 (0) 72ac (0)\n005 3 7d45 7de7 7fa4 | 6 7d45 (0) 7d94 (0) 7dc6 (0) 7de7 (0)\n006 1 7a41 | 1 7a41 (0)\n============ DEPTH: 7 ==========================================\n007 3 7829 7851 7854 | 3 7829 (0) 7851 (0) 7854 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 1 79ab | 1 79ab (0)\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ip":"0.0.0.0"}}},{"node":{"info":{"name":"node64","enode":"enode://4e88cc60efee147fb72a735775944c7b2ba0790e2b2b935b4b3c2da9a3158a2a7aae411e9204cdbe6b2304d90a3a8278f8bb1a800a409e8500d100d84ba1947f@0.0.0.0:0","listenAddr":"","ports":{"discovery":0,"listener":0},"protocols":{"bzz":"+5NBfFlwUPje6zCYR19s8NITkmMytZwlpTjBtOavicA=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: fb9341\npopulation: 14 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 79bd 4b00 | 135 388d (0) 396b (0) 3a4a (0) 3af3 (0)\n001 1 8163 | 56 9fee (0) 9eec (0) 9c01 (0) 9c0c (0)\n002 2 c9f3 c0d1 | 36 d564 (0) d7ab (0) d6d2 (0) d6f3 (0)\n003 2 e44b e839 | 12 e3c9 (0) e76a (0) e787 (0) e649 (0)\n004 2 f0e2 f4e0 | 11 f3d3 (0) f156 (0) f1fc (0) f048 (0)\n005 2 fd2d fed1 | 2 fd2d (0) fed1 (0)\n============ DEPTH: 6 ==========================================\n006 2 f915 f924 | 2 f915 (0) f924 (0)\n007 1 fa74 | 1 fa74 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ip":"0.0.0.0","id":"4e88cc60efee147fb72a735775944c7b2ba0790e2b2b935b4b3c2da9a3158a2a7aae411e9204cdbe6b2304d90a3a8278f8bb1a800a409e8500d100d84ba1947f"},"config":{"private_key":"f0045a14d36d5d17d8859c51edce3fd7afd083b6722cf6a3668dbd4f1db69e17","id":"4e88cc60efee147fb72a735775944c7b2ba0790e2b2b935b4b3c2da9a3158a2a7aae411e9204cdbe6b2304d90a3a8278f8bb1a800a409e8500d100d84ba1947f","name":"node64","services":["pss","bzz"]},"up":true}},{"node":{"info":{"listenAddr":"","enode":"enode://58f9139905ae1d005950f110b7ead3355672ecc478e8c66393566c64b935003f6fec3031dc9eb21cda660acb1955cf7bb33a20fdd74d493f29868ace328fcd75@0.0.0.0:0","name":"node65","id":"58f9139905ae1d005950f110b7ead3355672ecc478e8c66393566c64b935003f6fec3031dc9eb21cda660acb1955cf7bb33a20fdd74d493f29868ace328fcd75","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 4b00ab\npopulation: 22 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 f924 fb93 | 121 9eec (0) 9fee (0) 9c01 (0) 9c0c (0)\n001 3 1a83 3dca 2f22 | 73 388d (0) 396b (0) 3a4a (0) 3af3 (0)\n002 4 6330 72ac 7307 79bd | 31 6d21 (0) 6dbd (0) 6ea5 (0) 6544 (0)\n003 4 5110 566e 5716 57d5 | 14 5c5d (0) 5f05 (0) 5fd0 (0) 5fa8 (0)\n004 3 46c5 43af 4019 | 7 458a (0) 47f9 (0) 46c5 (0) 42c0 (0)\n005 1 4cf6 | 4 4f90 (0) 4fd6 (0) 4d44 (0) 4cf6 (0)\n006 1 487e | 1 487e (0)\n============ DEPTH: 7 ==========================================\n007 4 4a67 4a82 4a81 4af7 | 4 4a82 (0) 4a81 (0) 4af7 (0) 4a67 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"SwCrdDlasA4lRwx0S40y9EFS9UGbQ1QP7B+7r0kfUsA="},"ip":"0.0.0.0","ports":{"listener":0,"discovery":0}},"up":true,"config":{"services":["pss","bzz"],"name":"node65","id":"58f9139905ae1d005950f110b7ead3355672ecc478e8c66393566c64b935003f6fec3031dc9eb21cda660acb1955cf7bb33a20fdd74d493f29868ace328fcd75","private_key":"f00404704ec4c556b0ee4cbbc1b8fec0b741d8a587b0baffa9a0ce79648f6560"}}},{"node":{"config":{"name":"node66","services":["pss","bzz"],"private_key":"5998a146afa95186e2ecf2d1daa4376812bbcbbf22809ba0807dc5e34e5d1e9c","id":"0c9a05514b96e7c3a0fbca21552e158faa70047246b230addca172a5023fd7439acd1c3a0b4f9191579b308dab38c961734ffdb36fb8e16383e912d070fc0218"},"up":true,"info":{"id":"0c9a05514b96e7c3a0fbca21552e158faa70047246b230addca172a5023fd7439acd1c3a0b4f9191579b308dab38c961734ffdb36fb8e16383e912d070fc0218","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: f9243a\npopulation: 15 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 4b00 | 135 396b (0) 388d (0) 3a4a (0) 3af3 (0)\n001 2 8ac8 baf3 | 56 a80b (0) abfa (0) aa88 (0) aa50 (0)\n002 2 c9f3 c0d1 | 36 d822 (0) d8b0 (0) daa2 (0) dae3 (0)\n003 2 e44b e839 | 12 e3c9 (0) e76a (0) e787 (0) e649 (0)\n004 3 f156 f4ee f4e0 | 11 f3d3 (0) f1fc (0) f156 (0) f048 (0)\n005 2 fd2d fed1 | 2 fd2d (0) fed1 (0)\n============ DEPTH: 6 ==========================================\n006 2 fa74 fb93 | 2 fa74 (0) fb93 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 1 f915 | 1 f915 (0)\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"+SQ62GSFnt01FZLSSr31ycTjf0/+KuEgHEXyZXbuVyU="},"ports":{"discovery":0,"listener":0},"ip":"0.0.0.0","listenAddr":"","enode":"enode://0c9a05514b96e7c3a0fbca21552e158faa70047246b230addca172a5023fd7439acd1c3a0b4f9191579b308dab38c961734ffdb36fb8e16383e912d070fc0218@0.0.0.0:0","name":"node66"}}},{"node":{"up":true,"config":{"private_key":"542904a26056c4d86aafe32a8dbbb30ef4a31b36c81563f47a8ce22145e5da4d","id":"77e7d427b65b6c29c0d92c51184af73031bfa768a47fc20be6c264f422bf718865259c17c103bf47289b3abe62f93452781c6303d757e76d3d56ceeb26262fab","name":"node67","services":["pss","bzz"]},"info":{"ip":"0.0.0.0","protocols":{"bzz":"6Dkr3Okqfc+l4xlqbh1OXcSBTHLhBNPiqh8auZ4qR6Y=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: e8392b\npopulation: 19 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 759e | 135 388d (0) 396b (0) 3a4a (0) 3af3 (0)\n001 1 baf3 | 56 a80b (0) abfa (0) aa88 (0) aa50 (0)\n002 2 c9f3 c0d1 | 36 d822 (0) d8b0 (0) daa2 (0) dae3 (0)\n003 7 f0e2 f5dd f4e0 fed1 | 17 f3d3 (0) f156 (0) f1fc (0) f048 (0)\n004 4 e3c9 e67d e4c3 e44b | 7 e3c9 (0) e76a (0) e787 (0) e649 (0)\n============ DEPTH: 5 ==========================================\n005 4 ecd2 edca ed13 ed65 | 4 ecd2 (0) edca (0) ed65 (0) ed13 (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"listener":0,"discovery":0},"id":"77e7d427b65b6c29c0d92c51184af73031bfa768a47fc20be6c264f422bf718865259c17c103bf47289b3abe62f93452781c6303d757e76d3d56ceeb26262fab","enode":"enode://77e7d427b65b6c29c0d92c51184af73031bfa768a47fc20be6c264f422bf718865259c17c103bf47289b3abe62f93452781c6303d757e76d3d56ceeb26262fab@0.0.0.0:0","name":"node67","listenAddr":""}}},{"node":{"config":{"id":"fee3fa1ba2a051d40a582908384ee81179db6c2b5f4bfa58c24f8015b794b43a093ed68b69bb209684135f972a055a9845978fa1b7d489e2126c3b514297f1c2","private_key":"4feddb131b7fb4c20144641fd72951bf356b4ec190a8a8cb322f2d0819aaf317","services":["pss","bzz"],"name":"node68"},"up":true,"info":{"id":"fee3fa1ba2a051d40a582908384ee81179db6c2b5f4bfa58c24f8015b794b43a093ed68b69bb209684135f972a055a9845978fa1b7d489e2126c3b514297f1c2","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 759eac\npopulation: 24 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 e839 fa74 f4e0 | 121 a80b (0) abfa (0) aa88 (0) aa50 (0)\n001 2 1a83 2f22 | 73 388d (0) 396b (0) 3a4a (0) 3af3 (0)\n002 3 57d5 46c5 4019 | 31 5c5d (0) 5f05 (0) 5fd0 (0) 5fa8 (0)\n003 4 6ea5 6783 6143 6330 | 11 6d21 (0) 6dbd (0) 6ea5 (0) 6544 (0)\n004 5 7dc6 7fa4 7854 7829 | 12 7d45 (0) 7d94 (0) 7dc6 (0) 7de7 (0)\n005 4 7307 72fa 7294 72ac | 4 7307 (0) 72fa (0) 7294 (0) 72ac (0)\n006 1 77ec | 1 77ec (0)\n============ DEPTH: 7 ==========================================\n007 2 7471 7406 | 2 7471 (0) 7406 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"dZ6su0vCPY9oJtX/PTg0PkFDyXNIhSXKdH5m5gAuI2Q="},"ip":"0.0.0.0","ports":{"listener":0,"discovery":0},"listenAddr":"","enode":"enode://fee3fa1ba2a051d40a582908384ee81179db6c2b5f4bfa58c24f8015b794b43a093ed68b69bb209684135f972a055a9845978fa1b7d489e2126c3b514297f1c2@0.0.0.0:0","name":"node68"}}},{"node":{"info":{"listenAddr":"","enode":"enode://8f3e9102306a13adb91e01f7a847e7880054f1a7df8976d05facb3a8fb37d47cce04f25e18a19713e5c3da7541e96e829fc67c8b924b717d2d9586c9c12d4fcf@0.0.0.0:0","name":"node69","id":"8f3e9102306a13adb91e01f7a847e7880054f1a7df8976d05facb3a8fb37d47cce04f25e18a19713e5c3da7541e96e829fc67c8b924b717d2d9586c9c12d4fcf","protocols":{"bzz":"9ODZHKWO1haRi/JoVlwu20F2KT6FG40py72lW9xghTQ=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: f4e0d9\npopulation: 18 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 4019 6330 759e | 135 388d (0) 396b (0) 3a4a (0) 3af3 (0)\n001 1 8ac8 | 56 a80b (0) abfa (0) aa88 (0) aa50 (0)\n002 2 d3d2 c0d1 | 36 d8b0 (0) d822 (0) dae3 (0) daa2 (0)\n003 1 e839 | 12 e3c9 (0) e649 (0) e67d (0) e787 (0)\n004 4 fed1 f924 fb93 fa74 | 6 fd2d (0) fed1 (0) fa74 (0) fb93 (0)\n005 2 f1fc f0e2 | 5 f3d3 (0) f156 (0) f1fc (0) f048 (0)\n006 2 f78a f644 | 2 f78a (0) f644 (0)\n============ DEPTH: 7 ==========================================\n007 2 f5cc f5dd | 2 f5cc (0) f5dd (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 1 f4ee | 1 f4ee (0)\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"listener":0,"discovery":0},"ip":"0.0.0.0"},"config":{"name":"node69","services":["pss","bzz"],"private_key":"1fa8a1ef0703e81a32dd0faf6d25447a183ecb90d6994f45921c3db0e8dc3d06","id":"8f3e9102306a13adb91e01f7a847e7880054f1a7df8976d05facb3a8fb37d47cce04f25e18a19713e5c3da7541e96e829fc67c8b924b717d2d9586c9c12d4fcf"},"up":true}},{"node":{"info":{"protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 4019ce\npopulation: 19 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 d3d2 f4e0 | 121 abfa (0) aa88 (0) aa50 (0) a80b (0)\n001 1 0f5e | 73 388d (0) 396b (0) 3a4a (0) 3af3 (0)\n002 2 6330 759e | 31 6d21 (0) 6dbd (0) 6ea5 (0) 6544 (0)\n003 3 5fab 57d5 5110 | 14 5c5d (0) 5f05 (0) 5fd0 (0) 5fa8 (0)\n004 6 4cf6 4af7 4a82 4a81 | 10 4fd6 (0) 4f90 (0) 4d44 (0) 4cf6 (0)\n005 2 458a 46c5 | 3 458a (0) 47f9 (0) 46c5 (0)\n============ DEPTH: 6 ==========================================\n006 3 43af 42c0 42d4 | 3 42c0 (0) 42d4 (0) 43af (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"QBnOHcZn2QqFAhtfv0mtd8Hef9NEOkChe9+vUXXvoeE="},"ports":{"listener":0,"discovery":0},"ip":"0.0.0.0","id":"b183f12f3602bfdab0480cb0b0ba7dc69b267b0dbc7e54c316741cb78b9e99aa69fd321ad7755d095e9be14e6bd90fe14ef8fe9bafc1a0dea10a144795021a08","name":"node70","enode":"enode://b183f12f3602bfdab0480cb0b0ba7dc69b267b0dbc7e54c316741cb78b9e99aa69fd321ad7755d095e9be14e6bd90fe14ef8fe9bafc1a0dea10a144795021a08@0.0.0.0:0","listenAddr":""},"up":true,"config":{"private_key":"dffd7a3c7cb1c3a0d129522290be15481d609d4d268daa13364cb16e13213398","id":"b183f12f3602bfdab0480cb0b0ba7dc69b267b0dbc7e54c316741cb78b9e99aa69fd321ad7755d095e9be14e6bd90fe14ef8fe9bafc1a0dea10a144795021a08","name":"node70","services":["pss","bzz"]}}},{"node":{"info":{"listenAddr":"","enode":"enode://212a8048ab9925171475e81dce047865df186222d673d524c810a9f613e4a21f3b130fa34c5f44974fbeaab1f6028177e71568e00a1184d9fd05443c172f5fcf@0.0.0.0:0","name":"node71","id":"212a8048ab9925171475e81dce047865df186222d673d524c810a9f613e4a21f3b130fa34c5f44974fbeaab1f6028177e71568e00a1184d9fd05443c172f5fcf","protocols":{"bzz":"URDH5UoY32ljkZhm5/bAw6SDBF1awg/A36XhkmaBvn8=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 5110c7\npopulation: 18 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 8ac8 d68f | 121 aca1 (0) adfc (0) ad36 (0) ae71 (0)\n001 3 0f5e 05e8 2f22 | 73 31ed (0) 32dd (0) 3345 (0) 34fc (0)\n002 1 72ac | 31 6d21 (0) 6dbd (0) 6ea5 (0) 6610 (0)\n003 3 4af7 4b00 4019 | 17 4fd6 (0) 4f90 (0) 4d44 (0) 4cf6 (0)\n004 1 5fab | 5 5c5d (0) 5f05 (0) 5fd0 (0) 5fa8 (0)\n005 5 5571 5695 566e 5716 | 5 5571 (0) 5695 (0) 566e (0) 5716 (0)\n============ DEPTH: 6 ==========================================\n006 2 5261 5288 | 2 5261 (0) 5288 (0)\n007 1 5093 | 1 5093 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"discovery":0,"listener":0},"ip":"0.0.0.0"},"config":{"id":"212a8048ab9925171475e81dce047865df186222d673d524c810a9f613e4a21f3b130fa34c5f44974fbeaab1f6028177e71568e00a1184d9fd05443c172f5fcf","private_key":"c5ab7f8e52d35ba6f3aae971d7215e9dd234f82a3331ca904c2b6b526d2a59db","services":["pss","bzz"],"name":"node71"},"up":true}},{"node":{"info":{"listenAddr":"","enode":"enode://af9b80f6836113aeda897d6903e9ffb4f7f1a706a7f821d0d40f03a0d83c18d6a19795ee4bfc1093ada04014415b1f230db1d2f056df3f5027cce71611588046@0.0.0.0:0","name":"node72","id":"af9b80f6836113aeda897d6903e9ffb4f7f1a706a7f821d0d40f03a0d83c18d6a19795ee4bfc1093ada04014415b1f230db1d2f056df3f5027cce71611588046","ip":"0.0.0.0","protocols":{"bzz":"1o9QR1W0j41BVwFp3TVE7xyuoqsbszT42MX7J/6BbwE=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: d68f50\npopulation: 19 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 5fab 5110 | 135 388d (0) 396b (0) 3a4a (0) 3af3 (0)\n001 3 8163 8ac8 baf3 | 56 adfc (0) ad36 (0) aca1 (0) ae65 (0)\n002 1 fa74 | 29 ecd2 (0) edca (0) ed65 (0) ed13 (0)\n003 3 c9f3 c3f3 c0d1 | 18 ceee (0) cb69 (0) ca81 (0) c8fe (0)\n004 4 dae3 dc3e df25 df5e | 11 d822 (0) d8b0 (0) daa2 (0) dae3 (0)\n005 2 d3fd d3d2 | 2 d3fd (0) d3d2 (0)\n006 1 d564 | 1 d564 (0)\n007 1 d7ab | 1 d7ab (0)\n008 0 | 0\n============ DEPTH: 9 ==========================================\n009 2 d6d2 d6f3 | 2 d6f3 (0) d6d2 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"listener":0,"discovery":0}},"up":true,"config":{"id":"af9b80f6836113aeda897d6903e9ffb4f7f1a706a7f821d0d40f03a0d83c18d6a19795ee4bfc1093ada04014415b1f230db1d2f056df3f5027cce71611588046","private_key":"07c9b7896ed7f5c9763b72ab6631797941cd615c3ecd431de30169fdbe89cc2a","services":["pss","bzz"],"name":"node72"}}},{"node":{"up":true,"config":{"id":"99a7649bdf2ee7f0bc049308b0997e33abb68481c05a573df9aea30da5a1f267df07b2c584e3e985baf31704f04ad2a2c4876e0f8555333be6d09f5080b583f1","private_key":"da65f19428056c9c512efa6c1e97a409861ab28956b2c9ed0b8a72bba67c010e","services":["pss","bzz"],"name":"node73"},"info":{"protocols":{"bzz":"+nSDw7hlICmjyFmew8wc7Fp1GBxWSn9sUAlDcNQwNv8=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: fa7483\npopulation: 22 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 5 0f5e 05e8 566e 72ac | 135 396b (0) 388d (0) 3a4a (0) 3af3 (0)\n001 1 8ac8 | 56 a80b (0) abfa (0) aa88 (0) aa50 (0)\n002 4 c9f3 c0d1 d3d2 d68f | 36 ceee (0) cb69 (0) ca81 (0) c8fe (0)\n003 2 e44b e839 | 12 e3c9 (0) e76a (0) e787 (0) e649 (0)\n004 5 f156 f0e2 f5dd f4ee | 11 f3d3 (0) f1fc (0) f156 (0) f048 (0)\n005 2 fd2d fed1 | 2 fd2d (0) fed1 (0)\n============ DEPTH: 6 ==========================================\n006 2 f915 f924 | 2 f915 (0) f924 (0)\n007 1 fb93 | 1 fb93 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"discovery":0,"listener":0},"ip":"0.0.0.0","id":"99a7649bdf2ee7f0bc049308b0997e33abb68481c05a573df9aea30da5a1f267df07b2c584e3e985baf31704f04ad2a2c4876e0f8555333be6d09f5080b583f1","name":"node73","enode":"enode://99a7649bdf2ee7f0bc049308b0997e33abb68481c05a573df9aea30da5a1f267df07b2c584e3e985baf31704f04ad2a2c4876e0f8555333be6d09f5080b583f1@0.0.0.0:0","listenAddr":""}}},{"node":{"info":{"protocols":{"bzz":"isha/eDEb1MmncQoY+lZnP5+0MoyIuNxjYPqZIGUerM=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 8ac85a\npopulation: 24 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 5110 5fab | 135 2454 (0) 259d (0) 275c (0) 265d (0)\n001 8 c0d1 c9f3 d68f d3d2 | 65 d822 (0) d8b0 (0) dae3 (0) daa2 (0)\n002 1 bf5a | 30 a80b (0) abfa (0) aa88 (0) aa50 (0)\n003 5 9c0c 985c 9390 9232 | 16 9fee (0) 9eec (0) 9c01 (0) 9c0c (0)\n004 2 86f7 8163 | 3 8612 (0) 86f7 (0) 8163 (0)\n005 2 8c89 8c61 | 2 8c89 (0) 8c61 (0)\n============ DEPTH: 6 ==========================================\n006 3 89ee 8874 88da | 3 89ee (0) 8874 (0) 88da (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 1 8ae6 | 1 8ae6 (0)\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"discovery":0,"listener":0},"ip":"0.0.0.0","id":"b1dd1b08975319030626aab821032a0c687a103ee8942e8a2e2cf029dd72832a49630e78d2d8b184579f22178aca0e875f9fad701fb81afd2ac110ab2b417376","enode":"enode://b1dd1b08975319030626aab821032a0c687a103ee8942e8a2e2cf029dd72832a49630e78d2d8b184579f22178aca0e875f9fad701fb81afd2ac110ab2b417376@0.0.0.0:0","name":"node74","listenAddr":""},"up":true,"config":{"id":"b1dd1b08975319030626aab821032a0c687a103ee8942e8a2e2cf029dd72832a49630e78d2d8b184579f22178aca0e875f9fad701fb81afd2ac110ab2b417376","private_key":"3ea7d8647b5a7f04bdae56288940cc9dc8289c49fcc4a1a79e9d3fd9a6ceab2a","services":["pss","bzz"],"name":"node74"}}},{"node":{"info":{"listenAddr":"","name":"node75","enode":"enode://93073da602d6326a48464a8b6890220b3aae0abf5b6961180f3aff2a14573c43411bd519d3e0012a646ec2977be18915d95a36d935a69f93985f5307ea4e3ebe@0.0.0.0:0","id":"93073da602d6326a48464a8b6890220b3aae0abf5b6961180f3aff2a14573c43411bd519d3e0012a646ec2977be18915d95a36d935a69f93985f5307ea4e3ebe","protocols":{"bzz":"X6t3L/+IPQTPfkcTJm+x6Y+hdG4S+usE6HvLN7i2EYc=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 5fab77\npopulation: 16 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 d68f 8ac8 | 121 d822 (0) d8b0 (0) daa2 (0) dae3 (0)\n001 1 0f5e | 73 388d (0) 396b (0) 3a4a (0) 3af3 (0)\n002 1 6330 | 31 7d45 (0) 7d94 (0) 7dc6 (0) 7de7 (0)\n003 3 4af7 46c5 4019 | 17 487e (0) 4a67 (0) 4a81 (0) 4a82 (0)\n004 5 566e 5716 57d5 5093 | 9 5261 (0) 5288 (0) 5093 (0) 5110 (0)\n005 0 | 0\n006 1 5c5d | 1 5c5d (0)\n007 0 | 0\n008 1 5f05 | 1 5f05 (0)\n============ DEPTH: 9 ==========================================\n009 1 5fd0 | 1 5fd0 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 1 5fa8 | 1 5fa8 (0)\n015 0 | 0\n========================================================================="},"ip":"0.0.0.0","ports":{"discovery":0,"listener":0}},"up":true,"config":{"private_key":"86dd972691e02a4562fde8ab7cfa9ceb75201e42e506cf2d51c16d9d474bad2d","id":"93073da602d6326a48464a8b6890220b3aae0abf5b6961180f3aff2a14573c43411bd519d3e0012a646ec2977be18915d95a36d935a69f93985f5307ea4e3ebe","name":"node75","services":["pss","bzz"]}}},{"node":{"config":{"name":"node76","services":["pss","bzz"],"private_key":"cb578a8fabe87c91b214032286af35c973b3f27880dd80fcd1efb929d1dd4756","id":"431644cf162bc267237c4e798288888dd835c1b0546b0cc679782e33568988d75b4294f4aa08359a6b152ed9a0fbd13133681156bcf09a871c4f362615ea6dae"},"up":true,"info":{"listenAddr":"","enode":"enode://431644cf162bc267237c4e798288888dd835c1b0546b0cc679782e33568988d75b4294f4aa08359a6b152ed9a0fbd13133681156bcf09a871c4f362615ea6dae@0.0.0.0:0","name":"node76","id":"431644cf162bc267237c4e798288888dd835c1b0546b0cc679782e33568988d75b4294f4aa08359a6b152ed9a0fbd13133681156bcf09a871c4f362615ea6dae","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 0f5e34\npopulation: 20 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 fa74 d3d2 | 121 aca1 (0) adfc (0) ad36 (0) ae65 (0)\n001 6 72ac 6330 4019 5110 | 62 7d45 (0) 7d94 (0) 7dc6 (0) 7de7 (0)\n002 2 3648 265d | 35 396b (0) 388d (0) 3a4a (0) 3af3 (0)\n003 2 1a83 13d8 | 26 1e42 (0) 1e44 (0) 1c98 (0) 1da3 (0)\n004 5 03f5 06aa 0592 05ec | 8 004e (0) 0210 (0) 03f5 (0) 06aa (0)\n005 0 | 0\n006 0 | 0\n============ DEPTH: 7 ==========================================\n007 2 0eee 0ea2 | 2 0eee (0) 0ea2 (0)\n008 1 0f81 | 1 0f81 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"D140sl9oUdDztXLGRCDeCuwBdUvqCFS9fpkQtLHMZsM="},"ports":{"listener":0,"discovery":0},"ip":"0.0.0.0"}}},{"node":{"info":{"protocols":{"bzz":"09JUowJKeqwB6XpfCv8TdWdBhn5Zm8lMBo8NHRnKgXY=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: d3d254\npopulation: 18 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 4019 6330 0f5e | 135 7a41 (0) 7851 (0) 7854 (0) 7829 (0)\n001 1 8ac8 | 56 a80b (0) aa88 (0) aa50 (0) abfa (0)\n002 2 f4e0 fa74 | 29 e3c9 (0) e787 (0) e76a (0) e649 (0)\n003 2 c9f3 c0d1 | 18 ceee (0) cb69 (0) ca81 (0) c8fe (0)\n004 4 dae3 dc3e df25 df5e | 11 d822 (0) d8b0 (0) daa2 (0) dae3 (0)\n============ DEPTH: 5 ==========================================\n005 5 d564 d7ab d6d2 d6f3 | 5 d564 (0) d7ab (0) d6d2 (0) d6f3 (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 1 d3fd | 1 d3fd (0)\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ip":"0.0.0.0","ports":{"listener":0,"discovery":0},"id":"c63b88f494b14d5a7c1da124ffebbd985d19806b91d4b111c83ae129c4ef19614469980a09fbeccebe3b0358dd16194bdb6452d0b3dbb43a5467e23bb13f40d6","name":"node77","enode":"enode://c63b88f494b14d5a7c1da124ffebbd985d19806b91d4b111c83ae129c4ef19614469980a09fbeccebe3b0358dd16194bdb6452d0b3dbb43a5467e23bb13f40d6@0.0.0.0:0","listenAddr":""},"up":true,"config":{"private_key":"d4921582200b69793cc182b16d32031dd9559865007b31b1011d35512379ae8a","id":"c63b88f494b14d5a7c1da124ffebbd985d19806b91d4b111c83ae129c4ef19614469980a09fbeccebe3b0358dd16194bdb6452d0b3dbb43a5467e23bb13f40d6","name":"node77","services":["pss","bzz"]}}},{"node":{"up":true,"config":{"name":"node78","services":["pss","bzz"],"private_key":"286143c4711912830a900f8a45b11baa1bef2b6b96e9a918484cb95aafd2164f","id":"70cce7cb0c18091dbb6d41160ab560935f1759b969bf8118cee030ee707cb15ba407b8c48dcd9fd012cbf778e219f7d16a74064b4983cf098fb118297748edb6"},"info":{"enode":"enode://70cce7cb0c18091dbb6d41160ab560935f1759b969bf8118cee030ee707cb15ba407b8c48dcd9fd012cbf778e219f7d16a74064b4983cf098fb118297748edb6@0.0.0.0:0","name":"node78","listenAddr":"","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 63304d\npopulation: 24 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 f4e0 d3d2 9232 | 121 ecd2 (0) edca (0) ed65 (0) ed13 (0)\n001 4 3648 2f22 1a83 0f5e | 73 388d (0) 396b (0) 3a4a (0) 3af3 (0)\n002 3 5fab 4019 4b00 | 31 5c5d (0) 5f05 (0) 5fd0 (0) 5fa8 (0)\n003 6 759e 72ac 7307 7de7 | 20 7d45 (0) 7d94 (0) 7dc6 (0) 7de7 (0)\n004 2 6d21 6ea5 | 3 6d21 (0) 6dbd (0) 6ea5 (0)\n005 4 6544 67a2 6783 670d | 5 6544 (0) 6610 (0) 67a2 (0) 6783 (0)\n============ DEPTH: 6 ==========================================\n006 2 604c 6143 | 2 604c (0) 6143 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"YzBN+OmWD3qRphhc4Ptp5wYfJke54hzOEjfwh840p4o="},"ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"id":"70cce7cb0c18091dbb6d41160ab560935f1759b969bf8118cee030ee707cb15ba407b8c48dcd9fd012cbf778e219f7d16a74064b4983cf098fb118297748edb6"}}},{"node":{"info":{"ports":{"listener":0,"discovery":0},"protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 92325e\npopulation: 11 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 6330 | 135 388d (0) 396b (0) 3a4a (0) 3af3 (0)\n001 1 c0d1 | 65 e3c9 (0) e76a (0) e787 (0) e649 (0)\n002 1 baf3 | 30 a80b (0) abfa (0) aa88 (0) aa50 (0)\n003 3 88da 8ac8 8163 | 10 8c89 (0) 8c61 (0) 8ae6 (0) 8ac8 (0)\n004 1 985c | 9 9fee (0) 9eec (0) 9c01 (0) 9c0c (0)\n005 2 9461 96b6 | 4 95e0 (0) 94aa (0) 9461 (0) 96b6 (0)\n006 0 | 0\n============ DEPTH: 7 ==========================================\n007 1 9390 | 1 9390 (0)\n008 1 9294 | 1 9294 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"kjJeUrq78riuPDe+7H5EDRHv7S0QO++ixKlpMVouq1Y="},"ip":"0.0.0.0","id":"3376cfc924fef1a45aae35d106439b131f363b3a42904b3974cc7cddde325441cce8551729dd62f1119120b0d452e78f063e8e711ecacdc27d9087aac5ab09b5","name":"node79","enode":"enode://3376cfc924fef1a45aae35d106439b131f363b3a42904b3974cc7cddde325441cce8551729dd62f1119120b0d452e78f063e8e711ecacdc27d9087aac5ab09b5@0.0.0.0:0","listenAddr":""},"up":true,"config":{"name":"node79","services":["pss","bzz"],"private_key":"48d763e65d8c5b6a83609844cf203d410e1afa134af6eb6ed22a42bbfd55ccb9","id":"3376cfc924fef1a45aae35d106439b131f363b3a42904b3974cc7cddde325441cce8551729dd62f1119120b0d452e78f063e8e711ecacdc27d9087aac5ab09b5"}}},{"node":{"info":{"name":"node80","enode":"enode://bab07c2e4dc09add884869b31fb474b6d7151f9cc331d831f55c2b088397370fb0a1e1592c8dff9c8bc8e83de9faf6e91683acfb2df1b41856d70e523a99d370@0.0.0.0:0","listenAddr":"","ip":"0.0.0.0","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: c0d1ac\npopulation: 19 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 57d5 46c5 | 135 388d (0) 396b (0) 3a4a (0) 3af3 (0)\n001 3 8ac8 9294 9232 | 56 a80b (0) abfa (0) aa88 (0) aa50 (0)\n002 6 e839 f0e2 f4e0 f924 | 29 e3c9 (0) e76a (0) e787 (0) e649 (0)\n003 3 df5e d3d2 d68f | 18 d822 (0) d8b0 (0) daa2 (0) dae3 (0)\n004 1 c9f3 | 9 ceee (0) cb69 (0) ca81 (0) c8fe (0)\n005 2 c484 c64f | 6 c463 (0) c484 (0) c770 (0) c723 (0)\n============ DEPTH: 6 ==========================================\n006 1 c3f3 | 1 c3f3 (0)\n007 1 c15d | 1 c15d (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"wNGsQwoUZqGijLGqPSlXPM7bE2QawZ5uYV8qlujwlQs="},"ports":{"listener":0,"discovery":0},"id":"bab07c2e4dc09add884869b31fb474b6d7151f9cc331d831f55c2b088397370fb0a1e1592c8dff9c8bc8e83de9faf6e91683acfb2df1b41856d70e523a99d370"},"config":{"services":["pss","bzz"],"name":"node80","id":"bab07c2e4dc09add884869b31fb474b6d7151f9cc331d831f55c2b088397370fb0a1e1592c8dff9c8bc8e83de9faf6e91683acfb2df1b41856d70e523a99d370","private_key":"98a9e2aaeb4c53a781d4150faa14cc0ff5f066e7be28098cbc25a0c379be18a4"},"up":true}},{"node":{"info":{"ip":"0.0.0.0","protocols":{"bzz":"RsWiZt1GBBpi8hlGKQqtc20imCd7u7FrHvtEkNnTH6g=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 46c5a2\npopulation: 18 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 9294 c0d1 | 121 e3c9 (0) e76a (0) e787 (0) e649 (0)\n001 2 05ec 275c | 73 123f (0) 12b9 (0) 13d8 (0) 1566 (0)\n002 3 72ac 759e 7829 | 31 6d21 (0) 6dbd (0) 6ea5 (0) 6544 (0)\n003 3 5fab 566e 57d5 | 14 5261 (0) 5288 (0) 5093 (0) 5110 (0)\n004 4 4cf6 4b00 4a67 4af7 | 10 4fd6 (0) 4f90 (0) 4d44 (0) 4cf6 (0)\n005 2 43af 4019 | 4 42c0 (0) 42d4 (0) 43af (0) 4019 (0)\n============ DEPTH: 6 ==========================================\n006 1 458a | 1 458a (0)\n007 1 47f9 | 1 47f9 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"listener":0,"discovery":0},"id":"ecb93d8eba17afe92979e8154252a08dd58de6ff3188b6829e3e25967846686f54199ab2b081e77b0048dcab204f05aa2c5cbd0efae4bc43a612d471d4e1197b","name":"node81","enode":"enode://ecb93d8eba17afe92979e8154252a08dd58de6ff3188b6829e3e25967846686f54199ab2b081e77b0048dcab204f05aa2c5cbd0efae4bc43a612d471d4e1197b@0.0.0.0:0","listenAddr":""},"up":true,"config":{"private_key":"97df41163f6dfeb248b196fff24b95edb55e2b6c48c551480226459fde0ce62a","id":"ecb93d8eba17afe92979e8154252a08dd58de6ff3188b6829e3e25967846686f54199ab2b081e77b0048dcab204f05aa2c5cbd0efae4bc43a612d471d4e1197b","name":"node81","services":["pss","bzz"]}}},{"node":{"info":{"listenAddr":"","name":"node82","enode":"enode://52cf04f88d8b00214f11f329ebacca69291958372aa8ccfbe3cfdbc03d51d90389f3c307b82c108f0c074d78aeac0b48e8b8c8f3bf3b20b21d9747f284075de2@0.0.0.0:0","id":"52cf04f88d8b00214f11f329ebacca69291958372aa8ccfbe3cfdbc03d51d90389f3c307b82c108f0c074d78aeac0b48e8b8c8f3bf3b20b21d9747f284075de2","protocols":{"bzz":"J1yTZ3rv2Sqzj55bW00p+Q6AnMr3ewiBAgcauiZCHz4=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 275c93\npopulation: 13 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 9294 | 121 ddf8 (0) dc86 (0) dc3e (0) def4 (0)\n001 1 46c5 | 62 6330 (0) 604c (0) 6143 (0) 6544 (0)\n002 2 06aa 05ec | 38 123f (0) 12b9 (0) 13d8 (0) 1566 (0)\n003 1 3f3e | 15 3345 (0) 32dd (0) 31ed (0) 34fc (0)\n004 2 29fd 2e9f | 11 2af0 (0) 2a69 (0) 2a22 (0) 290f (0)\n005 3 2279 2013 211a | 5 2374 (0) 2279 (0) 2013 (0) 2168 (0)\n============ DEPTH: 6 ==========================================\n006 2 2454 259d | 2 2454 (0) 259d (0)\n007 1 265d | 1 265d (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"listener":0,"discovery":0},"ip":"0.0.0.0"},"config":{"id":"52cf04f88d8b00214f11f329ebacca69291958372aa8ccfbe3cfdbc03d51d90389f3c307b82c108f0c074d78aeac0b48e8b8c8f3bf3b20b21d9747f284075de2","private_key":"887a82d3553c5107cd8d6220f2ac36ca2d6d499b8c82b765a17bd6295e9861d4","services":["pss","bzz"],"name":"node82"},"up":true}},{"node":{"up":true,"config":{"id":"48e35d67e14ee2f329c0275bc965829b761885dbc3671f4673d84d76d18a5b6415e619e219b5d90761a5c6bd2f43c6a58708286a063daf46b502944f8ef9230b","private_key":"b067efa25d200683b69e2fa485be6ac0a6bbc34a18796bc0b0e794d4dadf83b1","services":["pss","bzz"],"name":"node83"},"info":{"name":"node83","enode":"enode://48e35d67e14ee2f329c0275bc965829b761885dbc3671f4673d84d76d18a5b6415e619e219b5d90761a5c6bd2f43c6a58708286a063daf46b502944f8ef9230b@0.0.0.0:0","listenAddr":"","protocols":{"bzz":"kpTls5oc1CMEAOAz2hrB95pAJa2rQc6MDg5H3aJBjLU=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 9294e5\npopulation: 15 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 46c5 05ec 2e9f 275c | 135 4fd6 (0) 4f90 (0) 4d44 (0) 4cf6 (0)\n001 2 c0d1 f0e2 | 65 d822 (0) d8b0 (0) daa2 (0) dae3 (0)\n002 3 a749 baf3 b79f | 30 a80b (0) abfa (0) aa88 (0) aa50 (0)\n003 1 8ac8 | 10 8612 (0) 86f7 (0) 8163 (0) 8c89 (0)\n004 1 985c | 9 9fee (0) 9eec (0) 9c01 (0) 9c0c (0)\n005 2 95e0 96b6 | 4 95e0 (0) 9461 (0) 94aa (0) 96b6 (0)\n006 0 | 0\n============ DEPTH: 7 ==========================================\n007 1 9390 | 1 9390 (0)\n008 1 9232 | 1 9232 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ip":"0.0.0.0","ports":{"listener":0,"discovery":0},"id":"48e35d67e14ee2f329c0275bc965829b761885dbc3671f4673d84d76d18a5b6415e619e219b5d90761a5c6bd2f43c6a58708286a063daf46b502944f8ef9230b"}}},{"node":{"info":{"name":"node84","enode":"enode://4ff2981a47da46c753090e193a8bf43c3372a6b07a37cf0552de2ced455fbb8a76d969cd97b3e4601d8a808bd2a73f7729ed8a61df2f2a0c2cee1425d0bd9ab4@0.0.0.0:0","listenAddr":"","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 05ec2c\npopulation: 22 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 b79f 985c 9294 | 121 ddf8 (0) dc86 (0) dc3e (0) def4 (0)\n001 3 7829 46c5 4af7 | 62 7307 (0) 72fa (0) 7294 (0) 72ac (0)\n002 4 275c 2279 211a 2e9f | 35 3345 (0) 32dd (0) 31ed (0) 34fc (0)\n003 4 1673 1d07 1a83 18f9 | 26 123f (0) 12b9 (0) 13d8 (0) 1566 (0)\n004 3 0eee 0f81 0f5e | 4 0eee (0) 0ea2 (0) 0f81 (0) 0f5e (0)\n005 1 03f5 | 3 004e (0) 0210 (0) 03f5 (0)\n006 1 06aa | 1 06aa (0)\n007 1 043f | 1 043f (0)\n008 0 | 0\n============ DEPTH: 9 ==========================================\n009 1 0592 | 1 0592 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 1 05e8 | 1 05e8 (0)\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"Bewshcg7u47e66mP0u9LdlEU9dw2qIF19QF8CeQ7elo="},"ports":{"listener":0,"discovery":0},"ip":"0.0.0.0","id":"4ff2981a47da46c753090e193a8bf43c3372a6b07a37cf0552de2ced455fbb8a76d969cd97b3e4601d8a808bd2a73f7729ed8a61df2f2a0c2cee1425d0bd9ab4"},"config":{"services":["pss","bzz"],"name":"node84","id":"4ff2981a47da46c753090e193a8bf43c3372a6b07a37cf0552de2ced455fbb8a76d969cd97b3e4601d8a808bd2a73f7729ed8a61df2f2a0c2cee1425d0bd9ab4","private_key":"f2b10950651367c628d1675c7a07962c0af4062b2c3c8154075cf61f9635cd67"},"up":true}},{"node":{"info":{"name":"node85","enode":"enode://6909a0fa47718cfc463b1e96c21734b46bd5b28dd59cd3d66d67990783436b7538ab2659d427029b97c8dddf313b26532518c0c34a2b1fca8cd852b0fdb83ab8@0.0.0.0:0","listenAddr":"","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 2e9f7d\npopulation: 19 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 a749 9294 | 121 d564 (0) d7ab (0) d6d2 (0) d6f3 (0)\n001 2 7829 4af7 | 62 7307 (0) 72fa (0) 7294 (0) 72ac (0)\n002 3 18f9 06aa 05ec | 38 123f (0) 12b9 (0) 13d8 (0) 1566 (0)\n003 3 3648 32dd 31ed | 15 3345 (0) 32dd (0) 31ed (0) 3538 (0)\n004 3 275c 2279 211a | 9 2454 (0) 259d (0) 265d (0) 275c (0)\n005 2 29ff 29fd | 6 2a69 (0) 2a22 (0) 2af0 (0) 290f (0)\n006 0 | 0\n============ DEPTH: 7 ==========================================\n007 3 2f9f 2fd8 2f22 | 3 2f9f (0) 2fd8 (0) 2f22 (0)\n008 1 2e4c | 1 2e4c (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"Lp99NxBrWdb0Ed+gOSMl0fonn+RcGKEB4y7OZxboiUY="},"ports":{"listener":0,"discovery":0},"ip":"0.0.0.0","id":"6909a0fa47718cfc463b1e96c21734b46bd5b28dd59cd3d66d67990783436b7538ab2659d427029b97c8dddf313b26532518c0c34a2b1fca8cd852b0fdb83ab8"},"config":{"id":"6909a0fa47718cfc463b1e96c21734b46bd5b28dd59cd3d66d67990783436b7538ab2659d427029b97c8dddf313b26532518c0c34a2b1fca8cd852b0fdb83ab8","private_key":"55f59b8404f62f76682812c128cde0b37da46140d69661f3de90af132daa04c8","services":["pss","bzz"],"name":"node85"},"up":true}},{"node":{"info":{"ip":"0.0.0.0","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 4af7cc\npopulation: 28 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 7 c64f f5dd f0e2 e3c9 | 121 d8b0 (0) d822 (0) daa2 (0) dae3 (0)\n001 5 18f9 05ec 211a 2279 | 73 123f (0) 12b9 (0) 13d8 (0) 1441 (0)\n002 2 6ea5 7829 | 31 6544 (0) 6610 (0) 670d (0) 67a2 (0)\n003 4 5110 5716 57d5 5fab | 14 5c5d (0) 5f05 (0) 5fd0 (0) 5fa8 (0)\n004 4 43af 4019 458a 46c5 | 7 4019 (0) 42d4 (0) 42c0 (0) 43af (0)\n005 1 4cf6 | 4 4f90 (0) 4fd6 (0) 4d44 (0) 4cf6 (0)\n006 1 487e | 1 487e (0)\n007 1 4b00 | 1 4b00 (0)\n008 1 4a67 | 1 4a67 (0)\n============ DEPTH: 9 ==========================================\n009 2 4a81 4a82 | 2 4a81 (0) 4a82 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"SvfMtcFO/LJ5UC3jf0Nldu7ele++VkHxL0fpmyvZoXI="},"ports":{"listener":0,"discovery":0},"id":"b9c7b885430b9b1a4425bde30b3629559f5437e0e30a0299fc6f6e097cbcca8af9e285caf5dea685a0237f60e06f490c39a1e3e487f14a2b9f41a5135f2ba994","name":"node86","enode":"enode://b9c7b885430b9b1a4425bde30b3629559f5437e0e30a0299fc6f6e097cbcca8af9e285caf5dea685a0237f60e06f490c39a1e3e487f14a2b9f41a5135f2ba994@0.0.0.0:0","listenAddr":""},"up":true,"config":{"id":"b9c7b885430b9b1a4425bde30b3629559f5437e0e30a0299fc6f6e097cbcca8af9e285caf5dea685a0237f60e06f490c39a1e3e487f14a2b9f41a5135f2ba994","private_key":"bc5bbbdd85ae3b09a493f0b43542448acf2976654a249f32bf92eff0d414866c","services":["pss","bzz"],"name":"node86"}}},{"node":{"up":true,"config":{"name":"node87","services":["pss","bzz"],"private_key":"f342c7683da21156a1f53ce673f78414f580cdd86eda879596d087439e4475f9","id":"da22fb43c6d230d92f9c09454e282dc45dffc759740566039f1bdfb58171c6801f721841de83217277b3fb70983e7d34da53bbf25d1d45413a78d9afff151826"},"info":{"enode":"enode://da22fb43c6d230d92f9c09454e282dc45dffc759740566039f1bdfb58171c6801f721841de83217277b3fb70983e7d34da53bbf25d1d45413a78d9afff151826@0.0.0.0:0","name":"node87","listenAddr":"","protocols":{"bzz":"eClnPuwLQT1iuwYYTnQAQuJS07aLPRzBdL8B4y+Hc28=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 782967\npopulation: 23 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 5 c64f f5dd e3c9 bfec | 121 def4 (0) de82 (0) df5e (0) df25 (0)\n001 5 2e9f 2279 211a 18f9 | 73 123f (0) 12b9 (0) 13d8 (0) 1566 (0)\n002 2 46c5 4af7 | 31 5c5d (0) 5f05 (0) 5fd0 (0) 5fa8 (0)\n003 1 6ea5 | 11 6544 (0) 6610 (0) 670d (0) 67a2 (0)\n004 1 759e | 8 7307 (0) 72fa (0) 7294 (0) 72ac (0)\n005 4 7de7 7d45 7fa4 7ffe | 6 7d94 (0) 7dc6 (0) 7de7 (0) 7d45 (0)\n006 1 7a41 | 1 7a41 (0)\n007 2 79bd 79ab | 2 79bd (0) 79ab (0)\n008 0 | 0\n============ DEPTH: 9 ==========================================\n009 2 7851 7854 | 2 7851 (0) 7854 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"discovery":0,"listener":0},"ip":"0.0.0.0","id":"da22fb43c6d230d92f9c09454e282dc45dffc759740566039f1bdfb58171c6801f721841de83217277b3fb70983e7d34da53bbf25d1d45413a78d9afff151826"}}},{"node":{"info":{"enode":"enode://588df3185f63a5443d8c6b972f67805f0557184d916005f537a4b27cd02bd6a12e432a2b34b234a34f22e923c6f116da85be20bad77a2bf69913684e9d0732ba@0.0.0.0:0","name":"node88","listenAddr":"","ip":"0.0.0.0","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 985c14\npopulation: 19 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 5 05ec 211a 4af7 6ea5 | 135 12b9 (0) 123f (0) 13d8 (0) 1441 (0)\n001 1 f0e2 | 65 d822 (0) d8b0 (0) daa2 (0) dae3 (0)\n002 2 b79f a749 | 30 bc08 (0) be0a (0) bfec (0) bf5a (0)\n003 1 8ac8 | 10 86f7 (0) 8612 (0) 8163 (0) 8c89 (0)\n004 5 94aa 96b6 9390 9232 | 7 96b6 (0) 95e0 (0) 9461 (0) 94aa (0)\n005 1 9c0c | 4 9eec (0) 9fee (0) 9c01 (0) 9c0c (0)\n006 1 9a82 | 1 9a82 (0)\n============ DEPTH: 7 ==========================================\n007 3 99aa 99db 99fb | 3 99aa (0) 99db (0) 99fb (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"mFwUkQ2SK70VVsMGIOOrchcNplU+ZY3TgG13OnNKHJM="},"ports":{"listener":0,"discovery":0},"id":"588df3185f63a5443d8c6b972f67805f0557184d916005f537a4b27cd02bd6a12e432a2b34b234a34f22e923c6f116da85be20bad77a2bf69913684e9d0732ba"},"config":{"id":"588df3185f63a5443d8c6b972f67805f0557184d916005f537a4b27cd02bd6a12e432a2b34b234a34f22e923c6f116da85be20bad77a2bf69913684e9d0732ba","private_key":"f9550b9a11e9aece642e0e863b82852f4c5c8cb6044144627d678ce3988cda39","services":["pss","bzz"],"name":"node88"},"up":true}},{"node":{"up":true,"config":{"name":"node89","services":["pss","bzz"],"private_key":"111dc027f4345175a5a141eff93a8d04d82ec6d67a15d0ed0c53ae7fe954868c","id":"c29e80096fbe7bc9fcbfdbe3cf6c06449192a3ed280e46a1fa5d424428d893c3456c985c1352c119236cf783834365439751cc87e7ed196614705dd3db6674cf"},"info":{"enode":"enode://c29e80096fbe7bc9fcbfdbe3cf6c06449192a3ed280e46a1fa5d424428d893c3456c985c1352c119236cf783834365439751cc87e7ed196614705dd3db6674cf@0.0.0.0:0","name":"node89","listenAddr":"","ports":{"listener":0,"discovery":0},"protocols":{"bzz":"bqWbhJqXVMAiIZFG78J/plYeWsqDOKERhHJZaVGYJns=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 6ea59b\npopulation: 17 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 985c | 121 d8b0 (0) d822 (0) daa2 (0) dae3 (0)\n001 1 211a | 73 123f (0) 12b9 (0) 13d8 (0) 14c8 (0)\n002 1 4af7 | 31 5c5d (0) 5f05 (0) 5fd0 (0) 5fa8 (0)\n003 5 7307 759e 7ffe 7fa4 | 20 7307 (0) 72fa (0) 7294 (0) 72ac (0)\n004 7 6544 670d 67a2 6783 | 8 6544 (0) 6610 (2) 670d (0) 67a2 (0)\n005 0 | 0\n============ DEPTH: 6 ==========================================\n006 2 6d21 6dbd | 2 6d21 (0) 6dbd (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ip":"0.0.0.0","id":"c29e80096fbe7bc9fcbfdbe3cf6c06449192a3ed280e46a1fa5d424428d893c3456c985c1352c119236cf783834365439751cc87e7ed196614705dd3db6674cf"}}},{"node":{"up":true,"config":{"private_key":"30caccc4af13ac896656ca1add341299bb51773c44f91f3105a1564abbe84f5b","id":"8ee65c0937cdf860d5329132c34bf28b5dc4d2593986fae80e4b35efb54ec24cdbf294223515363a917a22dbc6db463c10c7484e22b479b9010059c2521b6317","name":"node90","services":["pss","bzz"]},"info":{"listenAddr":"","name":"node90","enode":"enode://8ee65c0937cdf860d5329132c34bf28b5dc4d2593986fae80e4b35efb54ec24cdbf294223515363a917a22dbc6db463c10c7484e22b479b9010059c2521b6317@0.0.0.0:0","id":"8ee65c0937cdf860d5329132c34bf28b5dc4d2593986fae80e4b35efb54ec24cdbf294223515363a917a22dbc6db463c10c7484e22b479b9010059c2521b6317","protocols":{"bzz":"IRpRb7ldCT60P0cW7eseb3btedKu7jOTdA4kSXAYeEA=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 211a51\npopulation: 17 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 985c a749 | 121 d822 (0) d8b0 (0) daa2 (0) dae3 (0)\n001 3 4af7 7829 6ea5 | 62 5c5d (0) 5f05 (0) 5fd0 (0) 5fa8 (0)\n002 2 18f9 05ec | 38 123f (0) 12b9 (0) 13d8 (0) 14c8 (0)\n003 2 3f3e 3648 | 15 3345 (0) 32dd (0) 31ed (0) 34fc (0)\n004 1 2e9f | 11 2af0 (0) 2a69 (0) 2a22 (0) 290f (0)\n005 3 259d 265d 275c | 4 2454 (0) 259d (0) 265d (0) 275c (0)\n006 2 2374 2279 | 2 2374 (0) 2279 (0)\n============ DEPTH: 7 ==========================================\n007 1 2013 | 1 2013 (0)\n008 0 | 0\n009 1 2168 | 1 2168 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ip":"0.0.0.0","ports":{"listener":0,"discovery":0}}}},{"node":{"up":true,"config":{"id":"5717a49591a0ecdff3d4449874d5ff9ba016afad5da19712ca0c8ebca8cefd84e6d8c778245f67f68c8dd730ad294fd017b8de279fde4fc919768ce85dba132d","private_key":"ca298279e19e3d8437a361debb136898e8bf05c7946dd3ffdef8d267f1c79049","services":["pss","bzz"],"name":"node91"},"info":{"protocols":{"bzz":"p0k3LMy3ABpIC5QWxBMFvR07xBfhVmmuWH1DdfK7y/c=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: a74937\npopulation: 18 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 4af7 2e9f 211a | 135 5c5d (0) 5f05 (0) 5fd0 (0) 5fa8 (0)\n001 1 f0e2 | 65 d822 (0) d8b0 (0) daa2 (0) dae3 (0)\n002 3 9390 9294 985c | 26 8612 (0) 86f7 (0) 8163 (0) 8c89 (0)\n003 7 baf3 bf5a bfec b5c7 | 14 bc08 (0) be0a (0) bfec (0) bf5a (0)\n004 1 ad36 | 12 a80b (0) aa88 (0) aa50 (0) abfa (0)\n005 1 a033 | 1 a033 (0)\n============ DEPTH: 6 ==========================================\n006 1 a485 | 1 a485 (0)\n007 1 a672 | 1 a672 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"id":"5717a49591a0ecdff3d4449874d5ff9ba016afad5da19712ca0c8ebca8cefd84e6d8c778245f67f68c8dd730ad294fd017b8de279fde4fc919768ce85dba132d","enode":"enode://5717a49591a0ecdff3d4449874d5ff9ba016afad5da19712ca0c8ebca8cefd84e6d8c778245f67f68c8dd730ad294fd017b8de279fde4fc919768ce85dba132d@0.0.0.0:0","name":"node91","listenAddr":""}}},{"node":{"info":{"id":"224c3b969149d50d1bb4f473bb9725223c1dafe152efe1b08e8859213c543a66565b5d68a99cef3d5f4eccad6282a12f78d7b38eec14deebf44ad8dd9cba8680","protocols":{"bzz":"8OIJ9db2n1EJhghUYd3ilHUM8OfCkY8BpcFBmsYp3iI=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: f0e209\npopulation: 23 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 4af7 06aa | 135 5c5d (0) 5f05 (0) 5fd0 (0) 5fa8 (0)\n001 5 8ac8 985c 9294 b79f | 56 86f7 (0) 8612 (0) 8163 (0) 8c89 (0)\n002 2 c64f c0d1 | 36 d822 (0) d8b0 (0) daa2 (0) dae3 (0)\n003 1 e839 | 12 e839 (0) ecd2 (0) edca (0) ed13 (0)\n004 3 fd2d fb93 fa74 | 6 fd2d (0) fed1 (0) f915 (0) f924 (0)\n005 6 f78a f644 f5cc f5dd | 6 f78a (0) f644 (0) f5cc (0) f5dd (0)\n006 1 f3d3 | 1 f3d3 (0)\n============ DEPTH: 7 ==========================================\n007 2 f156 f1fc | 2 f1fc (0) f156 (0)\n008 1 f048 | 1 f048 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"discovery":0,"listener":0},"ip":"0.0.0.0","listenAddr":"","name":"node92","enode":"enode://224c3b969149d50d1bb4f473bb9725223c1dafe152efe1b08e8859213c543a66565b5d68a99cef3d5f4eccad6282a12f78d7b38eec14deebf44ad8dd9cba8680@0.0.0.0:0"},"up":true,"config":{"private_key":"d513af6f8087302defbc40f0f03c63b144c07a636b7c5c970e962d445232a6f9","id":"224c3b969149d50d1bb4f473bb9725223c1dafe152efe1b08e8859213c543a66565b5d68a99cef3d5f4eccad6282a12f78d7b38eec14deebf44ad8dd9cba8680","name":"node92","services":["pss","bzz"]}}},{"node":{"info":{"ip":"0.0.0.0","protocols":{"bzz":"t5/SbOl+mOdDICnepr8R5I6p6PI4XexcYL4MvVG771Q=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: b79fd2\npopulation: 14 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 05ec 18f9 | 135 5c5d (0) 5f05 (0) 5fd0 (0) 5fa8 (0)\n001 1 f0e2 | 65 d822 (0) d8b0 (0) daa2 (0) dae3 (0)\n002 2 985c 9294 | 26 8612 (0) 86f7 (0) 8163 (0) 8c89 (0)\n003 2 adfc a749 | 16 a80b (0) abfa (0) aa88 (0) aa50 (0)\n004 2 bfec baf3 | 6 bc08 (0) be0a (0) bfec (0) bf5a (0)\n005 1 b310 | 1 b310 (0)\n006 2 b5c7 b4c7 | 4 b45d (0) b463 (0) b4c7 (0) b5c7 (0)\n============ DEPTH: 7 ==========================================\n007 1 b60d | 1 b60d (0)\n008 1 b710 | 1 b710 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"listener":0,"discovery":0},"id":"c61ffc88f23f9f536497cc10ffcb7000ec6c4b801998ae7075ddc9079fdc1da8350e68744dc9e95ff892dfc5e52c62a3ad913a87fdacc455aea99b09aa002b57","name":"node93","enode":"enode://c61ffc88f23f9f536497cc10ffcb7000ec6c4b801998ae7075ddc9079fdc1da8350e68744dc9e95ff892dfc5e52c62a3ad913a87fdacc455aea99b09aa002b57@0.0.0.0:0","listenAddr":""},"config":{"private_key":"e5808b0004f64868225ce7362aa1b0d787d6c8bafbf5d08aadf4a804bfa4519a","id":"c61ffc88f23f9f536497cc10ffcb7000ec6c4b801998ae7075ddc9079fdc1da8350e68744dc9e95ff892dfc5e52c62a3ad913a87fdacc455aea99b09aa002b57","name":"node93","services":["pss","bzz"]},"up":true}},{"node":{"info":{"protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 18f929\npopulation: 18 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 bfec b79f | 121 d8b0 (0) d822 (0) daa2 (0) dae3 (0)\n001 2 4af7 7829 | 62 5261 (0) 5288 (0) 5093 (0) 5110 (0)\n002 3 3f3e 2e9f 211a | 35 34fc (0) 3538 (0) 3648 (0) 3345 (0)\n003 2 05ec 06aa | 12 0eee (0) 0ea2 (0) 0f81 (0) 0f5e (0)\n004 2 13d8 1673 | 8 123f (0) 12b9 (0) 13d8 (0) 1566 (0)\n005 1 1d07 | 8 1e44 (0) 1e42 (0) 1c98 (0) 1da3 (0)\n006 2 1b86 1a83 | 5 1b1e (0) 1b72 (0) 1b86 (0) 1a02 (0)\n007 2 194a 193e | 2 194a (0) 193e (0)\n============ DEPTH: 8 ==========================================\n008 2 185a 1835 | 2 185a (0) 1835 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"GPkpL75ulOw99NColsce0rF3FDfkLYR1p6rmPHmSg00="},"ports":{"listener":0,"discovery":0},"ip":"0.0.0.0","id":"c402495c2110a6531a530ebdcd9ab1b883f1c707fe25aa13a255a0a9edb4113669b4aee9eadf803f9fe4c2ef66d5e4dff7064549f672598410f2d9794747a600","enode":"enode://c402495c2110a6531a530ebdcd9ab1b883f1c707fe25aa13a255a0a9edb4113669b4aee9eadf803f9fe4c2ef66d5e4dff7064549f672598410f2d9794747a600@0.0.0.0:0","name":"node94","listenAddr":""},"up":true,"config":{"id":"c402495c2110a6531a530ebdcd9ab1b883f1c707fe25aa13a255a0a9edb4113669b4aee9eadf803f9fe4c2ef66d5e4dff7064549f672598410f2d9794747a600","private_key":"68c381bcacc6c4396824a929cd7124a13b8032185de88ce2cc3cb75badc6a5d5","services":["pss","bzz"],"name":"node94"}}},{"node":{"up":true,"config":{"private_key":"0d0d4c6da032e6ceb496ec71883cff52efa41a9383d2b83b747d1bc6f8269a17","id":"6ad4ea3730ddec500e56248d1025aea79ec10f0d6a9720ee48026df10e219b41965d7a611fd99ee765f6afbc8c977db7e67c3a340881904acb983d1e2fb016cc","name":"node95","services":["pss","bzz"]},"info":{"listenAddr":"","enode":"enode://6ad4ea3730ddec500e56248d1025aea79ec10f0d6a9720ee48026df10e219b41965d7a611fd99ee765f6afbc8c977db7e67c3a340881904acb983d1e2fb016cc@0.0.0.0:0","name":"node95","id":"6ad4ea3730ddec500e56248d1025aea79ec10f0d6a9720ee48026df10e219b41965d7a611fd99ee765f6afbc8c977db7e67c3a340881904acb983d1e2fb016cc","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 06aa2f\npopulation: 19 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 c64f f0e2 e3c9 | 121 d822 (0) d8b0 (0) daa2 (0) dae3 (0)\n001 1 57d5 | 62 5c5d (0) 5f05 (0) 5fd0 (0) 5fa8 (0)\n002 3 2e9f 275c 2279 | 35 3345 (0) 32dd (0) 31ed (0) 34fc (0)\n003 4 1673 1d07 1a83 18f9 | 26 123f (0) 12b9 (0) 13d8 (0) 1566 (0)\n004 3 0eee 0ea2 0f5e | 4 0eee (0) 0ea2 (0) 0f81 (0) 0f5e (0)\n005 1 03f5 | 3 004e (0) 0210 (0) 03f5 (0)\n============ DEPTH: 6 ==========================================\n006 4 043f 0592 05e8 05ec | 4 043f (0) 0592 (0) 05e8 (0) 05ec (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"BqovQ5Vvl4q+e4+PeKWozVney2bsVLfIGuUMN1J5jF4="},"ports":{"listener":0,"discovery":0},"ip":"0.0.0.0"}}},{"node":{"up":true,"config":{"name":"node96","services":["pss","bzz"],"private_key":"53c79eca1a5cc6b186db543273722c0168564d7cecceb76d1433330101f8e62a","id":"a48cd04cdc66e1bb182529a789e1417d60d5e7d0f73068c1b17c6f231defeb943357789123e8d89cad90d1dd1726c48b808300d213bc1ddf7ae43cd58527f1f3"},"info":{"enode":"enode://a48cd04cdc66e1bb182529a789e1417d60d5e7d0f73068c1b17c6f231defeb943357789123e8d89cad90d1dd1726c48b808300d213bc1ddf7ae43cd58527f1f3@0.0.0.0:0","name":"node96","listenAddr":"","ports":{"discovery":0,"listener":0},"protocols":{"bzz":"InnWEkVP8DQDKlrPWgOUd6EUebm5qT7cJrYTEujZsVY=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 2279d6\npopulation: 16 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 e3c9 | 121 a80b (0) abfa (0) aa88 (0) aa50 (0)\n001 2 7829 4af7 | 62 5c5d (0) 5f05 (0) 5fd0 (0) 5fa8 (0)\n002 3 1d07 05ec 06aa | 38 123f (0) 12b9 (0) 13d8 (0) 1566 (0)\n003 1 3f3e | 15 3345 (0) 32dd (0) 31ed (0) 34fc (0)\n004 3 29ff 29fd 2e9f | 11 2af0 (0) 2a69 (0) 2a22 (0) 290f (0)\n005 2 265d 275c | 4 2454 (0) 259d (0) 265d (0) 275c (0)\n============ DEPTH: 6 ==========================================\n006 3 2013 2168 211a | 3 2013 (0) 2168 (0) 211a (0)\n007 1 2374 | 1 2374 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ip":"0.0.0.0","id":"a48cd04cdc66e1bb182529a789e1417d60d5e7d0f73068c1b17c6f231defeb943357789123e8d89cad90d1dd1726c48b808300d213bc1ddf7ae43cd58527f1f3"}}},{"node":{"up":true,"config":{"private_key":"cd3e3585e9c28d16a0a5c11e8efd66671e8cac68915eb6b7bae228e10e867fd8","id":"e8a679f627d03347a4fcec0a0940f7ffa90ce3fefea290db3af4f3a32d27965bfb51832b6a6de2495c8a8cc026bcf993b84a0cced778e158bb81c034f5e4bd76","name":"node97","services":["pss","bzz"]},"info":{"listenAddr":"","enode":"enode://e8a679f627d03347a4fcec0a0940f7ffa90ce3fefea290db3af4f3a32d27965bfb51832b6a6de2495c8a8cc026bcf993b84a0cced778e158bb81c034f5e4bd76@0.0.0.0:0","name":"node97","id":"e8a679f627d03347a4fcec0a0940f7ffa90ce3fefea290db3af4f3a32d27965bfb51832b6a6de2495c8a8cc026bcf993b84a0cced778e158bb81c034f5e4bd76","protocols":{"bzz":"48lagvNz2kUiUzJSVJwdaLb3YhqIf+tmGZz9S3o1tvw=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: e3c95a\npopulation: 18 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 7829 4af7 06aa 2279 | 135 5c5d (0) 5f05 (0) 5fd0 (0) 5fa8 (0)\n001 1 bfec | 56 8163 (0) 86f7 (0) 8612 (0) 8c89 (0)\n002 2 c64f c3f3 | 36 ddf8 (0) dc86 (0) dc3e (0) de82 (0)\n003 1 f5dd | 17 fd2d (0) fed1 (0) f915 (0) f924 (0)\n004 4 e839 ecd2 edca ed65 | 5 e839 (0) ecd2 (0) edca (0) ed13 (0)\n============ DEPTH: 5 ==========================================\n005 6 e76a e787 e649 e67d | 6 e649 (0) e67d (0) e787 (0) e76a (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"listener":0,"discovery":0},"ip":"0.0.0.0"}}},{"node":{"info":{"listenAddr":"","enode":"enode://535287ca3d41fc1cdf20a964749a849c51d0aba285f41f447cc2b1dd6f5845b6b98e0241dbda0718b234ea850081bfbf9df01d1aa636d7dcbd99ef3c0a773aff@0.0.0.0:0","name":"node98","id":"535287ca3d41fc1cdf20a964749a849c51d0aba285f41f447cc2b1dd6f5845b6b98e0241dbda0718b234ea850081bfbf9df01d1aa636d7dcbd99ef3c0a773aff","ip":"0.0.0.0","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: bfeca8\npopulation: 19 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 18f9 1673 4af7 7829 | 135 5c5d (0) 5f05 (0) 5fd0 (0) 5fa8 (0)\n001 4 c64f c3f3 e3c9 f5dd | 65 def4 (0) de82 (0) df5e (0) df25 (0)\n002 1 9390 | 26 8612 (0) 86f7 (0) 8163 (0) 8c89 (0)\n003 2 a749 ad36 | 16 a033 (0) a485 (0) a672 (0) a749 (0)\n004 3 b79f b60d b4c7 | 8 b310 (0) b5c7 (0) b463 (0) b45d (0)\n005 2 b8a7 baf3 | 2 b8a7 (0) baf3 (0)\n006 1 bc08 | 1 bc08 (0)\n============ DEPTH: 7 ==========================================\n007 1 be0a | 1 be0a (0)\n008 1 bf5a | 1 bf5a (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"v+yomLF1WgAesLz49a1XE6VQ0Fl/me95Z+pOet2NPoE="},"ports":{"discovery":0,"listener":0}},"up":true,"config":{"id":"535287ca3d41fc1cdf20a964749a849c51d0aba285f41f447cc2b1dd6f5845b6b98e0241dbda0718b234ea850081bfbf9df01d1aa636d7dcbd99ef3c0a773aff","private_key":"60f513f00eb15da948e892d69bec82991bfb0747c9d5879c6c26c2a5a6095365","services":["pss","bzz"],"name":"node98"}}},{"node":{"info":{"ports":{"listener":0,"discovery":0},"protocols":{"bzz":"9d0A2USI8zh9ZMzCEVzZHlBzwG3jbRlaXBqV2yPNXGg=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: f5dd00\npopulation: 20 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 1673 7829 4af7 | 135 5c5d (0) 5f05 (0) 5fd0 (0) 5fa8 (0)\n001 1 bfec | 56 8612 (0) 86f7 (0) 8163 (0) 8c61 (0)\n002 2 c3f3 c64f | 36 d564 (0) d7ab (0) d6f3 (0) d6d2 (0)\n003 4 e839 ed65 e4c3 e3c9 | 12 e839 (0) ecd2 (0) edca (0) ed13 (0)\n004 3 fd2d f915 fa74 | 6 fed1 (0) fd2d (0) f915 (0) f924 (0)\n005 2 f1fc f0e2 | 5 f3d3 (0) f156 (0) f1fc (0) f048 (0)\n006 2 f78a f644 | 2 f78a (0) f644 (0)\n============ DEPTH: 7 ==========================================\n007 2 f4ee f4e0 | 2 f4ee (0) f4e0 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 1 f5cc | 1 f5cc (0)\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ip":"0.0.0.0","id":"29619924833116cb1160bf7a8066a528b7182794368bfae62b5bacbae680d9161a479f217e30c3b4f19a250b1b59e08f86c94726117dc3bc94ff9ceac6bee6e4","name":"node99","enode":"enode://29619924833116cb1160bf7a8066a528b7182794368bfae62b5bacbae680d9161a479f217e30c3b4f19a250b1b59e08f86c94726117dc3bc94ff9ceac6bee6e4@0.0.0.0:0","listenAddr":""},"up":true,"config":{"private_key":"94b0c348b1ec7288d57eb195f114f38da5a6fc3f604e8f1ed76135ef26f50c6d","id":"29619924833116cb1160bf7a8066a528b7182794368bfae62b5bacbae680d9161a479f217e30c3b4f19a250b1b59e08f86c94726117dc3bc94ff9ceac6bee6e4","name":"node99","services":["pss","bzz"]}}},{"node":{"info":{"enode":"enode://624248a794fd62248024360f128b2e503c752340694a316bed420e5ed2cebeb5bf970df95a2806732237a26de3778222b0454e2e7d2875129b193e7890fd5b95@0.0.0.0:0","name":"node100","listenAddr":"","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: c64f6b\npopulation: 24 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 6 7829 7294 4af7 06aa | 135 5288 (0) 5261 (0) 5093 (0) 5110 (0)\n001 2 9c0c bfec | 56 8612 (0) 86f7 (0) 8163 (0) 8c89 (0)\n002 4 e4c3 e3c9 f0e2 f5dd | 29 e839 (0) ecd2 (0) edca (0) ed13 (0)\n003 1 dae3 | 18 d564 (0) d7ab (0) d6f3 (0) d6d2 (0)\n004 3 c883 c99c c9f3 | 9 ceee (0) cb69 (0) ca81 (0) c8f9 (0)\n005 3 c15d c0d1 c3f3 | 3 c15d (0) c0d1 (0) c3f3 (0)\n006 2 c463 c484 | 2 c463 (0) c484 (0)\n============ DEPTH: 7 ==========================================\n007 2 c770 c723 | 2 c770 (0) c723 (0)\n008 0 | 0\n009 1 c63e | 1 c63e (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"xk9ryhXU7yGje2nI+L27v8NOLOD8YSy8apNzOcDMu9s="},"ports":{"listener":0,"discovery":0},"ip":"0.0.0.0","id":"624248a794fd62248024360f128b2e503c752340694a316bed420e5ed2cebeb5bf970df95a2806732237a26de3778222b0454e2e7d2875129b193e7890fd5b95"},"config":{"services":["pss","bzz"],"name":"node100","id":"624248a794fd62248024360f128b2e503c752340694a316bed420e5ed2cebeb5bf970df95a2806732237a26de3778222b0454e2e7d2875129b193e7890fd5b95","private_key":"a6e6ca4e3f494adc69bb1aaa01dfc3dd625d9923fa4c979ec80ee221b83a589b"},"up":true}},{"node":{"info":{"id":"5a6318af8b4615cf30610a05ade7704182fefd0a3fb3d76c47cb392e114d8d30004f0ec214326b11532fd1e928e66f632bbcde126a94c87774063853a9518dc5","ports":{"listener":0,"discovery":0},"protocols":{"bzz":"HQdSDwrOhf1y8UyIHz1qVRGQKyC24PeNKiYRkcByul0=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 1d0752\npopulation: 23 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 c64f | 121 8c61 (0) 8c89 (0) 8874 (0) 88da (0)\n001 3 7294 43af 458a | 62 6dbd (0) 6d21 (0) 6ea5 (0) 6143 (0)\n002 3 29fd 2279 3f3e | 35 2af0 (0) 2a69 (0) 2a22 (0) 290f (0)\n003 3 05e8 05ec 06aa | 12 0eee (0) 0ea2 (0) 0f81 (0) 0f5e (0)\n004 1 1673 | 8 123f (0) 12b9 (0) 13d8 (0) 1566 (0)\n005 5 1b72 1a83 193e 185a | 10 1b86 (0) 1b1e (0) 1b72 (0) 1a02 (0)\n006 2 1e42 1e44 | 2 1e42 (0) 1e44 (0)\n007 1 1c98 | 1 1c98 (0)\n============ DEPTH: 8 ==========================================\n008 3 1da3 1d94 1d93 | 3 1da3 (0) 1d94 (0) 1d93 (0)\n009 1 1d5f | 1 1d5f (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ip":"0.0.0.0","listenAddr":"","name":"node101","enode":"enode://5a6318af8b4615cf30610a05ade7704182fefd0a3fb3d76c47cb392e114d8d30004f0ec214326b11532fd1e928e66f632bbcde126a94c87774063853a9518dc5@0.0.0.0:0"},"config":{"id":"5a6318af8b4615cf30610a05ade7704182fefd0a3fb3d76c47cb392e114d8d30004f0ec214326b11532fd1e928e66f632bbcde126a94c87774063853a9518dc5","private_key":"2c11691d22adc7bee004f61ad67b543d9ca22c7c65125427e310fc5c8784091f","services":["pss","bzz"],"name":"node101"},"up":true}},{"node":{"info":{"listenAddr":"","name":"node102","enode":"enode://7dd2801259c071a6e1dcc01d1cb74775fdec92da1da0b1eaf5f893cd5ed118894493ca5284c12bbd6cf7959449bc610d26ac6c9ef2845d1645d425f56ac003fd@0.0.0.0:0","id":"7dd2801259c071a6e1dcc01d1cb74775fdec92da1da0b1eaf5f893cd5ed118894493ca5284c12bbd6cf7959449bc610d26ac6c9ef2845d1645d425f56ac003fd","ip":"0.0.0.0","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 458a31\npopulation: 16 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 e4c3 | 121 a033 (0) a485 (0) a749 (0) a672 (0)\n001 3 3f3e 1673 1d07 | 73 2af0 (0) 2a69 (0) 2a22 (0) 290f (0)\n002 4 7ffe 7406 77ec 7294 | 31 6dbd (0) 6d21 (0) 6ea5 (0) 6143 (0)\n003 1 5716 | 14 5c5d (0) 5f05 (0) 5fd0 (0) 5fa8 (0)\n004 2 487e 4af7 | 10 4d44 (0) 4cf6 (0) 4fd6 (0) 4f90 (0)\n005 3 4019 42d4 43af | 4 4019 (0) 42c0 (0) 42d4 (0) 43af (0)\n============ DEPTH: 6 ==========================================\n006 2 47f9 46c5 | 2 47f9 (0) 46c5 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"RYoxuP28QvXoDwERjJ3AQXQCEsCd37SxN8nn6Trp7FE="},"ports":{"listener":0,"discovery":0}},"config":{"id":"7dd2801259c071a6e1dcc01d1cb74775fdec92da1da0b1eaf5f893cd5ed118894493ca5284c12bbd6cf7959449bc610d26ac6c9ef2845d1645d425f56ac003fd","private_key":"1ebabfc78e1b9d17e6fe38508bc354ab54be2a8bf57483b0afe7dc3530533e0f","services":["pss","bzz"],"name":"node102"},"up":true}},{"node":{"up":true,"config":{"private_key":"9b22a93b1dd1ac5ad34771c2cf183292f9ca7133b4ed8a1d0fceb889d6017170","id":"a47697063a2fb973449bdabd0925e10944ba1f6d8b2cc5c38b295f611eea3402b5cf3ae857716a34d84194955f5ed61350affe56223349124c8233852141f9a2","name":"node103","services":["pss","bzz"]},"info":{"id":"a47697063a2fb973449bdabd0925e10944ba1f6d8b2cc5c38b295f611eea3402b5cf3ae857716a34d84194955f5ed61350affe56223349124c8233852141f9a2","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: e4c3fa\npopulation: 19 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 6 1673 3f3e 7294 77ec | 135 004e (0) 03f5 (0) 0210 (0) 06aa (0)\n001 2 b4c7 ad36 | 56 a033 (0) a485 (0) a672 (0) a749 (0)\n002 2 c3f3 c64f | 36 d564 (0) d7ab (0) d68f (0) d6f3 (0)\n003 1 f5dd | 17 f915 (0) f924 (0) fb93 (0) fa74 (0)\n004 2 e839 ed65 | 5 e839 (0) ecd2 (0) edca (0) ed13 (0)\n005 1 e3c9 | 1 e3c9 (0)\n============ DEPTH: 6 ==========================================\n006 4 e787 e76a e649 e67d | 4 e787 (0) e76a (0) e649 (0) e67d (0)\n007 0 | 0\n008 1 e44b | 1 e44b (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"5MP6BwBRbaVlD3lAZ+sckLp+qrK2UBm/NFUsJvjB2aY="},"ports":{"discovery":0,"listener":0},"ip":"0.0.0.0","listenAddr":"","enode":"enode://a47697063a2fb973449bdabd0925e10944ba1f6d8b2cc5c38b295f611eea3402b5cf3ae857716a34d84194955f5ed61350affe56223349124c8233852141f9a2@0.0.0.0:0","name":"node103"}}},{"node":{"info":{"listenAddr":"","name":"node104","enode":"enode://8e65496318637446a51f0dc87d0a5cf82655866cd1579db1e381af52e12545172b9c88119999ccac3b8b8644efc9675ff183ebe7584c16eb40792cc21f7e9b76@0.0.0.0:0","id":"8e65496318637446a51f0dc87d0a5cf82655866cd1579db1e381af52e12545172b9c88119999ccac3b8b8644efc9675ff183ebe7584c16eb40792cc21f7e9b76","ip":"0.0.0.0","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 3f3e66\npopulation: 20 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 e4c3 | 121 a033 (0) a485 (0) a749 (0) a672 (0)\n001 2 458a 77ec | 62 6d21 (0) 6dbd (0) 6ea5 (0) 604c (0)\n002 3 18f9 1d07 1673 | 38 0eee (0) 0ea2 (0) 0f81 (0) 0f5e (0)\n003 5 29fd 29ff 275c 211a | 20 2af0 (0) 2a69 (0) 2a22 (0) 290f (0)\n004 3 3648 32dd 31ed | 6 34fc (0) 3538 (0) 3648 (0) 3345 (0)\n005 2 388d 3af3 | 4 396b (0) 388d (0) 3a4a (0) 3af3 (0)\n006 2 3dca 3d6b | 2 3dca (0) 3d6b (0)\n============ DEPTH: 7 ==========================================\n007 2 3e85 3e44 | 2 3e85 (0) 3e44 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"Pz5m98j8farop6hKnJDx6mT6pDkw82/I8R4te3Ufjuk="},"ports":{"discovery":0,"listener":0}},"up":true,"config":{"services":["pss","bzz"],"name":"node104","id":"8e65496318637446a51f0dc87d0a5cf82655866cd1579db1e381af52e12545172b9c88119999ccac3b8b8644efc9675ff183ebe7584c16eb40792cc21f7e9b76","private_key":"b4d7978eed053b73224b969ad03abd7503081764e86f7815f8b650b7ba9a34b0"}}},{"node":{"info":{"listenAddr":"","name":"node105","enode":"enode://207764262a208c17db61fda4208d4664bf74010e0ad051a863e131e748c9304e11ccf007c925488ea86b974ee61cdac3dca4d4b3f4043524e03c194ab3c8eb5a@0.0.0.0:0","id":"207764262a208c17db61fda4208d4664bf74010e0ad051a863e131e748c9304e11ccf007c925488ea86b974ee61cdac3dca4d4b3f4043524e03c194ab3c8eb5a","protocols":{"bzz":"FnMG+w4k3dd1wqwHIhA85duYuw72AVm5H1hEddNMtb8=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 167306\npopulation: 18 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 bfec c64f f5dd e4c3 | 121 a033 (0) a485 (0) a672 (0) a749 (0)\n001 2 458a 77ec | 62 5c5d (0) 5f05 (0) 5fd0 (0) 5fa8 (0)\n002 1 3f3e | 35 2af0 (0) 2a22 (0) 2a69 (0) 290f (0)\n003 2 06aa 05ec | 12 0ea2 (0) 0eee (0) 0f81 (0) 0f5e (0)\n004 3 1a83 18f9 1d07 | 18 1b86 (0) 1b1e (0) 1b72 (0) 1a02 (0)\n005 2 12b9 13d8 | 3 123f (0) 12b9 (0) 13d8 (0)\n============ DEPTH: 6 ==========================================\n006 4 1441 14c8 1566 15f6 | 4 1441 (0) 14c8 (0) 1566 (0) 15f6 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"listener":0,"discovery":0},"ip":"0.0.0.0"},"up":true,"config":{"name":"node105","services":["pss","bzz"],"private_key":"18bbd14788534b3f7490b55c2243e84c1ed1d158bd769a47fdc2d8550098ba97","id":"207764262a208c17db61fda4208d4664bf74010e0ad051a863e131e748c9304e11ccf007c925488ea86b974ee61cdac3dca4d4b3f4043524e03c194ab3c8eb5a"}}},{"node":{"info":{"id":"33e9d4674b5b9b23e838583f01b429abca1330393dfc100b19ede6090a53df213011fae53169a66aa05d18e4cb497a17aa81eaedf1fe2e4348f9825c309438b5","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 77ec3a\npopulation: 15 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 e4c3 c3f3 | 121 a033 (0) a485 (0) a749 (0) a672 (0)\n001 2 3f3e 1673 | 73 2f9f (0) 2fd8 (0) 2f22 (0) 2e4c (0)\n002 2 43af 458a | 31 5c5d (0) 5f05 (0) 5fd0 (0) 5fa8 (0)\n003 2 670d 6783 | 11 6d21 (0) 6dbd (0) 6ea5 (0) 6143 (0)\n004 3 7dc6 7ffe 79ab | 12 7a41 (0) 7851 (0) 7854 (0) 7829 (0)\n005 1 7294 | 4 7307 (0) 72fa (0) 72ac (0) 7294 (0)\n============ DEPTH: 6 ==========================================\n006 3 759e 7471 7406 | 3 759e (0) 7471 (0) 7406 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"d+w6c84dWX0wfofqjQJrquKn300oimV/JA6qquf9tFY="},"ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","enode":"enode://33e9d4674b5b9b23e838583f01b429abca1330393dfc100b19ede6090a53df213011fae53169a66aa05d18e4cb497a17aa81eaedf1fe2e4348f9825c309438b5@0.0.0.0:0","name":"node106"},"up":true,"config":{"id":"33e9d4674b5b9b23e838583f01b429abca1330393dfc100b19ede6090a53df213011fae53169a66aa05d18e4cb497a17aa81eaedf1fe2e4348f9825c309438b5","private_key":"ff55b25abe67052213c916a734949cb6a98d1ad2f240183bfa1fe694cfa0937a","services":["pss","bzz"],"name":"node106"}}},{"node":{"config":{"services":["pss","bzz"],"name":"node107","id":"90b8e73916046b5433dce049bfe125ca2bf2fb390ff7301f9bc5d8d0183988577aa2a7392aaa28091aa81c8ac23942b5751420b9ee48e488a68411f9d2b1e5d5","private_key":"406c029264f74f39f2ad851342bc311d4800fe07db744f69557ad9e3e5899aeb"},"up":true,"info":{"ip":"0.0.0.0","protocols":{"bzz":"w/NWMl6x5h8s/Y2A0IX7FExoh+HXEMnRMxCbhLgjQl0=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: c3f356\npopulation: 21 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 7294 77ec | 135 0eee (0) 0ea2 (0) 0f81 (0) 0f5e (0)\n001 5 ad36 b60d bfec 9c0c | 56 a033 (0) a485 (0) a672 (0) a749 (0)\n002 4 ed65 e3c9 e4c3 f5dd | 29 fd2d (0) fed1 (0) f915 (0) f924 (0)\n003 1 d68f | 18 d564 (0) d7ab (0) d6f3 (0) d6d2 (0)\n004 3 c99c c9f3 c883 | 9 ceee (0) cb69 (0) ca81 (0) c8fe (0)\n005 4 c484 c723 c63e c64f | 6 c463 (0) c484 (0) c770 (0) c723 (0)\n============ DEPTH: 6 ==========================================\n006 2 c15d c0d1 | 2 c15d (0) c0d1 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"listener":0,"discovery":0},"id":"90b8e73916046b5433dce049bfe125ca2bf2fb390ff7301f9bc5d8d0183988577aa2a7392aaa28091aa81c8ac23942b5751420b9ee48e488a68411f9d2b1e5d5","enode":"enode://90b8e73916046b5433dce049bfe125ca2bf2fb390ff7301f9bc5d8d0183988577aa2a7392aaa28091aa81c8ac23942b5751420b9ee48e488a68411f9d2b1e5d5@0.0.0.0:0","name":"node107","listenAddr":""}}},{"node":{"info":{"listenAddr":"","enode":"enode://eb58e478b16056e0af344397cf5f078a3312a6db2189ec2042ec06ab6550e3ee71ebcfeff1814332c552c12a5a488f96b3f2935e90a189d238da19d30a2c9874@0.0.0.0:0","name":"node108","id":"eb58e478b16056e0af344397cf5f078a3312a6db2189ec2042ec06ab6550e3ee71ebcfeff1814332c552c12a5a488f96b3f2935e90a189d238da19d30a2c9874","protocols":{"bzz":"cpQiPAqyeFHfjCVBis8Joo76lfwjglKvimg5DbB7d+Q=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 729422\npopulation: 19 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 5 ed65 e4c3 c64f c3f3 | 121 fed1 (0) fd2d (0) f924 (0) f915 (0)\n001 1 1d07 | 73 34fc (0) 3538 (0) 3648 (0) 3345 (0)\n002 2 458a 43af | 31 5c5d (0) 5f05 (0) 5fd0 (0) 5fa8 (0)\n003 2 6783 670d | 11 6d21 (0) 6dbd (0) 6ea5 (0) 6143 (0)\n004 3 79ab 7d45 7ffe | 12 7a41 (0) 79bd (0) 79ab (0) 7851 (0)\n005 3 759e 7406 77ec | 4 759e (0) 7471 (0) 7406 (0) 77ec (0)\n006 0 | 0\n007 1 7307 | 1 7307 (0)\n008 0 | 0\n============ DEPTH: 9 ==========================================\n009 1 72fa | 1 72fa (0)\n010 1 72ac | 1 72ac (0)\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"discovery":0,"listener":0},"ip":"0.0.0.0"},"up":true,"config":{"name":"node108","services":["pss","bzz"],"private_key":"9f9be5e82bec360e52170374b35e26ab30480bf5effa10bc43527c191d1efc84","id":"eb58e478b16056e0af344397cf5f078a3312a6db2189ec2042ec06ab6550e3ee71ebcfeff1814332c552c12a5a488f96b3f2935e90a189d238da19d30a2c9874"}}},{"node":{"info":{"id":"3a2cacc430f13f31c52b7205455420cf0fb9ed9e28b0898b69ef97951bf295b29118e573a42dd97abe38fee5ab4c03dad9ff6dc448126cefc1da12b6c8e8d915","ports":{"discovery":0,"listener":0},"protocols":{"bzz":"k5DvYXU/z52uXlhahWUCh/4feSU4chos92etxExefOA=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 9390ef\npopulation: 18 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 7294 | 135 0ea2 (0) 0eee (0) 0f5e (0) 0f81 (0)\n001 2 ed65 c3f3 | 65 fd2d (0) fed1 (0) f915 (0) f924 (0)\n002 5 a749 ad36 bfec b60d | 30 a033 (0) a485 (0) a749 (0) a672 (0)\n003 3 8874 8ac8 8c89 | 10 86f7 (0) 8612 (0) 8163 (0) 8c61 (0)\n004 3 985c 9fee 9c0c | 9 9a82 (0) 99aa (0) 99db (0) 99fb (0)\n005 2 95e0 94aa | 4 96b6 (0) 95e0 (0) 9461 (0) 94aa (0)\n006 0 | 0\n============ DEPTH: 7 ==========================================\n007 2 9294 9232 | 2 9294 (0) 9232 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ip":"0.0.0.0","listenAddr":"","enode":"enode://3a2cacc430f13f31c52b7205455420cf0fb9ed9e28b0898b69ef97951bf295b29118e573a42dd97abe38fee5ab4c03dad9ff6dc448126cefc1da12b6c8e8d915@0.0.0.0:0","name":"node109"},"config":{"id":"3a2cacc430f13f31c52b7205455420cf0fb9ed9e28b0898b69ef97951bf295b29118e573a42dd97abe38fee5ab4c03dad9ff6dc448126cefc1da12b6c8e8d915","private_key":"01c46dd80b68bfbc5916277ab36142ff3033b126df71354bc7b21993be4f27b4","services":["pss","bzz"],"name":"node109"},"up":true}},{"node":{"config":{"id":"ba430731fc2082f4217ebd859c2865c28bf50a39674ca8615dd89f608ae434a09657e24644ac32807634aad7857547118c9228460195e50ec58b34789d4ad151","private_key":"d4ea8e3d466c3fadc709252e0b35240e831250311a3023363aaa2de0d4068efe","services":["pss","bzz"],"name":"node110"},"up":true,"info":{"id":"ba430731fc2082f4217ebd859c2865c28bf50a39674ca8615dd89f608ae434a09657e24644ac32807634aad7857547118c9228460195e50ec58b34789d4ad151","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 9c0c7b\npopulation: 17 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 29fd 670d 43af | 135 0f81 (0) 0f5e (0) 0ea2 (0) 0eee (0)\n001 3 ed65 c64f c3f3 | 65 d3fd (0) d3d2 (0) d564 (0) d7ab (0)\n002 3 ad36 b4c7 b60d | 30 a033 (0) a485 (0) a749 (0) a672 (0)\n003 2 8c89 8ac8 | 10 8163 (0) 8612 (0) 86f7 (0) 8c61 (0)\n004 2 94aa 9390 | 7 96b6 (0) 95e0 (0) 9461 (0) 94aa (0)\n005 1 985c | 5 9a82 (0) 99aa (0) 99db (0) 99fb (0)\n============ DEPTH: 6 ==========================================\n006 2 9eec 9fee | 2 9eec (0) 9fee (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 1 9c01 | 1 9c01 (0)\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"nAx7baM1IEQLGBpfzDCqinV27JxvZKzvDJUl0Fou45M="},"ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","name":"node110","enode":"enode://ba430731fc2082f4217ebd859c2865c28bf50a39674ca8615dd89f608ae434a09657e24644ac32807634aad7857547118c9228460195e50ec58b34789d4ad151@0.0.0.0:0"}}},{"node":{"up":true,"config":{"private_key":"ff786dd6bdf5a54dfd71c73ab93427d94008f2854eec2a87c96223aeaf5a2357","id":"8d3ad57509b36c4ca5c4663f3d1977a3125e069078842634e6cfeb22c044281e3d02f06eafc6d2a60089f03d70f5134a6635c35563c9f911fd845a6ef9bc8952","name":"node111","services":["pss","bzz"]},"info":{"id":"8d3ad57509b36c4ca5c4663f3d1977a3125e069078842634e6cfeb22c044281e3d02f06eafc6d2a60089f03d70f5134a6635c35563c9f911fd845a6ef9bc8952","ports":{"discovery":0,"listener":0},"protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 43afd8\npopulation: 17 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 e4c3 9c0c b60d | 121 d3fd (0) d3d2 (0) d564 (0) d7ab (0)\n001 1 1d07 | 73 0ea2 (0) 0eee (0) 0f81 (0) 0f5e (0)\n002 4 670d 77ec 7406 7294 | 31 6d21 (0) 6dbd (0) 6ea5 (0) 604c (0)\n003 1 5716 | 14 5c5d (0) 5f05 (0) 5fd0 (0) 5fa8 (0)\n004 3 4b00 4af7 487e | 10 4cf6 (0) 4d44 (0) 4fd6 (0) 4f90 (0)\n005 2 46c5 458a | 3 47f9 (1) 46c5 (0) 458a (0)\n006 1 4019 | 1 4019 (0)\n============ DEPTH: 7 ==========================================\n007 2 42c0 42d4 | 2 42c0 (0) 42d4 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"Q6/YNZMOrJHAyJRwAd1g2NqREsGc8/E1ZYm1i0iWIWY="},"ip":"0.0.0.0","listenAddr":"","enode":"enode://8d3ad57509b36c4ca5c4663f3d1977a3125e069078842634e6cfeb22c044281e3d02f06eafc6d2a60089f03d70f5134a6635c35563c9f911fd845a6ef9bc8952@0.0.0.0:0","name":"node111"}}},{"node":{"info":{"ports":{"discovery":0,"listener":0},"protocols":{"bzz":"tg3rp8hnYwW2evQdLehmvd1y7cBmfUJ+Ufw/LpFBK0U=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: b60deb\npopulation: 21 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 29fd 670d 43af | 135 0f81 (0) 0f5e (0) 0ea2 (0) 0eee (0)\n001 2 c3f3 ed65 | 65 d3fd (0) d3d2 (0) d564 (0) d7ab (0)\n002 2 9390 9c0c | 26 8612 (0) 86f7 (0) 8163 (0) 8c61 (0)\n003 6 abfa af35 af5f adfc | 16 a033 (0) a485 (0) a672 (0) a749 (0)\n004 1 bfec | 6 b8a7 (0) baf3 (0) bc08 (0) be0a (0)\n005 1 b310 | 1 b310 (0)\n006 4 b5c7 b463 b45d b4c7 | 4 b5c7 (0) b463 (0) b45d (0) b4c7 (0)\n============ DEPTH: 7 ==========================================\n007 2 b710 b79f | 2 b710 (0) b79f (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ip":"0.0.0.0","id":"17ae0b24297a3e6e027884e5e4529b6646ae340f5736eebc6187a9b59832a445f3644172d92438351e3803e56a67472b29f3e1d48844ae2e11e5e6670eed1436","enode":"enode://17ae0b24297a3e6e027884e5e4529b6646ae340f5736eebc6187a9b59832a445f3644172d92438351e3803e56a67472b29f3e1d48844ae2e11e5e6670eed1436@0.0.0.0:0","name":"node112","listenAddr":""},"up":true,"config":{"name":"node112","services":["pss","bzz"],"private_key":"81d2fd2b16f53fcb3749b3c8575a00ddf39ee32f760cc7e8365c046e364ec849","id":"17ae0b24297a3e6e027884e5e4529b6646ae340f5736eebc6187a9b59832a445f3644172d92438351e3803e56a67472b29f3e1d48844ae2e11e5e6670eed1436"}}},{"node":{"up":true,"config":{"private_key":"5017533627afd71f2684b9ef264ac79ff826f1cbbfedd788d969d9ae1bb87b20","id":"8c459100df488b992fdad207a096a434d67cb733619adfd09a311095568d4c9db293d9a892675551805559456d49a3fdb19c2cc698b14552bf0ace584d4d90dc","name":"node113","services":["pss","bzz"]},"info":{"name":"node113","enode":"enode://8c459100df488b992fdad207a096a434d67cb733619adfd09a311095568d4c9db293d9a892675551805559456d49a3fdb19c2cc698b14552bf0ace584d4d90dc@0.0.0.0:0","listenAddr":"","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 670d1c\npopulation: 19 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 9c0c b4c7 b60d ad36 | 121 d3fd (0) d3d2 (0) d564 (0) d7ab (0)\n001 1 29fd | 73 0f81 (0) 0f5e (0) 0ea2 (0) 0eee (0)\n002 1 43af | 31 5c5d (0) 5f05 (0) 5fd0 (0) 5fa8 (0)\n003 5 7ffe 7d45 7294 77ec | 20 7a41 (0) 7851 (0) 7854 (0) 7829 (0)\n004 2 6d21 6ea5 | 3 6d21 (0) 6dbd (0) 6ea5 (0)\n005 2 6143 6330 | 3 604c (0) 6143 (0) 6330 (0)\n006 1 6544 | 1 6544 (0)\n007 1 6610 | 1 6610 (0)\n============ DEPTH: 8 ==========================================\n008 2 67a2 6783 | 2 67a2 (0) 6783 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"Zw0cMUB7TzS7lVAx6aOreYAnMVUIC0WaCCaH1To7QqY="},"ports":{"discovery":0,"listener":0},"ip":"0.0.0.0","id":"8c459100df488b992fdad207a096a434d67cb733619adfd09a311095568d4c9db293d9a892675551805559456d49a3fdb19c2cc698b14552bf0ace584d4d90dc"}}},{"node":{"info":{"ports":{"listener":0,"discovery":0},"protocols":{"bzz":"rTa4AumwFyflFoecAFXjxGuBCEV5T3dyrYXoBiERsWc=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: ad36b8\npopulation: 20 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 670d | 135 0ea2 (0) 0eee (0) 0f81 (0) 0f5e (0)\n001 3 e4c3 ed65 c3f3 | 65 d3fd (0) d3d2 (0) d564 (0) d7ab (0)\n002 2 9390 9c0c | 26 8163 (0) 86f7 (0) 8612 (0) 89ee (0)\n003 3 bfec b60d b4c7 | 14 b8a7 (0) baf3 (0) bc08 (0) be0a (0)\n004 2 a749 a672 | 4 a033 (0) a485 (0) a749 (0) a672 (0)\n005 2 abfa aa50 | 4 a80b (0) abfa (0) aa88 (0) aa50 (0)\n006 5 af5f af30 af35 ae65 | 5 af5f (0) af30 (0) af35 (0) ae65 (0)\n============ DEPTH: 7 ==========================================\n007 1 aca1 | 1 aca1 (0)\n008 1 adfc | 1 adfc (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ip":"0.0.0.0","id":"c2a9c77247871cfa4d3c2d1b47619df91ed5b331a44c8e21f7c9ce431a4db9dfb87713558cc8a37911393907b4cc60be9445bad18adcea1bc5f318256e71be14","enode":"enode://c2a9c77247871cfa4d3c2d1b47619df91ed5b331a44c8e21f7c9ce431a4db9dfb87713558cc8a37911393907b4cc60be9445bad18adcea1bc5f318256e71be14@0.0.0.0:0","name":"node114","listenAddr":""},"config":{"name":"node114","services":["pss","bzz"],"private_key":"92a91e558f70fffacaea7b5c86540ae940da57dcb660d8c3e6eb5c7b38f015f0","id":"c2a9c77247871cfa4d3c2d1b47619df91ed5b331a44c8e21f7c9ce431a4db9dfb87713558cc8a37911393907b4cc60be9445bad18adcea1bc5f318256e71be14"},"up":true}},{"node":{"info":{"id":"aa2028d356a88eca8e0fcaf218d62ace099c3f72dfd95bb28f30ac9a926034cf1d60a40511f7495652745de80d71c0f6830019e206c88e2b6ef0cf4f05d7fe9e","protocols":{"bzz":"tMdVWjjR1OO9HQG8xHqE79YSjozA/YAzYtqLNB+YSk0=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: b4c755\npopulation: 21 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 7406 670d | 135 388d (0) 396b (0) 3a4a (0) 3af3 (0)\n001 2 e4c3 ed65 | 65 d3fd (0) d3d2 (0) d564 (0) d7ab (0)\n002 2 9390 9c0c | 26 8612 (0) 86f7 (0) 8163 (0) 89ee (0)\n003 7 a749 a672 abfa aa50 | 16 a033 (0) a485 (0) a749 (0) a672 (0)\n004 1 bfec | 6 b8a7 (0) baf3 (0) bc08 (0) be0a (0)\n005 1 b310 | 1 b310 (0)\n006 3 b710 b79f b60d | 3 b710 (0) b79f (0) b60d (0)\n007 1 b5c7 | 1 b5c7 (0)\n============ DEPTH: 8 ==========================================\n008 2 b463 b45d | 2 b463 (0) b45d (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ip":"0.0.0.0","ports":{"listener":0,"discovery":0},"listenAddr":"","name":"node115","enode":"enode://aa2028d356a88eca8e0fcaf218d62ace099c3f72dfd95bb28f30ac9a926034cf1d60a40511f7495652745de80d71c0f6830019e206c88e2b6ef0cf4f05d7fe9e@0.0.0.0:0"},"up":true,"config":{"private_key":"91f18de340c4916711d69fea368a4248eca8a13910d576e24ff9125fbccae3a3","id":"aa2028d356a88eca8e0fcaf218d62ace099c3f72dfd95bb28f30ac9a926034cf1d60a40511f7495652745de80d71c0f6830019e206c88e2b6ef0cf4f05d7fe9e","name":"node115","services":["pss","bzz"]}}},{"node":{"up":true,"config":{"services":["pss","bzz"],"name":"node116","id":"8ec699020ab5e7719fe23b80268b5d1d37052bb71f5d81200ae805cf27825823733206165f0a7507c2595853361dd122e9ec1b2deb543591e22b71ec0b873b5b","private_key":"f1e5638e4912ca0ccd446a27531942b75039807eea70118fad6880f5b1ad5ee7"},"info":{"name":"node116","enode":"enode://8ec699020ab5e7719fe23b80268b5d1d37052bb71f5d81200ae805cf27825823733206165f0a7507c2595853361dd122e9ec1b2deb543591e22b71ec0b873b5b@0.0.0.0:0","listenAddr":"","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: ed6570\npopulation: 20 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 7294 29fd | 135 5c5d (0) 5fa8 (0) 5fab (0) 5fd0 (0)\n001 5 9c0c 9390 ad36 b60d | 56 8163 (0) 86f7 (0) 8612 (0) 89ee (0)\n002 3 dae3 c723 c3f3 | 36 d564 (0) d7ab (0) d68f (0) d6f3 (0)\n003 3 f1fc f644 f5dd | 17 fd2d (0) fed1 (0) f915 (0) f924 (0)\n004 3 e76a e4c3 e3c9 | 7 e649 (0) e67d (0) e787 (0) e76a (0)\n005 1 e839 | 1 e839 (0)\n006 0 | 0\n007 1 ecd2 | 1 ecd2 (0)\n============ DEPTH: 8 ==========================================\n008 1 edca | 1 edca (0)\n009 1 ed13 | 1 ed13 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"7WVw5j/A4uLWKQZFxDObcKDxwUBk0oa04LoUNge9cMg="},"ports":{"listener":0,"discovery":0},"ip":"0.0.0.0","id":"8ec699020ab5e7719fe23b80268b5d1d37052bb71f5d81200ae805cf27825823733206165f0a7507c2595853361dd122e9ec1b2deb543591e22b71ec0b873b5b"}}},{"node":{"info":{"listenAddr":"","name":"node117","enode":"enode://c0164fb4a1acfb4f3b1a09f9f3ab226c382529a73891937c6f3c91798098cf10b909eb92e5f8acfe0e8f3aee0b71cb23ee2d9e6ad1e0f4492a0272c52d529849@0.0.0.0:0","id":"c0164fb4a1acfb4f3b1a09f9f3ab226c382529a73891937c6f3c91798098cf10b909eb92e5f8acfe0e8f3aee0b71cb23ee2d9e6ad1e0f4492a0272c52d529849","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 29fd44\npopulation: 19 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 b60d 9c0c ed65 | 121 8163 (0) 86f7 (0) 8612 (0) 89ee (0)\n001 4 670d 6783 7ffe 7406 | 62 5f05 (0) 5fd0 (0) 5fab (0) 5fa8 (0)\n002 2 185a 1d07 | 38 0ea2 (0) 0eee (0) 0f81 (0) 0f5e (0)\n003 3 3f3e 32dd 31ed | 15 396b (0) 388d (0) 3af3 (0) 3a4a (0)\n004 2 275c 2279 | 9 259d (0) 2454 (0) 265d (0) 275c (0)\n005 1 2e9f | 5 2f9f (0) 2fd8 (0) 2f22 (0) 2e4c (0)\n006 2 2a69 2a22 | 3 2af0 (0) 2a69 (0) 2a22 (0)\n007 0 | 0\n============ DEPTH: 8 ==========================================\n008 1 290f | 1 290f (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 1 29ff | 1 29ff (0)\n015 0 | 0\n=========================================================================","bzz":"Kf1Ec/G2w3+CaNc91faDoPfrZL15PassRQwQ2KsLZm0="},"ports":{"listener":0,"discovery":0},"ip":"0.0.0.0"},"config":{"private_key":"83bcea8f8c409f9470bca240d19fb29d9fea6cf94435ebbdf0a8faf5f1cb5ca0","id":"c0164fb4a1acfb4f3b1a09f9f3ab226c382529a73891937c6f3c91798098cf10b909eb92e5f8acfe0e8f3aee0b71cb23ee2d9e6ad1e0f4492a0272c52d529849","name":"node117","services":["pss","bzz"]},"up":true}},{"node":{"info":{"name":"node118","enode":"enode://f60755ee9464c7db769bb7237016fa165441d18ac3bfed7cd2a220a9bcbead202dd34eaf2f9398a3d36bdfc2671bbd46ac25ebe264a8118afe1b7d0bd38710f4@0.0.0.0:0","listenAddr":"","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 74062d\npopulation: 18 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 f644 dae3 b4c7 | 121 86f7 (0) 8612 (0) 8163 (0) 89ee (0)\n001 2 32dd 29fd | 73 0f81 (0) 0f5e (0) 0ea2 (0) 0eee (0)\n002 3 487e 458a 43af | 31 5c5d (0) 5f05 (0) 5fd0 (0) 5fa8 (0)\n003 2 670d 6783 | 11 6d21 (0) 6dbd (0) 6ea5 (0) 6143 (0)\n004 3 79ab 7d45 7ffe | 12 7a41 (0) 7851 (0) 7854 (0) 7829 (0)\n005 2 7307 7294 | 4 7307 (0) 72fa (0) 72ac (0) 7294 (0)\n006 1 77ec | 1 77ec (0)\n============ DEPTH: 7 ==========================================\n007 1 759e | 1 759e (0)\n008 0 | 0\n009 1 7471 | 1 7471 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"dAYtndc+JgZv1E5PbGlvJxydxoYL3Fuj/PRH9FXIyvo="},"ports":{"listener":0,"discovery":0},"ip":"0.0.0.0","id":"f60755ee9464c7db769bb7237016fa165441d18ac3bfed7cd2a220a9bcbead202dd34eaf2f9398a3d36bdfc2671bbd46ac25ebe264a8118afe1b7d0bd38710f4"},"up":true,"config":{"id":"f60755ee9464c7db769bb7237016fa165441d18ac3bfed7cd2a220a9bcbead202dd34eaf2f9398a3d36bdfc2671bbd46ac25ebe264a8118afe1b7d0bd38710f4","private_key":"33c3e295cfb9706d4d5e081ec3c220d8c35415d7c256de99511e76474e8c906b","services":["pss","bzz"],"name":"node118"}}},{"node":{"config":{"services":["pss","bzz"],"name":"node119","id":"b3b4b203395bb6655d79ecdcee11638dd9a16baccfcc1f6fcc8b31832c8ca35650eb6c2802104eeec6d96ea80404381a2bd9b01dcadc748a4666b761d9ce64f8","private_key":"af0dcfc78e50f0893cd504a3567a8515538bd85a1d3eb72809dd503690d0d274"},"up":true,"info":{"enode":"enode://b3b4b203395bb6655d79ecdcee11638dd9a16baccfcc1f6fcc8b31832c8ca35650eb6c2802104eeec6d96ea80404381a2bd9b01dcadc748a4666b761d9ce64f8@0.0.0.0:0","name":"node119","listenAddr":"","ports":{"listener":0,"discovery":0},"protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 7ffed7\npopulation: 18 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 f644 | 121 a80b (0) aa88 (0) aa50 (0) abfa (0)\n001 1 29fd | 73 0f81 (0) 0f5e (0) 0ea2 (0) 0eee (0)\n002 3 458a 487e 5716 | 31 5c5d (0) 5f05 (0) 5fd0 (0) 5fa8 (0)\n003 3 6ea5 670d 6783 | 11 6d21 (0) 6dbd (0) 6ea5 (0) 604c (0)\n004 3 7294 77ec 7406 | 8 7307 (0) 72fa (0) 72ac (0) 7294 (0)\n005 2 79ab 7829 | 6 7a41 (0) 7851 (0) 7854 (0) 7829 (0)\n============ DEPTH: 6 ==========================================\n006 4 7d94 7de7 7dc6 7d45 | 4 7d94 (0) 7de7 (0) 7dc6 (0) 7d45 (0)\n007 0 | 0\n008 0 | 0\n009 1 7fa4 | 1 7fa4 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"f/7XjhHHHsz93fao5eNngxsmprEeTTtgxbn8UPS83zM="},"ip":"0.0.0.0","id":"b3b4b203395bb6655d79ecdcee11638dd9a16baccfcc1f6fcc8b31832c8ca35650eb6c2802104eeec6d96ea80404381a2bd9b01dcadc748a4666b761d9ce64f8"}}},{"node":{"config":{"name":"node120","services":["pss","bzz"],"private_key":"8c806f6fed9bc74fb07341b080bc3067c953b5d6093ef5779221924d4ead4bb8","id":"96cd4caa32c0b3a3493e24e13fad1ef75c621005d74154c3fc8a73cca4c0120452b6432334d94849c63f75d56a2943a453c86d2a14ad1fb61ae6833e58451187"},"up":true,"info":{"enode":"enode://96cd4caa32c0b3a3493e24e13fad1ef75c621005d74154c3fc8a73cca4c0120452b6432334d94849c63f75d56a2943a453c86d2a14ad1fb61ae6833e58451187@0.0.0.0:0","name":"node120","listenAddr":"","protocols":{"bzz":"9kTHPix+Kd1FUGc2ykoMLKs/gpTAGm1d7MGTyy0ZpHM=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: f644c7\npopulation: 22 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 5 29ff 6783 7406 7d45 | 135 004e (0) 03f5 (0) 0210 (0) 06aa (0)\n001 3 9fee af5f ae71 | 56 baf3 (0) b8a7 (0) be0a (0) bf5a (0)\n002 4 c723 d6d2 df25 dae3 | 36 ceee (0) cb69 (0) ca81 (0) c9f3 (0)\n003 1 ed65 | 12 e3c9 (0) e44b (0) e4c3 (0) e649 (0)\n004 2 f915 fd2d | 6 fa74 (0) fb93 (0) f924 (0) f915 (0)\n005 2 f0e2 f1fc | 5 f3d3 (0) f048 (0) f0e2 (0) f156 (0)\n============ DEPTH: 6 ==========================================\n006 4 f4e0 f4ee f5cc f5dd | 4 f4ee (0) f4e0 (0) f5cc (0) f5dd (0)\n007 1 f78a | 1 f78a (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"discovery":0,"listener":0},"ip":"0.0.0.0","id":"96cd4caa32c0b3a3493e24e13fad1ef75c621005d74154c3fc8a73cca4c0120452b6432334d94849c63f75d56a2943a453c86d2a14ad1fb61ae6833e58451187"}}},{"node":{"info":{"protocols":{"bzz":"Z4MUadf5t3nfQxjNqdQxDFP91mMyrzdA5lQjPOs/vLw=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 678314\npopulation: 19 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 f644 | 121 b8a7 (0) baf3 (0) bc08 (0) be0a (0)\n001 2 29fd 29ff | 73 0f81 (0) 0f5e (0) 0ea2 (0) 0eee (0)\n002 1 5716 | 31 5c5d (0) 5f05 (0) 5fd0 (0) 5fa8 (0)\n003 7 79ab 7d45 7ffe 7294 | 20 7a41 (0) 7851 (0) 7854 (0) 7829 (0)\n004 2 6d21 6ea5 | 3 6d21 (0) 6dbd (0) 6ea5 (0)\n005 2 6330 604c | 3 6143 (0) 604c (0) 6330 (0)\n006 1 6544 | 1 6544 (0)\n007 1 6610 | 1 6610 (0)\n============ DEPTH: 8 ==========================================\n008 1 670d | 1 670d (0)\n009 0 | 0\n010 1 67a2 | 1 67a2 (0)\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"discovery":0,"listener":0},"ip":"0.0.0.0","id":"97b1eaf8274ece76d75e7f60126f1b351ed5fe55088b9fcbb825a3a8d8f84f61bc72469916b280497dabf01345057525cae89da73c9a1a8a8cd19367d44dede1","enode":"enode://97b1eaf8274ece76d75e7f60126f1b351ed5fe55088b9fcbb825a3a8d8f84f61bc72469916b280497dabf01345057525cae89da73c9a1a8a8cd19367d44dede1@0.0.0.0:0","name":"node121","listenAddr":""},"up":true,"config":{"name":"node121","services":["pss","bzz"],"private_key":"a1a11eedc4fe78f42dd23b093d9fbcbf1643899eca875296b0374ec0e8ab619c","id":"97b1eaf8274ece76d75e7f60126f1b351ed5fe55088b9fcbb825a3a8d8f84f61bc72469916b280497dabf01345057525cae89da73c9a1a8a8cd19367d44dede1"}}},{"node":{"config":{"private_key":"15d8362248798e68c5eda882717ee691573e5477b7f0444222fabaaf1a025a8a","id":"bdd17545242bedba1e4c36fadea95db655f8f220f10ae143084690a3c8d4e7ffb79a64af9f1bc8514addbd63695b2f20857e8d162f25318faac885f77b385138","name":"node122","services":["pss","bzz"]},"up":true,"info":{"id":"bdd17545242bedba1e4c36fadea95db655f8f220f10ae143084690a3c8d4e7ffb79a64af9f1bc8514addbd63695b2f20857e8d162f25318faac885f77b385138","protocols":{"bzz":"Kf/XPrOzZZNIIgj1vxucgrfxqSsGFzx2nbCZnZJMiWk=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 29ffd7\npopulation: 23 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 5 ae71 9fee f644 dae3 | 121 bc08 (0) be0a (0) bfec (0) bf5a (0)\n001 5 487e 5716 79ab 7d45 | 62 4019 (0) 42c0 (0) 42d4 (0) 43af (0)\n002 2 1d93 185a | 38 0ea2 (0) 0eee (0) 0f81 (0) 0f5e (0)\n003 4 3f3e 3648 31ed 32dd | 15 396b (0) 388d (0) 3af3 (0) 3a4a (0)\n004 1 2279 | 9 2454 (0) 259d (0) 265d (0) 275c (0)\n005 2 2fd8 2e9f | 5 2f22 (0) 2f9f (0) 2fd8 (0) 2e4c (0)\n006 2 2a22 2a69 | 3 2af0 (0) 2a69 (0) 2a22 (0)\n007 0 | 0\n============ DEPTH: 8 ==========================================\n008 1 290f | 1 290f (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 1 29fd | 1 29fd (0)\n015 0 | 0\n========================================================================="},"ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","enode":"enode://bdd17545242bedba1e4c36fadea95db655f8f220f10ae143084690a3c8d4e7ffb79a64af9f1bc8514addbd63695b2f20857e8d162f25318faac885f77b385138@0.0.0.0:0","name":"node122"}}},{"node":{"config":{"name":"node123","services":["pss","bzz"],"private_key":"c1d6cf53ce48953f5b6bb0e0b644aaebd16b84a3910894f93c157140c88988a5","id":"c0a2c08fa8b70ecbf1932254945d5f689b0da7a287019d384152f383f6229acd4d82eef26205bc12e062dae4569814bd1c996ee4fe5886bd6bdd93c4f0ac113a"},"up":true,"info":{"listenAddr":"","name":"node123","enode":"enode://c0a2c08fa8b70ecbf1932254945d5f689b0da7a287019d384152f383f6229acd4d82eef26205bc12e062dae4569814bd1c996ee4fe5886bd6bdd93c4f0ac113a@0.0.0.0:0","id":"c0a2c08fa8b70ecbf1932254945d5f689b0da7a287019d384152f383f6229acd4d82eef26205bc12e062dae4569814bd1c996ee4fe5886bd6bdd93c4f0ac113a","ip":"0.0.0.0","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: c7230d\npopulation: 18 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 29ff | 135 4019 (0) 42c0 (0) 42d4 (0) 43af (0)\n001 3 9fee af5f ae71 | 56 8163 (0) 86f7 (0) 8612 (0) 8ac8 (0)\n002 3 ed65 f644 f1fc | 29 e44b (0) e4c3 (0) e67d (0) e649 (0)\n003 3 df25 dae3 d6d2 | 18 d3fd (0) d3d2 (0) d564 (0) d7ab (0)\n004 2 c883 c99c | 9 ceee (0) cb69 (0) ca81 (0) c9f3 (0)\n005 1 c3f3 | 3 c0d1 (0) c15d (0) c3f3 (0)\n006 2 c463 c484 | 2 c463 (0) c484 (0)\n============ DEPTH: 7 ==========================================\n007 2 c63e c64f | 2 c63e (0) c64f (0)\n008 0 | 0\n009 1 c770 | 1 c770 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"xyMNjVa2WmarchqCaO1DaveCEKrn0GjMK4r+ObbmHIE="},"ports":{"listener":0,"discovery":0}}}},{"node":{"info":{"protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: ae715a\npopulation: 21 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 29ff | 135 5c5d (0) 5fd0 (0) 5fab (0) 5fa8 (0)\n001 6 f644 f1fc df25 dae3 | 65 e44b (0) e4c3 (0) e67d (0) e649 (0)\n002 3 8c89 94aa 9fee | 26 8163 (0) 86f7 (0) 8612 (0) 8ac8 (0)\n003 1 b4c7 | 14 b8a7 (0) baf3 (0) bc08 (0) be0a (0)\n004 1 a672 | 4 a033 (0) a485 (0) a749 (0) a672 (0)\n005 2 abfa aa50 | 4 a80b (0) abfa (0) aa88 (0) aa50 (0)\n006 3 aca1 adfc ad36 | 3 aca1 (0) ad36 (0) adfc (0)\n============ DEPTH: 7 ==========================================\n007 3 af30 af35 af5f | 3 af30 (0) af35 (0) af5f (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 1 ae65 | 1 ae65 (0)\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"rnFaQOm/ULTrlUxrh++/Gm56vD2m2EBV5FkarfW61cg="},"ip":"0.0.0.0","ports":{"listener":0,"discovery":0},"id":"9d372d73848389cfa1676f0cdb030950980ed5b68d5b2ef8a058f1d2095b26ff0fafab5fd3c243296ee2620edc67752970ab47370270856287f8612d1b190a19","name":"node124","enode":"enode://9d372d73848389cfa1676f0cdb030950980ed5b68d5b2ef8a058f1d2095b26ff0fafab5fd3c243296ee2620edc67752970ab47370270856287f8612d1b190a19@0.0.0.0:0","listenAddr":""},"up":true,"config":{"name":"node124","services":["pss","bzz"],"private_key":"a67b1d8e2abb33c866d215b81af3a23fe0657a9155a8e17754bc0028dcf87852","id":"9d372d73848389cfa1676f0cdb030950980ed5b68d5b2ef8a058f1d2095b26ff0fafab5fd3c243296ee2620edc67752970ab47370270856287f8612d1b190a19"}}},{"node":{"info":{"id":"b152eb30c9f46ec39166016f03d289f98cc285ac62d204da32e5a003da14e4f02c64df8ae1d0c8a2a902adc5f7dd7604081a0b140c9b64052082f0861945f5a4","ports":{"discovery":0,"listener":0},"protocols":{"bzz":"8fz8BkRGpDKseiHvw4b6PQU9DKRUD9Tdu7JT7BH5zpQ=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: f1fcfc\npopulation: 19 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 7d45 | 135 06aa (0) 043f (0) 0592 (0) 05e8 (0)\n001 2 af5f ae71 | 56 8163 (0) 86f7 (0) 8612 (0) 8ae6 (0)\n002 4 d6d2 dae3 df25 c723 | 36 ceee (0) cb69 (0) ca81 (0) c9f3 (0)\n003 2 e76a ed65 | 12 e3c9 (0) e44b (0) e4c3 (0) e67d (0)\n004 2 f915 fd2d | 6 fa74 (0) fb93 (0) f924 (0) f915 (0)\n005 4 f4e0 f5dd f78a f644 | 6 f4ee (0) f4e0 (0) f5cc (0) f5dd (0)\n006 1 f3d3 | 1 f3d3 (0)\n============ DEPTH: 7 ==========================================\n007 2 f048 f0e2 | 2 f048 (0) f0e2 (0)\n008 1 f156 | 1 f156 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ip":"0.0.0.0","listenAddr":"","name":"node125","enode":"enode://b152eb30c9f46ec39166016f03d289f98cc285ac62d204da32e5a003da14e4f02c64df8ae1d0c8a2a902adc5f7dd7604081a0b140c9b64052082f0861945f5a4@0.0.0.0:0"},"config":{"name":"node125","services":["pss","bzz"],"private_key":"b9da682c3a119f650ebbaccf2974166f3162ce600afd50152f95e9be3f688bd4","id":"b152eb30c9f46ec39166016f03d289f98cc285ac62d204da32e5a003da14e4f02c64df8ae1d0c8a2a902adc5f7dd7604081a0b140c9b64052082f0861945f5a4"},"up":true}},{"node":{"up":true,"config":{"id":"e993be8034861aebc9bbd11115f25d9c719d43fcdefc323599616cc26240cee38dfc27bb7f339149a54a3c9ad13b2d6ca4f0ae690e4355605eda6b789c4a431e","private_key":"a6ca067c4be7a67d6c5b14fe7e0b62a964d844462a6b26a981cb73ffcbb48e46","services":["pss","bzz"],"name":"node126"},"info":{"protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 7d45f1\npopulation: 19 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 af5f f644 f1fc | 121 8163 (0) 86f7 (0) 8612 (0) 89ee (0)\n001 3 185a 32dd 29ff | 73 0f81 (0) 0f5e (0) 0ea2 (0) 0eee (0)\n002 1 487e | 31 4019 (0) 42c0 (0) 42d4 (0) 43af (0)\n003 2 6783 670d | 11 6d21 (0) 6dbd (0) 6ea5 (0) 6143 (0)\n004 2 7294 7406 | 8 7307 (0) 72fa (0) 72ac (0) 7294 (0)\n005 3 7829 79bd 79ab | 6 7a41 (0) 7851 (0) 7854 (0) 7829 (0)\n006 2 7fa4 7ffe | 2 7fa4 (0) 7ffe (0)\n007 0 | 0\n============ DEPTH: 8 ==========================================\n008 3 7d94 7dc6 7de7 | 3 7d94 (0) 7de7 (0) 7dc6 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"fUXx6RvNaD2HBCKy9ZHHb2qwf/SwefNcKAzkb3/DZOE="},"ports":{"discovery":0,"listener":0},"ip":"0.0.0.0","id":"e993be8034861aebc9bbd11115f25d9c719d43fcdefc323599616cc26240cee38dfc27bb7f339149a54a3c9ad13b2d6ca4f0ae690e4355605eda6b789c4a431e","enode":"enode://e993be8034861aebc9bbd11115f25d9c719d43fcdefc323599616cc26240cee38dfc27bb7f339149a54a3c9ad13b2d6ca4f0ae690e4355605eda6b789c4a431e@0.0.0.0:0","name":"node126","listenAddr":""}}},{"node":{"up":true,"config":{"name":"node127","services":["pss","bzz"],"private_key":"08926af18a3a13a1bf786aa6946ab5bde52c531026a8561524925f1d9f0d665c","id":"fc9b1b2bbd5e682eb350d23f3ee33b245495daedae9370de7b1f55f91cd45db831d196c17615e11decf6b67696a268ac788130e3de38c7f6aeae811f3ec8c8ee"},"info":{"listenAddr":"","name":"node127","enode":"enode://fc9b1b2bbd5e682eb350d23f3ee33b245495daedae9370de7b1f55f91cd45db831d196c17615e11decf6b67696a268ac788130e3de38c7f6aeae811f3ec8c8ee@0.0.0.0:0","id":"fc9b1b2bbd5e682eb350d23f3ee33b245495daedae9370de7b1f55f91cd45db831d196c17615e11decf6b67696a268ac788130e3de38c7f6aeae811f3ec8c8ee","ports":{"listener":0,"discovery":0},"protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: af5fcb\npopulation: 23 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 487e 7d45 32dd | 135 6d21 (0) 6dbd (0) 6ea5 (0) 6330 (0)\n001 6 c723 df25 dae3 d6d2 | 65 e67d (0) e649 (0) e787 (0) e76a (0)\n002 2 9fee 94aa | 26 8163 (0) 86f7 (0) 8612 (0) 8ae6 (0)\n003 2 b4c7 b60d | 14 b8a7 (0) baf3 (0) bc08 (0) be0a (0)\n004 1 a672 | 4 a033 (0) a485 (0) a749 (0) a672 (0)\n005 2 abfa aa50 | 4 a80b (0) abfa (0) aa88 (0) aa50 (0)\n006 3 aca1 ad36 adfc | 3 aca1 (0) ad36 (0) adfc (0)\n007 2 ae65 ae71 | 2 ae65 (0) ae71 (0)\n008 0 | 0\n============ DEPTH: 9 ==========================================\n009 2 af30 af35 | 2 af30 (0) af35 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"r1/LNxT22l/ldv7WMS9ZBCy6pUrIvYbnr80HU3Q0h9s="},"ip":"0.0.0.0"}}},{"node":{"info":{"listenAddr":"","name":"node128","enode":"enode://28cdd55fc871ffd8d63d05994be706959c9780dbfc859070a41047a1b40dd5fd7adb53919400a4c6f4d06c69bc1ecccc0e230e5b702598a7fe8003a282479872@0.0.0.0:0","id":"28cdd55fc871ffd8d63d05994be706959c9780dbfc859070a41047a1b40dd5fd7adb53919400a4c6f4d06c69bc1ecccc0e230e5b702598a7fe8003a282479872","ports":{"discovery":0,"listener":0},"protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 32dd86\npopulation: 13 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 af5f | 121 e67d (0) e649 (0) e76a (0) e787 (0)\n001 3 7406 7d45 487e | 62 6d21 (0) 6dbd (0) 6ea5 (0) 6143 (0)\n002 1 185a | 38 0f81 (0) 0f5e (0) 0ea2 (0) 0eee (0)\n003 3 2e9f 29fd 29ff | 20 2013 (0) 2168 (0) 211a (0) 2374 (0)\n004 1 3f3e | 9 3a4a (0) 3af3 (0) 388d (0) 396b (0)\n005 2 3538 3648 | 3 3538 (0) 34fc (0) 3648 (0)\n============ DEPTH: 6 ==========================================\n006 1 31ed | 1 31ed (0)\n007 1 3345 | 1 3345 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"Mt2G8/XDq+Vdax/jUunR0Mxj1hz6YLjnCy7p2y4o4ao="},"ip":"0.0.0.0"},"config":{"services":["pss","bzz"],"name":"node128","id":"28cdd55fc871ffd8d63d05994be706959c9780dbfc859070a41047a1b40dd5fd7adb53919400a4c6f4d06c69bc1ecccc0e230e5b702598a7fe8003a282479872","private_key":"793a4b0ec03ee3d4c1cc8fc8084366fc20e5852ecc3aa96ba2882babd7b8ff37"},"up":true}},{"node":{"info":{"listenAddr":"","enode":"enode://d7e3661c0af6754c875217f93d34b254f1f45fc1359a4c6146cd0efa4c6e12aed9a4fb0a21a136f73af4fc2c6d0a63cb809d81855bbc9f51e29d23d90f77b326@0.0.0.0:0","name":"node129","id":"d7e3661c0af6754c875217f93d34b254f1f45fc1359a4c6146cd0efa4c6e12aed9a4fb0a21a136f73af4fc2c6d0a63cb809d81855bbc9f51e29d23d90f77b326","protocols":{"bzz":"SH7fMgJzgSVqhkvC6byhdfchbMEjRzG9TckNLLrWl10=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 487edf\npopulation: 21 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 af5f d6d2 | 121 8ae6 (0) 8ac8 (0) 89ee (0) 8874 (0)\n001 3 185a 29ff 32dd | 73 0f81 (0) 0f5e (0) 0ea2 (0) 0eee (0)\n002 4 7406 79ab 7ffe 7d45 | 31 6dbd (0) 6d21 (0) 6ea5 (0) 6330 (0)\n003 1 5716 | 14 5c5d (0) 5f05 (0) 5fd0 (0) 5fa8 (0)\n004 2 458a 43af | 7 47f9 (0) 46c5 (0) 458a (0) 4019 (0)\n005 4 4cf6 4d44 4fd6 4f90 | 4 4cf6 (0) 4d44 (0) 4fd6 (0) 4f90 (0)\n============ DEPTH: 6 ==========================================\n006 5 4b00 4a67 4a81 4a82 | 5 4b00 (0) 4a67 (0) 4a81 (0) 4a82 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ip":"0.0.0.0","ports":{"discovery":0,"listener":0}},"up":true,"config":{"name":"node129","services":["pss","bzz"],"private_key":"9d2fd418a2966f748dd746ca5b5f0c3a82496a0a6274355c059d5f48be6870b8","id":"d7e3661c0af6754c875217f93d34b254f1f45fc1359a4c6146cd0efa4c6e12aed9a4fb0a21a136f73af4fc2c6d0a63cb809d81855bbc9f51e29d23d90f77b326"}}},{"node":{"config":{"services":["pss","bzz"],"name":"node130","id":"3f322f9b1f1f0692663bc3be11cf11386f4a14696aab610916cfcadf0234cce0c86b51c85ce2108e9bc21d50ad71cc10a6eeaec3fc7732908f3a8b193465a0ac","private_key":"7c7cfd0cdb3cede7dc5d152c6f5a8d89941656a3e9e560cf993a319c9012f074"},"up":true,"info":{"listenAddr":"","enode":"enode://3f322f9b1f1f0692663bc3be11cf11386f4a14696aab610916cfcadf0234cce0c86b51c85ce2108e9bc21d50ad71cc10a6eeaec3fc7732908f3a8b193465a0ac@0.0.0.0:0","name":"node130","id":"3f322f9b1f1f0692663bc3be11cf11386f4a14696aab610916cfcadf0234cce0c86b51c85ce2108e9bc21d50ad71cc10a6eeaec3fc7732908f3a8b193465a0ac","protocols":{"bzz":"1tLTWzgZ4Ds51xRsTdG1P7e3BoHIhgRkZQ1estCd2iw=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: d6d2d3\npopulation: 15 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 487e | 135 06aa (0) 043f (0) 0592 (0) 05ec (0)\n001 3 ae71 af5f 9fee | 56 baf3 (0) b8a7 (0) be0a (0) bf5a (0)\n002 2 f1fc f644 | 29 e649 (0) e67d (0) e787 (0) e76a (0)\n003 1 c723 | 18 ceee (0) cb69 (0) ca81 (0) c9f3 (0)\n004 2 df25 dae3 | 11 dc86 (0) dc3e (0) ddf8 (0) def4 (0)\n005 2 d3fd d3d2 | 2 d3fd (0) d3d2 (0)\n006 1 d564 | 1 d564 (0)\n007 1 d7ab | 1 d7ab (0)\n008 0 | 0\n============ DEPTH: 9 ==========================================\n009 1 d68f | 1 d68f (0)\n010 1 d6f3 | 1 d6f3 (0)\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"listener":0,"discovery":0},"ip":"0.0.0.0"}}},{"node":{"info":{"ip":"0.0.0.0","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 9fee94\npopulation: 20 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 29ff 185a | 135 6d21 (0) 6dbd (0) 6ea5 (0) 6330 (0)\n001 5 f644 c723 dae3 df25 | 65 e839 (0) ecd2 (0) edca (0) ed13 (0)\n002 5 a672 abfa af35 af5f | 30 b8a7 (0) baf3 (0) bc08 (0) be0a (0)\n003 1 8c89 | 10 86f7 (0) 8612 (0) 8163 (0) 89ee (0)\n004 3 9390 9461 94aa | 7 9294 (0) 9232 (0) 9390 (0) 96b6 (0)\n005 1 99fb | 5 9a82 (0) 985c (0) 99aa (0) 99db (0)\n============ DEPTH: 6 ==========================================\n006 2 9c0c 9c01 | 2 9c01 (0) 9c0c (0)\n007 1 9eec | 1 9eec (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"n+6UXInWu1nneiQYPChV9O7OC10yZvdQ6pVIPq4eGHE="},"ports":{"listener":0,"discovery":0},"id":"7c6e6a49429a4e24aa4aa5c7ba19684f77cd67d3744688baff6e7f1d74b7e9d2df85f3e57e0df0a9b960b5bf982a610c5639c3e7a6935ba13fbc77243b2dad19","name":"node131","enode":"enode://7c6e6a49429a4e24aa4aa5c7ba19684f77cd67d3744688baff6e7f1d74b7e9d2df85f3e57e0df0a9b960b5bf982a610c5639c3e7a6935ba13fbc77243b2dad19@0.0.0.0:0","listenAddr":""},"up":true,"config":{"private_key":"457954e43019a3f3e510a0f818996c28e372410ba50490b5042068ff63f3e17d","id":"7c6e6a49429a4e24aa4aa5c7ba19684f77cd67d3744688baff6e7f1d74b7e9d2df85f3e57e0df0a9b960b5bf982a610c5639c3e7a6935ba13fbc77243b2dad19","name":"node131","services":["pss","bzz"]}}},{"node":{"config":{"id":"9ea856ea440c776b9ffaad1237ec11d570a1f912a908b8363ff97cf7947d2523e3c73663240d8fac988698cdd81e877ddd4a609485fe9f26494136fae14212df","private_key":"d45a6d15ff3a2073f6d31d9df7fe6778cac0ca1d62aeacec44341aef19924624","services":["pss","bzz"],"name":"node132"},"up":true,"info":{"id":"9ea856ea440c776b9ffaad1237ec11d570a1f912a908b8363ff97cf7947d2523e3c73663240d8fac988698cdd81e877ddd4a609485fe9f26494136fae14212df","protocols":{"bzz":"GFp5Uphbjv74rI7jcoOSGkWKahB8ug9/oz2nSAsFxM8=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 185a79\npopulation: 24 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 5 dae3 a672 adfc 94aa | 121 e649 (0) e67d (0) e76a (0) e787 (0)\n001 3 7d45 487e 5716 | 62 6dbd (0) 6d21 (0) 6ea5 (0) 6330 (0)\n002 4 32dd 31ed 29fd 29ff | 35 3d6b (0) 3dca (0) 3e85 (0) 3e44 (0)\n003 1 05e8 | 12 0f5e (0) 0f81 (0) 0eee (0) 0ea2 (0)\n004 1 123f | 8 1566 (0) 15f6 (0) 1441 (0) 14c8 (0)\n005 4 1e42 1e44 1d93 1d07 | 8 1e42 (0) 1e44 (0) 1c98 (0) 1da3 (0)\n006 2 1a02 1b72 | 5 1a83 (0) 1a02 (0) 1b86 (0) 1b1e (0)\n007 2 193e 194a | 2 193e (0) 194a (0)\n============ DEPTH: 8 ==========================================\n008 1 18f9 | 1 18f9 (0)\n009 1 1835 | 1 1835 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ip":"0.0.0.0","ports":{"listener":0,"discovery":0},"listenAddr":"","enode":"enode://9ea856ea440c776b9ffaad1237ec11d570a1f912a908b8363ff97cf7947d2523e3c73663240d8fac988698cdd81e877ddd4a609485fe9f26494136fae14212df@0.0.0.0:0","name":"node132"}}},{"node":{"info":{"listenAddr":"","name":"node133","enode":"enode://2cb076669efbaf2ff0b181a1b454061a31ef23937a40405022b126f0eb4bfba60c9e3397009d8c0ff0cabb603692532d0072c18c6838f43397c98483306f62db@0.0.0.0:0","id":"2cb076669efbaf2ff0b181a1b454061a31ef23937a40405022b126f0eb4bfba60c9e3397009d8c0ff0cabb603692532d0072c18c6838f43397c98483306f62db","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: dae3ea\npopulation: 29 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 29ff 185a 7406 5716 | 135 004e (0) 0210 (0) 03f5 (0) 06aa (0)\n001 5 a672 af5f ae71 9fee | 56 b8a7 (0) baf3 (0) bc08 (0) be0a (0)\n002 4 ed65 fd2d f1fc f644 | 29 e3c9 (0) e649 (0) e67d (0) e787 (0)\n003 4 c883 c64f c63e c723 | 18 ceee (0) cb69 (0) ca81 (0) c9f3 (0)\n004 5 d3d2 d564 d68f d6f3 | 7 d3fd (0) d3d2 (0) d564 (0) d7ab (0)\n005 4 dc3e de82 df5e df25 | 7 ddf8 (0) dc86 (0) dc3e (0) def4 (0)\n============ DEPTH: 6 ==========================================\n006 2 d822 d8b0 | 2 d8b0 (0) d822 (0)\n007 0 | 0\n008 0 | 0\n009 1 daa2 | 1 daa2 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"2uPqQOTm4ECkdAphTJnsa55kQwITXPNH6m7J68h6nyE="},"ports":{"listener":0,"discovery":0},"ip":"0.0.0.0"},"config":{"services":["pss","bzz"],"name":"node133","id":"2cb076669efbaf2ff0b181a1b454061a31ef23937a40405022b126f0eb4bfba60c9e3397009d8c0ff0cabb603692532d0072c18c6838f43397c98483306f62db","private_key":"c1e5c2bc35a1030f8bd3ffd9099376d32ca3029eff92b5c79055ae2454a6fd6a"},"up":false}},{"node":{"info":{"id":"643da2591098f9698f27cccf7c17832e0717ee6a1276398a1a29edc947125585dcfab9417c2721a8a55d4dfc75b826be7581b6e30b020f6341ac549877c9f122","protocols":{"bzz":"VxY4Y3FWva+S2ccVZHoc9k6Rh3wtmYZYt8bNJ1Iicb0=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 571638\npopulation: 20 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 adfc dae3 | 121 bc08 (0) be0a (0) bf5a (0) bfec (0)\n001 3 185a 29ff 31ed | 73 0f81 (0) 0f5e (0) 0ea2 (0) 0eee (0)\n002 3 6783 7ffe 79ab | 31 6d21 (0) 6dbd (0) 6ea5 (0) 6330 (0)\n003 5 458a 43af 4b00 4af7 | 17 4019 (0) 42c0 (0) 42d4 (0) 43af (0)\n004 1 5fab | 5 5c5d (0) 5f05 (0) 5fd0 (0) 5fa8 (0)\n005 2 5261 5110 | 4 5288 (0) 5261 (0) 5093 (0) 5110 (0)\n006 1 5571 | 1 5571 (0)\n============ DEPTH: 7 ==========================================\n007 2 5695 566e | 2 5695 (0) 566e (0)\n008 1 57d5 | 1 57d5 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"discovery":0,"listener":0},"ip":"0.0.0.0","listenAddr":"","name":"node134","enode":"enode://643da2591098f9698f27cccf7c17832e0717ee6a1276398a1a29edc947125585dcfab9417c2721a8a55d4dfc75b826be7581b6e30b020f6341ac549877c9f122@0.0.0.0:0"},"up":true,"config":{"name":"node134","services":["pss","bzz"],"private_key":"89da1a80c7122d19de9b63637b1f1675ee7e009a5ecf1f6c51cb29b2a09cc908","id":"643da2591098f9698f27cccf7c17832e0717ee6a1276398a1a29edc947125585dcfab9417c2721a8a55d4dfc75b826be7581b6e30b020f6341ac549877c9f122"}}},{"node":{"config":{"private_key":"e5596012d345aff602e83361bc5fb1f7e3feee7b23782a8c7f0a1c7933ab928c","id":"15ceb62ee0f53379aa202950634ed881ba3b7bd4b46c80723ee48190079311e24ffaacb167a126a40bd6732c384f3c26163aa043edca03cb52a97b6da189aec7","name":"node135","services":["pss","bzz"]},"up":true,"info":{"id":"15ceb62ee0f53379aa202950634ed881ba3b7bd4b46c80723ee48190079311e24ffaacb167a126a40bd6732c384f3c26163aa043edca03cb52a97b6da189aec7","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 31edba\npopulation: 18 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 94aa adfc | 121 e839 (0) ecd2 (0) edca (0) ed13 (0)\n001 2 79ab 5716 | 62 6d21 (0) 6dbd (0) 6ea5 (0) 6143 (0)\n002 3 1d93 1b72 185a | 38 0f81 (0) 0f5e (0) 0ea2 (0) 0eee (0)\n003 3 2e9f 29fd 29ff | 20 259d (0) 2454 (0) 265d (0) 275c (0)\n004 3 3a4a 3dca 3f3e | 9 396b (0) 388d (0) 3af3 (0) 3a4a (0)\n005 3 3538 34fc 3648 | 3 34fc (0) 3538 (0) 3648 (0)\n============ DEPTH: 6 ==========================================\n006 2 3345 32dd | 2 3345 (0) 32dd (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"Me26ZeU5qaPHEHoTHE+0tajiwtTi23h0oBFsFzlh4nw="},"ports":{"discovery":0,"listener":0},"ip":"0.0.0.0","listenAddr":"","name":"node135","enode":"enode://15ceb62ee0f53379aa202950634ed881ba3b7bd4b46c80723ee48190079311e24ffaacb167a126a40bd6732c384f3c26163aa043edca03cb52a97b6da189aec7@0.0.0.0:0"}}},{"node":{"up":true,"config":{"services":["pss","bzz"],"name":"node136","id":"154d5ddb15ec12dc65362039d801383c189b5bcf6688883f2d7e3d0e8dc78e45f9f58d5dabc79a8798a243ce59abb95c77525db14f050fd8cb37d04b7276557c","private_key":"91af9b7387bad90d696b549270c0302fbe3805efb01f311e801b317217b92cca"},"info":{"listenAddr":"","name":"node136","enode":"enode://154d5ddb15ec12dc65362039d801383c189b5bcf6688883f2d7e3d0e8dc78e45f9f58d5dabc79a8798a243ce59abb95c77525db14f050fd8cb37d04b7276557c@0.0.0.0:0","id":"154d5ddb15ec12dc65362039d801383c189b5bcf6688883f2d7e3d0e8dc78e45f9f58d5dabc79a8798a243ce59abb95c77525db14f050fd8cb37d04b7276557c","ip":"0.0.0.0","protocols":{"bzz":"rfwDEYQGvFr04/PGyJw0SMP+T53yCxW8ypu6z1juVFc=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: adfc03\npopulation: 18 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 185a 31ed 5716 79ab | 135 004e (0) 03f5 (0) 0210 (0) 06aa (0)\n001 2 df25 fd2d | 65 e787 (0) e76a (0) e67d (0) e649 (0)\n002 1 94aa | 26 86f7 (0) 8612 (0) 8163 (0) 8ae6 (0)\n003 2 b79f b60d | 14 b8a7 (0) baf3 (0) bc08 (0) be0a (0)\n004 1 a672 | 4 a033 (0) a485 (0) a749 (0) a672 (0)\n005 2 abfa aa50 | 4 a80b (0) abfa (0) aa88 (0) aa50 (0)\n006 4 ae71 af5f af30 af35 | 5 ae65 (0) ae71 (0) af5f (0) af30 (0)\n============ DEPTH: 7 ==========================================\n007 1 aca1 | 1 aca1 (0)\n008 1 ad36 | 1 ad36 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"discovery":0,"listener":0}}}},{"node":{"info":{"enode":"enode://740919ebae9b4fe646ca716ebb8923bf2a1b1963767d86f55ea95911d88d163cc2e07b1420669e64b62cb267b625413444b783b8e4a7bd6a0f481f4d84e984b1@0.0.0.0:0","name":"node137","listenAddr":"","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 79abd3\npopulation: 18 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 aa50 adfc | 121 e839 (0) ecd2 (0) edca (0) ed13 (0)\n001 2 29ff 31ed | 73 004e (0) 03f5 (0) 0210 (0) 06aa (0)\n002 2 487e 5716 | 31 4019 (0) 42c0 (0) 42d4 (0) 43af (0)\n003 1 6783 | 11 6d21 (0) 6dbd (0) 6ea5 (0) 6143 (0)\n004 3 7406 77ec 7294 | 8 77ec (0) 759e (0) 7471 (0) 7406 (0)\n005 3 7fa4 7ffe 7d45 | 6 7fa4 (0) 7ffe (0) 7d94 (0) 7de7 (0)\n006 1 7a41 | 1 7a41 (0)\n============ DEPTH: 7 ==========================================\n007 3 7851 7854 7829 | 3 7851 (0) 7854 (0) 7829 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 1 79bd | 1 79bd (0)\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"eavTPRUP28vOb1Xz0QFgi4DgPt5+Rie8BrpcGwAVOKQ="},"ports":{"listener":0,"discovery":0},"ip":"0.0.0.0","id":"740919ebae9b4fe646ca716ebb8923bf2a1b1963767d86f55ea95911d88d163cc2e07b1420669e64b62cb267b625413444b783b8e4a7bd6a0f481f4d84e984b1"},"up":true,"config":{"id":"740919ebae9b4fe646ca716ebb8923bf2a1b1963767d86f55ea95911d88d163cc2e07b1420669e64b62cb267b625413444b783b8e4a7bd6a0f481f4d84e984b1","private_key":"af83c717380c5132acd3357ec3e29daaacfc4e4a65fd1f5b14479b78e5fb01f6","services":["pss","bzz"],"name":"node137"}}},{"node":{"info":{"enode":"enode://a070b5cff5eff533a2267ceb0d88e221088038af773e18f80110c8a2c329f0543b8d43c4e6132e9416723e3e94c87f0053456760ced4426767b95cee36ed93f8@0.0.0.0:0","name":"node138","listenAddr":"","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: aa5046\npopulation: 15 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 1d93 79ab | 135 0210 (0) 03f5 (0) 004e (0) 043f (0)\n001 2 df25 fd2d | 65 e67d (0) e649 (0) e787 (0) e76a (0)\n002 1 94aa | 26 8163 (0) 86f7 (0) 8612 (0) 8ac8 (0)\n003 1 b4c7 | 14 b8a7 (0) baf3 (0) bc08 (0) be0a (0)\n004 1 a672 | 4 a033 (0) a485 (0) a749 (0) a672 (0)\n005 5 af5f af35 ae71 ad36 | 8 af5f (0) af30 (0) af35 (0) ae65 (0)\n006 1 a80b | 1 a80b (0)\n============ DEPTH: 7 ==========================================\n007 1 abfa | 1 abfa (0)\n008 1 aa88 | 1 aa88 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"qlBGgcmRxpAVx+8EaZAsRPxOkANWsYGqJSoSgP+9Ljs="},"ports":{"listener":0,"discovery":0},"ip":"0.0.0.0","id":"a070b5cff5eff533a2267ceb0d88e221088038af773e18f80110c8a2c329f0543b8d43c4e6132e9416723e3e94c87f0053456760ced4426767b95cee36ed93f8"},"up":true,"config":{"private_key":"2645348387e283c7f69d634a71ee38a65d4fc6928ecc383fb25cea4525fcdad9","id":"a070b5cff5eff533a2267ceb0d88e221088038af773e18f80110c8a2c329f0543b8d43c4e6132e9416723e3e94c87f0053456760ced4426767b95cee36ed93f8","name":"node138","services":["pss","bzz"]}}},{"node":{"up":true,"config":{"id":"c9d705012a06d82c4d44db95b4f1c63ddd33ad64d732e96b1d878caa0caac433d4096f01495a6f0e8a56af122b0470fd745db6d906353b590a4710472b93f5b2","private_key":"bc25724231b7bb54d17219feff13e1fe8e0486cace91c0cc6f3731a986f4a8ae","services":["pss","bzz"],"name":"node139"},"info":{"listenAddr":"","enode":"enode://c9d705012a06d82c4d44db95b4f1c63ddd33ad64d732e96b1d878caa0caac433d4096f01495a6f0e8a56af122b0470fd745db6d906353b590a4710472b93f5b2@0.0.0.0:0","name":"node139","id":"c9d705012a06d82c4d44db95b4f1c63ddd33ad64d732e96b1d878caa0caac433d4096f01495a6f0e8a56af122b0470fd745db6d906353b590a4710472b93f5b2","protocols":{"bzz":"lKpsrblN/ATirjFQrurrc7b8SDSCFW/KvcpMZZbqoJg=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 94aa6c\npopulation: 23 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 1e42 1d93 185a 31ed | 135 004e (0) 03f5 (0) 0210 (0) 06aa (0)\n001 3 fd2d dae3 df25 | 65 e3c9 (0) e44b (0) e4c3 (0) e787 (0)\n002 7 a672 ae71 af5f af35 | 30 b8a7 (0) baf3 (0) bc08 (0) be0a (0)\n003 1 8c89 | 10 8163 (0) 8612 (0) 86f7 (0) 8ac8 (0)\n004 4 985c 9c01 9c0c 9fee | 9 9a82 (0) 99aa (0) 99db (0) 99fb (0)\n005 1 9390 | 3 9232 (0) 9294 (0) 9390 (0)\n006 1 96b6 | 1 96b6 (0)\n============ DEPTH: 7 ==========================================\n007 1 95e0 | 1 95e0 (0)\n008 1 9461 | 1 9461 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ip":"0.0.0.0","ports":{"discovery":0,"listener":0}}}},{"node":{"info":{"id":"5d002c37b74a6656db86f102b0cec82bc35a819a480e5a2952db0140ebab65dffeb1a79f04d53ff61447b5fad7c58cb75ea1c91ea47fcb9e024f27b92c6c874d","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: df25c4\npopulation: 27 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 1e42 1d93 | 135 6d21 (0) 6dbd (0) 6ea5 (0) 6330 (0)\n001 8 9fee 94aa aa50 ae71 | 56 8163 (0) 86f7 (0) 8612 (0) 8ac8 (0)\n002 3 f644 f1fc fd2d | 29 e67d (0) e649 (0) e787 (0) e76a (0)\n003 4 c63e c723 c883 c99c | 18 c0d1 (0) c15d (0) c3f3 (0) c463 (0)\n004 4 d3d2 d564 d68f d6d2 | 7 d3fd (0) d3d2 (0) d564 (0) d7ab (0)\n005 1 dae3 | 4 d8b0 (0) d822 (0) daa2 (0) dae3 (0)\n006 2 dc86 ddf8 | 3 ddf8 (0) dc86 (0) dc3e (5)\n============ DEPTH: 7 ==========================================\n007 2 def4 de82 | 2 def4 (0) de82 (0)\n008 0 | 0\n009 1 df5e | 1 df5e (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"3yXEQ84ae2P+XYm//P60k2amI1JWYP3o6lCaGTSqBQw="},"ports":{"discovery":0,"listener":0},"ip":"0.0.0.0","listenAddr":"","enode":"enode://5d002c37b74a6656db86f102b0cec82bc35a819a480e5a2952db0140ebab65dffeb1a79f04d53ff61447b5fad7c58cb75ea1c91ea47fcb9e024f27b92c6c874d@0.0.0.0:0","name":"node140"},"config":{"name":"node140","services":["pss","bzz"],"private_key":"1b90feec9d475fc13f1394c4b39d837fbd09f4c329ef5747d988b17b84967ccc","id":"5d002c37b74a6656db86f102b0cec82bc35a819a480e5a2952db0140ebab65dffeb1a79f04d53ff61447b5fad7c58cb75ea1c91ea47fcb9e024f27b92c6c874d"},"up":true}},{"node":{"info":{"protocols":{"bzz":"pnIEJvqh6n4tVcHFrQW6LoxTTRIOu14Tdc92nXMZFwg=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: a67204\npopulation: 21 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 185a 1b72 1e42 1d93 | 135 46c5 (0) 47f9 (0) 458a (0) 4019 (0)\n001 2 dae3 df25 | 65 e3c9 (0) e649 (0) e67d (0) e787 (0)\n002 2 9fee 94aa | 26 8163 (0) 8612 (0) 86f7 (0) 8ac8 (0)\n003 1 b4c7 | 14 b8a7 (0) baf3 (0) bc08 (0) be0a (0)\n004 9 a80b abfa aa88 aa50 | 12 a80b (0) abfa (0) aa88 (0) aa50 (0)\n005 1 a033 | 1 a033 (0)\n============ DEPTH: 6 ==========================================\n006 1 a485 | 1 a485 (0)\n007 1 a749 | 1 a749 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ip":"0.0.0.0","ports":{"listener":0,"discovery":0},"id":"6a37e63feed9e68c52cb8b385d5e8d8dbd2b211c57ded0d3b01fe8b306af5c0e5a7405d0d9a942648f0131926240d53450bc43f922a053528e5830d918313c3d","enode":"enode://6a37e63feed9e68c52cb8b385d5e8d8dbd2b211c57ded0d3b01fe8b306af5c0e5a7405d0d9a942648f0131926240d53450bc43f922a053528e5830d918313c3d@0.0.0.0:0","name":"node141","listenAddr":""},"up":true,"config":{"id":"6a37e63feed9e68c52cb8b385d5e8d8dbd2b211c57ded0d3b01fe8b306af5c0e5a7405d0d9a942648f0131926240d53450bc43f922a053528e5830d918313c3d","private_key":"392b881dddc671e72fc89ef71b340f19840650943cae22682d6cb6f97570c1ac","services":["pss","bzz"],"name":"node141"}}},{"node":{"info":{"id":"f5d95e0c5a873ff5a95e1eb34f1ed258d77adf98ee0886d93c4a24b1feaf6955e6e4c4ea0eccb2b9723870bae61e693643d6ad96dd8da01672542611f7c49069","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 1d9364\npopulation: 23 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 8 94aa abfa aa50 a672 | 121 8163 (0) 86f7 (0) 8612 (0) 8ac8 (0)\n001 1 5571 | 62 6ea5 (0) 6d21 (0) 6dbd (0) 6330 (0)\n002 2 29ff 31ed | 35 3af3 (0) 3a4a (0) 396b (0) 388d (0)\n003 1 0eee | 12 03f5 (0) 0210 (0) 004e (0) 06aa (0)\n004 1 1441 | 8 13d8 (0) 12b9 (0) 123f (0) 1673 (0)\n005 3 185a 1a02 1b72 | 10 194a (0) 193e (0) 18f9 (0) 1835 (0)\n006 2 1e44 1e42 | 2 1e44 (0) 1e42 (0)\n007 1 1c98 | 1 1c98 (0)\n008 2 1d5f 1d07 | 2 1d5f (0) 1d07 (0)\n009 0 | 0\n============ DEPTH: 10 ==========================================\n010 1 1da3 | 1 1da3 (0)\n011 0 | 0\n012 0 | 0\n013 1 1d94 | 1 1d94 (0)\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"HZNk3MGenJRFm+QqhHQgeAaBPVWsdo6o50Io+9c75ZE="},"ip":"0.0.0.0","ports":{"listener":0,"discovery":0},"listenAddr":"","enode":"enode://f5d95e0c5a873ff5a95e1eb34f1ed258d77adf98ee0886d93c4a24b1feaf6955e6e4c4ea0eccb2b9723870bae61e693643d6ad96dd8da01672542611f7c49069@0.0.0.0:0","name":"node142"},"up":true,"config":{"name":"node142","services":["pss","bzz"],"private_key":"f6541fa1eb8508dbcfde0259a988d0564c192cd25b2051e1299c32cad9ceb149","id":"f5d95e0c5a873ff5a95e1eb34f1ed258d77adf98ee0886d93c4a24b1feaf6955e6e4c4ea0eccb2b9723870bae61e693643d6ad96dd8da01672542611f7c49069"}}},{"node":{"info":{"ports":{"discovery":0,"listener":0},"protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: c99c6a\npopulation: 16 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 1d93 | 135 6dbd (0) 6d21 (0) 6ea5 (0) 6544 (0)\n001 1 af35 | 56 8163 (0) 86f7 (0) 8612 (0) 8ac8 (0)\n002 1 fd2d | 29 e44b (0) e4c3 (0) e649 (0) e67d (0)\n003 1 df25 | 18 d3fd (0) d3d2 (0) d564 (0) d7ab (0)\n004 5 c3f3 c484 c723 c64f | 9 c15d (0) c0d1 (0) c3f3 (0) c463 (0)\n005 1 ceee | 1 ceee (0)\n006 2 cb69 ca81 | 2 cb69 (0) ca81 (0)\n007 2 c8fe c883 | 3 c8f9 (0) c8fe (0) c883 (0)\n008 0 | 0\n============ DEPTH: 9 ==========================================\n009 1 c9f3 | 1 c9f3 (0)\n010 0 | 0\n011 1 c98d | 1 c98d (0)\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"yZxqKi/n9GE8jZGEBMlW6uCgD85UTJ7rpdpkDl6ViHQ="},"ip":"0.0.0.0","id":"bac3fd2ea491d8e4ce1e5d469ec73f3d537d61279ae66e7a394b20a188244a886d3059ef0d304c0801878f9640374f7c8aaf56558c41f12296d3fc7f911ed66c","name":"node143","enode":"enode://bac3fd2ea491d8e4ce1e5d469ec73f3d537d61279ae66e7a394b20a188244a886d3059ef0d304c0801878f9640374f7c8aaf56558c41f12296d3fc7f911ed66c@0.0.0.0:0","listenAddr":""},"up":true,"config":{"name":"node143","services":["pss","bzz"],"private_key":"59014852ab4f95ef336b10bb7c05d22e54eb0ea453d0f1c56638852ffac3aab0","id":"bac3fd2ea491d8e4ce1e5d469ec73f3d537d61279ae66e7a394b20a188244a886d3059ef0d304c0801878f9640374f7c8aaf56558c41f12296d3fc7f911ed66c"}}},{"node":{"info":{"listenAddr":"","name":"node144","enode":"enode://33cac8f621b9122e118036154778d27dc419b6b58ea2e89b833f3932f411dbc3511d92b55ae4cf80632142bc8e67994899aaa30c499d0289fae85b12564cf01f@0.0.0.0:0","id":"33cac8f621b9122e118036154778d27dc419b6b58ea2e89b833f3932f411dbc3511d92b55ae4cf80632142bc8e67994899aaa30c499d0289fae85b12564cf01f","ip":"0.0.0.0","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: af358f\npopulation: 15 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 1b72 | 135 6d21 (0) 6dbd (0) 6ea5 (0) 6330 (0)\n001 2 df25 c99c | 65 e839 (0) ecd2 (0) edca (0) ed13 (0)\n002 2 9fee 94aa | 26 8163 (0) 8612 (0) 86f7 (0) 8ae6 (0)\n003 1 b60d | 14 bc08 (0) be0a (0) bf5a (0) bfec (0)\n004 1 a672 | 4 a033 (0) a485 (0) a749 (0) a672 (0)\n005 2 abfa aa50 | 4 a80b (0) abfa (0) aa88 (0) aa50 (0)\n006 2 ad36 adfc | 3 aca1 (0) ad36 (0) adfc (0)\n007 2 ae65 ae71 | 2 ae65 (0) ae71 (0)\n008 0 | 0\n============ DEPTH: 9 ==========================================\n009 1 af5f | 1 af5f (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 1 af30 | 1 af30 (0)\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"rzWPYmc40uXRcGCruvJMsBJKSMXtuPO67aML6ntAPfo="},"ports":{"listener":0,"discovery":0}},"config":{"name":"node144","services":["pss","bzz"],"private_key":"45d467a8320183e6e9f9fb0219c71ee08f43352c83c0b2d84da4ae4241b0173c","id":"33cac8f621b9122e118036154778d27dc419b6b58ea2e89b833f3932f411dbc3511d92b55ae4cf80632142bc8e67994899aaa30c499d0289fae85b12564cf01f"},"up":true}},{"node":{"up":true,"config":{"services":["pss","bzz"],"name":"node145","id":"f056acbdf491d1bb091937335c10096ea44b7034e994d134bc16d55212ff049bb097424de96c615ea699359a7ef77b3b54def2b3a5f43d735ffda65f73d61f7f","private_key":"3c564ae34741afc14a8ea217a734d5a8bc6d8dfcce3f4943acff14036edbf1c0"},"info":{"id":"f056acbdf491d1bb091937335c10096ea44b7034e994d134bc16d55212ff049bb097424de96c615ea699359a7ef77b3b54def2b3a5f43d735ffda65f73d61f7f","ip":"0.0.0.0","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 1b7250\npopulation: 18 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 c63e fd2d a672 af35 | 121 e839 (0) ecd2 (0) edca (0) ed13 (0)\n001 1 5571 | 62 6d21 (0) 6dbd (0) 6ea5 (0) 6544 (0)\n002 2 31ed 3538 | 35 3af3 (0) 3a4a (0) 396b (0) 388d (0)\n003 1 0eee | 12 03f5 (0) 0210 (0) 004e (0) 06aa (0)\n004 1 123f | 8 13d8 (0) 12b9 (0) 123f (0) 1673 (0)\n005 4 1d07 1d93 1e44 1e42 | 8 1c98 (0) 1d5f (0) 1d07 (0) 1da3 (0)\n006 1 185a | 5 194a (0) 193e (0) 18f9 (0) 1835 (0)\n007 2 1a83 1a02 | 2 1a83 (0) 1a02 (0)\n============ DEPTH: 8 ==========================================\n008 1 1b86 | 1 1b86 (0)\n009 1 1b1e | 1 1b1e (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"G3JQ2uHysHUEs4HSgIS3UaJqx5Gh7YQupXRoJquFuiI="},"ports":{"listener":0,"discovery":0},"listenAddr":"","enode":"enode://f056acbdf491d1bb091937335c10096ea44b7034e994d134bc16d55212ff049bb097424de96c615ea699359a7ef77b3b54def2b3a5f43d735ffda65f73d61f7f@0.0.0.0:0","name":"node145"}}},{"node":{"info":{"protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 1e42fc\npopulation: 23 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 7 abfa a672 94aa 8c89 | 121 e839 (0) ecd2 (0) edca (0) ed13 (0)\n001 1 5571 | 62 77ec (0) 7471 (0) 7406 (0) 759e (0)\n002 3 34fc 3538 2a22 | 35 211a (0) 2168 (0) 2013 (0) 2279 (0)\n003 1 0eee | 12 06aa (0) 05ec (0) 05e8 (0) 0592 (0)\n004 1 1441 | 8 13d8 (0) 12b9 (0) 123f (0) 1673 (0)\n005 3 185a 1a02 1b72 | 10 193e (0) 194a (0) 18f9 (0) 1835 (0)\n============ DEPTH: 6 ==========================================\n006 6 1c98 1d07 1d5f 1da3 | 6 1c98 (0) 1d07 (0) 1d5f (0) 1da3 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 1 1e44 | 1 1e44 (0)\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"HkL8vWc1dE5QXxL2sIWKn9F8Cnc2ppqwuWkkWjyx1uQ="},"ports":{"discovery":0,"listener":0},"ip":"0.0.0.0","id":"b87e7f36ed6bf142d48545024d2fd6e120c44511701e7c0b7d7fc786f4f29d3357024b15f70b78215d8a4c2b7572d608c11b31612743e23db4fa673f0cd6519b","enode":"enode://b87e7f36ed6bf142d48545024d2fd6e120c44511701e7c0b7d7fc786f4f29d3357024b15f70b78215d8a4c2b7572d608c11b31612743e23db4fa673f0cd6519b@0.0.0.0:0","name":"node146","listenAddr":""},"config":{"id":"b87e7f36ed6bf142d48545024d2fd6e120c44511701e7c0b7d7fc786f4f29d3357024b15f70b78215d8a4c2b7572d608c11b31612743e23db4fa673f0cd6519b","private_key":"43f552096880ddd297dd590b83f738fa13826e6120ec3d6311ac565b78a252c7","services":["pss","bzz"],"name":"node146"},"up":true}},{"node":{"up":true,"config":{"services":["pss","bzz"],"name":"node147","id":"46717bc5fb7fcbcdc961e7ef091020f9f222858cf3d4afcc0b0bb1b782b7055d9eb833e0a04cb32d80406133ac77162521c43edf9f9690872222760e31462ccc","private_key":"177c7e7e8e870ff8b4b606ee3bc6f94d6fa57fd6deabefdabb250776939ef9f9"},"info":{"id":"46717bc5fb7fcbcdc961e7ef091020f9f222858cf3d4afcc0b0bb1b782b7055d9eb833e0a04cb32d80406133ac77162521c43edf9f9690872222760e31462ccc","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: fd2df4\npopulation: 24 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 1b72 1d93 1e42 | 135 7307 (0) 72fa (0) 72ac (0) 7294 (0)\n001 5 8c89 94aa adfc aa50 | 56 9a82 (0) 99aa (0) 99fb (0) 99db (0)\n002 5 dae3 df25 c883 c99c | 36 d3fd (0) d3d2 (0) d564 (0) d7ab (0)\n003 1 e76a | 12 e839 (0) ecd2 (0) edca (0) ed13 (0)\n004 5 f5dd f644 f78a f0e2 | 11 f3d3 (0) f048 (0) f0e2 (0) f156 (0)\n============ DEPTH: 5 ==========================================\n005 4 fa74 fb93 f924 f915 | 4 fa74 (0) fb93 (0) f924 (0) f915 (0)\n006 1 fed1 | 1 fed1 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"/S30349ffHzOGYzf8H8q3A5otkb8wEY2PShGNcaLu5M="},"ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","name":"node147","enode":"enode://46717bc5fb7fcbcdc961e7ef091020f9f222858cf3d4afcc0b0bb1b782b7055d9eb833e0a04cb32d80406133ac77162521c43edf9f9690872222760e31462ccc@0.0.0.0:0"}}},{"node":{"info":{"listenAddr":"","enode":"enode://c2568576c2c9ef47aca0baca52709a4fa44b2ed478a062f7b161fac2bdba68568df371ac7754255fd07d79bb9918249a914946a6c318d579730bee9bc609922a@0.0.0.0:0","name":"node148","id":"c2568576c2c9ef47aca0baca52709a4fa44b2ed478a062f7b161fac2bdba68568df371ac7754255fd07d79bb9918249a914946a6c318d579730bee9bc609922a","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: abfabc\npopulation: 20 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 1e42 1d93 5571 | 135 6d21 (0) 6dbd (0) 6ea5 (0) 6544 (0)\n001 3 c883 c63e fd2d | 65 d3fd (0) d3d2 (0) d564 (0) d7ab (0)\n002 3 9fee 94aa 8c89 | 26 9a82 (0) 99aa (0) 99fb (0) 99db (0)\n003 2 b4c7 b60d | 14 b8a7 (0) baf3 (0) bc08 (0) be0a (0)\n004 1 a672 | 4 a033 (0) a485 (0) a749 (0) a672 (0)\n005 5 ad36 adfc af5f af35 | 8 ae65 (0) ae71 (0) af5f (0) af30 (0)\n006 1 a80b | 1 a80b (0)\n============ DEPTH: 7 ==========================================\n007 2 aa88 aa50 | 2 aa88 (0) aa50 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"q/q8KWTOL3uLNwLol6jMg/sMAJ1a+WcLiJ21guV+98E="},"ports":{"discovery":0,"listener":0},"ip":"0.0.0.0"},"config":{"name":"node148","services":["pss","bzz"],"private_key":"26c019de3883a787fafed3839e768c71553ec8fe6cf607725f0e2acc80711cee","id":"c2568576c2c9ef47aca0baca52709a4fa44b2ed478a062f7b161fac2bdba68568df371ac7754255fd07d79bb9918249a914946a6c318d579730bee9bc609922a"},"up":true}},{"node":{"info":{"name":"node149","enode":"enode://6b104eff1dcf58d11a7f707bbd41a910b2735b262c29e0f4e4127fda1b67def4e89b6ebc1b3cc1e06c3968d0898e1085badc7da24d3cd6624cb100e85863cc97@0.0.0.0:0","listenAddr":"","protocols":{"bzz":"xj55bv3ERxJAMZnBHD5f8o5dak2ezfPpViD71q+xvC0=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: c63e79\npopulation: 16 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 1b72 604c 5571 | 135 77ec (0) 759e (0) 7471 (0) 7406 (0)\n001 2 8c89 abfa | 56 9a82 (0) 99aa (0) 99db (0) 99fb (0)\n002 1 fd2d | 29 e839 (0) ecd2 (0) edca (0) ed13 (0)\n003 2 dae3 df25 | 18 d3fd (0) d3d2 (0) d564 (0) d7ab (0)\n004 2 c99c c883 | 9 ceee (0) cb69 (0) ca81 (0) c9f3 (0)\n005 1 c3f3 | 3 c15d (0) c0d1 (0) c3f3 (0)\n006 2 c463 c484 | 2 c463 (0) c484 (0)\n============ DEPTH: 7 ==========================================\n007 2 c770 c723 | 2 c770 (0) c723 (0)\n008 0 | 0\n009 1 c64f | 1 c64f (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"discovery":0,"listener":0},"ip":"0.0.0.0","id":"6b104eff1dcf58d11a7f707bbd41a910b2735b262c29e0f4e4127fda1b67def4e89b6ebc1b3cc1e06c3968d0898e1085badc7da24d3cd6624cb100e85863cc97"},"config":{"private_key":"943fd9910b9fa6cdb47ec68ec64b2faecd9a56de487fba1b7773a6dd54f94664","id":"6b104eff1dcf58d11a7f707bbd41a910b2735b262c29e0f4e4127fda1b67def4e89b6ebc1b3cc1e06c3968d0898e1085badc7da24d3cd6624cb100e85863cc97","name":"node149","services":["pss","bzz"]},"up":true}},{"node":{"up":true,"config":{"id":"3e7aef8260c0d9717aa59b65ce7c554e53b81f19f5b9400321704a7ddf5041b0fe31b5634e90b93e6984060defee0e153997bbfe196166cc8d83165fd5eaf41f","private_key":"f75e19af5d5e340e6a07d85042608f0500511042eb2e1ccbae8fe8569b9cbc8c","services":["pss","bzz"],"name":"node150"},"info":{"name":"node150","enode":"enode://3e7aef8260c0d9717aa59b65ce7c554e53b81f19f5b9400321704a7ddf5041b0fe31b5634e90b93e6984060defee0e153997bbfe196166cc8d83165fd5eaf41f@0.0.0.0:0","listenAddr":"","ip":"0.0.0.0","protocols":{"bzz":"yIPihQ8KkBr1gTDofE+B2JiwO+i4i1gK5wdebECzPY4=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: c883e2\npopulation: 21 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 5571 2a22 1e42 1d93 | 135 3dca (0) 3d6b (0) 3f3e (0) 3e44 (0)\n001 2 abfa 8c89 | 56 9294 (0) 9232 (0) 9390 (0) 96b6 (0)\n002 1 fd2d | 29 e839 (0) ecd2 (0) edca (0) ed13 (0)\n003 3 d822 dae3 df25 | 18 d3fd (0) d3d2 (0) d564 (0) d7ab (0)\n004 4 c3f3 c723 c64f c63e | 9 c15d (0) c0d1 (0) c3f3 (0) c463 (0)\n005 1 ceee | 1 ceee (0)\n006 2 ca81 cb69 | 2 ca81 (0) cb69 (0)\n007 2 c9f3 c99c | 3 c9f3 (0) c98d (0) c99c (0)\n008 0 | 0\n============ DEPTH: 9 ==========================================\n009 2 c8f9 c8fe | 2 c8f9 (0) c8fe (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"listener":0,"discovery":0},"id":"3e7aef8260c0d9717aa59b65ce7c554e53b81f19f5b9400321704a7ddf5041b0fe31b5634e90b93e6984060defee0e153997bbfe196166cc8d83165fd5eaf41f"}}},{"node":{"up":true,"config":{"private_key":"e400c8293b9474c5aa84b48e37e1f435a53c910af98fd4e1b23ff9bd670bb51f","id":"dbb6621460b054f584f1c6157b4020f3c58d84c3a12b57436e10525ae60ab27036bf3edd68b92f2b13674877d01c2871dc67a9031c3d0470985f4b071696346e","name":"node151","services":["pss","bzz"]},"info":{"listenAddr":"","name":"node151","enode":"enode://dbb6621460b054f584f1c6157b4020f3c58d84c3a12b57436e10525ae60ab27036bf3edd68b92f2b13674877d01c2871dc67a9031c3d0470985f4b071696346e@0.0.0.0:0","id":"dbb6621460b054f584f1c6157b4020f3c58d84c3a12b57436e10525ae60ab27036bf3edd68b92f2b13674877d01c2871dc67a9031c3d0470985f4b071696346e","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 8c89e1\npopulation: 25 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 6 0eee 1a02 1e42 604c | 135 3af3 (0) 3a4a (0) 396b (0) 388d (0)\n001 4 f915 fd2d c63e c883 | 65 e3c9 (0) e44b (0) e4c3 (0) e67d (0)\n002 2 ae71 abfa | 30 baf3 (0) b8a7 (0) be0a (0) bf5a (0)\n003 5 9c0c 9c01 9fee 9390 | 16 9a82 (0) 99aa (0) 99fb (0) 99db (0)\n004 2 8612 86f7 | 3 8163 (0) 8612 (0) 86f7 (0)\n============ DEPTH: 5 ==========================================\n005 5 8ac8 8ae6 8874 88da | 5 8ac8 (0) 8ae6 (0) 8874 (0) 88da (0)\n006 0 | 0\n007 0 | 0\n008 1 8c61 | 1 8c61 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"jInhgcb7GAeLQE1HsQxw1X1mQzk1Be2KyI5jI26iJKA="},"ports":{"listener":0,"discovery":0},"ip":"0.0.0.0"}}},{"node":{"info":{"id":"6c2788dec7ae7a77134065afc1174bb92b87833e87acaa72fe9e62c92d2017f217f9fbc5884cdfb7236a7bb75e463e49ecceb1641a8629516211d9699587046e","ip":"0.0.0.0","protocols":{"bzz":"VXHJNkJnAlU9ZFZNVqkJxiioIz7UNqzCo7n4UMXGtvA=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 5571c9\npopulation: 22 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 c883 c63e abfa 8c89 | 121 e839 (0) ecd2 (0) edca (0) ed13 (0)\n001 5 2a22 0eee 1b72 1d93 | 73 3af3 (0) 3a4a (0) 396b (0) 388d (0)\n002 3 6610 604c 7dc6 | 31 6ea5 (0) 6dbd (0) 6d21 (0) 6544 (0)\n003 3 4d44 4fd6 4f90 | 17 4019 (0) 43af (0) 42c0 (0) 42d4 (0)\n004 1 5c5d | 5 5fd0 (0) 5fab (0) 5fa8 (0) 5f05 (0)\n005 2 5110 5261 | 4 5093 (0) 5110 (0) 5288 (0) 5261 (0)\n============ DEPTH: 6 ==========================================\n006 4 566e 5695 57d5 5716 | 4 566e (0) 5695 (0) 57d5 (0) 5716 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"listener":0,"discovery":0},"listenAddr":"","name":"node152","enode":"enode://6c2788dec7ae7a77134065afc1174bb92b87833e87acaa72fe9e62c92d2017f217f9fbc5884cdfb7236a7bb75e463e49ecceb1641a8629516211d9699587046e@0.0.0.0:0"},"config":{"name":"node152","services":["pss","bzz"],"private_key":"f5a6a565c7c14cba96a75712373743d09ba804a9b8332a667492617dd5211abb","id":"6c2788dec7ae7a77134065afc1174bb92b87833e87acaa72fe9e62c92d2017f217f9fbc5884cdfb7236a7bb75e463e49ecceb1641a8629516211d9699587046e"},"up":true}},{"node":{"up":true,"config":{"services":["pss","bzz"],"name":"node153","id":"89d46e664ac471c7150fbfe43a49c98750fc64d5ca22fdc2a040c7ab78c25c48c1e9c2f0e5130d6b8eb7f0760fe962759d83f68cc08ffaac3520499b0ce694de","private_key":"4f592401cb57bcdc263bb96492ca66258130460b5fcb1a1cfafdedef3cee99f7"},"info":{"listenAddr":"","enode":"enode://89d46e664ac471c7150fbfe43a49c98750fc64d5ca22fdc2a040c7ab78c25c48c1e9c2f0e5130d6b8eb7f0760fe962759d83f68cc08ffaac3520499b0ce694de@0.0.0.0:0","name":"node153","id":"89d46e664ac471c7150fbfe43a49c98750fc64d5ca22fdc2a040c7ab78c25c48c1e9c2f0e5130d6b8eb7f0760fe962759d83f68cc08ffaac3520499b0ce694de","ports":{"listener":0,"discovery":0},"protocols":{"bzz":"fcY8gUbtCSqkyVOavREtw6cDYx42SmL9dLGS7uV3gSM=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 7dc63c\npopulation: 16 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 8c89 | 121 e3c9 (0) e649 (0) e67d (0) e787 (0)\n001 1 0eee | 73 3a4a (0) 3af3 (0) 396b (0) 388d (0)\n002 2 5261 5571 | 31 4019 (0) 43af (0) 42c0 (0) 42d4 (0)\n003 2 6610 604c | 11 6ea5 (0) 6dbd (0) 6d21 (0) 6544 (0)\n004 3 77ec 7471 759e | 8 77ec (0) 7471 (0) 7406 (0) 759e (0)\n005 2 7a41 7851 | 6 7a41 (0) 79bd (0) 79ab (0) 7829 (0)\n006 2 7fa4 7ffe | 2 7fa4 (0) 7ffe (0)\n007 0 | 0\n008 1 7d45 | 1 7d45 (0)\n============ DEPTH: 9 ==========================================\n009 1 7d94 | 1 7d94 (0)\n010 1 7de7 | 1 7de7 (0)\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ip":"0.0.0.0"}}},{"node":{"up":true,"config":{"name":"node154","services":["pss","bzz"],"private_key":"97486d2d37010143a830ed6a0be6528a5611fc42962ae80e44a12c9b3399502c","id":"5319bc9864d87eb33f26ff9732824d21a0a5ab70b254bc70a47554ffc763ae1559000d07e3eac9f883bd9e7f249d80edf14ab39c89c375bfcc5ec9e840ec9673"},"info":{"listenAddr":"","name":"node154","enode":"enode://5319bc9864d87eb33f26ff9732824d21a0a5ab70b254bc70a47554ffc763ae1559000d07e3eac9f883bd9e7f249d80edf14ab39c89c375bfcc5ec9e840ec9673@0.0.0.0:0","id":"5319bc9864d87eb33f26ff9732824d21a0a5ab70b254bc70a47554ffc763ae1559000d07e3eac9f883bd9e7f249d80edf14ab39c89c375bfcc5ec9e840ec9673","protocols":{"bzz":"Du7ZCBTpQIyU6BKW97aBrBjtrNpethGvf2kwZSTxiLg=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 0eeed9\npopulation: 24 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 f915 8c89 | 121 d68f (0) d6f3 (0) d6d2 (0) d7ab (0)\n001 3 5571 7dc6 604c | 62 4019 (0) 43af (0) 42c0 (0) 42d4 (0)\n002 2 34fc 2a22 | 35 3af3 (0) 3a4a (0) 396b (0) 388d (0)\n003 6 123f 1da3 1d93 1e42 | 26 13d8 (0) 12b9 (0) 123f (0) 1673 (0)\n004 8 03f5 0210 004e 06aa | 8 03f5 (0) 0210 (0) 004e (0) 06aa (0)\n005 0 | 0\n006 0 | 0\n============ DEPTH: 7 ==========================================\n007 2 0f5e 0f81 | 2 0f5e (0) 0f81 (0)\n008 0 | 0\n009 1 0ea2 | 1 0ea2 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ip":"0.0.0.0","ports":{"listener":0,"discovery":0}}}},{"node":{"info":{"enode":"enode://488854534ec5a3479d8ee13d9b7daf07479f6b5505f319eced44dad8c316f6ff241ce2101e95608ba635067f5e5741481b78f419c4bbd465bf7e837dc4e54d64@0.0.0.0:0","name":"node155","listenAddr":"","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 604c6b\npopulation: 20 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 f915 c63e 8c89 | 121 d3d2 (0) d3fd (0) d7ab (0) d68f (0)\n001 3 2a22 1a02 0eee | 73 3a4a (0) 3af3 (0) 396b (0) 388d (0)\n002 3 4f90 5571 5261 | 31 4019 (0) 43af (0) 42c0 (0) 42d4 (0)\n003 2 7851 7dc6 | 20 77ec (0) 759e (0) 7406 (0) 7471 (0)\n004 3 6ea5 6dbd 6d21 | 3 6ea5 (0) 6dbd (0) 6d21 (0)\n005 4 6544 67a2 6783 6610 | 5 6544 (0) 670d (0) 67a2 (0) 6783 (0)\n============ DEPTH: 6 ==========================================\n006 1 6330 | 1 6330 (0)\n007 1 6143 | 1 6143 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"YExr+rT10W1beGMYz4+eAZf8GOXYqOb0/TReZT0qvhc="},"ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"id":"488854534ec5a3479d8ee13d9b7daf07479f6b5505f319eced44dad8c316f6ff241ce2101e95608ba635067f5e5741481b78f419c4bbd465bf7e837dc4e54d64"},"up":true,"config":{"name":"node155","services":["pss","bzz"],"private_key":"d93efde40fe67c2f412577aefbc6af1e876bde81b53c22ef6da4a5a23c8c13ad","id":"488854534ec5a3479d8ee13d9b7daf07479f6b5505f319eced44dad8c316f6ff241ce2101e95608ba635067f5e5741481b78f419c4bbd465bf7e837dc4e54d64"}}},{"node":{"up":true,"config":{"services":["pss","bzz"],"name":"node156","id":"3b71a324bd7b1a8fb19d8206eea1ca8190cb1faf5fcd1bfc52cef6b52296fe1db3e54d70180133fad1fa1188499d0dd73d2d075fdc6b3ffd9042d690e7d88e02","private_key":"eaab112f5381b5b84ac9920fede88f2e04b725398e37a0b1b003442c281e32a1"},"info":{"id":"3b71a324bd7b1a8fb19d8206eea1ca8190cb1faf5fcd1bfc52cef6b52296fe1db3e54d70180133fad1fa1188499d0dd73d2d075fdc6b3ffd9042d690e7d88e02","protocols":{"bzz":"GgIQjZFJc5vmuoXd0eijlhre7Dj3f875WrV/jy859Ls=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 1a0210\npopulation: 18 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 8c89 | 121 d564 (0) d68f (0) d6f3 (0) d6d2 (0)\n001 2 6610 604c | 62 4019 (0) 43af (0) 42c0 (0) 42d4 (0)\n002 2 2a22 34fc | 35 2374 (0) 2279 (0) 2013 (0) 211a (0)\n003 1 0eee | 12 03f5 (0) 0210 (0) 004e (0) 06aa (0)\n004 2 1441 123f | 8 13d8 (0) 12b9 (0) 123f (0) 1673 (0)\n005 4 1d5f 1da3 1d93 1e42 | 8 1c98 (0) 1d07 (0) 1d5f (0) 1da3 (0)\n006 2 1835 185a | 5 194a (0) 193e (0) 18f9 (0) 1835 (0)\n============ DEPTH: 7 ==========================================\n007 3 1b86 1b1e 1b72 | 3 1b86 (0) 1b1e (0) 1b72 (0)\n008 1 1a83 | 1 1a83 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"discovery":0,"listener":0},"ip":"0.0.0.0","listenAddr":"","enode":"enode://3b71a324bd7b1a8fb19d8206eea1ca8190cb1faf5fcd1bfc52cef6b52296fe1db3e54d70180133fad1fa1188499d0dd73d2d075fdc6b3ffd9042d690e7d88e02@0.0.0.0:0","name":"node156"}}},{"node":{"config":{"name":"node157","services":["pss","bzz"],"private_key":"f79356978056456eb8f10bcf3c06b107a4afb4d5a8c2fc9380011a7420d59c81","id":"45d3827eb5c3b906fc61aaad79c5968f3dcf7b1ecc1e3be63e827ad6fb9291542686f42b3e142f43cc0437a2177b7362727842ea1d6c33bc795d936bba3ae457"},"up":true,"info":{"ip":"0.0.0.0","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 34fce2\npopulation: 13 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 a80b | 121 b310 (0) b5c7 (0) b4c7 (0) b45d (0)\n001 1 4f90 | 62 77ec (0) 759e (0) 7406 (0) 7471 (0)\n002 3 0eee 1e42 1a02 | 38 03f5 (0) 0210 (0) 004e (0) 06aa (0)\n003 1 2a22 | 20 2374 (0) 2279 (0) 2013 (0) 211a (0)\n004 3 396b 388d 3e85 | 9 3af3 (0) 3a4a (0) 396b (0) 388d (0)\n005 2 31ed 3345 | 3 31ed (0) 32dd (0) 3345 (0)\n============ DEPTH: 6 ==========================================\n006 1 3648 | 1 3648 (0)\n007 1 3538 | 1 3538 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"NPziuCCMbI7QBZQ7Pyy5+JI3Oc4mLiBA9//ASAk++RA="},"ports":{"listener":0,"discovery":0},"id":"45d3827eb5c3b906fc61aaad79c5968f3dcf7b1ecc1e3be63e827ad6fb9291542686f42b3e142f43cc0437a2177b7362727842ea1d6c33bc795d936bba3ae457","name":"node157","enode":"enode://45d3827eb5c3b906fc61aaad79c5968f3dcf7b1ecc1e3be63e827ad6fb9291542686f42b3e142f43cc0437a2177b7362727842ea1d6c33bc795d936bba3ae457@0.0.0.0:0","listenAddr":""}}},{"node":{"up":true,"config":{"services":["pss","bzz"],"name":"node158","id":"e9cd25d1ef3fef22160bce7f7badd7646ac58ee40da6a438f61a067c51bc51d6087ed950ec9e909bc438ebe62e316cbd9489f3c9bfa2898615632414e04f1dcd","private_key":"f0c66841f0adf1a9af04982fcce0c38c5012595de449dd0a8ea97ba06d5e43e9"},"info":{"id":"e9cd25d1ef3fef22160bce7f7badd7646ac58ee40da6a438f61a067c51bc51d6087ed950ec9e909bc438ebe62e316cbd9489f3c9bfa2898615632414e04f1dcd","protocols":{"bzz":"T5D1N1TuUDV0kdurfD5nSLQBM+MzmSCzL0w0V/QlhHc=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 4f90f5\npopulation: 14 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 f915 | 121 b310 (0) b60d (0) b79f (0) b710 (0)\n001 2 2a22 34fc | 73 03f5 (0) 0210 (0) 004e (0) 06aa (0)\n002 2 6610 604c | 31 77ec (0) 759e (0) 7406 (0) 7471 (0)\n003 2 5571 5261 | 14 5fd0 (0) 5fab (0) 5fa8 (0) 5f05 (0)\n004 3 47f9 42c0 42d4 | 7 4019 (0) 43af (0) 42c0 (0) 42d4 (0)\n005 1 487e | 6 4b00 (0) 4a67 (0) 4a82 (0) 4a81 (0)\n============ DEPTH: 6 ==========================================\n006 2 4cf6 4d44 | 2 4cf6 (0) 4d44 (0)\n007 0 | 0\n008 0 | 0\n009 1 4fd6 | 1 4fd6 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"listener":0,"discovery":0},"ip":"0.0.0.0","listenAddr":"","name":"node158","enode":"enode://e9cd25d1ef3fef22160bce7f7badd7646ac58ee40da6a438f61a067c51bc51d6087ed950ec9e909bc438ebe62e316cbd9489f3c9bfa2898615632414e04f1dcd@0.0.0.0:0"}}},{"node":{"info":{"protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 52619a\npopulation: 17 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 f915 | 121 b310 (0) b60d (0) b79f (0) b710 (0)\n001 1 2a22 | 73 03f5 (0) 0210 (0) 004e (0) 06aa (0)\n002 3 7dc6 604c 6610 | 31 77ec (0) 759e (0) 7406 (0) 7471 (0)\n003 3 4d44 4fd6 4f90 | 17 4019 (0) 43af (0) 42c0 (0) 42d4 (0)\n004 3 5fa8 5f05 5c5d | 5 5fd0 (0) 5fab (0) 5fa8 (0) 5f05 (0)\n005 3 5716 5695 5571 | 5 57d5 (0) 5716 (0) 566e (0) 5695 (0)\n============ DEPTH: 6 ==========================================\n006 2 5093 5110 | 2 5110 (0) 5093 (0)\n007 0 | 0\n008 1 5288 | 1 5288 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"UmGaUjBQqoyqMkSOWXIadtwzIdySz8sbBfHOxbedQko="},"ports":{"discovery":0,"listener":0},"ip":"0.0.0.0","id":"3dcf18c35593b47bc463688493b792d6b9d13eabe05396e491953608f20cf55f770fc21be32b00335fcb2f0ba02735b92569b2b64a44c344ac348042876e8f15","name":"node159","enode":"enode://3dcf18c35593b47bc463688493b792d6b9d13eabe05396e491953608f20cf55f770fc21be32b00335fcb2f0ba02735b92569b2b64a44c344ac348042876e8f15@0.0.0.0:0","listenAddr":""},"up":true,"config":{"name":"node159","services":["pss","bzz"],"private_key":"cc124633e255f1c6ba0beb16fb978958ed79be0e0f6ebd7968ef82b6d439fcda","id":"3dcf18c35593b47bc463688493b792d6b9d13eabe05396e491953608f20cf55f770fc21be32b00335fcb2f0ba02735b92569b2b64a44c344ac348042876e8f15"}}},{"node":{"up":true,"config":{"name":"node160","services":["pss","bzz"],"private_key":"223b2c119cccb5059319a4a0305aec9c1bace6e731215f699cbd4d9a056ec777","id":"ee3471e1d835c4294f7ba642103039ccc548fe4edc177c79b63433ebbb0dc9d06600844f1fed76c7096ee9538e49e4e86fb8cffe9095dbdcde27695ff28ad395"},"info":{"ports":{"listener":0,"discovery":0},"protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 66100e\npopulation: 19 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 f915 | 121 b310 (0) b60d (0) b79f (0) b710 (0)\n001 3 3538 1da3 1a02 | 73 03f5 (0) 0210 (0) 004e (0) 06aa (0)\n002 5 5571 5261 4d44 4f90 | 31 5fd0 (0) 5fab (0) 5fa8 (0) 5f05 (0)\n003 2 7851 7dc6 | 20 77ec (0) 759e (0) 7471 (0) 7406 (0)\n004 2 6dbd 6d21 | 3 6ea5 (0) 6dbd (0) 6d21 (0)\n005 2 6143 604c | 3 6330 (0) 6143 (0) 604c (0)\n006 1 6544 | 1 6544 (0)\n============ DEPTH: 7 ==========================================\n007 3 670d 6783 67a2 | 3 670d (0) 6783 (0) 67a2 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"ZhAOT50QPZNRZPOeo/AzJwjzgl688xrG+MlxTHWlCGA="},"ip":"0.0.0.0","id":"ee3471e1d835c4294f7ba642103039ccc548fe4edc177c79b63433ebbb0dc9d06600844f1fed76c7096ee9538e49e4e86fb8cffe9095dbdcde27695ff28ad395","enode":"enode://ee3471e1d835c4294f7ba642103039ccc548fe4edc177c79b63433ebbb0dc9d06600844f1fed76c7096ee9538e49e4e86fb8cffe9095dbdcde27695ff28ad395@0.0.0.0:0","name":"node160","listenAddr":""}}},{"node":{"info":{"protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 4fd6a4\npopulation: 11 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 f915 | 121 b310 (0) b79f (0) b710 (0) b60d (0)\n001 1 2a22 | 73 03f5 (0) 0210 (0) 004e (0) 06aa (0)\n002 1 6610 | 31 77ec (0) 759e (0) 7471 (0) 7406 (0)\n003 2 5571 5261 | 14 5fd0 (0) 5fab (0) 5fa8 (0) 5f05 (0)\n004 2 47f9 42d4 | 7 4019 (0) 43af (0) 42c0 (0) 42d4 (0)\n005 1 487e | 6 4b00 (0) 4a67 (0) 4a82 (0) 4a81 (0)\n============ DEPTH: 6 ==========================================\n006 2 4cf6 4d44 | 2 4cf6 (0) 4d44 (0)\n007 0 | 0\n008 0 | 0\n009 1 4f90 | 1 4f90 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"T9akuZsbp2d1WUZzQhyO6hdcEUUZyFVHmMLDZBdbuq4="},"ports":{"listener":0,"discovery":0},"ip":"0.0.0.0","id":"aa53ca208cc0c9e544fd9d52cab44b5e2887256bb006037b855b5c94d7f79c9388fdbb23c0bf1d2eee12d67125e082fa7ecb34c1129ca8eaecfd85772b009435","name":"node161","enode":"enode://aa53ca208cc0c9e544fd9d52cab44b5e2887256bb006037b855b5c94d7f79c9388fdbb23c0bf1d2eee12d67125e082fa7ecb34c1129ca8eaecfd85772b009435@0.0.0.0:0","listenAddr":""},"up":true,"config":{"name":"node161","services":["pss","bzz"],"private_key":"158d4468a6b4e7413f8b1d4112ef2b2c562e6dd26101b022ece2fa57801e6b03","id":"aa53ca208cc0c9e544fd9d52cab44b5e2887256bb006037b855b5c94d7f79c9388fdbb23c0bf1d2eee12d67125e082fa7ecb34c1129ca8eaecfd85772b009435"}}},{"node":{"info":{"listenAddr":"","enode":"enode://9c8fca41b833e88110559b9258653160f5fb236bd637272ac58fe1adf333f4df75b94a805eaebb9f10a8c1a26d357dd75140560551d3fc4da79da2c4fc9479c3@0.0.0.0:0","name":"node162","id":"9c8fca41b833e88110559b9258653160f5fb236bd637272ac58fe1adf333f4df75b94a805eaebb9f10a8c1a26d357dd75140560551d3fc4da79da2c4fc9479c3","ip":"0.0.0.0","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 2a2253\npopulation: 24 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 c883 e76a | 121 b310 (0) b79f (0) b710 (0) b60d (0)\n001 6 604c 5571 5261 4d44 | 62 7307 (0) 7294 (0) 72ac (0) 72fa (0)\n002 3 0eee 1e42 1a02 | 38 0f81 (0) 0f5e (0) 0ea2 (0) 0eee (0)\n003 6 3345 3538 34fc 388d | 15 31ed (0) 32dd (0) 3345 (0) 3648 (0)\n004 2 2168 2454 | 9 2374 (0) 2279 (0) 2013 (0) 211a (0)\n005 1 2fd8 | 5 2f22 (0) 2f9f (0) 2fd8 (0) 2e9f (1)\n006 2 29fd 29ff | 3 290f (0) 29fd (0) 29ff (0)\n007 0 | 0\n============ DEPTH: 8 ==========================================\n008 1 2af0 | 1 2af0 (0)\n009 1 2a69 | 1 2a69 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"KiJT7GOJR/5AuXSJsuLsDfJuvHfSAidsHSCKPIAsM24="},"ports":{"discovery":0,"listener":0}},"up":true,"config":{"name":"node162","services":["pss","bzz"],"private_key":"9b9249eb2418f61bc1e6a582b28e46c0d25eecf549e98414e2ca5ab1d3f5b1f7","id":"9c8fca41b833e88110559b9258653160f5fb236bd637272ac58fe1adf333f4df75b94a805eaebb9f10a8c1a26d357dd75140560551d3fc4da79da2c4fc9479c3"}}},{"node":{"info":{"id":"ab8eda9b360d3e0b002ba31d48311057880844b828ad9817a2ad19736860d0114d4a17e9e9427c842d52e7ff61a09c2cad9b70f506e338909535542dae38ede0","ports":{"listener":0,"discovery":0},"protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 3e85d2\npopulation: 16 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 e76a f915 | 121 8c61 (0) 8c89 (0) 8ac8 (0) 8ae6 (0)\n001 1 4d44 | 62 77ec (0) 759e (0) 7406 (0) 7471 (0)\n002 2 043f 1da3 | 38 13d8 (0) 12b9 (0) 123f (0) 1673 (0)\n003 1 2a22 | 20 2374 (0) 2279 (0) 2013 (0) 211a (0)\n004 3 3538 34fc 3345 | 6 3648 (0) 3538 (0) 34fc (0) 31ed (0)\n005 3 3a4a 396b 388d | 4 3af3 (0) 3a4a (0) 396b (0) 388d (0)\n006 2 3dca 3d6b | 2 3dca (0) 3d6b (0)\n============ DEPTH: 7 ==========================================\n007 1 3f3e | 1 3f3e (0)\n008 1 3e44 | 1 3e44 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"PoXS09Z1D4RQD89SN0PgwkKUPmkYjLgxFK2tF4fmwIk="},"ip":"0.0.0.0","listenAddr":"","name":"node163","enode":"enode://ab8eda9b360d3e0b002ba31d48311057880844b828ad9817a2ad19736860d0114d4a17e9e9427c842d52e7ff61a09c2cad9b70f506e338909535542dae38ede0@0.0.0.0:0"},"up":true,"config":{"name":"node163","services":["pss","bzz"],"private_key":"92f63cfcb2341c43aee585f9b965979e49d307de204dcc09b8e869f4e67640b4","id":"ab8eda9b360d3e0b002ba31d48311057880844b828ad9817a2ad19736860d0114d4a17e9e9427c842d52e7ff61a09c2cad9b70f506e338909535542dae38ede0"}}},{"node":{"config":{"private_key":"81e7d25a3c5700b592d3ea4cd85440f914f919e65f0a6e55c99ba619a519c70a","id":"1cdef98d7b4de45c902c725384bd14c66084fe4159b26a0f9a24f432e1f561d035ca41e1c60fe64f3213b4f91a1afb953193dca1a7d535be0602b5d046bcbab8","name":"node164","services":["pss","bzz"]},"up":true,"info":{"listenAddr":"","enode":"enode://1cdef98d7b4de45c902c725384bd14c66084fe4159b26a0f9a24f432e1f561d035ca41e1c60fe64f3213b4f91a1afb953193dca1a7d535be0602b5d046bcbab8@0.0.0.0:0","name":"node164","id":"1cdef98d7b4de45c902c725384bd14c66084fe4159b26a0f9a24f432e1f561d035ca41e1c60fe64f3213b4f91a1afb953193dca1a7d535be0602b5d046bcbab8","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 4d447e\npopulation: 16 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 e76a f915 | 121 b310 (0) b60d (0) b79f (0) b710 (0)\n001 5 043f 2a22 3345 3e85 | 73 13d8 (0) 12b9 (0) 123f (0) 1673 (0)\n002 1 6610 | 31 759e (0) 7471 (0) 7406 (0) 77ec (0)\n003 2 5571 5261 | 14 5fd0 (0) 5fab (0) 5fa8 (0) 5f05 (0)\n004 2 42c0 42d4 | 7 4019 (0) 43af (0) 42c0 (0) 42d4 (0)\n005 1 487e | 6 4b00 (0) 4a67 (0) 4a82 (0) 4a81 (0)\n============ DEPTH: 6 ==========================================\n006 2 4fd6 4f90 | 2 4f90 (0) 4fd6 (0)\n007 1 4cf6 | 1 4cf6 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"TUR+qAvBJuV7n8kSA6MQxfSyQt9a1w1Qh9Fml6Ym5gE="},"ports":{"discovery":0,"listener":0},"ip":"0.0.0.0"}}},{"node":{"info":{"ports":{"discovery":0,"listener":0},"protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 388d46\npopulation: 16 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 f915 e76a | 121 b310 (0) b60d (0) b710 (0) b79f (0)\n001 1 4d44 | 62 77ec (0) 759e (0) 7406 (0) 7471 (0)\n002 2 043f 1da3 | 38 13d8 (0) 12b9 (0) 123f (0) 1673 (0)\n003 1 2a22 | 20 2374 (0) 2279 (0) 2013 (0) 211a (0)\n004 3 3538 34fc 3345 | 6 3648 (0) 34fc (0) 3538 (0) 31ed (0)\n005 4 3d6b 3f3e 3e44 3e85 | 5 3dca (0) 3d6b (0) 3f3e (0) 3e44 (0)\n============ DEPTH: 6 ==========================================\n006 2 3af3 3a4a | 2 3af3 (0) 3a4a (0)\n007 1 396b | 1 396b (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"OI1G1uo/2SqpWbBNWX/xCW1hM/FxGByPtU5Sk1ti0zw="},"ip":"0.0.0.0","id":"f8a5ae50e5b2d84096c10a6a8493a9eb8113df64c4f1336c0cf4649302649b158fa4cb7941591e55356891bcc1008a535df427546af19988a241c5f466467963","enode":"enode://f8a5ae50e5b2d84096c10a6a8493a9eb8113df64c4f1336c0cf4649302649b158fa4cb7941591e55356891bcc1008a535df427546af19988a241c5f466467963@0.0.0.0:0","name":"node165","listenAddr":""},"config":{"private_key":"09ab58931e7729bf23cdcb2772b3869d1aacece96070df5790f8343b70ef5e3b","id":"f8a5ae50e5b2d84096c10a6a8493a9eb8113df64c4f1336c0cf4649302649b158fa4cb7941591e55356891bcc1008a535df427546af19988a241c5f466467963","name":"node165","services":["pss","bzz"]},"up":true}},{"node":{"info":{"listenAddr":"","name":"node166","enode":"enode://d6a7257771baa4d9944592ead46b8ab700dbf91ebd4dc0ec7e5fb41cbda0622944269172fcec8352b89ef2c186d4c787af2b45a50533f627a97818477de034b4@0.0.0.0:0","id":"d6a7257771baa4d9944592ead46b8ab700dbf91ebd4dc0ec7e5fb41cbda0622944269172fcec8352b89ef2c186d4c787af2b45a50533f627a97818477de034b4","ip":"0.0.0.0","protocols":{"bzz":"M0XgOIDDd/wf57YgUBHOPjJSXO/uXgMWEQXxUSiT+fs=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 3345e0\npopulation: 14 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 f915 e76a | 121 b310 (0) b5c7 (0) b463 (0) b45d (0)\n001 1 4d44 | 62 7307 (0) 72fa (0) 72ac (0) 7294 (0)\n002 2 043f 1da3 | 38 13d8 (0) 12b9 (0) 123f (0) 1673 (0)\n003 1 2a22 | 20 2374 (0) 2279 (0) 2013 (0) 211a (0)\n004 3 3d6b 3e85 388d | 9 3dca (0) 3d6b (0) 3f3e (0) 3e44 (0)\n005 3 3648 34fc 3538 | 3 3648 (0) 34fc (0) 3538 (0)\n============ DEPTH: 6 ==========================================\n006 1 31ed | 1 31ed (0)\n007 1 32dd | 1 32dd (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"listener":0,"discovery":0}},"config":{"id":"d6a7257771baa4d9944592ead46b8ab700dbf91ebd4dc0ec7e5fb41cbda0622944269172fcec8352b89ef2c186d4c787af2b45a50533f627a97818477de034b4","private_key":"c330a5f7858f47d6653c52c88207fd10c6c87d8e77c87b9be95165f094918210","services":["pss","bzz"],"name":"node166"},"up":true}},{"node":{"up":true,"config":{"id":"8e5e8366251e33277e7db6f6c04629b2ce3eee217e973acb97c83773671b0160c40732794584db741a29a763672b90f3bdf34151fd4a6986b9d0956dc61d9723","private_key":"7bbb910a655225eccc1fa6ab5abd3696725591448d5b628656692c1170f1f095","services":["pss","bzz"],"name":"node167"},"info":{"name":"node167","enode":"enode://8e5e8366251e33277e7db6f6c04629b2ce3eee217e973acb97c83773671b0160c40732794584db741a29a763672b90f3bdf34151fd4a6986b9d0956dc61d9723@0.0.0.0:0","listenAddr":"","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: e76a40\npopulation: 22 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 7 4d44 2a22 3e85 388d | 135 7471 (0) 7406 (0) 759e (0) 77ec (0)\n001 2 8612 9c01 | 56 b310 (0) b5c7 (0) b4c7 (0) b463 (0)\n002 2 d3fd d822 | 36 c3f3 (0) c0d1 (0) c15d (0) c770 (0)\n003 4 f1fc f78a fd2d f915 | 17 f3d3 (0) f048 (0) f0e2 (0) f156 (0)\n004 1 ed65 | 5 e839 (0) ecd2 (0) edca (0) ed13 (0)\n005 1 e3c9 | 1 e3c9 (0)\n006 2 e44b e4c3 | 2 e44b (0) e4c3 (0)\n============ DEPTH: 7 ==========================================\n007 2 e649 e67d | 2 e67d (0) e649 (0)\n008 1 e787 | 1 e787 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"52pAR35p9jf/cPG/OTsdyWqUY4Q0CzQdC+l7oB3BJmA="},"ports":{"discovery":0,"listener":0},"ip":"0.0.0.0","id":"8e5e8366251e33277e7db6f6c04629b2ce3eee217e973acb97c83773671b0160c40732794584db741a29a763672b90f3bdf34151fd4a6986b9d0956dc61d9723"}}},{"node":{"info":{"enode":"enode://002cb6ffa63ad71ee6ebc1df4c41f7a97c51f274b1d3b22420c87b73136be5169b9670508061d8261e20055fefce3b855388994672aa9a0f1475c43839aae4fa@0.0.0.0:0","name":"node168","listenAddr":"","ip":"0.0.0.0","protocols":{"bzz":"BD8kzof70B9vZj8yOsbBVoEKZ7Eu++wvIZrpqIKkvRY=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 043f24\npopulation: 21 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 d822 e76a f915 f78a | 121 b4c7 (0) b45d (0) b463 (0) b5c7 (0)\n001 2 4d44 5c5d | 62 6ea5 (0) 6dbd (0) 6d21 (0) 6330 (0)\n002 5 388d 3e85 3d6b 3538 | 35 2279 (0) 2374 (0) 2013 (0) 211a (0)\n003 3 1441 1d5f 1da3 | 26 13d8 (0) 12b9 (0) 123f (0) 1673 (0)\n004 1 0eee | 4 0f81 (0) 0f5e (0) 0ea2 (0) 0eee (0)\n005 2 0210 004e | 3 03f5 (0) 0210 (0) 004e (0)\n006 1 06aa | 1 06aa (0)\n============ DEPTH: 7 ==========================================\n007 3 05e8 05ec 0592 | 3 05e8 (0) 05ec (0) 0592 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"listener":0,"discovery":0},"id":"002cb6ffa63ad71ee6ebc1df4c41f7a97c51f274b1d3b22420c87b73136be5169b9670508061d8261e20055fefce3b855388994672aa9a0f1475c43839aae4fa"},"up":true,"config":{"private_key":"9a0adb03a36d31dc716a280bc0b0ccdb5a891c5242f507aed5f6c370ea6bca05","id":"002cb6ffa63ad71ee6ebc1df4c41f7a97c51f274b1d3b22420c87b73136be5169b9670508061d8261e20055fefce3b855388994672aa9a0f1475c43839aae4fa","name":"node168","services":["pss","bzz"]}}},{"node":{"info":{"protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: f78a54\npopulation: 15 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 3d6b 043f | 135 7307 (0) 72ac (0) 7294 (0) 72fa (0)\n001 2 8612 9c01 | 56 b310 (0) b5c7 (0) b45d (0) b463 (0)\n002 1 d822 | 36 c15d (0) c0d1 (0) c3f3 (0) c484 (0)\n003 1 e76a | 12 e839 (0) ecd2 (0) edca (0) ed13 (0)\n004 2 fd2d f915 | 6 fed1 (0) fd2d (0) fa74 (0) fb93 (0)\n005 2 f0e2 f1fc | 5 f3d3 (0) f048 (0) f0e2 (0) f156 (0)\n============ DEPTH: 6 ==========================================\n006 4 f4ee f4e0 f5dd f5cc | 4 f4ee (0) f4e0 (0) f5dd (0) f5cc (0)\n007 1 f644 | 1 f644 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"94pUuks/p1zbVCvc1toNSZhqX355OZWaUbO0iodgVlQ="},"ports":{"discovery":0,"listener":0},"ip":"0.0.0.0","id":"7465fe601a9ad8e640069e6e07d56afabd3d4f008f3084f944d869b47fda3f511f191062802a53da511f60891dd0bcc5fac60254ef9db7aa3b41f5791b0b6975","name":"node169","enode":"enode://7465fe601a9ad8e640069e6e07d56afabd3d4f008f3084f944d869b47fda3f511f191062802a53da511f60891dd0bcc5fac60254ef9db7aa3b41f5791b0b6975@0.0.0.0:0","listenAddr":""},"up":true,"config":{"name":"node169","services":["pss","bzz"],"private_key":"c9271845738bb80612a262956270b72e5152311e2e80fe21b3c7238f394911a7","id":"7465fe601a9ad8e640069e6e07d56afabd3d4f008f3084f944d869b47fda3f511f191062802a53da511f60891dd0bcc5fac60254ef9db7aa3b41f5791b0b6975"}}},{"node":{"info":{"id":"e0f13606a7f35b9ad8a9c4e70336c4c554ac718720a451a349eb4e1a4b055079483cac040ec64e0ed3d8bdb336618a5ae6ef74e31642fae4d7ed9949858eb361","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 9c01d0\npopulation: 17 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 1da3 | 135 7307 (0) 72ac (0) 7294 (0) 72fa (0)\n001 4 d822 e76a f915 f78a | 65 c0d1 (0) c15d (0) c3f3 (0) c770 (0)\n002 2 a033 be0a | 30 b310 (0) b5c7 (0) b4c7 (0) b45d (0)\n003 3 8c89 89ee 86f7 | 10 8163 (0) 86f7 (0) 8612 (0) 8c61 (0)\n004 2 94aa 95e0 | 7 9294 (0) 9232 (0) 9390 (0) 96b6 (0)\n005 2 99db 99fb | 5 9a82 (0) 985c (0) 99aa (0) 99db (0)\n============ DEPTH: 6 ==========================================\n006 2 9fee 9eec | 2 9fee (0) 9eec (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 1 9c0c | 1 9c0c (0)\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"nAHQFqrxH557BIuhDOo8NR2atcjGboYF94wGdycImFw="},"ip":"0.0.0.0","ports":{"listener":0,"discovery":0},"listenAddr":"","name":"node170","enode":"enode://e0f13606a7f35b9ad8a9c4e70336c4c554ac718720a451a349eb4e1a4b055079483cac040ec64e0ed3d8bdb336618a5ae6ef74e31642fae4d7ed9949858eb361@0.0.0.0:0"},"up":true,"config":{"id":"e0f13606a7f35b9ad8a9c4e70336c4c554ac718720a451a349eb4e1a4b055079483cac040ec64e0ed3d8bdb336618a5ae6ef74e31642fae4d7ed9949858eb361","private_key":"1710672c4d27d5363877ec9be4202445a3404d3e16ff221611f0c2d82c34af1c","services":["pss","bzz"],"name":"node170"}}},{"node":{"config":{"name":"node171","services":["pss","bzz"],"private_key":"fe3ddcd5732357d3e602b35b79a21afd716fadbe7b569e44eb014dd4b944ad49","id":"6b082a09e343a160b60a01f74641c1d707b2fa8fee5f6f5a8b9e4a203bd86434227d2df982b246a752f843483cdf517e85fe3bd65453354232a6eb38dedbf314"},"up":true,"info":{"ip":"0.0.0.0","protocols":{"bzz":"HaNOdWkSwfkpCXDitg1diohAeSPA6sjECbdfD0cOvDY=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 1da34e\npopulation: 23 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 f915 e76a 9c01 | 121 c484 (0) c463 (0) c723 (0) c770 (0)\n001 2 6610 5c5d | 62 77ec (0) 759e (0) 7406 (0) 7471 (0)\n002 5 388d 3e85 3d6b 3538 | 35 2279 (0) 2374 (0) 2013 (0) 211a (0)\n003 3 0eee 004e 043f | 12 0f5e (0) 0f81 (0) 0ea2 (0) 0eee (0)\n004 2 123f 1441 | 8 13d8 (0) 12b9 (0) 123f (0) 1673 (0)\n005 1 1a02 | 10 193e (0) 194a (0) 18f9 (0) 1835 (0)\n006 2 1e44 1e42 | 2 1e44 (0) 1e42 (0)\n007 1 1c98 | 1 1c98 (0)\n008 2 1d07 1d5f | 2 1d07 (0) 1d5f (0)\n009 0 | 0\n============ DEPTH: 10 ==========================================\n010 2 1d94 1d93 | 2 1d94 (0) 1d93 (0)\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"listener":0,"discovery":0},"id":"6b082a09e343a160b60a01f74641c1d707b2fa8fee5f6f5a8b9e4a203bd86434227d2df982b246a752f843483cdf517e85fe3bd65453354232a6eb38dedbf314","name":"node171","enode":"enode://6b082a09e343a160b60a01f74641c1d707b2fa8fee5f6f5a8b9e4a203bd86434227d2df982b246a752f843483cdf517e85fe3bd65453354232a6eb38dedbf314@0.0.0.0:0","listenAddr":""}}},{"node":{"up":false,"config":{"id":"69f999937943be00e5fca5c7cc942ce13b6752a72813368da2fbfcf74ad807bc6edd85537e087b6f73c0469c7b76a5d8f7d883bd315f3b35af32b8da293ed243","private_key":"85d961e31726c6d75913c901b5db7e115dd67338d9d89584e0c73df8f673a01c","services":["pss","bzz"],"name":"node172"},"info":{"id":"69f999937943be00e5fca5c7cc942ce13b6752a72813368da2fbfcf74ad807bc6edd85537e087b6f73c0469c7b76a5d8f7d883bd315f3b35af32b8da293ed243","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: f915fb\npopulation: 32 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 13 604c 6610 5261 4fd6 | 135 77ec (0) 759e (0) 7471 (0) 7406 (0)\n001 4 8c89 89ee 9c01 95e0 | 56 b310 (0) b5c7 (0) b4c7 (0) b463 (0)\n002 1 d822 | 36 c0d1 (0) c15d (0) c3f3 (0) c484 (0)\n003 2 e649 e76a | 12 e839 (0) ecd2 (0) edca (0) ed13 (0)\n004 7 f3d3 f048 f1fc f5dd | 11 f3d3 (0) f0e2 (0) f048 (0) f156 (0)\n005 2 fed1 fd2d | 2 fed1 (0) fd2d (0)\n============ DEPTH: 6 ==========================================\n006 2 fb93 fa74 | 2 fb93 (0) fa74 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 1 f924 | 1 f924 (0)\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"+RX7vOLvWKQ3j2K5x0l2TpaNpG33vtSUs1pCLQNZpd0="},"ports":{"discovery":0,"listener":0},"ip":"0.0.0.0","listenAddr":"","enode":"enode://69f999937943be00e5fca5c7cc942ce13b6752a72813368da2fbfcf74ad807bc6edd85537e087b6f73c0469c7b76a5d8f7d883bd315f3b35af32b8da293ed243@0.0.0.0:0","name":"node172"}}},{"node":{"config":{"id":"a5f7163586fce1750fd9a6e5c418af1c18ca6983069dcf1738fc9106ebf542a86e4ccfc50b45a0d97ca8681af8207128877f930f945e59ee262aa7f4014a01f3","private_key":"ded7d4f338d0e906b79482b6a79c0a2224820bac1893e3ee083a66eaaebea363","services":["pss","bzz"],"name":"node173"},"up":true,"info":{"id":"a5f7163586fce1750fd9a6e5c418af1c18ca6983069dcf1738fc9106ebf542a86e4ccfc50b45a0d97ca8681af8207128877f930f945e59ee262aa7f4014a01f3","ports":{"listener":0,"discovery":0},"protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: d8222a\npopulation: 18 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 043f 3d6b 3538 | 135 77ec (0) 7406 (0) 7471 (0) 759e (0)\n001 3 95e0 9c01 89ee | 56 b310 (0) b5c7 (0) b4c7 (0) b45d (0)\n002 3 e76a f78a f915 | 29 e839 (0) ecd2 (0) edca (0) ed13 (0)\n003 1 c883 | 18 c3f3 (0) c0d1 (0) c15d (0) c723 (0)\n004 2 d3fd d564 | 7 d3d2 (0) d3fd (0) d68f (0) d6f3 (0)\n005 3 dc86 ddf8 def4 | 7 dc3e (0) dc86 (0) ddf8 (0) df5e (0)\n============ DEPTH: 6 ==========================================\n006 2 dae3 daa2 | 2 dae3 (0) daa2 (0)\n007 0 | 0\n008 1 d8b0 | 1 d8b0 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"2CIqLBd/DNF7quKDJ69cE/L7VR3QEpjReFXOf29PYYk="},"ip":"0.0.0.0","listenAddr":"","name":"node173","enode":"enode://a5f7163586fce1750fd9a6e5c418af1c18ca6983069dcf1738fc9106ebf542a86e4ccfc50b45a0d97ca8681af8207128877f930f945e59ee262aa7f4014a01f3@0.0.0.0:0"}}},{"node":{"config":{"private_key":"f2b75f511327f380d86989fed2d67129f32bb0aeafb3aba0250c8e9e5b581d16","id":"876618c8ba66c1b91b473a154be3e10ded3590ba83d620d30e0ff1fbac2f31f258b1299a3da5b56aa03269a80c119b7fc41dfd87d5bd996359e4ad8dd0ab2a6a","name":"node174","services":["pss","bzz"]},"up":true,"info":{"name":"node174","enode":"enode://876618c8ba66c1b91b473a154be3e10ded3590ba83d620d30e0ff1fbac2f31f258b1299a3da5b56aa03269a80c119b7fc41dfd87d5bd996359e4ad8dd0ab2a6a@0.0.0.0:0","listenAddr":"","protocols":{"bzz":"NTh11K4rnFzGyxQFm9+5VAZHEAx8MzS8YNssorTd8/U=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 353875\npopulation: 19 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 95e0 89ee d822 | 121 b310 (0) b5c7 (0) b4c7 (0) b463 (0)\n001 2 6610 5c5d | 62 77ec (0) 759e (0) 7406 (0) 7471 (0)\n002 4 043f 1b72 1e42 1da3 | 38 0f81 (0) 0f5e (0) 0ea2 (0) 0eee (0)\n003 2 2a22 2454 | 20 2374 (0) 2279 (0) 2013 (0) 211a (0)\n004 3 388d 3e85 3d6b | 9 3af3 (0) 3a4a (0) 396b (0) 388d (0)\n005 3 31ed 32dd 3345 | 3 31ed (0) 32dd (0) 3345 (0)\n============ DEPTH: 6 ==========================================\n006 1 3648 | 1 3648 (0)\n007 1 34fc | 1 34fc (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ip":"0.0.0.0","ports":{"listener":0,"discovery":0},"id":"876618c8ba66c1b91b473a154be3e10ded3590ba83d620d30e0ff1fbac2f31f258b1299a3da5b56aa03269a80c119b7fc41dfd87d5bd996359e4ad8dd0ab2a6a"}}},{"node":{"info":{"listenAddr":"","name":"node175","enode":"enode://6b7c94db790a2c1b903208904c4c75b66b17e7a00404727dbc7aeff404ac1118dc78ce4ca443f6b5245236f9e358c09b6da027ae1144e1a6682edca301176330@0.0.0.0:0","id":"6b7c94db790a2c1b903208904c4c75b66b17e7a00404727dbc7aeff404ac1118dc78ce4ca443f6b5245236f9e358c09b6da027ae1144e1a6682edca301176330","ports":{"discovery":0,"listener":0},"protocols":{"bzz":"ie5ihYO24DRc6zEsLiy/WsQQ6wBTG+kDpLlLYLY5mTs=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 89ee62\npopulation: 15 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 3538 | 135 2374 (0) 2279 (0) 2013 (0) 211a (0)\n001 2 f915 d822 | 65 ceee (0) cb69 (0) ca81 (0) c9f3 (0)\n002 1 a80b | 30 b310 (0) b5c7 (0) b4c7 (0) b45d (0)\n003 2 9c01 95e0 | 16 9a82 (0) 985c (0) 99aa (0) 99db (0)\n004 3 8163 86f7 8612 | 3 8163 (0) 86f7 (0) 8612 (0)\n005 2 8c61 8c89 | 2 8c61 (0) 8c89 (0)\n006 2 8ac8 8ae6 | 2 8ac8 (0) 8ae6 (0)\n============ DEPTH: 7 ==========================================\n007 2 88da 8874 | 2 88da (0) 8874 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ip":"0.0.0.0"},"up":true,"config":{"private_key":"a9bc40abaa967e683f994c9d053b90fa4daa9602fc810cd974a8f6a3629dbd28","id":"6b7c94db790a2c1b903208904c4c75b66b17e7a00404727dbc7aeff404ac1118dc78ce4ca443f6b5245236f9e358c09b6da027ae1144e1a6682edca301176330","name":"node175","services":["pss","bzz"]}}},{"node":{"info":{"name":"node176","enode":"enode://c69b9b181b2756a1345b73a97afb3dca909c253188c3b905f0b414465b750d2ffccb4c8e8eb5e3809549af55db473f3b12682f9bd97c5c75d68f23d67d91b866@0.0.0.0:0","listenAddr":"","ports":{"listener":0,"discovery":0},"protocols":{"bzz":"leBSkicobUQs3u7UKGFPmcGfkiNCbm9s777y2dR86W8=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 95e052\npopulation: 21 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 3538 3d6b 5c5d | 135 290f (0) 29fd (0) 29ff (0) 2af0 (0)\n001 3 d3fd d822 f915 | 65 cb69 (0) ca81 (0) c9f3 (0) c98d (0)\n002 1 a80b | 30 b310 (0) b5c7 (0) b4c7 (0) b45d (0)\n003 4 86f7 8612 8874 89ee | 10 8163 (0) 86f7 (0) 8612 (0) 8c61 (0)\n004 5 9a82 99db 99aa 9eec | 9 9a82 (0) 985c (0) 99aa (0) 99db (0)\n005 2 9294 9390 | 3 9390 (0) 9232 (0) 9294 (0)\n006 1 96b6 | 1 96b6 (0)\n============ DEPTH: 7 ==========================================\n007 2 94aa 9461 | 2 94aa (0) 9461 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ip":"0.0.0.0","id":"c69b9b181b2756a1345b73a97afb3dca909c253188c3b905f0b414465b750d2ffccb4c8e8eb5e3809549af55db473f3b12682f9bd97c5c75d68f23d67d91b866"},"up":true,"config":{"name":"node176","services":["pss","bzz"],"private_key":"fa312311679e17f36872e8c75b78bd3b730d7423c613f5d7cbcaf653d847419e","id":"c69b9b181b2756a1345b73a97afb3dca909c253188c3b905f0b414465b750d2ffccb4c8e8eb5e3809549af55db473f3b12682f9bd97c5c75d68f23d67d91b866"}}},{"node":{"info":{"protocols":{"bzz":"XF2QqCUiG6+yq3JvkEIsmln5v5fxgcCiiH2ypTF5gEg=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 5c5d90\npopulation: 25 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 a80b 8612 86f7 95e0 | 121 c3f3 (0) c0d1 (0) c15d (0) c64f (0)\n001 9 2454 3538 3d6b 043f | 73 290f (0) 29fd (0) 29ff (0) 2a69 (0)\n002 2 7851 7d94 | 31 77ec (0) 759e (0) 7406 (0) 7471 (0)\n003 3 42c0 42d4 47f9 | 17 487e (0) 4b00 (0) 4a67 (0) 4af7 (0)\n004 3 5695 5571 5261 | 9 57d5 (0) 5716 (0) 566e (0) 5695 (0)\n005 0 | 0\n============ DEPTH: 6 ==========================================\n006 4 5fd0 5fab 5fa8 5f05 | 4 5fd0 (0) 5fab (0) 5fa8 (0) 5f05 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"listener":0,"discovery":0},"ip":"0.0.0.0","id":"f6a12b23423c047927a3024a6dba7ce88927cb21d4df3778bc5ebb262cc403261c79ba6d9bda07f1852c009d803a77f429e9e48ec1d63cae98256e529d45b276","enode":"enode://f6a12b23423c047927a3024a6dba7ce88927cb21d4df3778bc5ebb262cc403261c79ba6d9bda07f1852c009d803a77f429e9e48ec1d63cae98256e529d45b276@0.0.0.0:0","name":"node177","listenAddr":""},"up":true,"config":{"private_key":"3532d20f2d6b03b910ef2d4dc968b71d89bd0fa3c9a758fd355ec3f8c9b6b62b","id":"f6a12b23423c047927a3024a6dba7ce88927cb21d4df3778bc5ebb262cc403261c79ba6d9bda07f1852c009d803a77f429e9e48ec1d63cae98256e529d45b276","name":"node177","services":["pss","bzz"]}}},{"node":{"config":{"services":["pss","bzz"],"name":"node178","id":"4116fbb7d55bfd4bd8db9cbfa570ac361bb88605b6aacbf84e245893cf3fa599ecc086688a4c534c81f61a90fa344ca37e4d4013ddc03f7f08218724a55f66b1","private_key":"d491504fcc40f961febbbf2089616ac2a2b7cc79e5dc9c01b632ab9d226bca86"},"up":true,"info":{"ports":{"listener":0,"discovery":0},"protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 144185\npopulation: 17 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 8612 | 121 e839 (0) ecd2 (0) edca (0) ed65 (0)\n001 1 5c5d | 62 77ec (0) 759e (0) 7406 (0) 7471 (0)\n002 2 2454 3d6b | 35 2f22 (0) 2fd8 (0) 2f9f (0) 2e9f (0)\n003 2 043f 004e | 12 0f81 (0) 0f5e (0) 0ea2 (0) 0eee (0)\n004 6 1a02 1b1e 1e42 1d93 | 18 193e (0) 194a (0) 18f9 (0) 1835 (0)\n005 1 123f | 3 13d8 (0) 12b9 (0) 123f (0)\n006 1 1673 | 1 1673 (0)\n============ DEPTH: 7 ==========================================\n007 2 1566 15f6 | 2 1566 (0) 15f6 (0)\n008 1 14c8 | 1 14c8 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"FEGFV69E4z/I1GNpQmw+L8kWIssId5s/785waWnsIWM="},"ip":"0.0.0.0","id":"4116fbb7d55bfd4bd8db9cbfa570ac361bb88605b6aacbf84e245893cf3fa599ecc086688a4c534c81f61a90fa344ca37e4d4013ddc03f7f08218724a55f66b1","name":"node178","enode":"enode://4116fbb7d55bfd4bd8db9cbfa570ac361bb88605b6aacbf84e245893cf3fa599ecc086688a4c534c81f61a90fa344ca37e4d4013ddc03f7f08218724a55f66b1@0.0.0.0:0","listenAddr":""}}},{"node":{"up":true,"config":{"id":"eb6d41d8d96f1933dff017d5fa0c46c6d0bad5d273b7c321a12858ac90ec00fca6191d29419897d2e25ec2d8ebd8c6a81bbde2d3f266f842e64b2b822161f1ea","private_key":"9653af0c5c528f1079ce38ba8e44273a7eed8efe91036d0219e08121fc62ca06","services":["pss","bzz"],"name":"node179"},"info":{"name":"node179","enode":"enode://eb6d41d8d96f1933dff017d5fa0c46c6d0bad5d273b7c321a12858ac90ec00fca6191d29419897d2e25ec2d8ebd8c6a81bbde2d3f266f842e64b2b822161f1ea@0.0.0.0:0","listenAddr":"","protocols":{"bzz":"AE6BKZW8BPIpk0Zt+YicobZQu6JCz4C7BwzpVk577dg=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 004e81\npopulation: 14 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 a80b 86f7 8612 | 121 e839 (0) ecd2 (0) edca (0) ed13 (0)\n001 1 5c5d | 62 77ec (0) 759e (0) 7406 (0) 7471 (0)\n002 2 3d6b 2454 | 35 2f9f (0) 2fd8 (0) 2f22 (0) 2e9f (0)\n003 4 1da3 1d5f 123f 1441 | 26 193e (0) 194a (0) 18f9 (0) 185a (0)\n004 1 0eee | 4 0f81 (0) 0f5e (0) 0ea2 (0) 0eee (0)\n005 1 043f | 5 06aa (0) 0592 (0) 05ec (0) 05e8 (0)\n============ DEPTH: 6 ==========================================\n006 2 0210 03f5 | 2 03f5 (0) 0210 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ip":"0.0.0.0","ports":{"listener":0,"discovery":0},"id":"eb6d41d8d96f1933dff017d5fa0c46c6d0bad5d273b7c321a12858ac90ec00fca6191d29419897d2e25ec2d8ebd8c6a81bbde2d3f266f842e64b2b822161f1ea"}}},{"node":{"up":true,"config":{"name":"node180","services":["pss","bzz"],"private_key":"09d927a912f0daefdca0fdb594feea4e25c384ac07efb663ea46ba893d0f32f9","id":"11e9729700f5046b47d5e4521630cb57408f59a3337ca7db7984477a16c1f3b90c1d8d1f8d6a3f2a72e35f373fa73ec47a5636b36e40b2fb83756622a08896b8"},"info":{"listenAddr":"","name":"node180","enode":"enode://11e9729700f5046b47d5e4521630cb57408f59a3337ca7db7984477a16c1f3b90c1d8d1f8d6a3f2a72e35f373fa73ec47a5636b36e40b2fb83756622a08896b8@0.0.0.0:0","id":"11e9729700f5046b47d5e4521630cb57408f59a3337ca7db7984477a16c1f3b90c1d8d1f8d6a3f2a72e35f373fa73ec47a5636b36e40b2fb83756622a08896b8","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 1d5fc6\npopulation: 16 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 8612 | 121 e839 (0) ecd2 (0) ed65 (0) ed13 (0)\n001 1 5c5d | 62 77ec (0) 759e (0) 7406 (0) 7471 (0)\n002 1 3d6b | 35 2f22 (0) 2fd8 (0) 2f9f (0) 2e9f (0)\n003 2 043f 004e | 12 0f81 (0) 0f5e (0) 0ea2 (0) 0eee (0)\n004 2 123f 1441 | 8 13d8 (0) 12b9 (0) 123f (0) 1673 (0)\n005 2 1b1e 1a02 | 10 194a (0) 193e (0) 18f9 (0) 1835 (0)\n006 2 1e44 1e42 | 2 1e44 (0) 1e42 (0)\n007 1 1c98 | 1 1c98 (0)\n============ DEPTH: 8 ==========================================\n008 3 1d94 1d93 1da3 | 3 1d94 (0) 1d93 (0) 1da3 (0)\n009 1 1d07 | 1 1d07 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"HV/GW0EhzMr/DSqFPGu/8MELTsKM/F71y+qLwovEy+w="},"ports":{"discovery":0,"listener":0},"ip":"0.0.0.0"}}},{"node":{"info":{"protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 3d6baa\npopulation: 24 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 5 d822 f78a f915 95e0 | 121 c3f3 (0) c15d (0) c0d1 (0) c770 (0)\n001 1 5c5d | 62 759e (0) 7406 (0) 7471 (0) 77ec (0)\n002 6 004e 043f 123f 1441 | 38 0f81 (0) 0f5e (0) 0ea2 (0) 0eee (0)\n003 3 2a22 2168 2454 | 20 2f22 (0) 2fd8 (0) 2f9f (0) 2e9f (0)\n004 2 3345 3538 | 6 31ed (0) 32dd (0) 3345 (0) 3648 (0)\n005 3 3a4a 396b 388d | 4 3af3 (0) 3a4a (0) 396b (0) 388d (0)\n============ DEPTH: 6 ==========================================\n006 3 3f3e 3e44 3e85 | 3 3f3e (0) 3e44 (0) 3e85 (0)\n007 0 | 0\n008 1 3dca | 1 3dca (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"PWuqnaF8Mw/TSkDOzzMYd9SlYfa09xHNWt9BvXfWh0g="},"ports":{"listener":0,"discovery":0},"ip":"0.0.0.0","id":"51a570637394e9ab61fe95b3a608cc4e9dc8ceb63efe717938ccd4260a962d52e01b30e7034fbfdabd9a3c9616ee569550b38a6d6b4b19847f523254069a9f27","name":"node181","enode":"enode://51a570637394e9ab61fe95b3a608cc4e9dc8ceb63efe717938ccd4260a962d52e01b30e7034fbfdabd9a3c9616ee569550b38a6d6b4b19847f523254069a9f27@0.0.0.0:0","listenAddr":""},"config":{"private_key":"b5c4da646e3485b765e530ff19f36c4753764dda9d4aa308fb8d5c3d52d9b04f","id":"51a570637394e9ab61fe95b3a608cc4e9dc8ceb63efe717938ccd4260a962d52e01b30e7034fbfdabd9a3c9616ee569550b38a6d6b4b19847f523254069a9f27","name":"node181","services":["pss","bzz"]},"up":true}},{"node":{"info":{"name":"node182","enode":"enode://ec19efa1d488e74da6bf239825b24678f549c377326c5d33d100b708a9a28a3fe129d542d7ba71e0ade46c15c6e9b38f09422560444388e609a8a66ceb8e0ae8@0.0.0.0:0","listenAddr":"","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 861286\npopulation: 19 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 7 5c5d 004e 1d5f 123f | 135 7fa4 (0) 7ffe (0) 7d45 (0) 7d94 (0)\n001 3 f78a e76a d3fd | 65 ceee (0) cb69 (0) ca81 (0) c9f3 (0)\n002 1 a80b | 30 b310 (0) b5c7 (0) b4c7 (0) b45d (0)\n003 2 9eec 95e0 | 16 9a82 (0) 985c (0) 99aa (0) 99db (0)\n004 4 8c89 8ae6 8874 89ee | 7 8c61 (0) 8c89 (0) 8ac8 (0) 8ae6 (0)\n============ DEPTH: 5 ==========================================\n005 1 8163 | 1 8163 (0)\n006 0 | 0\n007 0 | 0\n008 1 86f7 | 1 86f7 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"hhKGibA3Bvmoa69HUxVK+7DFNfhAiQOe9WENgvuWmm4="},"ports":{"listener":0,"discovery":0},"ip":"0.0.0.0","id":"ec19efa1d488e74da6bf239825b24678f549c377326c5d33d100b708a9a28a3fe129d542d7ba71e0ade46c15c6e9b38f09422560444388e609a8a66ceb8e0ae8"},"up":true,"config":{"private_key":"cf80dfc2e5888e69aa7c570430d76fb7a11991c8f8bd4c8dec3e2303085624ad","id":"ec19efa1d488e74da6bf239825b24678f549c377326c5d33d100b708a9a28a3fe129d542d7ba71e0ade46c15c6e9b38f09422560444388e609a8a66ceb8e0ae8","name":"node182","services":["pss","bzz"]}}},{"node":{"config":{"private_key":"33a68fc227f5f745114937915a4678fbcd985ff8c589698f241091a32fd901b2","id":"24047e1a816cbf9b7a90e6c78dc896a3b624047ef5cfd3aa495132d57b1074aa129ea6eff171f5cca91d0f4793a07c9672b0a55232f2415c6220e443ebd0791d","name":"node183","services":["pss","bzz"]},"up":true,"info":{"name":"node183","enode":"enode://24047e1a816cbf9b7a90e6c78dc896a3b624047ef5cfd3aa495132d57b1074aa129ea6eff171f5cca91d0f4793a07c9672b0a55232f2415c6220e443ebd0791d@0.0.0.0:0","listenAddr":"","ports":{"discovery":0,"listener":0},"protocols":{"bzz":"JFSVJQ04CVEGAi0/yQXrfrb1StsssLrN2gswWXTqpQo=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 245495\npopulation: 14 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 a80b 8612 | 121 ed65 (0) ed13 (0) edca (0) ecd2 (0)\n001 1 5c5d | 62 77ec (0) 759e (0) 7406 (0) 7471 (0)\n002 3 123f 1441 004e | 38 0f81 (0) 0f5e (0) 0ea2 (0) 0eee (0)\n003 2 3538 3d6b | 15 31ed (0) 32dd (0) 3345 (0) 3648 (0)\n004 1 2a22 | 11 2f22 (0) 2f9f (0) 2fd8 (0) 2e9f (0)\n005 2 2374 2168 | 5 2279 (0) 2374 (0) 2013 (0) 211a (0)\n============ DEPTH: 6 ==========================================\n006 2 265d 275c | 2 265d (0) 275c (0)\n007 1 259d | 1 259d (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ip":"0.0.0.0","id":"24047e1a816cbf9b7a90e6c78dc896a3b624047ef5cfd3aa495132d57b1074aa129ea6eff171f5cca91d0f4793a07c9672b0a55232f2415c6220e443ebd0791d"}}},{"node":{"info":{"id":"60995852a2385ce8d7d24dc94b85a2f0dab6e5c32e910dfe367ea9c6ccb7b0b2eb611fdf120f8c697097e2f137cefff42e8d9db16b664a857a38c5ace837ffa4","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: a80b39\npopulation: 21 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 5 5c5d 123f 004e 34fc | 135 77ec (0) 759e (0) 7406 (0) 7471 (0)\n001 1 d3fd | 65 ecd2 (0) edca (0) ed65 (0) ed13 (0)\n002 5 95e0 99fb 89ee 8612 | 26 9390 (0) 9294 (0) 9232 (0) 96b6 (0)\n003 1 be0a | 14 b310 (0) b5c7 (0) b4c7 (0) b45d (0)\n004 3 a033 a672 a485 | 4 a672 (0) a749 (0) a485 (0) a033 (0)\n005 3 aca1 af30 ae65 | 8 adfc (0) ad36 (0) aca1 (0) af5f (0)\n============ DEPTH: 6 ==========================================\n006 3 abfa aa50 aa88 | 3 abfa (0) aa50 (0) aa88 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"qAs5zygPqAsyM3DPw36OP/ON5H1d5EXFAPNsjPI5C1M="},"ports":{"listener":0,"discovery":0},"ip":"0.0.0.0","listenAddr":"","name":"node184","enode":"enode://60995852a2385ce8d7d24dc94b85a2f0dab6e5c32e910dfe367ea9c6ccb7b0b2eb611fdf120f8c697097e2f137cefff42e8d9db16b664a857a38c5ace837ffa4@0.0.0.0:0"},"config":{"id":"60995852a2385ce8d7d24dc94b85a2f0dab6e5c32e910dfe367ea9c6ccb7b0b2eb611fdf120f8c697097e2f137cefff42e8d9db16b664a857a38c5ace837ffa4","private_key":"ff80b3d224dd48711a8b71840a9762289dbcac4d27cb6c24878fb4dd01b7c55f","services":["pss","bzz"],"name":"node184"},"up":true}},{"node":{"info":{"id":"9bdacc256acef0433805477d38f32be849a8846d88cb883b19d290454639b42c6ab6c5c52d4f83453e8a156af7d85f606458aa9c0977c67282f56f34ff0acbfb","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 86f71d\npopulation: 21 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 47f9 5c5d 004e 123f | 135 77ec (0) 759e (0) 7406 (0) 7471 (0)\n001 1 d3fd | 65 ed65 (0) ed13 (0) edca (0) ecd2 (0)\n002 2 be0a a80b | 30 b310 (0) b5c7 (0) b4c7 (0) b45d (0)\n003 5 95e0 9461 9c01 9eec | 16 9390 (0) 9294 (0) 9232 (0) 96b6 (0)\n004 7 8c61 8c89 8ac8 8ae6 | 7 8c61 (0) 8c89 (0) 8ac8 (0) 8ae6 (0)\n============ DEPTH: 5 ==========================================\n005 1 8163 | 1 8163 (0)\n006 0 | 0\n007 0 | 0\n008 1 8612 | 1 8612 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"hvcdI+tO/u7UZ5vno9D1j5i4PSOz4Ki3P2DxU1tR8lw="},"ports":{"listener":0,"discovery":0},"ip":"0.0.0.0","listenAddr":"","name":"node185","enode":"enode://9bdacc256acef0433805477d38f32be849a8846d88cb883b19d290454639b42c6ab6c5c52d4f83453e8a156af7d85f606458aa9c0977c67282f56f34ff0acbfb@0.0.0.0:0"},"up":true,"config":{"id":"9bdacc256acef0433805477d38f32be849a8846d88cb883b19d290454639b42c6ab6c5c52d4f83453e8a156af7d85f606458aa9c0977c67282f56f34ff0acbfb","private_key":"9b8f03ec5acc438bfb8ef1d604066899d9108b46efa0136298d820aad5752cf6","services":["pss","bzz"],"name":"node185"}}},{"node":{"config":{"private_key":"b3496c97ca4de82c4133936c457c24ece46c36d35193ff6a5cd269701841cfd4","id":"682288e4dae2374c4784acd0b285508920ce39a6b72cc0e30a3dbb7972e0394a2bddd5ee5f22a1dbf80f284dde4d9f8ede7847318d5353566b35a83e212477e7","name":"node186","services":["pss","bzz"]},"up":true,"info":{"id":"682288e4dae2374c4784acd0b285508920ce39a6b72cc0e30a3dbb7972e0394a2bddd5ee5f22a1dbf80f284dde4d9f8ede7847318d5353566b35a83e212477e7","protocols":{"bzz":"Ej/h1ELH3JBacgbnEvvZzqZAKVpoI7ObGUVin/qJ6JU=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 123fe1\npopulation: 21 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 6 d3fd 99fb 8612 86f7 | 121 e839 (0) ecd2 (0) edca (0) ed13 (0)\n001 2 47f9 5c5d | 62 77ec (0) 759e (0) 7406 (0) 7471 (0)\n002 2 3d6b 2454 | 35 31ed (0) 32dd (0) 3345 (0) 3648 (0)\n003 2 0eee 004e | 12 0f5e (0) 0f81 (0) 0ea2 (0) 0eee (0)\n004 6 185a 1b72 1b1e 1a02 | 18 194a (0) 193e (0) 18f9 (0) 1835 (0)\n005 1 1441 | 5 1673 (0) 15f6 (0) 1566 (0) 14c8 (0)\n006 0 | 0\n============ DEPTH: 7 ==========================================\n007 1 13d8 | 1 13d8 (0)\n008 1 12b9 | 1 12b9 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ip":"0.0.0.0","ports":{"listener":0,"discovery":0},"listenAddr":"","name":"node186","enode":"enode://682288e4dae2374c4784acd0b285508920ce39a6b72cc0e30a3dbb7972e0394a2bddd5ee5f22a1dbf80f284dde4d9f8ede7847318d5353566b35a83e212477e7@0.0.0.0:0"}}},{"node":{"info":{"enode":"enode://510536aba28aa635d8a1098a6dbd2070748ce1eb0e14b54b93a21196543a60df546ff6a2b3b5b9f32a5c2a37f5aba77d0b74f28b2dabeeebf3fe5afc20a3209c@0.0.0.0:0","name":"node187","listenAddr":"","ip":"0.0.0.0","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: be0ab3\npopulation: 16 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 123f | 135 6330 (0) 6143 (0) 604c (0) 670d (0)\n001 1 d3fd | 65 e839 (0) ecd2 (0) edca (0) ed65 (0)\n002 3 86f7 9c01 99fb | 26 8c89 (0) 8c61 (0) 8ac8 (0) 8ae6 (0)\n003 5 a033 aca1 ae65 aa88 | 16 a672 (0) a749 (0) a485 (0) a033 (0)\n004 1 b710 | 8 b310 (0) b5c7 (0) b45d (0) b463 (0)\n005 2 baf3 b8a7 | 2 baf3 (0) b8a7 (0)\n006 1 bc08 | 1 bc08 (0)\n============ DEPTH: 7 ==========================================\n007 2 bfec bf5a | 2 bfec (0) bf5a (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"vgqz3cZWVokA2OH0I5TMlCRkWWt1ZdtA9sWgwk7pQvI="},"ports":{"discovery":0,"listener":0},"id":"510536aba28aa635d8a1098a6dbd2070748ce1eb0e14b54b93a21196543a60df546ff6a2b3b5b9f32a5c2a37f5aba77d0b74f28b2dabeeebf3fe5afc20a3209c"},"config":{"id":"510536aba28aa635d8a1098a6dbd2070748ce1eb0e14b54b93a21196543a60df546ff6a2b3b5b9f32a5c2a37f5aba77d0b74f28b2dabeeebf3fe5afc20a3209c","private_key":"65f6b15bed8bfb72144314f9aa2a7364bcb356e60cdb0212a7d04a3eb9e2d3af","services":["pss","bzz"],"name":"node187"},"up":true}},{"node":{"up":true,"config":{"id":"aa90454031068598ee39af5f1429c7a72277946d50ec2004f340406dbcc9f80cac505c9d9b071f85e2ccfd4b13bcf943f3cb9dd9f96f62d41352af9d8fffe7e4","private_key":"fe832e4f1c7485f3906f1807544431a825ca6ff8ea89d3d87a14aba92ba4d995","services":["pss","bzz"],"name":"node188"},"info":{"protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 99fba7\npopulation: 16 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 47f9 123f | 135 6330 (0) 604c (0) 6143 (0) 670d (0)\n001 2 def4 d3fd | 65 e839 (0) ecd2 (0) ed65 (0) ed13 (0)\n002 3 aa88 a80b be0a | 30 a672 (0) a749 (0) a485 (0) a033 (0)\n003 1 86f7 | 10 8c61 (0) 8c89 (0) 8ac8 (0) 8ae6 (0)\n004 1 9461 | 7 9390 (0) 9294 (0) 9232 (0) 96b6 (0)\n005 3 9c01 9fee 9eec | 4 9c0c (0) 9c01 (0) 9fee (0) 9eec (0)\n006 1 9a82 | 1 9a82 (0)\n007 1 985c | 1 985c (0)\n008 0 | 0\n============ DEPTH: 9 ==========================================\n009 1 99aa | 1 99aa (0)\n010 1 99db | 1 99db (0)\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"mfunM09Hv88hMx1heb+y7uLs69HqI/2CnFQoRLEO2XQ="},"ip":"0.0.0.0","ports":{"listener":0,"discovery":0},"id":"aa90454031068598ee39af5f1429c7a72277946d50ec2004f340406dbcc9f80cac505c9d9b071f85e2ccfd4b13bcf943f3cb9dd9f96f62d41352af9d8fffe7e4","enode":"enode://aa90454031068598ee39af5f1429c7a72277946d50ec2004f340406dbcc9f80cac505c9d9b071f85e2ccfd4b13bcf943f3cb9dd9f96f62d41352af9d8fffe7e4@0.0.0.0:0","name":"node188","listenAddr":""}}},{"node":{"info":{"listenAddr":"","enode":"enode://85c0b055439f114dee5eb0961013c117a48d62b0f17c61a7fd92a84092ef09bb3bbce686aa96e14528d5663565c57d657fa9813b1f38e268caeb1cb0842ef232@0.0.0.0:0","name":"node189","id":"85c0b055439f114dee5eb0961013c117a48d62b0f17c61a7fd92a84092ef09bb3bbce686aa96e14528d5663565c57d657fa9813b1f38e268caeb1cb0842ef232","ports":{"listener":0,"discovery":0},"protocols":{"bzz":"0/105gSdvs61t4/0aBsADaWtijhg1KEHBUG19SfSzIQ=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: d3fd74\npopulation: 23 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 123f 47f9 | 135 31ed (0) 32dd (0) 3345 (0) 3648 (0)\n001 6 be0a a80b 8612 86f7 | 56 a672 (0) a749 (0) a485 (0) a033 (0)\n002 3 e76a e649 f3d3 | 29 e839 (0) ecd2 (0) edca (0) ed65 (0)\n003 2 ceee c8fe | 18 ceee (0) ca81 (0) cb69 (0) c9f3 (0)\n004 4 d822 de82 def4 ddf8 | 11 daa2 (0) dae3 (0) d8b0 (0) d822 (0)\n============ DEPTH: 5 ==========================================\n005 5 d68f d6f3 d6d2 d7ab | 5 d6f3 (0) d6d2 (0) d68f (0) d7ab (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 1 d3d2 | 1 d3d2 (0)\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ip":"0.0.0.0"},"config":{"private_key":"50f4adfdd5287853b06a93a0214c09ee109edc00698de65c0c0523e10e7d828b","id":"85c0b055439f114dee5eb0961013c117a48d62b0f17c61a7fd92a84092ef09bb3bbce686aa96e14528d5663565c57d657fa9813b1f38e268caeb1cb0842ef232","name":"node189","services":["pss","bzz"]},"up":true}},{"node":{"info":{"protocols":{"bzz":"R/lXCEdcnWH/IBbncHxKN5b2yHMTvR0r+RqmIBE7pfg=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 47f957\npopulation: 18 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 5 99fb 86f7 ddf8 def4 | 121 a033 (0) a749 (0) a672 (0) a485 (0)\n001 1 123f | 73 31ed (0) 32dd (0) 3345 (0) 3648 (0)\n002 2 6544 7851 | 31 77ec (0) 759e (0) 7471 (0) 7406 (0)\n003 4 5695 5fa8 5f05 5c5d | 14 5110 (0) 5093 (0) 5288 (0) 5261 (0)\n004 2 4fd6 4f90 | 10 4b00 (0) 4a67 (0) 4a82 (0) 4a81 (0)\n005 2 42c0 42d4 | 4 4019 (0) 43af (0) 42c0 (0) 42d4 (0)\n============ DEPTH: 6 ==========================================\n006 1 458a | 1 458a (0)\n007 1 46c5 | 1 46c5 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"discovery":0,"listener":0},"ip":"0.0.0.0","id":"7b4585f8a4e4904239994a1b8bdc76299da8e46a8a632fabc6c33dd4170f8f3715e4c4f526ea5dd14093b150855960e432b1b140594aca21995f9e0722fb57f1","name":"node190","enode":"enode://7b4585f8a4e4904239994a1b8bdc76299da8e46a8a632fabc6c33dd4170f8f3715e4c4f526ea5dd14093b150855960e432b1b140594aca21995f9e0722fb57f1@0.0.0.0:0","listenAddr":""},"up":true,"config":{"name":"node190","services":["pss","bzz"],"private_key":"e40b799e72dc611e2a8f64d5b8c7ca95535499887a0eb36f5f4f3690097e0ce0","id":"7b4585f8a4e4904239994a1b8bdc76299da8e46a8a632fabc6c33dd4170f8f3715e4c4f526ea5dd14093b150855960e432b1b140594aca21995f9e0722fb57f1"}}},{"node":{"info":{"name":"node191","enode":"enode://c674c405068bb908312917a319e24ddf90e814ee8ef54bbf740f176b2a7eda6950e3e1ed69484ebcc27b13d82c7f0b20daba71a17700018e769ca612ca8d2208@0.0.0.0:0","listenAddr":"","ports":{"discovery":0,"listener":0},"protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: def4f0\npopulation: 18 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 47f9 | 135 0f5e (0) 0f81 (0) 0eee (0) 0ea2 (0)\n001 2 99fb 9461 | 56 8c89 (0) 8c61 (0) 89ee (0) 88da (0)\n002 2 e649 f3d3 | 29 e839 (0) ecd2 (0) edca (0) ed65 (0)\n003 1 c463 | 18 c9f3 (0) c99c (0) c98d (0) c883 (0)\n004 3 d3fd d7ab d564 | 7 d3d2 (0) d3fd (0) d68f (0) d6d2 (0)\n005 3 daa2 d8b0 d822 | 4 dae3 (0) daa2 (0) d822 (0) d8b0 (0)\n006 3 dc3e dc86 ddf8 | 3 dc3e (0) dc86 (0) ddf8 (0)\n============ DEPTH: 7 ==========================================\n007 2 df25 df5e | 2 df25 (0) df5e (0)\n008 0 | 0\n009 1 de82 | 1 de82 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"3vTwuYiUKoaZ9rUAzCUxx96gZePcW9y+smvKjwDh06Y="},"ip":"0.0.0.0","id":"c674c405068bb908312917a319e24ddf90e814ee8ef54bbf740f176b2a7eda6950e3e1ed69484ebcc27b13d82c7f0b20daba71a17700018e769ca612ca8d2208"},"up":true,"config":{"name":"node191","services":["pss","bzz"],"private_key":"11535d8be8b31e5bf636e9671c7be140d596984e31eb44adeb0002976fa05b97","id":"c674c405068bb908312917a319e24ddf90e814ee8ef54bbf740f176b2a7eda6950e3e1ed69484ebcc27b13d82c7f0b20daba71a17700018e769ca612ca8d2208"}}},{"node":{"config":{"id":"f52281c227aa82a3bd5fabfdcf8bdf1d9ea6739ab9b9075340143d59b4f2f8a79a981609c9f42823a0253c19a7281eed0e912e4054363ab7fe50117563ef14e0","private_key":"9870e0dfa67e07bbfca9e8eb065c1085adc82bf75d9d75fab9909f3681b654ed","services":["pss","bzz"],"name":"node192"},"up":true,"info":{"id":"f52281c227aa82a3bd5fabfdcf8bdf1d9ea6739ab9b9075340143d59b4f2f8a79a981609c9f42823a0253c19a7281eed0e912e4054363ab7fe50117563ef14e0","ports":{"listener":0,"discovery":0},"protocols":{"bzz":"xGMuFkFw016R/ORvZgJl9zeV8dhA7/zlqyquGMcwA9c=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: c4632e\npopulation: 21 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 2af0 6544 42d4 | 135 0f5e (0) 0f81 (0) 0eee (0) 0ea2 (0)\n001 2 9461 aa88 | 56 8c89 (0) 8c61 (0) 8ac8 (0) 8ae6 (0)\n002 1 f3d3 | 29 e839 (0) ecd2 (0) ed65 (0) ed13 (0)\n003 7 d7ab d564 d8b0 dc86 | 18 d3d2 (0) d3fd (0) d68f (0) d6d2 (0)\n004 2 ca81 ceee | 9 c9f3 (0) c99c (0) c98d (0) c883 (0)\n005 1 c15d | 3 c3f3 (0) c0d1 (0) c15d (0)\n============ DEPTH: 6 ==========================================\n006 4 c63e c64f c723 c770 | 4 c63e (0) c64f (0) c723 (0) c770 (0)\n007 0 | 0\n008 1 c484 | 1 c484 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ip":"0.0.0.0","listenAddr":"","name":"node192","enode":"enode://f52281c227aa82a3bd5fabfdcf8bdf1d9ea6739ab9b9075340143d59b4f2f8a79a981609c9f42823a0253c19a7281eed0e912e4054363ab7fe50117563ef14e0@0.0.0.0:0"}}},{"node":{"up":true,"config":{"private_key":"01d68cdd16950c65e5781ece848e201a6ebbd5097f74dadfd7a5fb007bbcc11d","id":"7a8cb96685c1b8fbaeb18c8dc1f9f2631b23bc035e704e2f5df915b8bcabd6e2025ddc30324c69833f86e577b250c0721fee9d294f3e22016ae4c59c5f88845b","name":"node193","services":["pss","bzz"]},"info":{"listenAddr":"","name":"node193","enode":"enode://7a8cb96685c1b8fbaeb18c8dc1f9f2631b23bc035e704e2f5df915b8bcabd6e2025ddc30324c69833f86e577b250c0721fee9d294f3e22016ae4c59c5f88845b@0.0.0.0:0","id":"7a8cb96685c1b8fbaeb18c8dc1f9f2631b23bc035e704e2f5df915b8bcabd6e2025ddc30324c69833f86e577b250c0721fee9d294f3e22016ae4c59c5f88845b","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 42d403\npopulation: 21 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 c463 ae65 aa88 9461 | 121 e839 (0) ecd2 (0) edca (0) ed65 (0)\n001 3 3a4a 2af0 2168 | 73 0f5e (0) 0f81 (0) 0eee (0) 0ea2 (0)\n002 2 6544 7d94 | 31 6ea5 (0) 6dbd (0) 6d21 (0) 6330 (0)\n003 4 5695 5c5d 5fa8 5f05 | 14 5110 (0) 5093 (0) 5288 (0) 5261 (0)\n004 3 4d44 4fd6 4f90 | 10 4b00 (0) 4a67 (0) 4af7 (0) 4a82 (0)\n005 2 458a 47f9 | 3 458a (0) 46c5 (0) 47f9 (0)\n006 1 4019 | 1 4019 (0)\n============ DEPTH: 7 ==========================================\n007 1 43af | 1 43af (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 1 42c0 | 1 42c0 (0)\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"QtQD9O5knry5R1PgZTka/QtNqZWiYoaWr9tLhR6fN3Q="},"ip":"0.0.0.0","ports":{"listener":0,"discovery":0}}}},{"node":{"info":{"id":"e323da6ae861cb092543992b8985639f9b3bcaf1c3c68757f4603a67800be62950fe7d8f8ef80eb83a18107b677c7f5047ea89a5790e0ea2a7969f4856d28488","protocols":{"bzz":"lGGSitg8GW5qAY6irxOEiDRv2cZBR7VEKH5Ec7qV7ZA=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 946192\npopulation: 24 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 5 2af0 0210 6d21 7d94 | 135 13d8 (0) 12b9 (0) 123f (0) 1673 (0)\n001 5 d7ab d564 def4 c463 | 65 e839 (0) ecd2 (0) edca (0) ed65 (0)\n002 2 ae65 aa88 | 30 baf3 (0) b8a7 (0) bc08 (0) bfec (0)\n003 2 8874 86f7 | 10 8c89 (0) 8c61 (0) 8ac8 (0) 8ae6 (0)\n004 6 9fee 9eec 9a82 99fb | 9 9c0c (0) 9c01 (0) 9fee (0) 9eec (0)\n005 1 9232 | 3 9390 (0) 9294 (2) 9232 (0)\n006 1 96b6 | 1 96b6 (0)\n============ DEPTH: 7 ==========================================\n007 1 95e0 | 1 95e0 (0)\n008 1 94aa | 1 94aa (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"discovery":0,"listener":0},"ip":"0.0.0.0","listenAddr":"","enode":"enode://e323da6ae861cb092543992b8985639f9b3bcaf1c3c68757f4603a67800be62950fe7d8f8ef80eb83a18107b677c7f5047ea89a5790e0ea2a7969f4856d28488@0.0.0.0:0","name":"node194"},"config":{"id":"e323da6ae861cb092543992b8985639f9b3bcaf1c3c68757f4603a67800be62950fe7d8f8ef80eb83a18107b677c7f5047ea89a5790e0ea2a7969f4856d28488","private_key":"7d7d75371a52b4d22411fc3dec135a945466d9fcce8615dbb959ebaf62bcebac","services":["pss","bzz"],"name":"node194"},"up":true}},{"node":{"up":true,"config":{"private_key":"cdcb88f25a626c1434db6d9ee8ae5934f466813535a8b9425572a888ade1bd98","id":"e7b2adabc2c99ac47b1e94fc0a2c63a00a1d622ea67a4c1858f4cec93fca957d43d8429605761bdf5eed4f733dac1a3d12fb928f22abf248965994acde63864a","name":"node195","services":["pss","bzz"]},"info":{"name":"node195","enode":"enode://e7b2adabc2c99ac47b1e94fc0a2c63a00a1d622ea67a4c1858f4cec93fca957d43d8429605761bdf5eed4f733dac1a3d12fb928f22abf248965994acde63864a@0.0.0.0:0","listenAddr":"","ip":"0.0.0.0","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 7d9414\npopulation: 17 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 9461 | 121 e839 (0) ed13 (0) ed65 (0) edca (0)\n001 2 2168 2af0 | 73 0f81 (0) 0f5e (0) 0eee (0) 0ea2 (0)\n002 4 5c5d 5f05 5fa8 42d4 | 31 5110 (0) 5093 (0) 5288 (0) 5261 (0)\n003 2 6d21 6544 | 11 6ea5 (0) 6dbd (0) 6d21 (0) 6330 (0)\n004 1 72fa | 8 77ec (0) 759e (0) 7406 (0) 7471 (0)\n005 2 7851 7a41 | 6 7a41 (0) 79ab (0) 79bd (0) 7829 (0)\n006 2 7fa4 7ffe | 2 7ffe (0) 7fa4 (0)\n007 0 | 0\n008 1 7d45 | 1 7d45 (0)\n============ DEPTH: 9 ==========================================\n009 2 7de7 7dc6 | 2 7de7 (0) 7dc6 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"fZQUdPkJgaA8la9M9ovhY9AaMX4gKsDbguJfRvw9uKo="},"ports":{"listener":0,"discovery":0},"id":"e7b2adabc2c99ac47b1e94fc0a2c63a00a1d622ea67a4c1858f4cec93fca957d43d8429605761bdf5eed4f733dac1a3d12fb928f22abf248965994acde63864a"}}},{"node":{"config":{"services":["pss","bzz"],"name":"node196","id":"5114329db828f9568ccb0d7643a10e273aa626177910f55e22a53abf1ce8ec75b95465c983446b20eac0ff9c59c5dc53eca95b24aabcc8dd110e397cd2934047","private_key":"70186f9ea20bd1f26270c4a3cc72d7fd6997f6ff1e81fa580ac396cfb8a53d96"},"up":true,"info":{"id":"5114329db828f9568ccb0d7643a10e273aa626177910f55e22a53abf1ce8ec75b95465c983446b20eac0ff9c59c5dc53eca95b24aabcc8dd110e397cd2934047","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 2af02e\npopulation: 17 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 9461 aa88 ddf8 c463 | 121 e839 (0) ecd2 (0) ed65 (0) ed13 (0)\n001 5 42d4 5fa8 7851 7d94 | 62 5110 (0) 5093 (0) 5288 (0) 5261 (0)\n002 1 1b1e | 38 0f5e (0) 0f81 (0) 0eee (0) 0ea2 (0)\n003 2 396b 3a4a | 15 31ed (0) 32dd (0) 3345 (0) 34fc (0)\n004 1 2168 | 9 275c (0) 265d (0) 2454 (0) 259d (0)\n005 1 2e4c | 5 2f22 (0) 2fd8 (0) 2f9f (0) 2e9f (0)\n006 1 290f | 3 29fd (0) 29ff (0) 290f (0)\n007 0 | 0\n============ DEPTH: 8 ==========================================\n008 2 2a22 2a69 | 2 2a22 (0) 2a69 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"KvAuYv8+QL4l0iwvdFpQW4lbOASoBmPLU9tO3VNlxWg="},"ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","name":"node196","enode":"enode://5114329db828f9568ccb0d7643a10e273aa626177910f55e22a53abf1ce8ec75b95465c983446b20eac0ff9c59c5dc53eca95b24aabcc8dd110e397cd2934047@0.0.0.0:0"}}},{"node":{"config":{"services":["pss","bzz"],"name":"node197","id":"4eab70233789c544bec97040a04099494bf269a819584a5d0b42295c918a52b02f224a8ed127aba3d92c02f567356bea4b95f77230ef548dfa7fe44b643d8704","private_key":"23e586de5f3e3d888e4b5afccbc7bbe9bc569233c4133cf8b4b6a6f722bcbcf4"},"up":true,"info":{"listenAddr":"","enode":"enode://4eab70233789c544bec97040a04099494bf269a819584a5d0b42295c918a52b02f224a8ed127aba3d92c02f567356bea4b95f77230ef548dfa7fe44b643d8704@0.0.0.0:0","name":"node197","id":"4eab70233789c544bec97040a04099494bf269a819584a5d0b42295c918a52b02f224a8ed127aba3d92c02f567356bea4b95f77230ef548dfa7fe44b643d8704","protocols":{"bzz":"ZUTEpAPZgJaXQg/5hA6p3gybpkkd4o2sKI22JX8twhg=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 6544c4\npopulation: 20 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 c463 | 121 e839 (0) ecd2 (0) ed65 (0) ed13 (0)\n001 2 2168 2af0 | 73 0f81 (0) 0f5e (0) 0eee (0) 0ea2 (0)\n002 4 47f9 42d4 5f05 5fa8 | 31 5110 (0) 5093 (0) 5288 (0) 5261 (0)\n003 3 7851 7a41 7d94 | 20 77ec (0) 759e (0) 7406 (0) 7471 (0)\n004 3 6ea5 6dbd 6d21 | 3 6ea5 (0) 6dbd (0) 6d21 (0)\n005 3 6330 604c 6143 | 3 6330 (0) 604c (0) 6143 (0)\n============ DEPTH: 6 ==========================================\n006 4 670d 67a2 6783 6610 | 4 670d (0) 67a2 (0) 6783 (0) 6610 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"discovery":0,"listener":0},"ip":"0.0.0.0"}}},{"node":{"info":{"id":"e0875ed6be1e163b15c13cdf37442f838670d0949349ee9ff119a0451beffb1a302943ee9d7cba48592922f64908aeb0f39f6e2e3725d1e7cdc5db34083b6977","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 21682c\npopulation: 20 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 ae65 aa88 | 121 e839 (0) ecd2 (0) ed65 (0) ed13 (0)\n001 5 42d4 5f05 5fa8 7d94 | 62 487e (0) 4b00 (0) 4a67 (0) 4af7 (0)\n002 1 1b1e | 38 0f5e (0) 0f81 (0) 0eee (0) 0ea2 (0)\n003 3 3d6b 396b 3a4a | 15 3648 (0) 3538 (0) 34fc (0) 31ed (0)\n004 4 2e4c 2a22 2a69 2af0 | 11 2f22 (0) 2fd8 (0) 2f9f (0) 2e9f (0)\n005 1 2454 | 4 275c (0) 265d (0) 259d (0) 2454 (0)\n006 2 2279 2374 | 2 2279 (0) 2374 (0)\n============ DEPTH: 7 ==========================================\n007 1 2013 | 1 2013 (0)\n008 0 | 0\n009 1 211a | 1 211a (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"IWgs1zbt+4tFHf2cVeueo7fPLjXK0yU38fSABkT7+ac="},"ports":{"listener":0,"discovery":0},"ip":"0.0.0.0","listenAddr":"","name":"node198","enode":"enode://e0875ed6be1e163b15c13cdf37442f838670d0949349ee9ff119a0451beffb1a302943ee9d7cba48592922f64908aeb0f39f6e2e3725d1e7cdc5db34083b6977@0.0.0.0:0"},"up":true,"config":{"name":"node198","services":["pss","bzz"],"private_key":"fa2860804ef40cd74e911bae08fd20f7fef5ee4d34f163dd456f566b899f18fd","id":"e0875ed6be1e163b15c13cdf37442f838670d0949349ee9ff119a0451beffb1a302943ee9d7cba48592922f64908aeb0f39f6e2e3725d1e7cdc5db34083b6977"}}},{"node":{"info":{"id":"c03ef1de42d522b44eef53be11f2c57b8b74fed9e87e6c2928c1feb48ddfecc67e1a3a8c8be1c47b3735a216d7054e2a4dda49fbd9a1ac702146aae5bdeced7c","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: aa889f\npopulation: 24 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 2af0 2168 42d4 5fa8 | 135 0f5e (0) 0f81 (0) 0eee (0) 0ea2 (0)\n001 5 c463 d7ab ddf8 e649 | 65 e839 (0) ecd2 (0) edca (0) ed65 (0)\n002 5 9461 9eec 99fb 99db | 26 8163 (0) 8612 (0) 86f7 (0) 8c89 (0)\n003 1 be0a | 14 b310 (0) b5c7 (0) b4c7 (0) b45d (0)\n004 3 a033 a672 a485 | 4 a672 (0) a749 (0) a485 (0) a033 (0)\n005 3 aca1 af30 ae65 | 8 adfc (0) ad36 (0) aca1 (0) af5f (0)\n006 1 a80b | 1 a80b (0)\n============ DEPTH: 7 ==========================================\n007 1 abfa | 1 abfa (0)\n008 1 aa50 | 1 aa50 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"qoifD6rsGltwMxUc6dPWhGaxKP+B3Le+/CzohdkjbHc="},"ports":{"listener":0,"discovery":0},"ip":"0.0.0.0","listenAddr":"","name":"node199","enode":"enode://c03ef1de42d522b44eef53be11f2c57b8b74fed9e87e6c2928c1feb48ddfecc67e1a3a8c8be1c47b3735a216d7054e2a4dda49fbd9a1ac702146aae5bdeced7c@0.0.0.0:0"},"config":{"services":["pss","bzz"],"name":"node199","id":"c03ef1de42d522b44eef53be11f2c57b8b74fed9e87e6c2928c1feb48ddfecc67e1a3a8c8be1c47b3735a216d7054e2a4dda49fbd9a1ac702146aae5bdeced7c","private_key":"1552e3359f865f955336c9e44aa94278481ebc3fba1bbac62a7e6c95d3348d6b"},"up":true}},{"node":{"up":true,"config":{"services":["pss","bzz"],"name":"node200","id":"0e164c8692532e59c76ef84319a1093324f46f77618d3a836a279df52edca6c839061c0582dac7481da1bd0f3e2b58fc0dacd6ee5d678ba1406d4a1a25fe761d","private_key":"da57c89729140a0f359ddf902197cddcb6b13a00c226d1a8a0975bda02f3a495"},"info":{"ip":"0.0.0.0","protocols":{"bzz":"X6iloppHaUZTpeVf2bdunE9xfsybcIim7H7ic7KR1J4=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 5fa8a5\npopulation: 17 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 ae65 aa88 | 121 e839 (0) ecd2 (0) edca (0) ed65 (0)\n001 3 3a4a 2af0 2168 | 73 0f5e (0) 0f81 (0) 0eee (0) 0ea2 (0)\n002 3 7d94 6544 6d21 | 31 6330 (0) 604c (0) 6143 (0) 670d (0)\n003 3 47f9 42c0 42d4 | 17 4b00 (0) 4a67 (0) 4af7 (0) 4a82 (0)\n004 2 5261 5695 | 9 5110 (0) 5093 (0) 5288 (0) 5261 (0)\n005 0 | 0\n006 1 5c5d | 1 5c5d (0)\n007 0 | 0\n008 1 5f05 | 1 5f05 (0)\n============ DEPTH: 9 ==========================================\n009 1 5fd0 | 1 5fd0 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 1 5fab | 1 5fab (0)\n015 0 | 0\n========================================================================="},"ports":{"discovery":0,"listener":0},"id":"0e164c8692532e59c76ef84319a1093324f46f77618d3a836a279df52edca6c839061c0582dac7481da1bd0f3e2b58fc0dacd6ee5d678ba1406d4a1a25fe761d","enode":"enode://0e164c8692532e59c76ef84319a1093324f46f77618d3a836a279df52edca6c839061c0582dac7481da1bd0f3e2b58fc0dacd6ee5d678ba1406d4a1a25fe761d@0.0.0.0:0","name":"node200","listenAddr":""}}},{"node":{"info":{"listenAddr":"","name":"node201","enode":"enode://a1fe0d27f82309911a4b758c4e597bde16adc1e2fdfb07b52dea5092cea40ff212ea2cc831e385094b044f519909cf978f350b16ffd4c70c159cf1372301a3cf@0.0.0.0:0","id":"a1fe0d27f82309911a4b758c4e597bde16adc1e2fdfb07b52dea5092cea40ff212ea2cc831e385094b044f519909cf978f350b16ffd4c70c159cf1372301a3cf","protocols":{"bzz":"XwVvlZO+RtPrpNyNnguTJizT8A4AfBPEwBHVPnwZlig=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 5f056f\npopulation: 15 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 f3d3 | 121 8c89 (0) 8c61 (0) 8ac8 (0) 8ae6 (0)\n001 2 2e4c 2168 | 73 0f5e (0) 0f81 (0) 0eee (0) 0ea2 (0)\n002 3 6d21 6544 7d94 | 31 6330 (0) 604c (0) 6143 (0) 67a2 (0)\n003 3 47f9 42c0 42d4 | 17 487e (0) 4b00 (0) 4a67 (0) 4af7 (0)\n004 2 5261 5695 | 9 5110 (0) 5093 (0) 5288 (0) 5261 (0)\n005 0 | 0\n006 1 5c5d | 1 5c5d (0)\n007 0 | 0\n============ DEPTH: 8 ==========================================\n008 3 5fd0 5fab 5fa8 | 3 5fd0 (0) 5fab (0) 5fa8 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"listener":0,"discovery":0},"ip":"0.0.0.0"},"up":true,"config":{"name":"node201","services":["pss","bzz"],"private_key":"a71ad1e471863026826e723cb60ef8221c29ef9c115f59ec22dccfdbf13724cb","id":"a1fe0d27f82309911a4b758c4e597bde16adc1e2fdfb07b52dea5092cea40ff212ea2cc831e385094b044f519909cf978f350b16ffd4c70c159cf1372301a3cf"}}},{"node":{"info":{"enode":"enode://8e89fe4b3fffea8af247d2581aa511056efbeb796058d50a341d57aa0f7ccc2192d90cfb8d18558363df798567faaddb86815e8bd671b36ca37af0651535aabf@0.0.0.0:0","name":"node202","listenAddr":"","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: f3d3ba\npopulation: 22 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 42c0 5f05 | 135 13d8 (0) 12b9 (0) 123f (0) 1673 (0)\n001 5 8874 9461 aa88 aca1 | 56 8163 (0) 8612 (0) 86f7 (0) 8c89 (0)\n002 7 ceee c463 d3fd d7ab | 36 cb69 (0) ca81 (0) c9f3 (0) c99c (0)\n003 2 e787 e649 | 12 e839 (0) ecd2 (0) edca (0) ed65 (0)\n004 1 f915 | 6 fd2d (0) fed1 (0) fb93 (0) fa74 (0)\n005 1 f5cc | 6 f644 (0) f78a (0) f4e0 (0) f4ee (0)\n============ DEPTH: 6 ==========================================\n006 4 f1fc f156 f0e2 f048 | 4 f1fc (0) f156 (0) f0e2 (0) f048 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"89O6IGUoJ7WMYFoTfi8H2qXROYBOtKnEJwEp3joN51k="},"ports":{"listener":0,"discovery":0},"ip":"0.0.0.0","id":"8e89fe4b3fffea8af247d2581aa511056efbeb796058d50a341d57aa0f7ccc2192d90cfb8d18558363df798567faaddb86815e8bd671b36ca37af0651535aabf"},"up":true,"config":{"private_key":"66b7f7a02087e6dda466b0fb6d05311ce95e179b4baf6cb7dd1fc1052f066367","id":"8e89fe4b3fffea8af247d2581aa511056efbeb796058d50a341d57aa0f7ccc2192d90cfb8d18558363df798567faaddb86815e8bd671b36ca37af0651535aabf","name":"node202","services":["pss","bzz"]}}},{"node":{"up":true,"config":{"services":["pss","bzz"],"name":"node203","id":"df9306a263f40e0e255996500523354de3cc78b68ae560f66d79f6ea28f30f773f1fd6ebc33928723dfde2ee3d4f982b203bee4c3803a5050df83477045bb279","private_key":"f4efac8f64908b896f893bb4b4113b00734dfcbf9aa87245f1aa8e9f65b644ce"},"info":{"protocols":{"bzz":"rmV4aT7ZM+Nqf0ma3eNAx5vcoPX1czTbpWRrweTXtxc=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: ae6578\npopulation: 22 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 42d4 5fa8 2168 2e4c | 135 0f81 (0) 0f5e (0) 0eee (0) 0ea2 (0)\n001 2 f3d3 ceee | 65 e839 (0) ecd2 (0) edca (0) ed65 (0)\n002 4 9461 9eec 99db 99aa | 26 8163 (0) 8612 (0) 86f7 (0) 8c89 (0)\n003 2 be0a b710 | 14 baf3 (0) b8a7 (0) bc08 (0) bfec (0)\n004 2 a033 a485 | 4 a033 (0) a672 (0) a749 (0) a485 (0)\n005 2 a80b aa88 | 4 a80b (0) abfa (0) aa50 (0) aa88 (0)\n006 2 ad36 aca1 | 3 adfc (0) ad36 (0) aca1 (0)\n============ DEPTH: 7 ==========================================\n007 3 af5f af35 af30 | 3 af5f (0) af35 (0) af30 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 1 ae71 | 1 ae71 (0)\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ip":"0.0.0.0","ports":{"listener":0,"discovery":0},"id":"df9306a263f40e0e255996500523354de3cc78b68ae560f66d79f6ea28f30f773f1fd6ebc33928723dfde2ee3d4f982b203bee4c3803a5050df83477045bb279","name":"node203","enode":"enode://df9306a263f40e0e255996500523354de3cc78b68ae560f66d79f6ea28f30f773f1fd6ebc33928723dfde2ee3d4f982b203bee4c3803a5050df83477045bb279@0.0.0.0:0","listenAddr":""}}},{"node":{"config":{"services":["pss","bzz"],"name":"node204","id":"b7cc9044d021b19cd8a6d290d21f1c91fd5deec472583d0aeed0a6aacc8efef9968079254132becc5443df14dd3f4feaee56d14b885c078649727b9659139fa6","private_key":"f15da5ee626bdec9e7b303afaff488d87aff1815668f878ea6b1f270c6300ec2"},"up":true,"info":{"listenAddr":"","name":"node204","enode":"enode://b7cc9044d021b19cd8a6d290d21f1c91fd5deec472583d0aeed0a6aacc8efef9968079254132becc5443df14dd3f4feaee56d14b885c078649727b9659139fa6@0.0.0.0:0","id":"b7cc9044d021b19cd8a6d290d21f1c91fd5deec472583d0aeed0a6aacc8efef9968079254132becc5443df14dd3f4feaee56d14b885c078649727b9659139fa6","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: ceee9a\npopulation: 17 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 3a4a | 135 7307 (0) 7294 (0) 72ac (0) 72fa (0)\n001 2 99aa ae65 | 56 baf3 (0) b8a7 (0) bfec (0) bf5a (0)\n002 1 f3d3 | 29 e839 (0) ecd2 (0) edca (0) ed65 (0)\n003 4 d3fd d7ab d564 ddf8 | 18 d3d2 (0) d3fd (0) d68f (0) d6d2 (0)\n004 1 c463 | 9 c3f3 (0) c0d1 (0) c15d (0) c63e (0)\n============ DEPTH: 5 ==========================================\n005 8 cb69 ca81 c883 c8f9 | 8 c883 (0) c8f9 (0) c8fe (0) c9f3 (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"zu6axjeGrWjYhPXQGCSK4be2DwrUNHdtKb1N/NwPBME="},"ports":{"discovery":0,"listener":0},"ip":"0.0.0.0"}}},{"node":{"info":{"id":"842f0ac24370f14edfe72a7d07219de60fc767d2d0356fa6ce9d535a43647ad4bb17d9be75ed83542868ba430ec104ba168f27c16915cdbd6e57ae62d60707cb","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 3a4a30\npopulation: 15 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 99aa ceee | 121 baf3 (0) b8a7 (0) bfec (0) bf5a (0)\n001 2 42d4 5fa8 | 62 7307 (0) 7294 (0) 72ac (0) 72fa (0)\n002 1 0210 | 38 13d8 (0) 12b9 (0) 123f (0) 1673 (0)\n003 4 2a69 2af0 2e4c 2168 | 20 290f (0) 29ff (0) 29fd (0) 2a22 (0)\n004 1 31ed | 6 31ed (0) 32dd (0) 3345 (0) 3648 (0)\n005 2 3e85 3d6b | 5 3f3e (0) 3e44 (0) 3e85 (0) 3dca (0)\n============ DEPTH: 6 ==========================================\n006 2 388d 396b | 2 388d (0) 396b (0)\n007 0 | 0\n008 1 3af3 | 1 3af3 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"OkowDeEAnWlL684jYspCkIat4vVRmJ1VukWaaO/qFa8="},"ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","enode":"enode://842f0ac24370f14edfe72a7d07219de60fc767d2d0356fa6ce9d535a43647ad4bb17d9be75ed83542868ba430ec104ba168f27c16915cdbd6e57ae62d60707cb@0.0.0.0:0","name":"node205"},"up":true,"config":{"private_key":"ec037812b58da37d27db08df00018a39dc06d096116acf7f56921452cf7cfc0b","id":"842f0ac24370f14edfe72a7d07219de60fc767d2d0356fa6ce9d535a43647ad4bb17d9be75ed83542868ba430ec104ba168f27c16915cdbd6e57ae62d60707cb","name":"node205","services":["pss","bzz"]}}},{"node":{"info":{"listenAddr":"","name":"node206","enode":"enode://7d9979c13cd8841e84e5d199fc263962ca6fee12664d8526a581bfcdca2e3427ca169b9a0244dd8292a9a1be2bcedb0e8f626eadd307068c11c03b6df13aee33@0.0.0.0:0","id":"7d9979c13cd8841e84e5d199fc263962ca6fee12664d8526a581bfcdca2e3427ca169b9a0244dd8292a9a1be2bcedb0e8f626eadd307068c11c03b6df13aee33","protocols":{"bzz":"maqqfJgROVXswBY5QzF/bsCK51XpbCXJ95yh9SnGBYc=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 99aaaa\npopulation: 16 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 6d21 3a4a | 135 77ec (0) 759e (0) 7406 (0) 7471 (0)\n001 3 ceee ddf8 d564 | 65 c3f3 (0) c0d1 (0) c15d (0) c63e (0)\n002 3 aa88 aca1 ae65 | 30 baf3 (0) b8a7 (0) bfec (0) bf5a (0)\n003 1 8874 | 10 8163 (0) 8612 (0) 86f7 (0) 8c89 (0)\n004 2 95e0 9461 | 7 9390 (0) 9294 (0) 9232 (0) 96b6 (0)\n005 1 9eec | 4 9c0c (0) 9c01 (0) 9fee (0) 9eec (0)\n006 1 9a82 | 1 9a82 (0)\n007 1 985c | 1 985c (0)\n008 0 | 0\n============ DEPTH: 9 ==========================================\n009 2 99fb 99db | 2 99fb (0) 99db (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ip":"0.0.0.0","ports":{"discovery":0,"listener":0}},"up":true,"config":{"name":"node206","services":["pss","bzz"],"private_key":"9a037c145472a92a10b90fce8fe35501e93af7b73b026641d66a53ccfd3930dd","id":"7d9979c13cd8841e84e5d199fc263962ca6fee12664d8526a581bfcdca2e3427ca169b9a0244dd8292a9a1be2bcedb0e8f626eadd307068c11c03b6df13aee33"}}},{"node":{"up":true,"config":{"services":["pss","bzz"],"name":"node207","id":"5a235aca7005df295d5bd924b1272452e9bdad408ca5223b9eb76800b4bd4e3158a1d663ce5243fee92233227249fe4bb8507e8cb2c3729744b273bf488ba60c","private_key":"14480f714ca25c522c067b4bce766945c9c2e8d0b697eacf9ff286fb0c26dac9"},"info":{"ports":{"discovery":0,"listener":0},"protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 99dbf3\npopulation: 15 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 6d21 | 135 0f5e (0) 0f81 (0) 0eee (0) 0ea2 (0)\n001 2 d564 ddf8 | 65 c3f3 (0) c0d1 (0) c15d (0) c64f (0)\n002 3 aca1 ae65 aa88 | 30 baf3 (0) b8a7 (0) bc08 (0) bfec (0)\n003 1 8874 | 10 8163 (0) 8612 (0) 86f7 (0) 8c89 (0)\n004 2 95e0 9461 | 7 9390 (0) 9232 (0) 9294 (0) 96b6 (0)\n005 2 9c01 9eec | 4 9c0c (0) 9c01 (0) 9fee (0) 9eec (0)\n006 1 9a82 | 1 9a82 (0)\n007 1 985c | 1 985c (0)\n008 0 | 0\n============ DEPTH: 9 ==========================================\n009 1 99aa | 1 99aa (0)\n010 1 99fb | 1 99fb (0)\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"mdvzYbZ9bDcP1PIBsFnpPaUN2IzeLiXQvPPHOvvxNTU="},"ip":"0.0.0.0","id":"5a235aca7005df295d5bd924b1272452e9bdad408ca5223b9eb76800b4bd4e3158a1d663ce5243fee92233227249fe4bb8507e8cb2c3729744b273bf488ba60c","name":"node207","enode":"enode://5a235aca7005df295d5bd924b1272452e9bdad408ca5223b9eb76800b4bd4e3158a1d663ce5243fee92233227249fe4bb8507e8cb2c3729744b273bf488ba60c@0.0.0.0:0","listenAddr":""}}},{"node":{"config":{"private_key":"c756a2bbb4c7b536c169fea0b09c7834ce6ce6f687c4968e598b72606163b8f3","id":"c088bf88f1e152ca3fad17f098a71ca1021d46d8af12d0ee1c587a5e2a430d8e48beaf171fe01ee7680b671c00dd88c90f12a35c328a3f334661fdeee914a4bc","name":"node208","services":["pss","bzz"]},"up":true,"info":{"id":"c088bf88f1e152ca3fad17f098a71ca1021d46d8af12d0ee1c587a5e2a430d8e48beaf171fe01ee7680b671c00dd88c90f12a35c328a3f334661fdeee914a4bc","ip":"0.0.0.0","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 6d219b\npopulation: 19 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 ddf8 9461 99aa 99db | 121 e839 (0) ecd2 (0) edca (0) ed65 (0)\n001 1 2e4c | 73 0f81 (0) 0f5e (0) 0eee (0) 0ea2 (0)\n002 2 5f05 5fa8 | 31 487e (0) 4b00 (0) 4a67 (0) 4af7 (0)\n003 3 7d94 7851 7a41 | 20 77ec (0) 759e (0) 7406 (0) 7471 (0)\n004 7 6330 6143 604c 6783 | 8 6330 (0) 604c (0) 6143 (0) 670d (0)\n005 0 | 0\n============ DEPTH: 6 ==========================================\n006 1 6ea5 | 1 6ea5 (0)\n007 0 | 0\n008 1 6dbd | 1 6dbd (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"bSGbDqShYgp7oFHMR42m356kQ+h93nnpY+x4mlutdFk="},"ports":{"listener":0,"discovery":0},"listenAddr":"","enode":"enode://c088bf88f1e152ca3fad17f098a71ca1021d46d8af12d0ee1c587a5e2a430d8e48beaf171fe01ee7680b671c00dd88c90f12a35c328a3f334661fdeee914a4bc@0.0.0.0:0","name":"node208"}}},{"node":{"info":{"id":"77811b007dd1fc1b11e447858df37062e97b6fc14e059399814f3b4736188e3fb28bf7c3958bb8ebc6ae16c36884ba7c98b810fb6f8b358323412123c803abd4","ip":"0.0.0.0","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: ddf8ff\npopulation: 26 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 7 0210 1b1e 2af0 2e4c | 135 0f5e (0) 0f81 (0) 0eee (0) 0ea2 (0)\n001 4 aca1 aa88 99aa 99db | 56 baf3 (0) b8a7 (0) bc08 (0) bfec (0)\n002 2 e649 f3d3 | 29 e839 (0) ecd2 (0) edca (0) ed65 (0)\n003 2 c463 ceee | 18 c3f3 (0) c0d1 (0) c15d (0) c63e (0)\n004 3 d3fd d7ab d564 | 7 d3d2 (0) d3fd (0) d6d2 (0) d6f3 (0)\n005 3 daa2 d822 d8b0 | 4 dae3 (0) daa2 (0) d822 (0) d8b0 (0)\n006 3 df25 de82 def4 | 4 df25 (0) df5e (0) de82 (0) def4 (0)\n============ DEPTH: 7 ==========================================\n007 2 dc3e dc86 | 2 dc3e (0) dc86 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"3fj/5h/dFED/LVDUJhnVLrElq4qh6OXOFidMxPRyixk="},"ports":{"discovery":0,"listener":0},"listenAddr":"","enode":"enode://77811b007dd1fc1b11e447858df37062e97b6fc14e059399814f3b4736188e3fb28bf7c3958bb8ebc6ae16c36884ba7c98b810fb6f8b358323412123c803abd4@0.0.0.0:0","name":"node209"},"up":true,"config":{"services":["pss","bzz"],"name":"node209","id":"77811b007dd1fc1b11e447858df37062e97b6fc14e059399814f3b4736188e3fb28bf7c3958bb8ebc6ae16c36884ba7c98b810fb6f8b358323412123c803abd4","private_key":"a837afe73ba3598ea681339261b12f5b9f02f1ce5243d6f7d18c735562b5a485"}}},{"node":{"info":{"listenAddr":"","name":"node210","enode":"enode://228b3646b15527f4df07b847a62dbf9620cb068f829e9086b5f437d0b64d8a027cab44f19db5e44189b5099545ecb25d49384c261748f9533cfb0eb11a1eca5f@0.0.0.0:0","id":"228b3646b15527f4df07b847a62dbf9620cb068f829e9086b5f437d0b64d8a027cab44f19db5e44189b5099545ecb25d49384c261748f9533cfb0eb11a1eca5f","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: d5644a\npopulation: 26 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 0210 1b1e 2e4c | 135 6ea5 (0) 6dbd (0) 6d21 (0) 604c (0)\n001 5 aca1 9461 99db 99aa | 56 baf3 (0) b8a7 (0) bc08 (0) bfec (0)\n002 2 e649 f3d3 | 29 e839 (0) ecd2 (0) edca (0) ed65 (0)\n003 2 c463 ceee | 18 c3f3 (0) c0d1 (0) c15d (0) c64f (0)\n004 8 dae3 d822 d8b0 df25 | 11 dae3 (0) daa2 (0) d822 (0) d8b0 (0)\n005 2 d3d2 d3fd | 2 d3d2 (0) d3fd (0)\n============ DEPTH: 6 ==========================================\n006 4 d6d2 d6f3 d68f d7ab | 4 d68f (0) d6d2 (0) d6f3 (0) d7ab (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"1WRKcqmt72Z/4z+/WvRSFNHdCTMRZbJOUE6PXu+2GV4="},"ports":{"discovery":0,"listener":0},"ip":"0.0.0.0"},"config":{"private_key":"6dab6d6b30b7515d850f1f4e7d6fffc75064eafafd86b8754a4000153113b1de","id":"228b3646b15527f4df07b847a62dbf9620cb068f829e9086b5f437d0b64d8a027cab44f19db5e44189b5099545ecb25d49384c261748f9533cfb0eb11a1eca5f","name":"node210","services":["pss","bzz"]},"up":true}},{"node":{"info":{"name":"node211","enode":"enode://ecd217e8bdb53c9ef085929b8c2d2b40425a4be617a087b8e7f88e8507b3c981e90fda2119744ca394fe65bd4eb1cdd3fa7258db936048e236d2f15ee91bc3b6@0.0.0.0:0","listenAddr":"","protocols":{"bzz":"nuxdU1dzKnrNJsyKoLxl9sYGmu3086tKZ5DH//a8JpU=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 9eec5d\npopulation: 15 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 5695 | 135 1673 (0) 15f6 (0) 1566 (0) 1441 (0)\n001 1 d564 | 65 e839 (0) ecd2 (0) ed65 (0) ed13 (0)\n002 2 ae65 aa88 | 30 baf3 (0) b8a7 (0) bc08 (0) bfec (0)\n003 2 86f7 8612 | 10 8163 (0) 8612 (0) 86f7 (0) 8c89 (0)\n004 2 95e0 9461 | 7 9390 (0) 9294 (0) 9232 (0) 96b6 (0)\n005 4 9a82 99fb 99db 99aa | 5 9a82 (0) 985c (0) 99aa (0) 99fb (0)\n============ DEPTH: 6 ==========================================\n006 2 9c0c 9c01 | 2 9c0c (0) 9c01 (0)\n007 1 9fee | 1 9fee (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ip":"0.0.0.0","ports":{"listener":0,"discovery":0},"id":"ecd217e8bdb53c9ef085929b8c2d2b40425a4be617a087b8e7f88e8507b3c981e90fda2119744ca394fe65bd4eb1cdd3fa7258db936048e236d2f15ee91bc3b6"},"up":true,"config":{"private_key":"431d8e4e06f15988a4ea9b3c077ca2b2bfc5b8b04135fea5ad7dee050940422b","id":"ecd217e8bdb53c9ef085929b8c2d2b40425a4be617a087b8e7f88e8507b3c981e90fda2119744ca394fe65bd4eb1cdd3fa7258db936048e236d2f15ee91bc3b6","name":"node211","services":["pss","bzz"]}}},{"node":{"config":{"name":"node212","services":["pss","bzz"],"private_key":"adf12e35cb550ed5a52fb5fa25fe7a6298e71b77a2dae474ebefbf2f9b8aac69","id":"ab13f773f6f2ff73032aa5f79c8897b75dda29bcbb14aa511e9401c2417dc9c510253071e28c7833c8d62fd2aef16fcd0c14ce016fbf4fec1b9a2173c717603f"},"up":true,"info":{"protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 569567\npopulation: 24 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 c8fe 9eec | 121 e839 (0) ecd2 (0) edca (0) ed65 (0)\n001 3 1b1e 0210 2e4c | 73 12b9 (0) 123f (0) 13d8 (0) 1673 (0)\n002 3 6dbd 7a41 7851 | 31 6330 (0) 604c (0) 6143 (0) 670d (0)\n003 4 4a82 47f9 42d4 42c0 | 17 487e (0) 4b00 (0) 4a67 (0) 4af7 (0)\n004 4 5c5d 5fa8 5fd0 5f05 | 5 5c5d (0) 5fd0 (0) 5fab (0) 5fa8 (0)\n005 4 5110 5093 5261 5288 | 4 5110 (0) 5093 (0) 5261 (0) 5288 (0)\n006 1 5571 | 1 5571 (0)\n============ DEPTH: 7 ==========================================\n007 2 5716 57d5 | 2 5716 (0) 57d5 (0)\n008 1 566e | 1 566e (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"VpVnYD8FdRip2t4x8tEsV8Xd4F7lBYbvDwpvmPT2NmA="},"ports":{"listener":0,"discovery":0},"ip":"0.0.0.0","id":"ab13f773f6f2ff73032aa5f79c8897b75dda29bcbb14aa511e9401c2417dc9c510253071e28c7833c8d62fd2aef16fcd0c14ce016fbf4fec1b9a2173c717603f","enode":"enode://ab13f773f6f2ff73032aa5f79c8897b75dda29bcbb14aa511e9401c2417dc9c510253071e28c7833c8d62fd2aef16fcd0c14ce016fbf4fec1b9a2173c717603f@0.0.0.0:0","name":"node212","listenAddr":""}}},{"node":{"config":{"id":"b60def37233dbbc0d5f7fcddb304be1c0b6508e1e3d8a09a8290f7363e9bb84152dcaf70b8f6bb3a882fee77ff03ab796a5c1c3654f251c9f5c746ac5ad88556","private_key":"7a94e705247608b3fe77122138a93f8477964e4a1a5d068091ff655f6ff0acd9","services":["pss","bzz"],"name":"node213"},"up":true,"info":{"listenAddr":"","name":"node213","enode":"enode://b60def37233dbbc0d5f7fcddb304be1c0b6508e1e3d8a09a8290f7363e9bb84152dcaf70b8f6bb3a882fee77ff03ab796a5c1c3654f251c9f5c746ac5ad88556@0.0.0.0:0","id":"b60def37233dbbc0d5f7fcddb304be1c0b6508e1e3d8a09a8290f7363e9bb84152dcaf70b8f6bb3a882fee77ff03ab796a5c1c3654f251c9f5c746ac5ad88556","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 2e4c8c\npopulation: 23 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 5 ae65 c8fe ddf8 d564 | 121 baf3 (0) b8a7 (0) be0a (0) bf5a (0)\n001 7 6dbd 6d21 7a41 7851 | 62 6330 (0) 604c (0) 6143 (0) 6610 (0)\n002 2 1e44 0210 | 38 13d8 (0) 12b9 (0) 123f (0) 1673 (0)\n003 2 3a4a 396b | 15 31ed (0) 32dd (0) 3345 (0) 34fc (0)\n004 1 2168 | 9 275c (0) 265d (0) 259d (0) 2454 (0)\n005 2 2a69 2af0 | 6 29ff (0) 29fd (0) 290f (0) 2a22 (0)\n006 0 | 0\n============ DEPTH: 7 ==========================================\n007 3 2fd8 2f9f 2f22 | 3 2f22 (0) 2f9f (0) 2fd8 (0)\n008 1 2e9f | 1 2e9f (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"LkyMNxlo86POouLBybxF+KDL7Umnofut4X6jSm5XScs="},"ports":{"discovery":0,"listener":0},"ip":"0.0.0.0"}}},{"node":{"info":{"name":"node214","enode":"enode://dd3dccc1758765569905b3b137ef4c7dd31c2dc0dea827bcc4c4e976be94ffbb0f2ef6fe725cf9042063a96d663efea546837f35ca1fc67a854fbc9e27abb754@0.0.0.0:0","listenAddr":"","ip":"0.0.0.0","protocols":{"bzz":"16u61zKUi2ZHbhgz8K9rtiUNu/SscbnHW0/GNLYX6Nc=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: d7abba\npopulation: 23 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 0210 2e4c 42c0 | 135 13d8 (0) 123f (0) 12b9 (0) 1673 (0)\n001 4 8874 9461 a033 aa88 | 56 baf3 (0) b8a7 (0) bf5a (0) bfec (0)\n002 2 f3d3 e649 | 29 e839 (0) ecd2 (0) edca (0) ed65 (0)\n003 2 ceee c463 | 18 cb69 (0) ca81 (0) c9f3 (0) c99c (0)\n004 6 d8b0 def4 de82 dc3e | 11 dae3 (0) daa2 (0) d822 (0) d8b0 (0)\n005 2 d3fd d3d2 | 2 d3fd (0) d3d2 (0)\n006 1 d564 | 1 d564 (0)\n============ DEPTH: 7 ==========================================\n007 3 d68f d6d2 d6f3 | 3 d68f (0) d6d2 (0) d6f3 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"listener":0,"discovery":0},"id":"dd3dccc1758765569905b3b137ef4c7dd31c2dc0dea827bcc4c4e976be94ffbb0f2ef6fe725cf9042063a96d663efea546837f35ca1fc67a854fbc9e27abb754"},"up":true,"config":{"id":"dd3dccc1758765569905b3b137ef4c7dd31c2dc0dea827bcc4c4e976be94ffbb0f2ef6fe725cf9042063a96d663efea546837f35ca1fc67a854fbc9e27abb754","private_key":"c121bd7298c0130e294b88e6bb3b99fa0db790e9760b605448356e1fd89a3e5b","services":["pss","bzz"],"name":"node214"}}},{"node":{"info":{"id":"936fad959da2d8b0cfb2bcd78c5da65bcce5e9463be7fc7367f45cdfa20678f4c466fb1e3f600783a270855fd4b9cd6265054f79ecb116141e7c67a492041bed","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 42c019\npopulation: 19 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 d7ab f3d3 e649 | 121 b310 (0) b5c7 (0) b4c7 (0) b45d (0)\n001 3 0210 396b 2e4c | 73 13d8 (0) 12b9 (0) 123f (0) 1673 (0)\n002 3 6dbd 7a41 7851 | 31 6330 (0) 6143 (0) 604c (0) 670d (0)\n003 4 5c5d 5fa8 5f05 5695 | 14 5c5d (0) 5fd0 (0) 5fab (0) 5fa8 (0)\n004 2 4f90 4d44 | 10 487e (0) 4b00 (0) 4a67 (0) 4af7 (0)\n005 1 47f9 | 3 458a (0) 46c5 (0) 47f9 (0)\n006 1 4019 | 1 4019 (0)\n============ DEPTH: 7 ==========================================\n007 1 43af | 1 43af (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 1 42d4 | 1 42d4 (0)\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"QsAZ3a0v3g8Mf1BB61hJlpdoRPiy4I4gRYQ3V40CV+8="},"ports":{"listener":0,"discovery":0},"ip":"0.0.0.0","listenAddr":"","enode":"enode://936fad959da2d8b0cfb2bcd78c5da65bcce5e9463be7fc7367f45cdfa20678f4c466fb1e3f600783a270855fd4b9cd6265054f79ecb116141e7c67a492041bed@0.0.0.0:0","name":"node215"},"up":true,"config":{"services":["pss","bzz"],"name":"node215","id":"936fad959da2d8b0cfb2bcd78c5da65bcce5e9463be7fc7367f45cdfa20678f4c466fb1e3f600783a270855fd4b9cd6265054f79ecb116141e7c67a492041bed","private_key":"562bd811ced052733cf87caf5888571e4482ae46e14ae1585debfb6b10298249"}}},{"node":{"info":{"ip":"0.0.0.0","protocols":{"bzz":"5kke5SkRlyHSwc4W0iD10FW6NZePTXxmxOwuOsNhg/o=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: e6491e\npopulation: 22 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 7851 42c0 | 135 13d8 (0) 12b9 (0) 123f (0) 1673 (0)\n001 2 aa88 aca1 | 56 b8a7 (0) baf3 (0) bc08 (0) bfec (0)\n002 5 def4 ddf8 d3fd d7ab | 36 c8f9 (0) c8fe (0) c883 (0) c9f3 (0)\n003 4 f915 f4ee f5cc f3d3 | 17 fed1 (0) fd2d (0) fb93 (0) fa74 (0)\n004 3 ecd2 edca ed13 | 5 e839 (0) ecd2 (0) edca (0) ed65 (0)\n005 1 e3c9 | 1 e3c9 (0)\n006 2 e4c3 e44b | 2 e4c3 (0) e44b (0)\n============ DEPTH: 7 ==========================================\n007 2 e76a e787 | 2 e76a (0) e787 (0)\n008 0 | 0\n009 0 | 0\n010 1 e67d | 1 e67d (0)\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"listener":0,"discovery":0},"id":"6a55b94c9990249b24cdbeed96f065137f7b79ea8ee5f58da150d3962dfb62ba401960a53e7e8bd4e2c2908aa1a59b9d5efb4aafb316a9ab4fa67a0d95b58c54","name":"node216","enode":"enode://6a55b94c9990249b24cdbeed96f065137f7b79ea8ee5f58da150d3962dfb62ba401960a53e7e8bd4e2c2908aa1a59b9d5efb4aafb316a9ab4fa67a0d95b58c54@0.0.0.0:0","listenAddr":""},"config":{"id":"6a55b94c9990249b24cdbeed96f065137f7b79ea8ee5f58da150d3962dfb62ba401960a53e7e8bd4e2c2908aa1a59b9d5efb4aafb316a9ab4fa67a0d95b58c54","private_key":"8ebd5353e11b993fd7941ca1a936fc21799344607325c2879687b5e90adee6db","services":["pss","bzz"],"name":"node216"},"up":true}},{"node":{"up":true,"config":{"services":["pss","bzz"],"name":"node217","id":"a25958cf192a4f62301feda5d442535f78b983dd9e4599354f4898c8c1e6ad97ca7112549e1d1a1eacb4682cd1bf8b762368b5905ab33dbdacb585b128514ca1","private_key":"8234acebca52619acf23d978bbc19bf2d8cbbc933bc7e18c7903d4b047471348"},"info":{"listenAddr":"","enode":"enode://a25958cf192a4f62301feda5d442535f78b983dd9e4599354f4898c8c1e6ad97ca7112549e1d1a1eacb4682cd1bf8b762368b5905ab33dbdacb585b128514ca1@0.0.0.0:0","name":"node217","id":"a25958cf192a4f62301feda5d442535f78b983dd9e4599354f4898c8c1e6ad97ca7112549e1d1a1eacb4682cd1bf8b762368b5905ab33dbdacb585b128514ca1","ports":{"listener":0,"discovery":0},"protocols":{"bzz":"eFH2cZa4Ev1sq31Xe5DiVMb56jMlnGC179kWVL2NtEw=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 7851f6\npopulation: 25 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 aca1 ddf8 e649 | 121 9390 (0) 9294 (0) 9232 (0) 96b6 (0)\n001 4 0210 2af0 2e4c 396b | 73 13d8 (0) 12b9 (0) 123f (0) 1673 (0)\n002 4 47f9 42c0 5c5d 5695 | 31 4b00 (0) 4a67 (0) 4af7 (0) 4a82 (0)\n003 5 604c 6610 6544 6d21 | 11 6330 (0) 6143 (0) 604c (0) 670d (0)\n004 1 72fa | 8 77ec (0) 759e (0) 7406 (0) 7471 (0)\n005 3 7fa4 7dc6 7d94 | 6 7ffe (0) 7fa4 (0) 7d45 (0) 7de7 (0)\n006 1 7a41 | 1 7a41 (0)\n007 2 79bd 79ab | 2 79ab (0) 79bd (0)\n008 0 | 0\n============ DEPTH: 9 ==========================================\n009 1 7829 | 1 7829 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 1 7854 | 1 7854 (0)\n014 0 | 0\n015 0 | 0\n========================================================================="},"ip":"0.0.0.0"}}},{"node":{"up":true,"config":{"id":"ef7157fdfe62390d8a6d4ef976478d17465b42b63fddb03664973d63efb62318a8f59e412150528a32aa2c028b9de6bc67f05e012b8c43d710032ad871bc27e5","private_key":"1a4a47a0b83da4f2ccd94ee24a3657f777cc93c6a58b8ec0145586ba2c161429","services":["pss","bzz"],"name":"node218"},"info":{"id":"ef7157fdfe62390d8a6d4ef976478d17465b42b63fddb03664973d63efb62318a8f59e412150528a32aa2c028b9de6bc67f05e012b8c43d710032ad871bc27e5","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 396b25\npopulation: 19 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 aca1 | 121 c3f3 (0) c0d1 (0) c15d (0) c484 (0)\n001 3 42c0 7a41 7851 | 62 4b00 (0) 4a67 (0) 4af7 (0) 4a82 (0)\n002 4 1566 1e44 1b1e 0210 | 38 13d8 (0) 123f (0) 12b9 (0) 1673 (0)\n003 4 2168 2af0 2f9f 2e4c | 20 275c (0) 265d (0) 259d (0) 2454 (0)\n004 1 34fc | 6 31ed (0) 32dd (0) 3345 (0) 3648 (0)\n005 3 3e44 3e85 3d6b | 5 3dca (0) 3d6b (0) 3f3e (0) 3e85 (0)\n============ DEPTH: 6 ==========================================\n006 2 3af3 3a4a | 2 3af3 (0) 3a4a (0)\n007 1 388d | 1 388d (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"OWslayI/NGpJCESJW58QRrR5DWJK8cQ+yuHeMYxyFKg="},"ip":"0.0.0.0","ports":{"listener":0,"discovery":0},"listenAddr":"","enode":"enode://ef7157fdfe62390d8a6d4ef976478d17465b42b63fddb03664973d63efb62318a8f59e412150528a32aa2c028b9de6bc67f05e012b8c43d710032ad871bc27e5@0.0.0.0:0","name":"node218"}}},{"node":{"info":{"id":"1edeb91789b9aa996fea7a70964e0be33ee50acbe6d8f7d9d9fcf6dcf755dab6402637a610116f0eb716b19259429bdcced8bebc28ffa334387a430efc21b9b0","protocols":{"bzz":"rKGgI3zO8Eu//0NZzxKUWIDkheqtgQ/hvC8lacxC/qM=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: aca1a0\npopulation: 22 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 396b 7851 7a41 | 135 13d8 (0) 12b9 (0) 123f (0) 1673 (0)\n001 4 ddf8 d564 f3d3 e649 | 65 c0d1 (0) c15d (0) c3f3 (0) c484 (0)\n002 3 99aa 99db 8874 | 26 9294 (0) 9232 (0) 9390 (0) 96b6 (0)\n003 2 be0a b710 | 14 baf3 (0) b8a7 (0) bc08 (0) bfec (0)\n004 2 a485 a033 | 4 a672 (0) a749 (0) a485 (0) a033 (0)\n005 2 aa88 a80b | 4 a80b (0) abfa (0) aa50 (0) aa88 (0)\n006 4 ae71 ae65 af5f af30 | 5 ae71 (0) ae65 (0) af5f (0) af35 (0)\n============ DEPTH: 7 ==========================================\n007 2 adfc ad36 | 2 adfc (0) ad36 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ip":"0.0.0.0","ports":{"listener":0,"discovery":0},"listenAddr":"","enode":"enode://1edeb91789b9aa996fea7a70964e0be33ee50acbe6d8f7d9d9fcf6dcf755dab6402637a610116f0eb716b19259429bdcced8bebc28ffa334387a430efc21b9b0@0.0.0.0:0","name":"node219"},"up":true,"config":{"name":"node219","services":["pss","bzz"],"private_key":"5b5aede47f05e99b807a7451cec469c1f77786d45d9f55b5a797b82d76db93af","id":"1edeb91789b9aa996fea7a70964e0be33ee50acbe6d8f7d9d9fcf6dcf755dab6402637a610116f0eb716b19259429bdcced8bebc28ffa334387a430efc21b9b0"}}},{"node":{"info":{"protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 7a4118\npopulation: 19 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 aca1 | 121 ceee (0) c9f3 (0) c99c (0) c98d (0)\n001 3 2e4c 396b 0210 | 73 13d8 (0) 12b9 (0) 123f (0) 1673 (0)\n002 3 4a81 42c0 5695 | 31 4fd6 (0) 4f90 (0) 4cf6 (0) 4d44 (0)\n003 3 6544 6d21 6dbd | 11 6330 (0) 6143 (0) 604c (0) 670d (0)\n004 1 72fa | 8 77ec (0) 759e (0) 7406 (0) 7471 (0)\n005 3 7de7 7dc6 7d94 | 6 7ffe (0) 7fa4 (0) 7d45 (0) 7de7 (0)\n============ DEPTH: 6 ==========================================\n006 5 79ab 79bd 7829 7854 | 5 79ab (0) 79bd (0) 7829 (0) 7854 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"ekEY0s4W6CWMws3zHFiRlF43h8RsCDb8kWYBWEYJt9s="},"ports":{"discovery":0,"listener":0},"ip":"0.0.0.0","id":"222d7a2f94dc82a09fda70b8195fc3a60433a90f53998872318c57625c528c90572d78b444ac4901dcfece1a03ef8b6cbe7845366a845a942f341f6db58a9b3b","name":"node220","enode":"enode://222d7a2f94dc82a09fda70b8195fc3a60433a90f53998872318c57625c528c90572d78b444ac4901dcfece1a03ef8b6cbe7845366a845a942f341f6db58a9b3b@0.0.0.0:0","listenAddr":""},"up":true,"config":{"name":"node220","services":["pss","bzz"],"private_key":"96ada7ff2fc583b6dd41941edfff92a81778c698d3b1f9fbf4130c2f7cbbec84","id":"222d7a2f94dc82a09fda70b8195fc3a60433a90f53998872318c57625c528c90572d78b444ac4901dcfece1a03ef8b6cbe7845366a845a942f341f6db58a9b3b"}}},{"node":{"info":{"ip":"0.0.0.0","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 021014\npopulation: 21 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 5 d7ab d564 ddf8 8874 | 121 b310 (0) b4c7 (0) b463 (0) b45d (0)\n001 4 5695 42c0 7851 7a41 | 62 4fd6 (0) 4f90 (0) 4cf6 (0) 4d44 (0)\n002 3 3a4a 396b 2e4c | 35 31ed (0) 32dd (0) 3345 (0) 34fc (0)\n003 2 1e44 1b1e | 26 123f (0) 12b9 (0) 13d8 (0) 1673 (0)\n004 3 0eee 0ea2 0f81 | 4 0eee (0) 0ea2 (0) 0f5e (0) 0f81 (0)\n005 2 043f 0592 | 5 06aa (0) 043f (0) 05ec (0) 05e8 (0)\n============ DEPTH: 6 ==========================================\n006 1 004e | 1 004e (0)\n007 1 03f5 | 1 03f5 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"AhAUbmUBMt0M64zqd5yvxUhYIu7rn8wX8pKvXO9uljI="},"ports":{"listener":0,"discovery":0},"id":"3948a7a939b9a1f4201953bd9b955ee7be87d09b63c7a45167f556ac06fe3c4c2a75d935bff50668da5e71e46802b55d7a9945a92d7807c00625d129cbb48f82","enode":"enode://3948a7a939b9a1f4201953bd9b955ee7be87d09b63c7a45167f556ac06fe3c4c2a75d935bff50668da5e71e46802b55d7a9945a92d7807c00625d129cbb48f82@0.0.0.0:0","name":"node221","listenAddr":""},"config":{"private_key":"1616cc42cae550c0104204c1c7f6ed0b3f65da627bd834a2d1239d70cc5b1e77","id":"3948a7a939b9a1f4201953bd9b955ee7be87d09b63c7a45167f556ac06fe3c4c2a75d935bff50668da5e71e46802b55d7a9945a92d7807c00625d129cbb48f82","name":"node221","services":["pss","bzz"]},"up":true}},{"node":{"info":{"protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 1b1eca\npopulation: 21 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 d564 ddf8 8874 | 121 a033 (0) a749 (0) a672 (0) a485 (0)\n001 2 6dbd 5695 | 62 487e (0) 4b00 (0) 4af7 (0) 4a81 (0)\n002 3 2af0 2168 396b | 35 3648 (0) 34fc (0) 3538 (0) 31ed (0)\n003 1 0210 | 12 0f5e (0) 0f81 (0) 0eee (0) 0ea2 (0)\n004 3 123f 1441 1566 | 8 123f (0) 12b9 (0) 13d8 (0) 1673 (0)\n005 2 1d5f 1e44 | 8 1c98 (0) 1d5f (0) 1d07 (0) 1da3 (0)\n006 3 194a 193e 1835 | 5 193e (0) 194a (0) 18f9 (0) 185a (0)\n007 2 1a02 1a83 | 2 1a02 (0) 1a83 (0)\n============ DEPTH: 8 ==========================================\n008 1 1b86 | 1 1b86 (0)\n009 1 1b72 | 1 1b72 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"Gx7KezUIbYshdDHB1qAfwH3IvIFhlqgAFcnhY77Wdv8="},"ports":{"discovery":0,"listener":0},"ip":"0.0.0.0","id":"dd6acfd151220f21b03701ca554a5e134dbd1154dda21d9eec45809e7858fe83eca3953fc688f499030198f22052c3681a9f49207ef9b11a760456ab9637352b","name":"node222","enode":"enode://dd6acfd151220f21b03701ca554a5e134dbd1154dda21d9eec45809e7858fe83eca3953fc688f499030198f22052c3681a9f49207ef9b11a760456ab9637352b@0.0.0.0:0","listenAddr":""},"up":true,"config":{"name":"node222","services":["pss","bzz"],"private_key":"1d029cbabb2eaef44889598c8fa2297996a69661d29c14035424dce781deb15e","id":"dd6acfd151220f21b03701ca554a5e134dbd1154dda21d9eec45809e7858fe83eca3953fc688f499030198f22052c3681a9f49207ef9b11a760456ab9637352b"}}},{"node":{"up":true,"config":{"private_key":"83c0403796648d484818f74b9de3c755c56b24f69e3394e062dd55a9d7cecbc3","id":"2751df9f64a8f2ff8ea45efc9bd02b281d963ced285260bcda7f9dfaed998fe4386fe65a7265876da6b4fee77ea5c12454869a70ad627da7ca888076fc629665","name":"node223","services":["pss","bzz"]},"info":{"name":"node223","enode":"enode://2751df9f64a8f2ff8ea45efc9bd02b281d963ced285260bcda7f9dfaed998fe4386fe65a7265876da6b4fee77ea5c12454869a70ad627da7ca888076fc629665@0.0.0.0:0","listenAddr":"","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 1e4441\npopulation: 18 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 8874 | 121 a033 (0) a749 (0) a672 (0) a485 (0)\n001 1 6dbd | 62 4f90 (0) 4fd6 (0) 4cf6 (0) 4d44 (0)\n002 2 396b 2e4c | 35 34fc (0) 3538 (0) 3648 (0) 31ed (0)\n003 1 0210 | 12 0f5e (0) 0f81 (0) 0eee (0) 0ea2 (0)\n004 1 1566 | 8 123f (0) 12b9 (0) 13d8 (0) 1673 (0)\n005 5 185a 1835 194a 1b72 | 10 193e (0) 194a (0) 18f9 (0) 185a (0)\n============ DEPTH: 6 ==========================================\n006 6 1d5f 1d07 1da3 1d93 | 6 1c98 (0) 1d5f (0) 1d07 (0) 1da3 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 1 1e42 | 1 1e42 (0)\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"HkRBMJQEsN2N2eix/nhwiwFaCwJ4zoa82qvH0taReRo="},"ports":{"discovery":0,"listener":0},"ip":"0.0.0.0","id":"2751df9f64a8f2ff8ea45efc9bd02b281d963ced285260bcda7f9dfaed998fe4386fe65a7265876da6b4fee77ea5c12454869a70ad627da7ca888076fc629665"}}},{"node":{"up":true,"config":{"id":"bc0df855bdadcde3e447415444f655eb430925a8fa81cdcac75909e7d79750f01827938570e75e388cc7058ba8ebca47afadf8b07172bc078488fb618ba71024","private_key":"3f64513ae7746b16fa9ef3978d1bdf3c87ab4842c75aa3b946385dcdb23a3430","services":["pss","bzz"],"name":"node224"},"info":{"listenAddr":"","name":"node224","enode":"enode://bc0df855bdadcde3e447415444f655eb430925a8fa81cdcac75909e7d79750f01827938570e75e388cc7058ba8ebca47afadf8b07172bc078488fb618ba71024@0.0.0.0:0","id":"bc0df855bdadcde3e447415444f655eb430925a8fa81cdcac75909e7d79750f01827938570e75e388cc7058ba8ebca47afadf8b07172bc078488fb618ba71024","ports":{"listener":0,"discovery":0},"protocols":{"bzz":"iHSCiQsZBQW+xJg45ADz8eyyYQOaznC9YMNovpQTHuM=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 887482\npopulation: 26 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 0210 1b1e 1e44 6dbd | 135 31ed (0) 32dd (0) 3345 (0) 3648 (0)\n001 4 d7ab f5cc f3d3 e787 | 65 fed1 (0) fd2d (0) fb93 (0) fa74 (0)\n002 2 aca1 b710 | 30 a672 (0) a749 (0) a485 (0) a033 (0)\n003 7 9390 96b6 95e0 9461 | 16 9390 (0) 9294 (0) 9232 (0) 96b6 (0)\n004 3 8163 8612 86f7 | 3 8163 (0) 8612 (0) 86f7 (0)\n005 2 8c89 8c61 | 2 8c89 (0) 8c61 (0)\n006 2 8ac8 8ae6 | 2 8ac8 (0) 8ae6 (0)\n============ DEPTH: 7 ==========================================\n007 1 89ee | 1 89ee (0)\n008 1 88da | 1 88da (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ip":"0.0.0.0"}}},{"node":{"up":true,"config":{"name":"node225","services":["pss","bzz"],"private_key":"a9db544f2fa00dc2d658a531934db6efeec93208b76d5b6859e6f0c4abac116d","id":"884d32d09dfef937f3ef1cd6fb5f530c2c574487c0ffd4185ca405c8b2ac73044a196c34352e850ce15321eec6579da654a696381f3e5830d03c7aa18923da6e"},"info":{"listenAddr":"","enode":"enode://884d32d09dfef937f3ef1cd6fb5f530c2c574487c0ffd4185ca405c8b2ac73044a196c34352e850ce15321eec6579da654a696381f3e5830d03c7aa18923da6e@0.0.0.0:0","name":"node225","id":"884d32d09dfef937f3ef1cd6fb5f530c2c574487c0ffd4185ca405c8b2ac73044a196c34352e850ce15321eec6579da654a696381f3e5830d03c7aa18923da6e","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 6dbd2d\npopulation: 23 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 8 f5cc c8fe c98d de82 | 121 fd2d (0) fed1 (0) fb93 (0) fa74 (0)\n001 4 2e4c 1566 1b1e 1e44 | 73 34fc (0) 3538 (0) 3648 (0) 31ed (0)\n002 2 42c0 5695 | 31 4fd6 (0) 4f90 (0) 4cf6 (0) 4d44 (0)\n003 2 7a41 7851 | 20 77ec (0) 759e (0) 7406 (0) 7471 (0)\n004 5 604c 6143 6610 67a2 | 8 6330 (0) 604c (0) 6143 (0) 670d (0)\n005 0 | 0\n============ DEPTH: 6 ==========================================\n006 1 6ea5 | 1 6ea5 (0)\n007 0 | 0\n008 1 6d21 | 1 6d21 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"bb0t2PEa3r+9PsQSieNeSokw2hvvUhKxUt7tioqy8bw="},"ports":{"discovery":0,"listener":0},"ip":"0.0.0.0"}}},{"node":{"info":{"ip":"0.0.0.0","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: b71052\npopulation: 20 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 3dca 6dbd | 135 0f5e (0) 0f81 (0) 0eee (0) 0ea2 (0)\n001 3 dc86 c98d c8fe | 65 fd2d (0) fed1 (0) fb93 (0) fa74 (0)\n002 2 8874 9a82 | 26 8163 (0) 8612 (0) 86f7 (0) 8c89 (0)\n003 3 aca1 ae65 af30 | 16 a672 (0) a749 (0) a485 (0) a033 (0)\n004 3 b8a7 be0a bc08 | 6 baf3 (0) b8a7 (0) bfec (0) bf5a (0)\n005 1 b310 | 1 b310 (0)\n006 4 b5c7 b4c7 b45d b463 | 4 b5c7 (0) b4c7 (0) b45d (0) b463 (0)\n============ DEPTH: 7 ==========================================\n007 1 b60d | 1 b60d (0)\n008 1 b79f | 1 b79f (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"txBSsHLLmPt5FR/QxgRIKOU1oFR8rOkxGDx+Tn8idpg="},"ports":{"discovery":0,"listener":0},"id":"2880e0defd1bf2665bdd20dfb46bc0a9ad707f495211fc78e611ab479d78398db7daff7d3f4b6bf81fd13bf766ecc8271e0ea99a2d74abd2f9ddf98835ffdcf1","name":"node226","enode":"enode://2880e0defd1bf2665bdd20dfb46bc0a9ad707f495211fc78e611ab479d78398db7daff7d3f4b6bf81fd13bf766ecc8271e0ea99a2d74abd2f9ddf98835ffdcf1@0.0.0.0:0","listenAddr":""},"up":true,"config":{"private_key":"d53b2fef355d63448b93647458df0ba5b73bc42492d376377401a568eeb4d81f","id":"2880e0defd1bf2665bdd20dfb46bc0a9ad707f495211fc78e611ab479d78398db7daff7d3f4b6bf81fd13bf766ecc8271e0ea99a2d74abd2f9ddf98835ffdcf1","name":"node226","services":["pss","bzz"]}}},{"node":{"info":{"enode":"enode://4b332b389f1142c0da42aaeb2e2692081d0002de0eb6741b3269e898a8101571d4556b755f2e8841e7a607bb41e398d2b0577fbe71098e7097f0fe6c720e1526@0.0.0.0:0","name":"node227","listenAddr":"","ports":{"listener":0,"discovery":0},"protocols":{"bzz":"yP5ibGDWzRWRKiLSxYcvEKj4rvW29rLxBw7exmcL+LE=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: c8fe62\npopulation: 21 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 5695 6dbd 2e4c 1566 | 135 06aa (0) 043f (0) 05ec (0) 05e8 (0)\n001 2 bc08 b710 | 56 8163 (0) 8612 (0) 86f7 (0) 8c89 (0)\n002 2 f048 e787 | 29 e839 (0) ecd2 (0) edca (0) ed65 (0)\n003 4 d3fd d8b0 de82 dc86 | 18 d3d2 (0) d3fd (0) d564 (0) d68f (0)\n004 1 c770 | 9 c3f3 (0) c0d1 (0) c15d (0) c484 (0)\n005 1 ceee | 1 ceee (0)\n006 2 cb69 ca81 | 2 cb69 (0) ca81 (0)\n007 3 c9f3 c99c c98d | 3 c9f3 (0) c99c (0) c98d (0)\n008 0 | 0\n============ DEPTH: 9 ==========================================\n009 1 c883 | 1 c883 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 1 c8f9 | 1 c8f9 (0)\n014 0 | 0\n015 0 | 0\n========================================================================="},"ip":"0.0.0.0","id":"4b332b389f1142c0da42aaeb2e2692081d0002de0eb6741b3269e898a8101571d4556b755f2e8841e7a607bb41e398d2b0577fbe71098e7097f0fe6c720e1526"},"up":true,"config":{"private_key":"a04acf8d5198d0e7da1a6e9228c8ac6a74542a8d91906d5e83f1db219ae25350","id":"4b332b389f1142c0da42aaeb2e2692081d0002de0eb6741b3269e898a8101571d4556b755f2e8841e7a607bb41e398d2b0577fbe71098e7097f0fe6c720e1526","name":"node227","services":["pss","bzz"]}}},{"node":{"config":{"services":["pss","bzz"],"name":"node228","id":"0c82c4b414375479375703ed9c19fb08c8143229ed4f1dcf448c6cf313810c098905123bec17969276936ae0cc39ed251b2811dbffb551d61159862b0eac0a23","private_key":"d5ad27697670f66cacf3e0ffb4473ab4912ed96fba311ddc8af12ad7663adeda"},"up":true,"info":{"listenAddr":"","enode":"enode://0c82c4b414375479375703ed9c19fb08c8143229ed4f1dcf448c6cf313810c098905123bec17969276936ae0cc39ed251b2811dbffb551d61159862b0eac0a23@0.0.0.0:0","name":"node228","id":"0c82c4b414375479375703ed9c19fb08c8143229ed4f1dcf448c6cf313810c098905123bec17969276936ae0cc39ed251b2811dbffb551d61159862b0eac0a23","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: dc86cf\npopulation: 24 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 1566 6dbd | 135 275c (0) 265d (0) 2454 (0) 259d (0)\n001 4 b463 b710 af30 9a82 | 56 a672 (0) a749 (0) a485 (0) a033 (0)\n002 2 f5cc f048 | 29 e839 (0) ecd2 (0) edca (0) ed65 (0)\n003 5 c463 c770 ca81 c98d | 18 c3f3 (0) c0d1 (0) c15d (0) c484 (0)\n004 2 d564 d7ab | 7 d3d2 (0) d3fd (0) d564 (0) d68f (0)\n005 3 daa2 d822 d8b0 | 4 dae3 (0) daa2 (0) d822 (0) d8b0 (0)\n006 4 df25 df5e def4 de82 | 4 df25 (0) df5e (0) def4 (0) de82 (0)\n============ DEPTH: 7 ==========================================\n007 1 ddf8 | 1 ddf8 (0)\n008 1 dc3e | 1 dc3e (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"3IbPkqlkBxJFWCT8fh6ruTn2A3DRvo//VVhsSqqLMzE="},"ports":{"listener":0,"discovery":0},"ip":"0.0.0.0"}}},{"node":{"config":{"private_key":"dd217caf701902c94b57e1eeccbeaeddc4a7837b56d82ae2f034935d2828d222","id":"877d17ec7e95998ead831606d3363fbff1c8d1fa377b8e621e6a876d2c7776b9af356211a7e4df66adeaf38cf9b49c04871e8804edde4c18435ff45e110ecb04","name":"node229","services":["pss","bzz"]},"up":true,"info":{"enode":"enode://877d17ec7e95998ead831606d3363fbff1c8d1fa377b8e621e6a876d2c7776b9af356211a7e4df66adeaf38cf9b49c04871e8804edde4c18435ff45e110ecb04@0.0.0.0:0","name":"node229","listenAddr":"","ports":{"discovery":0,"listener":0},"protocols":{"bzz":"moLSKynIjqyi8gpi6eY2dZBAZecscM4vu+/AydLlPpA=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 9a82d2\npopulation: 19 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 6dbd | 135 3648 (0) 3538 (0) 34fc (0) 31ed (0)\n001 3 f5cc de82 dc86 | 65 e839 (0) ecd2 (0) edca (0) ed65 (0)\n002 5 a033 af30 bc08 b463 | 30 a672 (0) a749 (0) a485 (0) a033 (0)\n003 2 8ae6 8874 | 10 8163 (0) 8612 (0) 86f7 (0) 8c89 (0)\n004 3 95e0 9461 96b6 | 7 9390 (0) 9294 (0) 9232 (0) 95e0 (0)\n005 1 9eec | 4 9c0c (0) 9c01 (0) 9fee (0) 9eec (0)\n============ DEPTH: 6 ==========================================\n006 4 985c 99db 99fb 99aa | 4 985c (0) 99fb (0) 99db (0) 99aa (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ip":"0.0.0.0","id":"877d17ec7e95998ead831606d3363fbff1c8d1fa377b8e621e6a876d2c7776b9af356211a7e4df66adeaf38cf9b49c04871e8804edde4c18435ff45e110ecb04"}}},{"node":{"config":{"id":"a8fac88fba179fb9b259d94caac9cbe45d873a0131bef8844ac4383b177daf6f301f8793623fec5876885db1a91e5b3e98e2aafdaa47e03b1f6d9740f48af7ac","private_key":"69b9f99ba6c47542a17c63be200102194fe3ab24084ea1e684033e68d580b5af","services":["pss","bzz"],"name":"node230"},"up":true,"info":{"ip":"0.0.0.0","protocols":{"bzz":"9cx2pad9ebj509wutTr19kNYOqk5KzYaqVeM2tgf1KU=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: f5cc76\npopulation: 25 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 1566 6dbd | 135 3648 (0) 3538 (0) 34fc (0) 31ed (0)\n001 5 a033 af30 8874 96b6 | 56 a672 (0) a749 (0) a485 (0) a033 (0)\n002 5 daa2 dc86 de82 c770 | 36 d3d2 (0) d3fd (0) d564 (0) d68f (0)\n003 3 ed13 e649 e787 | 12 e839 (0) ecd2 (0) edca (0) ed65 (0)\n004 1 f915 | 6 fd2d (0) fed1 (0) fb93 (0) fa74 (0)\n005 4 f3d3 f156 f0e2 f048 | 5 f3d3 (0) f1fc (0) f156 (0) f0e2 (0)\n006 2 f644 f78a | 2 f644 (0) f78a (0)\n============ DEPTH: 7 ==========================================\n007 2 f4e0 f4ee | 2 f4e0 (0) f4ee (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 1 f5dd | 1 f5dd (0)\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"listener":0,"discovery":0},"id":"a8fac88fba179fb9b259d94caac9cbe45d873a0131bef8844ac4383b177daf6f301f8793623fec5876885db1a91e5b3e98e2aafdaa47e03b1f6d9740f48af7ac","enode":"enode://a8fac88fba179fb9b259d94caac9cbe45d873a0131bef8844ac4383b177daf6f301f8793623fec5876885db1a91e5b3e98e2aafdaa47e03b1f6d9740f48af7ac@0.0.0.0:0","name":"node230","listenAddr":""}}},{"node":{"up":true,"config":{"id":"2bea7540c99456ea889a8ba2e448c11e6257bf987d01f13eea48128ba58577ab0936855035ee140c9907e382a34ca85a179c74892cbd9eb92fc2b35601addc6b","private_key":"ead9e2c8c0b3993304cb0a4a0dcb3ebe7c4331a87fee7c70194a3b3690413f43","services":["pss","bzz"],"name":"node231"},"info":{"id":"2bea7540c99456ea889a8ba2e448c11e6257bf987d01f13eea48128ba58577ab0936855035ee140c9907e382a34ca85a179c74892cbd9eb92fc2b35601addc6b","protocols":{"bzz":"54f9NbQ42649AoP3GB/Er7628zMgGtTNG0a/cJSmqF8=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: e787fd\npopulation: 19 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 03f5 2a69 2013 | 135 3345 (0) 32dd (0) 31ed (0) 3538 (0)\n001 1 8874 | 56 8163 (0) 8612 (0) 86f7 (0) 8c61 (0)\n002 5 d8b0 c770 ca81 c8fe | 36 d3d2 (0) d3fd (0) d564 (0) d68f (0)\n003 3 f048 f3d3 f5cc | 17 fd2d (0) fed1 (0) fb93 (0) fa74 (0)\n004 1 ed13 | 5 e839 (0) ecd2 (0) edca (0) ed65 (0)\n005 1 e3c9 | 1 e3c9 (0)\n006 2 e4c3 e44b | 2 e4c3 (0) e44b (0)\n============ DEPTH: 7 ==========================================\n007 2 e649 e67d | 2 e67d (0) e649 (0)\n008 1 e76a | 1 e76a (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"listener":0,"discovery":0},"ip":"0.0.0.0","listenAddr":"","name":"node231","enode":"enode://2bea7540c99456ea889a8ba2e448c11e6257bf987d01f13eea48128ba58577ab0936855035ee140c9907e382a34ca85a179c74892cbd9eb92fc2b35601addc6b@0.0.0.0:0"}}},{"node":{"up":true,"config":{"services":["pss","bzz"],"name":"node232","id":"be93fafaf43f6bb3efd2667d1468a8636cb752b245328eaa01468c0606d790322a7cd8e47857068e60118e28b8dd8aa1d2d4977c5b3d28d4b47f4c0658f05e90","private_key":"96cf35a39c0753abb6cc71c2a23e92fc936169a0600e936611216fd8ec31e310"},"info":{"listenAddr":"","name":"node232","enode":"enode://be93fafaf43f6bb3efd2667d1468a8636cb752b245328eaa01468c0606d790322a7cd8e47857068e60118e28b8dd8aa1d2d4977c5b3d28d4b47f4c0658f05e90@0.0.0.0:0","id":"be93fafaf43f6bb3efd2667d1468a8636cb752b245328eaa01468c0606d790322a7cd8e47857068e60118e28b8dd8aa1d2d4977c5b3d28d4b47f4c0658f05e90","ip":"0.0.0.0","protocols":{"bzz":"yY04mm2ObrWh61pvI1hX1dk50w5RwW2AwDnJ4Osvfso=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: c98d38\npopulation: 15 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 6dbd | 135 31ed (0) 32dd (0) 3345 (0) 34fc (0)\n001 2 b710 bc08 | 56 8163 (0) 8612 (0) 86f7 (0) 8c89 (0)\n002 2 f5cc e787 | 29 fd2d (0) fed1 (0) fb93 (0) fa74 (0)\n003 2 dc86 de82 | 18 d3d2 (0) d3fd (0) d564 (0) d68f (0)\n004 1 c770 | 9 c3f3 (0) c0d1 (0) c15d (0) c463 (0)\n005 1 ceee | 1 ceee (0)\n006 2 cb69 ca81 | 2 cb69 (0) ca81 (0)\n007 2 c8f9 c8fe | 3 c883 (0) c8f9 (0) c8fe (0)\n008 0 | 0\n============ DEPTH: 9 ==========================================\n009 1 c9f3 | 1 c9f3 (0)\n010 0 | 0\n011 1 c99c | 1 c99c (0)\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"listener":0,"discovery":0}}}},{"node":{"info":{"protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: bc08af\npopulation: 18 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 1566 | 135 32dd (0) 3345 (0) 31ed (0) 34fc (0)\n001 4 c770 ca81 c8fe c98d | 65 e839 (0) ecd2 (0) edca (0) ed65 (0)\n002 2 8ae6 9a82 | 26 8163 (0) 8612 (0) 86f7 (0) 8c89 (0)\n003 1 af30 | 16 a672 (0) a749 (0) a485 (0) a033 (0)\n004 5 b310 b5c7 b45d b463 | 8 b310 (0) b5c7 (0) b4c7 (0) b45d (0)\n005 2 baf3 b8a7 | 2 baf3 (0) b8a7 (0)\n============ DEPTH: 6 ==========================================\n006 3 be0a bfec bf5a | 3 be0a (0) bfec (0) bf5a (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"vAivKEq2YdzByyOFknFZDlCgn/ivgHN2nIEpAeoLkIA="},"ports":{"listener":0,"discovery":0},"ip":"0.0.0.0","id":"81dc656de121016bcde81d5bf7919839acfc180dfbf1a6de2cadf704ff13af98aa5715a4168832ca6f651b2ea7ad9e6ca5f1c1cb7e885dbc2eb23d4aefb87bd6","name":"node233","enode":"enode://81dc656de121016bcde81d5bf7919839acfc180dfbf1a6de2cadf704ff13af98aa5715a4168832ca6f651b2ea7ad9e6ca5f1c1cb7e885dbc2eb23d4aefb87bd6@0.0.0.0:0","listenAddr":""},"up":true,"config":{"services":["pss","bzz"],"name":"node233","id":"81dc656de121016bcde81d5bf7919839acfc180dfbf1a6de2cadf704ff13af98aa5715a4168832ca6f651b2ea7ad9e6ca5f1c1cb7e885dbc2eb23d4aefb87bd6","private_key":"12ecde7517662f6d425f22ce7ecde84688ab9ed7fd443de2f309f095857faca9"}}},{"node":{"info":{"name":"node234","enode":"enode://d3cd2f34f67830ccdc295b7537a6d27c02b44503808ca666124f52ecc3d6c35b7d3f14343997006aef2cfbefc8d27809d389477e99c236b9f8a897a4bc406a43@0.0.0.0:0","listenAddr":"","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: c7703c\npopulation: 20 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 1566 | 135 7d45 (0) 7d94 (0) 7dc6 (0) 7de7 (0)\n001 3 af30 b463 bc08 | 56 8163 (0) 8612 (0) 86f7 (0) 8c89 (0)\n002 3 f048 f5cc e787 | 29 e839 (0) ecd2 (0) edca (0) ed65 (0)\n003 3 d8b0 dc86 de82 | 18 d3d2 (0) d3fd (0) d564 (0) d68f (0)\n004 4 c8fe c98d cb69 ca81 | 9 ceee (0) c9f3 (0) c99c (0) c98d (0)\n005 1 c15d | 3 c3f3 (0) c0d1 (0) c15d (0)\n006 2 c463 c484 | 2 c463 (0) c484 (0)\n============ DEPTH: 7 ==========================================\n007 2 c63e c64f | 2 c63e (0) c64f (0)\n008 0 | 0\n009 1 c723 | 1 c723 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"x3A8Rpdjf0ClCl0LZWxOVAEO8Sd7ZNJRzNB1JRLiRuk="},"ip":"0.0.0.0","ports":{"listener":0,"discovery":0},"id":"d3cd2f34f67830ccdc295b7537a6d27c02b44503808ca666124f52ecc3d6c35b7d3f14343997006aef2cfbefc8d27809d389477e99c236b9f8a897a4bc406a43"},"up":true,"config":{"services":["pss","bzz"],"name":"node234","id":"d3cd2f34f67830ccdc295b7537a6d27c02b44503808ca666124f52ecc3d6c35b7d3f14343997006aef2cfbefc8d27809d389477e99c236b9f8a897a4bc406a43","private_key":"bc558cb24210cea0443678c5a9a412b3512b5b965b14df80818039b6fe28fe06"}}},{"node":{"info":{"ip":"0.0.0.0","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: de827c\npopulation: 24 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 6dbd 1566 | 135 4cf6 (0) 4d44 (0) 4f90 (0) 4fd6 (0)\n001 3 b463 af30 9a82 | 56 8163 (0) 8612 (0) 86f7 (0) 8c89 (0)\n002 2 f048 f5cc | 29 e839 (0) ecd2 (0) edca (0) ed65 (0)\n003 5 c98d c8fe ca81 c463 | 18 ceee (0) c9f3 (0) c99c (0) c98d (0)\n004 3 d3fd d7ab d564 | 7 d3d2 (0) d3fd (0) d564 (0) d68f (0)\n005 3 dae3 daa2 d8b0 | 4 dae3 (0) daa2 (0) d822 (0) d8b0 (0)\n006 3 ddf8 dc3e dc86 | 3 ddf8 (0) dc3e (0) dc86 (0)\n============ DEPTH: 7 ==========================================\n007 2 df25 df5e | 2 df25 (0) df5e (0)\n008 0 | 0\n009 1 def4 | 1 def4 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"3oJ8avHTQj+mC/UMpuEhctIan8OaY2DigE+DADcQtTQ="},"ports":{"discovery":0,"listener":0},"id":"d43bd6d3ae39a04e4e144a8a6f80b2d54472b5b9b6491dccf44b1716a63d24c56e3a871b3b8fe983d992988dc07ace06736ead3b1287914b629fcfe17e81f36f","name":"node235","enode":"enode://d43bd6d3ae39a04e4e144a8a6f80b2d54472b5b9b6491dccf44b1716a63d24c56e3a871b3b8fe983d992988dc07ace06736ead3b1287914b629fcfe17e81f36f@0.0.0.0:0","listenAddr":""},"config":{"name":"node235","services":["pss","bzz"],"private_key":"1f2ab03e6921c321f5f783a3105d69bb69a4c031d50195fb94324c3280d52310","id":"d43bd6d3ae39a04e4e144a8a6f80b2d54472b5b9b6491dccf44b1716a63d24c56e3a871b3b8fe983d992988dc07ace06736ead3b1287914b629fcfe17e81f36f"},"up":true}},{"node":{"info":{"enode":"enode://95ff4dea07303e1ba641a5c510e714ef232f4dbce9ad2e8b2f62644975eae41fc4bb9d1af3fae4d5ea4daeb18f8248e0b3131c7d843d35d33f3afbf7dfa4c2fe@0.0.0.0:0","name":"node236","listenAddr":"","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: ca81f5\npopulation: 22 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 194a 1566 | 135 7ffe (0) 7fa4 (0) 7d45 (0) 7d94 (0)\n001 4 96b6 a033 bc08 b463 | 56 8163 (0) 8612 (0) 86f7 (0) 8c89 (0)\n002 2 e787 f048 | 29 e839 (0) ecd2 (0) edca (0) ed65 (0)\n003 4 daa2 d8b0 dc86 de82 | 18 d3d2 (0) d3fd (0) d564 (0) d68f (0)\n004 2 c463 c770 | 9 c3f3 (0) c0d1 (0) c15d (0) c463 (0)\n005 1 ceee | 1 ceee (0)\n============ DEPTH: 6 ==========================================\n006 6 c883 c8f9 c8fe c9f3 | 6 c9f3 (0) c99c (0) c98d (0) c883 (0)\n007 1 cb69 | 1 cb69 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"yoH1C1tJIe9/WElyYJ4XdNoSQjPr3gv48sqDgwF8ihM="},"ports":{"discovery":0,"listener":0},"ip":"0.0.0.0","id":"95ff4dea07303e1ba641a5c510e714ef232f4dbce9ad2e8b2f62644975eae41fc4bb9d1af3fae4d5ea4daeb18f8248e0b3131c7d843d35d33f3afbf7dfa4c2fe"},"up":true,"config":{"services":["pss","bzz"],"name":"node236","id":"95ff4dea07303e1ba641a5c510e714ef232f4dbce9ad2e8b2f62644975eae41fc4bb9d1af3fae4d5ea4daeb18f8248e0b3131c7d843d35d33f3afbf7dfa4c2fe","private_key":"8f1333ea7bd671c671ba94c4c7c59d6b0687a5c475b21712c6a49600e71f78b5"}}},{"node":{"config":{"private_key":"e7fceaf57233e8a351a5a97e433d38131867965c883d53430f8f635f0563a168","id":"b18c7131a319db61ab84d06e90092d93c91141e9a270630af9c3ab1eaf3bcad09f4d20a1fc845b21c994bf4d9e337d0bd756a75e2198097540355e7ebbb531b2","name":"node237","services":["pss","bzz"]},"up":true,"info":{"ports":{"listener":0,"discovery":0},"protocols":{"bzz":"tGOXUdZ9sLMq0YRplv7Q1cWb52t3767F9m5k3zXu+ug=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: b46397\npopulation: 17 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 1566 | 135 458a (0) 46c5 (0) 47f9 (0) 4019 (0)\n001 5 d8b0 dc86 de82 c770 | 65 e839 (0) ecd2 (0) edca (0) ed65 (0)\n002 1 9a82 | 26 8163 (0) 8612 (0) 86f7 (0) 8c89 (0)\n003 2 a485 af30 | 16 a672 (0) a749 (0) a485 (0) a033 (0)\n004 2 b8a7 bc08 | 6 baf3 (0) b8a7 (0) be0a (0) bfec (0)\n005 1 b310 | 1 b310 (0)\n006 2 b60d b710 | 3 b60d (0) b79f (0) b710 (0)\n007 1 b5c7 | 1 b5c7 (0)\n============ DEPTH: 8 ==========================================\n008 1 b4c7 | 1 b4c7 (0)\n009 0 | 0\n010 1 b45d | 1 b45d (0)\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ip":"0.0.0.0","id":"b18c7131a319db61ab84d06e90092d93c91141e9a270630af9c3ab1eaf3bcad09f4d20a1fc845b21c994bf4d9e337d0bd756a75e2198097540355e7ebbb531b2","name":"node237","enode":"enode://b18c7131a319db61ab84d06e90092d93c91141e9a270630af9c3ab1eaf3bcad09f4d20a1fc845b21c994bf4d9e337d0bd756a75e2198097540355e7ebbb531b2@0.0.0.0:0","listenAddr":""}}},{"node":{"info":{"enode":"enode://06aab75fed9a03f5525e3f1d8f8997fefaefd5b16e8f485d571beda00b1741efbb61a8a74fa12c2f6de66227c3fabb4d411659cd9c7b1ef32e171e6bf517cc39@0.0.0.0:0","name":"node238","listenAddr":"","protocols":{"bzz":"FWbjyOKHPS++Dx6e7b0svVxpFhpGHjekj9+xHUSGAeg=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 1566e3\npopulation: 28 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 10 bc08 b463 f5cc f048 | 121 9390 (0) 9232 (0) 9294 (0) 95e0 (0)\n001 2 5fd0 6dbd | 62 77ec (0) 759e (0) 7406 (0) 7471 (0)\n002 4 396b 3dca 259d 2374 | 35 32dd (0) 3345 (0) 31ed (0) 3648 (0)\n003 3 0f81 0592 03f5 | 12 06aa (0) 043f (0) 05e8 (0) 05ec (0)\n004 4 1e44 1b1e 1835 194a | 18 1c98 (0) 1d5f (0) 1d07 (0) 1da3 (0)\n005 1 12b9 | 3 13d8 (0) 123f (0) 12b9 (0)\n006 1 1673 | 1 1673 (0)\n============ DEPTH: 7 ==========================================\n007 2 1441 14c8 | 2 1441 (0) 14c8 (0)\n008 1 15f6 | 1 15f6 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ip":"0.0.0.0","ports":{"listener":0,"discovery":0},"id":"06aab75fed9a03f5525e3f1d8f8997fefaefd5b16e8f485d571beda00b1741efbb61a8a74fa12c2f6de66227c3fabb4d411659cd9c7b1ef32e171e6bf517cc39"},"config":{"services":["pss","bzz"],"name":"node238","id":"06aab75fed9a03f5525e3f1d8f8997fefaefd5b16e8f485d571beda00b1741efbb61a8a74fa12c2f6de66227c3fabb4d411659cd9c7b1ef32e171e6bf517cc39","private_key":"c5c6440cb8356bd270d8ce8d543b85c784f5c049b80e951c26fbcc92cfd1669e"},"up":false}},{"node":{"info":{"id":"e5cb29b25debcfaaacc0b04e708c8c1cb9d2dee29e82596a1c72a934032cf738800b9525cc277d0c5f5dacf2f278329b54da161b4bafa285243fa0e9fd7b2f3a","ports":{"listener":0,"discovery":0},"protocols":{"bzz":"2LBCXky1E03bLeXAXgrpuGG9Z0CcFEbKIoMY959d0fY=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: d8b042\npopulation: 19 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 1566 | 135 4f90 (0) 4fd6 (0) 4d44 (0) 4cf6 (0)\n001 2 b463 af30 | 56 9390 (0) 9294 (0) 9232 (0) 96b6 (0)\n002 2 e787 f048 | 29 e839 (0) ecd2 (0) edca (0) ed65 (0)\n003 4 c463 c770 c8fe ca81 | 18 c3f3 (0) c0d1 (0) c15d (0) c484 (0)\n004 2 d564 d7ab | 7 d3d2 (0) d3fd (0) d564 (0) d68f (0)\n005 5 ddf8 dc3e dc86 def4 | 7 ddf8 (0) dc3e (0) dc86 (0) df25 (0)\n============ DEPTH: 6 ==========================================\n006 2 dae3 daa2 | 2 dae3 (0) daa2 (0)\n007 0 | 0\n008 1 d822 | 1 d822 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ip":"0.0.0.0","listenAddr":"","name":"node239","enode":"enode://e5cb29b25debcfaaacc0b04e708c8c1cb9d2dee29e82596a1c72a934032cf738800b9525cc277d0c5f5dacf2f278329b54da161b4bafa285243fa0e9fd7b2f3a@0.0.0.0:0"},"up":true,"config":{"id":"e5cb29b25debcfaaacc0b04e708c8c1cb9d2dee29e82596a1c72a934032cf738800b9525cc277d0c5f5dacf2f278329b54da161b4bafa285243fa0e9fd7b2f3a","private_key":"64939e66b20f857b3b5c94f6e5f72f15ae524ce46058ebf20c98e796bcc608c8","services":["pss","bzz"],"name":"node239"}}},{"node":{"info":{"name":"node240","enode":"enode://6c40910f0556f892a7542989fa01d7e3682fca89aeefb5ed885808f88ff17b6d13862f461c10d629a005ae67abef542d75e5b20816891b6944f71560f5c2dfa8@0.0.0.0:0","listenAddr":"","ports":{"listener":0,"discovery":0},"protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: f048e3\npopulation: 21 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 2013 1566 | 135 5571 (0) 5716 (0) 57d5 (0) 5695 (0)\n001 3 96b6 a033 af30 | 56 8163 (0) 86f7 (0) 8612 (0) 8c89 (0)\n002 6 c770 c8fe ca81 dc86 | 36 c3f3 (0) c0d1 (0) c15d (0) c463 (0)\n003 3 edca ed13 e787 | 12 e839 (0) ecd2 (0) edca (0) ed65 (0)\n004 1 f915 | 6 fd2d (0) fed1 (0) fb93 (0) fa74 (0)\n005 2 f4ee f5cc | 6 f644 (0) f78a (0) f4e0 (0) f4ee (0)\n006 1 f3d3 | 1 f3d3 (0)\n============ DEPTH: 7 ==========================================\n007 2 f1fc f156 | 2 f1fc (0) f156 (0)\n008 1 f0e2 | 1 f0e2 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"8EjjdCfWjEE0oRXMffaokk6pXyTn8kNTcq4zHiS1t/0="},"ip":"0.0.0.0","id":"6c40910f0556f892a7542989fa01d7e3682fca89aeefb5ed885808f88ff17b6d13862f461c10d629a005ae67abef542d75e5b20816891b6944f71560f5c2dfa8"},"up":true,"config":{"id":"6c40910f0556f892a7542989fa01d7e3682fca89aeefb5ed885808f88ff17b6d13862f461c10d629a005ae67abef542d75e5b20816891b6944f71560f5c2dfa8","private_key":"9fa335b0c4f3fed78cb6aa4c0137589fe77d15b2127788adbca0633ef881b61c","services":["pss","bzz"],"name":"node240"}}},{"node":{"info":{"name":"node241","enode":"enode://d6747e1f8594f7449fc6d7c0e63ee843480567d498db096ff04229420861c83bca5215fc19d8fede0c54484f111f1f2581e189e638c21c5d9e1fd3174bbb3e98@0.0.0.0:0","listenAddr":"","protocols":{"bzz":"rzA/YekWISJNWWjjh5RtTh2/dtHn7m+PKuYJkRVNNzQ=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: af303f\npopulation: 24 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 2fd8 | 135 7ffe (0) 7fa4 (0) 7d45 (0) 7d94 (0)\n001 6 c770 d8b0 de82 dc86 | 65 d3fd (0) d3d2 (0) d564 (0) d68f (0)\n002 2 96b6 9a82 | 26 8163 (0) 8612 (0) 86f7 (0) 8c89 (0)\n003 4 b8a7 bc08 b710 b463 | 14 baf3 (0) b8a7 (0) bfec (0) bf5a (0)\n004 2 a485 a033 | 4 a672 (0) a749 (0) a485 (0) a033 (0)\n005 2 aa88 a80b | 4 abfa (0) aa50 (0) aa88 (0) a80b (0)\n006 3 adfc ad36 aca1 | 3 adfc (0) ad36 (0) aca1 (0)\n007 2 ae71 ae65 | 2 ae71 (0) ae65 (0)\n008 0 | 0\n============ DEPTH: 9 ==========================================\n009 1 af5f | 1 af5f (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 1 af35 | 1 af35 (0)\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"listener":0,"discovery":0},"ip":"0.0.0.0","id":"d6747e1f8594f7449fc6d7c0e63ee843480567d498db096ff04229420861c83bca5215fc19d8fede0c54484f111f1f2581e189e638c21c5d9e1fd3174bbb3e98"},"up":true,"config":{"private_key":"a36da338278d776a57dad648f8c5627834918fcaa86367e4aeaccefbb4142c1c","id":"d6747e1f8594f7449fc6d7c0e63ee843480567d498db096ff04229420861c83bca5215fc19d8fede0c54484f111f1f2581e189e638c21c5d9e1fd3174bbb3e98","name":"node241","services":["pss","bzz"]}}},{"node":{"config":{"id":"49256eccce3e036928a4b6b346126c6777dca5ea0134de85efca340f97ad0f827f3094f1562e3e186d35b8292a50c20ffae01409890bbb78598494285e14dc2c","private_key":"dfbcc9238ce614f0a4711f04948064ddbd5b2997a19f1e62c8f9636e9961fd5d","services":["pss","bzz"],"name":"node242"},"up":true,"info":{"id":"49256eccce3e036928a4b6b346126c6777dca5ea0134de85efca340f97ad0f827f3094f1562e3e186d35b8292a50c20ffae01409890bbb78598494285e14dc2c","ports":{"discovery":0,"listener":0},"protocols":{"bzz":"L9gA0iTxJORwOL8UDr1Ibx0KuTFpyZjS36v9HTztlu0=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 2fd800\npopulation: 21 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 af30 | 121 d3fd (0) d3d2 (0) d564 (0) d68f (0)\n001 2 67a2 4a81 | 62 7d45 (0) 7d94 (0) 7dc6 (0) 7de7 (0)\n002 6 12b9 14c8 15f6 1835 | 38 0f5e (0) 0f81 (0) 0eee (0) 0ea2 (0)\n003 1 3dca | 15 3345 (0) 32dd (0) 31ed (0) 3538 (0)\n004 3 265d 259d 2013 | 9 2279 (0) 2374 (0) 211a (0) 2168 (0)\n005 4 29ff 290f 2a22 2a69 | 6 29fd (0) 29ff (0) 290f (0) 2af0 (0)\n006 0 | 0\n007 2 2e4c 2e9f | 2 2e4c (0) 2e9f (0)\n============ DEPTH: 8 ==========================================\n008 1 2f22 | 1 2f22 (0)\n009 1 2f9f | 1 2f9f (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ip":"0.0.0.0","listenAddr":"","name":"node242","enode":"enode://49256eccce3e036928a4b6b346126c6777dca5ea0134de85efca340f97ad0f827f3094f1562e3e186d35b8292a50c20ffae01409890bbb78598494285e14dc2c@0.0.0.0:0"}}},{"node":{"info":{"protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 194ad1\npopulation: 20 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 ca81 | 121 8163 (0) 8612 (0) 86f7 (0) 8c89 (0)\n001 2 5093 5fd0 | 62 6ea5 (0) 6d21 (0) 6dbd (0) 6330 (0)\n002 2 259d 2fd8 | 35 3345 (0) 32dd (0) 31ed (0) 3538 (0)\n003 2 0f81 0592 | 12 0f5e (0) 0f81 (0) 0eee (0) 0ea2 (0)\n004 4 12b9 14c8 15f6 1566 | 8 13d8 (0) 123f (0) 12b9 (0) 1673 (0)\n005 3 1e44 1c98 1d94 | 8 1e42 (0) 1e44 (0) 1c98 (0) 1d5f (0)\n006 2 1b1e 1b86 | 5 1a02 (0) 1a83 (0) 1b72 (0) 1b1e (0)\n============ DEPTH: 7 ==========================================\n007 3 18f9 185a 1835 | 3 18f9 (0) 185a (0) 1835 (0)\n008 0 | 0\n009 1 193e | 1 193e (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"GUrRJsQcSH2VyDsZ7SuwU+TS7AYFlS06OW3UME6ONjw="},"ip":"0.0.0.0","ports":{"listener":0,"discovery":0},"id":"869cae165389e7dee7b7df4e012ee1a39737366c306d8f4b0db4510b2236e0bd3a4d1d4af00b1a8c1d360e23da47de52fc1632edb03c7f1429aacc8aa4994750","name":"node243","enode":"enode://869cae165389e7dee7b7df4e012ee1a39737366c306d8f4b0db4510b2236e0bd3a4d1d4af00b1a8c1d360e23da47de52fc1632edb03c7f1429aacc8aa4994750@0.0.0.0:0","listenAddr":""},"up":true,"config":{"services":["pss","bzz"],"name":"node243","id":"869cae165389e7dee7b7df4e012ee1a39737366c306d8f4b0db4510b2236e0bd3a4d1d4af00b1a8c1d360e23da47de52fc1632edb03c7f1429aacc8aa4994750","private_key":"ea0d5ec78fdcca32a257905b595a0c7bc8f2934d088b0f4c695a76927fa9e791"}}},{"node":{"up":true,"config":{"private_key":"01bbc4df92bfd5efca325ff653fcab3ac6aca83696f57927d3313fdf03dadafb","id":"1b3107d9a96cfd11f4cd0ed8baeb7b23db1406c9c4a9dac76c772f49c0fc9404f6a4adae11120aa821757173f0cc1cb00e6ab555b5abffaae9001c0557cb75c9","name":"node244","services":["pss","bzz"]},"info":{"listenAddr":"","enode":"enode://1b3107d9a96cfd11f4cd0ed8baeb7b23db1406c9c4a9dac76c772f49c0fc9404f6a4adae11120aa821757173f0cc1cb00e6ab555b5abffaae9001c0557cb75c9@0.0.0.0:0","name":"node244","id":"1b3107d9a96cfd11f4cd0ed8baeb7b23db1406c9c4a9dac76c772f49c0fc9404f6a4adae11120aa821757173f0cc1cb00e6ab555b5abffaae9001c0557cb75c9","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 5fd02e\npopulation: 19 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 a033 | 121 8163 (0) 8612 (0) 86f7 (0) 89ee (0)\n001 6 1566 14c8 12b9 1835 | 73 3345 (0) 32dd (0) 31ed (0) 3538 (0)\n002 2 72fa 67a2 | 31 7ffe (0) 7fa4 (0) 7d45 (0) 7d94 (0)\n003 2 4a82 4a81 | 17 458a (0) 46c5 (0) 47f9 (0) 4019 (0)\n004 4 566e 5695 5288 5093 | 9 5571 (0) 5716 (0) 57d5 (0) 566e (0)\n005 0 | 0\n006 1 5c5d | 1 5c5d (0)\n007 0 | 0\n008 1 5f05 | 1 5f05 (0)\n============ DEPTH: 9 ==========================================\n009 2 5fa8 5fab | 2 5fa8 (0) 5fab (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"X9AuqYl32Xb11HpABTALmGWx3NrHe/ipiokgqJtXglw="},"ports":{"discovery":0,"listener":0},"ip":"0.0.0.0"}}},{"node":{"config":{"id":"ee0b09ee6a1057c47102e582e2fdec7b9212802e59f062a9360da0db535d4987126ab24848c0d76fa8485431a5140307e2b0c0d9f37cbdb35756e6cc1bdb3bc0","private_key":"2e16fcbc5651872d962bf9cbbd32cccbef2adac9e86006e4b4e9abbe6c22d7cc","services":["pss","bzz"],"name":"node245"},"up":true,"info":{"listenAddr":"","enode":"enode://ee0b09ee6a1057c47102e582e2fdec7b9212802e59f062a9360da0db535d4987126ab24848c0d76fa8485431a5140307e2b0c0d9f37cbdb35756e6cc1bdb3bc0@0.0.0.0:0","name":"node245","id":"ee0b09ee6a1057c47102e582e2fdec7b9212802e59f062a9360da0db535d4987126ab24848c0d76fa8485431a5140307e2b0c0d9f37cbdb35756e6cc1bdb3bc0","protocols":{"bzz":"SoHukpB0vW2ZMvtNlw9SB9uGgL2g6VGqcqa9ZN9FEI0=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 4a81ee\npopulation: 21 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 a033 | 121 d3fd (0) d3d2 (0) d564 (0) d6d2 (0)\n001 8 193e 0f81 0ea2 2a69 | 73 32dd (0) 3345 (0) 31ed (0) 34fc (0)\n002 2 7a41 67a2 | 31 7307 (0) 7294 (0) 72ac (0) 72fa (0)\n003 3 5093 5288 5fd0 | 14 5571 (0) 5695 (0) 566e (0) 5716 (0)\n004 1 4019 | 7 458a (0) 47f9 (0) 46c5 (0) 42d4 (0)\n005 1 4cf6 | 4 4fd6 (0) 4f90 (0) 4d44 (0) 4cf6 (0)\n006 1 487e | 1 487e (0)\n007 1 4b00 | 1 4b00 (0)\n008 1 4a67 | 1 4a67 (0)\n============ DEPTH: 9 ==========================================\n009 1 4af7 | 1 4af7 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 1 4a82 | 1 4a82 (0)\n015 0 | 0\n========================================================================="},"ports":{"listener":0,"discovery":0},"ip":"0.0.0.0"}}},{"node":{"up":true,"config":{"services":["pss","bzz"],"name":"node246","id":"243164c4dd583f80c50813f43e5c27c894463400cd3afd776b36e79e7123d9261f01f06f92914aab83096b9a43fb655e79687590599284640a3a7d2c25454597","private_key":"a26a19f61e9c2c83a632e779651442713ae7026ff3889b0c2ba690ad206500cf"},"info":{"id":"243164c4dd583f80c50813f43e5c27c894463400cd3afd776b36e79e7123d9261f01f06f92914aab83096b9a43fb655e79687590599284640a3a7d2c25454597","protocols":{"bzz":"oDOA5R82VEUQe1kAnqqQQIc5aMrkd75WAu+730pkFOw=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: a03380\npopulation: 23 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 3dca 1835 5fd0 4a81 | 135 32dd (0) 3345 (0) 31ed (0) 3648 (0)\n001 5 ca81 d7ab daa2 f5cc | 65 d3d2 (0) d3fd (0) d564 (0) d68f (0)\n002 3 9c01 9a82 96b6 | 26 8163 (0) 8612 (0) 86f7 (0) 8c89 (0)\n003 3 be0a bf5a b8a7 | 14 b310 (0) b5c7 (0) b4c7 (0) b45d (0)\n004 5 aa88 a80b aca1 ae65 | 12 abfa (0) aa50 (0) aa88 (0) a80b (0)\n============ DEPTH: 5 ==========================================\n005 3 a672 a749 a485 | 3 a672 (0) a749 (0) a485 (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"listener":0,"discovery":0},"ip":"0.0.0.0","listenAddr":"","name":"node246","enode":"enode://243164c4dd583f80c50813f43e5c27c894463400cd3afd776b36e79e7123d9261f01f06f92914aab83096b9a43fb655e79687590599284640a3a7d2c25454597@0.0.0.0:0"}}},{"node":{"info":{"listenAddr":"","name":"node247","enode":"enode://e33a1476fcb8d2a1b9ee15871a960ce7a3337c93f5956a2825b1f8b2885dbdc0ed652b1eba549523866632b5b6898310bc638d946a9fcce27d65117eb44c25f3@0.0.0.0:0","id":"e33a1476fcb8d2a1b9ee15871a960ce7a3337c93f5956a2825b1f8b2885dbdc0ed652b1eba549523866632b5b6898310bc638d946a9fcce27d65117eb44c25f3","ports":{"listener":0,"discovery":0},"protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 1835f6\npopulation: 19 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 a033 | 121 d3fd (0) d3d2 (0) d564 (0) d68f (0)\n001 1 5fd0 | 62 7ffe (0) 7fa4 (0) 7d45 (0) 7d94 (0)\n002 2 2fd8 259d | 35 3345 (0) 32dd (0) 31ed (0) 3538 (0)\n003 1 0592 | 12 0eee (0) 0ea2 (0) 0f5e (0) 0f81 (0)\n004 3 12b9 1566 14c8 | 8 13d8 (0) 123f (0) 12b9 (0) 1673 (0)\n005 3 1e44 1d94 1c98 | 8 1e42 (0) 1e44 (0) 1d5f (0) 1d07 (0)\n006 4 1a02 1a83 1b1e 1b86 | 5 1a02 (0) 1a83 (0) 1b72 (0) 1b1e (0)\n007 2 194a 193e | 2 194a (0) 193e (0)\n============ DEPTH: 8 ==========================================\n008 1 18f9 | 1 18f9 (0)\n009 1 185a | 1 185a (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"GDX2L+OIn0O6e0tXeGnsdk6W+poFHxMB+5Z5XaqLB1U="},"ip":"0.0.0.0"},"config":{"name":"node247","services":["pss","bzz"],"private_key":"fd1c4ea6d2c07317eeaebbcd485aaf9267d81f2dc547b2136eba8ed02ae2c635","id":"e33a1476fcb8d2a1b9ee15871a960ce7a3337c93f5956a2825b1f8b2885dbdc0ed652b1eba549523866632b5b6898310bc638d946a9fcce27d65117eb44c25f3"},"up":true}},{"node":{"info":{"id":"2b0a1f3a6466c6be1d7e84120db384fa37f7c73a01e9a105ae90e7d2203212ec974f016d3012afd26bc0f9a8411d0716cc59b6ecc9f665db12e306af8b34cb63","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 259d38\npopulation: 20 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 96b6 | 121 d3fd (0) d3d2 (0) d564 (0) d68f (0)\n001 1 4a81 | 62 6ea5 (0) 6d21 (0) 6dbd (0) 6330 (0)\n002 6 03f5 0f81 1566 193e | 38 0eee (0) 0ea2 (0) 0f5e (0) 0f81 (0)\n003 2 3af3 3dca | 15 32dd (0) 3345 (0) 31ed (0) 3538 (0)\n004 4 290f 2a69 2f9f 2fd8 | 11 29fd (0) 29ff (0) 290f (0) 2af0 (0)\n005 3 2374 211a 2013 | 5 2279 (0) 2374 (0) 211a (0) 2168 (0)\n============ DEPTH: 6 ==========================================\n006 2 275c 265d | 2 275c (0) 265d (0)\n007 1 2454 | 1 2454 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"JZ04dGl6DDGS+XPGIIgLKoZWcon1Ii0H65GlGGc1JVk="},"ports":{"discovery":0,"listener":0},"ip":"0.0.0.0","listenAddr":"","enode":"enode://2b0a1f3a6466c6be1d7e84120db384fa37f7c73a01e9a105ae90e7d2203212ec974f016d3012afd26bc0f9a8411d0716cc59b6ecc9f665db12e306af8b34cb63@0.0.0.0:0","name":"node248"},"config":{"private_key":"a655a637ca80f8c5354e51e46d31d79b36a8a8b44d50e2838a118ea8b33512ee","id":"2b0a1f3a6466c6be1d7e84120db384fa37f7c73a01e9a105ae90e7d2203212ec974f016d3012afd26bc0f9a8411d0716cc59b6ecc9f665db12e306af8b34cb63","name":"node248","services":["pss","bzz"]},"up":true}},{"node":{"up":true,"config":{"id":"7db14fde1da8794ae7ab5de37c9e2537e1024bc830c176c0d01635cafed47773d3a28e156db81ecdb95903222b900c3ebd4c4b3db2971dc0ef6a1e386027ffaa","private_key":"02d1f6c1a867e9dd9cf7bff6121f3eb99e7c75866f8fb00d83782e69de6dacc5","services":["pss","bzz"],"name":"node249"},"info":{"enode":"enode://7db14fde1da8794ae7ab5de37c9e2537e1024bc830c176c0d01635cafed47773d3a28e156db81ecdb95903222b900c3ebd4c4b3db2971dc0ef6a1e386027ffaa@0.0.0.0:0","name":"node249","listenAddr":"","protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 96b6ec\npopulation: 20 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 12b9 193e 259d | 135 7a41 (0) 79bd (0) 79ab (0) 7829 (0)\n001 4 f5cc f048 daa2 ca81 | 65 d3d2 (0) d3fd (0) d564 (0) d6d2 (0)\n002 3 af30 a485 a033 | 30 b310 (0) b60d (0) b79f (0) b710 (0)\n003 3 8c61 8874 8ae6 | 10 8612 (0) 86f7 (0) 8163 (0) 8c89 (0)\n004 2 985c 9a82 | 9 9c0c (0) 9c01 (0) 9fee (0) 9eec (0)\n005 2 9294 9232 | 3 9390 (0) 9294 (0) 9232 (0)\n============ DEPTH: 6 ==========================================\n006 3 94aa 9461 95e0 | 3 95e0 (0) 94aa (0) 9461 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"lrbsLNp8npYrvJfnkWuS1psRImXERW0w2t6Abgn+pi4="},"ports":{"listener":0,"discovery":0},"ip":"0.0.0.0","id":"7db14fde1da8794ae7ab5de37c9e2537e1024bc830c176c0d01635cafed47773d3a28e156db81ecdb95903222b900c3ebd4c4b3db2971dc0ef6a1e386027ffaa"}}},{"node":{"config":{"name":"node250","services":["pss","bzz"],"private_key":"e0f98f6ae876455342403d6cd7ee64b21f5e5d691ed720d81e0db64529d8cd19","id":"865dbf61d8511603fe0d9ebfb10792b9f6b798187c0909039bd9b2492c41e428876f386beeac86d0dea871f4fc24ba435f0fbd9a11e74c044024934592af14ee"},"up":true,"info":{"id":"865dbf61d8511603fe0d9ebfb10792b9f6b798187c0909039bd9b2492c41e428876f386beeac86d0dea871f4fc24ba435f0fbd9a11e74c044024934592af14ee","protocols":{"bzz":"GT5SzikGLOyk9Gi0llWgbn1B9tJv8Mq0LB2Ja3C7khg=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 193e52\npopulation: 22 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 96b6 | 121 e3c9 (0) e4c3 (0) e44b (0) e76a (0)\n001 3 4a81 5fd0 67a2 | 62 5571 (0) 5716 (0) 57d5 (0) 566e (0)\n002 3 2fd8 259d 2013 | 35 34fc (0) 3538 (0) 3648 (0) 32dd (0)\n003 4 03f5 0592 0ea2 0f81 | 12 0f5e (0) 0f81 (0) 0eee (0) 0ea2 (0)\n004 2 15f6 12b9 | 8 13d8 (0) 123f (0) 12b9 (0) 1673 (0)\n005 2 1d07 1d94 | 8 1e42 (0) 1e44 (0) 1c98 (0) 1d5f (0)\n006 3 1a83 1b1e 1b86 | 5 1a02 (0) 1a83 (0) 1b72 (0) 1b1e (0)\n============ DEPTH: 7 ==========================================\n007 3 18f9 185a 1835 | 3 18f9 (0) 185a (0) 1835 (0)\n008 0 | 0\n009 1 194a | 1 194a (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","name":"node250","enode":"enode://865dbf61d8511603fe0d9ebfb10792b9f6b798187c0909039bd9b2492c41e428876f386beeac86d0dea871f4fc24ba435f0fbd9a11e74c044024934592af14ee@0.0.0.0:0"}}},{"node":{"config":{"name":"node251","services":["pss","bzz"],"private_key":"53adafcbccccca52e7bbf9524234d7c6c5874e3a328d3ded48c93c7b07f34428","id":"c0f233e79d0a8d4af01f54c40640975bc113f464271ba8922fca0c28acc60367af0db06629e701977e86cb5917c891e39c21418cab459fe49132b680aa31600b"},"up":true,"info":{"ip":"0.0.0.0","protocols":{"bzz":"IBPOY0g68pkLNfnsvlp2U8NLJN7Rc3U1dbJEUXh+2Lk=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 2013ce\npopulation: 17 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 e787 f048 | 121 e839 (0) ecd2 (0) edca (0) ed65 (0)\n001 2 4a81 67a2 | 62 5c5d (0) 5f05 (0) 5fa8 (0) 5fab (0)\n002 1 193e | 38 0eee (0) 0ea2 (0) 0f5e (0) 0f81 (0)\n003 2 3dca 3af3 | 15 3345 (0) 32dd (0) 31ed (0) 3538 (0)\n004 3 2f9f 2fd8 2a69 | 11 29fd (0) 29ff (0) 290f (0) 2af0 (0)\n005 3 275c 265d 259d | 4 275c (0) 265d (0) 2454 (0) 259d (0)\n006 2 2279 2374 | 2 2279 (0) 2374 (0)\n============ DEPTH: 7 ==========================================\n007 2 2168 211a | 2 211a (0) 2168 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"listener":0,"discovery":0},"id":"c0f233e79d0a8d4af01f54c40640975bc113f464271ba8922fca0c28acc60367af0db06629e701977e86cb5917c891e39c21418cab459fe49132b680aa31600b","enode":"enode://c0f233e79d0a8d4af01f54c40640975bc113f464271ba8922fca0c28acc60367af0db06629e701977e86cb5917c891e39c21418cab459fe49132b680aa31600b@0.0.0.0:0","name":"node251","listenAddr":""}}},{"node":{"up":true,"config":{"private_key":"b91ef086d245c3849c46234765c2d479c053b5974568062618a768ebb7014b64","id":"b8e0a56df21baae43058f575b714ae9a33c097d18f1a628b3b6ae5e86dd46a06e44c0dc272baacb5be0f7bf57fd6ddce107544eb3b94dca1aeae9f5773496a72","name":"node252","services":["pss","bzz"]},"info":{"id":"b8e0a56df21baae43058f575b714ae9a33c097d18f1a628b3b6ae5e86dd46a06e44c0dc272baacb5be0f7bf57fd6ddce107544eb3b94dca1aeae9f5773496a72","protocols":{"bzz":"Z6JGVAwfoZoIVs9amUgKOCb8keEls79eweR6LFr/VL4=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 67a246\npopulation: 23 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 daa2 | 121 b310 (0) b60d (0) b79f (0) b710 (0)\n001 6 0592 193e 2fd8 2f9f | 73 0eee (0) 0ea2 (0) 0f5e (0) 0f81 (0)\n002 5 4a81 4a82 5fd0 5093 | 31 5c5d (0) 5f05 (0) 5fa8 (0) 5fab (0)\n003 2 7471 72fa | 20 7a41 (0) 7829 (0) 7851 (0) 7854 (0)\n004 2 6ea5 6dbd | 3 6ea5 (0) 6d21 (0) 6dbd (0)\n005 3 604c 6143 6330 | 3 604c (0) 6143 (0) 6330 (0)\n006 1 6544 | 1 6544 (0)\n007 1 6610 | 1 6610 (0)\n============ DEPTH: 8 ==========================================\n008 1 670d | 1 670d (0)\n009 0 | 0\n010 1 6783 | 1 6783 (0)\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","name":"node252","enode":"enode://b8e0a56df21baae43058f575b714ae9a33c097d18f1a628b3b6ae5e86dd46a06e44c0dc272baacb5be0f7bf57fd6ddce107544eb3b94dca1aeae9f5773496a72@0.0.0.0:0"}}},{"node":{"config":{"id":"b58b3e200f6072ddb38130944a01d2829c755b8bd1a08abd010d1bbf86dabd851b2c1ab4cb961451bd7e8499f6c7378830bcd27cde825846654853c172597bf3","private_key":"438a2cd1d35d995ba9e35fe1b4086196934e0a6087ca2ae18543512299224b1e","services":["pss","bzz"],"name":"node253"},"up":true,"info":{"ports":{"discovery":0,"listener":0},"protocols":{"bzz":"2qLEJ+jsxWbmNJCPsNRwd9jnmFS/iENCwGxLyzVegOY=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: daa2c4\npopulation: 20 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 4 2f9f 5288 72fa 67a2 | 135 0f5e (0) 0f81 (0) 0eee (0) 0ea2 (0)\n001 3 a033 b8a7 96b6 | 56 b310 (0) b60d (0) b79f (0) b710 (0)\n002 2 f5cc ed13 | 29 fd2d (0) fed1 (0) f924 (0) f915 (0)\n003 1 ca81 | 18 c0d1 (0) c15d (0) c3f3 (0) c63e (0)\n004 1 d6f3 | 7 d3fd (0) d3d2 (0) d564 (0) d7ab (0)\n005 6 def4 de82 df5e ddf8 | 7 df25 (0) df5e (0) def4 (0) de82 (0)\n============ DEPTH: 6 ==========================================\n006 2 d822 d8b0 | 2 d822 (0) d8b0 (0)\n007 0 | 0\n008 0 | 0\n009 1 dae3 | 1 dae3 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ip":"0.0.0.0","id":"b58b3e200f6072ddb38130944a01d2829c755b8bd1a08abd010d1bbf86dabd851b2c1ab4cb961451bd7e8499f6c7378830bcd27cde825846654853c172597bf3","enode":"enode://b58b3e200f6072ddb38130944a01d2829c755b8bd1a08abd010d1bbf86dabd851b2c1ab4cb961451bd7e8499f6c7378830bcd27cde825846654853c172597bf3@0.0.0.0:0","name":"node253","listenAddr":""}}},{"node":{"up":true,"config":{"private_key":"1945283cb814bb48cbb80a03a2660606e5c5e023e3b8ac887baf7cc912ec5be7","id":"9309549fc50173d6826fe63cf18699f49199c3789616b843042fe1a6adab6ed4bdd7a7a06acd276e0398cf8bffb26c12a4227725d7bbd386a9a55fc601c21405","name":"node254","services":["pss","bzz"]},"info":{"protocols":{"bzz":"L58majtmD+aF3iky3oKXm9IhcG2x4rlUqT7cZgnDeNk=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 2f9f26\npopulation: 20 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 daa2 | 121 b310 (0) b60d (0) b79f (0) b710 (0)\n001 3 5288 72fa 67a2 | 62 458a (0) 47f9 (0) 46c5 (0) 42c0 (0)\n002 2 0592 12b9 | 38 1e44 (0) 1e42 (0) 1c98 (0) 1d5f (0)\n003 5 3648 396b 3af3 3e44 | 15 31ed (0) 3345 (0) 32dd (0) 3538 (0)\n004 3 265d 259d 2013 | 9 275c (0) 265d (0) 2454 (0) 259d (0)\n005 2 290f 2a69 | 6 29fd (0) 29ff (0) 290f (0) 2af0 (0)\n006 0 | 0\n007 2 2e9f 2e4c | 2 2e9f (0) 2e4c (0)\n============ DEPTH: 8 ==========================================\n008 1 2f22 | 1 2f22 (0)\n009 1 2fd8 | 1 2fd8 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"discovery":0,"listener":0},"ip":"0.0.0.0","id":"9309549fc50173d6826fe63cf18699f49199c3789616b843042fe1a6adab6ed4bdd7a7a06acd276e0398cf8bffb26c12a4227725d7bbd386a9a55fc601c21405","name":"node254","enode":"enode://9309549fc50173d6826fe63cf18699f49199c3789616b843042fe1a6adab6ed4bdd7a7a06acd276e0398cf8bffb26c12a4227725d7bbd386a9a55fc601c21405@0.0.0.0:0","listenAddr":""}}},{"node":{"info":{"name":"node255","enode":"enode://81901d9f043b4b1649ade3b5d22ae5f8bb42dd6db1eb37b836b99dd1c0388509ed4b54cc5638c9d4a6c5ae6c6913bbfffb303d7d94bf4ed50e871cf95459e2c3@0.0.0.0:0","listenAddr":"","ports":{"listener":0,"discovery":0},"protocols":{"hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 3dca1a\npopulation: 21 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 a033 b8a7 b710 | 121 b310 (0) b5c7 (0) b463 (0) b45d (0)\n001 2 4a82 4b00 | 62 43af (0) 42d4 (0) 42c0 (0) 4019 (0)\n002 3 1566 1d94 1b86 | 38 0f5e (0) 0f81 (0) 0eee (0) 0ea2 (0)\n003 7 2013 2374 259d 290f | 20 275c (0) 265d (0) 2454 (0) 259d (0)\n004 1 31ed | 6 3345 (0) 32dd (0) 31ed (0) 3538 (0)\n005 1 3af3 | 4 388d (0) 396b (0) 3a4a (0) 3af3 (0)\n============ DEPTH: 6 ==========================================\n006 3 3f3e 3e85 3e44 | 3 3f3e (0) 3e85 (0) 3e44 (0)\n007 0 | 0\n008 1 3d6b | 1 3d6b (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"Pcoa5IjMSX/nOMYwRl+Ye0GaW7JZ/foX/nEw4jjKMCI="},"ip":"0.0.0.0","id":"81901d9f043b4b1649ade3b5d22ae5f8bb42dd6db1eb37b836b99dd1c0388509ed4b54cc5638c9d4a6c5ae6c6913bbfffb303d7d94bf4ed50e871cf95459e2c3"},"up":true,"config":{"name":"node255","services":["pss","bzz"],"private_key":"be6f375f22929e615c683dc9b07e4e2c609a06e07a849a718617c2a0c2ad49f6","id":"81901d9f043b4b1649ade3b5d22ae5f8bb42dd6db1eb37b836b99dd1c0388509ed4b54cc5638c9d4a6c5ae6c6913bbfffb303d7d94bf4ed50e871cf95459e2c3"}}},{"node":{"config":{"name":"node256","services":["pss","bzz"],"private_key":"9775c9bb0b01e8a605866b96d386a1f8c3dbba2605cb9f8089c4f85fecfb6c62","id":"2abb91884cc3a8fb91b2f2f369f9430f2b3b05c75ce6203aa7a50312c9f141f9d0f615063d3576a5ce8a4be9ecb942aa804a717f76d9e8dca03d115dcc43f775"},"up":true,"info":{"listenAddr":"","name":"node256","enode":"enode://2abb91884cc3a8fb91b2f2f369f9430f2b3b05c75ce6203aa7a50312c9f141f9d0f615063d3576a5ce8a4be9ecb942aa804a717f76d9e8dca03d115dcc43f775@0.0.0.0:0","id":"2abb91884cc3a8fb91b2f2f369f9430f2b3b05c75ce6203aa7a50312c9f141f9d0f615063d3576a5ce8a4be9ecb942aa804a717f76d9e8dca03d115dcc43f775","ports":{"discovery":0,"listener":0},"protocols":{"bzz":"G4acpa7B/wyZgLBreQhAGXUv1FVwVOJRwAke5dLH1Hg=","hive":"\n=========================================================================\nSat Sep 30 16:35:25 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 1b869c\npopulation: 19 (255), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 b310 | 121 b60d (0) b79f (0) b710 (0) b5c7 (0)\n001 2 5288 5093 | 62 7ffe (0) 7fa4 (0) 7d45 (0) 7d94 (0)\n002 1 3dca | 35 275c (0) 265d (0) 2454 (0) 259d (0)\n003 2 0592 03f5 | 12 004e (0) 0210 (0) 03f5 (0) 06aa (0)\n004 3 13d8 12b9 15f6 | 8 13d8 (0) 123f (0) 12b9 (0) 1673 (0)\n005 2 1c98 1d94 | 8 1e42 (0) 1e44 (0) 1c98 (0) 1d5f (0)\n006 4 18f9 1835 193e 194a | 5 18f9 (0) 185a (0) 1835 (0) 193e (0)\n007 2 1a02 1a83 | 2 1a02 (0) 1a83 (0)\n============ DEPTH: 8 ==========================================\n008 2 1b72 1b1e | 2 1b72 (0) 1b1e (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ip":"0.0.0.0"}}}]} \ No newline at end of file diff --git a/swarm/pss/testdata/snapshot_3.json b/swarm/pss/testdata/snapshot_3.json new file mode 100644 index 0000000000..2d815eef40 --- /dev/null +++ b/swarm/pss/testdata/snapshot_3.json @@ -0,0 +1,100 @@ +{ + "conns":[ + { + "one":"0eec333dd211c2ea81db614fe58bf0300c15e50e1b044e47ef93067a6cdbc3bc666b40bdcc515bbf580355dbef9370294ef1ee92ee0525e78a8beed00c2b99f5", + "other":"6f6ee658538ea66a68c9cb914d09f228f6ee9942c337a8d5a2cb3a0f021e83dd0fab481ca8ebf56ed913f6ddf69caa3249459d43e61e5e5b162ded7e1c918c9c", + "up":true + }, + { + "other":"0eec333dd211c2ea81db614fe58bf0300c15e50e1b044e47ef93067a6cdbc3bc666b40bdcc515bbf580355dbef9370294ef1ee92ee0525e78a8beed00c2b99f5", + "one":"7b12f55c7c012104e006775d03b89722b403fb0e1ecb79af8cadfa6947425aedb323fb9416c84b782d35f3216acb5d94a1dd31d60a3eba45f9051bf503de1b66", + "up":true + } + ], + "nodes":[ + { + "node":{ + "config":{ + "private_key":"e567b7d9c554e5102cdc99b6523bace02dbb8951415c8816d82ba2d2e97fa23b", + "name":"node01", + "id":"7b12f55c7c012104e006775d03b89722b403fb0e1ecb79af8cadfa6947425aedb323fb9416c84b782d35f3216acb5d94a1dd31d60a3eba45f9051bf503de1b66", + "services":[ + "bzz","pss" + ] + }, + "info":{ + "ip":"0.0.0.0", + "listenAddr":"", + "protocols":{ + "hive":"\n=========================================================================\nFri Sep 29 21:22:53 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 73d6ad\npopulation: 5 (7), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 dfd4 | 3 8a1e (0) d776 (0) dfd4 (0)\n============ DEPTH: 1 ==========================================\n001 3 05da 159c 3451 | 3 05da (0) 159c (0) 3451 (0)\n002 0 | 0\n003 1 6e8d | 1 6e8d (0)\n004 0 | 0\n005 0 | 0\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================", + "bzz":"c9atSnUGnc7WYPpMuYFD7lVz33yxXZopWs8WVeloM4Q=" + }, + "ports":{ + "listener":0, + "discovery":0 + }, + "name":"node01", + "id":"7b12f55c7c012104e006775d03b89722b403fb0e1ecb79af8cadfa6947425aedb323fb9416c84b782d35f3216acb5d94a1dd31d60a3eba45f9051bf503de1b66", + "enode":"enode://7b12f55c7c012104e006775d03b89722b403fb0e1ecb79af8cadfa6947425aedb323fb9416c84b782d35f3216acb5d94a1dd31d60a3eba45f9051bf503de1b66@0.0.0.0:0" + }, + "up":true + } + }, + { + "node":{ + "info":{ + "listenAddr":"", + "ip":"0.0.0.0", + "ports":{ + "discovery":0, + "listener":0 + }, + "protocols":{ + "hive":"\n=========================================================================\nFri Sep 29 21:22:53 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 6e8da8\npopulation: 5 (7), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 8a1e | 3 8a1e (0) d776 (0) dfd4 (0)\n============ DEPTH: 1 ==========================================\n001 3 3451 159c 05da | 3 05da (0) 159c (0) 3451 (0)\n002 0 | 0\n003 1 73d6 | 1 73d6 (0)\n004 0 | 0\n005 0 | 0\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================", + "bzz":"bo2oaruJSrNQRMjEVRRyJd+WyrSY2gZ6EY8fuaQX+eM=" + }, + "id":"0eec333dd211c2ea81db614fe58bf0300c15e50e1b044e47ef93067a6cdbc3bc666b40bdcc515bbf580355dbef9370294ef1ee92ee0525e78a8beed00c2b99f5", + "name":"node02", + "enode":"enode://0eec333dd211c2ea81db614fe58bf0300c15e50e1b044e47ef93067a6cdbc3bc666b40bdcc515bbf580355dbef9370294ef1ee92ee0525e78a8beed00c2b99f5@0.0.0.0:0" + }, + "config":{ + "name":"node02", + "id":"0eec333dd211c2ea81db614fe58bf0300c15e50e1b044e47ef93067a6cdbc3bc666b40bdcc515bbf580355dbef9370294ef1ee92ee0525e78a8beed00c2b99f5", + "services":[ + "bzz","pss" + ], + "private_key":"c7526db70acd02f36d3b201ef3e1d85e38c52bee6931453213dbc5edec4d0976" + }, + "up":true + } + }, + { + "node":{ + "config":{ + "private_key":"61b5728f59bc43080c3b8eb0458fb30d7723e2747355b6dc980f35f3ed431199", + "id":"6f6ee658538ea66a68c9cb914d09f228f6ee9942c337a8d5a2cb3a0f021e83dd0fab481ca8ebf56ed913f6ddf69caa3249459d43e61e5e5b162ded7e1c918c9c", + "name":"node03", + "services":[ + "bzz","pss" + ] + }, + "info":{ + "ip":"0.0.0.0", + "listenAddr":"", + "protocols":{ + "hive":"\n=========================================================================\nFri Sep 29 21:22:53 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 8a1eb7\npopulation: 3 (7), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 6e8d | 5 05da (0) 159c (0) 3451 (0) 73d6 (0)\n============ DEPTH: 1 ==========================================\n001 2 dfd4 d776 | 2 dfd4 (0) d776 (0)\n002 0 | 0\n003 0 | 0\n004 0 | 0\n005 0 | 0\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================", + "bzz":"ih63j/E98xjn+BFt/+6YzX2ZBWUPpT8Wdmt1SmPzh6w=" + }, + "ports":{ + "discovery":0, + "listener":0 + }, + "name":"node03", + "id":"6f6ee658538ea66a68c9cb914d09f228f6ee9942c337a8d5a2cb3a0f021e83dd0fab481ca8ebf56ed913f6ddf69caa3249459d43e61e5e5b162ded7e1c918c9c", + "enode":"enode://6f6ee658538ea66a68c9cb914d09f228f6ee9942c337a8d5a2cb3a0f021e83dd0fab481ca8ebf56ed913f6ddf69caa3249459d43e61e5e5b162ded7e1c918c9c@0.0.0.0:0" + }, + "up":true + } + } + ] +} diff --git a/swarm/pss/testdata/snapshot_32.json b/swarm/pss/testdata/snapshot_32.json new file mode 100644 index 0000000000..5ff2e024dc --- /dev/null +++ b/swarm/pss/testdata/snapshot_32.json @@ -0,0 +1 @@ +{"nodes":[{"node":{"info":{"listenAddr":"","protocols":{"hive":"\n=========================================================================\nFri Sep 29 21:23:27 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 41de70\npopulation: 8 (31), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 c386 | 14 8144 (0) 8564 (0) 8939 (0) 8b72 (0)\n001 1 0b07 | 10 3a26 (0) 3efb (0) 3efa (0) 211b (0)\n002 1 7f25 | 1 7f25 (0)\n003 3 55b8 5e88 58eb | 4 59b2 (0) 58eb (0) 5e88 (0) 55b8 (0)\n004 0 | 0\n============ DEPTH: 5 ==========================================\n005 2 4659 461d | 2 4659 (0) 461d (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"Qd5wtE57CwZw1C8K40i8ZQHO+LQXSmxtmYZkXNXkeq8="},"ports":{"discovery":0,"listener":0},"ip":"0.0.0.0","id":"fcdcb9c138c3bdc51b6280a1224419097c4fb188867ca381ac9b92ab08f9fdef0c6267d9ce9fa53944e39cf1b76ce6bf3b17272f97a457649bff6a838eccbf69","name":"node01","enode":"enode://fcdcb9c138c3bdc51b6280a1224419097c4fb188867ca381ac9b92ab08f9fdef0c6267d9ce9fa53944e39cf1b76ce6bf3b17272f97a457649bff6a838eccbf69@0.0.0.0:0"},"config":{"services":["pss","bzz"],"id":"fcdcb9c138c3bdc51b6280a1224419097c4fb188867ca381ac9b92ab08f9fdef0c6267d9ce9fa53944e39cf1b76ce6bf3b17272f97a457649bff6a838eccbf69","name":"node01","private_key":"294c55925f084f4af87c7e09716c6334a538bac3e6b7157844c0c96a9dd02b4a"},"up":true}},{"node":{"info":{"enode":"enode://9456ce63934b1f648d870d6d2e71634a2ec78df8ccb6c83a364e656b4fe280a9273cccb92bfac7996ed1e6351963e076f3fe6fb89b95c866cc072c8d31775388@0.0.0.0:0","id":"9456ce63934b1f648d870d6d2e71634a2ec78df8ccb6c83a364e656b4fe280a9273cccb92bfac7996ed1e6351963e076f3fe6fb89b95c866cc072c8d31775388","ip":"0.0.0.0","name":"node02","ports":{"discovery":0,"listener":0},"protocols":{"hive":"\n=========================================================================\nFri Sep 29 21:23:27 UTC 2017 KΛÐΞMLIΛ hive: queen's address: c38639\npopulation: 8 (31), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 0688 41de | 18 3a26 (0) 3efb (0) 3efa (0) 211b (0)\n001 1 9ea0 | 5 8144 (0) 8564 (0) 8939 (0) 8b72 (0)\n002 1 f1e3 | 4 f1e3 (0) fbe2 (0) e9bc (0) ea5a (0)\n003 2 de8f dcf5 | 2 dcf5 (0) de8f (0)\n============ DEPTH: 4 ==========================================\n004 1 cd92 | 1 cd92 (0)\n005 1 c6b6 | 1 c6b6 (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"w4Y5Rvt9Q6dcviUD+jAaSiDPZcqsHfy+X6+i2HOlxuU="},"listenAddr":""},"config":{"services":["pss","bzz"],"name":"node02","private_key":"010dbe172f1240848fae9639e029301ebd297b29ad2d6936c67669d23470cee4","id":"9456ce63934b1f648d870d6d2e71634a2ec78df8ccb6c83a364e656b4fe280a9273cccb92bfac7996ed1e6351963e076f3fe6fb89b95c866cc072c8d31775388"},"up":true}},{"node":{"config":{"private_key":"7f974cee5ec96d070bf88898c24035988667ea21242a02822bccbe4ec487d126","name":"node03","id":"60bf8283de94e5192962b86a9c6cbe90adb9d7b399c5ea8b51ad0883a5438814939512c40e4e13ba0ea9b2d3e60a44a25297d005939eeec21f9f304b25798719","services":["pss","bzz"]},"info":{"protocols":{"hive":"\n=========================================================================\nFri Sep 29 21:23:27 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 0688bd\npopulation: 8 (31), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 c386 | 14 8939 (0) 8b72 (0) 8144 (0) 8564 (0)\n001 1 59b2 | 8 7f25 (0) 41de (0) 4659 (0) 461d (0)\n002 1 211b | 4 3a26 (0) 3efb (0) 3efa (0) 211b (0)\n003 1 175e | 1 175e (0)\n============ DEPTH: 4 ==========================================\n004 3 0c14 0a5c 0b07 | 3 0a5c (0) 0b07 (0) 0c14 (0)\n005 1 02f7 | 1 02f7 (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"Boi9FjMFJihaUysu40qSB1SH2Tk44nieMkzLWDr3lWo="},"listenAddr":"","ports":{"listener":0,"discovery":0},"ip":"0.0.0.0","name":"node03","id":"60bf8283de94e5192962b86a9c6cbe90adb9d7b399c5ea8b51ad0883a5438814939512c40e4e13ba0ea9b2d3e60a44a25297d005939eeec21f9f304b25798719","enode":"enode://60bf8283de94e5192962b86a9c6cbe90adb9d7b399c5ea8b51ad0883a5438814939512c40e4e13ba0ea9b2d3e60a44a25297d005939eeec21f9f304b25798719@0.0.0.0:0"},"up":true}},{"node":{"config":{"services":["pss","bzz"],"name":"node04","id":"44b0032c765d307d53ff64c7c86a0409b119b87d1ef5007c37a1663beac3fa4ddb092c06dd0c0ffe05505928a578207968afad2204db317a418da617ca132948","private_key":"d7e181b51ba95fd1475314470468045205d7ddefb1bbecfda3340267062489d1"},"info":{"ports":{"listener":0,"discovery":0},"listenAddr":"","protocols":{"bzz":"IRtzzNRF31Gbivq7B7O1kPNZTwFxWryo+cx/reM/dbo=","hive":"\n=========================================================================\nFri Sep 29 21:23:27 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 211b73\npopulation: 8 (26), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 9ea0 | 10 9ea0 (0) f1e3 (0) fbe2 (0) ea5a (0)\n001 1 7f25 | 7 7f25 (0) 41de (0) 4659 (0) 461d (0)\n002 3 0a5c 0c14 0688 | 6 175e (0) 0a5c (0) 0b07 (0) 0c14 (0)\n============ DEPTH: 3 ==========================================\n003 3 3a26 3efa 3efb | 3 3a26 (0) 3efa (0) 3efb (0)\n004 0 | 0\n005 0 | 0\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"enode":"enode://44b0032c765d307d53ff64c7c86a0409b119b87d1ef5007c37a1663beac3fa4ddb092c06dd0c0ffe05505928a578207968afad2204db317a418da617ca132948@0.0.0.0:0","ip":"0.0.0.0","name":"node04","id":"44b0032c765d307d53ff64c7c86a0409b119b87d1ef5007c37a1663beac3fa4ddb092c06dd0c0ffe05505928a578207968afad2204db317a418da617ca132948"},"up":true}},{"node":{"config":{"services":["pss","bzz"],"private_key":"87ed3ffe3111baec0adfd92068b47ed9e1efb642d0ff3115d7d76338f25eea76","name":"node05","id":"3d27bc8fb22ad60ca25a70734e1d87fb7ab8105f5c95e9ae21922eb651076bbb331b3b84df907edb4fae23f2a722c77a6dd40f5fb926f909477611cae3773610"},"info":{"listenAddr":"","protocols":{"bzz":"PvsNlTDJMcnkfG/2IsitaVy/rSFs2aK0JoyMN2P/r/A=","hive":"\n=========================================================================\nFri Sep 29 21:23:27 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 3efb0d\npopulation: 8 (31), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 f1e3 8b72 | 14 8144 (0) 8564 (0) 8939 (0) 8b72 (0)\n001 2 461d 55b8 | 8 7f25 (0) 41de (0) 4659 (0) 461d (0)\n002 1 0c14 | 6 175e (0) 0a5c (0) 0b07 (0) 0c14 (0)\n003 1 211b | 1 211b (0)\n004 0 | 0\n============ DEPTH: 5 ==========================================\n005 1 3a26 | 1 3a26 (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 1 3efa | 1 3efa (0)\n========================================================================="},"ports":{"listener":0,"discovery":0},"id":"3d27bc8fb22ad60ca25a70734e1d87fb7ab8105f5c95e9ae21922eb651076bbb331b3b84df907edb4fae23f2a722c77a6dd40f5fb926f909477611cae3773610","ip":"0.0.0.0","name":"node05","enode":"enode://3d27bc8fb22ad60ca25a70734e1d87fb7ab8105f5c95e9ae21922eb651076bbb331b3b84df907edb4fae23f2a722c77a6dd40f5fb926f909477611cae3773610@0.0.0.0:0"},"up":true}},{"node":{"info":{"protocols":{"hive":"\n=========================================================================\nFri Sep 29 21:23:27 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 55b8a5\npopulation: 7 (26), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 9ea0 | 9 9ea0 (0) f1e3 (0) fbe2 (0) ea5a (0)\n001 1 3efb | 10 175e (0) 0688 (0) 02f7 (0) 0a5c (0)\n002 1 7f25 | 1 7f25 (0)\n003 1 41de | 3 41de (0) 4659 (0) 461d (0)\n============ DEPTH: 4 ==========================================\n004 3 5e88 58eb 59b2 | 3 5e88 (0) 58eb (0) 59b2 (0)\n005 0 | 0\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"Vbil8tGZzBFbnQl4RYREmDE3iIWRsOkQFswvdc5ZOkE="},"listenAddr":"","ports":{"discovery":0,"listener":0},"id":"aed42225cae33605337d1c034564b46cad9f2cb17ce0f0b91c3f3b8f8f8c0e14357d6d6323ffe1f5f50931394d49c9ef589e4f2251f1bdc5c8e45d7c10f9b1e6","ip":"0.0.0.0","name":"node06","enode":"enode://aed42225cae33605337d1c034564b46cad9f2cb17ce0f0b91c3f3b8f8f8c0e14357d6d6323ffe1f5f50931394d49c9ef589e4f2251f1bdc5c8e45d7c10f9b1e6@0.0.0.0:0"},"config":{"services":["pss","bzz"],"id":"aed42225cae33605337d1c034564b46cad9f2cb17ce0f0b91c3f3b8f8f8c0e14357d6d6323ffe1f5f50931394d49c9ef589e4f2251f1bdc5c8e45d7c10f9b1e6","name":"node06","private_key":"7dbb4fe973c714c4291ce5a8aedce9c3425a25cdecfd5fe0c7f14b55e91d6a03"},"up":true}},{"node":{"config":{"name":"node07","private_key":"6f8900888d42ea5340f13634776acfd4a261837cdb772b9a059b23c7d425da1d","id":"af45ddac579286a5850ea494b3e76c1fe116b44de10f183a55ac1eced6eb34682f35eca605dd5b32015645e0e7527090d956236fdeade90b8cc920c54992d161","services":["pss","bzz"]},"info":{"id":"af45ddac579286a5850ea494b3e76c1fe116b44de10f183a55ac1eced6eb34682f35eca605dd5b32015645e0e7527090d956236fdeade90b8cc920c54992d161","ip":"0.0.0.0","name":"node07","enode":"enode://af45ddac579286a5850ea494b3e76c1fe116b44de10f183a55ac1eced6eb34682f35eca605dd5b32015645e0e7527090d956236fdeade90b8cc920c54992d161@0.0.0.0:0","listenAddr":"","protocols":{"bzz":"WbIUNwynxgvNqVoY0rZoUZ747lOvnkpnfxmB3v551Kc=","hive":"\n=========================================================================\nFri Sep 29 21:23:27 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 59b214\npopulation: 8 (31), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 e9bc | 14 8b72 (0) 8939 (0) 8144 (0) 8564 (0)\n001 1 0688 | 10 175e (0) 0688 (0) 02f7 (0) 0a5c (0)\n002 1 7f25 | 1 7f25 (0)\n003 2 461d 4659 | 3 41de (0) 4659 (0) 461d (0)\n004 1 55b8 | 1 55b8 (0)\n============ DEPTH: 5 ==========================================\n005 1 5e88 | 1 5e88 (0)\n006 0 | 0\n007 1 58eb | 1 58eb (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"listener":0,"discovery":0}},"up":true}},{"node":{"up":true,"config":{"id":"7405baadb8ddcc559dc29f72e5c8a85f539c7836675eac274f043acc3bdb378faf91feab452af20388f4e1cf187a47e5e93fa232da007c9aa6ee6155fdd3329d","name":"node08","private_key":"a94698db3c1a809d255fedabcb4f3314be27cad7be63cda59bb71724d24ca0d9","services":["pss","bzz"]},"info":{"name":"node08","ip":"0.0.0.0","id":"7405baadb8ddcc559dc29f72e5c8a85f539c7836675eac274f043acc3bdb378faf91feab452af20388f4e1cf187a47e5e93fa232da007c9aa6ee6155fdd3329d","enode":"enode://7405baadb8ddcc559dc29f72e5c8a85f539c7836675eac274f043acc3bdb378faf91feab452af20388f4e1cf187a47e5e93fa232da007c9aa6ee6155fdd3329d@0.0.0.0:0","protocols":{"bzz":"6bz/2DVa9D3+TsRBXnepL29ol/nGvHjzEoE0bNRgzTQ=","hive":"\n=========================================================================\nFri Sep 29 21:23:27 UTC 2017 KΛÐΞMLIΛ hive: queen's address: e9bcff\npopulation: 8 (31), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 59b2 | 18 7f25 (0) 41de (0) 4659 (0) 461d (0)\n001 3 8144 8b72 8939 | 5 8939 (0) 8b72 (0) 8564 (0) 8144 (0)\n002 1 cd92 | 5 dcf5 (0) de8f (0) c6b6 (0) c386 (0)\n============ DEPTH: 3 ==========================================\n003 2 f1e3 fbe2 | 2 f1e3 (0) fbe2 (0)\n004 0 | 0\n005 0 | 0\n006 1 ea5a | 1 ea5a (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"listenAddr":"","ports":{"discovery":0,"listener":0}}}},{"node":{"info":{"listenAddr":"","protocols":{"bzz":"zZLZKXPcJfYj5EkqFl+KiwQ+ndlZykmKp8boLsgDjVQ=","hive":"\n=========================================================================\nFri Sep 29 21:23:27 UTC 2017 KΛÐΞMLIΛ hive: queen's address: cd92d9\npopulation: 8 (26), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 3efa | 17 7f25 (0) 41de (0) 4659 (0) 461d (0)\n001 1 9ea0 | 1 9ea0 (0)\n002 2 fbe2 e9bc | 4 f1e3 (0) fbe2 (0) ea5a (0) e9bc (0)\n003 2 dcf5 de8f | 2 dcf5 (0) de8f (0)\n============ DEPTH: 4 ==========================================\n004 2 c6b6 c386 | 2 c6b6 (0) c386 (0)\n005 0 | 0\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"discovery":0,"listener":0},"ip":"0.0.0.0","name":"node09","id":"275252d736821f456466bca13738d5e62ce93dec8bbc26c9e9f11d399e2ae83d8b540797322215c859993389082ccf2d4da69fee1193e31fb225e39961780c2c","enode":"enode://275252d736821f456466bca13738d5e62ce93dec8bbc26c9e9f11d399e2ae83d8b540797322215c859993389082ccf2d4da69fee1193e31fb225e39961780c2c@0.0.0.0:0"},"config":{"services":["pss","bzz"],"id":"275252d736821f456466bca13738d5e62ce93dec8bbc26c9e9f11d399e2ae83d8b540797322215c859993389082ccf2d4da69fee1193e31fb225e39961780c2c","name":"node09","private_key":"37f683b58015f6a7ce73f814fc3860318bb2048052356a215f9eff00aa6ed34b"},"up":true}},{"node":{"up":true,"info":{"ip":"0.0.0.0","name":"node10","id":"09fbec10eccc27dfc7cc82ea3ffc15c5d1fff4265c930f0a2a2daaf0baa786864a82e9f50a24f703c7b8f521eee760421be9c50ec988442d783e23c8e6caec55","enode":"enode://09fbec10eccc27dfc7cc82ea3ffc15c5d1fff4265c930f0a2a2daaf0baa786864a82e9f50a24f703c7b8f521eee760421be9c50ec988442d783e23c8e6caec55@0.0.0.0:0","listenAddr":"","protocols":{"hive":"\n=========================================================================\nFri Sep 29 21:23:27 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 3efa59\npopulation: 6 (26), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 cd92 | 10 9ea0 (0) fbe2 (0) f1e3 (0) e9bc (0)\n001 1 4659 | 7 7f25 (0) 41de (0) 4659 (0) 461d (0)\n002 1 175e | 6 0688 (0) 02f7 (0) 0a5c (0) 0b07 (0)\n003 1 211b | 1 211b (0)\n004 0 | 0\n============ DEPTH: 5 ==========================================\n005 1 3a26 | 1 3a26 (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 1 3efb | 1 3efb (0)\n=========================================================================","bzz":"PvpZMJ+WirIOBTg28B4Ni0yed3Bjpz6HHKuGwf5qAVk="},"ports":{"discovery":0,"listener":0}},"config":{"services":["pss","bzz"],"id":"09fbec10eccc27dfc7cc82ea3ffc15c5d1fff4265c930f0a2a2daaf0baa786864a82e9f50a24f703c7b8f521eee760421be9c50ec988442d783e23c8e6caec55","name":"node10","private_key":"b27bdea692559a2a77d497ee567e972e033d4e6e5dfb7c35948a9d231c25b0e0"}}},{"node":{"up":true,"config":{"name":"node11","id":"b74000b69ff5e8cdce944c92b701df83a456a478e22f946870b3acfea1684ef5d382543c6f61f223fd50994e089a8df3bef3232f5fdf3b865649be760a4fe651","private_key":"0a75e7e7dfabf4ee693bfe127221c97eb9b2f4e19d32f7bc836ba253445358d7","services":["pss","bzz"]},"info":{"protocols":{"hive":"\n=========================================================================\nFri Sep 29 21:23:27 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 175e3b\npopulation: 7 (28), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 0 | 11 8564 (0) 9ea0 (0) fbe2 (0) f1e3 (0)\n001 1 5e88 | 8 7f25 (0) 41de (0) 4659 (0) 461d (0)\n002 1 3efa | 4 211b (0) 3a26 (0) 3efb (0) 3efa (0)\n============ DEPTH: 3 ==========================================\n003 5 02f7 0688 0b07 0a5c | 5 0688 (0) 02f7 (0) 0a5c (0) 0b07 (0)\n004 0 | 0\n005 0 | 0\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"F147u/xwtEOt+Ic4ZIWkwBcd8m7a97RMMuQw/De4MNM="},"listenAddr":"","ports":{"listener":0,"discovery":0},"ip":"0.0.0.0","name":"node11","id":"b74000b69ff5e8cdce944c92b701df83a456a478e22f946870b3acfea1684ef5d382543c6f61f223fd50994e089a8df3bef3232f5fdf3b865649be760a4fe651","enode":"enode://b74000b69ff5e8cdce944c92b701df83a456a478e22f946870b3acfea1684ef5d382543c6f61f223fd50994e089a8df3bef3232f5fdf3b865649be760a4fe651@0.0.0.0:0"}}},{"node":{"up":true,"config":{"id":"633a8d6240ea0bd01ed55c8caf4a31443545e018130c3a1a21c51e074cc7a9262a6ebb165723afeb339e426a05c3364b4c3dae908df33f0c02a6d44451d52d5b","name":"node12","private_key":"1557c4754c71e6468fae0c7d0e1b5af2cf70511ed2d5d9b0bc276315a4c8f922","services":["pss","bzz"]},"info":{"listenAddr":"","protocols":{"bzz":"Xog94jGLQ1UUDtsApg23ndwW4Nq+xHzTTiorF14ZhxE=","hive":"\n=========================================================================\nFri Sep 29 21:23:27 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 5e883d\npopulation: 8 (31), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 8564 | 14 8b72 (0) 8939 (0) 8144 (0) 8564 (0)\n001 2 175e 0a5c | 10 211b (0) 3efa (0) 3efb (0) 3a26 (0)\n002 1 7f25 | 1 7f25 (0)\n003 1 41de | 3 41de (0) 4659 (0) 461d (0)\n004 1 55b8 | 1 55b8 (0)\n============ DEPTH: 5 ==========================================\n005 2 58eb 59b2 | 2 58eb (0) 59b2 (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"discovery":0,"listener":0},"id":"633a8d6240ea0bd01ed55c8caf4a31443545e018130c3a1a21c51e074cc7a9262a6ebb165723afeb339e426a05c3364b4c3dae908df33f0c02a6d44451d52d5b","ip":"0.0.0.0","name":"node12","enode":"enode://633a8d6240ea0bd01ed55c8caf4a31443545e018130c3a1a21c51e074cc7a9262a6ebb165723afeb339e426a05c3364b4c3dae908df33f0c02a6d44451d52d5b@0.0.0.0:0"}}},{"node":{"info":{"protocols":{"bzz":"ClzHluczsGhmtn7DZS5BoDoMA3B/7Va3Z8pcv+OCizU=","hive":"\n=========================================================================\nFri Sep 29 21:23:27 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 0a5cc7\npopulation: 8 (31), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 8144 | 14 e9bc (0) ea5a (0) fbe2 (0) f1e3 (0)\n001 1 5e88 | 8 7f25 (0) 41de (0) 4659 (0) 461d (0)\n002 1 211b | 4 211b (0) 3efa (0) 3efb (0) 3a26 (0)\n003 1 175e | 1 175e (0)\n004 2 0688 02f7 | 2 0688 (0) 02f7 (0)\n============ DEPTH: 5 ==========================================\n005 1 0c14 | 1 0c14 (0)\n006 0 | 0\n007 1 0b07 | 1 0b07 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"listenAddr":"","ports":{"listener":0,"discovery":0},"ip":"0.0.0.0","id":"7009eea5c5600d6aa87ed5fa951c486f7b0d260ca1a07dcb057c3cb9afe7e964a0b825001e9ffa6919f382643d4a5fd3bc40d3d413748f2f9964939ae86e55ce","name":"node13","enode":"enode://7009eea5c5600d6aa87ed5fa951c486f7b0d260ca1a07dcb057c3cb9afe7e964a0b825001e9ffa6919f382643d4a5fd3bc40d3d413748f2f9964939ae86e55ce@0.0.0.0:0"},"config":{"name":"node13","private_key":"d2b18f4edef23f629bc5624a36ac1d58f59207bf7de0b19220f90fc3c64b5a61","id":"7009eea5c5600d6aa87ed5fa951c486f7b0d260ca1a07dcb057c3cb9afe7e964a0b825001e9ffa6919f382643d4a5fd3bc40d3d413748f2f9964939ae86e55ce","services":["pss","bzz"]},"up":true}},{"node":{"info":{"ip":"0.0.0.0","name":"node14","id":"7410ddeba8db7202f93b250ad4a346c022670cffd8866223ab62260103b6f0938ad001ec054cca00cf9cf7e78c25be1b83cbcec868ab10f9f7628ae05d10ad8b","enode":"enode://7410ddeba8db7202f93b250ad4a346c022670cffd8866223ab62260103b6f0938ad001ec054cca00cf9cf7e78c25be1b83cbcec868ab10f9f7628ae05d10ad8b@0.0.0.0:0","listenAddr":"","protocols":{"hive":"\n=========================================================================\nFri Sep 29 21:23:27 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 81449f\npopulation: 6 (31), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 0a5c | 18 7f25 (0) 41de (0) 4659 (0) 461d (0)\n001 1 e9bc | 9 e9bc (0) ea5a (0) fbe2 (0) f1e3 (0)\n002 0 | 0\n003 1 9ea0 | 1 9ea0 (0)\n============ DEPTH: 4 ==========================================\n004 2 8939 8b72 | 2 8939 (0) 8b72 (0)\n005 1 8564 | 1 8564 (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"gUSfuFCnwnE3hLyTjaPhVz2S6T39iBmejYd3RrbCYK8="},"ports":{"listener":0,"discovery":0}},"config":{"name":"node14","private_key":"48fe56dfc63a454ab004e7a5dc7938e29694377b6bcc27d1c19d8a72349a8c2d","id":"7410ddeba8db7202f93b250ad4a346c022670cffd8866223ab62260103b6f0938ad001ec054cca00cf9cf7e78c25be1b83cbcec868ab10f9f7628ae05d10ad8b","services":["pss","bzz"]},"up":true}},{"node":{"up":true,"info":{"enode":"enode://d303661d4146e4f2c9342d722074c545b99b80a79e7361e83ce55f5710369eccddfecd2ae1a1f8155f7aabb1675b44efbc4c070c6b3bf4a26ade342d383d4c32@0.0.0.0:0","name":"node15","ip":"0.0.0.0","id":"d303661d4146e4f2c9342d722074c545b99b80a79e7361e83ce55f5710369eccddfecd2ae1a1f8155f7aabb1675b44efbc4c070c6b3bf4a26ade342d383d4c32","ports":{"discovery":0,"listener":0},"protocols":{"bzz":"i3LSqGZdVFquQ7MXog9Rr4A1eykOgmgiMJ2aHcZ6RHA=","hive":"\n=========================================================================\nFri Sep 29 21:23:27 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 8b72d2\npopulation: 7 (31), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 3efb 02f7 | 18 7f25 (0) 41de (0) 4659 (0) 461d (0)\n001 1 e9bc | 9 e9bc (0) ea5a (0) fbe2 (0) f1e3 (0)\n002 0 | 0\n003 1 9ea0 | 1 9ea0 (0)\n============ DEPTH: 4 ==========================================\n004 2 8564 8144 | 2 8564 (0) 8144 (0)\n005 0 | 0\n006 1 8939 | 1 8939 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"listenAddr":""},"config":{"id":"d303661d4146e4f2c9342d722074c545b99b80a79e7361e83ce55f5710369eccddfecd2ae1a1f8155f7aabb1675b44efbc4c070c6b3bf4a26ade342d383d4c32","name":"node15","private_key":"9155d38d2a2bbe1e5239f9993d96a350182e3840813436e23e1f2a4a9a32b7d9","services":["pss","bzz"]}}},{"node":{"config":{"services":["pss","bzz"],"id":"8fac0d980714c5968e57d62c36c315b8dd85eae37b84f9c6afdc9db6ebfe7a38af4ed8aac9ab93939f38b817902744f568397e51c51bca13f0c03c4d40121b24","name":"node16","private_key":"e60772916c9d248e3a3819de52aacdd4008412aab20a457e88e764752679b8f8"},"info":{"name":"node16","ip":"0.0.0.0","id":"8fac0d980714c5968e57d62c36c315b8dd85eae37b84f9c6afdc9db6ebfe7a38af4ed8aac9ab93939f38b817902744f568397e51c51bca13f0c03c4d40121b24","enode":"enode://8fac0d980714c5968e57d62c36c315b8dd85eae37b84f9c6afdc9db6ebfe7a38af4ed8aac9ab93939f38b817902744f568397e51c51bca13f0c03c4d40121b24@0.0.0.0:0","listenAddr":"","protocols":{"bzz":"Ave2JA08OZBVnSljVbuG9AFi/uekXC4JLrkCdyZuy9g=","hive":"\n=========================================================================\nFri Sep 29 21:23:27 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 02f7b6\npopulation: 8 (31), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 8b72 | 14 dcf5 (0) de8f (0) cd92 (0) c6b6 (0)\n001 1 7f25 | 8 7f25 (0) 41de (0) 4659 (0) 461d (0)\n002 1 3a26 | 4 211b (0) 3efa (0) 3efb (0) 3a26 (0)\n003 1 175e | 1 175e (0)\n============ DEPTH: 4 ==========================================\n004 3 0a5c 0b07 0c14 | 3 0a5c (0) 0b07 (0) 0c14 (0)\n005 1 0688 | 1 0688 (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"listener":0,"discovery":0}},"up":true}},{"node":{"up":true,"info":{"listenAddr":"","protocols":{"bzz":"OiaKDbfosx1LNi7LWY8+VJoqpZOSWRtNLyujfmzrcrM=","hive":"\n=========================================================================\nFri Sep 29 21:23:27 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 3a268a\npopulation: 7 (31), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 8939 | 14 dcf5 (0) de8f (0) cd92 (0) c6b6 (0)\n001 1 4659 | 8 7f25 (0) 41de (0) 4659 (0) 461d (0)\n002 2 0b07 02f7 | 6 175e (0) 0a5c (0) 0b07 (0) 0c14 (0)\n003 1 211b | 1 211b (0)\n004 0 | 0\n============ DEPTH: 5 ==========================================\n005 2 3efa 3efb | 2 3efa (0) 3efb (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"discovery":0,"listener":0},"ip":"0.0.0.0","id":"cdfcfd49b6f27643da799946e2b6d4c84d9feb485278ca9ddb1dcd72f87ce7ffad55c6ec3719069815ba2758a64bd8915d964540f44eda8104d5f7a19691b2af","name":"node17","enode":"enode://cdfcfd49b6f27643da799946e2b6d4c84d9feb485278ca9ddb1dcd72f87ce7ffad55c6ec3719069815ba2758a64bd8915d964540f44eda8104d5f7a19691b2af@0.0.0.0:0"},"config":{"id":"cdfcfd49b6f27643da799946e2b6d4c84d9feb485278ca9ddb1dcd72f87ce7ffad55c6ec3719069815ba2758a64bd8915d964540f44eda8104d5f7a19691b2af","name":"node17","private_key":"e7f27ccf343d2124211ba980dfe8ee7e774a5956268a25522347bb3be99bf38e","services":["pss","bzz"]}}},{"node":{"up":true,"config":{"private_key":"0e9cb88a7d70a04f0780ea51e001aabda0830f504e29e31c69d859acce0a9019","name":"node18","id":"8c5864a90b102a241d675841ac91c66ddecc73eeca039ef005ce63ccc0bbd13c26c3c834a216efb9dc5acb2401f5ef1b81eff02f5b9a3eef332748a5df53cea2","services":["pss","bzz"]},"info":{"name":"node18","ip":"0.0.0.0","id":"8c5864a90b102a241d675841ac91c66ddecc73eeca039ef005ce63ccc0bbd13c26c3c834a216efb9dc5acb2401f5ef1b81eff02f5b9a3eef332748a5df53cea2","enode":"enode://8c5864a90b102a241d675841ac91c66ddecc73eeca039ef005ce63ccc0bbd13c26c3c834a216efb9dc5acb2401f5ef1b81eff02f5b9a3eef332748a5df53cea2@0.0.0.0:0","protocols":{"hive":"\n=========================================================================\nFri Sep 29 21:23:27 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 893963\npopulation: 7 (31), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 3a26 | 18 7f25 (0) 41de (0) 4659 (0) 461d (0)\n001 2 f1e3 e9bc | 9 dcf5 (0) de8f (0) cd92 (0) c6b6 (0)\n002 0 | 0\n003 1 9ea0 | 1 9ea0 (0)\n============ DEPTH: 4 ==========================================\n004 2 8144 8564 | 2 8144 (0) 8564 (0)\n005 0 | 0\n006 1 8b72 | 1 8b72 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"iTljYAjsLuwiK9SQq4a0L57x/ufkGjLHDetnaSDDRUo="},"listenAddr":"","ports":{"listener":0,"discovery":0}}}},{"node":{"info":{"ip":"0.0.0.0","id":"2870cbae6af3e8083eaa5003b310a4f18f3c6e41f1cad27ba3eaf8b129f20eb40ce7cd7c54c93556dda9a79ce0d88355c0d3d9d41ef1d479eb63711d13a49b53","name":"node19","enode":"enode://2870cbae6af3e8083eaa5003b310a4f18f3c6e41f1cad27ba3eaf8b129f20eb40ce7cd7c54c93556dda9a79ce0d88355c0d3d9d41ef1d479eb63711d13a49b53@0.0.0.0:0","listenAddr":"","protocols":{"hive":"\n=========================================================================\nFri Sep 29 21:23:27 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 8564a5\npopulation: 8 (31), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 5e88 58eb | 18 7f25 (0) 461d (0) 4659 (0) 41de (0)\n001 2 de8f dcf5 | 9 dcf5 (0) de8f (0) cd92 (0) c6b6 (0)\n002 0 | 0\n003 1 9ea0 | 1 9ea0 (0)\n============ DEPTH: 4 ==========================================\n004 2 8b72 8939 | 2 8b72 (0) 8939 (0)\n005 1 8144 | 1 8144 (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"hWSlN1KqPn7bjgnDrWG3Zc5avSrZxctjv6A2kw1t4kQ="},"ports":{"discovery":0,"listener":0}},"config":{"services":["pss","bzz"],"name":"node19","private_key":"cf8362e06e18a783f7e20baf956d40e2ea4a204ec868f8d34909802af222e997","id":"2870cbae6af3e8083eaa5003b310a4f18f3c6e41f1cad27ba3eaf8b129f20eb40ce7cd7c54c93556dda9a79ce0d88355c0d3d9d41ef1d479eb63711d13a49b53"},"up":true}},{"node":{"info":{"id":"e20125c0ce3cafd1e19eeff2630fd132539e084b2d2a8c30fcf0202a89623885d9cfdf48f4c3cb04f1ba6abda8f1e69d6f57571f02d8a6e2bc508aa4046d37ed","ip":"0.0.0.0","name":"node20","enode":"enode://e20125c0ce3cafd1e19eeff2630fd132539e084b2d2a8c30fcf0202a89623885d9cfdf48f4c3cb04f1ba6abda8f1e69d6f57571f02d8a6e2bc508aa4046d37ed@0.0.0.0:0","listenAddr":"","protocols":{"hive":"\n=========================================================================\nFri Sep 29 21:23:27 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 9ea072\npopulation: 13 (31), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 211b 55b8 58eb | 18 3a26 (0) 3efb (0) 3efa (0) 211b (0)\n001 6 ea5a fbe2 cd92 c6b6 | 9 dcf5 (0) de8f (0) cd92 (0) c6b6 (0)\n002 0 | 0\n============ DEPTH: 3 ==========================================\n003 4 8b72 8939 8144 8564 | 4 8b72 (0) 8939 (0) 8144 (0) 8564 (0)\n004 0 | 0\n005 0 | 0\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"nqByFVUoqsqP73olryYTSJi2Wu0kZNuqOXI1y5b3zRU="},"ports":{"discovery":0,"listener":0}},"config":{"services":["pss","bzz"],"name":"node20","private_key":"9a63fae9e77f9cfdc30f4747a939ba44e85824560d98b49047bfa8f4156d426c","id":"e20125c0ce3cafd1e19eeff2630fd132539e084b2d2a8c30fcf0202a89623885d9cfdf48f4c3cb04f1ba6abda8f1e69d6f57571f02d8a6e2bc508aa4046d37ed"},"up":true}},{"node":{"up":true,"info":{"enode":"enode://65a6264a6515ca7a4dadd911be9ecacce0f810ec2c213f27f1b982bdea6c8bad09396f2e2d502aa999880ee4028223ac14b8be966f67ffd92fa48a51ea2454ed@0.0.0.0:0","id":"65a6264a6515ca7a4dadd911be9ecacce0f810ec2c213f27f1b982bdea6c8bad09396f2e2d502aa999880ee4028223ac14b8be966f67ffd92fa48a51ea2454ed","ip":"0.0.0.0","name":"node21","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"WOusR8iE53BJpsnIUf+x50Yi0nvo4wEX8fd1ORrCdxc=","hive":"\n=========================================================================\nFri Sep 29 21:23:27 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 58ebac\npopulation: 8 (31), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 8564 9ea0 | 14 dcf5 (0) de8f (0) cd92 (0) c6b6 (0)\n001 1 0c14 | 10 3a26 (0) 3efb (0) 3efa (0) 211b (0)\n002 1 7f25 | 1 7f25 (0)\n003 1 41de | 3 41de (0) 461d (0) 4659 (0)\n004 1 55b8 | 1 55b8 (0)\n============ DEPTH: 5 ==========================================\n005 1 5e88 | 1 5e88 (0)\n006 0 | 0\n007 1 59b2 | 1 59b2 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}},"config":{"services":["pss","bzz"],"name":"node21","private_key":"748efd85864661c429fd70a74bc32f1d81685bd81927c1499dbd93993dc27cad","id":"65a6264a6515ca7a4dadd911be9ecacce0f810ec2c213f27f1b982bdea6c8bad09396f2e2d502aa999880ee4028223ac14b8be966f67ffd92fa48a51ea2454ed"}}},{"node":{"config":{"services":["pss","bzz"],"id":"2be0cb6fc267fba8bf3c2c5ce7f0e7092939af7c8a4db19219ff847e3c8e3d40f4965c1ce905c88bc5182bbfad7163072242ef398b9f67f816da43f660cb7cbf","name":"node22","private_key":"fed7bc6fd67e331e642253e604215ba088daa48a1b84979699ad770c09b909dd"},"info":{"ports":{"discovery":0,"listener":0},"protocols":{"bzz":"DBRWJXirl5bGNdHltxO8lmNB9udCrNSoqTpSTK3Waes=","hive":"\n=========================================================================\nFri Sep 29 21:23:27 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 0c1456\npopulation: 10 (31), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 dcf5 | 14 dcf5 (0) de8f (0) cd92 (0) c6b6 (0)\n001 2 4659 58eb | 8 7f25 (0) 41de (0) 461d (0) 4659 (0)\n002 2 3efb 211b | 4 3a26 (0) 3efa (0) 3efb (0) 211b (0)\n003 1 175e | 1 175e (0)\n004 2 0688 02f7 | 2 02f7 (0) 0688 (0)\n============ DEPTH: 5 ==========================================\n005 2 0b07 0a5c | 2 0a5c (0) 0b07 (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"listenAddr":"","enode":"enode://2be0cb6fc267fba8bf3c2c5ce7f0e7092939af7c8a4db19219ff847e3c8e3d40f4965c1ce905c88bc5182bbfad7163072242ef398b9f67f816da43f660cb7cbf@0.0.0.0:0","ip":"0.0.0.0","name":"node22","id":"2be0cb6fc267fba8bf3c2c5ce7f0e7092939af7c8a4db19219ff847e3c8e3d40f4965c1ce905c88bc5182bbfad7163072242ef398b9f67f816da43f660cb7cbf"},"up":true}},{"node":{"config":{"name":"node23","id":"9517123df57cd87ee0a5ae86a275af4140cbf52b43a57a439408cbd33e2defaee2e0f8298b2e2cb9aad356a321729a9160320e4edc05f2021e32518e5d4593fc","private_key":"c61c4e9235825e60f2d8c57169e7d1913f45b057f298ba8fb05d51515e92a902","services":["pss","bzz"]},"info":{"enode":"enode://9517123df57cd87ee0a5ae86a275af4140cbf52b43a57a439408cbd33e2defaee2e0f8298b2e2cb9aad356a321729a9160320e4edc05f2021e32518e5d4593fc@0.0.0.0:0","id":"9517123df57cd87ee0a5ae86a275af4140cbf52b43a57a439408cbd33e2defaee2e0f8298b2e2cb9aad356a321729a9160320e4edc05f2021e32518e5d4593fc","ip":"0.0.0.0","name":"node23","ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"hive":"\n=========================================================================\nFri Sep 29 21:23:27 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 46599a\npopulation: 8 (31), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 dcf5 | 14 8564 (0) 8144 (0) 8b72 (0) 8939 (0)\n001 3 3a26 3efa 0c14 | 10 3a26 (0) 3efb (0) 3efa (0) 211b (0)\n002 1 7f25 | 1 7f25 (0)\n003 1 59b2 | 4 59b2 (0) 58eb (0) 5e88 (0) 55b8 (0)\n004 0 | 0\n============ DEPTH: 5 ==========================================\n005 1 41de | 1 41de (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 1 461d | 1 461d (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"RlmaqWcVViY6XlgYV1uKEufHVaRPnax4c8HEjzPBRl4="}},"up":true}},{"node":{"up":true,"info":{"enode":"enode://4169f023f910388983026973c136f36f3d97241e96b839583da84c74a5eef50a8c0cc7181fb2c849354fe03d70df5f2231f107ca14616a4597d058facd2da8c7@0.0.0.0:0","ip":"0.0.0.0","name":"node24","id":"4169f023f910388983026973c136f36f3d97241e96b839583da84c74a5eef50a8c0cc7181fb2c849354fe03d70df5f2231f107ca14616a4597d058facd2da8c7","ports":{"listener":0,"discovery":0},"protocols":{"bzz":"3PXRE93znlFqOHGjGEPaPNd0Daoqj0gnJlo9m/qjtAI=","hive":"\n=========================================================================\nFri Sep 29 21:23:27 UTC 2017 KΛÐΞMLIΛ hive: queen's address: dcf5d1\npopulation: 9 (31), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 0c14 4659 7f25 | 18 3a26 (0) 3efb (0) 3efa (0) 211b (0)\n001 2 8564 9ea0 | 5 8564 (0) 8144 (0) 8b72 (0) 8939 (0)\n002 0 | 4 e9bc (0) ea5a (0) fbe2 (0) f1e3 (0)\n============ DEPTH: 3 ==========================================\n003 3 cd92 c6b6 c386 | 3 cd92 (0) c6b6 (0) c386 (0)\n004 0 | 0\n005 0 | 0\n006 1 de8f | 1 de8f (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"listenAddr":""},"config":{"name":"node24","private_key":"53704ffbabad329a9032a58cd7ec012499b0a521bb0300e1d7160d4e5d1220fd","id":"4169f023f910388983026973c136f36f3d97241e96b839583da84c74a5eef50a8c0cc7181fb2c849354fe03d70df5f2231f107ca14616a4597d058facd2da8c7","services":["pss","bzz"]}}},{"node":{"info":{"protocols":{"hive":"\n=========================================================================\nFri Sep 29 21:23:27 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 7f25ae\npopulation: 11 (31), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 dcf5 fbe2 | 14 8564 (0) 8144 (0) 8b72 (0) 8939 (0)\n001 2 211b 02f7 | 10 3a26 (0) 3efb (0) 3efa (0) 211b (0)\n============ DEPTH: 2 ==========================================\n002 7 55b8 5e88 59b2 58eb | 7 59b2 (0) 58eb (0) 5e88 (0) 55b8 (0)\n003 0 | 0\n004 0 | 0\n005 0 | 0\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"fyWumAtK6sBB2L0XqKQUD3YqynhxDP0vtB+NkdcT5N8="},"listenAddr":"","ports":{"listener":0,"discovery":0},"name":"node25","ip":"0.0.0.0","id":"0f79e2ef69e046888e83eb9f358b16cf7bb9204c31ea1d03de9872f485652407af00787a758d32d3b9440918645a94a0b95efe169bc2a72d8841b2705bdbe4c0","enode":"enode://0f79e2ef69e046888e83eb9f358b16cf7bb9204c31ea1d03de9872f485652407af00787a758d32d3b9440918645a94a0b95efe169bc2a72d8841b2705bdbe4c0@0.0.0.0:0"},"config":{"services":["pss","bzz"],"private_key":"7098a0386bb10a213728ea65f3ca98fd25a31daf3917190f6a1889d350e09674","name":"node25","id":"0f79e2ef69e046888e83eb9f358b16cf7bb9204c31ea1d03de9872f485652407af00787a758d32d3b9440918645a94a0b95efe169bc2a72d8841b2705bdbe4c0"},"up":true}},{"node":{"up":true,"config":{"services":["pss","bzz"],"private_key":"e967b2c9db78764c1ce024423c48e170b68fb6232c313a32133faf4936e2c114","name":"node26","id":"a33863af3dfd52d157d9b0c348aa3baa3e5406a5e1504ef398379fafd5c4699feee620d1210c61ab583610e4c951c054a7f715c33ba9a5c10ad15cb8d0ee1b1b"},"info":{"ports":{"discovery":0,"listener":0},"listenAddr":"","protocols":{"bzz":"++L3MbS82/hJC6dZmgEfVh7GpGyVvJo07/rynJEIXAk=","hive":"\n=========================================================================\nFri Sep 29 21:23:27 UTC 2017 KΛÐΞMLIΛ hive: queen's address: fbe2f7\npopulation: 6 (31), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 7f25 | 18 3a26 (0) 3efb (0) 3efa (0) 211b (0)\n001 1 9ea0 | 5 8b72 (0) 8939 (0) 8564 (0) 8144 (0)\n002 1 cd92 | 5 cd92 (0) c6b6 (0) c386 (0) de8f (0)\n============ DEPTH: 3 ==========================================\n003 2 e9bc ea5a | 2 ea5a (0) e9bc (0)\n004 1 f1e3 | 1 f1e3 (0)\n005 0 | 0\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"enode":"enode://a33863af3dfd52d157d9b0c348aa3baa3e5406a5e1504ef398379fafd5c4699feee620d1210c61ab583610e4c951c054a7f715c33ba9a5c10ad15cb8d0ee1b1b@0.0.0.0:0","ip":"0.0.0.0","id":"a33863af3dfd52d157d9b0c348aa3baa3e5406a5e1504ef398379fafd5c4699feee620d1210c61ab583610e4c951c054a7f715c33ba9a5c10ad15cb8d0ee1b1b","name":"node26"}}},{"node":{"config":{"services":["pss","bzz"],"name":"node27","id":"2624a85e506a0881abd273f0e4a9f65268afddc668b8d303582ebe0b634648e07ee4d1e7587862b5ef2cc6f90d8b404e4fea8197378a33f3184083c86c25b060","private_key":"f8cf717ad5b26578e58a97eddc6074cebb814cdaf3f4144acbafcce51ccbd249"},"info":{"listenAddr":"","protocols":{"hive":"\n=========================================================================\nFri Sep 29 21:23:27 UTC 2017 KΛÐΞMLIΛ hive: queen's address: f1e371\npopulation: 7 (31), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 3efb | 18 3a26 (0) 3efb (0) 3efa (0) 211b (0)\n001 1 8939 | 5 8939 (0) 8b72 (0) 8564 (0) 8144 (0)\n002 2 c386 de8f | 5 cd92 (0) c6b6 (0) c386 (0) dcf5 (0)\n============ DEPTH: 3 ==========================================\n003 2 e9bc ea5a | 2 ea5a (0) e9bc (0)\n004 1 fbe2 | 1 fbe2 (0)\n005 0 | 0\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"8eNxNpH5CIxyKVZYt+iH2DBYxmhJWDDGPAJBcWycroA="},"ports":{"discovery":0,"listener":0},"name":"node27","ip":"0.0.0.0","id":"2624a85e506a0881abd273f0e4a9f65268afddc668b8d303582ebe0b634648e07ee4d1e7587862b5ef2cc6f90d8b404e4fea8197378a33f3184083c86c25b060","enode":"enode://2624a85e506a0881abd273f0e4a9f65268afddc668b8d303582ebe0b634648e07ee4d1e7587862b5ef2cc6f90d8b404e4fea8197378a33f3184083c86c25b060@0.0.0.0:0"},"up":true}},{"node":{"up":true,"info":{"listenAddr":"","protocols":{"bzz":"3o8RRiG1Olpo38GHBgDGC/mRKtTTZFjlJgarJ6bXw/o=","hive":"\n=========================================================================\nFri Sep 29 21:23:27 UTC 2017 KΛÐΞMLIΛ hive: queen's address: de8f11\npopulation: 7 (31), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 461d | 18 3a26 (0) 3efb (0) 3efa (0) 211b (0)\n001 1 8564 | 5 8564 (0) 8144 (0) 8939 (0) 8b72 (0)\n002 1 f1e3 | 4 ea5a (0) e9bc (0) fbe2 (0) f1e3 (0)\n============ DEPTH: 3 ==========================================\n003 3 c386 c6b6 cd92 | 3 cd92 (0) c6b6 (0) c386 (0)\n004 0 | 0\n005 0 | 0\n006 1 dcf5 | 1 dcf5 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"discovery":0,"listener":0},"id":"5d9cc967ae4136594db226749d415a51ae18c3327fb7e3fb9159bc92c92c9e63984c57f539129ecc393153111dc5115a395329d4333380bfd836ffc48ed5349e","ip":"0.0.0.0","name":"node28","enode":"enode://5d9cc967ae4136594db226749d415a51ae18c3327fb7e3fb9159bc92c92c9e63984c57f539129ecc393153111dc5115a395329d4333380bfd836ffc48ed5349e@0.0.0.0:0"},"config":{"services":["pss","bzz"],"private_key":"e6573973825826d193b5093ec610c34368630376e4e13843e5f2203c3ca88fa9","name":"node28","id":"5d9cc967ae4136594db226749d415a51ae18c3327fb7e3fb9159bc92c92c9e63984c57f539129ecc393153111dc5115a395329d4333380bfd836ffc48ed5349e"}}},{"node":{"up":true,"info":{"ip":"0.0.0.0","name":"node29","id":"b964f0d4cbaf1fac1f0016d7f957fbc4dcc3922224c273ff9e0d5f58770ed80fa4a17528f16d698fb6a3de2906a52ef2befb4e7f1aad960d9e5e72c853f258a6","enode":"enode://b964f0d4cbaf1fac1f0016d7f957fbc4dcc3922224c273ff9e0d5f58770ed80fa4a17528f16d698fb6a3de2906a52ef2befb4e7f1aad960d9e5e72c853f258a6@0.0.0.0:0","listenAddr":"","protocols":{"bzz":"Rh3Bh8ORH9EoKfsxaLaBNeMgh3HThTJENOjKfs9ysuI=","hive":"\n=========================================================================\nFri Sep 29 21:23:27 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 461dc1\npopulation: 7 (31), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 de8f c6b6 | 14 8144 (0) 8564 (0) 8939 (0) 8b72 (0)\n001 1 3efb | 10 3a26 (0) 3efb (0) 3efa (0) 211b (0)\n002 1 7f25 | 1 7f25 (0)\n003 1 59b2 | 4 59b2 (0) 58eb (0) 5e88 (0) 55b8 (0)\n004 0 | 0\n============ DEPTH: 5 ==========================================\n005 1 41de | 1 41de (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 1 4659 | 1 4659 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"listener":0,"discovery":0}},"config":{"name":"node29","id":"b964f0d4cbaf1fac1f0016d7f957fbc4dcc3922224c273ff9e0d5f58770ed80fa4a17528f16d698fb6a3de2906a52ef2befb4e7f1aad960d9e5e72c853f258a6","private_key":"0ff9df0f439480bc31f8a3ae593af2662bad0f5bd4e0c3e87839af326929de07","services":["pss","bzz"]}}},{"node":{"up":true,"config":{"services":["pss","bzz"],"id":"7a1a4a9ab567d1e4f93213126558103ec26094795b9972b433085b548b71c6b1a0a8652339a9e01fb39ac9b3b13ed1d9c3359b03d7e8d39417423990b627d20c","name":"node30","private_key":"1daf1094602b9234a1651a8ba6013a807d9c0d56339c784d618e2c6705b65e23"},"info":{"protocols":{"bzz":"xradhW7IrBgitKHVT407xEgxvNIPu1yPjGe2izNUH+k=","hive":"\n=========================================================================\nFri Sep 29 21:23:27 UTC 2017 KΛÐΞMLIΛ hive: queen's address: c6b69d\npopulation: 7 (31), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 461d | 18 3a26 (0) 3efb (0) 3efa (0) 211b (0)\n001 1 9ea0 | 5 8564 (0) 8144 (0) 8939 (0) 8b72 (0)\n002 1 ea5a | 4 f1e3 (0) fbe2 (0) e9bc (0) ea5a (0)\n003 2 dcf5 de8f | 2 dcf5 (0) de8f (0)\n============ DEPTH: 4 ==========================================\n004 1 cd92 | 1 cd92 (0)\n005 1 c386 | 1 c386 (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"listenAddr":"","ports":{"listener":0,"discovery":0},"id":"7a1a4a9ab567d1e4f93213126558103ec26094795b9972b433085b548b71c6b1a0a8652339a9e01fb39ac9b3b13ed1d9c3359b03d7e8d39417423990b627d20c","ip":"0.0.0.0","name":"node30","enode":"enode://7a1a4a9ab567d1e4f93213126558103ec26094795b9972b433085b548b71c6b1a0a8652339a9e01fb39ac9b3b13ed1d9c3359b03d7e8d39417423990b627d20c@0.0.0.0:0"}}},{"node":{"up":true,"info":{"enode":"enode://21278d7b532622901447d27ae7bea917fc3b104ec7d54c402ebfbc9587f3351c5d9a5bc11b088170e06341849533bcfe622509ea1d34d80771848453bdb64158@0.0.0.0:0","id":"21278d7b532622901447d27ae7bea917fc3b104ec7d54c402ebfbc9587f3351c5d9a5bc11b088170e06341849533bcfe622509ea1d34d80771848453bdb64158","ip":"0.0.0.0","name":"node31","ports":{"listener":0,"discovery":0},"protocols":{"bzz":"6lrotjn6gNtoTHdNgUt+nP8M+WIkJ9rjUjnMhMG32rw=","hive":"\n=========================================================================\nFri Sep 29 21:23:27 UTC 2017 KΛÐΞMLIΛ hive: queen's address: ea5ae8\npopulation: 6 (31), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 0b07 | 18 7f25 (0) 59b2 (0) 58eb (0) 5e88 (0)\n001 1 9ea0 | 5 8b72 (0) 8939 (0) 8564 (0) 8144 (0)\n002 1 c6b6 | 5 dcf5 (0) de8f (0) cd92 (0) c386 (0)\n============ DEPTH: 3 ==========================================\n003 2 fbe2 f1e3 | 2 f1e3 (0) fbe2 (0)\n004 0 | 0\n005 0 | 0\n006 1 e9bc | 1 e9bc (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"listenAddr":""},"config":{"id":"21278d7b532622901447d27ae7bea917fc3b104ec7d54c402ebfbc9587f3351c5d9a5bc11b088170e06341849533bcfe622509ea1d34d80771848453bdb64158","name":"node31","private_key":"376cc1c769c48c4a04f3f1447fe31112cdbc8d898266a338f6675906511bc9c6","services":["pss","bzz"]}}},{"node":{"up":true,"config":{"services":["pss","bzz"],"name":"node32","private_key":"6a9a93cae21630926926ece339463ca165823f499f47d45632dbe1a49a84257c","id":"f6159d1c9d9120ae52e77a09d82f0b86bd74b88062323033700a661039719ee100d758eaea57ce03398384c3371c8023bf6a69a4788186f657e987938be8f305"},"info":{"protocols":{"bzz":"CwehPxIxZZQBP7IgoUkQya7JRGJ0tun4naO/H1cyYks=","hive":"\n=========================================================================\nFri Sep 29 21:23:27 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 0b07a1\npopulation: 8 (31), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 ea5a | 14 8b72 (0) 8939 (0) 8564 (0) 8144 (0)\n001 1 41de | 8 7f25 (0) 59b2 (0) 58eb (0) 5e88 (0)\n002 1 3a26 | 4 3a26 (0) 3efb (0) 3efa (0) 211b (0)\n003 1 175e | 1 175e (0)\n004 2 02f7 0688 | 2 02f7 (0) 0688 (0)\n============ DEPTH: 5 ==========================================\n005 1 0c14 | 1 0c14 (0)\n006 0 | 0\n007 1 0a5c | 1 0a5c (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"listenAddr":"","ports":{"listener":0,"discovery":0},"id":"f6159d1c9d9120ae52e77a09d82f0b86bd74b88062323033700a661039719ee100d758eaea57ce03398384c3371c8023bf6a69a4788186f657e987938be8f305","ip":"0.0.0.0","name":"node32","enode":"enode://f6159d1c9d9120ae52e77a09d82f0b86bd74b88062323033700a661039719ee100d758eaea57ce03398384c3371c8023bf6a69a4788186f657e987938be8f305@0.0.0.0:0"}}}],"conns":[{"one":"44b0032c765d307d53ff64c7c86a0409b119b87d1ef5007c37a1663beac3fa4ddb092c06dd0c0ffe05505928a578207968afad2204db317a418da617ca132948","other":"3d27bc8fb22ad60ca25a70734e1d87fb7ab8105f5c95e9ae21922eb651076bbb331b3b84df907edb4fae23f2a722c77a6dd40f5fb926f909477611cae3773610","up":true},{"up":true,"one":"aed42225cae33605337d1c034564b46cad9f2cb17ce0f0b91c3f3b8f8f8c0e14357d6d6323ffe1f5f50931394d49c9ef589e4f2251f1bdc5c8e45d7c10f9b1e6","other":"af45ddac579286a5850ea494b3e76c1fe116b44de10f183a55ac1eced6eb34682f35eca605dd5b32015645e0e7527090d956236fdeade90b8cc920c54992d161"},{"up":true,"other":"fcdcb9c138c3bdc51b6280a1224419097c4fb188867ca381ac9b92ab08f9fdef0c6267d9ce9fa53944e39cf1b76ce6bf3b17272f97a457649bff6a838eccbf69","one":"f6159d1c9d9120ae52e77a09d82f0b86bd74b88062323033700a661039719ee100d758eaea57ce03398384c3371c8023bf6a69a4788186f657e987938be8f305"},{"up":true,"other":"9456ce63934b1f648d870d6d2e71634a2ec78df8ccb6c83a364e656b4fe280a9273cccb92bfac7996ed1e6351963e076f3fe6fb89b95c866cc072c8d31775388","one":"fcdcb9c138c3bdc51b6280a1224419097c4fb188867ca381ac9b92ab08f9fdef0c6267d9ce9fa53944e39cf1b76ce6bf3b17272f97a457649bff6a838eccbf69"},{"other":"275252d736821f456466bca13738d5e62ce93dec8bbc26c9e9f11d399e2ae83d8b540797322215c859993389082ccf2d4da69fee1193e31fb225e39961780c2c","one":"7405baadb8ddcc559dc29f72e5c8a85f539c7836675eac274f043acc3bdb378faf91feab452af20388f4e1cf187a47e5e93fa232da007c9aa6ee6155fdd3329d","up":true},{"up":true,"other":"09fbec10eccc27dfc7cc82ea3ffc15c5d1fff4265c930f0a2a2daaf0baa786864a82e9f50a24f703c7b8f521eee760421be9c50ec988442d783e23c8e6caec55","one":"275252d736821f456466bca13738d5e62ce93dec8bbc26c9e9f11d399e2ae83d8b540797322215c859993389082ccf2d4da69fee1193e31fb225e39961780c2c"},{"other":"b74000b69ff5e8cdce944c92b701df83a456a478e22f946870b3acfea1684ef5d382543c6f61f223fd50994e089a8df3bef3232f5fdf3b865649be760a4fe651","one":"09fbec10eccc27dfc7cc82ea3ffc15c5d1fff4265c930f0a2a2daaf0baa786864a82e9f50a24f703c7b8f521eee760421be9c50ec988442d783e23c8e6caec55","up":true},{"one":"b74000b69ff5e8cdce944c92b701df83a456a478e22f946870b3acfea1684ef5d382543c6f61f223fd50994e089a8df3bef3232f5fdf3b865649be760a4fe651","other":"633a8d6240ea0bd01ed55c8caf4a31443545e018130c3a1a21c51e074cc7a9262a6ebb165723afeb339e426a05c3364b4c3dae908df33f0c02a6d44451d52d5b","up":true},{"other":"7009eea5c5600d6aa87ed5fa951c486f7b0d260ca1a07dcb057c3cb9afe7e964a0b825001e9ffa6919f382643d4a5fd3bc40d3d413748f2f9964939ae86e55ce","one":"633a8d6240ea0bd01ed55c8caf4a31443545e018130c3a1a21c51e074cc7a9262a6ebb165723afeb339e426a05c3364b4c3dae908df33f0c02a6d44451d52d5b","up":true},{"one":"7009eea5c5600d6aa87ed5fa951c486f7b0d260ca1a07dcb057c3cb9afe7e964a0b825001e9ffa6919f382643d4a5fd3bc40d3d413748f2f9964939ae86e55ce","other":"7410ddeba8db7202f93b250ad4a346c022670cffd8866223ab62260103b6f0938ad001ec054cca00cf9cf7e78c25be1b83cbcec868ab10f9f7628ae05d10ad8b","up":true},{"other":"d303661d4146e4f2c9342d722074c545b99b80a79e7361e83ce55f5710369eccddfecd2ae1a1f8155f7aabb1675b44efbc4c070c6b3bf4a26ade342d383d4c32","one":"7410ddeba8db7202f93b250ad4a346c022670cffd8866223ab62260103b6f0938ad001ec054cca00cf9cf7e78c25be1b83cbcec868ab10f9f7628ae05d10ad8b","up":true},{"up":true,"one":"d303661d4146e4f2c9342d722074c545b99b80a79e7361e83ce55f5710369eccddfecd2ae1a1f8155f7aabb1675b44efbc4c070c6b3bf4a26ade342d383d4c32","other":"8fac0d980714c5968e57d62c36c315b8dd85eae37b84f9c6afdc9db6ebfe7a38af4ed8aac9ab93939f38b817902744f568397e51c51bca13f0c03c4d40121b24"},{"one":"8fac0d980714c5968e57d62c36c315b8dd85eae37b84f9c6afdc9db6ebfe7a38af4ed8aac9ab93939f38b817902744f568397e51c51bca13f0c03c4d40121b24","other":"cdfcfd49b6f27643da799946e2b6d4c84d9feb485278ca9ddb1dcd72f87ce7ffad55c6ec3719069815ba2758a64bd8915d964540f44eda8104d5f7a19691b2af","up":true},{"other":"8c5864a90b102a241d675841ac91c66ddecc73eeca039ef005ce63ccc0bbd13c26c3c834a216efb9dc5acb2401f5ef1b81eff02f5b9a3eef332748a5df53cea2","one":"cdfcfd49b6f27643da799946e2b6d4c84d9feb485278ca9ddb1dcd72f87ce7ffad55c6ec3719069815ba2758a64bd8915d964540f44eda8104d5f7a19691b2af","up":true},{"other":"2870cbae6af3e8083eaa5003b310a4f18f3c6e41f1cad27ba3eaf8b129f20eb40ce7cd7c54c93556dda9a79ce0d88355c0d3d9d41ef1d479eb63711d13a49b53","one":"8c5864a90b102a241d675841ac91c66ddecc73eeca039ef005ce63ccc0bbd13c26c3c834a216efb9dc5acb2401f5ef1b81eff02f5b9a3eef332748a5df53cea2","up":true},{"one":"2870cbae6af3e8083eaa5003b310a4f18f3c6e41f1cad27ba3eaf8b129f20eb40ce7cd7c54c93556dda9a79ce0d88355c0d3d9d41ef1d479eb63711d13a49b53","other":"e20125c0ce3cafd1e19eeff2630fd132539e084b2d2a8c30fcf0202a89623885d9cfdf48f4c3cb04f1ba6abda8f1e69d6f57571f02d8a6e2bc508aa4046d37ed","up":true},{"other":"65a6264a6515ca7a4dadd911be9ecacce0f810ec2c213f27f1b982bdea6c8bad09396f2e2d502aa999880ee4028223ac14b8be966f67ffd92fa48a51ea2454ed","one":"e20125c0ce3cafd1e19eeff2630fd132539e084b2d2a8c30fcf0202a89623885d9cfdf48f4c3cb04f1ba6abda8f1e69d6f57571f02d8a6e2bc508aa4046d37ed","up":true},{"one":"65a6264a6515ca7a4dadd911be9ecacce0f810ec2c213f27f1b982bdea6c8bad09396f2e2d502aa999880ee4028223ac14b8be966f67ffd92fa48a51ea2454ed","other":"2be0cb6fc267fba8bf3c2c5ce7f0e7092939af7c8a4db19219ff847e3c8e3d40f4965c1ce905c88bc5182bbfad7163072242ef398b9f67f816da43f660cb7cbf","up":true},{"up":true,"other":"9517123df57cd87ee0a5ae86a275af4140cbf52b43a57a439408cbd33e2defaee2e0f8298b2e2cb9aad356a321729a9160320e4edc05f2021e32518e5d4593fc","one":"2be0cb6fc267fba8bf3c2c5ce7f0e7092939af7c8a4db19219ff847e3c8e3d40f4965c1ce905c88bc5182bbfad7163072242ef398b9f67f816da43f660cb7cbf"},{"other":"4169f023f910388983026973c136f36f3d97241e96b839583da84c74a5eef50a8c0cc7181fb2c849354fe03d70df5f2231f107ca14616a4597d058facd2da8c7","one":"9517123df57cd87ee0a5ae86a275af4140cbf52b43a57a439408cbd33e2defaee2e0f8298b2e2cb9aad356a321729a9160320e4edc05f2021e32518e5d4593fc","up":true},{"other":"0f79e2ef69e046888e83eb9f358b16cf7bb9204c31ea1d03de9872f485652407af00787a758d32d3b9440918645a94a0b95efe169bc2a72d8841b2705bdbe4c0","one":"4169f023f910388983026973c136f36f3d97241e96b839583da84c74a5eef50a8c0cc7181fb2c849354fe03d70df5f2231f107ca14616a4597d058facd2da8c7","up":true},{"one":"0f79e2ef69e046888e83eb9f358b16cf7bb9204c31ea1d03de9872f485652407af00787a758d32d3b9440918645a94a0b95efe169bc2a72d8841b2705bdbe4c0","other":"a33863af3dfd52d157d9b0c348aa3baa3e5406a5e1504ef398379fafd5c4699feee620d1210c61ab583610e4c951c054a7f715c33ba9a5c10ad15cb8d0ee1b1b","up":true},{"one":"a33863af3dfd52d157d9b0c348aa3baa3e5406a5e1504ef398379fafd5c4699feee620d1210c61ab583610e4c951c054a7f715c33ba9a5c10ad15cb8d0ee1b1b","other":"2624a85e506a0881abd273f0e4a9f65268afddc668b8d303582ebe0b634648e07ee4d1e7587862b5ef2cc6f90d8b404e4fea8197378a33f3184083c86c25b060","up":true},{"up":true,"other":"5d9cc967ae4136594db226749d415a51ae18c3327fb7e3fb9159bc92c92c9e63984c57f539129ecc393153111dc5115a395329d4333380bfd836ffc48ed5349e","one":"2624a85e506a0881abd273f0e4a9f65268afddc668b8d303582ebe0b634648e07ee4d1e7587862b5ef2cc6f90d8b404e4fea8197378a33f3184083c86c25b060"},{"one":"5d9cc967ae4136594db226749d415a51ae18c3327fb7e3fb9159bc92c92c9e63984c57f539129ecc393153111dc5115a395329d4333380bfd836ffc48ed5349e","other":"b964f0d4cbaf1fac1f0016d7f957fbc4dcc3922224c273ff9e0d5f58770ed80fa4a17528f16d698fb6a3de2906a52ef2befb4e7f1aad960d9e5e72c853f258a6","up":true},{"one":"b964f0d4cbaf1fac1f0016d7f957fbc4dcc3922224c273ff9e0d5f58770ed80fa4a17528f16d698fb6a3de2906a52ef2befb4e7f1aad960d9e5e72c853f258a6","other":"7a1a4a9ab567d1e4f93213126558103ec26094795b9972b433085b548b71c6b1a0a8652339a9e01fb39ac9b3b13ed1d9c3359b03d7e8d39417423990b627d20c","up":true},{"one":"7a1a4a9ab567d1e4f93213126558103ec26094795b9972b433085b548b71c6b1a0a8652339a9e01fb39ac9b3b13ed1d9c3359b03d7e8d39417423990b627d20c","other":"21278d7b532622901447d27ae7bea917fc3b104ec7d54c402ebfbc9587f3351c5d9a5bc11b088170e06341849533bcfe622509ea1d34d80771848453bdb64158","up":true},{"up":true,"one":"21278d7b532622901447d27ae7bea917fc3b104ec7d54c402ebfbc9587f3351c5d9a5bc11b088170e06341849533bcfe622509ea1d34d80771848453bdb64158","other":"f6159d1c9d9120ae52e77a09d82f0b86bd74b88062323033700a661039719ee100d758eaea57ce03398384c3371c8023bf6a69a4788186f657e987938be8f305"},{"up":true,"one":"3d27bc8fb22ad60ca25a70734e1d87fb7ab8105f5c95e9ae21922eb651076bbb331b3b84df907edb4fae23f2a722c77a6dd40f5fb926f909477611cae3773610","other":"aed42225cae33605337d1c034564b46cad9f2cb17ce0f0b91c3f3b8f8f8c0e14357d6d6323ffe1f5f50931394d49c9ef589e4f2251f1bdc5c8e45d7c10f9b1e6"},{"up":true,"other":"60bf8283de94e5192962b86a9c6cbe90adb9d7b399c5ea8b51ad0883a5438814939512c40e4e13ba0ea9b2d3e60a44a25297d005939eeec21f9f304b25798719","one":"9456ce63934b1f648d870d6d2e71634a2ec78df8ccb6c83a364e656b4fe280a9273cccb92bfac7996ed1e6351963e076f3fe6fb89b95c866cc072c8d31775388"},{"up":true,"other":"44b0032c765d307d53ff64c7c86a0409b119b87d1ef5007c37a1663beac3fa4ddb092c06dd0c0ffe05505928a578207968afad2204db317a418da617ca132948","one":"60bf8283de94e5192962b86a9c6cbe90adb9d7b399c5ea8b51ad0883a5438814939512c40e4e13ba0ea9b2d3e60a44a25297d005939eeec21f9f304b25798719"},{"other":"7405baadb8ddcc559dc29f72e5c8a85f539c7836675eac274f043acc3bdb378faf91feab452af20388f4e1cf187a47e5e93fa232da007c9aa6ee6155fdd3329d","one":"af45ddac579286a5850ea494b3e76c1fe116b44de10f183a55ac1eced6eb34682f35eca605dd5b32015645e0e7527090d956236fdeade90b8cc920c54992d161","up":true},{"other":"b964f0d4cbaf1fac1f0016d7f957fbc4dcc3922224c273ff9e0d5f58770ed80fa4a17528f16d698fb6a3de2906a52ef2befb4e7f1aad960d9e5e72c853f258a6","one":"fcdcb9c138c3bdc51b6280a1224419097c4fb188867ca381ac9b92ab08f9fdef0c6267d9ce9fa53944e39cf1b76ce6bf3b17272f97a457649bff6a838eccbf69","up":true},{"one":"44b0032c765d307d53ff64c7c86a0409b119b87d1ef5007c37a1663beac3fa4ddb092c06dd0c0ffe05505928a578207968afad2204db317a418da617ca132948","other":"2be0cb6fc267fba8bf3c2c5ce7f0e7092939af7c8a4db19219ff847e3c8e3d40f4965c1ce905c88bc5182bbfad7163072242ef398b9f67f816da43f660cb7cbf","up":true},{"one":"3d27bc8fb22ad60ca25a70734e1d87fb7ab8105f5c95e9ae21922eb651076bbb331b3b84df907edb4fae23f2a722c77a6dd40f5fb926f909477611cae3773610","other":"2be0cb6fc267fba8bf3c2c5ce7f0e7092939af7c8a4db19219ff847e3c8e3d40f4965c1ce905c88bc5182bbfad7163072242ef398b9f67f816da43f660cb7cbf","up":true},{"up":true,"other":"65a6264a6515ca7a4dadd911be9ecacce0f810ec2c213f27f1b982bdea6c8bad09396f2e2d502aa999880ee4028223ac14b8be966f67ffd92fa48a51ea2454ed","one":"aed42225cae33605337d1c034564b46cad9f2cb17ce0f0b91c3f3b8f8f8c0e14357d6d6323ffe1f5f50931394d49c9ef589e4f2251f1bdc5c8e45d7c10f9b1e6"},{"one":"af45ddac579286a5850ea494b3e76c1fe116b44de10f183a55ac1eced6eb34682f35eca605dd5b32015645e0e7527090d956236fdeade90b8cc920c54992d161","other":"65a6264a6515ca7a4dadd911be9ecacce0f810ec2c213f27f1b982bdea6c8bad09396f2e2d502aa999880ee4028223ac14b8be966f67ffd92fa48a51ea2454ed","up":true},{"other":"3d27bc8fb22ad60ca25a70734e1d87fb7ab8105f5c95e9ae21922eb651076bbb331b3b84df907edb4fae23f2a722c77a6dd40f5fb926f909477611cae3773610","one":"09fbec10eccc27dfc7cc82ea3ffc15c5d1fff4265c930f0a2a2daaf0baa786864a82e9f50a24f703c7b8f521eee760421be9c50ec988442d783e23c8e6caec55","up":true},{"up":true,"one":"275252d736821f456466bca13738d5e62ce93dec8bbc26c9e9f11d399e2ae83d8b540797322215c859993389082ccf2d4da69fee1193e31fb225e39961780c2c","other":"9456ce63934b1f648d870d6d2e71634a2ec78df8ccb6c83a364e656b4fe280a9273cccb92bfac7996ed1e6351963e076f3fe6fb89b95c866cc072c8d31775388"},{"up":true,"other":"5d9cc967ae4136594db226749d415a51ae18c3327fb7e3fb9159bc92c92c9e63984c57f539129ecc393153111dc5115a395329d4333380bfd836ffc48ed5349e","one":"4169f023f910388983026973c136f36f3d97241e96b839583da84c74a5eef50a8c0cc7181fb2c849354fe03d70df5f2231f107ca14616a4597d058facd2da8c7"},{"up":true,"one":"0f79e2ef69e046888e83eb9f358b16cf7bb9204c31ea1d03de9872f485652407af00787a758d32d3b9440918645a94a0b95efe169bc2a72d8841b2705bdbe4c0","other":"9517123df57cd87ee0a5ae86a275af4140cbf52b43a57a439408cbd33e2defaee2e0f8298b2e2cb9aad356a321729a9160320e4edc05f2021e32518e5d4593fc"},{"up":true,"one":"7009eea5c5600d6aa87ed5fa951c486f7b0d260ca1a07dcb057c3cb9afe7e964a0b825001e9ffa6919f382643d4a5fd3bc40d3d413748f2f9964939ae86e55ce","other":"2be0cb6fc267fba8bf3c2c5ce7f0e7092939af7c8a4db19219ff847e3c8e3d40f4965c1ce905c88bc5182bbfad7163072242ef398b9f67f816da43f660cb7cbf"},{"one":"2624a85e506a0881abd273f0e4a9f65268afddc668b8d303582ebe0b634648e07ee4d1e7587862b5ef2cc6f90d8b404e4fea8197378a33f3184083c86c25b060","other":"21278d7b532622901447d27ae7bea917fc3b104ec7d54c402ebfbc9587f3351c5d9a5bc11b088170e06341849533bcfe622509ea1d34d80771848453bdb64158","up":true},{"one":"7410ddeba8db7202f93b250ad4a346c022670cffd8866223ab62260103b6f0938ad001ec054cca00cf9cf7e78c25be1b83cbcec868ab10f9f7628ae05d10ad8b","other":"e20125c0ce3cafd1e19eeff2630fd132539e084b2d2a8c30fcf0202a89623885d9cfdf48f4c3cb04f1ba6abda8f1e69d6f57571f02d8a6e2bc508aa4046d37ed","up":true},{"up":true,"one":"8fac0d980714c5968e57d62c36c315b8dd85eae37b84f9c6afdc9db6ebfe7a38af4ed8aac9ab93939f38b817902744f568397e51c51bca13f0c03c4d40121b24","other":"2be0cb6fc267fba8bf3c2c5ce7f0e7092939af7c8a4db19219ff847e3c8e3d40f4965c1ce905c88bc5182bbfad7163072242ef398b9f67f816da43f660cb7cbf"},{"up":true,"other":"3d27bc8fb22ad60ca25a70734e1d87fb7ab8105f5c95e9ae21922eb651076bbb331b3b84df907edb4fae23f2a722c77a6dd40f5fb926f909477611cae3773610","one":"cdfcfd49b6f27643da799946e2b6d4c84d9feb485278ca9ddb1dcd72f87ce7ffad55c6ec3719069815ba2758a64bd8915d964540f44eda8104d5f7a19691b2af"},{"one":"65a6264a6515ca7a4dadd911be9ecacce0f810ec2c213f27f1b982bdea6c8bad09396f2e2d502aa999880ee4028223ac14b8be966f67ffd92fa48a51ea2454ed","other":"633a8d6240ea0bd01ed55c8caf4a31443545e018130c3a1a21c51e074cc7a9262a6ebb165723afeb339e426a05c3364b4c3dae908df33f0c02a6d44451d52d5b","up":true},{"up":true,"other":"65a6264a6515ca7a4dadd911be9ecacce0f810ec2c213f27f1b982bdea6c8bad09396f2e2d502aa999880ee4028223ac14b8be966f67ffd92fa48a51ea2454ed","one":"2870cbae6af3e8083eaa5003b310a4f18f3c6e41f1cad27ba3eaf8b129f20eb40ce7cd7c54c93556dda9a79ce0d88355c0d3d9d41ef1d479eb63711d13a49b53"},{"other":"4169f023f910388983026973c136f36f3d97241e96b839583da84c74a5eef50a8c0cc7181fb2c849354fe03d70df5f2231f107ca14616a4597d058facd2da8c7","one":"e20125c0ce3cafd1e19eeff2630fd132539e084b2d2a8c30fcf0202a89623885d9cfdf48f4c3cb04f1ba6abda8f1e69d6f57571f02d8a6e2bc508aa4046d37ed","up":true},{"one":"7405baadb8ddcc559dc29f72e5c8a85f539c7836675eac274f043acc3bdb378faf91feab452af20388f4e1cf187a47e5e93fa232da007c9aa6ee6155fdd3329d","other":"21278d7b532622901447d27ae7bea917fc3b104ec7d54c402ebfbc9587f3351c5d9a5bc11b088170e06341849533bcfe622509ea1d34d80771848453bdb64158","up":true},{"up":true,"one":"633a8d6240ea0bd01ed55c8caf4a31443545e018130c3a1a21c51e074cc7a9262a6ebb165723afeb339e426a05c3364b4c3dae908df33f0c02a6d44451d52d5b","other":"af45ddac579286a5850ea494b3e76c1fe116b44de10f183a55ac1eced6eb34682f35eca605dd5b32015645e0e7527090d956236fdeade90b8cc920c54992d161"},{"other":"f6159d1c9d9120ae52e77a09d82f0b86bd74b88062323033700a661039719ee100d758eaea57ce03398384c3371c8023bf6a69a4788186f657e987938be8f305","one":"2be0cb6fc267fba8bf3c2c5ce7f0e7092939af7c8a4db19219ff847e3c8e3d40f4965c1ce905c88bc5182bbfad7163072242ef398b9f67f816da43f660cb7cbf","up":true},{"one":"7a1a4a9ab567d1e4f93213126558103ec26094795b9972b433085b548b71c6b1a0a8652339a9e01fb39ac9b3b13ed1d9c3359b03d7e8d39417423990b627d20c","other":"9456ce63934b1f648d870d6d2e71634a2ec78df8ccb6c83a364e656b4fe280a9273cccb92bfac7996ed1e6351963e076f3fe6fb89b95c866cc072c8d31775388","up":true},{"other":"60bf8283de94e5192962b86a9c6cbe90adb9d7b399c5ea8b51ad0883a5438814939512c40e4e13ba0ea9b2d3e60a44a25297d005939eeec21f9f304b25798719","one":"f6159d1c9d9120ae52e77a09d82f0b86bd74b88062323033700a661039719ee100d758eaea57ce03398384c3371c8023bf6a69a4788186f657e987938be8f305","up":true},{"up":true,"other":"e20125c0ce3cafd1e19eeff2630fd132539e084b2d2a8c30fcf0202a89623885d9cfdf48f4c3cb04f1ba6abda8f1e69d6f57571f02d8a6e2bc508aa4046d37ed","one":"8c5864a90b102a241d675841ac91c66ddecc73eeca039ef005ce63ccc0bbd13c26c3c834a216efb9dc5acb2401f5ef1b81eff02f5b9a3eef332748a5df53cea2"},{"one":"9517123df57cd87ee0a5ae86a275af4140cbf52b43a57a439408cbd33e2defaee2e0f8298b2e2cb9aad356a321729a9160320e4edc05f2021e32518e5d4593fc","other":"b964f0d4cbaf1fac1f0016d7f957fbc4dcc3922224c273ff9e0d5f58770ed80fa4a17528f16d698fb6a3de2906a52ef2befb4e7f1aad960d9e5e72c853f258a6","up":true},{"one":"21278d7b532622901447d27ae7bea917fc3b104ec7d54c402ebfbc9587f3351c5d9a5bc11b088170e06341849533bcfe622509ea1d34d80771848453bdb64158","other":"a33863af3dfd52d157d9b0c348aa3baa3e5406a5e1504ef398379fafd5c4699feee620d1210c61ab583610e4c951c054a7f715c33ba9a5c10ad15cb8d0ee1b1b","up":true},{"other":"2be0cb6fc267fba8bf3c2c5ce7f0e7092939af7c8a4db19219ff847e3c8e3d40f4965c1ce905c88bc5182bbfad7163072242ef398b9f67f816da43f660cb7cbf","one":"b74000b69ff5e8cdce944c92b701df83a456a478e22f946870b3acfea1684ef5d382543c6f61f223fd50994e089a8df3bef3232f5fdf3b865649be760a4fe651","up":true},{"up":true,"other":"8c5864a90b102a241d675841ac91c66ddecc73eeca039ef005ce63ccc0bbd13c26c3c834a216efb9dc5acb2401f5ef1b81eff02f5b9a3eef332748a5df53cea2","one":"d303661d4146e4f2c9342d722074c545b99b80a79e7361e83ce55f5710369eccddfecd2ae1a1f8155f7aabb1675b44efbc4c070c6b3bf4a26ade342d383d4c32"},{"up":true,"one":"b964f0d4cbaf1fac1f0016d7f957fbc4dcc3922224c273ff9e0d5f58770ed80fa4a17528f16d698fb6a3de2906a52ef2befb4e7f1aad960d9e5e72c853f258a6","other":"3d27bc8fb22ad60ca25a70734e1d87fb7ab8105f5c95e9ae21922eb651076bbb331b3b84df907edb4fae23f2a722c77a6dd40f5fb926f909477611cae3773610"},{"one":"60bf8283de94e5192962b86a9c6cbe90adb9d7b399c5ea8b51ad0883a5438814939512c40e4e13ba0ea9b2d3e60a44a25297d005939eeec21f9f304b25798719","other":"8fac0d980714c5968e57d62c36c315b8dd85eae37b84f9c6afdc9db6ebfe7a38af4ed8aac9ab93939f38b817902744f568397e51c51bca13f0c03c4d40121b24","up":true},{"other":"e20125c0ce3cafd1e19eeff2630fd132539e084b2d2a8c30fcf0202a89623885d9cfdf48f4c3cb04f1ba6abda8f1e69d6f57571f02d8a6e2bc508aa4046d37ed","one":"9456ce63934b1f648d870d6d2e71634a2ec78df8ccb6c83a364e656b4fe280a9273cccb92bfac7996ed1e6351963e076f3fe6fb89b95c866cc072c8d31775388","up":true},{"other":"275252d736821f456466bca13738d5e62ce93dec8bbc26c9e9f11d399e2ae83d8b540797322215c859993389082ccf2d4da69fee1193e31fb225e39961780c2c","one":"5d9cc967ae4136594db226749d415a51ae18c3327fb7e3fb9159bc92c92c9e63984c57f539129ecc393153111dc5115a395329d4333380bfd836ffc48ed5349e","up":true},{"other":"7405baadb8ddcc559dc29f72e5c8a85f539c7836675eac274f043acc3bdb378faf91feab452af20388f4e1cf187a47e5e93fa232da007c9aa6ee6155fdd3329d","one":"a33863af3dfd52d157d9b0c348aa3baa3e5406a5e1504ef398379fafd5c4699feee620d1210c61ab583610e4c951c054a7f715c33ba9a5c10ad15cb8d0ee1b1b","up":true},{"up":true,"other":"9517123df57cd87ee0a5ae86a275af4140cbf52b43a57a439408cbd33e2defaee2e0f8298b2e2cb9aad356a321729a9160320e4edc05f2021e32518e5d4593fc","one":"fcdcb9c138c3bdc51b6280a1224419097c4fb188867ca381ac9b92ab08f9fdef0c6267d9ce9fa53944e39cf1b76ce6bf3b17272f97a457649bff6a838eccbf69"},{"up":true,"one":"9456ce63934b1f648d870d6d2e71634a2ec78df8ccb6c83a364e656b4fe280a9273cccb92bfac7996ed1e6351963e076f3fe6fb89b95c866cc072c8d31775388","other":"2624a85e506a0881abd273f0e4a9f65268afddc668b8d303582ebe0b634648e07ee4d1e7587862b5ef2cc6f90d8b404e4fea8197378a33f3184083c86c25b060"},{"up":true,"one":"60bf8283de94e5192962b86a9c6cbe90adb9d7b399c5ea8b51ad0883a5438814939512c40e4e13ba0ea9b2d3e60a44a25297d005939eeec21f9f304b25798719","other":"2be0cb6fc267fba8bf3c2c5ce7f0e7092939af7c8a4db19219ff847e3c8e3d40f4965c1ce905c88bc5182bbfad7163072242ef398b9f67f816da43f660cb7cbf"},{"up":true,"one":"44b0032c765d307d53ff64c7c86a0409b119b87d1ef5007c37a1663beac3fa4ddb092c06dd0c0ffe05505928a578207968afad2204db317a418da617ca132948","other":"09fbec10eccc27dfc7cc82ea3ffc15c5d1fff4265c930f0a2a2daaf0baa786864a82e9f50a24f703c7b8f521eee760421be9c50ec988442d783e23c8e6caec55"},{"up":true,"one":"3d27bc8fb22ad60ca25a70734e1d87fb7ab8105f5c95e9ae21922eb651076bbb331b3b84df907edb4fae23f2a722c77a6dd40f5fb926f909477611cae3773610","other":"d303661d4146e4f2c9342d722074c545b99b80a79e7361e83ce55f5710369eccddfecd2ae1a1f8155f7aabb1675b44efbc4c070c6b3bf4a26ade342d383d4c32"},{"up":true,"one":"aed42225cae33605337d1c034564b46cad9f2cb17ce0f0b91c3f3b8f8f8c0e14357d6d6323ffe1f5f50931394d49c9ef589e4f2251f1bdc5c8e45d7c10f9b1e6","other":"633a8d6240ea0bd01ed55c8caf4a31443545e018130c3a1a21c51e074cc7a9262a6ebb165723afeb339e426a05c3364b4c3dae908df33f0c02a6d44451d52d5b"},{"other":"60bf8283de94e5192962b86a9c6cbe90adb9d7b399c5ea8b51ad0883a5438814939512c40e4e13ba0ea9b2d3e60a44a25297d005939eeec21f9f304b25798719","one":"af45ddac579286a5850ea494b3e76c1fe116b44de10f183a55ac1eced6eb34682f35eca605dd5b32015645e0e7527090d956236fdeade90b8cc920c54992d161","up":true},{"other":"7009eea5c5600d6aa87ed5fa951c486f7b0d260ca1a07dcb057c3cb9afe7e964a0b825001e9ffa6919f382643d4a5fd3bc40d3d413748f2f9964939ae86e55ce","one":"b74000b69ff5e8cdce944c92b701df83a456a478e22f946870b3acfea1684ef5d382543c6f61f223fd50994e089a8df3bef3232f5fdf3b865649be760a4fe651","up":true},{"one":"09fbec10eccc27dfc7cc82ea3ffc15c5d1fff4265c930f0a2a2daaf0baa786864a82e9f50a24f703c7b8f521eee760421be9c50ec988442d783e23c8e6caec55","other":"cdfcfd49b6f27643da799946e2b6d4c84d9feb485278ca9ddb1dcd72f87ce7ffad55c6ec3719069815ba2758a64bd8915d964540f44eda8104d5f7a19691b2af","up":true},{"up":true,"one":"7405baadb8ddcc559dc29f72e5c8a85f539c7836675eac274f043acc3bdb378faf91feab452af20388f4e1cf187a47e5e93fa232da007c9aa6ee6155fdd3329d","other":"2624a85e506a0881abd273f0e4a9f65268afddc668b8d303582ebe0b634648e07ee4d1e7587862b5ef2cc6f90d8b404e4fea8197378a33f3184083c86c25b060"},{"up":true,"one":"633a8d6240ea0bd01ed55c8caf4a31443545e018130c3a1a21c51e074cc7a9262a6ebb165723afeb339e426a05c3364b4c3dae908df33f0c02a6d44451d52d5b","other":"2870cbae6af3e8083eaa5003b310a4f18f3c6e41f1cad27ba3eaf8b129f20eb40ce7cd7c54c93556dda9a79ce0d88355c0d3d9d41ef1d479eb63711d13a49b53"},{"one":"e20125c0ce3cafd1e19eeff2630fd132539e084b2d2a8c30fcf0202a89623885d9cfdf48f4c3cb04f1ba6abda8f1e69d6f57571f02d8a6e2bc508aa4046d37ed","other":"d303661d4146e4f2c9342d722074c545b99b80a79e7361e83ce55f5710369eccddfecd2ae1a1f8155f7aabb1675b44efbc4c070c6b3bf4a26ade342d383d4c32","up":true},{"up":true,"other":"7a1a4a9ab567d1e4f93213126558103ec26094795b9972b433085b548b71c6b1a0a8652339a9e01fb39ac9b3b13ed1d9c3359b03d7e8d39417423990b627d20c","one":"275252d736821f456466bca13738d5e62ce93dec8bbc26c9e9f11d399e2ae83d8b540797322215c859993389082ccf2d4da69fee1193e31fb225e39961780c2c"},{"up":true,"other":"9456ce63934b1f648d870d6d2e71634a2ec78df8ccb6c83a364e656b4fe280a9273cccb92bfac7996ed1e6351963e076f3fe6fb89b95c866cc072c8d31775388","one":"4169f023f910388983026973c136f36f3d97241e96b839583da84c74a5eef50a8c0cc7181fb2c849354fe03d70df5f2231f107ca14616a4597d058facd2da8c7"},{"one":"7009eea5c5600d6aa87ed5fa951c486f7b0d260ca1a07dcb057c3cb9afe7e964a0b825001e9ffa6919f382643d4a5fd3bc40d3d413748f2f9964939ae86e55ce","other":"f6159d1c9d9120ae52e77a09d82f0b86bd74b88062323033700a661039719ee100d758eaea57ce03398384c3371c8023bf6a69a4788186f657e987938be8f305","up":true},{"up":true,"other":"0f79e2ef69e046888e83eb9f358b16cf7bb9204c31ea1d03de9872f485652407af00787a758d32d3b9440918645a94a0b95efe169bc2a72d8841b2705bdbe4c0","one":"65a6264a6515ca7a4dadd911be9ecacce0f810ec2c213f27f1b982bdea6c8bad09396f2e2d502aa999880ee4028223ac14b8be966f67ffd92fa48a51ea2454ed"},{"other":"2870cbae6af3e8083eaa5003b310a4f18f3c6e41f1cad27ba3eaf8b129f20eb40ce7cd7c54c93556dda9a79ce0d88355c0d3d9d41ef1d479eb63711d13a49b53","one":"7410ddeba8db7202f93b250ad4a346c022670cffd8866223ab62260103b6f0938ad001ec054cca00cf9cf7e78c25be1b83cbcec868ab10f9f7628ae05d10ad8b","up":true},{"up":true,"other":"4169f023f910388983026973c136f36f3d97241e96b839583da84c74a5eef50a8c0cc7181fb2c849354fe03d70df5f2231f107ca14616a4597d058facd2da8c7","one":"2be0cb6fc267fba8bf3c2c5ce7f0e7092939af7c8a4db19219ff847e3c8e3d40f4965c1ce905c88bc5182bbfad7163072242ef398b9f67f816da43f660cb7cbf"},{"up":true,"one":"d303661d4146e4f2c9342d722074c545b99b80a79e7361e83ce55f5710369eccddfecd2ae1a1f8155f7aabb1675b44efbc4c070c6b3bf4a26ade342d383d4c32","other":"2870cbae6af3e8083eaa5003b310a4f18f3c6e41f1cad27ba3eaf8b129f20eb40ce7cd7c54c93556dda9a79ce0d88355c0d3d9d41ef1d479eb63711d13a49b53"},{"up":true,"other":"af45ddac579286a5850ea494b3e76c1fe116b44de10f183a55ac1eced6eb34682f35eca605dd5b32015645e0e7527090d956236fdeade90b8cc920c54992d161","one":"9517123df57cd87ee0a5ae86a275af4140cbf52b43a57a439408cbd33e2defaee2e0f8298b2e2cb9aad356a321729a9160320e4edc05f2021e32518e5d4593fc"},{"one":"8fac0d980714c5968e57d62c36c315b8dd85eae37b84f9c6afdc9db6ebfe7a38af4ed8aac9ab93939f38b817902744f568397e51c51bca13f0c03c4d40121b24","other":"7009eea5c5600d6aa87ed5fa951c486f7b0d260ca1a07dcb057c3cb9afe7e964a0b825001e9ffa6919f382643d4a5fd3bc40d3d413748f2f9964939ae86e55ce","up":true},{"up":true,"other":"44b0032c765d307d53ff64c7c86a0409b119b87d1ef5007c37a1663beac3fa4ddb092c06dd0c0ffe05505928a578207968afad2204db317a418da617ca132948","one":"cdfcfd49b6f27643da799946e2b6d4c84d9feb485278ca9ddb1dcd72f87ce7ffad55c6ec3719069815ba2758a64bd8915d964540f44eda8104d5f7a19691b2af"},{"up":true,"one":"0f79e2ef69e046888e83eb9f358b16cf7bb9204c31ea1d03de9872f485652407af00787a758d32d3b9440918645a94a0b95efe169bc2a72d8841b2705bdbe4c0","other":"b964f0d4cbaf1fac1f0016d7f957fbc4dcc3922224c273ff9e0d5f58770ed80fa4a17528f16d698fb6a3de2906a52ef2befb4e7f1aad960d9e5e72c853f258a6"},{"other":"7410ddeba8db7202f93b250ad4a346c022670cffd8866223ab62260103b6f0938ad001ec054cca00cf9cf7e78c25be1b83cbcec868ab10f9f7628ae05d10ad8b","one":"8c5864a90b102a241d675841ac91c66ddecc73eeca039ef005ce63ccc0bbd13c26c3c834a216efb9dc5acb2401f5ef1b81eff02f5b9a3eef332748a5df53cea2","up":true},{"other":"e20125c0ce3cafd1e19eeff2630fd132539e084b2d2a8c30fcf0202a89623885d9cfdf48f4c3cb04f1ba6abda8f1e69d6f57571f02d8a6e2bc508aa4046d37ed","one":"a33863af3dfd52d157d9b0c348aa3baa3e5406a5e1504ef398379fafd5c4699feee620d1210c61ab583610e4c951c054a7f715c33ba9a5c10ad15cb8d0ee1b1b","up":true},{"up":true,"one":"2870cbae6af3e8083eaa5003b310a4f18f3c6e41f1cad27ba3eaf8b129f20eb40ce7cd7c54c93556dda9a79ce0d88355c0d3d9d41ef1d479eb63711d13a49b53","other":"4169f023f910388983026973c136f36f3d97241e96b839583da84c74a5eef50a8c0cc7181fb2c849354fe03d70df5f2231f107ca14616a4597d058facd2da8c7"},{"other":"3d27bc8fb22ad60ca25a70734e1d87fb7ab8105f5c95e9ae21922eb651076bbb331b3b84df907edb4fae23f2a722c77a6dd40f5fb926f909477611cae3773610","one":"2624a85e506a0881abd273f0e4a9f65268afddc668b8d303582ebe0b634648e07ee4d1e7587862b5ef2cc6f90d8b404e4fea8197378a33f3184083c86c25b060","up":true},{"up":true,"one":"5d9cc967ae4136594db226749d415a51ae18c3327fb7e3fb9159bc92c92c9e63984c57f539129ecc393153111dc5115a395329d4333380bfd836ffc48ed5349e","other":"7a1a4a9ab567d1e4f93213126558103ec26094795b9972b433085b548b71c6b1a0a8652339a9e01fb39ac9b3b13ed1d9c3359b03d7e8d39417423990b627d20c"},{"up":true,"other":"af45ddac579286a5850ea494b3e76c1fe116b44de10f183a55ac1eced6eb34682f35eca605dd5b32015645e0e7527090d956236fdeade90b8cc920c54992d161","one":"b964f0d4cbaf1fac1f0016d7f957fbc4dcc3922224c273ff9e0d5f58770ed80fa4a17528f16d698fb6a3de2906a52ef2befb4e7f1aad960d9e5e72c853f258a6"},{"up":true,"other":"8fac0d980714c5968e57d62c36c315b8dd85eae37b84f9c6afdc9db6ebfe7a38af4ed8aac9ab93939f38b817902744f568397e51c51bca13f0c03c4d40121b24","one":"f6159d1c9d9120ae52e77a09d82f0b86bd74b88062323033700a661039719ee100d758eaea57ce03398384c3371c8023bf6a69a4788186f657e987938be8f305"},{"up":true,"other":"e20125c0ce3cafd1e19eeff2630fd132539e084b2d2a8c30fcf0202a89623885d9cfdf48f4c3cb04f1ba6abda8f1e69d6f57571f02d8a6e2bc508aa4046d37ed","one":"7a1a4a9ab567d1e4f93213126558103ec26094795b9972b433085b548b71c6b1a0a8652339a9e01fb39ac9b3b13ed1d9c3359b03d7e8d39417423990b627d20c"},{"one":"21278d7b532622901447d27ae7bea917fc3b104ec7d54c402ebfbc9587f3351c5d9a5bc11b088170e06341849533bcfe622509ea1d34d80771848453bdb64158","other":"e20125c0ce3cafd1e19eeff2630fd132539e084b2d2a8c30fcf0202a89623885d9cfdf48f4c3cb04f1ba6abda8f1e69d6f57571f02d8a6e2bc508aa4046d37ed","up":true},{"one":"fcdcb9c138c3bdc51b6280a1224419097c4fb188867ca381ac9b92ab08f9fdef0c6267d9ce9fa53944e39cf1b76ce6bf3b17272f97a457649bff6a838eccbf69","other":"0f79e2ef69e046888e83eb9f358b16cf7bb9204c31ea1d03de9872f485652407af00787a758d32d3b9440918645a94a0b95efe169bc2a72d8841b2705bdbe4c0","up":true},{"up":true,"other":"e20125c0ce3cafd1e19eeff2630fd132539e084b2d2a8c30fcf0202a89623885d9cfdf48f4c3cb04f1ba6abda8f1e69d6f57571f02d8a6e2bc508aa4046d37ed","one":"aed42225cae33605337d1c034564b46cad9f2cb17ce0f0b91c3f3b8f8f8c0e14357d6d6323ffe1f5f50931394d49c9ef589e4f2251f1bdc5c8e45d7c10f9b1e6"},{"up":true,"one":"af45ddac579286a5850ea494b3e76c1fe116b44de10f183a55ac1eced6eb34682f35eca605dd5b32015645e0e7527090d956236fdeade90b8cc920c54992d161","other":"0f79e2ef69e046888e83eb9f358b16cf7bb9204c31ea1d03de9872f485652407af00787a758d32d3b9440918645a94a0b95efe169bc2a72d8841b2705bdbe4c0"},{"other":"e20125c0ce3cafd1e19eeff2630fd132539e084b2d2a8c30fcf0202a89623885d9cfdf48f4c3cb04f1ba6abda8f1e69d6f57571f02d8a6e2bc508aa4046d37ed","one":"44b0032c765d307d53ff64c7c86a0409b119b87d1ef5007c37a1663beac3fa4ddb092c06dd0c0ffe05505928a578207968afad2204db317a418da617ca132948","up":true},{"one":"60bf8283de94e5192962b86a9c6cbe90adb9d7b399c5ea8b51ad0883a5438814939512c40e4e13ba0ea9b2d3e60a44a25297d005939eeec21f9f304b25798719","other":"7009eea5c5600d6aa87ed5fa951c486f7b0d260ca1a07dcb057c3cb9afe7e964a0b825001e9ffa6919f382643d4a5fd3bc40d3d413748f2f9964939ae86e55ce","up":true},{"one":"7405baadb8ddcc559dc29f72e5c8a85f539c7836675eac274f043acc3bdb378faf91feab452af20388f4e1cf187a47e5e93fa232da007c9aa6ee6155fdd3329d","other":"8c5864a90b102a241d675841ac91c66ddecc73eeca039ef005ce63ccc0bbd13c26c3c834a216efb9dc5acb2401f5ef1b81eff02f5b9a3eef332748a5df53cea2","up":true},{"up":true,"one":"275252d736821f456466bca13738d5e62ce93dec8bbc26c9e9f11d399e2ae83d8b540797322215c859993389082ccf2d4da69fee1193e31fb225e39961780c2c","other":"e20125c0ce3cafd1e19eeff2630fd132539e084b2d2a8c30fcf0202a89623885d9cfdf48f4c3cb04f1ba6abda8f1e69d6f57571f02d8a6e2bc508aa4046d37ed"},{"up":true,"one":"09fbec10eccc27dfc7cc82ea3ffc15c5d1fff4265c930f0a2a2daaf0baa786864a82e9f50a24f703c7b8f521eee760421be9c50ec988442d783e23c8e6caec55","other":"9517123df57cd87ee0a5ae86a275af4140cbf52b43a57a439408cbd33e2defaee2e0f8298b2e2cb9aad356a321729a9160320e4edc05f2021e32518e5d4593fc"},{"one":"633a8d6240ea0bd01ed55c8caf4a31443545e018130c3a1a21c51e074cc7a9262a6ebb165723afeb339e426a05c3364b4c3dae908df33f0c02a6d44451d52d5b","other":"0f79e2ef69e046888e83eb9f358b16cf7bb9204c31ea1d03de9872f485652407af00787a758d32d3b9440918645a94a0b95efe169bc2a72d8841b2705bdbe4c0","up":true},{"up":true,"one":"b74000b69ff5e8cdce944c92b701df83a456a478e22f946870b3acfea1684ef5d382543c6f61f223fd50994e089a8df3bef3232f5fdf3b865649be760a4fe651","other":"f6159d1c9d9120ae52e77a09d82f0b86bd74b88062323033700a661039719ee100d758eaea57ce03398384c3371c8023bf6a69a4788186f657e987938be8f305"},{"up":true,"other":"44b0032c765d307d53ff64c7c86a0409b119b87d1ef5007c37a1663beac3fa4ddb092c06dd0c0ffe05505928a578207968afad2204db317a418da617ca132948","one":"7009eea5c5600d6aa87ed5fa951c486f7b0d260ca1a07dcb057c3cb9afe7e964a0b825001e9ffa6919f382643d4a5fd3bc40d3d413748f2f9964939ae86e55ce"},{"one":"8fac0d980714c5968e57d62c36c315b8dd85eae37b84f9c6afdc9db6ebfe7a38af4ed8aac9ab93939f38b817902744f568397e51c51bca13f0c03c4d40121b24","other":"0f79e2ef69e046888e83eb9f358b16cf7bb9204c31ea1d03de9872f485652407af00787a758d32d3b9440918645a94a0b95efe169bc2a72d8841b2705bdbe4c0","up":true},{"one":"7410ddeba8db7202f93b250ad4a346c022670cffd8866223ab62260103b6f0938ad001ec054cca00cf9cf7e78c25be1b83cbcec868ab10f9f7628ae05d10ad8b","other":"7405baadb8ddcc559dc29f72e5c8a85f539c7836675eac274f043acc3bdb378faf91feab452af20388f4e1cf187a47e5e93fa232da007c9aa6ee6155fdd3329d","up":true},{"one":"d303661d4146e4f2c9342d722074c545b99b80a79e7361e83ce55f5710369eccddfecd2ae1a1f8155f7aabb1675b44efbc4c070c6b3bf4a26ade342d383d4c32","other":"7405baadb8ddcc559dc29f72e5c8a85f539c7836675eac274f043acc3bdb378faf91feab452af20388f4e1cf187a47e5e93fa232da007c9aa6ee6155fdd3329d","up":true},{"up":true,"one":"cdfcfd49b6f27643da799946e2b6d4c84d9feb485278ca9ddb1dcd72f87ce7ffad55c6ec3719069815ba2758a64bd8915d964540f44eda8104d5f7a19691b2af","other":"9517123df57cd87ee0a5ae86a275af4140cbf52b43a57a439408cbd33e2defaee2e0f8298b2e2cb9aad356a321729a9160320e4edc05f2021e32518e5d4593fc"},{"up":true,"other":"fcdcb9c138c3bdc51b6280a1224419097c4fb188867ca381ac9b92ab08f9fdef0c6267d9ce9fa53944e39cf1b76ce6bf3b17272f97a457649bff6a838eccbf69","one":"65a6264a6515ca7a4dadd911be9ecacce0f810ec2c213f27f1b982bdea6c8bad09396f2e2d502aa999880ee4028223ac14b8be966f67ffd92fa48a51ea2454ed"},{"other":"275252d736821f456466bca13738d5e62ce93dec8bbc26c9e9f11d399e2ae83d8b540797322215c859993389082ccf2d4da69fee1193e31fb225e39961780c2c","one":"a33863af3dfd52d157d9b0c348aa3baa3e5406a5e1504ef398379fafd5c4699feee620d1210c61ab583610e4c951c054a7f715c33ba9a5c10ad15cb8d0ee1b1b","up":true},{"up":true,"one":"2624a85e506a0881abd273f0e4a9f65268afddc668b8d303582ebe0b634648e07ee4d1e7587862b5ef2cc6f90d8b404e4fea8197378a33f3184083c86c25b060","other":"8c5864a90b102a241d675841ac91c66ddecc73eeca039ef005ce63ccc0bbd13c26c3c834a216efb9dc5acb2401f5ef1b81eff02f5b9a3eef332748a5df53cea2"},{"other":"9456ce63934b1f648d870d6d2e71634a2ec78df8ccb6c83a364e656b4fe280a9273cccb92bfac7996ed1e6351963e076f3fe6fb89b95c866cc072c8d31775388","one":"5d9cc967ae4136594db226749d415a51ae18c3327fb7e3fb9159bc92c92c9e63984c57f539129ecc393153111dc5115a395329d4333380bfd836ffc48ed5349e","up":true},{"up":true,"one":"4169f023f910388983026973c136f36f3d97241e96b839583da84c74a5eef50a8c0cc7181fb2c849354fe03d70df5f2231f107ca14616a4597d058facd2da8c7","other":"7a1a4a9ab567d1e4f93213126558103ec26094795b9972b433085b548b71c6b1a0a8652339a9e01fb39ac9b3b13ed1d9c3359b03d7e8d39417423990b627d20c"},{"other":"cdfcfd49b6f27643da799946e2b6d4c84d9feb485278ca9ddb1dcd72f87ce7ffad55c6ec3719069815ba2758a64bd8915d964540f44eda8104d5f7a19691b2af","one":"f6159d1c9d9120ae52e77a09d82f0b86bd74b88062323033700a661039719ee100d758eaea57ce03398384c3371c8023bf6a69a4788186f657e987938be8f305","up":true},{"other":"aed42225cae33605337d1c034564b46cad9f2cb17ce0f0b91c3f3b8f8f8c0e14357d6d6323ffe1f5f50931394d49c9ef589e4f2251f1bdc5c8e45d7c10f9b1e6","one":"0f79e2ef69e046888e83eb9f358b16cf7bb9204c31ea1d03de9872f485652407af00787a758d32d3b9440918645a94a0b95efe169bc2a72d8841b2705bdbe4c0","up":true},{"one":"60bf8283de94e5192962b86a9c6cbe90adb9d7b399c5ea8b51ad0883a5438814939512c40e4e13ba0ea9b2d3e60a44a25297d005939eeec21f9f304b25798719","other":"b74000b69ff5e8cdce944c92b701df83a456a478e22f946870b3acfea1684ef5d382543c6f61f223fd50994e089a8df3bef3232f5fdf3b865649be760a4fe651","up":true},{"one":"44b0032c765d307d53ff64c7c86a0409b119b87d1ef5007c37a1663beac3fa4ddb092c06dd0c0ffe05505928a578207968afad2204db317a418da617ca132948","other":"0f79e2ef69e046888e83eb9f358b16cf7bb9204c31ea1d03de9872f485652407af00787a758d32d3b9440918645a94a0b95efe169bc2a72d8841b2705bdbe4c0","up":true},{"up":true,"one":"aed42225cae33605337d1c034564b46cad9f2cb17ce0f0b91c3f3b8f8f8c0e14357d6d6323ffe1f5f50931394d49c9ef589e4f2251f1bdc5c8e45d7c10f9b1e6","other":"fcdcb9c138c3bdc51b6280a1224419097c4fb188867ca381ac9b92ab08f9fdef0c6267d9ce9fa53944e39cf1b76ce6bf3b17272f97a457649bff6a838eccbf69"},{"one":"b74000b69ff5e8cdce944c92b701df83a456a478e22f946870b3acfea1684ef5d382543c6f61f223fd50994e089a8df3bef3232f5fdf3b865649be760a4fe651","other":"8fac0d980714c5968e57d62c36c315b8dd85eae37b84f9c6afdc9db6ebfe7a38af4ed8aac9ab93939f38b817902744f568397e51c51bca13f0c03c4d40121b24","up":true},{"one":"633a8d6240ea0bd01ed55c8caf4a31443545e018130c3a1a21c51e074cc7a9262a6ebb165723afeb339e426a05c3364b4c3dae908df33f0c02a6d44451d52d5b","other":"fcdcb9c138c3bdc51b6280a1224419097c4fb188867ca381ac9b92ab08f9fdef0c6267d9ce9fa53944e39cf1b76ce6bf3b17272f97a457649bff6a838eccbf69","up":true},{"up":true,"other":"2870cbae6af3e8083eaa5003b310a4f18f3c6e41f1cad27ba3eaf8b129f20eb40ce7cd7c54c93556dda9a79ce0d88355c0d3d9d41ef1d479eb63711d13a49b53","one":"5d9cc967ae4136594db226749d415a51ae18c3327fb7e3fb9159bc92c92c9e63984c57f539129ecc393153111dc5115a395329d4333380bfd836ffc48ed5349e"},{"one":"4169f023f910388983026973c136f36f3d97241e96b839583da84c74a5eef50a8c0cc7181fb2c849354fe03d70df5f2231f107ca14616a4597d058facd2da8c7","other":"275252d736821f456466bca13738d5e62ce93dec8bbc26c9e9f11d399e2ae83d8b540797322215c859993389082ccf2d4da69fee1193e31fb225e39961780c2c","up":true}]} \ No newline at end of file diff --git a/swarm/pss/testdata/snapshot_4.json b/swarm/pss/testdata/snapshot_4.json new file mode 100644 index 0000000000..36058bfe33 --- /dev/null +++ b/swarm/pss/testdata/snapshot_4.json @@ -0,0 +1,133 @@ +{ + "conns":[ + { + "one":"0eec333dd211c2ea81db614fe58bf0300c15e50e1b044e47ef93067a6cdbc3bc666b40bdcc515bbf580355dbef9370294ef1ee92ee0525e78a8beed00c2b99f5", + "other":"6f6ee658538ea66a68c9cb914d09f228f6ee9942c337a8d5a2cb3a0f021e83dd0fab481ca8ebf56ed913f6ddf69caa3249459d43e61e5e5b162ded7e1c918c9c", + "up":true + }, + { + "other":"0eec333dd211c2ea81db614fe58bf0300c15e50e1b044e47ef93067a6cdbc3bc666b40bdcc515bbf580355dbef9370294ef1ee92ee0525e78a8beed00c2b99f5", + "one":"7b12f55c7c012104e006775d03b89722b403fb0e1ecb79af8cadfa6947425aedb323fb9416c84b782d35f3216acb5d94a1dd31d60a3eba45f9051bf503de1b66", + "up":true + }, + { + "up":true, + "other":"83388147883592bab4fdaddb4e56f8cb1c56dc5c2e910fc6a7277ac89b77cc7ce24892ed6984f3414589cb3b8c4b69356ff9aab7ca52fdd58f12dee2a2152523", + "one":"6f6ee658538ea66a68c9cb914d09f228f6ee9942c337a8d5a2cb3a0f021e83dd0fab481ca8ebf56ed913f6ddf69caa3249459d43e61e5e5b162ded7e1c918c9c" + } + ], + "nodes":[ + { + "node":{ + "config":{ + "private_key":"e567b7d9c554e5102cdc99b6523bace02dbb8951415c8816d82ba2d2e97fa23b", + "name":"node01", + "id":"7b12f55c7c012104e006775d03b89722b403fb0e1ecb79af8cadfa6947425aedb323fb9416c84b782d35f3216acb5d94a1dd31d60a3eba45f9051bf503de1b66", + "services":[ + "bzz","pss" + ] + }, + "info":{ + "ip":"0.0.0.0", + "listenAddr":"", + "protocols":{ + "hive":"\n=========================================================================\nFri Sep 29 21:22:53 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 73d6ad\npopulation: 5 (7), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 dfd4 | 3 8a1e (0) d776 (0) dfd4 (0)\n============ DEPTH: 1 ==========================================\n001 3 05da 159c 3451 | 3 05da (0) 159c (0) 3451 (0)\n002 0 | 0\n003 1 6e8d | 1 6e8d (0)\n004 0 | 0\n005 0 | 0\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================", + "bzz":"c9atSnUGnc7WYPpMuYFD7lVz33yxXZopWs8WVeloM4Q=" + }, + "ports":{ + "listener":0, + "discovery":0 + }, + "name":"node01", + "id":"7b12f55c7c012104e006775d03b89722b403fb0e1ecb79af8cadfa6947425aedb323fb9416c84b782d35f3216acb5d94a1dd31d60a3eba45f9051bf503de1b66", + "enode":"enode://7b12f55c7c012104e006775d03b89722b403fb0e1ecb79af8cadfa6947425aedb323fb9416c84b782d35f3216acb5d94a1dd31d60a3eba45f9051bf503de1b66@0.0.0.0:0" + }, + "up":true + } + }, + { + "node":{ + "info":{ + "listenAddr":"", + "ip":"0.0.0.0", + "ports":{ + "discovery":0, + "listener":0 + }, + "protocols":{ + "hive":"\n=========================================================================\nFri Sep 29 21:22:53 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 6e8da8\npopulation: 5 (7), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 8a1e | 3 8a1e (0) d776 (0) dfd4 (0)\n============ DEPTH: 1 ==========================================\n001 3 3451 159c 05da | 3 05da (0) 159c (0) 3451 (0)\n002 0 | 0\n003 1 73d6 | 1 73d6 (0)\n004 0 | 0\n005 0 | 0\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================", + "bzz":"bo2oaruJSrNQRMjEVRRyJd+WyrSY2gZ6EY8fuaQX+eM=" + }, + "id":"0eec333dd211c2ea81db614fe58bf0300c15e50e1b044e47ef93067a6cdbc3bc666b40bdcc515bbf580355dbef9370294ef1ee92ee0525e78a8beed00c2b99f5", + "name":"node02", + "enode":"enode://0eec333dd211c2ea81db614fe58bf0300c15e50e1b044e47ef93067a6cdbc3bc666b40bdcc515bbf580355dbef9370294ef1ee92ee0525e78a8beed00c2b99f5@0.0.0.0:0" + }, + "config":{ + "name":"node02", + "id":"0eec333dd211c2ea81db614fe58bf0300c15e50e1b044e47ef93067a6cdbc3bc666b40bdcc515bbf580355dbef9370294ef1ee92ee0525e78a8beed00c2b99f5", + "services":[ + "bzz","pss" + ], + "private_key":"c7526db70acd02f36d3b201ef3e1d85e38c52bee6931453213dbc5edec4d0976" + }, + "up":true + } + }, + { + "node":{ + "config":{ + "private_key":"61b5728f59bc43080c3b8eb0458fb30d7723e2747355b6dc980f35f3ed431199", + "id":"6f6ee658538ea66a68c9cb914d09f228f6ee9942c337a8d5a2cb3a0f021e83dd0fab481ca8ebf56ed913f6ddf69caa3249459d43e61e5e5b162ded7e1c918c9c", + "name":"node03", + "services":[ + "bzz","pss" + ] + }, + "info":{ + "ip":"0.0.0.0", + "listenAddr":"", + "protocols":{ + "hive":"\n=========================================================================\nFri Sep 29 21:22:53 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 8a1eb7\npopulation: 3 (7), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 6e8d | 5 05da (0) 159c (0) 3451 (0) 73d6 (0)\n============ DEPTH: 1 ==========================================\n001 2 dfd4 d776 | 2 dfd4 (0) d776 (0)\n002 0 | 0\n003 0 | 0\n004 0 | 0\n005 0 | 0\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================", + "bzz":"ih63j/E98xjn+BFt/+6YzX2ZBWUPpT8Wdmt1SmPzh6w=" + }, + "ports":{ + "discovery":0, + "listener":0 + }, + "name":"node03", + "id":"6f6ee658538ea66a68c9cb914d09f228f6ee9942c337a8d5a2cb3a0f021e83dd0fab481ca8ebf56ed913f6ddf69caa3249459d43e61e5e5b162ded7e1c918c9c", + "enode":"enode://6f6ee658538ea66a68c9cb914d09f228f6ee9942c337a8d5a2cb3a0f021e83dd0fab481ca8ebf56ed913f6ddf69caa3249459d43e61e5e5b162ded7e1c918c9c@0.0.0.0:0" + }, + "up":true + } + }, + { + "node":{ + "info":{ + "name":"node04", + "id":"83388147883592bab4fdaddb4e56f8cb1c56dc5c2e910fc6a7277ac89b77cc7ce24892ed6984f3414589cb3b8c4b69356ff9aab7ca52fdd58f12dee2a2152523", + "enode":"enode://83388147883592bab4fdaddb4e56f8cb1c56dc5c2e910fc6a7277ac89b77cc7ce24892ed6984f3414589cb3b8c4b69356ff9aab7ca52fdd58f12dee2a2152523@0.0.0.0:0", + "ip":"0.0.0.0", + "listenAddr":"", + "protocols":{ + "bzz":"13aDNPedYmrbQz9EtwOoGFVeMzEFYDbvP40Sglhr8EQ=", + "hive":"\n=========================================================================\nFri Sep 29 21:22:53 UTC 2017 KΛÐΞMLIΛ hive: queen's address: d77683\npopulation: 5 (7), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 3451 159c 05da | 5 6e8d (0) 73d6 (0) 3451 (0) 159c (0)\n============ DEPTH: 1 ==========================================\n001 1 8a1e | 1 8a1e (0)\n002 0 | 0\n003 0 | 0\n004 1 dfd4 | 1 dfd4 (0)\n005 0 | 0\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================" + }, + "ports":{ + "listener":0, + "discovery":0 + } + }, + "config":{ + "services":[ + "bzz","pss" + ], + "id":"83388147883592bab4fdaddb4e56f8cb1c56dc5c2e910fc6a7277ac89b77cc7ce24892ed6984f3414589cb3b8c4b69356ff9aab7ca52fdd58f12dee2a2152523", + "name":"node04", + "private_key":"075b07c29ceac4ffa2a114afd67b21dfc438126bc169bf7c154be6d81d86ed38" + }, + "up":true + } + } + ] +} diff --git a/swarm/pss/testdata/snapshot_64.json b/swarm/pss/testdata/snapshot_64.json new file mode 100644 index 0000000000..82a90a6dbc --- /dev/null +++ b/swarm/pss/testdata/snapshot_64.json @@ -0,0 +1 @@ +{"conns":[{"one":"ddfccaa30a25c32b199a98046669df50b5bb07447cf9dafec69934d9b38dfe447bd0b8fc8b33b0453d63088ff65deca8bec067a3f79a545c988ab7f7b735e1f2","other":"0445005ab3e1a97c7fb9d9a4e77d4da6c51881f2454a35f945fdce1318e863ef3e27784938720c80ebbb3c6440e63bd9ae0fecdf21d78d7e24357ddd9b430b37","up":true},{"one":"0445005ab3e1a97c7fb9d9a4e77d4da6c51881f2454a35f945fdce1318e863ef3e27784938720c80ebbb3c6440e63bd9ae0fecdf21d78d7e24357ddd9b430b37","up":true,"other":"841c007c8c5c96f6d7759d186bbf008e64fb9ab6e88c215c0fff31285ac3a47108962699f6fcc995bce7059787fa69bfbc82d36bfaa155ee207a7044bb839c96"},{"one":"841c007c8c5c96f6d7759d186bbf008e64fb9ab6e88c215c0fff31285ac3a47108962699f6fcc995bce7059787fa69bfbc82d36bfaa155ee207a7044bb839c96","other":"06a6d7bd7fc3d209e3464e20fdc04df0c20f5fc991172a7847dab790db55daf735cf56d65d5471291511ce99524a934c2cb839cdb6ef4dcf7f025b600f5adbea","up":true},{"one":"b13271912256c91940de954a90f73889c8abb76c4e92ecedd68e37dc50dcb253a2164607400f2b798d3c2d612d1c77bc677ddac892614a7296254099251e8379","up":true,"other":"f9db826a99d327db544fa023ed13b689fd7c40ac9abdfd59d376efd245839ab8d34a3b5d9783fe0461e7ccdff35395e8df8983396df1a87f505663139eab7b20"},{"one":"c581746c5ea238a632de0b30da06de317dc9f613cc9bb16c41509e5d1381b041f2d2e6a65018667bb6b57868577ff04a2773a451dd03b6b599bff5d8cbd4017a","up":true,"other":"5732476eb1c7b5ab050759a7169281e6ff583df6de07c2019fb105dfad4df268587b87baf6e0d210f77b048bd62b501b713a919964f35b862b403b478d88a1b6"},{"up":true,"other":"740371f4438046c4f3cb3e0c47cd1c35df4565addb44dc4a7aa0be864cf43f726dc0616502cd67fd7d88008acf8ba1e3f9ef60aeb2d3de3896dccd8765c2bfb3","one":"aee9aaece9a50dd4e85d79f1286165181251ebbbffe461e87e98e04ee5a4730b3d31ff6ed63fe403c1ecff165cbe1cf7d791f4a6fd16685726c290344ed65406"},{"one":"f9db826a99d327db544fa023ed13b689fd7c40ac9abdfd59d376efd245839ab8d34a3b5d9783fe0461e7ccdff35395e8df8983396df1a87f505663139eab7b20","other":"dd1ecdd5e7bdd1ab85a946132cfd7e27c8a29e0256ebe859a9c9283cbb872f9406b30a835826ecece342ab5c41f4c34fdb75049acf0ee134ca8f94c3158a73e0","up":true},{"other":"ec96e314abe60637723a8242b6afeed45ff1a8faca649f8dc7f175ed9db4118bc6d406f5d26d3d71e54699a97b7da59a3d8fb934501b60c15bd5e0501f8fe792","up":true,"one":"eb4bab9ad390760b3eece117dbec9792aa56485cd4a6824094337f83463efbe0174b73aba386da238f7b1724aef4cb6a3017cf35999ca591a1e56b67b1ecc250"},{"other":"ccbbc901d05610202edfd1eba445dc0c93c3ab1dfcc4c9eecd9f1f12521508407429b605840eb8fed9893a1fd8ef6dcd29c9627fe8d3d41ca094b10ab977aa8b","up":true,"one":"ef8f752702c272b1efa3df07957eaaf69854f906df7eebc65b9e5afcb2d3302c712ecf7f4730915f7f29d60cd3463e8393f4d7e34c1b4a7696c855332e4b3d25"},{"one":"8b3023625eecf7dd330df127a31454cea24354d099ca621af1a1232e5b59961ceafbd9f7e0f658905d80617f7efbc4038d84fb6e3cc9347a1f4f1775fff46965","up":true,"other":"aee9aaece9a50dd4e85d79f1286165181251ebbbffe461e87e98e04ee5a4730b3d31ff6ed63fe403c1ecff165cbe1cf7d791f4a6fd16685726c290344ed65406"},{"one":"dd1ecdd5e7bdd1ab85a946132cfd7e27c8a29e0256ebe859a9c9283cbb872f9406b30a835826ecece342ab5c41f4c34fdb75049acf0ee134ca8f94c3158a73e0","up":true,"other":"ef8f752702c272b1efa3df07957eaaf69854f906df7eebc65b9e5afcb2d3302c712ecf7f4730915f7f29d60cd3463e8393f4d7e34c1b4a7696c855332e4b3d25"},{"one":"78739942ae915ea9447fbc435162fc63f18a6f54a1473fd4aa2ed2391a5d62ffa8e32e0aaaa2b83022bd1ff15210daea42433e944235c95a681fac54f75da5de","other":"a93e19158ae6a4261186b663bf109258d759e42b8e0e1d5c06e79a9b6844e6acb41c0a4ce38dfdf250d6016aa796fb78807a7f91738f4eef8a36dafdd60afec7","up":true},{"other":"3780f49d8de4f4a44cba2cff7c6acedb10c32a737808c8c7328c29f7686d0351f9c8d4429b320af2560f550f9692507c426c5d30858b0ef79bd8c5e4db58d6b8","up":true,"one":"06a6d7bd7fc3d209e3464e20fdc04df0c20f5fc991172a7847dab790db55daf735cf56d65d5471291511ce99524a934c2cb839cdb6ef4dcf7f025b600f5adbea"},{"one":"2cb9a1452559314b74e4e1956a260ee2ef7bed85215e444968f54148eb7662f76ec8e7e0fe2cb32d9eecde8d4748a1f776dca7c7f121fde1722d0ba514498d11","other":"00508d6e28f4b503d346983d740c24c440c6eab33128d86c60cb2ce8c70d17189a96a7e6f212dd25f383d1902d04206784edb7fc8b1c391e4465afcd18192c1c","up":true},{"one":"70af807b8e945627dae8a77496db558a2d1581eb89b15f25d2b4881679e5895c12955fd61558a554f5efb989e8940a2fb5eab2aca46de46ba1f059fe58c43311","other":"eb4bab9ad390760b3eece117dbec9792aa56485cd4a6824094337f83463efbe0174b73aba386da238f7b1724aef4cb6a3017cf35999ca591a1e56b67b1ecc250","up":true},{"one":"a93e19158ae6a4261186b663bf109258d759e42b8e0e1d5c06e79a9b6844e6acb41c0a4ce38dfdf250d6016aa796fb78807a7f91738f4eef8a36dafdd60afec7","other":"c581746c5ea238a632de0b30da06de317dc9f613cc9bb16c41509e5d1381b041f2d2e6a65018667bb6b57868577ff04a2773a451dd03b6b599bff5d8cbd4017a","up":true},{"up":true,"other":"2cb9a1452559314b74e4e1956a260ee2ef7bed85215e444968f54148eb7662f76ec8e7e0fe2cb32d9eecde8d4748a1f776dca7c7f121fde1722d0ba514498d11","one":"740371f4438046c4f3cb3e0c47cd1c35df4565addb44dc4a7aa0be864cf43f726dc0616502cd67fd7d88008acf8ba1e3f9ef60aeb2d3de3896dccd8765c2bfb3"},{"other":"08f640d4494b0db8b99e7f7a7b3a1d267f457d5c42ea8002d2a509fee7f06fda7e115e270f43372ebc836748aa3456b8d47783064655b38314731f0ee1d8fac1","up":true,"one":"32627f1a91175809b9141af528c4d77407385102a3ed6afee81acb79b0988f91075c670a09203238e266f5ad0d61b9388c9097fe00a54ced8f04423830768768"},{"one":"698cf5333166bf22a15679cb0d88d7382fe980455a6c288556310898e6aeb3fb04262b89e146d4bff2a4e5501574bd7b55adf3a2ccde080e7a3acab9fdb78e1a","other":"e968aa3ce0d669bab524f11df68ea707d6f4ed9c4367b78e20acd66af8deb0a965368ed4fa171f579ba931001f47092e97d5d37d80075570f61a2eebb21bbd4b","up":true},{"one":"5732476eb1c7b5ab050759a7169281e6ff583df6de07c2019fb105dfad4df268587b87baf6e0d210f77b048bd62b501b713a919964f35b862b403b478d88a1b6","up":true,"other":"4367ed557fe94e971003fe0a3236c6bd619e232117818a35f394995ef9782b930279344042dc165069780e8457106299679af6f61c1482d54f31fd19d4f9dd88"},{"one":"bee0751f64c744ef2862b780ce251b2e21e073b57cec0b57c974b913b92c452aa089f1f66dcf259bdd7ab612bfbca0c8f421a94c564941efd4a1a99c2443fade","other":"528d9876a41762f88bbe70f95de1b28998844d65449a5eff254b034db3b4925b6ee3b56fa32f012b448a19d5f429ba0892cce3634cedad6cbed0e03914ccc2b5","up":true},{"one":"08f640d4494b0db8b99e7f7a7b3a1d267f457d5c42ea8002d2a509fee7f06fda7e115e270f43372ebc836748aa3456b8d47783064655b38314731f0ee1d8fac1","up":true,"other":"e777565409c3fa228f25352f28004671b6f9451fe21666263e71d67d18cf7890f3015af4717267bcd736322239aae34ba0f596e8e98d1628a539cef3a521ed7d"},{"one":"269e5d200ae242b0b101bd7d465e009fc7eb22b074f1d9b562580bf452d592420e4063d03fab92c6fa61a32633492ee1b4fb20c3a8f44ec7ca07839bee871828","up":true,"other":"12b2d36d0e1a7255bde9c81fc9fac8befd7119bbafb74773cee281a73a9095fcceb8a5bc6fc01d8fcc948adbf2b6b6d190017b307875fbea971e6604ddb219de"},{"one":"4367ed557fe94e971003fe0a3236c6bd619e232117818a35f394995ef9782b930279344042dc165069780e8457106299679af6f61c1482d54f31fd19d4f9dd88","other":"0d502ca2f60cadbf375c195365090b216ac99af07abb3a35d3f3dbdc4de7eb2a8f93a3f2a240fc5905dca74e78a05a5837484a117477fb279052889c52b99c6c","up":true},{"one":"00508d6e28f4b503d346983d740c24c440c6eab33128d86c60cb2ce8c70d17189a96a7e6f212dd25f383d1902d04206784edb7fc8b1c391e4465afcd18192c1c","other":"f808e36fd29885cc4f1ad57b26e64deabc0b0fb164ac03017ff2c89671a1ec07706dd28120ceadd8322c6e2387623bc14fa284a0173f70fe722ecc8326f8c932","up":true},{"one":"e777565409c3fa228f25352f28004671b6f9451fe21666263e71d67d18cf7890f3015af4717267bcd736322239aae34ba0f596e8e98d1628a539cef3a521ed7d","up":true,"other":"df4e07354dd593b1986e996f84c3e97147f72f4c6367ec876472c7384fe2d850ee6a8abeb37b789e7c50c12aa3533f19a6c7d9c37bb1b884c61eee307488ed88"},{"other":"2455595a3aefc0cd619c569d920c279e968022ee53cc07b5a0e3e4d7f8ce315739d432389a2bc26c1890fd8af33c1ced0790c7f644d205361e78c787c803ad88","up":true,"one":"12b2d36d0e1a7255bde9c81fc9fac8befd7119bbafb74773cee281a73a9095fcceb8a5bc6fc01d8fcc948adbf2b6b6d190017b307875fbea971e6604ddb219de"},{"up":true,"other":"bee0751f64c744ef2862b780ce251b2e21e073b57cec0b57c974b913b92c452aa089f1f66dcf259bdd7ab612bfbca0c8f421a94c564941efd4a1a99c2443fade","one":"641004e2e499316f46b8b5e0744a5bfcb24323d44c25ed043d57b18406b71bb4e6053df63eb83488c950ba74ae007bc4d5ae711a891eded4a8ea6aa45fb8312a"},{"up":true,"other":"641004e2e499316f46b8b5e0744a5bfcb24323d44c25ed043d57b18406b71bb4e6053df63eb83488c950ba74ae007bc4d5ae711a891eded4a8ea6aa45fb8312a","one":"f808e36fd29885cc4f1ad57b26e64deabc0b0fb164ac03017ff2c89671a1ec07706dd28120ceadd8322c6e2387623bc14fa284a0173f70fe722ecc8326f8c932"},{"up":true,"other":"e24f63d4515d5d1e8e85f06afde4da3144258f7569d2a0b007aecc13c9cb17a8ad75d85e30a1bb7bfee7b81a219b58e969787f11710c82d0904568a60cc2fe5d","one":"ccbbc901d05610202edfd1eba445dc0c93c3ab1dfcc4c9eecd9f1f12521508407429b605840eb8fed9893a1fd8ef6dcd29c9627fe8d3d41ca094b10ab977aa8b"},{"up":true,"other":"5e36d45cd33f0deda83595a1d7196ae42408793b821245224d6585b4291c88149403d2f8b49523137fb26f8353647b3e48261c198504ccf8544cc9131d2890d8","one":"2455595a3aefc0cd619c569d920c279e968022ee53cc07b5a0e3e4d7f8ce315739d432389a2bc26c1890fd8af33c1ced0790c7f644d205361e78c787c803ad88"},{"one":"df4e07354dd593b1986e996f84c3e97147f72f4c6367ec876472c7384fe2d850ee6a8abeb37b789e7c50c12aa3533f19a6c7d9c37bb1b884c61eee307488ed88","other":"20fcc315548210e104fb0bd5deb4c5af2d78a075a3441015e7e27f8c711a5d6055d8c01692502ca4648f82704424c25a7252e3505657e25dd30c1096e16fcccf","up":true},{"up":true,"other":"18c79fcf8500f4d5cb609ef72277112430da75ef83466bdbe0ea4d3a5d6997ca27a94ba0bb35a7a40f5b56bd8242cb20228a6802c4cbb27b934a904eed057b2c","one":"5e36d45cd33f0deda83595a1d7196ae42408793b821245224d6585b4291c88149403d2f8b49523137fb26f8353647b3e48261c198504ccf8544cc9131d2890d8"},{"one":"20fcc315548210e104fb0bd5deb4c5af2d78a075a3441015e7e27f8c711a5d6055d8c01692502ca4648f82704424c25a7252e3505657e25dd30c1096e16fcccf","other":"70af807b8e945627dae8a77496db558a2d1581eb89b15f25d2b4881679e5895c12955fd61558a554f5efb989e8940a2fb5eab2aca46de46ba1f059fe58c43311","up":true},{"other":"128c42c3e21d7ba3c1bb7481c1119fa85124e827114a0bf7243c9b34b61f2f70111402ef1d4bfa8df69f2472f95b4ad44a95991c1adbe85c20f66436c9247e4e","up":true,"one":"18c79fcf8500f4d5cb609ef72277112430da75ef83466bdbe0ea4d3a5d6997ca27a94ba0bb35a7a40f5b56bd8242cb20228a6802c4cbb27b934a904eed057b2c"},{"one":"e24f63d4515d5d1e8e85f06afde4da3144258f7569d2a0b007aecc13c9cb17a8ad75d85e30a1bb7bfee7b81a219b58e969787f11710c82d0904568a60cc2fe5d","up":true,"other":"8eea2dd2475d894484f737bb61fa632585ab0a82e47c070327eb65de8b5cf76ad6bbebba1b94b5fe19f6c631e429d1273740937da9ec6cabbcdfd5bd176cc362"},{"one":"4c53fcf455540cc5f4fd48a57fb68e643eaf769085f350129e1dfa76ef56d33f31b950a42721dbe445a73151edbdb54ce0169204a17a58031a07f11ea1347ed0","other":"b13271912256c91940de954a90f73889c8abb76c4e92ecedd68e37dc50dcb253a2164607400f2b798d3c2d612d1c77bc677ddac892614a7296254099251e8379","up":true},{"one":"067835838d850b0a649e0e359329349cb2c599c3301bbc122547847a0273597187f745cd820f743775d6c1c44bf3be7e9bdb470a1defa3aa78f41411773cd371","up":true,"other":"a0a7b4ccd7d2222f59c202373736c03204f38088dcae48afab6e204b663dff0b06df2ceafc808351e45f54effd5c32481df220a938d1c58d49cd31c32bb20d1e"},{"other":"ba5b2e12f30e2819c19f9336b13b84145af8dc91197840f49c6dc9a8995fbdf37635d5bc42fbc9f59da666df42a3a16e10c02bb0e556e5c9526a74194b23bb96","up":true,"one":"8eea2dd2475d894484f737bb61fa632585ab0a82e47c070327eb65de8b5cf76ad6bbebba1b94b5fe19f6c631e429d1273740937da9ec6cabbcdfd5bd176cc362"},{"one":"ba5b2e12f30e2819c19f9336b13b84145af8dc91197840f49c6dc9a8995fbdf37635d5bc42fbc9f59da666df42a3a16e10c02bb0e556e5c9526a74194b23bb96","up":true,"other":"32627f1a91175809b9141af528c4d77407385102a3ed6afee81acb79b0988f91075c670a09203238e266f5ad0d61b9388c9097fe00a54ced8f04423830768768"},{"one":"3780f49d8de4f4a44cba2cff7c6acedb10c32a737808c8c7328c29f7686d0351f9c8d4429b320af2560f550f9692507c426c5d30858b0ef79bd8c5e4db58d6b8","other":"698cf5333166bf22a15679cb0d88d7382fe980455a6c288556310898e6aeb3fb04262b89e146d4bff2a4e5501574bd7b55adf3a2ccde080e7a3acab9fdb78e1a","up":true},{"other":"78739942ae915ea9447fbc435162fc63f18a6f54a1473fd4aa2ed2391a5d62ffa8e32e0aaaa2b83022bd1ff15210daea42433e944235c95a681fac54f75da5de","up":true,"one":"ec96e314abe60637723a8242b6afeed45ff1a8faca649f8dc7f175ed9db4118bc6d406f5d26d3d71e54699a97b7da59a3d8fb934501b60c15bd5e0501f8fe792"},{"other":"8b3023625eecf7dd330df127a31454cea24354d099ca621af1a1232e5b59961ceafbd9f7e0f658905d80617f7efbc4038d84fb6e3cc9347a1f4f1775fff46965","up":true,"one":"0d502ca2f60cadbf375c195365090b216ac99af07abb3a35d3f3dbdc4de7eb2a8f93a3f2a240fc5905dca74e78a05a5837484a117477fb279052889c52b99c6c"},{"one":"e968aa3ce0d669bab524f11df68ea707d6f4ed9c4367b78e20acd66af8deb0a965368ed4fa171f579ba931001f47092e97d5d37d80075570f61a2eebb21bbd4b","up":true,"other":"269e5d200ae242b0b101bd7d465e009fc7eb22b074f1d9b562580bf452d592420e4063d03fab92c6fa61a32633492ee1b4fb20c3a8f44ec7ca07839bee871828"},{"one":"528d9876a41762f88bbe70f95de1b28998844d65449a5eff254b034db3b4925b6ee3b56fa32f012b448a19d5f429ba0892cce3634cedad6cbed0e03914ccc2b5","up":true,"other":"067835838d850b0a649e0e359329349cb2c599c3301bbc122547847a0273597187f745cd820f743775d6c1c44bf3be7e9bdb470a1defa3aa78f41411773cd371"},{"one":"5fd28368ab1f2702060367fbc0aa218a5461a60fa9fb4aa77cf9a65b06980c8802df4ec04392e78a83276a7509acba337fd9d8391fa47b3ea77d3959f5c6a35b","up":true,"other":"2017096c1b5481de69fff5c6a993e2f2014e6f39fd725613cd441ba883356ce1beea333028890bfd277a6e5118e7fd3bc15d7c3e11d9453a8fc9aeccff68306b"},{"one":"dc41672c95ae1af5b7008f7b1c4e232dc469c4969095d357a6e713257ddb8f7220eadf41082cb22503cee38c042160f5d9750f4787b6e44dc8eaa5bd76df8e55","up":true,"other":"ddfccaa30a25c32b199a98046669df50b5bb07447cf9dafec69934d9b38dfe447bd0b8fc8b33b0453d63088ff65deca8bec067a3f79a545c988ab7f7b735e1f2"},{"one":"9e67e97b2552fd6c0a82cff57d6144aecc05f751a30bf61438cc545fb5932f9b9c901309a14c7ad868bae0d274b999cec111ec9dfd51d6392db9dc717fa5378c","up":true,"other":"ee9e52421dac0a5654edba1892117bb8762de147ef6719a85d627b6af451cddf265f0282af905e72e19c754ffe3c4eb5c37fc56d26dc0873182891a85205552c"},{"up":true,"other":"47e3e22c28c4217e3ba4f83ecf3b5767943c3d49c3b829ad510a7412ae868d60f2c9e4cb51e52e6153aa6555eb2cc1ecaae62793119774dbe3a09d8550d9e2d7","one":"ee9e52421dac0a5654edba1892117bb8762de147ef6719a85d627b6af451cddf265f0282af905e72e19c754ffe3c4eb5c37fc56d26dc0873182891a85205552c"},{"up":true,"other":"c8b55e1f0042ff9ac2b73593f79ce125b3b613354ed90a086b18e1f1809c883d0c0e9df6ec080181ef023833cde585de184523483db878aa65c9939a1a1fcf2d","one":"47e3e22c28c4217e3ba4f83ecf3b5767943c3d49c3b829ad510a7412ae868d60f2c9e4cb51e52e6153aa6555eb2cc1ecaae62793119774dbe3a09d8550d9e2d7"},{"other":"03e750d46b9a4a9e2047a5b718f427834417f4eb48d8794fde26593a3adbbce48750fa93f47548e342677e94888941ebd492a844a5d8325f67a0db8e94a09b55","up":true,"one":"c8b55e1f0042ff9ac2b73593f79ce125b3b613354ed90a086b18e1f1809c883d0c0e9df6ec080181ef023833cde585de184523483db878aa65c9939a1a1fcf2d"},{"other":"dc41672c95ae1af5b7008f7b1c4e232dc469c4969095d357a6e713257ddb8f7220eadf41082cb22503cee38c042160f5d9750f4787b6e44dc8eaa5bd76df8e55","up":true,"one":"03e750d46b9a4a9e2047a5b718f427834417f4eb48d8794fde26593a3adbbce48750fa93f47548e342677e94888941ebd492a844a5d8325f67a0db8e94a09b55"},{"one":"a0a7b4ccd7d2222f59c202373736c03204f38088dcae48afab6e204b663dff0b06df2ceafc808351e45f54effd5c32481df220a938d1c58d49cd31c32bb20d1e","up":true,"other":"93f716fc299e1ef6c7ca4f12f5d81a68d65a07f5c86e7605c6518b8f99d792b8d653583ccf031d3855a8835674c16cff79eeee407ed090e94a58bf7333062d1e"},{"one":"93f716fc299e1ef6c7ca4f12f5d81a68d65a07f5c86e7605c6518b8f99d792b8d653583ccf031d3855a8835674c16cff79eeee407ed090e94a58bf7333062d1e","up":true,"other":"96d5ac5effb367c45d8329e73de0cb9f7bd4090b1627416fd7b0a28062959ed5e87042c9f1b4bc8653d27d5f9ab3e0bdec8f09a2f2d4a1bcfd69d68234fdfb12"},{"one":"128c42c3e21d7ba3c1bb7481c1119fa85124e827114a0bf7243c9b34b61f2f70111402ef1d4bfa8df69f2472f95b4ad44a95991c1adbe85c20f66436c9247e4e","other":"4c53fcf455540cc5f4fd48a57fb68e643eaf769085f350129e1dfa76ef56d33f31b950a42721dbe445a73151edbdb54ce0169204a17a58031a07f11ea1347ed0","up":true},{"one":"9af8f0912f664cb4b4515f6b66c432b6d9e8a97f338691517bab0f221718c9ea95ef04243ea7c9573daa5183969b9e9fd4469a58014d88acd0adca3379679cff","up":true,"other":"9e67e97b2552fd6c0a82cff57d6144aecc05f751a30bf61438cc545fb5932f9b9c901309a14c7ad868bae0d274b999cec111ec9dfd51d6392db9dc717fa5378c"},{"up":true,"other":"1e2f58e271f5f55bf1ec82db59cd6b29b3badae06263ea3bb876a131f1869f9fa9477538887fad30ca623f23d06a952a3f8aca1a581c3ed4faf0ad79b47d42b9","one":"1dd15e2816825bb52419c0f79a13ef9380a2e15fae07d7edae177b334d202c5546d701cebec53b7bc26b97928d5c317fffbe84ed130510f195f9c91b120c93ca"},{"one":"96d5ac5effb367c45d8329e73de0cb9f7bd4090b1627416fd7b0a28062959ed5e87042c9f1b4bc8653d27d5f9ab3e0bdec8f09a2f2d4a1bcfd69d68234fdfb12","up":true,"other":"e34e530095c62d56ea231fc2fd30f3099d7ec88212d4bfb0144efb0232b2f7b48ab438fe3c2211f6bb70a0bf89816b590da44d5cfb9ef817f4c04cfbd0ca37a6"},{"up":true,"other":"4a13668afb8e9fb9db2c4e4e4ff754cbb40c59692c6c5cd70fcba3199ef05c1cf1b19c4fca62396690c90ab7b16f9a18ed375f946a4166137cac349ff3b02933","one":"1e2f58e271f5f55bf1ec82db59cd6b29b3badae06263ea3bb876a131f1869f9fa9477538887fad30ca623f23d06a952a3f8aca1a581c3ed4faf0ad79b47d42b9"},{"one":"e34e530095c62d56ea231fc2fd30f3099d7ec88212d4bfb0144efb0232b2f7b48ab438fe3c2211f6bb70a0bf89816b590da44d5cfb9ef817f4c04cfbd0ca37a6","other":"bde03ff26a216400b61d07d3eaa865f8b597a52f130ecd44af60d526d4b30c8978cb10c16f4fcbf391ef3a3e5de2aace4c077e9ae6d15451506f370190fbda04","up":true},{"one":"4a13668afb8e9fb9db2c4e4e4ff754cbb40c59692c6c5cd70fcba3199ef05c1cf1b19c4fca62396690c90ab7b16f9a18ed375f946a4166137cac349ff3b02933","up":true,"other":"9af8f0912f664cb4b4515f6b66c432b6d9e8a97f338691517bab0f221718c9ea95ef04243ea7c9573daa5183969b9e9fd4469a58014d88acd0adca3379679cff"},{"other":"5fd28368ab1f2702060367fbc0aa218a5461a60fa9fb4aa77cf9a65b06980c8802df4ec04392e78a83276a7509acba337fd9d8391fa47b3ea77d3959f5c6a35b","up":true,"one":"bde03ff26a216400b61d07d3eaa865f8b597a52f130ecd44af60d526d4b30c8978cb10c16f4fcbf391ef3a3e5de2aace4c077e9ae6d15451506f370190fbda04"},{"up":true,"other":"1dd15e2816825bb52419c0f79a13ef9380a2e15fae07d7edae177b334d202c5546d701cebec53b7bc26b97928d5c317fffbe84ed130510f195f9c91b120c93ca","one":"213a1fdcf601bbda1a8531eb2aefc33daef7d7a2312012e8a781bd4ac732d7c267fdc8ceb45061783e64995ce74e67fc330c6a043bbab3f5f88a0e1e2bb4b48c"},{"other":"213a1fdcf601bbda1a8531eb2aefc33daef7d7a2312012e8a781bd4ac732d7c267fdc8ceb45061783e64995ce74e67fc330c6a043bbab3f5f88a0e1e2bb4b48c","up":true,"one":"2017096c1b5481de69fff5c6a993e2f2014e6f39fd725613cd441ba883356ce1beea333028890bfd277a6e5118e7fd3bc15d7c3e11d9453a8fc9aeccff68306b"},{"one":"ddfccaa30a25c32b199a98046669df50b5bb07447cf9dafec69934d9b38dfe447bd0b8fc8b33b0453d63088ff65deca8bec067a3f79a545c988ab7f7b735e1f2","other":"213a1fdcf601bbda1a8531eb2aefc33daef7d7a2312012e8a781bd4ac732d7c267fdc8ceb45061783e64995ce74e67fc330c6a043bbab3f5f88a0e1e2bb4b48c","up":true},{"one":"12b2d36d0e1a7255bde9c81fc9fac8befd7119bbafb74773cee281a73a9095fcceb8a5bc6fc01d8fcc948adbf2b6b6d190017b307875fbea971e6604ddb219de","other":"47e3e22c28c4217e3ba4f83ecf3b5767943c3d49c3b829ad510a7412ae868d60f2c9e4cb51e52e6153aa6555eb2cc1ecaae62793119774dbe3a09d8550d9e2d7","up":true},{"other":"528d9876a41762f88bbe70f95de1b28998844d65449a5eff254b034db3b4925b6ee3b56fa32f012b448a19d5f429ba0892cce3634cedad6cbed0e03914ccc2b5","up":true,"one":"698cf5333166bf22a15679cb0d88d7382fe980455a6c288556310898e6aeb3fb04262b89e146d4bff2a4e5501574bd7b55adf3a2ccde080e7a3acab9fdb78e1a"},{"one":"3780f49d8de4f4a44cba2cff7c6acedb10c32a737808c8c7328c29f7686d0351f9c8d4429b320af2560f550f9692507c426c5d30858b0ef79bd8c5e4db58d6b8","up":true,"other":"528d9876a41762f88bbe70f95de1b28998844d65449a5eff254b034db3b4925b6ee3b56fa32f012b448a19d5f429ba0892cce3634cedad6cbed0e03914ccc2b5"},{"up":true,"other":"70af807b8e945627dae8a77496db558a2d1581eb89b15f25d2b4881679e5895c12955fd61558a554f5efb989e8940a2fb5eab2aca46de46ba1f059fe58c43311","one":"e968aa3ce0d669bab524f11df68ea707d6f4ed9c4367b78e20acd66af8deb0a965368ed4fa171f579ba931001f47092e97d5d37d80075570f61a2eebb21bbd4b"},{"other":"128c42c3e21d7ba3c1bb7481c1119fa85124e827114a0bf7243c9b34b61f2f70111402ef1d4bfa8df69f2472f95b4ad44a95991c1adbe85c20f66436c9247e4e","up":true,"one":"06a6d7bd7fc3d209e3464e20fdc04df0c20f5fc991172a7847dab790db55daf735cf56d65d5471291511ce99524a934c2cb839cdb6ef4dcf7f025b600f5adbea"},{"one":"128c42c3e21d7ba3c1bb7481c1119fa85124e827114a0bf7243c9b34b61f2f70111402ef1d4bfa8df69f2472f95b4ad44a95991c1adbe85c20f66436c9247e4e","other":"dd1ecdd5e7bdd1ab85a946132cfd7e27c8a29e0256ebe859a9c9283cbb872f9406b30a835826ecece342ab5c41f4c34fdb75049acf0ee134ca8f94c3158a73e0","up":true},{"one":"ba5b2e12f30e2819c19f9336b13b84145af8dc91197840f49c6dc9a8995fbdf37635d5bc42fbc9f59da666df42a3a16e10c02bb0e556e5c9526a74194b23bb96","other":"1e2f58e271f5f55bf1ec82db59cd6b29b3badae06263ea3bb876a131f1869f9fa9477538887fad30ca623f23d06a952a3f8aca1a581c3ed4faf0ad79b47d42b9","up":true},{"up":true,"other":"e24f63d4515d5d1e8e85f06afde4da3144258f7569d2a0b007aecc13c9cb17a8ad75d85e30a1bb7bfee7b81a219b58e969787f11710c82d0904568a60cc2fe5d","one":"2455595a3aefc0cd619c569d920c279e968022ee53cc07b5a0e3e4d7f8ce315739d432389a2bc26c1890fd8af33c1ced0790c7f644d205361e78c787c803ad88"},{"other":"f9db826a99d327db544fa023ed13b689fd7c40ac9abdfd59d376efd245839ab8d34a3b5d9783fe0461e7ccdff35395e8df8983396df1a87f505663139eab7b20","up":true,"one":"4c53fcf455540cc5f4fd48a57fb68e643eaf769085f350129e1dfa76ef56d33f31b950a42721dbe445a73151edbdb54ce0169204a17a58031a07f11ea1347ed0"},{"other":"e777565409c3fa228f25352f28004671b6f9451fe21666263e71d67d18cf7890f3015af4717267bcd736322239aae34ba0f596e8e98d1628a539cef3a521ed7d","up":true,"one":"f9db826a99d327db544fa023ed13b689fd7c40ac9abdfd59d376efd245839ab8d34a3b5d9783fe0461e7ccdff35395e8df8983396df1a87f505663139eab7b20"},{"other":"06a6d7bd7fc3d209e3464e20fdc04df0c20f5fc991172a7847dab790db55daf735cf56d65d5471291511ce99524a934c2cb839cdb6ef4dcf7f025b600f5adbea","up":true,"one":"dd1ecdd5e7bdd1ab85a946132cfd7e27c8a29e0256ebe859a9c9283cbb872f9406b30a835826ecece342ab5c41f4c34fdb75049acf0ee134ca8f94c3158a73e0"},{"other":"70af807b8e945627dae8a77496db558a2d1581eb89b15f25d2b4881679e5895c12955fd61558a554f5efb989e8940a2fb5eab2aca46de46ba1f059fe58c43311","up":true,"one":"ef8f752702c272b1efa3df07957eaaf69854f906df7eebc65b9e5afcb2d3302c712ecf7f4730915f7f29d60cd3463e8393f4d7e34c1b4a7696c855332e4b3d25"},{"one":"ccbbc901d05610202edfd1eba445dc0c93c3ab1dfcc4c9eecd9f1f12521508407429b605840eb8fed9893a1fd8ef6dcd29c9627fe8d3d41ca094b10ab977aa8b","other":"ddfccaa30a25c32b199a98046669df50b5bb07447cf9dafec69934d9b38dfe447bd0b8fc8b33b0453d63088ff65deca8bec067a3f79a545c988ab7f7b735e1f2","up":true},{"up":true,"other":"128c42c3e21d7ba3c1bb7481c1119fa85124e827114a0bf7243c9b34b61f2f70111402ef1d4bfa8df69f2472f95b4ad44a95991c1adbe85c20f66436c9247e4e","one":"f808e36fd29885cc4f1ad57b26e64deabc0b0fb164ac03017ff2c89671a1ec07706dd28120ceadd8322c6e2387623bc14fa284a0173f70fe722ecc8326f8c932"},{"other":"ddfccaa30a25c32b199a98046669df50b5bb07447cf9dafec69934d9b38dfe447bd0b8fc8b33b0453d63088ff65deca8bec067a3f79a545c988ab7f7b735e1f2","up":true,"one":"e24f63d4515d5d1e8e85f06afde4da3144258f7569d2a0b007aecc13c9cb17a8ad75d85e30a1bb7bfee7b81a219b58e969787f11710c82d0904568a60cc2fe5d"},{"up":true,"other":"70af807b8e945627dae8a77496db558a2d1581eb89b15f25d2b4881679e5895c12955fd61558a554f5efb989e8940a2fb5eab2aca46de46ba1f059fe58c43311","one":"8eea2dd2475d894484f737bb61fa632585ab0a82e47c070327eb65de8b5cf76ad6bbebba1b94b5fe19f6c631e429d1273740937da9ec6cabbcdfd5bd176cc362"},{"one":"18c79fcf8500f4d5cb609ef72277112430da75ef83466bdbe0ea4d3a5d6997ca27a94ba0bb35a7a40f5b56bd8242cb20228a6802c4cbb27b934a904eed057b2c","other":"1e2f58e271f5f55bf1ec82db59cd6b29b3badae06263ea3bb876a131f1869f9fa9477538887fad30ca623f23d06a952a3f8aca1a581c3ed4faf0ad79b47d42b9","up":true},{"one":"08f640d4494b0db8b99e7f7a7b3a1d267f457d5c42ea8002d2a509fee7f06fda7e115e270f43372ebc836748aa3456b8d47783064655b38314731f0ee1d8fac1","up":true,"other":"3780f49d8de4f4a44cba2cff7c6acedb10c32a737808c8c7328c29f7686d0351f9c8d4429b320af2560f550f9692507c426c5d30858b0ef79bd8c5e4db58d6b8"},{"up":true,"other":"ccbbc901d05610202edfd1eba445dc0c93c3ab1dfcc4c9eecd9f1f12521508407429b605840eb8fed9893a1fd8ef6dcd29c9627fe8d3d41ca094b10ab977aa8b","one":"e34e530095c62d56ea231fc2fd30f3099d7ec88212d4bfb0144efb0232b2f7b48ab438fe3c2211f6bb70a0bf89816b590da44d5cfb9ef817f4c04cfbd0ca37a6"},{"up":true,"other":"ee9e52421dac0a5654edba1892117bb8762de147ef6719a85d627b6af451cddf265f0282af905e72e19c754ffe3c4eb5c37fc56d26dc0873182891a85205552c","one":"e777565409c3fa228f25352f28004671b6f9451fe21666263e71d67d18cf7890f3015af4717267bcd736322239aae34ba0f596e8e98d1628a539cef3a521ed7d"},{"one":"641004e2e499316f46b8b5e0744a5bfcb24323d44c25ed043d57b18406b71bb4e6053df63eb83488c950ba74ae007bc4d5ae711a891eded4a8ea6aa45fb8312a","other":"0d502ca2f60cadbf375c195365090b216ac99af07abb3a35d3f3dbdc4de7eb2a8f93a3f2a240fc5905dca74e78a05a5837484a117477fb279052889c52b99c6c","up":true},{"one":"20fcc315548210e104fb0bd5deb4c5af2d78a075a3441015e7e27f8c711a5d6055d8c01692502ca4648f82704424c25a7252e3505657e25dd30c1096e16fcccf","up":true,"other":"e968aa3ce0d669bab524f11df68ea707d6f4ed9c4367b78e20acd66af8deb0a965368ed4fa171f579ba931001f47092e97d5d37d80075570f61a2eebb21bbd4b"},{"other":"9e67e97b2552fd6c0a82cff57d6144aecc05f751a30bf61438cc545fb5932f9b9c901309a14c7ad868bae0d274b999cec111ec9dfd51d6392db9dc717fa5378c","up":true,"one":"528d9876a41762f88bbe70f95de1b28998844d65449a5eff254b034db3b4925b6ee3b56fa32f012b448a19d5f429ba0892cce3634cedad6cbed0e03914ccc2b5"},{"up":true,"other":"213a1fdcf601bbda1a8531eb2aefc33daef7d7a2312012e8a781bd4ac732d7c267fdc8ceb45061783e64995ce74e67fc330c6a043bbab3f5f88a0e1e2bb4b48c","one":"740371f4438046c4f3cb3e0c47cd1c35df4565addb44dc4a7aa0be864cf43f726dc0616502cd67fd7d88008acf8ba1e3f9ef60aeb2d3de3896dccd8765c2bfb3"},{"up":true,"other":"841c007c8c5c96f6d7759d186bbf008e64fb9ab6e88c215c0fff31285ac3a47108962699f6fcc995bce7059787fa69bfbc82d36bfaa155ee207a7044bb839c96","one":"067835838d850b0a649e0e359329349cb2c599c3301bbc122547847a0273597187f745cd820f743775d6c1c44bf3be7e9bdb470a1defa3aa78f41411773cd371"},{"one":"ec96e314abe60637723a8242b6afeed45ff1a8faca649f8dc7f175ed9db4118bc6d406f5d26d3d71e54699a97b7da59a3d8fb934501b60c15bd5e0501f8fe792","up":true,"other":"128c42c3e21d7ba3c1bb7481c1119fa85124e827114a0bf7243c9b34b61f2f70111402ef1d4bfa8df69f2472f95b4ad44a95991c1adbe85c20f66436c9247e4e"},{"one":"a0a7b4ccd7d2222f59c202373736c03204f38088dcae48afab6e204b663dff0b06df2ceafc808351e45f54effd5c32481df220a938d1c58d49cd31c32bb20d1e","up":true,"other":"841c007c8c5c96f6d7759d186bbf008e64fb9ab6e88c215c0fff31285ac3a47108962699f6fcc995bce7059787fa69bfbc82d36bfaa155ee207a7044bb839c96"},{"one":"a93e19158ae6a4261186b663bf109258d759e42b8e0e1d5c06e79a9b6844e6acb41c0a4ce38dfdf250d6016aa796fb78807a7f91738f4eef8a36dafdd60afec7","up":true,"other":"70af807b8e945627dae8a77496db558a2d1581eb89b15f25d2b4881679e5895c12955fd61558a554f5efb989e8940a2fb5eab2aca46de46ba1f059fe58c43311"},{"up":true,"other":"0d502ca2f60cadbf375c195365090b216ac99af07abb3a35d3f3dbdc4de7eb2a8f93a3f2a240fc5905dca74e78a05a5837484a117477fb279052889c52b99c6c","one":"dc41672c95ae1af5b7008f7b1c4e232dc469c4969095d357a6e713257ddb8f7220eadf41082cb22503cee38c042160f5d9750f4787b6e44dc8eaa5bd76df8e55"},{"one":"c581746c5ea238a632de0b30da06de317dc9f613cc9bb16c41509e5d1381b041f2d2e6a65018667bb6b57868577ff04a2773a451dd03b6b599bff5d8cbd4017a","other":"528d9876a41762f88bbe70f95de1b28998844d65449a5eff254b034db3b4925b6ee3b56fa32f012b448a19d5f429ba0892cce3634cedad6cbed0e03914ccc2b5","up":true},{"up":true,"other":"1e2f58e271f5f55bf1ec82db59cd6b29b3badae06263ea3bb876a131f1869f9fa9477538887fad30ca623f23d06a952a3f8aca1a581c3ed4faf0ad79b47d42b9","one":"4367ed557fe94e971003fe0a3236c6bd619e232117818a35f394995ef9782b930279344042dc165069780e8457106299679af6f61c1482d54f31fd19d4f9dd88"},{"other":"5e36d45cd33f0deda83595a1d7196ae42408793b821245224d6585b4291c88149403d2f8b49523137fb26f8353647b3e48261c198504ccf8544cc9131d2890d8","up":true,"one":"32627f1a91175809b9141af528c4d77407385102a3ed6afee81acb79b0988f91075c670a09203238e266f5ad0d61b9388c9097fe00a54ced8f04423830768768"},{"one":"96d5ac5effb367c45d8329e73de0cb9f7bd4090b1627416fd7b0a28062959ed5e87042c9f1b4bc8653d27d5f9ab3e0bdec8f09a2f2d4a1bcfd69d68234fdfb12","other":"3780f49d8de4f4a44cba2cff7c6acedb10c32a737808c8c7328c29f7686d0351f9c8d4429b320af2560f550f9692507c426c5d30858b0ef79bd8c5e4db58d6b8","up":true},{"other":"ddfccaa30a25c32b199a98046669df50b5bb07447cf9dafec69934d9b38dfe447bd0b8fc8b33b0453d63088ff65deca8bec067a3f79a545c988ab7f7b735e1f2","up":true,"one":"2017096c1b5481de69fff5c6a993e2f2014e6f39fd725613cd441ba883356ce1beea333028890bfd277a6e5118e7fd3bc15d7c3e11d9453a8fc9aeccff68306b"},{"other":"841c007c8c5c96f6d7759d186bbf008e64fb9ab6e88c215c0fff31285ac3a47108962699f6fcc995bce7059787fa69bfbc82d36bfaa155ee207a7044bb839c96","up":true,"one":"93f716fc299e1ef6c7ca4f12f5d81a68d65a07f5c86e7605c6518b8f99d792b8d653583ccf031d3855a8835674c16cff79eeee407ed090e94a58bf7333062d1e"},{"one":"213a1fdcf601bbda1a8531eb2aefc33daef7d7a2312012e8a781bd4ac732d7c267fdc8ceb45061783e64995ce74e67fc330c6a043bbab3f5f88a0e1e2bb4b48c","other":"5e36d45cd33f0deda83595a1d7196ae42408793b821245224d6585b4291c88149403d2f8b49523137fb26f8353647b3e48261c198504ccf8544cc9131d2890d8","up":true},{"one":"0d502ca2f60cadbf375c195365090b216ac99af07abb3a35d3f3dbdc4de7eb2a8f93a3f2a240fc5905dca74e78a05a5837484a117477fb279052889c52b99c6c","up":true,"other":"ccbbc901d05610202edfd1eba445dc0c93c3ab1dfcc4c9eecd9f1f12521508407429b605840eb8fed9893a1fd8ef6dcd29c9627fe8d3d41ca094b10ab977aa8b"},{"other":"20fcc315548210e104fb0bd5deb4c5af2d78a075a3441015e7e27f8c711a5d6055d8c01692502ca4648f82704424c25a7252e3505657e25dd30c1096e16fcccf","up":true,"one":"269e5d200ae242b0b101bd7d465e009fc7eb22b074f1d9b562580bf452d592420e4063d03fab92c6fa61a32633492ee1b4fb20c3a8f44ec7ca07839bee871828"},{"one":"2cb9a1452559314b74e4e1956a260ee2ef7bed85215e444968f54148eb7662f76ec8e7e0fe2cb32d9eecde8d4748a1f776dca7c7f121fde1722d0ba514498d11","other":"70af807b8e945627dae8a77496db558a2d1581eb89b15f25d2b4881679e5895c12955fd61558a554f5efb989e8940a2fb5eab2aca46de46ba1f059fe58c43311","up":true},{"one":"1dd15e2816825bb52419c0f79a13ef9380a2e15fae07d7edae177b334d202c5546d701cebec53b7bc26b97928d5c317fffbe84ed130510f195f9c91b120c93ca","up":true,"other":"03e750d46b9a4a9e2047a5b718f427834417f4eb48d8794fde26593a3adbbce48750fa93f47548e342677e94888941ebd492a844a5d8325f67a0db8e94a09b55"},{"up":true,"other":"8eea2dd2475d894484f737bb61fa632585ab0a82e47c070327eb65de8b5cf76ad6bbebba1b94b5fe19f6c631e429d1273740937da9ec6cabbcdfd5bd176cc362","one":"00508d6e28f4b503d346983d740c24c440c6eab33128d86c60cb2ce8c70d17189a96a7e6f212dd25f383d1902d04206784edb7fc8b1c391e4465afcd18192c1c"},{"up":true,"other":"93f716fc299e1ef6c7ca4f12f5d81a68d65a07f5c86e7605c6518b8f99d792b8d653583ccf031d3855a8835674c16cff79eeee407ed090e94a58bf7333062d1e","one":"bee0751f64c744ef2862b780ce251b2e21e073b57cec0b57c974b913b92c452aa089f1f66dcf259bdd7ab612bfbca0c8f421a94c564941efd4a1a99c2443fade"},{"other":"4c53fcf455540cc5f4fd48a57fb68e643eaf769085f350129e1dfa76ef56d33f31b950a42721dbe445a73151edbdb54ce0169204a17a58031a07f11ea1347ed0","up":true,"one":"ee9e52421dac0a5654edba1892117bb8762de147ef6719a85d627b6af451cddf265f0282af905e72e19c754ffe3c4eb5c37fc56d26dc0873182891a85205552c"},{"one":"9af8f0912f664cb4b4515f6b66c432b6d9e8a97f338691517bab0f221718c9ea95ef04243ea7c9573daa5183969b9e9fd4469a58014d88acd0adca3379679cff","up":true,"other":"2017096c1b5481de69fff5c6a993e2f2014e6f39fd725613cd441ba883356ce1beea333028890bfd277a6e5118e7fd3bc15d7c3e11d9453a8fc9aeccff68306b"},{"up":true,"other":"e777565409c3fa228f25352f28004671b6f9451fe21666263e71d67d18cf7890f3015af4717267bcd736322239aae34ba0f596e8e98d1628a539cef3a521ed7d","one":"47e3e22c28c4217e3ba4f83ecf3b5767943c3d49c3b829ad510a7412ae868d60f2c9e4cb51e52e6153aa6555eb2cc1ecaae62793119774dbe3a09d8550d9e2d7"},{"one":"c8b55e1f0042ff9ac2b73593f79ce125b3b613354ed90a086b18e1f1809c883d0c0e9df6ec080181ef023833cde585de184523483db878aa65c9939a1a1fcf2d","other":"ec96e314abe60637723a8242b6afeed45ff1a8faca649f8dc7f175ed9db4118bc6d406f5d26d3d71e54699a97b7da59a3d8fb934501b60c15bd5e0501f8fe792","up":true},{"up":true,"other":"3780f49d8de4f4a44cba2cff7c6acedb10c32a737808c8c7328c29f7686d0351f9c8d4429b320af2560f550f9692507c426c5d30858b0ef79bd8c5e4db58d6b8","one":"78739942ae915ea9447fbc435162fc63f18a6f54a1473fd4aa2ed2391a5d62ffa8e32e0aaaa2b83022bd1ff15210daea42433e944235c95a681fac54f75da5de"},{"one":"03e750d46b9a4a9e2047a5b718f427834417f4eb48d8794fde26593a3adbbce48750fa93f47548e342677e94888941ebd492a844a5d8325f67a0db8e94a09b55","up":true,"other":"3780f49d8de4f4a44cba2cff7c6acedb10c32a737808c8c7328c29f7686d0351f9c8d4429b320af2560f550f9692507c426c5d30858b0ef79bd8c5e4db58d6b8"},{"one":"aee9aaece9a50dd4e85d79f1286165181251ebbbffe461e87e98e04ee5a4730b3d31ff6ed63fe403c1ecff165cbe1cf7d791f4a6fd16685726c290344ed65406","up":true,"other":"c581746c5ea238a632de0b30da06de317dc9f613cc9bb16c41509e5d1381b041f2d2e6a65018667bb6b57868577ff04a2773a451dd03b6b599bff5d8cbd4017a"},{"one":"5e36d45cd33f0deda83595a1d7196ae42408793b821245224d6585b4291c88149403d2f8b49523137fb26f8353647b3e48261c198504ccf8544cc9131d2890d8","up":true,"other":"ddfccaa30a25c32b199a98046669df50b5bb07447cf9dafec69934d9b38dfe447bd0b8fc8b33b0453d63088ff65deca8bec067a3f79a545c988ab7f7b735e1f2"},{"one":"b13271912256c91940de954a90f73889c8abb76c4e92ecedd68e37dc50dcb253a2164607400f2b798d3c2d612d1c77bc677ddac892614a7296254099251e8379","up":true,"other":"841c007c8c5c96f6d7759d186bbf008e64fb9ab6e88c215c0fff31285ac3a47108962699f6fcc995bce7059787fa69bfbc82d36bfaa155ee207a7044bb839c96"},{"other":"128c42c3e21d7ba3c1bb7481c1119fa85124e827114a0bf7243c9b34b61f2f70111402ef1d4bfa8df69f2472f95b4ad44a95991c1adbe85c20f66436c9247e4e","up":true,"one":"1e2f58e271f5f55bf1ec82db59cd6b29b3badae06263ea3bb876a131f1869f9fa9477538887fad30ca623f23d06a952a3f8aca1a581c3ed4faf0ad79b47d42b9"},{"up":true,"other":"03e750d46b9a4a9e2047a5b718f427834417f4eb48d8794fde26593a3adbbce48750fa93f47548e342677e94888941ebd492a844a5d8325f67a0db8e94a09b55","one":"5fd28368ab1f2702060367fbc0aa218a5461a60fa9fb4aa77cf9a65b06980c8802df4ec04392e78a83276a7509acba337fd9d8391fa47b3ea77d3959f5c6a35b"},{"one":"9e67e97b2552fd6c0a82cff57d6144aecc05f751a30bf61438cc545fb5932f9b9c901309a14c7ad868bae0d274b999cec111ec9dfd51d6392db9dc717fa5378c","other":"8b3023625eecf7dd330df127a31454cea24354d099ca621af1a1232e5b59961ceafbd9f7e0f658905d80617f7efbc4038d84fb6e3cc9347a1f4f1775fff46965","up":true},{"one":"8b3023625eecf7dd330df127a31454cea24354d099ca621af1a1232e5b59961ceafbd9f7e0f658905d80617f7efbc4038d84fb6e3cc9347a1f4f1775fff46965","up":true,"other":"c581746c5ea238a632de0b30da06de317dc9f613cc9bb16c41509e5d1381b041f2d2e6a65018667bb6b57868577ff04a2773a451dd03b6b599bff5d8cbd4017a"},{"one":"eb4bab9ad390760b3eece117dbec9792aa56485cd4a6824094337f83463efbe0174b73aba386da238f7b1724aef4cb6a3017cf35999ca591a1e56b67b1ecc250","up":true,"other":"5732476eb1c7b5ab050759a7169281e6ff583df6de07c2019fb105dfad4df268587b87baf6e0d210f77b048bd62b501b713a919964f35b862b403b478d88a1b6"},{"other":"bee0751f64c744ef2862b780ce251b2e21e073b57cec0b57c974b913b92c452aa089f1f66dcf259bdd7ab612bfbca0c8f421a94c564941efd4a1a99c2443fade","up":true,"one":"841c007c8c5c96f6d7759d186bbf008e64fb9ab6e88c215c0fff31285ac3a47108962699f6fcc995bce7059787fa69bfbc82d36bfaa155ee207a7044bb839c96"},{"one":"5732476eb1c7b5ab050759a7169281e6ff583df6de07c2019fb105dfad4df268587b87baf6e0d210f77b048bd62b501b713a919964f35b862b403b478d88a1b6","other":"5e36d45cd33f0deda83595a1d7196ae42408793b821245224d6585b4291c88149403d2f8b49523137fb26f8353647b3e48261c198504ccf8544cc9131d2890d8","up":true},{"one":"0445005ab3e1a97c7fb9d9a4e77d4da6c51881f2454a35f945fdce1318e863ef3e27784938720c80ebbb3c6440e63bd9ae0fecdf21d78d7e24357ddd9b430b37","other":"4c53fcf455540cc5f4fd48a57fb68e643eaf769085f350129e1dfa76ef56d33f31b950a42721dbe445a73151edbdb54ce0169204a17a58031a07f11ea1347ed0","up":true},{"other":"4367ed557fe94e971003fe0a3236c6bd619e232117818a35f394995ef9782b930279344042dc165069780e8457106299679af6f61c1482d54f31fd19d4f9dd88","up":true,"one":"70af807b8e945627dae8a77496db558a2d1581eb89b15f25d2b4881679e5895c12955fd61558a554f5efb989e8940a2fb5eab2aca46de46ba1f059fe58c43311"},{"up":true,"other":"03e750d46b9a4a9e2047a5b718f427834417f4eb48d8794fde26593a3adbbce48750fa93f47548e342677e94888941ebd492a844a5d8325f67a0db8e94a09b55","one":"4a13668afb8e9fb9db2c4e4e4ff754cbb40c59692c6c5cd70fcba3199ef05c1cf1b19c4fca62396690c90ab7b16f9a18ed375f946a4166137cac349ff3b02933"},{"one":"841c007c8c5c96f6d7759d186bbf008e64fb9ab6e88c215c0fff31285ac3a47108962699f6fcc995bce7059787fa69bfbc82d36bfaa155ee207a7044bb839c96","other":"e24f63d4515d5d1e8e85f06afde4da3144258f7569d2a0b007aecc13c9cb17a8ad75d85e30a1bb7bfee7b81a219b58e969787f11710c82d0904568a60cc2fe5d","up":true},{"one":"df4e07354dd593b1986e996f84c3e97147f72f4c6367ec876472c7384fe2d850ee6a8abeb37b789e7c50c12aa3533f19a6c7d9c37bb1b884c61eee307488ed88","other":"e968aa3ce0d669bab524f11df68ea707d6f4ed9c4367b78e20acd66af8deb0a965368ed4fa171f579ba931001f47092e97d5d37d80075570f61a2eebb21bbd4b","up":true},{"one":"ddfccaa30a25c32b199a98046669df50b5bb07447cf9dafec69934d9b38dfe447bd0b8fc8b33b0453d63088ff65deca8bec067a3f79a545c988ab7f7b735e1f2","up":true,"other":"5732476eb1c7b5ab050759a7169281e6ff583df6de07c2019fb105dfad4df268587b87baf6e0d210f77b048bd62b501b713a919964f35b862b403b478d88a1b6"},{"one":"0445005ab3e1a97c7fb9d9a4e77d4da6c51881f2454a35f945fdce1318e863ef3e27784938720c80ebbb3c6440e63bd9ae0fecdf21d78d7e24357ddd9b430b37","other":"e777565409c3fa228f25352f28004671b6f9451fe21666263e71d67d18cf7890f3015af4717267bcd736322239aae34ba0f596e8e98d1628a539cef3a521ed7d","up":true},{"one":"8eea2dd2475d894484f737bb61fa632585ab0a82e47c070327eb65de8b5cf76ad6bbebba1b94b5fe19f6c631e429d1273740937da9ec6cabbcdfd5bd176cc362","up":true,"other":"2cb9a1452559314b74e4e1956a260ee2ef7bed85215e444968f54148eb7662f76ec8e7e0fe2cb32d9eecde8d4748a1f776dca7c7f121fde1722d0ba514498d11"},{"one":"06a6d7bd7fc3d209e3464e20fdc04df0c20f5fc991172a7847dab790db55daf735cf56d65d5471291511ce99524a934c2cb839cdb6ef4dcf7f025b600f5adbea","up":true,"other":"f808e36fd29885cc4f1ad57b26e64deabc0b0fb164ac03017ff2c89671a1ec07706dd28120ceadd8322c6e2387623bc14fa284a0173f70fe722ecc8326f8c932"},{"one":"0d502ca2f60cadbf375c195365090b216ac99af07abb3a35d3f3dbdc4de7eb2a8f93a3f2a240fc5905dca74e78a05a5837484a117477fb279052889c52b99c6c","up":true,"other":"2455595a3aefc0cd619c569d920c279e968022ee53cc07b5a0e3e4d7f8ce315739d432389a2bc26c1890fd8af33c1ced0790c7f644d205361e78c787c803ad88"},{"up":true,"other":"47e3e22c28c4217e3ba4f83ecf3b5767943c3d49c3b829ad510a7412ae868d60f2c9e4cb51e52e6153aa6555eb2cc1ecaae62793119774dbe3a09d8550d9e2d7","one":"3780f49d8de4f4a44cba2cff7c6acedb10c32a737808c8c7328c29f7686d0351f9c8d4429b320af2560f550f9692507c426c5d30858b0ef79bd8c5e4db58d6b8"},{"other":"4367ed557fe94e971003fe0a3236c6bd619e232117818a35f394995ef9782b930279344042dc165069780e8457106299679af6f61c1482d54f31fd19d4f9dd88","up":true,"one":"ba5b2e12f30e2819c19f9336b13b84145af8dc91197840f49c6dc9a8995fbdf37635d5bc42fbc9f59da666df42a3a16e10c02bb0e556e5c9526a74194b23bb96"},{"up":true,"other":"08f640d4494b0db8b99e7f7a7b3a1d267f457d5c42ea8002d2a509fee7f06fda7e115e270f43372ebc836748aa3456b8d47783064655b38314731f0ee1d8fac1","one":"698cf5333166bf22a15679cb0d88d7382fe980455a6c288556310898e6aeb3fb04262b89e146d4bff2a4e5501574bd7b55adf3a2ccde080e7a3acab9fdb78e1a"},{"one":"32627f1a91175809b9141af528c4d77407385102a3ed6afee81acb79b0988f91075c670a09203238e266f5ad0d61b9388c9097fe00a54ced8f04423830768768","other":"740371f4438046c4f3cb3e0c47cd1c35df4565addb44dc4a7aa0be864cf43f726dc0616502cd67fd7d88008acf8ba1e3f9ef60aeb2d3de3896dccd8765c2bfb3","up":true},{"one":"e968aa3ce0d669bab524f11df68ea707d6f4ed9c4367b78e20acd66af8deb0a965368ed4fa171f579ba931001f47092e97d5d37d80075570f61a2eebb21bbd4b","other":"2cb9a1452559314b74e4e1956a260ee2ef7bed85215e444968f54148eb7662f76ec8e7e0fe2cb32d9eecde8d4748a1f776dca7c7f121fde1722d0ba514498d11","up":true},{"one":"08f640d4494b0db8b99e7f7a7b3a1d267f457d5c42ea8002d2a509fee7f06fda7e115e270f43372ebc836748aa3456b8d47783064655b38314731f0ee1d8fac1","up":true,"other":"78739942ae915ea9447fbc435162fc63f18a6f54a1473fd4aa2ed2391a5d62ffa8e32e0aaaa2b83022bd1ff15210daea42433e944235c95a681fac54f75da5de"},{"other":"2cb9a1452559314b74e4e1956a260ee2ef7bed85215e444968f54148eb7662f76ec8e7e0fe2cb32d9eecde8d4748a1f776dca7c7f121fde1722d0ba514498d11","up":true,"one":"269e5d200ae242b0b101bd7d465e009fc7eb22b074f1d9b562580bf452d592420e4063d03fab92c6fa61a32633492ee1b4fb20c3a8f44ec7ca07839bee871828"},{"one":"213a1fdcf601bbda1a8531eb2aefc33daef7d7a2312012e8a781bd4ac732d7c267fdc8ceb45061783e64995ce74e67fc330c6a043bbab3f5f88a0e1e2bb4b48c","up":true,"other":"5732476eb1c7b5ab050759a7169281e6ff583df6de07c2019fb105dfad4df268587b87baf6e0d210f77b048bd62b501b713a919964f35b862b403b478d88a1b6"},{"other":"4c53fcf455540cc5f4fd48a57fb68e643eaf769085f350129e1dfa76ef56d33f31b950a42721dbe445a73151edbdb54ce0169204a17a58031a07f11ea1347ed0","up":true,"one":"e777565409c3fa228f25352f28004671b6f9451fe21666263e71d67d18cf7890f3015af4717267bcd736322239aae34ba0f596e8e98d1628a539cef3a521ed7d"},{"one":"1e2f58e271f5f55bf1ec82db59cd6b29b3badae06263ea3bb876a131f1869f9fa9477538887fad30ca623f23d06a952a3f8aca1a581c3ed4faf0ad79b47d42b9","up":true,"other":"00508d6e28f4b503d346983d740c24c440c6eab33128d86c60cb2ce8c70d17189a96a7e6f212dd25f383d1902d04206784edb7fc8b1c391e4465afcd18192c1c"},{"other":"4c53fcf455540cc5f4fd48a57fb68e643eaf769085f350129e1dfa76ef56d33f31b950a42721dbe445a73151edbdb54ce0169204a17a58031a07f11ea1347ed0","up":true,"one":"12b2d36d0e1a7255bde9c81fc9fac8befd7119bbafb74773cee281a73a9095fcceb8a5bc6fc01d8fcc948adbf2b6b6d190017b307875fbea971e6604ddb219de"},{"other":"528d9876a41762f88bbe70f95de1b28998844d65449a5eff254b034db3b4925b6ee3b56fa32f012b448a19d5f429ba0892cce3634cedad6cbed0e03914ccc2b5","up":true,"one":"8b3023625eecf7dd330df127a31454cea24354d099ca621af1a1232e5b59961ceafbd9f7e0f658905d80617f7efbc4038d84fb6e3cc9347a1f4f1775fff46965"},{"one":"df4e07354dd593b1986e996f84c3e97147f72f4c6367ec876472c7384fe2d850ee6a8abeb37b789e7c50c12aa3533f19a6c7d9c37bb1b884c61eee307488ed88","other":"2cb9a1452559314b74e4e1956a260ee2ef7bed85215e444968f54148eb7662f76ec8e7e0fe2cb32d9eecde8d4748a1f776dca7c7f121fde1722d0ba514498d11","up":true},{"one":"1dd15e2816825bb52419c0f79a13ef9380a2e15fae07d7edae177b334d202c5546d701cebec53b7bc26b97928d5c317fffbe84ed130510f195f9c91b120c93ca","up":true,"other":"4a13668afb8e9fb9db2c4e4e4ff754cbb40c59692c6c5cd70fcba3199ef05c1cf1b19c4fca62396690c90ab7b16f9a18ed375f946a4166137cac349ff3b02933"},{"one":"2455595a3aefc0cd619c569d920c279e968022ee53cc07b5a0e3e4d7f8ce315739d432389a2bc26c1890fd8af33c1ced0790c7f644d205361e78c787c803ad88","other":"ccbbc901d05610202edfd1eba445dc0c93c3ab1dfcc4c9eecd9f1f12521508407429b605840eb8fed9893a1fd8ef6dcd29c9627fe8d3d41ca094b10ab977aa8b","up":true},{"up":true,"other":"528d9876a41762f88bbe70f95de1b28998844d65449a5eff254b034db3b4925b6ee3b56fa32f012b448a19d5f429ba0892cce3634cedad6cbed0e03914ccc2b5","one":"aee9aaece9a50dd4e85d79f1286165181251ebbbffe461e87e98e04ee5a4730b3d31ff6ed63fe403c1ecff165cbe1cf7d791f4a6fd16685726c290344ed65406"},{"other":"2cb9a1452559314b74e4e1956a260ee2ef7bed85215e444968f54148eb7662f76ec8e7e0fe2cb32d9eecde8d4748a1f776dca7c7f121fde1722d0ba514498d11","up":true,"one":"20fcc315548210e104fb0bd5deb4c5af2d78a075a3441015e7e27f8c711a5d6055d8c01692502ca4648f82704424c25a7252e3505657e25dd30c1096e16fcccf"},{"one":"5e36d45cd33f0deda83595a1d7196ae42408793b821245224d6585b4291c88149403d2f8b49523137fb26f8353647b3e48261c198504ccf8544cc9131d2890d8","up":true,"other":"b13271912256c91940de954a90f73889c8abb76c4e92ecedd68e37dc50dcb253a2164607400f2b798d3c2d612d1c77bc677ddac892614a7296254099251e8379"},{"one":"740371f4438046c4f3cb3e0c47cd1c35df4565addb44dc4a7aa0be864cf43f726dc0616502cd67fd7d88008acf8ba1e3f9ef60aeb2d3de3896dccd8765c2bfb3","up":true,"other":"eb4bab9ad390760b3eece117dbec9792aa56485cd4a6824094337f83463efbe0174b73aba386da238f7b1724aef4cb6a3017cf35999ca591a1e56b67b1ecc250"},{"one":"70af807b8e945627dae8a77496db558a2d1581eb89b15f25d2b4881679e5895c12955fd61558a554f5efb989e8940a2fb5eab2aca46de46ba1f059fe58c43311","up":true,"other":"1e2f58e271f5f55bf1ec82db59cd6b29b3badae06263ea3bb876a131f1869f9fa9477538887fad30ca623f23d06a952a3f8aca1a581c3ed4faf0ad79b47d42b9"},{"other":"e24f63d4515d5d1e8e85f06afde4da3144258f7569d2a0b007aecc13c9cb17a8ad75d85e30a1bb7bfee7b81a219b58e969787f11710c82d0904568a60cc2fe5d","up":true,"one":"dc41672c95ae1af5b7008f7b1c4e232dc469c4969095d357a6e713257ddb8f7220eadf41082cb22503cee38c042160f5d9750f4787b6e44dc8eaa5bd76df8e55"},{"one":"18c79fcf8500f4d5cb609ef72277112430da75ef83466bdbe0ea4d3a5d6997ca27a94ba0bb35a7a40f5b56bd8242cb20228a6802c4cbb27b934a904eed057b2c","up":true,"other":"4367ed557fe94e971003fe0a3236c6bd619e232117818a35f394995ef9782b930279344042dc165069780e8457106299679af6f61c1482d54f31fd19d4f9dd88"},{"one":"2cb9a1452559314b74e4e1956a260ee2ef7bed85215e444968f54148eb7662f76ec8e7e0fe2cb32d9eecde8d4748a1f776dca7c7f121fde1722d0ba514498d11","up":true,"other":"a93e19158ae6a4261186b663bf109258d759e42b8e0e1d5c06e79a9b6844e6acb41c0a4ce38dfdf250d6016aa796fb78807a7f91738f4eef8a36dafdd60afec7"},{"up":true,"other":"9af8f0912f664cb4b4515f6b66c432b6d9e8a97f338691517bab0f221718c9ea95ef04243ea7c9573daa5183969b9e9fd4469a58014d88acd0adca3379679cff","one":"eb4bab9ad390760b3eece117dbec9792aa56485cd4a6824094337f83463efbe0174b73aba386da238f7b1724aef4cb6a3017cf35999ca591a1e56b67b1ecc250"},{"other":"3780f49d8de4f4a44cba2cff7c6acedb10c32a737808c8c7328c29f7686d0351f9c8d4429b320af2560f550f9692507c426c5d30858b0ef79bd8c5e4db58d6b8","up":true,"one":"4a13668afb8e9fb9db2c4e4e4ff754cbb40c59692c6c5cd70fcba3199ef05c1cf1b19c4fca62396690c90ab7b16f9a18ed375f946a4166137cac349ff3b02933"},{"one":"128c42c3e21d7ba3c1bb7481c1119fa85124e827114a0bf7243c9b34b61f2f70111402ef1d4bfa8df69f2472f95b4ad44a95991c1adbe85c20f66436c9247e4e","up":true,"other":"641004e2e499316f46b8b5e0744a5bfcb24323d44c25ed043d57b18406b71bb4e6053df63eb83488c950ba74ae007bc4d5ae711a891eded4a8ea6aa45fb8312a"},{"one":"00508d6e28f4b503d346983d740c24c440c6eab33128d86c60cb2ce8c70d17189a96a7e6f212dd25f383d1902d04206784edb7fc8b1c391e4465afcd18192c1c","up":true,"other":"70af807b8e945627dae8a77496db558a2d1581eb89b15f25d2b4881679e5895c12955fd61558a554f5efb989e8940a2fb5eab2aca46de46ba1f059fe58c43311"},{"one":"ec96e314abe60637723a8242b6afeed45ff1a8faca649f8dc7f175ed9db4118bc6d406f5d26d3d71e54699a97b7da59a3d8fb934501b60c15bd5e0501f8fe792","other":"b13271912256c91940de954a90f73889c8abb76c4e92ecedd68e37dc50dcb253a2164607400f2b798d3c2d612d1c77bc677ddac892614a7296254099251e8379","up":true},{"one":"9af8f0912f664cb4b4515f6b66c432b6d9e8a97f338691517bab0f221718c9ea95ef04243ea7c9573daa5183969b9e9fd4469a58014d88acd0adca3379679cff","other":"740371f4438046c4f3cb3e0c47cd1c35df4565addb44dc4a7aa0be864cf43f726dc0616502cd67fd7d88008acf8ba1e3f9ef60aeb2d3de3896dccd8765c2bfb3","up":true},{"one":"4c53fcf455540cc5f4fd48a57fb68e643eaf769085f350129e1dfa76ef56d33f31b950a42721dbe445a73151edbdb54ce0169204a17a58031a07f11ea1347ed0","up":true,"other":"4367ed557fe94e971003fe0a3236c6bd619e232117818a35f394995ef9782b930279344042dc165069780e8457106299679af6f61c1482d54f31fd19d4f9dd88"},{"other":"ec96e314abe60637723a8242b6afeed45ff1a8faca649f8dc7f175ed9db4118bc6d406f5d26d3d71e54699a97b7da59a3d8fb934501b60c15bd5e0501f8fe792","up":true,"one":"f808e36fd29885cc4f1ad57b26e64deabc0b0fb164ac03017ff2c89671a1ec07706dd28120ceadd8322c6e2387623bc14fa284a0173f70fe722ecc8326f8c932"},{"other":"96d5ac5effb367c45d8329e73de0cb9f7bd4090b1627416fd7b0a28062959ed5e87042c9f1b4bc8653d27d5f9ab3e0bdec8f09a2f2d4a1bcfd69d68234fdfb12","up":true,"one":"78739942ae915ea9447fbc435162fc63f18a6f54a1473fd4aa2ed2391a5d62ffa8e32e0aaaa2b83022bd1ff15210daea42433e944235c95a681fac54f75da5de"},{"up":true,"other":"aee9aaece9a50dd4e85d79f1286165181251ebbbffe461e87e98e04ee5a4730b3d31ff6ed63fe403c1ecff165cbe1cf7d791f4a6fd16685726c290344ed65406","one":"9e67e97b2552fd6c0a82cff57d6144aecc05f751a30bf61438cc545fb5932f9b9c901309a14c7ad868bae0d274b999cec111ec9dfd51d6392db9dc717fa5378c"},{"one":"b13271912256c91940de954a90f73889c8abb76c4e92ecedd68e37dc50dcb253a2164607400f2b798d3c2d612d1c77bc677ddac892614a7296254099251e8379","other":"067835838d850b0a649e0e359329349cb2c599c3301bbc122547847a0273597187f745cd820f743775d6c1c44bf3be7e9bdb470a1defa3aa78f41411773cd371","up":true},{"other":"e34e530095c62d56ea231fc2fd30f3099d7ec88212d4bfb0144efb0232b2f7b48ab438fe3c2211f6bb70a0bf89816b590da44d5cfb9ef817f4c04cfbd0ca37a6","up":true,"one":"641004e2e499316f46b8b5e0744a5bfcb24323d44c25ed043d57b18406b71bb4e6053df63eb83488c950ba74ae007bc4d5ae711a891eded4a8ea6aa45fb8312a"},{"up":true,"other":"ef8f752702c272b1efa3df07957eaaf69854f906df7eebc65b9e5afcb2d3302c712ecf7f4730915f7f29d60cd3463e8393f4d7e34c1b4a7696c855332e4b3d25","one":"a93e19158ae6a4261186b663bf109258d759e42b8e0e1d5c06e79a9b6844e6acb41c0a4ce38dfdf250d6016aa796fb78807a7f91738f4eef8a36dafdd60afec7"},{"other":"0445005ab3e1a97c7fb9d9a4e77d4da6c51881f2454a35f945fdce1318e863ef3e27784938720c80ebbb3c6440e63bd9ae0fecdf21d78d7e24357ddd9b430b37","up":true,"one":"ee9e52421dac0a5654edba1892117bb8762de147ef6719a85d627b6af451cddf265f0282af905e72e19c754ffe3c4eb5c37fc56d26dc0873182891a85205552c"},{"other":"528d9876a41762f88bbe70f95de1b28998844d65449a5eff254b034db3b4925b6ee3b56fa32f012b448a19d5f429ba0892cce3634cedad6cbed0e03914ccc2b5","up":true,"one":"bde03ff26a216400b61d07d3eaa865f8b597a52f130ecd44af60d526d4b30c8978cb10c16f4fcbf391ef3a3e5de2aace4c077e9ae6d15451506f370190fbda04"},{"other":"a0a7b4ccd7d2222f59c202373736c03204f38088dcae48afab6e204b663dff0b06df2ceafc808351e45f54effd5c32481df220a938d1c58d49cd31c32bb20d1e","up":true,"one":"bee0751f64c744ef2862b780ce251b2e21e073b57cec0b57c974b913b92c452aa089f1f66dcf259bdd7ab612bfbca0c8f421a94c564941efd4a1a99c2443fade"},{"one":"c581746c5ea238a632de0b30da06de317dc9f613cc9bb16c41509e5d1381b041f2d2e6a65018667bb6b57868577ff04a2773a451dd03b6b599bff5d8cbd4017a","other":"4a13668afb8e9fb9db2c4e4e4ff754cbb40c59692c6c5cd70fcba3199ef05c1cf1b19c4fca62396690c90ab7b16f9a18ed375f946a4166137cac349ff3b02933","up":true},{"one":"47e3e22c28c4217e3ba4f83ecf3b5767943c3d49c3b829ad510a7412ae868d60f2c9e4cb51e52e6153aa6555eb2cc1ecaae62793119774dbe3a09d8550d9e2d7","other":"f9db826a99d327db544fa023ed13b689fd7c40ac9abdfd59d376efd245839ab8d34a3b5d9783fe0461e7ccdff35395e8df8983396df1a87f505663139eab7b20","up":true},{"one":"f9db826a99d327db544fa023ed13b689fd7c40ac9abdfd59d376efd245839ab8d34a3b5d9783fe0461e7ccdff35395e8df8983396df1a87f505663139eab7b20","up":true,"other":"0445005ab3e1a97c7fb9d9a4e77d4da6c51881f2454a35f945fdce1318e863ef3e27784938720c80ebbb3c6440e63bd9ae0fecdf21d78d7e24357ddd9b430b37"},{"other":"ef8f752702c272b1efa3df07957eaaf69854f906df7eebc65b9e5afcb2d3302c712ecf7f4730915f7f29d60cd3463e8393f4d7e34c1b4a7696c855332e4b3d25","up":true,"one":"528d9876a41762f88bbe70f95de1b28998844d65449a5eff254b034db3b4925b6ee3b56fa32f012b448a19d5f429ba0892cce3634cedad6cbed0e03914ccc2b5"},{"one":"5732476eb1c7b5ab050759a7169281e6ff583df6de07c2019fb105dfad4df268587b87baf6e0d210f77b048bd62b501b713a919964f35b862b403b478d88a1b6","other":"740371f4438046c4f3cb3e0c47cd1c35df4565addb44dc4a7aa0be864cf43f726dc0616502cd67fd7d88008acf8ba1e3f9ef60aeb2d3de3896dccd8765c2bfb3","up":true},{"one":"c8b55e1f0042ff9ac2b73593f79ce125b3b613354ed90a086b18e1f1809c883d0c0e9df6ec080181ef023833cde585de184523483db878aa65c9939a1a1fcf2d","other":"128c42c3e21d7ba3c1bb7481c1119fa85124e827114a0bf7243c9b34b61f2f70111402ef1d4bfa8df69f2472f95b4ad44a95991c1adbe85c20f66436c9247e4e","up":true},{"one":"dd1ecdd5e7bdd1ab85a946132cfd7e27c8a29e0256ebe859a9c9283cbb872f9406b30a835826ecece342ab5c41f4c34fdb75049acf0ee134ca8f94c3158a73e0","other":"c8b55e1f0042ff9ac2b73593f79ce125b3b613354ed90a086b18e1f1809c883d0c0e9df6ec080181ef023833cde585de184523483db878aa65c9939a1a1fcf2d","up":true},{"up":true,"other":"bee0751f64c744ef2862b780ce251b2e21e073b57cec0b57c974b913b92c452aa089f1f66dcf259bdd7ab612bfbca0c8f421a94c564941efd4a1a99c2443fade","one":"067835838d850b0a649e0e359329349cb2c599c3301bbc122547847a0273597187f745cd820f743775d6c1c44bf3be7e9bdb470a1defa3aa78f41411773cd371"},{"one":"4367ed557fe94e971003fe0a3236c6bd619e232117818a35f394995ef9782b930279344042dc165069780e8457106299679af6f61c1482d54f31fd19d4f9dd88","up":true,"other":"c581746c5ea238a632de0b30da06de317dc9f613cc9bb16c41509e5d1381b041f2d2e6a65018667bb6b57868577ff04a2773a451dd03b6b599bff5d8cbd4017a"},{"other":"00508d6e28f4b503d346983d740c24c440c6eab33128d86c60cb2ce8c70d17189a96a7e6f212dd25f383d1902d04206784edb7fc8b1c391e4465afcd18192c1c","up":true,"one":"03e750d46b9a4a9e2047a5b718f427834417f4eb48d8794fde26593a3adbbce48750fa93f47548e342677e94888941ebd492a844a5d8325f67a0db8e94a09b55"},{"one":"ef8f752702c272b1efa3df07957eaaf69854f906df7eebc65b9e5afcb2d3302c712ecf7f4730915f7f29d60cd3463e8393f4d7e34c1b4a7696c855332e4b3d25","up":true,"other":"2cb9a1452559314b74e4e1956a260ee2ef7bed85215e444968f54148eb7662f76ec8e7e0fe2cb32d9eecde8d4748a1f776dca7c7f121fde1722d0ba514498d11"},{"one":"a0a7b4ccd7d2222f59c202373736c03204f38088dcae48afab6e204b663dff0b06df2ceafc808351e45f54effd5c32481df220a938d1c58d49cd31c32bb20d1e","other":"b13271912256c91940de954a90f73889c8abb76c4e92ecedd68e37dc50dcb253a2164607400f2b798d3c2d612d1c77bc677ddac892614a7296254099251e8379","up":true},{"one":"ccbbc901d05610202edfd1eba445dc0c93c3ab1dfcc4c9eecd9f1f12521508407429b605840eb8fed9893a1fd8ef6dcd29c9627fe8d3d41ca094b10ab977aa8b","other":"841c007c8c5c96f6d7759d186bbf008e64fb9ab6e88c215c0fff31285ac3a47108962699f6fcc995bce7059787fa69bfbc82d36bfaa155ee207a7044bb839c96","up":true},{"one":"93f716fc299e1ef6c7ca4f12f5d81a68d65a07f5c86e7605c6518b8f99d792b8d653583ccf031d3855a8835674c16cff79eeee407ed090e94a58bf7333062d1e","up":true,"other":"5e36d45cd33f0deda83595a1d7196ae42408793b821245224d6585b4291c88149403d2f8b49523137fb26f8353647b3e48261c198504ccf8544cc9131d2890d8"},{"one":"96d5ac5effb367c45d8329e73de0cb9f7bd4090b1627416fd7b0a28062959ed5e87042c9f1b4bc8653d27d5f9ab3e0bdec8f09a2f2d4a1bcfd69d68234fdfb12","up":true,"other":"08f640d4494b0db8b99e7f7a7b3a1d267f457d5c42ea8002d2a509fee7f06fda7e115e270f43372ebc836748aa3456b8d47783064655b38314731f0ee1d8fac1"},{"one":"e34e530095c62d56ea231fc2fd30f3099d7ec88212d4bfb0144efb0232b2f7b48ab438fe3c2211f6bb70a0bf89816b590da44d5cfb9ef817f4c04cfbd0ca37a6","up":true,"other":"2455595a3aefc0cd619c569d920c279e968022ee53cc07b5a0e3e4d7f8ce315739d432389a2bc26c1890fd8af33c1ced0790c7f644d205361e78c787c803ad88"},{"up":true,"other":"4a13668afb8e9fb9db2c4e4e4ff754cbb40c59692c6c5cd70fcba3199ef05c1cf1b19c4fca62396690c90ab7b16f9a18ed375f946a4166137cac349ff3b02933","one":"5fd28368ab1f2702060367fbc0aa218a5461a60fa9fb4aa77cf9a65b06980c8802df4ec04392e78a83276a7509acba337fd9d8391fa47b3ea77d3959f5c6a35b"},{"up":true,"other":"e34e530095c62d56ea231fc2fd30f3099d7ec88212d4bfb0144efb0232b2f7b48ab438fe3c2211f6bb70a0bf89816b590da44d5cfb9ef817f4c04cfbd0ca37a6","one":"e24f63d4515d5d1e8e85f06afde4da3144258f7569d2a0b007aecc13c9cb17a8ad75d85e30a1bb7bfee7b81a219b58e969787f11710c82d0904568a60cc2fe5d"},{"up":true,"other":"740371f4438046c4f3cb3e0c47cd1c35df4565addb44dc4a7aa0be864cf43f726dc0616502cd67fd7d88008acf8ba1e3f9ef60aeb2d3de3896dccd8765c2bfb3","one":"2017096c1b5481de69fff5c6a993e2f2014e6f39fd725613cd441ba883356ce1beea333028890bfd277a6e5118e7fd3bc15d7c3e11d9453a8fc9aeccff68306b"},{"one":"18c79fcf8500f4d5cb609ef72277112430da75ef83466bdbe0ea4d3a5d6997ca27a94ba0bb35a7a40f5b56bd8242cb20228a6802c4cbb27b934a904eed057b2c","other":"ba5b2e12f30e2819c19f9336b13b84145af8dc91197840f49c6dc9a8995fbdf37635d5bc42fbc9f59da666df42a3a16e10c02bb0e556e5c9526a74194b23bb96","up":true},{"one":"ddfccaa30a25c32b199a98046669df50b5bb07447cf9dafec69934d9b38dfe447bd0b8fc8b33b0453d63088ff65deca8bec067a3f79a545c988ab7f7b735e1f2","up":true,"other":"128c42c3e21d7ba3c1bb7481c1119fa85124e827114a0bf7243c9b34b61f2f70111402ef1d4bfa8df69f2472f95b4ad44a95991c1adbe85c20f66436c9247e4e"},{"one":"0445005ab3e1a97c7fb9d9a4e77d4da6c51881f2454a35f945fdce1318e863ef3e27784938720c80ebbb3c6440e63bd9ae0fecdf21d78d7e24357ddd9b430b37","up":true,"other":"c581746c5ea238a632de0b30da06de317dc9f613cc9bb16c41509e5d1381b041f2d2e6a65018667bb6b57868577ff04a2773a451dd03b6b599bff5d8cbd4017a"},{"one":"06a6d7bd7fc3d209e3464e20fdc04df0c20f5fc991172a7847dab790db55daf735cf56d65d5471291511ce99524a934c2cb839cdb6ef4dcf7f025b600f5adbea","up":true,"other":"ccbbc901d05610202edfd1eba445dc0c93c3ab1dfcc4c9eecd9f1f12521508407429b605840eb8fed9893a1fd8ef6dcd29c9627fe8d3d41ca094b10ab977aa8b"},{"one":"e777565409c3fa228f25352f28004671b6f9451fe21666263e71d67d18cf7890f3015af4717267bcd736322239aae34ba0f596e8e98d1628a539cef3a521ed7d","up":true,"other":"ec96e314abe60637723a8242b6afeed45ff1a8faca649f8dc7f175ed9db4118bc6d406f5d26d3d71e54699a97b7da59a3d8fb934501b60c15bd5e0501f8fe792"},{"up":true,"other":"70af807b8e945627dae8a77496db558a2d1581eb89b15f25d2b4881679e5895c12955fd61558a554f5efb989e8940a2fb5eab2aca46de46ba1f059fe58c43311","one":"df4e07354dd593b1986e996f84c3e97147f72f4c6367ec876472c7384fe2d850ee6a8abeb37b789e7c50c12aa3533f19a6c7d9c37bb1b884c61eee307488ed88"},{"other":"12b2d36d0e1a7255bde9c81fc9fac8befd7119bbafb74773cee281a73a9095fcceb8a5bc6fc01d8fcc948adbf2b6b6d190017b307875fbea971e6604ddb219de","up":true,"one":"70af807b8e945627dae8a77496db558a2d1581eb89b15f25d2b4881679e5895c12955fd61558a554f5efb989e8940a2fb5eab2aca46de46ba1f059fe58c43311"},{"up":true,"other":"b13271912256c91940de954a90f73889c8abb76c4e92ecedd68e37dc50dcb253a2164607400f2b798d3c2d612d1c77bc677ddac892614a7296254099251e8379","one":"128c42c3e21d7ba3c1bb7481c1119fa85124e827114a0bf7243c9b34b61f2f70111402ef1d4bfa8df69f2472f95b4ad44a95991c1adbe85c20f66436c9247e4e"},{"up":true,"other":"78739942ae915ea9447fbc435162fc63f18a6f54a1473fd4aa2ed2391a5d62ffa8e32e0aaaa2b83022bd1ff15210daea42433e944235c95a681fac54f75da5de","one":"698cf5333166bf22a15679cb0d88d7382fe980455a6c288556310898e6aeb3fb04262b89e146d4bff2a4e5501574bd7b55adf3a2ccde080e7a3acab9fdb78e1a"},{"up":true,"other":"c8b55e1f0042ff9ac2b73593f79ce125b3b613354ed90a086b18e1f1809c883d0c0e9df6ec080181ef023833cde585de184523483db878aa65c9939a1a1fcf2d","one":"20fcc315548210e104fb0bd5deb4c5af2d78a075a3441015e7e27f8c711a5d6055d8c01692502ca4648f82704424c25a7252e3505657e25dd30c1096e16fcccf"},{"up":true,"other":"ef8f752702c272b1efa3df07957eaaf69854f906df7eebc65b9e5afcb2d3302c712ecf7f4730915f7f29d60cd3463e8393f4d7e34c1b4a7696c855332e4b3d25","one":"4c53fcf455540cc5f4fd48a57fb68e643eaf769085f350129e1dfa76ef56d33f31b950a42721dbe445a73151edbdb54ce0169204a17a58031a07f11ea1347ed0"},{"one":"e968aa3ce0d669bab524f11df68ea707d6f4ed9c4367b78e20acd66af8deb0a965368ed4fa171f579ba931001f47092e97d5d37d80075570f61a2eebb21bbd4b","up":true,"other":"ccbbc901d05610202edfd1eba445dc0c93c3ab1dfcc4c9eecd9f1f12521508407429b605840eb8fed9893a1fd8ef6dcd29c9627fe8d3d41ca094b10ab977aa8b"},{"other":"5fd28368ab1f2702060367fbc0aa218a5461a60fa9fb4aa77cf9a65b06980c8802df4ec04392e78a83276a7509acba337fd9d8391fa47b3ea77d3959f5c6a35b","up":true,"one":"f9db826a99d327db544fa023ed13b689fd7c40ac9abdfd59d376efd245839ab8d34a3b5d9783fe0461e7ccdff35395e8df8983396df1a87f505663139eab7b20"},{"one":"0d502ca2f60cadbf375c195365090b216ac99af07abb3a35d3f3dbdc4de7eb2a8f93a3f2a240fc5905dca74e78a05a5837484a117477fb279052889c52b99c6c","up":true,"other":"e34e530095c62d56ea231fc2fd30f3099d7ec88212d4bfb0144efb0232b2f7b48ab438fe3c2211f6bb70a0bf89816b590da44d5cfb9ef817f4c04cfbd0ca37a6"},{"other":"70af807b8e945627dae8a77496db558a2d1581eb89b15f25d2b4881679e5895c12955fd61558a554f5efb989e8940a2fb5eab2aca46de46ba1f059fe58c43311","up":true,"one":"269e5d200ae242b0b101bd7d465e009fc7eb22b074f1d9b562580bf452d592420e4063d03fab92c6fa61a32633492ee1b4fb20c3a8f44ec7ca07839bee871828"},{"up":true,"other":"ec96e314abe60637723a8242b6afeed45ff1a8faca649f8dc7f175ed9db4118bc6d406f5d26d3d71e54699a97b7da59a3d8fb934501b60c15bd5e0501f8fe792","one":"dd1ecdd5e7bdd1ab85a946132cfd7e27c8a29e0256ebe859a9c9283cbb872f9406b30a835826ecece342ab5c41f4c34fdb75049acf0ee134ca8f94c3158a73e0"},{"one":"2cb9a1452559314b74e4e1956a260ee2ef7bed85215e444968f54148eb7662f76ec8e7e0fe2cb32d9eecde8d4748a1f776dca7c7f121fde1722d0ba514498d11","other":"5fd28368ab1f2702060367fbc0aa218a5461a60fa9fb4aa77cf9a65b06980c8802df4ec04392e78a83276a7509acba337fd9d8391fa47b3ea77d3959f5c6a35b","up":true},{"other":"32627f1a91175809b9141af528c4d77407385102a3ed6afee81acb79b0988f91075c670a09203238e266f5ad0d61b9388c9097fe00a54ced8f04423830768768","up":true,"one":"eb4bab9ad390760b3eece117dbec9792aa56485cd4a6824094337f83463efbe0174b73aba386da238f7b1724aef4cb6a3017cf35999ca591a1e56b67b1ecc250"},{"up":true,"other":"0445005ab3e1a97c7fb9d9a4e77d4da6c51881f2454a35f945fdce1318e863ef3e27784938720c80ebbb3c6440e63bd9ae0fecdf21d78d7e24357ddd9b430b37","one":"12b2d36d0e1a7255bde9c81fc9fac8befd7119bbafb74773cee281a73a9095fcceb8a5bc6fc01d8fcc948adbf2b6b6d190017b307875fbea971e6604ddb219de"},{"one":"ef8f752702c272b1efa3df07957eaaf69854f906df7eebc65b9e5afcb2d3302c712ecf7f4730915f7f29d60cd3463e8393f4d7e34c1b4a7696c855332e4b3d25","up":true,"other":"20fcc315548210e104fb0bd5deb4c5af2d78a075a3441015e7e27f8c711a5d6055d8c01692502ca4648f82704424c25a7252e3505657e25dd30c1096e16fcccf"},{"one":"ec96e314abe60637723a8242b6afeed45ff1a8faca649f8dc7f175ed9db4118bc6d406f5d26d3d71e54699a97b7da59a3d8fb934501b60c15bd5e0501f8fe792","up":true,"other":"06a6d7bd7fc3d209e3464e20fdc04df0c20f5fc991172a7847dab790db55daf735cf56d65d5471291511ce99524a934c2cb839cdb6ef4dcf7f025b600f5adbea"},{"other":"bde03ff26a216400b61d07d3eaa865f8b597a52f130ecd44af60d526d4b30c8978cb10c16f4fcbf391ef3a3e5de2aace4c077e9ae6d15451506f370190fbda04","up":true,"one":"8b3023625eecf7dd330df127a31454cea24354d099ca621af1a1232e5b59961ceafbd9f7e0f658905d80617f7efbc4038d84fb6e3cc9347a1f4f1775fff46965"},{"up":true,"other":"b13271912256c91940de954a90f73889c8abb76c4e92ecedd68e37dc50dcb253a2164607400f2b798d3c2d612d1c77bc677ddac892614a7296254099251e8379","one":"2455595a3aefc0cd619c569d920c279e968022ee53cc07b5a0e3e4d7f8ce315739d432389a2bc26c1890fd8af33c1ced0790c7f644d205361e78c787c803ad88"},{"one":"ccbbc901d05610202edfd1eba445dc0c93c3ab1dfcc4c9eecd9f1f12521508407429b605840eb8fed9893a1fd8ef6dcd29c9627fe8d3d41ca094b10ab977aa8b","up":true,"other":"641004e2e499316f46b8b5e0744a5bfcb24323d44c25ed043d57b18406b71bb4e6053df63eb83488c950ba74ae007bc4d5ae711a891eded4a8ea6aa45fb8312a"},{"other":"18c79fcf8500f4d5cb609ef72277112430da75ef83466bdbe0ea4d3a5d6997ca27a94ba0bb35a7a40f5b56bd8242cb20228a6802c4cbb27b934a904eed057b2c","up":true,"one":"78739942ae915ea9447fbc435162fc63f18a6f54a1473fd4aa2ed2391a5d62ffa8e32e0aaaa2b83022bd1ff15210daea42433e944235c95a681fac54f75da5de"},{"up":true,"other":"bde03ff26a216400b61d07d3eaa865f8b597a52f130ecd44af60d526d4b30c8978cb10c16f4fcbf391ef3a3e5de2aace4c077e9ae6d15451506f370190fbda04","one":"aee9aaece9a50dd4e85d79f1286165181251ebbbffe461e87e98e04ee5a4730b3d31ff6ed63fe403c1ecff165cbe1cf7d791f4a6fd16685726c290344ed65406"},{"other":"0d502ca2f60cadbf375c195365090b216ac99af07abb3a35d3f3dbdc4de7eb2a8f93a3f2a240fc5905dca74e78a05a5837484a117477fb279052889c52b99c6c","up":true,"one":"e24f63d4515d5d1e8e85f06afde4da3144258f7569d2a0b007aecc13c9cb17a8ad75d85e30a1bb7bfee7b81a219b58e969787f11710c82d0904568a60cc2fe5d"},{"up":true,"other":"e968aa3ce0d669bab524f11df68ea707d6f4ed9c4367b78e20acd66af8deb0a965368ed4fa171f579ba931001f47092e97d5d37d80075570f61a2eebb21bbd4b","one":"a93e19158ae6a4261186b663bf109258d759e42b8e0e1d5c06e79a9b6844e6acb41c0a4ce38dfdf250d6016aa796fb78807a7f91738f4eef8a36dafdd60afec7"},{"other":"128c42c3e21d7ba3c1bb7481c1119fa85124e827114a0bf7243c9b34b61f2f70111402ef1d4bfa8df69f2472f95b4ad44a95991c1adbe85c20f66436c9247e4e","up":true,"one":"740371f4438046c4f3cb3e0c47cd1c35df4565addb44dc4a7aa0be864cf43f726dc0616502cd67fd7d88008acf8ba1e3f9ef60aeb2d3de3896dccd8765c2bfb3"},{"one":"8eea2dd2475d894484f737bb61fa632585ab0a82e47c070327eb65de8b5cf76ad6bbebba1b94b5fe19f6c631e429d1273740937da9ec6cabbcdfd5bd176cc362","other":"20fcc315548210e104fb0bd5deb4c5af2d78a075a3441015e7e27f8c711a5d6055d8c01692502ca4648f82704424c25a7252e3505657e25dd30c1096e16fcccf","up":true},{"one":"9af8f0912f664cb4b4515f6b66c432b6d9e8a97f338691517bab0f221718c9ea95ef04243ea7c9573daa5183969b9e9fd4469a58014d88acd0adca3379679cff","other":"32627f1a91175809b9141af528c4d77407385102a3ed6afee81acb79b0988f91075c670a09203238e266f5ad0d61b9388c9097fe00a54ced8f04423830768768","up":true},{"up":true,"other":"bde03ff26a216400b61d07d3eaa865f8b597a52f130ecd44af60d526d4b30c8978cb10c16f4fcbf391ef3a3e5de2aace4c077e9ae6d15451506f370190fbda04","one":"c581746c5ea238a632de0b30da06de317dc9f613cc9bb16c41509e5d1381b041f2d2e6a65018667bb6b57868577ff04a2773a451dd03b6b599bff5d8cbd4017a"},{"other":"4a13668afb8e9fb9db2c4e4e4ff754cbb40c59692c6c5cd70fcba3199ef05c1cf1b19c4fca62396690c90ab7b16f9a18ed375f946a4166137cac349ff3b02933","up":true,"one":"ba5b2e12f30e2819c19f9336b13b84145af8dc91197840f49c6dc9a8995fbdf37635d5bc42fbc9f59da666df42a3a16e10c02bb0e556e5c9526a74194b23bb96"},{"other":"b13271912256c91940de954a90f73889c8abb76c4e92ecedd68e37dc50dcb253a2164607400f2b798d3c2d612d1c77bc677ddac892614a7296254099251e8379","up":true,"one":"5732476eb1c7b5ab050759a7169281e6ff583df6de07c2019fb105dfad4df268587b87baf6e0d210f77b048bd62b501b713a919964f35b862b403b478d88a1b6"},{"one":"00508d6e28f4b503d346983d740c24c440c6eab33128d86c60cb2ce8c70d17189a96a7e6f212dd25f383d1902d04206784edb7fc8b1c391e4465afcd18192c1c","up":true,"other":"e968aa3ce0d669bab524f11df68ea707d6f4ed9c4367b78e20acd66af8deb0a965368ed4fa171f579ba931001f47092e97d5d37d80075570f61a2eebb21bbd4b"},{"one":"32627f1a91175809b9141af528c4d77407385102a3ed6afee81acb79b0988f91075c670a09203238e266f5ad0d61b9388c9097fe00a54ced8f04423830768768","up":true,"other":"2017096c1b5481de69fff5c6a993e2f2014e6f39fd725613cd441ba883356ce1beea333028890bfd277a6e5118e7fd3bc15d7c3e11d9453a8fc9aeccff68306b"},{"one":"4367ed557fe94e971003fe0a3236c6bd619e232117818a35f394995ef9782b930279344042dc165069780e8457106299679af6f61c1482d54f31fd19d4f9dd88","other":"4a13668afb8e9fb9db2c4e4e4ff754cbb40c59692c6c5cd70fcba3199ef05c1cf1b19c4fca62396690c90ab7b16f9a18ed375f946a4166137cac349ff3b02933","up":true},{"up":true,"other":"b13271912256c91940de954a90f73889c8abb76c4e92ecedd68e37dc50dcb253a2164607400f2b798d3c2d612d1c77bc677ddac892614a7296254099251e8379","one":"f808e36fd29885cc4f1ad57b26e64deabc0b0fb164ac03017ff2c89671a1ec07706dd28120ceadd8322c6e2387623bc14fa284a0173f70fe722ecc8326f8c932"},{"one":"08f640d4494b0db8b99e7f7a7b3a1d267f457d5c42ea8002d2a509fee7f06fda7e115e270f43372ebc836748aa3456b8d47783064655b38314731f0ee1d8fac1","other":"18c79fcf8500f4d5cb609ef72277112430da75ef83466bdbe0ea4d3a5d6997ca27a94ba0bb35a7a40f5b56bd8242cb20228a6802c4cbb27b934a904eed057b2c","up":true},{"one":"641004e2e499316f46b8b5e0744a5bfcb24323d44c25ed043d57b18406b71bb4e6053df63eb83488c950ba74ae007bc4d5ae711a891eded4a8ea6aa45fb8312a","up":true,"other":"2455595a3aefc0cd619c569d920c279e968022ee53cc07b5a0e3e4d7f8ce315739d432389a2bc26c1890fd8af33c1ced0790c7f644d205361e78c787c803ad88"},{"one":"528d9876a41762f88bbe70f95de1b28998844d65449a5eff254b034db3b4925b6ee3b56fa32f012b448a19d5f429ba0892cce3634cedad6cbed0e03914ccc2b5","up":true,"other":"ba5b2e12f30e2819c19f9336b13b84145af8dc91197840f49c6dc9a8995fbdf37635d5bc42fbc9f59da666df42a3a16e10c02bb0e556e5c9526a74194b23bb96"},{"other":"eb4bab9ad390760b3eece117dbec9792aa56485cd4a6824094337f83463efbe0174b73aba386da238f7b1724aef4cb6a3017cf35999ca591a1e56b67b1ecc250","up":true,"one":"067835838d850b0a649e0e359329349cb2c599c3301bbc122547847a0273597187f745cd820f743775d6c1c44bf3be7e9bdb470a1defa3aa78f41411773cd371"},{"one":"bee0751f64c744ef2862b780ce251b2e21e073b57cec0b57c974b913b92c452aa089f1f66dcf259bdd7ab612bfbca0c8f421a94c564941efd4a1a99c2443fade","up":true,"other":"06a6d7bd7fc3d209e3464e20fdc04df0c20f5fc991172a7847dab790db55daf735cf56d65d5471291511ce99524a934c2cb839cdb6ef4dcf7f025b600f5adbea"},{"other":"ef8f752702c272b1efa3df07957eaaf69854f906df7eebc65b9e5afcb2d3302c712ecf7f4730915f7f29d60cd3463e8393f4d7e34c1b4a7696c855332e4b3d25","up":true,"one":"a0a7b4ccd7d2222f59c202373736c03204f38088dcae48afab6e204b663dff0b06df2ceafc808351e45f54effd5c32481df220a938d1c58d49cd31c32bb20d1e"},{"other":"e34e530095c62d56ea231fc2fd30f3099d7ec88212d4bfb0144efb0232b2f7b48ab438fe3c2211f6bb70a0bf89816b590da44d5cfb9ef817f4c04cfbd0ca37a6","up":true,"one":"dc41672c95ae1af5b7008f7b1c4e232dc469c4969095d357a6e713257ddb8f7220eadf41082cb22503cee38c042160f5d9750f4787b6e44dc8eaa5bd76df8e55"},{"other":"128c42c3e21d7ba3c1bb7481c1119fa85124e827114a0bf7243c9b34b61f2f70111402ef1d4bfa8df69f2472f95b4ad44a95991c1adbe85c20f66436c9247e4e","up":true,"one":"213a1fdcf601bbda1a8531eb2aefc33daef7d7a2312012e8a781bd4ac732d7c267fdc8ceb45061783e64995ce74e67fc330c6a043bbab3f5f88a0e1e2bb4b48c"},{"one":"93f716fc299e1ef6c7ca4f12f5d81a68d65a07f5c86e7605c6518b8f99d792b8d653583ccf031d3855a8835674c16cff79eeee407ed090e94a58bf7333062d1e","up":true,"other":"f808e36fd29885cc4f1ad57b26e64deabc0b0fb164ac03017ff2c89671a1ec07706dd28120ceadd8322c6e2387623bc14fa284a0173f70fe722ecc8326f8c932"},{"one":"9e67e97b2552fd6c0a82cff57d6144aecc05f751a30bf61438cc545fb5932f9b9c901309a14c7ad868bae0d274b999cec111ec9dfd51d6392db9dc717fa5378c","up":true,"other":"bde03ff26a216400b61d07d3eaa865f8b597a52f130ecd44af60d526d4b30c8978cb10c16f4fcbf391ef3a3e5de2aace4c077e9ae6d15451506f370190fbda04"},{"one":"1dd15e2816825bb52419c0f79a13ef9380a2e15fae07d7edae177b334d202c5546d701cebec53b7bc26b97928d5c317fffbe84ed130510f195f9c91b120c93ca","up":true,"other":"5fd28368ab1f2702060367fbc0aa218a5461a60fa9fb4aa77cf9a65b06980c8802df4ec04392e78a83276a7509acba337fd9d8391fa47b3ea77d3959f5c6a35b"},{"one":"2017096c1b5481de69fff5c6a993e2f2014e6f39fd725613cd441ba883356ce1beea333028890bfd277a6e5118e7fd3bc15d7c3e11d9453a8fc9aeccff68306b","other":"eb4bab9ad390760b3eece117dbec9792aa56485cd4a6824094337f83463efbe0174b73aba386da238f7b1724aef4cb6a3017cf35999ca591a1e56b67b1ecc250","up":true},{"up":true,"other":"f9db826a99d327db544fa023ed13b689fd7c40ac9abdfd59d376efd245839ab8d34a3b5d9783fe0461e7ccdff35395e8df8983396df1a87f505663139eab7b20","one":"ee9e52421dac0a5654edba1892117bb8762de147ef6719a85d627b6af451cddf265f0282af905e72e19c754ffe3c4eb5c37fc56d26dc0873182891a85205552c"},{"up":true,"other":"8eea2dd2475d894484f737bb61fa632585ab0a82e47c070327eb65de8b5cf76ad6bbebba1b94b5fe19f6c631e429d1273740937da9ec6cabbcdfd5bd176cc362","one":"96d5ac5effb367c45d8329e73de0cb9f7bd4090b1627416fd7b0a28062959ed5e87042c9f1b4bc8653d27d5f9ab3e0bdec8f09a2f2d4a1bcfd69d68234fdfb12"},{"one":"1e2f58e271f5f55bf1ec82db59cd6b29b3badae06263ea3bb876a131f1869f9fa9477538887fad30ca623f23d06a952a3f8aca1a581c3ed4faf0ad79b47d42b9","up":true,"other":"c581746c5ea238a632de0b30da06de317dc9f613cc9bb16c41509e5d1381b041f2d2e6a65018667bb6b57868577ff04a2773a451dd03b6b599bff5d8cbd4017a"},{"one":"47e3e22c28c4217e3ba4f83ecf3b5767943c3d49c3b829ad510a7412ae868d60f2c9e4cb51e52e6153aa6555eb2cc1ecaae62793119774dbe3a09d8550d9e2d7","up":true,"other":"0445005ab3e1a97c7fb9d9a4e77d4da6c51881f2454a35f945fdce1318e863ef3e27784938720c80ebbb3c6440e63bd9ae0fecdf21d78d7e24357ddd9b430b37"},{"other":"00508d6e28f4b503d346983d740c24c440c6eab33128d86c60cb2ce8c70d17189a96a7e6f212dd25f383d1902d04206784edb7fc8b1c391e4465afcd18192c1c","up":true,"one":"4a13668afb8e9fb9db2c4e4e4ff754cbb40c59692c6c5cd70fcba3199ef05c1cf1b19c4fca62396690c90ab7b16f9a18ed375f946a4166137cac349ff3b02933"},{"up":true,"other":"06a6d7bd7fc3d209e3464e20fdc04df0c20f5fc991172a7847dab790db55daf735cf56d65d5471291511ce99524a934c2cb839cdb6ef4dcf7f025b600f5adbea","one":"e34e530095c62d56ea231fc2fd30f3099d7ec88212d4bfb0144efb0232b2f7b48ab438fe3c2211f6bb70a0bf89816b590da44d5cfb9ef817f4c04cfbd0ca37a6"},{"one":"bde03ff26a216400b61d07d3eaa865f8b597a52f130ecd44af60d526d4b30c8978cb10c16f4fcbf391ef3a3e5de2aace4c077e9ae6d15451506f370190fbda04","other":"ba5b2e12f30e2819c19f9336b13b84145af8dc91197840f49c6dc9a8995fbdf37635d5bc42fbc9f59da666df42a3a16e10c02bb0e556e5c9526a74194b23bb96","up":true},{"one":"c8b55e1f0042ff9ac2b73593f79ce125b3b613354ed90a086b18e1f1809c883d0c0e9df6ec080181ef023833cde585de184523483db878aa65c9939a1a1fcf2d","up":true,"other":"dc41672c95ae1af5b7008f7b1c4e232dc469c4969095d357a6e713257ddb8f7220eadf41082cb22503cee38c042160f5d9750f4787b6e44dc8eaa5bd76df8e55"},{"one":"5fd28368ab1f2702060367fbc0aa218a5461a60fa9fb4aa77cf9a65b06980c8802df4ec04392e78a83276a7509acba337fd9d8391fa47b3ea77d3959f5c6a35b","other":"df4e07354dd593b1986e996f84c3e97147f72f4c6367ec876472c7384fe2d850ee6a8abeb37b789e7c50c12aa3533f19a6c7d9c37bb1b884c61eee307488ed88","up":true},{"other":"4367ed557fe94e971003fe0a3236c6bd619e232117818a35f394995ef9782b930279344042dc165069780e8457106299679af6f61c1482d54f31fd19d4f9dd88","up":true,"one":"03e750d46b9a4a9e2047a5b718f427834417f4eb48d8794fde26593a3adbbce48750fa93f47548e342677e94888941ebd492a844a5d8325f67a0db8e94a09b55"},{"up":true,"other":"00508d6e28f4b503d346983d740c24c440c6eab33128d86c60cb2ce8c70d17189a96a7e6f212dd25f383d1902d04206784edb7fc8b1c391e4465afcd18192c1c","one":"0445005ab3e1a97c7fb9d9a4e77d4da6c51881f2454a35f945fdce1318e863ef3e27784938720c80ebbb3c6440e63bd9ae0fecdf21d78d7e24357ddd9b430b37"},{"one":"698cf5333166bf22a15679cb0d88d7382fe980455a6c288556310898e6aeb3fb04262b89e146d4bff2a4e5501574bd7b55adf3a2ccde080e7a3acab9fdb78e1a","up":true,"other":"96d5ac5effb367c45d8329e73de0cb9f7bd4090b1627416fd7b0a28062959ed5e87042c9f1b4bc8653d27d5f9ab3e0bdec8f09a2f2d4a1bcfd69d68234fdfb12"},{"up":true,"other":"8eea2dd2475d894484f737bb61fa632585ab0a82e47c070327eb65de8b5cf76ad6bbebba1b94b5fe19f6c631e429d1273740937da9ec6cabbcdfd5bd176cc362","one":"18c79fcf8500f4d5cb609ef72277112430da75ef83466bdbe0ea4d3a5d6997ca27a94ba0bb35a7a40f5b56bd8242cb20228a6802c4cbb27b934a904eed057b2c"},{"other":"12b2d36d0e1a7255bde9c81fc9fac8befd7119bbafb74773cee281a73a9095fcceb8a5bc6fc01d8fcc948adbf2b6b6d190017b307875fbea971e6604ddb219de","up":true,"one":"e968aa3ce0d669bab524f11df68ea707d6f4ed9c4367b78e20acd66af8deb0a965368ed4fa171f579ba931001f47092e97d5d37d80075570f61a2eebb21bbd4b"},{"other":"e968aa3ce0d669bab524f11df68ea707d6f4ed9c4367b78e20acd66af8deb0a965368ed4fa171f579ba931001f47092e97d5d37d80075570f61a2eebb21bbd4b","up":true,"one":"ef8f752702c272b1efa3df07957eaaf69854f906df7eebc65b9e5afcb2d3302c712ecf7f4730915f7f29d60cd3463e8393f4d7e34c1b4a7696c855332e4b3d25"},{"one":"269e5d200ae242b0b101bd7d465e009fc7eb22b074f1d9b562580bf452d592420e4063d03fab92c6fa61a32633492ee1b4fb20c3a8f44ec7ca07839bee871828","up":true,"other":"a0a7b4ccd7d2222f59c202373736c03204f38088dcae48afab6e204b663dff0b06df2ceafc808351e45f54effd5c32481df220a938d1c58d49cd31c32bb20d1e"},{"one":"e24f63d4515d5d1e8e85f06afde4da3144258f7569d2a0b007aecc13c9cb17a8ad75d85e30a1bb7bfee7b81a219b58e969787f11710c82d0904568a60cc2fe5d","up":true,"other":"641004e2e499316f46b8b5e0744a5bfcb24323d44c25ed043d57b18406b71bb4e6053df63eb83488c950ba74ae007bc4d5ae711a891eded4a8ea6aa45fb8312a"},{"one":"f9db826a99d327db544fa023ed13b689fd7c40ac9abdfd59d376efd245839ab8d34a3b5d9783fe0461e7ccdff35395e8df8983396df1a87f505663139eab7b20","other":"df4e07354dd593b1986e996f84c3e97147f72f4c6367ec876472c7384fe2d850ee6a8abeb37b789e7c50c12aa3533f19a6c7d9c37bb1b884c61eee307488ed88","up":true},{"one":"12b2d36d0e1a7255bde9c81fc9fac8befd7119bbafb74773cee281a73a9095fcceb8a5bc6fc01d8fcc948adbf2b6b6d190017b307875fbea971e6604ddb219de","up":true,"other":"e777565409c3fa228f25352f28004671b6f9451fe21666263e71d67d18cf7890f3015af4717267bcd736322239aae34ba0f596e8e98d1628a539cef3a521ed7d"},{"up":true,"other":"e968aa3ce0d669bab524f11df68ea707d6f4ed9c4367b78e20acd66af8deb0a965368ed4fa171f579ba931001f47092e97d5d37d80075570f61a2eebb21bbd4b","one":"8eea2dd2475d894484f737bb61fa632585ab0a82e47c070327eb65de8b5cf76ad6bbebba1b94b5fe19f6c631e429d1273740937da9ec6cabbcdfd5bd176cc362"},{"one":"dd1ecdd5e7bdd1ab85a946132cfd7e27c8a29e0256ebe859a9c9283cbb872f9406b30a835826ecece342ab5c41f4c34fdb75049acf0ee134ca8f94c3158a73e0","other":"eb4bab9ad390760b3eece117dbec9792aa56485cd4a6824094337f83463efbe0174b73aba386da238f7b1724aef4cb6a3017cf35999ca591a1e56b67b1ecc250","up":true},{"other":"4a13668afb8e9fb9db2c4e4e4ff754cbb40c59692c6c5cd70fcba3199ef05c1cf1b19c4fca62396690c90ab7b16f9a18ed375f946a4166137cac349ff3b02933","up":true,"one":"78739942ae915ea9447fbc435162fc63f18a6f54a1473fd4aa2ed2391a5d62ffa8e32e0aaaa2b83022bd1ff15210daea42433e944235c95a681fac54f75da5de"},{"other":"b13271912256c91940de954a90f73889c8abb76c4e92ecedd68e37dc50dcb253a2164607400f2b798d3c2d612d1c77bc677ddac892614a7296254099251e8379","up":true,"one":"32627f1a91175809b9141af528c4d77407385102a3ed6afee81acb79b0988f91075c670a09203238e266f5ad0d61b9388c9097fe00a54ced8f04423830768768"},{"up":true,"other":"4a13668afb8e9fb9db2c4e4e4ff754cbb40c59692c6c5cd70fcba3199ef05c1cf1b19c4fca62396690c90ab7b16f9a18ed375f946a4166137cac349ff3b02933","one":"08f640d4494b0db8b99e7f7a7b3a1d267f457d5c42ea8002d2a509fee7f06fda7e115e270f43372ebc836748aa3456b8d47783064655b38314731f0ee1d8fac1"},{"other":"269e5d200ae242b0b101bd7d465e009fc7eb22b074f1d9b562580bf452d592420e4063d03fab92c6fa61a32633492ee1b4fb20c3a8f44ec7ca07839bee871828","up":true,"one":"df4e07354dd593b1986e996f84c3e97147f72f4c6367ec876472c7384fe2d850ee6a8abeb37b789e7c50c12aa3533f19a6c7d9c37bb1b884c61eee307488ed88"},{"one":"20fcc315548210e104fb0bd5deb4c5af2d78a075a3441015e7e27f8c711a5d6055d8c01692502ca4648f82704424c25a7252e3505657e25dd30c1096e16fcccf","other":"18c79fcf8500f4d5cb609ef72277112430da75ef83466bdbe0ea4d3a5d6997ca27a94ba0bb35a7a40f5b56bd8242cb20228a6802c4cbb27b934a904eed057b2c","up":true},{"other":"e24f63d4515d5d1e8e85f06afde4da3144258f7569d2a0b007aecc13c9cb17a8ad75d85e30a1bb7bfee7b81a219b58e969787f11710c82d0904568a60cc2fe5d","up":true,"one":"eb4bab9ad390760b3eece117dbec9792aa56485cd4a6824094337f83463efbe0174b73aba386da238f7b1724aef4cb6a3017cf35999ca591a1e56b67b1ecc250"},{"one":"5fd28368ab1f2702060367fbc0aa218a5461a60fa9fb4aa77cf9a65b06980c8802df4ec04392e78a83276a7509acba337fd9d8391fa47b3ea77d3959f5c6a35b","other":"08f640d4494b0db8b99e7f7a7b3a1d267f457d5c42ea8002d2a509fee7f06fda7e115e270f43372ebc836748aa3456b8d47783064655b38314731f0ee1d8fac1","up":true},{"one":"a93e19158ae6a4261186b663bf109258d759e42b8e0e1d5c06e79a9b6844e6acb41c0a4ce38dfdf250d6016aa796fb78807a7f91738f4eef8a36dafdd60afec7","up":true,"other":"20fcc315548210e104fb0bd5deb4c5af2d78a075a3441015e7e27f8c711a5d6055d8c01692502ca4648f82704424c25a7252e3505657e25dd30c1096e16fcccf"},{"one":"dc41672c95ae1af5b7008f7b1c4e232dc469c4969095d357a6e713257ddb8f7220eadf41082cb22503cee38c042160f5d9750f4787b6e44dc8eaa5bd76df8e55","other":"2455595a3aefc0cd619c569d920c279e968022ee53cc07b5a0e3e4d7f8ce315739d432389a2bc26c1890fd8af33c1ced0790c7f644d205361e78c787c803ad88","up":true},{"one":"5732476eb1c7b5ab050759a7169281e6ff583df6de07c2019fb105dfad4df268587b87baf6e0d210f77b048bd62b501b713a919964f35b862b403b478d88a1b6","other":"841c007c8c5c96f6d7759d186bbf008e64fb9ab6e88c215c0fff31285ac3a47108962699f6fcc995bce7059787fa69bfbc82d36bfaa155ee207a7044bb839c96","up":true},{"other":"06a6d7bd7fc3d209e3464e20fdc04df0c20f5fc991172a7847dab790db55daf735cf56d65d5471291511ce99524a934c2cb839cdb6ef4dcf7f025b600f5adbea","up":true,"one":"0d502ca2f60cadbf375c195365090b216ac99af07abb3a35d3f3dbdc4de7eb2a8f93a3f2a240fc5905dca74e78a05a5837484a117477fb279052889c52b99c6c"},{"other":"f808e36fd29885cc4f1ad57b26e64deabc0b0fb164ac03017ff2c89671a1ec07706dd28120ceadd8322c6e2387623bc14fa284a0173f70fe722ecc8326f8c932","up":true,"one":"2017096c1b5481de69fff5c6a993e2f2014e6f39fd725613cd441ba883356ce1beea333028890bfd277a6e5118e7fd3bc15d7c3e11d9453a8fc9aeccff68306b"},{"other":"12b2d36d0e1a7255bde9c81fc9fac8befd7119bbafb74773cee281a73a9095fcceb8a5bc6fc01d8fcc948adbf2b6b6d190017b307875fbea971e6604ddb219de","up":true,"one":"8b3023625eecf7dd330df127a31454cea24354d099ca621af1a1232e5b59961ceafbd9f7e0f658905d80617f7efbc4038d84fb6e3cc9347a1f4f1775fff46965"},{"other":"12b2d36d0e1a7255bde9c81fc9fac8befd7119bbafb74773cee281a73a9095fcceb8a5bc6fc01d8fcc948adbf2b6b6d190017b307875fbea971e6604ddb219de","up":true,"one":"aee9aaece9a50dd4e85d79f1286165181251ebbbffe461e87e98e04ee5a4730b3d31ff6ed63fe403c1ecff165cbe1cf7d791f4a6fd16685726c290344ed65406"},{"one":"213a1fdcf601bbda1a8531eb2aefc33daef7d7a2312012e8a781bd4ac732d7c267fdc8ceb45061783e64995ce74e67fc330c6a043bbab3f5f88a0e1e2bb4b48c","up":true,"other":"e24f63d4515d5d1e8e85f06afde4da3144258f7569d2a0b007aecc13c9cb17a8ad75d85e30a1bb7bfee7b81a219b58e969787f11710c82d0904568a60cc2fe5d"},{"up":true,"other":"dc41672c95ae1af5b7008f7b1c4e232dc469c4969095d357a6e713257ddb8f7220eadf41082cb22503cee38c042160f5d9750f4787b6e44dc8eaa5bd76df8e55","one":"740371f4438046c4f3cb3e0c47cd1c35df4565addb44dc4a7aa0be864cf43f726dc0616502cd67fd7d88008acf8ba1e3f9ef60aeb2d3de3896dccd8765c2bfb3"},{"one":"2cb9a1452559314b74e4e1956a260ee2ef7bed85215e444968f54148eb7662f76ec8e7e0fe2cb32d9eecde8d4748a1f776dca7c7f121fde1722d0ba514498d11","other":"12b2d36d0e1a7255bde9c81fc9fac8befd7119bbafb74773cee281a73a9095fcceb8a5bc6fc01d8fcc948adbf2b6b6d190017b307875fbea971e6604ddb219de","up":true},{"one":"00508d6e28f4b503d346983d740c24c440c6eab33128d86c60cb2ce8c70d17189a96a7e6f212dd25f383d1902d04206784edb7fc8b1c391e4465afcd18192c1c","other":"20fcc315548210e104fb0bd5deb4c5af2d78a075a3441015e7e27f8c711a5d6055d8c01692502ca4648f82704424c25a7252e3505657e25dd30c1096e16fcccf","up":true},{"one":"1dd15e2816825bb52419c0f79a13ef9380a2e15fae07d7edae177b334d202c5546d701cebec53b7bc26b97928d5c317fffbe84ed130510f195f9c91b120c93ca","up":true,"other":"df4e07354dd593b1986e996f84c3e97147f72f4c6367ec876472c7384fe2d850ee6a8abeb37b789e7c50c12aa3533f19a6c7d9c37bb1b884c61eee307488ed88"},{"one":"641004e2e499316f46b8b5e0744a5bfcb24323d44c25ed043d57b18406b71bb4e6053df63eb83488c950ba74ae007bc4d5ae711a891eded4a8ea6aa45fb8312a","other":"08f640d4494b0db8b99e7f7a7b3a1d267f457d5c42ea8002d2a509fee7f06fda7e115e270f43372ebc836748aa3456b8d47783064655b38314731f0ee1d8fac1","up":true},{"up":true,"other":"06a6d7bd7fc3d209e3464e20fdc04df0c20f5fc991172a7847dab790db55daf735cf56d65d5471291511ce99524a934c2cb839cdb6ef4dcf7f025b600f5adbea","one":"067835838d850b0a649e0e359329349cb2c599c3301bbc122547847a0273597187f745cd820f743775d6c1c44bf3be7e9bdb470a1defa3aa78f41411773cd371"},{"one":"9af8f0912f664cb4b4515f6b66c432b6d9e8a97f338691517bab0f221718c9ea95ef04243ea7c9573daa5183969b9e9fd4469a58014d88acd0adca3379679cff","up":true,"other":"06a6d7bd7fc3d209e3464e20fdc04df0c20f5fc991172a7847dab790db55daf735cf56d65d5471291511ce99524a934c2cb839cdb6ef4dcf7f025b600f5adbea"},{"one":"a0a7b4ccd7d2222f59c202373736c03204f38088dcae48afab6e204b663dff0b06df2ceafc808351e45f54effd5c32481df220a938d1c58d49cd31c32bb20d1e","up":true,"other":"e24f63d4515d5d1e8e85f06afde4da3144258f7569d2a0b007aecc13c9cb17a8ad75d85e30a1bb7bfee7b81a219b58e969787f11710c82d0904568a60cc2fe5d"},{"one":"9e67e97b2552fd6c0a82cff57d6144aecc05f751a30bf61438cc545fb5932f9b9c901309a14c7ad868bae0d274b999cec111ec9dfd51d6392db9dc717fa5378c","other":"c581746c5ea238a632de0b30da06de317dc9f613cc9bb16c41509e5d1381b041f2d2e6a65018667bb6b57868577ff04a2773a451dd03b6b599bff5d8cbd4017a","up":true},{"up":true,"other":"ba5b2e12f30e2819c19f9336b13b84145af8dc91197840f49c6dc9a8995fbdf37635d5bc42fbc9f59da666df42a3a16e10c02bb0e556e5c9526a74194b23bb96","one":"96d5ac5effb367c45d8329e73de0cb9f7bd4090b1627416fd7b0a28062959ed5e87042c9f1b4bc8653d27d5f9ab3e0bdec8f09a2f2d4a1bcfd69d68234fdfb12"},{"other":"9af8f0912f664cb4b4515f6b66c432b6d9e8a97f338691517bab0f221718c9ea95ef04243ea7c9573daa5183969b9e9fd4469a58014d88acd0adca3379679cff","up":true,"one":"e34e530095c62d56ea231fc2fd30f3099d7ec88212d4bfb0144efb0232b2f7b48ab438fe3c2211f6bb70a0bf89816b590da44d5cfb9ef817f4c04cfbd0ca37a6"},{"other":"00508d6e28f4b503d346983d740c24c440c6eab33128d86c60cb2ce8c70d17189a96a7e6f212dd25f383d1902d04206784edb7fc8b1c391e4465afcd18192c1c","up":true,"one":"bde03ff26a216400b61d07d3eaa865f8b597a52f130ecd44af60d526d4b30c8978cb10c16f4fcbf391ef3a3e5de2aace4c077e9ae6d15451506f370190fbda04"},{"one":"ee9e52421dac0a5654edba1892117bb8762de147ef6719a85d627b6af451cddf265f0282af905e72e19c754ffe3c4eb5c37fc56d26dc0873182891a85205552c","other":"06a6d7bd7fc3d209e3464e20fdc04df0c20f5fc991172a7847dab790db55daf735cf56d65d5471291511ce99524a934c2cb839cdb6ef4dcf7f025b600f5adbea","up":true},{"other":"4c53fcf455540cc5f4fd48a57fb68e643eaf769085f350129e1dfa76ef56d33f31b950a42721dbe445a73151edbdb54ce0169204a17a58031a07f11ea1347ed0","up":true,"one":"47e3e22c28c4217e3ba4f83ecf3b5767943c3d49c3b829ad510a7412ae868d60f2c9e4cb51e52e6153aa6555eb2cc1ecaae62793119774dbe3a09d8550d9e2d7"},{"other":"a0a7b4ccd7d2222f59c202373736c03204f38088dcae48afab6e204b663dff0b06df2ceafc808351e45f54effd5c32481df220a938d1c58d49cd31c32bb20d1e","up":true,"one":"c8b55e1f0042ff9ac2b73593f79ce125b3b613354ed90a086b18e1f1809c883d0c0e9df6ec080181ef023833cde585de184523483db878aa65c9939a1a1fcf2d"},{"other":"aee9aaece9a50dd4e85d79f1286165181251ebbbffe461e87e98e04ee5a4730b3d31ff6ed63fe403c1ecff165cbe1cf7d791f4a6fd16685726c290344ed65406","up":true,"one":"269e5d200ae242b0b101bd7d465e009fc7eb22b074f1d9b562580bf452d592420e4063d03fab92c6fa61a32633492ee1b4fb20c3a8f44ec7ca07839bee871828"},{"other":"641004e2e499316f46b8b5e0744a5bfcb24323d44c25ed043d57b18406b71bb4e6053df63eb83488c950ba74ae007bc4d5ae711a891eded4a8ea6aa45fb8312a","up":true,"one":"698cf5333166bf22a15679cb0d88d7382fe980455a6c288556310898e6aeb3fb04262b89e146d4bff2a4e5501574bd7b55adf3a2ccde080e7a3acab9fdb78e1a"},{"up":true,"other":"269e5d200ae242b0b101bd7d465e009fc7eb22b074f1d9b562580bf452d592420e4063d03fab92c6fa61a32633492ee1b4fb20c3a8f44ec7ca07839bee871828","one":"ef8f752702c272b1efa3df07957eaaf69854f906df7eebc65b9e5afcb2d3302c712ecf7f4730915f7f29d60cd3463e8393f4d7e34c1b4a7696c855332e4b3d25"},{"other":"269e5d200ae242b0b101bd7d465e009fc7eb22b074f1d9b562580bf452d592420e4063d03fab92c6fa61a32633492ee1b4fb20c3a8f44ec7ca07839bee871828","up":true,"one":"8eea2dd2475d894484f737bb61fa632585ab0a82e47c070327eb65de8b5cf76ad6bbebba1b94b5fe19f6c631e429d1273740937da9ec6cabbcdfd5bd176cc362"},{"up":true,"other":"269e5d200ae242b0b101bd7d465e009fc7eb22b074f1d9b562580bf452d592420e4063d03fab92c6fa61a32633492ee1b4fb20c3a8f44ec7ca07839bee871828","one":"00508d6e28f4b503d346983d740c24c440c6eab33128d86c60cb2ce8c70d17189a96a7e6f212dd25f383d1902d04206784edb7fc8b1c391e4465afcd18192c1c"},{"other":"5732476eb1c7b5ab050759a7169281e6ff583df6de07c2019fb105dfad4df268587b87baf6e0d210f77b048bd62b501b713a919964f35b862b403b478d88a1b6","up":true,"one":"641004e2e499316f46b8b5e0744a5bfcb24323d44c25ed043d57b18406b71bb4e6053df63eb83488c950ba74ae007bc4d5ae711a891eded4a8ea6aa45fb8312a"},{"other":"08f640d4494b0db8b99e7f7a7b3a1d267f457d5c42ea8002d2a509fee7f06fda7e115e270f43372ebc836748aa3456b8d47783064655b38314731f0ee1d8fac1","up":true,"one":"1dd15e2816825bb52419c0f79a13ef9380a2e15fae07d7edae177b334d202c5546d701cebec53b7bc26b97928d5c317fffbe84ed130510f195f9c91b120c93ca"},{"up":true,"other":"f9db826a99d327db544fa023ed13b689fd7c40ac9abdfd59d376efd245839ab8d34a3b5d9783fe0461e7ccdff35395e8df8983396df1a87f505663139eab7b20","one":"12b2d36d0e1a7255bde9c81fc9fac8befd7119bbafb74773cee281a73a9095fcceb8a5bc6fc01d8fcc948adbf2b6b6d190017b307875fbea971e6604ddb219de"},{"one":"32627f1a91175809b9141af528c4d77407385102a3ed6afee81acb79b0988f91075c670a09203238e266f5ad0d61b9388c9097fe00a54ced8f04423830768768","up":true,"other":"e24f63d4515d5d1e8e85f06afde4da3144258f7569d2a0b007aecc13c9cb17a8ad75d85e30a1bb7bfee7b81a219b58e969787f11710c82d0904568a60cc2fe5d"},{"one":"96d5ac5effb367c45d8329e73de0cb9f7bd4090b1627416fd7b0a28062959ed5e87042c9f1b4bc8653d27d5f9ab3e0bdec8f09a2f2d4a1bcfd69d68234fdfb12","up":true,"other":"1dd15e2816825bb52419c0f79a13ef9380a2e15fae07d7edae177b334d202c5546d701cebec53b7bc26b97928d5c317fffbe84ed130510f195f9c91b120c93ca"},{"one":"bde03ff26a216400b61d07d3eaa865f8b597a52f130ecd44af60d526d4b30c8978cb10c16f4fcbf391ef3a3e5de2aace4c077e9ae6d15451506f370190fbda04","other":"8eea2dd2475d894484f737bb61fa632585ab0a82e47c070327eb65de8b5cf76ad6bbebba1b94b5fe19f6c631e429d1273740937da9ec6cabbcdfd5bd176cc362","up":true},{"other":"c581746c5ea238a632de0b30da06de317dc9f613cc9bb16c41509e5d1381b041f2d2e6a65018667bb6b57868577ff04a2773a451dd03b6b599bff5d8cbd4017a","up":true,"one":"18c79fcf8500f4d5cb609ef72277112430da75ef83466bdbe0ea4d3a5d6997ca27a94ba0bb35a7a40f5b56bd8242cb20228a6802c4cbb27b934a904eed057b2c"},{"up":true,"other":"e24f63d4515d5d1e8e85f06afde4da3144258f7569d2a0b007aecc13c9cb17a8ad75d85e30a1bb7bfee7b81a219b58e969787f11710c82d0904568a60cc2fe5d","one":"2017096c1b5481de69fff5c6a993e2f2014e6f39fd725613cd441ba883356ce1beea333028890bfd277a6e5118e7fd3bc15d7c3e11d9453a8fc9aeccff68306b"},{"one":"df4e07354dd593b1986e996f84c3e97147f72f4c6367ec876472c7384fe2d850ee6a8abeb37b789e7c50c12aa3533f19a6c7d9c37bb1b884c61eee307488ed88","other":"a93e19158ae6a4261186b663bf109258d759e42b8e0e1d5c06e79a9b6844e6acb41c0a4ce38dfdf250d6016aa796fb78807a7f91738f4eef8a36dafdd60afec7","up":true},{"up":true,"other":"12b2d36d0e1a7255bde9c81fc9fac8befd7119bbafb74773cee281a73a9095fcceb8a5bc6fc01d8fcc948adbf2b6b6d190017b307875fbea971e6604ddb219de","one":"20fcc315548210e104fb0bd5deb4c5af2d78a075a3441015e7e27f8c711a5d6055d8c01692502ca4648f82704424c25a7252e3505657e25dd30c1096e16fcccf"},{"other":"00508d6e28f4b503d346983d740c24c440c6eab33128d86c60cb2ce8c70d17189a96a7e6f212dd25f383d1902d04206784edb7fc8b1c391e4465afcd18192c1c","up":true,"one":"f9db826a99d327db544fa023ed13b689fd7c40ac9abdfd59d376efd245839ab8d34a3b5d9783fe0461e7ccdff35395e8df8983396df1a87f505663139eab7b20"},{"up":true,"other":"269e5d200ae242b0b101bd7d465e009fc7eb22b074f1d9b562580bf452d592420e4063d03fab92c6fa61a32633492ee1b4fb20c3a8f44ec7ca07839bee871828","one":"a93e19158ae6a4261186b663bf109258d759e42b8e0e1d5c06e79a9b6844e6acb41c0a4ce38dfdf250d6016aa796fb78807a7f91738f4eef8a36dafdd60afec7"},{"up":true,"other":"e24f63d4515d5d1e8e85f06afde4da3144258f7569d2a0b007aecc13c9cb17a8ad75d85e30a1bb7bfee7b81a219b58e969787f11710c82d0904568a60cc2fe5d","one":"5732476eb1c7b5ab050759a7169281e6ff583df6de07c2019fb105dfad4df268587b87baf6e0d210f77b048bd62b501b713a919964f35b862b403b478d88a1b6"},{"one":"0d502ca2f60cadbf375c195365090b216ac99af07abb3a35d3f3dbdc4de7eb2a8f93a3f2a240fc5905dca74e78a05a5837484a117477fb279052889c52b99c6c","up":true,"other":"eb4bab9ad390760b3eece117dbec9792aa56485cd4a6824094337f83463efbe0174b73aba386da238f7b1724aef4cb6a3017cf35999ca591a1e56b67b1ecc250"},{"one":"dd1ecdd5e7bdd1ab85a946132cfd7e27c8a29e0256ebe859a9c9283cbb872f9406b30a835826ecece342ab5c41f4c34fdb75049acf0ee134ca8f94c3158a73e0","up":true,"other":"b13271912256c91940de954a90f73889c8abb76c4e92ecedd68e37dc50dcb253a2164607400f2b798d3c2d612d1c77bc677ddac892614a7296254099251e8379"},{"one":"8b3023625eecf7dd330df127a31454cea24354d099ca621af1a1232e5b59961ceafbd9f7e0f658905d80617f7efbc4038d84fb6e3cc9347a1f4f1775fff46965","up":true,"other":"4a13668afb8e9fb9db2c4e4e4ff754cbb40c59692c6c5cd70fcba3199ef05c1cf1b19c4fca62396690c90ab7b16f9a18ed375f946a4166137cac349ff3b02933"},{"up":true,"other":"5fd28368ab1f2702060367fbc0aa218a5461a60fa9fb4aa77cf9a65b06980c8802df4ec04392e78a83276a7509acba337fd9d8391fa47b3ea77d3959f5c6a35b","one":"aee9aaece9a50dd4e85d79f1286165181251ebbbffe461e87e98e04ee5a4730b3d31ff6ed63fe403c1ecff165cbe1cf7d791f4a6fd16685726c290344ed65406"},{"one":"dc41672c95ae1af5b7008f7b1c4e232dc469c4969095d357a6e713257ddb8f7220eadf41082cb22503cee38c042160f5d9750f4787b6e44dc8eaa5bd76df8e55","other":"ccbbc901d05610202edfd1eba445dc0c93c3ab1dfcc4c9eecd9f1f12521508407429b605840eb8fed9893a1fd8ef6dcd29c9627fe8d3d41ca094b10ab977aa8b","up":true},{"up":true,"other":"5732476eb1c7b5ab050759a7169281e6ff583df6de07c2019fb105dfad4df268587b87baf6e0d210f77b048bd62b501b713a919964f35b862b403b478d88a1b6","one":"9af8f0912f664cb4b4515f6b66c432b6d9e8a97f338691517bab0f221718c9ea95ef04243ea7c9573daa5183969b9e9fd4469a58014d88acd0adca3379679cff"},{"up":true,"other":"5fd28368ab1f2702060367fbc0aa218a5461a60fa9fb4aa77cf9a65b06980c8802df4ec04392e78a83276a7509acba337fd9d8391fa47b3ea77d3959f5c6a35b","one":"9e67e97b2552fd6c0a82cff57d6144aecc05f751a30bf61438cc545fb5932f9b9c901309a14c7ad868bae0d274b999cec111ec9dfd51d6392db9dc717fa5378c"},{"up":true,"other":"8eea2dd2475d894484f737bb61fa632585ab0a82e47c070327eb65de8b5cf76ad6bbebba1b94b5fe19f6c631e429d1273740937da9ec6cabbcdfd5bd176cc362","one":"ee9e52421dac0a5654edba1892117bb8762de147ef6719a85d627b6af451cddf265f0282af905e72e19c754ffe3c4eb5c37fc56d26dc0873182891a85205552c"},{"other":"00508d6e28f4b503d346983d740c24c440c6eab33128d86c60cb2ce8c70d17189a96a7e6f212dd25f383d1902d04206784edb7fc8b1c391e4465afcd18192c1c","up":true,"one":"47e3e22c28c4217e3ba4f83ecf3b5767943c3d49c3b829ad510a7412ae868d60f2c9e4cb51e52e6153aa6555eb2cc1ecaae62793119774dbe3a09d8550d9e2d7"},{"other":"4a13668afb8e9fb9db2c4e4e4ff754cbb40c59692c6c5cd70fcba3199ef05c1cf1b19c4fca62396690c90ab7b16f9a18ed375f946a4166137cac349ff3b02933","up":true,"one":"698cf5333166bf22a15679cb0d88d7382fe980455a6c288556310898e6aeb3fb04262b89e146d4bff2a4e5501574bd7b55adf3a2ccde080e7a3acab9fdb78e1a"},{"one":"269e5d200ae242b0b101bd7d465e009fc7eb22b074f1d9b562580bf452d592420e4063d03fab92c6fa61a32633492ee1b4fb20c3a8f44ec7ca07839bee871828","other":"c581746c5ea238a632de0b30da06de317dc9f613cc9bb16c41509e5d1381b041f2d2e6a65018667bb6b57868577ff04a2773a451dd03b6b599bff5d8cbd4017a","up":true},{"up":true,"other":"18c79fcf8500f4d5cb609ef72277112430da75ef83466bdbe0ea4d3a5d6997ca27a94ba0bb35a7a40f5b56bd8242cb20228a6802c4cbb27b934a904eed057b2c","one":"8b3023625eecf7dd330df127a31454cea24354d099ca621af1a1232e5b59961ceafbd9f7e0f658905d80617f7efbc4038d84fb6e3cc9347a1f4f1775fff46965"},{"up":true,"other":"18c79fcf8500f4d5cb609ef72277112430da75ef83466bdbe0ea4d3a5d6997ca27a94ba0bb35a7a40f5b56bd8242cb20228a6802c4cbb27b934a904eed057b2c","one":"aee9aaece9a50dd4e85d79f1286165181251ebbbffe461e87e98e04ee5a4730b3d31ff6ed63fe403c1ecff165cbe1cf7d791f4a6fd16685726c290344ed65406"},{"other":"4367ed557fe94e971003fe0a3236c6bd619e232117818a35f394995ef9782b930279344042dc165069780e8457106299679af6f61c1482d54f31fd19d4f9dd88","up":true,"one":"9e67e97b2552fd6c0a82cff57d6144aecc05f751a30bf61438cc545fb5932f9b9c901309a14c7ad868bae0d274b999cec111ec9dfd51d6392db9dc717fa5378c"},{"up":true,"other":"8eea2dd2475d894484f737bb61fa632585ab0a82e47c070327eb65de8b5cf76ad6bbebba1b94b5fe19f6c631e429d1273740937da9ec6cabbcdfd5bd176cc362","one":"47e3e22c28c4217e3ba4f83ecf3b5767943c3d49c3b829ad510a7412ae868d60f2c9e4cb51e52e6153aa6555eb2cc1ecaae62793119774dbe3a09d8550d9e2d7"},{"up":true,"other":"00508d6e28f4b503d346983d740c24c440c6eab33128d86c60cb2ce8c70d17189a96a7e6f212dd25f383d1902d04206784edb7fc8b1c391e4465afcd18192c1c","one":"ef8f752702c272b1efa3df07957eaaf69854f906df7eebc65b9e5afcb2d3302c712ecf7f4730915f7f29d60cd3463e8393f4d7e34c1b4a7696c855332e4b3d25"},{"one":"12b2d36d0e1a7255bde9c81fc9fac8befd7119bbafb74773cee281a73a9095fcceb8a5bc6fc01d8fcc948adbf2b6b6d190017b307875fbea971e6604ddb219de","other":"ee9e52421dac0a5654edba1892117bb8762de147ef6719a85d627b6af451cddf265f0282af905e72e19c754ffe3c4eb5c37fc56d26dc0873182891a85205552c","up":true},{"up":true,"other":"841c007c8c5c96f6d7759d186bbf008e64fb9ab6e88c215c0fff31285ac3a47108962699f6fcc995bce7059787fa69bfbc82d36bfaa155ee207a7044bb839c96","one":"dd1ecdd5e7bdd1ab85a946132cfd7e27c8a29e0256ebe859a9c9283cbb872f9406b30a835826ecece342ab5c41f4c34fdb75049acf0ee134ca8f94c3158a73e0"},{"one":"8eea2dd2475d894484f737bb61fa632585ab0a82e47c070327eb65de8b5cf76ad6bbebba1b94b5fe19f6c631e429d1273740937da9ec6cabbcdfd5bd176cc362","up":true,"other":"a93e19158ae6a4261186b663bf109258d759e42b8e0e1d5c06e79a9b6844e6acb41c0a4ce38dfdf250d6016aa796fb78807a7f91738f4eef8a36dafdd60afec7"},{"other":"ef8f752702c272b1efa3df07957eaaf69854f906df7eebc65b9e5afcb2d3302c712ecf7f4730915f7f29d60cd3463e8393f4d7e34c1b4a7696c855332e4b3d25","up":true,"one":"df4e07354dd593b1986e996f84c3e97147f72f4c6367ec876472c7384fe2d850ee6a8abeb37b789e7c50c12aa3533f19a6c7d9c37bb1b884c61eee307488ed88"},{"one":"a93e19158ae6a4261186b663bf109258d759e42b8e0e1d5c06e79a9b6844e6acb41c0a4ce38dfdf250d6016aa796fb78807a7f91738f4eef8a36dafdd60afec7","up":true,"other":"b13271912256c91940de954a90f73889c8abb76c4e92ecedd68e37dc50dcb253a2164607400f2b798d3c2d612d1c77bc677ddac892614a7296254099251e8379"},{"one":"dc41672c95ae1af5b7008f7b1c4e232dc469c4969095d357a6e713257ddb8f7220eadf41082cb22503cee38c042160f5d9750f4787b6e44dc8eaa5bd76df8e55","up":true,"other":"641004e2e499316f46b8b5e0744a5bfcb24323d44c25ed043d57b18406b71bb4e6053df63eb83488c950ba74ae007bc4d5ae711a891eded4a8ea6aa45fb8312a"},{"one":"00508d6e28f4b503d346983d740c24c440c6eab33128d86c60cb2ce8c70d17189a96a7e6f212dd25f383d1902d04206784edb7fc8b1c391e4465afcd18192c1c","other":"a93e19158ae6a4261186b663bf109258d759e42b8e0e1d5c06e79a9b6844e6acb41c0a4ce38dfdf250d6016aa796fb78807a7f91738f4eef8a36dafdd60afec7","up":true},{"up":true,"other":"841c007c8c5c96f6d7759d186bbf008e64fb9ab6e88c215c0fff31285ac3a47108962699f6fcc995bce7059787fa69bfbc82d36bfaa155ee207a7044bb839c96","one":"a93e19158ae6a4261186b663bf109258d759e42b8e0e1d5c06e79a9b6844e6acb41c0a4ce38dfdf250d6016aa796fb78807a7f91738f4eef8a36dafdd60afec7"},{"up":true,"other":"ef8f752702c272b1efa3df07957eaaf69854f906df7eebc65b9e5afcb2d3302c712ecf7f4730915f7f29d60cd3463e8393f4d7e34c1b4a7696c855332e4b3d25","one":"8eea2dd2475d894484f737bb61fa632585ab0a82e47c070327eb65de8b5cf76ad6bbebba1b94b5fe19f6c631e429d1273740937da9ec6cabbcdfd5bd176cc362"},{"one":"00508d6e28f4b503d346983d740c24c440c6eab33128d86c60cb2ce8c70d17189a96a7e6f212dd25f383d1902d04206784edb7fc8b1c391e4465afcd18192c1c","other":"df4e07354dd593b1986e996f84c3e97147f72f4c6367ec876472c7384fe2d850ee6a8abeb37b789e7c50c12aa3533f19a6c7d9c37bb1b884c61eee307488ed88","up":true},{"up":true,"other":"dd1ecdd5e7bdd1ab85a946132cfd7e27c8a29e0256ebe859a9c9283cbb872f9406b30a835826ecece342ab5c41f4c34fdb75049acf0ee134ca8f94c3158a73e0","one":"df4e07354dd593b1986e996f84c3e97147f72f4c6367ec876472c7384fe2d850ee6a8abeb37b789e7c50c12aa3533f19a6c7d9c37bb1b884c61eee307488ed88"},{"other":"12b2d36d0e1a7255bde9c81fc9fac8befd7119bbafb74773cee281a73a9095fcceb8a5bc6fc01d8fcc948adbf2b6b6d190017b307875fbea971e6604ddb219de","up":true,"one":"a93e19158ae6a4261186b663bf109258d759e42b8e0e1d5c06e79a9b6844e6acb41c0a4ce38dfdf250d6016aa796fb78807a7f91738f4eef8a36dafdd60afec7"},{"other":"df4e07354dd593b1986e996f84c3e97147f72f4c6367ec876472c7384fe2d850ee6a8abeb37b789e7c50c12aa3533f19a6c7d9c37bb1b884c61eee307488ed88","up":true,"one":"8eea2dd2475d894484f737bb61fa632585ab0a82e47c070327eb65de8b5cf76ad6bbebba1b94b5fe19f6c631e429d1273740937da9ec6cabbcdfd5bd176cc362"}],"nodes":[{"node":{"config":{"private_key":"8f572fa1cb0643b3413cd0dfceac00a4dac9ec09af0c2d134809b6385dad35d7","services":["pss","bzz"],"id":"ddfccaa30a25c32b199a98046669df50b5bb07447cf9dafec69934d9b38dfe447bd0b8fc8b33b0453d63088ff65deca8bec067a3f79a545c988ab7f7b735e1f2","name":"node01"},"up":true,"info":{"enode":"enode://ddfccaa30a25c32b199a98046669df50b5bb07447cf9dafec69934d9b38dfe447bd0b8fc8b33b0453d63088ff65deca8bec067a3f79a545c988ab7f7b735e1f2@0.0.0.0:0","listenAddr":"","ports":{"discovery":0,"listener":0},"protocols":{"bzz":"f0GY3c+1Xp9pACTMGc5PMtW7yNVs+0P4BlE6dOUtwnc=","hive":"\n=========================================================================\nFri Sep 29 20:17:10 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 7f4198\npopulation: 9 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 e752 | 36 b2a2 (0) b04c (0) b45f (0) b523 (0)\n001 1 3bc8 | 12 34ad (0) 39e7 (0) 3bc8 (0) 292b (0)\n002 3 5fd6 461c 4ff2 | 7 5205 (0) 5c19 (0) 5e64 (0) 5fd6 (0)\n003 1 647c | 5 6d29 (0) 6b33 (0) 6a5c (0) 647c (0)\n============ DEPTH: 4 ==========================================\n004 2 71fe 7411 | 2 71fe (0) 7411 (0)\n005 0 | 0\n006 0 | 0\n007 0 | 0\n008 1 7fe4 | 1 7fe4 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ip":"0.0.0.0","name":"node01","id":"ddfccaa30a25c32b199a98046669df50b5bb07447cf9dafec69934d9b38dfe447bd0b8fc8b33b0453d63088ff65deca8bec067a3f79a545c988ab7f7b735e1f2"}}},{"node":{"config":{"private_key":"a66e079664952b1fb1028e959dd8a05a21477e2f298ea89592adc522d38e511b","name":"node02","id":"0445005ab3e1a97c7fb9d9a4e77d4da6c51881f2454a35f945fdce1318e863ef3e27784938720c80ebbb3c6440e63bd9ae0fecdf21d78d7e24357ddd9b430b37","services":["pss","bzz"]},"up":true,"info":{"id":"0445005ab3e1a97c7fb9d9a4e77d4da6c51881f2454a35f945fdce1318e863ef3e27784938720c80ebbb3c6440e63bd9ae0fecdf21d78d7e24357ddd9b430b37","name":"node02","ip":"0.0.0.0","protocols":{"bzz":"51I4E18MBxylQfsKlWnjgDbFGvNQoWv0oVJvF1IxgFk=","hive":"\n=========================================================================\nFri Sep 29 20:17:10 UTC 2017 KΛÐΞMLIΛ hive: queen's address: e75238\npopulation: 10 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 1102 7f41 | 28 34ad (0) 39e7 (0) 3bc8 (0) 292b (0)\n001 1 b2a2 | 19 b2a2 (0) b04c (0) b45f (0) b523 (0)\n002 1 d79a | 10 df45 (0) d79a (0) c0d6 (0) cab4 (0)\n003 2 f051 f3a5 | 2 f3a5 (0) f051 (0)\n004 1 eebe | 1 eebe (0)\n============ DEPTH: 5 ==========================================\n005 2 e020 e046 | 2 e046 (0) e020 (0)\n006 1 e45d | 1 e45d (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"listener":0,"discovery":0},"enode":"enode://0445005ab3e1a97c7fb9d9a4e77d4da6c51881f2454a35f945fdce1318e863ef3e27784938720c80ebbb3c6440e63bd9ae0fecdf21d78d7e24357ddd9b430b37@0.0.0.0:0","listenAddr":""}}},{"node":{"up":true,"info":{"listenAddr":"","enode":"enode://841c007c8c5c96f6d7759d186bbf008e64fb9ab6e88c215c0fff31285ac3a47108962699f6fcc995bce7059787fa69bfbc82d36bfaa155ee207a7044bb839c96@0.0.0.0:0","ports":{"listener":0,"discovery":0},"protocols":{"bzz":"EQLSh8cr7PG/qFZ89DzCBRrtFqeRlvkQnN7fgpoqWi0=","hive":"\n=========================================================================\nFri Sep 29 20:17:10 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 1102d2\npopulation: 12 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 cab4 e752 | 36 b04c (0) b2a2 (0) b45f (0) b523 (0)\n001 3 71fe 5fd6 461c | 16 4ff2 (0) 461c (0) 5205 (0) 5c19 (0)\n002 2 2218 34ad | 6 292b (0) 2218 (0) 2597 (0) 39e7 (0)\n003 3 0b45 0f5c 0f98 | 3 0b45 (0) 0f5c (0) 0f98 (0)\n============ DEPTH: 4 ==========================================\n004 1 1f17 | 1 1f17 (0)\n005 0 | 0\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 1 113d | 1 113d (0)\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ip":"0.0.0.0","name":"node03","id":"841c007c8c5c96f6d7759d186bbf008e64fb9ab6e88c215c0fff31285ac3a47108962699f6fcc995bce7059787fa69bfbc82d36bfaa155ee207a7044bb839c96"},"config":{"services":["pss","bzz"],"name":"node03","id":"841c007c8c5c96f6d7759d186bbf008e64fb9ab6e88c215c0fff31285ac3a47108962699f6fcc995bce7059787fa69bfbc82d36bfaa155ee207a7044bb839c96","private_key":"072e1cf99b52c2f1d40560809048fea86f39ae1db94bec2c9b71b0bfe092910a"}}},{"node":{"info":{"ports":{"listener":0,"discovery":0},"ip":"0.0.0.0","protocols":{"hive":"\n=========================================================================\nFri Sep 29 20:17:10 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 34ad94\npopulation: 13 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 eebe 9bb1 | 36 b04c (0) b2a2 (0) b45f (0) b523 (0)\n001 4 66d5 5a4f 5c19 5fd6 | 16 461c (0) 4ff2 (0) 5205 (0) 5c19 (0)\n002 3 0f5c 1f17 1102 | 6 0b45 (0) 0f5c (0) 0f98 (0) 1f17 (0)\n003 2 292b 2218 | 3 292b (0) 2218 (0) 2597 (0)\n============ DEPTH: 4 ==========================================\n004 2 39e7 3bc8 | 2 39e7 (0) 3bc8 (0)\n005 0 | 0\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"NK2UMbcc3q4MGUGzrmgDh7PO3YFfOdZQNIkpIKqGnzg="},"enode":"enode://06a6d7bd7fc3d209e3464e20fdc04df0c20f5fc991172a7847dab790db55daf735cf56d65d5471291511ce99524a934c2cb839cdb6ef4dcf7f025b600f5adbea@0.0.0.0:0","listenAddr":"","name":"node04","id":"06a6d7bd7fc3d209e3464e20fdc04df0c20f5fc991172a7847dab790db55daf735cf56d65d5471291511ce99524a934c2cb839cdb6ef4dcf7f025b600f5adbea"},"up":true,"config":{"name":"node04","id":"06a6d7bd7fc3d209e3464e20fdc04df0c20f5fc991172a7847dab790db55daf735cf56d65d5471291511ce99524a934c2cb839cdb6ef4dcf7f025b600f5adbea","services":["pss","bzz"],"private_key":"003ec9cb18f157360d7a3eb506b37ec69dbbd141bbeb7b8fae5f470b1a0768db"}}},{"node":{"config":{"private_key":"fd6fc50368fbc7e848635726291264cf6ad682fb4fe785b724c8b22ea31e1e24","name":"node05","id":"3780f49d8de4f4a44cba2cff7c6acedb10c32a737808c8c7328c29f7686d0351f9c8d4429b320af2560f550f9692507c426c5d30858b0ef79bd8c5e4db58d6b8","services":["pss","bzz"]},"up":true,"info":{"name":"node05","id":"3780f49d8de4f4a44cba2cff7c6acedb10c32a737808c8c7328c29f7686d0351f9c8d4429b320af2560f550f9692507c426c5d30858b0ef79bd8c5e4db58d6b8","enode":"enode://3780f49d8de4f4a44cba2cff7c6acedb10c32a737808c8c7328c29f7686d0351f9c8d4429b320af2560f550f9692507c426c5d30858b0ef79bd8c5e4db58d6b8@0.0.0.0:0","listenAddr":"","ports":{"discovery":0,"listener":0},"protocols":{"hive":"\n=========================================================================\nFri Sep 29 20:17:10 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 9bb12f\npopulation: 9 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 34ad | 28 461c (0) 4ff2 (0) 5205 (0) 5c19 (0)\n001 1 f051 | 17 f3a5 (0) f051 (0) eebe (0) e046 (0)\n002 1 b523 | 10 b04c (0) b2a2 (0) b45f (0) b523 (0)\n003 2 80d0 8c5f | 4 80d0 (0) 85d6 (0) 88b4 (0) 8c5f (0)\n004 2 9035 9045 | 2 9035 (0) 9045 (0)\n============ DEPTH: 5 ==========================================\n005 2 9e94 9e38 | 2 9e94 (0) 9e38 (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"m7EvZgBvM0d5DCxOdOVGP9arZRdoKW7kHeUXV7n0C4k="},"ip":"0.0.0.0"}}},{"node":{"up":true,"info":{"id":"698cf5333166bf22a15679cb0d88d7382fe980455a6c288556310898e6aeb3fb04262b89e146d4bff2a4e5501574bd7b55adf3a2ccde080e7a3acab9fdb78e1a","name":"node06","enode":"enode://698cf5333166bf22a15679cb0d88d7382fe980455a6c288556310898e6aeb3fb04262b89e146d4bff2a4e5501574bd7b55adf3a2ccde080e7a3acab9fdb78e1a@0.0.0.0:0","listenAddr":"","ip":"0.0.0.0","protocols":{"bzz":"kEXpEtwKyvnYbsddmOk7yQgy28oRGWQfhWmpgEC+lAw=","hive":"\n=========================================================================\nFri Sep 29 20:17:10 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 9045e9\npopulation: 8 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 5205 | 28 4ff2 (0) 461c (0) 5205 (0) 5c19 (0)\n001 1 cf69 | 17 f3a5 (0) f051 (0) eebe (0) e046 (0)\n002 1 b523 | 10 b04c (0) b2a2 (0) b45f (0) b523 (0)\n003 1 80d0 | 4 80d0 (0) 85d6 (0) 88b4 (0) 8c5f (0)\n============ DEPTH: 4 ==========================================\n004 3 9e38 9e94 9bb1 | 3 9e94 (0) 9e38 (0) 9bb1 (0)\n005 0 | 0\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 1 9035 | 1 9035 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"discovery":0,"listener":0}},"config":{"private_key":"da156f269cb01e7fbea5efd5f7ab6283ef0994a1ca139768f49c68e027ca76b0","services":["pss","bzz"],"id":"698cf5333166bf22a15679cb0d88d7382fe980455a6c288556310898e6aeb3fb04262b89e146d4bff2a4e5501574bd7b55adf3a2ccde080e7a3acab9fdb78e1a","name":"node06"}}},{"node":{"info":{"id":"e968aa3ce0d669bab524f11df68ea707d6f4ed9c4367b78e20acd66af8deb0a965368ed4fa171f579ba931001f47092e97d5d37d80075570f61a2eebb21bbd4b","name":"node07","listenAddr":"","enode":"enode://e968aa3ce0d669bab524f11df68ea707d6f4ed9c4367b78e20acd66af8deb0a965368ed4fa171f579ba931001f47092e97d5d37d80075570f61a2eebb21bbd4b@0.0.0.0:0","ip":"0.0.0.0","protocols":{"hive":"\n=========================================================================\nFri Sep 29 20:17:10 UTC 2017 KΛÐΞMLIΛ hive: queen's address: cf69e5\npopulation: 12 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 5fd6 | 28 461c (0) 4ff2 (0) 5205 (0) 5c19 (0)\n001 1 9045 | 19 b04c (0) b2a2 (0) b45f (0) b523 (0)\n002 1 f3a5 | 7 f3a5 (0) f051 (0) eebe (0) e046 (0)\n003 2 df45 d79a | 2 d79a (0) df45 (0)\n004 1 c0d6 | 1 c0d6 (0)\n005 2 c85b cab4 | 2 cab4 (0) c85b (0)\n006 1 cc70 | 1 cc70 (0)\n============ DEPTH: 7 ==========================================\n007 2 cee0 cec7 | 2 cee0 (0) cec7 (0)\n008 1 cfc8 | 1 cfc8 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"z2nl+O/+4ADcFhCafg0E5OE66y9sCJmZ5VWUakblSPY="},"ports":{"discovery":0,"listener":0}},"up":true,"config":{"private_key":"ae570046bebe22a2cd095ca2b2282cab29b2501c6f217ae3e19d96bace36c199","services":["pss","bzz"],"id":"e968aa3ce0d669bab524f11df68ea707d6f4ed9c4367b78e20acd66af8deb0a965368ed4fa171f579ba931001f47092e97d5d37d80075570f61a2eebb21bbd4b","name":"node07"}}},{"node":{"up":true,"info":{"name":"node08","id":"269e5d200ae242b0b101bd7d465e009fc7eb22b074f1d9b562580bf452d592420e4063d03fab92c6fa61a32633492ee1b4fb20c3a8f44ec7ca07839bee871828","ports":{"discovery":0,"listener":0},"protocols":{"bzz":"zHCORxlqZDWxOxjyE/UL8HXz+XEA1S0Y1wBS78MByRo=","hive":"\n=========================================================================\nFri Sep 29 20:17:10 UTC 2017 KΛÐΞMLIΛ hive: queen's address: cc708e\npopulation: 13 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 0f98 | 28 1f17 (0) 1102 (0) 113d (0) 0b45 (0)\n001 2 b2a2 b04c | 19 b04c (0) b2a2 (0) b45f (0) b523 (0)\n002 1 f3a5 | 7 eebe (0) e046 (0) e020 (0) e752 (0)\n003 2 d79a df45 | 2 d79a (0) df45 (0)\n004 1 c0d6 | 1 c0d6 (0)\n005 2 c85b cab4 | 2 cab4 (0) c85b (0)\n============ DEPTH: 6 ==========================================\n006 4 cec7 cee0 cfc8 cf69 | 4 cee0 (0) cec7 (0) cfc8 (0) cf69 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ip":"0.0.0.0","listenAddr":"","enode":"enode://269e5d200ae242b0b101bd7d465e009fc7eb22b074f1d9b562580bf452d592420e4063d03fab92c6fa61a32633492ee1b4fb20c3a8f44ec7ca07839bee871828@0.0.0.0:0"},"config":{"services":["pss","bzz"],"name":"node08","id":"269e5d200ae242b0b101bd7d465e009fc7eb22b074f1d9b562580bf452d592420e4063d03fab92c6fa61a32633492ee1b4fb20c3a8f44ec7ca07839bee871828","private_key":"dee3b946981d4b7bd055941cd6722b166efc24f28f6b26da9cd52a8f91f3a411"}}},{"node":{"info":{"id":"12b2d36d0e1a7255bde9c81fc9fac8befd7119bbafb74773cee281a73a9095fcceb8a5bc6fc01d8fcc948adbf2b6b6d190017b307875fbea971e6604ddb219de","name":"node09","listenAddr":"","enode":"enode://12b2d36d0e1a7255bde9c81fc9fac8befd7119bbafb74773cee281a73a9095fcceb8a5bc6fc01d8fcc948adbf2b6b6d190017b307875fbea971e6604ddb219de@0.0.0.0:0","ip":"0.0.0.0","protocols":{"bzz":"86V/iH3c8XkyB5SDdM5n2p9qEifyU+OpCsxbNqSO5kU=","hive":"\n=========================================================================\nFri Sep 29 20:17:10 UTC 2017 KΛÐΞMLIΛ hive: queen's address: f3a57f\npopulation: 15 (62), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 5e64 | 28 113d (0) 1102 (0) 1f17 (0) 0b45 (0)\n001 2 b04c bece | 18 8c5f (0) 88b4 (0) 80d0 (0) 85d6 (0)\n002 6 cab4 cfc8 cf69 cee0 | 10 d79a (0) df45 (0) c0d6 (0) cab4 (0)\n============ DEPTH: 3 ==========================================\n003 5 eebe e020 e046 e752 | 5 eebe (0) e046 (0) e020 (0) e752 (0)\n004 0 | 0\n005 0 | 0\n006 1 f051 | 1 f051 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"listener":0,"discovery":0}},"up":true,"config":{"services":["pss","bzz"],"id":"12b2d36d0e1a7255bde9c81fc9fac8befd7119bbafb74773cee281a73a9095fcceb8a5bc6fc01d8fcc948adbf2b6b6d190017b307875fbea971e6604ddb219de","name":"node09","private_key":"b7e566b24a7c97f714c9920c4e426dd462ee171bb8fd91a3efee9bd1d28dd060"}}},{"node":{"info":{"id":"2455595a3aefc0cd619c569d920c279e968022ee53cc07b5a0e3e4d7f8ce315739d432389a2bc26c1890fd8af33c1ced0790c7f644d205361e78c787c803ad88","name":"node10","protocols":{"hive":"\n=========================================================================\nFri Sep 29 20:17:10 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 5e64f3\npopulation: 9 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 f3a5 | 36 8c5f (0) 88b4 (0) 85d6 (0) 80d0 (0)\n001 1 113d | 12 113d (0) 1102 (0) 1f17 (0) 0b45 (0)\n002 1 7411 | 9 66d5 (0) 647c (0) 6d29 (0) 6a5c (0)\n003 2 4ff2 461c | 2 4ff2 (0) 461c (0)\n004 1 5205 | 1 5205 (0)\n005 1 5a4f | 1 5a4f (0)\n============ DEPTH: 6 ==========================================\n006 1 5c19 | 1 5c19 (0)\n007 1 5fd6 | 1 5fd6 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"XmTzKVJeFxKbP1FYCzmaXwnXZSpmO7qsg8gXPdn97UE="},"ip":"0.0.0.0","ports":{"listener":0,"discovery":0},"listenAddr":"","enode":"enode://2455595a3aefc0cd619c569d920c279e968022ee53cc07b5a0e3e4d7f8ce315739d432389a2bc26c1890fd8af33c1ced0790c7f644d205361e78c787c803ad88@0.0.0.0:0"},"up":true,"config":{"id":"2455595a3aefc0cd619c569d920c279e968022ee53cc07b5a0e3e4d7f8ce315739d432389a2bc26c1890fd8af33c1ced0790c7f644d205361e78c787c803ad88","name":"node10","services":["pss","bzz"],"private_key":"070b030d06605c46eafadabb979d38f9d4f48cf55e24a96378f4f0bbe2806887"}}},{"node":{"config":{"id":"5e36d45cd33f0deda83595a1d7196ae42408793b821245224d6585b4291c88149403d2f8b49523137fb26f8353647b3e48261c198504ccf8544cc9131d2890d8","name":"node11","services":["pss","bzz"],"private_key":"4ad1a65bb55e2f6d41cc3383b1de11c79bab13723c02d4f5abaf725d6aaea3e4"},"info":{"listenAddr":"","enode":"enode://5e36d45cd33f0deda83595a1d7196ae42408793b821245224d6585b4291c88149403d2f8b49523137fb26f8353647b3e48261c198504ccf8544cc9131d2890d8@0.0.0.0:0","ip":"0.0.0.0","protocols":{"bzz":"dBF+KZ//zh738yPqHW+xxQnNVYH2xT4PXpr40Lg3SPI=","hive":"\n=========================================================================\nFri Sep 29 20:17:10 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 74117e\npopulation: 8 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 a416 | 36 f3a5 (0) f051 (0) eebe (0) e046 (0)\n001 2 113d 0b45 | 12 113d (0) 1102 (0) 1f17 (0) 0b45 (0)\n002 1 5e64 | 7 4ff2 (0) 461c (0) 5205 (0) 5a4f (0)\n003 1 6b33 | 5 647c (0) 66d5 (0) 6d29 (0) 6a5c (0)\n============ DEPTH: 4 ==========================================\n004 2 7f41 7fe4 | 2 7f41 (0) 7fe4 (0)\n005 1 71fe | 1 71fe (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"listener":0,"discovery":0},"id":"5e36d45cd33f0deda83595a1d7196ae42408793b821245224d6585b4291c88149403d2f8b49523137fb26f8353647b3e48261c198504ccf8544cc9131d2890d8","name":"node11"},"up":true}},{"node":{"up":true,"info":{"id":"18c79fcf8500f4d5cb609ef72277112430da75ef83466bdbe0ea4d3a5d6997ca27a94ba0bb35a7a40f5b56bd8242cb20228a6802c4cbb27b934a904eed057b2c","name":"node12","ip":"0.0.0.0","protocols":{"hive":"\n=========================================================================\nFri Sep 29 20:17:10 UTC 2017 KΛÐΞMLIΛ hive: queen's address: a416fa\npopulation: 12 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 7411 3bc8 | 28 5205 (0) 5a4f (0) 5c19 (0) 5fd6 (0)\n001 2 df45 cfc8 | 17 df45 (0) d79a (0) c0d6 (0) cab4 (0)\n002 2 9035 9e94 | 9 80d0 (0) 85d6 (0) 8c5f (0) 88b4 (0)\n003 3 bece b04c b2a2 | 6 b2a2 (0) b04c (0) b45f (0) b523 (0)\n============ DEPTH: 4 ==========================================\n004 2 aa65 ab1c | 2 aa65 (0) ab1c (0)\n005 1 a365 | 1 a365 (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"pBb6hSu0JeALgF/6u1Ja5FAkQDaFoOimeBVhf9HQeNo="},"ports":{"discovery":0,"listener":0},"listenAddr":"","enode":"enode://18c79fcf8500f4d5cb609ef72277112430da75ef83466bdbe0ea4d3a5d6997ca27a94ba0bb35a7a40f5b56bd8242cb20228a6802c4cbb27b934a904eed057b2c@0.0.0.0:0"},"config":{"id":"18c79fcf8500f4d5cb609ef72277112430da75ef83466bdbe0ea4d3a5d6997ca27a94ba0bb35a7a40f5b56bd8242cb20228a6802c4cbb27b934a904eed057b2c","name":"node12","services":["pss","bzz"],"private_key":"bbe3351a79ad82f8b832dc16567dd1bcc24b1897bc9bfec930f3461a61f7d652"}}},{"node":{"up":true,"info":{"protocols":{"bzz":"O8jUBTWaZl0/bWTPm6GUt+YUwgUK3QoSBb5/bDyYTh0=","hive":"\n=========================================================================\nFri Sep 29 20:17:10 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 3bc8d4\npopulation: 13 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 e45d ab1c a416 | 36 df45 (0) d79a (0) c0d6 (0) cab4 (0)\n001 4 6a5c 7fe4 7f41 5205 | 16 5205 (0) 5a4f (0) 5c19 (0) 5e64 (0)\n002 1 113d | 6 113d (0) 1102 (0) 1f17 (0) 0b45 (0)\n003 3 292b 2597 2218 | 3 292b (0) 2597 (0) 2218 (0)\n============ DEPTH: 4 ==========================================\n004 1 34ad | 1 34ad (0)\n005 0 | 0\n006 1 39e7 | 1 39e7 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"enode":"enode://128c42c3e21d7ba3c1bb7481c1119fa85124e827114a0bf7243c9b34b61f2f70111402ef1d4bfa8df69f2472f95b4ad44a95991c1adbe85c20f66436c9247e4e@0.0.0.0:0","listenAddr":"","id":"128c42c3e21d7ba3c1bb7481c1119fa85124e827114a0bf7243c9b34b61f2f70111402ef1d4bfa8df69f2472f95b4ad44a95991c1adbe85c20f66436c9247e4e","name":"node13"},"config":{"private_key":"26e548a577ae1fcc718256e75d48d70ed406dda8798f84c967d7dfe45c6aceb5","services":["pss","bzz"],"name":"node13","id":"128c42c3e21d7ba3c1bb7481c1119fa85124e827114a0bf7243c9b34b61f2f70111402ef1d4bfa8df69f2472f95b4ad44a95991c1adbe85c20f66436c9247e4e"}}},{"node":{"config":{"private_key":"97ca855261319532dfa74bf6194b4302c3d2f971adbd462e3437408df6dcbe47","services":["pss","bzz"],"id":"4c53fcf455540cc5f4fd48a57fb68e643eaf769085f350129e1dfa76ef56d33f31b950a42721dbe445a73151edbdb54ce0169204a17a58031a07f11ea1347ed0","name":"node14"},"up":true,"info":{"listenAddr":"","enode":"enode://4c53fcf455540cc5f4fd48a57fb68e643eaf769085f350129e1dfa76ef56d33f31b950a42721dbe445a73151edbdb54ce0169204a17a58031a07f11ea1347ed0@0.0.0.0:0","ports":{"listener":0,"discovery":0},"protocols":{"hive":"\n=========================================================================\nFri Sep 29 20:17:10 UTC 2017 KΛÐΞMLIΛ hive: queen's address: e45d7b\npopulation: 10 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 3bc8 113d | 28 647c (0) 66d5 (0) 6d29 (0) 6b33 (0)\n001 1 a365 | 19 a365 (0) a416 (0) aa65 (0) ab1c (0)\n002 1 c85b | 10 df45 (0) d79a (0) c0d6 (0) cab4 (0)\n003 2 f051 f3a5 | 2 f3a5 (0) f051 (0)\n004 1 eebe | 1 eebe (0)\n============ DEPTH: 5 ==========================================\n005 2 e046 e020 | 2 e046 (0) e020 (0)\n006 1 e752 | 1 e752 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"5F17SHCsuKmEwGXM570XrK95xa1NR3+BBWMxWuus2OM="},"ip":"0.0.0.0","name":"node14","id":"4c53fcf455540cc5f4fd48a57fb68e643eaf769085f350129e1dfa76ef56d33f31b950a42721dbe445a73151edbdb54ce0169204a17a58031a07f11ea1347ed0"}}},{"node":{"config":{"services":["pss","bzz"],"name":"node15","id":"b13271912256c91940de954a90f73889c8abb76c4e92ecedd68e37dc50dcb253a2164607400f2b798d3c2d612d1c77bc677ddac892614a7296254099251e8379","private_key":"a762e1b25bed356f9a9e3aed01c7a38e8f57441b6caa18874712ef1159616b57"},"info":{"name":"node15","id":"b13271912256c91940de954a90f73889c8abb76c4e92ecedd68e37dc50dcb253a2164607400f2b798d3c2d612d1c77bc677ddac892614a7296254099251e8379","ports":{"listener":0,"discovery":0},"ip":"0.0.0.0","protocols":{"hive":"\n=========================================================================\nFri Sep 29 20:17:10 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 113d78\npopulation: 14 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 cab4 e020 e45d | 36 a365 (0) a416 (0) aa65 (0) ab1c (0)\n001 4 5e64 6b33 71fe 7411 | 16 6d29 (0) 6b33 (0) 6a5c (0) 66d5 (0)\n002 4 39e7 3bc8 2218 292b | 6 292b (0) 2597 (0) 2218 (0) 34ad (0)\n003 1 0f98 | 3 0b45 (0) 0f98 (0) 0f5c (0)\n============ DEPTH: 4 ==========================================\n004 1 1f17 | 1 1f17 (0)\n005 0 | 0\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 1 1102 | 1 1102 (0)\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"ET14UOgWl2HTV+CtWiYlYP5hN/xqmSs7LO3Ou+XV9qI="},"listenAddr":"","enode":"enode://b13271912256c91940de954a90f73889c8abb76c4e92ecedd68e37dc50dcb253a2164607400f2b798d3c2d612d1c77bc677ddac892614a7296254099251e8379@0.0.0.0:0"},"up":true}},{"node":{"config":{"private_key":"53407f7862d16cdfd7beb23612d5d57dda1963cf729766feb046966e15850b32","name":"node16","id":"f9db826a99d327db544fa023ed13b689fd7c40ac9abdfd59d376efd245839ab8d34a3b5d9783fe0461e7ccdff35395e8df8983396df1a87f505663139eab7b20","services":["pss","bzz"]},"up":true,"info":{"id":"f9db826a99d327db544fa023ed13b689fd7c40ac9abdfd59d376efd245839ab8d34a3b5d9783fe0461e7ccdff35395e8df8983396df1a87f505663139eab7b20","name":"node16","protocols":{"hive":"\n=========================================================================\nFri Sep 29 20:17:10 UTC 2017 KΛÐΞMLIΛ hive: queen's address: e0205d\npopulation: 11 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 2218 113d | 28 6d29 (0) 6b33 (0) 6a5c (0) 66d5 (0)\n001 1 85d6 | 19 85d6 (0) 80d0 (0) 8c5f (0) 88b4 (0)\n002 2 d79a c0d6 | 10 df45 (0) d79a (0) c0d6 (0) cab4 (0)\n003 2 f3a5 f051 | 2 f3a5 (0) f051 (0)\n004 1 eebe | 1 eebe (0)\n============ DEPTH: 5 ==========================================\n005 2 e752 e45d | 2 e752 (0) e45d (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 1 e046 | 1 e046 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"4CBdoiXnf6FTMoZOrvHEN74wYJCwSJ+vP2clyzxbRxI="},"ip":"0.0.0.0","ports":{"listener":0,"discovery":0},"enode":"enode://f9db826a99d327db544fa023ed13b689fd7c40ac9abdfd59d376efd245839ab8d34a3b5d9783fe0461e7ccdff35395e8df8983396df1a87f505663139eab7b20@0.0.0.0:0","listenAddr":""}}},{"node":{"config":{"services":["pss","bzz"],"name":"node17","id":"dd1ecdd5e7bdd1ab85a946132cfd7e27c8a29e0256ebe859a9c9283cbb872f9406b30a835826ecece342ab5c41f4c34fdb75049acf0ee134ca8f94c3158a73e0","private_key":"f3ffbcce6a7f7bfe25c3ab3ba95dd0574944bb5a09eabda3da69f187c48ea747"},"info":{"listenAddr":"","enode":"enode://dd1ecdd5e7bdd1ab85a946132cfd7e27c8a29e0256ebe859a9c9283cbb872f9406b30a835826ecece342ab5c41f4c34fdb75049acf0ee134ca8f94c3158a73e0@0.0.0.0:0","protocols":{"bzz":"IhgXDe+ZYtQAv5Ms7ZHzwUWVBitQ74brTS9/04T8hZc=","hive":"\n=========================================================================\nFri Sep 29 20:17:10 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 221817\npopulation: 10 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 e020 c0d6 c85b | 36 85d6 (0) 80d0 (0) 8c5f (0) 88b4 (0)\n001 1 6d29 | 16 6d29 (0) 6b33 (0) 6a5c (0) 66d5 (0)\n002 2 113d 1102 | 6 113d (0) 1102 (0) 1f17 (0) 0b45 (0)\n003 2 34ad 3bc8 | 3 34ad (0) 39e7 (0) 3bc8 (0)\n============ DEPTH: 4 ==========================================\n004 1 292b | 1 292b (0)\n005 1 2597 | 1 2597 (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"id":"dd1ecdd5e7bdd1ab85a946132cfd7e27c8a29e0256ebe859a9c9283cbb872f9406b30a835826ecece342ab5c41f4c34fdb75049acf0ee134ca8f94c3158a73e0","name":"node17"},"up":true}},{"node":{"info":{"ip":"0.0.0.0","protocols":{"bzz":"yFs5ZoSGxes+qfMS2Yl72laIxJlTGOTmSgvirAy0dpI=","hive":"\n=========================================================================\nFri Sep 29 20:17:10 UTC 2017 KΛÐΞMLIΛ hive: queen's address: c85b39\npopulation: 14 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 0f98 2218 5fd6 | 28 113d (0) 1102 (0) 1f17 (0) 0b45 (0)\n001 1 b523 | 19 85d6 (0) 80d0 (0) 8c5f (0) 88b4 (0)\n002 1 e45d | 7 f3a5 (0) f051 (0) eebe (0) e752 (0)\n003 2 df45 d79a | 2 d79a (0) df45 (0)\n004 1 c0d6 | 1 c0d6 (0)\n============ DEPTH: 5 ==========================================\n005 5 cc70 cf69 cfc8 cee0 | 5 cc70 (0) cfc8 (0) cf69 (0) cee0 (0)\n006 1 cab4 | 1 cab4 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"discovery":0,"listener":0},"listenAddr":"","enode":"enode://ef8f752702c272b1efa3df07957eaaf69854f906df7eebc65b9e5afcb2d3302c712ecf7f4730915f7f29d60cd3463e8393f4d7e34c1b4a7696c855332e4b3d25@0.0.0.0:0","id":"ef8f752702c272b1efa3df07957eaaf69854f906df7eebc65b9e5afcb2d3302c712ecf7f4730915f7f29d60cd3463e8393f4d7e34c1b4a7696c855332e4b3d25","name":"node18"},"up":true,"config":{"private_key":"0fc26e702e6bf4755536ef14b178df72099f9d2e818b53ce85f5b5ff3ea6c9c8","services":["pss","bzz"],"name":"node18","id":"ef8f752702c272b1efa3df07957eaaf69854f906df7eebc65b9e5afcb2d3302c712ecf7f4730915f7f29d60cd3463e8393f4d7e34c1b4a7696c855332e4b3d25"}}},{"node":{"config":{"id":"ccbbc901d05610202edfd1eba445dc0c93c3ab1dfcc4c9eecd9f1f12521508407429b605840eb8fed9893a1fd8ef6dcd29c9627fe8d3d41ca094b10ab977aa8b","name":"node19","services":["pss","bzz"],"private_key":"6f1be181439476148e13cd2c39dd8983588047ef5f966091688ce37a01f78441"},"up":true,"info":{"listenAddr":"","enode":"enode://ccbbc901d05610202edfd1eba445dc0c93c3ab1dfcc4c9eecd9f1f12521508407429b605840eb8fed9893a1fd8ef6dcd29c9627fe8d3d41ca094b10ab977aa8b@0.0.0.0:0","ip":"0.0.0.0","protocols":{"bzz":"X9ZkRn+sZVlMPdb4m/KlOY4oqpXSSMOj0hq67P6/3l0=","hive":"\n=========================================================================\nFri Sep 29 20:17:10 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 5fd664\npopulation: 11 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 cf69 c85b | 36 8c5f (0) 88b4 (0) 80d0 (0) 85d6 (0)\n001 2 34ad 1102 | 12 113d (0) 1102 (0) 1f17 (0) 0b45 (0)\n002 1 7f41 | 9 6d29 (0) 6b33 (0) 6a5c (0) 66d5 (0)\n003 2 4ff2 461c | 2 4ff2 (0) 461c (0)\n004 1 5205 | 1 5205 (0)\n005 1 5a4f | 1 5a4f (0)\n============ DEPTH: 6 ==========================================\n006 1 5c19 | 1 5c19 (0)\n007 1 5e64 | 1 5e64 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"listener":0,"discovery":0},"id":"ccbbc901d05610202edfd1eba445dc0c93c3ab1dfcc4c9eecd9f1f12521508407429b605840eb8fed9893a1fd8ef6dcd29c9627fe8d3d41ca094b10ab977aa8b","name":"node19"}}},{"node":{"info":{"ports":{"discovery":0,"listener":0},"protocols":{"bzz":"Rhx/j4lIaT3qcXZ5/8S78OtXP0WXVDmT474501lP3Uc=","hive":"\n=========================================================================\nFri Sep 29 20:17:10 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 461c7f\npopulation: 15 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 df45 | 36 80d0 (0) 85d6 (0) 88b4 (0) 8c5f (0)\n001 2 0f98 1102 | 12 113d (0) 1102 (0) 1f17 (0) 0b45 (0)\n002 6 647c 6b33 6d29 71fe | 9 6d29 (0) 6b33 (0) 6a5c (0) 66d5 (0)\n============ DEPTH: 3 ==========================================\n003 5 5205 5a4f 5c19 5e64 | 5 5205 (0) 5a4f (0) 5c19 (0) 5e64 (0)\n004 1 4ff2 | 1 4ff2 (0)\n005 0 | 0\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ip":"0.0.0.0","listenAddr":"","enode":"enode://e24f63d4515d5d1e8e85f06afde4da3144258f7569d2a0b007aecc13c9cb17a8ad75d85e30a1bb7bfee7b81a219b58e969787f11710c82d0904568a60cc2fe5d@0.0.0.0:0","name":"node20","id":"e24f63d4515d5d1e8e85f06afde4da3144258f7569d2a0b007aecc13c9cb17a8ad75d85e30a1bb7bfee7b81a219b58e969787f11710c82d0904568a60cc2fe5d"},"up":true,"config":{"name":"node20","id":"e24f63d4515d5d1e8e85f06afde4da3144258f7569d2a0b007aecc13c9cb17a8ad75d85e30a1bb7bfee7b81a219b58e969787f11710c82d0904568a60cc2fe5d","services":["pss","bzz"],"private_key":"b2732f7493e1101eb17248f6a6d83b5811c49cfc13f1aa41a624d1bb3e85368f"}}},{"node":{"config":{"id":"8eea2dd2475d894484f737bb61fa632585ab0a82e47c070327eb65de8b5cf76ad6bbebba1b94b5fe19f6c631e429d1273740937da9ec6cabbcdfd5bd176cc362","name":"node21","services":["pss","bzz"],"private_key":"b573a79bddda3cee3997d5c1210e33810dfce4f43a9a47d3f41ad02352d0515e"},"info":{"enode":"enode://8eea2dd2475d894484f737bb61fa632585ab0a82e47c070327eb65de8b5cf76ad6bbebba1b94b5fe19f6c631e429d1273740937da9ec6cabbcdfd5bd176cc362@0.0.0.0:0","listenAddr":"","ip":"0.0.0.0","protocols":{"bzz":"30W+/tR+7DJIzjtV6cxW+NcY/BPcsaA3Vc3AzaieTcs=","hive":"\n=========================================================================\nFri Sep 29 20:17:10 UTC 2017 KΛÐΞMLIΛ hive: queen's address: df45be\npopulation: 16 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 461c | 28 113d (0) 1102 (0) 1f17 (0) 0b45 (0)\n001 4 9e38 b45f a416 aa65 | 19 80d0 (0) 85d6 (0) 88b4 (0) 8c5f (0)\n002 2 f051 eebe | 7 f3a5 (0) f051 (0) eebe (0) e752 (0)\n============ DEPTH: 3 ==========================================\n003 8 c0d6 c85b cab4 cc70 | 8 c0d6 (0) cab4 (0) c85b (0) cc70 (0)\n004 1 d79a | 1 d79a (0)\n005 0 | 0\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"discovery":0,"listener":0},"id":"8eea2dd2475d894484f737bb61fa632585ab0a82e47c070327eb65de8b5cf76ad6bbebba1b94b5fe19f6c631e429d1273740937da9ec6cabbcdfd5bd176cc362","name":"node21"},"up":true}},{"node":{"up":true,"info":{"protocols":{"bzz":"qmVbSLIl1pIYSiGi9xYpUIUakU+JZxzBrz6Hohs3xeM=","hive":"\n=========================================================================\nFri Sep 29 20:17:10 UTC 2017 KΛÐΞMLIΛ hive: queen's address: aa655b\npopulation: 9 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 6b33 | 28 113d (0) 1102 (0) 1f17 (0) 0b45 (0)\n001 1 df45 | 17 f3a5 (0) f051 (0) eebe (0) e752 (0)\n002 2 9e38 80d0 | 9 80d0 (0) 85d6 (0) 88b4 (0) 8c5f (0)\n003 2 b523 b45f | 6 b2a2 (0) b04c (0) b45f (0) b523 (0)\n============ DEPTH: 4 ==========================================\n004 2 a416 a365 | 2 a416 (0) a365 (0)\n005 0 | 0\n006 0 | 0\n007 1 ab1c | 1 ab1c (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"enode":"enode://ba5b2e12f30e2819c19f9336b13b84145af8dc91197840f49c6dc9a8995fbdf37635d5bc42fbc9f59da666df42a3a16e10c02bb0e556e5c9526a74194b23bb96@0.0.0.0:0","listenAddr":"","id":"ba5b2e12f30e2819c19f9336b13b84145af8dc91197840f49c6dc9a8995fbdf37635d5bc42fbc9f59da666df42a3a16e10c02bb0e556e5c9526a74194b23bb96","name":"node22"},"config":{"private_key":"3e8547c0320dad0457a7c6d576c1700ac4af59504cae9178faafcd60c9830e99","services":["pss","bzz"],"id":"ba5b2e12f30e2819c19f9336b13b84145af8dc91197840f49c6dc9a8995fbdf37635d5bc42fbc9f59da666df42a3a16e10c02bb0e556e5c9526a74194b23bb96","name":"node22"}}},{"node":{"info":{"ports":{"discovery":0,"listener":0},"protocols":{"bzz":"azNs//DUMe3OTO4M81/7HlC3pcbhXT2Bb7G7HPZIjyI=","hive":"\n=========================================================================\nFri Sep 29 20:17:10 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 6b336c\npopulation: 9 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 9035 aa65 | 36 d79a (0) df45 (0) c0d6 (0) cab4 (0)\n001 1 113d | 12 113d (0) 1102 (0) 1f17 (0) 0b45 (0)\n002 1 461c | 7 461c (0) 4ff2 (0) 5205 (0) 5a4f (0)\n003 1 7411 | 4 7f41 (0) 7fe4 (0) 71fe (0) 7411 (0)\n004 2 647c 66d5 | 2 647c (0) 66d5 (0)\n============ DEPTH: 5 ==========================================\n005 1 6d29 | 1 6d29 (0)\n006 0 | 0\n007 1 6a5c | 1 6a5c (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ip":"0.0.0.0","listenAddr":"","enode":"enode://32627f1a91175809b9141af528c4d77407385102a3ed6afee81acb79b0988f91075c670a09203238e266f5ad0d61b9388c9097fe00a54ced8f04423830768768@0.0.0.0:0","name":"node23","id":"32627f1a91175809b9141af528c4d77407385102a3ed6afee81acb79b0988f91075c670a09203238e266f5ad0d61b9388c9097fe00a54ced8f04423830768768"},"up":true,"config":{"private_key":"dcee5e2db10836dcd5e3bbe14845a6203eebb791ae82200732e6b21d453e0642","name":"node23","id":"32627f1a91175809b9141af528c4d77407385102a3ed6afee81acb79b0988f91075c670a09203238e266f5ad0d61b9388c9097fe00a54ced8f04423830768768","services":["pss","bzz"]}}},{"node":{"config":{"services":["pss","bzz"],"id":"08f640d4494b0db8b99e7f7a7b3a1d267f457d5c42ea8002d2a509fee7f06fda7e115e270f43372ebc836748aa3456b8d47783064655b38314731f0ee1d8fac1","name":"node24","private_key":"e895b2d5bfbd538d231463563cec8889c8aef0fbeb77acfd3ab9bb75504d39cd"},"info":{"listenAddr":"","enode":"enode://08f640d4494b0db8b99e7f7a7b3a1d267f457d5c42ea8002d2a509fee7f06fda7e115e270f43372ebc836748aa3456b8d47783064655b38314731f0ee1d8fac1@0.0.0.0:0","protocols":{"hive":"\n=========================================================================\nFri Sep 29 20:17:10 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 903561\npopulation: 11 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 5205 6b33 | 28 113d (0) 1102 (0) 1f17 (0) 0b45 (0)\n001 1 e046 | 17 d79a (0) df45 (0) c0d6 (0) cab4 (0)\n002 1 a416 | 10 a416 (0) a365 (0) aa65 (0) ab1c (0)\n003 3 88b4 85d6 80d0 | 4 80d0 (0) 85d6 (0) 88b4 (0) 8c5f (0)\n============ DEPTH: 4 ==========================================\n004 3 9e38 9e94 9bb1 | 3 9e94 (0) 9e38 (0) 9bb1 (0)\n005 0 | 0\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 1 9045 | 1 9045 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"kDVhryRZsORtgYgSHmbYuZmtOTQZROsJnv9wITJEyBM="},"ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"id":"08f640d4494b0db8b99e7f7a7b3a1d267f457d5c42ea8002d2a509fee7f06fda7e115e270f43372ebc836748aa3456b8d47783064655b38314731f0ee1d8fac1","name":"node24"},"up":true}},{"node":{"config":{"private_key":"199b03688e42fbdcdd00b6230f59bf7a0b6ac22f6088c7d398535121f867b30a","services":["pss","bzz"],"id":"e777565409c3fa228f25352f28004671b6f9451fe21666263e71d67d18cf7890f3015af4717267bcd736322239aae34ba0f596e8e98d1628a539cef3a521ed7d","name":"node25"},"info":{"id":"e777565409c3fa228f25352f28004671b6f9451fe21666263e71d67d18cf7890f3015af4717267bcd736322239aae34ba0f596e8e98d1628a539cef3a521ed7d","name":"node25","ip":"0.0.0.0","protocols":{"bzz":"4EY8h7C33u+9UhchQw4P0kaDqotBxl8lnWeNmES9gA8=","hive":"\n=========================================================================\nFri Sep 29 20:17:10 UTC 2017 KΛÐΞMLIΛ hive: queen's address: e0463c\npopulation: 9 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 292b | 28 2597 (0) 2218 (0) 292b (0) 34ad (0)\n001 1 9035 | 19 a416 (0) a365 (0) aa65 (0) ab1c (0)\n002 1 c0d6 | 10 d79a (0) df45 (0) cab4 (0) c85b (0)\n003 2 f3a5 f051 | 2 f3a5 (0) f051 (0)\n004 1 eebe | 1 eebe (0)\n============ DEPTH: 5 ==========================================\n005 2 e45d e752 | 2 e752 (0) e45d (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 1 e020 | 1 e020 (0)\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"listener":0,"discovery":0},"listenAddr":"","enode":"enode://e777565409c3fa228f25352f28004671b6f9451fe21666263e71d67d18cf7890f3015af4717267bcd736322239aae34ba0f596e8e98d1628a539cef3a521ed7d@0.0.0.0:0"},"up":true}},{"node":{"config":{"name":"node26","id":"df4e07354dd593b1986e996f84c3e97147f72f4c6367ec876472c7384fe2d850ee6a8abeb37b789e7c50c12aa3533f19a6c7d9c37bb1b884c61eee307488ed88","services":["pss","bzz"],"private_key":"04a50f62b3bd30de9b6a4ca7c72d0fe81f6c111ab99bbbf4bb9c21b6c8983639"},"up":true,"info":{"name":"node26","id":"df4e07354dd593b1986e996f84c3e97147f72f4c6367ec876472c7384fe2d850ee6a8abeb37b789e7c50c12aa3533f19a6c7d9c37bb1b884c61eee307488ed88","ports":{"listener":0,"discovery":0},"ip":"0.0.0.0","protocols":{"hive":"\n=========================================================================\nFri Sep 29 20:17:10 UTC 2017 KΛÐΞMLIΛ hive: queen's address: c0d6b4\npopulation: 14 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 2218 | 28 2218 (0) 2597 (0) 292b (0) 34ad (0)\n001 2 88b4 85d6 | 19 a416 (0) a365 (0) aa65 (0) ab1c (0)\n002 2 e020 e046 | 7 f3a5 (0) f051 (0) eebe (0) e752 (0)\n003 2 df45 d79a | 2 d79a (0) df45 (0)\n============ DEPTH: 4 ==========================================\n004 7 c85b cab4 cc70 cec7 | 7 cab4 (0) c85b (0) cc70 (0) cee0 (0)\n005 0 | 0\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"wNa0lQdxiI6XcAUdNB8gcf7NsJ4owoniUWaDJ+uMz2Y="},"enode":"enode://df4e07354dd593b1986e996f84c3e97147f72f4c6367ec876472c7384fe2d850ee6a8abeb37b789e7c50c12aa3533f19a6c7d9c37bb1b884c61eee307488ed88@0.0.0.0:0","listenAddr":""}}},{"node":{"config":{"id":"20fcc315548210e104fb0bd5deb4c5af2d78a075a3441015e7e27f8c711a5d6055d8c01692502ca4648f82704424c25a7252e3505657e25dd30c1096e16fcccf","name":"node27","services":["pss","bzz"],"private_key":"dee1658338c1840984753b1121833d17232db7a62a8ed1b4fc1268e99138385e"},"up":true,"info":{"enode":"enode://20fcc315548210e104fb0bd5deb4c5af2d78a075a3441015e7e27f8c711a5d6055d8c01692502ca4648f82704424c25a7252e3505657e25dd30c1096e16fcccf@0.0.0.0:0","listenAddr":"","protocols":{"hive":"\n=========================================================================\nFri Sep 29 20:17:10 UTC 2017 KΛÐΞMLIΛ hive: queen's address: cfc872\npopulation: 12 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 2597 | 28 2218 (0) 2597 (0) 292b (0) 34ad (0)\n001 1 a416 | 19 a416 (0) a365 (0) aa65 (0) ab1c (0)\n002 1 f3a5 | 7 f3a5 (0) f051 (0) eebe (0) e45d (0)\n003 2 d79a df45 | 2 d79a (0) df45 (0)\n004 1 c0d6 | 1 c0d6 (0)\n005 2 cab4 c85b | 2 cab4 (0) c85b (0)\n006 1 cc70 | 1 cc70 (0)\n============ DEPTH: 7 ==========================================\n007 2 cee0 cec7 | 2 cee0 (0) cec7 (0)\n008 1 cf69 | 1 cf69 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"z8hy/n8hP0raXsQTA3RQrisUEVfIOZi5UgrC3bUXB70="},"ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"id":"20fcc315548210e104fb0bd5deb4c5af2d78a075a3441015e7e27f8c711a5d6055d8c01692502ca4648f82704424c25a7252e3505657e25dd30c1096e16fcccf","name":"node27"}}},{"node":{"config":{"name":"node28","id":"70af807b8e945627dae8a77496db558a2d1581eb89b15f25d2b4881679e5895c12955fd61558a554f5efb989e8940a2fb5eab2aca46de46ba1f059fe58c43311","services":["pss","bzz"],"private_key":"9fa3a527ec0ce68f936c2dadcc080238cfd5a3a462c20462567976eaf1d52810"},"up":true,"info":{"id":"70af807b8e945627dae8a77496db558a2d1581eb89b15f25d2b4881679e5895c12955fd61558a554f5efb989e8940a2fb5eab2aca46de46ba1f059fe58c43311","name":"node28","protocols":{"hive":"\n=========================================================================\nFri Sep 29 20:17:10 UTC 2017 KΛÐΞMLIΛ hive: queen's address: cec77f\npopulation: 13 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 6d29 | 28 2218 (0) 2597 (0) 292b (0) 34ad (0)\n001 2 ab1c a365 | 19 a416 (0) a365 (0) aa65 (0) ab1c (0)\n002 1 f3a5 | 7 f3a5 (0) f051 (0) eebe (0) e752 (0)\n003 2 d79a df45 | 2 d79a (0) df45 (0)\n004 1 c0d6 | 1 c0d6 (0)\n005 2 cab4 c85b | 2 cab4 (0) c85b (0)\n006 1 cc70 | 1 cc70 (0)\n============ DEPTH: 7 ==========================================\n007 2 cf69 cfc8 | 2 cf69 (0) cfc8 (0)\n008 0 | 0\n009 0 | 0\n010 1 cee0 | 1 cee0 (0)\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"zsd/GINR0k1QZ94uDMV7SKmlRV14vaa3Yy0UpnkHDD0="},"ip":"0.0.0.0","ports":{"listener":0,"discovery":0},"listenAddr":"","enode":"enode://70af807b8e945627dae8a77496db558a2d1581eb89b15f25d2b4881679e5895c12955fd61558a554f5efb989e8940a2fb5eab2aca46de46ba1f059fe58c43311@0.0.0.0:0"}}},{"node":{"config":{"id":"eb4bab9ad390760b3eece117dbec9792aa56485cd4a6824094337f83463efbe0174b73aba386da238f7b1724aef4cb6a3017cf35999ca591a1e56b67b1ecc250","name":"node29","services":["pss","bzz"],"private_key":"26df6d28e33e4da3390df260d9bbad739c31cc494a632239633485872b1ead29"},"up":true,"info":{"listenAddr":"","enode":"enode://eb4bab9ad390760b3eece117dbec9792aa56485cd4a6824094337f83463efbe0174b73aba386da238f7b1724aef4cb6a3017cf35999ca591a1e56b67b1ecc250@0.0.0.0:0","ports":{"listener":0,"discovery":0},"protocols":{"hive":"\n=========================================================================\nFri Sep 29 20:17:10 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 6d29db\npopulation: 11 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 cec7 | 36 f3a5 (0) f051 (0) eebe (0) e752 (0)\n001 3 1f17 2218 292b | 12 113d (0) 1102 (0) 1f17 (0) 0b45 (0)\n002 2 5a4f 461c | 7 461c (0) 4ff2 (0) 5205 (0) 5c19 (0)\n003 1 71fe | 4 7f41 (0) 7fe4 (0) 7411 (0) 71fe (0)\n004 2 647c 66d5 | 2 647c (0) 66d5 (0)\n============ DEPTH: 5 ==========================================\n005 2 6b33 6a5c | 2 6b33 (0) 6a5c (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"bSnb7ZkvDwAIpyl4BF3wikrhdTVx/e+7Z29Stf+ENDM="},"ip":"0.0.0.0","name":"node29","id":"eb4bab9ad390760b3eece117dbec9792aa56485cd4a6824094337f83463efbe0174b73aba386da238f7b1724aef4cb6a3017cf35999ca591a1e56b67b1ecc250"}}},{"node":{"config":{"services":["pss","bzz"],"id":"ec96e314abe60637723a8242b6afeed45ff1a8faca649f8dc7f175ed9db4118bc6d406f5d26d3d71e54699a97b7da59a3d8fb934501b60c15bd5e0501f8fe792","name":"node30","private_key":"d7549640c8223b3b3e55195e3b519a85b7af1f1fc26ebbd56c9117a639544593"},"info":{"ports":{"discovery":0,"listener":0},"ip":"0.0.0.0","protocols":{"bzz":"KSu3WlQH3aKte2QrG3kCZOfOFrvYzSLlEu7sPWAOpSA=","hive":"\n=========================================================================\nFri Sep 29 20:17:10 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 292bb7\npopulation: 9 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 e046 9e94 | 36 f3a5 (0) f051 (0) eebe (0) e752 (0)\n001 1 6d29 | 16 461c (0) 4ff2 (0) 5205 (0) 5c19 (0)\n002 1 113d | 6 113d (0) 1102 (0) 1f17 (0) 0b45 (0)\n003 3 34ad 39e7 3bc8 | 3 34ad (0) 39e7 (0) 3bc8 (0)\n============ DEPTH: 4 ==========================================\n004 2 2218 2597 | 2 2218 (0) 2597 (0)\n005 0 | 0\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"listenAddr":"","enode":"enode://ec96e314abe60637723a8242b6afeed45ff1a8faca649f8dc7f175ed9db4118bc6d406f5d26d3d71e54699a97b7da59a3d8fb934501b60c15bd5e0501f8fe792@0.0.0.0:0","name":"node30","id":"ec96e314abe60637723a8242b6afeed45ff1a8faca649f8dc7f175ed9db4118bc6d406f5d26d3d71e54699a97b7da59a3d8fb934501b60c15bd5e0501f8fe792"},"up":true}},{"node":{"up":true,"info":{"name":"node31","id":"78739942ae915ea9447fbc435162fc63f18a6f54a1473fd4aa2ed2391a5d62ffa8e32e0aaaa2b83022bd1ff15210daea42433e944235c95a681fac54f75da5de","enode":"enode://78739942ae915ea9447fbc435162fc63f18a6f54a1473fd4aa2ed2391a5d62ffa8e32e0aaaa2b83022bd1ff15210daea42433e944235c95a681fac54f75da5de@0.0.0.0:0","listenAddr":"","ports":{"discovery":0,"listener":0},"protocols":{"hive":"\n=========================================================================\nFri Sep 29 20:17:10 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 9e9451\npopulation: 8 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 292b | 28 461c (0) 4ff2 (0) 5205 (0) 5c19 (0)\n001 1 cab4 | 17 f3a5 (0) f051 (0) eebe (0) e752 (0)\n002 1 a416 | 10 a416 (0) a365 (0) aa65 (0) ab1c (0)\n003 1 80d0 | 4 80d0 (0) 85d6 (0) 88b4 (0) 8c5f (0)\n004 2 9045 9035 | 2 9045 (0) 9035 (0)\n============ DEPTH: 5 ==========================================\n005 1 9bb1 | 1 9bb1 (0)\n006 0 | 0\n007 0 | 0\n008 1 9e38 | 1 9e38 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"npRRy4TsEIgeFqh9hLDk4ap49em8ScpSRKPaQUtSENo="},"ip":"0.0.0.0"},"config":{"private_key":"16ea03e396aba3e56e9e2d89e53b68e46e51408b090fe2b99e65591ae6cd02c0","id":"78739942ae915ea9447fbc435162fc63f18a6f54a1473fd4aa2ed2391a5d62ffa8e32e0aaaa2b83022bd1ff15210daea42433e944235c95a681fac54f75da5de","name":"node31","services":["pss","bzz"]}}},{"node":{"config":{"private_key":"2f111d17fef6870e109950bfd76e7e6db0913a06d14f8f5a311a39f447e65aea","id":"a93e19158ae6a4261186b663bf109258d759e42b8e0e1d5c06e79a9b6844e6acb41c0a4ce38dfdf250d6016aa796fb78807a7f91738f4eef8a36dafdd60afec7","name":"node32","services":["pss","bzz"]},"info":{"id":"a93e19158ae6a4261186b663bf109258d759e42b8e0e1d5c06e79a9b6844e6acb41c0a4ce38dfdf250d6016aa796fb78807a7f91738f4eef8a36dafdd60afec7","name":"node32","listenAddr":"","enode":"enode://a93e19158ae6a4261186b663bf109258d759e42b8e0e1d5c06e79a9b6844e6acb41c0a4ce38dfdf250d6016aa796fb78807a7f91738f4eef8a36dafdd60afec7@0.0.0.0:0","ip":"0.0.0.0","protocols":{"hive":"\n=========================================================================\nFri Sep 29 20:17:10 UTC 2017 KΛÐΞMLIΛ hive: queen's address: cab41b\npopulation: 14 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 113d 1102 | 28 113d (0) 1102 (0) 1f17 (0) 0b45 (0)\n001 2 9e94 b2a2 | 19 80d0 (0) 85d6 (0) 88b4 (0) 8c5f (0)\n002 1 f3a5 | 7 f3a5 (0) f051 (0) eebe (0) e752 (0)\n003 2 d79a df45 | 2 d79a (0) df45 (0)\n004 1 c0d6 | 1 c0d6 (0)\n============ DEPTH: 5 ==========================================\n005 5 cc70 cfc8 cf69 cee0 | 5 cc70 (0) cf69 (0) cfc8 (0) cee0 (0)\n006 1 c85b | 1 c85b (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"yrQbRCKWgvEdaso9MTZZdSTp604WQBR7h/P4xyJ5WfE="},"ports":{"discovery":0,"listener":0}},"up":true}},{"node":{"up":true,"info":{"enode":"enode://c581746c5ea238a632de0b30da06de317dc9f613cc9bb16c41509e5d1381b041f2d2e6a65018667bb6b57868577ff04a2773a451dd03b6b599bff5d8cbd4017a@0.0.0.0:0","listenAddr":"","protocols":{"hive":"\n=========================================================================\nFri Sep 29 20:17:10 UTC 2017 KΛÐΞMLIΛ hive: queen's address: b2a236\npopulation: 13 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 71fe | 28 113d (0) 1102 (0) 1f17 (0) 0b45 (0)\n001 3 e752 cc70 cab4 | 17 f3a5 (0) f051 (0) eebe (0) e752 (0)\n002 1 80d0 | 9 80d0 (0) 85d6 (0) 88b4 (0) 8c5f (0)\n003 3 ab1c a416 a365 | 4 a416 (0) a365 (0) aa65 (0) ab1c (0)\n004 2 bd5b bece | 2 bd5b (0) bece (0)\n============ DEPTH: 5 ==========================================\n005 2 b45f b523 | 2 b45f (0) b523 (0)\n006 1 b04c | 1 b04c (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"sqI2oqz1z2dcUho+h++EeTPhc2wiClTPZttLoD82lIM="},"ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"id":"c581746c5ea238a632de0b30da06de317dc9f613cc9bb16c41509e5d1381b041f2d2e6a65018667bb6b57868577ff04a2773a451dd03b6b599bff5d8cbd4017a","name":"node33"},"config":{"services":["pss","bzz"],"name":"node33","id":"c581746c5ea238a632de0b30da06de317dc9f613cc9bb16c41509e5d1381b041f2d2e6a65018667bb6b57868577ff04a2773a451dd03b6b599bff5d8cbd4017a","private_key":"b20e729862ae141e3134c9eb2ed703957c0fd006f041df213946d66bfe06a3a7"}}},{"node":{"config":{"services":["pss","bzz"],"name":"node34","id":"5732476eb1c7b5ab050759a7169281e6ff583df6de07c2019fb105dfad4df268587b87baf6e0d210f77b048bd62b501b713a919964f35b862b403b478d88a1b6","private_key":"d35682e43d6382cb9508e5479fc2d09bec82166746bd406cc249f655715ae986"},"up":true,"info":{"enode":"enode://5732476eb1c7b5ab050759a7169281e6ff583df6de07c2019fb105dfad4df268587b87baf6e0d210f77b048bd62b501b713a919964f35b862b403b478d88a1b6@0.0.0.0:0","listenAddr":"","ip":"0.0.0.0","protocols":{"bzz":"cf4PIl7iMQbLbWxXzetJ7MT/srE0QZVuym2UUFqipyw=","hive":"\n=========================================================================\nFri Sep 29 20:17:10 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 71fe0f\npopulation: 12 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 b2a2 a365 | 36 f3a5 (0) f051 (0) eebe (0) e752 (0)\n001 2 1102 113d | 12 113d (0) 1102 (0) 1f17 (0) 0b45 (0)\n002 2 461c 5205 | 7 461c (0) 4ff2 (0) 5205 (0) 5c19 (0)\n003 3 66d5 6a5c 6d29 | 5 6d29 (0) 6b33 (0) 6a5c (0) 66d5 (0)\n============ DEPTH: 4 ==========================================\n004 2 7fe4 7f41 | 2 7f41 (0) 7fe4 (0)\n005 1 7411 | 1 7411 (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"listener":0,"discovery":0},"id":"5732476eb1c7b5ab050759a7169281e6ff583df6de07c2019fb105dfad4df268587b87baf6e0d210f77b048bd62b501b713a919964f35b862b403b478d88a1b6","name":"node34"}}},{"node":{"up":true,"info":{"name":"node35","id":"4367ed557fe94e971003fe0a3236c6bd619e232117818a35f394995ef9782b930279344042dc165069780e8457106299679af6f61c1482d54f31fd19d4f9dd88","ports":{"listener":0,"discovery":0},"protocols":{"hive":"\n=========================================================================\nFri Sep 29 20:17:10 UTC 2017 KΛÐΞMLIΛ hive: queen's address: a365bf\npopulation: 11 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 5a4f 71fe | 28 34ad (0) 39e7 (0) 3bc8 (0) 2218 (0)\n001 2 cec7 e45d | 17 f3a5 (0) f051 (0) eebe (0) e752 (0)\n002 2 8c5f 80d0 | 9 80d0 (0) 85d6 (0) 8c5f (0) 88b4 (0)\n003 2 bd5b b2a2 | 6 bd5b (0) bece (0) b45f (0) b523 (0)\n============ DEPTH: 4 ==========================================\n004 2 aa65 ab1c | 2 aa65 (0) ab1c (0)\n005 1 a416 | 1 a416 (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"o2W/Qn3BCUKWVwM/S3siV1tqjZVdbq9EKIcl5eR7CoY="},"ip":"0.0.0.0","listenAddr":"","enode":"enode://4367ed557fe94e971003fe0a3236c6bd619e232117818a35f394995ef9782b930279344042dc165069780e8457106299679af6f61c1482d54f31fd19d4f9dd88@0.0.0.0:0"},"config":{"services":["pss","bzz"],"name":"node35","id":"4367ed557fe94e971003fe0a3236c6bd619e232117818a35f394995ef9782b930279344042dc165069780e8457106299679af6f61c1482d54f31fd19d4f9dd88","private_key":"9d7b2568317659ec35ed53c64f5c1aa0813dde36f1f492139ffefdd91ae0717e"}}},{"node":{"info":{"ip":"0.0.0.0","protocols":{"bzz":"Wk+k9Egtuve75sPSrijDUYf70PANEpO+QXGaqOXko4g=","hive":"\n=========================================================================\nFri Sep 29 20:17:10 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 5a4fa4\npopulation: 10 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 bece a365 | 36 f3a5 (0) f051 (0) eebe (0) e752 (0)\n001 1 34ad | 12 34ad (0) 39e7 (0) 3bc8 (0) 2218 (0)\n002 1 6d29 | 9 6d29 (0) 6b33 (0) 6a5c (0) 66d5 (0)\n003 2 461c 4ff2 | 2 461c (0) 4ff2 (0)\n004 1 5205 | 1 5205 (0)\n============ DEPTH: 5 ==========================================\n005 3 5c19 5e64 5fd6 | 3 5c19 (0) 5e64 (0) 5fd6 (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"discovery":0,"listener":0},"enode":"enode://0d502ca2f60cadbf375c195365090b216ac99af07abb3a35d3f3dbdc4de7eb2a8f93a3f2a240fc5905dca74e78a05a5837484a117477fb279052889c52b99c6c@0.0.0.0:0","listenAddr":"","id":"0d502ca2f60cadbf375c195365090b216ac99af07abb3a35d3f3dbdc4de7eb2a8f93a3f2a240fc5905dca74e78a05a5837484a117477fb279052889c52b99c6c","name":"node36"},"up":true,"config":{"services":["pss","bzz"],"id":"0d502ca2f60cadbf375c195365090b216ac99af07abb3a35d3f3dbdc4de7eb2a8f93a3f2a240fc5905dca74e78a05a5837484a117477fb279052889c52b99c6c","name":"node36","private_key":"1177e7fa4a1e785fc30996682cf9ecd265d86943f65d7e3cf4c25cefcd861479"}}},{"node":{"info":{"enode":"enode://8b3023625eecf7dd330df127a31454cea24354d099ca621af1a1232e5b59961ceafbd9f7e0f658905d80617f7efbc4038d84fb6e3cc9347a1f4f1775fff46965@0.0.0.0:0","listenAddr":"","protocols":{"bzz":"vs5Nmfr9zr0i8DpGQAJsVfcVX/gUspWirsepjTlzWVo=","hive":"\n=========================================================================\nFri Sep 29 20:17:10 UTC 2017 KΛÐΞMLIΛ hive: queen's address: bece4d\npopulation: 9 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 5a4f | 28 34ad (0) 39e7 (0) 3bc8 (0) 2218 (0)\n001 1 f3a5 | 17 f3a5 (0) f051 (0) eebe (0) e752 (0)\n002 1 80d0 | 9 80d0 (0) 85d6 (0) 8c5f (0) 88b4 (0)\n003 1 a416 | 4 a416 (0) a365 (0) aa65 (0) ab1c (0)\n============ DEPTH: 4 ==========================================\n004 4 b45f b523 b2a2 b04c | 4 b45f (0) b523 (0) b2a2 (0) b04c (0)\n005 0 | 0\n006 1 bd5b | 1 bd5b (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ip":"0.0.0.0","ports":{"listener":0,"discovery":0},"id":"8b3023625eecf7dd330df127a31454cea24354d099ca621af1a1232e5b59961ceafbd9f7e0f658905d80617f7efbc4038d84fb6e3cc9347a1f4f1775fff46965","name":"node37"},"up":true,"config":{"private_key":"29e2a9ddf2c5b8914fcf8d3782d464b0be6252d589b2a7daa1ea6b93b205c4f4","id":"8b3023625eecf7dd330df127a31454cea24354d099ca621af1a1232e5b59961ceafbd9f7e0f658905d80617f7efbc4038d84fb6e3cc9347a1f4f1775fff46965","name":"node37","services":["pss","bzz"]}}},{"node":{"config":{"id":"aee9aaece9a50dd4e85d79f1286165181251ebbbffe461e87e98e04ee5a4730b3d31ff6ed63fe403c1ecff165cbe1cf7d791f4a6fd16685726c290344ed65406","name":"node38","services":["pss","bzz"],"private_key":"de7a36b57175c1b9dd9686884f73048ea29215a01fdee9f2cf5068218efdc9d6"},"up":true,"info":{"enode":"enode://aee9aaece9a50dd4e85d79f1286165181251ebbbffe461e87e98e04ee5a4730b3d31ff6ed63fe403c1ecff165cbe1cf7d791f4a6fd16685726c290344ed65406@0.0.0.0:0","listenAddr":"","ip":"0.0.0.0","protocols":{"hive":"\n=========================================================================\nFri Sep 29 20:17:10 UTC 2017 KΛÐΞMLIΛ hive: queen's address: b04c7f\npopulation: 10 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 6a5c | 28 34ad (0) 39e7 (0) 3bc8 (0) 2218 (0)\n001 2 cc70 f3a5 | 17 f3a5 (0) f051 (0) eebe (0) e45d (0)\n002 1 85d6 | 9 85d6 (0) 80d0 (0) 8c5f (0) 88b4 (0)\n003 1 a416 | 4 a416 (0) a365 (0) aa65 (0) ab1c (0)\n004 2 bd5b bece | 2 bd5b (0) bece (0)\n============ DEPTH: 5 ==========================================\n005 2 b45f b523 | 2 b45f (0) b523 (0)\n006 1 b2a2 | 1 b2a2 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"sEx/kHaRrFGtq2/mV91FkgRMpCIu5g64bHhRyFUFeo4="},"ports":{"discovery":0,"listener":0},"id":"aee9aaece9a50dd4e85d79f1286165181251ebbbffe461e87e98e04ee5a4730b3d31ff6ed63fe403c1ecff165cbe1cf7d791f4a6fd16685726c290344ed65406","name":"node38"}}},{"node":{"config":{"services":["pss","bzz"],"name":"node39","id":"740371f4438046c4f3cb3e0c47cd1c35df4565addb44dc4a7aa0be864cf43f726dc0616502cd67fd7d88008acf8ba1e3f9ef60aeb2d3de3896dccd8765c2bfb3","private_key":"209fa24e0d0a335e74967ae3ca2914ea6fb1ac99b9495820e9680855fab3081f"},"info":{"listenAddr":"","enode":"enode://740371f4438046c4f3cb3e0c47cd1c35df4565addb44dc4a7aa0be864cf43f726dc0616502cd67fd7d88008acf8ba1e3f9ef60aeb2d3de3896dccd8765c2bfb3@0.0.0.0:0","ports":{"listener":0,"discovery":0},"ip":"0.0.0.0","protocols":{"bzz":"alzWEaWoqUyC1tO0CRKQnzJtQRHIKYPD9xnPo/YhMS8=","hive":"\n=========================================================================\nFri Sep 29 20:17:10 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 6a5cd6\npopulation: 10 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 b04c cee0 | 36 80d0 (0) 85d6 (0) 8c5f (0) 88b4 (0)\n001 1 3bc8 | 12 34ad (0) 39e7 (0) 3bc8 (0) 2218 (0)\n002 1 4ff2 | 7 4ff2 (0) 461c (0) 5205 (0) 5c19 (0)\n003 2 71fe 7fe4 | 4 71fe (0) 7411 (0) 7f41 (0) 7fe4 (0)\n004 2 66d5 647c | 2 66d5 (0) 647c (0)\n============ DEPTH: 5 ==========================================\n005 1 6d29 | 1 6d29 (0)\n006 0 | 0\n007 1 6b33 | 1 6b33 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"name":"node39","id":"740371f4438046c4f3cb3e0c47cd1c35df4565addb44dc4a7aa0be864cf43f726dc0616502cd67fd7d88008acf8ba1e3f9ef60aeb2d3de3896dccd8765c2bfb3"},"up":true}},{"node":{"config":{"services":["pss","bzz"],"name":"node40","id":"2cb9a1452559314b74e4e1956a260ee2ef7bed85215e444968f54148eb7662f76ec8e7e0fe2cb32d9eecde8d4748a1f776dca7c7f121fde1722d0ba514498d11","private_key":"225e538725db916b0e7be129cbda4da08e6be4ccaef64cf870551466d2658834"},"info":{"id":"2cb9a1452559314b74e4e1956a260ee2ef7bed85215e444968f54148eb7662f76ec8e7e0fe2cb32d9eecde8d4748a1f776dca7c7f121fde1722d0ba514498d11","name":"node40","protocols":{"bzz":"zuC3K8sKESyaoz64AWbSecLMAhZ4KhlFSghsAUe4Em0=","hive":"\n=========================================================================\nFri Sep 29 20:17:10 UTC 2017 KΛÐΞMLIΛ hive: queen's address: cee0b7\npopulation: 12 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 6a5c | 28 34ad (0) 39e7 (0) 3bc8 (0) 2218 (0)\n001 1 85d6 | 19 8c5f (0) 88b4 (0) 80d0 (0) 85d6 (0)\n002 1 f3a5 | 7 f3a5 (0) f051 (0) eebe (0) e45d (0)\n003 2 df45 d79a | 2 df45 (0) d79a (0)\n004 1 c0d6 | 1 c0d6 (0)\n005 2 c85b cab4 | 2 cab4 (0) c85b (0)\n006 1 cc70 | 1 cc70 (0)\n============ DEPTH: 7 ==========================================\n007 2 cf69 cfc8 | 2 cf69 (0) cfc8 (0)\n008 0 | 0\n009 0 | 0\n010 1 cec7 | 1 cec7 (0)\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","enode":"enode://2cb9a1452559314b74e4e1956a260ee2ef7bed85215e444968f54148eb7662f76ec8e7e0fe2cb32d9eecde8d4748a1f776dca7c7f121fde1722d0ba514498d11@0.0.0.0:0"},"up":true}},{"node":{"up":true,"info":{"name":"node41","id":"00508d6e28f4b503d346983d740c24c440c6eab33128d86c60cb2ce8c70d17189a96a7e6f212dd25f383d1902d04206784edb7fc8b1c391e4465afcd18192c1c","ports":{"discovery":0,"listener":0},"ip":"0.0.0.0","protocols":{"bzz":"15oebz3A4zgurM3B+w9JzWb0g63cxS12f8EvS2dU4gY=","hive":"\n=========================================================================\nFri Sep 29 20:17:10 UTC 2017 KΛÐΞMLIΛ hive: queen's address: d79a1e\npopulation: 17 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 39e7 | 28 4ff2 (0) 461c (0) 5205 (0) 5c19 (0)\n001 4 b45f ab1c 80d0 8c5f | 19 80d0 (0) 85d6 (0) 88b4 (0) 8c5f (0)\n002 3 f051 e020 e752 | 7 f3a5 (0) f051 (0) eebe (0) e752 (0)\n============ DEPTH: 3 ==========================================\n003 8 c0d6 cab4 c85b cc70 | 8 c0d6 (0) cab4 (0) c85b (0) cc70 (0)\n004 1 df45 | 1 df45 (0)\n005 0 | 0\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"listenAddr":"","enode":"enode://00508d6e28f4b503d346983d740c24c440c6eab33128d86c60cb2ce8c70d17189a96a7e6f212dd25f383d1902d04206784edb7fc8b1c391e4465afcd18192c1c@0.0.0.0:0"},"config":{"id":"00508d6e28f4b503d346983d740c24c440c6eab33128d86c60cb2ce8c70d17189a96a7e6f212dd25f383d1902d04206784edb7fc8b1c391e4465afcd18192c1c","name":"node41","services":["pss","bzz"],"private_key":"1cf5c454ae9746fb367557d4f4a4a9d22157508dd1b19223b4640a3fa9c1dce8"}}},{"node":{"up":true,"info":{"listenAddr":"","enode":"enode://f808e36fd29885cc4f1ad57b26e64deabc0b0fb164ac03017ff2c89671a1ec07706dd28120ceadd8322c6e2387623bc14fa284a0173f70fe722ecc8326f8c932@0.0.0.0:0","ports":{"listener":0,"discovery":0},"protocols":{"hive":"\n=========================================================================\nFri Sep 29 20:17:10 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 39e710\npopulation: 8 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 d79a | 36 80d0 (0) 85d6 (0) 88b4 (0) 8c5f (0)\n001 2 647c 5205 | 16 71fe (0) 7411 (0) 7f41 (0) 7fe4 (0)\n002 2 113d 0b45 | 6 113d (0) 1102 (0) 1f17 (0) 0b45 (0)\n003 1 292b | 3 2597 (0) 2218 (0) 292b (0)\n============ DEPTH: 4 ==========================================\n004 1 34ad | 1 34ad (0)\n005 0 | 0\n006 1 3bc8 | 1 3bc8 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"OecQMn9BdrXtfrySHbWSprkZeyNwKfqrRSWgDRhHDoo="},"ip":"0.0.0.0","name":"node42","id":"f808e36fd29885cc4f1ad57b26e64deabc0b0fb164ac03017ff2c89671a1ec07706dd28120ceadd8322c6e2387623bc14fa284a0173f70fe722ecc8326f8c932"},"config":{"private_key":"e4f81e7a844611f55194d22f62b681f479dadd58596a292cbbf6ef794df1c99a","name":"node42","id":"f808e36fd29885cc4f1ad57b26e64deabc0b0fb164ac03017ff2c89671a1ec07706dd28120ceadd8322c6e2387623bc14fa284a0173f70fe722ecc8326f8c932","services":["pss","bzz"]}}},{"node":{"config":{"private_key":"cfea4812067444b8816b5d70ed03fe5491d28ca6012a871bcb8aebbd100f9489","services":["pss","bzz"],"name":"node43","id":"641004e2e499316f46b8b5e0744a5bfcb24323d44c25ed043d57b18406b71bb4e6053df63eb83488c950ba74ae007bc4d5ae711a891eded4a8ea6aa45fb8312a"},"up":true,"info":{"listenAddr":"","enode":"enode://641004e2e499316f46b8b5e0744a5bfcb24323d44c25ed043d57b18406b71bb4e6053df63eb83488c950ba74ae007bc4d5ae711a891eded4a8ea6aa45fb8312a@0.0.0.0:0","ports":{"discovery":0,"listener":0},"ip":"0.0.0.0","protocols":{"bzz":"UgW70cKYhkBF8I/nzEwkCQVds+5NeQ0lh8nKM2as2Xc=","hive":"\n=========================================================================\nFri Sep 29 20:17:10 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 5205bb\npopulation: 12 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 9045 9035 | 36 9045 (0) 9035 (0) 9bb1 (0) 9e94 (0)\n001 3 0f5c 3bc8 39e7 | 12 113d (0) 1102 (0) 1f17 (0) 0b45 (0)\n002 1 71fe | 9 71fe (0) 7411 (0) 7f41 (0) 7fe4 (0)\n003 2 4ff2 461c | 2 4ff2 (0) 461c (0)\n============ DEPTH: 4 ==========================================\n004 4 5fd6 5e64 5c19 5a4f | 4 5c19 (0) 5e64 (0) 5fd6 (0) 5a4f (0)\n005 0 | 0\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"name":"node43","id":"641004e2e499316f46b8b5e0744a5bfcb24323d44c25ed043d57b18406b71bb4e6053df63eb83488c950ba74ae007bc4d5ae711a891eded4a8ea6aa45fb8312a"}}},{"node":{"config":{"services":["pss","bzz"],"id":"bee0751f64c744ef2862b780ce251b2e21e073b57cec0b57c974b913b92c452aa089f1f66dcf259bdd7ab612bfbca0c8f421a94c564941efd4a1a99c2443fade","name":"node44","private_key":"384043ea1944918b9fac6bbbd88341254533ae49e3b2ce16c1df0941b1118303"},"up":true,"info":{"id":"bee0751f64c744ef2862b780ce251b2e21e073b57cec0b57c974b913b92c452aa089f1f66dcf259bdd7ab612bfbca0c8f421a94c564941efd4a1a99c2443fade","name":"node44","listenAddr":"","enode":"enode://bee0751f64c744ef2862b780ce251b2e21e073b57cec0b57c974b913b92c452aa089f1f66dcf259bdd7ab612bfbca0c8f421a94c564941efd4a1a99c2443fade@0.0.0.0:0","ip":"0.0.0.0","protocols":{"hive":"\n=========================================================================\nFri Sep 29 20:17:10 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 0f5c44\npopulation: 7 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 b523 | 36 df45 (0) d79a (0) c0d6 (0) cab4 (0)\n001 1 5205 | 16 6d29 (0) 6b33 (0) 6a5c (0) 66d5 (0)\n002 1 34ad | 6 34ad (0) 39e7 (0) 3bc8 (0) 2597 (0)\n003 2 1f17 1102 | 3 113d (0) 1102 (0) 1f17 (0)\n004 0 | 0\n============ DEPTH: 5 ==========================================\n005 1 0b45 | 1 0b45 (0)\n006 0 | 0\n007 0 | 0\n008 1 0f98 | 1 0f98 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"D1xEx01MybENKDoAmful+SXDRV9TCNIETDd/ilGBcDo="},"ports":{"listener":0,"discovery":0}}}},{"node":{"info":{"ports":{"listener":0,"discovery":0},"protocols":{"hive":"\n=========================================================================\nFri Sep 29 20:17:10 UTC 2017 KΛÐΞMLIΛ hive: queen's address: b52335\npopulation: 11 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 1f17 0f5c | 28 66d5 (0) 647c (0) 6d29 (0) 6b33 (0)\n001 1 c85b | 17 df45 (0) d79a (0) c0d6 (0) cab4 (0)\n002 2 9bb1 9045 | 9 9035 (0) 9045 (0) 9e94 (0) 9e38 (0)\n003 1 aa65 | 4 aa65 (0) ab1c (0) a365 (0) a416 (0)\n004 2 bece bd5b | 2 bece (0) bd5b (0)\n============ DEPTH: 5 ==========================================\n005 2 b04c b2a2 | 2 b04c (0) b2a2 (0)\n006 0 | 0\n007 1 b45f | 1 b45f (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"tSM137k2dHEgTfuiMbonSBW4WRZOGe6HLiAybQV1uIo="},"ip":"0.0.0.0","enode":"enode://528d9876a41762f88bbe70f95de1b28998844d65449a5eff254b034db3b4925b6ee3b56fa32f012b448a19d5f429ba0892cce3634cedad6cbed0e03914ccc2b5@0.0.0.0:0","listenAddr":"","name":"node45","id":"528d9876a41762f88bbe70f95de1b28998844d65449a5eff254b034db3b4925b6ee3b56fa32f012b448a19d5f429ba0892cce3634cedad6cbed0e03914ccc2b5"},"up":true,"config":{"private_key":"2de5004aa7337bd0819c88121cb0e708bc072c153bf94e274d7e786288996630","services":["pss","bzz"],"name":"node45","id":"528d9876a41762f88bbe70f95de1b28998844d65449a5eff254b034db3b4925b6ee3b56fa32f012b448a19d5f429ba0892cce3634cedad6cbed0e03914ccc2b5"}}},{"node":{"config":{"id":"067835838d850b0a649e0e359329349cb2c599c3301bbc122547847a0273597187f745cd820f743775d6c1c44bf3be7e9bdb470a1defa3aa78f41411773cd371","name":"node46","services":["pss","bzz"],"private_key":"aeb73b9ba035e0d3569e9dd5780dea2994151e2b43cb74e0e297fa285ba3d794"},"up":true,"info":{"name":"node46","id":"067835838d850b0a649e0e359329349cb2c599c3301bbc122547847a0273597187f745cd820f743775d6c1c44bf3be7e9bdb470a1defa3aa78f41411773cd371","listenAddr":"","enode":"enode://067835838d850b0a649e0e359329349cb2c599c3301bbc122547847a0273597187f745cd820f743775d6c1c44bf3be7e9bdb470a1defa3aa78f41411773cd371@0.0.0.0:0","ports":{"listener":0,"discovery":0},"protocols":{"bzz":"HxfJIjmHzPTZaD3wZkzVaBZMadL2K60qee9GNmI7qHo=","hive":"\n=========================================================================\nFri Sep 29 20:17:10 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 1f17c9\npopulation: 7 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 b523 | 36 df45 (0) d79a (0) c0d6 (0) cab4 (0)\n001 1 6d29 | 16 66d5 (0) 647c (0) 6a5c (0) 6b33 (0)\n002 1 34ad | 6 34ad (0) 39e7 (0) 3bc8 (0) 2597 (0)\n003 2 0f5c 0f98 | 3 0b45 (0) 0f5c (0) 0f98 (0)\n============ DEPTH: 4 ==========================================\n004 2 113d 1102 | 2 113d (0) 1102 (0)\n005 0 | 0\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ip":"0.0.0.0"}}},{"node":{"config":{"private_key":"6f192dda3ba98c5d13e94cc2e64ed95478ee64e97b230f224237977bf04cd724","services":["pss","bzz"],"name":"node47","id":"a0a7b4ccd7d2222f59c202373736c03204f38088dcae48afab6e204b663dff0b06df2ceafc808351e45f54effd5c32481df220a938d1c58d49cd31c32bb20d1e"},"info":{"listenAddr":"","enode":"enode://a0a7b4ccd7d2222f59c202373736c03204f38088dcae48afab6e204b663dff0b06df2ceafc808351e45f54effd5c32481df220a938d1c58d49cd31c32bb20d1e@0.0.0.0:0","ports":{"discovery":0,"listener":0},"ip":"0.0.0.0","protocols":{"bzz":"D5iKFw/cd2G42YFKGnrAzA6YSDuRhBBGuZSHg77+7Yg=","hive":"\n=========================================================================\nFri Sep 29 20:17:10 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 0f988a\npopulation: 9 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 cc70 c85b | 36 df45 (0) d79a (0) c0d6 (0) cab4 (0)\n001 1 461c | 16 461c (0) 4ff2 (0) 5205 (0) 5c19 (0)\n002 1 2597 | 6 34ad (0) 39e7 (0) 3bc8 (0) 2597 (0)\n003 3 113d 1102 1f17 | 3 113d (0) 1102 (0) 1f17 (0)\n004 0 | 0\n============ DEPTH: 5 ==========================================\n005 1 0b45 | 1 0b45 (0)\n006 0 | 0\n007 0 | 0\n008 1 0f5c | 1 0f5c (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"name":"node47","id":"a0a7b4ccd7d2222f59c202373736c03204f38088dcae48afab6e204b663dff0b06df2ceafc808351e45f54effd5c32481df220a938d1c58d49cd31c32bb20d1e"},"up":true}},{"node":{"info":{"enode":"enode://93f716fc299e1ef6c7ca4f12f5d81a68d65a07f5c86e7605c6518b8f99d792b8d653583ccf031d3855a8835674c16cff79eeee407ed090e94a58bf7333062d1e@0.0.0.0:0","listenAddr":"","protocols":{"hive":"\n=========================================================================\nFri Sep 29 20:17:10 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 0b45cb\npopulation: 6 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 9e38 | 36 df45 (0) d79a (0) c0d6 (0) cab4 (0)\n001 1 7411 | 16 647c (0) 66d5 (0) 6d29 (0) 6b33 (0)\n002 1 39e7 | 6 34ad (0) 39e7 (0) 3bc8 (0) 2597 (0)\n003 1 1102 | 3 1f17 (0) 113d (0) 1102 (0)\n004 0 | 0\n============ DEPTH: 5 ==========================================\n005 2 0f5c 0f98 | 2 0f5c (0) 0f98 (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"C0XLivePsa96tV0CLtANpmOTt+6ht6Oi+AL/66THndM="},"ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"id":"93f716fc299e1ef6c7ca4f12f5d81a68d65a07f5c86e7605c6518b8f99d792b8d653583ccf031d3855a8835674c16cff79eeee407ed090e94a58bf7333062d1e","name":"node48"},"up":true,"config":{"private_key":"5c3a125bd1eca6243b28fcbd20a0811d7e09ce602ca98ba5f253435d76e0e4a9","services":["pss","bzz"],"id":"93f716fc299e1ef6c7ca4f12f5d81a68d65a07f5c86e7605c6518b8f99d792b8d653583ccf031d3855a8835674c16cff79eeee407ed090e94a58bf7333062d1e","name":"node48"}}},{"node":{"info":{"id":"96d5ac5effb367c45d8329e73de0cb9f7bd4090b1627416fd7b0a28062959ed5e87042c9f1b4bc8653d27d5f9ab3e0bdec8f09a2f2d4a1bcfd69d68234fdfb12","name":"node49","protocols":{"hive":"\n=========================================================================\nFri Sep 29 20:17:10 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 9e384d\npopulation: 9 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 5c19 0b45 | 28 66d5 (0) 647c (0) 6d29 (0) 6b33 (0)\n001 1 df45 | 17 df45 (0) d79a (0) c0d6 (0) cab4 (0)\n002 1 aa65 | 10 aa65 (0) ab1c (0) a365 (0) a416 (0)\n003 1 88b4 | 4 88b4 (0) 8c5f (0) 80d0 (0) 85d6 (0)\n004 2 9045 9035 | 2 9035 (0) 9045 (0)\n============ DEPTH: 5 ==========================================\n005 1 9bb1 | 1 9bb1 (0)\n006 0 | 0\n007 0 | 0\n008 1 9e94 | 1 9e94 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"njhNjm0xkBbCgHiE4LRtpM6fy0Ju+3YiTOQbXU2uVjI="},"ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"listenAddr":"","enode":"enode://96d5ac5effb367c45d8329e73de0cb9f7bd4090b1627416fd7b0a28062959ed5e87042c9f1b4bc8653d27d5f9ab3e0bdec8f09a2f2d4a1bcfd69d68234fdfb12@0.0.0.0:0"},"up":true,"config":{"services":["pss","bzz"],"id":"96d5ac5effb367c45d8329e73de0cb9f7bd4090b1627416fd7b0a28062959ed5e87042c9f1b4bc8653d27d5f9ab3e0bdec8f09a2f2d4a1bcfd69d68234fdfb12","name":"node49","private_key":"e4c7dec3dd327bfaa41b91fb8ccdbb96156d1fe464da973445a35f61e5bc6814"}}},{"node":{"up":true,"info":{"ip":"0.0.0.0","protocols":{"bzz":"XBl+Yjq0DA3iyDpP/RaTDPeR5gNX8WL1sqLoZf8M6nM=","hive":"\n=========================================================================\nFri Sep 29 20:17:10 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 5c197e\npopulation: 10 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 b45f 9e38 | 36 d79a (0) df45 (0) c0d6 (0) cab4 (0)\n001 1 34ad | 12 34ad (0) 39e7 (0) 3bc8 (0) 2218 (0)\n002 1 66d5 | 9 66d5 (0) 647c (0) 6d29 (0) 6b33 (0)\n003 2 4ff2 461c | 2 461c (0) 4ff2 (0)\n004 1 5205 | 1 5205 (0)\n005 1 5a4f | 1 5a4f (0)\n============ DEPTH: 6 ==========================================\n006 2 5e64 5fd6 | 2 5e64 (0) 5fd6 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"discovery":0,"listener":0},"listenAddr":"","enode":"enode://e34e530095c62d56ea231fc2fd30f3099d7ec88212d4bfb0144efb0232b2f7b48ab438fe3c2211f6bb70a0bf89816b590da44d5cfb9ef817f4c04cfbd0ca37a6@0.0.0.0:0","id":"e34e530095c62d56ea231fc2fd30f3099d7ec88212d4bfb0144efb0232b2f7b48ab438fe3c2211f6bb70a0bf89816b590da44d5cfb9ef817f4c04cfbd0ca37a6","name":"node50"},"config":{"id":"e34e530095c62d56ea231fc2fd30f3099d7ec88212d4bfb0144efb0232b2f7b48ab438fe3c2211f6bb70a0bf89816b590da44d5cfb9ef817f4c04cfbd0ca37a6","name":"node50","services":["pss","bzz"],"private_key":"07853d60907494e01f54f879c85c5f3fec6d4d615f9553d12b3da9ea1ad7a4ec"}}},{"node":{"config":{"private_key":"6de081218acdb9ac4c4b8fbf1fde5f2be3c601cbf9104c970de43c2512c5e4c3","services":["pss","bzz"],"id":"bde03ff26a216400b61d07d3eaa865f8b597a52f130ecd44af60d526d4b30c8978cb10c16f4fcbf391ef3a3e5de2aace4c077e9ae6d15451506f370190fbda04","name":"node51"},"up":true,"info":{"ports":{"listener":0,"discovery":0},"ip":"0.0.0.0","protocols":{"hive":"\n=========================================================================\nFri Sep 29 20:17:10 UTC 2017 KΛÐΞMLIΛ hive: queen's address: b45f23\npopulation: 10 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 5c19 | 28 34ad (0) 39e7 (0) 3bc8 (0) 2218 (0)\n001 2 df45 d79a | 17 d79a (0) df45 (0) c0d6 (0) cab4 (0)\n002 1 85d6 | 9 9035 (0) 9045 (0) 9e94 (0) 9e38 (0)\n003 1 aa65 | 4 aa65 (0) ab1c (0) a365 (0) a416 (0)\n004 2 bd5b bece | 2 bece (0) bd5b (0)\n============ DEPTH: 5 ==========================================\n005 2 b2a2 b04c | 2 b04c (0) b2a2 (0)\n006 0 | 0\n007 1 b523 | 1 b523 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"tF8j1qyIJLSA9x8lq/WqLJ20w6kEZg05F2gWhDA1WCc="},"listenAddr":"","enode":"enode://bde03ff26a216400b61d07d3eaa865f8b597a52f130ecd44af60d526d4b30c8978cb10c16f4fcbf391ef3a3e5de2aace4c077e9ae6d15451506f370190fbda04@0.0.0.0:0","name":"node51","id":"bde03ff26a216400b61d07d3eaa865f8b597a52f130ecd44af60d526d4b30c8978cb10c16f4fcbf391ef3a3e5de2aace4c077e9ae6d15451506f370190fbda04"}}},{"node":{"up":true,"info":{"name":"node52","id":"5fd28368ab1f2702060367fbc0aa218a5461a60fa9fb4aa77cf9a65b06980c8802df4ec04392e78a83276a7509acba337fd9d8391fa47b3ea77d3959f5c6a35b","listenAddr":"","enode":"enode://5fd28368ab1f2702060367fbc0aa218a5461a60fa9fb4aa77cf9a65b06980c8802df4ec04392e78a83276a7509acba337fd9d8391fa47b3ea77d3959f5c6a35b@0.0.0.0:0","ports":{"discovery":0,"listener":0},"protocols":{"bzz":"hdZF43OMRB9QhnH1LN4Kp64gMsCCyGt8pq+SWY1xdNU=","hive":"\n=========================================================================\nFri Sep 29 20:17:10 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 85d645\npopulation: 11 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 647c | 28 34ad (0) 39e7 (0) 3bc8 (0) 2218 (0)\n001 3 e020 cee0 c0d6 | 17 df45 (0) d79a (0) c0d6 (0) cab4 (0)\n002 3 bd5b b04c b45f | 10 aa65 (0) ab1c (0) a365 (0) a416 (0)\n003 1 9035 | 5 9035 (0) 9045 (0) 9e94 (0) 9e38 (0)\n============ DEPTH: 4 ==========================================\n004 2 88b4 8c5f | 2 88b4 (0) 8c5f (0)\n005 1 80d0 | 1 80d0 (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ip":"0.0.0.0"},"config":{"private_key":"7b7cb0ca071a27ee059bda50862b7fed343122d2546f5ac5a49dd5b47910530a","name":"node52","id":"5fd28368ab1f2702060367fbc0aa218a5461a60fa9fb4aa77cf9a65b06980c8802df4ec04392e78a83276a7509acba337fd9d8391fa47b3ea77d3959f5c6a35b","services":["pss","bzz"]}}},{"node":{"config":{"name":"node53","id":"2017096c1b5481de69fff5c6a993e2f2014e6f39fd725613cd441ba883356ce1beea333028890bfd277a6e5118e7fd3bc15d7c3e11d9453a8fc9aeccff68306b","services":["pss","bzz"],"private_key":"542108cf09fe9447bb772d25802153811dd504943271556789165c6742636520"},"up":true,"info":{"id":"2017096c1b5481de69fff5c6a993e2f2014e6f39fd725613cd441ba883356ce1beea333028890bfd277a6e5118e7fd3bc15d7c3e11d9453a8fc9aeccff68306b","name":"node53","ip":"0.0.0.0","protocols":{"bzz":"ZHzLJbI6kX9hGkanKxL9RXYQ8HFDFV4fgotB/S0+C1g=","hive":"\n=========================================================================\nFri Sep 29 20:17:10 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 647ccb\npopulation: 9 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 85d6 | 36 df45 (0) d79a (0) c0d6 (0) cab4 (0)\n001 1 39e7 | 12 34ad (0) 39e7 (0) 3bc8 (0) 2218 (0)\n002 1 461c | 7 461c (0) 4ff2 (0) 5205 (0) 5c19 (0)\n003 2 7f41 7fe4 | 4 71fe (0) 7411 (0) 7f41 (0) 7fe4 (0)\n============ DEPTH: 4 ==========================================\n004 3 6d29 6b33 6a5c | 3 6d29 (0) 6b33 (0) 6a5c (0)\n005 0 | 0\n006 1 66d5 | 1 66d5 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"listener":0,"discovery":0},"enode":"enode://2017096c1b5481de69fff5c6a993e2f2014e6f39fd725613cd441ba883356ce1beea333028890bfd277a6e5118e7fd3bc15d7c3e11d9453a8fc9aeccff68306b@0.0.0.0:0","listenAddr":""}}},{"node":{"up":true,"info":{"id":"213a1fdcf601bbda1a8531eb2aefc33daef7d7a2312012e8a781bd4ac732d7c267fdc8ceb45061783e64995ce74e67fc330c6a043bbab3f5f88a0e1e2bb4b48c","name":"node54","protocols":{"hive":"\n=========================================================================\nFri Sep 29 20:17:10 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 7fe487\npopulation: 8 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 88b4 | 36 d79a (0) df45 (0) c0d6 (0) cab4 (0)\n001 1 3bc8 | 12 34ad (0) 39e7 (0) 3bc8 (0) 2597 (0)\n002 1 461c | 7 4ff2 (0) 461c (0) 5205 (0) 5c19 (0)\n003 2 6a5c 647c | 5 6d29 (0) 6b33 (0) 6a5c (0) 66d5 (0)\n============ DEPTH: 4 ==========================================\n004 2 71fe 7411 | 2 71fe (0) 7411 (0)\n005 0 | 0\n006 0 | 0\n007 0 | 0\n008 1 7f41 | 1 7f41 (0)\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"f+SHkBgKs452hwCYRyhfevXnOyG2DPrZ2ES6iy51duQ="},"ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"enode":"enode://213a1fdcf601bbda1a8531eb2aefc33daef7d7a2312012e8a781bd4ac732d7c267fdc8ceb45061783e64995ce74e67fc330c6a043bbab3f5f88a0e1e2bb4b48c@0.0.0.0:0","listenAddr":""},"config":{"private_key":"87ab72e1c606a3b799ef3f34d3aa14549953c570f569a7b7952bb8f460b05a56","id":"213a1fdcf601bbda1a8531eb2aefc33daef7d7a2312012e8a781bd4ac732d7c267fdc8ceb45061783e64995ce74e67fc330c6a043bbab3f5f88a0e1e2bb4b48c","name":"node54","services":["pss","bzz"]}}},{"node":{"config":{"services":["pss","bzz"],"name":"node55","id":"1dd15e2816825bb52419c0f79a13ef9380a2e15fae07d7edae177b334d202c5546d701cebec53b7bc26b97928d5c317fffbe84ed130510f195f9c91b120c93ca","private_key":"a568b1f02f9c9129fd2924f704b8948351325edea81e43132c857be97dc7216d"},"up":true,"info":{"listenAddr":"","enode":"enode://1dd15e2816825bb52419c0f79a13ef9380a2e15fae07d7edae177b334d202c5546d701cebec53b7bc26b97928d5c317fffbe84ed130510f195f9c91b120c93ca@0.0.0.0:0","ports":{"discovery":0,"listener":0},"protocols":{"hive":"\n=========================================================================\nFri Sep 29 20:17:10 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 88b4c3\npopulation: 8 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 7fe4 | 28 34ad (0) 39e7 (0) 3bc8 (0) 2597 (0)\n001 1 c0d6 | 17 d79a (0) df45 (0) c0d6 (0) cab4 (0)\n002 1 ab1c | 10 b2a2 (0) b04c (0) b45f (0) b523 (0)\n003 2 9035 9e38 | 5 9035 (0) 9045 (0) 9e94 (0) 9e38 (0)\n============ DEPTH: 4 ==========================================\n004 2 85d6 80d0 | 2 85d6 (0) 80d0 (0)\n005 1 8c5f | 1 8c5f (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"iLTD1q5qHUw5yu+E1W8wi1jiygR3zFGX8/W+QciQvXw="},"ip":"0.0.0.0","name":"node55","id":"1dd15e2816825bb52419c0f79a13ef9380a2e15fae07d7edae177b334d202c5546d701cebec53b7bc26b97928d5c317fffbe84ed130510f195f9c91b120c93ca"}}},{"node":{"config":{"private_key":"885083158aab574e1ab94645ea978b0e98a06605b1cbbfc48450f46522476b22","services":["pss","bzz"],"name":"node56","id":"1e2f58e271f5f55bf1ec82db59cd6b29b3badae06263ea3bb876a131f1869f9fa9477538887fad30ca623f23d06a952a3f8aca1a581c3ed4faf0ad79b47d42b9"},"up":true,"info":{"ports":{"discovery":0,"listener":0},"protocols":{"bzz":"qxyLv+qUNFduFUZc+9ZujGVlNF2D4kjW/NN0joKAbJU=","hive":"\n=========================================================================\nFri Sep 29 20:17:10 UTC 2017 KΛÐΞMLIΛ hive: queen's address: ab1c8b\npopulation: 9 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 3bc8 | 28 34ad (0) 39e7 (0) 3bc8 (0) 2218 (0)\n001 2 cec7 d79a | 17 df45 (0) d79a (0) c0d6 (0) cab4 (0)\n002 2 80d0 88b4 | 9 9035 (0) 9045 (0) 9e94 (0) 9e38 (0)\n003 1 b2a2 | 6 b2a2 (0) b04c (0) b45f (0) b523 (0)\n============ DEPTH: 4 ==========================================\n004 2 a365 a416 | 2 a365 (0) a416 (0)\n005 0 | 0\n006 0 | 0\n007 1 aa65 | 1 aa65 (0)\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ip":"0.0.0.0","listenAddr":"","enode":"enode://1e2f58e271f5f55bf1ec82db59cd6b29b3badae06263ea3bb876a131f1869f9fa9477538887fad30ca623f23d06a952a3f8aca1a581c3ed4faf0ad79b47d42b9@0.0.0.0:0","name":"node56","id":"1e2f58e271f5f55bf1ec82db59cd6b29b3badae06263ea3bb876a131f1869f9fa9477538887fad30ca623f23d06a952a3f8aca1a581c3ed4faf0ad79b47d42b9"}}},{"node":{"up":true,"info":{"ports":{"listener":0,"discovery":0},"ip":"0.0.0.0","protocols":{"bzz":"gNClQfBB+6tYAWQijQmva+njvuxTAemYOYIxNiKYg14=","hive":"\n=========================================================================\nFri Sep 29 20:17:10 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 80d0a5\npopulation: 14 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 66d5 | 28 34ad (0) 39e7 (0) 3bc8 (0) 2218 (0)\n001 1 d79a | 17 df45 (0) d79a (0) c0d6 (0) cab4 (0)\n002 5 bece b2a2 a365 aa65 | 10 b04c (0) b2a2 (0) b45f (0) b523 (0)\n003 4 9045 9035 9e94 9bb1 | 5 9035 (0) 9045 (0) 9e94 (0) 9e38 (0)\n============ DEPTH: 4 ==========================================\n004 2 88b4 8c5f | 2 88b4 (0) 8c5f (0)\n005 1 85d6 | 1 85d6 (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"listenAddr":"","enode":"enode://4a13668afb8e9fb9db2c4e4e4ff754cbb40c59692c6c5cd70fcba3199ef05c1cf1b19c4fca62396690c90ab7b16f9a18ed375f946a4166137cac349ff3b02933@0.0.0.0:0","name":"node57","id":"4a13668afb8e9fb9db2c4e4e4ff754cbb40c59692c6c5cd70fcba3199ef05c1cf1b19c4fca62396690c90ab7b16f9a18ed375f946a4166137cac349ff3b02933"},"config":{"name":"node57","id":"4a13668afb8e9fb9db2c4e4e4ff754cbb40c59692c6c5cd70fcba3199ef05c1cf1b19c4fca62396690c90ab7b16f9a18ed375f946a4166137cac349ff3b02933","services":["pss","bzz"],"private_key":"5ee85ab61759ce457c89801346b14f68f1f16d6c59b2c034a2aef87242488041"}}},{"node":{"config":{"services":["pss","bzz"],"id":"9af8f0912f664cb4b4515f6b66c432b6d9e8a97f338691517bab0f221718c9ea95ef04243ea7c9573daa5183969b9e9fd4469a58014d88acd0adca3379679cff","name":"node58","private_key":"0bc8227f073c115b1ecd2add3e0ce8f58974528279de040eeaf189abfa6bc506"},"up":true,"info":{"name":"node58","id":"9af8f0912f664cb4b4515f6b66c432b6d9e8a97f338691517bab0f221718c9ea95ef04243ea7c9573daa5183969b9e9fd4469a58014d88acd0adca3379679cff","enode":"enode://9af8f0912f664cb4b4515f6b66c432b6d9e8a97f338691517bab0f221718c9ea95ef04243ea7c9573daa5183969b9e9fd4469a58014d88acd0adca3379679cff@0.0.0.0:0","listenAddr":"","ports":{"discovery":0,"listener":0},"ip":"0.0.0.0","protocols":{"bzz":"ZtWG0vBuCybQUdP+2Um/jzbKO6TGS4IwmHrgx9KcLf0=","hive":"\n=========================================================================\nFri Sep 29 20:17:10 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 66d586\npopulation: 9 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 bd5b 80d0 | 36 df45 (0) d79a (0) c0d6 (0) cab4 (0)\n001 1 34ad | 12 34ad (0) 39e7 (0) 3bc8 (0) 2218 (0)\n002 1 5c19 | 7 4ff2 (0) 461c (0) 5205 (0) 5c19 (0)\n003 1 71fe | 4 71fe (0) 7411 (0) 7f41 (0) 7fe4 (0)\n============ DEPTH: 4 ==========================================\n004 3 6d29 6b33 6a5c | 3 6d29 (0) 6b33 (0) 6a5c (0)\n005 0 | 0\n006 1 647c | 1 647c (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="}}}},{"node":{"info":{"name":"node59","id":"9e67e97b2552fd6c0a82cff57d6144aecc05f751a30bf61438cc545fb5932f9b9c901309a14c7ad868bae0d274b999cec111ec9dfd51d6392db9dc717fa5378c","enode":"enode://9e67e97b2552fd6c0a82cff57d6144aecc05f751a30bf61438cc545fb5932f9b9c901309a14c7ad868bae0d274b999cec111ec9dfd51d6392db9dc717fa5378c@0.0.0.0:0","listenAddr":"","ports":{"discovery":0,"listener":0},"protocols":{"bzz":"vVsR37O/kDxMuM5EdW5B/vtVgt63kFXMxl/ntHsqGkE=","hive":"\n=========================================================================\nFri Sep 29 20:17:10 UTC 2017 KΛÐΞMLIΛ hive: queen's address: bd5b11\npopulation: 9 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 66d5 | 28 34ad (0) 39e7 (0) 3bc8 (0) 2218 (0)\n001 1 eebe | 17 df45 (0) d79a (0) c0d6 (0) cab4 (0)\n002 1 85d6 | 9 85d6 (0) 80d0 (0) 88b4 (0) 8c5f (0)\n003 1 a365 | 4 a365 (0) a416 (0) aa65 (0) ab1c (0)\n============ DEPTH: 4 ==========================================\n004 4 b2a2 b04c b45f b523 | 4 b04c (0) b2a2 (0) b45f (0) b523 (0)\n005 0 | 0\n006 1 bece | 1 bece (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ip":"0.0.0.0"},"up":true,"config":{"private_key":"a548a32f98cf950d6811b01fd764cd17b51d7012b18e944b3bb90dc660e35817","services":["pss","bzz"],"id":"9e67e97b2552fd6c0a82cff57d6144aecc05f751a30bf61438cc545fb5932f9b9c901309a14c7ad868bae0d274b999cec111ec9dfd51d6392db9dc717fa5378c","name":"node59"}}},{"node":{"config":{"private_key":"55c9fd7b7ce7d50376a51050ac0a0a61b4657f9392ad14509bf432758a02b102","services":["pss","bzz"],"name":"node60","id":"ee9e52421dac0a5654edba1892117bb8762de147ef6719a85d627b6af451cddf265f0282af905e72e19c754ffe3c4eb5c37fc56d26dc0873182891a85205552c"},"up":true,"info":{"listenAddr":"","enode":"enode://ee9e52421dac0a5654edba1892117bb8762de147ef6719a85d627b6af451cddf265f0282af905e72e19c754ffe3c4eb5c37fc56d26dc0873182891a85205552c@0.0.0.0:0","ports":{"listener":0,"discovery":0},"protocols":{"bzz":"7r6AgrD277reBi60nyWSUZUkqMPyKXW6kB7ZdVqdDq0=","hive":"\n=========================================================================\nFri Sep 29 20:17:10 UTC 2017 KΛÐΞMLIΛ hive: queen's address: eebe80\npopulation: 9 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 34ad | 28 34ad (0) 39e7 (0) 3bc8 (0) 2597 (0)\n001 1 bd5b | 19 85d6 (0) 80d0 (0) 88b4 (0) 8c5f (0)\n002 1 df45 | 10 df45 (0) d79a (0) c0d6 (0) c85b (0)\n003 2 f3a5 f051 | 2 f3a5 (0) f051 (0)\n============ DEPTH: 4 ==========================================\n004 4 e752 e45d e020 e046 | 4 e046 (0) e020 (0) e752 (0) e45d (0)\n005 0 | 0\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ip":"0.0.0.0","name":"node60","id":"ee9e52421dac0a5654edba1892117bb8762de147ef6719a85d627b6af451cddf265f0282af905e72e19c754ffe3c4eb5c37fc56d26dc0873182891a85205552c"}}},{"node":{"config":{"private_key":"daa4e758bca88df487bb1bcd41e59643256d23f237f96d654010801c07240435","id":"47e3e22c28c4217e3ba4f83ecf3b5767943c3d49c3b829ad510a7412ae868d60f2c9e4cb51e52e6153aa6555eb2cc1ecaae62793119774dbe3a09d8550d9e2d7","name":"node61","services":["pss","bzz"]},"up":true,"info":{"ports":{"discovery":0,"listener":0},"protocols":{"bzz":"8FF/ahGH0PRUqvmFBv3IMOFNMSWfvxlfFpQHjcqlWC8=","hive":"\n=========================================================================\nFri Sep 29 20:17:10 UTC 2017 KΛÐΞMLIΛ hive: queen's address: f0517f\npopulation: 10 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 2597 | 28 4ff2 (0) 461c (0) 5205 (0) 5c19 (0)\n001 1 9bb1 | 19 80d0 (0) 85d6 (0) 88b4 (0) 8c5f (0)\n002 2 df45 d79a | 10 df45 (0) d79a (0) c0d6 (0) c85b (0)\n============ DEPTH: 3 ==========================================\n003 5 e45d e752 e020 e046 | 5 e046 (0) e020 (0) e752 (0) e45d (0)\n004 0 | 0\n005 0 | 0\n006 1 f3a5 | 1 f3a5 (0)\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ip":"0.0.0.0","listenAddr":"","enode":"enode://47e3e22c28c4217e3ba4f83ecf3b5767943c3d49c3b829ad510a7412ae868d60f2c9e4cb51e52e6153aa6555eb2cc1ecaae62793119774dbe3a09d8550d9e2d7@0.0.0.0:0","name":"node61","id":"47e3e22c28c4217e3ba4f83ecf3b5767943c3d49c3b829ad510a7412ae868d60f2c9e4cb51e52e6153aa6555eb2cc1ecaae62793119774dbe3a09d8550d9e2d7"}}},{"node":{"info":{"listenAddr":"","enode":"enode://c8b55e1f0042ff9ac2b73593f79ce125b3b613354ed90a086b18e1f1809c883d0c0e9df6ec080181ef023833cde585de184523483db878aa65c9939a1a1fcf2d@0.0.0.0:0","ip":"0.0.0.0","protocols":{"bzz":"JZdGMhTqD6o9t4H6jLM22lmv9DVT8EWg9wSrEPX1TPI=","hive":"\n=========================================================================\nFri Sep 29 20:17:10 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 259746\npopulation: 8 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 cfc8 f051 8c5f | 36 df45 (0) d79a (0) c0d6 (0) c85b (0)\n001 1 4ff2 | 16 4ff2 (0) 461c (0) 5205 (0) 5c19 (0)\n002 1 0f98 | 6 0b45 (0) 0f5c (0) 0f98 (0) 1f17 (0)\n003 1 3bc8 | 3 34ad (0) 39e7 (0) 3bc8 (0)\n============ DEPTH: 4 ==========================================\n004 1 292b | 1 292b (0)\n005 1 2218 | 1 2218 (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"discovery":0,"listener":0},"id":"c8b55e1f0042ff9ac2b73593f79ce125b3b613354ed90a086b18e1f1809c883d0c0e9df6ec080181ef023833cde585de184523483db878aa65c9939a1a1fcf2d","name":"node62"},"up":true,"config":{"name":"node62","id":"c8b55e1f0042ff9ac2b73593f79ce125b3b613354ed90a086b18e1f1809c883d0c0e9df6ec080181ef023833cde585de184523483db878aa65c9939a1a1fcf2d","services":["pss","bzz"],"private_key":"0090eced227d4fcb0e639349e4164040aa3c9d858531c2df416023c416753a5d"}}},{"node":{"info":{"name":"node63","id":"03e750d46b9a4a9e2047a5b718f427834417f4eb48d8794fde26593a3adbbce48750fa93f47548e342677e94888941ebd492a844a5d8325f67a0db8e94a09b55","enode":"enode://03e750d46b9a4a9e2047a5b718f427834417f4eb48d8794fde26593a3adbbce48750fa93f47548e342677e94888941ebd492a844a5d8325f67a0db8e94a09b55@0.0.0.0:0","listenAddr":"","ports":{"discovery":0,"listener":0},"protocols":{"hive":"\n=========================================================================\nFri Sep 29 20:17:10 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 8c5f07\npopulation: 8 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 2597 4ff2 | 28 0b45 (0) 0f5c (0) 0f98 (0) 1f17 (0)\n001 1 d79a | 17 df45 (0) d79a (0) c0d6 (0) c85b (0)\n002 1 a365 | 10 a365 (0) a416 (0) aa65 (0) ab1c (0)\n003 1 9bb1 | 5 9035 (0) 9045 (0) 9e38 (0) 9e94 (0)\n============ DEPTH: 4 ==========================================\n004 2 80d0 85d6 | 2 80d0 (0) 85d6 (0)\n005 1 88b4 | 1 88b4 (0)\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"jF8Hvclse72Px7z147qEHKv8R/kQrL9BZzD15n+EezQ="},"ip":"0.0.0.0"},"up":true,"config":{"name":"node63","id":"03e750d46b9a4a9e2047a5b718f427834417f4eb48d8794fde26593a3adbbce48750fa93f47548e342677e94888941ebd492a844a5d8325f67a0db8e94a09b55","services":["pss","bzz"],"private_key":"96f0c30375428cd6184d43806adfbc9a4600e0180b50afa6ce06bfb1581cf1e0"}}},{"node":{"config":{"services":["pss","bzz"],"id":"dc41672c95ae1af5b7008f7b1c4e232dc469c4969095d357a6e713257ddb8f7220eadf41082cb22503cee38c042160f5d9750f4787b6e44dc8eaa5bd76df8e55","name":"node64","private_key":"4738e28b9e3f0920f9c89ac195862299c670e5b354e5bbd644395336a446166f"},"up":true,"info":{"ip":"0.0.0.0","protocols":{"bzz":"T/KG+eH30tCo4UpVR+A1gNZ9vt0eLKDIitAaLlbA9Fw=","hive":"\n=========================================================================\nFri Sep 29 20:17:10 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 4ff286\npopulation: 10 (63), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 8c5f | 36 aa65 (0) ab1c (0) a365 (0) a416 (0)\n001 1 2597 | 12 0b45 (0) 0f5c (0) 0f98 (0) 1f17 (0)\n002 2 6a5c 7f41 | 9 6d29 (0) 6b33 (0) 6a5c (0) 647c (0)\n============ DEPTH: 3 ==========================================\n003 5 5205 5fd6 5e64 5c19 | 5 5205 (0) 5c19 (0) 5e64 (0) 5fd6 (0)\n004 1 461c | 1 461c (0)\n005 0 | 0\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"discovery":0,"listener":0},"listenAddr":"","enode":"enode://dc41672c95ae1af5b7008f7b1c4e232dc469c4969095d357a6e713257ddb8f7220eadf41082cb22503cee38c042160f5d9750f4787b6e44dc8eaa5bd76df8e55@0.0.0.0:0","id":"dc41672c95ae1af5b7008f7b1c4e232dc469c4969095d357a6e713257ddb8f7220eadf41082cb22503cee38c042160f5d9750f4787b6e44dc8eaa5bd76df8e55","name":"node64"}}}]} \ No newline at end of file diff --git a/swarm/pss/testdata/snapshot_8.json b/swarm/pss/testdata/snapshot_8.json new file mode 100644 index 0000000000..9650fb4e95 --- /dev/null +++ b/swarm/pss/testdata/snapshot_8.json @@ -0,0 +1 @@ +{"conns":[{"one":"0eec333dd211c2ea81db614fe58bf0300c15e50e1b044e47ef93067a6cdbc3bc666b40bdcc515bbf580355dbef9370294ef1ee92ee0525e78a8beed00c2b99f5","other":"6f6ee658538ea66a68c9cb914d09f228f6ee9942c337a8d5a2cb3a0f021e83dd0fab481ca8ebf56ed913f6ddf69caa3249459d43e61e5e5b162ded7e1c918c9c","up":true},{"one":"1835ee9d95eb124a3fda550d7b0cc32be81f928a78c84fee5954d8f2d26fd4c9c194d2e885daff1985f6b5ea5ccfdcd2f95292c84c665461f36e5a868e696df3","other":"32ef43c17cb3230284a3ab365b5707a8814fcb244ab62134d1576d9d516151ff6f8051d3de562588616fbb957d90b648b452ae5fad0e7b2179f29c59b528b6e4","up":true},{"other":"0eec333dd211c2ea81db614fe58bf0300c15e50e1b044e47ef93067a6cdbc3bc666b40bdcc515bbf580355dbef9370294ef1ee92ee0525e78a8beed00c2b99f5","one":"7b12f55c7c012104e006775d03b89722b403fb0e1ecb79af8cadfa6947425aedb323fb9416c84b782d35f3216acb5d94a1dd31d60a3eba45f9051bf503de1b66","up":true},{"up":true,"one":"a3095fd0d1e36e36de7c0d188dc76fd7d156296e1b767238c736f791baf0841a1f5ade1c9e0f33d5bb384993e6c3a5552e41748f3f08243f3604854007031d5b","other":"438712d36b9ced9a2f58ee6c7b65468ad288094a49ff0783da9245ab98cd0e74a10deec79839a3e3dd5bc06cc190d7ed6e09a4ba0c64b3f0209fa165938f3a8a"},{"up":true,"other":"7b12f55c7c012104e006775d03b89722b403fb0e1ecb79af8cadfa6947425aedb323fb9416c84b782d35f3216acb5d94a1dd31d60a3eba45f9051bf503de1b66","one":"438712d36b9ced9a2f58ee6c7b65468ad288094a49ff0783da9245ab98cd0e74a10deec79839a3e3dd5bc06cc190d7ed6e09a4ba0c64b3f0209fa165938f3a8a"},{"other":"a3095fd0d1e36e36de7c0d188dc76fd7d156296e1b767238c736f791baf0841a1f5ade1c9e0f33d5bb384993e6c3a5552e41748f3f08243f3604854007031d5b","one":"32ef43c17cb3230284a3ab365b5707a8814fcb244ab62134d1576d9d516151ff6f8051d3de562588616fbb957d90b648b452ae5fad0e7b2179f29c59b528b6e4","up":true},{"other":"1835ee9d95eb124a3fda550d7b0cc32be81f928a78c84fee5954d8f2d26fd4c9c194d2e885daff1985f6b5ea5ccfdcd2f95292c84c665461f36e5a868e696df3","one":"83388147883592bab4fdaddb4e56f8cb1c56dc5c2e910fc6a7277ac89b77cc7ce24892ed6984f3414589cb3b8c4b69356ff9aab7ca52fdd58f12dee2a2152523","up":true},{"up":true,"other":"83388147883592bab4fdaddb4e56f8cb1c56dc5c2e910fc6a7277ac89b77cc7ce24892ed6984f3414589cb3b8c4b69356ff9aab7ca52fdd58f12dee2a2152523","one":"6f6ee658538ea66a68c9cb914d09f228f6ee9942c337a8d5a2cb3a0f021e83dd0fab481ca8ebf56ed913f6ddf69caa3249459d43e61e5e5b162ded7e1c918c9c"},{"one":"7b12f55c7c012104e006775d03b89722b403fb0e1ecb79af8cadfa6947425aedb323fb9416c84b782d35f3216acb5d94a1dd31d60a3eba45f9051bf503de1b66","other":"32ef43c17cb3230284a3ab365b5707a8814fcb244ab62134d1576d9d516151ff6f8051d3de562588616fbb957d90b648b452ae5fad0e7b2179f29c59b528b6e4","up":true},{"up":true,"other":"a3095fd0d1e36e36de7c0d188dc76fd7d156296e1b767238c736f791baf0841a1f5ade1c9e0f33d5bb384993e6c3a5552e41748f3f08243f3604854007031d5b","one":"83388147883592bab4fdaddb4e56f8cb1c56dc5c2e910fc6a7277ac89b77cc7ce24892ed6984f3414589cb3b8c4b69356ff9aab7ca52fdd58f12dee2a2152523"},{"one":"1835ee9d95eb124a3fda550d7b0cc32be81f928a78c84fee5954d8f2d26fd4c9c194d2e885daff1985f6b5ea5ccfdcd2f95292c84c665461f36e5a868e696df3","other":"a3095fd0d1e36e36de7c0d188dc76fd7d156296e1b767238c736f791baf0841a1f5ade1c9e0f33d5bb384993e6c3a5552e41748f3f08243f3604854007031d5b","up":true},{"other":"7b12f55c7c012104e006775d03b89722b403fb0e1ecb79af8cadfa6947425aedb323fb9416c84b782d35f3216acb5d94a1dd31d60a3eba45f9051bf503de1b66","one":"a3095fd0d1e36e36de7c0d188dc76fd7d156296e1b767238c736f791baf0841a1f5ade1c9e0f33d5bb384993e6c3a5552e41748f3f08243f3604854007031d5b","up":true},{"up":true,"one":"32ef43c17cb3230284a3ab365b5707a8814fcb244ab62134d1576d9d516151ff6f8051d3de562588616fbb957d90b648b452ae5fad0e7b2179f29c59b528b6e4","other":"83388147883592bab4fdaddb4e56f8cb1c56dc5c2e910fc6a7277ac89b77cc7ce24892ed6984f3414589cb3b8c4b69356ff9aab7ca52fdd58f12dee2a2152523"},{"up":true,"other":"83388147883592bab4fdaddb4e56f8cb1c56dc5c2e910fc6a7277ac89b77cc7ce24892ed6984f3414589cb3b8c4b69356ff9aab7ca52fdd58f12dee2a2152523","one":"438712d36b9ced9a2f58ee6c7b65468ad288094a49ff0783da9245ab98cd0e74a10deec79839a3e3dd5bc06cc190d7ed6e09a4ba0c64b3f0209fa165938f3a8a"},{"up":true,"other":"438712d36b9ced9a2f58ee6c7b65468ad288094a49ff0783da9245ab98cd0e74a10deec79839a3e3dd5bc06cc190d7ed6e09a4ba0c64b3f0209fa165938f3a8a","one":"6f6ee658538ea66a68c9cb914d09f228f6ee9942c337a8d5a2cb3a0f021e83dd0fab481ca8ebf56ed913f6ddf69caa3249459d43e61e5e5b162ded7e1c918c9c"},{"up":true,"one":"0eec333dd211c2ea81db614fe58bf0300c15e50e1b044e47ef93067a6cdbc3bc666b40bdcc515bbf580355dbef9370294ef1ee92ee0525e78a8beed00c2b99f5","other":"1835ee9d95eb124a3fda550d7b0cc32be81f928a78c84fee5954d8f2d26fd4c9c194d2e885daff1985f6b5ea5ccfdcd2f95292c84c665461f36e5a868e696df3"},{"other":"1835ee9d95eb124a3fda550d7b0cc32be81f928a78c84fee5954d8f2d26fd4c9c194d2e885daff1985f6b5ea5ccfdcd2f95292c84c665461f36e5a868e696df3","one":"7b12f55c7c012104e006775d03b89722b403fb0e1ecb79af8cadfa6947425aedb323fb9416c84b782d35f3216acb5d94a1dd31d60a3eba45f9051bf503de1b66","up":true},{"other":"a3095fd0d1e36e36de7c0d188dc76fd7d156296e1b767238c736f791baf0841a1f5ade1c9e0f33d5bb384993e6c3a5552e41748f3f08243f3604854007031d5b","one":"0eec333dd211c2ea81db614fe58bf0300c15e50e1b044e47ef93067a6cdbc3bc666b40bdcc515bbf580355dbef9370294ef1ee92ee0525e78a8beed00c2b99f5","up":true},{"up":true,"one":"0eec333dd211c2ea81db614fe58bf0300c15e50e1b044e47ef93067a6cdbc3bc666b40bdcc515bbf580355dbef9370294ef1ee92ee0525e78a8beed00c2b99f5","other":"32ef43c17cb3230284a3ab365b5707a8814fcb244ab62134d1576d9d516151ff6f8051d3de562588616fbb957d90b648b452ae5fad0e7b2179f29c59b528b6e4"}],"nodes":[{"node":{"config":{"private_key":"e567b7d9c554e5102cdc99b6523bace02dbb8951415c8816d82ba2d2e97fa23b","name":"node01","id":"7b12f55c7c012104e006775d03b89722b403fb0e1ecb79af8cadfa6947425aedb323fb9416c84b782d35f3216acb5d94a1dd31d60a3eba45f9051bf503de1b66","services":["pss","bzz"]},"info":{"ip":"0.0.0.0","listenAddr":"","protocols":{"hive":"\n=========================================================================\nFri Sep 29 21:22:53 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 73d6ad\npopulation: 5 (7), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 dfd4 | 3 8a1e (0) d776 (0) dfd4 (0)\n============ DEPTH: 1 ==========================================\n001 3 05da 159c 3451 | 3 05da (0) 159c (0) 3451 (0)\n002 0 | 0\n003 1 6e8d | 1 6e8d (0)\n004 0 | 0\n005 0 | 0\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"c9atSnUGnc7WYPpMuYFD7lVz33yxXZopWs8WVeloM4Q="},"ports":{"listener":0,"discovery":0},"name":"node01","id":"7b12f55c7c012104e006775d03b89722b403fb0e1ecb79af8cadfa6947425aedb323fb9416c84b782d35f3216acb5d94a1dd31d60a3eba45f9051bf503de1b66","enode":"enode://7b12f55c7c012104e006775d03b89722b403fb0e1ecb79af8cadfa6947425aedb323fb9416c84b782d35f3216acb5d94a1dd31d60a3eba45f9051bf503de1b66@0.0.0.0:0"},"up":true}},{"node":{"info":{"listenAddr":"","ip":"0.0.0.0","ports":{"discovery":0,"listener":0},"protocols":{"hive":"\n=========================================================================\nFri Sep 29 21:22:53 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 6e8da8\npopulation: 5 (7), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 8a1e | 3 8a1e (0) d776 (0) dfd4 (0)\n============ DEPTH: 1 ==========================================\n001 3 3451 159c 05da | 3 05da (0) 159c (0) 3451 (0)\n002 0 | 0\n003 1 73d6 | 1 73d6 (0)\n004 0 | 0\n005 0 | 0\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"bo2oaruJSrNQRMjEVRRyJd+WyrSY2gZ6EY8fuaQX+eM="},"id":"0eec333dd211c2ea81db614fe58bf0300c15e50e1b044e47ef93067a6cdbc3bc666b40bdcc515bbf580355dbef9370294ef1ee92ee0525e78a8beed00c2b99f5","name":"node02","enode":"enode://0eec333dd211c2ea81db614fe58bf0300c15e50e1b044e47ef93067a6cdbc3bc666b40bdcc515bbf580355dbef9370294ef1ee92ee0525e78a8beed00c2b99f5@0.0.0.0:0"},"config":{"name":"node02","id":"0eec333dd211c2ea81db614fe58bf0300c15e50e1b044e47ef93067a6cdbc3bc666b40bdcc515bbf580355dbef9370294ef1ee92ee0525e78a8beed00c2b99f5","services":["pss","bzz"],"private_key":"c7526db70acd02f36d3b201ef3e1d85e38c52bee6931453213dbc5edec4d0976"},"up":true}},{"node":{"config":{"private_key":"61b5728f59bc43080c3b8eb0458fb30d7723e2747355b6dc980f35f3ed431199","id":"6f6ee658538ea66a68c9cb914d09f228f6ee9942c337a8d5a2cb3a0f021e83dd0fab481ca8ebf56ed913f6ddf69caa3249459d43e61e5e5b162ded7e1c918c9c","name":"node03","services":["pss","bzz"]},"info":{"ip":"0.0.0.0","listenAddr":"","protocols":{"hive":"\n=========================================================================\nFri Sep 29 21:22:53 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 8a1eb7\npopulation: 3 (7), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 6e8d | 5 05da (0) 159c (0) 3451 (0) 73d6 (0)\n============ DEPTH: 1 ==========================================\n001 2 dfd4 d776 | 2 dfd4 (0) d776 (0)\n002 0 | 0\n003 0 | 0\n004 0 | 0\n005 0 | 0\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"ih63j/E98xjn+BFt/+6YzX2ZBWUPpT8Wdmt1SmPzh6w="},"ports":{"discovery":0,"listener":0},"name":"node03","id":"6f6ee658538ea66a68c9cb914d09f228f6ee9942c337a8d5a2cb3a0f021e83dd0fab481ca8ebf56ed913f6ddf69caa3249459d43e61e5e5b162ded7e1c918c9c","enode":"enode://6f6ee658538ea66a68c9cb914d09f228f6ee9942c337a8d5a2cb3a0f021e83dd0fab481ca8ebf56ed913f6ddf69caa3249459d43e61e5e5b162ded7e1c918c9c@0.0.0.0:0"},"up":true}},{"node":{"info":{"name":"node04","id":"83388147883592bab4fdaddb4e56f8cb1c56dc5c2e910fc6a7277ac89b77cc7ce24892ed6984f3414589cb3b8c4b69356ff9aab7ca52fdd58f12dee2a2152523","enode":"enode://83388147883592bab4fdaddb4e56f8cb1c56dc5c2e910fc6a7277ac89b77cc7ce24892ed6984f3414589cb3b8c4b69356ff9aab7ca52fdd58f12dee2a2152523@0.0.0.0:0","ip":"0.0.0.0","listenAddr":"","protocols":{"bzz":"13aDNPedYmrbQz9EtwOoGFVeMzEFYDbvP40Sglhr8EQ=","hive":"\n=========================================================================\nFri Sep 29 21:22:53 UTC 2017 KΛÐΞMLIΛ hive: queen's address: d77683\npopulation: 5 (7), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 3 3451 159c 05da | 5 6e8d (0) 73d6 (0) 3451 (0) 159c (0)\n============ DEPTH: 1 ==========================================\n001 1 8a1e | 1 8a1e (0)\n002 0 | 0\n003 0 | 0\n004 1 dfd4 | 1 dfd4 (0)\n005 0 | 0\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"listener":0,"discovery":0}},"config":{"services":["pss","bzz"],"id":"83388147883592bab4fdaddb4e56f8cb1c56dc5c2e910fc6a7277ac89b77cc7ce24892ed6984f3414589cb3b8c4b69356ff9aab7ca52fdd58f12dee2a2152523","name":"node04","private_key":"075b07c29ceac4ffa2a114afd67b21dfc438126bc169bf7c154be6d81d86ed38"},"up":true}},{"node":{"info":{"id":"1835ee9d95eb124a3fda550d7b0cc32be81f928a78c84fee5954d8f2d26fd4c9c194d2e885daff1985f6b5ea5ccfdcd2f95292c84c665461f36e5a868e696df3","name":"node05","enode":"enode://1835ee9d95eb124a3fda550d7b0cc32be81f928a78c84fee5954d8f2d26fd4c9c194d2e885daff1985f6b5ea5ccfdcd2f95292c84c665461f36e5a868e696df3@0.0.0.0:0","listenAddr":"","ip":"0.0.0.0","ports":{"listener":0,"discovery":0},"protocols":{"hive":"\n=========================================================================\nFri Sep 29 21:22:53 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 05dacb\npopulation: 5 (7), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 d776 | 3 8a1e (0) dfd4 (0) d776 (0)\n001 2 73d6 6e8d | 2 6e8d (0) 73d6 (0)\n============ DEPTH: 2 ==========================================\n002 1 3451 | 1 3451 (0)\n003 1 159c | 1 159c (0)\n004 0 | 0\n005 0 | 0\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"BdrL4GnkUkSPt77gm4JwoCGAiabUQcRh/EXTONK1lJI="}},"config":{"private_key":"4882fdd34676c2158f7bfc761bf824fcf693736a8df294cc7e79ef1848c7bae6","id":"1835ee9d95eb124a3fda550d7b0cc32be81f928a78c84fee5954d8f2d26fd4c9c194d2e885daff1985f6b5ea5ccfdcd2f95292c84c665461f36e5a868e696df3","name":"node05","services":["pss","bzz"]},"up":true}},{"node":{"config":{"private_key":"0470652ac57af40a43bc67b1b49699219fc35a805da167244f505d27858334c7","id":"32ef43c17cb3230284a3ab365b5707a8814fcb244ab62134d1576d9d516151ff6f8051d3de562588616fbb957d90b648b452ae5fad0e7b2179f29c59b528b6e4","name":"node06","services":["pss","bzz"]},"info":{"ip":"0.0.0.0","listenAddr":"","protocols":{"bzz":"NFHfgIqeEi67xjBvFZrpDM005e8+BFfFAfVKwIRXI4o=","hive":"\n=========================================================================\nFri Sep 29 21:22:53 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 3451df\npopulation: 5 (7), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 1 d776 | 3 dfd4 (0) d776 (0) 8a1e (0)\n001 2 6e8d 73d6 | 2 6e8d (0) 73d6 (0)\n============ DEPTH: 2 ==========================================\n002 2 159c 05da | 2 159c (0) 05da (0)\n003 0 | 0\n004 0 | 0\n005 0 | 0\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"ports":{"discovery":0,"listener":0},"name":"node06","id":"32ef43c17cb3230284a3ab365b5707a8814fcb244ab62134d1576d9d516151ff6f8051d3de562588616fbb957d90b648b452ae5fad0e7b2179f29c59b528b6e4","enode":"enode://32ef43c17cb3230284a3ab365b5707a8814fcb244ab62134d1576d9d516151ff6f8051d3de562588616fbb957d90b648b452ae5fad0e7b2179f29c59b528b6e4@0.0.0.0:0"},"up":true}},{"node":{"info":{"ports":{"discovery":0,"listener":0},"protocols":{"hive":"\n=========================================================================\nFri Sep 29 21:22:53 UTC 2017 KΛÐΞMLIΛ hive: queen's address: 159c0b\npopulation: 6 (7), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 d776 dfd4 | 3 8a1e (0) d776 (0) dfd4 (0)\n001 2 6e8d 73d6 | 2 6e8d (0) 73d6 (0)\n============ DEPTH: 2 ==========================================\n002 1 3451 | 1 3451 (0)\n003 1 05da | 1 05da (0)\n004 0 | 0\n005 0 | 0\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n=========================================================================","bzz":"FZwL2zwWOOZt5S7AxHYoLrWnsfz3Y9wzuTjFOB71oUk="},"listenAddr":"","ip":"0.0.0.0","enode":"enode://a3095fd0d1e36e36de7c0d188dc76fd7d156296e1b767238c736f791baf0841a1f5ade1c9e0f33d5bb384993e6c3a5552e41748f3f08243f3604854007031d5b@0.0.0.0:0","id":"a3095fd0d1e36e36de7c0d188dc76fd7d156296e1b767238c736f791baf0841a1f5ade1c9e0f33d5bb384993e6c3a5552e41748f3f08243f3604854007031d5b","name":"node07"},"config":{"private_key":"2cbf6256e92736e1b54279b79addbb830a607a71488cdd3462a44fcaa68c018e","id":"a3095fd0d1e36e36de7c0d188dc76fd7d156296e1b767238c736f791baf0841a1f5ade1c9e0f33d5bb384993e6c3a5552e41748f3f08243f3604854007031d5b","name":"node07","services":["pss","bzz"]},"up":true}},{"node":{"up":true,"info":{"enode":"enode://438712d36b9ced9a2f58ee6c7b65468ad288094a49ff0783da9245ab98cd0e74a10deec79839a3e3dd5bc06cc190d7ed6e09a4ba0c64b3f0209fa165938f3a8a@0.0.0.0:0","id":"438712d36b9ced9a2f58ee6c7b65468ad288094a49ff0783da9245ab98cd0e74a10deec79839a3e3dd5bc06cc190d7ed6e09a4ba0c64b3f0209fa165938f3a8a","name":"node08","ports":{"listener":0,"discovery":0},"protocols":{"bzz":"39R9VEkurAlwhkGnEVsf2jKOLdj3XO2QJiEtNplyL5Q=","hive":"\n=========================================================================\nFri Sep 29 21:22:53 UTC 2017 KΛÐΞMLIΛ hive: queen's address: dfd47d\npopulation: 4 (7), MinProxBinSize: 2, MinBinSize: 1, MaxBinSize: 3\n000 2 73d6 159c | 5 6e8d (0) 73d6 (0) 3451 (0) 05da (0)\n============ DEPTH: 1 ==========================================\n001 1 8a1e | 1 8a1e (0)\n002 0 | 0\n003 0 | 0\n004 1 d776 | 1 d776 (0)\n005 0 | 0\n006 0 | 0\n007 0 | 0\n008 0 | 0\n009 0 | 0\n010 0 | 0\n011 0 | 0\n012 0 | 0\n013 0 | 0\n014 0 | 0\n015 0 | 0\n========================================================================="},"listenAddr":"","ip":"0.0.0.0"},"config":{"services":["pss","bzz"],"id":"438712d36b9ced9a2f58ee6c7b65468ad288094a49ff0783da9245ab98cd0e74a10deec79839a3e3dd5bc06cc190d7ed6e09a4ba0c64b3f0209fa165938f3a8a","name":"node08","private_key":"e659774a5ff4f76b021bf4884ad359eadeb8ff33e843a3f76fcf4a38b0d82b35"}}}]} \ No newline at end of file diff --git a/swarm/pss/types.go b/swarm/pss/types.go new file mode 100644 index 0000000000..1e33ecdcac --- /dev/null +++ b/swarm/pss/types.go @@ -0,0 +1,191 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package pss + +import ( + "encoding/json" + "fmt" + "sync" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/p2p" + "github.com/ethereum/go-ethereum/rlp" + "github.com/ethereum/go-ethereum/swarm/storage" + whisper "github.com/ethereum/go-ethereum/whisper/whisperv5" +) + +const ( + defaultWhisperTTL = 6000 +) + +const ( + pssControlSym = 1 + pssControlRaw = 1 << 1 +) + +var ( + topicHashMutex = sync.Mutex{} + topicHashFunc = storage.MakeHashFunc("SHA256")() + rawTopic = Topic{} +) + +// Topic is the PSS encapsulation of the Whisper topic type +type Topic whisper.TopicType + +func (t *Topic) String() string { + return hexutil.Encode(t[:]) +} + +// MarshalJSON implements the json.Marshaler interface +func (t Topic) MarshalJSON() (b []byte, err error) { + return json.Marshal(t.String()) +} + +// MarshalJSON implements the json.Marshaler interface +func (t *Topic) UnmarshalJSON(input []byte) error { + topicbytes, err := hexutil.Decode(string(input[1 : len(input)-1])) + if err != nil { + return err + } + copy(t[:], topicbytes) + return nil +} + +// PssAddress is an alias for []byte. It represents a variable length address +type PssAddress []byte + +// MarshalJSON implements the json.Marshaler interface +func (a PssAddress) MarshalJSON() ([]byte, error) { + return json.Marshal(hexutil.Encode(a[:])) +} + +// UnmarshalJSON implements the json.Marshaler interface +func (a *PssAddress) UnmarshalJSON(input []byte) error { + b, err := hexutil.Decode(string(input[1 : len(input)-1])) + if err != nil { + return err + } + for _, bb := range b { + *a = append(*a, bb) + } + return nil +} + +// holds the digest of a message used for caching +type pssDigest [digestLength]byte + +// conceals bitwise operations on the control flags byte +type msgParams struct { + raw bool + sym bool +} + +func newMsgParamsFromBytes(paramBytes []byte) *msgParams { + if len(paramBytes) != 1 { + return nil + } + return &msgParams{ + raw: paramBytes[0]&pssControlRaw > 0, + sym: paramBytes[0]&pssControlSym > 0, + } +} + +func (m *msgParams) Bytes() (paramBytes []byte) { + var b byte + if m.raw { + b |= pssControlRaw + } + if m.sym { + b |= pssControlSym + } + paramBytes = append(paramBytes, b) + return paramBytes +} + +// PssMsg encapsulates messages transported over pss. +type PssMsg struct { + To []byte + Control []byte + Expire uint32 + Payload *whisper.Envelope +} + +func newPssMsg(param *msgParams) *PssMsg { + return &PssMsg{ + Control: param.Bytes(), + } +} + +// message is flagged as raw / external encryption +func (msg *PssMsg) isRaw() bool { + return msg.Control[0]&pssControlRaw > 0 +} + +// message is flagged as symmetrically encrypted +func (msg *PssMsg) isSym() bool { + return msg.Control[0]&pssControlSym > 0 +} + +// serializes the message for use in cache +func (msg *PssMsg) serialize() []byte { + rlpdata, _ := rlp.EncodeToBytes(struct { + To []byte + Payload *whisper.Envelope + }{ + To: msg.To, + Payload: msg.Payload, + }) + return rlpdata +} + +// String representation of PssMsg +func (msg *PssMsg) String() string { + return fmt.Sprintf("PssMsg: Recipient: %x", common.ToHex(msg.To)) +} + +// Signature for a message handler function for a PssMsg +// +// Implementations of this type are passed to Pss.Register together with a topic, +type Handler func(msg []byte, p *p2p.Peer, asymmetric bool, keyid string) error + +// the stateStore handles saving and loading PSS peers and their corresponding keys +// it is currently unimplemented +type stateStore struct { + values map[string][]byte +} + +func newStateStore() *stateStore { + return &stateStore{values: make(map[string][]byte)} +} + +func (store *stateStore) Load(key string) ([]byte, error) { + return nil, nil +} + +func (store *stateStore) Save(key string, v []byte) error { + return nil +} + +// BytesToTopic hashes an arbitrary length byte slice and truncates it to the length of a topic, using only the first bytes of the digest +func BytesToTopic(b []byte) Topic { + topicHashMutex.Lock() + defer topicHashMutex.Unlock() + topicHashFunc.Reset() + topicHashFunc.Write(b) + return Topic(whisper.BytesToTopic(topicHashFunc.Sum(nil))) +} diff --git a/swarm/pss/writeup.md b/swarm/pss/writeup.md new file mode 100644 index 0000000000..a0506ffa43 --- /dev/null +++ b/swarm/pss/writeup.md @@ -0,0 +1,125 @@ +## PSS tests failures explanation + +This document aims to explain the changes in https://github.com/ethersphere/go-ethereum/pull/126 and how those changes affect the pss_test.go TestNetwork tests. + +### Problem + +When running the TestNetwork test, execution sometimes: + +* deadlocks +* panics +* failures with wrong result, such as: + +``` +$ go test -v ./swarm/pss -cpu 4 -run TestNetwork +``` + +``` +--- FAIL: TestNetwork (68.13s) + --- FAIL: TestNetwork/3/10/4/sim (68.13s) + pss_test.go:697: 7 of 10 messages received + pss_test.go:700: 3 messages were not received +FAIL +``` + +Moreover execution almost always deadlocks with `sim` adapter, and `sock` adapter (when buffer is low), but is mostly stable with `exec` and `tcp` adapters. + +### Findings and Fixes + +#### 1. Addressing panics + +Panics were caused due to concurrent map read/writes and unsynchronised access to shared memory by multiple goroutines. This is visible when running the test with the `-race` flag. + +``` +go test -race -v ./swarm/pss -cpu 4 -run TestNetwork + + 1 ================== + 2 WARNING: DATA RACE + 3 Read at 0x00c424d456a0 by goroutine 1089: + 4 github.com/ethereum/go-ethereum/swarm/pss.(*Pss).forward.func1() + 5 /Users/nonsense/code/src/github.com/ethereum/go-ethereum/swarm/pss/pss.go:654 +0x44f + 6 github.com/ethereum/go-ethereum/swarm/network.(*Kademlia).eachConn.func1() + 7 /Users/nonsense/code/src/github.com/ethereum/go-ethereum/swarm/network/kademlia.go:350 +0xc9 + 8 github.com/ethereum/go-ethereum/pot.(*Pot).eachNeighbour.func1() + 9 /Users/nonsense/code/src/github.com/ethereum/go-ethereum/pot/pot.go:599 +0x59 + ... + + 28 + 29 Previous write at 0x00c424d456a0 by goroutine 829: + 30 github.com/ethereum/go-ethereum/swarm/pss.(*Pss).Run() + 31 /Users/nonsense/code/src/github.com/ethereum/go-ethereum/swarm/pss/pss.go:192 +0x16a + 32 github.com/ethereum/go-ethereum/swarm/pss.(*Pss).Run-fm() + 33 /Users/nonsense/code/src/github.com/ethereum/go-ethereum/swarm/pss/pss.go:185 +0x63 + 34 github.com/ethereum/go-ethereum/p2p.(*Peer).startProtocols.func1() + 35 /Users/nonsense/code/src/github.com/ethereum/go-ethereum/p2p/peer.go:347 +0x8b + ... +``` + +##### Current solution + +Adding a mutex around all shared data. + +#### 2. Failures with wrong result + +The validation phase of the TestNetwork test is done using an RPC subscription: + +``` + ... + triggerChecks := func(trigger chan discover.NodeID, id discover.NodeID, rpcclient *rpc.Client) error { + msgC := make(chan APIMsg) + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + sub, err := rpcclient.Subscribe(ctx, "pss", msgC, "receive", hextopic) + ... +``` + +By design the RPC uses a subscription buffer with a max length. When this length is reached, the subscription is dropped. The current config value is not suitable for stress tests. + +##### Current solution + +Increase the max length of the RPC subscription buffer. + +``` +const ( + // Subscriptions are removed when the subscriber cannot keep up. + // + // This can be worked around by supplying a channel with sufficiently sized buffer, + // but this can be inconvenient and hard to explain in the docs. Another issue with + // buffered channels is that the buffer is static even though it might not be needed + // most of the time. + // + // The approach taken here is to maintain a per-subscription linked list buffer + // shrinks on demand. If the buffer reaches the size below, the subscription is + // dropped. + maxClientSubscriptionBuffer = 20000 +) +``` + +#### 3. Deadlocks + +Deadlocks are triggered when using: +* `sim` adapter - synchronous, unbuffered channel +* `sock` adapter - asynchronous, buffered channel (when using a 1K buffer) + +No deadlocks were triggered when using: +* `tcp` adapter - asynchronous, buffered channel +* `exec` adapter - asynchronous, buffered channel + +Ultimately the deadlocks happen due to blocking `pp.Send()` call at: + + // attempt to send the message + err := pp.Send(msg) + if err != nil { + log.Debug(fmt.Sprintf("%v: failed forwarding: %v", sendMsg, err)) + return true + } + + `p2p` request handling is synchronous (as discussed at https://github.com/ethersphere/go-ethereum/issues/130), `pss` is also synchronous, therefore if two nodes happen to be processing a request, while at the same time waiting for response on `pp.Send(msg)`, deadlock occurs. + + `pp.Send(msg)` is only blocking when the underlying adapter is blocking (read `sim` or `sock`) or the buffer of the connection is full. + +##### Current solution + +Make no assumption on the undelying connection, and call `pp.Send` asynchronously in a go-routine. + +Alternatively, get rid of the `sim` and `sock` adapters, and use `tcp` adapter for testing. diff --git a/swarm/services/swap/swap.go b/swarm/services/swap/swap.go index 1f9b22b904..91fa54fcf0 100644 --- a/swarm/services/swap/swap.go +++ b/swarm/services/swap/swap.go @@ -19,6 +19,7 @@ package swap import ( "context" "crypto/ecdsa" + "errors" "fmt" "math/big" "os" @@ -32,7 +33,7 @@ import ( "github.com/ethereum/go-ethereum/contracts/chequebook/contract" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/swarm/log" "github.com/ethereum/go-ethereum/swarm/services/swap/swap" ) @@ -59,16 +60,19 @@ const ( chequebookDeployDelay = 1 * time.Second // delay between retries ) -type SwapParams struct { +// LocalProfile combines a PayProfile with *swap.Params +type LocalProfile struct { *swap.Params *PayProfile } -type SwapProfile struct { +// RemoteProfile combines a PayProfile with *swap.Profile +type RemoteProfile struct { *swap.Profile *PayProfile } +// PayProfile is a container for relevant chequebook and beneficiary options type PayProfile struct { PublicKey string // check against signature of promise Contract common.Address // address of chequebook contract @@ -80,9 +84,9 @@ type PayProfile struct { lock sync.RWMutex } -//create params with default values -func NewDefaultSwapParams() *SwapParams { - return &SwapParams{ +// NewDefaultSwapParams create params with default values +func NewDefaultSwapParams() *LocalProfile { + return &LocalProfile{ PayProfile: &PayProfile{}, Params: &swap.Params{ Profile: &swap.Profile{ @@ -102,12 +106,12 @@ func NewDefaultSwapParams() *SwapParams { } } -//this can only finally be set after all config options (file, cmd line, env vars) -//have been evaluated -func (self *SwapParams) Init(contract common.Address, prvkey *ecdsa.PrivateKey) { +// Init this can only finally be set after all config options (file, cmd line, env vars) +// have been evaluated +func (lp *LocalProfile) Init(contract common.Address, prvkey *ecdsa.PrivateKey) { pubkey := &prvkey.PublicKey - self.PayProfile = &PayProfile{ + lp.PayProfile = &PayProfile{ PublicKey: common.ToHex(crypto.FromECDSAPub(pubkey)), Contract: contract, Beneficiary: crypto.PubkeyToAddress(*pubkey), @@ -117,7 +121,7 @@ func (self *SwapParams) Init(contract common.Address, prvkey *ecdsa.PrivateKey) } } -// swap constructor, parameters +// NewSwap constructor, parameters // * global chequebook, assume deployed service and // * the balance is at buffer. // swap.Add(n) called in netstore @@ -125,8 +129,7 @@ func (self *SwapParams) Init(contract common.Address, prvkey *ecdsa.PrivateKey) // OR sending cheques. // n < 0 called when receiving chunks = receiving delivery responses // OR receiving cheques. - -func NewSwap(local *SwapParams, remote *SwapProfile, backend chequebook.Backend, proto swap.Protocol) (self *swap.Swap, err error) { +func NewSwap(localProfile *LocalProfile, remoteProfile *RemoteProfile, backend chequebook.Backend, proto swap.Protocol) (swapInstance *swap.Swap, err error) { var ( ctx = context.TODO() ok bool @@ -134,26 +137,31 @@ func NewSwap(local *SwapParams, remote *SwapProfile, backend chequebook.Backend, out *chequebook.Outbox ) - // check if remote chequebook is valid + remotekey, err := crypto.UnmarshalPubkey(common.FromHex(remoteProfile.PublicKey)) + if err != nil { + return nil, errors.New("invalid remote public key") + } + + // check if remoteProfile chequebook is valid // insolvent chequebooks suicide so will signal as invalid // TODO: monitoring a chequebooks events - ok, err = chequebook.ValidateCode(ctx, backend, remote.Contract) + ok, err = chequebook.ValidateCode(ctx, backend, remoteProfile.Contract) if !ok { - log.Info(fmt.Sprintf("invalid contract %v for peer %v: %v)", remote.Contract.Hex()[:8], proto, err)) + log.Info(fmt.Sprintf("invalid contract %v for peer %v: %v)", remoteProfile.Contract.Hex()[:8], proto, err)) } else { - // remote contract valid, create inbox - in, err = chequebook.NewInbox(local.privateKey, remote.Contract, local.Beneficiary, crypto.ToECDSAPub(common.FromHex(remote.PublicKey)), backend) + // remoteProfile contract valid, create inbox + in, err = chequebook.NewInbox(localProfile.privateKey, remoteProfile.Contract, localProfile.Beneficiary, remotekey, backend) if err != nil { - log.Warn(fmt.Sprintf("unable to set up inbox for chequebook contract %v for peer %v: %v)", remote.Contract.Hex()[:8], proto, err)) + log.Warn(fmt.Sprintf("unable to set up inbox for chequebook contract %v for peer %v: %v)", remoteProfile.Contract.Hex()[:8], proto, err)) } } - // check if local chequebook contract is valid - ok, err = chequebook.ValidateCode(ctx, backend, local.Contract) + // check if localProfile chequebook contract is valid + ok, err = chequebook.ValidateCode(ctx, backend, localProfile.Contract) if !ok { - log.Warn(fmt.Sprintf("unable to set up outbox for peer %v: chequebook contract (owner: %v): %v)", proto, local.owner.Hex(), err)) + log.Warn(fmt.Sprintf("unable to set up outbox for peer %v: chequebook contract (owner: %v): %v)", proto, localProfile.owner.Hex(), err)) } else { - out = chequebook.NewOutbox(local.Chequebook(), remote.Beneficiary) + out = chequebook.NewOutbox(localProfile.Chequebook(), remoteProfile.Beneficiary) } pm := swap.Payment{ @@ -162,20 +170,20 @@ func NewSwap(local *SwapParams, remote *SwapProfile, backend chequebook.Backend, Buys: out != nil, Sells: in != nil, } - self, err = swap.New(local.Params, pm, proto) + swapInstance, err = swap.New(localProfile.Params, pm, proto) if err != nil { return } - // remote profile given (first) in handshake - self.SetRemote(remote.Profile) + // remoteProfile profile given (first) in handshake + swapInstance.SetRemote(remoteProfile.Profile) var buy, sell string - if self.Buys { - buy = "purchase from peer enabled at " + remote.SellAt.String() + " wei/chunk" + if swapInstance.Buys { + buy = "purchase from peer enabled at " + remoteProfile.SellAt.String() + " wei/chunk" } else { buy = "purchase from peer disabled" } - if self.Sells { - sell = "selling to peer enabled at " + local.SellAt.String() + " wei/chunk" + if swapInstance.Sells { + sell = "selling to peer enabled at " + localProfile.SellAt.String() + " wei/chunk" } else { sell = "selling to peer disabled" } @@ -184,66 +192,69 @@ func NewSwap(local *SwapParams, remote *SwapProfile, backend chequebook.Backend, return } -func (self *SwapParams) Chequebook() *chequebook.Chequebook { - defer self.lock.Unlock() - self.lock.Lock() - return self.chbook +// Chequebook get's chequebook from the localProfile +func (lp *LocalProfile) Chequebook() *chequebook.Chequebook { + defer lp.lock.Unlock() + lp.lock.Lock() + return lp.chbook } -func (self *SwapParams) PrivateKey() *ecdsa.PrivateKey { - return self.privateKey +// PrivateKey accessor +func (lp *LocalProfile) PrivateKey() *ecdsa.PrivateKey { + return lp.privateKey } -// func (self *SwapParams) PublicKey() *ecdsa.PublicKey { +// func (self *LocalProfile) PublicKey() *ecdsa.PublicKey { // return self.publicKey // } -func (self *SwapParams) SetKey(prvkey *ecdsa.PrivateKey) { - self.privateKey = prvkey - self.publicKey = &prvkey.PublicKey +// SetKey set's private and public key on localProfile +func (lp *LocalProfile) SetKey(prvkey *ecdsa.PrivateKey) { + lp.privateKey = prvkey + lp.publicKey = &prvkey.PublicKey } -// setChequebook(path, backend) wraps the -// chequebook initialiser and sets up autoDeposit to cover spending. -func (self *SwapParams) SetChequebook(ctx context.Context, backend chequebook.Backend, path string) error { - self.lock.Lock() - contract := self.Contract - self.lock.Unlock() +// SetChequebook wraps the chequebook initialiser and sets up autoDeposit to cover spending. +func (lp *LocalProfile) SetChequebook(ctx context.Context, backend chequebook.Backend, path string) error { + lp.lock.Lock() + swapContract := lp.Contract + lp.lock.Unlock() - valid, err := chequebook.ValidateCode(ctx, backend, contract) + valid, err := chequebook.ValidateCode(ctx, backend, swapContract) if err != nil { return err } else if valid { - return self.newChequebookFromContract(path, backend) + return lp.newChequebookFromContract(path, backend) } - return self.deployChequebook(ctx, backend, path) + return lp.deployChequebook(ctx, backend, path) } -func (self *SwapParams) deployChequebook(ctx context.Context, backend chequebook.Backend, path string) error { - opts := bind.NewKeyedTransactor(self.privateKey) - opts.Value = self.AutoDepositBuffer +// deployChequebook deploys the localProfile Chequebook +func (lp *LocalProfile) deployChequebook(ctx context.Context, backend chequebook.Backend, path string) error { + opts := bind.NewKeyedTransactor(lp.privateKey) + opts.Value = lp.AutoDepositBuffer opts.Context = ctx log.Info(fmt.Sprintf("Deploying new chequebook (owner: %v)", opts.From.Hex())) - contract, err := deployChequebookLoop(opts, backend) + address, err := deployChequebookLoop(opts, backend) if err != nil { log.Error(fmt.Sprintf("unable to deploy new chequebook: %v", err)) return err } - log.Info(fmt.Sprintf("new chequebook deployed at %v (owner: %v)", contract.Hex(), opts.From.Hex())) + log.Info(fmt.Sprintf("new chequebook deployed at %v (owner: %v)", address.Hex(), opts.From.Hex())) // need to save config at this point - self.lock.Lock() - self.Contract = contract - err = self.newChequebookFromContract(path, backend) - self.lock.Unlock() + lp.lock.Lock() + lp.Contract = address + err = lp.newChequebookFromContract(path, backend) + lp.lock.Unlock() if err != nil { log.Warn(fmt.Sprintf("error initialising cheque book (owner: %v): %v", opts.From.Hex(), err)) } return err } -// repeatedly tries to deploy a chequebook. +// deployChequebookLoop repeatedly tries to deploy a chequebook. func deployChequebookLoop(opts *bind.TransactOpts, backend chequebook.Backend) (addr common.Address, err error) { var tx *types.Transaction for try := 0; try < chequebookDeployRetries; try++ { @@ -263,28 +274,28 @@ func deployChequebookLoop(opts *bind.TransactOpts, backend chequebook.Backend) ( return addr, err } -// initialise the chequebook from a persisted json file or create a new one +// newChequebookFromContract - initialise the chequebook from a persisted json file or create a new one // caller holds the lock -func (self *SwapParams) newChequebookFromContract(path string, backend chequebook.Backend) error { - hexkey := common.Bytes2Hex(self.Contract.Bytes()) +func (lp *LocalProfile) newChequebookFromContract(path string, backend chequebook.Backend) error { + hexkey := common.Bytes2Hex(lp.Contract.Bytes()) err := os.MkdirAll(filepath.Join(path, "chequebooks"), os.ModePerm) if err != nil { return fmt.Errorf("unable to create directory for chequebooks: %v", err) } chbookpath := filepath.Join(path, "chequebooks", hexkey+".json") - self.chbook, err = chequebook.LoadChequebook(chbookpath, self.privateKey, backend, true) + lp.chbook, err = chequebook.LoadChequebook(chbookpath, lp.privateKey, backend, true) if err != nil { - self.chbook, err = chequebook.NewChequebook(chbookpath, self.Contract, self.privateKey, backend) + lp.chbook, err = chequebook.NewChequebook(chbookpath, lp.Contract, lp.privateKey, backend) if err != nil { - log.Warn(fmt.Sprintf("unable to initialise chequebook (owner: %v): %v", self.owner.Hex(), err)) - return fmt.Errorf("unable to initialise chequebook (owner: %v): %v", self.owner.Hex(), err) + log.Warn(fmt.Sprintf("unable to initialise chequebook (owner: %v): %v", lp.owner.Hex(), err)) + return fmt.Errorf("unable to initialise chequebook (owner: %v): %v", lp.owner.Hex(), err) } } - self.chbook.AutoDeposit(self.AutoDepositInterval, self.AutoDepositThreshold, self.AutoDepositBuffer) - log.Info(fmt.Sprintf("auto deposit ON for %v -> %v: interval = %v, threshold = %v, buffer = %v)", crypto.PubkeyToAddress(*(self.publicKey)).Hex()[:8], self.Contract.Hex()[:8], self.AutoDepositInterval, self.AutoDepositThreshold, self.AutoDepositBuffer)) + lp.chbook.AutoDeposit(lp.AutoDepositInterval, lp.AutoDepositThreshold, lp.AutoDepositBuffer) + log.Info(fmt.Sprintf("auto deposit ON for %v -> %v: interval = %v, threshold = %v, buffer = %v)", crypto.PubkeyToAddress(*(lp.publicKey)).Hex()[:8], lp.Contract.Hex()[:8], lp.AutoDepositInterval, lp.AutoDepositThreshold, lp.AutoDepositBuffer)) return nil } diff --git a/swarm/services/swap/swap/swap.go b/swarm/services/swap/swap/swap.go index a78f1f0e2a..0afca9ab30 100644 --- a/swarm/services/swap/swap/swap.go +++ b/swarm/services/swap/swap/swap.go @@ -22,14 +22,14 @@ import ( "sync" "time" - "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/swarm/log" ) // SwAP Swarm Accounting Protocol with // Swift Automatic Payments // a peer to peer micropayment system -// public swap profile +// Profile - public swap profile // public parameters for SWAP, serializable config struct passed in handshake type Profile struct { BuyAt *big.Int // accepted max price for chunk @@ -55,34 +55,33 @@ type Params struct { *Strategy } -// Promise -// 3rd party Provable Promise of Payment +// Promise - 3rd party Provable Promise of Payment // issued by outPayment -// serialisable to send with Protocol +// serializable to send with Protocol type Promise interface{} -// interface for the peer protocol for testing or external alternative payment +// Protocol interface for the peer protocol for testing or external alternative payment type Protocol interface { Pay(int, Promise) // units, payment proof Drop() String() string } -// interface for the (delayed) ougoing payment system with autodeposit +// OutPayment interface for the (delayed) outgoing payment system with auto-deposit type OutPayment interface { Issue(amount *big.Int) (promise Promise, err error) AutoDeposit(interval time.Duration, threshold, buffer *big.Int) Stop() } -// interface for the (delayed) incoming payment system with autocash +// InPayment interface for the (delayed) incoming payment system with autocash type InPayment interface { Receive(promise Promise) (*big.Int, error) AutoCash(cashInterval time.Duration, maxUncashed *big.Int) Stop() } -// swap is the swarm accounting protocol instance +// Swap is the swarm accounting protocol instance // * pairwise accounting and payments type Swap struct { lock sync.Mutex // mutex for balance access @@ -93,160 +92,161 @@ type Swap struct { Payment } +// Payment handlers type Payment struct { Out OutPayment // outgoing payment handler In InPayment // incoming payment handler Buys, Sells bool } -// swap constructor -func New(local *Params, pm Payment, proto Protocol) (self *Swap, err error) { +// New - swap constructor +func New(local *Params, pm Payment, proto Protocol) (swap *Swap, err error) { - self = &Swap{ + swap = &Swap{ local: local, Payment: pm, proto: proto, } - self.SetParams(local) + swap.SetParams(local) return } -// entry point for setting remote swap profile (e.g from handshake or other message) -func (self *Swap) SetRemote(remote *Profile) { - defer self.lock.Unlock() - self.lock.Lock() +// SetRemote - entry point for setting remote swap profile (e.g from handshake or other message) +func (swap *Swap) SetRemote(remote *Profile) { + defer swap.lock.Unlock() + swap.lock.Lock() - self.remote = remote - if self.Sells && (remote.BuyAt.Sign() <= 0 || self.local.SellAt.Sign() <= 0 || remote.BuyAt.Cmp(self.local.SellAt) < 0) { - self.Out.Stop() - self.Sells = false + swap.remote = remote + if swap.Sells && (remote.BuyAt.Sign() <= 0 || swap.local.SellAt.Sign() <= 0 || remote.BuyAt.Cmp(swap.local.SellAt) < 0) { + swap.Out.Stop() + swap.Sells = false } - if self.Buys && (remote.SellAt.Sign() <= 0 || self.local.BuyAt.Sign() <= 0 || self.local.BuyAt.Cmp(self.remote.SellAt) < 0) { - self.In.Stop() - self.Buys = false + if swap.Buys && (remote.SellAt.Sign() <= 0 || swap.local.BuyAt.Sign() <= 0 || swap.local.BuyAt.Cmp(swap.remote.SellAt) < 0) { + swap.In.Stop() + swap.Buys = false } - log.Debug(fmt.Sprintf("<%v> remote profile set: pay at: %v, drop at: %v, buy at: %v, sell at: %v", self.proto, remote.PayAt, remote.DropAt, remote.BuyAt, remote.SellAt)) + log.Debug(fmt.Sprintf("<%v> remote profile set: pay at: %v, drop at: %v, buy at: %v, sell at: %v", swap.proto, remote.PayAt, remote.DropAt, remote.BuyAt, remote.SellAt)) } -// to set strategy dynamically -func (self *Swap) SetParams(local *Params) { - defer self.lock.Unlock() - self.lock.Lock() - self.local = local - self.setParams(local) +// SetParams - to set strategy dynamically +func (swap *Swap) SetParams(local *Params) { + defer swap.lock.Unlock() + swap.lock.Lock() + swap.local = local + swap.setParams(local) } -// caller holds the lock +// setParams - caller holds the lock +func (swap *Swap) setParams(local *Params) { -func (self *Swap) setParams(local *Params) { - - if self.Sells { - self.In.AutoCash(local.AutoCashInterval, local.AutoCashThreshold) - log.Info(fmt.Sprintf("<%v> set autocash to every %v, max uncashed limit: %v", self.proto, local.AutoCashInterval, local.AutoCashThreshold)) + if swap.Sells { + swap.In.AutoCash(local.AutoCashInterval, local.AutoCashThreshold) + log.Info(fmt.Sprintf("<%v> set autocash to every %v, max uncashed limit: %v", swap.proto, local.AutoCashInterval, local.AutoCashThreshold)) } else { - log.Info(fmt.Sprintf("<%v> autocash off (not selling)", self.proto)) + log.Info(fmt.Sprintf("<%v> autocash off (not selling)", swap.proto)) } - if self.Buys { - self.Out.AutoDeposit(local.AutoDepositInterval, local.AutoDepositThreshold, local.AutoDepositBuffer) - log.Info(fmt.Sprintf("<%v> set autodeposit to every %v, pay at: %v, buffer: %v", self.proto, local.AutoDepositInterval, local.AutoDepositThreshold, local.AutoDepositBuffer)) + if swap.Buys { + swap.Out.AutoDeposit(local.AutoDepositInterval, local.AutoDepositThreshold, local.AutoDepositBuffer) + log.Info(fmt.Sprintf("<%v> set autodeposit to every %v, pay at: %v, buffer: %v", swap.proto, local.AutoDepositInterval, local.AutoDepositThreshold, local.AutoDepositBuffer)) } else { - log.Info(fmt.Sprintf("<%v> autodeposit off (not buying)", self.proto)) + log.Info(fmt.Sprintf("<%v> autodeposit off (not buying)", swap.proto)) } } -// Add(n) +// Add (n) // n > 0 called when promised/provided n units of service // n < 0 called when used/requested n units of service -func (self *Swap) Add(n int) error { - defer self.lock.Unlock() - self.lock.Lock() - self.balance += n - if !self.Sells && self.balance > 0 { - log.Trace(fmt.Sprintf("<%v> remote peer cannot have debt (balance: %v)", self.proto, self.balance)) - self.proto.Drop() - return fmt.Errorf("[SWAP] <%v> remote peer cannot have debt (balance: %v)", self.proto, self.balance) +func (swap *Swap) Add(n int) error { + defer swap.lock.Unlock() + swap.lock.Lock() + swap.balance += n + if !swap.Sells && swap.balance > 0 { + log.Trace(fmt.Sprintf("<%v> remote peer cannot have debt (balance: %v)", swap.proto, swap.balance)) + swap.proto.Drop() + return fmt.Errorf("[SWAP] <%v> remote peer cannot have debt (balance: %v)", swap.proto, swap.balance) } - if !self.Buys && self.balance < 0 { - log.Trace(fmt.Sprintf("<%v> we cannot have debt (balance: %v)", self.proto, self.balance)) - return fmt.Errorf("[SWAP] <%v> we cannot have debt (balance: %v)", self.proto, self.balance) + if !swap.Buys && swap.balance < 0 { + log.Trace(fmt.Sprintf("<%v> we cannot have debt (balance: %v)", swap.proto, swap.balance)) + return fmt.Errorf("[SWAP] <%v> we cannot have debt (balance: %v)", swap.proto, swap.balance) } - if self.balance >= int(self.local.DropAt) { - log.Trace(fmt.Sprintf("<%v> remote peer has too much debt (balance: %v, disconnect threshold: %v)", self.proto, self.balance, self.local.DropAt)) - self.proto.Drop() - return fmt.Errorf("[SWAP] <%v> remote peer has too much debt (balance: %v, disconnect threshold: %v)", self.proto, self.balance, self.local.DropAt) - } else if self.balance <= -int(self.remote.PayAt) { - self.send() + if swap.balance >= int(swap.local.DropAt) { + log.Trace(fmt.Sprintf("<%v> remote peer has too much debt (balance: %v, disconnect threshold: %v)", swap.proto, swap.balance, swap.local.DropAt)) + swap.proto.Drop() + return fmt.Errorf("[SWAP] <%v> remote peer has too much debt (balance: %v, disconnect threshold: %v)", swap.proto, swap.balance, swap.local.DropAt) + } else if swap.balance <= -int(swap.remote.PayAt) { + swap.send() } return nil } -func (self *Swap) Balance() int { - defer self.lock.Unlock() - self.lock.Lock() - return self.balance +// Balance accessor +func (swap *Swap) Balance() int { + defer swap.lock.Unlock() + swap.lock.Lock() + return swap.balance } -// send(units) is called when payment is due +// send (units) is called when payment is due // In case of insolvency no promise is issued and sent, safe against fraud // No return value: no error = payment is opportunistic = hang in till dropped -func (self *Swap) send() { - if self.local.BuyAt != nil && self.balance < 0 { - amount := big.NewInt(int64(-self.balance)) - amount.Mul(amount, self.remote.SellAt) - promise, err := self.Out.Issue(amount) +func (swap *Swap) send() { + if swap.local.BuyAt != nil && swap.balance < 0 { + amount := big.NewInt(int64(-swap.balance)) + amount.Mul(amount, swap.remote.SellAt) + promise, err := swap.Out.Issue(amount) if err != nil { - log.Warn(fmt.Sprintf("<%v> cannot issue cheque (amount: %v, channel: %v): %v", self.proto, amount, self.Out, err)) + log.Warn(fmt.Sprintf("<%v> cannot issue cheque (amount: %v, channel: %v): %v", swap.proto, amount, swap.Out, err)) } else { - log.Warn(fmt.Sprintf("<%v> cheque issued (amount: %v, channel: %v)", self.proto, amount, self.Out)) - self.proto.Pay(-self.balance, promise) - self.balance = 0 + log.Warn(fmt.Sprintf("<%v> cheque issued (amount: %v, channel: %v)", swap.proto, amount, swap.Out)) + swap.proto.Pay(-swap.balance, promise) + swap.balance = 0 } } } -// receive(units, promise) is called by the protocol when a payment msg is received +// Receive (units, promise) is called by the protocol when a payment msg is received // returns error if promise is invalid. -func (self *Swap) Receive(units int, promise Promise) error { +func (swap *Swap) Receive(units int, promise Promise) error { if units <= 0 { return fmt.Errorf("invalid units: %v <= 0", units) } price := new(big.Int).SetInt64(int64(units)) - price.Mul(price, self.local.SellAt) + price.Mul(price, swap.local.SellAt) - amount, err := self.In.Receive(promise) + amount, err := swap.In.Receive(promise) if err != nil { err = fmt.Errorf("invalid promise: %v", err) } else if price.Cmp(amount) != 0 { // verify amount = units * unit sale price - return fmt.Errorf("invalid amount: %v = %v * %v (units sent in msg * agreed sale unit price) != %v (signed in cheque)", price, units, self.local.SellAt, amount) + return fmt.Errorf("invalid amount: %v = %v * %v (units sent in msg * agreed sale unit price) != %v (signed in cheque)", price, units, swap.local.SellAt, amount) } if err != nil { - log.Trace(fmt.Sprintf("<%v> invalid promise (amount: %v, channel: %v): %v", self.proto, amount, self.In, err)) + log.Trace(fmt.Sprintf("<%v> invalid promise (amount: %v, channel: %v): %v", swap.proto, amount, swap.In, err)) return err } // credit remote peer with units - self.Add(-units) - log.Trace(fmt.Sprintf("<%v> received promise (amount: %v, channel: %v): %v", self.proto, amount, self.In, promise)) + swap.Add(-units) + log.Trace(fmt.Sprintf("<%v> received promise (amount: %v, channel: %v): %v", swap.proto, amount, swap.In, promise)) return nil } -// stop() causes autocash loop to terminate. +// Stop causes autocash loop to terminate. // Called after protocol handle loop terminates. -func (self *Swap) Stop() { - defer self.lock.Unlock() - self.lock.Lock() - if self.Buys { - self.Out.Stop() +func (swap *Swap) Stop() { + defer swap.lock.Unlock() + swap.lock.Lock() + if swap.Buys { + swap.Out.Stop() } - if self.Sells { - self.In.Stop() + if swap.Sells { + swap.In.Stop() } } diff --git a/swarm/services/swap/swap/swap_test.go b/swarm/services/swap/swap/swap_test.go index 222e0770f3..d0e34f8a54 100644 --- a/swarm/services/swap/swap/swap_test.go +++ b/swarm/services/swap/swap/swap_test.go @@ -34,20 +34,20 @@ type testPromise struct { amount *big.Int } -func (self *testInPayment) Receive(promise Promise) (*big.Int, error) { +func (test *testInPayment) Receive(promise Promise) (*big.Int, error) { p := promise.(*testPromise) - self.received = append(self.received, p) + test.received = append(test.received, p) return p.amount, nil } -func (self *testInPayment) AutoCash(interval time.Duration, limit *big.Int) { - self.autocashInterval = interval - self.autocashLimit = limit +func (test *testInPayment) AutoCash(interval time.Duration, limit *big.Int) { + test.autocashInterval = interval + test.autocashLimit = limit } -func (self *testInPayment) Cash() (string, error) { return "", nil } +func (test *testInPayment) Cash() (string, error) { return "", nil } -func (self *testInPayment) Stop() {} +func (test *testInPayment) Stop() {} type testOutPayment struct { deposits []*big.Int @@ -56,22 +56,22 @@ type testOutPayment struct { autodepositBuffer *big.Int } -func (self *testOutPayment) Issue(amount *big.Int) (promise Promise, err error) { +func (test *testOutPayment) Issue(amount *big.Int) (promise Promise, err error) { return &testPromise{amount}, nil } -func (self *testOutPayment) Deposit(amount *big.Int) (string, error) { - self.deposits = append(self.deposits, amount) +func (test *testOutPayment) Deposit(amount *big.Int) (string, error) { + test.deposits = append(test.deposits, amount) return "", nil } -func (self *testOutPayment) AutoDeposit(interval time.Duration, threshold, buffer *big.Int) { - self.autodepositInterval = interval - self.autodepositThreshold = threshold - self.autodepositBuffer = buffer +func (test *testOutPayment) AutoDeposit(interval time.Duration, threshold, buffer *big.Int) { + test.autodepositInterval = interval + test.autodepositThreshold = threshold + test.autodepositBuffer = buffer } -func (self *testOutPayment) Stop() {} +func (test *testOutPayment) Stop() {} type testProtocol struct { drop bool @@ -79,18 +79,18 @@ type testProtocol struct { promises []*testPromise } -func (self *testProtocol) Drop() { - self.drop = true +func (test *testProtocol) Drop() { + test.drop = true } -func (self *testProtocol) String() string { +func (test *testProtocol) String() string { return "" } -func (self *testProtocol) Pay(amount int, promise Promise) { +func (test *testProtocol) Pay(amount int, promise Promise) { p := promise.(*testPromise) - self.promises = append(self.promises, p) - self.amounts = append(self.amounts, amount) + test.promises = append(test.promises, p) + test.amounts = append(test.amounts, amount) } func TestSwap(t *testing.T) { diff --git a/swarm/spancontext/spancontext.go b/swarm/spancontext/spancontext.go new file mode 100644 index 0000000000..2cb9f82f7c --- /dev/null +++ b/swarm/spancontext/spancontext.go @@ -0,0 +1,49 @@ +package spancontext + +import ( + "context" + + opentracing "github.com/opentracing/opentracing-go" +) + +func WithContext(ctx context.Context, sctx opentracing.SpanContext) context.Context { + return context.WithValue(ctx, "span_context", sctx) +} + +func FromContext(ctx context.Context) opentracing.SpanContext { + sctx, ok := ctx.Value("span_context").(opentracing.SpanContext) + if ok { + return sctx + } + + return nil +} + +func StartSpan(ctx context.Context, name string) (context.Context, opentracing.Span) { + tracer := opentracing.GlobalTracer() + + sctx := FromContext(ctx) + + var sp opentracing.Span + if sctx != nil { + sp = tracer.StartSpan( + name, + opentracing.ChildOf(sctx)) + } else { + sp = tracer.StartSpan(name) + } + + nctx := context.WithValue(ctx, "span_context", sp.Context()) + + return nctx, sp +} + +func StartSpanFrom(name string, sctx opentracing.SpanContext) opentracing.Span { + tracer := opentracing.GlobalTracer() + + sp := tracer.StartSpan( + name, + opentracing.ChildOf(sctx)) + + return sp +} diff --git a/p2p/simulations/adapters/state.go b/swarm/state.go similarity index 67% rename from p2p/simulations/adapters/state.go rename to swarm/state.go index 0d4ecfb0ff..1984ab0311 100644 --- a/p2p/simulations/adapters/state.go +++ b/swarm/state.go @@ -1,4 +1,4 @@ -// Copyright 2017 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 @@ -14,23 +14,15 @@ // You should have received a copy of the GNU Lesser General Public License // along with the go-ethereum library. If not, see . -package adapters +package swarm -type SimStateStore struct { - m map[string][]byte +type Voidstore struct { } -func (self *SimStateStore) Load(s string) ([]byte, error) { - return self.m[s], nil +func (self Voidstore) Load(string) ([]byte, error) { + return nil, nil } -func (self *SimStateStore) Save(s string, data []byte) error { - self.m[s] = data +func (self Voidstore) Save(string, []byte) error { return nil } - -func NewSimStateStore() *SimStateStore { - return &SimStateStore{ - make(map[string][]byte), - } -} diff --git a/swarm/state/dbstore.go b/swarm/state/dbstore.go new file mode 100644 index 0000000000..5e5c172b25 --- /dev/null +++ b/swarm/state/dbstore.go @@ -0,0 +1,96 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package state + +import ( + "encoding" + "encoding/json" + "errors" + + "github.com/syndtr/goleveldb/leveldb" +) + +// ErrNotFound is returned when no results are returned from the database +var ErrNotFound = errors.New("ErrorNotFound") + +// ErrInvalidArgument is returned when the argument type does not match the expected type +var ErrInvalidArgument = errors.New("ErrorInvalidArgument") + +// DBStore uses LevelDB to store values. +type DBStore struct { + db *leveldb.DB +} + +// NewDBStore creates a new instance of DBStore. +func NewDBStore(path string) (s *DBStore, err error) { + db, err := leveldb.OpenFile(path, nil) + if err != nil { + return nil, err + } + return &DBStore{ + db: db, + }, nil +} + +// Get retrieves a persisted value for a specific key. If there is no results +// ErrNotFound is returned. The provided parameter should be either a byte slice or +// a struct that implements the encoding.BinaryUnmarshaler interface +func (s *DBStore) Get(key string, i interface{}) (err error) { + has, err := s.db.Has([]byte(key), nil) + if err != nil || !has { + return ErrNotFound + } + + data, err := s.db.Get([]byte(key), nil) + if err == leveldb.ErrNotFound { + return ErrNotFound + } + + unmarshaler, ok := i.(encoding.BinaryUnmarshaler) + if !ok { + return json.Unmarshal(data, i) + } + return unmarshaler.UnmarshalBinary(data) +} + +// Put stores an object that implements Binary for a specific key. +func (s *DBStore) Put(key string, i interface{}) (err error) { + bytes := []byte{} + + marshaler, ok := i.(encoding.BinaryMarshaler) + if !ok { + if bytes, err = json.Marshal(i); err != nil { + return err + } + } else { + if bytes, err = marshaler.MarshalBinary(); err != nil { + return err + } + } + + return s.db.Put([]byte(key), bytes, nil) +} + +// Delete removes entries stored under a specific key. +func (s *DBStore) Delete(key string) (err error) { + return s.db.Delete([]byte(key), nil) +} + +// Close releases the resources used by the underlying LevelDB. +func (s *DBStore) Close() error { + return s.db.Close() +} diff --git a/swarm/state/dbstore_test.go b/swarm/state/dbstore_test.go new file mode 100644 index 0000000000..6683e788f7 --- /dev/null +++ b/swarm/state/dbstore_test.go @@ -0,0 +1,122 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package state + +import ( + "bytes" + "errors" + "io/ioutil" + "os" + "strings" + "testing" +) + +var ErrInvalidArraySize = errors.New("invalid byte array size") +var ErrInvalidValuePersisted = errors.New("invalid value was persisted to the db") + +type SerializingType struct { + key string + value string +} + +func (st *SerializingType) MarshalBinary() (data []byte, err error) { + d := []byte(strings.Join([]string{st.key, st.value}, ";")) + + return d, nil +} + +func (st *SerializingType) UnmarshalBinary(data []byte) (err error) { + d := bytes.Split(data, []byte(";")) + l := len(d) + if l == 0 { + return ErrInvalidArraySize + } + if l == 2 { + keyLen := len(d[0]) + st.key = string(d[0][:keyLen]) + + valLen := len(d[1]) + st.value = string(d[1][:valLen]) + } + + return nil +} + +// TestDBStore tests basic functionality of DBStore. +func TestDBStore(t *testing.T) { + dir, err := ioutil.TempDir("", "db_store_test") + if err != nil { + panic(err) + } + defer os.RemoveAll(dir) + + store, err := NewDBStore(dir) + if err != nil { + t.Fatal(err) + } + + testStore(t, store) + + store.Close() + + persistedStore, err := NewDBStore(dir) + if err != nil { + t.Fatal(err) + } + defer persistedStore.Close() + + testPersistedStore(t, persistedStore) +} + +func testStore(t *testing.T, store Store) { + ser := &SerializingType{key: "key1", value: "value1"} + jsonify := []string{"a", "b", "c"} + + err := store.Put(ser.key, ser) + if err != nil { + t.Fatal(err) + } + + err = store.Put("key2", jsonify) + if err != nil { + t.Fatal(err) + } + +} + +func testPersistedStore(t *testing.T, store Store) { + ser := &SerializingType{} + + err := store.Get("key1", ser) + if err != nil { + t.Fatal(err) + } + + if ser.key != "key1" || ser.value != "value1" { + t.Fatal(ErrInvalidValuePersisted) + } + + as := []string{} + err = store.Get("key2", &as) + + if len(as) != 3 { + t.Fatalf("serialized array did not match expectation") + } + if as[0] != "a" || as[1] != "b" || as[2] != "c" { + t.Fatalf("elements serialized did not match expected values") + } +} diff --git a/swarm/state/inmemorystore.go b/swarm/state/inmemorystore.go new file mode 100644 index 0000000000..1ca25404a1 --- /dev/null +++ b/swarm/state/inmemorystore.go @@ -0,0 +1,94 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package state + +import ( + "encoding" + "encoding/json" + "sync" +) + +// InmemoryStore is the reference implementation of Store interface that is supposed +// to be used in tests. +type InmemoryStore struct { + db map[string][]byte + mu sync.RWMutex +} + +// NewInmemoryStore returns a new instance of InmemoryStore. +func NewInmemoryStore() *InmemoryStore { + return &InmemoryStore{ + db: make(map[string][]byte), + } +} + +// Get retrieves a value stored for a specific key. If there is no value found, +// ErrNotFound is returned. +func (s *InmemoryStore) Get(key string, i interface{}) (err error) { + s.mu.RLock() + defer s.mu.RUnlock() + + bytes, ok := s.db[key] + if !ok { + return ErrNotFound + } + + unmarshaler, ok := i.(encoding.BinaryUnmarshaler) + if !ok { + return json.Unmarshal(bytes, i) + } + + return unmarshaler.UnmarshalBinary(bytes) +} + +// Put stores a value for a specific key. +func (s *InmemoryStore) Put(key string, i interface{}) (err error) { + s.mu.Lock() + defer s.mu.Unlock() + bytes := []byte{} + + marshaler, ok := i.(encoding.BinaryMarshaler) + if !ok { + if bytes, err = json.Marshal(i); err != nil { + return err + } + } else { + if bytes, err = marshaler.MarshalBinary(); err != nil { + return err + } + } + + s.db[key] = bytes + return nil +} + +// Delete removes value stored under a specific key. +func (s *InmemoryStore) Delete(key string) (err error) { + s.mu.Lock() + defer s.mu.Unlock() + + if _, ok := s.db[key]; !ok { + return ErrNotFound + } + delete(s.db, key) + return nil +} + +// Close does not do anything. +func (s *InmemoryStore) Close() error { + return nil +} diff --git a/swarm/state/store.go b/swarm/state/store.go new file mode 100644 index 0000000000..fb7fe258f1 --- /dev/null +++ b/swarm/state/store.go @@ -0,0 +1,26 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package state + +// Store defines methods required to get, set, delete values for different keys +// and close the underlying resources. +type Store interface { + Get(key string, i interface{}) (err error) + Put(key string, i interface{}) (err error) + Delete(key string) (err error) + Close() error +} diff --git a/swarm/storage/chunker.go b/swarm/storage/chunker.go index 2b397f8010..b9b5022734 100644 --- a/swarm/storage/chunker.go +++ b/swarm/storage/chunker.go @@ -13,10 +13,10 @@ // // You should have received a copy of the GNU Lesser General Public License // along with the go-ethereum library. If not, see . - package storage import ( + "context" "encoding/binary" "errors" "fmt" @@ -25,6 +25,10 @@ import ( "time" "github.com/ethereum/go-ethereum/metrics" + "github.com/ethereum/go-ethereum/swarm/log" + "github.com/ethereum/go-ethereum/swarm/spancontext" + opentracing "github.com/opentracing/opentracing-go" + olog "github.com/opentracing/opentracing-go/log" ) /* @@ -65,129 +69,220 @@ var ( errOperationTimedOut = errors.New("operation timed out") ) -//metrics variables -var ( - newChunkCounter = metrics.NewRegisteredCounter("storage.chunks.new", nil) +const ( + DefaultChunkSize int64 = 4096 ) +type ChunkerParams struct { + chunkSize int64 + hashSize int64 +} + +type SplitterParams struct { + ChunkerParams + reader io.Reader + putter Putter + addr Address +} + +type TreeSplitterParams struct { + SplitterParams + size int64 +} + +type JoinerParams struct { + ChunkerParams + addr Address + getter Getter + // TODO: there is a bug, so depth can only be 0 today, see: https://github.com/ethersphere/go-ethereum/issues/344 + depth int + ctx context.Context +} + type TreeChunker struct { + ctx context.Context + branches int64 hashFunc SwarmHasher + dataSize int64 + data io.Reader // calculated + addr Address + depth int hashSize int64 // self.hashFunc.New().Size() chunkSize int64 // hashSize* branches workerCount int64 // the number of worker routines used workerLock sync.RWMutex // lock for the worker count + jobC chan *hashJob + wg *sync.WaitGroup + putter Putter + getter Getter + errC chan error + quitC chan bool } -func NewTreeChunker(params *ChunkerParams) (self *TreeChunker) { - self = &TreeChunker{} - self.hashFunc = MakeHashFunc(params.Hash) - self.branches = params.Branches - self.hashSize = int64(self.hashFunc().Size()) - self.chunkSize = self.hashSize * self.branches - self.workerCount = 0 +/* + Join reconstructs original content based on a root key. + When joining, the caller gets returned a Lazy SectionReader, which is + seekable and implements on-demand fetching of chunks as and where it is read. + New chunks to retrieve are coming from the getter, which the caller provides. + If an error is encountered during joining, it appears as a reader error. + The SectionReader. + As a result, partial reads from a document are possible even if other parts + are corrupt or lost. + The chunks are not meant to be validated by the chunker when joining. This + is because it is left to the DPA to decide which sources are trusted. +*/ +func TreeJoin(ctx context.Context, addr Address, getter Getter, depth int) *LazyChunkReader { + jp := &JoinerParams{ + ChunkerParams: ChunkerParams{ + chunkSize: DefaultChunkSize, + hashSize: int64(len(addr)), + }, + addr: addr, + getter: getter, + depth: depth, + ctx: ctx, + } - return + return NewTreeJoiner(jp).Join(ctx) } -// func (self *TreeChunker) KeySize() int64 { -// return self.hashSize -// } +/* + When splitting, data is given as a SectionReader, and the key is a hashSize long byte slice (Key), the root hash of the entire content will fill this once processing finishes. + New chunks to store are store using the putter which the caller provides. +*/ +func TreeSplit(ctx context.Context, data io.Reader, size int64, putter Putter) (k Address, wait func(context.Context) error, err error) { + tsp := &TreeSplitterParams{ + SplitterParams: SplitterParams{ + ChunkerParams: ChunkerParams{ + chunkSize: DefaultChunkSize, + hashSize: putter.RefSize(), + }, + reader: data, + putter: putter, + }, + size: size, + } + return NewTreeSplitter(tsp).Split(ctx) +} + +func NewTreeJoiner(params *JoinerParams) *TreeChunker { + tc := &TreeChunker{} + tc.hashSize = params.hashSize + tc.branches = params.chunkSize / params.hashSize + tc.addr = params.addr + tc.getter = params.getter + tc.depth = params.depth + tc.chunkSize = params.chunkSize + tc.workerCount = 0 + tc.jobC = make(chan *hashJob, 2*ChunkProcessors) + tc.wg = &sync.WaitGroup{} + tc.errC = make(chan error) + tc.quitC = make(chan bool) + + tc.ctx = params.ctx + + return tc +} + +func NewTreeSplitter(params *TreeSplitterParams) *TreeChunker { + tc := &TreeChunker{} + tc.data = params.reader + tc.dataSize = params.size + tc.hashSize = params.hashSize + tc.branches = params.chunkSize / params.hashSize + tc.addr = params.addr + tc.chunkSize = params.chunkSize + tc.putter = params.putter + tc.workerCount = 0 + tc.jobC = make(chan *hashJob, 2*ChunkProcessors) + tc.wg = &sync.WaitGroup{} + tc.errC = make(chan error) + tc.quitC = make(chan bool) + + return tc +} // String() for pretty printing -func (self *Chunk) String() string { - return fmt.Sprintf("Key: %v TreeSize: %v Chunksize: %v", self.Key.Log(), self.Size, len(self.SData)) +func (c *Chunk) String() string { + return fmt.Sprintf("Key: %v TreeSize: %v Chunksize: %v", c.Addr.Log(), c.Size, len(c.SData)) } type hashJob struct { - key Key + key Address chunk []byte size int64 parentWg *sync.WaitGroup } -func (self *TreeChunker) incrementWorkerCount() { - self.workerLock.Lock() - defer self.workerLock.Unlock() - self.workerCount += 1 +func (tc *TreeChunker) incrementWorkerCount() { + tc.workerLock.Lock() + defer tc.workerLock.Unlock() + tc.workerCount += 1 } -func (self *TreeChunker) getWorkerCount() int64 { - self.workerLock.RLock() - defer self.workerLock.RUnlock() - return self.workerCount +func (tc *TreeChunker) getWorkerCount() int64 { + tc.workerLock.RLock() + defer tc.workerLock.RUnlock() + return tc.workerCount } -func (self *TreeChunker) decrementWorkerCount() { - self.workerLock.Lock() - defer self.workerLock.Unlock() - self.workerCount -= 1 +func (tc *TreeChunker) decrementWorkerCount() { + tc.workerLock.Lock() + defer tc.workerLock.Unlock() + tc.workerCount -= 1 } -func (self *TreeChunker) Split(data io.Reader, size int64, chunkC chan *Chunk, swg, wwg *sync.WaitGroup) (Key, error) { - if self.chunkSize <= 0 { +func (tc *TreeChunker) Split(ctx context.Context) (k Address, wait func(context.Context) error, err error) { + if tc.chunkSize <= 0 { panic("chunker must be initialised") } - jobC := make(chan *hashJob, 2*ChunkProcessors) - wg := &sync.WaitGroup{} - errC := make(chan error) - quitC := make(chan bool) - - // wwg = workers waitgroup keeps track of hashworkers spawned by this split call - if wwg != nil { - wwg.Add(1) - } - - self.incrementWorkerCount() - go self.hashWorker(jobC, chunkC, errC, quitC, swg, wwg) + tc.runWorker() depth := 0 - treeSize := self.chunkSize + treeSize := tc.chunkSize // takes lowest depth such that chunksize*HashCount^(depth+1) > size // power series, will find the order of magnitude of the data size in base hashCount or numbers of levels of branching in the resulting tree. - for ; treeSize < size; treeSize *= self.branches { + for ; treeSize < tc.dataSize; treeSize *= tc.branches { depth++ } - key := make([]byte, self.hashFunc().Size()) + key := make([]byte, tc.hashSize) // this waitgroup member is released after the root hash is calculated - wg.Add(1) + tc.wg.Add(1) //launch actual recursive function passing the waitgroups - go self.split(depth, treeSize/self.branches, key, data, size, jobC, chunkC, errC, quitC, wg, swg, wwg) + go tc.split(depth, treeSize/tc.branches, key, tc.dataSize, tc.wg) // closes internal error channel if all subprocesses in the workgroup finished go func() { // waiting for all threads to finish - wg.Wait() - // if storage waitgroup is non-nil, we wait for storage to finish too - if swg != nil { - swg.Wait() - } - close(errC) + tc.wg.Wait() + close(tc.errC) }() - defer close(quitC) + defer close(tc.quitC) + defer tc.putter.Close() select { - case err := <-errC: + case err := <-tc.errC: if err != nil { - return nil, err + return nil, nil, err } case <-time.NewTimer(splitTimeout).C: - return nil, errOperationTimedOut + return nil, nil, errOperationTimedOut } - return key, nil + return key, tc.putter.Wait, nil } -func (self *TreeChunker) split(depth int, treeSize int64, key Key, data io.Reader, size int64, jobC chan *hashJob, chunkC chan *Chunk, errC chan error, quitC chan bool, parentWg, swg, wwg *sync.WaitGroup) { +func (tc *TreeChunker) split(depth int, treeSize int64, addr Address, size int64, parentWg *sync.WaitGroup) { // for depth > 0 && size < treeSize { - treeSize /= self.branches + treeSize /= tc.branches depth-- } @@ -197,16 +292,16 @@ func (self *TreeChunker) split(depth int, treeSize int64, key Key, data io.Reade binary.LittleEndian.PutUint64(chunkData[0:8], uint64(size)) var readBytes int64 for readBytes < size { - n, err := data.Read(chunkData[8+readBytes:]) + n, err := tc.data.Read(chunkData[8+readBytes:]) readBytes += int64(n) if err != nil && !(err == io.EOF && readBytes == size) { - errC <- err + tc.errC <- err return } } select { - case jobC <- &hashJob{key, chunkData, size, parentWg}: - case <-quitC: + case tc.jobC <- &hashJob{addr, chunkData, size, parentWg}: + case <-tc.quitC: } return } @@ -214,7 +309,7 @@ func (self *TreeChunker) split(depth int, treeSize int64, key Key, data io.Reade // intermediate chunk containing child nodes hashes branchCnt := (size + treeSize - 1) / treeSize - var chunk = make([]byte, branchCnt*self.hashSize+8) + var chunk = make([]byte, branchCnt*tc.hashSize+8) var pos, i int64 binary.LittleEndian.PutUint64(chunk[0:8], uint64(size)) @@ -229,10 +324,10 @@ func (self *TreeChunker) split(depth int, treeSize int64, key Key, data io.Reade secSize = treeSize } // the hash of that data - subTreeKey := chunk[8+i*self.hashSize : 8+(i+1)*self.hashSize] + subTreeKey := chunk[8+i*tc.hashSize : 8+(i+1)*tc.hashSize] childrenWg.Add(1) - self.split(depth-1, treeSize/self.branches, subTreeKey, data, secSize, jobC, chunkC, errC, quitC, childrenWg, swg, wwg) + tc.split(depth-1, treeSize/tc.branches, subTreeKey, secSize, childrenWg) i++ pos += treeSize @@ -242,135 +337,133 @@ func (self *TreeChunker) split(depth int, treeSize int64, key Key, data io.Reade // go func() { childrenWg.Wait() - worker := self.getWorkerCount() - if int64(len(jobC)) > worker && worker < ChunkProcessors { - if wwg != nil { - wwg.Add(1) - } - self.incrementWorkerCount() - go self.hashWorker(jobC, chunkC, errC, quitC, swg, wwg) + worker := tc.getWorkerCount() + if int64(len(tc.jobC)) > worker && worker < ChunkProcessors { + tc.runWorker() } select { - case jobC <- &hashJob{key, chunk, size, parentWg}: - case <-quitC: + case tc.jobC <- &hashJob{addr, chunk, size, parentWg}: + case <-tc.quitC: } } -func (self *TreeChunker) hashWorker(jobC chan *hashJob, chunkC chan *Chunk, errC chan error, quitC chan bool, swg, wwg *sync.WaitGroup) { - defer self.decrementWorkerCount() +func (tc *TreeChunker) runWorker() { + tc.incrementWorkerCount() + go func() { + defer tc.decrementWorkerCount() + for { + select { - hasher := self.hashFunc() - if wwg != nil { - defer wwg.Done() - } - for { - select { + case job, ok := <-tc.jobC: + if !ok { + return + } - case job, ok := <-jobC: - if !ok { + h, err := tc.putter.Put(tc.ctx, job.chunk) + if err != nil { + tc.errC <- err + return + } + copy(job.key, h) + job.parentWg.Done() + case <-tc.quitC: return } - // now we got the hashes in the chunk, then hash the chunks - self.hashChunk(hasher, job, chunkC, swg) - case <-quitC: - return } - } + }() } -// The treeChunkers own Hash hashes together -// - the size (of the subtree encoded in the Chunk) -// - the Chunk, ie. the contents read from the input reader -func (self *TreeChunker) hashChunk(hasher SwarmHash, job *hashJob, chunkC chan *Chunk, swg *sync.WaitGroup) { - hasher.ResetWithLength(job.chunk[:8]) // 8 bytes of length - hasher.Write(job.chunk[8:]) // minus 8 []byte length - h := hasher.Sum(nil) - - newChunk := &Chunk{ - Key: h, - SData: job.chunk, - Size: job.size, - wg: swg, - } - - // report hash of this chunk one level up (keys corresponds to the proper subslice of the parent chunk) - copy(job.key, h) - // send off new chunk to storage - if chunkC != nil { - if swg != nil { - swg.Add(1) - } - } - job.parentWg.Done() - - if chunkC != nil { - //NOTE: this increases the chunk count even if the local node already has this chunk; - //on file upload the node will increase this counter even if the same file has already been uploaded - //So it should be evaluated whether it is worth keeping this counter - //and/or actually better track when the chunk is Put to the local database - //(which may question the need for disambiguation when a completely new chunk has been created - //and/or a chunk is being put to the local DB; for chunk tracking it may be worth distinguishing - newChunkCounter.Inc(1) - chunkC <- newChunk - } -} - -func (self *TreeChunker) Append(key Key, data io.Reader, chunkC chan *Chunk, swg, wwg *sync.WaitGroup) (Key, error) { - return nil, errAppendOppNotSuported +func (tc *TreeChunker) Append() (Address, func(), error) { + return nil, nil, errAppendOppNotSuported } // LazyChunkReader implements LazySectionReader type LazyChunkReader struct { - key Key // root key - chunkC chan *Chunk // chunk channel to send retrieve requests on - chunk *Chunk // size of the entire subtree - off int64 // offset - chunkSize int64 // inherit from chunker - branches int64 // inherit from chunker - hashSize int64 // inherit from chunker + Ctx context.Context + key Address // root key + chunkData ChunkData + off int64 // offset + chunkSize int64 // inherit from chunker + branches int64 // inherit from chunker + hashSize int64 // inherit from chunker + depth int + getter Getter } -// implements the Joiner interface -func (self *TreeChunker) Join(key Key, chunkC chan *Chunk) LazySectionReader { +func (tc *TreeChunker) Join(ctx context.Context) *LazyChunkReader { return &LazyChunkReader{ - key: key, - chunkC: chunkC, - chunkSize: self.chunkSize, - branches: self.branches, - hashSize: self.hashSize, + key: tc.addr, + chunkSize: tc.chunkSize, + branches: tc.branches, + hashSize: tc.hashSize, + depth: tc.depth, + getter: tc.getter, + Ctx: tc.ctx, } } +func (r *LazyChunkReader) Context() context.Context { + return r.Ctx +} + // Size is meant to be called on the LazySectionReader -func (self *LazyChunkReader) Size(quitC chan bool) (n int64, err error) { - if self.chunk != nil { - return self.chunk.Size, nil - } - chunk := retrieve(self.key, self.chunkC, quitC) - if chunk == nil { - select { - case <-quitC: - return 0, errors.New("aborted") - default: - return 0, fmt.Errorf("root chunk not found for %v", self.key.Hex()) +func (r *LazyChunkReader) Size(ctx context.Context, quitC chan bool) (n int64, err error) { + metrics.GetOrRegisterCounter("lazychunkreader.size", nil).Inc(1) + + var sp opentracing.Span + var cctx context.Context + cctx, sp = spancontext.StartSpan( + ctx, + "lcr.size") + defer sp.Finish() + + log.Debug("lazychunkreader.size", "key", r.key) + if r.chunkData == nil { + chunkData, err := r.getter.Get(cctx, Reference(r.key)) + if err != nil { + return 0, err } + if chunkData == nil { + select { + case <-quitC: + return 0, errors.New("aborted") + default: + return 0, fmt.Errorf("root chunk not found for %v", r.key.Hex()) + } + } + r.chunkData = chunkData } - self.chunk = chunk - return chunk.Size, nil + return r.chunkData.Size(), nil } // read at can be called numerous times // concurrent reads are allowed // Size() needs to be called synchronously on the LazyChunkReader first -func (self *LazyChunkReader) ReadAt(b []byte, off int64) (read int, err error) { +func (r *LazyChunkReader) ReadAt(b []byte, off int64) (read int, err error) { + metrics.GetOrRegisterCounter("lazychunkreader.readat", nil).Inc(1) + + var sp opentracing.Span + var cctx context.Context + cctx, sp = spancontext.StartSpan( + r.Ctx, + "lcr.read") + defer sp.Finish() + + defer func() { + sp.LogFields( + olog.Int("off", int(off)), + olog.Int("read", read)) + }() + // this is correct, a swarm doc cannot be zero length, so no EOF is expected if len(b) == 0 { return 0, nil } quitC := make(chan bool) - size, err := self.Size(quitC) + size, err := r.Size(cctx, quitC) if err != nil { + log.Error("lazychunkreader.readat.size", "size", size, "err", err) return 0, err } @@ -380,13 +473,18 @@ func (self *LazyChunkReader) ReadAt(b []byte, off int64) (read int, err error) { var treeSize int64 var depth int // calculate depth and max treeSize - treeSize = self.chunkSize - for ; treeSize < size; treeSize *= self.branches { + treeSize = r.chunkSize + for ; treeSize < size; treeSize *= r.branches { depth++ } wg := sync.WaitGroup{} + length := int64(len(b)) + for d := 0; d < r.depth; d++ { + off *= r.chunkSize + length *= r.chunkSize + } wg.Add(1) - go self.join(b, off, off+int64(len(b)), depth, treeSize/self.branches, self.chunk, &wg, errC, quitC) + go r.join(cctx, b, off, off+length, depth, treeSize/r.branches, r.chunkData, &wg, errC, quitC) go func() { wg.Wait() close(errC) @@ -394,35 +492,31 @@ func (self *LazyChunkReader) ReadAt(b []byte, off int64) (read int, err error) { err = <-errC if err != nil { + log.Error("lazychunkreader.readat.errc", "err", err) close(quitC) - return 0, err } if off+int64(len(b)) >= size { - return len(b), io.EOF + return int(size - off), io.EOF } return len(b), nil } -func (self *LazyChunkReader) join(b []byte, off int64, eoff int64, depth int, treeSize int64, chunk *Chunk, parentWg *sync.WaitGroup, errC chan error, quitC chan bool) { +func (r *LazyChunkReader) join(ctx context.Context, b []byte, off int64, eoff int64, depth int, treeSize int64, chunkData ChunkData, parentWg *sync.WaitGroup, errC chan error, quitC chan bool) { defer parentWg.Done() - // return NewDPA(&LocalStore{}) - - // chunk.Size = int64(binary.LittleEndian.Uint64(chunk.SData[0:8])) - // find appropriate block level - for chunk.Size < treeSize && depth > 0 { - treeSize /= self.branches + for chunkData.Size() < treeSize && depth > r.depth { + treeSize /= r.branches depth-- } // leaf chunk found - if depth == 0 { - extra := 8 + eoff - int64(len(chunk.SData)) + if depth == r.depth { + extra := 8 + eoff - int64(len(chunkData)) if extra > 0 { eoff -= extra } - copy(b, chunk.SData[8+off:8+eoff]) + copy(b, chunkData[8+off:8+eoff]) return // simply give back the chunks reader for content chunks } @@ -430,9 +524,14 @@ func (self *LazyChunkReader) join(b []byte, off int64, eoff int64, depth int, tr start := off / treeSize end := (eoff + treeSize - 1) / treeSize + // last non-leaf chunk can be shorter than default chunk size, let's not read it further then its end + currentBranches := int64(len(chunkData)-8) / r.hashSize + if end > currentBranches { + end = currentBranches + } + wg := &sync.WaitGroup{} defer wg.Wait() - for i := start; i < end; i++ { soff := i * treeSize roff := soff @@ -449,11 +548,19 @@ func (self *LazyChunkReader) join(b []byte, off int64, eoff int64, depth int, tr } wg.Add(1) go func(j int64) { - childKey := chunk.SData[8+j*self.hashSize : 8+(j+1)*self.hashSize] - chunk := retrieve(childKey, self.chunkC, quitC) - if chunk == nil { + childKey := chunkData[8+j*r.hashSize : 8+(j+1)*r.hashSize] + chunkData, err := r.getter.Get(ctx, Reference(childKey)) + if err != nil { + log.Error("lazychunkreader.join", "key", fmt.Sprintf("%x", childKey), "err", err) select { - case errC <- fmt.Errorf("chunk %v-%v not found", off, off+treeSize): + case errC <- fmt.Errorf("chunk %v-%v not found; key: %s", off, off+treeSize, fmt.Sprintf("%x", childKey)): + case <-quitC: + } + return + } + if l := len(chunkData); l < 9 { + select { + case errC <- fmt.Errorf("chunk %v-%v incomplete; key: %s, data length %v", off, off+treeSize, fmt.Sprintf("%x", childKey), l): case <-quitC: } return @@ -461,45 +568,25 @@ func (self *LazyChunkReader) join(b []byte, off int64, eoff int64, depth int, tr if soff < off { soff = off } - self.join(b[soff-off:seoff-off], soff-roff, seoff-roff, depth-1, treeSize/self.branches, chunk, wg, errC, quitC) + r.join(ctx, b[soff-off:seoff-off], soff-roff, seoff-roff, depth-1, treeSize/r.branches, chunkData, wg, errC, quitC) }(i) } //for } -// the helper method submits chunks for a key to a oueue (DPA) and -// block until they time out or arrive -// abort if quitC is readable -func retrieve(key Key, chunkC chan *Chunk, quitC chan bool) *Chunk { - chunk := &Chunk{ - Key: key, - C: make(chan bool), // close channel to signal data delivery - } - // submit chunk for retrieval - select { - case chunkC <- chunk: // submit retrieval request, someone should be listening on the other side (or we will time out globally) - case <-quitC: - return nil - } - // waiting for the chunk retrieval - select { // chunk.Size = int64(binary.LittleEndian.Uint64(chunk.SData[0:8])) - - case <-quitC: - // this is how we control process leakage (quitC is closed once join is finished (after timeout)) - return nil - case <-chunk.C: // bells are ringing, data have been delivered - } - if len(chunk.SData) == 0 { - return nil // chunk.Size = int64(binary.LittleEndian.Uint64(chunk.SData[0:8])) - - } - return chunk -} - // Read keeps a cursor so cannot be called simulateously, see ReadAt -func (self *LazyChunkReader) Read(b []byte) (read int, err error) { - read, err = self.ReadAt(b, self.off) +func (r *LazyChunkReader) Read(b []byte) (read int, err error) { + log.Debug("lazychunkreader.read", "key", r.key) + metrics.GetOrRegisterCounter("lazychunkreader.read", nil).Inc(1) - self.off += int64(read) + read, err = r.ReadAt(b, r.off) + if err != nil && err != io.EOF { + log.Error("lazychunkreader.readat", "read", read, "err", err) + metrics.GetOrRegisterCounter("lazychunkreader.read.err", nil).Inc(1) + } + + metrics.GetOrRegisterCounter("lazychunkreader.read.bytes", nil).Inc(int64(read)) + + r.off += int64(read) return } @@ -507,27 +594,28 @@ func (self *LazyChunkReader) Read(b []byte) (read int, err error) { var errWhence = errors.New("Seek: invalid whence") var errOffset = errors.New("Seek: invalid offset") -func (s *LazyChunkReader) Seek(offset int64, whence int) (int64, error) { +func (r *LazyChunkReader) Seek(offset int64, whence int) (int64, error) { + log.Debug("lazychunkreader.seek", "key", r.key, "offset", offset) switch whence { default: return 0, errWhence case 0: offset += 0 case 1: - offset += s.off + offset += r.off case 2: - if s.chunk == nil { //seek from the end requires rootchunk for size. call Size first - _, err := s.Size(nil) + if r.chunkData == nil { //seek from the end requires rootchunk for size. call Size first + _, err := r.Size(context.TODO(), nil) if err != nil { return 0, fmt.Errorf("can't get size: %v", err) } } - offset += s.chunk.Size + offset += r.chunkData.Size() } if offset < 0 { return 0, errOffset } - s.off = offset + r.off = offset return offset, nil } diff --git a/swarm/storage/chunker_test.go b/swarm/storage/chunker_test.go index c8bd12299a..dbcc8700d1 100644 --- a/swarm/storage/chunker_test.go +++ b/swarm/storage/chunker_test.go @@ -18,14 +18,13 @@ package storage import ( "bytes" + "context" "crypto/rand" "encoding/binary" "errors" "fmt" "io" - "sync" "testing" - "time" "github.com/ethereum/go-ethereum/crypto/sha3" ) @@ -41,133 +40,33 @@ type test interface { type chunkerTester struct { inputs map[uint64][]byte - chunks map[string]*Chunk t test } -func (self *chunkerTester) Split(chunker Splitter, data io.Reader, size int64, chunkC chan *Chunk, swg *sync.WaitGroup, expectedError error) (key Key, err error) { - // reset - self.chunks = make(map[string]*Chunk) - - if self.inputs == nil { - self.inputs = make(map[uint64][]byte) - } - - quitC := make(chan bool) - timeout := time.After(600 * time.Second) - if chunkC != nil { - go func() error { - for { - select { - case <-timeout: - return errors.New("Split timeout error") - case <-quitC: - return nil - case chunk := <-chunkC: - // self.chunks = append(self.chunks, chunk) - self.chunks[chunk.Key.String()] = chunk - if chunk.wg != nil { - chunk.wg.Done() - } - } - - } - }() - } - - key, err = chunker.Split(data, size, chunkC, swg, nil) - if err != nil && expectedError == nil { - err = fmt.Errorf("Split error: %v", err) - } - - if chunkC != nil { - if swg != nil { - swg.Wait() - } - close(quitC) - } - return key, err +// fakeChunkStore doesn't store anything, just implements the ChunkStore interface +// It can be used to inject into a hasherStore if you don't want to actually store data just do the +// hashing +type fakeChunkStore struct { } -func (self *chunkerTester) Append(chunker Splitter, rootKey Key, data io.Reader, chunkC chan *Chunk, swg *sync.WaitGroup, expectedError error) (key Key, err error) { - quitC := make(chan bool) - timeout := time.After(60 * time.Second) - if chunkC != nil { - go func() error { - for { - select { - case <-timeout: - return errors.New("Append timeout error") - case <-quitC: - return nil - case chunk := <-chunkC: - if chunk != nil { - stored, success := self.chunks[chunk.Key.String()] - if !success { - // Requesting data - self.chunks[chunk.Key.String()] = chunk - if chunk.wg != nil { - chunk.wg.Done() - } - } else { - // getting data - chunk.SData = stored.SData - chunk.Size = int64(binary.LittleEndian.Uint64(chunk.SData[0:8])) - close(chunk.C) - } - } - } - } - }() - } - - key, err = chunker.Append(rootKey, data, chunkC, swg, nil) - if err != nil && expectedError == nil { - err = fmt.Errorf("Append error: %v", err) - } - - if chunkC != nil { - if swg != nil { - swg.Wait() - } - close(quitC) - } - return key, err +// Put doesn't store anything it is just here to implement ChunkStore +func (f *fakeChunkStore) Put(context.Context, *Chunk) { } -func (self *chunkerTester) Join(chunker Chunker, key Key, c int, chunkC chan *Chunk, quitC chan bool) LazySectionReader { - // reset but not the chunks - - reader := chunker.Join(key, chunkC) - - timeout := time.After(600 * time.Second) - i := 0 - go func() error { - for { - select { - case <-timeout: - return errors.New("Join timeout error") - case chunk, ok := <-chunkC: - if !ok { - close(quitC) - return nil - } - // this just mocks the behaviour of a chunk store retrieval - stored, success := self.chunks[chunk.Key.String()] - if !success { - return errors.New("Not found") - } - chunk.SData = stored.SData - chunk.Size = int64(binary.LittleEndian.Uint64(chunk.SData[0:8])) - close(chunk.C) - i++ - } - } - }() - return reader +// Gut doesn't store anything it is just here to implement ChunkStore +func (f *fakeChunkStore) Get(context.Context, Address) (*Chunk, error) { + return nil, errors.New("FakeChunkStore doesn't support Get") } -func testRandomBrokenData(splitter Splitter, n int, tester *chunkerTester) { +// Close doesn't store anything it is just here to implement ChunkStore +func (f *fakeChunkStore) Close() { +} + +func newTestHasherStore(chunkStore ChunkStore, hash string) *hasherStore { + return NewHasherStore(chunkStore, MakeHashFunc(hash), false) +} + +func testRandomBrokenData(n int, tester *chunkerTester) { data := io.LimitReader(rand.Reader, int64(n)) brokendata := brokenLimitReader(data, n, n/2) @@ -180,44 +79,50 @@ func testRandomBrokenData(splitter Splitter, n int, tester *chunkerTester) { data = io.LimitReader(rand.Reader, int64(n)) brokendata = brokenLimitReader(data, n, n/2) - chunkC := make(chan *Chunk, 1000) - swg := &sync.WaitGroup{} + putGetter := newTestHasherStore(NewMapChunkStore(), SHA3Hash) expectedError := fmt.Errorf("Broken reader") - key, err := tester.Split(splitter, brokendata, int64(n), chunkC, swg, expectedError) + addr, _, err := TreeSplit(context.TODO(), brokendata, int64(n), putGetter) if err == nil || err.Error() != expectedError.Error() { tester.t.Fatalf("Not receiving the correct error! Expected %v, received %v", expectedError, err) } - tester.t.Logf(" Key = %v\n", key) + tester.t.Logf(" Key = %v\n", addr) } -func testRandomData(splitter Splitter, n int, tester *chunkerTester) Key { +func testRandomData(usePyramid bool, hash string, n int, tester *chunkerTester) Address { if tester.inputs == nil { tester.inputs = make(map[uint64][]byte) } input, found := tester.inputs[uint64(n)] var data io.Reader if !found { - data, input = testDataReaderAndSlice(n) + data, input = generateRandomData(n) tester.inputs[uint64(n)] = input } else { data = io.LimitReader(bytes.NewReader(input), int64(n)) } - chunkC := make(chan *Chunk, 1000) - swg := &sync.WaitGroup{} + putGetter := newTestHasherStore(NewMapChunkStore(), hash) - key, err := tester.Split(splitter, data, int64(n), chunkC, swg, nil) + var addr Address + var wait func(context.Context) error + var err error + ctx := context.TODO() + if usePyramid { + addr, wait, err = PyramidSplit(ctx, data, putGetter, putGetter) + } else { + addr, wait, err = TreeSplit(ctx, data, int64(n), putGetter) + } + if err != nil { + tester.t.Fatalf(err.Error()) + } + tester.t.Logf(" Key = %v\n", addr) + err = wait(ctx) if err != nil { tester.t.Fatalf(err.Error()) } - tester.t.Logf(" Key = %v\n", key) - chunkC = make(chan *Chunk, 1000) - quitC := make(chan bool) - - chunker := NewTreeChunker(NewChunkerParams()) - reader := tester.Join(chunker, key, 0, chunkC, quitC) + reader := TreeJoin(context.TODO(), addr, putGetter, 0) output := make([]byte, n) r, err := reader.Read(output) if r != n || err != io.EOF { @@ -228,70 +133,23 @@ func testRandomData(splitter Splitter, n int, tester *chunkerTester) Key { tester.t.Fatalf("input and output mismatch\n IN: %v\nOUT: %v\n", input, output) } } - close(chunkC) - <-quitC - return key -} - -func testRandomDataAppend(splitter Splitter, n, m int, tester *chunkerTester) { - if tester.inputs == nil { - tester.inputs = make(map[uint64][]byte) - } - input, found := tester.inputs[uint64(n)] - var data io.Reader - if !found { - data, input = testDataReaderAndSlice(n) - tester.inputs[uint64(n)] = input - } else { - data = io.LimitReader(bytes.NewReader(input), int64(n)) + // testing partial read + for i := 1; i < n; i += 10000 { + readableLength := n - i + output := make([]byte, readableLength) + r, err := reader.ReadAt(output, int64(i)) + if r != readableLength || err != io.EOF { + tester.t.Fatalf("readAt error with offset %v read: %v n = %v err = %v\n", i, r, readableLength, err) + } + if input != nil { + if !bytes.Equal(output, input[i:]) { + tester.t.Fatalf("input and output mismatch\n IN: %v\nOUT: %v\n", input[i:], output) + } + } } - chunkC := make(chan *Chunk, 1000) - swg := &sync.WaitGroup{} - - key, err := tester.Split(splitter, data, int64(n), chunkC, swg, nil) - if err != nil { - tester.t.Fatalf(err.Error()) - } - tester.t.Logf(" Key = %v\n", key) - - //create a append data stream - appendInput, found := tester.inputs[uint64(m)] - var appendData io.Reader - if !found { - appendData, appendInput = testDataReaderAndSlice(m) - tester.inputs[uint64(m)] = appendInput - } else { - appendData = io.LimitReader(bytes.NewReader(appendInput), int64(m)) - } - - chunkC = make(chan *Chunk, 1000) - swg = &sync.WaitGroup{} - - newKey, err := tester.Append(splitter, key, appendData, chunkC, swg, nil) - if err != nil { - tester.t.Fatalf(err.Error()) - } - tester.t.Logf(" NewKey = %v\n", newKey) - - chunkC = make(chan *Chunk, 1000) - quitC := make(chan bool) - - chunker := NewTreeChunker(NewChunkerParams()) - reader := tester.Join(chunker, newKey, 0, chunkC, quitC) - newOutput := make([]byte, n+m) - r, err := reader.Read(newOutput) - if r != (n + m) { - tester.t.Fatalf("read error read: %v n = %v err = %v\n", r, n, err) - } - - newInput := append(input, appendInput...) - if !bytes.Equal(newOutput, newInput) { - tester.t.Fatalf("input and output mismatch\n IN: %v\nOUT: %v\n", newInput, newOutput) - } - - close(chunkC) + return addr } func TestSha3ForCorrectness(t *testing.T) { @@ -328,90 +186,137 @@ func TestDataAppend(t *testing.T) { appendSizes := []int{4095, 4096, 4097, 1, 1, 1, 8191, 8192, 8193, 9000, 3000, 5000} tester := &chunkerTester{t: t} - chunker := NewPyramidChunker(NewChunkerParams()) - for i, s := range sizes { - testRandomDataAppend(chunker, s, appendSizes[i], tester) + for i := range sizes { + n := sizes[i] + m := appendSizes[i] + if tester.inputs == nil { + tester.inputs = make(map[uint64][]byte) + } + input, found := tester.inputs[uint64(n)] + var data io.Reader + if !found { + data, input = generateRandomData(n) + tester.inputs[uint64(n)] = input + } else { + data = io.LimitReader(bytes.NewReader(input), int64(n)) + } + + chunkStore := NewMapChunkStore() + putGetter := newTestHasherStore(chunkStore, SHA3Hash) + + ctx := context.TODO() + addr, wait, err := PyramidSplit(ctx, data, putGetter, putGetter) + if err != nil { + tester.t.Fatalf(err.Error()) + } + err = wait(ctx) + if err != nil { + tester.t.Fatalf(err.Error()) + } + + //create a append data stream + appendInput, found := tester.inputs[uint64(m)] + var appendData io.Reader + if !found { + appendData, appendInput = generateRandomData(m) + tester.inputs[uint64(m)] = appendInput + } else { + appendData = io.LimitReader(bytes.NewReader(appendInput), int64(m)) + } + + putGetter = newTestHasherStore(chunkStore, SHA3Hash) + newAddr, wait, err := PyramidAppend(ctx, addr, appendData, putGetter, putGetter) + if err != nil { + tester.t.Fatalf(err.Error()) + } + err = wait(ctx) + if err != nil { + tester.t.Fatalf(err.Error()) + } + + reader := TreeJoin(ctx, newAddr, putGetter, 0) + newOutput := make([]byte, n+m) + r, err := reader.Read(newOutput) + if r != (n + m) { + tester.t.Fatalf("read error read: %v n = %v m = %v err = %v\n", r, n, m, err) + } + + newInput := append(input, appendInput...) + if !bytes.Equal(newOutput, newInput) { + tester.t.Fatalf("input and output mismatch\n IN: %v\nOUT: %v\n", newInput, newOutput) + } } } func TestRandomData(t *testing.T) { - sizes := []int{1, 60, 83, 179, 253, 1024, 4095, 4096, 4097, 8191, 8192, 8193, 12287, 12288, 12289, 123456, 2345678} + // This test can validate files up to a relatively short length, as tree chunker slows down drastically. + // Validation of longer files is done by TestLocalStoreAndRetrieve in swarm package. + sizes := []int{1, 60, 83, 179, 253, 1024, 4095, 4096, 4097, 8191, 8192, 8193, 12287, 12288, 12289, 524288, 524288 + 1, 524288 + 4097, 7 * 524288, 7*524288 + 1, 7*524288 + 4097} tester := &chunkerTester{t: t} - chunker := NewTreeChunker(NewChunkerParams()) - pyramid := NewPyramidChunker(NewChunkerParams()) for _, s := range sizes { - treeChunkerKey := testRandomData(chunker, s, tester) - pyramidChunkerKey := testRandomData(pyramid, s, tester) + treeChunkerKey := testRandomData(false, SHA3Hash, s, tester) + pyramidChunkerKey := testRandomData(true, SHA3Hash, s, tester) if treeChunkerKey.String() != pyramidChunkerKey.String() { tester.t.Fatalf("tree chunker and pyramid chunker key mismatch for size %v\n TC: %v\n PC: %v\n", s, treeChunkerKey.String(), pyramidChunkerKey.String()) } } - cp := NewChunkerParams() - cp.Hash = BMTHash - chunker = NewTreeChunker(cp) - pyramid = NewPyramidChunker(cp) for _, s := range sizes { - treeChunkerKey := testRandomData(chunker, s, tester) - pyramidChunkerKey := testRandomData(pyramid, s, tester) + treeChunkerKey := testRandomData(false, BMTHash, s, tester) + pyramidChunkerKey := testRandomData(true, BMTHash, s, tester) if treeChunkerKey.String() != pyramidChunkerKey.String() { - tester.t.Fatalf("tree chunker BMT and pyramid chunker BMT key mismatch for size %v \n TC: %v\n PC: %v\n", s, treeChunkerKey.String(), pyramidChunkerKey.String()) + tester.t.Fatalf("tree chunker and pyramid chunker key mismatch for size %v\n TC: %v\n PC: %v\n", s, treeChunkerKey.String(), pyramidChunkerKey.String()) } } - } -func XTestRandomBrokenData(t *testing.T) { +func TestRandomBrokenData(t *testing.T) { sizes := []int{1, 60, 83, 179, 253, 1024, 4095, 4096, 4097, 8191, 8192, 8193, 12287, 12288, 12289, 123456, 2345678} tester := &chunkerTester{t: t} - chunker := NewTreeChunker(NewChunkerParams()) for _, s := range sizes { - testRandomBrokenData(chunker, s, tester) + testRandomBrokenData(s, tester) } } func benchReadAll(reader LazySectionReader) { - size, _ := reader.Size(nil) + size, _ := reader.Size(context.TODO(), nil) output := make([]byte, 1000) for pos := int64(0); pos < size; pos += 1000 { reader.ReadAt(output, pos) } } -func benchmarkJoin(n int, t *testing.B) { +func benchmarkSplitJoin(n int, t *testing.B) { t.ReportAllocs() for i := 0; i < t.N; i++ { - chunker := NewTreeChunker(NewChunkerParams()) - tester := &chunkerTester{t: t} data := testDataReader(n) - chunkC := make(chan *Chunk, 1000) - swg := &sync.WaitGroup{} - - key, err := tester.Split(chunker, data, int64(n), chunkC, swg, nil) + putGetter := newTestHasherStore(NewMapChunkStore(), SHA3Hash) + ctx := context.TODO() + key, wait, err := PyramidSplit(ctx, data, putGetter, putGetter) if err != nil { - tester.t.Fatalf(err.Error()) + t.Fatalf(err.Error()) } - chunkC = make(chan *Chunk, 1000) - quitC := make(chan bool) - reader := tester.Join(chunker, key, i, chunkC, quitC) + err = wait(ctx) + if err != nil { + t.Fatalf(err.Error()) + } + reader := TreeJoin(ctx, key, putGetter, 0) benchReadAll(reader) - close(chunkC) - <-quitC } } func benchmarkSplitTreeSHA3(n int, t *testing.B) { t.ReportAllocs() for i := 0; i < t.N; i++ { - chunker := NewTreeChunker(NewChunkerParams()) - tester := &chunkerTester{t: t} data := testDataReader(n) - _, err := tester.Split(chunker, data, int64(n), nil, nil, nil) + putGetter := newTestHasherStore(&fakeChunkStore{}, SHA3Hash) + + _, _, err := TreeSplit(context.TODO(), data, int64(n), putGetter) if err != nil { - tester.t.Fatalf(err.Error()) + t.Fatalf(err.Error()) } } } @@ -419,14 +324,12 @@ func benchmarkSplitTreeSHA3(n int, t *testing.B) { func benchmarkSplitTreeBMT(n int, t *testing.B) { t.ReportAllocs() for i := 0; i < t.N; i++ { - cp := NewChunkerParams() - cp.Hash = BMTHash - chunker := NewTreeChunker(cp) - tester := &chunkerTester{t: t} data := testDataReader(n) - _, err := tester.Split(chunker, data, int64(n), nil, nil, nil) + putGetter := newTestHasherStore(&fakeChunkStore{}, BMTHash) + + _, _, err := TreeSplit(context.TODO(), data, int64(n), putGetter) if err != nil { - tester.t.Fatalf(err.Error()) + t.Fatalf(err.Error()) } } } @@ -434,65 +337,69 @@ func benchmarkSplitTreeBMT(n int, t *testing.B) { func benchmarkSplitPyramidSHA3(n int, t *testing.B) { t.ReportAllocs() for i := 0; i < t.N; i++ { - splitter := NewPyramidChunker(NewChunkerParams()) - tester := &chunkerTester{t: t} data := testDataReader(n) - _, err := tester.Split(splitter, data, int64(n), nil, nil, nil) + putGetter := newTestHasherStore(&fakeChunkStore{}, SHA3Hash) + + _, _, err := PyramidSplit(context.TODO(), data, putGetter, putGetter) if err != nil { - tester.t.Fatalf(err.Error()) + t.Fatalf(err.Error()) } + } } func benchmarkSplitPyramidBMT(n int, t *testing.B) { t.ReportAllocs() for i := 0; i < t.N; i++ { - cp := NewChunkerParams() - cp.Hash = BMTHash - splitter := NewPyramidChunker(cp) - tester := &chunkerTester{t: t} data := testDataReader(n) - _, err := tester.Split(splitter, data, int64(n), nil, nil, nil) + putGetter := newTestHasherStore(&fakeChunkStore{}, BMTHash) + + _, _, err := PyramidSplit(context.TODO(), data, putGetter, putGetter) if err != nil { - tester.t.Fatalf(err.Error()) + t.Fatalf(err.Error()) } } } -func benchmarkAppendPyramid(n, m int, t *testing.B) { +func benchmarkSplitAppendPyramid(n, m int, t *testing.B) { t.ReportAllocs() for i := 0; i < t.N; i++ { - chunker := NewPyramidChunker(NewChunkerParams()) - tester := &chunkerTester{t: t} data := testDataReader(n) data1 := testDataReader(m) - chunkC := make(chan *Chunk, 1000) - swg := &sync.WaitGroup{} - key, err := tester.Split(chunker, data, int64(n), chunkC, swg, nil) + chunkStore := NewMapChunkStore() + putGetter := newTestHasherStore(chunkStore, SHA3Hash) + + ctx := context.TODO() + key, wait, err := PyramidSplit(ctx, data, putGetter, putGetter) if err != nil { - tester.t.Fatalf(err.Error()) + t.Fatalf(err.Error()) + } + err = wait(ctx) + if err != nil { + t.Fatalf(err.Error()) } - chunkC = make(chan *Chunk, 1000) - swg = &sync.WaitGroup{} - - _, err = tester.Append(chunker, key, data1, chunkC, swg, nil) + putGetter = newTestHasherStore(chunkStore, SHA3Hash) + _, wait, err = PyramidAppend(ctx, key, data1, putGetter, putGetter) if err != nil { - tester.t.Fatalf(err.Error()) + t.Fatalf(err.Error()) + } + err = wait(ctx) + if err != nil { + t.Fatalf(err.Error()) } - - close(chunkC) } } -func BenchmarkJoin_2(t *testing.B) { benchmarkJoin(100, t) } -func BenchmarkJoin_3(t *testing.B) { benchmarkJoin(1000, t) } -func BenchmarkJoin_4(t *testing.B) { benchmarkJoin(10000, t) } -func BenchmarkJoin_5(t *testing.B) { benchmarkJoin(100000, t) } -func BenchmarkJoin_6(t *testing.B) { benchmarkJoin(1000000, t) } -func BenchmarkJoin_7(t *testing.B) { benchmarkJoin(10000000, t) } -func BenchmarkJoin_8(t *testing.B) { benchmarkJoin(100000000, t) } +func BenchmarkSplitJoin_2(t *testing.B) { benchmarkSplitJoin(100, t) } +func BenchmarkSplitJoin_3(t *testing.B) { benchmarkSplitJoin(1000, t) } +func BenchmarkSplitJoin_4(t *testing.B) { benchmarkSplitJoin(10000, t) } +func BenchmarkSplitJoin_5(t *testing.B) { benchmarkSplitJoin(100000, t) } +func BenchmarkSplitJoin_6(t *testing.B) { benchmarkSplitJoin(1000000, t) } +func BenchmarkSplitJoin_7(t *testing.B) { benchmarkSplitJoin(10000000, t) } + +// func BenchmarkSplitJoin_8(t *testing.B) { benchmarkJoin(100000000, t) } func BenchmarkSplitTreeSHA3_2(t *testing.B) { benchmarkSplitTreeSHA3(100, t) } func BenchmarkSplitTreeSHA3_2h(t *testing.B) { benchmarkSplitTreeSHA3(500, t) } @@ -503,7 +410,8 @@ func BenchmarkSplitTreeSHA3_4h(t *testing.B) { benchmarkSplitTreeSHA3(50000, t) func BenchmarkSplitTreeSHA3_5(t *testing.B) { benchmarkSplitTreeSHA3(100000, t) } func BenchmarkSplitTreeSHA3_6(t *testing.B) { benchmarkSplitTreeSHA3(1000000, t) } func BenchmarkSplitTreeSHA3_7(t *testing.B) { benchmarkSplitTreeSHA3(10000000, t) } -func BenchmarkSplitTreeSHA3_8(t *testing.B) { benchmarkSplitTreeSHA3(100000000, t) } + +// func BenchmarkSplitTreeSHA3_8(t *testing.B) { benchmarkSplitTreeSHA3(100000000, t) } func BenchmarkSplitTreeBMT_2(t *testing.B) { benchmarkSplitTreeBMT(100, t) } func BenchmarkSplitTreeBMT_2h(t *testing.B) { benchmarkSplitTreeBMT(500, t) } @@ -514,7 +422,8 @@ func BenchmarkSplitTreeBMT_4h(t *testing.B) { benchmarkSplitTreeBMT(50000, t) } func BenchmarkSplitTreeBMT_5(t *testing.B) { benchmarkSplitTreeBMT(100000, t) } func BenchmarkSplitTreeBMT_6(t *testing.B) { benchmarkSplitTreeBMT(1000000, t) } func BenchmarkSplitTreeBMT_7(t *testing.B) { benchmarkSplitTreeBMT(10000000, t) } -func BenchmarkSplitTreeBMT_8(t *testing.B) { benchmarkSplitTreeBMT(100000000, t) } + +// func BenchmarkSplitTreeBMT_8(t *testing.B) { benchmarkSplitTreeBMT(100000000, t) } func BenchmarkSplitPyramidSHA3_2(t *testing.B) { benchmarkSplitPyramidSHA3(100, t) } func BenchmarkSplitPyramidSHA3_2h(t *testing.B) { benchmarkSplitPyramidSHA3(500, t) } @@ -525,7 +434,8 @@ func BenchmarkSplitPyramidSHA3_4h(t *testing.B) { benchmarkSplitPyramidSHA3(5000 func BenchmarkSplitPyramidSHA3_5(t *testing.B) { benchmarkSplitPyramidSHA3(100000, t) } func BenchmarkSplitPyramidSHA3_6(t *testing.B) { benchmarkSplitPyramidSHA3(1000000, t) } func BenchmarkSplitPyramidSHA3_7(t *testing.B) { benchmarkSplitPyramidSHA3(10000000, t) } -func BenchmarkSplitPyramidSHA3_8(t *testing.B) { benchmarkSplitPyramidSHA3(100000000, t) } + +// func BenchmarkSplitPyramidSHA3_8(t *testing.B) { benchmarkSplitPyramidSHA3(100000000, t) } func BenchmarkSplitPyramidBMT_2(t *testing.B) { benchmarkSplitPyramidBMT(100, t) } func BenchmarkSplitPyramidBMT_2h(t *testing.B) { benchmarkSplitPyramidBMT(500, t) } @@ -536,17 +446,19 @@ func BenchmarkSplitPyramidBMT_4h(t *testing.B) { benchmarkSplitPyramidBMT(50000, func BenchmarkSplitPyramidBMT_5(t *testing.B) { benchmarkSplitPyramidBMT(100000, t) } func BenchmarkSplitPyramidBMT_6(t *testing.B) { benchmarkSplitPyramidBMT(1000000, t) } func BenchmarkSplitPyramidBMT_7(t *testing.B) { benchmarkSplitPyramidBMT(10000000, t) } -func BenchmarkSplitPyramidBMT_8(t *testing.B) { benchmarkSplitPyramidBMT(100000000, t) } -func BenchmarkAppendPyramid_2(t *testing.B) { benchmarkAppendPyramid(100, 1000, t) } -func BenchmarkAppendPyramid_2h(t *testing.B) { benchmarkAppendPyramid(500, 1000, t) } -func BenchmarkAppendPyramid_3(t *testing.B) { benchmarkAppendPyramid(1000, 1000, t) } -func BenchmarkAppendPyramid_4(t *testing.B) { benchmarkAppendPyramid(10000, 1000, t) } -func BenchmarkAppendPyramid_4h(t *testing.B) { benchmarkAppendPyramid(50000, 1000, t) } -func BenchmarkAppendPyramid_5(t *testing.B) { benchmarkAppendPyramid(1000000, 1000, t) } -func BenchmarkAppendPyramid_6(t *testing.B) { benchmarkAppendPyramid(1000000, 1000, t) } -func BenchmarkAppendPyramid_7(t *testing.B) { benchmarkAppendPyramid(10000000, 1000, t) } -func BenchmarkAppendPyramid_8(t *testing.B) { benchmarkAppendPyramid(100000000, 1000, t) } +// func BenchmarkSplitPyramidBMT_8(t *testing.B) { benchmarkSplitPyramidBMT(100000000, t) } + +func BenchmarkSplitAppendPyramid_2(t *testing.B) { benchmarkSplitAppendPyramid(100, 1000, t) } +func BenchmarkSplitAppendPyramid_2h(t *testing.B) { benchmarkSplitAppendPyramid(500, 1000, t) } +func BenchmarkSplitAppendPyramid_3(t *testing.B) { benchmarkSplitAppendPyramid(1000, 1000, t) } +func BenchmarkSplitAppendPyramid_4(t *testing.B) { benchmarkSplitAppendPyramid(10000, 1000, t) } +func BenchmarkSplitAppendPyramid_4h(t *testing.B) { benchmarkSplitAppendPyramid(50000, 1000, t) } +func BenchmarkSplitAppendPyramid_5(t *testing.B) { benchmarkSplitAppendPyramid(1000000, 1000, t) } +func BenchmarkSplitAppendPyramid_6(t *testing.B) { benchmarkSplitAppendPyramid(1000000, 1000, t) } +func BenchmarkSplitAppendPyramid_7(t *testing.B) { benchmarkSplitAppendPyramid(10000000, 1000, t) } + +// func BenchmarkAppendPyramid_8(t *testing.B) { benchmarkAppendPyramid(100000000, 1000, t) } // go test -timeout 20m -cpu 4 -bench=./swarm/storage -run no // If you dont add the timeout argument above .. the benchmark will timeout and dump diff --git a/swarm/storage/chunkstore.go b/swarm/storage/chunkstore.go new file mode 100644 index 0000000000..3b4d97a7a7 --- /dev/null +++ b/swarm/storage/chunkstore.go @@ -0,0 +1,69 @@ +// 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 storage + +import ( + "context" + "sync" +) + +/* +ChunkStore interface is implemented by : + +- MemStore: a memory cache +- DbStore: local disk/db store +- LocalStore: a combination (sequence of) memStore and dbStore +- NetStore: cloud storage abstraction layer +- FakeChunkStore: dummy store which doesn't store anything just implements the interface +*/ +type ChunkStore interface { + Put(context.Context, *Chunk) // effectively there is no error even if there is an error + Get(context.Context, Address) (*Chunk, error) + Close() +} + +// MapChunkStore is a very simple ChunkStore implementation to store chunks in a map in memory. +type MapChunkStore struct { + chunks map[string]*Chunk + mu sync.RWMutex +} + +func NewMapChunkStore() *MapChunkStore { + return &MapChunkStore{ + chunks: make(map[string]*Chunk), + } +} + +func (m *MapChunkStore) Put(ctx context.Context, chunk *Chunk) { + m.mu.Lock() + defer m.mu.Unlock() + m.chunks[chunk.Addr.Hex()] = chunk + chunk.markAsStored() +} + +func (m *MapChunkStore) Get(ctx context.Context, addr Address) (*Chunk, error) { + m.mu.RLock() + defer m.mu.RUnlock() + chunk := m.chunks[addr.Hex()] + if chunk == nil { + return nil, ErrChunkNotFound + } + return chunk, nil +} + +func (m *MapChunkStore) Close() { +} diff --git a/swarm/storage/common.go b/swarm/storage/common.go new file mode 100644 index 0000000000..d6352820eb --- /dev/null +++ b/swarm/storage/common.go @@ -0,0 +1,44 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . +package storage + +import ( + "context" + "sync" + + "github.com/ethereum/go-ethereum/swarm/log" +) + +// PutChunks adds chunks to localstore +// It waits for receive on the stored channel +// It logs but does not fail on delivery error +func PutChunks(store *LocalStore, chunks ...*Chunk) { + wg := sync.WaitGroup{} + wg.Add(len(chunks)) + go func() { + for _, c := range chunks { + <-c.dbStoredC + if err := c.GetErrored(); err != nil { + log.Error("chunk store fail", "err", err, "key", c.Addr) + } + wg.Done() + } + }() + for _, c := range chunks { + go store.Put(context.TODO(), c) + } + wg.Wait() +} diff --git a/swarm/storage/common_test.go b/swarm/storage/common_test.go index cd4c2ef139..dc1a3ab35f 100644 --- a/swarm/storage/common_test.go +++ b/swarm/storage/common_test.go @@ -18,15 +18,29 @@ package storage import ( "bytes" + "context" "crypto/rand" + "flag" "fmt" "io" "sync" "testing" + "time" "github.com/ethereum/go-ethereum/log" + colorable "github.com/mattn/go-colorable" ) +var ( + loglevel = flag.Int("loglevel", 3, "verbosity of logs") +) + +func init() { + flag.Parse() + log.PrintOrigins(true) + log.Root().SetHandler(log.LvlFilterHandler(log.Lvl(*loglevel), log.StreamHandler(colorable.NewColorableStderr(), log.TerminalFormat(true)))) +} + type brokenLimitedReader struct { lr io.Reader errAt int @@ -42,19 +56,94 @@ func brokenLimitReader(data io.Reader, size int, errAt int) *brokenLimitedReader } } +func mputRandomChunks(store ChunkStore, processors int, n int, chunksize int64) (hs []Address) { + return mput(store, processors, n, GenerateRandomChunk) +} + +func mput(store ChunkStore, processors int, n int, f func(i int64) *Chunk) (hs []Address) { + wg := sync.WaitGroup{} + wg.Add(processors) + c := make(chan *Chunk) + for i := 0; i < processors; i++ { + go func() { + defer wg.Done() + for chunk := range c { + wg.Add(1) + chunk := chunk + store.Put(context.TODO(), chunk) + go func() { + defer wg.Done() + <-chunk.dbStoredC + }() + } + }() + } + fa := f + if _, ok := store.(*MemStore); ok { + fa = func(i int64) *Chunk { + chunk := f(i) + chunk.markAsStored() + return chunk + } + } + for i := 0; i < n; i++ { + chunk := fa(int64(i)) + hs = append(hs, chunk.Addr) + c <- chunk + } + close(c) + wg.Wait() + return hs +} + +func mget(store ChunkStore, hs []Address, f func(h Address, chunk *Chunk) error) error { + wg := sync.WaitGroup{} + wg.Add(len(hs)) + errc := make(chan error) + + for _, k := range hs { + go func(h Address) { + defer wg.Done() + chunk, err := store.Get(context.TODO(), h) + if err != nil { + errc <- err + return + } + if f != nil { + err = f(h, chunk) + if err != nil { + errc <- err + return + } + } + }(k) + } + go func() { + wg.Wait() + close(errc) + }() + var err error + select { + case err = <-errc: + case <-time.NewTimer(5 * time.Second).C: + err = fmt.Errorf("timed out after 5 seconds") + } + return err +} + func testDataReader(l int) (r io.Reader) { return io.LimitReader(rand.Reader, int64(l)) } -func (self *brokenLimitedReader) Read(buf []byte) (int, error) { - if self.off+len(buf) > self.errAt { +func (r *brokenLimitedReader) Read(buf []byte) (int, error) { + if r.off+len(buf) > r.errAt { return 0, fmt.Errorf("Broken reader") } - self.off += len(buf) - return self.lr.Read(buf) + r.off += len(buf) + return r.lr.Read(buf) } -func testDataReaderAndSlice(l int) (r io.Reader, slice []byte) { +func generateRandomData(l int) (r io.Reader, slice []byte) { slice = make([]byte, l) if _, err := rand.Read(slice); err != nil { panic("rand error") @@ -63,54 +152,70 @@ func testDataReaderAndSlice(l int) (r io.Reader, slice []byte) { return } -func testStore(m ChunkStore, l int64, branches int64, t *testing.T) { - - chunkC := make(chan *Chunk) - go func() { - for chunk := range chunkC { - m.Put(chunk) - if chunk.wg != nil { - chunk.wg.Done() - } - } - }() - chunker := NewTreeChunker(&ChunkerParams{ - Branches: branches, - Hash: SHA3Hash, - }) - swg := &sync.WaitGroup{} - key, _ := chunker.Split(rand.Reader, l, chunkC, swg, nil) - swg.Wait() - close(chunkC) - chunkC = make(chan *Chunk) - - quit := make(chan bool) - - go func() { - for ch := range chunkC { - go func(chunk *Chunk) { - storedChunk, err := m.Get(chunk.Key) - if err == notFound { - log.Trace(fmt.Sprintf("chunk '%v' not found", chunk.Key.Log())) - } else if err != nil { - log.Trace(fmt.Sprintf("error retrieving chunk %v: %v", chunk.Key.Log(), err)) - } else { - chunk.SData = storedChunk.SData - chunk.Size = storedChunk.Size - } - log.Trace(fmt.Sprintf("chunk '%v' not found", chunk.Key.Log())) - close(chunk.C) - }(ch) - } - close(quit) - }() - r := chunker.Join(key, chunkC) - - b := make([]byte, l) - n, err := r.ReadAt(b, 0) - if err != io.EOF { - t.Fatalf("read error (%v/%v) %v", n, l, err) +func testStoreRandom(m ChunkStore, processors int, n int, chunksize int64, t *testing.T) { + hs := mputRandomChunks(m, processors, n, chunksize) + err := mget(m, hs, nil) + if err != nil { + t.Fatalf("testStore failed: %v", err) + } +} + +func testStoreCorrect(m ChunkStore, processors int, n int, chunksize int64, t *testing.T) { + hs := mputRandomChunks(m, processors, n, chunksize) + f := func(h Address, chunk *Chunk) error { + if !bytes.Equal(h, chunk.Addr) { + return fmt.Errorf("key does not match retrieved chunk Key") + } + hasher := MakeHashFunc(DefaultHash)() + hasher.ResetWithLength(chunk.SData[:8]) + hasher.Write(chunk.SData[8:]) + exp := hasher.Sum(nil) + if !bytes.Equal(h, exp) { + return fmt.Errorf("key is not hash of chunk data") + } + return nil + } + err := mget(m, hs, f) + if err != nil { + t.Fatalf("testStore failed: %v", err) + } +} + +func benchmarkStorePut(store ChunkStore, processors int, n int, chunksize int64, b *testing.B) { + chunks := make([]*Chunk, n) + i := 0 + f := func(dataSize int64) *Chunk { + chunk := GenerateRandomChunk(dataSize) + chunks[i] = chunk + i++ + return chunk + } + + mput(store, processors, n, f) + + f = func(dataSize int64) *Chunk { + chunk := chunks[i] + i++ + return chunk + } + + b.ReportAllocs() + b.ResetTimer() + + for j := 0; j < b.N; j++ { + i = 0 + mput(store, processors, n, f) + } +} + +func benchmarkStoreGet(store ChunkStore, processors int, n int, chunksize int64, b *testing.B) { + hs := mputRandomChunks(store, processors, n, chunksize) + b.ReportAllocs() + b.ResetTimer() + for i := 0; i < b.N; i++ { + err := mget(store, hs, nil) + if err != nil { + b.Fatalf("mget failed: %v", err) + } } - close(chunkC) - <-quit } diff --git a/swarm/storage/database.go b/swarm/storage/database.go index 2532490cc9..3b5d003de1 100644 --- a/swarm/storage/database.go +++ b/swarm/storage/database.go @@ -22,7 +22,7 @@ package storage import ( "fmt" - "github.com/ethereum/go-ethereum/compression/rle" + "github.com/ethereum/go-ethereum/metrics" "github.com/syndtr/goleveldb/leveldb" "github.com/syndtr/goleveldb/leveldb/iterator" "github.com/syndtr/goleveldb/leveldb/opt" @@ -31,8 +31,7 @@ import ( const openFileLimit = 128 type LDBDatabase struct { - db *leveldb.DB - comp bool + db *leveldb.DB } func NewLDBDatabase(file string) (*LDBDatabase, error) { @@ -42,41 +41,36 @@ func NewLDBDatabase(file string) (*LDBDatabase, error) { return nil, err } - database := &LDBDatabase{db: db, comp: false} + database := &LDBDatabase{db: db} return database, nil } -func (self *LDBDatabase) Put(key []byte, value []byte) { - if self.comp { - value = rle.Compress(value) - } +func (db *LDBDatabase) Put(key []byte, value []byte) { + metrics.GetOrRegisterCounter("ldbdatabase.put", nil).Inc(1) - err := self.db.Put(key, value, nil) + err := db.db.Put(key, value, nil) if err != nil { fmt.Println("Error put", err) } } -func (self *LDBDatabase) Get(key []byte) ([]byte, error) { - dat, err := self.db.Get(key, nil) +func (db *LDBDatabase) Get(key []byte) ([]byte, error) { + metrics.GetOrRegisterCounter("ldbdatabase.get", nil).Inc(1) + + dat, err := db.db.Get(key, nil) if err != nil { return nil, err } - - if self.comp { - return rle.Decompress(dat) - } - return dat, nil } -func (self *LDBDatabase) Delete(key []byte) error { - return self.db.Delete(key, nil) +func (db *LDBDatabase) Delete(key []byte) error { + return db.db.Delete(key, nil) } -func (self *LDBDatabase) LastKnownTD() []byte { - data, _ := self.Get([]byte("LTD")) +func (db *LDBDatabase) LastKnownTD() []byte { + data, _ := db.Get([]byte("LTD")) if len(data) == 0 { data = []byte{0x0} @@ -85,15 +79,19 @@ func (self *LDBDatabase) LastKnownTD() []byte { return data } -func (self *LDBDatabase) NewIterator() iterator.Iterator { - return self.db.NewIterator(nil, nil) +func (db *LDBDatabase) NewIterator() iterator.Iterator { + metrics.GetOrRegisterCounter("ldbdatabase.newiterator", nil).Inc(1) + + return db.db.NewIterator(nil, nil) } -func (self *LDBDatabase) Write(batch *leveldb.Batch) error { - return self.db.Write(batch, nil) +func (db *LDBDatabase) Write(batch *leveldb.Batch) error { + metrics.GetOrRegisterCounter("ldbdatabase.write", nil).Inc(1) + + return db.db.Write(batch, nil) } -func (self *LDBDatabase) Close() { +func (db *LDBDatabase) Close() { // Close the leveldb database - self.db.Close() + db.db.Close() } diff --git a/swarm/storage/dbapi.go b/swarm/storage/dbapi.go new file mode 100644 index 0000000000..dd71752eb2 --- /dev/null +++ b/swarm/storage/dbapi.go @@ -0,0 +1,54 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package storage + +import "context" + +// wrapper of db-s to provide mockable custom local chunk store access to syncer +type DBAPI struct { + db *LDBStore + loc *LocalStore +} + +func NewDBAPI(loc *LocalStore) *DBAPI { + return &DBAPI{loc.DbStore, loc} +} + +// to obtain the chunks from address or request db entry only +func (d *DBAPI) Get(ctx context.Context, addr Address) (*Chunk, error) { + return d.loc.Get(ctx, addr) +} + +// current storage counter of chunk db +func (d *DBAPI) CurrentBucketStorageIndex(po uint8) uint64 { + return d.db.CurrentBucketStorageIndex(po) +} + +// iteration storage counter and proximity order +func (d *DBAPI) Iterator(from uint64, to uint64, po uint8, f func(Address, uint64) bool) error { + return d.db.SyncIterator(from, to, po, f) +} + +// to obtain the chunks from address or request db entry only +func (d *DBAPI) GetOrCreateRequest(ctx context.Context, addr Address) (*Chunk, bool) { + return d.loc.GetOrCreateRequest(ctx, addr) +} + +// to obtain the chunks from key or request db entry only +func (d *DBAPI) Put(ctx context.Context, chunk *Chunk) { + d.loc.Put(ctx, chunk) +} diff --git a/swarm/storage/dbstore.go b/swarm/storage/dbstore.go deleted file mode 100644 index 421bb061d5..0000000000 --- a/swarm/storage/dbstore.go +++ /dev/null @@ -1,601 +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 . - -// disk storage layer for the package bzz -// DbStore implements the ChunkStore interface and is used by the DPA as -// persistent storage of chunks -// it implements purging based on access count allowing for external control of -// max capacity - -package storage - -import ( - "archive/tar" - "bytes" - "encoding/binary" - "encoding/hex" - "fmt" - "io" - "io/ioutil" - "sync" - - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/metrics" - "github.com/ethereum/go-ethereum/rlp" - "github.com/syndtr/goleveldb/leveldb" - "github.com/syndtr/goleveldb/leveldb/iterator" -) - -//metrics variables -var ( - gcCounter = metrics.NewRegisteredCounter("storage.db.dbstore.gc.count", nil) - dbStoreDeleteCounter = metrics.NewRegisteredCounter("storage.db.dbstore.rm.count", nil) -) - -const ( - defaultDbCapacity = 5000000 - defaultRadius = 0 // not yet used - - gcArraySize = 10000 - gcArrayFreeRatio = 0.1 - - // key prefixes for leveldb storage - kpIndex = 0 - kpData = 1 -) - -var ( - keyAccessCnt = []byte{2} - keyEntryCnt = []byte{3} - keyDataIdx = []byte{4} - keyGCPos = []byte{5} -) - -type gcItem struct { - idx uint64 - value uint64 - idxKey []byte -} - -type DbStore struct { - db *LDBDatabase - - // this should be stored in db, accessed transactionally - entryCnt, accessCnt, dataIdx, capacity uint64 - - gcPos, gcStartPos []byte - gcArray []*gcItem - - hashfunc SwarmHasher - - lock sync.Mutex -} - -func NewDbStore(path string, hash SwarmHasher, capacity uint64, radius int) (s *DbStore, err error) { - s = new(DbStore) - - s.hashfunc = hash - - s.db, err = NewLDBDatabase(path) - if err != nil { - return - } - - s.setCapacity(capacity) - - s.gcStartPos = make([]byte, 1) - s.gcStartPos[0] = kpIndex - s.gcArray = make([]*gcItem, gcArraySize) - - data, _ := s.db.Get(keyEntryCnt) - s.entryCnt = BytesToU64(data) - data, _ = s.db.Get(keyAccessCnt) - s.accessCnt = BytesToU64(data) - data, _ = s.db.Get(keyDataIdx) - s.dataIdx = BytesToU64(data) - s.gcPos, _ = s.db.Get(keyGCPos) - if s.gcPos == nil { - s.gcPos = s.gcStartPos - } - return -} - -type dpaDBIndex struct { - Idx uint64 - Access uint64 -} - -func BytesToU64(data []byte) uint64 { - if len(data) < 8 { - return 0 - } - return binary.LittleEndian.Uint64(data) -} - -func U64ToBytes(val uint64) []byte { - data := make([]byte, 8) - binary.LittleEndian.PutUint64(data, val) - return data -} - -func getIndexGCValue(index *dpaDBIndex) uint64 { - return index.Access -} - -func (s *DbStore) updateIndexAccess(index *dpaDBIndex) { - index.Access = s.accessCnt -} - -func getIndexKey(hash Key) []byte { - HashSize := len(hash) - key := make([]byte, HashSize+1) - key[0] = 0 - copy(key[1:], hash[:]) - return key -} - -func getDataKey(idx uint64) []byte { - key := make([]byte, 9) - key[0] = 1 - binary.BigEndian.PutUint64(key[1:9], idx) - - return key -} - -func encodeIndex(index *dpaDBIndex) []byte { - data, _ := rlp.EncodeToBytes(index) - return data -} - -func encodeData(chunk *Chunk) []byte { - return chunk.SData -} - -func decodeIndex(data []byte, index *dpaDBIndex) { - dec := rlp.NewStream(bytes.NewReader(data), 0) - dec.Decode(index) -} - -func decodeData(data []byte, chunk *Chunk) { - chunk.SData = data - chunk.Size = int64(binary.LittleEndian.Uint64(data[0:8])) -} - -func gcListPartition(list []*gcItem, left int, right int, pivotIndex int) int { - pivotValue := list[pivotIndex].value - dd := list[pivotIndex] - list[pivotIndex] = list[right] - list[right] = dd - storeIndex := left - for i := left; i < right; i++ { - if list[i].value < pivotValue { - dd = list[storeIndex] - list[storeIndex] = list[i] - list[i] = dd - storeIndex++ - } - } - dd = list[storeIndex] - list[storeIndex] = list[right] - list[right] = dd - return storeIndex -} - -func gcListSelect(list []*gcItem, left int, right int, n int) int { - if left == right { - return left - } - pivotIndex := (left + right) / 2 - pivotIndex = gcListPartition(list, left, right, pivotIndex) - if n == pivotIndex { - return n - } else { - if n < pivotIndex { - return gcListSelect(list, left, pivotIndex-1, n) - } else { - return gcListSelect(list, pivotIndex+1, right, n) - } - } -} - -func (s *DbStore) collectGarbage(ratio float32) { - it := s.db.NewIterator() - it.Seek(s.gcPos) - if it.Valid() { - s.gcPos = it.Key() - } else { - s.gcPos = nil - } - gcnt := 0 - - for (gcnt < gcArraySize) && (uint64(gcnt) < s.entryCnt) { - - if (s.gcPos == nil) || (s.gcPos[0] != kpIndex) { - it.Seek(s.gcStartPos) - if it.Valid() { - s.gcPos = it.Key() - } else { - s.gcPos = nil - } - } - - if (s.gcPos == nil) || (s.gcPos[0] != kpIndex) { - break - } - - gci := new(gcItem) - gci.idxKey = s.gcPos - var index dpaDBIndex - decodeIndex(it.Value(), &index) - gci.idx = index.Idx - // the smaller, the more likely to be gc'd - gci.value = getIndexGCValue(&index) - s.gcArray[gcnt] = gci - gcnt++ - it.Next() - if it.Valid() { - s.gcPos = it.Key() - } else { - s.gcPos = nil - } - } - it.Release() - - cutidx := gcListSelect(s.gcArray, 0, gcnt-1, int(float32(gcnt)*ratio)) - cutval := s.gcArray[cutidx].value - - // fmt.Print(gcnt, " ", s.entryCnt, " ") - - // actual gc - for i := 0; i < gcnt; i++ { - if s.gcArray[i].value <= cutval { - gcCounter.Inc(1) - s.delete(s.gcArray[i].idx, s.gcArray[i].idxKey) - } - } - - // fmt.Println(s.entryCnt) - - s.db.Put(keyGCPos, s.gcPos) -} - -// Export writes all chunks from the store to a tar archive, returning the -// number of chunks written. -func (s *DbStore) Export(out io.Writer) (int64, error) { - tw := tar.NewWriter(out) - defer tw.Close() - - it := s.db.NewIterator() - defer it.Release() - var count int64 - for ok := it.Seek([]byte{kpIndex}); ok; ok = it.Next() { - key := it.Key() - if (key == nil) || (key[0] != kpIndex) { - break - } - - var index dpaDBIndex - decodeIndex(it.Value(), &index) - - data, err := s.db.Get(getDataKey(index.Idx)) - if err != nil { - log.Warn(fmt.Sprintf("Chunk %x found but could not be accessed: %v", key[:], err)) - continue - } - - hdr := &tar.Header{ - Name: hex.EncodeToString(key[1:]), - Mode: 0644, - Size: int64(len(data)), - } - if err := tw.WriteHeader(hdr); err != nil { - return count, err - } - if _, err := tw.Write(data); err != nil { - return count, err - } - count++ - } - - return count, nil -} - -// Import reads chunks into the store from a tar archive, returning the number -// of chunks read. -func (s *DbStore) Import(in io.Reader) (int64, error) { - tr := tar.NewReader(in) - - var count int64 - for { - hdr, err := tr.Next() - if err == io.EOF { - break - } else if err != nil { - return count, err - } - - if len(hdr.Name) != 64 { - log.Warn("ignoring non-chunk file", "name", hdr.Name) - continue - } - - key, err := hex.DecodeString(hdr.Name) - if err != nil { - log.Warn("ignoring invalid chunk file", "name", hdr.Name, "err", err) - continue - } - - data, err := ioutil.ReadAll(tr) - if err != nil { - return count, err - } - - s.Put(&Chunk{Key: key, SData: data}) - count++ - } - - return count, nil -} - -func (s *DbStore) Cleanup() { - //Iterates over the database and checks that there are no faulty chunks - it := s.db.NewIterator() - startPosition := []byte{kpIndex} - it.Seek(startPosition) - var key []byte - var errorsFound, total int - for it.Valid() { - key = it.Key() - if (key == nil) || (key[0] != kpIndex) { - break - } - total++ - var index dpaDBIndex - decodeIndex(it.Value(), &index) - - data, err := s.db.Get(getDataKey(index.Idx)) - if err != nil { - log.Warn(fmt.Sprintf("Chunk %x found but could not be accessed: %v", key[:], err)) - s.delete(index.Idx, getIndexKey(key[1:])) - errorsFound++ - } else { - hasher := s.hashfunc() - hasher.Write(data) - hash := hasher.Sum(nil) - if !bytes.Equal(hash, key[1:]) { - log.Warn(fmt.Sprintf("Found invalid chunk. Hash mismatch. hash=%x, key=%x", hash, key[:])) - s.delete(index.Idx, getIndexKey(key[1:])) - errorsFound++ - } - } - it.Next() - } - it.Release() - log.Warn(fmt.Sprintf("Found %v errors out of %v entries", errorsFound, total)) -} - -func (s *DbStore) delete(idx uint64, idxKey []byte) { - batch := new(leveldb.Batch) - batch.Delete(idxKey) - batch.Delete(getDataKey(idx)) - dbStoreDeleteCounter.Inc(1) - s.entryCnt-- - batch.Put(keyEntryCnt, U64ToBytes(s.entryCnt)) - s.db.Write(batch) -} - -func (s *DbStore) Counter() uint64 { - s.lock.Lock() - defer s.lock.Unlock() - return s.dataIdx -} - -func (s *DbStore) Put(chunk *Chunk) { - s.lock.Lock() - defer s.lock.Unlock() - - ikey := getIndexKey(chunk.Key) - var index dpaDBIndex - - if s.tryAccessIdx(ikey, &index) { - if chunk.dbStored != nil { - close(chunk.dbStored) - } - log.Trace(fmt.Sprintf("Storing to DB: chunk already exists, only update access")) - return // already exists, only update access - } - - data := encodeData(chunk) - //data := ethutil.Encode([]interface{}{entry}) - - if s.entryCnt >= s.capacity { - s.collectGarbage(gcArrayFreeRatio) - } - - batch := new(leveldb.Batch) - - batch.Put(getDataKey(s.dataIdx), data) - - index.Idx = s.dataIdx - s.updateIndexAccess(&index) - - idata := encodeIndex(&index) - batch.Put(ikey, idata) - - batch.Put(keyEntryCnt, U64ToBytes(s.entryCnt)) - s.entryCnt++ - batch.Put(keyDataIdx, U64ToBytes(s.dataIdx)) - s.dataIdx++ - batch.Put(keyAccessCnt, U64ToBytes(s.accessCnt)) - s.accessCnt++ - - s.db.Write(batch) - if chunk.dbStored != nil { - close(chunk.dbStored) - } - log.Trace(fmt.Sprintf("DbStore.Put: %v. db storage counter: %v ", chunk.Key.Log(), s.dataIdx)) -} - -// try to find index; if found, update access cnt and return true -func (s *DbStore) tryAccessIdx(ikey []byte, index *dpaDBIndex) bool { - idata, err := s.db.Get(ikey) - if err != nil { - return false - } - decodeIndex(idata, index) - - batch := new(leveldb.Batch) - - batch.Put(keyAccessCnt, U64ToBytes(s.accessCnt)) - s.accessCnt++ - s.updateIndexAccess(index) - idata = encodeIndex(index) - batch.Put(ikey, idata) - - s.db.Write(batch) - - return true -} - -func (s *DbStore) Get(key Key) (chunk *Chunk, err error) { - s.lock.Lock() - defer s.lock.Unlock() - - var index dpaDBIndex - - if s.tryAccessIdx(getIndexKey(key), &index) { - var data []byte - data, err = s.db.Get(getDataKey(index.Idx)) - if err != nil { - log.Trace(fmt.Sprintf("DBStore: Chunk %v found but could not be accessed: %v", key.Log(), err)) - s.delete(index.Idx, getIndexKey(key)) - return - } - - hasher := s.hashfunc() - hasher.Write(data) - hash := hasher.Sum(nil) - if !bytes.Equal(hash, key) { - s.delete(index.Idx, getIndexKey(key)) - log.Warn("Invalid Chunk in Database. Please repair with command: 'swarm cleandb'") - } - - chunk = &Chunk{ - Key: key, - } - decodeData(data, chunk) - } else { - err = notFound - } - - return - -} - -func (s *DbStore) updateAccessCnt(key Key) { - - s.lock.Lock() - defer s.lock.Unlock() - - var index dpaDBIndex - s.tryAccessIdx(getIndexKey(key), &index) // result_chn == nil, only update access cnt - -} - -func (s *DbStore) setCapacity(c uint64) { - - s.lock.Lock() - defer s.lock.Unlock() - - s.capacity = c - - if s.entryCnt > c { - ratio := float32(1.01) - float32(c)/float32(s.entryCnt) - if ratio < gcArrayFreeRatio { - ratio = gcArrayFreeRatio - } - if ratio > 1 { - ratio = 1 - } - for s.entryCnt > c { - s.collectGarbage(ratio) - } - } -} - -func (s *DbStore) Close() { - s.db.Close() -} - -// describes a section of the DbStore representing the unsynced -// domain relevant to a peer -// Start - Stop designate a continuous area Keys in an address space -// typically the addresses closer to us than to the peer but not closer -// another closer peer in between -// From - To designates a time interval typically from the last disconnect -// till the latest connection (real time traffic is relayed) -type DbSyncState struct { - Start, Stop Key - First, Last uint64 -} - -// implements the syncer iterator interface -// iterates by storage index (~ time of storage = first entry to db) -type dbSyncIterator struct { - it iterator.Iterator - DbSyncState -} - -// initialises a sync iterator from a syncToken (passed in with the handshake) -func (self *DbStore) NewSyncIterator(state DbSyncState) (si *dbSyncIterator, err error) { - if state.First > state.Last { - return nil, fmt.Errorf("no entries found") - } - si = &dbSyncIterator{ - it: self.db.NewIterator(), - DbSyncState: state, - } - si.it.Seek(getIndexKey(state.Start)) - return si, nil -} - -// walk the area from Start to Stop and returns items within time interval -// First to Last -func (self *dbSyncIterator) Next() (key Key) { - for self.it.Valid() { - dbkey := self.it.Key() - if dbkey[0] != 0 { - break - } - key = Key(make([]byte, len(dbkey)-1)) - copy(key[:], dbkey[1:]) - if bytes.Compare(key[:], self.Start) <= 0 { - self.it.Next() - continue - } - if bytes.Compare(key[:], self.Stop) > 0 { - break - } - var index dpaDBIndex - decodeIndex(self.it.Value(), &index) - self.it.Next() - if (index.Idx >= self.First) && (index.Idx < self.Last) { - return - } - } - self.it.Release() - return nil -} diff --git a/swarm/storage/dbstore_test.go b/swarm/storage/dbstore_test.go deleted file mode 100644 index dd165b5768..0000000000 --- a/swarm/storage/dbstore_test.go +++ /dev/null @@ -1,191 +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 storage - -import ( - "bytes" - "io/ioutil" - "testing" - - "github.com/ethereum/go-ethereum/common" -) - -func initDbStore(t *testing.T) *DbStore { - dir, err := ioutil.TempDir("", "bzz-storage-test") - if err != nil { - t.Fatal(err) - } - m, err := NewDbStore(dir, MakeHashFunc(SHA3Hash), defaultDbCapacity, defaultRadius) - if err != nil { - t.Fatal("can't create store:", err) - } - return m -} - -func testDbStore(l int64, branches int64, t *testing.T) { - m := initDbStore(t) - defer m.Close() - testStore(m, l, branches, t) -} - -func TestDbStore128_0x1000000(t *testing.T) { - testDbStore(0x1000000, 128, t) -} - -func TestDbStore128_10000_(t *testing.T) { - testDbStore(10000, 128, t) -} - -func TestDbStore128_1000_(t *testing.T) { - testDbStore(1000, 128, t) -} - -func TestDbStore128_100_(t *testing.T) { - testDbStore(100, 128, t) -} - -func TestDbStore2_100_(t *testing.T) { - testDbStore(100, 2, t) -} - -func TestDbStoreNotFound(t *testing.T) { - m := initDbStore(t) - defer m.Close() - _, err := m.Get(ZeroKey) - if err != notFound { - t.Errorf("Expected notFound, got %v", err) - } -} - -func TestDbStoreSyncIterator(t *testing.T) { - m := initDbStore(t) - defer m.Close() - keys := []Key{ - Key(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000000")), - Key(common.Hex2Bytes("4000000000000000000000000000000000000000000000000000000000000000")), - Key(common.Hex2Bytes("5000000000000000000000000000000000000000000000000000000000000000")), - Key(common.Hex2Bytes("3000000000000000000000000000000000000000000000000000000000000000")), - Key(common.Hex2Bytes("2000000000000000000000000000000000000000000000000000000000000000")), - Key(common.Hex2Bytes("1000000000000000000000000000000000000000000000000000000000000000")), - } - for _, key := range keys { - m.Put(NewChunk(key, nil)) - } - it, err := m.NewSyncIterator(DbSyncState{ - Start: Key(common.Hex2Bytes("1000000000000000000000000000000000000000000000000000000000000000")), - Stop: Key(common.Hex2Bytes("4000000000000000000000000000000000000000000000000000000000000000")), - First: 2, - Last: 4, - }) - if err != nil { - t.Fatalf("unexpected error creating NewSyncIterator") - } - - var chunk Key - var res []Key - for { - chunk = it.Next() - if chunk == nil { - break - } - res = append(res, chunk) - } - if len(res) != 1 { - t.Fatalf("Expected 1 chunk, got %v: %v", len(res), res) - } - if !bytes.Equal(res[0][:], keys[3]) { - t.Fatalf("Expected %v chunk, got %v", keys[3], res[0]) - } - - if err != nil { - t.Fatalf("unexpected error creating NewSyncIterator") - } - - it, err = m.NewSyncIterator(DbSyncState{ - Start: Key(common.Hex2Bytes("1000000000000000000000000000000000000000000000000000000000000000")), - Stop: Key(common.Hex2Bytes("5000000000000000000000000000000000000000000000000000000000000000")), - First: 2, - Last: 4, - }) - - res = nil - for { - chunk = it.Next() - if chunk == nil { - break - } - res = append(res, chunk) - } - if len(res) != 2 { - t.Fatalf("Expected 2 chunk, got %v: %v", len(res), res) - } - if !bytes.Equal(res[0][:], keys[3]) { - t.Fatalf("Expected %v chunk, got %v", keys[3], res[0]) - } - if !bytes.Equal(res[1][:], keys[2]) { - t.Fatalf("Expected %v chunk, got %v", keys[2], res[1]) - } - - if err != nil { - t.Fatalf("unexpected error creating NewSyncIterator") - } - - it, _ = m.NewSyncIterator(DbSyncState{ - Start: Key(common.Hex2Bytes("1000000000000000000000000000000000000000000000000000000000000000")), - Stop: Key(common.Hex2Bytes("4000000000000000000000000000000000000000000000000000000000000000")), - First: 2, - Last: 5, - }) - res = nil - for { - chunk = it.Next() - if chunk == nil { - break - } - res = append(res, chunk) - } - if len(res) != 2 { - t.Fatalf("Expected 2 chunk, got %v", len(res)) - } - if !bytes.Equal(res[0][:], keys[4]) { - t.Fatalf("Expected %v chunk, got %v", keys[4], res[0]) - } - if !bytes.Equal(res[1][:], keys[3]) { - t.Fatalf("Expected %v chunk, got %v", keys[3], res[1]) - } - - it, _ = m.NewSyncIterator(DbSyncState{ - Start: Key(common.Hex2Bytes("2000000000000000000000000000000000000000000000000000000000000000")), - Stop: Key(common.Hex2Bytes("4000000000000000000000000000000000000000000000000000000000000000")), - First: 2, - Last: 5, - }) - res = nil - for { - chunk = it.Next() - if chunk == nil { - break - } - res = append(res, chunk) - } - if len(res) != 1 { - t.Fatalf("Expected 1 chunk, got %v", len(res)) - } - if !bytes.Equal(res[0][:], keys[3]) { - t.Fatalf("Expected %v chunk, got %v", keys[3], res[0]) - } -} diff --git a/swarm/storage/dpa.go b/swarm/storage/dpa.go deleted file mode 100644 index 44a2669f12..0000000000 --- a/swarm/storage/dpa.go +++ /dev/null @@ -1,241 +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 storage - -import ( - "errors" - "fmt" - "io" - "sync" - "time" - - "github.com/ethereum/go-ethereum/log" -) - -/* -DPA provides the client API entrypoints Store and Retrieve to store and retrieve -It can store anything that has a byte slice representation, so files or serialised objects etc. - -Storage: DPA calls the Chunker to segment the input datastream of any size to a merkle hashed tree of chunks. The key of the root block is returned to the client. - -Retrieval: given the key of the root block, the DPA retrieves the block chunks and reconstructs the original data and passes it back as a lazy reader. A lazy reader is a reader with on-demand delayed processing, i.e. the chunks needed to reconstruct a large file are only fetched and processed if that particular part of the document is actually read. - -As the chunker produces chunks, DPA dispatches them to its own chunk store -implementation for storage or retrieval. -*/ - -const ( - storeChanCapacity = 100 - retrieveChanCapacity = 100 - singletonSwarmDbCapacity = 50000 - singletonSwarmCacheCapacity = 500 - maxStoreProcesses = 8 - maxRetrieveProcesses = 8 -) - -var ( - notFound = errors.New("not found") -) - -type DPA struct { - ChunkStore - storeC chan *Chunk - retrieveC chan *Chunk - Chunker Chunker - - lock sync.Mutex - running bool - quitC chan bool -} - -// for testing locally -func NewLocalDPA(datadir string) (*DPA, error) { - - hash := MakeHashFunc("SHA256") - - dbStore, err := NewDbStore(datadir, hash, singletonSwarmDbCapacity, 0) - if err != nil { - return nil, err - } - - return NewDPA(&LocalStore{ - NewMemStore(dbStore, singletonSwarmCacheCapacity), - dbStore, - }, NewChunkerParams()), nil -} - -func NewDPA(store ChunkStore, params *ChunkerParams) *DPA { - chunker := NewTreeChunker(params) - return &DPA{ - Chunker: chunker, - ChunkStore: store, - } -} - -// Public API. Main entry point for document retrieval directly. Used by the -// FS-aware API and httpaccess -// Chunk retrieval blocks on netStore requests with a timeout so reader will -// report error if retrieval of chunks within requested range time out. -func (self *DPA) Retrieve(key Key) LazySectionReader { - return self.Chunker.Join(key, self.retrieveC) -} - -// Public API. Main entry point for document storage directly. Used by the -// FS-aware API and httpaccess -func (self *DPA) Store(data io.Reader, size int64, swg *sync.WaitGroup, wwg *sync.WaitGroup) (key Key, err error) { - return self.Chunker.Split(data, size, self.storeC, swg, wwg) -} - -func (self *DPA) Start() { - self.lock.Lock() - defer self.lock.Unlock() - if self.running { - return - } - self.running = true - self.retrieveC = make(chan *Chunk, retrieveChanCapacity) - self.storeC = make(chan *Chunk, storeChanCapacity) - self.quitC = make(chan bool) - self.storeLoop() - self.retrieveLoop() -} - -func (self *DPA) Stop() { - self.lock.Lock() - defer self.lock.Unlock() - if !self.running { - return - } - self.running = false - close(self.quitC) -} - -// retrieveLoop dispatches the parallel chunk retrieval requests received on the -// retrieve channel to its ChunkStore (NetStore or LocalStore) -func (self *DPA) retrieveLoop() { - for i := 0; i < maxRetrieveProcesses; i++ { - go self.retrieveWorker() - } - log.Trace(fmt.Sprintf("dpa: retrieve loop spawning %v workers", maxRetrieveProcesses)) -} - -func (self *DPA) retrieveWorker() { - for chunk := range self.retrieveC { - log.Trace(fmt.Sprintf("dpa: retrieve loop : chunk %v", chunk.Key.Log())) - storedChunk, err := self.Get(chunk.Key) - if err == notFound { - log.Trace(fmt.Sprintf("chunk %v not found", chunk.Key.Log())) - } else if err != nil { - log.Trace(fmt.Sprintf("error retrieving chunk %v: %v", chunk.Key.Log(), err)) - } else { - chunk.SData = storedChunk.SData - chunk.Size = storedChunk.Size - } - close(chunk.C) - - select { - case <-self.quitC: - return - default: - } - } -} - -// storeLoop dispatches the parallel chunk store request processors -// received on the store channel to its ChunkStore (NetStore or LocalStore) -func (self *DPA) storeLoop() { - for i := 0; i < maxStoreProcesses; i++ { - go self.storeWorker() - } - log.Trace(fmt.Sprintf("dpa: store spawning %v workers", maxStoreProcesses)) -} - -func (self *DPA) storeWorker() { - - for chunk := range self.storeC { - self.Put(chunk) - if chunk.wg != nil { - log.Trace(fmt.Sprintf("dpa: store processor %v", chunk.Key.Log())) - chunk.wg.Done() - - } - select { - case <-self.quitC: - return - default: - } - } -} - -// DpaChunkStore implements the ChunkStore interface, -// this chunk access layer assumed 2 chunk stores -// local storage eg. LocalStore and network storage eg., NetStore -// access by calling network is blocking with a timeout - -type dpaChunkStore struct { - n int - localStore ChunkStore - netStore ChunkStore -} - -func NewDpaChunkStore(localStore, netStore ChunkStore) *dpaChunkStore { - return &dpaChunkStore{0, localStore, netStore} -} - -// Get is the entrypoint for local retrieve requests -// waits for response or times out -func (self *dpaChunkStore) Get(key Key) (chunk *Chunk, err error) { - chunk, err = self.netStore.Get(key) - // timeout := time.Now().Add(searchTimeout) - if chunk.SData != nil { - log.Trace(fmt.Sprintf("DPA.Get: %v found locally, %d bytes", key.Log(), len(chunk.SData))) - return - } - // TODO: use self.timer time.Timer and reset with defer disableTimer - timer := time.After(searchTimeout) - select { - case <-timer: - log.Trace(fmt.Sprintf("DPA.Get: %v request time out ", key.Log())) - err = notFound - case <-chunk.Req.C: - log.Trace(fmt.Sprintf("DPA.Get: %v retrieved, %d bytes (%p)", key.Log(), len(chunk.SData), chunk)) - } - return -} - -// Put is the entrypoint for local store requests coming from storeLoop -func (self *dpaChunkStore) Put(entry *Chunk) { - chunk, err := self.localStore.Get(entry.Key) - if err != nil { - log.Trace(fmt.Sprintf("DPA.Put: %v new chunk. call netStore.Put", entry.Key.Log())) - chunk = entry - } else if chunk.SData == nil { - log.Trace(fmt.Sprintf("DPA.Put: %v request entry found", entry.Key.Log())) - chunk.SData = entry.SData - chunk.Size = entry.Size - } else { - log.Trace(fmt.Sprintf("DPA.Put: %v chunk already known", entry.Key.Log())) - return - } - // from this point on the storage logic is the same with network storage requests - log.Trace(fmt.Sprintf("DPA.Put %v: %v", self.n, chunk.Key.Log())) - self.n++ - self.netStore.Put(chunk) -} - -// Close chunk store -func (self *dpaChunkStore) Close() {} diff --git a/swarm/storage/encryption/encryption.go b/swarm/storage/encryption/encryption.go new file mode 100644 index 0000000000..e50f2163db --- /dev/null +++ b/swarm/storage/encryption/encryption.go @@ -0,0 +1,116 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package encryption + +import ( + "crypto/rand" + "encoding/binary" + "fmt" + "hash" +) + +const KeyLength = 32 + +type Key []byte + +type Encryption interface { + Encrypt(data []byte, key Key) ([]byte, error) + Decrypt(data []byte, key Key) ([]byte, error) +} + +type encryption struct { + padding int + initCtr uint32 + hashFunc func() hash.Hash +} + +func New(padding int, initCtr uint32, hashFunc func() hash.Hash) *encryption { + return &encryption{ + padding: padding, + initCtr: initCtr, + hashFunc: hashFunc, + } +} + +func (e *encryption) Encrypt(data []byte, key Key) ([]byte, error) { + length := len(data) + isFixedPadding := e.padding > 0 + if isFixedPadding && length > e.padding { + return nil, fmt.Errorf("Data length longer than padding, data length %v padding %v", length, e.padding) + } + + paddedData := data + if isFixedPadding && length < e.padding { + paddedData = make([]byte, e.padding) + copy(paddedData[:length], data) + rand.Read(paddedData[length:]) + } + return e.transform(paddedData, key), nil +} + +func (e *encryption) Decrypt(data []byte, key Key) ([]byte, error) { + length := len(data) + if e.padding > 0 && length != e.padding { + return nil, fmt.Errorf("Data length different than padding, data length %v padding %v", length, e.padding) + } + + return e.transform(data, key), nil +} + +func (e *encryption) transform(data []byte, key Key) []byte { + dataLength := len(data) + transformedData := make([]byte, dataLength) + hasher := e.hashFunc() + ctr := e.initCtr + hashSize := hasher.Size() + for i := 0; i < dataLength; i += hashSize { + hasher.Write(key) + + ctrBytes := make([]byte, 4) + binary.LittleEndian.PutUint32(ctrBytes, ctr) + + hasher.Write(ctrBytes) + + ctrHash := hasher.Sum(nil) + hasher.Reset() + hasher.Write(ctrHash) + + segmentKey := hasher.Sum(nil) + + hasher.Reset() + + segmentSize := min(hashSize, dataLength-i) + for j := 0; j < segmentSize; j++ { + transformedData[i+j] = data[i+j] ^ segmentKey[j] + } + ctr++ + } + return transformedData +} + +func GenerateRandomKey() (Key, error) { + key := make([]byte, KeyLength) + _, err := rand.Read(key) + return key, err +} + +func min(x, y int) int { + if x < y { + return x + } + return y +} diff --git a/swarm/storage/encryption/encryption_test.go b/swarm/storage/encryption/encryption_test.go new file mode 100644 index 0000000000..5ea546d6bf --- /dev/null +++ b/swarm/storage/encryption/encryption_test.go @@ -0,0 +1,149 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package encryption + +import ( + "bytes" + "crypto/rand" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto/sha3" +) + +var expectedTransformedHex = "470c6c67ba1820d5cb4c23ccef22aa2417a323dc97e5f5dced930d74f2932fd178df80ddf129f4f8a4ccec0225c1c2e6765cbbd92bbad8413c50d93d53f7b2fec975d6f29468eccdaf6458f7a3306a7bc207211ea7f9ee5e6951ce6874aef09eb7ff9bed0aa00920b4dcc105e5f1f8dfbdb0564751311d6ceaca1e4e6d988097582638106404c03cfaef8db0e46674d9e8192c1b62d1cd952389cab3a8dee9329fdb059bafd9bae3df3a6b5a9a10961a0333016c99ee3d65cf18ea8ea7b4c386d59dcbf317460d517d5b55504b5992ffb9c3d7c49ebe1fe3ab7b00ad84b1d76d95f8165141260e6980b2ffe8a0000c36dd77ace4c7a781887f831f740d92d8b4848f1b9e237877b988b5a3e23d7b07b2c8eda0ea9fa748ab10bb6bfd7447b66f44e528d24eff31defdecddaf2bb5e6b8e2aa3d2f1a83de44e0ee3789b75dadba1375b7f3a8f7f1eb2d9b78ad1844d425fb76ea6ba45eabe88f1e062d7552d8c7d44c9c66c2753c41892cb675fd1d564b5f4746e76aa4b24ad121a907b8786715483067f46f1cd4a3dad5125f58c3d348db776e99e8a562ebe603e0e98509c72118ee81259b43f1f770dc9220dddbe4d12d2ffabdad76663d1cf30304eacbb43e9bbe0e4f95aae8609bf8a0786e56e0d20d4875d17cec644ca16824424c6c0700e5082ad5288d1a9fec637b75d24c270086a3606b97cc3240314ac123c04ff4d67ef547504f0eeea5e6252f9b5b75e47d32e583c4dee95ac84b6f03fef412e24c09697d6f7bc8408c2118c524f8e277b82658a5869d6d69d7fde469be27ea33fa22b47f3276f60580f2a05b0fbceb67949d2c8e6d8b097ceef6781d962866b23bc71b54597dd05caafbd533ff4e0013f0fc7e202782ba1e6ccd11242a5bc823af9ad0d5bcb8b78d0ce150fc6f8b97c66f9337adaf3878cbb70733044fd14f318d8e389940d07e0593e35f46dc84e7a9a75dadda153bbe5755af0683cfd262ce3797b1bc648a4e5cef5d9aa47d08cf78c6c9dd872096deb856680d5d932abfd5f2024f908ab84d19b762fdcd31209b1d9adf9cbab904bc58f5b00d5a3e0eb2ade52c7c9a678aadedb1b9257263e6145d34ebcc250d0867e2fdc2ed23b4a8e8aa580424308b543b76595f7e09127e8c301d3f6c228e656df2b5e63a89d634db2f87249025ad3b53d2703d6b93c4ab6b1dee4f9b4d2a0b383ed87458e0e1b2a3c04f9a08b885d856ea7ca9abda9a9c8bd28ecce78675b16829493dbeb66963a3665a8386bc4b97d13cfacacfa80b12e36b598d4f09ab7847481a95b35a937bd4f0107598844fc518c4134e8ca55cec024773dcf0a17c71f602406363dcc03912f23cffad9c611e34605fb03fea3d84aac33886efed6c53d455c786231436c01524cd41e2b6c35b339feaa94d7df0b3572db5595c05a1d4a96e1a17e814cea965be81786784af5697b5c7909fd7701d0f5d991f469e20fbc39536239c7a53278c0b1189253d3d978d54b51d33e0c8ac03ca1f08cfd440130944ae9d353b0b7f263a3a27d15290f35c0ad7cf62e8429ebfa10f5471987c53c5d574c9aebb935bdb8339fee9e1030b3f2845c36272642233afba71f81f10322057b51a33b434a4bc45530581c4a636895fc773e20cf6b8a6cef060920310f4cb79f735fc14e758f646b0cf3bf0ce1f1479788f5b73507203d54022c7afd805d46f45e7ede96b2660869939440d7d575fbf372a7f63421728343dfd88c5fa29ea3f15b68fe360f54afa0681093f2c82888d6babf9558159383c1a76264deec2d7fccb20dbd3ab4b3f137fb3dcf253fb6953df2f663d08e8b39909c9dbff98d49377ce0ce03c580b5e1bca6fcf58aceda42b00b1f478cff2995d47c82f2d5a3dc0e9718a0a46d8330353f2039e68d9565d29e77efea91e058ae03140a4b58b297ae664c9f0e7af78f3633f4aeabd95fd367ac5c67eb63fa2bd7035f4adfe3ab8502952d1675b47118b2006b4a5a1b2a3d03aa670862adc5f1ad1b39f0e4a08e2412128e0ef5fa84366b4b50992cc139e7837f8d65f8eae3c8dc2730f2ef1e1585ce95b0fe354c6c853526558a1732171b6017254ba0f0c22273b55caa2ee680791fb34e22bf897a0998156083c83d03310956b1f947ef474c90b2d7e20beae27f5d33b79ad6d9b1b0188e3cf850108f3a02f9386a314b97fb6c946e572e40024da3e4784c523cf2a70e45f6c0f8f35e9b279aecee183ccb30477ee4f5d57c246ab9918495159307935340a92bd46d6519bcc51af4a785a7eb7fa6eae9def89e2411efd2cb2c33f4d605b77af1ae298967fd846453e8b0a55c57706e79d7badd93268d93be27790bbb051496552b094f37bf96843cdf7604dc7f696976bebbe3561c7bd4b3f2843bd07e34a3c3acf0d6c755014a3e9d922dabdbc892511b6af3214958b3531baceab9082c2b4e19ef802b99db2cfa4076ba681efae8a9546582e4cbf07000fb3903727261b93d1bd08809ddc41b2a61b0bfa6b9210b8731394fd9084bc1406bcdd0992410e90f749a087edafb76f6617209855269bb5c89711d2830ea99f2a0e548991ef8dd3e62ced239dff4e9d8c1e834fb57078dc2a4322acc1ea1dbe64064db4cc2a7cdc32884cb7c31aa3c95634356b4d32f1c92fa039e5ed18c1af6605e2f66e5383fa1fcc610a3cc1eef5fe6296ac378f2440d0bd3c77d458af0bfa6b64cedd0301b116efafbbb8f9e88d4bedf56d11cfe0967fc06932e1f232c7daf2c73b58c52daa82dc22b2290147e358348f991f1473c4e63ac943cabc429f5689da8aee6801fd941778966da87fe137b033a0231a90a2ac759efbcb7c52de8e8f27bcc4e5bcb560524d17b0345727f8092e22b6a0e03ceee355085d4fe81568b5b8b84b69870dd333c9b3bdca45db7e43b876a217819928fec31f3ca4c44c4f03a91d578f9ed883bf1247a10eefe42279484af6f70719e193b07a14fc7d93fd6cee9e883a81cc51b53044fa2f1b2525c10e23fb988b31559e1fae4c082d905486d984d2f1e87c40976a571f92e4fdf09e23cad561d9cd3d1ca94e778d08b82852dbe9bab2c7f147c6078504c30fc3fe749fca95ed23791dcf6b935ab0ed08645c481cd2b7969258405f183593617c0d24ebe79bc6c87df65ddc25f933b12a641cc95cf321c1b2edf5db5813a98d99fd1760b5fac19c2b47c2a750e96da49c97276cf31cbd73e1e93ef6990fdf1b08a3e7963dffcf65aa6496727f6be5d9225cfbbadfd6a3a06a454acbb80e761699be97b9caeb71dc3c20a2c253f349ee190b9d8c1ff95751a281ed88b098e4a78fae8249232d4280daf46580ca6c14411f8c4d0e8fa44f8808a5a2dda36d35f79aa77c1c4c615216ec309aa5f3caff3a449b9740baad11e525a5651416a12dd4688897b5ee5e1e8361a87269e9be0789ea7564f64752788f3ac57bda4aa45582d8dabc4d44759639984514d9b151004bf0d9d3140becde41603ffd9d412ec08a1b2f7262862a761d7ce5b91a239d68cdfe7c615b62217422c5a224e652cffdbbe7b41064c9375bbf2c23b63130afedd93987c1f1e4a1623a77d3ef4960fd232afc7d12159c8f1245984e4bd390685668f10da77bf5f6130a5d405a42fb02d0048d63ca48cd4901f3704975b0493714c78de33c1a969993529bac13e310ee098a7b1e8e93b4fcb269773a1521defef98f403f79a8e24e1594b8dc6055223b79b4d7009498c02790a37dd3a9ac7168b11568877ee852395165f87d881355327e57ba48be948b1325824244a552ca80c2ecb79a04a199f0b6a58b455327d998a67ebae414394928161a311de9d3d7f1fc99c0bc35b0a814e7821d2d6958129775c56fdd9b28b6e43a3132a95eb64805f9941b0c5ca2078c37bc7a4d43ddcbc6e8c66de2ef51c714a81913bebeb8f9c6aa14da7e71854870fba9f093aa77abeb23e8d37f3a50135a3f894d1cdf647d3dceb3f16ad4b4f01dffe99d74cd1f18d37735ac69287df0a8b49b2fc3773bf426c881b64a1241c1143e39b6dca59e28c116947aac39585dd81f6fe3832f97d873884738982976f9f29aa6463662cc81c2abbd5eafbb3d9800ba811410a521065d61ad01cfde2c2d98f5fa0ec63e8b01ec6a2d738a1f6cf8c99725079aa51ed3dc7630deeea0b27ee8edbfa19bdb8504cf80a1ca74ea6777fa8786fd76d4ab019c00da35278bf49be5a42aff264875b69bab9e7f3f9299f2ea6a883fc5fd77e34debf414ce8af37a3e9a7de05f33bc547899d25a13389d9048be8b2b7c9b836b401eac9c53ba3d44a14e683a6b378248fdedcbfbc408e5ec83a6c3f769533ae90e339222d80d433ae820fca43d80bca7fbd9d6e5eb760271c74a95a35a853285f7dcfe10182af922508501d269cc53ed38756e8d202b25782ec208a39981ef6c9e9342eb6cee2142471574ab39ebdbbf140f64e305d6f6aa73d49d5bb765347a27ebd0ba1bdcaa8a383526b41f3361faddafec726e185cc223f8465472d7a53ad2d74717960ba5684bc692f773e680d0247f9de1650c046ea56fa18c1c3fb6636327f863f37dca86867c57cc643ff6b7973f97c91716502c33f0dc66176357315f09064c70df7db026413567ac9ec7605acd80606d962f7463359998b92f8a33ccffc80f6e162c1b5a65404e0cc4e37688ded910e6ae5f774e3238a1248b05c53486d149734dd1e38073603df0aa4a4f01fd0c1a0e82b6a513f7d22d1b09ff107923462fbfffbf5fb1f2c043e305917eee1f7f18f62dc604a1d39e5bf675dca67da52f95d312b31be7720efd391bf4794f0555b299325b5dfea9eb00e695861634ad28717cffff266e30c864ba844b0c3fd88bd0cee4d929530c2bb3663c5170a15a66c412ff2fed2d962dd0ff145f19f8085931cbd6bde4c11c9c2debfbdb6748d1a6dabf1404762343d468944a0495026091bc44c69dad971890b7221e1eac2e985097d344a4e2375938aa93806ad1715be8d05f4068ec67ef411e704b01851b7427c4137e6dadedfbb25378ecf1c6b749214f2655cf43fdbb72cb842aaab3074cd792f30f96e874d92f2ef62667d81ccd663dfd969c18dff790b6b7b261f0a03baa85bfd7db72baffe2ddc4cc3985183301a77daa826b1f76f6b6f2ac075c6a2b86609e4d26eb08f3ed6f341d7946966e654ed2c30a629ff81a57014a84105a9ad36a525033f16e3e60d639bf8f89ae6cfdbcdb41e93859354957dcfe9a847757c3cd946d8994cda126f146b77119bbc87c49ce79ad844715cd9bb0c7a4f800fce14c81d175aed59fce0377e62c6e597ab5acf1b3b7100403f371c19dd0f131c4c572e57e3e13743f9bac24a6a177d71f03c5d185bb7e163ec5866dda629340a964bc442d423ad7bc5187f3da68d1498dfe9f1815b31bae11df3585ece230cc3521f7a0b4b3360ddf898984b528afff75f229915f1f2d5c4491c65e2f38d26c0de7dc483860da7bf52859fdbc21946badec0bbf00ba8143b8b7289cfb7096d3405e3183e56f1cbb8c48f25d058530894d0302cdce7c43ea31768b5b610820c97f6e9a8e31a8e9c4624117d213a03ef7d655513cffd8fb5606fc8790692c99828a47382e3e37b9c1317028f5c9d196ff3c2f09435df7614fb37ea20b2371c52b6c4667799922010edeb28001de2a137889db4d3dbf0a406ba90f3631be485ec5e4110b01502f557f15026716030fb6384499adee3cfc44015638e05b206ce3cbc3cbf21b7dd1dcb3b932629e7cd4f4f6b148f37f976803644e5ce792583daf39608a3cd02ff2f47e9bc6" + +var hashFunc = sha3.NewKeccak256 + +func TestEncryptDataLongerThanPadding(t *testing.T) { + enc := New(4095, uint32(0), hashFunc) + + data := make([]byte, 4096) + key := make([]byte, 32) + + expectedError := "Data length longer than padding, data length 4096 padding 4095" + + _, err := enc.Encrypt(data, key) + if err == nil || err.Error() != expectedError { + t.Fatalf("Expected error \"%v\" got \"%v\"", expectedError, err) + } +} + +func TestEncryptDataZeroPadding(t *testing.T) { + enc := New(0, uint32(0), hashFunc) + + data := make([]byte, 2048) + key := make([]byte, 32) + + encrypted, err := enc.Encrypt(data, key) + if err != nil { + t.Fatalf("Expected no error got %v", err) + } + if len(encrypted) != 2048 { + t.Fatalf("Encrypted data length expected \"%v\" got %v", 2048, len(encrypted)) + } +} + +func TestEncryptDataLengthEqualsPadding(t *testing.T) { + enc := New(4096, uint32(0), hashFunc) + + data := make([]byte, 4096) + key := make([]byte, 32) + + encrypted, err := enc.Encrypt(data, key) + if err != nil { + t.Fatalf("Expected no error got %v", err) + } + encryptedHex := common.Bytes2Hex(encrypted) + expectedTransformed := common.Hex2Bytes(expectedTransformedHex) + + if !bytes.Equal(encrypted, expectedTransformed) { + t.Fatalf("Expected %v got %v", expectedTransformedHex, encryptedHex) + } +} + +func TestEncryptDataLengthSmallerThanPadding(t *testing.T) { + enc := New(4096, uint32(0), hashFunc) + + data := make([]byte, 4080) + key := make([]byte, 32) + + encrypted, err := enc.Encrypt(data, key) + if err != nil { + t.Fatalf("Expected no error got %v", err) + } + if len(encrypted) != 4096 { + t.Fatalf("Encrypted data length expected %v got %v", 4096, len(encrypted)) + } +} + +func TestEncryptDataCounterNonZero(t *testing.T) { + // TODO +} + +func TestDecryptDataLengthNotEqualsPadding(t *testing.T) { + enc := New(4096, uint32(0), hashFunc) + + data := make([]byte, 4097) + key := make([]byte, 32) + + expectedError := "Data length different than padding, data length 4097 padding 4096" + + _, err := enc.Decrypt(data, key) + if err == nil || err.Error() != expectedError { + t.Fatalf("Expected error \"%v\" got \"%v\"", expectedError, err) + } +} + +func TestEncryptDecryptIsIdentity(t *testing.T) { + testEncryptDecryptIsIdentity(t, 2048, 0, 2048, 32) + testEncryptDecryptIsIdentity(t, 4096, 0, 4096, 32) + testEncryptDecryptIsIdentity(t, 4096, 0, 1000, 32) + testEncryptDecryptIsIdentity(t, 32, 10, 32, 32) +} + +func testEncryptDecryptIsIdentity(t *testing.T, padding int, initCtr uint32, dataLength int, keyLength int) { + enc := New(padding, initCtr, hashFunc) + + data := make([]byte, dataLength) + rand.Read(data) + + key := make([]byte, keyLength) + rand.Read(key) + + encrypted, err := enc.Encrypt(data, key) + if err != nil { + t.Fatalf("Expected no error got %v", err) + } + + decrypted, err := enc.Decrypt(encrypted, key) + if err != nil { + t.Fatalf("Expected no error got %v", err) + } + if len(decrypted) != padding { + t.Fatalf("Expected decrypted data length %v got %v", padding, len(decrypted)) + } + + // we have to remove the extra bytes which were randomly added to fill until padding + if len(data) < padding { + decrypted = decrypted[:len(data)] + } + + if !bytes.Equal(data, decrypted) { + t.Fatalf("Expected decrypted %v got %v", common.Bytes2Hex(data), common.Bytes2Hex(decrypted)) + } +} diff --git a/swarm/storage/error.go b/swarm/storage/error.go new file mode 100644 index 0000000000..44261c084e --- /dev/null +++ b/swarm/storage/error.go @@ -0,0 +1,45 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package storage + +import ( + "errors" +) + +const ( + ErrInit = iota + ErrNotFound + ErrIO + ErrUnauthorized + ErrInvalidValue + ErrDataOverflow + ErrNothingToReturn + ErrCorruptData + ErrInvalidSignature + ErrNotSynced + ErrPeriodDepth + ErrCnt +) + +var ( + ErrChunkNotFound = errors.New("chunk not found") + ErrFetching = errors.New("chunk still fetching") + ErrChunkInvalid = errors.New("invalid chunk") + ErrChunkForward = errors.New("cannot forward") + ErrChunkUnavailable = errors.New("chunk unavailable") + ErrChunkTimeout = errors.New("timeout") +) diff --git a/swarm/storage/filestore.go b/swarm/storage/filestore.go new file mode 100644 index 0000000000..2d8d82d95a --- /dev/null +++ b/swarm/storage/filestore.go @@ -0,0 +1,98 @@ +// 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 storage + +import ( + "context" + "io" +) + +/* +FileStore provides the client API entrypoints Store and Retrieve to store and retrieve +It can store anything that has a byte slice representation, so files or serialised objects etc. + +Storage: FileStore calls the Chunker to segment the input datastream of any size to a merkle hashed tree of chunks. The key of the root block is returned to the client. + +Retrieval: given the key of the root block, the FileStore retrieves the block chunks and reconstructs the original data and passes it back as a lazy reader. A lazy reader is a reader with on-demand delayed processing, i.e. the chunks needed to reconstruct a large file are only fetched and processed if that particular part of the document is actually read. + +As the chunker produces chunks, FileStore dispatches them to its own chunk store +implementation for storage or retrieval. +*/ + +const ( + defaultLDBCapacity = 5000000 // capacity for LevelDB, by default 5*10^6*4096 bytes == 20GB + defaultCacheCapacity = 10000 // capacity for in-memory chunks' cache + defaultChunkRequestsCacheCapacity = 5000000 // capacity for container holding outgoing requests for chunks. should be set to LevelDB capacity +) + +type FileStore struct { + ChunkStore + hashFunc SwarmHasher +} + +type FileStoreParams struct { + Hash string +} + +func NewFileStoreParams() *FileStoreParams { + return &FileStoreParams{ + Hash: DefaultHash, + } +} + +// for testing locally +func NewLocalFileStore(datadir string, basekey []byte) (*FileStore, error) { + params := NewDefaultLocalStoreParams() + params.Init(datadir) + localStore, err := NewLocalStore(params, nil) + if err != nil { + return nil, err + } + localStore.Validators = append(localStore.Validators, NewContentAddressValidator(MakeHashFunc(DefaultHash))) + return NewFileStore(localStore, NewFileStoreParams()), nil +} + +func NewFileStore(store ChunkStore, params *FileStoreParams) *FileStore { + hashFunc := MakeHashFunc(params.Hash) + return &FileStore{ + ChunkStore: store, + hashFunc: hashFunc, + } +} + +// Public API. Main entry point for document retrieval directly. Used by the +// FS-aware API and httpaccess +// Chunk retrieval blocks on netStore requests with a timeout so reader will +// report error if retrieval of chunks within requested range time out. +// It returns a reader with the chunk data and whether the content was encrypted +func (f *FileStore) Retrieve(ctx context.Context, addr Address) (reader *LazyChunkReader, isEncrypted bool) { + isEncrypted = len(addr) > f.hashFunc().Size() + getter := NewHasherStore(f.ChunkStore, f.hashFunc, isEncrypted) + reader = TreeJoin(ctx, addr, getter, 0) + return +} + +// Public API. Main entry point for document storage directly. Used by the +// FS-aware API and httpaccess +func (f *FileStore) Store(ctx context.Context, data io.Reader, size int64, toEncrypt bool) (addr Address, wait func(context.Context) error, err error) { + putter := NewHasherStore(f.ChunkStore, f.hashFunc, toEncrypt) + return PyramidSplit(ctx, data, putter, putter) +} + +func (f *FileStore) HashSize() int { + return f.hashFunc().Size() +} diff --git a/swarm/storage/dpa_test.go b/swarm/storage/filestore_test.go similarity index 55% rename from swarm/storage/dpa_test.go rename to swarm/storage/filestore_test.go index a23b9efebe..f3f5972558 100644 --- a/swarm/storage/dpa_test.go +++ b/swarm/storage/filestore_test.go @@ -18,40 +18,51 @@ package storage import ( "bytes" + "context" "io" "io/ioutil" "os" - "sync" "testing" ) const testDataSize = 0x1000000 -func TestDPArandom(t *testing.T) { - dbStore := initDbStore(t) - dbStore.setCapacity(50000) - memStore := NewMemStore(dbStore, defaultCacheCapacity) +func TestFileStorerandom(t *testing.T) { + testFileStoreRandom(false, t) + testFileStoreRandom(true, t) +} + +func testFileStoreRandom(toEncrypt bool, t *testing.T) { + tdb, cleanup, err := newTestDbStore(false, false) + defer cleanup() + if err != nil { + t.Fatalf("init dbStore failed: %v", err) + } + db := tdb.LDBStore + db.setCapacity(50000) + memStore := NewMemStore(NewDefaultStoreParams(), db) localStore := &LocalStore{ - memStore, - dbStore, + memStore: memStore, + DbStore: db, } - chunker := NewTreeChunker(NewChunkerParams()) - dpa := &DPA{ - Chunker: chunker, - ChunkStore: localStore, - } - dpa.Start() - defer dpa.Stop() + + fileStore := NewFileStore(localStore, NewFileStoreParams()) defer os.RemoveAll("/tmp/bzz") - reader, slice := testDataReaderAndSlice(testDataSize) - wg := &sync.WaitGroup{} - key, err := dpa.Store(reader, testDataSize, wg, nil) + reader, slice := generateRandomData(testDataSize) + ctx := context.TODO() + key, wait, err := fileStore.Store(ctx, reader, testDataSize, toEncrypt) if err != nil { t.Errorf("Store error: %v", err) } - wg.Wait() - resultReader := dpa.Retrieve(key) + err = wait(ctx) + if err != nil { + t.Fatalf("Store waitt error: %v", err.Error()) + } + resultReader, isEncrypted := fileStore.Retrieve(context.TODO(), key) + if isEncrypted != toEncrypt { + t.Fatalf("isEncrypted expected %v got %v", toEncrypt, isEncrypted) + } resultSlice := make([]byte, len(slice)) n, err := resultReader.ReadAt(resultSlice, 0) if err != io.EOF { @@ -65,8 +76,11 @@ func TestDPArandom(t *testing.T) { } ioutil.WriteFile("/tmp/slice.bzz.16M", slice, 0666) ioutil.WriteFile("/tmp/result.bzz.16M", resultSlice, 0666) - localStore.memStore = NewMemStore(dbStore, defaultCacheCapacity) - resultReader = dpa.Retrieve(key) + localStore.memStore = NewMemStore(NewDefaultStoreParams(), db) + resultReader, isEncrypted = fileStore.Retrieve(context.TODO(), key) + if isEncrypted != toEncrypt { + t.Fatalf("isEncrypted expected %v got %v", toEncrypt, isEncrypted) + } for i := range resultSlice { resultSlice[i] = 0 } @@ -82,28 +96,38 @@ func TestDPArandom(t *testing.T) { } } -func TestDPA_capacity(t *testing.T) { - dbStore := initDbStore(t) - memStore := NewMemStore(dbStore, defaultCacheCapacity) +func TestFileStoreCapacity(t *testing.T) { + testFileStoreCapacity(false, t) + testFileStoreCapacity(true, t) +} + +func testFileStoreCapacity(toEncrypt bool, t *testing.T) { + tdb, cleanup, err := newTestDbStore(false, false) + defer cleanup() + if err != nil { + t.Fatalf("init dbStore failed: %v", err) + } + db := tdb.LDBStore + memStore := NewMemStore(NewDefaultStoreParams(), db) localStore := &LocalStore{ - memStore, - dbStore, + memStore: memStore, + DbStore: db, } - memStore.setCapacity(0) - chunker := NewTreeChunker(NewChunkerParams()) - dpa := &DPA{ - Chunker: chunker, - ChunkStore: localStore, - } - dpa.Start() - reader, slice := testDataReaderAndSlice(testDataSize) - wg := &sync.WaitGroup{} - key, err := dpa.Store(reader, testDataSize, wg, nil) + fileStore := NewFileStore(localStore, NewFileStoreParams()) + reader, slice := generateRandomData(testDataSize) + ctx := context.TODO() + key, wait, err := fileStore.Store(ctx, reader, testDataSize, toEncrypt) if err != nil { t.Errorf("Store error: %v", err) } - wg.Wait() - resultReader := dpa.Retrieve(key) + err = wait(ctx) + if err != nil { + t.Errorf("Store error: %v", err) + } + resultReader, isEncrypted := fileStore.Retrieve(context.TODO(), key) + if isEncrypted != toEncrypt { + t.Fatalf("isEncrypted expected %v got %v", toEncrypt, isEncrypted) + } resultSlice := make([]byte, len(slice)) n, err := resultReader.ReadAt(resultSlice, 0) if err != io.EOF { @@ -118,15 +142,21 @@ func TestDPA_capacity(t *testing.T) { // Clear memStore memStore.setCapacity(0) // check whether it is, indeed, empty - dpa.ChunkStore = memStore - resultReader = dpa.Retrieve(key) + fileStore.ChunkStore = memStore + resultReader, isEncrypted = fileStore.Retrieve(context.TODO(), key) + if isEncrypted != toEncrypt { + t.Fatalf("isEncrypted expected %v got %v", toEncrypt, isEncrypted) + } if _, err = resultReader.ReadAt(resultSlice, 0); err == nil { t.Errorf("Was able to read %d bytes from an empty memStore.", len(slice)) } // check how it works with localStore - dpa.ChunkStore = localStore + fileStore.ChunkStore = localStore // localStore.dbStore.setCapacity(0) - resultReader = dpa.Retrieve(key) + resultReader, isEncrypted = fileStore.Retrieve(context.TODO(), key) + if isEncrypted != toEncrypt { + t.Fatalf("isEncrypted expected %v got %v", toEncrypt, isEncrypted) + } for i := range resultSlice { resultSlice[i] = 0 } diff --git a/swarm/storage/hasherstore.go b/swarm/storage/hasherstore.go new file mode 100644 index 0000000000..139c0ee031 --- /dev/null +++ b/swarm/storage/hasherstore.go @@ -0,0 +1,231 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package storage + +import ( + "context" + "fmt" + "sync" + + "github.com/ethereum/go-ethereum/crypto/sha3" + "github.com/ethereum/go-ethereum/swarm/storage/encryption" +) + +type chunkEncryption struct { + spanEncryption encryption.Encryption + dataEncryption encryption.Encryption +} + +type hasherStore struct { + store ChunkStore + hashFunc SwarmHasher + chunkEncryption *chunkEncryption + hashSize int // content hash size + refSize int64 // reference size (content hash + possibly encryption key) + wg *sync.WaitGroup + closed chan struct{} +} + +func newChunkEncryption(chunkSize, refSize int64) *chunkEncryption { + return &chunkEncryption{ + spanEncryption: encryption.New(0, uint32(chunkSize/refSize), sha3.NewKeccak256), + dataEncryption: encryption.New(int(chunkSize), 0, sha3.NewKeccak256), + } +} + +// NewHasherStore creates a hasherStore object, which implements Putter and Getter interfaces. +// With the HasherStore you can put and get chunk data (which is just []byte) into a ChunkStore +// and the hasherStore will take core of encryption/decryption of data if necessary +func NewHasherStore(chunkStore ChunkStore, hashFunc SwarmHasher, toEncrypt bool) *hasherStore { + var chunkEncryption *chunkEncryption + + hashSize := hashFunc().Size() + refSize := int64(hashSize) + if toEncrypt { + refSize += encryption.KeyLength + chunkEncryption = newChunkEncryption(DefaultChunkSize, refSize) + } + + return &hasherStore{ + store: chunkStore, + hashFunc: hashFunc, + chunkEncryption: chunkEncryption, + hashSize: hashSize, + refSize: refSize, + wg: &sync.WaitGroup{}, + closed: make(chan struct{}), + } +} + +// Put stores the chunkData into the ChunkStore of the hasherStore and returns the reference. +// If hasherStore has a chunkEncryption object, the data will be encrypted. +// Asynchronous function, the data will not necessarily be stored when it returns. +func (h *hasherStore) Put(ctx context.Context, chunkData ChunkData) (Reference, error) { + c := chunkData + size := chunkData.Size() + var encryptionKey encryption.Key + if h.chunkEncryption != nil { + var err error + c, encryptionKey, err = h.encryptChunkData(chunkData) + if err != nil { + return nil, err + } + } + chunk := h.createChunk(c, size) + + h.storeChunk(ctx, chunk) + + return Reference(append(chunk.Addr, encryptionKey...)), nil +} + +// Get returns data of the chunk with the given reference (retrieved from the ChunkStore of hasherStore). +// If the data is encrypted and the reference contains an encryption key, it will be decrypted before +// return. +func (h *hasherStore) Get(ctx context.Context, ref Reference) (ChunkData, error) { + key, encryptionKey, err := parseReference(ref, h.hashSize) + if err != nil { + return nil, err + } + toDecrypt := (encryptionKey != nil) + + chunk, err := h.store.Get(ctx, key) + if err != nil { + return nil, err + } + + chunkData := chunk.SData + if toDecrypt { + var err error + chunkData, err = h.decryptChunkData(chunkData, encryptionKey) + if err != nil { + return nil, err + } + } + return chunkData, nil +} + +// Close indicates that no more chunks will be put with the hasherStore, so the Wait +// function can return when all the previously put chunks has been stored. +func (h *hasherStore) Close() { + close(h.closed) +} + +// Wait returns when +// 1) the Close() function has been called and +// 2) all the chunks which has been Put has been stored +func (h *hasherStore) Wait(ctx context.Context) error { + <-h.closed + h.wg.Wait() + return nil +} + +func (h *hasherStore) createHash(chunkData ChunkData) Address { + hasher := h.hashFunc() + hasher.ResetWithLength(chunkData[:8]) // 8 bytes of length + hasher.Write(chunkData[8:]) // minus 8 []byte length + return hasher.Sum(nil) +} + +func (h *hasherStore) createChunk(chunkData ChunkData, chunkSize int64) *Chunk { + hash := h.createHash(chunkData) + chunk := NewChunk(hash, nil) + chunk.SData = chunkData + chunk.Size = chunkSize + + return chunk +} + +func (h *hasherStore) encryptChunkData(chunkData ChunkData) (ChunkData, encryption.Key, error) { + if len(chunkData) < 8 { + return nil, nil, fmt.Errorf("Invalid ChunkData, min length 8 got %v", len(chunkData)) + } + + encryptionKey, err := encryption.GenerateRandomKey() + if err != nil { + return nil, nil, err + } + + encryptedSpan, err := h.chunkEncryption.spanEncryption.Encrypt(chunkData[:8], encryptionKey) + if err != nil { + return nil, nil, err + } + encryptedData, err := h.chunkEncryption.dataEncryption.Encrypt(chunkData[8:], encryptionKey) + if err != nil { + return nil, nil, err + } + c := make(ChunkData, len(encryptedSpan)+len(encryptedData)) + copy(c[:8], encryptedSpan) + copy(c[8:], encryptedData) + return c, encryptionKey, nil +} + +func (h *hasherStore) decryptChunkData(chunkData ChunkData, encryptionKey encryption.Key) (ChunkData, error) { + if len(chunkData) < 8 { + return nil, fmt.Errorf("Invalid ChunkData, min length 8 got %v", len(chunkData)) + } + + decryptedSpan, err := h.chunkEncryption.spanEncryption.Decrypt(chunkData[:8], encryptionKey) + if err != nil { + return nil, err + } + + decryptedData, err := h.chunkEncryption.dataEncryption.Decrypt(chunkData[8:], encryptionKey) + if err != nil { + return nil, err + } + + // removing extra bytes which were just added for padding + length := ChunkData(decryptedSpan).Size() + for length > DefaultChunkSize { + length = length + (DefaultChunkSize - 1) + length = length / DefaultChunkSize + length *= h.refSize + } + + c := make(ChunkData, length+8) + copy(c[:8], decryptedSpan) + copy(c[8:], decryptedData[:length]) + + return c[:length+8], nil +} + +func (h *hasherStore) RefSize() int64 { + return h.refSize +} + +func (h *hasherStore) storeChunk(ctx context.Context, chunk *Chunk) { + h.wg.Add(1) + go func() { + <-chunk.dbStoredC + h.wg.Done() + }() + h.store.Put(ctx, chunk) +} + +func parseReference(ref Reference, hashSize int) (Address, encryption.Key, error) { + encryptedKeyLength := hashSize + encryption.KeyLength + switch len(ref) { + case KeyLength: + return Address(ref), nil, nil + case encryptedKeyLength: + encKeyIdx := len(ref) - encryption.KeyLength + return Address(ref[:encKeyIdx]), encryption.Key(ref[encKeyIdx:]), nil + default: + return nil, nil, fmt.Errorf("Invalid reference length, expected %v or %v got %v", hashSize, encryptedKeyLength, len(ref)) + } + +} diff --git a/swarm/storage/hasherstore_test.go b/swarm/storage/hasherstore_test.go new file mode 100644 index 0000000000..ddf1c39b08 --- /dev/null +++ b/swarm/storage/hasherstore_test.go @@ -0,0 +1,122 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package storage + +import ( + "bytes" + "context" + "testing" + + "github.com/ethereum/go-ethereum/swarm/storage/encryption" + + "github.com/ethereum/go-ethereum/common" +) + +func TestHasherStore(t *testing.T) { + var tests = []struct { + chunkLength int + toEncrypt bool + }{ + {10, false}, + {100, false}, + {1000, false}, + {4096, false}, + {10, true}, + {100, true}, + {1000, true}, + {4096, true}, + } + + for _, tt := range tests { + chunkStore := NewMapChunkStore() + hasherStore := NewHasherStore(chunkStore, MakeHashFunc(DefaultHash), tt.toEncrypt) + + // Put two random chunks into the hasherStore + chunkData1 := GenerateRandomChunk(int64(tt.chunkLength)).SData + key1, err := hasherStore.Put(context.TODO(), chunkData1) + if err != nil { + t.Fatalf("Expected no error got \"%v\"", err) + } + + chunkData2 := GenerateRandomChunk(int64(tt.chunkLength)).SData + key2, err := hasherStore.Put(context.TODO(), chunkData2) + if err != nil { + t.Fatalf("Expected no error got \"%v\"", err) + } + + hasherStore.Close() + + // Wait until chunks are really stored + err = hasherStore.Wait(context.TODO()) + if err != nil { + t.Fatalf("Expected no error got \"%v\"", err) + } + + // Get the first chunk + retrievedChunkData1, err := hasherStore.Get(context.TODO(), key1) + if err != nil { + t.Fatalf("Expected no error, got \"%v\"", err) + } + + // Retrieved data should be same as the original + if !bytes.Equal(chunkData1, retrievedChunkData1) { + t.Fatalf("Expected retrieved chunk data %v, got %v", common.Bytes2Hex(chunkData1), common.Bytes2Hex(retrievedChunkData1)) + } + + // Get the second chunk + retrievedChunkData2, err := hasherStore.Get(context.TODO(), key2) + if err != nil { + t.Fatalf("Expected no error, got \"%v\"", err) + } + + // Retrieved data should be same as the original + if !bytes.Equal(chunkData2, retrievedChunkData2) { + t.Fatalf("Expected retrieved chunk data %v, got %v", common.Bytes2Hex(chunkData2), common.Bytes2Hex(retrievedChunkData2)) + } + + hash1, encryptionKey1, err := parseReference(key1, hasherStore.hashSize) + if err != nil { + t.Fatalf("Expected no error, got \"%v\"", err) + } + + if tt.toEncrypt { + if encryptionKey1 == nil { + t.Fatal("Expected non-nil encryption key, got nil") + } else if len(encryptionKey1) != encryption.KeyLength { + t.Fatalf("Expected encryption key length %v, got %v", encryption.KeyLength, len(encryptionKey1)) + } + } + if !tt.toEncrypt && encryptionKey1 != nil { + t.Fatalf("Expected nil encryption key, got key with length %v", len(encryptionKey1)) + } + + // Check if chunk data in store is encrypted or not + chunkInStore, err := chunkStore.Get(context.TODO(), hash1) + if err != nil { + t.Fatalf("Expected no error got \"%v\"", err) + } + + chunkDataInStore := chunkInStore.SData + + if tt.toEncrypt && bytes.Equal(chunkData1, chunkDataInStore) { + t.Fatalf("Chunk expected to be encrypted but it is stored without encryption") + } + if !tt.toEncrypt && !bytes.Equal(chunkData1, chunkDataInStore) { + t.Fatalf("Chunk expected to be not encrypted but stored content is different. Expected %v got %v", common.Bytes2Hex(chunkData1), common.Bytes2Hex(chunkDataInStore)) + } + } +} diff --git a/swarm/storage/ldbstore.go b/swarm/storage/ldbstore.go new file mode 100644 index 0000000000..7920ee7674 --- /dev/null +++ b/swarm/storage/ldbstore.go @@ -0,0 +1,772 @@ +// 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 . + +// disk storage layer for the package bzz +// DbStore implements the ChunkStore interface and is used by the FileStore as +// persistent storage of chunks +// it implements purging based on access count allowing for external control of +// max capacity + +package storage + +import ( + "archive/tar" + "bytes" + "context" + "encoding/binary" + "encoding/hex" + "fmt" + "io" + "io/ioutil" + "sort" + "sync" + + "github.com/ethereum/go-ethereum/metrics" + "github.com/ethereum/go-ethereum/rlp" + "github.com/ethereum/go-ethereum/swarm/log" + "github.com/ethereum/go-ethereum/swarm/storage/mock" + "github.com/syndtr/goleveldb/leveldb" + "github.com/syndtr/goleveldb/leveldb/opt" +) + +const ( + gcArrayFreeRatio = 0.1 + maxGCitems = 5000 // max number of items to be gc'd per call to collectGarbage() +) + +var ( + keyIndex = byte(0) + keyOldData = byte(1) + keyAccessCnt = []byte{2} + keyEntryCnt = []byte{3} + keyDataIdx = []byte{4} + keyData = byte(6) + keyDistanceCnt = byte(7) +) + +type gcItem struct { + idx uint64 + value uint64 + idxKey []byte + po uint8 +} + +type LDBStoreParams struct { + *StoreParams + Path string + Po func(Address) uint8 +} + +// NewLDBStoreParams constructs LDBStoreParams with the specified values. +func NewLDBStoreParams(storeparams *StoreParams, path string) *LDBStoreParams { + return &LDBStoreParams{ + StoreParams: storeparams, + Path: path, + Po: func(k Address) (ret uint8) { return uint8(Proximity(storeparams.BaseKey[:], k[:])) }, + } +} + +type LDBStore struct { + db *LDBDatabase + + // this should be stored in db, accessed transactionally + entryCnt uint64 // number of items in the LevelDB + accessCnt uint64 // ever-accumulating number increased every time we read/access an entry + dataIdx uint64 // similar to entryCnt, but we only increment it + capacity uint64 + bucketCnt []uint64 + + hashfunc SwarmHasher + po func(Address) uint8 + + batchC chan bool + batchesC chan struct{} + batch *leveldb.Batch + lock sync.RWMutex + quit chan struct{} + + // Functions encodeDataFunc is used to bypass + // the default functionality of DbStore with + // mock.NodeStore for testing purposes. + encodeDataFunc func(chunk *Chunk) []byte + // If getDataFunc is defined, it will be used for + // retrieving the chunk data instead from the local + // LevelDB database. + getDataFunc func(addr Address) (data []byte, err error) +} + +// TODO: Instead of passing the distance function, just pass the address from which distances are calculated +// to avoid the appearance of a pluggable distance metric and opportunities of bugs associated with providing +// a function different from the one that is actually used. +func NewLDBStore(params *LDBStoreParams) (s *LDBStore, err error) { + s = new(LDBStore) + s.hashfunc = params.Hash + s.quit = make(chan struct{}) + + s.batchC = make(chan bool) + s.batchesC = make(chan struct{}, 1) + go s.writeBatches() + s.batch = new(leveldb.Batch) + // associate encodeData with default functionality + s.encodeDataFunc = encodeData + + s.db, err = NewLDBDatabase(params.Path) + if err != nil { + return nil, err + } + + s.po = params.Po + s.setCapacity(params.DbCapacity) + + s.bucketCnt = make([]uint64, 0x100) + for i := 0; i < 0x100; i++ { + k := make([]byte, 2) + k[0] = keyDistanceCnt + k[1] = uint8(i) + cnt, _ := s.db.Get(k) + s.bucketCnt[i] = BytesToU64(cnt) + s.bucketCnt[i]++ + } + data, _ := s.db.Get(keyEntryCnt) + s.entryCnt = BytesToU64(data) + s.entryCnt++ + data, _ = s.db.Get(keyAccessCnt) + s.accessCnt = BytesToU64(data) + s.accessCnt++ + data, _ = s.db.Get(keyDataIdx) + s.dataIdx = BytesToU64(data) + s.dataIdx++ + + return s, nil +} + +// NewMockDbStore creates a new instance of DbStore with +// mockStore set to a provided value. If mockStore argument is nil, +// this function behaves exactly as NewDbStore. +func NewMockDbStore(params *LDBStoreParams, mockStore *mock.NodeStore) (s *LDBStore, err error) { + s, err = NewLDBStore(params) + if err != nil { + return nil, err + } + + // replace put and get with mock store functionality + if mockStore != nil { + s.encodeDataFunc = newMockEncodeDataFunc(mockStore) + s.getDataFunc = newMockGetDataFunc(mockStore) + } + return +} + +type dpaDBIndex struct { + Idx uint64 + Access uint64 +} + +func BytesToU64(data []byte) uint64 { + if len(data) < 8 { + return 0 + } + return binary.BigEndian.Uint64(data) +} + +func U64ToBytes(val uint64) []byte { + data := make([]byte, 8) + binary.BigEndian.PutUint64(data, val) + return data +} + +func (s *LDBStore) updateIndexAccess(index *dpaDBIndex) { + index.Access = s.accessCnt +} + +func getIndexKey(hash Address) []byte { + hashSize := len(hash) + key := make([]byte, hashSize+1) + key[0] = keyIndex + copy(key[1:], hash[:]) + return key +} + +func getOldDataKey(idx uint64) []byte { + key := make([]byte, 9) + key[0] = keyOldData + binary.BigEndian.PutUint64(key[1:9], idx) + + return key +} + +func getDataKey(idx uint64, po uint8) []byte { + key := make([]byte, 10) + key[0] = keyData + key[1] = po + binary.BigEndian.PutUint64(key[2:], idx) + + return key +} + +func encodeIndex(index *dpaDBIndex) []byte { + data, _ := rlp.EncodeToBytes(index) + return data +} + +func encodeData(chunk *Chunk) []byte { + // Always create a new underlying array for the returned byte slice. + // The chunk.Key array may be used in the returned slice which + // may be changed later in the code or by the LevelDB, resulting + // that the Key is changed as well. + return append(append([]byte{}, chunk.Addr[:]...), chunk.SData...) +} + +func decodeIndex(data []byte, index *dpaDBIndex) error { + dec := rlp.NewStream(bytes.NewReader(data), 0) + return dec.Decode(index) +} + +func decodeData(data []byte, chunk *Chunk) { + chunk.SData = data[32:] + chunk.Size = int64(binary.BigEndian.Uint64(data[32:40])) +} + +func decodeOldData(data []byte, chunk *Chunk) { + chunk.SData = data + chunk.Size = int64(binary.BigEndian.Uint64(data[0:8])) +} + +func (s *LDBStore) collectGarbage(ratio float32) { + metrics.GetOrRegisterCounter("ldbstore.collectgarbage", nil).Inc(1) + + it := s.db.NewIterator() + defer it.Release() + + garbage := []*gcItem{} + gcnt := 0 + + for ok := it.Seek([]byte{keyIndex}); ok && (gcnt < maxGCitems) && (uint64(gcnt) < s.entryCnt); ok = it.Next() { + itkey := it.Key() + + if (itkey == nil) || (itkey[0] != keyIndex) { + break + } + + // it.Key() contents change on next call to it.Next(), so we must copy it + key := make([]byte, len(it.Key())) + copy(key, it.Key()) + + val := it.Value() + + var index dpaDBIndex + + hash := key[1:] + decodeIndex(val, &index) + po := s.po(hash) + + gci := &gcItem{ + idxKey: key, + idx: index.Idx, + value: index.Access, // the smaller, the more likely to be gc'd. see sort comparator below. + po: po, + } + + garbage = append(garbage, gci) + gcnt++ + } + + sort.Slice(garbage[:gcnt], func(i, j int) bool { return garbage[i].value < garbage[j].value }) + + cutoff := int(float32(gcnt) * ratio) + metrics.GetOrRegisterCounter("ldbstore.collectgarbage.delete", nil).Inc(int64(cutoff)) + + for i := 0; i < cutoff; i++ { + s.delete(garbage[i].idx, garbage[i].idxKey, garbage[i].po) + } +} + +// Export writes all chunks from the store to a tar archive, returning the +// number of chunks written. +func (s *LDBStore) Export(out io.Writer) (int64, error) { + tw := tar.NewWriter(out) + defer tw.Close() + + it := s.db.NewIterator() + defer it.Release() + var count int64 + for ok := it.Seek([]byte{keyIndex}); ok; ok = it.Next() { + key := it.Key() + if (key == nil) || (key[0] != keyIndex) { + break + } + + var index dpaDBIndex + + hash := key[1:] + decodeIndex(it.Value(), &index) + po := s.po(hash) + datakey := getDataKey(index.Idx, po) + log.Trace("store.export", "dkey", fmt.Sprintf("%x", datakey), "dataidx", index.Idx, "po", po) + data, err := s.db.Get(datakey) + if err != nil { + log.Warn(fmt.Sprintf("Chunk %x found but could not be accessed: %v", key[:], err)) + continue + } + + hdr := &tar.Header{ + Name: hex.EncodeToString(hash), + Mode: 0644, + Size: int64(len(data)), + } + if err := tw.WriteHeader(hdr); err != nil { + return count, err + } + if _, err := tw.Write(data); err != nil { + return count, err + } + count++ + } + + return count, nil +} + +// of chunks read. +func (s *LDBStore) Import(in io.Reader) (int64, error) { + tr := tar.NewReader(in) + + var count int64 + var wg sync.WaitGroup + for { + hdr, err := tr.Next() + if err == io.EOF { + break + } else if err != nil { + return count, err + } + + if len(hdr.Name) != 64 { + log.Warn("ignoring non-chunk file", "name", hdr.Name) + continue + } + + keybytes, err := hex.DecodeString(hdr.Name) + if err != nil { + log.Warn("ignoring invalid chunk file", "name", hdr.Name, "err", err) + continue + } + + data, err := ioutil.ReadAll(tr) + if err != nil { + return count, err + } + key := Address(keybytes) + chunk := NewChunk(key, nil) + chunk.SData = data[32:] + s.Put(context.TODO(), chunk) + wg.Add(1) + go func() { + defer wg.Done() + <-chunk.dbStoredC + }() + count++ + } + wg.Wait() + return count, nil +} + +func (s *LDBStore) Cleanup() { + //Iterates over the database and checks that there are no faulty chunks + it := s.db.NewIterator() + startPosition := []byte{keyIndex} + it.Seek(startPosition) + var key []byte + var errorsFound, total int + for it.Valid() { + key = it.Key() + if (key == nil) || (key[0] != keyIndex) { + break + } + total++ + var index dpaDBIndex + err := decodeIndex(it.Value(), &index) + if err != nil { + it.Next() + continue + } + data, err := s.db.Get(getDataKey(index.Idx, s.po(Address(key[1:])))) + if err != nil { + log.Warn(fmt.Sprintf("Chunk %x found but could not be accessed: %v", key[:], err)) + s.delete(index.Idx, getIndexKey(key[1:]), s.po(Address(key[1:]))) + errorsFound++ + } else { + hasher := s.hashfunc() + hasher.Write(data[32:]) + hash := hasher.Sum(nil) + if !bytes.Equal(hash, key[1:]) { + log.Warn(fmt.Sprintf("Found invalid chunk. Hash mismatch. hash=%x, key=%x", hash, key[:])) + s.delete(index.Idx, getIndexKey(key[1:]), s.po(Address(key[1:]))) + } + } + it.Next() + } + it.Release() + log.Warn(fmt.Sprintf("Found %v errors out of %v entries", errorsFound, total)) +} + +func (s *LDBStore) ReIndex() { + //Iterates over the database and checks that there are no faulty chunks + it := s.db.NewIterator() + startPosition := []byte{keyOldData} + it.Seek(startPosition) + var key []byte + var errorsFound, total int + for it.Valid() { + key = it.Key() + if (key == nil) || (key[0] != keyOldData) { + break + } + data := it.Value() + hasher := s.hashfunc() + hasher.Write(data) + hash := hasher.Sum(nil) + + newKey := make([]byte, 10) + oldCntKey := make([]byte, 2) + newCntKey := make([]byte, 2) + oldCntKey[0] = keyDistanceCnt + newCntKey[0] = keyDistanceCnt + key[0] = keyData + key[1] = s.po(Address(key[1:])) + oldCntKey[1] = key[1] + newCntKey[1] = s.po(Address(newKey[1:])) + copy(newKey[2:], key[1:]) + newValue := append(hash, data...) + + batch := new(leveldb.Batch) + batch.Delete(key) + s.bucketCnt[oldCntKey[1]]-- + batch.Put(oldCntKey, U64ToBytes(s.bucketCnt[oldCntKey[1]])) + batch.Put(newKey, newValue) + s.bucketCnt[newCntKey[1]]++ + batch.Put(newCntKey, U64ToBytes(s.bucketCnt[newCntKey[1]])) + s.db.Write(batch) + it.Next() + } + it.Release() + log.Warn(fmt.Sprintf("Found %v errors out of %v entries", errorsFound, total)) +} + +func (s *LDBStore) delete(idx uint64, idxKey []byte, po uint8) { + metrics.GetOrRegisterCounter("ldbstore.delete", nil).Inc(1) + + batch := new(leveldb.Batch) + batch.Delete(idxKey) + batch.Delete(getDataKey(idx, po)) + s.entryCnt-- + s.bucketCnt[po]-- + cntKey := make([]byte, 2) + cntKey[0] = keyDistanceCnt + cntKey[1] = po + batch.Put(keyEntryCnt, U64ToBytes(s.entryCnt)) + batch.Put(cntKey, U64ToBytes(s.bucketCnt[po])) + s.db.Write(batch) +} + +func (s *LDBStore) CurrentBucketStorageIndex(po uint8) uint64 { + s.lock.RLock() + defer s.lock.RUnlock() + + return s.bucketCnt[po] +} + +func (s *LDBStore) Size() uint64 { + s.lock.Lock() + defer s.lock.Unlock() + return s.entryCnt +} + +func (s *LDBStore) CurrentStorageIndex() uint64 { + s.lock.RLock() + defer s.lock.RUnlock() + return s.dataIdx +} + +func (s *LDBStore) Put(ctx context.Context, chunk *Chunk) { + metrics.GetOrRegisterCounter("ldbstore.put", nil).Inc(1) + log.Trace("ldbstore.put", "key", chunk.Addr) + + ikey := getIndexKey(chunk.Addr) + var index dpaDBIndex + + po := s.po(chunk.Addr) + s.lock.Lock() + defer s.lock.Unlock() + + log.Trace("ldbstore.put: s.db.Get", "key", chunk.Addr, "ikey", fmt.Sprintf("%x", ikey)) + idata, err := s.db.Get(ikey) + if err != nil { + s.doPut(chunk, &index, po) + batchC := s.batchC + go func() { + <-batchC + chunk.markAsStored() + }() + } else { + log.Trace("ldbstore.put: chunk already exists, only update access", "key", chunk.Addr) + decodeIndex(idata, &index) + chunk.markAsStored() + } + index.Access = s.accessCnt + s.accessCnt++ + idata = encodeIndex(&index) + s.batch.Put(ikey, idata) + select { + case s.batchesC <- struct{}{}: + default: + } +} + +// force putting into db, does not check access index +func (s *LDBStore) doPut(chunk *Chunk, index *dpaDBIndex, po uint8) { + data := s.encodeDataFunc(chunk) + dkey := getDataKey(s.dataIdx, po) + s.batch.Put(dkey, data) + index.Idx = s.dataIdx + s.bucketCnt[po] = s.dataIdx + s.entryCnt++ + s.dataIdx++ + + cntKey := make([]byte, 2) + cntKey[0] = keyDistanceCnt + cntKey[1] = po + s.batch.Put(cntKey, U64ToBytes(s.bucketCnt[po])) +} + +func (s *LDBStore) writeBatches() { +mainLoop: + for { + select { + case <-s.quit: + break mainLoop + case <-s.batchesC: + s.lock.Lock() + b := s.batch + e := s.entryCnt + d := s.dataIdx + a := s.accessCnt + c := s.batchC + s.batchC = make(chan bool) + s.batch = new(leveldb.Batch) + err := s.writeBatch(b, e, d, a) + // TODO: set this error on the batch, then tell the chunk + if err != nil { + log.Error(fmt.Sprintf("spawn batch write (%d entries): %v", b.Len(), err)) + } + close(c) + for e > s.capacity { + // Collect garbage in a separate goroutine + // to be able to interrupt this loop by s.quit. + done := make(chan struct{}) + go func() { + s.collectGarbage(gcArrayFreeRatio) + close(done) + }() + + e = s.entryCnt + select { + case <-s.quit: + s.lock.Unlock() + break mainLoop + case <-done: + } + } + s.lock.Unlock() + } + } + log.Trace(fmt.Sprintf("DbStore: quit batch write loop")) +} + +// must be called non concurrently +func (s *LDBStore) writeBatch(b *leveldb.Batch, entryCnt, dataIdx, accessCnt uint64) error { + b.Put(keyEntryCnt, U64ToBytes(entryCnt)) + b.Put(keyDataIdx, U64ToBytes(dataIdx)) + b.Put(keyAccessCnt, U64ToBytes(accessCnt)) + l := b.Len() + if err := s.db.Write(b); err != nil { + return fmt.Errorf("unable to write batch: %v", err) + } + log.Trace(fmt.Sprintf("batch write (%d entries)", l)) + return nil +} + +// newMockEncodeDataFunc returns a function that stores the chunk data +// to a mock store to bypass the default functionality encodeData. +// The constructed function always returns the nil data, as DbStore does +// not need to store the data, but still need to create the index. +func newMockEncodeDataFunc(mockStore *mock.NodeStore) func(chunk *Chunk) []byte { + return func(chunk *Chunk) []byte { + if err := mockStore.Put(chunk.Addr, encodeData(chunk)); err != nil { + log.Error(fmt.Sprintf("%T: Chunk %v put: %v", mockStore, chunk.Addr.Log(), err)) + } + return chunk.Addr[:] + } +} + +// try to find index; if found, update access cnt and return true +func (s *LDBStore) tryAccessIdx(ikey []byte, index *dpaDBIndex) bool { + idata, err := s.db.Get(ikey) + if err != nil { + return false + } + decodeIndex(idata, index) + s.batch.Put(keyAccessCnt, U64ToBytes(s.accessCnt)) + s.accessCnt++ + index.Access = s.accessCnt + idata = encodeIndex(index) + s.batch.Put(ikey, idata) + select { + case s.batchesC <- struct{}{}: + default: + } + return true +} + +func (s *LDBStore) Get(ctx context.Context, addr Address) (chunk *Chunk, err error) { + metrics.GetOrRegisterCounter("ldbstore.get", nil).Inc(1) + log.Trace("ldbstore.get", "key", addr) + + s.lock.Lock() + defer s.lock.Unlock() + return s.get(addr) +} + +func (s *LDBStore) get(addr Address) (chunk *Chunk, err error) { + var indx dpaDBIndex + + if s.tryAccessIdx(getIndexKey(addr), &indx) { + var data []byte + if s.getDataFunc != nil { + // if getDataFunc is defined, use it to retrieve the chunk data + log.Trace("ldbstore.get retrieve with getDataFunc", "key", addr) + data, err = s.getDataFunc(addr) + if err != nil { + return + } + } else { + // default DbStore functionality to retrieve chunk data + proximity := s.po(addr) + datakey := getDataKey(indx.Idx, proximity) + data, err = s.db.Get(datakey) + log.Trace("ldbstore.get retrieve", "key", addr, "indexkey", indx.Idx, "datakey", fmt.Sprintf("%x", datakey), "proximity", proximity) + if err != nil { + log.Trace("ldbstore.get chunk found but could not be accessed", "key", addr, "err", err) + s.delete(indx.Idx, getIndexKey(addr), s.po(addr)) + return + } + } + + chunk = NewChunk(addr, nil) + chunk.markAsStored() + decodeData(data, chunk) + } else { + err = ErrChunkNotFound + } + + return +} + +// newMockGetFunc returns a function that reads chunk data from +// the mock database, which is used as the value for DbStore.getFunc +// to bypass the default functionality of DbStore with a mock store. +func newMockGetDataFunc(mockStore *mock.NodeStore) func(addr Address) (data []byte, err error) { + return func(addr Address) (data []byte, err error) { + data, err = mockStore.Get(addr) + if err == mock.ErrNotFound { + // preserve ErrChunkNotFound error + err = ErrChunkNotFound + } + return data, err + } +} + +func (s *LDBStore) updateAccessCnt(addr Address) { + + s.lock.Lock() + defer s.lock.Unlock() + + var index dpaDBIndex + s.tryAccessIdx(getIndexKey(addr), &index) // result_chn == nil, only update access cnt + +} + +func (s *LDBStore) setCapacity(c uint64) { + s.lock.Lock() + defer s.lock.Unlock() + + s.capacity = c + + if s.entryCnt > c { + ratio := float32(1.01) - float32(c)/float32(s.entryCnt) + if ratio < gcArrayFreeRatio { + ratio = gcArrayFreeRatio + } + if ratio > 1 { + ratio = 1 + } + for s.entryCnt > c { + s.collectGarbage(ratio) + } + } +} + +func (s *LDBStore) Close() { + close(s.quit) + s.db.Close() +} + +// SyncIterator(start, stop, po, f) calls f on each hash of a bin po from start to stop +func (s *LDBStore) SyncIterator(since uint64, until uint64, po uint8, f func(Address, uint64) bool) error { + metrics.GetOrRegisterCounter("ldbstore.synciterator", nil).Inc(1) + + sincekey := getDataKey(since, po) + untilkey := getDataKey(until, po) + it := s.db.NewIterator() + defer it.Release() + + for ok := it.Seek(sincekey); ok; ok = it.Next() { + metrics.GetOrRegisterCounter("ldbstore.synciterator.seek", nil).Inc(1) + + dbkey := it.Key() + if dbkey[0] != keyData || dbkey[1] != po || bytes.Compare(untilkey, dbkey) < 0 { + break + } + key := make([]byte, 32) + val := it.Value() + copy(key, val[:32]) + if !f(Address(key), binary.BigEndian.Uint64(dbkey[2:])) { + break + } + } + return it.Error() +} + +func databaseExists(path string) bool { + o := &opt.Options{ + ErrorIfMissing: true, + } + tdb, err := leveldb.OpenFile(path, o) + if err != nil { + return false + } + defer tdb.Close() + return true +} diff --git a/swarm/storage/ldbstore_test.go b/swarm/storage/ldbstore_test.go new file mode 100644 index 0000000000..baf9e8c142 --- /dev/null +++ b/swarm/storage/ldbstore_test.go @@ -0,0 +1,523 @@ +// 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 storage + +import ( + "bytes" + "context" + "fmt" + "io/ioutil" + "os" + "sync" + "testing" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/swarm/log" + "github.com/ethereum/go-ethereum/swarm/storage/mock/mem" + + ldberrors "github.com/syndtr/goleveldb/leveldb/errors" +) + +type testDbStore struct { + *LDBStore + dir string +} + +func newTestDbStore(mock bool, trusted bool) (*testDbStore, func(), error) { + dir, err := ioutil.TempDir("", "bzz-storage-test") + if err != nil { + return nil, func() {}, err + } + + var db *LDBStore + storeparams := NewDefaultStoreParams() + params := NewLDBStoreParams(storeparams, dir) + params.Po = testPoFunc + + if mock { + globalStore := mem.NewGlobalStore() + addr := common.HexToAddress("0x5aaeb6053f3e94c9b9a09f33669435e7ef1beaed") + mockStore := globalStore.NewNodeStore(addr) + + db, err = NewMockDbStore(params, mockStore) + } else { + db, err = NewLDBStore(params) + } + + cleanup := func() { + if db != nil { + db.Close() + } + err = os.RemoveAll(dir) + if err != nil { + panic(fmt.Sprintf("db cleanup failed: %v", err)) + } + } + + return &testDbStore{db, dir}, cleanup, err +} + +func testPoFunc(k Address) (ret uint8) { + basekey := make([]byte, 32) + return uint8(Proximity(basekey[:], k[:])) +} + +func (db *testDbStore) close() { + db.Close() + err := os.RemoveAll(db.dir) + if err != nil { + panic(err) + } +} + +func testDbStoreRandom(n int, processors int, chunksize int64, mock bool, t *testing.T) { + db, cleanup, err := newTestDbStore(mock, true) + defer cleanup() + if err != nil { + t.Fatalf("init dbStore failed: %v", err) + } + testStoreRandom(db, processors, n, chunksize, t) +} + +func testDbStoreCorrect(n int, processors int, chunksize int64, mock bool, t *testing.T) { + db, cleanup, err := newTestDbStore(mock, false) + defer cleanup() + if err != nil { + t.Fatalf("init dbStore failed: %v", err) + } + testStoreCorrect(db, processors, n, chunksize, t) +} + +func TestDbStoreRandom_1(t *testing.T) { + testDbStoreRandom(1, 1, 0, false, t) +} + +func TestDbStoreCorrect_1(t *testing.T) { + testDbStoreCorrect(1, 1, 4096, false, t) +} + +func TestDbStoreRandom_1_5k(t *testing.T) { + testDbStoreRandom(8, 5000, 0, false, t) +} + +func TestDbStoreRandom_8_5k(t *testing.T) { + testDbStoreRandom(8, 5000, 0, false, t) +} + +func TestDbStoreCorrect_1_5k(t *testing.T) { + testDbStoreCorrect(1, 5000, 4096, false, t) +} + +func TestDbStoreCorrect_8_5k(t *testing.T) { + testDbStoreCorrect(8, 5000, 4096, false, t) +} + +func TestMockDbStoreRandom_1(t *testing.T) { + testDbStoreRandom(1, 1, 0, true, t) +} + +func TestMockDbStoreCorrect_1(t *testing.T) { + testDbStoreCorrect(1, 1, 4096, true, t) +} + +func TestMockDbStoreRandom_1_5k(t *testing.T) { + testDbStoreRandom(8, 5000, 0, true, t) +} + +func TestMockDbStoreRandom_8_5k(t *testing.T) { + testDbStoreRandom(8, 5000, 0, true, t) +} + +func TestMockDbStoreCorrect_1_5k(t *testing.T) { + testDbStoreCorrect(1, 5000, 4096, true, t) +} + +func TestMockDbStoreCorrect_8_5k(t *testing.T) { + testDbStoreCorrect(8, 5000, 4096, true, t) +} + +func testDbStoreNotFound(t *testing.T, mock bool) { + db, cleanup, err := newTestDbStore(mock, false) + defer cleanup() + if err != nil { + t.Fatalf("init dbStore failed: %v", err) + } + + _, err = db.Get(context.TODO(), ZeroAddr) + if err != ErrChunkNotFound { + t.Errorf("Expected ErrChunkNotFound, got %v", err) + } +} + +func TestDbStoreNotFound(t *testing.T) { + testDbStoreNotFound(t, false) +} +func TestMockDbStoreNotFound(t *testing.T) { + testDbStoreNotFound(t, true) +} + +func testIterator(t *testing.T, mock bool) { + var chunkcount int = 32 + var i int + var poc uint + chunkkeys := NewAddressCollection(chunkcount) + chunkkeys_results := NewAddressCollection(chunkcount) + + db, cleanup, err := newTestDbStore(mock, false) + defer cleanup() + if err != nil { + t.Fatalf("init dbStore failed: %v", err) + } + + chunks := GenerateRandomChunks(DefaultChunkSize, chunkcount) + + wg := &sync.WaitGroup{} + wg.Add(len(chunks)) + for i = 0; i < len(chunks); i++ { + db.Put(context.TODO(), chunks[i]) + chunkkeys[i] = chunks[i].Addr + j := i + go func() { + defer wg.Done() + <-chunks[j].dbStoredC + }() + } + + //testSplit(m, l, 128, chunkkeys, t) + + for i = 0; i < len(chunkkeys); i++ { + log.Trace(fmt.Sprintf("Chunk array pos %d/%d: '%v'", i, chunkcount, chunkkeys[i])) + } + wg.Wait() + i = 0 + for poc = 0; poc <= 255; poc++ { + err := db.SyncIterator(0, uint64(chunkkeys.Len()), uint8(poc), func(k Address, n uint64) bool { + log.Trace(fmt.Sprintf("Got key %v number %d poc %d", k, n, uint8(poc))) + chunkkeys_results[n-1] = k + i++ + return true + }) + if err != nil { + t.Fatalf("Iterator call failed: %v", err) + } + } + + for i = 0; i < chunkcount; i++ { + if !bytes.Equal(chunkkeys[i], chunkkeys_results[i]) { + t.Fatalf("Chunk put #%d key '%v' does not match iterator's key '%v'", i, chunkkeys[i], chunkkeys_results[i]) + } + } + +} + +func TestIterator(t *testing.T) { + testIterator(t, false) +} +func TestMockIterator(t *testing.T) { + testIterator(t, true) +} + +func benchmarkDbStorePut(n int, processors int, chunksize int64, mock bool, b *testing.B) { + db, cleanup, err := newTestDbStore(mock, true) + defer cleanup() + if err != nil { + b.Fatalf("init dbStore failed: %v", err) + } + benchmarkStorePut(db, processors, n, chunksize, b) +} + +func benchmarkDbStoreGet(n int, processors int, chunksize int64, mock bool, b *testing.B) { + db, cleanup, err := newTestDbStore(mock, true) + defer cleanup() + if err != nil { + b.Fatalf("init dbStore failed: %v", err) + } + benchmarkStoreGet(db, processors, n, chunksize, b) +} + +func BenchmarkDbStorePut_1_500(b *testing.B) { + benchmarkDbStorePut(500, 1, 4096, false, b) +} + +func BenchmarkDbStorePut_8_500(b *testing.B) { + benchmarkDbStorePut(500, 8, 4096, false, b) +} + +func BenchmarkDbStoreGet_1_500(b *testing.B) { + benchmarkDbStoreGet(500, 1, 4096, false, b) +} + +func BenchmarkDbStoreGet_8_500(b *testing.B) { + benchmarkDbStoreGet(500, 8, 4096, false, b) +} + +func BenchmarkMockDbStorePut_1_500(b *testing.B) { + benchmarkDbStorePut(500, 1, 4096, true, b) +} + +func BenchmarkMockDbStorePut_8_500(b *testing.B) { + benchmarkDbStorePut(500, 8, 4096, true, b) +} + +func BenchmarkMockDbStoreGet_1_500(b *testing.B) { + benchmarkDbStoreGet(500, 1, 4096, true, b) +} + +func BenchmarkMockDbStoreGet_8_500(b *testing.B) { + benchmarkDbStoreGet(500, 8, 4096, true, b) +} + +// TestLDBStoreWithoutCollectGarbage tests that we can put a number of random chunks in the LevelDB store, and +// retrieve them, provided we don't hit the garbage collection +func TestLDBStoreWithoutCollectGarbage(t *testing.T) { + capacity := 50 + n := 10 + + ldb, cleanup := newLDBStore(t) + ldb.setCapacity(uint64(capacity)) + defer cleanup() + + chunks := []*Chunk{} + for i := 0; i < n; i++ { + c := GenerateRandomChunk(DefaultChunkSize) + chunks = append(chunks, c) + log.Trace("generate random chunk", "idx", i, "chunk", c) + } + + for i := 0; i < n; i++ { + go ldb.Put(context.TODO(), chunks[i]) + } + + // wait for all chunks to be stored + for i := 0; i < n; i++ { + <-chunks[i].dbStoredC + } + + log.Info("ldbstore", "entrycnt", ldb.entryCnt, "accesscnt", ldb.accessCnt) + + for i := 0; i < n; i++ { + ret, err := ldb.Get(context.TODO(), chunks[i].Addr) + if err != nil { + t.Fatal(err) + } + + if !bytes.Equal(ret.SData, chunks[i].SData) { + t.Fatal("expected to get the same data back, but got smth else") + } + + log.Info("got back chunk", "chunk", ret) + } + + if ldb.entryCnt != uint64(n+1) { + t.Fatalf("expected entryCnt to be equal to %v, but got %v", n+1, ldb.entryCnt) + } + + if ldb.accessCnt != uint64(2*n+1) { + t.Fatalf("expected accessCnt to be equal to %v, but got %v", n+1, ldb.accessCnt) + } +} + +// TestLDBStoreCollectGarbage tests that we can put more chunks than LevelDB's capacity, and +// retrieve only some of them, because garbage collection must have cleared some of them +func TestLDBStoreCollectGarbage(t *testing.T) { + capacity := 500 + n := 2000 + + ldb, cleanup := newLDBStore(t) + ldb.setCapacity(uint64(capacity)) + defer cleanup() + + chunks := []*Chunk{} + for i := 0; i < n; i++ { + c := GenerateRandomChunk(DefaultChunkSize) + chunks = append(chunks, c) + log.Trace("generate random chunk", "idx", i, "chunk", c) + } + + for i := 0; i < n; i++ { + ldb.Put(context.TODO(), chunks[i]) + } + + // wait for all chunks to be stored + for i := 0; i < n; i++ { + <-chunks[i].dbStoredC + } + + log.Info("ldbstore", "entrycnt", ldb.entryCnt, "accesscnt", ldb.accessCnt) + + // wait for garbage collection to kick in on the responsible actor + time.Sleep(5 * time.Second) + + var missing int + for i := 0; i < n; i++ { + ret, err := ldb.Get(context.TODO(), chunks[i].Addr) + if err == ErrChunkNotFound || err == ldberrors.ErrNotFound { + missing++ + continue + } + if err != nil { + t.Fatal(err) + } + + if !bytes.Equal(ret.SData, chunks[i].SData) { + t.Fatal("expected to get the same data back, but got smth else") + } + + log.Trace("got back chunk", "chunk", ret) + } + + if missing < n-capacity { + t.Fatalf("gc failure: expected to miss %v chunks, but only %v are actually missing", n-capacity, missing) + } + + log.Info("ldbstore", "total", n, "missing", missing, "entrycnt", ldb.entryCnt, "accesscnt", ldb.accessCnt) +} + +// TestLDBStoreAddRemove tests that we can put and then delete a given chunk +func TestLDBStoreAddRemove(t *testing.T) { + ldb, cleanup := newLDBStore(t) + ldb.setCapacity(200) + defer cleanup() + + n := 100 + + chunks := []*Chunk{} + for i := 0; i < n; i++ { + c := GenerateRandomChunk(DefaultChunkSize) + chunks = append(chunks, c) + log.Trace("generate random chunk", "idx", i, "chunk", c) + } + + for i := 0; i < n; i++ { + go ldb.Put(context.TODO(), chunks[i]) + } + + // wait for all chunks to be stored before continuing + for i := 0; i < n; i++ { + <-chunks[i].dbStoredC + } + + for i := 0; i < n; i++ { + // delete all even index chunks + if i%2 == 0 { + + key := chunks[i].Addr + ikey := getIndexKey(key) + + var indx dpaDBIndex + ldb.tryAccessIdx(ikey, &indx) + + ldb.delete(indx.Idx, ikey, ldb.po(key)) + } + } + + log.Info("ldbstore", "entrycnt", ldb.entryCnt, "accesscnt", ldb.accessCnt) + + for i := 0; i < n; i++ { + ret, err := ldb.Get(context.TODO(), chunks[i].Addr) + + if i%2 == 0 { + // expect even chunks to be missing + if err == nil || ret != nil { + t.Fatal("expected chunk to be missing, but got no error") + } + } else { + // expect odd chunks to be retrieved successfully + if err != nil { + t.Fatalf("expected no error, but got %s", err) + } + + if !bytes.Equal(ret.SData, chunks[i].SData) { + t.Fatal("expected to get the same data back, but got smth else") + } + } + } +} + +// TestLDBStoreRemoveThenCollectGarbage tests that we can delete chunks and that we can trigger garbage collection +func TestLDBStoreRemoveThenCollectGarbage(t *testing.T) { + capacity := 10 + + ldb, cleanup := newLDBStore(t) + ldb.setCapacity(uint64(capacity)) + + n := 7 + + chunks := []*Chunk{} + for i := 0; i < capacity; i++ { + c := GenerateRandomChunk(DefaultChunkSize) + chunks = append(chunks, c) + log.Trace("generate random chunk", "idx", i, "chunk", c) + } + + for i := 0; i < n; i++ { + ldb.Put(context.TODO(), chunks[i]) + } + + // wait for all chunks to be stored before continuing + for i := 0; i < n; i++ { + <-chunks[i].dbStoredC + } + + // delete all chunks + for i := 0; i < n; i++ { + key := chunks[i].Addr + ikey := getIndexKey(key) + + var indx dpaDBIndex + ldb.tryAccessIdx(ikey, &indx) + + ldb.delete(indx.Idx, ikey, ldb.po(key)) + } + + log.Info("ldbstore", "entrycnt", ldb.entryCnt, "accesscnt", ldb.accessCnt) + + cleanup() + + ldb, cleanup = newLDBStore(t) + ldb.setCapacity(uint64(capacity)) + + n = 10 + + for i := 0; i < n; i++ { + ldb.Put(context.TODO(), chunks[i]) + } + + // wait for all chunks to be stored before continuing + for i := 0; i < n; i++ { + <-chunks[i].dbStoredC + } + + // expect for first chunk to be missing, because it has the smallest access value + idx := 0 + ret, err := ldb.Get(context.TODO(), chunks[idx].Addr) + if err == nil || ret != nil { + t.Fatal("expected first chunk to be missing, but got no error") + } + + // expect for last chunk to be present, as it has the largest access value + idx = 9 + ret, err = ldb.Get(context.TODO(), chunks[idx].Addr) + if err != nil { + t.Fatalf("expected no error, but got %s", err) + } + + if !bytes.Equal(ret.SData, chunks[idx].SData) { + t.Fatal("expected to get the same data back, but got smth else") + } +} diff --git a/swarm/storage/localstore.go b/swarm/storage/localstore.go index ece0c86155..096d150ae3 100644 --- a/swarm/storage/localstore.go +++ b/swarm/storage/localstore.go @@ -17,77 +17,210 @@ package storage import ( + "context" "encoding/binary" + "fmt" + "path/filepath" + "sync" "github.com/ethereum/go-ethereum/metrics" + "github.com/ethereum/go-ethereum/swarm/log" + "github.com/ethereum/go-ethereum/swarm/storage/mock" ) -//metrics variables -var ( - dbStorePutCounter = metrics.NewRegisteredCounter("storage.db.dbstore.put.count", nil) -) +type LocalStoreParams struct { + *StoreParams + ChunkDbPath string + Validators []ChunkValidator `toml:"-"` +} + +func NewDefaultLocalStoreParams() *LocalStoreParams { + return &LocalStoreParams{ + StoreParams: NewDefaultStoreParams(), + } +} + +//this can only finally be set after all config options (file, cmd line, env vars) +//have been evaluated +func (p *LocalStoreParams) Init(path string) { + if p.ChunkDbPath == "" { + p.ChunkDbPath = filepath.Join(path, "chunks") + } +} // LocalStore is a combination of inmemory db over a disk persisted db // implements a Get/Put with fallback (caching) logic using any 2 ChunkStores type LocalStore struct { - memStore ChunkStore - DbStore ChunkStore + Validators []ChunkValidator + memStore *MemStore + DbStore *LDBStore + mu sync.Mutex } // This constructor uses MemStore and DbStore as components -func NewLocalStore(hash SwarmHasher, params *StoreParams) (*LocalStore, error) { - dbStore, err := NewDbStore(params.ChunkDbPath, hash, params.DbCapacity, params.Radius) +func NewLocalStore(params *LocalStoreParams, mockStore *mock.NodeStore) (*LocalStore, error) { + ldbparams := NewLDBStoreParams(params.StoreParams, params.ChunkDbPath) + dbStore, err := NewMockDbStore(ldbparams, mockStore) if err != nil { return nil, err } return &LocalStore{ - memStore: NewMemStore(dbStore, params.CacheCapacity), - DbStore: dbStore, + memStore: NewMemStore(params.StoreParams, dbStore), + DbStore: dbStore, + Validators: params.Validators, }, nil } -func (self *LocalStore) CacheCounter() uint64 { - return uint64(self.memStore.(*MemStore).Counter()) -} - -func (self *LocalStore) DbCounter() uint64 { - return self.DbStore.(*DbStore).Counter() -} - -// LocalStore is itself a chunk store -// unsafe, in that the data is not integrity checked -func (self *LocalStore) Put(chunk *Chunk) { - chunk.dbStored = make(chan bool) - self.memStore.Put(chunk) - if chunk.wg != nil { - chunk.wg.Add(1) +func NewTestLocalStoreForAddr(params *LocalStoreParams) (*LocalStore, error) { + ldbparams := NewLDBStoreParams(params.StoreParams, params.ChunkDbPath) + dbStore, err := NewLDBStore(ldbparams) + if err != nil { + return nil, err } - go func() { - dbStorePutCounter.Inc(1) - self.DbStore.Put(chunk) - if chunk.wg != nil { - chunk.wg.Done() + localStore := &LocalStore{ + memStore: NewMemStore(params.StoreParams, dbStore), + DbStore: dbStore, + Validators: params.Validators, + } + return localStore, nil +} + +// Put is responsible for doing validation and storage of the chunk +// by using configured ChunkValidators, MemStore and LDBStore. +// If the chunk is not valid, its GetErrored function will +// return ErrChunkInvalid. +// This method will check if the chunk is already in the MemStore +// and it will return it if it is. If there is an error from +// the MemStore.Get, it will be returned by calling GetErrored +// on the chunk. +// This method is responsible for closing Chunk.ReqC channel +// when the chunk is stored in memstore. +// After the LDBStore.Put, it is ensured that the MemStore +// contains the chunk with the same data, but nil ReqC channel. +func (ls *LocalStore) Put(ctx context.Context, chunk *Chunk) { + if l := len(chunk.SData); l < 9 { + log.Debug("incomplete chunk data", "addr", chunk.Addr, "length", l) + chunk.SetErrored(ErrChunkInvalid) + chunk.markAsStored() + return + } + valid := true + for _, v := range ls.Validators { + if valid = v.Validate(chunk.Addr, chunk.SData); valid { + break } - }() + } + if !valid { + log.Trace("invalid content address", "addr", chunk.Addr) + chunk.SetErrored(ErrChunkInvalid) + chunk.markAsStored() + return + } + + log.Trace("localstore.put", "addr", chunk.Addr) + + ls.mu.Lock() + defer ls.mu.Unlock() + + chunk.Size = int64(binary.LittleEndian.Uint64(chunk.SData[0:8])) + + memChunk, err := ls.memStore.Get(ctx, chunk.Addr) + switch err { + case nil: + if memChunk.ReqC == nil { + chunk.markAsStored() + return + } + case ErrChunkNotFound: + default: + chunk.SetErrored(err) + return + } + + ls.DbStore.Put(ctx, chunk) + + // chunk is no longer a request, but a chunk with data, so replace it in memStore + newc := NewChunk(chunk.Addr, nil) + newc.SData = chunk.SData + newc.Size = chunk.Size + newc.dbStoredC = chunk.dbStoredC + + ls.memStore.Put(ctx, newc) + + if memChunk != nil && memChunk.ReqC != nil { + close(memChunk.ReqC) + } } // Get(chunk *Chunk) looks up a chunk in the local stores // This method is blocking until the chunk is retrieved // so additional timeout may be needed to wrap this call if // ChunkStores are remote and can have long latency -func (self *LocalStore) Get(key Key) (chunk *Chunk, err error) { - chunk, err = self.memStore.Get(key) +func (ls *LocalStore) Get(ctx context.Context, addr Address) (chunk *Chunk, err error) { + ls.mu.Lock() + defer ls.mu.Unlock() + + return ls.get(ctx, addr) +} + +func (ls *LocalStore) get(ctx context.Context, addr Address) (chunk *Chunk, err error) { + chunk, err = ls.memStore.Get(ctx, addr) if err == nil { + if chunk.ReqC != nil { + select { + case <-chunk.ReqC: + default: + metrics.GetOrRegisterCounter("localstore.get.errfetching", nil).Inc(1) + return chunk, ErrFetching + } + } + metrics.GetOrRegisterCounter("localstore.get.cachehit", nil).Inc(1) return } - chunk, err = self.DbStore.Get(key) + metrics.GetOrRegisterCounter("localstore.get.cachemiss", nil).Inc(1) + chunk, err = ls.DbStore.Get(ctx, addr) if err != nil { + metrics.GetOrRegisterCounter("localstore.get.error", nil).Inc(1) return } chunk.Size = int64(binary.LittleEndian.Uint64(chunk.SData[0:8])) - self.memStore.Put(chunk) + ls.memStore.Put(ctx, chunk) return } -// Close local store -func (self *LocalStore) Close() {} +// retrieve logic common for local and network chunk retrieval requests +func (ls *LocalStore) GetOrCreateRequest(ctx context.Context, addr Address) (chunk *Chunk, created bool) { + metrics.GetOrRegisterCounter("localstore.getorcreaterequest", nil).Inc(1) + + ls.mu.Lock() + defer ls.mu.Unlock() + + var err error + chunk, err = ls.get(ctx, addr) + if err == nil && chunk.GetErrored() == nil { + metrics.GetOrRegisterCounter("localstore.getorcreaterequest.hit", nil).Inc(1) + log.Trace(fmt.Sprintf("LocalStore.GetOrRetrieve: %v found locally", addr)) + return chunk, false + } + if err == ErrFetching && chunk.GetErrored() == nil { + metrics.GetOrRegisterCounter("localstore.getorcreaterequest.errfetching", nil).Inc(1) + log.Trace(fmt.Sprintf("LocalStore.GetOrRetrieve: %v hit on an existing request %v", addr, chunk.ReqC)) + return chunk, false + } + // no data and no request status + metrics.GetOrRegisterCounter("localstore.getorcreaterequest.miss", nil).Inc(1) + log.Trace(fmt.Sprintf("LocalStore.GetOrRetrieve: %v not found locally. open new request", addr)) + chunk = NewChunk(addr, make(chan bool)) + ls.memStore.Put(ctx, chunk) + return chunk, true +} + +// RequestsCacheLen returns the current number of outgoing requests stored in the cache +func (ls *LocalStore) RequestsCacheLen() int { + return ls.memStore.requests.Len() +} + +// Close the local store +func (ls *LocalStore) Close() { + ls.DbStore.Close() +} diff --git a/swarm/storage/localstore_test.go b/swarm/storage/localstore_test.go new file mode 100644 index 0000000000..2bb81efa3a --- /dev/null +++ b/swarm/storage/localstore_test.go @@ -0,0 +1,118 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package storage + +import ( + "io/ioutil" + "os" + "testing" +) + +var ( + hashfunc = MakeHashFunc(DefaultHash) +) + +// tests that the content address validator correctly checks the data +// tests that resource update chunks are passed through content address validator +// the test checking the resouce update validator internal correctness is found in resource_test.go +func TestValidator(t *testing.T) { + // set up localstore + datadir, err := ioutil.TempDir("", "storage-testvalidator") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(datadir) + + params := NewDefaultLocalStoreParams() + params.Init(datadir) + store, err := NewLocalStore(params, nil) + if err != nil { + t.Fatal(err) + } + + // check puts with no validators, both succeed + chunks := GenerateRandomChunks(259, 2) + goodChunk := chunks[0] + badChunk := chunks[1] + copy(badChunk.SData, goodChunk.SData) + + PutChunks(store, goodChunk, badChunk) + if err := goodChunk.GetErrored(); err != nil { + t.Fatalf("expected no error on good content address chunk in spite of no validation, but got: %s", err) + } + if err := badChunk.GetErrored(); err != nil { + t.Fatalf("expected no error on bad content address chunk in spite of no validation, but got: %s", err) + } + + // add content address validator and check puts + // bad should fail, good should pass + store.Validators = append(store.Validators, NewContentAddressValidator(hashfunc)) + chunks = GenerateRandomChunks(DefaultChunkSize, 2) + goodChunk = chunks[0] + badChunk = chunks[1] + copy(badChunk.SData, goodChunk.SData) + + PutChunks(store, goodChunk, badChunk) + if err := goodChunk.GetErrored(); err != nil { + t.Fatalf("expected no error on good content address chunk with content address validator only, but got: %s", err) + } + if err := badChunk.GetErrored(); err == nil { + t.Fatal("expected error on bad content address chunk with content address validator only, but got nil") + } + + // append a validator that always denies + // bad should fail, good should pass, + var negV boolTestValidator + store.Validators = append(store.Validators, negV) + + chunks = GenerateRandomChunks(DefaultChunkSize, 2) + goodChunk = chunks[0] + badChunk = chunks[1] + copy(badChunk.SData, goodChunk.SData) + + PutChunks(store, goodChunk, badChunk) + if err := goodChunk.GetErrored(); err != nil { + t.Fatalf("expected no error on good content address chunk with content address validator only, but got: %s", err) + } + if err := badChunk.GetErrored(); err == nil { + t.Fatal("expected error on bad content address chunk with content address validator only, but got nil") + } + + // append a validator that always approves + // all shall pass + var posV boolTestValidator = true + store.Validators = append(store.Validators, posV) + + chunks = GenerateRandomChunks(DefaultChunkSize, 2) + goodChunk = chunks[0] + badChunk = chunks[1] + copy(badChunk.SData, goodChunk.SData) + + PutChunks(store, goodChunk, badChunk) + if err := goodChunk.GetErrored(); err != nil { + t.Fatalf("expected no error on good content address chunk with content address validator only, but got: %s", err) + } + if err := badChunk.GetErrored(); err != nil { + t.Fatalf("expected no error on bad content address chunk with content address validator only, but got: %s", err) + } +} + +type boolTestValidator bool + +func (self boolTestValidator) Validate(addr Address, data []byte) bool { + return bool(self) +} diff --git a/swarm/storage/memstore.go b/swarm/storage/memstore.go index d6be542203..55cfcbfeaf 100644 --- a/swarm/storage/memstore.go +++ b/swarm/storage/memstore.go @@ -1,4 +1,4 @@ -// Copyright 2016 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 @@ -19,316 +19,130 @@ package storage import ( - "fmt" + "context" "sync" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/metrics" -) - -//metrics variables -var ( - memstorePutCounter = metrics.NewRegisteredCounter("storage.db.memstore.put.count", nil) - memstoreRemoveCounter = metrics.NewRegisteredCounter("storage.db.memstore.rm.count", nil) -) - -const ( - memTreeLW = 2 // log2(subtree count) of the subtrees - memTreeFLW = 14 // log2(subtree count) of the root layer - dbForceUpdateAccessCnt = 1000 - defaultCacheCapacity = 5000 + lru "github.com/hashicorp/golang-lru" ) type MemStore struct { - memtree *memTree - entryCnt, capacity uint // stored entries - accessCnt uint64 // access counter; oldest is thrown away when full - dbAccessCnt uint64 - dbStore *DbStore - lock sync.Mutex + cache *lru.Cache + requests *lru.Cache + mu sync.RWMutex + disabled bool } -/* -a hash prefix subtree containing subtrees or one storage entry (but never both) - -- access[0] stores the smallest (oldest) access count value in this subtree -- if it contains more subtrees and its subtree count is at least 4, access[1:2] - stores the smallest access count in the first and second halves of subtrees - (so that access[0] = min(access[1], access[2]) -- likewise, if subtree count is at least 8, - access[1] = min(access[3], access[4]) - access[2] = min(access[5], access[6]) - (access[] is a binary tree inside the multi-bit leveled hash tree) -*/ - -func NewMemStore(d *DbStore, capacity uint) (m *MemStore) { - m = &MemStore{} - m.memtree = newMemTree(memTreeFLW, nil, 0) - m.dbStore = d - m.setCapacity(capacity) - return -} - -type memTree struct { - subtree []*memTree - parent *memTree - parentIdx uint - - bits uint // log2(subtree count) - width uint // subtree count - - entry *Chunk // if subtrees are present, entry should be nil - lastDBaccess uint64 - access []uint64 -} - -func newMemTree(b uint, parent *memTree, pidx uint) (node *memTree) { - node = new(memTree) - node.bits = b - node.width = 1 << b - node.subtree = make([]*memTree, node.width) - node.access = make([]uint64, node.width-1) - node.parent = parent - node.parentIdx = pidx - if parent != nil { - parent.subtree[pidx] = node - } - - return node -} - -func (node *memTree) updateAccess(a uint64) { - aidx := uint(0) - var aa uint64 - oa := node.access[0] - for node.access[aidx] == oa { - node.access[aidx] = a - if aidx > 0 { - aa = node.access[((aidx-1)^1)+1] - aidx = (aidx - 1) >> 1 - } else { - pidx := node.parentIdx - node = node.parent - if node == nil { - return - } - nn := node.subtree[pidx^1] - if nn != nil { - aa = nn.access[0] - } else { - aa = 0 - } - aidx = (node.width + pidx - 2) >> 1 - } - - if (aa != 0) && (aa < a) { - a = aa +//NewMemStore is instantiating a MemStore cache. We are keeping a record of all outgoing requests for chunks, that +//should later be delivered by peer nodes, in the `requests` LRU cache. We are also keeping all frequently requested +//chunks in the `cache` LRU cache. +// +//`requests` LRU cache capacity should ideally never be reached, this is why for the time being it should be initialised +//with the same value as the LDBStore capacity. +func NewMemStore(params *StoreParams, _ *LDBStore) (m *MemStore) { + if params.CacheCapacity == 0 { + return &MemStore{ + disabled: true, } } -} -func (s *MemStore) setCapacity(c uint) { - s.lock.Lock() - defer s.lock.Unlock() - - for c < s.entryCnt { - s.removeOldest() + onEvicted := func(key interface{}, value interface{}) { + v := value.(*Chunk) + <-v.dbStoredC + } + c, err := lru.NewWithEvict(int(params.CacheCapacity), onEvicted) + if err != nil { + panic(err) + } + + requestEvicted := func(key interface{}, value interface{}) { + // temporary remove of the error log, until we figure out the problem, as it is too spamy + //log.Error("evict called on outgoing request") + } + r, err := lru.NewWithEvict(int(params.ChunkRequestsCacheCapacity), requestEvicted) + if err != nil { + panic(err) + } + + return &MemStore{ + cache: c, + requests: r, } - s.capacity = c } -func (s *MemStore) Counter() uint { - return s.entryCnt +func (m *MemStore) Get(ctx context.Context, addr Address) (*Chunk, error) { + if m.disabled { + return nil, ErrChunkNotFound + } + + m.mu.RLock() + defer m.mu.RUnlock() + + r, ok := m.requests.Get(string(addr)) + // it is a request + if ok { + return r.(*Chunk), nil + } + + // it is not a request + c, ok := m.cache.Get(string(addr)) + if !ok { + return nil, ErrChunkNotFound + } + return c.(*Chunk), nil } -// entry (not its copy) is going to be in MemStore -func (s *MemStore) Put(entry *Chunk) { - if s.capacity == 0 { +func (m *MemStore) Put(ctx context.Context, c *Chunk) { + if m.disabled { return } - s.lock.Lock() - defer s.lock.Unlock() + m.mu.Lock() + defer m.mu.Unlock() - if s.entryCnt >= s.capacity { - s.removeOldest() - } - - s.accessCnt++ - - memstorePutCounter.Inc(1) - - node := s.memtree - bitpos := uint(0) - for node.entry == nil { - l := entry.Key.bits(bitpos, node.bits) - st := node.subtree[l] - if st == nil { - st = newMemTree(memTreeLW, node, l) - bitpos += node.bits - node = st - break - } - bitpos += node.bits - node = st - } - - if node.entry != nil { - - if node.entry.Key.isEqual(entry.Key) { - node.updateAccess(s.accessCnt) - if entry.SData == nil { - entry.Size = node.entry.Size - entry.SData = node.entry.SData - } - if entry.Req == nil { - entry.Req = node.entry.Req - } - entry.C = node.entry.C - node.entry = entry - return - } - - for node.entry != nil { - - l := node.entry.Key.bits(bitpos, node.bits) - st := node.subtree[l] - if st == nil { - st = newMemTree(memTreeLW, node, l) - } - st.entry = node.entry - node.entry = nil - st.updateAccess(node.access[0]) - - l = entry.Key.bits(bitpos, node.bits) - st = node.subtree[l] - if st == nil { - st = newMemTree(memTreeLW, node, l) - } - bitpos += node.bits - node = st - - } - } - - node.entry = entry - node.lastDBaccess = s.dbAccessCnt - node.updateAccess(s.accessCnt) - s.entryCnt++ -} - -func (s *MemStore) Get(hash Key) (chunk *Chunk, err error) { - s.lock.Lock() - defer s.lock.Unlock() - - node := s.memtree - bitpos := uint(0) - for node.entry == nil { - l := hash.bits(bitpos, node.bits) - st := node.subtree[l] - if st == nil { - return nil, notFound - } - bitpos += node.bits - node = st - } - - if node.entry.Key.isEqual(hash) { - s.accessCnt++ - node.updateAccess(s.accessCnt) - chunk = node.entry - if s.dbAccessCnt-node.lastDBaccess > dbForceUpdateAccessCnt { - s.dbAccessCnt++ - node.lastDBaccess = s.dbAccessCnt - if s.dbStore != nil { - s.dbStore.updateAccessCnt(hash) - } - } - } else { - err = notFound - } - - return -} - -func (s *MemStore) removeOldest() { - node := s.memtree - - for node.entry == nil { - - aidx := uint(0) - av := node.access[aidx] - - for aidx < node.width/2-1 { - if av == node.access[aidx*2+1] { - node.access[aidx] = node.access[aidx*2+2] - aidx = aidx*2 + 1 - } else if av == node.access[aidx*2+2] { - node.access[aidx] = node.access[aidx*2+1] - aidx = aidx*2 + 2 - } else { - panic(nil) - } - } - pidx := aidx*2 + 2 - node.width - if (node.subtree[pidx] != nil) && (av == node.subtree[pidx].access[0]) { - if node.subtree[pidx+1] != nil { - node.access[aidx] = node.subtree[pidx+1].access[0] - } else { - node.access[aidx] = 0 - } - } else if (node.subtree[pidx+1] != nil) && (av == node.subtree[pidx+1].access[0]) { - if node.subtree[pidx] != nil { - node.access[aidx] = node.subtree[pidx].access[0] - } else { - node.access[aidx] = 0 - } - pidx++ - } else { - panic(nil) - } - - //fmt.Println(pidx) - node = node.subtree[pidx] - - } - - if node.entry.dbStored != nil { - log.Trace(fmt.Sprintf("Memstore Clean: Waiting for chunk %v to be saved", node.entry.Key.Log())) - <-node.entry.dbStored - log.Trace(fmt.Sprintf("Memstore Clean: Chunk %v saved to DBStore. Ready to clear from mem.", node.entry.Key.Log())) - } else { - log.Trace(fmt.Sprintf("Memstore Clean: Chunk %v already in DB. Ready to delete.", node.entry.Key.Log())) - } - - if node.entry.SData != nil { - memstoreRemoveCounter.Inc(1) - node.entry = nil - s.entryCnt-- - } - - node.access[0] = 0 - - //--- - - aidx := uint(0) - for { - aa := node.access[aidx] - if aidx > 0 { - aidx = (aidx - 1) >> 1 - } else { - pidx := node.parentIdx - node = node.parent - if node == nil { + // it is a request + if c.ReqC != nil { + select { + case <-c.ReqC: + if c.GetErrored() != nil { + m.requests.Remove(string(c.Addr)) return } - aidx = (node.width + pidx - 2) >> 1 + m.cache.Add(string(c.Addr), c) + m.requests.Remove(string(c.Addr)) + default: + m.requests.Add(string(c.Addr), c) } - if (aa != 0) && ((aa < node.access[aidx]) || (node.access[aidx] == 0)) { - node.access[aidx] = aa + return + } + + // it is not a request + m.cache.Add(string(c.Addr), c) + m.requests.Remove(string(c.Addr)) +} + +func (m *MemStore) setCapacity(n int) { + if n <= 0 { + m.disabled = true + } else { + onEvicted := func(key interface{}, value interface{}) { + v := value.(*Chunk) + <-v.dbStoredC + } + c, err := lru.NewWithEvict(n, onEvicted) + if err != nil { + panic(err) + } + + r, err := lru.New(defaultChunkRequestsCacheCapacity) + if err != nil { + panic(err) + } + + m = &MemStore{ + cache: c, + requests: r, } } } -// Close memstore func (s *MemStore) Close() {} diff --git a/swarm/storage/memstore_test.go b/swarm/storage/memstore_test.go index 2e0ab535af..2c1b0e89e6 100644 --- a/swarm/storage/memstore_test.go +++ b/swarm/storage/memstore_test.go @@ -17,34 +17,233 @@ package storage import ( + "context" + "crypto/rand" + "encoding/binary" + "io/ioutil" + "os" + "sync" "testing" + + "github.com/ethereum/go-ethereum/swarm/log" ) -func testMemStore(l int64, branches int64, t *testing.T) { - m := NewMemStore(nil, defaultCacheCapacity) - testStore(m, l, branches, t) +func newTestMemStore() *MemStore { + storeparams := NewDefaultStoreParams() + return NewMemStore(storeparams, nil) } -func TestMemStore128_10000(t *testing.T) { - testMemStore(10000, 128, t) +func testMemStoreRandom(n int, processors int, chunksize int64, t *testing.T) { + m := newTestMemStore() + defer m.Close() + testStoreRandom(m, processors, n, chunksize, t) } -func TestMemStore128_1000(t *testing.T) { - testMemStore(1000, 128, t) +func testMemStoreCorrect(n int, processors int, chunksize int64, t *testing.T) { + m := newTestMemStore() + defer m.Close() + testStoreCorrect(m, processors, n, chunksize, t) } -func TestMemStore128_100(t *testing.T) { - testMemStore(100, 128, t) +func TestMemStoreRandom_1(t *testing.T) { + testMemStoreRandom(1, 1, 0, t) } -func TestMemStore2_100(t *testing.T) { - testMemStore(100, 2, t) +func TestMemStoreCorrect_1(t *testing.T) { + testMemStoreCorrect(1, 1, 4104, t) +} + +func TestMemStoreRandom_1_1k(t *testing.T) { + testMemStoreRandom(1, 1000, 0, t) +} + +func TestMemStoreCorrect_1_1k(t *testing.T) { + testMemStoreCorrect(1, 100, 4096, t) +} + +func TestMemStoreRandom_8_1k(t *testing.T) { + testMemStoreRandom(8, 1000, 0, t) +} + +func TestMemStoreCorrect_8_1k(t *testing.T) { + testMemStoreCorrect(8, 1000, 4096, t) } func TestMemStoreNotFound(t *testing.T) { - m := NewMemStore(nil, defaultCacheCapacity) - _, err := m.Get(ZeroKey) - if err != notFound { - t.Errorf("Expected notFound, got %v", err) + m := newTestMemStore() + defer m.Close() + + _, err := m.Get(context.TODO(), ZeroAddr) + if err != ErrChunkNotFound { + t.Errorf("Expected ErrChunkNotFound, got %v", err) } } + +func benchmarkMemStorePut(n int, processors int, chunksize int64, b *testing.B) { + m := newTestMemStore() + defer m.Close() + benchmarkStorePut(m, processors, n, chunksize, b) +} + +func benchmarkMemStoreGet(n int, processors int, chunksize int64, b *testing.B) { + m := newTestMemStore() + defer m.Close() + benchmarkStoreGet(m, processors, n, chunksize, b) +} + +func BenchmarkMemStorePut_1_500(b *testing.B) { + benchmarkMemStorePut(500, 1, 4096, b) +} + +func BenchmarkMemStorePut_8_500(b *testing.B) { + benchmarkMemStorePut(500, 8, 4096, b) +} + +func BenchmarkMemStoreGet_1_500(b *testing.B) { + benchmarkMemStoreGet(500, 1, 4096, b) +} + +func BenchmarkMemStoreGet_8_500(b *testing.B) { + benchmarkMemStoreGet(500, 8, 4096, b) +} + +func newLDBStore(t *testing.T) (*LDBStore, func()) { + dir, err := ioutil.TempDir("", "bzz-storage-test") + if err != nil { + t.Fatal(err) + } + log.Trace("memstore.tempdir", "dir", dir) + + ldbparams := NewLDBStoreParams(NewDefaultStoreParams(), dir) + db, err := NewLDBStore(ldbparams) + if err != nil { + t.Fatal(err) + } + + cleanup := func() { + db.Close() + err := os.RemoveAll(dir) + if err != nil { + t.Fatal(err) + } + } + + return db, cleanup +} + +func TestMemStoreAndLDBStore(t *testing.T) { + ldb, cleanup := newLDBStore(t) + ldb.setCapacity(4000) + defer cleanup() + + cacheCap := 200 + requestsCap := 200 + memStore := NewMemStore(NewStoreParams(4000, 200, 200, nil, nil), nil) + + tests := []struct { + n int // number of chunks to push to memStore + chunkSize uint64 // size of chunk (by default in Swarm - 4096) + request bool // whether or not to set the ReqC channel on the random chunks + }{ + { + n: 1, + chunkSize: 4096, + request: false, + }, + { + n: 201, + chunkSize: 4096, + request: false, + }, + { + n: 501, + chunkSize: 4096, + request: false, + }, + { + n: 3100, + chunkSize: 4096, + request: false, + }, + { + n: 100, + chunkSize: 4096, + request: true, + }, + } + + for i, tt := range tests { + log.Info("running test", "idx", i, "tt", tt) + var chunks []*Chunk + + for i := 0; i < tt.n; i++ { + var c *Chunk + if tt.request { + c = NewRandomRequestChunk(tt.chunkSize) + } else { + c = NewRandomChunk(tt.chunkSize) + } + + chunks = append(chunks, c) + } + + for i := 0; i < tt.n; i++ { + go ldb.Put(context.TODO(), chunks[i]) + memStore.Put(context.TODO(), chunks[i]) + + if got := memStore.cache.Len(); got > cacheCap { + t.Fatalf("expected to get cache capacity less than %v, but got %v", cacheCap, got) + } + + if got := memStore.requests.Len(); got > requestsCap { + t.Fatalf("expected to get requests capacity less than %v, but got %v", requestsCap, got) + } + } + + for i := 0; i < tt.n; i++ { + _, err := memStore.Get(context.TODO(), chunks[i].Addr) + if err != nil { + if err == ErrChunkNotFound { + _, err := ldb.Get(context.TODO(), chunks[i].Addr) + if err != nil { + t.Fatalf("couldn't get chunk %v from ldb, got error: %v", i, err) + } + } else { + t.Fatalf("got error from memstore: %v", err) + } + } + } + + // wait for all chunks to be stored before ending the test are cleaning up + for i := 0; i < tt.n; i++ { + <-chunks[i].dbStoredC + } + } +} + +func NewRandomChunk(chunkSize uint64) *Chunk { + c := &Chunk{ + Addr: make([]byte, 32), + ReqC: nil, + SData: make([]byte, chunkSize+8), // SData should be chunkSize + 8 bytes reserved for length + dbStoredC: make(chan bool), + dbStoredMu: &sync.Mutex{}, + } + + rand.Read(c.SData) + + binary.LittleEndian.PutUint64(c.SData[:8], chunkSize) + + hasher := MakeHashFunc(SHA3Hash)() + hasher.Write(c.SData) + copy(c.Addr, hasher.Sum(nil)) + + return c +} + +func NewRandomRequestChunk(chunkSize uint64) *Chunk { + c := NewRandomChunk(chunkSize) + c.ReqC = make(chan bool) + + return c +} diff --git a/swarm/storage/mock/db/db.go b/swarm/storage/mock/db/db.go new file mode 100644 index 0000000000..43bfa24f05 --- /dev/null +++ b/swarm/storage/mock/db/db.go @@ -0,0 +1,236 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +// Package db implements a mock store that keeps all chunk data in LevelDB database. +package db + +import ( + "archive/tar" + "bytes" + "encoding/json" + "io" + "io/ioutil" + + "github.com/syndtr/goleveldb/leveldb" + "github.com/syndtr/goleveldb/leveldb/util" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/swarm/storage/mock" +) + +// GlobalStore contains the LevelDB database that is storing +// chunk data for all swarm nodes. +// Closing the GlobalStore with Close method is required to +// release resources used by the database. +type GlobalStore struct { + db *leveldb.DB +} + +// NewGlobalStore creates a new instance of GlobalStore. +func NewGlobalStore(path string) (s *GlobalStore, err error) { + db, err := leveldb.OpenFile(path, nil) + if err != nil { + return nil, err + } + return &GlobalStore{ + db: db, + }, nil +} + +// Close releases the resources used by the underlying LevelDB. +func (s *GlobalStore) Close() error { + return s.db.Close() +} + +// NewNodeStore returns a new instance of NodeStore that retrieves and stores +// chunk data only for a node with address addr. +func (s *GlobalStore) NewNodeStore(addr common.Address) *mock.NodeStore { + return mock.NewNodeStore(addr, s) +} + +// Get returns chunk data if the chunk with key exists for node +// on address addr. +func (s *GlobalStore) Get(addr common.Address, key []byte) (data []byte, err error) { + has, err := s.db.Has(nodeDBKey(addr, key), nil) + if err != nil { + return nil, mock.ErrNotFound + } + if !has { + return nil, mock.ErrNotFound + } + data, err = s.db.Get(dataDBKey(key), nil) + if err == leveldb.ErrNotFound { + err = mock.ErrNotFound + } + return +} + +// Put saves the chunk data for node with address addr. +func (s *GlobalStore) Put(addr common.Address, key []byte, data []byte) error { + batch := new(leveldb.Batch) + batch.Put(nodeDBKey(addr, key), nil) + batch.Put(dataDBKey(key), data) + return s.db.Write(batch, nil) +} + +// HasKey returns whether a node with addr contains the key. +func (s *GlobalStore) HasKey(addr common.Address, key []byte) bool { + has, err := s.db.Has(nodeDBKey(addr, key), nil) + if err != nil { + has = false + } + return has +} + +// Import reads tar archive from a reader that contains exported chunk data. +// It returns the number of chunks imported and an error. +func (s *GlobalStore) Import(r io.Reader) (n int, err error) { + tr := tar.NewReader(r) + + for { + hdr, err := tr.Next() + if err != nil { + if err == io.EOF { + break + } + return n, err + } + + data, err := ioutil.ReadAll(tr) + if err != nil { + return n, err + } + + var c mock.ExportedChunk + if err = json.Unmarshal(data, &c); err != nil { + return n, err + } + + batch := new(leveldb.Batch) + for _, addr := range c.Addrs { + batch.Put(nodeDBKeyHex(addr, hdr.Name), nil) + } + + batch.Put(dataDBKey(common.Hex2Bytes(hdr.Name)), c.Data) + if err = s.db.Write(batch, nil); err != nil { + return n, err + } + + n++ + } + return n, err +} + +// Export writes to a writer a tar archive with all chunk data from +// the store. It returns the number fo chunks exported and an error. +func (s *GlobalStore) Export(w io.Writer) (n int, err error) { + tw := tar.NewWriter(w) + defer tw.Close() + + buf := bytes.NewBuffer(make([]byte, 0, 1024)) + encoder := json.NewEncoder(buf) + + iter := s.db.NewIterator(util.BytesPrefix(nodeKeyPrefix), nil) + defer iter.Release() + + var currentKey string + var addrs []common.Address + + saveChunk := func(hexKey string) error { + key := common.Hex2Bytes(hexKey) + + data, err := s.db.Get(dataDBKey(key), nil) + if err != nil { + return err + } + + buf.Reset() + if err = encoder.Encode(mock.ExportedChunk{ + Addrs: addrs, + Data: data, + }); err != nil { + return err + } + + d := buf.Bytes() + hdr := &tar.Header{ + Name: hexKey, + Mode: 0644, + Size: int64(len(d)), + } + if err := tw.WriteHeader(hdr); err != nil { + return err + } + if _, err := tw.Write(d); err != nil { + return err + } + n++ + return nil + } + + for iter.Next() { + k := bytes.TrimPrefix(iter.Key(), nodeKeyPrefix) + i := bytes.Index(k, []byte("-")) + if i < 0 { + continue + } + hexKey := string(k[:i]) + + if currentKey == "" { + currentKey = hexKey + } + + if hexKey != currentKey { + if err = saveChunk(currentKey); err != nil { + return n, err + } + + addrs = addrs[:0] + } + + currentKey = hexKey + addrs = append(addrs, common.BytesToAddress(k[i:])) + } + + if len(addrs) > 0 { + if err = saveChunk(currentKey); err != nil { + return n, err + } + } + + return n, err +} + +var ( + nodeKeyPrefix = []byte("node-") + dataKeyPrefix = []byte("data-") +) + +// nodeDBKey constructs a database key for key/node mappings. +func nodeDBKey(addr common.Address, key []byte) []byte { + return nodeDBKeyHex(addr, common.Bytes2Hex(key)) +} + +// nodeDBKeyHex constructs a database key for key/node mappings +// using the hexadecimal string representation of the key. +func nodeDBKeyHex(addr common.Address, hexKey string) []byte { + return append(append(nodeKeyPrefix, []byte(hexKey+"-")...), addr[:]...) +} + +// dataDBkey constructs a database key for key/data storage. +func dataDBKey(key []byte) []byte { + return append(dataKeyPrefix, key...) +} diff --git a/swarm/storage/mock/db/db_test.go b/swarm/storage/mock/db/db_test.go new file mode 100644 index 0000000000..782faaf35c --- /dev/null +++ b/swarm/storage/mock/db/db_test.go @@ -0,0 +1,75 @@ +// +build go1.8 +// +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package db + +import ( + "io/ioutil" + "os" + "testing" + + "github.com/ethereum/go-ethereum/swarm/storage/mock/test" +) + +// TestDBStore is running a test.MockStore tests +// using test.MockStore function. +func TestDBStore(t *testing.T) { + dir, err := ioutil.TempDir("", "mock_"+t.Name()) + if err != nil { + panic(err) + } + defer os.RemoveAll(dir) + + store, err := NewGlobalStore(dir) + if err != nil { + t.Fatal(err) + } + defer store.Close() + + test.MockStore(t, store, 100) +} + +// TestImportExport is running a test.ImportExport tests +// using test.MockStore function. +func TestImportExport(t *testing.T) { + dir1, err := ioutil.TempDir("", "mock_"+t.Name()+"_exporter") + if err != nil { + panic(err) + } + defer os.RemoveAll(dir1) + + store1, err := NewGlobalStore(dir1) + if err != nil { + t.Fatal(err) + } + defer store1.Close() + + dir2, err := ioutil.TempDir("", "mock_"+t.Name()+"_importer") + if err != nil { + panic(err) + } + defer os.RemoveAll(dir2) + + store2, err := NewGlobalStore(dir2) + if err != nil { + t.Fatal(err) + } + defer store2.Close() + + test.ImportExport(t, store1, store2, 100) +} diff --git a/swarm/storage/mock/mem/mem.go b/swarm/storage/mock/mem/mem.go new file mode 100644 index 0000000000..8878309d0e --- /dev/null +++ b/swarm/storage/mock/mem/mem.go @@ -0,0 +1,175 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +// Package mem implements a mock store that keeps all chunk data in memory. +// While it can be used for testing on smaller scales, the main purpose of this +// package is to provide the simplest reference implementation of a mock store. +package mem + +import ( + "archive/tar" + "bytes" + "encoding/json" + "io" + "io/ioutil" + "sync" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/swarm/storage/mock" +) + +// GlobalStore stores all chunk data and also keys and node addresses relations. +// It implements mock.GlobalStore interface. +type GlobalStore struct { + nodes map[string]map[common.Address]struct{} + data map[string][]byte + mu sync.Mutex +} + +// NewGlobalStore creates a new instance of GlobalStore. +func NewGlobalStore() *GlobalStore { + return &GlobalStore{ + nodes: make(map[string]map[common.Address]struct{}), + data: make(map[string][]byte), + } +} + +// NewNodeStore returns a new instance of NodeStore that retrieves and stores +// chunk data only for a node with address addr. +func (s *GlobalStore) NewNodeStore(addr common.Address) *mock.NodeStore { + return mock.NewNodeStore(addr, s) +} + +// Get returns chunk data if the chunk with key exists for node +// on address addr. +func (s *GlobalStore) Get(addr common.Address, key []byte) (data []byte, err error) { + s.mu.Lock() + defer s.mu.Unlock() + + if _, ok := s.nodes[string(key)][addr]; !ok { + return nil, mock.ErrNotFound + } + + data, ok := s.data[string(key)] + if !ok { + return nil, mock.ErrNotFound + } + return data, nil +} + +// Put saves the chunk data for node with address addr. +func (s *GlobalStore) Put(addr common.Address, key []byte, data []byte) error { + s.mu.Lock() + defer s.mu.Unlock() + + if _, ok := s.nodes[string(key)]; !ok { + s.nodes[string(key)] = make(map[common.Address]struct{}) + } + s.nodes[string(key)][addr] = struct{}{} + s.data[string(key)] = data + return nil +} + +// HasKey returns whether a node with addr contains the key. +func (s *GlobalStore) HasKey(addr common.Address, key []byte) bool { + s.mu.Lock() + defer s.mu.Unlock() + + _, ok := s.nodes[string(key)][addr] + return ok +} + +// Import reads tar archive from a reader that contains exported chunk data. +// It returns the number of chunks imported and an error. +func (s *GlobalStore) Import(r io.Reader) (n int, err error) { + s.mu.Lock() + defer s.mu.Unlock() + + tr := tar.NewReader(r) + + for { + hdr, err := tr.Next() + if err != nil { + if err == io.EOF { + break + } + return n, err + } + + data, err := ioutil.ReadAll(tr) + if err != nil { + return n, err + } + + var c mock.ExportedChunk + if err = json.Unmarshal(data, &c); err != nil { + return n, err + } + + addrs := make(map[common.Address]struct{}) + for _, a := range c.Addrs { + addrs[a] = struct{}{} + } + + key := string(common.Hex2Bytes(hdr.Name)) + s.nodes[key] = addrs + s.data[key] = c.Data + n++ + } + return n, err +} + +// Export writes to a writer a tar archive with all chunk data from +// the store. It returns the number of chunks exported and an error. +func (s *GlobalStore) Export(w io.Writer) (n int, err error) { + s.mu.Lock() + defer s.mu.Unlock() + + tw := tar.NewWriter(w) + defer tw.Close() + + buf := bytes.NewBuffer(make([]byte, 0, 1024)) + encoder := json.NewEncoder(buf) + for key, addrs := range s.nodes { + al := make([]common.Address, 0, len(addrs)) + for a := range addrs { + al = append(al, a) + } + + buf.Reset() + if err = encoder.Encode(mock.ExportedChunk{ + Addrs: al, + Data: s.data[key], + }); err != nil { + return n, err + } + + data := buf.Bytes() + hdr := &tar.Header{ + Name: common.Bytes2Hex([]byte(key)), + Mode: 0644, + Size: int64(len(data)), + } + if err := tw.WriteHeader(hdr); err != nil { + return n, err + } + if _, err := tw.Write(data); err != nil { + return n, err + } + n++ + } + return n, err +} diff --git a/swarm/storage/mock/mem/mem_test.go b/swarm/storage/mock/mem/mem_test.go new file mode 100644 index 0000000000..adcefaabb4 --- /dev/null +++ b/swarm/storage/mock/mem/mem_test.go @@ -0,0 +1,36 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package mem + +import ( + "testing" + + "github.com/ethereum/go-ethereum/swarm/storage/mock/test" +) + +// TestGlobalStore is running test for a GlobalStore +// using test.MockStore function. +func TestGlobalStore(t *testing.T) { + test.MockStore(t, NewGlobalStore(), 100) +} + +// TestImportExport is running tests for importing and +// exporting data between two GlobalStores +// using test.ImportExport function. +func TestImportExport(t *testing.T) { + test.ImportExport(t, NewGlobalStore(), NewGlobalStore(), 100) +} diff --git a/swarm/storage/mock/mock.go b/swarm/storage/mock/mock.go new file mode 100644 index 0000000000..81340f9274 --- /dev/null +++ b/swarm/storage/mock/mock.go @@ -0,0 +1,111 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +// Package mock defines types that are used by different implementations +// of mock storages. +// +// Implementations of mock storages are located in directories +// under this package: +// +// - db - LevelDB backend +// - mem - in memory map backend +// - rpc - RPC client that can connect to other backends +// +// Mock storages can implement Importer and Exporter interfaces +// for importing and exporting all chunk data that they contain. +// The exported file is a tar archive with all files named by +// hexadecimal representations of chunk keys and with content +// with JSON-encoded ExportedChunk structure. Exported format +// should be preserved across all mock store implementations. +package mock + +import ( + "errors" + "io" + + "github.com/ethereum/go-ethereum/common" +) + +// ErrNotFound indicates that the chunk is not found. +var ErrNotFound = errors.New("not found") + +// NodeStore holds the node address and a reference to the GlobalStore +// in order to access and store chunk data only for one node. +type NodeStore struct { + store GlobalStorer + addr common.Address +} + +// NewNodeStore creates a new instance of NodeStore that keeps +// chunk data using GlobalStorer with a provided address. +func NewNodeStore(addr common.Address, store GlobalStorer) *NodeStore { + return &NodeStore{ + store: store, + addr: addr, + } +} + +// Get returns chunk data for a key for a node that has the address +// provided on NodeStore initialization. +func (n *NodeStore) Get(key []byte) (data []byte, err error) { + return n.store.Get(n.addr, key) +} + +// Put saves chunk data for a key for a node that has the address +// provided on NodeStore initialization. +func (n *NodeStore) Put(key []byte, data []byte) error { + return n.store.Put(n.addr, key, data) +} + +// GlobalStorer defines methods for mock db store +// that stores chunk data for all swarm nodes. +// It is used in tests to construct mock NodeStores +// for swarm nodes and to track and validate chunks. +type GlobalStorer interface { + Get(addr common.Address, key []byte) (data []byte, err error) + Put(addr common.Address, key []byte, data []byte) error + HasKey(addr common.Address, key []byte) bool + // NewNodeStore creates an instance of NodeStore + // to be used by a single swarm node with + // address addr. + NewNodeStore(addr common.Address) *NodeStore +} + +// Importer defines method for importing mock store data +// from an exported tar archive. +type Importer interface { + Import(r io.Reader) (n int, err error) +} + +// Exporter defines method for exporting mock store data +// to a tar archive. +type Exporter interface { + Export(w io.Writer) (n int, err error) +} + +// ImportExporter is an interface for importing and exporting +// mock store data to and from a tar archive. +type ImportExporter interface { + Importer + Exporter +} + +// ExportedChunk is the structure that is saved in tar archive for +// each chunk as JSON-encoded bytes. +type ExportedChunk struct { + Data []byte `json:"d"` + Addrs []common.Address `json:"a"` +} diff --git a/swarm/storage/mock/rpc/rpc.go b/swarm/storage/mock/rpc/rpc.go new file mode 100644 index 0000000000..6e735f6988 --- /dev/null +++ b/swarm/storage/mock/rpc/rpc.go @@ -0,0 +1,84 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +// Package rpc implements an RPC client that connect to a centralized mock store. +// Centralazied mock store can be any other mock store implementation that is +// registered to Ethereum RPC server under mockStore name. Methods that defines +// mock.GlobalStore are the same that are used by RPC. Example: +// +// server := rpc.NewServer() +// server.RegisterName("mockStore", mem.NewGlobalStore()) +package rpc + +import ( + "fmt" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/rpc" + "github.com/ethereum/go-ethereum/swarm/log" + "github.com/ethereum/go-ethereum/swarm/storage/mock" +) + +// GlobalStore is rpc.Client that connects to a centralized mock store. +// Closing GlobalStore instance is required to release RPC client resources. +type GlobalStore struct { + client *rpc.Client +} + +// NewGlobalStore creates a new instance of GlobalStore. +func NewGlobalStore(client *rpc.Client) *GlobalStore { + return &GlobalStore{ + client: client, + } +} + +// Close closes RPC client. +func (s *GlobalStore) Close() error { + s.client.Close() + return nil +} + +// NewNodeStore returns a new instance of NodeStore that retrieves and stores +// chunk data only for a node with address addr. +func (s *GlobalStore) NewNodeStore(addr common.Address) *mock.NodeStore { + return mock.NewNodeStore(addr, s) +} + +// Get calls a Get method to RPC server. +func (s *GlobalStore) Get(addr common.Address, key []byte) (data []byte, err error) { + err = s.client.Call(&data, "mockStore_get", addr, key) + if err != nil && err.Error() == "not found" { + // pass the mock package value of error instead an rpc error + return data, mock.ErrNotFound + } + return data, err +} + +// Put calls a Put method to RPC server. +func (s *GlobalStore) Put(addr common.Address, key []byte, data []byte) error { + err := s.client.Call(nil, "mockStore_put", addr, key, data) + return err +} + +// HasKey calls a HasKey method to RPC server. +func (s *GlobalStore) HasKey(addr common.Address, key []byte) bool { + var has bool + if err := s.client.Call(&has, "mockStore_hasKey", addr, key); err != nil { + log.Error(fmt.Sprintf("mock store HasKey: addr %s, key %064x: %v", addr, key, err)) + return false + } + return has +} diff --git a/swarm/storage/mock/rpc/rpc_test.go b/swarm/storage/mock/rpc/rpc_test.go new file mode 100644 index 0000000000..52b634a445 --- /dev/null +++ b/swarm/storage/mock/rpc/rpc_test.go @@ -0,0 +1,41 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package rpc + +import ( + "testing" + + "github.com/ethereum/go-ethereum/rpc" + "github.com/ethereum/go-ethereum/swarm/storage/mock/mem" + "github.com/ethereum/go-ethereum/swarm/storage/mock/test" +) + +// TestDBStore is running test for a GlobalStore +// using test.MockStore function. +func TestRPCStore(t *testing.T) { + serverStore := mem.NewGlobalStore() + + server := rpc.NewServer() + if err := server.RegisterName("mockStore", serverStore); err != nil { + t.Fatal(err) + } + + store := NewGlobalStore(rpc.DialInProc(server)) + defer store.Close() + + test.MockStore(t, store, 100) +} diff --git a/swarm/storage/mock/test/test.go b/swarm/storage/mock/test/test.go new file mode 100644 index 0000000000..02da3af553 --- /dev/null +++ b/swarm/storage/mock/test/test.go @@ -0,0 +1,186 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +// Package test provides functions that are used for testing +// GlobalStorer implementations. +package test + +import ( + "bytes" + "fmt" + "io" + "strconv" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/swarm/storage" + "github.com/ethereum/go-ethereum/swarm/storage/mock" +) + +// MockStore creates NodeStore instances from provided GlobalStorer, +// each one with a unique address, stores different chunks on them +// and checks if they are retrievable or not on all nodes. +// Attribute n defines the number of NodeStores that will be created. +func MockStore(t *testing.T, globalStore mock.GlobalStorer, n int) { + t.Run("GlobalStore", func(t *testing.T) { + addrs := make([]common.Address, n) + for i := 0; i < n; i++ { + addrs[i] = common.HexToAddress(strconv.FormatInt(int64(i)+1, 16)) + } + + for i, addr := range addrs { + chunkAddr := storage.Address(append(addr[:], []byte(strconv.FormatInt(int64(i)+1, 16))...)) + data := []byte(strconv.FormatInt(int64(i)+1, 16)) + data = append(data, make([]byte, 4096-len(data))...) + globalStore.Put(addr, chunkAddr, data) + + for _, cAddr := range addrs { + cData, err := globalStore.Get(cAddr, chunkAddr) + if cAddr == addr { + if err != nil { + t.Fatalf("get data from store %s key %s: %v", cAddr.Hex(), chunkAddr.Hex(), err) + } + if !bytes.Equal(data, cData) { + t.Fatalf("data on store %s: expected %x, got %x", cAddr.Hex(), data, cData) + } + if !globalStore.HasKey(cAddr, chunkAddr) { + t.Fatalf("expected key %s on global store for node %s, but it was not found", chunkAddr.Hex(), cAddr.Hex()) + } + } else { + if err != mock.ErrNotFound { + t.Fatalf("expected error from store %s: %v, got %v", cAddr.Hex(), mock.ErrNotFound, err) + } + if len(cData) > 0 { + t.Fatalf("data on store %s: expected nil, got %x", cAddr.Hex(), cData) + } + if globalStore.HasKey(cAddr, chunkAddr) { + t.Fatalf("not expected key %s on global store for node %s, but it was found", chunkAddr.Hex(), cAddr.Hex()) + } + } + } + } + }) + + t.Run("NodeStore", func(t *testing.T) { + nodes := make(map[common.Address]*mock.NodeStore) + for i := 0; i < n; i++ { + addr := common.HexToAddress(strconv.FormatInt(int64(i)+1, 16)) + nodes[addr] = globalStore.NewNodeStore(addr) + } + + i := 0 + for addr, store := range nodes { + i++ + chunkAddr := storage.Address(append(addr[:], []byte(fmt.Sprintf("%x", i))...)) + data := []byte(strconv.FormatInt(int64(i)+1, 16)) + data = append(data, make([]byte, 4096-len(data))...) + store.Put(chunkAddr, data) + + for cAddr, cStore := range nodes { + cData, err := cStore.Get(chunkAddr) + if cAddr == addr { + if err != nil { + t.Fatalf("get data from store %s key %s: %v", cAddr.Hex(), chunkAddr.Hex(), err) + } + if !bytes.Equal(data, cData) { + t.Fatalf("data on store %s: expected %x, got %x", cAddr.Hex(), data, cData) + } + if !globalStore.HasKey(cAddr, chunkAddr) { + t.Fatalf("expected key %s on global store for node %s, but it was not found", chunkAddr.Hex(), cAddr.Hex()) + } + } else { + if err != mock.ErrNotFound { + t.Fatalf("expected error from store %s: %v, got %v", cAddr.Hex(), mock.ErrNotFound, err) + } + if len(cData) > 0 { + t.Fatalf("data on store %s: expected nil, got %x", cAddr.Hex(), cData) + } + if globalStore.HasKey(cAddr, chunkAddr) { + t.Fatalf("not expected key %s on global store for node %s, but it was found", chunkAddr.Hex(), cAddr.Hex()) + } + } + } + } + }) +} + +// ImportExport saves chunks to the outStore, exports them to the tar archive, +// imports tar archive to the inStore and checks if all chunks are imported correctly. +func ImportExport(t *testing.T, outStore, inStore mock.GlobalStorer, n int) { + exporter, ok := outStore.(mock.Exporter) + if !ok { + t.Fatal("outStore does not implement mock.Exporter") + } + importer, ok := inStore.(mock.Importer) + if !ok { + t.Fatal("inStore does not implement mock.Importer") + } + addrs := make([]common.Address, n) + for i := 0; i < n; i++ { + addrs[i] = common.HexToAddress(strconv.FormatInt(int64(i)+1, 16)) + } + + for i, addr := range addrs { + chunkAddr := storage.Address(append(addr[:], []byte(strconv.FormatInt(int64(i)+1, 16))...)) + data := []byte(strconv.FormatInt(int64(i)+1, 16)) + data = append(data, make([]byte, 4096-len(data))...) + outStore.Put(addr, chunkAddr, data) + } + + r, w := io.Pipe() + defer r.Close() + + go func() { + defer w.Close() + if _, err := exporter.Export(w); err != nil { + t.Fatalf("export: %v", err) + } + }() + + if _, err := importer.Import(r); err != nil { + t.Fatalf("import: %v", err) + } + + for i, addr := range addrs { + chunkAddr := storage.Address(append(addr[:], []byte(strconv.FormatInt(int64(i)+1, 16))...)) + data := []byte(strconv.FormatInt(int64(i)+1, 16)) + data = append(data, make([]byte, 4096-len(data))...) + for _, cAddr := range addrs { + cData, err := inStore.Get(cAddr, chunkAddr) + if cAddr == addr { + if err != nil { + t.Fatalf("get data from store %s key %s: %v", cAddr.Hex(), chunkAddr.Hex(), err) + } + if !bytes.Equal(data, cData) { + t.Fatalf("data on store %s: expected %x, got %x", cAddr.Hex(), data, cData) + } + if !inStore.HasKey(cAddr, chunkAddr) { + t.Fatalf("expected key %s on global store for node %s, but it was not found", chunkAddr.Hex(), cAddr.Hex()) + } + } else { + if err != mock.ErrNotFound { + t.Fatalf("expected error from store %s: %v, got %v", cAddr.Hex(), mock.ErrNotFound, err) + } + if len(cData) > 0 { + t.Fatalf("data on store %s: expected nil, got %x", cAddr.Hex(), cData) + } + if inStore.HasKey(cAddr, chunkAddr) { + t.Fatalf("not expected key %s on global store for node %s, but it was found", chunkAddr.Hex(), cAddr.Hex()) + } + } + } + } +} diff --git a/swarm/storage/mru/doc.go b/swarm/storage/mru/doc.go new file mode 100644 index 0000000000..e1d7c2c343 --- /dev/null +++ b/swarm/storage/mru/doc.go @@ -0,0 +1,61 @@ +// Package mru defines Mutable resource updates. +// A Mutable Resource is an entity which allows updates to a resource +// without resorting to ENS on each update. +// The update scheme is built on swarm chunks with chunk keys following +// a predictable, versionable pattern. +// +// Updates are defined to be periodic in nature, where the update frequency +// is expressed in seconds. +// +// The root entry of a mutable resource is tied to a unique identifier that +// is deterministically generated out of the metadata content that describes +// the resource. This metadata includes a user-defined resource name, a resource +// start time that indicates when the resource becomes valid, +// the frequency in seconds with which the resource is expected to be updated, both of +// which are stored as little-endian uint64 values in the database (for a +// total of 16 bytes). It also contains the owner's address (ownerAddr) +// This MRU info is stored in a separate content-addressed chunk +// (call it the metadata chunk), with the following layout: +// +// (00|length|startTime|frequency|name|ownerAddr) +// +// (The two first zero-value bytes are used for disambiguation by the chunk validator, +// and update chunk will always have a value > 0 there.) +// +// Each metadata chunk is identified by its rootAddr, calculated as follows: +// metaHash=H(len(metadata), startTime, frequency,name) +// rootAddr = H(metaHash, ownerAddr). +// where H is the SHA3 hash function +// This scheme effectively locks the root chunk so that only the owner of the private key +// that ownerAddr was derived from can sign updates. +// +// The root entry tells the requester from when the mutable resource was +// first added (Unix time in seconds) and in which moments to look for the +// actual updates. Thus, a resource update for identifier "føø.bar" +// starting at unix time 1528800000 with frequency 300 (every 5 mins) will have updates on 1528800300, +// 1528800600, 1528800900 and so on. +// +// Actual data updates are also made in the form of swarm chunks. The keys +// of the updates are the hash of a concatenation of properties as follows: +// +// updateAddr = H(period, version, rootAddr) +// where H is the SHA3 hash function +// The period is (currentTime - startTime) / frequency +// +// Using our previous example, this means that a period 3 will happen when the +// clock hits 1528800900 +// +// If more than one update is made in the same period, incremental +// version numbers are used successively. +// +// A user looking up a resource would only need to know the rootAddr in order to get the versions +// +// the resource update data is: +// resourcedata = headerlength|period|version|rootAddr|flags|metaHash +// where flags is a 1-byte flags field. Flag 0 is set to 1 to indicate multihash +// +// the full update data that goes in the chunk payload is: +// resourcedata|sign(resourcedata) +// +// headerlength is a 16 bit value containing the byte length of period|version|rootAddr|flags|metaHash +package mru diff --git a/swarm/storage/mru/error.go b/swarm/storage/mru/error.go new file mode 100644 index 0000000000..18ab525582 --- /dev/null +++ b/swarm/storage/mru/error.go @@ -0,0 +1,73 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package mru + +import ( + "fmt" +) + +const ( + ErrInit = iota + ErrNotFound + ErrIO + ErrUnauthorized + ErrInvalidValue + ErrDataOverflow + ErrNothingToReturn + ErrCorruptData + ErrInvalidSignature + ErrNotSynced + ErrPeriodDepth + ErrCnt +) + +// Error is a the typed error object used for Mutable Resources +type Error struct { + code int + err string +} + +// Error implements the error interface +func (e *Error) Error() string { + return e.err +} + +// Code returns the error code +// Error codes are enumerated in the error.go file within the mru package +func (e *Error) Code() int { + return e.code +} + +// NewError creates a new Mutable Resource Error object with the specified code and custom error message +func NewError(code int, s string) error { + if code < 0 || code >= ErrCnt { + panic("no such error code!") + } + r := &Error{ + err: s, + } + switch code { + case ErrNotFound, ErrIO, ErrUnauthorized, ErrInvalidValue, ErrDataOverflow, ErrNothingToReturn, ErrInvalidSignature, ErrNotSynced, ErrPeriodDepth, ErrCorruptData: + r.code = code + } + return r +} + +// NewErrorf is a convenience version of NewError that incorporates printf-style formatting +func NewErrorf(code int, format string, args ...interface{}) error { + return NewError(code, fmt.Sprintf(format, args...)) +} diff --git a/swarm/storage/mru/handler.go b/swarm/storage/mru/handler.go new file mode 100644 index 0000000000..188b986b85 --- /dev/null +++ b/swarm/storage/mru/handler.go @@ -0,0 +1,514 @@ +// 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 . + +// Handler is the API for Mutable Resources +// It enables creating, updating, syncing and retrieving resources and their update data +package mru + +import ( + "bytes" + "context" + "fmt" + "sync" + "time" + "unsafe" + + "github.com/ethereum/go-ethereum/swarm/log" + "github.com/ethereum/go-ethereum/swarm/storage" +) + +const chunkSize = 4096 // temporary until we implement FileStore in the resourcehandler + +type Handler struct { + chunkStore *storage.NetStore + HashSize int + resources map[uint64]*resource + resourceLock sync.RWMutex + storeTimeout time.Duration + queryMaxPeriods uint32 +} + +// HandlerParams pass parameters to the Handler constructor NewHandler +// Signer and TimestampProvider are mandatory parameters +type HandlerParams struct { + QueryMaxPeriods uint32 +} + +// hashPool contains a pool of ready hashers +var hashPool sync.Pool +var minimumChunkLength int + +// init initializes the package and hashPool +func init() { + hashPool = sync.Pool{ + New: func() interface{} { + return storage.MakeHashFunc(resourceHashAlgorithm)() + }, + } + if minimumMetadataLength < minimumUpdateDataLength { + minimumChunkLength = minimumMetadataLength + } else { + minimumChunkLength = minimumUpdateDataLength + } +} + +// NewHandler creates a new Mutable Resource API +func NewHandler(params *HandlerParams) (*Handler, error) { + + rh := &Handler{ + resources: make(map[uint64]*resource), + storeTimeout: defaultStoreTimeout, + queryMaxPeriods: params.QueryMaxPeriods, + } + + for i := 0; i < hasherCount; i++ { + hashfunc := storage.MakeHashFunc(resourceHashAlgorithm)() + if rh.HashSize == 0 { + rh.HashSize = hashfunc.Size() + } + hashPool.Put(hashfunc) + } + + return rh, nil +} + +// SetStore sets the store backend for the Mutable Resource API +func (h *Handler) SetStore(store *storage.NetStore) { + h.chunkStore = store +} + +// Validate is a chunk validation method +// If it looks like a resource update, the chunk address is checked against the ownerAddr of the update's signature +// It implements the storage.ChunkValidator interface +func (h *Handler) Validate(chunkAddr storage.Address, data []byte) bool { + + dataLength := len(data) + if dataLength < minimumChunkLength { + return false + } + + //metadata chunks have the first two bytes set to zero + if data[0] == 0 && data[1] == 0 && dataLength >= minimumMetadataLength { + //metadata chunk + rootAddr, _ := metadataHash(data) + valid := bytes.Equal(chunkAddr, rootAddr) + if !valid { + log.Debug(fmt.Sprintf("Invalid root metadata chunk with address: %s", chunkAddr.Hex())) + } + return valid + } + + // if it is not a metadata chunk, check if it is a properly formatted update chunk with + // valid signature and proof of ownership of the resource it is trying + // to update + + // First, deserialize the chunk + var r SignedResourceUpdate + if err := r.fromChunk(chunkAddr, data); err != nil { + log.Debug("Invalid resource chunk with address %s: %s ", chunkAddr.Hex(), err.Error()) + return false + } + + // check that the lookup information contained in the chunk matches the updateAddr (chunk search key) + // that was used to retrieve this chunk + // if this validation fails, someone forged a chunk. + if !bytes.Equal(chunkAddr, r.updateHeader.UpdateAddr()) { + log.Debug("period,version,rootAddr contained in update chunk do not match updateAddr %s", chunkAddr.Hex()) + return false + } + + // Verify signatures and that the signer actually owns the resource + // If it fails, it means either the signature is not valid, data is corrupted + // or someone is trying to update someone else's resource. + if err := r.Verify(); err != nil { + log.Debug("Invalid signature: %v", err) + return false + } + + return true +} + +// GetContent retrieves the data payload of the last synced update of the Mutable Resource +func (h *Handler) GetContent(rootAddr storage.Address) (storage.Address, []byte, error) { + rsrc := h.get(rootAddr) + if rsrc == nil || !rsrc.isSynced() { + return nil, nil, NewError(ErrNotFound, " does not exist or is not synced") + } + return rsrc.lastKey, rsrc.data, nil +} + +// GetLastPeriod retrieves the period of the last synced update of the Mutable Resource +func (h *Handler) GetLastPeriod(rootAddr storage.Address) (uint32, error) { + rsrc := h.get(rootAddr) + if rsrc == nil { + return 0, NewError(ErrNotFound, " does not exist") + } else if !rsrc.isSynced() { + return 0, NewError(ErrNotSynced, " is not synced") + } + return rsrc.period, nil +} + +// GetVersion retrieves the period of the last synced update of the Mutable Resource +func (h *Handler) GetVersion(rootAddr storage.Address) (uint32, error) { + rsrc := h.get(rootAddr) + if rsrc == nil { + return 0, NewError(ErrNotFound, " does not exist") + } else if !rsrc.isSynced() { + return 0, NewError(ErrNotSynced, " is not synced") + } + return rsrc.version, nil +} + +// \TODO should be hashsize * branches from the chosen chunker, implement with FileStore +func (h *Handler) chunkSize() int64 { + return chunkSize +} + +// New creates a new metadata chunk out of the request passed in. +func (h *Handler) New(ctx context.Context, request *Request) error { + + // frequency 0 is invalid + if request.metadata.Frequency == 0 { + return NewError(ErrInvalidValue, "frequency cannot be 0 when creating a resource") + } + + // make sure owner is set to something + if request.metadata.Owner == zeroAddr { + return NewError(ErrInvalidValue, "ownerAddr must be set to create a new metadata chunk") + } + + // create the meta chunk and store it in swarm + chunk, metaHash, err := request.metadata.newChunk() + if err != nil { + return err + } + if request.metaHash != nil && !bytes.Equal(request.metaHash, metaHash) || + request.rootAddr != nil && !bytes.Equal(request.rootAddr, chunk.Addr) { + return NewError(ErrInvalidValue, "metaHash in UpdateRequest does not match actual metadata") + } + + request.metaHash = metaHash + request.rootAddr = chunk.Addr + + h.chunkStore.Put(ctx, chunk) + log.Debug("new resource", "name", request.metadata.Name, "startTime", request.metadata.StartTime, "frequency", request.metadata.Frequency, "owner", request.metadata.Owner) + + // create the internal index for the resource and populate it with its metadata + rsrc := &resource{ + resourceUpdate: resourceUpdate{ + updateHeader: updateHeader{ + UpdateLookup: UpdateLookup{ + rootAddr: chunk.Addr, + }, + }, + }, + ResourceMetadata: request.metadata, + updated: time.Now(), + } + h.set(chunk.Addr, rsrc) + + return nil +} + +// NewUpdateRequest prepares an UpdateRequest structure with all the necessary information to +// just add the desired data and sign it. +// The resulting structure can then be signed and passed to Handler.Update to be verified and sent +func (h *Handler) NewUpdateRequest(ctx context.Context, rootAddr storage.Address) (updateRequest *Request, err error) { + + if rootAddr == nil { + return nil, NewError(ErrInvalidValue, "rootAddr cannot be nil") + } + + // Make sure we have a cache of the metadata chunk + rsrc, err := h.Load(ctx, rootAddr) + if err != nil { + return nil, err + } + + now := TimestampProvider.Now() + + updateRequest = new(Request) + updateRequest.period, err = getNextPeriod(rsrc.StartTime.Time, now.Time, rsrc.Frequency) + if err != nil { + return nil, err + } + + if _, err = h.lookup(rsrc, LookupLatestVersionInPeriod(rsrc.rootAddr, updateRequest.period)); err != nil { + if err.(*Error).code != ErrNotFound { + return nil, err + } + // not finding updates means that there is a network error + // or that the resource really does not have updates in this period. + } + + updateRequest.multihash = rsrc.multihash + updateRequest.rootAddr = rsrc.rootAddr + updateRequest.metaHash = rsrc.metaHash + updateRequest.metadata = rsrc.ResourceMetadata + + // if we already have an update for this period then increment version + // resource object MUST be in sync for version to be correct, but we checked this earlier in the method already + if h.hasUpdate(rootAddr, updateRequest.period) { + updateRequest.version = rsrc.version + 1 + } else { + updateRequest.version = 1 + } + + return updateRequest, nil +} + +// Lookup retrieves a specific or latest version of the resource update with metadata chunk at params.Root +// Lookup works differently depending on the configuration of `LookupParams` +// See the `LookupParams` documentation and helper functions: +// `LookupLatest`, `LookupLatestVersionInPeriod` and `LookupVersion` +// When looking for the latest update, it starts at the next period after the current time. +// upon failure tries the corresponding keys of each previous period until one is found +// (or startTime is reached, in which case there are no updates). +func (h *Handler) Lookup(ctx context.Context, params *LookupParams) (*resource, error) { + + rsrc := h.get(params.rootAddr) + if rsrc == nil { + return nil, NewError(ErrNothingToReturn, "resource not loaded") + } + return h.lookup(rsrc, params) +} + +// LookupPrevious returns the resource before the one currently loaded in the resource cache +// This is useful where resource updates are used incrementally in contrast to +// merely replacing content. +// Requires a cached resource object to determine the current state of the resource. +func (h *Handler) LookupPrevious(ctx context.Context, params *LookupParams) (*resource, error) { + rsrc := h.get(params.rootAddr) + if rsrc == nil { + return nil, NewError(ErrNothingToReturn, "resource not loaded") + } + if !rsrc.isSynced() { + return nil, NewError(ErrNotSynced, "LookupPrevious requires synced resource.") + } else if rsrc.period == 0 { + return nil, NewError(ErrNothingToReturn, " not found") + } + var version, period uint32 + if rsrc.version > 1 { + version = rsrc.version - 1 + period = rsrc.period + } else if rsrc.period == 1 { + return nil, NewError(ErrNothingToReturn, "Current update is the oldest") + } else { + version = 0 + period = rsrc.period - 1 + } + return h.lookup(rsrc, NewLookupParams(rsrc.rootAddr, period, version, params.Limit)) +} + +// base code for public lookup methods +func (h *Handler) lookup(rsrc *resource, params *LookupParams) (*resource, error) { + + lp := *params + // we can't look for anything without a store + if h.chunkStore == nil { + return nil, NewError(ErrInit, "Call Handler.SetStore() before performing lookups") + } + + var specificperiod bool + if lp.period > 0 { + specificperiod = true + } else { + // get the current time and the next period + now := TimestampProvider.Now() + + var period uint32 + period, err := getNextPeriod(rsrc.StartTime.Time, now.Time, rsrc.Frequency) + if err != nil { + return nil, err + } + lp.period = period + } + + // start from the last possible period, and iterate previous ones + // (unless we want a specific period only) until we find a match. + // If we hit startTime we're out of options + var specificversion bool + if lp.version > 0 { + specificversion = true + } else { + lp.version = 1 + } + + var hops uint32 + if lp.Limit == 0 { + lp.Limit = h.queryMaxPeriods + } + log.Trace("resource lookup", "period", lp.period, "version", lp.version, "limit", lp.Limit) + for lp.period > 0 { + if lp.Limit != 0 && hops > lp.Limit { + return nil, NewErrorf(ErrPeriodDepth, "Lookup exceeded max period hops (%d)", lp.Limit) + } + updateAddr := lp.UpdateAddr() + chunk, err := h.chunkStore.GetWithTimeout(context.TODO(), updateAddr, defaultRetrieveTimeout) + if err == nil { + if specificversion { + return h.updateIndex(rsrc, chunk) + } + // check if we have versions > 1. If a version fails, the previous version is used and returned. + log.Trace("rsrc update version 1 found, checking for version updates", "period", lp.period, "updateAddr", updateAddr) + for { + newversion := lp.version + 1 + updateAddr := lp.UpdateAddr() + newchunk, err := h.chunkStore.GetWithTimeout(context.TODO(), updateAddr, defaultRetrieveTimeout) + if err != nil { + return h.updateIndex(rsrc, chunk) + } + chunk = newchunk + lp.version = newversion + log.Trace("version update found, checking next", "version", lp.version, "period", lp.period, "updateAddr", updateAddr) + } + } + if specificperiod { + break + } + log.Trace("rsrc update not found, checking previous period", "period", lp.period, "updateAddr", updateAddr) + lp.period-- + hops++ + } + return nil, NewError(ErrNotFound, "no updates found") +} + +// Load retrieves the Mutable Resource metadata chunk stored at rootAddr +// Upon retrieval it creates/updates the index entry for it with metadata corresponding to the chunk contents +func (h *Handler) Load(ctx context.Context, rootAddr storage.Address) (*resource, error) { + chunk, err := h.chunkStore.GetWithTimeout(ctx, rootAddr, defaultRetrieveTimeout) + if err != nil { + return nil, NewError(ErrNotFound, err.Error()) + } + + // create the index entry + rsrc := &resource{} + + if err := rsrc.ResourceMetadata.binaryGet(chunk.SData); err != nil { // Will fail if this is not really a metadata chunk + return nil, err + } + + rsrc.rootAddr, rsrc.metaHash = metadataHash(chunk.SData) + if !bytes.Equal(rsrc.rootAddr, rootAddr) { + return nil, NewError(ErrCorruptData, "Corrupt metadata chunk") + } + h.set(rootAddr, rsrc) + log.Trace("resource index load", "rootkey", rootAddr, "name", rsrc.ResourceMetadata.Name, "starttime", rsrc.ResourceMetadata.StartTime, "frequency", rsrc.ResourceMetadata.Frequency) + return rsrc, nil +} + +// update mutable resource index map with specified content +func (h *Handler) updateIndex(rsrc *resource, chunk *storage.Chunk) (*resource, error) { + + // retrieve metadata from chunk data and check that it matches this mutable resource + var r SignedResourceUpdate + if err := r.fromChunk(chunk.Addr, chunk.SData); err != nil { + return nil, err + } + log.Trace("resource index update", "name", rsrc.ResourceMetadata.Name, "updatekey", chunk.Addr, "period", r.period, "version", r.version) + + // update our rsrcs entry map + rsrc.lastKey = chunk.Addr + rsrc.period = r.period + rsrc.version = r.version + rsrc.updated = time.Now() + rsrc.data = make([]byte, len(r.data)) + rsrc.multihash = r.multihash + copy(rsrc.data, r.data) + rsrc.Reader = bytes.NewReader(rsrc.data) + log.Debug("resource synced", "name", rsrc.ResourceMetadata.Name, "updateAddr", chunk.Addr, "period", rsrc.period, "version", rsrc.version) + h.set(chunk.Addr, rsrc) + return rsrc, nil +} + +// Update adds an actual data update +// Uses the Mutable Resource metadata currently loaded in the resources map entry. +// It is the caller's responsibility to make sure that this data is not stale. +// Note that a Mutable Resource update cannot span chunks, and thus has a MAX NET LENGTH 4096, INCLUDING update header data and signature. An error will be returned if the total length of the chunk payload will exceed this limit. +// Update can only check if the caller is trying to overwrite the very last known version, otherwise it just puts the update +// on the network. +func (h *Handler) Update(ctx context.Context, r *SignedResourceUpdate) (storage.Address, error) { + return h.update(ctx, r) +} + +// create and commit an update +func (h *Handler) update(ctx context.Context, r *SignedResourceUpdate) (updateAddr storage.Address, err error) { + + // we can't update anything without a store + if h.chunkStore == nil { + return nil, NewError(ErrInit, "Call Handler.SetStore() before updating") + } + + rsrc := h.get(r.rootAddr) + if rsrc != nil && rsrc.period != 0 && rsrc.version != 0 && // This is the only cheap check we can do for sure + rsrc.period == r.period && rsrc.version >= r.version { // without having to lookup update chunks + + return nil, NewError(ErrInvalidValue, "A former update in this period is already known to exist") + } + + chunk, err := r.toChunk() // Serialize the update into a chunk. Fails if data is too big + if err != nil { + return nil, err + } + + // send the chunk + h.chunkStore.Put(ctx, chunk) + log.Trace("resource update", "updateAddr", r.updateAddr, "lastperiod", r.period, "version", r.version, "data", chunk.SData, "multihash", r.multihash) + + // update our resources map entry if the new update is older than the one we have, if we have it. + if rsrc != nil && r.period > rsrc.period || (rsrc.period == r.period && r.version > rsrc.version) { + rsrc.period = r.period + rsrc.version = r.version + rsrc.data = make([]byte, len(r.data)) + rsrc.updated = time.Now() + rsrc.lastKey = r.updateAddr + rsrc.multihash = r.multihash + copy(rsrc.data, r.data) + rsrc.Reader = bytes.NewReader(rsrc.data) + } + return r.updateAddr, nil +} + +// Retrieves the resource index value for the given nameHash +func (h *Handler) get(rootAddr storage.Address) *resource { + if len(rootAddr) < storage.KeyLength { + log.Warn("Handler.get with invalid rootAddr") + return nil + } + hashKey := *(*uint64)(unsafe.Pointer(&rootAddr[0])) + h.resourceLock.RLock() + defer h.resourceLock.RUnlock() + rsrc := h.resources[hashKey] + return rsrc +} + +// Sets the resource index value for the given nameHash +func (h *Handler) set(rootAddr storage.Address, rsrc *resource) { + if len(rootAddr) < storage.KeyLength { + log.Warn("Handler.set with invalid rootAddr") + return + } + hashKey := *(*uint64)(unsafe.Pointer(&rootAddr[0])) + h.resourceLock.Lock() + defer h.resourceLock.Unlock() + h.resources[hashKey] = rsrc +} + +// Checks if we already have an update on this resource, according to the value in the current state of the resource index +func (h *Handler) hasUpdate(rootAddr storage.Address, period uint32) bool { + rsrc := h.get(rootAddr) + return rsrc != nil && rsrc.period == period +} diff --git a/swarm/storage/mru/lookup.go b/swarm/storage/mru/lookup.go new file mode 100644 index 0000000000..eb28336e12 --- /dev/null +++ b/swarm/storage/mru/lookup.go @@ -0,0 +1,117 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package mru + +import ( + "encoding/binary" + "hash" + + "github.com/ethereum/go-ethereum/swarm/storage" +) + +// LookupParams is used to specify constraints when performing an update lookup +// Limit defines whether or not the lookup should be limited +// If Limit is set to true then Max defines the amount of hops that can be performed +type LookupParams struct { + UpdateLookup + Limit uint32 +} + +// RootAddr returns the metadata chunk address +func (r *LookupParams) RootAddr() storage.Address { + return r.rootAddr +} + +func NewLookupParams(rootAddr storage.Address, period, version uint32, limit uint32) *LookupParams { + return &LookupParams{ + UpdateLookup: UpdateLookup{ + period: period, + version: version, + rootAddr: rootAddr, + }, + Limit: limit, + } +} + +// LookupLatest generates lookup parameters that look for the latest version of a resource +func LookupLatest(rootAddr storage.Address) *LookupParams { + return NewLookupParams(rootAddr, 0, 0, 0) +} + +// LookupLatestVersionInPeriod generates lookup parameters that look for the latest version of a resource in a given period +func LookupLatestVersionInPeriod(rootAddr storage.Address, period uint32) *LookupParams { + return NewLookupParams(rootAddr, period, 0, 0) +} + +// LookupVersion generates lookup parameters that look for a specific version of a resource +func LookupVersion(rootAddr storage.Address, period, version uint32) *LookupParams { + return NewLookupParams(rootAddr, period, version, 0) +} + +// UpdateLookup represents the components of a resource update search key +type UpdateLookup struct { + period uint32 + version uint32 + rootAddr storage.Address +} + +// 4 bytes period +// 4 bytes version +// storage.Keylength for rootAddr +const updateLookupLength = 4 + 4 + storage.KeyLength + +// UpdateAddr calculates the resource update chunk address corresponding to this lookup key +func (u *UpdateLookup) UpdateAddr() (updateAddr storage.Address) { + serializedData := make([]byte, updateLookupLength) + u.binaryPut(serializedData) + hasher := hashPool.Get().(hash.Hash) + defer hashPool.Put(hasher) + hasher.Reset() + hasher.Write(serializedData) + return hasher.Sum(nil) +} + +// binaryPut serializes this UpdateLookup instance into the provided slice +func (u *UpdateLookup) binaryPut(serializedData []byte) error { + if len(serializedData) != updateLookupLength { + return NewErrorf(ErrInvalidValue, "Incorrect slice size to serialize UpdateLookup. Expected %d, got %d", updateLookupLength, len(serializedData)) + } + if len(u.rootAddr) != storage.KeyLength { + return NewError(ErrInvalidValue, "UpdateLookup.binaryPut called without rootAddr set") + } + binary.LittleEndian.PutUint32(serializedData[:4], u.period) + binary.LittleEndian.PutUint32(serializedData[4:8], u.version) + copy(serializedData[8:], u.rootAddr[:]) + return nil +} + +// binaryLength returns the expected size of this structure when serialized +func (u *UpdateLookup) binaryLength() int { + return updateLookupLength +} + +// binaryGet restores the current instance from the information contained in the passed slice +func (u *UpdateLookup) binaryGet(serializedData []byte) error { + if len(serializedData) != updateLookupLength { + return NewErrorf(ErrInvalidValue, "Incorrect slice size to read UpdateLookup. Expected %d, got %d", updateLookupLength, len(serializedData)) + } + u.period = binary.LittleEndian.Uint32(serializedData[:4]) + u.version = binary.LittleEndian.Uint32(serializedData[4:8]) + u.rootAddr = storage.Address(make([]byte, storage.KeyLength)) + copy(u.rootAddr[:], serializedData[8:]) + return nil +} diff --git a/swarm/storage/mru/lookup_test.go b/swarm/storage/mru/lookup_test.go new file mode 100644 index 0000000000..b66b200a36 --- /dev/null +++ b/swarm/storage/mru/lookup_test.go @@ -0,0 +1,85 @@ +package mru + +import ( + "bytes" + "testing" + + "github.com/ethereum/go-ethereum/common/hexutil" +) + +func getTestUpdateLookup() *UpdateLookup { + metadata := *getTestMetadata() + rootAddr, _, _, _ := metadata.serializeAndHash() + return &UpdateLookup{ + period: 79, + version: 2010, + rootAddr: rootAddr, + } +} + +func compareUpdateLookup(a, b *UpdateLookup) bool { + return a.version == b.version && + a.period == b.period && + bytes.Equal(a.rootAddr, b.rootAddr) +} + +func TestUpdateLookupUpdateAddr(t *testing.T) { + ul := getTestUpdateLookup() + updateAddr := ul.UpdateAddr() + compareByteSliceToExpectedHex(t, "updateAddr", updateAddr, "0x8fbc8d4777ef6da790257eda80ab4321fabd08cbdbe67e4e3da6caca386d64e0") +} + +func TestUpdateLookupSerializer(t *testing.T) { + serializedUpdateLookup := make([]byte, updateLookupLength) + ul := getTestUpdateLookup() + if err := ul.binaryPut(serializedUpdateLookup); err != nil { + t.Fatal(err) + } + compareByteSliceToExpectedHex(t, "serializedUpdateLookup", serializedUpdateLookup, "0x4f000000da070000fb0ed7efa696bdb0b54cd75554cc3117ffc891454317df7dd6fefad978e2f2fb") + + // set receiving slice to the wrong size + serializedUpdateLookup = make([]byte, updateLookupLength+7) + if err := ul.binaryPut(serializedUpdateLookup); err == nil { + t.Fatalf("Expected UpdateLookup.binaryPut to fail when receiving slice has a length != %d", updateLookupLength) + } + + // set rootAddr to an invalid length + ul.rootAddr = []byte{1, 2, 3, 4} + serializedUpdateLookup = make([]byte, updateLookupLength) + if err := ul.binaryPut(serializedUpdateLookup); err == nil { + t.Fatal("Expected UpdateLookup.binaryPut to fail when rootAddr is not of the correct size") + } +} + +func TestUpdateLookupDeserializer(t *testing.T) { + serializedUpdateLookup, _ := hexutil.Decode("0x4f000000da070000fb0ed7efa696bdb0b54cd75554cc3117ffc891454317df7dd6fefad978e2f2fb") + var recoveredUpdateLookup UpdateLookup + if err := recoveredUpdateLookup.binaryGet(serializedUpdateLookup); err != nil { + t.Fatal(err) + } + originalUpdateLookup := *getTestUpdateLookup() + if !compareUpdateLookup(&originalUpdateLookup, &recoveredUpdateLookup) { + t.Fatalf("Expected recovered UpdateLookup to match") + } + + // set source slice to the wrong size + serializedUpdateLookup = make([]byte, updateLookupLength+4) + if err := recoveredUpdateLookup.binaryGet(serializedUpdateLookup); err == nil { + t.Fatalf("Expected UpdateLookup.binaryGet to fail when source slice has a length != %d", updateLookupLength) + } +} + +func TestUpdateLookupSerializeDeserialize(t *testing.T) { + serializedUpdateLookup := make([]byte, updateLookupLength) + originalUpdateLookup := getTestUpdateLookup() + if err := originalUpdateLookup.binaryPut(serializedUpdateLookup); err != nil { + t.Fatal(err) + } + var recoveredUpdateLookup UpdateLookup + if err := recoveredUpdateLookup.binaryGet(serializedUpdateLookup); err != nil { + t.Fatal(err) + } + if !compareUpdateLookup(originalUpdateLookup, &recoveredUpdateLookup) { + t.Fatalf("Expected recovered UpdateLookup to match") + } +} diff --git a/swarm/storage/mru/metadata.go b/swarm/storage/mru/metadata.go new file mode 100644 index 0000000000..0ab0ed1d9e --- /dev/null +++ b/swarm/storage/mru/metadata.go @@ -0,0 +1,189 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package mru + +import ( + "encoding/binary" + "hash" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/swarm/storage" +) + +// ResourceMetadata encapsulates the immutable information about a mutable resource :) +// once serialized into a chunk, the resource can be retrieved by knowing its content-addressed rootAddr +type ResourceMetadata struct { + StartTime Timestamp // time at which the resource starts to be valid + Frequency uint64 // expected update frequency for the resource + Name string // name of the resource, for the reference of the user or to disambiguate resources with same starttime, frequency, owneraddr + Owner common.Address // public address of the resource owner +} + +const frequencyLength = 8 // sizeof(uint64) +const nameLengthLength = 1 + +// Resource metadata chunk layout: +// 4 prefix bytes (chunkPrefixLength). The first two set to zero. The second two indicate the length +// Timestamp: timestampLength bytes +// frequency: frequencyLength bytes +// name length: nameLengthLength bytes +// name (variable length, can be empty, up to 255 bytes) +// ownerAddr: common.AddressLength +const minimumMetadataLength = chunkPrefixLength + timestampLength + frequencyLength + nameLengthLength + common.AddressLength + +// binaryGet populates the resource metadata from a byte array +func (r *ResourceMetadata) binaryGet(serializedData []byte) error { + if len(serializedData) < minimumMetadataLength { + return NewErrorf(ErrInvalidValue, "Metadata chunk to deserialize is too short. Expected at least %d. Got %d.", minimumMetadataLength, len(serializedData)) + } + + // first two bytes must be set to zero to indicate metadata chunks, so enforce this. + if serializedData[0] != 0 || serializedData[1] != 0 { + return NewError(ErrCorruptData, "Invalid metadata chunk") + } + + cursor := 2 + metadataLength := int(binary.LittleEndian.Uint16(serializedData[cursor : cursor+2])) // metadataLength does not include the 4 prefix bytes + if metadataLength+chunkPrefixLength != len(serializedData) { + return NewErrorf(ErrCorruptData, "Incorrect declared metadata length. Expected %d, got %d.", metadataLength+chunkPrefixLength, len(serializedData)) + } + + cursor += 2 + + if err := r.StartTime.binaryGet(serializedData[cursor : cursor+timestampLength]); err != nil { + return err + } + cursor += timestampLength + + r.Frequency = binary.LittleEndian.Uint64(serializedData[cursor : cursor+frequencyLength]) + cursor += frequencyLength + + nameLength := int(serializedData[cursor]) + if nameLength+minimumMetadataLength > len(serializedData) { + return NewErrorf(ErrInvalidValue, "Metadata chunk to deserialize is too short when decoding resource name. Expected at least %d. Got %d.", nameLength+minimumMetadataLength, len(serializedData)) + } + cursor++ + r.Name = string(serializedData[cursor : cursor+nameLength]) + cursor += nameLength + + copy(r.Owner[:], serializedData[cursor:]) + cursor += common.AddressLength + if cursor != len(serializedData) { + return NewErrorf(ErrInvalidValue, "Metadata chunk has leftover data after deserialization. %d left to read", len(serializedData)-cursor) + } + return nil +} + +// binaryPut encodes the metadata into a byte array +func (r *ResourceMetadata) binaryPut(serializedData []byte) error { + metadataChunkLength := r.binaryLength() + if len(serializedData) != metadataChunkLength { + return NewErrorf(ErrInvalidValue, "Need a slice of exactly %d bytes to serialize this metadata, but got a slice of size %d.", metadataChunkLength, len(serializedData)) + } + + // root chunk has first two bytes both set to 0, which distinguishes from update bytes + // therefore, skip the first two bytes of a zero-initialized array. + cursor := 2 + binary.LittleEndian.PutUint16(serializedData[cursor:cursor+2], uint16(metadataChunkLength-chunkPrefixLength)) // metadataLength does not include the 4 prefix bytes + cursor += 2 + + r.StartTime.binaryPut(serializedData[cursor : cursor+timestampLength]) + cursor += timestampLength + + binary.LittleEndian.PutUint64(serializedData[cursor:cursor+frequencyLength], r.Frequency) + cursor += frequencyLength + + // Encode the name string as a 1 byte length followed by the encoded string. + // Longer strings will be truncated. + nameLength := len(r.Name) + if nameLength > 255 { + nameLength = 255 + } + serializedData[cursor] = uint8(nameLength) + cursor++ + copy(serializedData[cursor:cursor+nameLength], []byte(r.Name[:nameLength])) + cursor += nameLength + + copy(serializedData[cursor:cursor+common.AddressLength], r.Owner[:]) + cursor += common.AddressLength + + return nil +} + +func (r *ResourceMetadata) binaryLength() int { + return minimumMetadataLength + len(r.Name) +} + +// serializeAndHash returns the root chunk addr and metadata hash that help identify and ascertain ownership of this resource +// returns the serialized metadata as a byproduct of having to hash it. +func (r *ResourceMetadata) serializeAndHash() (rootAddr, metaHash []byte, chunkData []byte, err error) { + + chunkData = make([]byte, r.binaryLength()) + if err := r.binaryPut(chunkData); err != nil { + return nil, nil, nil, err + } + rootAddr, metaHash = metadataHash(chunkData) + return rootAddr, metaHash, chunkData, nil + +} + +// creates a metadata chunk out of a resourceMetadata structure +func (metadata *ResourceMetadata) newChunk() (chunk *storage.Chunk, metaHash []byte, err error) { + // the metadata chunk contains a timestamp of when the resource starts to be valid + // and also how frequently it is expected to be updated + // from this we know at what time we should look for updates, and how often + // it also contains the name of the resource, so we know what resource we are working with + + // the key (rootAddr) of the metadata chunk is content-addressed + // if it wasn't we couldn't replace it later + // resolving this relationship is left up to external agents (for example ENS) + rootAddr, metaHash, chunkData, err := metadata.serializeAndHash() + if err != nil { + return nil, nil, err + } + + // make the chunk and send it to swarm + chunk = storage.NewChunk(rootAddr, nil) + chunk.SData = chunkData + chunk.Size = int64(len(chunkData)) + + return chunk, metaHash, nil +} + +// metadataHash returns the metadata chunk root address and metadata hash +// that help identify and ascertain ownership of this resource +// We compute it as rootAddr = H(ownerAddr, H(metadata)) +// Where H() is SHA3 +// metadata are all the metadata fields, except ownerAddr +// ownerAddr is the public address of the resource owner +// Update chunks must carry a rootAddr reference and metaHash in order to be verified +// This way, a node that receives an update can check the signature, recover the public address +// and check the ownership by computing H(ownerAddr, metaHash) and comparing it to the rootAddr +// the resource is claiming to update without having to lookup the metadata chunk. +// see verifyResourceOwnerhsip in signedupdate.go +func metadataHash(chunkData []byte) (rootAddr, metaHash []byte) { + hasher := hashPool.Get().(hash.Hash) + defer hashPool.Put(hasher) + hasher.Reset() + hasher.Write(chunkData[:len(chunkData)-common.AddressLength]) + metaHash = hasher.Sum(nil) + hasher.Reset() + hasher.Write(metaHash) + hasher.Write(chunkData[len(chunkData)-common.AddressLength:]) + rootAddr = hasher.Sum(nil) + return +} diff --git a/swarm/storage/mru/metadata_test.go b/swarm/storage/mru/metadata_test.go new file mode 100644 index 0000000000..abbac6e3e4 --- /dev/null +++ b/swarm/storage/mru/metadata_test.go @@ -0,0 +1,126 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . +package mru + +import ( + "testing" + + "github.com/ethereum/go-ethereum/common/hexutil" +) + +func compareByteSliceToExpectedHex(t *testing.T, variableName string, actualValue []byte, expectedHex string) { + if hexutil.Encode(actualValue) != expectedHex { + t.Fatalf("%s: Expected %s to be %s, got %s", t.Name(), variableName, expectedHex, hexutil.Encode(actualValue)) + } +} + +func getTestMetadata() *ResourceMetadata { + return &ResourceMetadata{ + Name: "world news report, every hour, on the hour", + StartTime: Timestamp{ + Time: 1528880400, + }, + Frequency: 3600, + Owner: newCharlieSigner().Address(), + } +} + +func TestMetadataSerializerDeserializer(t *testing.T) { + metadata := *getTestMetadata() + + rootAddr, metaHash, chunkData, err := metadata.serializeAndHash() // creates hashes and marshals, in one go + if err != nil { + t.Fatal(err) + } + const expectedRootAddr = "0xfb0ed7efa696bdb0b54cd75554cc3117ffc891454317df7dd6fefad978e2f2fb" + const expectedMetaHash = "0xf74a10ce8f26ffc8bfaa07c3031a34b2c61f517955e7deb1592daccf96c69cf0" + const expectedChunkData = "0x00004f0010dd205b00000000100e0000000000002a776f726c64206e657773207265706f72742c20657665727920686f75722c206f6e2074686520686f7572876a8936a7cd0b79ef0735ad0896c1afe278781c" + + compareByteSliceToExpectedHex(t, "rootAddr", rootAddr, expectedRootAddr) + compareByteSliceToExpectedHex(t, "metaHash", metaHash, expectedMetaHash) + compareByteSliceToExpectedHex(t, "chunkData", chunkData, expectedChunkData) + + recoveredMetadata := ResourceMetadata{} + recoveredMetadata.binaryGet(chunkData) + + if recoveredMetadata != metadata { + t.Fatalf("Expected that the recovered metadata equals the marshalled metadata") + } + + // we are going to mess with the data, so create a backup to go back to it for the next test + backup := make([]byte, len(chunkData)) + copy(backup, chunkData) + + chunkData = []byte{1, 2, 3} + if err := recoveredMetadata.binaryGet(chunkData); err == nil { + t.Fatal("Expected binaryGet to fail since chunk is too small") + } + + // restore backup + chunkData = make([]byte, len(backup)) + copy(chunkData, backup) + + // mess with the prefix so it is not zero + chunkData[0] = 7 + chunkData[1] = 9 + + if err := recoveredMetadata.binaryGet(chunkData); err == nil { + t.Fatal("Expected binaryGet to fail since prefix bytes are not zero") + } + + // restore backup + chunkData = make([]byte, len(backup)) + copy(chunkData, backup) + + // mess with the length header to trigger an error + chunkData[2] = 255 + chunkData[3] = 44 + if err := recoveredMetadata.binaryGet(chunkData); err == nil { + t.Fatal("Expected binaryGet to fail since header length does not match") + } + + // restore backup + chunkData = make([]byte, len(backup)) + copy(chunkData, backup) + + // mess with name length header to trigger a chunk too short error + chunkData[20] = 255 + if err := recoveredMetadata.binaryGet(chunkData); err == nil { + t.Fatal("Expected binaryGet to fail since name length is incorrect") + } + + // restore backup + chunkData = make([]byte, len(backup)) + copy(chunkData, backup) + + // mess with name length header to trigger an leftover bytes to read error + chunkData[20] = 3 + if err := recoveredMetadata.binaryGet(chunkData); err == nil { + t.Fatal("Expected binaryGet to fail since name length is too small") + } +} + +func TestMetadataSerializerLengthCheck(t *testing.T) { + metadata := *getTestMetadata() + + // make a slice that is too small to contain the metadata + serializedMetadata := make([]byte, 4) + + if err := metadata.binaryPut(serializedMetadata); err == nil { + t.Fatal("Expected metadata.binaryPut to fail, since target slice is too small") + } + +} diff --git a/swarm/storage/mru/request.go b/swarm/storage/mru/request.go new file mode 100644 index 0000000000..dd71f855d6 --- /dev/null +++ b/swarm/storage/mru/request.go @@ -0,0 +1,297 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package mru + +import ( + "bytes" + "encoding/json" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/swarm/storage" +) + +// updateRequestJSON represents a JSON-serialized UpdateRequest +type updateRequestJSON struct { + Name string `json:"name,omitempty"` + Frequency uint64 `json:"frequency,omitempty"` + StartTime uint64 `json:"startTime,omitempty"` + Owner string `json:"ownerAddr,omitempty"` + RootAddr string `json:"rootAddr,omitempty"` + MetaHash string `json:"metaHash,omitempty"` + Version uint32 `json:"version,omitempty"` + Period uint32 `json:"period,omitempty"` + Data string `json:"data,omitempty"` + Multihash bool `json:"multiHash"` + Signature string `json:"signature,omitempty"` +} + +// Request represents an update and/or resource create message +type Request struct { + SignedResourceUpdate + metadata ResourceMetadata + isNew bool +} + +var zeroAddr = common.Address{} + +// NewCreateUpdateRequest returns a ready to sign request to create and initialize a resource with data +func NewCreateUpdateRequest(metadata *ResourceMetadata) (*Request, error) { + + request, err := NewCreateRequest(metadata) + if err != nil { + return nil, err + } + + // get the current time + now := TimestampProvider.Now().Time + + request.version = 1 + request.period, err = getNextPeriod(metadata.StartTime.Time, now, metadata.Frequency) + if err != nil { + return nil, err + } + return request, nil +} + +// NewCreateRequest returns a request to create a new resource +func NewCreateRequest(metadata *ResourceMetadata) (request *Request, err error) { + if metadata.StartTime.Time == 0 { // get the current time + metadata.StartTime = TimestampProvider.Now() + } + + if metadata.Owner == zeroAddr { + return nil, NewError(ErrInvalidValue, "OwnerAddr is not set") + } + + request = &Request{ + metadata: *metadata, + } + request.rootAddr, request.metaHash, _, err = request.metadata.serializeAndHash() + request.isNew = true + return request, nil +} + +// Frequency returns the resource's expected update frequency +func (r *Request) Frequency() uint64 { + return r.metadata.Frequency +} + +// Name returns the resource human-readable name +func (r *Request) Name() string { + return r.metadata.Name +} + +// Multihash returns true if the resource data should be interpreted as a multihash +func (r *Request) Multihash() bool { + return r.multihash +} + +// Period returns in which period the resource will be published +func (r *Request) Period() uint32 { + return r.period +} + +// Version returns the resource version to publish +func (r *Request) Version() uint32 { + return r.version +} + +// RootAddr returns the metadata chunk address +func (r *Request) RootAddr() storage.Address { + return r.rootAddr +} + +// StartTime returns the time that the resource was/will be created at +func (r *Request) StartTime() Timestamp { + return r.metadata.StartTime +} + +// Owner returns the resource owner's address +func (r *Request) Owner() common.Address { + return r.metadata.Owner +} + +// Sign executes the signature to validate the resource and sets the owner address field +func (r *Request) Sign(signer Signer) error { + if r.metadata.Owner != zeroAddr && r.metadata.Owner != signer.Address() { + return NewError(ErrInvalidSignature, "Signer does not match current owner of the resource") + } + + if err := r.SignedResourceUpdate.Sign(signer); err != nil { + return err + } + r.metadata.Owner = signer.Address() + return nil +} + +// SetData stores the payload data the resource will be updated with +func (r *Request) SetData(data []byte, multihash bool) { + r.data = data + r.multihash = multihash + r.signature = nil + if !r.isNew { + r.metadata.Frequency = 0 // mark as update + } +} + +func (r *Request) IsNew() bool { + return r.metadata.Frequency > 0 && (r.period <= 1 || r.version <= 1) +} + +func (r *Request) IsUpdate() bool { + return r.signature != nil +} + +// fromJSON takes an update request JSON and populates an UpdateRequest +func (r *Request) fromJSON(j *updateRequestJSON) error { + + r.version = j.Version + r.period = j.Period + r.multihash = j.Multihash + r.metadata.Name = j.Name + r.metadata.Frequency = j.Frequency + r.metadata.StartTime.Time = j.StartTime + + if err := decodeHexArray(r.metadata.Owner[:], j.Owner, "ownerAddr"); err != nil { + return err + } + + var err error + if j.Data != "" { + r.data, err = hexutil.Decode(j.Data) + if err != nil { + return NewError(ErrInvalidValue, "Cannot decode data") + } + } + + var declaredRootAddr storage.Address + var declaredMetaHash []byte + + declaredRootAddr, err = decodeHexSlice(j.RootAddr, storage.KeyLength, "rootAddr") + if err != nil { + return err + } + declaredMetaHash, err = decodeHexSlice(j.MetaHash, 32, "metaHash") + if err != nil { + return err + } + + if r.IsNew() { + // for new resource creation, rootAddr and metaHash are optional because + // we can derive them from the content itself. + // however, if the user sent them, we check them for consistency. + + r.rootAddr, r.metaHash, _, err = r.metadata.serializeAndHash() + if err != nil { + return err + } + if j.RootAddr != "" && !bytes.Equal(declaredRootAddr, r.rootAddr) { + return NewError(ErrInvalidValue, "rootAddr does not match resource metadata") + } + if j.MetaHash != "" && !bytes.Equal(declaredMetaHash, r.metaHash) { + return NewError(ErrInvalidValue, "metaHash does not match resource metadata") + } + + } else { + //Update message + r.rootAddr = declaredRootAddr + r.metaHash = declaredMetaHash + } + + if j.Signature != "" { + sigBytes, err := hexutil.Decode(j.Signature) + if err != nil || len(sigBytes) != signatureLength { + return NewError(ErrInvalidSignature, "Cannot decode signature") + } + r.signature = new(Signature) + r.updateAddr = r.UpdateAddr() + copy(r.signature[:], sigBytes) + } + return nil +} + +func decodeHexArray(dst []byte, src, name string) error { + bytes, err := decodeHexSlice(src, len(dst), name) + if err != nil { + return err + } + if bytes != nil { + copy(dst, bytes) + } + return nil +} + +func decodeHexSlice(src string, expectedLength int, name string) (bytes []byte, err error) { + if src != "" { + bytes, err = hexutil.Decode(src) + if err != nil || len(bytes) != expectedLength { + return nil, NewErrorf(ErrInvalidValue, "Cannot decode %s", name) + } + } + return bytes, nil +} + +// UnmarshalJSON takes a JSON structure stored in a byte array and populates the Request object +// Implements json.Unmarshaler interface +func (r *Request) UnmarshalJSON(rawData []byte) error { + var requestJSON updateRequestJSON + if err := json.Unmarshal(rawData, &requestJSON); err != nil { + return err + } + return r.fromJSON(&requestJSON) +} + +// MarshalJSON takes an update request and encodes it as a JSON structure into a byte array +// Implements json.Marshaler interface +func (r *Request) MarshalJSON() (rawData []byte, err error) { + var signatureString, dataHashString, rootAddrString, metaHashString string + if r.signature != nil { + signatureString = hexutil.Encode(r.signature[:]) + } + if r.data != nil { + dataHashString = hexutil.Encode(r.data) + } + if r.rootAddr != nil { + rootAddrString = hexutil.Encode(r.rootAddr) + } + if r.metaHash != nil { + metaHashString = hexutil.Encode(r.metaHash) + } + var ownerAddrString string + if r.metadata.Frequency == 0 { + ownerAddrString = "" + } else { + ownerAddrString = hexutil.Encode(r.metadata.Owner[:]) + } + + requestJSON := &updateRequestJSON{ + Name: r.metadata.Name, + Frequency: r.metadata.Frequency, + StartTime: r.metadata.StartTime.Time, + Version: r.version, + Period: r.period, + Owner: ownerAddrString, + Data: dataHashString, + Multihash: r.multihash, + Signature: signatureString, + RootAddr: rootAddrString, + MetaHash: metaHashString, + } + + return json.Marshal(requestJSON) +} diff --git a/swarm/storage/mru/request_test.go b/swarm/storage/mru/request_test.go new file mode 100644 index 0000000000..dba55b27e3 --- /dev/null +++ b/swarm/storage/mru/request_test.go @@ -0,0 +1,175 @@ +package mru + +import ( + "encoding/binary" + "encoding/json" + "fmt" + "reflect" + "testing" +) + +func areEqualJSON(s1, s2 string) (bool, error) { + //credit for the trick: turtlemonvh https://gist.github.com/turtlemonvh/e4f7404e28387fadb8ad275a99596f67 + var o1 interface{} + var o2 interface{} + + err := json.Unmarshal([]byte(s1), &o1) + if err != nil { + return false, fmt.Errorf("Error mashalling string 1 :: %s", err.Error()) + } + err = json.Unmarshal([]byte(s2), &o2) + if err != nil { + return false, fmt.Errorf("Error mashalling string 2 :: %s", err.Error()) + } + + return reflect.DeepEqual(o1, o2), nil +} + +// TestEncodingDecodingUpdateRequests ensures that requests are serialized properly +// while also checking cryptographically that only the owner of a resource can update it. +func TestEncodingDecodingUpdateRequests(t *testing.T) { + + signer := newCharlieSigner() //Charlie, our good guy + falseSigner := newBobSigner() //Bob will play the bad guy again + + // Create a resource to our good guy Charlie's name + createRequest, err := NewCreateRequest(&ResourceMetadata{ + Name: "a good resource name", + Frequency: 300, + StartTime: Timestamp{Time: 1528900000}, + Owner: signer.Address()}) + + if err != nil { + t.Fatalf("Error creating resource name: %s", err) + } + + // We now encode the create message to simulate we send it over the wire + messageRawData, err := createRequest.MarshalJSON() + if err != nil { + t.Fatalf("Error encoding create resource request: %s", err) + } + + // ... the message arrives and is decoded... + var recoveredCreateRequest Request + if err := recoveredCreateRequest.UnmarshalJSON(messageRawData); err != nil { + t.Fatalf("Error decoding create resource request: %s", err) + } + + // ... but verification should fail because it is not signed! + if err := recoveredCreateRequest.Verify(); err == nil { + t.Fatal("Expected Verify to fail since the message is not signed") + } + + // We now assume that the resource was created and propagated. With rootAddr we can retrieve the resource metadata + // and recover the information above. To sign an update, we need the rootAddr and the metaHash to construct + // proof of ownership + + metaHash := createRequest.metaHash + rootAddr := createRequest.rootAddr + const expectedSignature = "0x1c2bab66dc4ed63783d62934e3a628e517888d6949aef0349f3bd677121db9aa09bbfb865904e6c50360e209e0fe6fe757f8a2474cf1b34169c99b95e3fd5a5101" + const expectedJSON = `{"rootAddr":"0x6e744a730f7ea0881528576f0354b6268b98e35a6981ef703153ff1b8d32bbef","metaHash":"0x0c0d5c18b89da503af92302a1a64fab6acb60f78e288eb9c3d541655cd359b60","version":1,"period":7,"data":"0x5468697320686f75722773207570646174653a20537761726d2039392e3020686173206265656e2072656c656173656421","multiHash":false}` + + //Put together an unsigned update request that we will serialize to send it to the signer. + data := []byte("This hour's update: Swarm 99.0 has been released!") + request := &Request{ + SignedResourceUpdate: SignedResourceUpdate{ + resourceUpdate: resourceUpdate{ + updateHeader: updateHeader{ + UpdateLookup: UpdateLookup{ + period: 7, + version: 1, + rootAddr: rootAddr, + }, + multihash: false, + metaHash: metaHash, + }, + data: data, + }, + }, + } + + messageRawData, err = request.MarshalJSON() + if err != nil { + t.Fatalf("Error encoding update request: %s", err) + } + + equalJSON, err := areEqualJSON(string(messageRawData), expectedJSON) + if err != nil { + t.Fatalf("Error decoding update request JSON: %s", err) + } + if !equalJSON { + t.Fatalf("Received a different JSON message. Expected %s, got %s", expectedJSON, string(messageRawData)) + } + + // now the encoded message messageRawData is sent over the wire and arrives to the signer + + //Attempt to extract an UpdateRequest out of the encoded message + var recoveredRequest Request + if err := recoveredRequest.UnmarshalJSON(messageRawData); err != nil { + t.Fatalf("Error decoding update request: %s", err) + } + + //sign the request and see if it matches our predefined signature above. + if err := recoveredRequest.Sign(signer); err != nil { + t.Fatalf("Error signing request: %s", err) + } + + compareByteSliceToExpectedHex(t, "signature", recoveredRequest.signature[:], expectedSignature) + + // mess with the signature and see what happens. To alter the signature, we briefly decode it as JSON + // to alter the signature field. + var j updateRequestJSON + if err := json.Unmarshal([]byte(expectedJSON), &j); err != nil { + t.Fatal("Error unmarshalling test json, check expectedJSON constant") + } + j.Signature = "Certainly not a signature" + corruptMessage, _ := json.Marshal(j) // encode the message with the bad signature + var corruptRequest Request + if err = corruptRequest.UnmarshalJSON(corruptMessage); err == nil { + t.Fatal("Expected DecodeUpdateRequest to fail when trying to interpret a corrupt message with an invalid signature") + } + + // Now imagine Evil Bob (why always Bob, poor Bob) attempts to update Charlie's resource, + // signing a message with his private key + if err := request.Sign(falseSigner); err != nil { + t.Fatalf("Error signing: %s", err) + } + + // Now Bob encodes the message to send it over the wire... + messageRawData, err = request.MarshalJSON() + if err != nil { + t.Fatalf("Error encoding message:%s", err) + } + + // ... the message arrives to our Swarm node and it is decoded. + recoveredRequest = Request{} + if err := recoveredRequest.UnmarshalJSON(messageRawData); err != nil { + t.Fatalf("Error decoding message:%s", err) + } + + // Before discovering Bob's misdemeanor, let's see what would happen if we mess + // with the signature big time to see if Verify catches it + savedSignature := *recoveredRequest.signature // save the signature for later + binary.LittleEndian.PutUint64(recoveredRequest.signature[5:], 556845463424) // write some random data to break the signature + if err = recoveredRequest.Verify(); err == nil { + t.Fatal("Expected Verify to fail on corrupt signature") + } + + // restore the Evil Bob's signature from corruption + *recoveredRequest.signature = savedSignature + + // Now the signature is not corrupt, however Verify should now fail because Bob doesn't own the resource + if err = recoveredRequest.Verify(); err == nil { + t.Fatalf("Expected Verify to fail because this resource belongs to Charlie, not Bob the attacker:%s", err) + } + + // Sign with our friend Charlie's private key + if err := recoveredRequest.Sign(signer); err != nil { + t.Fatalf("Error signing with the correct private key: %s", err) + } + + // And now, Verify should work since this resource belongs to Charlie + if err = recoveredRequest.Verify(); err != nil { + t.Fatalf("Error verifying that Charlie, the good guy, can sign his resource:%s", err) + } +} diff --git a/swarm/storage/mru/resource.go b/swarm/storage/mru/resource.go new file mode 100644 index 0000000000..aa83ff62a9 --- /dev/null +++ b/swarm/storage/mru/resource.go @@ -0,0 +1,76 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package mru + +import ( + "bytes" + "context" + "time" + + "github.com/ethereum/go-ethereum/swarm/storage" +) + +const ( + defaultStoreTimeout = 4000 * time.Millisecond + hasherCount = 8 + resourceHashAlgorithm = storage.SHA3Hash + defaultRetrieveTimeout = 100 * time.Millisecond +) + +// resource caches resource data and the metadata of its root chunk. +type resource struct { + resourceUpdate + ResourceMetadata + *bytes.Reader + lastKey storage.Address + updated time.Time +} + +func (r *resource) Context() context.Context { + return context.TODO() +} + +// TODO Expire content after a defined period (to force resync) +func (r *resource) isSynced() bool { + return !r.updated.IsZero() +} + +// implements storage.LazySectionReader +func (r *resource) Size(ctx context.Context, _ chan bool) (int64, error) { + if !r.isSynced() { + return 0, NewError(ErrNotSynced, "Not synced") + } + return int64(len(r.resourceUpdate.data)), nil +} + +//returns the resource's human-readable name +func (r *resource) Name() string { + return r.ResourceMetadata.Name +} + +// Helper function to calculate the next update period number from the current time, start time and frequency +func getNextPeriod(start uint64, current uint64, frequency uint64) (uint32, error) { + if current < start { + return 0, NewErrorf(ErrInvalidValue, "given current time value %d < start time %d", current, start) + } + if frequency == 0 { + return 0, NewError(ErrInvalidValue, "frequency is 0") + } + timeDiff := current - start + period := timeDiff / frequency + return uint32(period + 1), nil +} diff --git a/swarm/storage/mru/resource_sign.go b/swarm/storage/mru/resource_sign.go new file mode 100644 index 0000000000..a9f7cb6296 --- /dev/null +++ b/swarm/storage/mru/resource_sign.go @@ -0,0 +1,66 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package mru + +import ( + "crypto/ecdsa" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" +) + +const signatureLength = 65 + +// Signature is an alias for a static byte array with the size of a signature +type Signature [signatureLength]byte + +// Signer signs Mutable Resource update payloads +type Signer interface { + Sign(common.Hash) (Signature, error) + Address() common.Address +} + +// GenericSigner implements the Signer interface +// It is the vanilla signer that probably should be used in most cases +type GenericSigner struct { + PrivKey *ecdsa.PrivateKey + address common.Address +} + +// NewGenericSigner builds a signer that will sign everything with the provided private key +func NewGenericSigner(privKey *ecdsa.PrivateKey) *GenericSigner { + return &GenericSigner{ + PrivKey: privKey, + address: crypto.PubkeyToAddress(privKey.PublicKey), + } +} + +// Sign signs the supplied data +// It wraps the ethereum crypto.Sign() method +func (s *GenericSigner) Sign(data common.Hash) (signature Signature, err error) { + signaturebytes, err := crypto.Sign(data.Bytes(), s.PrivKey) + if err != nil { + return + } + copy(signature[:], signaturebytes) + return +} + +// PublicKey returns the public key of the signer's private key +func (s *GenericSigner) Address() common.Address { + return s.address +} diff --git a/swarm/storage/mru/resource_test.go b/swarm/storage/mru/resource_test.go new file mode 100644 index 0000000000..95c9eccdfc --- /dev/null +++ b/swarm/storage/mru/resource_test.go @@ -0,0 +1,906 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package mru + +import ( + "bytes" + "context" + "crypto/rand" + "encoding/binary" + "flag" + "io/ioutil" + "os" + "testing" + "time" + + "github.com/ethereum/go-ethereum/contracts/ens" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/swarm/multihash" + "github.com/ethereum/go-ethereum/swarm/storage" +) + +var ( + loglevel = flag.Int("loglevel", 3, "loglevel") + testHasher = storage.MakeHashFunc(resourceHashAlgorithm)() + startTime = Timestamp{ + Time: uint64(4200), + } + resourceFrequency = uint64(42) + cleanF func() + resourceName = "føø.bar" + hashfunc = storage.MakeHashFunc(storage.DefaultHash) +) + +func init() { + flag.Parse() + log.Root().SetHandler(log.CallerFileHandler(log.LvlFilterHandler(log.Lvl(*loglevel), log.StreamHandler(os.Stderr, log.TerminalFormat(true))))) +} + +// simulated timeProvider +type fakeTimeProvider struct { + currentTime uint64 +} + +func (f *fakeTimeProvider) Tick() { + f.currentTime++ +} + +func (f *fakeTimeProvider) Now() Timestamp { + return Timestamp{ + Time: f.currentTime, + } +} + +func TestUpdateChunkSerializationErrorChecking(t *testing.T) { + + // Test that parseUpdate fails if the chunk is too small + var r SignedResourceUpdate + if err := r.fromChunk(storage.ZeroAddr, make([]byte, minimumUpdateDataLength-1)); err == nil { + t.Fatalf("Expected parseUpdate to fail when chunkData contains less than %d bytes", minimumUpdateDataLength) + } + + r = SignedResourceUpdate{} + // Test that parseUpdate fails when the length header does not match the data array length + fakeChunk := make([]byte, 150) + binary.LittleEndian.PutUint16(fakeChunk, 44) + if err := r.fromChunk(storage.ZeroAddr, fakeChunk); err == nil { + t.Fatal("Expected parseUpdate to fail when the header length does not match the actual data array passed in") + } + + r = SignedResourceUpdate{ + resourceUpdate: resourceUpdate{ + updateHeader: updateHeader{ + UpdateLookup: UpdateLookup{ + + rootAddr: make([]byte, 79), // put the wrong length, should be storage.KeyLength + }, + metaHash: nil, + multihash: false, + }, + }, + } + _, err := r.toChunk() + if err == nil { + t.Fatal("Expected newUpdateChunk to fail when rootAddr or metaHash have the wrong length") + } + r.rootAddr = make([]byte, storage.KeyLength) + r.metaHash = make([]byte, storage.KeyLength) + _, err = r.toChunk() + if err == nil { + t.Fatal("Expected newUpdateChunk to fail when there is no data") + } + r.data = make([]byte, 79) // put some arbitrary length data + _, err = r.toChunk() + if err == nil { + t.Fatal("expected newUpdateChunk to fail when there is no signature", err) + } + + alice := newAliceSigner() + if err := r.Sign(alice); err != nil { + t.Fatalf("error signing:%s", err) + + } + _, err = r.toChunk() + if err != nil { + t.Fatalf("error creating update chunk:%s", err) + } + + r.multihash = true + r.data[1] = 79 // mess with the multihash, corrupting one byte of it. + if err := r.Sign(alice); err == nil { + t.Fatal("expected Sign() to fail when an invalid multihash is in data and multihash=true", err) + } +} + +// check that signature address matches update signer address +func TestReverse(t *testing.T) { + + period := uint32(4) + version := uint32(2) + + // make fake timeProvider + timeProvider := &fakeTimeProvider{ + currentTime: startTime.Time, + } + + // signer containing private key + signer := newAliceSigner() + + // set up rpc and create resourcehandler + _, _, teardownTest, err := setupTest(timeProvider, signer) + if err != nil { + t.Fatal(err) + } + defer teardownTest() + + metadata := ResourceMetadata{ + Name: resourceName, + StartTime: startTime, + Frequency: resourceFrequency, + Owner: signer.Address(), + } + + rootAddr, metaHash, _, err := metadata.serializeAndHash() + if err != nil { + t.Fatal(err) + } + + // generate some bogus data for the chunk and sign it + data := make([]byte, 8) + _, err = rand.Read(data) + if err != nil { + t.Fatal(err) + } + testHasher.Reset() + testHasher.Write(data) + + update := &SignedResourceUpdate{ + resourceUpdate: resourceUpdate{ + updateHeader: updateHeader{ + UpdateLookup: UpdateLookup{ + period: period, + version: version, + rootAddr: rootAddr, + }, + metaHash: metaHash, + }, + data: data, + }, + } + // generate a hash for t=4200 version 1 + key := update.UpdateAddr() + + if err = update.Sign(signer); err != nil { + t.Fatal(err) + } + + chunk, err := update.toChunk() + if err != nil { + t.Fatal(err) + } + + // check that we can recover the owner account from the update chunk's signature + var checkUpdate SignedResourceUpdate + if err := checkUpdate.fromChunk(chunk.Addr, chunk.SData); err != nil { + t.Fatal(err) + } + checkdigest, err := checkUpdate.GetDigest() + if err != nil { + t.Fatal(err) + } + recoveredaddress, err := getOwner(checkdigest, *checkUpdate.signature) + if err != nil { + t.Fatalf("Retrieve address from signature fail: %v", err) + } + originaladdress := crypto.PubkeyToAddress(signer.PrivKey.PublicKey) + + // check that the metadata retrieved from the chunk matches what we gave it + if recoveredaddress != originaladdress { + t.Fatalf("addresses dont match: %x != %x", originaladdress, recoveredaddress) + } + + if !bytes.Equal(key[:], chunk.Addr[:]) { + t.Fatalf("Expected chunk key '%x', was '%x'", key, chunk.Addr) + } + if period != checkUpdate.period { + t.Fatalf("Expected period '%d', was '%d'", period, checkUpdate.period) + } + if version != checkUpdate.version { + t.Fatalf("Expected version '%d', was '%d'", version, checkUpdate.version) + } + if !bytes.Equal(data, checkUpdate.data) { + t.Fatalf("Expectedn data '%x', was '%x'", data, checkUpdate.data) + } +} + +// make updates and retrieve them based on periods and versions +func TestResourceHandler(t *testing.T) { + + // make fake timeProvider + timeProvider := &fakeTimeProvider{ + currentTime: startTime.Time, + } + + // signer containing private key + signer := newAliceSigner() + + rh, datadir, teardownTest, err := setupTest(timeProvider, signer) + if err != nil { + t.Fatal(err) + } + defer teardownTest() + + // create a new resource + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + metadata := &ResourceMetadata{ + Name: resourceName, + Frequency: resourceFrequency, + StartTime: Timestamp{Time: timeProvider.Now().Time}, + Owner: signer.Address(), + } + + request, err := NewCreateUpdateRequest(metadata) + if err != nil { + t.Fatal(err) + } + request.Sign(signer) + if err != nil { + t.Fatal(err) + } + err = rh.New(ctx, request) + if err != nil { + t.Fatal(err) + } + + chunk, err := rh.chunkStore.Get(context.TODO(), storage.Address(request.rootAddr)) + if err != nil { + t.Fatal(err) + } else if len(chunk.SData) < 16 { + t.Fatalf("chunk data must be minimum 16 bytes, is %d", len(chunk.SData)) + } + + var recoveredMetadata ResourceMetadata + + recoveredMetadata.binaryGet(chunk.SData) + if err != nil { + t.Fatal(err) + } + if recoveredMetadata.StartTime.Time != timeProvider.currentTime { + t.Fatalf("stored startTime %d does not match provided startTime %d", recoveredMetadata.StartTime.Time, timeProvider.currentTime) + } + if recoveredMetadata.Frequency != resourceFrequency { + t.Fatalf("stored frequency %d does not match provided frequency %d", recoveredMetadata.Frequency, resourceFrequency) + } + + // data for updates: + updates := []string{ + "blinky", + "pinky", + "inky", + "clyde", + } + + // update halfway to first period. period=1, version=1 + resourcekey := make(map[string]storage.Address) + fwdClock(int(resourceFrequency/2), timeProvider) + data := []byte(updates[0]) + request.SetData(data, false) + if err := request.Sign(signer); err != nil { + t.Fatal(err) + } + resourcekey[updates[0]], err = rh.Update(ctx, &request.SignedResourceUpdate) + if err != nil { + t.Fatal(err) + } + + // update on first period with version = 1 to make it fail since there is already one update with version=1 + request, err = rh.NewUpdateRequest(ctx, request.rootAddr) + if err != nil { + t.Fatal(err) + } + if request.version != 2 || request.period != 1 { + t.Fatal("Suggested period should be 1 and version should be 2") + } + + request.version = 1 // force version 1 instead of 2 to make it fail + data = []byte(updates[1]) + request.SetData(data, false) + if err := request.Sign(signer); err != nil { + t.Fatal(err) + } + resourcekey[updates[1]], err = rh.Update(ctx, &request.SignedResourceUpdate) + if err == nil { + t.Fatal("Expected update to fail since this version already exists") + } + + // update on second period with version = 1, correct. period=2, version=1 + fwdClock(int(resourceFrequency/2), timeProvider) + request, err = rh.NewUpdateRequest(ctx, request.rootAddr) + if err != nil { + t.Fatal(err) + } + request.SetData(data, false) + if err := request.Sign(signer); err != nil { + t.Fatal(err) + } + resourcekey[updates[1]], err = rh.Update(ctx, &request.SignedResourceUpdate) + if err != nil { + t.Fatal(err) + } + + fwdClock(int(resourceFrequency), timeProvider) + // Update on third period, with version = 1 + request, err = rh.NewUpdateRequest(ctx, request.rootAddr) + if err != nil { + t.Fatal(err) + } + data = []byte(updates[2]) + request.SetData(data, false) + if err := request.Sign(signer); err != nil { + t.Fatal(err) + } + resourcekey[updates[2]], err = rh.Update(ctx, &request.SignedResourceUpdate) + if err != nil { + t.Fatal(err) + } + + // update just after third period + fwdClock(1, timeProvider) + request, err = rh.NewUpdateRequest(ctx, request.rootAddr) + if err != nil { + t.Fatal(err) + } + if request.period != 3 || request.version != 2 { + t.Fatal("Suggested period should be 3 and version should be 2") + } + data = []byte(updates[3]) + request.SetData(data, false) + + if err := request.Sign(signer); err != nil { + t.Fatal(err) + } + resourcekey[updates[3]], err = rh.Update(ctx, &request.SignedResourceUpdate) + if err != nil { + t.Fatal(err) + } + + time.Sleep(time.Second) + rh.Close() + + // check we can retrieve the updates after close + // it will match on second iteration startTime + (resourceFrequency * 3) + fwdClock(int(resourceFrequency*2)-1, timeProvider) + + rhparams := &HandlerParams{} + + rh2, err := NewTestHandler(datadir, rhparams) + if err != nil { + t.Fatal(err) + } + + rsrc2, err := rh2.Load(context.TODO(), request.rootAddr) + if err != nil { + t.Fatal(err) + } + + _, err = rh2.Lookup(ctx, LookupLatest(request.rootAddr)) + if err != nil { + t.Fatal(err) + } + + // last update should be "clyde", version two, time= startTime + (resourcefrequency * 3) + if !bytes.Equal(rsrc2.data, []byte(updates[len(updates)-1])) { + t.Fatalf("resource data was %v, expected %v", string(rsrc2.data), updates[len(updates)-1]) + } + if rsrc2.version != 2 { + t.Fatalf("resource version was %d, expected 2", rsrc2.version) + } + if rsrc2.period != 3 { + t.Fatalf("resource period was %d, expected 3", rsrc2.period) + } + log.Debug("Latest lookup", "period", rsrc2.period, "version", rsrc2.version, "data", rsrc2.data) + + // specific period, latest version + rsrc, err := rh2.Lookup(ctx, LookupLatestVersionInPeriod(request.rootAddr, 3)) + if err != nil { + t.Fatal(err) + } + // check data + if !bytes.Equal(rsrc.data, []byte(updates[len(updates)-1])) { + t.Fatalf("resource data (historical) was %v, expected %v", string(rsrc2.data), updates[len(updates)-1]) + } + log.Debug("Historical lookup", "period", rsrc2.period, "version", rsrc2.version, "data", rsrc2.data) + + // specific period, specific version + lookupParams := LookupVersion(request.rootAddr, 3, 1) + rsrc, err = rh2.Lookup(ctx, lookupParams) + if err != nil { + t.Fatal(err) + } + // check data + if !bytes.Equal(rsrc.data, []byte(updates[2])) { + t.Fatalf("resource data (historical) was %v, expected %v", string(rsrc2.data), updates[2]) + } + log.Debug("Specific version lookup", "period", rsrc2.period, "version", rsrc2.version, "data", rsrc2.data) + + // we are now at third update + // check backwards stepping to the first + for i := 1; i >= 0; i-- { + rsrc, err := rh2.LookupPrevious(ctx, lookupParams) + if err != nil { + t.Fatal(err) + } + if !bytes.Equal(rsrc.data, []byte(updates[i])) { + t.Fatalf("resource data (previous) was %v, expected %v", rsrc.data, updates[i]) + + } + } + + // beyond the first should yield an error + rsrc, err = rh2.LookupPrevious(ctx, lookupParams) + if err == nil { + t.Fatalf("expected previous to fail, returned period %d version %d data %v", rsrc.period, rsrc.version, rsrc.data) + } + +} + +func TestMultihash(t *testing.T) { + + // make fake timeProvider + timeProvider := &fakeTimeProvider{ + currentTime: startTime.Time, + } + + // signer containing private key + signer := newAliceSigner() + + // set up rpc and create resourcehandler + rh, datadir, teardownTest, err := setupTest(timeProvider, signer) + if err != nil { + t.Fatal(err) + } + defer teardownTest() + + // create a new resource + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + metadata := &ResourceMetadata{ + Name: resourceName, + Frequency: resourceFrequency, + StartTime: Timestamp{Time: timeProvider.Now().Time}, + Owner: signer.Address(), + } + + mr, err := NewCreateRequest(metadata) + if err != nil { + t.Fatal(err) + } + err = rh.New(ctx, mr) + if err != nil { + t.Fatal(err) + } + + // we're naïvely assuming keccak256 for swarm hashes + // if it ever changes this test should also change + multihashbytes := ens.EnsNode("foo") + multihashmulti := multihash.ToMultihash(multihashbytes.Bytes()) + if err != nil { + t.Fatal(err) + } + mr.SetData(multihashmulti, true) + mr.Sign(signer) + if err != nil { + t.Fatal(err) + } + multihashkey, err := rh.Update(ctx, &mr.SignedResourceUpdate) + if err != nil { + t.Fatal(err) + } + + sha1bytes := make([]byte, multihash.MultihashLength) + sha1multi := multihash.ToMultihash(sha1bytes) + if err != nil { + t.Fatal(err) + } + mr, err = rh.NewUpdateRequest(ctx, mr.rootAddr) + if err != nil { + t.Fatal(err) + } + mr.SetData(sha1multi, true) + mr.Sign(signer) + if err != nil { + t.Fatal(err) + } + sha1key, err := rh.Update(ctx, &mr.SignedResourceUpdate) + if err != nil { + t.Fatal(err) + } + + // invalid multihashes + mr, err = rh.NewUpdateRequest(ctx, mr.rootAddr) + if err != nil { + t.Fatal(err) + } + mr.SetData(multihashmulti[1:], true) + mr.Sign(signer) + if err != nil { + t.Fatal(err) + } + _, err = rh.Update(ctx, &mr.SignedResourceUpdate) + if err == nil { + t.Fatalf("Expected update to fail with first byte skipped") + } + mr, err = rh.NewUpdateRequest(ctx, mr.rootAddr) + if err != nil { + t.Fatal(err) + } + mr.SetData(multihashmulti[:len(multihashmulti)-2], true) + mr.Sign(signer) + if err != nil { + t.Fatal(err) + } + + _, err = rh.Update(ctx, &mr.SignedResourceUpdate) + if err == nil { + t.Fatalf("Expected update to fail with last byte skipped") + } + + data, err := getUpdateDirect(rh.Handler, multihashkey) + if err != nil { + t.Fatal(err) + } + multihashdecode, err := multihash.FromMultihash(data) + if err != nil { + t.Fatal(err) + } + if !bytes.Equal(multihashdecode, multihashbytes.Bytes()) { + t.Fatalf("Decoded hash '%x' does not match original hash '%x'", multihashdecode, multihashbytes.Bytes()) + } + data, err = getUpdateDirect(rh.Handler, sha1key) + if err != nil { + t.Fatal(err) + } + shadecode, err := multihash.FromMultihash(data) + if err != nil { + t.Fatal(err) + } + if !bytes.Equal(shadecode, sha1bytes) { + t.Fatalf("Decoded hash '%x' does not match original hash '%x'", shadecode, sha1bytes) + } + rh.Close() + + rhparams := &HandlerParams{} + // test with signed data + rh2, err := NewTestHandler(datadir, rhparams) + if err != nil { + t.Fatal(err) + } + mr, err = NewCreateRequest(metadata) + if err != nil { + t.Fatal(err) + } + err = rh2.New(ctx, mr) + if err != nil { + t.Fatal(err) + } + + mr.SetData(multihashmulti, true) + mr.Sign(signer) + + if err != nil { + t.Fatal(err) + } + multihashsignedkey, err := rh2.Update(ctx, &mr.SignedResourceUpdate) + if err != nil { + t.Fatal(err) + } + + mr, err = rh2.NewUpdateRequest(ctx, mr.rootAddr) + if err != nil { + t.Fatal(err) + } + mr.SetData(sha1multi, true) + mr.Sign(signer) + if err != nil { + t.Fatal(err) + } + + sha1signedkey, err := rh2.Update(ctx, &mr.SignedResourceUpdate) + if err != nil { + t.Fatal(err) + } + + data, err = getUpdateDirect(rh2.Handler, multihashsignedkey) + if err != nil { + t.Fatal(err) + } + multihashdecode, err = multihash.FromMultihash(data) + if err != nil { + t.Fatal(err) + } + if !bytes.Equal(multihashdecode, multihashbytes.Bytes()) { + t.Fatalf("Decoded hash '%x' does not match original hash '%x'", multihashdecode, multihashbytes.Bytes()) + } + data, err = getUpdateDirect(rh2.Handler, sha1signedkey) + if err != nil { + t.Fatal(err) + } + shadecode, err = multihash.FromMultihash(data) + if err != nil { + t.Fatal(err) + } + if !bytes.Equal(shadecode, sha1bytes) { + t.Fatalf("Decoded hash '%x' does not match original hash '%x'", shadecode, sha1bytes) + } +} + +// \TODO verify testing of signature validation and enforcement +func TestValidator(t *testing.T) { + + // make fake timeProvider + timeProvider := &fakeTimeProvider{ + currentTime: startTime.Time, + } + + // signer containing private key. Alice will be the good girl + signer := newAliceSigner() + + // fake signer for false results. Bob will play the bad guy today. + falseSigner := newBobSigner() + + // set up sim timeProvider + rh, _, teardownTest, err := setupTest(timeProvider, signer) + if err != nil { + t.Fatal(err) + } + defer teardownTest() + + // create new resource + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + metadata := &ResourceMetadata{ + Name: resourceName, + Frequency: resourceFrequency, + StartTime: Timestamp{Time: timeProvider.Now().Time}, + Owner: signer.Address(), + } + mr, err := NewCreateRequest(metadata) + if err != nil { + t.Fatal(err) + } + mr.Sign(signer) + + err = rh.New(ctx, mr) + if err != nil { + t.Fatalf("Create resource fail: %v", err) + } + + // chunk with address + data := []byte("foo") + mr.SetData(data, false) + if err := mr.Sign(signer); err != nil { + t.Fatalf("sign fail: %v", err) + } + chunk, err := mr.SignedResourceUpdate.toChunk() + if err != nil { + t.Fatal(err) + } + if !rh.Validate(chunk.Addr, chunk.SData) { + t.Fatal("Chunk validator fail on update chunk") + } + + // chunk with address made from different publickey + if err := mr.Sign(falseSigner); err == nil { + t.Fatalf("Expected Sign to fail since we are using a different OwnerAddr: %v", err) + } + + // chunk with address made from different publickey + mr.metadata.Owner = zeroAddr // set to zero to bypass .Sign() check + if err := mr.Sign(falseSigner); err != nil { + t.Fatalf("sign fail: %v", err) + } + + chunk, err = mr.SignedResourceUpdate.toChunk() + if err != nil { + t.Fatal(err) + } + + if rh.Validate(chunk.Addr, chunk.SData) { + t.Fatal("Chunk validator did not fail on update chunk with false address") + } + + ctx, cancel = context.WithTimeout(context.Background(), time.Second) + defer cancel() + + metadata = &ResourceMetadata{ + Name: resourceName, + StartTime: TimestampProvider.Now(), + Frequency: resourceFrequency, + Owner: signer.Address(), + } + chunk, _, err = metadata.newChunk() + if err != nil { + t.Fatal(err) + } + + if !rh.Validate(chunk.Addr, chunk.SData) { + t.Fatal("Chunk validator fail on metadata chunk") + } +} + +// tests that the content address validator correctly checks the data +// tests that resource update chunks are passed through content address validator +// there is some redundancy in this test as it also tests content addressed chunks, +// which should be evaluated as invalid chunks by this validator +func TestValidatorInStore(t *testing.T) { + + // make fake timeProvider + TimestampProvider = &fakeTimeProvider{ + currentTime: startTime.Time, + } + + // signer containing private key + signer := newAliceSigner() + + // set up localstore + datadir, err := ioutil.TempDir("", "storage-testresourcevalidator") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(datadir) + + params := storage.NewDefaultLocalStoreParams() + params.Init(datadir) + store, err := storage.NewLocalStore(params, nil) + if err != nil { + t.Fatal(err) + } + + // set up resource handler and add is as a validator to the localstore + rhParams := &HandlerParams{} + rh, err := NewHandler(rhParams) + if err != nil { + t.Fatal(err) + } + store.Validators = append(store.Validators, rh) + + // create content addressed chunks, one good, one faulty + chunks := storage.GenerateRandomChunks(storage.DefaultChunkSize, 2) + goodChunk := chunks[0] + badChunk := chunks[1] + badChunk.SData = goodChunk.SData + + metadata := &ResourceMetadata{ + StartTime: startTime, + Name: "xyzzy", + Frequency: resourceFrequency, + Owner: signer.Address(), + } + + rootChunk, metaHash, err := metadata.newChunk() + if err != nil { + t.Fatal(err) + } + // create a resource update chunk with correct publickey + updateLookup := UpdateLookup{ + period: 42, + version: 1, + rootAddr: rootChunk.Addr, + } + + updateAddr := updateLookup.UpdateAddr() + data := []byte("bar") + + r := SignedResourceUpdate{ + updateAddr: updateAddr, + resourceUpdate: resourceUpdate{ + updateHeader: updateHeader{ + UpdateLookup: updateLookup, + metaHash: metaHash, + }, + data: data, + }, + } + + r.Sign(signer) + + uglyChunk, err := r.toChunk() + if err != nil { + t.Fatal(err) + } + + // put the chunks in the store and check their error status + storage.PutChunks(store, goodChunk) + if goodChunk.GetErrored() == nil { + t.Fatal("expected error on good content address chunk with resource validator only, but got nil") + } + storage.PutChunks(store, badChunk) + if badChunk.GetErrored() == nil { + t.Fatal("expected error on bad content address chunk with resource validator only, but got nil") + } + storage.PutChunks(store, uglyChunk) + if err := uglyChunk.GetErrored(); err != nil { + t.Fatalf("expected no error on resource update chunk with resource validator only, but got: %s", err) + } +} + +// fast-forward clock +func fwdClock(count int, timeProvider *fakeTimeProvider) { + for i := 0; i < count; i++ { + timeProvider.Tick() + } +} + +// create rpc and resourcehandler +func setupTest(timeProvider timestampProvider, signer Signer) (rh *TestHandler, datadir string, teardown func(), err error) { + + var fsClean func() + var rpcClean func() + cleanF = func() { + if fsClean != nil { + fsClean() + } + if rpcClean != nil { + rpcClean() + } + } + + // temp datadir + datadir, err = ioutil.TempDir("", "rh") + if err != nil { + return nil, "", nil, err + } + fsClean = func() { + os.RemoveAll(datadir) + } + + TimestampProvider = timeProvider + rhparams := &HandlerParams{} + rh, err = NewTestHandler(datadir, rhparams) + return rh, datadir, cleanF, err +} + +func newAliceSigner() *GenericSigner { + privKey, _ := crypto.HexToECDSA("deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef") + return NewGenericSigner(privKey) +} + +func newBobSigner() *GenericSigner { + privKey, _ := crypto.HexToECDSA("accedeaccedeaccedeaccedeaccedeaccedeaccedeaccedeaccedeaccedecaca") + return NewGenericSigner(privKey) +} + +func newCharlieSigner() *GenericSigner { + privKey, _ := crypto.HexToECDSA("facadefacadefacadefacadefacadefacadefacadefacadefacadefacadefaca") + return NewGenericSigner(privKey) +} + +func getUpdateDirect(rh *Handler, addr storage.Address) ([]byte, error) { + chunk, err := rh.chunkStore.Get(context.TODO(), addr) + if err != nil { + return nil, err + } + var r SignedResourceUpdate + if err := r.fromChunk(addr, chunk.SData); err != nil { + return nil, err + } + return r.data, nil +} diff --git a/swarm/storage/mru/signedupdate.go b/swarm/storage/mru/signedupdate.go new file mode 100644 index 0000000000..1c6d02e82a --- /dev/null +++ b/swarm/storage/mru/signedupdate.go @@ -0,0 +1,184 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package mru + +import ( + "bytes" + "hash" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/swarm/storage" +) + +// SignedResourceUpdate represents a resource update with all the necessary information to prove ownership of the resource +type SignedResourceUpdate struct { + resourceUpdate // actual content that will be put on the chunk, less signature + signature *Signature + updateAddr storage.Address // resulting chunk address for the update (not serialized, for internal use) + binaryData []byte // resulting serialized data (not serialized, for efficiency/internal use) +} + +// Verify checks that signatures are valid and that the signer owns the resource to be updated +func (r *SignedResourceUpdate) Verify() (err error) { + if len(r.data) == 0 { + return NewError(ErrInvalidValue, "Update does not contain data") + } + if r.signature == nil { + return NewError(ErrInvalidSignature, "Missing signature field") + } + + digest, err := r.GetDigest() + if err != nil { + return err + } + + // get the address of the signer (which also checks that it's a valid signature) + ownerAddr, err := getOwner(digest, *r.signature) + if err != nil { + return err + } + + if !bytes.Equal(r.updateAddr, r.UpdateAddr()) { + return NewError(ErrInvalidSignature, "Signature address does not match with ownerAddr") + } + + // Check if who signed the resource update really owns the resource + if !verifyOwner(ownerAddr, r.metaHash, r.rootAddr) { + return NewErrorf(ErrUnauthorized, "signature is valid but signer does not own the resource: %v", err) + } + + return nil +} + +// Sign executes the signature to validate the resource +func (r *SignedResourceUpdate) Sign(signer Signer) error { + + r.binaryData = nil //invalidate serialized data + digest, err := r.GetDigest() // computes digest and serializes into .binaryData + if err != nil { + return err + } + + signature, err := signer.Sign(digest) + if err != nil { + return err + } + + // Although the Signer interface returns the public address of the signer, + // recover it from the signature to see if they match + ownerAddress, err := getOwner(digest, signature) + if err != nil { + return NewError(ErrInvalidSignature, "Error verifying signature") + } + + if ownerAddress != signer.Address() { // sanity check to make sure the Signer is declaring the same address used to sign! + return NewError(ErrInvalidSignature, "Signer address does not match ownerAddr") + } + + r.signature = &signature + r.updateAddr = r.UpdateAddr() + return nil +} + +// create an update chunk. +func (r *SignedResourceUpdate) toChunk() (*storage.Chunk, error) { + + // Check that the update is signed and serialized + // For efficiency, data is serialized during signature and cached in + // the binaryData field when computing the signature digest in .getDigest() + if r.signature == nil || r.binaryData == nil { + return nil, NewError(ErrInvalidSignature, "newUpdateChunk called without a valid signature or payload data. Call .Sign() first.") + } + + chunk := storage.NewChunk(r.updateAddr, nil) + resourceUpdateLength := r.resourceUpdate.binaryLength() + chunk.SData = r.binaryData + + // signature is the last item in the chunk data + copy(chunk.SData[resourceUpdateLength:], r.signature[:]) + + chunk.Size = int64(len(chunk.SData)) + return chunk, nil +} + +// fromChunk populates this structure from chunk data. It does not verify the signature is valid. +func (r *SignedResourceUpdate) fromChunk(updateAddr storage.Address, chunkdata []byte) error { + // for update chunk layout see SignedResourceUpdate definition + + //deserialize the resource update portion + if err := r.resourceUpdate.binaryGet(chunkdata); err != nil { + return err + } + + // Extract the signature + var signature *Signature + cursor := r.resourceUpdate.binaryLength() + sigdata := chunkdata[cursor : cursor+signatureLength] + if len(sigdata) > 0 { + signature = &Signature{} + copy(signature[:], sigdata) + } + + r.signature = signature + r.updateAddr = updateAddr + r.binaryData = chunkdata + + return nil + +} + +// GetDigest creates the resource update digest used in signatures (formerly known as keyDataHash) +// the serialized payload is cached in .binaryData +func (r *SignedResourceUpdate) GetDigest() (result common.Hash, err error) { + hasher := hashPool.Get().(hash.Hash) + defer hashPool.Put(hasher) + hasher.Reset() + dataLength := r.resourceUpdate.binaryLength() + if r.binaryData == nil { + r.binaryData = make([]byte, dataLength+signatureLength) + if err := r.resourceUpdate.binaryPut(r.binaryData[:dataLength]); err != nil { + return result, err + } + } + hasher.Write(r.binaryData[:dataLength]) //everything except the signature. + + return common.BytesToHash(hasher.Sum(nil)), nil +} + +// getOwner extracts the address of the resource update signer +func getOwner(digest common.Hash, signature Signature) (common.Address, error) { + pub, err := crypto.SigToPub(digest.Bytes(), signature[:]) + if err != nil { + return common.Address{}, err + } + return crypto.PubkeyToAddress(*pub), nil +} + +// verifyResourceOwnerhsip checks that the signer of the update actually owns the resource +// H(ownerAddr, metaHash) is computed. If it matches the rootAddr the update chunk is claiming +// to update, it is proven that signer of the resource update owns the resource. +// See metadataHash in metadata.go for a more detailed explanation +func verifyOwner(ownerAddr common.Address, metaHash []byte, rootAddr storage.Address) bool { + hasher := hashPool.Get().(hash.Hash) + defer hashPool.Put(hasher) + hasher.Reset() + hasher.Write(metaHash) + hasher.Write(ownerAddr.Bytes()) + rootAddr2 := hasher.Sum(nil) + return bytes.Equal(rootAddr2, rootAddr) +} diff --git a/swarm/storage/mru/testutil.go b/swarm/storage/mru/testutil.go new file mode 100644 index 0000000000..751f51af32 --- /dev/null +++ b/swarm/storage/mru/testutil.go @@ -0,0 +1,56 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package mru + +import ( + "fmt" + "path/filepath" + + "github.com/ethereum/go-ethereum/swarm/storage" +) + +const ( + testDbDirName = "mru" +) + +type TestHandler struct { + *Handler +} + +func (t *TestHandler) Close() { + t.chunkStore.Close() +} + +// NewTestHandler creates Handler object to be used for testing purposes. +func NewTestHandler(datadir string, params *HandlerParams) (*TestHandler, error) { + path := filepath.Join(datadir, testDbDirName) + rh, err := NewHandler(params) + if err != nil { + return nil, fmt.Errorf("resource handler create fail: %v", err) + } + localstoreparams := storage.NewDefaultLocalStoreParams() + localstoreparams.Init(path) + localStore, err := storage.NewLocalStore(localstoreparams, nil) + if err != nil { + return nil, fmt.Errorf("localstore create fail, path %s: %v", path, err) + } + localStore.Validators = append(localStore.Validators, storage.NewContentAddressValidator(storage.MakeHashFunc(resourceHashAlgorithm))) + localStore.Validators = append(localStore.Validators, rh) + netStore := storage.NewNetStore(localStore, nil) + rh.SetStore(netStore) + return &TestHandler{rh}, nil +} diff --git a/swarm/storage/mru/timestampprovider.go b/swarm/storage/mru/timestampprovider.go new file mode 100644 index 0000000000..f483491aa1 --- /dev/null +++ b/swarm/storage/mru/timestampprovider.go @@ -0,0 +1,71 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package mru + +import ( + "encoding/binary" + "time" +) + +// TimestampProvider sets the time source of the mru package +var TimestampProvider timestampProvider = NewDefaultTimestampProvider() + +// Encodes a point in time as a Unix epoch +type Timestamp struct { + Time uint64 // Unix epoch timestamp, in seconds +} + +// 8 bytes uint64 Time +const timestampLength = 8 + +// timestampProvider interface describes a source of timestamp information +type timestampProvider interface { + Now() Timestamp // returns the current timestamp information +} + +// binaryGet populates the timestamp structure from the given byte slice +func (t *Timestamp) binaryGet(data []byte) error { + if len(data) != timestampLength { + return NewError(ErrCorruptData, "timestamp data has the wrong size") + } + t.Time = binary.LittleEndian.Uint64(data[:8]) + return nil +} + +// binaryPut Serializes a Timestamp to a byte slice +func (t *Timestamp) binaryPut(data []byte) error { + if len(data) != timestampLength { + return NewError(ErrCorruptData, "timestamp data has the wrong size") + } + binary.LittleEndian.PutUint64(data, t.Time) + return nil +} + +type DefaultTimestampProvider struct { +} + +// NewDefaultTimestampProvider creates a system clock based timestamp provider +func NewDefaultTimestampProvider() *DefaultTimestampProvider { + return &DefaultTimestampProvider{} +} + +// Now returns the current time according to this provider +func (dtp *DefaultTimestampProvider) Now() Timestamp { + return Timestamp{ + Time: uint64(time.Now().Unix()), + } +} diff --git a/swarm/storage/mru/update.go b/swarm/storage/mru/update.go new file mode 100644 index 0000000000..88c4ac4e59 --- /dev/null +++ b/swarm/storage/mru/update.go @@ -0,0 +1,147 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package mru + +import ( + "encoding/binary" + "errors" + + "github.com/ethereum/go-ethereum/swarm/log" + "github.com/ethereum/go-ethereum/swarm/multihash" +) + +// resourceUpdate encapsulates the information sent as part of a resource update +type resourceUpdate struct { + updateHeader // metainformationa about this resource update + data []byte // actual data payload +} + +// Update chunk layout +// Prefix: +// 2 bytes updateHeaderLength +// 2 bytes data length +const chunkPrefixLength = 2 + 2 + +// Header: (see updateHeader) +// Data: +// data (datalength bytes) +// +// Minimum size is Header + 1 (minimum data length, enforced) +const minimumUpdateDataLength = updateHeaderLength + 1 +const maxUpdateDataLength = chunkSize - signatureLength - updateHeaderLength - chunkPrefixLength + +// binaryPut serializes the resource update information into the given slice +func (r *resourceUpdate) binaryPut(serializedData []byte) error { + datalength := len(r.data) + if datalength == 0 { + return NewError(ErrInvalidValue, "cannot update a resource with no data") + } + + if datalength > maxUpdateDataLength { + return NewErrorf(ErrInvalidValue, "data is too big (length=%d). Max length=%d", datalength, maxUpdateDataLength) + } + + if len(serializedData) != r.binaryLength() { + return NewErrorf(ErrInvalidValue, "slice passed to putBinary must be of exact size. Expected %d bytes", r.binaryLength()) + } + + if r.multihash { + if _, _, err := multihash.GetMultihashLength(r.data); err != nil { + return NewError(ErrInvalidValue, "Invalid multihash") + } + } + + // Add prefix: updateHeaderLength and actual data length + cursor := 0 + binary.LittleEndian.PutUint16(serializedData[cursor:], uint16(updateHeaderLength)) + cursor += 2 + + // data length + binary.LittleEndian.PutUint16(serializedData[cursor:], uint16(datalength)) + cursor += 2 + + // serialize header (see updateHeader) + if err := r.updateHeader.binaryPut(serializedData[cursor : cursor+updateHeaderLength]); err != nil { + return err + } + cursor += updateHeaderLength + + // add the data + copy(serializedData[cursor:], r.data) + cursor += datalength + + return nil +} + +// binaryLength returns the expected number of bytes this structure will take to encode +func (r *resourceUpdate) binaryLength() int { + return chunkPrefixLength + updateHeaderLength + len(r.data) +} + +// binaryGet populates this instance from the information contained in the passed byte slice +func (r *resourceUpdate) binaryGet(serializedData []byte) error { + if len(serializedData) < minimumUpdateDataLength { + return NewErrorf(ErrNothingToReturn, "chunk less than %d bytes cannot be a resource update chunk", minimumUpdateDataLength) + } + cursor := 0 + declaredHeaderlength := binary.LittleEndian.Uint16(serializedData[cursor : cursor+2]) + if declaredHeaderlength != updateHeaderLength { + return NewErrorf(ErrCorruptData, "Invalid header length. Expected %d, got %d", updateHeaderLength, declaredHeaderlength) + } + + cursor += 2 + datalength := int(binary.LittleEndian.Uint16(serializedData[cursor : cursor+2])) + cursor += 2 + + if chunkPrefixLength+updateHeaderLength+datalength+signatureLength != len(serializedData) { + return NewError(ErrNothingToReturn, "length specified in header is different than actual chunk size") + } + + // at this point we can be satisfied that we have the correct data length to read + if err := r.updateHeader.binaryGet(serializedData[cursor : cursor+updateHeaderLength]); err != nil { + return err + } + cursor += updateHeaderLength + + data := serializedData[cursor : cursor+datalength] + cursor += datalength + + // if multihash content is indicated we check the validity of the multihash + if r.updateHeader.multihash { + mhLength, mhHeaderLength, err := multihash.GetMultihashLength(data) + if err != nil { + log.Error("multihash parse error", "err", err) + return err + } + if datalength != mhLength+mhHeaderLength { + log.Debug("multihash error", "datalength", datalength, "mhLength", mhLength, "mhHeaderLength", mhHeaderLength) + return errors.New("Corrupt multihash data") + } + } + + // now that all checks have passed, copy data into structure + r.data = make([]byte, datalength) + copy(r.data, data) + + return nil + +} + +// Multihash specifies whether the resource data should be interpreted as multihash +func (r *resourceUpdate) Multihash() bool { + return r.multihash +} diff --git a/swarm/storage/mru/update_test.go b/swarm/storage/mru/update_test.go new file mode 100644 index 0000000000..51e9d2fcc5 --- /dev/null +++ b/swarm/storage/mru/update_test.go @@ -0,0 +1,72 @@ +package mru + +import ( + "bytes" + "testing" +) + +const serializedUpdateHex = "0x490034004f000000da070000fb0ed7efa696bdb0b54cd75554cc3117ffc891454317df7dd6fefad978e2f2fbf74a10ce8f26ffc8bfaa07c3031a34b2c61f517955e7deb1592daccf96c69cf000456c20717565206c6565206d7563686f207920616e6461206d7563686f2c207665206d7563686f20792073616265206d7563686f" +const serializedUpdateMultihashHex = "0x490022004f000000da070000fb0ed7efa696bdb0b54cd75554cc3117ffc891454317df7dd6fefad978e2f2fbf74a10ce8f26ffc8bfaa07c3031a34b2c61f517955e7deb1592daccf96c69cf0011b200102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1c1e1f20" + +func getTestResourceUpdate() *resourceUpdate { + return &resourceUpdate{ + updateHeader: *getTestUpdateHeader(false), + data: []byte("El que lee mucho y anda mucho, ve mucho y sabe mucho"), + } +} + +func getTestResourceUpdateMultihash() *resourceUpdate { + return &resourceUpdate{ + updateHeader: *getTestUpdateHeader(true), + data: []byte{0x1b, 0x20, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 28, 30, 31, 32}, + } +} + +func compareResourceUpdate(a, b *resourceUpdate) bool { + return compareUpdateHeader(&a.updateHeader, &b.updateHeader) && + bytes.Equal(a.data, b.data) +} + +func TestResourceUpdateSerializer(t *testing.T) { + var serializedUpdateLength = len(serializedUpdateHex)/2 - 1 // hack to calculate the byte length out of the hex representation + update := getTestResourceUpdate() + serializedUpdate := make([]byte, serializedUpdateLength) + if err := update.binaryPut(serializedUpdate); err != nil { + t.Fatal(err) + } + compareByteSliceToExpectedHex(t, "serializedUpdate", serializedUpdate, serializedUpdateHex) + + // Test fail if update does not contain data + update.data = nil + if err := update.binaryPut(serializedUpdate); err == nil { + t.Fatal("Expected resourceUpdate.binaryPut to fail since update does not contain data") + } + + // Test fail if update is too big + update.data = make([]byte, 10000) + if err := update.binaryPut(serializedUpdate); err == nil { + t.Fatal("Expected resourceUpdate.binaryPut to fail since update is too big") + } + + // Test fail if passed slice is not of the exact size required for this update + update.data = make([]byte, 1) + if err := update.binaryPut(serializedUpdate); err == nil { + t.Fatal("Expected resourceUpdate.binaryPut to fail since passed slice is not of the appropriate size") + } + + // Test serializing a multihash update + var serializedUpdateMultihashLength = len(serializedUpdateMultihashHex)/2 - 1 // hack to calculate the byte length out of the hex representation + update = getTestResourceUpdateMultihash() + serializedUpdate = make([]byte, serializedUpdateMultihashLength) + if err := update.binaryPut(serializedUpdate); err != nil { + t.Fatal(err) + } + compareByteSliceToExpectedHex(t, "serializedUpdate", serializedUpdate, serializedUpdateMultihashHex) + + // mess with the multihash to test it fails with a wrong multihash error + update.data[1] = 79 + if err := update.binaryPut(serializedUpdate); err == nil { + t.Fatal("Expected resourceUpdate.binaryPut to fail since data contains an invalid multihash") + } + +} diff --git a/swarm/storage/mru/updateheader.go b/swarm/storage/mru/updateheader.go new file mode 100644 index 0000000000..3ac20c1890 --- /dev/null +++ b/swarm/storage/mru/updateheader.go @@ -0,0 +1,88 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package mru + +import ( + "github.com/ethereum/go-ethereum/swarm/storage" +) + +// updateHeader models the non-payload components of a Resource Update +type updateHeader struct { + UpdateLookup // UpdateLookup contains the information required to locate this resource (components of the search key used to find it) + multihash bool // Whether the data in this Resource Update should be interpreted as multihash + metaHash []byte // SHA3 hash of the metadata chunk (less ownerAddr). Used to prove ownerhsip of the resource. +} + +const metaHashLength = storage.KeyLength + +// updateLookupLength bytes +// 1 byte flags (multihash bool for now) +// 32 bytes metaHash +const updateHeaderLength = updateLookupLength + 1 + metaHashLength + +// binaryPut serializes the resource header information into the given slice +func (h *updateHeader) binaryPut(serializedData []byte) error { + if len(serializedData) != updateHeaderLength { + return NewErrorf(ErrInvalidValue, "Incorrect slice size to serialize updateHeaderLength. Expected %d, got %d", updateHeaderLength, len(serializedData)) + } + if len(h.metaHash) != metaHashLength { + return NewError(ErrInvalidValue, "updateHeader.binaryPut called without metaHash set") + } + if err := h.UpdateLookup.binaryPut(serializedData[:updateLookupLength]); err != nil { + return err + } + cursor := updateLookupLength + copy(serializedData[cursor:], h.metaHash[:metaHashLength]) + cursor += metaHashLength + + var flags byte + if h.multihash { + flags |= 0x01 + } + + serializedData[cursor] = flags + cursor++ + + return nil +} + +// binaryLength returns the expected size of this structure when serialized +func (h *updateHeader) binaryLength() int { + return updateHeaderLength +} + +// binaryGet restores the current updateHeader instance from the information contained in the passed slice +func (h *updateHeader) binaryGet(serializedData []byte) error { + if len(serializedData) != updateHeaderLength { + return NewErrorf(ErrInvalidValue, "Incorrect slice size to read updateHeaderLength. Expected %d, got %d", updateHeaderLength, len(serializedData)) + } + + if err := h.UpdateLookup.binaryGet(serializedData[:updateLookupLength]); err != nil { + return err + } + cursor := updateLookupLength + h.metaHash = make([]byte, metaHashLength) + copy(h.metaHash[:storage.KeyLength], serializedData[cursor:cursor+storage.KeyLength]) + cursor += metaHashLength + + flags := serializedData[cursor] + cursor++ + + h.multihash = flags&0x01 != 0 + + return nil +} diff --git a/swarm/storage/mru/updateheader_test.go b/swarm/storage/mru/updateheader_test.go new file mode 100644 index 0000000000..b1f5059892 --- /dev/null +++ b/swarm/storage/mru/updateheader_test.go @@ -0,0 +1,64 @@ +package mru + +import ( + "bytes" + "testing" + + "github.com/ethereum/go-ethereum/common/hexutil" +) + +const serializedUpdateHeaderMultihashHex = "0x4f000000da070000fb0ed7efa696bdb0b54cd75554cc3117ffc891454317df7dd6fefad978e2f2fbf74a10ce8f26ffc8bfaa07c3031a34b2c61f517955e7deb1592daccf96c69cf001" + +func getTestUpdateHeader(multihash bool) (header *updateHeader) { + _, metaHash, _, _ := getTestMetadata().serializeAndHash() + return &updateHeader{ + UpdateLookup: *getTestUpdateLookup(), + multihash: multihash, + metaHash: metaHash, + } +} + +func compareUpdateHeader(a, b *updateHeader) bool { + return compareUpdateLookup(&a.UpdateLookup, &b.UpdateLookup) && + a.multihash == b.multihash && + bytes.Equal(a.metaHash, b.metaHash) +} + +func TestUpdateHeaderSerializer(t *testing.T) { + header := getTestUpdateHeader(true) + serializedHeader := make([]byte, updateHeaderLength) + if err := header.binaryPut(serializedHeader); err != nil { + t.Fatal(err) + } + compareByteSliceToExpectedHex(t, "serializedHeader", serializedHeader, serializedUpdateHeaderMultihashHex) + + // trigger incorrect slice length error passing a slice that is 1 byte too big + if err := header.binaryPut(make([]byte, updateHeaderLength+1)); err == nil { + t.Fatal("Expected updateHeader.binaryPut to fail since supplied slice is of incorrect length") + } + + // trigger invalid metaHash error + header.metaHash = nil + if err := header.binaryPut(serializedHeader); err == nil { + t.Fatal("Expected updateHeader.binaryPut to fail metaHash is of incorrect length") + } +} + +func TestUpdateHeaderDeserializer(t *testing.T) { + originalUpdate := getTestUpdateHeader(true) + serializedData, _ := hexutil.Decode(serializedUpdateHeaderMultihashHex) + var retrievedUpdate updateHeader + if err := retrievedUpdate.binaryGet(serializedData); err != nil { + t.Fatal(err) + } + if !compareUpdateHeader(originalUpdate, &retrievedUpdate) { + t.Fatalf("Expected deserialized structure to equal the original") + } + + // mess with source slice to test length checks + serializedData = []byte{1, 2, 3} + if err := retrievedUpdate.binaryGet(serializedData); err == nil { + t.Fatal("Expected retrievedUpdate.binaryGet, since passed slice is too small") + } + +} diff --git a/swarm/storage/netstore.go b/swarm/storage/netstore.go index 5d4f17deb1..96a7e51f77 100644 --- a/swarm/storage/netstore.go +++ b/swarm/storage/netstore.go @@ -17,125 +17,182 @@ package storage import ( - "fmt" - "path/filepath" + "context" "time" - "github.com/ethereum/go-ethereum/log" -) - -/* -NetStore is a cloud storage access abstaction layer for swarm -it contains the shared logic of network served chunk store/retrieval requests -both local (coming from DPA api) and remote (coming from peers via bzz protocol) -it implements the ChunkStore interface and embeds LocalStore - -It is called by the bzz protocol instances via Depo (the store/retrieve request handler) -a protocol instance is running on each peer, so this is heavily parallelised. -NetStore falls back to a backend (CloudStorage interface) -implemented by bzz/network/forwarder. forwarder or IPFS or IPΞS -*/ -type NetStore struct { - hashfunc SwarmHasher - localStore *LocalStore - cloud CloudStore -} - -// backend engine for cloud store -// It can be aggregate dispatching to several parallel implementations: -// bzz/network/forwarder. forwarder or IPFS or IPΞS -type CloudStore interface { - Store(*Chunk) - Deliver(*Chunk) - Retrieve(*Chunk) -} - -type StoreParams struct { - ChunkDbPath string - DbCapacity uint64 - CacheCapacity uint - Radius int -} - -//create params with default values -func NewDefaultStoreParams() (self *StoreParams) { - return &StoreParams{ - DbCapacity: defaultDbCapacity, - CacheCapacity: defaultCacheCapacity, - Radius: defaultRadius, - } -} - -//this can only finally be set after all config options (file, cmd line, env vars) -//have been evaluated -func (self *StoreParams) Init(path string) { - self.ChunkDbPath = filepath.Join(path, "chunks") -} - -// netstore contructor, takes path argument that is used to initialise dbStore, -// the persistent (disk) storage component of LocalStore -// the second argument is the hive, the connection/logistics manager for the node -func NewNetStore(hash SwarmHasher, lstore *LocalStore, cloud CloudStore, params *StoreParams) *NetStore { - return &NetStore{ - hashfunc: hash, - localStore: lstore, - cloud: cloud, - } -} - -const ( - // maximum number of peers that a retrieved message is delivered to - requesterCount = 3 + "github.com/ethereum/go-ethereum/swarm/log" + "github.com/ethereum/go-ethereum/swarm/spancontext" + opentracing "github.com/opentracing/opentracing-go" ) var ( - // timeout interval before retrieval is timed out - searchTimeout = 3 * time.Second + // NetStore.Get timeout for get and get retries + // This is the maximum period that the Get will block. + // If it is reached, Get will return ErrChunkNotFound. + netStoreRetryTimeout = 30 * time.Second + // Minimal period between calling get method on NetStore + // on retry. It protects calling get very frequently if + // it returns ErrChunkNotFound very fast. + netStoreMinRetryDelay = 3 * time.Second + // Timeout interval before retrieval is timed out. + // It is used in NetStore.get on waiting for ReqC to be + // closed on a single retrieve request. + searchTimeout = 10 * time.Second ) -// store logic common to local and network chunk store requests -// ~ unsafe put in localdb no check if exists no extra copy no hash validation -// the chunk is forced to propagate (Cloud.Store) even if locally found! -// caller needs to make sure if that is wanted -func (self *NetStore) Put(entry *Chunk) { - self.localStore.Put(entry) +// NetStore implements the ChunkStore interface, +// this chunk access layer assumed 2 chunk stores +// local storage eg. LocalStore and network storage eg., NetStore +// access by calling network is blocking with a timeout +type NetStore struct { + localStore *LocalStore + retrieve func(ctx context.Context, chunk *Chunk) error +} - // handle deliveries - if entry.Req != nil { - log.Trace(fmt.Sprintf("NetStore.Put: localStore.Put %v hit existing request...delivering", entry.Key.Log())) - // closing C signals to other routines (local requests) - // that the chunk is has been retrieved - close(entry.Req.C) - // deliver the chunk to requesters upstream - go self.cloud.Deliver(entry) - } else { - log.Trace(fmt.Sprintf("NetStore.Put: localStore.Put %v stored locally", entry.Key.Log())) - // handle propagating store requests - // go self.cloud.Store(entry) - go self.cloud.Store(entry) +func NewNetStore(localStore *LocalStore, retrieve func(ctx context.Context, chunk *Chunk) error) *NetStore { + return &NetStore{localStore, retrieve} +} + +// Get is the entrypoint for local retrieve requests +// waits for response or times out +// +// Get uses get method to retrieve request, but retries if the +// ErrChunkNotFound is returned by get, until the netStoreRetryTimeout +// is reached. +func (ns *NetStore) Get(ctx context.Context, addr Address) (chunk *Chunk, err error) { + + var sp opentracing.Span + ctx, sp = spancontext.StartSpan( + ctx, + "netstore.get.global") + defer sp.Finish() + + timer := time.NewTimer(netStoreRetryTimeout) + defer timer.Stop() + + // result and resultC provide results from the goroutine + // where NetStore.get is called. + type result struct { + chunk *Chunk + err error + } + resultC := make(chan result) + + // quitC ensures that retring goroutine is terminated + // when this function returns. + quitC := make(chan struct{}) + defer close(quitC) + + // do retries in a goroutine so that the timer can + // force this method to return after the netStoreRetryTimeout. + go func() { + // limiter ensures that NetStore.get is not called more frequently + // then netStoreMinRetryDelay. If NetStore.get takes longer + // then netStoreMinRetryDelay, the next retry call will be + // without a delay. + limiter := time.NewTimer(netStoreMinRetryDelay) + defer limiter.Stop() + + for { + chunk, err := ns.get(ctx, addr, 0) + if err != ErrChunkNotFound { + // break retry only if the error is nil + // or other error then ErrChunkNotFound + select { + case <-quitC: + // Maybe NetStore.Get function has returned + // by the timer.C while we were waiting for the + // results. Terminate this goroutine. + case resultC <- result{chunk: chunk, err: err}: + // Send the result to the parrent goroutine. + } + return + + } + select { + case <-quitC: + // NetStore.Get function has returned, possibly + // by the timer.C, which makes this goroutine + // not needed. + return + case <-limiter.C: + } + // Reset the limiter for the next iteration. + limiter.Reset(netStoreMinRetryDelay) + log.Debug("NetStore.Get retry chunk", "key", addr) + } + }() + + select { + case r := <-resultC: + return r.chunk, r.err + case <-timer.C: + return nil, ErrChunkNotFound } } -// retrieve logic common for local and network chunk retrieval requests -func (self *NetStore) Get(key Key) (*Chunk, error) { - var err error - chunk, err := self.localStore.Get(key) - if err == nil { - if chunk.Req == nil { - log.Trace(fmt.Sprintf("NetStore.Get: %v found locally", key)) - } else { - log.Trace(fmt.Sprintf("NetStore.Get: %v hit on an existing request", key)) - // no need to launch again - } - return chunk, err +// GetWithTimeout makes a single retrieval attempt for a chunk with a explicit timeout parameter +func (ns *NetStore) GetWithTimeout(ctx context.Context, addr Address, timeout time.Duration) (chunk *Chunk, err error) { + return ns.get(ctx, addr, timeout) +} + +func (ns *NetStore) get(ctx context.Context, addr Address, timeout time.Duration) (chunk *Chunk, err error) { + if timeout == 0 { + timeout = searchTimeout } - // no data and no request status - log.Trace(fmt.Sprintf("NetStore.Get: %v not found locally. open new request", key)) - chunk = NewChunk(key, newRequestStatus(key)) - self.localStore.memStore.Put(chunk) - go self.cloud.Retrieve(chunk) + + var sp opentracing.Span + ctx, sp = spancontext.StartSpan( + ctx, + "netstore.get") + defer sp.Finish() + + if ns.retrieve == nil { + chunk, err = ns.localStore.Get(ctx, addr) + if err == nil { + return chunk, nil + } + if err != ErrFetching { + return nil, err + } + } else { + var created bool + chunk, created = ns.localStore.GetOrCreateRequest(ctx, addr) + + if chunk.ReqC == nil { + return chunk, nil + } + + if created { + err := ns.retrieve(ctx, chunk) + if err != nil { + // mark chunk request as failed so that we can retry it later + chunk.SetErrored(ErrChunkUnavailable) + return nil, err + } + } + } + + t := time.NewTicker(timeout) + defer t.Stop() + + select { + case <-t.C: + // mark chunk request as failed so that we can retry + chunk.SetErrored(ErrChunkNotFound) + return nil, ErrChunkNotFound + case <-chunk.ReqC: + } + chunk.SetErrored(nil) return chunk, nil } -// Close netstore -func (self *NetStore) Close() {} +// Put is the entrypoint for local store requests coming from storeLoop +func (ns *NetStore) Put(ctx context.Context, chunk *Chunk) { + ns.localStore.Put(ctx, chunk) +} + +// Close chunk store +func (ns *NetStore) Close() { + ns.localStore.Close() +} diff --git a/swarm/storage/netstore_test.go b/swarm/storage/netstore_test.go new file mode 100644 index 0000000000..7babbf5e0c --- /dev/null +++ b/swarm/storage/netstore_test.go @@ -0,0 +1,123 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package storage + +import ( + "context" + "encoding/hex" + "errors" + "io/ioutil" + "testing" + "time" + + "github.com/ethereum/go-ethereum/swarm/network" +) + +var ( + errUnknown = errors.New("unknown error") +) + +type mockRetrieve struct { + requests map[string]int +} + +func NewMockRetrieve() *mockRetrieve { + return &mockRetrieve{requests: make(map[string]int)} +} + +func newDummyChunk(addr Address) *Chunk { + chunk := NewChunk(addr, make(chan bool)) + chunk.SData = []byte{3, 4, 5} + chunk.Size = 3 + + return chunk +} + +func (m *mockRetrieve) retrieve(ctx context.Context, chunk *Chunk) error { + hkey := hex.EncodeToString(chunk.Addr) + m.requests[hkey] += 1 + + // on second call return error + if m.requests[hkey] == 2 { + return errUnknown + } + + // on third call return data + if m.requests[hkey] == 3 { + *chunk = *newDummyChunk(chunk.Addr) + go func() { + time.Sleep(100 * time.Millisecond) + close(chunk.ReqC) + }() + + return nil + } + + return nil +} + +func TestNetstoreFailedRequest(t *testing.T) { + searchTimeout = 300 * time.Millisecond + + // setup + addr := network.RandomAddr() // tested peers peer address + + // temp datadir + datadir, err := ioutil.TempDir("", "netstore") + if err != nil { + t.Fatal(err) + } + params := NewDefaultLocalStoreParams() + params.Init(datadir) + params.BaseKey = addr.Over() + localStore, err := NewTestLocalStoreForAddr(params) + if err != nil { + t.Fatal(err) + } + + r := NewMockRetrieve() + netStore := NewNetStore(localStore, r.retrieve) + + key := Address{} + + // first call is done by the retry on ErrChunkNotFound, no need to do it here + // _, err = netStore.Get(key) + // if err == nil || err != ErrChunkNotFound { + // t.Fatalf("expected to get ErrChunkNotFound, but got: %s", err) + // } + + // second call + _, err = netStore.Get(context.TODO(), key) + if got := r.requests[hex.EncodeToString(key)]; got != 2 { + t.Fatalf("expected to have called retrieve two times, but got: %v", got) + } + if err != errUnknown { + t.Fatalf("expected to get an unknown error, but got: %s", err) + } + + // third call + chunk, err := netStore.Get(context.TODO(), key) + if got := r.requests[hex.EncodeToString(key)]; got != 3 { + t.Fatalf("expected to have called retrieve three times, but got: %v", got) + } + if err != nil || chunk == nil { + t.Fatalf("expected to get a chunk but got: %v, %s", chunk, err) + } + if len(chunk.SData) != 3 { + t.Fatalf("expected to get a chunk with size 3, but got: %v", chunk.SData) + } +} diff --git a/swarm/storage/pyramid.go b/swarm/storage/pyramid.go index 19d493405a..2923c81c5a 100644 --- a/swarm/storage/pyramid.go +++ b/swarm/storage/pyramid.go @@ -17,11 +17,15 @@ package storage import ( + "context" "encoding/binary" "errors" "io" + "io/ioutil" "sync" "time" + + "github.com/ethereum/go-ethereum/swarm/log" ) /* @@ -62,9 +66,8 @@ var ( ) const ( - ChunkProcessors = 8 - DefaultBranches int64 = 128 - splitTimeout = time.Minute * 5 + ChunkProcessors = 8 + splitTimeout = time.Minute * 5 ) const ( @@ -72,18 +75,39 @@ const ( TreeChunk = 1 ) -type ChunkerParams struct { - Branches int64 - Hash string +type PyramidSplitterParams struct { + SplitterParams + getter Getter } -func NewChunkerParams() *ChunkerParams { - return &ChunkerParams{ - Branches: DefaultBranches, - Hash: SHA3Hash, +func NewPyramidSplitterParams(addr Address, reader io.Reader, putter Putter, getter Getter, chunkSize int64) *PyramidSplitterParams { + hashSize := putter.RefSize() + return &PyramidSplitterParams{ + SplitterParams: SplitterParams{ + ChunkerParams: ChunkerParams{ + chunkSize: chunkSize, + hashSize: hashSize, + }, + reader: reader, + putter: putter, + addr: addr, + }, + getter: getter, } } +/* + When splitting, data is given as a SectionReader, and the key is a hashSize long byte slice (Key), the root hash of the entire content will fill this once processing finishes. + New chunks to store are store using the putter which the caller provides. +*/ +func PyramidSplit(ctx context.Context, reader io.Reader, putter Putter, getter Getter) (Address, func(context.Context) error, error) { + return NewPyramidSplitter(NewPyramidSplitterParams(nil, reader, putter, getter, DefaultChunkSize)).Split(ctx) +} + +func PyramidAppend(ctx context.Context, addr Address, reader io.Reader, putter Putter, getter Getter) (Address, func(context.Context) error, error) { + return NewPyramidSplitter(NewPyramidSplitterParams(addr, reader, putter, getter, DefaultChunkSize)).Append(ctx) +} + // Entry to create a tree node type TreeEntry struct { level int @@ -109,264 +133,250 @@ func NewTreeEntry(pyramid *PyramidChunker) *TreeEntry { // Used by the hash processor to create a data/tree chunk and send to storage type chunkJob struct { - key Key - chunk []byte - size int64 - parentWg *sync.WaitGroup - chunkType int // used to identify the tree related chunks for debugging - chunkLvl int // leaf-1 is level 0 and goes upwards until it reaches root + key Address + chunk []byte + parentWg *sync.WaitGroup } type PyramidChunker struct { - hashFunc SwarmHasher chunkSize int64 hashSize int64 branches int64 + reader io.Reader + putter Putter + getter Getter + key Address workerCount int64 workerLock sync.RWMutex + jobC chan *chunkJob + wg *sync.WaitGroup + errC chan error + quitC chan bool + rootKey []byte + chunkLevel [][]*TreeEntry } -func NewPyramidChunker(params *ChunkerParams) (self *PyramidChunker) { - self = &PyramidChunker{} - self.hashFunc = MakeHashFunc(params.Hash) - self.branches = params.Branches - self.hashSize = int64(self.hashFunc().Size()) - self.chunkSize = self.hashSize * self.branches - self.workerCount = 0 +func NewPyramidSplitter(params *PyramidSplitterParams) (pc *PyramidChunker) { + pc = &PyramidChunker{} + pc.reader = params.reader + pc.hashSize = params.hashSize + pc.branches = params.chunkSize / pc.hashSize + pc.chunkSize = pc.hashSize * pc.branches + pc.putter = params.putter + pc.getter = params.getter + pc.key = params.addr + pc.workerCount = 0 + pc.jobC = make(chan *chunkJob, 2*ChunkProcessors) + pc.wg = &sync.WaitGroup{} + pc.errC = make(chan error) + pc.quitC = make(chan bool) + pc.rootKey = make([]byte, pc.hashSize) + pc.chunkLevel = make([][]*TreeEntry, pc.branches) return } -func (self *PyramidChunker) Join(key Key, chunkC chan *Chunk) LazySectionReader { +func (pc *PyramidChunker) Join(addr Address, getter Getter, depth int) LazySectionReader { return &LazyChunkReader{ - key: key, - chunkC: chunkC, - chunkSize: self.chunkSize, - branches: self.branches, - hashSize: self.hashSize, + key: addr, + depth: depth, + chunkSize: pc.chunkSize, + branches: pc.branches, + hashSize: pc.hashSize, + getter: getter, } } -func (self *PyramidChunker) incrementWorkerCount() { - self.workerLock.Lock() - defer self.workerLock.Unlock() - self.workerCount += 1 +func (pc *PyramidChunker) incrementWorkerCount() { + pc.workerLock.Lock() + defer pc.workerLock.Unlock() + pc.workerCount += 1 } -func (self *PyramidChunker) getWorkerCount() int64 { - self.workerLock.Lock() - defer self.workerLock.Unlock() - return self.workerCount +func (pc *PyramidChunker) getWorkerCount() int64 { + pc.workerLock.Lock() + defer pc.workerLock.Unlock() + return pc.workerCount } -func (self *PyramidChunker) decrementWorkerCount() { - self.workerLock.Lock() - defer self.workerLock.Unlock() - self.workerCount -= 1 +func (pc *PyramidChunker) decrementWorkerCount() { + pc.workerLock.Lock() + defer pc.workerLock.Unlock() + pc.workerCount -= 1 } -func (self *PyramidChunker) Split(data io.Reader, size int64, chunkC chan *Chunk, storageWG, processorWG *sync.WaitGroup) (Key, error) { - jobC := make(chan *chunkJob, 2*ChunkProcessors) - wg := &sync.WaitGroup{} - errC := make(chan error) - quitC := make(chan bool) - rootKey := make([]byte, self.hashSize) - chunkLevel := make([][]*TreeEntry, self.branches) +func (pc *PyramidChunker) Split(ctx context.Context) (k Address, wait func(context.Context) error, err error) { + log.Debug("pyramid.chunker: Split()") - wg.Add(1) - go self.prepareChunks(false, chunkLevel, data, rootKey, quitC, wg, jobC, processorWG, chunkC, errC, storageWG) + pc.wg.Add(1) + pc.prepareChunks(false) // closes internal error channel if all subprocesses in the workgroup finished go func() { // waiting for all chunks to finish - wg.Wait() + pc.wg.Wait() - // if storage waitgroup is non-nil, we wait for storage to finish too - if storageWG != nil { - storageWG.Wait() - } //We close errC here because this is passed down to 8 parallel routines underneath. // if a error happens in one of them.. that particular routine raises error... // once they all complete successfully, the control comes back and we can safely close this here. - close(errC) + close(pc.errC) }() - defer close(quitC) + defer close(pc.quitC) + defer pc.putter.Close() select { - case err := <-errC: + case err := <-pc.errC: if err != nil { - return nil, err + return nil, nil, err } case <-time.NewTimer(splitTimeout).C: } - return rootKey, nil + return pc.rootKey, pc.putter.Wait, nil } -func (self *PyramidChunker) Append(key Key, data io.Reader, chunkC chan *Chunk, storageWG, processorWG *sync.WaitGroup) (Key, error) { - quitC := make(chan bool) - rootKey := make([]byte, self.hashSize) - chunkLevel := make([][]*TreeEntry, self.branches) - +func (pc *PyramidChunker) Append(ctx context.Context) (k Address, wait func(context.Context) error, err error) { + log.Debug("pyramid.chunker: Append()") // Load the right most unfinished tree chunks in every level - self.loadTree(chunkLevel, key, chunkC, quitC) + pc.loadTree() - jobC := make(chan *chunkJob, 2*ChunkProcessors) - wg := &sync.WaitGroup{} - errC := make(chan error) - - wg.Add(1) - go self.prepareChunks(true, chunkLevel, data, rootKey, quitC, wg, jobC, processorWG, chunkC, errC, storageWG) + pc.wg.Add(1) + pc.prepareChunks(true) // closes internal error channel if all subprocesses in the workgroup finished go func() { // waiting for all chunks to finish - wg.Wait() + pc.wg.Wait() - // if storage waitgroup is non-nil, we wait for storage to finish too - if storageWG != nil { - storageWG.Wait() - } - close(errC) + close(pc.errC) }() - defer close(quitC) + defer close(pc.quitC) + defer pc.putter.Close() select { - case err := <-errC: + case err := <-pc.errC: if err != nil { - return nil, err + return nil, nil, err } case <-time.NewTimer(splitTimeout).C: } - return rootKey, nil + + return pc.rootKey, pc.putter.Wait, nil } -func (self *PyramidChunker) processor(id int64, jobC chan *chunkJob, chunkC chan *Chunk, errC chan error, quitC chan bool, swg, wwg *sync.WaitGroup) { - defer self.decrementWorkerCount() - - hasher := self.hashFunc() - if wwg != nil { - defer wwg.Done() - } +func (pc *PyramidChunker) processor(id int64) { + defer pc.decrementWorkerCount() for { select { - case job, ok := <-jobC: + case job, ok := <-pc.jobC: if !ok { return } - self.processChunk(id, hasher, job, chunkC, swg) - case <-quitC: + pc.processChunk(id, job) + case <-pc.quitC: return } } } -func (self *PyramidChunker) processChunk(id int64, hasher SwarmHash, job *chunkJob, chunkC chan *Chunk, swg *sync.WaitGroup) { - hasher.ResetWithLength(job.chunk[:8]) // 8 bytes of length - hasher.Write(job.chunk[8:]) // minus 8 []byte length - h := hasher.Sum(nil) +func (pc *PyramidChunker) processChunk(id int64, job *chunkJob) { + log.Debug("pyramid.chunker: processChunk()", "id", id) - newChunk := &Chunk{ - Key: h, - SData: job.chunk, - Size: job.size, - wg: swg, + ref, err := pc.putter.Put(context.TODO(), job.chunk) + if err != nil { + pc.errC <- err } // report hash of this chunk one level up (keys corresponds to the proper subslice of the parent chunk) - copy(job.key, h) + copy(job.key, ref) // send off new chunk to storage - if chunkC != nil { - if swg != nil { - swg.Add(1) - } - } job.parentWg.Done() - - if chunkC != nil { - chunkC <- newChunk - } } -func (self *PyramidChunker) loadTree(chunkLevel [][]*TreeEntry, key Key, chunkC chan *Chunk, quitC chan bool) error { +func (pc *PyramidChunker) loadTree() error { + log.Debug("pyramid.chunker: loadTree()") // Get the root chunk to get the total size - chunk := retrieve(key, chunkC, quitC) - if chunk == nil { + chunkData, err := pc.getter.Get(context.TODO(), Reference(pc.key)) + if err != nil { return errLoadingTreeRootChunk } + chunkSize := chunkData.Size() + log.Trace("pyramid.chunker: root chunk", "chunk.Size", chunkSize, "pc.chunkSize", pc.chunkSize) //if data size is less than a chunk... add a parent with update as pending - if chunk.Size <= self.chunkSize { + if chunkSize <= pc.chunkSize { newEntry := &TreeEntry{ level: 0, branchCount: 1, - subtreeSize: uint64(chunk.Size), - chunk: make([]byte, self.chunkSize+8), - key: make([]byte, self.hashSize), + subtreeSize: uint64(chunkSize), + chunk: make([]byte, pc.chunkSize+8), + key: make([]byte, pc.hashSize), index: 0, updatePending: true, } - copy(newEntry.chunk[8:], chunk.Key) - chunkLevel[0] = append(chunkLevel[0], newEntry) + copy(newEntry.chunk[8:], pc.key) + pc.chunkLevel[0] = append(pc.chunkLevel[0], newEntry) return nil } var treeSize int64 var depth int - treeSize = self.chunkSize - for ; treeSize < chunk.Size; treeSize *= self.branches { + treeSize = pc.chunkSize + for ; treeSize < chunkSize; treeSize *= pc.branches { depth++ } + log.Trace("pyramid.chunker", "depth", depth) // Add the root chunk entry - branchCount := int64(len(chunk.SData)-8) / self.hashSize + branchCount := int64(len(chunkData)-8) / pc.hashSize newEntry := &TreeEntry{ level: depth - 1, branchCount: branchCount, - subtreeSize: uint64(chunk.Size), - chunk: chunk.SData, - key: key, + subtreeSize: uint64(chunkSize), + chunk: chunkData, + key: pc.key, index: 0, updatePending: true, } - chunkLevel[depth-1] = append(chunkLevel[depth-1], newEntry) + pc.chunkLevel[depth-1] = append(pc.chunkLevel[depth-1], newEntry) // Add the rest of the tree for lvl := depth - 1; lvl >= 1; lvl-- { //TODO(jmozah): instead of loading finished branches and then trim in the end, //avoid loading them in the first place - for _, ent := range chunkLevel[lvl] { - branchCount = int64(len(ent.chunk)-8) / self.hashSize + for _, ent := range pc.chunkLevel[lvl] { + branchCount = int64(len(ent.chunk)-8) / pc.hashSize for i := int64(0); i < branchCount; i++ { - key := ent.chunk[8+(i*self.hashSize) : 8+((i+1)*self.hashSize)] - newChunk := retrieve(key, chunkC, quitC) - if newChunk == nil { + key := ent.chunk[8+(i*pc.hashSize) : 8+((i+1)*pc.hashSize)] + newChunkData, err := pc.getter.Get(context.TODO(), Reference(key)) + if err != nil { return errLoadingTreeChunk } - bewBranchCount := int64(len(newChunk.SData)-8) / self.hashSize + newChunkSize := newChunkData.Size() + bewBranchCount := int64(len(newChunkData)-8) / pc.hashSize newEntry := &TreeEntry{ level: lvl - 1, branchCount: bewBranchCount, - subtreeSize: uint64(newChunk.Size), - chunk: newChunk.SData, + subtreeSize: uint64(newChunkSize), + chunk: newChunkData, key: key, index: 0, updatePending: true, } - chunkLevel[lvl-1] = append(chunkLevel[lvl-1], newEntry) + pc.chunkLevel[lvl-1] = append(pc.chunkLevel[lvl-1], newEntry) } // We need to get only the right most unfinished branch.. so trim all finished branches - if int64(len(chunkLevel[lvl-1])) >= self.branches { - chunkLevel[lvl-1] = nil + if int64(len(pc.chunkLevel[lvl-1])) >= pc.branches { + pc.chunkLevel[lvl-1] = nil } } } @@ -374,29 +384,25 @@ func (self *PyramidChunker) loadTree(chunkLevel [][]*TreeEntry, key Key, chunkC return nil } -func (self *PyramidChunker) prepareChunks(isAppend bool, chunkLevel [][]*TreeEntry, data io.Reader, rootKey []byte, quitC chan bool, wg *sync.WaitGroup, jobC chan *chunkJob, processorWG *sync.WaitGroup, chunkC chan *Chunk, errC chan error, storageWG *sync.WaitGroup) { - defer wg.Done() +func (pc *PyramidChunker) prepareChunks(isAppend bool) { + log.Debug("pyramid.chunker: prepareChunks", "isAppend", isAppend) + defer pc.wg.Done() chunkWG := &sync.WaitGroup{} - totalDataSize := 0 - // processorWG keeps track of workers spawned for hashing chunks - if processorWG != nil { - processorWG.Add(1) - } + pc.incrementWorkerCount() - self.incrementWorkerCount() - go self.processor(self.workerCount, jobC, chunkC, errC, quitC, storageWG, processorWG) + go pc.processor(pc.workerCount) - parent := NewTreeEntry(self) - var unFinishedChunk *Chunk + parent := NewTreeEntry(pc) + var unfinishedChunkData ChunkData + var unfinishedChunkSize int64 - if isAppend && len(chunkLevel[0]) != 0 { + if isAppend && len(pc.chunkLevel[0]) != 0 { + lastIndex := len(pc.chunkLevel[0]) - 1 + ent := pc.chunkLevel[0][lastIndex] - lastIndex := len(chunkLevel[0]) - 1 - ent := chunkLevel[0][lastIndex] - - if ent.branchCount < self.branches { + if ent.branchCount < pc.branches { parent = &TreeEntry{ level: 0, branchCount: ent.branchCount, @@ -408,104 +414,132 @@ func (self *PyramidChunker) prepareChunks(isAppend bool, chunkLevel [][]*TreeEnt } lastBranch := parent.branchCount - 1 - lastKey := parent.chunk[8+lastBranch*self.hashSize : 8+(lastBranch+1)*self.hashSize] + lastKey := parent.chunk[8+lastBranch*pc.hashSize : 8+(lastBranch+1)*pc.hashSize] - unFinishedChunk = retrieve(lastKey, chunkC, quitC) - if unFinishedChunk.Size < self.chunkSize { - - parent.subtreeSize = parent.subtreeSize - uint64(unFinishedChunk.Size) + var err error + unfinishedChunkData, err = pc.getter.Get(context.TODO(), lastKey) + if err != nil { + pc.errC <- err + } + unfinishedChunkSize = unfinishedChunkData.Size() + if unfinishedChunkSize < pc.chunkSize { + parent.subtreeSize = parent.subtreeSize - uint64(unfinishedChunkSize) parent.branchCount = parent.branchCount - 1 } else { - unFinishedChunk = nil + unfinishedChunkData = nil } } } for index := 0; ; index++ { - - var n int var err error - chunkData := make([]byte, self.chunkSize+8) - if unFinishedChunk != nil { - copy(chunkData, unFinishedChunk.SData) - n, err = data.Read(chunkData[8+unFinishedChunk.Size:]) - n += int(unFinishedChunk.Size) - unFinishedChunk = nil - } else { - n, err = data.Read(chunkData[8:]) + chunkData := make([]byte, pc.chunkSize+8) + + var readBytes int + + if unfinishedChunkData != nil { + copy(chunkData, unfinishedChunkData) + readBytes += int(unfinishedChunkSize) + unfinishedChunkData = nil + log.Trace("pyramid.chunker: found unfinished chunk", "readBytes", readBytes) } - totalDataSize += n + var res []byte + res, err = ioutil.ReadAll(io.LimitReader(pc.reader, int64(len(chunkData)-(8+readBytes)))) + + // hack for ioutil.ReadAll: + // a successful call to ioutil.ReadAll returns err == nil, not err == EOF, whereas we + // want to propagate the io.EOF error + if len(res) == 0 && err == nil { + err = io.EOF + } + copy(chunkData[8+readBytes:], res) + + readBytes += len(res) + log.Trace("pyramid.chunker: copied all data", "readBytes", readBytes) + if err != nil { if err == io.EOF || err == io.ErrUnexpectedEOF { - if parent.branchCount == 1 { + + pc.cleanChunkLevels() + + // Check if we are appending or the chunk is the only one. + if parent.branchCount == 1 && (pc.depth() == 0 || isAppend) { // Data is exactly one chunk.. pick the last chunk key as root chunkWG.Wait() - lastChunksKey := parent.chunk[8 : 8+self.hashSize] - copy(rootKey, lastChunksKey) + lastChunksKey := parent.chunk[8 : 8+pc.hashSize] + copy(pc.rootKey, lastChunksKey) break } } else { - close(quitC) + close(pc.quitC) break } } // Data ended in chunk boundary.. just signal to start bulding tree - if n == 0 { - self.buildTree(isAppend, chunkLevel, parent, chunkWG, jobC, quitC, true, rootKey) + if readBytes == 0 { + pc.buildTree(isAppend, parent, chunkWG, true, nil) break } else { - - pkey := self.enqueueDataChunk(chunkData, uint64(n), parent, chunkWG, jobC, quitC) + pkey := pc.enqueueDataChunk(chunkData, uint64(readBytes), parent, chunkWG) // update tree related parent data structures - parent.subtreeSize += uint64(n) + parent.subtreeSize += uint64(readBytes) parent.branchCount++ // Data got exhausted... signal to send any parent tree related chunks - if int64(n) < self.chunkSize { + if int64(readBytes) < pc.chunkSize { + + pc.cleanChunkLevels() // only one data chunk .. so dont add any parent chunk if parent.branchCount <= 1 { chunkWG.Wait() - copy(rootKey, pkey) + + if isAppend || pc.depth() == 0 { + // No need to build the tree if the depth is 0 + // or we are appending. + // Just use the last key. + copy(pc.rootKey, pkey) + } else { + // We need to build the tree and and provide the lonely + // chunk key to replace the last tree chunk key. + pc.buildTree(isAppend, parent, chunkWG, true, pkey) + } break } - self.buildTree(isAppend, chunkLevel, parent, chunkWG, jobC, quitC, true, rootKey) + pc.buildTree(isAppend, parent, chunkWG, true, nil) break } - if parent.branchCount == self.branches { - self.buildTree(isAppend, chunkLevel, parent, chunkWG, jobC, quitC, false, rootKey) - parent = NewTreeEntry(self) + if parent.branchCount == pc.branches { + pc.buildTree(isAppend, parent, chunkWG, false, nil) + parent = NewTreeEntry(pc) } } - workers := self.getWorkerCount() - if int64(len(jobC)) > workers && workers < ChunkProcessors { - if processorWG != nil { - processorWG.Add(1) - } - self.incrementWorkerCount() - go self.processor(self.workerCount, jobC, chunkC, errC, quitC, storageWG, processorWG) + workers := pc.getWorkerCount() + if int64(len(pc.jobC)) > workers && workers < ChunkProcessors { + pc.incrementWorkerCount() + go pc.processor(pc.workerCount) } } } -func (self *PyramidChunker) buildTree(isAppend bool, chunkLevel [][]*TreeEntry, ent *TreeEntry, chunkWG *sync.WaitGroup, jobC chan *chunkJob, quitC chan bool, last bool, rootKey []byte) { +func (pc *PyramidChunker) buildTree(isAppend bool, ent *TreeEntry, chunkWG *sync.WaitGroup, last bool, lonelyChunkKey []byte) { chunkWG.Wait() - self.enqueueTreeChunk(chunkLevel, ent, chunkWG, jobC, quitC, last) + pc.enqueueTreeChunk(ent, chunkWG, last) compress := false - endLvl := self.branches - for lvl := int64(0); lvl < self.branches; lvl++ { - lvlCount := int64(len(chunkLevel[lvl])) - if lvlCount >= self.branches { + endLvl := pc.branches + for lvl := int64(0); lvl < pc.branches; lvl++ { + lvlCount := int64(len(pc.chunkLevel[lvl])) + if lvlCount >= pc.branches { endLvl = lvl + 1 compress = true break @@ -521,42 +555,42 @@ func (self *PyramidChunker) buildTree(isAppend bool, chunkLevel [][]*TreeEntry, for lvl := int64(ent.level); lvl < endLvl; lvl++ { - lvlCount := int64(len(chunkLevel[lvl])) + lvlCount := int64(len(pc.chunkLevel[lvl])) if lvlCount == 1 && last { - copy(rootKey, chunkLevel[lvl][0].key) + copy(pc.rootKey, pc.chunkLevel[lvl][0].key) return } - for startCount := int64(0); startCount < lvlCount; startCount += self.branches { + for startCount := int64(0); startCount < lvlCount; startCount += pc.branches { - endCount := startCount + self.branches + endCount := startCount + pc.branches if endCount > lvlCount { endCount = lvlCount } var nextLvlCount int64 var tempEntry *TreeEntry - if len(chunkLevel[lvl+1]) > 0 { - nextLvlCount = int64(len(chunkLevel[lvl+1]) - 1) - tempEntry = chunkLevel[lvl+1][nextLvlCount] + if len(pc.chunkLevel[lvl+1]) > 0 { + nextLvlCount = int64(len(pc.chunkLevel[lvl+1]) - 1) + tempEntry = pc.chunkLevel[lvl+1][nextLvlCount] } if isAppend && tempEntry != nil && tempEntry.updatePending { updateEntry := &TreeEntry{ level: int(lvl + 1), branchCount: 0, subtreeSize: 0, - chunk: make([]byte, self.chunkSize+8), - key: make([]byte, self.hashSize), + chunk: make([]byte, pc.chunkSize+8), + key: make([]byte, pc.hashSize), index: int(nextLvlCount), updatePending: true, } for index := int64(0); index < lvlCount; index++ { updateEntry.branchCount++ - updateEntry.subtreeSize += chunkLevel[lvl][index].subtreeSize - copy(updateEntry.chunk[8+(index*self.hashSize):8+((index+1)*self.hashSize)], chunkLevel[lvl][index].key[:self.hashSize]) + updateEntry.subtreeSize += pc.chunkLevel[lvl][index].subtreeSize + copy(updateEntry.chunk[8+(index*pc.hashSize):8+((index+1)*pc.hashSize)], pc.chunkLevel[lvl][index].key[:pc.hashSize]) } - self.enqueueTreeChunk(chunkLevel, updateEntry, chunkWG, jobC, quitC, last) + pc.enqueueTreeChunk(updateEntry, chunkWG, last) } else { @@ -565,21 +599,27 @@ func (self *PyramidChunker) buildTree(isAppend bool, chunkLevel [][]*TreeEntry, level: int(lvl + 1), branchCount: noOfBranches, subtreeSize: 0, - chunk: make([]byte, (noOfBranches*self.hashSize)+8), - key: make([]byte, self.hashSize), + chunk: make([]byte, (noOfBranches*pc.hashSize)+8), + key: make([]byte, pc.hashSize), index: int(nextLvlCount), updatePending: false, } index := int64(0) for i := startCount; i < endCount; i++ { - entry := chunkLevel[lvl][i] + entry := pc.chunkLevel[lvl][i] newEntry.subtreeSize += entry.subtreeSize - copy(newEntry.chunk[8+(index*self.hashSize):8+((index+1)*self.hashSize)], entry.key[:self.hashSize]) + copy(newEntry.chunk[8+(index*pc.hashSize):8+((index+1)*pc.hashSize)], entry.key[:pc.hashSize]) index++ } + // Lonely chunk key is the key of the last chunk that is only one on the last branch. + // In this case, ignore the its tree chunk key and replace it with the lonely chunk key. + if lonelyChunkKey != nil { + // Overwrite the last tree chunk key with the lonely data chunk key. + copy(newEntry.chunk[int64(len(newEntry.chunk))-pc.hashSize:], lonelyChunkKey[:pc.hashSize]) + } - self.enqueueTreeChunk(chunkLevel, newEntry, chunkWG, jobC, quitC, last) + pc.enqueueTreeChunk(newEntry, chunkWG, last) } @@ -588,15 +628,15 @@ func (self *PyramidChunker) buildTree(isAppend bool, chunkLevel [][]*TreeEntry, if !isAppend { chunkWG.Wait() if compress { - chunkLevel[lvl] = nil + pc.chunkLevel[lvl] = nil } } } } -func (self *PyramidChunker) enqueueTreeChunk(chunkLevel [][]*TreeEntry, ent *TreeEntry, chunkWG *sync.WaitGroup, jobC chan *chunkJob, quitC chan bool, last bool) { - if ent != nil { +func (pc *PyramidChunker) enqueueTreeChunk(ent *TreeEntry, chunkWG *sync.WaitGroup, last bool) { + if ent != nil && ent.branchCount > 0 { // wait for data chunks to get over before processing the tree chunk if last { @@ -604,34 +644,57 @@ func (self *PyramidChunker) enqueueTreeChunk(chunkLevel [][]*TreeEntry, ent *Tre } binary.LittleEndian.PutUint64(ent.chunk[:8], ent.subtreeSize) - ent.key = make([]byte, self.hashSize) + ent.key = make([]byte, pc.hashSize) chunkWG.Add(1) select { - case jobC <- &chunkJob{ent.key, ent.chunk[:ent.branchCount*self.hashSize+8], int64(ent.subtreeSize), chunkWG, TreeChunk, 0}: - case <-quitC: + case pc.jobC <- &chunkJob{ent.key, ent.chunk[:ent.branchCount*pc.hashSize+8], chunkWG}: + case <-pc.quitC: } // Update or append based on weather it is a new entry or being reused if ent.updatePending { chunkWG.Wait() - chunkLevel[ent.level][ent.index] = ent + pc.chunkLevel[ent.level][ent.index] = ent } else { - chunkLevel[ent.level] = append(chunkLevel[ent.level], ent) + pc.chunkLevel[ent.level] = append(pc.chunkLevel[ent.level], ent) } } } -func (self *PyramidChunker) enqueueDataChunk(chunkData []byte, size uint64, parent *TreeEntry, chunkWG *sync.WaitGroup, jobC chan *chunkJob, quitC chan bool) Key { +func (pc *PyramidChunker) enqueueDataChunk(chunkData []byte, size uint64, parent *TreeEntry, chunkWG *sync.WaitGroup) Address { binary.LittleEndian.PutUint64(chunkData[:8], size) - pkey := parent.chunk[8+parent.branchCount*self.hashSize : 8+(parent.branchCount+1)*self.hashSize] + pkey := parent.chunk[8+parent.branchCount*pc.hashSize : 8+(parent.branchCount+1)*pc.hashSize] chunkWG.Add(1) select { - case jobC <- &chunkJob{pkey, chunkData[:size+8], int64(size), chunkWG, DataChunk, -1}: - case <-quitC: + case pc.jobC <- &chunkJob{pkey, chunkData[:size+8], chunkWG}: + case <-pc.quitC: } return pkey } + +// depth returns the number of chunk levels. +// It is used to detect if there is only one data chunk +// left for the last branch. +func (pc *PyramidChunker) depth() (d int) { + for _, l := range pc.chunkLevel { + if l == nil { + return + } + d++ + } + return +} + +// cleanChunkLevels removes gaps (nil levels) between chunk levels +// that are not nil. +func (pc *PyramidChunker) cleanChunkLevels() { + for i, l := range pc.chunkLevel { + if l == nil { + pc.chunkLevel = append(pc.chunkLevel[:i], append(pc.chunkLevel[i+1:], nil)...) + } + } +} diff --git a/swarm/storage/swarmhasher.go b/swarm/storage/swarmhasher.go index 38b86373c5..fae03f0c72 100644 --- a/swarm/storage/swarmhasher.go +++ b/swarm/storage/swarmhasher.go @@ -21,8 +21,9 @@ import ( ) const ( - BMTHash = "BMT" - SHA3Hash = "SHA3" // http://golang.org/pkg/hash/#Hash + BMTHash = "BMT" + SHA3Hash = "SHA3" // http://golang.org/pkg/hash/#Hash + DefaultHash = BMTHash ) type SwarmHash interface { @@ -34,7 +35,7 @@ type HashWithLength struct { hash.Hash } -func (self *HashWithLength) ResetWithLength(length []byte) { - self.Reset() - self.Write(length) +func (h *HashWithLength) ResetWithLength(length []byte) { + h.Reset() + h.Write(length) } diff --git a/swarm/storage/types.go b/swarm/storage/types.go index d35f1f9294..3114ef5767 100644 --- a/swarm/storage/types.go +++ b/swarm/storage/types.go @@ -18,17 +18,23 @@ package storage import ( "bytes" + "context" "crypto" + "crypto/rand" + "encoding/binary" "fmt" "hash" "io" "sync" - "github.com/ethereum/go-ethereum/bmt" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto/sha3" + "github.com/ethereum/go-ethereum/swarm/bmt" ) +const MaxPO = 16 +const KeyLength = 32 + type Hasher func() hash.Hash type SwarmHasher func() SwarmHash @@ -36,48 +42,68 @@ type SwarmHasher func() SwarmHash // should probably not be here? but network should wrap chunk object type Peer interface{} -type Key []byte +type Address []byte -func (x Key) Size() uint { - return uint(len(x)) +func (a Address) Size() uint { + return uint(len(a)) } -func (x Key) isEqual(y Key) bool { - return bytes.Equal(x, y) +func (a Address) isEqual(y Address) bool { + return bytes.Equal(a, y) } -func (h Key) bits(i, j uint) uint { +func (a Address) bits(i, j uint) uint { ii := i >> 3 jj := i & 7 - if ii >= h.Size() { + if ii >= a.Size() { return 0 } if jj+j <= 8 { - return uint((h[ii] >> jj) & ((1 << j) - 1)) + return uint((a[ii] >> jj) & ((1 << j) - 1)) } - res := uint(h[ii] >> jj) + res := uint(a[ii] >> jj) jj = 8 - jj j -= jj for j != 0 { ii++ if j < 8 { - res += uint(h[ii]&((1< len(one) { + b = len(one) + } + m := 8 + for i := 0; i < b; i++ { + oxo := one[i] ^ other[i] + if i == b-1 { + m = MaxPO % 8 + } + for j := 0; j < m; j++ { + if (oxo>>uint8(7-j))&0x01 != 0 { + return i*8 + j + } + } + } + return MaxPO } -var ZeroKey = Key(common.Hash{}.Bytes()) +func IsZeroAddr(addr Address) bool { + return len(addr) == 0 || bytes.Equal(addr, ZeroAddr) +} + +var ZeroAddr = Address(common.Hash{}.Bytes()) func MakeHashFunc(hash string) SwarmHasher { switch hash { @@ -88,59 +114,56 @@ func MakeHashFunc(hash string) SwarmHasher { case "BMT": return func() SwarmHash { hasher := sha3.NewKeccak256 - pool := bmt.NewTreePool(hasher, bmt.DefaultSegmentCount, bmt.DefaultPoolSize) + pool := bmt.NewTreePool(hasher, bmt.SegmentCount, bmt.PoolSize) return bmt.New(pool) } } return nil } -func (key Key) Hex() string { - return fmt.Sprintf("%064x", []byte(key[:])) +func (a Address) Hex() string { + return fmt.Sprintf("%064x", []byte(a[:])) } -func (key Key) Log() string { - if len(key[:]) < 4 { - return fmt.Sprintf("%x", []byte(key[:])) +func (a Address) Log() string { + if len(a[:]) < 8 { + return fmt.Sprintf("%x", []byte(a[:])) } - return fmt.Sprintf("%08x", []byte(key[:4])) + return fmt.Sprintf("%016x", []byte(a[:8])) } -func (key Key) String() string { - return fmt.Sprintf("%064x", []byte(key)[:]) +func (a Address) String() string { + return fmt.Sprintf("%064x", []byte(a)[:]) } -func (key Key) MarshalJSON() (out []byte, err error) { - return []byte(`"` + key.String() + `"`), nil +func (a Address) MarshalJSON() (out []byte, err error) { + return []byte(`"` + a.String() + `"`), nil } -func (key *Key) UnmarshalJSON(value []byte) error { +func (a *Address) UnmarshalJSON(value []byte) error { s := string(value) - *key = make([]byte, 32) + *a = make([]byte, 32) h := common.Hex2Bytes(s[1 : len(s)-1]) - copy(*key, h) + copy(*a, h) return nil } -// each chunk when first requested opens a record associated with the request -// next time a request for the same chunk arrives, this record is updated -// this request status keeps track of the request ID-s as well as the requesting -// peers and has a channel that is closed when the chunk is retrieved. Multiple -// local callers can wait on this channel (or combined with a timeout, block with a -// select). -type RequestStatus struct { - Key Key - Source Peer - C chan bool - Requesters map[uint64][]interface{} +type AddressCollection []Address + +func NewAddressCollection(l int) AddressCollection { + return make(AddressCollection, l) } -func newRequestStatus(key Key) *RequestStatus { - return &RequestStatus{ - Key: key, - Requesters: make(map[uint64][]interface{}), - C: make(chan bool), - } +func (c AddressCollection) Len() int { + return len(c) +} + +func (c AddressCollection) Less(i, j int) bool { + return bytes.Compare(c[i], c[j]) == -1 +} + +func (c AddressCollection) Swap(i, j int) { + c[i], c[j] = c[j], c[i] } // Chunk also serves as a request object passed to ChunkStores @@ -149,91 +172,86 @@ func newRequestStatus(key Key) *RequestStatus { // but the size of the subtree encoded in the chunk // 0 if request, to be supplied by the dpa type Chunk struct { - Key Key // always - SData []byte // nil if request, to be supplied by dpa - Size int64 // size of the data covered by the subtree encoded in this chunk - Source Peer // peer - C chan bool // to signal data delivery by the dpa - Req *RequestStatus // request Status needed by netStore - wg *sync.WaitGroup // wg to synchronize - dbStored chan bool // never remove a chunk from memStore before it is written to dbStore + Addr Address // always + SData []byte // nil if request, to be supplied by dpa + Size int64 // size of the data covered by the subtree encoded in this chunk + //Source Peer // peer + C chan bool // to signal data delivery by the dpa + ReqC chan bool // to signal the request done + dbStoredC chan bool // never remove a chunk from memStore before it is written to dbStore + dbStored bool + dbStoredMu *sync.Mutex + errored error // flag which is set when the chunk request has errored or timeouted + erroredMu sync.Mutex } -func NewChunk(key Key, rs *RequestStatus) *Chunk { - return &Chunk{Key: key, Req: rs} +func (c *Chunk) SetErrored(err error) { + c.erroredMu.Lock() + defer c.erroredMu.Unlock() + + c.errored = err } -/* -The ChunkStore interface is implemented by : +func (c *Chunk) GetErrored() error { + c.erroredMu.Lock() + defer c.erroredMu.Unlock() -- MemStore: a memory cache -- DbStore: local disk/db store -- LocalStore: a combination (sequence of) memStore and dbStore -- NetStore: cloud storage abstraction layer -- DPA: local requests for swarm storage and retrieval -*/ -type ChunkStore interface { - Put(*Chunk) // effectively there is no error even if there is an error - Get(Key) (*Chunk, error) - Close() + return c.errored } -/* -Chunker is the interface to a component that is responsible for disassembling and assembling larger data and indended to be the dependency of a DPA storage system with fixed maximum chunksize. - -It relies on the underlying chunking model. - -When calling Split, the caller provides a channel (chan *Chunk) on which it receives chunks to store. The DPA delegates to storage layers (implementing ChunkStore interface). - -Split returns an error channel, which the caller can monitor. -After getting notified that all the data has been split (the error channel is closed), the caller can safely read or save the root key. Optionally it times out if not all chunks get stored or not the entire stream of data has been processed. By inspecting the errc channel the caller can check if any explicit errors (typically IO read/write failures) occurred during splitting. - -When calling Join with a root key, the caller gets returned a seekable lazy reader. The caller again provides a channel on which the caller receives placeholder chunks with missing data. The DPA is supposed to forward this to the chunk stores and notify the chunker if the data has been delivered (i.e. retrieved from memory cache, disk-persisted db or cloud based swarm delivery). As the seekable reader is used, the chunker then puts these together the relevant parts on demand. -*/ -type Splitter interface { - /* - When splitting, data is given as a SectionReader, and the key is a hashSize long byte slice (Key), the root hash of the entire content will fill this once processing finishes. - New chunks to store are coming to caller via the chunk storage channel, which the caller provides. - wg is a Waitgroup (can be nil) that can be used to block until the local storage finishes - The caller gets returned an error channel, if an error is encountered during splitting, it is fed to errC error channel. - A closed error signals process completion at which point the key can be considered final if there were no errors. - */ - Split(io.Reader, int64, chan *Chunk, *sync.WaitGroup, *sync.WaitGroup) (Key, error) - - /* This is the first step in making files mutable (not chunks).. - Append allows adding more data chunks to the end of the already existsing file. - The key for the root chunk is supplied to load the respective tree. - Rest of the parameters behave like Split. - */ - Append(Key, io.Reader, chan *Chunk, *sync.WaitGroup, *sync.WaitGroup) (Key, error) +func NewChunk(addr Address, reqC chan bool) *Chunk { + return &Chunk{ + Addr: addr, + ReqC: reqC, + dbStoredC: make(chan bool), + dbStoredMu: &sync.Mutex{}, + } } -type Joiner interface { - /* - Join reconstructs original content based on a root key. - When joining, the caller gets returned a Lazy SectionReader, which is - seekable and implements on-demand fetching of chunks as and where it is read. - New chunks to retrieve are coming to caller via the Chunk channel, which the caller provides. - If an error is encountered during joining, it appears as a reader error. - The SectionReader. - As a result, partial reads from a document are possible even if other parts - are corrupt or lost. - The chunks are not meant to be validated by the chunker when joining. This - is because it is left to the DPA to decide which sources are trusted. - */ - Join(key Key, chunkC chan *Chunk) LazySectionReader +func (c *Chunk) markAsStored() { + c.dbStoredMu.Lock() + defer c.dbStoredMu.Unlock() + + if !c.dbStored { + close(c.dbStoredC) + c.dbStored = true + } } -type Chunker interface { - Joiner - Splitter - // returns the key length - // KeySize() int64 +func (c *Chunk) WaitToStore() error { + <-c.dbStoredC + return c.GetErrored() +} + +func GenerateRandomChunk(dataSize int64) *Chunk { + return GenerateRandomChunks(dataSize, 1)[0] +} + +func GenerateRandomChunks(dataSize int64, count int) (chunks []*Chunk) { + var i int + hasher := MakeHashFunc(DefaultHash)() + if dataSize > DefaultChunkSize { + dataSize = DefaultChunkSize + } + + for i = 0; i < count; i++ { + chunks = append(chunks, NewChunk(nil, nil)) + chunks[i].SData = make([]byte, dataSize+8) + rand.Read(chunks[i].SData) + binary.LittleEndian.PutUint64(chunks[i].SData[:8], uint64(dataSize)) + hasher.ResetWithLength(chunks[i].SData[:8]) + hasher.Write(chunks[i].SData[8:]) + chunks[i].Addr = make([]byte, 32) + copy(chunks[i].Addr, hasher.Sum(nil)) + } + + return chunks } // Size, Seek, Read, ReadAt type LazySectionReader interface { - Size(chan bool) (int64, error) + Context() context.Context + Size(context.Context, chan bool) (int64, error) io.Seeker io.Reader io.ReaderAt @@ -243,6 +261,94 @@ type LazyTestSectionReader struct { *io.SectionReader } -func (self *LazyTestSectionReader) Size(chan bool) (int64, error) { - return self.SectionReader.Size(), nil +func (r *LazyTestSectionReader) Size(context.Context, chan bool) (int64, error) { + return r.SectionReader.Size(), nil +} + +func (r *LazyTestSectionReader) Context() context.Context { + return context.TODO() +} + +type StoreParams struct { + Hash SwarmHasher `toml:"-"` + DbCapacity uint64 + CacheCapacity uint + ChunkRequestsCacheCapacity uint + BaseKey []byte +} + +func NewDefaultStoreParams() *StoreParams { + return NewStoreParams(defaultLDBCapacity, defaultCacheCapacity, defaultChunkRequestsCacheCapacity, nil, nil) +} + +func NewStoreParams(ldbCap uint64, cacheCap uint, requestsCap uint, hash SwarmHasher, basekey []byte) *StoreParams { + if basekey == nil { + basekey = make([]byte, 32) + } + if hash == nil { + hash = MakeHashFunc(DefaultHash) + } + return &StoreParams{ + Hash: hash, + DbCapacity: ldbCap, + CacheCapacity: cacheCap, + ChunkRequestsCacheCapacity: requestsCap, + BaseKey: basekey, + } +} + +type ChunkData []byte + +type Reference []byte + +// Putter is responsible to store data and create a reference for it +type Putter interface { + Put(context.Context, ChunkData) (Reference, error) + // RefSize returns the length of the Reference created by this Putter + RefSize() int64 + // Close is to indicate that no more chunk data will be Put on this Putter + Close() + // Wait returns if all data has been store and the Close() was called. + Wait(context.Context) error +} + +// Getter is an interface to retrieve a chunk's data by its reference +type Getter interface { + Get(context.Context, Reference) (ChunkData, error) +} + +// NOTE: this returns invalid data if chunk is encrypted +func (c ChunkData) Size() int64 { + return int64(binary.LittleEndian.Uint64(c[:8])) +} + +func (c ChunkData) Data() []byte { + return c[8:] +} + +type ChunkValidator interface { + Validate(addr Address, data []byte) bool +} + +// Provides method for validation of content address in chunks +// Holds the corresponding hasher to create the address +type ContentAddressValidator struct { + Hasher SwarmHasher +} + +// Constructor +func NewContentAddressValidator(hasher SwarmHasher) *ContentAddressValidator { + return &ContentAddressValidator{ + Hasher: hasher, + } +} + +// Validate that the given key is a valid content address for the given data +func (v *ContentAddressValidator) Validate(addr Address, data []byte) bool { + hasher := v.Hasher() + hasher.ResetWithLength(data[:8]) + hasher.Write(data[8:]) + hash := hasher.Sum(nil) + + return bytes.Equal(hash, addr[:]) } diff --git a/swarm/swarm.go b/swarm/swarm.go index 0a120db1fa..db7d2dfedc 100644 --- a/swarm/swarm.go +++ b/swarm/swarm.go @@ -21,8 +21,10 @@ import ( "context" "crypto/ecdsa" "fmt" + "io" "math/big" "net" + "path/filepath" "strings" "time" "unicode" @@ -31,20 +33,25 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/contracts/chequebook" "github.com/ethereum/go-ethereum/contracts/ens" - "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethclient" - "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/metrics" - "github.com/ethereum/go-ethereum/node" "github.com/ethereum/go-ethereum/p2p" "github.com/ethereum/go-ethereum/p2p/discover" + "github.com/ethereum/go-ethereum/p2p/protocols" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rpc" "github.com/ethereum/go-ethereum/swarm/api" httpapi "github.com/ethereum/go-ethereum/swarm/api/http" "github.com/ethereum/go-ethereum/swarm/fuse" + "github.com/ethereum/go-ethereum/swarm/log" "github.com/ethereum/go-ethereum/swarm/network" + "github.com/ethereum/go-ethereum/swarm/network/stream" + "github.com/ethereum/go-ethereum/swarm/pss" + "github.com/ethereum/go-ethereum/swarm/state" "github.com/ethereum/go-ethereum/swarm/storage" + "github.com/ethereum/go-ethereum/swarm/storage/mock" + "github.com/ethereum/go-ethereum/swarm/storage/mru" + "github.com/ethereum/go-ethereum/swarm/tracing" ) var ( @@ -53,31 +60,30 @@ var ( startCounter = metrics.NewRegisteredCounter("stack,start", nil) stopCounter = metrics.NewRegisteredCounter("stack,stop", nil) uptimeGauge = metrics.NewRegisteredGauge("stack.uptime", nil) - dbSizeGauge = metrics.NewRegisteredGauge("storage.db.chunks.size", nil) - cacheSizeGauge = metrics.NewRegisteredGauge("storage.db.cache.size", nil) + requestsCacheGauge = metrics.NewRegisteredGauge("storage.cache.requests.size", nil) ) // the swarm stack type Swarm struct { - config *api.Config // swarm configuration - api *api.Api // high level api layer (fs/manifest) - dns api.Resolver // DNS registrar - dbAccess *network.DbAccess // access to local chunk db iterator and storage counter - storage storage.ChunkStore // internal access to storage, common interface to cloud storage backends - dpa *storage.DPA // distributed preimage archive, the local API to the storage with document level storage/retrieval support - depo network.StorageHandler // remote request handler, interface between bzz protocol and the storage - cloud storage.CloudStore // procurement, cloud storage backend (can multi-cloud) - hive *network.Hive // the logistic manager - backend chequebook.Backend // simple blockchain Backend + config *api.Config // swarm configuration + api *api.API // high level api layer (fs/manifest) + dns api.Resolver // DNS registrar + fileStore *storage.FileStore // distributed preimage archive, the local API to the storage with document level storage/retrieval support + streamer *stream.Registry + bzz *network.Bzz // the logistic manager + backend chequebook.Backend // simple blockchain Backend privateKey *ecdsa.PrivateKey corsString string swapEnabled bool lstore *storage.LocalStore // local store, needs to store for releasing resources after node stopped sfs *fuse.SwarmFS // need this to cleanup all the active mounts on node exit + ps *pss.Pss + + tracerClose io.Closer } type SwarmAPI struct { - Api *api.Api + Api *api.API Backend chequebook.Backend PrvKey *ecdsa.PrivateKey } @@ -92,77 +98,130 @@ func (self *Swarm) API() *SwarmAPI { // creates a new swarm service instance // implements node.Service -func NewSwarm(ctx *node.ServiceContext, backend chequebook.Backend, config *api.Config) (self *Swarm, err error) { - if bytes.Equal(common.FromHex(config.PublicKey), storage.ZeroKey) { +// If mockStore is not nil, it will be used as the storage for chunk data. +// MockStore should be used only for testing. +func NewSwarm(config *api.Config, mockStore *mock.NodeStore) (self *Swarm, err error) { + + if bytes.Equal(common.FromHex(config.PublicKey), storage.ZeroAddr) { return nil, fmt.Errorf("empty public key") } - if bytes.Equal(common.FromHex(config.BzzKey), storage.ZeroKey) { + if bytes.Equal(common.FromHex(config.BzzKey), storage.ZeroAddr) { return nil, fmt.Errorf("empty bzz key") } + var backend chequebook.Backend + if config.SwapAPI != "" && config.SwapEnabled { + log.Info("connecting to SWAP API", "url", config.SwapAPI) + backend, err = ethclient.Dial(config.SwapAPI) + if err != nil { + return nil, fmt.Errorf("error connecting to SWAP API %s: %s", config.SwapAPI, err) + } + } + self = &Swarm{ - config: config, - swapEnabled: config.SwapEnabled, - backend: backend, - privateKey: config.Swap.PrivateKey(), - corsString: config.Cors, + config: config, + backend: backend, + privateKey: config.ShiftPrivateKey(), } log.Debug(fmt.Sprintf("Setting up Swarm service components")) - hash := storage.MakeHashFunc(config.ChunkerParams.Hash) - self.lstore, err = storage.NewLocalStore(hash, config.StoreParams) + config.HiveParams.Discovery = true + + log.Debug(fmt.Sprintf("-> swarm net store shared access layer to Swarm Chunk Store")) + + nodeID, err := discover.HexID(config.NodeID) + if err != nil { + return nil, err + } + addr := &network.BzzAddr{ + OAddr: common.FromHex(config.BzzKey), + UAddr: []byte(discover.NewNode(nodeID, net.IP{127, 0, 0, 1}, 30303, 30303).String()), + } + + bzzconfig := &network.BzzConfig{ + NetworkID: config.NetworkID, + OverlayAddr: addr.OAddr, + UnderlayAddr: addr.UAddr, + HiveParams: config.HiveParams, + } + + stateStore, err := state.NewDBStore(filepath.Join(config.Path, "state-store.db")) if err != nil { return } - // setup local store - log.Debug(fmt.Sprintf("Set up local storage")) - - self.dbAccess = network.NewDbAccess(self.lstore) - log.Debug(fmt.Sprintf("Set up local db access (iterator/counter)")) - - // set up the kademlia hive - self.hive = network.NewHive( - common.HexToHash(self.config.BzzKey), // key to hive (kademlia base address) - config.HiveParams, // configuration parameters - config.SwapEnabled, // SWAP enabled - config.SyncEnabled, // syncronisation enabled - ) - log.Debug(fmt.Sprintf("Set up swarm network with Kademlia hive")) - - // setup cloud storage backend - self.cloud = network.NewForwarder(self.hive) - log.Debug(fmt.Sprintf("-> set swarm forwarder as cloud storage backend")) - - // setup cloud storage internal access layer - self.storage = storage.NewNetStore(hash, self.lstore, self.cloud, config.StoreParams) - log.Debug(fmt.Sprintf("-> swarm net store shared access layer to Swarm Chunk Store")) - - // set up Depo (storage handler = cloud storage access layer for incoming remote requests) - self.depo = network.NewDepo(hash, self.lstore, self.storage) - log.Debug(fmt.Sprintf("-> REmote Access to CHunks")) - - // set up DPA, the cloud storage local access layer - dpaChunkStore := storage.NewDpaChunkStore(self.lstore, self.storage) - log.Debug(fmt.Sprintf("-> Local Access to Swarm")) - // Swarm Hash Merklised Chunking for Arbitrary-length Document/File storage - self.dpa = storage.NewDPA(dpaChunkStore, self.config.ChunkerParams) - log.Debug(fmt.Sprintf("-> Content Store API")) - + // set up high level api + var resolver *api.MultiResolver if len(config.EnsAPIs) > 0 { opts := []api.MultiResolverOption{} for _, c := range config.EnsAPIs { tld, endpoint, addr := parseEnsAPIAddress(c) - r, err := newEnsClient(endpoint, addr, config) + r, err := newEnsClient(endpoint, addr, config, self.privateKey) if err != nil { return nil, err } opts = append(opts, api.MultiResolverOptionWithResolver(r, tld)) + } - self.dns = api.NewMultiResolver(opts...) + resolver = api.NewMultiResolver(opts...) + self.dns = resolver } - self.api = api.NewApi(self.dpa, self.dns) + self.lstore, err = storage.NewLocalStore(config.LocalStoreParams, mockStore) + if err != nil { + return + } + + db := storage.NewDBAPI(self.lstore) + to := network.NewKademlia( + common.FromHex(config.BzzKey), + network.NewKadParams(), + ) + delivery := stream.NewDelivery(to, db) + + self.streamer = stream.NewRegistry(addr, delivery, db, stateStore, &stream.RegistryOptions{ + SkipCheck: config.DeliverySkipCheck, + DoSync: config.SyncEnabled, + DoRetrieve: true, + SyncUpdateDelay: config.SyncUpdateDelay, + }) + + // set up NetStore, the cloud storage local access layer + netStore := storage.NewNetStore(self.lstore, self.streamer.Retrieve) + // Swarm Hash Merklised Chunking for Arbitrary-length Document/File storage + self.fileStore = storage.NewFileStore(netStore, self.config.FileStoreParams) + + var resourceHandler *mru.Handler + rhparams := &mru.HandlerParams{} + + resourceHandler, err = mru.NewHandler(rhparams) + if err != nil { + return nil, err + } + resourceHandler.SetStore(netStore) + + var validators []storage.ChunkValidator + validators = append(validators, storage.NewContentAddressValidator(storage.MakeHashFunc(storage.DefaultHash))) + if resourceHandler != nil { + validators = append(validators, resourceHandler) + } + self.lstore.Validators = validators + + // setup local store + log.Debug(fmt.Sprintf("Set up local storage")) + + self.bzz = network.NewBzz(bzzconfig, to, stateStore, stream.Spec, self.streamer.Run) + + // Pss = postal service over swarm (devp2p over bzz) + self.ps, err = pss.NewPss(to, config.Pss) + if err != nil { + return nil, err + } + if pss.IsActiveHandshake { + pss.SetHandshakeController(self.ps, pss.NewHandshakeParams()) + } + + self.api = api.NewAPI(self.fileStore, self.dns, resourceHandler) // Manifests for Smart Hosting log.Debug(fmt.Sprintf("-> Web3 virtual server API")) @@ -198,16 +257,22 @@ func parseEnsAPIAddress(s string) (tld, endpoint string, addr common.Address) { return } +// ensClient provides functionality for api.ResolveValidator +type ensClient struct { + *ens.ENS + *ethclient.Client +} + // newEnsClient creates a new ENS client for that is a consumer of // a ENS API on a specific endpoint. It is used as a helper function // for creating multiple resolvers in NewSwarm function. -func newEnsClient(endpoint string, addr common.Address, config *api.Config) (*ens.ENS, error) { +func newEnsClient(endpoint string, addr common.Address, config *api.Config, privkey *ecdsa.PrivateKey) (*ensClient, error) { log.Info("connecting to ENS API", "url", endpoint) client, err := rpc.Dial(endpoint) if err != nil { return nil, fmt.Errorf("error connecting to ENS API %s: %s", endpoint, err) } - ensClient := ethclient.NewClient(client) + ethClient := ethclient.NewClient(client) ensRoot := config.EnsRoot if addr != (common.Address{}) { @@ -220,13 +285,16 @@ func newEnsClient(endpoint string, addr common.Address, config *api.Config) (*en log.Warn(fmt.Sprintf("could not determine ENS contract address, using default %s", ensRoot), "err", err) } } - transactOpts := bind.NewKeyedTransactor(config.Swap.PrivateKey()) - dns, err := ens.NewENS(transactOpts, ensRoot, ensClient) + transactOpts := bind.NewKeyedTransactor(privkey) + dns, err := ens.NewENS(transactOpts, ensRoot, ethClient) if err != nil { return nil, err } log.Debug(fmt.Sprintf("-> Swarm Domain Name Registrar %v @ address %v", endpoint, ensRoot.Hex())) - return dns, err + return &ensClient{ + ENS: dns, + Client: ethClient, + }, err } // detectEnsAddr determines the ENS contract address by getting both the @@ -274,16 +342,14 @@ Start is called when the stack is started // implements the node.Service interface func (self *Swarm) Start(srv *p2p.Server) error { startTime = time.Now() - connectPeer := func(url string) error { - node, err := discover.ParseNode(url) - if err != nil { - return fmt.Errorf("invalid node URL: %v", err) - } - srv.AddPeer(node) - return nil - } + + self.tracerClose = tracing.Closer + + // update uaddr to correct enode + newaddr := self.bzz.UpdateLocalAddr([]byte(srv.Self().String())) + log.Warn("Updated bzz local addr", "oaddr", fmt.Sprintf("%x", newaddr.OAddr), "uaddr", fmt.Sprintf("%s", newaddr.UAddr)) // set chequebook - if self.swapEnabled { + if self.config.SwapEnabled { ctx := context.Background() // The initial setup has no deadline. err := self.SetChequebook(ctx) if err != nil { @@ -295,33 +361,37 @@ func (self *Swarm) Start(srv *p2p.Server) error { } log.Warn(fmt.Sprintf("Starting Swarm service")) - self.hive.Start( - discover.PubkeyID(&srv.PrivateKey.PublicKey), - func() string { return srv.ListenAddr }, - connectPeer, - ) - log.Info(fmt.Sprintf("Swarm network started on bzz address: %v", self.hive.Addr())) - self.dpa.Start() - log.Debug(fmt.Sprintf("Swarm DPA started")) + err := self.bzz.Start(srv) + if err != nil { + log.Error("bzz failed", "err", err) + return err + } + log.Info(fmt.Sprintf("Swarm network started on bzz address: %x", self.bzz.Hive.Overlay.BaseAddr())) + + if self.ps != nil { + self.ps.Start(srv) + log.Info("Pss started") + } // start swarm http proxy server if self.config.Port != "" { addr := net.JoinHostPort(self.config.ListenAddr, self.config.Port) - go httpapi.StartHttpServer(self.api, &httpapi.ServerConfig{ - Addr: addr, - CorsString: self.corsString, - }) - log.Info(fmt.Sprintf("Swarm http proxy started on %v", addr)) + server := httpapi.NewServer(self.api, self.config.Cors) - if self.corsString != "" { - log.Debug(fmt.Sprintf("Swarm http proxy started with corsdomain: %v", self.corsString)) - } + go server.ListenAndServe(addr) + } + + log.Debug(fmt.Sprintf("Swarm http proxy started on port: %v", self.config.Port)) + + if self.config.Cors != "" { + log.Debug(fmt.Sprintf("Swarm http proxy started with corsdomain: %v", self.config.Cors)) } self.periodicallyUpdateGauges() startCounter.Inc(1) + self.streamer.Start(srv) return nil } @@ -336,16 +406,23 @@ func (self *Swarm) periodicallyUpdateGauges() { } func (self *Swarm) updateGauges() { - dbSizeGauge.Update(int64(self.lstore.DbCounter())) - cacheSizeGauge.Update(int64(self.lstore.CacheCounter())) uptimeGauge.Update(time.Since(startTime).Nanoseconds()) + requestsCacheGauge.Update(int64(self.lstore.RequestsCacheLen())) } // implements the node.Service interface // stops all component services. func (self *Swarm) Stop() error { - self.dpa.Stop() - err := self.hive.Stop() + if self.tracerClose != nil { + err := self.tracerClose.Close() + if err != nil { + return err + } + } + + if self.ps != nil { + self.ps.Stop() + } if ch := self.config.Swap.Chequebook(); ch != nil { ch.Stop() ch.Save() @@ -356,34 +433,45 @@ func (self *Swarm) Stop() error { } self.sfs.Stop() stopCounter.Inc(1) - return err + self.streamer.Stop() + return self.bzz.Stop() } // implements the node.Service interface -func (self *Swarm) Protocols() []p2p.Protocol { - proto, err := network.Bzz(self.depo, self.backend, self.hive, self.dbAccess, self.config.Swap, self.config.SyncParams, self.config.NetworkId) - if err != nil { - return nil +func (self *Swarm) Protocols() (protos []p2p.Protocol) { + protos = append(protos, self.bzz.Protocols()...) + + if self.ps != nil { + protos = append(protos, self.ps.Protocols()...) } - return []p2p.Protocol{proto} + return +} + +func (self *Swarm) RegisterPssProtocol(spec *protocols.Spec, targetprotocol *p2p.Protocol, options *pss.ProtocolParams) (*pss.Protocol, error) { + if !pss.IsActiveProtocol { + return nil, fmt.Errorf("Pss protocols not available (built with !nopssprotocol tag)") + } + topic := pss.ProtocolTopic(spec) + return pss.RegisterProtocol(self.ps, &topic, spec, targetprotocol, options) } // implements node.Service -// Apis returns the RPC Api descriptors the Swarm implementation offers +// APIs returns the RPC API descriptors the Swarm implementation offers func (self *Swarm) APIs() []rpc.API { - return []rpc.API{ + + apis := []rpc.API{ // public APIs { Namespace: "bzz", - Version: "0.1", + Version: "3.0", Service: &Info{self.config, chequebook.ContractParams}, Public: true, }, // admin APIs { Namespace: "bzz", - Version: "0.1", - Service: api.NewControl(self.api, self.hive), + Version: "3.0", + Service: api.NewControl(self.api, self.bzz.Hive), Public: false, }, { @@ -414,9 +502,17 @@ func (self *Swarm) APIs() []rpc.API { }, // {Namespace, Version, api.NewAdmin(self), false}, } + + apis = append(apis, self.bzz.APIs()...) + + if self.ps != nil { + apis = append(apis, self.ps.APIs()...) + } + + return apis } -func (self *Swarm) Api() *api.Api { +func (self *Swarm) Api() *api.API { return self.api } @@ -427,36 +523,9 @@ func (self *Swarm) SetChequebook(ctx context.Context) error { return err } log.Info(fmt.Sprintf("new chequebook set (%v): saving config file, resetting all connections in the hive", self.config.Swap.Contract.Hex())) - self.hive.DropAll() return nil } -// Local swarm without netStore -func NewLocalSwarm(datadir, port string) (self *Swarm, err error) { - - prvKey, err := crypto.GenerateKey() - if err != nil { - return - } - - config := api.NewDefaultConfig() - config.Path = datadir - config.Init(prvKey) - config.Port = port - - dpa, err := storage.NewLocalDPA(datadir) - if err != nil { - return - } - - self = &Swarm{ - api: api.NewApi(dpa, nil), - config: config, - } - - return -} - // serialisable info about swarm type Info struct { *api.Config diff --git a/swarm/swarm_test.go b/swarm/swarm_test.go index 8b1ae28884..0827748ae2 100644 --- a/swarm/swarm_test.go +++ b/swarm/swarm_test.go @@ -17,11 +17,181 @@ package swarm import ( + "context" + "encoding/hex" + "io/ioutil" + "math/rand" + "os" + "path" + "runtime" + "strings" "testing" + "time" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/rpc" + "github.com/ethereum/go-ethereum/swarm/api" ) +// TestNewSwarm validates Swarm fields in repsect to the provided configuration. +func TestNewSwarm(t *testing.T) { + dir, err := ioutil.TempDir("", "swarm") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(dir) + + // a simple rpc endpoint for testing dialing + ipcEndpoint := path.Join(dir, "TestSwarm.ipc") + + // windows namedpipes are not on filesystem but on NPFS + if runtime.GOOS == "windows" { + b := make([]byte, 8) + rand.Read(b) + ipcEndpoint = `\\.\pipe\TestSwarm-` + hex.EncodeToString(b) + } + + _, server, err := rpc.StartIPCEndpoint(ipcEndpoint, nil) + if err != nil { + t.Error(err) + } + defer server.Stop() + + for _, tc := range []struct { + name string + configure func(*api.Config) + check func(*testing.T, *Swarm, *api.Config) + }{ + { + name: "defaults", + configure: nil, + check: func(t *testing.T, s *Swarm, config *api.Config) { + if s.config != config { + t.Error("config is not the same object") + } + if s.backend != nil { + t.Error("backend is not nil") + } + if s.privateKey == nil { + t.Error("private key is not set") + } + if !s.config.HiveParams.Discovery { + t.Error("config.HiveParams.Discovery is false, must be true regardless the configuration") + } + if s.dns != nil { + t.Error("dns initialized, but it should not be") + } + if s.lstore == nil { + t.Error("localstore not initialized") + } + if s.streamer == nil { + t.Error("streamer not initialized") + } + if s.fileStore == nil { + t.Error("fileStore not initialized") + } + if s.lstore.Validators == nil { + t.Error("localstore validators not initialized") + } + if s.bzz == nil { + t.Error("bzz not initialized") + } + if s.ps == nil { + t.Error("pss not initialized") + } + if s.api == nil { + t.Error("api not initialized") + } + if s.sfs == nil { + t.Error("swarm filesystem not initialized") + } + }, + }, + { + name: "with swap", + configure: func(config *api.Config) { + config.SwapAPI = ipcEndpoint + config.SwapEnabled = true + }, + check: func(t *testing.T, s *Swarm, _ *api.Config) { + if s.backend == nil { + t.Error("backend is nil") + } + }, + }, + { + name: "with swap disabled", + configure: func(config *api.Config) { + config.SwapAPI = ipcEndpoint + config.SwapEnabled = false + }, + check: func(t *testing.T, s *Swarm, _ *api.Config) { + if s.backend != nil { + t.Error("backend is not nil") + } + }, + }, + { + name: "with swap enabled and api endpoint blank", + configure: func(config *api.Config) { + config.SwapAPI = "" + config.SwapEnabled = true + }, + check: func(t *testing.T, s *Swarm, _ *api.Config) { + if s.backend != nil { + t.Error("backend is not nil") + } + }, + }, + { + name: "ens", + configure: func(config *api.Config) { + config.EnsAPIs = []string{ + "http://127.0.0.1:8888", + } + }, + check: func(t *testing.T, s *Swarm, _ *api.Config) { + if s.dns == nil { + t.Error("dns is not initialized") + } + }, + }, + } { + t.Run(tc.name, func(t *testing.T) { + config := api.NewConfig() + + dir, err := ioutil.TempDir("", "swarm") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(dir) + + config.Path = dir + + privkey, err := crypto.GenerateKey() + if err != nil { + t.Fatal(err) + } + + config.Init(privkey) + + if tc.configure != nil { + tc.configure(config) + } + + s, err := NewSwarm(config, nil) + if err != nil { + t.Fatal(err) + } + + if tc.check != nil { + tc.check(t, s, config) + } + }) + } +} + func TestParseEnsAPIAddress(t *testing.T) { for _, x := range []struct { description string @@ -117,3 +287,92 @@ func TestParseEnsAPIAddress(t *testing.T) { }) } } + +// TestLocalStoreAndRetrieve runs multiple tests where different size files are uploaded +// to a single Swarm instance using API Store and checked against the content returned +// by API Retrieve function. +// +// This test is intended to validate functionality of chunker store and join functions +// and their intergartion into Swarm, without comparing results with ones produced by +// another chunker implementation, as it is done in swarm/storage tests. +func TestLocalStoreAndRetrieve(t *testing.T) { + config := api.NewConfig() + + dir, err := ioutil.TempDir("", "node") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(dir) + + config.Path = dir + + privkey, err := crypto.GenerateKey() + if err != nil { + t.Fatal(err) + } + + config.Init(privkey) + + swarm, err := NewSwarm(config, nil) + if err != nil { + t.Fatal(err) + } + + // by default, test only the lonely chunk cases + sizes := []int{1, 60, 4097, 524288 + 1, 7*524288 + 1, 128*524288 + 1} + + if *longrunning { + // test broader set of cases if -longruning flag is set + sizes = append(sizes, 83, 179, 253, 1024, 4095, 4096, 8191, 8192, 8193, 12287, 12288, 12289, 123456, 2345678, 67298391, 524288, 524288+4096, 524288+4097, 7*524288, 7*524288+4096, 7*524288+4097, 128*524288, 128*524288+4096, 128*524288+4097, 816778334) + } + for _, n := range sizes { + testLocalStoreAndRetrieve(t, swarm, n, true) + testLocalStoreAndRetrieve(t, swarm, n, false) + } +} + +// testLocalStoreAndRetrieve is using a single Swarm instance, to upload +// a file of length n with optional random data using API Store function, +// and checks the output of API Retrieve function on the same instance. +// This is a regression test for issue +// https://github.com/ethersphere/go-ethereum/issues/639 +// where pyramid chunker did not split correctly files with lengths that +// are edge cases for chunk and tree parameters, depending whether there +// is a tree chunk with only one data chunk and how the compress functionality +// changed the tree. +func testLocalStoreAndRetrieve(t *testing.T, swarm *Swarm, n int, randomData bool) { + slice := make([]byte, n) + if randomData { + rand.Seed(time.Now().UnixNano()) + rand.Read(slice) + } + dataPut := string(slice) + + ctx := context.TODO() + k, wait, err := swarm.api.Store(ctx, strings.NewReader(dataPut), int64(len(dataPut)), false) + if err != nil { + t.Fatal(err) + } + if wait != nil { + err = wait(ctx) + if err != nil { + t.Fatal(err) + } + } + + r, _ := swarm.api.Retrieve(context.TODO(), k) + + d, err := ioutil.ReadAll(r) + if err != nil { + t.Fatal(err) + } + dataGet := string(d) + + if len(dataPut) != len(dataGet) { + t.Fatalf("data not matched: length expected %v, got %v", len(dataPut), len(dataGet)) + } else { + if dataPut != dataGet { + t.Fatal("data not matched") + } + } +} diff --git a/swarm/testutil/http.go b/swarm/testutil/http.go index f2922fab00..238f783088 100644 --- a/swarm/testutil/http.go +++ b/swarm/testutil/http.go @@ -18,55 +18,95 @@ package testutil import ( "io/ioutil" + "net/http" "net/http/httptest" "os" "testing" "github.com/ethereum/go-ethereum/swarm/api" - httpapi "github.com/ethereum/go-ethereum/swarm/api/http" "github.com/ethereum/go-ethereum/swarm/storage" + "github.com/ethereum/go-ethereum/swarm/storage/mru" ) -func NewTestSwarmServer(t *testing.T) *TestSwarmServer { +type TestServer interface { + ServeHTTP(http.ResponseWriter, *http.Request) +} + +// simulated timeProvider +type fakeTimeProvider struct { + currentTime uint64 +} + +func (f *fakeTimeProvider) Tick() { + f.currentTime++ +} + +func (f *fakeTimeProvider) Now() mru.Timestamp { + return mru.Timestamp{Time: f.currentTime} +} + +func NewTestSwarmServer(t *testing.T, serverFunc func(*api.API) TestServer) *TestSwarmServer { dir, err := ioutil.TempDir("", "swarm-storage-test") if err != nil { t.Fatal(err) } - storeparams := &storage.StoreParams{ - ChunkDbPath: dir, - DbCapacity: 5000000, - CacheCapacity: 5000, - Radius: 0, - } - localStore, err := storage.NewLocalStore(storage.MakeHashFunc("SHA3"), storeparams) + storeparams := storage.NewDefaultLocalStoreParams() + storeparams.DbCapacity = 5000000 + storeparams.CacheCapacity = 5000 + storeparams.Init(dir) + localStore, err := storage.NewLocalStore(storeparams, nil) if err != nil { os.RemoveAll(dir) t.Fatal(err) } - chunker := storage.NewTreeChunker(storage.NewChunkerParams()) - dpa := &storage.DPA{ - Chunker: chunker, - ChunkStore: localStore, + fileStore := storage.NewFileStore(localStore, storage.NewFileStoreParams()) + + // mutable resources test setup + resourceDir, err := ioutil.TempDir("", "swarm-resource-test") + if err != nil { + t.Fatal(err) } - dpa.Start() - a := api.NewApi(dpa, nil) - srv := httptest.NewServer(httpapi.NewServer(a)) + + fakeTimeProvider := &fakeTimeProvider{ + currentTime: 42, + } + mru.TimestampProvider = fakeTimeProvider + rhparams := &mru.HandlerParams{} + rh, err := mru.NewTestHandler(resourceDir, rhparams) + if err != nil { + t.Fatal(err) + } + + a := api.NewAPI(fileStore, nil, rh.Handler) + srv := httptest.NewServer(serverFunc(a)) return &TestSwarmServer{ - Server: srv, - Dpa: dpa, - dir: dir, + Server: srv, + FileStore: fileStore, + dir: dir, + Hasher: storage.MakeHashFunc(storage.DefaultHash)(), + timestampProvider: fakeTimeProvider, + cleanup: func() { + srv.Close() + rh.Close() + os.RemoveAll(dir) + os.RemoveAll(resourceDir) + }, } } type TestSwarmServer struct { *httptest.Server - - Dpa *storage.DPA - dir string + Hasher storage.SwarmHash + FileStore *storage.FileStore + dir string + cleanup func() + timestampProvider *fakeTimeProvider } func (t *TestSwarmServer) Close() { - t.Server.Close() - t.Dpa.Stop() - os.RemoveAll(t.dir) + t.cleanup() +} + +func (t *TestSwarmServer) GetCurrentTime() mru.Timestamp { + return t.timestampProvider.Now() } diff --git a/swarm/tracing/tracing.go b/swarm/tracing/tracing.go new file mode 100644 index 0000000000..b84cfb3102 --- /dev/null +++ b/swarm/tracing/tracing.go @@ -0,0 +1,103 @@ +package tracing + +import ( + "io" + "os" + "strings" + "time" + + "github.com/ethereum/go-ethereum/log" + jaeger "github.com/uber/jaeger-client-go" + jaegercfg "github.com/uber/jaeger-client-go/config" + jaegerlog "github.com/uber/jaeger-client-go/log" + cli "gopkg.in/urfave/cli.v1" +) + +var Enabled bool = false + +// TracingEnabledFlag is the CLI flag name to use to enable trace collections. +const TracingEnabledFlag = "tracing" + +var ( + Closer io.Closer +) + +var ( + TracingFlag = cli.BoolFlag{ + Name: TracingEnabledFlag, + Usage: "Enable tracing", + } + TracingEndpointFlag = cli.StringFlag{ + Name: "tracing.endpoint", + Usage: "Tracing endpoint", + Value: "0.0.0.0:6831", + } + TracingSvcFlag = cli.StringFlag{ + Name: "tracing.svc", + Usage: "Tracing service name", + Value: "swarm", + } +) + +// Flags holds all command-line flags required for tracing collection. +var Flags = []cli.Flag{ + TracingFlag, + TracingEndpointFlag, + TracingSvcFlag, +} + +// Init enables or disables the open tracing system. +func init() { + for _, arg := range os.Args { + if flag := strings.TrimLeft(arg, "-"); flag == TracingEnabledFlag { + Enabled = true + } + } +} + +func Setup(ctx *cli.Context) { + if Enabled { + log.Info("Enabling opentracing") + var ( + endpoint = ctx.GlobalString(TracingEndpointFlag.Name) + svc = ctx.GlobalString(TracingSvcFlag.Name) + ) + + Closer = initTracer(endpoint, svc) + } +} + +func initTracer(endpoint, svc string) (closer io.Closer) { + // Sample configuration for testing. Use constant sampling to sample every trace + // and enable LogSpan to log every span via configured Logger. + cfg := jaegercfg.Configuration{ + Sampler: &jaegercfg.SamplerConfig{ + Type: jaeger.SamplerTypeConst, + Param: 1, + }, + Reporter: &jaegercfg.ReporterConfig{ + LogSpans: true, + BufferFlushInterval: 1 * time.Second, + LocalAgentHostPort: endpoint, + }, + } + + // Example logger and metrics factory. Use github.com/uber/jaeger-client-go/log + // and github.com/uber/jaeger-lib/metrics respectively to bind to real logging and metrics + // frameworks. + jLogger := jaegerlog.StdLogger + //jMetricsFactory := metrics.NullFactory + + // Initialize tracer with a logger and a metrics factory + closer, err := cfg.InitGlobalTracer( + svc, + jaegercfg.Logger(jLogger), + //jaegercfg.Metrics(jMetricsFactory), + //jaegercfg.Observer(rpcmetrics.NewObserver(jMetricsFactory, rpcmetrics.DefaultNameNormalizer)), + ) + if err != nil { + log.Error("Could not initialize Jaeger tracer", "err", err) + } + + return closer +} diff --git a/swarm/version/version.go b/swarm/version/version.go new file mode 100644 index 0000000000..5e8c78823f --- /dev/null +++ b/swarm/version/version.go @@ -0,0 +1,64 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package version + +import ( + "fmt" +) + +const ( + VersionMajor = 0 // Major version component of the current release + VersionMinor = 3 // Minor version component of the current release + VersionPatch = 1 // Patch version component of the current release + VersionMeta = "stable" // Version metadata to append to the version string +) + +// Version holds the textual version string. +var Version = func() string { + return fmt.Sprintf("%d.%d.%d", VersionMajor, VersionMinor, VersionPatch) +}() + +// VersionWithMeta holds the textual version string including the metadata. +var VersionWithMeta = func() string { + v := Version + if VersionMeta != "" { + v += "-" + VersionMeta + } + return v +}() + +// ArchiveVersion holds the textual version string used for Swarm archives. +// e.g. "0.3.0-dea1ce05" for stable releases, or +// "0.3.1-unstable-21c059b6" for unstable releases +func ArchiveVersion(gitCommit string) string { + vsn := Version + if VersionMeta != "stable" { + vsn += "-" + VersionMeta + } + if len(gitCommit) >= 8 { + vsn += "-" + gitCommit[:8] + } + return vsn +} + +func VersionWithCommit(gitCommit string) string { + vsn := Version + if len(gitCommit) >= 8 { + vsn += "-" + gitCommit[:8] + } + return vsn +} diff --git a/tests/block_test_util.go b/tests/block_test_util.go index bb8a4b58fc..d912995827 100644 --- a/tests/block_test_util.go +++ b/tests/block_test_util.go @@ -42,6 +42,7 @@ type BlockTest struct { json btJSON } +// UnmarshalJSON implements json.Unmarshaler interface. func (t *BlockTest) UnmarshalJSON(in []byte) error { return json.Unmarshal(in, &t.json) } @@ -98,13 +99,13 @@ func (t *BlockTest) Run() error { } // import pre accounts & construct test genesis block & state root - db, _ := ethdb.NewMemDatabase() + db := ethdb.NewMemDatabase() gblock, err := t.genesis(config).Commit(db) if err != nil { return err } if gblock.Hash() != t.json.Genesis.Hash { - return fmt.Errorf("genesis block hash doesn't match test: computed=%x, test=%x\n", gblock.Hash().Bytes(), t.json.Genesis.Hash) + return fmt.Errorf("genesis block hash doesn't match test: computed=%x, test=%x", gblock.Hash().Bytes()[:6], t.json.Genesis.Hash[:6]) } if gblock.Root() != t.json.Genesis.StateRoot { return fmt.Errorf("genesis block state root does not match test: computed=%x, test=%x", gblock.Root().Bytes(), t.json.Genesis.StateRoot) diff --git a/tests/difficulty_test.go b/tests/difficulty_test.go index 6006373009..20294cc9d5 100644 --- a/tests/difficulty_test.go +++ b/tests/difficulty_test.go @@ -27,7 +27,7 @@ import ( var ( mainnetChainConfig = params.ChainConfig{ - ChainId: big.NewInt(1), + ChainID: big.NewInt(1), HomesteadBlock: big.NewInt(1150000), DAOForkBlock: big.NewInt(1920000), DAOForkSupport: true, diff --git a/tests/init.go b/tests/init.go index ff8ee7da18..af65f92069 100644 --- a/tests/init.go +++ b/tests/init.go @@ -23,29 +23,29 @@ import ( "github.com/ethereum/go-ethereum/params" ) -// This table defines supported forks and their chain config. +// Forks table defines supported forks and their chain config. var Forks = map[string]*params.ChainConfig{ "Frontier": { - ChainId: big.NewInt(1), + ChainID: big.NewInt(1), }, "Homestead": { - ChainId: big.NewInt(1), + ChainID: big.NewInt(1), HomesteadBlock: big.NewInt(0), }, "EIP150": { - ChainId: big.NewInt(1), + ChainID: big.NewInt(1), HomesteadBlock: big.NewInt(0), EIP150Block: big.NewInt(0), }, "EIP158": { - ChainId: big.NewInt(1), + ChainID: big.NewInt(1), HomesteadBlock: big.NewInt(0), EIP150Block: big.NewInt(0), EIP155Block: big.NewInt(0), EIP158Block: big.NewInt(0), }, "Byzantium": { - ChainId: big.NewInt(1), + ChainID: big.NewInt(1), HomesteadBlock: big.NewInt(0), EIP150Block: big.NewInt(0), EIP155Block: big.NewInt(0), @@ -54,22 +54,22 @@ var Forks = map[string]*params.ChainConfig{ ByzantiumBlock: big.NewInt(0), }, "FrontierToHomesteadAt5": { - ChainId: big.NewInt(1), + ChainID: big.NewInt(1), HomesteadBlock: big.NewInt(5), }, "HomesteadToEIP150At5": { - ChainId: big.NewInt(1), + ChainID: big.NewInt(1), HomesteadBlock: big.NewInt(0), EIP150Block: big.NewInt(5), }, "HomesteadToDaoAt5": { - ChainId: big.NewInt(1), + ChainID: big.NewInt(1), HomesteadBlock: big.NewInt(0), DAOForkBlock: big.NewInt(5), DAOForkSupport: true, }, "EIP158ToByzantiumAt5": { - ChainId: big.NewInt(1), + ChainID: big.NewInt(1), HomesteadBlock: big.NewInt(0), EIP150Block: big.NewInt(0), EIP155Block: big.NewInt(0), diff --git a/tests/init_test.go b/tests/init_test.go index fbb214b08c..26e919d24b 100644 --- a/tests/init_test.go +++ b/tests/init_test.go @@ -42,7 +42,7 @@ var ( difficultyTestDir = filepath.Join(baseDir, "BasicTests") ) -func readJson(reader io.Reader, value interface{}) error { +func readJSON(reader io.Reader, value interface{}) error { data, err := ioutil.ReadAll(reader) if err != nil { return fmt.Errorf("error reading JSON file: %v", err) @@ -57,14 +57,14 @@ func readJson(reader io.Reader, value interface{}) error { return nil } -func readJsonFile(fn string, value interface{}) error { +func readJSONFile(fn string, value interface{}) error { file, err := os.Open(fn) if err != nil { return err } defer file.Close() - err = readJson(file, value) + err = readJSON(file, value) if err != nil { return fmt.Errorf("%s in file %s", err.Error(), fn) } @@ -169,9 +169,8 @@ func (tm *testMatcher) checkFailure(t *testing.T, name string, err error) error if err != nil { t.Logf("error: %v", err) return nil - } else { - return fmt.Errorf("test succeeded unexpectedly") } + return fmt.Errorf("test succeeded unexpectedly") } return err } @@ -213,7 +212,7 @@ func (tm *testMatcher) runTestFile(t *testing.T, path, name string, runTest inte // Load the file as map[string]. m := makeMapFromTestFunc(runTest) - if err := readJsonFile(path, m.Addr().Interface()); err != nil { + if err := readJSONFile(path, m.Addr().Interface()); err != nil { t.Fatal(err) } diff --git a/tests/state_test.go b/tests/state_test.go index 9ca5f18303..adec4feb2b 100644 --- a/tests/state_test.go +++ b/tests/state_test.go @@ -36,14 +36,7 @@ func TestState(t *testing.T) { st.skipLoad(`^stTransactionTest/zeroSigTransa[^/]*\.json`) // EIP-86 is not supported yet // Expected failures: st.fails(`^stRevertTest/RevertPrecompiledTouch\.json/EIP158`, "bug in test") - st.fails(`^stRevertTest/RevertPrefoundEmptyOOG\.json/EIP158`, "bug in test") st.fails(`^stRevertTest/RevertPrecompiledTouch\.json/Byzantium`, "bug in test") - st.fails(`^stRevertTest/RevertPrefoundEmptyOOG\.json/Byzantium`, "bug in test") - st.fails(`^stRandom2/randomStatetest64[45]\.json/(EIP150|Frontier|Homestead)/.*`, "known bug #15119") - st.fails(`^stCreateTest/TransactionCollisionToEmpty\.json/EIP158/2`, "known bug ") - st.fails(`^stCreateTest/TransactionCollisionToEmpty\.json/EIP158/3`, "known bug ") - st.fails(`^stCreateTest/TransactionCollisionToEmpty\.json/Byzantium/2`, "known bug ") - st.fails(`^stCreateTest/TransactionCollisionToEmpty\.json/Byzantium/3`, "known bug ") st.walk(t, stateTestDir, func(t *testing.T, name string, test *StateTest) { for _, subtest := range test.Subtests() { diff --git a/tests/state_test_util.go b/tests/state_test_util.go index 3b761bd771..84581fae18 100644 --- a/tests/state_test_util.go +++ b/tests/state_test_util.go @@ -126,8 +126,7 @@ func (t *StateTest) Run(subtest StateSubtest, vmconfig vm.Config) (*state.StateD return nil, UnsupportedForkError{subtest.Fork} } block := t.genesis(config).ToBlock(nil) - db, _ := ethdb.NewMemDatabase() - statedb := MakePreState(db, t.json.Pre) + statedb := MakePreState(ethdb.NewMemDatabase(), t.json.Pre) post := t.json.Post[subtest.Fork][subtest.Index] msg, err := t.json.Tx.toMessage(post) diff --git a/tests/transaction_test.go b/tests/transaction_test.go index c743996c2a..42ad81877e 100644 --- a/tests/transaction_test.go +++ b/tests/transaction_test.go @@ -35,7 +35,7 @@ func TestTransaction(t *testing.T) { EIP150Block: big.NewInt(0), EIP155Block: big.NewInt(0), EIP158Block: big.NewInt(0), - ChainId: big.NewInt(1), + ChainID: big.NewInt(1), }) txt.config(`^Byzantium/`, params.ChainConfig{ HomesteadBlock: big.NewInt(0), diff --git a/tests/transaction_test_util.go b/tests/transaction_test_util.go index 2028d2a278..8c3dac088c 100644 --- a/tests/transaction_test_util.go +++ b/tests/transaction_test_util.go @@ -72,9 +72,8 @@ func (tt *TransactionTest) Run(config *params.ChainConfig) error { if err := rlp.DecodeBytes(tt.json.RLP, tx); err != nil { if tt.json.Transaction == nil { return nil - } else { - return fmt.Errorf("RLP decoding failed: %v", err) } + return fmt.Errorf("RLP decoding failed: %v", err) } // Check sender derivation. signer := types.MakeSigner(config, new(big.Int).SetUint64(uint64(tt.json.BlockNumber))) diff --git a/tests/vm_test_util.go b/tests/vm_test_util.go index b365167a69..cb81c5b94e 100644 --- a/tests/vm_test_util.go +++ b/tests/vm_test_util.go @@ -79,8 +79,7 @@ type vmExecMarshaling struct { } func (t *VMTest) Run(vmconfig vm.Config) error { - db, _ := ethdb.NewMemDatabase() - statedb := MakePreState(db, t.json.Pre) + statedb := MakePreState(ethdb.NewMemDatabase(), t.json.Pre) ret, gasRemaining, err := t.exec(statedb, vmconfig) if t.json.GasRemaining == nil { diff --git a/trie/database.go b/trie/database.go index da36e72f98..8675b9f0a0 100644 --- a/trie/database.go +++ b/trie/database.go @@ -17,12 +17,30 @@ package trie import ( + "fmt" + "io" "sync" "time" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/metrics" + "github.com/ethereum/go-ethereum/rlp" +) + +var ( + memcacheFlushTimeTimer = metrics.NewRegisteredResettingTimer("trie/memcache/flush/time", nil) + memcacheFlushNodesMeter = metrics.NewRegisteredMeter("trie/memcache/flush/nodes", nil) + memcacheFlushSizeMeter = metrics.NewRegisteredMeter("trie/memcache/flush/size", nil) + + memcacheGCTimeTimer = metrics.NewRegisteredResettingTimer("trie/memcache/gc/time", nil) + memcacheGCNodesMeter = metrics.NewRegisteredMeter("trie/memcache/gc/nodes", nil) + memcacheGCSizeMeter = metrics.NewRegisteredMeter("trie/memcache/gc/size", nil) + + memcacheCommitTimeTimer = metrics.NewRegisteredResettingTimer("trie/memcache/commit/time", nil) + memcacheCommitNodesMeter = metrics.NewRegisteredMeter("trie/memcache/commit/nodes", nil) + memcacheCommitSizeMeter = metrics.NewRegisteredMeter("trie/memcache/commit/size", nil) ) // secureKeyPrefix is the database key prefix used to store trie node preimages. @@ -46,36 +64,209 @@ type DatabaseReader interface { type Database struct { diskdb ethdb.Database // Persistent storage for matured trie nodes - nodes map[common.Hash]*cachedNode // Data and references relationships of a node - preimages map[common.Hash][]byte // Preimages of nodes from the secure trie - seckeybuf [secureKeyLength]byte // Ephemeral buffer for calculating preimage keys + nodes map[common.Hash]*cachedNode // Data and references relationships of a node + oldest common.Hash // Oldest tracked node, flush-list head + newest common.Hash // Newest tracked node, flush-list tail + + preimages map[common.Hash][]byte // Preimages of nodes from the secure trie + seckeybuf [secureKeyLength]byte // Ephemeral buffer for calculating preimage keys gctime time.Duration // Time spent on garbage collection since last commit gcnodes uint64 // Nodes garbage collected since last commit gcsize common.StorageSize // Data storage garbage collected since last commit - nodesSize common.StorageSize // Storage size of the nodes cache + flushtime time.Duration // Time spent on data flushing since last commit + flushnodes uint64 // Nodes flushed since last commit + flushsize common.StorageSize // Data storage flushed since last commit + + nodesSize common.StorageSize // Storage size of the nodes cache (exc. flushlist) preimagesSize common.StorageSize // Storage size of the preimages cache lock sync.RWMutex } +// 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) canUnload(uint16, uint16) bool { panic("this should never end up in a live trie") } +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") } + +// rawFullNode represents only the useful data content of a full node, with the +// caches and flags stripped out to minimize its data storage. This type honors +// the same RLP encoding as the original parent. +type rawFullNode [17]node + +func (n rawFullNode) canUnload(uint16, uint16) bool { panic("this should never end up in a live trie") } +func (n rawFullNode) cache() (hashNode, bool) { panic("this should never end up in a live trie") } +func (n rawFullNode) fstring(ind string) string { panic("this should never end up in a live trie") } + +func (n rawFullNode) EncodeRLP(w io.Writer) error { + var nodes [17]node + + for i, child := range n { + if child != nil { + nodes[i] = child + } else { + nodes[i] = nilValueNode + } + } + return rlp.Encode(w, nodes) +} + +// rawShortNode represents only the useful data content of a short node, with the +// caches and flags stripped out to minimize its data storage. This type honors +// the same RLP encoding as the original parent. +type rawShortNode struct { + Key []byte + Val node +} + +func (n rawShortNode) canUnload(uint16, uint16) bool { panic("this should never end up in a live trie") } +func (n rawShortNode) cache() (hashNode, bool) { panic("this should never end up in a live trie") } +func (n rawShortNode) fstring(ind string) string { panic("this should never end up in a live trie") } + // cachedNode is all the information we know about a single cached node in the // memory database write layer. type cachedNode struct { - blob []byte // Cached data block of the trie node - parents int // Number of live nodes referencing this one - children map[common.Hash]int // Children referenced by this nodes + node node // Cached collapsed trie node, or raw rlp data + size uint16 // Byte size of the useful cached data + + parents uint16 // Number of live nodes referencing this one + children map[common.Hash]uint16 // External children referenced by this node + + flushPrev common.Hash // Previous node in the flush-list + flushNext common.Hash // Next node in the flush-list +} + +// rlp returns the raw rlp encoded blob of the cached node, either directly from +// the cache, or by regenerating it from the collapsed node. +func (n *cachedNode) rlp() []byte { + if node, ok := n.node.(rawNode); ok { + return node + } + blob, err := rlp.EncodeToBytes(n.node) + if err != nil { + panic(err) + } + return blob +} + +// obj returns the decoded and expanded trie node, either directly from the cache, +// or by regenerating it from the rlp encoded blob. +func (n *cachedNode) obj(hash common.Hash, cachegen uint16) node { + if node, ok := n.node.(rawNode); ok { + return mustDecodeNode(hash[:], node, cachegen) + } + return expandNode(hash[:], n.node, cachegen) +} + +// childs returns all the tracked children of this node, both the implicit ones +// from inside the node as well as the explicit ones from outside the node. +func (n *cachedNode) childs() []common.Hash { + children := make([]common.Hash, 0, 16) + for child := range n.children { + children = append(children, child) + } + if _, ok := n.node.(rawNode); !ok { + gatherChildren(n.node, &children) + } + return children +} + +// gatherChildren traverses the node hierarchy of a collapsed storage node and +// retrieves all the hashnode children. +func gatherChildren(n node, children *[]common.Hash) { + switch n := n.(type) { + case *rawShortNode: + gatherChildren(n.Val, children) + + case rawFullNode: + for i := 0; i < 16; i++ { + gatherChildren(n[i], children) + } + case hashNode: + *children = append(*children, common.BytesToHash(n)) + + case valueNode, nil: + + default: + panic(fmt.Sprintf("unknown node type: %T", n)) + } +} + +// simplifyNode traverses the hierarchy of an expanded memory node and discards +// all the internal caches, returning a node that only contains the raw data. +func simplifyNode(n node) node { + switch n := n.(type) { + case *shortNode: + // Short nodes discard the flags and cascade + return &rawShortNode{Key: n.Key, Val: simplifyNode(n.Val)} + + case *fullNode: + // Full nodes discard the flags and cascade + node := rawFullNode(n.Children) + for i := 0; i < len(node); i++ { + if node[i] != nil { + node[i] = simplifyNode(node[i]) + } + } + return node + + case valueNode, hashNode, rawNode: + return n + + default: + panic(fmt.Sprintf("unknown node type: %T", n)) + } +} + +// expandNode traverses the node hierarchy of a collapsed storage node and converts +// all fields and keys into expanded memory form. +func expandNode(hash hashNode, n node, cachegen uint16) node { + switch n := n.(type) { + case *rawShortNode: + // Short nodes need key and child expansion + return &shortNode{ + Key: compactToHex(n.Key), + Val: expandNode(nil, n.Val, cachegen), + flags: nodeFlag{ + hash: hash, + gen: cachegen, + }, + } + + case rawFullNode: + // Full nodes need child expansion + node := &fullNode{ + flags: nodeFlag{ + hash: hash, + gen: cachegen, + }, + } + for i := 0; i < len(node.Children); i++ { + if n[i] != nil { + node.Children[i] = expandNode(nil, n[i], cachegen) + } + } + return node + + case valueNode, hashNode: + return n + + default: + panic(fmt.Sprintf("unknown node type: %T", n)) + } } // NewDatabase creates a new trie database to store ephemeral trie content before // its written out to disk or garbage collected. func NewDatabase(diskdb ethdb.Database) *Database { return &Database{ - diskdb: diskdb, - nodes: map[common.Hash]*cachedNode{ - {}: {children: make(map[common.Hash]int)}, - }, + diskdb: diskdb, + nodes: map[common.Hash]*cachedNode{{}: {}}, preimages: make(map[common.Hash][]byte), } } @@ -85,25 +276,46 @@ func (db *Database) DiskDB() DatabaseReader { return db.diskdb } -// Insert writes a new trie node to the memory database if it's yet unknown. The -// method will make a copy of the slice. -func (db *Database) Insert(hash common.Hash, blob []byte) { +// InsertBlob writes a new reference tracked blob to the memory database if it's +// yet unknown. This method should only be used for non-trie nodes that require +// reference counting, since trie nodes are garbage collected directly through +// their embedded children. +func (db *Database) InsertBlob(hash common.Hash, blob []byte) { db.lock.Lock() defer db.lock.Unlock() - db.insert(hash, blob) + db.insert(hash, blob, rawNode(blob)) } -// insert is the private locked version of Insert. -func (db *Database) insert(hash common.Hash, blob []byte) { +// insert inserts a collapsed trie node into the memory database. This method is +// a more generic version of InsertBlob, supporting both raw blob insertions as +// well ex trie node insertions. The blob must always be specified to allow proper +// size tracking. +func (db *Database) insert(hash common.Hash, blob []byte, node node) { + // If the node's already cached, skip if _, ok := db.nodes[hash]; ok { return } - db.nodes[hash] = &cachedNode{ - blob: common.CopyBytes(blob), - children: make(map[common.Hash]int), + // Create the cached entry for this node + entry := &cachedNode{ + node: simplifyNode(node), + size: uint16(len(blob)), + flushPrev: db.newest, } - db.nodesSize += common.StorageSize(common.HashLength + len(blob)) + for _, child := range entry.childs() { + if c := db.nodes[child]; c != nil { + c.parents++ + } + } + db.nodes[hash] = entry + + // Update the flush-list endpoints + if db.oldest == (common.Hash{}) { + db.oldest, db.newest = hash, hash + } else { + db.nodes[db.newest].flushNext, db.newest = hash, hash + } + db.nodesSize += common.StorageSize(common.HashLength + entry.size) } // insertPreimage writes a new trie node pre-image to the memory database if it's @@ -118,8 +330,27 @@ func (db *Database) insertPreimage(hash common.Hash, preimage []byte) { db.preimagesSize += common.StorageSize(common.HashLength + len(preimage)) } -// Node retrieves a cached trie node from memory. If it cannot be found cached, -// the method queries the persistent database for the content. +// node retrieves a cached trie node from memory, or returns nil if none can be +// found in the memory cache. +func (db *Database) node(hash common.Hash, cachegen uint16) node { + // Retrieve the node from cache if available + db.lock.RLock() + node := db.nodes[hash] + db.lock.RUnlock() + + if node != nil { + return node.obj(hash, cachegen) + } + // Content unavailable in memory, attempt to retrieve from disk + enc, err := db.diskdb.Get(hash[:]) + if err != nil || enc == nil { + return nil + } + return mustDecodeNode(hash[:], enc, cachegen) +} + +// Node retrieves an encoded cached trie node from memory. If it cannot be found +// cached, the method queries the persistent database for the content. func (db *Database) Node(hash common.Hash) ([]byte, error) { // Retrieve the node from cache if available db.lock.RLock() @@ -127,7 +358,7 @@ func (db *Database) Node(hash common.Hash) ([]byte, error) { db.lock.RUnlock() if node != nil { - return node.blob, nil + return node.rlp(), nil } // Content unavailable in memory, attempt to retrieve from disk return db.diskdb.Get(hash[:]) @@ -189,25 +420,31 @@ func (db *Database) reference(child common.Hash, parent common.Hash) { return } // If the reference already exists, only duplicate for roots - if _, ok = db.nodes[parent].children[child]; ok && parent != (common.Hash{}) { + if db.nodes[parent].children == nil { + db.nodes[parent].children = make(map[common.Hash]uint16) + } else if _, ok = db.nodes[parent].children[child]; ok && parent != (common.Hash{}) { return } node.parents++ db.nodes[parent].children[child]++ } -// Dereference removes an existing reference from a parent node to a child node. -func (db *Database) Dereference(child common.Hash, parent common.Hash) { +// Dereference removes an existing reference from a root node. +func (db *Database) Dereference(root common.Hash) { db.lock.Lock() defer db.lock.Unlock() nodes, storage, start := len(db.nodes), db.nodesSize, time.Now() - db.dereference(child, parent) + db.dereference(root, common.Hash{}) db.gcnodes += uint64(nodes - len(db.nodes)) db.gcsize += storage - db.nodesSize db.gctime += time.Since(start) + memcacheGCTimeTimer.Update(time.Since(start)) + memcacheGCSizeMeter.Mark(int64(storage - db.nodesSize)) + memcacheGCNodesMeter.Mark(int64(nodes - len(db.nodes))) + log.Debug("Dereferenced trie from memory database", "nodes", nodes-len(db.nodes), "size", storage-db.nodesSize, "time", time.Since(start), "gcnodes", db.gcnodes, "gcsize", db.gcsize, "gctime", db.gctime, "livenodes", len(db.nodes), "livesize", db.nodesSize) } @@ -217,26 +454,148 @@ func (db *Database) dereference(child common.Hash, parent common.Hash) { // Dereference the parent-child node := db.nodes[parent] - node.children[child]-- - if node.children[child] == 0 { - delete(node.children, child) + if node.children != nil && node.children[child] > 0 { + node.children[child]-- + if node.children[child] == 0 { + delete(node.children, child) + } } - // If the node does not exist, it's a previously committed node. + // If the child does not exist, it's a previously committed node. node, ok := db.nodes[child] if !ok { return } // If there are no more references to the child, delete it and cascade - node.parents-- + if node.parents > 0 { + // This is a special cornercase where a node loaded from disk (i.e. not in the + // memcache any more) gets reinjected as a new node (short node split into full, + // then reverted into short), causing a cached node to have no parents. That is + // no problem in itself, but don't make maxint parents out of it. + node.parents-- + } if node.parents == 0 { - for hash := range node.children { + // Remove the node from the flush-list + switch child { + case db.oldest: + db.oldest = node.flushNext + db.nodes[node.flushNext].flushPrev = common.Hash{} + case db.newest: + db.newest = node.flushPrev + db.nodes[node.flushPrev].flushNext = common.Hash{} + default: + db.nodes[node.flushPrev].flushNext = node.flushNext + db.nodes[node.flushNext].flushPrev = node.flushPrev + } + // Dereference all children and delete the node + for _, hash := range node.childs() { db.dereference(hash, child) } delete(db.nodes, child) - db.nodesSize -= common.StorageSize(common.HashLength + len(node.blob)) + db.nodesSize -= common.StorageSize(common.HashLength + int(node.size)) } } +// Cap iteratively flushes old but still referenced trie nodes until the total +// memory usage goes below the given threshold. +func (db *Database) Cap(limit common.StorageSize) error { + // Create a database batch to flush persistent data out. It is important that + // outside code doesn't see an inconsistent state (referenced data removed from + // memory cache during commit but not yet in persistent storage). This is ensured + // by only uncaching existing data when the database write finalizes. + db.lock.RLock() + + nodes, storage, start := len(db.nodes), db.nodesSize, time.Now() + batch := db.diskdb.NewBatch() + + // db.nodesSize only contains the useful data in the cache, but when reporting + // the total memory consumption, the maintenance metadata is also needed to be + // counted. For every useful node, we track 2 extra hashes as the flushlist. + size := db.nodesSize + common.StorageSize((len(db.nodes)-1)*2*common.HashLength) + + // If the preimage cache got large enough, push to disk. If it's still small + // leave for later to deduplicate writes. + flushPreimages := db.preimagesSize > 4*1024*1024 + if flushPreimages { + for hash, preimage := range db.preimages { + if err := batch.Put(db.secureKey(hash[:]), preimage); err != nil { + log.Error("Failed to commit preimage from trie database", "err", err) + db.lock.RUnlock() + return err + } + if batch.ValueSize() > ethdb.IdealBatchSize { + if err := batch.Write(); err != nil { + db.lock.RUnlock() + return err + } + batch.Reset() + } + } + } + // Keep committing nodes from the flush-list until we're below allowance + oldest := db.oldest + for size > limit && oldest != (common.Hash{}) { + // Fetch the oldest referenced node and push into the batch + node := db.nodes[oldest] + if err := batch.Put(oldest[:], node.rlp()); err != nil { + db.lock.RUnlock() + return err + } + // If we exceeded the ideal batch size, commit and reset + if batch.ValueSize() >= ethdb.IdealBatchSize { + if err := batch.Write(); err != nil { + log.Error("Failed to write flush list to disk", "err", err) + db.lock.RUnlock() + return err + } + batch.Reset() + } + // Iterate to the next flush item, or abort if the size cap was achieved. Size + // is the total size, including both the useful cached data (hash -> blob), as + // well as the flushlist metadata (2*hash). When flushing items from the cache, + // we need to reduce both. + size -= common.StorageSize(3*common.HashLength + int(node.size)) + oldest = node.flushNext + } + // Flush out any remainder data from the last batch + if err := batch.Write(); err != nil { + log.Error("Failed to write flush list to disk", "err", err) + db.lock.RUnlock() + return err + } + db.lock.RUnlock() + + // Write successful, clear out the flushed data + db.lock.Lock() + defer db.lock.Unlock() + + if flushPreimages { + db.preimages = make(map[common.Hash][]byte) + db.preimagesSize = 0 + } + for db.oldest != oldest { + node := db.nodes[db.oldest] + delete(db.nodes, db.oldest) + db.oldest = node.flushNext + + db.nodesSize -= common.StorageSize(common.HashLength + int(node.size)) + } + if db.oldest != (common.Hash{}) { + db.nodes[db.oldest].flushPrev = common.Hash{} + } + db.flushnodes += uint64(nodes - len(db.nodes)) + db.flushsize += storage - db.nodesSize + db.flushtime += time.Since(start) + + memcacheFlushTimeTimer.Update(time.Since(start)) + memcacheFlushSizeMeter.Mark(int64(storage - db.nodesSize)) + memcacheFlushNodesMeter.Mark(int64(nodes - len(db.nodes))) + + log.Debug("Persisted nodes from memory database", "nodes", nodes-len(db.nodes), "size", storage-db.nodesSize, "time", time.Since(start), + "flushnodes", db.flushnodes, "flushsize", db.flushsize, "flushtime", db.flushtime, "livenodes", len(db.nodes), "livesize", db.nodesSize) + + return nil +} + // Commit iterates over all the children of a particular node, writes them out // to disk, forcefully tearing down all references in both directions. // @@ -266,7 +625,7 @@ func (db *Database) Commit(node common.Hash, report bool) error { } } // Move the trie itself into the batch, flushing if enough data is accumulated - nodes, storage := len(db.nodes), db.nodesSize+db.preimagesSize + nodes, storage := len(db.nodes), db.nodesSize if err := db.commit(node, batch); err != nil { log.Error("Failed to commit trie from trie database", "err", err) db.lock.RUnlock() @@ -289,15 +648,20 @@ func (db *Database) Commit(node common.Hash, report bool) error { db.uncache(node) + memcacheCommitTimeTimer.Update(time.Since(start)) + memcacheCommitSizeMeter.Mark(int64(storage - db.nodesSize)) + memcacheCommitNodesMeter.Mark(int64(nodes - len(db.nodes))) + logger := log.Info if !report { logger = log.Debug } - logger("Persisted trie from memory database", "nodes", nodes-len(db.nodes), "size", storage-db.nodesSize, "time", time.Since(start), + logger("Persisted trie from memory database", "nodes", nodes-len(db.nodes)+int(db.flushnodes), "size", storage-db.nodesSize+db.flushsize, "time", time.Since(start)+db.flushtime, "gcnodes", db.gcnodes, "gcsize", db.gcsize, "gctime", db.gctime, "livenodes", len(db.nodes), "livesize", db.nodesSize) // Reset the garbage collection statistics db.gcnodes, db.gcsize, db.gctime = 0, 0, 0 + db.flushnodes, db.flushsize, db.flushtime = 0, 0, 0 return nil } @@ -309,15 +673,15 @@ func (db *Database) commit(hash common.Hash, batch ethdb.Batch) error { if !ok { return nil } - for child := range node.children { + for _, child := range node.childs() { if err := db.commit(child, batch); err != nil { return err } } - if err := batch.Put(hash[:], node.blob); err != nil { + if err := batch.Put(hash[:], node.rlp()); err != nil { return err } - // If we've reached an optimal match size, commit and start over + // If we've reached an optimal batch size, commit and start over if batch.ValueSize() >= ethdb.IdealBatchSize { if err := batch.Write(); err != nil { return err @@ -337,19 +701,77 @@ func (db *Database) uncache(hash common.Hash) { if !ok { return } - // Otherwise uncache the node's subtries and remove the node itself too - for child := range node.children { + // Node still exists, remove it from the flush-list + switch hash { + case db.oldest: + db.oldest = node.flushNext + db.nodes[node.flushNext].flushPrev = common.Hash{} + case db.newest: + db.newest = node.flushPrev + db.nodes[node.flushPrev].flushNext = common.Hash{} + default: + db.nodes[node.flushPrev].flushNext = node.flushNext + db.nodes[node.flushNext].flushPrev = node.flushPrev + } + // Uncache the node's subtries and remove the node itself too + for _, child := range node.childs() { db.uncache(child) } delete(db.nodes, hash) - db.nodesSize -= common.StorageSize(common.HashLength + len(node.blob)) + db.nodesSize -= common.StorageSize(common.HashLength + int(node.size)) } // Size returns the current storage size of the memory cache in front of the // persistent database layer. -func (db *Database) Size() common.StorageSize { +func (db *Database) Size() (common.StorageSize, common.StorageSize) { db.lock.RLock() defer db.lock.RUnlock() - return db.nodesSize + db.preimagesSize + // db.nodesSize only contains the useful data in the cache, but when reporting + // the total memory consumption, the maintenance metadata is also needed to be + // counted. For every useful node, we track 2 extra hashes as the flushlist. + var flushlistSize = common.StorageSize((len(db.nodes) - 1) * 2 * common.HashLength) + return db.nodesSize + flushlistSize, db.preimagesSize +} + +// verifyIntegrity is a debug method to iterate over the entire trie stored in +// memory and check whether every node is reachable from the meta root. The goal +// is to find any errors that might cause memory leaks and or trie nodes to go +// missing. +// +// This method is extremely CPU and memory intensive, only use when must. +func (db *Database) verifyIntegrity() { + // Iterate over all the cached nodes and accumulate them into a set + reachable := map[common.Hash]struct{}{{}: {}} + + for child := range db.nodes[common.Hash{}].children { + db.accumulate(child, reachable) + } + // Find any unreachable but cached nodes + unreachable := []string{} + for hash, node := range db.nodes { + if _, ok := reachable[hash]; !ok { + unreachable = append(unreachable, fmt.Sprintf("%x: {Node: %v, Parents: %d, Prev: %x, Next: %x}", + hash, node.node, node.parents, node.flushPrev, node.flushNext)) + } + } + if len(unreachable) != 0 { + panic(fmt.Sprintf("trie cache memory leak: %v", unreachable)) + } +} + +// accumulate iterates over the trie defined by hash and accumulates all the +// cached children found in memory. +func (db *Database) accumulate(hash common.Hash, reachable map[common.Hash]struct{}) { + // Mark the node reachable if present in the memory cache + node, ok := db.nodes[hash] + if !ok { + return + } + reachable[hash] = struct{}{} + + // Iterate over all the children and accumulate them too + for _, child := range node.childs() { + db.accumulate(child, reachable) + } } diff --git a/trie/encoding.go b/trie/encoding.go index e96a786e40..5f120de638 100644 --- a/trie/encoding.go +++ b/trie/encoding.go @@ -53,10 +53,9 @@ func hexToCompact(hex []byte) []byte { func compactToHex(compact []byte) []byte { base := keybytesToHex(compact) - base = base[:len(base)-1] - // apply terminator flag - if base[0] >= 2 { - base = append(base, 16) + // delete terminator flag + if base[0] < 2 { + base = base[:len(base)-1] } // apply odd flag chop := 2 - base[0]&1 @@ -83,7 +82,7 @@ func hexToKeybytes(hex []byte) []byte { if len(hex)&1 != 0 { panic("can't convert hex key of odd length") } - key := make([]byte, (len(hex)+1)/2) + key := make([]byte, len(hex)/2) decodeNibbles(hex, key) return key } diff --git a/trie/hasher.go b/trie/hasher.go index cc0f006441..7b1d7793fa 100644 --- a/trie/hasher.go +++ b/trie/hasher.go @@ -17,7 +17,6 @@ package trie import ( - "bytes" "hash" "sync" @@ -27,17 +26,39 @@ import ( ) type hasher struct { - tmp *bytes.Buffer - sha hash.Hash + tmp sliceBuffer + sha keccakState cachegen uint16 cachelimit uint16 onleaf LeafCallback } +// keccakState wraps sha3.state. In addition to the usual hash methods, it also supports +// Read to get a variable amount of data from the hash state. Read is faster than Sum +// because it doesn't copy the internal state, but also modifies the internal state. +type keccakState interface { + hash.Hash + Read([]byte) (int, error) +} + +type sliceBuffer []byte + +func (b *sliceBuffer) Write(data []byte) (n int, err error) { + *b = append(*b, data...) + return len(data), nil +} + +func (b *sliceBuffer) Reset() { + *b = (*b)[:0] +} + // hashers live in a global db. var hasherPool = sync.Pool{ New: func() interface{} { - return &hasher{tmp: new(bytes.Buffer), sha: sha3.NewKeccak256()} + return &hasher{ + tmp: make(sliceBuffer, 0, 550), // cap is as large as a full fullNode. + sha: sha3.NewKeccak256().(keccakState), + } }, } @@ -53,9 +74,9 @@ func returnHasherToPool(h *hasher) { // 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, db *Database, force bool) (Node, Node, error) { +func (h *hasher) hash(n node, db *Database, force bool) (node, node, error) { // If we're not storing the node, just hashing, use available cached data - if hash, dirty := n.Cache(); hash != nil { + if hash, dirty := n.cache(); hash != nil { if db == nil { return hash, n, nil } @@ -72,23 +93,23 @@ func (h *hasher) hash(n Node, db *Database, force bool) (Node, Node, error) { // Trie not processed yet or needs storage, walk the children collapsed, cached, err := h.hashChildren(n, db) if err != nil { - return HashNode{}, n, err + return hashNode{}, n, err } hashed, err := h.store(collapsed, db, force) if err != nil { - return HashNode{}, n, err + return hashNode{}, n, err } // Cache the hash of the node for later reuse and remove // the dirty flag in commit mode. It's fine to assign these values directly // without copying the node first because hashChildren copies it. - cachedHash, _ := hashed.(HashNode) + cachedHash, _ := hashed.(hashNode) switch cn := cached.(type) { - case *ShortNode: + case *shortNode: cn.flags.hash = cachedHash if db != nil { cn.flags.dirty = false } - case *FullNode: + case *fullNode: cn.flags.hash = cachedHash if db != nil { cn.flags.dirty = false @@ -100,28 +121,25 @@ func (h *hasher) hash(n Node, db *Database, force bool) (Node, Node, error) { // hashChildren replaces the children of a node with their hashes if the encoded // size of the child is larger than a hash, returning the collapsed node as well // as a replacement for the original node with the child hashes cached in. -func (h *hasher) hashChildren(original Node, db *Database) (Node, Node, error) { +func (h *hasher) hashChildren(original node, db *Database) (node, node, error) { var err error switch n := original.(type) { - case *ShortNode: - // Hash the short Node's child, caching the newly hashed subtree + case *shortNode: + // Hash the short node's child, caching the newly hashed subtree collapsed, cached := n.copy(), n.copy() collapsed.Key = hexToCompact(n.Key) cached.Key = common.CopyBytes(n.Key) - if _, ok := n.Val.(ValueNode); !ok { + if _, ok := n.Val.(valueNode); !ok { collapsed.Val, cached.Val, err = h.hash(n.Val, db, false) if err != nil { return original, original, err } } - if collapsed.Val == nil { - collapsed.Val = ValueNode(nil) // Ensure that nil children are encoded as empty strings. - } return collapsed, cached, nil - case *FullNode: + case *fullNode: // Hash the full node's children, caching the newly hashed subtrees collapsed, cached := n.copy(), n.copy() @@ -131,14 +149,9 @@ func (h *hasher) hashChildren(original Node, db *Database) (Node, Node, error) { if err != nil { return original, original, err } - } else { - collapsed.Children[i] = ValueNode(nil) // Ensure that nil children are encoded as empty strings. } } cached.Children[16] = n.Children[16] - if collapsed.Children[16] == nil { - collapsed.Children[16] = ValueNode(nil) - } return collapsed, cached, nil default: @@ -150,58 +163,43 @@ func (h *hasher) hashChildren(original Node, db *Database) (Node, Node, error) { // store hashes the node n and if we have a storage layer specified, it writes // the key/value pair to it and tracks any node->child references as well as any // node->external trie references. -func (h *hasher) store(n Node, db *Database, force bool) (Node, error) { +func (h *hasher) store(n node, db *Database, force bool) (node, error) { // Don't store hashes or empty nodes. - if _, isHash := n.(HashNode); n == nil || isHash { + if _, isHash := n.(hashNode); n == nil || isHash { return n, nil } // Generate the RLP encoding of the node h.tmp.Reset() - if err := rlp.Encode(h.tmp, n); err != nil { + if err := rlp.Encode(&h.tmp, n); err != nil { panic("encode error: " + err.Error()) } - if h.tmp.Len() < 32 && !force { + if len(h.tmp) < 32 && !force { return n, nil // Nodes smaller than 32 bytes are stored inside their parent } // Larger nodes are replaced by their hash and stored in the database. - hash, _ := n.Cache() + hash, _ := n.cache() if hash == nil { - h.sha.Reset() - h.sha.Write(h.tmp.Bytes()) - hash = HashNode(h.sha.Sum(nil)) + hash = h.makeHashNode(h.tmp) } + if db != nil { // We are pooling the trie nodes into an intermediate memory cache - db.lock.Lock() - hash := common.BytesToHash(hash) - db.insert(hash, h.tmp.Bytes()) - // Track all direct parent->child node references - switch n := n.(type) { - case *ShortNode: - if child, ok := n.Val.(HashNode); ok { - db.reference(common.BytesToHash(child), hash) - } - case *FullNode: - for i := 0; i < 16; i++ { - if child, ok := n.Children[i].(HashNode); ok { - db.reference(common.BytesToHash(child), hash) - } - } - } + db.lock.Lock() + db.insert(hash, h.tmp, n) db.lock.Unlock() // Track external references from account->storage trie if h.onleaf != nil { switch n := n.(type) { - case *ShortNode: - if child, ok := n.Val.(ValueNode); ok { + case *shortNode: + if child, ok := n.Val.(valueNode); ok { h.onleaf(child, hash) } - case *FullNode: + case *fullNode: for i := 0; i < 16; i++ { - if child, ok := n.Children[i].(ValueNode); ok { + if child, ok := n.Children[i].(valueNode); ok { h.onleaf(child, hash) } } @@ -210,3 +208,11 @@ func (h *hasher) store(n Node, db *Database, force bool) (Node, error) { } return hash, nil } + +func (h *hasher) makeHashNode(data []byte) hashNode { + n := make(hashNode, h.sha.Size()) + h.sha.Reset() + h.sha.Write(data) + h.sha.Read(n) + return n +} diff --git a/trie/iterator.go b/trie/iterator.go index e30504b151..00b890eb89 100644 --- a/trie/iterator.go +++ b/trie/iterator.go @@ -20,7 +20,9 @@ import ( "bytes" "container/heap" "errors" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/rlp" ) // Iterator is a key-value trie iterator that traverses a Trie. @@ -54,6 +56,12 @@ func (it *Iterator) Next() bool { return false } +// Prove generates the Merkle proof for the leaf node the iterator is currently +// positioned on. +func (it *Iterator) Prove() [][]byte { + return it.nodeIt.LeafProof() +} + // NodeIterator is an iterator to traverse the trie pre-order. type NodeIterator interface { // Next moves the iterator to the next node. If the parameter is false, any child @@ -65,28 +73,40 @@ type NodeIterator interface { // Hash returns the hash of the current node. Hash() common.Hash + // Parent returns the hash of the parent of the current node. The hash may be the one // grandparent if the immediate parent is an internal node with no hash. Parent() common.Hash + // Path returns the hex-encoded path to the current node. // Callers must not retain references to the return value after calling Next. // For leaf nodes, the last element of the path is the 'terminator symbol' 0x10. Path() []byte // Leaf returns true iff the current node is a leaf node. - // LeafBlob, LeafKey return the contents and key of the leaf node. These - // method panic if the iterator is not positioned at a leaf. - // Callers must not retain references to their return value after calling Next Leaf() bool - LeafBlob() []byte + + // LeafKey returns the key of the leaf. The method panics if the iterator is not + // positioned at a leaf. Callers must not retain references to the value after + // calling Next. LeafKey() []byte + + // LeafBlob returns the content of the leaf. The method panics if the iterator + // is not positioned at a leaf. Callers must not retain references to the value + // after calling Next. + LeafBlob() []byte + + // LeafProof returns the Merkle proof of the leaf. The method panics if the + // iterator is not positioned at a leaf. Callers must not retain references + // to the value after calling Next. + LeafProof() [][]byte } // nodeIteratorState represents the iteration state at one particular node of the // trie, which can be resumed at a later invocation. type nodeIteratorState struct { hash common.Hash // Hash of the node being iterated (nil if not standalone) - node Node // Trie node being iterated + node node // Trie node being iterated parent common.Hash // Hash of the first full ancestor node (nil if current is the root) index int // Child to be processed next pathlen int // Length of the path to this node @@ -99,8 +119,8 @@ type nodeIterator struct { err error // Failure set in case of an internal error in the iterator } -// iteratorEnd is stored in nodeIterator.err when iteration is done. -var iteratorEnd = errors.New("end of iteration") +// errIteratorEnd is stored in nodeIterator.err when iteration is done. +var errIteratorEnd = errors.New("end of iteration") // seekError is stored in nodeIterator.err if the initial seek has failed. type seekError struct { @@ -112,7 +132,7 @@ func (e seekError) Error() string { return "seek error: " + e.err.Error() } -func NewNodeIterator(trie *Trie, start []byte) NodeIterator { +func newNodeIterator(trie *Trie, start []byte) NodeIterator { if trie.Hash() == emptyState { return new(nodeIterator) } @@ -139,19 +159,40 @@ func (it *nodeIterator) Leaf() bool { return hasTerm(it.path) } +func (it *nodeIterator) LeafKey() []byte { + if len(it.stack) > 0 { + if _, ok := it.stack[len(it.stack)-1].node.(valueNode); ok { + return hexToKeybytes(it.path) + } + } + panic("not at leaf") +} + func (it *nodeIterator) LeafBlob() []byte { if len(it.stack) > 0 { - if node, ok := it.stack[len(it.stack)-1].node.(ValueNode); ok { + if node, ok := it.stack[len(it.stack)-1].node.(valueNode); ok { return []byte(node) } } panic("not at leaf") } -func (it *nodeIterator) LeafKey() []byte { +func (it *nodeIterator) LeafProof() [][]byte { if len(it.stack) > 0 { - if _, ok := it.stack[len(it.stack)-1].node.(ValueNode); ok { - return hexToKeybytes(it.path) + if _, ok := it.stack[len(it.stack)-1].node.(valueNode); ok { + hasher := newHasher(0, 0, nil) + proofs := make([][]byte, 0, len(it.stack)) + + for i, item := range it.stack[:len(it.stack)-1] { + // Gather nodes that end up as hash nodes (or the root) + node, _, _ := hasher.hashChildren(item.node, nil) + hashed, _ := hasher.store(node, nil, false) + if _, ok := hashed.(hashNode); ok || i == 0 { + enc, _ := rlp.EncodeToBytes(node) + proofs = append(proofs, enc) + } + } + return proofs } } panic("not at leaf") @@ -162,7 +203,7 @@ func (it *nodeIterator) Path() []byte { } func (it *nodeIterator) Error() error { - if it.err == iteratorEnd { + if it.err == errIteratorEnd { return nil } if seek, ok := it.err.(seekError); ok { @@ -176,7 +217,7 @@ func (it *nodeIterator) Error() error { // sets the Error field to the encountered failure. If `descend` is false, // skips iterating over any subnodes of the current node. func (it *nodeIterator) Next(descend bool) bool { - if it.err == iteratorEnd { + if it.err == errIteratorEnd { return false } if seek, ok := it.err.(seekError); ok { @@ -201,8 +242,8 @@ func (it *nodeIterator) seek(prefix []byte) error { // Move forward until we're just before the closest match to key. for { state, parentIndex, path, err := it.peek(bytes.HasPrefix(key, it.path)) - if err == iteratorEnd { - return iteratorEnd + if err == errIteratorEnd { + return errIteratorEnd } else if err != nil { return seekError{prefix, err} } else if bytes.Compare(path, key) >= 0 { @@ -246,11 +287,11 @@ func (it *nodeIterator) peek(descend bool) (*nodeIteratorState, *int, []byte, er // No more child nodes, move back up. it.pop() } - return nil, nil, nil, iteratorEnd + return nil, nil, nil, errIteratorEnd } func (st *nodeIteratorState) resolve(tr *Trie, path []byte) error { - if hash, ok := st.node.(HashNode); ok { + if hash, ok := st.node.(hashNode); ok { resolved, err := tr.resolveHash(hash, path) if err != nil { return err @@ -263,12 +304,12 @@ func (st *nodeIteratorState) resolve(tr *Trie, path []byte) error { func (it *nodeIterator) nextChild(parent *nodeIteratorState, ancestor common.Hash) (*nodeIteratorState, []byte, bool) { switch node := parent.node.(type) { - case *FullNode: - // Full Node, move to the first non-nil child. + case *fullNode: + // Full node, move to the first non-nil child. for i := parent.index + 1; i < len(node.Children); i++ { child := node.Children[i] if child != nil { - hash, _ := child.Cache() + hash, _ := child.cache() state := &nodeIteratorState{ hash: common.BytesToHash(hash), node: child, @@ -281,10 +322,10 @@ func (it *nodeIterator) nextChild(parent *nodeIteratorState, ancestor common.Has return state, path, true } } - case *ShortNode: + case *shortNode: // Short node, return the pointer singleton child if parent.index < 0 { - hash, _ := node.Val.Cache() + hash, _ := node.Val.cache() state := &nodeIteratorState{ hash: common.BytesToHash(hash), node: node.Val, @@ -303,7 +344,7 @@ func (it *nodeIterator) push(state *nodeIteratorState, parentIndex *int, path [] it.path = path it.stack = append(it.stack, state) if parentIndex != nil { - *parentIndex += 1 + *parentIndex++ } } @@ -361,12 +402,16 @@ func (it *differenceIterator) Leaf() bool { return it.b.Leaf() } +func (it *differenceIterator) LeafKey() []byte { + return it.b.LeafKey() +} + func (it *differenceIterator) LeafBlob() []byte { return it.b.LeafBlob() } -func (it *differenceIterator) LeafKey() []byte { - return it.b.LeafKey() +func (it *differenceIterator) LeafProof() [][]byte { + return it.b.LeafProof() } func (it *differenceIterator) Path() []byte { @@ -380,7 +425,7 @@ func (it *differenceIterator) Next(bool) bool { if !it.b.Next(true) { return false } - it.count += 1 + it.count++ if it.eof { // a has reached eof, so we just return all elements from b @@ -395,7 +440,7 @@ func (it *differenceIterator) Next(bool) bool { it.eof = true return true } - it.count += 1 + it.count++ case 1: // b is before a return true @@ -405,12 +450,12 @@ func (it *differenceIterator) Next(bool) bool { if !it.b.Next(hasHash) { return false } - it.count += 1 + it.count++ if !it.a.Next(hasHash) { it.eof = true return true } - it.count += 1 + it.count++ } } } @@ -464,12 +509,16 @@ func (it *unionIterator) Leaf() bool { return (*it.items)[0].Leaf() } +func (it *unionIterator) LeafKey() []byte { + return (*it.items)[0].LeafKey() +} + func (it *unionIterator) LeafBlob() []byte { return (*it.items)[0].LeafBlob() } -func (it *unionIterator) LeafKey() []byte { - return (*it.items)[0].LeafKey() +func (it *unionIterator) LeafProof() [][]byte { + return (*it.items)[0].LeafProof() } func (it *unionIterator) Path() []byte { @@ -504,17 +553,15 @@ func (it *unionIterator) Next(descend bool) bool { skipped := heap.Pop(it.items).(NodeIterator) // Skip the whole subtree if the nodes have hashes; otherwise just skip this node if skipped.Next(skipped.Hash() == common.Hash{}) { - it.count += 1 + it.count++ // If there are more elements, push the iterator back on the heap heap.Push(it.items, skipped) } } - if least.Next(descend) { - it.count += 1 + it.count++ heap.Push(it.items, least) } - return len(*it.items) > 0 } diff --git a/trie/iterator_test.go b/trie/iterator_test.go index dce1c78b5d..2a510b1c2d 100644 --- a/trie/iterator_test.go +++ b/trie/iterator_test.go @@ -289,7 +289,7 @@ func TestIteratorContinueAfterErrorDisk(t *testing.T) { testIteratorContinueA func TestIteratorContinueAfterErrorMemonly(t *testing.T) { testIteratorContinueAfterError(t, true) } func testIteratorContinueAfterError(t *testing.T, memonly bool) { - diskdb, _ := ethdb.NewMemDatabase() + diskdb := ethdb.NewMemDatabase() triedb := NewDatabase(diskdb) tr, _ := New(common.Hash{}, triedb) @@ -376,7 +376,7 @@ func TestIteratorContinueAfterSeekErrorMemonly(t *testing.T) { func testIteratorContinueAfterSeekError(t *testing.T, memonly bool) { // Commit test trie to db, then remove the node containing "bars". - diskdb, _ := ethdb.NewMemDatabase() + diskdb := ethdb.NewMemDatabase() triedb := NewDatabase(diskdb) ctr, _ := New(common.Hash{}, triedb) diff --git a/trie/node.go b/trie/node.go index 2b70d75314..a06f1b3898 100644 --- a/trie/node.go +++ b/trie/node.go @@ -27,63 +27,76 @@ import ( var indices = []string{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f", "[17]"} -type Node interface { +type node interface { fstring(string) string - Cache() (HashNode, bool) + cache() (hashNode, bool) canUnload(cachegen, cachelimit uint16) bool } type ( - FullNode struct { - Children [17]Node // Actual trie node data to encode/decode (needs custom encoder) + fullNode struct { + Children [17]node // Actual trie node data to encode/decode (needs custom encoder) flags nodeFlag } - ShortNode struct { + shortNode struct { Key []byte - Val Node + Val node flags nodeFlag } - HashNode []byte - ValueNode []byte + hashNode []byte + valueNode []byte ) +// nilValueNode is used when collapsing internal trie nodes for hashing, since +// unset children need to serialize correctly. +var nilValueNode = valueNode(nil) + // EncodeRLP encodes a full node into the consensus RLP format. -func (n *FullNode) EncodeRLP(w io.Writer) error { - return rlp.Encode(w, n.Children) +func (n *fullNode) EncodeRLP(w io.Writer) error { + var nodes [17]node + + for i, child := range n.Children { + if child != nil { + nodes[i] = child + } else { + nodes[i] = nilValueNode + } + } + return rlp.Encode(w, nodes) } -func (n *FullNode) copy() *FullNode { copy := *n; return © } -func (n *ShortNode) copy() *ShortNode { copy := *n; return © } +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) + hash hashNode // cached hash of the node (may be nil) gen uint16 // cache generation counter dirty bool // whether the node has changes that must be written to the database } -// canUnload tells whether a Node can be unloaded. +// canUnload tells whether a node can be unloaded. func (n *nodeFlag) canUnload(cachegen, cachelimit uint16) bool { return !n.dirty && cachegen-n.gen >= cachelimit } -func (n *FullNode) canUnload(gen, limit uint16) bool { return n.flags.canUnload(gen, limit) } -func (n *ShortNode) canUnload(gen, limit uint16) bool { return n.flags.canUnload(gen, limit) } -func (n HashNode) canUnload(uint16, uint16) bool { return false } -func (n ValueNode) canUnload(uint16, uint16) bool { return false } +func (n *fullNode) canUnload(gen, limit uint16) bool { return n.flags.canUnload(gen, limit) } +func (n *shortNode) canUnload(gen, limit uint16) bool { return n.flags.canUnload(gen, limit) } +func (n hashNode) canUnload(uint16, uint16) bool { return false } +func (n valueNode) canUnload(uint16, uint16) bool { return false } -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 } -func (n ValueNode) Cache() (HashNode, bool) { return nil, true } +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 } +func (n valueNode) cache() (hashNode, bool) { return nil, true } // Pretty printing. -func (n *FullNode) String() string { return n.fstring("") } -func (n *ShortNode) String() string { return n.fstring("") } -func (n HashNode) String() string { return n.fstring("") } -func (n ValueNode) String() string { return n.fstring("") } +func (n *fullNode) String() string { return n.fstring("") } +func (n *shortNode) String() string { return n.fstring("") } +func (n hashNode) String() string { return n.fstring("") } +func (n valueNode) String() string { return n.fstring("") } -func (n *FullNode) fstring(ind string) string { +func (n *fullNode) fstring(ind string) string { resp := fmt.Sprintf("[\n%s ", ind) for i, node := range n.Children { if node == nil { @@ -94,17 +107,17 @@ func (n *FullNode) fstring(ind string) string { } return resp + fmt.Sprintf("\n%s] ", ind) } -func (n *ShortNode) fstring(ind string) string { +func (n *shortNode) fstring(ind string) string { return fmt.Sprintf("{%x: %v} ", n.Key, n.Val.fstring(ind+" ")) } -func (n HashNode) fstring(ind string) string { +func (n hashNode) fstring(ind string) string { return fmt.Sprintf("<%x> ", []byte(n)) } -func (n ValueNode) fstring(ind string) string { +func (n valueNode) fstring(ind string) string { return fmt.Sprintf("%x ", []byte(n)) } -func MustDecodeNode(hash, buf []byte, cachegen uint16) Node { +func mustDecodeNode(hash, buf []byte, cachegen uint16) node { n, err := decodeNode(hash, buf, cachegen) if err != nil { panic(fmt.Sprintf("node %x: %v", hash, err)) @@ -113,7 +126,7 @@ func MustDecodeNode(hash, buf []byte, cachegen uint16) Node { } // decodeNode parses the RLP encoding of a trie node. -func decodeNode(hash, buf []byte, cachegen uint16) (Node, error) { +func decodeNode(hash, buf []byte, cachegen uint16) (node, error) { if len(buf) == 0 { return nil, io.ErrUnexpectedEOF } @@ -123,17 +136,17 @@ func decodeNode(hash, buf []byte, cachegen uint16) (Node, error) { } switch c, _ := rlp.CountValues(elems); c { case 2: - n, err := decodeShort(hash, buf, elems, cachegen) + n, err := decodeShort(hash, elems, cachegen) return n, wrapError(err, "short") case 17: - n, err := decodeFull(hash, buf, elems, cachegen) + n, err := decodeFull(hash, elems, cachegen) return n, wrapError(err, "full") default: return nil, fmt.Errorf("invalid number of list elements: %v", c) } } -func decodeShort(hash, buf, elems []byte, cachegen uint16) (Node, error) { +func decodeShort(hash, elems []byte, cachegen uint16) (node, error) { kbuf, rest, err := rlp.SplitString(elems) if err != nil { return nil, err @@ -146,17 +159,17 @@ func decodeShort(hash, buf, elems []byte, cachegen uint16) (Node, error) { if err != nil { return nil, fmt.Errorf("invalid value node: %v", err) } - return &ShortNode{key, append(ValueNode{}, val...), flag}, nil + return &shortNode{key, append(valueNode{}, val...), flag}, nil } r, _, err := decodeRef(rest, cachegen) if err != nil { return nil, wrapError(err, "val") } - return &ShortNode{key, r, flag}, nil + return &shortNode{key, r, flag}, nil } -func decodeFull(hash, buf, elems []byte, cachegen uint16) (*FullNode, error) { - n := &FullNode{flags: nodeFlag{hash: hash, gen: cachegen}} +func decodeFull(hash, elems []byte, cachegen uint16) (*fullNode, error) { + n := &fullNode{flags: nodeFlag{hash: hash, gen: cachegen}} for i := 0; i < 16; i++ { cld, rest, err := decodeRef(elems, cachegen) if err != nil { @@ -169,14 +182,14 @@ func decodeFull(hash, buf, elems []byte, cachegen uint16) (*FullNode, error) { return n, err } if len(val) > 0 { - n.Children[16] = append(ValueNode{}, val...) + n.Children[16] = append(valueNode{}, val...) } return n, nil } const hashLen = len(common.Hash{}) -func decodeRef(buf []byte, cachegen uint16) (Node, []byte, error) { +func decodeRef(buf []byte, cachegen uint16) (node, []byte, error) { kind, val, rest, err := rlp.Split(buf) if err != nil { return nil, buf, err @@ -195,7 +208,7 @@ func decodeRef(buf []byte, cachegen uint16) (Node, []byte, error) { // empty node return nil, rest, nil case kind == rlp.String && len(val) == 32: - return append(HashNode{}, val...), rest, nil + return append(hashNode{}, val...), rest, nil default: return nil, nil, fmt.Errorf("invalid RLP string size %d (want 0 or 32)", len(val)) } diff --git a/trie/proof.go b/trie/proof.go index 32738bd867..6cb8f4d5f7 100644 --- a/trie/proof.go +++ b/trie/proof.go @@ -37,11 +37,11 @@ import ( func (t *Trie) Prove(key []byte, fromLevel uint, proofDb ethdb.Putter) error { // Collect all nodes on the path to key. key = keybytesToHex(key) - nodes := []Node{} + nodes := []node{} tn := t.root for len(key) > 0 && tn != nil { switch n := tn.(type) { - case *ShortNode: + case *shortNode: if len(key) < len(n.Key) || !bytes.Equal(n.Key, key[:len(n.Key)]) { // The trie doesn't contain the key. tn = nil @@ -50,11 +50,11 @@ func (t *Trie) Prove(key []byte, fromLevel uint, proofDb ethdb.Putter) error { key = key[len(n.Key):] } nodes = append(nodes, n) - case *FullNode: + case *fullNode: tn = n.Children[key[0]] key = key[1:] nodes = append(nodes, n) - case HashNode: + case hashNode: var err error tn, err = t.resolveHash(n, nil) if err != nil { @@ -71,7 +71,7 @@ func (t *Trie) Prove(key []byte, fromLevel uint, proofDb ethdb.Putter) error { // if encoding doesn't work and we're not writing to any database. n, _, _ = hasher.hashChildren(n, nil) hn, _ := hasher.store(n, nil, false) - if hash, ok := hn.(HashNode); ok || i == 0 { + if hash, ok := hn.(hashNode); ok || i == 0 { // If the node's database encoding is a hash (or is the // root node), it becomes a proof element. if fromLevel > 0 { @@ -102,49 +102,49 @@ func (t *SecureTrie) Prove(key []byte, fromLevel uint, proofDb ethdb.Putter) err // VerifyProof checks merkle proofs. The given proof must contain the value for // key in a trie with the given root hash. VerifyProof returns an error if the // proof contains invalid trie nodes or the wrong value. -func VerifyProof(rootHash common.Hash, key []byte, proofDb DatabaseReader) (value []byte, err error, nodes int) { +func VerifyProof(rootHash common.Hash, key []byte, proofDb DatabaseReader) (value []byte, nodes int, err error) { key = keybytesToHex(key) wantHash := rootHash for i := 0; ; i++ { buf, _ := proofDb.Get(wantHash[:]) if buf == nil { - return nil, fmt.Errorf("proof node %d (hash %064x) missing", i, wantHash), i + return nil, i, fmt.Errorf("proof node %d (hash %064x) missing", i, wantHash) } n, err := decodeNode(wantHash[:], buf, 0) if err != nil { - return nil, fmt.Errorf("bad proof node %d: %v", i, err), i + return nil, i, fmt.Errorf("bad proof node %d: %v", i, err) } keyrest, cld := get(n, key) switch cld := cld.(type) { case nil: // The trie doesn't contain the key. - return nil, nil, i - case HashNode: + return nil, i, nil + case hashNode: key = keyrest copy(wantHash[:], cld) - case ValueNode: - return cld, nil, i + 1 + case valueNode: + return cld, i + 1, nil } } } -func get(tn Node, key []byte) ([]byte, Node) { +func get(tn node, key []byte) ([]byte, node) { for { switch n := tn.(type) { - case *ShortNode: + case *shortNode: if len(key) < len(n.Key) || !bytes.Equal(n.Key, key[:len(n.Key)]) { return nil, nil } tn = n.Val key = key[len(n.Key):] - case *FullNode: + case *fullNode: tn = n.Children[key[0]] key = key[1:] - case HashNode: + case hashNode: return key, n case nil: return key, nil - case ValueNode: + case valueNode: return nil, n default: panic(fmt.Sprintf("%T: invalid node: %v", tn, tn)) diff --git a/trie/proof_test.go b/trie/proof_test.go index fff313d7fd..996f874781 100644 --- a/trie/proof_test.go +++ b/trie/proof_test.go @@ -32,20 +32,46 @@ func init() { mrand.Seed(time.Now().Unix()) } +// makeProvers creates Merkle trie provers based on different implementations to +// test all variations. +func makeProvers(trie *Trie) []func(key []byte) *ethdb.MemDatabase { + var provers []func(key []byte) *ethdb.MemDatabase + + // Create a direct trie based Merkle prover + provers = append(provers, func(key []byte) *ethdb.MemDatabase { + proof := ethdb.NewMemDatabase() + trie.Prove(key, 0, proof) + return proof + }) + // Create a leaf iterator based Merkle prover + provers = append(provers, func(key []byte) *ethdb.MemDatabase { + proof := ethdb.NewMemDatabase() + if it := NewIterator(trie.NodeIterator(key)); it.Next() && bytes.Equal(key, it.Key) { + for _, p := range it.Prove() { + proof.Put(crypto.Keccak256(p), p) + } + } + return proof + }) + return provers +} + func TestProof(t *testing.T) { trie, vals := randomTrie(500) root := trie.Hash() - for _, kv := range vals { - proofs, _ := ethdb.NewMemDatabase() - if trie.Prove(kv.k, 0, proofs) != nil { - t.Fatalf("missing key %x while constructing proof", kv.k) - } - val, err, _ := VerifyProof(root, kv.k, proofs) - if err != nil { - t.Fatalf("VerifyProof error for key %x: %v\nraw proof: %v", kv.k, err, proofs) - } - if !bytes.Equal(val, kv.v) { - t.Fatalf("VerifyProof returned wrong value for key %x: got %x, want %x", kv.k, val, kv.v) + for i, prover := range makeProvers(trie) { + for _, kv := range vals { + proof := prover(kv.k) + if proof == nil { + t.Fatalf("prover %d: missing key %x while constructing proof", i, kv.k) + } + val, _, err := VerifyProof(root, kv.k, proof) + if err != nil { + t.Fatalf("prover %d: failed to verify proof for key %x: %v\nraw proof: %x", i, kv.k, err, proof) + } + if !bytes.Equal(val, kv.v) { + t.Fatalf("prover %d: verified value mismatch for key %x: have %x, want %x", i, kv.k, val, kv.v) + } } } } @@ -53,37 +79,66 @@ func TestProof(t *testing.T) { func TestOneElementProof(t *testing.T) { trie := new(Trie) updateString(trie, "k", "v") - proofs, _ := ethdb.NewMemDatabase() - trie.Prove([]byte("k"), 0, proofs) - if len(proofs.Keys()) != 1 { - t.Error("proof should have one element") - } - val, err, _ := VerifyProof(trie.Hash(), []byte("k"), proofs) - if err != nil { - t.Fatalf("VerifyProof error: %v\nproof hashes: %v", err, proofs.Keys()) - } - if !bytes.Equal(val, []byte("v")) { - t.Fatalf("VerifyProof returned wrong value: got %x, want 'k'", val) + for i, prover := range makeProvers(trie) { + proof := prover([]byte("k")) + if proof == nil { + t.Fatalf("prover %d: nil proof", i) + } + if proof.Len() != 1 { + t.Errorf("prover %d: proof should have one element", i) + } + val, _, err := VerifyProof(trie.Hash(), []byte("k"), proof) + if err != nil { + t.Fatalf("prover %d: failed to verify proof: %v\nraw proof: %x", i, err, proof) + } + if !bytes.Equal(val, []byte("v")) { + t.Fatalf("prover %d: verified value mismatch: have %x, want 'k'", i, val) + } } } -func TestVerifyBadProof(t *testing.T) { +func TestBadProof(t *testing.T) { trie, vals := randomTrie(800) root := trie.Hash() - for _, kv := range vals { - proofs, _ := ethdb.NewMemDatabase() - trie.Prove(kv.k, 0, proofs) - if len(proofs.Keys()) == 0 { - t.Fatal("zero length proof") + for i, prover := range makeProvers(trie) { + for _, kv := range vals { + proof := prover(kv.k) + if proof == nil { + t.Fatalf("prover %d: nil proof", i) + } + key := proof.Keys()[mrand.Intn(proof.Len())] + val, _ := proof.Get(key) + proof.Delete(key) + + mutateByte(val) + proof.Put(crypto.Keccak256(val), val) + + if _, _, err := VerifyProof(root, kv.k, proof); err == nil { + t.Fatalf("prover %d: expected proof to fail for key %x", i, kv.k) + } } - keys := proofs.Keys() - key := keys[mrand.Intn(len(keys))] - node, _ := proofs.Get(key) - proofs.Delete(key) - mutateByte(node) - proofs.Put(crypto.Keccak256(node), node) - if _, err, _ := VerifyProof(root, kv.k, proofs); err == nil { - t.Fatalf("expected proof to fail for key %x", kv.k) + } +} + +// Tests that missing keys can also be proven. The test explicitly uses a single +// entry trie and checks for missing keys both before and after the single entry. +func TestMissingKeyProof(t *testing.T) { + trie := new(Trie) + updateString(trie, "k", "v") + + for i, key := range []string{"a", "j", "l", "z"} { + proof := ethdb.NewMemDatabase() + trie.Prove([]byte(key), 0, proof) + + if proof.Len() != 1 { + t.Errorf("test %d: proof should have one element", i) + } + val, _, err := VerifyProof(trie.Hash(), []byte(key), proof) + if err != nil { + t.Fatalf("test %d: failed to verify proof: %v\nraw proof: %x", i, err, proof) + } + if val != nil { + t.Fatalf("test %d: verified value mismatch: have %x, want nil", i, val) } } } @@ -109,7 +164,7 @@ func BenchmarkProve(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { kv := vals[keys[i%len(keys)]] - proofs, _ := ethdb.NewMemDatabase() + proofs := ethdb.NewMemDatabase() if trie.Prove(kv.k, 0, proofs); len(proofs.Keys()) == 0 { b.Fatalf("zero length proof for %x", kv.k) } @@ -123,7 +178,7 @@ func BenchmarkVerifyProof(b *testing.B) { var proofs []*ethdb.MemDatabase for k := range vals { keys = append(keys, k) - proof, _ := ethdb.NewMemDatabase() + proof := ethdb.NewMemDatabase() trie.Prove([]byte(k), 0, proof) proofs = append(proofs, proof) } @@ -131,7 +186,7 @@ func BenchmarkVerifyProof(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { im := i % len(keys) - if _, err, _ := VerifyProof(root, []byte(keys[im]), proofs[im]); err != nil { + if _, _, err := VerifyProof(root, []byte(keys[im]), proofs[im]); err != nil { b.Fatalf("key %x: %v", keys[im], err) } } diff --git a/trie/secure_trie.go b/trie/secure_trie.go index 3881ee18a0..6a50cfd5a6 100644 --- a/trie/secure_trie.go +++ b/trie/secure_trie.go @@ -155,14 +155,19 @@ func (t *SecureTrie) Commit(onleaf LeafCallback) (root common.Hash, err error) { return t.trie.Commit(onleaf) } +// Hash returns the root hash of SecureTrie. It does not write to the +// database and can be used even if the trie doesn't have one. func (t *SecureTrie) Hash() common.Hash { return t.trie.Hash() } +// Root returns the root hash of SecureTrie. +// Deprecated: use Hash instead. func (t *SecureTrie) Root() []byte { return t.trie.Root() } +// Copy returns a copy of SecureTrie. func (t *SecureTrie) Copy() *SecureTrie { cpy := *t return &cpy diff --git a/trie/secure_trie_test.go b/trie/secure_trie_test.go index aedf5a1cde..d16d999684 100644 --- a/trie/secure_trie_test.go +++ b/trie/secure_trie_test.go @@ -28,18 +28,14 @@ import ( ) func newEmptySecure() *SecureTrie { - diskdb, _ := ethdb.NewMemDatabase() - triedb := NewDatabase(diskdb) - - trie, _ := NewSecure(common.Hash{}, triedb, 0) + trie, _ := NewSecure(common.Hash{}, NewDatabase(ethdb.NewMemDatabase()), 0) return trie } // makeTestSecureTrie creates a large enough secure trie for testing. func makeTestSecureTrie() (*Database, *SecureTrie, map[string][]byte) { // Create an empty trie - diskdb, _ := ethdb.NewMemDatabase() - triedb := NewDatabase(diskdb) + triedb := NewDatabase(ethdb.NewMemDatabase()) trie, _ := NewSecure(common.Hash{}, triedb, 0) diff --git a/trie/sync.go b/trie/sync.go index 3e0939fddd..ccec80c9e3 100644 --- a/trie/sync.go +++ b/trie/sync.go @@ -68,19 +68,19 @@ func newSyncMemBatch() *syncMemBatch { } } -// TrieSync is the main state trie synchronisation scheduler, which provides yet +// Sync is the main state trie synchronisation scheduler, which provides yet // unknown trie hashes to retrieve, accepts node data associated with said hashes // and reconstructs the trie step by step until all is done. -type TrieSync struct { +type Sync struct { database DatabaseReader // Persistent database to check for existing entries membatch *syncMemBatch // Memory buffer to avoid frequest database writes requests map[common.Hash]*request // Pending requests pertaining to a key hash queue *prque.Prque // Priority queue with the pending requests } -// NewTrieSync creates a new trie data download scheduler. -func NewTrieSync(root common.Hash, database DatabaseReader, callback LeafCallback) *TrieSync { - ts := &TrieSync{ +// NewSync creates a new trie data download scheduler. +func NewSync(root common.Hash, database DatabaseReader, callback LeafCallback) *Sync { + ts := &Sync{ database: database, membatch: newSyncMemBatch(), requests: make(map[common.Hash]*request), @@ -91,7 +91,7 @@ func NewTrieSync(root common.Hash, database DatabaseReader, callback LeafCallbac } // AddSubTrie registers a new trie to the sync code, rooted at the designated parent. -func (s *TrieSync) AddSubTrie(root common.Hash, depth int, parent common.Hash, callback LeafCallback) { +func (s *Sync) AddSubTrie(root common.Hash, depth int, parent common.Hash, callback LeafCallback) { // Short circuit if the trie is empty or already known if root == emptyRoot { return @@ -126,7 +126,7 @@ func (s *TrieSync) AddSubTrie(root common.Hash, depth int, parent common.Hash, c // interpreted as a trie node, but rather accepted and stored into the database // as is. This method's goal is to support misc state metadata retrievals (e.g. // contract code). -func (s *TrieSync) AddRawEntry(hash common.Hash, depth int, parent common.Hash) { +func (s *Sync) AddRawEntry(hash common.Hash, depth int, parent common.Hash) { // Short circuit if the entry is empty or already known if hash == emptyState { return @@ -156,7 +156,7 @@ func (s *TrieSync) AddRawEntry(hash common.Hash, depth int, parent common.Hash) } // Missing retrieves the known missing nodes from the trie for retrieval. -func (s *TrieSync) Missing(max int) []common.Hash { +func (s *Sync) Missing(max int) []common.Hash { requests := []common.Hash{} for !s.queue.Empty() && (max == 0 || len(requests) < max) { requests = append(requests, s.queue.PopItem().(common.Hash)) @@ -167,7 +167,7 @@ func (s *TrieSync) Missing(max int) []common.Hash { // Process injects a batch of retrieved trie nodes data, returning if something // was committed to the database and also the index of an entry if processing of // it failed. -func (s *TrieSync) Process(results []SyncResult) (bool, int, error) { +func (s *Sync) Process(results []SyncResult) (bool, int, error) { committed := false for i, item := range results { @@ -212,8 +212,8 @@ func (s *TrieSync) Process(results []SyncResult) (bool, int, error) { } // Commit flushes the data stored in the internal membatch out to persistent -// storage, returning th enumber of items written and any occurred error. -func (s *TrieSync) Commit(dbw ethdb.Putter) (int, error) { +// storage, returning the number of items written and any occurred error. +func (s *Sync) Commit(dbw ethdb.Putter) (int, error) { // Dump the membatch into a database dbw for i, key := range s.membatch.order { if err := dbw.Put(key[:], s.membatch.batch[key]); err != nil { @@ -228,14 +228,14 @@ func (s *TrieSync) Commit(dbw ethdb.Putter) (int, error) { } // Pending returns the number of state entries currently pending for download. -func (s *TrieSync) Pending() int { +func (s *Sync) Pending() int { return len(s.requests) } // schedule inserts a new state retrieval request into the fetch queue. If there // is already a pending request for this node, the new request will be discarded // and only a parent reference added to the old one. -func (s *TrieSync) schedule(req *request) { +func (s *Sync) schedule(req *request) { // If we're already requesting this node, add a new reference and stop if old, ok := s.requests[req.hash]; ok { old.parents = append(old.parents, req.parents...) @@ -248,21 +248,21 @@ func (s *TrieSync) schedule(req *request) { // children retrieves all the missing children of a state trie entry for future // retrieval scheduling. -func (s *TrieSync) children(req *request, object Node) ([]*request, error) { +func (s *Sync) children(req *request, object node) ([]*request, error) { // Gather all the children of the node, irrelevant whether known or not type child struct { - node Node + node node depth int } children := []child{} switch node := (object).(type) { - case *ShortNode: + case *shortNode: children = []child{{ node: node.Val, depth: req.depth + len(node.Key), }} - case *FullNode: + case *fullNode: for i := 0; i < 17; i++ { if node.Children[i] != nil { children = append(children, child{ @@ -279,14 +279,14 @@ func (s *TrieSync) children(req *request, object Node) ([]*request, error) { for _, child := range children { // Notify any external watcher of a new key/value node if req.callback != nil { - if node, ok := (child.node).(ValueNode); ok { + if node, ok := (child.node).(valueNode); ok { if err := req.callback(node, req.hash); err != nil { return nil, err } } } // If the child references another node, resolve or schedule - if node, ok := (child.node).(HashNode); ok { + if node, ok := (child.node).(hashNode); ok { // Try to resolve the node from the local database hash := common.BytesToHash(node) if _, ok := s.membatch.batch[hash]; ok { @@ -310,7 +310,7 @@ func (s *TrieSync) children(req *request, object Node) ([]*request, error) { // commit finalizes a retrieval request and stores it into the membatch. If any // of the referencing parent requests complete due to this commit, they are also // committed themselves. -func (s *TrieSync) commit(req *request) (err error) { +func (s *Sync) commit(req *request) (err error) { // Write the node content to the membatch s.membatch.batch[req.hash] = req.data s.membatch.order = append(s.membatch.order, req.hash) diff --git a/trie/sync_test.go b/trie/sync_test.go index 4a720612b6..c76779e5c7 100644 --- a/trie/sync_test.go +++ b/trie/sync_test.go @@ -27,8 +27,7 @@ import ( // makeTestTrie create a sample test trie to test node-wise reconstruction. func makeTestTrie() (*Database, *Trie, map[string][]byte) { // Create an empty trie - diskdb, _ := ethdb.NewMemDatabase() - triedb := NewDatabase(diskdb) + triedb := NewDatabase(ethdb.NewMemDatabase()) trie, _ := New(common.Hash{}, triedb) // Fill it with some arbitrary data @@ -88,19 +87,14 @@ func checkTrieConsistency(db *Database, root common.Hash) error { } // Tests that an empty trie is not scheduled for syncing. -func TestEmptyTrieSync(t *testing.T) { - diskdbA, _ := ethdb.NewMemDatabase() - triedbA := NewDatabase(diskdbA) - - diskdbB, _ := ethdb.NewMemDatabase() - triedbB := NewDatabase(diskdbB) - - emptyA, _ := New(common.Hash{}, triedbA) - emptyB, _ := New(emptyRoot, triedbB) +func TestEmptySync(t *testing.T) { + dbA := NewDatabase(ethdb.NewMemDatabase()) + dbB := NewDatabase(ethdb.NewMemDatabase()) + emptyA, _ := New(common.Hash{}, dbA) + emptyB, _ := New(emptyRoot, dbB) for i, trie := range []*Trie{emptyA, emptyB} { - diskdb, _ := ethdb.NewMemDatabase() - if req := NewTrieSync(trie.Hash(), diskdb, nil).Missing(1); len(req) != 0 { + if req := NewSync(trie.Hash(), ethdb.NewMemDatabase(), nil).Missing(1); len(req) != 0 { t.Errorf("test %d: content requested for empty trie: %v", i, req) } } @@ -108,17 +102,17 @@ func TestEmptyTrieSync(t *testing.T) { // Tests that given a root hash, a trie can sync iteratively on a single thread, // requesting retrieval tasks and returning all of them in one go. -func TestIterativeTrieSyncIndividual(t *testing.T) { testIterativeTrieSync(t, 1) } -func TestIterativeTrieSyncBatched(t *testing.T) { testIterativeTrieSync(t, 100) } +func TestIterativeSyncIndividual(t *testing.T) { testIterativeSync(t, 1) } +func TestIterativeSyncBatched(t *testing.T) { testIterativeSync(t, 100) } -func testIterativeTrieSync(t *testing.T, batch int) { +func testIterativeSync(t *testing.T, batch int) { // Create a random trie to copy srcDb, srcTrie, srcData := makeTestTrie() // Create a destination trie and sync with the scheduler - diskdb, _ := ethdb.NewMemDatabase() + diskdb := ethdb.NewMemDatabase() triedb := NewDatabase(diskdb) - sched := NewTrieSync(srcTrie.Hash(), diskdb, nil) + sched := NewSync(srcTrie.Hash(), diskdb, nil) queue := append([]common.Hash{}, sched.Missing(batch)...) for len(queue) > 0 { @@ -144,14 +138,14 @@ func testIterativeTrieSync(t *testing.T, batch int) { // Tests that the trie scheduler can correctly reconstruct the state even if only // partial results are returned, and the others sent only later. -func TestIterativeDelayedTrieSync(t *testing.T) { +func TestIterativeDelayedSync(t *testing.T) { // Create a random trie to copy srcDb, srcTrie, srcData := makeTestTrie() // Create a destination trie and sync with the scheduler - diskdb, _ := ethdb.NewMemDatabase() + diskdb := ethdb.NewMemDatabase() triedb := NewDatabase(diskdb) - sched := NewTrieSync(srcTrie.Hash(), diskdb, nil) + sched := NewSync(srcTrie.Hash(), diskdb, nil) queue := append([]common.Hash{}, sched.Missing(10000)...) for len(queue) > 0 { @@ -179,17 +173,17 @@ func TestIterativeDelayedTrieSync(t *testing.T) { // Tests that given a root hash, a trie can sync iteratively on a single thread, // requesting retrieval tasks and returning all of them in one go, however in a // random order. -func TestIterativeRandomTrieSyncIndividual(t *testing.T) { testIterativeRandomTrieSync(t, 1) } -func TestIterativeRandomTrieSyncBatched(t *testing.T) { testIterativeRandomTrieSync(t, 100) } +func TestIterativeRandomSyncIndividual(t *testing.T) { testIterativeRandomSync(t, 1) } +func TestIterativeRandomSyncBatched(t *testing.T) { testIterativeRandomSync(t, 100) } -func testIterativeRandomTrieSync(t *testing.T, batch int) { +func testIterativeRandomSync(t *testing.T, batch int) { // Create a random trie to copy srcDb, srcTrie, srcData := makeTestTrie() // Create a destination trie and sync with the scheduler - diskdb, _ := ethdb.NewMemDatabase() + diskdb := ethdb.NewMemDatabase() triedb := NewDatabase(diskdb) - sched := NewTrieSync(srcTrie.Hash(), diskdb, nil) + sched := NewSync(srcTrie.Hash(), diskdb, nil) queue := make(map[common.Hash]struct{}) for _, hash := range sched.Missing(batch) { @@ -223,14 +217,14 @@ func testIterativeRandomTrieSync(t *testing.T, batch int) { // Tests that the trie scheduler can correctly reconstruct the state even if only // partial results are returned (Even those randomly), others sent only later. -func TestIterativeRandomDelayedTrieSync(t *testing.T) { +func TestIterativeRandomDelayedSync(t *testing.T) { // Create a random trie to copy srcDb, srcTrie, srcData := makeTestTrie() // Create a destination trie and sync with the scheduler - diskdb, _ := ethdb.NewMemDatabase() + diskdb := ethdb.NewMemDatabase() triedb := NewDatabase(diskdb) - sched := NewTrieSync(srcTrie.Hash(), diskdb, nil) + sched := NewSync(srcTrie.Hash(), diskdb, nil) queue := make(map[common.Hash]struct{}) for _, hash := range sched.Missing(10000) { @@ -270,14 +264,14 @@ func TestIterativeRandomDelayedTrieSync(t *testing.T) { // Tests that a trie sync will not request nodes multiple times, even if they // have such references. -func TestDuplicateAvoidanceTrieSync(t *testing.T) { +func TestDuplicateAvoidanceSync(t *testing.T) { // Create a random trie to copy srcDb, srcTrie, srcData := makeTestTrie() // Create a destination trie and sync with the scheduler - diskdb, _ := ethdb.NewMemDatabase() + diskdb := ethdb.NewMemDatabase() triedb := NewDatabase(diskdb) - sched := NewTrieSync(srcTrie.Hash(), diskdb, nil) + sched := NewSync(srcTrie.Hash(), diskdb, nil) queue := append([]common.Hash{}, sched.Missing(0)...) requested := make(map[common.Hash]struct{}) @@ -310,14 +304,14 @@ func TestDuplicateAvoidanceTrieSync(t *testing.T) { // Tests that at any point in time during a sync, only complete sub-tries are in // the database. -func TestIncompleteTrieSync(t *testing.T) { +func TestIncompleteSync(t *testing.T) { // Create a random trie to copy srcDb, srcTrie, _ := makeTestTrie() // Create a destination trie and sync with the scheduler - diskdb, _ := ethdb.NewMemDatabase() + diskdb := ethdb.NewMemDatabase() triedb := NewDatabase(diskdb) - sched := NewTrieSync(srcTrie.Hash(), diskdb, nil) + sched := NewSync(srcTrie.Hash(), diskdb, nil) added := []common.Hash{} queue := append([]common.Hash{}, sched.Missing(1)...) diff --git a/trie/trie.go b/trie/trie.go index 0f0688a03e..4284e30ad4 100644 --- a/trie/trie.go +++ b/trie/trie.go @@ -66,7 +66,7 @@ type LeafCallback func(leaf []byte, parent common.Hash) error // Trie is not safe for concurrent use. type Trie struct { db *Database - root Node + root node originalRoot common.Hash // Cache generation values. @@ -101,7 +101,7 @@ func New(root common.Hash, db *Database) (*Trie, error) { db: db, originalRoot: root, } - if (root != common.Hash{}) && root != emptyRoot { + if root != (common.Hash{}) && root != emptyRoot { rootnode, err := trie.resolveHash(root[:], nil) if err != nil { return nil, err @@ -114,7 +114,7 @@ func New(root common.Hash, db *Database) (*Trie, error) { // NodeIterator returns an iterator that returns nodes of the trie. Iteration starts at // the key after the given start key. func (t *Trie) NodeIterator(start []byte) NodeIterator { - return NewNodeIterator(t, start) + return newNodeIterator(t, start) } // Get returns the value for key stored in the trie. @@ -139,13 +139,13 @@ func (t *Trie) TryGet(key []byte) ([]byte, error) { return value, err } -func (t *Trie) tryGet(origNode Node, key []byte, pos int) (value []byte, newnode Node, didResolve bool, err error) { +func (t *Trie) tryGet(origNode node, key []byte, pos int) (value []byte, newnode node, didResolve bool, err error) { switch n := (origNode).(type) { case nil: return nil, nil, false, nil - case ValueNode: + case valueNode: return n, n, false, nil - case *ShortNode: + case *shortNode: if len(key)-pos < len(n.Key) || !bytes.Equal(n.Key, key[pos:pos+len(n.Key)]) { // key not found in trie return nil, n, false, nil @@ -157,7 +157,7 @@ func (t *Trie) tryGet(origNode Node, key []byte, pos int) (value []byte, newnode n.flags.gen = t.cachegen } return value, n, didResolve, err - case *FullNode: + case *fullNode: value, newnode, didResolve, err = t.tryGet(n.Children[key[pos]], key, pos+1) if err == nil && didResolve { n = n.copy() @@ -165,7 +165,7 @@ func (t *Trie) tryGet(origNode Node, key []byte, pos int) (value []byte, newnode n.Children[key[pos]] = newnode } return value, n, didResolve, err - case HashNode: + case hashNode: child, err := t.resolveHash(n, key[:pos]) if err != nil { return nil, n, true, err @@ -200,7 +200,7 @@ func (t *Trie) Update(key, value []byte) { func (t *Trie) TryUpdate(key, value []byte) error { k := keybytesToHex(key) if len(value) != 0 { - _, n, err := t.insert(t.root, nil, k, ValueNode(value)) + _, n, err := t.insert(t.root, nil, k, valueNode(value)) if err != nil { return err } @@ -215,15 +215,15 @@ func (t *Trie) TryUpdate(key, value []byte) error { return nil } -func (t *Trie) insert(n Node, prefix, key []byte, value Node) (bool, Node, error) { +func (t *Trie) insert(n node, prefix, key []byte, value node) (bool, node, error) { if len(key) == 0 { - if v, ok := n.(ValueNode); ok { - return !bytes.Equal(v, value.(ValueNode)), value, nil + if v, ok := n.(valueNode); ok { + return !bytes.Equal(v, value.(valueNode)), value, nil } return true, value, nil } switch n := n.(type) { - case *ShortNode: + case *shortNode: matchlen := prefixLen(key, n.Key) // If the whole key matches, keep this short node as is // and only update the value. @@ -232,10 +232,10 @@ func (t *Trie) insert(n Node, prefix, key []byte, value Node) (bool, Node, error if !dirty || err != nil { return false, n, err } - return true, &ShortNode{n.Key, nn, t.newFlag()}, nil + return true, &shortNode{n.Key, nn, t.newFlag()}, nil } // Otherwise branch out at the index where they differ. - branch := &FullNode{flags: t.newFlag()} + branch := &fullNode{flags: t.newFlag()} var err error _, branch.Children[n.Key[matchlen]], err = t.insert(nil, append(prefix, n.Key[:matchlen+1]...), n.Key[matchlen+1:], n.Val) if err != nil { @@ -250,9 +250,9 @@ func (t *Trie) insert(n Node, prefix, key []byte, value Node) (bool, Node, error return true, branch, nil } // Otherwise, replace it with a short node leading up to the branch. - return true, &ShortNode{key[:matchlen], branch, t.newFlag()}, nil + return true, &shortNode{key[:matchlen], branch, t.newFlag()}, nil - case *FullNode: + case *fullNode: dirty, nn, err := t.insert(n.Children[key[0]], append(prefix, key[0]), key[1:], value) if !dirty || err != nil { return false, n, err @@ -263,9 +263,9 @@ func (t *Trie) insert(n Node, prefix, key []byte, value Node) (bool, Node, error return true, n, nil case nil: - return true, &ShortNode{key, value, t.newFlag()}, nil + return true, &shortNode{key, value, t.newFlag()}, nil - case HashNode: + case hashNode: // We've hit a part of the trie that isn't loaded yet. Load // the node and insert into it. This leaves all child nodes on // the path to the value in the trie. @@ -306,9 +306,9 @@ func (t *Trie) TryDelete(key []byte) error { // delete returns the new root of the trie with key deleted. // It reduces the trie to minimal form by simplifying // nodes on the way up after deleting recursively. -func (t *Trie) delete(n Node, prefix, key []byte) (bool, Node, error) { +func (t *Trie) delete(n node, prefix, key []byte) (bool, node, error) { switch n := n.(type) { - case *ShortNode: + case *shortNode: matchlen := prefixLen(key, n.Key) if matchlen < len(n.Key) { return false, n, nil // don't replace n on mismatch @@ -325,19 +325,19 @@ func (t *Trie) delete(n Node, prefix, key []byte) (bool, Node, error) { return false, n, err } switch child := child.(type) { - case *ShortNode: + case *shortNode: // Deleting from the subtrie reduced it to another // short node. Merge the nodes to avoid creating a // shortNode{..., shortNode{...}}. Use concat (which // always creates a new slice) instead of append to // avoid modifying n.Key since it might be shared with // other nodes. - return true, &ShortNode{concat(n.Key, child.Key...), child.Val, t.newFlag()}, nil + return true, &shortNode{concat(n.Key, child.Key...), child.Val, t.newFlag()}, nil default: - return true, &ShortNode{n.Key, child, t.newFlag()}, nil + return true, &shortNode{n.Key, child, t.newFlag()}, nil } - case *FullNode: + case *fullNode: dirty, nn, err := t.delete(n.Children[key[0]], append(prefix, key[0]), key[1:]) if !dirty || err != nil { return false, n, err @@ -368,7 +368,7 @@ func (t *Trie) delete(n Node, prefix, key []byte) (bool, Node, error) { } if pos >= 0 { if pos != 16 { - // If the remaining entry is a short node, it replaces + // If the remaining entry is a short node, it replaces // n and its key gets the missing nibble tacked to the // front. This avoids creating an invalid // shortNode{..., shortNode{...}}. Since the entry @@ -378,25 +378,25 @@ func (t *Trie) delete(n Node, prefix, key []byte) (bool, Node, error) { if err != nil { return false, nil, err } - if cnode, ok := cnode.(*ShortNode); ok { + if cnode, ok := cnode.(*shortNode); ok { k := append([]byte{byte(pos)}, cnode.Key...) - return true, &ShortNode{k, cnode.Val, t.newFlag()}, nil + return true, &shortNode{k, cnode.Val, t.newFlag()}, nil } } // Otherwise, n is replaced by a one-nibble short node // containing the child. - return true, &ShortNode{[]byte{byte(pos)}, n.Children[pos], t.newFlag()}, nil + return true, &shortNode{[]byte{byte(pos)}, n.Children[pos], t.newFlag()}, nil } // n still contains at least two values and cannot be reduced. return true, n, nil - case ValueNode: + case valueNode: return true, nil, nil case nil: return false, nil, nil - case HashNode: + case hashNode: // We've hit a part of the trie that isn't loaded yet. Load // the node and delete from it. This leaves all child nodes on // the path to the value in the trie. @@ -422,23 +422,21 @@ func concat(s1 []byte, s2 ...byte) []byte { return r } -func (t *Trie) resolve(n Node, prefix []byte) (Node, error) { - if n, ok := n.(HashNode); ok { +func (t *Trie) resolve(n node, prefix []byte) (node, error) { + if n, ok := n.(hashNode); ok { return t.resolveHash(n, prefix) } return n, nil } -func (t *Trie) resolveHash(n HashNode, prefix []byte) (Node, error) { +func (t *Trie) resolveHash(n hashNode, prefix []byte) (node, error) { cacheMissCounter.Inc(1) hash := common.BytesToHash(n) - - enc, err := t.db.Node(hash) - if err != nil || enc == nil { - return nil, &MissingNodeError{NodeHash: hash, Path: prefix} + if node := t.db.node(hash, t.cachegen); node != nil { + return node, nil } - return MustDecodeNode(n, enc, t.cachegen), nil + return nil, &MissingNodeError{NodeHash: hash, Path: prefix} } // Root returns the root hash of the trie. @@ -450,7 +448,7 @@ func (t *Trie) Root() []byte { return t.Hash().Bytes() } func (t *Trie) Hash() common.Hash { hash, cached, _ := t.hashRoot(nil, nil) t.root = cached - return common.BytesToHash(hash.(HashNode)) + return common.BytesToHash(hash.(hashNode)) } // Commit writes all nodes to the trie's memory database, tracking the internal @@ -465,12 +463,12 @@ func (t *Trie) Commit(onleaf LeafCallback) (root common.Hash, err error) { } t.root = cached t.cachegen++ - return common.BytesToHash(hash.(HashNode)), nil + return common.BytesToHash(hash.(hashNode)), nil } -func (t *Trie) hashRoot(db *Database, onleaf LeafCallback) (Node, Node, error) { +func (t *Trie) hashRoot(db *Database, onleaf LeafCallback) (node, node, error) { if t.root == nil { - return HashNode(emptyRoot.Bytes()), nil, nil + return hashNode(emptyRoot.Bytes()), nil, nil } h := newHasher(t.cachegen, t.cachelimit, onleaf) defer returnHasherToPool(h) diff --git a/trie/trie_test.go b/trie/trie_test.go index 8a8436270a..f8e5fd12a1 100644 --- a/trie/trie_test.go +++ b/trie/trie_test.go @@ -43,8 +43,7 @@ func init() { // Used for testing func newEmpty() *Trie { - diskdb, _ := ethdb.NewMemDatabase() - trie, _ := New(common.Hash{}, NewDatabase(diskdb)) + trie, _ := New(common.Hash{}, NewDatabase(ethdb.NewMemDatabase())) return trie } @@ -68,8 +67,7 @@ func TestNull(t *testing.T) { } func TestMissingRoot(t *testing.T) { - diskdb, _ := ethdb.NewMemDatabase() - trie, err := New(common.HexToHash("0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33"), NewDatabase(diskdb)) + trie, err := New(common.HexToHash("0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33"), NewDatabase(ethdb.NewMemDatabase())) if trie != nil { t.Error("New returned non-nil trie for invalid root") } @@ -82,7 +80,7 @@ func TestMissingNodeDisk(t *testing.T) { testMissingNode(t, false) } func TestMissingNodeMemonly(t *testing.T) { testMissingNode(t, true) } func testMissingNode(t *testing.T, memonly bool) { - diskdb, _ := ethdb.NewMemDatabase() + diskdb := ethdb.NewMemDatabase() triedb := NewDatabase(diskdb) trie, _ := New(common.Hash{}, triedb) @@ -413,8 +411,7 @@ func (randTest) Generate(r *rand.Rand, size int) reflect.Value { } func runRandTest(rt randTest) bool { - diskdb, _ := ethdb.NewMemDatabase() - triedb := NewDatabase(diskdb) + triedb := NewDatabase(ethdb.NewMemDatabase()) tr, _ := New(common.Hash{}, triedb) values := make(map[string]string) // tracks content of the trie @@ -469,14 +466,14 @@ func runRandTest(rt randTest) bool { return true } -func checkCacheInvariant(n, parent Node, parentCachegen uint16, parentDirty bool, depth int) error { - var children []Node +func checkCacheInvariant(n, parent node, parentCachegen uint16, parentDirty bool, depth int) error { + var children []node var flag nodeFlag switch n := n.(type) { - case *ShortNode: + case *shortNode: flag = n.flags - children = []Node{n.Val} - case *FullNode: + children = []node{n.Val} + case *fullNode: flag = n.flags children = n.Children[:] default: diff --git a/vendor/github.com/Azure/azure-storage-go/LICENSE b/vendor/github.com/Azure/azure-pipeline-go/LICENSE similarity index 98% rename from vendor/github.com/Azure/azure-storage-go/LICENSE rename to vendor/github.com/Azure/azure-pipeline-go/LICENSE index 21071075c2..d1ca00f20a 100644 --- a/vendor/github.com/Azure/azure-storage-go/LICENSE +++ b/vendor/github.com/Azure/azure-pipeline-go/LICENSE @@ -18,4 +18,4 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE + SOFTWARE \ No newline at end of file diff --git a/vendor/github.com/Azure/azure-pipeline-go/pipeline/core.go b/vendor/github.com/Azure/azure-pipeline-go/pipeline/core.go new file mode 100755 index 0000000000..0dde81d728 --- /dev/null +++ b/vendor/github.com/Azure/azure-pipeline-go/pipeline/core.go @@ -0,0 +1,255 @@ +package pipeline + +import ( + "context" + "net" + "net/http" + "os" + "time" +) + +// The Factory interface represents an object that can create its Policy object. Each HTTP request sent +// requires that this Factory create a new instance of its Policy object. +type Factory interface { + New(next Policy, po *PolicyOptions) Policy +} + +// FactoryFunc is an adapter that allows the use of an ordinary function as a Factory interface. +type FactoryFunc func(next Policy, po *PolicyOptions) PolicyFunc + +// New calls f(next,po). +func (f FactoryFunc) New(next Policy, po *PolicyOptions) Policy { + return f(next, po) +} + +// The Policy interface represents a mutable Policy object created by a Factory. The object can mutate/process +// the HTTP request and then forward it on to the next Policy object in the linked-list. The returned +// Response goes backward through the linked-list for additional processing. +// NOTE: Request is passed by value so changes do not change the caller's version of +// the request. However, Request has some fields that reference mutable objects (not strings). +// These references are copied; a deep copy is not performed. Specifically, this means that +// you should avoid modifying the objects referred to by these fields: URL, Header, Body, +// GetBody, TransferEncoding, Form, MultipartForm, Trailer, TLS, Cancel, and Response. +type Policy interface { + Do(ctx context.Context, request Request) (Response, error) +} + +// PolicyFunc is an adapter that allows the use of an ordinary function as a Policy interface. +type PolicyFunc func(ctx context.Context, request Request) (Response, error) + +// Do calls f(ctx, request). +func (f PolicyFunc) Do(ctx context.Context, request Request) (Response, error) { + return f(ctx, request) +} + +// Options configures a Pipeline's behavior. +type Options struct { + HTTPSender Factory // If sender is nil, then the pipeline's default client is used to send the HTTP requests. + Log LogOptions +} + +// LogLevel tells a logger the minimum level to log. When code reports a log entry, +// the LogLevel indicates the level of the log entry. The logger only records entries +// whose level is at least the level it was told to log. See the Log* constants. +// For example, if a logger is configured with LogError, then LogError, LogPanic, +// and LogFatal entries will be logged; lower level entries are ignored. +type LogLevel uint32 + +const ( + // LogNone tells a logger not to log any entries passed to it. + LogNone LogLevel = iota + + // LogFatal tells a logger to log all LogFatal entries passed to it. + LogFatal + + // LogPanic tells a logger to log all LogPanic and LogFatal entries passed to it. + LogPanic + + // LogError tells a logger to log all LogError, LogPanic and LogFatal entries passed to it. + LogError + + // LogWarning tells a logger to log all LogWarning, LogError, LogPanic and LogFatal entries passed to it. + LogWarning + + // LogInfo tells a logger to log all LogInfo, LogWarning, LogError, LogPanic and LogFatal entries passed to it. + LogInfo + + // LogDebug tells a logger to log all LogDebug, LogInfo, LogWarning, LogError, LogPanic and LogFatal entries passed to it. + LogDebug +) + +// LogOptions configures the pipeline's logging mechanism & level filtering. +type LogOptions struct { + Log func(level LogLevel, message string) + + // ShouldLog is called periodically allowing you to return whether the specified LogLevel should be logged or not. + // An application can return different values over the its lifetime; this allows the application to dynamically + // alter what is logged. NOTE: This method can be called by multiple goroutines simultaneously so make sure + // you implement it in a goroutine-safe way. If nil, nothing is logged (the equivalent of returning LogNone). + // Usually, the function will be implemented simply like this: return level <= LogWarning + ShouldLog func(level LogLevel) bool +} + +type pipeline struct { + factories []Factory + options Options +} + +// The Pipeline interface represents an ordered list of Factory objects and an object implementing the HTTPSender interface. +// You construct a Pipeline by calling the pipeline.NewPipeline function. To send an HTTP request, call pipeline.NewRequest +// and then call Pipeline's Do method passing a context, the request, and a method-specific Factory (or nil). Passing a +// method-specific Factory allows this one call to Do to inject a Policy into the linked-list. The policy is injected where +// the MethodFactoryMarker (see the pipeline.MethodFactoryMarker function) is in the slice of Factory objects. +// +// When Do is called, the Pipeline object asks each Factory object to construct its Policy object and adds each Policy to a linked-list. +// THen, Do sends the Context and Request through all the Policy objects. The final Policy object sends the request over the network +// (via the HTTPSender object passed to NewPipeline) and the response is returned backwards through all the Policy objects. +// Since Pipeline and Factory objects are goroutine-safe, you typically create 1 Pipeline object and reuse it to make many HTTP requests. +type Pipeline interface { + Do(ctx context.Context, methodFactory Factory, request Request) (Response, error) +} + +// NewPipeline creates a new goroutine-safe Pipeline object from the slice of Factory objects and the specified options. +func NewPipeline(factories []Factory, o Options) Pipeline { + if o.HTTPSender == nil { + o.HTTPSender = newDefaultHTTPClientFactory() + } + if o.Log.Log == nil { + o.Log.Log = func(LogLevel, string) {} // No-op logger + } + return &pipeline{factories: factories, options: o} +} + +// Do is called for each and every HTTP request. It tells each Factory to create its own (mutable) Policy object +// replacing a MethodFactoryMarker factory (if it exists) with the methodFactory passed in. Then, the Context and Request +// are sent through the pipeline of Policy objects (which can transform the Request's URL/query parameters/headers) and +// ultimately sends the transformed HTTP request over the network. +func (p *pipeline) Do(ctx context.Context, methodFactory Factory, request Request) (Response, error) { + response, err := p.newPolicies(methodFactory).Do(ctx, request) + request.close() + return response, err +} + +func (p *pipeline) newPolicies(methodFactory Factory) Policy { + // The last Policy is the one that actually sends the request over the wire and gets the response. + // It is overridable via the Options' HTTPSender field. + po := &PolicyOptions{pipeline: p} // One object shared by all policy objects + next := p.options.HTTPSender.New(nil, po) + + // Walk over the slice of Factory objects in reverse (from wire to API) + markers := 0 + for i := len(p.factories) - 1; i >= 0; i-- { + factory := p.factories[i] + if _, ok := factory.(methodFactoryMarker); ok { + markers++ + if markers > 1 { + panic("MethodFactoryMarker can only appear once in the pipeline") + } + if methodFactory != nil { + // Replace MethodFactoryMarker with passed-in methodFactory + next = methodFactory.New(next, po) + } + } else { + // Use the slice's Factory to construct its Policy + next = factory.New(next, po) + } + } + + // Each Factory has created its Policy + if markers == 0 && methodFactory != nil { + panic("Non-nil methodFactory requires MethodFactoryMarker in the pipeline") + } + return next // Return head of the Policy object linked-list +} + +// A PolicyOptions represents optional information that can be used by a node in the +// linked-list of Policy objects. A PolicyOptions is passed to the Factory's New method +// which passes it (if desired) to the Policy object it creates. Today, the Policy object +// uses the options to perform logging. But, in the future, this could be used for more. +type PolicyOptions struct { + pipeline *pipeline +} + +// ShouldLog returns true if the specified log level should be logged. +func (po *PolicyOptions) ShouldLog(level LogLevel) bool { + if po.pipeline.options.Log.ShouldLog != nil { + return po.pipeline.options.Log.ShouldLog(level) + } + return false +} + +// Log logs a string to the Pipeline's Logger. +func (po *PolicyOptions) Log(level LogLevel, msg string) { + if !po.ShouldLog(level) { + return // Short circuit message formatting if we're not logging it + } + + // We are logging it, ensure trailing newline + if len(msg) == 0 || msg[len(msg)-1] != '\n' { + msg += "\n" // Ensure trailing newline + } + po.pipeline.options.Log.Log(level, msg) + + // If logger doesn't handle fatal/panic, we'll do it here. + if level == LogFatal { + os.Exit(1) + } else if level == LogPanic { + panic(msg) + } +} + +var pipelineHTTPClient = newDefaultHTTPClient() + +func newDefaultHTTPClient() *http.Client { + // We want the Transport to have a large connection pool + return &http.Client{ + Transport: &http.Transport{ + Proxy: http.ProxyFromEnvironment, + // We use Dial instead of DialContext as DialContext has been reported to cause slower performance. + Dial /*Context*/ : (&net.Dialer{ + Timeout: 30 * time.Second, + KeepAlive: 30 * time.Second, + DualStack: true, + }).Dial, /*Context*/ + MaxIdleConns: 0, // No limit + MaxIdleConnsPerHost: 100, + IdleConnTimeout: 90 * time.Second, + TLSHandshakeTimeout: 10 * time.Second, + ExpectContinueTimeout: 1 * time.Second, + DisableKeepAlives: false, + DisableCompression: false, + MaxResponseHeaderBytes: 0, + //ResponseHeaderTimeout: time.Duration{}, + //ExpectContinueTimeout: time.Duration{}, + }, + } +} + +// newDefaultHTTPClientFactory creates a DefaultHTTPClientPolicyFactory object that sends HTTP requests to a Go's default http.Client. +func newDefaultHTTPClientFactory() Factory { + return FactoryFunc(func(next Policy, po *PolicyOptions) PolicyFunc { + return func(ctx context.Context, request Request) (Response, error) { + r, err := pipelineHTTPClient.Do(request.WithContext(ctx)) + if err != nil { + err = NewError(err, "HTTP request failed") + } + return NewHTTPResponse(r), err + } + }) +} + +var mfm = methodFactoryMarker{} // Singleton + +// MethodFactoryMarker returns a special marker Factory object. When Pipeline's Do method is called, any +// MethodMarkerFactory object is replaced with the specified methodFactory object. If nil is passed fro Do's +// methodFactory parameter, then the MethodFactoryMarker is ignored as the linked-list of Policy objects is created. +func MethodFactoryMarker() Factory { + return mfm +} + +type methodFactoryMarker struct { +} + +func (methodFactoryMarker) New(next Policy, po *PolicyOptions) Policy { + panic("methodFactoryMarker policy should have been replaced with a method policy") +} diff --git a/vendor/github.com/Azure/azure-pipeline-go/pipeline/defaultlog_syslog.go b/vendor/github.com/Azure/azure-pipeline-go/pipeline/defaultlog_syslog.go new file mode 100755 index 0000000000..d0bb774076 --- /dev/null +++ b/vendor/github.com/Azure/azure-pipeline-go/pipeline/defaultlog_syslog.go @@ -0,0 +1,33 @@ +// +build !windows,!nacl,!plan9 + +package pipeline + +import ( + "log" + "log/syslog" +) + +// ForceLog should rarely be used. It forceable logs an entry to the +// Windows Event Log (on Windows) or to the SysLog (on Linux) +func ForceLog(level LogLevel, msg string) { + if defaultLogger == nil { + return // Return fast if we failed to create the logger. + } + // We are logging it, ensure trailing newline + if len(msg) == 0 || msg[len(msg)-1] != '\n' { + msg += "\n" // Ensure trailing newline + } + switch level { + case LogFatal: + defaultLogger.Fatal(msg) + case LogPanic: + defaultLogger.Panic(msg) + case LogError, LogWarning, LogInfo: + defaultLogger.Print(msg) + } +} + +var defaultLogger = func() *log.Logger { + l, _ := syslog.NewLogger(syslog.LOG_USER|syslog.LOG_WARNING, log.LstdFlags) + return l +}() diff --git a/vendor/github.com/Azure/azure-pipeline-go/pipeline/defaultlog_windows.go b/vendor/github.com/Azure/azure-pipeline-go/pipeline/defaultlog_windows.go new file mode 100755 index 0000000000..cb67398995 --- /dev/null +++ b/vendor/github.com/Azure/azure-pipeline-go/pipeline/defaultlog_windows.go @@ -0,0 +1,61 @@ +package pipeline + +import ( + "os" + "syscall" + "unsafe" +) + +// ForceLog should rarely be used. It forceable logs an entry to the +// Windows Event Log (on Windows) or to the SysLog (on Linux) +func ForceLog(level LogLevel, msg string) { + var el eventType + switch level { + case LogError, LogFatal, LogPanic: + el = elError + case LogWarning: + el = elWarning + case LogInfo: + el = elInfo + } + // We are logging it, ensure trailing newline + if len(msg) == 0 || msg[len(msg)-1] != '\n' { + msg += "\n" // Ensure trailing newline + } + reportEvent(el, 0, msg) +} + +type eventType int16 + +const ( + elSuccess eventType = 0 + elError eventType = 1 + elWarning eventType = 2 + elInfo eventType = 4 +) + +var reportEvent = func() func(eventType eventType, eventID int32, msg string) { + advAPI32 := syscall.MustLoadDLL("AdvAPI32.dll") + registerEventSource := advAPI32.MustFindProc("RegisterEventSourceW") + + sourceName, _ := os.Executable() + sourceNameUTF16, _ := syscall.UTF16PtrFromString(sourceName) + handle, _, lastErr := registerEventSource.Call(uintptr(0), uintptr(unsafe.Pointer(sourceNameUTF16))) + if lastErr == nil { // On error, logging is a no-op + return func(eventType eventType, eventID int32, msg string) {} + } + reportEvent := advAPI32.MustFindProc("ReportEventW") + return func(eventType eventType, eventID int32, msg string) { + s, _ := syscall.UTF16PtrFromString(msg) + _, _, _ = reportEvent.Call( + uintptr(handle), // HANDLE hEventLog + uintptr(eventType), // WORD wType + uintptr(0), // WORD wCategory + uintptr(eventID), // DWORD dwEventID + uintptr(0), // PSID lpUserSid + uintptr(1), // WORD wNumStrings + uintptr(0), // DWORD dwDataSize + uintptr(unsafe.Pointer(&s)), // LPCTSTR *lpStrings + uintptr(0)) // LPVOID lpRawData + } +}() diff --git a/vendor/github.com/Azure/azure-pipeline-go/pipeline/doc.go b/vendor/github.com/Azure/azure-pipeline-go/pipeline/doc.go new file mode 100755 index 0000000000..b5ab05f4de --- /dev/null +++ b/vendor/github.com/Azure/azure-pipeline-go/pipeline/doc.go @@ -0,0 +1,161 @@ +// Copyright 2017 Microsoft Corporation. All rights reserved. +// Use of this source code is governed by an MIT +// license that can be found in the LICENSE file. + +/* +Package pipeline implements an HTTP request/response middleware pipeline whose +policy objects mutate an HTTP request's URL, query parameters, and/or headers before +the request is sent over the wire. + +Not all policy objects mutate an HTTP request; some policy objects simply impact the +flow of requests/responses by performing operations such as logging, retry policies, +timeouts, failure injection, and deserialization of response payloads. + +Implementing the Policy Interface + +To implement a policy, define a struct that implements the pipeline.Policy interface's Do method. Your Do +method is called when an HTTP request wants to be sent over the network. Your Do method can perform any +operation(s) it desires. For example, it can log the outgoing request, mutate the URL, headers, and/or query +parameters, inject a failure, etc. Your Do method must then forward the HTTP request to next Policy object +in a linked-list ensuring that the remaining Policy objects perform their work. Ultimately, the last Policy +object sends the HTTP request over the network (by calling the HTTPSender's Do method). + +When an HTTP response comes back, each Policy object in the linked-list gets a chance to process the response +(in reverse order). The Policy object can log the response, retry the operation if due to a transient failure +or timeout, deserialize the response body, etc. Ultimately, the last Policy object returns the HTTP response +to the code that initiated the original HTTP request. + +Here is a template for how to define a pipeline.Policy object: + + type myPolicy struct { + node PolicyNode + // TODO: Add configuration/setting fields here (if desired)... + } + + func (p *myPolicy) Do(ctx context.Context, request pipeline.Request) (pipeline.Response, error) { + // TODO: Mutate/process the HTTP request here... + response, err := p.node.Do(ctx, request) // Forward HTTP request to next Policy & get HTTP response + // TODO: Mutate/process the HTTP response here... + return response, err // Return response/error to previous Policy + } + +Implementing the Factory Interface + +Each Policy struct definition requires a factory struct definition that implements the pipeline.Factory interface's New +method. The New method is called when application code wants to initiate a new HTTP request. Factory's New method is +passed a pipeline.PolicyNode object which contains a reference to the owning pipeline.Pipeline object (discussed later) and +a reference to the next Policy object in the linked list. The New method should create its corresponding Policy object +passing it the PolicyNode and any other configuration/settings fields appropriate for the specific Policy object. + +Here is a template for how to define a pipeline.Policy object: + + // NOTE: Once created & initialized, Factory objects should be goroutine-safe (ex: immutable); + // this allows reuse (efficient use of memory) and makes these objects usable by multiple goroutines concurrently. + type myPolicyFactory struct { + // TODO: Add any configuration/setting fields if desired... + } + + func (f *myPolicyFactory) New(node pipeline.PolicyNode) Policy { + return &myPolicy{node: node} // TODO: Also initialize any configuration/setting fields here (if desired)... + } + +Using your Factory and Policy objects via a Pipeline + +To use the Factory and Policy objects, an application constructs a slice of Factory objects and passes +this slice to the pipeline.NewPipeline function. + + func NewPipeline(factories []pipeline.Factory, sender pipeline.HTTPSender) Pipeline + +This function also requires an object implementing the HTTPSender interface. For simple scenarios, +passing nil for HTTPSender causes a standard Go http.Client object to be created and used to actually +send the HTTP response over the network. For more advanced scenarios, you can pass your own HTTPSender +object in. This allows sharing of http.Client objects or the use of custom-configured http.Client objects +or other objects that can simulate the network requests for testing purposes. + +Now that you have a pipeline.Pipeline object, you can create a pipeline.Request object (which is a simple +wrapper around Go's standard http.Request object) and pass it to Pipeline's Do method along with passing a +context.Context for cancelling the HTTP request (if desired). + + type Pipeline interface { + Do(ctx context.Context, methodFactory pipeline.Factory, request pipeline.Request) (pipeline.Response, error) + } + +Do iterates over the slice of Factory objects and tells each one to create its corresponding +Policy object. After the linked-list of Policy objects have been created, Do calls the first +Policy object passing it the Context & HTTP request parameters. These parameters now flow through +all the Policy objects giving each object a chance to look at and/or mutate the HTTP request. +The last Policy object sends the message over the network. + +When the network operation completes, the HTTP response and error return values pass +back through the same Policy objects in reverse order. Most Policy objects ignore the +response/error but some log the result, retry the operation (depending on the exact +reason the operation failed), or deserialize the response's body. Your own Policy +objects can do whatever they like when processing outgoing requests or incoming responses. + +Note that after an I/O request runs to completion, the Policy objects for that request +are garbage collected. However, Pipeline object (like Factory objects) are goroutine-safe allowing +them to be created once and reused over many I/O operations. This allows for efficient use of +memory and also makes them safely usable by multiple goroutines concurrently. + +Inserting a Method-Specific Factory into the Linked-List of Policy Objects + +While Pipeline and Factory objects can be reused over many different operations, it is +common to have special behavior for a specific operation/method. For example, a method +may need to deserialize the response's body to an instance of a specific data type. +To accommodate this, the Pipeline's Do method takes an additional method-specific +Factory object. The Do method tells this Factory to create a Policy object and +injects this method-specific Policy object into the linked-list of Policy objects. + +When creating a Pipeline object, the slice of Factory objects passed must have 1 +(and only 1) entry marking where the method-specific Factory should be injected. +The Factory marker is obtained by calling the pipeline.MethodFactoryMarker() function: + + func MethodFactoryMarker() pipeline.Factory + +Creating an HTTP Request Object + +The HTTP request object passed to Pipeline's Do method is not Go's http.Request struct. +Instead, it is a pipeline.Request struct which is a simple wrapper around Go's standard +http.Request. You create a pipeline.Request object by calling the pipeline.NewRequest function: + + func NewRequest(method string, url url.URL, options pipeline.RequestOptions) (request pipeline.Request, err error) + +To this function, you must pass a pipeline.RequestOptions that looks like this: + + type RequestOptions struct { + // The readable and seekable stream to be sent to the server as the request's body. + Body io.ReadSeeker + + // The callback method (if not nil) to be invoked to report progress as the stream is uploaded in the HTTP request. + Progress ProgressReceiver + } + +The method and struct ensure that the request's body stream is a read/seekable stream. +A seekable stream is required so that upon retry, the final Policy object can seek +the stream back to the beginning before retrying the network request and re-uploading the +body. In addition, you can associate a ProgressReceiver callback function which will be +invoked periodically to report progress while bytes are being read from the body stream +and sent over the network. + +Processing the HTTP Response + +When an HTTP response comes in from the network, a reference to Go's http.Response struct is +embedded in a struct that implements the pipeline.Response interface: + + type Response interface { + Response() *http.Response + } + +This interface is returned through all the Policy objects. Each Policy object can call the Response +interface's Response method to examine (or mutate) the embedded http.Response object. + +A Policy object can internally define another struct (implementing the pipeline.Response interface) +that embeds an http.Response and adds additional fields and return this structure to other Policy +objects. This allows a Policy object to deserialize the body to some other struct and return the +original http.Response and the additional struct back through the Policy chain. Other Policy objects +can see the Response but cannot see the additional struct with the deserialized body. After all the +Policy objects have returned, the pipeline.Response interface is returned by Pipeline's Do method. +The caller of this method can perform a type assertion attempting to get back to the struct type +really returned by the Policy object. If the type assertion is successful, the caller now has +access to both the http.Response and the deserialized struct object.*/ +package pipeline diff --git a/vendor/github.com/Azure/azure-pipeline-go/pipeline/error.go b/vendor/github.com/Azure/azure-pipeline-go/pipeline/error.go new file mode 100755 index 0000000000..fd008364d6 --- /dev/null +++ b/vendor/github.com/Azure/azure-pipeline-go/pipeline/error.go @@ -0,0 +1,121 @@ +package pipeline + +import ( + "fmt" + "runtime" +) + +type causer interface { + Cause() error +} + +// ErrorNode can be an embedded field in a private error object. This field +// adds Program Counter support and a 'cause' (reference to a preceding error). +// When initializing a error type with this embedded field, initialize the +// ErrorNode field by calling ErrorNode{}.Initialize(cause). +type ErrorNode struct { + pc uintptr // Represents a Program Counter that you can get symbols for. + cause error // Refers to the preceding error (or nil) +} + +// Error returns a string with the PC's symbols or "" if the PC is invalid. +// When defining a new error type, have its Error method call this one passing +// it the string representation of the error. +func (e *ErrorNode) Error(msg string) string { + s := "" + if fn := runtime.FuncForPC(e.pc); fn != nil { + file, line := fn.FileLine(e.pc) + s = fmt.Sprintf("-> %v, %v:%v\n", fn.Name(), file, line) + } + s += msg + "\n\n" + if e.cause != nil { + s += e.cause.Error() + "\n" + } + return s +} + +// Cause returns the error that preceded this error. +func (e *ErrorNode) Cause() error { return e.cause } + +// Temporary returns true if the error occurred due to a temporary condition. +func (e ErrorNode) Temporary() bool { + type temporary interface { + Temporary() bool + } + + for err := e.cause; err != nil; { + if t, ok := err.(temporary); ok { + return t.Temporary() + } + + if cause, ok := err.(causer); ok { + err = cause.Cause() + } else { + err = nil + } + } + return false +} + +// Timeout returns true if the error occurred due to time expiring. +func (e ErrorNode) Timeout() bool { + type timeout interface { + Timeout() bool + } + + for err := e.cause; err != nil; { + if t, ok := err.(timeout); ok { + return t.Timeout() + } + + if cause, ok := err.(causer); ok { + err = cause.Cause() + } else { + err = nil + } + } + return false +} + +// Initialize is used to initialize an embedded ErrorNode field. +// It captures the caller's program counter and saves the cause (preceding error). +// To initialize the field, use "ErrorNode{}.Initialize(cause, 3)". A callersToSkip +// value of 3 is very common; but, depending on your code nesting, you may need +// a different value. +func (ErrorNode) Initialize(cause error, callersToSkip int) ErrorNode { + // Get the PC of Initialize method's caller. + pc := [1]uintptr{} + _ = runtime.Callers(callersToSkip, pc[:]) + return ErrorNode{pc: pc[0], cause: cause} +} + +// Cause walks all the preceding errors and return the originating error. +func Cause(err error) error { + for err != nil { + cause, ok := err.(causer) + if !ok { + break + } + err = cause.Cause() + } + return err +} + +// NewError creates a simple string error (like Error.New). But, this +// error also captures the caller's Program Counter and the preceding error. +func NewError(cause error, msg string) error { + return &pcError{ + ErrorNode: ErrorNode{}.Initialize(cause, 3), + msg: msg, + } +} + +// pcError is a simple string error (like error.New) with an ErrorNode (PC & cause). +type pcError struct { + ErrorNode + msg string +} + +// Error satisfies the error interface. It shows the error with Program Counter +// symbols and calls Error on the preceding error so you can see the full error chain. +func (e *pcError) Error() string { return e.ErrorNode.Error(e.msg) } diff --git a/vendor/github.com/Azure/azure-pipeline-go/pipeline/progress.go b/vendor/github.com/Azure/azure-pipeline-go/pipeline/progress.go new file mode 100755 index 0000000000..efa3c8ed06 --- /dev/null +++ b/vendor/github.com/Azure/azure-pipeline-go/pipeline/progress.go @@ -0,0 +1,82 @@ +package pipeline + +import "io" + +// ********** The following is common between the request body AND the response body. + +// ProgressReceiver defines the signature of a callback function invoked as progress is reported. +type ProgressReceiver func(bytesTransferred int64) + +// ********** The following are specific to the request body (a ReadSeekCloser) + +// This struct is used when sending a body to the network +type requestBodyProgress struct { + requestBody io.ReadSeeker // Seeking is required to support retries + pr ProgressReceiver +} + +// NewRequestBodyProgress adds progress reporting to an HTTP request's body stream. +func NewRequestBodyProgress(requestBody io.ReadSeeker, pr ProgressReceiver) io.ReadSeeker { + if pr == nil { + panic("pr must not be nil") + } + return &requestBodyProgress{requestBody: requestBody, pr: pr} +} + +// Read reads a block of data from an inner stream and reports progress +func (rbp *requestBodyProgress) Read(p []byte) (n int, err error) { + n, err = rbp.requestBody.Read(p) + if err != nil { + return + } + // Invokes the user's callback method to report progress + position, err := rbp.requestBody.Seek(0, io.SeekCurrent) + if err != nil { + panic(err) + } + rbp.pr(position) + return +} + +func (rbp *requestBodyProgress) Seek(offset int64, whence int) (offsetFromStart int64, err error) { + return rbp.requestBody.Seek(offset, whence) +} + +// requestBodyProgress supports Close but the underlying stream may not; if it does, Close will close it. +func (rbp *requestBodyProgress) Close() error { + if c, ok := rbp.requestBody.(io.Closer); ok { + return c.Close() + } + return nil +} + +// ********** The following are specific to the response body (a ReadCloser) + +// This struct is used when sending a body to the network +type responseBodyProgress struct { + responseBody io.ReadCloser + pr ProgressReceiver + offset int64 +} + +// NewResponseBodyProgress adds progress reporting to an HTTP response's body stream. +func NewResponseBodyProgress(responseBody io.ReadCloser, pr ProgressReceiver) io.ReadCloser { + if pr == nil { + panic("pr must not be nil") + } + return &responseBodyProgress{responseBody: responseBody, pr: pr, offset: 0} +} + +// Read reads a block of data from an inner stream and reports progress +func (rbp *responseBodyProgress) Read(p []byte) (n int, err error) { + n, err = rbp.responseBody.Read(p) + rbp.offset += int64(n) + + // Invokes the user's callback method to report progress + rbp.pr(rbp.offset) + return +} + +func (rbp *responseBodyProgress) Close() error { + return rbp.responseBody.Close() +} diff --git a/vendor/github.com/Azure/azure-pipeline-go/pipeline/request.go b/vendor/github.com/Azure/azure-pipeline-go/pipeline/request.go new file mode 100755 index 0000000000..1fbe72bd4d --- /dev/null +++ b/vendor/github.com/Azure/azure-pipeline-go/pipeline/request.go @@ -0,0 +1,147 @@ +package pipeline + +import ( + "io" + "net/http" + "net/url" + "strconv" +) + +// Request is a thin wrapper over an http.Request. The wrapper provides several helper methods. +type Request struct { + *http.Request +} + +// NewRequest initializes a new HTTP request object with any desired options. +func NewRequest(method string, url url.URL, body io.ReadSeeker) (request Request, err error) { + // Note: the url is passed by value so that any pipeline operations that modify it do so on a copy. + + // This code to construct an http.Request is copied from http.NewRequest(); we intentionally omitted removeEmptyPort for now. + request.Request = &http.Request{ + Method: method, + URL: &url, + Proto: "HTTP/1.1", + ProtoMajor: 1, + ProtoMinor: 1, + Header: make(http.Header), + Host: url.Host, + } + + if body != nil { + err = request.SetBody(body) + } + return +} + +// SetBody sets the body and content length, assumes body is not nil. +func (r Request) SetBody(body io.ReadSeeker) error { + size, err := body.Seek(0, io.SeekEnd) + if err != nil { + return err + } + + body.Seek(0, io.SeekStart) + r.ContentLength = size + r.Header["Content-Length"] = []string{strconv.FormatInt(size, 10)} + + if size != 0 { + r.Body = &retryableRequestBody{body: body} + r.GetBody = func() (io.ReadCloser, error) { + _, err := body.Seek(0, io.SeekStart) + if err != nil { + return nil, err + } + return r.Body, nil + } + } else { + // in case the body is an empty stream, we need to use http.NoBody to explicitly provide no content + r.Body = http.NoBody + r.GetBody = func() (io.ReadCloser, error) { + return http.NoBody, nil + } + + // close the user-provided empty body + if c, ok := body.(io.Closer); ok { + c.Close() + } + } + + return nil +} + +// Copy makes a copy of an http.Request. Specifically, it makes a deep copy +// of its Method, URL, Host, Proto(Major/Minor), Header. ContentLength, Close, +// RemoteAddr, RequestURI. Copy makes a shallow copy of the Body, GetBody, TLS, +// Cancel, Response, and ctx fields. Copy panics if any of these fields are +// not nil: TransferEncoding, Form, PostForm, MultipartForm, or Trailer. +func (r Request) Copy() Request { + if r.TransferEncoding != nil || r.Form != nil || r.PostForm != nil || r.MultipartForm != nil || r.Trailer != nil { + panic("Can't make a deep copy of the http.Request because at least one of the following is not nil:" + + "TransferEncoding, Form, PostForm, MultipartForm, or Trailer.") + } + copy := *r.Request // Copy the request + urlCopy := *(r.Request.URL) // Copy the URL + copy.URL = &urlCopy + copy.Header = http.Header{} // Copy the header + for k, vs := range r.Header { + for _, value := range vs { + copy.Header.Add(k, value) + } + } + return Request{Request: ©} // Return the copy +} + +func (r Request) close() error { + if r.Body != nil && r.Body != http.NoBody { + c, ok := r.Body.(*retryableRequestBody) + if !ok { + panic("unexpected request body type (should be *retryableReadSeekerCloser)") + } + return c.realClose() + } + return nil +} + +// RewindBody seeks the request's Body stream back to the beginning so it can be resent when retrying an operation. +func (r Request) RewindBody() error { + if r.Body != nil && r.Body != http.NoBody { + s, ok := r.Body.(io.Seeker) + if !ok { + panic("unexpected request body type (should be io.Seeker)") + } + + // Reset the stream back to the beginning + _, err := s.Seek(0, io.SeekStart) + return err + } + return nil +} + +// ********** The following type/methods implement the retryableRequestBody (a ReadSeekCloser) + +// This struct is used when sending a body to the network +type retryableRequestBody struct { + body io.ReadSeeker // Seeking is required to support retries +} + +// Read reads a block of data from an inner stream and reports progress +func (b *retryableRequestBody) Read(p []byte) (n int, err error) { + return b.body.Read(p) +} + +func (b *retryableRequestBody) Seek(offset int64, whence int) (offsetFromStart int64, err error) { + return b.body.Seek(offset, whence) +} + +func (b *retryableRequestBody) Close() error { + // We don't want the underlying transport to close the request body on transient failures so this is a nop. + // The pipeline closes the request body upon success. + return nil +} + +func (b *retryableRequestBody) realClose() error { + if c, ok := b.body.(io.Closer); ok { + return c.Close() + } + return nil +} diff --git a/vendor/github.com/Azure/azure-pipeline-go/pipeline/response.go b/vendor/github.com/Azure/azure-pipeline-go/pipeline/response.go new file mode 100755 index 0000000000..f2dc164821 --- /dev/null +++ b/vendor/github.com/Azure/azure-pipeline-go/pipeline/response.go @@ -0,0 +1,74 @@ +package pipeline + +import ( + "bytes" + "fmt" + "net/http" + "sort" + "strings" +) + +// The Response interface exposes an http.Response object as it returns through the pipeline of Policy objects. +// This ensures that Policy objects have access to the HTTP response. However, the object this interface encapsulates +// might be a struct with additional fields that is created by a Policy object (typically a method-specific Factory). +// The method that injected the method-specific Factory gets this returned Response and performs a type assertion +// to the expected struct and returns the struct to its caller. +type Response interface { + Response() *http.Response +} + +// This is the default struct that has the http.Response. +// A method can replace this struct with its own struct containing an http.Response +// field and any other additional fields. +type httpResponse struct { + response *http.Response +} + +// NewHTTPResponse is typically called by a Policy object to return a Response object. +func NewHTTPResponse(response *http.Response) Response { + return &httpResponse{response: response} +} + +// This method satisfies the public Response interface's Response method +func (r httpResponse) Response() *http.Response { + return r.response +} + +// WriteRequestWithResponse appends a formatted HTTP request into a Buffer. If request and/or err are +// not nil, then these are also written into the Buffer. +func WriteRequestWithResponse(b *bytes.Buffer, request *http.Request, response *http.Response, err error) { + // Write the request into the buffer. + fmt.Fprint(b, " "+request.Method+" "+request.URL.String()+"\n") + writeHeader(b, request.Header) + if response != nil { + fmt.Fprintln(b, " --------------------------------------------------------------------------------") + fmt.Fprint(b, " RESPONSE Status: "+response.Status+"\n") + writeHeader(b, response.Header) + } + if err != nil { + fmt.Fprintln(b, " --------------------------------------------------------------------------------") + fmt.Fprint(b, " ERROR:\n"+err.Error()+"\n") + } +} + +// formatHeaders appends an HTTP request's or response's header into a Buffer. +func writeHeader(b *bytes.Buffer, header map[string][]string) { + if len(header) == 0 { + b.WriteString(" (no headers)\n") + return + } + keys := make([]string, 0, len(header)) + // Alphabetize the headers + for k := range header { + keys = append(keys, k) + } + sort.Strings(keys) + for _, k := range keys { + // Redact the value of any Authorization header to prevent security information from persisting in logs + value := interface{}("REDACTED") + if !strings.EqualFold(k, "Authorization") { + value = header[k] + } + fmt.Fprintf(b, " %s: %+v\n", k, value) + } +} diff --git a/vendor/github.com/Azure/azure-pipeline-go/pipeline/version.go b/vendor/github.com/Azure/azure-pipeline-go/pipeline/version.go new file mode 100644 index 0000000000..c4bb62d810 --- /dev/null +++ b/vendor/github.com/Azure/azure-pipeline-go/pipeline/version.go @@ -0,0 +1,9 @@ +package pipeline + +const ( + // UserAgent is the string to be used in the user agent string when making requests. + UserAgent = "azure-pipeline-go/" + Version + + // Version is the semantic version (see http://semver.org) of the pipeline package. + Version = "0.1.0" +) diff --git a/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/access_conditions.go b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/access_conditions.go new file mode 100644 index 0000000000..c7432e41c3 --- /dev/null +++ b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/access_conditions.go @@ -0,0 +1,67 @@ +package azblob + +import ( + "time" +) + +// HTTPAccessConditions identifies standard HTTP access conditions which you optionally set. +type HTTPAccessConditions struct { + IfModifiedSince time.Time + IfUnmodifiedSince time.Time + IfMatch ETag + IfNoneMatch ETag +} + +// pointers is for internal infrastructure. It returns the fields as pointers. +func (ac HTTPAccessConditions) pointers() (ims *time.Time, ius *time.Time, ime *ETag, inme *ETag) { + if !ac.IfModifiedSince.IsZero() { + ims = &ac.IfModifiedSince + } + if !ac.IfUnmodifiedSince.IsZero() { + ius = &ac.IfUnmodifiedSince + } + if ac.IfMatch != ETagNone { + ime = &ac.IfMatch + } + if ac.IfNoneMatch != ETagNone { + inme = &ac.IfNoneMatch + } + return +} + +// ContainerAccessConditions identifies container-specific access conditions which you optionally set. +type ContainerAccessConditions struct { + HTTPAccessConditions + LeaseAccessConditions +} + +// BlobAccessConditions identifies blob-specific access conditions which you optionally set. +type BlobAccessConditions struct { + HTTPAccessConditions + LeaseAccessConditions + AppendBlobAccessConditions + PageBlobAccessConditions +} + +// LeaseAccessConditions identifies lease access conditions for a container or blob which you optionally set. +type LeaseAccessConditions struct { + LeaseID string +} + +// pointers is for internal infrastructure. It returns the fields as pointers. +func (ac LeaseAccessConditions) pointers() (leaseID *string) { + if ac.LeaseID != "" { + leaseID = &ac.LeaseID + } + return +} + +/* +// getInt32 is for internal infrastructure. It is used with access condition values where +// 0 (the default setting) is meaningful. The library interprets 0 as do not send the header +// and the privately-storage field in the access condition object is stored as +1 higher than desired. +// THis method returns true, if the value is > 0 (explicitly set) and the stored value - 1 (the set desired value). +func getInt32(value int32) (bool, int32) { + return value > 0, value - 1 +} +*/ diff --git a/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/atomicmorph.go b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/atomicmorph.go new file mode 100644 index 0000000000..385b0458b3 --- /dev/null +++ b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/atomicmorph.go @@ -0,0 +1,79 @@ +package azblob + +import "sync/atomic" + +// AtomicMorpherInt32 identifies a method passed to and invoked by the AtomicMorphInt32 function. +// The AtomicMorpher callback is passed a startValue and based on this value it returns +// what the new value should be and the result that AtomicMorph should return to its caller. +type AtomicMorpherInt32 func(startVal int32) (val int32, morphResult interface{}) + +// AtomicMorph atomically morphs target in to new value (and result) as indicated bythe AtomicMorpher callback function. +func AtomicMorphInt32(target *int32, morpher AtomicMorpherInt32) interface{} { + if target == nil || morpher == nil { + panic("target and morpher mut not be nil") + } + for { + currentVal := atomic.LoadInt32(target) + desiredVal, morphResult := morpher(currentVal) + if atomic.CompareAndSwapInt32(target, currentVal, desiredVal) { + return morphResult + } + } +} + +// AtomicMorpherUint32 identifies a method passed to and invoked by the AtomicMorph function. +// The AtomicMorpher callback is passed a startValue and based on this value it returns +// what the new value should be and the result that AtomicMorph should return to its caller. +type AtomicMorpherUint32 func(startVal uint32) (val uint32, morphResult interface{}) + +// AtomicMorph atomically morphs target in to new value (and result) as indicated bythe AtomicMorpher callback function. +func AtomicMorphUint32(target *uint32, morpher AtomicMorpherUint32) interface{} { + if target == nil || morpher == nil { + panic("target and morpher mut not be nil") + } + for { + currentVal := atomic.LoadUint32(target) + desiredVal, morphResult := morpher(currentVal) + if atomic.CompareAndSwapUint32(target, currentVal, desiredVal) { + return morphResult + } + } +} + +// AtomicMorpherUint64 identifies a method passed to and invoked by the AtomicMorphUint64 function. +// The AtomicMorpher callback is passed a startValue and based on this value it returns +// what the new value should be and the result that AtomicMorph should return to its caller. +type AtomicMorpherInt64 func(startVal int64) (val int64, morphResult interface{}) + +// AtomicMorph atomically morphs target in to new value (and result) as indicated bythe AtomicMorpher callback function. +func AtomicMorphInt64(target *int64, morpher AtomicMorpherInt64) interface{} { + if target == nil || morpher == nil { + panic("target and morpher mut not be nil") + } + for { + currentVal := atomic.LoadInt64(target) + desiredVal, morphResult := morpher(currentVal) + if atomic.CompareAndSwapInt64(target, currentVal, desiredVal) { + return morphResult + } + } +} + +// AtomicMorpherUint64 identifies a method passed to and invoked by the AtomicMorphUint64 function. +// The AtomicMorpher callback is passed a startValue and based on this value it returns +// what the new value should be and the result that AtomicMorph should return to its caller. +type AtomicMorpherUint64 func(startVal uint64) (val uint64, morphResult interface{}) + +// AtomicMorph atomically morphs target in to new value (and result) as indicated bythe AtomicMorpher callback function. +func AtomicMorphUint64(target *uint64, morpher AtomicMorpherUint64) interface{} { + if target == nil || morpher == nil { + panic("target and morpher mut not be nil") + } + for { + currentVal := atomic.LoadUint64(target) + desiredVal, morphResult := morpher(currentVal) + if atomic.CompareAndSwapUint64(target, currentVal, desiredVal) { + return morphResult + } + } +} diff --git a/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/highlevel.go b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/highlevel.go new file mode 100644 index 0000000000..aa022826bb --- /dev/null +++ b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/highlevel.go @@ -0,0 +1,510 @@ +package azblob + +import ( + "context" + "encoding/base64" + "fmt" + "io" + "net/http" + + "bytes" + "os" + "sync" + "time" + + "github.com/Azure/azure-pipeline-go/pipeline" +) + +// CommonResponseHeaders returns the headers common to all blob REST API responses. +type CommonResponse interface { + // ETag returns the value for header ETag. + ETag() ETag + + // LastModified returns the value for header Last-Modified. + LastModified() time.Time + + // RequestID returns the value for header x-ms-request-id. + RequestID() string + + // Date returns the value for header Date. + Date() time.Time + + // Version returns the value for header x-ms-version. + Version() string + + // Response returns the raw HTTP response object. + Response() *http.Response +} + +// UploadToBlockBlobOptions identifies options used by the UploadBufferToBlockBlob and UploadFileToBlockBlob functions. +type UploadToBlockBlobOptions struct { + // BlockSize specifies the block size to use; the default (and maximum size) is BlockBlobMaxStageBlockBytes. + BlockSize int64 + + // Progress is a function that is invoked periodically as bytes are sent to the BlockBlobURL. + Progress pipeline.ProgressReceiver + + // BlobHTTPHeaders indicates the HTTP headers to be associated with the blob. + BlobHTTPHeaders BlobHTTPHeaders + + // Metadata indicates the metadata to be associated with the blob when PutBlockList is called. + Metadata Metadata + + // AccessConditions indicates the access conditions for the block blob. + AccessConditions BlobAccessConditions + + // Parallelism indicates the maximum number of blocks to upload in parallel (0=default) + Parallelism uint16 +} + +// UploadBufferToBlockBlob uploads a buffer in blocks to a block blob. +func UploadBufferToBlockBlob(ctx context.Context, b []byte, + blockBlobURL BlockBlobURL, o UploadToBlockBlobOptions) (CommonResponse, error) { + + // Validate parameters and set defaults + if o.BlockSize < 0 || o.BlockSize > BlockBlobMaxUploadBlobBytes { + panic(fmt.Sprintf("BlockSize option must be > 0 and <= %d", BlockBlobMaxUploadBlobBytes)) + } + if o.BlockSize == 0 { + o.BlockSize = BlockBlobMaxUploadBlobBytes // Default if unspecified + } + size := int64(len(b)) + + if size <= BlockBlobMaxUploadBlobBytes { + // If the size can fit in 1 Upload call, do it this way + var body io.ReadSeeker = bytes.NewReader(b) + if o.Progress != nil { + body = pipeline.NewRequestBodyProgress(body, o.Progress) + } + return blockBlobURL.Upload(ctx, body, o.BlobHTTPHeaders, o.Metadata, o.AccessConditions) + } + + var numBlocks = uint16(((size - 1) / o.BlockSize) + 1) + if numBlocks > BlockBlobMaxBlocks { + panic(fmt.Sprintf("The buffer's size is too big or the BlockSize is too small; the number of blocks must be <= %d", BlockBlobMaxBlocks)) + } + + blockIDList := make([]string, numBlocks) // Base-64 encoded block IDs + progress := int64(0) + progressLock := &sync.Mutex{} + + err := doBatchTransfer(ctx, batchTransferOptions{ + operationName: "UploadBufferToBlockBlob", + transferSize: size, + chunkSize: o.BlockSize, + parallelism: o.Parallelism, + operation: func(offset int64, count int64) error { + // This function is called once per block. + // It is passed this block's offset within the buffer and its count of bytes + // Prepare to read the proper block/section of the buffer + var body io.ReadSeeker = bytes.NewReader(b[offset : offset+count]) + blockNum := offset / o.BlockSize + if o.Progress != nil { + blockProgress := int64(0) + body = pipeline.NewRequestBodyProgress(body, + func(bytesTransferred int64) { + diff := bytesTransferred - blockProgress + blockProgress = bytesTransferred + progressLock.Lock() // 1 goroutine at a time gets a progress report + progress += diff + o.Progress(progress) + progressLock.Unlock() + }) + } + + // Block IDs are unique values to avoid issue if 2+ clients are uploading blocks + // at the same time causing PutBlockList to get a mix of blocks from all the clients. + blockIDList[blockNum] = base64.StdEncoding.EncodeToString(newUUID().bytes()) + _, err := blockBlobURL.StageBlock(ctx, blockIDList[blockNum], body, o.AccessConditions.LeaseAccessConditions) + return err + }, + }) + if err != nil { + return nil, err + } + // All put blocks were successful, call Put Block List to finalize the blob + return blockBlobURL.CommitBlockList(ctx, blockIDList, o.BlobHTTPHeaders, o.Metadata, o.AccessConditions) +} + +// UploadFileToBlockBlob uploads a file in blocks to a block blob. +func UploadFileToBlockBlob(ctx context.Context, file *os.File, + blockBlobURL BlockBlobURL, o UploadToBlockBlobOptions) (CommonResponse, error) { + + stat, err := file.Stat() + if err != nil { + return nil, err + } + m := mmf{} // Default to an empty slice; used for 0-size file + if stat.Size() != 0 { + m, err = newMMF(file, false, 0, int(stat.Size())) + if err != nil { + return nil, err + } + defer m.unmap() + } + return UploadBufferToBlockBlob(ctx, m, blockBlobURL, o) +} + +/////////////////////////////////////////////////////////////////////////////// + + +const BlobDefaultDownloadBlockSize = int64(4 * 1024 * 1024) // 4MB + +// DownloadFromAzureFileOptions identifies options used by the DownloadAzureFileToBuffer and DownloadAzureFileToFile functions. +type DownloadFromBlobOptions struct { + // BlockSize specifies the block size to use for each parallel download; the default size is BlobDefaultDownloadBlockSize. + BlockSize int64 + + // Progress is a function that is invoked periodically as bytes are received. + Progress pipeline.ProgressReceiver + + // AccessConditions indicates the access conditions used when making HTTP GET requests against the blob. + AccessConditions BlobAccessConditions + + // Parallelism indicates the maximum number of blocks to download in parallel (0=default) + Parallelism uint16 + + // RetryReaderOptionsPerBlock is used when downloading each block. + RetryReaderOptionsPerBlock RetryReaderOptions +} + +// downloadAzureFileToBuffer downloads an Azure file to a buffer with parallel. +func downloadBlobToBuffer(ctx context.Context, blobURL BlobURL, offset int64, count int64, + ac BlobAccessConditions, b []byte, o DownloadFromBlobOptions, + initialDownloadResponse *DownloadResponse) error { + // Validate parameters, and set defaults. + if o.BlockSize < 0 { + panic("BlockSize option must be >= 0") + } + if o.BlockSize == 0 { + o.BlockSize = BlobDefaultDownloadBlockSize + } + + if offset < 0 { + panic("offset option must be >= 0") + } + + if count < 0 { + panic("count option must be >= 0") + } + + if count == CountToEnd { // If size not specified, calculate it + if initialDownloadResponse != nil { + count = initialDownloadResponse.ContentLength() - offset // if we have the length, use it + } else { + // If we don't have the length at all, get it + dr, err := blobURL.Download(ctx, 0, CountToEnd, ac, false) + if err != nil { + return err + } + count = dr.ContentLength() - offset + } + } + + if int64(len(b)) < count { + panic(fmt.Errorf("the buffer's size should be equal to or larger than the request count of bytes: %d", count)) + } + + // Prepare and do parallel download. + progress := int64(0) + progressLock := &sync.Mutex{} + + err := doBatchTransfer(ctx, batchTransferOptions{ + operationName: "downloadBlobToBuffer", + transferSize: count, + chunkSize: o.BlockSize, + parallelism: o.Parallelism, + operation: func(chunkStart int64, count int64) error { + dr, err := blobURL.Download(ctx, chunkStart+ offset, count, ac, false) + body := dr.Body(o.RetryReaderOptionsPerBlock) + if o.Progress != nil { + rangeProgress := int64(0) + body = pipeline.NewResponseBodyProgress( + body, + func(bytesTransferred int64) { + diff := bytesTransferred - rangeProgress + rangeProgress = bytesTransferred + progressLock.Lock() + progress += diff + o.Progress(progress) + progressLock.Unlock() + }) + } + _, err = io.ReadFull(body, b[chunkStart:chunkStart+count]) + body.Close() + return err + }, + }) + if err != nil { + return err + } + return nil +} + +// DownloadAzureFileToBuffer downloads an Azure file to a buffer with parallel. +// Offset and count are optional, pass 0 for both to download the entire blob. +func DownloadBlobToBuffer(ctx context.Context, blobURL BlobURL, offset int64, count int64, + ac BlobAccessConditions, b []byte, o DownloadFromBlobOptions) error { + return downloadBlobToBuffer(ctx, blobURL, offset, count, ac, b, o, nil) +} + +// DownloadBlobToFile downloads an Azure file to a local file. +// The file would be truncated if the size doesn't match. +// Offset and count are optional, pass 0 for both to download the entire blob. +func DownloadBlobToFile(ctx context.Context, blobURL BlobURL, offset int64, count int64, + ac BlobAccessConditions, file *os.File, o DownloadFromBlobOptions) error { + // 1. Validate parameters. + if file == nil { + panic("file must not be nil") + } + + // 2. Calculate the size of the destination file + var size int64 + + if count == CountToEnd { + // Try to get Azure file's size + props, err := blobURL.GetProperties(ctx, ac) + if err != nil { + return err + } + size = props.ContentLength() - offset + } else { + size = count + } + + // 3. Compare and try to resize local file's size if it doesn't match Azure file's size. + stat, err := file.Stat() + if err != nil { + return err + } + if stat.Size() != size { + if err = file.Truncate(size); err != nil { + return err + } + } + + if size > 0 { + // 4. Set mmap and call DownloadAzureFileToBuffer. + m, err := newMMF(file, true, 0, int(size)) + if err != nil { + return err + } + defer m.unmap() + return downloadBlobToBuffer(ctx, blobURL, offset, size, ac, m, o, nil) + } else { // if the blob's size is 0, there is no need in downloading it + return nil + } +} + + +/////////////////////////////////////////////////////////////////////////////// + +// BatchTransferOptions identifies options used by doBatchTransfer. +type batchTransferOptions struct { + transferSize int64 + chunkSize int64 + parallelism uint16 + operation func(offset int64, chunkSize int64) error + operationName string +} + +// doBatchTransfer helps to execute operations in a batch manner. +func doBatchTransfer(ctx context.Context, o batchTransferOptions) error { + // Prepare and do parallel operations. + numChunks := uint16(((o.transferSize - 1) / o.chunkSize) + 1) + operationChannel := make(chan func() error, o.parallelism) // Create the channel that release 'parallelism' goroutines concurrently + operationResponseChannel := make(chan error, numChunks) // Holds each response + ctx, cancel := context.WithCancel(ctx) + defer cancel() + + // Create the goroutines that process each operation (in parallel). + if o.parallelism == 0 { + o.parallelism = 5 // default parallelism + } + for g := uint16(0); g < o.parallelism; g++ { + //grIndex := g + go func() { + for f := range operationChannel { + //fmt.Printf("[%s] gr-%d start action\n", o.operationName, grIndex) + err := f() + operationResponseChannel <- err + //fmt.Printf("[%s] gr-%d end action\n", o.operationName, grIndex) + } + }() + } + + // Add each chunk's operation to the channel. + for chunkNum := uint16(0); chunkNum < numChunks; chunkNum++ { + curChunkSize := o.chunkSize + + if chunkNum == numChunks-1 { // Last chunk + curChunkSize = o.transferSize - (int64(chunkNum) * o.chunkSize) // Remove size of all transferred chunks from total + } + offset := int64(chunkNum) * o.chunkSize + + operationChannel <- func() error { + return o.operation(offset, curChunkSize) + } + } + close(operationChannel) + + // Wait for the operations to complete. + for chunkNum := uint16(0); chunkNum < numChunks; chunkNum++ { + responseError := <-operationResponseChannel + if responseError != nil { + cancel() // As soon as any operation fails, cancel all remaining operation calls + return responseError // No need to process anymore responses + } + } + return nil +} + +//////////////////////////////////////////////////////////////////////////////////////////////// + +type UploadStreamToBlockBlobOptions struct { + BufferSize int + MaxBuffers int + BlobHTTPHeaders BlobHTTPHeaders + Metadata Metadata + AccessConditions BlobAccessConditions +} + +func UploadStreamToBlockBlob(ctx context.Context, reader io.Reader, blockBlobURL BlockBlobURL, + o UploadStreamToBlockBlobOptions) (CommonResponse, error) { + result, err := uploadStream(ctx, reader, + UploadStreamOptions{BufferSize: o.BufferSize, MaxBuffers: o.MaxBuffers}, + &uploadStreamToBlockBlobOptions{b: blockBlobURL, o: o, blockIDPrefix: newUUID()}) + return result.(CommonResponse), err +} + +type uploadStreamToBlockBlobOptions struct { + b BlockBlobURL + o UploadStreamToBlockBlobOptions + blockIDPrefix uuid // UUID used with all blockIDs + maxBlockNum uint32 // defaults to 0 + firstBlock []byte // Used only if maxBlockNum is 0 +} + +func (t *uploadStreamToBlockBlobOptions) start(ctx context.Context) (interface{}, error) { + return nil, nil +} + +func (t *uploadStreamToBlockBlobOptions) chunk(ctx context.Context, num uint32, buffer []byte) error { + if num == 0 && len(buffer) < t.o.BufferSize { + // If whole payload fits in 1 block, don't stage it; End will upload it with 1 I/O operation + t.firstBlock = buffer + return nil + } + // Else, upload a staged block... + AtomicMorphUint32(&t.maxBlockNum, func(startVal uint32) (val uint32, morphResult interface{}) { + // Atomically remember (in t.numBlocks) the maximum block num we've ever seen + if startVal < num { + return num, nil + } + return startVal, nil + }) + blockID := newUuidBlockID(t.blockIDPrefix).WithBlockNumber(num).ToBase64() + _, err := t.b.StageBlock(ctx, blockID, bytes.NewReader(buffer), LeaseAccessConditions{}) + return err +} + +func (t *uploadStreamToBlockBlobOptions) end(ctx context.Context) (interface{}, error) { + if t.maxBlockNum == 0 { + // If whole payload fits in 1 block (block #0), upload it with 1 I/O operation + return t.b.Upload(ctx, bytes.NewReader(t.firstBlock), + t.o.BlobHTTPHeaders, t.o.Metadata, t.o.AccessConditions) + } + // Multiple blocks staged, commit them all now + blockID := newUuidBlockID(t.blockIDPrefix) + blockIDs := make([]string, t.maxBlockNum + 1) + for bn := uint32(0); bn <= t.maxBlockNum; bn++ { + blockIDs[bn] = blockID.WithBlockNumber(bn).ToBase64() + } + return t.b.CommitBlockList(ctx, blockIDs, t.o.BlobHTTPHeaders, t.o.Metadata, t.o.AccessConditions) +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +type iTransfer interface { + start(ctx context.Context) (interface{}, error) + chunk(ctx context.Context, num uint32, buffer []byte) error + end(ctx context.Context) (interface{}, error) +} + +type UploadStreamOptions struct { + MaxBuffers int + BufferSize int +} + +func uploadStream(ctx context.Context, reader io.Reader, o UploadStreamOptions, t iTransfer) (interface{}, error) { + ctx, cancel := context.WithCancel(ctx) // New context so that any failure cancels everything + defer cancel() + wg := sync.WaitGroup{} // Used to know when all outgoing messages have finished processing + type OutgoingMsg struct { + chunkNum uint32 + buffer []byte + } + + // Create a channel to hold the buffers usable for incoming datsa + incoming := make(chan []byte, o.MaxBuffers) + outgoing := make(chan OutgoingMsg, o.MaxBuffers) // Channel holding outgoing buffers + if result, err := t.start(ctx); err != nil { + return result, err + } + + numBuffers := 0 // The number of buffers & out going goroutines created so far + injectBuffer := func() { + // For each Buffer, create it and a goroutine to upload it + incoming <- make([]byte, o.BufferSize) // Add the new buffer to the incoming channel so this goroutine can from the reader into it + numBuffers++ + go func() { + for outgoingMsg := range outgoing { + // Upload the outgoing buffer + err := t.chunk(ctx, outgoingMsg.chunkNum, outgoingMsg.buffer) + wg.Done() // Indicate this buffer was sent + if nil != err { + cancel() + } + incoming <- outgoingMsg.buffer // The goroutine reading from the stream can use reuse this buffer now + } + }() + } + injectBuffer() // Create our 1st buffer & outgoing goroutine + + // This goroutine grabs a buffer, reads from the stream into the buffer, + // and inserts the buffer into the outgoing channel to be uploaded + for c := uint32(0); true; c++ { // Iterate once per chunk + var buffer []byte + if numBuffers < o.MaxBuffers { + select { + // We're not at max buffers, see if a previously-created buffer is available + case buffer = <-incoming: + break + default: + // No buffer available; inject a new buffer & go routine to process it + injectBuffer() + buffer = <-incoming // Grab the just-injected buffer + } + } else { + // We are at max buffers, block until we get to reuse one + buffer = <-incoming + } + n, err := io.ReadFull(reader, buffer) + if err != nil { + buffer = buffer[:n] // Make slice match the # of read bytes + } + if len(buffer) > 0 { + // Buffer not empty, upload it + wg.Add(1) // We're posting a buffer to be sent + outgoing <- OutgoingMsg{chunkNum: c, buffer: buffer} + } + if err != nil { // The reader is done, no more outgoing buffers + break + } + } + // NOTE: Don't close the incoming channel because the outgoing goroutines post buffers into it when they are done + close(outgoing) // Make all the outgoing goroutines terminate when this channel is empty + wg.Wait() // Wait for all pending outgoing messages to complete + // After all blocks uploaded, commit them to the blob & return the result + return t.end(ctx) +} diff --git a/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/parsing_urls.go b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/parsing_urls.go new file mode 100644 index 0000000000..e797a59c0b --- /dev/null +++ b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/parsing_urls.go @@ -0,0 +1,111 @@ +package azblob + +import ( + "net/url" + "strings" +) + +const ( + snapshot = "snapshot" + SnapshotTimeFormat = "2006-01-02T15:04:05.0000000Z07:00" +) + +// A BlobURLParts object represents the components that make up an Azure Storage Container/Blob URL. You parse an +// existing URL into its parts by calling NewBlobURLParts(). You construct a URL from parts by calling URL(). +// NOTE: Changing any SAS-related field requires computing a new SAS signature. +type BlobURLParts struct { + Scheme string // Ex: "https://" + Host string // Ex: "account.blob.core.windows.net" + ContainerName string // "" if no container + BlobName string // "" if no blob + Snapshot string // "" if not a snapshot + SAS SASQueryParameters + UnparsedParams string +} + +// NewBlobURLParts parses a URL initializing BlobURLParts' fields including any SAS-related & snapshot query parameters. Any other +// query parameters remain in the UnparsedParams field. This method overwrites all fields in the BlobURLParts object. +func NewBlobURLParts(u url.URL) BlobURLParts { + up := BlobURLParts{ + Scheme: u.Scheme, + Host: u.Host, + } + + // Find the container & blob names (if any) + if u.Path != "" { + path := u.Path + if path[0] == '/' { + path = path[1:] // If path starts with a slash, remove it + } + + // Find the next slash (if it exists) + containerEndIndex := strings.Index(path, "/") + if containerEndIndex == -1 { // Slash not found; path has container name & no blob name + up.ContainerName = path + } else { + up.ContainerName = path[:containerEndIndex] // The container name is the part between the slashes + up.BlobName = path[containerEndIndex+1:] // The blob name is after the container slash + } + } + + // Convert the query parameters to a case-sensitive map & trim whitespace + paramsMap := u.Query() + + up.Snapshot = "" // Assume no snapshot + if snapshotStr, ok := caseInsensitiveValues(paramsMap).Get(snapshot); ok { + up.Snapshot = snapshotStr[0] + // If we recognized the query parameter, remove it from the map + delete(paramsMap, snapshot) + } + up.SAS = newSASQueryParameters(paramsMap, true) + up.UnparsedParams = paramsMap.Encode() + return up +} + +type caseInsensitiveValues url.Values // map[string][]string +func (values caseInsensitiveValues) Get(key string) ([]string, bool) { + key = strings.ToLower(key) + for k, v := range values { + if strings.ToLower(k) == key { + return v, true + } + } + return []string{}, false +} + +// URL returns a URL object whose fields are initialized from the BlobURLParts fields. The URL's RawQuery +// field contains the SAS, snapshot, and unparsed query parameters. +func (up BlobURLParts) URL() url.URL { + path := "" + // Concatenate container & blob names (if they exist) + if up.ContainerName != "" { + path += "/" + up.ContainerName + if up.BlobName != "" { + path += "/" + up.BlobName + } + } + + rawQuery := up.UnparsedParams + + // Concatenate blob snapshot query parameter (if it exists) + if up.Snapshot != "" { + if len(rawQuery) > 0 { + rawQuery += "&" + } + rawQuery += snapshot + "=" + up.Snapshot + } + sas := up.SAS.Encode() + if sas != "" { + if len(rawQuery) > 0 { + rawQuery += "&" + } + rawQuery += sas + } + u := url.URL{ + Scheme: up.Scheme, + Host: up.Host, + Path: path, + RawQuery: rawQuery, + } + return u +} diff --git a/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/sas_service.go b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/sas_service.go new file mode 100644 index 0000000000..d0b12bc17a --- /dev/null +++ b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/sas_service.go @@ -0,0 +1,206 @@ +package azblob + +import ( + "bytes" + "fmt" + "strings" + "time" +) + +// BlobSASSignatureValues is used to generate a Shared Access Signature (SAS) for an Azure Storage container or blob. +type BlobSASSignatureValues struct { + Version string `param:"sv"` // If not specified, this defaults to SASVersion + Protocol SASProtocol `param:"spr"` // See the SASProtocol* constants + StartTime time.Time `param:"st"` // Not specified if IsZero + ExpiryTime time.Time `param:"se"` // Not specified if IsZero + Permissions string `param:"sp"` // Create by initializing a ContainerSASPermissions or BlobSASPermissions and then call String() + IPRange IPRange `param:"sip"` + Identifier string `param:"si"` + ContainerName string + BlobName string // Use "" to create a Container SAS + CacheControl string // rscc + ContentDisposition string // rscd + ContentEncoding string // rsce + ContentLanguage string // rscl + ContentType string // rsct +} + +// NewSASQueryParameters uses an account's shared key credential to sign this signature values to produce +// the proper SAS query parameters. +func (v BlobSASSignatureValues) NewSASQueryParameters(sharedKeyCredential *SharedKeyCredential) SASQueryParameters { + if sharedKeyCredential == nil { + panic("sharedKeyCredential can't be nil") + } + + resource := "c" + if v.BlobName == "" { + // Make sure the permission characters are in the correct order + perms := &ContainerSASPermissions{} + if err := perms.Parse(v.Permissions); err != nil { + panic(err) + } + v.Permissions = perms.String() + } else { + resource = "b" + // Make sure the permission characters are in the correct order + perms := &BlobSASPermissions{} + if err := perms.Parse(v.Permissions); err != nil { + panic(err) + } + v.Permissions = perms.String() + } + if v.Version == "" { + v.Version = SASVersion + } + startTime, expiryTime := FormatTimesForSASSigning(v.StartTime, v.ExpiryTime) + + // String to sign: http://msdn.microsoft.com/en-us/library/azure/dn140255.aspx + stringToSign := strings.Join([]string{ + v.Permissions, + startTime, + expiryTime, + getCanonicalName(sharedKeyCredential.AccountName(), v.ContainerName, v.BlobName), + v.Identifier, + v.IPRange.String(), + string(v.Protocol), + v.Version, + v.CacheControl, // rscc + v.ContentDisposition, // rscd + v.ContentEncoding, // rsce + v.ContentLanguage, // rscl + v.ContentType}, // rsct + "\n") + signature := sharedKeyCredential.ComputeHMACSHA256(stringToSign) + + p := SASQueryParameters{ + // Common SAS parameters + version: v.Version, + protocol: v.Protocol, + startTime: v.StartTime, + expiryTime: v.ExpiryTime, + permissions: v.Permissions, + ipRange: v.IPRange, + + // Container/Blob-specific SAS parameters + resource: resource, + identifier: v.Identifier, + + // Calculated SAS signature + signature: signature, + } + return p +} + +// getCanonicalName computes the canonical name for a container or blob resource for SAS signing. +func getCanonicalName(account string, containerName string, blobName string) string { + // Container: "/blob/account/containername" + // Blob: "/blob/account/containername/blobname" + elements := []string{"/blob/", account, "/", containerName} + if blobName != "" { + elements = append(elements, "/", strings.Replace(blobName, "\\", "/", -1)) + } + return strings.Join(elements, "") +} + +// The ContainerSASPermissions type simplifies creating the permissions string for an Azure Storage container SAS. +// Initialize an instance of this type and then call its String method to set BlobSASSignatureValues's Permissions field. +type ContainerSASPermissions struct { + Read, Add, Create, Write, Delete, List bool +} + +// String produces the SAS permissions string for an Azure Storage container. +// Call this method to set BlobSASSignatureValues's Permissions field. +func (p ContainerSASPermissions) String() string { + var b bytes.Buffer + if p.Read { + b.WriteRune('r') + } + if p.Add { + b.WriteRune('a') + } + if p.Create { + b.WriteRune('c') + } + if p.Write { + b.WriteRune('w') + } + if p.Delete { + b.WriteRune('d') + } + if p.List { + b.WriteRune('l') + } + return b.String() +} + +// Parse initializes the ContainerSASPermissions's fields from a string. +func (p *ContainerSASPermissions) Parse(s string) error { + *p = ContainerSASPermissions{} // Clear the flags + for _, r := range s { + switch r { + case 'r': + p.Read = true + case 'a': + p.Add = true + case 'c': + p.Create = true + case 'w': + p.Write = true + case 'd': + p.Delete = true + case 'l': + p.List = true + default: + return fmt.Errorf("Invalid permission: '%v'", r) + } + } + return nil +} + +// The BlobSASPermissions type simplifies creating the permissions string for an Azure Storage blob SAS. +// Initialize an instance of this type and then call its String method to set BlobSASSignatureValues's Permissions field. +type BlobSASPermissions struct{ Read, Add, Create, Write, Delete bool } + +// String produces the SAS permissions string for an Azure Storage blob. +// Call this method to set BlobSASSignatureValues's Permissions field. +func (p BlobSASPermissions) String() string { + var b bytes.Buffer + if p.Read { + b.WriteRune('r') + } + if p.Add { + b.WriteRune('a') + } + if p.Create { + b.WriteRune('c') + } + if p.Write { + b.WriteRune('w') + } + if p.Delete { + b.WriteRune('d') + } + return b.String() +} + +// Parse initializes the BlobSASPermissions's fields from a string. +func (p *BlobSASPermissions) Parse(s string) error { + *p = BlobSASPermissions{} // Clear the flags + for _, r := range s { + switch r { + case 'r': + p.Read = true + case 'a': + p.Add = true + case 'c': + p.Create = true + case 'w': + p.Write = true + case 'd': + p.Delete = true + default: + return fmt.Errorf("Invalid permission: '%v'", r) + } + } + return nil +} diff --git a/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/service_codes_blob.go b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/service_codes_blob.go new file mode 100644 index 0000000000..d260f8aee5 --- /dev/null +++ b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/service_codes_blob.go @@ -0,0 +1,195 @@ +package azblob + +// https://docs.microsoft.com/en-us/rest/api/storageservices/blob-service-error-codes + +// ServiceCode values indicate a service failure. +const ( + // ServiceCodeAppendPositionConditionNotMet means the append position condition specified was not met. + ServiceCodeAppendPositionConditionNotMet ServiceCodeType = "AppendPositionConditionNotMet" + + // ServiceCodeBlobAlreadyExists means the specified blob already exists. + ServiceCodeBlobAlreadyExists ServiceCodeType = "BlobAlreadyExists" + + // ServiceCodeBlobNotFound means the specified blob does not exist. + ServiceCodeBlobNotFound ServiceCodeType = "BlobNotFound" + + // ServiceCodeBlobOverwritten means the blob has been recreated since the previous snapshot was taken. + ServiceCodeBlobOverwritten ServiceCodeType = "BlobOverwritten" + + // ServiceCodeBlobTierInadequateForContentLength means the specified blob tier size limit cannot be less than content length. + ServiceCodeBlobTierInadequateForContentLength ServiceCodeType = "BlobTierInadequateForContentLength" + + // ServiceCodeBlockCountExceedsLimit means the committed block count cannot exceed the maximum limit of 50,000 blocks + // or that the uncommitted block count cannot exceed the maximum limit of 100,000 blocks. + ServiceCodeBlockCountExceedsLimit ServiceCodeType = "BlockCountExceedsLimit" + + // ServiceCodeBlockListTooLong means the block list may not contain more than 50,000 blocks. + ServiceCodeBlockListTooLong ServiceCodeType = "BlockListTooLong" + + // ServiceCodeCannotChangeToLowerTier means that a higher blob tier has already been explicitly set. + ServiceCodeCannotChangeToLowerTier ServiceCodeType = "CannotChangeToLowerTier" + + // ServiceCodeCannotVerifyCopySource means that the service could not verify the copy source within the specified time. + // Examine the HTTP status code and message for more information about the failure. + ServiceCodeCannotVerifyCopySource ServiceCodeType = "CannotVerifyCopySource" + + // ServiceCodeContainerAlreadyExists means the specified container already exists. + ServiceCodeContainerAlreadyExists ServiceCodeType = "ContainerAlreadyExists" + + // ServiceCodeContainerBeingDeleted means the specified container is being deleted. + ServiceCodeContainerBeingDeleted ServiceCodeType = "ContainerBeingDeleted" + + // ServiceCodeContainerDisabled means the specified container has been disabled by the administrator. + ServiceCodeContainerDisabled ServiceCodeType = "ContainerDisabled" + + // ServiceCodeContainerNotFound means the specified container does not exist. + ServiceCodeContainerNotFound ServiceCodeType = "ContainerNotFound" + + // ServiceCodeContentLengthLargerThanTierLimit means the blob's content length cannot exceed its tier limit. + ServiceCodeContentLengthLargerThanTierLimit ServiceCodeType = "ContentLengthLargerThanTierLimit" + + // ServiceCodeCopyAcrossAccountsNotSupported means the copy source account and destination account must be the same. + ServiceCodeCopyAcrossAccountsNotSupported ServiceCodeType = "CopyAcrossAccountsNotSupported" + + // ServiceCodeCopyIDMismatch means the specified copy ID did not match the copy ID for the pending copy operation. + ServiceCodeCopyIDMismatch ServiceCodeType = "CopyIdMismatch" + + // ServiceCodeFeatureVersionMismatch means the type of blob in the container is unrecognized by this version or + // that the operation for AppendBlob requires at least version 2015-02-21. + ServiceCodeFeatureVersionMismatch ServiceCodeType = "FeatureVersionMismatch" + + // ServiceCodeIncrementalCopyBlobMismatch means the specified source blob is different than the copy source of the existing incremental copy blob. + ServiceCodeIncrementalCopyBlobMismatch ServiceCodeType = "IncrementalCopyBlobMismatch" + + // ServiceCodeIncrementalCopyOfEralierVersionSnapshotNotAllowed means the specified snapshot is earlier than the last snapshot copied into the incremental copy blob. + ServiceCodeIncrementalCopyOfEralierVersionSnapshotNotAllowed ServiceCodeType = "IncrementalCopyOfEralierVersionSnapshotNotAllowed" + + // ServiceCodeIncrementalCopySourceMustBeSnapshot means the source for incremental copy request must be a snapshot. + ServiceCodeIncrementalCopySourceMustBeSnapshot ServiceCodeType = "IncrementalCopySourceMustBeSnapshot" + + // ServiceCodeInfiniteLeaseDurationRequired means the lease ID matched, but the specified lease must be an infinite-duration lease. + ServiceCodeInfiniteLeaseDurationRequired ServiceCodeType = "InfiniteLeaseDurationRequired" + + // ServiceCodeInvalidBlobOrBlock means the specified blob or block content is invalid. + ServiceCodeInvalidBlobOrBlock ServiceCodeType = "InvalidBlobOrBlock" + + // ServiceCodeInvalidBlobType means the blob type is invalid for this operation. + ServiceCodeInvalidBlobType ServiceCodeType = "InvalidBlobType" + + // ServiceCodeInvalidBlockID means the specified block ID is invalid. The block ID must be Base64-encoded. + ServiceCodeInvalidBlockID ServiceCodeType = "InvalidBlockId" + + // ServiceCodeInvalidBlockList means the specified block list is invalid. + ServiceCodeInvalidBlockList ServiceCodeType = "InvalidBlockList" + + // ServiceCodeInvalidOperation means an invalid operation against a blob snapshot. + ServiceCodeInvalidOperation ServiceCodeType = "InvalidOperation" + + // ServiceCodeInvalidPageRange means the page range specified is invalid. + ServiceCodeInvalidPageRange ServiceCodeType = "InvalidPageRange" + + // ServiceCodeInvalidSourceBlobType means the copy source blob type is invalid for this operation. + ServiceCodeInvalidSourceBlobType ServiceCodeType = "InvalidSourceBlobType" + + // ServiceCodeInvalidSourceBlobURL means the source URL for incremental copy request must be valid Azure Storage blob URL. + ServiceCodeInvalidSourceBlobURL ServiceCodeType = "InvalidSourceBlobUrl" + + // ServiceCodeInvalidVersionForPageBlobOperation means that all operations on page blobs require at least version 2009-09-19. + ServiceCodeInvalidVersionForPageBlobOperation ServiceCodeType = "InvalidVersionForPageBlobOperation" + + // ServiceCodeLeaseAlreadyPresent means there is already a lease present. + ServiceCodeLeaseAlreadyPresent ServiceCodeType = "LeaseAlreadyPresent" + + // ServiceCodeLeaseAlreadyBroken means the lease has already been broken and cannot be broken again. + ServiceCodeLeaseAlreadyBroken ServiceCodeType = "LeaseAlreadyBroken" + + // ServiceCodeLeaseIDMismatchWithBlobOperation means the lease ID specified did not match the lease ID for the blob. + ServiceCodeLeaseIDMismatchWithBlobOperation ServiceCodeType = "LeaseIdMismatchWithBlobOperation" + + // ServiceCodeLeaseIDMismatchWithContainerOperation means the lease ID specified did not match the lease ID for the container. + ServiceCodeLeaseIDMismatchWithContainerOperation ServiceCodeType = "LeaseIdMismatchWithContainerOperation" + + // ServiceCodeLeaseIDMismatchWithLeaseOperation means the lease ID specified did not match the lease ID for the blob/container. + ServiceCodeLeaseIDMismatchWithLeaseOperation ServiceCodeType = "LeaseIdMismatchWithLeaseOperation" + + // ServiceCodeLeaseIDMissing means there is currently a lease on the blob/container and no lease ID was specified in the request. + ServiceCodeLeaseIDMissing ServiceCodeType = "LeaseIdMissing" + + // ServiceCodeLeaseIsBreakingAndCannotBeAcquired means the lease ID matched, but the lease is currently in breaking state and cannot be acquired until it is broken. + ServiceCodeLeaseIsBreakingAndCannotBeAcquired ServiceCodeType = "LeaseIsBreakingAndCannotBeAcquired" + + // ServiceCodeLeaseIsBreakingAndCannotBeChanged means the lease ID matched, but the lease is currently in breaking state and cannot be changed. + ServiceCodeLeaseIsBreakingAndCannotBeChanged ServiceCodeType = "LeaseIsBreakingAndCannotBeChanged" + + // ServiceCodeLeaseIsBrokenAndCannotBeRenewed means the lease ID matched, but the lease has been broken explicitly and cannot be renewed. + ServiceCodeLeaseIsBrokenAndCannotBeRenewed ServiceCodeType = "LeaseIsBrokenAndCannotBeRenewed" + + // ServiceCodeLeaseLost means a lease ID was specified, but the lease for the blob/container has expired. + ServiceCodeLeaseLost ServiceCodeType = "LeaseLost" + + // ServiceCodeLeaseNotPresentWithBlobOperation means there is currently no lease on the blob. + ServiceCodeLeaseNotPresentWithBlobOperation ServiceCodeType = "LeaseNotPresentWithBlobOperation" + + // ServiceCodeLeaseNotPresentWithContainerOperation means there is currently no lease on the container. + ServiceCodeLeaseNotPresentWithContainerOperation ServiceCodeType = "LeaseNotPresentWithContainerOperation" + + // ServiceCodeLeaseNotPresentWithLeaseOperation means there is currently no lease on the blob/container. + ServiceCodeLeaseNotPresentWithLeaseOperation ServiceCodeType = "LeaseNotPresentWithLeaseOperation" + + // ServiceCodeMaxBlobSizeConditionNotMet means the max blob size condition specified was not met. + ServiceCodeMaxBlobSizeConditionNotMet ServiceCodeType = "MaxBlobSizeConditionNotMet" + + // ServiceCodeNoPendingCopyOperation means there is currently no pending copy operation. + ServiceCodeNoPendingCopyOperation ServiceCodeType = "NoPendingCopyOperation" + + // ServiceCodeOperationNotAllowedOnIncrementalCopyBlob means the specified operation is not allowed on an incremental copy blob. + ServiceCodeOperationNotAllowedOnIncrementalCopyBlob ServiceCodeType = "OperationNotAllowedOnIncrementalCopyBlob" + + // ServiceCodePendingCopyOperation means there is currently a pending copy operation. + ServiceCodePendingCopyOperation ServiceCodeType = "PendingCopyOperation" + + // ServiceCodePreviousSnapshotCannotBeNewer means the prevsnapshot query parameter value cannot be newer than snapshot query parameter value. + ServiceCodePreviousSnapshotCannotBeNewer ServiceCodeType = "PreviousSnapshotCannotBeNewer" + + // ServiceCodePreviousSnapshotNotFound means the previous snapshot is not found. + ServiceCodePreviousSnapshotNotFound ServiceCodeType = "PreviousSnapshotNotFound" + + // ServiceCodePreviousSnapshotOperationNotSupported means that differential Get Page Ranges is not supported on the previous snapshot. + ServiceCodePreviousSnapshotOperationNotSupported ServiceCodeType = "PreviousSnapshotOperationNotSupported" + + // ServiceCodeSequenceNumberConditionNotMet means the sequence number condition specified was not met. + ServiceCodeSequenceNumberConditionNotMet ServiceCodeType = "SequenceNumberConditionNotMet" + + // ServiceCodeSequenceNumberIncrementTooLarge means the sequence number increment cannot be performed because it would result in overflow of the sequence number. + ServiceCodeSequenceNumberIncrementTooLarge ServiceCodeType = "SequenceNumberIncrementTooLarge" + + // ServiceCodeSnapshotCountExceeded means the snapshot count against this blob has been exceeded. + ServiceCodeSnapshotCountExceeded ServiceCodeType = "SnapshotCountExceeded" + + // ServiceCodeSnaphotOperationRateExceeded means the rate of snapshot operations against this blob has been exceeded. + ServiceCodeSnaphotOperationRateExceeded ServiceCodeType = "SnaphotOperationRateExceeded" + + // ServiceCodeSnapshotsPresent means this operation is not permitted while the blob has snapshots. + ServiceCodeSnapshotsPresent ServiceCodeType = "SnapshotsPresent" + + // ServiceCodeSourceConditionNotMet means the source condition specified using HTTP conditional header(s) is not met. + ServiceCodeSourceConditionNotMet ServiceCodeType = "SourceConditionNotMet" + + // ServiceCodeSystemInUse means this blob is in use by the system. + ServiceCodeSystemInUse ServiceCodeType = "SystemInUse" + + // ServiceCodeTargetConditionNotMet means the target condition specified using HTTP conditional header(s) is not met. + ServiceCodeTargetConditionNotMet ServiceCodeType = "TargetConditionNotMet" + + // ServiceCodeUnauthorizedBlobOverwrite means this request is not authorized to perform blob overwrites. + ServiceCodeUnauthorizedBlobOverwrite ServiceCodeType = "UnauthorizedBlobOverwrite" + + // ServiceCodeBlobBeingRehydrated means this operation is not permitted because the blob is being rehydrated. + ServiceCodeBlobBeingRehydrated ServiceCodeType = "BlobBeingRehydrated" + + // ServiceCodeBlobArchived means this operation is not permitted on an archived blob. + ServiceCodeBlobArchived ServiceCodeType = "BlobArchived" + + // ServiceCodeBlobNotArchived means this blob is currently not in the archived state. + ServiceCodeBlobNotArchived ServiceCodeType = "BlobNotArchived" +) diff --git a/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/url_append_blob.go b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/url_append_blob.go new file mode 100644 index 0000000000..b8711f5a1c --- /dev/null +++ b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/url_append_blob.go @@ -0,0 +1,112 @@ +package azblob + +import ( + "context" + "io" + "net/url" + + "github.com/Azure/azure-pipeline-go/pipeline" +) + +const ( + // AppendBlobMaxAppendBlockBytes indicates the maximum number of bytes that can be sent in a call to AppendBlock. + AppendBlobMaxAppendBlockBytes = 4 * 1024 * 1024 // 4MB + + // AppendBlobMaxBlocks indicates the maximum number of blocks allowed in an append blob. + AppendBlobMaxBlocks = 50000 +) + +// AppendBlobURL defines a set of operations applicable to append blobs. +type AppendBlobURL struct { + BlobURL + abClient appendBlobClient +} + +// NewAppendBlobURL creates an AppendBlobURL object using the specified URL and request policy pipeline. +func NewAppendBlobURL(url url.URL, p pipeline.Pipeline) AppendBlobURL { + blobClient := newBlobClient(url, p) + abClient := newAppendBlobClient(url, p) + return AppendBlobURL{BlobURL: BlobURL{blobClient: blobClient}, abClient: abClient} +} + +// WithPipeline creates a new AppendBlobURL object identical to the source but with the specific request policy pipeline. +func (ab AppendBlobURL) WithPipeline(p pipeline.Pipeline) AppendBlobURL { + return NewAppendBlobURL(ab.blobClient.URL(), p) +} + +// WithSnapshot creates a new AppendBlobURL object identical to the source but with the specified snapshot timestamp. +// Pass "" to remove the snapshot returning a URL to the base blob. +func (ab AppendBlobURL) WithSnapshot(snapshot string) AppendBlobURL { + p := NewBlobURLParts(ab.URL()) + p.Snapshot = snapshot + return NewAppendBlobURL(p.URL(), ab.blobClient.Pipeline()) +} + +// Create creates a 0-length append blob. Call AppendBlock to append data to an append blob. +// For more information, see https://docs.microsoft.com/rest/api/storageservices/put-blob. +func (ab AppendBlobURL) Create(ctx context.Context, h BlobHTTPHeaders, metadata Metadata, ac BlobAccessConditions) (*AppendBlobCreateResponse, error) { + ifModifiedSince, ifUnmodifiedSince, ifMatch, ifNoneMatch := ac.HTTPAccessConditions.pointers() + return ab.abClient.Create(ctx, 0, nil, + &h.ContentType, &h.ContentEncoding, &h.ContentLanguage, h.ContentMD5, + &h.CacheControl, metadata, ac.LeaseAccessConditions.pointers(), &h.ContentDisposition, + ifModifiedSince, ifUnmodifiedSince, ifMatch, ifNoneMatch, nil) +} + +// AppendBlock writes a stream to a new block of data to the end of the existing append blob. +// This method panics if the stream is not at position 0. +// Note that the http client closes the body stream after the request is sent to the service. +// For more information, see https://docs.microsoft.com/rest/api/storageservices/append-block. +func (ab AppendBlobURL) AppendBlock(ctx context.Context, body io.ReadSeeker, ac BlobAccessConditions) (*AppendBlobAppendBlockResponse, error) { + ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.HTTPAccessConditions.pointers() + ifAppendPositionEqual, ifMaxSizeLessThanOrEqual := ac.AppendBlobAccessConditions.pointers() + return ab.abClient.AppendBlock(ctx, body, validateSeekableStreamAt0AndGetCount(body), nil, + ac.LeaseAccessConditions.pointers(), + ifMaxSizeLessThanOrEqual, ifAppendPositionEqual, + ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, nil) +} + +// AppendBlobAccessConditions identifies append blob-specific access conditions which you optionally set. +type AppendBlobAccessConditions struct { + // IfAppendPositionEqual ensures that the AppendBlock operation succeeds + // only if the append position is equal to a value. + // IfAppendPositionEqual=0 means no 'IfAppendPositionEqual' header specified. + // IfAppendPositionEqual>0 means 'IfAppendPositionEqual' header specified with its value + // IfAppendPositionEqual==-1 means IfAppendPositionEqual' header specified with a value of 0 + IfAppendPositionEqual int64 + + // IfMaxSizeLessThanOrEqual ensures that the AppendBlock operation succeeds + // only if the append blob's size is less than or equal to a value. + // IfMaxSizeLessThanOrEqual=0 means no 'IfMaxSizeLessThanOrEqual' header specified. + // IfMaxSizeLessThanOrEqual>0 means 'IfMaxSizeLessThanOrEqual' header specified with its value + // IfMaxSizeLessThanOrEqual==-1 means 'IfMaxSizeLessThanOrEqual' header specified with a value of 0 + IfMaxSizeLessThanOrEqual int64 +} + +// pointers is for internal infrastructure. It returns the fields as pointers. +func (ac AppendBlobAccessConditions) pointers() (iape *int64, imsltoe *int64) { + if ac.IfAppendPositionEqual < -1 { + panic("IfAppendPositionEqual can't be less than -1") + } + if ac.IfMaxSizeLessThanOrEqual < -1 { + panic("IfMaxSizeLessThanOrEqual can't be less than -1") + } + var zero int64 // defaults to 0 + switch ac.IfAppendPositionEqual { + case -1: + iape = &zero + case 0: + iape = nil + default: + iape = &ac.IfAppendPositionEqual + } + + switch ac.IfMaxSizeLessThanOrEqual { + case -1: + imsltoe = &zero + case 0: + imsltoe = nil + default: + imsltoe = &ac.IfMaxSizeLessThanOrEqual + } + return +} diff --git a/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/url_blob.go b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/url_blob.go new file mode 100644 index 0000000000..96d85cbfd8 --- /dev/null +++ b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/url_blob.go @@ -0,0 +1,222 @@ +package azblob + +import ( + "context" + "net/url" + + "github.com/Azure/azure-pipeline-go/pipeline" +) + +// A BlobURL represents a URL to an Azure Storage blob; the blob may be a block blob, append blob, or page blob. +type BlobURL struct { + blobClient blobClient +} + +// NewBlobURL creates a BlobURL object using the specified URL and request policy pipeline. +func NewBlobURL(url url.URL, p pipeline.Pipeline) BlobURL { + if p == nil { + panic("p can't be nil") + } + blobClient := newBlobClient(url, p) + return BlobURL{blobClient: blobClient} +} + +// URL returns the URL endpoint used by the BlobURL object. +func (b BlobURL) URL() url.URL { + return b.blobClient.URL() +} + +// String returns the URL as a string. +func (b BlobURL) String() string { + u := b.URL() + return u.String() +} + +// WithPipeline creates a new BlobURL object identical to the source but with the specified request policy pipeline. +func (b BlobURL) WithPipeline(p pipeline.Pipeline) BlobURL { + if p == nil { + panic("p can't be nil") + } + return NewBlobURL(b.blobClient.URL(), p) +} + +// WithSnapshot creates a new BlobURL object identical to the source but with the specified snapshot timestamp. +// Pass "" to remove the snapshot returning a URL to the base blob. +func (b BlobURL) WithSnapshot(snapshot string) BlobURL { + p := NewBlobURLParts(b.URL()) + p.Snapshot = snapshot + return NewBlobURL(p.URL(), b.blobClient.Pipeline()) +} + +// ToAppendBlobURL creates an AppendBlobURL using the source's URL and pipeline. +func (b BlobURL) ToAppendBlobURL() AppendBlobURL { + return NewAppendBlobURL(b.URL(), b.blobClient.Pipeline()) +} + +// ToBlockBlobURL creates a BlockBlobURL using the source's URL and pipeline. +func (b BlobURL) ToBlockBlobURL() BlockBlobURL { + return NewBlockBlobURL(b.URL(), b.blobClient.Pipeline()) +} + +// ToPageBlobURL creates a PageBlobURL using the source's URL and pipeline. +func (b BlobURL) ToPageBlobURL() PageBlobURL { + return NewPageBlobURL(b.URL(), b.blobClient.Pipeline()) +} + +// DownloadBlob reads a range of bytes from a blob. The response also includes the blob's properties and metadata. +// For more information, see https://docs.microsoft.com/rest/api/storageservices/get-blob. +func (b BlobURL) Download(ctx context.Context, offset int64, count int64, ac BlobAccessConditions, rangeGetContentMD5 bool) (*DownloadResponse, error) { + var xRangeGetContentMD5 *bool + if rangeGetContentMD5 { + xRangeGetContentMD5 = &rangeGetContentMD5 + } + ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.HTTPAccessConditions.pointers() + dr, err := b.blobClient.Download(ctx, nil, nil, + httpRange{offset: offset, count: count}.pointers(), + ac.LeaseAccessConditions.pointers(), xRangeGetContentMD5, + ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, nil) + if err != nil { + return nil, err + } + return &DownloadResponse{ + b: b, + r: dr, + ctx: ctx, + getInfo: HTTPGetterInfo{Offset: offset, Count: count, ETag: dr.ETag()}, + }, err +} + +// DeleteBlob marks the specified blob or snapshot for deletion. The blob is later deleted during garbage collection. +// Note that deleting a blob also deletes all its snapshots. +// For more information, see https://docs.microsoft.com/rest/api/storageservices/delete-blob. +func (b BlobURL) Delete(ctx context.Context, deleteOptions DeleteSnapshotsOptionType, ac BlobAccessConditions) (*BlobDeleteResponse, error) { + ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.HTTPAccessConditions.pointers() + return b.blobClient.Delete(ctx, nil, nil, ac.LeaseAccessConditions.pointers(), deleteOptions, + ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, nil) +} + +// Undelete restores the contents and metadata of a soft-deleted blob and any associated soft-deleted snapshots. +// For more information, see https://docs.microsoft.com/rest/api/storageservices/undelete-blob. +func (b BlobURL) Undelete(ctx context.Context) (*BlobUndeleteResponse, error) { + return b.blobClient.Undelete(ctx, nil, nil) +} + +// SetTier operation sets the tier on a blob. The operation is allowed on a page +// blob in a premium storage account and on a block blob in a blob storage account (locally +// redundant storage only). A premium page blob's tier determines the allowed size, IOPS, and +// bandwidth of the blob. A block blob's tier determines Hot/Cool/Archive storage type. This operation +// does not update the blob's ETag. +// For detailed information about block blob level tiering see https://docs.microsoft.com/en-us/azure/storage/blobs/storage-blob-storage-tiers. +func (b BlobURL) SetTier(ctx context.Context, tier AccessTierType) (*BlobSetTierResponse, error) { + return b.blobClient.SetTier(ctx, tier, nil, nil) +} + +// GetBlobProperties returns the blob's properties. +// For more information, see https://docs.microsoft.com/rest/api/storageservices/get-blob-properties. +func (b BlobURL) GetProperties(ctx context.Context, ac BlobAccessConditions) (*BlobGetPropertiesResponse, error) { + ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.HTTPAccessConditions.pointers() + return b.blobClient.GetProperties(ctx, nil, nil, ac.LeaseAccessConditions.pointers(), + ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, nil) +} + +// SetBlobHTTPHeaders changes a blob's HTTP headers. +// For more information, see https://docs.microsoft.com/rest/api/storageservices/set-blob-properties. +func (b BlobURL) SetHTTPHeaders(ctx context.Context, h BlobHTTPHeaders, ac BlobAccessConditions) (*BlobSetHTTPHeadersResponse, error) { + ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.HTTPAccessConditions.pointers() + return b.blobClient.SetHTTPHeaders(ctx, nil, + &h.CacheControl, &h.ContentType, h.ContentMD5, &h.ContentEncoding, &h.ContentLanguage, + ac.LeaseAccessConditions.pointers(), ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, + &h.ContentDisposition, nil) +} + +// SetBlobMetadata changes a blob's metadata. +// https://docs.microsoft.com/rest/api/storageservices/set-blob-metadata. +func (b BlobURL) SetMetadata(ctx context.Context, metadata Metadata, ac BlobAccessConditions) (*BlobSetMetadataResponse, error) { + ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.HTTPAccessConditions.pointers() + return b.blobClient.SetMetadata(ctx, nil, metadata, ac.LeaseAccessConditions.pointers(), + ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, nil) +} + +// CreateSnapshot creates a read-only snapshot of a blob. +// For more information, see https://docs.microsoft.com/rest/api/storageservices/snapshot-blob. +func (b BlobURL) CreateSnapshot(ctx context.Context, metadata Metadata, ac BlobAccessConditions) (*BlobCreateSnapshotResponse, error) { + // CreateSnapshot does NOT panic if the user tries to create a snapshot using a URL that already has a snapshot query parameter + // because checking this would be a performance hit for a VERY unusual path and I don't think the common case should suffer this + // performance hit. + ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.HTTPAccessConditions.pointers() + return b.blobClient.CreateSnapshot(ctx, nil, metadata, ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, ac.LeaseAccessConditions.pointers(), nil) +} + +// AcquireLease acquires a lease on the blob for write and delete operations. The lease duration must be between +// 15 to 60 seconds, or infinite (-1). +// For more information, see https://docs.microsoft.com/rest/api/storageservices/lease-blob. +func (b BlobURL) AcquireLease(ctx context.Context, proposedID string, duration int32, ac HTTPAccessConditions) (*BlobAcquireLeaseResponse, error) { + ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.pointers() + return b.blobClient.AcquireLease(ctx, nil, &duration, &proposedID, + ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, nil) +} + +// RenewLease renews the blob's previously-acquired lease. +// For more information, see https://docs.microsoft.com/rest/api/storageservices/lease-blob. +func (b BlobURL) RenewLease(ctx context.Context, leaseID string, ac HTTPAccessConditions) (*BlobRenewLeaseResponse, error) { + ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.pointers() + return b.blobClient.RenewLease(ctx, leaseID, nil, + ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, nil) +} + +// ReleaseLease releases the blob's previously-acquired lease. +// For more information, see https://docs.microsoft.com/rest/api/storageservices/lease-blob. +func (b BlobURL) ReleaseLease(ctx context.Context, leaseID string, ac HTTPAccessConditions) (*BlobReleaseLeaseResponse, error) { + ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.pointers() + return b.blobClient.ReleaseLease(ctx, leaseID, nil, + ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, nil) +} + +// BreakLease breaks the blob's previously-acquired lease (if it exists). Pass the LeaseBreakDefault (-1) +// constant to break a fixed-duration lease when it expires or an infinite lease immediately. +// For more information, see https://docs.microsoft.com/rest/api/storageservices/lease-blob. +func (b BlobURL) BreakLease(ctx context.Context, breakPeriodInSeconds int32, ac HTTPAccessConditions) (*BlobBreakLeaseResponse, error) { + ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.pointers() + return b.blobClient.BreakLease(ctx, nil, leasePeriodPointer(breakPeriodInSeconds), + ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, nil) +} + +// ChangeLease changes the blob's lease ID. +// For more information, see https://docs.microsoft.com/rest/api/storageservices/lease-blob. +func (b BlobURL) ChangeLease(ctx context.Context, leaseID string, proposedID string, ac HTTPAccessConditions) (*BlobChangeLeaseResponse, error) { + ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.pointers() + return b.blobClient.ChangeLease(ctx, leaseID, proposedID, + nil, ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, nil) +} + +// LeaseBreakNaturally tells ContainerURL's or BlobURL's BreakLease method to break the lease using service semantics. +const LeaseBreakNaturally = -1 + +func leasePeriodPointer(period int32) (p *int32) { + if period != LeaseBreakNaturally { + p = &period + } + return nil +} + +// StartCopyFromURL copies the data at the source URL to a blob. +// For more information, see https://docs.microsoft.com/rest/api/storageservices/copy-blob. +func (b BlobURL) StartCopyFromURL(ctx context.Context, source url.URL, metadata Metadata, srcac BlobAccessConditions, dstac BlobAccessConditions) (*BlobStartCopyFromURLResponse, error) { + srcIfModifiedSince, srcIfUnmodifiedSince, srcIfMatchETag, srcIfNoneMatchETag := srcac.HTTPAccessConditions.pointers() + dstIfModifiedSince, dstIfUnmodifiedSince, dstIfMatchETag, dstIfNoneMatchETag := dstac.HTTPAccessConditions.pointers() + srcLeaseID := srcac.LeaseAccessConditions.pointers() + dstLeaseID := dstac.LeaseAccessConditions.pointers() + + return b.blobClient.StartCopyFromURL(ctx, source.String(), nil, metadata, + srcIfModifiedSince, srcIfUnmodifiedSince, + srcIfMatchETag, srcIfNoneMatchETag, + dstIfModifiedSince, dstIfUnmodifiedSince, + dstIfMatchETag, dstIfNoneMatchETag, + dstLeaseID, srcLeaseID, nil) +} + +// AbortCopyFromURL stops a pending copy that was previously started and leaves a destination blob with 0 length and metadata. +// For more information, see https://docs.microsoft.com/rest/api/storageservices/abort-copy-blob. +func (b BlobURL) AbortCopyFromURL(ctx context.Context, copyID string, ac LeaseAccessConditions) (*BlobAbortCopyFromURLResponse, error) { + return b.blobClient.AbortCopyFromURL(ctx, copyID, nil, ac.pointers(), nil) +} diff --git a/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/url_block_blob.go b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/url_block_blob.go new file mode 100644 index 0000000000..ec70285587 --- /dev/null +++ b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/url_block_blob.go @@ -0,0 +1,157 @@ +package azblob + +import ( + "context" + "io" + "net/url" + + "encoding/base64" + "encoding/binary" + + "github.com/Azure/azure-pipeline-go/pipeline" +) + +const ( + // BlockBlobMaxPutBlobBytes indicates the maximum number of bytes that can be sent in a call to Upload. + BlockBlobMaxUploadBlobBytes = 256 * 1024 * 1024 // 256MB + + // BlockBlobMaxStageBlockBytes indicates the maximum number of bytes that can be sent in a call to StageBlock. + BlockBlobMaxStageBlockBytes = 100 * 1024 * 1024 // 100MB + + // BlockBlobMaxBlocks indicates the maximum number of blocks allowed in a block blob. + BlockBlobMaxBlocks = 50000 +) + +// BlockBlobURL defines a set of operations applicable to block blobs. +type BlockBlobURL struct { + BlobURL + bbClient blockBlobClient +} + +// NewBlockBlobURL creates a BlockBlobURL object using the specified URL and request policy pipeline. +func NewBlockBlobURL(url url.URL, p pipeline.Pipeline) BlockBlobURL { + if p == nil { + panic("p can't be nil") + } + blobClient := newBlobClient(url, p) + bbClient := newBlockBlobClient(url, p) + return BlockBlobURL{BlobURL: BlobURL{blobClient: blobClient}, bbClient: bbClient} +} + +// WithPipeline creates a new BlockBlobURL object identical to the source but with the specific request policy pipeline. +func (bb BlockBlobURL) WithPipeline(p pipeline.Pipeline) BlockBlobURL { + return NewBlockBlobURL(bb.blobClient.URL(), p) +} + +// WithSnapshot creates a new BlockBlobURL object identical to the source but with the specified snapshot timestamp. +// Pass "" to remove the snapshot returning a URL to the base blob. +func (bb BlockBlobURL) WithSnapshot(snapshot string) BlockBlobURL { + p := NewBlobURLParts(bb.URL()) + p.Snapshot = snapshot + return NewBlockBlobURL(p.URL(), bb.blobClient.Pipeline()) +} + +// Upload creates a new block blob or overwrites an existing block blob. +// Updating an existing block blob overwrites any existing metadata on the blob. Partial updates are not +// supported with Upload; the content of the existing blob is overwritten with the new content. To +// perform a partial update of a block blob, use StageBlock and CommitBlockList. +// This method panics if the stream is not at position 0. +// Note that the http client closes the body stream after the request is sent to the service. +// For more information, see https://docs.microsoft.com/rest/api/storageservices/put-blob. +func (bb BlockBlobURL) Upload(ctx context.Context, body io.ReadSeeker, h BlobHTTPHeaders, metadata Metadata, ac BlobAccessConditions) (*BlockBlobUploadResponse, error) { + ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.HTTPAccessConditions.pointers() + return bb.bbClient.Upload(ctx, body, validateSeekableStreamAt0AndGetCount(body), nil, + &h.ContentType, &h.ContentEncoding, &h.ContentLanguage, h.ContentMD5, + &h.CacheControl, metadata, ac.LeaseAccessConditions.pointers(), + &h.ContentDisposition, ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, + nil) +} + +// StageBlock uploads the specified block to the block blob's "staging area" to be later committed by a call to CommitBlockList. +// Note that the http client closes the body stream after the request is sent to the service. +// For more information, see https://docs.microsoft.com/rest/api/storageservices/put-block. +func (bb BlockBlobURL) StageBlock(ctx context.Context, base64BlockID string, body io.ReadSeeker, ac LeaseAccessConditions) (*BlockBlobStageBlockResponse, error) { + return bb.bbClient.StageBlock(ctx, base64BlockID, validateSeekableStreamAt0AndGetCount(body), body, nil, ac.pointers(), nil) +} + +// StageBlockFromURL copies the specified block from a source URL to the block blob's "staging area" to be later committed by a call to CommitBlockList. +// If count is CountToEnd (0), then data is read from specified offset to the end. +// For more information, see https://docs.microsoft.com/en-us/rest/api/storageservices/put-block-from-url. +func (bb BlockBlobURL) StageBlockFromURL(ctx context.Context, base64BlockID string, sourceURL url.URL, offset int64, count int64, ac LeaseAccessConditions) (*BlockBlobStageBlockFromURLResponse, error) { + sourceURLStr := sourceURL.String() + return bb.bbClient.StageBlockFromURL(ctx, base64BlockID, 0, &sourceURLStr, httpRange{offset: offset, count: count}.pointers(), nil, nil, ac.pointers(), nil) +} + +// CommitBlockList writes a blob by specifying the list of block IDs that make up the blob. +// In order to be written as part of a blob, a block must have been successfully written +// to the server in a prior PutBlock operation. You can call PutBlockList to update a blob +// by uploading only those blocks that have changed, then committing the new and existing +// blocks together. Any blocks not specified in the block list and permanently deleted. +// For more information, see https://docs.microsoft.com/rest/api/storageservices/put-block-list. +func (bb BlockBlobURL) CommitBlockList(ctx context.Context, base64BlockIDs []string, h BlobHTTPHeaders, + metadata Metadata, ac BlobAccessConditions) (*BlockBlobCommitBlockListResponse, error) { + ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.HTTPAccessConditions.pointers() + return bb.bbClient.CommitBlockList(ctx, BlockLookupList{Latest: base64BlockIDs}, nil, + &h.CacheControl, &h.ContentType, &h.ContentEncoding, &h.ContentLanguage, h.ContentMD5, + metadata, ac.LeaseAccessConditions.pointers(), &h.ContentDisposition, + ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, nil) +} + +// GetBlockList returns the list of blocks that have been uploaded as part of a block blob using the specified block list filter. +// For more information, see https://docs.microsoft.com/rest/api/storageservices/get-block-list. +func (bb BlockBlobURL) GetBlockList(ctx context.Context, listType BlockListType, ac LeaseAccessConditions) (*BlockList, error) { + return bb.bbClient.GetBlockList(ctx, listType, nil, nil, ac.pointers(), nil) +} + +////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +type BlockID [64]byte + +func (blockID BlockID) ToBase64() string { + return base64.StdEncoding.EncodeToString(blockID[:]) +} + +func (blockID *BlockID) FromBase64(s string) error { + *blockID = BlockID{} // Zero out the block ID + _, err := base64.StdEncoding.Decode(blockID[:], ([]byte)(s)) + return err +} + +////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +type uuidBlockID BlockID + +func (ubi uuidBlockID) UUID() uuid { + u := uuid{} + copy(u[:], ubi[:len(u)]) + return u +} + +func (ubi uuidBlockID) Number() uint32 { + return binary.BigEndian.Uint32(ubi[len(uuid{}):]) +} + +func newUuidBlockID(u uuid) uuidBlockID { + ubi := uuidBlockID{} // Create a new uuidBlockID + copy(ubi[:len(u)], u[:]) // Copy the specified UUID into it + // Block number defaults to 0 + return ubi +} + +func (ubi *uuidBlockID) SetUUID(u uuid) *uuidBlockID { + copy(ubi[:len(u)], u[:]) + return ubi +} + +func (ubi uuidBlockID) WithBlockNumber(blockNumber uint32) uuidBlockID { + binary.BigEndian.PutUint32(ubi[len(uuid{}):], blockNumber) // Put block number after UUID + return ubi // Return the passed-in copy +} + +func (ubi uuidBlockID) ToBase64() string { + return BlockID(ubi).ToBase64() +} + +func (ubi *uuidBlockID) FromBase64(s string) error { + return (*BlockID)(ubi).FromBase64(s) +} diff --git a/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/url_container.go b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/url_container.go new file mode 100644 index 0000000000..0fad9f0767 --- /dev/null +++ b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/url_container.go @@ -0,0 +1,300 @@ +package azblob + +import ( + "bytes" + "context" + "fmt" + "net/url" + + "github.com/Azure/azure-pipeline-go/pipeline" +) + +// A ContainerURL represents a URL to the Azure Storage container allowing you to manipulate its blobs. +type ContainerURL struct { + client containerClient +} + +// NewContainerURL creates a ContainerURL object using the specified URL and request policy pipeline. +func NewContainerURL(url url.URL, p pipeline.Pipeline) ContainerURL { + if p == nil { + panic("p can't be nil") + } + client := newContainerClient(url, p) + return ContainerURL{client: client} +} + +// URL returns the URL endpoint used by the ContainerURL object. +func (c ContainerURL) URL() url.URL { + return c.client.URL() +} + +// String returns the URL as a string. +func (c ContainerURL) String() string { + u := c.URL() + return u.String() +} + +// WithPipeline creates a new ContainerURL object identical to the source but with the specified request policy pipeline. +func (c ContainerURL) WithPipeline(p pipeline.Pipeline) ContainerURL { + return NewContainerURL(c.URL(), p) +} + +// NewBlobURL creates a new BlobURL object by concatenating blobName to the end of +// ContainerURL's URL. The new BlobURL uses the same request policy pipeline as the ContainerURL. +// To change the pipeline, create the BlobURL and then call its WithPipeline method passing in the +// desired pipeline object. Or, call this package's NewBlobURL instead of calling this object's +// NewBlobURL method. +func (c ContainerURL) NewBlobURL(blobName string) BlobURL { + blobURL := appendToURLPath(c.URL(), blobName) + return NewBlobURL(blobURL, c.client.Pipeline()) +} + +// NewAppendBlobURL creates a new AppendBlobURL object by concatenating blobName to the end of +// ContainerURL's URL. The new AppendBlobURL uses the same request policy pipeline as the ContainerURL. +// To change the pipeline, create the AppendBlobURL and then call its WithPipeline method passing in the +// desired pipeline object. Or, call this package's NewAppendBlobURL instead of calling this object's +// NewAppendBlobURL method. +func (c ContainerURL) NewAppendBlobURL(blobName string) AppendBlobURL { + blobURL := appendToURLPath(c.URL(), blobName) + return NewAppendBlobURL(blobURL, c.client.Pipeline()) +} + +// NewBlockBlobURL creates a new BlockBlobURL object by concatenating blobName to the end of +// ContainerURL's URL. The new BlockBlobURL uses the same request policy pipeline as the ContainerURL. +// To change the pipeline, create the BlockBlobURL and then call its WithPipeline method passing in the +// desired pipeline object. Or, call this package's NewBlockBlobURL instead of calling this object's +// NewBlockBlobURL method. +func (c ContainerURL) NewBlockBlobURL(blobName string) BlockBlobURL { + blobURL := appendToURLPath(c.URL(), blobName) + return NewBlockBlobURL(blobURL, c.client.Pipeline()) +} + +// NewPageBlobURL creates a new PageBlobURL object by concatenating blobName to the end of +// ContainerURL's URL. The new PageBlobURL uses the same request policy pipeline as the ContainerURL. +// To change the pipeline, create the PageBlobURL and then call its WithPipeline method passing in the +// desired pipeline object. Or, call this package's NewPageBlobURL instead of calling this object's +// NewPageBlobURL method. +func (c ContainerURL) NewPageBlobURL(blobName string) PageBlobURL { + blobURL := appendToURLPath(c.URL(), blobName) + return NewPageBlobURL(blobURL, c.client.Pipeline()) +} + +// Create creates a new container within a storage account. If a container with the same name already exists, the operation fails. +// For more information, see https://docs.microsoft.com/rest/api/storageservices/create-container. +func (c ContainerURL) Create(ctx context.Context, metadata Metadata, publicAccessType PublicAccessType) (*ContainerCreateResponse, error) { + return c.client.Create(ctx, nil, metadata, publicAccessType, nil) +} + +// Delete marks the specified container for deletion. The container and any blobs contained within it are later deleted during garbage collection. +// For more information, see https://docs.microsoft.com/rest/api/storageservices/delete-container. +func (c ContainerURL) Delete(ctx context.Context, ac ContainerAccessConditions) (*ContainerDeleteResponse, error) { + if ac.IfMatch != ETagNone || ac.IfNoneMatch != ETagNone { + panic("the IfMatch and IfNoneMatch access conditions must have their default values because they are ignored by the service") + } + + ifModifiedSince, ifUnmodifiedSince, _, _ := ac.HTTPAccessConditions.pointers() + return c.client.Delete(ctx, nil, ac.LeaseAccessConditions.pointers(), + ifModifiedSince, ifUnmodifiedSince, nil) +} + +// GetProperties returns the container's properties. +// For more information, see https://docs.microsoft.com/rest/api/storageservices/get-container-metadata. +func (c ContainerURL) GetProperties(ctx context.Context, ac LeaseAccessConditions) (*ContainerGetPropertiesResponse, error) { + // NOTE: GetMetadata actually calls GetProperties internally because GetProperties returns the metadata AND the properties. + // This allows us to not expose a GetProperties method at all simplifying the API. + return c.client.GetProperties(ctx, nil, ac.pointers(), nil) +} + +// SetMetadata sets the container's metadata. +// For more information, see https://docs.microsoft.com/rest/api/storageservices/set-container-metadata. +func (c ContainerURL) SetMetadata(ctx context.Context, metadata Metadata, ac ContainerAccessConditions) (*ContainerSetMetadataResponse, error) { + if !ac.IfUnmodifiedSince.IsZero() || ac.IfMatch != ETagNone || ac.IfNoneMatch != ETagNone { + panic("the IfUnmodifiedSince, IfMatch, and IfNoneMatch must have their default values because they are ignored by the blob service") + } + ifModifiedSince, _, _, _ := ac.HTTPAccessConditions.pointers() + return c.client.SetMetadata(ctx, nil, ac.LeaseAccessConditions.pointers(), metadata, ifModifiedSince, nil) +} + +// GetAccessPolicy returns the container's access policy. The access policy indicates whether container's blobs may be accessed publicly. +// For more information, see https://docs.microsoft.com/rest/api/storageservices/get-container-acl. +func (c ContainerURL) GetAccessPolicy(ctx context.Context, ac LeaseAccessConditions) (*SignedIdentifiers, error) { + return c.client.GetAccessPolicy(ctx, nil, ac.pointers(), nil) +} + +// The AccessPolicyPermission type simplifies creating the permissions string for a container's access policy. +// Initialize an instance of this type and then call its String method to set AccessPolicy's Permission field. +type AccessPolicyPermission struct { + Read, Add, Create, Write, Delete, List bool +} + +// String produces the access policy permission string for an Azure Storage container. +// Call this method to set AccessPolicy's Permission field. +func (p AccessPolicyPermission) String() string { + var b bytes.Buffer + if p.Read { + b.WriteRune('r') + } + if p.Add { + b.WriteRune('a') + } + if p.Create { + b.WriteRune('c') + } + if p.Write { + b.WriteRune('w') + } + if p.Delete { + b.WriteRune('d') + } + if p.List { + b.WriteRune('l') + } + return b.String() +} + +// Parse initializes the AccessPolicyPermission's fields from a string. +func (p *AccessPolicyPermission) Parse(s string) error { + *p = AccessPolicyPermission{} // Clear the flags + for _, r := range s { + switch r { + case 'r': + p.Read = true + case 'a': + p.Add = true + case 'c': + p.Create = true + case 'w': + p.Write = true + case 'd': + p.Delete = true + case 'l': + p.List = true + default: + return fmt.Errorf("invalid permission: '%v'", r) + } + } + return nil +} + +// SetAccessPolicy sets the container's permissions. The access policy indicates whether blobs in a container may be accessed publicly. +// For more information, see https://docs.microsoft.com/rest/api/storageservices/set-container-acl. +func (c ContainerURL) SetAccessPolicy(ctx context.Context, accessType PublicAccessType, si []SignedIdentifier, + ac ContainerAccessConditions) (*ContainerSetAccessPolicyResponse, error) { + if ac.IfMatch != ETagNone || ac.IfNoneMatch != ETagNone { + panic("the IfMatch and IfNoneMatch access conditions must have their default values because they are ignored by the service") + } + ifModifiedSince, ifUnmodifiedSince, _, _ := ac.HTTPAccessConditions.pointers() + return c.client.SetAccessPolicy(ctx, si, nil, ac.LeaseAccessConditions.pointers(), + accessType, ifModifiedSince, ifUnmodifiedSince, nil) +} + +// AcquireLease acquires a lease on the container for delete operations. The lease duration must be between 15 to 60 seconds, or infinite (-1). +// For more information, see https://docs.microsoft.com/rest/api/storageservices/lease-container. +func (c ContainerURL) AcquireLease(ctx context.Context, proposedID string, duration int32, ac HTTPAccessConditions) (*ContainerAcquireLeaseResponse, error) { + ifModifiedSince, ifUnmodifiedSince, _, _ := ac.pointers() + return c.client.AcquireLease(ctx, nil, &duration, &proposedID, + ifModifiedSince, ifUnmodifiedSince, nil) +} + +// RenewLease renews the container's previously-acquired lease. +// For more information, see https://docs.microsoft.com/rest/api/storageservices/lease-container. +func (c ContainerURL) RenewLease(ctx context.Context, leaseID string, ac HTTPAccessConditions) (*ContainerRenewLeaseResponse, error) { + ifModifiedSince, ifUnmodifiedSince, _, _ := ac.pointers() + return c.client.RenewLease(ctx, leaseID, nil, ifModifiedSince, ifUnmodifiedSince, nil) +} + +// ReleaseLease releases the container's previously-acquired lease. +// For more information, see https://docs.microsoft.com/rest/api/storageservices/lease-container. +func (c ContainerURL) ReleaseLease(ctx context.Context, leaseID string, ac HTTPAccessConditions) (*ContainerReleaseLeaseResponse, error) { + ifModifiedSince, ifUnmodifiedSince, _, _ := ac.pointers() + return c.client.ReleaseLease(ctx, leaseID, nil, ifModifiedSince, ifUnmodifiedSince, nil) +} + +// BreakLease breaks the container's previously-acquired lease (if it exists). +// For more information, see https://docs.microsoft.com/rest/api/storageservices/lease-container. +func (c ContainerURL) BreakLease(ctx context.Context, period int32, ac HTTPAccessConditions) (*ContainerBreakLeaseResponse, error) { + ifModifiedSince, ifUnmodifiedSince, _, _ := ac.pointers() + return c.client.BreakLease(ctx, nil, leasePeriodPointer(period), ifModifiedSince, ifUnmodifiedSince, nil) +} + +// ChangeLease changes the container's lease ID. +// For more information, see https://docs.microsoft.com/rest/api/storageservices/lease-container. +func (c ContainerURL) ChangeLease(ctx context.Context, leaseID string, proposedID string, ac HTTPAccessConditions) (*ContainerChangeLeaseResponse, error) { + ifModifiedSince, ifUnmodifiedSince, _, _ := ac.pointers() + return c.client.ChangeLease(ctx, leaseID, proposedID, nil, ifModifiedSince, ifUnmodifiedSince, nil) +} + +// ListBlobsFlatSegment returns a single segment of blobs starting from the specified Marker. Use an empty +// Marker to start enumeration from the beginning. Blob names are returned in lexicographic order. +// After getting a segment, process it, and then call ListBlobsFlatSegment again (passing the the +// previously-returned Marker) to get the next segment. +// For more information, see https://docs.microsoft.com/rest/api/storageservices/list-blobs. +func (c ContainerURL) ListBlobsFlatSegment(ctx context.Context, marker Marker, o ListBlobsSegmentOptions) (*ListBlobsFlatSegmentResponse, error) { + prefix, include, maxResults := o.pointers() + return c.client.ListBlobFlatSegment(ctx, prefix, marker.val, maxResults, include, nil, nil) +} + +// ListBlobsHierarchySegment returns a single segment of blobs starting from the specified Marker. Use an empty +// Marker to start enumeration from the beginning. Blob names are returned in lexicographic order. +// After getting a segment, process it, and then call ListBlobsHierarchicalSegment again (passing the the +// previously-returned Marker) to get the next segment. +// For more information, see https://docs.microsoft.com/rest/api/storageservices/list-blobs. +func (c ContainerURL) ListBlobsHierarchySegment(ctx context.Context, marker Marker, delimiter string, o ListBlobsSegmentOptions) (*ListBlobsHierarchySegmentResponse, error) { + if o.Details.Snapshots { + panic("snapshots are not supported in this listing operation") + } + prefix, include, maxResults := o.pointers() + return c.client.ListBlobHierarchySegment(ctx, delimiter, prefix, marker.val, maxResults, include, nil, nil) +} + +// ListBlobsSegmentOptions defines options available when calling ListBlobs. +type ListBlobsSegmentOptions struct { + Details BlobListingDetails // No IncludeType header is produced if "" + Prefix string // No Prefix header is produced if "" + + // SetMaxResults sets the maximum desired results you want the service to return. Note, the + // service may return fewer results than requested. + // MaxResults=0 means no 'MaxResults' header specified. + MaxResults int32 +} + +func (o *ListBlobsSegmentOptions) pointers() (prefix *string, include []ListBlobsIncludeItemType, maxResults *int32) { + if o.Prefix != "" { + prefix = &o.Prefix + } + include = o.Details.slice() + if o.MaxResults != 0 { + if o.MaxResults < 0 { + panic("MaxResults must be >= 0") + } + maxResults = &o.MaxResults + } + return +} + +// BlobListingDetails indicates what additional information the service should return with each blob. +type BlobListingDetails struct { + Copy, Metadata, Snapshots, UncommittedBlobs, Deleted bool +} + +// string produces the Include query parameter's value. +func (d *BlobListingDetails) slice() []ListBlobsIncludeItemType { + items := []ListBlobsIncludeItemType{} + // NOTE: Multiple strings MUST be appended in alphabetic order or signing the string for authentication fails! + if d.Copy { + items = append(items, ListBlobsIncludeItemCopy) + } + if d.Deleted { + items = append(items, ListBlobsIncludeItemDeleted) + } + if d.Metadata { + items = append(items, ListBlobsIncludeItemMetadata) + } + if d.Snapshots { + items = append(items, ListBlobsIncludeItemSnapshots) + } + if d.UncommittedBlobs { + items = append(items, ListBlobsIncludeItemUncommittedblobs) + } + return items +} diff --git a/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/url_page_blob.go b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/url_page_blob.go new file mode 100644 index 0000000000..fa87ef8527 --- /dev/null +++ b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/url_page_blob.go @@ -0,0 +1,236 @@ +package azblob + +import ( + "context" + "fmt" + "io" + "net/url" + "strconv" + + "github.com/Azure/azure-pipeline-go/pipeline" +) + +const ( + // PageBlobPageBytes indicates the number of bytes in a page (512). + PageBlobPageBytes = 512 + + // PageBlobMaxPutPagesBytes indicates the maximum number of bytes that can be sent in a call to PutPage. + PageBlobMaxUploadPagesBytes = 4 * 1024 * 1024 // 4MB +) + +// PageBlobURL defines a set of operations applicable to page blobs. +type PageBlobURL struct { + BlobURL + pbClient pageBlobClient +} + +// NewPageBlobURL creates a PageBlobURL object using the specified URL and request policy pipeline. +func NewPageBlobURL(url url.URL, p pipeline.Pipeline) PageBlobURL { + if p == nil { + panic("p can't be nil") + } + blobClient := newBlobClient(url, p) + pbClient := newPageBlobClient(url, p) + return PageBlobURL{BlobURL: BlobURL{blobClient: blobClient}, pbClient: pbClient} +} + +// WithPipeline creates a new PageBlobURL object identical to the source but with the specific request policy pipeline. +func (pb PageBlobURL) WithPipeline(p pipeline.Pipeline) PageBlobURL { + return NewPageBlobURL(pb.blobClient.URL(), p) +} + +// WithSnapshot creates a new PageBlobURL object identical to the source but with the specified snapshot timestamp. +// Pass "" to remove the snapshot returning a URL to the base blob. +func (pb PageBlobURL) WithSnapshot(snapshot string) PageBlobURL { + p := NewBlobURLParts(pb.URL()) + p.Snapshot = snapshot + return NewPageBlobURL(p.URL(), pb.blobClient.Pipeline()) +} + +// CreatePageBlob creates a page blob of the specified length. Call PutPage to upload data data to a page blob. +// For more information, see https://docs.microsoft.com/rest/api/storageservices/put-blob. +func (pb PageBlobURL) Create(ctx context.Context, size int64, sequenceNumber int64, h BlobHTTPHeaders, metadata Metadata, ac BlobAccessConditions) (*PageBlobCreateResponse, error) { + if sequenceNumber < 0 { + panic("sequenceNumber must be greater than or equal to 0") + } + ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.HTTPAccessConditions.pointers() + return pb.pbClient.Create(ctx, 0, nil, + &h.ContentType, &h.ContentEncoding, &h.ContentLanguage, h.ContentMD5, &h.CacheControl, + metadata, ac.LeaseAccessConditions.pointers(), + &h.ContentDisposition, ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, &size, &sequenceNumber, nil) +} + +// UploadPages writes 1 or more pages to the page blob. The start offset and the stream size must be a multiple of 512 bytes. +// This method panics if the stream is not at position 0. +// Note that the http client closes the body stream after the request is sent to the service. +// For more information, see https://docs.microsoft.com/rest/api/storageservices/put-page. +func (pb PageBlobURL) UploadPages(ctx context.Context, offset int64, body io.ReadSeeker, ac BlobAccessConditions) (*PageBlobUploadPagesResponse, error) { + count := validateSeekableStreamAt0AndGetCount(body) + ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.HTTPAccessConditions.pointers() + ifSequenceNumberLessThanOrEqual, ifSequenceNumberLessThan, ifSequenceNumberEqual := ac.PageBlobAccessConditions.pointers() + return pb.pbClient.UploadPages(ctx, body, count, nil, + PageRange{Start: offset, End: offset + count - 1}.pointers(), + ac.LeaseAccessConditions.pointers(), + ifSequenceNumberLessThanOrEqual, ifSequenceNumberLessThan, ifSequenceNumberEqual, + ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, nil) +} + +// ClearPages frees the specified pages from the page blob. +// For more information, see https://docs.microsoft.com/rest/api/storageservices/put-page. +func (pb PageBlobURL) ClearPages(ctx context.Context, offset int64, count int64, ac BlobAccessConditions) (*PageBlobClearPagesResponse, error) { + ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.HTTPAccessConditions.pointers() + ifSequenceNumberLessThanOrEqual, ifSequenceNumberLessThan, ifSequenceNumberEqual := ac.PageBlobAccessConditions.pointers() + return pb.pbClient.ClearPages(ctx, 0, nil, + PageRange{Start: offset, End: offset + count - 1}.pointers(), + ac.LeaseAccessConditions.pointers(), + ifSequenceNumberLessThanOrEqual, ifSequenceNumberLessThan, + ifSequenceNumberEqual, ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, nil) +} + +// GetPageRanges returns the list of valid page ranges for a page blob or snapshot of a page blob. +// For more information, see https://docs.microsoft.com/rest/api/storageservices/get-page-ranges. +func (pb PageBlobURL) GetPageRanges(ctx context.Context, offset int64, count int64, ac BlobAccessConditions) (*PageList, error) { + ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.HTTPAccessConditions.pointers() + return pb.pbClient.GetPageRanges(ctx, nil, nil, + httpRange{offset: offset, count: count}.pointers(), + ac.LeaseAccessConditions.pointers(), + ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, nil) +} + +// GetPageRangesDiff gets the collection of page ranges that differ between a specified snapshot and this page blob. +// For more information, see https://docs.microsoft.com/rest/api/storageservices/get-page-ranges. +func (pb PageBlobURL) GetPageRangesDiff(ctx context.Context, offset int64, count int64, prevSnapshot string, ac BlobAccessConditions) (*PageList, error) { + ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.HTTPAccessConditions.pointers() + return pb.pbClient.GetPageRangesDiff(ctx, nil, nil, &prevSnapshot, + httpRange{offset: offset, count: count}.pointers(), + ac.LeaseAccessConditions.pointers(), + ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, + nil) +} + +// Resize resizes the page blob to the specified size (which must be a multiple of 512). +// For more information, see https://docs.microsoft.com/rest/api/storageservices/set-blob-properties. +func (pb PageBlobURL) Resize(ctx context.Context, size int64, ac BlobAccessConditions) (*PageBlobResizeResponse, error) { + if size%PageBlobPageBytes != 0 { + panic("Size must be a multiple of PageBlobPageBytes (512)") + } + ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.HTTPAccessConditions.pointers() + return pb.pbClient.Resize(ctx, size, nil, ac.LeaseAccessConditions.pointers(), + ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, nil) +} + +// SetSequenceNumber sets the page blob's sequence number. +func (pb PageBlobURL) UpdateSequenceNumber(ctx context.Context, action SequenceNumberActionType, sequenceNumber int64, + ac BlobAccessConditions) (*PageBlobUpdateSequenceNumberResponse, error) { + if sequenceNumber < 0 { + panic("sequenceNumber must be greater than or equal to 0") + } + sn := &sequenceNumber + if action == SequenceNumberActionIncrement { + sn = nil + } + ifModifiedSince, ifUnmodifiedSince, ifMatch, ifNoneMatch := ac.HTTPAccessConditions.pointers() + return pb.pbClient.UpdateSequenceNumber(ctx, action, nil, + ac.LeaseAccessConditions.pointers(), ifModifiedSince, ifUnmodifiedSince, ifMatch, ifNoneMatch, + sn, nil) +} + +// StartIncrementalCopy begins an operation to start an incremental copy from one page blob's snapshot to this page blob. +// The snapshot is copied such that only the differential changes between the previously copied snapshot are transferred to the destination. +// The copied snapshots are complete copies of the original snapshot and can be read or copied from as usual. +// For more information, see https://docs.microsoft.com/rest/api/storageservices/incremental-copy-blob and +// https://docs.microsoft.com/en-us/azure/virtual-machines/windows/incremental-snapshots. +func (pb PageBlobURL) StartCopyIncremental(ctx context.Context, source url.URL, snapshot string, ac BlobAccessConditions) (*PageBlobCopyIncrementalResponse, error) { + ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag := ac.HTTPAccessConditions.pointers() + qp := source.Query() + qp.Set("snapshot", snapshot) + source.RawQuery = qp.Encode() + return pb.pbClient.CopyIncremental(ctx, source.String(), nil, nil, + ifModifiedSince, ifUnmodifiedSince, ifMatchETag, ifNoneMatchETag, nil) +} + +func (pr PageRange) pointers() *string { + if pr.Start < 0 { + panic("PageRange's Start value must be greater than or equal to 0") + } + if pr.End <= 0 { + panic("PageRange's End value must be greater than 0") + } + if pr.Start%PageBlobPageBytes != 0 { + panic("PageRange's Start value must be a multiple of 512") + } + if pr.End%PageBlobPageBytes != (PageBlobPageBytes - 1) { + panic("PageRange's End value must be 1 less than a multiple of 512") + } + if pr.End <= pr.Start { + panic("PageRange's End value must be after the start") + } + endOffset := strconv.FormatInt(int64(pr.End), 10) + asString := fmt.Sprintf("bytes=%v-%s", pr.Start, endOffset) + return &asString +} + +// PageBlobAccessConditions identifies page blob-specific access conditions which you optionally set. +type PageBlobAccessConditions struct { + // IfSequenceNumberLessThan ensures that the page blob operation succeeds + // only if the blob's sequence number is less than a value. + // IfSequenceNumberLessThan=0 means no 'IfSequenceNumberLessThan' header specified. + // IfSequenceNumberLessThan>0 means 'IfSequenceNumberLessThan' header specified with its value + // IfSequenceNumberLessThan==-1 means 'IfSequenceNumberLessThan' header specified with a value of 0 + IfSequenceNumberLessThan int64 + + // IfSequenceNumberLessThanOrEqual ensures that the page blob operation succeeds + // only if the blob's sequence number is less than or equal to a value. + // IfSequenceNumberLessThanOrEqual=0 means no 'IfSequenceNumberLessThanOrEqual' header specified. + // IfSequenceNumberLessThanOrEqual>0 means 'IfSequenceNumberLessThanOrEqual' header specified with its value + // IfSequenceNumberLessThanOrEqual=-1 means 'IfSequenceNumberLessThanOrEqual' header specified with a value of 0 + IfSequenceNumberLessThanOrEqual int64 + + // IfSequenceNumberEqual ensures that the page blob operation succeeds + // only if the blob's sequence number is equal to a value. + // IfSequenceNumberEqual=0 means no 'IfSequenceNumberEqual' header specified. + // IfSequenceNumberEqual>0 means 'IfSequenceNumberEqual' header specified with its value + // IfSequenceNumberEqual=-1 means 'IfSequenceNumberEqual' header specified with a value of 0 + IfSequenceNumberEqual int64 +} + +// pointers is for internal infrastructure. It returns the fields as pointers. +func (ac PageBlobAccessConditions) pointers() (snltoe *int64, snlt *int64, sne *int64) { + if ac.IfSequenceNumberLessThan < -1 { + panic("Ifsequencenumberlessthan can't be less than -1") + } + if ac.IfSequenceNumberLessThanOrEqual < -1 { + panic("IfSequenceNumberLessThanOrEqual can't be less than -1") + } + if ac.IfSequenceNumberEqual < -1 { + panic("IfSequenceNumberEqual can't be less than -1") + } + + var zero int64 // Defaults to 0 + switch ac.IfSequenceNumberLessThan { + case -1: + snlt = &zero + case 0: + snlt = nil + default: + snlt = &ac.IfSequenceNumberLessThan + } + + switch ac.IfSequenceNumberLessThanOrEqual { + case -1: + snltoe = &zero + case 0: + snltoe = nil + default: + snltoe = &ac.IfSequenceNumberLessThanOrEqual + } + switch ac.IfSequenceNumberEqual { + case -1: + sne = &zero + case 0: + sne = nil + default: + sne = &ac.IfSequenceNumberEqual + } + return +} diff --git a/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/url_service.go b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/url_service.go new file mode 100644 index 0000000000..d49a20846b --- /dev/null +++ b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/url_service.go @@ -0,0 +1,140 @@ +package azblob + +import ( + "context" + "net/url" + "strings" + + "github.com/Azure/azure-pipeline-go/pipeline" +) + +const ( + // ContainerNameRoot is the special Azure Storage name used to identify a storage account's root container. + ContainerNameRoot = "$root" + + // ContainerNameLogs is the special Azure Storage name used to identify a storage account's logs container. + ContainerNameLogs = "$logs" +) + +// A ServiceURL represents a URL to the Azure Storage Blob service allowing you to manipulate blob containers. +type ServiceURL struct { + client serviceClient +} + +// NewServiceURL creates a ServiceURL object using the specified URL and request policy pipeline. +func NewServiceURL(primaryURL url.URL, p pipeline.Pipeline) ServiceURL { + if p == nil { + panic("p can't be nil") + } + client := newServiceClient(primaryURL, p) + return ServiceURL{client: client} +} + +// URL returns the URL endpoint used by the ServiceURL object. +func (s ServiceURL) URL() url.URL { + return s.client.URL() +} + +// String returns the URL as a string. +func (s ServiceURL) String() string { + u := s.URL() + return u.String() +} + +// WithPipeline creates a new ServiceURL object identical to the source but with the specified request policy pipeline. +func (s ServiceURL) WithPipeline(p pipeline.Pipeline) ServiceURL { + return NewServiceURL(s.URL(), p) +} + +// NewContainerURL creates a new ContainerURL object by concatenating containerName to the end of +// ServiceURL's URL. The new ContainerURL uses the same request policy pipeline as the ServiceURL. +// To change the pipeline, create the ContainerURL and then call its WithPipeline method passing in the +// desired pipeline object. Or, call this package's NewContainerURL instead of calling this object's +// NewContainerURL method. +func (s ServiceURL) NewContainerURL(containerName string) ContainerURL { + containerURL := appendToURLPath(s.URL(), containerName) + return NewContainerURL(containerURL, s.client.Pipeline()) +} + +// appendToURLPath appends a string to the end of a URL's path (prefixing the string with a '/' if required) +func appendToURLPath(u url.URL, name string) url.URL { + // e.g. "https://ms.com/a/b/?k1=v1&k2=v2#f" + // When you call url.Parse() this is what you'll get: + // Scheme: "https" + // Opaque: "" + // User: nil + // Host: "ms.com" + // Path: "/a/b/" This should start with a / and it might or might not have a trailing slash + // RawPath: "" + // ForceQuery: false + // RawQuery: "k1=v1&k2=v2" + // Fragment: "f" + if len(u.Path) == 0 || u.Path[len(u.Path)-1] != '/' { + u.Path += "/" // Append "/" to end before appending name + } + u.Path += name + return u +} + +// ListContainersFlatSegment returns a single segment of containers starting from the specified Marker. Use an empty +// Marker to start enumeration from the beginning. Container names are returned in lexicographic order. +// After getting a segment, process it, and then call ListContainersFlatSegment again (passing the the +// previously-returned Marker) to get the next segment. For more information, see +// https://docs.microsoft.com/rest/api/storageservices/list-containers2. +func (s ServiceURL) ListContainersSegment(ctx context.Context, marker Marker, o ListContainersSegmentOptions) (*ListContainersResponse, error) { + prefix, include, maxResults := o.pointers() + return s.client.ListContainersSegment(ctx, prefix, marker.val, maxResults, include, nil, nil) +} + +// ListContainersOptions defines options available when calling ListContainers. +type ListContainersSegmentOptions struct { + Detail ListContainersDetail // No IncludeType header is produced if "" + Prefix string // No Prefix header is produced if "" + MaxResults int32 // 0 means unspecified + // TODO: update swagger to generate this type? +} + +func (o *ListContainersSegmentOptions) pointers() (prefix *string, include ListContainersIncludeType, maxResults *int32) { + if o.Prefix != "" { + prefix = &o.Prefix + } + if o.MaxResults != 0 { + if o.MaxResults < 0 { + panic("MaxResults must be >= 0") + } + maxResults = &o.MaxResults + } + include = ListContainersIncludeType(o.Detail.string()) + return +} + +// ListContainersFlatDetail indicates what additional information the service should return with each container. +type ListContainersDetail struct { + // Tells the service whether to return metadata for each container. + Metadata bool +} + +// string produces the Include query parameter's value. +func (d *ListContainersDetail) string() string { + items := make([]string, 0, 1) + // NOTE: Multiple strings MUST be appended in alphabetic order or signing the string for authentication fails! + if d.Metadata { + items = append(items, string(ListContainersIncludeMetadata)) + } + if len(items) > 0 { + return strings.Join(items, ",") + } + return string(ListContainersIncludeNone) +} + +func (bsu ServiceURL) GetProperties(ctx context.Context) (*StorageServiceProperties, error) { + return bsu.client.GetProperties(ctx, nil, nil) +} + +func (bsu ServiceURL) SetProperties(ctx context.Context, properties StorageServiceProperties) (*ServiceSetPropertiesResponse, error) { + return bsu.client.SetProperties(ctx, properties, nil, nil) +} + +func (bsu ServiceURL) GetStatistics(ctx context.Context) (*StorageServiceStats, error) { + return bsu.client.GetStatistics(ctx, nil, nil) +} diff --git a/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/version.go b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/version.go new file mode 100644 index 0000000000..8a8926bd33 --- /dev/null +++ b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/version.go @@ -0,0 +1,3 @@ +package azblob + +const serviceLibVersion = "0.1" diff --git a/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zc_credential_anonymous.go b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zc_credential_anonymous.go new file mode 100644 index 0000000000..a81987d54a --- /dev/null +++ b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zc_credential_anonymous.go @@ -0,0 +1,55 @@ +package azblob + +import ( + "context" + + "github.com/Azure/azure-pipeline-go/pipeline" +) + +// Credential represent any credential type; it is used to create a credential policy Factory. +type Credential interface { + pipeline.Factory + credentialMarker() +} + +type credentialFunc pipeline.FactoryFunc + +func (f credentialFunc) New(next pipeline.Policy, po *pipeline.PolicyOptions) pipeline.Policy { + return f(next, po) +} + +// credentialMarker is a package-internal method that exists just to satisfy the Credential interface. +func (credentialFunc) credentialMarker() {} + +////////////////////////////// + +// NewAnonymousCredential creates an anonymous credential for use with HTTP(S) requests that read public resource +// or for use with Shared Access Signatures (SAS). +func NewAnonymousCredential() Credential { + return anonymousCredentialFactory +} + +var anonymousCredentialFactory Credential = &anonymousCredentialPolicyFactory{} // Singleton + +// anonymousCredentialPolicyFactory is the credential's policy factory. +type anonymousCredentialPolicyFactory struct { +} + +// New creates a credential policy object. +func (f *anonymousCredentialPolicyFactory) New(next pipeline.Policy, po *pipeline.PolicyOptions) pipeline.Policy { + return &anonymousCredentialPolicy{next: next} +} + +// credentialMarker is a package-internal method that exists just to satisfy the Credential interface. +func (*anonymousCredentialPolicyFactory) credentialMarker() {} + +// anonymousCredentialPolicy is the credential's policy object. +type anonymousCredentialPolicy struct { + next pipeline.Policy +} + +// Do implements the credential's policy interface. +func (p anonymousCredentialPolicy) Do(ctx context.Context, request pipeline.Request) (pipeline.Response, error) { + // For anonymous credentials, this is effectively a no-op + return p.next.Do(ctx, request) +} diff --git a/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zc_credential_shared_key.go b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zc_credential_shared_key.go new file mode 100644 index 0000000000..51da162779 --- /dev/null +++ b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zc_credential_shared_key.go @@ -0,0 +1,187 @@ +package azblob + +import ( + "bytes" + "context" + "crypto/hmac" + "crypto/sha256" + "encoding/base64" + "net/http" + "net/url" + "sort" + "strings" + "time" + + "github.com/Azure/azure-pipeline-go/pipeline" +) + +// NewSharedKeyCredential creates an immutable SharedKeyCredential containing the +// storage account's name and either its primary or secondary key. +func NewSharedKeyCredential(accountName, accountKey string) *SharedKeyCredential { + bytes, err := base64.StdEncoding.DecodeString(accountKey) + if err != nil { + panic(err) + } + return &SharedKeyCredential{accountName: accountName, accountKey: bytes} +} + +// SharedKeyCredential contains an account's name and its primary or secondary key. +// It is immutable making it shareable and goroutine-safe. +type SharedKeyCredential struct { + // Only the NewSharedKeyCredential method should set these; all other methods should treat them as read-only + accountName string + accountKey []byte +} + +// AccountName returns the Storage account's name. +func (f SharedKeyCredential) AccountName() string { + return f.accountName +} + +// New creates a credential policy object. +func (f *SharedKeyCredential) New(next pipeline.Policy, po *pipeline.PolicyOptions) pipeline.Policy { + return pipeline.PolicyFunc(func(ctx context.Context, request pipeline.Request) (pipeline.Response, error) { + // Add a x-ms-date header if it doesn't already exist + if d := request.Header.Get(headerXmsDate); d == "" { + request.Header[headerXmsDate] = []string{time.Now().UTC().Format(http.TimeFormat)} + } + stringToSign := f.buildStringToSign(request) + signature := f.ComputeHMACSHA256(stringToSign) + authHeader := strings.Join([]string{"SharedKey ", f.accountName, ":", signature}, "") + request.Header[headerAuthorization] = []string{authHeader} + + response, err := next.Do(ctx, request) + if err != nil && response != nil && response.Response() != nil && response.Response().StatusCode == http.StatusForbidden { + // Service failed to authenticate request, log it + po.Log(pipeline.LogError, "===== HTTP Forbidden status, String-to-Sign:\n"+stringToSign+"\n===============================\n") + } + return response, err + }) +} + +// credentialMarker is a package-internal method that exists just to satisfy the Credential interface. +func (*SharedKeyCredential) credentialMarker() {} + +// Constants ensuring that header names are correctly spelled and consistently cased. +const ( + headerAuthorization = "Authorization" + headerCacheControl = "Cache-Control" + headerContentEncoding = "Content-Encoding" + headerContentDisposition = "Content-Disposition" + headerContentLanguage = "Content-Language" + headerContentLength = "Content-Length" + headerContentMD5 = "Content-MD5" + headerContentType = "Content-Type" + headerDate = "Date" + headerIfMatch = "If-Match" + headerIfModifiedSince = "If-Modified-Since" + headerIfNoneMatch = "If-None-Match" + headerIfUnmodifiedSince = "If-Unmodified-Since" + headerRange = "Range" + headerUserAgent = "User-Agent" + headerXmsDate = "x-ms-date" + headerXmsVersion = "x-ms-version" +) + +// ComputeHMACSHA256 generates a hash signature for an HTTP request or for a SAS. +func (f *SharedKeyCredential) ComputeHMACSHA256(message string) (base64String string) { + h := hmac.New(sha256.New, f.accountKey) + h.Write([]byte(message)) + return base64.StdEncoding.EncodeToString(h.Sum(nil)) +} + +func (f *SharedKeyCredential) buildStringToSign(request pipeline.Request) string { + // https://docs.microsoft.com/en-us/rest/api/storageservices/authentication-for-the-azure-storage-services + headers := request.Header + contentLength := headers.Get(headerContentLength) + if contentLength == "0" { + contentLength = "" + } + + stringToSign := strings.Join([]string{ + request.Method, + headers.Get(headerContentEncoding), + headers.Get(headerContentLanguage), + contentLength, + headers.Get(headerContentMD5), + headers.Get(headerContentType), + "", // Empty date because x-ms-date is expected (as per web page above) + headers.Get(headerIfModifiedSince), + headers.Get(headerIfMatch), + headers.Get(headerIfNoneMatch), + headers.Get(headerIfUnmodifiedSince), + headers.Get(headerRange), + buildCanonicalizedHeader(headers), + f.buildCanonicalizedResource(request.URL), + }, "\n") + return stringToSign +} + +func buildCanonicalizedHeader(headers http.Header) string { + cm := map[string][]string{} + for k, v := range headers { + headerName := strings.TrimSpace(strings.ToLower(k)) + if strings.HasPrefix(headerName, "x-ms-") { + cm[headerName] = v // NOTE: the value must not have any whitespace around it. + } + } + if len(cm) == 0 { + return "" + } + + keys := make([]string, 0, len(cm)) + for key := range cm { + keys = append(keys, key) + } + sort.Strings(keys) + ch := bytes.NewBufferString("") + for i, key := range keys { + if i > 0 { + ch.WriteRune('\n') + } + ch.WriteString(key) + ch.WriteRune(':') + ch.WriteString(strings.Join(cm[key], ",")) + } + return string(ch.Bytes()) +} + +func (f *SharedKeyCredential) buildCanonicalizedResource(u *url.URL) string { + // https://docs.microsoft.com/en-us/rest/api/storageservices/authentication-for-the-azure-storage-services + cr := bytes.NewBufferString("/") + cr.WriteString(f.accountName) + + if len(u.Path) > 0 { + // Any portion of the CanonicalizedResource string that is derived from + // the resource's URI should be encoded exactly as it is in the URI. + // -- https://msdn.microsoft.com/en-gb/library/azure/dd179428.aspx + cr.WriteString(u.EscapedPath()) + } else { + // a slash is required to indicate the root path + cr.WriteString("/") + } + + // params is a map[string][]string; param name is key; params values is []string + params, err := url.ParseQuery(u.RawQuery) // Returns URL decoded values + if err != nil { + panic(err) + } + + if len(params) > 0 { // There is at least 1 query parameter + paramNames := []string{} // We use this to sort the parameter key names + for paramName := range params { + paramNames = append(paramNames, paramName) // paramNames must be lowercase + } + sort.Strings(paramNames) + + for _, paramName := range paramNames { + paramValues := params[paramName] + sort.Strings(paramValues) + + // Join the sorted key values separated by ',' + // Then prepend "keyName:"; then add this string to the buffer + cr.WriteString("\n" + paramName + ":" + strings.Join(paramValues, ",")) + } + } + return string(cr.Bytes()) +} diff --git a/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zc_credential_token.go b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zc_credential_token.go new file mode 100644 index 0000000000..d7f925d398 --- /dev/null +++ b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zc_credential_token.go @@ -0,0 +1,126 @@ +package azblob + +import ( + "context" + "sync/atomic" + + "runtime" + "sync" + "time" + + "github.com/Azure/azure-pipeline-go/pipeline" +) + +// TokenCredential represents a token credential (which is also a pipeline.Factory). +type TokenCredential interface { + Credential + Token() string + SetToken(newToken string) +} + +// NewTokenCredential creates a token credential for use with role-based access control (RBAC) access to Azure Storage +// resources. You initialize the TokenCredential with an initial token value. If you pass a non-nil value for +// tokenRefresher, then the function you pass will be called immediately (so it can refresh and change the +// TokenCredential's token value by calling SetToken; your tokenRefresher function must return a time.Duration +// indicating how long the TokenCredential object should wait before calling your tokenRefresher function again. +func NewTokenCredential(initialToken string, tokenRefresher func(credential TokenCredential) time.Duration) TokenCredential { + tc := &tokenCredential{} + tc.SetToken(initialToken) // We dont' set it above to guarantee atomicity + if tokenRefresher == nil { + return tc // If no callback specified, return the simple tokenCredential + } + + tcwr := &tokenCredentialWithRefresh{token: tc} + tcwr.token.startRefresh(tokenRefresher) + runtime.SetFinalizer(tcwr, func(deadTC *tokenCredentialWithRefresh) { + deadTC.token.stopRefresh() + deadTC.token = nil // Sanity (not really required) + }) + return tcwr +} + +// tokenCredentialWithRefresh is a wrapper over a token credential. +// When this wrapper object gets GC'd, it stops the tokenCredential's timer +// which allows the tokenCredential object to also be GC'd. +type tokenCredentialWithRefresh struct { + token *tokenCredential +} + +// credentialMarker is a package-internal method that exists just to satisfy the Credential interface. +func (*tokenCredentialWithRefresh) credentialMarker() {} + +// Token returns the current token value +func (f *tokenCredentialWithRefresh) Token() string { return f.token.Token() } + +// SetToken changes the current token value +func (f *tokenCredentialWithRefresh) SetToken(token string) { f.token.SetToken(token) } + +// New satisfies pipeline.Factory's New method creating a pipeline policy object. +func (f *tokenCredentialWithRefresh) New(next pipeline.Policy, po *pipeline.PolicyOptions) pipeline.Policy { + return f.token.New(next, po) +} + +/////////////////////////////////////////////////////////////////////////////// + +// tokenCredential is a pipeline.Factory is the credential's policy factory. +type tokenCredential struct { + token atomic.Value + + // The members below are only used if the user specified a tokenRefresher callback function. + timer *time.Timer + tokenRefresher func(c TokenCredential) time.Duration + lock sync.Mutex + stopped bool +} + +// credentialMarker is a package-internal method that exists just to satisfy the Credential interface. +func (*tokenCredential) credentialMarker() {} + +// Token returns the current token value +func (f *tokenCredential) Token() string { return f.token.Load().(string) } + +// SetToken changes the current token value +func (f *tokenCredential) SetToken(token string) { f.token.Store(token) } + +// startRefresh calls refresh which immediately calls tokenRefresher +// and then starts a timer to call tokenRefresher in the future. +func (f *tokenCredential) startRefresh(tokenRefresher func(c TokenCredential) time.Duration) { + f.tokenRefresher = tokenRefresher + f.stopped = false // In case user calls StartRefresh, StopRefresh, & then StartRefresh again + f.refresh() +} + +// refresh calls the user's tokenRefresher so they can refresh the token (by +// calling SetToken) and then starts another time (based on the returned duration) +// in order to refresh the token again in the future. +func (f *tokenCredential) refresh() { + d := f.tokenRefresher(f) // Invoke the user's refresh callback outside of the lock + f.lock.Lock() + if !f.stopped { + f.timer = time.AfterFunc(d, f.refresh) + } + f.lock.Unlock() +} + +// stopRefresh stops any pending timer and sets stopped field to true to prevent +// any new timer from starting. +// NOTE: Stopping the timer allows the GC to destroy the tokenCredential object. +func (f *tokenCredential) stopRefresh() { + f.lock.Lock() + f.stopped = true + if f.timer != nil { + f.timer.Stop() + } + f.lock.Unlock() +} + +// New satisfies pipeline.Factory's New method creating a pipeline policy object. +func (f *tokenCredential) New(next pipeline.Policy, po *pipeline.PolicyOptions) pipeline.Policy { + return pipeline.PolicyFunc(func(ctx context.Context, request pipeline.Request) (pipeline.Response, error) { + if request.URL.Scheme != "https" { + panic("Token credentials require a URL using the https protocol scheme.") + } + request.Header[headerAuthorization] = []string{"Bearer " + f.Token()} + return next.Do(ctx, request) + }) +} diff --git a/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zc_mmf_unix.go b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zc_mmf_unix.go new file mode 100644 index 0000000000..b6c668ac64 --- /dev/null +++ b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zc_mmf_unix.go @@ -0,0 +1,27 @@ +// +build linux darwin freebsd + +package azblob + +import ( + "os" + "syscall" +) + +type mmf []byte + +func newMMF(file *os.File, writable bool, offset int64, length int) (mmf, error) { + prot, flags := syscall.PROT_READ, syscall.MAP_SHARED // Assume read-only + if writable { + prot, flags = syscall.PROT_READ|syscall.PROT_WRITE, syscall.MAP_SHARED + } + addr, err := syscall.Mmap(int(file.Fd()), offset, length, prot, flags) + return mmf(addr), err +} + +func (m *mmf) unmap() { + err := syscall.Munmap(*m) + *m = nil + if err != nil { + panic(err) + } +} diff --git a/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zc_mmf_windows.go b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zc_mmf_windows.go new file mode 100644 index 0000000000..1a6e83dad9 --- /dev/null +++ b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zc_mmf_windows.go @@ -0,0 +1,38 @@ +package azblob + +import ( + "os" + "reflect" + "syscall" + "unsafe" +) + +type mmf []byte + +func newMMF(file *os.File, writable bool, offset int64, length int) (mmf, error) { + prot, access := uint32(syscall.PAGE_READONLY), uint32(syscall.FILE_MAP_READ) // Assume read-only + if writable { + prot, access = uint32(syscall.PAGE_READWRITE), uint32(syscall.FILE_MAP_WRITE) + } + hMMF, errno := syscall.CreateFileMapping(syscall.Handle(file.Fd()), nil, prot, uint32(int64(length)>>32), uint32(int64(length)&0xffffffff), nil) + if hMMF == 0 { + return nil, os.NewSyscallError("CreateFileMapping", errno) + } + defer syscall.CloseHandle(hMMF) + addr, errno := syscall.MapViewOfFile(hMMF, access, uint32(offset>>32), uint32(offset&0xffffffff), uintptr(length)) + m := mmf{} + h := (*reflect.SliceHeader)(unsafe.Pointer(&m)) + h.Data = addr + h.Len = length + h.Cap = h.Len + return m, nil +} + +func (m *mmf) unmap() { + addr := uintptr(unsafe.Pointer(&(([]byte)(*m)[0]))) + *m = mmf{} + err := syscall.UnmapViewOfFile(addr) + if err != nil { + panic(err) + } +} diff --git a/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zc_pipeline.go b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zc_pipeline.go new file mode 100644 index 0000000000..af5fcd6c7f --- /dev/null +++ b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zc_pipeline.go @@ -0,0 +1,46 @@ +package azblob + +import ( + "github.com/Azure/azure-pipeline-go/pipeline" +) + +// PipelineOptions is used to configure a request policy pipeline's retry policy and logging. +type PipelineOptions struct { + // Log configures the pipeline's logging infrastructure indicating what information is logged and where. + Log pipeline.LogOptions + + // Retry configures the built-in retry policy behavior. + Retry RetryOptions + + // RequestLog configures the built-in request logging policy. + RequestLog RequestLogOptions + + // Telemetry configures the built-in telemetry policy behavior. + Telemetry TelemetryOptions +} + +// NewPipeline creates a Pipeline using the specified credentials and options. +func NewPipeline(c Credential, o PipelineOptions) pipeline.Pipeline { + if c == nil { + panic("c can't be nil") + } + + // Closest to API goes first; closest to the wire goes last + f := []pipeline.Factory{ + NewTelemetryPolicyFactory(o.Telemetry), + NewUniqueRequestIDPolicyFactory(), + NewRetryPolicyFactory(o.Retry), + } + + if _, ok := c.(*anonymousCredentialPolicyFactory); !ok { + // For AnonymousCredential, we optimize out the policy factory since it doesn't do anything + // NOTE: The credential's policy factory must appear close to the wire so it can sign any + // changes made by other factories (like UniqueRequestIDPolicyFactory) + f = append(f, c) + } + f = append(f, + pipeline.MethodFactoryMarker(), // indicates at what stage in the pipeline the method factory is invoked + NewRequestLogPolicyFactory(o.RequestLog)) + + return pipeline.NewPipeline(f, pipeline.Options{HTTPSender: nil, Log: o.Log}) +} diff --git a/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zc_policy_request_log.go b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zc_policy_request_log.go new file mode 100644 index 0000000000..23d559eb7c --- /dev/null +++ b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zc_policy_request_log.go @@ -0,0 +1,150 @@ +package azblob + +import ( + "bytes" + "context" + "fmt" + "net/http" + "net/url" + "runtime" + "strings" + "time" + + "github.com/Azure/azure-pipeline-go/pipeline" +) + +// RequestLogOptions configures the retry policy's behavior. +type RequestLogOptions struct { + // LogWarningIfTryOverThreshold logs a warning if a tried operation takes longer than the specified + // duration (-1=no logging; 0=default threshold). + LogWarningIfTryOverThreshold time.Duration +} + +func (o RequestLogOptions) defaults() RequestLogOptions { + if o.LogWarningIfTryOverThreshold == 0 { + // It would be good to relate this to https://azure.microsoft.com/en-us/support/legal/sla/storage/v1_2/ + // But this monitors the time to get the HTTP response; NOT the time to download the response body. + o.LogWarningIfTryOverThreshold = 3 * time.Second // Default to 3 seconds + } + return o +} + +// NewRequestLogPolicyFactory creates a RequestLogPolicyFactory object configured using the specified options. +func NewRequestLogPolicyFactory(o RequestLogOptions) pipeline.Factory { + o = o.defaults() // Force defaults to be calculated + return pipeline.FactoryFunc(func(next pipeline.Policy, po *pipeline.PolicyOptions) pipeline.PolicyFunc { + // These variables are per-policy; shared by multiple calls to Do + var try int32 + operationStart := time.Now() // If this is the 1st try, record the operation state time + return func(ctx context.Context, request pipeline.Request) (response pipeline.Response, err error) { + try++ // The first try is #1 (not #0) + + // Log the outgoing request as informational + if po.ShouldLog(pipeline.LogInfo) { + b := &bytes.Buffer{} + fmt.Fprintf(b, "==> OUTGOING REQUEST (Try=%d)\n", try) + pipeline.WriteRequestWithResponse(b, prepareRequestForLogging(request), nil, nil) + po.Log(pipeline.LogInfo, b.String()) + } + + // Set the time for this particular retry operation and then Do the operation. + tryStart := time.Now() + response, err = next.Do(ctx, request) // Make the request + tryEnd := time.Now() + tryDuration := tryEnd.Sub(tryStart) + opDuration := tryEnd.Sub(operationStart) + + logLevel, forceLog := pipeline.LogInfo, false // Default logging information + + // If the response took too long, we'll upgrade to warning. + if o.LogWarningIfTryOverThreshold > 0 && tryDuration > o.LogWarningIfTryOverThreshold { + // Log a warning if the try duration exceeded the specified threshold + logLevel, forceLog = pipeline.LogWarning, true + } + + if err == nil { // We got a response from the service + sc := response.Response().StatusCode + if ((sc >= 400 && sc <= 499) && sc != http.StatusNotFound && sc != http.StatusConflict && sc != http.StatusPreconditionFailed && sc != http.StatusRequestedRangeNotSatisfiable) || (sc >= 500 && sc <= 599) { + logLevel, forceLog = pipeline.LogError, true // Promote to Error any 4xx (except those listed is an error) or any 5xx + } else { + // For other status codes, we leave the level as is. + } + } else { // This error did not get an HTTP response from the service; upgrade the severity to Error + logLevel, forceLog = pipeline.LogError, true + } + + if shouldLog := po.ShouldLog(logLevel); forceLog || shouldLog { + // We're going to log this; build the string to log + b := &bytes.Buffer{} + slow := "" + if o.LogWarningIfTryOverThreshold > 0 && tryDuration > o.LogWarningIfTryOverThreshold { + slow = fmt.Sprintf("[SLOW >%v]", o.LogWarningIfTryOverThreshold) + } + fmt.Fprintf(b, "==> REQUEST/RESPONSE (Try=%d/%v%s, OpTime=%v) -- ", try, tryDuration, slow, opDuration) + if err != nil { // This HTTP request did not get a response from the service + fmt.Fprint(b, "REQUEST ERROR\n") + } else { + if logLevel == pipeline.LogError { + fmt.Fprint(b, "RESPONSE STATUS CODE ERROR\n") + } else { + fmt.Fprint(b, "RESPONSE SUCCESSFULLY RECEIVED\n") + } + } + + pipeline.WriteRequestWithResponse(b, prepareRequestForLogging(request), response.Response(), err) + if logLevel <= pipeline.LogError { + b.Write(stack()) // For errors (or lower levels), we append the stack trace (an expensive operation) + } + msg := b.String() + + if forceLog { + pipeline.ForceLog(logLevel, msg) + } + if shouldLog { + po.Log(logLevel, msg) + } + } + return response, err + } + }) +} + +func redactSigQueryParam(rawQuery string) (bool, string) { + rawQuery = strings.ToLower(rawQuery) // lowercase the string so we can look for ?sig= and &sig= + sigFound := strings.Contains(rawQuery, "?sig=") + if !sigFound { + sigFound = strings.Contains(rawQuery, "&sig=") + if !sigFound { + return sigFound, rawQuery // [?|&]sig= not found; return same rawQuery passed in (no memory allocation) + } + } + // [?|&]sig= found, redact its value + values, _ := url.ParseQuery(rawQuery) + for name := range values { + if strings.EqualFold(name, "sig") { + values[name] = []string{"REDACTED"} + } + } + return sigFound, values.Encode() +} + +func prepareRequestForLogging(request pipeline.Request) *http.Request { + req := request + if sigFound, rawQuery := redactSigQueryParam(req.URL.RawQuery); sigFound { + // Make copy so we don't destroy the query parameters we actually need to send in the request + req = request.Copy() + req.Request.URL.RawQuery = rawQuery + } + return req.Request +} + +func stack() []byte { + buf := make([]byte, 1024) + for { + n := runtime.Stack(buf, false) + if n < len(buf) { + return buf[:n] + } + buf = make([]byte, 2*len(buf)) + } +} diff --git a/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zc_policy_retry.go b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zc_policy_retry.go new file mode 100644 index 0000000000..4c885ea1aa --- /dev/null +++ b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zc_policy_retry.go @@ -0,0 +1,318 @@ +package azblob + +import ( + "context" + "math/rand" + "net" + "net/http" + "strconv" + "time" + + "github.com/Azure/azure-pipeline-go/pipeline" + "io/ioutil" + "io" +) + +// RetryPolicy tells the pipeline what kind of retry policy to use. See the RetryPolicy* constants. +type RetryPolicy int32 + +const ( + // RetryPolicyExponential tells the pipeline to use an exponential back-off retry policy + RetryPolicyExponential RetryPolicy = 0 + + // RetryPolicyFixed tells the pipeline to use a fixed back-off retry policy + RetryPolicyFixed RetryPolicy = 1 +) + +// RetryOptions configures the retry policy's behavior. +type RetryOptions struct { + // Policy tells the pipeline what kind of retry policy to use. See the RetryPolicy* constants.\ + // A value of zero means that you accept our default policy. + Policy RetryPolicy + + // MaxTries specifies the maximum number of attempts an operation will be tried before producing an error (0=default). + // A value of zero means that you accept our default policy. A value of 1 means 1 try and no retries. + MaxTries int32 + + // TryTimeout indicates the maximum time allowed for any single try of an HTTP request. + // A value of zero means that you accept our default timeout. NOTE: When transferring large amounts + // of data, the default TryTimeout will probably not be sufficient. You should override this value + // based on the bandwidth available to the host machine and proximity to the Storage service. A good + // starting point may be something like (60 seconds per MB of anticipated-payload-size). + TryTimeout time.Duration + + // RetryDelay specifies the amount of delay to use before retrying an operation (0=default). + // When RetryPolicy is specified as RetryPolicyExponential, the delay increases exponentially + // with each retry up to a maximum specified by MaxRetryDelay. + // If you specify 0, then you must also specify 0 for MaxRetryDelay. + // If you specify RetryDelay, then you must also specify MaxRetryDelay, and MaxRetryDelay should be + // equal to or greater than RetryDelay. + RetryDelay time.Duration + + // MaxRetryDelay specifies the maximum delay allowed before retrying an operation (0=default). + // If you specify 0, then you must also specify 0 for RetryDelay. + MaxRetryDelay time.Duration + + // RetryReadsFromSecondaryHost specifies whether the retry policy should retry a read operation against another host. + // If RetryReadsFromSecondaryHost is "" (the default) then operations are not retried against another host. + // NOTE: Before setting this field, make sure you understand the issues around reading stale & potentially-inconsistent + // data at this webpage: https://docs.microsoft.com/en-us/azure/storage/common/storage-designing-ha-apps-with-ragrs + RetryReadsFromSecondaryHost string // Comment this our for non-Blob SDKs +} + +func (o RetryOptions) retryReadsFromSecondaryHost() string { + return o.RetryReadsFromSecondaryHost // This is for the Blob SDK only + //return "" // This is for non-blob SDKs +} + +func (o RetryOptions) defaults() RetryOptions { + if o.Policy != RetryPolicyExponential && o.Policy != RetryPolicyFixed { + panic("RetryPolicy must be RetryPolicyExponential or RetryPolicyFixed") + } + if o.MaxTries < 0 { + panic("MaxTries must be >= 0") + } + if o.TryTimeout < 0 || o.RetryDelay < 0 || o.MaxRetryDelay < 0 { + panic("TryTimeout, RetryDelay, and MaxRetryDelay must all be >= 0") + } + if o.RetryDelay > o.MaxRetryDelay { + panic("RetryDelay must be <= MaxRetryDelay") + } + if (o.RetryDelay == 0 && o.MaxRetryDelay != 0) || (o.RetryDelay != 0 && o.MaxRetryDelay == 0) { + panic("Both RetryDelay and MaxRetryDelay must be 0 or neither can be 0") + } + + IfDefault := func(current *time.Duration, desired time.Duration) { + if *current == time.Duration(0) { + *current = desired + } + } + + // Set defaults if unspecified + if o.MaxTries == 0 { + o.MaxTries = 4 + } + switch o.Policy { + case RetryPolicyExponential: + IfDefault(&o.TryTimeout, 1*time.Minute) + IfDefault(&o.RetryDelay, 4*time.Second) + IfDefault(&o.MaxRetryDelay, 120*time.Second) + + case RetryPolicyFixed: + IfDefault(&o.TryTimeout, 1*time.Minute) + IfDefault(&o.RetryDelay, 30*time.Second) + IfDefault(&o.MaxRetryDelay, 120*time.Second) + } + return o +} + +func (o RetryOptions) calcDelay(try int32) time.Duration { // try is >=1; never 0 + pow := func(number int64, exponent int32) int64 { // pow is nested helper function + var result int64 = 1 + for n := int32(0); n < exponent; n++ { + result *= number + } + return result + } + + delay := time.Duration(0) + switch o.Policy { + case RetryPolicyExponential: + delay = time.Duration(pow(2, try-1)-1) * o.RetryDelay + + case RetryPolicyFixed: + if try > 1 { // Any try after the 1st uses the fixed delay + delay = o.RetryDelay + } + } + + // Introduce some jitter: [0.0, 1.0) / 2 = [0.0, 0.5) + 0.8 = [0.8, 1.3) + delay = time.Duration(delay.Seconds() * (rand.Float64()/2 + 0.8) * float64(time.Second)) // NOTE: We want math/rand; not crypto/rand + if delay > o.MaxRetryDelay { + delay = o.MaxRetryDelay + } + return delay +} + +// NewRetryPolicyFactory creates a RetryPolicyFactory object configured using the specified options. +func NewRetryPolicyFactory(o RetryOptions) pipeline.Factory { + o = o.defaults() // Force defaults to be calculated + return pipeline.FactoryFunc(func(next pipeline.Policy, po *pipeline.PolicyOptions) pipeline.PolicyFunc { + return func(ctx context.Context, request pipeline.Request) (response pipeline.Response, err error) { + // Before each try, we'll select either the primary or secondary URL. + primaryTry := int32(0) // This indicates how many tries we've attempted against the primary DC + + // We only consider retrying against a secondary if we have a read request (GET/HEAD) AND this policy has a Secondary URL it can use + considerSecondary := (request.Method == http.MethodGet || request.Method == http.MethodHead) && o.retryReadsFromSecondaryHost() != "" + + // Exponential retry algorithm: ((2 ^ attempt) - 1) * delay * random(0.8, 1.2) + // When to retry: connection failure or temporary/timeout. NOTE: StorageError considers HTTP 500/503 as temporary & is therefore retryable + // If using a secondary: + // Even tries go against primary; odd tries go against the secondary + // For a primary wait ((2 ^ primaryTries - 1) * delay * random(0.8, 1.2) + // If secondary gets a 404, don't fail, retry but future retries are only against the primary + // When retrying against a secondary, ignore the retry count and wait (.1 second * random(0.8, 1.2)) + for try := int32(1); try <= o.MaxTries; try++ { + logf("\n=====> Try=%d\n", try) + + // Determine which endpoint to try. It's primary if there is no secondary or if it is an add # attempt. + tryingPrimary := !considerSecondary || (try%2 == 1) + // Select the correct host and delay + if tryingPrimary { + primaryTry++ + delay := o.calcDelay(primaryTry) + logf("Primary try=%d, Delay=%v\n", primaryTry, delay) + time.Sleep(delay) // The 1st try returns 0 delay + } else { + delay := time.Second * time.Duration(rand.Float32()/2+0.8) + logf("Secondary try=%d, Delay=%v\n", try-primaryTry, delay) + time.Sleep(delay) // Delay with some jitter before trying secondary + } + + // Clone the original request to ensure that each try starts with the original (unmutated) request. + requestCopy := request.Copy() + + // For each try, seek to the beginning of the Body stream. We do this even for the 1st try because + // the stream may not be at offset 0 when we first get it and we want the same behavior for the + // 1st try as for additional tries. + if err = requestCopy.RewindBody(); err != nil { + panic(err) + } + if !tryingPrimary { + requestCopy.Request.URL.Host = o.retryReadsFromSecondaryHost() + } + + // Set the server-side timeout query parameter "timeout=[seconds]" + timeout := int32(o.TryTimeout.Seconds()) // Max seconds per try + if deadline, ok := ctx.Deadline(); ok { // If user's ctx has a deadline, make the timeout the smaller of the two + t := int32(deadline.Sub(time.Now()).Seconds()) // Duration from now until user's ctx reaches its deadline + logf("MaxTryTimeout=%d secs, TimeTilDeadline=%d sec\n", timeout, t) + if t < timeout { + timeout = t + } + if timeout < 0 { + timeout = 0 // If timeout ever goes negative, set it to zero; this happen while debugging + } + logf("TryTimeout adjusted to=%d sec\n", timeout) + } + q := requestCopy.Request.URL.Query() + q.Set("timeout", strconv.Itoa(int(timeout+1))) // Add 1 to "round up" + requestCopy.Request.URL.RawQuery = q.Encode() + logf("Url=%s\n", requestCopy.Request.URL.String()) + + // Set the time for this particular retry operation and then Do the operation. + tryCtx, tryCancel := context.WithTimeout(ctx, time.Second*time.Duration(timeout)) + //requestCopy.Body = &deadlineExceededReadCloser{r: requestCopy.Request.Body} + response, err = next.Do(tryCtx, requestCopy) // Make the request + /*err = improveDeadlineExceeded(err) + if err == nil { + response.Response().Body = &deadlineExceededReadCloser{r: response.Response().Body} + }*/ + logf("Err=%v, response=%v\n", err, response) + + action := "" // This MUST get changed within the switch code below + switch { + case ctx.Err() != nil: + action = "NoRetry: Op timeout" + case !tryingPrimary && response != nil && response.Response().StatusCode == http.StatusNotFound: + // If attempt was against the secondary & it returned a StatusNotFound (404), then + // the resource was not found. This may be due to replication delay. So, in this + // case, we'll never try the secondary again for this operation. + considerSecondary = false + action = "Retry: Secondary URL returned 404" + case err != nil: + // NOTE: Protocol Responder returns non-nil if REST API returns invalid status code for the invoked operation + if netErr, ok := err.(net.Error); ok && (netErr.Temporary() || netErr.Timeout()) { + action = "Retry: net.Error and Temporary() or Timeout()" + } else { + action = "NoRetry: unrecognized error" + } + default: + action = "NoRetry: successful HTTP request" // no error + } + + logf("Action=%s\n", action) + // fmt.Println(action + "\n") // This is where we could log the retry operation; action is why we're retrying + if action[0] != 'R' { // Retry only if action starts with 'R' + if err != nil { + tryCancel() // If we're returning an error, cancel this current/last per-retry timeout context + } else { + // TODO: Right now, we've decided to leak the per-try Context until the user's Context is canceled. + // Another option is that we wrap the last per-try context in a body and overwrite the Response's Body field with our wrapper. + // So, when the user closes the Body, the our per-try context gets closed too. + // Another option, is that the Last Policy do this wrapping for a per-retry context (not for the user's context) + _ = tryCancel // So, for now, we don't call cancel: cancel() + } + break // Don't retry + } + if response != nil && response.Response() != nil && response.Response().Body != nil { + // If we're going to retry and we got a previous response, then flush its body to avoid leaking its TCP connection + body := response.Response().Body + io.Copy(ioutil.Discard, body) + body.Close() + } + // If retrying, cancel the current per-try timeout context + tryCancel() + } + return response, err // Not retryable or too many retries; return the last response/error + } + }) +} + +// According to https://github.com/golang/go/wiki/CompilerOptimizations, the compiler will inline this method and hopefully optimize all calls to it away +var logf = func(format string, a ...interface{}) {} + +// Use this version to see the retry method's code path (import "fmt") +//var logf = fmt.Printf + +/* +type deadlineExceededReadCloser struct { + r io.ReadCloser +} + +func (r *deadlineExceededReadCloser) Read(p []byte) (int, error) { + n, err := 0, io.EOF + if r.r != nil { + n, err = r.r.Read(p) + } + return n, improveDeadlineExceeded(err) +} +func (r *deadlineExceededReadCloser) Seek(offset int64, whence int) (int64, error) { + // For an HTTP request, the ReadCloser MUST also implement seek + // For an HTTP response, Seek MUST not be called (or this will panic) + o, err := r.r.(io.Seeker).Seek(offset, whence) + return o, improveDeadlineExceeded(err) +} +func (r *deadlineExceededReadCloser) Close() error { + if c, ok := r.r.(io.Closer); ok { + c.Close() + } + return nil +} + +// timeoutError is the internal struct that implements our richer timeout error. +type deadlineExceeded struct { + responseError +} + +var _ net.Error = (*deadlineExceeded)(nil) // Ensure deadlineExceeded implements the net.Error interface at compile time + +// improveDeadlineExceeded creates a timeoutError object that implements the error interface IF cause is a context.DeadlineExceeded error. +func improveDeadlineExceeded(cause error) error { + // If cause is not DeadlineExceeded, return the same error passed in. + if cause != context.DeadlineExceeded { + return cause + } + // Else, convert DeadlineExceeded to our timeoutError which gives a richer string message + return &deadlineExceeded{ + responseError: responseError{ + ErrorNode: pipeline.ErrorNode{}.Initialize(cause, 3), + }, + } +} + +// Error implements the error interface's Error method to return a string representation of the error. +func (e *deadlineExceeded) Error() string { + return e.ErrorNode.Error("context deadline exceeded; when creating a pipeline, consider increasing RetryOptions' TryTimeout field") +} +*/ diff --git a/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zc_policy_telemetry.go b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zc_policy_telemetry.go new file mode 100644 index 0000000000..608e1051ca --- /dev/null +++ b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zc_policy_telemetry.go @@ -0,0 +1,51 @@ +package azblob + +import ( + "bytes" + "context" + "fmt" + "os" + "runtime" + + "github.com/Azure/azure-pipeline-go/pipeline" +) + +// TelemetryOptions configures the telemetry policy's behavior. +type TelemetryOptions struct { + // Value is a string prepended to each request's User-Agent and sent to the service. + // The service records the user-agent in logs for diagnostics and tracking of client requests. + Value string +} + +// NewTelemetryPolicyFactory creates a factory that can create telemetry policy objects +// which add telemetry information to outgoing HTTP requests. +func NewTelemetryPolicyFactory(o TelemetryOptions) pipeline.Factory { + b := &bytes.Buffer{} + b.WriteString(o.Value) + if b.Len() > 0 { + b.WriteRune(' ') + } + fmt.Fprintf(b, "Azure-Storage/%s %s", serviceLibVersion, platformInfo) + telemetryValue := b.String() + + return pipeline.FactoryFunc(func(next pipeline.Policy, po *pipeline.PolicyOptions) pipeline.PolicyFunc { + return func(ctx context.Context, request pipeline.Request) (pipeline.Response, error) { + request.Header.Set("User-Agent", telemetryValue) + return next.Do(ctx, request) + } + }) +} + +// NOTE: the ONLY function that should write to this variable is this func +var platformInfo = func() string { + // Azure-Storage/version (runtime; os type and version)” + // Azure-Storage/1.4.0 (NODE-VERSION v4.5.0; Windows_NT 10.0.14393)' + operatingSystem := runtime.GOOS // Default OS string + switch operatingSystem { + case "windows": + operatingSystem = os.Getenv("OS") // Get more specific OS information + case "linux": // accept default OS info + case "freebsd": // accept default OS info + } + return fmt.Sprintf("(%s; %s)", runtime.Version(), operatingSystem) +}() diff --git a/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zc_policy_unique_request_id.go b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zc_policy_unique_request_id.go new file mode 100644 index 0000000000..a75c7d1d2e --- /dev/null +++ b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zc_policy_unique_request_id.go @@ -0,0 +1,24 @@ +package azblob + +import ( + "context" + + "github.com/Azure/azure-pipeline-go/pipeline" +) + +// NewUniqueRequestIDPolicyFactory creates a UniqueRequestIDPolicyFactory object +// that sets the request's x-ms-client-request-id header if it doesn't already exist. +func NewUniqueRequestIDPolicyFactory() pipeline.Factory { + return pipeline.FactoryFunc(func(next pipeline.Policy, po *pipeline.PolicyOptions) pipeline.PolicyFunc { + // This is Policy's Do method: + return func(ctx context.Context, request pipeline.Request) (pipeline.Response, error) { + id := request.Header.Get(xMsClientRequestID) + if id == "" { // Add a unique request ID if the caller didn't specify one already + request.Header.Set(xMsClientRequestID, newUUID().String()) + } + return next.Do(ctx, request) + } + }) +} + +const xMsClientRequestID = "x-ms-client-request-id" diff --git a/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zc_retry_reader.go b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zc_retry_reader.go new file mode 100644 index 0000000000..42724efa52 --- /dev/null +++ b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zc_retry_reader.go @@ -0,0 +1,122 @@ +package azblob + +import ( + "context" + "io" + "net" + "net/http" +) + +const CountToEnd = 0 + +// HTTPGetter is a function type that refers to a method that performs an HTTP GET operation. +type HTTPGetter func(ctx context.Context, i HTTPGetterInfo) (*http.Response, error) + +// HTTPGetterInfo is passed to an HTTPGetter function passing it parameters +// that should be used to make an HTTP GET request. +type HTTPGetterInfo struct { + // Offset specifies the start offset that should be used when + // creating the HTTP GET request's Range header + Offset int64 + + // Count specifies the count of bytes that should be used to calculate + // the end offset when creating the HTTP GET request's Range header + Count int64 + + // ETag specifies the resource's etag that should be used when creating + // the HTTP GET request's If-Match header + ETag ETag +} + +// RetryReaderOptions contains properties which can help to decide when to do retry. +type RetryReaderOptions struct { + // MaxRetryRequests specifies the maximum number of HTTP GET requests that will be made + // while reading from a RetryReader. A value of zero means that no additional HTTP + // GET requests will be made. + MaxRetryRequests int + doInjectError bool + doInjectErrorRound int +} + +// retryReader implements io.ReaderCloser methods. +// retryReader tries to read from response, and if there is retriable network error +// returned during reading, it will retry according to retry reader option through executing +// user defined action with provided data to get a new response, and continue the overall reading process +// through reading from the new response. +type retryReader struct { + ctx context.Context + response *http.Response + info HTTPGetterInfo + countWasBounded bool + o RetryReaderOptions + getter HTTPGetter +} + +// NewRetryReader creates a retry reader. +func NewRetryReader(ctx context.Context, initialResponse *http.Response, + info HTTPGetterInfo, o RetryReaderOptions, getter HTTPGetter) io.ReadCloser { + if getter == nil { + panic("getter must not be nil") + } + if info.Count < 0 { + panic("info.Count must be >= 0") + } + if o.MaxRetryRequests < 0 { + panic("o.MaxRetryRequests must be >= 0") + } + return &retryReader{ctx: ctx, getter: getter, info: info, countWasBounded: info.Count != CountToEnd, response: initialResponse, o: o} +} + +func (s *retryReader) Read(p []byte) (n int, err error) { + for try := 0; ; try++ { + //fmt.Println(try) // Comment out for debugging. + if s.countWasBounded && s.info.Count == CountToEnd { + // User specified an original count and the remaining bytes are 0, return 0, EOF + return 0, io.EOF + } + + if s.response == nil { // We don't have a response stream to read from, try to get one. + response, err := s.getter(s.ctx, s.info) + if err != nil { + return 0, err + } + // Successful GET; this is the network stream we'll read from. + s.response = response + } + n, err := s.response.Body.Read(p) // Read from the stream + + // Injection mechanism for testing. + if s.o.doInjectError && try == s.o.doInjectErrorRound { + err = &net.DNSError{IsTemporary: true} + } + + // We successfully read data or end EOF. + if err == nil || err == io.EOF { + s.info.Offset += int64(n) // Increments the start offset in case we need to make a new HTTP request in the future + if s.info.Count != CountToEnd { + s.info.Count -= int64(n) // Decrement the count in case we need to make a new HTTP request in the future + } + return n, err // Return the return to the caller + } + s.Close() // Error, close stream + s.response = nil // Our stream is no longer good + + // Check the retry count and error code, and decide whether to retry. + if try >= s.o.MaxRetryRequests { + return n, err // All retries exhausted + } + + if netErr, ok := err.(net.Error); ok && (netErr.Timeout() || netErr.Temporary()) { + continue + // Loop around and try to get and read from new stream. + } + return n, err // Not retryable, just return + } +} + +func (s *retryReader) Close() error { + if s.response != nil && s.response.Body != nil { + return s.response.Body.Close() + } + return nil +} diff --git a/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zc_sas_account.go b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zc_sas_account.go new file mode 100644 index 0000000000..8b51193f6a --- /dev/null +++ b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zc_sas_account.go @@ -0,0 +1,217 @@ +package azblob + +import ( + "bytes" + "fmt" + "strings" + "time" +) + +// AccountSASSignatureValues is used to generate a Shared Access Signature (SAS) for an Azure Storage account. +// For more information, see https://docs.microsoft.com/rest/api/storageservices/constructing-an-account-sas +type AccountSASSignatureValues struct { + Version string `param:"sv"` // If not specified, this defaults to SASVersion + Protocol SASProtocol `param:"spr"` // See the SASProtocol* constants + StartTime time.Time `param:"st"` // Not specified if IsZero + ExpiryTime time.Time `param:"se"` // Not specified if IsZero + Permissions string `param:"sp"` // Create by initializing a AccountSASPermissions and then call String() + IPRange IPRange `param:"sip"` + Services string `param:"ss"` // Create by initializing AccountSASServices and then call String() + ResourceTypes string `param:"srt"` // Create by initializing AccountSASResourceTypes and then call String() +} + +// NewSASQueryParameters uses an account's shared key credential to sign this signature values to produce +// the proper SAS query parameters. +func (v AccountSASSignatureValues) NewSASQueryParameters(sharedKeyCredential *SharedKeyCredential) SASQueryParameters { + // https://docs.microsoft.com/en-us/rest/api/storageservices/Constructing-an-Account-SAS + if v.ExpiryTime.IsZero() || v.Permissions == "" || v.ResourceTypes == "" || v.Services == "" { + panic("Account SAS is missing at least one of these: ExpiryTime, Permissions, Service, or ResourceType") + } + if v.Version == "" { + v.Version = SASVersion + } + perms := &AccountSASPermissions{} + if err := perms.Parse(v.Permissions); err != nil { + panic(err) + } + v.Permissions = perms.String() + + startTime, expiryTime := FormatTimesForSASSigning(v.StartTime, v.ExpiryTime) + + stringToSign := strings.Join([]string{ + sharedKeyCredential.AccountName(), + v.Permissions, + v.Services, + v.ResourceTypes, + startTime, + expiryTime, + v.IPRange.String(), + string(v.Protocol), + v.Version, + ""}, // That right, the account SAS requires a terminating extra newline + "\n") + + signature := sharedKeyCredential.ComputeHMACSHA256(stringToSign) + p := SASQueryParameters{ + // Common SAS parameters + version: v.Version, + protocol: v.Protocol, + startTime: v.StartTime, + expiryTime: v.ExpiryTime, + permissions: v.Permissions, + ipRange: v.IPRange, + + // Account-specific SAS parameters + services: v.Services, + resourceTypes: v.ResourceTypes, + + // Calculated SAS signature + signature: signature, + } + return p +} + +// The AccountSASPermissions type simplifies creating the permissions string for an Azure Storage Account SAS. +// Initialize an instance of this type and then call its String method to set AccountSASSignatureValues's Permissions field. +type AccountSASPermissions struct { + Read, Write, Delete, List, Add, Create, Update, Process bool +} + +// String produces the SAS permissions string for an Azure Storage account. +// Call this method to set AccountSASSignatureValues's Permissions field. +func (p AccountSASPermissions) String() string { + var buffer bytes.Buffer + if p.Read { + buffer.WriteRune('r') + } + if p.Write { + buffer.WriteRune('w') + } + if p.Delete { + buffer.WriteRune('d') + } + if p.List { + buffer.WriteRune('l') + } + if p.Add { + buffer.WriteRune('a') + } + if p.Create { + buffer.WriteRune('c') + } + if p.Update { + buffer.WriteRune('u') + } + if p.Process { + buffer.WriteRune('p') + } + return buffer.String() +} + +// Parse initializes the AccountSASPermissions's fields from a string. +func (p *AccountSASPermissions) Parse(s string) error { + *p = AccountSASPermissions{} // Clear out the flags + for _, r := range s { + switch r { + case 'r': + p.Read = true + case 'w': + p.Write = true + case 'd': + p.Delete = true + case 'l': + p.List = true + case 'a': + p.Add = true + case 'c': + p.Create = true + case 'u': + p.Update = true + case 'p': + p.Process = true + default: + return fmt.Errorf("Invalid permission character: '%v'", r) + } + } + return nil +} + +// The AccountSASServices type simplifies creating the services string for an Azure Storage Account SAS. +// Initialize an instance of this type and then call its String method to set AccountSASSignatureValues's Services field. +type AccountSASServices struct { + Blob, Queue, File bool +} + +// String produces the SAS services string for an Azure Storage account. +// Call this method to set AccountSASSignatureValues's Services field. +func (s AccountSASServices) String() string { + var buffer bytes.Buffer + if s.Blob { + buffer.WriteRune('b') + } + if s.Queue { + buffer.WriteRune('q') + } + if s.File { + buffer.WriteRune('f') + } + return buffer.String() +} + +// Parse initializes the AccountSASServices' fields from a string. +func (a *AccountSASServices) Parse(s string) error { + *a = AccountSASServices{} // Clear out the flags + for _, r := range s { + switch r { + case 'b': + a.Blob = true + case 'q': + a.Queue = true + case 'f': + a.File = true + default: + return fmt.Errorf("Invalid service character: '%v'", r) + } + } + return nil +} + +// The AccountSASResourceTypes type simplifies creating the resource types string for an Azure Storage Account SAS. +// Initialize an instance of this type and then call its String method to set AccountSASSignatureValues's ResourceTypes field. +type AccountSASResourceTypes struct { + Service, Container, Object bool +} + +// String produces the SAS resource types string for an Azure Storage account. +// Call this method to set AccountSASSignatureValues's ResourceTypes field. +func (rt AccountSASResourceTypes) String() string { + var buffer bytes.Buffer + if rt.Service { + buffer.WriteRune('s') + } + if rt.Container { + buffer.WriteRune('c') + } + if rt.Object { + buffer.WriteRune('o') + } + return buffer.String() +} + +// Parse initializes the AccountSASResourceType's fields from a string. +func (rt *AccountSASResourceTypes) Parse(s string) error { + *rt = AccountSASResourceTypes{} // Clear out the flags + for _, r := range s { + switch r { + case 's': + rt.Service = true + case 'q': + rt.Container = true + case 'o': + rt.Object = true + default: + return fmt.Errorf("Invalid resource type: '%v'", r) + } + } + return nil +} diff --git a/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zc_sas_query_params.go b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zc_sas_query_params.go new file mode 100644 index 0000000000..db10171e75 --- /dev/null +++ b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zc_sas_query_params.go @@ -0,0 +1,211 @@ +package azblob + +import ( + "net" + "net/url" + "strings" + "time" +) + +// SASVersion indicates the SAS version. +const SASVersion = ServiceVersion + +type SASProtocol string + +const ( + // SASProtocolHTTPS can be specified for a SAS protocol + SASProtocolHTTPS SASProtocol = "https" + + // SASProtocolHTTPSandHTTP can be specified for a SAS protocol + SASProtocolHTTPSandHTTP SASProtocol = "https,http" +) + +// FormatTimesForSASSigning converts a time.Time to a snapshotTimeFormat string suitable for a +// SASField's StartTime or ExpiryTime fields. Returns "" if value.IsZero(). +func FormatTimesForSASSigning(startTime, expiryTime time.Time) (string, string) { + ss := "" + if !startTime.IsZero() { + ss = startTime.Format(SASTimeFormat) // "yyyy-MM-ddTHH:mm:ssZ" + } + se := "" + if !expiryTime.IsZero() { + se = expiryTime.Format(SASTimeFormat) // "yyyy-MM-ddTHH:mm:ssZ" + } + return ss, se +} + +// SASTimeFormat represents the format of a SAS start or expiry time. Use it when formatting/parsing a time.Time. +const SASTimeFormat = "2006-01-02T15:04:05Z" //"2017-07-27T00:00:00Z" // ISO 8601 + +// https://docs.microsoft.com/en-us/rest/api/storageservices/constructing-a-service-sas + +// A SASQueryParameters object represents the components that make up an Azure Storage SAS' query parameters. +// You parse a map of query parameters into its fields by calling NewSASQueryParameters(). You add the components +// to a query parameter map by calling AddToValues(). +// NOTE: Changing any field requires computing a new SAS signature using a XxxSASSignatureValues type. +// +// This type defines the components used by all Azure Storage resources (Containers, Blobs, Files, & Queues). +type SASQueryParameters struct { + // All members are immutable or values so copies of this struct are goroutine-safe. + version string `param:"sv"` + services string `param:"ss"` + resourceTypes string `param:"srt"` + protocol SASProtocol `param:"spr"` + startTime time.Time `param:"st"` + expiryTime time.Time `param:"se"` + ipRange IPRange `param:"sip"` + identifier string `param:"si"` + resource string `param:"sr"` + permissions string `param:"sp"` + signature string `param:"sig"` +} + +func (p *SASQueryParameters) Version() string { + return p.version +} + +func (p *SASQueryParameters) Services() string { + return p.services +} +func (p *SASQueryParameters) ResourceTypes() string { + return p.resourceTypes +} +func (p *SASQueryParameters) Protocol() SASProtocol { + return p.protocol +} +func (p *SASQueryParameters) StartTime() time.Time { + return p.startTime +} +func (p *SASQueryParameters) ExpiryTime() time.Time { + return p.expiryTime +} + +func (p *SASQueryParameters) IPRange() IPRange { + return p.ipRange +} + +func (p *SASQueryParameters) Identifier() string { + return p.identifier +} + +func (p *SASQueryParameters) Resource() string { + return p.resource +} +func (p *SASQueryParameters) Permissions() string { + return p.permissions +} + +func (p *SASQueryParameters) Signature() string { + return p.signature +} + +// IPRange represents a SAS IP range's start IP and (optionally) end IP. +type IPRange struct { + Start net.IP // Not specified if length = 0 + End net.IP // Not specified if length = 0 +} + +// String returns a string representation of an IPRange. +func (ipr *IPRange) String() string { + if len(ipr.Start) == 0 { + return "" + } + start := ipr.Start.String() + if len(ipr.End) == 0 { + return start + } + return start + "-" + ipr.End.String() +} + +// NewSASQueryParameters creates and initializes a SASQueryParameters object based on the +// query parameter map's passed-in values. If deleteSASParametersFromValues is true, +// all SAS-related query parameters are removed from the passed-in map. If +// deleteSASParametersFromValues is false, the map passed-in map is unaltered. +func newSASQueryParameters(values url.Values, deleteSASParametersFromValues bool) SASQueryParameters { + p := SASQueryParameters{} + for k, v := range values { + val := v[0] + isSASKey := true + switch strings.ToLower(k) { + case "sv": + p.version = val + case "ss": + p.services = val + case "srt": + p.resourceTypes = val + case "spr": + p.protocol = SASProtocol(val) + case "st": + p.startTime, _ = time.Parse(SASTimeFormat, val) + case "se": + p.expiryTime, _ = time.Parse(SASTimeFormat, val) + case "sip": + dashIndex := strings.Index(val, "-") + if dashIndex == -1 { + p.ipRange.Start = net.ParseIP(val) + } else { + p.ipRange.Start = net.ParseIP(val[:dashIndex]) + p.ipRange.End = net.ParseIP(val[dashIndex+1:]) + } + case "si": + p.identifier = val + case "sr": + p.resource = val + case "sp": + p.permissions = val + case "sig": + p.signature = val + default: + isSASKey = false // We didn't recognize the query parameter + } + if isSASKey && deleteSASParametersFromValues { + delete(values, k) + } + } + return p +} + +// AddToValues adds the SAS components to the specified query parameters map. +func (p *SASQueryParameters) addToValues(v url.Values) url.Values { + if p.version != "" { + v.Add("sv", p.version) + } + if p.services != "" { + v.Add("ss", p.services) + } + if p.resourceTypes != "" { + v.Add("srt", p.resourceTypes) + } + if p.protocol != "" { + v.Add("spr", string(p.protocol)) + } + if !p.startTime.IsZero() { + v.Add("st", p.startTime.Format(SASTimeFormat)) + } + if !p.expiryTime.IsZero() { + v.Add("se", p.expiryTime.Format(SASTimeFormat)) + } + if len(p.ipRange.Start) > 0 { + v.Add("sip", p.ipRange.String()) + } + if p.identifier != "" { + v.Add("si", p.identifier) + } + if p.resource != "" { + v.Add("sr", p.resource) + } + if p.permissions != "" { + v.Add("sp", p.permissions) + } + if p.signature != "" { + v.Add("sig", p.signature) + } + return v +} + +// Encode encodes the SAS query parameters into URL encoded form sorted by key. +func (p *SASQueryParameters) Encode() string { + v := url.Values{} + p.addToValues(v) + return v.Encode() +} diff --git a/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zc_service_codes_common.go b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zc_service_codes_common.go new file mode 100644 index 0000000000..765beb2415 --- /dev/null +++ b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zc_service_codes_common.go @@ -0,0 +1,131 @@ +package azblob + +// https://docs.microsoft.com/en-us/rest/api/storageservices/common-rest-api-error-codes + +const ( + // ServiceCodeNone is the default value. It indicates that the error was related to the service or that the service didn't return a code. + ServiceCodeNone ServiceCodeType = "" + + // ServiceCodeAccountAlreadyExists means the specified account already exists. + ServiceCodeAccountAlreadyExists ServiceCodeType = "AccountAlreadyExists" + + // ServiceCodeAccountBeingCreated means the specified account is in the process of being created (403). + ServiceCodeAccountBeingCreated ServiceCodeType = "AccountBeingCreated" + + // ServiceCodeAccountIsDisabled means the specified account is disabled (403). + ServiceCodeAccountIsDisabled ServiceCodeType = "AccountIsDisabled" + + // ServiceCodeAuthenticationFailed means the server failed to authenticate the request. Make sure the value of the Authorization header is formed correctly including the signature (403). + ServiceCodeAuthenticationFailed ServiceCodeType = "AuthenticationFailed" + + // ServiceCodeConditionHeadersNotSupported means the condition headers are not supported (400). + ServiceCodeConditionHeadersNotSupported ServiceCodeType = "ConditionHeadersNotSupported" + + // ServiceCodeConditionNotMet means the condition specified in the conditional header(s) was not met for a read/write operation (304/412). + ServiceCodeConditionNotMet ServiceCodeType = "ConditionNotMet" + + // ServiceCodeEmptyMetadataKey means the key for one of the metadata key-value pairs is empty (400). + ServiceCodeEmptyMetadataKey ServiceCodeType = "EmptyMetadataKey" + + // ServiceCodeInsufficientAccountPermissions means read operations are currently disabled or Write operations are not allowed or The account being accessed does not have sufficient permissions to execute this operation (403). + ServiceCodeInsufficientAccountPermissions ServiceCodeType = "InsufficientAccountPermissions" + + // ServiceCodeInternalError means the server encountered an internal error. Please retry the request (500). + ServiceCodeInternalError ServiceCodeType = "InternalError" + + // ServiceCodeInvalidAuthenticationInfo means the authentication information was not provided in the correct format. Verify the value of Authorization header (400). + ServiceCodeInvalidAuthenticationInfo ServiceCodeType = "InvalidAuthenticationInfo" + + // ServiceCodeInvalidHeaderValue means the value provided for one of the HTTP headers was not in the correct format (400). + ServiceCodeInvalidHeaderValue ServiceCodeType = "InvalidHeaderValue" + + // ServiceCodeInvalidHTTPVerb means the HTTP verb specified was not recognized by the server (400). + ServiceCodeInvalidHTTPVerb ServiceCodeType = "InvalidHttpVerb" + + // ServiceCodeInvalidInput means one of the request inputs is not valid (400). + ServiceCodeInvalidInput ServiceCodeType = "InvalidInput" + + // ServiceCodeInvalidMd5 means the MD5 value specified in the request is invalid. The MD5 value must be 128 bits and Base64-encoded (400). + ServiceCodeInvalidMd5 ServiceCodeType = "InvalidMd5" + + // ServiceCodeInvalidMetadata means the specified metadata is invalid. It includes characters that are not permitted (400). + ServiceCodeInvalidMetadata ServiceCodeType = "InvalidMetadata" + + // ServiceCodeInvalidQueryParameterValue means an invalid value was specified for one of the query parameters in the request URI (400). + ServiceCodeInvalidQueryParameterValue ServiceCodeType = "InvalidQueryParameterValue" + + // ServiceCodeInvalidRange means the range specified is invalid for the current size of the resource (416). + ServiceCodeInvalidRange ServiceCodeType = "InvalidRange" + + // ServiceCodeInvalidResourceName means the specified resource name contains invalid characters (400). + ServiceCodeInvalidResourceName ServiceCodeType = "InvalidResourceName" + + // ServiceCodeInvalidURI means the requested URI does not represent any resource on the server (400). + ServiceCodeInvalidURI ServiceCodeType = "InvalidUri" + + // ServiceCodeInvalidXMLDocument means the specified XML is not syntactically valid (400). + ServiceCodeInvalidXMLDocument ServiceCodeType = "InvalidXmlDocument" + + // ServiceCodeInvalidXMLNodeValue means the value provided for one of the XML nodes in the request body was not in the correct format (400). + ServiceCodeInvalidXMLNodeValue ServiceCodeType = "InvalidXmlNodeValue" + + // ServiceCodeMd5Mismatch means the MD5 value specified in the request did not match the MD5 value calculated by the server (400). + ServiceCodeMd5Mismatch ServiceCodeType = "Md5Mismatch" + + // ServiceCodeMetadataTooLarge means the size of the specified metadata exceeds the maximum size permitted (400). + ServiceCodeMetadataTooLarge ServiceCodeType = "MetadataTooLarge" + + // ServiceCodeMissingContentLengthHeader means the Content-Length header was not specified (411). + ServiceCodeMissingContentLengthHeader ServiceCodeType = "MissingContentLengthHeader" + + // ServiceCodeMissingRequiredQueryParameter means a required query parameter was not specified for this request (400). + ServiceCodeMissingRequiredQueryParameter ServiceCodeType = "MissingRequiredQueryParameter" + + // ServiceCodeMissingRequiredHeader means a required HTTP header was not specified (400). + ServiceCodeMissingRequiredHeader ServiceCodeType = "MissingRequiredHeader" + + // ServiceCodeMissingRequiredXMLNode means a required XML node was not specified in the request body (400). + ServiceCodeMissingRequiredXMLNode ServiceCodeType = "MissingRequiredXmlNode" + + // ServiceCodeMultipleConditionHeadersNotSupported means multiple condition headers are not supported (400). + ServiceCodeMultipleConditionHeadersNotSupported ServiceCodeType = "MultipleConditionHeadersNotSupported" + + // ServiceCodeOperationTimedOut means the operation could not be completed within the permitted time (500). + ServiceCodeOperationTimedOut ServiceCodeType = "OperationTimedOut" + + // ServiceCodeOutOfRangeInput means one of the request inputs is out of range (400). + ServiceCodeOutOfRangeInput ServiceCodeType = "OutOfRangeInput" + + // ServiceCodeOutOfRangeQueryParameterValue means a query parameter specified in the request URI is outside the permissible range (400). + ServiceCodeOutOfRangeQueryParameterValue ServiceCodeType = "OutOfRangeQueryParameterValue" + + // ServiceCodeRequestBodyTooLarge means the size of the request body exceeds the maximum size permitted (413). + ServiceCodeRequestBodyTooLarge ServiceCodeType = "RequestBodyTooLarge" + + // ServiceCodeResourceTypeMismatch means the specified resource type does not match the type of the existing resource (409). + ServiceCodeResourceTypeMismatch ServiceCodeType = "ResourceTypeMismatch" + + // ServiceCodeRequestURLFailedToParse means the url in the request could not be parsed (400). + ServiceCodeRequestURLFailedToParse ServiceCodeType = "RequestUrlFailedToParse" + + // ServiceCodeResourceAlreadyExists means the specified resource already exists (409). + ServiceCodeResourceAlreadyExists ServiceCodeType = "ResourceAlreadyExists" + + // ServiceCodeResourceNotFound means the specified resource does not exist (404). + ServiceCodeResourceNotFound ServiceCodeType = "ResourceNotFound" + + // ServiceCodeServerBusy means the server is currently unable to receive requests. Please retry your request or Ingress/egress is over the account limit or operations per second is over the account limit (503). + ServiceCodeServerBusy ServiceCodeType = "ServerBusy" + + // ServiceCodeUnsupportedHeader means one of the HTTP headers specified in the request is not supported (400). + ServiceCodeUnsupportedHeader ServiceCodeType = "UnsupportedHeader" + + // ServiceCodeUnsupportedXMLNode means one of the XML nodes specified in the request body is not supported (400). + ServiceCodeUnsupportedXMLNode ServiceCodeType = "UnsupportedXmlNode" + + // ServiceCodeUnsupportedQueryParameter means one of the query parameters specified in the request URI is not supported (400). + ServiceCodeUnsupportedQueryParameter ServiceCodeType = "UnsupportedQueryParameter" + + // ServiceCodeUnsupportedHTTPVerb means the resource doesn't support the specified HTTP verb (405). + ServiceCodeUnsupportedHTTPVerb ServiceCodeType = "UnsupportedHttpVerb" +) diff --git a/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zc_storage_error.go b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zc_storage_error.go new file mode 100644 index 0000000000..03178b247a --- /dev/null +++ b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zc_storage_error.go @@ -0,0 +1,110 @@ +package azblob + +import ( + "bytes" + "encoding/xml" + "fmt" + "net/http" + "sort" + + "github.com/Azure/azure-pipeline-go/pipeline" +) + +func init() { + // wire up our custom error handling constructor + responseErrorFactory = newStorageError +} + +// ServiceCodeType is a string identifying a storage service error. +// For more information, see https://docs.microsoft.com/en-us/rest/api/storageservices/status-and-error-codes2 +type ServiceCodeType string + +// StorageError identifies a responder-generated network or response parsing error. +type StorageError interface { + // ResponseError implements error's Error(), net.Error's Temporary() and Timeout() methods & Response(). + ResponseError + + // ServiceCode returns a service error code. Your code can use this to make error recovery decisions. + ServiceCode() ServiceCodeType +} + +// storageError is the internal struct that implements the public StorageError interface. +type storageError struct { + responseError + serviceCode ServiceCodeType + details map[string]string +} + +// newStorageError creates an error object that implements the error interface. +func newStorageError(cause error, response *http.Response, description string) error { + return &storageError{ + responseError: responseError{ + ErrorNode: pipeline.ErrorNode{}.Initialize(cause, 3), + response: response, + description: description, + }, + } +} + +// ServiceCode returns service-error information. The caller may examine these values but should not modify any of them. +func (e *storageError) ServiceCode() ServiceCodeType { return e.serviceCode } + +// Error implements the error interface's Error method to return a string representation of the error. +func (e *storageError) Error() string { + b := &bytes.Buffer{} + fmt.Fprintf(b, "===== RESPONSE ERROR (ServiceCode=%s) =====\n", e.serviceCode) + fmt.Fprintf(b, "Description=%s, Details: ", e.description) + if len(e.details) == 0 { + b.WriteString("(none)\n") + } else { + b.WriteRune('\n') + keys := make([]string, 0, len(e.details)) + // Alphabetize the details + for k := range e.details { + keys = append(keys, k) + } + sort.Strings(keys) + for _, k := range keys { + fmt.Fprintf(b, " %s: %+v\n", k, e.details[k]) + } + } + req := pipeline.Request{Request: e.response.Request}.Copy() // Make a copy of the response's request + pipeline.WriteRequestWithResponse(b, prepareRequestForLogging(req), e.response, nil) + return e.ErrorNode.Error(b.String()) +} + +// Temporary returns true if the error occurred due to a temporary condition (including an HTTP status of 500 or 503). +func (e *storageError) Temporary() bool { + if e.response != nil { + if (e.response.StatusCode == http.StatusInternalServerError) || (e.response.StatusCode == http.StatusServiceUnavailable) { + return true + } + } + return e.ErrorNode.Temporary() +} + +// UnmarshalXML performs custom unmarshalling of XML-formatted Azure storage request errors. +func (e *storageError) UnmarshalXML(d *xml.Decoder, start xml.StartElement) (err error) { + tokName := "" + var t xml.Token + for t, err = d.Token(); err == nil; t, err = d.Token() { + switch tt := t.(type) { + case xml.StartElement: + tokName = tt.Name.Local + break + case xml.CharData: + switch tokName { + case "Code": + e.serviceCode = ServiceCodeType(tt) + case "Message": + e.description = string(tt) + default: + if e.details == nil { + e.details = map[string]string{} + } + e.details[tokName] = string(tt) + } + } + } + return nil +} diff --git a/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zc_util_validate.go b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zc_util_validate.go new file mode 100644 index 0000000000..001a21c696 --- /dev/null +++ b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zc_util_validate.go @@ -0,0 +1,61 @@ +package azblob + +import ( + "errors" + "fmt" + "io" + "strconv" +) + +// httpRange defines a range of bytes within an HTTP resource, starting at offset and +// ending at offset+count. A zero-value httpRange indicates the entire resource. An httpRange +// which has an offset but na zero value count indicates from the offset to the resource's end. +type httpRange struct { + offset int64 + count int64 +} + +func (r httpRange) pointers() *string { + if r.offset == 0 && r.count == 0 { // Do common case first for performance + return nil // No specified range + } + if r.offset < 0 { + panic("The range offset must be >= 0") + } + if r.count < 0 { + panic("The range count must be >= 0") + } + endOffset := "" // if count == 0 + if r.count > 0 { + endOffset = strconv.FormatInt((r.offset+r.count)-1, 10) + } + dataRange := fmt.Sprintf("bytes=%v-%s", r.offset, endOffset) + return &dataRange +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +func validateSeekableStreamAt0AndGetCount(body io.ReadSeeker) int64 { + if body == nil { // nil body's are "logically" seekable to 0 and are 0 bytes long + return 0 + } + validateSeekableStreamAt0(body) + count, err := body.Seek(0, io.SeekEnd) + if err != nil { + panic("failed to seek stream") + } + body.Seek(0, io.SeekStart) + return count +} + +func validateSeekableStreamAt0(body io.ReadSeeker) { + if body == nil { // nil body's are "logically" seekable to 0 + return + } + if pos, err := body.Seek(0, io.SeekCurrent); pos != 0 || err != nil { + if err != nil { + panic(err) + } + panic(errors.New("stream must be set to position 0")) + } +} diff --git a/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zc_uuid.go b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zc_uuid.go new file mode 100644 index 0000000000..1fc7e89cf2 --- /dev/null +++ b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zc_uuid.go @@ -0,0 +1,80 @@ +package azblob + +import ( + "crypto/rand" + "fmt" + "strconv" +) + +// The UUID reserved variants. +const ( + reservedNCS byte = 0x80 + reservedRFC4122 byte = 0x40 + reservedMicrosoft byte = 0x20 + reservedFuture byte = 0x00 +) + +// A UUID representation compliant with specification in RFC 4122 document. +type uuid [16]byte + +// NewUUID returns a new uuid using RFC 4122 algorithm. +func newUUID() (u uuid) { + u = uuid{} + // Set all bits to randomly (or pseudo-randomly) chosen values. + _, err := rand.Read(u[:]) + if err != nil { + panic("ran.Read failed") + } + u[8] = (u[8] | reservedRFC4122) & 0x7F // u.setVariant(ReservedRFC4122) + + var version byte = 4 + u[6] = (u[6] & 0xF) | (version << 4) // u.setVersion(4) + return +} + +// String returns an unparsed version of the generated UUID sequence. +func (u uuid) String() string { + return fmt.Sprintf("%x-%x-%x-%x-%x", u[0:4], u[4:6], u[6:8], u[8:10], u[10:]) +} + +// ParseUUID parses a string formatted as "003020100-0504-0706-0809-0a0b0c0d0e0f" +// or "{03020100-0504-0706-0809-0a0b0c0d0e0f}" into a UUID. +func parseUUID(uuidStr string) uuid { + char := func(hexString string) byte { + i, _ := strconv.ParseUint(hexString, 16, 8) + return byte(i) + } + if uuidStr[0] == '{' { + uuidStr = uuidStr[1:] // Skip over the '{' + } + // 03020100 - 05 04 - 07 06 - 08 09 - 0a 0b 0c 0d 0e 0f + // 1 11 1 11 11 1 12 22 2 22 22 22 33 33 33 + // 01234567 8 90 12 3 45 67 8 90 12 3 45 67 89 01 23 45 + uuidVal := uuid{ + char(uuidStr[0:2]), + char(uuidStr[2:4]), + char(uuidStr[4:6]), + char(uuidStr[6:8]), + + char(uuidStr[9:11]), + char(uuidStr[11:13]), + + char(uuidStr[14:16]), + char(uuidStr[16:18]), + + char(uuidStr[19:21]), + char(uuidStr[21:23]), + + char(uuidStr[24:26]), + char(uuidStr[26:28]), + char(uuidStr[28:30]), + char(uuidStr[30:32]), + char(uuidStr[32:34]), + char(uuidStr[34:36]), + } + return uuidVal +} + +func (u uuid) bytes() []byte { + return u[:] +} diff --git a/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zt_doc.go b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zt_doc.go new file mode 100644 index 0000000000..6b3779c0e9 --- /dev/null +++ b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zt_doc.go @@ -0,0 +1,89 @@ +// Copyright 2017 Microsoft Corporation. All rights reserved. +// Use of this source code is governed by an MIT +// license that can be found in the LICENSE file. + +/* +Package azblob allows you to manipulate Azure Storage containers and blobs objects. + +URL Types + +The most common types you'll work with are the XxxURL types. The methods of these types make requests +against the Azure Storage Service. + + - ServiceURL's methods perform operations on a storage account. + - ContainerURL's methods perform operations on an account's container. + - BlockBlobURL's methods perform operations on a container's block blob. + - AppendBlobURL's methods perform operations on a container's append blob. + - PageBlobURL's methods perform operations on a container's page blob. + - BlobURL's methods perform operations on a container's blob regardless of the blob's type. + +Internally, each XxxURL object contains a URL and a request pipeline. The URL indicates the endpoint where each HTTP +request is sent and the pipeline indicates how the outgoing HTTP request and incoming HTTP response is processed. +The pipeline specifies things like retry policies, logging, deserialization of HTTP response payloads, and more. + +Pipelines are threadsafe and may be shared by multiple XxxURL objects. When you create a ServiceURL, you pass +an initial pipeline. When you call ServiceURL's NewContainerURL method, the new ContainerURL object has its own +URL but it shares the same pipeline as the parent ServiceURL object. + +To work with a blob, call one of ContainerURL's 4 NewXxxBlobURL methods depending on how you want to treat the blob. +To treat the blob as a block blob, append blob, or page blob, call NewBlockBlobURL, NewAppendBlobURL, or NewPageBlobURL +respectively. These three types are all identical except for the methods they expose; each type exposes the methods +relevant to the type of blob represented. If you're not sure how you want to treat a blob, you can call NewBlobURL; +this returns an object whose methods are relevant to any kind of blob. When you call ContainerURL's NewXxxBlobURL, +the new XxxBlobURL object has its own URL but it shares the same pipeline as the parent ContainerURL object. You +can easily switch between blob types (method sets) by calling a ToXxxBlobURL method. + +If you'd like to use a different pipeline with a ServiceURL, ContainerURL, or XxxBlobURL object, then call the XxxURL +object's WithPipeline method passing in the desired pipeline. The WithPipeline methods create a new XxxURL object +with the same URL as the original but with the specified pipeline. + +Note that XxxURL objects use little memory, are goroutine-safe, and many objects share the same pipeline. This means that +XxxURL objects share a lot of system resources making them very efficient. + +All of XxxURL's methods that make HTTP requests return rich error handling information so you can discern network failures, +transient failures, timeout failures, service failures, etc. See the StorageError interface for more information and an +example of how to do deal with errors. + +URL and Shared Access Signature Manipulation + +The library includes a BlobURLParts type for deconstructing and reconstructing URLs. And you can use the following types +for generating and parsing Shared Access Signature (SAS) + - Use the AccountSASSignatureValues type to create a SAS for a storage account. + - Use the BlobSASSignatureValues type to create a SAS for a container or blob. + - Use the SASQueryParameters type to turn signature values in to query parameres or to parse query parameters. + +To generate a SAS, you must use the SharedKeyCredential type. + +Credentials + +When creating a request pipeline, you must specify one of this package's credential types. + - Call the NewAnonymousCredential function for requests that contain a Shared Access Signature (SAS). + - Call the NewSharedKeyCredential function (with an account name & key) to access any account resources. You must also use this + to generate Shared Access Signatures. + +HTTP Request Policy Factories + +This package defines several request policy factories for use with the pipeline package. +Most applications will not use these factories directly; instead, the NewPipeline +function creates these factories, initializes them (via the PipelineOptions type) +and returns a pipeline object for use by the XxxURL objects. + +However, for advanced scenarios, developers can access these policy factories directly +and even create their own and then construct their own pipeline in order to affect HTTP +requests and responses performed by the XxxURL objects. For example, developers can +introduce their own logging, random failures, request recording & playback for fast +testing, HTTP request pacing, alternate retry mechanisms, metering, metrics, etc. The +possibilities are endless! + +Below are the request pipeline policy factory functions that are provided with this +package: + - NewRetryPolicyFactory Enables rich retry semantics for failed HTTP requests. + - NewRequestLogPolicyFactory Enables rich logging support for HTTP requests/responses & failures. + - NewTelemetryPolicyFactory Enables simple modification of the HTTP request's User-Agent header so each request reports the SDK version & language/runtime making the requests. + - NewUniqueRequestIDPolicyFactory Adds a x-ms-client-request-id header with a unique UUID value to an HTTP request to help with diagnosing failures. + +Also, note that all the NewXxxCredential functions return request policy factory objects which get injected into the pipeline. +*/ +package azblob + +// TokenCredential Use this to access resources using Role-Based Access Control (RBAC). diff --git a/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zz_generated_append_blob.go b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zz_generated_append_blob.go new file mode 100644 index 0000000000..8f3dc99349 --- /dev/null +++ b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zz_generated_append_blob.go @@ -0,0 +1,234 @@ +package azblob + +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "context" + "encoding/base64" + "github.com/Azure/azure-pipeline-go/pipeline" + "io" + "io/ioutil" + "net/http" + "net/url" + "strconv" + "time" +) + +// appendBlobClient is the client for the AppendBlob methods of the Azblob service. +type appendBlobClient struct { + managementClient +} + +// newAppendBlobClient creates an instance of the appendBlobClient client. +func newAppendBlobClient(url url.URL, p pipeline.Pipeline) appendBlobClient { + return appendBlobClient{newManagementClient(url, p)} +} + +// AppendBlock the Append Block operation commits a new block of data to the end of an existing append blob. The Append +// Block operation is permitted only if the blob was created with x-ms-blob-type set to AppendBlob. Append Block is +// supported only on version 2015-02-21 version or later. +// +// body is initial data body will be closed upon successful return. Callers should ensure closure when receiving an +// error.contentLength is the length of the request. timeout is the timeout parameter is expressed in seconds. For more +// information, see Setting +// Timeouts for Blob Service Operations. leaseID is if specified, the operation only succeeds if the container's +// lease is active and matches this ID. maxSize is optional conditional header. The max length in bytes permitted for +// the append blob. If the Append Block operation would cause the blob to exceed that limit or if the blob size is +// already greater than the value specified in this header, the request will fail with MaxBlobSizeConditionNotMet error +// (HTTP status code 412 - Precondition Failed). appendPosition is optional conditional header, used only for the +// Append Block operation. A number indicating the byte offset to compare. Append Block will succeed only if the append +// position is equal to this number. If it is not, the request will fail with the AppendPositionConditionNotMet error +// (HTTP status code 412 - Precondition Failed). ifModifiedSince is specify this header value to operate only on a blob +// if it has been modified since the specified date/time. ifUnmodifiedSince is specify this header value to operate +// only on a blob if it has not been modified since the specified date/time. ifMatches is specify an ETag value to +// operate only on blobs with a matching value. ifNoneMatch is specify an ETag value to operate only on blobs without a +// matching value. requestID is provides a client-generated, opaque value with a 1 KB character limit that is recorded +// in the analytics logs when storage analytics logging is enabled. +func (client appendBlobClient) AppendBlock(ctx context.Context, body io.ReadSeeker, contentLength int64, timeout *int32, leaseID *string, maxSize *int64, appendPosition *int64, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (*AppendBlobAppendBlockResponse, error) { + if err := validate([]validation{ + {targetValue: body, + constraints: []constraint{{target: "body", name: null, rule: true, chain: nil}}}, + {targetValue: timeout, + constraints: []constraint{{target: "timeout", name: null, rule: false, + chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil { + return nil, err + } + req, err := client.appendBlockPreparer(body, contentLength, timeout, leaseID, maxSize, appendPosition, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestID) + if err != nil { + return nil, err + } + resp, err := client.Pipeline().Do(ctx, responderPolicyFactory{responder: client.appendBlockResponder}, req) + if err != nil { + return nil, err + } + return resp.(*AppendBlobAppendBlockResponse), err +} + +// appendBlockPreparer prepares the AppendBlock request. +func (client appendBlobClient) appendBlockPreparer(body io.ReadSeeker, contentLength int64, timeout *int32, leaseID *string, maxSize *int64, appendPosition *int64, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (pipeline.Request, error) { + req, err := pipeline.NewRequest("PUT", client.url, body) + if err != nil { + return req, pipeline.NewError(err, "failed to create request") + } + params := req.URL.Query() + if timeout != nil { + params.Set("timeout", strconv.FormatInt(int64(*timeout), 10)) + } + params.Set("comp", "appendblock") + req.URL.RawQuery = params.Encode() + req.Header.Set("Content-Length", strconv.FormatInt(contentLength, 10)) + if leaseID != nil { + req.Header.Set("x-ms-lease-id", *leaseID) + } + if maxSize != nil { + req.Header.Set("x-ms-blob-condition-maxsize", strconv.FormatInt(*maxSize, 10)) + } + if appendPosition != nil { + req.Header.Set("x-ms-blob-condition-appendpos", strconv.FormatInt(*appendPosition, 10)) + } + if ifModifiedSince != nil { + req.Header.Set("If-Modified-Since", (*ifModifiedSince).In(gmt).Format(time.RFC1123)) + } + if ifUnmodifiedSince != nil { + req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123)) + } + if ifMatches != nil { + req.Header.Set("If-Match", string(*ifMatches)) + } + if ifNoneMatch != nil { + req.Header.Set("If-None-Match", string(*ifNoneMatch)) + } + req.Header.Set("x-ms-version", ServiceVersion) + if requestID != nil { + req.Header.Set("x-ms-client-request-id", *requestID) + } + return req, nil +} + +// appendBlockResponder handles the response to the AppendBlock request. +func (client appendBlobClient) appendBlockResponder(resp pipeline.Response) (pipeline.Response, error) { + err := validateResponse(resp, http.StatusOK, http.StatusCreated) + if resp == nil { + return nil, err + } + io.Copy(ioutil.Discard, resp.Response().Body) + resp.Response().Body.Close() + return &AppendBlobAppendBlockResponse{rawResponse: resp.Response()}, err +} + +// Create the Create Append Blob operation creates a new append blob. +// +// contentLength is the length of the request. timeout is the timeout parameter is expressed in seconds. For more +// information, see Setting +// Timeouts for Blob Service Operations. blobContentType is optional. Sets the blob's content type. If specified, +// this property is stored with the blob and returned with a read request. blobContentEncoding is optional. Sets the +// blob's content encoding. If specified, this property is stored with the blob and returned with a read request. +// blobContentLanguage is optional. Set the blob's content language. If specified, this property is stored with the +// blob and returned with a read request. blobContentMD5 is optional. An MD5 hash of the blob content. Note that this +// hash is not validated, as the hashes for the individual blocks were validated when each was uploaded. +// blobCacheControl is optional. Sets the blob's cache control. If specified, this property is stored with the blob and +// returned with a read request. metadata is optional. Specifies a user-defined name-value pair associated with the +// blob. If no name-value pairs are specified, the operation will copy the metadata from the source blob or file to the +// destination blob. If one or more name-value pairs are specified, the destination blob is created with the specified +// metadata, and metadata is not copied from the source blob or file. Note that beginning with version 2009-09-19, +// metadata names must adhere to the naming rules for C# identifiers. See Naming and Referencing Containers, Blobs, and +// Metadata for more information. leaseID is if specified, the operation only succeeds if the container's lease is +// active and matches this ID. blobContentDisposition is optional. Sets the blob's Content-Disposition header. +// ifModifiedSince is specify this header value to operate only on a blob if it has been modified since the specified +// date/time. ifUnmodifiedSince is specify this header value to operate only on a blob if it has not been modified +// since the specified date/time. ifMatches is specify an ETag value to operate only on blobs with a matching value. +// ifNoneMatch is specify an ETag value to operate only on blobs without a matching value. requestID is provides a +// client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage +// analytics logging is enabled. +func (client appendBlobClient) Create(ctx context.Context, contentLength int64, timeout *int32, blobContentType *string, blobContentEncoding *string, blobContentLanguage *string, blobContentMD5 []byte, blobCacheControl *string, metadata map[string]string, leaseID *string, blobContentDisposition *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (*AppendBlobCreateResponse, error) { + if err := validate([]validation{ + {targetValue: timeout, + constraints: []constraint{{target: "timeout", name: null, rule: false, + chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}, + {targetValue: metadata, + constraints: []constraint{{target: "metadata", name: null, rule: false, + chain: []constraint{{target: "metadata", name: pattern, rule: `^[a-zA-Z]+$`, chain: nil}}}}}}); err != nil { + return nil, err + } + req, err := client.createPreparer(contentLength, timeout, blobContentType, blobContentEncoding, blobContentLanguage, blobContentMD5, blobCacheControl, metadata, leaseID, blobContentDisposition, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestID) + if err != nil { + return nil, err + } + resp, err := client.Pipeline().Do(ctx, responderPolicyFactory{responder: client.createResponder}, req) + if err != nil { + return nil, err + } + return resp.(*AppendBlobCreateResponse), err +} + +// createPreparer prepares the Create request. +func (client appendBlobClient) createPreparer(contentLength int64, timeout *int32, blobContentType *string, blobContentEncoding *string, blobContentLanguage *string, blobContentMD5 []byte, blobCacheControl *string, metadata map[string]string, leaseID *string, blobContentDisposition *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (pipeline.Request, error) { + req, err := pipeline.NewRequest("PUT", client.url, nil) + if err != nil { + return req, pipeline.NewError(err, "failed to create request") + } + params := req.URL.Query() + if timeout != nil { + params.Set("timeout", strconv.FormatInt(int64(*timeout), 10)) + } + req.URL.RawQuery = params.Encode() + req.Header.Set("Content-Length", strconv.FormatInt(contentLength, 10)) + if blobContentType != nil { + req.Header.Set("x-ms-blob-content-type", *blobContentType) + } + if blobContentEncoding != nil { + req.Header.Set("x-ms-blob-content-encoding", *blobContentEncoding) + } + if blobContentLanguage != nil { + req.Header.Set("x-ms-blob-content-language", *blobContentLanguage) + } + if blobContentMD5 != nil { + req.Header.Set("x-ms-blob-content-md5", base64.StdEncoding.EncodeToString(blobContentMD5)) + } + if blobCacheControl != nil { + req.Header.Set("x-ms-blob-cache-control", *blobCacheControl) + } + if metadata != nil { + for k, v := range metadata { + req.Header.Set("x-ms-meta-"+k, v) + } + } + if leaseID != nil { + req.Header.Set("x-ms-lease-id", *leaseID) + } + if blobContentDisposition != nil { + req.Header.Set("x-ms-blob-content-disposition", *blobContentDisposition) + } + if ifModifiedSince != nil { + req.Header.Set("If-Modified-Since", (*ifModifiedSince).In(gmt).Format(time.RFC1123)) + } + if ifUnmodifiedSince != nil { + req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123)) + } + if ifMatches != nil { + req.Header.Set("If-Match", string(*ifMatches)) + } + if ifNoneMatch != nil { + req.Header.Set("If-None-Match", string(*ifNoneMatch)) + } + req.Header.Set("x-ms-version", ServiceVersion) + if requestID != nil { + req.Header.Set("x-ms-client-request-id", *requestID) + } + req.Header.Set("x-ms-blob-type", "AppendBlob") + return req, nil +} + +// createResponder handles the response to the Create request. +func (client appendBlobClient) createResponder(resp pipeline.Response) (pipeline.Response, error) { + err := validateResponse(resp, http.StatusOK, http.StatusCreated) + if resp == nil { + return nil, err + } + io.Copy(ioutil.Discard, resp.Response().Body) + resp.Response().Body.Close() + return &AppendBlobCreateResponse{rawResponse: resp.Response()}, err +} diff --git a/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zz_generated_blob.go b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zz_generated_blob.go new file mode 100644 index 0000000000..b2f8eac665 --- /dev/null +++ b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zz_generated_blob.go @@ -0,0 +1,1233 @@ +package azblob + +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "context" + "encoding/base64" + "io" + "io/ioutil" + "net/http" + "net/url" + "strconv" + "time" + + "github.com/Azure/azure-pipeline-go/pipeline" +) + +// blobClient is the client for the Blob methods of the Azblob service. +type blobClient struct { + managementClient +} + +// newBlobClient creates an instance of the blobClient client. +func newBlobClient(url url.URL, p pipeline.Pipeline) blobClient { + return blobClient{newManagementClient(url, p)} +} + +// AbortCopyFromURL the Abort Copy From URL operation aborts a pending Copy From URL operation, and leaves a +// destination blob with zero length and full metadata. +// +// copyID is the copy identifier provided in the x-ms-copy-id header of the original Copy Blob operation. timeout is +// the timeout parameter is expressed in seconds. For more information, see Setting +// Timeouts for Blob Service Operations. leaseID is if specified, the operation only succeeds if the container's +// lease is active and matches this ID. requestID is provides a client-generated, opaque value with a 1 KB character +// limit that is recorded in the analytics logs when storage analytics logging is enabled. +func (client blobClient) AbortCopyFromURL(ctx context.Context, copyID string, timeout *int32, leaseID *string, requestID *string) (*BlobAbortCopyFromURLResponse, error) { + if err := validate([]validation{ + {targetValue: timeout, + constraints: []constraint{{target: "timeout", name: null, rule: false, + chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil { + return nil, err + } + req, err := client.abortCopyFromURLPreparer(copyID, timeout, leaseID, requestID) + if err != nil { + return nil, err + } + resp, err := client.Pipeline().Do(ctx, responderPolicyFactory{responder: client.abortCopyFromURLResponder}, req) + if err != nil { + return nil, err + } + return resp.(*BlobAbortCopyFromURLResponse), err +} + +// abortCopyFromURLPreparer prepares the AbortCopyFromURL request. +func (client blobClient) abortCopyFromURLPreparer(copyID string, timeout *int32, leaseID *string, requestID *string) (pipeline.Request, error) { + req, err := pipeline.NewRequest("PUT", client.url, nil) + if err != nil { + return req, pipeline.NewError(err, "failed to create request") + } + params := req.URL.Query() + params.Set("copyid", copyID) + if timeout != nil { + params.Set("timeout", strconv.FormatInt(int64(*timeout), 10)) + } + params.Set("comp", "copy") + req.URL.RawQuery = params.Encode() + if leaseID != nil { + req.Header.Set("x-ms-lease-id", *leaseID) + } + req.Header.Set("x-ms-version", ServiceVersion) + if requestID != nil { + req.Header.Set("x-ms-client-request-id", *requestID) + } + req.Header.Set("x-ms-copy-action", "abort") + return req, nil +} + +// abortCopyFromURLResponder handles the response to the AbortCopyFromURL request. +func (client blobClient) abortCopyFromURLResponder(resp pipeline.Response) (pipeline.Response, error) { + err := validateResponse(resp, http.StatusOK, http.StatusNoContent) + if resp == nil { + return nil, err + } + io.Copy(ioutil.Discard, resp.Response().Body) + resp.Response().Body.Close() + return &BlobAbortCopyFromURLResponse{rawResponse: resp.Response()}, err +} + +// AcquireLease [Update] The Lease Blob operation establishes and manages a lock on a blob for write and delete +// operations +// +// timeout is the timeout parameter is expressed in seconds. For more information, see Setting +// Timeouts for Blob Service Operations. duration is specifies the duration of the lease, in seconds, or negative +// one (-1) for a lease that never expires. A non-infinite lease can be between 15 and 60 seconds. A lease duration +// cannot be changed using renew or change. proposedLeaseID is proposed lease ID, in a GUID string format. The Blob +// service returns 400 (Invalid request) if the proposed lease ID is not in the correct format. See Guid Constructor +// (String) for a list of valid GUID string formats. ifModifiedSince is specify this header value to operate only on a +// blob if it has been modified since the specified date/time. ifUnmodifiedSince is specify this header value to +// operate only on a blob if it has not been modified since the specified date/time. ifMatches is specify an ETag value +// to operate only on blobs with a matching value. ifNoneMatch is specify an ETag value to operate only on blobs +// without a matching value. requestID is provides a client-generated, opaque value with a 1 KB character limit that is +// recorded in the analytics logs when storage analytics logging is enabled. +func (client blobClient) AcquireLease(ctx context.Context, timeout *int32, duration *int32, proposedLeaseID *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (*BlobAcquireLeaseResponse, error) { + if err := validate([]validation{ + {targetValue: timeout, + constraints: []constraint{{target: "timeout", name: null, rule: false, + chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil { + return nil, err + } + req, err := client.acquireLeasePreparer(timeout, duration, proposedLeaseID, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestID) + if err != nil { + return nil, err + } + resp, err := client.Pipeline().Do(ctx, responderPolicyFactory{responder: client.acquireLeaseResponder}, req) + if err != nil { + return nil, err + } + return resp.(*BlobAcquireLeaseResponse), err +} + +// acquireLeasePreparer prepares the AcquireLease request. +func (client blobClient) acquireLeasePreparer(timeout *int32, duration *int32, proposedLeaseID *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (pipeline.Request, error) { + req, err := pipeline.NewRequest("PUT", client.url, nil) + if err != nil { + return req, pipeline.NewError(err, "failed to create request") + } + params := req.URL.Query() + if timeout != nil { + params.Set("timeout", strconv.FormatInt(int64(*timeout), 10)) + } + params.Set("comp", "lease") + req.URL.RawQuery = params.Encode() + if duration != nil { + req.Header.Set("x-ms-lease-duration", strconv.FormatInt(int64(*duration), 10)) + } + if proposedLeaseID != nil { + req.Header.Set("x-ms-proposed-lease-id", *proposedLeaseID) + } + if ifModifiedSince != nil { + req.Header.Set("If-Modified-Since", (*ifModifiedSince).In(gmt).Format(time.RFC1123)) + } + if ifUnmodifiedSince != nil { + req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123)) + } + if ifMatches != nil { + req.Header.Set("If-Match", string(*ifMatches)) + } + if ifNoneMatch != nil { + req.Header.Set("If-None-Match", string(*ifNoneMatch)) + } + req.Header.Set("x-ms-version", ServiceVersion) + if requestID != nil { + req.Header.Set("x-ms-client-request-id", *requestID) + } + req.Header.Set("x-ms-lease-action", "acquire") + return req, nil +} + +// acquireLeaseResponder handles the response to the AcquireLease request. +func (client blobClient) acquireLeaseResponder(resp pipeline.Response) (pipeline.Response, error) { + err := validateResponse(resp, http.StatusOK, http.StatusCreated) + if resp == nil { + return nil, err + } + io.Copy(ioutil.Discard, resp.Response().Body) + resp.Response().Body.Close() + return &BlobAcquireLeaseResponse{rawResponse: resp.Response()}, err +} + +// BreakLease [Update] The Lease Blob operation establishes and manages a lock on a blob for write and delete +// operations +// +// timeout is the timeout parameter is expressed in seconds. For more information, see Setting +// Timeouts for Blob Service Operations. breakPeriod is for a break operation, proposed duration the lease should +// continue before it is broken, in seconds, between 0 and 60. This break period is only used if it is shorter than the +// time remaining on the lease. If longer, the time remaining on the lease is used. A new lease will not be available +// before the break period has expired, but the lease may be held for longer than the break period. If this header does +// not appear with a break operation, a fixed-duration lease breaks after the remaining lease period elapses, and an +// infinite lease breaks immediately. ifModifiedSince is specify this header value to operate only on a blob if it has +// been modified since the specified date/time. ifUnmodifiedSince is specify this header value to operate only on a +// blob if it has not been modified since the specified date/time. ifMatches is specify an ETag value to operate only +// on blobs with a matching value. ifNoneMatch is specify an ETag value to operate only on blobs without a matching +// value. requestID is provides a client-generated, opaque value with a 1 KB character limit that is recorded in the +// analytics logs when storage analytics logging is enabled. +func (client blobClient) BreakLease(ctx context.Context, timeout *int32, breakPeriod *int32, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (*BlobBreakLeaseResponse, error) { + if err := validate([]validation{ + {targetValue: timeout, + constraints: []constraint{{target: "timeout", name: null, rule: false, + chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil { + return nil, err + } + req, err := client.breakLeasePreparer(timeout, breakPeriod, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestID) + if err != nil { + return nil, err + } + resp, err := client.Pipeline().Do(ctx, responderPolicyFactory{responder: client.breakLeaseResponder}, req) + if err != nil { + return nil, err + } + return resp.(*BlobBreakLeaseResponse), err +} + +// breakLeasePreparer prepares the BreakLease request. +func (client blobClient) breakLeasePreparer(timeout *int32, breakPeriod *int32, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (pipeline.Request, error) { + req, err := pipeline.NewRequest("PUT", client.url, nil) + if err != nil { + return req, pipeline.NewError(err, "failed to create request") + } + params := req.URL.Query() + if timeout != nil { + params.Set("timeout", strconv.FormatInt(int64(*timeout), 10)) + } + params.Set("comp", "lease") + req.URL.RawQuery = params.Encode() + if breakPeriod != nil { + req.Header.Set("x-ms-lease-break-period", strconv.FormatInt(int64(*breakPeriod), 10)) + } + if ifModifiedSince != nil { + req.Header.Set("If-Modified-Since", (*ifModifiedSince).In(gmt).Format(time.RFC1123)) + } + if ifUnmodifiedSince != nil { + req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123)) + } + if ifMatches != nil { + req.Header.Set("If-Match", string(*ifMatches)) + } + if ifNoneMatch != nil { + req.Header.Set("If-None-Match", string(*ifNoneMatch)) + } + req.Header.Set("x-ms-version", ServiceVersion) + if requestID != nil { + req.Header.Set("x-ms-client-request-id", *requestID) + } + req.Header.Set("x-ms-lease-action", "break") + return req, nil +} + +// breakLeaseResponder handles the response to the BreakLease request. +func (client blobClient) breakLeaseResponder(resp pipeline.Response) (pipeline.Response, error) { + err := validateResponse(resp, http.StatusOK, http.StatusAccepted) + if resp == nil { + return nil, err + } + io.Copy(ioutil.Discard, resp.Response().Body) + resp.Response().Body.Close() + return &BlobBreakLeaseResponse{rawResponse: resp.Response()}, err +} + +// ChangeLease [Update] The Lease Blob operation establishes and manages a lock on a blob for write and delete +// operations +// +// leaseID is if specified, the operation only succeeds if the container's lease is active and matches this ID. +// proposedLeaseID is proposed lease ID, in a GUID string format. The Blob service returns 400 (Invalid request) if the +// proposed lease ID is not in the correct format. See Guid Constructor (String) for a list of valid GUID string +// formats. timeout is the timeout parameter is expressed in seconds. For more information, see Setting +// Timeouts for Blob Service Operations. ifModifiedSince is specify this header value to operate only on a blob if +// it has been modified since the specified date/time. ifUnmodifiedSince is specify this header value to operate only +// on a blob if it has not been modified since the specified date/time. ifMatches is specify an ETag value to operate +// only on blobs with a matching value. ifNoneMatch is specify an ETag value to operate only on blobs without a +// matching value. requestID is provides a client-generated, opaque value with a 1 KB character limit that is recorded +// in the analytics logs when storage analytics logging is enabled. +func (client blobClient) ChangeLease(ctx context.Context, leaseID string, proposedLeaseID string, timeout *int32, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (*BlobChangeLeaseResponse, error) { + if err := validate([]validation{ + {targetValue: timeout, + constraints: []constraint{{target: "timeout", name: null, rule: false, + chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil { + return nil, err + } + req, err := client.changeLeasePreparer(leaseID, proposedLeaseID, timeout, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestID) + if err != nil { + return nil, err + } + resp, err := client.Pipeline().Do(ctx, responderPolicyFactory{responder: client.changeLeaseResponder}, req) + if err != nil { + return nil, err + } + return resp.(*BlobChangeLeaseResponse), err +} + +// changeLeasePreparer prepares the ChangeLease request. +func (client blobClient) changeLeasePreparer(leaseID string, proposedLeaseID string, timeout *int32, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (pipeline.Request, error) { + req, err := pipeline.NewRequest("PUT", client.url, nil) + if err != nil { + return req, pipeline.NewError(err, "failed to create request") + } + params := req.URL.Query() + if timeout != nil { + params.Set("timeout", strconv.FormatInt(int64(*timeout), 10)) + } + params.Set("comp", "lease") + req.URL.RawQuery = params.Encode() + req.Header.Set("x-ms-lease-id", leaseID) + req.Header.Set("x-ms-proposed-lease-id", proposedLeaseID) + if ifModifiedSince != nil { + req.Header.Set("If-Modified-Since", (*ifModifiedSince).In(gmt).Format(time.RFC1123)) + } + if ifUnmodifiedSince != nil { + req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123)) + } + if ifMatches != nil { + req.Header.Set("If-Match", string(*ifMatches)) + } + if ifNoneMatch != nil { + req.Header.Set("If-None-Match", string(*ifNoneMatch)) + } + req.Header.Set("x-ms-version", ServiceVersion) + if requestID != nil { + req.Header.Set("x-ms-client-request-id", *requestID) + } + req.Header.Set("x-ms-lease-action", "change") + return req, nil +} + +// changeLeaseResponder handles the response to the ChangeLease request. +func (client blobClient) changeLeaseResponder(resp pipeline.Response) (pipeline.Response, error) { + err := validateResponse(resp, http.StatusOK) + if resp == nil { + return nil, err + } + io.Copy(ioutil.Discard, resp.Response().Body) + resp.Response().Body.Close() + return &BlobChangeLeaseResponse{rawResponse: resp.Response()}, err +} + +// CreateSnapshot the Create Snapshot operation creates a read-only snapshot of a blob +// +// timeout is the timeout parameter is expressed in seconds. For more information, see Setting +// Timeouts for Blob Service Operations. metadata is optional. Specifies a user-defined name-value pair associated +// with the blob. If no name-value pairs are specified, the operation will copy the metadata from the source blob or +// file to the destination blob. If one or more name-value pairs are specified, the destination blob is created with +// the specified metadata, and metadata is not copied from the source blob or file. Note that beginning with version +// 2009-09-19, metadata names must adhere to the naming rules for C# identifiers. See Naming and Referencing +// Containers, Blobs, and Metadata for more information. ifModifiedSince is specify this header value to operate only +// on a blob if it has been modified since the specified date/time. ifUnmodifiedSince is specify this header value to +// operate only on a blob if it has not been modified since the specified date/time. ifMatches is specify an ETag value +// to operate only on blobs with a matching value. ifNoneMatch is specify an ETag value to operate only on blobs +// without a matching value. leaseID is if specified, the operation only succeeds if the container's lease is active +// and matches this ID. requestID is provides a client-generated, opaque value with a 1 KB character limit that is +// recorded in the analytics logs when storage analytics logging is enabled. +func (client blobClient) CreateSnapshot(ctx context.Context, timeout *int32, metadata map[string]string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, leaseID *string, requestID *string) (*BlobCreateSnapshotResponse, error) { + if err := validate([]validation{ + {targetValue: timeout, + constraints: []constraint{{target: "timeout", name: null, rule: false, + chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}, + {targetValue: metadata, + constraints: []constraint{{target: "metadata", name: null, rule: false, + chain: []constraint{{target: "metadata", name: pattern, rule: `^[a-zA-Z]+$`, chain: nil}}}}}}); err != nil { + return nil, err + } + req, err := client.createSnapshotPreparer(timeout, metadata, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, leaseID, requestID) + if err != nil { + return nil, err + } + resp, err := client.Pipeline().Do(ctx, responderPolicyFactory{responder: client.createSnapshotResponder}, req) + if err != nil { + return nil, err + } + return resp.(*BlobCreateSnapshotResponse), err +} + +// createSnapshotPreparer prepares the CreateSnapshot request. +func (client blobClient) createSnapshotPreparer(timeout *int32, metadata map[string]string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, leaseID *string, requestID *string) (pipeline.Request, error) { + req, err := pipeline.NewRequest("PUT", client.url, nil) + if err != nil { + return req, pipeline.NewError(err, "failed to create request") + } + params := req.URL.Query() + if timeout != nil { + params.Set("timeout", strconv.FormatInt(int64(*timeout), 10)) + } + params.Set("comp", "snapshot") + req.URL.RawQuery = params.Encode() + if metadata != nil { + for k, v := range metadata { + req.Header.Set("x-ms-meta-"+k, v) + } + } + if ifModifiedSince != nil { + req.Header.Set("If-Modified-Since", (*ifModifiedSince).In(gmt).Format(time.RFC1123)) + } + if ifUnmodifiedSince != nil { + req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123)) + } + if ifMatches != nil { + req.Header.Set("If-Match", string(*ifMatches)) + } + if ifNoneMatch != nil { + req.Header.Set("If-None-Match", string(*ifNoneMatch)) + } + if leaseID != nil { + req.Header.Set("x-ms-lease-id", *leaseID) + } + req.Header.Set("x-ms-version", ServiceVersion) + if requestID != nil { + req.Header.Set("x-ms-client-request-id", *requestID) + } + return req, nil +} + +// createSnapshotResponder handles the response to the CreateSnapshot request. +func (client blobClient) createSnapshotResponder(resp pipeline.Response) (pipeline.Response, error) { + err := validateResponse(resp, http.StatusOK, http.StatusCreated) + if resp == nil { + return nil, err + } + io.Copy(ioutil.Discard, resp.Response().Body) + resp.Response().Body.Close() + return &BlobCreateSnapshotResponse{rawResponse: resp.Response()}, err +} + +// Delete if the storage account's soft delete feature is disabled then, when a blob is deleted, it is permanently +// removed from the storage account. If the storage account's soft delete feature is enabled, then, when a blob is +// deleted, it is marked for deletion and becomes inaccessible immediately. However, the blob service retains the blob +// or snapshot for the number of days specified by the DeleteRetentionPolicy section of [Storage service properties] +// (Set-Blob-Service-Properties.md). After the specified number of days has passed, the blob's data is permanently +// removed from the storage account. Note that you continue to be charged for the soft-deleted blob's storage until it +// is permanently removed. Use the List Blobs API and specify the "include=deleted" query parameter to discover which +// blobs and snapshots have been soft deleted. You can then use the Undelete Blob API to restore a soft-deleted blob. +// All other operations on a soft-deleted blob or snapshot causes the service to return an HTTP status code of 404 +// (ResourceNotFound). +// +// snapshot is the snapshot parameter is an opaque DateTime value that, when present, specifies the blob snapshot to +// retrieve. For more information on working with blob snapshots, see Creating +// a Snapshot of a Blob. timeout is the timeout parameter is expressed in seconds. For more information, see Setting +// Timeouts for Blob Service Operations. leaseID is if specified, the operation only succeeds if the container's +// lease is active and matches this ID. deleteSnapshots is required if the blob has associated snapshots. Specify one +// of the following two options: include: Delete the base blob and all of its snapshots. only: Delete only the blob's +// snapshots and not the blob itself ifModifiedSince is specify this header value to operate only on a blob if it has +// been modified since the specified date/time. ifUnmodifiedSince is specify this header value to operate only on a +// blob if it has not been modified since the specified date/time. ifMatches is specify an ETag value to operate only +// on blobs with a matching value. ifNoneMatch is specify an ETag value to operate only on blobs without a matching +// value. requestID is provides a client-generated, opaque value with a 1 KB character limit that is recorded in the +// analytics logs when storage analytics logging is enabled. +func (client blobClient) Delete(ctx context.Context, snapshot *string, timeout *int32, leaseID *string, deleteSnapshots DeleteSnapshotsOptionType, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (*BlobDeleteResponse, error) { + if err := validate([]validation{ + {targetValue: timeout, + constraints: []constraint{{target: "timeout", name: null, rule: false, + chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil { + return nil, err + } + req, err := client.deletePreparer(snapshot, timeout, leaseID, deleteSnapshots, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestID) + if err != nil { + return nil, err + } + resp, err := client.Pipeline().Do(ctx, responderPolicyFactory{responder: client.deleteResponder}, req) + if err != nil { + return nil, err + } + return resp.(*BlobDeleteResponse), err +} + +// deletePreparer prepares the Delete request. +func (client blobClient) deletePreparer(snapshot *string, timeout *int32, leaseID *string, deleteSnapshots DeleteSnapshotsOptionType, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (pipeline.Request, error) { + req, err := pipeline.NewRequest("DELETE", client.url, nil) + if err != nil { + return req, pipeline.NewError(err, "failed to create request") + } + params := req.URL.Query() + if snapshot != nil && len(*snapshot) > 0 { + params.Set("snapshot", *snapshot) + } + if timeout != nil { + params.Set("timeout", strconv.FormatInt(int64(*timeout), 10)) + } + req.URL.RawQuery = params.Encode() + if leaseID != nil { + req.Header.Set("x-ms-lease-id", *leaseID) + } + if deleteSnapshots != DeleteSnapshotsOptionNone { + req.Header.Set("x-ms-delete-snapshots", string(deleteSnapshots)) + } + if ifModifiedSince != nil { + req.Header.Set("If-Modified-Since", (*ifModifiedSince).In(gmt).Format(time.RFC1123)) + } + if ifUnmodifiedSince != nil { + req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123)) + } + if ifMatches != nil { + req.Header.Set("If-Match", string(*ifMatches)) + } + if ifNoneMatch != nil { + req.Header.Set("If-None-Match", string(*ifNoneMatch)) + } + req.Header.Set("x-ms-version", ServiceVersion) + if requestID != nil { + req.Header.Set("x-ms-client-request-id", *requestID) + } + return req, nil +} + +// deleteResponder handles the response to the Delete request. +func (client blobClient) deleteResponder(resp pipeline.Response) (pipeline.Response, error) { + err := validateResponse(resp, http.StatusOK, http.StatusAccepted) + if resp == nil { + return nil, err + } + io.Copy(ioutil.Discard, resp.Response().Body) + resp.Response().Body.Close() + return &BlobDeleteResponse{rawResponse: resp.Response()}, err +} + +// Download the Download operation reads or downloads a blob from the system, including its metadata and properties. +// You can also call Download to read a snapshot. +// +// snapshot is the snapshot parameter is an opaque DateTime value that, when present, specifies the blob snapshot to +// retrieve. For more information on working with blob snapshots, see Creating +// a Snapshot of a Blob. timeout is the timeout parameter is expressed in seconds. For more information, see Setting +// Timeouts for Blob Service Operations. rangeParameter is return only the bytes of the blob in the specified +// range. leaseID is if specified, the operation only succeeds if the container's lease is active and matches this ID. +// rangeGetContentMD5 is when set to true and specified together with the Range, the service returns the MD5 hash for +// the range, as long as the range is less than or equal to 4 MB in size. ifModifiedSince is specify this header value +// to operate only on a blob if it has been modified since the specified date/time. ifUnmodifiedSince is specify this +// header value to operate only on a blob if it has not been modified since the specified date/time. ifMatches is +// specify an ETag value to operate only on blobs with a matching value. ifNoneMatch is specify an ETag value to +// operate only on blobs without a matching value. requestID is provides a client-generated, opaque value with a 1 KB +// character limit that is recorded in the analytics logs when storage analytics logging is enabled. +func (client blobClient) Download(ctx context.Context, snapshot *string, timeout *int32, rangeParameter *string, leaseID *string, rangeGetContentMD5 *bool, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (*downloadResponse, error) { + if err := validate([]validation{ + {targetValue: timeout, + constraints: []constraint{{target: "timeout", name: null, rule: false, + chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil { + return nil, err + } + req, err := client.downloadPreparer(snapshot, timeout, rangeParameter, leaseID, rangeGetContentMD5, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestID) + if err != nil { + return nil, err + } + resp, err := client.Pipeline().Do(ctx, responderPolicyFactory{responder: client.downloadResponder}, req) + if err != nil { + return nil, err + } + return resp.(*downloadResponse), err +} + +// downloadPreparer prepares the Download request. +func (client blobClient) downloadPreparer(snapshot *string, timeout *int32, rangeParameter *string, leaseID *string, rangeGetContentMD5 *bool, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (pipeline.Request, error) { + req, err := pipeline.NewRequest("GET", client.url, nil) + if err != nil { + return req, pipeline.NewError(err, "failed to create request") + } + params := req.URL.Query() + if snapshot != nil && len(*snapshot) > 0 { + params.Set("snapshot", *snapshot) + } + if timeout != nil { + params.Set("timeout", strconv.FormatInt(int64(*timeout), 10)) + } + req.URL.RawQuery = params.Encode() + if rangeParameter != nil { + req.Header.Set("x-ms-range", *rangeParameter) + } + if leaseID != nil { + req.Header.Set("x-ms-lease-id", *leaseID) + } + if rangeGetContentMD5 != nil { + req.Header.Set("x-ms-range-get-content-md5", strconv.FormatBool(*rangeGetContentMD5)) + } + if ifModifiedSince != nil { + req.Header.Set("If-Modified-Since", (*ifModifiedSince).In(gmt).Format(time.RFC1123)) + } + if ifUnmodifiedSince != nil { + req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123)) + } + if ifMatches != nil { + req.Header.Set("If-Match", string(*ifMatches)) + } + if ifNoneMatch != nil { + req.Header.Set("If-None-Match", string(*ifNoneMatch)) + } + req.Header.Set("x-ms-version", ServiceVersion) + if requestID != nil { + req.Header.Set("x-ms-client-request-id", *requestID) + } + return req, nil +} + +// downloadResponder handles the response to the Download request. +func (client blobClient) downloadResponder(resp pipeline.Response) (pipeline.Response, error) { + err := validateResponse(resp, http.StatusOK, http.StatusPartialContent) + if resp == nil { + return nil, err + } + return &downloadResponse{rawResponse: resp.Response()}, err +} + +// GetProperties the Get Properties operation returns all user-defined metadata, standard HTTP properties, and system +// properties for the blob. It does not return the content of the blob. +// +// snapshot is the snapshot parameter is an opaque DateTime value that, when present, specifies the blob snapshot to +// retrieve. For more information on working with blob snapshots, see Creating +// a Snapshot of a Blob. timeout is the timeout parameter is expressed in seconds. For more information, see Setting +// Timeouts for Blob Service Operations. leaseID is if specified, the operation only succeeds if the container's +// lease is active and matches this ID. ifModifiedSince is specify this header value to operate only on a blob if it +// has been modified since the specified date/time. ifUnmodifiedSince is specify this header value to operate only on a +// blob if it has not been modified since the specified date/time. ifMatches is specify an ETag value to operate only +// on blobs with a matching value. ifNoneMatch is specify an ETag value to operate only on blobs without a matching +// value. requestID is provides a client-generated, opaque value with a 1 KB character limit that is recorded in the +// analytics logs when storage analytics logging is enabled. +func (client blobClient) GetProperties(ctx context.Context, snapshot *string, timeout *int32, leaseID *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (*BlobGetPropertiesResponse, error) { + if err := validate([]validation{ + {targetValue: timeout, + constraints: []constraint{{target: "timeout", name: null, rule: false, + chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil { + return nil, err + } + req, err := client.getPropertiesPreparer(snapshot, timeout, leaseID, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestID) + if err != nil { + return nil, err + } + resp, err := client.Pipeline().Do(ctx, responderPolicyFactory{responder: client.getPropertiesResponder}, req) + if err != nil { + return nil, err + } + return resp.(*BlobGetPropertiesResponse), err +} + +// getPropertiesPreparer prepares the GetProperties request. +func (client blobClient) getPropertiesPreparer(snapshot *string, timeout *int32, leaseID *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (pipeline.Request, error) { + req, err := pipeline.NewRequest("HEAD", client.url, nil) + if err != nil { + return req, pipeline.NewError(err, "failed to create request") + } + params := req.URL.Query() + if snapshot != nil && len(*snapshot) > 0 { + params.Set("snapshot", *snapshot) + } + if timeout != nil { + params.Set("timeout", strconv.FormatInt(int64(*timeout), 10)) + } + req.URL.RawQuery = params.Encode() + if leaseID != nil { + req.Header.Set("x-ms-lease-id", *leaseID) + } + if ifModifiedSince != nil { + req.Header.Set("If-Modified-Since", (*ifModifiedSince).In(gmt).Format(time.RFC1123)) + } + if ifUnmodifiedSince != nil { + req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123)) + } + if ifMatches != nil { + req.Header.Set("If-Match", string(*ifMatches)) + } + if ifNoneMatch != nil { + req.Header.Set("If-None-Match", string(*ifNoneMatch)) + } + req.Header.Set("x-ms-version", ServiceVersion) + if requestID != nil { + req.Header.Set("x-ms-client-request-id", *requestID) + } + return req, nil +} + +// getPropertiesResponder handles the response to the GetProperties request. +func (client blobClient) getPropertiesResponder(resp pipeline.Response) (pipeline.Response, error) { + err := validateResponse(resp, http.StatusOK) + if resp == nil { + return nil, err + } + io.Copy(ioutil.Discard, resp.Response().Body) + resp.Response().Body.Close() + return &BlobGetPropertiesResponse{rawResponse: resp.Response()}, err +} + +// ReleaseLease [Update] The Lease Blob operation establishes and manages a lock on a blob for write and delete +// operations +// +// leaseID is if specified, the operation only succeeds if the container's lease is active and matches this ID. timeout +// is the timeout parameter is expressed in seconds. For more information, see Setting +// Timeouts for Blob Service Operations. ifModifiedSince is specify this header value to operate only on a blob if +// it has been modified since the specified date/time. ifUnmodifiedSince is specify this header value to operate only +// on a blob if it has not been modified since the specified date/time. ifMatches is specify an ETag value to operate +// only on blobs with a matching value. ifNoneMatch is specify an ETag value to operate only on blobs without a +// matching value. requestID is provides a client-generated, opaque value with a 1 KB character limit that is recorded +// in the analytics logs when storage analytics logging is enabled. +func (client blobClient) ReleaseLease(ctx context.Context, leaseID string, timeout *int32, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (*BlobReleaseLeaseResponse, error) { + if err := validate([]validation{ + {targetValue: timeout, + constraints: []constraint{{target: "timeout", name: null, rule: false, + chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil { + return nil, err + } + req, err := client.releaseLeasePreparer(leaseID, timeout, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestID) + if err != nil { + return nil, err + } + resp, err := client.Pipeline().Do(ctx, responderPolicyFactory{responder: client.releaseLeaseResponder}, req) + if err != nil { + return nil, err + } + return resp.(*BlobReleaseLeaseResponse), err +} + +// releaseLeasePreparer prepares the ReleaseLease request. +func (client blobClient) releaseLeasePreparer(leaseID string, timeout *int32, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (pipeline.Request, error) { + req, err := pipeline.NewRequest("PUT", client.url, nil) + if err != nil { + return req, pipeline.NewError(err, "failed to create request") + } + params := req.URL.Query() + if timeout != nil { + params.Set("timeout", strconv.FormatInt(int64(*timeout), 10)) + } + params.Set("comp", "lease") + req.URL.RawQuery = params.Encode() + req.Header.Set("x-ms-lease-id", leaseID) + if ifModifiedSince != nil { + req.Header.Set("If-Modified-Since", (*ifModifiedSince).In(gmt).Format(time.RFC1123)) + } + if ifUnmodifiedSince != nil { + req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123)) + } + if ifMatches != nil { + req.Header.Set("If-Match", string(*ifMatches)) + } + if ifNoneMatch != nil { + req.Header.Set("If-None-Match", string(*ifNoneMatch)) + } + req.Header.Set("x-ms-version", ServiceVersion) + if requestID != nil { + req.Header.Set("x-ms-client-request-id", *requestID) + } + req.Header.Set("x-ms-lease-action", "release") + return req, nil +} + +// releaseLeaseResponder handles the response to the ReleaseLease request. +func (client blobClient) releaseLeaseResponder(resp pipeline.Response) (pipeline.Response, error) { + err := validateResponse(resp, http.StatusOK) + if resp == nil { + return nil, err + } + io.Copy(ioutil.Discard, resp.Response().Body) + resp.Response().Body.Close() + return &BlobReleaseLeaseResponse{rawResponse: resp.Response()}, err +} + +// RenewLease [Update] The Lease Blob operation establishes and manages a lock on a blob for write and delete +// operations +// +// leaseID is if specified, the operation only succeeds if the container's lease is active and matches this ID. timeout +// is the timeout parameter is expressed in seconds. For more information, see Setting +// Timeouts for Blob Service Operations. ifModifiedSince is specify this header value to operate only on a blob if +// it has been modified since the specified date/time. ifUnmodifiedSince is specify this header value to operate only +// on a blob if it has not been modified since the specified date/time. ifMatches is specify an ETag value to operate +// only on blobs with a matching value. ifNoneMatch is specify an ETag value to operate only on blobs without a +// matching value. requestID is provides a client-generated, opaque value with a 1 KB character limit that is recorded +// in the analytics logs when storage analytics logging is enabled. +func (client blobClient) RenewLease(ctx context.Context, leaseID string, timeout *int32, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (*BlobRenewLeaseResponse, error) { + if err := validate([]validation{ + {targetValue: timeout, + constraints: []constraint{{target: "timeout", name: null, rule: false, + chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil { + return nil, err + } + req, err := client.renewLeasePreparer(leaseID, timeout, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestID) + if err != nil { + return nil, err + } + resp, err := client.Pipeline().Do(ctx, responderPolicyFactory{responder: client.renewLeaseResponder}, req) + if err != nil { + return nil, err + } + return resp.(*BlobRenewLeaseResponse), err +} + +// renewLeasePreparer prepares the RenewLease request. +func (client blobClient) renewLeasePreparer(leaseID string, timeout *int32, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (pipeline.Request, error) { + req, err := pipeline.NewRequest("PUT", client.url, nil) + if err != nil { + return req, pipeline.NewError(err, "failed to create request") + } + params := req.URL.Query() + if timeout != nil { + params.Set("timeout", strconv.FormatInt(int64(*timeout), 10)) + } + params.Set("comp", "lease") + req.URL.RawQuery = params.Encode() + req.Header.Set("x-ms-lease-id", leaseID) + if ifModifiedSince != nil { + req.Header.Set("If-Modified-Since", (*ifModifiedSince).In(gmt).Format(time.RFC1123)) + } + if ifUnmodifiedSince != nil { + req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123)) + } + if ifMatches != nil { + req.Header.Set("If-Match", string(*ifMatches)) + } + if ifNoneMatch != nil { + req.Header.Set("If-None-Match", string(*ifNoneMatch)) + } + req.Header.Set("x-ms-version", ServiceVersion) + if requestID != nil { + req.Header.Set("x-ms-client-request-id", *requestID) + } + req.Header.Set("x-ms-lease-action", "renew") + return req, nil +} + +// renewLeaseResponder handles the response to the RenewLease request. +func (client blobClient) renewLeaseResponder(resp pipeline.Response) (pipeline.Response, error) { + err := validateResponse(resp, http.StatusOK) + if resp == nil { + return nil, err + } + io.Copy(ioutil.Discard, resp.Response().Body) + resp.Response().Body.Close() + return &BlobRenewLeaseResponse{rawResponse: resp.Response()}, err +} + +// SetHTTPHeaders the Set HTTP Headers operation sets system properties on the blob +// +// timeout is the timeout parameter is expressed in seconds. For more information, see Setting +// Timeouts for Blob Service Operations. blobCacheControl is optional. Sets the blob's cache control. If specified, +// this property is stored with the blob and returned with a read request. blobContentType is optional. Sets the blob's +// content type. If specified, this property is stored with the blob and returned with a read request. blobContentMD5 +// is optional. An MD5 hash of the blob content. Note that this hash is not validated, as the hashes for the individual +// blocks were validated when each was uploaded. blobContentEncoding is optional. Sets the blob's content encoding. If +// specified, this property is stored with the blob and returned with a read request. blobContentLanguage is optional. +// Set the blob's content language. If specified, this property is stored with the blob and returned with a read +// request. leaseID is if specified, the operation only succeeds if the container's lease is active and matches this +// ID. ifModifiedSince is specify this header value to operate only on a blob if it has been modified since the +// specified date/time. ifUnmodifiedSince is specify this header value to operate only on a blob if it has not been +// modified since the specified date/time. ifMatches is specify an ETag value to operate only on blobs with a matching +// value. ifNoneMatch is specify an ETag value to operate only on blobs without a matching value. +// blobContentDisposition is optional. Sets the blob's Content-Disposition header. requestID is provides a +// client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage +// analytics logging is enabled. +func (client blobClient) SetHTTPHeaders(ctx context.Context, timeout *int32, blobCacheControl *string, blobContentType *string, blobContentMD5 []byte, blobContentEncoding *string, blobContentLanguage *string, leaseID *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, blobContentDisposition *string, requestID *string) (*BlobSetHTTPHeadersResponse, error) { + if err := validate([]validation{ + {targetValue: timeout, + constraints: []constraint{{target: "timeout", name: null, rule: false, + chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil { + return nil, err + } + req, err := client.setHTTPHeadersPreparer(timeout, blobCacheControl, blobContentType, blobContentMD5, blobContentEncoding, blobContentLanguage, leaseID, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, blobContentDisposition, requestID) + if err != nil { + return nil, err + } + resp, err := client.Pipeline().Do(ctx, responderPolicyFactory{responder: client.setHTTPHeadersResponder}, req) + if err != nil { + return nil, err + } + return resp.(*BlobSetHTTPHeadersResponse), err +} + +// setHTTPHeadersPreparer prepares the SetHTTPHeaders request. +func (client blobClient) setHTTPHeadersPreparer(timeout *int32, blobCacheControl *string, blobContentType *string, blobContentMD5 []byte, blobContentEncoding *string, blobContentLanguage *string, leaseID *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, blobContentDisposition *string, requestID *string) (pipeline.Request, error) { + req, err := pipeline.NewRequest("PUT", client.url, nil) + if err != nil { + return req, pipeline.NewError(err, "failed to create request") + } + params := req.URL.Query() + if timeout != nil { + params.Set("timeout", strconv.FormatInt(int64(*timeout), 10)) + } + params.Set("comp", "properties") + req.URL.RawQuery = params.Encode() + if blobCacheControl != nil { + req.Header.Set("x-ms-blob-cache-control", *blobCacheControl) + } + if blobContentType != nil { + req.Header.Set("x-ms-blob-content-type", *blobContentType) + } + if blobContentMD5 != nil { + req.Header.Set("x-ms-blob-content-md5", base64.StdEncoding.EncodeToString(blobContentMD5)) + } + if blobContentEncoding != nil { + req.Header.Set("x-ms-blob-content-encoding", *blobContentEncoding) + } + if blobContentLanguage != nil { + req.Header.Set("x-ms-blob-content-language", *blobContentLanguage) + } + if leaseID != nil { + req.Header.Set("x-ms-lease-id", *leaseID) + } + if ifModifiedSince != nil { + req.Header.Set("If-Modified-Since", (*ifModifiedSince).In(gmt).Format(time.RFC1123)) + } + if ifUnmodifiedSince != nil { + req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123)) + } + if ifMatches != nil { + req.Header.Set("If-Match", string(*ifMatches)) + } + if ifNoneMatch != nil { + req.Header.Set("If-None-Match", string(*ifNoneMatch)) + } + if blobContentDisposition != nil { + req.Header.Set("x-ms-blob-content-disposition", *blobContentDisposition) + } + req.Header.Set("x-ms-version", ServiceVersion) + if requestID != nil { + req.Header.Set("x-ms-client-request-id", *requestID) + } + return req, nil +} + +// setHTTPHeadersResponder handles the response to the SetHTTPHeaders request. +func (client blobClient) setHTTPHeadersResponder(resp pipeline.Response) (pipeline.Response, error) { + err := validateResponse(resp, http.StatusOK) + if resp == nil { + return nil, err + } + io.Copy(ioutil.Discard, resp.Response().Body) + resp.Response().Body.Close() + return &BlobSetHTTPHeadersResponse{rawResponse: resp.Response()}, err +} + +// SetMetadata the Set Blob Metadata operation sets user-defined metadata for the specified blob as one or more +// name-value pairs +// +// timeout is the timeout parameter is expressed in seconds. For more information, see Setting +// Timeouts for Blob Service Operations. metadata is optional. Specifies a user-defined name-value pair associated +// with the blob. If no name-value pairs are specified, the operation will copy the metadata from the source blob or +// file to the destination blob. If one or more name-value pairs are specified, the destination blob is created with +// the specified metadata, and metadata is not copied from the source blob or file. Note that beginning with version +// 2009-09-19, metadata names must adhere to the naming rules for C# identifiers. See Naming and Referencing +// Containers, Blobs, and Metadata for more information. leaseID is if specified, the operation only succeeds if the +// container's lease is active and matches this ID. ifModifiedSince is specify this header value to operate only on a +// blob if it has been modified since the specified date/time. ifUnmodifiedSince is specify this header value to +// operate only on a blob if it has not been modified since the specified date/time. ifMatches is specify an ETag value +// to operate only on blobs with a matching value. ifNoneMatch is specify an ETag value to operate only on blobs +// without a matching value. requestID is provides a client-generated, opaque value with a 1 KB character limit that is +// recorded in the analytics logs when storage analytics logging is enabled. +func (client blobClient) SetMetadata(ctx context.Context, timeout *int32, metadata map[string]string, leaseID *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (*BlobSetMetadataResponse, error) { + if err := validate([]validation{ + {targetValue: timeout, + constraints: []constraint{{target: "timeout", name: null, rule: false, + chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}, + {targetValue: metadata, + constraints: []constraint{{target: "metadata", name: null, rule: false, + chain: []constraint{{target: "metadata", name: pattern, rule: `^[a-zA-Z]+$`, chain: nil}}}}}}); err != nil { + return nil, err + } + req, err := client.setMetadataPreparer(timeout, metadata, leaseID, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestID) + if err != nil { + return nil, err + } + resp, err := client.Pipeline().Do(ctx, responderPolicyFactory{responder: client.setMetadataResponder}, req) + if err != nil { + return nil, err + } + return resp.(*BlobSetMetadataResponse), err +} + +// setMetadataPreparer prepares the SetMetadata request. +func (client blobClient) setMetadataPreparer(timeout *int32, metadata map[string]string, leaseID *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (pipeline.Request, error) { + req, err := pipeline.NewRequest("PUT", client.url, nil) + if err != nil { + return req, pipeline.NewError(err, "failed to create request") + } + params := req.URL.Query() + if timeout != nil { + params.Set("timeout", strconv.FormatInt(int64(*timeout), 10)) + } + params.Set("comp", "metadata") + req.URL.RawQuery = params.Encode() + if metadata != nil { + for k, v := range metadata { + req.Header.Set("x-ms-meta-"+k, v) + } + } + if leaseID != nil { + req.Header.Set("x-ms-lease-id", *leaseID) + } + if ifModifiedSince != nil { + req.Header.Set("If-Modified-Since", (*ifModifiedSince).In(gmt).Format(time.RFC1123)) + } + if ifUnmodifiedSince != nil { + req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123)) + } + if ifMatches != nil { + req.Header.Set("If-Match", string(*ifMatches)) + } + if ifNoneMatch != nil { + req.Header.Set("If-None-Match", string(*ifNoneMatch)) + } + req.Header.Set("x-ms-version", ServiceVersion) + if requestID != nil { + req.Header.Set("x-ms-client-request-id", *requestID) + } + return req, nil +} + +// setMetadataResponder handles the response to the SetMetadata request. +func (client blobClient) setMetadataResponder(resp pipeline.Response) (pipeline.Response, error) { + err := validateResponse(resp, http.StatusOK) + if resp == nil { + return nil, err + } + io.Copy(ioutil.Discard, resp.Response().Body) + resp.Response().Body.Close() + return &BlobSetMetadataResponse{rawResponse: resp.Response()}, err +} + +// SetTier the Set Tier operation sets the tier on a blob. The operation is allowed on a page blob in a premium storage +// account and on a block blob in a blob storage account (locally redundant storage only). A premium page blob's tier +// determines the allowed size, IOPS, and bandwidth of the blob. A block blob's tier determines Hot/Cool/Archive +// storage type. This operation does not update the blob's ETag. +// +// tier is indicates the tier to be set on the blob. timeout is the timeout parameter is expressed in seconds. For more +// information, see Setting +// Timeouts for Blob Service Operations. requestID is provides a client-generated, opaque value with a 1 KB +// character limit that is recorded in the analytics logs when storage analytics logging is enabled. +func (client blobClient) SetTier(ctx context.Context, tier AccessTierType, timeout *int32, requestID *string) (*BlobSetTierResponse, error) { + if err := validate([]validation{ + {targetValue: timeout, + constraints: []constraint{{target: "timeout", name: null, rule: false, + chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil { + return nil, err + } + req, err := client.setTierPreparer(tier, timeout, requestID) + if err != nil { + return nil, err + } + resp, err := client.Pipeline().Do(ctx, responderPolicyFactory{responder: client.setTierResponder}, req) + if err != nil { + return nil, err + } + return resp.(*BlobSetTierResponse), err +} + +// setTierPreparer prepares the SetTier request. +func (client blobClient) setTierPreparer(tier AccessTierType, timeout *int32, requestID *string) (pipeline.Request, error) { + req, err := pipeline.NewRequest("PUT", client.url, nil) + if err != nil { + return req, pipeline.NewError(err, "failed to create request") + } + params := req.URL.Query() + if timeout != nil { + params.Set("timeout", strconv.FormatInt(int64(*timeout), 10)) + } + params.Set("comp", "tier") + req.URL.RawQuery = params.Encode() + req.Header.Set("x-ms-access-tier", string(tier)) + req.Header.Set("x-ms-version", ServiceVersion) + if requestID != nil { + req.Header.Set("x-ms-client-request-id", *requestID) + } + return req, nil +} + +// setTierResponder handles the response to the SetTier request. +func (client blobClient) setTierResponder(resp pipeline.Response) (pipeline.Response, error) { + err := validateResponse(resp, http.StatusOK, http.StatusAccepted) + if resp == nil { + return nil, err + } + io.Copy(ioutil.Discard, resp.Response().Body) + resp.Response().Body.Close() + return &BlobSetTierResponse{rawResponse: resp.Response()}, err +} + +// StartCopyFromURL the Start Copy From URL operation copies a blob or an internet resource to a new blob. +// +// copySource is specifies the name of the source page blob snapshot. This value is a URL of up to 2 KB in length that +// specifies a page blob snapshot. The value should be URL-encoded as it would appear in a request URI. The source blob +// must either be public or must be authenticated via a shared access signature. timeout is the timeout parameter is +// expressed in seconds. For more information, see Setting +// Timeouts for Blob Service Operations. metadata is optional. Specifies a user-defined name-value pair associated +// with the blob. If no name-value pairs are specified, the operation will copy the metadata from the source blob or +// file to the destination blob. If one or more name-value pairs are specified, the destination blob is created with +// the specified metadata, and metadata is not copied from the source blob or file. Note that beginning with version +// 2009-09-19, metadata names must adhere to the naming rules for C# identifiers. See Naming and Referencing +// Containers, Blobs, and Metadata for more information. sourceIfModifiedSince is specify this header value to operate +// only on a blob if it has been modified since the specified date/time. sourceIfUnmodifiedSince is specify this header +// value to operate only on a blob if it has not been modified since the specified date/time. sourceIfMatches is +// specify an ETag value to operate only on blobs with a matching value. sourceIfNoneMatch is specify an ETag value to +// operate only on blobs without a matching value. ifModifiedSince is specify this header value to operate only on a +// blob if it has been modified since the specified date/time. ifUnmodifiedSince is specify this header value to +// operate only on a blob if it has not been modified since the specified date/time. ifMatches is specify an ETag value +// to operate only on blobs with a matching value. ifNoneMatch is specify an ETag value to operate only on blobs +// without a matching value. leaseID is if specified, the operation only succeeds if the container's lease is active +// and matches this ID. sourceLeaseID is specify this header to perform the operation only if the lease ID given +// matches the active lease ID of the source blob. requestID is provides a client-generated, opaque value with a 1 KB +// character limit that is recorded in the analytics logs when storage analytics logging is enabled. +func (client blobClient) StartCopyFromURL(ctx context.Context, copySource string, timeout *int32, metadata map[string]string, sourceIfModifiedSince *time.Time, sourceIfUnmodifiedSince *time.Time, sourceIfMatches *ETag, sourceIfNoneMatch *ETag, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, leaseID *string, sourceLeaseID *string, requestID *string) (*BlobStartCopyFromURLResponse, error) { + if err := validate([]validation{ + {targetValue: timeout, + constraints: []constraint{{target: "timeout", name: null, rule: false, + chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}, + {targetValue: metadata, + constraints: []constraint{{target: "metadata", name: null, rule: false, + chain: []constraint{{target: "metadata", name: pattern, rule: `^[a-zA-Z]+$`, chain: nil}}}}}}); err != nil { + return nil, err + } + req, err := client.startCopyFromURLPreparer(copySource, timeout, metadata, sourceIfModifiedSince, sourceIfUnmodifiedSince, sourceIfMatches, sourceIfNoneMatch, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, leaseID, sourceLeaseID, requestID) + if err != nil { + return nil, err + } + resp, err := client.Pipeline().Do(ctx, responderPolicyFactory{responder: client.startCopyFromURLResponder}, req) + if err != nil { + return nil, err + } + return resp.(*BlobStartCopyFromURLResponse), err +} + +// startCopyFromURLPreparer prepares the StartCopyFromURL request. +func (client blobClient) startCopyFromURLPreparer(copySource string, timeout *int32, metadata map[string]string, sourceIfModifiedSince *time.Time, sourceIfUnmodifiedSince *time.Time, sourceIfMatches *ETag, sourceIfNoneMatch *ETag, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, leaseID *string, sourceLeaseID *string, requestID *string) (pipeline.Request, error) { + req, err := pipeline.NewRequest("PUT", client.url, nil) + if err != nil { + return req, pipeline.NewError(err, "failed to create request") + } + params := req.URL.Query() + if timeout != nil { + params.Set("timeout", strconv.FormatInt(int64(*timeout), 10)) + } + req.URL.RawQuery = params.Encode() + if metadata != nil { + for k, v := range metadata { + req.Header.Set("x-ms-meta-"+k, v) + } + } + if sourceIfModifiedSince != nil { + req.Header.Set("x-ms-source-if-modified-since", (*sourceIfModifiedSince).In(gmt).Format(time.RFC1123)) + } + if sourceIfUnmodifiedSince != nil { + req.Header.Set("x-ms-source-if-unmodified-since", (*sourceIfUnmodifiedSince).In(gmt).Format(time.RFC1123)) + } + if sourceIfMatches != nil { + req.Header.Set("x-ms-source-if-match", string(*sourceIfMatches)) + } + if sourceIfNoneMatch != nil { + req.Header.Set("x-ms-source-if-none-match", string(*sourceIfNoneMatch)) + } + if ifModifiedSince != nil { + req.Header.Set("If-Modified-Since", (*ifModifiedSince).In(gmt).Format(time.RFC1123)) + } + if ifUnmodifiedSince != nil { + req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123)) + } + if ifMatches != nil { + req.Header.Set("If-Match", string(*ifMatches)) + } + if ifNoneMatch != nil { + req.Header.Set("If-None-Match", string(*ifNoneMatch)) + } + req.Header.Set("x-ms-copy-source", copySource) + if leaseID != nil { + req.Header.Set("x-ms-lease-id", *leaseID) + } + if sourceLeaseID != nil { + req.Header.Set("x-ms-source-lease-id", *sourceLeaseID) + } + req.Header.Set("x-ms-version", ServiceVersion) + if requestID != nil { + req.Header.Set("x-ms-client-request-id", *requestID) + } + return req, nil +} + +// startCopyFromURLResponder handles the response to the StartCopyFromURL request. +func (client blobClient) startCopyFromURLResponder(resp pipeline.Response) (pipeline.Response, error) { + err := validateResponse(resp, http.StatusOK, http.StatusAccepted) + if resp == nil { + return nil, err + } + io.Copy(ioutil.Discard, resp.Response().Body) + resp.Response().Body.Close() + return &BlobStartCopyFromURLResponse{rawResponse: resp.Response()}, err +} + +// Undelete undelete a blob that was previously soft deleted +// +// timeout is the timeout parameter is expressed in seconds. For more information, see Setting +// Timeouts for Blob Service Operations. requestID is provides a client-generated, opaque value with a 1 KB +// character limit that is recorded in the analytics logs when storage analytics logging is enabled. +func (client blobClient) Undelete(ctx context.Context, timeout *int32, requestID *string) (*BlobUndeleteResponse, error) { + if err := validate([]validation{ + {targetValue: timeout, + constraints: []constraint{{target: "timeout", name: null, rule: false, + chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil { + return nil, err + } + req, err := client.undeletePreparer(timeout, requestID) + if err != nil { + return nil, err + } + resp, err := client.Pipeline().Do(ctx, responderPolicyFactory{responder: client.undeleteResponder}, req) + if err != nil { + return nil, err + } + return resp.(*BlobUndeleteResponse), err +} + +// undeletePreparer prepares the Undelete request. +func (client blobClient) undeletePreparer(timeout *int32, requestID *string) (pipeline.Request, error) { + req, err := pipeline.NewRequest("PUT", client.url, nil) + if err != nil { + return req, pipeline.NewError(err, "failed to create request") + } + params := req.URL.Query() + if timeout != nil { + params.Set("timeout", strconv.FormatInt(int64(*timeout), 10)) + } + params.Set("comp", "undelete") + req.URL.RawQuery = params.Encode() + req.Header.Set("x-ms-version", ServiceVersion) + if requestID != nil { + req.Header.Set("x-ms-client-request-id", *requestID) + } + return req, nil +} + +// undeleteResponder handles the response to the Undelete request. +func (client blobClient) undeleteResponder(resp pipeline.Response) (pipeline.Response, error) { + err := validateResponse(resp, http.StatusOK) + if resp == nil { + return nil, err + } + io.Copy(ioutil.Discard, resp.Response().Body) + resp.Response().Body.Close() + return &BlobUndeleteResponse{rawResponse: resp.Response()}, err +} diff --git a/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zz_generated_block_blob.go b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zz_generated_block_blob.go new file mode 100644 index 0000000000..4e75dcea33 --- /dev/null +++ b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zz_generated_block_blob.go @@ -0,0 +1,498 @@ +package azblob + +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "bytes" + "context" + "encoding/base64" + "encoding/xml" + "github.com/Azure/azure-pipeline-go/pipeline" + "io" + "io/ioutil" + "net/http" + "net/url" + "strconv" + "time" +) + +// blockBlobClient is the client for the BlockBlob methods of the Azblob service. +type blockBlobClient struct { + managementClient +} + +// newBlockBlobClient creates an instance of the blockBlobClient client. +func newBlockBlobClient(url url.URL, p pipeline.Pipeline) blockBlobClient { + return blockBlobClient{newManagementClient(url, p)} +} + +// CommitBlockList the Commit Block List operation writes a blob by specifying the list of block IDs that make up the +// blob. In order to be written as part of a blob, a block must have been successfully written to the server in a prior +// Put Block operation. You can call Put Block List to update a blob by uploading only those blocks that have changed, +// then committing the new and existing blocks together. You can do this by specifying whether to commit a block from +// the committed block list or from the uncommitted block list, or to commit the most recently uploaded version of the +// block, whichever list it may belong to. +// +// timeout is the timeout parameter is expressed in seconds. For more information, see Setting +// Timeouts for Blob Service Operations. blobCacheControl is optional. Sets the blob's cache control. If specified, +// this property is stored with the blob and returned with a read request. blobContentType is optional. Sets the blob's +// content type. If specified, this property is stored with the blob and returned with a read request. +// blobContentEncoding is optional. Sets the blob's content encoding. If specified, this property is stored with the +// blob and returned with a read request. blobContentLanguage is optional. Set the blob's content language. If +// specified, this property is stored with the blob and returned with a read request. blobContentMD5 is optional. An +// MD5 hash of the blob content. Note that this hash is not validated, as the hashes for the individual blocks were +// validated when each was uploaded. metadata is optional. Specifies a user-defined name-value pair associated with the +// blob. If no name-value pairs are specified, the operation will copy the metadata from the source blob or file to the +// destination blob. If one or more name-value pairs are specified, the destination blob is created with the specified +// metadata, and metadata is not copied from the source blob or file. Note that beginning with version 2009-09-19, +// metadata names must adhere to the naming rules for C# identifiers. See Naming and Referencing Containers, Blobs, and +// Metadata for more information. leaseID is if specified, the operation only succeeds if the container's lease is +// active and matches this ID. blobContentDisposition is optional. Sets the blob's Content-Disposition header. +// ifModifiedSince is specify this header value to operate only on a blob if it has been modified since the specified +// date/time. ifUnmodifiedSince is specify this header value to operate only on a blob if it has not been modified +// since the specified date/time. ifMatches is specify an ETag value to operate only on blobs with a matching value. +// ifNoneMatch is specify an ETag value to operate only on blobs without a matching value. requestID is provides a +// client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage +// analytics logging is enabled. +func (client blockBlobClient) CommitBlockList(ctx context.Context, blocks BlockLookupList, timeout *int32, blobCacheControl *string, blobContentType *string, blobContentEncoding *string, blobContentLanguage *string, blobContentMD5 []byte, metadata map[string]string, leaseID *string, blobContentDisposition *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (*BlockBlobCommitBlockListResponse, error) { + if err := validate([]validation{ + {targetValue: timeout, + constraints: []constraint{{target: "timeout", name: null, rule: false, + chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}, + {targetValue: metadata, + constraints: []constraint{{target: "metadata", name: null, rule: false, + chain: []constraint{{target: "metadata", name: pattern, rule: `^[a-zA-Z]+$`, chain: nil}}}}}}); err != nil { + return nil, err + } + req, err := client.commitBlockListPreparer(blocks, timeout, blobCacheControl, blobContentType, blobContentEncoding, blobContentLanguage, blobContentMD5, metadata, leaseID, blobContentDisposition, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestID) + if err != nil { + return nil, err + } + resp, err := client.Pipeline().Do(ctx, responderPolicyFactory{responder: client.commitBlockListResponder}, req) + if err != nil { + return nil, err + } + return resp.(*BlockBlobCommitBlockListResponse), err +} + +// commitBlockListPreparer prepares the CommitBlockList request. +func (client blockBlobClient) commitBlockListPreparer(blocks BlockLookupList, timeout *int32, blobCacheControl *string, blobContentType *string, blobContentEncoding *string, blobContentLanguage *string, blobContentMD5 []byte, metadata map[string]string, leaseID *string, blobContentDisposition *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (pipeline.Request, error) { + req, err := pipeline.NewRequest("PUT", client.url, nil) + if err != nil { + return req, pipeline.NewError(err, "failed to create request") + } + params := req.URL.Query() + if timeout != nil { + params.Set("timeout", strconv.FormatInt(int64(*timeout), 10)) + } + params.Set("comp", "blocklist") + req.URL.RawQuery = params.Encode() + if blobCacheControl != nil { + req.Header.Set("x-ms-blob-cache-control", *blobCacheControl) + } + if blobContentType != nil { + req.Header.Set("x-ms-blob-content-type", *blobContentType) + } + if blobContentEncoding != nil { + req.Header.Set("x-ms-blob-content-encoding", *blobContentEncoding) + } + if blobContentLanguage != nil { + req.Header.Set("x-ms-blob-content-language", *blobContentLanguage) + } + if blobContentMD5 != nil { + req.Header.Set("x-ms-blob-content-md5", base64.StdEncoding.EncodeToString(blobContentMD5)) + } + if metadata != nil { + for k, v := range metadata { + req.Header.Set("x-ms-meta-"+k, v) + } + } + if leaseID != nil { + req.Header.Set("x-ms-lease-id", *leaseID) + } + if blobContentDisposition != nil { + req.Header.Set("x-ms-blob-content-disposition", *blobContentDisposition) + } + if ifModifiedSince != nil { + req.Header.Set("If-Modified-Since", (*ifModifiedSince).In(gmt).Format(time.RFC1123)) + } + if ifUnmodifiedSince != nil { + req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123)) + } + if ifMatches != nil { + req.Header.Set("If-Match", string(*ifMatches)) + } + if ifNoneMatch != nil { + req.Header.Set("If-None-Match", string(*ifNoneMatch)) + } + req.Header.Set("x-ms-version", ServiceVersion) + if requestID != nil { + req.Header.Set("x-ms-client-request-id", *requestID) + } + b, err := xml.Marshal(blocks) + if err != nil { + return req, pipeline.NewError(err, "failed to marshal request body") + } + req.Header.Set("Content-Type", "application/xml") + err = req.SetBody(bytes.NewReader(b)) + if err != nil { + return req, pipeline.NewError(err, "failed to set request body") + } + return req, nil +} + +// commitBlockListResponder handles the response to the CommitBlockList request. +func (client blockBlobClient) commitBlockListResponder(resp pipeline.Response) (pipeline.Response, error) { + err := validateResponse(resp, http.StatusOK, http.StatusCreated) + if resp == nil { + return nil, err + } + io.Copy(ioutil.Discard, resp.Response().Body) + resp.Response().Body.Close() + return &BlockBlobCommitBlockListResponse{rawResponse: resp.Response()}, err +} + +// GetBlockList the Get Block List operation retrieves the list of blocks that have been uploaded as part of a block +// blob +// +// listType is specifies whether to return the list of committed blocks, the list of uncommitted blocks, or both lists +// together. snapshot is the snapshot parameter is an opaque DateTime value that, when present, specifies the blob +// snapshot to retrieve. For more information on working with blob snapshots, see Creating +// a Snapshot of a Blob. timeout is the timeout parameter is expressed in seconds. For more information, see Setting +// Timeouts for Blob Service Operations. leaseID is if specified, the operation only succeeds if the container's +// lease is active and matches this ID. requestID is provides a client-generated, opaque value with a 1 KB character +// limit that is recorded in the analytics logs when storage analytics logging is enabled. +func (client blockBlobClient) GetBlockList(ctx context.Context, listType BlockListType, snapshot *string, timeout *int32, leaseID *string, requestID *string) (*BlockList, error) { + if err := validate([]validation{ + {targetValue: timeout, + constraints: []constraint{{target: "timeout", name: null, rule: false, + chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil { + return nil, err + } + req, err := client.getBlockListPreparer(listType, snapshot, timeout, leaseID, requestID) + if err != nil { + return nil, err + } + resp, err := client.Pipeline().Do(ctx, responderPolicyFactory{responder: client.getBlockListResponder}, req) + if err != nil { + return nil, err + } + return resp.(*BlockList), err +} + +// getBlockListPreparer prepares the GetBlockList request. +func (client blockBlobClient) getBlockListPreparer(listType BlockListType, snapshot *string, timeout *int32, leaseID *string, requestID *string) (pipeline.Request, error) { + req, err := pipeline.NewRequest("GET", client.url, nil) + if err != nil { + return req, pipeline.NewError(err, "failed to create request") + } + params := req.URL.Query() + if snapshot != nil && len(*snapshot) > 0 { + params.Set("snapshot", *snapshot) + } + params.Set("blocklisttype", string(listType)) + if timeout != nil { + params.Set("timeout", strconv.FormatInt(int64(*timeout), 10)) + } + params.Set("comp", "blocklist") + req.URL.RawQuery = params.Encode() + if leaseID != nil { + req.Header.Set("x-ms-lease-id", *leaseID) + } + req.Header.Set("x-ms-version", ServiceVersion) + if requestID != nil { + req.Header.Set("x-ms-client-request-id", *requestID) + } + return req, nil +} + +// getBlockListResponder handles the response to the GetBlockList request. +func (client blockBlobClient) getBlockListResponder(resp pipeline.Response) (pipeline.Response, error) { + err := validateResponse(resp, http.StatusOK) + if resp == nil { + return nil, err + } + result := &BlockList{rawResponse: resp.Response()} + if err != nil { + return result, err + } + defer resp.Response().Body.Close() + b, err := ioutil.ReadAll(resp.Response().Body) + if err != nil { + return result, NewResponseError(err, resp.Response(), "failed to read response body") + } + if len(b) > 0 { + b = removeBOM(b) + err = xml.Unmarshal(b, result) + if err != nil { + return result, NewResponseError(err, resp.Response(), "failed to unmarshal response body") + } + } + return result, nil +} + +// StageBlock the Stage Block operation creates a new block to be committed as part of a blob +// +// blockID is a valid Base64 string value that identifies the block. Prior to encoding, the string must be less than or +// equal to 64 bytes in size. For a given blob, the length of the value specified for the blockid parameter must be the +// same size for each block. contentLength is the length of the request. body is initial data body will be closed upon +// successful return. Callers should ensure closure when receiving an error.timeout is the timeout parameter is +// expressed in seconds. For more information, see Setting +// Timeouts for Blob Service Operations. leaseID is if specified, the operation only succeeds if the container's +// lease is active and matches this ID. requestID is provides a client-generated, opaque value with a 1 KB character +// limit that is recorded in the analytics logs when storage analytics logging is enabled. +func (client blockBlobClient) StageBlock(ctx context.Context, blockID string, contentLength int64, body io.ReadSeeker, timeout *int32, leaseID *string, requestID *string) (*BlockBlobStageBlockResponse, error) { + if err := validate([]validation{ + {targetValue: body, + constraints: []constraint{{target: "body", name: null, rule: true, chain: nil}}}, + {targetValue: timeout, + constraints: []constraint{{target: "timeout", name: null, rule: false, + chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil { + return nil, err + } + req, err := client.stageBlockPreparer(blockID, contentLength, body, timeout, leaseID, requestID) + if err != nil { + return nil, err + } + resp, err := client.Pipeline().Do(ctx, responderPolicyFactory{responder: client.stageBlockResponder}, req) + if err != nil { + return nil, err + } + return resp.(*BlockBlobStageBlockResponse), err +} + +// stageBlockPreparer prepares the StageBlock request. +func (client blockBlobClient) stageBlockPreparer(blockID string, contentLength int64, body io.ReadSeeker, timeout *int32, leaseID *string, requestID *string) (pipeline.Request, error) { + req, err := pipeline.NewRequest("PUT", client.url, body) + if err != nil { + return req, pipeline.NewError(err, "failed to create request") + } + params := req.URL.Query() + params.Set("blockid", blockID) + if timeout != nil { + params.Set("timeout", strconv.FormatInt(int64(*timeout), 10)) + } + params.Set("comp", "block") + req.URL.RawQuery = params.Encode() + req.Header.Set("Content-Length", strconv.FormatInt(contentLength, 10)) + if leaseID != nil { + req.Header.Set("x-ms-lease-id", *leaseID) + } + req.Header.Set("x-ms-version", ServiceVersion) + if requestID != nil { + req.Header.Set("x-ms-client-request-id", *requestID) + } + return req, nil +} + +// stageBlockResponder handles the response to the StageBlock request. +func (client blockBlobClient) stageBlockResponder(resp pipeline.Response) (pipeline.Response, error) { + err := validateResponse(resp, http.StatusOK, http.StatusCreated) + if resp == nil { + return nil, err + } + io.Copy(ioutil.Discard, resp.Response().Body) + resp.Response().Body.Close() + return &BlockBlobStageBlockResponse{rawResponse: resp.Response()}, err +} + +// StageBlockFromURL the Stage Block operation creates a new block to be committed as part of a blob where the contents +// are read from a URL. +// +// blockID is a valid Base64 string value that identifies the block. Prior to encoding, the string must be less than or +// equal to 64 bytes in size. For a given blob, the length of the value specified for the blockid parameter must be the +// same size for each block. contentLength is the length of the request. sourceURL is specifiy an URL to the copy +// source. sourceRange is bytes of source data in the specified range. sourceContentMD5 is specify the md5 calculated +// for the range of bytes that must be read from the copy source. timeout is the timeout parameter is expressed in +// seconds. For more information, see Setting +// Timeouts for Blob Service Operations. leaseID is if specified, the operation only succeeds if the container's +// lease is active and matches this ID. requestID is provides a client-generated, opaque value with a 1 KB character +// limit that is recorded in the analytics logs when storage analytics logging is enabled. +func (client blockBlobClient) StageBlockFromURL(ctx context.Context, blockID string, contentLength int64, sourceURL *string, sourceRange *string, sourceContentMD5 []byte, timeout *int32, leaseID *string, requestID *string) (*BlockBlobStageBlockFromURLResponse, error) { + if err := validate([]validation{ + {targetValue: timeout, + constraints: []constraint{{target: "timeout", name: null, rule: false, + chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil { + return nil, err + } + req, err := client.stageBlockFromURLPreparer(blockID, contentLength, sourceURL, sourceRange, sourceContentMD5, timeout, leaseID, requestID) + if err != nil { + return nil, err + } + resp, err := client.Pipeline().Do(ctx, responderPolicyFactory{responder: client.stageBlockFromURLResponder}, req) + if err != nil { + return nil, err + } + return resp.(*BlockBlobStageBlockFromURLResponse), err +} + +// stageBlockFromURLPreparer prepares the StageBlockFromURL request. +func (client blockBlobClient) stageBlockFromURLPreparer(blockID string, contentLength int64, sourceURL *string, sourceRange *string, sourceContentMD5 []byte, timeout *int32, leaseID *string, requestID *string) (pipeline.Request, error) { + req, err := pipeline.NewRequest("PUT", client.url, nil) + if err != nil { + return req, pipeline.NewError(err, "failed to create request") + } + params := req.URL.Query() + params.Set("blockid", blockID) + if timeout != nil { + params.Set("timeout", strconv.FormatInt(int64(*timeout), 10)) + } + params.Set("comp", "block") + req.URL.RawQuery = params.Encode() + req.Header.Set("Content-Length", strconv.FormatInt(contentLength, 10)) + if sourceURL != nil { + req.Header.Set("x-ms-copy-source", *sourceURL) + } + if sourceRange != nil { + req.Header.Set("x-ms-source-range", *sourceRange) + } + if sourceContentMD5 != nil { + req.Header.Set("x-ms-source-content-md5", base64.StdEncoding.EncodeToString(sourceContentMD5)) + } + if leaseID != nil { + req.Header.Set("x-ms-lease-id", *leaseID) + } + req.Header.Set("x-ms-version", ServiceVersion) + if requestID != nil { + req.Header.Set("x-ms-client-request-id", *requestID) + } + return req, nil +} + +// stageBlockFromURLResponder handles the response to the StageBlockFromURL request. +func (client blockBlobClient) stageBlockFromURLResponder(resp pipeline.Response) (pipeline.Response, error) { + err := validateResponse(resp, http.StatusOK, http.StatusCreated) + if resp == nil { + return nil, err + } + io.Copy(ioutil.Discard, resp.Response().Body) + resp.Response().Body.Close() + return &BlockBlobStageBlockFromURLResponse{rawResponse: resp.Response()}, err +} + +// Upload the Upload Block Blob operation updates the content of an existing block blob. Updating an existing block +// blob overwrites any existing metadata on the blob. Partial updates are not supported with Put Blob; the content of +// the existing blob is overwritten with the content of the new blob. To perform a partial update of the content of a +// block blob, use the Put Block List operation. +// +// body is initial data body will be closed upon successful return. Callers should ensure closure when receiving an +// error.contentLength is the length of the request. timeout is the timeout parameter is expressed in seconds. For more +// information, see Setting +// Timeouts for Blob Service Operations. blobContentType is optional. Sets the blob's content type. If specified, +// this property is stored with the blob and returned with a read request. blobContentEncoding is optional. Sets the +// blob's content encoding. If specified, this property is stored with the blob and returned with a read request. +// blobContentLanguage is optional. Set the blob's content language. If specified, this property is stored with the +// blob and returned with a read request. blobContentMD5 is optional. An MD5 hash of the blob content. Note that this +// hash is not validated, as the hashes for the individual blocks were validated when each was uploaded. +// blobCacheControl is optional. Sets the blob's cache control. If specified, this property is stored with the blob and +// returned with a read request. metadata is optional. Specifies a user-defined name-value pair associated with the +// blob. If no name-value pairs are specified, the operation will copy the metadata from the source blob or file to the +// destination blob. If one or more name-value pairs are specified, the destination blob is created with the specified +// metadata, and metadata is not copied from the source blob or file. Note that beginning with version 2009-09-19, +// metadata names must adhere to the naming rules for C# identifiers. See Naming and Referencing Containers, Blobs, and +// Metadata for more information. leaseID is if specified, the operation only succeeds if the container's lease is +// active and matches this ID. blobContentDisposition is optional. Sets the blob's Content-Disposition header. +// ifModifiedSince is specify this header value to operate only on a blob if it has been modified since the specified +// date/time. ifUnmodifiedSince is specify this header value to operate only on a blob if it has not been modified +// since the specified date/time. ifMatches is specify an ETag value to operate only on blobs with a matching value. +// ifNoneMatch is specify an ETag value to operate only on blobs without a matching value. requestID is provides a +// client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage +// analytics logging is enabled. +func (client blockBlobClient) Upload(ctx context.Context, body io.ReadSeeker, contentLength int64, timeout *int32, blobContentType *string, blobContentEncoding *string, blobContentLanguage *string, blobContentMD5 []byte, blobCacheControl *string, metadata map[string]string, leaseID *string, blobContentDisposition *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (*BlockBlobUploadResponse, error) { + if err := validate([]validation{ + {targetValue: body, + constraints: []constraint{{target: "body", name: null, rule: true, chain: nil}}}, + {targetValue: timeout, + constraints: []constraint{{target: "timeout", name: null, rule: false, + chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}, + {targetValue: metadata, + constraints: []constraint{{target: "metadata", name: null, rule: false, + chain: []constraint{{target: "metadata", name: pattern, rule: `^[a-zA-Z]+$`, chain: nil}}}}}}); err != nil { + return nil, err + } + req, err := client.uploadPreparer(body, contentLength, timeout, blobContentType, blobContentEncoding, blobContentLanguage, blobContentMD5, blobCacheControl, metadata, leaseID, blobContentDisposition, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestID) + if err != nil { + return nil, err + } + resp, err := client.Pipeline().Do(ctx, responderPolicyFactory{responder: client.uploadResponder}, req) + if err != nil { + return nil, err + } + return resp.(*BlockBlobUploadResponse), err +} + +// uploadPreparer prepares the Upload request. +func (client blockBlobClient) uploadPreparer(body io.ReadSeeker, contentLength int64, timeout *int32, blobContentType *string, blobContentEncoding *string, blobContentLanguage *string, blobContentMD5 []byte, blobCacheControl *string, metadata map[string]string, leaseID *string, blobContentDisposition *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (pipeline.Request, error) { + req, err := pipeline.NewRequest("PUT", client.url, body) + if err != nil { + return req, pipeline.NewError(err, "failed to create request") + } + params := req.URL.Query() + if timeout != nil { + params.Set("timeout", strconv.FormatInt(int64(*timeout), 10)) + } + req.URL.RawQuery = params.Encode() + req.Header.Set("Content-Length", strconv.FormatInt(contentLength, 10)) + if blobContentType != nil { + req.Header.Set("x-ms-blob-content-type", *blobContentType) + } + if blobContentEncoding != nil { + req.Header.Set("x-ms-blob-content-encoding", *blobContentEncoding) + } + if blobContentLanguage != nil { + req.Header.Set("x-ms-blob-content-language", *blobContentLanguage) + } + if blobContentMD5 != nil { + req.Header.Set("x-ms-blob-content-md5", base64.StdEncoding.EncodeToString(blobContentMD5)) + } + if blobCacheControl != nil { + req.Header.Set("x-ms-blob-cache-control", *blobCacheControl) + } + if metadata != nil { + for k, v := range metadata { + req.Header.Set("x-ms-meta-"+k, v) + } + } + if leaseID != nil { + req.Header.Set("x-ms-lease-id", *leaseID) + } + if blobContentDisposition != nil { + req.Header.Set("x-ms-blob-content-disposition", *blobContentDisposition) + } + if ifModifiedSince != nil { + req.Header.Set("If-Modified-Since", (*ifModifiedSince).In(gmt).Format(time.RFC1123)) + } + if ifUnmodifiedSince != nil { + req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123)) + } + if ifMatches != nil { + req.Header.Set("If-Match", string(*ifMatches)) + } + if ifNoneMatch != nil { + req.Header.Set("If-None-Match", string(*ifNoneMatch)) + } + req.Header.Set("x-ms-version", ServiceVersion) + if requestID != nil { + req.Header.Set("x-ms-client-request-id", *requestID) + } + req.Header.Set("x-ms-blob-type", "BlockBlob") + return req, nil +} + +// uploadResponder handles the response to the Upload request. +func (client blockBlobClient) uploadResponder(resp pipeline.Response) (pipeline.Response, error) { + err := validateResponse(resp, http.StatusOK, http.StatusCreated) + if resp == nil { + return nil, err + } + io.Copy(ioutil.Discard, resp.Response().Body) + resp.Response().Body.Close() + return &BlockBlobUploadResponse{rawResponse: resp.Response()}, err +} diff --git a/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zz_generated_client.go b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zz_generated_client.go new file mode 100644 index 0000000000..b42a79b157 --- /dev/null +++ b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zz_generated_client.go @@ -0,0 +1,38 @@ +package azblob + +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/Azure/azure-pipeline-go/pipeline" + "net/url" +) + +const ( + // ServiceVersion specifies the version of the operations used in this package. + ServiceVersion = "2018-03-28" +) + +// managementClient is the base client for Azblob. +type managementClient struct { + url url.URL + p pipeline.Pipeline +} + +// newManagementClient creates an instance of the managementClient client. +func newManagementClient(url url.URL, p pipeline.Pipeline) managementClient { + return managementClient{ + url: url, + p: p, + } +} + +// URL returns a copy of the URL for this client. +func (mc managementClient) URL() url.URL { + return mc.url +} + +// Pipeline returns the pipeline for this client. +func (mc managementClient) Pipeline() pipeline.Pipeline { + return mc.p +} diff --git a/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zz_generated_container.go b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zz_generated_container.go new file mode 100644 index 0000000000..3e744fcbed --- /dev/null +++ b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zz_generated_container.go @@ -0,0 +1,1006 @@ +package azblob + +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "bytes" + "context" + "encoding/xml" + "io" + "io/ioutil" + "net/http" + "net/url" + "strconv" + "time" + + "github.com/Azure/azure-pipeline-go/pipeline" +) + +// containerClient is the client for the Container methods of the Azblob service. +type containerClient struct { + managementClient +} + +// newContainerClient creates an instance of the containerClient client. +func newContainerClient(url url.URL, p pipeline.Pipeline) containerClient { + return containerClient{newManagementClient(url, p)} +} + +// AcquireLease [Update] establishes and manages a lock on a container for delete operations. The lock duration can be +// 15 to 60 seconds, or can be infinite +// +// timeout is the timeout parameter is expressed in seconds. For more information, see Setting +// Timeouts for Blob Service Operations. duration is specifies the duration of the lease, in seconds, or negative +// one (-1) for a lease that never expires. A non-infinite lease can be between 15 and 60 seconds. A lease duration +// cannot be changed using renew or change. proposedLeaseID is proposed lease ID, in a GUID string format. The Blob +// service returns 400 (Invalid request) if the proposed lease ID is not in the correct format. See Guid Constructor +// (String) for a list of valid GUID string formats. ifModifiedSince is specify this header value to operate only on a +// blob if it has been modified since the specified date/time. ifUnmodifiedSince is specify this header value to +// operate only on a blob if it has not been modified since the specified date/time. requestID is provides a +// client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage +// analytics logging is enabled. +func (client containerClient) AcquireLease(ctx context.Context, timeout *int32, duration *int32, proposedLeaseID *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, requestID *string) (*ContainerAcquireLeaseResponse, error) { + if err := validate([]validation{ + {targetValue: timeout, + constraints: []constraint{{target: "timeout", name: null, rule: false, + chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil { + return nil, err + } + req, err := client.acquireLeasePreparer(timeout, duration, proposedLeaseID, ifModifiedSince, ifUnmodifiedSince, requestID) + if err != nil { + return nil, err + } + resp, err := client.Pipeline().Do(ctx, responderPolicyFactory{responder: client.acquireLeaseResponder}, req) + if err != nil { + return nil, err + } + return resp.(*ContainerAcquireLeaseResponse), err +} + +// acquireLeasePreparer prepares the AcquireLease request. +func (client containerClient) acquireLeasePreparer(timeout *int32, duration *int32, proposedLeaseID *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, requestID *string) (pipeline.Request, error) { + req, err := pipeline.NewRequest("PUT", client.url, nil) + if err != nil { + return req, pipeline.NewError(err, "failed to create request") + } + params := req.URL.Query() + if timeout != nil { + params.Set("timeout", strconv.FormatInt(int64(*timeout), 10)) + } + params.Set("comp", "lease") + params.Set("restype", "container") + req.URL.RawQuery = params.Encode() + if duration != nil { + req.Header.Set("x-ms-lease-duration", strconv.FormatInt(int64(*duration), 10)) + } + if proposedLeaseID != nil { + req.Header.Set("x-ms-proposed-lease-id", *proposedLeaseID) + } + if ifModifiedSince != nil { + req.Header.Set("If-Modified-Since", (*ifModifiedSince).In(gmt).Format(time.RFC1123)) + } + if ifUnmodifiedSince != nil { + req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123)) + } + req.Header.Set("x-ms-version", ServiceVersion) + if requestID != nil { + req.Header.Set("x-ms-client-request-id", *requestID) + } + req.Header.Set("x-ms-lease-action", "acquire") + return req, nil +} + +// acquireLeaseResponder handles the response to the AcquireLease request. +func (client containerClient) acquireLeaseResponder(resp pipeline.Response) (pipeline.Response, error) { + err := validateResponse(resp, http.StatusOK, http.StatusCreated) + if resp == nil { + return nil, err + } + io.Copy(ioutil.Discard, resp.Response().Body) + resp.Response().Body.Close() + return &ContainerAcquireLeaseResponse{rawResponse: resp.Response()}, err +} + +// BreakLease [Update] establishes and manages a lock on a container for delete operations. The lock duration can be 15 +// to 60 seconds, or can be infinite +// +// timeout is the timeout parameter is expressed in seconds. For more information, see Setting +// Timeouts for Blob Service Operations. breakPeriod is for a break operation, proposed duration the lease should +// continue before it is broken, in seconds, between 0 and 60. This break period is only used if it is shorter than the +// time remaining on the lease. If longer, the time remaining on the lease is used. A new lease will not be available +// before the break period has expired, but the lease may be held for longer than the break period. If this header does +// not appear with a break operation, a fixed-duration lease breaks after the remaining lease period elapses, and an +// infinite lease breaks immediately. ifModifiedSince is specify this header value to operate only on a blob if it has +// been modified since the specified date/time. ifUnmodifiedSince is specify this header value to operate only on a +// blob if it has not been modified since the specified date/time. requestID is provides a client-generated, opaque +// value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. +func (client containerClient) BreakLease(ctx context.Context, timeout *int32, breakPeriod *int32, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, requestID *string) (*ContainerBreakLeaseResponse, error) { + if err := validate([]validation{ + {targetValue: timeout, + constraints: []constraint{{target: "timeout", name: null, rule: false, + chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil { + return nil, err + } + req, err := client.breakLeasePreparer(timeout, breakPeriod, ifModifiedSince, ifUnmodifiedSince, requestID) + if err != nil { + return nil, err + } + resp, err := client.Pipeline().Do(ctx, responderPolicyFactory{responder: client.breakLeaseResponder}, req) + if err != nil { + return nil, err + } + return resp.(*ContainerBreakLeaseResponse), err +} + +// breakLeasePreparer prepares the BreakLease request. +func (client containerClient) breakLeasePreparer(timeout *int32, breakPeriod *int32, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, requestID *string) (pipeline.Request, error) { + req, err := pipeline.NewRequest("PUT", client.url, nil) + if err != nil { + return req, pipeline.NewError(err, "failed to create request") + } + params := req.URL.Query() + if timeout != nil { + params.Set("timeout", strconv.FormatInt(int64(*timeout), 10)) + } + params.Set("comp", "lease") + params.Set("restype", "container") + req.URL.RawQuery = params.Encode() + if breakPeriod != nil { + req.Header.Set("x-ms-lease-break-period", strconv.FormatInt(int64(*breakPeriod), 10)) + } + if ifModifiedSince != nil { + req.Header.Set("If-Modified-Since", (*ifModifiedSince).In(gmt).Format(time.RFC1123)) + } + if ifUnmodifiedSince != nil { + req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123)) + } + req.Header.Set("x-ms-version", ServiceVersion) + if requestID != nil { + req.Header.Set("x-ms-client-request-id", *requestID) + } + req.Header.Set("x-ms-lease-action", "break") + return req, nil +} + +// breakLeaseResponder handles the response to the BreakLease request. +func (client containerClient) breakLeaseResponder(resp pipeline.Response) (pipeline.Response, error) { + err := validateResponse(resp, http.StatusOK, http.StatusAccepted) + if resp == nil { + return nil, err + } + io.Copy(ioutil.Discard, resp.Response().Body) + resp.Response().Body.Close() + return &ContainerBreakLeaseResponse{rawResponse: resp.Response()}, err +} + +// ChangeLease [Update] establishes and manages a lock on a container for delete operations. The lock duration can be +// 15 to 60 seconds, or can be infinite +// +// leaseID is if specified, the operation only succeeds if the container's lease is active and matches this ID. +// proposedLeaseID is proposed lease ID, in a GUID string format. The Blob service returns 400 (Invalid request) if the +// proposed lease ID is not in the correct format. See Guid Constructor (String) for a list of valid GUID string +// formats. timeout is the timeout parameter is expressed in seconds. For more information, see Setting +// Timeouts for Blob Service Operations. ifModifiedSince is specify this header value to operate only on a blob if +// it has been modified since the specified date/time. ifUnmodifiedSince is specify this header value to operate only +// on a blob if it has not been modified since the specified date/time. requestID is provides a client-generated, +// opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is +// enabled. +func (client containerClient) ChangeLease(ctx context.Context, leaseID string, proposedLeaseID string, timeout *int32, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, requestID *string) (*ContainerChangeLeaseResponse, error) { + if err := validate([]validation{ + {targetValue: timeout, + constraints: []constraint{{target: "timeout", name: null, rule: false, + chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil { + return nil, err + } + req, err := client.changeLeasePreparer(leaseID, proposedLeaseID, timeout, ifModifiedSince, ifUnmodifiedSince, requestID) + if err != nil { + return nil, err + } + resp, err := client.Pipeline().Do(ctx, responderPolicyFactory{responder: client.changeLeaseResponder}, req) + if err != nil { + return nil, err + } + return resp.(*ContainerChangeLeaseResponse), err +} + +// changeLeasePreparer prepares the ChangeLease request. +func (client containerClient) changeLeasePreparer(leaseID string, proposedLeaseID string, timeout *int32, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, requestID *string) (pipeline.Request, error) { + req, err := pipeline.NewRequest("PUT", client.url, nil) + if err != nil { + return req, pipeline.NewError(err, "failed to create request") + } + params := req.URL.Query() + if timeout != nil { + params.Set("timeout", strconv.FormatInt(int64(*timeout), 10)) + } + params.Set("comp", "lease") + params.Set("restype", "container") + req.URL.RawQuery = params.Encode() + req.Header.Set("x-ms-lease-id", leaseID) + req.Header.Set("x-ms-proposed-lease-id", proposedLeaseID) + if ifModifiedSince != nil { + req.Header.Set("If-Modified-Since", (*ifModifiedSince).In(gmt).Format(time.RFC1123)) + } + if ifUnmodifiedSince != nil { + req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123)) + } + req.Header.Set("x-ms-version", ServiceVersion) + if requestID != nil { + req.Header.Set("x-ms-client-request-id", *requestID) + } + req.Header.Set("x-ms-lease-action", "change") + return req, nil +} + +// changeLeaseResponder handles the response to the ChangeLease request. +func (client containerClient) changeLeaseResponder(resp pipeline.Response) (pipeline.Response, error) { + err := validateResponse(resp, http.StatusOK) + if resp == nil { + return nil, err + } + io.Copy(ioutil.Discard, resp.Response().Body) + resp.Response().Body.Close() + return &ContainerChangeLeaseResponse{rawResponse: resp.Response()}, err +} + +// Create creates a new container under the specified account. If the container with the same name already exists, the +// operation fails +// +// timeout is the timeout parameter is expressed in seconds. For more information, see Setting +// Timeouts for Blob Service Operations. metadata is optional. Specifies a user-defined name-value pair associated +// with the blob. If no name-value pairs are specified, the operation will copy the metadata from the source blob or +// file to the destination blob. If one or more name-value pairs are specified, the destination blob is created with +// the specified metadata, and metadata is not copied from the source blob or file. Note that beginning with version +// 2009-09-19, metadata names must adhere to the naming rules for C# identifiers. See Naming and Referencing +// Containers, Blobs, and Metadata for more information. access is specifies whether data in the container may be +// accessed publicly and the level of access requestID is provides a client-generated, opaque value with a 1 KB +// character limit that is recorded in the analytics logs when storage analytics logging is enabled. +func (client containerClient) Create(ctx context.Context, timeout *int32, metadata map[string]string, access PublicAccessType, requestID *string) (*ContainerCreateResponse, error) { + if err := validate([]validation{ + {targetValue: timeout, + constraints: []constraint{{target: "timeout", name: null, rule: false, + chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}, + {targetValue: metadata, + constraints: []constraint{{target: "metadata", name: null, rule: false, + chain: []constraint{{target: "metadata", name: pattern, rule: `^[a-zA-Z]+$`, chain: nil}}}}}}); err != nil { + return nil, err + } + req, err := client.createPreparer(timeout, metadata, access, requestID) + if err != nil { + return nil, err + } + resp, err := client.Pipeline().Do(ctx, responderPolicyFactory{responder: client.createResponder}, req) + if err != nil { + return nil, err + } + return resp.(*ContainerCreateResponse), err +} + +// createPreparer prepares the Create request. +func (client containerClient) createPreparer(timeout *int32, metadata map[string]string, access PublicAccessType, requestID *string) (pipeline.Request, error) { + req, err := pipeline.NewRequest("PUT", client.url, nil) + if err != nil { + return req, pipeline.NewError(err, "failed to create request") + } + params := req.URL.Query() + if timeout != nil { + params.Set("timeout", strconv.FormatInt(int64(*timeout), 10)) + } + params.Set("restype", "container") + req.URL.RawQuery = params.Encode() + if metadata != nil { + for k, v := range metadata { + req.Header.Set("x-ms-meta-"+k, v) + } + } + if access != PublicAccessNone { + req.Header.Set("x-ms-blob-public-access", string(access)) + } + req.Header.Set("x-ms-version", ServiceVersion) + if requestID != nil { + req.Header.Set("x-ms-client-request-id", *requestID) + } + return req, nil +} + +// createResponder handles the response to the Create request. +func (client containerClient) createResponder(resp pipeline.Response) (pipeline.Response, error) { + err := validateResponse(resp, http.StatusOK, http.StatusCreated) + if resp == nil { + return nil, err + } + io.Copy(ioutil.Discard, resp.Response().Body) + resp.Response().Body.Close() + return &ContainerCreateResponse{rawResponse: resp.Response()}, err +} + +// Delete operation marks the specified container for deletion. The container and any blobs contained within it are +// later deleted during garbage collection +// +// timeout is the timeout parameter is expressed in seconds. For more information, see Setting +// Timeouts for Blob Service Operations. leaseID is if specified, the operation only succeeds if the container's +// lease is active and matches this ID. ifModifiedSince is specify this header value to operate only on a blob if it +// has been modified since the specified date/time. ifUnmodifiedSince is specify this header value to operate only on a +// blob if it has not been modified since the specified date/time. requestID is provides a client-generated, opaque +// value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. +func (client containerClient) Delete(ctx context.Context, timeout *int32, leaseID *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, requestID *string) (*ContainerDeleteResponse, error) { + if err := validate([]validation{ + {targetValue: timeout, + constraints: []constraint{{target: "timeout", name: null, rule: false, + chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil { + return nil, err + } + req, err := client.deletePreparer(timeout, leaseID, ifModifiedSince, ifUnmodifiedSince, requestID) + if err != nil { + return nil, err + } + resp, err := client.Pipeline().Do(ctx, responderPolicyFactory{responder: client.deleteResponder}, req) + if err != nil { + return nil, err + } + return resp.(*ContainerDeleteResponse), err +} + +// deletePreparer prepares the Delete request. +func (client containerClient) deletePreparer(timeout *int32, leaseID *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, requestID *string) (pipeline.Request, error) { + req, err := pipeline.NewRequest("DELETE", client.url, nil) + if err != nil { + return req, pipeline.NewError(err, "failed to create request") + } + params := req.URL.Query() + if timeout != nil { + params.Set("timeout", strconv.FormatInt(int64(*timeout), 10)) + } + params.Set("restype", "container") + req.URL.RawQuery = params.Encode() + if leaseID != nil { + req.Header.Set("x-ms-lease-id", *leaseID) + } + if ifModifiedSince != nil { + req.Header.Set("If-Modified-Since", (*ifModifiedSince).In(gmt).Format(time.RFC1123)) + } + if ifUnmodifiedSince != nil { + req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123)) + } + req.Header.Set("x-ms-version", ServiceVersion) + if requestID != nil { + req.Header.Set("x-ms-client-request-id", *requestID) + } + return req, nil +} + +// deleteResponder handles the response to the Delete request. +func (client containerClient) deleteResponder(resp pipeline.Response) (pipeline.Response, error) { + err := validateResponse(resp, http.StatusOK, http.StatusAccepted) + if resp == nil { + return nil, err + } + io.Copy(ioutil.Discard, resp.Response().Body) + resp.Response().Body.Close() + return &ContainerDeleteResponse{rawResponse: resp.Response()}, err +} + +// GetAccessPolicy gets the permissions for the specified container. The permissions indicate whether container data +// may be accessed publicly. +// +// timeout is the timeout parameter is expressed in seconds. For more information, see Setting +// Timeouts for Blob Service Operations. leaseID is if specified, the operation only succeeds if the container's +// lease is active and matches this ID. requestID is provides a client-generated, opaque value with a 1 KB character +// limit that is recorded in the analytics logs when storage analytics logging is enabled. +func (client containerClient) GetAccessPolicy(ctx context.Context, timeout *int32, leaseID *string, requestID *string) (*SignedIdentifiers, error) { + if err := validate([]validation{ + {targetValue: timeout, + constraints: []constraint{{target: "timeout", name: null, rule: false, + chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil { + return nil, err + } + req, err := client.getAccessPolicyPreparer(timeout, leaseID, requestID) + if err != nil { + return nil, err + } + resp, err := client.Pipeline().Do(ctx, responderPolicyFactory{responder: client.getAccessPolicyResponder}, req) + if err != nil { + return nil, err + } + return resp.(*SignedIdentifiers), err +} + +// getAccessPolicyPreparer prepares the GetAccessPolicy request. +func (client containerClient) getAccessPolicyPreparer(timeout *int32, leaseID *string, requestID *string) (pipeline.Request, error) { + req, err := pipeline.NewRequest("GET", client.url, nil) + if err != nil { + return req, pipeline.NewError(err, "failed to create request") + } + params := req.URL.Query() + if timeout != nil { + params.Set("timeout", strconv.FormatInt(int64(*timeout), 10)) + } + params.Set("restype", "container") + params.Set("comp", "acl") + req.URL.RawQuery = params.Encode() + if leaseID != nil { + req.Header.Set("x-ms-lease-id", *leaseID) + } + req.Header.Set("x-ms-version", ServiceVersion) + if requestID != nil { + req.Header.Set("x-ms-client-request-id", *requestID) + } + return req, nil +} + +// getAccessPolicyResponder handles the response to the GetAccessPolicy request. +func (client containerClient) getAccessPolicyResponder(resp pipeline.Response) (pipeline.Response, error) { + err := validateResponse(resp, http.StatusOK) + if resp == nil { + return nil, err + } + result := &SignedIdentifiers{rawResponse: resp.Response()} + if err != nil { + return result, err + } + defer resp.Response().Body.Close() + b, err := ioutil.ReadAll(resp.Response().Body) + if err != nil { + return result, NewResponseError(err, resp.Response(), "failed to read response body") + } + if len(b) > 0 { + b = removeBOM(b) + err = xml.Unmarshal(b, result) + if err != nil { + return result, NewResponseError(err, resp.Response(), "failed to unmarshal response body") + } + } + return result, nil +} + +// GetProperties returns all user-defined metadata and system properties for the specified container. The data returned +// does not include the container's list of blobs +// +// timeout is the timeout parameter is expressed in seconds. For more information, see Setting +// Timeouts for Blob Service Operations. leaseID is if specified, the operation only succeeds if the container's +// lease is active and matches this ID. requestID is provides a client-generated, opaque value with a 1 KB character +// limit that is recorded in the analytics logs when storage analytics logging is enabled. +func (client containerClient) GetProperties(ctx context.Context, timeout *int32, leaseID *string, requestID *string) (*ContainerGetPropertiesResponse, error) { + if err := validate([]validation{ + {targetValue: timeout, + constraints: []constraint{{target: "timeout", name: null, rule: false, + chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil { + return nil, err + } + req, err := client.getPropertiesPreparer(timeout, leaseID, requestID) + if err != nil { + return nil, err + } + resp, err := client.Pipeline().Do(ctx, responderPolicyFactory{responder: client.getPropertiesResponder}, req) + if err != nil { + return nil, err + } + return resp.(*ContainerGetPropertiesResponse), err +} + +// getPropertiesPreparer prepares the GetProperties request. +func (client containerClient) getPropertiesPreparer(timeout *int32, leaseID *string, requestID *string) (pipeline.Request, error) { + req, err := pipeline.NewRequest("GET", client.url, nil) + if err != nil { + return req, pipeline.NewError(err, "failed to create request") + } + params := req.URL.Query() + if timeout != nil { + params.Set("timeout", strconv.FormatInt(int64(*timeout), 10)) + } + params.Set("restype", "container") + req.URL.RawQuery = params.Encode() + if leaseID != nil { + req.Header.Set("x-ms-lease-id", *leaseID) + } + req.Header.Set("x-ms-version", ServiceVersion) + if requestID != nil { + req.Header.Set("x-ms-client-request-id", *requestID) + } + return req, nil +} + +// getPropertiesResponder handles the response to the GetProperties request. +func (client containerClient) getPropertiesResponder(resp pipeline.Response) (pipeline.Response, error) { + err := validateResponse(resp, http.StatusOK) + if resp == nil { + return nil, err + } + io.Copy(ioutil.Discard, resp.Response().Body) + resp.Response().Body.Close() + return &ContainerGetPropertiesResponse{rawResponse: resp.Response()}, err +} + +// ListBlobFlatSegment [Update] The List Blobs operation returns a list of the blobs under the specified container +// +// prefix is filters the results to return only containers whose name begins with the specified prefix. marker is a +// string value that identifies the portion of the list of containers to be returned with the next listing operation. +// The operation returns the NextMarker value within the response body if the listing operation did not return all +// containers remaining to be listed with the current page. The NextMarker value can be used as the value for the +// marker parameter in a subsequent call to request the next page of list items. The marker value is opaque to the +// client. maxresults is specifies the maximum number of containers to return. If the request does not specify +// maxresults, or specifies a value greater than 5000, the server will return up to 5000 items. Note that if the +// listing operation crosses a partition boundary, then the service will return a continuation token for retrieving the +// remainder of the results. For this reason, it is possible that the service will return fewer results than specified +// by maxresults, or than the default of 5000. include is include this parameter to specify one or more datasets to +// include in the response. timeout is the timeout parameter is expressed in seconds. For more information, see Setting +// Timeouts for Blob Service Operations. requestID is provides a client-generated, opaque value with a 1 KB +// character limit that is recorded in the analytics logs when storage analytics logging is enabled. +func (client containerClient) ListBlobFlatSegment(ctx context.Context, prefix *string, marker *string, maxresults *int32, include []ListBlobsIncludeItemType, timeout *int32, requestID *string) (*ListBlobsFlatSegmentResponse, error) { + if err := validate([]validation{ + {targetValue: maxresults, + constraints: []constraint{{target: "maxresults", name: null, rule: false, + chain: []constraint{{target: "maxresults", name: inclusiveMinimum, rule: 1, chain: nil}}}}}, + {targetValue: timeout, + constraints: []constraint{{target: "timeout", name: null, rule: false, + chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil { + return nil, err + } + req, err := client.listBlobFlatSegmentPreparer(prefix, marker, maxresults, include, timeout, requestID) + if err != nil { + return nil, err + } + resp, err := client.Pipeline().Do(ctx, responderPolicyFactory{responder: client.listBlobFlatSegmentResponder}, req) + if err != nil { + return nil, err + } + return resp.(*ListBlobsFlatSegmentResponse), err +} + +// listBlobFlatSegmentPreparer prepares the ListBlobFlatSegment request. +func (client containerClient) listBlobFlatSegmentPreparer(prefix *string, marker *string, maxresults *int32, include []ListBlobsIncludeItemType, timeout *int32, requestID *string) (pipeline.Request, error) { + req, err := pipeline.NewRequest("GET", client.url, nil) + if err != nil { + return req, pipeline.NewError(err, "failed to create request") + } + params := req.URL.Query() + if prefix != nil && len(*prefix) > 0 { + params.Set("prefix", *prefix) + } + if marker != nil && len(*marker) > 0 { + params.Set("marker", *marker) + } + if maxresults != nil { + params.Set("maxresults", strconv.FormatInt(int64(*maxresults), 10)) + } + if include != nil && len(include) > 0 { + params.Set("include", joinConst(include, ",")) + } + if timeout != nil { + params.Set("timeout", strconv.FormatInt(int64(*timeout), 10)) + } + params.Set("restype", "container") + params.Set("comp", "list") + req.URL.RawQuery = params.Encode() + req.Header.Set("x-ms-version", ServiceVersion) + if requestID != nil { + req.Header.Set("x-ms-client-request-id", *requestID) + } + return req, nil +} + +// listBlobFlatSegmentResponder handles the response to the ListBlobFlatSegment request. +func (client containerClient) listBlobFlatSegmentResponder(resp pipeline.Response) (pipeline.Response, error) { + err := validateResponse(resp, http.StatusOK) + if resp == nil { + return nil, err + } + result := &ListBlobsFlatSegmentResponse{rawResponse: resp.Response()} + if err != nil { + return result, err + } + defer resp.Response().Body.Close() + b, err := ioutil.ReadAll(resp.Response().Body) + if err != nil { + return result, NewResponseError(err, resp.Response(), "failed to read response body") + } + if len(b) > 0 { + b = removeBOM(b) + err = xml.Unmarshal(b, result) + if err != nil { + return result, NewResponseError(err, resp.Response(), "failed to unmarshal response body") + } + } + return result, nil +} + +// ListBlobHierarchySegment [Update] The List Blobs operation returns a list of the blobs under the specified container +// +// delimiter is when the request includes this parameter, the operation returns a BlobPrefix element in the response +// body that acts as a placeholder for all blobs whose names begin with the same substring up to the appearance of the +// delimiter character. The delimiter may be a single character or a string. prefix is filters the results to return +// only containers whose name begins with the specified prefix. marker is a string value that identifies the portion of +// the list of containers to be returned with the next listing operation. The operation returns the NextMarker value +// within the response body if the listing operation did not return all containers remaining to be listed with the +// current page. The NextMarker value can be used as the value for the marker parameter in a subsequent call to request +// the next page of list items. The marker value is opaque to the client. maxresults is specifies the maximum number of +// containers to return. If the request does not specify maxresults, or specifies a value greater than 5000, the server +// will return up to 5000 items. Note that if the listing operation crosses a partition boundary, then the service will +// return a continuation token for retrieving the remainder of the results. For this reason, it is possible that the +// service will return fewer results than specified by maxresults, or than the default of 5000. include is include this +// parameter to specify one or more datasets to include in the response. timeout is the timeout parameter is expressed +// in seconds. For more information, see Setting +// Timeouts for Blob Service Operations. requestID is provides a client-generated, opaque value with a 1 KB +// character limit that is recorded in the analytics logs when storage analytics logging is enabled. +func (client containerClient) ListBlobHierarchySegment(ctx context.Context, delimiter string, prefix *string, marker *string, maxresults *int32, include []ListBlobsIncludeItemType, timeout *int32, requestID *string) (*ListBlobsHierarchySegmentResponse, error) { + if err := validate([]validation{ + {targetValue: maxresults, + constraints: []constraint{{target: "maxresults", name: null, rule: false, + chain: []constraint{{target: "maxresults", name: inclusiveMinimum, rule: 1, chain: nil}}}}}, + {targetValue: timeout, + constraints: []constraint{{target: "timeout", name: null, rule: false, + chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil { + return nil, err + } + req, err := client.listBlobHierarchySegmentPreparer(delimiter, prefix, marker, maxresults, include, timeout, requestID) + if err != nil { + return nil, err + } + resp, err := client.Pipeline().Do(ctx, responderPolicyFactory{responder: client.listBlobHierarchySegmentResponder}, req) + if err != nil { + return nil, err + } + return resp.(*ListBlobsHierarchySegmentResponse), err +} + +// listBlobHierarchySegmentPreparer prepares the ListBlobHierarchySegment request. +func (client containerClient) listBlobHierarchySegmentPreparer(delimiter string, prefix *string, marker *string, maxresults *int32, include []ListBlobsIncludeItemType, timeout *int32, requestID *string) (pipeline.Request, error) { + req, err := pipeline.NewRequest("GET", client.url, nil) + if err != nil { + return req, pipeline.NewError(err, "failed to create request") + } + params := req.URL.Query() + if prefix != nil && len(*prefix) > 0 { + params.Set("prefix", *prefix) + } + params.Set("delimiter", delimiter) + if marker != nil && len(*marker) > 0 { + params.Set("marker", *marker) + } + if maxresults != nil { + params.Set("maxresults", strconv.FormatInt(int64(*maxresults), 10)) + } + if include != nil && len(include) > 0 { + params.Set("include", joinConst(include, ",")) + } + if timeout != nil { + params.Set("timeout", strconv.FormatInt(int64(*timeout), 10)) + } + params.Set("restype", "container") + params.Set("comp", "list") + req.URL.RawQuery = params.Encode() + req.Header.Set("x-ms-version", ServiceVersion) + if requestID != nil { + req.Header.Set("x-ms-client-request-id", *requestID) + } + return req, nil +} + +// listBlobHierarchySegmentResponder handles the response to the ListBlobHierarchySegment request. +func (client containerClient) listBlobHierarchySegmentResponder(resp pipeline.Response) (pipeline.Response, error) { + err := validateResponse(resp, http.StatusOK) + if resp == nil { + return nil, err + } + result := &ListBlobsHierarchySegmentResponse{rawResponse: resp.Response()} + if err != nil { + return result, err + } + defer resp.Response().Body.Close() + b, err := ioutil.ReadAll(resp.Response().Body) + if err != nil { + return result, NewResponseError(err, resp.Response(), "failed to read response body") + } + if len(b) > 0 { + b = removeBOM(b) + err = xml.Unmarshal(b, result) + if err != nil { + return result, NewResponseError(err, resp.Response(), "failed to unmarshal response body") + } + } + return result, nil +} + +// ReleaseLease [Update] establishes and manages a lock on a container for delete operations. The lock duration can be +// 15 to 60 seconds, or can be infinite +// +// leaseID is if specified, the operation only succeeds if the container's lease is active and matches this ID. timeout +// is the timeout parameter is expressed in seconds. For more information, see Setting +// Timeouts for Blob Service Operations. ifModifiedSince is specify this header value to operate only on a blob if +// it has been modified since the specified date/time. ifUnmodifiedSince is specify this header value to operate only +// on a blob if it has not been modified since the specified date/time. requestID is provides a client-generated, +// opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is +// enabled. +func (client containerClient) ReleaseLease(ctx context.Context, leaseID string, timeout *int32, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, requestID *string) (*ContainerReleaseLeaseResponse, error) { + if err := validate([]validation{ + {targetValue: timeout, + constraints: []constraint{{target: "timeout", name: null, rule: false, + chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil { + return nil, err + } + req, err := client.releaseLeasePreparer(leaseID, timeout, ifModifiedSince, ifUnmodifiedSince, requestID) + if err != nil { + return nil, err + } + resp, err := client.Pipeline().Do(ctx, responderPolicyFactory{responder: client.releaseLeaseResponder}, req) + if err != nil { + return nil, err + } + return resp.(*ContainerReleaseLeaseResponse), err +} + +// releaseLeasePreparer prepares the ReleaseLease request. +func (client containerClient) releaseLeasePreparer(leaseID string, timeout *int32, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, requestID *string) (pipeline.Request, error) { + req, err := pipeline.NewRequest("PUT", client.url, nil) + if err != nil { + return req, pipeline.NewError(err, "failed to create request") + } + params := req.URL.Query() + if timeout != nil { + params.Set("timeout", strconv.FormatInt(int64(*timeout), 10)) + } + params.Set("comp", "lease") + params.Set("restype", "container") + req.URL.RawQuery = params.Encode() + req.Header.Set("x-ms-lease-id", leaseID) + if ifModifiedSince != nil { + req.Header.Set("If-Modified-Since", (*ifModifiedSince).In(gmt).Format(time.RFC1123)) + } + if ifUnmodifiedSince != nil { + req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123)) + } + req.Header.Set("x-ms-version", ServiceVersion) + if requestID != nil { + req.Header.Set("x-ms-client-request-id", *requestID) + } + req.Header.Set("x-ms-lease-action", "release") + return req, nil +} + +// releaseLeaseResponder handles the response to the ReleaseLease request. +func (client containerClient) releaseLeaseResponder(resp pipeline.Response) (pipeline.Response, error) { + err := validateResponse(resp, http.StatusOK) + if resp == nil { + return nil, err + } + io.Copy(ioutil.Discard, resp.Response().Body) + resp.Response().Body.Close() + return &ContainerReleaseLeaseResponse{rawResponse: resp.Response()}, err +} + +// RenewLease [Update] establishes and manages a lock on a container for delete operations. The lock duration can be 15 +// to 60 seconds, or can be infinite +// +// leaseID is if specified, the operation only succeeds if the container's lease is active and matches this ID. timeout +// is the timeout parameter is expressed in seconds. For more information, see Setting +// Timeouts for Blob Service Operations. ifModifiedSince is specify this header value to operate only on a blob if +// it has been modified since the specified date/time. ifUnmodifiedSince is specify this header value to operate only +// on a blob if it has not been modified since the specified date/time. requestID is provides a client-generated, +// opaque value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is +// enabled. +func (client containerClient) RenewLease(ctx context.Context, leaseID string, timeout *int32, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, requestID *string) (*ContainerRenewLeaseResponse, error) { + if err := validate([]validation{ + {targetValue: timeout, + constraints: []constraint{{target: "timeout", name: null, rule: false, + chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil { + return nil, err + } + req, err := client.renewLeasePreparer(leaseID, timeout, ifModifiedSince, ifUnmodifiedSince, requestID) + if err != nil { + return nil, err + } + resp, err := client.Pipeline().Do(ctx, responderPolicyFactory{responder: client.renewLeaseResponder}, req) + if err != nil { + return nil, err + } + return resp.(*ContainerRenewLeaseResponse), err +} + +// renewLeasePreparer prepares the RenewLease request. +func (client containerClient) renewLeasePreparer(leaseID string, timeout *int32, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, requestID *string) (pipeline.Request, error) { + req, err := pipeline.NewRequest("PUT", client.url, nil) + if err != nil { + return req, pipeline.NewError(err, "failed to create request") + } + params := req.URL.Query() + if timeout != nil { + params.Set("timeout", strconv.FormatInt(int64(*timeout), 10)) + } + params.Set("comp", "lease") + params.Set("restype", "container") + req.URL.RawQuery = params.Encode() + req.Header.Set("x-ms-lease-id", leaseID) + if ifModifiedSince != nil { + req.Header.Set("If-Modified-Since", (*ifModifiedSince).In(gmt).Format(time.RFC1123)) + } + if ifUnmodifiedSince != nil { + req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123)) + } + req.Header.Set("x-ms-version", ServiceVersion) + if requestID != nil { + req.Header.Set("x-ms-client-request-id", *requestID) + } + req.Header.Set("x-ms-lease-action", "renew") + return req, nil +} + +// renewLeaseResponder handles the response to the RenewLease request. +func (client containerClient) renewLeaseResponder(resp pipeline.Response) (pipeline.Response, error) { + err := validateResponse(resp, http.StatusOK) + if resp == nil { + return nil, err + } + io.Copy(ioutil.Discard, resp.Response().Body) + resp.Response().Body.Close() + return &ContainerRenewLeaseResponse{rawResponse: resp.Response()}, err +} + +// SetAccessPolicy sets the permissions for the specified container. The permissions indicate whether blobs in a +// container may be accessed publicly. +// +// containerACL is the acls for the container timeout is the timeout parameter is expressed in seconds. For more +// information, see Setting +// Timeouts for Blob Service Operations. leaseID is if specified, the operation only succeeds if the container's +// lease is active and matches this ID. access is specifies whether data in the container may be accessed publicly and +// the level of access ifModifiedSince is specify this header value to operate only on a blob if it has been modified +// since the specified date/time. ifUnmodifiedSince is specify this header value to operate only on a blob if it has +// not been modified since the specified date/time. requestID is provides a client-generated, opaque value with a 1 KB +// character limit that is recorded in the analytics logs when storage analytics logging is enabled. +func (client containerClient) SetAccessPolicy(ctx context.Context, containerACL []SignedIdentifier, timeout *int32, leaseID *string, access PublicAccessType, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, requestID *string) (*ContainerSetAccessPolicyResponse, error) { + if err := validate([]validation{ + {targetValue: timeout, + constraints: []constraint{{target: "timeout", name: null, rule: false, + chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil { + return nil, err + } + req, err := client.setAccessPolicyPreparer(containerACL, timeout, leaseID, access, ifModifiedSince, ifUnmodifiedSince, requestID) + if err != nil { + return nil, err + } + resp, err := client.Pipeline().Do(ctx, responderPolicyFactory{responder: client.setAccessPolicyResponder}, req) + if err != nil { + return nil, err + } + return resp.(*ContainerSetAccessPolicyResponse), err +} + +// setAccessPolicyPreparer prepares the SetAccessPolicy request. +func (client containerClient) setAccessPolicyPreparer(containerACL []SignedIdentifier, timeout *int32, leaseID *string, access PublicAccessType, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, requestID *string) (pipeline.Request, error) { + req, err := pipeline.NewRequest("PUT", client.url, nil) + if err != nil { + return req, pipeline.NewError(err, "failed to create request") + } + params := req.URL.Query() + if timeout != nil { + params.Set("timeout", strconv.FormatInt(int64(*timeout), 10)) + } + params.Set("restype", "container") + params.Set("comp", "acl") + req.URL.RawQuery = params.Encode() + if leaseID != nil { + req.Header.Set("x-ms-lease-id", *leaseID) + } + if access != PublicAccessNone { + req.Header.Set("x-ms-blob-public-access", string(access)) + } + if ifModifiedSince != nil { + req.Header.Set("If-Modified-Since", (*ifModifiedSince).In(gmt).Format(time.RFC1123)) + } + if ifUnmodifiedSince != nil { + req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123)) + } + req.Header.Set("x-ms-version", ServiceVersion) + if requestID != nil { + req.Header.Set("x-ms-client-request-id", *requestID) + } + b, err := xml.Marshal(SignedIdentifiers{Items: containerACL}) + if err != nil { + return req, pipeline.NewError(err, "failed to marshal request body") + } + req.Header.Set("Content-Type", "application/xml") + err = req.SetBody(bytes.NewReader(b)) + if err != nil { + return req, pipeline.NewError(err, "failed to set request body") + } + return req, nil +} + +// setAccessPolicyResponder handles the response to the SetAccessPolicy request. +func (client containerClient) setAccessPolicyResponder(resp pipeline.Response) (pipeline.Response, error) { + err := validateResponse(resp, http.StatusOK) + if resp == nil { + return nil, err + } + io.Copy(ioutil.Discard, resp.Response().Body) + resp.Response().Body.Close() + return &ContainerSetAccessPolicyResponse{rawResponse: resp.Response()}, err +} + +// SetMetadata operation sets one or more user-defined name-value pairs for the specified container. +// +// timeout is the timeout parameter is expressed in seconds. For more information, see Setting +// Timeouts for Blob Service Operations. leaseID is if specified, the operation only succeeds if the container's +// lease is active and matches this ID. metadata is optional. Specifies a user-defined name-value pair associated with +// the blob. If no name-value pairs are specified, the operation will copy the metadata from the source blob or file to +// the destination blob. If one or more name-value pairs are specified, the destination blob is created with the +// specified metadata, and metadata is not copied from the source blob or file. Note that beginning with version +// 2009-09-19, metadata names must adhere to the naming rules for C# identifiers. See Naming and Referencing +// Containers, Blobs, and Metadata for more information. ifModifiedSince is specify this header value to operate only +// on a blob if it has been modified since the specified date/time. requestID is provides a client-generated, opaque +// value with a 1 KB character limit that is recorded in the analytics logs when storage analytics logging is enabled. +func (client containerClient) SetMetadata(ctx context.Context, timeout *int32, leaseID *string, metadata map[string]string, ifModifiedSince *time.Time, requestID *string) (*ContainerSetMetadataResponse, error) { + if err := validate([]validation{ + {targetValue: timeout, + constraints: []constraint{{target: "timeout", name: null, rule: false, + chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}, + {targetValue: metadata, + constraints: []constraint{{target: "metadata", name: null, rule: false, + chain: []constraint{{target: "metadata", name: pattern, rule: `^[a-zA-Z]+$`, chain: nil}}}}}}); err != nil { + return nil, err + } + req, err := client.setMetadataPreparer(timeout, leaseID, metadata, ifModifiedSince, requestID) + if err != nil { + return nil, err + } + resp, err := client.Pipeline().Do(ctx, responderPolicyFactory{responder: client.setMetadataResponder}, req) + if err != nil { + return nil, err + } + return resp.(*ContainerSetMetadataResponse), err +} + +// setMetadataPreparer prepares the SetMetadata request. +func (client containerClient) setMetadataPreparer(timeout *int32, leaseID *string, metadata map[string]string, ifModifiedSince *time.Time, requestID *string) (pipeline.Request, error) { + req, err := pipeline.NewRequest("PUT", client.url, nil) + if err != nil { + return req, pipeline.NewError(err, "failed to create request") + } + params := req.URL.Query() + if timeout != nil { + params.Set("timeout", strconv.FormatInt(int64(*timeout), 10)) + } + params.Set("restype", "container") + params.Set("comp", "metadata") + req.URL.RawQuery = params.Encode() + if leaseID != nil { + req.Header.Set("x-ms-lease-id", *leaseID) + } + if metadata != nil { + for k, v := range metadata { + req.Header.Set("x-ms-meta-"+k, v) + } + } + if ifModifiedSince != nil { + req.Header.Set("If-Modified-Since", (*ifModifiedSince).In(gmt).Format(time.RFC1123)) + } + req.Header.Set("x-ms-version", ServiceVersion) + if requestID != nil { + req.Header.Set("x-ms-client-request-id", *requestID) + } + return req, nil +} + +// setMetadataResponder handles the response to the SetMetadata request. +func (client containerClient) setMetadataResponder(resp pipeline.Response) (pipeline.Response, error) { + err := validateResponse(resp, http.StatusOK) + if resp == nil { + return nil, err + } + io.Copy(ioutil.Discard, resp.Response().Body) + resp.Response().Body.Close() + return &ContainerSetMetadataResponse{rawResponse: resp.Response()}, err +} diff --git a/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zz_generated_models.go b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zz_generated_models.go new file mode 100644 index 0000000000..3d8114ae6b --- /dev/null +++ b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zz_generated_models.go @@ -0,0 +1,4501 @@ +package azblob + +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "encoding/base64" + "encoding/xml" + "io" + "net/http" + "reflect" + "strconv" + "strings" + "time" + "unsafe" +) + +// ETag is an entity tag. +type ETag string + +const ( + // ETagNone represents an empty entity tag. + ETagNone ETag = "" + + // ETagAny matches any entity tag. + ETagAny ETag = "*" +) + +// Metadata contains metadata key/value pairs. +type Metadata map[string]string + +const mdPrefix = "x-ms-meta-" + +const mdPrefixLen = len(mdPrefix) + +// UnmarshalXML implements the xml.Unmarshaler interface for Metadata. +func (md *Metadata) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { + tokName := "" + for t, err := d.Token(); err == nil; t, err = d.Token() { + switch tt := t.(type) { + case xml.StartElement: + tokName = strings.ToLower(tt.Name.Local) + break + case xml.CharData: + if *md == nil { + *md = Metadata{} + } + (*md)[tokName] = string(tt) + break + } + } + return nil +} + +// Marker represents an opaque value used in paged responses. +type Marker struct { + val *string +} + +// NotDone returns true if the list enumeration should be started or is not yet complete. Specifically, NotDone returns true +// for a just-initialized (zero value) Marker indicating that you should make an initial request to get a result portion from +// the service. NotDone also returns true whenever the service returns an interim result portion. NotDone returns false only +// after the service has returned the final result portion. +func (m Marker) NotDone() bool { + return m.val == nil || *m.val != "" +} + +// UnmarshalXML implements the xml.Unmarshaler interface for Marker. +func (m *Marker) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { + var out string + err := d.DecodeElement(&out, &start) + m.val = &out + return err +} + +// concatenates a slice of const values with the specified separator between each item +func joinConst(s interface{}, sep string) string { + v := reflect.ValueOf(s) + if v.Kind() != reflect.Slice && v.Kind() != reflect.Array { + panic("s wasn't a slice or array") + } + ss := make([]string, 0, v.Len()) + for i := 0; i < v.Len(); i++ { + ss = append(ss, v.Index(i).String()) + } + return strings.Join(ss, sep) +} + +// AccessTierType enumerates the values for access tier type. +type AccessTierType string + +const ( + // AccessTierArchive ... + AccessTierArchive AccessTierType = "Archive" + // AccessTierCool ... + AccessTierCool AccessTierType = "Cool" + // AccessTierHot ... + AccessTierHot AccessTierType = "Hot" + // AccessTierNone represents an empty AccessTierType. + AccessTierNone AccessTierType = "" + // AccessTierP10 ... + AccessTierP10 AccessTierType = "P10" + // AccessTierP20 ... + AccessTierP20 AccessTierType = "P20" + // AccessTierP30 ... + AccessTierP30 AccessTierType = "P30" + // AccessTierP4 ... + AccessTierP4 AccessTierType = "P4" + // AccessTierP40 ... + AccessTierP40 AccessTierType = "P40" + // AccessTierP50 ... + AccessTierP50 AccessTierType = "P50" + // AccessTierP6 ... + AccessTierP6 AccessTierType = "P6" +) + +// PossibleAccessTierTypeValues returns an array of possible values for the AccessTierType const type. +func PossibleAccessTierTypeValues() []AccessTierType { + return []AccessTierType{AccessTierArchive, AccessTierCool, AccessTierHot, AccessTierNone, AccessTierP10, AccessTierP20, AccessTierP30, AccessTierP4, AccessTierP40, AccessTierP50, AccessTierP6} +} + +// ArchiveStatusType enumerates the values for archive status type. +type ArchiveStatusType string + +const ( + // ArchiveStatusNone represents an empty ArchiveStatusType. + ArchiveStatusNone ArchiveStatusType = "" + // ArchiveStatusRehydratePendingToCool ... + ArchiveStatusRehydratePendingToCool ArchiveStatusType = "rehydrate-pending-to-cool" + // ArchiveStatusRehydratePendingToHot ... + ArchiveStatusRehydratePendingToHot ArchiveStatusType = "rehydrate-pending-to-hot" +) + +// PossibleArchiveStatusTypeValues returns an array of possible values for the ArchiveStatusType const type. +func PossibleArchiveStatusTypeValues() []ArchiveStatusType { + return []ArchiveStatusType{ArchiveStatusNone, ArchiveStatusRehydratePendingToCool, ArchiveStatusRehydratePendingToHot} +} + +// BlobType enumerates the values for blob type. +type BlobType string + +const ( + // BlobAppendBlob ... + BlobAppendBlob BlobType = "AppendBlob" + // BlobBlockBlob ... + BlobBlockBlob BlobType = "BlockBlob" + // BlobNone represents an empty BlobType. + BlobNone BlobType = "" + // BlobPageBlob ... + BlobPageBlob BlobType = "PageBlob" +) + +// PossibleBlobTypeValues returns an array of possible values for the BlobType const type. +func PossibleBlobTypeValues() []BlobType { + return []BlobType{BlobAppendBlob, BlobBlockBlob, BlobNone, BlobPageBlob} +} + +// BlockListType enumerates the values for block list type. +type BlockListType string + +const ( + // BlockListAll ... + BlockListAll BlockListType = "all" + // BlockListCommitted ... + BlockListCommitted BlockListType = "committed" + // BlockListNone represents an empty BlockListType. + BlockListNone BlockListType = "" + // BlockListUncommitted ... + BlockListUncommitted BlockListType = "uncommitted" +) + +// PossibleBlockListTypeValues returns an array of possible values for the BlockListType const type. +func PossibleBlockListTypeValues() []BlockListType { + return []BlockListType{BlockListAll, BlockListCommitted, BlockListNone, BlockListUncommitted} +} + +// CopyStatusType enumerates the values for copy status type. +type CopyStatusType string + +const ( + // CopyStatusAborted ... + CopyStatusAborted CopyStatusType = "aborted" + // CopyStatusFailed ... + CopyStatusFailed CopyStatusType = "failed" + // CopyStatusNone represents an empty CopyStatusType. + CopyStatusNone CopyStatusType = "" + // CopyStatusPending ... + CopyStatusPending CopyStatusType = "pending" + // CopyStatusSuccess ... + CopyStatusSuccess CopyStatusType = "success" +) + +// PossibleCopyStatusTypeValues returns an array of possible values for the CopyStatusType const type. +func PossibleCopyStatusTypeValues() []CopyStatusType { + return []CopyStatusType{CopyStatusAborted, CopyStatusFailed, CopyStatusNone, CopyStatusPending, CopyStatusSuccess} +} + +// DeleteSnapshotsOptionType enumerates the values for delete snapshots option type. +type DeleteSnapshotsOptionType string + +const ( + // DeleteSnapshotsOptionInclude ... + DeleteSnapshotsOptionInclude DeleteSnapshotsOptionType = "include" + // DeleteSnapshotsOptionNone represents an empty DeleteSnapshotsOptionType. + DeleteSnapshotsOptionNone DeleteSnapshotsOptionType = "" + // DeleteSnapshotsOptionOnly ... + DeleteSnapshotsOptionOnly DeleteSnapshotsOptionType = "only" +) + +// PossibleDeleteSnapshotsOptionTypeValues returns an array of possible values for the DeleteSnapshotsOptionType const type. +func PossibleDeleteSnapshotsOptionTypeValues() []DeleteSnapshotsOptionType { + return []DeleteSnapshotsOptionType{DeleteSnapshotsOptionInclude, DeleteSnapshotsOptionNone, DeleteSnapshotsOptionOnly} +} + +// GeoReplicationStatusType enumerates the values for geo replication status type. +type GeoReplicationStatusType string + +const ( + // GeoReplicationStatusBootstrap ... + GeoReplicationStatusBootstrap GeoReplicationStatusType = "bootstrap" + // GeoReplicationStatusLive ... + GeoReplicationStatusLive GeoReplicationStatusType = "live" + // GeoReplicationStatusNone represents an empty GeoReplicationStatusType. + GeoReplicationStatusNone GeoReplicationStatusType = "" + // GeoReplicationStatusUnavailable ... + GeoReplicationStatusUnavailable GeoReplicationStatusType = "unavailable" +) + +// PossibleGeoReplicationStatusTypeValues returns an array of possible values for the GeoReplicationStatusType const type. +func PossibleGeoReplicationStatusTypeValues() []GeoReplicationStatusType { + return []GeoReplicationStatusType{GeoReplicationStatusBootstrap, GeoReplicationStatusLive, GeoReplicationStatusNone, GeoReplicationStatusUnavailable} +} + +// LeaseDurationType enumerates the values for lease duration type. +type LeaseDurationType string + +const ( + // LeaseDurationFixed ... + LeaseDurationFixed LeaseDurationType = "fixed" + // LeaseDurationInfinite ... + LeaseDurationInfinite LeaseDurationType = "infinite" + // LeaseDurationNone represents an empty LeaseDurationType. + LeaseDurationNone LeaseDurationType = "" +) + +// PossibleLeaseDurationTypeValues returns an array of possible values for the LeaseDurationType const type. +func PossibleLeaseDurationTypeValues() []LeaseDurationType { + return []LeaseDurationType{LeaseDurationFixed, LeaseDurationInfinite, LeaseDurationNone} +} + +// LeaseStateType enumerates the values for lease state type. +type LeaseStateType string + +const ( + // LeaseStateAvailable ... + LeaseStateAvailable LeaseStateType = "available" + // LeaseStateBreaking ... + LeaseStateBreaking LeaseStateType = "breaking" + // LeaseStateBroken ... + LeaseStateBroken LeaseStateType = "broken" + // LeaseStateExpired ... + LeaseStateExpired LeaseStateType = "expired" + // LeaseStateLeased ... + LeaseStateLeased LeaseStateType = "leased" + // LeaseStateNone represents an empty LeaseStateType. + LeaseStateNone LeaseStateType = "" +) + +// PossibleLeaseStateTypeValues returns an array of possible values for the LeaseStateType const type. +func PossibleLeaseStateTypeValues() []LeaseStateType { + return []LeaseStateType{LeaseStateAvailable, LeaseStateBreaking, LeaseStateBroken, LeaseStateExpired, LeaseStateLeased, LeaseStateNone} +} + +// LeaseStatusType enumerates the values for lease status type. +type LeaseStatusType string + +const ( + // LeaseStatusLocked ... + LeaseStatusLocked LeaseStatusType = "locked" + // LeaseStatusNone represents an empty LeaseStatusType. + LeaseStatusNone LeaseStatusType = "" + // LeaseStatusUnlocked ... + LeaseStatusUnlocked LeaseStatusType = "unlocked" +) + +// PossibleLeaseStatusTypeValues returns an array of possible values for the LeaseStatusType const type. +func PossibleLeaseStatusTypeValues() []LeaseStatusType { + return []LeaseStatusType{LeaseStatusLocked, LeaseStatusNone, LeaseStatusUnlocked} +} + +// ListBlobsIncludeItemType enumerates the values for list blobs include item type. +type ListBlobsIncludeItemType string + +const ( + // ListBlobsIncludeItemCopy ... + ListBlobsIncludeItemCopy ListBlobsIncludeItemType = "copy" + // ListBlobsIncludeItemDeleted ... + ListBlobsIncludeItemDeleted ListBlobsIncludeItemType = "deleted" + // ListBlobsIncludeItemMetadata ... + ListBlobsIncludeItemMetadata ListBlobsIncludeItemType = "metadata" + // ListBlobsIncludeItemNone represents an empty ListBlobsIncludeItemType. + ListBlobsIncludeItemNone ListBlobsIncludeItemType = "" + // ListBlobsIncludeItemSnapshots ... + ListBlobsIncludeItemSnapshots ListBlobsIncludeItemType = "snapshots" + // ListBlobsIncludeItemUncommittedblobs ... + ListBlobsIncludeItemUncommittedblobs ListBlobsIncludeItemType = "uncommittedblobs" +) + +// PossibleListBlobsIncludeItemTypeValues returns an array of possible values for the ListBlobsIncludeItemType const type. +func PossibleListBlobsIncludeItemTypeValues() []ListBlobsIncludeItemType { + return []ListBlobsIncludeItemType{ListBlobsIncludeItemCopy, ListBlobsIncludeItemDeleted, ListBlobsIncludeItemMetadata, ListBlobsIncludeItemNone, ListBlobsIncludeItemSnapshots, ListBlobsIncludeItemUncommittedblobs} +} + +// ListContainersIncludeType enumerates the values for list containers include type. +type ListContainersIncludeType string + +const ( + // ListContainersIncludeMetadata ... + ListContainersIncludeMetadata ListContainersIncludeType = "metadata" + // ListContainersIncludeNone represents an empty ListContainersIncludeType. + ListContainersIncludeNone ListContainersIncludeType = "" +) + +// PossibleListContainersIncludeTypeValues returns an array of possible values for the ListContainersIncludeType const type. +func PossibleListContainersIncludeTypeValues() []ListContainersIncludeType { + return []ListContainersIncludeType{ListContainersIncludeMetadata, ListContainersIncludeNone} +} + +// PublicAccessType enumerates the values for public access type. +type PublicAccessType string + +const ( + // PublicAccessBlob ... + PublicAccessBlob PublicAccessType = "blob" + // PublicAccessContainer ... + PublicAccessContainer PublicAccessType = "container" + // PublicAccessNone represents an empty PublicAccessType. + PublicAccessNone PublicAccessType = "" +) + +// PossiblePublicAccessTypeValues returns an array of possible values for the PublicAccessType const type. +func PossiblePublicAccessTypeValues() []PublicAccessType { + return []PublicAccessType{PublicAccessBlob, PublicAccessContainer, PublicAccessNone} +} + +// SequenceNumberActionType enumerates the values for sequence number action type. +type SequenceNumberActionType string + +const ( + // SequenceNumberActionIncrement ... + SequenceNumberActionIncrement SequenceNumberActionType = "increment" + // SequenceNumberActionMax ... + SequenceNumberActionMax SequenceNumberActionType = "max" + // SequenceNumberActionNone represents an empty SequenceNumberActionType. + SequenceNumberActionNone SequenceNumberActionType = "" + // SequenceNumberActionUpdate ... + SequenceNumberActionUpdate SequenceNumberActionType = "update" +) + +// PossibleSequenceNumberActionTypeValues returns an array of possible values for the SequenceNumberActionType const type. +func PossibleSequenceNumberActionTypeValues() []SequenceNumberActionType { + return []SequenceNumberActionType{SequenceNumberActionIncrement, SequenceNumberActionMax, SequenceNumberActionNone, SequenceNumberActionUpdate} +} + +// StorageErrorCodeType enumerates the values for storage error code type. +type StorageErrorCodeType string + +const ( + // StorageErrorCodeAccountAlreadyExists ... + StorageErrorCodeAccountAlreadyExists StorageErrorCodeType = "AccountAlreadyExists" + // StorageErrorCodeAccountBeingCreated ... + StorageErrorCodeAccountBeingCreated StorageErrorCodeType = "AccountBeingCreated" + // StorageErrorCodeAccountIsDisabled ... + StorageErrorCodeAccountIsDisabled StorageErrorCodeType = "AccountIsDisabled" + // StorageErrorCodeAppendPositionConditionNotMet ... + StorageErrorCodeAppendPositionConditionNotMet StorageErrorCodeType = "AppendPositionConditionNotMet" + // StorageErrorCodeAuthenticationFailed ... + StorageErrorCodeAuthenticationFailed StorageErrorCodeType = "AuthenticationFailed" + // StorageErrorCodeBlobAlreadyExists ... + StorageErrorCodeBlobAlreadyExists StorageErrorCodeType = "BlobAlreadyExists" + // StorageErrorCodeBlobArchived ... + StorageErrorCodeBlobArchived StorageErrorCodeType = "BlobArchived" + // StorageErrorCodeBlobBeingRehydrated ... + StorageErrorCodeBlobBeingRehydrated StorageErrorCodeType = "BlobBeingRehydrated" + // StorageErrorCodeBlobNotArchived ... + StorageErrorCodeBlobNotArchived StorageErrorCodeType = "BlobNotArchived" + // StorageErrorCodeBlobNotFound ... + StorageErrorCodeBlobNotFound StorageErrorCodeType = "BlobNotFound" + // StorageErrorCodeBlobOverwritten ... + StorageErrorCodeBlobOverwritten StorageErrorCodeType = "BlobOverwritten" + // StorageErrorCodeBlobTierInadequateForContentLength ... + StorageErrorCodeBlobTierInadequateForContentLength StorageErrorCodeType = "BlobTierInadequateForContentLength" + // StorageErrorCodeBlockCountExceedsLimit ... + StorageErrorCodeBlockCountExceedsLimit StorageErrorCodeType = "BlockCountExceedsLimit" + // StorageErrorCodeBlockListTooLong ... + StorageErrorCodeBlockListTooLong StorageErrorCodeType = "BlockListTooLong" + // StorageErrorCodeCannotChangeToLowerTier ... + StorageErrorCodeCannotChangeToLowerTier StorageErrorCodeType = "CannotChangeToLowerTier" + // StorageErrorCodeCannotVerifyCopySource ... + StorageErrorCodeCannotVerifyCopySource StorageErrorCodeType = "CannotVerifyCopySource" + // StorageErrorCodeConditionHeadersNotSupported ... + StorageErrorCodeConditionHeadersNotSupported StorageErrorCodeType = "ConditionHeadersNotSupported" + // StorageErrorCodeConditionNotMet ... + StorageErrorCodeConditionNotMet StorageErrorCodeType = "ConditionNotMet" + // StorageErrorCodeContainerAlreadyExists ... + StorageErrorCodeContainerAlreadyExists StorageErrorCodeType = "ContainerAlreadyExists" + // StorageErrorCodeContainerBeingDeleted ... + StorageErrorCodeContainerBeingDeleted StorageErrorCodeType = "ContainerBeingDeleted" + // StorageErrorCodeContainerDisabled ... + StorageErrorCodeContainerDisabled StorageErrorCodeType = "ContainerDisabled" + // StorageErrorCodeContainerNotFound ... + StorageErrorCodeContainerNotFound StorageErrorCodeType = "ContainerNotFound" + // StorageErrorCodeContentLengthLargerThanTierLimit ... + StorageErrorCodeContentLengthLargerThanTierLimit StorageErrorCodeType = "ContentLengthLargerThanTierLimit" + // StorageErrorCodeCopyAcrossAccountsNotSupported ... + StorageErrorCodeCopyAcrossAccountsNotSupported StorageErrorCodeType = "CopyAcrossAccountsNotSupported" + // StorageErrorCodeCopyIDMismatch ... + StorageErrorCodeCopyIDMismatch StorageErrorCodeType = "CopyIdMismatch" + // StorageErrorCodeEmptyMetadataKey ... + StorageErrorCodeEmptyMetadataKey StorageErrorCodeType = "EmptyMetadataKey" + // StorageErrorCodeFeatureVersionMismatch ... + StorageErrorCodeFeatureVersionMismatch StorageErrorCodeType = "FeatureVersionMismatch" + // StorageErrorCodeIncrementalCopyBlobMismatch ... + StorageErrorCodeIncrementalCopyBlobMismatch StorageErrorCodeType = "IncrementalCopyBlobMismatch" + // StorageErrorCodeIncrementalCopyOfEralierVersionSnapshotNotAllowed ... + StorageErrorCodeIncrementalCopyOfEralierVersionSnapshotNotAllowed StorageErrorCodeType = "IncrementalCopyOfEralierVersionSnapshotNotAllowed" + // StorageErrorCodeIncrementalCopySourceMustBeSnapshot ... + StorageErrorCodeIncrementalCopySourceMustBeSnapshot StorageErrorCodeType = "IncrementalCopySourceMustBeSnapshot" + // StorageErrorCodeInfiniteLeaseDurationRequired ... + StorageErrorCodeInfiniteLeaseDurationRequired StorageErrorCodeType = "InfiniteLeaseDurationRequired" + // StorageErrorCodeInsufficientAccountPermissions ... + StorageErrorCodeInsufficientAccountPermissions StorageErrorCodeType = "InsufficientAccountPermissions" + // StorageErrorCodeInternalError ... + StorageErrorCodeInternalError StorageErrorCodeType = "InternalError" + // StorageErrorCodeInvalidAuthenticationInfo ... + StorageErrorCodeInvalidAuthenticationInfo StorageErrorCodeType = "InvalidAuthenticationInfo" + // StorageErrorCodeInvalidBlobOrBlock ... + StorageErrorCodeInvalidBlobOrBlock StorageErrorCodeType = "InvalidBlobOrBlock" + // StorageErrorCodeInvalidBlobTier ... + StorageErrorCodeInvalidBlobTier StorageErrorCodeType = "InvalidBlobTier" + // StorageErrorCodeInvalidBlobType ... + StorageErrorCodeInvalidBlobType StorageErrorCodeType = "InvalidBlobType" + // StorageErrorCodeInvalidBlockID ... + StorageErrorCodeInvalidBlockID StorageErrorCodeType = "InvalidBlockId" + // StorageErrorCodeInvalidBlockList ... + StorageErrorCodeInvalidBlockList StorageErrorCodeType = "InvalidBlockList" + // StorageErrorCodeInvalidHeaderValue ... + StorageErrorCodeInvalidHeaderValue StorageErrorCodeType = "InvalidHeaderValue" + // StorageErrorCodeInvalidHTTPVerb ... + StorageErrorCodeInvalidHTTPVerb StorageErrorCodeType = "InvalidHttpVerb" + // StorageErrorCodeInvalidInput ... + StorageErrorCodeInvalidInput StorageErrorCodeType = "InvalidInput" + // StorageErrorCodeInvalidMd5 ... + StorageErrorCodeInvalidMd5 StorageErrorCodeType = "InvalidMd5" + // StorageErrorCodeInvalidMetadata ... + StorageErrorCodeInvalidMetadata StorageErrorCodeType = "InvalidMetadata" + // StorageErrorCodeInvalidOperation ... + StorageErrorCodeInvalidOperation StorageErrorCodeType = "InvalidOperation" + // StorageErrorCodeInvalidPageRange ... + StorageErrorCodeInvalidPageRange StorageErrorCodeType = "InvalidPageRange" + // StorageErrorCodeInvalidQueryParameterValue ... + StorageErrorCodeInvalidQueryParameterValue StorageErrorCodeType = "InvalidQueryParameterValue" + // StorageErrorCodeInvalidRange ... + StorageErrorCodeInvalidRange StorageErrorCodeType = "InvalidRange" + // StorageErrorCodeInvalidResourceName ... + StorageErrorCodeInvalidResourceName StorageErrorCodeType = "InvalidResourceName" + // StorageErrorCodeInvalidSourceBlobType ... + StorageErrorCodeInvalidSourceBlobType StorageErrorCodeType = "InvalidSourceBlobType" + // StorageErrorCodeInvalidSourceBlobURL ... + StorageErrorCodeInvalidSourceBlobURL StorageErrorCodeType = "InvalidSourceBlobUrl" + // StorageErrorCodeInvalidURI ... + StorageErrorCodeInvalidURI StorageErrorCodeType = "InvalidUri" + // StorageErrorCodeInvalidVersionForPageBlobOperation ... + StorageErrorCodeInvalidVersionForPageBlobOperation StorageErrorCodeType = "InvalidVersionForPageBlobOperation" + // StorageErrorCodeInvalidXMLDocument ... + StorageErrorCodeInvalidXMLDocument StorageErrorCodeType = "InvalidXmlDocument" + // StorageErrorCodeInvalidXMLNodeValue ... + StorageErrorCodeInvalidXMLNodeValue StorageErrorCodeType = "InvalidXmlNodeValue" + // StorageErrorCodeLeaseAlreadyBroken ... + StorageErrorCodeLeaseAlreadyBroken StorageErrorCodeType = "LeaseAlreadyBroken" + // StorageErrorCodeLeaseAlreadyPresent ... + StorageErrorCodeLeaseAlreadyPresent StorageErrorCodeType = "LeaseAlreadyPresent" + // StorageErrorCodeLeaseIDMismatchWithBlobOperation ... + StorageErrorCodeLeaseIDMismatchWithBlobOperation StorageErrorCodeType = "LeaseIdMismatchWithBlobOperation" + // StorageErrorCodeLeaseIDMismatchWithContainerOperation ... + StorageErrorCodeLeaseIDMismatchWithContainerOperation StorageErrorCodeType = "LeaseIdMismatchWithContainerOperation" + // StorageErrorCodeLeaseIDMismatchWithLeaseOperation ... + StorageErrorCodeLeaseIDMismatchWithLeaseOperation StorageErrorCodeType = "LeaseIdMismatchWithLeaseOperation" + // StorageErrorCodeLeaseIDMissing ... + StorageErrorCodeLeaseIDMissing StorageErrorCodeType = "LeaseIdMissing" + // StorageErrorCodeLeaseIsBreakingAndCannotBeAcquired ... + StorageErrorCodeLeaseIsBreakingAndCannotBeAcquired StorageErrorCodeType = "LeaseIsBreakingAndCannotBeAcquired" + // StorageErrorCodeLeaseIsBreakingAndCannotBeChanged ... + StorageErrorCodeLeaseIsBreakingAndCannotBeChanged StorageErrorCodeType = "LeaseIsBreakingAndCannotBeChanged" + // StorageErrorCodeLeaseIsBrokenAndCannotBeRenewed ... + StorageErrorCodeLeaseIsBrokenAndCannotBeRenewed StorageErrorCodeType = "LeaseIsBrokenAndCannotBeRenewed" + // StorageErrorCodeLeaseLost ... + StorageErrorCodeLeaseLost StorageErrorCodeType = "LeaseLost" + // StorageErrorCodeLeaseNotPresentWithBlobOperation ... + StorageErrorCodeLeaseNotPresentWithBlobOperation StorageErrorCodeType = "LeaseNotPresentWithBlobOperation" + // StorageErrorCodeLeaseNotPresentWithContainerOperation ... + StorageErrorCodeLeaseNotPresentWithContainerOperation StorageErrorCodeType = "LeaseNotPresentWithContainerOperation" + // StorageErrorCodeLeaseNotPresentWithLeaseOperation ... + StorageErrorCodeLeaseNotPresentWithLeaseOperation StorageErrorCodeType = "LeaseNotPresentWithLeaseOperation" + // StorageErrorCodeMaxBlobSizeConditionNotMet ... + StorageErrorCodeMaxBlobSizeConditionNotMet StorageErrorCodeType = "MaxBlobSizeConditionNotMet" + // StorageErrorCodeMd5Mismatch ... + StorageErrorCodeMd5Mismatch StorageErrorCodeType = "Md5Mismatch" + // StorageErrorCodeMetadataTooLarge ... + StorageErrorCodeMetadataTooLarge StorageErrorCodeType = "MetadataTooLarge" + // StorageErrorCodeMissingContentLengthHeader ... + StorageErrorCodeMissingContentLengthHeader StorageErrorCodeType = "MissingContentLengthHeader" + // StorageErrorCodeMissingRequiredHeader ... + StorageErrorCodeMissingRequiredHeader StorageErrorCodeType = "MissingRequiredHeader" + // StorageErrorCodeMissingRequiredQueryParameter ... + StorageErrorCodeMissingRequiredQueryParameter StorageErrorCodeType = "MissingRequiredQueryParameter" + // StorageErrorCodeMissingRequiredXMLNode ... + StorageErrorCodeMissingRequiredXMLNode StorageErrorCodeType = "MissingRequiredXmlNode" + // StorageErrorCodeMultipleConditionHeadersNotSupported ... + StorageErrorCodeMultipleConditionHeadersNotSupported StorageErrorCodeType = "MultipleConditionHeadersNotSupported" + // StorageErrorCodeNone represents an empty StorageErrorCodeType. + StorageErrorCodeNone StorageErrorCodeType = "" + // StorageErrorCodeNoPendingCopyOperation ... + StorageErrorCodeNoPendingCopyOperation StorageErrorCodeType = "NoPendingCopyOperation" + // StorageErrorCodeOperationNotAllowedOnIncrementalCopyBlob ... + StorageErrorCodeOperationNotAllowedOnIncrementalCopyBlob StorageErrorCodeType = "OperationNotAllowedOnIncrementalCopyBlob" + // StorageErrorCodeOperationTimedOut ... + StorageErrorCodeOperationTimedOut StorageErrorCodeType = "OperationTimedOut" + // StorageErrorCodeOutOfRangeInput ... + StorageErrorCodeOutOfRangeInput StorageErrorCodeType = "OutOfRangeInput" + // StorageErrorCodeOutOfRangeQueryParameterValue ... + StorageErrorCodeOutOfRangeQueryParameterValue StorageErrorCodeType = "OutOfRangeQueryParameterValue" + // StorageErrorCodePendingCopyOperation ... + StorageErrorCodePendingCopyOperation StorageErrorCodeType = "PendingCopyOperation" + // StorageErrorCodePreviousSnapshotCannotBeNewer ... + StorageErrorCodePreviousSnapshotCannotBeNewer StorageErrorCodeType = "PreviousSnapshotCannotBeNewer" + // StorageErrorCodePreviousSnapshotNotFound ... + StorageErrorCodePreviousSnapshotNotFound StorageErrorCodeType = "PreviousSnapshotNotFound" + // StorageErrorCodePreviousSnapshotOperationNotSupported ... + StorageErrorCodePreviousSnapshotOperationNotSupported StorageErrorCodeType = "PreviousSnapshotOperationNotSupported" + // StorageErrorCodeRequestBodyTooLarge ... + StorageErrorCodeRequestBodyTooLarge StorageErrorCodeType = "RequestBodyTooLarge" + // StorageErrorCodeRequestURLFailedToParse ... + StorageErrorCodeRequestURLFailedToParse StorageErrorCodeType = "RequestUrlFailedToParse" + // StorageErrorCodeResourceAlreadyExists ... + StorageErrorCodeResourceAlreadyExists StorageErrorCodeType = "ResourceAlreadyExists" + // StorageErrorCodeResourceNotFound ... + StorageErrorCodeResourceNotFound StorageErrorCodeType = "ResourceNotFound" + // StorageErrorCodeResourceTypeMismatch ... + StorageErrorCodeResourceTypeMismatch StorageErrorCodeType = "ResourceTypeMismatch" + // StorageErrorCodeSequenceNumberConditionNotMet ... + StorageErrorCodeSequenceNumberConditionNotMet StorageErrorCodeType = "SequenceNumberConditionNotMet" + // StorageErrorCodeSequenceNumberIncrementTooLarge ... + StorageErrorCodeSequenceNumberIncrementTooLarge StorageErrorCodeType = "SequenceNumberIncrementTooLarge" + // StorageErrorCodeServerBusy ... + StorageErrorCodeServerBusy StorageErrorCodeType = "ServerBusy" + // StorageErrorCodeSnaphotOperationRateExceeded ... + StorageErrorCodeSnaphotOperationRateExceeded StorageErrorCodeType = "SnaphotOperationRateExceeded" + // StorageErrorCodeSnapshotCountExceeded ... + StorageErrorCodeSnapshotCountExceeded StorageErrorCodeType = "SnapshotCountExceeded" + // StorageErrorCodeSnapshotsPresent ... + StorageErrorCodeSnapshotsPresent StorageErrorCodeType = "SnapshotsPresent" + // StorageErrorCodeSourceConditionNotMet ... + StorageErrorCodeSourceConditionNotMet StorageErrorCodeType = "SourceConditionNotMet" + // StorageErrorCodeSystemInUse ... + StorageErrorCodeSystemInUse StorageErrorCodeType = "SystemInUse" + // StorageErrorCodeTargetConditionNotMet ... + StorageErrorCodeTargetConditionNotMet StorageErrorCodeType = "TargetConditionNotMet" + // StorageErrorCodeUnauthorizedBlobOverwrite ... + StorageErrorCodeUnauthorizedBlobOverwrite StorageErrorCodeType = "UnauthorizedBlobOverwrite" + // StorageErrorCodeUnsupportedHeader ... + StorageErrorCodeUnsupportedHeader StorageErrorCodeType = "UnsupportedHeader" + // StorageErrorCodeUnsupportedHTTPVerb ... + StorageErrorCodeUnsupportedHTTPVerb StorageErrorCodeType = "UnsupportedHttpVerb" + // StorageErrorCodeUnsupportedQueryParameter ... + StorageErrorCodeUnsupportedQueryParameter StorageErrorCodeType = "UnsupportedQueryParameter" + // StorageErrorCodeUnsupportedXMLNode ... + StorageErrorCodeUnsupportedXMLNode StorageErrorCodeType = "UnsupportedXmlNode" +) + +// PossibleStorageErrorCodeTypeValues returns an array of possible values for the StorageErrorCodeType const type. +func PossibleStorageErrorCodeTypeValues() []StorageErrorCodeType { + return []StorageErrorCodeType{StorageErrorCodeAccountAlreadyExists, StorageErrorCodeAccountBeingCreated, StorageErrorCodeAccountIsDisabled, StorageErrorCodeAppendPositionConditionNotMet, StorageErrorCodeAuthenticationFailed, StorageErrorCodeBlobAlreadyExists, StorageErrorCodeBlobArchived, StorageErrorCodeBlobBeingRehydrated, StorageErrorCodeBlobNotArchived, StorageErrorCodeBlobNotFound, StorageErrorCodeBlobOverwritten, StorageErrorCodeBlobTierInadequateForContentLength, StorageErrorCodeBlockCountExceedsLimit, StorageErrorCodeBlockListTooLong, StorageErrorCodeCannotChangeToLowerTier, StorageErrorCodeCannotVerifyCopySource, StorageErrorCodeConditionHeadersNotSupported, StorageErrorCodeConditionNotMet, StorageErrorCodeContainerAlreadyExists, StorageErrorCodeContainerBeingDeleted, StorageErrorCodeContainerDisabled, StorageErrorCodeContainerNotFound, StorageErrorCodeContentLengthLargerThanTierLimit, StorageErrorCodeCopyAcrossAccountsNotSupported, StorageErrorCodeCopyIDMismatch, StorageErrorCodeEmptyMetadataKey, StorageErrorCodeFeatureVersionMismatch, StorageErrorCodeIncrementalCopyBlobMismatch, StorageErrorCodeIncrementalCopyOfEralierVersionSnapshotNotAllowed, StorageErrorCodeIncrementalCopySourceMustBeSnapshot, StorageErrorCodeInfiniteLeaseDurationRequired, StorageErrorCodeInsufficientAccountPermissions, StorageErrorCodeInternalError, StorageErrorCodeInvalidAuthenticationInfo, StorageErrorCodeInvalidBlobOrBlock, StorageErrorCodeInvalidBlobTier, StorageErrorCodeInvalidBlobType, StorageErrorCodeInvalidBlockID, StorageErrorCodeInvalidBlockList, StorageErrorCodeInvalidHeaderValue, StorageErrorCodeInvalidHTTPVerb, StorageErrorCodeInvalidInput, StorageErrorCodeInvalidMd5, StorageErrorCodeInvalidMetadata, StorageErrorCodeInvalidOperation, StorageErrorCodeInvalidPageRange, StorageErrorCodeInvalidQueryParameterValue, StorageErrorCodeInvalidRange, StorageErrorCodeInvalidResourceName, StorageErrorCodeInvalidSourceBlobType, StorageErrorCodeInvalidSourceBlobURL, StorageErrorCodeInvalidURI, StorageErrorCodeInvalidVersionForPageBlobOperation, StorageErrorCodeInvalidXMLDocument, StorageErrorCodeInvalidXMLNodeValue, StorageErrorCodeLeaseAlreadyBroken, StorageErrorCodeLeaseAlreadyPresent, StorageErrorCodeLeaseIDMismatchWithBlobOperation, StorageErrorCodeLeaseIDMismatchWithContainerOperation, StorageErrorCodeLeaseIDMismatchWithLeaseOperation, StorageErrorCodeLeaseIDMissing, StorageErrorCodeLeaseIsBreakingAndCannotBeAcquired, StorageErrorCodeLeaseIsBreakingAndCannotBeChanged, StorageErrorCodeLeaseIsBrokenAndCannotBeRenewed, StorageErrorCodeLeaseLost, StorageErrorCodeLeaseNotPresentWithBlobOperation, StorageErrorCodeLeaseNotPresentWithContainerOperation, StorageErrorCodeLeaseNotPresentWithLeaseOperation, StorageErrorCodeMaxBlobSizeConditionNotMet, StorageErrorCodeMd5Mismatch, StorageErrorCodeMetadataTooLarge, StorageErrorCodeMissingContentLengthHeader, StorageErrorCodeMissingRequiredHeader, StorageErrorCodeMissingRequiredQueryParameter, StorageErrorCodeMissingRequiredXMLNode, StorageErrorCodeMultipleConditionHeadersNotSupported, StorageErrorCodeNone, StorageErrorCodeNoPendingCopyOperation, StorageErrorCodeOperationNotAllowedOnIncrementalCopyBlob, StorageErrorCodeOperationTimedOut, StorageErrorCodeOutOfRangeInput, StorageErrorCodeOutOfRangeQueryParameterValue, StorageErrorCodePendingCopyOperation, StorageErrorCodePreviousSnapshotCannotBeNewer, StorageErrorCodePreviousSnapshotNotFound, StorageErrorCodePreviousSnapshotOperationNotSupported, StorageErrorCodeRequestBodyTooLarge, StorageErrorCodeRequestURLFailedToParse, StorageErrorCodeResourceAlreadyExists, StorageErrorCodeResourceNotFound, StorageErrorCodeResourceTypeMismatch, StorageErrorCodeSequenceNumberConditionNotMet, StorageErrorCodeSequenceNumberIncrementTooLarge, StorageErrorCodeServerBusy, StorageErrorCodeSnaphotOperationRateExceeded, StorageErrorCodeSnapshotCountExceeded, StorageErrorCodeSnapshotsPresent, StorageErrorCodeSourceConditionNotMet, StorageErrorCodeSystemInUse, StorageErrorCodeTargetConditionNotMet, StorageErrorCodeUnauthorizedBlobOverwrite, StorageErrorCodeUnsupportedHeader, StorageErrorCodeUnsupportedHTTPVerb, StorageErrorCodeUnsupportedQueryParameter, StorageErrorCodeUnsupportedXMLNode} +} + +// AccessPolicy - An Access policy +type AccessPolicy struct { + // Start - the date-time the policy is active + Start time.Time `xml:"Start"` + // Expiry - the date-time the policy expires + Expiry time.Time `xml:"Expiry"` + // Permission - the permissions for the acl policy + Permission string `xml:"Permission"` +} + +// MarshalXML implements the xml.Marshaler interface for AccessPolicy. +func (ap AccessPolicy) MarshalXML(e *xml.Encoder, start xml.StartElement) error { + if reflect.TypeOf((*AccessPolicy)(nil)).Elem().Size() != reflect.TypeOf((*accessPolicy)(nil)).Elem().Size() { + panic("size mismatch between AccessPolicy and accessPolicy") + } + ap2 := (*accessPolicy)(unsafe.Pointer(&ap)) + return e.EncodeElement(*ap2, start) +} + +// UnmarshalXML implements the xml.Unmarshaler interface for AccessPolicy. +func (ap *AccessPolicy) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { + if reflect.TypeOf((*AccessPolicy)(nil)).Elem().Size() != reflect.TypeOf((*accessPolicy)(nil)).Elem().Size() { + panic("size mismatch between AccessPolicy and accessPolicy") + } + ap2 := (*accessPolicy)(unsafe.Pointer(ap)) + return d.DecodeElement(ap2, &start) +} + +// AppendBlobAppendBlockResponse ... +type AppendBlobAppendBlockResponse struct { + rawResponse *http.Response +} + +// Response returns the raw HTTP response object. +func (ababr AppendBlobAppendBlockResponse) Response() *http.Response { + return ababr.rawResponse +} + +// StatusCode returns the HTTP status code of the response, e.g. 200. +func (ababr AppendBlobAppendBlockResponse) StatusCode() int { + return ababr.rawResponse.StatusCode +} + +// Status returns the HTTP status message of the response, e.g. "200 OK". +func (ababr AppendBlobAppendBlockResponse) Status() string { + return ababr.rawResponse.Status +} + +// BlobAppendOffset returns the value for header x-ms-blob-append-offset. +func (ababr AppendBlobAppendBlockResponse) BlobAppendOffset() string { + return ababr.rawResponse.Header.Get("x-ms-blob-append-offset") +} + +// BlobCommittedBlockCount returns the value for header x-ms-blob-committed-block-count. +func (ababr AppendBlobAppendBlockResponse) BlobCommittedBlockCount() int32 { + s := ababr.rawResponse.Header.Get("x-ms-blob-committed-block-count") + if s == "" { + return -1 + } + i, err := strconv.ParseInt(s, 10, 32) + if err != nil { + panic(err) + } + return int32(i) +} + +// ContentMD5 returns the value for header Content-MD5. +func (ababr AppendBlobAppendBlockResponse) ContentMD5() []byte { + s := ababr.rawResponse.Header.Get("Content-MD5") + if s == "" { + return nil + } + b, err := base64.StdEncoding.DecodeString(s) + if err != nil { + panic(err) + } + return b +} + +// Date returns the value for header Date. +func (ababr AppendBlobAppendBlockResponse) Date() time.Time { + s := ababr.rawResponse.Header.Get("Date") + if s == "" { + return time.Time{} + } + t, err := time.Parse(time.RFC1123, s) + if err != nil { + panic(err) + } + return t +} + +// ErrorCode returns the value for header x-ms-error-code. +func (ababr AppendBlobAppendBlockResponse) ErrorCode() string { + return ababr.rawResponse.Header.Get("x-ms-error-code") +} + +// ETag returns the value for header ETag. +func (ababr AppendBlobAppendBlockResponse) ETag() ETag { + return ETag(ababr.rawResponse.Header.Get("ETag")) +} + +// LastModified returns the value for header Last-Modified. +func (ababr AppendBlobAppendBlockResponse) LastModified() time.Time { + s := ababr.rawResponse.Header.Get("Last-Modified") + if s == "" { + return time.Time{} + } + t, err := time.Parse(time.RFC1123, s) + if err != nil { + panic(err) + } + return t +} + +// RequestID returns the value for header x-ms-request-id. +func (ababr AppendBlobAppendBlockResponse) RequestID() string { + return ababr.rawResponse.Header.Get("x-ms-request-id") +} + +// Version returns the value for header x-ms-version. +func (ababr AppendBlobAppendBlockResponse) Version() string { + return ababr.rawResponse.Header.Get("x-ms-version") +} + +// AppendBlobCreateResponse ... +type AppendBlobCreateResponse struct { + rawResponse *http.Response +} + +// Response returns the raw HTTP response object. +func (abcr AppendBlobCreateResponse) Response() *http.Response { + return abcr.rawResponse +} + +// StatusCode returns the HTTP status code of the response, e.g. 200. +func (abcr AppendBlobCreateResponse) StatusCode() int { + return abcr.rawResponse.StatusCode +} + +// Status returns the HTTP status message of the response, e.g. "200 OK". +func (abcr AppendBlobCreateResponse) Status() string { + return abcr.rawResponse.Status +} + +// ContentMD5 returns the value for header Content-MD5. +func (abcr AppendBlobCreateResponse) ContentMD5() []byte { + s := abcr.rawResponse.Header.Get("Content-MD5") + if s == "" { + return nil + } + b, err := base64.StdEncoding.DecodeString(s) + if err != nil { + panic(err) + } + return b +} + +// Date returns the value for header Date. +func (abcr AppendBlobCreateResponse) Date() time.Time { + s := abcr.rawResponse.Header.Get("Date") + if s == "" { + return time.Time{} + } + t, err := time.Parse(time.RFC1123, s) + if err != nil { + panic(err) + } + return t +} + +// ErrorCode returns the value for header x-ms-error-code. +func (abcr AppendBlobCreateResponse) ErrorCode() string { + return abcr.rawResponse.Header.Get("x-ms-error-code") +} + +// ETag returns the value for header ETag. +func (abcr AppendBlobCreateResponse) ETag() ETag { + return ETag(abcr.rawResponse.Header.Get("ETag")) +} + +// IsServerEncrypted returns the value for header x-ms-request-server-encrypted. +func (abcr AppendBlobCreateResponse) IsServerEncrypted() string { + return abcr.rawResponse.Header.Get("x-ms-request-server-encrypted") +} + +// LastModified returns the value for header Last-Modified. +func (abcr AppendBlobCreateResponse) LastModified() time.Time { + s := abcr.rawResponse.Header.Get("Last-Modified") + if s == "" { + return time.Time{} + } + t, err := time.Parse(time.RFC1123, s) + if err != nil { + panic(err) + } + return t +} + +// RequestID returns the value for header x-ms-request-id. +func (abcr AppendBlobCreateResponse) RequestID() string { + return abcr.rawResponse.Header.Get("x-ms-request-id") +} + +// Version returns the value for header x-ms-version. +func (abcr AppendBlobCreateResponse) Version() string { + return abcr.rawResponse.Header.Get("x-ms-version") +} + +// BlobAbortCopyFromURLResponse ... +type BlobAbortCopyFromURLResponse struct { + rawResponse *http.Response +} + +// Response returns the raw HTTP response object. +func (bacfur BlobAbortCopyFromURLResponse) Response() *http.Response { + return bacfur.rawResponse +} + +// StatusCode returns the HTTP status code of the response, e.g. 200. +func (bacfur BlobAbortCopyFromURLResponse) StatusCode() int { + return bacfur.rawResponse.StatusCode +} + +// Status returns the HTTP status message of the response, e.g. "200 OK". +func (bacfur BlobAbortCopyFromURLResponse) Status() string { + return bacfur.rawResponse.Status +} + +// Date returns the value for header Date. +func (bacfur BlobAbortCopyFromURLResponse) Date() time.Time { + s := bacfur.rawResponse.Header.Get("Date") + if s == "" { + return time.Time{} + } + t, err := time.Parse(time.RFC1123, s) + if err != nil { + panic(err) + } + return t +} + +// ErrorCode returns the value for header x-ms-error-code. +func (bacfur BlobAbortCopyFromURLResponse) ErrorCode() string { + return bacfur.rawResponse.Header.Get("x-ms-error-code") +} + +// RequestID returns the value for header x-ms-request-id. +func (bacfur BlobAbortCopyFromURLResponse) RequestID() string { + return bacfur.rawResponse.Header.Get("x-ms-request-id") +} + +// Version returns the value for header x-ms-version. +func (bacfur BlobAbortCopyFromURLResponse) Version() string { + return bacfur.rawResponse.Header.Get("x-ms-version") +} + +// BlobAcquireLeaseResponse ... +type BlobAcquireLeaseResponse struct { + rawResponse *http.Response +} + +// Response returns the raw HTTP response object. +func (balr BlobAcquireLeaseResponse) Response() *http.Response { + return balr.rawResponse +} + +// StatusCode returns the HTTP status code of the response, e.g. 200. +func (balr BlobAcquireLeaseResponse) StatusCode() int { + return balr.rawResponse.StatusCode +} + +// Status returns the HTTP status message of the response, e.g. "200 OK". +func (balr BlobAcquireLeaseResponse) Status() string { + return balr.rawResponse.Status +} + +// Date returns the value for header Date. +func (balr BlobAcquireLeaseResponse) Date() time.Time { + s := balr.rawResponse.Header.Get("Date") + if s == "" { + return time.Time{} + } + t, err := time.Parse(time.RFC1123, s) + if err != nil { + panic(err) + } + return t +} + +// ErrorCode returns the value for header x-ms-error-code. +func (balr BlobAcquireLeaseResponse) ErrorCode() string { + return balr.rawResponse.Header.Get("x-ms-error-code") +} + +// ETag returns the value for header ETag. +func (balr BlobAcquireLeaseResponse) ETag() ETag { + return ETag(balr.rawResponse.Header.Get("ETag")) +} + +// LastModified returns the value for header Last-Modified. +func (balr BlobAcquireLeaseResponse) LastModified() time.Time { + s := balr.rawResponse.Header.Get("Last-Modified") + if s == "" { + return time.Time{} + } + t, err := time.Parse(time.RFC1123, s) + if err != nil { + panic(err) + } + return t +} + +// LeaseID returns the value for header x-ms-lease-id. +func (balr BlobAcquireLeaseResponse) LeaseID() string { + return balr.rawResponse.Header.Get("x-ms-lease-id") +} + +// RequestID returns the value for header x-ms-request-id. +func (balr BlobAcquireLeaseResponse) RequestID() string { + return balr.rawResponse.Header.Get("x-ms-request-id") +} + +// Version returns the value for header x-ms-version. +func (balr BlobAcquireLeaseResponse) Version() string { + return balr.rawResponse.Header.Get("x-ms-version") +} + +// BlobBreakLeaseResponse ... +type BlobBreakLeaseResponse struct { + rawResponse *http.Response +} + +// Response returns the raw HTTP response object. +func (bblr BlobBreakLeaseResponse) Response() *http.Response { + return bblr.rawResponse +} + +// StatusCode returns the HTTP status code of the response, e.g. 200. +func (bblr BlobBreakLeaseResponse) StatusCode() int { + return bblr.rawResponse.StatusCode +} + +// Status returns the HTTP status message of the response, e.g. "200 OK". +func (bblr BlobBreakLeaseResponse) Status() string { + return bblr.rawResponse.Status +} + +// Date returns the value for header Date. +func (bblr BlobBreakLeaseResponse) Date() time.Time { + s := bblr.rawResponse.Header.Get("Date") + if s == "" { + return time.Time{} + } + t, err := time.Parse(time.RFC1123, s) + if err != nil { + panic(err) + } + return t +} + +// ErrorCode returns the value for header x-ms-error-code. +func (bblr BlobBreakLeaseResponse) ErrorCode() string { + return bblr.rawResponse.Header.Get("x-ms-error-code") +} + +// ETag returns the value for header ETag. +func (bblr BlobBreakLeaseResponse) ETag() ETag { + return ETag(bblr.rawResponse.Header.Get("ETag")) +} + +// LastModified returns the value for header Last-Modified. +func (bblr BlobBreakLeaseResponse) LastModified() time.Time { + s := bblr.rawResponse.Header.Get("Last-Modified") + if s == "" { + return time.Time{} + } + t, err := time.Parse(time.RFC1123, s) + if err != nil { + panic(err) + } + return t +} + +// LeaseTime returns the value for header x-ms-lease-time. +func (bblr BlobBreakLeaseResponse) LeaseTime() int32 { + s := bblr.rawResponse.Header.Get("x-ms-lease-time") + if s == "" { + return -1 + } + i, err := strconv.ParseInt(s, 10, 32) + if err != nil { + panic(err) + } + return int32(i) +} + +// RequestID returns the value for header x-ms-request-id. +func (bblr BlobBreakLeaseResponse) RequestID() string { + return bblr.rawResponse.Header.Get("x-ms-request-id") +} + +// Version returns the value for header x-ms-version. +func (bblr BlobBreakLeaseResponse) Version() string { + return bblr.rawResponse.Header.Get("x-ms-version") +} + +// BlobChangeLeaseResponse ... +type BlobChangeLeaseResponse struct { + rawResponse *http.Response +} + +// Response returns the raw HTTP response object. +func (bclr BlobChangeLeaseResponse) Response() *http.Response { + return bclr.rawResponse +} + +// StatusCode returns the HTTP status code of the response, e.g. 200. +func (bclr BlobChangeLeaseResponse) StatusCode() int { + return bclr.rawResponse.StatusCode +} + +// Status returns the HTTP status message of the response, e.g. "200 OK". +func (bclr BlobChangeLeaseResponse) Status() string { + return bclr.rawResponse.Status +} + +// Date returns the value for header Date. +func (bclr BlobChangeLeaseResponse) Date() time.Time { + s := bclr.rawResponse.Header.Get("Date") + if s == "" { + return time.Time{} + } + t, err := time.Parse(time.RFC1123, s) + if err != nil { + panic(err) + } + return t +} + +// ErrorCode returns the value for header x-ms-error-code. +func (bclr BlobChangeLeaseResponse) ErrorCode() string { + return bclr.rawResponse.Header.Get("x-ms-error-code") +} + +// ETag returns the value for header ETag. +func (bclr BlobChangeLeaseResponse) ETag() ETag { + return ETag(bclr.rawResponse.Header.Get("ETag")) +} + +// LastModified returns the value for header Last-Modified. +func (bclr BlobChangeLeaseResponse) LastModified() time.Time { + s := bclr.rawResponse.Header.Get("Last-Modified") + if s == "" { + return time.Time{} + } + t, err := time.Parse(time.RFC1123, s) + if err != nil { + panic(err) + } + return t +} + +// LeaseID returns the value for header x-ms-lease-id. +func (bclr BlobChangeLeaseResponse) LeaseID() string { + return bclr.rawResponse.Header.Get("x-ms-lease-id") +} + +// RequestID returns the value for header x-ms-request-id. +func (bclr BlobChangeLeaseResponse) RequestID() string { + return bclr.rawResponse.Header.Get("x-ms-request-id") +} + +// Version returns the value for header x-ms-version. +func (bclr BlobChangeLeaseResponse) Version() string { + return bclr.rawResponse.Header.Get("x-ms-version") +} + +// BlobCreateSnapshotResponse ... +type BlobCreateSnapshotResponse struct { + rawResponse *http.Response +} + +// Response returns the raw HTTP response object. +func (bcsr BlobCreateSnapshotResponse) Response() *http.Response { + return bcsr.rawResponse +} + +// StatusCode returns the HTTP status code of the response, e.g. 200. +func (bcsr BlobCreateSnapshotResponse) StatusCode() int { + return bcsr.rawResponse.StatusCode +} + +// Status returns the HTTP status message of the response, e.g. "200 OK". +func (bcsr BlobCreateSnapshotResponse) Status() string { + return bcsr.rawResponse.Status +} + +// Date returns the value for header Date. +func (bcsr BlobCreateSnapshotResponse) Date() time.Time { + s := bcsr.rawResponse.Header.Get("Date") + if s == "" { + return time.Time{} + } + t, err := time.Parse(time.RFC1123, s) + if err != nil { + panic(err) + } + return t +} + +// ErrorCode returns the value for header x-ms-error-code. +func (bcsr BlobCreateSnapshotResponse) ErrorCode() string { + return bcsr.rawResponse.Header.Get("x-ms-error-code") +} + +// ETag returns the value for header ETag. +func (bcsr BlobCreateSnapshotResponse) ETag() ETag { + return ETag(bcsr.rawResponse.Header.Get("ETag")) +} + +// LastModified returns the value for header Last-Modified. +func (bcsr BlobCreateSnapshotResponse) LastModified() time.Time { + s := bcsr.rawResponse.Header.Get("Last-Modified") + if s == "" { + return time.Time{} + } + t, err := time.Parse(time.RFC1123, s) + if err != nil { + panic(err) + } + return t +} + +// RequestID returns the value for header x-ms-request-id. +func (bcsr BlobCreateSnapshotResponse) RequestID() string { + return bcsr.rawResponse.Header.Get("x-ms-request-id") +} + +// Snapshot returns the value for header x-ms-snapshot. +func (bcsr BlobCreateSnapshotResponse) Snapshot() string { + return bcsr.rawResponse.Header.Get("x-ms-snapshot") +} + +// Version returns the value for header x-ms-version. +func (bcsr BlobCreateSnapshotResponse) Version() string { + return bcsr.rawResponse.Header.Get("x-ms-version") +} + +// BlobDeleteResponse ... +type BlobDeleteResponse struct { + rawResponse *http.Response +} + +// Response returns the raw HTTP response object. +func (bdr BlobDeleteResponse) Response() *http.Response { + return bdr.rawResponse +} + +// StatusCode returns the HTTP status code of the response, e.g. 200. +func (bdr BlobDeleteResponse) StatusCode() int { + return bdr.rawResponse.StatusCode +} + +// Status returns the HTTP status message of the response, e.g. "200 OK". +func (bdr BlobDeleteResponse) Status() string { + return bdr.rawResponse.Status +} + +// Date returns the value for header Date. +func (bdr BlobDeleteResponse) Date() time.Time { + s := bdr.rawResponse.Header.Get("Date") + if s == "" { + return time.Time{} + } + t, err := time.Parse(time.RFC1123, s) + if err != nil { + panic(err) + } + return t +} + +// ErrorCode returns the value for header x-ms-error-code. +func (bdr BlobDeleteResponse) ErrorCode() string { + return bdr.rawResponse.Header.Get("x-ms-error-code") +} + +// RequestID returns the value for header x-ms-request-id. +func (bdr BlobDeleteResponse) RequestID() string { + return bdr.rawResponse.Header.Get("x-ms-request-id") +} + +// Version returns the value for header x-ms-version. +func (bdr BlobDeleteResponse) Version() string { + return bdr.rawResponse.Header.Get("x-ms-version") +} + +// BlobFlatList ... +type BlobFlatList struct { + BlobItems []BlobItem `xml:"Blob"` +} + +// BlobGetPropertiesResponse ... +type BlobGetPropertiesResponse struct { + rawResponse *http.Response +} + +// NewMetadata returns user-defined key/value pairs. +func (bgpr BlobGetPropertiesResponse) NewMetadata() Metadata { + md := Metadata{} + for k, v := range bgpr.rawResponse.Header { + if len(k) > mdPrefixLen { + if prefix := k[0:mdPrefixLen]; strings.EqualFold(prefix, mdPrefix) { + md[strings.ToLower(k[mdPrefixLen:])] = v[0] + } + } + } + return md +} + +// Response returns the raw HTTP response object. +func (bgpr BlobGetPropertiesResponse) Response() *http.Response { + return bgpr.rawResponse +} + +// StatusCode returns the HTTP status code of the response, e.g. 200. +func (bgpr BlobGetPropertiesResponse) StatusCode() int { + return bgpr.rawResponse.StatusCode +} + +// Status returns the HTTP status message of the response, e.g. "200 OK". +func (bgpr BlobGetPropertiesResponse) Status() string { + return bgpr.rawResponse.Status +} + +// AcceptRanges returns the value for header Accept-Ranges. +func (bgpr BlobGetPropertiesResponse) AcceptRanges() string { + return bgpr.rawResponse.Header.Get("Accept-Ranges") +} + +// AccessTier returns the value for header x-ms-access-tier. +func (bgpr BlobGetPropertiesResponse) AccessTier() string { + return bgpr.rawResponse.Header.Get("x-ms-access-tier") +} + +// AccessTierInferred returns the value for header x-ms-access-tier-inferred. +func (bgpr BlobGetPropertiesResponse) AccessTierInferred() string { + return bgpr.rawResponse.Header.Get("x-ms-access-tier-inferred") +} + +// ArchiveStatus returns the value for header x-ms-archive-status. +func (bgpr BlobGetPropertiesResponse) ArchiveStatus() string { + return bgpr.rawResponse.Header.Get("x-ms-archive-status") +} + +// BlobCommittedBlockCount returns the value for header x-ms-blob-committed-block-count. +func (bgpr BlobGetPropertiesResponse) BlobCommittedBlockCount() int32 { + s := bgpr.rawResponse.Header.Get("x-ms-blob-committed-block-count") + if s == "" { + return -1 + } + i, err := strconv.ParseInt(s, 10, 32) + if err != nil { + panic(err) + } + return int32(i) +} + +// BlobSequenceNumber returns the value for header x-ms-blob-sequence-number. +func (bgpr BlobGetPropertiesResponse) BlobSequenceNumber() int64 { + s := bgpr.rawResponse.Header.Get("x-ms-blob-sequence-number") + if s == "" { + return -1 + } + i, err := strconv.ParseInt(s, 10, 64) + if err != nil { + panic(err) + } + return i +} + +// BlobType returns the value for header x-ms-blob-type. +func (bgpr BlobGetPropertiesResponse) BlobType() BlobType { + return BlobType(bgpr.rawResponse.Header.Get("x-ms-blob-type")) +} + +// CacheControl returns the value for header Cache-Control. +func (bgpr BlobGetPropertiesResponse) CacheControl() string { + return bgpr.rawResponse.Header.Get("Cache-Control") +} + +// ContentDisposition returns the value for header Content-Disposition. +func (bgpr BlobGetPropertiesResponse) ContentDisposition() string { + return bgpr.rawResponse.Header.Get("Content-Disposition") +} + +// ContentEncoding returns the value for header Content-Encoding. +func (bgpr BlobGetPropertiesResponse) ContentEncoding() string { + return bgpr.rawResponse.Header.Get("Content-Encoding") +} + +// ContentLanguage returns the value for header Content-Language. +func (bgpr BlobGetPropertiesResponse) ContentLanguage() string { + return bgpr.rawResponse.Header.Get("Content-Language") +} + +// ContentLength returns the value for header Content-Length. +func (bgpr BlobGetPropertiesResponse) ContentLength() int64 { + s := bgpr.rawResponse.Header.Get("Content-Length") + if s == "" { + return -1 + } + i, err := strconv.ParseInt(s, 10, 64) + if err != nil { + panic(err) + } + return i +} + +// ContentMD5 returns the value for header Content-MD5. +func (bgpr BlobGetPropertiesResponse) ContentMD5() []byte { + s := bgpr.rawResponse.Header.Get("Content-MD5") + if s == "" { + return nil + } + b, err := base64.StdEncoding.DecodeString(s) + if err != nil { + panic(err) + } + return b +} + +// ContentType returns the value for header Content-Type. +func (bgpr BlobGetPropertiesResponse) ContentType() string { + return bgpr.rawResponse.Header.Get("Content-Type") +} + +// CopyCompletionTime returns the value for header x-ms-copy-completion-time. +func (bgpr BlobGetPropertiesResponse) CopyCompletionTime() time.Time { + s := bgpr.rawResponse.Header.Get("x-ms-copy-completion-time") + if s == "" { + return time.Time{} + } + t, err := time.Parse(time.RFC1123, s) + if err != nil { + panic(err) + } + return t +} + +// CopyID returns the value for header x-ms-copy-id. +func (bgpr BlobGetPropertiesResponse) CopyID() string { + return bgpr.rawResponse.Header.Get("x-ms-copy-id") +} + +// CopyProgress returns the value for header x-ms-copy-progress. +func (bgpr BlobGetPropertiesResponse) CopyProgress() string { + return bgpr.rawResponse.Header.Get("x-ms-copy-progress") +} + +// CopySource returns the value for header x-ms-copy-source. +func (bgpr BlobGetPropertiesResponse) CopySource() string { + return bgpr.rawResponse.Header.Get("x-ms-copy-source") +} + +// CopyStatus returns the value for header x-ms-copy-status. +func (bgpr BlobGetPropertiesResponse) CopyStatus() CopyStatusType { + return CopyStatusType(bgpr.rawResponse.Header.Get("x-ms-copy-status")) +} + +// CopyStatusDescription returns the value for header x-ms-copy-status-description. +func (bgpr BlobGetPropertiesResponse) CopyStatusDescription() string { + return bgpr.rawResponse.Header.Get("x-ms-copy-status-description") +} + +// Date returns the value for header Date. +func (bgpr BlobGetPropertiesResponse) Date() time.Time { + s := bgpr.rawResponse.Header.Get("Date") + if s == "" { + return time.Time{} + } + t, err := time.Parse(time.RFC1123, s) + if err != nil { + panic(err) + } + return t +} + +// DestinationSnapshot returns the value for header x-ms-copy-destination-snapshot. +func (bgpr BlobGetPropertiesResponse) DestinationSnapshot() string { + return bgpr.rawResponse.Header.Get("x-ms-copy-destination-snapshot") +} + +// ErrorCode returns the value for header x-ms-error-code. +func (bgpr BlobGetPropertiesResponse) ErrorCode() string { + return bgpr.rawResponse.Header.Get("x-ms-error-code") +} + +// ETag returns the value for header ETag. +func (bgpr BlobGetPropertiesResponse) ETag() ETag { + return ETag(bgpr.rawResponse.Header.Get("ETag")) +} + +// IsIncrementalCopy returns the value for header x-ms-incremental-copy. +func (bgpr BlobGetPropertiesResponse) IsIncrementalCopy() string { + return bgpr.rawResponse.Header.Get("x-ms-incremental-copy") +} + +// IsServerEncrypted returns the value for header x-ms-server-encrypted. +func (bgpr BlobGetPropertiesResponse) IsServerEncrypted() string { + return bgpr.rawResponse.Header.Get("x-ms-server-encrypted") +} + +// LastModified returns the value for header Last-Modified. +func (bgpr BlobGetPropertiesResponse) LastModified() time.Time { + s := bgpr.rawResponse.Header.Get("Last-Modified") + if s == "" { + return time.Time{} + } + t, err := time.Parse(time.RFC1123, s) + if err != nil { + panic(err) + } + return t +} + +// LeaseDuration returns the value for header x-ms-lease-duration. +func (bgpr BlobGetPropertiesResponse) LeaseDuration() LeaseDurationType { + return LeaseDurationType(bgpr.rawResponse.Header.Get("x-ms-lease-duration")) +} + +// LeaseState returns the value for header x-ms-lease-state. +func (bgpr BlobGetPropertiesResponse) LeaseState() LeaseStateType { + return LeaseStateType(bgpr.rawResponse.Header.Get("x-ms-lease-state")) +} + +// LeaseStatus returns the value for header x-ms-lease-status. +func (bgpr BlobGetPropertiesResponse) LeaseStatus() LeaseStatusType { + return LeaseStatusType(bgpr.rawResponse.Header.Get("x-ms-lease-status")) +} + +// RequestID returns the value for header x-ms-request-id. +func (bgpr BlobGetPropertiesResponse) RequestID() string { + return bgpr.rawResponse.Header.Get("x-ms-request-id") +} + +// Version returns the value for header x-ms-version. +func (bgpr BlobGetPropertiesResponse) Version() string { + return bgpr.rawResponse.Header.Get("x-ms-version") +} + +// BlobHierarchyList ... +type BlobHierarchyList struct { + BlobPrefixes []BlobPrefix `xml:"BlobPrefix"` + BlobItems []BlobItem `xml:"Blob"` +} + +// BlobItem - An Azure Storage blob +type BlobItem struct { + Name string `xml:"Name"` + Deleted bool `xml:"Deleted"` + Snapshot string `xml:"Snapshot"` + Properties BlobProperties `xml:"Properties"` + Metadata Metadata `xml:"Metadata"` +} + +// BlobPrefix ... +type BlobPrefix struct { + Name string `xml:"Name"` +} + +// BlobProperties - Properties of a blob +type BlobProperties struct { + LastModified time.Time `xml:"Last-Modified"` + Etag ETag `xml:"Etag"` + // ContentLength - Size in bytes + ContentLength *int64 `xml:"Content-Length"` + ContentType *string `xml:"Content-Type"` + ContentEncoding *string `xml:"Content-Encoding"` + ContentLanguage *string `xml:"Content-Language"` + ContentMD5 []byte `xml:"Content-MD5"` + ContentDisposition *string `xml:"Content-Disposition"` + CacheControl *string `xml:"Cache-Control"` + BlobSequenceNumber *int64 `xml:"x-ms-blob-sequence-number"` + // BlobType - Possible values include: 'BlobBlockBlob', 'BlobPageBlob', 'BlobAppendBlob', 'BlobNone' + BlobType BlobType `xml:"BlobType"` + // LeaseStatus - Possible values include: 'LeaseStatusLocked', 'LeaseStatusUnlocked', 'LeaseStatusNone' + LeaseStatus LeaseStatusType `xml:"LeaseStatus"` + // LeaseState - Possible values include: 'LeaseStateAvailable', 'LeaseStateLeased', 'LeaseStateExpired', 'LeaseStateBreaking', 'LeaseStateBroken', 'LeaseStateNone' + LeaseState LeaseStateType `xml:"LeaseState"` + // LeaseDuration - Possible values include: 'LeaseDurationInfinite', 'LeaseDurationFixed', 'LeaseDurationNone' + LeaseDuration LeaseDurationType `xml:"LeaseDuration"` + CopyID *string `xml:"CopyId"` + // CopyStatus - Possible values include: 'CopyStatusPending', 'CopyStatusSuccess', 'CopyStatusAborted', 'CopyStatusFailed', 'CopyStatusNone' + CopyStatus CopyStatusType `xml:"CopyStatus"` + CopySource *string `xml:"CopySource"` + CopyProgress *string `xml:"CopyProgress"` + CopyCompletionTime *time.Time `xml:"CopyCompletionTime"` + CopyStatusDescription *string `xml:"CopyStatusDescription"` + ServerEncrypted *bool `xml:"ServerEncrypted"` + IncrementalCopy *bool `xml:"IncrementalCopy"` + DestinationSnapshot *string `xml:"DestinationSnapshot"` + DeletedTime *time.Time `xml:"DeletedTime"` + RemainingRetentionDays *int32 `xml:"RemainingRetentionDays"` + // AccessTier - Possible values include: 'AccessTierP4', 'AccessTierP6', 'AccessTierP10', 'AccessTierP20', 'AccessTierP30', 'AccessTierP40', 'AccessTierP50', 'AccessTierHot', 'AccessTierCool', 'AccessTierArchive', 'AccessTierNone' + AccessTier AccessTierType `xml:"AccessTier"` + AccessTierInferred *bool `xml:"AccessTierInferred"` + // ArchiveStatus - Possible values include: 'ArchiveStatusRehydratePendingToHot', 'ArchiveStatusRehydratePendingToCool', 'ArchiveStatusNone' + ArchiveStatus ArchiveStatusType `xml:"ArchiveStatus"` +} + +// MarshalXML implements the xml.Marshaler interface for BlobProperties. +func (bp BlobProperties) MarshalXML(e *xml.Encoder, start xml.StartElement) error { + if reflect.TypeOf((*BlobProperties)(nil)).Elem().Size() != reflect.TypeOf((*blobProperties)(nil)).Elem().Size() { + panic("size mismatch between BlobProperties and blobProperties") + } + bp2 := (*blobProperties)(unsafe.Pointer(&bp)) + return e.EncodeElement(*bp2, start) +} + +// UnmarshalXML implements the xml.Unmarshaler interface for BlobProperties. +func (bp *BlobProperties) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { + if reflect.TypeOf((*BlobProperties)(nil)).Elem().Size() != reflect.TypeOf((*blobProperties)(nil)).Elem().Size() { + panic("size mismatch between BlobProperties and blobProperties") + } + bp2 := (*blobProperties)(unsafe.Pointer(bp)) + return d.DecodeElement(bp2, &start) +} + +// BlobReleaseLeaseResponse ... +type BlobReleaseLeaseResponse struct { + rawResponse *http.Response +} + +// Response returns the raw HTTP response object. +func (brlr BlobReleaseLeaseResponse) Response() *http.Response { + return brlr.rawResponse +} + +// StatusCode returns the HTTP status code of the response, e.g. 200. +func (brlr BlobReleaseLeaseResponse) StatusCode() int { + return brlr.rawResponse.StatusCode +} + +// Status returns the HTTP status message of the response, e.g. "200 OK". +func (brlr BlobReleaseLeaseResponse) Status() string { + return brlr.rawResponse.Status +} + +// Date returns the value for header Date. +func (brlr BlobReleaseLeaseResponse) Date() time.Time { + s := brlr.rawResponse.Header.Get("Date") + if s == "" { + return time.Time{} + } + t, err := time.Parse(time.RFC1123, s) + if err != nil { + panic(err) + } + return t +} + +// ErrorCode returns the value for header x-ms-error-code. +func (brlr BlobReleaseLeaseResponse) ErrorCode() string { + return brlr.rawResponse.Header.Get("x-ms-error-code") +} + +// ETag returns the value for header ETag. +func (brlr BlobReleaseLeaseResponse) ETag() ETag { + return ETag(brlr.rawResponse.Header.Get("ETag")) +} + +// LastModified returns the value for header Last-Modified. +func (brlr BlobReleaseLeaseResponse) LastModified() time.Time { + s := brlr.rawResponse.Header.Get("Last-Modified") + if s == "" { + return time.Time{} + } + t, err := time.Parse(time.RFC1123, s) + if err != nil { + panic(err) + } + return t +} + +// RequestID returns the value for header x-ms-request-id. +func (brlr BlobReleaseLeaseResponse) RequestID() string { + return brlr.rawResponse.Header.Get("x-ms-request-id") +} + +// Version returns the value for header x-ms-version. +func (brlr BlobReleaseLeaseResponse) Version() string { + return brlr.rawResponse.Header.Get("x-ms-version") +} + +// BlobRenewLeaseResponse ... +type BlobRenewLeaseResponse struct { + rawResponse *http.Response +} + +// Response returns the raw HTTP response object. +func (brlr BlobRenewLeaseResponse) Response() *http.Response { + return brlr.rawResponse +} + +// StatusCode returns the HTTP status code of the response, e.g. 200. +func (brlr BlobRenewLeaseResponse) StatusCode() int { + return brlr.rawResponse.StatusCode +} + +// Status returns the HTTP status message of the response, e.g. "200 OK". +func (brlr BlobRenewLeaseResponse) Status() string { + return brlr.rawResponse.Status +} + +// Date returns the value for header Date. +func (brlr BlobRenewLeaseResponse) Date() time.Time { + s := brlr.rawResponse.Header.Get("Date") + if s == "" { + return time.Time{} + } + t, err := time.Parse(time.RFC1123, s) + if err != nil { + panic(err) + } + return t +} + +// ErrorCode returns the value for header x-ms-error-code. +func (brlr BlobRenewLeaseResponse) ErrorCode() string { + return brlr.rawResponse.Header.Get("x-ms-error-code") +} + +// ETag returns the value for header ETag. +func (brlr BlobRenewLeaseResponse) ETag() ETag { + return ETag(brlr.rawResponse.Header.Get("ETag")) +} + +// LastModified returns the value for header Last-Modified. +func (brlr BlobRenewLeaseResponse) LastModified() time.Time { + s := brlr.rawResponse.Header.Get("Last-Modified") + if s == "" { + return time.Time{} + } + t, err := time.Parse(time.RFC1123, s) + if err != nil { + panic(err) + } + return t +} + +// LeaseID returns the value for header x-ms-lease-id. +func (brlr BlobRenewLeaseResponse) LeaseID() string { + return brlr.rawResponse.Header.Get("x-ms-lease-id") +} + +// RequestID returns the value for header x-ms-request-id. +func (brlr BlobRenewLeaseResponse) RequestID() string { + return brlr.rawResponse.Header.Get("x-ms-request-id") +} + +// Version returns the value for header x-ms-version. +func (brlr BlobRenewLeaseResponse) Version() string { + return brlr.rawResponse.Header.Get("x-ms-version") +} + +// BlobSetHTTPHeadersResponse ... +type BlobSetHTTPHeadersResponse struct { + rawResponse *http.Response +} + +// Response returns the raw HTTP response object. +func (bshhr BlobSetHTTPHeadersResponse) Response() *http.Response { + return bshhr.rawResponse +} + +// StatusCode returns the HTTP status code of the response, e.g. 200. +func (bshhr BlobSetHTTPHeadersResponse) StatusCode() int { + return bshhr.rawResponse.StatusCode +} + +// Status returns the HTTP status message of the response, e.g. "200 OK". +func (bshhr BlobSetHTTPHeadersResponse) Status() string { + return bshhr.rawResponse.Status +} + +// BlobSequenceNumber returns the value for header x-ms-blob-sequence-number. +func (bshhr BlobSetHTTPHeadersResponse) BlobSequenceNumber() int64 { + s := bshhr.rawResponse.Header.Get("x-ms-blob-sequence-number") + if s == "" { + return -1 + } + i, err := strconv.ParseInt(s, 10, 64) + if err != nil { + panic(err) + } + return i +} + +// Date returns the value for header Date. +func (bshhr BlobSetHTTPHeadersResponse) Date() time.Time { + s := bshhr.rawResponse.Header.Get("Date") + if s == "" { + return time.Time{} + } + t, err := time.Parse(time.RFC1123, s) + if err != nil { + panic(err) + } + return t +} + +// ErrorCode returns the value for header x-ms-error-code. +func (bshhr BlobSetHTTPHeadersResponse) ErrorCode() string { + return bshhr.rawResponse.Header.Get("x-ms-error-code") +} + +// ETag returns the value for header ETag. +func (bshhr BlobSetHTTPHeadersResponse) ETag() ETag { + return ETag(bshhr.rawResponse.Header.Get("ETag")) +} + +// LastModified returns the value for header Last-Modified. +func (bshhr BlobSetHTTPHeadersResponse) LastModified() time.Time { + s := bshhr.rawResponse.Header.Get("Last-Modified") + if s == "" { + return time.Time{} + } + t, err := time.Parse(time.RFC1123, s) + if err != nil { + panic(err) + } + return t +} + +// RequestID returns the value for header x-ms-request-id. +func (bshhr BlobSetHTTPHeadersResponse) RequestID() string { + return bshhr.rawResponse.Header.Get("x-ms-request-id") +} + +// Version returns the value for header x-ms-version. +func (bshhr BlobSetHTTPHeadersResponse) Version() string { + return bshhr.rawResponse.Header.Get("x-ms-version") +} + +// BlobSetMetadataResponse ... +type BlobSetMetadataResponse struct { + rawResponse *http.Response +} + +// Response returns the raw HTTP response object. +func (bsmr BlobSetMetadataResponse) Response() *http.Response { + return bsmr.rawResponse +} + +// StatusCode returns the HTTP status code of the response, e.g. 200. +func (bsmr BlobSetMetadataResponse) StatusCode() int { + return bsmr.rawResponse.StatusCode +} + +// Status returns the HTTP status message of the response, e.g. "200 OK". +func (bsmr BlobSetMetadataResponse) Status() string { + return bsmr.rawResponse.Status +} + +// Date returns the value for header Date. +func (bsmr BlobSetMetadataResponse) Date() time.Time { + s := bsmr.rawResponse.Header.Get("Date") + if s == "" { + return time.Time{} + } + t, err := time.Parse(time.RFC1123, s) + if err != nil { + panic(err) + } + return t +} + +// ErrorCode returns the value for header x-ms-error-code. +func (bsmr BlobSetMetadataResponse) ErrorCode() string { + return bsmr.rawResponse.Header.Get("x-ms-error-code") +} + +// ETag returns the value for header ETag. +func (bsmr BlobSetMetadataResponse) ETag() ETag { + return ETag(bsmr.rawResponse.Header.Get("ETag")) +} + +// IsServerEncrypted returns the value for header x-ms-request-server-encrypted. +func (bsmr BlobSetMetadataResponse) IsServerEncrypted() string { + return bsmr.rawResponse.Header.Get("x-ms-request-server-encrypted") +} + +// LastModified returns the value for header Last-Modified. +func (bsmr BlobSetMetadataResponse) LastModified() time.Time { + s := bsmr.rawResponse.Header.Get("Last-Modified") + if s == "" { + return time.Time{} + } + t, err := time.Parse(time.RFC1123, s) + if err != nil { + panic(err) + } + return t +} + +// RequestID returns the value for header x-ms-request-id. +func (bsmr BlobSetMetadataResponse) RequestID() string { + return bsmr.rawResponse.Header.Get("x-ms-request-id") +} + +// Version returns the value for header x-ms-version. +func (bsmr BlobSetMetadataResponse) Version() string { + return bsmr.rawResponse.Header.Get("x-ms-version") +} + +// BlobSetTierResponse ... +type BlobSetTierResponse struct { + rawResponse *http.Response +} + +// Response returns the raw HTTP response object. +func (bstr BlobSetTierResponse) Response() *http.Response { + return bstr.rawResponse +} + +// StatusCode returns the HTTP status code of the response, e.g. 200. +func (bstr BlobSetTierResponse) StatusCode() int { + return bstr.rawResponse.StatusCode +} + +// Status returns the HTTP status message of the response, e.g. "200 OK". +func (bstr BlobSetTierResponse) Status() string { + return bstr.rawResponse.Status +} + +// ErrorCode returns the value for header x-ms-error-code. +func (bstr BlobSetTierResponse) ErrorCode() string { + return bstr.rawResponse.Header.Get("x-ms-error-code") +} + +// RequestID returns the value for header x-ms-request-id. +func (bstr BlobSetTierResponse) RequestID() string { + return bstr.rawResponse.Header.Get("x-ms-request-id") +} + +// Version returns the value for header x-ms-version. +func (bstr BlobSetTierResponse) Version() string { + return bstr.rawResponse.Header.Get("x-ms-version") +} + +// BlobStartCopyFromURLResponse ... +type BlobStartCopyFromURLResponse struct { + rawResponse *http.Response +} + +// Response returns the raw HTTP response object. +func (bscfur BlobStartCopyFromURLResponse) Response() *http.Response { + return bscfur.rawResponse +} + +// StatusCode returns the HTTP status code of the response, e.g. 200. +func (bscfur BlobStartCopyFromURLResponse) StatusCode() int { + return bscfur.rawResponse.StatusCode +} + +// Status returns the HTTP status message of the response, e.g. "200 OK". +func (bscfur BlobStartCopyFromURLResponse) Status() string { + return bscfur.rawResponse.Status +} + +// CopyID returns the value for header x-ms-copy-id. +func (bscfur BlobStartCopyFromURLResponse) CopyID() string { + return bscfur.rawResponse.Header.Get("x-ms-copy-id") +} + +// CopyStatus returns the value for header x-ms-copy-status. +func (bscfur BlobStartCopyFromURLResponse) CopyStatus() CopyStatusType { + return CopyStatusType(bscfur.rawResponse.Header.Get("x-ms-copy-status")) +} + +// Date returns the value for header Date. +func (bscfur BlobStartCopyFromURLResponse) Date() time.Time { + s := bscfur.rawResponse.Header.Get("Date") + if s == "" { + return time.Time{} + } + t, err := time.Parse(time.RFC1123, s) + if err != nil { + panic(err) + } + return t +} + +// ErrorCode returns the value for header x-ms-error-code. +func (bscfur BlobStartCopyFromURLResponse) ErrorCode() string { + return bscfur.rawResponse.Header.Get("x-ms-error-code") +} + +// ETag returns the value for header ETag. +func (bscfur BlobStartCopyFromURLResponse) ETag() ETag { + return ETag(bscfur.rawResponse.Header.Get("ETag")) +} + +// LastModified returns the value for header Last-Modified. +func (bscfur BlobStartCopyFromURLResponse) LastModified() time.Time { + s := bscfur.rawResponse.Header.Get("Last-Modified") + if s == "" { + return time.Time{} + } + t, err := time.Parse(time.RFC1123, s) + if err != nil { + panic(err) + } + return t +} + +// RequestID returns the value for header x-ms-request-id. +func (bscfur BlobStartCopyFromURLResponse) RequestID() string { + return bscfur.rawResponse.Header.Get("x-ms-request-id") +} + +// Version returns the value for header x-ms-version. +func (bscfur BlobStartCopyFromURLResponse) Version() string { + return bscfur.rawResponse.Header.Get("x-ms-version") +} + +// BlobUndeleteResponse ... +type BlobUndeleteResponse struct { + rawResponse *http.Response +} + +// Response returns the raw HTTP response object. +func (bur BlobUndeleteResponse) Response() *http.Response { + return bur.rawResponse +} + +// StatusCode returns the HTTP status code of the response, e.g. 200. +func (bur BlobUndeleteResponse) StatusCode() int { + return bur.rawResponse.StatusCode +} + +// Status returns the HTTP status message of the response, e.g. "200 OK". +func (bur BlobUndeleteResponse) Status() string { + return bur.rawResponse.Status +} + +// Date returns the value for header Date. +func (bur BlobUndeleteResponse) Date() time.Time { + s := bur.rawResponse.Header.Get("Date") + if s == "" { + return time.Time{} + } + t, err := time.Parse(time.RFC1123, s) + if err != nil { + panic(err) + } + return t +} + +// ErrorCode returns the value for header x-ms-error-code. +func (bur BlobUndeleteResponse) ErrorCode() string { + return bur.rawResponse.Header.Get("x-ms-error-code") +} + +// RequestID returns the value for header x-ms-request-id. +func (bur BlobUndeleteResponse) RequestID() string { + return bur.rawResponse.Header.Get("x-ms-request-id") +} + +// Version returns the value for header x-ms-version. +func (bur BlobUndeleteResponse) Version() string { + return bur.rawResponse.Header.Get("x-ms-version") +} + +// Block - Represents a single block in a block blob. It describes the block's ID and size. +type Block struct { + // Name - The base64 encoded block ID. + Name string `xml:"Name"` + // Size - The block size in bytes. + Size int32 `xml:"Size"` +} + +// BlockBlobCommitBlockListResponse ... +type BlockBlobCommitBlockListResponse struct { + rawResponse *http.Response +} + +// Response returns the raw HTTP response object. +func (bbcblr BlockBlobCommitBlockListResponse) Response() *http.Response { + return bbcblr.rawResponse +} + +// StatusCode returns the HTTP status code of the response, e.g. 200. +func (bbcblr BlockBlobCommitBlockListResponse) StatusCode() int { + return bbcblr.rawResponse.StatusCode +} + +// Status returns the HTTP status message of the response, e.g. "200 OK". +func (bbcblr BlockBlobCommitBlockListResponse) Status() string { + return bbcblr.rawResponse.Status +} + +// ContentMD5 returns the value for header Content-MD5. +func (bbcblr BlockBlobCommitBlockListResponse) ContentMD5() []byte { + s := bbcblr.rawResponse.Header.Get("Content-MD5") + if s == "" { + return nil + } + b, err := base64.StdEncoding.DecodeString(s) + if err != nil { + panic(err) + } + return b +} + +// Date returns the value for header Date. +func (bbcblr BlockBlobCommitBlockListResponse) Date() time.Time { + s := bbcblr.rawResponse.Header.Get("Date") + if s == "" { + return time.Time{} + } + t, err := time.Parse(time.RFC1123, s) + if err != nil { + panic(err) + } + return t +} + +// ErrorCode returns the value for header x-ms-error-code. +func (bbcblr BlockBlobCommitBlockListResponse) ErrorCode() string { + return bbcblr.rawResponse.Header.Get("x-ms-error-code") +} + +// ETag returns the value for header ETag. +func (bbcblr BlockBlobCommitBlockListResponse) ETag() ETag { + return ETag(bbcblr.rawResponse.Header.Get("ETag")) +} + +// IsServerEncrypted returns the value for header x-ms-request-server-encrypted. +func (bbcblr BlockBlobCommitBlockListResponse) IsServerEncrypted() string { + return bbcblr.rawResponse.Header.Get("x-ms-request-server-encrypted") +} + +// LastModified returns the value for header Last-Modified. +func (bbcblr BlockBlobCommitBlockListResponse) LastModified() time.Time { + s := bbcblr.rawResponse.Header.Get("Last-Modified") + if s == "" { + return time.Time{} + } + t, err := time.Parse(time.RFC1123, s) + if err != nil { + panic(err) + } + return t +} + +// RequestID returns the value for header x-ms-request-id. +func (bbcblr BlockBlobCommitBlockListResponse) RequestID() string { + return bbcblr.rawResponse.Header.Get("x-ms-request-id") +} + +// Version returns the value for header x-ms-version. +func (bbcblr BlockBlobCommitBlockListResponse) Version() string { + return bbcblr.rawResponse.Header.Get("x-ms-version") +} + +// BlockBlobStageBlockFromURLResponse ... +type BlockBlobStageBlockFromURLResponse struct { + rawResponse *http.Response +} + +// Response returns the raw HTTP response object. +func (bbsbfur BlockBlobStageBlockFromURLResponse) Response() *http.Response { + return bbsbfur.rawResponse +} + +// StatusCode returns the HTTP status code of the response, e.g. 200. +func (bbsbfur BlockBlobStageBlockFromURLResponse) StatusCode() int { + return bbsbfur.rawResponse.StatusCode +} + +// Status returns the HTTP status message of the response, e.g. "200 OK". +func (bbsbfur BlockBlobStageBlockFromURLResponse) Status() string { + return bbsbfur.rawResponse.Status +} + +// ContentMD5 returns the value for header Content-MD5. +func (bbsbfur BlockBlobStageBlockFromURLResponse) ContentMD5() []byte { + s := bbsbfur.rawResponse.Header.Get("Content-MD5") + if s == "" { + return nil + } + b, err := base64.StdEncoding.DecodeString(s) + if err != nil { + panic(err) + } + return b +} + +// Date returns the value for header Date. +func (bbsbfur BlockBlobStageBlockFromURLResponse) Date() time.Time { + s := bbsbfur.rawResponse.Header.Get("Date") + if s == "" { + return time.Time{} + } + t, err := time.Parse(time.RFC1123, s) + if err != nil { + panic(err) + } + return t +} + +// ErrorCode returns the value for header x-ms-error-code. +func (bbsbfur BlockBlobStageBlockFromURLResponse) ErrorCode() string { + return bbsbfur.rawResponse.Header.Get("x-ms-error-code") +} + +// IsServerEncrypted returns the value for header x-ms-request-server-encrypted. +func (bbsbfur BlockBlobStageBlockFromURLResponse) IsServerEncrypted() string { + return bbsbfur.rawResponse.Header.Get("x-ms-request-server-encrypted") +} + +// RequestID returns the value for header x-ms-request-id. +func (bbsbfur BlockBlobStageBlockFromURLResponse) RequestID() string { + return bbsbfur.rawResponse.Header.Get("x-ms-request-id") +} + +// Version returns the value for header x-ms-version. +func (bbsbfur BlockBlobStageBlockFromURLResponse) Version() string { + return bbsbfur.rawResponse.Header.Get("x-ms-version") +} + +// BlockBlobStageBlockResponse ... +type BlockBlobStageBlockResponse struct { + rawResponse *http.Response +} + +// Response returns the raw HTTP response object. +func (bbsbr BlockBlobStageBlockResponse) Response() *http.Response { + return bbsbr.rawResponse +} + +// StatusCode returns the HTTP status code of the response, e.g. 200. +func (bbsbr BlockBlobStageBlockResponse) StatusCode() int { + return bbsbr.rawResponse.StatusCode +} + +// Status returns the HTTP status message of the response, e.g. "200 OK". +func (bbsbr BlockBlobStageBlockResponse) Status() string { + return bbsbr.rawResponse.Status +} + +// ContentMD5 returns the value for header Content-MD5. +func (bbsbr BlockBlobStageBlockResponse) ContentMD5() []byte { + s := bbsbr.rawResponse.Header.Get("Content-MD5") + if s == "" { + return nil + } + b, err := base64.StdEncoding.DecodeString(s) + if err != nil { + panic(err) + } + return b +} + +// Date returns the value for header Date. +func (bbsbr BlockBlobStageBlockResponse) Date() time.Time { + s := bbsbr.rawResponse.Header.Get("Date") + if s == "" { + return time.Time{} + } + t, err := time.Parse(time.RFC1123, s) + if err != nil { + panic(err) + } + return t +} + +// ErrorCode returns the value for header x-ms-error-code. +func (bbsbr BlockBlobStageBlockResponse) ErrorCode() string { + return bbsbr.rawResponse.Header.Get("x-ms-error-code") +} + +// IsServerEncrypted returns the value for header x-ms-request-server-encrypted. +func (bbsbr BlockBlobStageBlockResponse) IsServerEncrypted() string { + return bbsbr.rawResponse.Header.Get("x-ms-request-server-encrypted") +} + +// RequestID returns the value for header x-ms-request-id. +func (bbsbr BlockBlobStageBlockResponse) RequestID() string { + return bbsbr.rawResponse.Header.Get("x-ms-request-id") +} + +// Version returns the value for header x-ms-version. +func (bbsbr BlockBlobStageBlockResponse) Version() string { + return bbsbr.rawResponse.Header.Get("x-ms-version") +} + +// BlockBlobUploadResponse ... +type BlockBlobUploadResponse struct { + rawResponse *http.Response +} + +// Response returns the raw HTTP response object. +func (bbur BlockBlobUploadResponse) Response() *http.Response { + return bbur.rawResponse +} + +// StatusCode returns the HTTP status code of the response, e.g. 200. +func (bbur BlockBlobUploadResponse) StatusCode() int { + return bbur.rawResponse.StatusCode +} + +// Status returns the HTTP status message of the response, e.g. "200 OK". +func (bbur BlockBlobUploadResponse) Status() string { + return bbur.rawResponse.Status +} + +// ContentMD5 returns the value for header Content-MD5. +func (bbur BlockBlobUploadResponse) ContentMD5() []byte { + s := bbur.rawResponse.Header.Get("Content-MD5") + if s == "" { + return nil + } + b, err := base64.StdEncoding.DecodeString(s) + if err != nil { + panic(err) + } + return b +} + +// Date returns the value for header Date. +func (bbur BlockBlobUploadResponse) Date() time.Time { + s := bbur.rawResponse.Header.Get("Date") + if s == "" { + return time.Time{} + } + t, err := time.Parse(time.RFC1123, s) + if err != nil { + panic(err) + } + return t +} + +// ErrorCode returns the value for header x-ms-error-code. +func (bbur BlockBlobUploadResponse) ErrorCode() string { + return bbur.rawResponse.Header.Get("x-ms-error-code") +} + +// ETag returns the value for header ETag. +func (bbur BlockBlobUploadResponse) ETag() ETag { + return ETag(bbur.rawResponse.Header.Get("ETag")) +} + +// IsServerEncrypted returns the value for header x-ms-request-server-encrypted. +func (bbur BlockBlobUploadResponse) IsServerEncrypted() string { + return bbur.rawResponse.Header.Get("x-ms-request-server-encrypted") +} + +// LastModified returns the value for header Last-Modified. +func (bbur BlockBlobUploadResponse) LastModified() time.Time { + s := bbur.rawResponse.Header.Get("Last-Modified") + if s == "" { + return time.Time{} + } + t, err := time.Parse(time.RFC1123, s) + if err != nil { + panic(err) + } + return t +} + +// RequestID returns the value for header x-ms-request-id. +func (bbur BlockBlobUploadResponse) RequestID() string { + return bbur.rawResponse.Header.Get("x-ms-request-id") +} + +// Version returns the value for header x-ms-version. +func (bbur BlockBlobUploadResponse) Version() string { + return bbur.rawResponse.Header.Get("x-ms-version") +} + +// BlockList ... +type BlockList struct { + rawResponse *http.Response + CommittedBlocks []Block `xml:"CommittedBlocks>Block"` + UncommittedBlocks []Block `xml:"UncommittedBlocks>Block"` +} + +// Response returns the raw HTTP response object. +func (bl BlockList) Response() *http.Response { + return bl.rawResponse +} + +// StatusCode returns the HTTP status code of the response, e.g. 200. +func (bl BlockList) StatusCode() int { + return bl.rawResponse.StatusCode +} + +// Status returns the HTTP status message of the response, e.g. "200 OK". +func (bl BlockList) Status() string { + return bl.rawResponse.Status +} + +// BlobContentLength returns the value for header x-ms-blob-content-length. +func (bl BlockList) BlobContentLength() int64 { + s := bl.rawResponse.Header.Get("x-ms-blob-content-length") + if s == "" { + return -1 + } + i, err := strconv.ParseInt(s, 10, 64) + if err != nil { + panic(err) + } + return i +} + +// ContentType returns the value for header Content-Type. +func (bl BlockList) ContentType() string { + return bl.rawResponse.Header.Get("Content-Type") +} + +// Date returns the value for header Date. +func (bl BlockList) Date() time.Time { + s := bl.rawResponse.Header.Get("Date") + if s == "" { + return time.Time{} + } + t, err := time.Parse(time.RFC1123, s) + if err != nil { + panic(err) + } + return t +} + +// ErrorCode returns the value for header x-ms-error-code. +func (bl BlockList) ErrorCode() string { + return bl.rawResponse.Header.Get("x-ms-error-code") +} + +// ETag returns the value for header ETag. +func (bl BlockList) ETag() ETag { + return ETag(bl.rawResponse.Header.Get("ETag")) +} + +// LastModified returns the value for header Last-Modified. +func (bl BlockList) LastModified() time.Time { + s := bl.rawResponse.Header.Get("Last-Modified") + if s == "" { + return time.Time{} + } + t, err := time.Parse(time.RFC1123, s) + if err != nil { + panic(err) + } + return t +} + +// RequestID returns the value for header x-ms-request-id. +func (bl BlockList) RequestID() string { + return bl.rawResponse.Header.Get("x-ms-request-id") +} + +// Version returns the value for header x-ms-version. +func (bl BlockList) Version() string { + return bl.rawResponse.Header.Get("x-ms-version") +} + +// BlockLookupList ... +type BlockLookupList struct { + // XMLName is used for marshalling and is subject to removal in a future release. + XMLName xml.Name `xml:"BlockList"` + Committed []string `xml:"Committed"` + Uncommitted []string `xml:"Uncommitted"` + Latest []string `xml:"Latest"` +} + +// ClearRange ... +type ClearRange struct { + Start int64 `xml:"Start"` + End int64 `xml:"End"` +} + +// ContainerAcquireLeaseResponse ... +type ContainerAcquireLeaseResponse struct { + rawResponse *http.Response +} + +// Response returns the raw HTTP response object. +func (calr ContainerAcquireLeaseResponse) Response() *http.Response { + return calr.rawResponse +} + +// StatusCode returns the HTTP status code of the response, e.g. 200. +func (calr ContainerAcquireLeaseResponse) StatusCode() int { + return calr.rawResponse.StatusCode +} + +// Status returns the HTTP status message of the response, e.g. "200 OK". +func (calr ContainerAcquireLeaseResponse) Status() string { + return calr.rawResponse.Status +} + +// Date returns the value for header Date. +func (calr ContainerAcquireLeaseResponse) Date() time.Time { + s := calr.rawResponse.Header.Get("Date") + if s == "" { + return time.Time{} + } + t, err := time.Parse(time.RFC1123, s) + if err != nil { + panic(err) + } + return t +} + +// ErrorCode returns the value for header x-ms-error-code. +func (calr ContainerAcquireLeaseResponse) ErrorCode() string { + return calr.rawResponse.Header.Get("x-ms-error-code") +} + +// ETag returns the value for header ETag. +func (calr ContainerAcquireLeaseResponse) ETag() ETag { + return ETag(calr.rawResponse.Header.Get("ETag")) +} + +// LastModified returns the value for header Last-Modified. +func (calr ContainerAcquireLeaseResponse) LastModified() time.Time { + s := calr.rawResponse.Header.Get("Last-Modified") + if s == "" { + return time.Time{} + } + t, err := time.Parse(time.RFC1123, s) + if err != nil { + panic(err) + } + return t +} + +// LeaseID returns the value for header x-ms-lease-id. +func (calr ContainerAcquireLeaseResponse) LeaseID() string { + return calr.rawResponse.Header.Get("x-ms-lease-id") +} + +// RequestID returns the value for header x-ms-request-id. +func (calr ContainerAcquireLeaseResponse) RequestID() string { + return calr.rawResponse.Header.Get("x-ms-request-id") +} + +// Version returns the value for header x-ms-version. +func (calr ContainerAcquireLeaseResponse) Version() string { + return calr.rawResponse.Header.Get("x-ms-version") +} + +// ContainerBreakLeaseResponse ... +type ContainerBreakLeaseResponse struct { + rawResponse *http.Response +} + +// Response returns the raw HTTP response object. +func (cblr ContainerBreakLeaseResponse) Response() *http.Response { + return cblr.rawResponse +} + +// StatusCode returns the HTTP status code of the response, e.g. 200. +func (cblr ContainerBreakLeaseResponse) StatusCode() int { + return cblr.rawResponse.StatusCode +} + +// Status returns the HTTP status message of the response, e.g. "200 OK". +func (cblr ContainerBreakLeaseResponse) Status() string { + return cblr.rawResponse.Status +} + +// Date returns the value for header Date. +func (cblr ContainerBreakLeaseResponse) Date() time.Time { + s := cblr.rawResponse.Header.Get("Date") + if s == "" { + return time.Time{} + } + t, err := time.Parse(time.RFC1123, s) + if err != nil { + panic(err) + } + return t +} + +// ErrorCode returns the value for header x-ms-error-code. +func (cblr ContainerBreakLeaseResponse) ErrorCode() string { + return cblr.rawResponse.Header.Get("x-ms-error-code") +} + +// ETag returns the value for header ETag. +func (cblr ContainerBreakLeaseResponse) ETag() ETag { + return ETag(cblr.rawResponse.Header.Get("ETag")) +} + +// LastModified returns the value for header Last-Modified. +func (cblr ContainerBreakLeaseResponse) LastModified() time.Time { + s := cblr.rawResponse.Header.Get("Last-Modified") + if s == "" { + return time.Time{} + } + t, err := time.Parse(time.RFC1123, s) + if err != nil { + panic(err) + } + return t +} + +// LeaseTime returns the value for header x-ms-lease-time. +func (cblr ContainerBreakLeaseResponse) LeaseTime() int32 { + s := cblr.rawResponse.Header.Get("x-ms-lease-time") + if s == "" { + return -1 + } + i, err := strconv.ParseInt(s, 10, 32) + if err != nil { + panic(err) + } + return int32(i) +} + +// RequestID returns the value for header x-ms-request-id. +func (cblr ContainerBreakLeaseResponse) RequestID() string { + return cblr.rawResponse.Header.Get("x-ms-request-id") +} + +// Version returns the value for header x-ms-version. +func (cblr ContainerBreakLeaseResponse) Version() string { + return cblr.rawResponse.Header.Get("x-ms-version") +} + +// ContainerChangeLeaseResponse ... +type ContainerChangeLeaseResponse struct { + rawResponse *http.Response +} + +// Response returns the raw HTTP response object. +func (cclr ContainerChangeLeaseResponse) Response() *http.Response { + return cclr.rawResponse +} + +// StatusCode returns the HTTP status code of the response, e.g. 200. +func (cclr ContainerChangeLeaseResponse) StatusCode() int { + return cclr.rawResponse.StatusCode +} + +// Status returns the HTTP status message of the response, e.g. "200 OK". +func (cclr ContainerChangeLeaseResponse) Status() string { + return cclr.rawResponse.Status +} + +// Date returns the value for header Date. +func (cclr ContainerChangeLeaseResponse) Date() time.Time { + s := cclr.rawResponse.Header.Get("Date") + if s == "" { + return time.Time{} + } + t, err := time.Parse(time.RFC1123, s) + if err != nil { + panic(err) + } + return t +} + +// ErrorCode returns the value for header x-ms-error-code. +func (cclr ContainerChangeLeaseResponse) ErrorCode() string { + return cclr.rawResponse.Header.Get("x-ms-error-code") +} + +// ETag returns the value for header ETag. +func (cclr ContainerChangeLeaseResponse) ETag() ETag { + return ETag(cclr.rawResponse.Header.Get("ETag")) +} + +// LastModified returns the value for header Last-Modified. +func (cclr ContainerChangeLeaseResponse) LastModified() time.Time { + s := cclr.rawResponse.Header.Get("Last-Modified") + if s == "" { + return time.Time{} + } + t, err := time.Parse(time.RFC1123, s) + if err != nil { + panic(err) + } + return t +} + +// LeaseID returns the value for header x-ms-lease-id. +func (cclr ContainerChangeLeaseResponse) LeaseID() string { + return cclr.rawResponse.Header.Get("x-ms-lease-id") +} + +// RequestID returns the value for header x-ms-request-id. +func (cclr ContainerChangeLeaseResponse) RequestID() string { + return cclr.rawResponse.Header.Get("x-ms-request-id") +} + +// Version returns the value for header x-ms-version. +func (cclr ContainerChangeLeaseResponse) Version() string { + return cclr.rawResponse.Header.Get("x-ms-version") +} + +// ContainerCreateResponse ... +type ContainerCreateResponse struct { + rawResponse *http.Response +} + +// Response returns the raw HTTP response object. +func (ccr ContainerCreateResponse) Response() *http.Response { + return ccr.rawResponse +} + +// StatusCode returns the HTTP status code of the response, e.g. 200. +func (ccr ContainerCreateResponse) StatusCode() int { + return ccr.rawResponse.StatusCode +} + +// Status returns the HTTP status message of the response, e.g. "200 OK". +func (ccr ContainerCreateResponse) Status() string { + return ccr.rawResponse.Status +} + +// Date returns the value for header Date. +func (ccr ContainerCreateResponse) Date() time.Time { + s := ccr.rawResponse.Header.Get("Date") + if s == "" { + return time.Time{} + } + t, err := time.Parse(time.RFC1123, s) + if err != nil { + panic(err) + } + return t +} + +// ErrorCode returns the value for header x-ms-error-code. +func (ccr ContainerCreateResponse) ErrorCode() string { + return ccr.rawResponse.Header.Get("x-ms-error-code") +} + +// ETag returns the value for header ETag. +func (ccr ContainerCreateResponse) ETag() ETag { + return ETag(ccr.rawResponse.Header.Get("ETag")) +} + +// LastModified returns the value for header Last-Modified. +func (ccr ContainerCreateResponse) LastModified() time.Time { + s := ccr.rawResponse.Header.Get("Last-Modified") + if s == "" { + return time.Time{} + } + t, err := time.Parse(time.RFC1123, s) + if err != nil { + panic(err) + } + return t +} + +// RequestID returns the value for header x-ms-request-id. +func (ccr ContainerCreateResponse) RequestID() string { + return ccr.rawResponse.Header.Get("x-ms-request-id") +} + +// Version returns the value for header x-ms-version. +func (ccr ContainerCreateResponse) Version() string { + return ccr.rawResponse.Header.Get("x-ms-version") +} + +// ContainerDeleteResponse ... +type ContainerDeleteResponse struct { + rawResponse *http.Response +} + +// Response returns the raw HTTP response object. +func (cdr ContainerDeleteResponse) Response() *http.Response { + return cdr.rawResponse +} + +// StatusCode returns the HTTP status code of the response, e.g. 200. +func (cdr ContainerDeleteResponse) StatusCode() int { + return cdr.rawResponse.StatusCode +} + +// Status returns the HTTP status message of the response, e.g. "200 OK". +func (cdr ContainerDeleteResponse) Status() string { + return cdr.rawResponse.Status +} + +// Date returns the value for header Date. +func (cdr ContainerDeleteResponse) Date() time.Time { + s := cdr.rawResponse.Header.Get("Date") + if s == "" { + return time.Time{} + } + t, err := time.Parse(time.RFC1123, s) + if err != nil { + panic(err) + } + return t +} + +// ErrorCode returns the value for header x-ms-error-code. +func (cdr ContainerDeleteResponse) ErrorCode() string { + return cdr.rawResponse.Header.Get("x-ms-error-code") +} + +// RequestID returns the value for header x-ms-request-id. +func (cdr ContainerDeleteResponse) RequestID() string { + return cdr.rawResponse.Header.Get("x-ms-request-id") +} + +// Version returns the value for header x-ms-version. +func (cdr ContainerDeleteResponse) Version() string { + return cdr.rawResponse.Header.Get("x-ms-version") +} + +// ContainerGetPropertiesResponse ... +type ContainerGetPropertiesResponse struct { + rawResponse *http.Response +} + +// NewMetadata returns user-defined key/value pairs. +func (cgpr ContainerGetPropertiesResponse) NewMetadata() Metadata { + md := Metadata{} + for k, v := range cgpr.rawResponse.Header { + if len(k) > mdPrefixLen { + if prefix := k[0:mdPrefixLen]; strings.EqualFold(prefix, mdPrefix) { + md[strings.ToLower(k[mdPrefixLen:])] = v[0] + } + } + } + return md +} + +// Response returns the raw HTTP response object. +func (cgpr ContainerGetPropertiesResponse) Response() *http.Response { + return cgpr.rawResponse +} + +// StatusCode returns the HTTP status code of the response, e.g. 200. +func (cgpr ContainerGetPropertiesResponse) StatusCode() int { + return cgpr.rawResponse.StatusCode +} + +// Status returns the HTTP status message of the response, e.g. "200 OK". +func (cgpr ContainerGetPropertiesResponse) Status() string { + return cgpr.rawResponse.Status +} + +// BlobPublicAccess returns the value for header x-ms-blob-public-access. +func (cgpr ContainerGetPropertiesResponse) BlobPublicAccess() PublicAccessType { + return PublicAccessType(cgpr.rawResponse.Header.Get("x-ms-blob-public-access")) +} + +// Date returns the value for header Date. +func (cgpr ContainerGetPropertiesResponse) Date() time.Time { + s := cgpr.rawResponse.Header.Get("Date") + if s == "" { + return time.Time{} + } + t, err := time.Parse(time.RFC1123, s) + if err != nil { + panic(err) + } + return t +} + +// ErrorCode returns the value for header x-ms-error-code. +func (cgpr ContainerGetPropertiesResponse) ErrorCode() string { + return cgpr.rawResponse.Header.Get("x-ms-error-code") +} + +// ETag returns the value for header ETag. +func (cgpr ContainerGetPropertiesResponse) ETag() ETag { + return ETag(cgpr.rawResponse.Header.Get("ETag")) +} + +// LastModified returns the value for header Last-Modified. +func (cgpr ContainerGetPropertiesResponse) LastModified() time.Time { + s := cgpr.rawResponse.Header.Get("Last-Modified") + if s == "" { + return time.Time{} + } + t, err := time.Parse(time.RFC1123, s) + if err != nil { + panic(err) + } + return t +} + +// LeaseDuration returns the value for header x-ms-lease-duration. +func (cgpr ContainerGetPropertiesResponse) LeaseDuration() LeaseDurationType { + return LeaseDurationType(cgpr.rawResponse.Header.Get("x-ms-lease-duration")) +} + +// LeaseState returns the value for header x-ms-lease-state. +func (cgpr ContainerGetPropertiesResponse) LeaseState() LeaseStateType { + return LeaseStateType(cgpr.rawResponse.Header.Get("x-ms-lease-state")) +} + +// LeaseStatus returns the value for header x-ms-lease-status. +func (cgpr ContainerGetPropertiesResponse) LeaseStatus() LeaseStatusType { + return LeaseStatusType(cgpr.rawResponse.Header.Get("x-ms-lease-status")) +} + +// RequestID returns the value for header x-ms-request-id. +func (cgpr ContainerGetPropertiesResponse) RequestID() string { + return cgpr.rawResponse.Header.Get("x-ms-request-id") +} + +// Version returns the value for header x-ms-version. +func (cgpr ContainerGetPropertiesResponse) Version() string { + return cgpr.rawResponse.Header.Get("x-ms-version") +} + +// ContainerItem - An Azure Storage container +type ContainerItem struct { + Name string `xml:"Name"` + Properties ContainerProperties `xml:"Properties"` + Metadata Metadata `xml:"Metadata"` +} + +// ContainerProperties - Properties of a container +type ContainerProperties struct { + LastModified time.Time `xml:"Last-Modified"` + Etag ETag `xml:"Etag"` + // LeaseStatus - Possible values include: 'LeaseStatusLocked', 'LeaseStatusUnlocked', 'LeaseStatusNone' + LeaseStatus LeaseStatusType `xml:"LeaseStatus"` + // LeaseState - Possible values include: 'LeaseStateAvailable', 'LeaseStateLeased', 'LeaseStateExpired', 'LeaseStateBreaking', 'LeaseStateBroken', 'LeaseStateNone' + LeaseState LeaseStateType `xml:"LeaseState"` + // LeaseDuration - Possible values include: 'LeaseDurationInfinite', 'LeaseDurationFixed', 'LeaseDurationNone' + LeaseDuration LeaseDurationType `xml:"LeaseDuration"` + // PublicAccess - Possible values include: 'PublicAccessContainer', 'PublicAccessBlob', 'PublicAccessNone' + PublicAccess PublicAccessType `xml:"PublicAccess"` +} + +// MarshalXML implements the xml.Marshaler interface for ContainerProperties. +func (cp ContainerProperties) MarshalXML(e *xml.Encoder, start xml.StartElement) error { + if reflect.TypeOf((*ContainerProperties)(nil)).Elem().Size() != reflect.TypeOf((*containerProperties)(nil)).Elem().Size() { + panic("size mismatch between ContainerProperties and containerProperties") + } + cp2 := (*containerProperties)(unsafe.Pointer(&cp)) + return e.EncodeElement(*cp2, start) +} + +// UnmarshalXML implements the xml.Unmarshaler interface for ContainerProperties. +func (cp *ContainerProperties) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { + if reflect.TypeOf((*ContainerProperties)(nil)).Elem().Size() != reflect.TypeOf((*containerProperties)(nil)).Elem().Size() { + panic("size mismatch between ContainerProperties and containerProperties") + } + cp2 := (*containerProperties)(unsafe.Pointer(cp)) + return d.DecodeElement(cp2, &start) +} + +// ContainerReleaseLeaseResponse ... +type ContainerReleaseLeaseResponse struct { + rawResponse *http.Response +} + +// Response returns the raw HTTP response object. +func (crlr ContainerReleaseLeaseResponse) Response() *http.Response { + return crlr.rawResponse +} + +// StatusCode returns the HTTP status code of the response, e.g. 200. +func (crlr ContainerReleaseLeaseResponse) StatusCode() int { + return crlr.rawResponse.StatusCode +} + +// Status returns the HTTP status message of the response, e.g. "200 OK". +func (crlr ContainerReleaseLeaseResponse) Status() string { + return crlr.rawResponse.Status +} + +// Date returns the value for header Date. +func (crlr ContainerReleaseLeaseResponse) Date() time.Time { + s := crlr.rawResponse.Header.Get("Date") + if s == "" { + return time.Time{} + } + t, err := time.Parse(time.RFC1123, s) + if err != nil { + panic(err) + } + return t +} + +// ErrorCode returns the value for header x-ms-error-code. +func (crlr ContainerReleaseLeaseResponse) ErrorCode() string { + return crlr.rawResponse.Header.Get("x-ms-error-code") +} + +// ETag returns the value for header ETag. +func (crlr ContainerReleaseLeaseResponse) ETag() ETag { + return ETag(crlr.rawResponse.Header.Get("ETag")) +} + +// LastModified returns the value for header Last-Modified. +func (crlr ContainerReleaseLeaseResponse) LastModified() time.Time { + s := crlr.rawResponse.Header.Get("Last-Modified") + if s == "" { + return time.Time{} + } + t, err := time.Parse(time.RFC1123, s) + if err != nil { + panic(err) + } + return t +} + +// RequestID returns the value for header x-ms-request-id. +func (crlr ContainerReleaseLeaseResponse) RequestID() string { + return crlr.rawResponse.Header.Get("x-ms-request-id") +} + +// Version returns the value for header x-ms-version. +func (crlr ContainerReleaseLeaseResponse) Version() string { + return crlr.rawResponse.Header.Get("x-ms-version") +} + +// ContainerRenewLeaseResponse ... +type ContainerRenewLeaseResponse struct { + rawResponse *http.Response +} + +// Response returns the raw HTTP response object. +func (crlr ContainerRenewLeaseResponse) Response() *http.Response { + return crlr.rawResponse +} + +// StatusCode returns the HTTP status code of the response, e.g. 200. +func (crlr ContainerRenewLeaseResponse) StatusCode() int { + return crlr.rawResponse.StatusCode +} + +// Status returns the HTTP status message of the response, e.g. "200 OK". +func (crlr ContainerRenewLeaseResponse) Status() string { + return crlr.rawResponse.Status +} + +// Date returns the value for header Date. +func (crlr ContainerRenewLeaseResponse) Date() time.Time { + s := crlr.rawResponse.Header.Get("Date") + if s == "" { + return time.Time{} + } + t, err := time.Parse(time.RFC1123, s) + if err != nil { + panic(err) + } + return t +} + +// ErrorCode returns the value for header x-ms-error-code. +func (crlr ContainerRenewLeaseResponse) ErrorCode() string { + return crlr.rawResponse.Header.Get("x-ms-error-code") +} + +// ETag returns the value for header ETag. +func (crlr ContainerRenewLeaseResponse) ETag() ETag { + return ETag(crlr.rawResponse.Header.Get("ETag")) +} + +// LastModified returns the value for header Last-Modified. +func (crlr ContainerRenewLeaseResponse) LastModified() time.Time { + s := crlr.rawResponse.Header.Get("Last-Modified") + if s == "" { + return time.Time{} + } + t, err := time.Parse(time.RFC1123, s) + if err != nil { + panic(err) + } + return t +} + +// LeaseID returns the value for header x-ms-lease-id. +func (crlr ContainerRenewLeaseResponse) LeaseID() string { + return crlr.rawResponse.Header.Get("x-ms-lease-id") +} + +// RequestID returns the value for header x-ms-request-id. +func (crlr ContainerRenewLeaseResponse) RequestID() string { + return crlr.rawResponse.Header.Get("x-ms-request-id") +} + +// Version returns the value for header x-ms-version. +func (crlr ContainerRenewLeaseResponse) Version() string { + return crlr.rawResponse.Header.Get("x-ms-version") +} + +// ContainerSetAccessPolicyResponse ... +type ContainerSetAccessPolicyResponse struct { + rawResponse *http.Response +} + +// Response returns the raw HTTP response object. +func (csapr ContainerSetAccessPolicyResponse) Response() *http.Response { + return csapr.rawResponse +} + +// StatusCode returns the HTTP status code of the response, e.g. 200. +func (csapr ContainerSetAccessPolicyResponse) StatusCode() int { + return csapr.rawResponse.StatusCode +} + +// Status returns the HTTP status message of the response, e.g. "200 OK". +func (csapr ContainerSetAccessPolicyResponse) Status() string { + return csapr.rawResponse.Status +} + +// Date returns the value for header Date. +func (csapr ContainerSetAccessPolicyResponse) Date() time.Time { + s := csapr.rawResponse.Header.Get("Date") + if s == "" { + return time.Time{} + } + t, err := time.Parse(time.RFC1123, s) + if err != nil { + panic(err) + } + return t +} + +// ErrorCode returns the value for header x-ms-error-code. +func (csapr ContainerSetAccessPolicyResponse) ErrorCode() string { + return csapr.rawResponse.Header.Get("x-ms-error-code") +} + +// ETag returns the value for header ETag. +func (csapr ContainerSetAccessPolicyResponse) ETag() ETag { + return ETag(csapr.rawResponse.Header.Get("ETag")) +} + +// LastModified returns the value for header Last-Modified. +func (csapr ContainerSetAccessPolicyResponse) LastModified() time.Time { + s := csapr.rawResponse.Header.Get("Last-Modified") + if s == "" { + return time.Time{} + } + t, err := time.Parse(time.RFC1123, s) + if err != nil { + panic(err) + } + return t +} + +// RequestID returns the value for header x-ms-request-id. +func (csapr ContainerSetAccessPolicyResponse) RequestID() string { + return csapr.rawResponse.Header.Get("x-ms-request-id") +} + +// Version returns the value for header x-ms-version. +func (csapr ContainerSetAccessPolicyResponse) Version() string { + return csapr.rawResponse.Header.Get("x-ms-version") +} + +// ContainerSetMetadataResponse ... +type ContainerSetMetadataResponse struct { + rawResponse *http.Response +} + +// Response returns the raw HTTP response object. +func (csmr ContainerSetMetadataResponse) Response() *http.Response { + return csmr.rawResponse +} + +// StatusCode returns the HTTP status code of the response, e.g. 200. +func (csmr ContainerSetMetadataResponse) StatusCode() int { + return csmr.rawResponse.StatusCode +} + +// Status returns the HTTP status message of the response, e.g. "200 OK". +func (csmr ContainerSetMetadataResponse) Status() string { + return csmr.rawResponse.Status +} + +// Date returns the value for header Date. +func (csmr ContainerSetMetadataResponse) Date() time.Time { + s := csmr.rawResponse.Header.Get("Date") + if s == "" { + return time.Time{} + } + t, err := time.Parse(time.RFC1123, s) + if err != nil { + panic(err) + } + return t +} + +// ErrorCode returns the value for header x-ms-error-code. +func (csmr ContainerSetMetadataResponse) ErrorCode() string { + return csmr.rawResponse.Header.Get("x-ms-error-code") +} + +// ETag returns the value for header ETag. +func (csmr ContainerSetMetadataResponse) ETag() ETag { + return ETag(csmr.rawResponse.Header.Get("ETag")) +} + +// LastModified returns the value for header Last-Modified. +func (csmr ContainerSetMetadataResponse) LastModified() time.Time { + s := csmr.rawResponse.Header.Get("Last-Modified") + if s == "" { + return time.Time{} + } + t, err := time.Parse(time.RFC1123, s) + if err != nil { + panic(err) + } + return t +} + +// RequestID returns the value for header x-ms-request-id. +func (csmr ContainerSetMetadataResponse) RequestID() string { + return csmr.rawResponse.Header.Get("x-ms-request-id") +} + +// Version returns the value for header x-ms-version. +func (csmr ContainerSetMetadataResponse) Version() string { + return csmr.rawResponse.Header.Get("x-ms-version") +} + +// CorsRule - CORS is an HTTP feature that enables a web application running under one domain to access +// resources in another domain. Web browsers implement a security restriction known as same-origin policy that +// prevents a web page from calling APIs in a different domain; CORS provides a secure way to allow one domain +// (the origin domain) to call APIs in another domain +type CorsRule struct { + // AllowedOrigins - The origin domains that are permitted to make a request against the storage service via CORS. The origin domain is the domain from which the request originates. Note that the origin must be an exact case-sensitive match with the origin that the user age sends to the service. You can also use the wildcard character '*' to allow all origin domains to make requests via CORS. + AllowedOrigins string `xml:"AllowedOrigins"` + // AllowedMethods - The methods (HTTP request verbs) that the origin domain may use for a CORS request. (comma separated) + AllowedMethods string `xml:"AllowedMethods"` + // AllowedHeaders - the request headers that the origin domain may specify on the CORS request. + AllowedHeaders string `xml:"AllowedHeaders"` + // ExposedHeaders - The response headers that may be sent in the response to the CORS request and exposed by the browser to the request issuer + ExposedHeaders string `xml:"ExposedHeaders"` + // MaxAgeInSeconds - The maximum amount time that a browser should cache the preflight OPTIONS request. + MaxAgeInSeconds int32 `xml:"MaxAgeInSeconds"` +} + +// downloadResponse ... +type downloadResponse struct { + rawResponse *http.Response +} + +// NewMetadata returns user-defined key/value pairs. +func (dr downloadResponse) NewMetadata() Metadata { + md := Metadata{} + for k, v := range dr.rawResponse.Header { + if len(k) > mdPrefixLen { + if prefix := k[0:mdPrefixLen]; strings.EqualFold(prefix, mdPrefix) { + md[strings.ToLower(k[mdPrefixLen:])] = v[0] + } + } + } + return md +} + +// Response returns the raw HTTP response object. +func (dr downloadResponse) Response() *http.Response { + return dr.rawResponse +} + +// StatusCode returns the HTTP status code of the response, e.g. 200. +func (dr downloadResponse) StatusCode() int { + return dr.rawResponse.StatusCode +} + +// Status returns the HTTP status message of the response, e.g. "200 OK". +func (dr downloadResponse) Status() string { + return dr.rawResponse.Status +} + +// Body returns the raw HTTP response object's Body. +func (dr downloadResponse) Body() io.ReadCloser { + return dr.rawResponse.Body +} + +// AcceptRanges returns the value for header Accept-Ranges. +func (dr downloadResponse) AcceptRanges() string { + return dr.rawResponse.Header.Get("Accept-Ranges") +} + +// BlobCommittedBlockCount returns the value for header x-ms-blob-committed-block-count. +func (dr downloadResponse) BlobCommittedBlockCount() int32 { + s := dr.rawResponse.Header.Get("x-ms-blob-committed-block-count") + if s == "" { + return -1 + } + i, err := strconv.ParseInt(s, 10, 32) + if err != nil { + panic(err) + } + return int32(i) +} + +// BlobContentMD5 returns the value for header x-ms-blob-content-md5. +func (dr downloadResponse) BlobContentMD5() []byte { + s := dr.rawResponse.Header.Get("x-ms-blob-content-md5") + if s == "" { + return nil + } + b, err := base64.StdEncoding.DecodeString(s) + if err != nil { + panic(err) + } + return b +} + +// BlobSequenceNumber returns the value for header x-ms-blob-sequence-number. +func (dr downloadResponse) BlobSequenceNumber() int64 { + s := dr.rawResponse.Header.Get("x-ms-blob-sequence-number") + if s == "" { + return -1 + } + i, err := strconv.ParseInt(s, 10, 64) + if err != nil { + panic(err) + } + return i +} + +// BlobType returns the value for header x-ms-blob-type. +func (dr downloadResponse) BlobType() BlobType { + return BlobType(dr.rawResponse.Header.Get("x-ms-blob-type")) +} + +// CacheControl returns the value for header Cache-Control. +func (dr downloadResponse) CacheControl() string { + return dr.rawResponse.Header.Get("Cache-Control") +} + +// ContentDisposition returns the value for header Content-Disposition. +func (dr downloadResponse) ContentDisposition() string { + return dr.rawResponse.Header.Get("Content-Disposition") +} + +// ContentEncoding returns the value for header Content-Encoding. +func (dr downloadResponse) ContentEncoding() string { + return dr.rawResponse.Header.Get("Content-Encoding") +} + +// ContentLanguage returns the value for header Content-Language. +func (dr downloadResponse) ContentLanguage() string { + return dr.rawResponse.Header.Get("Content-Language") +} + +// ContentLength returns the value for header Content-Length. +func (dr downloadResponse) ContentLength() int64 { + s := dr.rawResponse.Header.Get("Content-Length") + if s == "" { + return -1 + } + i, err := strconv.ParseInt(s, 10, 64) + if err != nil { + panic(err) + } + return i +} + +// ContentMD5 returns the value for header Content-MD5. +func (dr downloadResponse) ContentMD5() []byte { + s := dr.rawResponse.Header.Get("Content-MD5") + if s == "" { + return nil + } + b, err := base64.StdEncoding.DecodeString(s) + if err != nil { + panic(err) + } + return b +} + +// ContentRange returns the value for header Content-Range. +func (dr downloadResponse) ContentRange() string { + return dr.rawResponse.Header.Get("Content-Range") +} + +// ContentType returns the value for header Content-Type. +func (dr downloadResponse) ContentType() string { + return dr.rawResponse.Header.Get("Content-Type") +} + +// CopyCompletionTime returns the value for header x-ms-copy-completion-time. +func (dr downloadResponse) CopyCompletionTime() time.Time { + s := dr.rawResponse.Header.Get("x-ms-copy-completion-time") + if s == "" { + return time.Time{} + } + t, err := time.Parse(time.RFC1123, s) + if err != nil { + panic(err) + } + return t +} + +// CopyID returns the value for header x-ms-copy-id. +func (dr downloadResponse) CopyID() string { + return dr.rawResponse.Header.Get("x-ms-copy-id") +} + +// CopyProgress returns the value for header x-ms-copy-progress. +func (dr downloadResponse) CopyProgress() string { + return dr.rawResponse.Header.Get("x-ms-copy-progress") +} + +// CopySource returns the value for header x-ms-copy-source. +func (dr downloadResponse) CopySource() string { + return dr.rawResponse.Header.Get("x-ms-copy-source") +} + +// CopyStatus returns the value for header x-ms-copy-status. +func (dr downloadResponse) CopyStatus() CopyStatusType { + return CopyStatusType(dr.rawResponse.Header.Get("x-ms-copy-status")) +} + +// CopyStatusDescription returns the value for header x-ms-copy-status-description. +func (dr downloadResponse) CopyStatusDescription() string { + return dr.rawResponse.Header.Get("x-ms-copy-status-description") +} + +// Date returns the value for header Date. +func (dr downloadResponse) Date() time.Time { + s := dr.rawResponse.Header.Get("Date") + if s == "" { + return time.Time{} + } + t, err := time.Parse(time.RFC1123, s) + if err != nil { + panic(err) + } + return t +} + +// ErrorCode returns the value for header x-ms-error-code. +func (dr downloadResponse) ErrorCode() string { + return dr.rawResponse.Header.Get("x-ms-error-code") +} + +// ETag returns the value for header ETag. +func (dr downloadResponse) ETag() ETag { + return ETag(dr.rawResponse.Header.Get("ETag")) +} + +// IsServerEncrypted returns the value for header x-ms-server-encrypted. +func (dr downloadResponse) IsServerEncrypted() string { + return dr.rawResponse.Header.Get("x-ms-server-encrypted") +} + +// LastModified returns the value for header Last-Modified. +func (dr downloadResponse) LastModified() time.Time { + s := dr.rawResponse.Header.Get("Last-Modified") + if s == "" { + return time.Time{} + } + t, err := time.Parse(time.RFC1123, s) + if err != nil { + panic(err) + } + return t +} + +// LeaseDuration returns the value for header x-ms-lease-duration. +func (dr downloadResponse) LeaseDuration() LeaseDurationType { + return LeaseDurationType(dr.rawResponse.Header.Get("x-ms-lease-duration")) +} + +// LeaseState returns the value for header x-ms-lease-state. +func (dr downloadResponse) LeaseState() LeaseStateType { + return LeaseStateType(dr.rawResponse.Header.Get("x-ms-lease-state")) +} + +// LeaseStatus returns the value for header x-ms-lease-status. +func (dr downloadResponse) LeaseStatus() LeaseStatusType { + return LeaseStatusType(dr.rawResponse.Header.Get("x-ms-lease-status")) +} + +// RequestID returns the value for header x-ms-request-id. +func (dr downloadResponse) RequestID() string { + return dr.rawResponse.Header.Get("x-ms-request-id") +} + +// Version returns the value for header x-ms-version. +func (dr downloadResponse) Version() string { + return dr.rawResponse.Header.Get("x-ms-version") +} + +// GeoReplication ... +type GeoReplication struct { + // Status - The status of the secondary location. Possible values include: 'GeoReplicationStatusLive', 'GeoReplicationStatusBootstrap', 'GeoReplicationStatusUnavailable', 'GeoReplicationStatusNone' + Status GeoReplicationStatusType `xml:"Status"` + // LastSyncTime - A GMT date/time value, to the second. All primary writes preceding this value are guaranteed to be available for read operations at the secondary. Primary writes after this point in time may or may not be available for reads. + LastSyncTime time.Time `xml:"LastSyncTime"` +} + +// MarshalXML implements the xml.Marshaler interface for GeoReplication. +func (gr GeoReplication) MarshalXML(e *xml.Encoder, start xml.StartElement) error { + if reflect.TypeOf((*GeoReplication)(nil)).Elem().Size() != reflect.TypeOf((*geoReplication)(nil)).Elem().Size() { + panic("size mismatch between GeoReplication and geoReplication") + } + gr2 := (*geoReplication)(unsafe.Pointer(&gr)) + return e.EncodeElement(*gr2, start) +} + +// UnmarshalXML implements the xml.Unmarshaler interface for GeoReplication. +func (gr *GeoReplication) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { + if reflect.TypeOf((*GeoReplication)(nil)).Elem().Size() != reflect.TypeOf((*geoReplication)(nil)).Elem().Size() { + panic("size mismatch between GeoReplication and geoReplication") + } + gr2 := (*geoReplication)(unsafe.Pointer(gr)) + return d.DecodeElement(gr2, &start) +} + +// ListBlobsFlatSegmentResponse - An enumeration of blobs +type ListBlobsFlatSegmentResponse struct { + rawResponse *http.Response + // XMLName is used for marshalling and is subject to removal in a future release. + XMLName xml.Name `xml:"EnumerationResults"` + ServiceEndpoint string `xml:"ServiceEndpoint,attr"` + ContainerName string `xml:"ContainerName,attr"` + Prefix string `xml:"Prefix"` + Marker string `xml:"Marker"` + MaxResults int32 `xml:"MaxResults"` + Delimiter string `xml:"Delimiter"` + Segment BlobFlatList `xml:"Blobs"` + NextMarker Marker `xml:"NextMarker"` +} + +// Response returns the raw HTTP response object. +func (lbfsr ListBlobsFlatSegmentResponse) Response() *http.Response { + return lbfsr.rawResponse +} + +// StatusCode returns the HTTP status code of the response, e.g. 200. +func (lbfsr ListBlobsFlatSegmentResponse) StatusCode() int { + return lbfsr.rawResponse.StatusCode +} + +// Status returns the HTTP status message of the response, e.g. "200 OK". +func (lbfsr ListBlobsFlatSegmentResponse) Status() string { + return lbfsr.rawResponse.Status +} + +// ContentType returns the value for header Content-Type. +func (lbfsr ListBlobsFlatSegmentResponse) ContentType() string { + return lbfsr.rawResponse.Header.Get("Content-Type") +} + +// Date returns the value for header Date. +func (lbfsr ListBlobsFlatSegmentResponse) Date() time.Time { + s := lbfsr.rawResponse.Header.Get("Date") + if s == "" { + return time.Time{} + } + t, err := time.Parse(time.RFC1123, s) + if err != nil { + panic(err) + } + return t +} + +// ErrorCode returns the value for header x-ms-error-code. +func (lbfsr ListBlobsFlatSegmentResponse) ErrorCode() string { + return lbfsr.rawResponse.Header.Get("x-ms-error-code") +} + +// RequestID returns the value for header x-ms-request-id. +func (lbfsr ListBlobsFlatSegmentResponse) RequestID() string { + return lbfsr.rawResponse.Header.Get("x-ms-request-id") +} + +// Version returns the value for header x-ms-version. +func (lbfsr ListBlobsFlatSegmentResponse) Version() string { + return lbfsr.rawResponse.Header.Get("x-ms-version") +} + +// ListBlobsHierarchySegmentResponse - An enumeration of blobs +type ListBlobsHierarchySegmentResponse struct { + rawResponse *http.Response + // XMLName is used for marshalling and is subject to removal in a future release. + XMLName xml.Name `xml:"EnumerationResults"` + ServiceEndpoint string `xml:"ServiceEndpoint,attr"` + ContainerName string `xml:"ContainerName,attr"` + Prefix string `xml:"Prefix"` + Marker string `xml:"Marker"` + MaxResults int32 `xml:"MaxResults"` + Delimiter string `xml:"Delimiter"` + Segment BlobHierarchyList `xml:"Blobs"` + NextMarker Marker `xml:"NextMarker"` +} + +// Response returns the raw HTTP response object. +func (lbhsr ListBlobsHierarchySegmentResponse) Response() *http.Response { + return lbhsr.rawResponse +} + +// StatusCode returns the HTTP status code of the response, e.g. 200. +func (lbhsr ListBlobsHierarchySegmentResponse) StatusCode() int { + return lbhsr.rawResponse.StatusCode +} + +// Status returns the HTTP status message of the response, e.g. "200 OK". +func (lbhsr ListBlobsHierarchySegmentResponse) Status() string { + return lbhsr.rawResponse.Status +} + +// ContentType returns the value for header Content-Type. +func (lbhsr ListBlobsHierarchySegmentResponse) ContentType() string { + return lbhsr.rawResponse.Header.Get("Content-Type") +} + +// Date returns the value for header Date. +func (lbhsr ListBlobsHierarchySegmentResponse) Date() time.Time { + s := lbhsr.rawResponse.Header.Get("Date") + if s == "" { + return time.Time{} + } + t, err := time.Parse(time.RFC1123, s) + if err != nil { + panic(err) + } + return t +} + +// ErrorCode returns the value for header x-ms-error-code. +func (lbhsr ListBlobsHierarchySegmentResponse) ErrorCode() string { + return lbhsr.rawResponse.Header.Get("x-ms-error-code") +} + +// RequestID returns the value for header x-ms-request-id. +func (lbhsr ListBlobsHierarchySegmentResponse) RequestID() string { + return lbhsr.rawResponse.Header.Get("x-ms-request-id") +} + +// Version returns the value for header x-ms-version. +func (lbhsr ListBlobsHierarchySegmentResponse) Version() string { + return lbhsr.rawResponse.Header.Get("x-ms-version") +} + +// ListContainersResponse - An enumeration of containers +type ListContainersResponse struct { + rawResponse *http.Response + // XMLName is used for marshalling and is subject to removal in a future release. + XMLName xml.Name `xml:"EnumerationResults"` + ServiceEndpoint string `xml:"ServiceEndpoint,attr"` + Prefix string `xml:"Prefix"` + Marker *string `xml:"Marker"` + MaxResults int32 `xml:"MaxResults"` + ContainerItems []ContainerItem `xml:"Containers>Container"` + NextMarker Marker `xml:"NextMarker"` +} + +// Response returns the raw HTTP response object. +func (lcr ListContainersResponse) Response() *http.Response { + return lcr.rawResponse +} + +// StatusCode returns the HTTP status code of the response, e.g. 200. +func (lcr ListContainersResponse) StatusCode() int { + return lcr.rawResponse.StatusCode +} + +// Status returns the HTTP status message of the response, e.g. "200 OK". +func (lcr ListContainersResponse) Status() string { + return lcr.rawResponse.Status +} + +// ErrorCode returns the value for header x-ms-error-code. +func (lcr ListContainersResponse) ErrorCode() string { + return lcr.rawResponse.Header.Get("x-ms-error-code") +} + +// RequestID returns the value for header x-ms-request-id. +func (lcr ListContainersResponse) RequestID() string { + return lcr.rawResponse.Header.Get("x-ms-request-id") +} + +// Version returns the value for header x-ms-version. +func (lcr ListContainersResponse) Version() string { + return lcr.rawResponse.Header.Get("x-ms-version") +} + +// Logging - Azure Analytics Logging settings. +type Logging struct { + // Version - The version of Storage Analytics to configure. + Version string `xml:"Version"` + // Delete - Indicates whether all delete requests should be logged. + Delete bool `xml:"Delete"` + // Read - Indicates whether all read requests should be logged. + Read bool `xml:"Read"` + // Write - Indicates whether all write requests should be logged. + Write bool `xml:"Write"` + RetentionPolicy RetentionPolicy `xml:"RetentionPolicy"` +} + +// Metrics ... +type Metrics struct { + // Version - The version of Storage Analytics to configure. + Version *string `xml:"Version"` + // Enabled - Indicates whether metrics are enabled for the Blob service. + Enabled bool `xml:"Enabled"` + // IncludeAPIs - Indicates whether metrics should generate summary statistics for called API operations. + IncludeAPIs *bool `xml:"IncludeAPIs"` + RetentionPolicy *RetentionPolicy `xml:"RetentionPolicy"` +} + +// PageBlobClearPagesResponse ... +type PageBlobClearPagesResponse struct { + rawResponse *http.Response +} + +// Response returns the raw HTTP response object. +func (pbcpr PageBlobClearPagesResponse) Response() *http.Response { + return pbcpr.rawResponse +} + +// StatusCode returns the HTTP status code of the response, e.g. 200. +func (pbcpr PageBlobClearPagesResponse) StatusCode() int { + return pbcpr.rawResponse.StatusCode +} + +// Status returns the HTTP status message of the response, e.g. "200 OK". +func (pbcpr PageBlobClearPagesResponse) Status() string { + return pbcpr.rawResponse.Status +} + +// BlobSequenceNumber returns the value for header x-ms-blob-sequence-number. +func (pbcpr PageBlobClearPagesResponse) BlobSequenceNumber() int64 { + s := pbcpr.rawResponse.Header.Get("x-ms-blob-sequence-number") + if s == "" { + return -1 + } + i, err := strconv.ParseInt(s, 10, 64) + if err != nil { + panic(err) + } + return i +} + +// ContentMD5 returns the value for header Content-MD5. +func (pbcpr PageBlobClearPagesResponse) ContentMD5() []byte { + s := pbcpr.rawResponse.Header.Get("Content-MD5") + if s == "" { + return nil + } + b, err := base64.StdEncoding.DecodeString(s) + if err != nil { + panic(err) + } + return b +} + +// Date returns the value for header Date. +func (pbcpr PageBlobClearPagesResponse) Date() time.Time { + s := pbcpr.rawResponse.Header.Get("Date") + if s == "" { + return time.Time{} + } + t, err := time.Parse(time.RFC1123, s) + if err != nil { + panic(err) + } + return t +} + +// ErrorCode returns the value for header x-ms-error-code. +func (pbcpr PageBlobClearPagesResponse) ErrorCode() string { + return pbcpr.rawResponse.Header.Get("x-ms-error-code") +} + +// ETag returns the value for header ETag. +func (pbcpr PageBlobClearPagesResponse) ETag() ETag { + return ETag(pbcpr.rawResponse.Header.Get("ETag")) +} + +// LastModified returns the value for header Last-Modified. +func (pbcpr PageBlobClearPagesResponse) LastModified() time.Time { + s := pbcpr.rawResponse.Header.Get("Last-Modified") + if s == "" { + return time.Time{} + } + t, err := time.Parse(time.RFC1123, s) + if err != nil { + panic(err) + } + return t +} + +// RequestID returns the value for header x-ms-request-id. +func (pbcpr PageBlobClearPagesResponse) RequestID() string { + return pbcpr.rawResponse.Header.Get("x-ms-request-id") +} + +// Version returns the value for header x-ms-version. +func (pbcpr PageBlobClearPagesResponse) Version() string { + return pbcpr.rawResponse.Header.Get("x-ms-version") +} + +// PageBlobCopyIncrementalResponse ... +type PageBlobCopyIncrementalResponse struct { + rawResponse *http.Response +} + +// Response returns the raw HTTP response object. +func (pbcir PageBlobCopyIncrementalResponse) Response() *http.Response { + return pbcir.rawResponse +} + +// StatusCode returns the HTTP status code of the response, e.g. 200. +func (pbcir PageBlobCopyIncrementalResponse) StatusCode() int { + return pbcir.rawResponse.StatusCode +} + +// Status returns the HTTP status message of the response, e.g. "200 OK". +func (pbcir PageBlobCopyIncrementalResponse) Status() string { + return pbcir.rawResponse.Status +} + +// CopyID returns the value for header x-ms-copy-id. +func (pbcir PageBlobCopyIncrementalResponse) CopyID() string { + return pbcir.rawResponse.Header.Get("x-ms-copy-id") +} + +// CopyStatus returns the value for header x-ms-copy-status. +func (pbcir PageBlobCopyIncrementalResponse) CopyStatus() CopyStatusType { + return CopyStatusType(pbcir.rawResponse.Header.Get("x-ms-copy-status")) +} + +// Date returns the value for header Date. +func (pbcir PageBlobCopyIncrementalResponse) Date() time.Time { + s := pbcir.rawResponse.Header.Get("Date") + if s == "" { + return time.Time{} + } + t, err := time.Parse(time.RFC1123, s) + if err != nil { + panic(err) + } + return t +} + +// ErrorCode returns the value for header x-ms-error-code. +func (pbcir PageBlobCopyIncrementalResponse) ErrorCode() string { + return pbcir.rawResponse.Header.Get("x-ms-error-code") +} + +// ETag returns the value for header ETag. +func (pbcir PageBlobCopyIncrementalResponse) ETag() ETag { + return ETag(pbcir.rawResponse.Header.Get("ETag")) +} + +// LastModified returns the value for header Last-Modified. +func (pbcir PageBlobCopyIncrementalResponse) LastModified() time.Time { + s := pbcir.rawResponse.Header.Get("Last-Modified") + if s == "" { + return time.Time{} + } + t, err := time.Parse(time.RFC1123, s) + if err != nil { + panic(err) + } + return t +} + +// RequestID returns the value for header x-ms-request-id. +func (pbcir PageBlobCopyIncrementalResponse) RequestID() string { + return pbcir.rawResponse.Header.Get("x-ms-request-id") +} + +// Version returns the value for header x-ms-version. +func (pbcir PageBlobCopyIncrementalResponse) Version() string { + return pbcir.rawResponse.Header.Get("x-ms-version") +} + +// PageBlobCreateResponse ... +type PageBlobCreateResponse struct { + rawResponse *http.Response +} + +// Response returns the raw HTTP response object. +func (pbcr PageBlobCreateResponse) Response() *http.Response { + return pbcr.rawResponse +} + +// StatusCode returns the HTTP status code of the response, e.g. 200. +func (pbcr PageBlobCreateResponse) StatusCode() int { + return pbcr.rawResponse.StatusCode +} + +// Status returns the HTTP status message of the response, e.g. "200 OK". +func (pbcr PageBlobCreateResponse) Status() string { + return pbcr.rawResponse.Status +} + +// ContentMD5 returns the value for header Content-MD5. +func (pbcr PageBlobCreateResponse) ContentMD5() []byte { + s := pbcr.rawResponse.Header.Get("Content-MD5") + if s == "" { + return nil + } + b, err := base64.StdEncoding.DecodeString(s) + if err != nil { + panic(err) + } + return b +} + +// Date returns the value for header Date. +func (pbcr PageBlobCreateResponse) Date() time.Time { + s := pbcr.rawResponse.Header.Get("Date") + if s == "" { + return time.Time{} + } + t, err := time.Parse(time.RFC1123, s) + if err != nil { + panic(err) + } + return t +} + +// ErrorCode returns the value for header x-ms-error-code. +func (pbcr PageBlobCreateResponse) ErrorCode() string { + return pbcr.rawResponse.Header.Get("x-ms-error-code") +} + +// ETag returns the value for header ETag. +func (pbcr PageBlobCreateResponse) ETag() ETag { + return ETag(pbcr.rawResponse.Header.Get("ETag")) +} + +// IsServerEncrypted returns the value for header x-ms-request-server-encrypted. +func (pbcr PageBlobCreateResponse) IsServerEncrypted() string { + return pbcr.rawResponse.Header.Get("x-ms-request-server-encrypted") +} + +// LastModified returns the value for header Last-Modified. +func (pbcr PageBlobCreateResponse) LastModified() time.Time { + s := pbcr.rawResponse.Header.Get("Last-Modified") + if s == "" { + return time.Time{} + } + t, err := time.Parse(time.RFC1123, s) + if err != nil { + panic(err) + } + return t +} + +// RequestID returns the value for header x-ms-request-id. +func (pbcr PageBlobCreateResponse) RequestID() string { + return pbcr.rawResponse.Header.Get("x-ms-request-id") +} + +// Version returns the value for header x-ms-version. +func (pbcr PageBlobCreateResponse) Version() string { + return pbcr.rawResponse.Header.Get("x-ms-version") +} + +// PageBlobResizeResponse ... +type PageBlobResizeResponse struct { + rawResponse *http.Response +} + +// Response returns the raw HTTP response object. +func (pbrr PageBlobResizeResponse) Response() *http.Response { + return pbrr.rawResponse +} + +// StatusCode returns the HTTP status code of the response, e.g. 200. +func (pbrr PageBlobResizeResponse) StatusCode() int { + return pbrr.rawResponse.StatusCode +} + +// Status returns the HTTP status message of the response, e.g. "200 OK". +func (pbrr PageBlobResizeResponse) Status() string { + return pbrr.rawResponse.Status +} + +// BlobSequenceNumber returns the value for header x-ms-blob-sequence-number. +func (pbrr PageBlobResizeResponse) BlobSequenceNumber() int64 { + s := pbrr.rawResponse.Header.Get("x-ms-blob-sequence-number") + if s == "" { + return -1 + } + i, err := strconv.ParseInt(s, 10, 64) + if err != nil { + panic(err) + } + return i +} + +// Date returns the value for header Date. +func (pbrr PageBlobResizeResponse) Date() time.Time { + s := pbrr.rawResponse.Header.Get("Date") + if s == "" { + return time.Time{} + } + t, err := time.Parse(time.RFC1123, s) + if err != nil { + panic(err) + } + return t +} + +// ErrorCode returns the value for header x-ms-error-code. +func (pbrr PageBlobResizeResponse) ErrorCode() string { + return pbrr.rawResponse.Header.Get("x-ms-error-code") +} + +// ETag returns the value for header ETag. +func (pbrr PageBlobResizeResponse) ETag() ETag { + return ETag(pbrr.rawResponse.Header.Get("ETag")) +} + +// LastModified returns the value for header Last-Modified. +func (pbrr PageBlobResizeResponse) LastModified() time.Time { + s := pbrr.rawResponse.Header.Get("Last-Modified") + if s == "" { + return time.Time{} + } + t, err := time.Parse(time.RFC1123, s) + if err != nil { + panic(err) + } + return t +} + +// RequestID returns the value for header x-ms-request-id. +func (pbrr PageBlobResizeResponse) RequestID() string { + return pbrr.rawResponse.Header.Get("x-ms-request-id") +} + +// Version returns the value for header x-ms-version. +func (pbrr PageBlobResizeResponse) Version() string { + return pbrr.rawResponse.Header.Get("x-ms-version") +} + +// PageBlobUpdateSequenceNumberResponse ... +type PageBlobUpdateSequenceNumberResponse struct { + rawResponse *http.Response +} + +// Response returns the raw HTTP response object. +func (pbusnr PageBlobUpdateSequenceNumberResponse) Response() *http.Response { + return pbusnr.rawResponse +} + +// StatusCode returns the HTTP status code of the response, e.g. 200. +func (pbusnr PageBlobUpdateSequenceNumberResponse) StatusCode() int { + return pbusnr.rawResponse.StatusCode +} + +// Status returns the HTTP status message of the response, e.g. "200 OK". +func (pbusnr PageBlobUpdateSequenceNumberResponse) Status() string { + return pbusnr.rawResponse.Status +} + +// BlobSequenceNumber returns the value for header x-ms-blob-sequence-number. +func (pbusnr PageBlobUpdateSequenceNumberResponse) BlobSequenceNumber() int64 { + s := pbusnr.rawResponse.Header.Get("x-ms-blob-sequence-number") + if s == "" { + return -1 + } + i, err := strconv.ParseInt(s, 10, 64) + if err != nil { + panic(err) + } + return i +} + +// Date returns the value for header Date. +func (pbusnr PageBlobUpdateSequenceNumberResponse) Date() time.Time { + s := pbusnr.rawResponse.Header.Get("Date") + if s == "" { + return time.Time{} + } + t, err := time.Parse(time.RFC1123, s) + if err != nil { + panic(err) + } + return t +} + +// ErrorCode returns the value for header x-ms-error-code. +func (pbusnr PageBlobUpdateSequenceNumberResponse) ErrorCode() string { + return pbusnr.rawResponse.Header.Get("x-ms-error-code") +} + +// ETag returns the value for header ETag. +func (pbusnr PageBlobUpdateSequenceNumberResponse) ETag() ETag { + return ETag(pbusnr.rawResponse.Header.Get("ETag")) +} + +// LastModified returns the value for header Last-Modified. +func (pbusnr PageBlobUpdateSequenceNumberResponse) LastModified() time.Time { + s := pbusnr.rawResponse.Header.Get("Last-Modified") + if s == "" { + return time.Time{} + } + t, err := time.Parse(time.RFC1123, s) + if err != nil { + panic(err) + } + return t +} + +// RequestID returns the value for header x-ms-request-id. +func (pbusnr PageBlobUpdateSequenceNumberResponse) RequestID() string { + return pbusnr.rawResponse.Header.Get("x-ms-request-id") +} + +// Version returns the value for header x-ms-version. +func (pbusnr PageBlobUpdateSequenceNumberResponse) Version() string { + return pbusnr.rawResponse.Header.Get("x-ms-version") +} + +// PageBlobUploadPagesResponse ... +type PageBlobUploadPagesResponse struct { + rawResponse *http.Response +} + +// Response returns the raw HTTP response object. +func (pbupr PageBlobUploadPagesResponse) Response() *http.Response { + return pbupr.rawResponse +} + +// StatusCode returns the HTTP status code of the response, e.g. 200. +func (pbupr PageBlobUploadPagesResponse) StatusCode() int { + return pbupr.rawResponse.StatusCode +} + +// Status returns the HTTP status message of the response, e.g. "200 OK". +func (pbupr PageBlobUploadPagesResponse) Status() string { + return pbupr.rawResponse.Status +} + +// BlobSequenceNumber returns the value for header x-ms-blob-sequence-number. +func (pbupr PageBlobUploadPagesResponse) BlobSequenceNumber() int64 { + s := pbupr.rawResponse.Header.Get("x-ms-blob-sequence-number") + if s == "" { + return -1 + } + i, err := strconv.ParseInt(s, 10, 64) + if err != nil { + panic(err) + } + return i +} + +// ContentMD5 returns the value for header Content-MD5. +func (pbupr PageBlobUploadPagesResponse) ContentMD5() []byte { + s := pbupr.rawResponse.Header.Get("Content-MD5") + if s == "" { + return nil + } + b, err := base64.StdEncoding.DecodeString(s) + if err != nil { + panic(err) + } + return b +} + +// Date returns the value for header Date. +func (pbupr PageBlobUploadPagesResponse) Date() time.Time { + s := pbupr.rawResponse.Header.Get("Date") + if s == "" { + return time.Time{} + } + t, err := time.Parse(time.RFC1123, s) + if err != nil { + panic(err) + } + return t +} + +// ErrorCode returns the value for header x-ms-error-code. +func (pbupr PageBlobUploadPagesResponse) ErrorCode() string { + return pbupr.rawResponse.Header.Get("x-ms-error-code") +} + +// ETag returns the value for header ETag. +func (pbupr PageBlobUploadPagesResponse) ETag() ETag { + return ETag(pbupr.rawResponse.Header.Get("ETag")) +} + +// IsServerEncrypted returns the value for header x-ms-request-server-encrypted. +func (pbupr PageBlobUploadPagesResponse) IsServerEncrypted() string { + return pbupr.rawResponse.Header.Get("x-ms-request-server-encrypted") +} + +// LastModified returns the value for header Last-Modified. +func (pbupr PageBlobUploadPagesResponse) LastModified() time.Time { + s := pbupr.rawResponse.Header.Get("Last-Modified") + if s == "" { + return time.Time{} + } + t, err := time.Parse(time.RFC1123, s) + if err != nil { + panic(err) + } + return t +} + +// RequestID returns the value for header x-ms-request-id. +func (pbupr PageBlobUploadPagesResponse) RequestID() string { + return pbupr.rawResponse.Header.Get("x-ms-request-id") +} + +// Version returns the value for header x-ms-version. +func (pbupr PageBlobUploadPagesResponse) Version() string { + return pbupr.rawResponse.Header.Get("x-ms-version") +} + +// PageList - the list of pages +type PageList struct { + rawResponse *http.Response + PageRange []PageRange `xml:"PageRange"` + ClearRange []ClearRange `xml:"ClearRange"` +} + +// Response returns the raw HTTP response object. +func (pl PageList) Response() *http.Response { + return pl.rawResponse +} + +// StatusCode returns the HTTP status code of the response, e.g. 200. +func (pl PageList) StatusCode() int { + return pl.rawResponse.StatusCode +} + +// Status returns the HTTP status message of the response, e.g. "200 OK". +func (pl PageList) Status() string { + return pl.rawResponse.Status +} + +// BlobContentLength returns the value for header x-ms-blob-content-length. +func (pl PageList) BlobContentLength() int64 { + s := pl.rawResponse.Header.Get("x-ms-blob-content-length") + if s == "" { + return -1 + } + i, err := strconv.ParseInt(s, 10, 64) + if err != nil { + panic(err) + } + return i +} + +// Date returns the value for header Date. +func (pl PageList) Date() time.Time { + s := pl.rawResponse.Header.Get("Date") + if s == "" { + return time.Time{} + } + t, err := time.Parse(time.RFC1123, s) + if err != nil { + panic(err) + } + return t +} + +// ErrorCode returns the value for header x-ms-error-code. +func (pl PageList) ErrorCode() string { + return pl.rawResponse.Header.Get("x-ms-error-code") +} + +// ETag returns the value for header ETag. +func (pl PageList) ETag() ETag { + return ETag(pl.rawResponse.Header.Get("ETag")) +} + +// LastModified returns the value for header Last-Modified. +func (pl PageList) LastModified() time.Time { + s := pl.rawResponse.Header.Get("Last-Modified") + if s == "" { + return time.Time{} + } + t, err := time.Parse(time.RFC1123, s) + if err != nil { + panic(err) + } + return t +} + +// RequestID returns the value for header x-ms-request-id. +func (pl PageList) RequestID() string { + return pl.rawResponse.Header.Get("x-ms-request-id") +} + +// Version returns the value for header x-ms-version. +func (pl PageList) Version() string { + return pl.rawResponse.Header.Get("x-ms-version") +} + +// PageRange ... +type PageRange struct { + Start int64 `xml:"Start"` + End int64 `xml:"End"` +} + +// RetentionPolicy - the retention policy +type RetentionPolicy struct { + // Enabled - Indicates whether a retention policy is enabled for the storage service + Enabled bool `xml:"Enabled"` + // Days - Indicates the number of days that metrics or logging or soft-deleted data should be retained. All data older than this value will be deleted + Days *int32 `xml:"Days"` +} + +// ServiceSetPropertiesResponse ... +type ServiceSetPropertiesResponse struct { + rawResponse *http.Response +} + +// Response returns the raw HTTP response object. +func (sspr ServiceSetPropertiesResponse) Response() *http.Response { + return sspr.rawResponse +} + +// StatusCode returns the HTTP status code of the response, e.g. 200. +func (sspr ServiceSetPropertiesResponse) StatusCode() int { + return sspr.rawResponse.StatusCode +} + +// Status returns the HTTP status message of the response, e.g. "200 OK". +func (sspr ServiceSetPropertiesResponse) Status() string { + return sspr.rawResponse.Status +} + +// ErrorCode returns the value for header x-ms-error-code. +func (sspr ServiceSetPropertiesResponse) ErrorCode() string { + return sspr.rawResponse.Header.Get("x-ms-error-code") +} + +// RequestID returns the value for header x-ms-request-id. +func (sspr ServiceSetPropertiesResponse) RequestID() string { + return sspr.rawResponse.Header.Get("x-ms-request-id") +} + +// Version returns the value for header x-ms-version. +func (sspr ServiceSetPropertiesResponse) Version() string { + return sspr.rawResponse.Header.Get("x-ms-version") +} + +// SignedIdentifier - signed identifier +type SignedIdentifier struct { + // ID - a unique id + ID string `xml:"Id"` + // AccessPolicy - The access policy + AccessPolicy AccessPolicy `xml:"AccessPolicy"` +} + +// SignedIdentifiers ... +type SignedIdentifiers struct { + rawResponse *http.Response + Items []SignedIdentifier `xml:"SignedIdentifier"` +} + +// Response returns the raw HTTP response object. +func (si SignedIdentifiers) Response() *http.Response { + return si.rawResponse +} + +// StatusCode returns the HTTP status code of the response, e.g. 200. +func (si SignedIdentifiers) StatusCode() int { + return si.rawResponse.StatusCode +} + +// Status returns the HTTP status message of the response, e.g. "200 OK". +func (si SignedIdentifiers) Status() string { + return si.rawResponse.Status +} + +// BlobPublicAccess returns the value for header x-ms-blob-public-access. +func (si SignedIdentifiers) BlobPublicAccess() PublicAccessType { + return PublicAccessType(si.rawResponse.Header.Get("x-ms-blob-public-access")) +} + +// Date returns the value for header Date. +func (si SignedIdentifiers) Date() time.Time { + s := si.rawResponse.Header.Get("Date") + if s == "" { + return time.Time{} + } + t, err := time.Parse(time.RFC1123, s) + if err != nil { + panic(err) + } + return t +} + +// ErrorCode returns the value for header x-ms-error-code. +func (si SignedIdentifiers) ErrorCode() string { + return si.rawResponse.Header.Get("x-ms-error-code") +} + +// ETag returns the value for header ETag. +func (si SignedIdentifiers) ETag() ETag { + return ETag(si.rawResponse.Header.Get("ETag")) +} + +// LastModified returns the value for header Last-Modified. +func (si SignedIdentifiers) LastModified() time.Time { + s := si.rawResponse.Header.Get("Last-Modified") + if s == "" { + return time.Time{} + } + t, err := time.Parse(time.RFC1123, s) + if err != nil { + panic(err) + } + return t +} + +// RequestID returns the value for header x-ms-request-id. +func (si SignedIdentifiers) RequestID() string { + return si.rawResponse.Header.Get("x-ms-request-id") +} + +// Version returns the value for header x-ms-version. +func (si SignedIdentifiers) Version() string { + return si.rawResponse.Header.Get("x-ms-version") +} + +// StorageServiceProperties - Storage Service Properties. +type StorageServiceProperties struct { + rawResponse *http.Response + // Logging - Azure Analytics Logging settings + Logging *Logging `xml:"Logging"` + // HourMetrics - A summary of request statistics grouped by API in hourly aggregates for blobs + HourMetrics *Metrics `xml:"HourMetrics"` + // MinuteMetrics - a summary of request statistics grouped by API in minute aggregates for blobs + MinuteMetrics *Metrics `xml:"MinuteMetrics"` + // Cors - The set of CORS rules. + Cors []CorsRule `xml:"Cors>CorsRule"` + // DefaultServiceVersion - The default version to use for requests to the Blob service if an incoming request's version is not specified. Possible values include version 2008-10-27 and all more recent versions + DefaultServiceVersion *string `xml:"DefaultServiceVersion"` + // DeleteRetentionPolicy - The Delete Retention Policy for the service + DeleteRetentionPolicy *RetentionPolicy `xml:"DeleteRetentionPolicy"` +} + +// Response returns the raw HTTP response object. +func (ssp StorageServiceProperties) Response() *http.Response { + return ssp.rawResponse +} + +// StatusCode returns the HTTP status code of the response, e.g. 200. +func (ssp StorageServiceProperties) StatusCode() int { + return ssp.rawResponse.StatusCode +} + +// Status returns the HTTP status message of the response, e.g. "200 OK". +func (ssp StorageServiceProperties) Status() string { + return ssp.rawResponse.Status +} + +// ErrorCode returns the value for header x-ms-error-code. +func (ssp StorageServiceProperties) ErrorCode() string { + return ssp.rawResponse.Header.Get("x-ms-error-code") +} + +// RequestID returns the value for header x-ms-request-id. +func (ssp StorageServiceProperties) RequestID() string { + return ssp.rawResponse.Header.Get("x-ms-request-id") +} + +// Version returns the value for header x-ms-version. +func (ssp StorageServiceProperties) Version() string { + return ssp.rawResponse.Header.Get("x-ms-version") +} + +// StorageServiceStats - Stats for the storage service. +type StorageServiceStats struct { + rawResponse *http.Response + // GeoReplication - Geo-Replication information for the Secondary Storage Service + GeoReplication *GeoReplication `xml:"GeoReplication"` +} + +// Response returns the raw HTTP response object. +func (sss StorageServiceStats) Response() *http.Response { + return sss.rawResponse +} + +// StatusCode returns the HTTP status code of the response, e.g. 200. +func (sss StorageServiceStats) StatusCode() int { + return sss.rawResponse.StatusCode +} + +// Status returns the HTTP status message of the response, e.g. "200 OK". +func (sss StorageServiceStats) Status() string { + return sss.rawResponse.Status +} + +// Date returns the value for header Date. +func (sss StorageServiceStats) Date() time.Time { + s := sss.rawResponse.Header.Get("Date") + if s == "" { + return time.Time{} + } + t, err := time.Parse(time.RFC1123, s) + if err != nil { + panic(err) + } + return t +} + +// ErrorCode returns the value for header x-ms-error-code. +func (sss StorageServiceStats) ErrorCode() string { + return sss.rawResponse.Header.Get("x-ms-error-code") +} + +// RequestID returns the value for header x-ms-request-id. +func (sss StorageServiceStats) RequestID() string { + return sss.rawResponse.Header.Get("x-ms-request-id") +} + +// Version returns the value for header x-ms-version. +func (sss StorageServiceStats) Version() string { + return sss.rawResponse.Header.Get("x-ms-version") +} + +const ( + rfc3339Format = "2006-01-02T15:04:05.0000000Z07:00" +) + +// used to convert times from UTC to GMT before sending across the wire +var gmt = time.FixedZone("GMT", 0) + +// internal type used for marshalling time in RFC1123 format +type timeRFC1123 struct { + time.Time +} + +// MarshalText implements the encoding.TextMarshaler interface for timeRFC1123. +func (t timeRFC1123) MarshalText() ([]byte, error) { + return []byte(t.Format(time.RFC1123)), nil +} + +// UnmarshalText implements the encoding.TextUnmarshaler interface for timeRFC1123. +func (t *timeRFC1123) UnmarshalText(data []byte) (err error) { + t.Time, err = time.Parse(time.RFC1123, string(data)) + return +} + +// internal type used for marshalling time in RFC3339 format +type timeRFC3339 struct { + time.Time +} + +// MarshalText implements the encoding.TextMarshaler interface for timeRFC3339. +func (t timeRFC3339) MarshalText() ([]byte, error) { + return []byte(t.Format(rfc3339Format)), nil +} + +// UnmarshalText implements the encoding.TextUnmarshaler interface for timeRFC3339. +func (t *timeRFC3339) UnmarshalText(data []byte) (err error) { + t.Time, err = time.Parse(rfc3339Format, string(data)) + return +} + +// internal type used for marshalling +type accessPolicy struct { + Start timeRFC3339 `xml:"Start"` + Expiry timeRFC3339 `xml:"Expiry"` + Permission string `xml:"Permission"` +} + +// internal type used for marshalling +type blobProperties struct { + LastModified timeRFC1123 `xml:"Last-Modified"` + Etag ETag `xml:"Etag"` + ContentLength *int64 `xml:"Content-Length"` + ContentType *string `xml:"Content-Type"` + ContentEncoding *string `xml:"Content-Encoding"` + ContentLanguage *string `xml:"Content-Language"` + ContentMD5 []byte `xml:"Content-MD5"` + ContentDisposition *string `xml:"Content-Disposition"` + CacheControl *string `xml:"Cache-Control"` + BlobSequenceNumber *int64 `xml:"x-ms-blob-sequence-number"` + BlobType BlobType `xml:"BlobType"` + LeaseStatus LeaseStatusType `xml:"LeaseStatus"` + LeaseState LeaseStateType `xml:"LeaseState"` + LeaseDuration LeaseDurationType `xml:"LeaseDuration"` + CopyID *string `xml:"CopyId"` + CopyStatus CopyStatusType `xml:"CopyStatus"` + CopySource *string `xml:"CopySource"` + CopyProgress *string `xml:"CopyProgress"` + CopyCompletionTime *timeRFC1123 `xml:"CopyCompletionTime"` + CopyStatusDescription *string `xml:"CopyStatusDescription"` + ServerEncrypted *bool `xml:"ServerEncrypted"` + IncrementalCopy *bool `xml:"IncrementalCopy"` + DestinationSnapshot *string `xml:"DestinationSnapshot"` + DeletedTime *timeRFC1123 `xml:"DeletedTime"` + RemainingRetentionDays *int32 `xml:"RemainingRetentionDays"` + AccessTier AccessTierType `xml:"AccessTier"` + AccessTierInferred *bool `xml:"AccessTierInferred"` + ArchiveStatus ArchiveStatusType `xml:"ArchiveStatus"` +} + +// internal type used for marshalling +type containerProperties struct { + LastModified timeRFC1123 `xml:"Last-Modified"` + Etag ETag `xml:"Etag"` + LeaseStatus LeaseStatusType `xml:"LeaseStatus"` + LeaseState LeaseStateType `xml:"LeaseState"` + LeaseDuration LeaseDurationType `xml:"LeaseDuration"` + PublicAccess PublicAccessType `xml:"PublicAccess"` +} + +// internal type used for marshalling +type geoReplication struct { + Status GeoReplicationStatusType `xml:"Status"` + LastSyncTime timeRFC1123 `xml:"LastSyncTime"` +} diff --git a/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zz_generated_page_blob.go b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zz_generated_page_blob.go new file mode 100644 index 0000000000..ce6507080e --- /dev/null +++ b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zz_generated_page_blob.go @@ -0,0 +1,794 @@ +package azblob + +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "context" + "encoding/base64" + "encoding/xml" + "github.com/Azure/azure-pipeline-go/pipeline" + "io" + "io/ioutil" + "net/http" + "net/url" + "strconv" + "time" +) + +// pageBlobClient is the client for the PageBlob methods of the Azblob service. +type pageBlobClient struct { + managementClient +} + +// newPageBlobClient creates an instance of the pageBlobClient client. +func newPageBlobClient(url url.URL, p pipeline.Pipeline) pageBlobClient { + return pageBlobClient{newManagementClient(url, p)} +} + +// ClearPages the Clear Pages operation clears a set of pages from a page blob +// +// contentLength is the length of the request. timeout is the timeout parameter is expressed in seconds. For more +// information, see Setting +// Timeouts for Blob Service Operations. rangeParameter is return only the bytes of the blob in the specified +// range. leaseID is if specified, the operation only succeeds if the container's lease is active and matches this ID. +// ifSequenceNumberLessThanOrEqualTo is specify this header value to operate only on a blob if it has a sequence number +// less than or equal to the specified. ifSequenceNumberLessThan is specify this header value to operate only on a blob +// if it has a sequence number less than the specified. ifSequenceNumberEqualTo is specify this header value to operate +// only on a blob if it has the specified sequence number. ifModifiedSince is specify this header value to operate only +// on a blob if it has been modified since the specified date/time. ifUnmodifiedSince is specify this header value to +// operate only on a blob if it has not been modified since the specified date/time. ifMatches is specify an ETag value +// to operate only on blobs with a matching value. ifNoneMatch is specify an ETag value to operate only on blobs +// without a matching value. requestID is provides a client-generated, opaque value with a 1 KB character limit that is +// recorded in the analytics logs when storage analytics logging is enabled. +func (client pageBlobClient) ClearPages(ctx context.Context, contentLength int64, timeout *int32, rangeParameter *string, leaseID *string, ifSequenceNumberLessThanOrEqualTo *int64, ifSequenceNumberLessThan *int64, ifSequenceNumberEqualTo *int64, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (*PageBlobClearPagesResponse, error) { + if err := validate([]validation{ + {targetValue: timeout, + constraints: []constraint{{target: "timeout", name: null, rule: false, + chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil { + return nil, err + } + req, err := client.clearPagesPreparer(contentLength, timeout, rangeParameter, leaseID, ifSequenceNumberLessThanOrEqualTo, ifSequenceNumberLessThan, ifSequenceNumberEqualTo, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestID) + if err != nil { + return nil, err + } + resp, err := client.Pipeline().Do(ctx, responderPolicyFactory{responder: client.clearPagesResponder}, req) + if err != nil { + return nil, err + } + return resp.(*PageBlobClearPagesResponse), err +} + +// clearPagesPreparer prepares the ClearPages request. +func (client pageBlobClient) clearPagesPreparer(contentLength int64, timeout *int32, rangeParameter *string, leaseID *string, ifSequenceNumberLessThanOrEqualTo *int64, ifSequenceNumberLessThan *int64, ifSequenceNumberEqualTo *int64, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (pipeline.Request, error) { + req, err := pipeline.NewRequest("PUT", client.url, nil) + if err != nil { + return req, pipeline.NewError(err, "failed to create request") + } + params := req.URL.Query() + if timeout != nil { + params.Set("timeout", strconv.FormatInt(int64(*timeout), 10)) + } + params.Set("comp", "page") + req.URL.RawQuery = params.Encode() + req.Header.Set("Content-Length", strconv.FormatInt(contentLength, 10)) + if rangeParameter != nil { + req.Header.Set("x-ms-range", *rangeParameter) + } + if leaseID != nil { + req.Header.Set("x-ms-lease-id", *leaseID) + } + if ifSequenceNumberLessThanOrEqualTo != nil { + req.Header.Set("x-ms-if-sequence-number-le", strconv.FormatInt(*ifSequenceNumberLessThanOrEqualTo, 10)) + } + if ifSequenceNumberLessThan != nil { + req.Header.Set("x-ms-if-sequence-number-lt", strconv.FormatInt(*ifSequenceNumberLessThan, 10)) + } + if ifSequenceNumberEqualTo != nil { + req.Header.Set("x-ms-if-sequence-number-eq", strconv.FormatInt(*ifSequenceNumberEqualTo, 10)) + } + if ifModifiedSince != nil { + req.Header.Set("If-Modified-Since", (*ifModifiedSince).In(gmt).Format(time.RFC1123)) + } + if ifUnmodifiedSince != nil { + req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123)) + } + if ifMatches != nil { + req.Header.Set("If-Match", string(*ifMatches)) + } + if ifNoneMatch != nil { + req.Header.Set("If-None-Match", string(*ifNoneMatch)) + } + req.Header.Set("x-ms-version", ServiceVersion) + if requestID != nil { + req.Header.Set("x-ms-client-request-id", *requestID) + } + req.Header.Set("x-ms-page-write", "clear") + return req, nil +} + +// clearPagesResponder handles the response to the ClearPages request. +func (client pageBlobClient) clearPagesResponder(resp pipeline.Response) (pipeline.Response, error) { + err := validateResponse(resp, http.StatusOK, http.StatusCreated) + if resp == nil { + return nil, err + } + io.Copy(ioutil.Discard, resp.Response().Body) + resp.Response().Body.Close() + return &PageBlobClearPagesResponse{rawResponse: resp.Response()}, err +} + +// CopyIncremental the Copy Incremental operation copies a snapshot of the source page blob to a destination page blob. +// The snapshot is copied such that only the differential changes between the previously copied snapshot are +// transferred to the destination. The copied snapshots are complete copies of the original snapshot and can be read or +// copied from as usual. This API is supported since REST version 2016-05-31. +// +// copySource is specifies the name of the source page blob snapshot. This value is a URL of up to 2 KB in length that +// specifies a page blob snapshot. The value should be URL-encoded as it would appear in a request URI. The source blob +// must either be public or must be authenticated via a shared access signature. timeout is the timeout parameter is +// expressed in seconds. For more information, see Setting +// Timeouts for Blob Service Operations. metadata is optional. Specifies a user-defined name-value pair associated +// with the blob. If no name-value pairs are specified, the operation will copy the metadata from the source blob or +// file to the destination blob. If one or more name-value pairs are specified, the destination blob is created with +// the specified metadata, and metadata is not copied from the source blob or file. Note that beginning with version +// 2009-09-19, metadata names must adhere to the naming rules for C# identifiers. See Naming and Referencing +// Containers, Blobs, and Metadata for more information. ifModifiedSince is specify this header value to operate only +// on a blob if it has been modified since the specified date/time. ifUnmodifiedSince is specify this header value to +// operate only on a blob if it has not been modified since the specified date/time. ifMatches is specify an ETag value +// to operate only on blobs with a matching value. ifNoneMatch is specify an ETag value to operate only on blobs +// without a matching value. requestID is provides a client-generated, opaque value with a 1 KB character limit that is +// recorded in the analytics logs when storage analytics logging is enabled. +func (client pageBlobClient) CopyIncremental(ctx context.Context, copySource string, timeout *int32, metadata map[string]string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (*PageBlobCopyIncrementalResponse, error) { + if err := validate([]validation{ + {targetValue: timeout, + constraints: []constraint{{target: "timeout", name: null, rule: false, + chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}, + {targetValue: metadata, + constraints: []constraint{{target: "metadata", name: null, rule: false, + chain: []constraint{{target: "metadata", name: pattern, rule: `^[a-zA-Z]+$`, chain: nil}}}}}}); err != nil { + return nil, err + } + req, err := client.copyIncrementalPreparer(copySource, timeout, metadata, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestID) + if err != nil { + return nil, err + } + resp, err := client.Pipeline().Do(ctx, responderPolicyFactory{responder: client.copyIncrementalResponder}, req) + if err != nil { + return nil, err + } + return resp.(*PageBlobCopyIncrementalResponse), err +} + +// copyIncrementalPreparer prepares the CopyIncremental request. +func (client pageBlobClient) copyIncrementalPreparer(copySource string, timeout *int32, metadata map[string]string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (pipeline.Request, error) { + req, err := pipeline.NewRequest("PUT", client.url, nil) + if err != nil { + return req, pipeline.NewError(err, "failed to create request") + } + params := req.URL.Query() + if timeout != nil { + params.Set("timeout", strconv.FormatInt(int64(*timeout), 10)) + } + params.Set("comp", "incrementalcopy") + req.URL.RawQuery = params.Encode() + if metadata != nil { + for k, v := range metadata { + req.Header.Set("x-ms-meta-"+k, v) + } + } + if ifModifiedSince != nil { + req.Header.Set("If-Modified-Since", (*ifModifiedSince).In(gmt).Format(time.RFC1123)) + } + if ifUnmodifiedSince != nil { + req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123)) + } + if ifMatches != nil { + req.Header.Set("If-Match", string(*ifMatches)) + } + if ifNoneMatch != nil { + req.Header.Set("If-None-Match", string(*ifNoneMatch)) + } + req.Header.Set("x-ms-copy-source", copySource) + req.Header.Set("x-ms-version", ServiceVersion) + if requestID != nil { + req.Header.Set("x-ms-client-request-id", *requestID) + } + return req, nil +} + +// copyIncrementalResponder handles the response to the CopyIncremental request. +func (client pageBlobClient) copyIncrementalResponder(resp pipeline.Response) (pipeline.Response, error) { + err := validateResponse(resp, http.StatusOK, http.StatusAccepted) + if resp == nil { + return nil, err + } + io.Copy(ioutil.Discard, resp.Response().Body) + resp.Response().Body.Close() + return &PageBlobCopyIncrementalResponse{rawResponse: resp.Response()}, err +} + +// Create the Create operation creates a new page blob. +// +// contentLength is the length of the request. timeout is the timeout parameter is expressed in seconds. For more +// information, see Setting +// Timeouts for Blob Service Operations. blobContentType is optional. Sets the blob's content type. If specified, +// this property is stored with the blob and returned with a read request. blobContentEncoding is optional. Sets the +// blob's content encoding. If specified, this property is stored with the blob and returned with a read request. +// blobContentLanguage is optional. Set the blob's content language. If specified, this property is stored with the +// blob and returned with a read request. blobContentMD5 is optional. An MD5 hash of the blob content. Note that this +// hash is not validated, as the hashes for the individual blocks were validated when each was uploaded. +// blobCacheControl is optional. Sets the blob's cache control. If specified, this property is stored with the blob and +// returned with a read request. metadata is optional. Specifies a user-defined name-value pair associated with the +// blob. If no name-value pairs are specified, the operation will copy the metadata from the source blob or file to the +// destination blob. If one or more name-value pairs are specified, the destination blob is created with the specified +// metadata, and metadata is not copied from the source blob or file. Note that beginning with version 2009-09-19, +// metadata names must adhere to the naming rules for C# identifiers. See Naming and Referencing Containers, Blobs, and +// Metadata for more information. leaseID is if specified, the operation only succeeds if the container's lease is +// active and matches this ID. blobContentDisposition is optional. Sets the blob's Content-Disposition header. +// ifModifiedSince is specify this header value to operate only on a blob if it has been modified since the specified +// date/time. ifUnmodifiedSince is specify this header value to operate only on a blob if it has not been modified +// since the specified date/time. ifMatches is specify an ETag value to operate only on blobs with a matching value. +// ifNoneMatch is specify an ETag value to operate only on blobs without a matching value. blobContentLength is this +// header specifies the maximum size for the page blob, up to 1 TB. The page blob size must be aligned to a 512-byte +// boundary. blobSequenceNumber is set for page blobs only. The sequence number is a user-controlled value that you can +// use to track requests. The value of the sequence number must be between 0 and 2^63 - 1. requestID is provides a +// client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage +// analytics logging is enabled. +func (client pageBlobClient) Create(ctx context.Context, contentLength int64, timeout *int32, blobContentType *string, blobContentEncoding *string, blobContentLanguage *string, blobContentMD5 []byte, blobCacheControl *string, metadata map[string]string, leaseID *string, blobContentDisposition *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, blobContentLength *int64, blobSequenceNumber *int64, requestID *string) (*PageBlobCreateResponse, error) { + if err := validate([]validation{ + {targetValue: timeout, + constraints: []constraint{{target: "timeout", name: null, rule: false, + chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}, + {targetValue: metadata, + constraints: []constraint{{target: "metadata", name: null, rule: false, + chain: []constraint{{target: "metadata", name: pattern, rule: `^[a-zA-Z]+$`, chain: nil}}}}}}); err != nil { + return nil, err + } + req, err := client.createPreparer(contentLength, timeout, blobContentType, blobContentEncoding, blobContentLanguage, blobContentMD5, blobCacheControl, metadata, leaseID, blobContentDisposition, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, blobContentLength, blobSequenceNumber, requestID) + if err != nil { + return nil, err + } + resp, err := client.Pipeline().Do(ctx, responderPolicyFactory{responder: client.createResponder}, req) + if err != nil { + return nil, err + } + return resp.(*PageBlobCreateResponse), err +} + +// createPreparer prepares the Create request. +func (client pageBlobClient) createPreparer(contentLength int64, timeout *int32, blobContentType *string, blobContentEncoding *string, blobContentLanguage *string, blobContentMD5 []byte, blobCacheControl *string, metadata map[string]string, leaseID *string, blobContentDisposition *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, blobContentLength *int64, blobSequenceNumber *int64, requestID *string) (pipeline.Request, error) { + req, err := pipeline.NewRequest("PUT", client.url, nil) + if err != nil { + return req, pipeline.NewError(err, "failed to create request") + } + params := req.URL.Query() + if timeout != nil { + params.Set("timeout", strconv.FormatInt(int64(*timeout), 10)) + } + req.URL.RawQuery = params.Encode() + req.Header.Set("Content-Length", strconv.FormatInt(contentLength, 10)) + if blobContentType != nil { + req.Header.Set("x-ms-blob-content-type", *blobContentType) + } + if blobContentEncoding != nil { + req.Header.Set("x-ms-blob-content-encoding", *blobContentEncoding) + } + if blobContentLanguage != nil { + req.Header.Set("x-ms-blob-content-language", *blobContentLanguage) + } + if blobContentMD5 != nil { + req.Header.Set("x-ms-blob-content-md5", base64.StdEncoding.EncodeToString(blobContentMD5)) + } + if blobCacheControl != nil { + req.Header.Set("x-ms-blob-cache-control", *blobCacheControl) + } + if metadata != nil { + for k, v := range metadata { + req.Header.Set("x-ms-meta-"+k, v) + } + } + if leaseID != nil { + req.Header.Set("x-ms-lease-id", *leaseID) + } + if blobContentDisposition != nil { + req.Header.Set("x-ms-blob-content-disposition", *blobContentDisposition) + } + if ifModifiedSince != nil { + req.Header.Set("If-Modified-Since", (*ifModifiedSince).In(gmt).Format(time.RFC1123)) + } + if ifUnmodifiedSince != nil { + req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123)) + } + if ifMatches != nil { + req.Header.Set("If-Match", string(*ifMatches)) + } + if ifNoneMatch != nil { + req.Header.Set("If-None-Match", string(*ifNoneMatch)) + } + if blobContentLength != nil { + req.Header.Set("x-ms-blob-content-length", strconv.FormatInt(*blobContentLength, 10)) + } + if blobSequenceNumber != nil { + req.Header.Set("x-ms-blob-sequence-number", strconv.FormatInt(*blobSequenceNumber, 10)) + } + req.Header.Set("x-ms-version", ServiceVersion) + if requestID != nil { + req.Header.Set("x-ms-client-request-id", *requestID) + } + req.Header.Set("x-ms-blob-type", "PageBlob") + return req, nil +} + +// createResponder handles the response to the Create request. +func (client pageBlobClient) createResponder(resp pipeline.Response) (pipeline.Response, error) { + err := validateResponse(resp, http.StatusOK, http.StatusCreated) + if resp == nil { + return nil, err + } + io.Copy(ioutil.Discard, resp.Response().Body) + resp.Response().Body.Close() + return &PageBlobCreateResponse{rawResponse: resp.Response()}, err +} + +// GetPageRanges the Get Page Ranges operation returns the list of valid page ranges for a page blob or snapshot of a +// page blob +// +// snapshot is the snapshot parameter is an opaque DateTime value that, when present, specifies the blob snapshot to +// retrieve. For more information on working with blob snapshots, see Creating +// a Snapshot of a Blob. timeout is the timeout parameter is expressed in seconds. For more information, see Setting +// Timeouts for Blob Service Operations. rangeParameter is return only the bytes of the blob in the specified +// range. leaseID is if specified, the operation only succeeds if the container's lease is active and matches this ID. +// ifModifiedSince is specify this header value to operate only on a blob if it has been modified since the specified +// date/time. ifUnmodifiedSince is specify this header value to operate only on a blob if it has not been modified +// since the specified date/time. ifMatches is specify an ETag value to operate only on blobs with a matching value. +// ifNoneMatch is specify an ETag value to operate only on blobs without a matching value. requestID is provides a +// client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage +// analytics logging is enabled. +func (client pageBlobClient) GetPageRanges(ctx context.Context, snapshot *string, timeout *int32, rangeParameter *string, leaseID *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (*PageList, error) { + if err := validate([]validation{ + {targetValue: timeout, + constraints: []constraint{{target: "timeout", name: null, rule: false, + chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil { + return nil, err + } + req, err := client.getPageRangesPreparer(snapshot, timeout, rangeParameter, leaseID, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestID) + if err != nil { + return nil, err + } + resp, err := client.Pipeline().Do(ctx, responderPolicyFactory{responder: client.getPageRangesResponder}, req) + if err != nil { + return nil, err + } + return resp.(*PageList), err +} + +// getPageRangesPreparer prepares the GetPageRanges request. +func (client pageBlobClient) getPageRangesPreparer(snapshot *string, timeout *int32, rangeParameter *string, leaseID *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (pipeline.Request, error) { + req, err := pipeline.NewRequest("GET", client.url, nil) + if err != nil { + return req, pipeline.NewError(err, "failed to create request") + } + params := req.URL.Query() + if snapshot != nil && len(*snapshot) > 0 { + params.Set("snapshot", *snapshot) + } + if timeout != nil { + params.Set("timeout", strconv.FormatInt(int64(*timeout), 10)) + } + params.Set("comp", "pagelist") + req.URL.RawQuery = params.Encode() + if rangeParameter != nil { + req.Header.Set("x-ms-range", *rangeParameter) + } + if leaseID != nil { + req.Header.Set("x-ms-lease-id", *leaseID) + } + if ifModifiedSince != nil { + req.Header.Set("If-Modified-Since", (*ifModifiedSince).In(gmt).Format(time.RFC1123)) + } + if ifUnmodifiedSince != nil { + req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123)) + } + if ifMatches != nil { + req.Header.Set("If-Match", string(*ifMatches)) + } + if ifNoneMatch != nil { + req.Header.Set("If-None-Match", string(*ifNoneMatch)) + } + req.Header.Set("x-ms-version", ServiceVersion) + if requestID != nil { + req.Header.Set("x-ms-client-request-id", *requestID) + } + return req, nil +} + +// getPageRangesResponder handles the response to the GetPageRanges request. +func (client pageBlobClient) getPageRangesResponder(resp pipeline.Response) (pipeline.Response, error) { + err := validateResponse(resp, http.StatusOK) + if resp == nil { + return nil, err + } + result := &PageList{rawResponse: resp.Response()} + if err != nil { + return result, err + } + defer resp.Response().Body.Close() + b, err := ioutil.ReadAll(resp.Response().Body) + if err != nil { + return result, NewResponseError(err, resp.Response(), "failed to read response body") + } + if len(b) > 0 { + b = removeBOM(b) + err = xml.Unmarshal(b, result) + if err != nil { + return result, NewResponseError(err, resp.Response(), "failed to unmarshal response body") + } + } + return result, nil +} + +// GetPageRangesDiff [Update] The Get Page Ranges Diff operation returns the list of valid page ranges for a page blob +// that were changed between target blob and previous snapshot. +// +// snapshot is the snapshot parameter is an opaque DateTime value that, when present, specifies the blob snapshot to +// retrieve. For more information on working with blob snapshots, see Creating +// a Snapshot of a Blob. timeout is the timeout parameter is expressed in seconds. For more information, see Setting +// Timeouts for Blob Service Operations. prevsnapshot is optional in version 2015-07-08 and newer. The prevsnapshot +// parameter is a DateTime value that specifies that the response will contain only pages that were changed between +// target blob and previous snapshot. Changed pages include both updated and cleared pages. The target blob may be a +// snapshot, as long as the snapshot specified by prevsnapshot is the older of the two. Note that incremental snapshots +// are currently supported only for blobs created on or after January 1, 2016. rangeParameter is return only the bytes +// of the blob in the specified range. leaseID is if specified, the operation only succeeds if the container's lease is +// active and matches this ID. ifModifiedSince is specify this header value to operate only on a blob if it has been +// modified since the specified date/time. ifUnmodifiedSince is specify this header value to operate only on a blob if +// it has not been modified since the specified date/time. ifMatches is specify an ETag value to operate only on blobs +// with a matching value. ifNoneMatch is specify an ETag value to operate only on blobs without a matching value. +// requestID is provides a client-generated, opaque value with a 1 KB character limit that is recorded in the analytics +// logs when storage analytics logging is enabled. +func (client pageBlobClient) GetPageRangesDiff(ctx context.Context, snapshot *string, timeout *int32, prevsnapshot *string, rangeParameter *string, leaseID *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (*PageList, error) { + if err := validate([]validation{ + {targetValue: timeout, + constraints: []constraint{{target: "timeout", name: null, rule: false, + chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil { + return nil, err + } + req, err := client.getPageRangesDiffPreparer(snapshot, timeout, prevsnapshot, rangeParameter, leaseID, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestID) + if err != nil { + return nil, err + } + resp, err := client.Pipeline().Do(ctx, responderPolicyFactory{responder: client.getPageRangesDiffResponder}, req) + if err != nil { + return nil, err + } + return resp.(*PageList), err +} + +// getPageRangesDiffPreparer prepares the GetPageRangesDiff request. +func (client pageBlobClient) getPageRangesDiffPreparer(snapshot *string, timeout *int32, prevsnapshot *string, rangeParameter *string, leaseID *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (pipeline.Request, error) { + req, err := pipeline.NewRequest("GET", client.url, nil) + if err != nil { + return req, pipeline.NewError(err, "failed to create request") + } + params := req.URL.Query() + if snapshot != nil && len(*snapshot) > 0 { + params.Set("snapshot", *snapshot) + } + if timeout != nil { + params.Set("timeout", strconv.FormatInt(int64(*timeout), 10)) + } + if prevsnapshot != nil && len(*prevsnapshot) > 0 { + params.Set("prevsnapshot", *prevsnapshot) + } + params.Set("comp", "pagelist") + req.URL.RawQuery = params.Encode() + if rangeParameter != nil { + req.Header.Set("x-ms-range", *rangeParameter) + } + if leaseID != nil { + req.Header.Set("x-ms-lease-id", *leaseID) + } + if ifModifiedSince != nil { + req.Header.Set("If-Modified-Since", (*ifModifiedSince).In(gmt).Format(time.RFC1123)) + } + if ifUnmodifiedSince != nil { + req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123)) + } + if ifMatches != nil { + req.Header.Set("If-Match", string(*ifMatches)) + } + if ifNoneMatch != nil { + req.Header.Set("If-None-Match", string(*ifNoneMatch)) + } + req.Header.Set("x-ms-version", ServiceVersion) + if requestID != nil { + req.Header.Set("x-ms-client-request-id", *requestID) + } + return req, nil +} + +// getPageRangesDiffResponder handles the response to the GetPageRangesDiff request. +func (client pageBlobClient) getPageRangesDiffResponder(resp pipeline.Response) (pipeline.Response, error) { + err := validateResponse(resp, http.StatusOK) + if resp == nil { + return nil, err + } + result := &PageList{rawResponse: resp.Response()} + if err != nil { + return result, err + } + defer resp.Response().Body.Close() + b, err := ioutil.ReadAll(resp.Response().Body) + if err != nil { + return result, NewResponseError(err, resp.Response(), "failed to read response body") + } + if len(b) > 0 { + b = removeBOM(b) + err = xml.Unmarshal(b, result) + if err != nil { + return result, NewResponseError(err, resp.Response(), "failed to unmarshal response body") + } + } + return result, nil +} + +// Resize resize the Blob +// +// blobContentLength is this header specifies the maximum size for the page blob, up to 1 TB. The page blob size must +// be aligned to a 512-byte boundary. timeout is the timeout parameter is expressed in seconds. For more information, +// see Setting +// Timeouts for Blob Service Operations. leaseID is if specified, the operation only succeeds if the container's +// lease is active and matches this ID. ifModifiedSince is specify this header value to operate only on a blob if it +// has been modified since the specified date/time. ifUnmodifiedSince is specify this header value to operate only on a +// blob if it has not been modified since the specified date/time. ifMatches is specify an ETag value to operate only +// on blobs with a matching value. ifNoneMatch is specify an ETag value to operate only on blobs without a matching +// value. requestID is provides a client-generated, opaque value with a 1 KB character limit that is recorded in the +// analytics logs when storage analytics logging is enabled. +func (client pageBlobClient) Resize(ctx context.Context, blobContentLength int64, timeout *int32, leaseID *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (*PageBlobResizeResponse, error) { + if err := validate([]validation{ + {targetValue: timeout, + constraints: []constraint{{target: "timeout", name: null, rule: false, + chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil { + return nil, err + } + req, err := client.resizePreparer(blobContentLength, timeout, leaseID, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestID) + if err != nil { + return nil, err + } + resp, err := client.Pipeline().Do(ctx, responderPolicyFactory{responder: client.resizeResponder}, req) + if err != nil { + return nil, err + } + return resp.(*PageBlobResizeResponse), err +} + +// resizePreparer prepares the Resize request. +func (client pageBlobClient) resizePreparer(blobContentLength int64, timeout *int32, leaseID *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (pipeline.Request, error) { + req, err := pipeline.NewRequest("PUT", client.url, nil) + if err != nil { + return req, pipeline.NewError(err, "failed to create request") + } + params := req.URL.Query() + if timeout != nil { + params.Set("timeout", strconv.FormatInt(int64(*timeout), 10)) + } + params.Set("comp", "properties") + req.URL.RawQuery = params.Encode() + if leaseID != nil { + req.Header.Set("x-ms-lease-id", *leaseID) + } + if ifModifiedSince != nil { + req.Header.Set("If-Modified-Since", (*ifModifiedSince).In(gmt).Format(time.RFC1123)) + } + if ifUnmodifiedSince != nil { + req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123)) + } + if ifMatches != nil { + req.Header.Set("If-Match", string(*ifMatches)) + } + if ifNoneMatch != nil { + req.Header.Set("If-None-Match", string(*ifNoneMatch)) + } + req.Header.Set("x-ms-blob-content-length", strconv.FormatInt(blobContentLength, 10)) + req.Header.Set("x-ms-version", ServiceVersion) + if requestID != nil { + req.Header.Set("x-ms-client-request-id", *requestID) + } + return req, nil +} + +// resizeResponder handles the response to the Resize request. +func (client pageBlobClient) resizeResponder(resp pipeline.Response) (pipeline.Response, error) { + err := validateResponse(resp, http.StatusOK) + if resp == nil { + return nil, err + } + io.Copy(ioutil.Discard, resp.Response().Body) + resp.Response().Body.Close() + return &PageBlobResizeResponse{rawResponse: resp.Response()}, err +} + +// UpdateSequenceNumber update the sequence number of the blob +// +// sequenceNumberAction is required if the x-ms-blob-sequence-number header is set for the request. This property +// applies to page blobs only. This property indicates how the service should modify the blob's sequence number timeout +// is the timeout parameter is expressed in seconds. For more information, see Setting +// Timeouts for Blob Service Operations. leaseID is if specified, the operation only succeeds if the container's +// lease is active and matches this ID. ifModifiedSince is specify this header value to operate only on a blob if it +// has been modified since the specified date/time. ifUnmodifiedSince is specify this header value to operate only on a +// blob if it has not been modified since the specified date/time. ifMatches is specify an ETag value to operate only +// on blobs with a matching value. ifNoneMatch is specify an ETag value to operate only on blobs without a matching +// value. blobSequenceNumber is set for page blobs only. The sequence number is a user-controlled value that you can +// use to track requests. The value of the sequence number must be between 0 and 2^63 - 1. requestID is provides a +// client-generated, opaque value with a 1 KB character limit that is recorded in the analytics logs when storage +// analytics logging is enabled. +func (client pageBlobClient) UpdateSequenceNumber(ctx context.Context, sequenceNumberAction SequenceNumberActionType, timeout *int32, leaseID *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, blobSequenceNumber *int64, requestID *string) (*PageBlobUpdateSequenceNumberResponse, error) { + if err := validate([]validation{ + {targetValue: timeout, + constraints: []constraint{{target: "timeout", name: null, rule: false, + chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil { + return nil, err + } + req, err := client.updateSequenceNumberPreparer(sequenceNumberAction, timeout, leaseID, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, blobSequenceNumber, requestID) + if err != nil { + return nil, err + } + resp, err := client.Pipeline().Do(ctx, responderPolicyFactory{responder: client.updateSequenceNumberResponder}, req) + if err != nil { + return nil, err + } + return resp.(*PageBlobUpdateSequenceNumberResponse), err +} + +// updateSequenceNumberPreparer prepares the UpdateSequenceNumber request. +func (client pageBlobClient) updateSequenceNumberPreparer(sequenceNumberAction SequenceNumberActionType, timeout *int32, leaseID *string, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, blobSequenceNumber *int64, requestID *string) (pipeline.Request, error) { + req, err := pipeline.NewRequest("PUT", client.url, nil) + if err != nil { + return req, pipeline.NewError(err, "failed to create request") + } + params := req.URL.Query() + if timeout != nil { + params.Set("timeout", strconv.FormatInt(int64(*timeout), 10)) + } + params.Set("comp", "properties") + req.URL.RawQuery = params.Encode() + if leaseID != nil { + req.Header.Set("x-ms-lease-id", *leaseID) + } + if ifModifiedSince != nil { + req.Header.Set("If-Modified-Since", (*ifModifiedSince).In(gmt).Format(time.RFC1123)) + } + if ifUnmodifiedSince != nil { + req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123)) + } + if ifMatches != nil { + req.Header.Set("If-Match", string(*ifMatches)) + } + if ifNoneMatch != nil { + req.Header.Set("If-None-Match", string(*ifNoneMatch)) + } + req.Header.Set("x-ms-sequence-number-action", string(sequenceNumberAction)) + if blobSequenceNumber != nil { + req.Header.Set("x-ms-blob-sequence-number", strconv.FormatInt(*blobSequenceNumber, 10)) + } + req.Header.Set("x-ms-version", ServiceVersion) + if requestID != nil { + req.Header.Set("x-ms-client-request-id", *requestID) + } + return req, nil +} + +// updateSequenceNumberResponder handles the response to the UpdateSequenceNumber request. +func (client pageBlobClient) updateSequenceNumberResponder(resp pipeline.Response) (pipeline.Response, error) { + err := validateResponse(resp, http.StatusOK) + if resp == nil { + return nil, err + } + io.Copy(ioutil.Discard, resp.Response().Body) + resp.Response().Body.Close() + return &PageBlobUpdateSequenceNumberResponse{rawResponse: resp.Response()}, err +} + +// UploadPages the Upload Pages operation writes a range of pages to a page blob +// +// body is initial data body will be closed upon successful return. Callers should ensure closure when receiving an +// error.contentLength is the length of the request. timeout is the timeout parameter is expressed in seconds. For more +// information, see Setting +// Timeouts for Blob Service Operations. rangeParameter is return only the bytes of the blob in the specified +// range. leaseID is if specified, the operation only succeeds if the container's lease is active and matches this ID. +// ifSequenceNumberLessThanOrEqualTo is specify this header value to operate only on a blob if it has a sequence number +// less than or equal to the specified. ifSequenceNumberLessThan is specify this header value to operate only on a blob +// if it has a sequence number less than the specified. ifSequenceNumberEqualTo is specify this header value to operate +// only on a blob if it has the specified sequence number. ifModifiedSince is specify this header value to operate only +// on a blob if it has been modified since the specified date/time. ifUnmodifiedSince is specify this header value to +// operate only on a blob if it has not been modified since the specified date/time. ifMatches is specify an ETag value +// to operate only on blobs with a matching value. ifNoneMatch is specify an ETag value to operate only on blobs +// without a matching value. requestID is provides a client-generated, opaque value with a 1 KB character limit that is +// recorded in the analytics logs when storage analytics logging is enabled. +func (client pageBlobClient) UploadPages(ctx context.Context, body io.ReadSeeker, contentLength int64, timeout *int32, rangeParameter *string, leaseID *string, ifSequenceNumberLessThanOrEqualTo *int64, ifSequenceNumberLessThan *int64, ifSequenceNumberEqualTo *int64, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (*PageBlobUploadPagesResponse, error) { + if err := validate([]validation{ + {targetValue: body, + constraints: []constraint{{target: "body", name: null, rule: true, chain: nil}}}, + {targetValue: timeout, + constraints: []constraint{{target: "timeout", name: null, rule: false, + chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil { + return nil, err + } + req, err := client.uploadPagesPreparer(body, contentLength, timeout, rangeParameter, leaseID, ifSequenceNumberLessThanOrEqualTo, ifSequenceNumberLessThan, ifSequenceNumberEqualTo, ifModifiedSince, ifUnmodifiedSince, ifMatches, ifNoneMatch, requestID) + if err != nil { + return nil, err + } + resp, err := client.Pipeline().Do(ctx, responderPolicyFactory{responder: client.uploadPagesResponder}, req) + if err != nil { + return nil, err + } + return resp.(*PageBlobUploadPagesResponse), err +} + +// uploadPagesPreparer prepares the UploadPages request. +func (client pageBlobClient) uploadPagesPreparer(body io.ReadSeeker, contentLength int64, timeout *int32, rangeParameter *string, leaseID *string, ifSequenceNumberLessThanOrEqualTo *int64, ifSequenceNumberLessThan *int64, ifSequenceNumberEqualTo *int64, ifModifiedSince *time.Time, ifUnmodifiedSince *time.Time, ifMatches *ETag, ifNoneMatch *ETag, requestID *string) (pipeline.Request, error) { + req, err := pipeline.NewRequest("PUT", client.url, body) + if err != nil { + return req, pipeline.NewError(err, "failed to create request") + } + params := req.URL.Query() + if timeout != nil { + params.Set("timeout", strconv.FormatInt(int64(*timeout), 10)) + } + params.Set("comp", "page") + req.URL.RawQuery = params.Encode() + req.Header.Set("Content-Length", strconv.FormatInt(contentLength, 10)) + if rangeParameter != nil { + req.Header.Set("x-ms-range", *rangeParameter) + } + if leaseID != nil { + req.Header.Set("x-ms-lease-id", *leaseID) + } + if ifSequenceNumberLessThanOrEqualTo != nil { + req.Header.Set("x-ms-if-sequence-number-le", strconv.FormatInt(*ifSequenceNumberLessThanOrEqualTo, 10)) + } + if ifSequenceNumberLessThan != nil { + req.Header.Set("x-ms-if-sequence-number-lt", strconv.FormatInt(*ifSequenceNumberLessThan, 10)) + } + if ifSequenceNumberEqualTo != nil { + req.Header.Set("x-ms-if-sequence-number-eq", strconv.FormatInt(*ifSequenceNumberEqualTo, 10)) + } + if ifModifiedSince != nil { + req.Header.Set("If-Modified-Since", (*ifModifiedSince).In(gmt).Format(time.RFC1123)) + } + if ifUnmodifiedSince != nil { + req.Header.Set("If-Unmodified-Since", (*ifUnmodifiedSince).In(gmt).Format(time.RFC1123)) + } + if ifMatches != nil { + req.Header.Set("If-Match", string(*ifMatches)) + } + if ifNoneMatch != nil { + req.Header.Set("If-None-Match", string(*ifNoneMatch)) + } + req.Header.Set("x-ms-version", ServiceVersion) + if requestID != nil { + req.Header.Set("x-ms-client-request-id", *requestID) + } + req.Header.Set("x-ms-page-write", "update") + return req, nil +} + +// uploadPagesResponder handles the response to the UploadPages request. +func (client pageBlobClient) uploadPagesResponder(resp pipeline.Response) (pipeline.Response, error) { + err := validateResponse(resp, http.StatusOK, http.StatusCreated) + if resp == nil { + return nil, err + } + io.Copy(ioutil.Discard, resp.Response().Body) + resp.Response().Body.Close() + return &PageBlobUploadPagesResponse{rawResponse: resp.Response()}, err +} diff --git a/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zz_generated_responder_policy.go b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zz_generated_responder_policy.go new file mode 100644 index 0000000000..2f391d7312 --- /dev/null +++ b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zz_generated_responder_policy.go @@ -0,0 +1,74 @@ +package azblob + +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "bytes" + "context" + "encoding/xml" + "github.com/Azure/azure-pipeline-go/pipeline" + "io/ioutil" +) + +type responder func(resp pipeline.Response) (result pipeline.Response, err error) + +// ResponderPolicyFactory is a Factory capable of creating a responder pipeline. +type responderPolicyFactory struct { + responder responder +} + +// New creates a responder policy factory. +func (arpf responderPolicyFactory) New(next pipeline.Policy, po *pipeline.PolicyOptions) pipeline.Policy { + return responderPolicy{next: next, responder: arpf.responder} +} + +type responderPolicy struct { + next pipeline.Policy + responder responder +} + +// Do sends the request to the service and validates/deserializes the HTTP response. +func (arp responderPolicy) Do(ctx context.Context, request pipeline.Request) (pipeline.Response, error) { + resp, err := arp.next.Do(ctx, request) + if err != nil { + return resp, err + } + return arp.responder(resp) +} + +// validateResponse checks an HTTP response's status code against a legal set of codes. +// If the response code is not legal, then validateResponse reads all of the response's body +// (containing error information) and returns a response error. +func validateResponse(resp pipeline.Response, successStatusCodes ...int) error { + if resp == nil { + return NewResponseError(nil, nil, "nil response") + } + responseCode := resp.Response().StatusCode + for _, i := range successStatusCodes { + if i == responseCode { + return nil + } + } + // only close the body in the failure case. in the + // success case responders will close the body as required. + defer resp.Response().Body.Close() + b, err := ioutil.ReadAll(resp.Response().Body) + if err != nil { + return NewResponseError(err, resp.Response(), "failed to read response body") + } + // the service code, description and details will be populated during unmarshalling + responseError := NewResponseError(nil, resp.Response(), resp.Response().Status) + if len(b) > 0 { + if err = xml.Unmarshal(b, &responseError); err != nil { + return NewResponseError(err, resp.Response(), "failed to unmarshal response body") + } + } + return responseError +} + +// removes any BOM from the byte slice +func removeBOM(b []byte) []byte { + // UTF8 + return bytes.TrimPrefix(b, []byte("\xef\xbb\xbf")) +} diff --git a/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zz_generated_response_error.go b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zz_generated_response_error.go new file mode 100644 index 0000000000..3dcc75bb52 --- /dev/null +++ b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zz_generated_response_error.go @@ -0,0 +1,95 @@ +package azblob + +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "bytes" + "fmt" + "github.com/Azure/azure-pipeline-go/pipeline" + "net" + "net/http" +) + +// if you want to provide custom error handling set this variable to your constructor function +var responseErrorFactory func(cause error, response *http.Response, description string) error + +// ResponseError identifies a responder-generated network or response parsing error. +type ResponseError interface { + // Error exposes the Error(), Temporary() and Timeout() methods. + net.Error // Includes the Go error interface + // Response returns the HTTP response. You may examine this but you should not modify it. + Response() *http.Response +} + +// NewResponseError creates an error object that implements the error interface. +func NewResponseError(cause error, response *http.Response, description string) error { + if responseErrorFactory != nil { + return responseErrorFactory(cause, response, description) + } + return &responseError{ + ErrorNode: pipeline.ErrorNode{}.Initialize(cause, 3), + response: response, + description: description, + } +} + +// responseError is the internal struct that implements the public ResponseError interface. +type responseError struct { + pipeline.ErrorNode // This is embedded so that responseError "inherits" Error, Temporary, Timeout, and Cause + response *http.Response + description string +} + +// Error implements the error interface's Error method to return a string representation of the error. +func (e *responseError) Error() string { + b := &bytes.Buffer{} + fmt.Fprintf(b, "===== RESPONSE ERROR (Code=%v) =====\n", e.response.StatusCode) + fmt.Fprintf(b, "Status=%s, Description: %s\n", e.response.Status, e.description) + s := b.String() + return e.ErrorNode.Error(s) +} + +// Response implements the ResponseError interface's method to return the HTTP response. +func (e *responseError) Response() *http.Response { + return e.response +} + +// RFC7807 PROBLEM ------------------------------------------------------------------------------------ +// RFC7807Problem ... This type can be publicly embedded in another type that wants to add additional members. +/*type RFC7807Problem struct { + // Mandatory: A (relative) URI reference identifying the problem type (it MAY refer to human-readable documentation). + typeURI string // Should default to "about:blank" + // Optional: Short, human-readable summary (maybe localized). + title string + // Optional: HTTP status code generated by the origin server + status int + // Optional: Human-readable explanation for this problem occurance. + // Should help client correct the problem. Clients should NOT parse this string. + detail string + // Optional: A (relative) URI identifying this specific problem occurence (it may or may not be dereferenced). + instance string +} +// NewRFC7807Problem ... +func NewRFC7807Problem(typeURI string, status int, titleFormat string, a ...interface{}) error { + return &RFC7807Problem{ + typeURI: typeURI, + status: status, + title: fmt.Sprintf(titleFormat, a...), + } +} +// Error returns the error information as a string. +func (e *RFC7807Problem) Error() string { + return e.title +} +// TypeURI ... +func (e *RFC7807Problem) TypeURI() string { + if e.typeURI == "" { + e.typeURI = "about:blank" + } + return e.typeURI +} +// Members ... +func (e *RFC7807Problem) Members() (status int, title, detail, instance string) { + return e.status, e.title, e.detail, e.instance +}*/ diff --git a/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zz_generated_service.go b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zz_generated_service.go new file mode 100644 index 0000000000..76f235e159 --- /dev/null +++ b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zz_generated_service.go @@ -0,0 +1,350 @@ +package azblob + +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "bytes" + "context" + "encoding/xml" + "github.com/Azure/azure-pipeline-go/pipeline" + "io" + "io/ioutil" + "net/http" + "net/url" + "strconv" +) + +// serviceClient is the client for the Service methods of the Azblob service. +type serviceClient struct { + managementClient +} + +// newServiceClient creates an instance of the serviceClient client. +func newServiceClient(url url.URL, p pipeline.Pipeline) serviceClient { + return serviceClient{newManagementClient(url, p)} +} + +// GetProperties gets the properties of a storage account's Blob service, including properties for Storage Analytics +// and CORS (Cross-Origin Resource Sharing) rules. +// +// timeout is the timeout parameter is expressed in seconds. For more information, see Setting +// Timeouts for Blob Service Operations. requestID is provides a client-generated, opaque value with a 1 KB +// character limit that is recorded in the analytics logs when storage analytics logging is enabled. +func (client serviceClient) GetProperties(ctx context.Context, timeout *int32, requestID *string) (*StorageServiceProperties, error) { + if err := validate([]validation{ + {targetValue: timeout, + constraints: []constraint{{target: "timeout", name: null, rule: false, + chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil { + return nil, err + } + req, err := client.getPropertiesPreparer(timeout, requestID) + if err != nil { + return nil, err + } + resp, err := client.Pipeline().Do(ctx, responderPolicyFactory{responder: client.getPropertiesResponder}, req) + if err != nil { + return nil, err + } + return resp.(*StorageServiceProperties), err +} + +// getPropertiesPreparer prepares the GetProperties request. +func (client serviceClient) getPropertiesPreparer(timeout *int32, requestID *string) (pipeline.Request, error) { + req, err := pipeline.NewRequest("GET", client.url, nil) + if err != nil { + return req, pipeline.NewError(err, "failed to create request") + } + params := req.URL.Query() + if timeout != nil { + params.Set("timeout", strconv.FormatInt(int64(*timeout), 10)) + } + params.Set("restype", "service") + params.Set("comp", "properties") + req.URL.RawQuery = params.Encode() + req.Header.Set("x-ms-version", ServiceVersion) + if requestID != nil { + req.Header.Set("x-ms-client-request-id", *requestID) + } + return req, nil +} + +// getPropertiesResponder handles the response to the GetProperties request. +func (client serviceClient) getPropertiesResponder(resp pipeline.Response) (pipeline.Response, error) { + err := validateResponse(resp, http.StatusOK) + if resp == nil { + return nil, err + } + result := &StorageServiceProperties{rawResponse: resp.Response()} + if err != nil { + return result, err + } + defer resp.Response().Body.Close() + b, err := ioutil.ReadAll(resp.Response().Body) + if err != nil { + return result, NewResponseError(err, resp.Response(), "failed to read response body") + } + if len(b) > 0 { + b = removeBOM(b) + err = xml.Unmarshal(b, result) + if err != nil { + return result, NewResponseError(err, resp.Response(), "failed to unmarshal response body") + } + } + return result, nil +} + +// GetStatistics retrieves statistics related to replication for the Blob service. It is only available on the +// secondary location endpoint when read-access geo-redundant replication is enabled for the storage account. +// +// timeout is the timeout parameter is expressed in seconds. For more information, see Setting +// Timeouts for Blob Service Operations. requestID is provides a client-generated, opaque value with a 1 KB +// character limit that is recorded in the analytics logs when storage analytics logging is enabled. +func (client serviceClient) GetStatistics(ctx context.Context, timeout *int32, requestID *string) (*StorageServiceStats, error) { + if err := validate([]validation{ + {targetValue: timeout, + constraints: []constraint{{target: "timeout", name: null, rule: false, + chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil { + return nil, err + } + req, err := client.getStatisticsPreparer(timeout, requestID) + if err != nil { + return nil, err + } + resp, err := client.Pipeline().Do(ctx, responderPolicyFactory{responder: client.getStatisticsResponder}, req) + if err != nil { + return nil, err + } + return resp.(*StorageServiceStats), err +} + +// getStatisticsPreparer prepares the GetStatistics request. +func (client serviceClient) getStatisticsPreparer(timeout *int32, requestID *string) (pipeline.Request, error) { + req, err := pipeline.NewRequest("GET", client.url, nil) + if err != nil { + return req, pipeline.NewError(err, "failed to create request") + } + params := req.URL.Query() + if timeout != nil { + params.Set("timeout", strconv.FormatInt(int64(*timeout), 10)) + } + params.Set("restype", "service") + params.Set("comp", "stats") + req.URL.RawQuery = params.Encode() + req.Header.Set("x-ms-version", ServiceVersion) + if requestID != nil { + req.Header.Set("x-ms-client-request-id", *requestID) + } + return req, nil +} + +// getStatisticsResponder handles the response to the GetStatistics request. +func (client serviceClient) getStatisticsResponder(resp pipeline.Response) (pipeline.Response, error) { + err := validateResponse(resp, http.StatusOK) + if resp == nil { + return nil, err + } + result := &StorageServiceStats{rawResponse: resp.Response()} + if err != nil { + return result, err + } + defer resp.Response().Body.Close() + b, err := ioutil.ReadAll(resp.Response().Body) + if err != nil { + return result, NewResponseError(err, resp.Response(), "failed to read response body") + } + if len(b) > 0 { + b = removeBOM(b) + err = xml.Unmarshal(b, result) + if err != nil { + return result, NewResponseError(err, resp.Response(), "failed to unmarshal response body") + } + } + return result, nil +} + +// ListContainersSegment the List Containers Segment operation returns a list of the containers under the specified +// account +// +// prefix is filters the results to return only containers whose name begins with the specified prefix. marker is a +// string value that identifies the portion of the list of containers to be returned with the next listing operation. +// The operation returns the NextMarker value within the response body if the listing operation did not return all +// containers remaining to be listed with the current page. The NextMarker value can be used as the value for the +// marker parameter in a subsequent call to request the next page of list items. The marker value is opaque to the +// client. maxresults is specifies the maximum number of containers to return. If the request does not specify +// maxresults, or specifies a value greater than 5000, the server will return up to 5000 items. Note that if the +// listing operation crosses a partition boundary, then the service will return a continuation token for retrieving the +// remainder of the results. For this reason, it is possible that the service will return fewer results than specified +// by maxresults, or than the default of 5000. include is include this parameter to specify that the container's +// metadata be returned as part of the response body. timeout is the timeout parameter is expressed in seconds. For +// more information, see Setting +// Timeouts for Blob Service Operations. requestID is provides a client-generated, opaque value with a 1 KB +// character limit that is recorded in the analytics logs when storage analytics logging is enabled. +func (client serviceClient) ListContainersSegment(ctx context.Context, prefix *string, marker *string, maxresults *int32, include ListContainersIncludeType, timeout *int32, requestID *string) (*ListContainersResponse, error) { + if err := validate([]validation{ + {targetValue: maxresults, + constraints: []constraint{{target: "maxresults", name: null, rule: false, + chain: []constraint{{target: "maxresults", name: inclusiveMinimum, rule: 1, chain: nil}}}}}, + {targetValue: timeout, + constraints: []constraint{{target: "timeout", name: null, rule: false, + chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil { + return nil, err + } + req, err := client.listContainersSegmentPreparer(prefix, marker, maxresults, include, timeout, requestID) + if err != nil { + return nil, err + } + resp, err := client.Pipeline().Do(ctx, responderPolicyFactory{responder: client.listContainersSegmentResponder}, req) + if err != nil { + return nil, err + } + return resp.(*ListContainersResponse), err +} + +// listContainersSegmentPreparer prepares the ListContainersSegment request. +func (client serviceClient) listContainersSegmentPreparer(prefix *string, marker *string, maxresults *int32, include ListContainersIncludeType, timeout *int32, requestID *string) (pipeline.Request, error) { + req, err := pipeline.NewRequest("GET", client.url, nil) + if err != nil { + return req, pipeline.NewError(err, "failed to create request") + } + params := req.URL.Query() + if prefix != nil && len(*prefix) > 0 { + params.Set("prefix", *prefix) + } + if marker != nil && len(*marker) > 0 { + params.Set("marker", *marker) + } + if maxresults != nil { + params.Set("maxresults", strconv.FormatInt(int64(*maxresults), 10)) + } + if include != ListContainersIncludeNone { + params.Set("include", string(include)) + } + if timeout != nil { + params.Set("timeout", strconv.FormatInt(int64(*timeout), 10)) + } + params.Set("comp", "list") + req.URL.RawQuery = params.Encode() + req.Header.Set("x-ms-version", ServiceVersion) + if requestID != nil { + req.Header.Set("x-ms-client-request-id", *requestID) + } + return req, nil +} + +// listContainersSegmentResponder handles the response to the ListContainersSegment request. +func (client serviceClient) listContainersSegmentResponder(resp pipeline.Response) (pipeline.Response, error) { + err := validateResponse(resp, http.StatusOK) + if resp == nil { + return nil, err + } + result := &ListContainersResponse{rawResponse: resp.Response()} + if err != nil { + return result, err + } + defer resp.Response().Body.Close() + b, err := ioutil.ReadAll(resp.Response().Body) + if err != nil { + return result, NewResponseError(err, resp.Response(), "failed to read response body") + } + if len(b) > 0 { + b = removeBOM(b) + err = xml.Unmarshal(b, result) + if err != nil { + return result, NewResponseError(err, resp.Response(), "failed to unmarshal response body") + } + } + return result, nil +} + +// SetProperties sets properties for a storage account's Blob service endpoint, including properties for Storage +// Analytics and CORS (Cross-Origin Resource Sharing) rules +// +// storageServiceProperties is the StorageService properties. timeout is the timeout parameter is expressed in seconds. +// For more information, see Setting +// Timeouts for Blob Service Operations. requestID is provides a client-generated, opaque value with a 1 KB +// character limit that is recorded in the analytics logs when storage analytics logging is enabled. +func (client serviceClient) SetProperties(ctx context.Context, storageServiceProperties StorageServiceProperties, timeout *int32, requestID *string) (*ServiceSetPropertiesResponse, error) { + if err := validate([]validation{ + {targetValue: storageServiceProperties, + constraints: []constraint{{target: "storageServiceProperties.Logging", name: null, rule: false, + chain: []constraint{{target: "storageServiceProperties.Logging.RetentionPolicy", name: null, rule: true, + chain: []constraint{{target: "storageServiceProperties.Logging.RetentionPolicy.Days", name: null, rule: false, + chain: []constraint{{target: "storageServiceProperties.Logging.RetentionPolicy.Days", name: inclusiveMinimum, rule: 1, chain: nil}}}, + }}, + }}, + {target: "storageServiceProperties.HourMetrics", name: null, rule: false, + chain: []constraint{{target: "storageServiceProperties.HourMetrics.RetentionPolicy", name: null, rule: false, + chain: []constraint{{target: "storageServiceProperties.HourMetrics.RetentionPolicy.Days", name: null, rule: false, + chain: []constraint{{target: "storageServiceProperties.HourMetrics.RetentionPolicy.Days", name: inclusiveMinimum, rule: 1, chain: nil}}}, + }}, + }}, + {target: "storageServiceProperties.MinuteMetrics", name: null, rule: false, + chain: []constraint{{target: "storageServiceProperties.MinuteMetrics.RetentionPolicy", name: null, rule: false, + chain: []constraint{{target: "storageServiceProperties.MinuteMetrics.RetentionPolicy.Days", name: null, rule: false, + chain: []constraint{{target: "storageServiceProperties.MinuteMetrics.RetentionPolicy.Days", name: inclusiveMinimum, rule: 1, chain: nil}}}, + }}, + }}, + {target: "storageServiceProperties.DeleteRetentionPolicy", name: null, rule: false, + chain: []constraint{{target: "storageServiceProperties.DeleteRetentionPolicy.Days", name: null, rule: false, + chain: []constraint{{target: "storageServiceProperties.DeleteRetentionPolicy.Days", name: inclusiveMinimum, rule: 1, chain: nil}}}, + }}}}, + {targetValue: timeout, + constraints: []constraint{{target: "timeout", name: null, rule: false, + chain: []constraint{{target: "timeout", name: inclusiveMinimum, rule: 0, chain: nil}}}}}}); err != nil { + return nil, err + } + req, err := client.setPropertiesPreparer(storageServiceProperties, timeout, requestID) + if err != nil { + return nil, err + } + resp, err := client.Pipeline().Do(ctx, responderPolicyFactory{responder: client.setPropertiesResponder}, req) + if err != nil { + return nil, err + } + return resp.(*ServiceSetPropertiesResponse), err +} + +// setPropertiesPreparer prepares the SetProperties request. +func (client serviceClient) setPropertiesPreparer(storageServiceProperties StorageServiceProperties, timeout *int32, requestID *string) (pipeline.Request, error) { + req, err := pipeline.NewRequest("PUT", client.url, nil) + if err != nil { + return req, pipeline.NewError(err, "failed to create request") + } + params := req.URL.Query() + if timeout != nil { + params.Set("timeout", strconv.FormatInt(int64(*timeout), 10)) + } + params.Set("restype", "service") + params.Set("comp", "properties") + req.URL.RawQuery = params.Encode() + req.Header.Set("x-ms-version", ServiceVersion) + if requestID != nil { + req.Header.Set("x-ms-client-request-id", *requestID) + } + b, err := xml.Marshal(storageServiceProperties) + if err != nil { + return req, pipeline.NewError(err, "failed to marshal request body") + } + req.Header.Set("Content-Type", "application/xml") + err = req.SetBody(bytes.NewReader(b)) + if err != nil { + return req, pipeline.NewError(err, "failed to set request body") + } + return req, nil +} + +// setPropertiesResponder handles the response to the SetProperties request. +func (client serviceClient) setPropertiesResponder(resp pipeline.Response) (pipeline.Response, error) { + err := validateResponse(resp, http.StatusOK, http.StatusAccepted) + if resp == nil { + return nil, err + } + io.Copy(ioutil.Discard, resp.Response().Body) + resp.Response().Body.Close() + return &ServiceSetPropertiesResponse{rawResponse: resp.Response()}, err +} diff --git a/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zz_generated_validation.go b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zz_generated_validation.go new file mode 100644 index 0000000000..98a2614e60 --- /dev/null +++ b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zz_generated_validation.go @@ -0,0 +1,367 @@ +package azblob + +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "fmt" + "github.com/Azure/azure-pipeline-go/pipeline" + "reflect" + "regexp" + "strings" +) + +// Constraint stores constraint name, target field name +// Rule and chain validations. +type constraint struct { + // Target field name for validation. + target string + + // Constraint name e.g. minLength, MaxLength, Pattern, etc. + name string + + // Rule for constraint e.g. greater than 10, less than 5 etc. + rule interface{} + + // Chain validations for struct type + chain []constraint +} + +// Validation stores parameter-wise validation. +type validation struct { + targetValue interface{} + constraints []constraint +} + +// Constraint list +const ( + empty = "Empty" + null = "Null" + readOnly = "ReadOnly" + pattern = "Pattern" + maxLength = "MaxLength" + minLength = "MinLength" + maxItems = "MaxItems" + minItems = "MinItems" + multipleOf = "MultipleOf" + uniqueItems = "UniqueItems" + inclusiveMaximum = "InclusiveMaximum" + exclusiveMaximum = "ExclusiveMaximum" + exclusiveMinimum = "ExclusiveMinimum" + inclusiveMinimum = "InclusiveMinimum" +) + +// Validate method validates constraints on parameter +// passed in validation array. +func validate(m []validation) error { + for _, item := range m { + v := reflect.ValueOf(item.targetValue) + for _, constraint := range item.constraints { + var err error + switch v.Kind() { + case reflect.Ptr: + err = validatePtr(v, constraint) + case reflect.String: + err = validateString(v, constraint) + case reflect.Struct: + err = validateStruct(v, constraint) + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + err = validateInt(v, constraint) + case reflect.Float32, reflect.Float64: + err = validateFloat(v, constraint) + case reflect.Array, reflect.Slice, reflect.Map: + err = validateArrayMap(v, constraint) + default: + err = createError(v, constraint, fmt.Sprintf("unknown type %v", v.Kind())) + } + if err != nil { + return err + } + } + } + return nil +} + +func validateStruct(x reflect.Value, v constraint, name ...string) error { + //Get field name from target name which is in format a.b.c + s := strings.Split(v.target, ".") + f := x.FieldByName(s[len(s)-1]) + if isZero(f) { + return createError(x, v, fmt.Sprintf("field %q doesn't exist", v.target)) + } + err := validate([]validation{ + { + targetValue: getInterfaceValue(f), + constraints: []constraint{v}, + }, + }) + return err +} + +func validatePtr(x reflect.Value, v constraint) error { + if v.name == readOnly { + if !x.IsNil() { + return createError(x.Elem(), v, "readonly parameter; must send as nil or empty in request") + } + return nil + } + if x.IsNil() { + return checkNil(x, v) + } + if v.chain != nil { + return validate([]validation{ + { + targetValue: getInterfaceValue(x.Elem()), + constraints: v.chain, + }, + }) + } + return nil +} + +func validateInt(x reflect.Value, v constraint) error { + i := x.Int() + r, ok := v.rule.(int) + if !ok { + return createError(x, v, fmt.Sprintf("rule must be integer value for %v constraint; got: %v", v.name, v.rule)) + } + switch v.name { + case multipleOf: + if i%int64(r) != 0 { + return createError(x, v, fmt.Sprintf("value must be a multiple of %v", r)) + } + case exclusiveMinimum: + if i <= int64(r) { + return createError(x, v, fmt.Sprintf("value must be greater than %v", r)) + } + case exclusiveMaximum: + if i >= int64(r) { + return createError(x, v, fmt.Sprintf("value must be less than %v", r)) + } + case inclusiveMinimum: + if i < int64(r) { + return createError(x, v, fmt.Sprintf("value must be greater than or equal to %v", r)) + } + case inclusiveMaximum: + if i > int64(r) { + return createError(x, v, fmt.Sprintf("value must be less than or equal to %v", r)) + } + default: + return createError(x, v, fmt.Sprintf("constraint %v is not applicable for type integer", v.name)) + } + return nil +} + +func validateFloat(x reflect.Value, v constraint) error { + f := x.Float() + r, ok := v.rule.(float64) + if !ok { + return createError(x, v, fmt.Sprintf("rule must be float value for %v constraint; got: %v", v.name, v.rule)) + } + switch v.name { + case exclusiveMinimum: + if f <= r { + return createError(x, v, fmt.Sprintf("value must be greater than %v", r)) + } + case exclusiveMaximum: + if f >= r { + return createError(x, v, fmt.Sprintf("value must be less than %v", r)) + } + case inclusiveMinimum: + if f < r { + return createError(x, v, fmt.Sprintf("value must be greater than or equal to %v", r)) + } + case inclusiveMaximum: + if f > r { + return createError(x, v, fmt.Sprintf("value must be less than or equal to %v", r)) + } + default: + return createError(x, v, fmt.Sprintf("constraint %s is not applicable for type float", v.name)) + } + return nil +} + +func validateString(x reflect.Value, v constraint) error { + s := x.String() + switch v.name { + case empty: + if len(s) == 0 { + return checkEmpty(x, v) + } + case pattern: + reg, err := regexp.Compile(v.rule.(string)) + if err != nil { + return createError(x, v, err.Error()) + } + if !reg.MatchString(s) { + return createError(x, v, fmt.Sprintf("value doesn't match pattern %v", v.rule)) + } + case maxLength: + if _, ok := v.rule.(int); !ok { + return createError(x, v, fmt.Sprintf("rule must be integer value for %v constraint; got: %v", v.name, v.rule)) + } + if len(s) > v.rule.(int) { + return createError(x, v, fmt.Sprintf("value length must be less than %v", v.rule)) + } + case minLength: + if _, ok := v.rule.(int); !ok { + return createError(x, v, fmt.Sprintf("rule must be integer value for %v constraint; got: %v", v.name, v.rule)) + } + if len(s) < v.rule.(int) { + return createError(x, v, fmt.Sprintf("value length must be greater than %v", v.rule)) + } + case readOnly: + if len(s) > 0 { + return createError(reflect.ValueOf(s), v, "readonly parameter; must send as nil or empty in request") + } + default: + return createError(x, v, fmt.Sprintf("constraint %s is not applicable to string type", v.name)) + } + if v.chain != nil { + return validate([]validation{ + { + targetValue: getInterfaceValue(x), + constraints: v.chain, + }, + }) + } + return nil +} + +func validateArrayMap(x reflect.Value, v constraint) error { + switch v.name { + case null: + if x.IsNil() { + return checkNil(x, v) + } + case empty: + if x.IsNil() || x.Len() == 0 { + return checkEmpty(x, v) + } + case maxItems: + if _, ok := v.rule.(int); !ok { + return createError(x, v, fmt.Sprintf("rule must be integer for %v constraint; got: %v", v.name, v.rule)) + } + if x.Len() > v.rule.(int) { + return createError(x, v, fmt.Sprintf("maximum item limit is %v; got: %v", v.rule, x.Len())) + } + case minItems: + if _, ok := v.rule.(int); !ok { + return createError(x, v, fmt.Sprintf("rule must be integer for %v constraint; got: %v", v.name, v.rule)) + } + if x.Len() < v.rule.(int) { + return createError(x, v, fmt.Sprintf("minimum item limit is %v; got: %v", v.rule, x.Len())) + } + case uniqueItems: + if x.Kind() == reflect.Array || x.Kind() == reflect.Slice { + if !checkForUniqueInArray(x) { + return createError(x, v, fmt.Sprintf("all items in parameter %q must be unique; got:%v", v.target, x)) + } + } else if x.Kind() == reflect.Map { + if !checkForUniqueInMap(x) { + return createError(x, v, fmt.Sprintf("all items in parameter %q must be unique; got:%v", v.target, x)) + } + } else { + return createError(x, v, fmt.Sprintf("type must be array, slice or map for constraint %v; got: %v", v.name, x.Kind())) + } + case readOnly: + if x.Len() != 0 { + return createError(x, v, "readonly parameter; must send as nil or empty in request") + } + case pattern: + reg, err := regexp.Compile(v.rule.(string)) + if err != nil { + return createError(x, v, err.Error()) + } + keys := x.MapKeys() + for _, k := range keys { + if !reg.MatchString(k.String()) { + return createError(k, v, fmt.Sprintf("map key doesn't match pattern %v", v.rule)) + } + } + default: + return createError(x, v, fmt.Sprintf("constraint %v is not applicable to array, slice and map type", v.name)) + } + if v.chain != nil { + return validate([]validation{ + { + targetValue: getInterfaceValue(x), + constraints: v.chain, + }, + }) + } + return nil +} + +func checkNil(x reflect.Value, v constraint) error { + if _, ok := v.rule.(bool); !ok { + return createError(x, v, fmt.Sprintf("rule must be bool value for %v constraint; got: %v", v.name, v.rule)) + } + if v.rule.(bool) { + return createError(x, v, "value can not be null; required parameter") + } + return nil +} + +func checkEmpty(x reflect.Value, v constraint) error { + if _, ok := v.rule.(bool); !ok { + return createError(x, v, fmt.Sprintf("rule must be bool value for %v constraint; got: %v", v.name, v.rule)) + } + if v.rule.(bool) { + return createError(x, v, "value can not be null or empty; required parameter") + } + return nil +} + +func checkForUniqueInArray(x reflect.Value) bool { + if x == reflect.Zero(reflect.TypeOf(x)) || x.Len() == 0 { + return false + } + arrOfInterface := make([]interface{}, x.Len()) + for i := 0; i < x.Len(); i++ { + arrOfInterface[i] = x.Index(i).Interface() + } + m := make(map[interface{}]bool) + for _, val := range arrOfInterface { + if m[val] { + return false + } + m[val] = true + } + return true +} + +func checkForUniqueInMap(x reflect.Value) bool { + if x == reflect.Zero(reflect.TypeOf(x)) || x.Len() == 0 { + return false + } + mapOfInterface := make(map[interface{}]interface{}, x.Len()) + keys := x.MapKeys() + for _, k := range keys { + mapOfInterface[k.Interface()] = x.MapIndex(k).Interface() + } + m := make(map[interface{}]bool) + for _, val := range mapOfInterface { + if m[val] { + return false + } + m[val] = true + } + return true +} + +func getInterfaceValue(x reflect.Value) interface{} { + if x.Kind() == reflect.Invalid { + return nil + } + return x.Interface() +} + +func isZero(x interface{}) bool { + return x == reflect.Zero(reflect.TypeOf(x)).Interface() +} + +func createError(x reflect.Value, v constraint, message string) error { + return pipeline.NewError(nil, fmt.Sprintf("validation failed: parameter=%s constraint=%s value=%#v details: %s", + v.target, v.name, getInterfaceValue(x), message)) +} diff --git a/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zz_generated_version.go b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zz_generated_version.go new file mode 100644 index 0000000000..760271a421 --- /dev/null +++ b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zz_generated_version.go @@ -0,0 +1,14 @@ +package azblob + +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +// UserAgent returns the UserAgent string to use when sending http.Requests. +func UserAgent() string { + return "Azure-SDK-For-Go/0.0.0 azblob/2018-03-28" +} + +// Version returns the semantic version (see http://semver.org) of the client. +func Version() string { + return "0.0.0" +} diff --git a/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zz_response_helpers.go b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zz_response_helpers.go new file mode 100644 index 0000000000..b4f058b674 --- /dev/null +++ b/vendor/github.com/Azure/azure-storage-blob-go/2018-03-28/azblob/zz_response_helpers.go @@ -0,0 +1,242 @@ +package azblob + +import ( + "context" + "io" + "net/http" + "time" +) + +// BlobHTTPHeaders contains read/writeable blob properties. +type BlobHTTPHeaders struct { + ContentType string + ContentMD5 []byte + ContentEncoding string + ContentLanguage string + ContentDisposition string + CacheControl string +} + +// NewHTTPHeaders returns the user-modifiable properties for this blob. +func (bgpr BlobGetPropertiesResponse) NewHTTPHeaders() BlobHTTPHeaders { + return BlobHTTPHeaders{ + ContentType: bgpr.ContentType(), + ContentEncoding: bgpr.ContentEncoding(), + ContentLanguage: bgpr.ContentLanguage(), + ContentDisposition: bgpr.ContentDisposition(), + CacheControl: bgpr.CacheControl(), + ContentMD5: bgpr.ContentMD5(), + } +} + +/////////////////////////////////////////////////////////////////////////////// + +// NewHTTPHeaders returns the user-modifiable properties for this blob. +func (dr downloadResponse) NewHTTPHeaders() BlobHTTPHeaders { + return BlobHTTPHeaders{ + ContentType: dr.ContentType(), + ContentEncoding: dr.ContentEncoding(), + ContentLanguage: dr.ContentLanguage(), + ContentDisposition: dr.ContentDisposition(), + CacheControl: dr.CacheControl(), + ContentMD5: dr.ContentMD5(), + } +} + +/////////////////////////////////////////////////////////////////////////////// + +// DownloadResponse wraps AutoRest generated downloadResponse and helps to provide info for retry. +type DownloadResponse struct { + r *downloadResponse + ctx context.Context + b BlobURL + getInfo HTTPGetterInfo +} + +// Body constructs new RetryReader stream for reading data. If a connection failes +// while reading, it will make additional requests to reestablish a connection and +// continue reading. Specifying a RetryReaderOption's with MaxRetryRequests set to 0 +// (the default), returns the original response body and no retries will be performed. +func (r *DownloadResponse) Body(o RetryReaderOptions) io.ReadCloser { + if o.MaxRetryRequests == 0 { // No additional retries + return r.Response().Body + } + return NewRetryReader(r.ctx, r.Response(), r.getInfo, o, + func(ctx context.Context, getInfo HTTPGetterInfo) (*http.Response, error) { + resp, err := r.b.Download(ctx, getInfo.Offset, getInfo.Count, + BlobAccessConditions{ + HTTPAccessConditions: HTTPAccessConditions{IfMatch: getInfo.ETag}, + }, + false) + if err != nil { + return nil, err + } + return resp.Response(), err + }, + ) +} + +// Response returns the raw HTTP response object. +func (r DownloadResponse) Response() *http.Response { + return r.r.Response() +} + +// NewHTTPHeaders returns the user-modifiable properties for this blob. +func (r DownloadResponse) NewHTTPHeaders() BlobHTTPHeaders { + return r.r.NewHTTPHeaders() +} + +// BlobContentMD5 returns the value for header x-ms-blob-content-md5. +func (r DownloadResponse) BlobContentMD5() []byte { + return r.r.BlobContentMD5() +} + +// ContentMD5 returns the value for header Content-MD5. +func (r DownloadResponse) ContentMD5() []byte { + return r.r.ContentMD5() +} + +// StatusCode returns the HTTP status code of the response, e.g. 200. +func (r DownloadResponse) StatusCode() int { + return r.r.StatusCode() +} + +// Status returns the HTTP status message of the response, e.g. "200 OK". +func (r DownloadResponse) Status() string { + return r.r.Status() +} + +// AcceptRanges returns the value for header Accept-Ranges. +func (r DownloadResponse) AcceptRanges() string { + return r.r.AcceptRanges() +} + +// BlobCommittedBlockCount returns the value for header x-ms-blob-committed-block-count. +func (r DownloadResponse) BlobCommittedBlockCount() int32 { + return r.r.BlobCommittedBlockCount() +} + +// BlobSequenceNumber returns the value for header x-ms-blob-sequence-number. +func (r DownloadResponse) BlobSequenceNumber() int64 { + return r.r.BlobSequenceNumber() +} + +// BlobType returns the value for header x-ms-blob-type. +func (r DownloadResponse) BlobType() BlobType { + return r.r.BlobType() +} + +// CacheControl returns the value for header Cache-Control. +func (r DownloadResponse) CacheControl() string { + return r.r.CacheControl() +} + +// ContentDisposition returns the value for header Content-Disposition. +func (r DownloadResponse) ContentDisposition() string { + return r.r.ContentDisposition() +} + +// ContentEncoding returns the value for header Content-Encoding. +func (r DownloadResponse) ContentEncoding() string { + return r.r.ContentEncoding() +} + +// ContentLanguage returns the value for header Content-Language. +func (r DownloadResponse) ContentLanguage() string { + return r.r.ContentLanguage() +} + +// ContentLength returns the value for header Content-Length. +func (r DownloadResponse) ContentLength() int64 { + return r.r.ContentLength() +} + +// ContentRange returns the value for header Content-Range. +func (r DownloadResponse) ContentRange() string { + return r.r.ContentRange() +} + +// ContentType returns the value for header Content-Type. +func (r DownloadResponse) ContentType() string { + return r.r.ContentType() +} + +// CopyCompletionTime returns the value for header x-ms-copy-completion-time. +func (r DownloadResponse) CopyCompletionTime() time.Time { + return r.r.CopyCompletionTime() +} + +// CopyID returns the value for header x-ms-copy-id. +func (r DownloadResponse) CopyID() string { + return r.r.CopyID() +} + +// CopyProgress returns the value for header x-ms-copy-progress. +func (r DownloadResponse) CopyProgress() string { + return r.r.CopyProgress() +} + +// CopySource returns the value for header x-ms-copy-source. +func (r DownloadResponse) CopySource() string { + return r.r.CopySource() +} + +// CopyStatus returns the value for header x-ms-copy-status. +func (r DownloadResponse) CopyStatus() CopyStatusType { + return r.r.CopyStatus() +} + +// CopyStatusDescription returns the value for header x-ms-copy-status-description. +func (r DownloadResponse) CopyStatusDescription() string { + return r.r.CopyStatusDescription() +} + +// Date returns the value for header Date. +func (r DownloadResponse) Date() time.Time { + return r.r.Date() +} + +// ETag returns the value for header ETag. +func (r DownloadResponse) ETag() ETag { + return r.r.ETag() +} + +// IsServerEncrypted returns the value for header x-ms-server-encrypted. +func (r DownloadResponse) IsServerEncrypted() string { + return r.r.IsServerEncrypted() +} + +// LastModified returns the value for header Last-Modified. +func (r DownloadResponse) LastModified() time.Time { + return r.r.LastModified() +} + +// LeaseDuration returns the value for header x-ms-lease-duration. +func (r DownloadResponse) LeaseDuration() LeaseDurationType { + return r.r.LeaseDuration() +} + +// LeaseState returns the value for header x-ms-lease-state. +func (r DownloadResponse) LeaseState() LeaseStateType { + return r.r.LeaseState() +} + +// LeaseStatus returns the value for header x-ms-lease-status. +func (r DownloadResponse) LeaseStatus() LeaseStatusType { + return r.r.LeaseStatus() +} + +// RequestID returns the value for header x-ms-request-id. +func (r DownloadResponse) RequestID() string { + return r.r.RequestID() +} + +// Version returns the value for header x-ms-version. +func (r DownloadResponse) Version() string { + return r.r.Version() +} + +// NewMetadata returns user-defined key/value pairs. +func (r DownloadResponse) NewMetadata() Metadata { + return r.r.NewMetadata() +} diff --git a/vendor/github.com/Azure/azure-storage-blob-go/LICENSE b/vendor/github.com/Azure/azure-storage-blob-go/LICENSE new file mode 100644 index 0000000000..d1ca00f20a --- /dev/null +++ b/vendor/github.com/Azure/azure-storage-blob-go/LICENSE @@ -0,0 +1,21 @@ + MIT License + + Copyright (c) Microsoft Corporation. All rights reserved. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE \ No newline at end of file diff --git a/vendor/github.com/Azure/azure-storage-go/README.md b/vendor/github.com/Azure/azure-storage-go/README.md deleted file mode 100644 index f4af7bf399..0000000000 --- a/vendor/github.com/Azure/azure-storage-go/README.md +++ /dev/null @@ -1,10 +0,0 @@ -# Azure Storage SDK for Go -[![GoDoc](https://godoc.org/github.com/Azure/azure-storage-go?status.svg)](https://godoc.org/github.com/Azure/azure-storage-go) [![Build Status](https://travis-ci.org/Azure/azure-storage-go.svg?branch=master)](https://travis-ci.org/Azure/azure-storage-go) [![Go Report Card](https://goreportcard.com/badge/github.com/Azure/azure-storage-go)](https://goreportcard.com/report/github.com/Azure/azure-storage-go) - -The `github.com/Azure/azure-sdk-for-go/storage` package is used to perform operations in Azure Storage Service. To manage your storage accounts (Azure Resource Manager / ARM), use the [github.com/Azure/azure-sdk-for-go/arm/storage](../arm/storage) package. For your classic storage accounts (Azure Service Management / ASM), use [github.com/Azure/azure-sdk-for-go/management/storageservice](../management/storageservice) package. - -This package includes support for [Azure Storage Emulator](https://azure.microsoft.com/documentation/articles/storage-use-emulator/) - -# Contributing - -This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. diff --git a/vendor/github.com/Azure/azure-storage-go/authorization.go b/vendor/github.com/Azure/azure-storage-go/authorization.go deleted file mode 100644 index 89a0d0b3cd..0000000000 --- a/vendor/github.com/Azure/azure-storage-go/authorization.go +++ /dev/null @@ -1,223 +0,0 @@ -// Package storage provides clients for Microsoft Azure Storage Services. -package storage - -import ( - "bytes" - "fmt" - "net/url" - "sort" - "strings" -) - -// See: https://docs.microsoft.com/rest/api/storageservices/fileservices/authentication-for-the-azure-storage-services - -type authentication string - -const ( - sharedKey authentication = "sharedKey" - sharedKeyForTable authentication = "sharedKeyTable" - sharedKeyLite authentication = "sharedKeyLite" - sharedKeyLiteForTable authentication = "sharedKeyLiteTable" - - // headers - headerAuthorization = "Authorization" - headerContentLength = "Content-Length" - headerDate = "Date" - headerXmsDate = "x-ms-date" - headerXmsVersion = "x-ms-version" - headerContentEncoding = "Content-Encoding" - headerContentLanguage = "Content-Language" - headerContentType = "Content-Type" - headerContentMD5 = "Content-MD5" - headerIfModifiedSince = "If-Modified-Since" - headerIfMatch = "If-Match" - headerIfNoneMatch = "If-None-Match" - headerIfUnmodifiedSince = "If-Unmodified-Since" - headerRange = "Range" -) - -func (c *Client) addAuthorizationHeader(verb, url string, headers map[string]string, auth authentication) (map[string]string, error) { - authHeader, err := c.getSharedKey(verb, url, headers, auth) - if err != nil { - return nil, err - } - headers[headerAuthorization] = authHeader - return headers, nil -} - -func (c *Client) getSharedKey(verb, url string, headers map[string]string, auth authentication) (string, error) { - canRes, err := c.buildCanonicalizedResource(url, auth) - if err != nil { - return "", err - } - - canString, err := buildCanonicalizedString(verb, headers, canRes, auth) - if err != nil { - return "", err - } - return c.createAuthorizationHeader(canString, auth), nil -} - -func (c *Client) buildCanonicalizedResource(uri string, auth authentication) (string, error) { - errMsg := "buildCanonicalizedResource error: %s" - u, err := url.Parse(uri) - if err != nil { - return "", fmt.Errorf(errMsg, err.Error()) - } - - cr := bytes.NewBufferString("/") - cr.WriteString(c.getCanonicalizedAccountName()) - - if len(u.Path) > 0 { - // Any portion of the CanonicalizedResource string that is derived from - // the resource's URI should be encoded exactly as it is in the URI. - // -- https://msdn.microsoft.com/en-gb/library/azure/dd179428.aspx - cr.WriteString(u.EscapedPath()) - } - - params, err := url.ParseQuery(u.RawQuery) - if err != nil { - return "", fmt.Errorf(errMsg, err.Error()) - } - - // See https://github.com/Azure/azure-storage-net/blob/master/Lib/Common/Core/Util/AuthenticationUtility.cs#L277 - if auth == sharedKey { - if len(params) > 0 { - cr.WriteString("\n") - - keys := []string{} - for key := range params { - keys = append(keys, key) - } - sort.Strings(keys) - - completeParams := []string{} - for _, key := range keys { - if len(params[key]) > 1 { - sort.Strings(params[key]) - } - - completeParams = append(completeParams, fmt.Sprintf("%s:%s", key, strings.Join(params[key], ","))) - } - cr.WriteString(strings.Join(completeParams, "\n")) - } - } else { - // search for "comp" parameter, if exists then add it to canonicalizedresource - if v, ok := params["comp"]; ok { - cr.WriteString("?comp=" + v[0]) - } - } - - return string(cr.Bytes()), nil -} - -func (c *Client) getCanonicalizedAccountName() string { - // since we may be trying to access a secondary storage account, we need to - // remove the -secondary part of the storage name - return strings.TrimSuffix(c.accountName, "-secondary") -} - -func buildCanonicalizedString(verb string, headers map[string]string, canonicalizedResource string, auth authentication) (string, error) { - contentLength := headers[headerContentLength] - if contentLength == "0" { - contentLength = "" - } - date := headers[headerDate] - if v, ok := headers[headerXmsDate]; ok { - if auth == sharedKey || auth == sharedKeyLite { - date = "" - } else { - date = v - } - } - var canString string - switch auth { - case sharedKey: - canString = strings.Join([]string{ - verb, - headers[headerContentEncoding], - headers[headerContentLanguage], - contentLength, - headers[headerContentMD5], - headers[headerContentType], - date, - headers[headerIfModifiedSince], - headers[headerIfMatch], - headers[headerIfNoneMatch], - headers[headerIfUnmodifiedSince], - headers[headerRange], - buildCanonicalizedHeader(headers), - canonicalizedResource, - }, "\n") - case sharedKeyForTable: - canString = strings.Join([]string{ - verb, - headers[headerContentMD5], - headers[headerContentType], - date, - canonicalizedResource, - }, "\n") - case sharedKeyLite: - canString = strings.Join([]string{ - verb, - headers[headerContentMD5], - headers[headerContentType], - date, - buildCanonicalizedHeader(headers), - canonicalizedResource, - }, "\n") - case sharedKeyLiteForTable: - canString = strings.Join([]string{ - date, - canonicalizedResource, - }, "\n") - default: - return "", fmt.Errorf("%s authentication is not supported yet", auth) - } - return canString, nil -} - -func buildCanonicalizedHeader(headers map[string]string) string { - cm := make(map[string]string) - - for k, v := range headers { - headerName := strings.TrimSpace(strings.ToLower(k)) - if strings.HasPrefix(headerName, "x-ms-") { - cm[headerName] = v - } - } - - if len(cm) == 0 { - return "" - } - - keys := []string{} - for key := range cm { - keys = append(keys, key) - } - - sort.Strings(keys) - - ch := bytes.NewBufferString("") - - for _, key := range keys { - ch.WriteString(key) - ch.WriteRune(':') - ch.WriteString(cm[key]) - ch.WriteRune('\n') - } - - return strings.TrimSuffix(string(ch.Bytes()), "\n") -} - -func (c *Client) createAuthorizationHeader(canonicalizedString string, auth authentication) string { - signature := c.computeHmac256(canonicalizedString) - var key string - switch auth { - case sharedKey, sharedKeyForTable: - key = "SharedKey" - case sharedKeyLite, sharedKeyLiteForTable: - key = "SharedKeyLite" - } - return fmt.Sprintf("%s %s:%s", key, c.getCanonicalizedAccountName(), signature) -} diff --git a/vendor/github.com/Azure/azure-storage-go/blob.go b/vendor/github.com/Azure/azure-storage-go/blob.go deleted file mode 100644 index 636efc662d..0000000000 --- a/vendor/github.com/Azure/azure-storage-go/blob.go +++ /dev/null @@ -1,1130 +0,0 @@ -package storage - -import ( - "bytes" - "encoding/xml" - "errors" - "fmt" - "io" - "net/http" - "net/url" - "strconv" - "strings" - "time" -) - -// A Blob is an entry in BlobListResponse. -type Blob struct { - Name string `xml:"Name"` - Properties BlobProperties `xml:"Properties"` - Metadata BlobMetadata `xml:"Metadata"` -} - -// BlobMetadata is a set of custom name/value pairs. -// -// See https://msdn.microsoft.com/en-us/library/azure/dd179404.aspx -type BlobMetadata map[string]string - -type blobMetadataEntries struct { - Entries []blobMetadataEntry `xml:",any"` -} -type blobMetadataEntry struct { - XMLName xml.Name - Value string `xml:",chardata"` -} - -// UnmarshalXML converts the xml:Metadata into Metadata map -func (bm *BlobMetadata) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { - var entries blobMetadataEntries - if err := d.DecodeElement(&entries, &start); err != nil { - return err - } - for _, entry := range entries.Entries { - if *bm == nil { - *bm = make(BlobMetadata) - } - (*bm)[strings.ToLower(entry.XMLName.Local)] = entry.Value - } - return nil -} - -// MarshalXML implements the xml.Marshaler interface. It encodes -// metadata name/value pairs as they would appear in an Azure -// ListBlobs response. -func (bm BlobMetadata) MarshalXML(enc *xml.Encoder, start xml.StartElement) error { - entries := make([]blobMetadataEntry, 0, len(bm)) - for k, v := range bm { - entries = append(entries, blobMetadataEntry{ - XMLName: xml.Name{Local: http.CanonicalHeaderKey(k)}, - Value: v, - }) - } - return enc.EncodeElement(blobMetadataEntries{ - Entries: entries, - }, start) -} - -// BlobProperties contains various properties of a blob -// returned in various endpoints like ListBlobs or GetBlobProperties. -type BlobProperties struct { - LastModified string `xml:"Last-Modified"` - Etag string `xml:"Etag"` - ContentMD5 string `xml:"Content-MD5"` - ContentLength int64 `xml:"Content-Length"` - ContentType string `xml:"Content-Type"` - ContentEncoding string `xml:"Content-Encoding"` - CacheControl string `xml:"Cache-Control"` - ContentLanguage string `xml:"Cache-Language"` - BlobType BlobType `xml:"x-ms-blob-blob-type"` - SequenceNumber int64 `xml:"x-ms-blob-sequence-number"` - CopyID string `xml:"CopyId"` - CopyStatus string `xml:"CopyStatus"` - CopySource string `xml:"CopySource"` - CopyProgress string `xml:"CopyProgress"` - CopyCompletionTime string `xml:"CopyCompletionTime"` - CopyStatusDescription string `xml:"CopyStatusDescription"` - LeaseStatus string `xml:"LeaseStatus"` - LeaseState string `xml:"LeaseState"` -} - -// BlobHeaders contains various properties of a blob and is an entry -// in SetBlobProperties -type BlobHeaders struct { - ContentMD5 string `header:"x-ms-blob-content-md5"` - ContentLanguage string `header:"x-ms-blob-content-language"` - ContentEncoding string `header:"x-ms-blob-content-encoding"` - ContentType string `header:"x-ms-blob-content-type"` - CacheControl string `header:"x-ms-blob-cache-control"` -} - -// BlobType defines the type of the Azure Blob. -type BlobType string - -// Types of page blobs -const ( - BlobTypeBlock BlobType = "BlockBlob" - BlobTypePage BlobType = "PageBlob" - BlobTypeAppend BlobType = "AppendBlob" -) - -// PageWriteType defines the type updates that are going to be -// done on the page blob. -type PageWriteType string - -// Types of operations on page blobs -const ( - PageWriteTypeUpdate PageWriteType = "update" - PageWriteTypeClear PageWriteType = "clear" -) - -const ( - blobCopyStatusPending = "pending" - blobCopyStatusSuccess = "success" - blobCopyStatusAborted = "aborted" - blobCopyStatusFailed = "failed" -) - -// lease constants. -const ( - leaseHeaderPrefix = "x-ms-lease-" - headerLeaseID = "x-ms-lease-id" - leaseAction = "x-ms-lease-action" - leaseBreakPeriod = "x-ms-lease-break-period" - leaseDuration = "x-ms-lease-duration" - leaseProposedID = "x-ms-proposed-lease-id" - leaseTime = "x-ms-lease-time" - - acquireLease = "acquire" - renewLease = "renew" - changeLease = "change" - releaseLease = "release" - breakLease = "break" -) - -// BlockListType is used to filter out types of blocks in a Get Blocks List call -// for a block blob. -// -// See https://msdn.microsoft.com/en-us/library/azure/dd179400.aspx for all -// block types. -type BlockListType string - -// Filters for listing blocks in block blobs -const ( - BlockListTypeAll BlockListType = "all" - BlockListTypeCommitted BlockListType = "committed" - BlockListTypeUncommitted BlockListType = "uncommitted" -) - -// Maximum sizes (per REST API) for various concepts -const ( - MaxBlobBlockSize = 100 * 1024 * 1024 - MaxBlobPageSize = 4 * 1024 * 1024 -) - -// BlockStatus defines states a block for a block blob can -// be in. -type BlockStatus string - -// List of statuses that can be used to refer to a block in a block list -const ( - BlockStatusUncommitted BlockStatus = "Uncommitted" - BlockStatusCommitted BlockStatus = "Committed" - BlockStatusLatest BlockStatus = "Latest" -) - -// Block is used to create Block entities for Put Block List -// call. -type Block struct { - ID string - Status BlockStatus -} - -// BlockListResponse contains the response fields from Get Block List call. -// -// See https://msdn.microsoft.com/en-us/library/azure/dd179400.aspx -type BlockListResponse struct { - XMLName xml.Name `xml:"BlockList"` - CommittedBlocks []BlockResponse `xml:"CommittedBlocks>Block"` - UncommittedBlocks []BlockResponse `xml:"UncommittedBlocks>Block"` -} - -// BlockResponse contains the block information returned -// in the GetBlockListCall. -type BlockResponse struct { - Name string `xml:"Name"` - Size int64 `xml:"Size"` -} - -// GetPageRangesResponse contains the response fields from -// Get Page Ranges call. -// -// See https://msdn.microsoft.com/en-us/library/azure/ee691973.aspx -type GetPageRangesResponse struct { - XMLName xml.Name `xml:"PageList"` - PageList []PageRange `xml:"PageRange"` -} - -// PageRange contains information about a page of a page blob from -// Get Pages Range call. -// -// See https://msdn.microsoft.com/en-us/library/azure/ee691973.aspx -type PageRange struct { - Start int64 `xml:"Start"` - End int64 `xml:"End"` -} - -var ( - errBlobCopyAborted = errors.New("storage: blob copy is aborted") - errBlobCopyIDMismatch = errors.New("storage: blob copy id is a mismatch") -) - -// BlobExists returns true if a blob with given name exists on the specified -// container of the storage account. -func (b BlobStorageClient) BlobExists(container, name string) (bool, error) { - uri := b.client.getEndpoint(blobServiceName, pathForBlob(container, name), url.Values{}) - headers := b.client.getStandardHeaders() - resp, err := b.client.exec(http.MethodHead, uri, headers, nil, b.auth) - if resp != nil { - defer readAndCloseBody(resp.body) - if resp.statusCode == http.StatusOK || resp.statusCode == http.StatusNotFound { - return resp.statusCode == http.StatusOK, nil - } - } - return false, err -} - -// GetBlobURL gets the canonical URL to the blob with the specified name in the -// specified container. If name is not specified, the canonical URL for the entire -// container is obtained. -// This method does not create a publicly accessible URL if the blob or container -// is private and this method does not check if the blob exists. -func (b BlobStorageClient) GetBlobURL(container, name string) string { - if container == "" { - container = "$root" - } - return b.client.getEndpoint(blobServiceName, pathForResource(container, name), url.Values{}) -} - -// GetBlob returns a stream to read the blob. Caller must call Close() the -// reader to close on the underlying connection. -// -// See https://msdn.microsoft.com/en-us/library/azure/dd179440.aspx -func (b BlobStorageClient) GetBlob(container, name string) (io.ReadCloser, error) { - resp, err := b.getBlobRange(container, name, "", nil) - if err != nil { - return nil, err - } - - if err := checkRespCode(resp.statusCode, []int{http.StatusOK}); err != nil { - return nil, err - } - return resp.body, nil -} - -// GetBlobRange reads the specified range of a blob to a stream. The bytesRange -// string must be in a format like "0-", "10-100" as defined in HTTP 1.1 spec. -// -// See https://msdn.microsoft.com/en-us/library/azure/dd179440.aspx -func (b BlobStorageClient) GetBlobRange(container, name, bytesRange string, extraHeaders map[string]string) (io.ReadCloser, error) { - resp, err := b.getBlobRange(container, name, bytesRange, extraHeaders) - if err != nil { - return nil, err - } - - if err := checkRespCode(resp.statusCode, []int{http.StatusPartialContent}); err != nil { - return nil, err - } - return resp.body, nil -} - -func (b BlobStorageClient) getBlobRange(container, name, bytesRange string, extraHeaders map[string]string) (*storageResponse, error) { - uri := b.client.getEndpoint(blobServiceName, pathForBlob(container, name), url.Values{}) - - extraHeaders = b.client.protectUserAgent(extraHeaders) - headers := b.client.getStandardHeaders() - if bytesRange != "" { - headers["Range"] = fmt.Sprintf("bytes=%s", bytesRange) - } - - for k, v := range extraHeaders { - headers[k] = v - } - - resp, err := b.client.exec(http.MethodGet, uri, headers, nil, b.auth) - if err != nil { - return nil, err - } - return resp, err -} - -// leasePut is common PUT code for the various acquire/release/break etc functions. -func (b BlobStorageClient) leaseCommonPut(container string, name string, headers map[string]string, expectedStatus int) (http.Header, error) { - params := url.Values{"comp": {"lease"}} - uri := b.client.getEndpoint(blobServiceName, pathForBlob(container, name), params) - - resp, err := b.client.exec(http.MethodPut, uri, headers, nil, b.auth) - if err != nil { - return nil, err - } - defer readAndCloseBody(resp.body) - - if err := checkRespCode(resp.statusCode, []int{expectedStatus}); err != nil { - return nil, err - } - - return resp.headers, nil -} - -// SnapshotBlob creates a snapshot for a blob as per https://msdn.microsoft.com/en-us/library/azure/ee691971.aspx -func (b BlobStorageClient) SnapshotBlob(container string, name string, timeout int, extraHeaders map[string]string) (snapshotTimestamp *time.Time, err error) { - extraHeaders = b.client.protectUserAgent(extraHeaders) - headers := b.client.getStandardHeaders() - params := url.Values{"comp": {"snapshot"}} - - if timeout > 0 { - params.Add("timeout", strconv.Itoa(timeout)) - } - - for k, v := range extraHeaders { - headers[k] = v - } - - uri := b.client.getEndpoint(blobServiceName, pathForBlob(container, name), params) - resp, err := b.client.exec(http.MethodPut, uri, headers, nil, b.auth) - if err != nil || resp == nil { - return nil, err - } - - defer readAndCloseBody(resp.body) - - if err := checkRespCode(resp.statusCode, []int{http.StatusCreated}); err != nil { - return nil, err - } - - snapshotResponse := resp.headers.Get(http.CanonicalHeaderKey("x-ms-snapshot")) - if snapshotResponse != "" { - snapshotTimestamp, err := time.Parse(time.RFC3339, snapshotResponse) - if err != nil { - return nil, err - } - - return &snapshotTimestamp, nil - } - - return nil, errors.New("Snapshot not created") -} - -// AcquireLease creates a lease for a blob as per https://msdn.microsoft.com/en-us/library/azure/ee691972.aspx -// returns leaseID acquired -// In API Versions starting on 2012-02-12, the minimum leaseTimeInSeconds is 15, the maximum -// non-infinite leaseTimeInSeconds is 60. To specify an infinite lease, provide the value -1. -func (b BlobStorageClient) AcquireLease(container string, name string, leaseTimeInSeconds int, proposedLeaseID string) (returnedLeaseID string, err error) { - headers := b.client.getStandardHeaders() - headers[leaseAction] = acquireLease - - if leaseTimeInSeconds == -1 { - // Do nothing, but don't trigger the following clauses. - } else if leaseTimeInSeconds > 60 || b.client.apiVersion < "2012-02-12" { - leaseTimeInSeconds = 60 - } else if leaseTimeInSeconds < 15 { - leaseTimeInSeconds = 15 - } - - headers[leaseDuration] = strconv.Itoa(leaseTimeInSeconds) - - if proposedLeaseID != "" { - headers[leaseProposedID] = proposedLeaseID - } - - respHeaders, err := b.leaseCommonPut(container, name, headers, http.StatusCreated) - if err != nil { - return "", err - } - - returnedLeaseID = respHeaders.Get(http.CanonicalHeaderKey(headerLeaseID)) - - if returnedLeaseID != "" { - return returnedLeaseID, nil - } - - return "", errors.New("LeaseID not returned") -} - -// BreakLease breaks the lease for a blob as per https://msdn.microsoft.com/en-us/library/azure/ee691972.aspx -// Returns the timeout remaining in the lease in seconds -func (b BlobStorageClient) BreakLease(container string, name string) (breakTimeout int, err error) { - headers := b.client.getStandardHeaders() - headers[leaseAction] = breakLease - return b.breakLeaseCommon(container, name, headers) -} - -// BreakLeaseWithBreakPeriod breaks the lease for a blob as per https://msdn.microsoft.com/en-us/library/azure/ee691972.aspx -// breakPeriodInSeconds is used to determine how long until new lease can be created. -// Returns the timeout remaining in the lease in seconds -func (b BlobStorageClient) BreakLeaseWithBreakPeriod(container string, name string, breakPeriodInSeconds int) (breakTimeout int, err error) { - headers := b.client.getStandardHeaders() - headers[leaseAction] = breakLease - headers[leaseBreakPeriod] = strconv.Itoa(breakPeriodInSeconds) - return b.breakLeaseCommon(container, name, headers) -} - -// breakLeaseCommon is common code for both version of BreakLease (with and without break period) -func (b BlobStorageClient) breakLeaseCommon(container string, name string, headers map[string]string) (breakTimeout int, err error) { - - respHeaders, err := b.leaseCommonPut(container, name, headers, http.StatusAccepted) - if err != nil { - return 0, err - } - - breakTimeoutStr := respHeaders.Get(http.CanonicalHeaderKey(leaseTime)) - if breakTimeoutStr != "" { - breakTimeout, err = strconv.Atoi(breakTimeoutStr) - if err != nil { - return 0, err - } - } - - return breakTimeout, nil -} - -// ChangeLease changes a lease ID for a blob as per https://msdn.microsoft.com/en-us/library/azure/ee691972.aspx -// Returns the new LeaseID acquired -func (b BlobStorageClient) ChangeLease(container string, name string, currentLeaseID string, proposedLeaseID string) (newLeaseID string, err error) { - headers := b.client.getStandardHeaders() - headers[leaseAction] = changeLease - headers[headerLeaseID] = currentLeaseID - headers[leaseProposedID] = proposedLeaseID - - respHeaders, err := b.leaseCommonPut(container, name, headers, http.StatusOK) - if err != nil { - return "", err - } - - newLeaseID = respHeaders.Get(http.CanonicalHeaderKey(headerLeaseID)) - if newLeaseID != "" { - return newLeaseID, nil - } - - return "", errors.New("LeaseID not returned") -} - -// ReleaseLease releases the lease for a blob as per https://msdn.microsoft.com/en-us/library/azure/ee691972.aspx -func (b BlobStorageClient) ReleaseLease(container string, name string, currentLeaseID string) error { - headers := b.client.getStandardHeaders() - headers[leaseAction] = releaseLease - headers[headerLeaseID] = currentLeaseID - - _, err := b.leaseCommonPut(container, name, headers, http.StatusOK) - if err != nil { - return err - } - - return nil -} - -// RenewLease renews the lease for a blob as per https://msdn.microsoft.com/en-us/library/azure/ee691972.aspx -func (b BlobStorageClient) RenewLease(container string, name string, currentLeaseID string) error { - headers := b.client.getStandardHeaders() - headers[leaseAction] = renewLease - headers[headerLeaseID] = currentLeaseID - - _, err := b.leaseCommonPut(container, name, headers, http.StatusOK) - if err != nil { - return err - } - - return nil -} - -// GetBlobProperties provides various information about the specified -// blob. See https://msdn.microsoft.com/en-us/library/azure/dd179394.aspx -func (b BlobStorageClient) GetBlobProperties(container, name string) (*BlobProperties, error) { - uri := b.client.getEndpoint(blobServiceName, pathForBlob(container, name), url.Values{}) - - headers := b.client.getStandardHeaders() - resp, err := b.client.exec(http.MethodHead, uri, headers, nil, b.auth) - if err != nil { - return nil, err - } - defer readAndCloseBody(resp.body) - - if err = checkRespCode(resp.statusCode, []int{http.StatusOK}); err != nil { - return nil, err - } - - var contentLength int64 - contentLengthStr := resp.headers.Get("Content-Length") - if contentLengthStr != "" { - contentLength, err = strconv.ParseInt(contentLengthStr, 0, 64) - if err != nil { - return nil, err - } - } - - var sequenceNum int64 - sequenceNumStr := resp.headers.Get("x-ms-blob-sequence-number") - if sequenceNumStr != "" { - sequenceNum, err = strconv.ParseInt(sequenceNumStr, 0, 64) - if err != nil { - return nil, err - } - } - - return &BlobProperties{ - LastModified: resp.headers.Get("Last-Modified"), - Etag: resp.headers.Get("Etag"), - ContentMD5: resp.headers.Get("Content-MD5"), - ContentLength: contentLength, - ContentEncoding: resp.headers.Get("Content-Encoding"), - ContentType: resp.headers.Get("Content-Type"), - CacheControl: resp.headers.Get("Cache-Control"), - ContentLanguage: resp.headers.Get("Content-Language"), - SequenceNumber: sequenceNum, - CopyCompletionTime: resp.headers.Get("x-ms-copy-completion-time"), - CopyStatusDescription: resp.headers.Get("x-ms-copy-status-description"), - CopyID: resp.headers.Get("x-ms-copy-id"), - CopyProgress: resp.headers.Get("x-ms-copy-progress"), - CopySource: resp.headers.Get("x-ms-copy-source"), - CopyStatus: resp.headers.Get("x-ms-copy-status"), - BlobType: BlobType(resp.headers.Get("x-ms-blob-type")), - LeaseStatus: resp.headers.Get("x-ms-lease-status"), - LeaseState: resp.headers.Get("x-ms-lease-state"), - }, nil -} - -// SetBlobProperties replaces the BlobHeaders for the specified blob. -// -// Some keys may be converted to Camel-Case before sending. All keys -// are returned in lower case by GetBlobProperties. HTTP header names -// are case-insensitive so case munging should not matter to other -// applications either. -// -// See https://msdn.microsoft.com/en-us/library/azure/ee691966.aspx -func (b BlobStorageClient) SetBlobProperties(container, name string, blobHeaders BlobHeaders) error { - params := url.Values{"comp": {"properties"}} - uri := b.client.getEndpoint(blobServiceName, pathForBlob(container, name), params) - headers := b.client.getStandardHeaders() - - extraHeaders := headersFromStruct(blobHeaders) - - for k, v := range extraHeaders { - headers[k] = v - } - - resp, err := b.client.exec(http.MethodPut, uri, headers, nil, b.auth) - if err != nil { - return err - } - defer readAndCloseBody(resp.body) - - return checkRespCode(resp.statusCode, []int{http.StatusOK}) -} - -// SetBlobMetadata replaces the metadata for the specified blob. -// -// Some keys may be converted to Camel-Case before sending. All keys -// are returned in lower case by GetBlobMetadata. HTTP header names -// are case-insensitive so case munging should not matter to other -// applications either. -// -// See https://msdn.microsoft.com/en-us/library/azure/dd179414.aspx -func (b BlobStorageClient) SetBlobMetadata(container, name string, metadata map[string]string, extraHeaders map[string]string) error { - params := url.Values{"comp": {"metadata"}} - uri := b.client.getEndpoint(blobServiceName, pathForBlob(container, name), params) - metadata = b.client.protectUserAgent(metadata) - extraHeaders = b.client.protectUserAgent(extraHeaders) - headers := b.client.getStandardHeaders() - for k, v := range metadata { - headers[userDefinedMetadataHeaderPrefix+k] = v - } - - for k, v := range extraHeaders { - headers[k] = v - } - - resp, err := b.client.exec(http.MethodPut, uri, headers, nil, b.auth) - if err != nil { - return err - } - defer readAndCloseBody(resp.body) - - return checkRespCode(resp.statusCode, []int{http.StatusOK}) -} - -// GetBlobMetadata returns all user-defined metadata for the specified blob. -// -// All metadata keys will be returned in lower case. (HTTP header -// names are case-insensitive.) -// -// See https://msdn.microsoft.com/en-us/library/azure/dd179414.aspx -func (b BlobStorageClient) GetBlobMetadata(container, name string) (map[string]string, error) { - params := url.Values{"comp": {"metadata"}} - uri := b.client.getEndpoint(blobServiceName, pathForBlob(container, name), params) - headers := b.client.getStandardHeaders() - - resp, err := b.client.exec(http.MethodGet, uri, headers, nil, b.auth) - if err != nil { - return nil, err - } - defer readAndCloseBody(resp.body) - - if err := checkRespCode(resp.statusCode, []int{http.StatusOK}); err != nil { - return nil, err - } - - metadata := make(map[string]string) - for k, v := range resp.headers { - // Can't trust CanonicalHeaderKey() to munge case - // reliably. "_" is allowed in identifiers: - // https://msdn.microsoft.com/en-us/library/azure/dd179414.aspx - // https://msdn.microsoft.com/library/aa664670(VS.71).aspx - // http://tools.ietf.org/html/rfc7230#section-3.2 - // ...but "_" is considered invalid by - // CanonicalMIMEHeaderKey in - // https://golang.org/src/net/textproto/reader.go?s=14615:14659#L542 - // so k can be "X-Ms-Meta-Foo" or "x-ms-meta-foo_bar". - k = strings.ToLower(k) - if len(v) == 0 || !strings.HasPrefix(k, strings.ToLower(userDefinedMetadataHeaderPrefix)) { - continue - } - // metadata["foo"] = content of the last X-Ms-Meta-Foo header - k = k[len(userDefinedMetadataHeaderPrefix):] - metadata[k] = v[len(v)-1] - } - return metadata, nil -} - -// CreateBlockBlob initializes an empty block blob with no blocks. -// -// See https://msdn.microsoft.com/en-us/library/azure/dd179451.aspx -func (b BlobStorageClient) CreateBlockBlob(container, name string) error { - return b.CreateBlockBlobFromReader(container, name, 0, nil, nil) -} - -// CreateBlockBlobFromReader initializes a block blob using data from -// reader. Size must be the number of bytes read from reader. To -// create an empty blob, use size==0 and reader==nil. -// -// The API rejects requests with size > 256 MiB (but this limit is not -// checked by the SDK). To write a larger blob, use CreateBlockBlob, -// PutBlock, and PutBlockList. -// -// See https://msdn.microsoft.com/en-us/library/azure/dd179451.aspx -func (b BlobStorageClient) CreateBlockBlobFromReader(container, name string, size uint64, blob io.Reader, extraHeaders map[string]string) error { - path := fmt.Sprintf("%s/%s", container, name) - uri := b.client.getEndpoint(blobServiceName, path, url.Values{}) - extraHeaders = b.client.protectUserAgent(extraHeaders) - headers := b.client.getStandardHeaders() - headers["x-ms-blob-type"] = string(BlobTypeBlock) - headers["Content-Length"] = fmt.Sprintf("%d", size) - - for k, v := range extraHeaders { - headers[k] = v - } - - resp, err := b.client.exec(http.MethodPut, uri, headers, blob, b.auth) - if err != nil { - return err - } - defer readAndCloseBody(resp.body) - return checkRespCode(resp.statusCode, []int{http.StatusCreated}) -} - -// PutBlock saves the given data chunk to the specified block blob with -// given ID. -// -// The API rejects chunks larger than 100 MB (but this limit is not -// checked by the SDK). -// -// See https://msdn.microsoft.com/en-us/library/azure/dd135726.aspx -func (b BlobStorageClient) PutBlock(container, name, blockID string, chunk []byte) error { - return b.PutBlockWithLength(container, name, blockID, uint64(len(chunk)), bytes.NewReader(chunk), nil) -} - -// PutBlockWithLength saves the given data stream of exactly specified size to -// the block blob with given ID. It is an alternative to PutBlocks where data -// comes as stream but the length is known in advance. -// -// The API rejects requests with size > 100 MB (but this limit is not -// checked by the SDK). -// -// See https://msdn.microsoft.com/en-us/library/azure/dd135726.aspx -func (b BlobStorageClient) PutBlockWithLength(container, name, blockID string, size uint64, blob io.Reader, extraHeaders map[string]string) error { - uri := b.client.getEndpoint(blobServiceName, pathForBlob(container, name), url.Values{"comp": {"block"}, "blockid": {blockID}}) - extraHeaders = b.client.protectUserAgent(extraHeaders) - headers := b.client.getStandardHeaders() - headers["x-ms-blob-type"] = string(BlobTypeBlock) - headers["Content-Length"] = fmt.Sprintf("%v", size) - - for k, v := range extraHeaders { - headers[k] = v - } - - resp, err := b.client.exec(http.MethodPut, uri, headers, blob, b.auth) - if err != nil { - return err - } - - defer readAndCloseBody(resp.body) - return checkRespCode(resp.statusCode, []int{http.StatusCreated}) -} - -// PutBlockList saves list of blocks to the specified block blob. -// -// See https://msdn.microsoft.com/en-us/library/azure/dd179467.aspx -func (b BlobStorageClient) PutBlockList(container, name string, blocks []Block) error { - blockListXML := prepareBlockListRequest(blocks) - - uri := b.client.getEndpoint(blobServiceName, pathForBlob(container, name), url.Values{"comp": {"blocklist"}}) - headers := b.client.getStandardHeaders() - headers["Content-Length"] = fmt.Sprintf("%v", len(blockListXML)) - - resp, err := b.client.exec(http.MethodPut, uri, headers, strings.NewReader(blockListXML), b.auth) - if err != nil { - return err - } - defer readAndCloseBody(resp.body) - return checkRespCode(resp.statusCode, []int{http.StatusCreated}) -} - -// GetBlockList retrieves list of blocks in the specified block blob. -// -// See https://msdn.microsoft.com/en-us/library/azure/dd179400.aspx -func (b BlobStorageClient) GetBlockList(container, name string, blockType BlockListType) (BlockListResponse, error) { - params := url.Values{"comp": {"blocklist"}, "blocklisttype": {string(blockType)}} - uri := b.client.getEndpoint(blobServiceName, pathForBlob(container, name), params) - headers := b.client.getStandardHeaders() - - var out BlockListResponse - resp, err := b.client.exec(http.MethodGet, uri, headers, nil, b.auth) - if err != nil { - return out, err - } - defer resp.body.Close() - - err = xmlUnmarshal(resp.body, &out) - return out, err -} - -// PutPageBlob initializes an empty page blob with specified name and maximum -// size in bytes (size must be aligned to a 512-byte boundary). A page blob must -// be created using this method before writing pages. -// -// See https://msdn.microsoft.com/en-us/library/azure/dd179451.aspx -func (b BlobStorageClient) PutPageBlob(container, name string, size int64, extraHeaders map[string]string) error { - path := fmt.Sprintf("%s/%s", container, name) - uri := b.client.getEndpoint(blobServiceName, path, url.Values{}) - extraHeaders = b.client.protectUserAgent(extraHeaders) - headers := b.client.getStandardHeaders() - headers["x-ms-blob-type"] = string(BlobTypePage) - headers["x-ms-blob-content-length"] = fmt.Sprintf("%v", size) - - for k, v := range extraHeaders { - headers[k] = v - } - - resp, err := b.client.exec(http.MethodPut, uri, headers, nil, b.auth) - if err != nil { - return err - } - defer readAndCloseBody(resp.body) - - return checkRespCode(resp.statusCode, []int{http.StatusCreated}) -} - -// PutPage writes a range of pages to a page blob or clears the given range. -// In case of 'clear' writes, given chunk is discarded. Ranges must be aligned -// with 512-byte boundaries and chunk must be of size multiplies by 512. -// -// See https://msdn.microsoft.com/en-us/library/ee691975.aspx -func (b BlobStorageClient) PutPage(container, name string, startByte, endByte int64, writeType PageWriteType, chunk []byte, extraHeaders map[string]string) error { - path := fmt.Sprintf("%s/%s", container, name) - uri := b.client.getEndpoint(blobServiceName, path, url.Values{"comp": {"page"}}) - extraHeaders = b.client.protectUserAgent(extraHeaders) - headers := b.client.getStandardHeaders() - headers["x-ms-blob-type"] = string(BlobTypePage) - headers["x-ms-page-write"] = string(writeType) - headers["x-ms-range"] = fmt.Sprintf("bytes=%v-%v", startByte, endByte) - for k, v := range extraHeaders { - headers[k] = v - } - var contentLength int64 - var data io.Reader - if writeType == PageWriteTypeClear { - contentLength = 0 - data = bytes.NewReader([]byte{}) - } else { - contentLength = int64(len(chunk)) - data = bytes.NewReader(chunk) - } - headers["Content-Length"] = fmt.Sprintf("%v", contentLength) - - resp, err := b.client.exec(http.MethodPut, uri, headers, data, b.auth) - if err != nil { - return err - } - defer readAndCloseBody(resp.body) - - return checkRespCode(resp.statusCode, []int{http.StatusCreated}) -} - -// GetPageRanges returns the list of valid page ranges for a page blob. -// -// See https://msdn.microsoft.com/en-us/library/azure/ee691973.aspx -func (b BlobStorageClient) GetPageRanges(container, name string) (GetPageRangesResponse, error) { - path := fmt.Sprintf("%s/%s", container, name) - uri := b.client.getEndpoint(blobServiceName, path, url.Values{"comp": {"pagelist"}}) - headers := b.client.getStandardHeaders() - - var out GetPageRangesResponse - resp, err := b.client.exec(http.MethodGet, uri, headers, nil, b.auth) - if err != nil { - return out, err - } - defer resp.body.Close() - - if err = checkRespCode(resp.statusCode, []int{http.StatusOK}); err != nil { - return out, err - } - err = xmlUnmarshal(resp.body, &out) - return out, err -} - -// PutAppendBlob initializes an empty append blob with specified name. An -// append blob must be created using this method before appending blocks. -// -// See https://msdn.microsoft.com/en-us/library/azure/dd179451.aspx -func (b BlobStorageClient) PutAppendBlob(container, name string, extraHeaders map[string]string) error { - path := fmt.Sprintf("%s/%s", container, name) - uri := b.client.getEndpoint(blobServiceName, path, url.Values{}) - extraHeaders = b.client.protectUserAgent(extraHeaders) - headers := b.client.getStandardHeaders() - headers["x-ms-blob-type"] = string(BlobTypeAppend) - - for k, v := range extraHeaders { - headers[k] = v - } - - resp, err := b.client.exec(http.MethodPut, uri, headers, nil, b.auth) - if err != nil { - return err - } - defer readAndCloseBody(resp.body) - - return checkRespCode(resp.statusCode, []int{http.StatusCreated}) -} - -// AppendBlock appends a block to an append blob. -// -// See https://msdn.microsoft.com/en-us/library/azure/mt427365.aspx -func (b BlobStorageClient) AppendBlock(container, name string, chunk []byte, extraHeaders map[string]string) error { - path := fmt.Sprintf("%s/%s", container, name) - uri := b.client.getEndpoint(blobServiceName, path, url.Values{"comp": {"appendblock"}}) - extraHeaders = b.client.protectUserAgent(extraHeaders) - headers := b.client.getStandardHeaders() - headers["x-ms-blob-type"] = string(BlobTypeAppend) - headers["Content-Length"] = fmt.Sprintf("%v", len(chunk)) - - for k, v := range extraHeaders { - headers[k] = v - } - - resp, err := b.client.exec(http.MethodPut, uri, headers, bytes.NewReader(chunk), b.auth) - if err != nil { - return err - } - defer readAndCloseBody(resp.body) - - return checkRespCode(resp.statusCode, []int{http.StatusCreated}) -} - -// CopyBlob starts a blob copy operation and waits for the operation to -// complete. sourceBlob parameter must be a canonical URL to the blob (can be -// obtained using GetBlobURL method.) There is no SLA on blob copy and therefore -// this helper method works faster on smaller files. -// -// See https://msdn.microsoft.com/en-us/library/azure/dd894037.aspx -func (b BlobStorageClient) CopyBlob(container, name, sourceBlob string) error { - copyID, err := b.StartBlobCopy(container, name, sourceBlob) - if err != nil { - return err - } - - return b.WaitForBlobCopy(container, name, copyID) -} - -// StartBlobCopy starts a blob copy operation. -// sourceBlob parameter must be a canonical URL to the blob (can be -// obtained using GetBlobURL method.) -// -// See https://msdn.microsoft.com/en-us/library/azure/dd894037.aspx -func (b BlobStorageClient) StartBlobCopy(container, name, sourceBlob string) (string, error) { - uri := b.client.getEndpoint(blobServiceName, pathForBlob(container, name), url.Values{}) - - headers := b.client.getStandardHeaders() - headers["x-ms-copy-source"] = sourceBlob - - resp, err := b.client.exec(http.MethodPut, uri, headers, nil, b.auth) - if err != nil { - return "", err - } - defer readAndCloseBody(resp.body) - - if err := checkRespCode(resp.statusCode, []int{http.StatusAccepted, http.StatusCreated}); err != nil { - return "", err - } - - copyID := resp.headers.Get("x-ms-copy-id") - if copyID == "" { - return "", errors.New("Got empty copy id header") - } - return copyID, nil -} - -// AbortBlobCopy aborts a BlobCopy which has already been triggered by the StartBlobCopy function. -// copyID is generated from StartBlobCopy function. -// currentLeaseID is required IF the destination blob has an active lease on it. -// As defined in https://msdn.microsoft.com/en-us/library/azure/jj159098.aspx -func (b BlobStorageClient) AbortBlobCopy(container, name, copyID, currentLeaseID string, timeout int) error { - params := url.Values{"comp": {"copy"}, "copyid": {copyID}} - if timeout > 0 { - params.Add("timeout", strconv.Itoa(timeout)) - } - - uri := b.client.getEndpoint(blobServiceName, pathForBlob(container, name), params) - headers := b.client.getStandardHeaders() - headers["x-ms-copy-action"] = "abort" - - if currentLeaseID != "" { - headers[headerLeaseID] = currentLeaseID - } - - resp, err := b.client.exec(http.MethodPut, uri, headers, nil, b.auth) - if err != nil { - return err - } - defer readAndCloseBody(resp.body) - - if err := checkRespCode(resp.statusCode, []int{http.StatusNoContent}); err != nil { - return err - } - - return nil -} - -// WaitForBlobCopy loops until a BlobCopy operation is completed (or fails with error) -func (b BlobStorageClient) WaitForBlobCopy(container, name, copyID string) error { - for { - props, err := b.GetBlobProperties(container, name) - if err != nil { - return err - } - - if props.CopyID != copyID { - return errBlobCopyIDMismatch - } - - switch props.CopyStatus { - case blobCopyStatusSuccess: - return nil - case blobCopyStatusPending: - continue - case blobCopyStatusAborted: - return errBlobCopyAborted - case blobCopyStatusFailed: - return fmt.Errorf("storage: blob copy failed. Id=%s Description=%s", props.CopyID, props.CopyStatusDescription) - default: - return fmt.Errorf("storage: unhandled blob copy status: '%s'", props.CopyStatus) - } - } -} - -// DeleteBlob deletes the given blob from the specified container. -// If the blob does not exists at the time of the Delete Blob operation, it -// returns error. See https://msdn.microsoft.com/en-us/library/azure/dd179413.aspx -func (b BlobStorageClient) DeleteBlob(container, name string, extraHeaders map[string]string) error { - resp, err := b.deleteBlob(container, name, extraHeaders) - if err != nil { - return err - } - defer readAndCloseBody(resp.body) - return checkRespCode(resp.statusCode, []int{http.StatusAccepted}) -} - -// DeleteBlobIfExists deletes the given blob from the specified container If the -// blob is deleted with this call, returns true. Otherwise returns false. -// -// See https://msdn.microsoft.com/en-us/library/azure/dd179413.aspx -func (b BlobStorageClient) DeleteBlobIfExists(container, name string, extraHeaders map[string]string) (bool, error) { - resp, err := b.deleteBlob(container, name, extraHeaders) - if resp != nil { - defer readAndCloseBody(resp.body) - if resp.statusCode == http.StatusAccepted || resp.statusCode == http.StatusNotFound { - return resp.statusCode == http.StatusAccepted, nil - } - } - return false, err -} - -func (b BlobStorageClient) deleteBlob(container, name string, extraHeaders map[string]string) (*storageResponse, error) { - uri := b.client.getEndpoint(blobServiceName, pathForBlob(container, name), url.Values{}) - extraHeaders = b.client.protectUserAgent(extraHeaders) - headers := b.client.getStandardHeaders() - for k, v := range extraHeaders { - headers[k] = v - } - - return b.client.exec(http.MethodDelete, uri, headers, nil, b.auth) -} - -// helper method to construct the path to a blob given its container and blob -// name -func pathForBlob(container, name string) string { - return fmt.Sprintf("/%s/%s", container, name) -} - -// helper method to construct the path to either a blob or container -func pathForResource(container, name string) string { - if len(name) > 0 { - return fmt.Sprintf("/%s/%s", container, name) - } - return fmt.Sprintf("/%s", container) -} - -// GetBlobSASURIWithSignedIPAndProtocol creates an URL to the specified blob which contains the Shared -// Access Signature with specified permissions and expiration time. Also includes signedIPRange and allowed protocols. -// If old API version is used but no signedIP is passed (ie empty string) then this should still work. -// We only populate the signedIP when it non-empty. -// -// See https://msdn.microsoft.com/en-us/library/azure/ee395415.aspx -func (b BlobStorageClient) GetBlobSASURIWithSignedIPAndProtocol(container, name string, expiry time.Time, permissions string, signedIPRange string, HTTPSOnly bool) (string, error) { - var ( - signedPermissions = permissions - blobURL = b.GetBlobURL(container, name) - ) - canonicalizedResource, err := b.client.buildCanonicalizedResource(blobURL, b.auth) - if err != nil { - return "", err - } - - // "The canonicalizedresouce portion of the string is a canonical path to the signed resource. - // It must include the service name (blob, table, queue or file) for version 2015-02-21 or - // later, the storage account name, and the resource name, and must be URL-decoded. - // -- https://msdn.microsoft.com/en-us/library/azure/dn140255.aspx - - // We need to replace + with %2b first to avoid being treated as a space (which is correct for query strings, but not the path component). - canonicalizedResource = strings.Replace(canonicalizedResource, "+", "%2b", -1) - canonicalizedResource, err = url.QueryUnescape(canonicalizedResource) - if err != nil { - return "", err - } - - signedExpiry := expiry.UTC().Format(time.RFC3339) - - //If blob name is missing, resource is a container - signedResource := "c" - if len(name) > 0 { - signedResource = "b" - } - - protocols := "https,http" - if HTTPSOnly { - protocols = "https" - } - stringToSign, err := blobSASStringToSign(b.client.apiVersion, canonicalizedResource, signedExpiry, signedPermissions, signedIPRange, protocols) - if err != nil { - return "", err - } - - sig := b.client.computeHmac256(stringToSign) - sasParams := url.Values{ - "sv": {b.client.apiVersion}, - "se": {signedExpiry}, - "sr": {signedResource}, - "sp": {signedPermissions}, - "sig": {sig}, - } - - if b.client.apiVersion >= "2015-04-05" { - sasParams.Add("spr", protocols) - if signedIPRange != "" { - sasParams.Add("sip", signedIPRange) - } - } - - sasURL, err := url.Parse(blobURL) - if err != nil { - return "", err - } - sasURL.RawQuery = sasParams.Encode() - return sasURL.String(), nil -} - -// GetBlobSASURI creates an URL to the specified blob which contains the Shared -// Access Signature with specified permissions and expiration time. -// -// See https://msdn.microsoft.com/en-us/library/azure/ee395415.aspx -func (b BlobStorageClient) GetBlobSASURI(container, name string, expiry time.Time, permissions string) (string, error) { - url, err := b.GetBlobSASURIWithSignedIPAndProtocol(container, name, expiry, permissions, "", false) - return url, err -} - -func blobSASStringToSign(signedVersion, canonicalizedResource, signedExpiry, signedPermissions string, signedIP string, protocols string) (string, error) { - var signedStart, signedIdentifier, rscc, rscd, rsce, rscl, rsct string - - if signedVersion >= "2015-02-21" { - canonicalizedResource = "/blob" + canonicalizedResource - } - - // https://msdn.microsoft.com/en-us/library/azure/dn140255.aspx#Anchor_12 - if signedVersion >= "2015-04-05" { - return fmt.Sprintf("%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s", signedPermissions, signedStart, signedExpiry, canonicalizedResource, signedIdentifier, signedIP, protocols, signedVersion, rscc, rscd, rsce, rscl, rsct), nil - } - - // reference: http://msdn.microsoft.com/en-us/library/azure/dn140255.aspx - if signedVersion >= "2013-08-15" { - return fmt.Sprintf("%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s", signedPermissions, signedStart, signedExpiry, canonicalizedResource, signedIdentifier, signedVersion, rscc, rscd, rsce, rscl, rsct), nil - } - - return "", errors.New("storage: not implemented SAS for versions earlier than 2013-08-15") -} diff --git a/vendor/github.com/Azure/azure-storage-go/blobserviceclient.go b/vendor/github.com/Azure/azure-storage-go/blobserviceclient.go deleted file mode 100644 index e5911ac81b..0000000000 --- a/vendor/github.com/Azure/azure-storage-go/blobserviceclient.go +++ /dev/null @@ -1,92 +0,0 @@ -package storage - -import ( - "fmt" - "net/http" - "net/url" -) - -// BlobStorageClient contains operations for Microsoft Azure Blob Storage -// Service. -type BlobStorageClient struct { - client Client - auth authentication -} - -// GetServiceProperties gets the properties of your storage account's blob service. -// See: https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/get-blob-service-properties -func (b *BlobStorageClient) GetServiceProperties() (*ServiceProperties, error) { - return b.client.getServiceProperties(blobServiceName, b.auth) -} - -// SetServiceProperties sets the properties of your storage account's blob service. -// See: https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/set-blob-service-properties -func (b *BlobStorageClient) SetServiceProperties(props ServiceProperties) error { - return b.client.setServiceProperties(props, blobServiceName, b.auth) -} - -// ListContainersParameters defines the set of customizable parameters to make a -// List Containers call. -// -// See https://msdn.microsoft.com/en-us/library/azure/dd179352.aspx -type ListContainersParameters struct { - Prefix string - Marker string - Include string - MaxResults uint - Timeout uint -} - -// GetContainerReference returns a Container object for the specified container name. -func (b BlobStorageClient) GetContainerReference(name string) Container { - return Container{ - bsc: &b, - Name: name, - } -} - -// ListContainers returns the list of containers in a storage account along with -// pagination token and other response details. -// -// See https://msdn.microsoft.com/en-us/library/azure/dd179352.aspx -func (b BlobStorageClient) ListContainers(params ListContainersParameters) (*ContainerListResponse, error) { - q := mergeParams(params.getParameters(), url.Values{"comp": {"list"}}) - uri := b.client.getEndpoint(blobServiceName, "", q) - headers := b.client.getStandardHeaders() - - var out ContainerListResponse - resp, err := b.client.exec(http.MethodGet, uri, headers, nil, b.auth) - if err != nil { - return nil, err - } - defer resp.body.Close() - err = xmlUnmarshal(resp.body, &out) - - // assign our client to the newly created Container objects - for i := range out.Containers { - out.Containers[i].bsc = &b - } - return &out, err -} - -func (p ListContainersParameters) getParameters() url.Values { - out := url.Values{} - - if p.Prefix != "" { - out.Set("prefix", p.Prefix) - } - if p.Marker != "" { - out.Set("marker", p.Marker) - } - if p.Include != "" { - out.Set("include", p.Include) - } - if p.MaxResults != 0 { - out.Set("maxresults", fmt.Sprintf("%v", p.MaxResults)) - } - if p.Timeout != 0 { - out.Set("timeout", fmt.Sprintf("%v", p.Timeout)) - } - - return out -} diff --git a/vendor/github.com/Azure/azure-storage-go/client.go b/vendor/github.com/Azure/azure-storage-go/client.go deleted file mode 100644 index 9ddbf08aee..0000000000 --- a/vendor/github.com/Azure/azure-storage-go/client.go +++ /dev/null @@ -1,479 +0,0 @@ -// Package storage provides clients for Microsoft Azure Storage Services. -package storage - -import ( - "bytes" - "encoding/base64" - "encoding/json" - "encoding/xml" - "errors" - "fmt" - "io" - "io/ioutil" - "net/http" - "net/url" - "runtime" - "strconv" - "strings" - - "github.com/Azure/go-autorest/autorest/azure" -) - -const ( - // DefaultBaseURL is the domain name used for storage requests in the - // public cloud when a default client is created. - DefaultBaseURL = "core.windows.net" - - // DefaultAPIVersion is the Azure Storage API version string used when a - // basic client is created. - DefaultAPIVersion = "2016-05-31" - - defaultUseHTTPS = true - - // StorageEmulatorAccountName is the fixed storage account used by Azure Storage Emulator - StorageEmulatorAccountName = "devstoreaccount1" - - // StorageEmulatorAccountKey is the the fixed storage account used by Azure Storage Emulator - StorageEmulatorAccountKey = "Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==" - - blobServiceName = "blob" - tableServiceName = "table" - queueServiceName = "queue" - fileServiceName = "file" - - storageEmulatorBlob = "127.0.0.1:10000" - storageEmulatorTable = "127.0.0.1:10002" - storageEmulatorQueue = "127.0.0.1:10001" - - userAgentHeader = "User-Agent" -) - -// Client is the object that needs to be constructed to perform -// operations on the storage account. -type Client struct { - // HTTPClient is the http.Client used to initiate API - // requests. If it is nil, http.DefaultClient is used. - HTTPClient *http.Client - - accountName string - accountKey []byte - useHTTPS bool - UseSharedKeyLite bool - baseURL string - apiVersion string - userAgent string -} - -type storageResponse struct { - statusCode int - headers http.Header - body io.ReadCloser -} - -type odataResponse struct { - storageResponse - odata odataErrorMessage -} - -// AzureStorageServiceError contains fields of the error response from -// Azure Storage Service REST API. See https://msdn.microsoft.com/en-us/library/azure/dd179382.aspx -// Some fields might be specific to certain calls. -type AzureStorageServiceError struct { - Code string `xml:"Code"` - Message string `xml:"Message"` - AuthenticationErrorDetail string `xml:"AuthenticationErrorDetail"` - QueryParameterName string `xml:"QueryParameterName"` - QueryParameterValue string `xml:"QueryParameterValue"` - Reason string `xml:"Reason"` - StatusCode int - RequestID string -} - -type odataErrorMessageMessage struct { - Lang string `json:"lang"` - Value string `json:"value"` -} - -type odataErrorMessageInternal struct { - Code string `json:"code"` - Message odataErrorMessageMessage `json:"message"` -} - -type odataErrorMessage struct { - Err odataErrorMessageInternal `json:"odata.error"` -} - -// UnexpectedStatusCodeError is returned when a storage service responds with neither an error -// nor with an HTTP status code indicating success. -type UnexpectedStatusCodeError struct { - allowed []int - got int -} - -func (e UnexpectedStatusCodeError) Error() string { - s := func(i int) string { return fmt.Sprintf("%d %s", i, http.StatusText(i)) } - - got := s(e.got) - expected := []string{} - for _, v := range e.allowed { - expected = append(expected, s(v)) - } - return fmt.Sprintf("storage: status code from service response is %s; was expecting %s", got, strings.Join(expected, " or ")) -} - -// Got is the actual status code returned by Azure. -func (e UnexpectedStatusCodeError) Got() int { - return e.got -} - -// NewBasicClient constructs a Client with given storage service name and -// key. -func NewBasicClient(accountName, accountKey string) (Client, error) { - if accountName == StorageEmulatorAccountName { - return NewEmulatorClient() - } - return NewClient(accountName, accountKey, DefaultBaseURL, DefaultAPIVersion, defaultUseHTTPS) -} - -// NewBasicClientOnSovereignCloud constructs a Client with given storage service name and -// key in the referenced cloud. -func NewBasicClientOnSovereignCloud(accountName, accountKey string, env azure.Environment) (Client, error) { - if accountName == StorageEmulatorAccountName { - return NewEmulatorClient() - } - return NewClient(accountName, accountKey, env.StorageEndpointSuffix, DefaultAPIVersion, defaultUseHTTPS) -} - -//NewEmulatorClient contructs a Client intended to only work with Azure -//Storage Emulator -func NewEmulatorClient() (Client, error) { - return NewClient(StorageEmulatorAccountName, StorageEmulatorAccountKey, DefaultBaseURL, DefaultAPIVersion, false) -} - -// NewClient constructs a Client. This should be used if the caller wants -// to specify whether to use HTTPS, a specific REST API version or a custom -// storage endpoint than Azure Public Cloud. -func NewClient(accountName, accountKey, blobServiceBaseURL, apiVersion string, useHTTPS bool) (Client, error) { - var c Client - if accountName == "" { - return c, fmt.Errorf("azure: account name required") - } else if accountKey == "" { - return c, fmt.Errorf("azure: account key required") - } else if blobServiceBaseURL == "" { - return c, fmt.Errorf("azure: base storage service url required") - } - - key, err := base64.StdEncoding.DecodeString(accountKey) - if err != nil { - return c, fmt.Errorf("azure: malformed storage account key: %v", err) - } - - c = Client{ - accountName: accountName, - accountKey: key, - useHTTPS: useHTTPS, - baseURL: blobServiceBaseURL, - apiVersion: apiVersion, - UseSharedKeyLite: false, - } - c.userAgent = c.getDefaultUserAgent() - return c, nil -} - -func (c Client) getDefaultUserAgent() string { - return fmt.Sprintf("Go/%s (%s-%s) Azure-SDK-For-Go/%s storage-dataplane/%s", - runtime.Version(), - runtime.GOARCH, - runtime.GOOS, - sdkVersion, - c.apiVersion, - ) -} - -// AddToUserAgent adds an extension to the current user agent -func (c *Client) AddToUserAgent(extension string) error { - if extension != "" { - c.userAgent = fmt.Sprintf("%s %s", c.userAgent, extension) - return nil - } - return fmt.Errorf("Extension was empty, User Agent stayed as %s", c.userAgent) -} - -// protectUserAgent is used in funcs that include extraheaders as a parameter. -// It prevents the User-Agent header to be overwritten, instead if it happens to -// be present, it gets added to the current User-Agent. Use it before getStandardHeaders -func (c *Client) protectUserAgent(extraheaders map[string]string) map[string]string { - if v, ok := extraheaders[userAgentHeader]; ok { - c.AddToUserAgent(v) - delete(extraheaders, userAgentHeader) - } - return extraheaders -} - -func (c Client) getBaseURL(service string) string { - scheme := "http" - if c.useHTTPS { - scheme = "https" - } - host := "" - if c.accountName == StorageEmulatorAccountName { - switch service { - case blobServiceName: - host = storageEmulatorBlob - case tableServiceName: - host = storageEmulatorTable - case queueServiceName: - host = storageEmulatorQueue - } - } else { - host = fmt.Sprintf("%s.%s.%s", c.accountName, service, c.baseURL) - } - - u := &url.URL{ - Scheme: scheme, - Host: host} - return u.String() -} - -func (c Client) getEndpoint(service, path string, params url.Values) string { - u, err := url.Parse(c.getBaseURL(service)) - if err != nil { - // really should not be happening - panic(err) - } - - // API doesn't accept path segments not starting with '/' - if !strings.HasPrefix(path, "/") { - path = fmt.Sprintf("/%v", path) - } - - if c.accountName == StorageEmulatorAccountName { - path = fmt.Sprintf("/%v%v", StorageEmulatorAccountName, path) - } - - u.Path = path - u.RawQuery = params.Encode() - return u.String() -} - -// GetBlobService returns a BlobStorageClient which can operate on the blob -// service of the storage account. -func (c Client) GetBlobService() BlobStorageClient { - b := BlobStorageClient{ - client: c, - } - b.client.AddToUserAgent(blobServiceName) - b.auth = sharedKey - if c.UseSharedKeyLite { - b.auth = sharedKeyLite - } - return b -} - -// GetQueueService returns a QueueServiceClient which can operate on the queue -// service of the storage account. -func (c Client) GetQueueService() QueueServiceClient { - q := QueueServiceClient{ - client: c, - } - q.client.AddToUserAgent(queueServiceName) - q.auth = sharedKey - if c.UseSharedKeyLite { - q.auth = sharedKeyLite - } - return q -} - -// GetTableService returns a TableServiceClient which can operate on the table -// service of the storage account. -func (c Client) GetTableService() TableServiceClient { - t := TableServiceClient{ - client: c, - } - t.client.AddToUserAgent(tableServiceName) - t.auth = sharedKeyForTable - if c.UseSharedKeyLite { - t.auth = sharedKeyLiteForTable - } - return t -} - -// GetFileService returns a FileServiceClient which can operate on the file -// service of the storage account. -func (c Client) GetFileService() FileServiceClient { - f := FileServiceClient{ - client: c, - } - f.client.AddToUserAgent(fileServiceName) - f.auth = sharedKey - if c.UseSharedKeyLite { - f.auth = sharedKeyLite - } - return f -} - -func (c Client) getStandardHeaders() map[string]string { - return map[string]string{ - userAgentHeader: c.userAgent, - "x-ms-version": c.apiVersion, - "x-ms-date": currentTimeRfc1123Formatted(), - } -} - -func (c Client) exec(verb, url string, headers map[string]string, body io.Reader, auth authentication) (*storageResponse, error) { - headers, err := c.addAuthorizationHeader(verb, url, headers, auth) - if err != nil { - return nil, err - } - - req, err := http.NewRequest(verb, url, body) - if err != nil { - return nil, errors.New("azure/storage: error creating request: " + err.Error()) - } - - if clstr, ok := headers["Content-Length"]; ok { - // content length header is being signed, but completely ignored by golang. - // instead we have to use the ContentLength property on the request struct - // (see https://golang.org/src/net/http/request.go?s=18140:18370#L536 and - // https://golang.org/src/net/http/transfer.go?s=1739:2467#L49) - req.ContentLength, err = strconv.ParseInt(clstr, 10, 64) - if err != nil { - return nil, err - } - } - for k, v := range headers { - req.Header.Add(k, v) - } - - httpClient := c.HTTPClient - if httpClient == nil { - httpClient = http.DefaultClient - } - resp, err := httpClient.Do(req) - if err != nil { - return nil, err - } - - statusCode := resp.StatusCode - if statusCode >= 400 && statusCode <= 505 { - var respBody []byte - respBody, err = readAndCloseBody(resp.Body) - if err != nil { - return nil, err - } - - requestID := resp.Header.Get("x-ms-request-id") - if len(respBody) == 0 { - // no error in response body, might happen in HEAD requests - err = serviceErrFromStatusCode(resp.StatusCode, resp.Status, requestID) - } else { - // response contains storage service error object, unmarshal - storageErr, errIn := serviceErrFromXML(respBody, resp.StatusCode, requestID) - if err != nil { // error unmarshaling the error response - err = errIn - } - err = storageErr - } - return &storageResponse{ - statusCode: resp.StatusCode, - headers: resp.Header, - body: ioutil.NopCloser(bytes.NewReader(respBody)), /* restore the body */ - }, err - } - - return &storageResponse{ - statusCode: resp.StatusCode, - headers: resp.Header, - body: resp.Body}, nil -} - -func (c Client) execInternalJSON(verb, url string, headers map[string]string, body io.Reader, auth authentication) (*odataResponse, error) { - headers, err := c.addAuthorizationHeader(verb, url, headers, auth) - if err != nil { - return nil, err - } - - req, err := http.NewRequest(verb, url, body) - for k, v := range headers { - req.Header.Add(k, v) - } - - httpClient := c.HTTPClient - if httpClient == nil { - httpClient = http.DefaultClient - } - - resp, err := httpClient.Do(req) - if err != nil { - return nil, err - } - - respToRet := &odataResponse{} - respToRet.body = resp.Body - respToRet.statusCode = resp.StatusCode - respToRet.headers = resp.Header - - statusCode := resp.StatusCode - if statusCode >= 400 && statusCode <= 505 { - var respBody []byte - respBody, err = readAndCloseBody(resp.Body) - if err != nil { - return nil, err - } - - if len(respBody) == 0 { - // no error in response body, might happen in HEAD requests - err = serviceErrFromStatusCode(resp.StatusCode, resp.Status, resp.Header.Get("x-ms-request-id")) - return respToRet, err - } - // try unmarshal as odata.error json - err = json.Unmarshal(respBody, &respToRet.odata) - return respToRet, err - } - - return respToRet, nil -} - -func readAndCloseBody(body io.ReadCloser) ([]byte, error) { - defer body.Close() - out, err := ioutil.ReadAll(body) - if err == io.EOF { - err = nil - } - return out, err -} - -func serviceErrFromXML(body []byte, statusCode int, requestID string) (AzureStorageServiceError, error) { - var storageErr AzureStorageServiceError - if err := xml.Unmarshal(body, &storageErr); err != nil { - return storageErr, err - } - storageErr.StatusCode = statusCode - storageErr.RequestID = requestID - return storageErr, nil -} - -func serviceErrFromStatusCode(code int, status string, requestID string) AzureStorageServiceError { - return AzureStorageServiceError{ - StatusCode: code, - Code: status, - RequestID: requestID, - Message: "no response body was available for error status code", - } -} - -func (e AzureStorageServiceError) Error() string { - return fmt.Sprintf("storage: service returned error: StatusCode=%d, ErrorCode=%s, ErrorMessage=%s, RequestId=%s, QueryParameterName=%s, QueryParameterValue=%s", - e.StatusCode, e.Code, e.Message, e.RequestID, e.QueryParameterName, e.QueryParameterValue) -} - -// checkRespCode returns UnexpectedStatusError if the given response code is not -// one of the allowed status codes; otherwise nil. -func checkRespCode(respCode int, allowed []int) error { - for _, v := range allowed { - if respCode == v { - return nil - } - } - return UnexpectedStatusCodeError{allowed, respCode} -} diff --git a/vendor/github.com/Azure/azure-storage-go/container.go b/vendor/github.com/Azure/azure-storage-go/container.go deleted file mode 100644 index f064239674..0000000000 --- a/vendor/github.com/Azure/azure-storage-go/container.go +++ /dev/null @@ -1,376 +0,0 @@ -package storage - -import ( - "encoding/xml" - "errors" - "fmt" - "io" - "net/http" - "net/url" - "strconv" - "time" -) - -// Container represents an Azure container. -type Container struct { - bsc *BlobStorageClient - Name string `xml:"Name"` - Properties ContainerProperties `xml:"Properties"` -} - -func (c *Container) buildPath() string { - return fmt.Sprintf("/%s", c.Name) -} - -// ContainerProperties contains various properties of a container returned from -// various endpoints like ListContainers. -type ContainerProperties struct { - LastModified string `xml:"Last-Modified"` - Etag string `xml:"Etag"` - LeaseStatus string `xml:"LeaseStatus"` - LeaseState string `xml:"LeaseState"` - LeaseDuration string `xml:"LeaseDuration"` -} - -// ContainerListResponse contains the response fields from -// ListContainers call. -// -// See https://msdn.microsoft.com/en-us/library/azure/dd179352.aspx -type ContainerListResponse struct { - XMLName xml.Name `xml:"EnumerationResults"` - Xmlns string `xml:"xmlns,attr"` - Prefix string `xml:"Prefix"` - Marker string `xml:"Marker"` - NextMarker string `xml:"NextMarker"` - MaxResults int64 `xml:"MaxResults"` - Containers []Container `xml:"Containers>Container"` -} - -// BlobListResponse contains the response fields from ListBlobs call. -// -// See https://msdn.microsoft.com/en-us/library/azure/dd135734.aspx -type BlobListResponse struct { - XMLName xml.Name `xml:"EnumerationResults"` - Xmlns string `xml:"xmlns,attr"` - Prefix string `xml:"Prefix"` - Marker string `xml:"Marker"` - NextMarker string `xml:"NextMarker"` - MaxResults int64 `xml:"MaxResults"` - Blobs []Blob `xml:"Blobs>Blob"` - - // BlobPrefix is used to traverse blobs as if it were a file system. - // It is returned if ListBlobsParameters.Delimiter is specified. - // The list here can be thought of as "folders" that may contain - // other folders or blobs. - BlobPrefixes []string `xml:"Blobs>BlobPrefix>Name"` - - // Delimiter is used to traverse blobs as if it were a file system. - // It is returned if ListBlobsParameters.Delimiter is specified. - Delimiter string `xml:"Delimiter"` -} - -// ListBlobsParameters defines the set of customizable -// parameters to make a List Blobs call. -// -// See https://msdn.microsoft.com/en-us/library/azure/dd135734.aspx -type ListBlobsParameters struct { - Prefix string - Delimiter string - Marker string - Include string - MaxResults uint - Timeout uint -} - -func (p ListBlobsParameters) getParameters() url.Values { - out := url.Values{} - - if p.Prefix != "" { - out.Set("prefix", p.Prefix) - } - if p.Delimiter != "" { - out.Set("delimiter", p.Delimiter) - } - if p.Marker != "" { - out.Set("marker", p.Marker) - } - if p.Include != "" { - out.Set("include", p.Include) - } - if p.MaxResults != 0 { - out.Set("maxresults", fmt.Sprintf("%v", p.MaxResults)) - } - if p.Timeout != 0 { - out.Set("timeout", fmt.Sprintf("%v", p.Timeout)) - } - - return out -} - -// ContainerAccessType defines the access level to the container from a public -// request. -// -// See https://msdn.microsoft.com/en-us/library/azure/dd179468.aspx and "x-ms- -// blob-public-access" header. -type ContainerAccessType string - -// Access options for containers -const ( - ContainerAccessTypePrivate ContainerAccessType = "" - ContainerAccessTypeBlob ContainerAccessType = "blob" - ContainerAccessTypeContainer ContainerAccessType = "container" -) - -// ContainerAccessPolicy represents each access policy in the container ACL. -type ContainerAccessPolicy struct { - ID string - StartTime time.Time - ExpiryTime time.Time - CanRead bool - CanWrite bool - CanDelete bool -} - -// ContainerPermissions represents the container ACLs. -type ContainerPermissions struct { - AccessType ContainerAccessType - AccessPolicies []ContainerAccessPolicy -} - -// ContainerAccessHeader references header used when setting/getting container ACL -const ( - ContainerAccessHeader string = "x-ms-blob-public-access" -) - -// Create creates a blob container within the storage account -// with given name and access level. Returns error if container already exists. -// -// See https://msdn.microsoft.com/en-us/library/azure/dd179468.aspx -func (c *Container) Create() error { - resp, err := c.create() - if err != nil { - return err - } - defer readAndCloseBody(resp.body) - return checkRespCode(resp.statusCode, []int{http.StatusCreated}) -} - -// CreateIfNotExists creates a blob container if it does not exist. Returns -// true if container is newly created or false if container already exists. -func (c *Container) CreateIfNotExists() (bool, error) { - resp, err := c.create() - if resp != nil { - defer readAndCloseBody(resp.body) - if resp.statusCode == http.StatusCreated || resp.statusCode == http.StatusConflict { - return resp.statusCode == http.StatusCreated, nil - } - } - return false, err -} - -func (c *Container) create() (*storageResponse, error) { - uri := c.bsc.client.getEndpoint(blobServiceName, c.buildPath(), url.Values{"restype": {"container"}}) - headers := c.bsc.client.getStandardHeaders() - return c.bsc.client.exec(http.MethodPut, uri, headers, nil, c.bsc.auth) -} - -// Exists returns true if a container with given name exists -// on the storage account, otherwise returns false. -func (c *Container) Exists() (bool, error) { - uri := c.bsc.client.getEndpoint(blobServiceName, c.buildPath(), url.Values{"restype": {"container"}}) - headers := c.bsc.client.getStandardHeaders() - - resp, err := c.bsc.client.exec(http.MethodHead, uri, headers, nil, c.bsc.auth) - if resp != nil { - defer readAndCloseBody(resp.body) - if resp.statusCode == http.StatusOK || resp.statusCode == http.StatusNotFound { - return resp.statusCode == http.StatusOK, nil - } - } - return false, err -} - -// SetPermissions sets up container permissions as per https://msdn.microsoft.com/en-us/library/azure/dd179391.aspx -func (c *Container) SetPermissions(permissions ContainerPermissions, timeout int, leaseID string) error { - params := url.Values{ - "restype": {"container"}, - "comp": {"acl"}, - } - - if timeout > 0 { - params.Add("timeout", strconv.Itoa(timeout)) - } - - uri := c.bsc.client.getEndpoint(blobServiceName, c.buildPath(), params) - headers := c.bsc.client.getStandardHeaders() - if permissions.AccessType != "" { - headers[ContainerAccessHeader] = string(permissions.AccessType) - } - - if leaseID != "" { - headers[headerLeaseID] = leaseID - } - - body, length, err := generateContainerACLpayload(permissions.AccessPolicies) - headers["Content-Length"] = strconv.Itoa(length) - - resp, err := c.bsc.client.exec(http.MethodPut, uri, headers, body, c.bsc.auth) - if err != nil { - return err - } - defer readAndCloseBody(resp.body) - - if err := checkRespCode(resp.statusCode, []int{http.StatusOK}); err != nil { - return errors.New("Unable to set permissions") - } - - return nil -} - -// GetPermissions gets the container permissions as per https://msdn.microsoft.com/en-us/library/azure/dd179469.aspx -// If timeout is 0 then it will not be passed to Azure -// leaseID will only be passed to Azure if populated -func (c *Container) GetPermissions(timeout int, leaseID string) (*ContainerPermissions, error) { - params := url.Values{ - "restype": {"container"}, - "comp": {"acl"}, - } - - if timeout > 0 { - params.Add("timeout", strconv.Itoa(timeout)) - } - - uri := c.bsc.client.getEndpoint(blobServiceName, c.buildPath(), params) - headers := c.bsc.client.getStandardHeaders() - - if leaseID != "" { - headers[headerLeaseID] = leaseID - } - - resp, err := c.bsc.client.exec(http.MethodGet, uri, headers, nil, c.bsc.auth) - if err != nil { - return nil, err - } - defer resp.body.Close() - - var ap AccessPolicy - err = xmlUnmarshal(resp.body, &ap.SignedIdentifiersList) - if err != nil { - return nil, err - } - return buildAccessPolicy(ap, &resp.headers), nil -} - -func buildAccessPolicy(ap AccessPolicy, headers *http.Header) *ContainerPermissions { - // containerAccess. Blob, Container, empty - containerAccess := headers.Get(http.CanonicalHeaderKey(ContainerAccessHeader)) - permissions := ContainerPermissions{ - AccessType: ContainerAccessType(containerAccess), - AccessPolicies: []ContainerAccessPolicy{}, - } - - for _, policy := range ap.SignedIdentifiersList.SignedIdentifiers { - capd := ContainerAccessPolicy{ - ID: policy.ID, - StartTime: policy.AccessPolicy.StartTime, - ExpiryTime: policy.AccessPolicy.ExpiryTime, - } - capd.CanRead = updatePermissions(policy.AccessPolicy.Permission, "r") - capd.CanWrite = updatePermissions(policy.AccessPolicy.Permission, "w") - capd.CanDelete = updatePermissions(policy.AccessPolicy.Permission, "d") - - permissions.AccessPolicies = append(permissions.AccessPolicies, capd) - } - return &permissions -} - -// Delete deletes the container with given name on the storage -// account. If the container does not exist returns error. -// -// See https://msdn.microsoft.com/en-us/library/azure/dd179408.aspx -func (c *Container) Delete() error { - resp, err := c.delete() - if err != nil { - return err - } - defer readAndCloseBody(resp.body) - return checkRespCode(resp.statusCode, []int{http.StatusAccepted}) -} - -// DeleteIfExists deletes the container with given name on the storage -// account if it exists. Returns true if container is deleted with this call, or -// false if the container did not exist at the time of the Delete Container -// operation. -// -// See https://msdn.microsoft.com/en-us/library/azure/dd179408.aspx -func (c *Container) DeleteIfExists() (bool, error) { - resp, err := c.delete() - if resp != nil { - defer readAndCloseBody(resp.body) - if resp.statusCode == http.StatusAccepted || resp.statusCode == http.StatusNotFound { - return resp.statusCode == http.StatusAccepted, nil - } - } - return false, err -} - -func (c *Container) delete() (*storageResponse, error) { - uri := c.bsc.client.getEndpoint(blobServiceName, c.buildPath(), url.Values{"restype": {"container"}}) - headers := c.bsc.client.getStandardHeaders() - return c.bsc.client.exec(http.MethodDelete, uri, headers, nil, c.bsc.auth) -} - -// ListBlobs returns an object that contains list of blobs in the container, -// pagination token and other information in the response of List Blobs call. -// -// See https://msdn.microsoft.com/en-us/library/azure/dd135734.aspx -func (c *Container) ListBlobs(params ListBlobsParameters) (BlobListResponse, error) { - q := mergeParams(params.getParameters(), url.Values{ - "restype": {"container"}, - "comp": {"list"}}, - ) - uri := c.bsc.client.getEndpoint(blobServiceName, c.buildPath(), q) - headers := c.bsc.client.getStandardHeaders() - - var out BlobListResponse - resp, err := c.bsc.client.exec(http.MethodGet, uri, headers, nil, c.bsc.auth) - if err != nil { - return out, err - } - defer resp.body.Close() - - err = xmlUnmarshal(resp.body, &out) - return out, err -} - -func generateContainerACLpayload(policies []ContainerAccessPolicy) (io.Reader, int, error) { - sil := SignedIdentifiers{ - SignedIdentifiers: []SignedIdentifier{}, - } - for _, capd := range policies { - permission := capd.generateContainerPermissions() - signedIdentifier := convertAccessPolicyToXMLStructs(capd.ID, capd.StartTime, capd.ExpiryTime, permission) - sil.SignedIdentifiers = append(sil.SignedIdentifiers, signedIdentifier) - } - return xmlMarshal(sil) -} - -func (capd *ContainerAccessPolicy) generateContainerPermissions() (permissions string) { - // generate the permissions string (rwd). - // still want the end user API to have bool flags. - permissions = "" - - if capd.CanRead { - permissions += "r" - } - - if capd.CanWrite { - permissions += "w" - } - - if capd.CanDelete { - permissions += "d" - } - - return permissions -} diff --git a/vendor/github.com/Azure/azure-storage-go/directory.go b/vendor/github.com/Azure/azure-storage-go/directory.go deleted file mode 100644 index d27e62079a..0000000000 --- a/vendor/github.com/Azure/azure-storage-go/directory.go +++ /dev/null @@ -1,217 +0,0 @@ -package storage - -import ( - "encoding/xml" - "net/http" - "net/url" -) - -// Directory represents a directory on a share. -type Directory struct { - fsc *FileServiceClient - Metadata map[string]string - Name string `xml:"Name"` - parent *Directory - Properties DirectoryProperties - share *Share -} - -// DirectoryProperties contains various properties of a directory. -type DirectoryProperties struct { - LastModified string `xml:"Last-Modified"` - Etag string `xml:"Etag"` -} - -// ListDirsAndFilesParameters defines the set of customizable parameters to -// make a List Files and Directories call. -// -// See https://msdn.microsoft.com/en-us/library/azure/dn166980.aspx -type ListDirsAndFilesParameters struct { - Marker string - MaxResults uint - Timeout uint -} - -// DirsAndFilesListResponse contains the response fields from -// a List Files and Directories call. -// -// See https://msdn.microsoft.com/en-us/library/azure/dn166980.aspx -type DirsAndFilesListResponse struct { - XMLName xml.Name `xml:"EnumerationResults"` - Xmlns string `xml:"xmlns,attr"` - Marker string `xml:"Marker"` - MaxResults int64 `xml:"MaxResults"` - Directories []Directory `xml:"Entries>Directory"` - Files []File `xml:"Entries>File"` - NextMarker string `xml:"NextMarker"` -} - -// builds the complete directory path for this directory object. -func (d *Directory) buildPath() string { - path := "" - current := d - for current.Name != "" { - path = "/" + current.Name + path - current = current.parent - } - return d.share.buildPath() + path -} - -// Create this directory in the associated share. -// If a directory with the same name already exists, the operation fails. -// -// See https://msdn.microsoft.com/en-us/library/azure/dn166993.aspx -func (d *Directory) Create() error { - // if this is the root directory exit early - if d.parent == nil { - return nil - } - - headers, err := d.fsc.createResource(d.buildPath(), resourceDirectory, nil, mergeMDIntoExtraHeaders(d.Metadata, nil), []int{http.StatusCreated}) - if err != nil { - return err - } - - d.updateEtagAndLastModified(headers) - return nil -} - -// CreateIfNotExists creates this directory under the associated share if the -// directory does not exists. Returns true if the directory is newly created or -// false if the directory already exists. -// -// See https://msdn.microsoft.com/en-us/library/azure/dn166993.aspx -func (d *Directory) CreateIfNotExists() (bool, error) { - // if this is the root directory exit early - if d.parent == nil { - return false, nil - } - - resp, err := d.fsc.createResourceNoClose(d.buildPath(), resourceDirectory, nil, nil) - if resp != nil { - defer readAndCloseBody(resp.body) - if resp.statusCode == http.StatusCreated || resp.statusCode == http.StatusConflict { - if resp.statusCode == http.StatusCreated { - d.updateEtagAndLastModified(resp.headers) - return true, nil - } - - return false, d.FetchAttributes() - } - } - - return false, err -} - -// Delete removes this directory. It must be empty in order to be deleted. -// If the directory does not exist the operation fails. -// -// See https://msdn.microsoft.com/en-us/library/azure/dn166969.aspx -func (d *Directory) Delete() error { - return d.fsc.deleteResource(d.buildPath(), resourceDirectory) -} - -// DeleteIfExists removes this directory if it exists. -// -// See https://msdn.microsoft.com/en-us/library/azure/dn166969.aspx -func (d *Directory) DeleteIfExists() (bool, error) { - resp, err := d.fsc.deleteResourceNoClose(d.buildPath(), resourceDirectory) - if resp != nil { - defer readAndCloseBody(resp.body) - if resp.statusCode == http.StatusAccepted || resp.statusCode == http.StatusNotFound { - return resp.statusCode == http.StatusAccepted, nil - } - } - return false, err -} - -// Exists returns true if this directory exists. -func (d *Directory) Exists() (bool, error) { - exists, headers, err := d.fsc.resourceExists(d.buildPath(), resourceDirectory) - if exists { - d.updateEtagAndLastModified(headers) - } - return exists, err -} - -// FetchAttributes retrieves metadata for this directory. -func (d *Directory) FetchAttributes() error { - headers, err := d.fsc.getResourceHeaders(d.buildPath(), compNone, resourceDirectory, http.MethodHead) - if err != nil { - return err - } - - d.updateEtagAndLastModified(headers) - d.Metadata = getMetadataFromHeaders(headers) - - return nil -} - -// GetDirectoryReference returns a child Directory object for this directory. -func (d *Directory) GetDirectoryReference(name string) *Directory { - return &Directory{ - fsc: d.fsc, - Name: name, - parent: d, - share: d.share, - } -} - -// GetFileReference returns a child File object for this directory. -func (d *Directory) GetFileReference(name string) *File { - return &File{ - fsc: d.fsc, - Name: name, - parent: d, - share: d.share, - } -} - -// ListDirsAndFiles returns a list of files and directories under this directory. -// It also contains a pagination token and other response details. -// -// See https://msdn.microsoft.com/en-us/library/azure/dn166980.aspx -func (d *Directory) ListDirsAndFiles(params ListDirsAndFilesParameters) (*DirsAndFilesListResponse, error) { - q := mergeParams(params.getParameters(), getURLInitValues(compList, resourceDirectory)) - - resp, err := d.fsc.listContent(d.buildPath(), q, nil) - if err != nil { - return nil, err - } - - defer resp.body.Close() - var out DirsAndFilesListResponse - err = xmlUnmarshal(resp.body, &out) - return &out, err -} - -// SetMetadata replaces the metadata for this directory. -// -// Some keys may be converted to Camel-Case before sending. All keys -// are returned in lower case by GetDirectoryMetadata. HTTP header names -// are case-insensitive so case munging should not matter to other -// applications either. -// -// See https://msdn.microsoft.com/en-us/library/azure/mt427370.aspx -func (d *Directory) SetMetadata() error { - headers, err := d.fsc.setResourceHeaders(d.buildPath(), compMetadata, resourceDirectory, mergeMDIntoExtraHeaders(d.Metadata, nil)) - if err != nil { - return err - } - - d.updateEtagAndLastModified(headers) - return nil -} - -// updates Etag and last modified date -func (d *Directory) updateEtagAndLastModified(headers http.Header) { - d.Properties.Etag = headers.Get("Etag") - d.Properties.LastModified = headers.Get("Last-Modified") -} - -// URL gets the canonical URL to this directory. -// This method does not create a publicly accessible URL if the directory -// is private and this method does not check if the directory exists. -func (d *Directory) URL() string { - return d.fsc.client.getEndpoint(fileServiceName, d.buildPath(), url.Values{}) -} diff --git a/vendor/github.com/Azure/azure-storage-go/file.go b/vendor/github.com/Azure/azure-storage-go/file.go deleted file mode 100644 index e4901a1144..0000000000 --- a/vendor/github.com/Azure/azure-storage-go/file.go +++ /dev/null @@ -1,412 +0,0 @@ -package storage - -import ( - "errors" - "fmt" - "io" - "io/ioutil" - "net/http" - "net/url" - "strconv" -) - -const fourMB = uint64(4194304) -const oneTB = uint64(1099511627776) - -// File represents a file on a share. -type File struct { - fsc *FileServiceClient - Metadata map[string]string - Name string `xml:"Name"` - parent *Directory - Properties FileProperties `xml:"Properties"` - share *Share - FileCopyProperties FileCopyState -} - -// FileProperties contains various properties of a file. -type FileProperties struct { - CacheControl string `header:"x-ms-cache-control"` - Disposition string `header:"x-ms-content-disposition"` - Encoding string `header:"x-ms-content-encoding"` - Etag string - Language string `header:"x-ms-content-language"` - LastModified string - Length uint64 `xml:"Content-Length"` - MD5 string `header:"x-ms-content-md5"` - Type string `header:"x-ms-content-type"` -} - -// FileCopyState contains various properties of a file copy operation. -type FileCopyState struct { - CompletionTime string - ID string `header:"x-ms-copy-id"` - Progress string - Source string - Status string `header:"x-ms-copy-status"` - StatusDesc string -} - -// FileStream contains file data returned from a call to GetFile. -type FileStream struct { - Body io.ReadCloser - ContentMD5 string -} - -// FileRequestOptions will be passed to misc file operations. -// Currently just Timeout (in seconds) but will expand. -type FileRequestOptions struct { - Timeout uint // timeout duration in seconds. -} - -// getParameters, construct parameters for FileRequestOptions. -// currently only timeout, but expecting to grow as functionality fills out. -func (p FileRequestOptions) getParameters() url.Values { - out := url.Values{} - - if p.Timeout != 0 { - out.Set("timeout", fmt.Sprintf("%v", p.Timeout)) - } - - return out -} - -// FileRanges contains a list of file range information for a file. -// -// See https://msdn.microsoft.com/en-us/library/azure/dn166984.aspx -type FileRanges struct { - ContentLength uint64 - LastModified string - ETag string - FileRanges []FileRange `xml:"Range"` -} - -// FileRange contains range information for a file. -// -// See https://msdn.microsoft.com/en-us/library/azure/dn166984.aspx -type FileRange struct { - Start uint64 `xml:"Start"` - End uint64 `xml:"End"` -} - -func (fr FileRange) String() string { - return fmt.Sprintf("bytes=%d-%d", fr.Start, fr.End) -} - -// builds the complete file path for this file object -func (f *File) buildPath() string { - return f.parent.buildPath() + "/" + f.Name -} - -// ClearRange releases the specified range of space in a file. -// -// See https://msdn.microsoft.com/en-us/library/azure/dn194276.aspx -func (f *File) ClearRange(fileRange FileRange) error { - headers, err := f.modifyRange(nil, fileRange, nil) - if err != nil { - return err - } - - f.updateEtagAndLastModified(headers) - return nil -} - -// Create creates a new file or replaces an existing one. -// -// See https://msdn.microsoft.com/en-us/library/azure/dn194271.aspx -func (f *File) Create(maxSize uint64) error { - if maxSize > oneTB { - return fmt.Errorf("max file size is 1TB") - } - - extraHeaders := map[string]string{ - "x-ms-content-length": strconv.FormatUint(maxSize, 10), - "x-ms-type": "file", - } - - headers, err := f.fsc.createResource(f.buildPath(), resourceFile, nil, mergeMDIntoExtraHeaders(f.Metadata, extraHeaders), []int{http.StatusCreated}) - if err != nil { - return err - } - - f.Properties.Length = maxSize - f.updateEtagAndLastModified(headers) - return nil -} - -// CopyFile operation copied a file/blob from the sourceURL to the path provided. -// -// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/copy-file -func (f *File) CopyFile(sourceURL string, options *FileRequestOptions) error { - extraHeaders := map[string]string{ - "x-ms-type": "file", - "x-ms-copy-source": sourceURL, - } - - var parameters url.Values - if options != nil { - parameters = options.getParameters() - } - - headers, err := f.fsc.createResource(f.buildPath(), resourceFile, parameters, mergeMDIntoExtraHeaders(f.Metadata, extraHeaders), []int{http.StatusAccepted}) - if err != nil { - return err - } - - f.updateEtagLastModifiedAndCopyHeaders(headers) - return nil -} - -// Delete immediately removes this file from the storage account. -// -// See https://msdn.microsoft.com/en-us/library/azure/dn689085.aspx -func (f *File) Delete() error { - return f.fsc.deleteResource(f.buildPath(), resourceFile) -} - -// DeleteIfExists removes this file if it exists. -// -// See https://msdn.microsoft.com/en-us/library/azure/dn689085.aspx -func (f *File) DeleteIfExists() (bool, error) { - resp, err := f.fsc.deleteResourceNoClose(f.buildPath(), resourceFile) - if resp != nil { - defer readAndCloseBody(resp.body) - if resp.statusCode == http.StatusAccepted || resp.statusCode == http.StatusNotFound { - return resp.statusCode == http.StatusAccepted, nil - } - } - return false, err -} - -// DownloadRangeToStream operation downloads the specified range of this file with optional MD5 hash. -// -// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/get-file -func (f *File) DownloadRangeToStream(fileRange FileRange, getContentMD5 bool) (fs FileStream, err error) { - if getContentMD5 && isRangeTooBig(fileRange) { - return fs, fmt.Errorf("must specify a range less than or equal to 4MB when getContentMD5 is true") - } - - extraHeaders := map[string]string{ - "Range": fileRange.String(), - } - if getContentMD5 == true { - extraHeaders["x-ms-range-get-content-md5"] = "true" - } - - resp, err := f.fsc.getResourceNoClose(f.buildPath(), compNone, resourceFile, http.MethodGet, extraHeaders) - if err != nil { - return fs, err - } - - if err = checkRespCode(resp.statusCode, []int{http.StatusOK, http.StatusPartialContent}); err != nil { - resp.body.Close() - return fs, err - } - - fs.Body = resp.body - if getContentMD5 { - fs.ContentMD5 = resp.headers.Get("Content-MD5") - } - return fs, nil -} - -// Exists returns true if this file exists. -func (f *File) Exists() (bool, error) { - exists, headers, err := f.fsc.resourceExists(f.buildPath(), resourceFile) - if exists { - f.updateEtagAndLastModified(headers) - f.updateProperties(headers) - } - return exists, err -} - -// FetchAttributes updates metadata and properties for this file. -func (f *File) FetchAttributes() error { - headers, err := f.fsc.getResourceHeaders(f.buildPath(), compNone, resourceFile, http.MethodHead) - if err != nil { - return err - } - - f.updateEtagAndLastModified(headers) - f.updateProperties(headers) - f.Metadata = getMetadataFromHeaders(headers) - return nil -} - -// returns true if the range is larger than 4MB -func isRangeTooBig(fileRange FileRange) bool { - if fileRange.End-fileRange.Start > fourMB { - return true - } - - return false -} - -// ListRanges returns the list of valid ranges for this file. -// -// See https://msdn.microsoft.com/en-us/library/azure/dn166984.aspx -func (f *File) ListRanges(listRange *FileRange) (*FileRanges, error) { - params := url.Values{"comp": {"rangelist"}} - - // add optional range to list - var headers map[string]string - if listRange != nil { - headers = make(map[string]string) - headers["Range"] = listRange.String() - } - - resp, err := f.fsc.listContent(f.buildPath(), params, headers) - if err != nil { - return nil, err - } - - defer resp.body.Close() - var cl uint64 - cl, err = strconv.ParseUint(resp.headers.Get("x-ms-content-length"), 10, 64) - if err != nil { - ioutil.ReadAll(resp.body) - return nil, err - } - - var out FileRanges - out.ContentLength = cl - out.ETag = resp.headers.Get("ETag") - out.LastModified = resp.headers.Get("Last-Modified") - - err = xmlUnmarshal(resp.body, &out) - return &out, err -} - -// modifies a range of bytes in this file -func (f *File) modifyRange(bytes io.Reader, fileRange FileRange, contentMD5 *string) (http.Header, error) { - if err := f.fsc.checkForStorageEmulator(); err != nil { - return nil, err - } - if fileRange.End < fileRange.Start { - return nil, errors.New("the value for rangeEnd must be greater than or equal to rangeStart") - } - if bytes != nil && isRangeTooBig(fileRange) { - return nil, errors.New("range cannot exceed 4MB in size") - } - - uri := f.fsc.client.getEndpoint(fileServiceName, f.buildPath(), url.Values{"comp": {"range"}}) - - // default to clear - write := "clear" - cl := uint64(0) - - // if bytes is not nil then this is an update operation - if bytes != nil { - write = "update" - cl = (fileRange.End - fileRange.Start) + 1 - } - - extraHeaders := map[string]string{ - "Content-Length": strconv.FormatUint(cl, 10), - "Range": fileRange.String(), - "x-ms-write": write, - } - - if contentMD5 != nil { - extraHeaders["Content-MD5"] = *contentMD5 - } - - headers := mergeHeaders(f.fsc.client.getStandardHeaders(), extraHeaders) - resp, err := f.fsc.client.exec(http.MethodPut, uri, headers, bytes, f.fsc.auth) - if err != nil { - return nil, err - } - defer readAndCloseBody(resp.body) - return resp.headers, checkRespCode(resp.statusCode, []int{http.StatusCreated}) -} - -// SetMetadata replaces the metadata for this file. -// -// Some keys may be converted to Camel-Case before sending. All keys -// are returned in lower case by GetFileMetadata. HTTP header names -// are case-insensitive so case munging should not matter to other -// applications either. -// -// See https://msdn.microsoft.com/en-us/library/azure/dn689097.aspx -func (f *File) SetMetadata() error { - headers, err := f.fsc.setResourceHeaders(f.buildPath(), compMetadata, resourceFile, mergeMDIntoExtraHeaders(f.Metadata, nil)) - if err != nil { - return err - } - - f.updateEtagAndLastModified(headers) - return nil -} - -// SetProperties sets system properties on this file. -// -// Some keys may be converted to Camel-Case before sending. All keys -// are returned in lower case by SetFileProperties. HTTP header names -// are case-insensitive so case munging should not matter to other -// applications either. -// -// See https://msdn.microsoft.com/en-us/library/azure/dn166975.aspx -func (f *File) SetProperties() error { - headers, err := f.fsc.setResourceHeaders(f.buildPath(), compProperties, resourceFile, headersFromStruct(f.Properties)) - if err != nil { - return err - } - - f.updateEtagAndLastModified(headers) - return nil -} - -// updates Etag and last modified date -func (f *File) updateEtagAndLastModified(headers http.Header) { - f.Properties.Etag = headers.Get("Etag") - f.Properties.LastModified = headers.Get("Last-Modified") -} - -// updates Etag, last modified date and x-ms-copy-id -func (f *File) updateEtagLastModifiedAndCopyHeaders(headers http.Header) { - f.Properties.Etag = headers.Get("Etag") - f.Properties.LastModified = headers.Get("Last-Modified") - f.FileCopyProperties.ID = headers.Get("X-Ms-Copy-Id") - f.FileCopyProperties.Status = headers.Get("X-Ms-Copy-Status") -} - -// updates file properties from the specified HTTP header -func (f *File) updateProperties(header http.Header) { - size, err := strconv.ParseUint(header.Get("Content-Length"), 10, 64) - if err == nil { - f.Properties.Length = size - } - - f.updateEtagAndLastModified(header) - f.Properties.CacheControl = header.Get("Cache-Control") - f.Properties.Disposition = header.Get("Content-Disposition") - f.Properties.Encoding = header.Get("Content-Encoding") - f.Properties.Language = header.Get("Content-Language") - f.Properties.MD5 = header.Get("Content-MD5") - f.Properties.Type = header.Get("Content-Type") -} - -// URL gets the canonical URL to this file. -// This method does not create a publicly accessible URL if the file -// is private and this method does not check if the file exists. -func (f *File) URL() string { - return f.fsc.client.getEndpoint(fileServiceName, f.buildPath(), url.Values{}) -} - -// WriteRange writes a range of bytes to this file with an optional MD5 hash of the content. -// Note that the length of bytes must match (rangeEnd - rangeStart) + 1 with a maximum size of 4MB. -// -// See https://msdn.microsoft.com/en-us/library/azure/dn194276.aspx -func (f *File) WriteRange(bytes io.Reader, fileRange FileRange, contentMD5 *string) error { - if bytes == nil { - return errors.New("bytes cannot be nil") - } - - headers, err := f.modifyRange(bytes, fileRange, contentMD5) - if err != nil { - return err - } - - f.updateEtagAndLastModified(headers) - return nil -} diff --git a/vendor/github.com/Azure/azure-storage-go/fileserviceclient.go b/vendor/github.com/Azure/azure-storage-go/fileserviceclient.go deleted file mode 100644 index d68bd7f64e..0000000000 --- a/vendor/github.com/Azure/azure-storage-go/fileserviceclient.go +++ /dev/null @@ -1,375 +0,0 @@ -package storage - -import ( - "encoding/xml" - "fmt" - "net/http" - "net/url" - "strings" -) - -// FileServiceClient contains operations for Microsoft Azure File Service. -type FileServiceClient struct { - client Client - auth authentication -} - -// ListSharesParameters defines the set of customizable parameters to make a -// List Shares call. -// -// See https://msdn.microsoft.com/en-us/library/azure/dn167009.aspx -type ListSharesParameters struct { - Prefix string - Marker string - Include string - MaxResults uint - Timeout uint -} - -// ShareListResponse contains the response fields from -// ListShares call. -// -// See https://msdn.microsoft.com/en-us/library/azure/dn167009.aspx -type ShareListResponse struct { - XMLName xml.Name `xml:"EnumerationResults"` - Xmlns string `xml:"xmlns,attr"` - Prefix string `xml:"Prefix"` - Marker string `xml:"Marker"` - NextMarker string `xml:"NextMarker"` - MaxResults int64 `xml:"MaxResults"` - Shares []Share `xml:"Shares>Share"` -} - -type compType string - -const ( - compNone compType = "" - compList compType = "list" - compMetadata compType = "metadata" - compProperties compType = "properties" - compRangeList compType = "rangelist" -) - -func (ct compType) String() string { - return string(ct) -} - -type resourceType string - -const ( - resourceDirectory resourceType = "directory" - resourceFile resourceType = "" - resourceShare resourceType = "share" -) - -func (rt resourceType) String() string { - return string(rt) -} - -func (p ListSharesParameters) getParameters() url.Values { - out := url.Values{} - - if p.Prefix != "" { - out.Set("prefix", p.Prefix) - } - if p.Marker != "" { - out.Set("marker", p.Marker) - } - if p.Include != "" { - out.Set("include", p.Include) - } - if p.MaxResults != 0 { - out.Set("maxresults", fmt.Sprintf("%v", p.MaxResults)) - } - if p.Timeout != 0 { - out.Set("timeout", fmt.Sprintf("%v", p.Timeout)) - } - - return out -} - -func (p ListDirsAndFilesParameters) getParameters() url.Values { - out := url.Values{} - - if p.Marker != "" { - out.Set("marker", p.Marker) - } - if p.MaxResults != 0 { - out.Set("maxresults", fmt.Sprintf("%v", p.MaxResults)) - } - if p.Timeout != 0 { - out.Set("timeout", fmt.Sprintf("%v", p.Timeout)) - } - - return out -} - -// returns url.Values for the specified types -func getURLInitValues(comp compType, res resourceType) url.Values { - values := url.Values{} - if comp != compNone { - values.Set("comp", comp.String()) - } - if res != resourceFile { - values.Set("restype", res.String()) - } - return values -} - -// GetShareReference returns a Share object for the specified share name. -func (f FileServiceClient) GetShareReference(name string) Share { - return Share{ - fsc: &f, - Name: name, - Properties: ShareProperties{ - Quota: -1, - }, - } -} - -// ListShares returns the list of shares in a storage account along with -// pagination token and other response details. -// -// See https://msdn.microsoft.com/en-us/library/azure/dd179352.aspx -func (f FileServiceClient) ListShares(params ListSharesParameters) (*ShareListResponse, error) { - q := mergeParams(params.getParameters(), url.Values{"comp": {"list"}}) - - var out ShareListResponse - resp, err := f.listContent("", q, nil) - if err != nil { - return nil, err - } - defer resp.body.Close() - err = xmlUnmarshal(resp.body, &out) - - // assign our client to the newly created Share objects - for i := range out.Shares { - out.Shares[i].fsc = &f - } - return &out, err -} - -// GetServiceProperties gets the properties of your storage account's file service. -// File service does not support logging -// See: https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/get-file-service-properties -func (f *FileServiceClient) GetServiceProperties() (*ServiceProperties, error) { - return f.client.getServiceProperties(fileServiceName, f.auth) -} - -// SetServiceProperties sets the properties of your storage account's file service. -// File service does not support logging -// See: https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/set-file-service-properties -func (f *FileServiceClient) SetServiceProperties(props ServiceProperties) error { - return f.client.setServiceProperties(props, fileServiceName, f.auth) -} - -// retrieves directory or share content -func (f FileServiceClient) listContent(path string, params url.Values, extraHeaders map[string]string) (*storageResponse, error) { - if err := f.checkForStorageEmulator(); err != nil { - return nil, err - } - - uri := f.client.getEndpoint(fileServiceName, path, params) - extraHeaders = f.client.protectUserAgent(extraHeaders) - headers := mergeHeaders(f.client.getStandardHeaders(), extraHeaders) - - resp, err := f.client.exec(http.MethodGet, uri, headers, nil, f.auth) - if err != nil { - return nil, err - } - - if err = checkRespCode(resp.statusCode, []int{http.StatusOK}); err != nil { - readAndCloseBody(resp.body) - return nil, err - } - - return resp, nil -} - -// returns true if the specified resource exists -func (f FileServiceClient) resourceExists(path string, res resourceType) (bool, http.Header, error) { - if err := f.checkForStorageEmulator(); err != nil { - return false, nil, err - } - - uri := f.client.getEndpoint(fileServiceName, path, getURLInitValues(compNone, res)) - headers := f.client.getStandardHeaders() - - resp, err := f.client.exec(http.MethodHead, uri, headers, nil, f.auth) - if resp != nil { - defer readAndCloseBody(resp.body) - if resp.statusCode == http.StatusOK || resp.statusCode == http.StatusNotFound { - return resp.statusCode == http.StatusOK, resp.headers, nil - } - } - return false, nil, err -} - -// creates a resource depending on the specified resource type -func (f FileServiceClient) createResource(path string, res resourceType, urlParams url.Values, extraHeaders map[string]string, expectedResponseCodes []int) (http.Header, error) { - resp, err := f.createResourceNoClose(path, res, urlParams, extraHeaders) - if err != nil { - return nil, err - } - defer readAndCloseBody(resp.body) - return resp.headers, checkRespCode(resp.statusCode, expectedResponseCodes) -} - -// creates a resource depending on the specified resource type, doesn't close the response body -func (f FileServiceClient) createResourceNoClose(path string, res resourceType, urlParams url.Values, extraHeaders map[string]string) (*storageResponse, error) { - if err := f.checkForStorageEmulator(); err != nil { - return nil, err - } - - values := getURLInitValues(compNone, res) - combinedParams := mergeParams(values, urlParams) - uri := f.client.getEndpoint(fileServiceName, path, combinedParams) - extraHeaders = f.client.protectUserAgent(extraHeaders) - headers := mergeHeaders(f.client.getStandardHeaders(), extraHeaders) - - return f.client.exec(http.MethodPut, uri, headers, nil, f.auth) -} - -// returns HTTP header data for the specified directory or share -func (f FileServiceClient) getResourceHeaders(path string, comp compType, res resourceType, verb string) (http.Header, error) { - resp, err := f.getResourceNoClose(path, comp, res, verb, nil) - if err != nil { - return nil, err - } - defer readAndCloseBody(resp.body) - - if err = checkRespCode(resp.statusCode, []int{http.StatusOK}); err != nil { - return nil, err - } - - return resp.headers, nil -} - -// gets the specified resource, doesn't close the response body -func (f FileServiceClient) getResourceNoClose(path string, comp compType, res resourceType, verb string, extraHeaders map[string]string) (*storageResponse, error) { - if err := f.checkForStorageEmulator(); err != nil { - return nil, err - } - - params := getURLInitValues(comp, res) - uri := f.client.getEndpoint(fileServiceName, path, params) - extraHeaders = f.client.protectUserAgent(extraHeaders) - headers := mergeHeaders(f.client.getStandardHeaders(), extraHeaders) - - return f.client.exec(verb, uri, headers, nil, f.auth) -} - -// deletes the resource and returns the response -func (f FileServiceClient) deleteResource(path string, res resourceType) error { - resp, err := f.deleteResourceNoClose(path, res) - if err != nil { - return err - } - defer readAndCloseBody(resp.body) - return checkRespCode(resp.statusCode, []int{http.StatusAccepted}) -} - -// deletes the resource and returns the response, doesn't close the response body -func (f FileServiceClient) deleteResourceNoClose(path string, res resourceType) (*storageResponse, error) { - if err := f.checkForStorageEmulator(); err != nil { - return nil, err - } - - values := getURLInitValues(compNone, res) - uri := f.client.getEndpoint(fileServiceName, path, values) - return f.client.exec(http.MethodDelete, uri, f.client.getStandardHeaders(), nil, f.auth) -} - -// merges metadata into extraHeaders and returns extraHeaders -func mergeMDIntoExtraHeaders(metadata, extraHeaders map[string]string) map[string]string { - if metadata == nil && extraHeaders == nil { - return nil - } - if extraHeaders == nil { - extraHeaders = make(map[string]string) - } - for k, v := range metadata { - extraHeaders[userDefinedMetadataHeaderPrefix+k] = v - } - return extraHeaders -} - -// merges extraHeaders into headers and returns headers -func mergeHeaders(headers, extraHeaders map[string]string) map[string]string { - for k, v := range extraHeaders { - headers[k] = v - } - return headers -} - -// sets extra header data for the specified resource -func (f FileServiceClient) setResourceHeaders(path string, comp compType, res resourceType, extraHeaders map[string]string) (http.Header, error) { - if err := f.checkForStorageEmulator(); err != nil { - return nil, err - } - - params := getURLInitValues(comp, res) - uri := f.client.getEndpoint(fileServiceName, path, params) - extraHeaders = f.client.protectUserAgent(extraHeaders) - headers := mergeHeaders(f.client.getStandardHeaders(), extraHeaders) - - resp, err := f.client.exec(http.MethodPut, uri, headers, nil, f.auth) - if err != nil { - return nil, err - } - defer readAndCloseBody(resp.body) - - return resp.headers, checkRespCode(resp.statusCode, []int{http.StatusOK}) -} - -// gets metadata for the specified resource -func (f FileServiceClient) getMetadata(path string, res resourceType) (map[string]string, error) { - if err := f.checkForStorageEmulator(); err != nil { - return nil, err - } - - headers, err := f.getResourceHeaders(path, compMetadata, res, http.MethodGet) - if err != nil { - return nil, err - } - - return getMetadataFromHeaders(headers), nil -} - -// returns a map of custom metadata values from the specified HTTP header -func getMetadataFromHeaders(header http.Header) map[string]string { - metadata := make(map[string]string) - for k, v := range header { - // Can't trust CanonicalHeaderKey() to munge case - // reliably. "_" is allowed in identifiers: - // https://msdn.microsoft.com/en-us/library/azure/dd179414.aspx - // https://msdn.microsoft.com/library/aa664670(VS.71).aspx - // http://tools.ietf.org/html/rfc7230#section-3.2 - // ...but "_" is considered invalid by - // CanonicalMIMEHeaderKey in - // https://golang.org/src/net/textproto/reader.go?s=14615:14659#L542 - // so k can be "X-Ms-Meta-Foo" or "x-ms-meta-foo_bar". - k = strings.ToLower(k) - if len(v) == 0 || !strings.HasPrefix(k, strings.ToLower(userDefinedMetadataHeaderPrefix)) { - continue - } - // metadata["foo"] = content of the last X-Ms-Meta-Foo header - k = k[len(userDefinedMetadataHeaderPrefix):] - metadata[k] = v[len(v)-1] - } - - if len(metadata) == 0 { - return nil - } - - return metadata -} - -//checkForStorageEmulator determines if the client is setup for use with -//Azure Storage Emulator, and returns a relevant error -func (f FileServiceClient) checkForStorageEmulator() error { - if f.client.accountName == StorageEmulatorAccountName { - return fmt.Errorf("Error: File service is not currently supported by Azure Storage Emulator") - } - return nil -} diff --git a/vendor/github.com/Azure/azure-storage-go/glide.lock b/vendor/github.com/Azure/azure-storage-go/glide.lock deleted file mode 100644 index 5d3ce83618..0000000000 --- a/vendor/github.com/Azure/azure-storage-go/glide.lock +++ /dev/null @@ -1,14 +0,0 @@ -hash: a97c0c90fe4d23bbd8e5745431f633e75530bb611131b786d76b8e1763bce85e -updated: 2017-02-23T09:58:57.3701584-08:00 -imports: -- name: github.com/Azure/go-autorest - version: ec5f4903f77ed9927ac95b19ab8e44ada64c1356 - subpackages: - - autorest/azure - - autorest - - autorest/date -- name: github.com/dgrijalva/jwt-go - version: 2268707a8f0843315e2004ee4f1d021dc08baedf -testImports: -- name: gopkg.in/check.v1 - version: 20d25e2804050c1cd24a7eea1e7a6447dd0e74ec diff --git a/vendor/github.com/Azure/azure-storage-go/glide.yaml b/vendor/github.com/Azure/azure-storage-go/glide.yaml deleted file mode 100644 index e6783b7741..0000000000 --- a/vendor/github.com/Azure/azure-storage-go/glide.yaml +++ /dev/null @@ -1,4 +0,0 @@ -package: github.com/Azure/azure-sdk-for-go-storage -import: [] -testImport: -- package: gopkg.in/check.v1 diff --git a/vendor/github.com/Azure/azure-storage-go/queue.go b/vendor/github.com/Azure/azure-storage-go/queue.go deleted file mode 100644 index 4031410aeb..0000000000 --- a/vendor/github.com/Azure/azure-storage-go/queue.go +++ /dev/null @@ -1,339 +0,0 @@ -package storage - -import ( - "encoding/xml" - "fmt" - "net/http" - "net/url" - "strconv" - "strings" -) - -const ( - // casing is per Golang's http.Header canonicalizing the header names. - approximateMessagesCountHeader = "X-Ms-Approximate-Messages-Count" - userDefinedMetadataHeaderPrefix = "X-Ms-Meta-" -) - -func pathForQueue(queue string) string { return fmt.Sprintf("/%s", queue) } -func pathForQueueMessages(queue string) string { return fmt.Sprintf("/%s/messages", queue) } -func pathForMessage(queue, name string) string { return fmt.Sprintf("/%s/messages/%s", queue, name) } - -type putMessageRequest struct { - XMLName xml.Name `xml:"QueueMessage"` - MessageText string `xml:"MessageText"` -} - -// PutMessageParameters is the set of options can be specified for Put Messsage -// operation. A zero struct does not use any preferences for the request. -type PutMessageParameters struct { - VisibilityTimeout int - MessageTTL int -} - -func (p PutMessageParameters) getParameters() url.Values { - out := url.Values{} - if p.VisibilityTimeout != 0 { - out.Set("visibilitytimeout", strconv.Itoa(p.VisibilityTimeout)) - } - if p.MessageTTL != 0 { - out.Set("messagettl", strconv.Itoa(p.MessageTTL)) - } - return out -} - -// GetMessagesParameters is the set of options can be specified for Get -// Messsages operation. A zero struct does not use any preferences for the -// request. -type GetMessagesParameters struct { - NumOfMessages int - VisibilityTimeout int -} - -func (p GetMessagesParameters) getParameters() url.Values { - out := url.Values{} - if p.NumOfMessages != 0 { - out.Set("numofmessages", strconv.Itoa(p.NumOfMessages)) - } - if p.VisibilityTimeout != 0 { - out.Set("visibilitytimeout", strconv.Itoa(p.VisibilityTimeout)) - } - return out -} - -// PeekMessagesParameters is the set of options can be specified for Peek -// Messsage operation. A zero struct does not use any preferences for the -// request. -type PeekMessagesParameters struct { - NumOfMessages int -} - -func (p PeekMessagesParameters) getParameters() url.Values { - out := url.Values{"peekonly": {"true"}} // Required for peek operation - if p.NumOfMessages != 0 { - out.Set("numofmessages", strconv.Itoa(p.NumOfMessages)) - } - return out -} - -// UpdateMessageParameters is the set of options can be specified for Update Messsage -// operation. A zero struct does not use any preferences for the request. -type UpdateMessageParameters struct { - PopReceipt string - VisibilityTimeout int -} - -func (p UpdateMessageParameters) getParameters() url.Values { - out := url.Values{} - if p.PopReceipt != "" { - out.Set("popreceipt", p.PopReceipt) - } - if p.VisibilityTimeout != 0 { - out.Set("visibilitytimeout", strconv.Itoa(p.VisibilityTimeout)) - } - return out -} - -// GetMessagesResponse represents a response returned from Get Messages -// operation. -type GetMessagesResponse struct { - XMLName xml.Name `xml:"QueueMessagesList"` - QueueMessagesList []GetMessageResponse `xml:"QueueMessage"` -} - -// GetMessageResponse represents a QueueMessage object returned from Get -// Messages operation response. -type GetMessageResponse struct { - MessageID string `xml:"MessageId"` - InsertionTime string `xml:"InsertionTime"` - ExpirationTime string `xml:"ExpirationTime"` - PopReceipt string `xml:"PopReceipt"` - TimeNextVisible string `xml:"TimeNextVisible"` - DequeueCount int `xml:"DequeueCount"` - MessageText string `xml:"MessageText"` -} - -// PeekMessagesResponse represents a response returned from Get Messages -// operation. -type PeekMessagesResponse struct { - XMLName xml.Name `xml:"QueueMessagesList"` - QueueMessagesList []PeekMessageResponse `xml:"QueueMessage"` -} - -// PeekMessageResponse represents a QueueMessage object returned from Peek -// Messages operation response. -type PeekMessageResponse struct { - MessageID string `xml:"MessageId"` - InsertionTime string `xml:"InsertionTime"` - ExpirationTime string `xml:"ExpirationTime"` - DequeueCount int `xml:"DequeueCount"` - MessageText string `xml:"MessageText"` -} - -// QueueMetadataResponse represents user defined metadata and queue -// properties on a specific queue. -// -// See https://msdn.microsoft.com/en-us/library/azure/dd179384.aspx -type QueueMetadataResponse struct { - ApproximateMessageCount int - UserDefinedMetadata map[string]string -} - -// SetMetadata operation sets user-defined metadata on the specified queue. -// Metadata is associated with the queue as name-value pairs. -// -// See https://msdn.microsoft.com/en-us/library/azure/dd179348.aspx -func (c QueueServiceClient) SetMetadata(name string, metadata map[string]string) error { - uri := c.client.getEndpoint(queueServiceName, pathForQueue(name), url.Values{"comp": []string{"metadata"}}) - metadata = c.client.protectUserAgent(metadata) - headers := c.client.getStandardHeaders() - for k, v := range metadata { - headers[userDefinedMetadataHeaderPrefix+k] = v - } - - resp, err := c.client.exec(http.MethodPut, uri, headers, nil, c.auth) - if err != nil { - return err - } - defer readAndCloseBody(resp.body) - - return checkRespCode(resp.statusCode, []int{http.StatusNoContent}) -} - -// GetMetadata operation retrieves user-defined metadata and queue -// properties on the specified queue. Metadata is associated with -// the queue as name-values pairs. -// -// See https://msdn.microsoft.com/en-us/library/azure/dd179384.aspx -// -// Because the way Golang's http client (and http.Header in particular) -// canonicalize header names, the returned metadata names would always -// be all lower case. -func (c QueueServiceClient) GetMetadata(name string) (QueueMetadataResponse, error) { - qm := QueueMetadataResponse{} - qm.UserDefinedMetadata = make(map[string]string) - uri := c.client.getEndpoint(queueServiceName, pathForQueue(name), url.Values{"comp": []string{"metadata"}}) - headers := c.client.getStandardHeaders() - resp, err := c.client.exec(http.MethodGet, uri, headers, nil, c.auth) - if err != nil { - return qm, err - } - defer readAndCloseBody(resp.body) - - for k, v := range resp.headers { - if len(v) != 1 { - return qm, fmt.Errorf("Unexpected number of values (%d) in response header '%s'", len(v), k) - } - - value := v[0] - - if k == approximateMessagesCountHeader { - qm.ApproximateMessageCount, err = strconv.Atoi(value) - if err != nil { - return qm, fmt.Errorf("Unexpected value in response header '%s': '%s' ", k, value) - } - } else if strings.HasPrefix(k, userDefinedMetadataHeaderPrefix) { - name := strings.TrimPrefix(k, userDefinedMetadataHeaderPrefix) - qm.UserDefinedMetadata[strings.ToLower(name)] = value - } - } - - return qm, checkRespCode(resp.statusCode, []int{http.StatusOK}) -} - -// CreateQueue operation creates a queue under the given account. -// -// See https://msdn.microsoft.com/en-us/library/azure/dd179342.aspx -func (c QueueServiceClient) CreateQueue(name string) error { - uri := c.client.getEndpoint(queueServiceName, pathForQueue(name), url.Values{}) - headers := c.client.getStandardHeaders() - resp, err := c.client.exec(http.MethodPut, uri, headers, nil, c.auth) - if err != nil { - return err - } - defer readAndCloseBody(resp.body) - return checkRespCode(resp.statusCode, []int{http.StatusCreated}) -} - -// DeleteQueue operation permanently deletes the specified queue. -// -// See https://msdn.microsoft.com/en-us/library/azure/dd179436.aspx -func (c QueueServiceClient) DeleteQueue(name string) error { - uri := c.client.getEndpoint(queueServiceName, pathForQueue(name), url.Values{}) - resp, err := c.client.exec(http.MethodDelete, uri, c.client.getStandardHeaders(), nil, c.auth) - if err != nil { - return err - } - defer readAndCloseBody(resp.body) - return checkRespCode(resp.statusCode, []int{http.StatusNoContent}) -} - -// QueueExists returns true if a queue with given name exists. -func (c QueueServiceClient) QueueExists(name string) (bool, error) { - uri := c.client.getEndpoint(queueServiceName, pathForQueue(name), url.Values{"comp": {"metadata"}}) - resp, err := c.client.exec(http.MethodGet, uri, c.client.getStandardHeaders(), nil, c.auth) - if resp != nil && (resp.statusCode == http.StatusOK || resp.statusCode == http.StatusNotFound) { - return resp.statusCode == http.StatusOK, nil - } - - return false, err -} - -// PutMessage operation adds a new message to the back of the message queue. -// -// See https://msdn.microsoft.com/en-us/library/azure/dd179346.aspx -func (c QueueServiceClient) PutMessage(queue string, message string, params PutMessageParameters) error { - uri := c.client.getEndpoint(queueServiceName, pathForQueueMessages(queue), params.getParameters()) - req := putMessageRequest{MessageText: message} - body, nn, err := xmlMarshal(req) - if err != nil { - return err - } - headers := c.client.getStandardHeaders() - headers["Content-Length"] = strconv.Itoa(nn) - resp, err := c.client.exec(http.MethodPost, uri, headers, body, c.auth) - if err != nil { - return err - } - defer readAndCloseBody(resp.body) - return checkRespCode(resp.statusCode, []int{http.StatusCreated}) -} - -// ClearMessages operation deletes all messages from the specified queue. -// -// See https://msdn.microsoft.com/en-us/library/azure/dd179454.aspx -func (c QueueServiceClient) ClearMessages(queue string) error { - uri := c.client.getEndpoint(queueServiceName, pathForQueueMessages(queue), url.Values{}) - resp, err := c.client.exec(http.MethodDelete, uri, c.client.getStandardHeaders(), nil, c.auth) - if err != nil { - return err - } - defer readAndCloseBody(resp.body) - return checkRespCode(resp.statusCode, []int{http.StatusNoContent}) -} - -// GetMessages operation retrieves one or more messages from the front of the -// queue. -// -// See https://msdn.microsoft.com/en-us/library/azure/dd179474.aspx -func (c QueueServiceClient) GetMessages(queue string, params GetMessagesParameters) (GetMessagesResponse, error) { - var r GetMessagesResponse - uri := c.client.getEndpoint(queueServiceName, pathForQueueMessages(queue), params.getParameters()) - resp, err := c.client.exec(http.MethodGet, uri, c.client.getStandardHeaders(), nil, c.auth) - if err != nil { - return r, err - } - defer resp.body.Close() - err = xmlUnmarshal(resp.body, &r) - return r, err -} - -// PeekMessages retrieves one or more messages from the front of the queue, but -// does not alter the visibility of the message. -// -// See https://msdn.microsoft.com/en-us/library/azure/dd179472.aspx -func (c QueueServiceClient) PeekMessages(queue string, params PeekMessagesParameters) (PeekMessagesResponse, error) { - var r PeekMessagesResponse - uri := c.client.getEndpoint(queueServiceName, pathForQueueMessages(queue), params.getParameters()) - resp, err := c.client.exec(http.MethodGet, uri, c.client.getStandardHeaders(), nil, c.auth) - if err != nil { - return r, err - } - defer resp.body.Close() - err = xmlUnmarshal(resp.body, &r) - return r, err -} - -// DeleteMessage operation deletes the specified message. -// -// See https://msdn.microsoft.com/en-us/library/azure/dd179347.aspx -func (c QueueServiceClient) DeleteMessage(queue, messageID, popReceipt string) error { - uri := c.client.getEndpoint(queueServiceName, pathForMessage(queue, messageID), url.Values{ - "popreceipt": {popReceipt}}) - resp, err := c.client.exec(http.MethodDelete, uri, c.client.getStandardHeaders(), nil, c.auth) - if err != nil { - return err - } - defer readAndCloseBody(resp.body) - return checkRespCode(resp.statusCode, []int{http.StatusNoContent}) -} - -// UpdateMessage operation deletes the specified message. -// -// See https://msdn.microsoft.com/en-us/library/azure/hh452234.aspx -func (c QueueServiceClient) UpdateMessage(queue string, messageID string, message string, params UpdateMessageParameters) error { - uri := c.client.getEndpoint(queueServiceName, pathForMessage(queue, messageID), params.getParameters()) - req := putMessageRequest{MessageText: message} - body, nn, err := xmlMarshal(req) - if err != nil { - return err - } - headers := c.client.getStandardHeaders() - headers["Content-Length"] = fmt.Sprintf("%d", nn) - resp, err := c.client.exec(http.MethodPut, uri, headers, body, c.auth) - if err != nil { - return err - } - defer readAndCloseBody(resp.body) - return checkRespCode(resp.statusCode, []int{http.StatusNoContent}) -} diff --git a/vendor/github.com/Azure/azure-storage-go/queueserviceclient.go b/vendor/github.com/Azure/azure-storage-go/queueserviceclient.go deleted file mode 100644 index c26141339b..0000000000 --- a/vendor/github.com/Azure/azure-storage-go/queueserviceclient.go +++ /dev/null @@ -1,20 +0,0 @@ -package storage - -// QueueServiceClient contains operations for Microsoft Azure Queue Storage -// Service. -type QueueServiceClient struct { - client Client - auth authentication -} - -// GetServiceProperties gets the properties of your storage account's queue service. -// See: https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/get-queue-service-properties -func (c *QueueServiceClient) GetServiceProperties() (*ServiceProperties, error) { - return c.client.getServiceProperties(queueServiceName, c.auth) -} - -// SetServiceProperties sets the properties of your storage account's queue service. -// See: https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/set-queue-service-properties -func (c *QueueServiceClient) SetServiceProperties(props ServiceProperties) error { - return c.client.setServiceProperties(props, queueServiceName, c.auth) -} diff --git a/vendor/github.com/Azure/azure-storage-go/share.go b/vendor/github.com/Azure/azure-storage-go/share.go deleted file mode 100644 index e190097ea5..0000000000 --- a/vendor/github.com/Azure/azure-storage-go/share.go +++ /dev/null @@ -1,186 +0,0 @@ -package storage - -import ( - "fmt" - "net/http" - "net/url" - "strconv" -) - -// Share represents an Azure file share. -type Share struct { - fsc *FileServiceClient - Name string `xml:"Name"` - Properties ShareProperties `xml:"Properties"` - Metadata map[string]string -} - -// ShareProperties contains various properties of a share. -type ShareProperties struct { - LastModified string `xml:"Last-Modified"` - Etag string `xml:"Etag"` - Quota int `xml:"Quota"` -} - -// builds the complete path for this share object. -func (s *Share) buildPath() string { - return fmt.Sprintf("/%s", s.Name) -} - -// Create this share under the associated account. -// If a share with the same name already exists, the operation fails. -// -// See https://msdn.microsoft.com/en-us/library/azure/dn167008.aspx -func (s *Share) Create() error { - headers, err := s.fsc.createResource(s.buildPath(), resourceShare, nil, mergeMDIntoExtraHeaders(s.Metadata, nil), []int{http.StatusCreated}) - if err != nil { - return err - } - - s.updateEtagAndLastModified(headers) - return nil -} - -// CreateIfNotExists creates this share under the associated account if -// it does not exist. Returns true if the share is newly created or false if -// the share already exists. -// -// See https://msdn.microsoft.com/en-us/library/azure/dn167008.aspx -func (s *Share) CreateIfNotExists() (bool, error) { - resp, err := s.fsc.createResourceNoClose(s.buildPath(), resourceShare, nil, nil) - if resp != nil { - defer readAndCloseBody(resp.body) - if resp.statusCode == http.StatusCreated || resp.statusCode == http.StatusConflict { - if resp.statusCode == http.StatusCreated { - s.updateEtagAndLastModified(resp.headers) - return true, nil - } - return false, s.FetchAttributes() - } - } - - return false, err -} - -// Delete marks this share for deletion. The share along with any files -// and directories contained within it are later deleted during garbage -// collection. If the share does not exist the operation fails -// -// See https://msdn.microsoft.com/en-us/library/azure/dn689090.aspx -func (s *Share) Delete() error { - return s.fsc.deleteResource(s.buildPath(), resourceShare) -} - -// DeleteIfExists operation marks this share for deletion if it exists. -// -// See https://msdn.microsoft.com/en-us/library/azure/dn689090.aspx -func (s *Share) DeleteIfExists() (bool, error) { - resp, err := s.fsc.deleteResourceNoClose(s.buildPath(), resourceShare) - if resp != nil { - defer readAndCloseBody(resp.body) - if resp.statusCode == http.StatusAccepted || resp.statusCode == http.StatusNotFound { - return resp.statusCode == http.StatusAccepted, nil - } - } - return false, err -} - -// Exists returns true if this share already exists -// on the storage account, otherwise returns false. -func (s *Share) Exists() (bool, error) { - exists, headers, err := s.fsc.resourceExists(s.buildPath(), resourceShare) - if exists { - s.updateEtagAndLastModified(headers) - s.updateQuota(headers) - } - return exists, err -} - -// FetchAttributes retrieves metadata and properties for this share. -func (s *Share) FetchAttributes() error { - headers, err := s.fsc.getResourceHeaders(s.buildPath(), compNone, resourceShare, http.MethodHead) - if err != nil { - return err - } - - s.updateEtagAndLastModified(headers) - s.updateQuota(headers) - s.Metadata = getMetadataFromHeaders(headers) - - return nil -} - -// GetRootDirectoryReference returns a Directory object at the root of this share. -func (s *Share) GetRootDirectoryReference() *Directory { - return &Directory{ - fsc: s.fsc, - share: s, - } -} - -// ServiceClient returns the FileServiceClient associated with this share. -func (s *Share) ServiceClient() *FileServiceClient { - return s.fsc -} - -// SetMetadata replaces the metadata for this share. -// -// Some keys may be converted to Camel-Case before sending. All keys -// are returned in lower case by GetShareMetadata. HTTP header names -// are case-insensitive so case munging should not matter to other -// applications either. -// -// See https://msdn.microsoft.com/en-us/library/azure/dd179414.aspx -func (s *Share) SetMetadata() error { - headers, err := s.fsc.setResourceHeaders(s.buildPath(), compMetadata, resourceShare, mergeMDIntoExtraHeaders(s.Metadata, nil)) - if err != nil { - return err - } - - s.updateEtagAndLastModified(headers) - return nil -} - -// SetProperties sets system properties for this share. -// -// Some keys may be converted to Camel-Case before sending. All keys -// are returned in lower case by SetShareProperties. HTTP header names -// are case-insensitive so case munging should not matter to other -// applications either. -// -// See https://msdn.microsoft.com/en-us/library/azure/mt427368.aspx -func (s *Share) SetProperties() error { - if s.Properties.Quota < 1 || s.Properties.Quota > 5120 { - return fmt.Errorf("invalid value %v for quota, valid values are [1, 5120]", s.Properties.Quota) - } - - headers, err := s.fsc.setResourceHeaders(s.buildPath(), compProperties, resourceShare, map[string]string{ - "x-ms-share-quota": strconv.Itoa(s.Properties.Quota), - }) - if err != nil { - return err - } - - s.updateEtagAndLastModified(headers) - return nil -} - -// updates Etag and last modified date -func (s *Share) updateEtagAndLastModified(headers http.Header) { - s.Properties.Etag = headers.Get("Etag") - s.Properties.LastModified = headers.Get("Last-Modified") -} - -// updates quota value -func (s *Share) updateQuota(headers http.Header) { - quota, err := strconv.Atoi(headers.Get("x-ms-share-quota")) - if err == nil { - s.Properties.Quota = quota - } -} - -// URL gets the canonical URL to this share. This method does not create a publicly accessible -// URL if the share is private and this method does not check if the share exists. -func (s *Share) URL() string { - return s.fsc.client.getEndpoint(fileServiceName, s.buildPath(), url.Values{}) -} diff --git a/vendor/github.com/Azure/azure-storage-go/storagepolicy.go b/vendor/github.com/Azure/azure-storage-go/storagepolicy.go deleted file mode 100644 index bee1c31ad6..0000000000 --- a/vendor/github.com/Azure/azure-storage-go/storagepolicy.go +++ /dev/null @@ -1,47 +0,0 @@ -package storage - -import ( - "strings" - "time" -) - -// AccessPolicyDetailsXML has specifics about an access policy -// annotated with XML details. -type AccessPolicyDetailsXML struct { - StartTime time.Time `xml:"Start"` - ExpiryTime time.Time `xml:"Expiry"` - Permission string `xml:"Permission"` -} - -// SignedIdentifier is a wrapper for a specific policy -type SignedIdentifier struct { - ID string `xml:"Id"` - AccessPolicy AccessPolicyDetailsXML `xml:"AccessPolicy"` -} - -// SignedIdentifiers part of the response from GetPermissions call. -type SignedIdentifiers struct { - SignedIdentifiers []SignedIdentifier `xml:"SignedIdentifier"` -} - -// AccessPolicy is the response type from the GetPermissions call. -type AccessPolicy struct { - SignedIdentifiersList SignedIdentifiers `xml:"SignedIdentifiers"` -} - -// convertAccessPolicyToXMLStructs converts between AccessPolicyDetails which is a struct better for API usage to the -// AccessPolicy struct which will get converted to XML. -func convertAccessPolicyToXMLStructs(id string, startTime time.Time, expiryTime time.Time, permissions string) SignedIdentifier { - return SignedIdentifier{ - ID: id, - AccessPolicy: AccessPolicyDetailsXML{ - StartTime: startTime.UTC().Round(time.Second), - ExpiryTime: expiryTime.UTC().Round(time.Second), - Permission: permissions, - }, - } -} - -func updatePermissions(permissions, permission string) bool { - return strings.Contains(permissions, permission) -} diff --git a/vendor/github.com/Azure/azure-storage-go/storageservice.go b/vendor/github.com/Azure/azure-storage-go/storageservice.go deleted file mode 100644 index 817560b782..0000000000 --- a/vendor/github.com/Azure/azure-storage-go/storageservice.go +++ /dev/null @@ -1,118 +0,0 @@ -package storage - -import ( - "fmt" - "net/http" - "net/url" -) - -// ServiceProperties represents the storage account service properties -type ServiceProperties struct { - Logging *Logging - HourMetrics *Metrics - MinuteMetrics *Metrics - Cors *Cors -} - -// Logging represents the Azure Analytics Logging settings -type Logging struct { - Version string - Delete bool - Read bool - Write bool - RetentionPolicy *RetentionPolicy -} - -// RetentionPolicy indicates if retention is enabled and for how many days -type RetentionPolicy struct { - Enabled bool - Days *int -} - -// Metrics provide request statistics. -type Metrics struct { - Version string - Enabled bool - IncludeAPIs *bool - RetentionPolicy *RetentionPolicy -} - -// Cors includes all the CORS rules -type Cors struct { - CorsRule []CorsRule -} - -// CorsRule includes all settings for a Cors rule -type CorsRule struct { - AllowedOrigins string - AllowedMethods string - MaxAgeInSeconds int - ExposedHeaders string - AllowedHeaders string -} - -func (c Client) getServiceProperties(service string, auth authentication) (*ServiceProperties, error) { - query := url.Values{ - "restype": {"service"}, - "comp": {"properties"}, - } - uri := c.getEndpoint(service, "", query) - headers := c.getStandardHeaders() - - resp, err := c.exec(http.MethodGet, uri, headers, nil, auth) - if err != nil { - return nil, err - } - defer resp.body.Close() - - if err := checkRespCode(resp.statusCode, []int{http.StatusOK}); err != nil { - return nil, err - } - - var out ServiceProperties - err = xmlUnmarshal(resp.body, &out) - if err != nil { - return nil, err - } - - return &out, nil -} - -func (c Client) setServiceProperties(props ServiceProperties, service string, auth authentication) error { - query := url.Values{ - "restype": {"service"}, - "comp": {"properties"}, - } - uri := c.getEndpoint(service, "", query) - - // Ideally, StorageServiceProperties would be the output struct - // This is to avoid golint stuttering, while generating the correct XML - type StorageServiceProperties struct { - Logging *Logging - HourMetrics *Metrics - MinuteMetrics *Metrics - Cors *Cors - } - input := StorageServiceProperties{ - Logging: props.Logging, - HourMetrics: props.HourMetrics, - MinuteMetrics: props.MinuteMetrics, - Cors: props.Cors, - } - - body, length, err := xmlMarshal(input) - if err != nil { - return err - } - - headers := c.getStandardHeaders() - headers["Content-Length"] = fmt.Sprintf("%v", length) - - resp, err := c.exec(http.MethodPut, uri, headers, body, auth) - if err != nil { - return err - } - defer readAndCloseBody(resp.body) - - return checkRespCode(resp.statusCode, []int{http.StatusAccepted}) -} diff --git a/vendor/github.com/Azure/azure-storage-go/table.go b/vendor/github.com/Azure/azure-storage-go/table.go deleted file mode 100644 index 4123746e50..0000000000 --- a/vendor/github.com/Azure/azure-storage-go/table.go +++ /dev/null @@ -1,254 +0,0 @@ -package storage - -import ( - "bytes" - "encoding/json" - "fmt" - "io" - "io/ioutil" - "net/http" - "net/url" - "strconv" - "time" -) - -// AzureTable is the typedef of the Azure Table name -type AzureTable string - -const ( - tablesURIPath = "/Tables" -) - -type createTableRequest struct { - TableName string `json:"TableName"` -} - -// TableAccessPolicy are used for SETTING table policies -type TableAccessPolicy struct { - ID string - StartTime time.Time - ExpiryTime time.Time - CanRead bool - CanAppend bool - CanUpdate bool - CanDelete bool -} - -func pathForTable(table AzureTable) string { return fmt.Sprintf("%s", table) } - -func (c *TableServiceClient) getStandardHeaders() map[string]string { - return map[string]string{ - "x-ms-version": "2015-02-21", - "x-ms-date": currentTimeRfc1123Formatted(), - "Accept": "application/json;odata=nometadata", - "Accept-Charset": "UTF-8", - "Content-Type": "application/json", - userAgentHeader: c.client.userAgent, - } -} - -// QueryTables returns the tables created in the -// *TableServiceClient storage account. -func (c *TableServiceClient) QueryTables() ([]AzureTable, error) { - uri := c.client.getEndpoint(tableServiceName, tablesURIPath, url.Values{}) - - headers := c.getStandardHeaders() - headers["Content-Length"] = "0" - - resp, err := c.client.execInternalJSON(http.MethodGet, uri, headers, nil, c.auth) - if err != nil { - return nil, err - } - defer resp.body.Close() - - if err := checkRespCode(resp.statusCode, []int{http.StatusOK}); err != nil { - ioutil.ReadAll(resp.body) - return nil, err - } - - buf := new(bytes.Buffer) - if _, err := buf.ReadFrom(resp.body); err != nil { - return nil, err - } - - var respArray queryTablesResponse - if err := json.Unmarshal(buf.Bytes(), &respArray); err != nil { - return nil, err - } - - s := make([]AzureTable, len(respArray.TableName)) - for i, elem := range respArray.TableName { - s[i] = AzureTable(elem.TableName) - } - - return s, nil -} - -// CreateTable creates the table given the specific -// name. This function fails if the name is not compliant -// with the specification or the tables already exists. -func (c *TableServiceClient) CreateTable(table AzureTable) error { - uri := c.client.getEndpoint(tableServiceName, tablesURIPath, url.Values{}) - - headers := c.getStandardHeaders() - - req := createTableRequest{TableName: string(table)} - buf := new(bytes.Buffer) - - if err := json.NewEncoder(buf).Encode(req); err != nil { - return err - } - - headers["Content-Length"] = fmt.Sprintf("%d", buf.Len()) - - resp, err := c.client.execInternalJSON(http.MethodPost, uri, headers, buf, c.auth) - - if err != nil { - return err - } - defer readAndCloseBody(resp.body) - - if err := checkRespCode(resp.statusCode, []int{http.StatusCreated}); err != nil { - return err - } - - return nil -} - -// DeleteTable deletes the table given the specific -// name. This function fails if the table is not present. -// Be advised: DeleteTable deletes all the entries -// that may be present. -func (c *TableServiceClient) DeleteTable(table AzureTable) error { - uri := c.client.getEndpoint(tableServiceName, tablesURIPath, url.Values{}) - uri += fmt.Sprintf("('%s')", string(table)) - - headers := c.getStandardHeaders() - - headers["Content-Length"] = "0" - - resp, err := c.client.execInternalJSON(http.MethodDelete, uri, headers, nil, c.auth) - - if err != nil { - return err - } - defer readAndCloseBody(resp.body) - - if err := checkRespCode(resp.statusCode, []int{http.StatusNoContent}); err != nil { - return err - - } - return nil -} - -// SetTablePermissions sets up table ACL permissions as per REST details https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/Set-Table-ACL -func (c *TableServiceClient) SetTablePermissions(table AzureTable, policies []TableAccessPolicy, timeout uint) (err error) { - params := url.Values{"comp": {"acl"}} - - if timeout > 0 { - params.Add("timeout", fmt.Sprint(timeout)) - } - - uri := c.client.getEndpoint(tableServiceName, string(table), params) - headers := c.client.getStandardHeaders() - - body, length, err := generateTableACLPayload(policies) - if err != nil { - return err - } - headers["Content-Length"] = fmt.Sprintf("%v", length) - - resp, err := c.client.execInternalJSON(http.MethodPut, uri, headers, body, c.auth) - if err != nil { - return err - } - defer readAndCloseBody(resp.body) - - if err := checkRespCode(resp.statusCode, []int{http.StatusNoContent}); err != nil { - return err - } - return nil -} - -func generateTableACLPayload(policies []TableAccessPolicy) (io.Reader, int, error) { - sil := SignedIdentifiers{ - SignedIdentifiers: []SignedIdentifier{}, - } - for _, tap := range policies { - permission := generateTablePermissions(&tap) - signedIdentifier := convertAccessPolicyToXMLStructs(tap.ID, tap.StartTime, tap.ExpiryTime, permission) - sil.SignedIdentifiers = append(sil.SignedIdentifiers, signedIdentifier) - } - return xmlMarshal(sil) -} - -// GetTablePermissions gets the table ACL permissions, as per REST details https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/get-table-acl -func (c *TableServiceClient) GetTablePermissions(table AzureTable, timeout int) (permissionResponse []TableAccessPolicy, err error) { - params := url.Values{"comp": {"acl"}} - - if timeout > 0 { - params.Add("timeout", strconv.Itoa(timeout)) - } - - uri := c.client.getEndpoint(tableServiceName, string(table), params) - headers := c.client.getStandardHeaders() - resp, err := c.client.execInternalJSON(http.MethodGet, uri, headers, nil, c.auth) - if err != nil { - return nil, err - } - defer resp.body.Close() - - if err = checkRespCode(resp.statusCode, []int{http.StatusOK}); err != nil { - ioutil.ReadAll(resp.body) - return nil, err - } - - var ap AccessPolicy - err = xmlUnmarshal(resp.body, &ap.SignedIdentifiersList) - if err != nil { - return nil, err - } - out := updateTableAccessPolicy(ap) - return out, nil -} - -func updateTableAccessPolicy(ap AccessPolicy) []TableAccessPolicy { - out := []TableAccessPolicy{} - for _, policy := range ap.SignedIdentifiersList.SignedIdentifiers { - tap := TableAccessPolicy{ - ID: policy.ID, - StartTime: policy.AccessPolicy.StartTime, - ExpiryTime: policy.AccessPolicy.ExpiryTime, - } - tap.CanRead = updatePermissions(policy.AccessPolicy.Permission, "r") - tap.CanAppend = updatePermissions(policy.AccessPolicy.Permission, "a") - tap.CanUpdate = updatePermissions(policy.AccessPolicy.Permission, "u") - tap.CanDelete = updatePermissions(policy.AccessPolicy.Permission, "d") - - out = append(out, tap) - } - return out -} - -func generateTablePermissions(tap *TableAccessPolicy) (permissions string) { - // generate the permissions string (raud). - // still want the end user API to have bool flags. - permissions = "" - - if tap.CanRead { - permissions += "r" - } - - if tap.CanAppend { - permissions += "a" - } - - if tap.CanUpdate { - permissions += "u" - } - - if tap.CanDelete { - permissions += "d" - } - return permissions -} diff --git a/vendor/github.com/Azure/azure-storage-go/table_entities.go b/vendor/github.com/Azure/azure-storage-go/table_entities.go deleted file mode 100644 index 36413a0cff..0000000000 --- a/vendor/github.com/Azure/azure-storage-go/table_entities.go +++ /dev/null @@ -1,354 +0,0 @@ -package storage - -import ( - "bytes" - "encoding/json" - "fmt" - "io" - "net/http" - "net/url" - "reflect" -) - -// Annotating as secure for gas scanning -/* #nosec */ -const ( - partitionKeyNode = "PartitionKey" - rowKeyNode = "RowKey" - tag = "table" - tagIgnore = "-" - continuationTokenPartitionKeyHeader = "X-Ms-Continuation-Nextpartitionkey" - continuationTokenRowHeader = "X-Ms-Continuation-Nextrowkey" - maxTopParameter = 1000 -) - -type queryTablesResponse struct { - TableName []struct { - TableName string `json:"TableName"` - } `json:"value"` -} - -const ( - tableOperationTypeInsert = iota - tableOperationTypeUpdate = iota - tableOperationTypeMerge = iota - tableOperationTypeInsertOrReplace = iota - tableOperationTypeInsertOrMerge = iota -) - -type tableOperation int - -// TableEntity interface specifies -// the functions needed to support -// marshaling and unmarshaling into -// Azure Tables. The struct must only contain -// simple types because Azure Tables do not -// support hierarchy. -type TableEntity interface { - PartitionKey() string - RowKey() string - SetPartitionKey(string) error - SetRowKey(string) error -} - -// ContinuationToken is an opaque (ie not useful to inspect) -// struct that Get... methods can return if there are more -// entries to be returned than the ones already -// returned. Just pass it to the same function to continue -// receiving the remaining entries. -type ContinuationToken struct { - NextPartitionKey string - NextRowKey string -} - -type getTableEntriesResponse struct { - Elements []map[string]interface{} `json:"value"` -} - -// QueryTableEntities queries the specified table and returns the unmarshaled -// entities of type retType. -// top parameter limits the returned entries up to top. Maximum top -// allowed by Azure API is 1000. In case there are more than top entries to be -// returned the function will return a non nil *ContinuationToken. You can call the -// same function again passing the received ContinuationToken as previousContToken -// parameter in order to get the following entries. The query parameter -// is the odata query. To retrieve all the entries pass the empty string. -// The function returns a pointer to a TableEntity slice, the *ContinuationToken -// if there are more entries to be returned and an error in case something went -// wrong. -// -// Example: -// entities, cToken, err = tSvc.QueryTableEntities("table", cToken, reflect.TypeOf(entity), 20, "") -func (c *TableServiceClient) QueryTableEntities(tableName AzureTable, previousContToken *ContinuationToken, retType reflect.Type, top int, query string) ([]TableEntity, *ContinuationToken, error) { - if top > maxTopParameter { - return nil, nil, fmt.Errorf("top accepts at maximum %d elements. Requested %d instead", maxTopParameter, top) - } - - uri := c.client.getEndpoint(tableServiceName, pathForTable(tableName), url.Values{}) - uri += fmt.Sprintf("?$top=%d", top) - if query != "" { - uri += fmt.Sprintf("&$filter=%s", url.QueryEscape(query)) - } - - if previousContToken != nil { - uri += fmt.Sprintf("&NextPartitionKey=%s&NextRowKey=%s", previousContToken.NextPartitionKey, previousContToken.NextRowKey) - } - - headers := c.getStandardHeaders() - - headers["Content-Length"] = "0" - - resp, err := c.client.execInternalJSON(http.MethodGet, uri, headers, nil, c.auth) - - if err != nil { - return nil, nil, err - } - - contToken := extractContinuationTokenFromHeaders(resp.headers) - - defer resp.body.Close() - - if err = checkRespCode(resp.statusCode, []int{http.StatusOK}); err != nil { - return nil, contToken, err - } - - retEntries, err := deserializeEntity(retType, resp.body) - if err != nil { - return nil, contToken, err - } - - return retEntries, contToken, nil -} - -// InsertEntity inserts an entity in the specified table. -// The function fails if there is an entity with the same -// PartitionKey and RowKey in the table. -func (c *TableServiceClient) InsertEntity(table AzureTable, entity TableEntity) error { - sc, err := c.execTable(table, entity, false, http.MethodPost) - if err != nil { - return err - } - - return checkRespCode(sc, []int{http.StatusCreated}) -} - -func (c *TableServiceClient) execTable(table AzureTable, entity TableEntity, specifyKeysInURL bool, method string) (int, error) { - uri := c.client.getEndpoint(tableServiceName, pathForTable(table), url.Values{}) - if specifyKeysInURL { - uri += fmt.Sprintf("(PartitionKey='%s',RowKey='%s')", url.QueryEscape(entity.PartitionKey()), url.QueryEscape(entity.RowKey())) - } - - headers := c.getStandardHeaders() - - var buf bytes.Buffer - - if err := injectPartitionAndRowKeys(entity, &buf); err != nil { - return 0, err - } - - headers["Content-Length"] = fmt.Sprintf("%d", buf.Len()) - - resp, err := c.client.execInternalJSON(method, uri, headers, &buf, c.auth) - - if err != nil { - return 0, err - } - - defer resp.body.Close() - - return resp.statusCode, nil -} - -// UpdateEntity updates the contents of an entity with the -// one passed as parameter. The function fails if there is no entity -// with the same PartitionKey and RowKey in the table. -func (c *TableServiceClient) UpdateEntity(table AzureTable, entity TableEntity) error { - sc, err := c.execTable(table, entity, true, http.MethodPut) - if err != nil { - return err - } - - return checkRespCode(sc, []int{http.StatusNoContent}) -} - -// MergeEntity merges the contents of an entity with the -// one passed as parameter. -// The function fails if there is no entity -// with the same PartitionKey and RowKey in the table. -func (c *TableServiceClient) MergeEntity(table AzureTable, entity TableEntity) error { - sc, err := c.execTable(table, entity, true, "MERGE") - if err != nil { - return err - } - - return checkRespCode(sc, []int{http.StatusNoContent}) -} - -// DeleteEntityWithoutCheck deletes the entity matching by -// PartitionKey and RowKey. There is no check on IfMatch -// parameter so the entity is always deleted. -// The function fails if there is no entity -// with the same PartitionKey and RowKey in the table. -func (c *TableServiceClient) DeleteEntityWithoutCheck(table AzureTable, entity TableEntity) error { - return c.DeleteEntity(table, entity, "*") -} - -// DeleteEntity deletes the entity matching by -// PartitionKey, RowKey and ifMatch field. -// The function fails if there is no entity -// with the same PartitionKey and RowKey in the table or -// the ifMatch is different. -func (c *TableServiceClient) DeleteEntity(table AzureTable, entity TableEntity, ifMatch string) error { - uri := c.client.getEndpoint(tableServiceName, pathForTable(table), url.Values{}) - uri += fmt.Sprintf("(PartitionKey='%s',RowKey='%s')", url.QueryEscape(entity.PartitionKey()), url.QueryEscape(entity.RowKey())) - - headers := c.getStandardHeaders() - - headers["Content-Length"] = "0" - headers["If-Match"] = ifMatch - - resp, err := c.client.execInternalJSON(http.MethodDelete, uri, headers, nil, c.auth) - - if err != nil { - return err - } - defer resp.body.Close() - - if err := checkRespCode(resp.statusCode, []int{http.StatusNoContent}); err != nil { - return err - } - - return nil -} - -// InsertOrReplaceEntity inserts an entity in the specified table -// or replaced the existing one. -func (c *TableServiceClient) InsertOrReplaceEntity(table AzureTable, entity TableEntity) error { - sc, err := c.execTable(table, entity, true, http.MethodPut) - if err != nil { - return err - } - - return checkRespCode(sc, []int{http.StatusNoContent}) -} - -// InsertOrMergeEntity inserts an entity in the specified table -// or merges the existing one. -func (c *TableServiceClient) InsertOrMergeEntity(table AzureTable, entity TableEntity) error { - sc, err := c.execTable(table, entity, true, "MERGE") - if err != nil { - return err - } - - return checkRespCode(sc, []int{http.StatusNoContent}) -} - -func injectPartitionAndRowKeys(entity TableEntity, buf *bytes.Buffer) error { - if err := json.NewEncoder(buf).Encode(entity); err != nil { - return err - } - - dec := make(map[string]interface{}) - if err := json.NewDecoder(buf).Decode(&dec); err != nil { - return err - } - - // Inject PartitionKey and RowKey - dec[partitionKeyNode] = entity.PartitionKey() - dec[rowKeyNode] = entity.RowKey() - - // Remove tagged fields - // The tag is defined in the const section - // This is useful to avoid storing the PartitionKey and RowKey twice. - numFields := reflect.ValueOf(entity).Elem().NumField() - for i := 0; i < numFields; i++ { - f := reflect.ValueOf(entity).Elem().Type().Field(i) - - if f.Tag.Get(tag) == tagIgnore { - // we must look for its JSON name in the dictionary - // as the user can rename it using a tag - jsonName := f.Name - if f.Tag.Get("json") != "" { - jsonName = f.Tag.Get("json") - } - delete(dec, jsonName) - } - } - - buf.Reset() - - if err := json.NewEncoder(buf).Encode(&dec); err != nil { - return err - } - - return nil -} - -func deserializeEntity(retType reflect.Type, reader io.Reader) ([]TableEntity, error) { - buf := new(bytes.Buffer) - - var ret getTableEntriesResponse - if err := json.NewDecoder(reader).Decode(&ret); err != nil { - return nil, err - } - - tEntries := make([]TableEntity, len(ret.Elements)) - - for i, entry := range ret.Elements { - - buf.Reset() - if err := json.NewEncoder(buf).Encode(entry); err != nil { - return nil, err - } - - dec := make(map[string]interface{}) - if err := json.NewDecoder(buf).Decode(&dec); err != nil { - return nil, err - } - - var pKey, rKey string - // strip pk and rk - for key, val := range dec { - switch key { - case partitionKeyNode: - pKey = val.(string) - case rowKeyNode: - rKey = val.(string) - } - } - - delete(dec, partitionKeyNode) - delete(dec, rowKeyNode) - - buf.Reset() - if err := json.NewEncoder(buf).Encode(dec); err != nil { - return nil, err - } - - // Create a empty retType instance - tEntries[i] = reflect.New(retType.Elem()).Interface().(TableEntity) - // Popolate it with the values - if err := json.NewDecoder(buf).Decode(&tEntries[i]); err != nil { - return nil, err - } - - // Reset PartitionKey and RowKey - if err := tEntries[i].SetPartitionKey(pKey); err != nil { - return nil, err - } - if err := tEntries[i].SetRowKey(rKey); err != nil { - return nil, err - } - } - - return tEntries, nil -} - -func extractContinuationTokenFromHeaders(h http.Header) *ContinuationToken { - ct := ContinuationToken{h.Get(continuationTokenPartitionKeyHeader), h.Get(continuationTokenRowHeader)} - - if ct.NextPartitionKey != "" && ct.NextRowKey != "" { - return &ct - } - return nil -} diff --git a/vendor/github.com/Azure/azure-storage-go/tableserviceclient.go b/vendor/github.com/Azure/azure-storage-go/tableserviceclient.go deleted file mode 100644 index ee5e0a8671..0000000000 --- a/vendor/github.com/Azure/azure-storage-go/tableserviceclient.go +++ /dev/null @@ -1,20 +0,0 @@ -package storage - -// TableServiceClient contains operations for Microsoft Azure Table Storage -// Service. -type TableServiceClient struct { - client Client - auth authentication -} - -// GetServiceProperties gets the properties of your storage account's table service. -// See: https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/get-table-service-properties -func (c *TableServiceClient) GetServiceProperties() (*ServiceProperties, error) { - return c.client.getServiceProperties(tableServiceName, c.auth) -} - -// SetServiceProperties sets the properties of your storage account's table service. -// See: https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/set-table-service-properties -func (c *TableServiceClient) SetServiceProperties(props ServiceProperties) error { - return c.client.setServiceProperties(props, tableServiceName, c.auth) -} diff --git a/vendor/github.com/Azure/azure-storage-go/util.go b/vendor/github.com/Azure/azure-storage-go/util.go deleted file mode 100644 index 57ca1b6d93..0000000000 --- a/vendor/github.com/Azure/azure-storage-go/util.go +++ /dev/null @@ -1,85 +0,0 @@ -package storage - -import ( - "bytes" - "crypto/hmac" - "crypto/sha256" - "encoding/base64" - "encoding/xml" - "fmt" - "io" - "io/ioutil" - "net/http" - "net/url" - "reflect" - "time" -) - -func (c Client) computeHmac256(message string) string { - h := hmac.New(sha256.New, c.accountKey) - h.Write([]byte(message)) - return base64.StdEncoding.EncodeToString(h.Sum(nil)) -} - -func currentTimeRfc1123Formatted() string { - return timeRfc1123Formatted(time.Now().UTC()) -} - -func timeRfc1123Formatted(t time.Time) string { - return t.Format(http.TimeFormat) -} - -func mergeParams(v1, v2 url.Values) url.Values { - out := url.Values{} - for k, v := range v1 { - out[k] = v - } - for k, v := range v2 { - vals, ok := out[k] - if ok { - vals = append(vals, v...) - out[k] = vals - } else { - out[k] = v - } - } - return out -} - -func prepareBlockListRequest(blocks []Block) string { - s := `` - for _, v := range blocks { - s += fmt.Sprintf("<%s>%s", v.Status, v.ID, v.Status) - } - s += `` - return s -} - -func xmlUnmarshal(body io.Reader, v interface{}) error { - data, err := ioutil.ReadAll(body) - if err != nil { - return err - } - return xml.Unmarshal(data, v) -} - -func xmlMarshal(v interface{}) (io.Reader, int, error) { - b, err := xml.Marshal(v) - if err != nil { - return nil, 0, err - } - return bytes.NewReader(b), len(b), nil -} - -func headersFromStruct(v interface{}) map[string]string { - headers := make(map[string]string) - value := reflect.ValueOf(v) - for i := 0; i < value.NumField(); i++ { - key := value.Type().Field(i).Tag.Get("header") - val := value.Field(i).String() - if key != "" && val != "" { - headers[key] = val - } - } - return headers -} diff --git a/vendor/github.com/Azure/azure-storage-go/version.go b/vendor/github.com/Azure/azure-storage-go/version.go deleted file mode 100644 index c25fe33713..0000000000 --- a/vendor/github.com/Azure/azure-storage-go/version.go +++ /dev/null @@ -1,5 +0,0 @@ -package storage - -var ( - sdkVersion = "0.1.0" -) diff --git a/vendor/github.com/Azure/go-autorest/autorest/autorest.go b/vendor/github.com/Azure/go-autorest/autorest/autorest.go deleted file mode 100644 index 51f1c4bbca..0000000000 --- a/vendor/github.com/Azure/go-autorest/autorest/autorest.go +++ /dev/null @@ -1,115 +0,0 @@ -/* -Package autorest implements an HTTP request pipeline suitable for use across multiple go-routines -and provides the shared routines relied on by AutoRest (see https://github.com/Azure/autorest/) -generated Go code. - -The package breaks sending and responding to HTTP requests into three phases: Preparing, Sending, -and Responding. A typical pattern is: - - req, err := Prepare(&http.Request{}, - token.WithAuthorization()) - - resp, err := Send(req, - WithLogging(logger), - DoErrorIfStatusCode(http.StatusInternalServerError), - DoCloseIfError(), - DoRetryForAttempts(5, time.Second)) - - err = Respond(resp, - ByDiscardingBody(), - ByClosing()) - -Each phase relies on decorators to modify and / or manage processing. Decorators may first modify -and then pass the data along, pass the data first and then modify the result, or wrap themselves -around passing the data (such as a logger might do). Decorators run in the order provided. For -example, the following: - - req, err := Prepare(&http.Request{}, - WithBaseURL("https://microsoft.com/"), - WithPath("a"), - WithPath("b"), - WithPath("c")) - -will set the URL to: - - https://microsoft.com/a/b/c - -Preparers and Responders may be shared and re-used (assuming the underlying decorators support -sharing and re-use). Performant use is obtained by creating one or more Preparers and Responders -shared among multiple go-routines, and a single Sender shared among multiple sending go-routines, -all bound together by means of input / output channels. - -Decorators hold their passed state within a closure (such as the path components in the example -above). Be careful to share Preparers and Responders only in a context where such held state -applies. For example, it may not make sense to share a Preparer that applies a query string from a -fixed set of values. Similarly, sharing a Responder that reads the response body into a passed -struct (e.g., ByUnmarshallingJson) is likely incorrect. - -Lastly, the Swagger specification (https://swagger.io) that drives AutoRest -(https://github.com/Azure/autorest/) precisely defines two date forms: date and date-time. The -github.com/Azure/go-autorest/autorest/date package provides time.Time derivations to ensure -correct parsing and formatting. - -Errors raised by autorest objects and methods will conform to the autorest.Error interface. - -See the included examples for more detail. For details on the suggested use of this package by -generated clients, see the Client described below. -*/ -package autorest - -import ( - "net/http" - "time" -) - -const ( - // HeaderLocation specifies the HTTP Location header. - HeaderLocation = "Location" - - // HeaderRetryAfter specifies the HTTP Retry-After header. - HeaderRetryAfter = "Retry-After" -) - -// ResponseHasStatusCode returns true if the status code in the HTTP Response is in the passed set -// and false otherwise. -func ResponseHasStatusCode(resp *http.Response, codes ...int) bool { - return containsInt(codes, resp.StatusCode) -} - -// GetLocation retrieves the URL from the Location header of the passed response. -func GetLocation(resp *http.Response) string { - return resp.Header.Get(HeaderLocation) -} - -// GetRetryAfter extracts the retry delay from the Retry-After header of the passed response. If -// the header is absent or is malformed, it will return the supplied default delay time.Duration. -func GetRetryAfter(resp *http.Response, defaultDelay time.Duration) time.Duration { - retry := resp.Header.Get(HeaderRetryAfter) - if retry == "" { - return defaultDelay - } - - d, err := time.ParseDuration(retry + "s") - if err != nil { - return defaultDelay - } - - return d -} - -// NewPollingRequest allocates and returns a new http.Request to poll for the passed response. -func NewPollingRequest(resp *http.Response, cancel <-chan struct{}) (*http.Request, error) { - location := GetLocation(resp) - if location == "" { - return nil, NewErrorWithResponse("autorest", "NewPollingRequest", resp, "Location header missing from response that requires polling") - } - - req, err := Prepare(&http.Request{Cancel: cancel}, - AsGet(), - WithBaseURL(location)) - if err != nil { - return nil, NewErrorWithError(err, "autorest", "NewPollingRequest", nil, "Failure creating poll request to %s", location) - } - - return req, nil -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/azure/async.go b/vendor/github.com/Azure/go-autorest/autorest/azure/async.go deleted file mode 100644 index 6e076981f2..0000000000 --- a/vendor/github.com/Azure/go-autorest/autorest/azure/async.go +++ /dev/null @@ -1,308 +0,0 @@ -package azure - -import ( - "bytes" - "fmt" - "io/ioutil" - "net/http" - "strings" - "time" - - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/date" -) - -const ( - headerAsyncOperation = "Azure-AsyncOperation" -) - -const ( - methodDelete = "DELETE" - methodPatch = "PATCH" - methodPost = "POST" - methodPut = "PUT" - methodGet = "GET" - - operationInProgress string = "InProgress" - operationCanceled string = "Canceled" - operationFailed string = "Failed" - operationSucceeded string = "Succeeded" -) - -// DoPollForAsynchronous returns a SendDecorator that polls if the http.Response is for an Azure -// long-running operation. It will delay between requests for the duration specified in the -// RetryAfter header or, if the header is absent, the passed delay. Polling may be canceled by -// closing the optional channel on the http.Request. -func DoPollForAsynchronous(delay time.Duration) autorest.SendDecorator { - return func(s autorest.Sender) autorest.Sender { - return autorest.SenderFunc(func(r *http.Request) (resp *http.Response, err error) { - resp, err = s.Do(r) - if err != nil { - return resp, err - } - pollingCodes := []int{http.StatusAccepted, http.StatusCreated, http.StatusOK} - if !autorest.ResponseHasStatusCode(resp, pollingCodes...) { - return resp, nil - } - - ps := pollingState{} - for err == nil { - err = updatePollingState(resp, &ps) - if err != nil { - break - } - if ps.hasTerminated() { - if !ps.hasSucceeded() { - err = ps - } - break - } - - r, err = newPollingRequest(resp, ps) - if err != nil { - return resp, err - } - - delay = autorest.GetRetryAfter(resp, delay) - resp, err = autorest.SendWithSender(s, r, - autorest.AfterDelay(delay)) - } - - return resp, err - }) - } -} - -func getAsyncOperation(resp *http.Response) string { - return resp.Header.Get(http.CanonicalHeaderKey(headerAsyncOperation)) -} - -func hasSucceeded(state string) bool { - return state == operationSucceeded -} - -func hasTerminated(state string) bool { - switch state { - case operationCanceled, operationFailed, operationSucceeded: - return true - default: - return false - } -} - -func hasFailed(state string) bool { - return state == operationFailed -} - -type provisioningTracker interface { - state() string - hasSucceeded() bool - hasTerminated() bool -} - -type operationResource struct { - // Note: - // The specification states services should return the "id" field. However some return it as - // "operationId". - ID string `json:"id"` - OperationID string `json:"operationId"` - Name string `json:"name"` - Status string `json:"status"` - Properties map[string]interface{} `json:"properties"` - OperationError ServiceError `json:"error"` - StartTime date.Time `json:"startTime"` - EndTime date.Time `json:"endTime"` - PercentComplete float64 `json:"percentComplete"` -} - -func (or operationResource) state() string { - return or.Status -} - -func (or operationResource) hasSucceeded() bool { - return hasSucceeded(or.state()) -} - -func (or operationResource) hasTerminated() bool { - return hasTerminated(or.state()) -} - -type provisioningProperties struct { - ProvisioningState string `json:"provisioningState"` -} - -type provisioningStatus struct { - Properties provisioningProperties `json:"properties,omitempty"` - ProvisioningError ServiceError `json:"error,omitempty"` -} - -func (ps provisioningStatus) state() string { - return ps.Properties.ProvisioningState -} - -func (ps provisioningStatus) hasSucceeded() bool { - return hasSucceeded(ps.state()) -} - -func (ps provisioningStatus) hasTerminated() bool { - return hasTerminated(ps.state()) -} - -func (ps provisioningStatus) hasProvisioningError() bool { - return ps.ProvisioningError != ServiceError{} -} - -type pollingResponseFormat string - -const ( - usesOperationResponse pollingResponseFormat = "OperationResponse" - usesProvisioningStatus pollingResponseFormat = "ProvisioningStatus" - formatIsUnknown pollingResponseFormat = "" -) - -type pollingState struct { - responseFormat pollingResponseFormat - uri string - state string - code string - message string -} - -func (ps pollingState) hasSucceeded() bool { - return hasSucceeded(ps.state) -} - -func (ps pollingState) hasTerminated() bool { - return hasTerminated(ps.state) -} - -func (ps pollingState) hasFailed() bool { - return hasFailed(ps.state) -} - -func (ps pollingState) Error() string { - return fmt.Sprintf("Long running operation terminated with status '%s': Code=%q Message=%q", ps.state, ps.code, ps.message) -} - -// updatePollingState maps the operation status -- retrieved from either a provisioningState -// field, the status field of an OperationResource, or inferred from the HTTP status code -- -// into a well-known states. Since the process begins from the initial request, the state -// always comes from either a the provisioningState returned or is inferred from the HTTP -// status code. Subsequent requests will read an Azure OperationResource object if the -// service initially returned the Azure-AsyncOperation header. The responseFormat field notes -// the expected response format. -func updatePollingState(resp *http.Response, ps *pollingState) error { - // Determine the response shape - // -- The first response will always be a provisioningStatus response; only the polling requests, - // depending on the header returned, may be something otherwise. - var pt provisioningTracker - if ps.responseFormat == usesOperationResponse { - pt = &operationResource{} - } else { - pt = &provisioningStatus{} - } - - // If this is the first request (that is, the polling response shape is unknown), determine how - // to poll and what to expect - if ps.responseFormat == formatIsUnknown { - req := resp.Request - if req == nil { - return autorest.NewError("azure", "updatePollingState", "Azure Polling Error - Original HTTP request is missing") - } - - // Prefer the Azure-AsyncOperation header - ps.uri = getAsyncOperation(resp) - if ps.uri != "" { - ps.responseFormat = usesOperationResponse - } else { - ps.responseFormat = usesProvisioningStatus - } - - // Else, use the Location header - if ps.uri == "" { - ps.uri = autorest.GetLocation(resp) - } - - // Lastly, requests against an existing resource, use the last request URI - if ps.uri == "" { - m := strings.ToUpper(req.Method) - if m == methodPatch || m == methodPut || m == methodGet { - ps.uri = req.URL.String() - } - } - } - - // Read and interpret the response (saving the Body in case no polling is necessary) - b := &bytes.Buffer{} - err := autorest.Respond(resp, - autorest.ByCopying(b), - autorest.ByUnmarshallingJSON(pt), - autorest.ByClosing()) - resp.Body = ioutil.NopCloser(b) - if err != nil { - return err - } - - // Interpret the results - // -- Terminal states apply regardless - // -- Unknown states are per-service inprogress states - // -- Otherwise, infer state from HTTP status code - if pt.hasTerminated() { - ps.state = pt.state() - } else if pt.state() != "" { - ps.state = operationInProgress - } else { - switch resp.StatusCode { - case http.StatusAccepted: - ps.state = operationInProgress - - case http.StatusNoContent, http.StatusCreated, http.StatusOK: - ps.state = operationSucceeded - - default: - ps.state = operationFailed - } - } - - if ps.state == operationInProgress && ps.uri == "" { - return autorest.NewError("azure", "updatePollingState", "Azure Polling Error - Unable to obtain polling URI for %s %s", resp.Request.Method, resp.Request.URL) - } - - // For failed operation, check for error code and message in - // -- Operation resource - // -- Response - // -- Otherwise, Unknown - if ps.hasFailed() { - if ps.responseFormat == usesOperationResponse { - or := pt.(*operationResource) - ps.code = or.OperationError.Code - ps.message = or.OperationError.Message - } else { - p := pt.(*provisioningStatus) - if p.hasProvisioningError() { - ps.code = p.ProvisioningError.Code - ps.message = p.ProvisioningError.Message - } else { - ps.code = "Unknown" - ps.message = "None" - } - } - } - return nil -} - -func newPollingRequest(resp *http.Response, ps pollingState) (*http.Request, error) { - req := resp.Request - if req == nil { - return nil, autorest.NewError("azure", "newPollingRequest", "Azure Polling Error - Original HTTP request is missing") - } - - reqPoll, err := autorest.Prepare(&http.Request{Cancel: req.Cancel}, - autorest.AsGet(), - autorest.WithBaseURL(ps.uri)) - if err != nil { - return nil, autorest.NewErrorWithError(err, "azure", "newPollingRequest", nil, "Failure creating poll request to %s", ps.uri) - } - - return reqPoll, nil -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/azure/azure.go b/vendor/github.com/Azure/go-autorest/autorest/azure/azure.go deleted file mode 100644 index 3f4d13421a..0000000000 --- a/vendor/github.com/Azure/go-autorest/autorest/azure/azure.go +++ /dev/null @@ -1,180 +0,0 @@ -/* -Package azure provides Azure-specific implementations used with AutoRest. - -See the included examples for more detail. -*/ -package azure - -import ( - "encoding/json" - "fmt" - "io/ioutil" - "net/http" - "strconv" - - "github.com/Azure/go-autorest/autorest" -) - -const ( - // HeaderClientID is the Azure extension header to set a user-specified request ID. - HeaderClientID = "x-ms-client-request-id" - - // HeaderReturnClientID is the Azure extension header to set if the user-specified request ID - // should be included in the response. - HeaderReturnClientID = "x-ms-return-client-request-id" - - // HeaderRequestID is the Azure extension header of the service generated request ID returned - // in the response. - HeaderRequestID = "x-ms-request-id" -) - -// ServiceError encapsulates the error response from an Azure service. -type ServiceError struct { - Code string `json:"code"` - Message string `json:"message"` - Details *[]interface{} `json:"details"` -} - -func (se ServiceError) Error() string { - if se.Details != nil { - d, err := json.Marshal(*(se.Details)) - if err != nil { - return fmt.Sprintf("Code=%q Message=%q Details=%v", se.Code, se.Message, *se.Details) - } - return fmt.Sprintf("Code=%q Message=%q Details=%v", se.Code, se.Message, string(d)) - } - return fmt.Sprintf("Code=%q Message=%q", se.Code, se.Message) -} - -// RequestError describes an error response returned by Azure service. -type RequestError struct { - autorest.DetailedError - - // The error returned by the Azure service. - ServiceError *ServiceError `json:"error"` - - // The request id (from the x-ms-request-id-header) of the request. - RequestID string -} - -// Error returns a human-friendly error message from service error. -func (e RequestError) Error() string { - return fmt.Sprintf("autorest/azure: Service returned an error. Status=%v %v", - e.StatusCode, e.ServiceError) -} - -// IsAzureError returns true if the passed error is an Azure Service error; false otherwise. -func IsAzureError(e error) bool { - _, ok := e.(*RequestError) - return ok -} - -// NewErrorWithError creates a new Error conforming object from the -// passed packageType, method, statusCode of the given resp (UndefinedStatusCode -// if resp is nil), message, and original error. message is treated as a format -// string to which the optional args apply. -func NewErrorWithError(original error, packageType string, method string, resp *http.Response, message string, args ...interface{}) RequestError { - if v, ok := original.(*RequestError); ok { - return *v - } - - statusCode := autorest.UndefinedStatusCode - if resp != nil { - statusCode = resp.StatusCode - } - return RequestError{ - DetailedError: autorest.DetailedError{ - Original: original, - PackageType: packageType, - Method: method, - StatusCode: statusCode, - Message: fmt.Sprintf(message, args...), - }, - } -} - -// WithReturningClientID returns a PrepareDecorator that adds an HTTP extension header of -// x-ms-client-request-id whose value is the passed, undecorated UUID (e.g., -// "0F39878C-5F76-4DB8-A25D-61D2C193C3CA"). It also sets the x-ms-return-client-request-id -// header to true such that UUID accompanies the http.Response. -func WithReturningClientID(uuid string) autorest.PrepareDecorator { - preparer := autorest.CreatePreparer( - WithClientID(uuid), - WithReturnClientID(true)) - - return func(p autorest.Preparer) autorest.Preparer { - return autorest.PreparerFunc(func(r *http.Request) (*http.Request, error) { - r, err := p.Prepare(r) - if err != nil { - return r, err - } - return preparer.Prepare(r) - }) - } -} - -// WithClientID returns a PrepareDecorator that adds an HTTP extension header of -// x-ms-client-request-id whose value is passed, undecorated UUID (e.g., -// "0F39878C-5F76-4DB8-A25D-61D2C193C3CA"). -func WithClientID(uuid string) autorest.PrepareDecorator { - return autorest.WithHeader(HeaderClientID, uuid) -} - -// WithReturnClientID returns a PrepareDecorator that adds an HTTP extension header of -// x-ms-return-client-request-id whose boolean value indicates if the value of the -// x-ms-client-request-id header should be included in the http.Response. -func WithReturnClientID(b bool) autorest.PrepareDecorator { - return autorest.WithHeader(HeaderReturnClientID, strconv.FormatBool(b)) -} - -// ExtractClientID extracts the client identifier from the x-ms-client-request-id header set on the -// http.Request sent to the service (and returned in the http.Response) -func ExtractClientID(resp *http.Response) string { - return autorest.ExtractHeaderValue(HeaderClientID, resp) -} - -// ExtractRequestID extracts the Azure server generated request identifier from the -// x-ms-request-id header. -func ExtractRequestID(resp *http.Response) string { - return autorest.ExtractHeaderValue(HeaderRequestID, resp) -} - -// WithErrorUnlessStatusCode returns a RespondDecorator that emits an -// azure.RequestError by reading the response body unless the response HTTP status code -// is among the set passed. -// -// If there is a chance service may return responses other than the Azure error -// format and the response cannot be parsed into an error, a decoding error will -// be returned containing the response body. In any case, the Responder will -// return an error if the status code is not satisfied. -// -// If this Responder returns an error, the response body will be replaced with -// an in-memory reader, which needs no further closing. -func WithErrorUnlessStatusCode(codes ...int) autorest.RespondDecorator { - return func(r autorest.Responder) autorest.Responder { - return autorest.ResponderFunc(func(resp *http.Response) error { - err := r.Respond(resp) - if err == nil && !autorest.ResponseHasStatusCode(resp, codes...) { - var e RequestError - defer resp.Body.Close() - - // Copy and replace the Body in case it does not contain an error object. - // This will leave the Body available to the caller. - b, decodeErr := autorest.CopyAndDecode(autorest.EncodedAsJSON, resp.Body, &e) - resp.Body = ioutil.NopCloser(&b) - if decodeErr != nil { - return fmt.Errorf("autorest/azure: error response cannot be parsed: %q error: %v", b.String(), decodeErr) - } else if e.ServiceError == nil { - e.ServiceError = &ServiceError{Code: "Unknown", Message: "Unknown service error"} - } - - e.RequestID = ExtractRequestID(resp) - if e.StatusCode == nil { - e.StatusCode = resp.StatusCode - } - err = &e - } - return err - }) - } -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/azure/config.go b/vendor/github.com/Azure/go-autorest/autorest/azure/config.go deleted file mode 100644 index bea30b0d67..0000000000 --- a/vendor/github.com/Azure/go-autorest/autorest/azure/config.go +++ /dev/null @@ -1,13 +0,0 @@ -package azure - -import ( - "net/url" -) - -// OAuthConfig represents the endpoints needed -// in OAuth operations -type OAuthConfig struct { - AuthorizeEndpoint url.URL - TokenEndpoint url.URL - DeviceCodeEndpoint url.URL -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/azure/devicetoken.go b/vendor/github.com/Azure/go-autorest/autorest/azure/devicetoken.go deleted file mode 100644 index e1d5498a80..0000000000 --- a/vendor/github.com/Azure/go-autorest/autorest/azure/devicetoken.go +++ /dev/null @@ -1,193 +0,0 @@ -package azure - -/* - This file is largely based on rjw57/oauth2device's code, with the follow differences: - * scope -> resource, and only allow a single one - * receive "Message" in the DeviceCode struct and show it to users as the prompt - * azure-xplat-cli has the following behavior that this emulates: - - does not send client_secret during the token exchange - - sends resource again in the token exchange request -*/ - -import ( - "fmt" - "net/http" - "net/url" - "time" - - "github.com/Azure/go-autorest/autorest" -) - -const ( - logPrefix = "autorest/azure/devicetoken:" -) - -var ( - // ErrDeviceGeneric represents an unknown error from the token endpoint when using device flow - ErrDeviceGeneric = fmt.Errorf("%s Error while retrieving OAuth token: Unknown Error", logPrefix) - - // ErrDeviceAccessDenied represents an access denied error from the token endpoint when using device flow - ErrDeviceAccessDenied = fmt.Errorf("%s Error while retrieving OAuth token: Access Denied", logPrefix) - - // ErrDeviceAuthorizationPending represents the server waiting on the user to complete the device flow - ErrDeviceAuthorizationPending = fmt.Errorf("%s Error while retrieving OAuth token: Authorization Pending", logPrefix) - - // ErrDeviceCodeExpired represents the server timing out and expiring the code during device flow - ErrDeviceCodeExpired = fmt.Errorf("%s Error while retrieving OAuth token: Code Expired", logPrefix) - - // ErrDeviceSlowDown represents the service telling us we're polling too often during device flow - ErrDeviceSlowDown = fmt.Errorf("%s Error while retrieving OAuth token: Slow Down", logPrefix) - - errCodeSendingFails = "Error occurred while sending request for Device Authorization Code" - errCodeHandlingFails = "Error occurred while handling response from the Device Endpoint" - errTokenSendingFails = "Error occurred while sending request with device code for a token" - errTokenHandlingFails = "Error occurred while handling response from the Token Endpoint (during device flow)" -) - -// DeviceCode is the object returned by the device auth endpoint -// It contains information to instruct the user to complete the auth flow -type DeviceCode struct { - DeviceCode *string `json:"device_code,omitempty"` - UserCode *string `json:"user_code,omitempty"` - VerificationURL *string `json:"verification_url,omitempty"` - ExpiresIn *int64 `json:"expires_in,string,omitempty"` - Interval *int64 `json:"interval,string,omitempty"` - - Message *string `json:"message"` // Azure specific - Resource string // store the following, stored when initiating, used when exchanging - OAuthConfig OAuthConfig - ClientID string -} - -// TokenError is the object returned by the token exchange endpoint -// when something is amiss -type TokenError struct { - Error *string `json:"error,omitempty"` - ErrorCodes []int `json:"error_codes,omitempty"` - ErrorDescription *string `json:"error_description,omitempty"` - Timestamp *string `json:"timestamp,omitempty"` - TraceID *string `json:"trace_id,omitempty"` -} - -// DeviceToken is the object return by the token exchange endpoint -// It can either look like a Token or an ErrorToken, so put both here -// and check for presence of "Error" to know if we are in error state -type deviceToken struct { - Token - TokenError -} - -// InitiateDeviceAuth initiates a device auth flow. It returns a DeviceCode -// that can be used with CheckForUserCompletion or WaitForUserCompletion. -func InitiateDeviceAuth(client *autorest.Client, oauthConfig OAuthConfig, clientID, resource string) (*DeviceCode, error) { - req, _ := autorest.Prepare( - &http.Request{}, - autorest.AsPost(), - autorest.AsFormURLEncoded(), - autorest.WithBaseURL(oauthConfig.DeviceCodeEndpoint.String()), - autorest.WithFormData(url.Values{ - "client_id": []string{clientID}, - "resource": []string{resource}, - }), - ) - - resp, err := autorest.SendWithSender(client, req) - if err != nil { - return nil, fmt.Errorf("%s %s: %s", logPrefix, errCodeSendingFails, err) - } - - var code DeviceCode - err = autorest.Respond( - resp, - autorest.WithErrorUnlessStatusCode(http.StatusOK), - autorest.ByUnmarshallingJSON(&code), - autorest.ByClosing()) - if err != nil { - return nil, fmt.Errorf("%s %s: %s", logPrefix, errCodeHandlingFails, err) - } - - code.ClientID = clientID - code.Resource = resource - code.OAuthConfig = oauthConfig - - return &code, nil -} - -// CheckForUserCompletion takes a DeviceCode and checks with the Azure AD OAuth endpoint -// to see if the device flow has: been completed, timed out, or otherwise failed -func CheckForUserCompletion(client *autorest.Client, code *DeviceCode) (*Token, error) { - req, _ := autorest.Prepare( - &http.Request{}, - autorest.AsPost(), - autorest.AsFormURLEncoded(), - autorest.WithBaseURL(code.OAuthConfig.TokenEndpoint.String()), - autorest.WithFormData(url.Values{ - "client_id": []string{code.ClientID}, - "code": []string{*code.DeviceCode}, - "grant_type": []string{OAuthGrantTypeDeviceCode}, - "resource": []string{code.Resource}, - }), - ) - - resp, err := autorest.SendWithSender(client, req) - if err != nil { - return nil, fmt.Errorf("%s %s: %s", logPrefix, errTokenSendingFails, err) - } - - var token deviceToken - err = autorest.Respond( - resp, - autorest.WithErrorUnlessStatusCode(http.StatusOK, http.StatusBadRequest), - autorest.ByUnmarshallingJSON(&token), - autorest.ByClosing()) - if err != nil { - return nil, fmt.Errorf("%s %s: %s", logPrefix, errTokenHandlingFails, err) - } - - if token.Error == nil { - return &token.Token, nil - } - - switch *token.Error { - case "authorization_pending": - return nil, ErrDeviceAuthorizationPending - case "slow_down": - return nil, ErrDeviceSlowDown - case "access_denied": - return nil, ErrDeviceAccessDenied - case "code_expired": - return nil, ErrDeviceCodeExpired - default: - return nil, ErrDeviceGeneric - } -} - -// WaitForUserCompletion calls CheckForUserCompletion repeatedly until a token is granted or an error state occurs. -// This prevents the user from looping and checking against 'ErrDeviceAuthorizationPending'. -func WaitForUserCompletion(client *autorest.Client, code *DeviceCode) (*Token, error) { - intervalDuration := time.Duration(*code.Interval) * time.Second - waitDuration := intervalDuration - - for { - token, err := CheckForUserCompletion(client, code) - - if err == nil { - return token, nil - } - - switch err { - case ErrDeviceSlowDown: - waitDuration += waitDuration - case ErrDeviceAuthorizationPending: - // noop - default: // everything else is "fatal" to us - return nil, err - } - - if waitDuration > (intervalDuration * 3) { - return nil, fmt.Errorf("%s Error waiting for user to complete device flow. Server told us to slow_down too much", logPrefix) - } - - time.Sleep(waitDuration) - } -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/azure/environments.go b/vendor/github.com/Azure/go-autorest/autorest/azure/environments.go deleted file mode 100644 index 4701b43764..0000000000 --- a/vendor/github.com/Azure/go-autorest/autorest/azure/environments.go +++ /dev/null @@ -1,167 +0,0 @@ -package azure - -import ( - "fmt" - "net/url" - "strings" -) - -const ( - activeDirectoryAPIVersion = "1.0" -) - -var environments = map[string]Environment{ - "AZURECHINACLOUD": ChinaCloud, - "AZUREGERMANCLOUD": GermanCloud, - "AZUREPUBLICCLOUD": PublicCloud, - "AZUREUSGOVERNMENTCLOUD": USGovernmentCloud, -} - -// Environment represents a set of endpoints for each of Azure's Clouds. -type Environment struct { - Name string `json:"name"` - ManagementPortalURL string `json:"managementPortalURL"` - PublishSettingsURL string `json:"publishSettingsURL"` - ServiceManagementEndpoint string `json:"serviceManagementEndpoint"` - ResourceManagerEndpoint string `json:"resourceManagerEndpoint"` - ActiveDirectoryEndpoint string `json:"activeDirectoryEndpoint"` - GalleryEndpoint string `json:"galleryEndpoint"` - KeyVaultEndpoint string `json:"keyVaultEndpoint"` - GraphEndpoint string `json:"graphEndpoint"` - StorageEndpointSuffix string `json:"storageEndpointSuffix"` - SQLDatabaseDNSSuffix string `json:"sqlDatabaseDNSSuffix"` - TrafficManagerDNSSuffix string `json:"trafficManagerDNSSuffix"` - KeyVaultDNSSuffix string `json:"keyVaultDNSSuffix"` - ServiceBusEndpointSuffix string `json:"serviceBusEndpointSuffix"` - ServiceManagementVMDNSSuffix string `json:"serviceManagementVMDNSSuffix"` - ResourceManagerVMDNSSuffix string `json:"resourceManagerVMDNSSuffix"` - ContainerRegistryDNSSuffix string `json:"containerRegistryDNSSuffix"` -} - -var ( - // PublicCloud is the default public Azure cloud environment - PublicCloud = Environment{ - Name: "AzurePublicCloud", - ManagementPortalURL: "https://manage.windowsazure.com/", - PublishSettingsURL: "https://manage.windowsazure.com/publishsettings/index", - ServiceManagementEndpoint: "https://management.core.windows.net/", - ResourceManagerEndpoint: "https://management.azure.com/", - ActiveDirectoryEndpoint: "https://login.microsoftonline.com/", - GalleryEndpoint: "https://gallery.azure.com/", - KeyVaultEndpoint: "https://vault.azure.net/", - GraphEndpoint: "https://graph.windows.net/", - StorageEndpointSuffix: "core.windows.net", - SQLDatabaseDNSSuffix: "database.windows.net", - TrafficManagerDNSSuffix: "trafficmanager.net", - KeyVaultDNSSuffix: "vault.azure.net", - ServiceBusEndpointSuffix: "servicebus.azure.com", - ServiceManagementVMDNSSuffix: "cloudapp.net", - ResourceManagerVMDNSSuffix: "cloudapp.azure.com", - ContainerRegistryDNSSuffix: "azurecr.io", - } - - // USGovernmentCloud is the cloud environment for the US Government - USGovernmentCloud = Environment{ - Name: "AzureUSGovernmentCloud", - ManagementPortalURL: "https://manage.windowsazure.us/", - PublishSettingsURL: "https://manage.windowsazure.us/publishsettings/index", - ServiceManagementEndpoint: "https://management.core.usgovcloudapi.net/", - ResourceManagerEndpoint: "https://management.usgovcloudapi.net/", - ActiveDirectoryEndpoint: "https://login.microsoftonline.com/", - GalleryEndpoint: "https://gallery.usgovcloudapi.net/", - KeyVaultEndpoint: "https://vault.usgovcloudapi.net/", - GraphEndpoint: "https://graph.usgovcloudapi.net/", - StorageEndpointSuffix: "core.usgovcloudapi.net", - SQLDatabaseDNSSuffix: "database.usgovcloudapi.net", - TrafficManagerDNSSuffix: "usgovtrafficmanager.net", - KeyVaultDNSSuffix: "vault.usgovcloudapi.net", - ServiceBusEndpointSuffix: "servicebus.usgovcloudapi.net", - ServiceManagementVMDNSSuffix: "usgovcloudapp.net", - ResourceManagerVMDNSSuffix: "cloudapp.windowsazure.us", - ContainerRegistryDNSSuffix: "azurecr.io", - } - - // ChinaCloud is the cloud environment operated in China - ChinaCloud = Environment{ - Name: "AzureChinaCloud", - ManagementPortalURL: "https://manage.chinacloudapi.com/", - PublishSettingsURL: "https://manage.chinacloudapi.com/publishsettings/index", - ServiceManagementEndpoint: "https://management.core.chinacloudapi.cn/", - ResourceManagerEndpoint: "https://management.chinacloudapi.cn/", - ActiveDirectoryEndpoint: "https://login.chinacloudapi.cn/", - GalleryEndpoint: "https://gallery.chinacloudapi.cn/", - KeyVaultEndpoint: "https://vault.azure.cn/", - GraphEndpoint: "https://graph.chinacloudapi.cn/", - StorageEndpointSuffix: "core.chinacloudapi.cn", - SQLDatabaseDNSSuffix: "database.chinacloudapi.cn", - TrafficManagerDNSSuffix: "trafficmanager.cn", - KeyVaultDNSSuffix: "vault.azure.cn", - ServiceBusEndpointSuffix: "servicebus.chinacloudapi.net", - ServiceManagementVMDNSSuffix: "chinacloudapp.cn", - ResourceManagerVMDNSSuffix: "cloudapp.azure.cn", - ContainerRegistryDNSSuffix: "azurecr.io", - } - - // GermanCloud is the cloud environment operated in Germany - GermanCloud = Environment{ - Name: "AzureGermanCloud", - ManagementPortalURL: "http://portal.microsoftazure.de/", - PublishSettingsURL: "https://manage.microsoftazure.de/publishsettings/index", - ServiceManagementEndpoint: "https://management.core.cloudapi.de/", - ResourceManagerEndpoint: "https://management.microsoftazure.de/", - ActiveDirectoryEndpoint: "https://login.microsoftonline.de/", - GalleryEndpoint: "https://gallery.cloudapi.de/", - KeyVaultEndpoint: "https://vault.microsoftazure.de/", - GraphEndpoint: "https://graph.cloudapi.de/", - StorageEndpointSuffix: "core.cloudapi.de", - SQLDatabaseDNSSuffix: "database.cloudapi.de", - TrafficManagerDNSSuffix: "azuretrafficmanager.de", - KeyVaultDNSSuffix: "vault.microsoftazure.de", - ServiceBusEndpointSuffix: "servicebus.cloudapi.de", - ServiceManagementVMDNSSuffix: "azurecloudapp.de", - ResourceManagerVMDNSSuffix: "cloudapp.microsoftazure.de", - ContainerRegistryDNSSuffix: "azurecr.io", - } -) - -// EnvironmentFromName returns an Environment based on the common name specified -func EnvironmentFromName(name string) (Environment, error) { - name = strings.ToUpper(name) - env, ok := environments[name] - if !ok { - return env, fmt.Errorf("autorest/azure: There is no cloud environment matching the name %q", name) - } - return env, nil -} - -// OAuthConfigForTenant returns an OAuthConfig with tenant specific urls -func (env Environment) OAuthConfigForTenant(tenantID string) (*OAuthConfig, error) { - return OAuthConfigForTenant(env.ActiveDirectoryEndpoint, tenantID) -} - -// OAuthConfigForTenant returns an OAuthConfig with tenant specific urls for target cloud auth endpoint -func OAuthConfigForTenant(activeDirectoryEndpoint, tenantID string) (*OAuthConfig, error) { - template := "%s/oauth2/%s?api-version=%s" - u, err := url.Parse(activeDirectoryEndpoint) - if err != nil { - return nil, err - } - authorizeURL, err := u.Parse(fmt.Sprintf(template, tenantID, "authorize", activeDirectoryAPIVersion)) - if err != nil { - return nil, err - } - tokenURL, err := u.Parse(fmt.Sprintf(template, tenantID, "token", activeDirectoryAPIVersion)) - if err != nil { - return nil, err - } - deviceCodeURL, err := u.Parse(fmt.Sprintf(template, tenantID, "devicecode", activeDirectoryAPIVersion)) - if err != nil { - return nil, err - } - - return &OAuthConfig{ - AuthorizeEndpoint: *authorizeURL, - TokenEndpoint: *tokenURL, - DeviceCodeEndpoint: *deviceCodeURL, - }, nil -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/azure/persist.go b/vendor/github.com/Azure/go-autorest/autorest/azure/persist.go deleted file mode 100644 index d5cf62ddc7..0000000000 --- a/vendor/github.com/Azure/go-autorest/autorest/azure/persist.go +++ /dev/null @@ -1,59 +0,0 @@ -package azure - -import ( - "encoding/json" - "fmt" - "io/ioutil" - "os" - "path/filepath" -) - -// LoadToken restores a Token object from a file located at 'path'. -func LoadToken(path string) (*Token, error) { - file, err := os.Open(path) - if err != nil { - return nil, fmt.Errorf("failed to open file (%s) while loading token: %v", path, err) - } - defer file.Close() - - var token Token - - dec := json.NewDecoder(file) - if err = dec.Decode(&token); err != nil { - return nil, fmt.Errorf("failed to decode contents of file (%s) into Token representation: %v", path, err) - } - return &token, nil -} - -// SaveToken persists an oauth token at the given location on disk. -// It moves the new file into place so it can safely be used to replace an existing file -// that maybe accessed by multiple processes. -func SaveToken(path string, mode os.FileMode, token Token) error { - dir := filepath.Dir(path) - err := os.MkdirAll(dir, os.ModePerm) - if err != nil { - return fmt.Errorf("failed to create directory (%s) to store token in: %v", dir, err) - } - - newFile, err := ioutil.TempFile(dir, "token") - if err != nil { - return fmt.Errorf("failed to create the temp file to write the token: %v", err) - } - tempPath := newFile.Name() - - if err := json.NewEncoder(newFile).Encode(token); err != nil { - return fmt.Errorf("failed to encode token to file (%s) while saving token: %v", tempPath, err) - } - if err := newFile.Close(); err != nil { - return fmt.Errorf("failed to close temp file %s: %v", tempPath, err) - } - - // Atomic replace to avoid multi-writer file corruptions - if err := os.Rename(tempPath, path); err != nil { - return fmt.Errorf("failed to move temporary token to desired output location. src=%s dst=%s: %v", tempPath, path, err) - } - if err := os.Chmod(path, mode); err != nil { - return fmt.Errorf("failed to chmod the token file %s: %v", path, err) - } - return nil -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/azure/token.go b/vendor/github.com/Azure/go-autorest/autorest/azure/token.go deleted file mode 100644 index cfcd030114..0000000000 --- a/vendor/github.com/Azure/go-autorest/autorest/azure/token.go +++ /dev/null @@ -1,363 +0,0 @@ -package azure - -import ( - "crypto/rand" - "crypto/rsa" - "crypto/sha1" - "crypto/x509" - "encoding/base64" - "fmt" - "net/http" - "net/url" - "strconv" - "time" - - "github.com/Azure/go-autorest/autorest" - "github.com/dgrijalva/jwt-go" -) - -const ( - defaultRefresh = 5 * time.Minute - tokenBaseDate = "1970-01-01T00:00:00Z" - - // OAuthGrantTypeDeviceCode is the "grant_type" identifier used in device flow - OAuthGrantTypeDeviceCode = "device_code" - - // OAuthGrantTypeClientCredentials is the "grant_type" identifier used in credential flows - OAuthGrantTypeClientCredentials = "client_credentials" - - // OAuthGrantTypeRefreshToken is the "grant_type" identifier used in refresh token flows - OAuthGrantTypeRefreshToken = "refresh_token" -) - -var expirationBase time.Time - -func init() { - expirationBase, _ = time.Parse(time.RFC3339, tokenBaseDate) -} - -// TokenRefreshCallback is the type representing callbacks that will be called after -// a successful token refresh -type TokenRefreshCallback func(Token) error - -// Token encapsulates the access token used to authorize Azure requests. -type Token struct { - AccessToken string `json:"access_token"` - RefreshToken string `json:"refresh_token"` - - ExpiresIn string `json:"expires_in"` - ExpiresOn string `json:"expires_on"` - NotBefore string `json:"not_before"` - - Resource string `json:"resource"` - Type string `json:"token_type"` -} - -// Expires returns the time.Time when the Token expires. -func (t Token) Expires() time.Time { - s, err := strconv.Atoi(t.ExpiresOn) - if err != nil { - s = -3600 - } - return expirationBase.Add(time.Duration(s) * time.Second).UTC() -} - -// IsExpired returns true if the Token is expired, false otherwise. -func (t Token) IsExpired() bool { - return t.WillExpireIn(0) -} - -// WillExpireIn returns true if the Token will expire after the passed time.Duration interval -// from now, false otherwise. -func (t Token) WillExpireIn(d time.Duration) bool { - return !t.Expires().After(time.Now().Add(d)) -} - -// WithAuthorization returns a PrepareDecorator that adds an HTTP Authorization header whose -// value is "Bearer " followed by the AccessToken of the Token. -func (t *Token) WithAuthorization() autorest.PrepareDecorator { - return func(p autorest.Preparer) autorest.Preparer { - return autorest.PreparerFunc(func(r *http.Request) (*http.Request, error) { - return (autorest.WithBearerAuthorization(t.AccessToken)(p)).Prepare(r) - }) - } -} - -// ServicePrincipalNoSecret represents a secret type that contains no secret -// meaning it is not valid for fetching a fresh token. This is used by Manual -type ServicePrincipalNoSecret struct { -} - -// SetAuthenticationValues is a method of the interface ServicePrincipalSecret -// It only returns an error for the ServicePrincipalNoSecret type -func (noSecret *ServicePrincipalNoSecret) SetAuthenticationValues(spt *ServicePrincipalToken, v *url.Values) error { - return fmt.Errorf("Manually created ServicePrincipalToken does not contain secret material to retrieve a new access token") -} - -// ServicePrincipalSecret is an interface that allows various secret mechanism to fill the form -// that is submitted when acquiring an oAuth token. -type ServicePrincipalSecret interface { - SetAuthenticationValues(spt *ServicePrincipalToken, values *url.Values) error -} - -// ServicePrincipalTokenSecret implements ServicePrincipalSecret for client_secret type authorization. -type ServicePrincipalTokenSecret struct { - ClientSecret string -} - -// SetAuthenticationValues is a method of the interface ServicePrincipalSecret. -// It will populate the form submitted during oAuth Token Acquisition using the client_secret. -func (tokenSecret *ServicePrincipalTokenSecret) SetAuthenticationValues(spt *ServicePrincipalToken, v *url.Values) error { - v.Set("client_secret", tokenSecret.ClientSecret) - return nil -} - -// ServicePrincipalCertificateSecret implements ServicePrincipalSecret for generic RSA cert auth with signed JWTs. -type ServicePrincipalCertificateSecret struct { - Certificate *x509.Certificate - PrivateKey *rsa.PrivateKey -} - -// SignJwt returns the JWT signed with the certificate's private key. -func (secret *ServicePrincipalCertificateSecret) SignJwt(spt *ServicePrincipalToken) (string, error) { - hasher := sha1.New() - _, err := hasher.Write(secret.Certificate.Raw) - if err != nil { - return "", err - } - - thumbprint := base64.URLEncoding.EncodeToString(hasher.Sum(nil)) - - // The jti (JWT ID) claim provides a unique identifier for the JWT. - jti := make([]byte, 20) - _, err = rand.Read(jti) - if err != nil { - return "", err - } - - token := jwt.New(jwt.SigningMethodRS256) - token.Header["x5t"] = thumbprint - token.Claims = jwt.MapClaims{ - "aud": spt.oauthConfig.TokenEndpoint.String(), - "iss": spt.clientID, - "sub": spt.clientID, - "jti": base64.URLEncoding.EncodeToString(jti), - "nbf": time.Now().Unix(), - "exp": time.Now().Add(time.Hour * 24).Unix(), - } - - signedString, err := token.SignedString(secret.PrivateKey) - return signedString, err -} - -// SetAuthenticationValues is a method of the interface ServicePrincipalSecret. -// It will populate the form submitted during oAuth Token Acquisition using a JWT signed with a certificate. -func (secret *ServicePrincipalCertificateSecret) SetAuthenticationValues(spt *ServicePrincipalToken, v *url.Values) error { - jwt, err := secret.SignJwt(spt) - if err != nil { - return err - } - - v.Set("client_assertion", jwt) - v.Set("client_assertion_type", "urn:ietf:params:oauth:client-assertion-type:jwt-bearer") - return nil -} - -// ServicePrincipalToken encapsulates a Token created for a Service Principal. -type ServicePrincipalToken struct { - Token - - secret ServicePrincipalSecret - oauthConfig OAuthConfig - clientID string - resource string - autoRefresh bool - refreshWithin time.Duration - sender autorest.Sender - - refreshCallbacks []TokenRefreshCallback -} - -// NewServicePrincipalTokenWithSecret create a ServicePrincipalToken using the supplied ServicePrincipalSecret implementation. -func NewServicePrincipalTokenWithSecret(oauthConfig OAuthConfig, id string, resource string, secret ServicePrincipalSecret, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) { - spt := &ServicePrincipalToken{ - oauthConfig: oauthConfig, - secret: secret, - clientID: id, - resource: resource, - autoRefresh: true, - refreshWithin: defaultRefresh, - sender: &http.Client{}, - refreshCallbacks: callbacks, - } - return spt, nil -} - -// NewServicePrincipalTokenFromManualToken creates a ServicePrincipalToken using the supplied token -func NewServicePrincipalTokenFromManualToken(oauthConfig OAuthConfig, clientID string, resource string, token Token, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) { - spt, err := NewServicePrincipalTokenWithSecret( - oauthConfig, - clientID, - resource, - &ServicePrincipalNoSecret{}, - callbacks...) - if err != nil { - return nil, err - } - - spt.Token = token - - return spt, nil -} - -// NewServicePrincipalToken creates a ServicePrincipalToken from the supplied Service Principal -// credentials scoped to the named resource. -func NewServicePrincipalToken(oauthConfig OAuthConfig, clientID string, secret string, resource string, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) { - return NewServicePrincipalTokenWithSecret( - oauthConfig, - clientID, - resource, - &ServicePrincipalTokenSecret{ - ClientSecret: secret, - }, - callbacks..., - ) -} - -// NewServicePrincipalTokenFromCertificate create a ServicePrincipalToken from the supplied pkcs12 bytes. -func NewServicePrincipalTokenFromCertificate(oauthConfig OAuthConfig, clientID string, certificate *x509.Certificate, privateKey *rsa.PrivateKey, resource string, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) { - return NewServicePrincipalTokenWithSecret( - oauthConfig, - clientID, - resource, - &ServicePrincipalCertificateSecret{ - PrivateKey: privateKey, - Certificate: certificate, - }, - callbacks..., - ) -} - -// EnsureFresh will refresh the token if it will expire within the refresh window (as set by -// RefreshWithin). -func (spt *ServicePrincipalToken) EnsureFresh() error { - if spt.WillExpireIn(spt.refreshWithin) { - return spt.Refresh() - } - return nil -} - -// InvokeRefreshCallbacks calls any TokenRefreshCallbacks that were added to the SPT during initialization -func (spt *ServicePrincipalToken) InvokeRefreshCallbacks(token Token) error { - if spt.refreshCallbacks != nil { - for _, callback := range spt.refreshCallbacks { - err := callback(spt.Token) - if err != nil { - return autorest.NewErrorWithError(err, - "azure.ServicePrincipalToken", "InvokeRefreshCallbacks", nil, "A TokenRefreshCallback handler returned an error") - } - } - } - return nil -} - -// Refresh obtains a fresh token for the Service Principal. -func (spt *ServicePrincipalToken) Refresh() error { - return spt.refreshInternal(spt.resource) -} - -// RefreshExchange refreshes the token, but for a different resource. -func (spt *ServicePrincipalToken) RefreshExchange(resource string) error { - return spt.refreshInternal(resource) -} - -func (spt *ServicePrincipalToken) refreshInternal(resource string) error { - v := url.Values{} - v.Set("client_id", spt.clientID) - v.Set("resource", resource) - - if spt.RefreshToken != "" { - v.Set("grant_type", OAuthGrantTypeRefreshToken) - v.Set("refresh_token", spt.RefreshToken) - } else { - v.Set("grant_type", OAuthGrantTypeClientCredentials) - err := spt.secret.SetAuthenticationValues(spt, &v) - if err != nil { - return err - } - } - - req, _ := autorest.Prepare(&http.Request{}, - autorest.AsPost(), - autorest.AsFormURLEncoded(), - autorest.WithBaseURL(spt.oauthConfig.TokenEndpoint.String()), - autorest.WithFormData(v)) - - resp, err := autorest.SendWithSender(spt.sender, req) - if err != nil { - return autorest.NewErrorWithError(err, - "azure.ServicePrincipalToken", "Refresh", resp, "Failure sending request for Service Principal %s", - spt.clientID) - } - - var newToken Token - err = autorest.Respond(resp, - autorest.WithErrorUnlessStatusCode(http.StatusOK), - autorest.ByUnmarshallingJSON(&newToken), - autorest.ByClosing()) - if err != nil { - return autorest.NewErrorWithError(err, - "azure.ServicePrincipalToken", "Refresh", resp, "Failure handling response to Service Principal %s request", - spt.clientID) - } - - spt.Token = newToken - - err = spt.InvokeRefreshCallbacks(newToken) - if err != nil { - // its already wrapped inside InvokeRefreshCallbacks - return err - } - - return nil -} - -// SetAutoRefresh enables or disables automatic refreshing of stale tokens. -func (spt *ServicePrincipalToken) SetAutoRefresh(autoRefresh bool) { - spt.autoRefresh = autoRefresh -} - -// SetRefreshWithin sets the interval within which if the token will expire, EnsureFresh will -// refresh the token. -func (spt *ServicePrincipalToken) SetRefreshWithin(d time.Duration) { - spt.refreshWithin = d - return -} - -// SetSender sets the autorest.Sender used when obtaining the Service Principal token. An -// undecorated http.Client is used by default. -func (spt *ServicePrincipalToken) SetSender(s autorest.Sender) { - spt.sender = s -} - -// WithAuthorization returns a PrepareDecorator that adds an HTTP Authorization header whose -// value is "Bearer " followed by the AccessToken of the ServicePrincipalToken. -// -// By default, the token will automatically refresh if nearly expired (as determined by the -// RefreshWithin interval). Use the AutoRefresh method to enable or disable automatically refreshing -// tokens. -func (spt *ServicePrincipalToken) WithAuthorization() autorest.PrepareDecorator { - return func(p autorest.Preparer) autorest.Preparer { - return autorest.PreparerFunc(func(r *http.Request) (*http.Request, error) { - if spt.autoRefresh { - err := spt.EnsureFresh() - if err != nil { - return r, autorest.NewErrorWithError(err, - "azure.ServicePrincipalToken", "WithAuthorization", nil, "Failed to refresh Service Principal Token for request to %s", - r.URL) - } - } - return (autorest.WithBearerAuthorization(spt.AccessToken)(p)).Prepare(r) - }) - } -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/client.go b/vendor/github.com/Azure/go-autorest/autorest/client.go deleted file mode 100644 index b5f94b5c3c..0000000000 --- a/vendor/github.com/Azure/go-autorest/autorest/client.go +++ /dev/null @@ -1,235 +0,0 @@ -package autorest - -import ( - "bytes" - "fmt" - "io" - "io/ioutil" - "log" - "net/http" - "net/http/cookiejar" - "runtime" - "time" -) - -const ( - // DefaultPollingDelay is a reasonable delay between polling requests. - DefaultPollingDelay = 60 * time.Second - - // DefaultPollingDuration is a reasonable total polling duration. - DefaultPollingDuration = 15 * time.Minute - - // DefaultRetryAttempts is number of attempts for retry status codes (5xx). - DefaultRetryAttempts = 3 -) - -var ( - // defaultUserAgent builds a string containing the Go version, system archityecture and OS, - // and the go-autorest version. - defaultUserAgent = fmt.Sprintf("Go/%s (%s-%s) go-autorest/%s", - runtime.Version(), - runtime.GOARCH, - runtime.GOOS, - Version(), - ) - - statusCodesForRetry = []int{ - http.StatusRequestTimeout, // 408 - http.StatusInternalServerError, // 500 - http.StatusBadGateway, // 502 - http.StatusServiceUnavailable, // 503 - http.StatusGatewayTimeout, // 504 - } -) - -const ( - requestFormat = `HTTP Request Begin =================================================== -%s -===================================================== HTTP Request End -` - responseFormat = `HTTP Response Begin =================================================== -%s -===================================================== HTTP Response End -` -) - -// Response serves as the base for all responses from generated clients. It provides access to the -// last http.Response. -type Response struct { - *http.Response `json:"-"` -} - -// LoggingInspector implements request and response inspectors that log the full request and -// response to a supplied log. -type LoggingInspector struct { - Logger *log.Logger -} - -// WithInspection returns a PrepareDecorator that emits the http.Request to the supplied logger. The -// body is restored after being emitted. -// -// Note: Since it reads the entire Body, this decorator should not be used where body streaming is -// important. It is best used to trace JSON or similar body values. -func (li LoggingInspector) WithInspection() PrepareDecorator { - return func(p Preparer) Preparer { - return PreparerFunc(func(r *http.Request) (*http.Request, error) { - var body, b bytes.Buffer - - defer r.Body.Close() - - r.Body = ioutil.NopCloser(io.TeeReader(r.Body, &body)) - if err := r.Write(&b); err != nil { - return nil, fmt.Errorf("Failed to write response: %v", err) - } - - li.Logger.Printf(requestFormat, b.String()) - - r.Body = ioutil.NopCloser(&body) - return p.Prepare(r) - }) - } -} - -// ByInspecting returns a RespondDecorator that emits the http.Response to the supplied logger. The -// body is restored after being emitted. -// -// Note: Since it reads the entire Body, this decorator should not be used where body streaming is -// important. It is best used to trace JSON or similar body values. -func (li LoggingInspector) ByInspecting() RespondDecorator { - return func(r Responder) Responder { - return ResponderFunc(func(resp *http.Response) error { - var body, b bytes.Buffer - defer resp.Body.Close() - resp.Body = ioutil.NopCloser(io.TeeReader(resp.Body, &body)) - if err := resp.Write(&b); err != nil { - return fmt.Errorf("Failed to write response: %v", err) - } - - li.Logger.Printf(responseFormat, b.String()) - - resp.Body = ioutil.NopCloser(&body) - return r.Respond(resp) - }) - } -} - -// Client is the base for autorest generated clients. It provides default, "do nothing" -// implementations of an Authorizer, RequestInspector, and ResponseInspector. It also returns the -// standard, undecorated http.Client as a default Sender. -// -// Generated clients should also use Error (see NewError and NewErrorWithError) for errors and -// return responses that compose with Response. -// -// Most customization of generated clients is best achieved by supplying a custom Authorizer, custom -// RequestInspector, and / or custom ResponseInspector. Users may log requests, implement circuit -// breakers (see https://msdn.microsoft.com/en-us/library/dn589784.aspx) or otherwise influence -// sending the request by providing a decorated Sender. -type Client struct { - Authorizer Authorizer - Sender Sender - RequestInspector PrepareDecorator - ResponseInspector RespondDecorator - - // PollingDelay sets the polling frequency used in absence of a Retry-After HTTP header - PollingDelay time.Duration - - // PollingDuration sets the maximum polling time after which an error is returned. - PollingDuration time.Duration - - // RetryAttempts sets the default number of retry attempts for client. - RetryAttempts int - - // RetryDuration sets the delay duration for retries. - RetryDuration time.Duration - - // UserAgent, if not empty, will be set as the HTTP User-Agent header on all requests sent - // through the Do method. - UserAgent string - - Jar http.CookieJar -} - -// NewClientWithUserAgent returns an instance of a Client with the UserAgent set to the passed -// string. -func NewClientWithUserAgent(ua string) Client { - c := Client{ - PollingDelay: DefaultPollingDelay, - PollingDuration: DefaultPollingDuration, - RetryAttempts: DefaultRetryAttempts, - RetryDuration: 30 * time.Second, - UserAgent: defaultUserAgent, - } - c.AddToUserAgent(ua) - return c -} - -// AddToUserAgent adds an extension to the current user agent -func (c *Client) AddToUserAgent(extension string) error { - if extension != "" { - c.UserAgent = fmt.Sprintf("%s %s", c.UserAgent, extension) - return nil - } - return fmt.Errorf("Extension was empty, User Agent stayed as %s", c.UserAgent) -} - -// Do implements the Sender interface by invoking the active Sender after applying authorization. -// If Sender is not set, it uses a new instance of http.Client. In both cases it will, if UserAgent -// is set, apply set the User-Agent header. -func (c Client) Do(r *http.Request) (*http.Response, error) { - if r.UserAgent() == "" { - r, _ = Prepare(r, - WithUserAgent(c.UserAgent)) - } - r, err := Prepare(r, - c.WithInspection(), - c.WithAuthorization()) - if err != nil { - return nil, NewErrorWithError(err, "autorest/Client", "Do", nil, "Preparing request failed") - } - resp, err := SendWithSender(c.sender(), r, - DoRetryForStatusCodes(c.RetryAttempts, c.RetryDuration, statusCodesForRetry...)) - Respond(resp, - c.ByInspecting()) - return resp, err -} - -// sender returns the Sender to which to send requests. -func (c Client) sender() Sender { - if c.Sender == nil { - j, _ := cookiejar.New(nil) - return &http.Client{Jar: j} - } - return c.Sender -} - -// WithAuthorization is a convenience method that returns the WithAuthorization PrepareDecorator -// from the current Authorizer. If not Authorizer is set, it uses the NullAuthorizer. -func (c Client) WithAuthorization() PrepareDecorator { - return c.authorizer().WithAuthorization() -} - -// authorizer returns the Authorizer to use. -func (c Client) authorizer() Authorizer { - if c.Authorizer == nil { - return NullAuthorizer{} - } - return c.Authorizer -} - -// WithInspection is a convenience method that passes the request to the supplied RequestInspector, -// if present, or returns the WithNothing PrepareDecorator otherwise. -func (c Client) WithInspection() PrepareDecorator { - if c.RequestInspector == nil { - return WithNothing() - } - return c.RequestInspector -} - -// ByInspecting is a convenience method that passes the response to the supplied ResponseInspector, -// if present, or returns the ByIgnoring RespondDecorator otherwise. -func (c Client) ByInspecting() RespondDecorator { - if c.ResponseInspector == nil { - return ByIgnoring() - } - return c.ResponseInspector -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/date/date.go b/vendor/github.com/Azure/go-autorest/autorest/date/date.go deleted file mode 100644 index 80ca60e9b0..0000000000 --- a/vendor/github.com/Azure/go-autorest/autorest/date/date.go +++ /dev/null @@ -1,82 +0,0 @@ -/* -Package date provides time.Time derivatives that conform to the Swagger.io (https://swagger.io/) -defined date formats: Date and DateTime. Both types may, in most cases, be used in lieu of -time.Time types. And both convert to time.Time through a ToTime method. -*/ -package date - -import ( - "fmt" - "time" -) - -const ( - fullDate = "2006-01-02" - fullDateJSON = `"2006-01-02"` - dateFormat = "%04d-%02d-%02d" - jsonFormat = `"%04d-%02d-%02d"` -) - -// Date defines a type similar to time.Time but assumes a layout of RFC3339 full-date (i.e., -// 2006-01-02). -type Date struct { - time.Time -} - -// ParseDate create a new Date from the passed string. -func ParseDate(date string) (d Date, err error) { - return parseDate(date, fullDate) -} - -func parseDate(date string, format string) (Date, error) { - d, err := time.Parse(format, date) - return Date{Time: d}, err -} - -// MarshalBinary preserves the Date as a byte array conforming to RFC3339 full-date (i.e., -// 2006-01-02). -func (d Date) MarshalBinary() ([]byte, error) { - return d.MarshalText() -} - -// UnmarshalBinary reconstitutes a Date saved as a byte array conforming to RFC3339 full-date (i.e., -// 2006-01-02). -func (d *Date) UnmarshalBinary(data []byte) error { - return d.UnmarshalText(data) -} - -// MarshalJSON preserves the Date as a JSON string conforming to RFC3339 full-date (i.e., -// 2006-01-02). -func (d Date) MarshalJSON() (json []byte, err error) { - return []byte(fmt.Sprintf(jsonFormat, d.Year(), d.Month(), d.Day())), nil -} - -// UnmarshalJSON reconstitutes the Date from a JSON string conforming to RFC3339 full-date (i.e., -// 2006-01-02). -func (d *Date) UnmarshalJSON(data []byte) (err error) { - d.Time, err = time.Parse(fullDateJSON, string(data)) - return err -} - -// MarshalText preserves the Date as a byte array conforming to RFC3339 full-date (i.e., -// 2006-01-02). -func (d Date) MarshalText() (text []byte, err error) { - return []byte(fmt.Sprintf(dateFormat, d.Year(), d.Month(), d.Day())), nil -} - -// UnmarshalText reconstitutes a Date saved as a byte array conforming to RFC3339 full-date (i.e., -// 2006-01-02). -func (d *Date) UnmarshalText(data []byte) (err error) { - d.Time, err = time.Parse(fullDate, string(data)) - return err -} - -// String returns the Date formatted as an RFC3339 full-date string (i.e., 2006-01-02). -func (d Date) String() string { - return fmt.Sprintf(dateFormat, d.Year(), d.Month(), d.Day()) -} - -// ToTime returns a Date as a time.Time -func (d Date) ToTime() time.Time { - return d.Time -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/date/time.go b/vendor/github.com/Azure/go-autorest/autorest/date/time.go deleted file mode 100644 index c1af629634..0000000000 --- a/vendor/github.com/Azure/go-autorest/autorest/date/time.go +++ /dev/null @@ -1,89 +0,0 @@ -package date - -import ( - "regexp" - "time" -) - -// Azure reports time in UTC but it doesn't include the 'Z' time zone suffix in some cases. -const ( - azureUtcFormatJSON = `"2006-01-02T15:04:05.999999999"` - azureUtcFormat = "2006-01-02T15:04:05.999999999" - rfc3339JSON = `"` + time.RFC3339Nano + `"` - rfc3339 = time.RFC3339Nano - tzOffsetRegex = `(Z|z|\+|-)(\d+:\d+)*"*$` -) - -// Time defines a type similar to time.Time but assumes a layout of RFC3339 date-time (i.e., -// 2006-01-02T15:04:05Z). -type Time struct { - time.Time -} - -// MarshalBinary preserves the Time as a byte array conforming to RFC3339 date-time (i.e., -// 2006-01-02T15:04:05Z). -func (t Time) MarshalBinary() ([]byte, error) { - return t.Time.MarshalText() -} - -// UnmarshalBinary reconstitutes a Time saved as a byte array conforming to RFC3339 date-time -// (i.e., 2006-01-02T15:04:05Z). -func (t *Time) UnmarshalBinary(data []byte) error { - return t.UnmarshalText(data) -} - -// MarshalJSON preserves the Time as a JSON string conforming to RFC3339 date-time (i.e., -// 2006-01-02T15:04:05Z). -func (t Time) MarshalJSON() (json []byte, err error) { - return t.Time.MarshalJSON() -} - -// UnmarshalJSON reconstitutes the Time from a JSON string conforming to RFC3339 date-time -// (i.e., 2006-01-02T15:04:05Z). -func (t *Time) UnmarshalJSON(data []byte) (err error) { - timeFormat := azureUtcFormatJSON - match, err := regexp.Match(tzOffsetRegex, data) - if err != nil { - return err - } else if match { - timeFormat = rfc3339JSON - } - t.Time, err = ParseTime(timeFormat, string(data)) - return err -} - -// MarshalText preserves the Time as a byte array conforming to RFC3339 date-time (i.e., -// 2006-01-02T15:04:05Z). -func (t Time) MarshalText() (text []byte, err error) { - return t.Time.MarshalText() -} - -// UnmarshalText reconstitutes a Time saved as a byte array conforming to RFC3339 date-time -// (i.e., 2006-01-02T15:04:05Z). -func (t *Time) UnmarshalText(data []byte) (err error) { - timeFormat := azureUtcFormat - match, err := regexp.Match(tzOffsetRegex, data) - if err != nil { - return err - } else if match { - timeFormat = rfc3339 - } - t.Time, err = ParseTime(timeFormat, string(data)) - return err -} - -// String returns the Time formatted as an RFC3339 date-time string (i.e., -// 2006-01-02T15:04:05Z). -func (t Time) String() string { - // Note: time.Time.String does not return an RFC3339 compliant string, time.Time.MarshalText does. - b, err := t.MarshalText() - if err != nil { - return "" - } - return string(b) -} - -// ToTime returns a Time as a time.Time -func (t Time) ToTime() time.Time { - return t.Time -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/date/timerfc1123.go b/vendor/github.com/Azure/go-autorest/autorest/date/timerfc1123.go deleted file mode 100644 index 11995fb9f2..0000000000 --- a/vendor/github.com/Azure/go-autorest/autorest/date/timerfc1123.go +++ /dev/null @@ -1,86 +0,0 @@ -package date - -import ( - "errors" - "time" -) - -const ( - rfc1123JSON = `"` + time.RFC1123 + `"` - rfc1123 = time.RFC1123 -) - -// TimeRFC1123 defines a type similar to time.Time but assumes a layout of RFC1123 date-time (i.e., -// Mon, 02 Jan 2006 15:04:05 MST). -type TimeRFC1123 struct { - time.Time -} - -// UnmarshalJSON reconstitutes the Time from a JSON string conforming to RFC1123 date-time -// (i.e., Mon, 02 Jan 2006 15:04:05 MST). -func (t *TimeRFC1123) UnmarshalJSON(data []byte) (err error) { - t.Time, err = ParseTime(rfc1123JSON, string(data)) - if err != nil { - return err - } - return nil -} - -// MarshalJSON preserves the Time as a JSON string conforming to RFC1123 date-time (i.e., -// Mon, 02 Jan 2006 15:04:05 MST). -func (t TimeRFC1123) MarshalJSON() ([]byte, error) { - if y := t.Year(); y < 0 || y >= 10000 { - return nil, errors.New("Time.MarshalJSON: year outside of range [0,9999]") - } - b := []byte(t.Format(rfc1123JSON)) - return b, nil -} - -// MarshalText preserves the Time as a byte array conforming to RFC1123 date-time (i.e., -// Mon, 02 Jan 2006 15:04:05 MST). -func (t TimeRFC1123) MarshalText() ([]byte, error) { - if y := t.Year(); y < 0 || y >= 10000 { - return nil, errors.New("Time.MarshalText: year outside of range [0,9999]") - } - - b := []byte(t.Format(rfc1123)) - return b, nil -} - -// UnmarshalText reconstitutes a Time saved as a byte array conforming to RFC1123 date-time -// (i.e., Mon, 02 Jan 2006 15:04:05 MST). -func (t *TimeRFC1123) UnmarshalText(data []byte) (err error) { - t.Time, err = ParseTime(rfc1123, string(data)) - if err != nil { - return err - } - return nil -} - -// MarshalBinary preserves the Time as a byte array conforming to RFC1123 date-time (i.e., -// Mon, 02 Jan 2006 15:04:05 MST). -func (t TimeRFC1123) MarshalBinary() ([]byte, error) { - return t.MarshalText() -} - -// UnmarshalBinary reconstitutes a Time saved as a byte array conforming to RFC1123 date-time -// (i.e., Mon, 02 Jan 2006 15:04:05 MST). -func (t *TimeRFC1123) UnmarshalBinary(data []byte) error { - return t.UnmarshalText(data) -} - -// ToTime returns a Time as a time.Time -func (t TimeRFC1123) ToTime() time.Time { - return t.Time -} - -// String returns the Time formatted as an RFC1123 date-time string (i.e., -// Mon, 02 Jan 2006 15:04:05 MST). -func (t TimeRFC1123) String() string { - // Note: time.Time.String does not return an RFC1123 compliant string, time.Time.MarshalText does. - b, err := t.MarshalText() - if err != nil { - return "" - } - return string(b) -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/date/utility.go b/vendor/github.com/Azure/go-autorest/autorest/date/utility.go deleted file mode 100644 index 207b1a240a..0000000000 --- a/vendor/github.com/Azure/go-autorest/autorest/date/utility.go +++ /dev/null @@ -1,11 +0,0 @@ -package date - -import ( - "strings" - "time" -) - -// ParseTime to parse Time string to specified format. -func ParseTime(format string, t string) (d time.Time, err error) { - return time.Parse(format, strings.ToUpper(t)) -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/error.go b/vendor/github.com/Azure/go-autorest/autorest/error.go deleted file mode 100644 index 4bcb8f27b2..0000000000 --- a/vendor/github.com/Azure/go-autorest/autorest/error.go +++ /dev/null @@ -1,80 +0,0 @@ -package autorest - -import ( - "fmt" - "net/http" -) - -const ( - // UndefinedStatusCode is used when HTTP status code is not available for an error. - UndefinedStatusCode = 0 -) - -// DetailedError encloses a error with details of the package, method, and associated HTTP -// status code (if any). -type DetailedError struct { - Original error - - // PackageType is the package type of the object emitting the error. For types, the value - // matches that produced the the '%T' format specifier of the fmt package. For other elements, - // such as functions, it is just the package name (e.g., "autorest"). - PackageType string - - // Method is the name of the method raising the error. - Method string - - // StatusCode is the HTTP Response StatusCode (if non-zero) that led to the error. - StatusCode interface{} - - // Message is the error message. - Message string - - // Service Error is the response body of failed API in bytes - ServiceError []byte -} - -// NewError creates a new Error conforming object from the passed packageType, method, and -// message. message is treated as a format string to which the optional args apply. -func NewError(packageType string, method string, message string, args ...interface{}) DetailedError { - return NewErrorWithError(nil, packageType, method, nil, message, args...) -} - -// NewErrorWithResponse creates a new Error conforming object from the passed -// packageType, method, statusCode of the given resp (UndefinedStatusCode if -// resp is nil), and message. message is treated as a format string to which the -// optional args apply. -func NewErrorWithResponse(packageType string, method string, resp *http.Response, message string, args ...interface{}) DetailedError { - return NewErrorWithError(nil, packageType, method, resp, message, args...) -} - -// NewErrorWithError creates a new Error conforming object from the -// passed packageType, method, statusCode of the given resp (UndefinedStatusCode -// if resp is nil), message, and original error. message is treated as a format -// string to which the optional args apply. -func NewErrorWithError(original error, packageType string, method string, resp *http.Response, message string, args ...interface{}) DetailedError { - if v, ok := original.(DetailedError); ok { - return v - } - - statusCode := UndefinedStatusCode - if resp != nil { - statusCode = resp.StatusCode - } - - return DetailedError{ - Original: original, - PackageType: packageType, - Method: method, - StatusCode: statusCode, - Message: fmt.Sprintf(message, args...), - } -} - -// Error returns a formatted containing all available details (i.e., PackageType, Method, -// StatusCode, Message, and original error (if any)). -func (e DetailedError) Error() string { - if e.Original == nil { - return fmt.Sprintf("%s#%s: %s: StatusCode=%d", e.PackageType, e.Method, e.Message, e.StatusCode) - } - return fmt.Sprintf("%s#%s: %s: StatusCode=%d -- Original Error: %v", e.PackageType, e.Method, e.Message, e.StatusCode, e.Original) -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/preparer.go b/vendor/github.com/Azure/go-autorest/autorest/preparer.go deleted file mode 100644 index c9deb261a1..0000000000 --- a/vendor/github.com/Azure/go-autorest/autorest/preparer.go +++ /dev/null @@ -1,443 +0,0 @@ -package autorest - -import ( - "bytes" - "encoding/json" - "fmt" - "io" - "io/ioutil" - "mime/multipart" - "net/http" - "net/url" - "strings" -) - -const ( - mimeTypeJSON = "application/json" - mimeTypeFormPost = "application/x-www-form-urlencoded" - - headerAuthorization = "Authorization" - headerContentType = "Content-Type" - headerUserAgent = "User-Agent" -) - -// Preparer is the interface that wraps the Prepare method. -// -// Prepare accepts and possibly modifies an http.Request (e.g., adding Headers). Implementations -// must ensure to not share or hold per-invocation state since Preparers may be shared and re-used. -type Preparer interface { - Prepare(*http.Request) (*http.Request, error) -} - -// PreparerFunc is a method that implements the Preparer interface. -type PreparerFunc func(*http.Request) (*http.Request, error) - -// Prepare implements the Preparer interface on PreparerFunc. -func (pf PreparerFunc) Prepare(r *http.Request) (*http.Request, error) { - return pf(r) -} - -// PrepareDecorator takes and possibly decorates, by wrapping, a Preparer. Decorators may affect the -// http.Request and pass it along or, first, pass the http.Request along then affect the result. -type PrepareDecorator func(Preparer) Preparer - -// CreatePreparer creates, decorates, and returns a Preparer. -// Without decorators, the returned Preparer returns the passed http.Request unmodified. -// Preparers are safe to share and re-use. -func CreatePreparer(decorators ...PrepareDecorator) Preparer { - return DecoratePreparer( - Preparer(PreparerFunc(func(r *http.Request) (*http.Request, error) { return r, nil })), - decorators...) -} - -// DecoratePreparer accepts a Preparer and a, possibly empty, set of PrepareDecorators, which it -// applies to the Preparer. Decorators are applied in the order received, but their affect upon the -// request depends on whether they are a pre-decorator (change the http.Request and then pass it -// along) or a post-decorator (pass the http.Request along and alter it on return). -func DecoratePreparer(p Preparer, decorators ...PrepareDecorator) Preparer { - for _, decorate := range decorators { - p = decorate(p) - } - return p -} - -// Prepare accepts an http.Request and a, possibly empty, set of PrepareDecorators. -// It creates a Preparer from the decorators which it then applies to the passed http.Request. -func Prepare(r *http.Request, decorators ...PrepareDecorator) (*http.Request, error) { - if r == nil { - return nil, NewError("autorest", "Prepare", "Invoked without an http.Request") - } - return CreatePreparer(decorators...).Prepare(r) -} - -// WithNothing returns a "do nothing" PrepareDecorator that makes no changes to the passed -// http.Request. -func WithNothing() PrepareDecorator { - return func(p Preparer) Preparer { - return PreparerFunc(func(r *http.Request) (*http.Request, error) { - return p.Prepare(r) - }) - } -} - -// WithHeader returns a PrepareDecorator that sets the specified HTTP header of the http.Request to -// the passed value. It canonicalizes the passed header name (via http.CanonicalHeaderKey) before -// adding the header. -func WithHeader(header string, value string) PrepareDecorator { - return func(p Preparer) Preparer { - return PreparerFunc(func(r *http.Request) (*http.Request, error) { - r, err := p.Prepare(r) - if err == nil { - if r.Header == nil { - r.Header = make(http.Header) - } - r.Header.Set(http.CanonicalHeaderKey(header), value) - } - return r, err - }) - } -} - -// WithBearerAuthorization returns a PrepareDecorator that adds an HTTP Authorization header whose -// value is "Bearer " followed by the supplied token. -func WithBearerAuthorization(token string) PrepareDecorator { - return WithHeader(headerAuthorization, fmt.Sprintf("Bearer %s", token)) -} - -// AsContentType returns a PrepareDecorator that adds an HTTP Content-Type header whose value -// is the passed contentType. -func AsContentType(contentType string) PrepareDecorator { - return WithHeader(headerContentType, contentType) -} - -// WithUserAgent returns a PrepareDecorator that adds an HTTP User-Agent header whose value is the -// passed string. -func WithUserAgent(ua string) PrepareDecorator { - return WithHeader(headerUserAgent, ua) -} - -// AsFormURLEncoded returns a PrepareDecorator that adds an HTTP Content-Type header whose value is -// "application/x-www-form-urlencoded". -func AsFormURLEncoded() PrepareDecorator { - return AsContentType(mimeTypeFormPost) -} - -// AsJSON returns a PrepareDecorator that adds an HTTP Content-Type header whose value is -// "application/json". -func AsJSON() PrepareDecorator { - return AsContentType(mimeTypeJSON) -} - -// WithMethod returns a PrepareDecorator that sets the HTTP method of the passed request. The -// decorator does not validate that the passed method string is a known HTTP method. -func WithMethod(method string) PrepareDecorator { - return func(p Preparer) Preparer { - return PreparerFunc(func(r *http.Request) (*http.Request, error) { - r.Method = method - return p.Prepare(r) - }) - } -} - -// AsDelete returns a PrepareDecorator that sets the HTTP method to DELETE. -func AsDelete() PrepareDecorator { return WithMethod("DELETE") } - -// AsGet returns a PrepareDecorator that sets the HTTP method to GET. -func AsGet() PrepareDecorator { return WithMethod("GET") } - -// AsHead returns a PrepareDecorator that sets the HTTP method to HEAD. -func AsHead() PrepareDecorator { return WithMethod("HEAD") } - -// AsOptions returns a PrepareDecorator that sets the HTTP method to OPTIONS. -func AsOptions() PrepareDecorator { return WithMethod("OPTIONS") } - -// AsPatch returns a PrepareDecorator that sets the HTTP method to PATCH. -func AsPatch() PrepareDecorator { return WithMethod("PATCH") } - -// AsPost returns a PrepareDecorator that sets the HTTP method to POST. -func AsPost() PrepareDecorator { return WithMethod("POST") } - -// AsPut returns a PrepareDecorator that sets the HTTP method to PUT. -func AsPut() PrepareDecorator { return WithMethod("PUT") } - -// WithBaseURL returns a PrepareDecorator that populates the http.Request with a url.URL constructed -// from the supplied baseUrl. -func WithBaseURL(baseURL string) PrepareDecorator { - return func(p Preparer) Preparer { - return PreparerFunc(func(r *http.Request) (*http.Request, error) { - r, err := p.Prepare(r) - if err == nil { - var u *url.URL - if u, err = url.Parse(baseURL); err != nil { - return r, err - } - if u.Scheme == "" { - err = fmt.Errorf("autorest: No scheme detected in URL %s", baseURL) - } - if err == nil { - r.URL = u - } - } - return r, err - }) - } -} - -// WithCustomBaseURL returns a PrepareDecorator that replaces brace-enclosed keys within the -// request base URL (i.e., http.Request.URL) with the corresponding values from the passed map. -func WithCustomBaseURL(baseURL string, urlParameters map[string]interface{}) PrepareDecorator { - parameters := ensureValueStrings(urlParameters) - for key, value := range parameters { - baseURL = strings.Replace(baseURL, "{"+key+"}", value, -1) - } - return WithBaseURL(baseURL) -} - -// WithFormData returns a PrepareDecoratore that "URL encodes" (e.g., bar=baz&foo=quux) into the -// http.Request body. -func WithFormData(v url.Values) PrepareDecorator { - return func(p Preparer) Preparer { - return PreparerFunc(func(r *http.Request) (*http.Request, error) { - r, err := p.Prepare(r) - if err == nil { - s := v.Encode() - r.ContentLength = int64(len(s)) - r.Body = ioutil.NopCloser(strings.NewReader(s)) - } - return r, err - }) - } -} - -// WithMultiPartFormData returns a PrepareDecoratore that "URL encodes" (e.g., bar=baz&foo=quux) form parameters -// into the http.Request body. -func WithMultiPartFormData(formDataParameters map[string]interface{}) PrepareDecorator { - return func(p Preparer) Preparer { - return PreparerFunc(func(r *http.Request) (*http.Request, error) { - r, err := p.Prepare(r) - if err == nil { - var body bytes.Buffer - writer := multipart.NewWriter(&body) - for key, value := range formDataParameters { - if rc, ok := value.(io.ReadCloser); ok { - var fd io.Writer - if fd, err = writer.CreateFormFile(key, key); err != nil { - return r, err - } - if _, err = io.Copy(fd, rc); err != nil { - return r, err - } - } else { - if err = writer.WriteField(key, ensureValueString(value)); err != nil { - return r, err - } - } - } - if err = writer.Close(); err != nil { - return r, err - } - if r.Header == nil { - r.Header = make(http.Header) - } - r.Header.Set(http.CanonicalHeaderKey(headerContentType), writer.FormDataContentType()) - r.Body = ioutil.NopCloser(bytes.NewReader(body.Bytes())) - r.ContentLength = int64(body.Len()) - return r, err - } - return r, err - }) - } -} - -// WithFile returns a PrepareDecorator that sends file in request body. -func WithFile(f io.ReadCloser) PrepareDecorator { - return func(p Preparer) Preparer { - return PreparerFunc(func(r *http.Request) (*http.Request, error) { - r, err := p.Prepare(r) - if err == nil { - b, err := ioutil.ReadAll(f) - if err != nil { - return r, err - } - r.Body = ioutil.NopCloser(bytes.NewReader(b)) - r.ContentLength = int64(len(b)) - } - return r, err - }) - } -} - -// WithBool returns a PrepareDecorator that encodes the passed bool into the body of the request -// and sets the Content-Length header. -func WithBool(v bool) PrepareDecorator { - return WithString(fmt.Sprintf("%v", v)) -} - -// WithFloat32 returns a PrepareDecorator that encodes the passed float32 into the body of the -// request and sets the Content-Length header. -func WithFloat32(v float32) PrepareDecorator { - return WithString(fmt.Sprintf("%v", v)) -} - -// WithFloat64 returns a PrepareDecorator that encodes the passed float64 into the body of the -// request and sets the Content-Length header. -func WithFloat64(v float64) PrepareDecorator { - return WithString(fmt.Sprintf("%v", v)) -} - -// WithInt32 returns a PrepareDecorator that encodes the passed int32 into the body of the request -// and sets the Content-Length header. -func WithInt32(v int32) PrepareDecorator { - return WithString(fmt.Sprintf("%v", v)) -} - -// WithInt64 returns a PrepareDecorator that encodes the passed int64 into the body of the request -// and sets the Content-Length header. -func WithInt64(v int64) PrepareDecorator { - return WithString(fmt.Sprintf("%v", v)) -} - -// WithString returns a PrepareDecorator that encodes the passed string into the body of the request -// and sets the Content-Length header. -func WithString(v string) PrepareDecorator { - return func(p Preparer) Preparer { - return PreparerFunc(func(r *http.Request) (*http.Request, error) { - r, err := p.Prepare(r) - if err == nil { - r.ContentLength = int64(len(v)) - r.Body = ioutil.NopCloser(strings.NewReader(v)) - } - return r, err - }) - } -} - -// WithJSON returns a PrepareDecorator that encodes the data passed as JSON into the body of the -// request and sets the Content-Length header. -func WithJSON(v interface{}) PrepareDecorator { - return func(p Preparer) Preparer { - return PreparerFunc(func(r *http.Request) (*http.Request, error) { - r, err := p.Prepare(r) - if err == nil { - b, err := json.Marshal(v) - if err == nil { - r.ContentLength = int64(len(b)) - r.Body = ioutil.NopCloser(bytes.NewReader(b)) - } - } - return r, err - }) - } -} - -// WithPath returns a PrepareDecorator that adds the supplied path to the request URL. If the path -// is absolute (that is, it begins with a "/"), it replaces the existing path. -func WithPath(path string) PrepareDecorator { - return func(p Preparer) Preparer { - return PreparerFunc(func(r *http.Request) (*http.Request, error) { - r, err := p.Prepare(r) - if err == nil { - if r.URL == nil { - return r, NewError("autorest", "WithPath", "Invoked with a nil URL") - } - if r.URL, err = parseURL(r.URL, path); err != nil { - return r, err - } - } - return r, err - }) - } -} - -// WithEscapedPathParameters returns a PrepareDecorator that replaces brace-enclosed keys within the -// request path (i.e., http.Request.URL.Path) with the corresponding values from the passed map. The -// values will be escaped (aka URL encoded) before insertion into the path. -func WithEscapedPathParameters(path string, pathParameters map[string]interface{}) PrepareDecorator { - parameters := escapeValueStrings(ensureValueStrings(pathParameters)) - return func(p Preparer) Preparer { - return PreparerFunc(func(r *http.Request) (*http.Request, error) { - r, err := p.Prepare(r) - if err == nil { - if r.URL == nil { - return r, NewError("autorest", "WithEscapedPathParameters", "Invoked with a nil URL") - } - for key, value := range parameters { - path = strings.Replace(path, "{"+key+"}", value, -1) - } - if r.URL, err = parseURL(r.URL, path); err != nil { - return r, err - } - } - return r, err - }) - } -} - -// WithPathParameters returns a PrepareDecorator that replaces brace-enclosed keys within the -// request path (i.e., http.Request.URL.Path) with the corresponding values from the passed map. -func WithPathParameters(path string, pathParameters map[string]interface{}) PrepareDecorator { - parameters := ensureValueStrings(pathParameters) - return func(p Preparer) Preparer { - return PreparerFunc(func(r *http.Request) (*http.Request, error) { - r, err := p.Prepare(r) - if err == nil { - if r.URL == nil { - return r, NewError("autorest", "WithPathParameters", "Invoked with a nil URL") - } - for key, value := range parameters { - path = strings.Replace(path, "{"+key+"}", value, -1) - } - - if r.URL, err = parseURL(r.URL, path); err != nil { - return r, err - } - } - return r, err - }) - } -} - -func parseURL(u *url.URL, path string) (*url.URL, error) { - p := strings.TrimRight(u.String(), "/") - if !strings.HasPrefix(path, "/") { - path = "/" + path - } - return url.Parse(p + path) -} - -// WithQueryParameters returns a PrepareDecorators that encodes and applies the query parameters -// given in the supplied map (i.e., key=value). -func WithQueryParameters(queryParameters map[string]interface{}) PrepareDecorator { - parameters := ensureValueStrings(queryParameters) - return func(p Preparer) Preparer { - return PreparerFunc(func(r *http.Request) (*http.Request, error) { - r, err := p.Prepare(r) - if err == nil { - if r.URL == nil { - return r, NewError("autorest", "WithQueryParameters", "Invoked with a nil URL") - } - v := r.URL.Query() - for key, value := range parameters { - v.Add(key, value) - } - r.URL.RawQuery = createQuery(v) - } - return r, err - }) - } -} - -// Authorizer is the interface that provides a PrepareDecorator used to supply request -// authorization. Most often, the Authorizer decorator runs last so it has access to the full -// state of the formed HTTP request. -type Authorizer interface { - WithAuthorization() PrepareDecorator -} - -// NullAuthorizer implements a default, "do nothing" Authorizer. -type NullAuthorizer struct{} - -// WithAuthorization returns a PrepareDecorator that does nothing. -func (na NullAuthorizer) WithAuthorization() PrepareDecorator { - return WithNothing() -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/responder.go b/vendor/github.com/Azure/go-autorest/autorest/responder.go deleted file mode 100644 index 87f71e5854..0000000000 --- a/vendor/github.com/Azure/go-autorest/autorest/responder.go +++ /dev/null @@ -1,236 +0,0 @@ -package autorest - -import ( - "bytes" - "encoding/json" - "encoding/xml" - "fmt" - "io" - "io/ioutil" - "net/http" - "strings" -) - -// Responder is the interface that wraps the Respond method. -// -// Respond accepts and reacts to an http.Response. Implementations must ensure to not share or hold -// state since Responders may be shared and re-used. -type Responder interface { - Respond(*http.Response) error -} - -// ResponderFunc is a method that implements the Responder interface. -type ResponderFunc func(*http.Response) error - -// Respond implements the Responder interface on ResponderFunc. -func (rf ResponderFunc) Respond(r *http.Response) error { - return rf(r) -} - -// RespondDecorator takes and possibly decorates, by wrapping, a Responder. Decorators may react to -// the http.Response and pass it along or, first, pass the http.Response along then react. -type RespondDecorator func(Responder) Responder - -// CreateResponder creates, decorates, and returns a Responder. Without decorators, the returned -// Responder returns the passed http.Response unmodified. Responders may or may not be safe to share -// and re-used: It depends on the applied decorators. For example, a standard decorator that closes -// the response body is fine to share whereas a decorator that reads the body into a passed struct -// is not. -// -// To prevent memory leaks, ensure that at least one Responder closes the response body. -func CreateResponder(decorators ...RespondDecorator) Responder { - return DecorateResponder( - Responder(ResponderFunc(func(r *http.Response) error { return nil })), - decorators...) -} - -// DecorateResponder accepts a Responder and a, possibly empty, set of RespondDecorators, which it -// applies to the Responder. Decorators are applied in the order received, but their affect upon the -// request depends on whether they are a pre-decorator (react to the http.Response and then pass it -// along) or a post-decorator (pass the http.Response along and then react). -func DecorateResponder(r Responder, decorators ...RespondDecorator) Responder { - for _, decorate := range decorators { - r = decorate(r) - } - return r -} - -// Respond accepts an http.Response and a, possibly empty, set of RespondDecorators. -// It creates a Responder from the decorators it then applies to the passed http.Response. -func Respond(r *http.Response, decorators ...RespondDecorator) error { - if r == nil { - return nil - } - return CreateResponder(decorators...).Respond(r) -} - -// ByIgnoring returns a RespondDecorator that ignores the passed http.Response passing it unexamined -// to the next RespondDecorator. -func ByIgnoring() RespondDecorator { - return func(r Responder) Responder { - return ResponderFunc(func(resp *http.Response) error { - return r.Respond(resp) - }) - } -} - -// ByCopying copies the contents of the http.Response Body into the passed bytes.Buffer as -// the Body is read. -func ByCopying(b *bytes.Buffer) RespondDecorator { - return func(r Responder) Responder { - return ResponderFunc(func(resp *http.Response) error { - err := r.Respond(resp) - if err == nil && resp != nil && resp.Body != nil { - resp.Body = TeeReadCloser(resp.Body, b) - } - return err - }) - } -} - -// ByDiscardingBody returns a RespondDecorator that first invokes the passed Responder after which -// it copies the remaining bytes (if any) in the response body to ioutil.Discard. Since the passed -// Responder is invoked prior to discarding the response body, the decorator may occur anywhere -// within the set. -func ByDiscardingBody() RespondDecorator { - return func(r Responder) Responder { - return ResponderFunc(func(resp *http.Response) error { - err := r.Respond(resp) - if err == nil && resp != nil && resp.Body != nil { - if _, err := io.Copy(ioutil.Discard, resp.Body); err != nil { - return fmt.Errorf("Error discarding the response body: %v", err) - } - } - return err - }) - } -} - -// ByClosing returns a RespondDecorator that first invokes the passed Responder after which it -// closes the response body. Since the passed Responder is invoked prior to closing the response -// body, the decorator may occur anywhere within the set. -func ByClosing() RespondDecorator { - return func(r Responder) Responder { - return ResponderFunc(func(resp *http.Response) error { - err := r.Respond(resp) - if resp != nil && resp.Body != nil { - if err := resp.Body.Close(); err != nil { - return fmt.Errorf("Error closing the response body: %v", err) - } - } - return err - }) - } -} - -// ByClosingIfError returns a RespondDecorator that first invokes the passed Responder after which -// it closes the response if the passed Responder returns an error and the response body exists. -func ByClosingIfError() RespondDecorator { - return func(r Responder) Responder { - return ResponderFunc(func(resp *http.Response) error { - err := r.Respond(resp) - if err != nil && resp != nil && resp.Body != nil { - if err := resp.Body.Close(); err != nil { - return fmt.Errorf("Error closing the response body: %v", err) - } - } - return err - }) - } -} - -// ByUnmarshallingJSON returns a RespondDecorator that decodes a JSON document returned in the -// response Body into the value pointed to by v. -func ByUnmarshallingJSON(v interface{}) RespondDecorator { - return func(r Responder) Responder { - return ResponderFunc(func(resp *http.Response) error { - err := r.Respond(resp) - if err == nil { - b, errInner := ioutil.ReadAll(resp.Body) - // Some responses might include a BOM, remove for successful unmarshalling - b = bytes.TrimPrefix(b, []byte("\xef\xbb\xbf")) - if errInner != nil { - err = fmt.Errorf("Error occurred reading http.Response#Body - Error = '%v'", errInner) - } else if len(strings.Trim(string(b), " ")) > 0 { - errInner = json.Unmarshal(b, v) - if errInner != nil { - err = fmt.Errorf("Error occurred unmarshalling JSON - Error = '%v' JSON = '%s'", errInner, string(b)) - } - } - } - return err - }) - } -} - -// ByUnmarshallingXML returns a RespondDecorator that decodes a XML document returned in the -// response Body into the value pointed to by v. -func ByUnmarshallingXML(v interface{}) RespondDecorator { - return func(r Responder) Responder { - return ResponderFunc(func(resp *http.Response) error { - err := r.Respond(resp) - if err == nil { - b, errInner := ioutil.ReadAll(resp.Body) - if errInner != nil { - err = fmt.Errorf("Error occurred reading http.Response#Body - Error = '%v'", errInner) - } else { - errInner = xml.Unmarshal(b, v) - if errInner != nil { - err = fmt.Errorf("Error occurred unmarshalling Xml - Error = '%v' Xml = '%s'", errInner, string(b)) - } - } - } - return err - }) - } -} - -// WithErrorUnlessStatusCode returns a RespondDecorator that emits an error unless the response -// StatusCode is among the set passed. On error, response body is fully read into a buffer and -// presented in the returned error, as well as in the response body. -func WithErrorUnlessStatusCode(codes ...int) RespondDecorator { - return func(r Responder) Responder { - return ResponderFunc(func(resp *http.Response) error { - err := r.Respond(resp) - if err == nil && !ResponseHasStatusCode(resp, codes...) { - derr := NewErrorWithResponse("autorest", "WithErrorUnlessStatusCode", resp, "%v %v failed with %s", - resp.Request.Method, - resp.Request.URL, - resp.Status) - if resp.Body != nil { - defer resp.Body.Close() - b, _ := ioutil.ReadAll(resp.Body) - derr.ServiceError = b - resp.Body = ioutil.NopCloser(bytes.NewReader(b)) - } - err = derr - } - return err - }) - } -} - -// WithErrorUnlessOK returns a RespondDecorator that emits an error if the response StatusCode is -// anything other than HTTP 200. -func WithErrorUnlessOK() RespondDecorator { - return WithErrorUnlessStatusCode(http.StatusOK) -} - -// ExtractHeader extracts all values of the specified header from the http.Response. It returns an -// empty string slice if the passed http.Response is nil or the header does not exist. -func ExtractHeader(header string, resp *http.Response) []string { - if resp != nil && resp.Header != nil { - return resp.Header[http.CanonicalHeaderKey(header)] - } - return nil -} - -// ExtractHeaderValue extracts the first value of the specified header from the http.Response. It -// returns an empty string if the passed http.Response is nil or the header does not exist. -func ExtractHeaderValue(header string, resp *http.Response) string { - h := ExtractHeader(header, resp) - if len(h) > 0 { - return h[0] - } - return "" -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/sender.go b/vendor/github.com/Azure/go-autorest/autorest/sender.go deleted file mode 100644 index 9c0697815b..0000000000 --- a/vendor/github.com/Azure/go-autorest/autorest/sender.go +++ /dev/null @@ -1,270 +0,0 @@ -package autorest - -import ( - "bytes" - "fmt" - "io/ioutil" - "log" - "math" - "net/http" - "time" -) - -// Sender is the interface that wraps the Do method to send HTTP requests. -// -// The standard http.Client conforms to this interface. -type Sender interface { - Do(*http.Request) (*http.Response, error) -} - -// SenderFunc is a method that implements the Sender interface. -type SenderFunc func(*http.Request) (*http.Response, error) - -// Do implements the Sender interface on SenderFunc. -func (sf SenderFunc) Do(r *http.Request) (*http.Response, error) { - return sf(r) -} - -// SendDecorator takes and possibily decorates, by wrapping, a Sender. Decorators may affect the -// http.Request and pass it along or, first, pass the http.Request along then react to the -// http.Response result. -type SendDecorator func(Sender) Sender - -// CreateSender creates, decorates, and returns, as a Sender, the default http.Client. -func CreateSender(decorators ...SendDecorator) Sender { - return DecorateSender(&http.Client{}, decorators...) -} - -// DecorateSender accepts a Sender and a, possibly empty, set of SendDecorators, which is applies to -// the Sender. Decorators are applied in the order received, but their affect upon the request -// depends on whether they are a pre-decorator (change the http.Request and then pass it along) or a -// post-decorator (pass the http.Request along and react to the results in http.Response). -func DecorateSender(s Sender, decorators ...SendDecorator) Sender { - for _, decorate := range decorators { - s = decorate(s) - } - return s -} - -// Send sends, by means of the default http.Client, the passed http.Request, returning the -// http.Response and possible error. It also accepts a, possibly empty, set of SendDecorators which -// it will apply the http.Client before invoking the Do method. -// -// Send is a convenience method and not recommended for production. Advanced users should use -// SendWithSender, passing and sharing their own Sender (e.g., instance of http.Client). -// -// Send will not poll or retry requests. -func Send(r *http.Request, decorators ...SendDecorator) (*http.Response, error) { - return SendWithSender(&http.Client{}, r, decorators...) -} - -// SendWithSender sends the passed http.Request, through the provided Sender, returning the -// http.Response and possible error. It also accepts a, possibly empty, set of SendDecorators which -// it will apply the http.Client before invoking the Do method. -// -// SendWithSender will not poll or retry requests. -func SendWithSender(s Sender, r *http.Request, decorators ...SendDecorator) (*http.Response, error) { - return DecorateSender(s, decorators...).Do(r) -} - -// AfterDelay returns a SendDecorator that delays for the passed time.Duration before -// invoking the Sender. The delay may be terminated by closing the optional channel on the -// http.Request. If canceled, no further Senders are invoked. -func AfterDelay(d time.Duration) SendDecorator { - return func(s Sender) Sender { - return SenderFunc(func(r *http.Request) (*http.Response, error) { - if !DelayForBackoff(d, 0, r.Cancel) { - return nil, fmt.Errorf("autorest: AfterDelay canceled before full delay") - } - return s.Do(r) - }) - } -} - -// AsIs returns a SendDecorator that invokes the passed Sender without modifying the http.Request. -func AsIs() SendDecorator { - return func(s Sender) Sender { - return SenderFunc(func(r *http.Request) (*http.Response, error) { - return s.Do(r) - }) - } -} - -// DoCloseIfError returns a SendDecorator that first invokes the passed Sender after which -// it closes the response if the passed Sender returns an error and the response body exists. -func DoCloseIfError() SendDecorator { - return func(s Sender) Sender { - return SenderFunc(func(r *http.Request) (*http.Response, error) { - resp, err := s.Do(r) - if err != nil { - Respond(resp, ByDiscardingBody(), ByClosing()) - } - return resp, err - }) - } -} - -// DoErrorIfStatusCode returns a SendDecorator that emits an error if the response StatusCode is -// among the set passed. Since these are artificial errors, the response body may still require -// closing. -func DoErrorIfStatusCode(codes ...int) SendDecorator { - return func(s Sender) Sender { - return SenderFunc(func(r *http.Request) (*http.Response, error) { - resp, err := s.Do(r) - if err == nil && ResponseHasStatusCode(resp, codes...) { - err = NewErrorWithResponse("autorest", "DoErrorIfStatusCode", resp, "%v %v failed with %s", - resp.Request.Method, - resp.Request.URL, - resp.Status) - } - return resp, err - }) - } -} - -// DoErrorUnlessStatusCode returns a SendDecorator that emits an error unless the response -// StatusCode is among the set passed. Since these are artificial errors, the response body -// may still require closing. -func DoErrorUnlessStatusCode(codes ...int) SendDecorator { - return func(s Sender) Sender { - return SenderFunc(func(r *http.Request) (*http.Response, error) { - resp, err := s.Do(r) - if err == nil && !ResponseHasStatusCode(resp, codes...) { - err = NewErrorWithResponse("autorest", "DoErrorUnlessStatusCode", resp, "%v %v failed with %s", - resp.Request.Method, - resp.Request.URL, - resp.Status) - } - return resp, err - }) - } -} - -// DoPollForStatusCodes returns a SendDecorator that polls if the http.Response contains one of the -// passed status codes. It expects the http.Response to contain a Location header providing the -// URL at which to poll (using GET) and will poll until the time passed is equal to or greater than -// the supplied duration. It will delay between requests for the duration specified in the -// RetryAfter header or, if the header is absent, the passed delay. Polling may be canceled by -// closing the optional channel on the http.Request. -func DoPollForStatusCodes(duration time.Duration, delay time.Duration, codes ...int) SendDecorator { - return func(s Sender) Sender { - return SenderFunc(func(r *http.Request) (resp *http.Response, err error) { - resp, err = s.Do(r) - - if err == nil && ResponseHasStatusCode(resp, codes...) { - r, err = NewPollingRequest(resp, r.Cancel) - - for err == nil && ResponseHasStatusCode(resp, codes...) { - Respond(resp, - ByDiscardingBody(), - ByClosing()) - resp, err = SendWithSender(s, r, - AfterDelay(GetRetryAfter(resp, delay))) - } - } - - return resp, err - }) - } -} - -// DoRetryForAttempts returns a SendDecorator that retries a failed request for up to the specified -// number of attempts, exponentially backing off between requests using the supplied backoff -// time.Duration (which may be zero). Retrying may be canceled by closing the optional channel on -// the http.Request. -func DoRetryForAttempts(attempts int, backoff time.Duration) SendDecorator { - return func(s Sender) Sender { - return SenderFunc(func(r *http.Request) (resp *http.Response, err error) { - for attempt := 0; attempt < attempts; attempt++ { - resp, err = s.Do(r) - if err == nil { - return resp, err - } - DelayForBackoff(backoff, attempt, r.Cancel) - } - return resp, err - }) - } -} - -// DoRetryForStatusCodes returns a SendDecorator that retries for specified statusCodes for up to the specified -// number of attempts, exponentially backing off between requests using the supplied backoff -// time.Duration (which may be zero). Retrying may be canceled by closing the optional channel on -// the http.Request. -func DoRetryForStatusCodes(attempts int, backoff time.Duration, codes ...int) SendDecorator { - return func(s Sender) Sender { - return SenderFunc(func(r *http.Request) (resp *http.Response, err error) { - b := []byte{} - if r.Body != nil { - b, err = ioutil.ReadAll(r.Body) - if err != nil { - return resp, err - } - } - - // Increment to add the first call (attempts denotes number of retries) - attempts++ - for attempt := 0; attempt < attempts; attempt++ { - r.Body = ioutil.NopCloser(bytes.NewBuffer(b)) - resp, err = s.Do(r) - if err != nil || !ResponseHasStatusCode(resp, codes...) { - return resp, err - } - DelayForBackoff(backoff, attempt, r.Cancel) - } - return resp, err - }) - } -} - -// DoRetryForDuration returns a SendDecorator that retries the request until the total time is equal -// to or greater than the specified duration, exponentially backing off between requests using the -// supplied backoff time.Duration (which may be zero). Retrying may be canceled by closing the -// optional channel on the http.Request. -func DoRetryForDuration(d time.Duration, backoff time.Duration) SendDecorator { - return func(s Sender) Sender { - return SenderFunc(func(r *http.Request) (resp *http.Response, err error) { - end := time.Now().Add(d) - for attempt := 0; time.Now().Before(end); attempt++ { - resp, err = s.Do(r) - if err == nil { - return resp, err - } - DelayForBackoff(backoff, attempt, r.Cancel) - } - return resp, err - }) - } -} - -// WithLogging returns a SendDecorator that implements simple before and after logging of the -// request. -func WithLogging(logger *log.Logger) SendDecorator { - return func(s Sender) Sender { - return SenderFunc(func(r *http.Request) (*http.Response, error) { - logger.Printf("Sending %s %s", r.Method, r.URL) - resp, err := s.Do(r) - if err != nil { - logger.Printf("%s %s received error '%v'", r.Method, r.URL, err) - } else { - logger.Printf("%s %s received %s", r.Method, r.URL, resp.Status) - } - return resp, err - }) - } -} - -// DelayForBackoff invokes time.After for the supplied backoff duration raised to the power of -// passed attempt (i.e., an exponential backoff delay). Backoff duration is in seconds and can set -// to zero for no delay. The delay may be canceled by closing the passed channel. If terminated early, -// returns false. -// Note: Passing attempt 1 will result in doubling "backoff" duration. Treat this as a zero-based attempt -// count. -func DelayForBackoff(backoff time.Duration, attempt int, cancel <-chan struct{}) bool { - select { - case <-time.After(time.Duration(backoff.Seconds()*math.Pow(2, float64(attempt))) * time.Second): - return true - case <-cancel: - return false - } -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/utility.go b/vendor/github.com/Azure/go-autorest/autorest/utility.go deleted file mode 100644 index 78067148b2..0000000000 --- a/vendor/github.com/Azure/go-autorest/autorest/utility.go +++ /dev/null @@ -1,178 +0,0 @@ -package autorest - -import ( - "bytes" - "encoding/json" - "encoding/xml" - "fmt" - "io" - "net/url" - "reflect" - "sort" - "strings" -) - -// EncodedAs is a series of constants specifying various data encodings -type EncodedAs string - -const ( - // EncodedAsJSON states that data is encoded as JSON - EncodedAsJSON EncodedAs = "JSON" - - // EncodedAsXML states that data is encoded as Xml - EncodedAsXML EncodedAs = "XML" -) - -// Decoder defines the decoding method json.Decoder and xml.Decoder share -type Decoder interface { - Decode(v interface{}) error -} - -// NewDecoder creates a new decoder appropriate to the passed encoding. -// encodedAs specifies the type of encoding and r supplies the io.Reader containing the -// encoded data. -func NewDecoder(encodedAs EncodedAs, r io.Reader) Decoder { - if encodedAs == EncodedAsJSON { - return json.NewDecoder(r) - } else if encodedAs == EncodedAsXML { - return xml.NewDecoder(r) - } - return nil -} - -// CopyAndDecode decodes the data from the passed io.Reader while making a copy. Having a copy -// is especially useful if there is a chance the data will fail to decode. -// encodedAs specifies the expected encoding, r provides the io.Reader to the data, and v -// is the decoding destination. -func CopyAndDecode(encodedAs EncodedAs, r io.Reader, v interface{}) (bytes.Buffer, error) { - b := bytes.Buffer{} - return b, NewDecoder(encodedAs, io.TeeReader(r, &b)).Decode(v) -} - -// TeeReadCloser returns a ReadCloser that writes to w what it reads from rc. -// It utilizes io.TeeReader to copy the data read and has the same behavior when reading. -// Further, when it is closed, it ensures that rc is closed as well. -func TeeReadCloser(rc io.ReadCloser, w io.Writer) io.ReadCloser { - return &teeReadCloser{rc, io.TeeReader(rc, w)} -} - -type teeReadCloser struct { - rc io.ReadCloser - r io.Reader -} - -func (t *teeReadCloser) Read(p []byte) (int, error) { - return t.r.Read(p) -} - -func (t *teeReadCloser) Close() error { - return t.rc.Close() -} - -func containsInt(ints []int, n int) bool { - for _, i := range ints { - if i == n { - return true - } - } - return false -} - -func escapeValueStrings(m map[string]string) map[string]string { - for key, value := range m { - m[key] = url.QueryEscape(value) - } - return m -} - -func ensureValueStrings(mapOfInterface map[string]interface{}) map[string]string { - mapOfStrings := make(map[string]string) - for key, value := range mapOfInterface { - mapOfStrings[key] = ensureValueString(value) - } - return mapOfStrings -} - -func ensureValueString(value interface{}) string { - if value == nil { - return "" - } - switch v := value.(type) { - case string: - return v - case []byte: - return string(v) - default: - return fmt.Sprintf("%v", v) - } -} - -// MapToValues method converts map[string]interface{} to url.Values. -func MapToValues(m map[string]interface{}) url.Values { - v := url.Values{} - for key, value := range m { - x := reflect.ValueOf(value) - if x.Kind() == reflect.Array || x.Kind() == reflect.Slice { - for i := 0; i < x.Len(); i++ { - v.Add(key, ensureValueString(x.Index(i))) - } - } else { - v.Add(key, ensureValueString(value)) - } - } - return v -} - -// String method converts interface v to string. If interface is a list, it -// joins list elements using separator. -func String(v interface{}, sep ...string) string { - if len(sep) > 0 { - return ensureValueString(strings.Join(v.([]string), sep[0])) - } - return ensureValueString(v) -} - -// Encode method encodes url path and query parameters. -func Encode(location string, v interface{}, sep ...string) string { - s := String(v, sep...) - switch strings.ToLower(location) { - case "path": - return pathEscape(s) - case "query": - return queryEscape(s) - default: - return s - } -} - -func pathEscape(s string) string { - return strings.Replace(url.QueryEscape(s), "+", "%20", -1) -} - -func queryEscape(s string) string { - return url.QueryEscape(s) -} - -// This method is same as Encode() method of "net/url" go package, -// except it does not encode the query parameters because they -// already come encoded. It formats values map in query format (bar=foo&a=b). -func createQuery(v url.Values) string { - var buf bytes.Buffer - keys := make([]string, 0, len(v)) - for k := range v { - keys = append(keys, k) - } - sort.Strings(keys) - for _, k := range keys { - vs := v[k] - prefix := url.QueryEscape(k) + "=" - for _, v := range vs { - if buf.Len() > 0 { - buf.WriteByte('&') - } - buf.WriteString(prefix) - buf.WriteString(v) - } - } - return buf.String() -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/version.go b/vendor/github.com/Azure/go-autorest/autorest/version.go deleted file mode 100644 index 7a0bf9c9ff..0000000000 --- a/vendor/github.com/Azure/go-autorest/autorest/version.go +++ /dev/null @@ -1,23 +0,0 @@ -package autorest - -import ( - "fmt" -) - -const ( - major = "7" - minor = "3" - patch = "0" - tag = "" - semVerFormat = "%s.%s.%s%s" -) - -var version string - -// Version returns the semantic version (see http://semver.org). -func Version() string { - if version == "" { - version = fmt.Sprintf(semVerFormat, major, minor, patch, tag) - } - return version -} diff --git a/vendor/github.com/codahale/hdrhistogram/LICENSE b/vendor/github.com/codahale/hdrhistogram/LICENSE new file mode 100644 index 0000000000..f9835c241f --- /dev/null +++ b/vendor/github.com/codahale/hdrhistogram/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014 Coda Hale + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/codahale/hdrhistogram/README.md b/vendor/github.com/codahale/hdrhistogram/README.md new file mode 100644 index 0000000000..614b197c3d --- /dev/null +++ b/vendor/github.com/codahale/hdrhistogram/README.md @@ -0,0 +1,15 @@ +hdrhistogram +============ + +[![Build Status](https://travis-ci.org/codahale/hdrhistogram.png?branch=master)](https://travis-ci.org/codahale/hdrhistogram) + +A pure Go implementation of the [HDR Histogram](https://github.com/HdrHistogram/HdrHistogram). + +> A Histogram that supports recording and analyzing sampled data value counts +> across a configurable integer value range with configurable value precision +> within the range. Value precision is expressed as the number of significant +> digits in the value recording, and provides control over value quantization +> behavior across the value range and the subsequent value resolution at any +> given level. + +For documentation, check [godoc](http://godoc.org/github.com/codahale/hdrhistogram). diff --git a/vendor/github.com/codahale/hdrhistogram/hdr.go b/vendor/github.com/codahale/hdrhistogram/hdr.go new file mode 100644 index 0000000000..c97842926d --- /dev/null +++ b/vendor/github.com/codahale/hdrhistogram/hdr.go @@ -0,0 +1,564 @@ +// Package hdrhistogram provides an implementation of Gil Tene's HDR Histogram +// data structure. The HDR Histogram allows for fast and accurate analysis of +// the extreme ranges of data with non-normal distributions, like latency. +package hdrhistogram + +import ( + "fmt" + "math" +) + +// A Bracket is a part of a cumulative distribution. +type Bracket struct { + Quantile float64 + Count, ValueAt int64 +} + +// A Snapshot is an exported view of a Histogram, useful for serializing them. +// A Histogram can be constructed from it by passing it to Import. +type Snapshot struct { + LowestTrackableValue int64 + HighestTrackableValue int64 + SignificantFigures int64 + Counts []int64 +} + +// A Histogram is a lossy data structure used to record the distribution of +// non-normally distributed data (like latency) with a high degree of accuracy +// and a bounded degree of precision. +type Histogram struct { + lowestTrackableValue int64 + highestTrackableValue int64 + unitMagnitude int64 + significantFigures int64 + subBucketHalfCountMagnitude int32 + subBucketHalfCount int32 + subBucketMask int64 + subBucketCount int32 + bucketCount int32 + countsLen int32 + totalCount int64 + counts []int64 +} + +// New returns a new Histogram instance capable of tracking values in the given +// range and with the given amount of precision. +func New(minValue, maxValue int64, sigfigs int) *Histogram { + if sigfigs < 1 || 5 < sigfigs { + panic(fmt.Errorf("sigfigs must be [1,5] (was %d)", sigfigs)) + } + + largestValueWithSingleUnitResolution := 2 * math.Pow10(sigfigs) + subBucketCountMagnitude := int32(math.Ceil(math.Log2(float64(largestValueWithSingleUnitResolution)))) + + subBucketHalfCountMagnitude := subBucketCountMagnitude + if subBucketHalfCountMagnitude < 1 { + subBucketHalfCountMagnitude = 1 + } + subBucketHalfCountMagnitude-- + + unitMagnitude := int32(math.Floor(math.Log2(float64(minValue)))) + if unitMagnitude < 0 { + unitMagnitude = 0 + } + + subBucketCount := int32(math.Pow(2, float64(subBucketHalfCountMagnitude)+1)) + + subBucketHalfCount := subBucketCount / 2 + subBucketMask := int64(subBucketCount-1) << uint(unitMagnitude) + + // determine exponent range needed to support the trackable value with no + // overflow: + smallestUntrackableValue := int64(subBucketCount) << uint(unitMagnitude) + bucketsNeeded := int32(1) + for smallestUntrackableValue < maxValue { + smallestUntrackableValue <<= 1 + bucketsNeeded++ + } + + bucketCount := bucketsNeeded + countsLen := (bucketCount + 1) * (subBucketCount / 2) + + return &Histogram{ + lowestTrackableValue: minValue, + highestTrackableValue: maxValue, + unitMagnitude: int64(unitMagnitude), + significantFigures: int64(sigfigs), + subBucketHalfCountMagnitude: subBucketHalfCountMagnitude, + subBucketHalfCount: subBucketHalfCount, + subBucketMask: subBucketMask, + subBucketCount: subBucketCount, + bucketCount: bucketCount, + countsLen: countsLen, + totalCount: 0, + counts: make([]int64, countsLen), + } +} + +// ByteSize returns an estimate of the amount of memory allocated to the +// histogram in bytes. +// +// N.B.: This does not take into account the overhead for slices, which are +// small, constant, and specific to the compiler version. +func (h *Histogram) ByteSize() int { + return 6*8 + 5*4 + len(h.counts)*8 +} + +// Merge merges the data stored in the given histogram with the receiver, +// returning the number of recorded values which had to be dropped. +func (h *Histogram) Merge(from *Histogram) (dropped int64) { + i := from.rIterator() + for i.next() { + v := i.valueFromIdx + c := i.countAtIdx + + if h.RecordValues(v, c) != nil { + dropped += c + } + } + + return +} + +// TotalCount returns total number of values recorded. +func (h *Histogram) TotalCount() int64 { + return h.totalCount +} + +// Max returns the approximate maximum recorded value. +func (h *Histogram) Max() int64 { + var max int64 + i := h.iterator() + for i.next() { + if i.countAtIdx != 0 { + max = i.highestEquivalentValue + } + } + return h.highestEquivalentValue(max) +} + +// Min returns the approximate minimum recorded value. +func (h *Histogram) Min() int64 { + var min int64 + i := h.iterator() + for i.next() { + if i.countAtIdx != 0 && min == 0 { + min = i.highestEquivalentValue + break + } + } + return h.lowestEquivalentValue(min) +} + +// Mean returns the approximate arithmetic mean of the recorded values. +func (h *Histogram) Mean() float64 { + if h.totalCount == 0 { + return 0 + } + var total int64 + i := h.iterator() + for i.next() { + if i.countAtIdx != 0 { + total += i.countAtIdx * h.medianEquivalentValue(i.valueFromIdx) + } + } + return float64(total) / float64(h.totalCount) +} + +// StdDev returns the approximate standard deviation of the recorded values. +func (h *Histogram) StdDev() float64 { + if h.totalCount == 0 { + return 0 + } + + mean := h.Mean() + geometricDevTotal := 0.0 + + i := h.iterator() + for i.next() { + if i.countAtIdx != 0 { + dev := float64(h.medianEquivalentValue(i.valueFromIdx)) - mean + geometricDevTotal += (dev * dev) * float64(i.countAtIdx) + } + } + + return math.Sqrt(geometricDevTotal / float64(h.totalCount)) +} + +// Reset deletes all recorded values and restores the histogram to its original +// state. +func (h *Histogram) Reset() { + h.totalCount = 0 + for i := range h.counts { + h.counts[i] = 0 + } +} + +// RecordValue records the given value, returning an error if the value is out +// of range. +func (h *Histogram) RecordValue(v int64) error { + return h.RecordValues(v, 1) +} + +// RecordCorrectedValue records the given value, correcting for stalls in the +// recording process. This only works for processes which are recording values +// at an expected interval (e.g., doing jitter analysis). Processes which are +// recording ad-hoc values (e.g., latency for incoming requests) can't take +// advantage of this. +func (h *Histogram) RecordCorrectedValue(v, expectedInterval int64) error { + if err := h.RecordValue(v); err != nil { + return err + } + + if expectedInterval <= 0 || v <= expectedInterval { + return nil + } + + missingValue := v - expectedInterval + for missingValue >= expectedInterval { + if err := h.RecordValue(missingValue); err != nil { + return err + } + missingValue -= expectedInterval + } + + return nil +} + +// RecordValues records n occurrences of the given value, returning an error if +// the value is out of range. +func (h *Histogram) RecordValues(v, n int64) error { + idx := h.countsIndexFor(v) + if idx < 0 || int(h.countsLen) <= idx { + return fmt.Errorf("value %d is too large to be recorded", v) + } + h.counts[idx] += n + h.totalCount += n + + return nil +} + +// ValueAtQuantile returns the recorded value at the given quantile (0..100). +func (h *Histogram) ValueAtQuantile(q float64) int64 { + if q > 100 { + q = 100 + } + + total := int64(0) + countAtPercentile := int64(((q / 100) * float64(h.totalCount)) + 0.5) + + i := h.iterator() + for i.next() { + total += i.countAtIdx + if total >= countAtPercentile { + return h.highestEquivalentValue(i.valueFromIdx) + } + } + + return 0 +} + +// CumulativeDistribution returns an ordered list of brackets of the +// distribution of recorded values. +func (h *Histogram) CumulativeDistribution() []Bracket { + var result []Bracket + + i := h.pIterator(1) + for i.next() { + result = append(result, Bracket{ + Quantile: i.percentile, + Count: i.countToIdx, + ValueAt: i.highestEquivalentValue, + }) + } + + return result +} + +// SignificantFigures returns the significant figures used to create the +// histogram +func (h *Histogram) SignificantFigures() int64 { + return h.significantFigures +} + +// LowestTrackableValue returns the lower bound on values that will be added +// to the histogram +func (h *Histogram) LowestTrackableValue() int64 { + return h.lowestTrackableValue +} + +// HighestTrackableValue returns the upper bound on values that will be added +// to the histogram +func (h *Histogram) HighestTrackableValue() int64 { + return h.highestTrackableValue +} + +// Histogram bar for plotting +type Bar struct { + From, To, Count int64 +} + +// Pretty print as csv for easy plotting +func (b Bar) String() string { + return fmt.Sprintf("%v, %v, %v\n", b.From, b.To, b.Count) +} + +// Distribution returns an ordered list of bars of the +// distribution of recorded values, counts can be normalized to a probability +func (h *Histogram) Distribution() (result []Bar) { + i := h.iterator() + for i.next() { + result = append(result, Bar{ + Count: i.countAtIdx, + From: h.lowestEquivalentValue(i.valueFromIdx), + To: i.highestEquivalentValue, + }) + } + + return result +} + +// Equals returns true if the two Histograms are equivalent, false if not. +func (h *Histogram) Equals(other *Histogram) bool { + switch { + case + h.lowestTrackableValue != other.lowestTrackableValue, + h.highestTrackableValue != other.highestTrackableValue, + h.unitMagnitude != other.unitMagnitude, + h.significantFigures != other.significantFigures, + h.subBucketHalfCountMagnitude != other.subBucketHalfCountMagnitude, + h.subBucketHalfCount != other.subBucketHalfCount, + h.subBucketMask != other.subBucketMask, + h.subBucketCount != other.subBucketCount, + h.bucketCount != other.bucketCount, + h.countsLen != other.countsLen, + h.totalCount != other.totalCount: + return false + default: + for i, c := range h.counts { + if c != other.counts[i] { + return false + } + } + } + return true +} + +// Export returns a snapshot view of the Histogram. This can be later passed to +// Import to construct a new Histogram with the same state. +func (h *Histogram) Export() *Snapshot { + return &Snapshot{ + LowestTrackableValue: h.lowestTrackableValue, + HighestTrackableValue: h.highestTrackableValue, + SignificantFigures: h.significantFigures, + Counts: append([]int64(nil), h.counts...), // copy + } +} + +// Import returns a new Histogram populated from the Snapshot data (which the +// caller must stop accessing). +func Import(s *Snapshot) *Histogram { + h := New(s.LowestTrackableValue, s.HighestTrackableValue, int(s.SignificantFigures)) + h.counts = s.Counts + totalCount := int64(0) + for i := int32(0); i < h.countsLen; i++ { + countAtIndex := h.counts[i] + if countAtIndex > 0 { + totalCount += countAtIndex + } + } + h.totalCount = totalCount + return h +} + +func (h *Histogram) iterator() *iterator { + return &iterator{ + h: h, + subBucketIdx: -1, + } +} + +func (h *Histogram) rIterator() *rIterator { + return &rIterator{ + iterator: iterator{ + h: h, + subBucketIdx: -1, + }, + } +} + +func (h *Histogram) pIterator(ticksPerHalfDistance int32) *pIterator { + return &pIterator{ + iterator: iterator{ + h: h, + subBucketIdx: -1, + }, + ticksPerHalfDistance: ticksPerHalfDistance, + } +} + +func (h *Histogram) sizeOfEquivalentValueRange(v int64) int64 { + bucketIdx := h.getBucketIndex(v) + subBucketIdx := h.getSubBucketIdx(v, bucketIdx) + adjustedBucket := bucketIdx + if subBucketIdx >= h.subBucketCount { + adjustedBucket++ + } + return int64(1) << uint(h.unitMagnitude+int64(adjustedBucket)) +} + +func (h *Histogram) valueFromIndex(bucketIdx, subBucketIdx int32) int64 { + return int64(subBucketIdx) << uint(int64(bucketIdx)+h.unitMagnitude) +} + +func (h *Histogram) lowestEquivalentValue(v int64) int64 { + bucketIdx := h.getBucketIndex(v) + subBucketIdx := h.getSubBucketIdx(v, bucketIdx) + return h.valueFromIndex(bucketIdx, subBucketIdx) +} + +func (h *Histogram) nextNonEquivalentValue(v int64) int64 { + return h.lowestEquivalentValue(v) + h.sizeOfEquivalentValueRange(v) +} + +func (h *Histogram) highestEquivalentValue(v int64) int64 { + return h.nextNonEquivalentValue(v) - 1 +} + +func (h *Histogram) medianEquivalentValue(v int64) int64 { + return h.lowestEquivalentValue(v) + (h.sizeOfEquivalentValueRange(v) >> 1) +} + +func (h *Histogram) getCountAtIndex(bucketIdx, subBucketIdx int32) int64 { + return h.counts[h.countsIndex(bucketIdx, subBucketIdx)] +} + +func (h *Histogram) countsIndex(bucketIdx, subBucketIdx int32) int32 { + bucketBaseIdx := (bucketIdx + 1) << uint(h.subBucketHalfCountMagnitude) + offsetInBucket := subBucketIdx - h.subBucketHalfCount + return bucketBaseIdx + offsetInBucket +} + +func (h *Histogram) getBucketIndex(v int64) int32 { + pow2Ceiling := bitLen(v | h.subBucketMask) + return int32(pow2Ceiling - int64(h.unitMagnitude) - + int64(h.subBucketHalfCountMagnitude+1)) +} + +func (h *Histogram) getSubBucketIdx(v int64, idx int32) int32 { + return int32(v >> uint(int64(idx)+int64(h.unitMagnitude))) +} + +func (h *Histogram) countsIndexFor(v int64) int { + bucketIdx := h.getBucketIndex(v) + subBucketIdx := h.getSubBucketIdx(v, bucketIdx) + return int(h.countsIndex(bucketIdx, subBucketIdx)) +} + +type iterator struct { + h *Histogram + bucketIdx, subBucketIdx int32 + countAtIdx, countToIdx, valueFromIdx int64 + highestEquivalentValue int64 +} + +func (i *iterator) next() bool { + if i.countToIdx >= i.h.totalCount { + return false + } + + // increment bucket + i.subBucketIdx++ + if i.subBucketIdx >= i.h.subBucketCount { + i.subBucketIdx = i.h.subBucketHalfCount + i.bucketIdx++ + } + + if i.bucketIdx >= i.h.bucketCount { + return false + } + + i.countAtIdx = i.h.getCountAtIndex(i.bucketIdx, i.subBucketIdx) + i.countToIdx += i.countAtIdx + i.valueFromIdx = i.h.valueFromIndex(i.bucketIdx, i.subBucketIdx) + i.highestEquivalentValue = i.h.highestEquivalentValue(i.valueFromIdx) + + return true +} + +type rIterator struct { + iterator + countAddedThisStep int64 +} + +func (r *rIterator) next() bool { + for r.iterator.next() { + if r.countAtIdx != 0 { + r.countAddedThisStep = r.countAtIdx + return true + } + } + return false +} + +type pIterator struct { + iterator + seenLastValue bool + ticksPerHalfDistance int32 + percentileToIteratorTo float64 + percentile float64 +} + +func (p *pIterator) next() bool { + if !(p.countToIdx < p.h.totalCount) { + if p.seenLastValue { + return false + } + + p.seenLastValue = true + p.percentile = 100 + + return true + } + + if p.subBucketIdx == -1 && !p.iterator.next() { + return false + } + + var done = false + for !done { + currentPercentile := (100.0 * float64(p.countToIdx)) / float64(p.h.totalCount) + if p.countAtIdx != 0 && p.percentileToIteratorTo <= currentPercentile { + p.percentile = p.percentileToIteratorTo + halfDistance := math.Trunc(math.Pow(2, math.Trunc(math.Log2(100.0/(100.0-p.percentileToIteratorTo)))+1)) + percentileReportingTicks := float64(p.ticksPerHalfDistance) * halfDistance + p.percentileToIteratorTo += 100.0 / percentileReportingTicks + return true + } + done = !p.iterator.next() + } + + return true +} + +func bitLen(x int64) (n int64) { + for ; x >= 0x8000; x >>= 16 { + n += 16 + } + if x >= 0x80 { + x >>= 8 + n += 8 + } + if x >= 0x8 { + x >>= 4 + n += 4 + } + if x >= 0x2 { + x >>= 2 + n += 2 + } + if x >= 0x1 { + n++ + } + return +} diff --git a/vendor/github.com/codahale/hdrhistogram/window.go b/vendor/github.com/codahale/hdrhistogram/window.go new file mode 100644 index 0000000000..dc43612a4b --- /dev/null +++ b/vendor/github.com/codahale/hdrhistogram/window.go @@ -0,0 +1,45 @@ +package hdrhistogram + +// A WindowedHistogram combines histograms to provide windowed statistics. +type WindowedHistogram struct { + idx int + h []Histogram + m *Histogram + + Current *Histogram +} + +// NewWindowed creates a new WindowedHistogram with N underlying histograms with +// the given parameters. +func NewWindowed(n int, minValue, maxValue int64, sigfigs int) *WindowedHistogram { + w := WindowedHistogram{ + idx: -1, + h: make([]Histogram, n), + m: New(minValue, maxValue, sigfigs), + } + + for i := range w.h { + w.h[i] = *New(minValue, maxValue, sigfigs) + } + w.Rotate() + + return &w +} + +// Merge returns a histogram which includes the recorded values from all the +// sections of the window. +func (w *WindowedHistogram) Merge() *Histogram { + w.m.Reset() + for _, h := range w.h { + w.m.Merge(&h) + } + return w.m +} + +// Rotate resets the oldest histogram and rotates it to be used as the current +// histogram. +func (w *WindowedHistogram) Rotate() { + w.idx++ + w.Current = &w.h[w.idx%len(w.h)] + w.Current.Reset() +} diff --git a/vendor/gopkg.in/fatih/set.v0/LICENSE.md b/vendor/github.com/deckarep/golang-set/LICENSE similarity index 50% rename from vendor/gopkg.in/fatih/set.v0/LICENSE.md rename to vendor/github.com/deckarep/golang-set/LICENSE index 25fdaf639d..b5768f89cf 100644 --- a/vendor/gopkg.in/fatih/set.v0/LICENSE.md +++ b/vendor/github.com/deckarep/golang-set/LICENSE @@ -1,20 +1,22 @@ -The MIT License (MIT) +Open Source Initiative OSI - The MIT License (MIT):Licensing -Copyright (c) 2013 Fatih Arslan +The MIT License (MIT) +Copyright (c) 2013 Ralph Caraveo (deckarep@gmail.com) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/vendor/github.com/deckarep/golang-set/README.md b/vendor/github.com/deckarep/golang-set/README.md new file mode 100644 index 0000000000..c3b50b2c5c --- /dev/null +++ b/vendor/github.com/deckarep/golang-set/README.md @@ -0,0 +1,95 @@ +[![Build Status](https://travis-ci.org/deckarep/golang-set.svg?branch=master)](https://travis-ci.org/deckarep/golang-set) +[![Go Report Card](https://goreportcard.com/badge/github.com/deckarep/golang-set)](https://goreportcard.com/report/github.com/deckarep/golang-set) +[![GoDoc](https://godoc.org/github.com/deckarep/golang-set?status.svg)](http://godoc.org/github.com/deckarep/golang-set) + +## golang-set + + +The missing set collection for the Go language. Until Go has sets built-in...use this. + +Coming from Python one of the things I miss is the superbly wonderful set collection. This is my attempt to mimic the primary features of the set from Python. +You can of course argue that there is no need for a set in Go, otherwise the creators would have added one to the standard library. To those I say simply ignore this repository +and carry-on and to the rest that find this useful please contribute in helping me make it better by: + +* Helping to make more idiomatic improvements to the code. +* Helping to increase the performance of it. ~~(So far, no attempt has been made, but since it uses a map internally, I expect it to be mostly performant.)~~ +* Helping to make the unit-tests more robust and kick-ass. +* Helping to fill in the [documentation.](http://godoc.org/github.com/deckarep/golang-set) +* Simply offering feedback and suggestions. (Positive, constructive feedback is appreciated.) + +I have to give some credit for helping seed the idea with this post on [stackoverflow.](http://programmers.stackexchange.com/questions/177428/sets-data-structure-in-golang) + +*Update* - as of 3/9/2014, you can use a compile-time generic version of this package in the [gen](http://clipperhouse.github.io/gen/) framework. This framework allows you to use the golang-set in a completely generic and type-safe way by allowing you to generate a supporting .go file based on your custom types. + +## Features (as of 9/22/2014) + +* a CartesianProduct() method has been added with unit-tests: [Read more about the cartesian product](http://en.wikipedia.org/wiki/Cartesian_product) + +## Features (as of 9/15/2014) + +* a PowerSet() method has been added with unit-tests: [Read more about the Power set](http://en.wikipedia.org/wiki/Power_set) + +## Features (as of 4/22/2014) + +* One common interface to both implementations +* Two set implementations to choose from + * a thread-safe implementation designed for concurrent use + * a non-thread-safe implementation designed for performance +* 75 benchmarks for both implementations +* 35 unit tests for both implementations +* 14 concurrent tests for the thread-safe implementation + + + +Please see the unit test file for additional usage examples. The Python set documentation will also do a better job than I can of explaining how a set typically [works.](http://docs.python.org/2/library/sets.html) Please keep in mind +however that the Python set is a built-in type and supports additional features and syntax that make it awesome. + +## Examples but not exhaustive: + +```go +requiredClasses := mapset.NewSet() +requiredClasses.Add("Cooking") +requiredClasses.Add("English") +requiredClasses.Add("Math") +requiredClasses.Add("Biology") + +scienceSlice := []interface{}{"Biology", "Chemistry"} +scienceClasses := mapset.NewSetFromSlice(scienceSlice) + +electiveClasses := mapset.NewSet() +electiveClasses.Add("Welding") +electiveClasses.Add("Music") +electiveClasses.Add("Automotive") + +bonusClasses := mapset.NewSet() +bonusClasses.Add("Go Programming") +bonusClasses.Add("Python Programming") + +//Show me all the available classes I can take +allClasses := requiredClasses.Union(scienceClasses).Union(electiveClasses).Union(bonusClasses) +fmt.Println(allClasses) //Set{Cooking, English, Math, Chemistry, Welding, Biology, Music, Automotive, Go Programming, Python Programming} + + +//Is cooking considered a science class? +fmt.Println(scienceClasses.Contains("Cooking")) //false + +//Show me all classes that are not science classes, since I hate science. +fmt.Println(allClasses.Difference(scienceClasses)) //Set{Music, Automotive, Go Programming, Python Programming, Cooking, English, Math, Welding} + +//Which science classes are also required classes? +fmt.Println(scienceClasses.Intersect(requiredClasses)) //Set{Biology} + +//How many bonus classes do you offer? +fmt.Println(bonusClasses.Cardinality()) //2 + +//Do you have the following classes? Welding, Automotive and English? +fmt.Println(allClasses.IsSuperset(mapset.NewSetFromSlice([]interface{}{"Welding", "Automotive", "English"}))) //true +``` + +Thanks! + +-Ralph + +[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/deckarep/golang-set/trend.png)](https://bitdeli.com/free "Bitdeli Badge") + +[![Analytics](https://ga-beacon.appspot.com/UA-42584447-2/deckarep/golang-set)](https://github.com/igrigorik/ga-beacon) diff --git a/vendor/github.com/deckarep/golang-set/iterator.go b/vendor/github.com/deckarep/golang-set/iterator.go new file mode 100644 index 0000000000..9dfecade42 --- /dev/null +++ b/vendor/github.com/deckarep/golang-set/iterator.go @@ -0,0 +1,58 @@ +/* +Open Source Initiative OSI - The MIT License (MIT):Licensing + +The MIT License (MIT) +Copyright (c) 2013 Ralph Caraveo (deckarep@gmail.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +package mapset + +// Iterator defines an iterator over a Set, its C channel can be used to range over the Set's +// elements. +type Iterator struct { + C <-chan interface{} + stop chan struct{} +} + +// Stop stops the Iterator, no further elements will be received on C, C will be closed. +func (i *Iterator) Stop() { + // Allows for Stop() to be called multiple times + // (close() panics when called on already closed channel) + defer func() { + recover() + }() + + close(i.stop) + + // Exhaust any remaining elements. + for range i.C { + } +} + +// newIterator returns a new Iterator instance together with its item and stop channels. +func newIterator() (*Iterator, chan<- interface{}, <-chan struct{}) { + itemChan := make(chan interface{}) + stopChan := make(chan struct{}) + return &Iterator{ + C: itemChan, + stop: stopChan, + }, itemChan, stopChan +} diff --git a/vendor/github.com/deckarep/golang-set/set.go b/vendor/github.com/deckarep/golang-set/set.go new file mode 100644 index 0000000000..29eb2e5a22 --- /dev/null +++ b/vendor/github.com/deckarep/golang-set/set.go @@ -0,0 +1,217 @@ +/* +Open Source Initiative OSI - The MIT License (MIT):Licensing + +The MIT License (MIT) +Copyright (c) 2013 Ralph Caraveo (deckarep@gmail.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +// Package mapset implements a simple and generic set collection. +// Items stored within it are unordered and unique. It supports +// typical set operations: membership testing, intersection, union, +// difference, symmetric difference and cloning. +// +// Package mapset provides two implementations of the Set +// interface. The default implementation is safe for concurrent +// access, but a non-thread-safe implementation is also provided for +// programs that can benefit from the slight speed improvement and +// that can enforce mutual exclusion through other means. +package mapset + +// Set is the primary interface provided by the mapset package. It +// represents an unordered set of data and a large number of +// operations that can be applied to that set. +type Set interface { + // Adds an element to the set. Returns whether + // the item was added. + Add(i interface{}) bool + + // Returns the number of elements in the set. + Cardinality() int + + // Removes all elements from the set, leaving + // the empty set. + Clear() + + // Returns a clone of the set using the same + // implementation, duplicating all keys. + Clone() Set + + // Returns whether the given items + // are all in the set. + Contains(i ...interface{}) bool + + // Returns the difference between this set + // and other. The returned set will contain + // all elements of this set that are not also + // elements of other. + // + // Note that the argument to Difference + // must be of the same type as the receiver + // of the method. Otherwise, Difference will + // panic. + Difference(other Set) Set + + // Determines if two sets are equal to each + // other. If they have the same cardinality + // and contain the same elements, they are + // considered equal. The order in which + // the elements were added is irrelevant. + // + // Note that the argument to Equal must be + // of the same type as the receiver of the + // method. Otherwise, Equal will panic. + Equal(other Set) bool + + // Returns a new set containing only the elements + // that exist only in both sets. + // + // Note that the argument to Intersect + // must be of the same type as the receiver + // of the method. Otherwise, Intersect will + // panic. + Intersect(other Set) Set + + // Determines if every element in this set is in + // the other set but the two sets are not equal. + // + // Note that the argument to IsProperSubset + // must be of the same type as the receiver + // of the method. Otherwise, IsProperSubset + // will panic. + IsProperSubset(other Set) bool + + // Determines if every element in the other set + // is in this set but the two sets are not + // equal. + // + // Note that the argument to IsSuperset + // must be of the same type as the receiver + // of the method. Otherwise, IsSuperset will + // panic. + IsProperSuperset(other Set) bool + + // Determines if every element in this set is in + // the other set. + // + // Note that the argument to IsSubset + // must be of the same type as the receiver + // of the method. Otherwise, IsSubset will + // panic. + IsSubset(other Set) bool + + // Determines if every element in the other set + // is in this set. + // + // Note that the argument to IsSuperset + // must be of the same type as the receiver + // of the method. Otherwise, IsSuperset will + // panic. + IsSuperset(other Set) bool + + // Iterates over elements and executes the passed func against each element. + // If passed func returns true, stop iteration at the time. + Each(func(interface{}) bool) + + // Returns a channel of elements that you can + // range over. + Iter() <-chan interface{} + + // Returns an Iterator object that you can + // use to range over the set. + Iterator() *Iterator + + // Remove a single element from the set. + Remove(i interface{}) + + // Provides a convenient string representation + // of the current state of the set. + String() string + + // Returns a new set with all elements which are + // in either this set or the other set but not in both. + // + // Note that the argument to SymmetricDifference + // must be of the same type as the receiver + // of the method. Otherwise, SymmetricDifference + // will panic. + SymmetricDifference(other Set) Set + + // Returns a new set with all elements in both sets. + // + // Note that the argument to Union must be of the + + // same type as the receiver of the method. + // Otherwise, IsSuperset will panic. + Union(other Set) Set + + // Pop removes and returns an arbitrary item from the set. + Pop() interface{} + + // Returns all subsets of a given set (Power Set). + PowerSet() Set + + // Returns the Cartesian Product of two sets. + CartesianProduct(other Set) Set + + // Returns the members of the set as a slice. + ToSlice() []interface{} +} + +// NewSet creates and returns a reference to an empty set. Operations +// on the resulting set are thread-safe. +func NewSet(s ...interface{}) Set { + set := newThreadSafeSet() + for _, item := range s { + set.Add(item) + } + return &set +} + +// NewSetWith creates and returns a new set with the given elements. +// Operations on the resulting set are thread-safe. +func NewSetWith(elts ...interface{}) Set { + return NewSetFromSlice(elts) +} + +// NewSetFromSlice creates and returns a reference to a set from an +// existing slice. Operations on the resulting set are thread-safe. +func NewSetFromSlice(s []interface{}) Set { + a := NewSet(s...) + return a +} + +// NewThreadUnsafeSet creates and returns a reference to an empty set. +// Operations on the resulting set are not thread-safe. +func NewThreadUnsafeSet() Set { + set := newThreadUnsafeSet() + return &set +} + +// NewThreadUnsafeSetFromSlice creates and returns a reference to a +// set from an existing slice. Operations on the resulting set are +// not thread-safe. +func NewThreadUnsafeSetFromSlice(s []interface{}) Set { + a := NewThreadUnsafeSet() + for _, item := range s { + a.Add(item) + } + return a +} diff --git a/vendor/github.com/deckarep/golang-set/threadsafe.go b/vendor/github.com/deckarep/golang-set/threadsafe.go new file mode 100644 index 0000000000..002e06af1f --- /dev/null +++ b/vendor/github.com/deckarep/golang-set/threadsafe.go @@ -0,0 +1,277 @@ +/* +Open Source Initiative OSI - The MIT License (MIT):Licensing + +The MIT License (MIT) +Copyright (c) 2013 Ralph Caraveo (deckarep@gmail.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +package mapset + +import "sync" + +type threadSafeSet struct { + s threadUnsafeSet + sync.RWMutex +} + +func newThreadSafeSet() threadSafeSet { + return threadSafeSet{s: newThreadUnsafeSet()} +} + +func (set *threadSafeSet) Add(i interface{}) bool { + set.Lock() + ret := set.s.Add(i) + set.Unlock() + return ret +} + +func (set *threadSafeSet) Contains(i ...interface{}) bool { + set.RLock() + ret := set.s.Contains(i...) + set.RUnlock() + return ret +} + +func (set *threadSafeSet) IsSubset(other Set) bool { + o := other.(*threadSafeSet) + + set.RLock() + o.RLock() + + ret := set.s.IsSubset(&o.s) + set.RUnlock() + o.RUnlock() + return ret +} + +func (set *threadSafeSet) IsProperSubset(other Set) bool { + o := other.(*threadSafeSet) + + set.RLock() + defer set.RUnlock() + o.RLock() + defer o.RUnlock() + + return set.s.IsProperSubset(&o.s) +} + +func (set *threadSafeSet) IsSuperset(other Set) bool { + return other.IsSubset(set) +} + +func (set *threadSafeSet) IsProperSuperset(other Set) bool { + return other.IsProperSubset(set) +} + +func (set *threadSafeSet) Union(other Set) Set { + o := other.(*threadSafeSet) + + set.RLock() + o.RLock() + + unsafeUnion := set.s.Union(&o.s).(*threadUnsafeSet) + ret := &threadSafeSet{s: *unsafeUnion} + set.RUnlock() + o.RUnlock() + return ret +} + +func (set *threadSafeSet) Intersect(other Set) Set { + o := other.(*threadSafeSet) + + set.RLock() + o.RLock() + + unsafeIntersection := set.s.Intersect(&o.s).(*threadUnsafeSet) + ret := &threadSafeSet{s: *unsafeIntersection} + set.RUnlock() + o.RUnlock() + return ret +} + +func (set *threadSafeSet) Difference(other Set) Set { + o := other.(*threadSafeSet) + + set.RLock() + o.RLock() + + unsafeDifference := set.s.Difference(&o.s).(*threadUnsafeSet) + ret := &threadSafeSet{s: *unsafeDifference} + set.RUnlock() + o.RUnlock() + return ret +} + +func (set *threadSafeSet) SymmetricDifference(other Set) Set { + o := other.(*threadSafeSet) + + set.RLock() + o.RLock() + + unsafeDifference := set.s.SymmetricDifference(&o.s).(*threadUnsafeSet) + ret := &threadSafeSet{s: *unsafeDifference} + set.RUnlock() + o.RUnlock() + return ret +} + +func (set *threadSafeSet) Clear() { + set.Lock() + set.s = newThreadUnsafeSet() + set.Unlock() +} + +func (set *threadSafeSet) Remove(i interface{}) { + set.Lock() + delete(set.s, i) + set.Unlock() +} + +func (set *threadSafeSet) Cardinality() int { + set.RLock() + defer set.RUnlock() + return len(set.s) +} + +func (set *threadSafeSet) Each(cb func(interface{}) bool) { + set.RLock() + for elem := range set.s { + if cb(elem) { + break + } + } + set.RUnlock() +} + +func (set *threadSafeSet) Iter() <-chan interface{} { + ch := make(chan interface{}) + go func() { + set.RLock() + + for elem := range set.s { + ch <- elem + } + close(ch) + set.RUnlock() + }() + + return ch +} + +func (set *threadSafeSet) Iterator() *Iterator { + iterator, ch, stopCh := newIterator() + + go func() { + set.RLock() + L: + for elem := range set.s { + select { + case <-stopCh: + break L + case ch <- elem: + } + } + close(ch) + set.RUnlock() + }() + + return iterator +} + +func (set *threadSafeSet) Equal(other Set) bool { + o := other.(*threadSafeSet) + + set.RLock() + o.RLock() + + ret := set.s.Equal(&o.s) + set.RUnlock() + o.RUnlock() + return ret +} + +func (set *threadSafeSet) Clone() Set { + set.RLock() + + unsafeClone := set.s.Clone().(*threadUnsafeSet) + ret := &threadSafeSet{s: *unsafeClone} + set.RUnlock() + return ret +} + +func (set *threadSafeSet) String() string { + set.RLock() + ret := set.s.String() + set.RUnlock() + return ret +} + +func (set *threadSafeSet) PowerSet() Set { + set.RLock() + ret := set.s.PowerSet() + set.RUnlock() + return ret +} + +func (set *threadSafeSet) Pop() interface{} { + set.Lock() + defer set.Unlock() + return set.s.Pop() +} + +func (set *threadSafeSet) CartesianProduct(other Set) Set { + o := other.(*threadSafeSet) + + set.RLock() + o.RLock() + + unsafeCartProduct := set.s.CartesianProduct(&o.s).(*threadUnsafeSet) + ret := &threadSafeSet{s: *unsafeCartProduct} + set.RUnlock() + o.RUnlock() + return ret +} + +func (set *threadSafeSet) ToSlice() []interface{} { + keys := make([]interface{}, 0, set.Cardinality()) + set.RLock() + for elem := range set.s { + keys = append(keys, elem) + } + set.RUnlock() + return keys +} + +func (set *threadSafeSet) MarshalJSON() ([]byte, error) { + set.RLock() + b, err := set.s.MarshalJSON() + set.RUnlock() + + return b, err +} + +func (set *threadSafeSet) UnmarshalJSON(p []byte) error { + set.RLock() + err := set.s.UnmarshalJSON(p) + set.RUnlock() + + return err +} diff --git a/vendor/github.com/deckarep/golang-set/threadunsafe.go b/vendor/github.com/deckarep/golang-set/threadunsafe.go new file mode 100644 index 0000000000..10bdd46f15 --- /dev/null +++ b/vendor/github.com/deckarep/golang-set/threadunsafe.go @@ -0,0 +1,337 @@ +/* +Open Source Initiative OSI - The MIT License (MIT):Licensing + +The MIT License (MIT) +Copyright (c) 2013 Ralph Caraveo (deckarep@gmail.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +package mapset + +import ( + "bytes" + "encoding/json" + "fmt" + "reflect" + "strings" +) + +type threadUnsafeSet map[interface{}]struct{} + +// An OrderedPair represents a 2-tuple of values. +type OrderedPair struct { + First interface{} + Second interface{} +} + +func newThreadUnsafeSet() threadUnsafeSet { + return make(threadUnsafeSet) +} + +// Equal says whether two 2-tuples contain the same values in the same order. +func (pair *OrderedPair) Equal(other OrderedPair) bool { + if pair.First == other.First && + pair.Second == other.Second { + return true + } + + return false +} + +func (set *threadUnsafeSet) Add(i interface{}) bool { + _, found := (*set)[i] + if found { + return false //False if it existed already + } + + (*set)[i] = struct{}{} + return true +} + +func (set *threadUnsafeSet) Contains(i ...interface{}) bool { + for _, val := range i { + if _, ok := (*set)[val]; !ok { + return false + } + } + return true +} + +func (set *threadUnsafeSet) IsSubset(other Set) bool { + _ = other.(*threadUnsafeSet) + for elem := range *set { + if !other.Contains(elem) { + return false + } + } + return true +} + +func (set *threadUnsafeSet) IsProperSubset(other Set) bool { + return set.IsSubset(other) && !set.Equal(other) +} + +func (set *threadUnsafeSet) IsSuperset(other Set) bool { + return other.IsSubset(set) +} + +func (set *threadUnsafeSet) IsProperSuperset(other Set) bool { + return set.IsSuperset(other) && !set.Equal(other) +} + +func (set *threadUnsafeSet) Union(other Set) Set { + o := other.(*threadUnsafeSet) + + unionedSet := newThreadUnsafeSet() + + for elem := range *set { + unionedSet.Add(elem) + } + for elem := range *o { + unionedSet.Add(elem) + } + return &unionedSet +} + +func (set *threadUnsafeSet) Intersect(other Set) Set { + o := other.(*threadUnsafeSet) + + intersection := newThreadUnsafeSet() + // loop over smaller set + if set.Cardinality() < other.Cardinality() { + for elem := range *set { + if other.Contains(elem) { + intersection.Add(elem) + } + } + } else { + for elem := range *o { + if set.Contains(elem) { + intersection.Add(elem) + } + } + } + return &intersection +} + +func (set *threadUnsafeSet) Difference(other Set) Set { + _ = other.(*threadUnsafeSet) + + difference := newThreadUnsafeSet() + for elem := range *set { + if !other.Contains(elem) { + difference.Add(elem) + } + } + return &difference +} + +func (set *threadUnsafeSet) SymmetricDifference(other Set) Set { + _ = other.(*threadUnsafeSet) + + aDiff := set.Difference(other) + bDiff := other.Difference(set) + return aDiff.Union(bDiff) +} + +func (set *threadUnsafeSet) Clear() { + *set = newThreadUnsafeSet() +} + +func (set *threadUnsafeSet) Remove(i interface{}) { + delete(*set, i) +} + +func (set *threadUnsafeSet) Cardinality() int { + return len(*set) +} + +func (set *threadUnsafeSet) Each(cb func(interface{}) bool) { + for elem := range *set { + if cb(elem) { + break + } + } +} + +func (set *threadUnsafeSet) Iter() <-chan interface{} { + ch := make(chan interface{}) + go func() { + for elem := range *set { + ch <- elem + } + close(ch) + }() + + return ch +} + +func (set *threadUnsafeSet) Iterator() *Iterator { + iterator, ch, stopCh := newIterator() + + go func() { + L: + for elem := range *set { + select { + case <-stopCh: + break L + case ch <- elem: + } + } + close(ch) + }() + + return iterator +} + +func (set *threadUnsafeSet) Equal(other Set) bool { + _ = other.(*threadUnsafeSet) + + if set.Cardinality() != other.Cardinality() { + return false + } + for elem := range *set { + if !other.Contains(elem) { + return false + } + } + return true +} + +func (set *threadUnsafeSet) Clone() Set { + clonedSet := newThreadUnsafeSet() + for elem := range *set { + clonedSet.Add(elem) + } + return &clonedSet +} + +func (set *threadUnsafeSet) String() string { + items := make([]string, 0, len(*set)) + + for elem := range *set { + items = append(items, fmt.Sprintf("%v", elem)) + } + return fmt.Sprintf("Set{%s}", strings.Join(items, ", ")) +} + +// String outputs a 2-tuple in the form "(A, B)". +func (pair OrderedPair) String() string { + return fmt.Sprintf("(%v, %v)", pair.First, pair.Second) +} + +func (set *threadUnsafeSet) Pop() interface{} { + for item := range *set { + delete(*set, item) + return item + } + return nil +} + +func (set *threadUnsafeSet) PowerSet() Set { + powSet := NewThreadUnsafeSet() + nullset := newThreadUnsafeSet() + powSet.Add(&nullset) + + for es := range *set { + u := newThreadUnsafeSet() + j := powSet.Iter() + for er := range j { + p := newThreadUnsafeSet() + if reflect.TypeOf(er).Name() == "" { + k := er.(*threadUnsafeSet) + for ek := range *(k) { + p.Add(ek) + } + } else { + p.Add(er) + } + p.Add(es) + u.Add(&p) + } + + powSet = powSet.Union(&u) + } + + return powSet +} + +func (set *threadUnsafeSet) CartesianProduct(other Set) Set { + o := other.(*threadUnsafeSet) + cartProduct := NewThreadUnsafeSet() + + for i := range *set { + for j := range *o { + elem := OrderedPair{First: i, Second: j} + cartProduct.Add(elem) + } + } + + return cartProduct +} + +func (set *threadUnsafeSet) ToSlice() []interface{} { + keys := make([]interface{}, 0, set.Cardinality()) + for elem := range *set { + keys = append(keys, elem) + } + + return keys +} + +// MarshalJSON creates a JSON array from the set, it marshals all elements +func (set *threadUnsafeSet) MarshalJSON() ([]byte, error) { + items := make([]string, 0, set.Cardinality()) + + for elem := range *set { + b, err := json.Marshal(elem) + if err != nil { + return nil, err + } + + items = append(items, string(b)) + } + + return []byte(fmt.Sprintf("[%s]", strings.Join(items, ","))), nil +} + +// UnmarshalJSON recreates a set from a JSON array, it only decodes +// primitive types. Numbers are decoded as json.Number. +func (set *threadUnsafeSet) UnmarshalJSON(b []byte) error { + var i []interface{} + + d := json.NewDecoder(bytes.NewReader(b)) + d.UseNumber() + err := d.Decode(&i) + if err != nil { + return err + } + + for _, v := range i { + switch t := v.(type) { + case []interface{}, map[string]interface{}: + continue + default: + set.Add(t) + } + } + + return nil +} diff --git a/vendor/github.com/docker/docker/pkg/reexec/command_linux.go b/vendor/github.com/docker/docker/pkg/reexec/command_linux.go index 34ae2a9dcd..efea71794f 100644 --- a/vendor/github.com/docker/docker/pkg/reexec/command_linux.go +++ b/vendor/github.com/docker/docker/pkg/reexec/command_linux.go @@ -1,10 +1,10 @@ -// +build linux - -package reexec +package reexec // import "github.com/docker/docker/pkg/reexec" import ( "os/exec" "syscall" + + "golang.org/x/sys/unix" ) // Self returns the path to the current process's binary. @@ -22,7 +22,7 @@ func Command(args ...string) *exec.Cmd { Path: Self(), Args: args, SysProcAttr: &syscall.SysProcAttr{ - Pdeathsig: syscall.SIGTERM, + Pdeathsig: unix.SIGTERM, }, } } diff --git a/vendor/github.com/docker/docker/pkg/reexec/command_unix.go b/vendor/github.com/docker/docker/pkg/reexec/command_unix.go index 778a720e3b..ceaabbdeee 100644 --- a/vendor/github.com/docker/docker/pkg/reexec/command_unix.go +++ b/vendor/github.com/docker/docker/pkg/reexec/command_unix.go @@ -1,6 +1,6 @@ -// +build freebsd solaris darwin +// +build freebsd darwin -package reexec +package reexec // import "github.com/docker/docker/pkg/reexec" import ( "os/exec" diff --git a/vendor/github.com/docker/docker/pkg/reexec/command_unsupported.go b/vendor/github.com/docker/docker/pkg/reexec/command_unsupported.go index 76edd82427..e7eed24240 100644 --- a/vendor/github.com/docker/docker/pkg/reexec/command_unsupported.go +++ b/vendor/github.com/docker/docker/pkg/reexec/command_unsupported.go @@ -1,12 +1,16 @@ -// +build !linux,!windows,!freebsd,!solaris,!darwin +// +build !linux,!windows,!freebsd,!darwin -package reexec +package reexec // import "github.com/docker/docker/pkg/reexec" import ( "os/exec" ) -// Command is unsupported on operating systems apart from Linux, Windows, Solaris and Darwin. +func Self() string { + return "" +} + +// Command is unsupported on operating systems apart from Linux, Windows, and Darwin. func Command(args ...string) *exec.Cmd { return nil } diff --git a/vendor/github.com/docker/docker/pkg/reexec/command_windows.go b/vendor/github.com/docker/docker/pkg/reexec/command_windows.go index ca871c4227..438226890f 100644 --- a/vendor/github.com/docker/docker/pkg/reexec/command_windows.go +++ b/vendor/github.com/docker/docker/pkg/reexec/command_windows.go @@ -1,6 +1,4 @@ -// +build windows - -package reexec +package reexec // import "github.com/docker/docker/pkg/reexec" import ( "os/exec" diff --git a/vendor/github.com/docker/docker/pkg/reexec/reexec.go b/vendor/github.com/docker/docker/pkg/reexec/reexec.go index c56671d919..f8ccddd599 100644 --- a/vendor/github.com/docker/docker/pkg/reexec/reexec.go +++ b/vendor/github.com/docker/docker/pkg/reexec/reexec.go @@ -1,4 +1,4 @@ -package reexec +package reexec // import "github.com/docker/docker/pkg/reexec" import ( "fmt" diff --git a/vendor/github.com/elastic/gosigar/CHANGELOG.md b/vendor/github.com/elastic/gosigar/CHANGELOG.md index 12695e10ef..45262e7b8d 100644 --- a/vendor/github.com/elastic/gosigar/CHANGELOG.md +++ b/vendor/github.com/elastic/gosigar/CHANGELOG.md @@ -8,10 +8,21 @@ This project adheres to [Semantic Versioning](http://semver.org/). ### Fixed +- Added missing runtime import for FreeBSD. #104 + ### Changed ### Deprecated +## [0.9.0] + +### Added +- Added support for huge TLB pages on Linux #97 +- Added support for big endian platform #100 + +### Fixed +- Add missing method for OpenBSD #99 + ## [0.8.0] ### Added diff --git a/vendor/github.com/elastic/gosigar/README.md b/vendor/github.com/elastic/gosigar/README.md index 2482620a83..ecdfc1c3c5 100644 --- a/vendor/github.com/elastic/gosigar/README.md +++ b/vendor/github.com/elastic/gosigar/README.md @@ -26,6 +26,7 @@ The features vary by operating system. | FDUsage | X | | | | X | | FileSystemList | X | X | X | X | X | | FileSystemUsage | X | X | X | X | X | +| HugeTLBPages | X | | | | | | LoadAverage | X | X | | X | X | | Mem | X | X | X | X | X | | ProcArgs | X | X | X | | X | diff --git a/vendor/github.com/elastic/gosigar/concrete_sigar.go b/vendor/github.com/elastic/gosigar/concrete_sigar.go index 685aa6dedd..e3ee80a980 100644 --- a/vendor/github.com/elastic/gosigar/concrete_sigar.go +++ b/vendor/github.com/elastic/gosigar/concrete_sigar.go @@ -62,6 +62,12 @@ func (c *ConcreteSigar) GetSwap() (Swap, error) { return s, err } +func (c *ConcreteSigar) GetHugeTLBPages() (HugeTLBPages, error) { + p := HugeTLBPages{} + err := p.Get() + return p, err +} + func (c *ConcreteSigar) GetFileSystemUsage(path string) (FileSystemUsage, error) { f := FileSystemUsage{} err := f.Get(path) diff --git a/vendor/github.com/elastic/gosigar/sigar_darwin.go b/vendor/github.com/elastic/gosigar/sigar_darwin.go index f989f51608..a90b998c2e 100644 --- a/vendor/github.com/elastic/gosigar/sigar_darwin.go +++ b/vendor/github.com/elastic/gosigar/sigar_darwin.go @@ -91,6 +91,10 @@ func (self *Swap) Get() error { return nil } +func (self *HugeTLBPages) Get() error { + return ErrNotImplemented{runtime.GOOS} +} + func (self *Cpu) Get() error { var count C.mach_msg_type_number_t = C.HOST_CPU_LOAD_INFO_COUNT var cpuload C.host_cpu_load_info_data_t diff --git a/vendor/github.com/elastic/gosigar/sigar_freebsd.go b/vendor/github.com/elastic/gosigar/sigar_freebsd.go index 602b4a0aad..9b2af639b6 100644 --- a/vendor/github.com/elastic/gosigar/sigar_freebsd.go +++ b/vendor/github.com/elastic/gosigar/sigar_freebsd.go @@ -4,6 +4,7 @@ package gosigar import ( "io/ioutil" + "runtime" "strconv" "strings" "unsafe" @@ -97,6 +98,10 @@ func (self *ProcFDUsage) Get(pid int) error { return nil } +func (self *HugeTLBPages) Get() error { + return ErrNotImplemented{runtime.GOOS} +} + func parseCpuStat(self *Cpu, line string) error { fields := strings.Fields(line) diff --git a/vendor/github.com/elastic/gosigar/sigar_interface.go b/vendor/github.com/elastic/gosigar/sigar_interface.go index a956af604a..df79ae08d2 100644 --- a/vendor/github.com/elastic/gosigar/sigar_interface.go +++ b/vendor/github.com/elastic/gosigar/sigar_interface.go @@ -26,6 +26,7 @@ type Sigar interface { GetLoadAverage() (LoadAverage, error) GetMem() (Mem, error) GetSwap() (Swap, error) + GetHugeTLBPages(HugeTLBPages, error) GetFileSystemUsage(string) (FileSystemUsage, error) GetFDUsage() (FDUsage, error) GetRusage(who int) (Rusage, error) @@ -82,6 +83,15 @@ type Swap struct { Free uint64 } +type HugeTLBPages struct { + Total uint64 + Free uint64 + Reserved uint64 + Surplus uint64 + DefaultSize uint64 + TotalAllocatedSize uint64 +} + type CpuList struct { List []Cpu } diff --git a/vendor/github.com/elastic/gosigar/sigar_linux.go b/vendor/github.com/elastic/gosigar/sigar_linux.go index cb1d3525b5..09f2e30b2f 100644 --- a/vendor/github.com/elastic/gosigar/sigar_linux.go +++ b/vendor/github.com/elastic/gosigar/sigar_linux.go @@ -45,6 +45,30 @@ func (self *FDUsage) Get() error { }) } +func (self *HugeTLBPages) Get() error { + table, err := parseMeminfo() + if err != nil { + return err + } + + self.Total, _ = table["HugePages_Total"] + self.Free, _ = table["HugePages_Free"] + self.Reserved, _ = table["HugePages_Rsvd"] + self.Surplus, _ = table["HugePages_Surp"] + self.DefaultSize, _ = table["Hugepagesize"] + + if totalSize, found := table["Hugetlb"]; found { + self.TotalAllocatedSize = totalSize + } else { + // If Hugetlb is not present, or huge pages of different sizes + // are used, this figure can be unaccurate. + // TODO (jsoriano): Extract information from /sys/kernel/mm/hugepages too + self.TotalAllocatedSize = (self.Total - self.Free + self.Reserved) * self.DefaultSize + } + + return nil +} + func (self *ProcFDUsage) Get(pid int) error { err := readFile(procFileName(pid, "limits"), func(line string) bool { if strings.HasPrefix(line, "Max open files") { diff --git a/vendor/github.com/elastic/gosigar/sigar_linux_common.go b/vendor/github.com/elastic/gosigar/sigar_linux_common.go index 8e5e7856f6..7ca6497622 100644 --- a/vendor/github.com/elastic/gosigar/sigar_linux_common.go +++ b/vendor/github.com/elastic/gosigar/sigar_linux_common.go @@ -379,12 +379,16 @@ func parseMeminfo() (map[string]uint64, error) { return true // skip on errors } - num := strings.TrimLeft(fields[1], " ") - val, err := strtoull(strings.Fields(num)[0]) + valueUnit := strings.Fields(fields[1]) + value, err := strtoull(valueUnit[0]) if err != nil { return true // skip on errors } - table[fields[0]] = val * 1024 //in bytes + + if len(valueUnit) > 1 && valueUnit[1] == "kB" { + value *= 1024 + } + table[fields[0]] = value return true }) @@ -420,8 +424,18 @@ func procFileName(pid int, name string) string { return Procd + "/" + strconv.Itoa(pid) + "/" + name } -func readProcFile(pid int, name string) ([]byte, error) { +func readProcFile(pid int, name string) (content []byte, err error) { path := procFileName(pid, name) + + // Panics have been reported when reading proc files, let's recover and + // report the path if this happens + // See https://github.com/elastic/beats/issues/6692 + defer func() { + if r := recover(); r != nil { + content = nil + err = fmt.Errorf("recovered panic when reading proc file '%s': %v", path, r) + } + }() contents, err := ioutil.ReadFile(path) if err != nil { diff --git a/vendor/github.com/elastic/gosigar/sigar_openbsd.go b/vendor/github.com/elastic/gosigar/sigar_openbsd.go index 4f1383a6ba..e4371b8b68 100644 --- a/vendor/github.com/elastic/gosigar/sigar_openbsd.go +++ b/vendor/github.com/elastic/gosigar/sigar_openbsd.go @@ -294,6 +294,10 @@ func (self *Swap) Get() error { return nil } +func (self *HugeTLBPages) Get() error { + return ErrNotImplemented{runtime.GOOS} +} + func (self *Cpu) Get() error { load := [C.CPUSTATES]C.long{C.CP_USER, C.CP_NICE, C.CP_SYS, C.CP_INTR, C.CP_IDLE} @@ -381,6 +385,10 @@ func (self *ProcFDUsage) Get(pid int) error { return ErrNotImplemented{runtime.GOOS} } +func (self *Rusage) Get(pid int) error { + return ErrNotImplemented{runtime.GOOS} +} + func fillCpu(cpu *Cpu, load [C.CPUSTATES]C.long) { cpu.User = uint64(load[0]) cpu.Nice = uint64(load[1]) diff --git a/vendor/github.com/elastic/gosigar/sigar_stub.go b/vendor/github.com/elastic/gosigar/sigar_stub.go index 0b858f1c0c..de9565aec4 100644 --- a/vendor/github.com/elastic/gosigar/sigar_stub.go +++ b/vendor/github.com/elastic/gosigar/sigar_stub.go @@ -22,6 +22,10 @@ func (s *Swap) Get() error { return ErrNotImplemented{runtime.GOOS} } +func (s *HugeTLBPages) Get() error { + return ErrNotImplemented{runtime.GOOS} +} + func (f *FDUsage) Get() error { return ErrNotImplemented{runtime.GOOS} } diff --git a/vendor/github.com/elastic/gosigar/sigar_windows.go b/vendor/github.com/elastic/gosigar/sigar_windows.go index 0cdf928d16..c2b54d8d7f 100644 --- a/vendor/github.com/elastic/gosigar/sigar_windows.go +++ b/vendor/github.com/elastic/gosigar/sigar_windows.go @@ -120,6 +120,10 @@ func (self *Swap) Get() error { return nil } +func (self *HugeTLBPages) Get() error { + return ErrNotImplemented{runtime.GOOS} +} + func (self *Cpu) Get() error { idle, kernel, user, err := windows.GetSystemTimes() if err != nil { diff --git a/vendor/github.com/fjl/memsize/LICENSE b/vendor/github.com/fjl/memsize/LICENSE new file mode 100644 index 0000000000..8b80456419 --- /dev/null +++ b/vendor/github.com/fjl/memsize/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 Felix Lange + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/fjl/memsize/bitmap.go b/vendor/github.com/fjl/memsize/bitmap.go new file mode 100644 index 0000000000..47799ea8d3 --- /dev/null +++ b/vendor/github.com/fjl/memsize/bitmap.go @@ -0,0 +1,119 @@ +package memsize + +import ( + "math/bits" +) + +const ( + uintptrBits = 32 << (uint64(^uintptr(0)) >> 63) + uintptrBytes = uintptrBits / 8 + bmBlockRange = 1 * 1024 * 1024 // bytes covered by bmBlock + bmBlockWords = bmBlockRange / uintptrBits +) + +// bitmap is a sparse bitmap. +type bitmap struct { + blocks map[uintptr]*bmBlock +} + +func newBitmap() *bitmap { + return &bitmap{make(map[uintptr]*bmBlock)} +} + +// markRange sets n consecutive bits starting at addr. +func (b *bitmap) markRange(addr, n uintptr) { + for end := addr + n; addr < end; { + block, baddr := b.block(addr) + for i := baddr; i < bmBlockRange && addr < end; i++ { + block.mark(i) + addr++ + } + } +} + +// isMarked returns the value of the bit at the given address. +func (b *bitmap) isMarked(addr uintptr) bool { + block, baddr := b.block(addr) + return block.isMarked(baddr) +} + +// countRange returns the number of set bits in the range (addr,addr+n). +func (b *bitmap) countRange(addr, n uintptr) uintptr { + c := uintptr(0) + for end := addr + n; addr < end; { + block, baddr := b.block(addr) + bend := uintptr(bmBlockRange - 1) + if baddr+(end-addr) < bmBlockRange { + bend = baddr + (end - addr) + } + c += uintptr(block.count(baddr, bend)) + // Move addr to next block. + addr += bmBlockRange - baddr + } + return c +} + +// block finds the block corresponding to the given memory address. +// It also returns the block's starting address. +func (b *bitmap) block(addr uintptr) (*bmBlock, uintptr) { + index := addr / bmBlockRange + block := b.blocks[index] + if block == nil { + block = new(bmBlock) + b.blocks[index] = block + } + return block, addr % bmBlockRange +} + +// size returns the sum of the byte sizes of all blocks. +func (b *bitmap) size() uintptr { + return uintptr(len(b.blocks)) * bmBlockWords * uintptrBytes +} + +// utilization returns the mean percentage of one bits across all blocks. +func (b *bitmap) utilization() float32 { + var avg float32 + for _, block := range b.blocks { + avg += float32(block.count(0, bmBlockRange-1)) / float32(bmBlockRange) + } + return avg / float32(len(b.blocks)) +} + +// bmBlock is a bitmap block. +type bmBlock [bmBlockWords]uintptr + +// mark sets the i'th bit to one. +func (b *bmBlock) mark(i uintptr) { + b[i/uintptrBits] |= 1 << (i % uintptrBits) +} + +// isMarked returns the value of the i'th bit. +func (b *bmBlock) isMarked(i uintptr) bool { + return (b[i/uintptrBits] & (1 << (i % uintptrBits))) != 0 +} + +// count returns the number of set bits in the range (start,end). +func (b *bmBlock) count(start, end uintptr) (count int) { + br := b[start/uintptrBits : end/uintptrBits+1] + for i, w := range br { + if i == 0 { + w &= blockmask(start) + } + if i == len(br)-1 { + w &^= blockmask(end) + } + count += onesCountPtr(w) + } + return count +} + +func blockmask(x uintptr) uintptr { + return ^uintptr(0) << (x % uintptrBits) +} + +func onesCountPtr(x uintptr) int { + if uintptrBits == 64 { + return bits.OnesCount64(uint64(x)) + } + return bits.OnesCount32(uint32(x)) +} diff --git a/vendor/github.com/fjl/memsize/doc.go b/vendor/github.com/fjl/memsize/doc.go new file mode 100644 index 0000000000..640cfba5eb --- /dev/null +++ b/vendor/github.com/fjl/memsize/doc.go @@ -0,0 +1,16 @@ +/* +Package memsize computes the size of your object graph. + +So you made a spiffy algorithm and it works really well, but geez it's using +way too much memory. Where did it all go? memsize to the rescue! + +To get started, find a value that references all your objects and scan it. +This traverses the graph, counting sizes per type. + + sizes := memsize.Scan(myValue) + fmt.Println(sizes.Total) + +memsize can handle cycles just fine and tracks both private and public struct fields. +Unfortunately function closures cannot be inspected in any way. +*/ +package memsize diff --git a/vendor/github.com/fjl/memsize/memsize.go b/vendor/github.com/fjl/memsize/memsize.go new file mode 100644 index 0000000000..2664e87c46 --- /dev/null +++ b/vendor/github.com/fjl/memsize/memsize.go @@ -0,0 +1,243 @@ +package memsize + +import ( + "bytes" + "fmt" + "reflect" + "sort" + "strings" + "text/tabwriter" + "unsafe" +) + +// Scan traverses all objects reachable from v and counts how much memory +// is used per type. The value must be a non-nil pointer to any value. +func Scan(v interface{}) Sizes { + rv := reflect.ValueOf(v) + if rv.Kind() != reflect.Ptr || rv.IsNil() { + panic("value to scan must be non-nil pointer") + } + + stopTheWorld("memsize scan") + defer startTheWorld() + + ctx := newContext() + ctx.scan(invalidAddr, rv, false) + ctx.s.BitmapSize = ctx.seen.size() + ctx.s.BitmapUtilization = ctx.seen.utilization() + return *ctx.s +} + +// Sizes is the result of a scan. +type Sizes struct { + Total uintptr + ByType map[reflect.Type]*TypeSize + // Internal stats (for debugging) + BitmapSize uintptr + BitmapUtilization float32 +} + +type TypeSize struct { + Total uintptr + Count uintptr +} + +func newSizes() *Sizes { + return &Sizes{ByType: make(map[reflect.Type]*TypeSize)} +} + +// Report returns a human-readable report. +func (s Sizes) Report() string { + type typLine struct { + name string + count uintptr + total uintptr + } + tab := []typLine{{"ALL", 0, s.Total}} + for _, typ := range s.ByType { + tab[0].count += typ.Count + } + maxname := 0 + for typ, s := range s.ByType { + line := typLine{typ.String(), s.Count, s.Total} + tab = append(tab, line) + if len(line.name) > maxname { + maxname = len(line.name) + } + } + sort.Slice(tab, func(i, j int) bool { return tab[i].total > tab[j].total }) + + buf := new(bytes.Buffer) + w := tabwriter.NewWriter(buf, 0, 0, 0, ' ', tabwriter.AlignRight) + for _, line := range tab { + namespace := strings.Repeat(" ", maxname-len(line.name)) + fmt.Fprintf(w, "%s%s\t %v\t %s\t\n", line.name, namespace, line.count, HumanSize(line.total)) + } + w.Flush() + return buf.String() +} + +// addValue is called during scan and adds the memory of given object. +func (s *Sizes) addValue(v reflect.Value, size uintptr) { + s.Total += size + rs := s.ByType[v.Type()] + if rs == nil { + rs = new(TypeSize) + s.ByType[v.Type()] = rs + } + rs.Total += size + rs.Count++ +} + +type context struct { + // We track previously scanned objects to prevent infinite loops + // when scanning cycles and to prevent counting objects more than once. + seen *bitmap + tc typCache + s *Sizes +} + +func newContext() *context { + return &context{seen: newBitmap(), tc: make(typCache), s: newSizes()} +} + +// scan walks all objects below v, determining their size. All scan* functions return the +// amount of 'extra' memory (e.g. slice data) that is referenced by the object. +func (c *context) scan(addr address, v reflect.Value, add bool) (extraSize uintptr) { + size := v.Type().Size() + var marked uintptr + if addr.valid() { + marked = c.seen.countRange(uintptr(addr), size) + if marked == size { + return 0 // Skip if we have already seen the whole object. + } + c.seen.markRange(uintptr(addr), size) + } + // fmt.Printf("%v: %v ⮑ (marked %d)\n", addr, v.Type(), marked) + if c.tc.needScan(v.Type()) { + extraSize = c.scanContent(addr, v) + } + // fmt.Printf("%v: %v %d (add %v, size %d, marked %d, extra %d)\n", addr, v.Type(), size+extraSize, add, v.Type().Size(), marked, extraSize) + if add { + size -= marked + size += extraSize + c.s.addValue(v, size) + } + return extraSize +} + +func (c *context) scanContent(addr address, v reflect.Value) uintptr { + switch v.Kind() { + case reflect.Array: + return c.scanArray(addr, v) + case reflect.Chan: + return c.scanChan(v) + case reflect.Func: + // can't do anything here + return 0 + case reflect.Interface: + return c.scanInterface(v) + case reflect.Map: + return c.scanMap(v) + case reflect.Ptr: + if !v.IsNil() { + c.scan(address(v.Pointer()), v.Elem(), true) + } + return 0 + case reflect.Slice: + return c.scanSlice(v) + case reflect.String: + return uintptr(v.Len()) + case reflect.Struct: + return c.scanStruct(addr, v) + default: + unhandledKind(v.Kind()) + return 0 + } +} + +func (c *context) scanChan(v reflect.Value) uintptr { + etyp := v.Type().Elem() + extra := uintptr(0) + if c.tc.needScan(etyp) { + // Scan the channel buffer. This is unsafe but doesn't race because + // the world is stopped during scan. + hchan := unsafe.Pointer(v.Pointer()) + for i := uint(0); i < uint(v.Cap()); i++ { + addr := chanbuf(hchan, i) + elem := reflect.NewAt(etyp, addr).Elem() + extra += c.scanContent(address(addr), elem) + } + } + return uintptr(v.Cap())*etyp.Size() + extra +} + +func (c *context) scanStruct(base address, v reflect.Value) uintptr { + extra := uintptr(0) + for i := 0; i < v.NumField(); i++ { + f := v.Type().Field(i) + if c.tc.needScan(f.Type) { + addr := base.addOffset(f.Offset) + extra += c.scanContent(addr, v.Field(i)) + } + } + return extra +} + +func (c *context) scanArray(addr address, v reflect.Value) uintptr { + esize := v.Type().Elem().Size() + extra := uintptr(0) + for i := 0; i < v.Len(); i++ { + extra += c.scanContent(addr, v.Index(i)) + addr = addr.addOffset(esize) + } + return extra +} + +func (c *context) scanSlice(v reflect.Value) uintptr { + slice := v.Slice(0, v.Cap()) + esize := slice.Type().Elem().Size() + base := slice.Pointer() + // Add size of the unscanned portion of the backing array to extra. + blen := uintptr(slice.Len()) * esize + marked := c.seen.countRange(base, blen) + extra := blen - marked + c.seen.markRange(uintptr(base), blen) + if c.tc.needScan(slice.Type().Elem()) { + // Elements may contain pointers, scan them individually. + addr := address(base) + for i := 0; i < slice.Len(); i++ { + extra += c.scanContent(addr, slice.Index(i)) + addr = addr.addOffset(esize) + } + } + return extra +} + +func (c *context) scanMap(v reflect.Value) uintptr { + var ( + typ = v.Type() + len = uintptr(v.Len()) + extra = uintptr(0) + ) + if c.tc.needScan(typ.Key()) || c.tc.needScan(typ.Elem()) { + for _, k := range v.MapKeys() { + extra += c.scan(invalidAddr, k, false) + extra += c.scan(invalidAddr, v.MapIndex(k), false) + } + } + return len*typ.Key().Size() + len*typ.Elem().Size() + extra +} + +func (c *context) scanInterface(v reflect.Value) uintptr { + elem := v.Elem() + if !elem.IsValid() { + return 0 // nil interface + } + c.scan(invalidAddr, elem, false) + if !c.tc.isPointer(elem.Type()) { + // Account for non-pointer size of the value. + return elem.Type().Size() + } + return 0 +} diff --git a/vendor/github.com/fjl/memsize/memsizeui/template.go b/vendor/github.com/fjl/memsize/memsizeui/template.go new file mode 100644 index 0000000000..b60fe6ba54 --- /dev/null +++ b/vendor/github.com/fjl/memsize/memsizeui/template.go @@ -0,0 +1,106 @@ +package memsizeui + +import ( + "html/template" + "strconv" + "sync" + + "github.com/fjl/memsize" +) + +var ( + base *template.Template // the "base" template + baseInitOnce sync.Once +) + +func baseInit() { + base = template.Must(template.New("base").Parse(` + + + + memsize + + + + {{template "content" .}} + +`)) + + base.Funcs(template.FuncMap{ + "quote": strconv.Quote, + "humansize": memsize.HumanSize, + }) + + template.Must(base.New("rootbuttons").Parse(` +Overview +{{- range $root := .Roots -}} +
+ +
+{{- end -}}`)) +} + +func contentTemplate(source string) *template.Template { + baseInitOnce.Do(baseInit) + t := template.Must(base.Clone()) + template.Must(t.New("content").Parse(source)) + return t +} + +var rootTemplate = contentTemplate(` +

Memsize

+{{template "rootbuttons" .}} +
+

Reports

+ +`) + +var notFoundTemplate = contentTemplate(` +

{{.Data}}

+{{template "rootbuttons" .}} +`) + +var reportTemplate = contentTemplate(` +{{- $report := .Data -}} +

Memsize Report {{$report.ID}}

+
+ Overview + +
+
+Root: {{quote $report.RootName}}
+Date: {{$report.Date}}
+Duration: {{$report.Duration}}
+Bitmap Size: {{$report.Sizes.BitmapSize | humansize}}
+Bitmap Utilization: {{$report.Sizes.BitmapUtilization}}
+
+
+
+{{$report.Sizes.Report}}
+
+`) diff --git a/vendor/github.com/fjl/memsize/memsizeui/ui.go b/vendor/github.com/fjl/memsize/memsizeui/ui.go new file mode 100644 index 0000000000..c48fc53f7f --- /dev/null +++ b/vendor/github.com/fjl/memsize/memsizeui/ui.go @@ -0,0 +1,153 @@ +package memsizeui + +import ( + "bytes" + "fmt" + "html/template" + "net/http" + "reflect" + "sort" + "strings" + "sync" + "time" + + "github.com/fjl/memsize" +) + +type Handler struct { + init sync.Once + mux http.ServeMux + mu sync.Mutex + reports map[int]Report + roots map[string]interface{} + reportID int +} + +type Report struct { + ID int + Date time.Time + Duration time.Duration + RootName string + Sizes memsize.Sizes +} + +type templateInfo struct { + Roots []string + Reports map[int]Report + PathDepth int + Data interface{} +} + +func (ti *templateInfo) Link(path ...string) string { + prefix := strings.Repeat("../", ti.PathDepth) + return prefix + strings.Join(path, "") +} + +func (h *Handler) Add(name string, v interface{}) { + rv := reflect.ValueOf(v) + if rv.Kind() != reflect.Ptr || rv.IsNil() { + panic("root must be non-nil pointer") + } + h.mu.Lock() + if h.roots == nil { + h.roots = make(map[string]interface{}) + } + h.roots[name] = v + h.mu.Unlock() +} + +func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + h.init.Do(func() { + h.reports = make(map[int]Report) + h.mux.HandleFunc("/", h.handleRoot) + h.mux.HandleFunc("/scan", h.handleScan) + h.mux.HandleFunc("/report/", h.handleReport) + }) + h.mux.ServeHTTP(w, r) +} + +func (h *Handler) templateInfo(r *http.Request, data interface{}) *templateInfo { + h.mu.Lock() + roots := make([]string, 0, len(h.roots)) + for name := range h.roots { + roots = append(roots, name) + } + h.mu.Unlock() + sort.Strings(roots) + + return &templateInfo{ + Roots: roots, + Reports: h.reports, + PathDepth: strings.Count(r.URL.Path, "/") - 1, + Data: data, + } +} + +func (h *Handler) handleRoot(w http.ResponseWriter, r *http.Request) { + if r.URL.Path != "/" { + http.NotFound(w, r) + return + } + serveHTML(w, rootTemplate, http.StatusOK, h.templateInfo(r, nil)) +} + +func (h *Handler) handleScan(w http.ResponseWriter, r *http.Request) { + if r.Method != http.MethodPost { + http.Error(w, "invalid HTTP method, want POST", http.StatusMethodNotAllowed) + return + } + ti := h.templateInfo(r, "Unknown root") + id, ok := h.scan(r.URL.Query().Get("root")) + if !ok { + serveHTML(w, notFoundTemplate, http.StatusNotFound, ti) + return + } + w.Header().Add("Location", ti.Link(fmt.Sprintf("report/%d", id))) + w.WriteHeader(http.StatusSeeOther) +} + +func (h *Handler) handleReport(w http.ResponseWriter, r *http.Request) { + var id int + fmt.Sscan(strings.TrimPrefix(r.URL.Path, "/report/"), &id) + h.mu.Lock() + report, ok := h.reports[id] + h.mu.Unlock() + + if !ok { + serveHTML(w, notFoundTemplate, http.StatusNotFound, h.templateInfo(r, "Report not found")) + } else { + serveHTML(w, reportTemplate, http.StatusOK, h.templateInfo(r, report)) + } +} + +func (h *Handler) scan(root string) (int, bool) { + h.mu.Lock() + defer h.mu.Unlock() + + val, ok := h.roots[root] + if !ok { + return 0, false + } + id := h.reportID + start := time.Now() + sizes := memsize.Scan(val) + h.reports[id] = Report{ + ID: id, + RootName: root, + Date: start.Truncate(1 * time.Second), + Duration: time.Since(start), + Sizes: sizes, + } + h.reportID++ + return id, true +} + +func serveHTML(w http.ResponseWriter, tpl *template.Template, status int, ti *templateInfo) { + w.Header().Set("content-type", "text/html") + var buf bytes.Buffer + if err := tpl.Execute(&buf, ti); err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + buf.WriteTo(w) +} diff --git a/vendor/github.com/fjl/memsize/runtimefunc.go b/vendor/github.com/fjl/memsize/runtimefunc.go new file mode 100644 index 0000000000..912a3e768d --- /dev/null +++ b/vendor/github.com/fjl/memsize/runtimefunc.go @@ -0,0 +1,14 @@ +package memsize + +import "unsafe" + +var _ = unsafe.Pointer(nil) + +//go:linkname stopTheWorld runtime.stopTheWorld +func stopTheWorld(reason string) + +//go:linkname startTheWorld runtime.startTheWorld +func startTheWorld() + +//go:linkname chanbuf runtime.chanbuf +func chanbuf(ch unsafe.Pointer, i uint) unsafe.Pointer diff --git a/vendor/github.com/fjl/memsize/runtimefunc.s b/vendor/github.com/fjl/memsize/runtimefunc.s new file mode 100644 index 0000000000..a091e2fa72 --- /dev/null +++ b/vendor/github.com/fjl/memsize/runtimefunc.s @@ -0,0 +1 @@ +// This file is required to make stub function declarations work. diff --git a/vendor/github.com/fjl/memsize/type.go b/vendor/github.com/fjl/memsize/type.go new file mode 100644 index 0000000000..5d6f59e9ff --- /dev/null +++ b/vendor/github.com/fjl/memsize/type.go @@ -0,0 +1,119 @@ +package memsize + +import ( + "fmt" + "reflect" +) + +// address is a memory location. +// +// Code dealing with uintptr is oblivious to the zero address. +// Code dealing with address is not: it treats the zero address +// as invalid. Offsetting an invalid address doesn't do anything. +// +// This distinction is useful because there are objects that we can't +// get the pointer to. +type address uintptr + +const invalidAddr = address(0) + +func (a address) valid() bool { + return a != 0 +} + +func (a address) addOffset(off uintptr) address { + if !a.valid() { + return invalidAddr + } + return a + address(off) +} + +func (a address) String() string { + if uintptrBits == 32 { + return fmt.Sprintf("%#0.8x", uintptr(a)) + } + return fmt.Sprintf("%#0.16x", uintptr(a)) +} + +type typCache map[reflect.Type]typInfo + +type typInfo struct { + isPointer bool + needScan bool +} + +// isPointer returns true for pointer-ish values. The notion of +// pointer includes everything but plain values, i.e. slices, maps +// channels, interfaces are 'pointer', too. +func (tc *typCache) isPointer(typ reflect.Type) bool { + return tc.info(typ).isPointer +} + +// needScan reports whether a value of the type needs to be scanned +// recursively because it may contain pointers. +func (tc *typCache) needScan(typ reflect.Type) bool { + return tc.info(typ).needScan +} + +func (tc *typCache) info(typ reflect.Type) typInfo { + info, found := (*tc)[typ] + switch { + case found: + return info + case isPointer(typ): + info = typInfo{true, true} + default: + info = typInfo{false, tc.checkNeedScan(typ)} + } + (*tc)[typ] = info + return info +} + +func (tc *typCache) checkNeedScan(typ reflect.Type) bool { + switch k := typ.Kind(); k { + case reflect.Struct: + // Structs don't need scan if none of their fields need it. + for i := 0; i < typ.NumField(); i++ { + if tc.needScan(typ.Field(i).Type) { + return true + } + } + case reflect.Array: + // Arrays don't need scan if their element type doesn't. + return tc.needScan(typ.Elem()) + } + return false +} + +func isPointer(typ reflect.Type) bool { + k := typ.Kind() + switch { + case k <= reflect.Complex128: + return false + case k == reflect.Array: + return false + case k >= reflect.Chan && k <= reflect.String: + return true + case k == reflect.Struct || k == reflect.UnsafePointer: + return false + default: + unhandledKind(k) + return false + } +} + +func unhandledKind(k reflect.Kind) { + panic("unhandled kind " + k.String()) +} + +// HumanSize formats the given number of bytes as a readable string. +func HumanSize(bytes uintptr) string { + switch { + case bytes < 1024: + return fmt.Sprintf("%d B", bytes) + case bytes < 1024*1024: + return fmt.Sprintf("%.3f KB", float64(bytes)/1024) + default: + return fmt.Sprintf("%.3f MB", float64(bytes)/1024/1024) + } +} diff --git a/vendor/github.com/mohae/deepcopy/LICENSE b/vendor/github.com/mohae/deepcopy/LICENSE new file mode 100644 index 0000000000..419673f005 --- /dev/null +++ b/vendor/github.com/mohae/deepcopy/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014 Joel + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/mohae/deepcopy/README.md b/vendor/github.com/mohae/deepcopy/README.md new file mode 100644 index 0000000000..f81841885b --- /dev/null +++ b/vendor/github.com/mohae/deepcopy/README.md @@ -0,0 +1,8 @@ +deepCopy +======== +[![GoDoc](https://godoc.org/github.com/mohae/deepcopy?status.svg)](https://godoc.org/github.com/mohae/deepcopy)[![Build Status](https://travis-ci.org/mohae/deepcopy.png)](https://travis-ci.org/mohae/deepcopy) + +DeepCopy makes deep copies of things: unexported field values are not copied. + +## Usage + cpy := deepcopy.Copy(orig) diff --git a/vendor/github.com/mohae/deepcopy/deepcopy.go b/vendor/github.com/mohae/deepcopy/deepcopy.go new file mode 100644 index 0000000000..ba763ad091 --- /dev/null +++ b/vendor/github.com/mohae/deepcopy/deepcopy.go @@ -0,0 +1,125 @@ +// deepcopy makes deep copies of things. A standard copy will copy the +// pointers: deep copy copies the values pointed to. Unexported field +// values are not copied. +// +// Copyright (c)2014-2016, Joel Scoble (github.com/mohae), all rights reserved. +// License: MIT, for more details check the included LICENSE file. +package deepcopy + +import ( + "reflect" + "time" +) + +// Interface for delegating copy process to type +type Interface interface { + DeepCopy() interface{} +} + +// Iface is an alias to Copy; this exists for backwards compatibility reasons. +func Iface(iface interface{}) interface{} { + return Copy(iface) +} + +// Copy creates a deep copy of whatever is passed to it and returns the copy +// in an interface{}. The returned value will need to be asserted to the +// correct type. +func Copy(src interface{}) interface{} { + if src == nil { + return nil + } + + // Make the interface a reflect.Value + original := reflect.ValueOf(src) + + // Make a copy of the same type as the original. + cpy := reflect.New(original.Type()).Elem() + + // Recursively copy the original. + copyRecursive(original, cpy) + + // Return the copy as an interface. + return cpy.Interface() +} + +// copyRecursive does the actual copying of the interface. It currently has +// limited support for what it can handle. Add as needed. +func copyRecursive(original, cpy reflect.Value) { + // check for implement deepcopy.Interface + if original.CanInterface() { + if copier, ok := original.Interface().(Interface); ok { + cpy.Set(reflect.ValueOf(copier.DeepCopy())) + return + } + } + + // handle according to original's Kind + switch original.Kind() { + case reflect.Ptr: + // Get the actual value being pointed to. + originalValue := original.Elem() + + // if it isn't valid, return. + if !originalValue.IsValid() { + return + } + cpy.Set(reflect.New(originalValue.Type())) + copyRecursive(originalValue, cpy.Elem()) + + case reflect.Interface: + // If this is a nil, don't do anything + if original.IsNil() { + return + } + // Get the value for the interface, not the pointer. + originalValue := original.Elem() + + // Get the value by calling Elem(). + copyValue := reflect.New(originalValue.Type()).Elem() + copyRecursive(originalValue, copyValue) + cpy.Set(copyValue) + + case reflect.Struct: + t, ok := original.Interface().(time.Time) + if ok { + cpy.Set(reflect.ValueOf(t)) + return + } + // Go through each field of the struct and copy it. + for i := 0; i < original.NumField(); i++ { + // The Type's StructField for a given field is checked to see if StructField.PkgPath + // is set to determine if the field is exported or not because CanSet() returns false + // for settable fields. I'm not sure why. -mohae + if original.Type().Field(i).PkgPath != "" { + continue + } + copyRecursive(original.Field(i), cpy.Field(i)) + } + + case reflect.Slice: + if original.IsNil() { + return + } + // Make a new slice and copy each element. + cpy.Set(reflect.MakeSlice(original.Type(), original.Len(), original.Cap())) + for i := 0; i < original.Len(); i++ { + copyRecursive(original.Index(i), cpy.Index(i)) + } + + case reflect.Map: + if original.IsNil() { + return + } + cpy.Set(reflect.MakeMap(original.Type())) + for _, key := range original.MapKeys() { + originalValue := original.MapIndex(key) + copyValue := reflect.New(originalValue.Type()).Elem() + copyRecursive(originalValue, copyValue) + copyKey := Copy(key.Interface()) + cpy.SetMapIndex(reflect.ValueOf(copyKey), copyValue) + } + + default: + cpy.Set(original) + } +} diff --git a/vendor/github.com/naoina/toml/encode.go b/vendor/github.com/naoina/toml/encode.go index ae6bfd575f..15602f005a 100644 --- a/vendor/github.com/naoina/toml/encode.go +++ b/vendor/github.com/naoina/toml/encode.go @@ -61,20 +61,26 @@ func (cfg *Config) NewEncoder(w io.Writer) *Encoder { // Encode writes the TOML of v to the stream. // See the documentation for Marshal for details about the conversion of Go values to TOML. func (e *Encoder) Encode(v interface{}) error { - rv := reflect.ValueOf(v) + var ( + buf = &tableBuf{typ: ast.TableTypeNormal} + rv = reflect.ValueOf(v) + err error + ) + for rv.Kind() == reflect.Ptr { if rv.IsNil() { return &marshalNilError{rv.Type()} } rv = rv.Elem() } - buf := &tableBuf{typ: ast.TableTypeNormal} - var err error + switch rv.Kind() { case reflect.Struct: err = buf.structFields(e.cfg, rv) case reflect.Map: err = buf.mapFields(e.cfg, rv) + case reflect.Interface: + return e.Encode(rv.Interface()) default: err = &marshalTableError{rv.Type()} } diff --git a/vendor/github.com/naoina/toml/parse.go b/vendor/github.com/naoina/toml/parse.go index e6f95001e5..de9108566b 100644 --- a/vendor/github.com/naoina/toml/parse.go +++ b/vendor/github.com/naoina/toml/parse.go @@ -97,6 +97,7 @@ type toml struct { currentTable *ast.Table s string key string + tableKeys []string val ast.Value arr *array stack []*stack @@ -180,12 +181,12 @@ func (p *tomlParser) SetArray(begin, end int) { } func (p *toml) SetTable(buf []rune, begin, end int) { - p.setTable(p.table, buf, begin, end) + rawName := string(buf[begin:end]) + p.setTable(p.table, rawName, p.tableKeys) + p.tableKeys = nil } -func (p *toml) setTable(parent *ast.Table, buf []rune, begin, end int) { - name := string(buf[begin:end]) - names := splitTableKey(name) +func (p *toml) setTable(parent *ast.Table, name string, names []string) { parent, err := p.lookupTable(parent, names[:len(names)-1]) if err != nil { p.Error(err) @@ -230,12 +231,12 @@ func (p *tomlParser) SetTableString(begin, end int) { } func (p *toml) SetArrayTable(buf []rune, begin, end int) { - p.setArrayTable(p.table, buf, begin, end) + rawName := string(buf[begin:end]) + p.setArrayTable(p.table, rawName, p.tableKeys) + p.tableKeys = nil } -func (p *toml) setArrayTable(parent *ast.Table, buf []rune, begin, end int) { - name := string(buf[begin:end]) - names := splitTableKey(name) +func (p *toml) setArrayTable(parent *ast.Table, name string, names []string) { parent, err := p.lookupTable(parent, names[:len(names)-1]) if err != nil { p.Error(err) @@ -260,11 +261,11 @@ func (p *toml) setArrayTable(parent *ast.Table, buf []rune, begin, end int) { func (p *toml) StartInlineTable() { p.skip = false p.stack = append(p.stack, &stack{p.key, p.currentTable}) - buf := []rune(p.key) + names := []string{p.key} if p.arr == nil { - p.setTable(p.currentTable, buf, 0, len(buf)) + p.setTable(p.currentTable, names[0], names) } else { - p.setArrayTable(p.currentTable, buf, 0, len(buf)) + p.setArrayTable(p.currentTable, names[0], names) } } @@ -282,6 +283,13 @@ func (p *toml) AddLineCount(i int) { func (p *toml) SetKey(buf []rune, begin, end int) { p.key = string(buf[begin:end]) + if len(p.key) > 0 && p.key[0] == '"' { + p.key = p.unquote(p.key) + } +} + +func (p *toml) AddTableKey() { + p.tableKeys = append(p.tableKeys, p.key) } func (p *toml) AddKeyValue() { @@ -352,25 +360,3 @@ func (p *toml) lookupTable(t *ast.Table, keys []string) (*ast.Table, error) { } return t, nil } - -func splitTableKey(tk string) []string { - key := make([]byte, 0, 1) - keys := make([]string, 0, 1) - inQuote := false - for i := 0; i < len(tk); i++ { - k := tk[i] - switch { - case k == tableSeparator && !inQuote: - keys = append(keys, string(key)) - key = key[:0] // reuse buffer. - case k == '"': - inQuote = !inQuote - case (k == ' ' || k == '\t') && !inQuote: - // skip. - default: - key = append(key, k) - } - } - keys = append(keys, string(key)) - return keys -} diff --git a/vendor/github.com/naoina/toml/parse.peg b/vendor/github.com/naoina/toml/parse.peg index da31dae309..860ada3732 100644 --- a/vendor/github.com/naoina/toml/parse.peg +++ b/vendor/github.com/naoina/toml/parse.peg @@ -29,7 +29,7 @@ key <- bareKey / quotedKey bareKey <- <[0-9A-Za-z\-_]+> { p.SetKey(p.buffer, begin, end) } -quotedKey <- '"' '"' { p.SetKey(p.buffer, begin-1, end+1) } +quotedKey <- < '"' basicChar* '"' > { p.SetKey(p.buffer, begin, end) } val <- ( { p.SetTime(begin, end) } @@ -55,7 +55,9 @@ inlineTable <- ( inlineTableKeyValues <- (keyval inlineTableValSep?)* -tableKey <- key (tableKeySep key)* +tableKey <- tableKeyComp (tableKeySep tableKeyComp)* + +tableKeyComp <- key { p.AddTableKey() } tableKeySep <- ws '.' ws @@ -117,7 +119,7 @@ timeNumoffset <- [\-+] timeHour ':' timeMinute timeOffset <- 'Z' / timeNumoffset partialTime <- timeHour ':' timeMinute ':' timeSecond timeSecfrac? fullDate <- dateFullYear '-' dateMonth '-' dateMDay -fullTime <- partialTime timeOffset +fullTime <- partialTime timeOffset? datetime <- (fullDate ('T' fullTime)?) / partialTime digit <- [0-9] diff --git a/vendor/github.com/naoina/toml/parse.peg.go b/vendor/github.com/naoina/toml/parse.peg.go index d7de73b19c..fa377b19bd 100644 --- a/vendor/github.com/naoina/toml/parse.peg.go +++ b/vendor/github.com/naoina/toml/parse.peg.go @@ -31,6 +31,7 @@ const ( ruleinlineTable ruleinlineTableKeyValues ruletableKey + ruletableKeyComp ruletableKeySep ruleinlineTableValSep ruleinteger @@ -99,6 +100,7 @@ const ( ruleAction22 ruleAction23 ruleAction24 + ruleAction25 ) var rul3s = [...]string{ @@ -120,6 +122,7 @@ var rul3s = [...]string{ "inlineTable", "inlineTableKeyValues", "tableKey", + "tableKeyComp", "tableKeySep", "inlineTableValSep", "integer", @@ -188,6 +191,7 @@ var rul3s = [...]string{ "Action22", "Action23", "Action24", + "Action25", } type token32 struct { @@ -304,7 +308,7 @@ type tomlParser struct { Buffer string buffer []rune - rules [86]func() bool + rules [88]func() bool parse func(rule ...int) error reset func() Pretty bool @@ -409,7 +413,7 @@ func (p *tomlParser) Execute() { case ruleAction5: p.SetKey(p.buffer, begin, end) case ruleAction6: - p.SetKey(p.buffer, begin-1, end+1) + p.SetKey(p.buffer, begin, end) case ruleAction7: p.SetTime(begin, end) case ruleAction8: @@ -431,21 +435,23 @@ func (p *tomlParser) Execute() { case ruleAction16: p.EndInlineTable() case ruleAction17: - p.SetBasicString(p.buffer, begin, end) + p.AddTableKey() case ruleAction18: - p.SetMultilineString() + p.SetBasicString(p.buffer, begin, end) case ruleAction19: - p.AddMultilineBasicBody(p.buffer, begin, end) + p.SetMultilineString() case ruleAction20: - p.SetLiteralString(p.buffer, begin, end) + p.AddMultilineBasicBody(p.buffer, begin, end) case ruleAction21: - p.SetMultilineLiteralString(p.buffer, begin, end) + p.SetLiteralString(p.buffer, begin, end) case ruleAction22: - p.StartArray() + p.SetMultilineLiteralString(p.buffer, begin, end) case ruleAction23: - p.AddArrayVal() + p.StartArray() case ruleAction24: p.AddArrayVal() + case ruleAction25: + p.AddArrayVal() } } @@ -1069,15 +1075,12 @@ func (p *tomlParser) Init() { position, tokenIndex = position72, tokenIndex72 { position81 := position - if buffer[position] != rune('"') { - goto l70 - } - position++ { position82 := position - if !_rules[rulebasicChar]() { + if buffer[position] != rune('"') { goto l70 } + position++ l83: { position84, tokenIndex84 := position, tokenIndex @@ -1088,12 +1091,12 @@ func (p *tomlParser) Init() { l84: position, tokenIndex = position84, tokenIndex84 } + if buffer[position] != rune('"') { + goto l70 + } + position++ add(rulePegText, position82) } - if buffer[position] != rune('"') { - goto l70 - } - position++ { add(ruleAction6, position) } @@ -1110,7 +1113,7 @@ func (p *tomlParser) Init() { }, /* 8 bareKey <- <(<((&('_') '_') | (&('-') '-') | (&('a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | 'j' | 'k' | 'l' | 'm' | 'n' | 'o' | 'p' | 'q' | 'r' | 's' | 't' | 'u' | 'v' | 'w' | 'x' | 'y' | 'z') [a-z]) | (&('0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9') [0-9]) | (&('A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J' | 'K' | 'L' | 'M' | 'N' | 'O' | 'P' | 'Q' | 'R' | 'S' | 'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z') [A-Z]))+> Action5)> */ nil, - /* 9 quotedKey <- <('"' '"' Action6)> */ + /* 9 quotedKey <- <(<('"' basicChar* '"')> Action6)> */ nil, /* 10 val <- <(( Action7) / ( Action8) / ((&('{') inlineTable) | (&('[') ( Action12)) | (&('f' | 't') ( Action11)) | (&('"' | '\'') ( Action10)) | (&('+' | '-' | '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9') ( Action9))))> */ func() bool { @@ -1177,49 +1180,56 @@ func (p *tomlParser) Init() { goto l101 } { - position104 := position + position104, tokenIndex104 := position, tokenIndex { - position105, tokenIndex105 := position, tokenIndex - if buffer[position] != rune('Z') { - goto l106 - } - position++ - goto l105 - l106: - position, tokenIndex = position105, tokenIndex105 + position106 := position { - position107 := position - { - position108, tokenIndex108 := position, tokenIndex - if buffer[position] != rune('-') { - goto l109 - } - position++ + position107, tokenIndex107 := position, tokenIndex + if buffer[position] != rune('Z') { goto l108 - l109: - position, tokenIndex = position108, tokenIndex108 - if buffer[position] != rune('+') { - goto l101 - } - position++ - } - l108: - if !_rules[ruletimeHour]() { - goto l101 - } - if buffer[position] != rune(':') { - goto l101 } position++ - if !_rules[ruletimeMinute]() { - goto l101 + goto l107 + l108: + position, tokenIndex = position107, tokenIndex107 + { + position109 := position + { + position110, tokenIndex110 := position, tokenIndex + if buffer[position] != rune('-') { + goto l111 + } + position++ + goto l110 + l111: + position, tokenIndex = position110, tokenIndex110 + if buffer[position] != rune('+') { + goto l104 + } + position++ + } + l110: + if !_rules[ruletimeHour]() { + goto l104 + } + if buffer[position] != rune(':') { + goto l104 + } + position++ + if !_rules[ruletimeMinute]() { + goto l104 + } + add(ruletimeNumoffset, position109) } - add(ruletimeNumoffset, position107) } + l107: + add(ruletimeOffset, position106) } - l105: - add(ruletimeOffset, position104) + goto l105 + l104: + position, tokenIndex = position104, tokenIndex104 } + l105: add(rulefullTime, position103) } goto l102 @@ -1246,33 +1256,20 @@ func (p *tomlParser) Init() { l91: position, tokenIndex = position90, tokenIndex90 { - position112 := position + position114 := position { - position113 := position + position115 := position if !_rules[ruleinteger]() { - goto l111 + goto l113 } { - position114, tokenIndex114 := position, tokenIndex + position116, tokenIndex116 := position, tokenIndex if !_rules[rulefrac]() { - goto l115 - } - { - position116, tokenIndex116 := position, tokenIndex - if !_rules[ruleexp]() { - goto l116 - } goto l117 - l116: - position, tokenIndex = position116, tokenIndex116 } - l117: - goto l114 - l115: - position, tokenIndex = position114, tokenIndex114 { position118, tokenIndex118 := position, tokenIndex - if !_rules[rulefrac]() { + if !_rules[ruleexp]() { goto l118 } goto l119 @@ -1280,26 +1277,39 @@ func (p *tomlParser) Init() { position, tokenIndex = position118, tokenIndex118 } l119: + goto l116 + l117: + position, tokenIndex = position116, tokenIndex116 + { + position120, tokenIndex120 := position, tokenIndex + if !_rules[rulefrac]() { + goto l120 + } + goto l121 + l120: + position, tokenIndex = position120, tokenIndex120 + } + l121: if !_rules[ruleexp]() { - goto l111 + goto l113 } } - l114: - add(rulefloat, position113) + l116: + add(rulefloat, position115) } - add(rulePegText, position112) + add(rulePegText, position114) } { add(ruleAction8, position) } goto l90 - l111: + l113: position, tokenIndex = position90, tokenIndex90 { switch buffer[position] { case '{': { - position122 := position + position124 := position if buffer[position] != rune('{') { goto l88 } @@ -1311,39 +1321,39 @@ func (p *tomlParser) Init() { goto l88 } { - position124 := position - l125: + position126 := position + l127: { - position126, tokenIndex126 := position, tokenIndex + position128, tokenIndex128 := position, tokenIndex if !_rules[rulekeyval]() { - goto l126 + goto l128 } { - position127, tokenIndex127 := position, tokenIndex + position129, tokenIndex129 := position, tokenIndex { - position129 := position + position131 := position if !_rules[rulews]() { - goto l127 + goto l129 } if buffer[position] != rune(',') { - goto l127 + goto l129 } position++ if !_rules[rulews]() { - goto l127 + goto l129 } - add(ruleinlineTableValSep, position129) + add(ruleinlineTableValSep, position131) } - goto l128 - l127: - position, tokenIndex = position127, tokenIndex127 + goto l130 + l129: + position, tokenIndex = position129, tokenIndex129 } + l130: + goto l127 l128: - goto l125 - l126: - position, tokenIndex = position126, tokenIndex126 + position, tokenIndex = position128, tokenIndex128 } - add(ruleinlineTableKeyValues, position124) + add(ruleinlineTableKeyValues, position126) } if !_rules[rulews]() { goto l88 @@ -1355,58 +1365,39 @@ func (p *tomlParser) Init() { { add(ruleAction16, position) } - add(ruleinlineTable, position122) + add(ruleinlineTable, position124) } break case '[': { - position131 := position + position133 := position { - position132 := position + position134 := position if buffer[position] != rune('[') { goto l88 } position++ { - add(ruleAction22, position) + add(ruleAction23, position) } if !_rules[rulewsnl]() { goto l88 } { - position134, tokenIndex134 := position, tokenIndex + position136, tokenIndex136 := position, tokenIndex { - position136 := position + position138 := position if !_rules[ruleval]() { - goto l134 + goto l136 } { - add(ruleAction23, position) + add(ruleAction24, position) } - l138: + l140: { - position139, tokenIndex139 := position, tokenIndex + position141, tokenIndex141 := position, tokenIndex if !_rules[rulewsnl]() { - goto l139 - } - { - position140, tokenIndex140 := position, tokenIndex - if !_rules[rulecomment]() { - goto l140 - } goto l141 - l140: - position, tokenIndex = position140, tokenIndex140 - } - l141: - if !_rules[rulewsnl]() { - goto l139 - } - if !_rules[rulearraySep]() { - goto l139 - } - if !_rules[rulewsnl]() { - goto l139 } { position142, tokenIndex142 := position, tokenIndex @@ -1419,37 +1410,43 @@ func (p *tomlParser) Init() { } l143: if !_rules[rulewsnl]() { - goto l139 + goto l141 } - if !_rules[ruleval]() { - goto l139 + if !_rules[rulearraySep]() { + goto l141 + } + if !_rules[rulewsnl]() { + goto l141 } { - add(ruleAction24, position) - } - goto l138 - l139: - position, tokenIndex = position139, tokenIndex139 - } - if !_rules[rulewsnl]() { - goto l134 - } - { - position145, tokenIndex145 := position, tokenIndex - if !_rules[rulearraySep]() { + position144, tokenIndex144 := position, tokenIndex + if !_rules[rulecomment]() { + goto l144 + } goto l145 + l144: + position, tokenIndex = position144, tokenIndex144 } - goto l146 l145: - position, tokenIndex = position145, tokenIndex145 + if !_rules[rulewsnl]() { + goto l141 + } + if !_rules[ruleval]() { + goto l141 + } + { + add(ruleAction25, position) + } + goto l140 + l141: + position, tokenIndex = position141, tokenIndex141 } - l146: if !_rules[rulewsnl]() { - goto l134 + goto l136 } { position147, tokenIndex147 := position, tokenIndex - if !_rules[rulecomment]() { + if !_rules[rulearraySep]() { goto l147 } goto l148 @@ -1457,13 +1454,26 @@ func (p *tomlParser) Init() { position, tokenIndex = position147, tokenIndex147 } l148: - add(rulearrayValues, position136) + if !_rules[rulewsnl]() { + goto l136 + } + { + position149, tokenIndex149 := position, tokenIndex + if !_rules[rulecomment]() { + goto l149 + } + goto l150 + l149: + position, tokenIndex = position149, tokenIndex149 + } + l150: + add(rulearrayValues, position138) } - goto l135 - l134: - position, tokenIndex = position134, tokenIndex134 + goto l137 + l136: + position, tokenIndex = position136, tokenIndex136 } - l135: + l137: if !_rules[rulewsnl]() { goto l88 } @@ -1471,9 +1481,9 @@ func (p *tomlParser) Init() { goto l88 } position++ - add(rulearray, position132) + add(rulearray, position134) } - add(rulePegText, position131) + add(rulePegText, position133) } { add(ruleAction12, position) @@ -1481,30 +1491,30 @@ func (p *tomlParser) Init() { break case 'f', 't': { - position150 := position + position152 := position { - position151 := position + position153 := position { - position152, tokenIndex152 := position, tokenIndex + position154, tokenIndex154 := position, tokenIndex if buffer[position] != rune('t') { - goto l153 + goto l155 } position++ if buffer[position] != rune('r') { - goto l153 + goto l155 } position++ if buffer[position] != rune('u') { - goto l153 + goto l155 } position++ if buffer[position] != rune('e') { - goto l153 + goto l155 } position++ - goto l152 - l153: - position, tokenIndex = position152, tokenIndex152 + goto l154 + l155: + position, tokenIndex = position154, tokenIndex154 if buffer[position] != rune('f') { goto l88 } @@ -1526,10 +1536,10 @@ func (p *tomlParser) Init() { } position++ } - l152: - add(ruleboolean, position151) + l154: + add(ruleboolean, position153) } - add(rulePegText, position150) + add(rulePegText, position152) } { add(ruleAction11, position) @@ -1537,278 +1547,278 @@ func (p *tomlParser) Init() { break case '"', '\'': { - position155 := position + position157 := position { - position156 := position + position158 := position { - position157, tokenIndex157 := position, tokenIndex + position159, tokenIndex159 := position, tokenIndex { - position159 := position + position161 := position if buffer[position] != rune('\'') { - goto l158 + goto l160 } position++ if buffer[position] != rune('\'') { - goto l158 + goto l160 } position++ if buffer[position] != rune('\'') { - goto l158 + goto l160 } position++ { - position160 := position + position162 := position { - position161 := position - l162: + position163 := position + l164: { - position163, tokenIndex163 := position, tokenIndex + position165, tokenIndex165 := position, tokenIndex { - position164, tokenIndex164 := position, tokenIndex + position166, tokenIndex166 := position, tokenIndex if buffer[position] != rune('\'') { - goto l164 + goto l166 } position++ if buffer[position] != rune('\'') { - goto l164 + goto l166 } position++ if buffer[position] != rune('\'') { - goto l164 + goto l166 } position++ - goto l163 - l164: - position, tokenIndex = position164, tokenIndex164 + goto l165 + l166: + position, tokenIndex = position166, tokenIndex166 } { - position165, tokenIndex165 := position, tokenIndex + position167, tokenIndex167 := position, tokenIndex { - position167 := position + position169 := position { - position168, tokenIndex168 := position, tokenIndex + position170, tokenIndex170 := position, tokenIndex if buffer[position] != rune('\t') { - goto l169 + goto l171 } position++ - goto l168 - l169: - position, tokenIndex = position168, tokenIndex168 + goto l170 + l171: + position, tokenIndex = position170, tokenIndex170 if c := buffer[position]; c < rune(' ') || c > rune('\U0010ffff') { - goto l166 + goto l168 } position++ } - l168: - add(rulemlLiteralChar, position167) + l170: + add(rulemlLiteralChar, position169) } - goto l165 - l166: - position, tokenIndex = position165, tokenIndex165 + goto l167 + l168: + position, tokenIndex = position167, tokenIndex167 if !_rules[rulenewline]() { - goto l163 + goto l165 } } + l167: + goto l164 l165: - goto l162 - l163: - position, tokenIndex = position163, tokenIndex163 + position, tokenIndex = position165, tokenIndex165 } - add(rulemlLiteralBody, position161) + add(rulemlLiteralBody, position163) } - add(rulePegText, position160) + add(rulePegText, position162) } if buffer[position] != rune('\'') { - goto l158 + goto l160 } position++ if buffer[position] != rune('\'') { - goto l158 + goto l160 } position++ if buffer[position] != rune('\'') { - goto l158 + goto l160 } position++ { - add(ruleAction21, position) + add(ruleAction22, position) } - add(rulemlLiteralString, position159) + add(rulemlLiteralString, position161) } - goto l157 - l158: - position, tokenIndex = position157, tokenIndex157 + goto l159 + l160: + position, tokenIndex = position159, tokenIndex159 { - position172 := position + position174 := position if buffer[position] != rune('\'') { - goto l171 + goto l173 } position++ { - position173 := position - l174: + position175 := position + l176: { - position175, tokenIndex175 := position, tokenIndex + position177, tokenIndex177 := position, tokenIndex { - position176 := position + position178 := position { switch buffer[position] { case '\t': if buffer[position] != rune('\t') { - goto l175 + goto l177 } position++ break case ' ', '!', '"', '#', '$', '%', '&': if c := buffer[position]; c < rune(' ') || c > rune('&') { - goto l175 + goto l177 } position++ break default: if c := buffer[position]; c < rune('(') || c > rune('\U0010ffff') { - goto l175 + goto l177 } position++ break } } - add(ruleliteralChar, position176) + add(ruleliteralChar, position178) } - goto l174 - l175: - position, tokenIndex = position175, tokenIndex175 + goto l176 + l177: + position, tokenIndex = position177, tokenIndex177 } - add(rulePegText, position173) + add(rulePegText, position175) } if buffer[position] != rune('\'') { - goto l171 + goto l173 } position++ { - add(ruleAction20, position) + add(ruleAction21, position) } - add(ruleliteralString, position172) + add(ruleliteralString, position174) } - goto l157 - l171: - position, tokenIndex = position157, tokenIndex157 + goto l159 + l173: + position, tokenIndex = position159, tokenIndex159 { - position180 := position + position182 := position if buffer[position] != rune('"') { - goto l179 + goto l181 } position++ if buffer[position] != rune('"') { - goto l179 + goto l181 } position++ if buffer[position] != rune('"') { - goto l179 + goto l181 } position++ { - position181 := position - l182: + position183 := position + l184: { - position183, tokenIndex183 := position, tokenIndex + position185, tokenIndex185 := position, tokenIndex { - position184, tokenIndex184 := position, tokenIndex + position186, tokenIndex186 := position, tokenIndex { - position186 := position + position188 := position { - position187, tokenIndex187 := position, tokenIndex + position189, tokenIndex189 := position, tokenIndex if !_rules[rulebasicChar]() { - goto l188 + goto l190 } - goto l187 - l188: - position, tokenIndex = position187, tokenIndex187 + goto l189 + l190: + position, tokenIndex = position189, tokenIndex189 if !_rules[rulenewline]() { - goto l185 + goto l187 } } - l187: - add(rulePegText, position186) + l189: + add(rulePegText, position188) } { - add(ruleAction19, position) + add(ruleAction20, position) } - goto l184 - l185: - position, tokenIndex = position184, tokenIndex184 + goto l186 + l187: + position, tokenIndex = position186, tokenIndex186 if !_rules[ruleescape]() { - goto l183 + goto l185 } if !_rules[rulenewline]() { - goto l183 + goto l185 } if !_rules[rulewsnl]() { - goto l183 + goto l185 } } - l184: - goto l182 - l183: - position, tokenIndex = position183, tokenIndex183 + l186: + goto l184 + l185: + position, tokenIndex = position185, tokenIndex185 } - add(rulemlBasicBody, position181) + add(rulemlBasicBody, position183) } if buffer[position] != rune('"') { - goto l179 + goto l181 } position++ if buffer[position] != rune('"') { - goto l179 + goto l181 } position++ if buffer[position] != rune('"') { - goto l179 + goto l181 } position++ + { + add(ruleAction19, position) + } + add(rulemlBasicString, position182) + } + goto l159 + l181: + position, tokenIndex = position159, tokenIndex159 + { + position193 := position + { + position194 := position + if buffer[position] != rune('"') { + goto l88 + } + position++ + l195: + { + position196, tokenIndex196 := position, tokenIndex + if !_rules[rulebasicChar]() { + goto l196 + } + goto l195 + l196: + position, tokenIndex = position196, tokenIndex196 + } + if buffer[position] != rune('"') { + goto l88 + } + position++ + add(rulePegText, position194) + } { add(ruleAction18, position) } - add(rulemlBasicString, position180) - } - goto l157 - l179: - position, tokenIndex = position157, tokenIndex157 - { - position191 := position - { - position192 := position - if buffer[position] != rune('"') { - goto l88 - } - position++ - l193: - { - position194, tokenIndex194 := position, tokenIndex - if !_rules[rulebasicChar]() { - goto l194 - } - goto l193 - l194: - position, tokenIndex = position194, tokenIndex194 - } - if buffer[position] != rune('"') { - goto l88 - } - position++ - add(rulePegText, position192) - } - { - add(ruleAction17, position) - } - add(rulebasicString, position191) + add(rulebasicString, position193) } } - l157: - add(rulestring, position156) + l159: + add(rulestring, position158) } - add(rulePegText, position155) + add(rulePegText, position157) } { add(ruleAction10, position) @@ -1816,11 +1826,11 @@ func (p *tomlParser) Init() { break default: { - position197 := position + position199 := position if !_rules[ruleinteger]() { goto l88 } - add(rulePegText, position197) + add(rulePegText, position199) } { add(ruleAction9, position) @@ -1848,708 +1858,728 @@ func (p *tomlParser) Init() { nil, /* 15 inlineTableKeyValues <- <(keyval inlineTableValSep?)*> */ nil, - /* 16 tableKey <- <(key (tableKeySep key)*)> */ + /* 16 tableKey <- <(tableKeyComp (tableKeySep tableKeyComp)*)> */ func() bool { - position204, tokenIndex204 := position, tokenIndex + position206, tokenIndex206 := position, tokenIndex { - position205 := position - if !_rules[rulekey]() { - goto l204 + position207 := position + if !_rules[ruletableKeyComp]() { + goto l206 } - l206: + l208: { - position207, tokenIndex207 := position, tokenIndex + position209, tokenIndex209 := position, tokenIndex { - position208 := position + position210 := position if !_rules[rulews]() { - goto l207 + goto l209 } if buffer[position] != rune('.') { - goto l207 + goto l209 } position++ if !_rules[rulews]() { - goto l207 + goto l209 } - add(ruletableKeySep, position208) + add(ruletableKeySep, position210) } - if !_rules[rulekey]() { - goto l207 + if !_rules[ruletableKeyComp]() { + goto l209 } - goto l206 - l207: - position, tokenIndex = position207, tokenIndex207 + goto l208 + l209: + position, tokenIndex = position209, tokenIndex209 } - add(ruletableKey, position205) + add(ruletableKey, position207) } return true - l204: - position, tokenIndex = position204, tokenIndex204 + l206: + position, tokenIndex = position206, tokenIndex206 return false }, - /* 17 tableKeySep <- <(ws '.' ws)> */ - nil, - /* 18 inlineTableValSep <- <(ws ',' ws)> */ - nil, - /* 19 integer <- <(('-' / '+')? int)> */ + /* 17 tableKeyComp <- <(key Action17)> */ func() bool { position211, tokenIndex211 := position, tokenIndex { position212 := position - { - position213, tokenIndex213 := position, tokenIndex - { - position215, tokenIndex215 := position, tokenIndex - if buffer[position] != rune('-') { - goto l216 - } - position++ - goto l215 - l216: - position, tokenIndex = position215, tokenIndex215 - if buffer[position] != rune('+') { - goto l213 - } - position++ - } - l215: - goto l214 - l213: - position, tokenIndex = position213, tokenIndex213 + if !_rules[rulekey]() { + goto l211 } - l214: { - position217 := position - { - position218, tokenIndex218 := position, tokenIndex - if c := buffer[position]; c < rune('1') || c > rune('9') { - goto l219 - } - position++ - { - position222, tokenIndex222 := position, tokenIndex - if !_rules[ruledigit]() { - goto l223 - } - goto l222 - l223: - position, tokenIndex = position222, tokenIndex222 - if buffer[position] != rune('_') { - goto l219 - } - position++ - if !_rules[ruledigit]() { - goto l219 - } - } - l222: - l220: - { - position221, tokenIndex221 := position, tokenIndex - { - position224, tokenIndex224 := position, tokenIndex - if !_rules[ruledigit]() { - goto l225 - } - goto l224 - l225: - position, tokenIndex = position224, tokenIndex224 - if buffer[position] != rune('_') { - goto l221 - } - position++ - if !_rules[ruledigit]() { - goto l221 - } - } - l224: - goto l220 - l221: - position, tokenIndex = position221, tokenIndex221 - } - goto l218 - l219: - position, tokenIndex = position218, tokenIndex218 - if !_rules[ruledigit]() { - goto l211 - } - } - l218: - add(ruleint, position217) + add(ruleAction17, position) } - add(ruleinteger, position212) + add(ruletableKeyComp, position212) } return true l211: position, tokenIndex = position211, tokenIndex211 return false }, - /* 20 int <- <(([1-9] (digit / ('_' digit))+) / digit)> */ + /* 18 tableKeySep <- <(ws '.' ws)> */ nil, - /* 21 float <- <(integer ((frac exp?) / (frac? exp)))> */ + /* 19 inlineTableValSep <- <(ws ',' ws)> */ nil, - /* 22 frac <- <('.' digit (digit / ('_' digit))*)> */ + /* 20 integer <- <(('-' / '+')? int)> */ func() bool { - position228, tokenIndex228 := position, tokenIndex + position216, tokenIndex216 := position, tokenIndex { - position229 := position + position217 := position + { + position218, tokenIndex218 := position, tokenIndex + { + position220, tokenIndex220 := position, tokenIndex + if buffer[position] != rune('-') { + goto l221 + } + position++ + goto l220 + l221: + position, tokenIndex = position220, tokenIndex220 + if buffer[position] != rune('+') { + goto l218 + } + position++ + } + l220: + goto l219 + l218: + position, tokenIndex = position218, tokenIndex218 + } + l219: + { + position222 := position + { + position223, tokenIndex223 := position, tokenIndex + if c := buffer[position]; c < rune('1') || c > rune('9') { + goto l224 + } + position++ + { + position227, tokenIndex227 := position, tokenIndex + if !_rules[ruledigit]() { + goto l228 + } + goto l227 + l228: + position, tokenIndex = position227, tokenIndex227 + if buffer[position] != rune('_') { + goto l224 + } + position++ + if !_rules[ruledigit]() { + goto l224 + } + } + l227: + l225: + { + position226, tokenIndex226 := position, tokenIndex + { + position229, tokenIndex229 := position, tokenIndex + if !_rules[ruledigit]() { + goto l230 + } + goto l229 + l230: + position, tokenIndex = position229, tokenIndex229 + if buffer[position] != rune('_') { + goto l226 + } + position++ + if !_rules[ruledigit]() { + goto l226 + } + } + l229: + goto l225 + l226: + position, tokenIndex = position226, tokenIndex226 + } + goto l223 + l224: + position, tokenIndex = position223, tokenIndex223 + if !_rules[ruledigit]() { + goto l216 + } + } + l223: + add(ruleint, position222) + } + add(ruleinteger, position217) + } + return true + l216: + position, tokenIndex = position216, tokenIndex216 + return false + }, + /* 21 int <- <(([1-9] (digit / ('_' digit))+) / digit)> */ + nil, + /* 22 float <- <(integer ((frac exp?) / (frac? exp)))> */ + nil, + /* 23 frac <- <('.' digit (digit / ('_' digit))*)> */ + func() bool { + position233, tokenIndex233 := position, tokenIndex + { + position234 := position if buffer[position] != rune('.') { - goto l228 + goto l233 } position++ if !_rules[ruledigit]() { - goto l228 + goto l233 } - l230: - { - position231, tokenIndex231 := position, tokenIndex - { - position232, tokenIndex232 := position, tokenIndex - if !_rules[ruledigit]() { - goto l233 - } - goto l232 - l233: - position, tokenIndex = position232, tokenIndex232 - if buffer[position] != rune('_') { - goto l231 - } - position++ - if !_rules[ruledigit]() { - goto l231 - } - } - l232: - goto l230 - l231: - position, tokenIndex = position231, tokenIndex231 - } - add(rulefrac, position229) - } - return true - l228: - position, tokenIndex = position228, tokenIndex228 - return false - }, - /* 23 exp <- <(('e' / 'E') ('-' / '+')? digit (digit / ('_' digit))*)> */ - func() bool { - position234, tokenIndex234 := position, tokenIndex - { - position235 := position + l235: { position236, tokenIndex236 := position, tokenIndex - if buffer[position] != rune('e') { - goto l237 - } - position++ - goto l236 - l237: - position, tokenIndex = position236, tokenIndex236 - if buffer[position] != rune('E') { - goto l234 - } - position++ - } - l236: - { - position238, tokenIndex238 := position, tokenIndex { - position240, tokenIndex240 := position, tokenIndex - if buffer[position] != rune('-') { - goto l241 - } - position++ - goto l240 - l241: - position, tokenIndex = position240, tokenIndex240 - if buffer[position] != rune('+') { + position237, tokenIndex237 := position, tokenIndex + if !_rules[ruledigit]() { goto l238 } + goto l237 + l238: + position, tokenIndex = position237, tokenIndex237 + if buffer[position] != rune('_') { + goto l236 + } position++ + if !_rules[ruledigit]() { + goto l236 + } } - l240: - goto l239 - l238: - position, tokenIndex = position238, tokenIndex238 + l237: + goto l235 + l236: + position, tokenIndex = position236, tokenIndex236 } - l239: - if !_rules[ruledigit]() { - goto l234 + add(rulefrac, position234) + } + return true + l233: + position, tokenIndex = position233, tokenIndex233 + return false + }, + /* 24 exp <- <(('e' / 'E') ('-' / '+')? digit (digit / ('_' digit))*)> */ + func() bool { + position239, tokenIndex239 := position, tokenIndex + { + position240 := position + { + position241, tokenIndex241 := position, tokenIndex + if buffer[position] != rune('e') { + goto l242 + } + position++ + goto l241 + l242: + position, tokenIndex = position241, tokenIndex241 + if buffer[position] != rune('E') { + goto l239 + } + position++ } - l242: + l241: { position243, tokenIndex243 := position, tokenIndex { - position244, tokenIndex244 := position, tokenIndex - if !_rules[ruledigit]() { - goto l245 + position245, tokenIndex245 := position, tokenIndex + if buffer[position] != rune('-') { + goto l246 } - goto l244 - l245: - position, tokenIndex = position244, tokenIndex244 - if buffer[position] != rune('_') { + position++ + goto l245 + l246: + position, tokenIndex = position245, tokenIndex245 + if buffer[position] != rune('+') { goto l243 } position++ - if !_rules[ruledigit]() { - goto l243 - } } - l244: - goto l242 + l245: + goto l244 l243: position, tokenIndex = position243, tokenIndex243 } - add(ruleexp, position235) + l244: + if !_rules[ruledigit]() { + goto l239 + } + l247: + { + position248, tokenIndex248 := position, tokenIndex + { + position249, tokenIndex249 := position, tokenIndex + if !_rules[ruledigit]() { + goto l250 + } + goto l249 + l250: + position, tokenIndex = position249, tokenIndex249 + if buffer[position] != rune('_') { + goto l248 + } + position++ + if !_rules[ruledigit]() { + goto l248 + } + } + l249: + goto l247 + l248: + position, tokenIndex = position248, tokenIndex248 + } + add(ruleexp, position240) } return true - l234: - position, tokenIndex = position234, tokenIndex234 + l239: + position, tokenIndex = position239, tokenIndex239 return false }, - /* 24 string <- <(mlLiteralString / literalString / mlBasicString / basicString)> */ + /* 25 string <- <(mlLiteralString / literalString / mlBasicString / basicString)> */ nil, - /* 25 basicString <- <(<('"' basicChar* '"')> Action17)> */ + /* 26 basicString <- <(<('"' basicChar* '"')> Action18)> */ nil, - /* 26 basicChar <- <(basicUnescaped / escaped)> */ + /* 27 basicChar <- <(basicUnescaped / escaped)> */ func() bool { - position248, tokenIndex248 := position, tokenIndex + position253, tokenIndex253 := position, tokenIndex { - position249 := position + position254 := position { - position250, tokenIndex250 := position, tokenIndex + position255, tokenIndex255 := position, tokenIndex { - position252 := position + position257 := position { switch buffer[position] { case ' ', '!': if c := buffer[position]; c < rune(' ') || c > rune('!') { - goto l251 + goto l256 } position++ break case '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?', '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[': if c := buffer[position]; c < rune('#') || c > rune('[') { - goto l251 + goto l256 } position++ break default: if c := buffer[position]; c < rune(']') || c > rune('\U0010ffff') { - goto l251 + goto l256 } position++ break } } - add(rulebasicUnescaped, position252) + add(rulebasicUnescaped, position257) } - goto l250 - l251: - position, tokenIndex = position250, tokenIndex250 + goto l255 + l256: + position, tokenIndex = position255, tokenIndex255 { - position254 := position + position259 := position if !_rules[ruleescape]() { - goto l248 + goto l253 } { switch buffer[position] { case 'U': if buffer[position] != rune('U') { - goto l248 + goto l253 } position++ if !_rules[rulehexQuad]() { - goto l248 + goto l253 } if !_rules[rulehexQuad]() { - goto l248 + goto l253 } break case 'u': if buffer[position] != rune('u') { - goto l248 + goto l253 } position++ if !_rules[rulehexQuad]() { - goto l248 + goto l253 } break case '\\': if buffer[position] != rune('\\') { - goto l248 + goto l253 } position++ break case '/': if buffer[position] != rune('/') { - goto l248 + goto l253 } position++ break case '"': if buffer[position] != rune('"') { - goto l248 + goto l253 } position++ break case 'r': if buffer[position] != rune('r') { - goto l248 + goto l253 } position++ break case 'f': if buffer[position] != rune('f') { - goto l248 + goto l253 } position++ break case 'n': if buffer[position] != rune('n') { - goto l248 + goto l253 } position++ break case 't': if buffer[position] != rune('t') { - goto l248 + goto l253 } position++ break default: if buffer[position] != rune('b') { - goto l248 + goto l253 } position++ break } } - add(ruleescaped, position254) + add(ruleescaped, position259) } } - l250: - add(rulebasicChar, position249) + l255: + add(rulebasicChar, position254) } return true - l248: - position, tokenIndex = position248, tokenIndex248 + l253: + position, tokenIndex = position253, tokenIndex253 return false }, - /* 27 escaped <- <(escape ((&('U') ('U' hexQuad hexQuad)) | (&('u') ('u' hexQuad)) | (&('\\') '\\') | (&('/') '/') | (&('"') '"') | (&('r') 'r') | (&('f') 'f') | (&('n') 'n') | (&('t') 't') | (&('b') 'b')))> */ + /* 28 escaped <- <(escape ((&('U') ('U' hexQuad hexQuad)) | (&('u') ('u' hexQuad)) | (&('\\') '\\') | (&('/') '/') | (&('"') '"') | (&('r') 'r') | (&('f') 'f') | (&('n') 'n') | (&('t') 't') | (&('b') 'b')))> */ nil, - /* 28 basicUnescaped <- <((&(' ' | '!') [ -!]) | (&('#' | '$' | '%' | '&' | '\'' | '(' | ')' | '*' | '+' | ',' | '-' | '.' | '/' | '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | ':' | ';' | '<' | '=' | '>' | '?' | '@' | 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J' | 'K' | 'L' | 'M' | 'N' | 'O' | 'P' | 'Q' | 'R' | 'S' | 'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z' | '[') [#-[]) | (&(']' | '^' | '_' | '`' | 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | 'j' | 'k' | 'l' | 'm' | 'n' | 'o' | 'p' | 'q' | 'r' | 's' | 't' | 'u' | 'v' | 'w' | 'x' | 'y' | 'z' | '{' | '|' | '}' | '~' | '\u007f' | '\u0080' | '\u0081' | '\u0082' | '\u0083' | '\u0084' | '\u0085' | '\u0086' | '\u0087' | '\u0088' | '\u0089' | '\u008a' | '\u008b' | '\u008c' | '\u008d' | '\u008e' | '\u008f' | '\u0090' | '\u0091' | '\u0092' | '\u0093' | '\u0094' | '\u0095' | '\u0096' | '\u0097' | '\u0098' | '\u0099' | '\u009a' | '\u009b' | '\u009c' | '\u009d' | '\u009e' | '\u009f' | '\u00a0' | '¡' | '¢' | '£' | '¤' | '¥' | '¦' | '§' | '¨' | '©' | 'ª' | '«' | '¬' | '\u00ad' | '®' | '¯' | '°' | '±' | '²' | '³' | '´' | 'µ' | '¶' | '·' | '¸' | '¹' | 'º' | '»' | '¼' | '½' | '¾' | '¿' | 'À' | 'Á' | 'Â' | 'Ã' | 'Ä' | 'Å' | 'Æ' | 'Ç' | 'È' | 'É' | 'Ê' | 'Ë' | 'Ì' | 'Í' | 'Î' | 'Ï' | 'Ð' | 'Ñ' | 'Ò' | 'Ó' | 'Ô' | 'Õ' | 'Ö' | '×' | 'Ø' | 'Ù' | 'Ú' | 'Û' | 'Ü' | 'Ý' | 'Þ' | 'ß' | 'à' | 'á' | 'â' | 'ã' | 'ä' | 'å' | 'æ' | 'ç' | 'è' | 'é' | 'ê' | 'ë' | 'ì' | 'í' | 'î' | 'ï' | 'ð' | 'ñ' | 'ò' | 'ó' | 'ô' | 'õ' | 'ö' | '÷' | 'ø' | 'ù' | 'ú' | 'û' | 'ü' | 'ý' | 'þ' | 'ÿ') []-\U0010ffff]))> */ + /* 29 basicUnescaped <- <((&(' ' | '!') [ -!]) | (&('#' | '$' | '%' | '&' | '\'' | '(' | ')' | '*' | '+' | ',' | '-' | '.' | '/' | '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | ':' | ';' | '<' | '=' | '>' | '?' | '@' | 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J' | 'K' | 'L' | 'M' | 'N' | 'O' | 'P' | 'Q' | 'R' | 'S' | 'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z' | '[') [#-[]) | (&(']' | '^' | '_' | '`' | 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | 'j' | 'k' | 'l' | 'm' | 'n' | 'o' | 'p' | 'q' | 'r' | 's' | 't' | 'u' | 'v' | 'w' | 'x' | 'y' | 'z' | '{' | '|' | '}' | '~' | '\u007f' | '\u0080' | '\u0081' | '\u0082' | '\u0083' | '\u0084' | '\u0085' | '\u0086' | '\u0087' | '\u0088' | '\u0089' | '\u008a' | '\u008b' | '\u008c' | '\u008d' | '\u008e' | '\u008f' | '\u0090' | '\u0091' | '\u0092' | '\u0093' | '\u0094' | '\u0095' | '\u0096' | '\u0097' | '\u0098' | '\u0099' | '\u009a' | '\u009b' | '\u009c' | '\u009d' | '\u009e' | '\u009f' | '\u00a0' | '¡' | '¢' | '£' | '¤' | '¥' | '¦' | '§' | '¨' | '©' | 'ª' | '«' | '¬' | '\u00ad' | '®' | '¯' | '°' | '±' | '²' | '³' | '´' | 'µ' | '¶' | '·' | '¸' | '¹' | 'º' | '»' | '¼' | '½' | '¾' | '¿' | 'À' | 'Á' | 'Â' | 'Ã' | 'Ä' | 'Å' | 'Æ' | 'Ç' | 'È' | 'É' | 'Ê' | 'Ë' | 'Ì' | 'Í' | 'Î' | 'Ï' | 'Ð' | 'Ñ' | 'Ò' | 'Ó' | 'Ô' | 'Õ' | 'Ö' | '×' | 'Ø' | 'Ù' | 'Ú' | 'Û' | 'Ü' | 'Ý' | 'Þ' | 'ß' | 'à' | 'á' | 'â' | 'ã' | 'ä' | 'å' | 'æ' | 'ç' | 'è' | 'é' | 'ê' | 'ë' | 'ì' | 'í' | 'î' | 'ï' | 'ð' | 'ñ' | 'ò' | 'ó' | 'ô' | 'õ' | 'ö' | '÷' | 'ø' | 'ù' | 'ú' | 'û' | 'ü' | 'ý' | 'þ' | 'ÿ') []-\U0010ffff]))> */ nil, - /* 29 escape <- <'\\'> */ + /* 30 escape <- <'\\'> */ func() bool { - position258, tokenIndex258 := position, tokenIndex + position263, tokenIndex263 := position, tokenIndex { - position259 := position + position264 := position if buffer[position] != rune('\\') { - goto l258 + goto l263 } position++ - add(ruleescape, position259) + add(ruleescape, position264) } return true - l258: - position, tokenIndex = position258, tokenIndex258 + l263: + position, tokenIndex = position263, tokenIndex263 return false }, - /* 30 mlBasicString <- <('"' '"' '"' mlBasicBody ('"' '"' '"') Action18)> */ + /* 31 mlBasicString <- <('"' '"' '"' mlBasicBody ('"' '"' '"') Action19)> */ nil, - /* 31 mlBasicBody <- <((<(basicChar / newline)> Action19) / (escape newline wsnl))*> */ + /* 32 mlBasicBody <- <((<(basicChar / newline)> Action20) / (escape newline wsnl))*> */ nil, - /* 32 literalString <- <('\'' '\'' Action20)> */ + /* 33 literalString <- <('\'' '\'' Action21)> */ nil, - /* 33 literalChar <- <((&('\t') '\t') | (&(' ' | '!' | '"' | '#' | '$' | '%' | '&') [ -&]) | (&('(' | ')' | '*' | '+' | ',' | '-' | '.' | '/' | '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | ':' | ';' | '<' | '=' | '>' | '?' | '@' | 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J' | 'K' | 'L' | 'M' | 'N' | 'O' | 'P' | 'Q' | 'R' | 'S' | 'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z' | '[' | '\\' | ']' | '^' | '_' | '`' | 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | 'j' | 'k' | 'l' | 'm' | 'n' | 'o' | 'p' | 'q' | 'r' | 's' | 't' | 'u' | 'v' | 'w' | 'x' | 'y' | 'z' | '{' | '|' | '}' | '~' | '\u007f' | '\u0080' | '\u0081' | '\u0082' | '\u0083' | '\u0084' | '\u0085' | '\u0086' | '\u0087' | '\u0088' | '\u0089' | '\u008a' | '\u008b' | '\u008c' | '\u008d' | '\u008e' | '\u008f' | '\u0090' | '\u0091' | '\u0092' | '\u0093' | '\u0094' | '\u0095' | '\u0096' | '\u0097' | '\u0098' | '\u0099' | '\u009a' | '\u009b' | '\u009c' | '\u009d' | '\u009e' | '\u009f' | '\u00a0' | '¡' | '¢' | '£' | '¤' | '¥' | '¦' | '§' | '¨' | '©' | 'ª' | '«' | '¬' | '\u00ad' | '®' | '¯' | '°' | '±' | '²' | '³' | '´' | 'µ' | '¶' | '·' | '¸' | '¹' | 'º' | '»' | '¼' | '½' | '¾' | '¿' | 'À' | 'Á' | 'Â' | 'Ã' | 'Ä' | 'Å' | 'Æ' | 'Ç' | 'È' | 'É' | 'Ê' | 'Ë' | 'Ì' | 'Í' | 'Î' | 'Ï' | 'Ð' | 'Ñ' | 'Ò' | 'Ó' | 'Ô' | 'Õ' | 'Ö' | '×' | 'Ø' | 'Ù' | 'Ú' | 'Û' | 'Ü' | 'Ý' | 'Þ' | 'ß' | 'à' | 'á' | 'â' | 'ã' | 'ä' | 'å' | 'æ' | 'ç' | 'è' | 'é' | 'ê' | 'ë' | 'ì' | 'í' | 'î' | 'ï' | 'ð' | 'ñ' | 'ò' | 'ó' | 'ô' | 'õ' | 'ö' | '÷' | 'ø' | 'ù' | 'ú' | 'û' | 'ü' | 'ý' | 'þ' | 'ÿ') [(-\U0010ffff]))> */ + /* 34 literalChar <- <((&('\t') '\t') | (&(' ' | '!' | '"' | '#' | '$' | '%' | '&') [ -&]) | (&('(' | ')' | '*' | '+' | ',' | '-' | '.' | '/' | '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | ':' | ';' | '<' | '=' | '>' | '?' | '@' | 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J' | 'K' | 'L' | 'M' | 'N' | 'O' | 'P' | 'Q' | 'R' | 'S' | 'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z' | '[' | '\\' | ']' | '^' | '_' | '`' | 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | 'j' | 'k' | 'l' | 'm' | 'n' | 'o' | 'p' | 'q' | 'r' | 's' | 't' | 'u' | 'v' | 'w' | 'x' | 'y' | 'z' | '{' | '|' | '}' | '~' | '\u007f' | '\u0080' | '\u0081' | '\u0082' | '\u0083' | '\u0084' | '\u0085' | '\u0086' | '\u0087' | '\u0088' | '\u0089' | '\u008a' | '\u008b' | '\u008c' | '\u008d' | '\u008e' | '\u008f' | '\u0090' | '\u0091' | '\u0092' | '\u0093' | '\u0094' | '\u0095' | '\u0096' | '\u0097' | '\u0098' | '\u0099' | '\u009a' | '\u009b' | '\u009c' | '\u009d' | '\u009e' | '\u009f' | '\u00a0' | '¡' | '¢' | '£' | '¤' | '¥' | '¦' | '§' | '¨' | '©' | 'ª' | '«' | '¬' | '\u00ad' | '®' | '¯' | '°' | '±' | '²' | '³' | '´' | 'µ' | '¶' | '·' | '¸' | '¹' | 'º' | '»' | '¼' | '½' | '¾' | '¿' | 'À' | 'Á' | 'Â' | 'Ã' | 'Ä' | 'Å' | 'Æ' | 'Ç' | 'È' | 'É' | 'Ê' | 'Ë' | 'Ì' | 'Í' | 'Î' | 'Ï' | 'Ð' | 'Ñ' | 'Ò' | 'Ó' | 'Ô' | 'Õ' | 'Ö' | '×' | 'Ø' | 'Ù' | 'Ú' | 'Û' | 'Ü' | 'Ý' | 'Þ' | 'ß' | 'à' | 'á' | 'â' | 'ã' | 'ä' | 'å' | 'æ' | 'ç' | 'è' | 'é' | 'ê' | 'ë' | 'ì' | 'í' | 'î' | 'ï' | 'ð' | 'ñ' | 'ò' | 'ó' | 'ô' | 'õ' | 'ö' | '÷' | 'ø' | 'ù' | 'ú' | 'û' | 'ü' | 'ý' | 'þ' | 'ÿ') [(-\U0010ffff]))> */ nil, - /* 34 mlLiteralString <- <('\'' '\'' '\'' ('\'' '\'' '\'') Action21)> */ + /* 35 mlLiteralString <- <('\'' '\'' '\'' ('\'' '\'' '\'') Action22)> */ nil, - /* 35 mlLiteralBody <- <(!('\'' '\'' '\'') (mlLiteralChar / newline))*> */ + /* 36 mlLiteralBody <- <(!('\'' '\'' '\'') (mlLiteralChar / newline))*> */ nil, - /* 36 mlLiteralChar <- <('\t' / [ -\U0010ffff])> */ + /* 37 mlLiteralChar <- <('\t' / [ -\U0010ffff])> */ nil, - /* 37 hexdigit <- <((&('a' | 'b' | 'c' | 'd' | 'e' | 'f') [a-f]) | (&('A' | 'B' | 'C' | 'D' | 'E' | 'F') [A-F]) | (&('0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9') [0-9]))> */ + /* 38 hexdigit <- <((&('a' | 'b' | 'c' | 'd' | 'e' | 'f') [a-f]) | (&('A' | 'B' | 'C' | 'D' | 'E' | 'F') [A-F]) | (&('0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9') [0-9]))> */ func() bool { - position267, tokenIndex267 := position, tokenIndex + position272, tokenIndex272 := position, tokenIndex { - position268 := position + position273 := position { switch buffer[position] { case 'a', 'b', 'c', 'd', 'e', 'f': if c := buffer[position]; c < rune('a') || c > rune('f') { - goto l267 + goto l272 } position++ break case 'A', 'B', 'C', 'D', 'E', 'F': if c := buffer[position]; c < rune('A') || c > rune('F') { - goto l267 + goto l272 } position++ break default: if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l267 + goto l272 } position++ break } } - add(rulehexdigit, position268) + add(rulehexdigit, position273) } return true - l267: - position, tokenIndex = position267, tokenIndex267 + l272: + position, tokenIndex = position272, tokenIndex272 return false }, - /* 38 hexQuad <- <(hexdigit hexdigit hexdigit hexdigit)> */ + /* 39 hexQuad <- <(hexdigit hexdigit hexdigit hexdigit)> */ func() bool { - position270, tokenIndex270 := position, tokenIndex + position275, tokenIndex275 := position, tokenIndex { - position271 := position + position276 := position if !_rules[rulehexdigit]() { - goto l270 + goto l275 } if !_rules[rulehexdigit]() { - goto l270 + goto l275 } if !_rules[rulehexdigit]() { - goto l270 + goto l275 } if !_rules[rulehexdigit]() { - goto l270 + goto l275 } - add(rulehexQuad, position271) + add(rulehexQuad, position276) } return true - l270: - position, tokenIndex = position270, tokenIndex270 + l275: + position, tokenIndex = position275, tokenIndex275 return false }, - /* 39 boolean <- <(('t' 'r' 'u' 'e') / ('f' 'a' 'l' 's' 'e'))> */ + /* 40 boolean <- <(('t' 'r' 'u' 'e') / ('f' 'a' 'l' 's' 'e'))> */ nil, - /* 40 dateFullYear <- */ + /* 41 dateFullYear <- */ nil, - /* 41 dateMonth <- */ + /* 42 dateMonth <- */ nil, - /* 42 dateMDay <- */ + /* 43 dateMDay <- */ nil, - /* 43 timeHour <- */ + /* 44 timeHour <- */ func() bool { - position276, tokenIndex276 := position, tokenIndex + position281, tokenIndex281 := position, tokenIndex { - position277 := position + position282 := position if !_rules[ruledigitDual]() { - goto l276 + goto l281 } - add(ruletimeHour, position277) + add(ruletimeHour, position282) } return true - l276: - position, tokenIndex = position276, tokenIndex276 + l281: + position, tokenIndex = position281, tokenIndex281 return false }, - /* 44 timeMinute <- */ + /* 45 timeMinute <- */ func() bool { - position278, tokenIndex278 := position, tokenIndex + position283, tokenIndex283 := position, tokenIndex { - position279 := position + position284 := position if !_rules[ruledigitDual]() { - goto l278 + goto l283 } - add(ruletimeMinute, position279) + add(ruletimeMinute, position284) } return true - l278: - position, tokenIndex = position278, tokenIndex278 + l283: + position, tokenIndex = position283, tokenIndex283 return false }, - /* 45 timeSecond <- */ + /* 46 timeSecond <- */ nil, - /* 46 timeSecfrac <- <('.' digit+)> */ + /* 47 timeSecfrac <- <('.' digit+)> */ nil, - /* 47 timeNumoffset <- <(('-' / '+') timeHour ':' timeMinute)> */ + /* 48 timeNumoffset <- <(('-' / '+') timeHour ':' timeMinute)> */ nil, - /* 48 timeOffset <- <('Z' / timeNumoffset)> */ + /* 49 timeOffset <- <('Z' / timeNumoffset)> */ nil, - /* 49 partialTime <- <(timeHour ':' timeMinute ':' timeSecond timeSecfrac?)> */ + /* 50 partialTime <- <(timeHour ':' timeMinute ':' timeSecond timeSecfrac?)> */ func() bool { - position284, tokenIndex284 := position, tokenIndex + position289, tokenIndex289 := position, tokenIndex { - position285 := position + position290 := position if !_rules[ruletimeHour]() { - goto l284 + goto l289 } if buffer[position] != rune(':') { - goto l284 + goto l289 } position++ if !_rules[ruletimeMinute]() { - goto l284 + goto l289 } if buffer[position] != rune(':') { - goto l284 + goto l289 } position++ { - position286 := position + position291 := position if !_rules[ruledigitDual]() { - goto l284 + goto l289 } - add(ruletimeSecond, position286) + add(ruletimeSecond, position291) } { - position287, tokenIndex287 := position, tokenIndex + position292, tokenIndex292 := position, tokenIndex { - position289 := position + position294 := position if buffer[position] != rune('.') { - goto l287 + goto l292 } position++ if !_rules[ruledigit]() { - goto l287 + goto l292 } - l290: + l295: { - position291, tokenIndex291 := position, tokenIndex + position296, tokenIndex296 := position, tokenIndex if !_rules[ruledigit]() { - goto l291 + goto l296 } - goto l290 - l291: - position, tokenIndex = position291, tokenIndex291 + goto l295 + l296: + position, tokenIndex = position296, tokenIndex296 } - add(ruletimeSecfrac, position289) + add(ruletimeSecfrac, position294) } - goto l288 - l287: - position, tokenIndex = position287, tokenIndex287 + goto l293 + l292: + position, tokenIndex = position292, tokenIndex292 } - l288: - add(rulepartialTime, position285) + l293: + add(rulepartialTime, position290) } return true - l284: - position, tokenIndex = position284, tokenIndex284 + l289: + position, tokenIndex = position289, tokenIndex289 return false }, - /* 50 fullDate <- <(dateFullYear '-' dateMonth '-' dateMDay)> */ + /* 51 fullDate <- <(dateFullYear '-' dateMonth '-' dateMDay)> */ nil, - /* 51 fullTime <- <(partialTime timeOffset)> */ + /* 52 fullTime <- <(partialTime timeOffset?)> */ nil, - /* 52 datetime <- <((fullDate ('T' fullTime)?) / partialTime)> */ + /* 53 datetime <- <((fullDate ('T' fullTime)?) / partialTime)> */ nil, - /* 53 digit <- <[0-9]> */ + /* 54 digit <- <[0-9]> */ func() bool { - position295, tokenIndex295 := position, tokenIndex + position300, tokenIndex300 := position, tokenIndex { - position296 := position + position301 := position if c := buffer[position]; c < rune('0') || c > rune('9') { - goto l295 + goto l300 } position++ - add(ruledigit, position296) + add(ruledigit, position301) } return true - l295: - position, tokenIndex = position295, tokenIndex295 + l300: + position, tokenIndex = position300, tokenIndex300 return false }, - /* 54 digitDual <- <(digit digit)> */ - func() bool { - position297, tokenIndex297 := position, tokenIndex - { - position298 := position - if !_rules[ruledigit]() { - goto l297 - } - if !_rules[ruledigit]() { - goto l297 - } - add(ruledigitDual, position298) - } - return true - l297: - position, tokenIndex = position297, tokenIndex297 - return false - }, - /* 55 digitQuad <- <(digitDual digitDual)> */ - nil, - /* 56 array <- <('[' Action22 wsnl arrayValues? wsnl ']')> */ - nil, - /* 57 arrayValues <- <(val Action23 (wsnl comment? wsnl arraySep wsnl comment? wsnl val Action24)* wsnl arraySep? wsnl comment?)> */ - nil, - /* 58 arraySep <- <','> */ + /* 55 digitDual <- <(digit digit)> */ func() bool { position302, tokenIndex302 := position, tokenIndex { position303 := position - if buffer[position] != rune(',') { + if !_rules[ruledigit]() { goto l302 } - position++ - add(rulearraySep, position303) + if !_rules[ruledigit]() { + goto l302 + } + add(ruledigitDual, position303) } return true l302: position, tokenIndex = position302, tokenIndex302 return false }, - /* 60 Action0 <- <{ _ = buffer }> */ + /* 56 digitQuad <- <(digitDual digitDual)> */ + nil, + /* 57 array <- <('[' Action23 wsnl arrayValues? wsnl ']')> */ + nil, + /* 58 arrayValues <- <(val Action24 (wsnl comment? wsnl arraySep wsnl comment? wsnl val Action25)* wsnl arraySep? wsnl comment?)> */ + nil, + /* 59 arraySep <- <','> */ + func() bool { + position307, tokenIndex307 := position, tokenIndex + { + position308 := position + if buffer[position] != rune(',') { + goto l307 + } + position++ + add(rulearraySep, position308) + } + return true + l307: + position, tokenIndex = position307, tokenIndex307 + return false + }, + /* 61 Action0 <- <{ _ = buffer }> */ nil, nil, - /* 62 Action1 <- <{ p.SetTableString(begin, end) }> */ + /* 63 Action1 <- <{ p.SetTableString(begin, end) }> */ nil, - /* 63 Action2 <- <{ p.AddLineCount(end - begin) }> */ + /* 64 Action2 <- <{ p.AddLineCount(end - begin) }> */ nil, - /* 64 Action3 <- <{ p.AddLineCount(end - begin) }> */ + /* 65 Action3 <- <{ p.AddLineCount(end - begin) }> */ nil, - /* 65 Action4 <- <{ p.AddKeyValue() }> */ + /* 66 Action4 <- <{ p.AddKeyValue() }> */ nil, - /* 66 Action5 <- <{ p.SetKey(p.buffer, begin, end) }> */ + /* 67 Action5 <- <{ p.SetKey(p.buffer, begin, end) }> */ nil, - /* 67 Action6 <- <{ p.SetKey(p.buffer, begin-1, end+1) }> */ + /* 68 Action6 <- <{ p.SetKey(p.buffer, begin, end) }> */ nil, - /* 68 Action7 <- <{ p.SetTime(begin, end) }> */ + /* 69 Action7 <- <{ p.SetTime(begin, end) }> */ nil, - /* 69 Action8 <- <{ p.SetFloat64(begin, end) }> */ + /* 70 Action8 <- <{ p.SetFloat64(begin, end) }> */ nil, - /* 70 Action9 <- <{ p.SetInt64(begin, end) }> */ + /* 71 Action9 <- <{ p.SetInt64(begin, end) }> */ nil, - /* 71 Action10 <- <{ p.SetString(begin, end) }> */ + /* 72 Action10 <- <{ p.SetString(begin, end) }> */ nil, - /* 72 Action11 <- <{ p.SetBool(begin, end) }> */ + /* 73 Action11 <- <{ p.SetBool(begin, end) }> */ nil, - /* 73 Action12 <- <{ p.SetArray(begin, end) }> */ + /* 74 Action12 <- <{ p.SetArray(begin, end) }> */ nil, - /* 74 Action13 <- <{ p.SetTable(p.buffer, begin, end) }> */ + /* 75 Action13 <- <{ p.SetTable(p.buffer, begin, end) }> */ nil, - /* 75 Action14 <- <{ p.SetArrayTable(p.buffer, begin, end) }> */ + /* 76 Action14 <- <{ p.SetArrayTable(p.buffer, begin, end) }> */ nil, - /* 76 Action15 <- <{ p.StartInlineTable() }> */ + /* 77 Action15 <- <{ p.StartInlineTable() }> */ nil, - /* 77 Action16 <- <{ p.EndInlineTable() }> */ + /* 78 Action16 <- <{ p.EndInlineTable() }> */ nil, - /* 78 Action17 <- <{ p.SetBasicString(p.buffer, begin, end) }> */ + /* 79 Action17 <- <{ p.AddTableKey() }> */ nil, - /* 79 Action18 <- <{ p.SetMultilineString() }> */ + /* 80 Action18 <- <{ p.SetBasicString(p.buffer, begin, end) }> */ nil, - /* 80 Action19 <- <{ p.AddMultilineBasicBody(p.buffer, begin, end) }> */ + /* 81 Action19 <- <{ p.SetMultilineString() }> */ nil, - /* 81 Action20 <- <{ p.SetLiteralString(p.buffer, begin, end) }> */ + /* 82 Action20 <- <{ p.AddMultilineBasicBody(p.buffer, begin, end) }> */ nil, - /* 82 Action21 <- <{ p.SetMultilineLiteralString(p.buffer, begin, end) }> */ + /* 83 Action21 <- <{ p.SetLiteralString(p.buffer, begin, end) }> */ nil, - /* 83 Action22 <- <{ p.StartArray() }> */ + /* 84 Action22 <- <{ p.SetMultilineLiteralString(p.buffer, begin, end) }> */ nil, - /* 84 Action23 <- <{ p.AddArrayVal() }> */ + /* 85 Action23 <- <{ p.StartArray() }> */ nil, - /* 85 Action24 <- <{ p.AddArrayVal() }> */ + /* 86 Action24 <- <{ p.AddArrayVal() }> */ + nil, + /* 87 Action25 <- <{ p.AddArrayVal() }> */ nil, } p.rules = _rules diff --git a/vendor/github.com/opentracing/opentracing-go/CHANGELOG.md b/vendor/github.com/opentracing/opentracing-go/CHANGELOG.md new file mode 100644 index 0000000000..1fc9fdf7f3 --- /dev/null +++ b/vendor/github.com/opentracing/opentracing-go/CHANGELOG.md @@ -0,0 +1,14 @@ +Changes by Version +================== + +1.1.0 (unreleased) +------------------- + +- Deprecate InitGlobalTracer() in favor of SetGlobalTracer() + + +1.0.0 (2016-09-26) +------------------- + +- This release implements OpenTracing Specification 1.0 (http://opentracing.io/spec) + diff --git a/vendor/github.com/Azure/go-autorest/LICENSE b/vendor/github.com/opentracing/opentracing-go/LICENSE similarity index 94% rename from vendor/github.com/Azure/go-autorest/LICENSE rename to vendor/github.com/opentracing/opentracing-go/LICENSE index b9d6a27ea9..f0027349e8 100644 --- a/vendor/github.com/Azure/go-autorest/LICENSE +++ b/vendor/github.com/opentracing/opentracing-go/LICENSE @@ -1,4 +1,3 @@ - Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ @@ -176,7 +175,18 @@ END OF TERMS AND CONDITIONS - Copyright 2015 Microsoft Corporation + 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 2016 The OpenTracing Authors Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/vendor/github.com/opentracing/opentracing-go/Makefile b/vendor/github.com/opentracing/opentracing-go/Makefile new file mode 100644 index 0000000000..d49a5c0d44 --- /dev/null +++ b/vendor/github.com/opentracing/opentracing-go/Makefile @@ -0,0 +1,32 @@ +PACKAGES := . ./mocktracer/... ./ext/... + +.DEFAULT_GOAL := test-and-lint + +.PHONE: test-and-lint + +test-and-lint: test lint + +.PHONY: test +test: + go test -v -cover -race ./... + +cover: + @rm -rf cover-all.out + $(foreach pkg, $(PACKAGES), $(MAKE) cover-pkg PKG=$(pkg) || true;) + @grep mode: cover.out > coverage.out + @cat cover-all.out >> coverage.out + go tool cover -html=coverage.out -o cover.html + @rm -rf cover.out cover-all.out coverage.out + +cover-pkg: + go test -coverprofile cover.out $(PKG) + @grep -v mode: cover.out >> cover-all.out + +.PHONY: lint +lint: + go fmt ./... + golint ./... + @# Run again with magic to exit non-zero if golint outputs anything. + @! (golint ./... | read dummy) + go vet ./... + diff --git a/vendor/github.com/opentracing/opentracing-go/README.md b/vendor/github.com/opentracing/opentracing-go/README.md new file mode 100644 index 0000000000..007ee237c8 --- /dev/null +++ b/vendor/github.com/opentracing/opentracing-go/README.md @@ -0,0 +1,171 @@ +[![Gitter chat](http://img.shields.io/badge/gitter-join%20chat%20%E2%86%92-brightgreen.svg)](https://gitter.im/opentracing/public) [![Build Status](https://travis-ci.org/opentracing/opentracing-go.svg?branch=master)](https://travis-ci.org/opentracing/opentracing-go) [![GoDoc](https://godoc.org/github.com/opentracing/opentracing-go?status.svg)](http://godoc.org/github.com/opentracing/opentracing-go) +[![Sourcegraph Badge](https://sourcegraph.com/github.com/opentracing/opentracing-go/-/badge.svg)](https://sourcegraph.com/github.com/opentracing/opentracing-go?badge) + +# OpenTracing API for Go + +This package is a Go platform API for OpenTracing. + +## Required Reading + +In order to understand the Go platform API, one must first be familiar with the +[OpenTracing project](http://opentracing.io) and +[terminology](http://opentracing.io/documentation/pages/spec.html) more specifically. + +## API overview for those adding instrumentation + +Everyday consumers of this `opentracing` package really only need to worry +about a couple of key abstractions: the `StartSpan` function, the `Span` +interface, and binding a `Tracer` at `main()`-time. Here are code snippets +demonstrating some important use cases. + +#### Singleton initialization + +The simplest starting point is `./default_tracer.go`. As early as possible, call + +```go + import "github.com/opentracing/opentracing-go" + import ".../some_tracing_impl" + + func main() { + opentracing.SetGlobalTracer( + // tracing impl specific: + some_tracing_impl.New(...), + ) + ... + } +``` + +#### Non-Singleton initialization + +If you prefer direct control to singletons, manage ownership of the +`opentracing.Tracer` implementation explicitly. + +#### Creating a Span given an existing Go `context.Context` + +If you use `context.Context` in your application, OpenTracing's Go library will +happily rely on it for `Span` propagation. To start a new (blocking child) +`Span`, you can use `StartSpanFromContext`. + +```go + func xyz(ctx context.Context, ...) { + ... + span, ctx := opentracing.StartSpanFromContext(ctx, "operation_name") + defer span.Finish() + span.LogFields( + log.String("event", "soft error"), + log.String("type", "cache timeout"), + log.Int("waited.millis", 1500)) + ... + } +``` + +#### Starting an empty trace by creating a "root span" + +It's always possible to create a "root" `Span` with no parent or other causal +reference. + +```go + func xyz() { + ... + sp := opentracing.StartSpan("operation_name") + defer sp.Finish() + ... + } +``` + +#### Creating a (child) Span given an existing (parent) Span + +```go + func xyz(parentSpan opentracing.Span, ...) { + ... + sp := opentracing.StartSpan( + "operation_name", + opentracing.ChildOf(parentSpan.Context())) + defer sp.Finish() + ... + } +``` + +#### Serializing to the wire + +```go + func makeSomeRequest(ctx context.Context) ... { + if span := opentracing.SpanFromContext(ctx); span != nil { + httpClient := &http.Client{} + httpReq, _ := http.NewRequest("GET", "http://myservice/", nil) + + // Transmit the span's TraceContext as HTTP headers on our + // outbound request. + opentracing.GlobalTracer().Inject( + span.Context(), + opentracing.HTTPHeaders, + opentracing.HTTPHeadersCarrier(httpReq.Header)) + + resp, err := httpClient.Do(httpReq) + ... + } + ... + } +``` + +#### Deserializing from the wire + +```go + http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) { + var serverSpan opentracing.Span + appSpecificOperationName := ... + wireContext, err := opentracing.GlobalTracer().Extract( + opentracing.HTTPHeaders, + opentracing.HTTPHeadersCarrier(req.Header)) + if err != nil { + // Optionally record something about err here + } + + // Create the span referring to the RPC client if available. + // If wireContext == nil, a root span will be created. + serverSpan = opentracing.StartSpan( + appSpecificOperationName, + ext.RPCServerOption(wireContext)) + + defer serverSpan.Finish() + + ctx := opentracing.ContextWithSpan(context.Background(), serverSpan) + ... + } +``` + +#### Conditionally capture a field using `log.Noop` + +In some situations, you may want to dynamically decide whether or not +to log a field. For example, you may want to capture additional data, +such as a customer ID, in non-production environments: + +```go + func Customer(order *Order) log.Field { + if os.Getenv("ENVIRONMENT") == "dev" { + return log.String("customer", order.Customer.ID) + } + return log.Noop() + } +``` + +#### Goroutine-safety + +The entire public API is goroutine-safe and does not require external +synchronization. + +## API pointers for those implementing a tracing system + +Tracing system implementors may be able to reuse or copy-paste-modify the `basictracer` package, found [here](https://github.com/opentracing/basictracer-go). In particular, see `basictracer.New(...)`. + +## API compatibility + +For the time being, "mild" backwards-incompatible changes may be made without changing the major version number. As OpenTracing and `opentracing-go` mature, backwards compatibility will become more of a priority. + +## Tracer test suite + +A test suite is available in the [harness](https://godoc.org/github.com/opentracing/opentracing-go/harness) package that can assist Tracer implementors to assert that their Tracer is working correctly. + +## Licensing + +[Apache 2.0 License](./LICENSE). diff --git a/vendor/github.com/opentracing/opentracing-go/ext/tags.go b/vendor/github.com/opentracing/opentracing-go/ext/tags.go new file mode 100644 index 0000000000..8800129a23 --- /dev/null +++ b/vendor/github.com/opentracing/opentracing-go/ext/tags.go @@ -0,0 +1,210 @@ +package ext + +import opentracing "github.com/opentracing/opentracing-go" + +// These constants define common tag names recommended for better portability across +// tracing systems and languages/platforms. +// +// The tag names are defined as typed strings, so that in addition to the usual use +// +// span.setTag(TagName, value) +// +// they also support value type validation via this additional syntax: +// +// TagName.Set(span, value) +// +var ( + ////////////////////////////////////////////////////////////////////// + // SpanKind (client/server or producer/consumer) + ////////////////////////////////////////////////////////////////////// + + // SpanKind hints at relationship between spans, e.g. client/server + SpanKind = spanKindTagName("span.kind") + + // SpanKindRPCClient marks a span representing the client-side of an RPC + // or other remote call + SpanKindRPCClientEnum = SpanKindEnum("client") + SpanKindRPCClient = opentracing.Tag{Key: string(SpanKind), Value: SpanKindRPCClientEnum} + + // SpanKindRPCServer marks a span representing the server-side of an RPC + // or other remote call + SpanKindRPCServerEnum = SpanKindEnum("server") + SpanKindRPCServer = opentracing.Tag{Key: string(SpanKind), Value: SpanKindRPCServerEnum} + + // SpanKindProducer marks a span representing the producer-side of a + // message bus + SpanKindProducerEnum = SpanKindEnum("producer") + SpanKindProducer = opentracing.Tag{Key: string(SpanKind), Value: SpanKindProducerEnum} + + // SpanKindConsumer marks a span representing the consumer-side of a + // message bus + SpanKindConsumerEnum = SpanKindEnum("consumer") + SpanKindConsumer = opentracing.Tag{Key: string(SpanKind), Value: SpanKindConsumerEnum} + + ////////////////////////////////////////////////////////////////////// + // Component name + ////////////////////////////////////////////////////////////////////// + + // Component is a low-cardinality identifier of the module, library, + // or package that is generating a span. + Component = stringTagName("component") + + ////////////////////////////////////////////////////////////////////// + // Sampling hint + ////////////////////////////////////////////////////////////////////// + + // SamplingPriority determines the priority of sampling this Span. + SamplingPriority = uint16TagName("sampling.priority") + + ////////////////////////////////////////////////////////////////////// + // Peer tags. These tags can be emitted by either client-side of + // server-side to describe the other side/service in a peer-to-peer + // communications, like an RPC call. + ////////////////////////////////////////////////////////////////////// + + // PeerService records the service name of the peer. + PeerService = stringTagName("peer.service") + + // PeerAddress records the address name of the peer. This may be a "ip:port", + // a bare "hostname", a FQDN or even a database DSN substring + // like "mysql://username@127.0.0.1:3306/dbname" + PeerAddress = stringTagName("peer.address") + + // PeerHostname records the host name of the peer + PeerHostname = stringTagName("peer.hostname") + + // PeerHostIPv4 records IP v4 host address of the peer + PeerHostIPv4 = ipv4Tag("peer.ipv4") + + // PeerHostIPv6 records IP v6 host address of the peer + PeerHostIPv6 = stringTagName("peer.ipv6") + + // PeerPort records port number of the peer + PeerPort = uint16TagName("peer.port") + + ////////////////////////////////////////////////////////////////////// + // HTTP Tags + ////////////////////////////////////////////////////////////////////// + + // HTTPUrl should be the URL of the request being handled in this segment + // of the trace, in standard URI format. The protocol is optional. + HTTPUrl = stringTagName("http.url") + + // HTTPMethod is the HTTP method of the request, and is case-insensitive. + HTTPMethod = stringTagName("http.method") + + // HTTPStatusCode is the numeric HTTP status code (200, 404, etc) of the + // HTTP response. + HTTPStatusCode = uint16TagName("http.status_code") + + ////////////////////////////////////////////////////////////////////// + // DB Tags + ////////////////////////////////////////////////////////////////////// + + // DBInstance is database instance name. + DBInstance = stringTagName("db.instance") + + // DBStatement is a database statement for the given database type. + // It can be a query or a prepared statement (i.e., before substitution). + DBStatement = stringTagName("db.statement") + + // DBType is a database type. For any SQL database, "sql". + // For others, the lower-case database category, e.g. "redis" + DBType = stringTagName("db.type") + + // DBUser is a username for accessing database. + DBUser = stringTagName("db.user") + + ////////////////////////////////////////////////////////////////////// + // Message Bus Tag + ////////////////////////////////////////////////////////////////////// + + // MessageBusDestination is an address at which messages can be exchanged + MessageBusDestination = stringTagName("message_bus.destination") + + ////////////////////////////////////////////////////////////////////// + // Error Tag + ////////////////////////////////////////////////////////////////////// + + // Error indicates that operation represented by the span resulted in an error. + Error = boolTagName("error") +) + +// --- + +// SpanKindEnum represents common span types +type SpanKindEnum string + +type spanKindTagName string + +// Set adds a string tag to the `span` +func (tag spanKindTagName) Set(span opentracing.Span, value SpanKindEnum) { + span.SetTag(string(tag), value) +} + +type rpcServerOption struct { + clientContext opentracing.SpanContext +} + +func (r rpcServerOption) Apply(o *opentracing.StartSpanOptions) { + if r.clientContext != nil { + opentracing.ChildOf(r.clientContext).Apply(o) + } + SpanKindRPCServer.Apply(o) +} + +// RPCServerOption returns a StartSpanOption appropriate for an RPC server span +// with `client` representing the metadata for the remote peer Span if available. +// In case client == nil, due to the client not being instrumented, this RPC +// server span will be a root span. +func RPCServerOption(client opentracing.SpanContext) opentracing.StartSpanOption { + return rpcServerOption{client} +} + +// --- + +type stringTagName string + +// Set adds a string tag to the `span` +func (tag stringTagName) Set(span opentracing.Span, value string) { + span.SetTag(string(tag), value) +} + +// --- + +type uint32TagName string + +// Set adds a uint32 tag to the `span` +func (tag uint32TagName) Set(span opentracing.Span, value uint32) { + span.SetTag(string(tag), value) +} + +// --- + +type uint16TagName string + +// Set adds a uint16 tag to the `span` +func (tag uint16TagName) Set(span opentracing.Span, value uint16) { + span.SetTag(string(tag), value) +} + +// --- + +type boolTagName string + +// Add adds a bool tag to the `span` +func (tag boolTagName) Set(span opentracing.Span, value bool) { + span.SetTag(string(tag), value) +} + +type ipv4Tag string + +// Set adds IP v4 host address of the peer as an uint32 value to the `span`, keep this for backward and zipkin compatibility +func (tag ipv4Tag) Set(span opentracing.Span, value uint32) { + span.SetTag(string(tag), value) +} + +// SetString records IP v4 host address of the peer as a .-separated tuple to the `span`. E.g., "127.0.0.1" +func (tag ipv4Tag) SetString(span opentracing.Span, value string) { + span.SetTag(string(tag), value) +} diff --git a/vendor/github.com/opentracing/opentracing-go/globaltracer.go b/vendor/github.com/opentracing/opentracing-go/globaltracer.go new file mode 100644 index 0000000000..8c8e793ff2 --- /dev/null +++ b/vendor/github.com/opentracing/opentracing-go/globaltracer.go @@ -0,0 +1,32 @@ +package opentracing + +var ( + globalTracer Tracer = NoopTracer{} +) + +// SetGlobalTracer sets the [singleton] opentracing.Tracer returned by +// GlobalTracer(). Those who use GlobalTracer (rather than directly manage an +// opentracing.Tracer instance) should call SetGlobalTracer as early as +// possible in main(), prior to calling the `StartSpan` global func below. +// Prior to calling `SetGlobalTracer`, any Spans started via the `StartSpan` +// (etc) globals are noops. +func SetGlobalTracer(tracer Tracer) { + globalTracer = tracer +} + +// GlobalTracer returns the global singleton `Tracer` implementation. +// Before `SetGlobalTracer()` is called, the `GlobalTracer()` is a noop +// implementation that drops all data handed to it. +func GlobalTracer() Tracer { + return globalTracer +} + +// StartSpan defers to `Tracer.StartSpan`. See `GlobalTracer()`. +func StartSpan(operationName string, opts ...StartSpanOption) Span { + return globalTracer.StartSpan(operationName, opts...) +} + +// InitGlobalTracer is deprecated. Please use SetGlobalTracer. +func InitGlobalTracer(tracer Tracer) { + SetGlobalTracer(tracer) +} diff --git a/vendor/github.com/opentracing/opentracing-go/gocontext.go b/vendor/github.com/opentracing/opentracing-go/gocontext.go new file mode 100644 index 0000000000..05a62e70b1 --- /dev/null +++ b/vendor/github.com/opentracing/opentracing-go/gocontext.go @@ -0,0 +1,54 @@ +package opentracing + +import "context" + +type contextKey struct{} + +var activeSpanKey = contextKey{} + +// ContextWithSpan returns a new `context.Context` that holds a reference to +// `span`'s SpanContext. +func ContextWithSpan(ctx context.Context, span Span) context.Context { + return context.WithValue(ctx, activeSpanKey, span) +} + +// SpanFromContext returns the `Span` previously associated with `ctx`, or +// `nil` if no such `Span` could be found. +// +// NOTE: context.Context != SpanContext: the former is Go's intra-process +// context propagation mechanism, and the latter houses OpenTracing's per-Span +// identity and baggage information. +func SpanFromContext(ctx context.Context) Span { + val := ctx.Value(activeSpanKey) + if sp, ok := val.(Span); ok { + return sp + } + return nil +} + +// StartSpanFromContext starts and returns a Span with `operationName`, using +// any Span found within `ctx` as a ChildOfRef. If no such parent could be +// found, StartSpanFromContext creates a root (parentless) Span. +// +// The second return value is a context.Context object built around the +// returned Span. +// +// Example usage: +// +// SomeFunction(ctx context.Context, ...) { +// sp, ctx := opentracing.StartSpanFromContext(ctx, "SomeFunction") +// defer sp.Finish() +// ... +// } +func StartSpanFromContext(ctx context.Context, operationName string, opts ...StartSpanOption) (Span, context.Context) { + return startSpanFromContextWithTracer(ctx, GlobalTracer(), operationName, opts...) +} + +// startSpanFromContextWithTracer is factored out for testing purposes. +func startSpanFromContextWithTracer(ctx context.Context, tracer Tracer, operationName string, opts ...StartSpanOption) (Span, context.Context) { + if parentSpan := SpanFromContext(ctx); parentSpan != nil { + opts = append(opts, ChildOf(parentSpan.Context())) + } + span := tracer.StartSpan(operationName, opts...) + return span, ContextWithSpan(ctx, span) +} diff --git a/vendor/github.com/opentracing/opentracing-go/log/field.go b/vendor/github.com/opentracing/opentracing-go/log/field.go new file mode 100644 index 0000000000..50feea341a --- /dev/null +++ b/vendor/github.com/opentracing/opentracing-go/log/field.go @@ -0,0 +1,269 @@ +package log + +import ( + "fmt" + "math" +) + +type fieldType int + +const ( + stringType fieldType = iota + boolType + intType + int32Type + uint32Type + int64Type + uint64Type + float32Type + float64Type + errorType + objectType + lazyLoggerType + noopType +) + +// Field instances are constructed via LogBool, LogString, and so on. +// Tracing implementations may then handle them via the Field.Marshal +// method. +// +// "heavily influenced by" (i.e., partially stolen from) +// https://github.com/uber-go/zap +type Field struct { + key string + fieldType fieldType + numericVal int64 + stringVal string + interfaceVal interface{} +} + +// String adds a string-valued key:value pair to a Span.LogFields() record +func String(key, val string) Field { + return Field{ + key: key, + fieldType: stringType, + stringVal: val, + } +} + +// Bool adds a bool-valued key:value pair to a Span.LogFields() record +func Bool(key string, val bool) Field { + var numericVal int64 + if val { + numericVal = 1 + } + return Field{ + key: key, + fieldType: boolType, + numericVal: numericVal, + } +} + +// Int adds an int-valued key:value pair to a Span.LogFields() record +func Int(key string, val int) Field { + return Field{ + key: key, + fieldType: intType, + numericVal: int64(val), + } +} + +// Int32 adds an int32-valued key:value pair to a Span.LogFields() record +func Int32(key string, val int32) Field { + return Field{ + key: key, + fieldType: int32Type, + numericVal: int64(val), + } +} + +// Int64 adds an int64-valued key:value pair to a Span.LogFields() record +func Int64(key string, val int64) Field { + return Field{ + key: key, + fieldType: int64Type, + numericVal: val, + } +} + +// Uint32 adds a uint32-valued key:value pair to a Span.LogFields() record +func Uint32(key string, val uint32) Field { + return Field{ + key: key, + fieldType: uint32Type, + numericVal: int64(val), + } +} + +// Uint64 adds a uint64-valued key:value pair to a Span.LogFields() record +func Uint64(key string, val uint64) Field { + return Field{ + key: key, + fieldType: uint64Type, + numericVal: int64(val), + } +} + +// Float32 adds a float32-valued key:value pair to a Span.LogFields() record +func Float32(key string, val float32) Field { + return Field{ + key: key, + fieldType: float32Type, + numericVal: int64(math.Float32bits(val)), + } +} + +// Float64 adds a float64-valued key:value pair to a Span.LogFields() record +func Float64(key string, val float64) Field { + return Field{ + key: key, + fieldType: float64Type, + numericVal: int64(math.Float64bits(val)), + } +} + +// Error adds an error with the key "error" to a Span.LogFields() record +func Error(err error) Field { + return Field{ + key: "error", + fieldType: errorType, + interfaceVal: err, + } +} + +// Object adds an object-valued key:value pair to a Span.LogFields() record +func Object(key string, obj interface{}) Field { + return Field{ + key: key, + fieldType: objectType, + interfaceVal: obj, + } +} + +// LazyLogger allows for user-defined, late-bound logging of arbitrary data +type LazyLogger func(fv Encoder) + +// Lazy adds a LazyLogger to a Span.LogFields() record; the tracing +// implementation will call the LazyLogger function at an indefinite time in +// the future (after Lazy() returns). +func Lazy(ll LazyLogger) Field { + return Field{ + fieldType: lazyLoggerType, + interfaceVal: ll, + } +} + +// Noop creates a no-op log field that should be ignored by the tracer. +// It can be used to capture optional fields, for example those that should +// only be logged in non-production environment: +// +// func customerField(order *Order) log.Field { +// if os.Getenv("ENVIRONMENT") == "dev" { +// return log.String("customer", order.Customer.ID) +// } +// return log.Noop() +// } +// +// span.LogFields(log.String("event", "purchase"), customerField(order)) +// +func Noop() Field { + return Field{ + fieldType: noopType, + } +} + +// Encoder allows access to the contents of a Field (via a call to +// Field.Marshal). +// +// Tracer implementations typically provide an implementation of Encoder; +// OpenTracing callers typically do not need to concern themselves with it. +type Encoder interface { + EmitString(key, value string) + EmitBool(key string, value bool) + EmitInt(key string, value int) + EmitInt32(key string, value int32) + EmitInt64(key string, value int64) + EmitUint32(key string, value uint32) + EmitUint64(key string, value uint64) + EmitFloat32(key string, value float32) + EmitFloat64(key string, value float64) + EmitObject(key string, value interface{}) + EmitLazyLogger(value LazyLogger) +} + +// Marshal passes a Field instance through to the appropriate +// field-type-specific method of an Encoder. +func (lf Field) Marshal(visitor Encoder) { + switch lf.fieldType { + case stringType: + visitor.EmitString(lf.key, lf.stringVal) + case boolType: + visitor.EmitBool(lf.key, lf.numericVal != 0) + case intType: + visitor.EmitInt(lf.key, int(lf.numericVal)) + case int32Type: + visitor.EmitInt32(lf.key, int32(lf.numericVal)) + case int64Type: + visitor.EmitInt64(lf.key, int64(lf.numericVal)) + case uint32Type: + visitor.EmitUint32(lf.key, uint32(lf.numericVal)) + case uint64Type: + visitor.EmitUint64(lf.key, uint64(lf.numericVal)) + case float32Type: + visitor.EmitFloat32(lf.key, math.Float32frombits(uint32(lf.numericVal))) + case float64Type: + visitor.EmitFloat64(lf.key, math.Float64frombits(uint64(lf.numericVal))) + case errorType: + if err, ok := lf.interfaceVal.(error); ok { + visitor.EmitString(lf.key, err.Error()) + } else { + visitor.EmitString(lf.key, "") + } + case objectType: + visitor.EmitObject(lf.key, lf.interfaceVal) + case lazyLoggerType: + visitor.EmitLazyLogger(lf.interfaceVal.(LazyLogger)) + case noopType: + // intentionally left blank + } +} + +// Key returns the field's key. +func (lf Field) Key() string { + return lf.key +} + +// Value returns the field's value as interface{}. +func (lf Field) Value() interface{} { + switch lf.fieldType { + case stringType: + return lf.stringVal + case boolType: + return lf.numericVal != 0 + case intType: + return int(lf.numericVal) + case int32Type: + return int32(lf.numericVal) + case int64Type: + return int64(lf.numericVal) + case uint32Type: + return uint32(lf.numericVal) + case uint64Type: + return uint64(lf.numericVal) + case float32Type: + return math.Float32frombits(uint32(lf.numericVal)) + case float64Type: + return math.Float64frombits(uint64(lf.numericVal)) + case errorType, objectType, lazyLoggerType: + return lf.interfaceVal + case noopType: + return nil + default: + return nil + } +} + +// String returns a string representation of the key and value. +func (lf Field) String() string { + return fmt.Sprint(lf.key, ":", lf.Value()) +} diff --git a/vendor/github.com/opentracing/opentracing-go/log/util.go b/vendor/github.com/opentracing/opentracing-go/log/util.go new file mode 100644 index 0000000000..3832feb5ce --- /dev/null +++ b/vendor/github.com/opentracing/opentracing-go/log/util.go @@ -0,0 +1,54 @@ +package log + +import "fmt" + +// InterleavedKVToFields converts keyValues a la Span.LogKV() to a Field slice +// a la Span.LogFields(). +func InterleavedKVToFields(keyValues ...interface{}) ([]Field, error) { + if len(keyValues)%2 != 0 { + return nil, fmt.Errorf("non-even keyValues len: %d", len(keyValues)) + } + fields := make([]Field, len(keyValues)/2) + for i := 0; i*2 < len(keyValues); i++ { + key, ok := keyValues[i*2].(string) + if !ok { + return nil, fmt.Errorf( + "non-string key (pair #%d): %T", + i, keyValues[i*2]) + } + switch typedVal := keyValues[i*2+1].(type) { + case bool: + fields[i] = Bool(key, typedVal) + case string: + fields[i] = String(key, typedVal) + case int: + fields[i] = Int(key, typedVal) + case int8: + fields[i] = Int32(key, int32(typedVal)) + case int16: + fields[i] = Int32(key, int32(typedVal)) + case int32: + fields[i] = Int32(key, typedVal) + case int64: + fields[i] = Int64(key, typedVal) + case uint: + fields[i] = Uint64(key, uint64(typedVal)) + case uint64: + fields[i] = Uint64(key, typedVal) + case uint8: + fields[i] = Uint32(key, uint32(typedVal)) + case uint16: + fields[i] = Uint32(key, uint32(typedVal)) + case uint32: + fields[i] = Uint32(key, typedVal) + case float32: + fields[i] = Float32(key, typedVal) + case float64: + fields[i] = Float64(key, typedVal) + default: + // When in doubt, coerce to a string + fields[i] = String(key, fmt.Sprint(typedVal)) + } + } + return fields, nil +} diff --git a/vendor/github.com/opentracing/opentracing-go/noop.go b/vendor/github.com/opentracing/opentracing-go/noop.go new file mode 100644 index 0000000000..0d32f692c4 --- /dev/null +++ b/vendor/github.com/opentracing/opentracing-go/noop.go @@ -0,0 +1,64 @@ +package opentracing + +import "github.com/opentracing/opentracing-go/log" + +// A NoopTracer is a trivial, minimum overhead implementation of Tracer +// for which all operations are no-ops. +// +// The primary use of this implementation is in libraries, such as RPC +// frameworks, that make tracing an optional feature controlled by the +// end user. A no-op implementation allows said libraries to use it +// as the default Tracer and to write instrumentation that does +// not need to keep checking if the tracer instance is nil. +// +// For the same reason, the NoopTracer is the default "global" tracer +// (see GlobalTracer and SetGlobalTracer functions). +// +// WARNING: NoopTracer does not support baggage propagation. +type NoopTracer struct{} + +type noopSpan struct{} +type noopSpanContext struct{} + +var ( + defaultNoopSpanContext = noopSpanContext{} + defaultNoopSpan = noopSpan{} + defaultNoopTracer = NoopTracer{} +) + +const ( + emptyString = "" +) + +// noopSpanContext: +func (n noopSpanContext) ForeachBaggageItem(handler func(k, v string) bool) {} + +// noopSpan: +func (n noopSpan) Context() SpanContext { return defaultNoopSpanContext } +func (n noopSpan) SetBaggageItem(key, val string) Span { return defaultNoopSpan } +func (n noopSpan) BaggageItem(key string) string { return emptyString } +func (n noopSpan) SetTag(key string, value interface{}) Span { return n } +func (n noopSpan) LogFields(fields ...log.Field) {} +func (n noopSpan) LogKV(keyVals ...interface{}) {} +func (n noopSpan) Finish() {} +func (n noopSpan) FinishWithOptions(opts FinishOptions) {} +func (n noopSpan) SetOperationName(operationName string) Span { return n } +func (n noopSpan) Tracer() Tracer { return defaultNoopTracer } +func (n noopSpan) LogEvent(event string) {} +func (n noopSpan) LogEventWithPayload(event string, payload interface{}) {} +func (n noopSpan) Log(data LogData) {} + +// StartSpan belongs to the Tracer interface. +func (n NoopTracer) StartSpan(operationName string, opts ...StartSpanOption) Span { + return defaultNoopSpan +} + +// Inject belongs to the Tracer interface. +func (n NoopTracer) Inject(sp SpanContext, format interface{}, carrier interface{}) error { + return nil +} + +// Extract belongs to the Tracer interface. +func (n NoopTracer) Extract(format interface{}, carrier interface{}) (SpanContext, error) { + return nil, ErrSpanContextNotFound +} diff --git a/vendor/github.com/opentracing/opentracing-go/propagation.go b/vendor/github.com/opentracing/opentracing-go/propagation.go new file mode 100644 index 0000000000..0dd466a373 --- /dev/null +++ b/vendor/github.com/opentracing/opentracing-go/propagation.go @@ -0,0 +1,176 @@ +package opentracing + +import ( + "errors" + "net/http" +) + +/////////////////////////////////////////////////////////////////////////////// +// CORE PROPAGATION INTERFACES: +/////////////////////////////////////////////////////////////////////////////// + +var ( + // ErrUnsupportedFormat occurs when the `format` passed to Tracer.Inject() or + // Tracer.Extract() is not recognized by the Tracer implementation. + ErrUnsupportedFormat = errors.New("opentracing: Unknown or unsupported Inject/Extract format") + + // ErrSpanContextNotFound occurs when the `carrier` passed to + // Tracer.Extract() is valid and uncorrupted but has insufficient + // information to extract a SpanContext. + ErrSpanContextNotFound = errors.New("opentracing: SpanContext not found in Extract carrier") + + // ErrInvalidSpanContext errors occur when Tracer.Inject() is asked to + // operate on a SpanContext which it is not prepared to handle (for + // example, since it was created by a different tracer implementation). + ErrInvalidSpanContext = errors.New("opentracing: SpanContext type incompatible with tracer") + + // ErrInvalidCarrier errors occur when Tracer.Inject() or Tracer.Extract() + // implementations expect a different type of `carrier` than they are + // given. + ErrInvalidCarrier = errors.New("opentracing: Invalid Inject/Extract carrier") + + // ErrSpanContextCorrupted occurs when the `carrier` passed to + // Tracer.Extract() is of the expected type but is corrupted. + ErrSpanContextCorrupted = errors.New("opentracing: SpanContext data corrupted in Extract carrier") +) + +/////////////////////////////////////////////////////////////////////////////// +// BUILTIN PROPAGATION FORMATS: +/////////////////////////////////////////////////////////////////////////////// + +// BuiltinFormat is used to demarcate the values within package `opentracing` +// that are intended for use with the Tracer.Inject() and Tracer.Extract() +// methods. +type BuiltinFormat byte + +const ( + // Binary represents SpanContexts as opaque binary data. + // + // For Tracer.Inject(): the carrier must be an `io.Writer`. + // + // For Tracer.Extract(): the carrier must be an `io.Reader`. + Binary BuiltinFormat = iota + + // TextMap represents SpanContexts as key:value string pairs. + // + // Unlike HTTPHeaders, the TextMap format does not restrict the key or + // value character sets in any way. + // + // For Tracer.Inject(): the carrier must be a `TextMapWriter`. + // + // For Tracer.Extract(): the carrier must be a `TextMapReader`. + TextMap + + // HTTPHeaders represents SpanContexts as HTTP header string pairs. + // + // Unlike TextMap, the HTTPHeaders format requires that the keys and values + // be valid as HTTP headers as-is (i.e., character casing may be unstable + // and special characters are disallowed in keys, values should be + // URL-escaped, etc). + // + // For Tracer.Inject(): the carrier must be a `TextMapWriter`. + // + // For Tracer.Extract(): the carrier must be a `TextMapReader`. + // + // See HTTPHeadersCarrier for an implementation of both TextMapWriter + // and TextMapReader that defers to an http.Header instance for storage. + // For example, Inject(): + // + // carrier := opentracing.HTTPHeadersCarrier(httpReq.Header) + // err := span.Tracer().Inject( + // span.Context(), opentracing.HTTPHeaders, carrier) + // + // Or Extract(): + // + // carrier := opentracing.HTTPHeadersCarrier(httpReq.Header) + // clientContext, err := tracer.Extract( + // opentracing.HTTPHeaders, carrier) + // + HTTPHeaders +) + +// TextMapWriter is the Inject() carrier for the TextMap builtin format. With +// it, the caller can encode a SpanContext for propagation as entries in a map +// of unicode strings. +type TextMapWriter interface { + // Set a key:value pair to the carrier. Multiple calls to Set() for the + // same key leads to undefined behavior. + // + // NOTE: The backing store for the TextMapWriter may contain data unrelated + // to SpanContext. As such, Inject() and Extract() implementations that + // call the TextMapWriter and TextMapReader interfaces must agree on a + // prefix or other convention to distinguish their own key:value pairs. + Set(key, val string) +} + +// TextMapReader is the Extract() carrier for the TextMap builtin format. With it, +// the caller can decode a propagated SpanContext as entries in a map of +// unicode strings. +type TextMapReader interface { + // ForeachKey returns TextMap contents via repeated calls to the `handler` + // function. If any call to `handler` returns a non-nil error, ForeachKey + // terminates and returns that error. + // + // NOTE: The backing store for the TextMapReader may contain data unrelated + // to SpanContext. As such, Inject() and Extract() implementations that + // call the TextMapWriter and TextMapReader interfaces must agree on a + // prefix or other convention to distinguish their own key:value pairs. + // + // The "foreach" callback pattern reduces unnecessary copying in some cases + // and also allows implementations to hold locks while the map is read. + ForeachKey(handler func(key, val string) error) error +} + +// TextMapCarrier allows the use of regular map[string]string +// as both TextMapWriter and TextMapReader. +type TextMapCarrier map[string]string + +// ForeachKey conforms to the TextMapReader interface. +func (c TextMapCarrier) ForeachKey(handler func(key, val string) error) error { + for k, v := range c { + if err := handler(k, v); err != nil { + return err + } + } + return nil +} + +// Set implements Set() of opentracing.TextMapWriter +func (c TextMapCarrier) Set(key, val string) { + c[key] = val +} + +// HTTPHeadersCarrier satisfies both TextMapWriter and TextMapReader. +// +// Example usage for server side: +// +// carrier := opentracing.HTTPHeadersCarrier(httpReq.Header) +// clientContext, err := tracer.Extract(opentracing.HTTPHeaders, carrier) +// +// Example usage for client side: +// +// carrier := opentracing.HTTPHeadersCarrier(httpReq.Header) +// err := tracer.Inject( +// span.Context(), +// opentracing.HTTPHeaders, +// carrier) +// +type HTTPHeadersCarrier http.Header + +// Set conforms to the TextMapWriter interface. +func (c HTTPHeadersCarrier) Set(key, val string) { + h := http.Header(c) + h.Add(key, val) +} + +// ForeachKey conforms to the TextMapReader interface. +func (c HTTPHeadersCarrier) ForeachKey(handler func(key, val string) error) error { + for k, vals := range c { + for _, v := range vals { + if err := handler(k, v); err != nil { + return err + } + } + } + return nil +} diff --git a/vendor/github.com/opentracing/opentracing-go/span.go b/vendor/github.com/opentracing/opentracing-go/span.go new file mode 100644 index 0000000000..0d3fb53418 --- /dev/null +++ b/vendor/github.com/opentracing/opentracing-go/span.go @@ -0,0 +1,189 @@ +package opentracing + +import ( + "time" + + "github.com/opentracing/opentracing-go/log" +) + +// SpanContext represents Span state that must propagate to descendant Spans and across process +// boundaries (e.g., a tuple). +type SpanContext interface { + // ForeachBaggageItem grants access to all baggage items stored in the + // SpanContext. + // The handler function will be called for each baggage key/value pair. + // The ordering of items is not guaranteed. + // + // The bool return value indicates if the handler wants to continue iterating + // through the rest of the baggage items; for example if the handler is trying to + // find some baggage item by pattern matching the name, it can return false + // as soon as the item is found to stop further iterations. + ForeachBaggageItem(handler func(k, v string) bool) +} + +// Span represents an active, un-finished span in the OpenTracing system. +// +// Spans are created by the Tracer interface. +type Span interface { + // Sets the end timestamp and finalizes Span state. + // + // With the exception of calls to Context() (which are always allowed), + // Finish() must be the last call made to any span instance, and to do + // otherwise leads to undefined behavior. + Finish() + // FinishWithOptions is like Finish() but with explicit control over + // timestamps and log data. + FinishWithOptions(opts FinishOptions) + + // Context() yields the SpanContext for this Span. Note that the return + // value of Context() is still valid after a call to Span.Finish(), as is + // a call to Span.Context() after a call to Span.Finish(). + Context() SpanContext + + // Sets or changes the operation name. + // + // Returns a reference to this Span for chaining. + SetOperationName(operationName string) Span + + // Adds a tag to the span. + // + // If there is a pre-existing tag set for `key`, it is overwritten. + // + // Tag values can be numeric types, strings, or bools. The behavior of + // other tag value types is undefined at the OpenTracing level. If a + // tracing system does not know how to handle a particular value type, it + // may ignore the tag, but shall not panic. + // + // Returns a reference to this Span for chaining. + SetTag(key string, value interface{}) Span + + // LogFields is an efficient and type-checked way to record key:value + // logging data about a Span, though the programming interface is a little + // more verbose than LogKV(). Here's an example: + // + // span.LogFields( + // log.String("event", "soft error"), + // log.String("type", "cache timeout"), + // log.Int("waited.millis", 1500)) + // + // Also see Span.FinishWithOptions() and FinishOptions.BulkLogData. + LogFields(fields ...log.Field) + + // LogKV is a concise, readable way to record key:value logging data about + // a Span, though unfortunately this also makes it less efficient and less + // type-safe than LogFields(). Here's an example: + // + // span.LogKV( + // "event", "soft error", + // "type", "cache timeout", + // "waited.millis", 1500) + // + // For LogKV (as opposed to LogFields()), the parameters must appear as + // key-value pairs, like + // + // span.LogKV(key1, val1, key2, val2, key3, val3, ...) + // + // The keys must all be strings. The values may be strings, numeric types, + // bools, Go error instances, or arbitrary structs. + // + // (Note to implementors: consider the log.InterleavedKVToFields() helper) + LogKV(alternatingKeyValues ...interface{}) + + // SetBaggageItem sets a key:value pair on this Span and its SpanContext + // that also propagates to descendants of this Span. + // + // SetBaggageItem() enables powerful functionality given a full-stack + // opentracing integration (e.g., arbitrary application data from a mobile + // app can make it, transparently, all the way into the depths of a storage + // system), and with it some powerful costs: use this feature with care. + // + // IMPORTANT NOTE #1: SetBaggageItem() will only propagate baggage items to + // *future* causal descendants of the associated Span. + // + // IMPORTANT NOTE #2: Use this thoughtfully and with care. Every key and + // value is copied into every local *and remote* child of the associated + // Span, and that can add up to a lot of network and cpu overhead. + // + // Returns a reference to this Span for chaining. + SetBaggageItem(restrictedKey, value string) Span + + // Gets the value for a baggage item given its key. Returns the empty string + // if the value isn't found in this Span. + BaggageItem(restrictedKey string) string + + // Provides access to the Tracer that created this Span. + Tracer() Tracer + + // Deprecated: use LogFields or LogKV + LogEvent(event string) + // Deprecated: use LogFields or LogKV + LogEventWithPayload(event string, payload interface{}) + // Deprecated: use LogFields or LogKV + Log(data LogData) +} + +// LogRecord is data associated with a single Span log. Every LogRecord +// instance must specify at least one Field. +type LogRecord struct { + Timestamp time.Time + Fields []log.Field +} + +// FinishOptions allows Span.FinishWithOptions callers to override the finish +// timestamp and provide log data via a bulk interface. +type FinishOptions struct { + // FinishTime overrides the Span's finish time, or implicitly becomes + // time.Now() if FinishTime.IsZero(). + // + // FinishTime must resolve to a timestamp that's >= the Span's StartTime + // (per StartSpanOptions). + FinishTime time.Time + + // LogRecords allows the caller to specify the contents of many LogFields() + // calls with a single slice. May be nil. + // + // None of the LogRecord.Timestamp values may be .IsZero() (i.e., they must + // be set explicitly). Also, they must be >= the Span's start timestamp and + // <= the FinishTime (or time.Now() if FinishTime.IsZero()). Otherwise the + // behavior of FinishWithOptions() is undefined. + // + // If specified, the caller hands off ownership of LogRecords at + // FinishWithOptions() invocation time. + // + // If specified, the (deprecated) BulkLogData must be nil or empty. + LogRecords []LogRecord + + // BulkLogData is DEPRECATED. + BulkLogData []LogData +} + +// LogData is DEPRECATED +type LogData struct { + Timestamp time.Time + Event string + Payload interface{} +} + +// ToLogRecord converts a deprecated LogData to a non-deprecated LogRecord +func (ld *LogData) ToLogRecord() LogRecord { + var literalTimestamp time.Time + if ld.Timestamp.IsZero() { + literalTimestamp = time.Now() + } else { + literalTimestamp = ld.Timestamp + } + rval := LogRecord{ + Timestamp: literalTimestamp, + } + if ld.Payload == nil { + rval.Fields = []log.Field{ + log.String("event", ld.Event), + } + } else { + rval.Fields = []log.Field{ + log.String("event", ld.Event), + log.Object("payload", ld.Payload), + } + } + return rval +} diff --git a/vendor/github.com/opentracing/opentracing-go/tracer.go b/vendor/github.com/opentracing/opentracing-go/tracer.go new file mode 100644 index 0000000000..7bca1f7367 --- /dev/null +++ b/vendor/github.com/opentracing/opentracing-go/tracer.go @@ -0,0 +1,305 @@ +package opentracing + +import "time" + +// Tracer is a simple, thin interface for Span creation and SpanContext +// propagation. +type Tracer interface { + + // Create, start, and return a new Span with the given `operationName` and + // incorporate the given StartSpanOption `opts`. (Note that `opts` borrows + // from the "functional options" pattern, per + // http://dave.cheney.net/2014/10/17/functional-options-for-friendly-apis) + // + // A Span with no SpanReference options (e.g., opentracing.ChildOf() or + // opentracing.FollowsFrom()) becomes the root of its own trace. + // + // Examples: + // + // var tracer opentracing.Tracer = ... + // + // // The root-span case: + // sp := tracer.StartSpan("GetFeed") + // + // // The vanilla child span case: + // sp := tracer.StartSpan( + // "GetFeed", + // opentracing.ChildOf(parentSpan.Context())) + // + // // All the bells and whistles: + // sp := tracer.StartSpan( + // "GetFeed", + // opentracing.ChildOf(parentSpan.Context()), + // opentracing.Tag{"user_agent", loggedReq.UserAgent}, + // opentracing.StartTime(loggedReq.Timestamp), + // ) + // + StartSpan(operationName string, opts ...StartSpanOption) Span + + // Inject() takes the `sm` SpanContext instance and injects it for + // propagation within `carrier`. The actual type of `carrier` depends on + // the value of `format`. + // + // OpenTracing defines a common set of `format` values (see BuiltinFormat), + // and each has an expected carrier type. + // + // Other packages may declare their own `format` values, much like the keys + // used by `context.Context` (see + // https://godoc.org/golang.org/x/net/context#WithValue). + // + // Example usage (sans error handling): + // + // carrier := opentracing.HTTPHeadersCarrier(httpReq.Header) + // err := tracer.Inject( + // span.Context(), + // opentracing.HTTPHeaders, + // carrier) + // + // NOTE: All opentracing.Tracer implementations MUST support all + // BuiltinFormats. + // + // Implementations may return opentracing.ErrUnsupportedFormat if `format` + // is not supported by (or not known by) the implementation. + // + // Implementations may return opentracing.ErrInvalidCarrier or any other + // implementation-specific error if the format is supported but injection + // fails anyway. + // + // See Tracer.Extract(). + Inject(sm SpanContext, format interface{}, carrier interface{}) error + + // Extract() returns a SpanContext instance given `format` and `carrier`. + // + // OpenTracing defines a common set of `format` values (see BuiltinFormat), + // and each has an expected carrier type. + // + // Other packages may declare their own `format` values, much like the keys + // used by `context.Context` (see + // https://godoc.org/golang.org/x/net/context#WithValue). + // + // Example usage (with StartSpan): + // + // + // carrier := opentracing.HTTPHeadersCarrier(httpReq.Header) + // clientContext, err := tracer.Extract(opentracing.HTTPHeaders, carrier) + // + // // ... assuming the ultimate goal here is to resume the trace with a + // // server-side Span: + // var serverSpan opentracing.Span + // if err == nil { + // span = tracer.StartSpan( + // rpcMethodName, ext.RPCServerOption(clientContext)) + // } else { + // span = tracer.StartSpan(rpcMethodName) + // } + // + // + // NOTE: All opentracing.Tracer implementations MUST support all + // BuiltinFormats. + // + // Return values: + // - A successful Extract returns a SpanContext instance and a nil error + // - If there was simply no SpanContext to extract in `carrier`, Extract() + // returns (nil, opentracing.ErrSpanContextNotFound) + // - If `format` is unsupported or unrecognized, Extract() returns (nil, + // opentracing.ErrUnsupportedFormat) + // - If there are more fundamental problems with the `carrier` object, + // Extract() may return opentracing.ErrInvalidCarrier, + // opentracing.ErrSpanContextCorrupted, or implementation-specific + // errors. + // + // See Tracer.Inject(). + Extract(format interface{}, carrier interface{}) (SpanContext, error) +} + +// StartSpanOptions allows Tracer.StartSpan() callers and implementors a +// mechanism to override the start timestamp, specify Span References, and make +// a single Tag or multiple Tags available at Span start time. +// +// StartSpan() callers should look at the StartSpanOption interface and +// implementations available in this package. +// +// Tracer implementations can convert a slice of `StartSpanOption` instances +// into a `StartSpanOptions` struct like so: +// +// func StartSpan(opName string, opts ...opentracing.StartSpanOption) { +// sso := opentracing.StartSpanOptions{} +// for _, o := range opts { +// o.Apply(&sso) +// } +// ... +// } +// +type StartSpanOptions struct { + // Zero or more causal references to other Spans (via their SpanContext). + // If empty, start a "root" Span (i.e., start a new trace). + References []SpanReference + + // StartTime overrides the Span's start time, or implicitly becomes + // time.Now() if StartTime.IsZero(). + StartTime time.Time + + // Tags may have zero or more entries; the restrictions on map values are + // identical to those for Span.SetTag(). May be nil. + // + // If specified, the caller hands off ownership of Tags at + // StartSpan() invocation time. + Tags map[string]interface{} +} + +// StartSpanOption instances (zero or more) may be passed to Tracer.StartSpan. +// +// StartSpanOption borrows from the "functional options" pattern, per +// http://dave.cheney.net/2014/10/17/functional-options-for-friendly-apis +type StartSpanOption interface { + Apply(*StartSpanOptions) +} + +// SpanReferenceType is an enum type describing different categories of +// relationships between two Spans. If Span-2 refers to Span-1, the +// SpanReferenceType describes Span-1 from Span-2's perspective. For example, +// ChildOfRef means that Span-1 created Span-2. +// +// NOTE: Span-1 and Span-2 do *not* necessarily depend on each other for +// completion; e.g., Span-2 may be part of a background job enqueued by Span-1, +// or Span-2 may be sitting in a distributed queue behind Span-1. +type SpanReferenceType int + +const ( + // ChildOfRef refers to a parent Span that caused *and* somehow depends + // upon the new child Span. Often (but not always), the parent Span cannot + // finish until the child Span does. + // + // An timing diagram for a ChildOfRef that's blocked on the new Span: + // + // [-Parent Span---------] + // [-Child Span----] + // + // See http://opentracing.io/spec/ + // + // See opentracing.ChildOf() + ChildOfRef SpanReferenceType = iota + + // FollowsFromRef refers to a parent Span that does not depend in any way + // on the result of the new child Span. For instance, one might use + // FollowsFromRefs to describe pipeline stages separated by queues, + // or a fire-and-forget cache insert at the tail end of a web request. + // + // A FollowsFromRef Span is part of the same logical trace as the new Span: + // i.e., the new Span is somehow caused by the work of its FollowsFromRef. + // + // All of the following could be valid timing diagrams for children that + // "FollowFrom" a parent. + // + // [-Parent Span-] [-Child Span-] + // + // + // [-Parent Span--] + // [-Child Span-] + // + // + // [-Parent Span-] + // [-Child Span-] + // + // See http://opentracing.io/spec/ + // + // See opentracing.FollowsFrom() + FollowsFromRef +) + +// SpanReference is a StartSpanOption that pairs a SpanReferenceType and a +// referenced SpanContext. See the SpanReferenceType documentation for +// supported relationships. If SpanReference is created with +// ReferencedContext==nil, it has no effect. Thus it allows for a more concise +// syntax for starting spans: +// +// sc, _ := tracer.Extract(someFormat, someCarrier) +// span := tracer.StartSpan("operation", opentracing.ChildOf(sc)) +// +// The `ChildOf(sc)` option above will not panic if sc == nil, it will just +// not add the parent span reference to the options. +type SpanReference struct { + Type SpanReferenceType + ReferencedContext SpanContext +} + +// Apply satisfies the StartSpanOption interface. +func (r SpanReference) Apply(o *StartSpanOptions) { + if r.ReferencedContext != nil { + o.References = append(o.References, r) + } +} + +// ChildOf returns a StartSpanOption pointing to a dependent parent span. +// If sc == nil, the option has no effect. +// +// See ChildOfRef, SpanReference +func ChildOf(sc SpanContext) SpanReference { + return SpanReference{ + Type: ChildOfRef, + ReferencedContext: sc, + } +} + +// FollowsFrom returns a StartSpanOption pointing to a parent Span that caused +// the child Span but does not directly depend on its result in any way. +// If sc == nil, the option has no effect. +// +// See FollowsFromRef, SpanReference +func FollowsFrom(sc SpanContext) SpanReference { + return SpanReference{ + Type: FollowsFromRef, + ReferencedContext: sc, + } +} + +// StartTime is a StartSpanOption that sets an explicit start timestamp for the +// new Span. +type StartTime time.Time + +// Apply satisfies the StartSpanOption interface. +func (t StartTime) Apply(o *StartSpanOptions) { + o.StartTime = time.Time(t) +} + +// Tags are a generic map from an arbitrary string key to an opaque value type. +// The underlying tracing system is responsible for interpreting and +// serializing the values. +type Tags map[string]interface{} + +// Apply satisfies the StartSpanOption interface. +func (t Tags) Apply(o *StartSpanOptions) { + if o.Tags == nil { + o.Tags = make(map[string]interface{}) + } + for k, v := range t { + o.Tags[k] = v + } +} + +// Tag may be passed as a StartSpanOption to add a tag to new spans, +// or its Set method may be used to apply the tag to an existing Span, +// for example: +// +// tracer.StartSpan("opName", Tag{"Key", value}) +// +// or +// +// Tag{"key", value}.Set(span) +type Tag struct { + Key string + Value interface{} +} + +// Apply satisfies the StartSpanOption interface. +func (t Tag) Apply(o *StartSpanOptions) { + if o.Tags == nil { + o.Tags = make(map[string]interface{}) + } + o.Tags[t.Key] = t.Value +} + +// Set applies the tag to an existing Span. +func (t Tag) Set(s Span) { + s.SetTag(t.Key, t.Value) +} diff --git a/vendor/github.com/syndtr/goleveldb/leveldb/db.go b/vendor/github.com/syndtr/goleveldb/leveldb/db.go index 3655418ad3..e7ac065418 100644 --- a/vendor/github.com/syndtr/goleveldb/leveldb/db.go +++ b/vendor/github.com/syndtr/goleveldb/leveldb/db.go @@ -35,6 +35,7 @@ type DB struct { // Stats. Need 64-bit alignment. cWriteDelay int64 // The cumulative duration of write delays cWriteDelayN int32 // The cumulative number of write delays + inWritePaused int32 // The indicator whether write operation is paused by compaction aliveSnaps, aliveIters int32 // Session. @@ -967,7 +968,8 @@ func (db *DB) GetProperty(name string) (value string, err error) { float64(db.s.stor.writes())/1048576.0) case p == "writedelay": writeDelayN, writeDelay := atomic.LoadInt32(&db.cWriteDelayN), time.Duration(atomic.LoadInt64(&db.cWriteDelay)) - value = fmt.Sprintf("DelayN:%d Delay:%s", writeDelayN, writeDelay) + paused := atomic.LoadInt32(&db.inWritePaused) == 1 + value = fmt.Sprintf("DelayN:%d Delay:%s Paused:%t", writeDelayN, writeDelay, paused) case p == "sstables": for level, tables := range v.levels { value += fmt.Sprintf("--- level %d ---\n", level) @@ -996,6 +998,75 @@ func (db *DB) GetProperty(name string) (value string, err error) { return } +// DBStats is database statistics. +type DBStats struct { + WriteDelayCount int32 + WriteDelayDuration time.Duration + WritePaused bool + + AliveSnapshots int32 + AliveIterators int32 + + IOWrite uint64 + IORead uint64 + + BlockCacheSize int + OpenedTablesCount int + + LevelSizes []int64 + LevelTablesCounts []int + LevelRead []int64 + LevelWrite []int64 + LevelDurations []time.Duration +} + +// Stats populates s with database statistics. +func (db *DB) Stats(s *DBStats) error { + err := db.ok() + if err != nil { + return err + } + + s.IORead = db.s.stor.reads() + s.IOWrite = db.s.stor.writes() + s.WriteDelayCount = atomic.LoadInt32(&db.cWriteDelayN) + s.WriteDelayDuration = time.Duration(atomic.LoadInt64(&db.cWriteDelay)) + s.WritePaused = atomic.LoadInt32(&db.inWritePaused) == 1 + + s.OpenedTablesCount = db.s.tops.cache.Size() + if db.s.tops.bcache != nil { + s.BlockCacheSize = db.s.tops.bcache.Size() + } else { + s.BlockCacheSize = 0 + } + + s.AliveIterators = atomic.LoadInt32(&db.aliveIters) + s.AliveSnapshots = atomic.LoadInt32(&db.aliveSnaps) + + s.LevelDurations = s.LevelDurations[:0] + s.LevelRead = s.LevelRead[:0] + s.LevelWrite = s.LevelWrite[:0] + s.LevelSizes = s.LevelSizes[:0] + s.LevelTablesCounts = s.LevelTablesCounts[:0] + + v := db.s.version() + defer v.release() + + for level, tables := range v.levels { + duration, read, write := db.compStats.getStat(level) + if len(tables) == 0 && duration == 0 { + continue + } + s.LevelDurations = append(s.LevelDurations, duration) + s.LevelRead = append(s.LevelRead, read) + s.LevelWrite = append(s.LevelWrite, write) + s.LevelSizes = append(s.LevelSizes, tables.size()) + s.LevelTablesCounts = append(s.LevelTablesCounts, len(tables)) + } + + return nil +} + // SizeOf calculates approximate sizes of the given key ranges. // The length of the returned sizes are equal with the length of the given // ranges. The returned sizes measure storage space usage, so if the user diff --git a/vendor/github.com/syndtr/goleveldb/leveldb/db_compaction.go b/vendor/github.com/syndtr/goleveldb/leveldb/db_compaction.go index b6563e87e4..28e50906ad 100644 --- a/vendor/github.com/syndtr/goleveldb/leveldb/db_compaction.go +++ b/vendor/github.com/syndtr/goleveldb/leveldb/db_compaction.go @@ -640,6 +640,16 @@ func (db *DB) tableNeedCompaction() bool { return v.needCompaction() } +// resumeWrite returns an indicator whether we should resume write operation if enough level0 files are compacted. +func (db *DB) resumeWrite() bool { + v := db.s.version() + defer v.release() + if v.tLen(0) < db.s.o.GetWriteL0PauseTrigger() { + return true + } + return false +} + func (db *DB) pauseCompaction(ch chan<- struct{}) { select { case ch <- struct{}{}: @@ -653,6 +663,7 @@ type cCmd interface { } type cAuto struct { + // Note for table compaction, an empty ackC represents it's a compaction waiting command. ackC chan<- error } @@ -765,8 +776,10 @@ func (db *DB) mCompaction() { } func (db *DB) tCompaction() { - var x cCmd - var ackQ []cCmd + var ( + x cCmd + ackQ, waitQ []cCmd + ) defer func() { if x := recover(); x != nil { @@ -778,6 +791,10 @@ func (db *DB) tCompaction() { ackQ[i].ack(ErrClosed) ackQ[i] = nil } + for i := range waitQ { + waitQ[i].ack(ErrClosed) + waitQ[i] = nil + } if x != nil { x.ack(ErrClosed) } @@ -795,12 +812,25 @@ func (db *DB) tCompaction() { return default: } + // Resume write operation as soon as possible. + if len(waitQ) > 0 && db.resumeWrite() { + for i := range waitQ { + waitQ[i].ack(nil) + waitQ[i] = nil + } + waitQ = waitQ[:0] + } } else { for i := range ackQ { ackQ[i].ack(nil) ackQ[i] = nil } ackQ = ackQ[:0] + for i := range waitQ { + waitQ[i].ack(nil) + waitQ[i] = nil + } + waitQ = waitQ[:0] select { case x = <-db.tcompCmdC: case ch := <-db.tcompPauseC: @@ -813,7 +843,11 @@ func (db *DB) tCompaction() { if x != nil { switch cmd := x.(type) { case cAuto: - ackQ = append(ackQ, x) + if cmd.ackC != nil { + waitQ = append(waitQ, x) + } else { + ackQ = append(ackQ, x) + } case cRange: x.ack(db.tableRangeCompaction(cmd.level, cmd.min, cmd.max)) default: diff --git a/vendor/github.com/syndtr/goleveldb/leveldb/db_write.go b/vendor/github.com/syndtr/goleveldb/leveldb/db_write.go index 31f4bc5efc..db0c1bece1 100644 --- a/vendor/github.com/syndtr/goleveldb/leveldb/db_write.go +++ b/vendor/github.com/syndtr/goleveldb/leveldb/db_write.go @@ -89,7 +89,11 @@ func (db *DB) flush(n int) (mdb *memDB, mdbFree int, err error) { return false case tLen >= pauseTrigger: delayed = true + // Set the write paused flag explicitly. + atomic.StoreInt32(&db.inWritePaused, 1) err = db.compTriggerWait(db.tcompCmdC) + // Unset the write paused flag. + atomic.StoreInt32(&db.inWritePaused, 0) if err != nil { return false } diff --git a/vendor/github.com/syndtr/goleveldb/leveldb/storage/file_storage.go b/vendor/github.com/syndtr/goleveldb/leveldb/storage/file_storage.go index 1189decac6..9ba71fd6d1 100644 --- a/vendor/github.com/syndtr/goleveldb/leveldb/storage/file_storage.go +++ b/vendor/github.com/syndtr/goleveldb/leveldb/storage/file_storage.go @@ -9,10 +9,12 @@ package storage import ( "errors" "fmt" + "io" "io/ioutil" "os" "path/filepath" "runtime" + "sort" "strconv" "strings" "sync" @@ -42,6 +44,30 @@ func (lock *fileStorageLock) Unlock() { } } +type int64Slice []int64 + +func (p int64Slice) Len() int { return len(p) } +func (p int64Slice) Less(i, j int) bool { return p[i] < p[j] } +func (p int64Slice) Swap(i, j int) { p[i], p[j] = p[j], p[i] } + +func writeFileSynced(filename string, data []byte, perm os.FileMode) error { + f, err := os.OpenFile(filename, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm) + if err != nil { + return err + } + n, err := f.Write(data) + if err == nil && n < len(data) { + err = io.ErrShortWrite + } + if err1 := f.Sync(); err == nil { + err = err1 + } + if err1 := f.Close(); err == nil { + err = err1 + } + return err +} + const logSizeThreshold = 1024 * 1024 // 1 MiB // fileStorage is a file-system backed storage. @@ -60,7 +86,7 @@ type fileStorage struct { day int } -// OpenFile returns a new filesytem-backed storage implementation with the given +// OpenFile returns a new filesystem-backed storage implementation with the given // path. This also acquire a file lock, so any subsequent attempt to open the // same path will fail. // @@ -189,7 +215,8 @@ func (fs *fileStorage) doLog(t time.Time, str string) { // write fs.buf = append(fs.buf, []byte(str)...) fs.buf = append(fs.buf, '\n') - fs.logw.Write(fs.buf) + n, _ := fs.logw.Write(fs.buf) + fs.logSize += int64(n) } func (fs *fileStorage) Log(str string) { @@ -210,7 +237,46 @@ func (fs *fileStorage) log(str string) { } } -func (fs *fileStorage) SetMeta(fd FileDesc) (err error) { +func (fs *fileStorage) setMeta(fd FileDesc) error { + content := fsGenName(fd) + "\n" + // Check and backup old CURRENT file. + currentPath := filepath.Join(fs.path, "CURRENT") + if _, err := os.Stat(currentPath); err == nil { + b, err := ioutil.ReadFile(currentPath) + if err != nil { + fs.log(fmt.Sprintf("backup CURRENT: %v", err)) + return err + } + if string(b) == content { + // Content not changed, do nothing. + return nil + } + if err := writeFileSynced(currentPath+".bak", b, 0644); err != nil { + fs.log(fmt.Sprintf("backup CURRENT: %v", err)) + return err + } + } else if !os.IsNotExist(err) { + return err + } + path := fmt.Sprintf("%s.%d", filepath.Join(fs.path, "CURRENT"), fd.Num) + if err := writeFileSynced(path, []byte(content), 0644); err != nil { + fs.log(fmt.Sprintf("create CURRENT.%d: %v", fd.Num, err)) + return err + } + // Replace CURRENT file. + if err := rename(path, currentPath); err != nil { + fs.log(fmt.Sprintf("rename CURRENT.%d: %v", fd.Num, err)) + return err + } + // Sync root directory. + if err := syncDir(fs.path); err != nil { + fs.log(fmt.Sprintf("syncDir: %v", err)) + return err + } + return nil +} + +func (fs *fileStorage) SetMeta(fd FileDesc) error { if !FileDescOk(fd) { return ErrInvalidFile } @@ -223,44 +289,10 @@ func (fs *fileStorage) SetMeta(fd FileDesc) (err error) { if fs.open < 0 { return ErrClosed } - defer func() { - if err != nil { - fs.log(fmt.Sprintf("CURRENT: %v", err)) - } - }() - path := fmt.Sprintf("%s.%d", filepath.Join(fs.path, "CURRENT"), fd.Num) - w, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644) - if err != nil { - return - } - _, err = fmt.Fprintln(w, fsGenName(fd)) - if err != nil { - fs.log(fmt.Sprintf("write CURRENT.%d: %v", fd.Num, err)) - return - } - if err = w.Sync(); err != nil { - fs.log(fmt.Sprintf("flush CURRENT.%d: %v", fd.Num, err)) - return - } - if err = w.Close(); err != nil { - fs.log(fmt.Sprintf("close CURRENT.%d: %v", fd.Num, err)) - return - } - if err != nil { - return - } - if err = rename(path, filepath.Join(fs.path, "CURRENT")); err != nil { - fs.log(fmt.Sprintf("rename CURRENT.%d: %v", fd.Num, err)) - return - } - // Sync root directory. - if err = syncDir(fs.path); err != nil { - fs.log(fmt.Sprintf("syncDir: %v", err)) - } - return + return fs.setMeta(fd) } -func (fs *fileStorage) GetMeta() (fd FileDesc, err error) { +func (fs *fileStorage) GetMeta() (FileDesc, error) { fs.mu.Lock() defer fs.mu.Unlock() if fs.open < 0 { @@ -268,7 +300,7 @@ func (fs *fileStorage) GetMeta() (fd FileDesc, err error) { } dir, err := os.Open(fs.path) if err != nil { - return + return FileDesc{}, err } names, err := dir.Readdirnames(0) // Close the dir first before checking for Readdirnames error. @@ -276,94 +308,134 @@ func (fs *fileStorage) GetMeta() (fd FileDesc, err error) { fs.log(fmt.Sprintf("close dir: %v", ce)) } if err != nil { - return + return FileDesc{}, err } - // Find latest CURRENT file. - var rem []string - var pend bool - var cerr error + // Try this in order: + // - CURRENT.[0-9]+ ('pending rename' file, descending order) + // - CURRENT + // - CURRENT.bak + // + // Skip corrupted file or file that point to a missing target file. + type currentFile struct { + name string + fd FileDesc + } + tryCurrent := func(name string) (*currentFile, error) { + b, err := ioutil.ReadFile(filepath.Join(fs.path, name)) + if err != nil { + if os.IsNotExist(err) { + err = os.ErrNotExist + } + return nil, err + } + var fd FileDesc + if len(b) < 1 || b[len(b)-1] != '\n' || !fsParseNamePtr(string(b[:len(b)-1]), &fd) { + fs.log(fmt.Sprintf("%s: corrupted content: %q", name, b)) + err := &ErrCorrupted{ + Err: errors.New("leveldb/storage: corrupted or incomplete CURRENT file"), + } + return nil, err + } + if _, err := os.Stat(filepath.Join(fs.path, fsGenName(fd))); err != nil { + if os.IsNotExist(err) { + fs.log(fmt.Sprintf("%s: missing target file: %s", name, fd)) + err = os.ErrNotExist + } + return nil, err + } + return ¤tFile{name: name, fd: fd}, nil + } + tryCurrents := func(names []string) (*currentFile, error) { + var ( + cur *currentFile + // Last corruption error. + lastCerr error + ) + for _, name := range names { + var err error + cur, err = tryCurrent(name) + if err == nil { + break + } else if err == os.ErrNotExist { + // Fallback to the next file. + } else if isCorrupted(err) { + lastCerr = err + // Fallback to the next file. + } else { + // In case the error is due to permission, etc. + return nil, err + } + } + if cur == nil { + err := os.ErrNotExist + if lastCerr != nil { + err = lastCerr + } + return nil, err + } + return cur, nil + } + + // Try 'pending rename' files. + var nums []int64 for _, name := range names { - if strings.HasPrefix(name, "CURRENT") { - pend1 := len(name) > 7 - var pendNum int64 - // Make sure it is valid name for a CURRENT file, otherwise skip it. - if pend1 { - if name[7] != '.' || len(name) < 9 { - fs.log(fmt.Sprintf("skipping %s: invalid file name", name)) - continue - } - var e1 error - if pendNum, e1 = strconv.ParseInt(name[8:], 10, 0); e1 != nil { - fs.log(fmt.Sprintf("skipping %s: invalid file num: %v", name, e1)) - continue - } + if strings.HasPrefix(name, "CURRENT.") && name != "CURRENT.bak" { + i, err := strconv.ParseInt(name[8:], 10, 64) + if err == nil { + nums = append(nums, i) } - path := filepath.Join(fs.path, name) - r, e1 := os.OpenFile(path, os.O_RDONLY, 0) - if e1 != nil { - return FileDesc{}, e1 - } - b, e1 := ioutil.ReadAll(r) - if e1 != nil { - r.Close() - return FileDesc{}, e1 - } - var fd1 FileDesc - if len(b) < 1 || b[len(b)-1] != '\n' || !fsParseNamePtr(string(b[:len(b)-1]), &fd1) { - fs.log(fmt.Sprintf("skipping %s: corrupted or incomplete", name)) - if pend1 { - rem = append(rem, name) - } - if !pend1 || cerr == nil { - metaFd, _ := fsParseName(name) - cerr = &ErrCorrupted{ - Fd: metaFd, - Err: errors.New("leveldb/storage: corrupted or incomplete meta file"), + } + } + var ( + pendCur *currentFile + pendErr = os.ErrNotExist + pendNames []string + ) + if len(nums) > 0 { + sort.Sort(sort.Reverse(int64Slice(nums))) + pendNames = make([]string, len(nums)) + for i, num := range nums { + pendNames[i] = fmt.Sprintf("CURRENT.%d", num) + } + pendCur, pendErr = tryCurrents(pendNames) + if pendErr != nil && pendErr != os.ErrNotExist && !isCorrupted(pendErr) { + return FileDesc{}, pendErr + } + } + + // Try CURRENT and CURRENT.bak. + curCur, curErr := tryCurrents([]string{"CURRENT", "CURRENT.bak"}) + if curErr != nil && curErr != os.ErrNotExist && !isCorrupted(curErr) { + return FileDesc{}, curErr + } + + // pendCur takes precedence, but guards against obsolete pendCur. + if pendCur != nil && (curCur == nil || pendCur.fd.Num > curCur.fd.Num) { + curCur = pendCur + } + + if curCur != nil { + // Restore CURRENT file to proper state. + if !fs.readOnly && (curCur.name != "CURRENT" || len(pendNames) != 0) { + // Ignore setMeta errors, however don't delete obsolete files if we + // catch error. + if err := fs.setMeta(curCur.fd); err == nil { + // Remove 'pending rename' files. + for _, name := range pendNames { + if err := os.Remove(filepath.Join(fs.path, name)); err != nil { + fs.log(fmt.Sprintf("remove %s: %v", name, err)) } } - } else if pend1 && pendNum != fd1.Num { - fs.log(fmt.Sprintf("skipping %s: inconsistent pending-file num: %d vs %d", name, pendNum, fd1.Num)) - rem = append(rem, name) - } else if fd1.Num < fd.Num { - fs.log(fmt.Sprintf("skipping %s: obsolete", name)) - if pend1 { - rem = append(rem, name) - } - } else { - fd = fd1 - pend = pend1 - } - if err := r.Close(); err != nil { - fs.log(fmt.Sprintf("close %s: %v", name, err)) } } + return curCur.fd, nil } - // Don't remove any files if there is no valid CURRENT file. - if fd.Zero() { - if cerr != nil { - err = cerr - } else { - err = os.ErrNotExist - } - return + + // Nothing found. + if isCorrupted(pendErr) { + return FileDesc{}, pendErr } - if !fs.readOnly { - // Rename pending CURRENT file to an effective CURRENT. - if pend { - path := fmt.Sprintf("%s.%d", filepath.Join(fs.path, "CURRENT"), fd.Num) - if err := rename(path, filepath.Join(fs.path, "CURRENT")); err != nil { - fs.log(fmt.Sprintf("CURRENT.%d -> CURRENT: %v", fd.Num, err)) - } - } - // Remove obsolete or incomplete pending CURRENT files. - for _, name := range rem { - path := filepath.Join(fs.path, name) - if err := os.Remove(path); err != nil { - fs.log(fmt.Sprintf("remove %s: %v", name, err)) - } - } - } - return + return FileDesc{}, curErr } func (fs *fileStorage) List(ft FileType) (fds []FileDesc, err error) { diff --git a/vendor/github.com/syndtr/goleveldb/leveldb/storage/file_storage_unix.go b/vendor/github.com/syndtr/goleveldb/leveldb/storage/file_storage_unix.go index 7e29915379..d75f66a9ef 100644 --- a/vendor/github.com/syndtr/goleveldb/leveldb/storage/file_storage_unix.go +++ b/vendor/github.com/syndtr/goleveldb/leveldb/storage/file_storage_unix.go @@ -67,13 +67,25 @@ func isErrInvalid(err error) bool { if err == os.ErrInvalid { return true } + // Go < 1.8 if syserr, ok := err.(*os.SyscallError); ok && syserr.Err == syscall.EINVAL { return true } + // Go >= 1.8 returns *os.PathError instead + if patherr, ok := err.(*os.PathError); ok && patherr.Err == syscall.EINVAL { + return true + } return false } func syncDir(name string) error { + // As per fsync manpage, Linux seems to expect fsync on directory, however + // some system don't support this, so we will ignore syscall.EINVAL. + // + // From fsync(2): + // Calling fsync() does not necessarily ensure that the entry in the + // directory containing the file has also reached disk. For that an + // explicit fsync() on a file descriptor for the directory is also needed. f, err := os.Open(name) if err != nil { return err diff --git a/vendor/github.com/syndtr/goleveldb/leveldb/storage/storage.go b/vendor/github.com/syndtr/goleveldb/leveldb/storage/storage.go index c16bce6b66..4e4a724258 100644 --- a/vendor/github.com/syndtr/goleveldb/leveldb/storage/storage.go +++ b/vendor/github.com/syndtr/goleveldb/leveldb/storage/storage.go @@ -55,6 +55,14 @@ type ErrCorrupted struct { Err error } +func isCorrupted(err error) bool { + switch err.(type) { + case *ErrCorrupted: + return true + } + return false +} + func (e *ErrCorrupted) Error() string { if !e.Fd.Zero() { return fmt.Sprintf("%v [file=%v]", e.Err, e.Fd) diff --git a/vendor/github.com/uber/jaeger-client-go/CHANGELOG.md b/vendor/github.com/uber/jaeger-client-go/CHANGELOG.md new file mode 100644 index 0000000000..28e2c24255 --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/CHANGELOG.md @@ -0,0 +1,186 @@ +Changes by Version +================== + +2.15.0 (unreleased) +------------------- + +- nothing yet + + +2.14.0 (2018-04-30) +------------------- + +- Support throttling for debug traces (#274) +- Remove dependency on Apache Thrift (#303) +- Remove dependency on tchannel (#295) (#294) +- Test with Go 1.9 (#298) + + +2.13.0 (2018-04-15) +------------------- + +- Use value receiver for config.NewTracer() (#283) +- Lock span during jaeger thrift conversion (#273) +- Fix the RemotelyControlledSampler so that it terminates go-routine on Close() (#260) +- Added support for client configuration via env vars (#275) +- Allow overriding sampler in the Config (#270) + + +2.12.0 (2018-03-14) +------------------- + +- Use lock when retrieving span.Context() (#268) +- Add Configuration support for custom Injector and Extractor (#263) + + +2.11.2 (2018-01-12) +------------------- + +- Add Gopkg.toml to allow using the lib with `dep` + + +2.11.1 (2018-01-03) +------------------- + +- Do not enqueue spans after Reporter is closed (#235, #245) +- Change default flush interval to 1sec (#243) + + +2.11.0 (2017-11-27) +------------------- + +- Normalize metric names and tags to be compatible with Prometheus (#222) + + +2.10.0 (2017-11-14) +------------------- + +- Support custom tracing headers (#176) +- Add BaggageRestrictionManager (#178) and RemoteBaggageRestrictionManager (#182) +- Do not coerce baggage keys to lower case (#196) +- Log span name when span cannot be reported (#198) +- Add option to enable gen128Bit for tracer (#193) and allow custom generator for high bits of trace ID (#219) + + +2.9.0 (2017-07-29) +------------------ + +- Pin thrift <= 0.10 (#179) +- Introduce a parallel interface ContribObserver (#159) + + +2.8.0 (2017-07-05) +------------------ + +- Drop `jaeger.` prefix from `jaeger.hostname` process-level tag +- Add options to set tracer tags + + +2.7.0 (2017-06-21) +------------------ + +- Fix rate limiter balance [#135](https://github.com/uber/jaeger-client-go/pull/135) [#140](https://github.com/uber/jaeger-client-go/pull/140) +- Default client to send Jaeger.thrift [#147](https://github.com/uber/jaeger-client-go/pull/147) +- Save baggage in span [#153](https://github.com/uber/jaeger-client-go/pull/153) +- Move reporter.queueLength to the top of the struct to guarantee 64bit alignment [#158](https://github.com/uber/jaeger-client-go/pull/158) +- Support HTTP transport with jaeger.thrift [#161](https://github.com/uber/jaeger-client-go/pull/161) + + +2.6.0 (2017-03-28) +------------------ + +- Add config option to initialize RPC Metrics feature + + +2.5.0 (2017-03-23) +------------------ + +- Split request latency metric by success/failure [#123](https://github.com/uber/jaeger-client-go/pull/123) +- Add mutex to adaptive sampler and fix race condition [#124](https://github.com/uber/jaeger-client-go/pull/124) +- Fix rate limiter panic [#125](https://github.com/uber/jaeger-client-go/pull/125) + + +2.4.0 (2017-03-21) +------------------ + +- Remove `_ms` suffix from request latency metric name [#121](https://github.com/uber/jaeger-client-go/pull/121) +- Rename all metrics to "request" and "http_request" and use tags for other dimensions [#121](https://github.com/uber/jaeger-client-go/pull/121) + + +2.3.0 (2017-03-20) +------------------ + +- Make Span type public to allow access to non-std methods for testing [#117](https://github.com/uber/jaeger-client-go/pull/117) +- Add a structured way to extract traces for logging with zap [#118](https://github.com/uber/jaeger-client-go/pull/118) + + +2.2.1 (2017-03-14) +------------------ + +- Fix panic caused by updating the remote sampler from adaptive sampler to any other sampler type (https://github.com/uber/jaeger-client-go/pull/111) + + +2.2.0 (2017-03-10) +------------------ + +- Introduce Observer and SpanObserver (https://github.com/uber/jaeger-client-go/pull/94) +- Add RPC metrics emitter as Observer/SpanObserver (https://github.com/uber/jaeger-client-go/pull/103) + + +2.1.2 (2017-02-27) +------------------- + +- Fix leaky bucket bug (https://github.com/uber/jaeger-client-go/pull/99) +- Fix zap logger Infof (https://github.com/uber/jaeger-client-go/pull/100) +- Add tracer initialization godoc examples + + +2.1.1 (2017-02-21) +------------------- + +- Fix inefficient usage of zap.Logger + + +2.1.0 (2017-02-17) +------------------- + +- Add adapter for zap.Logger (https://github.com/uber-go/zap) +- Move logging API to ./log/ package + + +2.0.0 (2017-02-08) +------------------- + +- Support Adaptive Sampling +- Support 128bit Trace IDs +- Change trace/span IDs from uint64 to strong types TraceID and SpanID +- Add Zipkin HTTP B3 Propagation format support #72 +- Rip out existing metrics and use github.com/uber/jaeger-lib/metrics +- Change API for tracer, reporter, sampler initialization + + +1.6.0 (2016-10-14) +------------------- + +- Add Zipkin HTTP transport +- Support external baggage via jaeger-baggage header +- Unpin Thrift version, keep to master + + +1.5.1 (2016-09-27) +------------------- + +- Relax dependency on opentracing to ^1 + + +1.5.0 (2016-09-27) +------------------- + +- Upgrade to opentracing-go 1.0 +- Support KV logging for Spans + + +1.4.0 (2016-09-14) +------------------- + +- Support debug traces via HTTP header "jaeger-debug-id" diff --git a/vendor/github.com/uber/jaeger-client-go/CONTRIBUTING.md b/vendor/github.com/uber/jaeger-client-go/CONTRIBUTING.md new file mode 100644 index 0000000000..7cf014a51e --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/CONTRIBUTING.md @@ -0,0 +1,170 @@ +# How to Contribute to Jaeger + +We'd love your help! + +Jaeger is [Apache 2.0 licensed](LICENSE) and accepts contributions via GitHub +pull requests. This document outlines some of the conventions on development +workflow, commit message formatting, contact points and other resources to make +it easier to get your contribution accepted. + +We gratefully welcome improvements to documentation as well as to code. + +# Certificate of Origin + +By contributing to this project you agree to the [Developer Certificate of +Origin](https://developercertificate.org/) (DCO). This document was created +by the Linux Kernel community and is a simple statement that you, as a +contributor, have the legal right to make the contribution. See the [DCO](DCO) +file for details. + +## Getting Started + +This library uses [glide](https://github.com/Masterminds/glide) to manage dependencies. + +To get started, make sure you clone the Git repository into the correct location +`github.com/uber/jaeger-client-go` relative to `$GOPATH`: + +``` +mkdir -p $GOPATH/src/github.com/uber +cd $GOPATH/src/github.com/uber +git clone git@github.com:jaegertracing/jaeger-client-go.git jaeger-client-go +cd jaeger-client-go +``` + +Then install dependencies and run the tests: + +``` +git submodule update --init --recursive +glide install +make test +``` + +## Imports grouping + +This projects follows the following pattern for grouping imports in Go files: + * imports from standard library + * imports from other projects + * imports from `jaeger-client-go` project + +For example: + +```go +import ( + "fmt" + + "github.com/uber/jaeger-lib/metrics" + "go.uber.org/zap" + + "github.com/uber/jaeger-client-go/config" +) +``` + +## Making A Change + +*Before making any significant changes, please [open an +issue](https://github.com/jaegertracing/jaeger-client-go/issues).* Discussing your proposed +changes ahead of time will make the contribution process smooth for everyone. + +Once we've discussed your changes and you've got your code ready, make sure +that tests are passing (`make test` or `make cover`) and open your PR. Your +pull request is most likely to be accepted if it: + +* Includes tests for new functionality. +* Follows the guidelines in [Effective + Go](https://golang.org/doc/effective_go.html) and the [Go team's common code + review comments](https://github.com/golang/go/wiki/CodeReviewComments). +* Has a [good commit message](https://chris.beams.io/posts/git-commit/): + * Separate subject from body with a blank line + * Limit the subject line to 50 characters + * Capitalize the subject line + * Do not end the subject line with a period + * Use the imperative mood in the subject line + * Wrap the body at 72 characters + * Use the body to explain _what_ and _why_ instead of _how_ +* Each commit must be signed by the author ([see below](#sign-your-work)). + +## License + +By contributing your code, you agree to license your contribution under the terms +of the [Apache License](LICENSE). + +If you are adding a new file it should have a header like below. The easiest +way to add such header is to run `make fmt`. + +``` +// Copyright (c) 2017 The Jaeger Authors. +// +// 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. +``` + +## Sign your work + +The sign-off is a simple line at the end of the explanation for the +patch, which certifies that you wrote it or otherwise have the right to +pass it on as an open-source patch. The rules are pretty simple: if you +can certify the below (from +[developercertificate.org](http://developercertificate.org/)): + +``` +Developer Certificate of Origin +Version 1.1 + +Copyright (C) 2004, 2006 The Linux Foundation and its contributors. +660 York Street, Suite 102, +San Francisco, CA 94110 USA + +Everyone is permitted to copy and distribute verbatim copies of this +license document, but changing it is not allowed. + + +Developer's Certificate of Origin 1.1 + +By making a contribution to this project, I certify that: + +(a) The contribution was created in whole or in part by me and I + have the right to submit it under the open source license + indicated in the file; or + +(b) The contribution is based upon previous work that, to the best + of my knowledge, is covered under an appropriate open source + license and I have the right under that license to submit that + work with modifications, whether created in whole or in part + by me, under the same open source license (unless I am + permitted to submit under a different license), as indicated + in the file; or + +(c) The contribution was provided directly to me by some other + person who certified (a), (b) or (c) and I have not modified + it. + +(d) I understand and agree that this project and the contribution + are public and that a record of the contribution (including all + personal information I submit with it, including my sign-off) is + maintained indefinitely and may be redistributed consistent with + this project or the open source license(s) involved. +``` + +then you just add a line to every git commit message: + + Signed-off-by: Joe Smith + +using your real name (sorry, no pseudonyms or anonymous contributions.) + +You can add the sign off when creating the git commit via `git commit -s`. + +If you want this to be automatic you can set up some aliases: + +``` +git config --add alias.amend "commit -s --amend" +git config --add alias.c "commit -s" +``` diff --git a/vendor/github.com/uber/jaeger-client-go/DCO b/vendor/github.com/uber/jaeger-client-go/DCO new file mode 100644 index 0000000000..068953d4bd --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/DCO @@ -0,0 +1,37 @@ +Developer Certificate of Origin +Version 1.1 + +Copyright (C) 2004, 2006 The Linux Foundation and its contributors. +660 York Street, Suite 102, +San Francisco, CA 94110 USA + +Everyone is permitted to copy and distribute verbatim copies of this +license document, but changing it is not allowed. + + +Developer's Certificate of Origin 1.1 + +By making a contribution to this project, I certify that: + +(a) The contribution was created in whole or in part by me and I + have the right to submit it under the open source license + indicated in the file; or + +(b) The contribution is based upon previous work that, to the best + of my knowledge, is covered under an appropriate open source + license and I have the right under that license to submit that + work with modifications, whether created in whole or in part + by me, under the same open source license (unless I am + permitted to submit under a different license), as indicated + in the file; or + +(c) The contribution was provided directly to me by some other + person who certified (a), (b) or (c) and I have not modified + it. + +(d) I understand and agree that this project and the contribution + are public and that a record of the contribution (including all + personal information I submit with it, including my sign-off) is + maintained indefinitely and may be redistributed consistent with + this project or the open source license(s) involved. + diff --git a/vendor/github.com/uber/jaeger-client-go/Gopkg.lock b/vendor/github.com/uber/jaeger-client-go/Gopkg.lock new file mode 100644 index 0000000000..ec054c6ed6 --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/Gopkg.lock @@ -0,0 +1,164 @@ +# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. + + +[[projects]] + branch = "master" + name = "github.com/beorn7/perks" + packages = ["quantile"] + revision = "3a771d992973f24aa725d07868b467d1ddfceafb" + +[[projects]] + branch = "master" + name = "github.com/codahale/hdrhistogram" + packages = ["."] + revision = "3a0bb77429bd3a61596f5e8a3172445844342120" + +[[projects]] + branch = "master" + name = "github.com/crossdock/crossdock-go" + packages = [ + ".", + "assert", + "require" + ] + revision = "049aabb0122b03bc9bd30cab8f3f91fb60166361" + +[[projects]] + name = "github.com/davecgh/go-spew" + packages = ["spew"] + revision = "346938d642f2ec3594ed81d874461961cd0faa76" + version = "v1.1.0" + +[[projects]] + name = "github.com/golang/protobuf" + packages = ["proto"] + revision = "925541529c1fa6821df4e44ce2723319eb2be768" + version = "v1.0.0" + +[[projects]] + name = "github.com/matttproud/golang_protobuf_extensions" + packages = ["pbutil"] + revision = "3247c84500bff8d9fb6d579d800f20b3e091582c" + version = "v1.0.0" + +[[projects]] + name = "github.com/opentracing/opentracing-go" + packages = [ + ".", + "ext", + "log" + ] + revision = "1949ddbfd147afd4d964a9f00b24eb291e0e7c38" + version = "v1.0.2" + +[[projects]] + name = "github.com/pkg/errors" + packages = ["."] + revision = "645ef00459ed84a119197bfb8d8205042c6df63d" + version = "v0.8.0" + +[[projects]] + name = "github.com/pmezard/go-difflib" + packages = ["difflib"] + revision = "792786c7400a136282c1664665ae0a8db921c6c2" + version = "v1.0.0" + +[[projects]] + name = "github.com/prometheus/client_golang" + packages = ["prometheus"] + revision = "c5b7fccd204277076155f10851dad72b76a49317" + version = "v0.8.0" + +[[projects]] + branch = "master" + name = "github.com/prometheus/client_model" + packages = ["go"] + revision = "99fa1f4be8e564e8a6b613da7fa6f46c9edafc6c" + +[[projects]] + branch = "master" + name = "github.com/prometheus/common" + packages = [ + "expfmt", + "internal/bitbucket.org/ww/goautoneg", + "model" + ] + revision = "d811d2e9bf898806ecfb6ef6296774b13ffc314c" + +[[projects]] + branch = "master" + name = "github.com/prometheus/procfs" + packages = [ + ".", + "internal/util", + "nfs", + "xfs" + ] + revision = "8b1c2da0d56deffdbb9e48d4414b4e674bd8083e" + +[[projects]] + name = "github.com/stretchr/testify" + packages = [ + "assert", + "require", + "suite" + ] + revision = "12b6f73e6084dad08a7c6e575284b177ecafbc71" + version = "v1.2.1" + +[[projects]] + name = "github.com/uber-go/atomic" + packages = ["."] + revision = "8474b86a5a6f79c443ce4b2992817ff32cf208b8" + version = "v1.3.1" + +[[projects]] + name = "github.com/uber/jaeger-lib" + packages = [ + "metrics", + "metrics/prometheus", + "metrics/testutils" + ] + revision = "4267858c0679cd4e47cefed8d7f70fd386cfb567" + version = "v1.4.0" + +[[projects]] + name = "go.uber.org/atomic" + packages = ["."] + revision = "54f72d32435d760d5604f17a82e2435b28dc4ba5" + version = "v1.3.0" + +[[projects]] + name = "go.uber.org/multierr" + packages = ["."] + revision = "3c4937480c32f4c13a875a1829af76c98ca3d40a" + version = "v1.1.0" + +[[projects]] + name = "go.uber.org/zap" + packages = [ + ".", + "buffer", + "internal/bufferpool", + "internal/color", + "internal/exit", + "zapcore" + ] + revision = "eeedf312bc6c57391d84767a4cd413f02a917974" + version = "v1.8.0" + +[[projects]] + branch = "master" + name = "golang.org/x/net" + packages = [ + "context", + "context/ctxhttp" + ] + revision = "5f9ae10d9af5b1c89ae6904293b14b064d4ada23" + +[solve-meta] + analyzer-name = "dep" + analyzer-version = 1 + inputs-digest = "f9dcfaf37a785c5dac1e20c29605eda29a83ba9c6f8842e92960dc94c8c4ff80" + solver-name = "gps-cdcl" + solver-version = 1 diff --git a/vendor/github.com/uber/jaeger-client-go/Gopkg.toml b/vendor/github.com/uber/jaeger-client-go/Gopkg.toml new file mode 100644 index 0000000000..baf7a6bdf7 --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/Gopkg.toml @@ -0,0 +1,27 @@ +[[constraint]] + name = "github.com/crossdock/crossdock-go" + branch = "master" + +[[constraint]] + name = "github.com/opentracing/opentracing-go" + version = "^1" + +[[constraint]] + name = "github.com/prometheus/client_golang" + version = "0.8.0" + +[[constraint]] + name = "github.com/stretchr/testify" + version = "^1.1.3" + +[[constraint]] + name = "github.com/uber-go/atomic" + version = "^1" + +[[constraint]] + name = "github.com/uber/jaeger-lib" + version = "^1.3" + +[[constraint]] + name = "go.uber.org/zap" + version = "^1" diff --git a/vendor/github.com/uber/jaeger-client-go/LICENSE b/vendor/github.com/uber/jaeger-client-go/LICENSE new file mode 100644 index 0000000000..261eeb9e9f --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/LICENSE @@ -0,0 +1,201 @@ + 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/vendor/github.com/uber/jaeger-client-go/Makefile b/vendor/github.com/uber/jaeger-client-go/Makefile new file mode 100644 index 0000000000..601cc65148 --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/Makefile @@ -0,0 +1,117 @@ +PROJECT_ROOT=github.com/uber/jaeger-client-go +PACKAGES := $(shell glide novendor | grep -v -e ./thrift-gen/... -e ./thrift/...) +# all .go files that don't exist in hidden directories +ALL_SRC := $(shell find . -name "*.go" | grep -v -e vendor -e thrift-gen -e ./thrift/ \ + -e ".*/\..*" \ + -e ".*/_.*" \ + -e ".*/mocks.*") + +-include crossdock/rules.mk + +export GO15VENDOREXPERIMENT=1 + +RACE=-race +GOTEST=go test -v $(RACE) +GOLINT=golint +GOVET=go vet +GOFMT=gofmt +FMT_LOG=fmt.log +LINT_LOG=lint.log + +THRIFT_VER=0.9.3 +THRIFT_IMG=thrift:$(THRIFT_VER) +THRIFT=docker run -v "${PWD}:/data" $(THRIFT_IMG) thrift +THRIFT_GO_ARGS=thrift_import="github.com/apache/thrift/lib/go/thrift" +THRIFT_GEN_DIR=thrift-gen + +PASS=$(shell printf "\033[32mPASS\033[0m") +FAIL=$(shell printf "\033[31mFAIL\033[0m") +COLORIZE=sed ''/PASS/s//$(PASS)/'' | sed ''/FAIL/s//$(FAIL)/'' + +.DEFAULT_GOAL := test-and-lint + +.PHONY: test-and-lint +test-and-lint: test fmt lint + +.PHONY: test +test: + bash -c "set -e; set -o pipefail; $(GOTEST) $(PACKAGES) | $(COLORIZE)" + +.PHONY: fmt +fmt: + $(GOFMT) -e -s -l -w $(ALL_SRC) + ./scripts/updateLicenses.sh + +.PHONY: lint +lint: + $(GOVET) $(PACKAGES) + @cat /dev/null > $(LINT_LOG) + @$(foreach pkg, $(PACKAGES), $(GOLINT) $(pkg) | grep -v crossdock/thrift >> $(LINT_LOG) || true;) + @[ ! -s "$(LINT_LOG)" ] || (echo "Lint Failures" | cat - $(LINT_LOG) && false) + @$(GOFMT) -e -s -l $(ALL_SRC) > $(FMT_LOG) + ./scripts/updateLicenses.sh >> $(FMT_LOG) + @[ ! -s "$(FMT_LOG)" ] || (echo "go fmt or license check failures, run 'make fmt'" | cat - $(FMT_LOG) && false) + + +.PHONY: install +install: + glide --version || go get github.com/Masterminds/glide +ifeq ($(USE_DEP),true) + dep ensure +else + glide install +endif + + +.PHONY: cover +cover: + ./scripts/cover.sh $(shell go list $(PACKAGES)) + go tool cover -html=cover.out -o cover.html + + +# This is not part of the regular test target because we don't want to slow it +# down. +.PHONY: test-examples +test-examples: + make -C examples + +# TODO at the moment we're not generating tchan_*.go files +thrift: idl-submodule thrift-image + $(THRIFT) -o /data --gen go:$(THRIFT_GO_ARGS) --out /data/$(THRIFT_GEN_DIR) /data/idl/thrift/agent.thrift + $(THRIFT) -o /data --gen go:$(THRIFT_GO_ARGS) --out /data/$(THRIFT_GEN_DIR) /data/idl/thrift/sampling.thrift + $(THRIFT) -o /data --gen go:$(THRIFT_GO_ARGS) --out /data/$(THRIFT_GEN_DIR) /data/idl/thrift/jaeger.thrift + $(THRIFT) -o /data --gen go:$(THRIFT_GO_ARGS) --out /data/$(THRIFT_GEN_DIR) /data/idl/thrift/zipkincore.thrift + $(THRIFT) -o /data --gen go:$(THRIFT_GO_ARGS) --out /data/$(THRIFT_GEN_DIR) /data/idl/thrift/baggage.thrift + $(THRIFT) -o /data --gen go:$(THRIFT_GO_ARGS) --out /data/crossdock/thrift/ /data/idl/thrift/crossdock/tracetest.thrift + sed -i '' 's|"zipkincore"|"$(PROJECT_ROOT)/thrift-gen/zipkincore"|g' $(THRIFT_GEN_DIR)/agent/*.go + sed -i '' 's|"jaeger"|"$(PROJECT_ROOT)/thrift-gen/jaeger"|g' $(THRIFT_GEN_DIR)/agent/*.go + sed -i '' 's|"github.com/apache/thrift/lib/go/thrift"|"github.com/uber/jaeger-client-go/thrift"|g' \ + $(THRIFT_GEN_DIR)/*/*.go crossdock/thrift/tracetest/*.go + rm -rf thrift-gen/*/*-remote + rm -rf crossdock/thrift/*/*-remote + rm -rf thrift-gen/jaeger/collector.go + +idl-submodule: + git submodule init + git submodule update + +thrift-image: + $(THRIFT) -version + +.PHONY: install-dep-ci +install-dep-ci: + - curl -L -s https://github.com/golang/dep/releases/download/v0.3.2/dep-linux-amd64 -o $$GOPATH/bin/dep + - chmod +x $$GOPATH/bin/dep + +.PHONY: install-ci +install-ci: install-dep-ci install + go get github.com/wadey/gocovmerge + go get github.com/mattn/goveralls + go get golang.org/x/tools/cmd/cover + go get github.com/golang/lint/golint + +.PHONY: test-ci +test-ci: + @./scripts/cover.sh $(shell go list $(PACKAGES)) + make lint + diff --git a/vendor/github.com/uber/jaeger-client-go/README.md b/vendor/github.com/uber/jaeger-client-go/README.md new file mode 100644 index 0000000000..16b04454e1 --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/README.md @@ -0,0 +1,260 @@ +[![GoDoc][doc-img]][doc] [![Build Status][ci-img]][ci] [![Coverage Status][cov-img]][cov] [![OpenTracing 1.0 Enabled][ot-img]][ot-url] + +# Jaeger Bindings for Go OpenTracing API + +Instrumentation library that implements an +[OpenTracing](http://opentracing.io) Tracer for Jaeger (https://jaegertracing.io). + +**IMPORTANT**: The library's import path is based on its original location under `github.com/uber`. Do not try to import it as `github.com/jaegertracing`, it will not compile. We might revisit this in the next major release. + * :white_check_mark: `import "github.com/uber/jaeger-client-go"` + * :x: `import "github.com/jaegertracing/jaeger-client-go"` + +## How to Contribute + +Please see [CONTRIBUTING.md](CONTRIBUTING.md). + +## Installation + +We recommended using a dependency manager like [glide](https://github.com/Masterminds/glide) +and [semantic versioning](http://semver.org/) when including this library into an application. +For example, Jaeger backend imports this library like this: + +```yaml +- package: github.com/uber/jaeger-client-go + version: ^2.7.0 +``` + +If you instead want to use the latest version in `master`, you can pull it via `go get`. +Note that during `go get` you may see build errors due to incompatible dependencies, which is why +we recommend using semantic versions for dependencies. The error may be fixed by running +`make install` (it will install `glide` if you don't have it): + +```shell +go get -u github.com/uber/jaeger-client-go/ +cd $GOPATH/src/github.com/uber/jaeger-client-go/ +git submodule update --init --recursive +make install +``` + +## Initialization + +See tracer initialization examples in [godoc](https://godoc.org/github.com/uber/jaeger-client-go/config#pkg-examples) +and [config/example_test.go](./config/example_test.go). + +### Environment variables + +The tracer can be initialized with values coming from environment variables. None of the env vars are required +and all of them can be overriden via direct setting of the property on the configuration object. + +Property| Description +--- | --- +JAEGER_SERVICE_NAME | The service name +JAEGER_AGENT_HOST | The hostname for communicating with agent via UDP +JAEGER_AGENT_PORT | The port for communicating with agent via UDP +JAEGER_REPORTER_LOG_SPANS | Whether the reporter should also log the spans +JAEGER_REPORTER_MAX_QUEUE_SIZE | The reporter's maximum queue size +JAEGER_REPORTER_FLUSH_INTERVAL | The reporter's flush interval (ms) +JAEGER_SAMPLER_TYPE | The sampler type +JAEGER_SAMPLER_PARAM | The sampler parameter (number) +JAEGER_SAMPLER_MANAGER_HOST_PORT | The host name and port when using the remote controlled sampler +JAEGER_SAMPLER_MAX_OPERATIONS | The maximum number of operations that the sampler will keep track of +JAEGER_SAMPLER_REFRESH_INTERVAL | How often the remotely controlled sampler will poll jaeger-agent for the appropriate sampling strategy +JAEGER_TAGS | A comma separated list of `name = value` tracer level tags, which get added to all reported spans. The value can also refer to an environment variable using the format `${envVarName:default}`, where the `:default` is optional, and identifies a value to be used if the environment variable cannot be found +JAEGER_DISABLED | Whether the tracer is disabled or not. If true, the default `opentracing.NoopTracer` is used. +JAEGER_RPC_METRICS | Whether to store RPC metrics + +### Closing the tracer via `io.Closer` + +The constructor function for Jaeger Tracer returns the tracer itself and an `io.Closer` instance. +It is recommended to structure your `main()` so that it calls the `Close()` function on the closer +before exiting, e.g. + +```go +tracer, closer, err := cfg.NewTracer(...) +defer closer.Close() +``` + +This is especially useful for command-line tools that enable tracing, as well as +for the long-running apps that support graceful shutdown. For example, if your deployment +system sends SIGTERM instead of killing the process and you trap that signal to do a graceful +exit, then having `defer closer.Closer()` ensures that all buffered spans are flushed. + +### Metrics & Monitoring + +The tracer emits a number of different metrics, defined in +[metrics.go](metrics.go). The monitoring backend is expected to support +tag-based metric names, e.g. instead of `statsd`-style string names +like `counters.my-service.jaeger.spans.started.sampled`, the metrics +are defined by a short name and a collection of key/value tags, for +example: `name:jaeger.traces, state:started, sampled:y`. See [metrics.go](./metrics.go) +file for the full list and descriptions of emitted metrics. + +The monitoring backend is represented by the `metrics.Factory` interface from package +[`"github.com/uber/jaeger-lib/metrics"`](https://github.com/jaegertracing/jaeger-lib/tree/master/metrics). An implementation +of that interface can be passed as an option to either the Configuration object or the Tracer +constructor, for example: + +```go +import ( + "github.com/uber/jaeger-client-go/config" + "github.com/uber/jaeger-lib/metrics/prometheus" +) + + metricsFactory := prometheus.New() + tracer, closer, err := config.Configuration{ + ServiceName: "your-service-name", + }.NewTracer( + config.Metrics(metricsFactory), + ) +``` + +By default, a no-op `metrics.NullFactory` is used. + +### Logging + +The tracer can be configured with an optional logger, which will be +used to log communication errors, or log spans if a logging reporter +option is specified in the configuration. The logging API is abstracted +by the [Logger](logger.go) interface. A logger instance implementing +this interface can be set on the `Config` object before calling the +`New` method. + +Besides the [zap](https://github.com/uber-go/zap) implementation +bundled with this package there is also a [go-kit](https://github.com/go-kit/kit) +one in the [jaeger-lib](https://github.com/jaegertracing/jaeger-lib) repository. + +## Instrumentation for Tracing + +Since this tracer is fully compliant with OpenTracing API 1.0, +all code instrumentation should only use the API itself, as described +in the [opentracing-go](https://github.com/opentracing/opentracing-go) documentation. + +## Features + +### Reporters + +A "reporter" is a component that receives the finished spans and reports +them to somewhere. Under normal circumstances, the Tracer +should use the default `RemoteReporter`, which sends the spans out of +process via configurable "transport". For testing purposes, one can +use an `InMemoryReporter` that accumulates spans in a buffer and +allows to retrieve them for later verification. Also available are +`NullReporter`, a no-op reporter that does nothing, a `LoggingReporter` +which logs all finished spans using their `String()` method, and a +`CompositeReporter` that can be used to combine more than one reporter +into one, e.g. to attach a logging reporter to the main remote reporter. + +### Span Reporting Transports + +The remote reporter uses "transports" to actually send the spans out +of process. Currently the supported transports include: + * [Jaeger Thrift](https://github.com/jaegertracing/jaeger-idl/blob/master/thrift/agent.thrift) over UDP or HTTP, + * [Zipkin Thrift](https://github.com/jaegertracing/jaeger-idl/blob/master/thrift/zipkincore.thrift) over HTTP. + +### Sampling + +The tracer does not record all spans, but only those that have the +sampling bit set in the `flags`. When a new trace is started and a new +unique ID is generated, a sampling decision is made whether this trace +should be sampled. The sampling decision is propagated to all downstream +calls via the `flags` field of the trace context. The following samplers +are available: + 1. `RemotelyControlledSampler` uses one of the other simpler samplers + and periodically updates it by polling an external server. This + allows dynamic control of the sampling strategies. + 1. `ConstSampler` always makes the same sampling decision for all + trace IDs. it can be configured to either sample all traces, or + to sample none. + 1. `ProbabilisticSampler` uses a fixed sampling rate as a probability + for a given trace to be sampled. The actual decision is made by + comparing the trace ID with a random number multiplied by the + sampling rate. + 1. `RateLimitingSampler` can be used to allow only a certain fixed + number of traces to be sampled per second. + +### Baggage Injection + +The OpenTracing spec allows for [baggage][baggage], which are key value pairs that are added +to the span context and propagated throughout the trace. An external process can inject baggage +by setting the special HTTP Header `jaeger-baggage` on a request: + +```sh +curl -H "jaeger-baggage: key1=value1, key2=value2" http://myhost.com +``` + +Baggage can also be programatically set inside your service: + +```go +if span := opentracing.SpanFromContext(ctx); span != nil { + span.SetBaggageItem("key", "value") +} +``` + +Another service downstream of that can retrieve the baggage in a similar way: + +```go +if span := opentracing.SpanFromContext(ctx); span != nil { + val := span.BaggageItem("key") + println(val) +} +``` + +### Debug Traces (Forced Sampling) + +#### Programmatically + +The OpenTracing API defines a `sampling.priority` standard tag that +can be used to affect the sampling of a span and its children: + +```go +import ( + "github.com/opentracing/opentracing-go" + "github.com/opentracing/opentracing-go/ext" +) + +span := opentracing.SpanFromContext(ctx) +ext.SamplingPriority.Set(span, 1) +``` + +#### Via HTTP Headers + +Jaeger Tracer also understands a special HTTP Header `jaeger-debug-id`, +which can be set in the incoming request, e.g. + +```sh +curl -H "jaeger-debug-id: some-correlation-id" http://myhost.com +``` + +When Jaeger sees this header in the request that otherwise has no +tracing context, it ensures that the new trace started for this +request will be sampled in the "debug" mode (meaning it should survive +all downsampling that might happen in the collection pipeline), and the +root span will have a tag as if this statement was executed: + +```go +span.SetTag("jaeger-debug-id", "some-correlation-id") +``` + +This allows using Jaeger UI to find the trace by this tag. + +### Zipkin HTTP B3 compatible header propagation + +Jaeger Tracer supports Zipkin B3 Propagation HTTP headers, which are used +by a lot of Zipkin tracers. This means that you can use Jaeger in conjunction with e.g. [these OpenZipkin tracers](https://github.com/openzipkin). + +However it is not the default propagation format, see [here](zipkin/README.md#NewZipkinB3HTTPHeaderPropagator) how to set it up. + +## License + +[Apache 2.0 License](LICENSE). + + +[doc-img]: https://godoc.org/github.com/uber/jaeger-client-go?status.svg +[doc]: https://godoc.org/github.com/uber/jaeger-client-go +[ci-img]: https://travis-ci.org/jaegertracing/jaeger-client-go.svg?branch=master +[ci]: https://travis-ci.org/jaegertracing/jaeger-client-go +[cov-img]: https://codecov.io/gh/jaegertracing/jaeger-client-go/branch/master/graph/badge.svg +[cov]: https://codecov.io/gh/jaegertracing/jaeger-client-go +[ot-img]: https://img.shields.io/badge/OpenTracing--1.0-enabled-blue.svg +[ot-url]: http://opentracing.io +[baggage]: https://github.com/opentracing/specification/blob/master/specification.md#set-a-baggage-item diff --git a/vendor/github.com/uber/jaeger-client-go/RELEASE.md b/vendor/github.com/uber/jaeger-client-go/RELEASE.md new file mode 100644 index 0000000000..115e49ab8a --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/RELEASE.md @@ -0,0 +1,11 @@ +# Release Process + +1. Create a PR "Preparing for release X.Y.Z" against master branch + * Alter CHANGELOG.md from ` (unreleased)` to ` (YYYY-MM-DD)` + * Update `JaegerClientVersion` in constants.go to `Go-X.Y.Z` +2. Create a release "Release X.Y.Z" on Github + * Create Tag `vX.Y.Z` + * Copy CHANGELOG.md into the release notes +3. Create a PR "Back to development" against master branch + * Add ` (unreleased)` to CHANGELOG.md + * Update `JaegerClientVersion` in constants.go to `Go-dev` diff --git a/vendor/github.com/uber/jaeger-client-go/baggage_setter.go b/vendor/github.com/uber/jaeger-client-go/baggage_setter.go new file mode 100644 index 0000000000..1037ca0e86 --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/baggage_setter.go @@ -0,0 +1,77 @@ +// Copyright (c) 2017 Uber Technologies, Inc. +// +// 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 jaeger + +import ( + "github.com/opentracing/opentracing-go/log" + + "github.com/uber/jaeger-client-go/internal/baggage" +) + +// baggageSetter is an actor that can set a baggage value on a Span given certain +// restrictions (eg. maxValueLength). +type baggageSetter struct { + restrictionManager baggage.RestrictionManager + metrics *Metrics +} + +func newBaggageSetter(restrictionManager baggage.RestrictionManager, metrics *Metrics) *baggageSetter { + return &baggageSetter{ + restrictionManager: restrictionManager, + metrics: metrics, + } +} + +// (NB) span should hold the lock before making this call +func (s *baggageSetter) setBaggage(span *Span, key, value string) { + var truncated bool + var prevItem string + restriction := s.restrictionManager.GetRestriction(span.serviceName(), key) + if !restriction.KeyAllowed() { + s.logFields(span, key, value, prevItem, truncated, restriction.KeyAllowed()) + s.metrics.BaggageUpdateFailure.Inc(1) + return + } + if len(value) > restriction.MaxValueLength() { + truncated = true + value = value[:restriction.MaxValueLength()] + s.metrics.BaggageTruncate.Inc(1) + } + prevItem = span.context.baggage[key] + s.logFields(span, key, value, prevItem, truncated, restriction.KeyAllowed()) + span.context = span.context.WithBaggageItem(key, value) + s.metrics.BaggageUpdateSuccess.Inc(1) +} + +func (s *baggageSetter) logFields(span *Span, key, value, prevItem string, truncated, valid bool) { + if !span.context.IsSampled() { + return + } + fields := []log.Field{ + log.String("event", "baggage"), + log.String("key", key), + log.String("value", value), + } + if prevItem != "" { + fields = append(fields, log.String("override", "true")) + } + if truncated { + fields = append(fields, log.String("truncated", "true")) + } + if !valid { + fields = append(fields, log.String("invalid", "true")) + } + span.logFieldsNoLocking(fields...) +} diff --git a/vendor/github.com/uber/jaeger-client-go/config/config.go b/vendor/github.com/uber/jaeger-client-go/config/config.go new file mode 100644 index 0000000000..1eb2967785 --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/config/config.go @@ -0,0 +1,373 @@ +// Copyright (c) 2017-2018 Uber Technologies, Inc. +// +// 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 config + +import ( + "errors" + "fmt" + "io" + "strings" + "time" + + "github.com/opentracing/opentracing-go" + + "github.com/uber/jaeger-client-go" + "github.com/uber/jaeger-client-go/internal/baggage/remote" + throttler "github.com/uber/jaeger-client-go/internal/throttler/remote" + "github.com/uber/jaeger-client-go/rpcmetrics" +) + +const defaultSamplingProbability = 0.001 + +// Configuration configures and creates Jaeger Tracer +type Configuration struct { + // ServiceName specifies the service name to use on the tracer. + // Can be provided via environment variable named JAEGER_SERVICE_NAME + ServiceName string `yaml:"serviceName"` + + // Disabled can be provided via environment variable named JAEGER_DISABLED + Disabled bool `yaml:"disabled"` + + // RPCMetrics can be provided via environment variable named JAEGER_RPC_METRICS + RPCMetrics bool `yaml:"rpc_metrics"` + + // Tags can be provided via environment variable named JAEGER_TAGS + Tags []opentracing.Tag `yaml:"tags"` + + Sampler *SamplerConfig `yaml:"sampler"` + Reporter *ReporterConfig `yaml:"reporter"` + Headers *jaeger.HeadersConfig `yaml:"headers"` + BaggageRestrictions *BaggageRestrictionsConfig `yaml:"baggage_restrictions"` + Throttler *ThrottlerConfig `yaml:"throttler"` +} + +// SamplerConfig allows initializing a non-default sampler. All fields are optional. +type SamplerConfig struct { + // Type specifies the type of the sampler: const, probabilistic, rateLimiting, or remote + // Can be set by exporting an environment variable named JAEGER_SAMPLER_TYPE + Type string `yaml:"type"` + + // Param is a value passed to the sampler. + // Valid values for Param field are: + // - for "const" sampler, 0 or 1 for always false/true respectively + // - for "probabilistic" sampler, a probability between 0 and 1 + // - for "rateLimiting" sampler, the number of spans per second + // - for "remote" sampler, param is the same as for "probabilistic" + // and indicates the initial sampling rate before the actual one + // is received from the mothership. + // Can be set by exporting an environment variable named JAEGER_SAMPLER_PARAM + Param float64 `yaml:"param"` + + // SamplingServerURL is the address of jaeger-agent's HTTP sampling server + // Can be set by exporting an environment variable named JAEGER_SAMPLER_MANAGER_HOST_PORT + SamplingServerURL string `yaml:"samplingServerURL"` + + // MaxOperations is the maximum number of operations that the sampler + // will keep track of. If an operation is not tracked, a default probabilistic + // sampler will be used rather than the per operation specific sampler. + // Can be set by exporting an environment variable named JAEGER_SAMPLER_MAX_OPERATIONS + MaxOperations int `yaml:"maxOperations"` + + // SamplingRefreshInterval controls how often the remotely controlled sampler will poll + // jaeger-agent for the appropriate sampling strategy. + // Can be set by exporting an environment variable named JAEGER_SAMPLER_REFRESH_INTERVAL + SamplingRefreshInterval time.Duration `yaml:"samplingRefreshInterval"` +} + +// ReporterConfig configures the reporter. All fields are optional. +type ReporterConfig struct { + // QueueSize controls how many spans the reporter can keep in memory before it starts dropping + // new spans. The queue is continuously drained by a background go-routine, as fast as spans + // can be sent out of process. + // Can be set by exporting an environment variable named JAEGER_REPORTER_MAX_QUEUE_SIZE + QueueSize int `yaml:"queueSize"` + + // BufferFlushInterval controls how often the buffer is force-flushed, even if it's not full. + // It is generally not useful, as it only matters for very low traffic services. + // Can be set by exporting an environment variable named JAEGER_REPORTER_FLUSH_INTERVAL + BufferFlushInterval time.Duration + + // LogSpans, when true, enables LoggingReporter that runs in parallel with the main reporter + // and logs all submitted spans. Main Configuration.Logger must be initialized in the code + // for this option to have any effect. + // Can be set by exporting an environment variable named JAEGER_REPORTER_LOG_SPANS + LogSpans bool `yaml:"logSpans"` + + // LocalAgentHostPort instructs reporter to send spans to jaeger-agent at this address + // Can be set by exporting an environment variable named JAEGER_AGENT_HOST / JAEGER_AGENT_PORT + LocalAgentHostPort string `yaml:"localAgentHostPort"` +} + +// BaggageRestrictionsConfig configures the baggage restrictions manager which can be used to whitelist +// certain baggage keys. All fields are optional. +type BaggageRestrictionsConfig struct { + // DenyBaggageOnInitializationFailure controls the startup failure mode of the baggage restriction + // manager. If true, the manager will not allow any baggage to be written until baggage restrictions have + // been retrieved from jaeger-agent. If false, the manager wil allow any baggage to be written until baggage + // restrictions have been retrieved from jaeger-agent. + DenyBaggageOnInitializationFailure bool `yaml:"denyBaggageOnInitializationFailure"` + + // HostPort is the hostPort of jaeger-agent's baggage restrictions server + HostPort string `yaml:"hostPort"` + + // RefreshInterval controls how often the baggage restriction manager will poll + // jaeger-agent for the most recent baggage restrictions. + RefreshInterval time.Duration `yaml:"refreshInterval"` +} + +// ThrottlerConfig configures the throttler which can be used to throttle the +// rate at which the client may send debug requests. +type ThrottlerConfig struct { + // HostPort of jaeger-agent's credit server. + HostPort string `yaml:"hostPort"` + + // RefreshInterval controls how often the throttler will poll jaeger-agent + // for more throttling credits. + RefreshInterval time.Duration `yaml:"refreshInterval"` + + // SynchronousInitialization determines whether or not the throttler should + // synchronously fetch credits from the agent when an operation is seen for + // the first time. This should be set to true if the client will be used by + // a short lived service that needs to ensure that credits are fetched + // upfront such that sampling or throttling occurs. + SynchronousInitialization bool `yaml:"synchronousInitialization"` +} + +type nullCloser struct{} + +func (*nullCloser) Close() error { return nil } + +// New creates a new Jaeger Tracer, and a closer func that can be used to flush buffers +// before shutdown. +// +// Deprecated: use NewTracer() function +func (c Configuration) New( + serviceName string, + options ...Option, +) (opentracing.Tracer, io.Closer, error) { + if serviceName != "" { + c.ServiceName = serviceName + } + + return c.NewTracer(options...) +} + +// NewTracer returns a new tracer based on the current configuration, using the given options, +// and a closer func that can be used to flush buffers before shutdown. +func (c Configuration) NewTracer(options ...Option) (opentracing.Tracer, io.Closer, error) { + if c.ServiceName == "" { + return nil, nil, errors.New("no service name provided") + } + + if c.Disabled { + return &opentracing.NoopTracer{}, &nullCloser{}, nil + } + opts := applyOptions(options...) + tracerMetrics := jaeger.NewMetrics(opts.metrics, nil) + if c.RPCMetrics { + Observer( + rpcmetrics.NewObserver( + opts.metrics.Namespace("jaeger-rpc", map[string]string{"component": "jaeger"}), + rpcmetrics.DefaultNameNormalizer, + ), + )(&opts) // adds to c.observers + } + if c.Sampler == nil { + c.Sampler = &SamplerConfig{ + Type: jaeger.SamplerTypeRemote, + Param: defaultSamplingProbability, + } + } + if c.Reporter == nil { + c.Reporter = &ReporterConfig{} + } + + sampler := opts.sampler + if sampler == nil { + s, err := c.Sampler.NewSampler(c.ServiceName, tracerMetrics) + if err != nil { + return nil, nil, err + } + sampler = s + } + + reporter := opts.reporter + if reporter == nil { + r, err := c.Reporter.NewReporter(c.ServiceName, tracerMetrics, opts.logger) + if err != nil { + return nil, nil, err + } + reporter = r + } + + tracerOptions := []jaeger.TracerOption{ + jaeger.TracerOptions.Metrics(tracerMetrics), + jaeger.TracerOptions.Logger(opts.logger), + jaeger.TracerOptions.CustomHeaderKeys(c.Headers), + jaeger.TracerOptions.Gen128Bit(opts.gen128Bit), + jaeger.TracerOptions.ZipkinSharedRPCSpan(opts.zipkinSharedRPCSpan), + jaeger.TracerOptions.MaxTagValueLength(opts.maxTagValueLength), + } + + for _, tag := range opts.tags { + tracerOptions = append(tracerOptions, jaeger.TracerOptions.Tag(tag.Key, tag.Value)) + } + + for _, tag := range c.Tags { + tracerOptions = append(tracerOptions, jaeger.TracerOptions.Tag(tag.Key, tag.Value)) + } + + for _, obs := range opts.observers { + tracerOptions = append(tracerOptions, jaeger.TracerOptions.Observer(obs)) + } + + for _, cobs := range opts.contribObservers { + tracerOptions = append(tracerOptions, jaeger.TracerOptions.ContribObserver(cobs)) + } + + for format, injector := range opts.injectors { + tracerOptions = append(tracerOptions, jaeger.TracerOptions.Injector(format, injector)) + } + + for format, extractor := range opts.extractors { + tracerOptions = append(tracerOptions, jaeger.TracerOptions.Extractor(format, extractor)) + } + + if c.BaggageRestrictions != nil { + mgr := remote.NewRestrictionManager( + c.ServiceName, + remote.Options.Metrics(tracerMetrics), + remote.Options.Logger(opts.logger), + remote.Options.HostPort(c.BaggageRestrictions.HostPort), + remote.Options.RefreshInterval(c.BaggageRestrictions.RefreshInterval), + remote.Options.DenyBaggageOnInitializationFailure( + c.BaggageRestrictions.DenyBaggageOnInitializationFailure, + ), + ) + tracerOptions = append(tracerOptions, jaeger.TracerOptions.BaggageRestrictionManager(mgr)) + } + + if c.Throttler != nil { + debugThrottler := throttler.NewThrottler( + c.ServiceName, + throttler.Options.Metrics(tracerMetrics), + throttler.Options.Logger(opts.logger), + throttler.Options.HostPort(c.Throttler.HostPort), + throttler.Options.RefreshInterval(c.Throttler.RefreshInterval), + throttler.Options.SynchronousInitialization( + c.Throttler.SynchronousInitialization, + ), + ) + + tracerOptions = append(tracerOptions, jaeger.TracerOptions.DebugThrottler(debugThrottler)) + } + + tracer, closer := jaeger.NewTracer( + c.ServiceName, + sampler, + reporter, + tracerOptions..., + ) + + return tracer, closer, nil +} + +// InitGlobalTracer creates a new Jaeger Tracer, and sets it as global OpenTracing Tracer. +// It returns a closer func that can be used to flush buffers before shutdown. +func (c Configuration) InitGlobalTracer( + serviceName string, + options ...Option, +) (io.Closer, error) { + if c.Disabled { + return &nullCloser{}, nil + } + tracer, closer, err := c.New(serviceName, options...) + if err != nil { + return nil, err + } + opentracing.SetGlobalTracer(tracer) + return closer, nil +} + +// NewSampler creates a new sampler based on the configuration +func (sc *SamplerConfig) NewSampler( + serviceName string, + metrics *jaeger.Metrics, +) (jaeger.Sampler, error) { + samplerType := strings.ToLower(sc.Type) + if samplerType == jaeger.SamplerTypeConst { + return jaeger.NewConstSampler(sc.Param != 0), nil + } + if samplerType == jaeger.SamplerTypeProbabilistic { + if sc.Param >= 0 && sc.Param <= 1.0 { + return jaeger.NewProbabilisticSampler(sc.Param) + } + return nil, fmt.Errorf( + "Invalid Param for probabilistic sampler: %v. Expecting value between 0 and 1", + sc.Param, + ) + } + if samplerType == jaeger.SamplerTypeRateLimiting { + return jaeger.NewRateLimitingSampler(sc.Param), nil + } + if samplerType == jaeger.SamplerTypeRemote || sc.Type == "" { + sc2 := *sc + sc2.Type = jaeger.SamplerTypeProbabilistic + initSampler, err := sc2.NewSampler(serviceName, nil) + if err != nil { + return nil, err + } + options := []jaeger.SamplerOption{ + jaeger.SamplerOptions.Metrics(metrics), + jaeger.SamplerOptions.InitialSampler(initSampler), + jaeger.SamplerOptions.SamplingServerURL(sc.SamplingServerURL), + } + if sc.MaxOperations != 0 { + options = append(options, jaeger.SamplerOptions.MaxOperations(sc.MaxOperations)) + } + if sc.SamplingRefreshInterval != 0 { + options = append(options, jaeger.SamplerOptions.SamplingRefreshInterval(sc.SamplingRefreshInterval)) + } + return jaeger.NewRemotelyControlledSampler(serviceName, options...), nil + } + return nil, fmt.Errorf("Unknown sampler type %v", sc.Type) +} + +// NewReporter instantiates a new reporter that submits spans to tcollector +func (rc *ReporterConfig) NewReporter( + serviceName string, + metrics *jaeger.Metrics, + logger jaeger.Logger, +) (jaeger.Reporter, error) { + sender, err := rc.newTransport() + if err != nil { + return nil, err + } + reporter := jaeger.NewRemoteReporter( + sender, + jaeger.ReporterOptions.QueueSize(rc.QueueSize), + jaeger.ReporterOptions.BufferFlushInterval(rc.BufferFlushInterval), + jaeger.ReporterOptions.Logger(logger), + jaeger.ReporterOptions.Metrics(metrics)) + if rc.LogSpans && logger != nil { + logger.Infof("Initializing logging reporter\n") + reporter = jaeger.NewCompositeReporter(jaeger.NewLoggingReporter(logger), reporter) + } + return reporter, err +} + +func (rc *ReporterConfig) newTransport() (jaeger.Transport, error) { + return jaeger.NewUDPTransport(rc.LocalAgentHostPort, 0) +} diff --git a/vendor/github.com/uber/jaeger-client-go/config/config_env.go b/vendor/github.com/uber/jaeger-client-go/config/config_env.go new file mode 100644 index 0000000000..96f170c539 --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/config/config_env.go @@ -0,0 +1,205 @@ +// Copyright (c) 2018 The Jaeger Authors. +// +// 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 config + +import ( + "fmt" + "os" + "strconv" + "strings" + "time" + + opentracing "github.com/opentracing/opentracing-go" + "github.com/pkg/errors" + + "github.com/uber/jaeger-client-go" +) + +const ( + // environment variable names + envServiceName = "JAEGER_SERVICE_NAME" + envDisabled = "JAEGER_DISABLED" + envRPCMetrics = "JAEGER_RPC_METRICS" + envTags = "JAEGER_TAGS" + envSamplerType = "JAEGER_SAMPLER_TYPE" + envSamplerParam = "JAEGER_SAMPLER_PARAM" + envSamplerManagerHostPort = "JAEGER_SAMPLER_MANAGER_HOST_PORT" + envSamplerMaxOperations = "JAEGER_SAMPLER_MAX_OPERATIONS" + envSamplerRefreshInterval = "JAEGER_SAMPLER_REFRESH_INTERVAL" + envReporterMaxQueueSize = "JAEGER_REPORTER_MAX_QUEUE_SIZE" + envReporterFlushInterval = "JAEGER_REPORTER_FLUSH_INTERVAL" + envReporterLogSpans = "JAEGER_REPORTER_LOG_SPANS" + envAgentHost = "JAEGER_AGENT_HOST" + envAgentPort = "JAEGER_AGENT_PORT" +) + +// FromEnv uses environment variables to set the tracer's Configuration +func FromEnv() (*Configuration, error) { + c := &Configuration{} + + if e := os.Getenv(envServiceName); e != "" { + c.ServiceName = e + } + + if e := os.Getenv(envRPCMetrics); e != "" { + if value, err := strconv.ParseBool(e); err == nil { + c.RPCMetrics = value + } else { + return nil, errors.Wrapf(err, "cannot parse env var %s=%s", envRPCMetrics, e) + } + } + + if e := os.Getenv(envDisabled); e != "" { + if value, err := strconv.ParseBool(e); err == nil { + c.Disabled = value + } else { + return nil, errors.Wrapf(err, "cannot parse env var %s=%s", envDisabled, e) + } + } + + if e := os.Getenv(envTags); e != "" { + c.Tags = parseTags(e) + } + + if s, err := samplerConfigFromEnv(); err == nil { + c.Sampler = s + } else { + return nil, errors.Wrap(err, "cannot obtain sampler config from env") + } + + if r, err := reporterConfigFromEnv(); err == nil { + c.Reporter = r + } else { + return nil, errors.Wrap(err, "cannot obtain reporter config from env") + } + + return c, nil +} + +// samplerConfigFromEnv creates a new SamplerConfig based on the environment variables +func samplerConfigFromEnv() (*SamplerConfig, error) { + sc := &SamplerConfig{} + + if e := os.Getenv(envSamplerType); e != "" { + sc.Type = e + } + + if e := os.Getenv(envSamplerParam); e != "" { + if value, err := strconv.ParseFloat(e, 64); err == nil { + sc.Param = value + } else { + return nil, errors.Wrapf(err, "cannot parse env var %s=%s", envSamplerParam, e) + } + } + + if e := os.Getenv(envSamplerManagerHostPort); e != "" { + sc.SamplingServerURL = e + } + + if e := os.Getenv(envSamplerMaxOperations); e != "" { + if value, err := strconv.ParseInt(e, 10, 0); err == nil { + sc.MaxOperations = int(value) + } else { + return nil, errors.Wrapf(err, "cannot parse env var %s=%s", envSamplerMaxOperations, e) + } + } + + if e := os.Getenv(envSamplerRefreshInterval); e != "" { + if value, err := time.ParseDuration(e); err == nil { + sc.SamplingRefreshInterval = value + } else { + return nil, errors.Wrapf(err, "cannot parse env var %s=%s", envSamplerRefreshInterval, e) + } + } + + return sc, nil +} + +// reporterConfigFromEnv creates a new ReporterConfig based on the environment variables +func reporterConfigFromEnv() (*ReporterConfig, error) { + rc := &ReporterConfig{} + + if e := os.Getenv(envReporterMaxQueueSize); e != "" { + if value, err := strconv.ParseInt(e, 10, 0); err == nil { + rc.QueueSize = int(value) + } else { + return nil, errors.Wrapf(err, "cannot parse env var %s=%s", envReporterMaxQueueSize, e) + } + } + + if e := os.Getenv(envReporterFlushInterval); e != "" { + if value, err := time.ParseDuration(e); err == nil { + rc.BufferFlushInterval = value + } else { + return nil, errors.Wrapf(err, "cannot parse env var %s=%s", envReporterFlushInterval, e) + } + } + + if e := os.Getenv(envReporterLogSpans); e != "" { + if value, err := strconv.ParseBool(e); err == nil { + rc.LogSpans = value + } else { + return nil, errors.Wrapf(err, "cannot parse env var %s=%s", envReporterLogSpans, e) + } + } + + host := jaeger.DefaultUDPSpanServerHost + if e := os.Getenv(envAgentHost); e != "" { + host = e + } + + port := jaeger.DefaultUDPSpanServerPort + if e := os.Getenv(envAgentPort); e != "" { + if value, err := strconv.ParseInt(e, 10, 0); err == nil { + port = int(value) + } else { + return nil, errors.Wrapf(err, "cannot parse env var %s=%s", envAgentPort, e) + } + } + + // the side effect of this is that we are building the default value, even if none of the env vars + // were not explicitly passed + rc.LocalAgentHostPort = fmt.Sprintf("%s:%d", host, port) + + return rc, nil +} + +// parseTags parses the given string into a collection of Tags. +// Spec for this value: +// - comma separated list of key=value +// - value can be specified using the notation ${envVar:defaultValue}, where `envVar` +// is an environment variable and `defaultValue` is the value to use in case the env var is not set +func parseTags(sTags string) []opentracing.Tag { + pairs := strings.Split(sTags, ",") + tags := make([]opentracing.Tag, 0) + for _, p := range pairs { + kv := strings.SplitN(p, "=", 2) + k, v := strings.TrimSpace(kv[0]), strings.TrimSpace(kv[1]) + + if strings.HasPrefix(v, "${") && strings.HasSuffix(v, "}") { + ed := strings.SplitN(v[2:len(v)-1], ":", 2) + e, d := ed[0], ed[1] + v = os.Getenv(e) + if v == "" && d != "" { + v = d + } + } + + tag := opentracing.Tag{Key: k, Value: v} + tags = append(tags, tag) + } + + return tags +} diff --git a/vendor/github.com/uber/jaeger-client-go/config/options.go b/vendor/github.com/uber/jaeger-client-go/config/options.go new file mode 100644 index 0000000000..d14f1f8a9b --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/config/options.go @@ -0,0 +1,148 @@ +// Copyright (c) 2017 Uber Technologies, Inc. +// +// 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 config + +import ( + opentracing "github.com/opentracing/opentracing-go" + "github.com/uber/jaeger-lib/metrics" + + "github.com/uber/jaeger-client-go" +) + +// Option is a function that sets some option on the client. +type Option func(c *Options) + +// Options control behavior of the client. +type Options struct { + metrics metrics.Factory + logger jaeger.Logger + reporter jaeger.Reporter + sampler jaeger.Sampler + contribObservers []jaeger.ContribObserver + observers []jaeger.Observer + gen128Bit bool + zipkinSharedRPCSpan bool + maxTagValueLength int + tags []opentracing.Tag + injectors map[interface{}]jaeger.Injector + extractors map[interface{}]jaeger.Extractor +} + +// Metrics creates an Option that initializes Metrics in the tracer, +// which is used to emit statistics about spans. +func Metrics(factory metrics.Factory) Option { + return func(c *Options) { + c.metrics = factory + } +} + +// Logger can be provided to log Reporter errors, as well as to log spans +// if Reporter.LogSpans is set to true. +func Logger(logger jaeger.Logger) Option { + return func(c *Options) { + c.logger = logger + } +} + +// Reporter can be provided explicitly to override the configuration. +// Useful for testing, e.g. by passing InMemoryReporter. +func Reporter(reporter jaeger.Reporter) Option { + return func(c *Options) { + c.reporter = reporter + } +} + +// Sampler can be provided explicitly to override the configuration. +func Sampler(sampler jaeger.Sampler) Option { + return func(c *Options) { + c.sampler = sampler + } +} + +// Observer can be registered with the Tracer to receive notifications about new Spans. +func Observer(observer jaeger.Observer) Option { + return func(c *Options) { + c.observers = append(c.observers, observer) + } +} + +// ContribObserver can be registered with the Tracer to recieve notifications +// about new spans. +func ContribObserver(observer jaeger.ContribObserver) Option { + return func(c *Options) { + c.contribObservers = append(c.contribObservers, observer) + } +} + +// Gen128Bit specifies whether to generate 128bit trace IDs. +func Gen128Bit(gen128Bit bool) Option { + return func(c *Options) { + c.gen128Bit = gen128Bit + } +} + +// ZipkinSharedRPCSpan creates an option that enables sharing span ID between client +// and server spans a la zipkin. If false, client and server spans will be assigned +// different IDs. +func ZipkinSharedRPCSpan(zipkinSharedRPCSpan bool) Option { + return func(c *Options) { + c.zipkinSharedRPCSpan = zipkinSharedRPCSpan + } +} + +// MaxTagValueLength can be provided to override the default max tag value length. +func MaxTagValueLength(maxTagValueLength int) Option { + return func(c *Options) { + c.maxTagValueLength = maxTagValueLength + } +} + +// Tag creates an option that adds a tracer-level tag. +func Tag(key string, value interface{}) Option { + return func(c *Options) { + c.tags = append(c.tags, opentracing.Tag{Key: key, Value: value}) + } +} + +// Injector registers an Injector with the given format. +func Injector(format interface{}, injector jaeger.Injector) Option { + return func(c *Options) { + c.injectors[format] = injector + } +} + +// Extractor registers an Extractor with the given format. +func Extractor(format interface{}, extractor jaeger.Extractor) Option { + return func(c *Options) { + c.extractors[format] = extractor + } +} + +func applyOptions(options ...Option) Options { + opts := Options{ + injectors: make(map[interface{}]jaeger.Injector), + extractors: make(map[interface{}]jaeger.Extractor), + } + for _, option := range options { + option(&opts) + } + if opts.metrics == nil { + opts.metrics = metrics.NullFactory + } + if opts.logger == nil { + opts.logger = jaeger.NullLogger + } + return opts +} diff --git a/vendor/github.com/uber/jaeger-client-go/constants.go b/vendor/github.com/uber/jaeger-client-go/constants.go new file mode 100644 index 0000000000..b5368ff381 --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/constants.go @@ -0,0 +1,88 @@ +// Copyright (c) 2017 Uber Technologies, Inc. +// +// 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 jaeger + +const ( + // JaegerClientVersion is the version of the client library reported as Span tag. + JaegerClientVersion = "Go-2.15.0-dev" + + // JaegerClientVersionTagKey is the name of the tag used to report client version. + JaegerClientVersionTagKey = "jaeger.version" + + // JaegerDebugHeader is the name of HTTP header or a TextMap carrier key which, + // if found in the carrier, forces the trace to be sampled as "debug" trace. + // The value of the header is recorded as the tag on the root span, so that the + // trace can be found in the UI using this value as a correlation ID. + JaegerDebugHeader = "jaeger-debug-id" + + // JaegerBaggageHeader is the name of the HTTP header that is used to submit baggage. + // It differs from TraceBaggageHeaderPrefix in that it can be used only in cases where + // a root span does not exist. + JaegerBaggageHeader = "jaeger-baggage" + + // TracerHostnameTagKey used to report host name of the process. + TracerHostnameTagKey = "hostname" + + // TracerIPTagKey used to report ip of the process. + TracerIPTagKey = "ip" + + // TracerUUIDTagKey used to report UUID of the client process. + TracerUUIDTagKey = "client-uuid" + + // SamplerTypeTagKey reports which sampler was used on the root span. + SamplerTypeTagKey = "sampler.type" + + // SamplerParamTagKey reports the parameter of the sampler, like sampling probability. + SamplerParamTagKey = "sampler.param" + + // TraceContextHeaderName is the http header name used to propagate tracing context. + // This must be in lower-case to avoid mismatches when decoding incoming headers. + TraceContextHeaderName = "uber-trace-id" + + // TracerStateHeaderName is deprecated. + // Deprecated: use TraceContextHeaderName + TracerStateHeaderName = TraceContextHeaderName + + // TraceBaggageHeaderPrefix is the prefix for http headers used to propagate baggage. + // This must be in lower-case to avoid mismatches when decoding incoming headers. + TraceBaggageHeaderPrefix = "uberctx-" + + // SamplerTypeConst is the type of sampler that always makes the same decision. + SamplerTypeConst = "const" + + // SamplerTypeRemote is the type of sampler that polls Jaeger agent for sampling strategy. + SamplerTypeRemote = "remote" + + // SamplerTypeProbabilistic is the type of sampler that samples traces + // with a certain fixed probability. + SamplerTypeProbabilistic = "probabilistic" + + // SamplerTypeRateLimiting is the type of sampler that samples + // only up to a fixed number of traces per second. + SamplerTypeRateLimiting = "ratelimiting" + + // SamplerTypeLowerBound is the type of sampler that samples + // at least a fixed number of traces per second. + SamplerTypeLowerBound = "lowerbound" + + // DefaultUDPSpanServerHost is the default host to send the spans to, via UDP + DefaultUDPSpanServerHost = "localhost" + + // DefaultUDPSpanServerPort is the default port to send the spans to, via UDP + DefaultUDPSpanServerPort = 6831 + + // DefaultMaxTagValueLength is the default max length of byte array or string allowed in the tag value. + DefaultMaxTagValueLength = 256 +) diff --git a/vendor/github.com/uber/jaeger-client-go/context.go b/vendor/github.com/uber/jaeger-client-go/context.go new file mode 100644 index 0000000000..8b06173d98 --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/context.go @@ -0,0 +1,258 @@ +// Copyright (c) 2017 Uber Technologies, Inc. +// +// 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 jaeger + +import ( + "errors" + "fmt" + "strconv" + "strings" +) + +const ( + flagSampled = byte(1) + flagDebug = byte(2) +) + +var ( + errEmptyTracerStateString = errors.New("Cannot convert empty string to tracer state") + errMalformedTracerStateString = errors.New("String does not match tracer state format") + + emptyContext = SpanContext{} +) + +// TraceID represents unique 128bit identifier of a trace +type TraceID struct { + High, Low uint64 +} + +// SpanID represents unique 64bit identifier of a span +type SpanID uint64 + +// SpanContext represents propagated span identity and state +type SpanContext struct { + // traceID represents globally unique ID of the trace. + // Usually generated as a random number. + traceID TraceID + + // spanID represents span ID that must be unique within its trace, + // but does not have to be globally unique. + spanID SpanID + + // parentID refers to the ID of the parent span. + // Should be 0 if the current span is a root span. + parentID SpanID + + // flags is a bitmap containing such bits as 'sampled' and 'debug'. + flags byte + + // Distributed Context baggage. The is a snapshot in time. + baggage map[string]string + + // debugID can be set to some correlation ID when the context is being + // extracted from a TextMap carrier. + // + // See JaegerDebugHeader in constants.go + debugID string +} + +// ForeachBaggageItem implements ForeachBaggageItem() of opentracing.SpanContext +func (c SpanContext) ForeachBaggageItem(handler func(k, v string) bool) { + for k, v := range c.baggage { + if !handler(k, v) { + break + } + } +} + +// IsSampled returns whether this trace was chosen for permanent storage +// by the sampling mechanism of the tracer. +func (c SpanContext) IsSampled() bool { + return (c.flags & flagSampled) == flagSampled +} + +// IsDebug indicates whether sampling was explicitly requested by the service. +func (c SpanContext) IsDebug() bool { + return (c.flags & flagDebug) == flagDebug +} + +// IsValid indicates whether this context actually represents a valid trace. +func (c SpanContext) IsValid() bool { + return c.traceID.IsValid() && c.spanID != 0 +} + +func (c SpanContext) String() string { + if c.traceID.High == 0 { + return fmt.Sprintf("%x:%x:%x:%x", c.traceID.Low, uint64(c.spanID), uint64(c.parentID), c.flags) + } + return fmt.Sprintf("%x%016x:%x:%x:%x", c.traceID.High, c.traceID.Low, uint64(c.spanID), uint64(c.parentID), c.flags) +} + +// ContextFromString reconstructs the Context encoded in a string +func ContextFromString(value string) (SpanContext, error) { + var context SpanContext + if value == "" { + return emptyContext, errEmptyTracerStateString + } + parts := strings.Split(value, ":") + if len(parts) != 4 { + return emptyContext, errMalformedTracerStateString + } + var err error + if context.traceID, err = TraceIDFromString(parts[0]); err != nil { + return emptyContext, err + } + if context.spanID, err = SpanIDFromString(parts[1]); err != nil { + return emptyContext, err + } + if context.parentID, err = SpanIDFromString(parts[2]); err != nil { + return emptyContext, err + } + flags, err := strconv.ParseUint(parts[3], 10, 8) + if err != nil { + return emptyContext, err + } + context.flags = byte(flags) + return context, nil +} + +// TraceID returns the trace ID of this span context +func (c SpanContext) TraceID() TraceID { + return c.traceID +} + +// SpanID returns the span ID of this span context +func (c SpanContext) SpanID() SpanID { + return c.spanID +} + +// ParentID returns the parent span ID of this span context +func (c SpanContext) ParentID() SpanID { + return c.parentID +} + +// NewSpanContext creates a new instance of SpanContext +func NewSpanContext(traceID TraceID, spanID, parentID SpanID, sampled bool, baggage map[string]string) SpanContext { + flags := byte(0) + if sampled { + flags = flagSampled + } + return SpanContext{ + traceID: traceID, + spanID: spanID, + parentID: parentID, + flags: flags, + baggage: baggage} +} + +// CopyFrom copies data from ctx into this context, including span identity and baggage. +// TODO This is only used by interop.go. Remove once TChannel Go supports OpenTracing. +func (c *SpanContext) CopyFrom(ctx *SpanContext) { + c.traceID = ctx.traceID + c.spanID = ctx.spanID + c.parentID = ctx.parentID + c.flags = ctx.flags + if l := len(ctx.baggage); l > 0 { + c.baggage = make(map[string]string, l) + for k, v := range ctx.baggage { + c.baggage[k] = v + } + } else { + c.baggage = nil + } +} + +// WithBaggageItem creates a new context with an extra baggage item. +func (c SpanContext) WithBaggageItem(key, value string) SpanContext { + var newBaggage map[string]string + if c.baggage == nil { + newBaggage = map[string]string{key: value} + } else { + newBaggage = make(map[string]string, len(c.baggage)+1) + for k, v := range c.baggage { + newBaggage[k] = v + } + newBaggage[key] = value + } + // Use positional parameters so the compiler will help catch new fields. + return SpanContext{c.traceID, c.spanID, c.parentID, c.flags, newBaggage, ""} +} + +// isDebugIDContainerOnly returns true when the instance of the context is only +// used to return the debug/correlation ID from extract() method. This happens +// in the situation when "jaeger-debug-id" header is passed in the carrier to +// the extract() method, but the request otherwise has no span context in it. +// Previously this would've returned opentracing.ErrSpanContextNotFound from the +// extract method, but now it returns a dummy context with only debugID filled in. +// +// See JaegerDebugHeader in constants.go +// See textMapPropagator#Extract +func (c *SpanContext) isDebugIDContainerOnly() bool { + return !c.traceID.IsValid() && c.debugID != "" +} + +// ------- TraceID ------- + +func (t TraceID) String() string { + if t.High == 0 { + return fmt.Sprintf("%x", t.Low) + } + return fmt.Sprintf("%x%016x", t.High, t.Low) +} + +// TraceIDFromString creates a TraceID from a hexadecimal string +func TraceIDFromString(s string) (TraceID, error) { + var hi, lo uint64 + var err error + if len(s) > 32 { + return TraceID{}, fmt.Errorf("TraceID cannot be longer than 32 hex characters: %s", s) + } else if len(s) > 16 { + hiLen := len(s) - 16 + if hi, err = strconv.ParseUint(s[0:hiLen], 16, 64); err != nil { + return TraceID{}, err + } + if lo, err = strconv.ParseUint(s[hiLen:], 16, 64); err != nil { + return TraceID{}, err + } + } else { + if lo, err = strconv.ParseUint(s, 16, 64); err != nil { + return TraceID{}, err + } + } + return TraceID{High: hi, Low: lo}, nil +} + +// IsValid checks if the trace ID is valid, i.e. not zero. +func (t TraceID) IsValid() bool { + return t.High != 0 || t.Low != 0 +} + +// ------- SpanID ------- + +func (s SpanID) String() string { + return fmt.Sprintf("%x", uint64(s)) +} + +// SpanIDFromString creates a SpanID from a hexadecimal string +func SpanIDFromString(s string) (SpanID, error) { + if len(s) > 16 { + return SpanID(0), fmt.Errorf("SpanID cannot be longer than 16 hex characters: %s", s) + } + id, err := strconv.ParseUint(s, 16, 64) + if err != nil { + return SpanID(0), err + } + return SpanID(id), nil +} diff --git a/vendor/github.com/uber/jaeger-client-go/contrib_observer.go b/vendor/github.com/uber/jaeger-client-go/contrib_observer.go new file mode 100644 index 0000000000..4ce1881f3b --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/contrib_observer.go @@ -0,0 +1,56 @@ +// Copyright (c) 2017 Uber Technologies, Inc. +// +// 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 jaeger + +import ( + opentracing "github.com/opentracing/opentracing-go" +) + +// ContribObserver can be registered with the Tracer to receive notifications +// about new Spans. Modelled after github.com/opentracing-contrib/go-observer. +type ContribObserver interface { + // Create and return a span observer. Called when a span starts. + // If the Observer is not interested in the given span, it must return (nil, false). + // E.g : + // func StartSpan(opName string, opts ...opentracing.StartSpanOption) { + // var sp opentracing.Span + // sso := opentracing.StartSpanOptions{} + // if spanObserver, ok := Observer.OnStartSpan(span, opName, sso); ok { + // // we have a valid SpanObserver + // } + // ... + // } + OnStartSpan(sp opentracing.Span, operationName string, options opentracing.StartSpanOptions) (ContribSpanObserver, bool) +} + +// ContribSpanObserver is created by the Observer and receives notifications +// about other Span events. This interface is meant to match +// github.com/opentracing-contrib/go-observer, via duck typing, without +// directly importing the go-observer package. +type ContribSpanObserver interface { + OnSetOperationName(operationName string) + OnSetTag(key string, value interface{}) + OnFinish(options opentracing.FinishOptions) +} + +// wrapper observer for the old observers (see observer.go) +type oldObserver struct { + obs Observer +} + +func (o *oldObserver) OnStartSpan(sp opentracing.Span, operationName string, options opentracing.StartSpanOptions) (ContribSpanObserver, bool) { + spanObserver := o.obs.OnStartSpan(operationName, options) + return spanObserver, spanObserver != nil +} diff --git a/vendor/github.com/uber/jaeger-client-go/doc.go b/vendor/github.com/uber/jaeger-client-go/doc.go new file mode 100644 index 0000000000..4f5549033d --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/doc.go @@ -0,0 +1,24 @@ +// Copyright (c) 2017 Uber Technologies, Inc. +// +// 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 jaeger implements an OpenTracing (http://opentracing.io) Tracer. +It is currently using Zipkin-compatible data model and can be directly +itegrated with Zipkin backend (http://zipkin.io). + +For integration instructions please refer to the README: + +https://github.com/uber/jaeger-client-go/blob/master/README.md +*/ +package jaeger diff --git a/vendor/github.com/uber/jaeger-client-go/glide.lock b/vendor/github.com/uber/jaeger-client-go/glide.lock new file mode 100644 index 0000000000..d76b153617 --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/glide.lock @@ -0,0 +1,89 @@ +hash: 3accf84f97bff4a91162736104c0e9b9790820712bd86db6fec5e665f7196a82 +updated: 2018-04-30T11:46:43.804556-04:00 +imports: +- name: github.com/beorn7/perks + version: 3a771d992973f24aa725d07868b467d1ddfceafb + subpackages: + - quantile +- name: github.com/codahale/hdrhistogram + version: 3a0bb77429bd3a61596f5e8a3172445844342120 +- name: github.com/crossdock/crossdock-go + version: 049aabb0122b03bc9bd30cab8f3f91fb60166361 + subpackages: + - assert + - require +- name: github.com/davecgh/go-spew + version: 8991bc29aa16c548c550c7ff78260e27b9ab7c73 + subpackages: + - spew +- name: github.com/golang/protobuf + version: bbd03ef6da3a115852eaf24c8a1c46aeb39aa175 + subpackages: + - proto +- name: github.com/matttproud/golang_protobuf_extensions + version: c12348ce28de40eed0136aa2b644d0ee0650e56c + subpackages: + - pbutil +- name: github.com/opentracing/opentracing-go + version: 1949ddbfd147afd4d964a9f00b24eb291e0e7c38 + subpackages: + - ext + - log +- name: github.com/pkg/errors + version: 645ef00459ed84a119197bfb8d8205042c6df63d +- name: github.com/pmezard/go-difflib + version: 792786c7400a136282c1664665ae0a8db921c6c2 + subpackages: + - difflib +- name: github.com/prometheus/client_golang + version: c5b7fccd204277076155f10851dad72b76a49317 + subpackages: + - prometheus +- name: github.com/prometheus/client_model + version: 99fa1f4be8e564e8a6b613da7fa6f46c9edafc6c + subpackages: + - go +- name: github.com/prometheus/common + version: 38c53a9f4bfcd932d1b00bfc65e256a7fba6b37a + subpackages: + - expfmt + - internal/bitbucket.org/ww/goautoneg + - model +- name: github.com/prometheus/procfs + version: 780932d4fbbe0e69b84c34c20f5c8d0981e109ea + subpackages: + - internal/util + - nfs + - xfs +- name: github.com/stretchr/testify + version: 12b6f73e6084dad08a7c6e575284b177ecafbc71 + subpackages: + - assert + - require + - suite +- name: github.com/uber/jaeger-lib + version: 4267858c0679cd4e47cefed8d7f70fd386cfb567 + subpackages: + - metrics + - metrics/prometheus + - metrics/testutils +- name: go.uber.org/atomic + version: 8474b86a5a6f79c443ce4b2992817ff32cf208b8 +- name: go.uber.org/multierr + version: 3c4937480c32f4c13a875a1829af76c98ca3d40a +- name: go.uber.org/zap + version: eeedf312bc6c57391d84767a4cd413f02a917974 + subpackages: + - buffer + - internal/bufferpool + - internal/color + - internal/exit + - zapcore +- name: golang.org/x/net + version: 6078986fec03a1dcc236c34816c71b0e05018fda + subpackages: + - context + - context/ctxhttp +testImports: +- name: github.com/uber-go/atomic + version: 8474b86a5a6f79c443ce4b2992817ff32cf208b8 diff --git a/vendor/github.com/uber/jaeger-client-go/glide.yaml b/vendor/github.com/uber/jaeger-client-go/glide.yaml new file mode 100644 index 0000000000..6637da2152 --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/glide.yaml @@ -0,0 +1,22 @@ +package: github.com/uber/jaeger-client-go +import: +- package: github.com/opentracing/opentracing-go + version: ^1 + subpackages: + - ext + - log +- package: github.com/crossdock/crossdock-go +- package: github.com/uber/jaeger-lib + version: ^1.2.1 + subpackages: + - metrics +- package: github.com/pkg/errors + version: ~0.8.0 +testImport: +- package: github.com/stretchr/testify + subpackages: + - assert + - require + - suite +- package: github.com/prometheus/client_golang + version: v0.8.0 diff --git a/vendor/github.com/uber/jaeger-client-go/header.go b/vendor/github.com/uber/jaeger-client-go/header.go new file mode 100644 index 0000000000..19c2c055b8 --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/header.go @@ -0,0 +1,64 @@ +// Copyright (c) 2017 Uber Technologies, Inc. +// +// 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 jaeger + +// HeadersConfig contains the values for the header keys that Jaeger will use. +// These values may be either custom or default depending on whether custom +// values were provided via a configuration. +type HeadersConfig struct { + // JaegerDebugHeader is the name of HTTP header or a TextMap carrier key which, + // if found in the carrier, forces the trace to be sampled as "debug" trace. + // The value of the header is recorded as the tag on the root span, so that the + // trace can be found in the UI using this value as a correlation ID. + JaegerDebugHeader string `yaml:"jaegerDebugHeader"` + + // JaegerBaggageHeader is the name of the HTTP header that is used to submit baggage. + // It differs from TraceBaggageHeaderPrefix in that it can be used only in cases where + // a root span does not exist. + JaegerBaggageHeader string `yaml:"jaegerBaggageHeader"` + + // TraceContextHeaderName is the http header name used to propagate tracing context. + // This must be in lower-case to avoid mismatches when decoding incoming headers. + TraceContextHeaderName string `yaml:"TraceContextHeaderName"` + + // TraceBaggageHeaderPrefix is the prefix for http headers used to propagate baggage. + // This must be in lower-case to avoid mismatches when decoding incoming headers. + TraceBaggageHeaderPrefix string `yaml:"traceBaggageHeaderPrefix"` +} + +func (c *HeadersConfig) applyDefaults() *HeadersConfig { + if c.JaegerBaggageHeader == "" { + c.JaegerBaggageHeader = JaegerBaggageHeader + } + if c.JaegerDebugHeader == "" { + c.JaegerDebugHeader = JaegerDebugHeader + } + if c.TraceBaggageHeaderPrefix == "" { + c.TraceBaggageHeaderPrefix = TraceBaggageHeaderPrefix + } + if c.TraceContextHeaderName == "" { + c.TraceContextHeaderName = TraceContextHeaderName + } + return c +} + +func getDefaultHeadersConfig() *HeadersConfig { + return &HeadersConfig{ + JaegerDebugHeader: JaegerDebugHeader, + JaegerBaggageHeader: JaegerBaggageHeader, + TraceContextHeaderName: TraceContextHeaderName, + TraceBaggageHeaderPrefix: TraceBaggageHeaderPrefix, + } +} diff --git a/vendor/github.com/uber/jaeger-client-go/internal/baggage/remote/options.go b/vendor/github.com/uber/jaeger-client-go/internal/baggage/remote/options.go new file mode 100644 index 0000000000..745729319f --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/internal/baggage/remote/options.go @@ -0,0 +1,101 @@ +// Copyright (c) 2017 Uber Technologies, Inc. +// +// 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 remote + +import ( + "time" + + "github.com/uber/jaeger-client-go" +) + +const ( + defaultMaxValueLength = 2048 + defaultRefreshInterval = time.Minute + defaultHostPort = "localhost:5778" +) + +// Option is a function that sets some option on the RestrictionManager +type Option func(options *options) + +// Options is a factory for all available options +var Options options + +type options struct { + denyBaggageOnInitializationFailure bool + metrics *jaeger.Metrics + logger jaeger.Logger + hostPort string + refreshInterval time.Duration +} + +// DenyBaggageOnInitializationFailure creates an Option that determines the startup failure mode of RestrictionManager. +// If DenyBaggageOnInitializationFailure is true, RestrictionManager will not allow any baggage to be written until baggage +// restrictions have been retrieved from agent. +// If DenyBaggageOnInitializationFailure is false, RestrictionManager will allow any baggage to be written until baggage +// restrictions have been retrieved from agent. +func (options) DenyBaggageOnInitializationFailure(b bool) Option { + return func(o *options) { + o.denyBaggageOnInitializationFailure = b + } +} + +// Metrics creates an Option that initializes Metrics on the RestrictionManager, which is used to emit statistics. +func (options) Metrics(m *jaeger.Metrics) Option { + return func(o *options) { + o.metrics = m + } +} + +// Logger creates an Option that sets the logger used by the RestrictionManager. +func (options) Logger(logger jaeger.Logger) Option { + return func(o *options) { + o.logger = logger + } +} + +// HostPort creates an Option that sets the hostPort of the local agent that contains the baggage restrictions. +func (options) HostPort(hostPort string) Option { + return func(o *options) { + o.hostPort = hostPort + } +} + +// RefreshInterval creates an Option that sets how often the RestrictionManager will poll local agent for +// the baggage restrictions. +func (options) RefreshInterval(refreshInterval time.Duration) Option { + return func(o *options) { + o.refreshInterval = refreshInterval + } +} + +func applyOptions(o ...Option) options { + opts := options{} + for _, option := range o { + option(&opts) + } + if opts.metrics == nil { + opts.metrics = jaeger.NewNullMetrics() + } + if opts.logger == nil { + opts.logger = jaeger.NullLogger + } + if opts.hostPort == "" { + opts.hostPort = defaultHostPort + } + if opts.refreshInterval == 0 { + opts.refreshInterval = defaultRefreshInterval + } + return opts +} diff --git a/vendor/github.com/uber/jaeger-client-go/internal/baggage/remote/restriction_manager.go b/vendor/github.com/uber/jaeger-client-go/internal/baggage/remote/restriction_manager.go new file mode 100644 index 0000000000..a56515acab --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/internal/baggage/remote/restriction_manager.go @@ -0,0 +1,157 @@ +// Copyright (c) 2017 Uber Technologies, Inc. +// +// 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 remote + +import ( + "fmt" + "net/url" + "sync" + "time" + + "github.com/uber/jaeger-client-go/internal/baggage" + thrift "github.com/uber/jaeger-client-go/thrift-gen/baggage" + "github.com/uber/jaeger-client-go/utils" +) + +type httpBaggageRestrictionManagerProxy struct { + url string +} + +func newHTTPBaggageRestrictionManagerProxy(hostPort, serviceName string) *httpBaggageRestrictionManagerProxy { + v := url.Values{} + v.Set("service", serviceName) + return &httpBaggageRestrictionManagerProxy{ + url: fmt.Sprintf("http://%s/baggageRestrictions?%s", hostPort, v.Encode()), + } +} + +func (s *httpBaggageRestrictionManagerProxy) GetBaggageRestrictions(serviceName string) ([]*thrift.BaggageRestriction, error) { + var out []*thrift.BaggageRestriction + if err := utils.GetJSON(s.url, &out); err != nil { + return nil, err + } + return out, nil +} + +// RestrictionManager manages baggage restrictions by retrieving baggage restrictions from agent +type RestrictionManager struct { + options + + mux sync.RWMutex + serviceName string + restrictions map[string]*baggage.Restriction + thriftProxy thrift.BaggageRestrictionManager + pollStopped sync.WaitGroup + stopPoll chan struct{} + invalidRestriction *baggage.Restriction + validRestriction *baggage.Restriction + + // Determines if the manager has successfully retrieved baggage restrictions from agent + initialized bool +} + +// NewRestrictionManager returns a BaggageRestrictionManager that polls the agent for the latest +// baggage restrictions. +func NewRestrictionManager(serviceName string, options ...Option) *RestrictionManager { + // TODO there is a developing use case where a single tracer can generate traces on behalf of many services. + // restrictionsMap will need to exist per service + opts := applyOptions(options...) + m := &RestrictionManager{ + serviceName: serviceName, + options: opts, + restrictions: make(map[string]*baggage.Restriction), + thriftProxy: newHTTPBaggageRestrictionManagerProxy(opts.hostPort, serviceName), + stopPoll: make(chan struct{}), + invalidRestriction: baggage.NewRestriction(false, 0), + validRestriction: baggage.NewRestriction(true, defaultMaxValueLength), + } + m.pollStopped.Add(1) + go m.pollManager() + return m +} + +// isReady returns true if the manager has retrieved baggage restrictions from the remote source. +func (m *RestrictionManager) isReady() bool { + m.mux.RLock() + defer m.mux.RUnlock() + return m.initialized +} + +// GetRestriction implements RestrictionManager#GetRestriction. +func (m *RestrictionManager) GetRestriction(service, key string) *baggage.Restriction { + m.mux.RLock() + defer m.mux.RUnlock() + if !m.initialized { + if m.denyBaggageOnInitializationFailure { + return m.invalidRestriction + } + return m.validRestriction + } + if restriction, ok := m.restrictions[key]; ok { + return restriction + } + return m.invalidRestriction +} + +// Close stops remote polling and closes the RemoteRestrictionManager. +func (m *RestrictionManager) Close() error { + close(m.stopPoll) + m.pollStopped.Wait() + return nil +} + +func (m *RestrictionManager) pollManager() { + defer m.pollStopped.Done() + // attempt to initialize baggage restrictions + if err := m.updateRestrictions(); err != nil { + m.logger.Error(fmt.Sprintf("Failed to initialize baggage restrictions: %s", err.Error())) + } + ticker := time.NewTicker(m.refreshInterval) + defer ticker.Stop() + + for { + select { + case <-ticker.C: + if err := m.updateRestrictions(); err != nil { + m.logger.Error(fmt.Sprintf("Failed to update baggage restrictions: %s", err.Error())) + } + case <-m.stopPoll: + return + } + } +} + +func (m *RestrictionManager) updateRestrictions() error { + restrictions, err := m.thriftProxy.GetBaggageRestrictions(m.serviceName) + if err != nil { + m.metrics.BaggageRestrictionsUpdateFailure.Inc(1) + return err + } + newRestrictions := m.parseRestrictions(restrictions) + m.metrics.BaggageRestrictionsUpdateSuccess.Inc(1) + m.mux.Lock() + defer m.mux.Unlock() + m.initialized = true + m.restrictions = newRestrictions + return nil +} + +func (m *RestrictionManager) parseRestrictions(restrictions []*thrift.BaggageRestriction) map[string]*baggage.Restriction { + setters := make(map[string]*baggage.Restriction, len(restrictions)) + for _, restriction := range restrictions { + setters[restriction.BaggageKey] = baggage.NewRestriction(true, int(restriction.MaxValueLength)) + } + return setters +} diff --git a/vendor/github.com/uber/jaeger-client-go/internal/baggage/restriction_manager.go b/vendor/github.com/uber/jaeger-client-go/internal/baggage/restriction_manager.go new file mode 100644 index 0000000000..c16a5c5662 --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/internal/baggage/restriction_manager.go @@ -0,0 +1,71 @@ +// Copyright (c) 2017 Uber Technologies, Inc. +// +// 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 baggage + +const ( + defaultMaxValueLength = 2048 +) + +// Restriction determines whether a baggage key is allowed and contains any restrictions on the baggage value. +type Restriction struct { + keyAllowed bool + maxValueLength int +} + +// NewRestriction returns a new Restriction. +func NewRestriction(keyAllowed bool, maxValueLength int) *Restriction { + return &Restriction{ + keyAllowed: keyAllowed, + maxValueLength: maxValueLength, + } +} + +// KeyAllowed returns whether the baggage key for this restriction is allowed. +func (r *Restriction) KeyAllowed() bool { + return r.keyAllowed +} + +// MaxValueLength returns the max length for the baggage value. +func (r *Restriction) MaxValueLength() int { + return r.maxValueLength +} + +// RestrictionManager keeps track of valid baggage keys and their restrictions. The manager +// will return a Restriction for a specific baggage key which will determine whether the baggage +// key is allowed for the current service and any other applicable restrictions on the baggage +// value. +type RestrictionManager interface { + GetRestriction(service, key string) *Restriction +} + +// DefaultRestrictionManager allows any baggage key. +type DefaultRestrictionManager struct { + defaultRestriction *Restriction +} + +// NewDefaultRestrictionManager returns a DefaultRestrictionManager. +func NewDefaultRestrictionManager(maxValueLength int) *DefaultRestrictionManager { + if maxValueLength == 0 { + maxValueLength = defaultMaxValueLength + } + return &DefaultRestrictionManager{ + defaultRestriction: &Restriction{keyAllowed: true, maxValueLength: maxValueLength}, + } +} + +// GetRestriction implements RestrictionManager#GetRestriction. +func (m *DefaultRestrictionManager) GetRestriction(service, key string) *Restriction { + return m.defaultRestriction +} diff --git a/vendor/github.com/uber/jaeger-client-go/internal/spanlog/json.go b/vendor/github.com/uber/jaeger-client-go/internal/spanlog/json.go new file mode 100644 index 0000000000..0e10b8a5aa --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/internal/spanlog/json.go @@ -0,0 +1,81 @@ +// Copyright (c) 2017 Uber Technologies, Inc. +// +// 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 spanlog + +import ( + "encoding/json" + "fmt" + + "github.com/opentracing/opentracing-go/log" +) + +type fieldsAsMap map[string]string + +// MaterializeWithJSON converts log Fields into JSON string +// TODO refactor into pluggable materializer +func MaterializeWithJSON(logFields []log.Field) ([]byte, error) { + fields := fieldsAsMap(make(map[string]string, len(logFields))) + for _, field := range logFields { + field.Marshal(fields) + } + if event, ok := fields["event"]; ok && len(fields) == 1 { + return []byte(event), nil + } + return json.Marshal(fields) +} + +func (ml fieldsAsMap) EmitString(key, value string) { + ml[key] = value +} + +func (ml fieldsAsMap) EmitBool(key string, value bool) { + ml[key] = fmt.Sprintf("%t", value) +} + +func (ml fieldsAsMap) EmitInt(key string, value int) { + ml[key] = fmt.Sprintf("%d", value) +} + +func (ml fieldsAsMap) EmitInt32(key string, value int32) { + ml[key] = fmt.Sprintf("%d", value) +} + +func (ml fieldsAsMap) EmitInt64(key string, value int64) { + ml[key] = fmt.Sprintf("%d", value) +} + +func (ml fieldsAsMap) EmitUint32(key string, value uint32) { + ml[key] = fmt.Sprintf("%d", value) +} + +func (ml fieldsAsMap) EmitUint64(key string, value uint64) { + ml[key] = fmt.Sprintf("%d", value) +} + +func (ml fieldsAsMap) EmitFloat32(key string, value float32) { + ml[key] = fmt.Sprintf("%f", value) +} + +func (ml fieldsAsMap) EmitFloat64(key string, value float64) { + ml[key] = fmt.Sprintf("%f", value) +} + +func (ml fieldsAsMap) EmitObject(key string, value interface{}) { + ml[key] = fmt.Sprintf("%+v", value) +} + +func (ml fieldsAsMap) EmitLazyLogger(value log.LazyLogger) { + value(ml) +} diff --git a/vendor/github.com/uber/jaeger-client-go/internal/throttler/remote/options.go b/vendor/github.com/uber/jaeger-client-go/internal/throttler/remote/options.go new file mode 100644 index 0000000000..f52c322fb6 --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/internal/throttler/remote/options.go @@ -0,0 +1,99 @@ +// Copyright (c) 2018 The Jaeger Authors. +// +// 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 remote + +import ( + "time" + + "github.com/uber/jaeger-client-go" +) + +const ( + defaultHostPort = "localhost:5778" + defaultRefreshInterval = time.Second * 5 +) + +// Option is a function that sets some option on the Throttler +type Option func(options *options) + +// Options is a factory for all available options +var Options options + +type options struct { + metrics *jaeger.Metrics + logger jaeger.Logger + hostPort string + refreshInterval time.Duration + synchronousInitialization bool +} + +// Metrics creates an Option that initializes Metrics on the Throttler, which is used to emit statistics. +func (options) Metrics(m *jaeger.Metrics) Option { + return func(o *options) { + o.metrics = m + } +} + +// Logger creates an Option that sets the logger used by the Throttler. +func (options) Logger(logger jaeger.Logger) Option { + return func(o *options) { + o.logger = logger + } +} + +// HostPort creates an Option that sets the hostPort of the local agent that keeps track of credits. +func (options) HostPort(hostPort string) Option { + return func(o *options) { + o.hostPort = hostPort + } +} + +// RefreshInterval creates an Option that sets how often the Throttler will poll local agent for +// credits. +func (options) RefreshInterval(refreshInterval time.Duration) Option { + return func(o *options) { + o.refreshInterval = refreshInterval + } +} + +// SynchronousInitialization creates an Option that determines whether the throttler should synchronously +// fetch credits from the agent when an operation is seen for the first time. This should be set to true +// if the client will be used by a short lived service that needs to ensure that credits are fetched upfront +// such that sampling or throttling occurs. +func (options) SynchronousInitialization(b bool) Option { + return func(o *options) { + o.synchronousInitialization = b + } +} + +func applyOptions(o ...Option) options { + opts := options{} + for _, option := range o { + option(&opts) + } + if opts.metrics == nil { + opts.metrics = jaeger.NewNullMetrics() + } + if opts.logger == nil { + opts.logger = jaeger.NullLogger + } + if opts.hostPort == "" { + opts.hostPort = defaultHostPort + } + if opts.refreshInterval == 0 { + opts.refreshInterval = defaultRefreshInterval + } + return opts +} diff --git a/vendor/github.com/uber/jaeger-client-go/internal/throttler/remote/throttler.go b/vendor/github.com/uber/jaeger-client-go/internal/throttler/remote/throttler.go new file mode 100644 index 0000000000..20f434fe49 --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/internal/throttler/remote/throttler.go @@ -0,0 +1,216 @@ +// Copyright (c) 2018 The Jaeger Authors. +// +// 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 remote + +import ( + "fmt" + "net/url" + "sync" + "sync/atomic" + "time" + + "github.com/pkg/errors" + + "github.com/uber/jaeger-client-go" + "github.com/uber/jaeger-client-go/utils" +) + +const ( + // minimumCredits is the minimum amount of credits necessary to not be throttled. + // i.e. if currentCredits > minimumCredits, then the operation will not be throttled. + minimumCredits = 1.0 +) + +var ( + errorUUIDNotSet = errors.New("Throttler UUID must be set") +) + +type operationBalance struct { + Operation string `json:"operation"` + Balance float64 `json:"balance"` +} + +type creditResponse struct { + Balances []operationBalance `json:"balances"` +} + +type httpCreditManagerProxy struct { + hostPort string +} + +func newHTTPCreditManagerProxy(hostPort string) *httpCreditManagerProxy { + return &httpCreditManagerProxy{ + hostPort: hostPort, + } +} + +// N.B. Operations list must not be empty. +func (m *httpCreditManagerProxy) FetchCredits(uuid, serviceName string, operations []string) (*creditResponse, error) { + params := url.Values{} + params.Set("service", serviceName) + params.Set("uuid", uuid) + for _, op := range operations { + params.Add("operations", op) + } + var resp creditResponse + if err := utils.GetJSON(fmt.Sprintf("http://%s/credits?%s", m.hostPort, params.Encode()), &resp); err != nil { + return nil, errors.Wrap(err, "Failed to receive credits from agent") + } + return &resp, nil +} + +// Throttler retrieves credits from agent and uses it to throttle operations. +type Throttler struct { + options + + mux sync.RWMutex + service string + uuid atomic.Value + creditManager *httpCreditManagerProxy + credits map[string]float64 // map of operation->credits + close chan struct{} + stopped sync.WaitGroup +} + +// NewThrottler returns a Throttler that polls agent for credits and uses them to throttle +// the service. +func NewThrottler(service string, options ...Option) *Throttler { + opts := applyOptions(options...) + creditManager := newHTTPCreditManagerProxy(opts.hostPort) + t := &Throttler{ + options: opts, + creditManager: creditManager, + service: service, + credits: make(map[string]float64), + close: make(chan struct{}), + } + t.stopped.Add(1) + go t.pollManager() + return t +} + +// IsAllowed implements Throttler#IsAllowed. +func (t *Throttler) IsAllowed(operation string) bool { + t.mux.Lock() + defer t.mux.Unlock() + value, ok := t.credits[operation] + if !ok || value == 0 { + if !ok { + // NOTE: This appears to be a no-op at first glance, but it stores + // the operation key in the map. Necessary for functionality of + // Throttler#operations method. + t.credits[operation] = 0 + } + if !t.synchronousInitialization { + t.metrics.ThrottledDebugSpans.Inc(1) + return false + } + // If it is the first time this operation is being checked, synchronously fetch + // the credits. + credits, err := t.fetchCredits([]string{operation}) + if err != nil { + // Failed to receive credits from agent, try again next time + t.logger.Error("Failed to fetch credits: " + err.Error()) + return false + } + if len(credits.Balances) == 0 { + // This shouldn't happen but just in case + return false + } + for _, opBalance := range credits.Balances { + t.credits[opBalance.Operation] += opBalance.Balance + } + } + return t.isAllowed(operation) +} + +// Close stops the throttler from fetching credits from remote. +func (t *Throttler) Close() error { + close(t.close) + t.stopped.Wait() + return nil +} + +// SetProcess implements ProcessSetter#SetProcess. It's imperative that the UUID is set before any remote +// requests are made. +func (t *Throttler) SetProcess(process jaeger.Process) { + if process.UUID != "" { + t.uuid.Store(process.UUID) + } +} + +// N.B. This function must be called with the Write Lock +func (t *Throttler) isAllowed(operation string) bool { + credits := t.credits[operation] + if credits < minimumCredits { + t.metrics.ThrottledDebugSpans.Inc(1) + return false + } + t.credits[operation] = credits - minimumCredits + return true +} + +func (t *Throttler) pollManager() { + defer t.stopped.Done() + ticker := time.NewTicker(t.refreshInterval) + defer ticker.Stop() + for { + select { + case <-ticker.C: + t.refreshCredits() + case <-t.close: + return + } + } +} + +func (t *Throttler) operations() []string { + t.mux.RLock() + defer t.mux.RUnlock() + operations := make([]string, 0, len(t.credits)) + for op := range t.credits { + operations = append(operations, op) + } + return operations +} + +func (t *Throttler) refreshCredits() { + operations := t.operations() + if len(operations) == 0 { + return + } + newCredits, err := t.fetchCredits(operations) + if err != nil { + t.metrics.ThrottlerUpdateFailure.Inc(1) + t.logger.Error("Failed to fetch credits: " + err.Error()) + return + } + t.metrics.ThrottlerUpdateSuccess.Inc(1) + + t.mux.Lock() + defer t.mux.Unlock() + for _, opBalance := range newCredits.Balances { + t.credits[opBalance.Operation] += opBalance.Balance + } +} + +func (t *Throttler) fetchCredits(operations []string) (*creditResponse, error) { + uuid := t.uuid.Load() + uuidStr, _ := uuid.(string) + if uuid == nil || uuidStr == "" { + return nil, errorUUIDNotSet + } + return t.creditManager.FetchCredits(uuidStr, t.service, operations) +} diff --git a/vendor/github.com/uber/jaeger-client-go/internal/throttler/throttler.go b/vendor/github.com/uber/jaeger-client-go/internal/throttler/throttler.go new file mode 100644 index 0000000000..196ed69cac --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/internal/throttler/throttler.go @@ -0,0 +1,32 @@ +// Copyright (c) 2018 The Jaeger Authors. +// +// 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 throttler + +// Throttler is used to rate limits operations. For example, given how debug spans +// are always sampled, a throttler can be enabled per client to rate limit the amount +// of debug spans a client can start. +type Throttler interface { + // IsAllowed determines whether the operation should be allowed and not be + // throttled. + IsAllowed(operation string) bool +} + +// DefaultThrottler doesn't throttle at all. +type DefaultThrottler struct{} + +// IsAllowed implements Throttler#IsAllowed. +func (t DefaultThrottler) IsAllowed(operation string) bool { + return true +} diff --git a/vendor/github.com/uber/jaeger-client-go/interop.go b/vendor/github.com/uber/jaeger-client-go/interop.go new file mode 100644 index 0000000000..8402d087c2 --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/interop.go @@ -0,0 +1,55 @@ +// Copyright (c) 2017 Uber Technologies, Inc. +// +// 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 jaeger + +import ( + "github.com/opentracing/opentracing-go" +) + +// TODO this file should not be needed after TChannel PR. + +type formatKey int + +// SpanContextFormat is a constant used as OpenTracing Format. +// Requires *SpanContext as carrier. +// This format is intended for interop with TChannel or other Zipkin-like tracers. +const SpanContextFormat formatKey = iota + +type jaegerTraceContextPropagator struct { + tracer *Tracer +} + +func (p *jaegerTraceContextPropagator) Inject( + ctx SpanContext, + abstractCarrier interface{}, +) error { + carrier, ok := abstractCarrier.(*SpanContext) + if !ok { + return opentracing.ErrInvalidCarrier + } + + carrier.CopyFrom(&ctx) + return nil +} + +func (p *jaegerTraceContextPropagator) Extract(abstractCarrier interface{}) (SpanContext, error) { + carrier, ok := abstractCarrier.(*SpanContext) + if !ok { + return emptyContext, opentracing.ErrInvalidCarrier + } + ctx := new(SpanContext) + ctx.CopyFrom(carrier) + return *ctx, nil +} diff --git a/vendor/github.com/uber/jaeger-client-go/jaeger_tag.go b/vendor/github.com/uber/jaeger-client-go/jaeger_tag.go new file mode 100644 index 0000000000..868b2a5b54 --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/jaeger_tag.go @@ -0,0 +1,84 @@ +// Copyright (c) 2017 Uber Technologies, Inc. +// +// 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 jaeger + +import ( + "fmt" + + "github.com/opentracing/opentracing-go/log" + + j "github.com/uber/jaeger-client-go/thrift-gen/jaeger" +) + +type tags []*j.Tag + +// ConvertLogsToJaegerTags converts log Fields into jaeger tags. +func ConvertLogsToJaegerTags(logFields []log.Field) []*j.Tag { + fields := tags(make([]*j.Tag, 0, len(logFields))) + for _, field := range logFields { + field.Marshal(&fields) + } + return fields +} + +func (t *tags) EmitString(key, value string) { + *t = append(*t, &j.Tag{Key: key, VType: j.TagType_STRING, VStr: &value}) +} + +func (t *tags) EmitBool(key string, value bool) { + *t = append(*t, &j.Tag{Key: key, VType: j.TagType_BOOL, VBool: &value}) +} + +func (t *tags) EmitInt(key string, value int) { + vLong := int64(value) + *t = append(*t, &j.Tag{Key: key, VType: j.TagType_LONG, VLong: &vLong}) +} + +func (t *tags) EmitInt32(key string, value int32) { + vLong := int64(value) + *t = append(*t, &j.Tag{Key: key, VType: j.TagType_LONG, VLong: &vLong}) +} + +func (t *tags) EmitInt64(key string, value int64) { + *t = append(*t, &j.Tag{Key: key, VType: j.TagType_LONG, VLong: &value}) +} + +func (t *tags) EmitUint32(key string, value uint32) { + vLong := int64(value) + *t = append(*t, &j.Tag{Key: key, VType: j.TagType_LONG, VLong: &vLong}) +} + +func (t *tags) EmitUint64(key string, value uint64) { + vLong := int64(value) + *t = append(*t, &j.Tag{Key: key, VType: j.TagType_LONG, VLong: &vLong}) +} + +func (t *tags) EmitFloat32(key string, value float32) { + vDouble := float64(value) + *t = append(*t, &j.Tag{Key: key, VType: j.TagType_DOUBLE, VDouble: &vDouble}) +} + +func (t *tags) EmitFloat64(key string, value float64) { + *t = append(*t, &j.Tag{Key: key, VType: j.TagType_DOUBLE, VDouble: &value}) +} + +func (t *tags) EmitObject(key string, value interface{}) { + vStr := fmt.Sprintf("%+v", value) + *t = append(*t, &j.Tag{Key: key, VType: j.TagType_STRING, VStr: &vStr}) +} + +func (t *tags) EmitLazyLogger(value log.LazyLogger) { + value(t) +} diff --git a/vendor/github.com/uber/jaeger-client-go/jaeger_thrift_span.go b/vendor/github.com/uber/jaeger-client-go/jaeger_thrift_span.go new file mode 100644 index 0000000000..6ce1caf873 --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/jaeger_thrift_span.go @@ -0,0 +1,179 @@ +// Copyright (c) 2017 Uber Technologies, Inc. +// +// 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 jaeger + +import ( + "time" + + "github.com/opentracing/opentracing-go" + + j "github.com/uber/jaeger-client-go/thrift-gen/jaeger" + "github.com/uber/jaeger-client-go/utils" +) + +// BuildJaegerThrift builds jaeger span based on internal span. +func BuildJaegerThrift(span *Span) *j.Span { + span.Lock() + defer span.Unlock() + startTime := utils.TimeToMicrosecondsSinceEpochInt64(span.startTime) + duration := span.duration.Nanoseconds() / int64(time.Microsecond) + jaegerSpan := &j.Span{ + TraceIdLow: int64(span.context.traceID.Low), + TraceIdHigh: int64(span.context.traceID.High), + SpanId: int64(span.context.spanID), + ParentSpanId: int64(span.context.parentID), + OperationName: span.operationName, + Flags: int32(span.context.flags), + StartTime: startTime, + Duration: duration, + Tags: buildTags(span.tags, span.tracer.options.maxTagValueLength), + Logs: buildLogs(span.logs), + References: buildReferences(span.references), + } + return jaegerSpan +} + +// BuildJaegerProcessThrift creates a thrift Process type. +func BuildJaegerProcessThrift(span *Span) *j.Process { + span.Lock() + defer span.Unlock() + return buildJaegerProcessThrift(span.tracer) +} + +func buildJaegerProcessThrift(tracer *Tracer) *j.Process { + process := &j.Process{ + ServiceName: tracer.serviceName, + Tags: buildTags(tracer.tags, tracer.options.maxTagValueLength), + } + if tracer.process.UUID != "" { + process.Tags = append(process.Tags, &j.Tag{Key: TracerUUIDTagKey, VStr: &tracer.process.UUID, VType: j.TagType_STRING}) + } + return process +} + +func buildTags(tags []Tag, maxTagValueLength int) []*j.Tag { + jTags := make([]*j.Tag, 0, len(tags)) + for _, tag := range tags { + jTag := buildTag(&tag, maxTagValueLength) + jTags = append(jTags, jTag) + } + return jTags +} + +func buildLogs(logs []opentracing.LogRecord) []*j.Log { + jLogs := make([]*j.Log, 0, len(logs)) + for _, log := range logs { + jLog := &j.Log{ + Timestamp: utils.TimeToMicrosecondsSinceEpochInt64(log.Timestamp), + Fields: ConvertLogsToJaegerTags(log.Fields), + } + jLogs = append(jLogs, jLog) + } + return jLogs +} + +func buildTag(tag *Tag, maxTagValueLength int) *j.Tag { + jTag := &j.Tag{Key: tag.key} + switch value := tag.value.(type) { + case string: + vStr := truncateString(value, maxTagValueLength) + jTag.VStr = &vStr + jTag.VType = j.TagType_STRING + case []byte: + if len(value) > maxTagValueLength { + value = value[:maxTagValueLength] + } + jTag.VBinary = value + jTag.VType = j.TagType_BINARY + case int: + vLong := int64(value) + jTag.VLong = &vLong + jTag.VType = j.TagType_LONG + case uint: + vLong := int64(value) + jTag.VLong = &vLong + jTag.VType = j.TagType_LONG + case int8: + vLong := int64(value) + jTag.VLong = &vLong + jTag.VType = j.TagType_LONG + case uint8: + vLong := int64(value) + jTag.VLong = &vLong + jTag.VType = j.TagType_LONG + case int16: + vLong := int64(value) + jTag.VLong = &vLong + jTag.VType = j.TagType_LONG + case uint16: + vLong := int64(value) + jTag.VLong = &vLong + jTag.VType = j.TagType_LONG + case int32: + vLong := int64(value) + jTag.VLong = &vLong + jTag.VType = j.TagType_LONG + case uint32: + vLong := int64(value) + jTag.VLong = &vLong + jTag.VType = j.TagType_LONG + case int64: + vLong := int64(value) + jTag.VLong = &vLong + jTag.VType = j.TagType_LONG + case uint64: + vLong := int64(value) + jTag.VLong = &vLong + jTag.VType = j.TagType_LONG + case float32: + vDouble := float64(value) + jTag.VDouble = &vDouble + jTag.VType = j.TagType_DOUBLE + case float64: + vDouble := float64(value) + jTag.VDouble = &vDouble + jTag.VType = j.TagType_DOUBLE + case bool: + vBool := value + jTag.VBool = &vBool + jTag.VType = j.TagType_BOOL + default: + vStr := truncateString(stringify(value), maxTagValueLength) + jTag.VStr = &vStr + jTag.VType = j.TagType_STRING + } + return jTag +} + +func buildReferences(references []Reference) []*j.SpanRef { + retMe := make([]*j.SpanRef, 0, len(references)) + for _, ref := range references { + if ref.Type == opentracing.ChildOfRef { + retMe = append(retMe, spanRef(ref.Context, j.SpanRefType_CHILD_OF)) + } else if ref.Type == opentracing.FollowsFromRef { + retMe = append(retMe, spanRef(ref.Context, j.SpanRefType_FOLLOWS_FROM)) + } + } + return retMe +} + +func spanRef(ctx SpanContext, refType j.SpanRefType) *j.SpanRef { + return &j.SpanRef{ + RefType: refType, + TraceIdLow: int64(ctx.traceID.Low), + TraceIdHigh: int64(ctx.traceID.High), + SpanId: int64(ctx.spanID), + } +} diff --git a/vendor/github.com/uber/jaeger-client-go/log/logger.go b/vendor/github.com/uber/jaeger-client-go/log/logger.go new file mode 100644 index 0000000000..894bb3dbf7 --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/log/logger.go @@ -0,0 +1,90 @@ +// Copyright (c) 2017 Uber Technologies, Inc. +// +// 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 log + +import ( + "bytes" + "fmt" + "log" + "sync" +) + +// Logger provides an abstract interface for logging from Reporters. +// Applications can provide their own implementation of this interface to adapt +// reporters logging to whatever logging library they prefer (stdlib log, +// logrus, go-logging, etc). +type Logger interface { + // Error logs a message at error priority + Error(msg string) + + // Infof logs a message at info priority + Infof(msg string, args ...interface{}) +} + +// StdLogger is implementation of the Logger interface that delegates to default `log` package +var StdLogger = &stdLogger{} + +type stdLogger struct{} + +func (l *stdLogger) Error(msg string) { + log.Printf("ERROR: %s", msg) +} + +// Infof logs a message at info priority +func (l *stdLogger) Infof(msg string, args ...interface{}) { + log.Printf(msg, args...) +} + +// NullLogger is implementation of the Logger interface that is no-op +var NullLogger = &nullLogger{} + +type nullLogger struct{} + +func (l *nullLogger) Error(msg string) {} +func (l *nullLogger) Infof(msg string, args ...interface{}) {} + +// BytesBufferLogger implements Logger backed by a bytes.Buffer. +type BytesBufferLogger struct { + mux sync.Mutex + buf bytes.Buffer +} + +// Error implements Logger. +func (l *BytesBufferLogger) Error(msg string) { + l.mux.Lock() + l.buf.WriteString(fmt.Sprintf("ERROR: %s\n", msg)) + l.mux.Unlock() +} + +// Infof implements Logger. +func (l *BytesBufferLogger) Infof(msg string, args ...interface{}) { + l.mux.Lock() + l.buf.WriteString("INFO: " + fmt.Sprintf(msg, args...) + "\n") + l.mux.Unlock() +} + +// String returns string representation of the underlying buffer. +func (l *BytesBufferLogger) String() string { + l.mux.Lock() + defer l.mux.Unlock() + return l.buf.String() +} + +// Flush empties the underlying buffer. +func (l *BytesBufferLogger) Flush() { + l.mux.Lock() + defer l.mux.Unlock() + l.buf.Reset() +} diff --git a/vendor/github.com/uber/jaeger-client-go/logger.go b/vendor/github.com/uber/jaeger-client-go/logger.go new file mode 100644 index 0000000000..d4f0b50192 --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/logger.go @@ -0,0 +1,53 @@ +// Copyright (c) 2017 Uber Technologies, Inc. +// +// 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 jaeger + +import "log" + +// NB This will be deprecated in 3.0.0, please use jaeger-client-go/log/logger instead. + +// Logger provides an abstract interface for logging from Reporters. +// Applications can provide their own implementation of this interface to adapt +// reporters logging to whatever logging library they prefer (stdlib log, +// logrus, go-logging, etc). +type Logger interface { + // Error logs a message at error priority + Error(msg string) + + // Infof logs a message at info priority + Infof(msg string, args ...interface{}) +} + +// StdLogger is implementation of the Logger interface that delegates to default `log` package +var StdLogger = &stdLogger{} + +type stdLogger struct{} + +func (l *stdLogger) Error(msg string) { + log.Printf("ERROR: %s", msg) +} + +// Infof logs a message at info priority +func (l *stdLogger) Infof(msg string, args ...interface{}) { + log.Printf(msg, args...) +} + +// NullLogger is implementation of the Logger interface that delegates to default `log` package +var NullLogger = &nullLogger{} + +type nullLogger struct{} + +func (l *nullLogger) Error(msg string) {} +func (l *nullLogger) Infof(msg string, args ...interface{}) {} diff --git a/vendor/github.com/uber/jaeger-client-go/metrics.go b/vendor/github.com/uber/jaeger-client-go/metrics.go new file mode 100644 index 0000000000..cadb2b9c0f --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/metrics.go @@ -0,0 +1,107 @@ +// Copyright (c) 2017-2018 Uber Technologies, Inc. +// +// 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 jaeger + +import ( + "github.com/uber/jaeger-lib/metrics" +) + +// Metrics is a container of all stats emitted by Jaeger tracer. +type Metrics struct { + // Number of traces started by this tracer as sampled + TracesStartedSampled metrics.Counter `metric:"traces" tags:"state=started,sampled=y"` + + // Number of traces started by this tracer as not sampled + TracesStartedNotSampled metrics.Counter `metric:"traces" tags:"state=started,sampled=n"` + + // Number of externally started sampled traces this tracer joined + TracesJoinedSampled metrics.Counter `metric:"traces" tags:"state=joined,sampled=y"` + + // Number of externally started not-sampled traces this tracer joined + TracesJoinedNotSampled metrics.Counter `metric:"traces" tags:"state=joined,sampled=n"` + + // Number of sampled spans started by this tracer + SpansStartedSampled metrics.Counter `metric:"started_spans" tags:"sampled=y"` + + // Number of unsampled spans started by this tracer + SpansStartedNotSampled metrics.Counter `metric:"started_spans" tags:"sampled=n"` + + // Number of spans finished by this tracer + SpansFinished metrics.Counter `metric:"finished_spans"` + + // Number of errors decoding tracing context + DecodingErrors metrics.Counter `metric:"span_context_decoding_errors"` + + // Number of spans successfully reported + ReporterSuccess metrics.Counter `metric:"reporter_spans" tags:"result=ok"` + + // Number of spans not reported due to a Sender failure + ReporterFailure metrics.Counter `metric:"reporter_spans" tags:"result=err"` + + // Number of spans dropped due to internal queue overflow + ReporterDropped metrics.Counter `metric:"reporter_spans" tags:"result=dropped"` + + // Current number of spans in the reporter queue + ReporterQueueLength metrics.Gauge `metric:"reporter_queue_length"` + + // Number of times the Sampler succeeded to retrieve sampling strategy + SamplerRetrieved metrics.Counter `metric:"sampler_queries" tags:"result=ok"` + + // Number of times the Sampler failed to retrieve sampling strategy + SamplerQueryFailure metrics.Counter `metric:"sampler_queries" tags:"result=err"` + + // Number of times the Sampler succeeded to retrieve and update sampling strategy + SamplerUpdated metrics.Counter `metric:"sampler_updates" tags:"result=ok"` + + // Number of times the Sampler failed to update sampling strategy + SamplerUpdateFailure metrics.Counter `metric:"sampler_updates" tags:"result=err"` + + // Number of times baggage was successfully written or updated on spans. + BaggageUpdateSuccess metrics.Counter `metric:"baggage_updates" tags:"result=ok"` + + // Number of times baggage failed to write or update on spans. + BaggageUpdateFailure metrics.Counter `metric:"baggage_updates" tags:"result=err"` + + // Number of times baggage was truncated as per baggage restrictions. + BaggageTruncate metrics.Counter `metric:"baggage_truncations"` + + // Number of times baggage restrictions were successfully updated. + BaggageRestrictionsUpdateSuccess metrics.Counter `metric:"baggage_restrictions_updates" tags:"result=ok"` + + // Number of times baggage restrictions failed to update. + BaggageRestrictionsUpdateFailure metrics.Counter `metric:"baggage_restrictions_updates" tags:"result=err"` + + // Number of times debug spans were throttled. + ThrottledDebugSpans metrics.Counter `metric:"throttled_debug_spans"` + + // Number of times throttler successfully updated. + ThrottlerUpdateSuccess metrics.Counter `metric:"throttler_updates" tags:"result=ok"` + + // Number of times throttler failed to update. + ThrottlerUpdateFailure metrics.Counter `metric:"throttler_updates" tags:"result=err"` +} + +// NewMetrics creates a new Metrics struct and initializes it. +func NewMetrics(factory metrics.Factory, globalTags map[string]string) *Metrics { + m := &Metrics{} + // TODO the namespace "jaeger" should be configurable (e.g. in all-in-one "jaeger-client" would make more sense) + metrics.Init(m, factory.Namespace("jaeger", nil), globalTags) + return m +} + +// NewNullMetrics creates a new Metrics struct that won't report any metrics. +func NewNullMetrics() *Metrics { + return NewMetrics(metrics.NullFactory, nil) +} diff --git a/vendor/github.com/uber/jaeger-client-go/observer.go b/vendor/github.com/uber/jaeger-client-go/observer.go new file mode 100644 index 0000000000..7bbd028897 --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/observer.go @@ -0,0 +1,88 @@ +// Copyright (c) 2017 Uber Technologies, Inc. +// +// 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 jaeger + +import opentracing "github.com/opentracing/opentracing-go" + +// Observer can be registered with the Tracer to receive notifications about +// new Spans. +// +// Deprecated: use jaeger.ContribObserver instead. +type Observer interface { + OnStartSpan(operationName string, options opentracing.StartSpanOptions) SpanObserver +} + +// SpanObserver is created by the Observer and receives notifications about +// other Span events. +// +// Deprecated: use jaeger.ContribSpanObserver instead. +type SpanObserver interface { + OnSetOperationName(operationName string) + OnSetTag(key string, value interface{}) + OnFinish(options opentracing.FinishOptions) +} + +// compositeObserver is a dispatcher to other observers +type compositeObserver struct { + observers []ContribObserver +} + +// compositeSpanObserver is a dispatcher to other span observers +type compositeSpanObserver struct { + observers []ContribSpanObserver +} + +// noopSpanObserver is used when there are no observers registered +// on the Tracer or none of them returns span observers from OnStartSpan. +var noopSpanObserver = &compositeSpanObserver{} + +func (o *compositeObserver) append(contribObserver ContribObserver) { + o.observers = append(o.observers, contribObserver) +} + +func (o *compositeObserver) OnStartSpan(sp opentracing.Span, operationName string, options opentracing.StartSpanOptions) ContribSpanObserver { + var spanObservers []ContribSpanObserver + for _, obs := range o.observers { + spanObs, ok := obs.OnStartSpan(sp, operationName, options) + if ok { + if spanObservers == nil { + spanObservers = make([]ContribSpanObserver, 0, len(o.observers)) + } + spanObservers = append(spanObservers, spanObs) + } + } + if len(spanObservers) == 0 { + return noopSpanObserver + } + return &compositeSpanObserver{observers: spanObservers} +} + +func (o *compositeSpanObserver) OnSetOperationName(operationName string) { + for _, obs := range o.observers { + obs.OnSetOperationName(operationName) + } +} + +func (o *compositeSpanObserver) OnSetTag(key string, value interface{}) { + for _, obs := range o.observers { + obs.OnSetTag(key, value) + } +} + +func (o *compositeSpanObserver) OnFinish(options opentracing.FinishOptions) { + for _, obs := range o.observers { + obs.OnFinish(options) + } +} diff --git a/vendor/github.com/uber/jaeger-client-go/process.go b/vendor/github.com/uber/jaeger-client-go/process.go new file mode 100644 index 0000000000..30cbf99624 --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/process.go @@ -0,0 +1,29 @@ +// Copyright (c) 2018 The Jaeger Authors. +// +// 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 jaeger + +// Process holds process specific metadata that's relevant to this client. +type Process struct { + Service string + UUID string + Tags []Tag +} + +// ProcessSetter sets a process. This can be used by any class that requires +// the process to be set as part of initialization. +// See internal/throttler/remote/throttler.go for an example. +type ProcessSetter interface { + SetProcess(process Process) +} diff --git a/vendor/github.com/uber/jaeger-client-go/propagation.go b/vendor/github.com/uber/jaeger-client-go/propagation.go new file mode 100644 index 0000000000..abca67a3c9 --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/propagation.go @@ -0,0 +1,300 @@ +// Copyright (c) 2017 Uber Technologies, Inc. +// +// 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 jaeger + +import ( + "bytes" + "encoding/binary" + "fmt" + "io" + "log" + "net/url" + "strings" + "sync" + + opentracing "github.com/opentracing/opentracing-go" +) + +// Injector is responsible for injecting SpanContext instances in a manner suitable +// for propagation via a format-specific "carrier" object. Typically the +// injection will take place across an RPC boundary, but message queues and +// other IPC mechanisms are also reasonable places to use an Injector. +type Injector interface { + // Inject takes `SpanContext` and injects it into `carrier`. The actual type + // of `carrier` depends on the `format` passed to `Tracer.Inject()`. + // + // Implementations may return opentracing.ErrInvalidCarrier or any other + // implementation-specific error if injection fails. + Inject(ctx SpanContext, carrier interface{}) error +} + +// Extractor is responsible for extracting SpanContext instances from a +// format-specific "carrier" object. Typically the extraction will take place +// on the server side of an RPC boundary, but message queues and other IPC +// mechanisms are also reasonable places to use an Extractor. +type Extractor interface { + // Extract decodes a SpanContext instance from the given `carrier`, + // or (nil, opentracing.ErrSpanContextNotFound) if no context could + // be found in the `carrier`. + Extract(carrier interface{}) (SpanContext, error) +} + +type textMapPropagator struct { + headerKeys *HeadersConfig + metrics Metrics + encodeValue func(string) string + decodeValue func(string) string +} + +func newTextMapPropagator(headerKeys *HeadersConfig, metrics Metrics) *textMapPropagator { + return &textMapPropagator{ + headerKeys: headerKeys, + metrics: metrics, + encodeValue: func(val string) string { + return val + }, + decodeValue: func(val string) string { + return val + }, + } +} + +func newHTTPHeaderPropagator(headerKeys *HeadersConfig, metrics Metrics) *textMapPropagator { + return &textMapPropagator{ + headerKeys: headerKeys, + metrics: metrics, + encodeValue: func(val string) string { + return url.QueryEscape(val) + }, + decodeValue: func(val string) string { + // ignore decoding errors, cannot do anything about them + if v, err := url.QueryUnescape(val); err == nil { + return v + } + return val + }, + } +} + +type binaryPropagator struct { + tracer *Tracer + buffers sync.Pool +} + +func newBinaryPropagator(tracer *Tracer) *binaryPropagator { + return &binaryPropagator{ + tracer: tracer, + buffers: sync.Pool{New: func() interface{} { return &bytes.Buffer{} }}, + } +} + +func (p *textMapPropagator) Inject( + sc SpanContext, + abstractCarrier interface{}, +) error { + textMapWriter, ok := abstractCarrier.(opentracing.TextMapWriter) + if !ok { + return opentracing.ErrInvalidCarrier + } + + // Do not encode the string with trace context to avoid accidental double-encoding + // if people are using opentracing < 0.10.0. Our colon-separated representation + // of the trace context is already safe for HTTP headers. + textMapWriter.Set(p.headerKeys.TraceContextHeaderName, sc.String()) + for k, v := range sc.baggage { + safeKey := p.addBaggageKeyPrefix(k) + safeVal := p.encodeValue(v) + textMapWriter.Set(safeKey, safeVal) + } + return nil +} + +func (p *textMapPropagator) Extract(abstractCarrier interface{}) (SpanContext, error) { + textMapReader, ok := abstractCarrier.(opentracing.TextMapReader) + if !ok { + return emptyContext, opentracing.ErrInvalidCarrier + } + var ctx SpanContext + var baggage map[string]string + err := textMapReader.ForeachKey(func(rawKey, value string) error { + key := strings.ToLower(rawKey) // TODO not necessary for plain TextMap + if key == p.headerKeys.TraceContextHeaderName { + var err error + safeVal := p.decodeValue(value) + if ctx, err = ContextFromString(safeVal); err != nil { + return err + } + } else if key == p.headerKeys.JaegerDebugHeader { + ctx.debugID = p.decodeValue(value) + } else if key == p.headerKeys.JaegerBaggageHeader { + if baggage == nil { + baggage = make(map[string]string) + } + for k, v := range p.parseCommaSeparatedMap(value) { + baggage[k] = v + } + } else if strings.HasPrefix(key, p.headerKeys.TraceBaggageHeaderPrefix) { + if baggage == nil { + baggage = make(map[string]string) + } + safeKey := p.removeBaggageKeyPrefix(key) + safeVal := p.decodeValue(value) + baggage[safeKey] = safeVal + } + return nil + }) + if err != nil { + p.metrics.DecodingErrors.Inc(1) + return emptyContext, err + } + if !ctx.traceID.IsValid() && ctx.debugID == "" && len(baggage) == 0 { + return emptyContext, opentracing.ErrSpanContextNotFound + } + ctx.baggage = baggage + return ctx, nil +} + +func (p *binaryPropagator) Inject( + sc SpanContext, + abstractCarrier interface{}, +) error { + carrier, ok := abstractCarrier.(io.Writer) + if !ok { + return opentracing.ErrInvalidCarrier + } + + // Handle the tracer context + if err := binary.Write(carrier, binary.BigEndian, sc.traceID); err != nil { + return err + } + if err := binary.Write(carrier, binary.BigEndian, sc.spanID); err != nil { + return err + } + if err := binary.Write(carrier, binary.BigEndian, sc.parentID); err != nil { + return err + } + if err := binary.Write(carrier, binary.BigEndian, sc.flags); err != nil { + return err + } + + // Handle the baggage items + if err := binary.Write(carrier, binary.BigEndian, int32(len(sc.baggage))); err != nil { + return err + } + for k, v := range sc.baggage { + if err := binary.Write(carrier, binary.BigEndian, int32(len(k))); err != nil { + return err + } + io.WriteString(carrier, k) + if err := binary.Write(carrier, binary.BigEndian, int32(len(v))); err != nil { + return err + } + io.WriteString(carrier, v) + } + + return nil +} + +func (p *binaryPropagator) Extract(abstractCarrier interface{}) (SpanContext, error) { + carrier, ok := abstractCarrier.(io.Reader) + if !ok { + return emptyContext, opentracing.ErrInvalidCarrier + } + var ctx SpanContext + + if err := binary.Read(carrier, binary.BigEndian, &ctx.traceID); err != nil { + return emptyContext, opentracing.ErrSpanContextCorrupted + } + if err := binary.Read(carrier, binary.BigEndian, &ctx.spanID); err != nil { + return emptyContext, opentracing.ErrSpanContextCorrupted + } + if err := binary.Read(carrier, binary.BigEndian, &ctx.parentID); err != nil { + return emptyContext, opentracing.ErrSpanContextCorrupted + } + if err := binary.Read(carrier, binary.BigEndian, &ctx.flags); err != nil { + return emptyContext, opentracing.ErrSpanContextCorrupted + } + + // Handle the baggage items + var numBaggage int32 + if err := binary.Read(carrier, binary.BigEndian, &numBaggage); err != nil { + return emptyContext, opentracing.ErrSpanContextCorrupted + } + if iNumBaggage := int(numBaggage); iNumBaggage > 0 { + ctx.baggage = make(map[string]string, iNumBaggage) + buf := p.buffers.Get().(*bytes.Buffer) + defer p.buffers.Put(buf) + + var keyLen, valLen int32 + for i := 0; i < iNumBaggage; i++ { + if err := binary.Read(carrier, binary.BigEndian, &keyLen); err != nil { + return emptyContext, opentracing.ErrSpanContextCorrupted + } + buf.Reset() + buf.Grow(int(keyLen)) + if n, err := io.CopyN(buf, carrier, int64(keyLen)); err != nil || int32(n) != keyLen { + return emptyContext, opentracing.ErrSpanContextCorrupted + } + key := buf.String() + + if err := binary.Read(carrier, binary.BigEndian, &valLen); err != nil { + return emptyContext, opentracing.ErrSpanContextCorrupted + } + buf.Reset() + buf.Grow(int(valLen)) + if n, err := io.CopyN(buf, carrier, int64(valLen)); err != nil || int32(n) != valLen { + return emptyContext, opentracing.ErrSpanContextCorrupted + } + ctx.baggage[key] = buf.String() + } + } + + return ctx, nil +} + +// Converts a comma separated key value pair list into a map +// e.g. key1=value1, key2=value2, key3 = value3 +// is converted to map[string]string { "key1" : "value1", +// "key2" : "value2", +// "key3" : "value3" } +func (p *textMapPropagator) parseCommaSeparatedMap(value string) map[string]string { + baggage := make(map[string]string) + value, err := url.QueryUnescape(value) + if err != nil { + log.Printf("Unable to unescape %s, %v", value, err) + return baggage + } + for _, kvpair := range strings.Split(value, ",") { + kv := strings.Split(strings.TrimSpace(kvpair), "=") + if len(kv) == 2 { + baggage[kv[0]] = kv[1] + } else { + log.Printf("Malformed value passed in for %s", p.headerKeys.JaegerBaggageHeader) + } + } + return baggage +} + +// Converts a baggage item key into an http header format, +// by prepending TraceBaggageHeaderPrefix and encoding the key string +func (p *textMapPropagator) addBaggageKeyPrefix(key string) string { + // TODO encodeBaggageKeyAsHeader add caching and escaping + return fmt.Sprintf("%v%v", p.headerKeys.TraceBaggageHeaderPrefix, key) +} + +func (p *textMapPropagator) removeBaggageKeyPrefix(key string) string { + // TODO decodeBaggageHeaderKey add caching and escaping + return key[len(p.headerKeys.TraceBaggageHeaderPrefix):] +} diff --git a/vendor/github.com/uber/jaeger-client-go/reference.go b/vendor/github.com/uber/jaeger-client-go/reference.go new file mode 100644 index 0000000000..5646e78bb2 --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/reference.go @@ -0,0 +1,23 @@ +// Copyright (c) 2017 Uber Technologies, Inc. +// +// 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 jaeger + +import "github.com/opentracing/opentracing-go" + +// Reference represents a causal reference to other Spans (via their SpanContext). +type Reference struct { + Type opentracing.SpanReferenceType + Context SpanContext +} diff --git a/vendor/github.com/uber/jaeger-client-go/reporter.go b/vendor/github.com/uber/jaeger-client-go/reporter.go new file mode 100644 index 0000000000..fe6288c4b9 --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/reporter.go @@ -0,0 +1,289 @@ +// Copyright (c) 2017 Uber Technologies, Inc. +// +// 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 jaeger + +import ( + "fmt" + "sync" + "sync/atomic" + "time" + + "github.com/opentracing/opentracing-go" + + "github.com/uber/jaeger-client-go/log" +) + +// Reporter is called by the tracer when a span is completed to report the span to the tracing collector. +type Reporter interface { + // Report submits a new span to collectors, possibly asynchronously and/or with buffering. + Report(span *Span) + + // Close does a clean shutdown of the reporter, flushing any traces that may be buffered in memory. + Close() +} + +// ------------------------------ + +type nullReporter struct{} + +// NewNullReporter creates a no-op reporter that ignores all reported spans. +func NewNullReporter() Reporter { + return &nullReporter{} +} + +// Report implements Report() method of Reporter by doing nothing. +func (r *nullReporter) Report(span *Span) { + // no-op +} + +// Close implements Close() method of Reporter by doing nothing. +func (r *nullReporter) Close() { + // no-op +} + +// ------------------------------ + +type loggingReporter struct { + logger Logger +} + +// NewLoggingReporter creates a reporter that logs all reported spans to provided logger. +func NewLoggingReporter(logger Logger) Reporter { + return &loggingReporter{logger} +} + +// Report implements Report() method of Reporter by logging the span to the logger. +func (r *loggingReporter) Report(span *Span) { + r.logger.Infof("Reporting span %+v", span) +} + +// Close implements Close() method of Reporter by doing nothing. +func (r *loggingReporter) Close() { + // no-op +} + +// ------------------------------ + +// InMemoryReporter is used for testing, and simply collects spans in memory. +type InMemoryReporter struct { + spans []opentracing.Span + lock sync.Mutex +} + +// NewInMemoryReporter creates a reporter that stores spans in memory. +// NOTE: the Tracer should be created with options.PoolSpans = false. +func NewInMemoryReporter() *InMemoryReporter { + return &InMemoryReporter{ + spans: make([]opentracing.Span, 0, 10), + } +} + +// Report implements Report() method of Reporter by storing the span in the buffer. +func (r *InMemoryReporter) Report(span *Span) { + r.lock.Lock() + r.spans = append(r.spans, span) + r.lock.Unlock() +} + +// Close implements Close() method of Reporter by doing nothing. +func (r *InMemoryReporter) Close() { + // no-op +} + +// SpansSubmitted returns the number of spans accumulated in the buffer. +func (r *InMemoryReporter) SpansSubmitted() int { + r.lock.Lock() + defer r.lock.Unlock() + return len(r.spans) +} + +// GetSpans returns accumulated spans as a copy of the buffer. +func (r *InMemoryReporter) GetSpans() []opentracing.Span { + r.lock.Lock() + defer r.lock.Unlock() + copied := make([]opentracing.Span, len(r.spans)) + copy(copied, r.spans) + return copied +} + +// Reset clears all accumulated spans. +func (r *InMemoryReporter) Reset() { + r.lock.Lock() + defer r.lock.Unlock() + r.spans = nil +} + +// ------------------------------ + +type compositeReporter struct { + reporters []Reporter +} + +// NewCompositeReporter creates a reporter that ignores all reported spans. +func NewCompositeReporter(reporters ...Reporter) Reporter { + return &compositeReporter{reporters: reporters} +} + +// Report implements Report() method of Reporter by delegating to each underlying reporter. +func (r *compositeReporter) Report(span *Span) { + for _, reporter := range r.reporters { + reporter.Report(span) + } +} + +// Close implements Close() method of Reporter by closing each underlying reporter. +func (r *compositeReporter) Close() { + for _, reporter := range r.reporters { + reporter.Close() + } +} + +// ------------- REMOTE REPORTER ----------------- + +type reporterQueueItemType int + +const ( + defaultQueueSize = 100 + defaultBufferFlushInterval = 1 * time.Second + + reporterQueueItemSpan reporterQueueItemType = iota + reporterQueueItemClose +) + +type reporterQueueItem struct { + itemType reporterQueueItemType + span *Span + close *sync.WaitGroup +} + +type remoteReporter struct { + // These fields must be first in the struct because `sync/atomic` expects 64-bit alignment. + // Cf. https://github.com/uber/jaeger-client-go/issues/155, https://goo.gl/zW7dgq + queueLength int64 + closed int64 // 0 - not closed, 1 - closed + + reporterOptions + + sender Transport + queue chan reporterQueueItem +} + +// NewRemoteReporter creates a new reporter that sends spans out of process by means of Sender. +// Calls to Report(Span) return immediately (side effect: if internal buffer is full the span is dropped). +// Periodically the transport buffer is flushed even if it hasn't reached max packet size. +// Calls to Close() block until all spans reported prior to the call to Close are flushed. +func NewRemoteReporter(sender Transport, opts ...ReporterOption) Reporter { + options := reporterOptions{} + for _, option := range opts { + option(&options) + } + if options.bufferFlushInterval <= 0 { + options.bufferFlushInterval = defaultBufferFlushInterval + } + if options.logger == nil { + options.logger = log.NullLogger + } + if options.metrics == nil { + options.metrics = NewNullMetrics() + } + if options.queueSize <= 0 { + options.queueSize = defaultQueueSize + } + reporter := &remoteReporter{ + reporterOptions: options, + sender: sender, + queue: make(chan reporterQueueItem, options.queueSize), + } + go reporter.processQueue() + return reporter +} + +// Report implements Report() method of Reporter. +// It passes the span to a background go-routine for submission to Jaeger backend. +// If the internal queue is full, the span is dropped and metrics.ReporterDropped counter is incremented. +// If Report() is called after the reporter has been Close()-ed, the additional spans will not be +// sent to the backend, but the metrics.ReporterDropped counter may not reflect them correctly, +// because some of them may still be successfully added to the queue. +func (r *remoteReporter) Report(span *Span) { + select { + case r.queue <- reporterQueueItem{itemType: reporterQueueItemSpan, span: span}: + atomic.AddInt64(&r.queueLength, 1) + default: + r.metrics.ReporterDropped.Inc(1) + } +} + +// Close implements Close() method of Reporter by waiting for the queue to be drained. +func (r *remoteReporter) Close() { + if swapped := atomic.CompareAndSwapInt64(&r.closed, 0, 1); !swapped { + r.logger.Error("Repeated attempt to close the reporter is ignored") + return + } + r.sendCloseEvent() + r.sender.Close() +} + +func (r *remoteReporter) sendCloseEvent() { + wg := &sync.WaitGroup{} + wg.Add(1) + item := reporterQueueItem{itemType: reporterQueueItemClose, close: wg} + + r.queue <- item // if the queue is full we will block until there is space + atomic.AddInt64(&r.queueLength, 1) + wg.Wait() +} + +// processQueue reads spans from the queue, converts them to Thrift, and stores them in an internal buffer. +// When the buffer length reaches batchSize, it is flushed by submitting the accumulated spans to Jaeger. +// Buffer also gets flushed automatically every batchFlushInterval seconds, just in case the tracer stopped +// reporting new spans. +func (r *remoteReporter) processQueue() { + // flush causes the Sender to flush its accumulated spans and clear the buffer + flush := func() { + if flushed, err := r.sender.Flush(); err != nil { + r.metrics.ReporterFailure.Inc(int64(flushed)) + r.logger.Error(fmt.Sprintf("error when flushing the buffer: %s", err.Error())) + } else if flushed > 0 { + r.metrics.ReporterSuccess.Inc(int64(flushed)) + } + } + + timer := time.NewTicker(r.bufferFlushInterval) + for { + select { + case <-timer.C: + flush() + case item := <-r.queue: + atomic.AddInt64(&r.queueLength, -1) + switch item.itemType { + case reporterQueueItemSpan: + span := item.span + if flushed, err := r.sender.Append(span); err != nil { + r.metrics.ReporterFailure.Inc(int64(flushed)) + r.logger.Error(fmt.Sprintf("error reporting span %q: %s", span.OperationName(), err.Error())) + } else if flushed > 0 { + r.metrics.ReporterSuccess.Inc(int64(flushed)) + // to reduce the number of gauge stats, we only emit queue length on flush + r.metrics.ReporterQueueLength.Update(atomic.LoadInt64(&r.queueLength)) + } + case reporterQueueItemClose: + timer.Stop() + flush() + item.close.Done() + return + } + } + } +} diff --git a/vendor/github.com/uber/jaeger-client-go/reporter_options.go b/vendor/github.com/uber/jaeger-client-go/reporter_options.go new file mode 100644 index 0000000000..65012d7015 --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/reporter_options.go @@ -0,0 +1,69 @@ +// Copyright (c) 2017 Uber Technologies, Inc. +// +// 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 jaeger + +import ( + "time" +) + +// ReporterOption is a function that sets some option on the reporter. +type ReporterOption func(c *reporterOptions) + +// ReporterOptions is a factory for all available ReporterOption's +var ReporterOptions reporterOptions + +// reporterOptions control behavior of the reporter. +type reporterOptions struct { + // queueSize is the size of internal queue where reported spans are stored before they are processed in the background + queueSize int + // bufferFlushInterval is how often the buffer is force-flushed, even if it's not full + bufferFlushInterval time.Duration + // logger is used to log errors of span submissions + logger Logger + // metrics is used to record runtime stats + metrics *Metrics +} + +// QueueSize creates a ReporterOption that sets the size of the internal queue where +// spans are stored before they are processed. +func (reporterOptions) QueueSize(queueSize int) ReporterOption { + return func(r *reporterOptions) { + r.queueSize = queueSize + } +} + +// Metrics creates a ReporterOption that initializes Metrics in the reporter, +// which is used to record runtime statistics. +func (reporterOptions) Metrics(metrics *Metrics) ReporterOption { + return func(r *reporterOptions) { + r.metrics = metrics + } +} + +// BufferFlushInterval creates a ReporterOption that sets how often the queue +// is force-flushed. +func (reporterOptions) BufferFlushInterval(bufferFlushInterval time.Duration) ReporterOption { + return func(r *reporterOptions) { + r.bufferFlushInterval = bufferFlushInterval + } +} + +// Logger creates a ReporterOption that initializes the logger used to log +// errors of span submissions. +func (reporterOptions) Logger(logger Logger) ReporterOption { + return func(r *reporterOptions) { + r.logger = logger + } +} diff --git a/vendor/github.com/uber/jaeger-client-go/rpcmetrics/README.md b/vendor/github.com/uber/jaeger-client-go/rpcmetrics/README.md new file mode 100644 index 0000000000..879948e9c9 --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/rpcmetrics/README.md @@ -0,0 +1,5 @@ +An Observer that can be used to emit RPC metrics +================================================ + +It can be attached to the tracer during tracer construction. +See `ExampleObserver` function in [observer_test.go](./observer_test.go). diff --git a/vendor/github.com/uber/jaeger-client-go/rpcmetrics/doc.go b/vendor/github.com/uber/jaeger-client-go/rpcmetrics/doc.go new file mode 100644 index 0000000000..51aa11b350 --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/rpcmetrics/doc.go @@ -0,0 +1,16 @@ +// Copyright (c) 2017 Uber Technologies, Inc. +// +// 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 rpcmetrics implements an Observer that can be used to emit RPC metrics. +package rpcmetrics diff --git a/vendor/github.com/uber/jaeger-client-go/rpcmetrics/endpoints.go b/vendor/github.com/uber/jaeger-client-go/rpcmetrics/endpoints.go new file mode 100644 index 0000000000..30555243d0 --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/rpcmetrics/endpoints.go @@ -0,0 +1,63 @@ +// Copyright (c) 2017 Uber Technologies, Inc. +// +// 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 rpcmetrics + +import "sync" + +// normalizedEndpoints is a cache for endpointName -> safeName mappings. +type normalizedEndpoints struct { + names map[string]string + maxSize int + defaultName string + normalizer NameNormalizer + mux sync.RWMutex +} + +func newNormalizedEndpoints(maxSize int, normalizer NameNormalizer) *normalizedEndpoints { + return &normalizedEndpoints{ + maxSize: maxSize, + normalizer: normalizer, + names: make(map[string]string, maxSize), + } +} + +// normalize looks up the name in the cache, if not found it uses normalizer +// to convert the name to a safe name. If called with more than maxSize unique +// names it returns "" for all other names beyond those already cached. +func (n *normalizedEndpoints) normalize(name string) string { + n.mux.RLock() + norm, ok := n.names[name] + l := len(n.names) + n.mux.RUnlock() + if ok { + return norm + } + if l >= n.maxSize { + return "" + } + return n.normalizeWithLock(name) +} + +func (n *normalizedEndpoints) normalizeWithLock(name string) string { + norm := n.normalizer.Normalize(name) + n.mux.Lock() + defer n.mux.Unlock() + // cache may have grown while we were not holding the lock + if len(n.names) >= n.maxSize { + return "" + } + n.names[name] = norm + return norm +} diff --git a/vendor/github.com/uber/jaeger-client-go/rpcmetrics/metrics.go b/vendor/github.com/uber/jaeger-client-go/rpcmetrics/metrics.go new file mode 100644 index 0000000000..ab8d74c291 --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/rpcmetrics/metrics.go @@ -0,0 +1,124 @@ +// Copyright (c) 2017 Uber Technologies, Inc. +// +// 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 rpcmetrics + +import ( + "sync" + + "github.com/uber/jaeger-lib/metrics" +) + +const ( + otherEndpointsPlaceholder = "other" + endpointNameMetricTag = "endpoint" +) + +// Metrics is a collection of metrics for an endpoint describing +// throughput, success, errors, and performance. +type Metrics struct { + // RequestCountSuccess is a counter of the total number of successes. + RequestCountSuccess metrics.Counter `metric:"requests" tags:"error=false"` + + // RequestCountFailures is a counter of the number of times any failure has been observed. + RequestCountFailures metrics.Counter `metric:"requests" tags:"error=true"` + + // RequestLatencySuccess is a latency histogram of succesful requests. + RequestLatencySuccess metrics.Timer `metric:"request_latency" tags:"error=false"` + + // RequestLatencyFailures is a latency histogram of failed requests. + RequestLatencyFailures metrics.Timer `metric:"request_latency" tags:"error=true"` + + // HTTPStatusCode2xx is a counter of the total number of requests with HTTP status code 200-299 + HTTPStatusCode2xx metrics.Counter `metric:"http_requests" tags:"status_code=2xx"` + + // HTTPStatusCode3xx is a counter of the total number of requests with HTTP status code 300-399 + HTTPStatusCode3xx metrics.Counter `metric:"http_requests" tags:"status_code=3xx"` + + // HTTPStatusCode4xx is a counter of the total number of requests with HTTP status code 400-499 + HTTPStatusCode4xx metrics.Counter `metric:"http_requests" tags:"status_code=4xx"` + + // HTTPStatusCode5xx is a counter of the total number of requests with HTTP status code 500-599 + HTTPStatusCode5xx metrics.Counter `metric:"http_requests" tags:"status_code=5xx"` +} + +func (m *Metrics) recordHTTPStatusCode(statusCode uint16) { + if statusCode >= 200 && statusCode < 300 { + m.HTTPStatusCode2xx.Inc(1) + } else if statusCode >= 300 && statusCode < 400 { + m.HTTPStatusCode3xx.Inc(1) + } else if statusCode >= 400 && statusCode < 500 { + m.HTTPStatusCode4xx.Inc(1) + } else if statusCode >= 500 && statusCode < 600 { + m.HTTPStatusCode5xx.Inc(1) + } +} + +// MetricsByEndpoint is a registry/cache of metrics for each unique endpoint name. +// Only maxNumberOfEndpoints Metrics are stored, all other endpoint names are mapped +// to a generic endpoint name "other". +type MetricsByEndpoint struct { + metricsFactory metrics.Factory + endpoints *normalizedEndpoints + metricsByEndpoint map[string]*Metrics + mux sync.RWMutex +} + +func newMetricsByEndpoint( + metricsFactory metrics.Factory, + normalizer NameNormalizer, + maxNumberOfEndpoints int, +) *MetricsByEndpoint { + return &MetricsByEndpoint{ + metricsFactory: metricsFactory, + endpoints: newNormalizedEndpoints(maxNumberOfEndpoints, normalizer), + metricsByEndpoint: make(map[string]*Metrics, maxNumberOfEndpoints+1), // +1 for "other" + } +} + +func (m *MetricsByEndpoint) get(endpoint string) *Metrics { + safeName := m.endpoints.normalize(endpoint) + if safeName == "" { + safeName = otherEndpointsPlaceholder + } + m.mux.RLock() + met := m.metricsByEndpoint[safeName] + m.mux.RUnlock() + if met != nil { + return met + } + + return m.getWithWriteLock(safeName) +} + +// split to make easier to test +func (m *MetricsByEndpoint) getWithWriteLock(safeName string) *Metrics { + m.mux.Lock() + defer m.mux.Unlock() + + // it is possible that the name has been already registered after we released + // the read lock and before we grabbed the write lock, so check for that. + if met, ok := m.metricsByEndpoint[safeName]; ok { + return met + } + + // it would be nice to create the struct before locking, since Init() is somewhat + // expensive, however some metrics backends (e.g. expvar) may not like duplicate metrics. + met := &Metrics{} + tags := map[string]string{endpointNameMetricTag: safeName} + metrics.Init(met, m.metricsFactory, tags) + + m.metricsByEndpoint[safeName] = met + return met +} diff --git a/vendor/github.com/uber/jaeger-client-go/rpcmetrics/normalizer.go b/vendor/github.com/uber/jaeger-client-go/rpcmetrics/normalizer.go new file mode 100644 index 0000000000..148d84b3a1 --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/rpcmetrics/normalizer.go @@ -0,0 +1,101 @@ +// Copyright (c) 2017 Uber Technologies, Inc. +// +// 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 rpcmetrics + +// NameNormalizer is used to convert the endpoint names to strings +// that can be safely used as tags in the metrics. +type NameNormalizer interface { + Normalize(name string) string +} + +// DefaultNameNormalizer converts endpoint names so that they contain only characters +// from the safe charset [a-zA-Z0-9-./_]. All other characters are replaced with '-'. +var DefaultNameNormalizer = &SimpleNameNormalizer{ + SafeSets: []SafeCharacterSet{ + &Range{From: 'a', To: 'z'}, + &Range{From: 'A', To: 'Z'}, + &Range{From: '0', To: '9'}, + &Char{'-'}, + &Char{'_'}, + &Char{'/'}, + &Char{'.'}, + }, + Replacement: '-', +} + +// SimpleNameNormalizer uses a set of safe character sets. +type SimpleNameNormalizer struct { + SafeSets []SafeCharacterSet + Replacement byte +} + +// SafeCharacterSet determines if the given character is "safe" +type SafeCharacterSet interface { + IsSafe(c byte) bool +} + +// Range implements SafeCharacterSet +type Range struct { + From, To byte +} + +// IsSafe implements SafeCharacterSet +func (r *Range) IsSafe(c byte) bool { + return c >= r.From && c <= r.To +} + +// Char implements SafeCharacterSet +type Char struct { + Val byte +} + +// IsSafe implements SafeCharacterSet +func (ch *Char) IsSafe(c byte) bool { + return c == ch.Val +} + +// Normalize checks each character in the string against SafeSets, +// and if it's not safe substitutes it with Replacement. +func (n *SimpleNameNormalizer) Normalize(name string) string { + var retMe []byte + nameBytes := []byte(name) + for i, b := range nameBytes { + if n.safeByte(b) { + if retMe != nil { + retMe[i] = b + } + } else { + if retMe == nil { + retMe = make([]byte, len(nameBytes)) + copy(retMe[0:i], nameBytes[0:i]) + } + retMe[i] = n.Replacement + } + } + if retMe == nil { + return name + } + return string(retMe) +} + +// safeByte checks if b against all safe charsets. +func (n *SimpleNameNormalizer) safeByte(b byte) bool { + for i := range n.SafeSets { + if n.SafeSets[i].IsSafe(b) { + return true + } + } + return false +} diff --git a/vendor/github.com/uber/jaeger-client-go/rpcmetrics/observer.go b/vendor/github.com/uber/jaeger-client-go/rpcmetrics/observer.go new file mode 100644 index 0000000000..eca5ff6f3b --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/rpcmetrics/observer.go @@ -0,0 +1,171 @@ +// Copyright (c) 2017 Uber Technologies, Inc. +// +// 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 rpcmetrics + +import ( + "strconv" + "sync" + "time" + + "github.com/opentracing/opentracing-go" + "github.com/opentracing/opentracing-go/ext" + "github.com/uber/jaeger-lib/metrics" + + jaeger "github.com/uber/jaeger-client-go" +) + +const defaultMaxNumberOfEndpoints = 200 + +// Observer is an observer that can emit RPC metrics. +type Observer struct { + metricsByEndpoint *MetricsByEndpoint +} + +// NewObserver creates a new observer that can emit RPC metrics. +func NewObserver(metricsFactory metrics.Factory, normalizer NameNormalizer) *Observer { + return &Observer{ + metricsByEndpoint: newMetricsByEndpoint( + metricsFactory, + normalizer, + defaultMaxNumberOfEndpoints, + ), + } +} + +// OnStartSpan creates a new Observer for the span. +func (o *Observer) OnStartSpan( + operationName string, + options opentracing.StartSpanOptions, +) jaeger.SpanObserver { + return NewSpanObserver(o.metricsByEndpoint, operationName, options) +} + +// SpanKind identifies the span as inboud, outbound, or internal +type SpanKind int + +const ( + // Local span kind + Local SpanKind = iota + // Inbound span kind + Inbound + // Outbound span kind + Outbound +) + +// SpanObserver collects RPC metrics +type SpanObserver struct { + metricsByEndpoint *MetricsByEndpoint + operationName string + startTime time.Time + mux sync.Mutex + kind SpanKind + httpStatusCode uint16 + err bool +} + +// NewSpanObserver creates a new SpanObserver that can emit RPC metrics. +func NewSpanObserver( + metricsByEndpoint *MetricsByEndpoint, + operationName string, + options opentracing.StartSpanOptions, +) *SpanObserver { + so := &SpanObserver{ + metricsByEndpoint: metricsByEndpoint, + operationName: operationName, + startTime: options.StartTime, + } + for k, v := range options.Tags { + so.handleTagInLock(k, v) + } + return so +} + +// handleTags watches for special tags +// - SpanKind +// - HttpStatusCode +// - Error +func (so *SpanObserver) handleTagInLock(key string, value interface{}) { + if key == string(ext.SpanKind) { + if v, ok := value.(ext.SpanKindEnum); ok { + value = string(v) + } + if v, ok := value.(string); ok { + if v == string(ext.SpanKindRPCClientEnum) { + so.kind = Outbound + } else if v == string(ext.SpanKindRPCServerEnum) { + so.kind = Inbound + } + } + return + } + if key == string(ext.HTTPStatusCode) { + if v, ok := value.(uint16); ok { + so.httpStatusCode = v + } else if v, ok := value.(int); ok { + so.httpStatusCode = uint16(v) + } else if v, ok := value.(string); ok { + if vv, err := strconv.Atoi(v); err == nil { + so.httpStatusCode = uint16(vv) + } + } + return + } + if key == string(ext.Error) { + if v, ok := value.(bool); ok { + so.err = v + } else if v, ok := value.(string); ok { + if vv, err := strconv.ParseBool(v); err == nil { + so.err = vv + } + } + return + } +} + +// OnFinish emits the RPC metrics. It only has an effect when operation name +// is not blank, and the span kind is an RPC server. +func (so *SpanObserver) OnFinish(options opentracing.FinishOptions) { + so.mux.Lock() + defer so.mux.Unlock() + + if so.operationName == "" || so.kind != Inbound { + return + } + + mets := so.metricsByEndpoint.get(so.operationName) + latency := options.FinishTime.Sub(so.startTime) + if so.err { + mets.RequestCountFailures.Inc(1) + mets.RequestLatencyFailures.Record(latency) + } else { + mets.RequestCountSuccess.Inc(1) + mets.RequestLatencySuccess.Record(latency) + } + mets.recordHTTPStatusCode(so.httpStatusCode) +} + +// OnSetOperationName records new operation name. +func (so *SpanObserver) OnSetOperationName(operationName string) { + so.mux.Lock() + so.operationName = operationName + so.mux.Unlock() +} + +// OnSetTag implements SpanObserver +func (so *SpanObserver) OnSetTag(key string, value interface{}) { + so.mux.Lock() + so.handleTagInLock(key, value) + so.mux.Unlock() +} diff --git a/vendor/github.com/uber/jaeger-client-go/sampler.go b/vendor/github.com/uber/jaeger-client-go/sampler.go new file mode 100644 index 0000000000..e6a32b3837 --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/sampler.go @@ -0,0 +1,556 @@ +// Copyright (c) 2017 Uber Technologies, Inc. +// +// 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 jaeger + +import ( + "fmt" + "math" + "net/url" + "sync" + "sync/atomic" + "time" + + "github.com/uber/jaeger-client-go/log" + "github.com/uber/jaeger-client-go/thrift-gen/sampling" + "github.com/uber/jaeger-client-go/utils" +) + +const ( + defaultSamplingServerURL = "http://localhost:5778/sampling" + defaultSamplingRefreshInterval = time.Minute + defaultMaxOperations = 2000 +) + +// Sampler decides whether a new trace should be sampled or not. +type Sampler interface { + // IsSampled decides whether a trace with given `id` and `operation` + // should be sampled. This function will also return the tags that + // can be used to identify the type of sampling that was applied to + // the root span. Most simple samplers would return two tags, + // sampler.type and sampler.param, similar to those used in the Configuration + IsSampled(id TraceID, operation string) (sampled bool, tags []Tag) + + // Close does a clean shutdown of the sampler, stopping any background + // go-routines it may have started. + Close() + + // Equal checks if the `other` sampler is functionally equivalent + // to this sampler. + // TODO remove this function. This function is used to determine if 2 samplers are equivalent + // which does not bode well with the adaptive sampler which has to create all the composite samplers + // for the comparison to occur. This is expensive to do if only one sampler has changed. + Equal(other Sampler) bool +} + +// ----------------------- + +// ConstSampler is a sampler that always makes the same decision. +type ConstSampler struct { + Decision bool + tags []Tag +} + +// NewConstSampler creates a ConstSampler. +func NewConstSampler(sample bool) Sampler { + tags := []Tag{ + {key: SamplerTypeTagKey, value: SamplerTypeConst}, + {key: SamplerParamTagKey, value: sample}, + } + return &ConstSampler{Decision: sample, tags: tags} +} + +// IsSampled implements IsSampled() of Sampler. +func (s *ConstSampler) IsSampled(id TraceID, operation string) (bool, []Tag) { + return s.Decision, s.tags +} + +// Close implements Close() of Sampler. +func (s *ConstSampler) Close() { + // nothing to do +} + +// Equal implements Equal() of Sampler. +func (s *ConstSampler) Equal(other Sampler) bool { + if o, ok := other.(*ConstSampler); ok { + return s.Decision == o.Decision + } + return false +} + +// ----------------------- + +// ProbabilisticSampler is a sampler that randomly samples a certain percentage +// of traces. +type ProbabilisticSampler struct { + samplingRate float64 + samplingBoundary uint64 + tags []Tag +} + +const maxRandomNumber = ^(uint64(1) << 63) // i.e. 0x7fffffffffffffff + +// NewProbabilisticSampler creates a sampler that randomly samples a certain percentage of traces specified by the +// samplingRate, in the range between 0.0 and 1.0. +// +// It relies on the fact that new trace IDs are 63bit random numbers themselves, thus making the sampling decision +// without generating a new random number, but simply calculating if traceID < (samplingRate * 2^63). +// TODO remove the error from this function for next major release +func NewProbabilisticSampler(samplingRate float64) (*ProbabilisticSampler, error) { + if samplingRate < 0.0 || samplingRate > 1.0 { + return nil, fmt.Errorf("Sampling Rate must be between 0.0 and 1.0, received %f", samplingRate) + } + return newProbabilisticSampler(samplingRate), nil +} + +func newProbabilisticSampler(samplingRate float64) *ProbabilisticSampler { + samplingRate = math.Max(0.0, math.Min(samplingRate, 1.0)) + tags := []Tag{ + {key: SamplerTypeTagKey, value: SamplerTypeProbabilistic}, + {key: SamplerParamTagKey, value: samplingRate}, + } + return &ProbabilisticSampler{ + samplingRate: samplingRate, + samplingBoundary: uint64(float64(maxRandomNumber) * samplingRate), + tags: tags, + } +} + +// SamplingRate returns the sampling probability this sampled was constructed with. +func (s *ProbabilisticSampler) SamplingRate() float64 { + return s.samplingRate +} + +// IsSampled implements IsSampled() of Sampler. +func (s *ProbabilisticSampler) IsSampled(id TraceID, operation string) (bool, []Tag) { + return s.samplingBoundary >= id.Low, s.tags +} + +// Close implements Close() of Sampler. +func (s *ProbabilisticSampler) Close() { + // nothing to do +} + +// Equal implements Equal() of Sampler. +func (s *ProbabilisticSampler) Equal(other Sampler) bool { + if o, ok := other.(*ProbabilisticSampler); ok { + return s.samplingBoundary == o.samplingBoundary + } + return false +} + +// ----------------------- + +type rateLimitingSampler struct { + maxTracesPerSecond float64 + rateLimiter utils.RateLimiter + tags []Tag +} + +// NewRateLimitingSampler creates a sampler that samples at most maxTracesPerSecond. The distribution of sampled +// traces follows burstiness of the service, i.e. a service with uniformly distributed requests will have those +// requests sampled uniformly as well, but if requests are bursty, especially sub-second, then a number of +// sequential requests can be sampled each second. +func NewRateLimitingSampler(maxTracesPerSecond float64) Sampler { + tags := []Tag{ + {key: SamplerTypeTagKey, value: SamplerTypeRateLimiting}, + {key: SamplerParamTagKey, value: maxTracesPerSecond}, + } + return &rateLimitingSampler{ + maxTracesPerSecond: maxTracesPerSecond, + rateLimiter: utils.NewRateLimiter(maxTracesPerSecond, math.Max(maxTracesPerSecond, 1.0)), + tags: tags, + } +} + +// IsSampled implements IsSampled() of Sampler. +func (s *rateLimitingSampler) IsSampled(id TraceID, operation string) (bool, []Tag) { + return s.rateLimiter.CheckCredit(1.0), s.tags +} + +func (s *rateLimitingSampler) Close() { + // nothing to do +} + +func (s *rateLimitingSampler) Equal(other Sampler) bool { + if o, ok := other.(*rateLimitingSampler); ok { + return s.maxTracesPerSecond == o.maxTracesPerSecond + } + return false +} + +// ----------------------- + +// GuaranteedThroughputProbabilisticSampler is a sampler that leverages both probabilisticSampler and +// rateLimitingSampler. The rateLimitingSampler is used as a guaranteed lower bound sampler such that +// every operation is sampled at least once in a time interval defined by the lowerBound. ie a lowerBound +// of 1.0 / (60 * 10) will sample an operation at least once every 10 minutes. +// +// The probabilisticSampler is given higher priority when tags are emitted, ie. if IsSampled() for both +// samplers return true, the tags for probabilisticSampler will be used. +type GuaranteedThroughputProbabilisticSampler struct { + probabilisticSampler *ProbabilisticSampler + lowerBoundSampler Sampler + tags []Tag + samplingRate float64 + lowerBound float64 +} + +// NewGuaranteedThroughputProbabilisticSampler returns a delegating sampler that applies both +// probabilisticSampler and rateLimitingSampler. +func NewGuaranteedThroughputProbabilisticSampler( + lowerBound, samplingRate float64, +) (*GuaranteedThroughputProbabilisticSampler, error) { + return newGuaranteedThroughputProbabilisticSampler(lowerBound, samplingRate), nil +} + +func newGuaranteedThroughputProbabilisticSampler(lowerBound, samplingRate float64) *GuaranteedThroughputProbabilisticSampler { + s := &GuaranteedThroughputProbabilisticSampler{ + lowerBoundSampler: NewRateLimitingSampler(lowerBound), + lowerBound: lowerBound, + } + s.setProbabilisticSampler(samplingRate) + return s +} + +func (s *GuaranteedThroughputProbabilisticSampler) setProbabilisticSampler(samplingRate float64) { + if s.probabilisticSampler == nil || s.samplingRate != samplingRate { + s.probabilisticSampler = newProbabilisticSampler(samplingRate) + s.samplingRate = s.probabilisticSampler.SamplingRate() + s.tags = []Tag{ + {key: SamplerTypeTagKey, value: SamplerTypeLowerBound}, + {key: SamplerParamTagKey, value: s.samplingRate}, + } + } +} + +// IsSampled implements IsSampled() of Sampler. +func (s *GuaranteedThroughputProbabilisticSampler) IsSampled(id TraceID, operation string) (bool, []Tag) { + if sampled, tags := s.probabilisticSampler.IsSampled(id, operation); sampled { + s.lowerBoundSampler.IsSampled(id, operation) + return true, tags + } + sampled, _ := s.lowerBoundSampler.IsSampled(id, operation) + return sampled, s.tags +} + +// Close implements Close() of Sampler. +func (s *GuaranteedThroughputProbabilisticSampler) Close() { + s.probabilisticSampler.Close() + s.lowerBoundSampler.Close() +} + +// Equal implements Equal() of Sampler. +func (s *GuaranteedThroughputProbabilisticSampler) Equal(other Sampler) bool { + // NB The Equal() function is expensive and will be removed. See adaptiveSampler.Equal() for + // more information. + return false +} + +// this function should only be called while holding a Write lock +func (s *GuaranteedThroughputProbabilisticSampler) update(lowerBound, samplingRate float64) { + s.setProbabilisticSampler(samplingRate) + if s.lowerBound != lowerBound { + s.lowerBoundSampler = NewRateLimitingSampler(lowerBound) + s.lowerBound = lowerBound + } +} + +// ----------------------- + +type adaptiveSampler struct { + sync.RWMutex + + samplers map[string]*GuaranteedThroughputProbabilisticSampler + defaultSampler *ProbabilisticSampler + lowerBound float64 + maxOperations int +} + +// NewAdaptiveSampler returns a delegating sampler that applies both probabilisticSampler and +// rateLimitingSampler via the guaranteedThroughputProbabilisticSampler. This sampler keeps track of all +// operations and delegates calls to the respective guaranteedThroughputProbabilisticSampler. +func NewAdaptiveSampler(strategies *sampling.PerOperationSamplingStrategies, maxOperations int) (Sampler, error) { + return newAdaptiveSampler(strategies, maxOperations), nil +} + +func newAdaptiveSampler(strategies *sampling.PerOperationSamplingStrategies, maxOperations int) Sampler { + samplers := make(map[string]*GuaranteedThroughputProbabilisticSampler) + for _, strategy := range strategies.PerOperationStrategies { + sampler := newGuaranteedThroughputProbabilisticSampler( + strategies.DefaultLowerBoundTracesPerSecond, + strategy.ProbabilisticSampling.SamplingRate, + ) + samplers[strategy.Operation] = sampler + } + return &adaptiveSampler{ + samplers: samplers, + defaultSampler: newProbabilisticSampler(strategies.DefaultSamplingProbability), + lowerBound: strategies.DefaultLowerBoundTracesPerSecond, + maxOperations: maxOperations, + } +} + +func (s *adaptiveSampler) IsSampled(id TraceID, operation string) (bool, []Tag) { + s.RLock() + sampler, ok := s.samplers[operation] + if ok { + defer s.RUnlock() + return sampler.IsSampled(id, operation) + } + s.RUnlock() + s.Lock() + defer s.Unlock() + + // Check if sampler has already been created + sampler, ok = s.samplers[operation] + if ok { + return sampler.IsSampled(id, operation) + } + // Store only up to maxOperations of unique ops. + if len(s.samplers) >= s.maxOperations { + return s.defaultSampler.IsSampled(id, operation) + } + newSampler := newGuaranteedThroughputProbabilisticSampler(s.lowerBound, s.defaultSampler.SamplingRate()) + s.samplers[operation] = newSampler + return newSampler.IsSampled(id, operation) +} + +func (s *adaptiveSampler) Close() { + s.Lock() + defer s.Unlock() + for _, sampler := range s.samplers { + sampler.Close() + } + s.defaultSampler.Close() +} + +func (s *adaptiveSampler) Equal(other Sampler) bool { + // NB The Equal() function is overly expensive for adaptiveSampler since it's composed of multiple + // samplers which all need to be initialized before this function can be called for a comparison. + // Therefore, adaptiveSampler uses the update() function to only alter the samplers that need + // changing. Hence this function always returns false so that the update function can be called. + // Once the Equal() function is removed from the Sampler API, this will no longer be needed. + return false +} + +func (s *adaptiveSampler) update(strategies *sampling.PerOperationSamplingStrategies) { + s.Lock() + defer s.Unlock() + for _, strategy := range strategies.PerOperationStrategies { + operation := strategy.Operation + samplingRate := strategy.ProbabilisticSampling.SamplingRate + lowerBound := strategies.DefaultLowerBoundTracesPerSecond + if sampler, ok := s.samplers[operation]; ok { + sampler.update(lowerBound, samplingRate) + } else { + sampler := newGuaranteedThroughputProbabilisticSampler( + lowerBound, + samplingRate, + ) + s.samplers[operation] = sampler + } + } + s.lowerBound = strategies.DefaultLowerBoundTracesPerSecond + if s.defaultSampler.SamplingRate() != strategies.DefaultSamplingProbability { + s.defaultSampler = newProbabilisticSampler(strategies.DefaultSamplingProbability) + } +} + +// ----------------------- + +// RemotelyControlledSampler is a delegating sampler that polls a remote server +// for the appropriate sampling strategy, constructs a corresponding sampler and +// delegates to it for sampling decisions. +type RemotelyControlledSampler struct { + // These fields must be first in the struct because `sync/atomic` expects 64-bit alignment. + // Cf. https://github.com/uber/jaeger-client-go/issues/155, https://goo.gl/zW7dgq + closed int64 // 0 - not closed, 1 - closed + + sync.RWMutex + samplerOptions + + serviceName string + manager sampling.SamplingManager + doneChan chan *sync.WaitGroup +} + +type httpSamplingManager struct { + serverURL string +} + +func (s *httpSamplingManager) GetSamplingStrategy(serviceName string) (*sampling.SamplingStrategyResponse, error) { + var out sampling.SamplingStrategyResponse + v := url.Values{} + v.Set("service", serviceName) + if err := utils.GetJSON(s.serverURL+"?"+v.Encode(), &out); err != nil { + return nil, err + } + return &out, nil +} + +// NewRemotelyControlledSampler creates a sampler that periodically pulls +// the sampling strategy from an HTTP sampling server (e.g. jaeger-agent). +func NewRemotelyControlledSampler( + serviceName string, + opts ...SamplerOption, +) *RemotelyControlledSampler { + options := applySamplerOptions(opts...) + sampler := &RemotelyControlledSampler{ + samplerOptions: options, + serviceName: serviceName, + manager: &httpSamplingManager{serverURL: options.samplingServerURL}, + doneChan: make(chan *sync.WaitGroup), + } + go sampler.pollController() + return sampler +} + +func applySamplerOptions(opts ...SamplerOption) samplerOptions { + options := samplerOptions{} + for _, option := range opts { + option(&options) + } + if options.sampler == nil { + options.sampler = newProbabilisticSampler(0.001) + } + if options.logger == nil { + options.logger = log.NullLogger + } + if options.maxOperations <= 0 { + options.maxOperations = defaultMaxOperations + } + if options.samplingServerURL == "" { + options.samplingServerURL = defaultSamplingServerURL + } + if options.metrics == nil { + options.metrics = NewNullMetrics() + } + if options.samplingRefreshInterval <= 0 { + options.samplingRefreshInterval = defaultSamplingRefreshInterval + } + return options +} + +// IsSampled implements IsSampled() of Sampler. +func (s *RemotelyControlledSampler) IsSampled(id TraceID, operation string) (bool, []Tag) { + s.RLock() + defer s.RUnlock() + return s.sampler.IsSampled(id, operation) +} + +// Close implements Close() of Sampler. +func (s *RemotelyControlledSampler) Close() { + if swapped := atomic.CompareAndSwapInt64(&s.closed, 0, 1); !swapped { + s.logger.Error("Repeated attempt to close the sampler is ignored") + return + } + + var wg sync.WaitGroup + wg.Add(1) + s.doneChan <- &wg + wg.Wait() +} + +// Equal implements Equal() of Sampler. +func (s *RemotelyControlledSampler) Equal(other Sampler) bool { + // NB The Equal() function is expensive and will be removed. See adaptiveSampler.Equal() for + // more information. + if o, ok := other.(*RemotelyControlledSampler); ok { + s.RLock() + o.RLock() + defer s.RUnlock() + defer o.RUnlock() + return s.sampler.Equal(o.sampler) + } + return false +} + +func (s *RemotelyControlledSampler) pollController() { + ticker := time.NewTicker(s.samplingRefreshInterval) + defer ticker.Stop() + s.pollControllerWithTicker(ticker) +} + +func (s *RemotelyControlledSampler) pollControllerWithTicker(ticker *time.Ticker) { + for { + select { + case <-ticker.C: + s.updateSampler() + case wg := <-s.doneChan: + wg.Done() + return + } + } +} + +func (s *RemotelyControlledSampler) getSampler() Sampler { + s.Lock() + defer s.Unlock() + return s.sampler +} + +func (s *RemotelyControlledSampler) setSampler(sampler Sampler) { + s.Lock() + defer s.Unlock() + s.sampler = sampler +} + +func (s *RemotelyControlledSampler) updateSampler() { + res, err := s.manager.GetSamplingStrategy(s.serviceName) + if err != nil { + s.metrics.SamplerQueryFailure.Inc(1) + return + } + s.Lock() + defer s.Unlock() + + s.metrics.SamplerRetrieved.Inc(1) + if strategies := res.GetOperationSampling(); strategies != nil { + s.updateAdaptiveSampler(strategies) + } else { + err = s.updateRateLimitingOrProbabilisticSampler(res) + } + if err != nil { + s.metrics.SamplerUpdateFailure.Inc(1) + s.logger.Infof("Unable to handle sampling strategy response %+v. Got error: %v", res, err) + return + } + s.metrics.SamplerUpdated.Inc(1) +} + +// NB: this function should only be called while holding a Write lock +func (s *RemotelyControlledSampler) updateAdaptiveSampler(strategies *sampling.PerOperationSamplingStrategies) { + if adaptiveSampler, ok := s.sampler.(*adaptiveSampler); ok { + adaptiveSampler.update(strategies) + } else { + s.sampler = newAdaptiveSampler(strategies, s.maxOperations) + } +} + +// NB: this function should only be called while holding a Write lock +func (s *RemotelyControlledSampler) updateRateLimitingOrProbabilisticSampler(res *sampling.SamplingStrategyResponse) error { + var newSampler Sampler + if probabilistic := res.GetProbabilisticSampling(); probabilistic != nil { + newSampler = newProbabilisticSampler(probabilistic.SamplingRate) + } else if rateLimiting := res.GetRateLimitingSampling(); rateLimiting != nil { + newSampler = NewRateLimitingSampler(float64(rateLimiting.MaxTracesPerSecond)) + } else { + return fmt.Errorf("Unsupported sampling strategy type %v", res.GetStrategyType()) + } + if !s.sampler.Equal(newSampler) { + s.sampler = newSampler + } + return nil +} diff --git a/vendor/github.com/uber/jaeger-client-go/sampler_options.go b/vendor/github.com/uber/jaeger-client-go/sampler_options.go new file mode 100644 index 0000000000..75d28a5611 --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/sampler_options.go @@ -0,0 +1,81 @@ +// Copyright (c) 2017 Uber Technologies, Inc. +// +// 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 jaeger + +import ( + "time" +) + +// SamplerOption is a function that sets some option on the sampler +type SamplerOption func(options *samplerOptions) + +// SamplerOptions is a factory for all available SamplerOption's +var SamplerOptions samplerOptions + +type samplerOptions struct { + metrics *Metrics + maxOperations int + sampler Sampler + logger Logger + samplingServerURL string + samplingRefreshInterval time.Duration +} + +// Metrics creates a SamplerOption that initializes Metrics on the sampler, +// which is used to emit statistics. +func (samplerOptions) Metrics(m *Metrics) SamplerOption { + return func(o *samplerOptions) { + o.metrics = m + } +} + +// MaxOperations creates a SamplerOption that sets the maximum number of +// operations the sampler will keep track of. +func (samplerOptions) MaxOperations(maxOperations int) SamplerOption { + return func(o *samplerOptions) { + o.maxOperations = maxOperations + } +} + +// InitialSampler creates a SamplerOption that sets the initial sampler +// to use before a remote sampler is created and used. +func (samplerOptions) InitialSampler(sampler Sampler) SamplerOption { + return func(o *samplerOptions) { + o.sampler = sampler + } +} + +// Logger creates a SamplerOption that sets the logger used by the sampler. +func (samplerOptions) Logger(logger Logger) SamplerOption { + return func(o *samplerOptions) { + o.logger = logger + } +} + +// SamplingServerURL creates a SamplerOption that sets the sampling server url +// of the local agent that contains the sampling strategies. +func (samplerOptions) SamplingServerURL(samplingServerURL string) SamplerOption { + return func(o *samplerOptions) { + o.samplingServerURL = samplingServerURL + } +} + +// SamplingRefreshInterval creates a SamplerOption that sets how often the +// sampler will poll local agent for the appropriate sampling strategy. +func (samplerOptions) SamplingRefreshInterval(samplingRefreshInterval time.Duration) SamplerOption { + return func(o *samplerOptions) { + o.samplingRefreshInterval = samplingRefreshInterval + } +} diff --git a/vendor/github.com/uber/jaeger-client-go/span.go b/vendor/github.com/uber/jaeger-client-go/span.go new file mode 100644 index 0000000000..f0b497a90a --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/span.go @@ -0,0 +1,249 @@ +// Copyright (c) 2017-2018 Uber Technologies, Inc. +// +// 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 jaeger + +import ( + "sync" + "time" + + "github.com/opentracing/opentracing-go" + "github.com/opentracing/opentracing-go/ext" + "github.com/opentracing/opentracing-go/log" +) + +// Span implements opentracing.Span +type Span struct { + sync.RWMutex + + tracer *Tracer + + context SpanContext + + // The name of the "operation" this span is an instance of. + // Known as a "span name" in some implementations. + operationName string + + // firstInProcess, if true, indicates that this span is the root of the (sub)tree + // of spans in the current process. In other words it's true for the root spans, + // and the ingress spans when the process joins another trace. + firstInProcess bool + + // startTime is the timestamp indicating when the span began, with microseconds precision. + startTime time.Time + + // duration returns duration of the span with microseconds precision. + // Zero value means duration is unknown. + duration time.Duration + + // tags attached to this span + tags []Tag + + // The span's "micro-log" + logs []opentracing.LogRecord + + // references for this span + references []Reference + + observer ContribSpanObserver +} + +// Tag is a simple key value wrapper. +// TODO deprecate in the next major release, use opentracing.Tag instead. +type Tag struct { + key string + value interface{} +} + +// SetOperationName sets or changes the operation name. +func (s *Span) SetOperationName(operationName string) opentracing.Span { + s.Lock() + defer s.Unlock() + if s.context.IsSampled() { + s.operationName = operationName + } + s.observer.OnSetOperationName(operationName) + return s +} + +// SetTag implements SetTag() of opentracing.Span +func (s *Span) SetTag(key string, value interface{}) opentracing.Span { + s.observer.OnSetTag(key, value) + if key == string(ext.SamplingPriority) && !setSamplingPriority(s, value) { + return s + } + s.Lock() + defer s.Unlock() + if s.context.IsSampled() { + s.setTagNoLocking(key, value) + } + return s +} + +func (s *Span) setTagNoLocking(key string, value interface{}) { + s.tags = append(s.tags, Tag{key: key, value: value}) +} + +// LogFields implements opentracing.Span API +func (s *Span) LogFields(fields ...log.Field) { + s.Lock() + defer s.Unlock() + if !s.context.IsSampled() { + return + } + s.logFieldsNoLocking(fields...) +} + +// this function should only be called while holding a Write lock +func (s *Span) logFieldsNoLocking(fields ...log.Field) { + lr := opentracing.LogRecord{ + Fields: fields, + Timestamp: time.Now(), + } + s.appendLog(lr) +} + +// LogKV implements opentracing.Span API +func (s *Span) LogKV(alternatingKeyValues ...interface{}) { + s.RLock() + sampled := s.context.IsSampled() + s.RUnlock() + if !sampled { + return + } + fields, err := log.InterleavedKVToFields(alternatingKeyValues...) + if err != nil { + s.LogFields(log.Error(err), log.String("function", "LogKV")) + return + } + s.LogFields(fields...) +} + +// LogEvent implements opentracing.Span API +func (s *Span) LogEvent(event string) { + s.Log(opentracing.LogData{Event: event}) +} + +// LogEventWithPayload implements opentracing.Span API +func (s *Span) LogEventWithPayload(event string, payload interface{}) { + s.Log(opentracing.LogData{Event: event, Payload: payload}) +} + +// Log implements opentracing.Span API +func (s *Span) Log(ld opentracing.LogData) { + s.Lock() + defer s.Unlock() + if s.context.IsSampled() { + if ld.Timestamp.IsZero() { + ld.Timestamp = s.tracer.timeNow() + } + s.appendLog(ld.ToLogRecord()) + } +} + +// this function should only be called while holding a Write lock +func (s *Span) appendLog(lr opentracing.LogRecord) { + // TODO add logic to limit number of logs per span (issue #46) + s.logs = append(s.logs, lr) +} + +// SetBaggageItem implements SetBaggageItem() of opentracing.SpanContext +func (s *Span) SetBaggageItem(key, value string) opentracing.Span { + s.Lock() + defer s.Unlock() + s.tracer.setBaggage(s, key, value) + return s +} + +// BaggageItem implements BaggageItem() of opentracing.SpanContext +func (s *Span) BaggageItem(key string) string { + s.RLock() + defer s.RUnlock() + return s.context.baggage[key] +} + +// Finish implements opentracing.Span API +func (s *Span) Finish() { + s.FinishWithOptions(opentracing.FinishOptions{}) +} + +// FinishWithOptions implements opentracing.Span API +func (s *Span) FinishWithOptions(options opentracing.FinishOptions) { + if options.FinishTime.IsZero() { + options.FinishTime = s.tracer.timeNow() + } + s.observer.OnFinish(options) + s.Lock() + if s.context.IsSampled() { + s.duration = options.FinishTime.Sub(s.startTime) + // Note: bulk logs are not subject to maxLogsPerSpan limit + if options.LogRecords != nil { + s.logs = append(s.logs, options.LogRecords...) + } + for _, ld := range options.BulkLogData { + s.logs = append(s.logs, ld.ToLogRecord()) + } + } + s.Unlock() + // call reportSpan even for non-sampled traces, to return span to the pool + s.tracer.reportSpan(s) +} + +// Context implements opentracing.Span API +func (s *Span) Context() opentracing.SpanContext { + s.Lock() + defer s.Unlock() + return s.context +} + +// Tracer implements opentracing.Span API +func (s *Span) Tracer() opentracing.Tracer { + return s.tracer +} + +func (s *Span) String() string { + s.RLock() + defer s.RUnlock() + return s.context.String() +} + +// OperationName allows retrieving current operation name. +func (s *Span) OperationName() string { + s.RLock() + defer s.RUnlock() + return s.operationName +} + +func (s *Span) serviceName() string { + return s.tracer.serviceName +} + +// setSamplingPriority returns true if the flag was updated successfully, false otherwise. +func setSamplingPriority(s *Span, value interface{}) bool { + s.Lock() + defer s.Unlock() + val, ok := value.(uint16) + if !ok { + return false + } + if val == 0 { + s.context.flags = s.context.flags & (^flagSampled) + return true + } + if s.tracer.isDebugAllowed(s.operationName) { + s.context.flags = s.context.flags | flagDebug | flagSampled + return true + } + return false +} diff --git a/vendor/github.com/uber/jaeger-client-go/thrift-gen/agent/agent.go b/vendor/github.com/uber/jaeger-client-go/thrift-gen/agent/agent.go new file mode 100644 index 0000000000..e48811c500 --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/thrift-gen/agent/agent.go @@ -0,0 +1,411 @@ +// Autogenerated by Thrift Compiler (0.9.3) +// DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + +package agent + +import ( + "bytes" + "fmt" + "github.com/uber/jaeger-client-go/thrift" + "github.com/uber/jaeger-client-go/thrift-gen/jaeger" + "github.com/uber/jaeger-client-go/thrift-gen/zipkincore" +) + +// (needed to ensure safety because of naive import list construction.) +var _ = thrift.ZERO +var _ = fmt.Printf +var _ = bytes.Equal + +var _ = jaeger.GoUnusedProtection__ +var _ = zipkincore.GoUnusedProtection__ + +type Agent interface { + // Parameters: + // - Spans + EmitZipkinBatch(spans []*zipkincore.Span) (err error) + // Parameters: + // - Batch + EmitBatch(batch *jaeger.Batch) (err error) +} + +type AgentClient struct { + Transport thrift.TTransport + ProtocolFactory thrift.TProtocolFactory + InputProtocol thrift.TProtocol + OutputProtocol thrift.TProtocol + SeqId int32 +} + +func NewAgentClientFactory(t thrift.TTransport, f thrift.TProtocolFactory) *AgentClient { + return &AgentClient{Transport: t, + ProtocolFactory: f, + InputProtocol: f.GetProtocol(t), + OutputProtocol: f.GetProtocol(t), + SeqId: 0, + } +} + +func NewAgentClientProtocol(t thrift.TTransport, iprot thrift.TProtocol, oprot thrift.TProtocol) *AgentClient { + return &AgentClient{Transport: t, + ProtocolFactory: nil, + InputProtocol: iprot, + OutputProtocol: oprot, + SeqId: 0, + } +} + +// Parameters: +// - Spans +func (p *AgentClient) EmitZipkinBatch(spans []*zipkincore.Span) (err error) { + if err = p.sendEmitZipkinBatch(spans); err != nil { + return + } + return +} + +func (p *AgentClient) sendEmitZipkinBatch(spans []*zipkincore.Span) (err error) { + oprot := p.OutputProtocol + if oprot == nil { + oprot = p.ProtocolFactory.GetProtocol(p.Transport) + p.OutputProtocol = oprot + } + p.SeqId++ + if err = oprot.WriteMessageBegin("emitZipkinBatch", thrift.ONEWAY, p.SeqId); err != nil { + return + } + args := AgentEmitZipkinBatchArgs{ + Spans: spans, + } + if err = args.Write(oprot); err != nil { + return + } + if err = oprot.WriteMessageEnd(); err != nil { + return + } + return oprot.Flush() +} + +// Parameters: +// - Batch +func (p *AgentClient) EmitBatch(batch *jaeger.Batch) (err error) { + if err = p.sendEmitBatch(batch); err != nil { + return + } + return +} + +func (p *AgentClient) sendEmitBatch(batch *jaeger.Batch) (err error) { + oprot := p.OutputProtocol + if oprot == nil { + oprot = p.ProtocolFactory.GetProtocol(p.Transport) + p.OutputProtocol = oprot + } + p.SeqId++ + if err = oprot.WriteMessageBegin("emitBatch", thrift.ONEWAY, p.SeqId); err != nil { + return + } + args := AgentEmitBatchArgs{ + Batch: batch, + } + if err = args.Write(oprot); err != nil { + return + } + if err = oprot.WriteMessageEnd(); err != nil { + return + } + return oprot.Flush() +} + +type AgentProcessor struct { + processorMap map[string]thrift.TProcessorFunction + handler Agent +} + +func (p *AgentProcessor) AddToProcessorMap(key string, processor thrift.TProcessorFunction) { + p.processorMap[key] = processor +} + +func (p *AgentProcessor) GetProcessorFunction(key string) (processor thrift.TProcessorFunction, ok bool) { + processor, ok = p.processorMap[key] + return processor, ok +} + +func (p *AgentProcessor) ProcessorMap() map[string]thrift.TProcessorFunction { + return p.processorMap +} + +func NewAgentProcessor(handler Agent) *AgentProcessor { + + self0 := &AgentProcessor{handler: handler, processorMap: make(map[string]thrift.TProcessorFunction)} + self0.processorMap["emitZipkinBatch"] = &agentProcessorEmitZipkinBatch{handler: handler} + self0.processorMap["emitBatch"] = &agentProcessorEmitBatch{handler: handler} + return self0 +} + +func (p *AgentProcessor) Process(iprot, oprot thrift.TProtocol) (success bool, err thrift.TException) { + name, _, seqId, err := iprot.ReadMessageBegin() + if err != nil { + return false, err + } + if processor, ok := p.GetProcessorFunction(name); ok { + return processor.Process(seqId, iprot, oprot) + } + iprot.Skip(thrift.STRUCT) + iprot.ReadMessageEnd() + x1 := thrift.NewTApplicationException(thrift.UNKNOWN_METHOD, "Unknown function "+name) + oprot.WriteMessageBegin(name, thrift.EXCEPTION, seqId) + x1.Write(oprot) + oprot.WriteMessageEnd() + oprot.Flush() + return false, x1 + +} + +type agentProcessorEmitZipkinBatch struct { + handler Agent +} + +func (p *agentProcessorEmitZipkinBatch) Process(seqId int32, iprot, oprot thrift.TProtocol) (success bool, err thrift.TException) { + args := AgentEmitZipkinBatchArgs{} + if err = args.Read(iprot); err != nil { + iprot.ReadMessageEnd() + return false, err + } + + iprot.ReadMessageEnd() + var err2 error + if err2 = p.handler.EmitZipkinBatch(args.Spans); err2 != nil { + return true, err2 + } + return true, nil +} + +type agentProcessorEmitBatch struct { + handler Agent +} + +func (p *agentProcessorEmitBatch) Process(seqId int32, iprot, oprot thrift.TProtocol) (success bool, err thrift.TException) { + args := AgentEmitBatchArgs{} + if err = args.Read(iprot); err != nil { + iprot.ReadMessageEnd() + return false, err + } + + iprot.ReadMessageEnd() + var err2 error + if err2 = p.handler.EmitBatch(args.Batch); err2 != nil { + return true, err2 + } + return true, nil +} + +// HELPER FUNCTIONS AND STRUCTURES + +// Attributes: +// - Spans +type AgentEmitZipkinBatchArgs struct { + Spans []*zipkincore.Span `thrift:"spans,1" json:"spans"` +} + +func NewAgentEmitZipkinBatchArgs() *AgentEmitZipkinBatchArgs { + return &AgentEmitZipkinBatchArgs{} +} + +func (p *AgentEmitZipkinBatchArgs) GetSpans() []*zipkincore.Span { + return p.Spans +} +func (p *AgentEmitZipkinBatchArgs) Read(iprot thrift.TProtocol) error { + if _, err := iprot.ReadStructBegin(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T read error: ", p), err) + } + + for { + _, fieldTypeId, fieldId, err := iprot.ReadFieldBegin() + if err != nil { + return thrift.PrependError(fmt.Sprintf("%T field %d read error: ", p, fieldId), err) + } + if fieldTypeId == thrift.STOP { + break + } + switch fieldId { + case 1: + if err := p.readField1(iprot); err != nil { + return err + } + default: + if err := iprot.Skip(fieldTypeId); err != nil { + return err + } + } + if err := iprot.ReadFieldEnd(); err != nil { + return err + } + } + if err := iprot.ReadStructEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) + } + return nil +} + +func (p *AgentEmitZipkinBatchArgs) readField1(iprot thrift.TProtocol) error { + _, size, err := iprot.ReadListBegin() + if err != nil { + return thrift.PrependError("error reading list begin: ", err) + } + tSlice := make([]*zipkincore.Span, 0, size) + p.Spans = tSlice + for i := 0; i < size; i++ { + _elem2 := &zipkincore.Span{} + if err := _elem2.Read(iprot); err != nil { + return thrift.PrependError(fmt.Sprintf("%T error reading struct: ", _elem2), err) + } + p.Spans = append(p.Spans, _elem2) + } + if err := iprot.ReadListEnd(); err != nil { + return thrift.PrependError("error reading list end: ", err) + } + return nil +} + +func (p *AgentEmitZipkinBatchArgs) Write(oprot thrift.TProtocol) error { + if err := oprot.WriteStructBegin("emitZipkinBatch_args"); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) + } + if err := p.writeField1(oprot); err != nil { + return err + } + if err := oprot.WriteFieldStop(); err != nil { + return thrift.PrependError("write field stop error: ", err) + } + if err := oprot.WriteStructEnd(); err != nil { + return thrift.PrependError("write struct stop error: ", err) + } + return nil +} + +func (p *AgentEmitZipkinBatchArgs) writeField1(oprot thrift.TProtocol) (err error) { + if err := oprot.WriteFieldBegin("spans", thrift.LIST, 1); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 1:spans: ", p), err) + } + if err := oprot.WriteListBegin(thrift.STRUCT, len(p.Spans)); err != nil { + return thrift.PrependError("error writing list begin: ", err) + } + for _, v := range p.Spans { + if err := v.Write(oprot); err != nil { + return thrift.PrependError(fmt.Sprintf("%T error writing struct: ", v), err) + } + } + if err := oprot.WriteListEnd(); err != nil { + return thrift.PrependError("error writing list end: ", err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 1:spans: ", p), err) + } + return err +} + +func (p *AgentEmitZipkinBatchArgs) String() string { + if p == nil { + return "" + } + return fmt.Sprintf("AgentEmitZipkinBatchArgs(%+v)", *p) +} + +// Attributes: +// - Batch +type AgentEmitBatchArgs struct { + Batch *jaeger.Batch `thrift:"batch,1" json:"batch"` +} + +func NewAgentEmitBatchArgs() *AgentEmitBatchArgs { + return &AgentEmitBatchArgs{} +} + +var AgentEmitBatchArgs_Batch_DEFAULT *jaeger.Batch + +func (p *AgentEmitBatchArgs) GetBatch() *jaeger.Batch { + if !p.IsSetBatch() { + return AgentEmitBatchArgs_Batch_DEFAULT + } + return p.Batch +} +func (p *AgentEmitBatchArgs) IsSetBatch() bool { + return p.Batch != nil +} + +func (p *AgentEmitBatchArgs) Read(iprot thrift.TProtocol) error { + if _, err := iprot.ReadStructBegin(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T read error: ", p), err) + } + + for { + _, fieldTypeId, fieldId, err := iprot.ReadFieldBegin() + if err != nil { + return thrift.PrependError(fmt.Sprintf("%T field %d read error: ", p, fieldId), err) + } + if fieldTypeId == thrift.STOP { + break + } + switch fieldId { + case 1: + if err := p.readField1(iprot); err != nil { + return err + } + default: + if err := iprot.Skip(fieldTypeId); err != nil { + return err + } + } + if err := iprot.ReadFieldEnd(); err != nil { + return err + } + } + if err := iprot.ReadStructEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) + } + return nil +} + +func (p *AgentEmitBatchArgs) readField1(iprot thrift.TProtocol) error { + p.Batch = &jaeger.Batch{} + if err := p.Batch.Read(iprot); err != nil { + return thrift.PrependError(fmt.Sprintf("%T error reading struct: ", p.Batch), err) + } + return nil +} + +func (p *AgentEmitBatchArgs) Write(oprot thrift.TProtocol) error { + if err := oprot.WriteStructBegin("emitBatch_args"); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) + } + if err := p.writeField1(oprot); err != nil { + return err + } + if err := oprot.WriteFieldStop(); err != nil { + return thrift.PrependError("write field stop error: ", err) + } + if err := oprot.WriteStructEnd(); err != nil { + return thrift.PrependError("write struct stop error: ", err) + } + return nil +} + +func (p *AgentEmitBatchArgs) writeField1(oprot thrift.TProtocol) (err error) { + if err := oprot.WriteFieldBegin("batch", thrift.STRUCT, 1); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 1:batch: ", p), err) + } + if err := p.Batch.Write(oprot); err != nil { + return thrift.PrependError(fmt.Sprintf("%T error writing struct: ", p.Batch), err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 1:batch: ", p), err) + } + return err +} + +func (p *AgentEmitBatchArgs) String() string { + if p == nil { + return "" + } + return fmt.Sprintf("AgentEmitBatchArgs(%+v)", *p) +} diff --git a/vendor/github.com/uber/jaeger-client-go/thrift-gen/agent/constants.go b/vendor/github.com/uber/jaeger-client-go/thrift-gen/agent/constants.go new file mode 100644 index 0000000000..aa9857bb82 --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/thrift-gen/agent/constants.go @@ -0,0 +1,23 @@ +// Autogenerated by Thrift Compiler (0.9.3) +// DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + +package agent + +import ( + "bytes" + "fmt" + "github.com/uber/jaeger-client-go/thrift" + "github.com/uber/jaeger-client-go/thrift-gen/jaeger" + "github.com/uber/jaeger-client-go/thrift-gen/zipkincore" +) + +// (needed to ensure safety because of naive import list construction.) +var _ = thrift.ZERO +var _ = fmt.Printf +var _ = bytes.Equal + +var _ = jaeger.GoUnusedProtection__ +var _ = zipkincore.GoUnusedProtection__ + +func init() { +} diff --git a/vendor/github.com/uber/jaeger-client-go/thrift-gen/agent/ttypes.go b/vendor/github.com/uber/jaeger-client-go/thrift-gen/agent/ttypes.go new file mode 100644 index 0000000000..9c28f11c1a --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/thrift-gen/agent/ttypes.go @@ -0,0 +1,21 @@ +// Autogenerated by Thrift Compiler (0.9.3) +// DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + +package agent + +import ( + "bytes" + "fmt" + "github.com/uber/jaeger-client-go/thrift" + "github.com/uber/jaeger-client-go/thrift-gen/jaeger" + "github.com/uber/jaeger-client-go/thrift-gen/zipkincore" +) + +// (needed to ensure safety because of naive import list construction.) +var _ = thrift.ZERO +var _ = fmt.Printf +var _ = bytes.Equal + +var _ = jaeger.GoUnusedProtection__ +var _ = zipkincore.GoUnusedProtection__ +var GoUnusedProtection__ int diff --git a/vendor/github.com/uber/jaeger-client-go/thrift-gen/baggage/baggagerestrictionmanager.go b/vendor/github.com/uber/jaeger-client-go/thrift-gen/baggage/baggagerestrictionmanager.go new file mode 100644 index 0000000000..1f79c1255c --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/thrift-gen/baggage/baggagerestrictionmanager.go @@ -0,0 +1,435 @@ +// Autogenerated by Thrift Compiler (0.9.3) +// DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + +package baggage + +import ( + "bytes" + "fmt" + "github.com/uber/jaeger-client-go/thrift" +) + +// (needed to ensure safety because of naive import list construction.) +var _ = thrift.ZERO +var _ = fmt.Printf +var _ = bytes.Equal + +type BaggageRestrictionManager interface { + // getBaggageRestrictions retrieves the baggage restrictions for a specific service. + // Usually, baggageRestrictions apply to all services however there may be situations + // where a baggageKey might only be allowed to be set by a specific service. + // + // Parameters: + // - ServiceName + GetBaggageRestrictions(serviceName string) (r []*BaggageRestriction, err error) +} + +type BaggageRestrictionManagerClient struct { + Transport thrift.TTransport + ProtocolFactory thrift.TProtocolFactory + InputProtocol thrift.TProtocol + OutputProtocol thrift.TProtocol + SeqId int32 +} + +func NewBaggageRestrictionManagerClientFactory(t thrift.TTransport, f thrift.TProtocolFactory) *BaggageRestrictionManagerClient { + return &BaggageRestrictionManagerClient{Transport: t, + ProtocolFactory: f, + InputProtocol: f.GetProtocol(t), + OutputProtocol: f.GetProtocol(t), + SeqId: 0, + } +} + +func NewBaggageRestrictionManagerClientProtocol(t thrift.TTransport, iprot thrift.TProtocol, oprot thrift.TProtocol) *BaggageRestrictionManagerClient { + return &BaggageRestrictionManagerClient{Transport: t, + ProtocolFactory: nil, + InputProtocol: iprot, + OutputProtocol: oprot, + SeqId: 0, + } +} + +// getBaggageRestrictions retrieves the baggage restrictions for a specific service. +// Usually, baggageRestrictions apply to all services however there may be situations +// where a baggageKey might only be allowed to be set by a specific service. +// +// Parameters: +// - ServiceName +func (p *BaggageRestrictionManagerClient) GetBaggageRestrictions(serviceName string) (r []*BaggageRestriction, err error) { + if err = p.sendGetBaggageRestrictions(serviceName); err != nil { + return + } + return p.recvGetBaggageRestrictions() +} + +func (p *BaggageRestrictionManagerClient) sendGetBaggageRestrictions(serviceName string) (err error) { + oprot := p.OutputProtocol + if oprot == nil { + oprot = p.ProtocolFactory.GetProtocol(p.Transport) + p.OutputProtocol = oprot + } + p.SeqId++ + if err = oprot.WriteMessageBegin("getBaggageRestrictions", thrift.CALL, p.SeqId); err != nil { + return + } + args := BaggageRestrictionManagerGetBaggageRestrictionsArgs{ + ServiceName: serviceName, + } + if err = args.Write(oprot); err != nil { + return + } + if err = oprot.WriteMessageEnd(); err != nil { + return + } + return oprot.Flush() +} + +func (p *BaggageRestrictionManagerClient) recvGetBaggageRestrictions() (value []*BaggageRestriction, err error) { + iprot := p.InputProtocol + if iprot == nil { + iprot = p.ProtocolFactory.GetProtocol(p.Transport) + p.InputProtocol = iprot + } + method, mTypeId, seqId, err := iprot.ReadMessageBegin() + if err != nil { + return + } + if method != "getBaggageRestrictions" { + err = thrift.NewTApplicationException(thrift.WRONG_METHOD_NAME, "getBaggageRestrictions failed: wrong method name") + return + } + if p.SeqId != seqId { + err = thrift.NewTApplicationException(thrift.BAD_SEQUENCE_ID, "getBaggageRestrictions failed: out of sequence response") + return + } + if mTypeId == thrift.EXCEPTION { + error0 := thrift.NewTApplicationException(thrift.UNKNOWN_APPLICATION_EXCEPTION, "Unknown Exception") + var error1 error + error1, err = error0.Read(iprot) + if err != nil { + return + } + if err = iprot.ReadMessageEnd(); err != nil { + return + } + err = error1 + return + } + if mTypeId != thrift.REPLY { + err = thrift.NewTApplicationException(thrift.INVALID_MESSAGE_TYPE_EXCEPTION, "getBaggageRestrictions failed: invalid message type") + return + } + result := BaggageRestrictionManagerGetBaggageRestrictionsResult{} + if err = result.Read(iprot); err != nil { + return + } + if err = iprot.ReadMessageEnd(); err != nil { + return + } + value = result.GetSuccess() + return +} + +type BaggageRestrictionManagerProcessor struct { + processorMap map[string]thrift.TProcessorFunction + handler BaggageRestrictionManager +} + +func (p *BaggageRestrictionManagerProcessor) AddToProcessorMap(key string, processor thrift.TProcessorFunction) { + p.processorMap[key] = processor +} + +func (p *BaggageRestrictionManagerProcessor) GetProcessorFunction(key string) (processor thrift.TProcessorFunction, ok bool) { + processor, ok = p.processorMap[key] + return processor, ok +} + +func (p *BaggageRestrictionManagerProcessor) ProcessorMap() map[string]thrift.TProcessorFunction { + return p.processorMap +} + +func NewBaggageRestrictionManagerProcessor(handler BaggageRestrictionManager) *BaggageRestrictionManagerProcessor { + + self2 := &BaggageRestrictionManagerProcessor{handler: handler, processorMap: make(map[string]thrift.TProcessorFunction)} + self2.processorMap["getBaggageRestrictions"] = &baggageRestrictionManagerProcessorGetBaggageRestrictions{handler: handler} + return self2 +} + +func (p *BaggageRestrictionManagerProcessor) Process(iprot, oprot thrift.TProtocol) (success bool, err thrift.TException) { + name, _, seqId, err := iprot.ReadMessageBegin() + if err != nil { + return false, err + } + if processor, ok := p.GetProcessorFunction(name); ok { + return processor.Process(seqId, iprot, oprot) + } + iprot.Skip(thrift.STRUCT) + iprot.ReadMessageEnd() + x3 := thrift.NewTApplicationException(thrift.UNKNOWN_METHOD, "Unknown function "+name) + oprot.WriteMessageBegin(name, thrift.EXCEPTION, seqId) + x3.Write(oprot) + oprot.WriteMessageEnd() + oprot.Flush() + return false, x3 + +} + +type baggageRestrictionManagerProcessorGetBaggageRestrictions struct { + handler BaggageRestrictionManager +} + +func (p *baggageRestrictionManagerProcessorGetBaggageRestrictions) Process(seqId int32, iprot, oprot thrift.TProtocol) (success bool, err thrift.TException) { + args := BaggageRestrictionManagerGetBaggageRestrictionsArgs{} + if err = args.Read(iprot); err != nil { + iprot.ReadMessageEnd() + x := thrift.NewTApplicationException(thrift.PROTOCOL_ERROR, err.Error()) + oprot.WriteMessageBegin("getBaggageRestrictions", thrift.EXCEPTION, seqId) + x.Write(oprot) + oprot.WriteMessageEnd() + oprot.Flush() + return false, err + } + + iprot.ReadMessageEnd() + result := BaggageRestrictionManagerGetBaggageRestrictionsResult{} + var retval []*BaggageRestriction + var err2 error + if retval, err2 = p.handler.GetBaggageRestrictions(args.ServiceName); err2 != nil { + x := thrift.NewTApplicationException(thrift.INTERNAL_ERROR, "Internal error processing getBaggageRestrictions: "+err2.Error()) + oprot.WriteMessageBegin("getBaggageRestrictions", thrift.EXCEPTION, seqId) + x.Write(oprot) + oprot.WriteMessageEnd() + oprot.Flush() + return true, err2 + } else { + result.Success = retval + } + if err2 = oprot.WriteMessageBegin("getBaggageRestrictions", thrift.REPLY, seqId); err2 != nil { + err = err2 + } + if err2 = result.Write(oprot); err == nil && err2 != nil { + err = err2 + } + if err2 = oprot.WriteMessageEnd(); err == nil && err2 != nil { + err = err2 + } + if err2 = oprot.Flush(); err == nil && err2 != nil { + err = err2 + } + if err != nil { + return + } + return true, err +} + +// HELPER FUNCTIONS AND STRUCTURES + +// Attributes: +// - ServiceName +type BaggageRestrictionManagerGetBaggageRestrictionsArgs struct { + ServiceName string `thrift:"serviceName,1" json:"serviceName"` +} + +func NewBaggageRestrictionManagerGetBaggageRestrictionsArgs() *BaggageRestrictionManagerGetBaggageRestrictionsArgs { + return &BaggageRestrictionManagerGetBaggageRestrictionsArgs{} +} + +func (p *BaggageRestrictionManagerGetBaggageRestrictionsArgs) GetServiceName() string { + return p.ServiceName +} +func (p *BaggageRestrictionManagerGetBaggageRestrictionsArgs) Read(iprot thrift.TProtocol) error { + if _, err := iprot.ReadStructBegin(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T read error: ", p), err) + } + + for { + _, fieldTypeId, fieldId, err := iprot.ReadFieldBegin() + if err != nil { + return thrift.PrependError(fmt.Sprintf("%T field %d read error: ", p, fieldId), err) + } + if fieldTypeId == thrift.STOP { + break + } + switch fieldId { + case 1: + if err := p.readField1(iprot); err != nil { + return err + } + default: + if err := iprot.Skip(fieldTypeId); err != nil { + return err + } + } + if err := iprot.ReadFieldEnd(); err != nil { + return err + } + } + if err := iprot.ReadStructEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) + } + return nil +} + +func (p *BaggageRestrictionManagerGetBaggageRestrictionsArgs) readField1(iprot thrift.TProtocol) error { + if v, err := iprot.ReadString(); err != nil { + return thrift.PrependError("error reading field 1: ", err) + } else { + p.ServiceName = v + } + return nil +} + +func (p *BaggageRestrictionManagerGetBaggageRestrictionsArgs) Write(oprot thrift.TProtocol) error { + if err := oprot.WriteStructBegin("getBaggageRestrictions_args"); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) + } + if err := p.writeField1(oprot); err != nil { + return err + } + if err := oprot.WriteFieldStop(); err != nil { + return thrift.PrependError("write field stop error: ", err) + } + if err := oprot.WriteStructEnd(); err != nil { + return thrift.PrependError("write struct stop error: ", err) + } + return nil +} + +func (p *BaggageRestrictionManagerGetBaggageRestrictionsArgs) writeField1(oprot thrift.TProtocol) (err error) { + if err := oprot.WriteFieldBegin("serviceName", thrift.STRING, 1); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 1:serviceName: ", p), err) + } + if err := oprot.WriteString(string(p.ServiceName)); err != nil { + return thrift.PrependError(fmt.Sprintf("%T.serviceName (1) field write error: ", p), err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 1:serviceName: ", p), err) + } + return err +} + +func (p *BaggageRestrictionManagerGetBaggageRestrictionsArgs) String() string { + if p == nil { + return "" + } + return fmt.Sprintf("BaggageRestrictionManagerGetBaggageRestrictionsArgs(%+v)", *p) +} + +// Attributes: +// - Success +type BaggageRestrictionManagerGetBaggageRestrictionsResult struct { + Success []*BaggageRestriction `thrift:"success,0" json:"success,omitempty"` +} + +func NewBaggageRestrictionManagerGetBaggageRestrictionsResult() *BaggageRestrictionManagerGetBaggageRestrictionsResult { + return &BaggageRestrictionManagerGetBaggageRestrictionsResult{} +} + +var BaggageRestrictionManagerGetBaggageRestrictionsResult_Success_DEFAULT []*BaggageRestriction + +func (p *BaggageRestrictionManagerGetBaggageRestrictionsResult) GetSuccess() []*BaggageRestriction { + return p.Success +} +func (p *BaggageRestrictionManagerGetBaggageRestrictionsResult) IsSetSuccess() bool { + return p.Success != nil +} + +func (p *BaggageRestrictionManagerGetBaggageRestrictionsResult) Read(iprot thrift.TProtocol) error { + if _, err := iprot.ReadStructBegin(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T read error: ", p), err) + } + + for { + _, fieldTypeId, fieldId, err := iprot.ReadFieldBegin() + if err != nil { + return thrift.PrependError(fmt.Sprintf("%T field %d read error: ", p, fieldId), err) + } + if fieldTypeId == thrift.STOP { + break + } + switch fieldId { + case 0: + if err := p.readField0(iprot); err != nil { + return err + } + default: + if err := iprot.Skip(fieldTypeId); err != nil { + return err + } + } + if err := iprot.ReadFieldEnd(); err != nil { + return err + } + } + if err := iprot.ReadStructEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) + } + return nil +} + +func (p *BaggageRestrictionManagerGetBaggageRestrictionsResult) readField0(iprot thrift.TProtocol) error { + _, size, err := iprot.ReadListBegin() + if err != nil { + return thrift.PrependError("error reading list begin: ", err) + } + tSlice := make([]*BaggageRestriction, 0, size) + p.Success = tSlice + for i := 0; i < size; i++ { + _elem4 := &BaggageRestriction{} + if err := _elem4.Read(iprot); err != nil { + return thrift.PrependError(fmt.Sprintf("%T error reading struct: ", _elem4), err) + } + p.Success = append(p.Success, _elem4) + } + if err := iprot.ReadListEnd(); err != nil { + return thrift.PrependError("error reading list end: ", err) + } + return nil +} + +func (p *BaggageRestrictionManagerGetBaggageRestrictionsResult) Write(oprot thrift.TProtocol) error { + if err := oprot.WriteStructBegin("getBaggageRestrictions_result"); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) + } + if err := p.writeField0(oprot); err != nil { + return err + } + if err := oprot.WriteFieldStop(); err != nil { + return thrift.PrependError("write field stop error: ", err) + } + if err := oprot.WriteStructEnd(); err != nil { + return thrift.PrependError("write struct stop error: ", err) + } + return nil +} + +func (p *BaggageRestrictionManagerGetBaggageRestrictionsResult) writeField0(oprot thrift.TProtocol) (err error) { + if p.IsSetSuccess() { + if err := oprot.WriteFieldBegin("success", thrift.LIST, 0); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 0:success: ", p), err) + } + if err := oprot.WriteListBegin(thrift.STRUCT, len(p.Success)); err != nil { + return thrift.PrependError("error writing list begin: ", err) + } + for _, v := range p.Success { + if err := v.Write(oprot); err != nil { + return thrift.PrependError(fmt.Sprintf("%T error writing struct: ", v), err) + } + } + if err := oprot.WriteListEnd(); err != nil { + return thrift.PrependError("error writing list end: ", err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 0:success: ", p), err) + } + } + return err +} + +func (p *BaggageRestrictionManagerGetBaggageRestrictionsResult) String() string { + if p == nil { + return "" + } + return fmt.Sprintf("BaggageRestrictionManagerGetBaggageRestrictionsResult(%+v)", *p) +} diff --git a/vendor/github.com/uber/jaeger-client-go/thrift-gen/baggage/constants.go b/vendor/github.com/uber/jaeger-client-go/thrift-gen/baggage/constants.go new file mode 100644 index 0000000000..ed35ce9ab5 --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/thrift-gen/baggage/constants.go @@ -0,0 +1,18 @@ +// Autogenerated by Thrift Compiler (0.9.3) +// DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + +package baggage + +import ( + "bytes" + "fmt" + "github.com/uber/jaeger-client-go/thrift" +) + +// (needed to ensure safety because of naive import list construction.) +var _ = thrift.ZERO +var _ = fmt.Printf +var _ = bytes.Equal + +func init() { +} diff --git a/vendor/github.com/uber/jaeger-client-go/thrift-gen/baggage/ttypes.go b/vendor/github.com/uber/jaeger-client-go/thrift-gen/baggage/ttypes.go new file mode 100644 index 0000000000..7888892f63 --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/thrift-gen/baggage/ttypes.go @@ -0,0 +1,154 @@ +// Autogenerated by Thrift Compiler (0.9.3) +// DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + +package baggage + +import ( + "bytes" + "fmt" + "github.com/uber/jaeger-client-go/thrift" +) + +// (needed to ensure safety because of naive import list construction.) +var _ = thrift.ZERO +var _ = fmt.Printf +var _ = bytes.Equal + +var GoUnusedProtection__ int + +// Attributes: +// - BaggageKey +// - MaxValueLength +type BaggageRestriction struct { + BaggageKey string `thrift:"baggageKey,1,required" json:"baggageKey"` + MaxValueLength int32 `thrift:"maxValueLength,2,required" json:"maxValueLength"` +} + +func NewBaggageRestriction() *BaggageRestriction { + return &BaggageRestriction{} +} + +func (p *BaggageRestriction) GetBaggageKey() string { + return p.BaggageKey +} + +func (p *BaggageRestriction) GetMaxValueLength() int32 { + return p.MaxValueLength +} +func (p *BaggageRestriction) Read(iprot thrift.TProtocol) error { + if _, err := iprot.ReadStructBegin(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T read error: ", p), err) + } + + var issetBaggageKey bool = false + var issetMaxValueLength bool = false + + for { + _, fieldTypeId, fieldId, err := iprot.ReadFieldBegin() + if err != nil { + return thrift.PrependError(fmt.Sprintf("%T field %d read error: ", p, fieldId), err) + } + if fieldTypeId == thrift.STOP { + break + } + switch fieldId { + case 1: + if err := p.readField1(iprot); err != nil { + return err + } + issetBaggageKey = true + case 2: + if err := p.readField2(iprot); err != nil { + return err + } + issetMaxValueLength = true + default: + if err := iprot.Skip(fieldTypeId); err != nil { + return err + } + } + if err := iprot.ReadFieldEnd(); err != nil { + return err + } + } + if err := iprot.ReadStructEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) + } + if !issetBaggageKey { + return thrift.NewTProtocolExceptionWithType(thrift.INVALID_DATA, fmt.Errorf("Required field BaggageKey is not set")) + } + if !issetMaxValueLength { + return thrift.NewTProtocolExceptionWithType(thrift.INVALID_DATA, fmt.Errorf("Required field MaxValueLength is not set")) + } + return nil +} + +func (p *BaggageRestriction) readField1(iprot thrift.TProtocol) error { + if v, err := iprot.ReadString(); err != nil { + return thrift.PrependError("error reading field 1: ", err) + } else { + p.BaggageKey = v + } + return nil +} + +func (p *BaggageRestriction) readField2(iprot thrift.TProtocol) error { + if v, err := iprot.ReadI32(); err != nil { + return thrift.PrependError("error reading field 2: ", err) + } else { + p.MaxValueLength = v + } + return nil +} + +func (p *BaggageRestriction) Write(oprot thrift.TProtocol) error { + if err := oprot.WriteStructBegin("BaggageRestriction"); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) + } + if err := p.writeField1(oprot); err != nil { + return err + } + if err := p.writeField2(oprot); err != nil { + return err + } + if err := oprot.WriteFieldStop(); err != nil { + return thrift.PrependError("write field stop error: ", err) + } + if err := oprot.WriteStructEnd(); err != nil { + return thrift.PrependError("write struct stop error: ", err) + } + return nil +} + +func (p *BaggageRestriction) writeField1(oprot thrift.TProtocol) (err error) { + if err := oprot.WriteFieldBegin("baggageKey", thrift.STRING, 1); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 1:baggageKey: ", p), err) + } + if err := oprot.WriteString(string(p.BaggageKey)); err != nil { + return thrift.PrependError(fmt.Sprintf("%T.baggageKey (1) field write error: ", p), err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 1:baggageKey: ", p), err) + } + return err +} + +func (p *BaggageRestriction) writeField2(oprot thrift.TProtocol) (err error) { + if err := oprot.WriteFieldBegin("maxValueLength", thrift.I32, 2); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 2:maxValueLength: ", p), err) + } + if err := oprot.WriteI32(int32(p.MaxValueLength)); err != nil { + return thrift.PrependError(fmt.Sprintf("%T.maxValueLength (2) field write error: ", p), err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 2:maxValueLength: ", p), err) + } + return err +} + +func (p *BaggageRestriction) String() string { + if p == nil { + return "" + } + return fmt.Sprintf("BaggageRestriction(%+v)", *p) +} diff --git a/vendor/github.com/uber/jaeger-client-go/thrift-gen/jaeger/agent.go b/vendor/github.com/uber/jaeger-client-go/thrift-gen/jaeger/agent.go new file mode 100644 index 0000000000..b32c37dd26 --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/thrift-gen/jaeger/agent.go @@ -0,0 +1,242 @@ +// Autogenerated by Thrift Compiler (0.9.3) +// DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + +package jaeger + +import ( + "bytes" + "fmt" + "github.com/uber/jaeger-client-go/thrift" +) + +// (needed to ensure safety because of naive import list construction.) +var _ = thrift.ZERO +var _ = fmt.Printf +var _ = bytes.Equal + +type Agent interface { + // Parameters: + // - Batch + EmitBatch(batch *Batch) (err error) +} + +type AgentClient struct { + Transport thrift.TTransport + ProtocolFactory thrift.TProtocolFactory + InputProtocol thrift.TProtocol + OutputProtocol thrift.TProtocol + SeqId int32 +} + +func NewAgentClientFactory(t thrift.TTransport, f thrift.TProtocolFactory) *AgentClient { + return &AgentClient{Transport: t, + ProtocolFactory: f, + InputProtocol: f.GetProtocol(t), + OutputProtocol: f.GetProtocol(t), + SeqId: 0, + } +} + +func NewAgentClientProtocol(t thrift.TTransport, iprot thrift.TProtocol, oprot thrift.TProtocol) *AgentClient { + return &AgentClient{Transport: t, + ProtocolFactory: nil, + InputProtocol: iprot, + OutputProtocol: oprot, + SeqId: 0, + } +} + +// Parameters: +// - Batch +func (p *AgentClient) EmitBatch(batch *Batch) (err error) { + if err = p.sendEmitBatch(batch); err != nil { + return + } + return +} + +func (p *AgentClient) sendEmitBatch(batch *Batch) (err error) { + oprot := p.OutputProtocol + if oprot == nil { + oprot = p.ProtocolFactory.GetProtocol(p.Transport) + p.OutputProtocol = oprot + } + p.SeqId++ + if err = oprot.WriteMessageBegin("emitBatch", thrift.ONEWAY, p.SeqId); err != nil { + return + } + args := AgentEmitBatchArgs{ + Batch: batch, + } + if err = args.Write(oprot); err != nil { + return + } + if err = oprot.WriteMessageEnd(); err != nil { + return + } + return oprot.Flush() +} + +type AgentProcessor struct { + processorMap map[string]thrift.TProcessorFunction + handler Agent +} + +func (p *AgentProcessor) AddToProcessorMap(key string, processor thrift.TProcessorFunction) { + p.processorMap[key] = processor +} + +func (p *AgentProcessor) GetProcessorFunction(key string) (processor thrift.TProcessorFunction, ok bool) { + processor, ok = p.processorMap[key] + return processor, ok +} + +func (p *AgentProcessor) ProcessorMap() map[string]thrift.TProcessorFunction { + return p.processorMap +} + +func NewAgentProcessor(handler Agent) *AgentProcessor { + + self6 := &AgentProcessor{handler: handler, processorMap: make(map[string]thrift.TProcessorFunction)} + self6.processorMap["emitBatch"] = &agentProcessorEmitBatch{handler: handler} + return self6 +} + +func (p *AgentProcessor) Process(iprot, oprot thrift.TProtocol) (success bool, err thrift.TException) { + name, _, seqId, err := iprot.ReadMessageBegin() + if err != nil { + return false, err + } + if processor, ok := p.GetProcessorFunction(name); ok { + return processor.Process(seqId, iprot, oprot) + } + iprot.Skip(thrift.STRUCT) + iprot.ReadMessageEnd() + x7 := thrift.NewTApplicationException(thrift.UNKNOWN_METHOD, "Unknown function "+name) + oprot.WriteMessageBegin(name, thrift.EXCEPTION, seqId) + x7.Write(oprot) + oprot.WriteMessageEnd() + oprot.Flush() + return false, x7 + +} + +type agentProcessorEmitBatch struct { + handler Agent +} + +func (p *agentProcessorEmitBatch) Process(seqId int32, iprot, oprot thrift.TProtocol) (success bool, err thrift.TException) { + args := AgentEmitBatchArgs{} + if err = args.Read(iprot); err != nil { + iprot.ReadMessageEnd() + return false, err + } + + iprot.ReadMessageEnd() + var err2 error + if err2 = p.handler.EmitBatch(args.Batch); err2 != nil { + return true, err2 + } + return true, nil +} + +// HELPER FUNCTIONS AND STRUCTURES + +// Attributes: +// - Batch +type AgentEmitBatchArgs struct { + Batch *Batch `thrift:"batch,1" json:"batch"` +} + +func NewAgentEmitBatchArgs() *AgentEmitBatchArgs { + return &AgentEmitBatchArgs{} +} + +var AgentEmitBatchArgs_Batch_DEFAULT *Batch + +func (p *AgentEmitBatchArgs) GetBatch() *Batch { + if !p.IsSetBatch() { + return AgentEmitBatchArgs_Batch_DEFAULT + } + return p.Batch +} +func (p *AgentEmitBatchArgs) IsSetBatch() bool { + return p.Batch != nil +} + +func (p *AgentEmitBatchArgs) Read(iprot thrift.TProtocol) error { + if _, err := iprot.ReadStructBegin(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T read error: ", p), err) + } + + for { + _, fieldTypeId, fieldId, err := iprot.ReadFieldBegin() + if err != nil { + return thrift.PrependError(fmt.Sprintf("%T field %d read error: ", p, fieldId), err) + } + if fieldTypeId == thrift.STOP { + break + } + switch fieldId { + case 1: + if err := p.readField1(iprot); err != nil { + return err + } + default: + if err := iprot.Skip(fieldTypeId); err != nil { + return err + } + } + if err := iprot.ReadFieldEnd(); err != nil { + return err + } + } + if err := iprot.ReadStructEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) + } + return nil +} + +func (p *AgentEmitBatchArgs) readField1(iprot thrift.TProtocol) error { + p.Batch = &Batch{} + if err := p.Batch.Read(iprot); err != nil { + return thrift.PrependError(fmt.Sprintf("%T error reading struct: ", p.Batch), err) + } + return nil +} + +func (p *AgentEmitBatchArgs) Write(oprot thrift.TProtocol) error { + if err := oprot.WriteStructBegin("emitBatch_args"); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) + } + if err := p.writeField1(oprot); err != nil { + return err + } + if err := oprot.WriteFieldStop(); err != nil { + return thrift.PrependError("write field stop error: ", err) + } + if err := oprot.WriteStructEnd(); err != nil { + return thrift.PrependError("write struct stop error: ", err) + } + return nil +} + +func (p *AgentEmitBatchArgs) writeField1(oprot thrift.TProtocol) (err error) { + if err := oprot.WriteFieldBegin("batch", thrift.STRUCT, 1); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 1:batch: ", p), err) + } + if err := p.Batch.Write(oprot); err != nil { + return thrift.PrependError(fmt.Sprintf("%T error writing struct: ", p.Batch), err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 1:batch: ", p), err) + } + return err +} + +func (p *AgentEmitBatchArgs) String() string { + if p == nil { + return "" + } + return fmt.Sprintf("AgentEmitBatchArgs(%+v)", *p) +} diff --git a/vendor/github.com/uber/jaeger-client-go/thrift-gen/jaeger/constants.go b/vendor/github.com/uber/jaeger-client-go/thrift-gen/jaeger/constants.go new file mode 100644 index 0000000000..621b8b1c20 --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/thrift-gen/jaeger/constants.go @@ -0,0 +1,18 @@ +// Autogenerated by Thrift Compiler (0.9.3) +// DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + +package jaeger + +import ( + "bytes" + "fmt" + "github.com/uber/jaeger-client-go/thrift" +) + +// (needed to ensure safety because of naive import list construction.) +var _ = thrift.ZERO +var _ = fmt.Printf +var _ = bytes.Equal + +func init() { +} diff --git a/vendor/github.com/uber/jaeger-client-go/thrift-gen/jaeger/ttypes.go b/vendor/github.com/uber/jaeger-client-go/thrift-gen/jaeger/ttypes.go new file mode 100644 index 0000000000..d23ed2fc28 --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/thrift-gen/jaeger/ttypes.go @@ -0,0 +1,1838 @@ +// Autogenerated by Thrift Compiler (0.9.3) +// DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + +package jaeger + +import ( + "bytes" + "fmt" + "github.com/uber/jaeger-client-go/thrift" +) + +// (needed to ensure safety because of naive import list construction.) +var _ = thrift.ZERO +var _ = fmt.Printf +var _ = bytes.Equal + +var GoUnusedProtection__ int + +type TagType int64 + +const ( + TagType_STRING TagType = 0 + TagType_DOUBLE TagType = 1 + TagType_BOOL TagType = 2 + TagType_LONG TagType = 3 + TagType_BINARY TagType = 4 +) + +func (p TagType) String() string { + switch p { + case TagType_STRING: + return "STRING" + case TagType_DOUBLE: + return "DOUBLE" + case TagType_BOOL: + return "BOOL" + case TagType_LONG: + return "LONG" + case TagType_BINARY: + return "BINARY" + } + return "" +} + +func TagTypeFromString(s string) (TagType, error) { + switch s { + case "STRING": + return TagType_STRING, nil + case "DOUBLE": + return TagType_DOUBLE, nil + case "BOOL": + return TagType_BOOL, nil + case "LONG": + return TagType_LONG, nil + case "BINARY": + return TagType_BINARY, nil + } + return TagType(0), fmt.Errorf("not a valid TagType string") +} + +func TagTypePtr(v TagType) *TagType { return &v } + +func (p TagType) MarshalText() ([]byte, error) { + return []byte(p.String()), nil +} + +func (p *TagType) UnmarshalText(text []byte) error { + q, err := TagTypeFromString(string(text)) + if err != nil { + return err + } + *p = q + return nil +} + +type SpanRefType int64 + +const ( + SpanRefType_CHILD_OF SpanRefType = 0 + SpanRefType_FOLLOWS_FROM SpanRefType = 1 +) + +func (p SpanRefType) String() string { + switch p { + case SpanRefType_CHILD_OF: + return "CHILD_OF" + case SpanRefType_FOLLOWS_FROM: + return "FOLLOWS_FROM" + } + return "" +} + +func SpanRefTypeFromString(s string) (SpanRefType, error) { + switch s { + case "CHILD_OF": + return SpanRefType_CHILD_OF, nil + case "FOLLOWS_FROM": + return SpanRefType_FOLLOWS_FROM, nil + } + return SpanRefType(0), fmt.Errorf("not a valid SpanRefType string") +} + +func SpanRefTypePtr(v SpanRefType) *SpanRefType { return &v } + +func (p SpanRefType) MarshalText() ([]byte, error) { + return []byte(p.String()), nil +} + +func (p *SpanRefType) UnmarshalText(text []byte) error { + q, err := SpanRefTypeFromString(string(text)) + if err != nil { + return err + } + *p = q + return nil +} + +// Attributes: +// - Key +// - VType +// - VStr +// - VDouble +// - VBool +// - VLong +// - VBinary +type Tag struct { + Key string `thrift:"key,1,required" json:"key"` + VType TagType `thrift:"vType,2,required" json:"vType"` + VStr *string `thrift:"vStr,3" json:"vStr,omitempty"` + VDouble *float64 `thrift:"vDouble,4" json:"vDouble,omitempty"` + VBool *bool `thrift:"vBool,5" json:"vBool,omitempty"` + VLong *int64 `thrift:"vLong,6" json:"vLong,omitempty"` + VBinary []byte `thrift:"vBinary,7" json:"vBinary,omitempty"` +} + +func NewTag() *Tag { + return &Tag{} +} + +func (p *Tag) GetKey() string { + return p.Key +} + +func (p *Tag) GetVType() TagType { + return p.VType +} + +var Tag_VStr_DEFAULT string + +func (p *Tag) GetVStr() string { + if !p.IsSetVStr() { + return Tag_VStr_DEFAULT + } + return *p.VStr +} + +var Tag_VDouble_DEFAULT float64 + +func (p *Tag) GetVDouble() float64 { + if !p.IsSetVDouble() { + return Tag_VDouble_DEFAULT + } + return *p.VDouble +} + +var Tag_VBool_DEFAULT bool + +func (p *Tag) GetVBool() bool { + if !p.IsSetVBool() { + return Tag_VBool_DEFAULT + } + return *p.VBool +} + +var Tag_VLong_DEFAULT int64 + +func (p *Tag) GetVLong() int64 { + if !p.IsSetVLong() { + return Tag_VLong_DEFAULT + } + return *p.VLong +} + +var Tag_VBinary_DEFAULT []byte + +func (p *Tag) GetVBinary() []byte { + return p.VBinary +} +func (p *Tag) IsSetVStr() bool { + return p.VStr != nil +} + +func (p *Tag) IsSetVDouble() bool { + return p.VDouble != nil +} + +func (p *Tag) IsSetVBool() bool { + return p.VBool != nil +} + +func (p *Tag) IsSetVLong() bool { + return p.VLong != nil +} + +func (p *Tag) IsSetVBinary() bool { + return p.VBinary != nil +} + +func (p *Tag) Read(iprot thrift.TProtocol) error { + if _, err := iprot.ReadStructBegin(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T read error: ", p), err) + } + + var issetKey bool = false + var issetVType bool = false + + for { + _, fieldTypeId, fieldId, err := iprot.ReadFieldBegin() + if err != nil { + return thrift.PrependError(fmt.Sprintf("%T field %d read error: ", p, fieldId), err) + } + if fieldTypeId == thrift.STOP { + break + } + switch fieldId { + case 1: + if err := p.readField1(iprot); err != nil { + return err + } + issetKey = true + case 2: + if err := p.readField2(iprot); err != nil { + return err + } + issetVType = true + case 3: + if err := p.readField3(iprot); err != nil { + return err + } + case 4: + if err := p.readField4(iprot); err != nil { + return err + } + case 5: + if err := p.readField5(iprot); err != nil { + return err + } + case 6: + if err := p.readField6(iprot); err != nil { + return err + } + case 7: + if err := p.readField7(iprot); err != nil { + return err + } + default: + if err := iprot.Skip(fieldTypeId); err != nil { + return err + } + } + if err := iprot.ReadFieldEnd(); err != nil { + return err + } + } + if err := iprot.ReadStructEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) + } + if !issetKey { + return thrift.NewTProtocolExceptionWithType(thrift.INVALID_DATA, fmt.Errorf("Required field Key is not set")) + } + if !issetVType { + return thrift.NewTProtocolExceptionWithType(thrift.INVALID_DATA, fmt.Errorf("Required field VType is not set")) + } + return nil +} + +func (p *Tag) readField1(iprot thrift.TProtocol) error { + if v, err := iprot.ReadString(); err != nil { + return thrift.PrependError("error reading field 1: ", err) + } else { + p.Key = v + } + return nil +} + +func (p *Tag) readField2(iprot thrift.TProtocol) error { + if v, err := iprot.ReadI32(); err != nil { + return thrift.PrependError("error reading field 2: ", err) + } else { + temp := TagType(v) + p.VType = temp + } + return nil +} + +func (p *Tag) readField3(iprot thrift.TProtocol) error { + if v, err := iprot.ReadString(); err != nil { + return thrift.PrependError("error reading field 3: ", err) + } else { + p.VStr = &v + } + return nil +} + +func (p *Tag) readField4(iprot thrift.TProtocol) error { + if v, err := iprot.ReadDouble(); err != nil { + return thrift.PrependError("error reading field 4: ", err) + } else { + p.VDouble = &v + } + return nil +} + +func (p *Tag) readField5(iprot thrift.TProtocol) error { + if v, err := iprot.ReadBool(); err != nil { + return thrift.PrependError("error reading field 5: ", err) + } else { + p.VBool = &v + } + return nil +} + +func (p *Tag) readField6(iprot thrift.TProtocol) error { + if v, err := iprot.ReadI64(); err != nil { + return thrift.PrependError("error reading field 6: ", err) + } else { + p.VLong = &v + } + return nil +} + +func (p *Tag) readField7(iprot thrift.TProtocol) error { + if v, err := iprot.ReadBinary(); err != nil { + return thrift.PrependError("error reading field 7: ", err) + } else { + p.VBinary = v + } + return nil +} + +func (p *Tag) Write(oprot thrift.TProtocol) error { + if err := oprot.WriteStructBegin("Tag"); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) + } + if err := p.writeField1(oprot); err != nil { + return err + } + if err := p.writeField2(oprot); err != nil { + return err + } + if err := p.writeField3(oprot); err != nil { + return err + } + if err := p.writeField4(oprot); err != nil { + return err + } + if err := p.writeField5(oprot); err != nil { + return err + } + if err := p.writeField6(oprot); err != nil { + return err + } + if err := p.writeField7(oprot); err != nil { + return err + } + if err := oprot.WriteFieldStop(); err != nil { + return thrift.PrependError("write field stop error: ", err) + } + if err := oprot.WriteStructEnd(); err != nil { + return thrift.PrependError("write struct stop error: ", err) + } + return nil +} + +func (p *Tag) writeField1(oprot thrift.TProtocol) (err error) { + if err := oprot.WriteFieldBegin("key", thrift.STRING, 1); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 1:key: ", p), err) + } + if err := oprot.WriteString(string(p.Key)); err != nil { + return thrift.PrependError(fmt.Sprintf("%T.key (1) field write error: ", p), err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 1:key: ", p), err) + } + return err +} + +func (p *Tag) writeField2(oprot thrift.TProtocol) (err error) { + if err := oprot.WriteFieldBegin("vType", thrift.I32, 2); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 2:vType: ", p), err) + } + if err := oprot.WriteI32(int32(p.VType)); err != nil { + return thrift.PrependError(fmt.Sprintf("%T.vType (2) field write error: ", p), err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 2:vType: ", p), err) + } + return err +} + +func (p *Tag) writeField3(oprot thrift.TProtocol) (err error) { + if p.IsSetVStr() { + if err := oprot.WriteFieldBegin("vStr", thrift.STRING, 3); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 3:vStr: ", p), err) + } + if err := oprot.WriteString(string(*p.VStr)); err != nil { + return thrift.PrependError(fmt.Sprintf("%T.vStr (3) field write error: ", p), err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 3:vStr: ", p), err) + } + } + return err +} + +func (p *Tag) writeField4(oprot thrift.TProtocol) (err error) { + if p.IsSetVDouble() { + if err := oprot.WriteFieldBegin("vDouble", thrift.DOUBLE, 4); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 4:vDouble: ", p), err) + } + if err := oprot.WriteDouble(float64(*p.VDouble)); err != nil { + return thrift.PrependError(fmt.Sprintf("%T.vDouble (4) field write error: ", p), err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 4:vDouble: ", p), err) + } + } + return err +} + +func (p *Tag) writeField5(oprot thrift.TProtocol) (err error) { + if p.IsSetVBool() { + if err := oprot.WriteFieldBegin("vBool", thrift.BOOL, 5); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 5:vBool: ", p), err) + } + if err := oprot.WriteBool(bool(*p.VBool)); err != nil { + return thrift.PrependError(fmt.Sprintf("%T.vBool (5) field write error: ", p), err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 5:vBool: ", p), err) + } + } + return err +} + +func (p *Tag) writeField6(oprot thrift.TProtocol) (err error) { + if p.IsSetVLong() { + if err := oprot.WriteFieldBegin("vLong", thrift.I64, 6); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 6:vLong: ", p), err) + } + if err := oprot.WriteI64(int64(*p.VLong)); err != nil { + return thrift.PrependError(fmt.Sprintf("%T.vLong (6) field write error: ", p), err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 6:vLong: ", p), err) + } + } + return err +} + +func (p *Tag) writeField7(oprot thrift.TProtocol) (err error) { + if p.IsSetVBinary() { + if err := oprot.WriteFieldBegin("vBinary", thrift.STRING, 7); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 7:vBinary: ", p), err) + } + if err := oprot.WriteBinary(p.VBinary); err != nil { + return thrift.PrependError(fmt.Sprintf("%T.vBinary (7) field write error: ", p), err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 7:vBinary: ", p), err) + } + } + return err +} + +func (p *Tag) String() string { + if p == nil { + return "" + } + return fmt.Sprintf("Tag(%+v)", *p) +} + +// Attributes: +// - Timestamp +// - Fields +type Log struct { + Timestamp int64 `thrift:"timestamp,1,required" json:"timestamp"` + Fields []*Tag `thrift:"fields,2,required" json:"fields"` +} + +func NewLog() *Log { + return &Log{} +} + +func (p *Log) GetTimestamp() int64 { + return p.Timestamp +} + +func (p *Log) GetFields() []*Tag { + return p.Fields +} +func (p *Log) Read(iprot thrift.TProtocol) error { + if _, err := iprot.ReadStructBegin(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T read error: ", p), err) + } + + var issetTimestamp bool = false + var issetFields bool = false + + for { + _, fieldTypeId, fieldId, err := iprot.ReadFieldBegin() + if err != nil { + return thrift.PrependError(fmt.Sprintf("%T field %d read error: ", p, fieldId), err) + } + if fieldTypeId == thrift.STOP { + break + } + switch fieldId { + case 1: + if err := p.readField1(iprot); err != nil { + return err + } + issetTimestamp = true + case 2: + if err := p.readField2(iprot); err != nil { + return err + } + issetFields = true + default: + if err := iprot.Skip(fieldTypeId); err != nil { + return err + } + } + if err := iprot.ReadFieldEnd(); err != nil { + return err + } + } + if err := iprot.ReadStructEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) + } + if !issetTimestamp { + return thrift.NewTProtocolExceptionWithType(thrift.INVALID_DATA, fmt.Errorf("Required field Timestamp is not set")) + } + if !issetFields { + return thrift.NewTProtocolExceptionWithType(thrift.INVALID_DATA, fmt.Errorf("Required field Fields is not set")) + } + return nil +} + +func (p *Log) readField1(iprot thrift.TProtocol) error { + if v, err := iprot.ReadI64(); err != nil { + return thrift.PrependError("error reading field 1: ", err) + } else { + p.Timestamp = v + } + return nil +} + +func (p *Log) readField2(iprot thrift.TProtocol) error { + _, size, err := iprot.ReadListBegin() + if err != nil { + return thrift.PrependError("error reading list begin: ", err) + } + tSlice := make([]*Tag, 0, size) + p.Fields = tSlice + for i := 0; i < size; i++ { + _elem0 := &Tag{} + if err := _elem0.Read(iprot); err != nil { + return thrift.PrependError(fmt.Sprintf("%T error reading struct: ", _elem0), err) + } + p.Fields = append(p.Fields, _elem0) + } + if err := iprot.ReadListEnd(); err != nil { + return thrift.PrependError("error reading list end: ", err) + } + return nil +} + +func (p *Log) Write(oprot thrift.TProtocol) error { + if err := oprot.WriteStructBegin("Log"); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) + } + if err := p.writeField1(oprot); err != nil { + return err + } + if err := p.writeField2(oprot); err != nil { + return err + } + if err := oprot.WriteFieldStop(); err != nil { + return thrift.PrependError("write field stop error: ", err) + } + if err := oprot.WriteStructEnd(); err != nil { + return thrift.PrependError("write struct stop error: ", err) + } + return nil +} + +func (p *Log) writeField1(oprot thrift.TProtocol) (err error) { + if err := oprot.WriteFieldBegin("timestamp", thrift.I64, 1); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 1:timestamp: ", p), err) + } + if err := oprot.WriteI64(int64(p.Timestamp)); err != nil { + return thrift.PrependError(fmt.Sprintf("%T.timestamp (1) field write error: ", p), err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 1:timestamp: ", p), err) + } + return err +} + +func (p *Log) writeField2(oprot thrift.TProtocol) (err error) { + if err := oprot.WriteFieldBegin("fields", thrift.LIST, 2); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 2:fields: ", p), err) + } + if err := oprot.WriteListBegin(thrift.STRUCT, len(p.Fields)); err != nil { + return thrift.PrependError("error writing list begin: ", err) + } + for _, v := range p.Fields { + if err := v.Write(oprot); err != nil { + return thrift.PrependError(fmt.Sprintf("%T error writing struct: ", v), err) + } + } + if err := oprot.WriteListEnd(); err != nil { + return thrift.PrependError("error writing list end: ", err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 2:fields: ", p), err) + } + return err +} + +func (p *Log) String() string { + if p == nil { + return "" + } + return fmt.Sprintf("Log(%+v)", *p) +} + +// Attributes: +// - RefType +// - TraceIdLow +// - TraceIdHigh +// - SpanId +type SpanRef struct { + RefType SpanRefType `thrift:"refType,1,required" json:"refType"` + TraceIdLow int64 `thrift:"traceIdLow,2,required" json:"traceIdLow"` + TraceIdHigh int64 `thrift:"traceIdHigh,3,required" json:"traceIdHigh"` + SpanId int64 `thrift:"spanId,4,required" json:"spanId"` +} + +func NewSpanRef() *SpanRef { + return &SpanRef{} +} + +func (p *SpanRef) GetRefType() SpanRefType { + return p.RefType +} + +func (p *SpanRef) GetTraceIdLow() int64 { + return p.TraceIdLow +} + +func (p *SpanRef) GetTraceIdHigh() int64 { + return p.TraceIdHigh +} + +func (p *SpanRef) GetSpanId() int64 { + return p.SpanId +} +func (p *SpanRef) Read(iprot thrift.TProtocol) error { + if _, err := iprot.ReadStructBegin(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T read error: ", p), err) + } + + var issetRefType bool = false + var issetTraceIdLow bool = false + var issetTraceIdHigh bool = false + var issetSpanId bool = false + + for { + _, fieldTypeId, fieldId, err := iprot.ReadFieldBegin() + if err != nil { + return thrift.PrependError(fmt.Sprintf("%T field %d read error: ", p, fieldId), err) + } + if fieldTypeId == thrift.STOP { + break + } + switch fieldId { + case 1: + if err := p.readField1(iprot); err != nil { + return err + } + issetRefType = true + case 2: + if err := p.readField2(iprot); err != nil { + return err + } + issetTraceIdLow = true + case 3: + if err := p.readField3(iprot); err != nil { + return err + } + issetTraceIdHigh = true + case 4: + if err := p.readField4(iprot); err != nil { + return err + } + issetSpanId = true + default: + if err := iprot.Skip(fieldTypeId); err != nil { + return err + } + } + if err := iprot.ReadFieldEnd(); err != nil { + return err + } + } + if err := iprot.ReadStructEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) + } + if !issetRefType { + return thrift.NewTProtocolExceptionWithType(thrift.INVALID_DATA, fmt.Errorf("Required field RefType is not set")) + } + if !issetTraceIdLow { + return thrift.NewTProtocolExceptionWithType(thrift.INVALID_DATA, fmt.Errorf("Required field TraceIdLow is not set")) + } + if !issetTraceIdHigh { + return thrift.NewTProtocolExceptionWithType(thrift.INVALID_DATA, fmt.Errorf("Required field TraceIdHigh is not set")) + } + if !issetSpanId { + return thrift.NewTProtocolExceptionWithType(thrift.INVALID_DATA, fmt.Errorf("Required field SpanId is not set")) + } + return nil +} + +func (p *SpanRef) readField1(iprot thrift.TProtocol) error { + if v, err := iprot.ReadI32(); err != nil { + return thrift.PrependError("error reading field 1: ", err) + } else { + temp := SpanRefType(v) + p.RefType = temp + } + return nil +} + +func (p *SpanRef) readField2(iprot thrift.TProtocol) error { + if v, err := iprot.ReadI64(); err != nil { + return thrift.PrependError("error reading field 2: ", err) + } else { + p.TraceIdLow = v + } + return nil +} + +func (p *SpanRef) readField3(iprot thrift.TProtocol) error { + if v, err := iprot.ReadI64(); err != nil { + return thrift.PrependError("error reading field 3: ", err) + } else { + p.TraceIdHigh = v + } + return nil +} + +func (p *SpanRef) readField4(iprot thrift.TProtocol) error { + if v, err := iprot.ReadI64(); err != nil { + return thrift.PrependError("error reading field 4: ", err) + } else { + p.SpanId = v + } + return nil +} + +func (p *SpanRef) Write(oprot thrift.TProtocol) error { + if err := oprot.WriteStructBegin("SpanRef"); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) + } + if err := p.writeField1(oprot); err != nil { + return err + } + if err := p.writeField2(oprot); err != nil { + return err + } + if err := p.writeField3(oprot); err != nil { + return err + } + if err := p.writeField4(oprot); err != nil { + return err + } + if err := oprot.WriteFieldStop(); err != nil { + return thrift.PrependError("write field stop error: ", err) + } + if err := oprot.WriteStructEnd(); err != nil { + return thrift.PrependError("write struct stop error: ", err) + } + return nil +} + +func (p *SpanRef) writeField1(oprot thrift.TProtocol) (err error) { + if err := oprot.WriteFieldBegin("refType", thrift.I32, 1); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 1:refType: ", p), err) + } + if err := oprot.WriteI32(int32(p.RefType)); err != nil { + return thrift.PrependError(fmt.Sprintf("%T.refType (1) field write error: ", p), err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 1:refType: ", p), err) + } + return err +} + +func (p *SpanRef) writeField2(oprot thrift.TProtocol) (err error) { + if err := oprot.WriteFieldBegin("traceIdLow", thrift.I64, 2); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 2:traceIdLow: ", p), err) + } + if err := oprot.WriteI64(int64(p.TraceIdLow)); err != nil { + return thrift.PrependError(fmt.Sprintf("%T.traceIdLow (2) field write error: ", p), err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 2:traceIdLow: ", p), err) + } + return err +} + +func (p *SpanRef) writeField3(oprot thrift.TProtocol) (err error) { + if err := oprot.WriteFieldBegin("traceIdHigh", thrift.I64, 3); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 3:traceIdHigh: ", p), err) + } + if err := oprot.WriteI64(int64(p.TraceIdHigh)); err != nil { + return thrift.PrependError(fmt.Sprintf("%T.traceIdHigh (3) field write error: ", p), err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 3:traceIdHigh: ", p), err) + } + return err +} + +func (p *SpanRef) writeField4(oprot thrift.TProtocol) (err error) { + if err := oprot.WriteFieldBegin("spanId", thrift.I64, 4); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 4:spanId: ", p), err) + } + if err := oprot.WriteI64(int64(p.SpanId)); err != nil { + return thrift.PrependError(fmt.Sprintf("%T.spanId (4) field write error: ", p), err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 4:spanId: ", p), err) + } + return err +} + +func (p *SpanRef) String() string { + if p == nil { + return "" + } + return fmt.Sprintf("SpanRef(%+v)", *p) +} + +// Attributes: +// - TraceIdLow +// - TraceIdHigh +// - SpanId +// - ParentSpanId +// - OperationName +// - References +// - Flags +// - StartTime +// - Duration +// - Tags +// - Logs +type Span struct { + TraceIdLow int64 `thrift:"traceIdLow,1,required" json:"traceIdLow"` + TraceIdHigh int64 `thrift:"traceIdHigh,2,required" json:"traceIdHigh"` + SpanId int64 `thrift:"spanId,3,required" json:"spanId"` + ParentSpanId int64 `thrift:"parentSpanId,4,required" json:"parentSpanId"` + OperationName string `thrift:"operationName,5,required" json:"operationName"` + References []*SpanRef `thrift:"references,6" json:"references,omitempty"` + Flags int32 `thrift:"flags,7,required" json:"flags"` + StartTime int64 `thrift:"startTime,8,required" json:"startTime"` + Duration int64 `thrift:"duration,9,required" json:"duration"` + Tags []*Tag `thrift:"tags,10" json:"tags,omitempty"` + Logs []*Log `thrift:"logs,11" json:"logs,omitempty"` +} + +func NewSpan() *Span { + return &Span{} +} + +func (p *Span) GetTraceIdLow() int64 { + return p.TraceIdLow +} + +func (p *Span) GetTraceIdHigh() int64 { + return p.TraceIdHigh +} + +func (p *Span) GetSpanId() int64 { + return p.SpanId +} + +func (p *Span) GetParentSpanId() int64 { + return p.ParentSpanId +} + +func (p *Span) GetOperationName() string { + return p.OperationName +} + +var Span_References_DEFAULT []*SpanRef + +func (p *Span) GetReferences() []*SpanRef { + return p.References +} + +func (p *Span) GetFlags() int32 { + return p.Flags +} + +func (p *Span) GetStartTime() int64 { + return p.StartTime +} + +func (p *Span) GetDuration() int64 { + return p.Duration +} + +var Span_Tags_DEFAULT []*Tag + +func (p *Span) GetTags() []*Tag { + return p.Tags +} + +var Span_Logs_DEFAULT []*Log + +func (p *Span) GetLogs() []*Log { + return p.Logs +} +func (p *Span) IsSetReferences() bool { + return p.References != nil +} + +func (p *Span) IsSetTags() bool { + return p.Tags != nil +} + +func (p *Span) IsSetLogs() bool { + return p.Logs != nil +} + +func (p *Span) Read(iprot thrift.TProtocol) error { + if _, err := iprot.ReadStructBegin(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T read error: ", p), err) + } + + var issetTraceIdLow bool = false + var issetTraceIdHigh bool = false + var issetSpanId bool = false + var issetParentSpanId bool = false + var issetOperationName bool = false + var issetFlags bool = false + var issetStartTime bool = false + var issetDuration bool = false + + for { + _, fieldTypeId, fieldId, err := iprot.ReadFieldBegin() + if err != nil { + return thrift.PrependError(fmt.Sprintf("%T field %d read error: ", p, fieldId), err) + } + if fieldTypeId == thrift.STOP { + break + } + switch fieldId { + case 1: + if err := p.readField1(iprot); err != nil { + return err + } + issetTraceIdLow = true + case 2: + if err := p.readField2(iprot); err != nil { + return err + } + issetTraceIdHigh = true + case 3: + if err := p.readField3(iprot); err != nil { + return err + } + issetSpanId = true + case 4: + if err := p.readField4(iprot); err != nil { + return err + } + issetParentSpanId = true + case 5: + if err := p.readField5(iprot); err != nil { + return err + } + issetOperationName = true + case 6: + if err := p.readField6(iprot); err != nil { + return err + } + case 7: + if err := p.readField7(iprot); err != nil { + return err + } + issetFlags = true + case 8: + if err := p.readField8(iprot); err != nil { + return err + } + issetStartTime = true + case 9: + if err := p.readField9(iprot); err != nil { + return err + } + issetDuration = true + case 10: + if err := p.readField10(iprot); err != nil { + return err + } + case 11: + if err := p.readField11(iprot); err != nil { + return err + } + default: + if err := iprot.Skip(fieldTypeId); err != nil { + return err + } + } + if err := iprot.ReadFieldEnd(); err != nil { + return err + } + } + if err := iprot.ReadStructEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) + } + if !issetTraceIdLow { + return thrift.NewTProtocolExceptionWithType(thrift.INVALID_DATA, fmt.Errorf("Required field TraceIdLow is not set")) + } + if !issetTraceIdHigh { + return thrift.NewTProtocolExceptionWithType(thrift.INVALID_DATA, fmt.Errorf("Required field TraceIdHigh is not set")) + } + if !issetSpanId { + return thrift.NewTProtocolExceptionWithType(thrift.INVALID_DATA, fmt.Errorf("Required field SpanId is not set")) + } + if !issetParentSpanId { + return thrift.NewTProtocolExceptionWithType(thrift.INVALID_DATA, fmt.Errorf("Required field ParentSpanId is not set")) + } + if !issetOperationName { + return thrift.NewTProtocolExceptionWithType(thrift.INVALID_DATA, fmt.Errorf("Required field OperationName is not set")) + } + if !issetFlags { + return thrift.NewTProtocolExceptionWithType(thrift.INVALID_DATA, fmt.Errorf("Required field Flags is not set")) + } + if !issetStartTime { + return thrift.NewTProtocolExceptionWithType(thrift.INVALID_DATA, fmt.Errorf("Required field StartTime is not set")) + } + if !issetDuration { + return thrift.NewTProtocolExceptionWithType(thrift.INVALID_DATA, fmt.Errorf("Required field Duration is not set")) + } + return nil +} + +func (p *Span) readField1(iprot thrift.TProtocol) error { + if v, err := iprot.ReadI64(); err != nil { + return thrift.PrependError("error reading field 1: ", err) + } else { + p.TraceIdLow = v + } + return nil +} + +func (p *Span) readField2(iprot thrift.TProtocol) error { + if v, err := iprot.ReadI64(); err != nil { + return thrift.PrependError("error reading field 2: ", err) + } else { + p.TraceIdHigh = v + } + return nil +} + +func (p *Span) readField3(iprot thrift.TProtocol) error { + if v, err := iprot.ReadI64(); err != nil { + return thrift.PrependError("error reading field 3: ", err) + } else { + p.SpanId = v + } + return nil +} + +func (p *Span) readField4(iprot thrift.TProtocol) error { + if v, err := iprot.ReadI64(); err != nil { + return thrift.PrependError("error reading field 4: ", err) + } else { + p.ParentSpanId = v + } + return nil +} + +func (p *Span) readField5(iprot thrift.TProtocol) error { + if v, err := iprot.ReadString(); err != nil { + return thrift.PrependError("error reading field 5: ", err) + } else { + p.OperationName = v + } + return nil +} + +func (p *Span) readField6(iprot thrift.TProtocol) error { + _, size, err := iprot.ReadListBegin() + if err != nil { + return thrift.PrependError("error reading list begin: ", err) + } + tSlice := make([]*SpanRef, 0, size) + p.References = tSlice + for i := 0; i < size; i++ { + _elem1 := &SpanRef{} + if err := _elem1.Read(iprot); err != nil { + return thrift.PrependError(fmt.Sprintf("%T error reading struct: ", _elem1), err) + } + p.References = append(p.References, _elem1) + } + if err := iprot.ReadListEnd(); err != nil { + return thrift.PrependError("error reading list end: ", err) + } + return nil +} + +func (p *Span) readField7(iprot thrift.TProtocol) error { + if v, err := iprot.ReadI32(); err != nil { + return thrift.PrependError("error reading field 7: ", err) + } else { + p.Flags = v + } + return nil +} + +func (p *Span) readField8(iprot thrift.TProtocol) error { + if v, err := iprot.ReadI64(); err != nil { + return thrift.PrependError("error reading field 8: ", err) + } else { + p.StartTime = v + } + return nil +} + +func (p *Span) readField9(iprot thrift.TProtocol) error { + if v, err := iprot.ReadI64(); err != nil { + return thrift.PrependError("error reading field 9: ", err) + } else { + p.Duration = v + } + return nil +} + +func (p *Span) readField10(iprot thrift.TProtocol) error { + _, size, err := iprot.ReadListBegin() + if err != nil { + return thrift.PrependError("error reading list begin: ", err) + } + tSlice := make([]*Tag, 0, size) + p.Tags = tSlice + for i := 0; i < size; i++ { + _elem2 := &Tag{} + if err := _elem2.Read(iprot); err != nil { + return thrift.PrependError(fmt.Sprintf("%T error reading struct: ", _elem2), err) + } + p.Tags = append(p.Tags, _elem2) + } + if err := iprot.ReadListEnd(); err != nil { + return thrift.PrependError("error reading list end: ", err) + } + return nil +} + +func (p *Span) readField11(iprot thrift.TProtocol) error { + _, size, err := iprot.ReadListBegin() + if err != nil { + return thrift.PrependError("error reading list begin: ", err) + } + tSlice := make([]*Log, 0, size) + p.Logs = tSlice + for i := 0; i < size; i++ { + _elem3 := &Log{} + if err := _elem3.Read(iprot); err != nil { + return thrift.PrependError(fmt.Sprintf("%T error reading struct: ", _elem3), err) + } + p.Logs = append(p.Logs, _elem3) + } + if err := iprot.ReadListEnd(); err != nil { + return thrift.PrependError("error reading list end: ", err) + } + return nil +} + +func (p *Span) Write(oprot thrift.TProtocol) error { + if err := oprot.WriteStructBegin("Span"); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) + } + if err := p.writeField1(oprot); err != nil { + return err + } + if err := p.writeField2(oprot); err != nil { + return err + } + if err := p.writeField3(oprot); err != nil { + return err + } + if err := p.writeField4(oprot); err != nil { + return err + } + if err := p.writeField5(oprot); err != nil { + return err + } + if err := p.writeField6(oprot); err != nil { + return err + } + if err := p.writeField7(oprot); err != nil { + return err + } + if err := p.writeField8(oprot); err != nil { + return err + } + if err := p.writeField9(oprot); err != nil { + return err + } + if err := p.writeField10(oprot); err != nil { + return err + } + if err := p.writeField11(oprot); err != nil { + return err + } + if err := oprot.WriteFieldStop(); err != nil { + return thrift.PrependError("write field stop error: ", err) + } + if err := oprot.WriteStructEnd(); err != nil { + return thrift.PrependError("write struct stop error: ", err) + } + return nil +} + +func (p *Span) writeField1(oprot thrift.TProtocol) (err error) { + if err := oprot.WriteFieldBegin("traceIdLow", thrift.I64, 1); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 1:traceIdLow: ", p), err) + } + if err := oprot.WriteI64(int64(p.TraceIdLow)); err != nil { + return thrift.PrependError(fmt.Sprintf("%T.traceIdLow (1) field write error: ", p), err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 1:traceIdLow: ", p), err) + } + return err +} + +func (p *Span) writeField2(oprot thrift.TProtocol) (err error) { + if err := oprot.WriteFieldBegin("traceIdHigh", thrift.I64, 2); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 2:traceIdHigh: ", p), err) + } + if err := oprot.WriteI64(int64(p.TraceIdHigh)); err != nil { + return thrift.PrependError(fmt.Sprintf("%T.traceIdHigh (2) field write error: ", p), err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 2:traceIdHigh: ", p), err) + } + return err +} + +func (p *Span) writeField3(oprot thrift.TProtocol) (err error) { + if err := oprot.WriteFieldBegin("spanId", thrift.I64, 3); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 3:spanId: ", p), err) + } + if err := oprot.WriteI64(int64(p.SpanId)); err != nil { + return thrift.PrependError(fmt.Sprintf("%T.spanId (3) field write error: ", p), err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 3:spanId: ", p), err) + } + return err +} + +func (p *Span) writeField4(oprot thrift.TProtocol) (err error) { + if err := oprot.WriteFieldBegin("parentSpanId", thrift.I64, 4); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 4:parentSpanId: ", p), err) + } + if err := oprot.WriteI64(int64(p.ParentSpanId)); err != nil { + return thrift.PrependError(fmt.Sprintf("%T.parentSpanId (4) field write error: ", p), err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 4:parentSpanId: ", p), err) + } + return err +} + +func (p *Span) writeField5(oprot thrift.TProtocol) (err error) { + if err := oprot.WriteFieldBegin("operationName", thrift.STRING, 5); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 5:operationName: ", p), err) + } + if err := oprot.WriteString(string(p.OperationName)); err != nil { + return thrift.PrependError(fmt.Sprintf("%T.operationName (5) field write error: ", p), err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 5:operationName: ", p), err) + } + return err +} + +func (p *Span) writeField6(oprot thrift.TProtocol) (err error) { + if p.IsSetReferences() { + if err := oprot.WriteFieldBegin("references", thrift.LIST, 6); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 6:references: ", p), err) + } + if err := oprot.WriteListBegin(thrift.STRUCT, len(p.References)); err != nil { + return thrift.PrependError("error writing list begin: ", err) + } + for _, v := range p.References { + if err := v.Write(oprot); err != nil { + return thrift.PrependError(fmt.Sprintf("%T error writing struct: ", v), err) + } + } + if err := oprot.WriteListEnd(); err != nil { + return thrift.PrependError("error writing list end: ", err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 6:references: ", p), err) + } + } + return err +} + +func (p *Span) writeField7(oprot thrift.TProtocol) (err error) { + if err := oprot.WriteFieldBegin("flags", thrift.I32, 7); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 7:flags: ", p), err) + } + if err := oprot.WriteI32(int32(p.Flags)); err != nil { + return thrift.PrependError(fmt.Sprintf("%T.flags (7) field write error: ", p), err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 7:flags: ", p), err) + } + return err +} + +func (p *Span) writeField8(oprot thrift.TProtocol) (err error) { + if err := oprot.WriteFieldBegin("startTime", thrift.I64, 8); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 8:startTime: ", p), err) + } + if err := oprot.WriteI64(int64(p.StartTime)); err != nil { + return thrift.PrependError(fmt.Sprintf("%T.startTime (8) field write error: ", p), err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 8:startTime: ", p), err) + } + return err +} + +func (p *Span) writeField9(oprot thrift.TProtocol) (err error) { + if err := oprot.WriteFieldBegin("duration", thrift.I64, 9); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 9:duration: ", p), err) + } + if err := oprot.WriteI64(int64(p.Duration)); err != nil { + return thrift.PrependError(fmt.Sprintf("%T.duration (9) field write error: ", p), err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 9:duration: ", p), err) + } + return err +} + +func (p *Span) writeField10(oprot thrift.TProtocol) (err error) { + if p.IsSetTags() { + if err := oprot.WriteFieldBegin("tags", thrift.LIST, 10); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 10:tags: ", p), err) + } + if err := oprot.WriteListBegin(thrift.STRUCT, len(p.Tags)); err != nil { + return thrift.PrependError("error writing list begin: ", err) + } + for _, v := range p.Tags { + if err := v.Write(oprot); err != nil { + return thrift.PrependError(fmt.Sprintf("%T error writing struct: ", v), err) + } + } + if err := oprot.WriteListEnd(); err != nil { + return thrift.PrependError("error writing list end: ", err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 10:tags: ", p), err) + } + } + return err +} + +func (p *Span) writeField11(oprot thrift.TProtocol) (err error) { + if p.IsSetLogs() { + if err := oprot.WriteFieldBegin("logs", thrift.LIST, 11); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 11:logs: ", p), err) + } + if err := oprot.WriteListBegin(thrift.STRUCT, len(p.Logs)); err != nil { + return thrift.PrependError("error writing list begin: ", err) + } + for _, v := range p.Logs { + if err := v.Write(oprot); err != nil { + return thrift.PrependError(fmt.Sprintf("%T error writing struct: ", v), err) + } + } + if err := oprot.WriteListEnd(); err != nil { + return thrift.PrependError("error writing list end: ", err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 11:logs: ", p), err) + } + } + return err +} + +func (p *Span) String() string { + if p == nil { + return "" + } + return fmt.Sprintf("Span(%+v)", *p) +} + +// Attributes: +// - ServiceName +// - Tags +type Process struct { + ServiceName string `thrift:"serviceName,1,required" json:"serviceName"` + Tags []*Tag `thrift:"tags,2" json:"tags,omitempty"` +} + +func NewProcess() *Process { + return &Process{} +} + +func (p *Process) GetServiceName() string { + return p.ServiceName +} + +var Process_Tags_DEFAULT []*Tag + +func (p *Process) GetTags() []*Tag { + return p.Tags +} +func (p *Process) IsSetTags() bool { + return p.Tags != nil +} + +func (p *Process) Read(iprot thrift.TProtocol) error { + if _, err := iprot.ReadStructBegin(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T read error: ", p), err) + } + + var issetServiceName bool = false + + for { + _, fieldTypeId, fieldId, err := iprot.ReadFieldBegin() + if err != nil { + return thrift.PrependError(fmt.Sprintf("%T field %d read error: ", p, fieldId), err) + } + if fieldTypeId == thrift.STOP { + break + } + switch fieldId { + case 1: + if err := p.readField1(iprot); err != nil { + return err + } + issetServiceName = true + case 2: + if err := p.readField2(iprot); err != nil { + return err + } + default: + if err := iprot.Skip(fieldTypeId); err != nil { + return err + } + } + if err := iprot.ReadFieldEnd(); err != nil { + return err + } + } + if err := iprot.ReadStructEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) + } + if !issetServiceName { + return thrift.NewTProtocolExceptionWithType(thrift.INVALID_DATA, fmt.Errorf("Required field ServiceName is not set")) + } + return nil +} + +func (p *Process) readField1(iprot thrift.TProtocol) error { + if v, err := iprot.ReadString(); err != nil { + return thrift.PrependError("error reading field 1: ", err) + } else { + p.ServiceName = v + } + return nil +} + +func (p *Process) readField2(iprot thrift.TProtocol) error { + _, size, err := iprot.ReadListBegin() + if err != nil { + return thrift.PrependError("error reading list begin: ", err) + } + tSlice := make([]*Tag, 0, size) + p.Tags = tSlice + for i := 0; i < size; i++ { + _elem4 := &Tag{} + if err := _elem4.Read(iprot); err != nil { + return thrift.PrependError(fmt.Sprintf("%T error reading struct: ", _elem4), err) + } + p.Tags = append(p.Tags, _elem4) + } + if err := iprot.ReadListEnd(); err != nil { + return thrift.PrependError("error reading list end: ", err) + } + return nil +} + +func (p *Process) Write(oprot thrift.TProtocol) error { + if err := oprot.WriteStructBegin("Process"); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) + } + if err := p.writeField1(oprot); err != nil { + return err + } + if err := p.writeField2(oprot); err != nil { + return err + } + if err := oprot.WriteFieldStop(); err != nil { + return thrift.PrependError("write field stop error: ", err) + } + if err := oprot.WriteStructEnd(); err != nil { + return thrift.PrependError("write struct stop error: ", err) + } + return nil +} + +func (p *Process) writeField1(oprot thrift.TProtocol) (err error) { + if err := oprot.WriteFieldBegin("serviceName", thrift.STRING, 1); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 1:serviceName: ", p), err) + } + if err := oprot.WriteString(string(p.ServiceName)); err != nil { + return thrift.PrependError(fmt.Sprintf("%T.serviceName (1) field write error: ", p), err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 1:serviceName: ", p), err) + } + return err +} + +func (p *Process) writeField2(oprot thrift.TProtocol) (err error) { + if p.IsSetTags() { + if err := oprot.WriteFieldBegin("tags", thrift.LIST, 2); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 2:tags: ", p), err) + } + if err := oprot.WriteListBegin(thrift.STRUCT, len(p.Tags)); err != nil { + return thrift.PrependError("error writing list begin: ", err) + } + for _, v := range p.Tags { + if err := v.Write(oprot); err != nil { + return thrift.PrependError(fmt.Sprintf("%T error writing struct: ", v), err) + } + } + if err := oprot.WriteListEnd(); err != nil { + return thrift.PrependError("error writing list end: ", err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 2:tags: ", p), err) + } + } + return err +} + +func (p *Process) String() string { + if p == nil { + return "" + } + return fmt.Sprintf("Process(%+v)", *p) +} + +// Attributes: +// - Process +// - Spans +type Batch struct { + Process *Process `thrift:"process,1,required" json:"process"` + Spans []*Span `thrift:"spans,2,required" json:"spans"` +} + +func NewBatch() *Batch { + return &Batch{} +} + +var Batch_Process_DEFAULT *Process + +func (p *Batch) GetProcess() *Process { + if !p.IsSetProcess() { + return Batch_Process_DEFAULT + } + return p.Process +} + +func (p *Batch) GetSpans() []*Span { + return p.Spans +} +func (p *Batch) IsSetProcess() bool { + return p.Process != nil +} + +func (p *Batch) Read(iprot thrift.TProtocol) error { + if _, err := iprot.ReadStructBegin(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T read error: ", p), err) + } + + var issetProcess bool = false + var issetSpans bool = false + + for { + _, fieldTypeId, fieldId, err := iprot.ReadFieldBegin() + if err != nil { + return thrift.PrependError(fmt.Sprintf("%T field %d read error: ", p, fieldId), err) + } + if fieldTypeId == thrift.STOP { + break + } + switch fieldId { + case 1: + if err := p.readField1(iprot); err != nil { + return err + } + issetProcess = true + case 2: + if err := p.readField2(iprot); err != nil { + return err + } + issetSpans = true + default: + if err := iprot.Skip(fieldTypeId); err != nil { + return err + } + } + if err := iprot.ReadFieldEnd(); err != nil { + return err + } + } + if err := iprot.ReadStructEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) + } + if !issetProcess { + return thrift.NewTProtocolExceptionWithType(thrift.INVALID_DATA, fmt.Errorf("Required field Process is not set")) + } + if !issetSpans { + return thrift.NewTProtocolExceptionWithType(thrift.INVALID_DATA, fmt.Errorf("Required field Spans is not set")) + } + return nil +} + +func (p *Batch) readField1(iprot thrift.TProtocol) error { + p.Process = &Process{} + if err := p.Process.Read(iprot); err != nil { + return thrift.PrependError(fmt.Sprintf("%T error reading struct: ", p.Process), err) + } + return nil +} + +func (p *Batch) readField2(iprot thrift.TProtocol) error { + _, size, err := iprot.ReadListBegin() + if err != nil { + return thrift.PrependError("error reading list begin: ", err) + } + tSlice := make([]*Span, 0, size) + p.Spans = tSlice + for i := 0; i < size; i++ { + _elem5 := &Span{} + if err := _elem5.Read(iprot); err != nil { + return thrift.PrependError(fmt.Sprintf("%T error reading struct: ", _elem5), err) + } + p.Spans = append(p.Spans, _elem5) + } + if err := iprot.ReadListEnd(); err != nil { + return thrift.PrependError("error reading list end: ", err) + } + return nil +} + +func (p *Batch) Write(oprot thrift.TProtocol) error { + if err := oprot.WriteStructBegin("Batch"); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) + } + if err := p.writeField1(oprot); err != nil { + return err + } + if err := p.writeField2(oprot); err != nil { + return err + } + if err := oprot.WriteFieldStop(); err != nil { + return thrift.PrependError("write field stop error: ", err) + } + if err := oprot.WriteStructEnd(); err != nil { + return thrift.PrependError("write struct stop error: ", err) + } + return nil +} + +func (p *Batch) writeField1(oprot thrift.TProtocol) (err error) { + if err := oprot.WriteFieldBegin("process", thrift.STRUCT, 1); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 1:process: ", p), err) + } + if err := p.Process.Write(oprot); err != nil { + return thrift.PrependError(fmt.Sprintf("%T error writing struct: ", p.Process), err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 1:process: ", p), err) + } + return err +} + +func (p *Batch) writeField2(oprot thrift.TProtocol) (err error) { + if err := oprot.WriteFieldBegin("spans", thrift.LIST, 2); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 2:spans: ", p), err) + } + if err := oprot.WriteListBegin(thrift.STRUCT, len(p.Spans)); err != nil { + return thrift.PrependError("error writing list begin: ", err) + } + for _, v := range p.Spans { + if err := v.Write(oprot); err != nil { + return thrift.PrependError(fmt.Sprintf("%T error writing struct: ", v), err) + } + } + if err := oprot.WriteListEnd(); err != nil { + return thrift.PrependError("error writing list end: ", err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 2:spans: ", p), err) + } + return err +} + +func (p *Batch) String() string { + if p == nil { + return "" + } + return fmt.Sprintf("Batch(%+v)", *p) +} + +// Attributes: +// - Ok +type BatchSubmitResponse struct { + Ok bool `thrift:"ok,1,required" json:"ok"` +} + +func NewBatchSubmitResponse() *BatchSubmitResponse { + return &BatchSubmitResponse{} +} + +func (p *BatchSubmitResponse) GetOk() bool { + return p.Ok +} +func (p *BatchSubmitResponse) Read(iprot thrift.TProtocol) error { + if _, err := iprot.ReadStructBegin(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T read error: ", p), err) + } + + var issetOk bool = false + + for { + _, fieldTypeId, fieldId, err := iprot.ReadFieldBegin() + if err != nil { + return thrift.PrependError(fmt.Sprintf("%T field %d read error: ", p, fieldId), err) + } + if fieldTypeId == thrift.STOP { + break + } + switch fieldId { + case 1: + if err := p.readField1(iprot); err != nil { + return err + } + issetOk = true + default: + if err := iprot.Skip(fieldTypeId); err != nil { + return err + } + } + if err := iprot.ReadFieldEnd(); err != nil { + return err + } + } + if err := iprot.ReadStructEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) + } + if !issetOk { + return thrift.NewTProtocolExceptionWithType(thrift.INVALID_DATA, fmt.Errorf("Required field Ok is not set")) + } + return nil +} + +func (p *BatchSubmitResponse) readField1(iprot thrift.TProtocol) error { + if v, err := iprot.ReadBool(); err != nil { + return thrift.PrependError("error reading field 1: ", err) + } else { + p.Ok = v + } + return nil +} + +func (p *BatchSubmitResponse) Write(oprot thrift.TProtocol) error { + if err := oprot.WriteStructBegin("BatchSubmitResponse"); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) + } + if err := p.writeField1(oprot); err != nil { + return err + } + if err := oprot.WriteFieldStop(); err != nil { + return thrift.PrependError("write field stop error: ", err) + } + if err := oprot.WriteStructEnd(); err != nil { + return thrift.PrependError("write struct stop error: ", err) + } + return nil +} + +func (p *BatchSubmitResponse) writeField1(oprot thrift.TProtocol) (err error) { + if err := oprot.WriteFieldBegin("ok", thrift.BOOL, 1); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 1:ok: ", p), err) + } + if err := oprot.WriteBool(bool(p.Ok)); err != nil { + return thrift.PrependError(fmt.Sprintf("%T.ok (1) field write error: ", p), err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 1:ok: ", p), err) + } + return err +} + +func (p *BatchSubmitResponse) String() string { + if p == nil { + return "" + } + return fmt.Sprintf("BatchSubmitResponse(%+v)", *p) +} diff --git a/vendor/github.com/uber/jaeger-client-go/thrift-gen/sampling/constants.go b/vendor/github.com/uber/jaeger-client-go/thrift-gen/sampling/constants.go new file mode 100644 index 0000000000..0f6e3a884d --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/thrift-gen/sampling/constants.go @@ -0,0 +1,18 @@ +// Autogenerated by Thrift Compiler (0.9.3) +// DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + +package sampling + +import ( + "bytes" + "fmt" + "github.com/uber/jaeger-client-go/thrift" +) + +// (needed to ensure safety because of naive import list construction.) +var _ = thrift.ZERO +var _ = fmt.Printf +var _ = bytes.Equal + +func init() { +} diff --git a/vendor/github.com/uber/jaeger-client-go/thrift-gen/sampling/samplingmanager.go b/vendor/github.com/uber/jaeger-client-go/thrift-gen/sampling/samplingmanager.go new file mode 100644 index 0000000000..33179cfeb3 --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/thrift-gen/sampling/samplingmanager.go @@ -0,0 +1,410 @@ +// Autogenerated by Thrift Compiler (0.9.3) +// DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + +package sampling + +import ( + "bytes" + "fmt" + "github.com/uber/jaeger-client-go/thrift" +) + +// (needed to ensure safety because of naive import list construction.) +var _ = thrift.ZERO +var _ = fmt.Printf +var _ = bytes.Equal + +type SamplingManager interface { + // Parameters: + // - ServiceName + GetSamplingStrategy(serviceName string) (r *SamplingStrategyResponse, err error) +} + +type SamplingManagerClient struct { + Transport thrift.TTransport + ProtocolFactory thrift.TProtocolFactory + InputProtocol thrift.TProtocol + OutputProtocol thrift.TProtocol + SeqId int32 +} + +func NewSamplingManagerClientFactory(t thrift.TTransport, f thrift.TProtocolFactory) *SamplingManagerClient { + return &SamplingManagerClient{Transport: t, + ProtocolFactory: f, + InputProtocol: f.GetProtocol(t), + OutputProtocol: f.GetProtocol(t), + SeqId: 0, + } +} + +func NewSamplingManagerClientProtocol(t thrift.TTransport, iprot thrift.TProtocol, oprot thrift.TProtocol) *SamplingManagerClient { + return &SamplingManagerClient{Transport: t, + ProtocolFactory: nil, + InputProtocol: iprot, + OutputProtocol: oprot, + SeqId: 0, + } +} + +// Parameters: +// - ServiceName +func (p *SamplingManagerClient) GetSamplingStrategy(serviceName string) (r *SamplingStrategyResponse, err error) { + if err = p.sendGetSamplingStrategy(serviceName); err != nil { + return + } + return p.recvGetSamplingStrategy() +} + +func (p *SamplingManagerClient) sendGetSamplingStrategy(serviceName string) (err error) { + oprot := p.OutputProtocol + if oprot == nil { + oprot = p.ProtocolFactory.GetProtocol(p.Transport) + p.OutputProtocol = oprot + } + p.SeqId++ + if err = oprot.WriteMessageBegin("getSamplingStrategy", thrift.CALL, p.SeqId); err != nil { + return + } + args := SamplingManagerGetSamplingStrategyArgs{ + ServiceName: serviceName, + } + if err = args.Write(oprot); err != nil { + return + } + if err = oprot.WriteMessageEnd(); err != nil { + return + } + return oprot.Flush() +} + +func (p *SamplingManagerClient) recvGetSamplingStrategy() (value *SamplingStrategyResponse, err error) { + iprot := p.InputProtocol + if iprot == nil { + iprot = p.ProtocolFactory.GetProtocol(p.Transport) + p.InputProtocol = iprot + } + method, mTypeId, seqId, err := iprot.ReadMessageBegin() + if err != nil { + return + } + if method != "getSamplingStrategy" { + err = thrift.NewTApplicationException(thrift.WRONG_METHOD_NAME, "getSamplingStrategy failed: wrong method name") + return + } + if p.SeqId != seqId { + err = thrift.NewTApplicationException(thrift.BAD_SEQUENCE_ID, "getSamplingStrategy failed: out of sequence response") + return + } + if mTypeId == thrift.EXCEPTION { + error1 := thrift.NewTApplicationException(thrift.UNKNOWN_APPLICATION_EXCEPTION, "Unknown Exception") + var error2 error + error2, err = error1.Read(iprot) + if err != nil { + return + } + if err = iprot.ReadMessageEnd(); err != nil { + return + } + err = error2 + return + } + if mTypeId != thrift.REPLY { + err = thrift.NewTApplicationException(thrift.INVALID_MESSAGE_TYPE_EXCEPTION, "getSamplingStrategy failed: invalid message type") + return + } + result := SamplingManagerGetSamplingStrategyResult{} + if err = result.Read(iprot); err != nil { + return + } + if err = iprot.ReadMessageEnd(); err != nil { + return + } + value = result.GetSuccess() + return +} + +type SamplingManagerProcessor struct { + processorMap map[string]thrift.TProcessorFunction + handler SamplingManager +} + +func (p *SamplingManagerProcessor) AddToProcessorMap(key string, processor thrift.TProcessorFunction) { + p.processorMap[key] = processor +} + +func (p *SamplingManagerProcessor) GetProcessorFunction(key string) (processor thrift.TProcessorFunction, ok bool) { + processor, ok = p.processorMap[key] + return processor, ok +} + +func (p *SamplingManagerProcessor) ProcessorMap() map[string]thrift.TProcessorFunction { + return p.processorMap +} + +func NewSamplingManagerProcessor(handler SamplingManager) *SamplingManagerProcessor { + + self3 := &SamplingManagerProcessor{handler: handler, processorMap: make(map[string]thrift.TProcessorFunction)} + self3.processorMap["getSamplingStrategy"] = &samplingManagerProcessorGetSamplingStrategy{handler: handler} + return self3 +} + +func (p *SamplingManagerProcessor) Process(iprot, oprot thrift.TProtocol) (success bool, err thrift.TException) { + name, _, seqId, err := iprot.ReadMessageBegin() + if err != nil { + return false, err + } + if processor, ok := p.GetProcessorFunction(name); ok { + return processor.Process(seqId, iprot, oprot) + } + iprot.Skip(thrift.STRUCT) + iprot.ReadMessageEnd() + x4 := thrift.NewTApplicationException(thrift.UNKNOWN_METHOD, "Unknown function "+name) + oprot.WriteMessageBegin(name, thrift.EXCEPTION, seqId) + x4.Write(oprot) + oprot.WriteMessageEnd() + oprot.Flush() + return false, x4 + +} + +type samplingManagerProcessorGetSamplingStrategy struct { + handler SamplingManager +} + +func (p *samplingManagerProcessorGetSamplingStrategy) Process(seqId int32, iprot, oprot thrift.TProtocol) (success bool, err thrift.TException) { + args := SamplingManagerGetSamplingStrategyArgs{} + if err = args.Read(iprot); err != nil { + iprot.ReadMessageEnd() + x := thrift.NewTApplicationException(thrift.PROTOCOL_ERROR, err.Error()) + oprot.WriteMessageBegin("getSamplingStrategy", thrift.EXCEPTION, seqId) + x.Write(oprot) + oprot.WriteMessageEnd() + oprot.Flush() + return false, err + } + + iprot.ReadMessageEnd() + result := SamplingManagerGetSamplingStrategyResult{} + var retval *SamplingStrategyResponse + var err2 error + if retval, err2 = p.handler.GetSamplingStrategy(args.ServiceName); err2 != nil { + x := thrift.NewTApplicationException(thrift.INTERNAL_ERROR, "Internal error processing getSamplingStrategy: "+err2.Error()) + oprot.WriteMessageBegin("getSamplingStrategy", thrift.EXCEPTION, seqId) + x.Write(oprot) + oprot.WriteMessageEnd() + oprot.Flush() + return true, err2 + } else { + result.Success = retval + } + if err2 = oprot.WriteMessageBegin("getSamplingStrategy", thrift.REPLY, seqId); err2 != nil { + err = err2 + } + if err2 = result.Write(oprot); err == nil && err2 != nil { + err = err2 + } + if err2 = oprot.WriteMessageEnd(); err == nil && err2 != nil { + err = err2 + } + if err2 = oprot.Flush(); err == nil && err2 != nil { + err = err2 + } + if err != nil { + return + } + return true, err +} + +// HELPER FUNCTIONS AND STRUCTURES + +// Attributes: +// - ServiceName +type SamplingManagerGetSamplingStrategyArgs struct { + ServiceName string `thrift:"serviceName,1" json:"serviceName"` +} + +func NewSamplingManagerGetSamplingStrategyArgs() *SamplingManagerGetSamplingStrategyArgs { + return &SamplingManagerGetSamplingStrategyArgs{} +} + +func (p *SamplingManagerGetSamplingStrategyArgs) GetServiceName() string { + return p.ServiceName +} +func (p *SamplingManagerGetSamplingStrategyArgs) Read(iprot thrift.TProtocol) error { + if _, err := iprot.ReadStructBegin(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T read error: ", p), err) + } + + for { + _, fieldTypeId, fieldId, err := iprot.ReadFieldBegin() + if err != nil { + return thrift.PrependError(fmt.Sprintf("%T field %d read error: ", p, fieldId), err) + } + if fieldTypeId == thrift.STOP { + break + } + switch fieldId { + case 1: + if err := p.readField1(iprot); err != nil { + return err + } + default: + if err := iprot.Skip(fieldTypeId); err != nil { + return err + } + } + if err := iprot.ReadFieldEnd(); err != nil { + return err + } + } + if err := iprot.ReadStructEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) + } + return nil +} + +func (p *SamplingManagerGetSamplingStrategyArgs) readField1(iprot thrift.TProtocol) error { + if v, err := iprot.ReadString(); err != nil { + return thrift.PrependError("error reading field 1: ", err) + } else { + p.ServiceName = v + } + return nil +} + +func (p *SamplingManagerGetSamplingStrategyArgs) Write(oprot thrift.TProtocol) error { + if err := oprot.WriteStructBegin("getSamplingStrategy_args"); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) + } + if err := p.writeField1(oprot); err != nil { + return err + } + if err := oprot.WriteFieldStop(); err != nil { + return thrift.PrependError("write field stop error: ", err) + } + if err := oprot.WriteStructEnd(); err != nil { + return thrift.PrependError("write struct stop error: ", err) + } + return nil +} + +func (p *SamplingManagerGetSamplingStrategyArgs) writeField1(oprot thrift.TProtocol) (err error) { + if err := oprot.WriteFieldBegin("serviceName", thrift.STRING, 1); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 1:serviceName: ", p), err) + } + if err := oprot.WriteString(string(p.ServiceName)); err != nil { + return thrift.PrependError(fmt.Sprintf("%T.serviceName (1) field write error: ", p), err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 1:serviceName: ", p), err) + } + return err +} + +func (p *SamplingManagerGetSamplingStrategyArgs) String() string { + if p == nil { + return "" + } + return fmt.Sprintf("SamplingManagerGetSamplingStrategyArgs(%+v)", *p) +} + +// Attributes: +// - Success +type SamplingManagerGetSamplingStrategyResult struct { + Success *SamplingStrategyResponse `thrift:"success,0" json:"success,omitempty"` +} + +func NewSamplingManagerGetSamplingStrategyResult() *SamplingManagerGetSamplingStrategyResult { + return &SamplingManagerGetSamplingStrategyResult{} +} + +var SamplingManagerGetSamplingStrategyResult_Success_DEFAULT *SamplingStrategyResponse + +func (p *SamplingManagerGetSamplingStrategyResult) GetSuccess() *SamplingStrategyResponse { + if !p.IsSetSuccess() { + return SamplingManagerGetSamplingStrategyResult_Success_DEFAULT + } + return p.Success +} +func (p *SamplingManagerGetSamplingStrategyResult) IsSetSuccess() bool { + return p.Success != nil +} + +func (p *SamplingManagerGetSamplingStrategyResult) Read(iprot thrift.TProtocol) error { + if _, err := iprot.ReadStructBegin(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T read error: ", p), err) + } + + for { + _, fieldTypeId, fieldId, err := iprot.ReadFieldBegin() + if err != nil { + return thrift.PrependError(fmt.Sprintf("%T field %d read error: ", p, fieldId), err) + } + if fieldTypeId == thrift.STOP { + break + } + switch fieldId { + case 0: + if err := p.readField0(iprot); err != nil { + return err + } + default: + if err := iprot.Skip(fieldTypeId); err != nil { + return err + } + } + if err := iprot.ReadFieldEnd(); err != nil { + return err + } + } + if err := iprot.ReadStructEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) + } + return nil +} + +func (p *SamplingManagerGetSamplingStrategyResult) readField0(iprot thrift.TProtocol) error { + p.Success = &SamplingStrategyResponse{} + if err := p.Success.Read(iprot); err != nil { + return thrift.PrependError(fmt.Sprintf("%T error reading struct: ", p.Success), err) + } + return nil +} + +func (p *SamplingManagerGetSamplingStrategyResult) Write(oprot thrift.TProtocol) error { + if err := oprot.WriteStructBegin("getSamplingStrategy_result"); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) + } + if err := p.writeField0(oprot); err != nil { + return err + } + if err := oprot.WriteFieldStop(); err != nil { + return thrift.PrependError("write field stop error: ", err) + } + if err := oprot.WriteStructEnd(); err != nil { + return thrift.PrependError("write struct stop error: ", err) + } + return nil +} + +func (p *SamplingManagerGetSamplingStrategyResult) writeField0(oprot thrift.TProtocol) (err error) { + if p.IsSetSuccess() { + if err := oprot.WriteFieldBegin("success", thrift.STRUCT, 0); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 0:success: ", p), err) + } + if err := p.Success.Write(oprot); err != nil { + return thrift.PrependError(fmt.Sprintf("%T error writing struct: ", p.Success), err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 0:success: ", p), err) + } + } + return err +} + +func (p *SamplingManagerGetSamplingStrategyResult) String() string { + if p == nil { + return "" + } + return fmt.Sprintf("SamplingManagerGetSamplingStrategyResult(%+v)", *p) +} diff --git a/vendor/github.com/uber/jaeger-client-go/thrift-gen/sampling/ttypes.go b/vendor/github.com/uber/jaeger-client-go/thrift-gen/sampling/ttypes.go new file mode 100644 index 0000000000..9abaf0542d --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/thrift-gen/sampling/ttypes.go @@ -0,0 +1,873 @@ +// Autogenerated by Thrift Compiler (0.9.3) +// DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + +package sampling + +import ( + "bytes" + "fmt" + "github.com/uber/jaeger-client-go/thrift" +) + +// (needed to ensure safety because of naive import list construction.) +var _ = thrift.ZERO +var _ = fmt.Printf +var _ = bytes.Equal + +var GoUnusedProtection__ int + +type SamplingStrategyType int64 + +const ( + SamplingStrategyType_PROBABILISTIC SamplingStrategyType = 0 + SamplingStrategyType_RATE_LIMITING SamplingStrategyType = 1 +) + +func (p SamplingStrategyType) String() string { + switch p { + case SamplingStrategyType_PROBABILISTIC: + return "PROBABILISTIC" + case SamplingStrategyType_RATE_LIMITING: + return "RATE_LIMITING" + } + return "" +} + +func SamplingStrategyTypeFromString(s string) (SamplingStrategyType, error) { + switch s { + case "PROBABILISTIC": + return SamplingStrategyType_PROBABILISTIC, nil + case "RATE_LIMITING": + return SamplingStrategyType_RATE_LIMITING, nil + } + return SamplingStrategyType(0), fmt.Errorf("not a valid SamplingStrategyType string") +} + +func SamplingStrategyTypePtr(v SamplingStrategyType) *SamplingStrategyType { return &v } + +func (p SamplingStrategyType) MarshalText() ([]byte, error) { + return []byte(p.String()), nil +} + +func (p *SamplingStrategyType) UnmarshalText(text []byte) error { + q, err := SamplingStrategyTypeFromString(string(text)) + if err != nil { + return err + } + *p = q + return nil +} + +// Attributes: +// - SamplingRate +type ProbabilisticSamplingStrategy struct { + SamplingRate float64 `thrift:"samplingRate,1,required" json:"samplingRate"` +} + +func NewProbabilisticSamplingStrategy() *ProbabilisticSamplingStrategy { + return &ProbabilisticSamplingStrategy{} +} + +func (p *ProbabilisticSamplingStrategy) GetSamplingRate() float64 { + return p.SamplingRate +} +func (p *ProbabilisticSamplingStrategy) Read(iprot thrift.TProtocol) error { + if _, err := iprot.ReadStructBegin(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T read error: ", p), err) + } + + var issetSamplingRate bool = false + + for { + _, fieldTypeId, fieldId, err := iprot.ReadFieldBegin() + if err != nil { + return thrift.PrependError(fmt.Sprintf("%T field %d read error: ", p, fieldId), err) + } + if fieldTypeId == thrift.STOP { + break + } + switch fieldId { + case 1: + if err := p.readField1(iprot); err != nil { + return err + } + issetSamplingRate = true + default: + if err := iprot.Skip(fieldTypeId); err != nil { + return err + } + } + if err := iprot.ReadFieldEnd(); err != nil { + return err + } + } + if err := iprot.ReadStructEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) + } + if !issetSamplingRate { + return thrift.NewTProtocolExceptionWithType(thrift.INVALID_DATA, fmt.Errorf("Required field SamplingRate is not set")) + } + return nil +} + +func (p *ProbabilisticSamplingStrategy) readField1(iprot thrift.TProtocol) error { + if v, err := iprot.ReadDouble(); err != nil { + return thrift.PrependError("error reading field 1: ", err) + } else { + p.SamplingRate = v + } + return nil +} + +func (p *ProbabilisticSamplingStrategy) Write(oprot thrift.TProtocol) error { + if err := oprot.WriteStructBegin("ProbabilisticSamplingStrategy"); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) + } + if err := p.writeField1(oprot); err != nil { + return err + } + if err := oprot.WriteFieldStop(); err != nil { + return thrift.PrependError("write field stop error: ", err) + } + if err := oprot.WriteStructEnd(); err != nil { + return thrift.PrependError("write struct stop error: ", err) + } + return nil +} + +func (p *ProbabilisticSamplingStrategy) writeField1(oprot thrift.TProtocol) (err error) { + if err := oprot.WriteFieldBegin("samplingRate", thrift.DOUBLE, 1); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 1:samplingRate: ", p), err) + } + if err := oprot.WriteDouble(float64(p.SamplingRate)); err != nil { + return thrift.PrependError(fmt.Sprintf("%T.samplingRate (1) field write error: ", p), err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 1:samplingRate: ", p), err) + } + return err +} + +func (p *ProbabilisticSamplingStrategy) String() string { + if p == nil { + return "" + } + return fmt.Sprintf("ProbabilisticSamplingStrategy(%+v)", *p) +} + +// Attributes: +// - MaxTracesPerSecond +type RateLimitingSamplingStrategy struct { + MaxTracesPerSecond int16 `thrift:"maxTracesPerSecond,1,required" json:"maxTracesPerSecond"` +} + +func NewRateLimitingSamplingStrategy() *RateLimitingSamplingStrategy { + return &RateLimitingSamplingStrategy{} +} + +func (p *RateLimitingSamplingStrategy) GetMaxTracesPerSecond() int16 { + return p.MaxTracesPerSecond +} +func (p *RateLimitingSamplingStrategy) Read(iprot thrift.TProtocol) error { + if _, err := iprot.ReadStructBegin(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T read error: ", p), err) + } + + var issetMaxTracesPerSecond bool = false + + for { + _, fieldTypeId, fieldId, err := iprot.ReadFieldBegin() + if err != nil { + return thrift.PrependError(fmt.Sprintf("%T field %d read error: ", p, fieldId), err) + } + if fieldTypeId == thrift.STOP { + break + } + switch fieldId { + case 1: + if err := p.readField1(iprot); err != nil { + return err + } + issetMaxTracesPerSecond = true + default: + if err := iprot.Skip(fieldTypeId); err != nil { + return err + } + } + if err := iprot.ReadFieldEnd(); err != nil { + return err + } + } + if err := iprot.ReadStructEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) + } + if !issetMaxTracesPerSecond { + return thrift.NewTProtocolExceptionWithType(thrift.INVALID_DATA, fmt.Errorf("Required field MaxTracesPerSecond is not set")) + } + return nil +} + +func (p *RateLimitingSamplingStrategy) readField1(iprot thrift.TProtocol) error { + if v, err := iprot.ReadI16(); err != nil { + return thrift.PrependError("error reading field 1: ", err) + } else { + p.MaxTracesPerSecond = v + } + return nil +} + +func (p *RateLimitingSamplingStrategy) Write(oprot thrift.TProtocol) error { + if err := oprot.WriteStructBegin("RateLimitingSamplingStrategy"); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) + } + if err := p.writeField1(oprot); err != nil { + return err + } + if err := oprot.WriteFieldStop(); err != nil { + return thrift.PrependError("write field stop error: ", err) + } + if err := oprot.WriteStructEnd(); err != nil { + return thrift.PrependError("write struct stop error: ", err) + } + return nil +} + +func (p *RateLimitingSamplingStrategy) writeField1(oprot thrift.TProtocol) (err error) { + if err := oprot.WriteFieldBegin("maxTracesPerSecond", thrift.I16, 1); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 1:maxTracesPerSecond: ", p), err) + } + if err := oprot.WriteI16(int16(p.MaxTracesPerSecond)); err != nil { + return thrift.PrependError(fmt.Sprintf("%T.maxTracesPerSecond (1) field write error: ", p), err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 1:maxTracesPerSecond: ", p), err) + } + return err +} + +func (p *RateLimitingSamplingStrategy) String() string { + if p == nil { + return "" + } + return fmt.Sprintf("RateLimitingSamplingStrategy(%+v)", *p) +} + +// Attributes: +// - Operation +// - ProbabilisticSampling +type OperationSamplingStrategy struct { + Operation string `thrift:"operation,1,required" json:"operation"` + ProbabilisticSampling *ProbabilisticSamplingStrategy `thrift:"probabilisticSampling,2,required" json:"probabilisticSampling"` +} + +func NewOperationSamplingStrategy() *OperationSamplingStrategy { + return &OperationSamplingStrategy{} +} + +func (p *OperationSamplingStrategy) GetOperation() string { + return p.Operation +} + +var OperationSamplingStrategy_ProbabilisticSampling_DEFAULT *ProbabilisticSamplingStrategy + +func (p *OperationSamplingStrategy) GetProbabilisticSampling() *ProbabilisticSamplingStrategy { + if !p.IsSetProbabilisticSampling() { + return OperationSamplingStrategy_ProbabilisticSampling_DEFAULT + } + return p.ProbabilisticSampling +} +func (p *OperationSamplingStrategy) IsSetProbabilisticSampling() bool { + return p.ProbabilisticSampling != nil +} + +func (p *OperationSamplingStrategy) Read(iprot thrift.TProtocol) error { + if _, err := iprot.ReadStructBegin(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T read error: ", p), err) + } + + var issetOperation bool = false + var issetProbabilisticSampling bool = false + + for { + _, fieldTypeId, fieldId, err := iprot.ReadFieldBegin() + if err != nil { + return thrift.PrependError(fmt.Sprintf("%T field %d read error: ", p, fieldId), err) + } + if fieldTypeId == thrift.STOP { + break + } + switch fieldId { + case 1: + if err := p.readField1(iprot); err != nil { + return err + } + issetOperation = true + case 2: + if err := p.readField2(iprot); err != nil { + return err + } + issetProbabilisticSampling = true + default: + if err := iprot.Skip(fieldTypeId); err != nil { + return err + } + } + if err := iprot.ReadFieldEnd(); err != nil { + return err + } + } + if err := iprot.ReadStructEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) + } + if !issetOperation { + return thrift.NewTProtocolExceptionWithType(thrift.INVALID_DATA, fmt.Errorf("Required field Operation is not set")) + } + if !issetProbabilisticSampling { + return thrift.NewTProtocolExceptionWithType(thrift.INVALID_DATA, fmt.Errorf("Required field ProbabilisticSampling is not set")) + } + return nil +} + +func (p *OperationSamplingStrategy) readField1(iprot thrift.TProtocol) error { + if v, err := iprot.ReadString(); err != nil { + return thrift.PrependError("error reading field 1: ", err) + } else { + p.Operation = v + } + return nil +} + +func (p *OperationSamplingStrategy) readField2(iprot thrift.TProtocol) error { + p.ProbabilisticSampling = &ProbabilisticSamplingStrategy{} + if err := p.ProbabilisticSampling.Read(iprot); err != nil { + return thrift.PrependError(fmt.Sprintf("%T error reading struct: ", p.ProbabilisticSampling), err) + } + return nil +} + +func (p *OperationSamplingStrategy) Write(oprot thrift.TProtocol) error { + if err := oprot.WriteStructBegin("OperationSamplingStrategy"); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) + } + if err := p.writeField1(oprot); err != nil { + return err + } + if err := p.writeField2(oprot); err != nil { + return err + } + if err := oprot.WriteFieldStop(); err != nil { + return thrift.PrependError("write field stop error: ", err) + } + if err := oprot.WriteStructEnd(); err != nil { + return thrift.PrependError("write struct stop error: ", err) + } + return nil +} + +func (p *OperationSamplingStrategy) writeField1(oprot thrift.TProtocol) (err error) { + if err := oprot.WriteFieldBegin("operation", thrift.STRING, 1); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 1:operation: ", p), err) + } + if err := oprot.WriteString(string(p.Operation)); err != nil { + return thrift.PrependError(fmt.Sprintf("%T.operation (1) field write error: ", p), err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 1:operation: ", p), err) + } + return err +} + +func (p *OperationSamplingStrategy) writeField2(oprot thrift.TProtocol) (err error) { + if err := oprot.WriteFieldBegin("probabilisticSampling", thrift.STRUCT, 2); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 2:probabilisticSampling: ", p), err) + } + if err := p.ProbabilisticSampling.Write(oprot); err != nil { + return thrift.PrependError(fmt.Sprintf("%T error writing struct: ", p.ProbabilisticSampling), err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 2:probabilisticSampling: ", p), err) + } + return err +} + +func (p *OperationSamplingStrategy) String() string { + if p == nil { + return "" + } + return fmt.Sprintf("OperationSamplingStrategy(%+v)", *p) +} + +// Attributes: +// - DefaultSamplingProbability +// - DefaultLowerBoundTracesPerSecond +// - PerOperationStrategies +// - DefaultUpperBoundTracesPerSecond +type PerOperationSamplingStrategies struct { + DefaultSamplingProbability float64 `thrift:"defaultSamplingProbability,1,required" json:"defaultSamplingProbability"` + DefaultLowerBoundTracesPerSecond float64 `thrift:"defaultLowerBoundTracesPerSecond,2,required" json:"defaultLowerBoundTracesPerSecond"` + PerOperationStrategies []*OperationSamplingStrategy `thrift:"perOperationStrategies,3,required" json:"perOperationStrategies"` + DefaultUpperBoundTracesPerSecond *float64 `thrift:"defaultUpperBoundTracesPerSecond,4" json:"defaultUpperBoundTracesPerSecond,omitempty"` +} + +func NewPerOperationSamplingStrategies() *PerOperationSamplingStrategies { + return &PerOperationSamplingStrategies{} +} + +func (p *PerOperationSamplingStrategies) GetDefaultSamplingProbability() float64 { + return p.DefaultSamplingProbability +} + +func (p *PerOperationSamplingStrategies) GetDefaultLowerBoundTracesPerSecond() float64 { + return p.DefaultLowerBoundTracesPerSecond +} + +func (p *PerOperationSamplingStrategies) GetPerOperationStrategies() []*OperationSamplingStrategy { + return p.PerOperationStrategies +} + +var PerOperationSamplingStrategies_DefaultUpperBoundTracesPerSecond_DEFAULT float64 + +func (p *PerOperationSamplingStrategies) GetDefaultUpperBoundTracesPerSecond() float64 { + if !p.IsSetDefaultUpperBoundTracesPerSecond() { + return PerOperationSamplingStrategies_DefaultUpperBoundTracesPerSecond_DEFAULT + } + return *p.DefaultUpperBoundTracesPerSecond +} +func (p *PerOperationSamplingStrategies) IsSetDefaultUpperBoundTracesPerSecond() bool { + return p.DefaultUpperBoundTracesPerSecond != nil +} + +func (p *PerOperationSamplingStrategies) Read(iprot thrift.TProtocol) error { + if _, err := iprot.ReadStructBegin(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T read error: ", p), err) + } + + var issetDefaultSamplingProbability bool = false + var issetDefaultLowerBoundTracesPerSecond bool = false + var issetPerOperationStrategies bool = false + + for { + _, fieldTypeId, fieldId, err := iprot.ReadFieldBegin() + if err != nil { + return thrift.PrependError(fmt.Sprintf("%T field %d read error: ", p, fieldId), err) + } + if fieldTypeId == thrift.STOP { + break + } + switch fieldId { + case 1: + if err := p.readField1(iprot); err != nil { + return err + } + issetDefaultSamplingProbability = true + case 2: + if err := p.readField2(iprot); err != nil { + return err + } + issetDefaultLowerBoundTracesPerSecond = true + case 3: + if err := p.readField3(iprot); err != nil { + return err + } + issetPerOperationStrategies = true + case 4: + if err := p.readField4(iprot); err != nil { + return err + } + default: + if err := iprot.Skip(fieldTypeId); err != nil { + return err + } + } + if err := iprot.ReadFieldEnd(); err != nil { + return err + } + } + if err := iprot.ReadStructEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) + } + if !issetDefaultSamplingProbability { + return thrift.NewTProtocolExceptionWithType(thrift.INVALID_DATA, fmt.Errorf("Required field DefaultSamplingProbability is not set")) + } + if !issetDefaultLowerBoundTracesPerSecond { + return thrift.NewTProtocolExceptionWithType(thrift.INVALID_DATA, fmt.Errorf("Required field DefaultLowerBoundTracesPerSecond is not set")) + } + if !issetPerOperationStrategies { + return thrift.NewTProtocolExceptionWithType(thrift.INVALID_DATA, fmt.Errorf("Required field PerOperationStrategies is not set")) + } + return nil +} + +func (p *PerOperationSamplingStrategies) readField1(iprot thrift.TProtocol) error { + if v, err := iprot.ReadDouble(); err != nil { + return thrift.PrependError("error reading field 1: ", err) + } else { + p.DefaultSamplingProbability = v + } + return nil +} + +func (p *PerOperationSamplingStrategies) readField2(iprot thrift.TProtocol) error { + if v, err := iprot.ReadDouble(); err != nil { + return thrift.PrependError("error reading field 2: ", err) + } else { + p.DefaultLowerBoundTracesPerSecond = v + } + return nil +} + +func (p *PerOperationSamplingStrategies) readField3(iprot thrift.TProtocol) error { + _, size, err := iprot.ReadListBegin() + if err != nil { + return thrift.PrependError("error reading list begin: ", err) + } + tSlice := make([]*OperationSamplingStrategy, 0, size) + p.PerOperationStrategies = tSlice + for i := 0; i < size; i++ { + _elem0 := &OperationSamplingStrategy{} + if err := _elem0.Read(iprot); err != nil { + return thrift.PrependError(fmt.Sprintf("%T error reading struct: ", _elem0), err) + } + p.PerOperationStrategies = append(p.PerOperationStrategies, _elem0) + } + if err := iprot.ReadListEnd(); err != nil { + return thrift.PrependError("error reading list end: ", err) + } + return nil +} + +func (p *PerOperationSamplingStrategies) readField4(iprot thrift.TProtocol) error { + if v, err := iprot.ReadDouble(); err != nil { + return thrift.PrependError("error reading field 4: ", err) + } else { + p.DefaultUpperBoundTracesPerSecond = &v + } + return nil +} + +func (p *PerOperationSamplingStrategies) Write(oprot thrift.TProtocol) error { + if err := oprot.WriteStructBegin("PerOperationSamplingStrategies"); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) + } + if err := p.writeField1(oprot); err != nil { + return err + } + if err := p.writeField2(oprot); err != nil { + return err + } + if err := p.writeField3(oprot); err != nil { + return err + } + if err := p.writeField4(oprot); err != nil { + return err + } + if err := oprot.WriteFieldStop(); err != nil { + return thrift.PrependError("write field stop error: ", err) + } + if err := oprot.WriteStructEnd(); err != nil { + return thrift.PrependError("write struct stop error: ", err) + } + return nil +} + +func (p *PerOperationSamplingStrategies) writeField1(oprot thrift.TProtocol) (err error) { + if err := oprot.WriteFieldBegin("defaultSamplingProbability", thrift.DOUBLE, 1); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 1:defaultSamplingProbability: ", p), err) + } + if err := oprot.WriteDouble(float64(p.DefaultSamplingProbability)); err != nil { + return thrift.PrependError(fmt.Sprintf("%T.defaultSamplingProbability (1) field write error: ", p), err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 1:defaultSamplingProbability: ", p), err) + } + return err +} + +func (p *PerOperationSamplingStrategies) writeField2(oprot thrift.TProtocol) (err error) { + if err := oprot.WriteFieldBegin("defaultLowerBoundTracesPerSecond", thrift.DOUBLE, 2); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 2:defaultLowerBoundTracesPerSecond: ", p), err) + } + if err := oprot.WriteDouble(float64(p.DefaultLowerBoundTracesPerSecond)); err != nil { + return thrift.PrependError(fmt.Sprintf("%T.defaultLowerBoundTracesPerSecond (2) field write error: ", p), err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 2:defaultLowerBoundTracesPerSecond: ", p), err) + } + return err +} + +func (p *PerOperationSamplingStrategies) writeField3(oprot thrift.TProtocol) (err error) { + if err := oprot.WriteFieldBegin("perOperationStrategies", thrift.LIST, 3); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 3:perOperationStrategies: ", p), err) + } + if err := oprot.WriteListBegin(thrift.STRUCT, len(p.PerOperationStrategies)); err != nil { + return thrift.PrependError("error writing list begin: ", err) + } + for _, v := range p.PerOperationStrategies { + if err := v.Write(oprot); err != nil { + return thrift.PrependError(fmt.Sprintf("%T error writing struct: ", v), err) + } + } + if err := oprot.WriteListEnd(); err != nil { + return thrift.PrependError("error writing list end: ", err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 3:perOperationStrategies: ", p), err) + } + return err +} + +func (p *PerOperationSamplingStrategies) writeField4(oprot thrift.TProtocol) (err error) { + if p.IsSetDefaultUpperBoundTracesPerSecond() { + if err := oprot.WriteFieldBegin("defaultUpperBoundTracesPerSecond", thrift.DOUBLE, 4); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 4:defaultUpperBoundTracesPerSecond: ", p), err) + } + if err := oprot.WriteDouble(float64(*p.DefaultUpperBoundTracesPerSecond)); err != nil { + return thrift.PrependError(fmt.Sprintf("%T.defaultUpperBoundTracesPerSecond (4) field write error: ", p), err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 4:defaultUpperBoundTracesPerSecond: ", p), err) + } + } + return err +} + +func (p *PerOperationSamplingStrategies) String() string { + if p == nil { + return "" + } + return fmt.Sprintf("PerOperationSamplingStrategies(%+v)", *p) +} + +// Attributes: +// - StrategyType +// - ProbabilisticSampling +// - RateLimitingSampling +// - OperationSampling +type SamplingStrategyResponse struct { + StrategyType SamplingStrategyType `thrift:"strategyType,1,required" json:"strategyType"` + ProbabilisticSampling *ProbabilisticSamplingStrategy `thrift:"probabilisticSampling,2" json:"probabilisticSampling,omitempty"` + RateLimitingSampling *RateLimitingSamplingStrategy `thrift:"rateLimitingSampling,3" json:"rateLimitingSampling,omitempty"` + OperationSampling *PerOperationSamplingStrategies `thrift:"operationSampling,4" json:"operationSampling,omitempty"` +} + +func NewSamplingStrategyResponse() *SamplingStrategyResponse { + return &SamplingStrategyResponse{} +} + +func (p *SamplingStrategyResponse) GetStrategyType() SamplingStrategyType { + return p.StrategyType +} + +var SamplingStrategyResponse_ProbabilisticSampling_DEFAULT *ProbabilisticSamplingStrategy + +func (p *SamplingStrategyResponse) GetProbabilisticSampling() *ProbabilisticSamplingStrategy { + if !p.IsSetProbabilisticSampling() { + return SamplingStrategyResponse_ProbabilisticSampling_DEFAULT + } + return p.ProbabilisticSampling +} + +var SamplingStrategyResponse_RateLimitingSampling_DEFAULT *RateLimitingSamplingStrategy + +func (p *SamplingStrategyResponse) GetRateLimitingSampling() *RateLimitingSamplingStrategy { + if !p.IsSetRateLimitingSampling() { + return SamplingStrategyResponse_RateLimitingSampling_DEFAULT + } + return p.RateLimitingSampling +} + +var SamplingStrategyResponse_OperationSampling_DEFAULT *PerOperationSamplingStrategies + +func (p *SamplingStrategyResponse) GetOperationSampling() *PerOperationSamplingStrategies { + if !p.IsSetOperationSampling() { + return SamplingStrategyResponse_OperationSampling_DEFAULT + } + return p.OperationSampling +} +func (p *SamplingStrategyResponse) IsSetProbabilisticSampling() bool { + return p.ProbabilisticSampling != nil +} + +func (p *SamplingStrategyResponse) IsSetRateLimitingSampling() bool { + return p.RateLimitingSampling != nil +} + +func (p *SamplingStrategyResponse) IsSetOperationSampling() bool { + return p.OperationSampling != nil +} + +func (p *SamplingStrategyResponse) Read(iprot thrift.TProtocol) error { + if _, err := iprot.ReadStructBegin(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T read error: ", p), err) + } + + var issetStrategyType bool = false + + for { + _, fieldTypeId, fieldId, err := iprot.ReadFieldBegin() + if err != nil { + return thrift.PrependError(fmt.Sprintf("%T field %d read error: ", p, fieldId), err) + } + if fieldTypeId == thrift.STOP { + break + } + switch fieldId { + case 1: + if err := p.readField1(iprot); err != nil { + return err + } + issetStrategyType = true + case 2: + if err := p.readField2(iprot); err != nil { + return err + } + case 3: + if err := p.readField3(iprot); err != nil { + return err + } + case 4: + if err := p.readField4(iprot); err != nil { + return err + } + default: + if err := iprot.Skip(fieldTypeId); err != nil { + return err + } + } + if err := iprot.ReadFieldEnd(); err != nil { + return err + } + } + if err := iprot.ReadStructEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) + } + if !issetStrategyType { + return thrift.NewTProtocolExceptionWithType(thrift.INVALID_DATA, fmt.Errorf("Required field StrategyType is not set")) + } + return nil +} + +func (p *SamplingStrategyResponse) readField1(iprot thrift.TProtocol) error { + if v, err := iprot.ReadI32(); err != nil { + return thrift.PrependError("error reading field 1: ", err) + } else { + temp := SamplingStrategyType(v) + p.StrategyType = temp + } + return nil +} + +func (p *SamplingStrategyResponse) readField2(iprot thrift.TProtocol) error { + p.ProbabilisticSampling = &ProbabilisticSamplingStrategy{} + if err := p.ProbabilisticSampling.Read(iprot); err != nil { + return thrift.PrependError(fmt.Sprintf("%T error reading struct: ", p.ProbabilisticSampling), err) + } + return nil +} + +func (p *SamplingStrategyResponse) readField3(iprot thrift.TProtocol) error { + p.RateLimitingSampling = &RateLimitingSamplingStrategy{} + if err := p.RateLimitingSampling.Read(iprot); err != nil { + return thrift.PrependError(fmt.Sprintf("%T error reading struct: ", p.RateLimitingSampling), err) + } + return nil +} + +func (p *SamplingStrategyResponse) readField4(iprot thrift.TProtocol) error { + p.OperationSampling = &PerOperationSamplingStrategies{} + if err := p.OperationSampling.Read(iprot); err != nil { + return thrift.PrependError(fmt.Sprintf("%T error reading struct: ", p.OperationSampling), err) + } + return nil +} + +func (p *SamplingStrategyResponse) Write(oprot thrift.TProtocol) error { + if err := oprot.WriteStructBegin("SamplingStrategyResponse"); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) + } + if err := p.writeField1(oprot); err != nil { + return err + } + if err := p.writeField2(oprot); err != nil { + return err + } + if err := p.writeField3(oprot); err != nil { + return err + } + if err := p.writeField4(oprot); err != nil { + return err + } + if err := oprot.WriteFieldStop(); err != nil { + return thrift.PrependError("write field stop error: ", err) + } + if err := oprot.WriteStructEnd(); err != nil { + return thrift.PrependError("write struct stop error: ", err) + } + return nil +} + +func (p *SamplingStrategyResponse) writeField1(oprot thrift.TProtocol) (err error) { + if err := oprot.WriteFieldBegin("strategyType", thrift.I32, 1); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 1:strategyType: ", p), err) + } + if err := oprot.WriteI32(int32(p.StrategyType)); err != nil { + return thrift.PrependError(fmt.Sprintf("%T.strategyType (1) field write error: ", p), err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 1:strategyType: ", p), err) + } + return err +} + +func (p *SamplingStrategyResponse) writeField2(oprot thrift.TProtocol) (err error) { + if p.IsSetProbabilisticSampling() { + if err := oprot.WriteFieldBegin("probabilisticSampling", thrift.STRUCT, 2); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 2:probabilisticSampling: ", p), err) + } + if err := p.ProbabilisticSampling.Write(oprot); err != nil { + return thrift.PrependError(fmt.Sprintf("%T error writing struct: ", p.ProbabilisticSampling), err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 2:probabilisticSampling: ", p), err) + } + } + return err +} + +func (p *SamplingStrategyResponse) writeField3(oprot thrift.TProtocol) (err error) { + if p.IsSetRateLimitingSampling() { + if err := oprot.WriteFieldBegin("rateLimitingSampling", thrift.STRUCT, 3); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 3:rateLimitingSampling: ", p), err) + } + if err := p.RateLimitingSampling.Write(oprot); err != nil { + return thrift.PrependError(fmt.Sprintf("%T error writing struct: ", p.RateLimitingSampling), err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 3:rateLimitingSampling: ", p), err) + } + } + return err +} + +func (p *SamplingStrategyResponse) writeField4(oprot thrift.TProtocol) (err error) { + if p.IsSetOperationSampling() { + if err := oprot.WriteFieldBegin("operationSampling", thrift.STRUCT, 4); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 4:operationSampling: ", p), err) + } + if err := p.OperationSampling.Write(oprot); err != nil { + return thrift.PrependError(fmt.Sprintf("%T error writing struct: ", p.OperationSampling), err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 4:operationSampling: ", p), err) + } + } + return err +} + +func (p *SamplingStrategyResponse) String() string { + if p == nil { + return "" + } + return fmt.Sprintf("SamplingStrategyResponse(%+v)", *p) +} diff --git a/vendor/github.com/uber/jaeger-client-go/thrift-gen/zipkincore/constants.go b/vendor/github.com/uber/jaeger-client-go/thrift-gen/zipkincore/constants.go new file mode 100644 index 0000000000..f05144bfc6 --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/thrift-gen/zipkincore/constants.go @@ -0,0 +1,32 @@ +// Autogenerated by Thrift Compiler (0.9.3) +// DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + +package zipkincore + +import ( + "bytes" + "fmt" + "github.com/uber/jaeger-client-go/thrift" +) + +// (needed to ensure safety because of naive import list construction.) +var _ = thrift.ZERO +var _ = fmt.Printf +var _ = bytes.Equal + +const CLIENT_SEND = "cs" +const CLIENT_RECV = "cr" +const SERVER_SEND = "ss" +const SERVER_RECV = "sr" +const WIRE_SEND = "ws" +const WIRE_RECV = "wr" +const CLIENT_SEND_FRAGMENT = "csf" +const CLIENT_RECV_FRAGMENT = "crf" +const SERVER_SEND_FRAGMENT = "ssf" +const SERVER_RECV_FRAGMENT = "srf" +const LOCAL_COMPONENT = "lc" +const CLIENT_ADDR = "ca" +const SERVER_ADDR = "sa" + +func init() { +} diff --git a/vendor/github.com/uber/jaeger-client-go/thrift-gen/zipkincore/ttypes.go b/vendor/github.com/uber/jaeger-client-go/thrift-gen/zipkincore/ttypes.go new file mode 100644 index 0000000000..34b2b267eb --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/thrift-gen/zipkincore/ttypes.go @@ -0,0 +1,1247 @@ +// Autogenerated by Thrift Compiler (0.9.3) +// DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + +package zipkincore + +import ( + "bytes" + "fmt" + "github.com/uber/jaeger-client-go/thrift" +) + +// (needed to ensure safety because of naive import list construction.) +var _ = thrift.ZERO +var _ = fmt.Printf +var _ = bytes.Equal + +var GoUnusedProtection__ int + +type AnnotationType int64 + +const ( + AnnotationType_BOOL AnnotationType = 0 + AnnotationType_BYTES AnnotationType = 1 + AnnotationType_I16 AnnotationType = 2 + AnnotationType_I32 AnnotationType = 3 + AnnotationType_I64 AnnotationType = 4 + AnnotationType_DOUBLE AnnotationType = 5 + AnnotationType_STRING AnnotationType = 6 +) + +func (p AnnotationType) String() string { + switch p { + case AnnotationType_BOOL: + return "BOOL" + case AnnotationType_BYTES: + return "BYTES" + case AnnotationType_I16: + return "I16" + case AnnotationType_I32: + return "I32" + case AnnotationType_I64: + return "I64" + case AnnotationType_DOUBLE: + return "DOUBLE" + case AnnotationType_STRING: + return "STRING" + } + return "" +} + +func AnnotationTypeFromString(s string) (AnnotationType, error) { + switch s { + case "BOOL": + return AnnotationType_BOOL, nil + case "BYTES": + return AnnotationType_BYTES, nil + case "I16": + return AnnotationType_I16, nil + case "I32": + return AnnotationType_I32, nil + case "I64": + return AnnotationType_I64, nil + case "DOUBLE": + return AnnotationType_DOUBLE, nil + case "STRING": + return AnnotationType_STRING, nil + } + return AnnotationType(0), fmt.Errorf("not a valid AnnotationType string") +} + +func AnnotationTypePtr(v AnnotationType) *AnnotationType { return &v } + +func (p AnnotationType) MarshalText() ([]byte, error) { + return []byte(p.String()), nil +} + +func (p *AnnotationType) UnmarshalText(text []byte) error { + q, err := AnnotationTypeFromString(string(text)) + if err != nil { + return err + } + *p = q + return nil +} + +// Indicates the network context of a service recording an annotation with two +// exceptions. +// +// When a BinaryAnnotation, and key is CLIENT_ADDR or SERVER_ADDR, +// the endpoint indicates the source or destination of an RPC. This exception +// allows zipkin to display network context of uninstrumented services, or +// clients such as web browsers. +// +// Attributes: +// - Ipv4: IPv4 host address packed into 4 bytes. +// +// Ex for the ip 1.2.3.4, it would be (1 << 24) | (2 << 16) | (3 << 8) | 4 +// - Port: IPv4 port +// +// Note: this is to be treated as an unsigned integer, so watch for negatives. +// +// Conventionally, when the port isn't known, port = 0. +// - ServiceName: Service name in lowercase, such as "memcache" or "zipkin-web" +// +// Conventionally, when the service name isn't known, service_name = "unknown". +type Endpoint struct { + Ipv4 int32 `thrift:"ipv4,1" json:"ipv4"` + Port int16 `thrift:"port,2" json:"port"` + ServiceName string `thrift:"service_name,3" json:"service_name"` +} + +func NewEndpoint() *Endpoint { + return &Endpoint{} +} + +func (p *Endpoint) GetIpv4() int32 { + return p.Ipv4 +} + +func (p *Endpoint) GetPort() int16 { + return p.Port +} + +func (p *Endpoint) GetServiceName() string { + return p.ServiceName +} +func (p *Endpoint) Read(iprot thrift.TProtocol) error { + if _, err := iprot.ReadStructBegin(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T read error: ", p), err) + } + + for { + _, fieldTypeId, fieldId, err := iprot.ReadFieldBegin() + if err != nil { + return thrift.PrependError(fmt.Sprintf("%T field %d read error: ", p, fieldId), err) + } + if fieldTypeId == thrift.STOP { + break + } + switch fieldId { + case 1: + if err := p.readField1(iprot); err != nil { + return err + } + case 2: + if err := p.readField2(iprot); err != nil { + return err + } + case 3: + if err := p.readField3(iprot); err != nil { + return err + } + default: + if err := iprot.Skip(fieldTypeId); err != nil { + return err + } + } + if err := iprot.ReadFieldEnd(); err != nil { + return err + } + } + if err := iprot.ReadStructEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) + } + return nil +} + +func (p *Endpoint) readField1(iprot thrift.TProtocol) error { + if v, err := iprot.ReadI32(); err != nil { + return thrift.PrependError("error reading field 1: ", err) + } else { + p.Ipv4 = v + } + return nil +} + +func (p *Endpoint) readField2(iprot thrift.TProtocol) error { + if v, err := iprot.ReadI16(); err != nil { + return thrift.PrependError("error reading field 2: ", err) + } else { + p.Port = v + } + return nil +} + +func (p *Endpoint) readField3(iprot thrift.TProtocol) error { + if v, err := iprot.ReadString(); err != nil { + return thrift.PrependError("error reading field 3: ", err) + } else { + p.ServiceName = v + } + return nil +} + +func (p *Endpoint) Write(oprot thrift.TProtocol) error { + if err := oprot.WriteStructBegin("Endpoint"); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) + } + if err := p.writeField1(oprot); err != nil { + return err + } + if err := p.writeField2(oprot); err != nil { + return err + } + if err := p.writeField3(oprot); err != nil { + return err + } + if err := oprot.WriteFieldStop(); err != nil { + return thrift.PrependError("write field stop error: ", err) + } + if err := oprot.WriteStructEnd(); err != nil { + return thrift.PrependError("write struct stop error: ", err) + } + return nil +} + +func (p *Endpoint) writeField1(oprot thrift.TProtocol) (err error) { + if err := oprot.WriteFieldBegin("ipv4", thrift.I32, 1); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 1:ipv4: ", p), err) + } + if err := oprot.WriteI32(int32(p.Ipv4)); err != nil { + return thrift.PrependError(fmt.Sprintf("%T.ipv4 (1) field write error: ", p), err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 1:ipv4: ", p), err) + } + return err +} + +func (p *Endpoint) writeField2(oprot thrift.TProtocol) (err error) { + if err := oprot.WriteFieldBegin("port", thrift.I16, 2); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 2:port: ", p), err) + } + if err := oprot.WriteI16(int16(p.Port)); err != nil { + return thrift.PrependError(fmt.Sprintf("%T.port (2) field write error: ", p), err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 2:port: ", p), err) + } + return err +} + +func (p *Endpoint) writeField3(oprot thrift.TProtocol) (err error) { + if err := oprot.WriteFieldBegin("service_name", thrift.STRING, 3); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 3:service_name: ", p), err) + } + if err := oprot.WriteString(string(p.ServiceName)); err != nil { + return thrift.PrependError(fmt.Sprintf("%T.service_name (3) field write error: ", p), err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 3:service_name: ", p), err) + } + return err +} + +func (p *Endpoint) String() string { + if p == nil { + return "" + } + return fmt.Sprintf("Endpoint(%+v)", *p) +} + +// An annotation is similar to a log statement. It includes a host field which +// allows these events to be attributed properly, and also aggregatable. +// +// Attributes: +// - Timestamp: Microseconds from epoch. +// +// This value should use the most precise value possible. For example, +// gettimeofday or syncing nanoTime against a tick of currentTimeMillis. +// - Value +// - Host: Always the host that recorded the event. By specifying the host you allow +// rollup of all events (such as client requests to a service) by IP address. +type Annotation struct { + Timestamp int64 `thrift:"timestamp,1" json:"timestamp"` + Value string `thrift:"value,2" json:"value"` + Host *Endpoint `thrift:"host,3" json:"host,omitempty"` +} + +func NewAnnotation() *Annotation { + return &Annotation{} +} + +func (p *Annotation) GetTimestamp() int64 { + return p.Timestamp +} + +func (p *Annotation) GetValue() string { + return p.Value +} + +var Annotation_Host_DEFAULT *Endpoint + +func (p *Annotation) GetHost() *Endpoint { + if !p.IsSetHost() { + return Annotation_Host_DEFAULT + } + return p.Host +} +func (p *Annotation) IsSetHost() bool { + return p.Host != nil +} + +func (p *Annotation) Read(iprot thrift.TProtocol) error { + if _, err := iprot.ReadStructBegin(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T read error: ", p), err) + } + + for { + _, fieldTypeId, fieldId, err := iprot.ReadFieldBegin() + if err != nil { + return thrift.PrependError(fmt.Sprintf("%T field %d read error: ", p, fieldId), err) + } + if fieldTypeId == thrift.STOP { + break + } + switch fieldId { + case 1: + if err := p.readField1(iprot); err != nil { + return err + } + case 2: + if err := p.readField2(iprot); err != nil { + return err + } + case 3: + if err := p.readField3(iprot); err != nil { + return err + } + default: + if err := iprot.Skip(fieldTypeId); err != nil { + return err + } + } + if err := iprot.ReadFieldEnd(); err != nil { + return err + } + } + if err := iprot.ReadStructEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) + } + return nil +} + +func (p *Annotation) readField1(iprot thrift.TProtocol) error { + if v, err := iprot.ReadI64(); err != nil { + return thrift.PrependError("error reading field 1: ", err) + } else { + p.Timestamp = v + } + return nil +} + +func (p *Annotation) readField2(iprot thrift.TProtocol) error { + if v, err := iprot.ReadString(); err != nil { + return thrift.PrependError("error reading field 2: ", err) + } else { + p.Value = v + } + return nil +} + +func (p *Annotation) readField3(iprot thrift.TProtocol) error { + p.Host = &Endpoint{} + if err := p.Host.Read(iprot); err != nil { + return thrift.PrependError(fmt.Sprintf("%T error reading struct: ", p.Host), err) + } + return nil +} + +func (p *Annotation) Write(oprot thrift.TProtocol) error { + if err := oprot.WriteStructBegin("Annotation"); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) + } + if err := p.writeField1(oprot); err != nil { + return err + } + if err := p.writeField2(oprot); err != nil { + return err + } + if err := p.writeField3(oprot); err != nil { + return err + } + if err := oprot.WriteFieldStop(); err != nil { + return thrift.PrependError("write field stop error: ", err) + } + if err := oprot.WriteStructEnd(); err != nil { + return thrift.PrependError("write struct stop error: ", err) + } + return nil +} + +func (p *Annotation) writeField1(oprot thrift.TProtocol) (err error) { + if err := oprot.WriteFieldBegin("timestamp", thrift.I64, 1); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 1:timestamp: ", p), err) + } + if err := oprot.WriteI64(int64(p.Timestamp)); err != nil { + return thrift.PrependError(fmt.Sprintf("%T.timestamp (1) field write error: ", p), err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 1:timestamp: ", p), err) + } + return err +} + +func (p *Annotation) writeField2(oprot thrift.TProtocol) (err error) { + if err := oprot.WriteFieldBegin("value", thrift.STRING, 2); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 2:value: ", p), err) + } + if err := oprot.WriteString(string(p.Value)); err != nil { + return thrift.PrependError(fmt.Sprintf("%T.value (2) field write error: ", p), err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 2:value: ", p), err) + } + return err +} + +func (p *Annotation) writeField3(oprot thrift.TProtocol) (err error) { + if p.IsSetHost() { + if err := oprot.WriteFieldBegin("host", thrift.STRUCT, 3); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 3:host: ", p), err) + } + if err := p.Host.Write(oprot); err != nil { + return thrift.PrependError(fmt.Sprintf("%T error writing struct: ", p.Host), err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 3:host: ", p), err) + } + } + return err +} + +func (p *Annotation) String() string { + if p == nil { + return "" + } + return fmt.Sprintf("Annotation(%+v)", *p) +} + +// Binary annotations are tags applied to a Span to give it context. For +// example, a binary annotation of "http.uri" could the path to a resource in a +// RPC call. +// +// Binary annotations of type STRING are always queryable, though more a +// historical implementation detail than a structural concern. +// +// Binary annotations can repeat, and vary on the host. Similar to Annotation, +// the host indicates who logged the event. This allows you to tell the +// difference between the client and server side of the same key. For example, +// the key "http.uri" might be different on the client and server side due to +// rewriting, like "/api/v1/myresource" vs "/myresource. Via the host field, +// you can see the different points of view, which often help in debugging. +// +// Attributes: +// - Key +// - Value +// - AnnotationType +// - Host: The host that recorded tag, which allows you to differentiate between +// multiple tags with the same key. There are two exceptions to this. +// +// When the key is CLIENT_ADDR or SERVER_ADDR, host indicates the source or +// destination of an RPC. This exception allows zipkin to display network +// context of uninstrumented services, or clients such as web browsers. +type BinaryAnnotation struct { + Key string `thrift:"key,1" json:"key"` + Value []byte `thrift:"value,2" json:"value"` + AnnotationType AnnotationType `thrift:"annotation_type,3" json:"annotation_type"` + Host *Endpoint `thrift:"host,4" json:"host,omitempty"` +} + +func NewBinaryAnnotation() *BinaryAnnotation { + return &BinaryAnnotation{} +} + +func (p *BinaryAnnotation) GetKey() string { + return p.Key +} + +func (p *BinaryAnnotation) GetValue() []byte { + return p.Value +} + +func (p *BinaryAnnotation) GetAnnotationType() AnnotationType { + return p.AnnotationType +} + +var BinaryAnnotation_Host_DEFAULT *Endpoint + +func (p *BinaryAnnotation) GetHost() *Endpoint { + if !p.IsSetHost() { + return BinaryAnnotation_Host_DEFAULT + } + return p.Host +} +func (p *BinaryAnnotation) IsSetHost() bool { + return p.Host != nil +} + +func (p *BinaryAnnotation) Read(iprot thrift.TProtocol) error { + if _, err := iprot.ReadStructBegin(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T read error: ", p), err) + } + + for { + _, fieldTypeId, fieldId, err := iprot.ReadFieldBegin() + if err != nil { + return thrift.PrependError(fmt.Sprintf("%T field %d read error: ", p, fieldId), err) + } + if fieldTypeId == thrift.STOP { + break + } + switch fieldId { + case 1: + if err := p.readField1(iprot); err != nil { + return err + } + case 2: + if err := p.readField2(iprot); err != nil { + return err + } + case 3: + if err := p.readField3(iprot); err != nil { + return err + } + case 4: + if err := p.readField4(iprot); err != nil { + return err + } + default: + if err := iprot.Skip(fieldTypeId); err != nil { + return err + } + } + if err := iprot.ReadFieldEnd(); err != nil { + return err + } + } + if err := iprot.ReadStructEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) + } + return nil +} + +func (p *BinaryAnnotation) readField1(iprot thrift.TProtocol) error { + if v, err := iprot.ReadString(); err != nil { + return thrift.PrependError("error reading field 1: ", err) + } else { + p.Key = v + } + return nil +} + +func (p *BinaryAnnotation) readField2(iprot thrift.TProtocol) error { + if v, err := iprot.ReadBinary(); err != nil { + return thrift.PrependError("error reading field 2: ", err) + } else { + p.Value = v + } + return nil +} + +func (p *BinaryAnnotation) readField3(iprot thrift.TProtocol) error { + if v, err := iprot.ReadI32(); err != nil { + return thrift.PrependError("error reading field 3: ", err) + } else { + temp := AnnotationType(v) + p.AnnotationType = temp + } + return nil +} + +func (p *BinaryAnnotation) readField4(iprot thrift.TProtocol) error { + p.Host = &Endpoint{} + if err := p.Host.Read(iprot); err != nil { + return thrift.PrependError(fmt.Sprintf("%T error reading struct: ", p.Host), err) + } + return nil +} + +func (p *BinaryAnnotation) Write(oprot thrift.TProtocol) error { + if err := oprot.WriteStructBegin("BinaryAnnotation"); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) + } + if err := p.writeField1(oprot); err != nil { + return err + } + if err := p.writeField2(oprot); err != nil { + return err + } + if err := p.writeField3(oprot); err != nil { + return err + } + if err := p.writeField4(oprot); err != nil { + return err + } + if err := oprot.WriteFieldStop(); err != nil { + return thrift.PrependError("write field stop error: ", err) + } + if err := oprot.WriteStructEnd(); err != nil { + return thrift.PrependError("write struct stop error: ", err) + } + return nil +} + +func (p *BinaryAnnotation) writeField1(oprot thrift.TProtocol) (err error) { + if err := oprot.WriteFieldBegin("key", thrift.STRING, 1); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 1:key: ", p), err) + } + if err := oprot.WriteString(string(p.Key)); err != nil { + return thrift.PrependError(fmt.Sprintf("%T.key (1) field write error: ", p), err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 1:key: ", p), err) + } + return err +} + +func (p *BinaryAnnotation) writeField2(oprot thrift.TProtocol) (err error) { + if err := oprot.WriteFieldBegin("value", thrift.STRING, 2); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 2:value: ", p), err) + } + if err := oprot.WriteBinary(p.Value); err != nil { + return thrift.PrependError(fmt.Sprintf("%T.value (2) field write error: ", p), err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 2:value: ", p), err) + } + return err +} + +func (p *BinaryAnnotation) writeField3(oprot thrift.TProtocol) (err error) { + if err := oprot.WriteFieldBegin("annotation_type", thrift.I32, 3); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 3:annotation_type: ", p), err) + } + if err := oprot.WriteI32(int32(p.AnnotationType)); err != nil { + return thrift.PrependError(fmt.Sprintf("%T.annotation_type (3) field write error: ", p), err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 3:annotation_type: ", p), err) + } + return err +} + +func (p *BinaryAnnotation) writeField4(oprot thrift.TProtocol) (err error) { + if p.IsSetHost() { + if err := oprot.WriteFieldBegin("host", thrift.STRUCT, 4); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 4:host: ", p), err) + } + if err := p.Host.Write(oprot); err != nil { + return thrift.PrependError(fmt.Sprintf("%T error writing struct: ", p.Host), err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 4:host: ", p), err) + } + } + return err +} + +func (p *BinaryAnnotation) String() string { + if p == nil { + return "" + } + return fmt.Sprintf("BinaryAnnotation(%+v)", *p) +} + +// A trace is a series of spans (often RPC calls) which form a latency tree. +// +// The root span is where trace_id = id and parent_id = Nil. The root span is +// usually the longest interval in the trace, starting with a SERVER_RECV +// annotation and ending with a SERVER_SEND. +// +// Attributes: +// - TraceID +// - Name: Span name in lowercase, rpc method for example +// +// Conventionally, when the span name isn't known, name = "unknown". +// - ID +// - ParentID +// - Annotations +// - BinaryAnnotations +// - Debug +// - Timestamp: Microseconds from epoch of the creation of this span. +// +// This value should be set directly by instrumentation, using the most +// precise value possible. For example, gettimeofday or syncing nanoTime +// against a tick of currentTimeMillis. +// +// For compatibilty with instrumentation that precede this field, collectors +// or span stores can derive this via Annotation.timestamp. +// For example, SERVER_RECV.timestamp or CLIENT_SEND.timestamp. +// +// This field is optional for compatibility with old data: first-party span +// stores are expected to support this at time of introduction. +// - Duration: Measurement of duration in microseconds, used to support queries. +// +// This value should be set directly, where possible. Doing so encourages +// precise measurement decoupled from problems of clocks, such as skew or NTP +// updates causing time to move backwards. +// +// For compatibilty with instrumentation that precede this field, collectors +// or span stores can derive this by subtracting Annotation.timestamp. +// For example, SERVER_SEND.timestamp - SERVER_RECV.timestamp. +// +// If this field is persisted as unset, zipkin will continue to work, except +// duration query support will be implementation-specific. Similarly, setting +// this field non-atomically is implementation-specific. +// +// This field is i64 vs i32 to support spans longer than 35 minutes. +type Span struct { + TraceID int64 `thrift:"trace_id,1" json:"trace_id"` + // unused field # 2 + Name string `thrift:"name,3" json:"name"` + ID int64 `thrift:"id,4" json:"id"` + ParentID *int64 `thrift:"parent_id,5" json:"parent_id,omitempty"` + Annotations []*Annotation `thrift:"annotations,6" json:"annotations"` + // unused field # 7 + BinaryAnnotations []*BinaryAnnotation `thrift:"binary_annotations,8" json:"binary_annotations"` + Debug bool `thrift:"debug,9" json:"debug,omitempty"` + Timestamp *int64 `thrift:"timestamp,10" json:"timestamp,omitempty"` + Duration *int64 `thrift:"duration,11" json:"duration,omitempty"` +} + +func NewSpan() *Span { + return &Span{} +} + +func (p *Span) GetTraceID() int64 { + return p.TraceID +} + +func (p *Span) GetName() string { + return p.Name +} + +func (p *Span) GetID() int64 { + return p.ID +} + +var Span_ParentID_DEFAULT int64 + +func (p *Span) GetParentID() int64 { + if !p.IsSetParentID() { + return Span_ParentID_DEFAULT + } + return *p.ParentID +} + +func (p *Span) GetAnnotations() []*Annotation { + return p.Annotations +} + +func (p *Span) GetBinaryAnnotations() []*BinaryAnnotation { + return p.BinaryAnnotations +} + +var Span_Debug_DEFAULT bool = false + +func (p *Span) GetDebug() bool { + return p.Debug +} + +var Span_Timestamp_DEFAULT int64 + +func (p *Span) GetTimestamp() int64 { + if !p.IsSetTimestamp() { + return Span_Timestamp_DEFAULT + } + return *p.Timestamp +} + +var Span_Duration_DEFAULT int64 + +func (p *Span) GetDuration() int64 { + if !p.IsSetDuration() { + return Span_Duration_DEFAULT + } + return *p.Duration +} +func (p *Span) IsSetParentID() bool { + return p.ParentID != nil +} + +func (p *Span) IsSetDebug() bool { + return p.Debug != Span_Debug_DEFAULT +} + +func (p *Span) IsSetTimestamp() bool { + return p.Timestamp != nil +} + +func (p *Span) IsSetDuration() bool { + return p.Duration != nil +} + +func (p *Span) Read(iprot thrift.TProtocol) error { + if _, err := iprot.ReadStructBegin(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T read error: ", p), err) + } + + for { + _, fieldTypeId, fieldId, err := iprot.ReadFieldBegin() + if err != nil { + return thrift.PrependError(fmt.Sprintf("%T field %d read error: ", p, fieldId), err) + } + if fieldTypeId == thrift.STOP { + break + } + switch fieldId { + case 1: + if err := p.readField1(iprot); err != nil { + return err + } + case 3: + if err := p.readField3(iprot); err != nil { + return err + } + case 4: + if err := p.readField4(iprot); err != nil { + return err + } + case 5: + if err := p.readField5(iprot); err != nil { + return err + } + case 6: + if err := p.readField6(iprot); err != nil { + return err + } + case 8: + if err := p.readField8(iprot); err != nil { + return err + } + case 9: + if err := p.readField9(iprot); err != nil { + return err + } + case 10: + if err := p.readField10(iprot); err != nil { + return err + } + case 11: + if err := p.readField11(iprot); err != nil { + return err + } + default: + if err := iprot.Skip(fieldTypeId); err != nil { + return err + } + } + if err := iprot.ReadFieldEnd(); err != nil { + return err + } + } + if err := iprot.ReadStructEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) + } + return nil +} + +func (p *Span) readField1(iprot thrift.TProtocol) error { + if v, err := iprot.ReadI64(); err != nil { + return thrift.PrependError("error reading field 1: ", err) + } else { + p.TraceID = v + } + return nil +} + +func (p *Span) readField3(iprot thrift.TProtocol) error { + if v, err := iprot.ReadString(); err != nil { + return thrift.PrependError("error reading field 3: ", err) + } else { + p.Name = v + } + return nil +} + +func (p *Span) readField4(iprot thrift.TProtocol) error { + if v, err := iprot.ReadI64(); err != nil { + return thrift.PrependError("error reading field 4: ", err) + } else { + p.ID = v + } + return nil +} + +func (p *Span) readField5(iprot thrift.TProtocol) error { + if v, err := iprot.ReadI64(); err != nil { + return thrift.PrependError("error reading field 5: ", err) + } else { + p.ParentID = &v + } + return nil +} + +func (p *Span) readField6(iprot thrift.TProtocol) error { + _, size, err := iprot.ReadListBegin() + if err != nil { + return thrift.PrependError("error reading list begin: ", err) + } + tSlice := make([]*Annotation, 0, size) + p.Annotations = tSlice + for i := 0; i < size; i++ { + _elem0 := &Annotation{} + if err := _elem0.Read(iprot); err != nil { + return thrift.PrependError(fmt.Sprintf("%T error reading struct: ", _elem0), err) + } + p.Annotations = append(p.Annotations, _elem0) + } + if err := iprot.ReadListEnd(); err != nil { + return thrift.PrependError("error reading list end: ", err) + } + return nil +} + +func (p *Span) readField8(iprot thrift.TProtocol) error { + _, size, err := iprot.ReadListBegin() + if err != nil { + return thrift.PrependError("error reading list begin: ", err) + } + tSlice := make([]*BinaryAnnotation, 0, size) + p.BinaryAnnotations = tSlice + for i := 0; i < size; i++ { + _elem1 := &BinaryAnnotation{} + if err := _elem1.Read(iprot); err != nil { + return thrift.PrependError(fmt.Sprintf("%T error reading struct: ", _elem1), err) + } + p.BinaryAnnotations = append(p.BinaryAnnotations, _elem1) + } + if err := iprot.ReadListEnd(); err != nil { + return thrift.PrependError("error reading list end: ", err) + } + return nil +} + +func (p *Span) readField9(iprot thrift.TProtocol) error { + if v, err := iprot.ReadBool(); err != nil { + return thrift.PrependError("error reading field 9: ", err) + } else { + p.Debug = v + } + return nil +} + +func (p *Span) readField10(iprot thrift.TProtocol) error { + if v, err := iprot.ReadI64(); err != nil { + return thrift.PrependError("error reading field 10: ", err) + } else { + p.Timestamp = &v + } + return nil +} + +func (p *Span) readField11(iprot thrift.TProtocol) error { + if v, err := iprot.ReadI64(); err != nil { + return thrift.PrependError("error reading field 11: ", err) + } else { + p.Duration = &v + } + return nil +} + +func (p *Span) Write(oprot thrift.TProtocol) error { + if err := oprot.WriteStructBegin("Span"); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) + } + if err := p.writeField1(oprot); err != nil { + return err + } + if err := p.writeField3(oprot); err != nil { + return err + } + if err := p.writeField4(oprot); err != nil { + return err + } + if err := p.writeField5(oprot); err != nil { + return err + } + if err := p.writeField6(oprot); err != nil { + return err + } + if err := p.writeField8(oprot); err != nil { + return err + } + if err := p.writeField9(oprot); err != nil { + return err + } + if err := p.writeField10(oprot); err != nil { + return err + } + if err := p.writeField11(oprot); err != nil { + return err + } + if err := oprot.WriteFieldStop(); err != nil { + return thrift.PrependError("write field stop error: ", err) + } + if err := oprot.WriteStructEnd(); err != nil { + return thrift.PrependError("write struct stop error: ", err) + } + return nil +} + +func (p *Span) writeField1(oprot thrift.TProtocol) (err error) { + if err := oprot.WriteFieldBegin("trace_id", thrift.I64, 1); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 1:trace_id: ", p), err) + } + if err := oprot.WriteI64(int64(p.TraceID)); err != nil { + return thrift.PrependError(fmt.Sprintf("%T.trace_id (1) field write error: ", p), err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 1:trace_id: ", p), err) + } + return err +} + +func (p *Span) writeField3(oprot thrift.TProtocol) (err error) { + if err := oprot.WriteFieldBegin("name", thrift.STRING, 3); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 3:name: ", p), err) + } + if err := oprot.WriteString(string(p.Name)); err != nil { + return thrift.PrependError(fmt.Sprintf("%T.name (3) field write error: ", p), err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 3:name: ", p), err) + } + return err +} + +func (p *Span) writeField4(oprot thrift.TProtocol) (err error) { + if err := oprot.WriteFieldBegin("id", thrift.I64, 4); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 4:id: ", p), err) + } + if err := oprot.WriteI64(int64(p.ID)); err != nil { + return thrift.PrependError(fmt.Sprintf("%T.id (4) field write error: ", p), err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 4:id: ", p), err) + } + return err +} + +func (p *Span) writeField5(oprot thrift.TProtocol) (err error) { + if p.IsSetParentID() { + if err := oprot.WriteFieldBegin("parent_id", thrift.I64, 5); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 5:parent_id: ", p), err) + } + if err := oprot.WriteI64(int64(*p.ParentID)); err != nil { + return thrift.PrependError(fmt.Sprintf("%T.parent_id (5) field write error: ", p), err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 5:parent_id: ", p), err) + } + } + return err +} + +func (p *Span) writeField6(oprot thrift.TProtocol) (err error) { + if err := oprot.WriteFieldBegin("annotations", thrift.LIST, 6); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 6:annotations: ", p), err) + } + if err := oprot.WriteListBegin(thrift.STRUCT, len(p.Annotations)); err != nil { + return thrift.PrependError("error writing list begin: ", err) + } + for _, v := range p.Annotations { + if err := v.Write(oprot); err != nil { + return thrift.PrependError(fmt.Sprintf("%T error writing struct: ", v), err) + } + } + if err := oprot.WriteListEnd(); err != nil { + return thrift.PrependError("error writing list end: ", err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 6:annotations: ", p), err) + } + return err +} + +func (p *Span) writeField8(oprot thrift.TProtocol) (err error) { + if err := oprot.WriteFieldBegin("binary_annotations", thrift.LIST, 8); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 8:binary_annotations: ", p), err) + } + if err := oprot.WriteListBegin(thrift.STRUCT, len(p.BinaryAnnotations)); err != nil { + return thrift.PrependError("error writing list begin: ", err) + } + for _, v := range p.BinaryAnnotations { + if err := v.Write(oprot); err != nil { + return thrift.PrependError(fmt.Sprintf("%T error writing struct: ", v), err) + } + } + if err := oprot.WriteListEnd(); err != nil { + return thrift.PrependError("error writing list end: ", err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 8:binary_annotations: ", p), err) + } + return err +} + +func (p *Span) writeField9(oprot thrift.TProtocol) (err error) { + if p.IsSetDebug() { + if err := oprot.WriteFieldBegin("debug", thrift.BOOL, 9); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 9:debug: ", p), err) + } + if err := oprot.WriteBool(bool(p.Debug)); err != nil { + return thrift.PrependError(fmt.Sprintf("%T.debug (9) field write error: ", p), err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 9:debug: ", p), err) + } + } + return err +} + +func (p *Span) writeField10(oprot thrift.TProtocol) (err error) { + if p.IsSetTimestamp() { + if err := oprot.WriteFieldBegin("timestamp", thrift.I64, 10); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 10:timestamp: ", p), err) + } + if err := oprot.WriteI64(int64(*p.Timestamp)); err != nil { + return thrift.PrependError(fmt.Sprintf("%T.timestamp (10) field write error: ", p), err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 10:timestamp: ", p), err) + } + } + return err +} + +func (p *Span) writeField11(oprot thrift.TProtocol) (err error) { + if p.IsSetDuration() { + if err := oprot.WriteFieldBegin("duration", thrift.I64, 11); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 11:duration: ", p), err) + } + if err := oprot.WriteI64(int64(*p.Duration)); err != nil { + return thrift.PrependError(fmt.Sprintf("%T.duration (11) field write error: ", p), err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 11:duration: ", p), err) + } + } + return err +} + +func (p *Span) String() string { + if p == nil { + return "" + } + return fmt.Sprintf("Span(%+v)", *p) +} + +// Attributes: +// - Ok +type Response struct { + Ok bool `thrift:"ok,1,required" json:"ok"` +} + +func NewResponse() *Response { + return &Response{} +} + +func (p *Response) GetOk() bool { + return p.Ok +} +func (p *Response) Read(iprot thrift.TProtocol) error { + if _, err := iprot.ReadStructBegin(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T read error: ", p), err) + } + + var issetOk bool = false + + for { + _, fieldTypeId, fieldId, err := iprot.ReadFieldBegin() + if err != nil { + return thrift.PrependError(fmt.Sprintf("%T field %d read error: ", p, fieldId), err) + } + if fieldTypeId == thrift.STOP { + break + } + switch fieldId { + case 1: + if err := p.readField1(iprot); err != nil { + return err + } + issetOk = true + default: + if err := iprot.Skip(fieldTypeId); err != nil { + return err + } + } + if err := iprot.ReadFieldEnd(); err != nil { + return err + } + } + if err := iprot.ReadStructEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) + } + if !issetOk { + return thrift.NewTProtocolExceptionWithType(thrift.INVALID_DATA, fmt.Errorf("Required field Ok is not set")) + } + return nil +} + +func (p *Response) readField1(iprot thrift.TProtocol) error { + if v, err := iprot.ReadBool(); err != nil { + return thrift.PrependError("error reading field 1: ", err) + } else { + p.Ok = v + } + return nil +} + +func (p *Response) Write(oprot thrift.TProtocol) error { + if err := oprot.WriteStructBegin("Response"); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) + } + if err := p.writeField1(oprot); err != nil { + return err + } + if err := oprot.WriteFieldStop(); err != nil { + return thrift.PrependError("write field stop error: ", err) + } + if err := oprot.WriteStructEnd(); err != nil { + return thrift.PrependError("write struct stop error: ", err) + } + return nil +} + +func (p *Response) writeField1(oprot thrift.TProtocol) (err error) { + if err := oprot.WriteFieldBegin("ok", thrift.BOOL, 1); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 1:ok: ", p), err) + } + if err := oprot.WriteBool(bool(p.Ok)); err != nil { + return thrift.PrependError(fmt.Sprintf("%T.ok (1) field write error: ", p), err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 1:ok: ", p), err) + } + return err +} + +func (p *Response) String() string { + if p == nil { + return "" + } + return fmt.Sprintf("Response(%+v)", *p) +} diff --git a/vendor/github.com/uber/jaeger-client-go/thrift-gen/zipkincore/zipkincollector.go b/vendor/github.com/uber/jaeger-client-go/thrift-gen/zipkincore/zipkincollector.go new file mode 100644 index 0000000000..417e883d0e --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/thrift-gen/zipkincore/zipkincollector.go @@ -0,0 +1,446 @@ +// Autogenerated by Thrift Compiler (0.9.3) +// DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + +package zipkincore + +import ( + "bytes" + "fmt" + "github.com/uber/jaeger-client-go/thrift" +) + +// (needed to ensure safety because of naive import list construction.) +var _ = thrift.ZERO +var _ = fmt.Printf +var _ = bytes.Equal + +type ZipkinCollector interface { + // Parameters: + // - Spans + SubmitZipkinBatch(spans []*Span) (r []*Response, err error) +} + +type ZipkinCollectorClient struct { + Transport thrift.TTransport + ProtocolFactory thrift.TProtocolFactory + InputProtocol thrift.TProtocol + OutputProtocol thrift.TProtocol + SeqId int32 +} + +func NewZipkinCollectorClientFactory(t thrift.TTransport, f thrift.TProtocolFactory) *ZipkinCollectorClient { + return &ZipkinCollectorClient{Transport: t, + ProtocolFactory: f, + InputProtocol: f.GetProtocol(t), + OutputProtocol: f.GetProtocol(t), + SeqId: 0, + } +} + +func NewZipkinCollectorClientProtocol(t thrift.TTransport, iprot thrift.TProtocol, oprot thrift.TProtocol) *ZipkinCollectorClient { + return &ZipkinCollectorClient{Transport: t, + ProtocolFactory: nil, + InputProtocol: iprot, + OutputProtocol: oprot, + SeqId: 0, + } +} + +// Parameters: +// - Spans +func (p *ZipkinCollectorClient) SubmitZipkinBatch(spans []*Span) (r []*Response, err error) { + if err = p.sendSubmitZipkinBatch(spans); err != nil { + return + } + return p.recvSubmitZipkinBatch() +} + +func (p *ZipkinCollectorClient) sendSubmitZipkinBatch(spans []*Span) (err error) { + oprot := p.OutputProtocol + if oprot == nil { + oprot = p.ProtocolFactory.GetProtocol(p.Transport) + p.OutputProtocol = oprot + } + p.SeqId++ + if err = oprot.WriteMessageBegin("submitZipkinBatch", thrift.CALL, p.SeqId); err != nil { + return + } + args := ZipkinCollectorSubmitZipkinBatchArgs{ + Spans: spans, + } + if err = args.Write(oprot); err != nil { + return + } + if err = oprot.WriteMessageEnd(); err != nil { + return + } + return oprot.Flush() +} + +func (p *ZipkinCollectorClient) recvSubmitZipkinBatch() (value []*Response, err error) { + iprot := p.InputProtocol + if iprot == nil { + iprot = p.ProtocolFactory.GetProtocol(p.Transport) + p.InputProtocol = iprot + } + method, mTypeId, seqId, err := iprot.ReadMessageBegin() + if err != nil { + return + } + if method != "submitZipkinBatch" { + err = thrift.NewTApplicationException(thrift.WRONG_METHOD_NAME, "submitZipkinBatch failed: wrong method name") + return + } + if p.SeqId != seqId { + err = thrift.NewTApplicationException(thrift.BAD_SEQUENCE_ID, "submitZipkinBatch failed: out of sequence response") + return + } + if mTypeId == thrift.EXCEPTION { + error2 := thrift.NewTApplicationException(thrift.UNKNOWN_APPLICATION_EXCEPTION, "Unknown Exception") + var error3 error + error3, err = error2.Read(iprot) + if err != nil { + return + } + if err = iprot.ReadMessageEnd(); err != nil { + return + } + err = error3 + return + } + if mTypeId != thrift.REPLY { + err = thrift.NewTApplicationException(thrift.INVALID_MESSAGE_TYPE_EXCEPTION, "submitZipkinBatch failed: invalid message type") + return + } + result := ZipkinCollectorSubmitZipkinBatchResult{} + if err = result.Read(iprot); err != nil { + return + } + if err = iprot.ReadMessageEnd(); err != nil { + return + } + value = result.GetSuccess() + return +} + +type ZipkinCollectorProcessor struct { + processorMap map[string]thrift.TProcessorFunction + handler ZipkinCollector +} + +func (p *ZipkinCollectorProcessor) AddToProcessorMap(key string, processor thrift.TProcessorFunction) { + p.processorMap[key] = processor +} + +func (p *ZipkinCollectorProcessor) GetProcessorFunction(key string) (processor thrift.TProcessorFunction, ok bool) { + processor, ok = p.processorMap[key] + return processor, ok +} + +func (p *ZipkinCollectorProcessor) ProcessorMap() map[string]thrift.TProcessorFunction { + return p.processorMap +} + +func NewZipkinCollectorProcessor(handler ZipkinCollector) *ZipkinCollectorProcessor { + + self4 := &ZipkinCollectorProcessor{handler: handler, processorMap: make(map[string]thrift.TProcessorFunction)} + self4.processorMap["submitZipkinBatch"] = &zipkinCollectorProcessorSubmitZipkinBatch{handler: handler} + return self4 +} + +func (p *ZipkinCollectorProcessor) Process(iprot, oprot thrift.TProtocol) (success bool, err thrift.TException) { + name, _, seqId, err := iprot.ReadMessageBegin() + if err != nil { + return false, err + } + if processor, ok := p.GetProcessorFunction(name); ok { + return processor.Process(seqId, iprot, oprot) + } + iprot.Skip(thrift.STRUCT) + iprot.ReadMessageEnd() + x5 := thrift.NewTApplicationException(thrift.UNKNOWN_METHOD, "Unknown function "+name) + oprot.WriteMessageBegin(name, thrift.EXCEPTION, seqId) + x5.Write(oprot) + oprot.WriteMessageEnd() + oprot.Flush() + return false, x5 + +} + +type zipkinCollectorProcessorSubmitZipkinBatch struct { + handler ZipkinCollector +} + +func (p *zipkinCollectorProcessorSubmitZipkinBatch) Process(seqId int32, iprot, oprot thrift.TProtocol) (success bool, err thrift.TException) { + args := ZipkinCollectorSubmitZipkinBatchArgs{} + if err = args.Read(iprot); err != nil { + iprot.ReadMessageEnd() + x := thrift.NewTApplicationException(thrift.PROTOCOL_ERROR, err.Error()) + oprot.WriteMessageBegin("submitZipkinBatch", thrift.EXCEPTION, seqId) + x.Write(oprot) + oprot.WriteMessageEnd() + oprot.Flush() + return false, err + } + + iprot.ReadMessageEnd() + result := ZipkinCollectorSubmitZipkinBatchResult{} + var retval []*Response + var err2 error + if retval, err2 = p.handler.SubmitZipkinBatch(args.Spans); err2 != nil { + x := thrift.NewTApplicationException(thrift.INTERNAL_ERROR, "Internal error processing submitZipkinBatch: "+err2.Error()) + oprot.WriteMessageBegin("submitZipkinBatch", thrift.EXCEPTION, seqId) + x.Write(oprot) + oprot.WriteMessageEnd() + oprot.Flush() + return true, err2 + } else { + result.Success = retval + } + if err2 = oprot.WriteMessageBegin("submitZipkinBatch", thrift.REPLY, seqId); err2 != nil { + err = err2 + } + if err2 = result.Write(oprot); err == nil && err2 != nil { + err = err2 + } + if err2 = oprot.WriteMessageEnd(); err == nil && err2 != nil { + err = err2 + } + if err2 = oprot.Flush(); err == nil && err2 != nil { + err = err2 + } + if err != nil { + return + } + return true, err +} + +// HELPER FUNCTIONS AND STRUCTURES + +// Attributes: +// - Spans +type ZipkinCollectorSubmitZipkinBatchArgs struct { + Spans []*Span `thrift:"spans,1" json:"spans"` +} + +func NewZipkinCollectorSubmitZipkinBatchArgs() *ZipkinCollectorSubmitZipkinBatchArgs { + return &ZipkinCollectorSubmitZipkinBatchArgs{} +} + +func (p *ZipkinCollectorSubmitZipkinBatchArgs) GetSpans() []*Span { + return p.Spans +} +func (p *ZipkinCollectorSubmitZipkinBatchArgs) Read(iprot thrift.TProtocol) error { + if _, err := iprot.ReadStructBegin(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T read error: ", p), err) + } + + for { + _, fieldTypeId, fieldId, err := iprot.ReadFieldBegin() + if err != nil { + return thrift.PrependError(fmt.Sprintf("%T field %d read error: ", p, fieldId), err) + } + if fieldTypeId == thrift.STOP { + break + } + switch fieldId { + case 1: + if err := p.readField1(iprot); err != nil { + return err + } + default: + if err := iprot.Skip(fieldTypeId); err != nil { + return err + } + } + if err := iprot.ReadFieldEnd(); err != nil { + return err + } + } + if err := iprot.ReadStructEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) + } + return nil +} + +func (p *ZipkinCollectorSubmitZipkinBatchArgs) readField1(iprot thrift.TProtocol) error { + _, size, err := iprot.ReadListBegin() + if err != nil { + return thrift.PrependError("error reading list begin: ", err) + } + tSlice := make([]*Span, 0, size) + p.Spans = tSlice + for i := 0; i < size; i++ { + _elem6 := &Span{} + if err := _elem6.Read(iprot); err != nil { + return thrift.PrependError(fmt.Sprintf("%T error reading struct: ", _elem6), err) + } + p.Spans = append(p.Spans, _elem6) + } + if err := iprot.ReadListEnd(); err != nil { + return thrift.PrependError("error reading list end: ", err) + } + return nil +} + +func (p *ZipkinCollectorSubmitZipkinBatchArgs) Write(oprot thrift.TProtocol) error { + if err := oprot.WriteStructBegin("submitZipkinBatch_args"); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) + } + if err := p.writeField1(oprot); err != nil { + return err + } + if err := oprot.WriteFieldStop(); err != nil { + return thrift.PrependError("write field stop error: ", err) + } + if err := oprot.WriteStructEnd(); err != nil { + return thrift.PrependError("write struct stop error: ", err) + } + return nil +} + +func (p *ZipkinCollectorSubmitZipkinBatchArgs) writeField1(oprot thrift.TProtocol) (err error) { + if err := oprot.WriteFieldBegin("spans", thrift.LIST, 1); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 1:spans: ", p), err) + } + if err := oprot.WriteListBegin(thrift.STRUCT, len(p.Spans)); err != nil { + return thrift.PrependError("error writing list begin: ", err) + } + for _, v := range p.Spans { + if err := v.Write(oprot); err != nil { + return thrift.PrependError(fmt.Sprintf("%T error writing struct: ", v), err) + } + } + if err := oprot.WriteListEnd(); err != nil { + return thrift.PrependError("error writing list end: ", err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 1:spans: ", p), err) + } + return err +} + +func (p *ZipkinCollectorSubmitZipkinBatchArgs) String() string { + if p == nil { + return "" + } + return fmt.Sprintf("ZipkinCollectorSubmitZipkinBatchArgs(%+v)", *p) +} + +// Attributes: +// - Success +type ZipkinCollectorSubmitZipkinBatchResult struct { + Success []*Response `thrift:"success,0" json:"success,omitempty"` +} + +func NewZipkinCollectorSubmitZipkinBatchResult() *ZipkinCollectorSubmitZipkinBatchResult { + return &ZipkinCollectorSubmitZipkinBatchResult{} +} + +var ZipkinCollectorSubmitZipkinBatchResult_Success_DEFAULT []*Response + +func (p *ZipkinCollectorSubmitZipkinBatchResult) GetSuccess() []*Response { + return p.Success +} +func (p *ZipkinCollectorSubmitZipkinBatchResult) IsSetSuccess() bool { + return p.Success != nil +} + +func (p *ZipkinCollectorSubmitZipkinBatchResult) Read(iprot thrift.TProtocol) error { + if _, err := iprot.ReadStructBegin(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T read error: ", p), err) + } + + for { + _, fieldTypeId, fieldId, err := iprot.ReadFieldBegin() + if err != nil { + return thrift.PrependError(fmt.Sprintf("%T field %d read error: ", p, fieldId), err) + } + if fieldTypeId == thrift.STOP { + break + } + switch fieldId { + case 0: + if err := p.readField0(iprot); err != nil { + return err + } + default: + if err := iprot.Skip(fieldTypeId); err != nil { + return err + } + } + if err := iprot.ReadFieldEnd(); err != nil { + return err + } + } + if err := iprot.ReadStructEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) + } + return nil +} + +func (p *ZipkinCollectorSubmitZipkinBatchResult) readField0(iprot thrift.TProtocol) error { + _, size, err := iprot.ReadListBegin() + if err != nil { + return thrift.PrependError("error reading list begin: ", err) + } + tSlice := make([]*Response, 0, size) + p.Success = tSlice + for i := 0; i < size; i++ { + _elem7 := &Response{} + if err := _elem7.Read(iprot); err != nil { + return thrift.PrependError(fmt.Sprintf("%T error reading struct: ", _elem7), err) + } + p.Success = append(p.Success, _elem7) + } + if err := iprot.ReadListEnd(); err != nil { + return thrift.PrependError("error reading list end: ", err) + } + return nil +} + +func (p *ZipkinCollectorSubmitZipkinBatchResult) Write(oprot thrift.TProtocol) error { + if err := oprot.WriteStructBegin("submitZipkinBatch_result"); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err) + } + if err := p.writeField0(oprot); err != nil { + return err + } + if err := oprot.WriteFieldStop(); err != nil { + return thrift.PrependError("write field stop error: ", err) + } + if err := oprot.WriteStructEnd(); err != nil { + return thrift.PrependError("write struct stop error: ", err) + } + return nil +} + +func (p *ZipkinCollectorSubmitZipkinBatchResult) writeField0(oprot thrift.TProtocol) (err error) { + if p.IsSetSuccess() { + if err := oprot.WriteFieldBegin("success", thrift.LIST, 0); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field begin error 0:success: ", p), err) + } + if err := oprot.WriteListBegin(thrift.STRUCT, len(p.Success)); err != nil { + return thrift.PrependError("error writing list begin: ", err) + } + for _, v := range p.Success { + if err := v.Write(oprot); err != nil { + return thrift.PrependError(fmt.Sprintf("%T error writing struct: ", v), err) + } + } + if err := oprot.WriteListEnd(); err != nil { + return thrift.PrependError("error writing list end: ", err) + } + if err := oprot.WriteFieldEnd(); err != nil { + return thrift.PrependError(fmt.Sprintf("%T write field end error 0:success: ", p), err) + } + } + return err +} + +func (p *ZipkinCollectorSubmitZipkinBatchResult) String() string { + if p == nil { + return "" + } + return fmt.Sprintf("ZipkinCollectorSubmitZipkinBatchResult(%+v)", *p) +} diff --git a/vendor/github.com/uber/jaeger-client-go/thrift/README.md b/vendor/github.com/uber/jaeger-client-go/thrift/README.md new file mode 100644 index 0000000000..1d8e642e02 --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/thrift/README.md @@ -0,0 +1,7 @@ +# Apache Thrift + +This is a partial copy of Apache Thrift v0.10 (https://github.com/apache/thrift/commit/b2a4d4ae21c789b689dd162deb819665567f481c). + +It is vendored code to avoid compatibility issues introduced in Thrift v0.11. + +See https://github.com/jaegertracing/jaeger-client-go/pull/303. diff --git a/vendor/github.com/uber/jaeger-client-go/thrift/application_exception.go b/vendor/github.com/uber/jaeger-client-go/thrift/application_exception.go new file mode 100644 index 0000000000..6655cc5a97 --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/thrift/application_exception.go @@ -0,0 +1,142 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 thrift + +const ( + UNKNOWN_APPLICATION_EXCEPTION = 0 + UNKNOWN_METHOD = 1 + INVALID_MESSAGE_TYPE_EXCEPTION = 2 + WRONG_METHOD_NAME = 3 + BAD_SEQUENCE_ID = 4 + MISSING_RESULT = 5 + INTERNAL_ERROR = 6 + PROTOCOL_ERROR = 7 +) + +// Application level Thrift exception +type TApplicationException interface { + TException + TypeId() int32 + Read(iprot TProtocol) (TApplicationException, error) + Write(oprot TProtocol) error +} + +type tApplicationException struct { + message string + type_ int32 +} + +func (e tApplicationException) Error() string { + return e.message +} + +func NewTApplicationException(type_ int32, message string) TApplicationException { + return &tApplicationException{message, type_} +} + +func (p *tApplicationException) TypeId() int32 { + return p.type_ +} + +func (p *tApplicationException) Read(iprot TProtocol) (TApplicationException, error) { + _, err := iprot.ReadStructBegin() + if err != nil { + return nil, err + } + + message := "" + type_ := int32(UNKNOWN_APPLICATION_EXCEPTION) + + for { + _, ttype, id, err := iprot.ReadFieldBegin() + if err != nil { + return nil, err + } + if ttype == STOP { + break + } + switch id { + case 1: + if ttype == STRING { + if message, err = iprot.ReadString(); err != nil { + return nil, err + } + } else { + if err = SkipDefaultDepth(iprot, ttype); err != nil { + return nil, err + } + } + case 2: + if ttype == I32 { + if type_, err = iprot.ReadI32(); err != nil { + return nil, err + } + } else { + if err = SkipDefaultDepth(iprot, ttype); err != nil { + return nil, err + } + } + default: + if err = SkipDefaultDepth(iprot, ttype); err != nil { + return nil, err + } + } + if err = iprot.ReadFieldEnd(); err != nil { + return nil, err + } + } + return NewTApplicationException(type_, message), iprot.ReadStructEnd() +} + +func (p *tApplicationException) Write(oprot TProtocol) (err error) { + err = oprot.WriteStructBegin("TApplicationException") + if len(p.Error()) > 0 { + err = oprot.WriteFieldBegin("message", STRING, 1) + if err != nil { + return + } + err = oprot.WriteString(p.Error()) + if err != nil { + return + } + err = oprot.WriteFieldEnd() + if err != nil { + return + } + } + err = oprot.WriteFieldBegin("type", I32, 2) + if err != nil { + return + } + err = oprot.WriteI32(p.type_) + if err != nil { + return + } + err = oprot.WriteFieldEnd() + if err != nil { + return + } + err = oprot.WriteFieldStop() + if err != nil { + return + } + err = oprot.WriteStructEnd() + return +} diff --git a/vendor/github.com/uber/jaeger-client-go/thrift/binary_protocol.go b/vendor/github.com/uber/jaeger-client-go/thrift/binary_protocol.go new file mode 100644 index 0000000000..690d341111 --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/thrift/binary_protocol.go @@ -0,0 +1,514 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 thrift + +import ( + "bytes" + "encoding/binary" + "errors" + "fmt" + "io" + "math" +) + +type TBinaryProtocol struct { + trans TRichTransport + origTransport TTransport + reader io.Reader + writer io.Writer + strictRead bool + strictWrite bool + buffer [64]byte +} + +type TBinaryProtocolFactory struct { + strictRead bool + strictWrite bool +} + +func NewTBinaryProtocolTransport(t TTransport) *TBinaryProtocol { + return NewTBinaryProtocol(t, false, true) +} + +func NewTBinaryProtocol(t TTransport, strictRead, strictWrite bool) *TBinaryProtocol { + p := &TBinaryProtocol{origTransport: t, strictRead: strictRead, strictWrite: strictWrite} + if et, ok := t.(TRichTransport); ok { + p.trans = et + } else { + p.trans = NewTRichTransport(t) + } + p.reader = p.trans + p.writer = p.trans + return p +} + +func NewTBinaryProtocolFactoryDefault() *TBinaryProtocolFactory { + return NewTBinaryProtocolFactory(false, true) +} + +func NewTBinaryProtocolFactory(strictRead, strictWrite bool) *TBinaryProtocolFactory { + return &TBinaryProtocolFactory{strictRead: strictRead, strictWrite: strictWrite} +} + +func (p *TBinaryProtocolFactory) GetProtocol(t TTransport) TProtocol { + return NewTBinaryProtocol(t, p.strictRead, p.strictWrite) +} + +/** + * Writing Methods + */ + +func (p *TBinaryProtocol) WriteMessageBegin(name string, typeId TMessageType, seqId int32) error { + if p.strictWrite { + version := uint32(VERSION_1) | uint32(typeId) + e := p.WriteI32(int32(version)) + if e != nil { + return e + } + e = p.WriteString(name) + if e != nil { + return e + } + e = p.WriteI32(seqId) + return e + } else { + e := p.WriteString(name) + if e != nil { + return e + } + e = p.WriteByte(int8(typeId)) + if e != nil { + return e + } + e = p.WriteI32(seqId) + return e + } + return nil +} + +func (p *TBinaryProtocol) WriteMessageEnd() error { + return nil +} + +func (p *TBinaryProtocol) WriteStructBegin(name string) error { + return nil +} + +func (p *TBinaryProtocol) WriteStructEnd() error { + return nil +} + +func (p *TBinaryProtocol) WriteFieldBegin(name string, typeId TType, id int16) error { + e := p.WriteByte(int8(typeId)) + if e != nil { + return e + } + e = p.WriteI16(id) + return e +} + +func (p *TBinaryProtocol) WriteFieldEnd() error { + return nil +} + +func (p *TBinaryProtocol) WriteFieldStop() error { + e := p.WriteByte(STOP) + return e +} + +func (p *TBinaryProtocol) WriteMapBegin(keyType TType, valueType TType, size int) error { + e := p.WriteByte(int8(keyType)) + if e != nil { + return e + } + e = p.WriteByte(int8(valueType)) + if e != nil { + return e + } + e = p.WriteI32(int32(size)) + return e +} + +func (p *TBinaryProtocol) WriteMapEnd() error { + return nil +} + +func (p *TBinaryProtocol) WriteListBegin(elemType TType, size int) error { + e := p.WriteByte(int8(elemType)) + if e != nil { + return e + } + e = p.WriteI32(int32(size)) + return e +} + +func (p *TBinaryProtocol) WriteListEnd() error { + return nil +} + +func (p *TBinaryProtocol) WriteSetBegin(elemType TType, size int) error { + e := p.WriteByte(int8(elemType)) + if e != nil { + return e + } + e = p.WriteI32(int32(size)) + return e +} + +func (p *TBinaryProtocol) WriteSetEnd() error { + return nil +} + +func (p *TBinaryProtocol) WriteBool(value bool) error { + if value { + return p.WriteByte(1) + } + return p.WriteByte(0) +} + +func (p *TBinaryProtocol) WriteByte(value int8) error { + e := p.trans.WriteByte(byte(value)) + return NewTProtocolException(e) +} + +func (p *TBinaryProtocol) WriteI16(value int16) error { + v := p.buffer[0:2] + binary.BigEndian.PutUint16(v, uint16(value)) + _, e := p.writer.Write(v) + return NewTProtocolException(e) +} + +func (p *TBinaryProtocol) WriteI32(value int32) error { + v := p.buffer[0:4] + binary.BigEndian.PutUint32(v, uint32(value)) + _, e := p.writer.Write(v) + return NewTProtocolException(e) +} + +func (p *TBinaryProtocol) WriteI64(value int64) error { + v := p.buffer[0:8] + binary.BigEndian.PutUint64(v, uint64(value)) + _, err := p.writer.Write(v) + return NewTProtocolException(err) +} + +func (p *TBinaryProtocol) WriteDouble(value float64) error { + return p.WriteI64(int64(math.Float64bits(value))) +} + +func (p *TBinaryProtocol) WriteString(value string) error { + e := p.WriteI32(int32(len(value))) + if e != nil { + return e + } + _, err := p.trans.WriteString(value) + return NewTProtocolException(err) +} + +func (p *TBinaryProtocol) WriteBinary(value []byte) error { + e := p.WriteI32(int32(len(value))) + if e != nil { + return e + } + _, err := p.writer.Write(value) + return NewTProtocolException(err) +} + +/** + * Reading methods + */ + +func (p *TBinaryProtocol) ReadMessageBegin() (name string, typeId TMessageType, seqId int32, err error) { + size, e := p.ReadI32() + if e != nil { + return "", typeId, 0, NewTProtocolException(e) + } + if size < 0 { + typeId = TMessageType(size & 0x0ff) + version := int64(int64(size) & VERSION_MASK) + if version != VERSION_1 { + return name, typeId, seqId, NewTProtocolExceptionWithType(BAD_VERSION, fmt.Errorf("Bad version in ReadMessageBegin")) + } + name, e = p.ReadString() + if e != nil { + return name, typeId, seqId, NewTProtocolException(e) + } + seqId, e = p.ReadI32() + if e != nil { + return name, typeId, seqId, NewTProtocolException(e) + } + return name, typeId, seqId, nil + } + if p.strictRead { + return name, typeId, seqId, NewTProtocolExceptionWithType(BAD_VERSION, fmt.Errorf("Missing version in ReadMessageBegin")) + } + name, e2 := p.readStringBody(size) + if e2 != nil { + return name, typeId, seqId, e2 + } + b, e3 := p.ReadByte() + if e3 != nil { + return name, typeId, seqId, e3 + } + typeId = TMessageType(b) + seqId, e4 := p.ReadI32() + if e4 != nil { + return name, typeId, seqId, e4 + } + return name, typeId, seqId, nil +} + +func (p *TBinaryProtocol) ReadMessageEnd() error { + return nil +} + +func (p *TBinaryProtocol) ReadStructBegin() (name string, err error) { + return +} + +func (p *TBinaryProtocol) ReadStructEnd() error { + return nil +} + +func (p *TBinaryProtocol) ReadFieldBegin() (name string, typeId TType, seqId int16, err error) { + t, err := p.ReadByte() + typeId = TType(t) + if err != nil { + return name, typeId, seqId, err + } + if t != STOP { + seqId, err = p.ReadI16() + } + return name, typeId, seqId, err +} + +func (p *TBinaryProtocol) ReadFieldEnd() error { + return nil +} + +var invalidDataLength = NewTProtocolExceptionWithType(INVALID_DATA, errors.New("Invalid data length")) + +func (p *TBinaryProtocol) ReadMapBegin() (kType, vType TType, size int, err error) { + k, e := p.ReadByte() + if e != nil { + err = NewTProtocolException(e) + return + } + kType = TType(k) + v, e := p.ReadByte() + if e != nil { + err = NewTProtocolException(e) + return + } + vType = TType(v) + size32, e := p.ReadI32() + if e != nil { + err = NewTProtocolException(e) + return + } + if size32 < 0 { + err = invalidDataLength + return + } + size = int(size32) + return kType, vType, size, nil +} + +func (p *TBinaryProtocol) ReadMapEnd() error { + return nil +} + +func (p *TBinaryProtocol) ReadListBegin() (elemType TType, size int, err error) { + b, e := p.ReadByte() + if e != nil { + err = NewTProtocolException(e) + return + } + elemType = TType(b) + size32, e := p.ReadI32() + if e != nil { + err = NewTProtocolException(e) + return + } + if size32 < 0 { + err = invalidDataLength + return + } + size = int(size32) + + return +} + +func (p *TBinaryProtocol) ReadListEnd() error { + return nil +} + +func (p *TBinaryProtocol) ReadSetBegin() (elemType TType, size int, err error) { + b, e := p.ReadByte() + if e != nil { + err = NewTProtocolException(e) + return + } + elemType = TType(b) + size32, e := p.ReadI32() + if e != nil { + err = NewTProtocolException(e) + return + } + if size32 < 0 { + err = invalidDataLength + return + } + size = int(size32) + return elemType, size, nil +} + +func (p *TBinaryProtocol) ReadSetEnd() error { + return nil +} + +func (p *TBinaryProtocol) ReadBool() (bool, error) { + b, e := p.ReadByte() + v := true + if b != 1 { + v = false + } + return v, e +} + +func (p *TBinaryProtocol) ReadByte() (int8, error) { + v, err := p.trans.ReadByte() + return int8(v), err +} + +func (p *TBinaryProtocol) ReadI16() (value int16, err error) { + buf := p.buffer[0:2] + err = p.readAll(buf) + value = int16(binary.BigEndian.Uint16(buf)) + return value, err +} + +func (p *TBinaryProtocol) ReadI32() (value int32, err error) { + buf := p.buffer[0:4] + err = p.readAll(buf) + value = int32(binary.BigEndian.Uint32(buf)) + return value, err +} + +func (p *TBinaryProtocol) ReadI64() (value int64, err error) { + buf := p.buffer[0:8] + err = p.readAll(buf) + value = int64(binary.BigEndian.Uint64(buf)) + return value, err +} + +func (p *TBinaryProtocol) ReadDouble() (value float64, err error) { + buf := p.buffer[0:8] + err = p.readAll(buf) + value = math.Float64frombits(binary.BigEndian.Uint64(buf)) + return value, err +} + +func (p *TBinaryProtocol) ReadString() (value string, err error) { + size, e := p.ReadI32() + if e != nil { + return "", e + } + if size < 0 { + err = invalidDataLength + return + } + + return p.readStringBody(size) +} + +func (p *TBinaryProtocol) ReadBinary() ([]byte, error) { + size, e := p.ReadI32() + if e != nil { + return nil, e + } + if size < 0 { + return nil, invalidDataLength + } + if uint64(size) > p.trans.RemainingBytes() { + return nil, invalidDataLength + } + + isize := int(size) + buf := make([]byte, isize) + _, err := io.ReadFull(p.trans, buf) + return buf, NewTProtocolException(err) +} + +func (p *TBinaryProtocol) Flush() (err error) { + return NewTProtocolException(p.trans.Flush()) +} + +func (p *TBinaryProtocol) Skip(fieldType TType) (err error) { + return SkipDefaultDepth(p, fieldType) +} + +func (p *TBinaryProtocol) Transport() TTransport { + return p.origTransport +} + +func (p *TBinaryProtocol) readAll(buf []byte) error { + _, err := io.ReadFull(p.reader, buf) + return NewTProtocolException(err) +} + +const readLimit = 32768 + +func (p *TBinaryProtocol) readStringBody(size int32) (value string, err error) { + if size < 0 { + return "", nil + } + if uint64(size) > p.trans.RemainingBytes() { + return "", invalidDataLength + } + + var ( + buf bytes.Buffer + e error + b []byte + ) + + switch { + case int(size) <= len(p.buffer): + b = p.buffer[:size] // avoids allocation for small reads + case int(size) < readLimit: + b = make([]byte, size) + default: + b = make([]byte, readLimit) + } + + for size > 0 { + _, e = io.ReadFull(p.trans, b) + buf.Write(b) + if e != nil { + break + } + size -= readLimit + if size < readLimit && size > 0 { + b = b[:size] + } + } + return buf.String(), NewTProtocolException(e) +} diff --git a/vendor/github.com/uber/jaeger-client-go/thrift/compact_protocol.go b/vendor/github.com/uber/jaeger-client-go/thrift/compact_protocol.go new file mode 100644 index 0000000000..b9299f2fa1 --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/thrift/compact_protocol.go @@ -0,0 +1,815 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 thrift + +import ( + "encoding/binary" + "fmt" + "io" + "math" +) + +const ( + COMPACT_PROTOCOL_ID = 0x082 + COMPACT_VERSION = 1 + COMPACT_VERSION_MASK = 0x1f + COMPACT_TYPE_MASK = 0x0E0 + COMPACT_TYPE_BITS = 0x07 + COMPACT_TYPE_SHIFT_AMOUNT = 5 +) + +type tCompactType byte + +const ( + COMPACT_BOOLEAN_TRUE = 0x01 + COMPACT_BOOLEAN_FALSE = 0x02 + COMPACT_BYTE = 0x03 + COMPACT_I16 = 0x04 + COMPACT_I32 = 0x05 + COMPACT_I64 = 0x06 + COMPACT_DOUBLE = 0x07 + COMPACT_BINARY = 0x08 + COMPACT_LIST = 0x09 + COMPACT_SET = 0x0A + COMPACT_MAP = 0x0B + COMPACT_STRUCT = 0x0C +) + +var ( + ttypeToCompactType map[TType]tCompactType +) + +func init() { + ttypeToCompactType = map[TType]tCompactType{ + STOP: STOP, + BOOL: COMPACT_BOOLEAN_TRUE, + BYTE: COMPACT_BYTE, + I16: COMPACT_I16, + I32: COMPACT_I32, + I64: COMPACT_I64, + DOUBLE: COMPACT_DOUBLE, + STRING: COMPACT_BINARY, + LIST: COMPACT_LIST, + SET: COMPACT_SET, + MAP: COMPACT_MAP, + STRUCT: COMPACT_STRUCT, + } +} + +type TCompactProtocolFactory struct{} + +func NewTCompactProtocolFactory() *TCompactProtocolFactory { + return &TCompactProtocolFactory{} +} + +func (p *TCompactProtocolFactory) GetProtocol(trans TTransport) TProtocol { + return NewTCompactProtocol(trans) +} + +type TCompactProtocol struct { + trans TRichTransport + origTransport TTransport + + // Used to keep track of the last field for the current and previous structs, + // so we can do the delta stuff. + lastField []int + lastFieldId int + + // If we encounter a boolean field begin, save the TField here so it can + // have the value incorporated. + booleanFieldName string + booleanFieldId int16 + booleanFieldPending bool + + // If we read a field header, and it's a boolean field, save the boolean + // value here so that readBool can use it. + boolValue bool + boolValueIsNotNull bool + buffer [64]byte +} + +// Create a TCompactProtocol given a TTransport +func NewTCompactProtocol(trans TTransport) *TCompactProtocol { + p := &TCompactProtocol{origTransport: trans, lastField: []int{}} + if et, ok := trans.(TRichTransport); ok { + p.trans = et + } else { + p.trans = NewTRichTransport(trans) + } + + return p + +} + +// +// Public Writing methods. +// + +// Write a message header to the wire. Compact Protocol messages contain the +// protocol version so we can migrate forwards in the future if need be. +func (p *TCompactProtocol) WriteMessageBegin(name string, typeId TMessageType, seqid int32) error { + err := p.writeByteDirect(COMPACT_PROTOCOL_ID) + if err != nil { + return NewTProtocolException(err) + } + err = p.writeByteDirect((COMPACT_VERSION & COMPACT_VERSION_MASK) | ((byte(typeId) << COMPACT_TYPE_SHIFT_AMOUNT) & COMPACT_TYPE_MASK)) + if err != nil { + return NewTProtocolException(err) + } + _, err = p.writeVarint32(seqid) + if err != nil { + return NewTProtocolException(err) + } + e := p.WriteString(name) + return e + +} + +func (p *TCompactProtocol) WriteMessageEnd() error { return nil } + +// Write a struct begin. This doesn't actually put anything on the wire. We +// use it as an opportunity to put special placeholder markers on the field +// stack so we can get the field id deltas correct. +func (p *TCompactProtocol) WriteStructBegin(name string) error { + p.lastField = append(p.lastField, p.lastFieldId) + p.lastFieldId = 0 + return nil +} + +// Write a struct end. This doesn't actually put anything on the wire. We use +// this as an opportunity to pop the last field from the current struct off +// of the field stack. +func (p *TCompactProtocol) WriteStructEnd() error { + p.lastFieldId = p.lastField[len(p.lastField)-1] + p.lastField = p.lastField[:len(p.lastField)-1] + return nil +} + +func (p *TCompactProtocol) WriteFieldBegin(name string, typeId TType, id int16) error { + if typeId == BOOL { + // we want to possibly include the value, so we'll wait. + p.booleanFieldName, p.booleanFieldId, p.booleanFieldPending = name, id, true + return nil + } + _, err := p.writeFieldBeginInternal(name, typeId, id, 0xFF) + return NewTProtocolException(err) +} + +// The workhorse of writeFieldBegin. It has the option of doing a +// 'type override' of the type header. This is used specifically in the +// boolean field case. +func (p *TCompactProtocol) writeFieldBeginInternal(name string, typeId TType, id int16, typeOverride byte) (int, error) { + // short lastField = lastField_.pop(); + + // if there's a type override, use that. + var typeToWrite byte + if typeOverride == 0xFF { + typeToWrite = byte(p.getCompactType(typeId)) + } else { + typeToWrite = typeOverride + } + // check if we can use delta encoding for the field id + fieldId := int(id) + written := 0 + if fieldId > p.lastFieldId && fieldId-p.lastFieldId <= 15 { + // write them together + err := p.writeByteDirect(byte((fieldId-p.lastFieldId)<<4) | typeToWrite) + if err != nil { + return 0, err + } + } else { + // write them separate + err := p.writeByteDirect(typeToWrite) + if err != nil { + return 0, err + } + err = p.WriteI16(id) + written = 1 + 2 + if err != nil { + return 0, err + } + } + + p.lastFieldId = fieldId + // p.lastField.Push(field.id); + return written, nil +} + +func (p *TCompactProtocol) WriteFieldEnd() error { return nil } + +func (p *TCompactProtocol) WriteFieldStop() error { + err := p.writeByteDirect(STOP) + return NewTProtocolException(err) +} + +func (p *TCompactProtocol) WriteMapBegin(keyType TType, valueType TType, size int) error { + if size == 0 { + err := p.writeByteDirect(0) + return NewTProtocolException(err) + } + _, err := p.writeVarint32(int32(size)) + if err != nil { + return NewTProtocolException(err) + } + err = p.writeByteDirect(byte(p.getCompactType(keyType))<<4 | byte(p.getCompactType(valueType))) + return NewTProtocolException(err) +} + +func (p *TCompactProtocol) WriteMapEnd() error { return nil } + +// Write a list header. +func (p *TCompactProtocol) WriteListBegin(elemType TType, size int) error { + _, err := p.writeCollectionBegin(elemType, size) + return NewTProtocolException(err) +} + +func (p *TCompactProtocol) WriteListEnd() error { return nil } + +// Write a set header. +func (p *TCompactProtocol) WriteSetBegin(elemType TType, size int) error { + _, err := p.writeCollectionBegin(elemType, size) + return NewTProtocolException(err) +} + +func (p *TCompactProtocol) WriteSetEnd() error { return nil } + +func (p *TCompactProtocol) WriteBool(value bool) error { + v := byte(COMPACT_BOOLEAN_FALSE) + if value { + v = byte(COMPACT_BOOLEAN_TRUE) + } + if p.booleanFieldPending { + // we haven't written the field header yet + _, err := p.writeFieldBeginInternal(p.booleanFieldName, BOOL, p.booleanFieldId, v) + p.booleanFieldPending = false + return NewTProtocolException(err) + } + // we're not part of a field, so just write the value. + err := p.writeByteDirect(v) + return NewTProtocolException(err) +} + +// Write a byte. Nothing to see here! +func (p *TCompactProtocol) WriteByte(value int8) error { + err := p.writeByteDirect(byte(value)) + return NewTProtocolException(err) +} + +// Write an I16 as a zigzag varint. +func (p *TCompactProtocol) WriteI16(value int16) error { + _, err := p.writeVarint32(p.int32ToZigzag(int32(value))) + return NewTProtocolException(err) +} + +// Write an i32 as a zigzag varint. +func (p *TCompactProtocol) WriteI32(value int32) error { + _, err := p.writeVarint32(p.int32ToZigzag(value)) + return NewTProtocolException(err) +} + +// Write an i64 as a zigzag varint. +func (p *TCompactProtocol) WriteI64(value int64) error { + _, err := p.writeVarint64(p.int64ToZigzag(value)) + return NewTProtocolException(err) +} + +// Write a double to the wire as 8 bytes. +func (p *TCompactProtocol) WriteDouble(value float64) error { + buf := p.buffer[0:8] + binary.LittleEndian.PutUint64(buf, math.Float64bits(value)) + _, err := p.trans.Write(buf) + return NewTProtocolException(err) +} + +// Write a string to the wire with a varint size preceding. +func (p *TCompactProtocol) WriteString(value string) error { + _, e := p.writeVarint32(int32(len(value))) + if e != nil { + return NewTProtocolException(e) + } + if len(value) > 0 { + } + _, e = p.trans.WriteString(value) + return e +} + +// Write a byte array, using a varint for the size. +func (p *TCompactProtocol) WriteBinary(bin []byte) error { + _, e := p.writeVarint32(int32(len(bin))) + if e != nil { + return NewTProtocolException(e) + } + if len(bin) > 0 { + _, e = p.trans.Write(bin) + return NewTProtocolException(e) + } + return nil +} + +// +// Reading methods. +// + +// Read a message header. +func (p *TCompactProtocol) ReadMessageBegin() (name string, typeId TMessageType, seqId int32, err error) { + + protocolId, err := p.readByteDirect() + if err != nil { + return + } + + if protocolId != COMPACT_PROTOCOL_ID { + e := fmt.Errorf("Expected protocol id %02x but got %02x", COMPACT_PROTOCOL_ID, protocolId) + return "", typeId, seqId, NewTProtocolExceptionWithType(BAD_VERSION, e) + } + + versionAndType, err := p.readByteDirect() + if err != nil { + return + } + + version := versionAndType & COMPACT_VERSION_MASK + typeId = TMessageType((versionAndType >> COMPACT_TYPE_SHIFT_AMOUNT) & COMPACT_TYPE_BITS) + if version != COMPACT_VERSION { + e := fmt.Errorf("Expected version %02x but got %02x", COMPACT_VERSION, version) + err = NewTProtocolExceptionWithType(BAD_VERSION, e) + return + } + seqId, e := p.readVarint32() + if e != nil { + err = NewTProtocolException(e) + return + } + name, err = p.ReadString() + return +} + +func (p *TCompactProtocol) ReadMessageEnd() error { return nil } + +// Read a struct begin. There's nothing on the wire for this, but it is our +// opportunity to push a new struct begin marker onto the field stack. +func (p *TCompactProtocol) ReadStructBegin() (name string, err error) { + p.lastField = append(p.lastField, p.lastFieldId) + p.lastFieldId = 0 + return +} + +// Doesn't actually consume any wire data, just removes the last field for +// this struct from the field stack. +func (p *TCompactProtocol) ReadStructEnd() error { + // consume the last field we read off the wire. + p.lastFieldId = p.lastField[len(p.lastField)-1] + p.lastField = p.lastField[:len(p.lastField)-1] + return nil +} + +// Read a field header off the wire. +func (p *TCompactProtocol) ReadFieldBegin() (name string, typeId TType, id int16, err error) { + t, err := p.readByteDirect() + if err != nil { + return + } + + // if it's a stop, then we can return immediately, as the struct is over. + if (t & 0x0f) == STOP { + return "", STOP, 0, nil + } + + // mask off the 4 MSB of the type header. it could contain a field id delta. + modifier := int16((t & 0xf0) >> 4) + if modifier == 0 { + // not a delta. look ahead for the zigzag varint field id. + id, err = p.ReadI16() + if err != nil { + return + } + } else { + // has a delta. add the delta to the last read field id. + id = int16(p.lastFieldId) + modifier + } + typeId, e := p.getTType(tCompactType(t & 0x0f)) + if e != nil { + err = NewTProtocolException(e) + return + } + + // if this happens to be a boolean field, the value is encoded in the type + if p.isBoolType(t) { + // save the boolean value in a special instance variable. + p.boolValue = (byte(t)&0x0f == COMPACT_BOOLEAN_TRUE) + p.boolValueIsNotNull = true + } + + // push the new field onto the field stack so we can keep the deltas going. + p.lastFieldId = int(id) + return +} + +func (p *TCompactProtocol) ReadFieldEnd() error { return nil } + +// Read a map header off the wire. If the size is zero, skip reading the key +// and value type. This means that 0-length maps will yield TMaps without the +// "correct" types. +func (p *TCompactProtocol) ReadMapBegin() (keyType TType, valueType TType, size int, err error) { + size32, e := p.readVarint32() + if e != nil { + err = NewTProtocolException(e) + return + } + if size32 < 0 { + err = invalidDataLength + return + } + size = int(size32) + + keyAndValueType := byte(STOP) + if size != 0 { + keyAndValueType, err = p.readByteDirect() + if err != nil { + return + } + } + keyType, _ = p.getTType(tCompactType(keyAndValueType >> 4)) + valueType, _ = p.getTType(tCompactType(keyAndValueType & 0xf)) + return +} + +func (p *TCompactProtocol) ReadMapEnd() error { return nil } + +// Read a list header off the wire. If the list size is 0-14, the size will +// be packed into the element type header. If it's a longer list, the 4 MSB +// of the element type header will be 0xF, and a varint will follow with the +// true size. +func (p *TCompactProtocol) ReadListBegin() (elemType TType, size int, err error) { + size_and_type, err := p.readByteDirect() + if err != nil { + return + } + size = int((size_and_type >> 4) & 0x0f) + if size == 15 { + size2, e := p.readVarint32() + if e != nil { + err = NewTProtocolException(e) + return + } + if size2 < 0 { + err = invalidDataLength + return + } + size = int(size2) + } + elemType, e := p.getTType(tCompactType(size_and_type)) + if e != nil { + err = NewTProtocolException(e) + return + } + return +} + +func (p *TCompactProtocol) ReadListEnd() error { return nil } + +// Read a set header off the wire. If the set size is 0-14, the size will +// be packed into the element type header. If it's a longer set, the 4 MSB +// of the element type header will be 0xF, and a varint will follow with the +// true size. +func (p *TCompactProtocol) ReadSetBegin() (elemType TType, size int, err error) { + return p.ReadListBegin() +} + +func (p *TCompactProtocol) ReadSetEnd() error { return nil } + +// Read a boolean off the wire. If this is a boolean field, the value should +// already have been read during readFieldBegin, so we'll just consume the +// pre-stored value. Otherwise, read a byte. +func (p *TCompactProtocol) ReadBool() (value bool, err error) { + if p.boolValueIsNotNull { + p.boolValueIsNotNull = false + return p.boolValue, nil + } + v, err := p.readByteDirect() + return v == COMPACT_BOOLEAN_TRUE, err +} + +// Read a single byte off the wire. Nothing interesting here. +func (p *TCompactProtocol) ReadByte() (int8, error) { + v, err := p.readByteDirect() + if err != nil { + return 0, NewTProtocolException(err) + } + return int8(v), err +} + +// Read an i16 from the wire as a zigzag varint. +func (p *TCompactProtocol) ReadI16() (value int16, err error) { + v, err := p.ReadI32() + return int16(v), err +} + +// Read an i32 from the wire as a zigzag varint. +func (p *TCompactProtocol) ReadI32() (value int32, err error) { + v, e := p.readVarint32() + if e != nil { + return 0, NewTProtocolException(e) + } + value = p.zigzagToInt32(v) + return value, nil +} + +// Read an i64 from the wire as a zigzag varint. +func (p *TCompactProtocol) ReadI64() (value int64, err error) { + v, e := p.readVarint64() + if e != nil { + return 0, NewTProtocolException(e) + } + value = p.zigzagToInt64(v) + return value, nil +} + +// No magic here - just read a double off the wire. +func (p *TCompactProtocol) ReadDouble() (value float64, err error) { + longBits := p.buffer[0:8] + _, e := io.ReadFull(p.trans, longBits) + if e != nil { + return 0.0, NewTProtocolException(e) + } + return math.Float64frombits(p.bytesToUint64(longBits)), nil +} + +// Reads a []byte (via readBinary), and then UTF-8 decodes it. +func (p *TCompactProtocol) ReadString() (value string, err error) { + length, e := p.readVarint32() + if e != nil { + return "", NewTProtocolException(e) + } + if length < 0 { + return "", invalidDataLength + } + if uint64(length) > p.trans.RemainingBytes() { + return "", invalidDataLength + } + + if length == 0 { + return "", nil + } + var buf []byte + if length <= int32(len(p.buffer)) { + buf = p.buffer[0:length] + } else { + buf = make([]byte, length) + } + _, e = io.ReadFull(p.trans, buf) + return string(buf), NewTProtocolException(e) +} + +// Read a []byte from the wire. +func (p *TCompactProtocol) ReadBinary() (value []byte, err error) { + length, e := p.readVarint32() + if e != nil { + return nil, NewTProtocolException(e) + } + if length == 0 { + return []byte{}, nil + } + if length < 0 { + return nil, invalidDataLength + } + if uint64(length) > p.trans.RemainingBytes() { + return nil, invalidDataLength + } + + buf := make([]byte, length) + _, e = io.ReadFull(p.trans, buf) + return buf, NewTProtocolException(e) +} + +func (p *TCompactProtocol) Flush() (err error) { + return NewTProtocolException(p.trans.Flush()) +} + +func (p *TCompactProtocol) Skip(fieldType TType) (err error) { + return SkipDefaultDepth(p, fieldType) +} + +func (p *TCompactProtocol) Transport() TTransport { + return p.origTransport +} + +// +// Internal writing methods +// + +// Abstract method for writing the start of lists and sets. List and sets on +// the wire differ only by the type indicator. +func (p *TCompactProtocol) writeCollectionBegin(elemType TType, size int) (int, error) { + if size <= 14 { + return 1, p.writeByteDirect(byte(int32(size<<4) | int32(p.getCompactType(elemType)))) + } + err := p.writeByteDirect(0xf0 | byte(p.getCompactType(elemType))) + if err != nil { + return 0, err + } + m, err := p.writeVarint32(int32(size)) + return 1 + m, err +} + +// Write an i32 as a varint. Results in 1-5 bytes on the wire. +// TODO(pomack): make a permanent buffer like writeVarint64? +func (p *TCompactProtocol) writeVarint32(n int32) (int, error) { + i32buf := p.buffer[0:5] + idx := 0 + for { + if (n & ^0x7F) == 0 { + i32buf[idx] = byte(n) + idx++ + // p.writeByteDirect(byte(n)); + break + // return; + } else { + i32buf[idx] = byte((n & 0x7F) | 0x80) + idx++ + // p.writeByteDirect(byte(((n & 0x7F) | 0x80))); + u := uint32(n) + n = int32(u >> 7) + } + } + return p.trans.Write(i32buf[0:idx]) +} + +// Write an i64 as a varint. Results in 1-10 bytes on the wire. +func (p *TCompactProtocol) writeVarint64(n int64) (int, error) { + varint64out := p.buffer[0:10] + idx := 0 + for { + if (n & ^0x7F) == 0 { + varint64out[idx] = byte(n) + idx++ + break + } else { + varint64out[idx] = byte((n & 0x7F) | 0x80) + idx++ + u := uint64(n) + n = int64(u >> 7) + } + } + return p.trans.Write(varint64out[0:idx]) +} + +// Convert l into a zigzag long. This allows negative numbers to be +// represented compactly as a varint. +func (p *TCompactProtocol) int64ToZigzag(l int64) int64 { + return (l << 1) ^ (l >> 63) +} + +// Convert l into a zigzag long. This allows negative numbers to be +// represented compactly as a varint. +func (p *TCompactProtocol) int32ToZigzag(n int32) int32 { + return (n << 1) ^ (n >> 31) +} + +func (p *TCompactProtocol) fixedUint64ToBytes(n uint64, buf []byte) { + binary.LittleEndian.PutUint64(buf, n) +} + +func (p *TCompactProtocol) fixedInt64ToBytes(n int64, buf []byte) { + binary.LittleEndian.PutUint64(buf, uint64(n)) +} + +// Writes a byte without any possibility of all that field header nonsense. +// Used internally by other writing methods that know they need to write a byte. +func (p *TCompactProtocol) writeByteDirect(b byte) error { + return p.trans.WriteByte(b) +} + +// Writes a byte without any possibility of all that field header nonsense. +func (p *TCompactProtocol) writeIntAsByteDirect(n int) (int, error) { + return 1, p.writeByteDirect(byte(n)) +} + +// +// Internal reading methods +// + +// Read an i32 from the wire as a varint. The MSB of each byte is set +// if there is another byte to follow. This can read up to 5 bytes. +func (p *TCompactProtocol) readVarint32() (int32, error) { + // if the wire contains the right stuff, this will just truncate the i64 we + // read and get us the right sign. + v, err := p.readVarint64() + return int32(v), err +} + +// Read an i64 from the wire as a proper varint. The MSB of each byte is set +// if there is another byte to follow. This can read up to 10 bytes. +func (p *TCompactProtocol) readVarint64() (int64, error) { + shift := uint(0) + result := int64(0) + for { + b, err := p.readByteDirect() + if err != nil { + return 0, err + } + result |= int64(b&0x7f) << shift + if (b & 0x80) != 0x80 { + break + } + shift += 7 + } + return result, nil +} + +// Read a byte, unlike ReadByte that reads Thrift-byte that is i8. +func (p *TCompactProtocol) readByteDirect() (byte, error) { + return p.trans.ReadByte() +} + +// +// encoding helpers +// + +// Convert from zigzag int to int. +func (p *TCompactProtocol) zigzagToInt32(n int32) int32 { + u := uint32(n) + return int32(u>>1) ^ -(n & 1) +} + +// Convert from zigzag long to long. +func (p *TCompactProtocol) zigzagToInt64(n int64) int64 { + u := uint64(n) + return int64(u>>1) ^ -(n & 1) +} + +// Note that it's important that the mask bytes are long literals, +// otherwise they'll default to ints, and when you shift an int left 56 bits, +// you just get a messed up int. +func (p *TCompactProtocol) bytesToInt64(b []byte) int64 { + return int64(binary.LittleEndian.Uint64(b)) +} + +// Note that it's important that the mask bytes are long literals, +// otherwise they'll default to ints, and when you shift an int left 56 bits, +// you just get a messed up int. +func (p *TCompactProtocol) bytesToUint64(b []byte) uint64 { + return binary.LittleEndian.Uint64(b) +} + +// +// type testing and converting +// + +func (p *TCompactProtocol) isBoolType(b byte) bool { + return (b&0x0f) == COMPACT_BOOLEAN_TRUE || (b&0x0f) == COMPACT_BOOLEAN_FALSE +} + +// Given a tCompactType constant, convert it to its corresponding +// TType value. +func (p *TCompactProtocol) getTType(t tCompactType) (TType, error) { + switch byte(t) & 0x0f { + case STOP: + return STOP, nil + case COMPACT_BOOLEAN_FALSE, COMPACT_BOOLEAN_TRUE: + return BOOL, nil + case COMPACT_BYTE: + return BYTE, nil + case COMPACT_I16: + return I16, nil + case COMPACT_I32: + return I32, nil + case COMPACT_I64: + return I64, nil + case COMPACT_DOUBLE: + return DOUBLE, nil + case COMPACT_BINARY: + return STRING, nil + case COMPACT_LIST: + return LIST, nil + case COMPACT_SET: + return SET, nil + case COMPACT_MAP: + return MAP, nil + case COMPACT_STRUCT: + return STRUCT, nil + } + return STOP, TException(fmt.Errorf("don't know what type: %d", t&0x0f)) +} + +// Given a TType value, find the appropriate TCompactProtocol.Types constant. +func (p *TCompactProtocol) getCompactType(t TType) tCompactType { + return ttypeToCompactType[t] +} diff --git a/vendor/github.com/uber/jaeger-client-go/thrift/exception.go b/vendor/github.com/uber/jaeger-client-go/thrift/exception.go new file mode 100644 index 0000000000..ea8d6f6611 --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/thrift/exception.go @@ -0,0 +1,44 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 thrift + +import ( + "errors" +) + +// Generic Thrift exception +type TException interface { + error +} + +// Prepends additional information to an error without losing the Thrift exception interface +func PrependError(prepend string, err error) error { + if t, ok := err.(TTransportException); ok { + return NewTTransportException(t.TypeId(), prepend+t.Error()) + } + if t, ok := err.(TProtocolException); ok { + return NewTProtocolExceptionWithType(t.TypeId(), errors.New(prepend+err.Error())) + } + if t, ok := err.(TApplicationException); ok { + return NewTApplicationException(t.TypeId(), prepend+t.Error()) + } + + return errors.New(prepend + err.Error()) +} diff --git a/vendor/github.com/uber/jaeger-client-go/thrift/memory_buffer.go b/vendor/github.com/uber/jaeger-client-go/thrift/memory_buffer.go new file mode 100644 index 0000000000..b62fd56f06 --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/thrift/memory_buffer.go @@ -0,0 +1,79 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 thrift + +import ( + "bytes" +) + +// Memory buffer-based implementation of the TTransport interface. +type TMemoryBuffer struct { + *bytes.Buffer + size int +} + +type TMemoryBufferTransportFactory struct { + size int +} + +func (p *TMemoryBufferTransportFactory) GetTransport(trans TTransport) TTransport { + if trans != nil { + t, ok := trans.(*TMemoryBuffer) + if ok && t.size > 0 { + return NewTMemoryBufferLen(t.size) + } + } + return NewTMemoryBufferLen(p.size) +} + +func NewTMemoryBufferTransportFactory(size int) *TMemoryBufferTransportFactory { + return &TMemoryBufferTransportFactory{size: size} +} + +func NewTMemoryBuffer() *TMemoryBuffer { + return &TMemoryBuffer{Buffer: &bytes.Buffer{}, size: 0} +} + +func NewTMemoryBufferLen(size int) *TMemoryBuffer { + buf := make([]byte, 0, size) + return &TMemoryBuffer{Buffer: bytes.NewBuffer(buf), size: size} +} + +func (p *TMemoryBuffer) IsOpen() bool { + return true +} + +func (p *TMemoryBuffer) Open() error { + return nil +} + +func (p *TMemoryBuffer) Close() error { + p.Buffer.Reset() + return nil +} + +// Flushing a memory buffer is a no-op +func (p *TMemoryBuffer) Flush() error { + return nil +} + +func (p *TMemoryBuffer) RemainingBytes() (num_bytes uint64) { + return uint64(p.Buffer.Len()) +} diff --git a/vendor/github.com/uber/jaeger-client-go/thrift/messagetype.go b/vendor/github.com/uber/jaeger-client-go/thrift/messagetype.go new file mode 100644 index 0000000000..25ab2e98a2 --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/thrift/messagetype.go @@ -0,0 +1,31 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 thrift + +// Message type constants in the Thrift protocol. +type TMessageType int32 + +const ( + INVALID_TMESSAGE_TYPE TMessageType = 0 + CALL TMessageType = 1 + REPLY TMessageType = 2 + EXCEPTION TMessageType = 3 + ONEWAY TMessageType = 4 +) diff --git a/vendor/github.com/uber/jaeger-client-go/thrift/numeric.go b/vendor/github.com/uber/jaeger-client-go/thrift/numeric.go new file mode 100644 index 0000000000..aa8daa9b54 --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/thrift/numeric.go @@ -0,0 +1,164 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 thrift + +import ( + "math" + "strconv" +) + +type Numeric interface { + Int64() int64 + Int32() int32 + Int16() int16 + Byte() byte + Int() int + Float64() float64 + Float32() float32 + String() string + isNull() bool +} + +type numeric struct { + iValue int64 + dValue float64 + sValue string + isNil bool +} + +var ( + INFINITY Numeric + NEGATIVE_INFINITY Numeric + NAN Numeric + ZERO Numeric + NUMERIC_NULL Numeric +) + +func NewNumericFromDouble(dValue float64) Numeric { + if math.IsInf(dValue, 1) { + return INFINITY + } + if math.IsInf(dValue, -1) { + return NEGATIVE_INFINITY + } + if math.IsNaN(dValue) { + return NAN + } + iValue := int64(dValue) + sValue := strconv.FormatFloat(dValue, 'g', 10, 64) + isNil := false + return &numeric{iValue: iValue, dValue: dValue, sValue: sValue, isNil: isNil} +} + +func NewNumericFromI64(iValue int64) Numeric { + dValue := float64(iValue) + sValue := string(iValue) + isNil := false + return &numeric{iValue: iValue, dValue: dValue, sValue: sValue, isNil: isNil} +} + +func NewNumericFromI32(iValue int32) Numeric { + dValue := float64(iValue) + sValue := string(iValue) + isNil := false + return &numeric{iValue: int64(iValue), dValue: dValue, sValue: sValue, isNil: isNil} +} + +func NewNumericFromString(sValue string) Numeric { + if sValue == INFINITY.String() { + return INFINITY + } + if sValue == NEGATIVE_INFINITY.String() { + return NEGATIVE_INFINITY + } + if sValue == NAN.String() { + return NAN + } + iValue, _ := strconv.ParseInt(sValue, 10, 64) + dValue, _ := strconv.ParseFloat(sValue, 64) + isNil := len(sValue) == 0 + return &numeric{iValue: iValue, dValue: dValue, sValue: sValue, isNil: isNil} +} + +func NewNumericFromJSONString(sValue string, isNull bool) Numeric { + if isNull { + return NewNullNumeric() + } + if sValue == JSON_INFINITY { + return INFINITY + } + if sValue == JSON_NEGATIVE_INFINITY { + return NEGATIVE_INFINITY + } + if sValue == JSON_NAN { + return NAN + } + iValue, _ := strconv.ParseInt(sValue, 10, 64) + dValue, _ := strconv.ParseFloat(sValue, 64) + return &numeric{iValue: iValue, dValue: dValue, sValue: sValue, isNil: isNull} +} + +func NewNullNumeric() Numeric { + return &numeric{iValue: 0, dValue: 0.0, sValue: "", isNil: true} +} + +func (p *numeric) Int64() int64 { + return p.iValue +} + +func (p *numeric) Int32() int32 { + return int32(p.iValue) +} + +func (p *numeric) Int16() int16 { + return int16(p.iValue) +} + +func (p *numeric) Byte() byte { + return byte(p.iValue) +} + +func (p *numeric) Int() int { + return int(p.iValue) +} + +func (p *numeric) Float64() float64 { + return p.dValue +} + +func (p *numeric) Float32() float32 { + return float32(p.dValue) +} + +func (p *numeric) String() string { + return p.sValue +} + +func (p *numeric) isNull() bool { + return p.isNil +} + +func init() { + INFINITY = &numeric{iValue: 0, dValue: math.Inf(1), sValue: "Infinity", isNil: false} + NEGATIVE_INFINITY = &numeric{iValue: 0, dValue: math.Inf(-1), sValue: "-Infinity", isNil: false} + NAN = &numeric{iValue: 0, dValue: math.NaN(), sValue: "NaN", isNil: false} + ZERO = &numeric{iValue: 0, dValue: 0, sValue: "0", isNil: false} + NUMERIC_NULL = &numeric{iValue: 0, dValue: 0, sValue: "0", isNil: true} +} diff --git a/vendor/github.com/uber/jaeger-client-go/thrift/processor.go b/vendor/github.com/uber/jaeger-client-go/thrift/processor.go new file mode 100644 index 0000000000..ca0d3faf20 --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/thrift/processor.go @@ -0,0 +1,30 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 thrift + +// A processor is a generic object which operates upon an input stream and +// writes to some output stream. +type TProcessor interface { + Process(in, out TProtocol) (bool, TException) +} + +type TProcessorFunction interface { + Process(seqId int32, in, out TProtocol) (bool, TException) +} diff --git a/vendor/github.com/uber/jaeger-client-go/thrift/protocol.go b/vendor/github.com/uber/jaeger-client-go/thrift/protocol.go new file mode 100644 index 0000000000..45fa202e74 --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/thrift/protocol.go @@ -0,0 +1,175 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 thrift + +import ( + "errors" +) + +const ( + VERSION_MASK = 0xffff0000 + VERSION_1 = 0x80010000 +) + +type TProtocol interface { + WriteMessageBegin(name string, typeId TMessageType, seqid int32) error + WriteMessageEnd() error + WriteStructBegin(name string) error + WriteStructEnd() error + WriteFieldBegin(name string, typeId TType, id int16) error + WriteFieldEnd() error + WriteFieldStop() error + WriteMapBegin(keyType TType, valueType TType, size int) error + WriteMapEnd() error + WriteListBegin(elemType TType, size int) error + WriteListEnd() error + WriteSetBegin(elemType TType, size int) error + WriteSetEnd() error + WriteBool(value bool) error + WriteByte(value int8) error + WriteI16(value int16) error + WriteI32(value int32) error + WriteI64(value int64) error + WriteDouble(value float64) error + WriteString(value string) error + WriteBinary(value []byte) error + + ReadMessageBegin() (name string, typeId TMessageType, seqid int32, err error) + ReadMessageEnd() error + ReadStructBegin() (name string, err error) + ReadStructEnd() error + ReadFieldBegin() (name string, typeId TType, id int16, err error) + ReadFieldEnd() error + ReadMapBegin() (keyType TType, valueType TType, size int, err error) + ReadMapEnd() error + ReadListBegin() (elemType TType, size int, err error) + ReadListEnd() error + ReadSetBegin() (elemType TType, size int, err error) + ReadSetEnd() error + ReadBool() (value bool, err error) + ReadByte() (value int8, err error) + ReadI16() (value int16, err error) + ReadI32() (value int32, err error) + ReadI64() (value int64, err error) + ReadDouble() (value float64, err error) + ReadString() (value string, err error) + ReadBinary() (value []byte, err error) + + Skip(fieldType TType) (err error) + Flush() (err error) + + Transport() TTransport +} + +// The maximum recursive depth the skip() function will traverse +const DEFAULT_RECURSION_DEPTH = 64 + +// Skips over the next data element from the provided input TProtocol object. +func SkipDefaultDepth(prot TProtocol, typeId TType) (err error) { + return Skip(prot, typeId, DEFAULT_RECURSION_DEPTH) +} + +// Skips over the next data element from the provided input TProtocol object. +func Skip(self TProtocol, fieldType TType, maxDepth int) (err error) { + + if maxDepth <= 0 { + return NewTProtocolExceptionWithType( DEPTH_LIMIT, errors.New("Depth limit exceeded")) + } + + switch fieldType { + case STOP: + return + case BOOL: + _, err = self.ReadBool() + return + case BYTE: + _, err = self.ReadByte() + return + case I16: + _, err = self.ReadI16() + return + case I32: + _, err = self.ReadI32() + return + case I64: + _, err = self.ReadI64() + return + case DOUBLE: + _, err = self.ReadDouble() + return + case STRING: + _, err = self.ReadString() + return + case STRUCT: + if _, err = self.ReadStructBegin(); err != nil { + return err + } + for { + _, typeId, _, _ := self.ReadFieldBegin() + if typeId == STOP { + break + } + err := Skip(self, typeId, maxDepth-1) + if err != nil { + return err + } + self.ReadFieldEnd() + } + return self.ReadStructEnd() + case MAP: + keyType, valueType, size, err := self.ReadMapBegin() + if err != nil { + return err + } + for i := 0; i < size; i++ { + err := Skip(self, keyType, maxDepth-1) + if err != nil { + return err + } + self.Skip(valueType) + } + return self.ReadMapEnd() + case SET: + elemType, size, err := self.ReadSetBegin() + if err != nil { + return err + } + for i := 0; i < size; i++ { + err := Skip(self, elemType, maxDepth-1) + if err != nil { + return err + } + } + return self.ReadSetEnd() + case LIST: + elemType, size, err := self.ReadListBegin() + if err != nil { + return err + } + for i := 0; i < size; i++ { + err := Skip(self, elemType, maxDepth-1) + if err != nil { + return err + } + } + return self.ReadListEnd() + } + return nil +} diff --git a/vendor/github.com/uber/jaeger-client-go/thrift/protocol_exception.go b/vendor/github.com/uber/jaeger-client-go/thrift/protocol_exception.go new file mode 100644 index 0000000000..6e357ee890 --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/thrift/protocol_exception.go @@ -0,0 +1,78 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 thrift + +import ( + "encoding/base64" +) + +// Thrift Protocol exception +type TProtocolException interface { + TException + TypeId() int +} + +const ( + UNKNOWN_PROTOCOL_EXCEPTION = 0 + INVALID_DATA = 1 + NEGATIVE_SIZE = 2 + SIZE_LIMIT = 3 + BAD_VERSION = 4 + NOT_IMPLEMENTED = 5 + DEPTH_LIMIT = 6 +) + +type tProtocolException struct { + typeId int + message string +} + +func (p *tProtocolException) TypeId() int { + return p.typeId +} + +func (p *tProtocolException) String() string { + return p.message +} + +func (p *tProtocolException) Error() string { + return p.message +} + +func NewTProtocolException(err error) TProtocolException { + if err == nil { + return nil + } + if e,ok := err.(TProtocolException); ok { + return e + } + if _, ok := err.(base64.CorruptInputError); ok { + return &tProtocolException{INVALID_DATA, err.Error()} + } + return &tProtocolException{UNKNOWN_PROTOCOL_EXCEPTION, err.Error()} +} + +func NewTProtocolExceptionWithType(errType int, err error) TProtocolException { + if err == nil { + return nil + } + return &tProtocolException{errType, err.Error()} +} + diff --git a/vendor/github.com/uber/jaeger-client-go/thrift/protocol_factory.go b/vendor/github.com/uber/jaeger-client-go/thrift/protocol_factory.go new file mode 100644 index 0000000000..c40f796d88 --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/thrift/protocol_factory.go @@ -0,0 +1,25 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 thrift + +// Factory interface for constructing protocol instances. +type TProtocolFactory interface { + GetProtocol(trans TTransport) TProtocol +} diff --git a/vendor/github.com/uber/jaeger-client-go/thrift/rich_transport.go b/vendor/github.com/uber/jaeger-client-go/thrift/rich_transport.go new file mode 100644 index 0000000000..8e296a99b5 --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/thrift/rich_transport.go @@ -0,0 +1,69 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 thrift + +import "io" + +type RichTransport struct { + TTransport +} + +// Wraps Transport to provide TRichTransport interface +func NewTRichTransport(trans TTransport) *RichTransport { + return &RichTransport{trans} +} + +func (r *RichTransport) ReadByte() (c byte, err error) { + return readByte(r.TTransport) +} + +func (r *RichTransport) WriteByte(c byte) error { + return writeByte(r.TTransport, c) +} + +func (r *RichTransport) WriteString(s string) (n int, err error) { + return r.Write([]byte(s)) +} + +func (r *RichTransport) RemainingBytes() (num_bytes uint64) { + return r.TTransport.RemainingBytes() +} + +func readByte(r io.Reader) (c byte, err error) { + v := [1]byte{0} + n, err := r.Read(v[0:1]) + if n > 0 && (err == nil || err == io.EOF) { + return v[0], nil + } + if n > 0 && err != nil { + return v[0], err + } + if err != nil { + return 0, err + } + return v[0], nil +} + +func writeByte(w io.Writer, c byte) error { + v := [1]byte{c} + _, err := w.Write(v[0:1]) + return err +} + diff --git a/vendor/github.com/uber/jaeger-client-go/thrift/serializer.go b/vendor/github.com/uber/jaeger-client-go/thrift/serializer.go new file mode 100644 index 0000000000..7712229990 --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/thrift/serializer.go @@ -0,0 +1,75 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 thrift + +type TSerializer struct { + Transport *TMemoryBuffer + Protocol TProtocol +} + +type TStruct interface { + Write(p TProtocol) error + Read(p TProtocol) error +} + +func NewTSerializer() *TSerializer { + transport := NewTMemoryBufferLen(1024) + protocol := NewTBinaryProtocolFactoryDefault().GetProtocol(transport) + + return &TSerializer{ + transport, + protocol} +} + +func (t *TSerializer) WriteString(msg TStruct) (s string, err error) { + t.Transport.Reset() + + if err = msg.Write(t.Protocol); err != nil { + return + } + + if err = t.Protocol.Flush(); err != nil { + return + } + if err = t.Transport.Flush(); err != nil { + return + } + + return t.Transport.String(), nil +} + +func (t *TSerializer) Write(msg TStruct) (b []byte, err error) { + t.Transport.Reset() + + if err = msg.Write(t.Protocol); err != nil { + return + } + + if err = t.Protocol.Flush(); err != nil { + return + } + + if err = t.Transport.Flush(); err != nil { + return + } + + b = append(b, t.Transport.Bytes()...) + return +} diff --git a/vendor/github.com/uber/jaeger-client-go/thrift/simple_json_protocol.go b/vendor/github.com/uber/jaeger-client-go/thrift/simple_json_protocol.go new file mode 100644 index 0000000000..412a482d05 --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/thrift/simple_json_protocol.go @@ -0,0 +1,1337 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 thrift + +import ( + "bufio" + "bytes" + "encoding/base64" + "encoding/json" + "fmt" + "io" + "math" + "strconv" +) + +type _ParseContext int + +const ( + _CONTEXT_IN_TOPLEVEL _ParseContext = 1 + _CONTEXT_IN_LIST_FIRST _ParseContext = 2 + _CONTEXT_IN_LIST _ParseContext = 3 + _CONTEXT_IN_OBJECT_FIRST _ParseContext = 4 + _CONTEXT_IN_OBJECT_NEXT_KEY _ParseContext = 5 + _CONTEXT_IN_OBJECT_NEXT_VALUE _ParseContext = 6 +) + +func (p _ParseContext) String() string { + switch p { + case _CONTEXT_IN_TOPLEVEL: + return "TOPLEVEL" + case _CONTEXT_IN_LIST_FIRST: + return "LIST-FIRST" + case _CONTEXT_IN_LIST: + return "LIST" + case _CONTEXT_IN_OBJECT_FIRST: + return "OBJECT-FIRST" + case _CONTEXT_IN_OBJECT_NEXT_KEY: + return "OBJECT-NEXT-KEY" + case _CONTEXT_IN_OBJECT_NEXT_VALUE: + return "OBJECT-NEXT-VALUE" + } + return "UNKNOWN-PARSE-CONTEXT" +} + +// JSON protocol implementation for thrift. +// +// This protocol produces/consumes a simple output format +// suitable for parsing by scripting languages. It should not be +// confused with the full-featured TJSONProtocol. +// +type TSimpleJSONProtocol struct { + trans TTransport + + parseContextStack []int + dumpContext []int + + writer *bufio.Writer + reader *bufio.Reader +} + +// Constructor +func NewTSimpleJSONProtocol(t TTransport) *TSimpleJSONProtocol { + v := &TSimpleJSONProtocol{trans: t, + writer: bufio.NewWriter(t), + reader: bufio.NewReader(t), + } + v.parseContextStack = append(v.parseContextStack, int(_CONTEXT_IN_TOPLEVEL)) + v.dumpContext = append(v.dumpContext, int(_CONTEXT_IN_TOPLEVEL)) + return v +} + +// Factory +type TSimpleJSONProtocolFactory struct{} + +func (p *TSimpleJSONProtocolFactory) GetProtocol(trans TTransport) TProtocol { + return NewTSimpleJSONProtocol(trans) +} + +func NewTSimpleJSONProtocolFactory() *TSimpleJSONProtocolFactory { + return &TSimpleJSONProtocolFactory{} +} + +var ( + JSON_COMMA []byte + JSON_COLON []byte + JSON_LBRACE []byte + JSON_RBRACE []byte + JSON_LBRACKET []byte + JSON_RBRACKET []byte + JSON_QUOTE byte + JSON_QUOTE_BYTES []byte + JSON_NULL []byte + JSON_TRUE []byte + JSON_FALSE []byte + JSON_INFINITY string + JSON_NEGATIVE_INFINITY string + JSON_NAN string + JSON_INFINITY_BYTES []byte + JSON_NEGATIVE_INFINITY_BYTES []byte + JSON_NAN_BYTES []byte + json_nonbase_map_elem_bytes []byte +) + +func init() { + JSON_COMMA = []byte{','} + JSON_COLON = []byte{':'} + JSON_LBRACE = []byte{'{'} + JSON_RBRACE = []byte{'}'} + JSON_LBRACKET = []byte{'['} + JSON_RBRACKET = []byte{']'} + JSON_QUOTE = '"' + JSON_QUOTE_BYTES = []byte{'"'} + JSON_NULL = []byte{'n', 'u', 'l', 'l'} + JSON_TRUE = []byte{'t', 'r', 'u', 'e'} + JSON_FALSE = []byte{'f', 'a', 'l', 's', 'e'} + JSON_INFINITY = "Infinity" + JSON_NEGATIVE_INFINITY = "-Infinity" + JSON_NAN = "NaN" + JSON_INFINITY_BYTES = []byte{'I', 'n', 'f', 'i', 'n', 'i', 't', 'y'} + JSON_NEGATIVE_INFINITY_BYTES = []byte{'-', 'I', 'n', 'f', 'i', 'n', 'i', 't', 'y'} + JSON_NAN_BYTES = []byte{'N', 'a', 'N'} + json_nonbase_map_elem_bytes = []byte{']', ',', '['} +} + +func jsonQuote(s string) string { + b, _ := json.Marshal(s) + s1 := string(b) + return s1 +} + +func jsonUnquote(s string) (string, bool) { + s1 := new(string) + err := json.Unmarshal([]byte(s), s1) + return *s1, err == nil +} + +func mismatch(expected, actual string) error { + return fmt.Errorf("Expected '%s' but found '%s' while parsing JSON.", expected, actual) +} + +func (p *TSimpleJSONProtocol) WriteMessageBegin(name string, typeId TMessageType, seqId int32) error { + p.resetContextStack() // THRIFT-3735 + if e := p.OutputListBegin(); e != nil { + return e + } + if e := p.WriteString(name); e != nil { + return e + } + if e := p.WriteByte(int8(typeId)); e != nil { + return e + } + if e := p.WriteI32(seqId); e != nil { + return e + } + return nil +} + +func (p *TSimpleJSONProtocol) WriteMessageEnd() error { + return p.OutputListEnd() +} + +func (p *TSimpleJSONProtocol) WriteStructBegin(name string) error { + if e := p.OutputObjectBegin(); e != nil { + return e + } + return nil +} + +func (p *TSimpleJSONProtocol) WriteStructEnd() error { + return p.OutputObjectEnd() +} + +func (p *TSimpleJSONProtocol) WriteFieldBegin(name string, typeId TType, id int16) error { + if e := p.WriteString(name); e != nil { + return e + } + return nil +} + +func (p *TSimpleJSONProtocol) WriteFieldEnd() error { + //return p.OutputListEnd() + return nil +} + +func (p *TSimpleJSONProtocol) WriteFieldStop() error { return nil } + +func (p *TSimpleJSONProtocol) WriteMapBegin(keyType TType, valueType TType, size int) error { + if e := p.OutputListBegin(); e != nil { + return e + } + if e := p.WriteByte(int8(keyType)); e != nil { + return e + } + if e := p.WriteByte(int8(valueType)); e != nil { + return e + } + return p.WriteI32(int32(size)) +} + +func (p *TSimpleJSONProtocol) WriteMapEnd() error { + return p.OutputListEnd() +} + +func (p *TSimpleJSONProtocol) WriteListBegin(elemType TType, size int) error { + return p.OutputElemListBegin(elemType, size) +} + +func (p *TSimpleJSONProtocol) WriteListEnd() error { + return p.OutputListEnd() +} + +func (p *TSimpleJSONProtocol) WriteSetBegin(elemType TType, size int) error { + return p.OutputElemListBegin(elemType, size) +} + +func (p *TSimpleJSONProtocol) WriteSetEnd() error { + return p.OutputListEnd() +} + +func (p *TSimpleJSONProtocol) WriteBool(b bool) error { + return p.OutputBool(b) +} + +func (p *TSimpleJSONProtocol) WriteByte(b int8) error { + return p.WriteI32(int32(b)) +} + +func (p *TSimpleJSONProtocol) WriteI16(v int16) error { + return p.WriteI32(int32(v)) +} + +func (p *TSimpleJSONProtocol) WriteI32(v int32) error { + return p.OutputI64(int64(v)) +} + +func (p *TSimpleJSONProtocol) WriteI64(v int64) error { + return p.OutputI64(int64(v)) +} + +func (p *TSimpleJSONProtocol) WriteDouble(v float64) error { + return p.OutputF64(v) +} + +func (p *TSimpleJSONProtocol) WriteString(v string) error { + return p.OutputString(v) +} + +func (p *TSimpleJSONProtocol) WriteBinary(v []byte) error { + // JSON library only takes in a string, + // not an arbitrary byte array, to ensure bytes are transmitted + // efficiently we must convert this into a valid JSON string + // therefore we use base64 encoding to avoid excessive escaping/quoting + if e := p.OutputPreValue(); e != nil { + return e + } + if _, e := p.write(JSON_QUOTE_BYTES); e != nil { + return NewTProtocolException(e) + } + writer := base64.NewEncoder(base64.StdEncoding, p.writer) + if _, e := writer.Write(v); e != nil { + p.writer.Reset(p.trans) // THRIFT-3735 + return NewTProtocolException(e) + } + if e := writer.Close(); e != nil { + return NewTProtocolException(e) + } + if _, e := p.write(JSON_QUOTE_BYTES); e != nil { + return NewTProtocolException(e) + } + return p.OutputPostValue() +} + +// Reading methods. +func (p *TSimpleJSONProtocol) ReadMessageBegin() (name string, typeId TMessageType, seqId int32, err error) { + p.resetContextStack() // THRIFT-3735 + if isNull, err := p.ParseListBegin(); isNull || err != nil { + return name, typeId, seqId, err + } + if name, err = p.ReadString(); err != nil { + return name, typeId, seqId, err + } + bTypeId, err := p.ReadByte() + typeId = TMessageType(bTypeId) + if err != nil { + return name, typeId, seqId, err + } + if seqId, err = p.ReadI32(); err != nil { + return name, typeId, seqId, err + } + return name, typeId, seqId, nil +} + +func (p *TSimpleJSONProtocol) ReadMessageEnd() error { + return p.ParseListEnd() +} + +func (p *TSimpleJSONProtocol) ReadStructBegin() (name string, err error) { + _, err = p.ParseObjectStart() + return "", err +} + +func (p *TSimpleJSONProtocol) ReadStructEnd() error { + return p.ParseObjectEnd() +} + +func (p *TSimpleJSONProtocol) ReadFieldBegin() (string, TType, int16, error) { + if err := p.ParsePreValue(); err != nil { + return "", STOP, 0, err + } + b, _ := p.reader.Peek(1) + if len(b) > 0 { + switch b[0] { + case JSON_RBRACE[0]: + return "", STOP, 0, nil + case JSON_QUOTE: + p.reader.ReadByte() + name, err := p.ParseStringBody() + // simplejson is not meant to be read back into thrift + // - see http://wiki.apache.org/thrift/ThriftUsageJava + // - use JSON instead + if err != nil { + return name, STOP, 0, err + } + return name, STOP, -1, p.ParsePostValue() + /* + if err = p.ParsePostValue(); err != nil { + return name, STOP, 0, err + } + if isNull, err := p.ParseListBegin(); isNull || err != nil { + return name, STOP, 0, err + } + bType, err := p.ReadByte() + thetype := TType(bType) + if err != nil { + return name, thetype, 0, err + } + id, err := p.ReadI16() + return name, thetype, id, err + */ + } + e := fmt.Errorf("Expected \"}\" or '\"', but found: '%s'", string(b)) + return "", STOP, 0, NewTProtocolExceptionWithType(INVALID_DATA, e) + } + return "", STOP, 0, NewTProtocolException(io.EOF) +} + +func (p *TSimpleJSONProtocol) ReadFieldEnd() error { + return nil + //return p.ParseListEnd() +} + +func (p *TSimpleJSONProtocol) ReadMapBegin() (keyType TType, valueType TType, size int, e error) { + if isNull, e := p.ParseListBegin(); isNull || e != nil { + return VOID, VOID, 0, e + } + + // read keyType + bKeyType, e := p.ReadByte() + keyType = TType(bKeyType) + if e != nil { + return keyType, valueType, size, e + } + + // read valueType + bValueType, e := p.ReadByte() + valueType = TType(bValueType) + if e != nil { + return keyType, valueType, size, e + } + + // read size + iSize, err := p.ReadI64() + size = int(iSize) + return keyType, valueType, size, err +} + +func (p *TSimpleJSONProtocol) ReadMapEnd() error { + return p.ParseListEnd() +} + +func (p *TSimpleJSONProtocol) ReadListBegin() (elemType TType, size int, e error) { + return p.ParseElemListBegin() +} + +func (p *TSimpleJSONProtocol) ReadListEnd() error { + return p.ParseListEnd() +} + +func (p *TSimpleJSONProtocol) ReadSetBegin() (elemType TType, size int, e error) { + return p.ParseElemListBegin() +} + +func (p *TSimpleJSONProtocol) ReadSetEnd() error { + return p.ParseListEnd() +} + +func (p *TSimpleJSONProtocol) ReadBool() (bool, error) { + var value bool + + if err := p.ParsePreValue(); err != nil { + return value, err + } + f, _ := p.reader.Peek(1) + if len(f) > 0 { + switch f[0] { + case JSON_TRUE[0]: + b := make([]byte, len(JSON_TRUE)) + _, err := p.reader.Read(b) + if err != nil { + return false, NewTProtocolException(err) + } + if string(b) == string(JSON_TRUE) { + value = true + } else { + e := fmt.Errorf("Expected \"true\" but found: %s", string(b)) + return value, NewTProtocolExceptionWithType(INVALID_DATA, e) + } + break + case JSON_FALSE[0]: + b := make([]byte, len(JSON_FALSE)) + _, err := p.reader.Read(b) + if err != nil { + return false, NewTProtocolException(err) + } + if string(b) == string(JSON_FALSE) { + value = false + } else { + e := fmt.Errorf("Expected \"false\" but found: %s", string(b)) + return value, NewTProtocolExceptionWithType(INVALID_DATA, e) + } + break + case JSON_NULL[0]: + b := make([]byte, len(JSON_NULL)) + _, err := p.reader.Read(b) + if err != nil { + return false, NewTProtocolException(err) + } + if string(b) == string(JSON_NULL) { + value = false + } else { + e := fmt.Errorf("Expected \"null\" but found: %s", string(b)) + return value, NewTProtocolExceptionWithType(INVALID_DATA, e) + } + default: + e := fmt.Errorf("Expected \"true\", \"false\", or \"null\" but found: %s", string(f)) + return value, NewTProtocolExceptionWithType(INVALID_DATA, e) + } + } + return value, p.ParsePostValue() +} + +func (p *TSimpleJSONProtocol) ReadByte() (int8, error) { + v, err := p.ReadI64() + return int8(v), err +} + +func (p *TSimpleJSONProtocol) ReadI16() (int16, error) { + v, err := p.ReadI64() + return int16(v), err +} + +func (p *TSimpleJSONProtocol) ReadI32() (int32, error) { + v, err := p.ReadI64() + return int32(v), err +} + +func (p *TSimpleJSONProtocol) ReadI64() (int64, error) { + v, _, err := p.ParseI64() + return v, err +} + +func (p *TSimpleJSONProtocol) ReadDouble() (float64, error) { + v, _, err := p.ParseF64() + return v, err +} + +func (p *TSimpleJSONProtocol) ReadString() (string, error) { + var v string + if err := p.ParsePreValue(); err != nil { + return v, err + } + f, _ := p.reader.Peek(1) + if len(f) > 0 && f[0] == JSON_QUOTE { + p.reader.ReadByte() + value, err := p.ParseStringBody() + v = value + if err != nil { + return v, err + } + } else if len(f) > 0 && f[0] == JSON_NULL[0] { + b := make([]byte, len(JSON_NULL)) + _, err := p.reader.Read(b) + if err != nil { + return v, NewTProtocolException(err) + } + if string(b) != string(JSON_NULL) { + e := fmt.Errorf("Expected a JSON string, found unquoted data started with %s", string(b)) + return v, NewTProtocolExceptionWithType(INVALID_DATA, e) + } + } else { + e := fmt.Errorf("Expected a JSON string, found unquoted data started with %s", string(f)) + return v, NewTProtocolExceptionWithType(INVALID_DATA, e) + } + return v, p.ParsePostValue() +} + +func (p *TSimpleJSONProtocol) ReadBinary() ([]byte, error) { + var v []byte + if err := p.ParsePreValue(); err != nil { + return nil, err + } + f, _ := p.reader.Peek(1) + if len(f) > 0 && f[0] == JSON_QUOTE { + p.reader.ReadByte() + value, err := p.ParseBase64EncodedBody() + v = value + if err != nil { + return v, err + } + } else if len(f) > 0 && f[0] == JSON_NULL[0] { + b := make([]byte, len(JSON_NULL)) + _, err := p.reader.Read(b) + if err != nil { + return v, NewTProtocolException(err) + } + if string(b) != string(JSON_NULL) { + e := fmt.Errorf("Expected a JSON string, found unquoted data started with %s", string(b)) + return v, NewTProtocolExceptionWithType(INVALID_DATA, e) + } + } else { + e := fmt.Errorf("Expected a JSON string, found unquoted data started with %s", string(f)) + return v, NewTProtocolExceptionWithType(INVALID_DATA, e) + } + + return v, p.ParsePostValue() +} + +func (p *TSimpleJSONProtocol) Flush() (err error) { + return NewTProtocolException(p.writer.Flush()) +} + +func (p *TSimpleJSONProtocol) Skip(fieldType TType) (err error) { + return SkipDefaultDepth(p, fieldType) +} + +func (p *TSimpleJSONProtocol) Transport() TTransport { + return p.trans +} + +func (p *TSimpleJSONProtocol) OutputPreValue() error { + cxt := _ParseContext(p.dumpContext[len(p.dumpContext)-1]) + switch cxt { + case _CONTEXT_IN_LIST, _CONTEXT_IN_OBJECT_NEXT_KEY: + if _, e := p.write(JSON_COMMA); e != nil { + return NewTProtocolException(e) + } + break + case _CONTEXT_IN_OBJECT_NEXT_VALUE: + if _, e := p.write(JSON_COLON); e != nil { + return NewTProtocolException(e) + } + break + } + return nil +} + +func (p *TSimpleJSONProtocol) OutputPostValue() error { + cxt := _ParseContext(p.dumpContext[len(p.dumpContext)-1]) + switch cxt { + case _CONTEXT_IN_LIST_FIRST: + p.dumpContext = p.dumpContext[:len(p.dumpContext)-1] + p.dumpContext = append(p.dumpContext, int(_CONTEXT_IN_LIST)) + break + case _CONTEXT_IN_OBJECT_FIRST: + p.dumpContext = p.dumpContext[:len(p.dumpContext)-1] + p.dumpContext = append(p.dumpContext, int(_CONTEXT_IN_OBJECT_NEXT_VALUE)) + break + case _CONTEXT_IN_OBJECT_NEXT_KEY: + p.dumpContext = p.dumpContext[:len(p.dumpContext)-1] + p.dumpContext = append(p.dumpContext, int(_CONTEXT_IN_OBJECT_NEXT_VALUE)) + break + case _CONTEXT_IN_OBJECT_NEXT_VALUE: + p.dumpContext = p.dumpContext[:len(p.dumpContext)-1] + p.dumpContext = append(p.dumpContext, int(_CONTEXT_IN_OBJECT_NEXT_KEY)) + break + } + return nil +} + +func (p *TSimpleJSONProtocol) OutputBool(value bool) error { + if e := p.OutputPreValue(); e != nil { + return e + } + var v string + if value { + v = string(JSON_TRUE) + } else { + v = string(JSON_FALSE) + } + switch _ParseContext(p.dumpContext[len(p.dumpContext)-1]) { + case _CONTEXT_IN_OBJECT_FIRST, _CONTEXT_IN_OBJECT_NEXT_KEY: + v = jsonQuote(v) + default: + } + if e := p.OutputStringData(v); e != nil { + return e + } + return p.OutputPostValue() +} + +func (p *TSimpleJSONProtocol) OutputNull() error { + if e := p.OutputPreValue(); e != nil { + return e + } + if _, e := p.write(JSON_NULL); e != nil { + return NewTProtocolException(e) + } + return p.OutputPostValue() +} + +func (p *TSimpleJSONProtocol) OutputF64(value float64) error { + if e := p.OutputPreValue(); e != nil { + return e + } + var v string + if math.IsNaN(value) { + v = string(JSON_QUOTE) + JSON_NAN + string(JSON_QUOTE) + } else if math.IsInf(value, 1) { + v = string(JSON_QUOTE) + JSON_INFINITY + string(JSON_QUOTE) + } else if math.IsInf(value, -1) { + v = string(JSON_QUOTE) + JSON_NEGATIVE_INFINITY + string(JSON_QUOTE) + } else { + v = strconv.FormatFloat(value, 'g', -1, 64) + switch _ParseContext(p.dumpContext[len(p.dumpContext)-1]) { + case _CONTEXT_IN_OBJECT_FIRST, _CONTEXT_IN_OBJECT_NEXT_KEY: + v = string(JSON_QUOTE) + v + string(JSON_QUOTE) + default: + } + } + if e := p.OutputStringData(v); e != nil { + return e + } + return p.OutputPostValue() +} + +func (p *TSimpleJSONProtocol) OutputI64(value int64) error { + if e := p.OutputPreValue(); e != nil { + return e + } + v := strconv.FormatInt(value, 10) + switch _ParseContext(p.dumpContext[len(p.dumpContext)-1]) { + case _CONTEXT_IN_OBJECT_FIRST, _CONTEXT_IN_OBJECT_NEXT_KEY: + v = jsonQuote(v) + default: + } + if e := p.OutputStringData(v); e != nil { + return e + } + return p.OutputPostValue() +} + +func (p *TSimpleJSONProtocol) OutputString(s string) error { + if e := p.OutputPreValue(); e != nil { + return e + } + if e := p.OutputStringData(jsonQuote(s)); e != nil { + return e + } + return p.OutputPostValue() +} + +func (p *TSimpleJSONProtocol) OutputStringData(s string) error { + _, e := p.write([]byte(s)) + return NewTProtocolException(e) +} + +func (p *TSimpleJSONProtocol) OutputObjectBegin() error { + if e := p.OutputPreValue(); e != nil { + return e + } + if _, e := p.write(JSON_LBRACE); e != nil { + return NewTProtocolException(e) + } + p.dumpContext = append(p.dumpContext, int(_CONTEXT_IN_OBJECT_FIRST)) + return nil +} + +func (p *TSimpleJSONProtocol) OutputObjectEnd() error { + if _, e := p.write(JSON_RBRACE); e != nil { + return NewTProtocolException(e) + } + p.dumpContext = p.dumpContext[:len(p.dumpContext)-1] + if e := p.OutputPostValue(); e != nil { + return e + } + return nil +} + +func (p *TSimpleJSONProtocol) OutputListBegin() error { + if e := p.OutputPreValue(); e != nil { + return e + } + if _, e := p.write(JSON_LBRACKET); e != nil { + return NewTProtocolException(e) + } + p.dumpContext = append(p.dumpContext, int(_CONTEXT_IN_LIST_FIRST)) + return nil +} + +func (p *TSimpleJSONProtocol) OutputListEnd() error { + if _, e := p.write(JSON_RBRACKET); e != nil { + return NewTProtocolException(e) + } + p.dumpContext = p.dumpContext[:len(p.dumpContext)-1] + if e := p.OutputPostValue(); e != nil { + return e + } + return nil +} + +func (p *TSimpleJSONProtocol) OutputElemListBegin(elemType TType, size int) error { + if e := p.OutputListBegin(); e != nil { + return e + } + if e := p.WriteByte(int8(elemType)); e != nil { + return e + } + if e := p.WriteI64(int64(size)); e != nil { + return e + } + return nil +} + +func (p *TSimpleJSONProtocol) ParsePreValue() error { + if e := p.readNonSignificantWhitespace(); e != nil { + return NewTProtocolException(e) + } + cxt := _ParseContext(p.parseContextStack[len(p.parseContextStack)-1]) + b, _ := p.reader.Peek(1) + switch cxt { + case _CONTEXT_IN_LIST: + if len(b) > 0 { + switch b[0] { + case JSON_RBRACKET[0]: + return nil + case JSON_COMMA[0]: + p.reader.ReadByte() + if e := p.readNonSignificantWhitespace(); e != nil { + return NewTProtocolException(e) + } + return nil + default: + e := fmt.Errorf("Expected \"]\" or \",\" in list context, but found \"%s\"", string(b)) + return NewTProtocolExceptionWithType(INVALID_DATA, e) + } + } + break + case _CONTEXT_IN_OBJECT_NEXT_KEY: + if len(b) > 0 { + switch b[0] { + case JSON_RBRACE[0]: + return nil + case JSON_COMMA[0]: + p.reader.ReadByte() + if e := p.readNonSignificantWhitespace(); e != nil { + return NewTProtocolException(e) + } + return nil + default: + e := fmt.Errorf("Expected \"}\" or \",\" in object context, but found \"%s\"", string(b)) + return NewTProtocolExceptionWithType(INVALID_DATA, e) + } + } + break + case _CONTEXT_IN_OBJECT_NEXT_VALUE: + if len(b) > 0 { + switch b[0] { + case JSON_COLON[0]: + p.reader.ReadByte() + if e := p.readNonSignificantWhitespace(); e != nil { + return NewTProtocolException(e) + } + return nil + default: + e := fmt.Errorf("Expected \":\" in object context, but found \"%s\"", string(b)) + return NewTProtocolExceptionWithType(INVALID_DATA, e) + } + } + break + } + return nil +} + +func (p *TSimpleJSONProtocol) ParsePostValue() error { + if e := p.readNonSignificantWhitespace(); e != nil { + return NewTProtocolException(e) + } + cxt := _ParseContext(p.parseContextStack[len(p.parseContextStack)-1]) + switch cxt { + case _CONTEXT_IN_LIST_FIRST: + p.parseContextStack = p.parseContextStack[:len(p.parseContextStack)-1] + p.parseContextStack = append(p.parseContextStack, int(_CONTEXT_IN_LIST)) + break + case _CONTEXT_IN_OBJECT_FIRST, _CONTEXT_IN_OBJECT_NEXT_KEY: + p.parseContextStack = p.parseContextStack[:len(p.parseContextStack)-1] + p.parseContextStack = append(p.parseContextStack, int(_CONTEXT_IN_OBJECT_NEXT_VALUE)) + break + case _CONTEXT_IN_OBJECT_NEXT_VALUE: + p.parseContextStack = p.parseContextStack[:len(p.parseContextStack)-1] + p.parseContextStack = append(p.parseContextStack, int(_CONTEXT_IN_OBJECT_NEXT_KEY)) + break + } + return nil +} + +func (p *TSimpleJSONProtocol) readNonSignificantWhitespace() error { + for { + b, _ := p.reader.Peek(1) + if len(b) < 1 { + return nil + } + switch b[0] { + case ' ', '\r', '\n', '\t': + p.reader.ReadByte() + continue + default: + break + } + break + } + return nil +} + +func (p *TSimpleJSONProtocol) ParseStringBody() (string, error) { + line, err := p.reader.ReadString(JSON_QUOTE) + if err != nil { + return "", NewTProtocolException(err) + } + l := len(line) + // count number of escapes to see if we need to keep going + i := 1 + for ; i < l; i++ { + if line[l-i-1] != '\\' { + break + } + } + if i&0x01 == 1 { + v, ok := jsonUnquote(string(JSON_QUOTE) + line) + if !ok { + return "", NewTProtocolException(err) + } + return v, nil + } + s, err := p.ParseQuotedStringBody() + if err != nil { + return "", NewTProtocolException(err) + } + str := string(JSON_QUOTE) + line + s + v, ok := jsonUnquote(str) + if !ok { + e := fmt.Errorf("Unable to parse as JSON string %s", str) + return "", NewTProtocolExceptionWithType(INVALID_DATA, e) + } + return v, nil +} + +func (p *TSimpleJSONProtocol) ParseQuotedStringBody() (string, error) { + line, err := p.reader.ReadString(JSON_QUOTE) + if err != nil { + return "", NewTProtocolException(err) + } + l := len(line) + // count number of escapes to see if we need to keep going + i := 1 + for ; i < l; i++ { + if line[l-i-1] != '\\' { + break + } + } + if i&0x01 == 1 { + return line, nil + } + s, err := p.ParseQuotedStringBody() + if err != nil { + return "", NewTProtocolException(err) + } + v := line + s + return v, nil +} + +func (p *TSimpleJSONProtocol) ParseBase64EncodedBody() ([]byte, error) { + line, err := p.reader.ReadBytes(JSON_QUOTE) + if err != nil { + return line, NewTProtocolException(err) + } + line2 := line[0 : len(line)-1] + l := len(line2) + if (l % 4) != 0 { + pad := 4 - (l % 4) + fill := [...]byte{'=', '=', '='} + line2 = append(line2, fill[:pad]...) + l = len(line2) + } + output := make([]byte, base64.StdEncoding.DecodedLen(l)) + n, err := base64.StdEncoding.Decode(output, line2) + return output[0:n], NewTProtocolException(err) +} + +func (p *TSimpleJSONProtocol) ParseI64() (int64, bool, error) { + if err := p.ParsePreValue(); err != nil { + return 0, false, err + } + var value int64 + var isnull bool + if p.safePeekContains(JSON_NULL) { + p.reader.Read(make([]byte, len(JSON_NULL))) + isnull = true + } else { + num, err := p.readNumeric() + isnull = (num == nil) + if !isnull { + value = num.Int64() + } + if err != nil { + return value, isnull, err + } + } + return value, isnull, p.ParsePostValue() +} + +func (p *TSimpleJSONProtocol) ParseF64() (float64, bool, error) { + if err := p.ParsePreValue(); err != nil { + return 0, false, err + } + var value float64 + var isnull bool + if p.safePeekContains(JSON_NULL) { + p.reader.Read(make([]byte, len(JSON_NULL))) + isnull = true + } else { + num, err := p.readNumeric() + isnull = (num == nil) + if !isnull { + value = num.Float64() + } + if err != nil { + return value, isnull, err + } + } + return value, isnull, p.ParsePostValue() +} + +func (p *TSimpleJSONProtocol) ParseObjectStart() (bool, error) { + if err := p.ParsePreValue(); err != nil { + return false, err + } + var b []byte + b, err := p.reader.Peek(1) + if err != nil { + return false, err + } + if len(b) > 0 && b[0] == JSON_LBRACE[0] { + p.reader.ReadByte() + p.parseContextStack = append(p.parseContextStack, int(_CONTEXT_IN_OBJECT_FIRST)) + return false, nil + } else if p.safePeekContains(JSON_NULL) { + return true, nil + } + e := fmt.Errorf("Expected '{' or null, but found '%s'", string(b)) + return false, NewTProtocolExceptionWithType(INVALID_DATA, e) +} + +func (p *TSimpleJSONProtocol) ParseObjectEnd() error { + if isNull, err := p.readIfNull(); isNull || err != nil { + return err + } + cxt := _ParseContext(p.parseContextStack[len(p.parseContextStack)-1]) + if (cxt != _CONTEXT_IN_OBJECT_FIRST) && (cxt != _CONTEXT_IN_OBJECT_NEXT_KEY) { + e := fmt.Errorf("Expected to be in the Object Context, but not in Object Context (%d)", cxt) + return NewTProtocolExceptionWithType(INVALID_DATA, e) + } + line, err := p.reader.ReadString(JSON_RBRACE[0]) + if err != nil { + return NewTProtocolException(err) + } + for _, char := range line { + switch char { + default: + e := fmt.Errorf("Expecting end of object \"}\", but found: \"%s\"", line) + return NewTProtocolExceptionWithType(INVALID_DATA, e) + case ' ', '\n', '\r', '\t', '}': + break + } + } + p.parseContextStack = p.parseContextStack[:len(p.parseContextStack)-1] + return p.ParsePostValue() +} + +func (p *TSimpleJSONProtocol) ParseListBegin() (isNull bool, err error) { + if e := p.ParsePreValue(); e != nil { + return false, e + } + var b []byte + b, err = p.reader.Peek(1) + if err != nil { + return false, err + } + if len(b) >= 1 && b[0] == JSON_LBRACKET[0] { + p.parseContextStack = append(p.parseContextStack, int(_CONTEXT_IN_LIST_FIRST)) + p.reader.ReadByte() + isNull = false + } else if p.safePeekContains(JSON_NULL) { + isNull = true + } else { + err = fmt.Errorf("Expected \"null\" or \"[\", received %q", b) + } + return isNull, NewTProtocolExceptionWithType(INVALID_DATA, err) +} + +func (p *TSimpleJSONProtocol) ParseElemListBegin() (elemType TType, size int, e error) { + if isNull, e := p.ParseListBegin(); isNull || e != nil { + return VOID, 0, e + } + bElemType, err := p.ReadByte() + elemType = TType(bElemType) + if err != nil { + return elemType, size, err + } + nSize, err2 := p.ReadI64() + size = int(nSize) + return elemType, size, err2 +} + +func (p *TSimpleJSONProtocol) ParseListEnd() error { + if isNull, err := p.readIfNull(); isNull || err != nil { + return err + } + cxt := _ParseContext(p.parseContextStack[len(p.parseContextStack)-1]) + if cxt != _CONTEXT_IN_LIST { + e := fmt.Errorf("Expected to be in the List Context, but not in List Context (%d)", cxt) + return NewTProtocolExceptionWithType(INVALID_DATA, e) + } + line, err := p.reader.ReadString(JSON_RBRACKET[0]) + if err != nil { + return NewTProtocolException(err) + } + for _, char := range line { + switch char { + default: + e := fmt.Errorf("Expecting end of list \"]\", but found: \"%s\"", line) + return NewTProtocolExceptionWithType(INVALID_DATA, e) + case ' ', '\n', '\r', '\t', rune(JSON_RBRACKET[0]): + break + } + } + p.parseContextStack = p.parseContextStack[:len(p.parseContextStack)-1] + if _ParseContext(p.parseContextStack[len(p.parseContextStack)-1]) == _CONTEXT_IN_TOPLEVEL { + return nil + } + return p.ParsePostValue() +} + +func (p *TSimpleJSONProtocol) readSingleValue() (interface{}, TType, error) { + e := p.readNonSignificantWhitespace() + if e != nil { + return nil, VOID, NewTProtocolException(e) + } + b, e := p.reader.Peek(1) + if len(b) > 0 { + c := b[0] + switch c { + case JSON_NULL[0]: + buf := make([]byte, len(JSON_NULL)) + _, e := p.reader.Read(buf) + if e != nil { + return nil, VOID, NewTProtocolException(e) + } + if string(JSON_NULL) != string(buf) { + e = mismatch(string(JSON_NULL), string(buf)) + return nil, VOID, NewTProtocolExceptionWithType(INVALID_DATA, e) + } + return nil, VOID, nil + case JSON_QUOTE: + p.reader.ReadByte() + v, e := p.ParseStringBody() + if e != nil { + return v, UTF8, NewTProtocolException(e) + } + if v == JSON_INFINITY { + return INFINITY, DOUBLE, nil + } else if v == JSON_NEGATIVE_INFINITY { + return NEGATIVE_INFINITY, DOUBLE, nil + } else if v == JSON_NAN { + return NAN, DOUBLE, nil + } + return v, UTF8, nil + case JSON_TRUE[0]: + buf := make([]byte, len(JSON_TRUE)) + _, e := p.reader.Read(buf) + if e != nil { + return true, BOOL, NewTProtocolException(e) + } + if string(JSON_TRUE) != string(buf) { + e := mismatch(string(JSON_TRUE), string(buf)) + return true, BOOL, NewTProtocolExceptionWithType(INVALID_DATA, e) + } + return true, BOOL, nil + case JSON_FALSE[0]: + buf := make([]byte, len(JSON_FALSE)) + _, e := p.reader.Read(buf) + if e != nil { + return false, BOOL, NewTProtocolException(e) + } + if string(JSON_FALSE) != string(buf) { + e := mismatch(string(JSON_FALSE), string(buf)) + return false, BOOL, NewTProtocolExceptionWithType(INVALID_DATA, e) + } + return false, BOOL, nil + case JSON_LBRACKET[0]: + _, e := p.reader.ReadByte() + return make([]interface{}, 0), LIST, NewTProtocolException(e) + case JSON_LBRACE[0]: + _, e := p.reader.ReadByte() + return make(map[string]interface{}), STRUCT, NewTProtocolException(e) + case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'e', 'E', '.', '+', '-', JSON_INFINITY[0], JSON_NAN[0]: + // assume numeric + v, e := p.readNumeric() + return v, DOUBLE, e + default: + e := fmt.Errorf("Expected element in list but found '%s' while parsing JSON.", string(c)) + return nil, VOID, NewTProtocolExceptionWithType(INVALID_DATA, e) + } + } + e = fmt.Errorf("Cannot read a single element while parsing JSON.") + return nil, VOID, NewTProtocolExceptionWithType(INVALID_DATA, e) + +} + +func (p *TSimpleJSONProtocol) readIfNull() (bool, error) { + cont := true + for cont { + b, _ := p.reader.Peek(1) + if len(b) < 1 { + return false, nil + } + switch b[0] { + default: + return false, nil + case JSON_NULL[0]: + cont = false + break + case ' ', '\n', '\r', '\t': + p.reader.ReadByte() + break + } + } + if p.safePeekContains(JSON_NULL) { + p.reader.Read(make([]byte, len(JSON_NULL))) + return true, nil + } + return false, nil +} + +func (p *TSimpleJSONProtocol) readQuoteIfNext() { + b, _ := p.reader.Peek(1) + if len(b) > 0 && b[0] == JSON_QUOTE { + p.reader.ReadByte() + } +} + +func (p *TSimpleJSONProtocol) readNumeric() (Numeric, error) { + isNull, err := p.readIfNull() + if isNull || err != nil { + return NUMERIC_NULL, err + } + hasDecimalPoint := false + nextCanBeSign := true + hasE := false + MAX_LEN := 40 + buf := bytes.NewBuffer(make([]byte, 0, MAX_LEN)) + continueFor := true + inQuotes := false + for continueFor { + c, err := p.reader.ReadByte() + if err != nil { + if err == io.EOF { + break + } + return NUMERIC_NULL, NewTProtocolException(err) + } + switch c { + case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + buf.WriteByte(c) + nextCanBeSign = false + case '.': + if hasDecimalPoint { + e := fmt.Errorf("Unable to parse number with multiple decimal points '%s.'", buf.String()) + return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e) + } + if hasE { + e := fmt.Errorf("Unable to parse number with decimal points in the exponent '%s.'", buf.String()) + return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e) + } + buf.WriteByte(c) + hasDecimalPoint, nextCanBeSign = true, false + case 'e', 'E': + if hasE { + e := fmt.Errorf("Unable to parse number with multiple exponents '%s%c'", buf.String(), c) + return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e) + } + buf.WriteByte(c) + hasE, nextCanBeSign = true, true + case '-', '+': + if !nextCanBeSign { + e := fmt.Errorf("Negative sign within number") + return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e) + } + buf.WriteByte(c) + nextCanBeSign = false + case ' ', 0, '\t', '\n', '\r', JSON_RBRACE[0], JSON_RBRACKET[0], JSON_COMMA[0], JSON_COLON[0]: + p.reader.UnreadByte() + continueFor = false + case JSON_NAN[0]: + if buf.Len() == 0 { + buffer := make([]byte, len(JSON_NAN)) + buffer[0] = c + _, e := p.reader.Read(buffer[1:]) + if e != nil { + return NUMERIC_NULL, NewTProtocolException(e) + } + if JSON_NAN != string(buffer) { + e := mismatch(JSON_NAN, string(buffer)) + return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e) + } + if inQuotes { + p.readQuoteIfNext() + } + return NAN, nil + } else { + e := fmt.Errorf("Unable to parse number starting with character '%c'", c) + return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e) + } + case JSON_INFINITY[0]: + if buf.Len() == 0 || (buf.Len() == 1 && buf.Bytes()[0] == '+') { + buffer := make([]byte, len(JSON_INFINITY)) + buffer[0] = c + _, e := p.reader.Read(buffer[1:]) + if e != nil { + return NUMERIC_NULL, NewTProtocolException(e) + } + if JSON_INFINITY != string(buffer) { + e := mismatch(JSON_INFINITY, string(buffer)) + return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e) + } + if inQuotes { + p.readQuoteIfNext() + } + return INFINITY, nil + } else if buf.Len() == 1 && buf.Bytes()[0] == JSON_NEGATIVE_INFINITY[0] { + buffer := make([]byte, len(JSON_NEGATIVE_INFINITY)) + buffer[0] = JSON_NEGATIVE_INFINITY[0] + buffer[1] = c + _, e := p.reader.Read(buffer[2:]) + if e != nil { + return NUMERIC_NULL, NewTProtocolException(e) + } + if JSON_NEGATIVE_INFINITY != string(buffer) { + e := mismatch(JSON_NEGATIVE_INFINITY, string(buffer)) + return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e) + } + if inQuotes { + p.readQuoteIfNext() + } + return NEGATIVE_INFINITY, nil + } else { + e := fmt.Errorf("Unable to parse number starting with character '%c' due to existing buffer %s", c, buf.String()) + return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e) + } + case JSON_QUOTE: + if !inQuotes { + inQuotes = true + } else { + break + } + default: + e := fmt.Errorf("Unable to parse number starting with character '%c'", c) + return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e) + } + } + if buf.Len() == 0 { + e := fmt.Errorf("Unable to parse number from empty string ''") + return NUMERIC_NULL, NewTProtocolExceptionWithType(INVALID_DATA, e) + } + return NewNumericFromJSONString(buf.String(), false), nil +} + +// Safely peeks into the buffer, reading only what is necessary +func (p *TSimpleJSONProtocol) safePeekContains(b []byte) bool { + for i := 0; i < len(b); i++ { + a, _ := p.reader.Peek(i + 1) + if len(a) == 0 || a[i] != b[i] { + return false + } + } + return true +} + +// Reset the context stack to its initial state. +func (p *TSimpleJSONProtocol) resetContextStack() { + p.parseContextStack = []int{int(_CONTEXT_IN_TOPLEVEL)} + p.dumpContext = []int{int(_CONTEXT_IN_TOPLEVEL)} +} + +func (p *TSimpleJSONProtocol) write(b []byte) (int, error) { + n, err := p.writer.Write(b) + if err != nil { + p.writer.Reset(p.trans) // THRIFT-3735 + } + return n, err +} diff --git a/vendor/github.com/uber/jaeger-client-go/thrift/transport.go b/vendor/github.com/uber/jaeger-client-go/thrift/transport.go new file mode 100644 index 0000000000..453899651f --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/thrift/transport.go @@ -0,0 +1,68 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 thrift + +import ( + "errors" + "io" +) + +var errTransportInterrupted = errors.New("Transport Interrupted") + +type Flusher interface { + Flush() (err error) +} + +type ReadSizeProvider interface { + RemainingBytes() (num_bytes uint64) +} + + +// Encapsulates the I/O layer +type TTransport interface { + io.ReadWriteCloser + Flusher + ReadSizeProvider + + // Opens the transport for communication + Open() error + + // Returns true if the transport is open + IsOpen() bool +} + +type stringWriter interface { + WriteString(s string) (n int, err error) +} + + +// This is "enchanced" transport with extra capabilities. You need to use one of these +// to construct protocol. +// Notably, TSocket does not implement this interface, and it is always a mistake to use +// TSocket directly in protocol. +type TRichTransport interface { + io.ReadWriter + io.ByteReader + io.ByteWriter + stringWriter + Flusher + ReadSizeProvider +} + diff --git a/vendor/github.com/uber/jaeger-client-go/thrift/transport_exception.go b/vendor/github.com/uber/jaeger-client-go/thrift/transport_exception.go new file mode 100644 index 0000000000..9505b44612 --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/thrift/transport_exception.go @@ -0,0 +1,90 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 thrift + +import ( + "errors" + "io" +) + +type timeoutable interface { + Timeout() bool +} + +// Thrift Transport exception +type TTransportException interface { + TException + TypeId() int + Err() error +} + +const ( + UNKNOWN_TRANSPORT_EXCEPTION = 0 + NOT_OPEN = 1 + ALREADY_OPEN = 2 + TIMED_OUT = 3 + END_OF_FILE = 4 +) + +type tTransportException struct { + typeId int + err error +} + +func (p *tTransportException) TypeId() int { + return p.typeId +} + +func (p *tTransportException) Error() string { + return p.err.Error() +} + +func (p *tTransportException) Err() error { + return p.err +} + +func NewTTransportException(t int, e string) TTransportException { + return &tTransportException{typeId: t, err: errors.New(e)} +} + +func NewTTransportExceptionFromError(e error) TTransportException { + if e == nil { + return nil + } + + if t, ok := e.(TTransportException); ok { + return t + } + + switch v := e.(type) { + case TTransportException: + return v + case timeoutable: + if v.Timeout() { + return &tTransportException{typeId: TIMED_OUT, err: e} + } + } + + if e == io.EOF { + return &tTransportException{typeId: END_OF_FILE, err: e} + } + + return &tTransportException{typeId: UNKNOWN_TRANSPORT_EXCEPTION, err: e} +} diff --git a/vendor/github.com/uber/jaeger-client-go/thrift/transport_factory.go b/vendor/github.com/uber/jaeger-client-go/thrift/transport_factory.go new file mode 100644 index 0000000000..533d1b4375 --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/thrift/transport_factory.go @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 thrift + +// Factory class used to create wrapped instance of Transports. +// This is used primarily in servers, which get Transports from +// a ServerTransport and then may want to mutate them (i.e. create +// a BufferedTransport from the underlying base transport) +type TTransportFactory interface { + GetTransport(trans TTransport) TTransport +} + +type tTransportFactory struct{} + +// Return a wrapped instance of the base Transport. +func (p *tTransportFactory) GetTransport(trans TTransport) TTransport { + return trans +} + +func NewTTransportFactory() TTransportFactory { + return &tTransportFactory{} +} diff --git a/vendor/github.com/uber/jaeger-client-go/thrift/type.go b/vendor/github.com/uber/jaeger-client-go/thrift/type.go new file mode 100644 index 0000000000..4292ffcadb --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/thrift/type.go @@ -0,0 +1,69 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 thrift + +// Type constants in the Thrift protocol +type TType byte + +const ( + STOP = 0 + VOID = 1 + BOOL = 2 + BYTE = 3 + I08 = 3 + DOUBLE = 4 + I16 = 6 + I32 = 8 + I64 = 10 + STRING = 11 + UTF7 = 11 + STRUCT = 12 + MAP = 13 + SET = 14 + LIST = 15 + UTF8 = 16 + UTF16 = 17 + //BINARY = 18 wrong and unusued +) + +var typeNames = map[int]string{ + STOP: "STOP", + VOID: "VOID", + BOOL: "BOOL", + BYTE: "BYTE", + DOUBLE: "DOUBLE", + I16: "I16", + I32: "I32", + I64: "I64", + STRING: "STRING", + STRUCT: "STRUCT", + MAP: "MAP", + SET: "SET", + LIST: "LIST", + UTF8: "UTF8", + UTF16: "UTF16", +} + +func (p TType) String() string { + if s, ok := typeNames[int(p)]; ok { + return s + } + return "Unknown" +} diff --git a/vendor/github.com/uber/jaeger-client-go/tracer.go b/vendor/github.com/uber/jaeger-client-go/tracer.go new file mode 100644 index 0000000000..198c32eb4f --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/tracer.go @@ -0,0 +1,431 @@ +// Copyright (c) 2017-2018 Uber Technologies, Inc. +// +// 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 jaeger + +import ( + "fmt" + "io" + "os" + "reflect" + "strconv" + "sync" + "time" + + "github.com/opentracing/opentracing-go" + "github.com/opentracing/opentracing-go/ext" + + "github.com/uber/jaeger-client-go/internal/baggage" + "github.com/uber/jaeger-client-go/internal/throttler" + "github.com/uber/jaeger-client-go/log" + "github.com/uber/jaeger-client-go/utils" +) + +// Tracer implements opentracing.Tracer. +type Tracer struct { + serviceName string + hostIPv4 uint32 // this is for zipkin endpoint conversion + + sampler Sampler + reporter Reporter + metrics Metrics + logger log.Logger + + timeNow func() time.Time + randomNumber func() uint64 + + options struct { + poolSpans bool + gen128Bit bool // whether to generate 128bit trace IDs + zipkinSharedRPCSpan bool + highTraceIDGenerator func() uint64 // custom high trace ID generator + maxTagValueLength int + // more options to come + } + // pool for Span objects + spanPool sync.Pool + + injectors map[interface{}]Injector + extractors map[interface{}]Extractor + + observer compositeObserver + + tags []Tag + process Process + + baggageRestrictionManager baggage.RestrictionManager + baggageSetter *baggageSetter + + debugThrottler throttler.Throttler +} + +// NewTracer creates Tracer implementation that reports tracing to Jaeger. +// The returned io.Closer can be used in shutdown hooks to ensure that the internal +// queue of the Reporter is drained and all buffered spans are submitted to collectors. +func NewTracer( + serviceName string, + sampler Sampler, + reporter Reporter, + options ...TracerOption, +) (opentracing.Tracer, io.Closer) { + t := &Tracer{ + serviceName: serviceName, + sampler: sampler, + reporter: reporter, + injectors: make(map[interface{}]Injector), + extractors: make(map[interface{}]Extractor), + metrics: *NewNullMetrics(), + spanPool: sync.Pool{New: func() interface{} { + return &Span{} + }}, + } + + for _, option := range options { + option(t) + } + + // register default injectors/extractors unless they are already provided via options + textPropagator := newTextMapPropagator(getDefaultHeadersConfig(), t.metrics) + t.addCodec(opentracing.TextMap, textPropagator, textPropagator) + + httpHeaderPropagator := newHTTPHeaderPropagator(getDefaultHeadersConfig(), t.metrics) + t.addCodec(opentracing.HTTPHeaders, httpHeaderPropagator, httpHeaderPropagator) + + binaryPropagator := newBinaryPropagator(t) + t.addCodec(opentracing.Binary, binaryPropagator, binaryPropagator) + + // TODO remove after TChannel supports OpenTracing + interopPropagator := &jaegerTraceContextPropagator{tracer: t} + t.addCodec(SpanContextFormat, interopPropagator, interopPropagator) + + zipkinPropagator := &zipkinPropagator{tracer: t} + t.addCodec(ZipkinSpanFormat, zipkinPropagator, zipkinPropagator) + + if t.baggageRestrictionManager != nil { + t.baggageSetter = newBaggageSetter(t.baggageRestrictionManager, &t.metrics) + } else { + t.baggageSetter = newBaggageSetter(baggage.NewDefaultRestrictionManager(0), &t.metrics) + } + if t.debugThrottler == nil { + t.debugThrottler = throttler.DefaultThrottler{} + } + + if t.randomNumber == nil { + rng := utils.NewRand(time.Now().UnixNano()) + t.randomNumber = func() uint64 { + return uint64(rng.Int63()) + } + } + if t.timeNow == nil { + t.timeNow = time.Now + } + if t.logger == nil { + t.logger = log.NullLogger + } + // Set tracer-level tags + t.tags = append(t.tags, Tag{key: JaegerClientVersionTagKey, value: JaegerClientVersion}) + if hostname, err := os.Hostname(); err == nil { + t.tags = append(t.tags, Tag{key: TracerHostnameTagKey, value: hostname}) + } + if ip, err := utils.HostIP(); err == nil { + t.tags = append(t.tags, Tag{key: TracerIPTagKey, value: ip.String()}) + t.hostIPv4 = utils.PackIPAsUint32(ip) + } else { + t.logger.Error("Unable to determine this host's IP address: " + err.Error()) + } + + if t.options.gen128Bit { + if t.options.highTraceIDGenerator == nil { + t.options.highTraceIDGenerator = t.randomNumber + } + } else if t.options.highTraceIDGenerator != nil { + t.logger.Error("Overriding high trace ID generator but not generating " + + "128 bit trace IDs, consider enabling the \"Gen128Bit\" option") + } + if t.options.maxTagValueLength == 0 { + t.options.maxTagValueLength = DefaultMaxTagValueLength + } + t.process = Process{ + Service: serviceName, + UUID: strconv.FormatUint(t.randomNumber(), 16), + Tags: t.tags, + } + if throttler, ok := t.debugThrottler.(ProcessSetter); ok { + throttler.SetProcess(t.process) + } + + return t, t +} + +// addCodec adds registers injector and extractor for given propagation format if not already defined. +func (t *Tracer) addCodec(format interface{}, injector Injector, extractor Extractor) { + if _, ok := t.injectors[format]; !ok { + t.injectors[format] = injector + } + if _, ok := t.extractors[format]; !ok { + t.extractors[format] = extractor + } +} + +// StartSpan implements StartSpan() method of opentracing.Tracer. +func (t *Tracer) StartSpan( + operationName string, + options ...opentracing.StartSpanOption, +) opentracing.Span { + sso := opentracing.StartSpanOptions{} + for _, o := range options { + o.Apply(&sso) + } + return t.startSpanWithOptions(operationName, sso) +} + +func (t *Tracer) startSpanWithOptions( + operationName string, + options opentracing.StartSpanOptions, +) opentracing.Span { + if options.StartTime.IsZero() { + options.StartTime = t.timeNow() + } + + // Predicate whether the given span context is a valid reference + // which may be used as parent / debug ID / baggage items source + isValidReference := func(ctx SpanContext) bool { + return ctx.IsValid() || ctx.isDebugIDContainerOnly() || len(ctx.baggage) != 0 + } + + var references []Reference + var parent SpanContext + var hasParent bool // need this because `parent` is a value, not reference + for _, ref := range options.References { + ctx, ok := ref.ReferencedContext.(SpanContext) + if !ok { + t.logger.Error(fmt.Sprintf( + "Reference contains invalid type of SpanReference: %s", + reflect.ValueOf(ref.ReferencedContext))) + continue + } + if !isValidReference(ctx) { + continue + } + references = append(references, Reference{Type: ref.Type, Context: ctx}) + if !hasParent { + parent = ctx + hasParent = ref.Type == opentracing.ChildOfRef + } + } + if !hasParent && isValidReference(parent) { + // If ChildOfRef wasn't found but a FollowFromRef exists, use the context from + // the FollowFromRef as the parent + hasParent = true + } + + rpcServer := false + if v, ok := options.Tags[ext.SpanKindRPCServer.Key]; ok { + rpcServer = (v == ext.SpanKindRPCServerEnum || v == string(ext.SpanKindRPCServerEnum)) + } + + var samplerTags []Tag + var ctx SpanContext + newTrace := false + if !hasParent || !parent.IsValid() { + newTrace = true + ctx.traceID.Low = t.randomID() + if t.options.gen128Bit { + ctx.traceID.High = t.options.highTraceIDGenerator() + } + ctx.spanID = SpanID(ctx.traceID.Low) + ctx.parentID = 0 + ctx.flags = byte(0) + if hasParent && parent.isDebugIDContainerOnly() && t.isDebugAllowed(operationName) { + ctx.flags |= (flagSampled | flagDebug) + samplerTags = []Tag{{key: JaegerDebugHeader, value: parent.debugID}} + } else if sampled, tags := t.sampler.IsSampled(ctx.traceID, operationName); sampled { + ctx.flags |= flagSampled + samplerTags = tags + } + } else { + ctx.traceID = parent.traceID + if rpcServer && t.options.zipkinSharedRPCSpan { + // Support Zipkin's one-span-per-RPC model + ctx.spanID = parent.spanID + ctx.parentID = parent.parentID + } else { + ctx.spanID = SpanID(t.randomID()) + ctx.parentID = parent.spanID + } + ctx.flags = parent.flags + } + if hasParent { + // copy baggage items + if l := len(parent.baggage); l > 0 { + ctx.baggage = make(map[string]string, len(parent.baggage)) + for k, v := range parent.baggage { + ctx.baggage[k] = v + } + } + } + + sp := t.newSpan() + sp.context = ctx + sp.observer = t.observer.OnStartSpan(sp, operationName, options) + return t.startSpanInternal( + sp, + operationName, + options.StartTime, + samplerTags, + options.Tags, + newTrace, + rpcServer, + references, + ) +} + +// Inject implements Inject() method of opentracing.Tracer +func (t *Tracer) Inject(ctx opentracing.SpanContext, format interface{}, carrier interface{}) error { + c, ok := ctx.(SpanContext) + if !ok { + return opentracing.ErrInvalidSpanContext + } + if injector, ok := t.injectors[format]; ok { + return injector.Inject(c, carrier) + } + return opentracing.ErrUnsupportedFormat +} + +// Extract implements Extract() method of opentracing.Tracer +func (t *Tracer) Extract( + format interface{}, + carrier interface{}, +) (opentracing.SpanContext, error) { + if extractor, ok := t.extractors[format]; ok { + return extractor.Extract(carrier) + } + return nil, opentracing.ErrUnsupportedFormat +} + +// Close releases all resources used by the Tracer and flushes any remaining buffered spans. +func (t *Tracer) Close() error { + t.reporter.Close() + t.sampler.Close() + if mgr, ok := t.baggageRestrictionManager.(io.Closer); ok { + mgr.Close() + } + if throttler, ok := t.debugThrottler.(io.Closer); ok { + throttler.Close() + } + return nil +} + +// Tags returns a slice of tracer-level tags. +func (t *Tracer) Tags() []opentracing.Tag { + tags := make([]opentracing.Tag, len(t.tags)) + for i, tag := range t.tags { + tags[i] = opentracing.Tag{Key: tag.key, Value: tag.value} + } + return tags +} + +// newSpan returns an instance of a clean Span object. +// If options.PoolSpans is true, the spans are retrieved from an object pool. +func (t *Tracer) newSpan() *Span { + if !t.options.poolSpans { + return &Span{} + } + sp := t.spanPool.Get().(*Span) + sp.context = emptyContext + sp.tracer = nil + sp.tags = nil + sp.logs = nil + return sp +} + +func (t *Tracer) startSpanInternal( + sp *Span, + operationName string, + startTime time.Time, + internalTags []Tag, + tags opentracing.Tags, + newTrace bool, + rpcServer bool, + references []Reference, +) *Span { + sp.tracer = t + sp.operationName = operationName + sp.startTime = startTime + sp.duration = 0 + sp.references = references + sp.firstInProcess = rpcServer || sp.context.parentID == 0 + if len(tags) > 0 || len(internalTags) > 0 { + sp.tags = make([]Tag, len(internalTags), len(tags)+len(internalTags)) + copy(sp.tags, internalTags) + for k, v := range tags { + sp.observer.OnSetTag(k, v) + if k == string(ext.SamplingPriority) && !setSamplingPriority(sp, v) { + continue + } + sp.setTagNoLocking(k, v) + } + } + // emit metrics + if sp.context.IsSampled() { + t.metrics.SpansStartedSampled.Inc(1) + if newTrace { + // We cannot simply check for parentID==0 because in Zipkin model the + // server-side RPC span has the exact same trace/span/parent IDs as the + // calling client-side span, but obviously the server side span is + // no longer a root span of the trace. + t.metrics.TracesStartedSampled.Inc(1) + } else if sp.firstInProcess { + t.metrics.TracesJoinedSampled.Inc(1) + } + } else { + t.metrics.SpansStartedNotSampled.Inc(1) + if newTrace { + t.metrics.TracesStartedNotSampled.Inc(1) + } else if sp.firstInProcess { + t.metrics.TracesJoinedNotSampled.Inc(1) + } + } + return sp +} + +func (t *Tracer) reportSpan(sp *Span) { + t.metrics.SpansFinished.Inc(1) + if sp.context.IsSampled() { + t.reporter.Report(sp) + } + if t.options.poolSpans { + t.spanPool.Put(sp) + } +} + +// randomID generates a random trace/span ID, using tracer.random() generator. +// It never returns 0. +func (t *Tracer) randomID() uint64 { + val := t.randomNumber() + for val == 0 { + val = t.randomNumber() + } + return val +} + +// (NB) span must hold the lock before making this call +func (t *Tracer) setBaggage(sp *Span, key, value string) { + t.baggageSetter.setBaggage(sp, key, value) +} + +// (NB) span must hold the lock before making this call +func (t *Tracer) isDebugAllowed(operation string) bool { + return t.debugThrottler.IsAllowed(operation) +} diff --git a/vendor/github.com/uber/jaeger-client-go/tracer_options.go b/vendor/github.com/uber/jaeger-client-go/tracer_options.go new file mode 100644 index 0000000000..a90265f031 --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/tracer_options.go @@ -0,0 +1,159 @@ +// Copyright (c) 2017 Uber Technologies, Inc. +// +// 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 jaeger + +import ( + "time" + + "github.com/opentracing/opentracing-go" + + "github.com/uber/jaeger-client-go/internal/baggage" + "github.com/uber/jaeger-client-go/internal/throttler" +) + +// TracerOption is a function that sets some option on the tracer +type TracerOption func(tracer *Tracer) + +// TracerOptions is a factory for all available TracerOption's +var TracerOptions tracerOptions + +type tracerOptions struct{} + +// Metrics creates a TracerOption that initializes Metrics on the tracer, +// which is used to emit statistics. +func (tracerOptions) Metrics(m *Metrics) TracerOption { + return func(tracer *Tracer) { + tracer.metrics = *m + } +} + +// Logger creates a TracerOption that gives the tracer a Logger. +func (tracerOptions) Logger(logger Logger) TracerOption { + return func(tracer *Tracer) { + tracer.logger = logger + } +} + +func (tracerOptions) CustomHeaderKeys(headerKeys *HeadersConfig) TracerOption { + return func(tracer *Tracer) { + if headerKeys == nil { + return + } + textPropagator := newTextMapPropagator(headerKeys.applyDefaults(), tracer.metrics) + tracer.addCodec(opentracing.TextMap, textPropagator, textPropagator) + + httpHeaderPropagator := newHTTPHeaderPropagator(headerKeys.applyDefaults(), tracer.metrics) + tracer.addCodec(opentracing.HTTPHeaders, httpHeaderPropagator, httpHeaderPropagator) + } +} + +// TimeNow creates a TracerOption that gives the tracer a function +// used to generate timestamps for spans. +func (tracerOptions) TimeNow(timeNow func() time.Time) TracerOption { + return func(tracer *Tracer) { + tracer.timeNow = timeNow + } +} + +// RandomNumber creates a TracerOption that gives the tracer +// a thread-safe random number generator function for generating trace IDs. +func (tracerOptions) RandomNumber(randomNumber func() uint64) TracerOption { + return func(tracer *Tracer) { + tracer.randomNumber = randomNumber + } +} + +// PoolSpans creates a TracerOption that tells the tracer whether it should use +// an object pool to minimize span allocations. +// This should be used with care, only if the service is not running any async tasks +// that can access parent spans after those spans have been finished. +func (tracerOptions) PoolSpans(poolSpans bool) TracerOption { + return func(tracer *Tracer) { + tracer.options.poolSpans = poolSpans + } +} + +// Deprecated: HostIPv4 creates a TracerOption that identifies the current service/process. +// If not set, the factory method will obtain the current IP address. +// The TracerOption is deprecated; the tracer will attempt to automatically detect the IP. +func (tracerOptions) HostIPv4(hostIPv4 uint32) TracerOption { + return func(tracer *Tracer) { + tracer.hostIPv4 = hostIPv4 + } +} + +func (tracerOptions) Injector(format interface{}, injector Injector) TracerOption { + return func(tracer *Tracer) { + tracer.injectors[format] = injector + } +} + +func (tracerOptions) Extractor(format interface{}, extractor Extractor) TracerOption { + return func(tracer *Tracer) { + tracer.extractors[format] = extractor + } +} + +func (t tracerOptions) Observer(observer Observer) TracerOption { + return t.ContribObserver(&oldObserver{obs: observer}) +} + +func (tracerOptions) ContribObserver(observer ContribObserver) TracerOption { + return func(tracer *Tracer) { + tracer.observer.append(observer) + } +} + +func (tracerOptions) Gen128Bit(gen128Bit bool) TracerOption { + return func(tracer *Tracer) { + tracer.options.gen128Bit = gen128Bit + } +} + +func (tracerOptions) HighTraceIDGenerator(highTraceIDGenerator func() uint64) TracerOption { + return func(tracer *Tracer) { + tracer.options.highTraceIDGenerator = highTraceIDGenerator + } +} + +func (tracerOptions) MaxTagValueLength(maxTagValueLength int) TracerOption { + return func(tracer *Tracer) { + tracer.options.maxTagValueLength = maxTagValueLength + } +} + +func (tracerOptions) ZipkinSharedRPCSpan(zipkinSharedRPCSpan bool) TracerOption { + return func(tracer *Tracer) { + tracer.options.zipkinSharedRPCSpan = zipkinSharedRPCSpan + } +} + +func (tracerOptions) Tag(key string, value interface{}) TracerOption { + return func(tracer *Tracer) { + tracer.tags = append(tracer.tags, Tag{key: key, value: value}) + } +} + +func (tracerOptions) BaggageRestrictionManager(mgr baggage.RestrictionManager) TracerOption { + return func(tracer *Tracer) { + tracer.baggageRestrictionManager = mgr + } +} + +func (tracerOptions) DebugThrottler(throttler throttler.Throttler) TracerOption { + return func(tracer *Tracer) { + tracer.debugThrottler = throttler + } +} diff --git a/vendor/github.com/uber/jaeger-client-go/transport.go b/vendor/github.com/uber/jaeger-client-go/transport.go new file mode 100644 index 0000000000..c5f5b19551 --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/transport.go @@ -0,0 +1,38 @@ +// Copyright (c) 2017 Uber Technologies, Inc. +// +// 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 jaeger + +import ( + "io" +) + +// Transport abstracts the method of sending spans out of process. +// Implementations are NOT required to be thread-safe; the RemoteReporter +// is expected to only call methods on the Transport from the same go-routine. +type Transport interface { + // Append converts the span to the wire representation and adds it + // to sender's internal buffer. If the buffer exceeds its designated + // size, the transport should call Flush() and return the number of spans + // flushed, otherwise return 0. If error is returned, the returned number + // of spans is treated as failed span, and reported to metrics accordingly. + Append(span *Span) (int, error) + + // Flush submits the internal buffer to the remote server. It returns the + // number of spans flushed. If error is returned, the returned number of + // spans is treated as failed span, and reported to metrics accordingly. + Flush() (int, error) + + io.Closer +} diff --git a/vendor/github.com/uber/jaeger-client-go/transport_udp.go b/vendor/github.com/uber/jaeger-client-go/transport_udp.go new file mode 100644 index 0000000000..7b9ccf9374 --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/transport_udp.go @@ -0,0 +1,131 @@ +// Copyright (c) 2017 Uber Technologies, Inc. +// +// 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 jaeger + +import ( + "errors" + "fmt" + + "github.com/uber/jaeger-client-go/thrift" + + j "github.com/uber/jaeger-client-go/thrift-gen/jaeger" + "github.com/uber/jaeger-client-go/utils" +) + +// Empirically obtained constant for how many bytes in the message are used for envelope. +// The total datagram size is: +// sizeof(Span) * numSpans + processByteSize + emitBatchOverhead <= maxPacketSize +// There is a unit test `TestEmitBatchOverhead` that validates this number. +// Note that due to the use of Compact Thrift protocol, overhead grows with the number of spans +// in the batch, because the length of the list is encoded as varint32, as well as SeqId. +const emitBatchOverhead = 30 + +var errSpanTooLarge = errors.New("Span is too large") + +type udpSender struct { + client *utils.AgentClientUDP + maxPacketSize int // max size of datagram in bytes + maxSpanBytes int // max number of bytes to record spans (excluding envelope) in the datagram + byteBufferSize int // current number of span bytes accumulated in the buffer + spanBuffer []*j.Span // spans buffered before a flush + thriftBuffer *thrift.TMemoryBuffer // buffer used to calculate byte size of a span + thriftProtocol thrift.TProtocol + process *j.Process + processByteSize int +} + +// NewUDPTransport creates a reporter that submits spans to jaeger-agent +func NewUDPTransport(hostPort string, maxPacketSize int) (Transport, error) { + if len(hostPort) == 0 { + hostPort = fmt.Sprintf("%s:%d", DefaultUDPSpanServerHost, DefaultUDPSpanServerPort) + } + if maxPacketSize == 0 { + maxPacketSize = utils.UDPPacketMaxLength + } + + protocolFactory := thrift.NewTCompactProtocolFactory() + + // Each span is first written to thriftBuffer to determine its size in bytes. + thriftBuffer := thrift.NewTMemoryBufferLen(maxPacketSize) + thriftProtocol := protocolFactory.GetProtocol(thriftBuffer) + + client, err := utils.NewAgentClientUDP(hostPort, maxPacketSize) + if err != nil { + return nil, err + } + + sender := &udpSender{ + client: client, + maxSpanBytes: maxPacketSize - emitBatchOverhead, + thriftBuffer: thriftBuffer, + thriftProtocol: thriftProtocol} + return sender, nil +} + +func (s *udpSender) calcSizeOfSerializedThrift(thriftStruct thrift.TStruct) int { + s.thriftBuffer.Reset() + thriftStruct.Write(s.thriftProtocol) + return s.thriftBuffer.Len() +} + +func (s *udpSender) Append(span *Span) (int, error) { + if s.process == nil { + s.process = BuildJaegerProcessThrift(span) + s.processByteSize = s.calcSizeOfSerializedThrift(s.process) + s.byteBufferSize += s.processByteSize + } + jSpan := BuildJaegerThrift(span) + spanSize := s.calcSizeOfSerializedThrift(jSpan) + if spanSize > s.maxSpanBytes { + return 1, errSpanTooLarge + } + + s.byteBufferSize += spanSize + if s.byteBufferSize <= s.maxSpanBytes { + s.spanBuffer = append(s.spanBuffer, jSpan) + if s.byteBufferSize < s.maxSpanBytes { + return 0, nil + } + return s.Flush() + } + // the latest span did not fit in the buffer + n, err := s.Flush() + s.spanBuffer = append(s.spanBuffer, jSpan) + s.byteBufferSize = spanSize + s.processByteSize + return n, err +} + +func (s *udpSender) Flush() (int, error) { + n := len(s.spanBuffer) + if n == 0 { + return 0, nil + } + err := s.client.EmitBatch(&j.Batch{Process: s.process, Spans: s.spanBuffer}) + s.resetBuffers() + + return n, err +} + +func (s *udpSender) Close() error { + return s.client.Close() +} + +func (s *udpSender) resetBuffers() { + for i := range s.spanBuffer { + s.spanBuffer[i] = nil + } + s.spanBuffer = s.spanBuffer[:0] + s.byteBufferSize = s.processByteSize +} diff --git a/vendor/github.com/uber/jaeger-client-go/utils/http_json.go b/vendor/github.com/uber/jaeger-client-go/utils/http_json.go new file mode 100644 index 0000000000..237211f822 --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/utils/http_json.go @@ -0,0 +1,54 @@ +// Copyright (c) 2017 Uber Technologies, Inc. +// +// 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 utils + +import ( + "encoding/json" + "fmt" + "io" + "io/ioutil" + "net/http" +) + +// GetJSON makes an HTTP call to the specified URL and parses the returned JSON into `out`. +func GetJSON(url string, out interface{}) error { + resp, err := http.Get(url) + if err != nil { + return err + } + return ReadJSON(resp, out) +} + +// ReadJSON reads JSON from http.Response and parses it into `out` +func ReadJSON(resp *http.Response, out interface{}) error { + defer resp.Body.Close() + + if resp.StatusCode >= 400 { + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return err + } + + return fmt.Errorf("StatusCode: %d, Body: %s", resp.StatusCode, body) + } + + if out == nil { + io.Copy(ioutil.Discard, resp.Body) + return nil + } + + decoder := json.NewDecoder(resp.Body) + return decoder.Decode(out) +} diff --git a/vendor/github.com/uber/jaeger-client-go/utils/localip.go b/vendor/github.com/uber/jaeger-client-go/utils/localip.go new file mode 100644 index 0000000000..b51af7713f --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/utils/localip.go @@ -0,0 +1,84 @@ +// Copyright (c) 2017 Uber Technologies, Inc. +// +// 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 utils + +import ( + "errors" + "net" +) + +// This code is borrowed from https://github.com/uber/tchannel-go/blob/dev/localip.go + +// scoreAddr scores how likely the given addr is to be a remote address and returns the +// IP to use when listening. Any address which receives a negative score should not be used. +// Scores are calculated as: +// -1 for any unknown IP addresses. +// +300 for IPv4 addresses +// +100 for non-local addresses, extra +100 for "up" interaces. +func scoreAddr(iface net.Interface, addr net.Addr) (int, net.IP) { + var ip net.IP + if netAddr, ok := addr.(*net.IPNet); ok { + ip = netAddr.IP + } else if netIP, ok := addr.(*net.IPAddr); ok { + ip = netIP.IP + } else { + return -1, nil + } + + var score int + if ip.To4() != nil { + score += 300 + } + if iface.Flags&net.FlagLoopback == 0 && !ip.IsLoopback() { + score += 100 + if iface.Flags&net.FlagUp != 0 { + score += 100 + } + } + return score, ip +} + +// HostIP tries to find an IP that can be used by other machines to reach this machine. +func HostIP() (net.IP, error) { + interfaces, err := net.Interfaces() + if err != nil { + return nil, err + } + + bestScore := -1 + var bestIP net.IP + // Select the highest scoring IP as the best IP. + for _, iface := range interfaces { + addrs, err := iface.Addrs() + if err != nil { + // Skip this interface if there is an error. + continue + } + + for _, addr := range addrs { + score, ip := scoreAddr(iface, addr) + if score > bestScore { + bestScore = score + bestIP = ip + } + } + } + + if bestScore == -1 { + return nil, errors.New("no addresses to listen on") + } + + return bestIP, nil +} diff --git a/vendor/github.com/uber/jaeger-client-go/utils/rand.go b/vendor/github.com/uber/jaeger-client-go/utils/rand.go new file mode 100644 index 0000000000..9875f7f55c --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/utils/rand.go @@ -0,0 +1,46 @@ +// Copyright (c) 2017 Uber Technologies, Inc. +// +// 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 utils + +import ( + "math/rand" + "sync" +) + +// lockedSource allows a random number generator to be used by multiple goroutines concurrently. +// The code is very similar to math/rand.lockedSource, which is unfortunately not exposed. +type lockedSource struct { + mut sync.Mutex + src rand.Source +} + +// NewRand returns a rand.Rand that is threadsafe. +func NewRand(seed int64) *rand.Rand { + return rand.New(&lockedSource{src: rand.NewSource(seed)}) +} + +func (r *lockedSource) Int63() (n int64) { + r.mut.Lock() + n = r.src.Int63() + r.mut.Unlock() + return +} + +// Seed implements Seed() of Source +func (r *lockedSource) Seed(seed int64) { + r.mut.Lock() + r.src.Seed(seed) + r.mut.Unlock() +} diff --git a/vendor/github.com/uber/jaeger-client-go/utils/rate_limiter.go b/vendor/github.com/uber/jaeger-client-go/utils/rate_limiter.go new file mode 100644 index 0000000000..1b8db97584 --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/utils/rate_limiter.go @@ -0,0 +1,77 @@ +// Copyright (c) 2017 Uber Technologies, Inc. +// +// 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 utils + +import ( + "sync" + "time" +) + +// RateLimiter is a filter used to check if a message that is worth itemCost units is within the rate limits. +type RateLimiter interface { + CheckCredit(itemCost float64) bool +} + +type rateLimiter struct { + sync.Mutex + + creditsPerSecond float64 + balance float64 + maxBalance float64 + lastTick time.Time + + timeNow func() time.Time +} + +// NewRateLimiter creates a new rate limiter based on leaky bucket algorithm, formulated in terms of a +// credits balance that is replenished every time CheckCredit() method is called (tick) by the amount proportional +// to the time elapsed since the last tick, up to max of creditsPerSecond. A call to CheckCredit() takes a cost +// of an item we want to pay with the balance. If the balance exceeds the cost of the item, the item is "purchased" +// and the balance reduced, indicated by returned value of true. Otherwise the balance is unchanged and return false. +// +// This can be used to limit a rate of messages emitted by a service by instantiating the Rate Limiter with the +// max number of messages a service is allowed to emit per second, and calling CheckCredit(1.0) for each message +// to determine if the message is within the rate limit. +// +// It can also be used to limit the rate of traffic in bytes, by setting creditsPerSecond to desired throughput +// as bytes/second, and calling CheckCredit() with the actual message size. +func NewRateLimiter(creditsPerSecond, maxBalance float64) RateLimiter { + return &rateLimiter{ + creditsPerSecond: creditsPerSecond, + balance: maxBalance, + maxBalance: maxBalance, + lastTick: time.Now(), + timeNow: time.Now} +} + +func (b *rateLimiter) CheckCredit(itemCost float64) bool { + b.Lock() + defer b.Unlock() + // calculate how much time passed since the last tick, and update current tick + currentTime := b.timeNow() + elapsedTime := currentTime.Sub(b.lastTick) + b.lastTick = currentTime + // calculate how much credit have we accumulated since the last tick + b.balance += elapsedTime.Seconds() * b.creditsPerSecond + if b.balance > b.maxBalance { + b.balance = b.maxBalance + } + // if we have enough credits to pay for current item, then reduce balance and allow + if b.balance >= itemCost { + b.balance -= itemCost + return true + } + return false +} diff --git a/vendor/github.com/uber/jaeger-client-go/utils/udp_client.go b/vendor/github.com/uber/jaeger-client-go/utils/udp_client.go new file mode 100644 index 0000000000..6f042073d6 --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/utils/udp_client.go @@ -0,0 +1,98 @@ +// Copyright (c) 2017 Uber Technologies, Inc. +// +// 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 utils + +import ( + "errors" + "fmt" + "io" + "net" + + "github.com/uber/jaeger-client-go/thrift" + + "github.com/uber/jaeger-client-go/thrift-gen/agent" + "github.com/uber/jaeger-client-go/thrift-gen/jaeger" + "github.com/uber/jaeger-client-go/thrift-gen/zipkincore" +) + +// UDPPacketMaxLength is the max size of UDP packet we want to send, synced with jaeger-agent +const UDPPacketMaxLength = 65000 + +// AgentClientUDP is a UDP client to Jaeger agent that implements agent.Agent interface. +type AgentClientUDP struct { + agent.Agent + io.Closer + + connUDP *net.UDPConn + client *agent.AgentClient + maxPacketSize int // max size of datagram in bytes + thriftBuffer *thrift.TMemoryBuffer // buffer used to calculate byte size of a span +} + +// NewAgentClientUDP creates a client that sends spans to Jaeger Agent over UDP. +func NewAgentClientUDP(hostPort string, maxPacketSize int) (*AgentClientUDP, error) { + if maxPacketSize == 0 { + maxPacketSize = UDPPacketMaxLength + } + + thriftBuffer := thrift.NewTMemoryBufferLen(maxPacketSize) + protocolFactory := thrift.NewTCompactProtocolFactory() + client := agent.NewAgentClientFactory(thriftBuffer, protocolFactory) + + destAddr, err := net.ResolveUDPAddr("udp", hostPort) + if err != nil { + return nil, err + } + + connUDP, err := net.DialUDP(destAddr.Network(), nil, destAddr) + if err != nil { + return nil, err + } + if err := connUDP.SetWriteBuffer(maxPacketSize); err != nil { + return nil, err + } + + clientUDP := &AgentClientUDP{ + connUDP: connUDP, + client: client, + maxPacketSize: maxPacketSize, + thriftBuffer: thriftBuffer} + return clientUDP, nil +} + +// EmitZipkinBatch implements EmitZipkinBatch() of Agent interface +func (a *AgentClientUDP) EmitZipkinBatch(spans []*zipkincore.Span) error { + return errors.New("Not implemented") +} + +// EmitBatch implements EmitBatch() of Agent interface +func (a *AgentClientUDP) EmitBatch(batch *jaeger.Batch) error { + a.thriftBuffer.Reset() + a.client.SeqId = 0 // we have no need for distinct SeqIds for our one-way UDP messages + if err := a.client.EmitBatch(batch); err != nil { + return err + } + if a.thriftBuffer.Len() > a.maxPacketSize { + return fmt.Errorf("Data does not fit within one UDP packet; size %d, max %d, spans %d", + a.thriftBuffer.Len(), a.maxPacketSize, len(batch.Spans)) + } + _, err := a.connUDP.Write(a.thriftBuffer.Bytes()) + return err +} + +// Close implements Close() of io.Closer and closes the underlying UDP connection. +func (a *AgentClientUDP) Close() error { + return a.connUDP.Close() +} diff --git a/vendor/github.com/uber/jaeger-client-go/utils/utils.go b/vendor/github.com/uber/jaeger-client-go/utils/utils.go new file mode 100644 index 0000000000..ac3c325d1e --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/utils/utils.go @@ -0,0 +1,87 @@ +// Copyright (c) 2017 Uber Technologies, Inc. +// +// 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 utils + +import ( + "encoding/binary" + "errors" + "net" + "strconv" + "strings" + "time" +) + +var ( + // ErrEmptyIP an error for empty ip strings + ErrEmptyIP = errors.New("empty string given for ip") + + // ErrNotHostColonPort an error for invalid host port string + ErrNotHostColonPort = errors.New("expecting host:port") + + // ErrNotFourOctets an error for the wrong number of octets after splitting a string + ErrNotFourOctets = errors.New("Wrong number of octets") +) + +// ParseIPToUint32 converts a string ip (e.g. "x.y.z.w") to an uint32 +func ParseIPToUint32(ip string) (uint32, error) { + if ip == "" { + return 0, ErrEmptyIP + } + + if ip == "localhost" { + return 127<<24 | 1, nil + } + + octets := strings.Split(ip, ".") + if len(octets) != 4 { + return 0, ErrNotFourOctets + } + + var intIP uint32 + for i := 0; i < 4; i++ { + octet, err := strconv.Atoi(octets[i]) + if err != nil { + return 0, err + } + intIP = (intIP << 8) | uint32(octet) + } + + return intIP, nil +} + +// ParsePort converts port number from string to uin16 +func ParsePort(portString string) (uint16, error) { + port, err := strconv.ParseUint(portString, 10, 16) + return uint16(port), err +} + +// PackIPAsUint32 packs an IPv4 as uint32 +func PackIPAsUint32(ip net.IP) uint32 { + if ipv4 := ip.To4(); ipv4 != nil { + return binary.BigEndian.Uint32(ipv4) + } + return 0 +} + +// TimeToMicrosecondsSinceEpochInt64 converts Go time.Time to a long +// representing time since epoch in microseconds, which is used expected +// in the Jaeger spans encoded as Thrift. +func TimeToMicrosecondsSinceEpochInt64(t time.Time) int64 { + // ^^^ Passing time.Time by value is faster than passing a pointer! + // BenchmarkTimeByValue-8 2000000000 1.37 ns/op + // BenchmarkTimeByPtr-8 2000000000 1.98 ns/op + + return t.UnixNano() / 1000 +} diff --git a/vendor/github.com/uber/jaeger-client-go/zipkin.go b/vendor/github.com/uber/jaeger-client-go/zipkin.go new file mode 100644 index 0000000000..636952b7f1 --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/zipkin.go @@ -0,0 +1,76 @@ +// Copyright (c) 2017 Uber Technologies, Inc. +// +// 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 jaeger + +import ( + "github.com/opentracing/opentracing-go" +) + +// ZipkinSpanFormat is an OpenTracing carrier format constant +const ZipkinSpanFormat = "zipkin-span-format" + +// ExtractableZipkinSpan is a type of Carrier used for integration with Zipkin-aware +// RPC frameworks (like TChannel). It does not support baggage, only trace IDs. +type ExtractableZipkinSpan interface { + TraceID() uint64 + SpanID() uint64 + ParentID() uint64 + Flags() byte +} + +// InjectableZipkinSpan is a type of Carrier used for integration with Zipkin-aware +// RPC frameworks (like TChannel). It does not support baggage, only trace IDs. +type InjectableZipkinSpan interface { + SetTraceID(traceID uint64) + SetSpanID(spanID uint64) + SetParentID(parentID uint64) + SetFlags(flags byte) +} + +type zipkinPropagator struct { + tracer *Tracer +} + +func (p *zipkinPropagator) Inject( + ctx SpanContext, + abstractCarrier interface{}, +) error { + carrier, ok := abstractCarrier.(InjectableZipkinSpan) + if !ok { + return opentracing.ErrInvalidCarrier + } + + carrier.SetTraceID(ctx.TraceID().Low) // TODO this cannot work with 128bit IDs + carrier.SetSpanID(uint64(ctx.SpanID())) + carrier.SetParentID(uint64(ctx.ParentID())) + carrier.SetFlags(ctx.flags) + return nil +} + +func (p *zipkinPropagator) Extract(abstractCarrier interface{}) (SpanContext, error) { + carrier, ok := abstractCarrier.(ExtractableZipkinSpan) + if !ok { + return emptyContext, opentracing.ErrInvalidCarrier + } + if carrier.TraceID() == 0 { + return emptyContext, opentracing.ErrSpanContextNotFound + } + var ctx SpanContext + ctx.traceID.Low = carrier.TraceID() + ctx.spanID = SpanID(carrier.SpanID()) + ctx.parentID = SpanID(carrier.ParentID()) + ctx.flags = carrier.Flags() + return ctx, nil +} diff --git a/vendor/github.com/uber/jaeger-client-go/zipkin_thrift_span.go b/vendor/github.com/uber/jaeger-client-go/zipkin_thrift_span.go new file mode 100644 index 0000000000..dce58b4331 --- /dev/null +++ b/vendor/github.com/uber/jaeger-client-go/zipkin_thrift_span.go @@ -0,0 +1,322 @@ +// Copyright (c) 2017 Uber Technologies, Inc. +// +// 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 jaeger + +import ( + "encoding/binary" + "fmt" + "time" + + "github.com/opentracing/opentracing-go/ext" + + "github.com/uber/jaeger-client-go/internal/spanlog" + z "github.com/uber/jaeger-client-go/thrift-gen/zipkincore" + "github.com/uber/jaeger-client-go/utils" +) + +const ( + // Zipkin UI does not work well with non-string tag values + allowPackedNumbers = false +) + +var specialTagHandlers = map[string]func(*zipkinSpan, interface{}){ + string(ext.SpanKind): setSpanKind, + string(ext.PeerHostIPv4): setPeerIPv4, + string(ext.PeerPort): setPeerPort, + string(ext.PeerService): setPeerService, + TracerIPTagKey: removeTag, +} + +// BuildZipkinThrift builds thrift span based on internal span. +func BuildZipkinThrift(s *Span) *z.Span { + span := &zipkinSpan{Span: s} + span.handleSpecialTags() + parentID := int64(span.context.parentID) + var ptrParentID *int64 + if parentID != 0 { + ptrParentID = &parentID + } + timestamp := utils.TimeToMicrosecondsSinceEpochInt64(span.startTime) + duration := span.duration.Nanoseconds() / int64(time.Microsecond) + endpoint := &z.Endpoint{ + ServiceName: span.tracer.serviceName, + Ipv4: int32(span.tracer.hostIPv4)} + thriftSpan := &z.Span{ + TraceID: int64(span.context.traceID.Low), // TODO upgrade zipkin thrift and use TraceIdHigh + ID: int64(span.context.spanID), + ParentID: ptrParentID, + Name: span.operationName, + Timestamp: ×tamp, + Duration: &duration, + Debug: span.context.IsDebug(), + Annotations: buildAnnotations(span, endpoint), + BinaryAnnotations: buildBinaryAnnotations(span, endpoint)} + return thriftSpan +} + +func buildAnnotations(span *zipkinSpan, endpoint *z.Endpoint) []*z.Annotation { + // automatically adding 2 Zipkin CoreAnnotations + annotations := make([]*z.Annotation, 0, 2+len(span.logs)) + var startLabel, endLabel string + if span.spanKind == string(ext.SpanKindRPCClientEnum) { + startLabel, endLabel = z.CLIENT_SEND, z.CLIENT_RECV + } else if span.spanKind == string(ext.SpanKindRPCServerEnum) { + startLabel, endLabel = z.SERVER_RECV, z.SERVER_SEND + } + if !span.startTime.IsZero() && startLabel != "" { + start := &z.Annotation{ + Timestamp: utils.TimeToMicrosecondsSinceEpochInt64(span.startTime), + Value: startLabel, + Host: endpoint} + annotations = append(annotations, start) + if span.duration != 0 { + endTs := span.startTime.Add(span.duration) + end := &z.Annotation{ + Timestamp: utils.TimeToMicrosecondsSinceEpochInt64(endTs), + Value: endLabel, + Host: endpoint} + annotations = append(annotations, end) + } + } + for _, log := range span.logs { + anno := &z.Annotation{ + Timestamp: utils.TimeToMicrosecondsSinceEpochInt64(log.Timestamp), + Host: endpoint} + if content, err := spanlog.MaterializeWithJSON(log.Fields); err == nil { + anno.Value = truncateString(string(content), span.tracer.options.maxTagValueLength) + } else { + anno.Value = err.Error() + } + annotations = append(annotations, anno) + } + return annotations +} + +func buildBinaryAnnotations(span *zipkinSpan, endpoint *z.Endpoint) []*z.BinaryAnnotation { + // automatically adding local component or server/client address tag, and client version + annotations := make([]*z.BinaryAnnotation, 0, 2+len(span.tags)) + + if span.peerDefined() && span.isRPC() { + peer := z.Endpoint{ + Ipv4: span.peer.Ipv4, + Port: span.peer.Port, + ServiceName: span.peer.ServiceName} + label := z.CLIENT_ADDR + if span.isRPCClient() { + label = z.SERVER_ADDR + } + anno := &z.BinaryAnnotation{ + Key: label, + Value: []byte{1}, + AnnotationType: z.AnnotationType_BOOL, + Host: &peer} + annotations = append(annotations, anno) + } + if !span.isRPC() { + componentName := endpoint.ServiceName + for _, tag := range span.tags { + if tag.key == string(ext.Component) { + componentName = stringify(tag.value) + break + } + } + local := &z.BinaryAnnotation{ + Key: z.LOCAL_COMPONENT, + Value: []byte(componentName), + AnnotationType: z.AnnotationType_STRING, + Host: endpoint} + annotations = append(annotations, local) + } + for _, tag := range span.tags { + // "Special tags" are already handled by this point, we'd be double reporting the + // tags if we don't skip here + if _, ok := specialTagHandlers[tag.key]; ok { + continue + } + if anno := buildBinaryAnnotation(tag.key, tag.value, span.tracer.options.maxTagValueLength, nil); anno != nil { + annotations = append(annotations, anno) + } + } + return annotations +} + +func buildBinaryAnnotation(key string, val interface{}, maxTagValueLength int, endpoint *z.Endpoint) *z.BinaryAnnotation { + bann := &z.BinaryAnnotation{Key: key, Host: endpoint} + if value, ok := val.(string); ok { + bann.Value = []byte(truncateString(value, maxTagValueLength)) + bann.AnnotationType = z.AnnotationType_STRING + } else if value, ok := val.([]byte); ok { + if len(value) > maxTagValueLength { + value = value[:maxTagValueLength] + } + bann.Value = value + bann.AnnotationType = z.AnnotationType_BYTES + } else if value, ok := val.(int32); ok && allowPackedNumbers { + bann.Value = int32ToBytes(value) + bann.AnnotationType = z.AnnotationType_I32 + } else if value, ok := val.(int64); ok && allowPackedNumbers { + bann.Value = int64ToBytes(value) + bann.AnnotationType = z.AnnotationType_I64 + } else if value, ok := val.(int); ok && allowPackedNumbers { + bann.Value = int64ToBytes(int64(value)) + bann.AnnotationType = z.AnnotationType_I64 + } else if value, ok := val.(bool); ok { + bann.Value = []byte{boolToByte(value)} + bann.AnnotationType = z.AnnotationType_BOOL + } else { + value := stringify(val) + bann.Value = []byte(truncateString(value, maxTagValueLength)) + bann.AnnotationType = z.AnnotationType_STRING + } + return bann +} + +func stringify(value interface{}) string { + if s, ok := value.(string); ok { + return s + } + return fmt.Sprintf("%+v", value) +} + +func truncateString(value string, maxLength int) string { + // we ignore the problem of utf8 runes possibly being sliced in the middle, + // as it is rather expensive to iterate through each tag just to find rune + // boundaries. + if len(value) > maxLength { + return value[:maxLength] + } + return value +} + +func boolToByte(b bool) byte { + if b { + return 1 + } + return 0 +} + +// int32ToBytes converts int32 to bytes. +func int32ToBytes(i int32) []byte { + buf := make([]byte, 4) + binary.BigEndian.PutUint32(buf, uint32(i)) + return buf +} + +// int64ToBytes converts int64 to bytes. +func int64ToBytes(i int64) []byte { + buf := make([]byte, 8) + binary.BigEndian.PutUint64(buf, uint64(i)) + return buf +} + +type zipkinSpan struct { + *Span + + // peer points to the peer service participating in this span, + // e.g. the Client if this span is a server span, + // or Server if this span is a client span + peer struct { + Ipv4 int32 + Port int16 + ServiceName string + } + + // used to distinguish local vs. RPC Server vs. RPC Client spans + spanKind string +} + +func (s *zipkinSpan) handleSpecialTags() { + s.Lock() + defer s.Unlock() + if s.firstInProcess { + // append the process tags + s.tags = append(s.tags, s.tracer.tags...) + } + filteredTags := make([]Tag, 0, len(s.tags)) + for _, tag := range s.tags { + if handler, ok := specialTagHandlers[tag.key]; ok { + handler(s, tag.value) + } else { + filteredTags = append(filteredTags, tag) + } + } + s.tags = filteredTags +} + +func setSpanKind(s *zipkinSpan, value interface{}) { + if val, ok := value.(string); ok { + s.spanKind = val + return + } + if val, ok := value.(ext.SpanKindEnum); ok { + s.spanKind = string(val) + } +} + +func setPeerIPv4(s *zipkinSpan, value interface{}) { + if val, ok := value.(string); ok { + if ip, err := utils.ParseIPToUint32(val); err == nil { + s.peer.Ipv4 = int32(ip) + return + } + } + if val, ok := value.(uint32); ok { + s.peer.Ipv4 = int32(val) + return + } + if val, ok := value.(int32); ok { + s.peer.Ipv4 = val + } +} + +func setPeerPort(s *zipkinSpan, value interface{}) { + if val, ok := value.(string); ok { + if port, err := utils.ParsePort(val); err == nil { + s.peer.Port = int16(port) + return + } + } + if val, ok := value.(uint16); ok { + s.peer.Port = int16(val) + return + } + if val, ok := value.(int); ok { + s.peer.Port = int16(val) + } +} + +func setPeerService(s *zipkinSpan, value interface{}) { + if val, ok := value.(string); ok { + s.peer.ServiceName = val + } +} + +func removeTag(s *zipkinSpan, value interface{}) {} + +func (s *zipkinSpan) peerDefined() bool { + return s.peer.ServiceName != "" || s.peer.Ipv4 != 0 || s.peer.Port != 0 +} + +func (s *zipkinSpan) isRPC() bool { + s.RLock() + defer s.RUnlock() + return s.spanKind == string(ext.SpanKindRPCClientEnum) || s.spanKind == string(ext.SpanKindRPCServerEnum) +} + +func (s *zipkinSpan) isRPCClient() bool { + s.RLock() + defer s.RUnlock() + return s.spanKind == string(ext.SpanKindRPCClientEnum) +} diff --git a/vendor/github.com/uber/jaeger-lib/LICENSE b/vendor/github.com/uber/jaeger-lib/LICENSE new file mode 100644 index 0000000000..261eeb9e9f --- /dev/null +++ b/vendor/github.com/uber/jaeger-lib/LICENSE @@ -0,0 +1,201 @@ + 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/vendor/github.com/uber/jaeger-lib/metrics/counter.go b/vendor/github.com/uber/jaeger-lib/metrics/counter.go new file mode 100644 index 0000000000..2a6a43efdb --- /dev/null +++ b/vendor/github.com/uber/jaeger-lib/metrics/counter.go @@ -0,0 +1,28 @@ +// Copyright (c) 2017 Uber Technologies, Inc. +// +// 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 metrics + +// Counter tracks the number of times an event has occurred +type Counter interface { + // Inc adds the given value to the counter. + Inc(int64) +} + +// NullCounter counter that does nothing +var NullCounter Counter = nullCounter{} + +type nullCounter struct{} + +func (nullCounter) Inc(int64) {} diff --git a/vendor/github.com/uber/jaeger-lib/metrics/factory.go b/vendor/github.com/uber/jaeger-lib/metrics/factory.go new file mode 100644 index 0000000000..a744a890df --- /dev/null +++ b/vendor/github.com/uber/jaeger-lib/metrics/factory.go @@ -0,0 +1,35 @@ +// Copyright (c) 2017 Uber Technologies, Inc. +// +// 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 metrics + +// Factory creates new metrics +type Factory interface { + Counter(name string, tags map[string]string) Counter + Timer(name string, tags map[string]string) Timer + Gauge(name string, tags map[string]string) Gauge + + // Namespace returns a nested metrics factory. + Namespace(name string, tags map[string]string) Factory +} + +// NullFactory is a metrics factory that returns NullCounter, NullTimer, and NullGauge. +var NullFactory Factory = nullFactory{} + +type nullFactory struct{} + +func (nullFactory) Counter(name string, tags map[string]string) Counter { return NullCounter } +func (nullFactory) Timer(name string, tags map[string]string) Timer { return NullTimer } +func (nullFactory) Gauge(name string, tags map[string]string) Gauge { return NullGauge } +func (nullFactory) Namespace(name string, tags map[string]string) Factory { return NullFactory } diff --git a/vendor/github.com/uber/jaeger-lib/metrics/gauge.go b/vendor/github.com/uber/jaeger-lib/metrics/gauge.go new file mode 100644 index 0000000000..3c606391a0 --- /dev/null +++ b/vendor/github.com/uber/jaeger-lib/metrics/gauge.go @@ -0,0 +1,28 @@ +// Copyright (c) 2017 Uber Technologies, Inc. +// +// 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 metrics + +// Gauge returns instantaneous measurements of something as an int64 value +type Gauge interface { + // Update the gauge to the value passed in. + Update(int64) +} + +// NullGauge gauge that does nothing +var NullGauge Gauge = nullGauge{} + +type nullGauge struct{} + +func (nullGauge) Update(int64) {} diff --git a/vendor/github.com/uber/jaeger-lib/metrics/local.go b/vendor/github.com/uber/jaeger-lib/metrics/local.go new file mode 100644 index 0000000000..217d30600a --- /dev/null +++ b/vendor/github.com/uber/jaeger-lib/metrics/local.go @@ -0,0 +1,337 @@ +// Copyright (c) 2017 Uber Technologies, Inc. +// +// 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 metrics + +import ( + "sort" + "sync" + "sync/atomic" + "time" + + "github.com/codahale/hdrhistogram" +) + +// This is intentionally very similar to github.com/codahale/metrics, the +// main difference being that counters/gauges are scoped to the provider +// rather than being global (to facilitate testing). + +// A LocalBackend is a metrics provider which aggregates data in-vm, and +// allows exporting snapshots to shove the data into a remote collector +type LocalBackend struct { + cm sync.Mutex + gm sync.Mutex + tm sync.Mutex + counters map[string]*int64 + gauges map[string]*int64 + timers map[string]*localBackendTimer + stop chan struct{} + wg sync.WaitGroup + TagsSep string + TagKVSep string +} + +// NewLocalBackend returns a new LocalBackend. The collectionInterval is the histogram +// time window for each timer. +func NewLocalBackend(collectionInterval time.Duration) *LocalBackend { + b := &LocalBackend{ + counters: make(map[string]*int64), + gauges: make(map[string]*int64), + timers: make(map[string]*localBackendTimer), + stop: make(chan struct{}), + TagsSep: "|", + TagKVSep: "=", + } + if collectionInterval == 0 { + // Use one histogram time window for all timers + return b + } + b.wg.Add(1) + go b.runLoop(collectionInterval) + return b +} + +// Clear discards accumulated stats +func (b *LocalBackend) Clear() { + b.cm.Lock() + defer b.cm.Unlock() + b.gm.Lock() + defer b.gm.Unlock() + b.tm.Lock() + defer b.tm.Unlock() + b.counters = make(map[string]*int64) + b.gauges = make(map[string]*int64) + b.timers = make(map[string]*localBackendTimer) +} + +func (b *LocalBackend) runLoop(collectionInterval time.Duration) { + defer b.wg.Done() + ticker := time.NewTicker(collectionInterval) + for { + select { + case <-ticker.C: + b.tm.Lock() + timers := make(map[string]*localBackendTimer, len(b.timers)) + for timerName, timer := range b.timers { + timers[timerName] = timer + } + b.tm.Unlock() + + for _, t := range timers { + t.Lock() + t.hist.Rotate() + t.Unlock() + } + case <-b.stop: + ticker.Stop() + return + } + } +} + +// IncCounter increments a counter value +func (b *LocalBackend) IncCounter(name string, tags map[string]string, delta int64) { + name = GetKey(name, tags, b.TagsSep, b.TagKVSep) + b.cm.Lock() + defer b.cm.Unlock() + counter := b.counters[name] + if counter == nil { + b.counters[name] = new(int64) + *b.counters[name] = delta + return + } + atomic.AddInt64(counter, delta) +} + +// UpdateGauge updates the value of a gauge +func (b *LocalBackend) UpdateGauge(name string, tags map[string]string, value int64) { + name = GetKey(name, tags, b.TagsSep, b.TagKVSep) + b.gm.Lock() + defer b.gm.Unlock() + gauge := b.gauges[name] + if gauge == nil { + b.gauges[name] = new(int64) + *b.gauges[name] = value + return + } + atomic.StoreInt64(gauge, value) +} + +// RecordTimer records a timing duration +func (b *LocalBackend) RecordTimer(name string, tags map[string]string, d time.Duration) { + name = GetKey(name, tags, b.TagsSep, b.TagKVSep) + timer := b.findOrCreateTimer(name) + timer.Lock() + timer.hist.Current.RecordValue(int64(d / time.Millisecond)) + timer.Unlock() +} + +func (b *LocalBackend) findOrCreateTimer(name string) *localBackendTimer { + b.tm.Lock() + defer b.tm.Unlock() + if t, ok := b.timers[name]; ok { + return t + } + + t := &localBackendTimer{ + hist: hdrhistogram.NewWindowed(5, 0, int64((5*time.Minute)/time.Millisecond), 1), + } + b.timers[name] = t + return t +} + +type localBackendTimer struct { + sync.Mutex + hist *hdrhistogram.WindowedHistogram +} + +var ( + percentiles = map[string]float64{ + "P50": 50, + "P75": 75, + "P90": 90, + "P95": 95, + "P99": 99, + "P999": 99.9, + } +) + +// Snapshot captures a snapshot of the current counter and gauge values +func (b *LocalBackend) Snapshot() (counters, gauges map[string]int64) { + b.cm.Lock() + defer b.cm.Unlock() + + counters = make(map[string]int64, len(b.counters)) + for name, value := range b.counters { + counters[name] = atomic.LoadInt64(value) + } + + b.gm.Lock() + defer b.gm.Unlock() + + gauges = make(map[string]int64, len(b.gauges)) + for name, value := range b.gauges { + gauges[name] = atomic.LoadInt64(value) + } + + b.tm.Lock() + timers := make(map[string]*localBackendTimer) + for timerName, timer := range b.timers { + timers[timerName] = timer + } + b.tm.Unlock() + + for timerName, timer := range timers { + timer.Lock() + hist := timer.hist.Merge() + timer.Unlock() + for name, q := range percentiles { + gauges[timerName+"."+name] = hist.ValueAtQuantile(q) + } + } + + return +} + +// Stop cleanly closes the background goroutine spawned by NewLocalBackend. +func (b *LocalBackend) Stop() { + close(b.stop) + b.wg.Wait() +} + +// GetKey converts name+tags into a single string of the form +// "name|tag1=value1|...|tagN=valueN", where tag names are +// sorted alphabetically. +func GetKey(name string, tags map[string]string, tagsSep string, tagKVSep string) string { + keys := make([]string, 0, len(tags)) + for k := range tags { + keys = append(keys, k) + } + sort.Strings(keys) + key := name + for _, k := range keys { + key = key + tagsSep + k + tagKVSep + tags[k] + } + return key +} + +type stats struct { + name string + tags map[string]string + localBackend *LocalBackend +} + +type localTimer struct { + stats +} + +func (l *localTimer) Record(d time.Duration) { + l.localBackend.RecordTimer(l.name, l.tags, d) +} + +type localCounter struct { + stats +} + +func (l *localCounter) Inc(delta int64) { + l.localBackend.IncCounter(l.name, l.tags, delta) +} + +type localGauge struct { + stats +} + +func (l *localGauge) Update(value int64) { + l.localBackend.UpdateGauge(l.name, l.tags, value) +} + +// LocalFactory stats factory that creates metrics that are stored locally +type LocalFactory struct { + *LocalBackend + namespace string + tags map[string]string +} + +// NewLocalFactory returns a new LocalMetricsFactory +func NewLocalFactory(collectionInterval time.Duration) *LocalFactory { + return &LocalFactory{ + LocalBackend: NewLocalBackend(collectionInterval), + } +} + +// appendTags adds the tags to the namespace tags and returns a combined map. +func (l *LocalFactory) appendTags(tags map[string]string) map[string]string { + newTags := make(map[string]string) + for k, v := range l.tags { + newTags[k] = v + } + for k, v := range tags { + newTags[k] = v + } + return newTags +} + +func (l *LocalFactory) newNamespace(name string) string { + if l.namespace == "" { + return name + } + + if name == "" { + return l.namespace + } + + return l.namespace + "." + name +} + +// Counter returns a local stats counter +func (l *LocalFactory) Counter(name string, tags map[string]string) Counter { + return &localCounter{ + stats{ + name: l.newNamespace(name), + tags: l.appendTags(tags), + localBackend: l.LocalBackend, + }, + } +} + +// Timer returns a local stats timer. +func (l *LocalFactory) Timer(name string, tags map[string]string) Timer { + return &localTimer{ + stats{ + name: l.newNamespace(name), + tags: l.appendTags(tags), + localBackend: l.LocalBackend, + }, + } +} + +// Gauge returns a local stats gauge. +func (l *LocalFactory) Gauge(name string, tags map[string]string) Gauge { + return &localGauge{ + stats{ + name: l.newNamespace(name), + tags: l.appendTags(tags), + localBackend: l.LocalBackend, + }, + } +} + +// Namespace returns a new namespace. +func (l *LocalFactory) Namespace(name string, tags map[string]string) Factory { + return &LocalFactory{ + namespace: l.newNamespace(name), + tags: l.appendTags(tags), + LocalBackend: l.LocalBackend, + } +} diff --git a/vendor/github.com/uber/jaeger-lib/metrics/metrics.go b/vendor/github.com/uber/jaeger-lib/metrics/metrics.go new file mode 100644 index 0000000000..0b97707b07 --- /dev/null +++ b/vendor/github.com/uber/jaeger-lib/metrics/metrics.go @@ -0,0 +1,85 @@ +// Copyright (c) 2017 Uber Technologies, Inc. +// +// 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 metrics + +import ( + "fmt" + "reflect" + "strings" +) + +// Init initializes the passed in metrics and initializes its fields using the passed in factory. +func Init(metrics interface{}, factory Factory, globalTags map[string]string) { + if err := initMetrics(metrics, factory, globalTags); err != nil { + panic(err.Error()) + } +} + +// initMetrics uses reflection to initialize a struct containing metrics fields +// by assigning new Counter/Gauge/Timer values with the metric name retrieved +// from the `metric` tag and stats tags retrieved from the `tags` tag. +// +// Note: all fields of the struct must be exported, have a `metric` tag, and be +// of type Counter or Gauge or Timer. +func initMetrics(m interface{}, factory Factory, globalTags map[string]string) error { + // Allow user to opt out of reporting metrics by passing in nil. + if factory == nil { + factory = NullFactory + } + + counterPtrType := reflect.TypeOf((*Counter)(nil)).Elem() + gaugePtrType := reflect.TypeOf((*Gauge)(nil)).Elem() + timerPtrType := reflect.TypeOf((*Timer)(nil)).Elem() + + v := reflect.ValueOf(m).Elem() + t := v.Type() + for i := 0; i < t.NumField(); i++ { + tags := make(map[string]string) + for k, v := range globalTags { + tags[k] = v + } + field := t.Field(i) + metric := field.Tag.Get("metric") + if metric == "" { + return fmt.Errorf("Field %s is missing a tag 'metric'", field.Name) + } + if tagString := field.Tag.Get("tags"); tagString != "" { + tagPairs := strings.Split(tagString, ",") + for _, tagPair := range tagPairs { + tag := strings.Split(tagPair, "=") + if len(tag) != 2 { + return fmt.Errorf( + "Field [%s]: Tag [%s] is not of the form key=value in 'tags' string [%s]", + field.Name, tagPair, tagString) + } + tags[tag[0]] = tag[1] + } + } + var obj interface{} + if field.Type.AssignableTo(counterPtrType) { + obj = factory.Counter(metric, tags) + } else if field.Type.AssignableTo(gaugePtrType) { + obj = factory.Gauge(metric, tags) + } else if field.Type.AssignableTo(timerPtrType) { + obj = factory.Timer(metric, tags) + } else { + return fmt.Errorf( + "Field %s is not a pointer to timer, gauge, or counter", + field.Name) + } + v.Field(i).Set(reflect.ValueOf(obj)) + } + return nil +} diff --git a/vendor/github.com/uber/jaeger-lib/metrics/stopwatch.go b/vendor/github.com/uber/jaeger-lib/metrics/stopwatch.go new file mode 100644 index 0000000000..4a8abdb539 --- /dev/null +++ b/vendor/github.com/uber/jaeger-lib/metrics/stopwatch.go @@ -0,0 +1,43 @@ +// Copyright (c) 2017 Uber Technologies, Inc. +// +// 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 metrics + +import ( + "time" +) + +// StartStopwatch begins recording the executing time of an event, returning +// a Stopwatch that should be used to stop the recording the time for +// that event. Multiple events can be occurring simultaneously each +// represented by different active Stopwatches +func StartStopwatch(timer Timer) Stopwatch { + return Stopwatch{t: timer, start: time.Now()} +} + +// A Stopwatch tracks the execution time of a specific event +type Stopwatch struct { + t Timer + start time.Time +} + +// Stop stops executing of the stopwatch and records the amount of elapsed time +func (s Stopwatch) Stop() { + s.t.Record(s.ElapsedTime()) +} + +// ElapsedTime returns the amount of elapsed time (in time.Duration) +func (s Stopwatch) ElapsedTime() time.Duration { + return time.Since(s.start) +} diff --git a/vendor/github.com/uber/jaeger-lib/metrics/timer.go b/vendor/github.com/uber/jaeger-lib/metrics/timer.go new file mode 100644 index 0000000000..e18d222abb --- /dev/null +++ b/vendor/github.com/uber/jaeger-lib/metrics/timer.go @@ -0,0 +1,33 @@ +// Copyright (c) 2017 Uber Technologies, Inc. +// +// 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 metrics + +import ( + "time" +) + +// Timer accumulates observations about how long some operation took, +// and also maintains a historgam of percentiles. +type Timer interface { + // Records the time passed in. + Record(time.Duration) +} + +// NullTimer timer that does nothing +var NullTimer Timer = nullTimer{} + +type nullTimer struct{} + +func (nullTimer) Record(time.Duration) {} diff --git a/vendor/golang.org/x/net/idna/idna.go b/vendor/golang.org/x/net/idna/idna.go new file mode 100644 index 0000000000..346fe4423e --- /dev/null +++ b/vendor/golang.org/x/net/idna/idna.go @@ -0,0 +1,732 @@ +// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. + +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package idna implements IDNA2008 using the compatibility processing +// defined by UTS (Unicode Technical Standard) #46, which defines a standard to +// deal with the transition from IDNA2003. +// +// IDNA2008 (Internationalized Domain Names for Applications), is defined in RFC +// 5890, RFC 5891, RFC 5892, RFC 5893 and RFC 5894. +// UTS #46 is defined in http://www.unicode.org/reports/tr46. +// See http://unicode.org/cldr/utility/idna.jsp for a visualization of the +// differences between these two standards. +package idna // import "golang.org/x/net/idna" + +import ( + "fmt" + "strings" + "unicode/utf8" + + "golang.org/x/text/secure/bidirule" + "golang.org/x/text/unicode/bidi" + "golang.org/x/text/unicode/norm" +) + +// NOTE: Unlike common practice in Go APIs, the functions will return a +// sanitized domain name in case of errors. Browsers sometimes use a partially +// evaluated string as lookup. +// TODO: the current error handling is, in my opinion, the least opinionated. +// Other strategies are also viable, though: +// Option 1) Return an empty string in case of error, but allow the user to +// specify explicitly which errors to ignore. +// Option 2) Return the partially evaluated string if it is itself a valid +// string, otherwise return the empty string in case of error. +// Option 3) Option 1 and 2. +// Option 4) Always return an empty string for now and implement Option 1 as +// needed, and document that the return string may not be empty in case of +// error in the future. +// I think Option 1 is best, but it is quite opinionated. + +// ToASCII is a wrapper for Punycode.ToASCII. +func ToASCII(s string) (string, error) { + return Punycode.process(s, true) +} + +// ToUnicode is a wrapper for Punycode.ToUnicode. +func ToUnicode(s string) (string, error) { + return Punycode.process(s, false) +} + +// An Option configures a Profile at creation time. +type Option func(*options) + +// Transitional sets a Profile to use the Transitional mapping as defined in UTS +// #46. This will cause, for example, "ß" to be mapped to "ss". Using the +// transitional mapping provides a compromise between IDNA2003 and IDNA2008 +// compatibility. It is used by most browsers when resolving domain names. This +// option is only meaningful if combined with MapForLookup. +func Transitional(transitional bool) Option { + return func(o *options) { o.transitional = true } +} + +// VerifyDNSLength sets whether a Profile should fail if any of the IDN parts +// are longer than allowed by the RFC. +func VerifyDNSLength(verify bool) Option { + return func(o *options) { o.verifyDNSLength = verify } +} + +// RemoveLeadingDots removes leading label separators. Leading runes that map to +// dots, such as U+3002 IDEOGRAPHIC FULL STOP, are removed as well. +// +// This is the behavior suggested by the UTS #46 and is adopted by some +// browsers. +func RemoveLeadingDots(remove bool) Option { + return func(o *options) { o.removeLeadingDots = remove } +} + +// ValidateLabels sets whether to check the mandatory label validation criteria +// as defined in Section 5.4 of RFC 5891. This includes testing for correct use +// of hyphens ('-'), normalization, validity of runes, and the context rules. +func ValidateLabels(enable bool) Option { + return func(o *options) { + // Don't override existing mappings, but set one that at least checks + // normalization if it is not set. + if o.mapping == nil && enable { + o.mapping = normalize + } + o.trie = trie + o.validateLabels = enable + o.fromPuny = validateFromPunycode + } +} + +// StrictDomainName limits the set of permissible ASCII characters to those +// allowed in domain names as defined in RFC 1034 (A-Z, a-z, 0-9 and the +// hyphen). This is set by default for MapForLookup and ValidateForRegistration. +// +// This option is useful, for instance, for browsers that allow characters +// outside this range, for example a '_' (U+005F LOW LINE). See +// http://www.rfc-editor.org/std/std3.txt for more details This option +// corresponds to the UseSTD3ASCIIRules option in UTS #46. +func StrictDomainName(use bool) Option { + return func(o *options) { + o.trie = trie + o.useSTD3Rules = use + o.fromPuny = validateFromPunycode + } +} + +// NOTE: the following options pull in tables. The tables should not be linked +// in as long as the options are not used. + +// BidiRule enables the Bidi rule as defined in RFC 5893. Any application +// that relies on proper validation of labels should include this rule. +func BidiRule() Option { + return func(o *options) { o.bidirule = bidirule.ValidString } +} + +// ValidateForRegistration sets validation options to verify that a given IDN is +// properly formatted for registration as defined by Section 4 of RFC 5891. +func ValidateForRegistration() Option { + return func(o *options) { + o.mapping = validateRegistration + StrictDomainName(true)(o) + ValidateLabels(true)(o) + VerifyDNSLength(true)(o) + BidiRule()(o) + } +} + +// MapForLookup sets validation and mapping options such that a given IDN is +// transformed for domain name lookup according to the requirements set out in +// Section 5 of RFC 5891. The mappings follow the recommendations of RFC 5894, +// RFC 5895 and UTS 46. It does not add the Bidi Rule. Use the BidiRule option +// to add this check. +// +// The mappings include normalization and mapping case, width and other +// compatibility mappings. +func MapForLookup() Option { + return func(o *options) { + o.mapping = validateAndMap + StrictDomainName(true)(o) + ValidateLabels(true)(o) + } +} + +type options struct { + transitional bool + useSTD3Rules bool + validateLabels bool + verifyDNSLength bool + removeLeadingDots bool + + trie *idnaTrie + + // fromPuny calls validation rules when converting A-labels to U-labels. + fromPuny func(p *Profile, s string) error + + // mapping implements a validation and mapping step as defined in RFC 5895 + // or UTS 46, tailored to, for example, domain registration or lookup. + mapping func(p *Profile, s string) (mapped string, isBidi bool, err error) + + // bidirule, if specified, checks whether s conforms to the Bidi Rule + // defined in RFC 5893. + bidirule func(s string) bool +} + +// A Profile defines the configuration of an IDNA mapper. +type Profile struct { + options +} + +func apply(o *options, opts []Option) { + for _, f := range opts { + f(o) + } +} + +// New creates a new Profile. +// +// With no options, the returned Profile is the most permissive and equals the +// Punycode Profile. Options can be passed to further restrict the Profile. The +// MapForLookup and ValidateForRegistration options set a collection of options, +// for lookup and registration purposes respectively, which can be tailored by +// adding more fine-grained options, where later options override earlier +// options. +func New(o ...Option) *Profile { + p := &Profile{} + apply(&p.options, o) + return p +} + +// ToASCII converts a domain or domain label to its ASCII form. For example, +// ToASCII("bücher.example.com") is "xn--bcher-kva.example.com", and +// ToASCII("golang") is "golang". If an error is encountered it will return +// an error and a (partially) processed result. +func (p *Profile) ToASCII(s string) (string, error) { + return p.process(s, true) +} + +// ToUnicode converts a domain or domain label to its Unicode form. For example, +// ToUnicode("xn--bcher-kva.example.com") is "bücher.example.com", and +// ToUnicode("golang") is "golang". If an error is encountered it will return +// an error and a (partially) processed result. +func (p *Profile) ToUnicode(s string) (string, error) { + pp := *p + pp.transitional = false + return pp.process(s, false) +} + +// String reports a string with a description of the profile for debugging +// purposes. The string format may change with different versions. +func (p *Profile) String() string { + s := "" + if p.transitional { + s = "Transitional" + } else { + s = "NonTransitional" + } + if p.useSTD3Rules { + s += ":UseSTD3Rules" + } + if p.validateLabels { + s += ":ValidateLabels" + } + if p.verifyDNSLength { + s += ":VerifyDNSLength" + } + return s +} + +var ( + // Punycode is a Profile that does raw punycode processing with a minimum + // of validation. + Punycode *Profile = punycode + + // Lookup is the recommended profile for looking up domain names, according + // to Section 5 of RFC 5891. The exact configuration of this profile may + // change over time. + Lookup *Profile = lookup + + // Display is the recommended profile for displaying domain names. + // The configuration of this profile may change over time. + Display *Profile = display + + // Registration is the recommended profile for checking whether a given + // IDN is valid for registration, according to Section 4 of RFC 5891. + Registration *Profile = registration + + punycode = &Profile{} + lookup = &Profile{options{ + transitional: true, + useSTD3Rules: true, + validateLabels: true, + trie: trie, + fromPuny: validateFromPunycode, + mapping: validateAndMap, + bidirule: bidirule.ValidString, + }} + display = &Profile{options{ + useSTD3Rules: true, + validateLabels: true, + trie: trie, + fromPuny: validateFromPunycode, + mapping: validateAndMap, + bidirule: bidirule.ValidString, + }} + registration = &Profile{options{ + useSTD3Rules: true, + validateLabels: true, + verifyDNSLength: true, + trie: trie, + fromPuny: validateFromPunycode, + mapping: validateRegistration, + bidirule: bidirule.ValidString, + }} + + // TODO: profiles + // Register: recommended for approving domain names: don't do any mappings + // but rather reject on invalid input. Bundle or block deviation characters. +) + +type labelError struct{ label, code_ string } + +func (e labelError) code() string { return e.code_ } +func (e labelError) Error() string { + return fmt.Sprintf("idna: invalid label %q", e.label) +} + +type runeError rune + +func (e runeError) code() string { return "P1" } +func (e runeError) Error() string { + return fmt.Sprintf("idna: disallowed rune %U", e) +} + +// process implements the algorithm described in section 4 of UTS #46, +// see http://www.unicode.org/reports/tr46. +func (p *Profile) process(s string, toASCII bool) (string, error) { + var err error + var isBidi bool + if p.mapping != nil { + s, isBidi, err = p.mapping(p, s) + } + // Remove leading empty labels. + if p.removeLeadingDots { + for ; len(s) > 0 && s[0] == '.'; s = s[1:] { + } + } + // TODO: allow for a quick check of the tables data. + // It seems like we should only create this error on ToASCII, but the + // UTS 46 conformance tests suggests we should always check this. + if err == nil && p.verifyDNSLength && s == "" { + err = &labelError{s, "A4"} + } + labels := labelIter{orig: s} + for ; !labels.done(); labels.next() { + label := labels.label() + if label == "" { + // Empty labels are not okay. The label iterator skips the last + // label if it is empty. + if err == nil && p.verifyDNSLength { + err = &labelError{s, "A4"} + } + continue + } + if strings.HasPrefix(label, acePrefix) { + u, err2 := decode(label[len(acePrefix):]) + if err2 != nil { + if err == nil { + err = err2 + } + // Spec says keep the old label. + continue + } + isBidi = isBidi || bidirule.DirectionString(u) != bidi.LeftToRight + labels.set(u) + if err == nil && p.validateLabels { + err = p.fromPuny(p, u) + } + if err == nil { + // This should be called on NonTransitional, according to the + // spec, but that currently does not have any effect. Use the + // original profile to preserve options. + err = p.validateLabel(u) + } + } else if err == nil { + err = p.validateLabel(label) + } + } + if isBidi && p.bidirule != nil && err == nil { + for labels.reset(); !labels.done(); labels.next() { + if !p.bidirule(labels.label()) { + err = &labelError{s, "B"} + break + } + } + } + if toASCII { + for labels.reset(); !labels.done(); labels.next() { + label := labels.label() + if !ascii(label) { + a, err2 := encode(acePrefix, label) + if err == nil { + err = err2 + } + label = a + labels.set(a) + } + n := len(label) + if p.verifyDNSLength && err == nil && (n == 0 || n > 63) { + err = &labelError{label, "A4"} + } + } + } + s = labels.result() + if toASCII && p.verifyDNSLength && err == nil { + // Compute the length of the domain name minus the root label and its dot. + n := len(s) + if n > 0 && s[n-1] == '.' { + n-- + } + if len(s) < 1 || n > 253 { + err = &labelError{s, "A4"} + } + } + return s, err +} + +func normalize(p *Profile, s string) (mapped string, isBidi bool, err error) { + // TODO: consider first doing a quick check to see if any of these checks + // need to be done. This will make it slower in the general case, but + // faster in the common case. + mapped = norm.NFC.String(s) + isBidi = bidirule.DirectionString(mapped) == bidi.RightToLeft + return mapped, isBidi, nil +} + +func validateRegistration(p *Profile, s string) (idem string, bidi bool, err error) { + // TODO: filter need for normalization in loop below. + if !norm.NFC.IsNormalString(s) { + return s, false, &labelError{s, "V1"} + } + for i := 0; i < len(s); { + v, sz := trie.lookupString(s[i:]) + if sz == 0 { + return s, bidi, runeError(utf8.RuneError) + } + bidi = bidi || info(v).isBidi(s[i:]) + // Copy bytes not copied so far. + switch p.simplify(info(v).category()) { + // TODO: handle the NV8 defined in the Unicode idna data set to allow + // for strict conformance to IDNA2008. + case valid, deviation: + case disallowed, mapped, unknown, ignored: + r, _ := utf8.DecodeRuneInString(s[i:]) + return s, bidi, runeError(r) + } + i += sz + } + return s, bidi, nil +} + +func (c info) isBidi(s string) bool { + if !c.isMapped() { + return c&attributesMask == rtl + } + // TODO: also store bidi info for mapped data. This is possible, but a bit + // cumbersome and not for the common case. + p, _ := bidi.LookupString(s) + switch p.Class() { + case bidi.R, bidi.AL, bidi.AN: + return true + } + return false +} + +func validateAndMap(p *Profile, s string) (vm string, bidi bool, err error) { + var ( + b []byte + k int + ) + // combinedInfoBits contains the or-ed bits of all runes. We use this + // to derive the mayNeedNorm bit later. This may trigger normalization + // overeagerly, but it will not do so in the common case. The end result + // is another 10% saving on BenchmarkProfile for the common case. + var combinedInfoBits info + for i := 0; i < len(s); { + v, sz := trie.lookupString(s[i:]) + if sz == 0 { + b = append(b, s[k:i]...) + b = append(b, "\ufffd"...) + k = len(s) + if err == nil { + err = runeError(utf8.RuneError) + } + break + } + combinedInfoBits |= info(v) + bidi = bidi || info(v).isBidi(s[i:]) + start := i + i += sz + // Copy bytes not copied so far. + switch p.simplify(info(v).category()) { + case valid: + continue + case disallowed: + if err == nil { + r, _ := utf8.DecodeRuneInString(s[start:]) + err = runeError(r) + } + continue + case mapped, deviation: + b = append(b, s[k:start]...) + b = info(v).appendMapping(b, s[start:i]) + case ignored: + b = append(b, s[k:start]...) + // drop the rune + case unknown: + b = append(b, s[k:start]...) + b = append(b, "\ufffd"...) + } + k = i + } + if k == 0 { + // No changes so far. + if combinedInfoBits&mayNeedNorm != 0 { + s = norm.NFC.String(s) + } + } else { + b = append(b, s[k:]...) + if norm.NFC.QuickSpan(b) != len(b) { + b = norm.NFC.Bytes(b) + } + // TODO: the punycode converters require strings as input. + s = string(b) + } + return s, bidi, err +} + +// A labelIter allows iterating over domain name labels. +type labelIter struct { + orig string + slice []string + curStart int + curEnd int + i int +} + +func (l *labelIter) reset() { + l.curStart = 0 + l.curEnd = 0 + l.i = 0 +} + +func (l *labelIter) done() bool { + return l.curStart >= len(l.orig) +} + +func (l *labelIter) result() string { + if l.slice != nil { + return strings.Join(l.slice, ".") + } + return l.orig +} + +func (l *labelIter) label() string { + if l.slice != nil { + return l.slice[l.i] + } + p := strings.IndexByte(l.orig[l.curStart:], '.') + l.curEnd = l.curStart + p + if p == -1 { + l.curEnd = len(l.orig) + } + return l.orig[l.curStart:l.curEnd] +} + +// next sets the value to the next label. It skips the last label if it is empty. +func (l *labelIter) next() { + l.i++ + if l.slice != nil { + if l.i >= len(l.slice) || l.i == len(l.slice)-1 && l.slice[l.i] == "" { + l.curStart = len(l.orig) + } + } else { + l.curStart = l.curEnd + 1 + if l.curStart == len(l.orig)-1 && l.orig[l.curStart] == '.' { + l.curStart = len(l.orig) + } + } +} + +func (l *labelIter) set(s string) { + if l.slice == nil { + l.slice = strings.Split(l.orig, ".") + } + l.slice[l.i] = s +} + +// acePrefix is the ASCII Compatible Encoding prefix. +const acePrefix = "xn--" + +func (p *Profile) simplify(cat category) category { + switch cat { + case disallowedSTD3Mapped: + if p.useSTD3Rules { + cat = disallowed + } else { + cat = mapped + } + case disallowedSTD3Valid: + if p.useSTD3Rules { + cat = disallowed + } else { + cat = valid + } + case deviation: + if !p.transitional { + cat = valid + } + case validNV8, validXV8: + // TODO: handle V2008 + cat = valid + } + return cat +} + +func validateFromPunycode(p *Profile, s string) error { + if !norm.NFC.IsNormalString(s) { + return &labelError{s, "V1"} + } + // TODO: detect whether string may have to be normalized in the following + // loop. + for i := 0; i < len(s); { + v, sz := trie.lookupString(s[i:]) + if sz == 0 { + return runeError(utf8.RuneError) + } + if c := p.simplify(info(v).category()); c != valid && c != deviation { + return &labelError{s, "V6"} + } + i += sz + } + return nil +} + +const ( + zwnj = "\u200c" + zwj = "\u200d" +) + +type joinState int8 + +const ( + stateStart joinState = iota + stateVirama + stateBefore + stateBeforeVirama + stateAfter + stateFAIL +) + +var joinStates = [][numJoinTypes]joinState{ + stateStart: { + joiningL: stateBefore, + joiningD: stateBefore, + joinZWNJ: stateFAIL, + joinZWJ: stateFAIL, + joinVirama: stateVirama, + }, + stateVirama: { + joiningL: stateBefore, + joiningD: stateBefore, + }, + stateBefore: { + joiningL: stateBefore, + joiningD: stateBefore, + joiningT: stateBefore, + joinZWNJ: stateAfter, + joinZWJ: stateFAIL, + joinVirama: stateBeforeVirama, + }, + stateBeforeVirama: { + joiningL: stateBefore, + joiningD: stateBefore, + joiningT: stateBefore, + }, + stateAfter: { + joiningL: stateFAIL, + joiningD: stateBefore, + joiningT: stateAfter, + joiningR: stateStart, + joinZWNJ: stateFAIL, + joinZWJ: stateFAIL, + joinVirama: stateAfter, // no-op as we can't accept joiners here + }, + stateFAIL: { + 0: stateFAIL, + joiningL: stateFAIL, + joiningD: stateFAIL, + joiningT: stateFAIL, + joiningR: stateFAIL, + joinZWNJ: stateFAIL, + joinZWJ: stateFAIL, + joinVirama: stateFAIL, + }, +} + +// validateLabel validates the criteria from Section 4.1. Item 1, 4, and 6 are +// already implicitly satisfied by the overall implementation. +func (p *Profile) validateLabel(s string) (err error) { + if s == "" { + if p.verifyDNSLength { + return &labelError{s, "A4"} + } + return nil + } + if !p.validateLabels { + return nil + } + trie := p.trie // p.validateLabels is only set if trie is set. + if len(s) > 4 && s[2] == '-' && s[3] == '-' { + return &labelError{s, "V2"} + } + if s[0] == '-' || s[len(s)-1] == '-' { + return &labelError{s, "V3"} + } + // TODO: merge the use of this in the trie. + v, sz := trie.lookupString(s) + x := info(v) + if x.isModifier() { + return &labelError{s, "V5"} + } + // Quickly return in the absence of zero-width (non) joiners. + if strings.Index(s, zwj) == -1 && strings.Index(s, zwnj) == -1 { + return nil + } + st := stateStart + for i := 0; ; { + jt := x.joinType() + if s[i:i+sz] == zwj { + jt = joinZWJ + } else if s[i:i+sz] == zwnj { + jt = joinZWNJ + } + st = joinStates[st][jt] + if x.isViramaModifier() { + st = joinStates[st][joinVirama] + } + if i += sz; i == len(s) { + break + } + v, sz = trie.lookupString(s[i:]) + x = info(v) + } + if st == stateFAIL || st == stateAfter { + return &labelError{s, "C"} + } + return nil +} + +func ascii(s string) bool { + for i := 0; i < len(s); i++ { + if s[i] >= utf8.RuneSelf { + return false + } + } + return true +} diff --git a/vendor/golang.org/x/net/idna/punycode.go b/vendor/golang.org/x/net/idna/punycode.go new file mode 100644 index 0000000000..02c7d59af3 --- /dev/null +++ b/vendor/golang.org/x/net/idna/punycode.go @@ -0,0 +1,203 @@ +// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. + +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package idna + +// This file implements the Punycode algorithm from RFC 3492. + +import ( + "math" + "strings" + "unicode/utf8" +) + +// These parameter values are specified in section 5. +// +// All computation is done with int32s, so that overflow behavior is identical +// regardless of whether int is 32-bit or 64-bit. +const ( + base int32 = 36 + damp int32 = 700 + initialBias int32 = 72 + initialN int32 = 128 + skew int32 = 38 + tmax int32 = 26 + tmin int32 = 1 +) + +func punyError(s string) error { return &labelError{s, "A3"} } + +// decode decodes a string as specified in section 6.2. +func decode(encoded string) (string, error) { + if encoded == "" { + return "", nil + } + pos := 1 + strings.LastIndex(encoded, "-") + if pos == 1 { + return "", punyError(encoded) + } + if pos == len(encoded) { + return encoded[:len(encoded)-1], nil + } + output := make([]rune, 0, len(encoded)) + if pos != 0 { + for _, r := range encoded[:pos-1] { + output = append(output, r) + } + } + i, n, bias := int32(0), initialN, initialBias + for pos < len(encoded) { + oldI, w := i, int32(1) + for k := base; ; k += base { + if pos == len(encoded) { + return "", punyError(encoded) + } + digit, ok := decodeDigit(encoded[pos]) + if !ok { + return "", punyError(encoded) + } + pos++ + i += digit * w + if i < 0 { + return "", punyError(encoded) + } + t := k - bias + if t < tmin { + t = tmin + } else if t > tmax { + t = tmax + } + if digit < t { + break + } + w *= base - t + if w >= math.MaxInt32/base { + return "", punyError(encoded) + } + } + x := int32(len(output) + 1) + bias = adapt(i-oldI, x, oldI == 0) + n += i / x + i %= x + if n > utf8.MaxRune || len(output) >= 1024 { + return "", punyError(encoded) + } + output = append(output, 0) + copy(output[i+1:], output[i:]) + output[i] = n + i++ + } + return string(output), nil +} + +// encode encodes a string as specified in section 6.3 and prepends prefix to +// the result. +// +// The "while h < length(input)" line in the specification becomes "for +// remaining != 0" in the Go code, because len(s) in Go is in bytes, not runes. +func encode(prefix, s string) (string, error) { + output := make([]byte, len(prefix), len(prefix)+1+2*len(s)) + copy(output, prefix) + delta, n, bias := int32(0), initialN, initialBias + b, remaining := int32(0), int32(0) + for _, r := range s { + if r < 0x80 { + b++ + output = append(output, byte(r)) + } else { + remaining++ + } + } + h := b + if b > 0 { + output = append(output, '-') + } + for remaining != 0 { + m := int32(0x7fffffff) + for _, r := range s { + if m > r && r >= n { + m = r + } + } + delta += (m - n) * (h + 1) + if delta < 0 { + return "", punyError(s) + } + n = m + for _, r := range s { + if r < n { + delta++ + if delta < 0 { + return "", punyError(s) + } + continue + } + if r > n { + continue + } + q := delta + for k := base; ; k += base { + t := k - bias + if t < tmin { + t = tmin + } else if t > tmax { + t = tmax + } + if q < t { + break + } + output = append(output, encodeDigit(t+(q-t)%(base-t))) + q = (q - t) / (base - t) + } + output = append(output, encodeDigit(q)) + bias = adapt(delta, h+1, h == b) + delta = 0 + h++ + remaining-- + } + delta++ + n++ + } + return string(output), nil +} + +func decodeDigit(x byte) (digit int32, ok bool) { + switch { + case '0' <= x && x <= '9': + return int32(x - ('0' - 26)), true + case 'A' <= x && x <= 'Z': + return int32(x - 'A'), true + case 'a' <= x && x <= 'z': + return int32(x - 'a'), true + } + return 0, false +} + +func encodeDigit(digit int32) byte { + switch { + case 0 <= digit && digit < 26: + return byte(digit + 'a') + case 26 <= digit && digit < 36: + return byte(digit + ('0' - 26)) + } + panic("idna: internal error in punycode encoding") +} + +// adapt is the bias adaptation function specified in section 6.1. +func adapt(delta, numPoints int32, firstTime bool) int32 { + if firstTime { + delta /= damp + } else { + delta /= 2 + } + delta += delta / numPoints + k := int32(0) + for delta > ((base-tmin)*tmax)/2 { + delta /= base - tmin + k += base + } + return k + (base-tmin+1)*delta/(delta+skew) +} diff --git a/vendor/golang.org/x/net/idna/tables.go b/vendor/golang.org/x/net/idna/tables.go new file mode 100644 index 0000000000..f910b26914 --- /dev/null +++ b/vendor/golang.org/x/net/idna/tables.go @@ -0,0 +1,4557 @@ +// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. + +package idna + +// UnicodeVersion is the Unicode version from which the tables in this package are derived. +const UnicodeVersion = "10.0.0" + +var mappings string = "" + // Size: 8176 bytes + "\x00\x01 \x03 ̈\x01a\x03 ̄\x012\x013\x03 ́\x03 ̧\x011\x01o\x051⁄4\x051⁄2" + + "\x053⁄4\x03i̇\x03l·\x03ʼn\x01s\x03dž\x03ⱥ\x03ⱦ\x01h\x01j\x01r\x01w\x01y" + + "\x03 ̆\x03 ̇\x03 ̊\x03 ̨\x03 ̃\x03 ̋\x01l\x01x\x04̈́\x03 ι\x01;\x05 ̈́" + + "\x04եւ\x04اٴ\x04وٴ\x04ۇٴ\x04يٴ\x06क़\x06ख़\x06ग़\x06ज़\x06ड़\x06ढ़\x06फ़" + + "\x06य़\x06ড়\x06ঢ়\x06য়\x06ਲ਼\x06ਸ਼\x06ਖ਼\x06ਗ਼\x06ਜ਼\x06ਫ਼\x06ଡ଼\x06ଢ଼" + + "\x06ํา\x06ໍາ\x06ຫນ\x06ຫມ\x06གྷ\x06ཌྷ\x06དྷ\x06བྷ\x06ཛྷ\x06ཀྵ\x06ཱི\x06ཱུ" + + "\x06ྲྀ\x09ྲཱྀ\x06ླྀ\x09ླཱྀ\x06ཱྀ\x06ྒྷ\x06ྜྷ\x06ྡྷ\x06ྦྷ\x06ྫྷ\x06ྐྵ\x02" + + "в\x02д\x02о\x02с\x02т\x02ъ\x02ѣ\x02æ\x01b\x01d\x01e\x02ǝ\x01g\x01i\x01k" + + "\x01m\x01n\x02ȣ\x01p\x01t\x01u\x02ɐ\x02ɑ\x02ə\x02ɛ\x02ɜ\x02ŋ\x02ɔ\x02ɯ" + + "\x01v\x02β\x02γ\x02δ\x02φ\x02χ\x02ρ\x02н\x02ɒ\x01c\x02ɕ\x02ð\x01f\x02ɟ" + + "\x02ɡ\x02ɥ\x02ɨ\x02ɩ\x02ɪ\x02ʝ\x02ɭ\x02ʟ\x02ɱ\x02ɰ\x02ɲ\x02ɳ\x02ɴ\x02ɵ" + + "\x02ɸ\x02ʂ\x02ʃ\x02ƫ\x02ʉ\x02ʊ\x02ʋ\x02ʌ\x01z\x02ʐ\x02ʑ\x02ʒ\x02θ\x02ss" + + "\x02ά\x02έ\x02ή\x02ί\x02ό\x02ύ\x02ώ\x05ἀι\x05ἁι\x05ἂι\x05ἃι\x05ἄι\x05ἅι" + + "\x05ἆι\x05ἇι\x05ἠι\x05ἡι\x05ἢι\x05ἣι\x05ἤι\x05ἥι\x05ἦι\x05ἧι\x05ὠι\x05ὡι" + + "\x05ὢι\x05ὣι\x05ὤι\x05ὥι\x05ὦι\x05ὧι\x05ὰι\x04αι\x04άι\x05ᾶι\x02ι\x05 ̈͂" + + "\x05ὴι\x04ηι\x04ήι\x05ῆι\x05 ̓̀\x05 ̓́\x05 ̓͂\x02ΐ\x05 ̔̀\x05 ̔́\x05 ̔͂" + + "\x02ΰ\x05 ̈̀\x01`\x05ὼι\x04ωι\x04ώι\x05ῶι\x06′′\x09′′′\x06‵‵\x09‵‵‵\x02!" + + "!\x02??\x02?!\x02!?\x0c′′′′\x010\x014\x015\x016\x017\x018\x019\x01+\x01=" + + "\x01(\x01)\x02rs\x02ħ\x02no\x01q\x02sm\x02tm\x02ω\x02å\x02א\x02ב\x02ג" + + "\x02ד\x02π\x051⁄7\x051⁄9\x061⁄10\x051⁄3\x052⁄3\x051⁄5\x052⁄5\x053⁄5\x054" + + "⁄5\x051⁄6\x055⁄6\x051⁄8\x053⁄8\x055⁄8\x057⁄8\x041⁄\x02ii\x02iv\x02vi" + + "\x04viii\x02ix\x02xi\x050⁄3\x06∫∫\x09∫∫∫\x06∮∮\x09∮∮∮\x0210\x0211\x0212" + + "\x0213\x0214\x0215\x0216\x0217\x0218\x0219\x0220\x04(10)\x04(11)\x04(12)" + + "\x04(13)\x04(14)\x04(15)\x04(16)\x04(17)\x04(18)\x04(19)\x04(20)\x0c∫∫∫∫" + + "\x02==\x05⫝̸\x02ɫ\x02ɽ\x02ȿ\x02ɀ\x01.\x04 ゙\x04 ゚\x06より\x06コト\x05(ᄀ)\x05" + + "(ᄂ)\x05(ᄃ)\x05(ᄅ)\x05(ᄆ)\x05(ᄇ)\x05(ᄉ)\x05(ᄋ)\x05(ᄌ)\x05(ᄎ)\x05(ᄏ)\x05(ᄐ" + + ")\x05(ᄑ)\x05(ᄒ)\x05(가)\x05(나)\x05(다)\x05(라)\x05(마)\x05(바)\x05(사)\x05(아)" + + "\x05(자)\x05(차)\x05(카)\x05(타)\x05(파)\x05(하)\x05(주)\x08(오전)\x08(오후)\x05(一)" + + "\x05(二)\x05(三)\x05(四)\x05(五)\x05(六)\x05(七)\x05(八)\x05(九)\x05(十)\x05(月)" + + "\x05(火)\x05(水)\x05(木)\x05(金)\x05(土)\x05(日)\x05(株)\x05(有)\x05(社)\x05(名)" + + "\x05(特)\x05(財)\x05(祝)\x05(労)\x05(代)\x05(呼)\x05(学)\x05(監)\x05(企)\x05(資)" + + "\x05(協)\x05(祭)\x05(休)\x05(自)\x05(至)\x0221\x0222\x0223\x0224\x0225\x0226" + + "\x0227\x0228\x0229\x0230\x0231\x0232\x0233\x0234\x0235\x06참고\x06주의\x0236" + + "\x0237\x0238\x0239\x0240\x0241\x0242\x0243\x0244\x0245\x0246\x0247\x0248" + + "\x0249\x0250\x041月\x042月\x043月\x044月\x045月\x046月\x047月\x048月\x049月\x0510" + + "月\x0511月\x0512月\x02hg\x02ev\x0cアパート\x0cアルファ\x0cアンペア\x09アール\x0cイニング\x09" + + "インチ\x09ウォン\x0fエスクード\x0cエーカー\x09オンス\x09オーム\x09カイリ\x0cカラット\x0cカロリー\x09ガロ" + + "ン\x09ガンマ\x06ギガ\x09ギニー\x0cキュリー\x0cギルダー\x06キロ\x0fキログラム\x12キロメートル\x0fキロワッ" + + "ト\x09グラム\x0fグラムトン\x0fクルゼイロ\x0cクローネ\x09ケース\x09コルナ\x09コーポ\x0cサイクル\x0fサンチ" + + "ーム\x0cシリング\x09センチ\x09セント\x09ダース\x06デシ\x06ドル\x06トン\x06ナノ\x09ノット\x09ハイツ" + + "\x0fパーセント\x09パーツ\x0cバーレル\x0fピアストル\x09ピクル\x06ピコ\x06ビル\x0fファラッド\x0cフィート" + + "\x0fブッシェル\x09フラン\x0fヘクタール\x06ペソ\x09ペニヒ\x09ヘルツ\x09ペンス\x09ページ\x09ベータ\x0cポイ" + + "ント\x09ボルト\x06ホン\x09ポンド\x09ホール\x09ホーン\x0cマイクロ\x09マイル\x09マッハ\x09マルク\x0fマ" + + "ンション\x0cミクロン\x06ミリ\x0fミリバール\x06メガ\x0cメガトン\x0cメートル\x09ヤード\x09ヤール\x09ユアン" + + "\x0cリットル\x06リラ\x09ルピー\x0cルーブル\x06レム\x0fレントゲン\x09ワット\x040点\x041点\x042点" + + "\x043点\x044点\x045点\x046点\x047点\x048点\x049点\x0510点\x0511点\x0512点\x0513点" + + "\x0514点\x0515点\x0516点\x0517点\x0518点\x0519点\x0520点\x0521点\x0522点\x0523点" + + "\x0524点\x02da\x02au\x02ov\x02pc\x02dm\x02iu\x06平成\x06昭和\x06大正\x06明治\x0c株" + + "式会社\x02pa\x02na\x02ma\x02ka\x02kb\x02mb\x02gb\x04kcal\x02pf\x02nf\x02m" + + "g\x02kg\x02hz\x02ml\x02dl\x02kl\x02fm\x02nm\x02mm\x02cm\x02km\x02m2\x02m" + + "3\x05m∕s\x06m∕s2\x07rad∕s\x08rad∕s2\x02ps\x02ns\x02ms\x02pv\x02nv\x02mv" + + "\x02kv\x02pw\x02nw\x02mw\x02kw\x02bq\x02cc\x02cd\x06c∕kg\x02db\x02gy\x02" + + "ha\x02hp\x02in\x02kk\x02kt\x02lm\x02ln\x02lx\x02ph\x02pr\x02sr\x02sv\x02" + + "wb\x05v∕m\x05a∕m\x041日\x042日\x043日\x044日\x045日\x046日\x047日\x048日\x049日" + + "\x0510日\x0511日\x0512日\x0513日\x0514日\x0515日\x0516日\x0517日\x0518日\x0519日" + + "\x0520日\x0521日\x0522日\x0523日\x0524日\x0525日\x0526日\x0527日\x0528日\x0529日" + + "\x0530日\x0531日\x02ь\x02ɦ\x02ɬ\x02ʞ\x02ʇ\x02œ\x04𤋮\x04𢡊\x04𢡄\x04𣏕\x04𥉉" + + "\x04𥳐\x04𧻓\x02ff\x02fi\x02fl\x02st\x04մն\x04մե\x04մի\x04վն\x04մխ\x04יִ" + + "\x04ײַ\x02ע\x02ה\x02כ\x02ל\x02ם\x02ר\x02ת\x04שׁ\x04שׂ\x06שּׁ\x06שּׂ\x04א" + + "ַ\x04אָ\x04אּ\x04בּ\x04גּ\x04דּ\x04הּ\x04וּ\x04זּ\x04טּ\x04יּ\x04ךּ\x04" + + "כּ\x04לּ\x04מּ\x04נּ\x04סּ\x04ףּ\x04פּ\x04צּ\x04קּ\x04רּ\x04שּ\x04תּ" + + "\x04וֹ\x04בֿ\x04כֿ\x04פֿ\x04אל\x02ٱ\x02ٻ\x02پ\x02ڀ\x02ٺ\x02ٿ\x02ٹ\x02ڤ" + + "\x02ڦ\x02ڄ\x02ڃ\x02چ\x02ڇ\x02ڍ\x02ڌ\x02ڎ\x02ڈ\x02ژ\x02ڑ\x02ک\x02گ\x02ڳ" + + "\x02ڱ\x02ں\x02ڻ\x02ۀ\x02ہ\x02ھ\x02ے\x02ۓ\x02ڭ\x02ۇ\x02ۆ\x02ۈ\x02ۋ\x02ۅ" + + "\x02ۉ\x02ې\x02ى\x04ئا\x04ئە\x04ئو\x04ئۇ\x04ئۆ\x04ئۈ\x04ئې\x04ئى\x02ی\x04" + + "ئج\x04ئح\x04ئم\x04ئي\x04بج\x04بح\x04بخ\x04بم\x04بى\x04بي\x04تج\x04تح" + + "\x04تخ\x04تم\x04تى\x04تي\x04ثج\x04ثم\x04ثى\x04ثي\x04جح\x04جم\x04حج\x04حم" + + "\x04خج\x04خح\x04خم\x04سج\x04سح\x04سخ\x04سم\x04صح\x04صم\x04ضج\x04ضح\x04ضخ" + + "\x04ضم\x04طح\x04طم\x04ظم\x04عج\x04عم\x04غج\x04غم\x04فج\x04فح\x04فخ\x04فم" + + "\x04فى\x04في\x04قح\x04قم\x04قى\x04قي\x04كا\x04كج\x04كح\x04كخ\x04كل\x04كم" + + "\x04كى\x04كي\x04لج\x04لح\x04لخ\x04لم\x04لى\x04لي\x04مج\x04مح\x04مخ\x04مم" + + "\x04مى\x04مي\x04نج\x04نح\x04نخ\x04نم\x04نى\x04ني\x04هج\x04هم\x04هى\x04هي" + + "\x04يج\x04يح\x04يخ\x04يم\x04يى\x04يي\x04ذٰ\x04رٰ\x04ىٰ\x05 ٌّ\x05 ٍّ\x05" + + " َّ\x05 ُّ\x05 ِّ\x05 ّٰ\x04ئر\x04ئز\x04ئن\x04بر\x04بز\x04بن\x04تر\x04تز" + + "\x04تن\x04ثر\x04ثز\x04ثن\x04ما\x04نر\x04نز\x04نن\x04ير\x04يز\x04ين\x04ئخ" + + "\x04ئه\x04به\x04ته\x04صخ\x04له\x04نه\x04هٰ\x04يه\x04ثه\x04سه\x04شم\x04شه" + + "\x06ـَّ\x06ـُّ\x06ـِّ\x04طى\x04طي\x04عى\x04عي\x04غى\x04غي\x04سى\x04سي" + + "\x04شى\x04شي\x04حى\x04حي\x04جى\x04جي\x04خى\x04خي\x04صى\x04صي\x04ضى\x04ضي" + + "\x04شج\x04شح\x04شخ\x04شر\x04سر\x04صر\x04ضر\x04اً\x06تجم\x06تحج\x06تحم" + + "\x06تخم\x06تمج\x06تمح\x06تمخ\x06جمح\x06حمي\x06حمى\x06سحج\x06سجح\x06سجى" + + "\x06سمح\x06سمج\x06سمم\x06صحح\x06صمم\x06شحم\x06شجي\x06شمخ\x06شمم\x06ضحى" + + "\x06ضخم\x06طمح\x06طمم\x06طمي\x06عجم\x06عمم\x06عمى\x06غمم\x06غمي\x06غمى" + + "\x06فخم\x06قمح\x06قمم\x06لحم\x06لحي\x06لحى\x06لجج\x06لخم\x06لمح\x06محج" + + "\x06محم\x06محي\x06مجح\x06مجم\x06مخج\x06مخم\x06مجخ\x06همج\x06همم\x06نحم" + + "\x06نحى\x06نجم\x06نجى\x06نمي\x06نمى\x06يمم\x06بخي\x06تجي\x06تجى\x06تخي" + + "\x06تخى\x06تمي\x06تمى\x06جمي\x06جحى\x06جمى\x06سخى\x06صحي\x06شحي\x06ضحي" + + "\x06لجي\x06لمي\x06يحي\x06يجي\x06يمي\x06ممي\x06قمي\x06نحي\x06عمي\x06كمي" + + "\x06نجح\x06مخي\x06لجم\x06كمم\x06جحي\x06حجي\x06مجي\x06فمي\x06بحي\x06سخي" + + "\x06نجي\x06صلے\x06قلے\x08الله\x08اكبر\x08محمد\x08صلعم\x08رسول\x08عليه" + + "\x08وسلم\x06صلى!صلى الله عليه وسلم\x0fجل جلاله\x08ریال\x01,\x01:\x01!" + + "\x01?\x01_\x01{\x01}\x01[\x01]\x01#\x01&\x01*\x01-\x01<\x01>\x01\\\x01$" + + "\x01%\x01@\x04ـً\x04ـَ\x04ـُ\x04ـِ\x04ـّ\x04ـْ\x02ء\x02آ\x02أ\x02ؤ\x02إ" + + "\x02ئ\x02ا\x02ب\x02ة\x02ت\x02ث\x02ج\x02ح\x02خ\x02د\x02ذ\x02ر\x02ز\x02س" + + "\x02ش\x02ص\x02ض\x02ط\x02ظ\x02ع\x02غ\x02ف\x02ق\x02ك\x02ل\x02م\x02ن\x02ه" + + "\x02و\x02ي\x04لآ\x04لأ\x04لإ\x04لا\x01\x22\x01'\x01/\x01^\x01|\x01~\x02¢" + + "\x02£\x02¬\x02¦\x02¥\x08𝅗𝅥\x08𝅘𝅥\x0c𝅘𝅥𝅮\x0c𝅘𝅥𝅯\x0c𝅘𝅥𝅰\x0c𝅘𝅥𝅱\x0c𝅘𝅥𝅲\x08𝆹" + + "𝅥\x08𝆺𝅥\x0c𝆹𝅥𝅮\x0c𝆺𝅥𝅮\x0c𝆹𝅥𝅯\x0c𝆺𝅥𝅯\x02ı\x02ȷ\x02α\x02ε\x02ζ\x02η\x02" + + "κ\x02λ\x02μ\x02ν\x02ξ\x02ο\x02σ\x02τ\x02υ\x02ψ\x03∇\x03∂\x02ϝ\x02ٮ\x02ڡ" + + "\x02ٯ\x020,\x021,\x022,\x023,\x024,\x025,\x026,\x027,\x028,\x029,\x03(a)" + + "\x03(b)\x03(c)\x03(d)\x03(e)\x03(f)\x03(g)\x03(h)\x03(i)\x03(j)\x03(k)" + + "\x03(l)\x03(m)\x03(n)\x03(o)\x03(p)\x03(q)\x03(r)\x03(s)\x03(t)\x03(u)" + + "\x03(v)\x03(w)\x03(x)\x03(y)\x03(z)\x07〔s〕\x02wz\x02hv\x02sd\x03ppv\x02w" + + "c\x02mc\x02md\x02dj\x06ほか\x06ココ\x03サ\x03手\x03字\x03双\x03デ\x03二\x03多\x03解" + + "\x03天\x03交\x03映\x03無\x03料\x03前\x03後\x03再\x03新\x03初\x03終\x03生\x03販\x03声" + + "\x03吹\x03演\x03投\x03捕\x03一\x03三\x03遊\x03左\x03中\x03右\x03指\x03走\x03打\x03禁" + + "\x03空\x03合\x03満\x03有\x03月\x03申\x03割\x03営\x03配\x09〔本〕\x09〔三〕\x09〔二〕\x09〔安" + + "〕\x09〔点〕\x09〔打〕\x09〔盗〕\x09〔勝〕\x09〔敗〕\x03得\x03可\x03丽\x03丸\x03乁\x03你\x03" + + "侮\x03侻\x03倂\x03偺\x03備\x03僧\x03像\x03㒞\x03免\x03兔\x03兤\x03具\x03㒹\x03內\x03" + + "冗\x03冤\x03仌\x03冬\x03况\x03凵\x03刃\x03㓟\x03刻\x03剆\x03剷\x03㔕\x03勇\x03勉\x03" + + "勤\x03勺\x03包\x03匆\x03北\x03卉\x03卑\x03博\x03即\x03卽\x03卿\x03灰\x03及\x03叟\x03" + + "叫\x03叱\x03吆\x03咞\x03吸\x03呈\x03周\x03咢\x03哶\x03唐\x03啓\x03啣\x03善\x03喙\x03" + + "喫\x03喳\x03嗂\x03圖\x03嘆\x03圗\x03噑\x03噴\x03切\x03壮\x03城\x03埴\x03堍\x03型\x03" + + "堲\x03報\x03墬\x03売\x03壷\x03夆\x03夢\x03奢\x03姬\x03娛\x03娧\x03姘\x03婦\x03㛮\x03" + + "嬈\x03嬾\x03寃\x03寘\x03寧\x03寳\x03寿\x03将\x03尢\x03㞁\x03屠\x03屮\x03峀\x03岍\x03" + + "嵃\x03嵮\x03嵫\x03嵼\x03巡\x03巢\x03㠯\x03巽\x03帨\x03帽\x03幩\x03㡢\x03㡼\x03庰\x03" + + "庳\x03庶\x03廊\x03廾\x03舁\x03弢\x03㣇\x03形\x03彫\x03㣣\x03徚\x03忍\x03志\x03忹\x03" + + "悁\x03㤺\x03㤜\x03悔\x03惇\x03慈\x03慌\x03慎\x03慺\x03憎\x03憲\x03憤\x03憯\x03懞\x03" + + "懲\x03懶\x03成\x03戛\x03扝\x03抱\x03拔\x03捐\x03挽\x03拼\x03捨\x03掃\x03揤\x03搢\x03" + + "揅\x03掩\x03㨮\x03摩\x03摾\x03撝\x03摷\x03㩬\x03敏\x03敬\x03旣\x03書\x03晉\x03㬙\x03" + + "暑\x03㬈\x03㫤\x03冒\x03冕\x03最\x03暜\x03肭\x03䏙\x03朗\x03望\x03朡\x03杞\x03杓\x03" + + "㭉\x03柺\x03枅\x03桒\x03梅\x03梎\x03栟\x03椔\x03㮝\x03楂\x03榣\x03槪\x03檨\x03櫛\x03" + + "㰘\x03次\x03歔\x03㱎\x03歲\x03殟\x03殺\x03殻\x03汎\x03沿\x03泍\x03汧\x03洖\x03派\x03" + + "海\x03流\x03浩\x03浸\x03涅\x03洴\x03港\x03湮\x03㴳\x03滋\x03滇\x03淹\x03潮\x03濆\x03" + + "瀹\x03瀞\x03瀛\x03㶖\x03灊\x03災\x03灷\x03炭\x03煅\x03熜\x03爨\x03爵\x03牐\x03犀\x03" + + "犕\x03獺\x03王\x03㺬\x03玥\x03㺸\x03瑇\x03瑜\x03瑱\x03璅\x03瓊\x03㼛\x03甤\x03甾\x03" + + "異\x03瘐\x03㿼\x03䀈\x03直\x03眞\x03真\x03睊\x03䀹\x03瞋\x03䁆\x03䂖\x03硎\x03碌\x03" + + "磌\x03䃣\x03祖\x03福\x03秫\x03䄯\x03穀\x03穊\x03穏\x03䈂\x03篆\x03築\x03䈧\x03糒\x03" + + "䊠\x03糨\x03糣\x03紀\x03絣\x03䌁\x03緇\x03縂\x03繅\x03䌴\x03䍙\x03罺\x03羕\x03翺\x03" + + "者\x03聠\x03聰\x03䏕\x03育\x03脃\x03䐋\x03脾\x03媵\x03舄\x03辞\x03䑫\x03芑\x03芋\x03" + + "芝\x03劳\x03花\x03芳\x03芽\x03苦\x03若\x03茝\x03荣\x03莭\x03茣\x03莽\x03菧\x03著\x03" + + "荓\x03菊\x03菌\x03菜\x03䔫\x03蓱\x03蓳\x03蔖\x03蕤\x03䕝\x03䕡\x03䕫\x03虐\x03虜\x03" + + "虧\x03虩\x03蚩\x03蚈\x03蜎\x03蛢\x03蝹\x03蜨\x03蝫\x03螆\x03蟡\x03蠁\x03䗹\x03衠\x03" + + "衣\x03裗\x03裞\x03䘵\x03裺\x03㒻\x03䚾\x03䛇\x03誠\x03諭\x03變\x03豕\x03貫\x03賁\x03" + + "贛\x03起\x03跋\x03趼\x03跰\x03軔\x03輸\x03邔\x03郱\x03鄑\x03鄛\x03鈸\x03鋗\x03鋘\x03" + + "鉼\x03鏹\x03鐕\x03開\x03䦕\x03閷\x03䧦\x03雃\x03嶲\x03霣\x03䩮\x03䩶\x03韠\x03䪲\x03" + + "頋\x03頩\x03飢\x03䬳\x03餩\x03馧\x03駂\x03駾\x03䯎\x03鬒\x03鱀\x03鳽\x03䳎\x03䳭\x03" + + "鵧\x03䳸\x03麻\x03䵖\x03黹\x03黾\x03鼅\x03鼏\x03鼖\x03鼻" + +var xorData string = "" + // Size: 4855 bytes + "\x02\x0c\x09\x02\xb0\xec\x02\xad\xd8\x02\xad\xd9\x02\x06\x07\x02\x0f\x12" + + "\x02\x0f\x1f\x02\x0f\x1d\x02\x01\x13\x02\x0f\x16\x02\x0f\x0b\x02\x0f3" + + "\x02\x0f7\x02\x0f?\x02\x0f/\x02\x0f*\x02\x0c&\x02\x0c*\x02\x0c;\x02\x0c9" + + "\x02\x0c%\x02\xab\xed\x02\xab\xe2\x02\xab\xe3\x02\xa9\xe0\x02\xa9\xe1" + + "\x02\xa9\xe6\x02\xa3\xcb\x02\xa3\xc8\x02\xa3\xc9\x02\x01#\x02\x01\x08" + + "\x02\x0e>\x02\x0e'\x02\x0f\x03\x02\x03\x0d\x02\x03\x09\x02\x03\x17\x02" + + "\x03\x0e\x02\x02\x03\x02\x011\x02\x01\x00\x02\x01\x10\x02\x03<\x02\x07" + + "\x0d\x02\x02\x0c\x02\x0c0\x02\x01\x03\x02\x01\x01\x02\x01 \x02\x01\x22" + + "\x02\x01)\x02\x01\x0a\x02\x01\x0c\x02\x02\x06\x02\x02\x02\x02\x03\x10" + + "\x03\x037 \x03\x0b+\x03\x02\x01\x04\x02\x01\x02\x02\x019\x02\x03\x1c\x02" + + "\x02$\x03\x80p$\x02\x03:\x02\x03\x0a\x03\xc1r.\x03\xc1r,\x03\xc1r\x02" + + "\x02\x02:\x02\x02>\x02\x02,\x02\x02\x10\x02\x02\x00\x03\xc1s<\x03\xc1s*" + + "\x03\xc2L$\x03\xc2L;\x02\x09)\x02\x0a\x19\x03\x83\xab\xe3\x03\x83\xab" + + "\xf2\x03 4\xe0\x03\x81\xab\xea\x03\x81\xab\xf3\x03 4\xef\x03\x96\xe1\xcd" + + "\x03\x84\xe5\xc3\x02\x0d\x11\x03\x8b\xec\xcb\x03\x94\xec\xcf\x03\x9a\xec" + + "\xc2\x03\x8b\xec\xdb\x03\x94\xec\xdf\x03\x9a\xec\xd2\x03\x01\x0c!\x03" + + "\x01\x0c#\x03ʠ\x9d\x03ʣ\x9c\x03ʢ\x9f\x03ʥ\x9e\x03ʤ\x91\x03ʧ\x90\x03ʦ\x93" + + "\x03ʩ\x92\x03ʨ\x95\x03\xca\xf3\xb5\x03\xca\xf0\xb4\x03\xca\xf1\xb7\x03" + + "\xca\xf6\xb6\x03\xca\xf7\x89\x03\xca\xf4\x88\x03\xca\xf5\x8b\x03\xca\xfa" + + "\x8a\x03\xca\xfb\x8d\x03\xca\xf8\x8c\x03\xca\xf9\x8f\x03\xca\xfe\x8e\x03" + + "\xca\xff\x81\x03\xca\xfc\x80\x03\xca\xfd\x83\x03\xca\xe2\x82\x03\xca\xe3" + + "\x85\x03\xca\xe0\x84\x03\xca\xe1\x87\x03\xca\xe6\x86\x03\xca\xe7\x99\x03" + + "\xca\xe4\x98\x03\xca\xe5\x9b\x03\xca\xea\x9a\x03\xca\xeb\x9d\x03\xca\xe8" + + "\x9c\x03ؓ\x89\x03ߔ\x8b\x02\x010\x03\x03\x04\x1e\x03\x04\x15\x12\x03\x0b" + + "\x05,\x03\x06\x04\x00\x03\x06\x04)\x03\x06\x044\x03\x06\x04<\x03\x06\x05" + + "\x1d\x03\x06\x06\x00\x03\x06\x06\x0a\x03\x06\x06'\x03\x06\x062\x03\x0786" + + "\x03\x079/\x03\x079 \x03\x07:\x0e\x03\x07:\x1b\x03\x07:%\x03\x07;/\x03" + + "\x07;%\x03\x074\x11\x03\x076\x09\x03\x077*\x03\x070\x01\x03\x070\x0f\x03" + + "\x070.\x03\x071\x16\x03\x071\x04\x03\x0710\x03\x072\x18\x03\x072-\x03" + + "\x073\x14\x03\x073>\x03\x07'\x09\x03\x07 \x00\x03\x07\x1f\x0b\x03\x07" + + "\x18#\x03\x07\x18(\x03\x07\x186\x03\x07\x18\x03\x03\x07\x19\x16\x03\x07" + + "\x116\x03\x07\x12'\x03\x07\x13\x10\x03\x07\x0c&\x03\x07\x0c\x08\x03\x07" + + "\x0c\x13\x03\x07\x0d\x02\x03\x07\x0d\x1c\x03\x07\x0b5\x03\x07\x0b\x0a" + + "\x03\x07\x0b\x01\x03\x07\x0b\x0f\x03\x07\x05\x00\x03\x07\x05\x09\x03\x07" + + "\x05\x0b\x03\x07\x07\x01\x03\x07\x07\x08\x03\x07\x00<\x03\x07\x00+\x03" + + "\x07\x01)\x03\x07\x01\x1b\x03\x07\x01\x08\x03\x07\x03?\x03\x0445\x03\x04" + + "4\x08\x03\x0454\x03\x04)/\x03\x04)5\x03\x04+\x05\x03\x04+\x14\x03\x04+ " + + "\x03\x04+<\x03\x04*&\x03\x04*\x22\x03\x04&8\x03\x04!\x01\x03\x04!\x22" + + "\x03\x04\x11+\x03\x04\x10.\x03\x04\x104\x03\x04\x13=\x03\x04\x12\x04\x03" + + "\x04\x12\x0a\x03\x04\x0d\x1d\x03\x04\x0d\x07\x03\x04\x0d \x03\x05<>\x03" + + "\x055<\x03\x055!\x03\x055#\x03\x055&\x03\x054\x1d\x03\x054\x02\x03\x054" + + "\x07\x03\x0571\x03\x053\x1a\x03\x053\x16\x03\x05.<\x03\x05.\x07\x03\x05)" + + ":\x03\x05)<\x03\x05)\x0c\x03\x05)\x15\x03\x05+-\x03\x05+5\x03\x05$\x1e" + + "\x03\x05$\x14\x03\x05'\x04\x03\x05'\x14\x03\x05&\x02\x03\x05\x226\x03" + + "\x05\x22\x0c\x03\x05\x22\x1c\x03\x05\x19\x0a\x03\x05\x1b\x09\x03\x05\x1b" + + "\x0c\x03\x05\x14\x07\x03\x05\x16?\x03\x05\x16\x0c\x03\x05\x0c\x05\x03" + + "\x05\x0e\x0f\x03\x05\x01\x0e\x03\x05\x00(\x03\x05\x030\x03\x05\x03\x06" + + "\x03\x0a==\x03\x0a=1\x03\x0a=,\x03\x0a=\x0c\x03\x0a??\x03\x0a<\x08\x03" + + "\x0a9!\x03\x0a9)\x03\x0a97\x03\x0a99\x03\x0a6\x0a\x03\x0a6\x1c\x03\x0a6" + + "\x17\x03\x0a7'\x03\x0a78\x03\x0a73\x03\x0a'\x01\x03\x0a'&\x03\x0a\x1f" + + "\x0e\x03\x0a\x1f\x03\x03\x0a\x1f3\x03\x0a\x1b/\x03\x0a\x18\x19\x03\x0a" + + "\x19\x01\x03\x0a\x16\x14\x03\x0a\x0e\x22\x03\x0a\x0f\x10\x03\x0a\x0f\x02" + + "\x03\x0a\x0f \x03\x0a\x0c\x04\x03\x0a\x0b>\x03\x0a\x0b+\x03\x0a\x08/\x03" + + "\x0a\x046\x03\x0a\x05\x14\x03\x0a\x00\x04\x03\x0a\x00\x10\x03\x0a\x00" + + "\x14\x03\x0b<3\x03\x0b;*\x03\x0b9\x22\x03\x0b9)\x03\x0b97\x03\x0b+\x10" + + "\x03\x0b((\x03\x0b&5\x03\x0b$\x1c\x03\x0b$\x12\x03\x0b%\x04\x03\x0b#<" + + "\x03\x0b#0\x03\x0b#\x0d\x03\x0b#\x19\x03\x0b!:\x03\x0b!\x1f\x03\x0b!\x00" + + "\x03\x0b\x1e5\x03\x0b\x1c\x1d\x03\x0b\x1d-\x03\x0b\x1d(\x03\x0b\x18.\x03" + + "\x0b\x18 \x03\x0b\x18\x16\x03\x0b\x14\x13\x03\x0b\x15$\x03\x0b\x15\x22" + + "\x03\x0b\x12\x1b\x03\x0b\x12\x10\x03\x0b\x132\x03\x0b\x13=\x03\x0b\x12" + + "\x18\x03\x0b\x0c&\x03\x0b\x061\x03\x0b\x06:\x03\x0b\x05#\x03\x0b\x05<" + + "\x03\x0b\x04\x0b\x03\x0b\x04\x04\x03\x0b\x04\x1b\x03\x0b\x042\x03\x0b" + + "\x041\x03\x0b\x03\x03\x03\x0b\x03\x1d\x03\x0b\x03/\x03\x0b\x03+\x03\x0b" + + "\x02\x1b\x03\x0b\x02\x00\x03\x0b\x01\x1e\x03\x0b\x01\x08\x03\x0b\x015" + + "\x03\x06\x0d9\x03\x06\x0d=\x03\x06\x0d?\x03\x02\x001\x03\x02\x003\x03" + + "\x02\x02\x19\x03\x02\x006\x03\x02\x02\x1b\x03\x02\x004\x03\x02\x00<\x03" + + "\x02\x02\x0a\x03\x02\x02\x0e\x03\x02\x01\x1a\x03\x02\x01\x07\x03\x02\x01" + + "\x05\x03\x02\x01\x0b\x03\x02\x01%\x03\x02\x01\x0c\x03\x02\x01\x04\x03" + + "\x02\x01\x1c\x03\x02\x00.\x03\x02\x002\x03\x02\x00>\x03\x02\x00\x12\x03" + + "\x02\x00\x16\x03\x02\x011\x03\x02\x013\x03\x02\x02 \x03\x02\x02%\x03\x02" + + "\x02$\x03\x02\x028\x03\x02\x02;\x03\x02\x024\x03\x02\x012\x03\x02\x022" + + "\x03\x02\x02/\x03\x02\x01,\x03\x02\x01\x13\x03\x02\x01\x16\x03\x02\x01" + + "\x11\x03\x02\x01\x1e\x03\x02\x01\x15\x03\x02\x01\x17\x03\x02\x01\x0f\x03" + + "\x02\x01\x08\x03\x02\x00?\x03\x02\x03\x07\x03\x02\x03\x0d\x03\x02\x03" + + "\x13\x03\x02\x03\x1d\x03\x02\x03\x1f\x03\x02\x00\x03\x03\x02\x00\x0d\x03" + + "\x02\x00\x01\x03\x02\x00\x1b\x03\x02\x00\x19\x03\x02\x00\x18\x03\x02\x00" + + "\x13\x03\x02\x00/\x03\x07>\x12\x03\x07<\x1f\x03\x07>\x1d\x03\x06\x1d\x0e" + + "\x03\x07>\x1c\x03\x07>:\x03\x07>\x13\x03\x04\x12+\x03\x07?\x03\x03\x07>" + + "\x02\x03\x06\x224\x03\x06\x1a.\x03\x07<%\x03\x06\x1c\x0b\x03\x0609\x03" + + "\x05\x1f\x01\x03\x04'\x08\x03\x93\xfd\xf5\x03\x02\x0d \x03\x02\x0d#\x03" + + "\x02\x0d!\x03\x02\x0d&\x03\x02\x0d\x22\x03\x02\x0d/\x03\x02\x0d,\x03\x02" + + "\x0d$\x03\x02\x0d'\x03\x02\x0d%\x03\x02\x0d;\x03\x02\x0d=\x03\x02\x0d?" + + "\x03\x099.\x03\x08\x0b7\x03\x08\x02\x14\x03\x08\x14\x0d\x03\x08.:\x03" + + "\x089'\x03\x0f\x0b\x18\x03\x0f\x1c1\x03\x0f\x17&\x03\x0f9\x1f\x03\x0f0" + + "\x0c\x03\x0e\x0a9\x03\x0e\x056\x03\x0e\x1c#\x03\x0f\x13\x0e\x03\x072\x00" + + "\x03\x070\x0d\x03\x072\x0b\x03\x06\x11\x18\x03\x070\x10\x03\x06\x0f(\x03" + + "\x072\x05\x03\x06\x0f,\x03\x073\x15\x03\x06\x07\x08\x03\x05\x16\x02\x03" + + "\x04\x0b \x03\x05:8\x03\x05\x16%\x03\x0a\x0d\x1f\x03\x06\x16\x10\x03\x05" + + "\x1d5\x03\x05*;\x03\x05\x16\x1b\x03\x04.-\x03\x06\x1a\x19\x03\x04\x03," + + "\x03\x0b87\x03\x04/\x0a\x03\x06\x00,\x03\x04-\x01\x03\x04\x1e-\x03\x06/(" + + "\x03\x0a\x0b5\x03\x06\x0e7\x03\x06\x07.\x03\x0597\x03\x0a*%\x03\x0760" + + "\x03\x06\x0c;\x03\x05'\x00\x03\x072.\x03\x072\x08\x03\x06=\x01\x03\x06" + + "\x05\x1b\x03\x06\x06\x12\x03\x06$=\x03\x06'\x0d\x03\x04\x11\x0f\x03\x076" + + ",\x03\x06\x07;\x03\x06.,\x03\x86\xf9\xea\x03\x8f\xff\xeb\x02\x092\x02" + + "\x095\x02\x094\x02\x09;\x02\x09>\x02\x098\x02\x09*\x02\x09/\x02\x09,\x02" + + "\x09%\x02\x09&\x02\x09#\x02\x09 \x02\x08!\x02\x08%\x02\x08$\x02\x08+\x02" + + "\x08.\x02\x08*\x02\x08&\x02\x088\x02\x08>\x02\x084\x02\x086\x02\x080\x02" + + "\x08\x10\x02\x08\x17\x02\x08\x12\x02\x08\x1d\x02\x08\x1f\x02\x08\x13\x02" + + "\x08\x15\x02\x08\x14\x02\x08\x0c\x03\x8b\xfd\xd0\x03\x81\xec\xc6\x03\x87" + + "\xe0\x8a\x03-2\xe3\x03\x80\xef\xe4\x03-2\xea\x03\x88\xe6\xeb\x03\x8e\xe6" + + "\xe8\x03\x84\xe6\xe9\x03\x97\xe6\xee\x03-2\xf9\x03-2\xf6\x03\x8e\xe3\xad" + + "\x03\x80\xe3\x92\x03\x88\xe3\x90\x03\x8e\xe3\x90\x03\x80\xe3\x97\x03\x88" + + "\xe3\x95\x03\x88\xfe\xcb\x03\x8e\xfe\xca\x03\x84\xfe\xcd\x03\x91\xef\xc9" + + "\x03-2\xc1\x03-2\xc0\x03-2\xcb\x03\x88@\x09\x03\x8e@\x08\x03\x8f\xe0\xf5" + + "\x03\x8e\xe6\xf9\x03\x8e\xe0\xfa\x03\x93\xff\xf4\x03\x84\xee\xd3\x03\x0b" + + "(\x04\x023 \x021;\x02\x01*\x03\x0b#\x10\x03\x0b 0\x03\x0b!\x10\x03\x0b!0" + + "\x03\x07\x15\x08\x03\x09?5\x03\x07\x1f\x08\x03\x07\x17\x0b\x03\x09\x1f" + + "\x15\x03\x0b\x1c7\x03\x0a+#\x03\x06\x1a\x1b\x03\x06\x1a\x14\x03\x0a\x01" + + "\x18\x03\x06#\x1b\x03\x0a2\x0c\x03\x0a\x01\x04\x03\x09#;\x03\x08='\x03" + + "\x08\x1a\x0a\x03\x07\x03\x0a\x111\x03\x09\x1b\x09\x03\x073.\x03\x07\x01\x00" + + "\x03\x09/,\x03\x07#>\x03\x07\x048\x03\x0a\x1f\x22\x03\x098>\x03\x09\x11" + + "\x00\x03\x08/\x17\x03\x06'\x22\x03\x0b\x1a+\x03\x0a\x22\x19\x03\x0a/1" + + "\x03\x0974\x03\x09\x0f\x22\x03\x08,\x22\x03\x08?\x14\x03\x07$5\x03\x07<3" + + "\x03\x07=*\x03\x07\x13\x18\x03\x068\x0a\x03\x06\x09\x16\x03\x06\x13\x00" + + "\x03\x08\x067\x03\x08\x01\x03\x03\x08\x12\x1d\x03\x07+7\x03\x06(;\x03" + + "\x06\x1c?\x03\x07\x0e\x17\x03\x0a\x06\x1d\x03\x0a\x19\x07\x03\x08\x14$" + + "\x03\x07$;\x03\x08,$\x03\x08\x06\x0d\x03\x07\x16\x0a\x03\x06>>\x03\x0a" + + "\x06\x12\x03\x0a\x14)\x03\x09\x0d\x1f\x03\x09\x12\x17\x03\x09\x19\x01" + + "\x03\x08\x11 \x03\x08\x1d'\x03\x06<\x1a\x03\x0a.\x00\x03\x07'\x18\x03" + + "\x0a\x22\x08\x03\x08\x0d\x0a\x03\x08\x13)\x03\x07*)\x03\x06<,\x03\x07" + + "\x0b\x1a\x03\x09.\x14\x03\x09\x0d\x1e\x03\x07\x0e#\x03\x0b\x1d'\x03\x0a" + + "\x0a8\x03\x09%2\x03\x08+&\x03\x080\x12\x03\x0a)4\x03\x08\x06\x1f\x03\x0b" + + "\x1b\x1a\x03\x0a\x1b\x0f\x03\x0b\x1d*\x03\x09\x16$\x03\x090\x11\x03\x08" + + "\x11\x08\x03\x0a*(\x03\x0a\x042\x03\x089,\x03\x074'\x03\x07\x0f\x05\x03" + + "\x09\x0b\x0a\x03\x07\x1b\x01\x03\x09\x17:\x03\x09.\x0d\x03\x07.\x11\x03" + + "\x09+\x15\x03\x080\x13\x03\x0b\x1f\x19\x03\x0a \x11\x03\x0a\x220\x03\x09" + + "\x07;\x03\x08\x16\x1c\x03\x07,\x13\x03\x07\x0e/\x03\x06\x221\x03\x0a." + + "\x0a\x03\x0a7\x02\x03\x0a\x032\x03\x0a\x1d.\x03\x091\x06\x03\x09\x19:" + + "\x03\x08\x02/\x03\x060+\x03\x06\x0f-\x03\x06\x1c\x1f\x03\x06\x1d\x07\x03" + + "\x0a,\x11\x03\x09=\x0d\x03\x09\x0b;\x03\x07\x1b/\x03\x0a\x1f:\x03\x09 " + + "\x1f\x03\x09.\x10\x03\x094\x0b\x03\x09\x1a1\x03\x08#\x1a\x03\x084\x1d" + + "\x03\x08\x01\x1f\x03\x08\x11\x22\x03\x07'8\x03\x07\x1a>\x03\x0757\x03" + + "\x06&9\x03\x06+\x11\x03\x0a.\x0b\x03\x0a,>\x03\x0a4#\x03\x08%\x17\x03" + + "\x07\x05\x22\x03\x07\x0c\x0b\x03\x0a\x1d+\x03\x0a\x19\x16\x03\x09+\x1f" + + "\x03\x09\x08\x0b\x03\x08\x16\x18\x03\x08+\x12\x03\x0b\x1d\x0c\x03\x0a=" + + "\x10\x03\x0a\x09\x0d\x03\x0a\x10\x11\x03\x09&0\x03\x08(\x1f\x03\x087\x07" + + "\x03\x08\x185\x03\x07'6\x03\x06.\x05\x03\x06=\x04\x03\x06;;\x03\x06\x06," + + "\x03\x0b\x18>\x03\x08\x00\x18\x03\x06 \x03\x03\x06<\x00\x03\x09%\x18\x03" + + "\x0b\x1c<\x03\x0a%!\x03\x0a\x09\x12\x03\x0a\x16\x02\x03\x090'\x03\x09" + + "\x0e=\x03\x08 \x0e\x03\x08>\x03\x03\x074>\x03\x06&?\x03\x06\x19\x09\x03" + + "\x06?(\x03\x0a-\x0e\x03\x09:3\x03\x098:\x03\x09\x12\x0b\x03\x09\x1d\x17" + + "\x03\x087\x05\x03\x082\x14\x03\x08\x06%\x03\x08\x13\x1f\x03\x06\x06\x0e" + + "\x03\x0a\x22<\x03\x09/<\x03\x06>+\x03\x0a'?\x03\x0a\x13\x0c\x03\x09\x10<" + + "\x03\x07\x1b=\x03\x0a\x19\x13\x03\x09\x22\x1d\x03\x09\x07\x0d\x03\x08)" + + "\x1c\x03\x06=\x1a\x03\x0a/4\x03\x0a7\x11\x03\x0a\x16:\x03\x09?3\x03\x09:" + + "/\x03\x09\x05\x0a\x03\x09\x14\x06\x03\x087\x22\x03\x080\x07\x03\x08\x1a" + + "\x1f\x03\x07\x04(\x03\x07\x04\x09\x03\x06 %\x03\x06<\x08\x03\x0a+\x14" + + "\x03\x09\x1d\x16\x03\x0a70\x03\x08 >\x03\x0857\x03\x070\x0a\x03\x06=\x12" + + "\x03\x06\x16%\x03\x06\x1d,\x03\x099#\x03\x09\x10>\x03\x07 \x1e\x03\x08" + + "\x0c<\x03\x08\x0b\x18\x03\x08\x15+\x03\x08,:\x03\x08%\x22\x03\x07\x0a$" + + "\x03\x0b\x1c=\x03\x07+\x08\x03\x0a/\x05\x03\x0a \x07\x03\x0a\x12'\x03" + + "\x09#\x11\x03\x08\x1b\x15\x03\x0a\x06\x01\x03\x09\x1c\x1b\x03\x0922\x03" + + "\x07\x14<\x03\x07\x09\x04\x03\x061\x04\x03\x07\x0e\x01\x03\x0a\x13\x18" + + "\x03\x0a-\x0c\x03\x0a?\x0d\x03\x0a\x09\x0a\x03\x091&\x03\x0a/\x0b\x03" + + "\x08$<\x03\x083\x1d\x03\x08\x0c$\x03\x08\x0d\x07\x03\x08\x0d?\x03\x08" + + "\x0e\x14\x03\x065\x0a\x03\x08\x1a#\x03\x08\x16#\x03\x0702\x03\x07\x03" + + "\x1a\x03\x06(\x1d\x03\x06+\x1b\x03\x06\x0b\x05\x03\x06\x0b\x17\x03\x06" + + "\x0c\x04\x03\x06\x1e\x19\x03\x06+0\x03\x062\x18\x03\x0b\x16\x1e\x03\x0a+" + + "\x16\x03\x0a-?\x03\x0a#:\x03\x0a#\x10\x03\x0a%$\x03\x0a>+\x03\x0a01\x03" + + "\x0a1\x10\x03\x0a\x099\x03\x0a\x0a\x12\x03\x0a\x19\x1f\x03\x0a\x19\x12" + + "\x03\x09*)\x03\x09-\x16\x03\x09.1\x03\x09.2\x03\x09<\x0e\x03\x09> \x03" + + "\x093\x12\x03\x09\x0b\x01\x03\x09\x1c2\x03\x09\x11\x1c\x03\x09\x15%\x03" + + "\x08,&\x03\x08!\x22\x03\x089(\x03\x08\x0b\x1a\x03\x08\x0d2\x03\x08\x0c" + + "\x04\x03\x08\x0c\x06\x03\x08\x0c\x1f\x03\x08\x0c\x0c\x03\x08\x0f\x1f\x03" + + "\x08\x0f\x1d\x03\x08\x00\x14\x03\x08\x03\x14\x03\x08\x06\x16\x03\x08\x1e" + + "#\x03\x08\x11\x11\x03\x08\x10\x18\x03\x08\x14(\x03\x07)\x1e\x03\x07.1" + + "\x03\x07 $\x03\x07 '\x03\x078\x08\x03\x07\x0d0\x03\x07\x0f7\x03\x07\x05#" + + "\x03\x07\x05\x1a\x03\x07\x1a7\x03\x07\x1d-\x03\x07\x17\x10\x03\x06)\x1f" + + "\x03\x062\x0b\x03\x066\x16\x03\x06\x09\x11\x03\x09(\x1e\x03\x07!5\x03" + + "\x0b\x11\x16\x03\x0a/\x04\x03\x0a,\x1a\x03\x0b\x173\x03\x0a,1\x03\x0a/5" + + "\x03\x0a\x221\x03\x0a\x22\x0d\x03\x0a?%\x03\x0a<,\x03\x0a?#\x03\x0a>\x19" + + "\x03\x0a\x08&\x03\x0a\x0b\x0e\x03\x0a\x0c:\x03\x0a\x0c+\x03\x0a\x03\x22" + + "\x03\x0a\x06)\x03\x0a\x11\x10\x03\x0a\x11\x1a\x03\x0a\x17-\x03\x0a\x14(" + + "\x03\x09)\x1e\x03\x09/\x09\x03\x09.\x00\x03\x09,\x07\x03\x09/*\x03\x09-9" + + "\x03\x09\x228\x03\x09%\x09\x03\x09:\x12\x03\x09;\x1d\x03\x09?\x06\x03" + + "\x093%\x03\x096\x05\x03\x096\x08\x03\x097\x02\x03\x09\x07,\x03\x09\x04," + + "\x03\x09\x1f\x16\x03\x09\x11\x03\x03\x09\x11\x12\x03\x09\x168\x03\x08*" + + "\x05\x03\x08/2\x03\x084:\x03\x08\x22+\x03\x08 0\x03\x08&\x0a\x03\x08;" + + "\x10\x03\x08>$\x03\x08>\x18\x03\x0829\x03\x082:\x03\x081,\x03\x081<\x03" + + "\x081\x1c\x03\x087#\x03\x087*\x03\x08\x09'\x03\x08\x00\x1d\x03\x08\x05-" + + "\x03\x08\x1f4\x03\x08\x1d\x04\x03\x08\x16\x0f\x03\x07*7\x03\x07'!\x03" + + "\x07%\x1b\x03\x077\x0c\x03\x07\x0c1\x03\x07\x0c.\x03\x07\x00\x06\x03\x07" + + "\x01\x02\x03\x07\x010\x03\x07\x06=\x03\x07\x01\x03\x03\x07\x01\x13\x03" + + "\x07\x06\x06\x03\x07\x05\x0a\x03\x07\x1f\x09\x03\x07\x17:\x03\x06*1\x03" + + "\x06-\x1d\x03\x06\x223\x03\x062:\x03\x060$\x03\x066\x1e\x03\x064\x12\x03" + + "\x0645\x03\x06\x0b\x00\x03\x06\x0b7\x03\x06\x07\x1f\x03\x06\x15\x12\x03" + + "\x0c\x05\x0f\x03\x0b+\x0b\x03\x0b+-\x03\x06\x16\x1b\x03\x06\x15\x17\x03" + + "\x89\xca\xea\x03\x89\xca\xe8\x03\x0c8\x10\x03\x0c8\x01\x03\x0c8\x0f\x03" + + "\x0d8%\x03\x0d8!\x03\x0c8-\x03\x0c8/\x03\x0c8+\x03\x0c87\x03\x0c85\x03" + + "\x0c9\x09\x03\x0c9\x0d\x03\x0c9\x0f\x03\x0c9\x0b\x03\xcfu\x0c\x03\xcfu" + + "\x0f\x03\xcfu\x0e\x03\xcfu\x09\x03\x0c9\x10\x03\x0d9\x0c\x03\xcf`;\x03" + + "\xcf`>\x03\xcf`9\x03\xcf`8\x03\xcf`7\x03\xcf`*\x03\xcf`-\x03\xcf`,\x03" + + "\x0d\x1b\x1a\x03\x0d\x1b&\x03\x0c=.\x03\x0c=%\x03\x0c>\x1e\x03\x0c>\x14" + + "\x03\x0c?\x06\x03\x0c?\x0b\x03\x0c?\x0c\x03\x0c?\x0d\x03\x0c?\x02\x03" + + "\x0c>\x0f\x03\x0c>\x08\x03\x0c>\x09\x03\x0c>,\x03\x0c>\x0c\x03\x0c?\x13" + + "\x03\x0c?\x16\x03\x0c?\x15\x03\x0c?\x1c\x03\x0c?\x1f\x03\x0c?\x1d\x03" + + "\x0c?\x1a\x03\x0c?\x17\x03\x0c?\x08\x03\x0c?\x09\x03\x0c?\x0e\x03\x0c?" + + "\x04\x03\x0c?\x05\x03\x0c" + + "\x03\x0c=2\x03\x0c=6\x03\x0c<\x07\x03\x0c<\x05\x03\x0e:!\x03\x0e:#\x03" + + "\x0e8\x09\x03\x0e:&\x03\x0e8\x0b\x03\x0e:$\x03\x0e:,\x03\x0e8\x1a\x03" + + "\x0e8\x1e\x03\x0e:*\x03\x0e:7\x03\x0e:5\x03\x0e:;\x03\x0e:\x15\x03\x0e:<" + + "\x03\x0e:4\x03\x0e:'\x03\x0e:-\x03\x0e:%\x03\x0e:?\x03\x0e:=\x03\x0e:)" + + "\x03\x0e:/\x03\xcfs'\x03\x0d=\x0f\x03\x0d+*\x03\x0d99\x03\x0d9;\x03\x0d9" + + "?\x03\x0d)\x0d\x03\x0d(%\x02\x01\x18\x02\x01(\x02\x01\x1e\x03\x0f$!\x03" + + "\x0f87\x03\x0f4\x0e\x03\x0f5\x1d\x03\x06'\x03\x03\x0f\x08\x18\x03\x0f" + + "\x0d\x1b\x03\x0e2=\x03\x0e;\x08\x03\x0e:\x0b\x03\x0e\x06$\x03\x0e\x0d)" + + "\x03\x0e\x16\x1f\x03\x0e\x16\x1b\x03\x0d$\x0a\x03\x05,\x1d\x03\x0d. \x03" + + "\x0d.#\x03\x0c(/\x03\x09%\x02\x03\x0d90\x03\x0d\x0e4\x03\x0d\x0d\x0f\x03" + + "\x0c#\x00\x03\x0c,\x1e\x03\x0c2\x0e\x03\x0c\x01\x17\x03\x0c\x09:\x03\x0e" + + "\x173\x03\x0c\x08\x03\x03\x0c\x11\x07\x03\x0c\x10\x18\x03\x0c\x1f\x1c" + + "\x03\x0c\x19\x0e\x03\x0c\x1a\x1f\x03\x0f0>\x03\x0b->\x03\x0b<+\x03\x0b8" + + "\x13\x03\x0b\x043\x03\x0b\x14\x03\x03\x0b\x16%\x03\x0d\x22&\x03\x0b\x1a" + + "\x1a\x03\x0b\x1a\x04\x03\x0a%9\x03\x0a&2\x03\x0a&0\x03\x0a!\x1a\x03\x0a!" + + "7\x03\x0a5\x10\x03\x0a=4\x03\x0a?\x0e\x03\x0a>\x10\x03\x0a\x00 \x03\x0a" + + "\x0f:\x03\x0a\x0f9\x03\x0a\x0b\x0a\x03\x0a\x17%\x03\x0a\x1b-\x03\x09-" + + "\x1a\x03\x09,4\x03\x09.,\x03\x09)\x09\x03\x096!\x03\x091\x1f\x03\x093" + + "\x16\x03\x0c+\x1f\x03\x098 \x03\x098=\x03\x0c(\x1a\x03\x0c(\x16\x03\x09" + + "\x0a+\x03\x09\x16\x12\x03\x09\x13\x0e\x03\x09\x153\x03\x08)!\x03\x09\x1a" + + "\x01\x03\x09\x18\x01\x03\x08%#\x03\x08>\x22\x03\x08\x05%\x03\x08\x02*" + + "\x03\x08\x15;\x03\x08\x1b7\x03\x0f\x07\x1d\x03\x0f\x04\x03\x03\x070\x0c" + + "\x03\x07;\x0b\x03\x07\x08\x17\x03\x07\x12\x06\x03\x06/-\x03\x0671\x03" + + "\x065+\x03\x06>7\x03\x06\x049\x03\x05+\x1e\x03\x05,\x17\x03\x05 \x1d\x03" + + "\x05\x22\x05\x03\x050\x1d" + +// lookup returns the trie value for the first UTF-8 encoding in s and +// the width in bytes of this encoding. The size will be 0 if s does not +// hold enough bytes to complete the encoding. len(s) must be greater than 0. +func (t *idnaTrie) lookup(s []byte) (v uint16, sz int) { + c0 := s[0] + switch { + case c0 < 0x80: // is ASCII + return idnaValues[c0], 1 + case c0 < 0xC2: + return 0, 1 // Illegal UTF-8: not a starter, not ASCII. + case c0 < 0xE0: // 2-byte UTF-8 + if len(s) < 2 { + return 0, 0 + } + i := idnaIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c1), 2 + case c0 < 0xF0: // 3-byte UTF-8 + if len(s) < 3 { + return 0, 0 + } + i := idnaIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = idnaIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c2), 3 + case c0 < 0xF8: // 4-byte UTF-8 + if len(s) < 4 { + return 0, 0 + } + i := idnaIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = idnaIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + o = uint32(i)<<6 + uint32(c2) + i = idnaIndex[o] + c3 := s[3] + if c3 < 0x80 || 0xC0 <= c3 { + return 0, 3 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c3), 4 + } + // Illegal rune + return 0, 1 +} + +// lookupUnsafe returns the trie value for the first UTF-8 encoding in s. +// s must start with a full and valid UTF-8 encoded rune. +func (t *idnaTrie) lookupUnsafe(s []byte) uint16 { + c0 := s[0] + if c0 < 0x80 { // is ASCII + return idnaValues[c0] + } + i := idnaIndex[c0] + if c0 < 0xE0 { // 2-byte UTF-8 + return t.lookupValue(uint32(i), s[1]) + } + i = idnaIndex[uint32(i)<<6+uint32(s[1])] + if c0 < 0xF0 { // 3-byte UTF-8 + return t.lookupValue(uint32(i), s[2]) + } + i = idnaIndex[uint32(i)<<6+uint32(s[2])] + if c0 < 0xF8 { // 4-byte UTF-8 + return t.lookupValue(uint32(i), s[3]) + } + return 0 +} + +// lookupString returns the trie value for the first UTF-8 encoding in s and +// the width in bytes of this encoding. The size will be 0 if s does not +// hold enough bytes to complete the encoding. len(s) must be greater than 0. +func (t *idnaTrie) lookupString(s string) (v uint16, sz int) { + c0 := s[0] + switch { + case c0 < 0x80: // is ASCII + return idnaValues[c0], 1 + case c0 < 0xC2: + return 0, 1 // Illegal UTF-8: not a starter, not ASCII. + case c0 < 0xE0: // 2-byte UTF-8 + if len(s) < 2 { + return 0, 0 + } + i := idnaIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c1), 2 + case c0 < 0xF0: // 3-byte UTF-8 + if len(s) < 3 { + return 0, 0 + } + i := idnaIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = idnaIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c2), 3 + case c0 < 0xF8: // 4-byte UTF-8 + if len(s) < 4 { + return 0, 0 + } + i := idnaIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = idnaIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + o = uint32(i)<<6 + uint32(c2) + i = idnaIndex[o] + c3 := s[3] + if c3 < 0x80 || 0xC0 <= c3 { + return 0, 3 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c3), 4 + } + // Illegal rune + return 0, 1 +} + +// lookupStringUnsafe returns the trie value for the first UTF-8 encoding in s. +// s must start with a full and valid UTF-8 encoded rune. +func (t *idnaTrie) lookupStringUnsafe(s string) uint16 { + c0 := s[0] + if c0 < 0x80 { // is ASCII + return idnaValues[c0] + } + i := idnaIndex[c0] + if c0 < 0xE0 { // 2-byte UTF-8 + return t.lookupValue(uint32(i), s[1]) + } + i = idnaIndex[uint32(i)<<6+uint32(s[1])] + if c0 < 0xF0 { // 3-byte UTF-8 + return t.lookupValue(uint32(i), s[2]) + } + i = idnaIndex[uint32(i)<<6+uint32(s[2])] + if c0 < 0xF8 { // 4-byte UTF-8 + return t.lookupValue(uint32(i), s[3]) + } + return 0 +} + +// idnaTrie. Total size: 29052 bytes (28.37 KiB). Checksum: ef06e7ecc26f36dd. +type idnaTrie struct{} + +func newIdnaTrie(i int) *idnaTrie { + return &idnaTrie{} +} + +// lookupValue determines the type of block n and looks up the value for b. +func (t *idnaTrie) lookupValue(n uint32, b byte) uint16 { + switch { + case n < 125: + return uint16(idnaValues[n<<6+uint32(b)]) + default: + n -= 125 + return uint16(idnaSparse.lookup(n, b)) + } +} + +// idnaValues: 127 blocks, 8128 entries, 16256 bytes +// The third block is the zero block. +var idnaValues = [8128]uint16{ + // Block 0x0, offset 0x0 + 0x00: 0x0080, 0x01: 0x0080, 0x02: 0x0080, 0x03: 0x0080, 0x04: 0x0080, 0x05: 0x0080, + 0x06: 0x0080, 0x07: 0x0080, 0x08: 0x0080, 0x09: 0x0080, 0x0a: 0x0080, 0x0b: 0x0080, + 0x0c: 0x0080, 0x0d: 0x0080, 0x0e: 0x0080, 0x0f: 0x0080, 0x10: 0x0080, 0x11: 0x0080, + 0x12: 0x0080, 0x13: 0x0080, 0x14: 0x0080, 0x15: 0x0080, 0x16: 0x0080, 0x17: 0x0080, + 0x18: 0x0080, 0x19: 0x0080, 0x1a: 0x0080, 0x1b: 0x0080, 0x1c: 0x0080, 0x1d: 0x0080, + 0x1e: 0x0080, 0x1f: 0x0080, 0x20: 0x0080, 0x21: 0x0080, 0x22: 0x0080, 0x23: 0x0080, + 0x24: 0x0080, 0x25: 0x0080, 0x26: 0x0080, 0x27: 0x0080, 0x28: 0x0080, 0x29: 0x0080, + 0x2a: 0x0080, 0x2b: 0x0080, 0x2c: 0x0080, 0x2d: 0x0008, 0x2e: 0x0008, 0x2f: 0x0080, + 0x30: 0x0008, 0x31: 0x0008, 0x32: 0x0008, 0x33: 0x0008, 0x34: 0x0008, 0x35: 0x0008, + 0x36: 0x0008, 0x37: 0x0008, 0x38: 0x0008, 0x39: 0x0008, 0x3a: 0x0080, 0x3b: 0x0080, + 0x3c: 0x0080, 0x3d: 0x0080, 0x3e: 0x0080, 0x3f: 0x0080, + // Block 0x1, offset 0x40 + 0x40: 0x0080, 0x41: 0xe105, 0x42: 0xe105, 0x43: 0xe105, 0x44: 0xe105, 0x45: 0xe105, + 0x46: 0xe105, 0x47: 0xe105, 0x48: 0xe105, 0x49: 0xe105, 0x4a: 0xe105, 0x4b: 0xe105, + 0x4c: 0xe105, 0x4d: 0xe105, 0x4e: 0xe105, 0x4f: 0xe105, 0x50: 0xe105, 0x51: 0xe105, + 0x52: 0xe105, 0x53: 0xe105, 0x54: 0xe105, 0x55: 0xe105, 0x56: 0xe105, 0x57: 0xe105, + 0x58: 0xe105, 0x59: 0xe105, 0x5a: 0xe105, 0x5b: 0x0080, 0x5c: 0x0080, 0x5d: 0x0080, + 0x5e: 0x0080, 0x5f: 0x0080, 0x60: 0x0080, 0x61: 0x0008, 0x62: 0x0008, 0x63: 0x0008, + 0x64: 0x0008, 0x65: 0x0008, 0x66: 0x0008, 0x67: 0x0008, 0x68: 0x0008, 0x69: 0x0008, + 0x6a: 0x0008, 0x6b: 0x0008, 0x6c: 0x0008, 0x6d: 0x0008, 0x6e: 0x0008, 0x6f: 0x0008, + 0x70: 0x0008, 0x71: 0x0008, 0x72: 0x0008, 0x73: 0x0008, 0x74: 0x0008, 0x75: 0x0008, + 0x76: 0x0008, 0x77: 0x0008, 0x78: 0x0008, 0x79: 0x0008, 0x7a: 0x0008, 0x7b: 0x0080, + 0x7c: 0x0080, 0x7d: 0x0080, 0x7e: 0x0080, 0x7f: 0x0080, + // Block 0x2, offset 0x80 + // Block 0x3, offset 0xc0 + 0xc0: 0x0040, 0xc1: 0x0040, 0xc2: 0x0040, 0xc3: 0x0040, 0xc4: 0x0040, 0xc5: 0x0040, + 0xc6: 0x0040, 0xc7: 0x0040, 0xc8: 0x0040, 0xc9: 0x0040, 0xca: 0x0040, 0xcb: 0x0040, + 0xcc: 0x0040, 0xcd: 0x0040, 0xce: 0x0040, 0xcf: 0x0040, 0xd0: 0x0040, 0xd1: 0x0040, + 0xd2: 0x0040, 0xd3: 0x0040, 0xd4: 0x0040, 0xd5: 0x0040, 0xd6: 0x0040, 0xd7: 0x0040, + 0xd8: 0x0040, 0xd9: 0x0040, 0xda: 0x0040, 0xdb: 0x0040, 0xdc: 0x0040, 0xdd: 0x0040, + 0xde: 0x0040, 0xdf: 0x0040, 0xe0: 0x000a, 0xe1: 0x0018, 0xe2: 0x0018, 0xe3: 0x0018, + 0xe4: 0x0018, 0xe5: 0x0018, 0xe6: 0x0018, 0xe7: 0x0018, 0xe8: 0x001a, 0xe9: 0x0018, + 0xea: 0x0039, 0xeb: 0x0018, 0xec: 0x0018, 0xed: 0x03c0, 0xee: 0x0018, 0xef: 0x004a, + 0xf0: 0x0018, 0xf1: 0x0018, 0xf2: 0x0069, 0xf3: 0x0079, 0xf4: 0x008a, 0xf5: 0x0005, + 0xf6: 0x0018, 0xf7: 0x0008, 0xf8: 0x00aa, 0xf9: 0x00c9, 0xfa: 0x00d9, 0xfb: 0x0018, + 0xfc: 0x00e9, 0xfd: 0x0119, 0xfe: 0x0149, 0xff: 0x0018, + // Block 0x4, offset 0x100 + 0x100: 0xe00d, 0x101: 0x0008, 0x102: 0xe00d, 0x103: 0x0008, 0x104: 0xe00d, 0x105: 0x0008, + 0x106: 0xe00d, 0x107: 0x0008, 0x108: 0xe00d, 0x109: 0x0008, 0x10a: 0xe00d, 0x10b: 0x0008, + 0x10c: 0xe00d, 0x10d: 0x0008, 0x10e: 0xe00d, 0x10f: 0x0008, 0x110: 0xe00d, 0x111: 0x0008, + 0x112: 0xe00d, 0x113: 0x0008, 0x114: 0xe00d, 0x115: 0x0008, 0x116: 0xe00d, 0x117: 0x0008, + 0x118: 0xe00d, 0x119: 0x0008, 0x11a: 0xe00d, 0x11b: 0x0008, 0x11c: 0xe00d, 0x11d: 0x0008, + 0x11e: 0xe00d, 0x11f: 0x0008, 0x120: 0xe00d, 0x121: 0x0008, 0x122: 0xe00d, 0x123: 0x0008, + 0x124: 0xe00d, 0x125: 0x0008, 0x126: 0xe00d, 0x127: 0x0008, 0x128: 0xe00d, 0x129: 0x0008, + 0x12a: 0xe00d, 0x12b: 0x0008, 0x12c: 0xe00d, 0x12d: 0x0008, 0x12e: 0xe00d, 0x12f: 0x0008, + 0x130: 0x0179, 0x131: 0x0008, 0x132: 0x0035, 0x133: 0x004d, 0x134: 0xe00d, 0x135: 0x0008, + 0x136: 0xe00d, 0x137: 0x0008, 0x138: 0x0008, 0x139: 0xe01d, 0x13a: 0x0008, 0x13b: 0xe03d, + 0x13c: 0x0008, 0x13d: 0xe01d, 0x13e: 0x0008, 0x13f: 0x0199, + // Block 0x5, offset 0x140 + 0x140: 0x0199, 0x141: 0xe01d, 0x142: 0x0008, 0x143: 0xe03d, 0x144: 0x0008, 0x145: 0xe01d, + 0x146: 0x0008, 0x147: 0xe07d, 0x148: 0x0008, 0x149: 0x01b9, 0x14a: 0xe00d, 0x14b: 0x0008, + 0x14c: 0xe00d, 0x14d: 0x0008, 0x14e: 0xe00d, 0x14f: 0x0008, 0x150: 0xe00d, 0x151: 0x0008, + 0x152: 0xe00d, 0x153: 0x0008, 0x154: 0xe00d, 0x155: 0x0008, 0x156: 0xe00d, 0x157: 0x0008, + 0x158: 0xe00d, 0x159: 0x0008, 0x15a: 0xe00d, 0x15b: 0x0008, 0x15c: 0xe00d, 0x15d: 0x0008, + 0x15e: 0xe00d, 0x15f: 0x0008, 0x160: 0xe00d, 0x161: 0x0008, 0x162: 0xe00d, 0x163: 0x0008, + 0x164: 0xe00d, 0x165: 0x0008, 0x166: 0xe00d, 0x167: 0x0008, 0x168: 0xe00d, 0x169: 0x0008, + 0x16a: 0xe00d, 0x16b: 0x0008, 0x16c: 0xe00d, 0x16d: 0x0008, 0x16e: 0xe00d, 0x16f: 0x0008, + 0x170: 0xe00d, 0x171: 0x0008, 0x172: 0xe00d, 0x173: 0x0008, 0x174: 0xe00d, 0x175: 0x0008, + 0x176: 0xe00d, 0x177: 0x0008, 0x178: 0x0065, 0x179: 0xe01d, 0x17a: 0x0008, 0x17b: 0xe03d, + 0x17c: 0x0008, 0x17d: 0xe01d, 0x17e: 0x0008, 0x17f: 0x01d9, + // Block 0x6, offset 0x180 + 0x180: 0x0008, 0x181: 0x007d, 0x182: 0xe00d, 0x183: 0x0008, 0x184: 0xe00d, 0x185: 0x0008, + 0x186: 0x007d, 0x187: 0xe07d, 0x188: 0x0008, 0x189: 0x0095, 0x18a: 0x00ad, 0x18b: 0xe03d, + 0x18c: 0x0008, 0x18d: 0x0008, 0x18e: 0x00c5, 0x18f: 0x00dd, 0x190: 0x00f5, 0x191: 0xe01d, + 0x192: 0x0008, 0x193: 0x010d, 0x194: 0x0125, 0x195: 0x0008, 0x196: 0x013d, 0x197: 0x013d, + 0x198: 0xe00d, 0x199: 0x0008, 0x19a: 0x0008, 0x19b: 0x0008, 0x19c: 0x010d, 0x19d: 0x0155, + 0x19e: 0x0008, 0x19f: 0x016d, 0x1a0: 0xe00d, 0x1a1: 0x0008, 0x1a2: 0xe00d, 0x1a3: 0x0008, + 0x1a4: 0xe00d, 0x1a5: 0x0008, 0x1a6: 0x0185, 0x1a7: 0xe07d, 0x1a8: 0x0008, 0x1a9: 0x019d, + 0x1aa: 0x0008, 0x1ab: 0x0008, 0x1ac: 0xe00d, 0x1ad: 0x0008, 0x1ae: 0x0185, 0x1af: 0xe0fd, + 0x1b0: 0x0008, 0x1b1: 0x01b5, 0x1b2: 0x01cd, 0x1b3: 0xe03d, 0x1b4: 0x0008, 0x1b5: 0xe01d, + 0x1b6: 0x0008, 0x1b7: 0x01e5, 0x1b8: 0xe00d, 0x1b9: 0x0008, 0x1ba: 0x0008, 0x1bb: 0x0008, + 0x1bc: 0xe00d, 0x1bd: 0x0008, 0x1be: 0x0008, 0x1bf: 0x0008, + // Block 0x7, offset 0x1c0 + 0x1c0: 0x0008, 0x1c1: 0x0008, 0x1c2: 0x0008, 0x1c3: 0x0008, 0x1c4: 0x01e9, 0x1c5: 0x01e9, + 0x1c6: 0x01e9, 0x1c7: 0x01fd, 0x1c8: 0x0215, 0x1c9: 0x022d, 0x1ca: 0x0245, 0x1cb: 0x025d, + 0x1cc: 0x0275, 0x1cd: 0xe01d, 0x1ce: 0x0008, 0x1cf: 0xe0fd, 0x1d0: 0x0008, 0x1d1: 0xe01d, + 0x1d2: 0x0008, 0x1d3: 0xe03d, 0x1d4: 0x0008, 0x1d5: 0xe01d, 0x1d6: 0x0008, 0x1d7: 0xe07d, + 0x1d8: 0x0008, 0x1d9: 0xe01d, 0x1da: 0x0008, 0x1db: 0xe03d, 0x1dc: 0x0008, 0x1dd: 0x0008, + 0x1de: 0xe00d, 0x1df: 0x0008, 0x1e0: 0xe00d, 0x1e1: 0x0008, 0x1e2: 0xe00d, 0x1e3: 0x0008, + 0x1e4: 0xe00d, 0x1e5: 0x0008, 0x1e6: 0xe00d, 0x1e7: 0x0008, 0x1e8: 0xe00d, 0x1e9: 0x0008, + 0x1ea: 0xe00d, 0x1eb: 0x0008, 0x1ec: 0xe00d, 0x1ed: 0x0008, 0x1ee: 0xe00d, 0x1ef: 0x0008, + 0x1f0: 0x0008, 0x1f1: 0x028d, 0x1f2: 0x02a5, 0x1f3: 0x02bd, 0x1f4: 0xe00d, 0x1f5: 0x0008, + 0x1f6: 0x02d5, 0x1f7: 0x02ed, 0x1f8: 0xe00d, 0x1f9: 0x0008, 0x1fa: 0xe00d, 0x1fb: 0x0008, + 0x1fc: 0xe00d, 0x1fd: 0x0008, 0x1fe: 0xe00d, 0x1ff: 0x0008, + // Block 0x8, offset 0x200 + 0x200: 0xe00d, 0x201: 0x0008, 0x202: 0xe00d, 0x203: 0x0008, 0x204: 0xe00d, 0x205: 0x0008, + 0x206: 0xe00d, 0x207: 0x0008, 0x208: 0xe00d, 0x209: 0x0008, 0x20a: 0xe00d, 0x20b: 0x0008, + 0x20c: 0xe00d, 0x20d: 0x0008, 0x20e: 0xe00d, 0x20f: 0x0008, 0x210: 0xe00d, 0x211: 0x0008, + 0x212: 0xe00d, 0x213: 0x0008, 0x214: 0xe00d, 0x215: 0x0008, 0x216: 0xe00d, 0x217: 0x0008, + 0x218: 0xe00d, 0x219: 0x0008, 0x21a: 0xe00d, 0x21b: 0x0008, 0x21c: 0xe00d, 0x21d: 0x0008, + 0x21e: 0xe00d, 0x21f: 0x0008, 0x220: 0x0305, 0x221: 0x0008, 0x222: 0xe00d, 0x223: 0x0008, + 0x224: 0xe00d, 0x225: 0x0008, 0x226: 0xe00d, 0x227: 0x0008, 0x228: 0xe00d, 0x229: 0x0008, + 0x22a: 0xe00d, 0x22b: 0x0008, 0x22c: 0xe00d, 0x22d: 0x0008, 0x22e: 0xe00d, 0x22f: 0x0008, + 0x230: 0xe00d, 0x231: 0x0008, 0x232: 0xe00d, 0x233: 0x0008, 0x234: 0x0008, 0x235: 0x0008, + 0x236: 0x0008, 0x237: 0x0008, 0x238: 0x0008, 0x239: 0x0008, 0x23a: 0x0209, 0x23b: 0xe03d, + 0x23c: 0x0008, 0x23d: 0x031d, 0x23e: 0x0229, 0x23f: 0x0008, + // Block 0x9, offset 0x240 + 0x240: 0x0008, 0x241: 0x0008, 0x242: 0x0018, 0x243: 0x0018, 0x244: 0x0018, 0x245: 0x0018, + 0x246: 0x0008, 0x247: 0x0008, 0x248: 0x0008, 0x249: 0x0008, 0x24a: 0x0008, 0x24b: 0x0008, + 0x24c: 0x0008, 0x24d: 0x0008, 0x24e: 0x0008, 0x24f: 0x0008, 0x250: 0x0008, 0x251: 0x0008, + 0x252: 0x0018, 0x253: 0x0018, 0x254: 0x0018, 0x255: 0x0018, 0x256: 0x0018, 0x257: 0x0018, + 0x258: 0x029a, 0x259: 0x02ba, 0x25a: 0x02da, 0x25b: 0x02fa, 0x25c: 0x031a, 0x25d: 0x033a, + 0x25e: 0x0018, 0x25f: 0x0018, 0x260: 0x03ad, 0x261: 0x0359, 0x262: 0x01d9, 0x263: 0x0369, + 0x264: 0x03c5, 0x265: 0x0018, 0x266: 0x0018, 0x267: 0x0018, 0x268: 0x0018, 0x269: 0x0018, + 0x26a: 0x0018, 0x26b: 0x0018, 0x26c: 0x0008, 0x26d: 0x0018, 0x26e: 0x0008, 0x26f: 0x0018, + 0x270: 0x0018, 0x271: 0x0018, 0x272: 0x0018, 0x273: 0x0018, 0x274: 0x0018, 0x275: 0x0018, + 0x276: 0x0018, 0x277: 0x0018, 0x278: 0x0018, 0x279: 0x0018, 0x27a: 0x0018, 0x27b: 0x0018, + 0x27c: 0x0018, 0x27d: 0x0018, 0x27e: 0x0018, 0x27f: 0x0018, + // Block 0xa, offset 0x280 + 0x280: 0x03dd, 0x281: 0x03dd, 0x282: 0x3308, 0x283: 0x03f5, 0x284: 0x0379, 0x285: 0x040d, + 0x286: 0x3308, 0x287: 0x3308, 0x288: 0x3308, 0x289: 0x3308, 0x28a: 0x3308, 0x28b: 0x3308, + 0x28c: 0x3308, 0x28d: 0x3308, 0x28e: 0x3308, 0x28f: 0x33c0, 0x290: 0x3308, 0x291: 0x3308, + 0x292: 0x3308, 0x293: 0x3308, 0x294: 0x3308, 0x295: 0x3308, 0x296: 0x3308, 0x297: 0x3308, + 0x298: 0x3308, 0x299: 0x3308, 0x29a: 0x3308, 0x29b: 0x3308, 0x29c: 0x3308, 0x29d: 0x3308, + 0x29e: 0x3308, 0x29f: 0x3308, 0x2a0: 0x3308, 0x2a1: 0x3308, 0x2a2: 0x3308, 0x2a3: 0x3308, + 0x2a4: 0x3308, 0x2a5: 0x3308, 0x2a6: 0x3308, 0x2a7: 0x3308, 0x2a8: 0x3308, 0x2a9: 0x3308, + 0x2aa: 0x3308, 0x2ab: 0x3308, 0x2ac: 0x3308, 0x2ad: 0x3308, 0x2ae: 0x3308, 0x2af: 0x3308, + 0x2b0: 0xe00d, 0x2b1: 0x0008, 0x2b2: 0xe00d, 0x2b3: 0x0008, 0x2b4: 0x0425, 0x2b5: 0x0008, + 0x2b6: 0xe00d, 0x2b7: 0x0008, 0x2b8: 0x0040, 0x2b9: 0x0040, 0x2ba: 0x03a2, 0x2bb: 0x0008, + 0x2bc: 0x0008, 0x2bd: 0x0008, 0x2be: 0x03c2, 0x2bf: 0x043d, + // Block 0xb, offset 0x2c0 + 0x2c0: 0x0040, 0x2c1: 0x0040, 0x2c2: 0x0040, 0x2c3: 0x0040, 0x2c4: 0x008a, 0x2c5: 0x03d2, + 0x2c6: 0xe155, 0x2c7: 0x0455, 0x2c8: 0xe12d, 0x2c9: 0xe13d, 0x2ca: 0xe12d, 0x2cb: 0x0040, + 0x2cc: 0x03dd, 0x2cd: 0x0040, 0x2ce: 0x046d, 0x2cf: 0x0485, 0x2d0: 0x0008, 0x2d1: 0xe105, + 0x2d2: 0xe105, 0x2d3: 0xe105, 0x2d4: 0xe105, 0x2d5: 0xe105, 0x2d6: 0xe105, 0x2d7: 0xe105, + 0x2d8: 0xe105, 0x2d9: 0xe105, 0x2da: 0xe105, 0x2db: 0xe105, 0x2dc: 0xe105, 0x2dd: 0xe105, + 0x2de: 0xe105, 0x2df: 0xe105, 0x2e0: 0x049d, 0x2e1: 0x049d, 0x2e2: 0x0040, 0x2e3: 0x049d, + 0x2e4: 0x049d, 0x2e5: 0x049d, 0x2e6: 0x049d, 0x2e7: 0x049d, 0x2e8: 0x049d, 0x2e9: 0x049d, + 0x2ea: 0x049d, 0x2eb: 0x049d, 0x2ec: 0x0008, 0x2ed: 0x0008, 0x2ee: 0x0008, 0x2ef: 0x0008, + 0x2f0: 0x0008, 0x2f1: 0x0008, 0x2f2: 0x0008, 0x2f3: 0x0008, 0x2f4: 0x0008, 0x2f5: 0x0008, + 0x2f6: 0x0008, 0x2f7: 0x0008, 0x2f8: 0x0008, 0x2f9: 0x0008, 0x2fa: 0x0008, 0x2fb: 0x0008, + 0x2fc: 0x0008, 0x2fd: 0x0008, 0x2fe: 0x0008, 0x2ff: 0x0008, + // Block 0xc, offset 0x300 + 0x300: 0x0008, 0x301: 0x0008, 0x302: 0xe00f, 0x303: 0x0008, 0x304: 0x0008, 0x305: 0x0008, + 0x306: 0x0008, 0x307: 0x0008, 0x308: 0x0008, 0x309: 0x0008, 0x30a: 0x0008, 0x30b: 0x0008, + 0x30c: 0x0008, 0x30d: 0x0008, 0x30e: 0x0008, 0x30f: 0xe0c5, 0x310: 0x04b5, 0x311: 0x04cd, + 0x312: 0xe0bd, 0x313: 0xe0f5, 0x314: 0xe0fd, 0x315: 0xe09d, 0x316: 0xe0b5, 0x317: 0x0008, + 0x318: 0xe00d, 0x319: 0x0008, 0x31a: 0xe00d, 0x31b: 0x0008, 0x31c: 0xe00d, 0x31d: 0x0008, + 0x31e: 0xe00d, 0x31f: 0x0008, 0x320: 0xe00d, 0x321: 0x0008, 0x322: 0xe00d, 0x323: 0x0008, + 0x324: 0xe00d, 0x325: 0x0008, 0x326: 0xe00d, 0x327: 0x0008, 0x328: 0xe00d, 0x329: 0x0008, + 0x32a: 0xe00d, 0x32b: 0x0008, 0x32c: 0xe00d, 0x32d: 0x0008, 0x32e: 0xe00d, 0x32f: 0x0008, + 0x330: 0x04e5, 0x331: 0xe185, 0x332: 0xe18d, 0x333: 0x0008, 0x334: 0x04fd, 0x335: 0x03dd, + 0x336: 0x0018, 0x337: 0xe07d, 0x338: 0x0008, 0x339: 0xe1d5, 0x33a: 0xe00d, 0x33b: 0x0008, + 0x33c: 0x0008, 0x33d: 0x0515, 0x33e: 0x052d, 0x33f: 0x052d, + // Block 0xd, offset 0x340 + 0x340: 0x0008, 0x341: 0x0008, 0x342: 0x0008, 0x343: 0x0008, 0x344: 0x0008, 0x345: 0x0008, + 0x346: 0x0008, 0x347: 0x0008, 0x348: 0x0008, 0x349: 0x0008, 0x34a: 0x0008, 0x34b: 0x0008, + 0x34c: 0x0008, 0x34d: 0x0008, 0x34e: 0x0008, 0x34f: 0x0008, 0x350: 0x0008, 0x351: 0x0008, + 0x352: 0x0008, 0x353: 0x0008, 0x354: 0x0008, 0x355: 0x0008, 0x356: 0x0008, 0x357: 0x0008, + 0x358: 0x0008, 0x359: 0x0008, 0x35a: 0x0008, 0x35b: 0x0008, 0x35c: 0x0008, 0x35d: 0x0008, + 0x35e: 0x0008, 0x35f: 0x0008, 0x360: 0xe00d, 0x361: 0x0008, 0x362: 0xe00d, 0x363: 0x0008, + 0x364: 0xe00d, 0x365: 0x0008, 0x366: 0xe00d, 0x367: 0x0008, 0x368: 0xe00d, 0x369: 0x0008, + 0x36a: 0xe00d, 0x36b: 0x0008, 0x36c: 0xe00d, 0x36d: 0x0008, 0x36e: 0xe00d, 0x36f: 0x0008, + 0x370: 0xe00d, 0x371: 0x0008, 0x372: 0xe00d, 0x373: 0x0008, 0x374: 0xe00d, 0x375: 0x0008, + 0x376: 0xe00d, 0x377: 0x0008, 0x378: 0xe00d, 0x379: 0x0008, 0x37a: 0xe00d, 0x37b: 0x0008, + 0x37c: 0xe00d, 0x37d: 0x0008, 0x37e: 0xe00d, 0x37f: 0x0008, + // Block 0xe, offset 0x380 + 0x380: 0xe00d, 0x381: 0x0008, 0x382: 0x0018, 0x383: 0x3308, 0x384: 0x3308, 0x385: 0x3308, + 0x386: 0x3308, 0x387: 0x3308, 0x388: 0x3318, 0x389: 0x3318, 0x38a: 0xe00d, 0x38b: 0x0008, + 0x38c: 0xe00d, 0x38d: 0x0008, 0x38e: 0xe00d, 0x38f: 0x0008, 0x390: 0xe00d, 0x391: 0x0008, + 0x392: 0xe00d, 0x393: 0x0008, 0x394: 0xe00d, 0x395: 0x0008, 0x396: 0xe00d, 0x397: 0x0008, + 0x398: 0xe00d, 0x399: 0x0008, 0x39a: 0xe00d, 0x39b: 0x0008, 0x39c: 0xe00d, 0x39d: 0x0008, + 0x39e: 0xe00d, 0x39f: 0x0008, 0x3a0: 0xe00d, 0x3a1: 0x0008, 0x3a2: 0xe00d, 0x3a3: 0x0008, + 0x3a4: 0xe00d, 0x3a5: 0x0008, 0x3a6: 0xe00d, 0x3a7: 0x0008, 0x3a8: 0xe00d, 0x3a9: 0x0008, + 0x3aa: 0xe00d, 0x3ab: 0x0008, 0x3ac: 0xe00d, 0x3ad: 0x0008, 0x3ae: 0xe00d, 0x3af: 0x0008, + 0x3b0: 0xe00d, 0x3b1: 0x0008, 0x3b2: 0xe00d, 0x3b3: 0x0008, 0x3b4: 0xe00d, 0x3b5: 0x0008, + 0x3b6: 0xe00d, 0x3b7: 0x0008, 0x3b8: 0xe00d, 0x3b9: 0x0008, 0x3ba: 0xe00d, 0x3bb: 0x0008, + 0x3bc: 0xe00d, 0x3bd: 0x0008, 0x3be: 0xe00d, 0x3bf: 0x0008, + // Block 0xf, offset 0x3c0 + 0x3c0: 0x0040, 0x3c1: 0xe01d, 0x3c2: 0x0008, 0x3c3: 0xe03d, 0x3c4: 0x0008, 0x3c5: 0xe01d, + 0x3c6: 0x0008, 0x3c7: 0xe07d, 0x3c8: 0x0008, 0x3c9: 0xe01d, 0x3ca: 0x0008, 0x3cb: 0xe03d, + 0x3cc: 0x0008, 0x3cd: 0xe01d, 0x3ce: 0x0008, 0x3cf: 0x0008, 0x3d0: 0xe00d, 0x3d1: 0x0008, + 0x3d2: 0xe00d, 0x3d3: 0x0008, 0x3d4: 0xe00d, 0x3d5: 0x0008, 0x3d6: 0xe00d, 0x3d7: 0x0008, + 0x3d8: 0xe00d, 0x3d9: 0x0008, 0x3da: 0xe00d, 0x3db: 0x0008, 0x3dc: 0xe00d, 0x3dd: 0x0008, + 0x3de: 0xe00d, 0x3df: 0x0008, 0x3e0: 0xe00d, 0x3e1: 0x0008, 0x3e2: 0xe00d, 0x3e3: 0x0008, + 0x3e4: 0xe00d, 0x3e5: 0x0008, 0x3e6: 0xe00d, 0x3e7: 0x0008, 0x3e8: 0xe00d, 0x3e9: 0x0008, + 0x3ea: 0xe00d, 0x3eb: 0x0008, 0x3ec: 0xe00d, 0x3ed: 0x0008, 0x3ee: 0xe00d, 0x3ef: 0x0008, + 0x3f0: 0xe00d, 0x3f1: 0x0008, 0x3f2: 0xe00d, 0x3f3: 0x0008, 0x3f4: 0xe00d, 0x3f5: 0x0008, + 0x3f6: 0xe00d, 0x3f7: 0x0008, 0x3f8: 0xe00d, 0x3f9: 0x0008, 0x3fa: 0xe00d, 0x3fb: 0x0008, + 0x3fc: 0xe00d, 0x3fd: 0x0008, 0x3fe: 0xe00d, 0x3ff: 0x0008, + // Block 0x10, offset 0x400 + 0x400: 0xe00d, 0x401: 0x0008, 0x402: 0xe00d, 0x403: 0x0008, 0x404: 0xe00d, 0x405: 0x0008, + 0x406: 0xe00d, 0x407: 0x0008, 0x408: 0xe00d, 0x409: 0x0008, 0x40a: 0xe00d, 0x40b: 0x0008, + 0x40c: 0xe00d, 0x40d: 0x0008, 0x40e: 0xe00d, 0x40f: 0x0008, 0x410: 0xe00d, 0x411: 0x0008, + 0x412: 0xe00d, 0x413: 0x0008, 0x414: 0xe00d, 0x415: 0x0008, 0x416: 0xe00d, 0x417: 0x0008, + 0x418: 0xe00d, 0x419: 0x0008, 0x41a: 0xe00d, 0x41b: 0x0008, 0x41c: 0xe00d, 0x41d: 0x0008, + 0x41e: 0xe00d, 0x41f: 0x0008, 0x420: 0xe00d, 0x421: 0x0008, 0x422: 0xe00d, 0x423: 0x0008, + 0x424: 0xe00d, 0x425: 0x0008, 0x426: 0xe00d, 0x427: 0x0008, 0x428: 0xe00d, 0x429: 0x0008, + 0x42a: 0xe00d, 0x42b: 0x0008, 0x42c: 0xe00d, 0x42d: 0x0008, 0x42e: 0xe00d, 0x42f: 0x0008, + 0x430: 0x0040, 0x431: 0x03f5, 0x432: 0x03f5, 0x433: 0x03f5, 0x434: 0x03f5, 0x435: 0x03f5, + 0x436: 0x03f5, 0x437: 0x03f5, 0x438: 0x03f5, 0x439: 0x03f5, 0x43a: 0x03f5, 0x43b: 0x03f5, + 0x43c: 0x03f5, 0x43d: 0x03f5, 0x43e: 0x03f5, 0x43f: 0x03f5, + // Block 0x11, offset 0x440 + 0x440: 0x0840, 0x441: 0x0840, 0x442: 0x0840, 0x443: 0x0840, 0x444: 0x0840, 0x445: 0x0840, + 0x446: 0x0018, 0x447: 0x0018, 0x448: 0x0818, 0x449: 0x0018, 0x44a: 0x0018, 0x44b: 0x0818, + 0x44c: 0x0018, 0x44d: 0x0818, 0x44e: 0x0018, 0x44f: 0x0018, 0x450: 0x3308, 0x451: 0x3308, + 0x452: 0x3308, 0x453: 0x3308, 0x454: 0x3308, 0x455: 0x3308, 0x456: 0x3308, 0x457: 0x3308, + 0x458: 0x3308, 0x459: 0x3308, 0x45a: 0x3308, 0x45b: 0x0818, 0x45c: 0x0b40, 0x45d: 0x0040, + 0x45e: 0x0818, 0x45f: 0x0818, 0x460: 0x0a08, 0x461: 0x0808, 0x462: 0x0c08, 0x463: 0x0c08, + 0x464: 0x0c08, 0x465: 0x0c08, 0x466: 0x0a08, 0x467: 0x0c08, 0x468: 0x0a08, 0x469: 0x0c08, + 0x46a: 0x0a08, 0x46b: 0x0a08, 0x46c: 0x0a08, 0x46d: 0x0a08, 0x46e: 0x0a08, 0x46f: 0x0c08, + 0x470: 0x0c08, 0x471: 0x0c08, 0x472: 0x0c08, 0x473: 0x0a08, 0x474: 0x0a08, 0x475: 0x0a08, + 0x476: 0x0a08, 0x477: 0x0a08, 0x478: 0x0a08, 0x479: 0x0a08, 0x47a: 0x0a08, 0x47b: 0x0a08, + 0x47c: 0x0a08, 0x47d: 0x0a08, 0x47e: 0x0a08, 0x47f: 0x0a08, + // Block 0x12, offset 0x480 + 0x480: 0x0818, 0x481: 0x0a08, 0x482: 0x0a08, 0x483: 0x0a08, 0x484: 0x0a08, 0x485: 0x0a08, + 0x486: 0x0a08, 0x487: 0x0a08, 0x488: 0x0c08, 0x489: 0x0a08, 0x48a: 0x0a08, 0x48b: 0x3308, + 0x48c: 0x3308, 0x48d: 0x3308, 0x48e: 0x3308, 0x48f: 0x3308, 0x490: 0x3308, 0x491: 0x3308, + 0x492: 0x3308, 0x493: 0x3308, 0x494: 0x3308, 0x495: 0x3308, 0x496: 0x3308, 0x497: 0x3308, + 0x498: 0x3308, 0x499: 0x3308, 0x49a: 0x3308, 0x49b: 0x3308, 0x49c: 0x3308, 0x49d: 0x3308, + 0x49e: 0x3308, 0x49f: 0x3308, 0x4a0: 0x0808, 0x4a1: 0x0808, 0x4a2: 0x0808, 0x4a3: 0x0808, + 0x4a4: 0x0808, 0x4a5: 0x0808, 0x4a6: 0x0808, 0x4a7: 0x0808, 0x4a8: 0x0808, 0x4a9: 0x0808, + 0x4aa: 0x0018, 0x4ab: 0x0818, 0x4ac: 0x0818, 0x4ad: 0x0818, 0x4ae: 0x0a08, 0x4af: 0x0a08, + 0x4b0: 0x3308, 0x4b1: 0x0c08, 0x4b2: 0x0c08, 0x4b3: 0x0c08, 0x4b4: 0x0808, 0x4b5: 0x0429, + 0x4b6: 0x0451, 0x4b7: 0x0479, 0x4b8: 0x04a1, 0x4b9: 0x0a08, 0x4ba: 0x0a08, 0x4bb: 0x0a08, + 0x4bc: 0x0a08, 0x4bd: 0x0a08, 0x4be: 0x0a08, 0x4bf: 0x0a08, + // Block 0x13, offset 0x4c0 + 0x4c0: 0x0c08, 0x4c1: 0x0a08, 0x4c2: 0x0a08, 0x4c3: 0x0c08, 0x4c4: 0x0c08, 0x4c5: 0x0c08, + 0x4c6: 0x0c08, 0x4c7: 0x0c08, 0x4c8: 0x0c08, 0x4c9: 0x0c08, 0x4ca: 0x0c08, 0x4cb: 0x0c08, + 0x4cc: 0x0a08, 0x4cd: 0x0c08, 0x4ce: 0x0a08, 0x4cf: 0x0c08, 0x4d0: 0x0a08, 0x4d1: 0x0a08, + 0x4d2: 0x0c08, 0x4d3: 0x0c08, 0x4d4: 0x0818, 0x4d5: 0x0c08, 0x4d6: 0x3308, 0x4d7: 0x3308, + 0x4d8: 0x3308, 0x4d9: 0x3308, 0x4da: 0x3308, 0x4db: 0x3308, 0x4dc: 0x3308, 0x4dd: 0x0840, + 0x4de: 0x0018, 0x4df: 0x3308, 0x4e0: 0x3308, 0x4e1: 0x3308, 0x4e2: 0x3308, 0x4e3: 0x3308, + 0x4e4: 0x3308, 0x4e5: 0x0808, 0x4e6: 0x0808, 0x4e7: 0x3308, 0x4e8: 0x3308, 0x4e9: 0x0018, + 0x4ea: 0x3308, 0x4eb: 0x3308, 0x4ec: 0x3308, 0x4ed: 0x3308, 0x4ee: 0x0c08, 0x4ef: 0x0c08, + 0x4f0: 0x0008, 0x4f1: 0x0008, 0x4f2: 0x0008, 0x4f3: 0x0008, 0x4f4: 0x0008, 0x4f5: 0x0008, + 0x4f6: 0x0008, 0x4f7: 0x0008, 0x4f8: 0x0008, 0x4f9: 0x0008, 0x4fa: 0x0a08, 0x4fb: 0x0a08, + 0x4fc: 0x0a08, 0x4fd: 0x0808, 0x4fe: 0x0808, 0x4ff: 0x0a08, + // Block 0x14, offset 0x500 + 0x500: 0x0818, 0x501: 0x0818, 0x502: 0x0818, 0x503: 0x0818, 0x504: 0x0818, 0x505: 0x0818, + 0x506: 0x0818, 0x507: 0x0818, 0x508: 0x0818, 0x509: 0x0818, 0x50a: 0x0818, 0x50b: 0x0818, + 0x50c: 0x0818, 0x50d: 0x0818, 0x50e: 0x0040, 0x50f: 0x0b40, 0x510: 0x0c08, 0x511: 0x3308, + 0x512: 0x0a08, 0x513: 0x0a08, 0x514: 0x0a08, 0x515: 0x0c08, 0x516: 0x0c08, 0x517: 0x0c08, + 0x518: 0x0c08, 0x519: 0x0c08, 0x51a: 0x0a08, 0x51b: 0x0a08, 0x51c: 0x0a08, 0x51d: 0x0a08, + 0x51e: 0x0c08, 0x51f: 0x0a08, 0x520: 0x0a08, 0x521: 0x0a08, 0x522: 0x0a08, 0x523: 0x0a08, + 0x524: 0x0a08, 0x525: 0x0a08, 0x526: 0x0a08, 0x527: 0x0a08, 0x528: 0x0c08, 0x529: 0x0a08, + 0x52a: 0x0c08, 0x52b: 0x0a08, 0x52c: 0x0c08, 0x52d: 0x0a08, 0x52e: 0x0a08, 0x52f: 0x0c08, + 0x530: 0x3308, 0x531: 0x3308, 0x532: 0x3308, 0x533: 0x3308, 0x534: 0x3308, 0x535: 0x3308, + 0x536: 0x3308, 0x537: 0x3308, 0x538: 0x3308, 0x539: 0x3308, 0x53a: 0x3308, 0x53b: 0x3308, + 0x53c: 0x3308, 0x53d: 0x3308, 0x53e: 0x3308, 0x53f: 0x3308, + // Block 0x15, offset 0x540 + 0x540: 0x0c08, 0x541: 0x0a08, 0x542: 0x0a08, 0x543: 0x0a08, 0x544: 0x0a08, 0x545: 0x0a08, + 0x546: 0x0c08, 0x547: 0x0c08, 0x548: 0x0a08, 0x549: 0x0c08, 0x54a: 0x0a08, 0x54b: 0x0a08, + 0x54c: 0x0a08, 0x54d: 0x0a08, 0x54e: 0x0a08, 0x54f: 0x0a08, 0x550: 0x0a08, 0x551: 0x0a08, + 0x552: 0x0a08, 0x553: 0x0a08, 0x554: 0x0c08, 0x555: 0x0a08, 0x556: 0x0808, 0x557: 0x0808, + 0x558: 0x0808, 0x559: 0x3308, 0x55a: 0x3308, 0x55b: 0x3308, 0x55c: 0x0040, 0x55d: 0x0040, + 0x55e: 0x0818, 0x55f: 0x0040, 0x560: 0x0a08, 0x561: 0x0808, 0x562: 0x0a08, 0x563: 0x0a08, + 0x564: 0x0a08, 0x565: 0x0a08, 0x566: 0x0808, 0x567: 0x0c08, 0x568: 0x0a08, 0x569: 0x0c08, + 0x56a: 0x0c08, 0x56b: 0x0040, 0x56c: 0x0040, 0x56d: 0x0040, 0x56e: 0x0040, 0x56f: 0x0040, + 0x570: 0x0040, 0x571: 0x0040, 0x572: 0x0040, 0x573: 0x0040, 0x574: 0x0040, 0x575: 0x0040, + 0x576: 0x0040, 0x577: 0x0040, 0x578: 0x0040, 0x579: 0x0040, 0x57a: 0x0040, 0x57b: 0x0040, + 0x57c: 0x0040, 0x57d: 0x0040, 0x57e: 0x0040, 0x57f: 0x0040, + // Block 0x16, offset 0x580 + 0x580: 0x3008, 0x581: 0x3308, 0x582: 0x3308, 0x583: 0x3308, 0x584: 0x3308, 0x585: 0x3308, + 0x586: 0x3308, 0x587: 0x3308, 0x588: 0x3308, 0x589: 0x3008, 0x58a: 0x3008, 0x58b: 0x3008, + 0x58c: 0x3008, 0x58d: 0x3b08, 0x58e: 0x3008, 0x58f: 0x3008, 0x590: 0x0008, 0x591: 0x3308, + 0x592: 0x3308, 0x593: 0x3308, 0x594: 0x3308, 0x595: 0x3308, 0x596: 0x3308, 0x597: 0x3308, + 0x598: 0x04c9, 0x599: 0x0501, 0x59a: 0x0539, 0x59b: 0x0571, 0x59c: 0x05a9, 0x59d: 0x05e1, + 0x59e: 0x0619, 0x59f: 0x0651, 0x5a0: 0x0008, 0x5a1: 0x0008, 0x5a2: 0x3308, 0x5a3: 0x3308, + 0x5a4: 0x0018, 0x5a5: 0x0018, 0x5a6: 0x0008, 0x5a7: 0x0008, 0x5a8: 0x0008, 0x5a9: 0x0008, + 0x5aa: 0x0008, 0x5ab: 0x0008, 0x5ac: 0x0008, 0x5ad: 0x0008, 0x5ae: 0x0008, 0x5af: 0x0008, + 0x5b0: 0x0018, 0x5b1: 0x0008, 0x5b2: 0x0008, 0x5b3: 0x0008, 0x5b4: 0x0008, 0x5b5: 0x0008, + 0x5b6: 0x0008, 0x5b7: 0x0008, 0x5b8: 0x0008, 0x5b9: 0x0008, 0x5ba: 0x0008, 0x5bb: 0x0008, + 0x5bc: 0x0008, 0x5bd: 0x0008, 0x5be: 0x0008, 0x5bf: 0x0008, + // Block 0x17, offset 0x5c0 + 0x5c0: 0x0008, 0x5c1: 0x3308, 0x5c2: 0x3008, 0x5c3: 0x3008, 0x5c4: 0x0040, 0x5c5: 0x0008, + 0x5c6: 0x0008, 0x5c7: 0x0008, 0x5c8: 0x0008, 0x5c9: 0x0008, 0x5ca: 0x0008, 0x5cb: 0x0008, + 0x5cc: 0x0008, 0x5cd: 0x0040, 0x5ce: 0x0040, 0x5cf: 0x0008, 0x5d0: 0x0008, 0x5d1: 0x0040, + 0x5d2: 0x0040, 0x5d3: 0x0008, 0x5d4: 0x0008, 0x5d5: 0x0008, 0x5d6: 0x0008, 0x5d7: 0x0008, + 0x5d8: 0x0008, 0x5d9: 0x0008, 0x5da: 0x0008, 0x5db: 0x0008, 0x5dc: 0x0008, 0x5dd: 0x0008, + 0x5de: 0x0008, 0x5df: 0x0008, 0x5e0: 0x0008, 0x5e1: 0x0008, 0x5e2: 0x0008, 0x5e3: 0x0008, + 0x5e4: 0x0008, 0x5e5: 0x0008, 0x5e6: 0x0008, 0x5e7: 0x0008, 0x5e8: 0x0008, 0x5e9: 0x0040, + 0x5ea: 0x0008, 0x5eb: 0x0008, 0x5ec: 0x0008, 0x5ed: 0x0008, 0x5ee: 0x0008, 0x5ef: 0x0008, + 0x5f0: 0x0008, 0x5f1: 0x0040, 0x5f2: 0x0008, 0x5f3: 0x0040, 0x5f4: 0x0040, 0x5f5: 0x0040, + 0x5f6: 0x0008, 0x5f7: 0x0008, 0x5f8: 0x0008, 0x5f9: 0x0008, 0x5fa: 0x0040, 0x5fb: 0x0040, + 0x5fc: 0x3308, 0x5fd: 0x0008, 0x5fe: 0x3008, 0x5ff: 0x3008, + // Block 0x18, offset 0x600 + 0x600: 0x3008, 0x601: 0x3308, 0x602: 0x3308, 0x603: 0x3308, 0x604: 0x3308, 0x605: 0x0040, + 0x606: 0x0040, 0x607: 0x3008, 0x608: 0x3008, 0x609: 0x0040, 0x60a: 0x0040, 0x60b: 0x3008, + 0x60c: 0x3008, 0x60d: 0x3b08, 0x60e: 0x0008, 0x60f: 0x0040, 0x610: 0x0040, 0x611: 0x0040, + 0x612: 0x0040, 0x613: 0x0040, 0x614: 0x0040, 0x615: 0x0040, 0x616: 0x0040, 0x617: 0x3008, + 0x618: 0x0040, 0x619: 0x0040, 0x61a: 0x0040, 0x61b: 0x0040, 0x61c: 0x0689, 0x61d: 0x06c1, + 0x61e: 0x0040, 0x61f: 0x06f9, 0x620: 0x0008, 0x621: 0x0008, 0x622: 0x3308, 0x623: 0x3308, + 0x624: 0x0040, 0x625: 0x0040, 0x626: 0x0008, 0x627: 0x0008, 0x628: 0x0008, 0x629: 0x0008, + 0x62a: 0x0008, 0x62b: 0x0008, 0x62c: 0x0008, 0x62d: 0x0008, 0x62e: 0x0008, 0x62f: 0x0008, + 0x630: 0x0008, 0x631: 0x0008, 0x632: 0x0018, 0x633: 0x0018, 0x634: 0x0018, 0x635: 0x0018, + 0x636: 0x0018, 0x637: 0x0018, 0x638: 0x0018, 0x639: 0x0018, 0x63a: 0x0018, 0x63b: 0x0018, + 0x63c: 0x0008, 0x63d: 0x0018, 0x63e: 0x0040, 0x63f: 0x0040, + // Block 0x19, offset 0x640 + 0x640: 0x0040, 0x641: 0x3308, 0x642: 0x3308, 0x643: 0x3008, 0x644: 0x0040, 0x645: 0x0008, + 0x646: 0x0008, 0x647: 0x0008, 0x648: 0x0008, 0x649: 0x0008, 0x64a: 0x0008, 0x64b: 0x0040, + 0x64c: 0x0040, 0x64d: 0x0040, 0x64e: 0x0040, 0x64f: 0x0008, 0x650: 0x0008, 0x651: 0x0040, + 0x652: 0x0040, 0x653: 0x0008, 0x654: 0x0008, 0x655: 0x0008, 0x656: 0x0008, 0x657: 0x0008, + 0x658: 0x0008, 0x659: 0x0008, 0x65a: 0x0008, 0x65b: 0x0008, 0x65c: 0x0008, 0x65d: 0x0008, + 0x65e: 0x0008, 0x65f: 0x0008, 0x660: 0x0008, 0x661: 0x0008, 0x662: 0x0008, 0x663: 0x0008, + 0x664: 0x0008, 0x665: 0x0008, 0x666: 0x0008, 0x667: 0x0008, 0x668: 0x0008, 0x669: 0x0040, + 0x66a: 0x0008, 0x66b: 0x0008, 0x66c: 0x0008, 0x66d: 0x0008, 0x66e: 0x0008, 0x66f: 0x0008, + 0x670: 0x0008, 0x671: 0x0040, 0x672: 0x0008, 0x673: 0x0731, 0x674: 0x0040, 0x675: 0x0008, + 0x676: 0x0769, 0x677: 0x0040, 0x678: 0x0008, 0x679: 0x0008, 0x67a: 0x0040, 0x67b: 0x0040, + 0x67c: 0x3308, 0x67d: 0x0040, 0x67e: 0x3008, 0x67f: 0x3008, + // Block 0x1a, offset 0x680 + 0x680: 0x3008, 0x681: 0x3308, 0x682: 0x3308, 0x683: 0x0040, 0x684: 0x0040, 0x685: 0x0040, + 0x686: 0x0040, 0x687: 0x3308, 0x688: 0x3308, 0x689: 0x0040, 0x68a: 0x0040, 0x68b: 0x3308, + 0x68c: 0x3308, 0x68d: 0x3b08, 0x68e: 0x0040, 0x68f: 0x0040, 0x690: 0x0040, 0x691: 0x3308, + 0x692: 0x0040, 0x693: 0x0040, 0x694: 0x0040, 0x695: 0x0040, 0x696: 0x0040, 0x697: 0x0040, + 0x698: 0x0040, 0x699: 0x07a1, 0x69a: 0x07d9, 0x69b: 0x0811, 0x69c: 0x0008, 0x69d: 0x0040, + 0x69e: 0x0849, 0x69f: 0x0040, 0x6a0: 0x0040, 0x6a1: 0x0040, 0x6a2: 0x0040, 0x6a3: 0x0040, + 0x6a4: 0x0040, 0x6a5: 0x0040, 0x6a6: 0x0008, 0x6a7: 0x0008, 0x6a8: 0x0008, 0x6a9: 0x0008, + 0x6aa: 0x0008, 0x6ab: 0x0008, 0x6ac: 0x0008, 0x6ad: 0x0008, 0x6ae: 0x0008, 0x6af: 0x0008, + 0x6b0: 0x3308, 0x6b1: 0x3308, 0x6b2: 0x0008, 0x6b3: 0x0008, 0x6b4: 0x0008, 0x6b5: 0x3308, + 0x6b6: 0x0040, 0x6b7: 0x0040, 0x6b8: 0x0040, 0x6b9: 0x0040, 0x6ba: 0x0040, 0x6bb: 0x0040, + 0x6bc: 0x0040, 0x6bd: 0x0040, 0x6be: 0x0040, 0x6bf: 0x0040, + // Block 0x1b, offset 0x6c0 + 0x6c0: 0x0040, 0x6c1: 0x3308, 0x6c2: 0x3308, 0x6c3: 0x3008, 0x6c4: 0x0040, 0x6c5: 0x0008, + 0x6c6: 0x0008, 0x6c7: 0x0008, 0x6c8: 0x0008, 0x6c9: 0x0008, 0x6ca: 0x0008, 0x6cb: 0x0008, + 0x6cc: 0x0008, 0x6cd: 0x0008, 0x6ce: 0x0040, 0x6cf: 0x0008, 0x6d0: 0x0008, 0x6d1: 0x0008, + 0x6d2: 0x0040, 0x6d3: 0x0008, 0x6d4: 0x0008, 0x6d5: 0x0008, 0x6d6: 0x0008, 0x6d7: 0x0008, + 0x6d8: 0x0008, 0x6d9: 0x0008, 0x6da: 0x0008, 0x6db: 0x0008, 0x6dc: 0x0008, 0x6dd: 0x0008, + 0x6de: 0x0008, 0x6df: 0x0008, 0x6e0: 0x0008, 0x6e1: 0x0008, 0x6e2: 0x0008, 0x6e3: 0x0008, + 0x6e4: 0x0008, 0x6e5: 0x0008, 0x6e6: 0x0008, 0x6e7: 0x0008, 0x6e8: 0x0008, 0x6e9: 0x0040, + 0x6ea: 0x0008, 0x6eb: 0x0008, 0x6ec: 0x0008, 0x6ed: 0x0008, 0x6ee: 0x0008, 0x6ef: 0x0008, + 0x6f0: 0x0008, 0x6f1: 0x0040, 0x6f2: 0x0008, 0x6f3: 0x0008, 0x6f4: 0x0040, 0x6f5: 0x0008, + 0x6f6: 0x0008, 0x6f7: 0x0008, 0x6f8: 0x0008, 0x6f9: 0x0008, 0x6fa: 0x0040, 0x6fb: 0x0040, + 0x6fc: 0x3308, 0x6fd: 0x0008, 0x6fe: 0x3008, 0x6ff: 0x3008, + // Block 0x1c, offset 0x700 + 0x700: 0x3008, 0x701: 0x3308, 0x702: 0x3308, 0x703: 0x3308, 0x704: 0x3308, 0x705: 0x3308, + 0x706: 0x0040, 0x707: 0x3308, 0x708: 0x3308, 0x709: 0x3008, 0x70a: 0x0040, 0x70b: 0x3008, + 0x70c: 0x3008, 0x70d: 0x3b08, 0x70e: 0x0040, 0x70f: 0x0040, 0x710: 0x0008, 0x711: 0x0040, + 0x712: 0x0040, 0x713: 0x0040, 0x714: 0x0040, 0x715: 0x0040, 0x716: 0x0040, 0x717: 0x0040, + 0x718: 0x0040, 0x719: 0x0040, 0x71a: 0x0040, 0x71b: 0x0040, 0x71c: 0x0040, 0x71d: 0x0040, + 0x71e: 0x0040, 0x71f: 0x0040, 0x720: 0x0008, 0x721: 0x0008, 0x722: 0x3308, 0x723: 0x3308, + 0x724: 0x0040, 0x725: 0x0040, 0x726: 0x0008, 0x727: 0x0008, 0x728: 0x0008, 0x729: 0x0008, + 0x72a: 0x0008, 0x72b: 0x0008, 0x72c: 0x0008, 0x72d: 0x0008, 0x72e: 0x0008, 0x72f: 0x0008, + 0x730: 0x0018, 0x731: 0x0018, 0x732: 0x0040, 0x733: 0x0040, 0x734: 0x0040, 0x735: 0x0040, + 0x736: 0x0040, 0x737: 0x0040, 0x738: 0x0040, 0x739: 0x0008, 0x73a: 0x3308, 0x73b: 0x3308, + 0x73c: 0x3308, 0x73d: 0x3308, 0x73e: 0x3308, 0x73f: 0x3308, + // Block 0x1d, offset 0x740 + 0x740: 0x0040, 0x741: 0x3308, 0x742: 0x3008, 0x743: 0x3008, 0x744: 0x0040, 0x745: 0x0008, + 0x746: 0x0008, 0x747: 0x0008, 0x748: 0x0008, 0x749: 0x0008, 0x74a: 0x0008, 0x74b: 0x0008, + 0x74c: 0x0008, 0x74d: 0x0040, 0x74e: 0x0040, 0x74f: 0x0008, 0x750: 0x0008, 0x751: 0x0040, + 0x752: 0x0040, 0x753: 0x0008, 0x754: 0x0008, 0x755: 0x0008, 0x756: 0x0008, 0x757: 0x0008, + 0x758: 0x0008, 0x759: 0x0008, 0x75a: 0x0008, 0x75b: 0x0008, 0x75c: 0x0008, 0x75d: 0x0008, + 0x75e: 0x0008, 0x75f: 0x0008, 0x760: 0x0008, 0x761: 0x0008, 0x762: 0x0008, 0x763: 0x0008, + 0x764: 0x0008, 0x765: 0x0008, 0x766: 0x0008, 0x767: 0x0008, 0x768: 0x0008, 0x769: 0x0040, + 0x76a: 0x0008, 0x76b: 0x0008, 0x76c: 0x0008, 0x76d: 0x0008, 0x76e: 0x0008, 0x76f: 0x0008, + 0x770: 0x0008, 0x771: 0x0040, 0x772: 0x0008, 0x773: 0x0008, 0x774: 0x0040, 0x775: 0x0008, + 0x776: 0x0008, 0x777: 0x0008, 0x778: 0x0008, 0x779: 0x0008, 0x77a: 0x0040, 0x77b: 0x0040, + 0x77c: 0x3308, 0x77d: 0x0008, 0x77e: 0x3008, 0x77f: 0x3308, + // Block 0x1e, offset 0x780 + 0x780: 0x3008, 0x781: 0x3308, 0x782: 0x3308, 0x783: 0x3308, 0x784: 0x3308, 0x785: 0x0040, + 0x786: 0x0040, 0x787: 0x3008, 0x788: 0x3008, 0x789: 0x0040, 0x78a: 0x0040, 0x78b: 0x3008, + 0x78c: 0x3008, 0x78d: 0x3b08, 0x78e: 0x0040, 0x78f: 0x0040, 0x790: 0x0040, 0x791: 0x0040, + 0x792: 0x0040, 0x793: 0x0040, 0x794: 0x0040, 0x795: 0x0040, 0x796: 0x3308, 0x797: 0x3008, + 0x798: 0x0040, 0x799: 0x0040, 0x79a: 0x0040, 0x79b: 0x0040, 0x79c: 0x0881, 0x79d: 0x08b9, + 0x79e: 0x0040, 0x79f: 0x0008, 0x7a0: 0x0008, 0x7a1: 0x0008, 0x7a2: 0x3308, 0x7a3: 0x3308, + 0x7a4: 0x0040, 0x7a5: 0x0040, 0x7a6: 0x0008, 0x7a7: 0x0008, 0x7a8: 0x0008, 0x7a9: 0x0008, + 0x7aa: 0x0008, 0x7ab: 0x0008, 0x7ac: 0x0008, 0x7ad: 0x0008, 0x7ae: 0x0008, 0x7af: 0x0008, + 0x7b0: 0x0018, 0x7b1: 0x0008, 0x7b2: 0x0018, 0x7b3: 0x0018, 0x7b4: 0x0018, 0x7b5: 0x0018, + 0x7b6: 0x0018, 0x7b7: 0x0018, 0x7b8: 0x0040, 0x7b9: 0x0040, 0x7ba: 0x0040, 0x7bb: 0x0040, + 0x7bc: 0x0040, 0x7bd: 0x0040, 0x7be: 0x0040, 0x7bf: 0x0040, + // Block 0x1f, offset 0x7c0 + 0x7c0: 0x0040, 0x7c1: 0x0040, 0x7c2: 0x3308, 0x7c3: 0x0008, 0x7c4: 0x0040, 0x7c5: 0x0008, + 0x7c6: 0x0008, 0x7c7: 0x0008, 0x7c8: 0x0008, 0x7c9: 0x0008, 0x7ca: 0x0008, 0x7cb: 0x0040, + 0x7cc: 0x0040, 0x7cd: 0x0040, 0x7ce: 0x0008, 0x7cf: 0x0008, 0x7d0: 0x0008, 0x7d1: 0x0040, + 0x7d2: 0x0008, 0x7d3: 0x0008, 0x7d4: 0x0008, 0x7d5: 0x0008, 0x7d6: 0x0040, 0x7d7: 0x0040, + 0x7d8: 0x0040, 0x7d9: 0x0008, 0x7da: 0x0008, 0x7db: 0x0040, 0x7dc: 0x0008, 0x7dd: 0x0040, + 0x7de: 0x0008, 0x7df: 0x0008, 0x7e0: 0x0040, 0x7e1: 0x0040, 0x7e2: 0x0040, 0x7e3: 0x0008, + 0x7e4: 0x0008, 0x7e5: 0x0040, 0x7e6: 0x0040, 0x7e7: 0x0040, 0x7e8: 0x0008, 0x7e9: 0x0008, + 0x7ea: 0x0008, 0x7eb: 0x0040, 0x7ec: 0x0040, 0x7ed: 0x0040, 0x7ee: 0x0008, 0x7ef: 0x0008, + 0x7f0: 0x0008, 0x7f1: 0x0008, 0x7f2: 0x0008, 0x7f3: 0x0008, 0x7f4: 0x0008, 0x7f5: 0x0008, + 0x7f6: 0x0008, 0x7f7: 0x0008, 0x7f8: 0x0008, 0x7f9: 0x0008, 0x7fa: 0x0040, 0x7fb: 0x0040, + 0x7fc: 0x0040, 0x7fd: 0x0040, 0x7fe: 0x3008, 0x7ff: 0x3008, + // Block 0x20, offset 0x800 + 0x800: 0x3308, 0x801: 0x3008, 0x802: 0x3008, 0x803: 0x3008, 0x804: 0x3008, 0x805: 0x0040, + 0x806: 0x3308, 0x807: 0x3308, 0x808: 0x3308, 0x809: 0x0040, 0x80a: 0x3308, 0x80b: 0x3308, + 0x80c: 0x3308, 0x80d: 0x3b08, 0x80e: 0x0040, 0x80f: 0x0040, 0x810: 0x0040, 0x811: 0x0040, + 0x812: 0x0040, 0x813: 0x0040, 0x814: 0x0040, 0x815: 0x3308, 0x816: 0x3308, 0x817: 0x0040, + 0x818: 0x0008, 0x819: 0x0008, 0x81a: 0x0008, 0x81b: 0x0040, 0x81c: 0x0040, 0x81d: 0x0040, + 0x81e: 0x0040, 0x81f: 0x0040, 0x820: 0x0008, 0x821: 0x0008, 0x822: 0x3308, 0x823: 0x3308, + 0x824: 0x0040, 0x825: 0x0040, 0x826: 0x0008, 0x827: 0x0008, 0x828: 0x0008, 0x829: 0x0008, + 0x82a: 0x0008, 0x82b: 0x0008, 0x82c: 0x0008, 0x82d: 0x0008, 0x82e: 0x0008, 0x82f: 0x0008, + 0x830: 0x0040, 0x831: 0x0040, 0x832: 0x0040, 0x833: 0x0040, 0x834: 0x0040, 0x835: 0x0040, + 0x836: 0x0040, 0x837: 0x0040, 0x838: 0x0018, 0x839: 0x0018, 0x83a: 0x0018, 0x83b: 0x0018, + 0x83c: 0x0018, 0x83d: 0x0018, 0x83e: 0x0018, 0x83f: 0x0018, + // Block 0x21, offset 0x840 + 0x840: 0x0008, 0x841: 0x3308, 0x842: 0x3008, 0x843: 0x3008, 0x844: 0x0040, 0x845: 0x0008, + 0x846: 0x0008, 0x847: 0x0008, 0x848: 0x0008, 0x849: 0x0008, 0x84a: 0x0008, 0x84b: 0x0008, + 0x84c: 0x0008, 0x84d: 0x0040, 0x84e: 0x0008, 0x84f: 0x0008, 0x850: 0x0008, 0x851: 0x0040, + 0x852: 0x0008, 0x853: 0x0008, 0x854: 0x0008, 0x855: 0x0008, 0x856: 0x0008, 0x857: 0x0008, + 0x858: 0x0008, 0x859: 0x0008, 0x85a: 0x0008, 0x85b: 0x0008, 0x85c: 0x0008, 0x85d: 0x0008, + 0x85e: 0x0008, 0x85f: 0x0008, 0x860: 0x0008, 0x861: 0x0008, 0x862: 0x0008, 0x863: 0x0008, + 0x864: 0x0008, 0x865: 0x0008, 0x866: 0x0008, 0x867: 0x0008, 0x868: 0x0008, 0x869: 0x0040, + 0x86a: 0x0008, 0x86b: 0x0008, 0x86c: 0x0008, 0x86d: 0x0008, 0x86e: 0x0008, 0x86f: 0x0008, + 0x870: 0x0008, 0x871: 0x0008, 0x872: 0x0008, 0x873: 0x0008, 0x874: 0x0040, 0x875: 0x0008, + 0x876: 0x0008, 0x877: 0x0008, 0x878: 0x0008, 0x879: 0x0008, 0x87a: 0x0040, 0x87b: 0x0040, + 0x87c: 0x3308, 0x87d: 0x0008, 0x87e: 0x3008, 0x87f: 0x3308, + // Block 0x22, offset 0x880 + 0x880: 0x3008, 0x881: 0x3008, 0x882: 0x3008, 0x883: 0x3008, 0x884: 0x3008, 0x885: 0x0040, + 0x886: 0x3308, 0x887: 0x3008, 0x888: 0x3008, 0x889: 0x0040, 0x88a: 0x3008, 0x88b: 0x3008, + 0x88c: 0x3308, 0x88d: 0x3b08, 0x88e: 0x0040, 0x88f: 0x0040, 0x890: 0x0040, 0x891: 0x0040, + 0x892: 0x0040, 0x893: 0x0040, 0x894: 0x0040, 0x895: 0x3008, 0x896: 0x3008, 0x897: 0x0040, + 0x898: 0x0040, 0x899: 0x0040, 0x89a: 0x0040, 0x89b: 0x0040, 0x89c: 0x0040, 0x89d: 0x0040, + 0x89e: 0x0008, 0x89f: 0x0040, 0x8a0: 0x0008, 0x8a1: 0x0008, 0x8a2: 0x3308, 0x8a3: 0x3308, + 0x8a4: 0x0040, 0x8a5: 0x0040, 0x8a6: 0x0008, 0x8a7: 0x0008, 0x8a8: 0x0008, 0x8a9: 0x0008, + 0x8aa: 0x0008, 0x8ab: 0x0008, 0x8ac: 0x0008, 0x8ad: 0x0008, 0x8ae: 0x0008, 0x8af: 0x0008, + 0x8b0: 0x0040, 0x8b1: 0x0008, 0x8b2: 0x0008, 0x8b3: 0x0040, 0x8b4: 0x0040, 0x8b5: 0x0040, + 0x8b6: 0x0040, 0x8b7: 0x0040, 0x8b8: 0x0040, 0x8b9: 0x0040, 0x8ba: 0x0040, 0x8bb: 0x0040, + 0x8bc: 0x0040, 0x8bd: 0x0040, 0x8be: 0x0040, 0x8bf: 0x0040, + // Block 0x23, offset 0x8c0 + 0x8c0: 0x3008, 0x8c1: 0x3308, 0x8c2: 0x3308, 0x8c3: 0x3308, 0x8c4: 0x3308, 0x8c5: 0x0040, + 0x8c6: 0x3008, 0x8c7: 0x3008, 0x8c8: 0x3008, 0x8c9: 0x0040, 0x8ca: 0x3008, 0x8cb: 0x3008, + 0x8cc: 0x3008, 0x8cd: 0x3b08, 0x8ce: 0x0008, 0x8cf: 0x0018, 0x8d0: 0x0040, 0x8d1: 0x0040, + 0x8d2: 0x0040, 0x8d3: 0x0040, 0x8d4: 0x0008, 0x8d5: 0x0008, 0x8d6: 0x0008, 0x8d7: 0x3008, + 0x8d8: 0x0018, 0x8d9: 0x0018, 0x8da: 0x0018, 0x8db: 0x0018, 0x8dc: 0x0018, 0x8dd: 0x0018, + 0x8de: 0x0018, 0x8df: 0x0008, 0x8e0: 0x0008, 0x8e1: 0x0008, 0x8e2: 0x3308, 0x8e3: 0x3308, + 0x8e4: 0x0040, 0x8e5: 0x0040, 0x8e6: 0x0008, 0x8e7: 0x0008, 0x8e8: 0x0008, 0x8e9: 0x0008, + 0x8ea: 0x0008, 0x8eb: 0x0008, 0x8ec: 0x0008, 0x8ed: 0x0008, 0x8ee: 0x0008, 0x8ef: 0x0008, + 0x8f0: 0x0018, 0x8f1: 0x0018, 0x8f2: 0x0018, 0x8f3: 0x0018, 0x8f4: 0x0018, 0x8f5: 0x0018, + 0x8f6: 0x0018, 0x8f7: 0x0018, 0x8f8: 0x0018, 0x8f9: 0x0018, 0x8fa: 0x0008, 0x8fb: 0x0008, + 0x8fc: 0x0008, 0x8fd: 0x0008, 0x8fe: 0x0008, 0x8ff: 0x0008, + // Block 0x24, offset 0x900 + 0x900: 0x0040, 0x901: 0x0008, 0x902: 0x0008, 0x903: 0x0040, 0x904: 0x0008, 0x905: 0x0040, + 0x906: 0x0040, 0x907: 0x0008, 0x908: 0x0008, 0x909: 0x0040, 0x90a: 0x0008, 0x90b: 0x0040, + 0x90c: 0x0040, 0x90d: 0x0008, 0x90e: 0x0040, 0x90f: 0x0040, 0x910: 0x0040, 0x911: 0x0040, + 0x912: 0x0040, 0x913: 0x0040, 0x914: 0x0008, 0x915: 0x0008, 0x916: 0x0008, 0x917: 0x0008, + 0x918: 0x0040, 0x919: 0x0008, 0x91a: 0x0008, 0x91b: 0x0008, 0x91c: 0x0008, 0x91d: 0x0008, + 0x91e: 0x0008, 0x91f: 0x0008, 0x920: 0x0040, 0x921: 0x0008, 0x922: 0x0008, 0x923: 0x0008, + 0x924: 0x0040, 0x925: 0x0008, 0x926: 0x0040, 0x927: 0x0008, 0x928: 0x0040, 0x929: 0x0040, + 0x92a: 0x0008, 0x92b: 0x0008, 0x92c: 0x0040, 0x92d: 0x0008, 0x92e: 0x0008, 0x92f: 0x0008, + 0x930: 0x0008, 0x931: 0x3308, 0x932: 0x0008, 0x933: 0x0929, 0x934: 0x3308, 0x935: 0x3308, + 0x936: 0x3308, 0x937: 0x3308, 0x938: 0x3308, 0x939: 0x3308, 0x93a: 0x0040, 0x93b: 0x3308, + 0x93c: 0x3308, 0x93d: 0x0008, 0x93e: 0x0040, 0x93f: 0x0040, + // Block 0x25, offset 0x940 + 0x940: 0x0008, 0x941: 0x0008, 0x942: 0x0008, 0x943: 0x09d1, 0x944: 0x0008, 0x945: 0x0008, + 0x946: 0x0008, 0x947: 0x0008, 0x948: 0x0040, 0x949: 0x0008, 0x94a: 0x0008, 0x94b: 0x0008, + 0x94c: 0x0008, 0x94d: 0x0a09, 0x94e: 0x0008, 0x94f: 0x0008, 0x950: 0x0008, 0x951: 0x0008, + 0x952: 0x0a41, 0x953: 0x0008, 0x954: 0x0008, 0x955: 0x0008, 0x956: 0x0008, 0x957: 0x0a79, + 0x958: 0x0008, 0x959: 0x0008, 0x95a: 0x0008, 0x95b: 0x0008, 0x95c: 0x0ab1, 0x95d: 0x0008, + 0x95e: 0x0008, 0x95f: 0x0008, 0x960: 0x0008, 0x961: 0x0008, 0x962: 0x0008, 0x963: 0x0008, + 0x964: 0x0008, 0x965: 0x0008, 0x966: 0x0008, 0x967: 0x0008, 0x968: 0x0008, 0x969: 0x0ae9, + 0x96a: 0x0008, 0x96b: 0x0008, 0x96c: 0x0008, 0x96d: 0x0040, 0x96e: 0x0040, 0x96f: 0x0040, + 0x970: 0x0040, 0x971: 0x3308, 0x972: 0x3308, 0x973: 0x0b21, 0x974: 0x3308, 0x975: 0x0b59, + 0x976: 0x0b91, 0x977: 0x0bc9, 0x978: 0x0c19, 0x979: 0x0c51, 0x97a: 0x3308, 0x97b: 0x3308, + 0x97c: 0x3308, 0x97d: 0x3308, 0x97e: 0x3308, 0x97f: 0x3008, + // Block 0x26, offset 0x980 + 0x980: 0x3308, 0x981: 0x0ca1, 0x982: 0x3308, 0x983: 0x3308, 0x984: 0x3b08, 0x985: 0x0018, + 0x986: 0x3308, 0x987: 0x3308, 0x988: 0x0008, 0x989: 0x0008, 0x98a: 0x0008, 0x98b: 0x0008, + 0x98c: 0x0008, 0x98d: 0x3308, 0x98e: 0x3308, 0x98f: 0x3308, 0x990: 0x3308, 0x991: 0x3308, + 0x992: 0x3308, 0x993: 0x0cd9, 0x994: 0x3308, 0x995: 0x3308, 0x996: 0x3308, 0x997: 0x3308, + 0x998: 0x0040, 0x999: 0x3308, 0x99a: 0x3308, 0x99b: 0x3308, 0x99c: 0x3308, 0x99d: 0x0d11, + 0x99e: 0x3308, 0x99f: 0x3308, 0x9a0: 0x3308, 0x9a1: 0x3308, 0x9a2: 0x0d49, 0x9a3: 0x3308, + 0x9a4: 0x3308, 0x9a5: 0x3308, 0x9a6: 0x3308, 0x9a7: 0x0d81, 0x9a8: 0x3308, 0x9a9: 0x3308, + 0x9aa: 0x3308, 0x9ab: 0x3308, 0x9ac: 0x0db9, 0x9ad: 0x3308, 0x9ae: 0x3308, 0x9af: 0x3308, + 0x9b0: 0x3308, 0x9b1: 0x3308, 0x9b2: 0x3308, 0x9b3: 0x3308, 0x9b4: 0x3308, 0x9b5: 0x3308, + 0x9b6: 0x3308, 0x9b7: 0x3308, 0x9b8: 0x3308, 0x9b9: 0x0df1, 0x9ba: 0x3308, 0x9bb: 0x3308, + 0x9bc: 0x3308, 0x9bd: 0x0040, 0x9be: 0x0018, 0x9bf: 0x0018, + // Block 0x27, offset 0x9c0 + 0x9c0: 0x0008, 0x9c1: 0x0008, 0x9c2: 0x0008, 0x9c3: 0x0008, 0x9c4: 0x0008, 0x9c5: 0x0008, + 0x9c6: 0x0008, 0x9c7: 0x0008, 0x9c8: 0x0008, 0x9c9: 0x0008, 0x9ca: 0x0008, 0x9cb: 0x0008, + 0x9cc: 0x0008, 0x9cd: 0x0008, 0x9ce: 0x0008, 0x9cf: 0x0008, 0x9d0: 0x0008, 0x9d1: 0x0008, + 0x9d2: 0x0008, 0x9d3: 0x0008, 0x9d4: 0x0008, 0x9d5: 0x0008, 0x9d6: 0x0008, 0x9d7: 0x0008, + 0x9d8: 0x0008, 0x9d9: 0x0008, 0x9da: 0x0008, 0x9db: 0x0008, 0x9dc: 0x0008, 0x9dd: 0x0008, + 0x9de: 0x0008, 0x9df: 0x0008, 0x9e0: 0x0008, 0x9e1: 0x0008, 0x9e2: 0x0008, 0x9e3: 0x0008, + 0x9e4: 0x0008, 0x9e5: 0x0008, 0x9e6: 0x0008, 0x9e7: 0x0008, 0x9e8: 0x0008, 0x9e9: 0x0008, + 0x9ea: 0x0008, 0x9eb: 0x0008, 0x9ec: 0x0039, 0x9ed: 0x0ed1, 0x9ee: 0x0ee9, 0x9ef: 0x0008, + 0x9f0: 0x0ef9, 0x9f1: 0x0f09, 0x9f2: 0x0f19, 0x9f3: 0x0f31, 0x9f4: 0x0249, 0x9f5: 0x0f41, + 0x9f6: 0x0259, 0x9f7: 0x0f51, 0x9f8: 0x0359, 0x9f9: 0x0f61, 0x9fa: 0x0f71, 0x9fb: 0x0008, + 0x9fc: 0x00d9, 0x9fd: 0x0f81, 0x9fe: 0x0f99, 0x9ff: 0x0269, + // Block 0x28, offset 0xa00 + 0xa00: 0x0fa9, 0xa01: 0x0fb9, 0xa02: 0x0279, 0xa03: 0x0039, 0xa04: 0x0fc9, 0xa05: 0x0fe1, + 0xa06: 0x059d, 0xa07: 0x0ee9, 0xa08: 0x0ef9, 0xa09: 0x0f09, 0xa0a: 0x0ff9, 0xa0b: 0x1011, + 0xa0c: 0x1029, 0xa0d: 0x0f31, 0xa0e: 0x0008, 0xa0f: 0x0f51, 0xa10: 0x0f61, 0xa11: 0x1041, + 0xa12: 0x00d9, 0xa13: 0x1059, 0xa14: 0x05b5, 0xa15: 0x05b5, 0xa16: 0x0f99, 0xa17: 0x0fa9, + 0xa18: 0x0fb9, 0xa19: 0x059d, 0xa1a: 0x1071, 0xa1b: 0x1089, 0xa1c: 0x05cd, 0xa1d: 0x1099, + 0xa1e: 0x10b1, 0xa1f: 0x10c9, 0xa20: 0x10e1, 0xa21: 0x10f9, 0xa22: 0x0f41, 0xa23: 0x0269, + 0xa24: 0x0fb9, 0xa25: 0x1089, 0xa26: 0x1099, 0xa27: 0x10b1, 0xa28: 0x1111, 0xa29: 0x10e1, + 0xa2a: 0x10f9, 0xa2b: 0x0008, 0xa2c: 0x0008, 0xa2d: 0x0008, 0xa2e: 0x0008, 0xa2f: 0x0008, + 0xa30: 0x0008, 0xa31: 0x0008, 0xa32: 0x0008, 0xa33: 0x0008, 0xa34: 0x0008, 0xa35: 0x0008, + 0xa36: 0x0008, 0xa37: 0x0008, 0xa38: 0x1129, 0xa39: 0x0008, 0xa3a: 0x0008, 0xa3b: 0x0008, + 0xa3c: 0x0008, 0xa3d: 0x0008, 0xa3e: 0x0008, 0xa3f: 0x0008, + // Block 0x29, offset 0xa40 + 0xa40: 0x0008, 0xa41: 0x0008, 0xa42: 0x0008, 0xa43: 0x0008, 0xa44: 0x0008, 0xa45: 0x0008, + 0xa46: 0x0008, 0xa47: 0x0008, 0xa48: 0x0008, 0xa49: 0x0008, 0xa4a: 0x0008, 0xa4b: 0x0008, + 0xa4c: 0x0008, 0xa4d: 0x0008, 0xa4e: 0x0008, 0xa4f: 0x0008, 0xa50: 0x0008, 0xa51: 0x0008, + 0xa52: 0x0008, 0xa53: 0x0008, 0xa54: 0x0008, 0xa55: 0x0008, 0xa56: 0x0008, 0xa57: 0x0008, + 0xa58: 0x0008, 0xa59: 0x0008, 0xa5a: 0x0008, 0xa5b: 0x1141, 0xa5c: 0x1159, 0xa5d: 0x1169, + 0xa5e: 0x1181, 0xa5f: 0x1029, 0xa60: 0x1199, 0xa61: 0x11a9, 0xa62: 0x11c1, 0xa63: 0x11d9, + 0xa64: 0x11f1, 0xa65: 0x1209, 0xa66: 0x1221, 0xa67: 0x05e5, 0xa68: 0x1239, 0xa69: 0x1251, + 0xa6a: 0xe17d, 0xa6b: 0x1269, 0xa6c: 0x1281, 0xa6d: 0x1299, 0xa6e: 0x12b1, 0xa6f: 0x12c9, + 0xa70: 0x12e1, 0xa71: 0x12f9, 0xa72: 0x1311, 0xa73: 0x1329, 0xa74: 0x1341, 0xa75: 0x1359, + 0xa76: 0x1371, 0xa77: 0x1389, 0xa78: 0x05fd, 0xa79: 0x13a1, 0xa7a: 0x13b9, 0xa7b: 0x13d1, + 0xa7c: 0x13e1, 0xa7d: 0x13f9, 0xa7e: 0x1411, 0xa7f: 0x1429, + // Block 0x2a, offset 0xa80 + 0xa80: 0xe00d, 0xa81: 0x0008, 0xa82: 0xe00d, 0xa83: 0x0008, 0xa84: 0xe00d, 0xa85: 0x0008, + 0xa86: 0xe00d, 0xa87: 0x0008, 0xa88: 0xe00d, 0xa89: 0x0008, 0xa8a: 0xe00d, 0xa8b: 0x0008, + 0xa8c: 0xe00d, 0xa8d: 0x0008, 0xa8e: 0xe00d, 0xa8f: 0x0008, 0xa90: 0xe00d, 0xa91: 0x0008, + 0xa92: 0xe00d, 0xa93: 0x0008, 0xa94: 0xe00d, 0xa95: 0x0008, 0xa96: 0xe00d, 0xa97: 0x0008, + 0xa98: 0xe00d, 0xa99: 0x0008, 0xa9a: 0xe00d, 0xa9b: 0x0008, 0xa9c: 0xe00d, 0xa9d: 0x0008, + 0xa9e: 0xe00d, 0xa9f: 0x0008, 0xaa0: 0xe00d, 0xaa1: 0x0008, 0xaa2: 0xe00d, 0xaa3: 0x0008, + 0xaa4: 0xe00d, 0xaa5: 0x0008, 0xaa6: 0xe00d, 0xaa7: 0x0008, 0xaa8: 0xe00d, 0xaa9: 0x0008, + 0xaaa: 0xe00d, 0xaab: 0x0008, 0xaac: 0xe00d, 0xaad: 0x0008, 0xaae: 0xe00d, 0xaaf: 0x0008, + 0xab0: 0xe00d, 0xab1: 0x0008, 0xab2: 0xe00d, 0xab3: 0x0008, 0xab4: 0xe00d, 0xab5: 0x0008, + 0xab6: 0xe00d, 0xab7: 0x0008, 0xab8: 0xe00d, 0xab9: 0x0008, 0xaba: 0xe00d, 0xabb: 0x0008, + 0xabc: 0xe00d, 0xabd: 0x0008, 0xabe: 0xe00d, 0xabf: 0x0008, + // Block 0x2b, offset 0xac0 + 0xac0: 0xe00d, 0xac1: 0x0008, 0xac2: 0xe00d, 0xac3: 0x0008, 0xac4: 0xe00d, 0xac5: 0x0008, + 0xac6: 0xe00d, 0xac7: 0x0008, 0xac8: 0xe00d, 0xac9: 0x0008, 0xaca: 0xe00d, 0xacb: 0x0008, + 0xacc: 0xe00d, 0xacd: 0x0008, 0xace: 0xe00d, 0xacf: 0x0008, 0xad0: 0xe00d, 0xad1: 0x0008, + 0xad2: 0xe00d, 0xad3: 0x0008, 0xad4: 0xe00d, 0xad5: 0x0008, 0xad6: 0x0008, 0xad7: 0x0008, + 0xad8: 0x0008, 0xad9: 0x0008, 0xada: 0x0615, 0xadb: 0x0635, 0xadc: 0x0008, 0xadd: 0x0008, + 0xade: 0x1441, 0xadf: 0x0008, 0xae0: 0xe00d, 0xae1: 0x0008, 0xae2: 0xe00d, 0xae3: 0x0008, + 0xae4: 0xe00d, 0xae5: 0x0008, 0xae6: 0xe00d, 0xae7: 0x0008, 0xae8: 0xe00d, 0xae9: 0x0008, + 0xaea: 0xe00d, 0xaeb: 0x0008, 0xaec: 0xe00d, 0xaed: 0x0008, 0xaee: 0xe00d, 0xaef: 0x0008, + 0xaf0: 0xe00d, 0xaf1: 0x0008, 0xaf2: 0xe00d, 0xaf3: 0x0008, 0xaf4: 0xe00d, 0xaf5: 0x0008, + 0xaf6: 0xe00d, 0xaf7: 0x0008, 0xaf8: 0xe00d, 0xaf9: 0x0008, 0xafa: 0xe00d, 0xafb: 0x0008, + 0xafc: 0xe00d, 0xafd: 0x0008, 0xafe: 0xe00d, 0xaff: 0x0008, + // Block 0x2c, offset 0xb00 + 0xb00: 0x0008, 0xb01: 0x0008, 0xb02: 0x0008, 0xb03: 0x0008, 0xb04: 0x0008, 0xb05: 0x0008, + 0xb06: 0x0040, 0xb07: 0x0040, 0xb08: 0xe045, 0xb09: 0xe045, 0xb0a: 0xe045, 0xb0b: 0xe045, + 0xb0c: 0xe045, 0xb0d: 0xe045, 0xb0e: 0x0040, 0xb0f: 0x0040, 0xb10: 0x0008, 0xb11: 0x0008, + 0xb12: 0x0008, 0xb13: 0x0008, 0xb14: 0x0008, 0xb15: 0x0008, 0xb16: 0x0008, 0xb17: 0x0008, + 0xb18: 0x0040, 0xb19: 0xe045, 0xb1a: 0x0040, 0xb1b: 0xe045, 0xb1c: 0x0040, 0xb1d: 0xe045, + 0xb1e: 0x0040, 0xb1f: 0xe045, 0xb20: 0x0008, 0xb21: 0x0008, 0xb22: 0x0008, 0xb23: 0x0008, + 0xb24: 0x0008, 0xb25: 0x0008, 0xb26: 0x0008, 0xb27: 0x0008, 0xb28: 0xe045, 0xb29: 0xe045, + 0xb2a: 0xe045, 0xb2b: 0xe045, 0xb2c: 0xe045, 0xb2d: 0xe045, 0xb2e: 0xe045, 0xb2f: 0xe045, + 0xb30: 0x0008, 0xb31: 0x1459, 0xb32: 0x0008, 0xb33: 0x1471, 0xb34: 0x0008, 0xb35: 0x1489, + 0xb36: 0x0008, 0xb37: 0x14a1, 0xb38: 0x0008, 0xb39: 0x14b9, 0xb3a: 0x0008, 0xb3b: 0x14d1, + 0xb3c: 0x0008, 0xb3d: 0x14e9, 0xb3e: 0x0040, 0xb3f: 0x0040, + // Block 0x2d, offset 0xb40 + 0xb40: 0x1501, 0xb41: 0x1531, 0xb42: 0x1561, 0xb43: 0x1591, 0xb44: 0x15c1, 0xb45: 0x15f1, + 0xb46: 0x1621, 0xb47: 0x1651, 0xb48: 0x1501, 0xb49: 0x1531, 0xb4a: 0x1561, 0xb4b: 0x1591, + 0xb4c: 0x15c1, 0xb4d: 0x15f1, 0xb4e: 0x1621, 0xb4f: 0x1651, 0xb50: 0x1681, 0xb51: 0x16b1, + 0xb52: 0x16e1, 0xb53: 0x1711, 0xb54: 0x1741, 0xb55: 0x1771, 0xb56: 0x17a1, 0xb57: 0x17d1, + 0xb58: 0x1681, 0xb59: 0x16b1, 0xb5a: 0x16e1, 0xb5b: 0x1711, 0xb5c: 0x1741, 0xb5d: 0x1771, + 0xb5e: 0x17a1, 0xb5f: 0x17d1, 0xb60: 0x1801, 0xb61: 0x1831, 0xb62: 0x1861, 0xb63: 0x1891, + 0xb64: 0x18c1, 0xb65: 0x18f1, 0xb66: 0x1921, 0xb67: 0x1951, 0xb68: 0x1801, 0xb69: 0x1831, + 0xb6a: 0x1861, 0xb6b: 0x1891, 0xb6c: 0x18c1, 0xb6d: 0x18f1, 0xb6e: 0x1921, 0xb6f: 0x1951, + 0xb70: 0x0008, 0xb71: 0x0008, 0xb72: 0x1981, 0xb73: 0x19b1, 0xb74: 0x19d9, 0xb75: 0x0040, + 0xb76: 0x0008, 0xb77: 0x1a01, 0xb78: 0xe045, 0xb79: 0xe045, 0xb7a: 0x064d, 0xb7b: 0x1459, + 0xb7c: 0x19b1, 0xb7d: 0x0666, 0xb7e: 0x1a31, 0xb7f: 0x0686, + // Block 0x2e, offset 0xb80 + 0xb80: 0x06a6, 0xb81: 0x1a4a, 0xb82: 0x1a79, 0xb83: 0x1aa9, 0xb84: 0x1ad1, 0xb85: 0x0040, + 0xb86: 0x0008, 0xb87: 0x1af9, 0xb88: 0x06c5, 0xb89: 0x1471, 0xb8a: 0x06dd, 0xb8b: 0x1489, + 0xb8c: 0x1aa9, 0xb8d: 0x1b2a, 0xb8e: 0x1b5a, 0xb8f: 0x1b8a, 0xb90: 0x0008, 0xb91: 0x0008, + 0xb92: 0x0008, 0xb93: 0x1bb9, 0xb94: 0x0040, 0xb95: 0x0040, 0xb96: 0x0008, 0xb97: 0x0008, + 0xb98: 0xe045, 0xb99: 0xe045, 0xb9a: 0x06f5, 0xb9b: 0x14a1, 0xb9c: 0x0040, 0xb9d: 0x1bd2, + 0xb9e: 0x1c02, 0xb9f: 0x1c32, 0xba0: 0x0008, 0xba1: 0x0008, 0xba2: 0x0008, 0xba3: 0x1c61, + 0xba4: 0x0008, 0xba5: 0x0008, 0xba6: 0x0008, 0xba7: 0x0008, 0xba8: 0xe045, 0xba9: 0xe045, + 0xbaa: 0x070d, 0xbab: 0x14d1, 0xbac: 0xe04d, 0xbad: 0x1c7a, 0xbae: 0x03d2, 0xbaf: 0x1caa, + 0xbb0: 0x0040, 0xbb1: 0x0040, 0xbb2: 0x1cb9, 0xbb3: 0x1ce9, 0xbb4: 0x1d11, 0xbb5: 0x0040, + 0xbb6: 0x0008, 0xbb7: 0x1d39, 0xbb8: 0x0725, 0xbb9: 0x14b9, 0xbba: 0x0515, 0xbbb: 0x14e9, + 0xbbc: 0x1ce9, 0xbbd: 0x073e, 0xbbe: 0x075e, 0xbbf: 0x0040, + // Block 0x2f, offset 0xbc0 + 0xbc0: 0x000a, 0xbc1: 0x000a, 0xbc2: 0x000a, 0xbc3: 0x000a, 0xbc4: 0x000a, 0xbc5: 0x000a, + 0xbc6: 0x000a, 0xbc7: 0x000a, 0xbc8: 0x000a, 0xbc9: 0x000a, 0xbca: 0x000a, 0xbcb: 0x03c0, + 0xbcc: 0x0003, 0xbcd: 0x0003, 0xbce: 0x0340, 0xbcf: 0x0b40, 0xbd0: 0x0018, 0xbd1: 0xe00d, + 0xbd2: 0x0018, 0xbd3: 0x0018, 0xbd4: 0x0018, 0xbd5: 0x0018, 0xbd6: 0x0018, 0xbd7: 0x077e, + 0xbd8: 0x0018, 0xbd9: 0x0018, 0xbda: 0x0018, 0xbdb: 0x0018, 0xbdc: 0x0018, 0xbdd: 0x0018, + 0xbde: 0x0018, 0xbdf: 0x0018, 0xbe0: 0x0018, 0xbe1: 0x0018, 0xbe2: 0x0018, 0xbe3: 0x0018, + 0xbe4: 0x0040, 0xbe5: 0x0040, 0xbe6: 0x0040, 0xbe7: 0x0018, 0xbe8: 0x0040, 0xbe9: 0x0040, + 0xbea: 0x0340, 0xbeb: 0x0340, 0xbec: 0x0340, 0xbed: 0x0340, 0xbee: 0x0340, 0xbef: 0x000a, + 0xbf0: 0x0018, 0xbf1: 0x0018, 0xbf2: 0x0018, 0xbf3: 0x1d69, 0xbf4: 0x1da1, 0xbf5: 0x0018, + 0xbf6: 0x1df1, 0xbf7: 0x1e29, 0xbf8: 0x0018, 0xbf9: 0x0018, 0xbfa: 0x0018, 0xbfb: 0x0018, + 0xbfc: 0x1e7a, 0xbfd: 0x0018, 0xbfe: 0x079e, 0xbff: 0x0018, + // Block 0x30, offset 0xc00 + 0xc00: 0x0018, 0xc01: 0x0018, 0xc02: 0x0018, 0xc03: 0x0018, 0xc04: 0x0018, 0xc05: 0x0018, + 0xc06: 0x0018, 0xc07: 0x1e92, 0xc08: 0x1eaa, 0xc09: 0x1ec2, 0xc0a: 0x0018, 0xc0b: 0x0018, + 0xc0c: 0x0018, 0xc0d: 0x0018, 0xc0e: 0x0018, 0xc0f: 0x0018, 0xc10: 0x0018, 0xc11: 0x0018, + 0xc12: 0x0018, 0xc13: 0x0018, 0xc14: 0x0018, 0xc15: 0x0018, 0xc16: 0x0018, 0xc17: 0x1ed9, + 0xc18: 0x0018, 0xc19: 0x0018, 0xc1a: 0x0018, 0xc1b: 0x0018, 0xc1c: 0x0018, 0xc1d: 0x0018, + 0xc1e: 0x0018, 0xc1f: 0x000a, 0xc20: 0x03c0, 0xc21: 0x0340, 0xc22: 0x0340, 0xc23: 0x0340, + 0xc24: 0x03c0, 0xc25: 0x0040, 0xc26: 0x0040, 0xc27: 0x0040, 0xc28: 0x0040, 0xc29: 0x0040, + 0xc2a: 0x0340, 0xc2b: 0x0340, 0xc2c: 0x0340, 0xc2d: 0x0340, 0xc2e: 0x0340, 0xc2f: 0x0340, + 0xc30: 0x1f41, 0xc31: 0x0f41, 0xc32: 0x0040, 0xc33: 0x0040, 0xc34: 0x1f51, 0xc35: 0x1f61, + 0xc36: 0x1f71, 0xc37: 0x1f81, 0xc38: 0x1f91, 0xc39: 0x1fa1, 0xc3a: 0x1fb2, 0xc3b: 0x07bd, + 0xc3c: 0x1fc2, 0xc3d: 0x1fd2, 0xc3e: 0x1fe2, 0xc3f: 0x0f71, + // Block 0x31, offset 0xc40 + 0xc40: 0x1f41, 0xc41: 0x00c9, 0xc42: 0x0069, 0xc43: 0x0079, 0xc44: 0x1f51, 0xc45: 0x1f61, + 0xc46: 0x1f71, 0xc47: 0x1f81, 0xc48: 0x1f91, 0xc49: 0x1fa1, 0xc4a: 0x1fb2, 0xc4b: 0x07d5, + 0xc4c: 0x1fc2, 0xc4d: 0x1fd2, 0xc4e: 0x1fe2, 0xc4f: 0x0040, 0xc50: 0x0039, 0xc51: 0x0f09, + 0xc52: 0x00d9, 0xc53: 0x0369, 0xc54: 0x0ff9, 0xc55: 0x0249, 0xc56: 0x0f51, 0xc57: 0x0359, + 0xc58: 0x0f61, 0xc59: 0x0f71, 0xc5a: 0x0f99, 0xc5b: 0x01d9, 0xc5c: 0x0fa9, 0xc5d: 0x0040, + 0xc5e: 0x0040, 0xc5f: 0x0040, 0xc60: 0x0018, 0xc61: 0x0018, 0xc62: 0x0018, 0xc63: 0x0018, + 0xc64: 0x0018, 0xc65: 0x0018, 0xc66: 0x0018, 0xc67: 0x0018, 0xc68: 0x1ff1, 0xc69: 0x0018, + 0xc6a: 0x0018, 0xc6b: 0x0018, 0xc6c: 0x0018, 0xc6d: 0x0018, 0xc6e: 0x0018, 0xc6f: 0x0018, + 0xc70: 0x0018, 0xc71: 0x0018, 0xc72: 0x0018, 0xc73: 0x0018, 0xc74: 0x0018, 0xc75: 0x0018, + 0xc76: 0x0018, 0xc77: 0x0018, 0xc78: 0x0018, 0xc79: 0x0018, 0xc7a: 0x0018, 0xc7b: 0x0018, + 0xc7c: 0x0018, 0xc7d: 0x0018, 0xc7e: 0x0018, 0xc7f: 0x0018, + // Block 0x32, offset 0xc80 + 0xc80: 0x07ee, 0xc81: 0x080e, 0xc82: 0x1159, 0xc83: 0x082d, 0xc84: 0x0018, 0xc85: 0x084e, + 0xc86: 0x086e, 0xc87: 0x1011, 0xc88: 0x0018, 0xc89: 0x088d, 0xc8a: 0x0f31, 0xc8b: 0x0249, + 0xc8c: 0x0249, 0xc8d: 0x0249, 0xc8e: 0x0249, 0xc8f: 0x2009, 0xc90: 0x0f41, 0xc91: 0x0f41, + 0xc92: 0x0359, 0xc93: 0x0359, 0xc94: 0x0018, 0xc95: 0x0f71, 0xc96: 0x2021, 0xc97: 0x0018, + 0xc98: 0x0018, 0xc99: 0x0f99, 0xc9a: 0x2039, 0xc9b: 0x0269, 0xc9c: 0x0269, 0xc9d: 0x0269, + 0xc9e: 0x0018, 0xc9f: 0x0018, 0xca0: 0x2049, 0xca1: 0x08ad, 0xca2: 0x2061, 0xca3: 0x0018, + 0xca4: 0x13d1, 0xca5: 0x0018, 0xca6: 0x2079, 0xca7: 0x0018, 0xca8: 0x13d1, 0xca9: 0x0018, + 0xcaa: 0x0f51, 0xcab: 0x2091, 0xcac: 0x0ee9, 0xcad: 0x1159, 0xcae: 0x0018, 0xcaf: 0x0f09, + 0xcb0: 0x0f09, 0xcb1: 0x1199, 0xcb2: 0x0040, 0xcb3: 0x0f61, 0xcb4: 0x00d9, 0xcb5: 0x20a9, + 0xcb6: 0x20c1, 0xcb7: 0x20d9, 0xcb8: 0x20f1, 0xcb9: 0x0f41, 0xcba: 0x0018, 0xcbb: 0x08cd, + 0xcbc: 0x2109, 0xcbd: 0x10b1, 0xcbe: 0x10b1, 0xcbf: 0x2109, + // Block 0x33, offset 0xcc0 + 0xcc0: 0x08ed, 0xcc1: 0x0018, 0xcc2: 0x0018, 0xcc3: 0x0018, 0xcc4: 0x0018, 0xcc5: 0x0ef9, + 0xcc6: 0x0ef9, 0xcc7: 0x0f09, 0xcc8: 0x0f41, 0xcc9: 0x0259, 0xcca: 0x0018, 0xccb: 0x0018, + 0xccc: 0x0018, 0xccd: 0x0018, 0xcce: 0x0008, 0xccf: 0x0018, 0xcd0: 0x2121, 0xcd1: 0x2151, + 0xcd2: 0x2181, 0xcd3: 0x21b9, 0xcd4: 0x21e9, 0xcd5: 0x2219, 0xcd6: 0x2249, 0xcd7: 0x2279, + 0xcd8: 0x22a9, 0xcd9: 0x22d9, 0xcda: 0x2309, 0xcdb: 0x2339, 0xcdc: 0x2369, 0xcdd: 0x2399, + 0xcde: 0x23c9, 0xcdf: 0x23f9, 0xce0: 0x0f41, 0xce1: 0x2421, 0xce2: 0x0905, 0xce3: 0x2439, + 0xce4: 0x1089, 0xce5: 0x2451, 0xce6: 0x0925, 0xce7: 0x2469, 0xce8: 0x2491, 0xce9: 0x0369, + 0xcea: 0x24a9, 0xceb: 0x0945, 0xcec: 0x0359, 0xced: 0x1159, 0xcee: 0x0ef9, 0xcef: 0x0f61, + 0xcf0: 0x0f41, 0xcf1: 0x2421, 0xcf2: 0x0965, 0xcf3: 0x2439, 0xcf4: 0x1089, 0xcf5: 0x2451, + 0xcf6: 0x0985, 0xcf7: 0x2469, 0xcf8: 0x2491, 0xcf9: 0x0369, 0xcfa: 0x24a9, 0xcfb: 0x09a5, + 0xcfc: 0x0359, 0xcfd: 0x1159, 0xcfe: 0x0ef9, 0xcff: 0x0f61, + // Block 0x34, offset 0xd00 + 0xd00: 0x0018, 0xd01: 0x0018, 0xd02: 0x0018, 0xd03: 0x0018, 0xd04: 0x0018, 0xd05: 0x0018, + 0xd06: 0x0018, 0xd07: 0x0018, 0xd08: 0x0018, 0xd09: 0x0018, 0xd0a: 0x0018, 0xd0b: 0x0040, + 0xd0c: 0x0040, 0xd0d: 0x0040, 0xd0e: 0x0040, 0xd0f: 0x0040, 0xd10: 0x0040, 0xd11: 0x0040, + 0xd12: 0x0040, 0xd13: 0x0040, 0xd14: 0x0040, 0xd15: 0x0040, 0xd16: 0x0040, 0xd17: 0x0040, + 0xd18: 0x0040, 0xd19: 0x0040, 0xd1a: 0x0040, 0xd1b: 0x0040, 0xd1c: 0x0040, 0xd1d: 0x0040, + 0xd1e: 0x0040, 0xd1f: 0x0040, 0xd20: 0x00c9, 0xd21: 0x0069, 0xd22: 0x0079, 0xd23: 0x1f51, + 0xd24: 0x1f61, 0xd25: 0x1f71, 0xd26: 0x1f81, 0xd27: 0x1f91, 0xd28: 0x1fa1, 0xd29: 0x2601, + 0xd2a: 0x2619, 0xd2b: 0x2631, 0xd2c: 0x2649, 0xd2d: 0x2661, 0xd2e: 0x2679, 0xd2f: 0x2691, + 0xd30: 0x26a9, 0xd31: 0x26c1, 0xd32: 0x26d9, 0xd33: 0x26f1, 0xd34: 0x0a06, 0xd35: 0x0a26, + 0xd36: 0x0a46, 0xd37: 0x0a66, 0xd38: 0x0a86, 0xd39: 0x0aa6, 0xd3a: 0x0ac6, 0xd3b: 0x0ae6, + 0xd3c: 0x0b06, 0xd3d: 0x270a, 0xd3e: 0x2732, 0xd3f: 0x275a, + // Block 0x35, offset 0xd40 + 0xd40: 0x2782, 0xd41: 0x27aa, 0xd42: 0x27d2, 0xd43: 0x27fa, 0xd44: 0x2822, 0xd45: 0x284a, + 0xd46: 0x2872, 0xd47: 0x289a, 0xd48: 0x0040, 0xd49: 0x0040, 0xd4a: 0x0040, 0xd4b: 0x0040, + 0xd4c: 0x0040, 0xd4d: 0x0040, 0xd4e: 0x0040, 0xd4f: 0x0040, 0xd50: 0x0040, 0xd51: 0x0040, + 0xd52: 0x0040, 0xd53: 0x0040, 0xd54: 0x0040, 0xd55: 0x0040, 0xd56: 0x0040, 0xd57: 0x0040, + 0xd58: 0x0040, 0xd59: 0x0040, 0xd5a: 0x0040, 0xd5b: 0x0040, 0xd5c: 0x0b26, 0xd5d: 0x0b46, + 0xd5e: 0x0b66, 0xd5f: 0x0b86, 0xd60: 0x0ba6, 0xd61: 0x0bc6, 0xd62: 0x0be6, 0xd63: 0x0c06, + 0xd64: 0x0c26, 0xd65: 0x0c46, 0xd66: 0x0c66, 0xd67: 0x0c86, 0xd68: 0x0ca6, 0xd69: 0x0cc6, + 0xd6a: 0x0ce6, 0xd6b: 0x0d06, 0xd6c: 0x0d26, 0xd6d: 0x0d46, 0xd6e: 0x0d66, 0xd6f: 0x0d86, + 0xd70: 0x0da6, 0xd71: 0x0dc6, 0xd72: 0x0de6, 0xd73: 0x0e06, 0xd74: 0x0e26, 0xd75: 0x0e46, + 0xd76: 0x0039, 0xd77: 0x0ee9, 0xd78: 0x1159, 0xd79: 0x0ef9, 0xd7a: 0x0f09, 0xd7b: 0x1199, + 0xd7c: 0x0f31, 0xd7d: 0x0249, 0xd7e: 0x0f41, 0xd7f: 0x0259, + // Block 0x36, offset 0xd80 + 0xd80: 0x0f51, 0xd81: 0x0359, 0xd82: 0x0f61, 0xd83: 0x0f71, 0xd84: 0x00d9, 0xd85: 0x0f99, + 0xd86: 0x2039, 0xd87: 0x0269, 0xd88: 0x01d9, 0xd89: 0x0fa9, 0xd8a: 0x0fb9, 0xd8b: 0x1089, + 0xd8c: 0x0279, 0xd8d: 0x0369, 0xd8e: 0x0289, 0xd8f: 0x13d1, 0xd90: 0x0039, 0xd91: 0x0ee9, + 0xd92: 0x1159, 0xd93: 0x0ef9, 0xd94: 0x0f09, 0xd95: 0x1199, 0xd96: 0x0f31, 0xd97: 0x0249, + 0xd98: 0x0f41, 0xd99: 0x0259, 0xd9a: 0x0f51, 0xd9b: 0x0359, 0xd9c: 0x0f61, 0xd9d: 0x0f71, + 0xd9e: 0x00d9, 0xd9f: 0x0f99, 0xda0: 0x2039, 0xda1: 0x0269, 0xda2: 0x01d9, 0xda3: 0x0fa9, + 0xda4: 0x0fb9, 0xda5: 0x1089, 0xda6: 0x0279, 0xda7: 0x0369, 0xda8: 0x0289, 0xda9: 0x13d1, + 0xdaa: 0x1f41, 0xdab: 0x0018, 0xdac: 0x0018, 0xdad: 0x0018, 0xdae: 0x0018, 0xdaf: 0x0018, + 0xdb0: 0x0018, 0xdb1: 0x0018, 0xdb2: 0x0018, 0xdb3: 0x0018, 0xdb4: 0x0018, 0xdb5: 0x0018, + 0xdb6: 0x0018, 0xdb7: 0x0018, 0xdb8: 0x0018, 0xdb9: 0x0018, 0xdba: 0x0018, 0xdbb: 0x0018, + 0xdbc: 0x0018, 0xdbd: 0x0018, 0xdbe: 0x0018, 0xdbf: 0x0018, + // Block 0x37, offset 0xdc0 + 0xdc0: 0x0008, 0xdc1: 0x0008, 0xdc2: 0x0008, 0xdc3: 0x0008, 0xdc4: 0x0008, 0xdc5: 0x0008, + 0xdc6: 0x0008, 0xdc7: 0x0008, 0xdc8: 0x0008, 0xdc9: 0x0008, 0xdca: 0x0008, 0xdcb: 0x0008, + 0xdcc: 0x0008, 0xdcd: 0x0008, 0xdce: 0x0008, 0xdcf: 0x0008, 0xdd0: 0x0008, 0xdd1: 0x0008, + 0xdd2: 0x0008, 0xdd3: 0x0008, 0xdd4: 0x0008, 0xdd5: 0x0008, 0xdd6: 0x0008, 0xdd7: 0x0008, + 0xdd8: 0x0008, 0xdd9: 0x0008, 0xdda: 0x0008, 0xddb: 0x0008, 0xddc: 0x0008, 0xddd: 0x0008, + 0xdde: 0x0008, 0xddf: 0x0040, 0xde0: 0xe00d, 0xde1: 0x0008, 0xde2: 0x2971, 0xde3: 0x0ebd, + 0xde4: 0x2989, 0xde5: 0x0008, 0xde6: 0x0008, 0xde7: 0xe07d, 0xde8: 0x0008, 0xde9: 0xe01d, + 0xdea: 0x0008, 0xdeb: 0xe03d, 0xdec: 0x0008, 0xded: 0x0fe1, 0xdee: 0x1281, 0xdef: 0x0fc9, + 0xdf0: 0x1141, 0xdf1: 0x0008, 0xdf2: 0xe00d, 0xdf3: 0x0008, 0xdf4: 0x0008, 0xdf5: 0xe01d, + 0xdf6: 0x0008, 0xdf7: 0x0008, 0xdf8: 0x0008, 0xdf9: 0x0008, 0xdfa: 0x0008, 0xdfb: 0x0008, + 0xdfc: 0x0259, 0xdfd: 0x1089, 0xdfe: 0x29a1, 0xdff: 0x29b9, + // Block 0x38, offset 0xe00 + 0xe00: 0xe00d, 0xe01: 0x0008, 0xe02: 0xe00d, 0xe03: 0x0008, 0xe04: 0xe00d, 0xe05: 0x0008, + 0xe06: 0xe00d, 0xe07: 0x0008, 0xe08: 0xe00d, 0xe09: 0x0008, 0xe0a: 0xe00d, 0xe0b: 0x0008, + 0xe0c: 0xe00d, 0xe0d: 0x0008, 0xe0e: 0xe00d, 0xe0f: 0x0008, 0xe10: 0xe00d, 0xe11: 0x0008, + 0xe12: 0xe00d, 0xe13: 0x0008, 0xe14: 0xe00d, 0xe15: 0x0008, 0xe16: 0xe00d, 0xe17: 0x0008, + 0xe18: 0xe00d, 0xe19: 0x0008, 0xe1a: 0xe00d, 0xe1b: 0x0008, 0xe1c: 0xe00d, 0xe1d: 0x0008, + 0xe1e: 0xe00d, 0xe1f: 0x0008, 0xe20: 0xe00d, 0xe21: 0x0008, 0xe22: 0xe00d, 0xe23: 0x0008, + 0xe24: 0x0008, 0xe25: 0x0018, 0xe26: 0x0018, 0xe27: 0x0018, 0xe28: 0x0018, 0xe29: 0x0018, + 0xe2a: 0x0018, 0xe2b: 0xe03d, 0xe2c: 0x0008, 0xe2d: 0xe01d, 0xe2e: 0x0008, 0xe2f: 0x3308, + 0xe30: 0x3308, 0xe31: 0x3308, 0xe32: 0xe00d, 0xe33: 0x0008, 0xe34: 0x0040, 0xe35: 0x0040, + 0xe36: 0x0040, 0xe37: 0x0040, 0xe38: 0x0040, 0xe39: 0x0018, 0xe3a: 0x0018, 0xe3b: 0x0018, + 0xe3c: 0x0018, 0xe3d: 0x0018, 0xe3e: 0x0018, 0xe3f: 0x0018, + // Block 0x39, offset 0xe40 + 0xe40: 0x26fd, 0xe41: 0x271d, 0xe42: 0x273d, 0xe43: 0x275d, 0xe44: 0x277d, 0xe45: 0x279d, + 0xe46: 0x27bd, 0xe47: 0x27dd, 0xe48: 0x27fd, 0xe49: 0x281d, 0xe4a: 0x283d, 0xe4b: 0x285d, + 0xe4c: 0x287d, 0xe4d: 0x289d, 0xe4e: 0x28bd, 0xe4f: 0x28dd, 0xe50: 0x28fd, 0xe51: 0x291d, + 0xe52: 0x293d, 0xe53: 0x295d, 0xe54: 0x297d, 0xe55: 0x299d, 0xe56: 0x0040, 0xe57: 0x0040, + 0xe58: 0x0040, 0xe59: 0x0040, 0xe5a: 0x0040, 0xe5b: 0x0040, 0xe5c: 0x0040, 0xe5d: 0x0040, + 0xe5e: 0x0040, 0xe5f: 0x0040, 0xe60: 0x0040, 0xe61: 0x0040, 0xe62: 0x0040, 0xe63: 0x0040, + 0xe64: 0x0040, 0xe65: 0x0040, 0xe66: 0x0040, 0xe67: 0x0040, 0xe68: 0x0040, 0xe69: 0x0040, + 0xe6a: 0x0040, 0xe6b: 0x0040, 0xe6c: 0x0040, 0xe6d: 0x0040, 0xe6e: 0x0040, 0xe6f: 0x0040, + 0xe70: 0x0040, 0xe71: 0x0040, 0xe72: 0x0040, 0xe73: 0x0040, 0xe74: 0x0040, 0xe75: 0x0040, + 0xe76: 0x0040, 0xe77: 0x0040, 0xe78: 0x0040, 0xe79: 0x0040, 0xe7a: 0x0040, 0xe7b: 0x0040, + 0xe7c: 0x0040, 0xe7d: 0x0040, 0xe7e: 0x0040, 0xe7f: 0x0040, + // Block 0x3a, offset 0xe80 + 0xe80: 0x000a, 0xe81: 0x0018, 0xe82: 0x29d1, 0xe83: 0x0018, 0xe84: 0x0018, 0xe85: 0x0008, + 0xe86: 0x0008, 0xe87: 0x0008, 0xe88: 0x0018, 0xe89: 0x0018, 0xe8a: 0x0018, 0xe8b: 0x0018, + 0xe8c: 0x0018, 0xe8d: 0x0018, 0xe8e: 0x0018, 0xe8f: 0x0018, 0xe90: 0x0018, 0xe91: 0x0018, + 0xe92: 0x0018, 0xe93: 0x0018, 0xe94: 0x0018, 0xe95: 0x0018, 0xe96: 0x0018, 0xe97: 0x0018, + 0xe98: 0x0018, 0xe99: 0x0018, 0xe9a: 0x0018, 0xe9b: 0x0018, 0xe9c: 0x0018, 0xe9d: 0x0018, + 0xe9e: 0x0018, 0xe9f: 0x0018, 0xea0: 0x0018, 0xea1: 0x0018, 0xea2: 0x0018, 0xea3: 0x0018, + 0xea4: 0x0018, 0xea5: 0x0018, 0xea6: 0x0018, 0xea7: 0x0018, 0xea8: 0x0018, 0xea9: 0x0018, + 0xeaa: 0x3308, 0xeab: 0x3308, 0xeac: 0x3308, 0xead: 0x3308, 0xeae: 0x3018, 0xeaf: 0x3018, + 0xeb0: 0x0018, 0xeb1: 0x0018, 0xeb2: 0x0018, 0xeb3: 0x0018, 0xeb4: 0x0018, 0xeb5: 0x0018, + 0xeb6: 0xe125, 0xeb7: 0x0018, 0xeb8: 0x29bd, 0xeb9: 0x29dd, 0xeba: 0x29fd, 0xebb: 0x0018, + 0xebc: 0x0008, 0xebd: 0x0018, 0xebe: 0x0018, 0xebf: 0x0018, + // Block 0x3b, offset 0xec0 + 0xec0: 0x2b3d, 0xec1: 0x2b5d, 0xec2: 0x2b7d, 0xec3: 0x2b9d, 0xec4: 0x2bbd, 0xec5: 0x2bdd, + 0xec6: 0x2bdd, 0xec7: 0x2bdd, 0xec8: 0x2bfd, 0xec9: 0x2bfd, 0xeca: 0x2bfd, 0xecb: 0x2bfd, + 0xecc: 0x2c1d, 0xecd: 0x2c1d, 0xece: 0x2c1d, 0xecf: 0x2c3d, 0xed0: 0x2c5d, 0xed1: 0x2c5d, + 0xed2: 0x2a7d, 0xed3: 0x2a7d, 0xed4: 0x2c5d, 0xed5: 0x2c5d, 0xed6: 0x2c7d, 0xed7: 0x2c7d, + 0xed8: 0x2c5d, 0xed9: 0x2c5d, 0xeda: 0x2a7d, 0xedb: 0x2a7d, 0xedc: 0x2c5d, 0xedd: 0x2c5d, + 0xede: 0x2c3d, 0xedf: 0x2c3d, 0xee0: 0x2c9d, 0xee1: 0x2c9d, 0xee2: 0x2cbd, 0xee3: 0x2cbd, + 0xee4: 0x0040, 0xee5: 0x2cdd, 0xee6: 0x2cfd, 0xee7: 0x2d1d, 0xee8: 0x2d1d, 0xee9: 0x2d3d, + 0xeea: 0x2d5d, 0xeeb: 0x2d7d, 0xeec: 0x2d9d, 0xeed: 0x2dbd, 0xeee: 0x2ddd, 0xeef: 0x2dfd, + 0xef0: 0x2e1d, 0xef1: 0x2e3d, 0xef2: 0x2e3d, 0xef3: 0x2e5d, 0xef4: 0x2e7d, 0xef5: 0x2e7d, + 0xef6: 0x2e9d, 0xef7: 0x2ebd, 0xef8: 0x2e5d, 0xef9: 0x2edd, 0xefa: 0x2efd, 0xefb: 0x2edd, + 0xefc: 0x2e5d, 0xefd: 0x2f1d, 0xefe: 0x2f3d, 0xeff: 0x2f5d, + // Block 0x3c, offset 0xf00 + 0xf00: 0x2f7d, 0xf01: 0x2f9d, 0xf02: 0x2cfd, 0xf03: 0x2cdd, 0xf04: 0x2fbd, 0xf05: 0x2fdd, + 0xf06: 0x2ffd, 0xf07: 0x301d, 0xf08: 0x303d, 0xf09: 0x305d, 0xf0a: 0x307d, 0xf0b: 0x309d, + 0xf0c: 0x30bd, 0xf0d: 0x30dd, 0xf0e: 0x30fd, 0xf0f: 0x0040, 0xf10: 0x0018, 0xf11: 0x0018, + 0xf12: 0x311d, 0xf13: 0x313d, 0xf14: 0x315d, 0xf15: 0x317d, 0xf16: 0x319d, 0xf17: 0x31bd, + 0xf18: 0x31dd, 0xf19: 0x31fd, 0xf1a: 0x321d, 0xf1b: 0x323d, 0xf1c: 0x315d, 0xf1d: 0x325d, + 0xf1e: 0x327d, 0xf1f: 0x329d, 0xf20: 0x0008, 0xf21: 0x0008, 0xf22: 0x0008, 0xf23: 0x0008, + 0xf24: 0x0008, 0xf25: 0x0008, 0xf26: 0x0008, 0xf27: 0x0008, 0xf28: 0x0008, 0xf29: 0x0008, + 0xf2a: 0x0008, 0xf2b: 0x0008, 0xf2c: 0x0008, 0xf2d: 0x0008, 0xf2e: 0x0008, 0xf2f: 0x0008, + 0xf30: 0x0008, 0xf31: 0x0008, 0xf32: 0x0008, 0xf33: 0x0008, 0xf34: 0x0008, 0xf35: 0x0008, + 0xf36: 0x0008, 0xf37: 0x0008, 0xf38: 0x0008, 0xf39: 0x0008, 0xf3a: 0x0008, 0xf3b: 0x0040, + 0xf3c: 0x0040, 0xf3d: 0x0040, 0xf3e: 0x0040, 0xf3f: 0x0040, + // Block 0x3d, offset 0xf40 + 0xf40: 0x36a2, 0xf41: 0x36d2, 0xf42: 0x3702, 0xf43: 0x3732, 0xf44: 0x32bd, 0xf45: 0x32dd, + 0xf46: 0x32fd, 0xf47: 0x331d, 0xf48: 0x0018, 0xf49: 0x0018, 0xf4a: 0x0018, 0xf4b: 0x0018, + 0xf4c: 0x0018, 0xf4d: 0x0018, 0xf4e: 0x0018, 0xf4f: 0x0018, 0xf50: 0x333d, 0xf51: 0x3761, + 0xf52: 0x3779, 0xf53: 0x3791, 0xf54: 0x37a9, 0xf55: 0x37c1, 0xf56: 0x37d9, 0xf57: 0x37f1, + 0xf58: 0x3809, 0xf59: 0x3821, 0xf5a: 0x3839, 0xf5b: 0x3851, 0xf5c: 0x3869, 0xf5d: 0x3881, + 0xf5e: 0x3899, 0xf5f: 0x38b1, 0xf60: 0x335d, 0xf61: 0x337d, 0xf62: 0x339d, 0xf63: 0x33bd, + 0xf64: 0x33dd, 0xf65: 0x33dd, 0xf66: 0x33fd, 0xf67: 0x341d, 0xf68: 0x343d, 0xf69: 0x345d, + 0xf6a: 0x347d, 0xf6b: 0x349d, 0xf6c: 0x34bd, 0xf6d: 0x34dd, 0xf6e: 0x34fd, 0xf6f: 0x351d, + 0xf70: 0x353d, 0xf71: 0x355d, 0xf72: 0x357d, 0xf73: 0x359d, 0xf74: 0x35bd, 0xf75: 0x35dd, + 0xf76: 0x35fd, 0xf77: 0x361d, 0xf78: 0x363d, 0xf79: 0x365d, 0xf7a: 0x367d, 0xf7b: 0x369d, + 0xf7c: 0x38c9, 0xf7d: 0x3901, 0xf7e: 0x36bd, 0xf7f: 0x0018, + // Block 0x3e, offset 0xf80 + 0xf80: 0x36dd, 0xf81: 0x36fd, 0xf82: 0x371d, 0xf83: 0x373d, 0xf84: 0x375d, 0xf85: 0x377d, + 0xf86: 0x379d, 0xf87: 0x37bd, 0xf88: 0x37dd, 0xf89: 0x37fd, 0xf8a: 0x381d, 0xf8b: 0x383d, + 0xf8c: 0x385d, 0xf8d: 0x387d, 0xf8e: 0x389d, 0xf8f: 0x38bd, 0xf90: 0x38dd, 0xf91: 0x38fd, + 0xf92: 0x391d, 0xf93: 0x393d, 0xf94: 0x395d, 0xf95: 0x397d, 0xf96: 0x399d, 0xf97: 0x39bd, + 0xf98: 0x39dd, 0xf99: 0x39fd, 0xf9a: 0x3a1d, 0xf9b: 0x3a3d, 0xf9c: 0x3a5d, 0xf9d: 0x3a7d, + 0xf9e: 0x3a9d, 0xf9f: 0x3abd, 0xfa0: 0x3add, 0xfa1: 0x3afd, 0xfa2: 0x3b1d, 0xfa3: 0x3b3d, + 0xfa4: 0x3b5d, 0xfa5: 0x3b7d, 0xfa6: 0x127d, 0xfa7: 0x3b9d, 0xfa8: 0x3bbd, 0xfa9: 0x3bdd, + 0xfaa: 0x3bfd, 0xfab: 0x3c1d, 0xfac: 0x3c3d, 0xfad: 0x3c5d, 0xfae: 0x239d, 0xfaf: 0x3c7d, + 0xfb0: 0x3c9d, 0xfb1: 0x3939, 0xfb2: 0x3951, 0xfb3: 0x3969, 0xfb4: 0x3981, 0xfb5: 0x3999, + 0xfb6: 0x39b1, 0xfb7: 0x39c9, 0xfb8: 0x39e1, 0xfb9: 0x39f9, 0xfba: 0x3a11, 0xfbb: 0x3a29, + 0xfbc: 0x3a41, 0xfbd: 0x3a59, 0xfbe: 0x3a71, 0xfbf: 0x3a89, + // Block 0x3f, offset 0xfc0 + 0xfc0: 0x3aa1, 0xfc1: 0x3ac9, 0xfc2: 0x3af1, 0xfc3: 0x3b19, 0xfc4: 0x3b41, 0xfc5: 0x3b69, + 0xfc6: 0x3b91, 0xfc7: 0x3bb9, 0xfc8: 0x3be1, 0xfc9: 0x3c09, 0xfca: 0x3c39, 0xfcb: 0x3c69, + 0xfcc: 0x3c99, 0xfcd: 0x3cbd, 0xfce: 0x3cb1, 0xfcf: 0x3cdd, 0xfd0: 0x3cfd, 0xfd1: 0x3d15, + 0xfd2: 0x3d2d, 0xfd3: 0x3d45, 0xfd4: 0x3d5d, 0xfd5: 0x3d5d, 0xfd6: 0x3d45, 0xfd7: 0x3d75, + 0xfd8: 0x07bd, 0xfd9: 0x3d8d, 0xfda: 0x3da5, 0xfdb: 0x3dbd, 0xfdc: 0x3dd5, 0xfdd: 0x3ded, + 0xfde: 0x3e05, 0xfdf: 0x3e1d, 0xfe0: 0x3e35, 0xfe1: 0x3e4d, 0xfe2: 0x3e65, 0xfe3: 0x3e7d, + 0xfe4: 0x3e95, 0xfe5: 0x3e95, 0xfe6: 0x3ead, 0xfe7: 0x3ead, 0xfe8: 0x3ec5, 0xfe9: 0x3ec5, + 0xfea: 0x3edd, 0xfeb: 0x3ef5, 0xfec: 0x3f0d, 0xfed: 0x3f25, 0xfee: 0x3f3d, 0xfef: 0x3f3d, + 0xff0: 0x3f55, 0xff1: 0x3f55, 0xff2: 0x3f55, 0xff3: 0x3f6d, 0xff4: 0x3f85, 0xff5: 0x3f9d, + 0xff6: 0x3fb5, 0xff7: 0x3f9d, 0xff8: 0x3fcd, 0xff9: 0x3fe5, 0xffa: 0x3f6d, 0xffb: 0x3ffd, + 0xffc: 0x4015, 0xffd: 0x4015, 0xffe: 0x4015, 0xfff: 0x0040, + // Block 0x40, offset 0x1000 + 0x1000: 0x3cc9, 0x1001: 0x3d31, 0x1002: 0x3d99, 0x1003: 0x3e01, 0x1004: 0x3e51, 0x1005: 0x3eb9, + 0x1006: 0x3f09, 0x1007: 0x3f59, 0x1008: 0x3fd9, 0x1009: 0x4041, 0x100a: 0x4091, 0x100b: 0x40e1, + 0x100c: 0x4131, 0x100d: 0x4199, 0x100e: 0x4201, 0x100f: 0x4251, 0x1010: 0x42a1, 0x1011: 0x42d9, + 0x1012: 0x4329, 0x1013: 0x4391, 0x1014: 0x43f9, 0x1015: 0x4431, 0x1016: 0x44b1, 0x1017: 0x4549, + 0x1018: 0x45c9, 0x1019: 0x4619, 0x101a: 0x4699, 0x101b: 0x4719, 0x101c: 0x4781, 0x101d: 0x47d1, + 0x101e: 0x4821, 0x101f: 0x4871, 0x1020: 0x48d9, 0x1021: 0x4959, 0x1022: 0x49c1, 0x1023: 0x4a11, + 0x1024: 0x4a61, 0x1025: 0x4ab1, 0x1026: 0x4ae9, 0x1027: 0x4b21, 0x1028: 0x4b59, 0x1029: 0x4b91, + 0x102a: 0x4be1, 0x102b: 0x4c31, 0x102c: 0x4cb1, 0x102d: 0x4d01, 0x102e: 0x4d69, 0x102f: 0x4de9, + 0x1030: 0x4e39, 0x1031: 0x4e71, 0x1032: 0x4ea9, 0x1033: 0x4f29, 0x1034: 0x4f91, 0x1035: 0x5011, + 0x1036: 0x5061, 0x1037: 0x50e1, 0x1038: 0x5119, 0x1039: 0x5169, 0x103a: 0x51b9, 0x103b: 0x5209, + 0x103c: 0x5259, 0x103d: 0x52a9, 0x103e: 0x5311, 0x103f: 0x5361, + // Block 0x41, offset 0x1040 + 0x1040: 0x5399, 0x1041: 0x53e9, 0x1042: 0x5439, 0x1043: 0x5489, 0x1044: 0x54f1, 0x1045: 0x5541, + 0x1046: 0x5591, 0x1047: 0x55e1, 0x1048: 0x5661, 0x1049: 0x56c9, 0x104a: 0x5701, 0x104b: 0x5781, + 0x104c: 0x57b9, 0x104d: 0x5821, 0x104e: 0x5889, 0x104f: 0x58d9, 0x1050: 0x5929, 0x1051: 0x5979, + 0x1052: 0x59e1, 0x1053: 0x5a19, 0x1054: 0x5a69, 0x1055: 0x5ad1, 0x1056: 0x5b09, 0x1057: 0x5b89, + 0x1058: 0x5bd9, 0x1059: 0x5c01, 0x105a: 0x5c29, 0x105b: 0x5c51, 0x105c: 0x5c79, 0x105d: 0x5ca1, + 0x105e: 0x5cc9, 0x105f: 0x5cf1, 0x1060: 0x5d19, 0x1061: 0x5d41, 0x1062: 0x5d69, 0x1063: 0x5d99, + 0x1064: 0x5dc9, 0x1065: 0x5df9, 0x1066: 0x5e29, 0x1067: 0x5e59, 0x1068: 0x5e89, 0x1069: 0x5eb9, + 0x106a: 0x5ee9, 0x106b: 0x5f19, 0x106c: 0x5f49, 0x106d: 0x5f79, 0x106e: 0x5fa9, 0x106f: 0x5fd9, + 0x1070: 0x6009, 0x1071: 0x402d, 0x1072: 0x6039, 0x1073: 0x6051, 0x1074: 0x404d, 0x1075: 0x6069, + 0x1076: 0x6081, 0x1077: 0x6099, 0x1078: 0x406d, 0x1079: 0x406d, 0x107a: 0x60b1, 0x107b: 0x60c9, + 0x107c: 0x6101, 0x107d: 0x6139, 0x107e: 0x6171, 0x107f: 0x61a9, + // Block 0x42, offset 0x1080 + 0x1080: 0x6211, 0x1081: 0x6229, 0x1082: 0x408d, 0x1083: 0x6241, 0x1084: 0x6259, 0x1085: 0x6271, + 0x1086: 0x6289, 0x1087: 0x62a1, 0x1088: 0x40ad, 0x1089: 0x62b9, 0x108a: 0x62e1, 0x108b: 0x62f9, + 0x108c: 0x40cd, 0x108d: 0x40cd, 0x108e: 0x6311, 0x108f: 0x6329, 0x1090: 0x6341, 0x1091: 0x40ed, + 0x1092: 0x410d, 0x1093: 0x412d, 0x1094: 0x414d, 0x1095: 0x416d, 0x1096: 0x6359, 0x1097: 0x6371, + 0x1098: 0x6389, 0x1099: 0x63a1, 0x109a: 0x63b9, 0x109b: 0x418d, 0x109c: 0x63d1, 0x109d: 0x63e9, + 0x109e: 0x6401, 0x109f: 0x41ad, 0x10a0: 0x41cd, 0x10a1: 0x6419, 0x10a2: 0x41ed, 0x10a3: 0x420d, + 0x10a4: 0x422d, 0x10a5: 0x6431, 0x10a6: 0x424d, 0x10a7: 0x6449, 0x10a8: 0x6479, 0x10a9: 0x6211, + 0x10aa: 0x426d, 0x10ab: 0x428d, 0x10ac: 0x42ad, 0x10ad: 0x42cd, 0x10ae: 0x64b1, 0x10af: 0x64f1, + 0x10b0: 0x6539, 0x10b1: 0x6551, 0x10b2: 0x42ed, 0x10b3: 0x6569, 0x10b4: 0x6581, 0x10b5: 0x6599, + 0x10b6: 0x430d, 0x10b7: 0x65b1, 0x10b8: 0x65c9, 0x10b9: 0x65b1, 0x10ba: 0x65e1, 0x10bb: 0x65f9, + 0x10bc: 0x432d, 0x10bd: 0x6611, 0x10be: 0x6629, 0x10bf: 0x6611, + // Block 0x43, offset 0x10c0 + 0x10c0: 0x434d, 0x10c1: 0x436d, 0x10c2: 0x0040, 0x10c3: 0x6641, 0x10c4: 0x6659, 0x10c5: 0x6671, + 0x10c6: 0x6689, 0x10c7: 0x0040, 0x10c8: 0x66c1, 0x10c9: 0x66d9, 0x10ca: 0x66f1, 0x10cb: 0x6709, + 0x10cc: 0x6721, 0x10cd: 0x6739, 0x10ce: 0x6401, 0x10cf: 0x6751, 0x10d0: 0x6769, 0x10d1: 0x6781, + 0x10d2: 0x438d, 0x10d3: 0x6799, 0x10d4: 0x6289, 0x10d5: 0x43ad, 0x10d6: 0x43cd, 0x10d7: 0x67b1, + 0x10d8: 0x0040, 0x10d9: 0x43ed, 0x10da: 0x67c9, 0x10db: 0x67e1, 0x10dc: 0x67f9, 0x10dd: 0x6811, + 0x10de: 0x6829, 0x10df: 0x6859, 0x10e0: 0x6889, 0x10e1: 0x68b1, 0x10e2: 0x68d9, 0x10e3: 0x6901, + 0x10e4: 0x6929, 0x10e5: 0x6951, 0x10e6: 0x6979, 0x10e7: 0x69a1, 0x10e8: 0x69c9, 0x10e9: 0x69f1, + 0x10ea: 0x6a21, 0x10eb: 0x6a51, 0x10ec: 0x6a81, 0x10ed: 0x6ab1, 0x10ee: 0x6ae1, 0x10ef: 0x6b11, + 0x10f0: 0x6b41, 0x10f1: 0x6b71, 0x10f2: 0x6ba1, 0x10f3: 0x6bd1, 0x10f4: 0x6c01, 0x10f5: 0x6c31, + 0x10f6: 0x6c61, 0x10f7: 0x6c91, 0x10f8: 0x6cc1, 0x10f9: 0x6cf1, 0x10fa: 0x6d21, 0x10fb: 0x6d51, + 0x10fc: 0x6d81, 0x10fd: 0x6db1, 0x10fe: 0x6de1, 0x10ff: 0x440d, + // Block 0x44, offset 0x1100 + 0x1100: 0xe00d, 0x1101: 0x0008, 0x1102: 0xe00d, 0x1103: 0x0008, 0x1104: 0xe00d, 0x1105: 0x0008, + 0x1106: 0xe00d, 0x1107: 0x0008, 0x1108: 0xe00d, 0x1109: 0x0008, 0x110a: 0xe00d, 0x110b: 0x0008, + 0x110c: 0xe00d, 0x110d: 0x0008, 0x110e: 0xe00d, 0x110f: 0x0008, 0x1110: 0xe00d, 0x1111: 0x0008, + 0x1112: 0xe00d, 0x1113: 0x0008, 0x1114: 0xe00d, 0x1115: 0x0008, 0x1116: 0xe00d, 0x1117: 0x0008, + 0x1118: 0xe00d, 0x1119: 0x0008, 0x111a: 0xe00d, 0x111b: 0x0008, 0x111c: 0xe00d, 0x111d: 0x0008, + 0x111e: 0xe00d, 0x111f: 0x0008, 0x1120: 0xe00d, 0x1121: 0x0008, 0x1122: 0xe00d, 0x1123: 0x0008, + 0x1124: 0xe00d, 0x1125: 0x0008, 0x1126: 0xe00d, 0x1127: 0x0008, 0x1128: 0xe00d, 0x1129: 0x0008, + 0x112a: 0xe00d, 0x112b: 0x0008, 0x112c: 0xe00d, 0x112d: 0x0008, 0x112e: 0x0008, 0x112f: 0x3308, + 0x1130: 0x3318, 0x1131: 0x3318, 0x1132: 0x3318, 0x1133: 0x0018, 0x1134: 0x3308, 0x1135: 0x3308, + 0x1136: 0x3308, 0x1137: 0x3308, 0x1138: 0x3308, 0x1139: 0x3308, 0x113a: 0x3308, 0x113b: 0x3308, + 0x113c: 0x3308, 0x113d: 0x3308, 0x113e: 0x0018, 0x113f: 0x0008, + // Block 0x45, offset 0x1140 + 0x1140: 0xe00d, 0x1141: 0x0008, 0x1142: 0xe00d, 0x1143: 0x0008, 0x1144: 0xe00d, 0x1145: 0x0008, + 0x1146: 0xe00d, 0x1147: 0x0008, 0x1148: 0xe00d, 0x1149: 0x0008, 0x114a: 0xe00d, 0x114b: 0x0008, + 0x114c: 0xe00d, 0x114d: 0x0008, 0x114e: 0xe00d, 0x114f: 0x0008, 0x1150: 0xe00d, 0x1151: 0x0008, + 0x1152: 0xe00d, 0x1153: 0x0008, 0x1154: 0xe00d, 0x1155: 0x0008, 0x1156: 0xe00d, 0x1157: 0x0008, + 0x1158: 0xe00d, 0x1159: 0x0008, 0x115a: 0xe00d, 0x115b: 0x0008, 0x115c: 0x0ea1, 0x115d: 0x6e11, + 0x115e: 0x3308, 0x115f: 0x3308, 0x1160: 0x0008, 0x1161: 0x0008, 0x1162: 0x0008, 0x1163: 0x0008, + 0x1164: 0x0008, 0x1165: 0x0008, 0x1166: 0x0008, 0x1167: 0x0008, 0x1168: 0x0008, 0x1169: 0x0008, + 0x116a: 0x0008, 0x116b: 0x0008, 0x116c: 0x0008, 0x116d: 0x0008, 0x116e: 0x0008, 0x116f: 0x0008, + 0x1170: 0x0008, 0x1171: 0x0008, 0x1172: 0x0008, 0x1173: 0x0008, 0x1174: 0x0008, 0x1175: 0x0008, + 0x1176: 0x0008, 0x1177: 0x0008, 0x1178: 0x0008, 0x1179: 0x0008, 0x117a: 0x0008, 0x117b: 0x0008, + 0x117c: 0x0008, 0x117d: 0x0008, 0x117e: 0x0008, 0x117f: 0x0008, + // Block 0x46, offset 0x1180 + 0x1180: 0x0018, 0x1181: 0x0018, 0x1182: 0x0018, 0x1183: 0x0018, 0x1184: 0x0018, 0x1185: 0x0018, + 0x1186: 0x0018, 0x1187: 0x0018, 0x1188: 0x0018, 0x1189: 0x0018, 0x118a: 0x0018, 0x118b: 0x0018, + 0x118c: 0x0018, 0x118d: 0x0018, 0x118e: 0x0018, 0x118f: 0x0018, 0x1190: 0x0018, 0x1191: 0x0018, + 0x1192: 0x0018, 0x1193: 0x0018, 0x1194: 0x0018, 0x1195: 0x0018, 0x1196: 0x0018, 0x1197: 0x0008, + 0x1198: 0x0008, 0x1199: 0x0008, 0x119a: 0x0008, 0x119b: 0x0008, 0x119c: 0x0008, 0x119d: 0x0008, + 0x119e: 0x0008, 0x119f: 0x0008, 0x11a0: 0x0018, 0x11a1: 0x0018, 0x11a2: 0xe00d, 0x11a3: 0x0008, + 0x11a4: 0xe00d, 0x11a5: 0x0008, 0x11a6: 0xe00d, 0x11a7: 0x0008, 0x11a8: 0xe00d, 0x11a9: 0x0008, + 0x11aa: 0xe00d, 0x11ab: 0x0008, 0x11ac: 0xe00d, 0x11ad: 0x0008, 0x11ae: 0xe00d, 0x11af: 0x0008, + 0x11b0: 0x0008, 0x11b1: 0x0008, 0x11b2: 0xe00d, 0x11b3: 0x0008, 0x11b4: 0xe00d, 0x11b5: 0x0008, + 0x11b6: 0xe00d, 0x11b7: 0x0008, 0x11b8: 0xe00d, 0x11b9: 0x0008, 0x11ba: 0xe00d, 0x11bb: 0x0008, + 0x11bc: 0xe00d, 0x11bd: 0x0008, 0x11be: 0xe00d, 0x11bf: 0x0008, + // Block 0x47, offset 0x11c0 + 0x11c0: 0xe00d, 0x11c1: 0x0008, 0x11c2: 0xe00d, 0x11c3: 0x0008, 0x11c4: 0xe00d, 0x11c5: 0x0008, + 0x11c6: 0xe00d, 0x11c7: 0x0008, 0x11c8: 0xe00d, 0x11c9: 0x0008, 0x11ca: 0xe00d, 0x11cb: 0x0008, + 0x11cc: 0xe00d, 0x11cd: 0x0008, 0x11ce: 0xe00d, 0x11cf: 0x0008, 0x11d0: 0xe00d, 0x11d1: 0x0008, + 0x11d2: 0xe00d, 0x11d3: 0x0008, 0x11d4: 0xe00d, 0x11d5: 0x0008, 0x11d6: 0xe00d, 0x11d7: 0x0008, + 0x11d8: 0xe00d, 0x11d9: 0x0008, 0x11da: 0xe00d, 0x11db: 0x0008, 0x11dc: 0xe00d, 0x11dd: 0x0008, + 0x11de: 0xe00d, 0x11df: 0x0008, 0x11e0: 0xe00d, 0x11e1: 0x0008, 0x11e2: 0xe00d, 0x11e3: 0x0008, + 0x11e4: 0xe00d, 0x11e5: 0x0008, 0x11e6: 0xe00d, 0x11e7: 0x0008, 0x11e8: 0xe00d, 0x11e9: 0x0008, + 0x11ea: 0xe00d, 0x11eb: 0x0008, 0x11ec: 0xe00d, 0x11ed: 0x0008, 0x11ee: 0xe00d, 0x11ef: 0x0008, + 0x11f0: 0xe0fd, 0x11f1: 0x0008, 0x11f2: 0x0008, 0x11f3: 0x0008, 0x11f4: 0x0008, 0x11f5: 0x0008, + 0x11f6: 0x0008, 0x11f7: 0x0008, 0x11f8: 0x0008, 0x11f9: 0xe01d, 0x11fa: 0x0008, 0x11fb: 0xe03d, + 0x11fc: 0x0008, 0x11fd: 0x442d, 0x11fe: 0xe00d, 0x11ff: 0x0008, + // Block 0x48, offset 0x1200 + 0x1200: 0xe00d, 0x1201: 0x0008, 0x1202: 0xe00d, 0x1203: 0x0008, 0x1204: 0xe00d, 0x1205: 0x0008, + 0x1206: 0xe00d, 0x1207: 0x0008, 0x1208: 0x0008, 0x1209: 0x0018, 0x120a: 0x0018, 0x120b: 0xe03d, + 0x120c: 0x0008, 0x120d: 0x11d9, 0x120e: 0x0008, 0x120f: 0x0008, 0x1210: 0xe00d, 0x1211: 0x0008, + 0x1212: 0xe00d, 0x1213: 0x0008, 0x1214: 0x0008, 0x1215: 0x0008, 0x1216: 0xe00d, 0x1217: 0x0008, + 0x1218: 0xe00d, 0x1219: 0x0008, 0x121a: 0xe00d, 0x121b: 0x0008, 0x121c: 0xe00d, 0x121d: 0x0008, + 0x121e: 0xe00d, 0x121f: 0x0008, 0x1220: 0xe00d, 0x1221: 0x0008, 0x1222: 0xe00d, 0x1223: 0x0008, + 0x1224: 0xe00d, 0x1225: 0x0008, 0x1226: 0xe00d, 0x1227: 0x0008, 0x1228: 0xe00d, 0x1229: 0x0008, + 0x122a: 0x6e29, 0x122b: 0x1029, 0x122c: 0x11c1, 0x122d: 0x6e41, 0x122e: 0x1221, 0x122f: 0x0040, + 0x1230: 0x6e59, 0x1231: 0x6e71, 0x1232: 0x1239, 0x1233: 0x444d, 0x1234: 0xe00d, 0x1235: 0x0008, + 0x1236: 0xe00d, 0x1237: 0x0008, 0x1238: 0x0040, 0x1239: 0x0040, 0x123a: 0x0040, 0x123b: 0x0040, + 0x123c: 0x0040, 0x123d: 0x0040, 0x123e: 0x0040, 0x123f: 0x0040, + // Block 0x49, offset 0x1240 + 0x1240: 0x64d5, 0x1241: 0x64f5, 0x1242: 0x6515, 0x1243: 0x6535, 0x1244: 0x6555, 0x1245: 0x6575, + 0x1246: 0x6595, 0x1247: 0x65b5, 0x1248: 0x65d5, 0x1249: 0x65f5, 0x124a: 0x6615, 0x124b: 0x6635, + 0x124c: 0x6655, 0x124d: 0x6675, 0x124e: 0x0008, 0x124f: 0x0008, 0x1250: 0x6695, 0x1251: 0x0008, + 0x1252: 0x66b5, 0x1253: 0x0008, 0x1254: 0x0008, 0x1255: 0x66d5, 0x1256: 0x66f5, 0x1257: 0x6715, + 0x1258: 0x6735, 0x1259: 0x6755, 0x125a: 0x6775, 0x125b: 0x6795, 0x125c: 0x67b5, 0x125d: 0x67d5, + 0x125e: 0x67f5, 0x125f: 0x0008, 0x1260: 0x6815, 0x1261: 0x0008, 0x1262: 0x6835, 0x1263: 0x0008, + 0x1264: 0x0008, 0x1265: 0x6855, 0x1266: 0x6875, 0x1267: 0x0008, 0x1268: 0x0008, 0x1269: 0x0008, + 0x126a: 0x6895, 0x126b: 0x68b5, 0x126c: 0x68d5, 0x126d: 0x68f5, 0x126e: 0x6915, 0x126f: 0x6935, + 0x1270: 0x6955, 0x1271: 0x6975, 0x1272: 0x6995, 0x1273: 0x69b5, 0x1274: 0x69d5, 0x1275: 0x69f5, + 0x1276: 0x6a15, 0x1277: 0x6a35, 0x1278: 0x6a55, 0x1279: 0x6a75, 0x127a: 0x6a95, 0x127b: 0x6ab5, + 0x127c: 0x6ad5, 0x127d: 0x6af5, 0x127e: 0x6b15, 0x127f: 0x6b35, + // Block 0x4a, offset 0x1280 + 0x1280: 0x7a95, 0x1281: 0x7ab5, 0x1282: 0x7ad5, 0x1283: 0x7af5, 0x1284: 0x7b15, 0x1285: 0x7b35, + 0x1286: 0x7b55, 0x1287: 0x7b75, 0x1288: 0x7b95, 0x1289: 0x7bb5, 0x128a: 0x7bd5, 0x128b: 0x7bf5, + 0x128c: 0x7c15, 0x128d: 0x7c35, 0x128e: 0x7c55, 0x128f: 0x6ec9, 0x1290: 0x6ef1, 0x1291: 0x6f19, + 0x1292: 0x7c75, 0x1293: 0x7c95, 0x1294: 0x7cb5, 0x1295: 0x6f41, 0x1296: 0x6f69, 0x1297: 0x6f91, + 0x1298: 0x7cd5, 0x1299: 0x7cf5, 0x129a: 0x0040, 0x129b: 0x0040, 0x129c: 0x0040, 0x129d: 0x0040, + 0x129e: 0x0040, 0x129f: 0x0040, 0x12a0: 0x0040, 0x12a1: 0x0040, 0x12a2: 0x0040, 0x12a3: 0x0040, + 0x12a4: 0x0040, 0x12a5: 0x0040, 0x12a6: 0x0040, 0x12a7: 0x0040, 0x12a8: 0x0040, 0x12a9: 0x0040, + 0x12aa: 0x0040, 0x12ab: 0x0040, 0x12ac: 0x0040, 0x12ad: 0x0040, 0x12ae: 0x0040, 0x12af: 0x0040, + 0x12b0: 0x0040, 0x12b1: 0x0040, 0x12b2: 0x0040, 0x12b3: 0x0040, 0x12b4: 0x0040, 0x12b5: 0x0040, + 0x12b6: 0x0040, 0x12b7: 0x0040, 0x12b8: 0x0040, 0x12b9: 0x0040, 0x12ba: 0x0040, 0x12bb: 0x0040, + 0x12bc: 0x0040, 0x12bd: 0x0040, 0x12be: 0x0040, 0x12bf: 0x0040, + // Block 0x4b, offset 0x12c0 + 0x12c0: 0x6fb9, 0x12c1: 0x6fd1, 0x12c2: 0x6fe9, 0x12c3: 0x7d15, 0x12c4: 0x7d35, 0x12c5: 0x7001, + 0x12c6: 0x7001, 0x12c7: 0x0040, 0x12c8: 0x0040, 0x12c9: 0x0040, 0x12ca: 0x0040, 0x12cb: 0x0040, + 0x12cc: 0x0040, 0x12cd: 0x0040, 0x12ce: 0x0040, 0x12cf: 0x0040, 0x12d0: 0x0040, 0x12d1: 0x0040, + 0x12d2: 0x0040, 0x12d3: 0x7019, 0x12d4: 0x7041, 0x12d5: 0x7069, 0x12d6: 0x7091, 0x12d7: 0x70b9, + 0x12d8: 0x0040, 0x12d9: 0x0040, 0x12da: 0x0040, 0x12db: 0x0040, 0x12dc: 0x0040, 0x12dd: 0x70e1, + 0x12de: 0x3308, 0x12df: 0x7109, 0x12e0: 0x7131, 0x12e1: 0x20a9, 0x12e2: 0x20f1, 0x12e3: 0x7149, + 0x12e4: 0x7161, 0x12e5: 0x7179, 0x12e6: 0x7191, 0x12e7: 0x71a9, 0x12e8: 0x71c1, 0x12e9: 0x1fb2, + 0x12ea: 0x71d9, 0x12eb: 0x7201, 0x12ec: 0x7229, 0x12ed: 0x7261, 0x12ee: 0x7299, 0x12ef: 0x72c1, + 0x12f0: 0x72e9, 0x12f1: 0x7311, 0x12f2: 0x7339, 0x12f3: 0x7361, 0x12f4: 0x7389, 0x12f5: 0x73b1, + 0x12f6: 0x73d9, 0x12f7: 0x0040, 0x12f8: 0x7401, 0x12f9: 0x7429, 0x12fa: 0x7451, 0x12fb: 0x7479, + 0x12fc: 0x74a1, 0x12fd: 0x0040, 0x12fe: 0x74c9, 0x12ff: 0x0040, + // Block 0x4c, offset 0x1300 + 0x1300: 0x74f1, 0x1301: 0x7519, 0x1302: 0x0040, 0x1303: 0x7541, 0x1304: 0x7569, 0x1305: 0x0040, + 0x1306: 0x7591, 0x1307: 0x75b9, 0x1308: 0x75e1, 0x1309: 0x7609, 0x130a: 0x7631, 0x130b: 0x7659, + 0x130c: 0x7681, 0x130d: 0x76a9, 0x130e: 0x76d1, 0x130f: 0x76f9, 0x1310: 0x7721, 0x1311: 0x7721, + 0x1312: 0x7739, 0x1313: 0x7739, 0x1314: 0x7739, 0x1315: 0x7739, 0x1316: 0x7751, 0x1317: 0x7751, + 0x1318: 0x7751, 0x1319: 0x7751, 0x131a: 0x7769, 0x131b: 0x7769, 0x131c: 0x7769, 0x131d: 0x7769, + 0x131e: 0x7781, 0x131f: 0x7781, 0x1320: 0x7781, 0x1321: 0x7781, 0x1322: 0x7799, 0x1323: 0x7799, + 0x1324: 0x7799, 0x1325: 0x7799, 0x1326: 0x77b1, 0x1327: 0x77b1, 0x1328: 0x77b1, 0x1329: 0x77b1, + 0x132a: 0x77c9, 0x132b: 0x77c9, 0x132c: 0x77c9, 0x132d: 0x77c9, 0x132e: 0x77e1, 0x132f: 0x77e1, + 0x1330: 0x77e1, 0x1331: 0x77e1, 0x1332: 0x77f9, 0x1333: 0x77f9, 0x1334: 0x77f9, 0x1335: 0x77f9, + 0x1336: 0x7811, 0x1337: 0x7811, 0x1338: 0x7811, 0x1339: 0x7811, 0x133a: 0x7829, 0x133b: 0x7829, + 0x133c: 0x7829, 0x133d: 0x7829, 0x133e: 0x7841, 0x133f: 0x7841, + // Block 0x4d, offset 0x1340 + 0x1340: 0x7841, 0x1341: 0x7841, 0x1342: 0x7859, 0x1343: 0x7859, 0x1344: 0x7871, 0x1345: 0x7871, + 0x1346: 0x7889, 0x1347: 0x7889, 0x1348: 0x78a1, 0x1349: 0x78a1, 0x134a: 0x78b9, 0x134b: 0x78b9, + 0x134c: 0x78d1, 0x134d: 0x78d1, 0x134e: 0x78e9, 0x134f: 0x78e9, 0x1350: 0x78e9, 0x1351: 0x78e9, + 0x1352: 0x7901, 0x1353: 0x7901, 0x1354: 0x7901, 0x1355: 0x7901, 0x1356: 0x7919, 0x1357: 0x7919, + 0x1358: 0x7919, 0x1359: 0x7919, 0x135a: 0x7931, 0x135b: 0x7931, 0x135c: 0x7931, 0x135d: 0x7931, + 0x135e: 0x7949, 0x135f: 0x7949, 0x1360: 0x7961, 0x1361: 0x7961, 0x1362: 0x7961, 0x1363: 0x7961, + 0x1364: 0x7979, 0x1365: 0x7979, 0x1366: 0x7991, 0x1367: 0x7991, 0x1368: 0x7991, 0x1369: 0x7991, + 0x136a: 0x79a9, 0x136b: 0x79a9, 0x136c: 0x79a9, 0x136d: 0x79a9, 0x136e: 0x79c1, 0x136f: 0x79c1, + 0x1370: 0x79d9, 0x1371: 0x79d9, 0x1372: 0x0818, 0x1373: 0x0818, 0x1374: 0x0818, 0x1375: 0x0818, + 0x1376: 0x0818, 0x1377: 0x0818, 0x1378: 0x0818, 0x1379: 0x0818, 0x137a: 0x0818, 0x137b: 0x0818, + 0x137c: 0x0818, 0x137d: 0x0818, 0x137e: 0x0818, 0x137f: 0x0818, + // Block 0x4e, offset 0x1380 + 0x1380: 0x0818, 0x1381: 0x0818, 0x1382: 0x0040, 0x1383: 0x0040, 0x1384: 0x0040, 0x1385: 0x0040, + 0x1386: 0x0040, 0x1387: 0x0040, 0x1388: 0x0040, 0x1389: 0x0040, 0x138a: 0x0040, 0x138b: 0x0040, + 0x138c: 0x0040, 0x138d: 0x0040, 0x138e: 0x0040, 0x138f: 0x0040, 0x1390: 0x0040, 0x1391: 0x0040, + 0x1392: 0x0040, 0x1393: 0x79f1, 0x1394: 0x79f1, 0x1395: 0x79f1, 0x1396: 0x79f1, 0x1397: 0x7a09, + 0x1398: 0x7a09, 0x1399: 0x7a21, 0x139a: 0x7a21, 0x139b: 0x7a39, 0x139c: 0x7a39, 0x139d: 0x0479, + 0x139e: 0x7a51, 0x139f: 0x7a51, 0x13a0: 0x7a69, 0x13a1: 0x7a69, 0x13a2: 0x7a81, 0x13a3: 0x7a81, + 0x13a4: 0x7a99, 0x13a5: 0x7a99, 0x13a6: 0x7a99, 0x13a7: 0x7a99, 0x13a8: 0x7ab1, 0x13a9: 0x7ab1, + 0x13aa: 0x7ac9, 0x13ab: 0x7ac9, 0x13ac: 0x7af1, 0x13ad: 0x7af1, 0x13ae: 0x7b19, 0x13af: 0x7b19, + 0x13b0: 0x7b41, 0x13b1: 0x7b41, 0x13b2: 0x7b69, 0x13b3: 0x7b69, 0x13b4: 0x7b91, 0x13b5: 0x7b91, + 0x13b6: 0x7bb9, 0x13b7: 0x7bb9, 0x13b8: 0x7bb9, 0x13b9: 0x7be1, 0x13ba: 0x7be1, 0x13bb: 0x7be1, + 0x13bc: 0x7c09, 0x13bd: 0x7c09, 0x13be: 0x7c09, 0x13bf: 0x7c09, + // Block 0x4f, offset 0x13c0 + 0x13c0: 0x85f9, 0x13c1: 0x8621, 0x13c2: 0x8649, 0x13c3: 0x8671, 0x13c4: 0x8699, 0x13c5: 0x86c1, + 0x13c6: 0x86e9, 0x13c7: 0x8711, 0x13c8: 0x8739, 0x13c9: 0x8761, 0x13ca: 0x8789, 0x13cb: 0x87b1, + 0x13cc: 0x87d9, 0x13cd: 0x8801, 0x13ce: 0x8829, 0x13cf: 0x8851, 0x13d0: 0x8879, 0x13d1: 0x88a1, + 0x13d2: 0x88c9, 0x13d3: 0x88f1, 0x13d4: 0x8919, 0x13d5: 0x8941, 0x13d6: 0x8969, 0x13d7: 0x8991, + 0x13d8: 0x89b9, 0x13d9: 0x89e1, 0x13da: 0x8a09, 0x13db: 0x8a31, 0x13dc: 0x8a59, 0x13dd: 0x8a81, + 0x13de: 0x8aaa, 0x13df: 0x8ada, 0x13e0: 0x8b0a, 0x13e1: 0x8b3a, 0x13e2: 0x8b6a, 0x13e3: 0x8b9a, + 0x13e4: 0x8bc9, 0x13e5: 0x8bf1, 0x13e6: 0x7c71, 0x13e7: 0x8c19, 0x13e8: 0x7be1, 0x13e9: 0x7c99, + 0x13ea: 0x8c41, 0x13eb: 0x8c69, 0x13ec: 0x7d39, 0x13ed: 0x8c91, 0x13ee: 0x7d61, 0x13ef: 0x7d89, + 0x13f0: 0x8cb9, 0x13f1: 0x8ce1, 0x13f2: 0x7e29, 0x13f3: 0x8d09, 0x13f4: 0x7e51, 0x13f5: 0x7e79, + 0x13f6: 0x8d31, 0x13f7: 0x8d59, 0x13f8: 0x7ec9, 0x13f9: 0x8d81, 0x13fa: 0x7ef1, 0x13fb: 0x7f19, + 0x13fc: 0x83a1, 0x13fd: 0x83c9, 0x13fe: 0x8441, 0x13ff: 0x8469, + // Block 0x50, offset 0x1400 + 0x1400: 0x8491, 0x1401: 0x8531, 0x1402: 0x8559, 0x1403: 0x8581, 0x1404: 0x85a9, 0x1405: 0x8649, + 0x1406: 0x8671, 0x1407: 0x8699, 0x1408: 0x8da9, 0x1409: 0x8739, 0x140a: 0x8dd1, 0x140b: 0x8df9, + 0x140c: 0x8829, 0x140d: 0x8e21, 0x140e: 0x8851, 0x140f: 0x8879, 0x1410: 0x8a81, 0x1411: 0x8e49, + 0x1412: 0x8e71, 0x1413: 0x89b9, 0x1414: 0x8e99, 0x1415: 0x89e1, 0x1416: 0x8a09, 0x1417: 0x7c21, + 0x1418: 0x7c49, 0x1419: 0x8ec1, 0x141a: 0x7c71, 0x141b: 0x8ee9, 0x141c: 0x7cc1, 0x141d: 0x7ce9, + 0x141e: 0x7d11, 0x141f: 0x7d39, 0x1420: 0x8f11, 0x1421: 0x7db1, 0x1422: 0x7dd9, 0x1423: 0x7e01, + 0x1424: 0x7e29, 0x1425: 0x8f39, 0x1426: 0x7ec9, 0x1427: 0x7f41, 0x1428: 0x7f69, 0x1429: 0x7f91, + 0x142a: 0x7fb9, 0x142b: 0x7fe1, 0x142c: 0x8031, 0x142d: 0x8059, 0x142e: 0x8081, 0x142f: 0x80a9, + 0x1430: 0x80d1, 0x1431: 0x80f9, 0x1432: 0x8f61, 0x1433: 0x8121, 0x1434: 0x8149, 0x1435: 0x8171, + 0x1436: 0x8199, 0x1437: 0x81c1, 0x1438: 0x81e9, 0x1439: 0x8239, 0x143a: 0x8261, 0x143b: 0x8289, + 0x143c: 0x82b1, 0x143d: 0x82d9, 0x143e: 0x8301, 0x143f: 0x8329, + // Block 0x51, offset 0x1440 + 0x1440: 0x8351, 0x1441: 0x8379, 0x1442: 0x83f1, 0x1443: 0x8419, 0x1444: 0x84b9, 0x1445: 0x84e1, + 0x1446: 0x8509, 0x1447: 0x8531, 0x1448: 0x8559, 0x1449: 0x85d1, 0x144a: 0x85f9, 0x144b: 0x8621, + 0x144c: 0x8649, 0x144d: 0x8f89, 0x144e: 0x86c1, 0x144f: 0x86e9, 0x1450: 0x8711, 0x1451: 0x8739, + 0x1452: 0x87b1, 0x1453: 0x87d9, 0x1454: 0x8801, 0x1455: 0x8829, 0x1456: 0x8fb1, 0x1457: 0x88a1, + 0x1458: 0x88c9, 0x1459: 0x8fd9, 0x145a: 0x8941, 0x145b: 0x8969, 0x145c: 0x8991, 0x145d: 0x89b9, + 0x145e: 0x9001, 0x145f: 0x7c71, 0x1460: 0x8ee9, 0x1461: 0x7d39, 0x1462: 0x8f11, 0x1463: 0x7e29, + 0x1464: 0x8f39, 0x1465: 0x7ec9, 0x1466: 0x9029, 0x1467: 0x80d1, 0x1468: 0x9051, 0x1469: 0x9079, + 0x146a: 0x90a1, 0x146b: 0x8531, 0x146c: 0x8559, 0x146d: 0x8649, 0x146e: 0x8829, 0x146f: 0x8fb1, + 0x1470: 0x89b9, 0x1471: 0x9001, 0x1472: 0x90c9, 0x1473: 0x9101, 0x1474: 0x9139, 0x1475: 0x9171, + 0x1476: 0x9199, 0x1477: 0x91c1, 0x1478: 0x91e9, 0x1479: 0x9211, 0x147a: 0x9239, 0x147b: 0x9261, + 0x147c: 0x9289, 0x147d: 0x92b1, 0x147e: 0x92d9, 0x147f: 0x9301, + // Block 0x52, offset 0x1480 + 0x1480: 0x9329, 0x1481: 0x9351, 0x1482: 0x9379, 0x1483: 0x93a1, 0x1484: 0x93c9, 0x1485: 0x93f1, + 0x1486: 0x9419, 0x1487: 0x9441, 0x1488: 0x9469, 0x1489: 0x9491, 0x148a: 0x94b9, 0x148b: 0x94e1, + 0x148c: 0x9079, 0x148d: 0x9509, 0x148e: 0x9531, 0x148f: 0x9559, 0x1490: 0x9581, 0x1491: 0x9171, + 0x1492: 0x9199, 0x1493: 0x91c1, 0x1494: 0x91e9, 0x1495: 0x9211, 0x1496: 0x9239, 0x1497: 0x9261, + 0x1498: 0x9289, 0x1499: 0x92b1, 0x149a: 0x92d9, 0x149b: 0x9301, 0x149c: 0x9329, 0x149d: 0x9351, + 0x149e: 0x9379, 0x149f: 0x93a1, 0x14a0: 0x93c9, 0x14a1: 0x93f1, 0x14a2: 0x9419, 0x14a3: 0x9441, + 0x14a4: 0x9469, 0x14a5: 0x9491, 0x14a6: 0x94b9, 0x14a7: 0x94e1, 0x14a8: 0x9079, 0x14a9: 0x9509, + 0x14aa: 0x9531, 0x14ab: 0x9559, 0x14ac: 0x9581, 0x14ad: 0x9491, 0x14ae: 0x94b9, 0x14af: 0x94e1, + 0x14b0: 0x9079, 0x14b1: 0x9051, 0x14b2: 0x90a1, 0x14b3: 0x8211, 0x14b4: 0x8059, 0x14b5: 0x8081, + 0x14b6: 0x80a9, 0x14b7: 0x9491, 0x14b8: 0x94b9, 0x14b9: 0x94e1, 0x14ba: 0x8211, 0x14bb: 0x8239, + 0x14bc: 0x95a9, 0x14bd: 0x95a9, 0x14be: 0x0018, 0x14bf: 0x0018, + // Block 0x53, offset 0x14c0 + 0x14c0: 0x0040, 0x14c1: 0x0040, 0x14c2: 0x0040, 0x14c3: 0x0040, 0x14c4: 0x0040, 0x14c5: 0x0040, + 0x14c6: 0x0040, 0x14c7: 0x0040, 0x14c8: 0x0040, 0x14c9: 0x0040, 0x14ca: 0x0040, 0x14cb: 0x0040, + 0x14cc: 0x0040, 0x14cd: 0x0040, 0x14ce: 0x0040, 0x14cf: 0x0040, 0x14d0: 0x95d1, 0x14d1: 0x9609, + 0x14d2: 0x9609, 0x14d3: 0x9641, 0x14d4: 0x9679, 0x14d5: 0x96b1, 0x14d6: 0x96e9, 0x14d7: 0x9721, + 0x14d8: 0x9759, 0x14d9: 0x9759, 0x14da: 0x9791, 0x14db: 0x97c9, 0x14dc: 0x9801, 0x14dd: 0x9839, + 0x14de: 0x9871, 0x14df: 0x98a9, 0x14e0: 0x98a9, 0x14e1: 0x98e1, 0x14e2: 0x9919, 0x14e3: 0x9919, + 0x14e4: 0x9951, 0x14e5: 0x9951, 0x14e6: 0x9989, 0x14e7: 0x99c1, 0x14e8: 0x99c1, 0x14e9: 0x99f9, + 0x14ea: 0x9a31, 0x14eb: 0x9a31, 0x14ec: 0x9a69, 0x14ed: 0x9a69, 0x14ee: 0x9aa1, 0x14ef: 0x9ad9, + 0x14f0: 0x9ad9, 0x14f1: 0x9b11, 0x14f2: 0x9b11, 0x14f3: 0x9b49, 0x14f4: 0x9b81, 0x14f5: 0x9bb9, + 0x14f6: 0x9bf1, 0x14f7: 0x9bf1, 0x14f8: 0x9c29, 0x14f9: 0x9c61, 0x14fa: 0x9c99, 0x14fb: 0x9cd1, + 0x14fc: 0x9d09, 0x14fd: 0x9d09, 0x14fe: 0x9d41, 0x14ff: 0x9d79, + // Block 0x54, offset 0x1500 + 0x1500: 0xa949, 0x1501: 0xa981, 0x1502: 0xa9b9, 0x1503: 0xa8a1, 0x1504: 0x9bb9, 0x1505: 0x9989, + 0x1506: 0xa9f1, 0x1507: 0xaa29, 0x1508: 0x0040, 0x1509: 0x0040, 0x150a: 0x0040, 0x150b: 0x0040, + 0x150c: 0x0040, 0x150d: 0x0040, 0x150e: 0x0040, 0x150f: 0x0040, 0x1510: 0x0040, 0x1511: 0x0040, + 0x1512: 0x0040, 0x1513: 0x0040, 0x1514: 0x0040, 0x1515: 0x0040, 0x1516: 0x0040, 0x1517: 0x0040, + 0x1518: 0x0040, 0x1519: 0x0040, 0x151a: 0x0040, 0x151b: 0x0040, 0x151c: 0x0040, 0x151d: 0x0040, + 0x151e: 0x0040, 0x151f: 0x0040, 0x1520: 0x0040, 0x1521: 0x0040, 0x1522: 0x0040, 0x1523: 0x0040, + 0x1524: 0x0040, 0x1525: 0x0040, 0x1526: 0x0040, 0x1527: 0x0040, 0x1528: 0x0040, 0x1529: 0x0040, + 0x152a: 0x0040, 0x152b: 0x0040, 0x152c: 0x0040, 0x152d: 0x0040, 0x152e: 0x0040, 0x152f: 0x0040, + 0x1530: 0xaa61, 0x1531: 0xaa99, 0x1532: 0xaad1, 0x1533: 0xab19, 0x1534: 0xab61, 0x1535: 0xaba9, + 0x1536: 0xabf1, 0x1537: 0xac39, 0x1538: 0xac81, 0x1539: 0xacc9, 0x153a: 0xad02, 0x153b: 0xae12, + 0x153c: 0xae91, 0x153d: 0x0018, 0x153e: 0x0040, 0x153f: 0x0040, + // Block 0x55, offset 0x1540 + 0x1540: 0x33c0, 0x1541: 0x33c0, 0x1542: 0x33c0, 0x1543: 0x33c0, 0x1544: 0x33c0, 0x1545: 0x33c0, + 0x1546: 0x33c0, 0x1547: 0x33c0, 0x1548: 0x33c0, 0x1549: 0x33c0, 0x154a: 0x33c0, 0x154b: 0x33c0, + 0x154c: 0x33c0, 0x154d: 0x33c0, 0x154e: 0x33c0, 0x154f: 0x33c0, 0x1550: 0xaeda, 0x1551: 0x7d55, + 0x1552: 0x0040, 0x1553: 0xaeea, 0x1554: 0x03c2, 0x1555: 0xaefa, 0x1556: 0xaf0a, 0x1557: 0x7d75, + 0x1558: 0x7d95, 0x1559: 0x0040, 0x155a: 0x0040, 0x155b: 0x0040, 0x155c: 0x0040, 0x155d: 0x0040, + 0x155e: 0x0040, 0x155f: 0x0040, 0x1560: 0x3308, 0x1561: 0x3308, 0x1562: 0x3308, 0x1563: 0x3308, + 0x1564: 0x3308, 0x1565: 0x3308, 0x1566: 0x3308, 0x1567: 0x3308, 0x1568: 0x3308, 0x1569: 0x3308, + 0x156a: 0x3308, 0x156b: 0x3308, 0x156c: 0x3308, 0x156d: 0x3308, 0x156e: 0x3308, 0x156f: 0x3308, + 0x1570: 0x0040, 0x1571: 0x7db5, 0x1572: 0x7dd5, 0x1573: 0xaf1a, 0x1574: 0xaf1a, 0x1575: 0x1fd2, + 0x1576: 0x1fe2, 0x1577: 0xaf2a, 0x1578: 0xaf3a, 0x1579: 0x7df5, 0x157a: 0x7e15, 0x157b: 0x7e35, + 0x157c: 0x7df5, 0x157d: 0x7e55, 0x157e: 0x7e75, 0x157f: 0x7e55, + // Block 0x56, offset 0x1580 + 0x1580: 0x7e95, 0x1581: 0x7eb5, 0x1582: 0x7ed5, 0x1583: 0x7eb5, 0x1584: 0x7ef5, 0x1585: 0x0018, + 0x1586: 0x0018, 0x1587: 0xaf4a, 0x1588: 0xaf5a, 0x1589: 0x7f16, 0x158a: 0x7f36, 0x158b: 0x7f56, + 0x158c: 0x7f76, 0x158d: 0xaf1a, 0x158e: 0xaf1a, 0x158f: 0xaf1a, 0x1590: 0xaeda, 0x1591: 0x7f95, + 0x1592: 0x0040, 0x1593: 0x0040, 0x1594: 0x03c2, 0x1595: 0xaeea, 0x1596: 0xaf0a, 0x1597: 0xaefa, + 0x1598: 0x7fb5, 0x1599: 0x1fd2, 0x159a: 0x1fe2, 0x159b: 0xaf2a, 0x159c: 0xaf3a, 0x159d: 0x7e95, + 0x159e: 0x7ef5, 0x159f: 0xaf6a, 0x15a0: 0xaf7a, 0x15a1: 0xaf8a, 0x15a2: 0x1fb2, 0x15a3: 0xaf99, + 0x15a4: 0xafaa, 0x15a5: 0xafba, 0x15a6: 0x1fc2, 0x15a7: 0x0040, 0x15a8: 0xafca, 0x15a9: 0xafda, + 0x15aa: 0xafea, 0x15ab: 0xaffa, 0x15ac: 0x0040, 0x15ad: 0x0040, 0x15ae: 0x0040, 0x15af: 0x0040, + 0x15b0: 0x7fd6, 0x15b1: 0xb009, 0x15b2: 0x7ff6, 0x15b3: 0x0808, 0x15b4: 0x8016, 0x15b5: 0x0040, + 0x15b6: 0x8036, 0x15b7: 0xb031, 0x15b8: 0x8056, 0x15b9: 0xb059, 0x15ba: 0x8076, 0x15bb: 0xb081, + 0x15bc: 0x8096, 0x15bd: 0xb0a9, 0x15be: 0x80b6, 0x15bf: 0xb0d1, + // Block 0x57, offset 0x15c0 + 0x15c0: 0xb0f9, 0x15c1: 0xb111, 0x15c2: 0xb111, 0x15c3: 0xb129, 0x15c4: 0xb129, 0x15c5: 0xb141, + 0x15c6: 0xb141, 0x15c7: 0xb159, 0x15c8: 0xb159, 0x15c9: 0xb171, 0x15ca: 0xb171, 0x15cb: 0xb171, + 0x15cc: 0xb171, 0x15cd: 0xb189, 0x15ce: 0xb189, 0x15cf: 0xb1a1, 0x15d0: 0xb1a1, 0x15d1: 0xb1a1, + 0x15d2: 0xb1a1, 0x15d3: 0xb1b9, 0x15d4: 0xb1b9, 0x15d5: 0xb1d1, 0x15d6: 0xb1d1, 0x15d7: 0xb1d1, + 0x15d8: 0xb1d1, 0x15d9: 0xb1e9, 0x15da: 0xb1e9, 0x15db: 0xb1e9, 0x15dc: 0xb1e9, 0x15dd: 0xb201, + 0x15de: 0xb201, 0x15df: 0xb201, 0x15e0: 0xb201, 0x15e1: 0xb219, 0x15e2: 0xb219, 0x15e3: 0xb219, + 0x15e4: 0xb219, 0x15e5: 0xb231, 0x15e6: 0xb231, 0x15e7: 0xb231, 0x15e8: 0xb231, 0x15e9: 0xb249, + 0x15ea: 0xb249, 0x15eb: 0xb261, 0x15ec: 0xb261, 0x15ed: 0xb279, 0x15ee: 0xb279, 0x15ef: 0xb291, + 0x15f0: 0xb291, 0x15f1: 0xb2a9, 0x15f2: 0xb2a9, 0x15f3: 0xb2a9, 0x15f4: 0xb2a9, 0x15f5: 0xb2c1, + 0x15f6: 0xb2c1, 0x15f7: 0xb2c1, 0x15f8: 0xb2c1, 0x15f9: 0xb2d9, 0x15fa: 0xb2d9, 0x15fb: 0xb2d9, + 0x15fc: 0xb2d9, 0x15fd: 0xb2f1, 0x15fe: 0xb2f1, 0x15ff: 0xb2f1, + // Block 0x58, offset 0x1600 + 0x1600: 0xb2f1, 0x1601: 0xb309, 0x1602: 0xb309, 0x1603: 0xb309, 0x1604: 0xb309, 0x1605: 0xb321, + 0x1606: 0xb321, 0x1607: 0xb321, 0x1608: 0xb321, 0x1609: 0xb339, 0x160a: 0xb339, 0x160b: 0xb339, + 0x160c: 0xb339, 0x160d: 0xb351, 0x160e: 0xb351, 0x160f: 0xb351, 0x1610: 0xb351, 0x1611: 0xb369, + 0x1612: 0xb369, 0x1613: 0xb369, 0x1614: 0xb369, 0x1615: 0xb381, 0x1616: 0xb381, 0x1617: 0xb381, + 0x1618: 0xb381, 0x1619: 0xb399, 0x161a: 0xb399, 0x161b: 0xb399, 0x161c: 0xb399, 0x161d: 0xb3b1, + 0x161e: 0xb3b1, 0x161f: 0xb3b1, 0x1620: 0xb3b1, 0x1621: 0xb3c9, 0x1622: 0xb3c9, 0x1623: 0xb3c9, + 0x1624: 0xb3c9, 0x1625: 0xb3e1, 0x1626: 0xb3e1, 0x1627: 0xb3e1, 0x1628: 0xb3e1, 0x1629: 0xb3f9, + 0x162a: 0xb3f9, 0x162b: 0xb3f9, 0x162c: 0xb3f9, 0x162d: 0xb411, 0x162e: 0xb411, 0x162f: 0x7ab1, + 0x1630: 0x7ab1, 0x1631: 0xb429, 0x1632: 0xb429, 0x1633: 0xb429, 0x1634: 0xb429, 0x1635: 0xb441, + 0x1636: 0xb441, 0x1637: 0xb469, 0x1638: 0xb469, 0x1639: 0xb491, 0x163a: 0xb491, 0x163b: 0xb4b9, + 0x163c: 0xb4b9, 0x163d: 0x0040, 0x163e: 0x0040, 0x163f: 0x03c0, + // Block 0x59, offset 0x1640 + 0x1640: 0x0040, 0x1641: 0xaefa, 0x1642: 0xb4e2, 0x1643: 0xaf6a, 0x1644: 0xafda, 0x1645: 0xafea, + 0x1646: 0xaf7a, 0x1647: 0xb4f2, 0x1648: 0x1fd2, 0x1649: 0x1fe2, 0x164a: 0xaf8a, 0x164b: 0x1fb2, + 0x164c: 0xaeda, 0x164d: 0xaf99, 0x164e: 0x29d1, 0x164f: 0xb502, 0x1650: 0x1f41, 0x1651: 0x00c9, + 0x1652: 0x0069, 0x1653: 0x0079, 0x1654: 0x1f51, 0x1655: 0x1f61, 0x1656: 0x1f71, 0x1657: 0x1f81, + 0x1658: 0x1f91, 0x1659: 0x1fa1, 0x165a: 0xaeea, 0x165b: 0x03c2, 0x165c: 0xafaa, 0x165d: 0x1fc2, + 0x165e: 0xafba, 0x165f: 0xaf0a, 0x1660: 0xaffa, 0x1661: 0x0039, 0x1662: 0x0ee9, 0x1663: 0x1159, + 0x1664: 0x0ef9, 0x1665: 0x0f09, 0x1666: 0x1199, 0x1667: 0x0f31, 0x1668: 0x0249, 0x1669: 0x0f41, + 0x166a: 0x0259, 0x166b: 0x0f51, 0x166c: 0x0359, 0x166d: 0x0f61, 0x166e: 0x0f71, 0x166f: 0x00d9, + 0x1670: 0x0f99, 0x1671: 0x2039, 0x1672: 0x0269, 0x1673: 0x01d9, 0x1674: 0x0fa9, 0x1675: 0x0fb9, + 0x1676: 0x1089, 0x1677: 0x0279, 0x1678: 0x0369, 0x1679: 0x0289, 0x167a: 0x13d1, 0x167b: 0xaf4a, + 0x167c: 0xafca, 0x167d: 0xaf5a, 0x167e: 0xb512, 0x167f: 0xaf1a, + // Block 0x5a, offset 0x1680 + 0x1680: 0x1caa, 0x1681: 0x0039, 0x1682: 0x0ee9, 0x1683: 0x1159, 0x1684: 0x0ef9, 0x1685: 0x0f09, + 0x1686: 0x1199, 0x1687: 0x0f31, 0x1688: 0x0249, 0x1689: 0x0f41, 0x168a: 0x0259, 0x168b: 0x0f51, + 0x168c: 0x0359, 0x168d: 0x0f61, 0x168e: 0x0f71, 0x168f: 0x00d9, 0x1690: 0x0f99, 0x1691: 0x2039, + 0x1692: 0x0269, 0x1693: 0x01d9, 0x1694: 0x0fa9, 0x1695: 0x0fb9, 0x1696: 0x1089, 0x1697: 0x0279, + 0x1698: 0x0369, 0x1699: 0x0289, 0x169a: 0x13d1, 0x169b: 0xaf2a, 0x169c: 0xb522, 0x169d: 0xaf3a, + 0x169e: 0xb532, 0x169f: 0x80d5, 0x16a0: 0x80f5, 0x16a1: 0x29d1, 0x16a2: 0x8115, 0x16a3: 0x8115, + 0x16a4: 0x8135, 0x16a5: 0x8155, 0x16a6: 0x8175, 0x16a7: 0x8195, 0x16a8: 0x81b5, 0x16a9: 0x81d5, + 0x16aa: 0x81f5, 0x16ab: 0x8215, 0x16ac: 0x8235, 0x16ad: 0x8255, 0x16ae: 0x8275, 0x16af: 0x8295, + 0x16b0: 0x82b5, 0x16b1: 0x82d5, 0x16b2: 0x82f5, 0x16b3: 0x8315, 0x16b4: 0x8335, 0x16b5: 0x8355, + 0x16b6: 0x8375, 0x16b7: 0x8395, 0x16b8: 0x83b5, 0x16b9: 0x83d5, 0x16ba: 0x83f5, 0x16bb: 0x8415, + 0x16bc: 0x81b5, 0x16bd: 0x8435, 0x16be: 0x8455, 0x16bf: 0x8215, + // Block 0x5b, offset 0x16c0 + 0x16c0: 0x8475, 0x16c1: 0x8495, 0x16c2: 0x84b5, 0x16c3: 0x84d5, 0x16c4: 0x84f5, 0x16c5: 0x8515, + 0x16c6: 0x8535, 0x16c7: 0x8555, 0x16c8: 0x84d5, 0x16c9: 0x8575, 0x16ca: 0x84d5, 0x16cb: 0x8595, + 0x16cc: 0x8595, 0x16cd: 0x85b5, 0x16ce: 0x85b5, 0x16cf: 0x85d5, 0x16d0: 0x8515, 0x16d1: 0x85f5, + 0x16d2: 0x8615, 0x16d3: 0x85f5, 0x16d4: 0x8635, 0x16d5: 0x8615, 0x16d6: 0x8655, 0x16d7: 0x8655, + 0x16d8: 0x8675, 0x16d9: 0x8675, 0x16da: 0x8695, 0x16db: 0x8695, 0x16dc: 0x8615, 0x16dd: 0x8115, + 0x16de: 0x86b5, 0x16df: 0x86d5, 0x16e0: 0x0040, 0x16e1: 0x86f5, 0x16e2: 0x8715, 0x16e3: 0x8735, + 0x16e4: 0x8755, 0x16e5: 0x8735, 0x16e6: 0x8775, 0x16e7: 0x8795, 0x16e8: 0x87b5, 0x16e9: 0x87b5, + 0x16ea: 0x87d5, 0x16eb: 0x87d5, 0x16ec: 0x87f5, 0x16ed: 0x87f5, 0x16ee: 0x87d5, 0x16ef: 0x87d5, + 0x16f0: 0x8815, 0x16f1: 0x8835, 0x16f2: 0x8855, 0x16f3: 0x8875, 0x16f4: 0x8895, 0x16f5: 0x88b5, + 0x16f6: 0x88b5, 0x16f7: 0x88b5, 0x16f8: 0x88d5, 0x16f9: 0x88d5, 0x16fa: 0x88d5, 0x16fb: 0x88d5, + 0x16fc: 0x87b5, 0x16fd: 0x87b5, 0x16fe: 0x87b5, 0x16ff: 0x0040, + // Block 0x5c, offset 0x1700 + 0x1700: 0x0040, 0x1701: 0x0040, 0x1702: 0x8715, 0x1703: 0x86f5, 0x1704: 0x88f5, 0x1705: 0x86f5, + 0x1706: 0x8715, 0x1707: 0x86f5, 0x1708: 0x0040, 0x1709: 0x0040, 0x170a: 0x8915, 0x170b: 0x8715, + 0x170c: 0x8935, 0x170d: 0x88f5, 0x170e: 0x8935, 0x170f: 0x8715, 0x1710: 0x0040, 0x1711: 0x0040, + 0x1712: 0x8955, 0x1713: 0x8975, 0x1714: 0x8875, 0x1715: 0x8935, 0x1716: 0x88f5, 0x1717: 0x8935, + 0x1718: 0x0040, 0x1719: 0x0040, 0x171a: 0x8995, 0x171b: 0x89b5, 0x171c: 0x8995, 0x171d: 0x0040, + 0x171e: 0x0040, 0x171f: 0x0040, 0x1720: 0xb541, 0x1721: 0xb559, 0x1722: 0xb571, 0x1723: 0x89d6, + 0x1724: 0xb589, 0x1725: 0xb5a1, 0x1726: 0x89f5, 0x1727: 0x0040, 0x1728: 0x8a15, 0x1729: 0x8a35, + 0x172a: 0x8a55, 0x172b: 0x8a35, 0x172c: 0x8a75, 0x172d: 0x8a95, 0x172e: 0x8ab5, 0x172f: 0x0040, + 0x1730: 0x0040, 0x1731: 0x0040, 0x1732: 0x0040, 0x1733: 0x0040, 0x1734: 0x0040, 0x1735: 0x0040, + 0x1736: 0x0040, 0x1737: 0x0040, 0x1738: 0x0040, 0x1739: 0x0340, 0x173a: 0x0340, 0x173b: 0x0340, + 0x173c: 0x0040, 0x173d: 0x0040, 0x173e: 0x0040, 0x173f: 0x0040, + // Block 0x5d, offset 0x1740 + 0x1740: 0x0a08, 0x1741: 0x0a08, 0x1742: 0x0a08, 0x1743: 0x0a08, 0x1744: 0x0a08, 0x1745: 0x0c08, + 0x1746: 0x0808, 0x1747: 0x0c08, 0x1748: 0x0818, 0x1749: 0x0c08, 0x174a: 0x0c08, 0x174b: 0x0808, + 0x174c: 0x0808, 0x174d: 0x0908, 0x174e: 0x0c08, 0x174f: 0x0c08, 0x1750: 0x0c08, 0x1751: 0x0c08, + 0x1752: 0x0c08, 0x1753: 0x0a08, 0x1754: 0x0a08, 0x1755: 0x0a08, 0x1756: 0x0a08, 0x1757: 0x0908, + 0x1758: 0x0a08, 0x1759: 0x0a08, 0x175a: 0x0a08, 0x175b: 0x0a08, 0x175c: 0x0a08, 0x175d: 0x0c08, + 0x175e: 0x0a08, 0x175f: 0x0a08, 0x1760: 0x0a08, 0x1761: 0x0c08, 0x1762: 0x0808, 0x1763: 0x0808, + 0x1764: 0x0c08, 0x1765: 0x3308, 0x1766: 0x3308, 0x1767: 0x0040, 0x1768: 0x0040, 0x1769: 0x0040, + 0x176a: 0x0040, 0x176b: 0x0a18, 0x176c: 0x0a18, 0x176d: 0x0a18, 0x176e: 0x0a18, 0x176f: 0x0c18, + 0x1770: 0x0818, 0x1771: 0x0818, 0x1772: 0x0818, 0x1773: 0x0818, 0x1774: 0x0818, 0x1775: 0x0818, + 0x1776: 0x0818, 0x1777: 0x0040, 0x1778: 0x0040, 0x1779: 0x0040, 0x177a: 0x0040, 0x177b: 0x0040, + 0x177c: 0x0040, 0x177d: 0x0040, 0x177e: 0x0040, 0x177f: 0x0040, + // Block 0x5e, offset 0x1780 + 0x1780: 0x0a08, 0x1781: 0x0c08, 0x1782: 0x0a08, 0x1783: 0x0c08, 0x1784: 0x0c08, 0x1785: 0x0c08, + 0x1786: 0x0a08, 0x1787: 0x0a08, 0x1788: 0x0a08, 0x1789: 0x0c08, 0x178a: 0x0a08, 0x178b: 0x0a08, + 0x178c: 0x0c08, 0x178d: 0x0a08, 0x178e: 0x0c08, 0x178f: 0x0c08, 0x1790: 0x0a08, 0x1791: 0x0c08, + 0x1792: 0x0040, 0x1793: 0x0040, 0x1794: 0x0040, 0x1795: 0x0040, 0x1796: 0x0040, 0x1797: 0x0040, + 0x1798: 0x0040, 0x1799: 0x0818, 0x179a: 0x0818, 0x179b: 0x0818, 0x179c: 0x0818, 0x179d: 0x0040, + 0x179e: 0x0040, 0x179f: 0x0040, 0x17a0: 0x0040, 0x17a1: 0x0040, 0x17a2: 0x0040, 0x17a3: 0x0040, + 0x17a4: 0x0040, 0x17a5: 0x0040, 0x17a6: 0x0040, 0x17a7: 0x0040, 0x17a8: 0x0040, 0x17a9: 0x0c18, + 0x17aa: 0x0c18, 0x17ab: 0x0c18, 0x17ac: 0x0c18, 0x17ad: 0x0a18, 0x17ae: 0x0a18, 0x17af: 0x0818, + 0x17b0: 0x0040, 0x17b1: 0x0040, 0x17b2: 0x0040, 0x17b3: 0x0040, 0x17b4: 0x0040, 0x17b5: 0x0040, + 0x17b6: 0x0040, 0x17b7: 0x0040, 0x17b8: 0x0040, 0x17b9: 0x0040, 0x17ba: 0x0040, 0x17bb: 0x0040, + 0x17bc: 0x0040, 0x17bd: 0x0040, 0x17be: 0x0040, 0x17bf: 0x0040, + // Block 0x5f, offset 0x17c0 + 0x17c0: 0x3308, 0x17c1: 0x3308, 0x17c2: 0x3008, 0x17c3: 0x3008, 0x17c4: 0x0040, 0x17c5: 0x0008, + 0x17c6: 0x0008, 0x17c7: 0x0008, 0x17c8: 0x0008, 0x17c9: 0x0008, 0x17ca: 0x0008, 0x17cb: 0x0008, + 0x17cc: 0x0008, 0x17cd: 0x0040, 0x17ce: 0x0040, 0x17cf: 0x0008, 0x17d0: 0x0008, 0x17d1: 0x0040, + 0x17d2: 0x0040, 0x17d3: 0x0008, 0x17d4: 0x0008, 0x17d5: 0x0008, 0x17d6: 0x0008, 0x17d7: 0x0008, + 0x17d8: 0x0008, 0x17d9: 0x0008, 0x17da: 0x0008, 0x17db: 0x0008, 0x17dc: 0x0008, 0x17dd: 0x0008, + 0x17de: 0x0008, 0x17df: 0x0008, 0x17e0: 0x0008, 0x17e1: 0x0008, 0x17e2: 0x0008, 0x17e3: 0x0008, + 0x17e4: 0x0008, 0x17e5: 0x0008, 0x17e6: 0x0008, 0x17e7: 0x0008, 0x17e8: 0x0008, 0x17e9: 0x0040, + 0x17ea: 0x0008, 0x17eb: 0x0008, 0x17ec: 0x0008, 0x17ed: 0x0008, 0x17ee: 0x0008, 0x17ef: 0x0008, + 0x17f0: 0x0008, 0x17f1: 0x0040, 0x17f2: 0x0008, 0x17f3: 0x0008, 0x17f4: 0x0040, 0x17f5: 0x0008, + 0x17f6: 0x0008, 0x17f7: 0x0008, 0x17f8: 0x0008, 0x17f9: 0x0008, 0x17fa: 0x0040, 0x17fb: 0x0040, + 0x17fc: 0x3308, 0x17fd: 0x0008, 0x17fe: 0x3008, 0x17ff: 0x3008, + // Block 0x60, offset 0x1800 + 0x1800: 0x3308, 0x1801: 0x3008, 0x1802: 0x3008, 0x1803: 0x3008, 0x1804: 0x3008, 0x1805: 0x0040, + 0x1806: 0x0040, 0x1807: 0x3008, 0x1808: 0x3008, 0x1809: 0x0040, 0x180a: 0x0040, 0x180b: 0x3008, + 0x180c: 0x3008, 0x180d: 0x3808, 0x180e: 0x0040, 0x180f: 0x0040, 0x1810: 0x0008, 0x1811: 0x0040, + 0x1812: 0x0040, 0x1813: 0x0040, 0x1814: 0x0040, 0x1815: 0x0040, 0x1816: 0x0040, 0x1817: 0x3008, + 0x1818: 0x0040, 0x1819: 0x0040, 0x181a: 0x0040, 0x181b: 0x0040, 0x181c: 0x0040, 0x181d: 0x0008, + 0x181e: 0x0008, 0x181f: 0x0008, 0x1820: 0x0008, 0x1821: 0x0008, 0x1822: 0x3008, 0x1823: 0x3008, + 0x1824: 0x0040, 0x1825: 0x0040, 0x1826: 0x3308, 0x1827: 0x3308, 0x1828: 0x3308, 0x1829: 0x3308, + 0x182a: 0x3308, 0x182b: 0x3308, 0x182c: 0x3308, 0x182d: 0x0040, 0x182e: 0x0040, 0x182f: 0x0040, + 0x1830: 0x3308, 0x1831: 0x3308, 0x1832: 0x3308, 0x1833: 0x3308, 0x1834: 0x3308, 0x1835: 0x0040, + 0x1836: 0x0040, 0x1837: 0x0040, 0x1838: 0x0040, 0x1839: 0x0040, 0x183a: 0x0040, 0x183b: 0x0040, + 0x183c: 0x0040, 0x183d: 0x0040, 0x183e: 0x0040, 0x183f: 0x0040, + // Block 0x61, offset 0x1840 + 0x1840: 0x0039, 0x1841: 0x0ee9, 0x1842: 0x1159, 0x1843: 0x0ef9, 0x1844: 0x0f09, 0x1845: 0x1199, + 0x1846: 0x0f31, 0x1847: 0x0249, 0x1848: 0x0f41, 0x1849: 0x0259, 0x184a: 0x0f51, 0x184b: 0x0359, + 0x184c: 0x0f61, 0x184d: 0x0f71, 0x184e: 0x00d9, 0x184f: 0x0f99, 0x1850: 0x2039, 0x1851: 0x0269, + 0x1852: 0x01d9, 0x1853: 0x0fa9, 0x1854: 0x0fb9, 0x1855: 0x1089, 0x1856: 0x0279, 0x1857: 0x0369, + 0x1858: 0x0289, 0x1859: 0x13d1, 0x185a: 0x0039, 0x185b: 0x0ee9, 0x185c: 0x1159, 0x185d: 0x0ef9, + 0x185e: 0x0f09, 0x185f: 0x1199, 0x1860: 0x0f31, 0x1861: 0x0249, 0x1862: 0x0f41, 0x1863: 0x0259, + 0x1864: 0x0f51, 0x1865: 0x0359, 0x1866: 0x0f61, 0x1867: 0x0f71, 0x1868: 0x00d9, 0x1869: 0x0f99, + 0x186a: 0x2039, 0x186b: 0x0269, 0x186c: 0x01d9, 0x186d: 0x0fa9, 0x186e: 0x0fb9, 0x186f: 0x1089, + 0x1870: 0x0279, 0x1871: 0x0369, 0x1872: 0x0289, 0x1873: 0x13d1, 0x1874: 0x0039, 0x1875: 0x0ee9, + 0x1876: 0x1159, 0x1877: 0x0ef9, 0x1878: 0x0f09, 0x1879: 0x1199, 0x187a: 0x0f31, 0x187b: 0x0249, + 0x187c: 0x0f41, 0x187d: 0x0259, 0x187e: 0x0f51, 0x187f: 0x0359, + // Block 0x62, offset 0x1880 + 0x1880: 0x0f61, 0x1881: 0x0f71, 0x1882: 0x00d9, 0x1883: 0x0f99, 0x1884: 0x2039, 0x1885: 0x0269, + 0x1886: 0x01d9, 0x1887: 0x0fa9, 0x1888: 0x0fb9, 0x1889: 0x1089, 0x188a: 0x0279, 0x188b: 0x0369, + 0x188c: 0x0289, 0x188d: 0x13d1, 0x188e: 0x0039, 0x188f: 0x0ee9, 0x1890: 0x1159, 0x1891: 0x0ef9, + 0x1892: 0x0f09, 0x1893: 0x1199, 0x1894: 0x0f31, 0x1895: 0x0040, 0x1896: 0x0f41, 0x1897: 0x0259, + 0x1898: 0x0f51, 0x1899: 0x0359, 0x189a: 0x0f61, 0x189b: 0x0f71, 0x189c: 0x00d9, 0x189d: 0x0f99, + 0x189e: 0x2039, 0x189f: 0x0269, 0x18a0: 0x01d9, 0x18a1: 0x0fa9, 0x18a2: 0x0fb9, 0x18a3: 0x1089, + 0x18a4: 0x0279, 0x18a5: 0x0369, 0x18a6: 0x0289, 0x18a7: 0x13d1, 0x18a8: 0x0039, 0x18a9: 0x0ee9, + 0x18aa: 0x1159, 0x18ab: 0x0ef9, 0x18ac: 0x0f09, 0x18ad: 0x1199, 0x18ae: 0x0f31, 0x18af: 0x0249, + 0x18b0: 0x0f41, 0x18b1: 0x0259, 0x18b2: 0x0f51, 0x18b3: 0x0359, 0x18b4: 0x0f61, 0x18b5: 0x0f71, + 0x18b6: 0x00d9, 0x18b7: 0x0f99, 0x18b8: 0x2039, 0x18b9: 0x0269, 0x18ba: 0x01d9, 0x18bb: 0x0fa9, + 0x18bc: 0x0fb9, 0x18bd: 0x1089, 0x18be: 0x0279, 0x18bf: 0x0369, + // Block 0x63, offset 0x18c0 + 0x18c0: 0x0289, 0x18c1: 0x13d1, 0x18c2: 0x0039, 0x18c3: 0x0ee9, 0x18c4: 0x1159, 0x18c5: 0x0ef9, + 0x18c6: 0x0f09, 0x18c7: 0x1199, 0x18c8: 0x0f31, 0x18c9: 0x0249, 0x18ca: 0x0f41, 0x18cb: 0x0259, + 0x18cc: 0x0f51, 0x18cd: 0x0359, 0x18ce: 0x0f61, 0x18cf: 0x0f71, 0x18d0: 0x00d9, 0x18d1: 0x0f99, + 0x18d2: 0x2039, 0x18d3: 0x0269, 0x18d4: 0x01d9, 0x18d5: 0x0fa9, 0x18d6: 0x0fb9, 0x18d7: 0x1089, + 0x18d8: 0x0279, 0x18d9: 0x0369, 0x18da: 0x0289, 0x18db: 0x13d1, 0x18dc: 0x0039, 0x18dd: 0x0040, + 0x18de: 0x1159, 0x18df: 0x0ef9, 0x18e0: 0x0040, 0x18e1: 0x0040, 0x18e2: 0x0f31, 0x18e3: 0x0040, + 0x18e4: 0x0040, 0x18e5: 0x0259, 0x18e6: 0x0f51, 0x18e7: 0x0040, 0x18e8: 0x0040, 0x18e9: 0x0f71, + 0x18ea: 0x00d9, 0x18eb: 0x0f99, 0x18ec: 0x2039, 0x18ed: 0x0040, 0x18ee: 0x01d9, 0x18ef: 0x0fa9, + 0x18f0: 0x0fb9, 0x18f1: 0x1089, 0x18f2: 0x0279, 0x18f3: 0x0369, 0x18f4: 0x0289, 0x18f5: 0x13d1, + 0x18f6: 0x0039, 0x18f7: 0x0ee9, 0x18f8: 0x1159, 0x18f9: 0x0ef9, 0x18fa: 0x0040, 0x18fb: 0x1199, + 0x18fc: 0x0040, 0x18fd: 0x0249, 0x18fe: 0x0f41, 0x18ff: 0x0259, + // Block 0x64, offset 0x1900 + 0x1900: 0x0f51, 0x1901: 0x0359, 0x1902: 0x0f61, 0x1903: 0x0f71, 0x1904: 0x0040, 0x1905: 0x0f99, + 0x1906: 0x2039, 0x1907: 0x0269, 0x1908: 0x01d9, 0x1909: 0x0fa9, 0x190a: 0x0fb9, 0x190b: 0x1089, + 0x190c: 0x0279, 0x190d: 0x0369, 0x190e: 0x0289, 0x190f: 0x13d1, 0x1910: 0x0039, 0x1911: 0x0ee9, + 0x1912: 0x1159, 0x1913: 0x0ef9, 0x1914: 0x0f09, 0x1915: 0x1199, 0x1916: 0x0f31, 0x1917: 0x0249, + 0x1918: 0x0f41, 0x1919: 0x0259, 0x191a: 0x0f51, 0x191b: 0x0359, 0x191c: 0x0f61, 0x191d: 0x0f71, + 0x191e: 0x00d9, 0x191f: 0x0f99, 0x1920: 0x2039, 0x1921: 0x0269, 0x1922: 0x01d9, 0x1923: 0x0fa9, + 0x1924: 0x0fb9, 0x1925: 0x1089, 0x1926: 0x0279, 0x1927: 0x0369, 0x1928: 0x0289, 0x1929: 0x13d1, + 0x192a: 0x0039, 0x192b: 0x0ee9, 0x192c: 0x1159, 0x192d: 0x0ef9, 0x192e: 0x0f09, 0x192f: 0x1199, + 0x1930: 0x0f31, 0x1931: 0x0249, 0x1932: 0x0f41, 0x1933: 0x0259, 0x1934: 0x0f51, 0x1935: 0x0359, + 0x1936: 0x0f61, 0x1937: 0x0f71, 0x1938: 0x00d9, 0x1939: 0x0f99, 0x193a: 0x2039, 0x193b: 0x0269, + 0x193c: 0x01d9, 0x193d: 0x0fa9, 0x193e: 0x0fb9, 0x193f: 0x1089, + // Block 0x65, offset 0x1940 + 0x1940: 0x0279, 0x1941: 0x0369, 0x1942: 0x0289, 0x1943: 0x13d1, 0x1944: 0x0039, 0x1945: 0x0ee9, + 0x1946: 0x0040, 0x1947: 0x0ef9, 0x1948: 0x0f09, 0x1949: 0x1199, 0x194a: 0x0f31, 0x194b: 0x0040, + 0x194c: 0x0040, 0x194d: 0x0259, 0x194e: 0x0f51, 0x194f: 0x0359, 0x1950: 0x0f61, 0x1951: 0x0f71, + 0x1952: 0x00d9, 0x1953: 0x0f99, 0x1954: 0x2039, 0x1955: 0x0040, 0x1956: 0x01d9, 0x1957: 0x0fa9, + 0x1958: 0x0fb9, 0x1959: 0x1089, 0x195a: 0x0279, 0x195b: 0x0369, 0x195c: 0x0289, 0x195d: 0x0040, + 0x195e: 0x0039, 0x195f: 0x0ee9, 0x1960: 0x1159, 0x1961: 0x0ef9, 0x1962: 0x0f09, 0x1963: 0x1199, + 0x1964: 0x0f31, 0x1965: 0x0249, 0x1966: 0x0f41, 0x1967: 0x0259, 0x1968: 0x0f51, 0x1969: 0x0359, + 0x196a: 0x0f61, 0x196b: 0x0f71, 0x196c: 0x00d9, 0x196d: 0x0f99, 0x196e: 0x2039, 0x196f: 0x0269, + 0x1970: 0x01d9, 0x1971: 0x0fa9, 0x1972: 0x0fb9, 0x1973: 0x1089, 0x1974: 0x0279, 0x1975: 0x0369, + 0x1976: 0x0289, 0x1977: 0x13d1, 0x1978: 0x0039, 0x1979: 0x0ee9, 0x197a: 0x0040, 0x197b: 0x0ef9, + 0x197c: 0x0f09, 0x197d: 0x1199, 0x197e: 0x0f31, 0x197f: 0x0040, + // Block 0x66, offset 0x1980 + 0x1980: 0x0f41, 0x1981: 0x0259, 0x1982: 0x0f51, 0x1983: 0x0359, 0x1984: 0x0f61, 0x1985: 0x0040, + 0x1986: 0x00d9, 0x1987: 0x0040, 0x1988: 0x0040, 0x1989: 0x0040, 0x198a: 0x01d9, 0x198b: 0x0fa9, + 0x198c: 0x0fb9, 0x198d: 0x1089, 0x198e: 0x0279, 0x198f: 0x0369, 0x1990: 0x0289, 0x1991: 0x0040, + 0x1992: 0x0039, 0x1993: 0x0ee9, 0x1994: 0x1159, 0x1995: 0x0ef9, 0x1996: 0x0f09, 0x1997: 0x1199, + 0x1998: 0x0f31, 0x1999: 0x0249, 0x199a: 0x0f41, 0x199b: 0x0259, 0x199c: 0x0f51, 0x199d: 0x0359, + 0x199e: 0x0f61, 0x199f: 0x0f71, 0x19a0: 0x00d9, 0x19a1: 0x0f99, 0x19a2: 0x2039, 0x19a3: 0x0269, + 0x19a4: 0x01d9, 0x19a5: 0x0fa9, 0x19a6: 0x0fb9, 0x19a7: 0x1089, 0x19a8: 0x0279, 0x19a9: 0x0369, + 0x19aa: 0x0289, 0x19ab: 0x13d1, 0x19ac: 0x0039, 0x19ad: 0x0ee9, 0x19ae: 0x1159, 0x19af: 0x0ef9, + 0x19b0: 0x0f09, 0x19b1: 0x1199, 0x19b2: 0x0f31, 0x19b3: 0x0249, 0x19b4: 0x0f41, 0x19b5: 0x0259, + 0x19b6: 0x0f51, 0x19b7: 0x0359, 0x19b8: 0x0f61, 0x19b9: 0x0f71, 0x19ba: 0x00d9, 0x19bb: 0x0f99, + 0x19bc: 0x2039, 0x19bd: 0x0269, 0x19be: 0x01d9, 0x19bf: 0x0fa9, + // Block 0x67, offset 0x19c0 + 0x19c0: 0x0fb9, 0x19c1: 0x1089, 0x19c2: 0x0279, 0x19c3: 0x0369, 0x19c4: 0x0289, 0x19c5: 0x13d1, + 0x19c6: 0x0039, 0x19c7: 0x0ee9, 0x19c8: 0x1159, 0x19c9: 0x0ef9, 0x19ca: 0x0f09, 0x19cb: 0x1199, + 0x19cc: 0x0f31, 0x19cd: 0x0249, 0x19ce: 0x0f41, 0x19cf: 0x0259, 0x19d0: 0x0f51, 0x19d1: 0x0359, + 0x19d2: 0x0f61, 0x19d3: 0x0f71, 0x19d4: 0x00d9, 0x19d5: 0x0f99, 0x19d6: 0x2039, 0x19d7: 0x0269, + 0x19d8: 0x01d9, 0x19d9: 0x0fa9, 0x19da: 0x0fb9, 0x19db: 0x1089, 0x19dc: 0x0279, 0x19dd: 0x0369, + 0x19de: 0x0289, 0x19df: 0x13d1, 0x19e0: 0x0039, 0x19e1: 0x0ee9, 0x19e2: 0x1159, 0x19e3: 0x0ef9, + 0x19e4: 0x0f09, 0x19e5: 0x1199, 0x19e6: 0x0f31, 0x19e7: 0x0249, 0x19e8: 0x0f41, 0x19e9: 0x0259, + 0x19ea: 0x0f51, 0x19eb: 0x0359, 0x19ec: 0x0f61, 0x19ed: 0x0f71, 0x19ee: 0x00d9, 0x19ef: 0x0f99, + 0x19f0: 0x2039, 0x19f1: 0x0269, 0x19f2: 0x01d9, 0x19f3: 0x0fa9, 0x19f4: 0x0fb9, 0x19f5: 0x1089, + 0x19f6: 0x0279, 0x19f7: 0x0369, 0x19f8: 0x0289, 0x19f9: 0x13d1, 0x19fa: 0x0039, 0x19fb: 0x0ee9, + 0x19fc: 0x1159, 0x19fd: 0x0ef9, 0x19fe: 0x0f09, 0x19ff: 0x1199, + // Block 0x68, offset 0x1a00 + 0x1a00: 0x0f31, 0x1a01: 0x0249, 0x1a02: 0x0f41, 0x1a03: 0x0259, 0x1a04: 0x0f51, 0x1a05: 0x0359, + 0x1a06: 0x0f61, 0x1a07: 0x0f71, 0x1a08: 0x00d9, 0x1a09: 0x0f99, 0x1a0a: 0x2039, 0x1a0b: 0x0269, + 0x1a0c: 0x01d9, 0x1a0d: 0x0fa9, 0x1a0e: 0x0fb9, 0x1a0f: 0x1089, 0x1a10: 0x0279, 0x1a11: 0x0369, + 0x1a12: 0x0289, 0x1a13: 0x13d1, 0x1a14: 0x0039, 0x1a15: 0x0ee9, 0x1a16: 0x1159, 0x1a17: 0x0ef9, + 0x1a18: 0x0f09, 0x1a19: 0x1199, 0x1a1a: 0x0f31, 0x1a1b: 0x0249, 0x1a1c: 0x0f41, 0x1a1d: 0x0259, + 0x1a1e: 0x0f51, 0x1a1f: 0x0359, 0x1a20: 0x0f61, 0x1a21: 0x0f71, 0x1a22: 0x00d9, 0x1a23: 0x0f99, + 0x1a24: 0x2039, 0x1a25: 0x0269, 0x1a26: 0x01d9, 0x1a27: 0x0fa9, 0x1a28: 0x0fb9, 0x1a29: 0x1089, + 0x1a2a: 0x0279, 0x1a2b: 0x0369, 0x1a2c: 0x0289, 0x1a2d: 0x13d1, 0x1a2e: 0x0039, 0x1a2f: 0x0ee9, + 0x1a30: 0x1159, 0x1a31: 0x0ef9, 0x1a32: 0x0f09, 0x1a33: 0x1199, 0x1a34: 0x0f31, 0x1a35: 0x0249, + 0x1a36: 0x0f41, 0x1a37: 0x0259, 0x1a38: 0x0f51, 0x1a39: 0x0359, 0x1a3a: 0x0f61, 0x1a3b: 0x0f71, + 0x1a3c: 0x00d9, 0x1a3d: 0x0f99, 0x1a3e: 0x2039, 0x1a3f: 0x0269, + // Block 0x69, offset 0x1a40 + 0x1a40: 0x01d9, 0x1a41: 0x0fa9, 0x1a42: 0x0fb9, 0x1a43: 0x1089, 0x1a44: 0x0279, 0x1a45: 0x0369, + 0x1a46: 0x0289, 0x1a47: 0x13d1, 0x1a48: 0x0039, 0x1a49: 0x0ee9, 0x1a4a: 0x1159, 0x1a4b: 0x0ef9, + 0x1a4c: 0x0f09, 0x1a4d: 0x1199, 0x1a4e: 0x0f31, 0x1a4f: 0x0249, 0x1a50: 0x0f41, 0x1a51: 0x0259, + 0x1a52: 0x0f51, 0x1a53: 0x0359, 0x1a54: 0x0f61, 0x1a55: 0x0f71, 0x1a56: 0x00d9, 0x1a57: 0x0f99, + 0x1a58: 0x2039, 0x1a59: 0x0269, 0x1a5a: 0x01d9, 0x1a5b: 0x0fa9, 0x1a5c: 0x0fb9, 0x1a5d: 0x1089, + 0x1a5e: 0x0279, 0x1a5f: 0x0369, 0x1a60: 0x0289, 0x1a61: 0x13d1, 0x1a62: 0x0039, 0x1a63: 0x0ee9, + 0x1a64: 0x1159, 0x1a65: 0x0ef9, 0x1a66: 0x0f09, 0x1a67: 0x1199, 0x1a68: 0x0f31, 0x1a69: 0x0249, + 0x1a6a: 0x0f41, 0x1a6b: 0x0259, 0x1a6c: 0x0f51, 0x1a6d: 0x0359, 0x1a6e: 0x0f61, 0x1a6f: 0x0f71, + 0x1a70: 0x00d9, 0x1a71: 0x0f99, 0x1a72: 0x2039, 0x1a73: 0x0269, 0x1a74: 0x01d9, 0x1a75: 0x0fa9, + 0x1a76: 0x0fb9, 0x1a77: 0x1089, 0x1a78: 0x0279, 0x1a79: 0x0369, 0x1a7a: 0x0289, 0x1a7b: 0x13d1, + 0x1a7c: 0x0039, 0x1a7d: 0x0ee9, 0x1a7e: 0x1159, 0x1a7f: 0x0ef9, + // Block 0x6a, offset 0x1a80 + 0x1a80: 0x0f09, 0x1a81: 0x1199, 0x1a82: 0x0f31, 0x1a83: 0x0249, 0x1a84: 0x0f41, 0x1a85: 0x0259, + 0x1a86: 0x0f51, 0x1a87: 0x0359, 0x1a88: 0x0f61, 0x1a89: 0x0f71, 0x1a8a: 0x00d9, 0x1a8b: 0x0f99, + 0x1a8c: 0x2039, 0x1a8d: 0x0269, 0x1a8e: 0x01d9, 0x1a8f: 0x0fa9, 0x1a90: 0x0fb9, 0x1a91: 0x1089, + 0x1a92: 0x0279, 0x1a93: 0x0369, 0x1a94: 0x0289, 0x1a95: 0x13d1, 0x1a96: 0x0039, 0x1a97: 0x0ee9, + 0x1a98: 0x1159, 0x1a99: 0x0ef9, 0x1a9a: 0x0f09, 0x1a9b: 0x1199, 0x1a9c: 0x0f31, 0x1a9d: 0x0249, + 0x1a9e: 0x0f41, 0x1a9f: 0x0259, 0x1aa0: 0x0f51, 0x1aa1: 0x0359, 0x1aa2: 0x0f61, 0x1aa3: 0x0f71, + 0x1aa4: 0x00d9, 0x1aa5: 0x0f99, 0x1aa6: 0x2039, 0x1aa7: 0x0269, 0x1aa8: 0x01d9, 0x1aa9: 0x0fa9, + 0x1aaa: 0x0fb9, 0x1aab: 0x1089, 0x1aac: 0x0279, 0x1aad: 0x0369, 0x1aae: 0x0289, 0x1aaf: 0x13d1, + 0x1ab0: 0x0039, 0x1ab1: 0x0ee9, 0x1ab2: 0x1159, 0x1ab3: 0x0ef9, 0x1ab4: 0x0f09, 0x1ab5: 0x1199, + 0x1ab6: 0x0f31, 0x1ab7: 0x0249, 0x1ab8: 0x0f41, 0x1ab9: 0x0259, 0x1aba: 0x0f51, 0x1abb: 0x0359, + 0x1abc: 0x0f61, 0x1abd: 0x0f71, 0x1abe: 0x00d9, 0x1abf: 0x0f99, + // Block 0x6b, offset 0x1ac0 + 0x1ac0: 0x2039, 0x1ac1: 0x0269, 0x1ac2: 0x01d9, 0x1ac3: 0x0fa9, 0x1ac4: 0x0fb9, 0x1ac5: 0x1089, + 0x1ac6: 0x0279, 0x1ac7: 0x0369, 0x1ac8: 0x0289, 0x1ac9: 0x13d1, 0x1aca: 0x0039, 0x1acb: 0x0ee9, + 0x1acc: 0x1159, 0x1acd: 0x0ef9, 0x1ace: 0x0f09, 0x1acf: 0x1199, 0x1ad0: 0x0f31, 0x1ad1: 0x0249, + 0x1ad2: 0x0f41, 0x1ad3: 0x0259, 0x1ad4: 0x0f51, 0x1ad5: 0x0359, 0x1ad6: 0x0f61, 0x1ad7: 0x0f71, + 0x1ad8: 0x00d9, 0x1ad9: 0x0f99, 0x1ada: 0x2039, 0x1adb: 0x0269, 0x1adc: 0x01d9, 0x1add: 0x0fa9, + 0x1ade: 0x0fb9, 0x1adf: 0x1089, 0x1ae0: 0x0279, 0x1ae1: 0x0369, 0x1ae2: 0x0289, 0x1ae3: 0x13d1, + 0x1ae4: 0xba81, 0x1ae5: 0xba99, 0x1ae6: 0x0040, 0x1ae7: 0x0040, 0x1ae8: 0xbab1, 0x1ae9: 0x1099, + 0x1aea: 0x10b1, 0x1aeb: 0x10c9, 0x1aec: 0xbac9, 0x1aed: 0xbae1, 0x1aee: 0xbaf9, 0x1aef: 0x1429, + 0x1af0: 0x1a31, 0x1af1: 0xbb11, 0x1af2: 0xbb29, 0x1af3: 0xbb41, 0x1af4: 0xbb59, 0x1af5: 0xbb71, + 0x1af6: 0xbb89, 0x1af7: 0x2109, 0x1af8: 0x1111, 0x1af9: 0x1429, 0x1afa: 0xbba1, 0x1afb: 0xbbb9, + 0x1afc: 0xbbd1, 0x1afd: 0x10e1, 0x1afe: 0x10f9, 0x1aff: 0xbbe9, + // Block 0x6c, offset 0x1b00 + 0x1b00: 0x2079, 0x1b01: 0xbc01, 0x1b02: 0xbab1, 0x1b03: 0x1099, 0x1b04: 0x10b1, 0x1b05: 0x10c9, + 0x1b06: 0xbac9, 0x1b07: 0xbae1, 0x1b08: 0xbaf9, 0x1b09: 0x1429, 0x1b0a: 0x1a31, 0x1b0b: 0xbb11, + 0x1b0c: 0xbb29, 0x1b0d: 0xbb41, 0x1b0e: 0xbb59, 0x1b0f: 0xbb71, 0x1b10: 0xbb89, 0x1b11: 0x2109, + 0x1b12: 0x1111, 0x1b13: 0xbba1, 0x1b14: 0xbba1, 0x1b15: 0xbbb9, 0x1b16: 0xbbd1, 0x1b17: 0x10e1, + 0x1b18: 0x10f9, 0x1b19: 0xbbe9, 0x1b1a: 0x2079, 0x1b1b: 0xbc21, 0x1b1c: 0xbac9, 0x1b1d: 0x1429, + 0x1b1e: 0xbb11, 0x1b1f: 0x10e1, 0x1b20: 0x1111, 0x1b21: 0x2109, 0x1b22: 0xbab1, 0x1b23: 0x1099, + 0x1b24: 0x10b1, 0x1b25: 0x10c9, 0x1b26: 0xbac9, 0x1b27: 0xbae1, 0x1b28: 0xbaf9, 0x1b29: 0x1429, + 0x1b2a: 0x1a31, 0x1b2b: 0xbb11, 0x1b2c: 0xbb29, 0x1b2d: 0xbb41, 0x1b2e: 0xbb59, 0x1b2f: 0xbb71, + 0x1b30: 0xbb89, 0x1b31: 0x2109, 0x1b32: 0x1111, 0x1b33: 0x1429, 0x1b34: 0xbba1, 0x1b35: 0xbbb9, + 0x1b36: 0xbbd1, 0x1b37: 0x10e1, 0x1b38: 0x10f9, 0x1b39: 0xbbe9, 0x1b3a: 0x2079, 0x1b3b: 0xbc01, + 0x1b3c: 0xbab1, 0x1b3d: 0x1099, 0x1b3e: 0x10b1, 0x1b3f: 0x10c9, + // Block 0x6d, offset 0x1b40 + 0x1b40: 0xbac9, 0x1b41: 0xbae1, 0x1b42: 0xbaf9, 0x1b43: 0x1429, 0x1b44: 0x1a31, 0x1b45: 0xbb11, + 0x1b46: 0xbb29, 0x1b47: 0xbb41, 0x1b48: 0xbb59, 0x1b49: 0xbb71, 0x1b4a: 0xbb89, 0x1b4b: 0x2109, + 0x1b4c: 0x1111, 0x1b4d: 0xbba1, 0x1b4e: 0xbba1, 0x1b4f: 0xbbb9, 0x1b50: 0xbbd1, 0x1b51: 0x10e1, + 0x1b52: 0x10f9, 0x1b53: 0xbbe9, 0x1b54: 0x2079, 0x1b55: 0xbc21, 0x1b56: 0xbac9, 0x1b57: 0x1429, + 0x1b58: 0xbb11, 0x1b59: 0x10e1, 0x1b5a: 0x1111, 0x1b5b: 0x2109, 0x1b5c: 0xbab1, 0x1b5d: 0x1099, + 0x1b5e: 0x10b1, 0x1b5f: 0x10c9, 0x1b60: 0xbac9, 0x1b61: 0xbae1, 0x1b62: 0xbaf9, 0x1b63: 0x1429, + 0x1b64: 0x1a31, 0x1b65: 0xbb11, 0x1b66: 0xbb29, 0x1b67: 0xbb41, 0x1b68: 0xbb59, 0x1b69: 0xbb71, + 0x1b6a: 0xbb89, 0x1b6b: 0x2109, 0x1b6c: 0x1111, 0x1b6d: 0x1429, 0x1b6e: 0xbba1, 0x1b6f: 0xbbb9, + 0x1b70: 0xbbd1, 0x1b71: 0x10e1, 0x1b72: 0x10f9, 0x1b73: 0xbbe9, 0x1b74: 0x2079, 0x1b75: 0xbc01, + 0x1b76: 0xbab1, 0x1b77: 0x1099, 0x1b78: 0x10b1, 0x1b79: 0x10c9, 0x1b7a: 0xbac9, 0x1b7b: 0xbae1, + 0x1b7c: 0xbaf9, 0x1b7d: 0x1429, 0x1b7e: 0x1a31, 0x1b7f: 0xbb11, + // Block 0x6e, offset 0x1b80 + 0x1b80: 0xbb29, 0x1b81: 0xbb41, 0x1b82: 0xbb59, 0x1b83: 0xbb71, 0x1b84: 0xbb89, 0x1b85: 0x2109, + 0x1b86: 0x1111, 0x1b87: 0xbba1, 0x1b88: 0xbba1, 0x1b89: 0xbbb9, 0x1b8a: 0xbbd1, 0x1b8b: 0x10e1, + 0x1b8c: 0x10f9, 0x1b8d: 0xbbe9, 0x1b8e: 0x2079, 0x1b8f: 0xbc21, 0x1b90: 0xbac9, 0x1b91: 0x1429, + 0x1b92: 0xbb11, 0x1b93: 0x10e1, 0x1b94: 0x1111, 0x1b95: 0x2109, 0x1b96: 0xbab1, 0x1b97: 0x1099, + 0x1b98: 0x10b1, 0x1b99: 0x10c9, 0x1b9a: 0xbac9, 0x1b9b: 0xbae1, 0x1b9c: 0xbaf9, 0x1b9d: 0x1429, + 0x1b9e: 0x1a31, 0x1b9f: 0xbb11, 0x1ba0: 0xbb29, 0x1ba1: 0xbb41, 0x1ba2: 0xbb59, 0x1ba3: 0xbb71, + 0x1ba4: 0xbb89, 0x1ba5: 0x2109, 0x1ba6: 0x1111, 0x1ba7: 0x1429, 0x1ba8: 0xbba1, 0x1ba9: 0xbbb9, + 0x1baa: 0xbbd1, 0x1bab: 0x10e1, 0x1bac: 0x10f9, 0x1bad: 0xbbe9, 0x1bae: 0x2079, 0x1baf: 0xbc01, + 0x1bb0: 0xbab1, 0x1bb1: 0x1099, 0x1bb2: 0x10b1, 0x1bb3: 0x10c9, 0x1bb4: 0xbac9, 0x1bb5: 0xbae1, + 0x1bb6: 0xbaf9, 0x1bb7: 0x1429, 0x1bb8: 0x1a31, 0x1bb9: 0xbb11, 0x1bba: 0xbb29, 0x1bbb: 0xbb41, + 0x1bbc: 0xbb59, 0x1bbd: 0xbb71, 0x1bbe: 0xbb89, 0x1bbf: 0x2109, + // Block 0x6f, offset 0x1bc0 + 0x1bc0: 0x1111, 0x1bc1: 0xbba1, 0x1bc2: 0xbba1, 0x1bc3: 0xbbb9, 0x1bc4: 0xbbd1, 0x1bc5: 0x10e1, + 0x1bc6: 0x10f9, 0x1bc7: 0xbbe9, 0x1bc8: 0x2079, 0x1bc9: 0xbc21, 0x1bca: 0xbac9, 0x1bcb: 0x1429, + 0x1bcc: 0xbb11, 0x1bcd: 0x10e1, 0x1bce: 0x1111, 0x1bcf: 0x2109, 0x1bd0: 0xbab1, 0x1bd1: 0x1099, + 0x1bd2: 0x10b1, 0x1bd3: 0x10c9, 0x1bd4: 0xbac9, 0x1bd5: 0xbae1, 0x1bd6: 0xbaf9, 0x1bd7: 0x1429, + 0x1bd8: 0x1a31, 0x1bd9: 0xbb11, 0x1bda: 0xbb29, 0x1bdb: 0xbb41, 0x1bdc: 0xbb59, 0x1bdd: 0xbb71, + 0x1bde: 0xbb89, 0x1bdf: 0x2109, 0x1be0: 0x1111, 0x1be1: 0x1429, 0x1be2: 0xbba1, 0x1be3: 0xbbb9, + 0x1be4: 0xbbd1, 0x1be5: 0x10e1, 0x1be6: 0x10f9, 0x1be7: 0xbbe9, 0x1be8: 0x2079, 0x1be9: 0xbc01, + 0x1bea: 0xbab1, 0x1beb: 0x1099, 0x1bec: 0x10b1, 0x1bed: 0x10c9, 0x1bee: 0xbac9, 0x1bef: 0xbae1, + 0x1bf0: 0xbaf9, 0x1bf1: 0x1429, 0x1bf2: 0x1a31, 0x1bf3: 0xbb11, 0x1bf4: 0xbb29, 0x1bf5: 0xbb41, + 0x1bf6: 0xbb59, 0x1bf7: 0xbb71, 0x1bf8: 0xbb89, 0x1bf9: 0x2109, 0x1bfa: 0x1111, 0x1bfb: 0xbba1, + 0x1bfc: 0xbba1, 0x1bfd: 0xbbb9, 0x1bfe: 0xbbd1, 0x1bff: 0x10e1, + // Block 0x70, offset 0x1c00 + 0x1c00: 0x10f9, 0x1c01: 0xbbe9, 0x1c02: 0x2079, 0x1c03: 0xbc21, 0x1c04: 0xbac9, 0x1c05: 0x1429, + 0x1c06: 0xbb11, 0x1c07: 0x10e1, 0x1c08: 0x1111, 0x1c09: 0x2109, 0x1c0a: 0xbc41, 0x1c0b: 0xbc41, + 0x1c0c: 0x0040, 0x1c0d: 0x0040, 0x1c0e: 0x1f41, 0x1c0f: 0x00c9, 0x1c10: 0x0069, 0x1c11: 0x0079, + 0x1c12: 0x1f51, 0x1c13: 0x1f61, 0x1c14: 0x1f71, 0x1c15: 0x1f81, 0x1c16: 0x1f91, 0x1c17: 0x1fa1, + 0x1c18: 0x1f41, 0x1c19: 0x00c9, 0x1c1a: 0x0069, 0x1c1b: 0x0079, 0x1c1c: 0x1f51, 0x1c1d: 0x1f61, + 0x1c1e: 0x1f71, 0x1c1f: 0x1f81, 0x1c20: 0x1f91, 0x1c21: 0x1fa1, 0x1c22: 0x1f41, 0x1c23: 0x00c9, + 0x1c24: 0x0069, 0x1c25: 0x0079, 0x1c26: 0x1f51, 0x1c27: 0x1f61, 0x1c28: 0x1f71, 0x1c29: 0x1f81, + 0x1c2a: 0x1f91, 0x1c2b: 0x1fa1, 0x1c2c: 0x1f41, 0x1c2d: 0x00c9, 0x1c2e: 0x0069, 0x1c2f: 0x0079, + 0x1c30: 0x1f51, 0x1c31: 0x1f61, 0x1c32: 0x1f71, 0x1c33: 0x1f81, 0x1c34: 0x1f91, 0x1c35: 0x1fa1, + 0x1c36: 0x1f41, 0x1c37: 0x00c9, 0x1c38: 0x0069, 0x1c39: 0x0079, 0x1c3a: 0x1f51, 0x1c3b: 0x1f61, + 0x1c3c: 0x1f71, 0x1c3d: 0x1f81, 0x1c3e: 0x1f91, 0x1c3f: 0x1fa1, + // Block 0x71, offset 0x1c40 + 0x1c40: 0xe115, 0x1c41: 0xe115, 0x1c42: 0xe135, 0x1c43: 0xe135, 0x1c44: 0xe115, 0x1c45: 0xe115, + 0x1c46: 0xe175, 0x1c47: 0xe175, 0x1c48: 0xe115, 0x1c49: 0xe115, 0x1c4a: 0xe135, 0x1c4b: 0xe135, + 0x1c4c: 0xe115, 0x1c4d: 0xe115, 0x1c4e: 0xe1f5, 0x1c4f: 0xe1f5, 0x1c50: 0xe115, 0x1c51: 0xe115, + 0x1c52: 0xe135, 0x1c53: 0xe135, 0x1c54: 0xe115, 0x1c55: 0xe115, 0x1c56: 0xe175, 0x1c57: 0xe175, + 0x1c58: 0xe115, 0x1c59: 0xe115, 0x1c5a: 0xe135, 0x1c5b: 0xe135, 0x1c5c: 0xe115, 0x1c5d: 0xe115, + 0x1c5e: 0x8b05, 0x1c5f: 0x8b05, 0x1c60: 0x04b5, 0x1c61: 0x04b5, 0x1c62: 0x0a08, 0x1c63: 0x0a08, + 0x1c64: 0x0a08, 0x1c65: 0x0a08, 0x1c66: 0x0a08, 0x1c67: 0x0a08, 0x1c68: 0x0a08, 0x1c69: 0x0a08, + 0x1c6a: 0x0a08, 0x1c6b: 0x0a08, 0x1c6c: 0x0a08, 0x1c6d: 0x0a08, 0x1c6e: 0x0a08, 0x1c6f: 0x0a08, + 0x1c70: 0x0a08, 0x1c71: 0x0a08, 0x1c72: 0x0a08, 0x1c73: 0x0a08, 0x1c74: 0x0a08, 0x1c75: 0x0a08, + 0x1c76: 0x0a08, 0x1c77: 0x0a08, 0x1c78: 0x0a08, 0x1c79: 0x0a08, 0x1c7a: 0x0a08, 0x1c7b: 0x0a08, + 0x1c7c: 0x0a08, 0x1c7d: 0x0a08, 0x1c7e: 0x0a08, 0x1c7f: 0x0a08, + // Block 0x72, offset 0x1c80 + 0x1c80: 0xb189, 0x1c81: 0xb1a1, 0x1c82: 0xb201, 0x1c83: 0xb249, 0x1c84: 0x0040, 0x1c85: 0xb411, + 0x1c86: 0xb291, 0x1c87: 0xb219, 0x1c88: 0xb309, 0x1c89: 0xb429, 0x1c8a: 0xb399, 0x1c8b: 0xb3b1, + 0x1c8c: 0xb3c9, 0x1c8d: 0xb3e1, 0x1c8e: 0xb2a9, 0x1c8f: 0xb339, 0x1c90: 0xb369, 0x1c91: 0xb2d9, + 0x1c92: 0xb381, 0x1c93: 0xb279, 0x1c94: 0xb2c1, 0x1c95: 0xb1d1, 0x1c96: 0xb1e9, 0x1c97: 0xb231, + 0x1c98: 0xb261, 0x1c99: 0xb2f1, 0x1c9a: 0xb321, 0x1c9b: 0xb351, 0x1c9c: 0xbc59, 0x1c9d: 0x7949, + 0x1c9e: 0xbc71, 0x1c9f: 0xbc89, 0x1ca0: 0x0040, 0x1ca1: 0xb1a1, 0x1ca2: 0xb201, 0x1ca3: 0x0040, + 0x1ca4: 0xb3f9, 0x1ca5: 0x0040, 0x1ca6: 0x0040, 0x1ca7: 0xb219, 0x1ca8: 0x0040, 0x1ca9: 0xb429, + 0x1caa: 0xb399, 0x1cab: 0xb3b1, 0x1cac: 0xb3c9, 0x1cad: 0xb3e1, 0x1cae: 0xb2a9, 0x1caf: 0xb339, + 0x1cb0: 0xb369, 0x1cb1: 0xb2d9, 0x1cb2: 0xb381, 0x1cb3: 0x0040, 0x1cb4: 0xb2c1, 0x1cb5: 0xb1d1, + 0x1cb6: 0xb1e9, 0x1cb7: 0xb231, 0x1cb8: 0x0040, 0x1cb9: 0xb2f1, 0x1cba: 0x0040, 0x1cbb: 0xb351, + 0x1cbc: 0x0040, 0x1cbd: 0x0040, 0x1cbe: 0x0040, 0x1cbf: 0x0040, + // Block 0x73, offset 0x1cc0 + 0x1cc0: 0x0040, 0x1cc1: 0x0040, 0x1cc2: 0xb201, 0x1cc3: 0x0040, 0x1cc4: 0x0040, 0x1cc5: 0x0040, + 0x1cc6: 0x0040, 0x1cc7: 0xb219, 0x1cc8: 0x0040, 0x1cc9: 0xb429, 0x1cca: 0x0040, 0x1ccb: 0xb3b1, + 0x1ccc: 0x0040, 0x1ccd: 0xb3e1, 0x1cce: 0xb2a9, 0x1ccf: 0xb339, 0x1cd0: 0x0040, 0x1cd1: 0xb2d9, + 0x1cd2: 0xb381, 0x1cd3: 0x0040, 0x1cd4: 0xb2c1, 0x1cd5: 0x0040, 0x1cd6: 0x0040, 0x1cd7: 0xb231, + 0x1cd8: 0x0040, 0x1cd9: 0xb2f1, 0x1cda: 0x0040, 0x1cdb: 0xb351, 0x1cdc: 0x0040, 0x1cdd: 0x7949, + 0x1cde: 0x0040, 0x1cdf: 0xbc89, 0x1ce0: 0x0040, 0x1ce1: 0xb1a1, 0x1ce2: 0xb201, 0x1ce3: 0x0040, + 0x1ce4: 0xb3f9, 0x1ce5: 0x0040, 0x1ce6: 0x0040, 0x1ce7: 0xb219, 0x1ce8: 0xb309, 0x1ce9: 0xb429, + 0x1cea: 0xb399, 0x1ceb: 0x0040, 0x1cec: 0xb3c9, 0x1ced: 0xb3e1, 0x1cee: 0xb2a9, 0x1cef: 0xb339, + 0x1cf0: 0xb369, 0x1cf1: 0xb2d9, 0x1cf2: 0xb381, 0x1cf3: 0x0040, 0x1cf4: 0xb2c1, 0x1cf5: 0xb1d1, + 0x1cf6: 0xb1e9, 0x1cf7: 0xb231, 0x1cf8: 0x0040, 0x1cf9: 0xb2f1, 0x1cfa: 0xb321, 0x1cfb: 0xb351, + 0x1cfc: 0xbc59, 0x1cfd: 0x0040, 0x1cfe: 0xbc71, 0x1cff: 0x0040, + // Block 0x74, offset 0x1d00 + 0x1d00: 0xb189, 0x1d01: 0xb1a1, 0x1d02: 0xb201, 0x1d03: 0xb249, 0x1d04: 0xb3f9, 0x1d05: 0xb411, + 0x1d06: 0xb291, 0x1d07: 0xb219, 0x1d08: 0xb309, 0x1d09: 0xb429, 0x1d0a: 0x0040, 0x1d0b: 0xb3b1, + 0x1d0c: 0xb3c9, 0x1d0d: 0xb3e1, 0x1d0e: 0xb2a9, 0x1d0f: 0xb339, 0x1d10: 0xb369, 0x1d11: 0xb2d9, + 0x1d12: 0xb381, 0x1d13: 0xb279, 0x1d14: 0xb2c1, 0x1d15: 0xb1d1, 0x1d16: 0xb1e9, 0x1d17: 0xb231, + 0x1d18: 0xb261, 0x1d19: 0xb2f1, 0x1d1a: 0xb321, 0x1d1b: 0xb351, 0x1d1c: 0x0040, 0x1d1d: 0x0040, + 0x1d1e: 0x0040, 0x1d1f: 0x0040, 0x1d20: 0x0040, 0x1d21: 0xb1a1, 0x1d22: 0xb201, 0x1d23: 0xb249, + 0x1d24: 0x0040, 0x1d25: 0xb411, 0x1d26: 0xb291, 0x1d27: 0xb219, 0x1d28: 0xb309, 0x1d29: 0xb429, + 0x1d2a: 0x0040, 0x1d2b: 0xb3b1, 0x1d2c: 0xb3c9, 0x1d2d: 0xb3e1, 0x1d2e: 0xb2a9, 0x1d2f: 0xb339, + 0x1d30: 0xb369, 0x1d31: 0xb2d9, 0x1d32: 0xb381, 0x1d33: 0xb279, 0x1d34: 0xb2c1, 0x1d35: 0xb1d1, + 0x1d36: 0xb1e9, 0x1d37: 0xb231, 0x1d38: 0xb261, 0x1d39: 0xb2f1, 0x1d3a: 0xb321, 0x1d3b: 0xb351, + 0x1d3c: 0x0040, 0x1d3d: 0x0040, 0x1d3e: 0x0040, 0x1d3f: 0x0040, + // Block 0x75, offset 0x1d40 + 0x1d40: 0x0040, 0x1d41: 0xbca2, 0x1d42: 0xbcba, 0x1d43: 0xbcd2, 0x1d44: 0xbcea, 0x1d45: 0xbd02, + 0x1d46: 0xbd1a, 0x1d47: 0xbd32, 0x1d48: 0xbd4a, 0x1d49: 0xbd62, 0x1d4a: 0xbd7a, 0x1d4b: 0x0018, + 0x1d4c: 0x0018, 0x1d4d: 0x0040, 0x1d4e: 0x0040, 0x1d4f: 0x0040, 0x1d50: 0xbd92, 0x1d51: 0xbdb2, + 0x1d52: 0xbdd2, 0x1d53: 0xbdf2, 0x1d54: 0xbe12, 0x1d55: 0xbe32, 0x1d56: 0xbe52, 0x1d57: 0xbe72, + 0x1d58: 0xbe92, 0x1d59: 0xbeb2, 0x1d5a: 0xbed2, 0x1d5b: 0xbef2, 0x1d5c: 0xbf12, 0x1d5d: 0xbf32, + 0x1d5e: 0xbf52, 0x1d5f: 0xbf72, 0x1d60: 0xbf92, 0x1d61: 0xbfb2, 0x1d62: 0xbfd2, 0x1d63: 0xbff2, + 0x1d64: 0xc012, 0x1d65: 0xc032, 0x1d66: 0xc052, 0x1d67: 0xc072, 0x1d68: 0xc092, 0x1d69: 0xc0b2, + 0x1d6a: 0xc0d1, 0x1d6b: 0x1159, 0x1d6c: 0x0269, 0x1d6d: 0x6671, 0x1d6e: 0xc111, 0x1d6f: 0x0040, + 0x1d70: 0x0039, 0x1d71: 0x0ee9, 0x1d72: 0x1159, 0x1d73: 0x0ef9, 0x1d74: 0x0f09, 0x1d75: 0x1199, + 0x1d76: 0x0f31, 0x1d77: 0x0249, 0x1d78: 0x0f41, 0x1d79: 0x0259, 0x1d7a: 0x0f51, 0x1d7b: 0x0359, + 0x1d7c: 0x0f61, 0x1d7d: 0x0f71, 0x1d7e: 0x00d9, 0x1d7f: 0x0f99, + // Block 0x76, offset 0x1d80 + 0x1d80: 0x2039, 0x1d81: 0x0269, 0x1d82: 0x01d9, 0x1d83: 0x0fa9, 0x1d84: 0x0fb9, 0x1d85: 0x1089, + 0x1d86: 0x0279, 0x1d87: 0x0369, 0x1d88: 0x0289, 0x1d89: 0x13d1, 0x1d8a: 0xc129, 0x1d8b: 0x65b1, + 0x1d8c: 0xc141, 0x1d8d: 0x1441, 0x1d8e: 0xc159, 0x1d8f: 0xc179, 0x1d90: 0x0018, 0x1d91: 0x0018, + 0x1d92: 0x0018, 0x1d93: 0x0018, 0x1d94: 0x0018, 0x1d95: 0x0018, 0x1d96: 0x0018, 0x1d97: 0x0018, + 0x1d98: 0x0018, 0x1d99: 0x0018, 0x1d9a: 0x0018, 0x1d9b: 0x0018, 0x1d9c: 0x0018, 0x1d9d: 0x0018, + 0x1d9e: 0x0018, 0x1d9f: 0x0018, 0x1da0: 0x0018, 0x1da1: 0x0018, 0x1da2: 0x0018, 0x1da3: 0x0018, + 0x1da4: 0x0018, 0x1da5: 0x0018, 0x1da6: 0x0018, 0x1da7: 0x0018, 0x1da8: 0x0018, 0x1da9: 0x0018, + 0x1daa: 0xc191, 0x1dab: 0xc1a9, 0x1dac: 0x0040, 0x1dad: 0x0040, 0x1dae: 0x0040, 0x1daf: 0x0040, + 0x1db0: 0x0018, 0x1db1: 0x0018, 0x1db2: 0x0018, 0x1db3: 0x0018, 0x1db4: 0x0018, 0x1db5: 0x0018, + 0x1db6: 0x0018, 0x1db7: 0x0018, 0x1db8: 0x0018, 0x1db9: 0x0018, 0x1dba: 0x0018, 0x1dbb: 0x0018, + 0x1dbc: 0x0018, 0x1dbd: 0x0018, 0x1dbe: 0x0018, 0x1dbf: 0x0018, + // Block 0x77, offset 0x1dc0 + 0x1dc0: 0xc1d9, 0x1dc1: 0xc211, 0x1dc2: 0xc249, 0x1dc3: 0x0040, 0x1dc4: 0x0040, 0x1dc5: 0x0040, + 0x1dc6: 0x0040, 0x1dc7: 0x0040, 0x1dc8: 0x0040, 0x1dc9: 0x0040, 0x1dca: 0x0040, 0x1dcb: 0x0040, + 0x1dcc: 0x0040, 0x1dcd: 0x0040, 0x1dce: 0x0040, 0x1dcf: 0x0040, 0x1dd0: 0xc269, 0x1dd1: 0xc289, + 0x1dd2: 0xc2a9, 0x1dd3: 0xc2c9, 0x1dd4: 0xc2e9, 0x1dd5: 0xc309, 0x1dd6: 0xc329, 0x1dd7: 0xc349, + 0x1dd8: 0xc369, 0x1dd9: 0xc389, 0x1dda: 0xc3a9, 0x1ddb: 0xc3c9, 0x1ddc: 0xc3e9, 0x1ddd: 0xc409, + 0x1dde: 0xc429, 0x1ddf: 0xc449, 0x1de0: 0xc469, 0x1de1: 0xc489, 0x1de2: 0xc4a9, 0x1de3: 0xc4c9, + 0x1de4: 0xc4e9, 0x1de5: 0xc509, 0x1de6: 0xc529, 0x1de7: 0xc549, 0x1de8: 0xc569, 0x1de9: 0xc589, + 0x1dea: 0xc5a9, 0x1deb: 0xc5c9, 0x1dec: 0xc5e9, 0x1ded: 0xc609, 0x1dee: 0xc629, 0x1def: 0xc649, + 0x1df0: 0xc669, 0x1df1: 0xc689, 0x1df2: 0xc6a9, 0x1df3: 0xc6c9, 0x1df4: 0xc6e9, 0x1df5: 0xc709, + 0x1df6: 0xc729, 0x1df7: 0xc749, 0x1df8: 0xc769, 0x1df9: 0xc789, 0x1dfa: 0xc7a9, 0x1dfb: 0xc7c9, + 0x1dfc: 0x0040, 0x1dfd: 0x0040, 0x1dfe: 0x0040, 0x1dff: 0x0040, + // Block 0x78, offset 0x1e00 + 0x1e00: 0xcaf9, 0x1e01: 0xcb19, 0x1e02: 0xcb39, 0x1e03: 0x8b1d, 0x1e04: 0xcb59, 0x1e05: 0xcb79, + 0x1e06: 0xcb99, 0x1e07: 0xcbb9, 0x1e08: 0xcbd9, 0x1e09: 0xcbf9, 0x1e0a: 0xcc19, 0x1e0b: 0xcc39, + 0x1e0c: 0xcc59, 0x1e0d: 0x8b3d, 0x1e0e: 0xcc79, 0x1e0f: 0xcc99, 0x1e10: 0xccb9, 0x1e11: 0xccd9, + 0x1e12: 0x8b5d, 0x1e13: 0xccf9, 0x1e14: 0xcd19, 0x1e15: 0xc429, 0x1e16: 0x8b7d, 0x1e17: 0xcd39, + 0x1e18: 0xcd59, 0x1e19: 0xcd79, 0x1e1a: 0xcd99, 0x1e1b: 0xcdb9, 0x1e1c: 0x8b9d, 0x1e1d: 0xcdd9, + 0x1e1e: 0xcdf9, 0x1e1f: 0xce19, 0x1e20: 0xce39, 0x1e21: 0xce59, 0x1e22: 0xc789, 0x1e23: 0xce79, + 0x1e24: 0xce99, 0x1e25: 0xceb9, 0x1e26: 0xced9, 0x1e27: 0xcef9, 0x1e28: 0xcf19, 0x1e29: 0xcf39, + 0x1e2a: 0xcf59, 0x1e2b: 0xcf79, 0x1e2c: 0xcf99, 0x1e2d: 0xcfb9, 0x1e2e: 0xcfd9, 0x1e2f: 0xcff9, + 0x1e30: 0xd019, 0x1e31: 0xd039, 0x1e32: 0xd039, 0x1e33: 0xd039, 0x1e34: 0x8bbd, 0x1e35: 0xd059, + 0x1e36: 0xd079, 0x1e37: 0xd099, 0x1e38: 0x8bdd, 0x1e39: 0xd0b9, 0x1e3a: 0xd0d9, 0x1e3b: 0xd0f9, + 0x1e3c: 0xd119, 0x1e3d: 0xd139, 0x1e3e: 0xd159, 0x1e3f: 0xd179, + // Block 0x79, offset 0x1e40 + 0x1e40: 0xd199, 0x1e41: 0xd1b9, 0x1e42: 0xd1d9, 0x1e43: 0xd1f9, 0x1e44: 0xd219, 0x1e45: 0xd239, + 0x1e46: 0xd239, 0x1e47: 0xd259, 0x1e48: 0xd279, 0x1e49: 0xd299, 0x1e4a: 0xd2b9, 0x1e4b: 0xd2d9, + 0x1e4c: 0xd2f9, 0x1e4d: 0xd319, 0x1e4e: 0xd339, 0x1e4f: 0xd359, 0x1e50: 0xd379, 0x1e51: 0xd399, + 0x1e52: 0xd3b9, 0x1e53: 0xd3d9, 0x1e54: 0xd3f9, 0x1e55: 0xd419, 0x1e56: 0xd439, 0x1e57: 0xd459, + 0x1e58: 0xd479, 0x1e59: 0x8bfd, 0x1e5a: 0xd499, 0x1e5b: 0xd4b9, 0x1e5c: 0xd4d9, 0x1e5d: 0xc309, + 0x1e5e: 0xd4f9, 0x1e5f: 0xd519, 0x1e60: 0x8c1d, 0x1e61: 0x8c3d, 0x1e62: 0xd539, 0x1e63: 0xd559, + 0x1e64: 0xd579, 0x1e65: 0xd599, 0x1e66: 0xd5b9, 0x1e67: 0xd5d9, 0x1e68: 0x2040, 0x1e69: 0xd5f9, + 0x1e6a: 0xd619, 0x1e6b: 0xd619, 0x1e6c: 0x8c5d, 0x1e6d: 0xd639, 0x1e6e: 0xd659, 0x1e6f: 0xd679, + 0x1e70: 0xd699, 0x1e71: 0x8c7d, 0x1e72: 0xd6b9, 0x1e73: 0xd6d9, 0x1e74: 0x2040, 0x1e75: 0xd6f9, + 0x1e76: 0xd719, 0x1e77: 0xd739, 0x1e78: 0xd759, 0x1e79: 0xd779, 0x1e7a: 0xd799, 0x1e7b: 0x8c9d, + 0x1e7c: 0xd7b9, 0x1e7d: 0x8cbd, 0x1e7e: 0xd7d9, 0x1e7f: 0xd7f9, + // Block 0x7a, offset 0x1e80 + 0x1e80: 0xd819, 0x1e81: 0xd839, 0x1e82: 0xd859, 0x1e83: 0xd879, 0x1e84: 0xd899, 0x1e85: 0xd8b9, + 0x1e86: 0xd8d9, 0x1e87: 0xd8f9, 0x1e88: 0xd919, 0x1e89: 0x8cdd, 0x1e8a: 0xd939, 0x1e8b: 0xd959, + 0x1e8c: 0xd979, 0x1e8d: 0xd999, 0x1e8e: 0xd9b9, 0x1e8f: 0x8cfd, 0x1e90: 0xd9d9, 0x1e91: 0x8d1d, + 0x1e92: 0x8d3d, 0x1e93: 0xd9f9, 0x1e94: 0xda19, 0x1e95: 0xda19, 0x1e96: 0xda39, 0x1e97: 0x8d5d, + 0x1e98: 0x8d7d, 0x1e99: 0xda59, 0x1e9a: 0xda79, 0x1e9b: 0xda99, 0x1e9c: 0xdab9, 0x1e9d: 0xdad9, + 0x1e9e: 0xdaf9, 0x1e9f: 0xdb19, 0x1ea0: 0xdb39, 0x1ea1: 0xdb59, 0x1ea2: 0xdb79, 0x1ea3: 0xdb99, + 0x1ea4: 0x8d9d, 0x1ea5: 0xdbb9, 0x1ea6: 0xdbd9, 0x1ea7: 0xdbf9, 0x1ea8: 0xdc19, 0x1ea9: 0xdbf9, + 0x1eaa: 0xdc39, 0x1eab: 0xdc59, 0x1eac: 0xdc79, 0x1ead: 0xdc99, 0x1eae: 0xdcb9, 0x1eaf: 0xdcd9, + 0x1eb0: 0xdcf9, 0x1eb1: 0xdd19, 0x1eb2: 0xdd39, 0x1eb3: 0xdd59, 0x1eb4: 0xdd79, 0x1eb5: 0xdd99, + 0x1eb6: 0xddb9, 0x1eb7: 0xddd9, 0x1eb8: 0x8dbd, 0x1eb9: 0xddf9, 0x1eba: 0xde19, 0x1ebb: 0xde39, + 0x1ebc: 0xde59, 0x1ebd: 0xde79, 0x1ebe: 0x8ddd, 0x1ebf: 0xde99, + // Block 0x7b, offset 0x1ec0 + 0x1ec0: 0xe599, 0x1ec1: 0xe5b9, 0x1ec2: 0xe5d9, 0x1ec3: 0xe5f9, 0x1ec4: 0xe619, 0x1ec5: 0xe639, + 0x1ec6: 0x8efd, 0x1ec7: 0xe659, 0x1ec8: 0xe679, 0x1ec9: 0xe699, 0x1eca: 0xe6b9, 0x1ecb: 0xe6d9, + 0x1ecc: 0xe6f9, 0x1ecd: 0x8f1d, 0x1ece: 0xe719, 0x1ecf: 0xe739, 0x1ed0: 0x8f3d, 0x1ed1: 0x8f5d, + 0x1ed2: 0xe759, 0x1ed3: 0xe779, 0x1ed4: 0xe799, 0x1ed5: 0xe7b9, 0x1ed6: 0xe7d9, 0x1ed7: 0xe7f9, + 0x1ed8: 0xe819, 0x1ed9: 0xe839, 0x1eda: 0xe859, 0x1edb: 0x8f7d, 0x1edc: 0xe879, 0x1edd: 0x8f9d, + 0x1ede: 0xe899, 0x1edf: 0x2040, 0x1ee0: 0xe8b9, 0x1ee1: 0xe8d9, 0x1ee2: 0xe8f9, 0x1ee3: 0x8fbd, + 0x1ee4: 0xe919, 0x1ee5: 0xe939, 0x1ee6: 0x8fdd, 0x1ee7: 0x8ffd, 0x1ee8: 0xe959, 0x1ee9: 0xe979, + 0x1eea: 0xe999, 0x1eeb: 0xe9b9, 0x1eec: 0xe9d9, 0x1eed: 0xe9d9, 0x1eee: 0xe9f9, 0x1eef: 0xea19, + 0x1ef0: 0xea39, 0x1ef1: 0xea59, 0x1ef2: 0xea79, 0x1ef3: 0xea99, 0x1ef4: 0xeab9, 0x1ef5: 0x901d, + 0x1ef6: 0xead9, 0x1ef7: 0x903d, 0x1ef8: 0xeaf9, 0x1ef9: 0x905d, 0x1efa: 0xeb19, 0x1efb: 0x907d, + 0x1efc: 0x909d, 0x1efd: 0x90bd, 0x1efe: 0xeb39, 0x1eff: 0xeb59, + // Block 0x7c, offset 0x1f00 + 0x1f00: 0xeb79, 0x1f01: 0x90dd, 0x1f02: 0x90fd, 0x1f03: 0x911d, 0x1f04: 0x913d, 0x1f05: 0xeb99, + 0x1f06: 0xebb9, 0x1f07: 0xebb9, 0x1f08: 0xebd9, 0x1f09: 0xebf9, 0x1f0a: 0xec19, 0x1f0b: 0xec39, + 0x1f0c: 0xec59, 0x1f0d: 0x915d, 0x1f0e: 0xec79, 0x1f0f: 0xec99, 0x1f10: 0xecb9, 0x1f11: 0xecd9, + 0x1f12: 0x917d, 0x1f13: 0xecf9, 0x1f14: 0x919d, 0x1f15: 0x91bd, 0x1f16: 0xed19, 0x1f17: 0xed39, + 0x1f18: 0xed59, 0x1f19: 0xed79, 0x1f1a: 0xed99, 0x1f1b: 0xedb9, 0x1f1c: 0x91dd, 0x1f1d: 0x91fd, + 0x1f1e: 0x921d, 0x1f1f: 0x2040, 0x1f20: 0xedd9, 0x1f21: 0x923d, 0x1f22: 0xedf9, 0x1f23: 0xee19, + 0x1f24: 0xee39, 0x1f25: 0x925d, 0x1f26: 0xee59, 0x1f27: 0xee79, 0x1f28: 0xee99, 0x1f29: 0xeeb9, + 0x1f2a: 0xeed9, 0x1f2b: 0x927d, 0x1f2c: 0xeef9, 0x1f2d: 0xef19, 0x1f2e: 0xef39, 0x1f2f: 0xef59, + 0x1f30: 0xef79, 0x1f31: 0xef99, 0x1f32: 0x929d, 0x1f33: 0x92bd, 0x1f34: 0xefb9, 0x1f35: 0x92dd, + 0x1f36: 0xefd9, 0x1f37: 0x92fd, 0x1f38: 0xeff9, 0x1f39: 0xf019, 0x1f3a: 0xf039, 0x1f3b: 0x931d, + 0x1f3c: 0x933d, 0x1f3d: 0xf059, 0x1f3e: 0x935d, 0x1f3f: 0xf079, + // Block 0x7d, offset 0x1f40 + 0x1f40: 0xf6b9, 0x1f41: 0xf6d9, 0x1f42: 0xf6f9, 0x1f43: 0xf719, 0x1f44: 0xf739, 0x1f45: 0x951d, + 0x1f46: 0xf759, 0x1f47: 0xf779, 0x1f48: 0xf799, 0x1f49: 0xf7b9, 0x1f4a: 0xf7d9, 0x1f4b: 0x953d, + 0x1f4c: 0x955d, 0x1f4d: 0xf7f9, 0x1f4e: 0xf819, 0x1f4f: 0xf839, 0x1f50: 0xf859, 0x1f51: 0xf879, + 0x1f52: 0xf899, 0x1f53: 0x957d, 0x1f54: 0xf8b9, 0x1f55: 0xf8d9, 0x1f56: 0xf8f9, 0x1f57: 0xf919, + 0x1f58: 0x959d, 0x1f59: 0x95bd, 0x1f5a: 0xf939, 0x1f5b: 0xf959, 0x1f5c: 0xf979, 0x1f5d: 0x95dd, + 0x1f5e: 0xf999, 0x1f5f: 0xf9b9, 0x1f60: 0x6815, 0x1f61: 0x95fd, 0x1f62: 0xf9d9, 0x1f63: 0xf9f9, + 0x1f64: 0xfa19, 0x1f65: 0x961d, 0x1f66: 0xfa39, 0x1f67: 0xfa59, 0x1f68: 0xfa79, 0x1f69: 0xfa99, + 0x1f6a: 0xfab9, 0x1f6b: 0xfad9, 0x1f6c: 0xfaf9, 0x1f6d: 0x963d, 0x1f6e: 0xfb19, 0x1f6f: 0xfb39, + 0x1f70: 0xfb59, 0x1f71: 0x965d, 0x1f72: 0xfb79, 0x1f73: 0xfb99, 0x1f74: 0xfbb9, 0x1f75: 0xfbd9, + 0x1f76: 0x7b35, 0x1f77: 0x967d, 0x1f78: 0xfbf9, 0x1f79: 0xfc19, 0x1f7a: 0xfc39, 0x1f7b: 0x969d, + 0x1f7c: 0xfc59, 0x1f7d: 0x96bd, 0x1f7e: 0xfc79, 0x1f7f: 0xfc79, + // Block 0x7e, offset 0x1f80 + 0x1f80: 0xfc99, 0x1f81: 0x96dd, 0x1f82: 0xfcb9, 0x1f83: 0xfcd9, 0x1f84: 0xfcf9, 0x1f85: 0xfd19, + 0x1f86: 0xfd39, 0x1f87: 0xfd59, 0x1f88: 0xfd79, 0x1f89: 0x96fd, 0x1f8a: 0xfd99, 0x1f8b: 0xfdb9, + 0x1f8c: 0xfdd9, 0x1f8d: 0xfdf9, 0x1f8e: 0xfe19, 0x1f8f: 0xfe39, 0x1f90: 0x971d, 0x1f91: 0xfe59, + 0x1f92: 0x973d, 0x1f93: 0x975d, 0x1f94: 0x977d, 0x1f95: 0xfe79, 0x1f96: 0xfe99, 0x1f97: 0xfeb9, + 0x1f98: 0xfed9, 0x1f99: 0xfef9, 0x1f9a: 0xff19, 0x1f9b: 0xff39, 0x1f9c: 0xff59, 0x1f9d: 0x979d, + 0x1f9e: 0x0040, 0x1f9f: 0x0040, 0x1fa0: 0x0040, 0x1fa1: 0x0040, 0x1fa2: 0x0040, 0x1fa3: 0x0040, + 0x1fa4: 0x0040, 0x1fa5: 0x0040, 0x1fa6: 0x0040, 0x1fa7: 0x0040, 0x1fa8: 0x0040, 0x1fa9: 0x0040, + 0x1faa: 0x0040, 0x1fab: 0x0040, 0x1fac: 0x0040, 0x1fad: 0x0040, 0x1fae: 0x0040, 0x1faf: 0x0040, + 0x1fb0: 0x0040, 0x1fb1: 0x0040, 0x1fb2: 0x0040, 0x1fb3: 0x0040, 0x1fb4: 0x0040, 0x1fb5: 0x0040, + 0x1fb6: 0x0040, 0x1fb7: 0x0040, 0x1fb8: 0x0040, 0x1fb9: 0x0040, 0x1fba: 0x0040, 0x1fbb: 0x0040, + 0x1fbc: 0x0040, 0x1fbd: 0x0040, 0x1fbe: 0x0040, 0x1fbf: 0x0040, +} + +// idnaIndex: 36 blocks, 2304 entries, 4608 bytes +// Block 0 is the zero block. +var idnaIndex = [2304]uint16{ + // Block 0x0, offset 0x0 + // Block 0x1, offset 0x40 + // Block 0x2, offset 0x80 + // Block 0x3, offset 0xc0 + 0xc2: 0x01, 0xc3: 0x7d, 0xc4: 0x02, 0xc5: 0x03, 0xc6: 0x04, 0xc7: 0x05, + 0xc8: 0x06, 0xc9: 0x7e, 0xca: 0x7f, 0xcb: 0x07, 0xcc: 0x80, 0xcd: 0x08, 0xce: 0x09, 0xcf: 0x0a, + 0xd0: 0x81, 0xd1: 0x0b, 0xd2: 0x0c, 0xd3: 0x0d, 0xd4: 0x0e, 0xd5: 0x82, 0xd6: 0x83, 0xd7: 0x84, + 0xd8: 0x0f, 0xd9: 0x10, 0xda: 0x85, 0xdb: 0x11, 0xdc: 0x12, 0xdd: 0x86, 0xde: 0x87, 0xdf: 0x88, + 0xe0: 0x02, 0xe1: 0x03, 0xe2: 0x04, 0xe3: 0x05, 0xe4: 0x06, 0xe5: 0x07, 0xe6: 0x07, 0xe7: 0x07, + 0xe8: 0x07, 0xe9: 0x08, 0xea: 0x09, 0xeb: 0x07, 0xec: 0x07, 0xed: 0x0a, 0xee: 0x0b, 0xef: 0x0c, + 0xf0: 0x1d, 0xf1: 0x1e, 0xf2: 0x1e, 0xf3: 0x20, 0xf4: 0x21, + // Block 0x4, offset 0x100 + 0x120: 0x89, 0x121: 0x13, 0x122: 0x8a, 0x123: 0x8b, 0x124: 0x8c, 0x125: 0x14, 0x126: 0x15, 0x127: 0x16, + 0x128: 0x17, 0x129: 0x18, 0x12a: 0x19, 0x12b: 0x1a, 0x12c: 0x1b, 0x12d: 0x1c, 0x12e: 0x1d, 0x12f: 0x8d, + 0x130: 0x8e, 0x131: 0x1e, 0x132: 0x1f, 0x133: 0x20, 0x134: 0x8f, 0x135: 0x21, 0x136: 0x90, 0x137: 0x91, + 0x138: 0x92, 0x139: 0x93, 0x13a: 0x22, 0x13b: 0x94, 0x13c: 0x95, 0x13d: 0x23, 0x13e: 0x24, 0x13f: 0x96, + // Block 0x5, offset 0x140 + 0x140: 0x97, 0x141: 0x98, 0x142: 0x99, 0x143: 0x9a, 0x144: 0x9b, 0x145: 0x9c, 0x146: 0x9d, 0x147: 0x9e, + 0x148: 0x9f, 0x149: 0xa0, 0x14a: 0xa1, 0x14b: 0xa2, 0x14c: 0xa3, 0x14d: 0xa4, 0x14e: 0xa5, 0x14f: 0xa6, + 0x150: 0xa7, 0x151: 0x9f, 0x152: 0x9f, 0x153: 0x9f, 0x154: 0x9f, 0x155: 0x9f, 0x156: 0x9f, 0x157: 0x9f, + 0x158: 0x9f, 0x159: 0xa8, 0x15a: 0xa9, 0x15b: 0xaa, 0x15c: 0xab, 0x15d: 0xac, 0x15e: 0xad, 0x15f: 0xae, + 0x160: 0xaf, 0x161: 0xb0, 0x162: 0xb1, 0x163: 0xb2, 0x164: 0xb3, 0x165: 0xb4, 0x166: 0xb5, 0x167: 0xb6, + 0x168: 0xb7, 0x169: 0xb8, 0x16a: 0xb9, 0x16b: 0xba, 0x16c: 0xbb, 0x16d: 0xbc, 0x16e: 0xbd, 0x16f: 0xbe, + 0x170: 0xbf, 0x171: 0xc0, 0x172: 0xc1, 0x173: 0xc2, 0x174: 0x25, 0x175: 0x26, 0x176: 0x27, 0x177: 0xc3, + 0x178: 0x28, 0x179: 0x28, 0x17a: 0x29, 0x17b: 0x28, 0x17c: 0xc4, 0x17d: 0x2a, 0x17e: 0x2b, 0x17f: 0x2c, + // Block 0x6, offset 0x180 + 0x180: 0x2d, 0x181: 0x2e, 0x182: 0x2f, 0x183: 0xc5, 0x184: 0x30, 0x185: 0x31, 0x186: 0xc6, 0x187: 0x9b, + 0x188: 0xc7, 0x189: 0xc8, 0x18a: 0x9b, 0x18b: 0x9b, 0x18c: 0xc9, 0x18d: 0x9b, 0x18e: 0x9b, 0x18f: 0x9b, + 0x190: 0xca, 0x191: 0x32, 0x192: 0x33, 0x193: 0x34, 0x194: 0x9b, 0x195: 0x9b, 0x196: 0x9b, 0x197: 0x9b, + 0x198: 0x9b, 0x199: 0x9b, 0x19a: 0x9b, 0x19b: 0x9b, 0x19c: 0x9b, 0x19d: 0x9b, 0x19e: 0x9b, 0x19f: 0x9b, + 0x1a0: 0x9b, 0x1a1: 0x9b, 0x1a2: 0x9b, 0x1a3: 0x9b, 0x1a4: 0x9b, 0x1a5: 0x9b, 0x1a6: 0x9b, 0x1a7: 0x9b, + 0x1a8: 0xcb, 0x1a9: 0xcc, 0x1aa: 0x9b, 0x1ab: 0xcd, 0x1ac: 0x9b, 0x1ad: 0xce, 0x1ae: 0xcf, 0x1af: 0xd0, + 0x1b0: 0xd1, 0x1b1: 0x35, 0x1b2: 0x28, 0x1b3: 0x36, 0x1b4: 0xd2, 0x1b5: 0xd3, 0x1b6: 0xd4, 0x1b7: 0xd5, + 0x1b8: 0xd6, 0x1b9: 0xd7, 0x1ba: 0xd8, 0x1bb: 0xd9, 0x1bc: 0xda, 0x1bd: 0xdb, 0x1be: 0xdc, 0x1bf: 0x37, + // Block 0x7, offset 0x1c0 + 0x1c0: 0x38, 0x1c1: 0xdd, 0x1c2: 0xde, 0x1c3: 0xdf, 0x1c4: 0xe0, 0x1c5: 0x39, 0x1c6: 0x3a, 0x1c7: 0xe1, + 0x1c8: 0xe2, 0x1c9: 0x3b, 0x1ca: 0x3c, 0x1cb: 0x3d, 0x1cc: 0x3e, 0x1cd: 0x3f, 0x1ce: 0x40, 0x1cf: 0x41, + 0x1d0: 0x9f, 0x1d1: 0x9f, 0x1d2: 0x9f, 0x1d3: 0x9f, 0x1d4: 0x9f, 0x1d5: 0x9f, 0x1d6: 0x9f, 0x1d7: 0x9f, + 0x1d8: 0x9f, 0x1d9: 0x9f, 0x1da: 0x9f, 0x1db: 0x9f, 0x1dc: 0x9f, 0x1dd: 0x9f, 0x1de: 0x9f, 0x1df: 0x9f, + 0x1e0: 0x9f, 0x1e1: 0x9f, 0x1e2: 0x9f, 0x1e3: 0x9f, 0x1e4: 0x9f, 0x1e5: 0x9f, 0x1e6: 0x9f, 0x1e7: 0x9f, + 0x1e8: 0x9f, 0x1e9: 0x9f, 0x1ea: 0x9f, 0x1eb: 0x9f, 0x1ec: 0x9f, 0x1ed: 0x9f, 0x1ee: 0x9f, 0x1ef: 0x9f, + 0x1f0: 0x9f, 0x1f1: 0x9f, 0x1f2: 0x9f, 0x1f3: 0x9f, 0x1f4: 0x9f, 0x1f5: 0x9f, 0x1f6: 0x9f, 0x1f7: 0x9f, + 0x1f8: 0x9f, 0x1f9: 0x9f, 0x1fa: 0x9f, 0x1fb: 0x9f, 0x1fc: 0x9f, 0x1fd: 0x9f, 0x1fe: 0x9f, 0x1ff: 0x9f, + // Block 0x8, offset 0x200 + 0x200: 0x9f, 0x201: 0x9f, 0x202: 0x9f, 0x203: 0x9f, 0x204: 0x9f, 0x205: 0x9f, 0x206: 0x9f, 0x207: 0x9f, + 0x208: 0x9f, 0x209: 0x9f, 0x20a: 0x9f, 0x20b: 0x9f, 0x20c: 0x9f, 0x20d: 0x9f, 0x20e: 0x9f, 0x20f: 0x9f, + 0x210: 0x9f, 0x211: 0x9f, 0x212: 0x9f, 0x213: 0x9f, 0x214: 0x9f, 0x215: 0x9f, 0x216: 0x9f, 0x217: 0x9f, + 0x218: 0x9f, 0x219: 0x9f, 0x21a: 0x9f, 0x21b: 0x9f, 0x21c: 0x9f, 0x21d: 0x9f, 0x21e: 0x9f, 0x21f: 0x9f, + 0x220: 0x9f, 0x221: 0x9f, 0x222: 0x9f, 0x223: 0x9f, 0x224: 0x9f, 0x225: 0x9f, 0x226: 0x9f, 0x227: 0x9f, + 0x228: 0x9f, 0x229: 0x9f, 0x22a: 0x9f, 0x22b: 0x9f, 0x22c: 0x9f, 0x22d: 0x9f, 0x22e: 0x9f, 0x22f: 0x9f, + 0x230: 0x9f, 0x231: 0x9f, 0x232: 0x9f, 0x233: 0x9f, 0x234: 0x9f, 0x235: 0x9f, 0x236: 0xb2, 0x237: 0x9b, + 0x238: 0x9f, 0x239: 0x9f, 0x23a: 0x9f, 0x23b: 0x9f, 0x23c: 0x9f, 0x23d: 0x9f, 0x23e: 0x9f, 0x23f: 0x9f, + // Block 0x9, offset 0x240 + 0x240: 0x9f, 0x241: 0x9f, 0x242: 0x9f, 0x243: 0x9f, 0x244: 0x9f, 0x245: 0x9f, 0x246: 0x9f, 0x247: 0x9f, + 0x248: 0x9f, 0x249: 0x9f, 0x24a: 0x9f, 0x24b: 0x9f, 0x24c: 0x9f, 0x24d: 0x9f, 0x24e: 0x9f, 0x24f: 0x9f, + 0x250: 0x9f, 0x251: 0x9f, 0x252: 0x9f, 0x253: 0x9f, 0x254: 0x9f, 0x255: 0x9f, 0x256: 0x9f, 0x257: 0x9f, + 0x258: 0x9f, 0x259: 0x9f, 0x25a: 0x9f, 0x25b: 0x9f, 0x25c: 0x9f, 0x25d: 0x9f, 0x25e: 0x9f, 0x25f: 0x9f, + 0x260: 0x9f, 0x261: 0x9f, 0x262: 0x9f, 0x263: 0x9f, 0x264: 0x9f, 0x265: 0x9f, 0x266: 0x9f, 0x267: 0x9f, + 0x268: 0x9f, 0x269: 0x9f, 0x26a: 0x9f, 0x26b: 0x9f, 0x26c: 0x9f, 0x26d: 0x9f, 0x26e: 0x9f, 0x26f: 0x9f, + 0x270: 0x9f, 0x271: 0x9f, 0x272: 0x9f, 0x273: 0x9f, 0x274: 0x9f, 0x275: 0x9f, 0x276: 0x9f, 0x277: 0x9f, + 0x278: 0x9f, 0x279: 0x9f, 0x27a: 0x9f, 0x27b: 0x9f, 0x27c: 0x9f, 0x27d: 0x9f, 0x27e: 0x9f, 0x27f: 0x9f, + // Block 0xa, offset 0x280 + 0x280: 0x9f, 0x281: 0x9f, 0x282: 0x9f, 0x283: 0x9f, 0x284: 0x9f, 0x285: 0x9f, 0x286: 0x9f, 0x287: 0x9f, + 0x288: 0x9f, 0x289: 0x9f, 0x28a: 0x9f, 0x28b: 0x9f, 0x28c: 0x9f, 0x28d: 0x9f, 0x28e: 0x9f, 0x28f: 0x9f, + 0x290: 0x9f, 0x291: 0x9f, 0x292: 0x9f, 0x293: 0x9f, 0x294: 0x9f, 0x295: 0x9f, 0x296: 0x9f, 0x297: 0x9f, + 0x298: 0x9f, 0x299: 0x9f, 0x29a: 0x9f, 0x29b: 0x9f, 0x29c: 0x9f, 0x29d: 0x9f, 0x29e: 0x9f, 0x29f: 0x9f, + 0x2a0: 0x9f, 0x2a1: 0x9f, 0x2a2: 0x9f, 0x2a3: 0x9f, 0x2a4: 0x9f, 0x2a5: 0x9f, 0x2a6: 0x9f, 0x2a7: 0x9f, + 0x2a8: 0x9f, 0x2a9: 0x9f, 0x2aa: 0x9f, 0x2ab: 0x9f, 0x2ac: 0x9f, 0x2ad: 0x9f, 0x2ae: 0x9f, 0x2af: 0x9f, + 0x2b0: 0x9f, 0x2b1: 0x9f, 0x2b2: 0x9f, 0x2b3: 0x9f, 0x2b4: 0x9f, 0x2b5: 0x9f, 0x2b6: 0x9f, 0x2b7: 0x9f, + 0x2b8: 0x9f, 0x2b9: 0x9f, 0x2ba: 0x9f, 0x2bb: 0x9f, 0x2bc: 0x9f, 0x2bd: 0x9f, 0x2be: 0x9f, 0x2bf: 0xe3, + // Block 0xb, offset 0x2c0 + 0x2c0: 0x9f, 0x2c1: 0x9f, 0x2c2: 0x9f, 0x2c3: 0x9f, 0x2c4: 0x9f, 0x2c5: 0x9f, 0x2c6: 0x9f, 0x2c7: 0x9f, + 0x2c8: 0x9f, 0x2c9: 0x9f, 0x2ca: 0x9f, 0x2cb: 0x9f, 0x2cc: 0x9f, 0x2cd: 0x9f, 0x2ce: 0x9f, 0x2cf: 0x9f, + 0x2d0: 0x9f, 0x2d1: 0x9f, 0x2d2: 0xe4, 0x2d3: 0xe5, 0x2d4: 0x9f, 0x2d5: 0x9f, 0x2d6: 0x9f, 0x2d7: 0x9f, + 0x2d8: 0xe6, 0x2d9: 0x42, 0x2da: 0x43, 0x2db: 0xe7, 0x2dc: 0x44, 0x2dd: 0x45, 0x2de: 0x46, 0x2df: 0xe8, + 0x2e0: 0xe9, 0x2e1: 0xea, 0x2e2: 0xeb, 0x2e3: 0xec, 0x2e4: 0xed, 0x2e5: 0xee, 0x2e6: 0xef, 0x2e7: 0xf0, + 0x2e8: 0xf1, 0x2e9: 0xf2, 0x2ea: 0xf3, 0x2eb: 0xf4, 0x2ec: 0xf5, 0x2ed: 0xf6, 0x2ee: 0xf7, 0x2ef: 0xf8, + 0x2f0: 0x9f, 0x2f1: 0x9f, 0x2f2: 0x9f, 0x2f3: 0x9f, 0x2f4: 0x9f, 0x2f5: 0x9f, 0x2f6: 0x9f, 0x2f7: 0x9f, + 0x2f8: 0x9f, 0x2f9: 0x9f, 0x2fa: 0x9f, 0x2fb: 0x9f, 0x2fc: 0x9f, 0x2fd: 0x9f, 0x2fe: 0x9f, 0x2ff: 0x9f, + // Block 0xc, offset 0x300 + 0x300: 0x9f, 0x301: 0x9f, 0x302: 0x9f, 0x303: 0x9f, 0x304: 0x9f, 0x305: 0x9f, 0x306: 0x9f, 0x307: 0x9f, + 0x308: 0x9f, 0x309: 0x9f, 0x30a: 0x9f, 0x30b: 0x9f, 0x30c: 0x9f, 0x30d: 0x9f, 0x30e: 0x9f, 0x30f: 0x9f, + 0x310: 0x9f, 0x311: 0x9f, 0x312: 0x9f, 0x313: 0x9f, 0x314: 0x9f, 0x315: 0x9f, 0x316: 0x9f, 0x317: 0x9f, + 0x318: 0x9f, 0x319: 0x9f, 0x31a: 0x9f, 0x31b: 0x9f, 0x31c: 0x9f, 0x31d: 0x9f, 0x31e: 0xf9, 0x31f: 0xfa, + // Block 0xd, offset 0x340 + 0x340: 0xba, 0x341: 0xba, 0x342: 0xba, 0x343: 0xba, 0x344: 0xba, 0x345: 0xba, 0x346: 0xba, 0x347: 0xba, + 0x348: 0xba, 0x349: 0xba, 0x34a: 0xba, 0x34b: 0xba, 0x34c: 0xba, 0x34d: 0xba, 0x34e: 0xba, 0x34f: 0xba, + 0x350: 0xba, 0x351: 0xba, 0x352: 0xba, 0x353: 0xba, 0x354: 0xba, 0x355: 0xba, 0x356: 0xba, 0x357: 0xba, + 0x358: 0xba, 0x359: 0xba, 0x35a: 0xba, 0x35b: 0xba, 0x35c: 0xba, 0x35d: 0xba, 0x35e: 0xba, 0x35f: 0xba, + 0x360: 0xba, 0x361: 0xba, 0x362: 0xba, 0x363: 0xba, 0x364: 0xba, 0x365: 0xba, 0x366: 0xba, 0x367: 0xba, + 0x368: 0xba, 0x369: 0xba, 0x36a: 0xba, 0x36b: 0xba, 0x36c: 0xba, 0x36d: 0xba, 0x36e: 0xba, 0x36f: 0xba, + 0x370: 0xba, 0x371: 0xba, 0x372: 0xba, 0x373: 0xba, 0x374: 0xba, 0x375: 0xba, 0x376: 0xba, 0x377: 0xba, + 0x378: 0xba, 0x379: 0xba, 0x37a: 0xba, 0x37b: 0xba, 0x37c: 0xba, 0x37d: 0xba, 0x37e: 0xba, 0x37f: 0xba, + // Block 0xe, offset 0x380 + 0x380: 0xba, 0x381: 0xba, 0x382: 0xba, 0x383: 0xba, 0x384: 0xba, 0x385: 0xba, 0x386: 0xba, 0x387: 0xba, + 0x388: 0xba, 0x389: 0xba, 0x38a: 0xba, 0x38b: 0xba, 0x38c: 0xba, 0x38d: 0xba, 0x38e: 0xba, 0x38f: 0xba, + 0x390: 0xba, 0x391: 0xba, 0x392: 0xba, 0x393: 0xba, 0x394: 0xba, 0x395: 0xba, 0x396: 0xba, 0x397: 0xba, + 0x398: 0xba, 0x399: 0xba, 0x39a: 0xba, 0x39b: 0xba, 0x39c: 0xba, 0x39d: 0xba, 0x39e: 0xba, 0x39f: 0xba, + 0x3a0: 0xba, 0x3a1: 0xba, 0x3a2: 0xba, 0x3a3: 0xba, 0x3a4: 0xfb, 0x3a5: 0xfc, 0x3a6: 0xfd, 0x3a7: 0xfe, + 0x3a8: 0x47, 0x3a9: 0xff, 0x3aa: 0x100, 0x3ab: 0x48, 0x3ac: 0x49, 0x3ad: 0x4a, 0x3ae: 0x4b, 0x3af: 0x4c, + 0x3b0: 0x101, 0x3b1: 0x4d, 0x3b2: 0x4e, 0x3b3: 0x4f, 0x3b4: 0x50, 0x3b5: 0x51, 0x3b6: 0x102, 0x3b7: 0x52, + 0x3b8: 0x53, 0x3b9: 0x54, 0x3ba: 0x55, 0x3bb: 0x56, 0x3bc: 0x57, 0x3bd: 0x58, 0x3be: 0x59, 0x3bf: 0x5a, + // Block 0xf, offset 0x3c0 + 0x3c0: 0x103, 0x3c1: 0x104, 0x3c2: 0x9f, 0x3c3: 0x105, 0x3c4: 0x106, 0x3c5: 0x9b, 0x3c6: 0x107, 0x3c7: 0x108, + 0x3c8: 0xba, 0x3c9: 0xba, 0x3ca: 0x109, 0x3cb: 0x10a, 0x3cc: 0x10b, 0x3cd: 0x10c, 0x3ce: 0x10d, 0x3cf: 0x10e, + 0x3d0: 0x10f, 0x3d1: 0x9f, 0x3d2: 0x110, 0x3d3: 0x111, 0x3d4: 0x112, 0x3d5: 0x113, 0x3d6: 0xba, 0x3d7: 0xba, + 0x3d8: 0x9f, 0x3d9: 0x9f, 0x3da: 0x9f, 0x3db: 0x9f, 0x3dc: 0x114, 0x3dd: 0x115, 0x3de: 0xba, 0x3df: 0xba, + 0x3e0: 0x116, 0x3e1: 0x117, 0x3e2: 0x118, 0x3e3: 0x119, 0x3e4: 0x11a, 0x3e5: 0xba, 0x3e6: 0x11b, 0x3e7: 0x11c, + 0x3e8: 0x11d, 0x3e9: 0x11e, 0x3ea: 0x11f, 0x3eb: 0x5b, 0x3ec: 0x120, 0x3ed: 0x121, 0x3ee: 0x5c, 0x3ef: 0xba, + 0x3f0: 0x122, 0x3f1: 0x123, 0x3f2: 0x124, 0x3f3: 0x125, 0x3f4: 0xba, 0x3f5: 0xba, 0x3f6: 0xba, 0x3f7: 0xba, + 0x3f8: 0xba, 0x3f9: 0x126, 0x3fa: 0xba, 0x3fb: 0xba, 0x3fc: 0xba, 0x3fd: 0xba, 0x3fe: 0xba, 0x3ff: 0xba, + // Block 0x10, offset 0x400 + 0x400: 0x127, 0x401: 0x128, 0x402: 0x129, 0x403: 0x12a, 0x404: 0x12b, 0x405: 0x12c, 0x406: 0x12d, 0x407: 0x12e, + 0x408: 0x12f, 0x409: 0xba, 0x40a: 0x130, 0x40b: 0x131, 0x40c: 0x5d, 0x40d: 0x5e, 0x40e: 0xba, 0x40f: 0xba, + 0x410: 0x132, 0x411: 0x133, 0x412: 0x134, 0x413: 0x135, 0x414: 0xba, 0x415: 0xba, 0x416: 0x136, 0x417: 0x137, + 0x418: 0x138, 0x419: 0x139, 0x41a: 0x13a, 0x41b: 0x13b, 0x41c: 0x13c, 0x41d: 0xba, 0x41e: 0xba, 0x41f: 0xba, + 0x420: 0xba, 0x421: 0xba, 0x422: 0x13d, 0x423: 0x13e, 0x424: 0xba, 0x425: 0xba, 0x426: 0xba, 0x427: 0xba, + 0x428: 0x13f, 0x429: 0x140, 0x42a: 0x141, 0x42b: 0x142, 0x42c: 0xba, 0x42d: 0xba, 0x42e: 0xba, 0x42f: 0xba, + 0x430: 0x143, 0x431: 0x144, 0x432: 0x145, 0x433: 0xba, 0x434: 0x146, 0x435: 0x147, 0x436: 0xba, 0x437: 0xba, + 0x438: 0xba, 0x439: 0xba, 0x43a: 0xba, 0x43b: 0xba, 0x43c: 0xba, 0x43d: 0xba, 0x43e: 0xba, 0x43f: 0xba, + // Block 0x11, offset 0x440 + 0x440: 0x9f, 0x441: 0x9f, 0x442: 0x9f, 0x443: 0x9f, 0x444: 0x9f, 0x445: 0x9f, 0x446: 0x9f, 0x447: 0x9f, + 0x448: 0x9f, 0x449: 0x9f, 0x44a: 0x9f, 0x44b: 0x9f, 0x44c: 0x9f, 0x44d: 0x9f, 0x44e: 0x148, 0x44f: 0xba, + 0x450: 0x9b, 0x451: 0x149, 0x452: 0x9f, 0x453: 0x9f, 0x454: 0x9f, 0x455: 0x14a, 0x456: 0xba, 0x457: 0xba, + 0x458: 0xba, 0x459: 0xba, 0x45a: 0xba, 0x45b: 0xba, 0x45c: 0xba, 0x45d: 0xba, 0x45e: 0xba, 0x45f: 0xba, + 0x460: 0xba, 0x461: 0xba, 0x462: 0xba, 0x463: 0xba, 0x464: 0xba, 0x465: 0xba, 0x466: 0xba, 0x467: 0xba, + 0x468: 0xba, 0x469: 0xba, 0x46a: 0xba, 0x46b: 0xba, 0x46c: 0xba, 0x46d: 0xba, 0x46e: 0xba, 0x46f: 0xba, + 0x470: 0xba, 0x471: 0xba, 0x472: 0xba, 0x473: 0xba, 0x474: 0xba, 0x475: 0xba, 0x476: 0xba, 0x477: 0xba, + 0x478: 0xba, 0x479: 0xba, 0x47a: 0xba, 0x47b: 0xba, 0x47c: 0xba, 0x47d: 0xba, 0x47e: 0xba, 0x47f: 0xba, + // Block 0x12, offset 0x480 + 0x480: 0x9f, 0x481: 0x9f, 0x482: 0x9f, 0x483: 0x9f, 0x484: 0x9f, 0x485: 0x9f, 0x486: 0x9f, 0x487: 0x9f, + 0x488: 0x9f, 0x489: 0x9f, 0x48a: 0x9f, 0x48b: 0x9f, 0x48c: 0x9f, 0x48d: 0x9f, 0x48e: 0x9f, 0x48f: 0x9f, + 0x490: 0x14b, 0x491: 0xba, 0x492: 0xba, 0x493: 0xba, 0x494: 0xba, 0x495: 0xba, 0x496: 0xba, 0x497: 0xba, + 0x498: 0xba, 0x499: 0xba, 0x49a: 0xba, 0x49b: 0xba, 0x49c: 0xba, 0x49d: 0xba, 0x49e: 0xba, 0x49f: 0xba, + 0x4a0: 0xba, 0x4a1: 0xba, 0x4a2: 0xba, 0x4a3: 0xba, 0x4a4: 0xba, 0x4a5: 0xba, 0x4a6: 0xba, 0x4a7: 0xba, + 0x4a8: 0xba, 0x4a9: 0xba, 0x4aa: 0xba, 0x4ab: 0xba, 0x4ac: 0xba, 0x4ad: 0xba, 0x4ae: 0xba, 0x4af: 0xba, + 0x4b0: 0xba, 0x4b1: 0xba, 0x4b2: 0xba, 0x4b3: 0xba, 0x4b4: 0xba, 0x4b5: 0xba, 0x4b6: 0xba, 0x4b7: 0xba, + 0x4b8: 0xba, 0x4b9: 0xba, 0x4ba: 0xba, 0x4bb: 0xba, 0x4bc: 0xba, 0x4bd: 0xba, 0x4be: 0xba, 0x4bf: 0xba, + // Block 0x13, offset 0x4c0 + 0x4c0: 0xba, 0x4c1: 0xba, 0x4c2: 0xba, 0x4c3: 0xba, 0x4c4: 0xba, 0x4c5: 0xba, 0x4c6: 0xba, 0x4c7: 0xba, + 0x4c8: 0xba, 0x4c9: 0xba, 0x4ca: 0xba, 0x4cb: 0xba, 0x4cc: 0xba, 0x4cd: 0xba, 0x4ce: 0xba, 0x4cf: 0xba, + 0x4d0: 0x9f, 0x4d1: 0x9f, 0x4d2: 0x9f, 0x4d3: 0x9f, 0x4d4: 0x9f, 0x4d5: 0x9f, 0x4d6: 0x9f, 0x4d7: 0x9f, + 0x4d8: 0x9f, 0x4d9: 0x14c, 0x4da: 0xba, 0x4db: 0xba, 0x4dc: 0xba, 0x4dd: 0xba, 0x4de: 0xba, 0x4df: 0xba, + 0x4e0: 0xba, 0x4e1: 0xba, 0x4e2: 0xba, 0x4e3: 0xba, 0x4e4: 0xba, 0x4e5: 0xba, 0x4e6: 0xba, 0x4e7: 0xba, + 0x4e8: 0xba, 0x4e9: 0xba, 0x4ea: 0xba, 0x4eb: 0xba, 0x4ec: 0xba, 0x4ed: 0xba, 0x4ee: 0xba, 0x4ef: 0xba, + 0x4f0: 0xba, 0x4f1: 0xba, 0x4f2: 0xba, 0x4f3: 0xba, 0x4f4: 0xba, 0x4f5: 0xba, 0x4f6: 0xba, 0x4f7: 0xba, + 0x4f8: 0xba, 0x4f9: 0xba, 0x4fa: 0xba, 0x4fb: 0xba, 0x4fc: 0xba, 0x4fd: 0xba, 0x4fe: 0xba, 0x4ff: 0xba, + // Block 0x14, offset 0x500 + 0x500: 0xba, 0x501: 0xba, 0x502: 0xba, 0x503: 0xba, 0x504: 0xba, 0x505: 0xba, 0x506: 0xba, 0x507: 0xba, + 0x508: 0xba, 0x509: 0xba, 0x50a: 0xba, 0x50b: 0xba, 0x50c: 0xba, 0x50d: 0xba, 0x50e: 0xba, 0x50f: 0xba, + 0x510: 0xba, 0x511: 0xba, 0x512: 0xba, 0x513: 0xba, 0x514: 0xba, 0x515: 0xba, 0x516: 0xba, 0x517: 0xba, + 0x518: 0xba, 0x519: 0xba, 0x51a: 0xba, 0x51b: 0xba, 0x51c: 0xba, 0x51d: 0xba, 0x51e: 0xba, 0x51f: 0xba, + 0x520: 0x9f, 0x521: 0x9f, 0x522: 0x9f, 0x523: 0x9f, 0x524: 0x9f, 0x525: 0x9f, 0x526: 0x9f, 0x527: 0x9f, + 0x528: 0x142, 0x529: 0x14d, 0x52a: 0xba, 0x52b: 0x14e, 0x52c: 0x14f, 0x52d: 0x150, 0x52e: 0x151, 0x52f: 0xba, + 0x530: 0xba, 0x531: 0xba, 0x532: 0xba, 0x533: 0xba, 0x534: 0xba, 0x535: 0xba, 0x536: 0xba, 0x537: 0xba, + 0x538: 0xba, 0x539: 0xba, 0x53a: 0xba, 0x53b: 0xba, 0x53c: 0x9f, 0x53d: 0x152, 0x53e: 0x153, 0x53f: 0x154, + // Block 0x15, offset 0x540 + 0x540: 0x9f, 0x541: 0x9f, 0x542: 0x9f, 0x543: 0x9f, 0x544: 0x9f, 0x545: 0x9f, 0x546: 0x9f, 0x547: 0x9f, + 0x548: 0x9f, 0x549: 0x9f, 0x54a: 0x9f, 0x54b: 0x9f, 0x54c: 0x9f, 0x54d: 0x9f, 0x54e: 0x9f, 0x54f: 0x9f, + 0x550: 0x9f, 0x551: 0x9f, 0x552: 0x9f, 0x553: 0x9f, 0x554: 0x9f, 0x555: 0x9f, 0x556: 0x9f, 0x557: 0x9f, + 0x558: 0x9f, 0x559: 0x9f, 0x55a: 0x9f, 0x55b: 0x9f, 0x55c: 0x9f, 0x55d: 0x9f, 0x55e: 0x9f, 0x55f: 0x155, + 0x560: 0x9f, 0x561: 0x9f, 0x562: 0x9f, 0x563: 0x9f, 0x564: 0x9f, 0x565: 0x9f, 0x566: 0x9f, 0x567: 0x9f, + 0x568: 0x9f, 0x569: 0x9f, 0x56a: 0x9f, 0x56b: 0x156, 0x56c: 0xba, 0x56d: 0xba, 0x56e: 0xba, 0x56f: 0xba, + 0x570: 0xba, 0x571: 0xba, 0x572: 0xba, 0x573: 0xba, 0x574: 0xba, 0x575: 0xba, 0x576: 0xba, 0x577: 0xba, + 0x578: 0xba, 0x579: 0xba, 0x57a: 0xba, 0x57b: 0xba, 0x57c: 0xba, 0x57d: 0xba, 0x57e: 0xba, 0x57f: 0xba, + // Block 0x16, offset 0x580 + 0x580: 0x9f, 0x581: 0x9f, 0x582: 0x9f, 0x583: 0x9f, 0x584: 0x157, 0x585: 0x158, 0x586: 0x9f, 0x587: 0x9f, + 0x588: 0x9f, 0x589: 0x9f, 0x58a: 0x9f, 0x58b: 0x159, 0x58c: 0xba, 0x58d: 0xba, 0x58e: 0xba, 0x58f: 0xba, + 0x590: 0xba, 0x591: 0xba, 0x592: 0xba, 0x593: 0xba, 0x594: 0xba, 0x595: 0xba, 0x596: 0xba, 0x597: 0xba, + 0x598: 0xba, 0x599: 0xba, 0x59a: 0xba, 0x59b: 0xba, 0x59c: 0xba, 0x59d: 0xba, 0x59e: 0xba, 0x59f: 0xba, + 0x5a0: 0xba, 0x5a1: 0xba, 0x5a2: 0xba, 0x5a3: 0xba, 0x5a4: 0xba, 0x5a5: 0xba, 0x5a6: 0xba, 0x5a7: 0xba, + 0x5a8: 0xba, 0x5a9: 0xba, 0x5aa: 0xba, 0x5ab: 0xba, 0x5ac: 0xba, 0x5ad: 0xba, 0x5ae: 0xba, 0x5af: 0xba, + 0x5b0: 0x9f, 0x5b1: 0x15a, 0x5b2: 0x15b, 0x5b3: 0xba, 0x5b4: 0xba, 0x5b5: 0xba, 0x5b6: 0xba, 0x5b7: 0xba, + 0x5b8: 0xba, 0x5b9: 0xba, 0x5ba: 0xba, 0x5bb: 0xba, 0x5bc: 0xba, 0x5bd: 0xba, 0x5be: 0xba, 0x5bf: 0xba, + // Block 0x17, offset 0x5c0 + 0x5c0: 0x9b, 0x5c1: 0x9b, 0x5c2: 0x9b, 0x5c3: 0x15c, 0x5c4: 0x15d, 0x5c5: 0x15e, 0x5c6: 0x15f, 0x5c7: 0x160, + 0x5c8: 0x9b, 0x5c9: 0x161, 0x5ca: 0xba, 0x5cb: 0xba, 0x5cc: 0x9b, 0x5cd: 0x162, 0x5ce: 0xba, 0x5cf: 0xba, + 0x5d0: 0x5f, 0x5d1: 0x60, 0x5d2: 0x61, 0x5d3: 0x62, 0x5d4: 0x63, 0x5d5: 0x64, 0x5d6: 0x65, 0x5d7: 0x66, + 0x5d8: 0x67, 0x5d9: 0x68, 0x5da: 0x69, 0x5db: 0x6a, 0x5dc: 0x6b, 0x5dd: 0x6c, 0x5de: 0x6d, 0x5df: 0x6e, + 0x5e0: 0x9b, 0x5e1: 0x9b, 0x5e2: 0x9b, 0x5e3: 0x9b, 0x5e4: 0x9b, 0x5e5: 0x9b, 0x5e6: 0x9b, 0x5e7: 0x9b, + 0x5e8: 0x163, 0x5e9: 0x164, 0x5ea: 0x165, 0x5eb: 0xba, 0x5ec: 0xba, 0x5ed: 0xba, 0x5ee: 0xba, 0x5ef: 0xba, + 0x5f0: 0xba, 0x5f1: 0xba, 0x5f2: 0xba, 0x5f3: 0xba, 0x5f4: 0xba, 0x5f5: 0xba, 0x5f6: 0xba, 0x5f7: 0xba, + 0x5f8: 0xba, 0x5f9: 0xba, 0x5fa: 0xba, 0x5fb: 0xba, 0x5fc: 0xba, 0x5fd: 0xba, 0x5fe: 0xba, 0x5ff: 0xba, + // Block 0x18, offset 0x600 + 0x600: 0x166, 0x601: 0xba, 0x602: 0xba, 0x603: 0xba, 0x604: 0xba, 0x605: 0xba, 0x606: 0xba, 0x607: 0xba, + 0x608: 0xba, 0x609: 0xba, 0x60a: 0xba, 0x60b: 0xba, 0x60c: 0xba, 0x60d: 0xba, 0x60e: 0xba, 0x60f: 0xba, + 0x610: 0xba, 0x611: 0xba, 0x612: 0xba, 0x613: 0xba, 0x614: 0xba, 0x615: 0xba, 0x616: 0xba, 0x617: 0xba, + 0x618: 0xba, 0x619: 0xba, 0x61a: 0xba, 0x61b: 0xba, 0x61c: 0xba, 0x61d: 0xba, 0x61e: 0xba, 0x61f: 0xba, + 0x620: 0x122, 0x621: 0x122, 0x622: 0x122, 0x623: 0x167, 0x624: 0x6f, 0x625: 0x168, 0x626: 0xba, 0x627: 0xba, + 0x628: 0xba, 0x629: 0xba, 0x62a: 0xba, 0x62b: 0xba, 0x62c: 0xba, 0x62d: 0xba, 0x62e: 0xba, 0x62f: 0xba, + 0x630: 0xba, 0x631: 0xba, 0x632: 0xba, 0x633: 0xba, 0x634: 0xba, 0x635: 0xba, 0x636: 0xba, 0x637: 0xba, + 0x638: 0x70, 0x639: 0x71, 0x63a: 0x72, 0x63b: 0x169, 0x63c: 0xba, 0x63d: 0xba, 0x63e: 0xba, 0x63f: 0xba, + // Block 0x19, offset 0x640 + 0x640: 0x16a, 0x641: 0x9b, 0x642: 0x16b, 0x643: 0x16c, 0x644: 0x73, 0x645: 0x74, 0x646: 0x16d, 0x647: 0x16e, + 0x648: 0x75, 0x649: 0x16f, 0x64a: 0xba, 0x64b: 0xba, 0x64c: 0x9b, 0x64d: 0x9b, 0x64e: 0x9b, 0x64f: 0x9b, + 0x650: 0x9b, 0x651: 0x9b, 0x652: 0x9b, 0x653: 0x9b, 0x654: 0x9b, 0x655: 0x9b, 0x656: 0x9b, 0x657: 0x9b, + 0x658: 0x9b, 0x659: 0x9b, 0x65a: 0x9b, 0x65b: 0x170, 0x65c: 0x9b, 0x65d: 0x171, 0x65e: 0x9b, 0x65f: 0x172, + 0x660: 0x173, 0x661: 0x174, 0x662: 0x175, 0x663: 0xba, 0x664: 0x176, 0x665: 0x177, 0x666: 0x178, 0x667: 0x179, + 0x668: 0xba, 0x669: 0xba, 0x66a: 0xba, 0x66b: 0xba, 0x66c: 0xba, 0x66d: 0xba, 0x66e: 0xba, 0x66f: 0xba, + 0x670: 0xba, 0x671: 0xba, 0x672: 0xba, 0x673: 0xba, 0x674: 0xba, 0x675: 0xba, 0x676: 0xba, 0x677: 0xba, + 0x678: 0xba, 0x679: 0xba, 0x67a: 0xba, 0x67b: 0xba, 0x67c: 0xba, 0x67d: 0xba, 0x67e: 0xba, 0x67f: 0xba, + // Block 0x1a, offset 0x680 + 0x680: 0x9f, 0x681: 0x9f, 0x682: 0x9f, 0x683: 0x9f, 0x684: 0x9f, 0x685: 0x9f, 0x686: 0x9f, 0x687: 0x9f, + 0x688: 0x9f, 0x689: 0x9f, 0x68a: 0x9f, 0x68b: 0x9f, 0x68c: 0x9f, 0x68d: 0x9f, 0x68e: 0x9f, 0x68f: 0x9f, + 0x690: 0x9f, 0x691: 0x9f, 0x692: 0x9f, 0x693: 0x9f, 0x694: 0x9f, 0x695: 0x9f, 0x696: 0x9f, 0x697: 0x9f, + 0x698: 0x9f, 0x699: 0x9f, 0x69a: 0x9f, 0x69b: 0x17a, 0x69c: 0x9f, 0x69d: 0x9f, 0x69e: 0x9f, 0x69f: 0x9f, + 0x6a0: 0x9f, 0x6a1: 0x9f, 0x6a2: 0x9f, 0x6a3: 0x9f, 0x6a4: 0x9f, 0x6a5: 0x9f, 0x6a6: 0x9f, 0x6a7: 0x9f, + 0x6a8: 0x9f, 0x6a9: 0x9f, 0x6aa: 0x9f, 0x6ab: 0x9f, 0x6ac: 0x9f, 0x6ad: 0x9f, 0x6ae: 0x9f, 0x6af: 0x9f, + 0x6b0: 0x9f, 0x6b1: 0x9f, 0x6b2: 0x9f, 0x6b3: 0x9f, 0x6b4: 0x9f, 0x6b5: 0x9f, 0x6b6: 0x9f, 0x6b7: 0x9f, + 0x6b8: 0x9f, 0x6b9: 0x9f, 0x6ba: 0x9f, 0x6bb: 0x9f, 0x6bc: 0x9f, 0x6bd: 0x9f, 0x6be: 0x9f, 0x6bf: 0x9f, + // Block 0x1b, offset 0x6c0 + 0x6c0: 0x9f, 0x6c1: 0x9f, 0x6c2: 0x9f, 0x6c3: 0x9f, 0x6c4: 0x9f, 0x6c5: 0x9f, 0x6c6: 0x9f, 0x6c7: 0x9f, + 0x6c8: 0x9f, 0x6c9: 0x9f, 0x6ca: 0x9f, 0x6cb: 0x9f, 0x6cc: 0x9f, 0x6cd: 0x9f, 0x6ce: 0x9f, 0x6cf: 0x9f, + 0x6d0: 0x9f, 0x6d1: 0x9f, 0x6d2: 0x9f, 0x6d3: 0x9f, 0x6d4: 0x9f, 0x6d5: 0x9f, 0x6d6: 0x9f, 0x6d7: 0x9f, + 0x6d8: 0x9f, 0x6d9: 0x9f, 0x6da: 0x9f, 0x6db: 0x9f, 0x6dc: 0x17b, 0x6dd: 0x9f, 0x6de: 0x9f, 0x6df: 0x9f, + 0x6e0: 0x17c, 0x6e1: 0x9f, 0x6e2: 0x9f, 0x6e3: 0x9f, 0x6e4: 0x9f, 0x6e5: 0x9f, 0x6e6: 0x9f, 0x6e7: 0x9f, + 0x6e8: 0x9f, 0x6e9: 0x9f, 0x6ea: 0x9f, 0x6eb: 0x9f, 0x6ec: 0x9f, 0x6ed: 0x9f, 0x6ee: 0x9f, 0x6ef: 0x9f, + 0x6f0: 0x9f, 0x6f1: 0x9f, 0x6f2: 0x9f, 0x6f3: 0x9f, 0x6f4: 0x9f, 0x6f5: 0x9f, 0x6f6: 0x9f, 0x6f7: 0x9f, + 0x6f8: 0x9f, 0x6f9: 0x9f, 0x6fa: 0x9f, 0x6fb: 0x9f, 0x6fc: 0x9f, 0x6fd: 0x9f, 0x6fe: 0x9f, 0x6ff: 0x9f, + // Block 0x1c, offset 0x700 + 0x700: 0x9f, 0x701: 0x9f, 0x702: 0x9f, 0x703: 0x9f, 0x704: 0x9f, 0x705: 0x9f, 0x706: 0x9f, 0x707: 0x9f, + 0x708: 0x9f, 0x709: 0x9f, 0x70a: 0x9f, 0x70b: 0x9f, 0x70c: 0x9f, 0x70d: 0x9f, 0x70e: 0x9f, 0x70f: 0x9f, + 0x710: 0x9f, 0x711: 0x9f, 0x712: 0x9f, 0x713: 0x9f, 0x714: 0x9f, 0x715: 0x9f, 0x716: 0x9f, 0x717: 0x9f, + 0x718: 0x9f, 0x719: 0x9f, 0x71a: 0x9f, 0x71b: 0x9f, 0x71c: 0x9f, 0x71d: 0x9f, 0x71e: 0x9f, 0x71f: 0x9f, + 0x720: 0x9f, 0x721: 0x9f, 0x722: 0x9f, 0x723: 0x9f, 0x724: 0x9f, 0x725: 0x9f, 0x726: 0x9f, 0x727: 0x9f, + 0x728: 0x9f, 0x729: 0x9f, 0x72a: 0x9f, 0x72b: 0x9f, 0x72c: 0x9f, 0x72d: 0x9f, 0x72e: 0x9f, 0x72f: 0x9f, + 0x730: 0x9f, 0x731: 0x9f, 0x732: 0x9f, 0x733: 0x9f, 0x734: 0x9f, 0x735: 0x9f, 0x736: 0x9f, 0x737: 0x9f, + 0x738: 0x9f, 0x739: 0x9f, 0x73a: 0x17d, 0x73b: 0x9f, 0x73c: 0x9f, 0x73d: 0x9f, 0x73e: 0x9f, 0x73f: 0x9f, + // Block 0x1d, offset 0x740 + 0x740: 0x9f, 0x741: 0x9f, 0x742: 0x9f, 0x743: 0x9f, 0x744: 0x9f, 0x745: 0x9f, 0x746: 0x9f, 0x747: 0x9f, + 0x748: 0x9f, 0x749: 0x9f, 0x74a: 0x9f, 0x74b: 0x9f, 0x74c: 0x9f, 0x74d: 0x9f, 0x74e: 0x9f, 0x74f: 0x9f, + 0x750: 0x9f, 0x751: 0x9f, 0x752: 0x9f, 0x753: 0x9f, 0x754: 0x9f, 0x755: 0x9f, 0x756: 0x9f, 0x757: 0x9f, + 0x758: 0x9f, 0x759: 0x9f, 0x75a: 0x9f, 0x75b: 0x9f, 0x75c: 0x9f, 0x75d: 0x9f, 0x75e: 0x9f, 0x75f: 0x9f, + 0x760: 0x9f, 0x761: 0x9f, 0x762: 0x9f, 0x763: 0x9f, 0x764: 0x9f, 0x765: 0x9f, 0x766: 0x9f, 0x767: 0x9f, + 0x768: 0x9f, 0x769: 0x9f, 0x76a: 0x9f, 0x76b: 0x9f, 0x76c: 0x9f, 0x76d: 0x9f, 0x76e: 0x9f, 0x76f: 0x17e, + 0x770: 0xba, 0x771: 0xba, 0x772: 0xba, 0x773: 0xba, 0x774: 0xba, 0x775: 0xba, 0x776: 0xba, 0x777: 0xba, + 0x778: 0xba, 0x779: 0xba, 0x77a: 0xba, 0x77b: 0xba, 0x77c: 0xba, 0x77d: 0xba, 0x77e: 0xba, 0x77f: 0xba, + // Block 0x1e, offset 0x780 + 0x780: 0xba, 0x781: 0xba, 0x782: 0xba, 0x783: 0xba, 0x784: 0xba, 0x785: 0xba, 0x786: 0xba, 0x787: 0xba, + 0x788: 0xba, 0x789: 0xba, 0x78a: 0xba, 0x78b: 0xba, 0x78c: 0xba, 0x78d: 0xba, 0x78e: 0xba, 0x78f: 0xba, + 0x790: 0xba, 0x791: 0xba, 0x792: 0xba, 0x793: 0xba, 0x794: 0xba, 0x795: 0xba, 0x796: 0xba, 0x797: 0xba, + 0x798: 0xba, 0x799: 0xba, 0x79a: 0xba, 0x79b: 0xba, 0x79c: 0xba, 0x79d: 0xba, 0x79e: 0xba, 0x79f: 0xba, + 0x7a0: 0x76, 0x7a1: 0x77, 0x7a2: 0x78, 0x7a3: 0x17f, 0x7a4: 0x79, 0x7a5: 0x7a, 0x7a6: 0x180, 0x7a7: 0x7b, + 0x7a8: 0x7c, 0x7a9: 0xba, 0x7aa: 0xba, 0x7ab: 0xba, 0x7ac: 0xba, 0x7ad: 0xba, 0x7ae: 0xba, 0x7af: 0xba, + 0x7b0: 0xba, 0x7b1: 0xba, 0x7b2: 0xba, 0x7b3: 0xba, 0x7b4: 0xba, 0x7b5: 0xba, 0x7b6: 0xba, 0x7b7: 0xba, + 0x7b8: 0xba, 0x7b9: 0xba, 0x7ba: 0xba, 0x7bb: 0xba, 0x7bc: 0xba, 0x7bd: 0xba, 0x7be: 0xba, 0x7bf: 0xba, + // Block 0x1f, offset 0x7c0 + 0x7d0: 0x0d, 0x7d1: 0x0e, 0x7d2: 0x0f, 0x7d3: 0x10, 0x7d4: 0x11, 0x7d5: 0x0b, 0x7d6: 0x12, 0x7d7: 0x07, + 0x7d8: 0x13, 0x7d9: 0x0b, 0x7da: 0x0b, 0x7db: 0x14, 0x7dc: 0x0b, 0x7dd: 0x15, 0x7de: 0x16, 0x7df: 0x17, + 0x7e0: 0x07, 0x7e1: 0x07, 0x7e2: 0x07, 0x7e3: 0x07, 0x7e4: 0x07, 0x7e5: 0x07, 0x7e6: 0x07, 0x7e7: 0x07, + 0x7e8: 0x07, 0x7e9: 0x07, 0x7ea: 0x18, 0x7eb: 0x19, 0x7ec: 0x1a, 0x7ed: 0x07, 0x7ee: 0x1b, 0x7ef: 0x1c, + 0x7f0: 0x0b, 0x7f1: 0x0b, 0x7f2: 0x0b, 0x7f3: 0x0b, 0x7f4: 0x0b, 0x7f5: 0x0b, 0x7f6: 0x0b, 0x7f7: 0x0b, + 0x7f8: 0x0b, 0x7f9: 0x0b, 0x7fa: 0x0b, 0x7fb: 0x0b, 0x7fc: 0x0b, 0x7fd: 0x0b, 0x7fe: 0x0b, 0x7ff: 0x0b, + // Block 0x20, offset 0x800 + 0x800: 0x0b, 0x801: 0x0b, 0x802: 0x0b, 0x803: 0x0b, 0x804: 0x0b, 0x805: 0x0b, 0x806: 0x0b, 0x807: 0x0b, + 0x808: 0x0b, 0x809: 0x0b, 0x80a: 0x0b, 0x80b: 0x0b, 0x80c: 0x0b, 0x80d: 0x0b, 0x80e: 0x0b, 0x80f: 0x0b, + 0x810: 0x0b, 0x811: 0x0b, 0x812: 0x0b, 0x813: 0x0b, 0x814: 0x0b, 0x815: 0x0b, 0x816: 0x0b, 0x817: 0x0b, + 0x818: 0x0b, 0x819: 0x0b, 0x81a: 0x0b, 0x81b: 0x0b, 0x81c: 0x0b, 0x81d: 0x0b, 0x81e: 0x0b, 0x81f: 0x0b, + 0x820: 0x0b, 0x821: 0x0b, 0x822: 0x0b, 0x823: 0x0b, 0x824: 0x0b, 0x825: 0x0b, 0x826: 0x0b, 0x827: 0x0b, + 0x828: 0x0b, 0x829: 0x0b, 0x82a: 0x0b, 0x82b: 0x0b, 0x82c: 0x0b, 0x82d: 0x0b, 0x82e: 0x0b, 0x82f: 0x0b, + 0x830: 0x0b, 0x831: 0x0b, 0x832: 0x0b, 0x833: 0x0b, 0x834: 0x0b, 0x835: 0x0b, 0x836: 0x0b, 0x837: 0x0b, + 0x838: 0x0b, 0x839: 0x0b, 0x83a: 0x0b, 0x83b: 0x0b, 0x83c: 0x0b, 0x83d: 0x0b, 0x83e: 0x0b, 0x83f: 0x0b, + // Block 0x21, offset 0x840 + 0x840: 0x181, 0x841: 0x182, 0x842: 0xba, 0x843: 0xba, 0x844: 0x183, 0x845: 0x183, 0x846: 0x183, 0x847: 0x184, + 0x848: 0xba, 0x849: 0xba, 0x84a: 0xba, 0x84b: 0xba, 0x84c: 0xba, 0x84d: 0xba, 0x84e: 0xba, 0x84f: 0xba, + 0x850: 0xba, 0x851: 0xba, 0x852: 0xba, 0x853: 0xba, 0x854: 0xba, 0x855: 0xba, 0x856: 0xba, 0x857: 0xba, + 0x858: 0xba, 0x859: 0xba, 0x85a: 0xba, 0x85b: 0xba, 0x85c: 0xba, 0x85d: 0xba, 0x85e: 0xba, 0x85f: 0xba, + 0x860: 0xba, 0x861: 0xba, 0x862: 0xba, 0x863: 0xba, 0x864: 0xba, 0x865: 0xba, 0x866: 0xba, 0x867: 0xba, + 0x868: 0xba, 0x869: 0xba, 0x86a: 0xba, 0x86b: 0xba, 0x86c: 0xba, 0x86d: 0xba, 0x86e: 0xba, 0x86f: 0xba, + 0x870: 0xba, 0x871: 0xba, 0x872: 0xba, 0x873: 0xba, 0x874: 0xba, 0x875: 0xba, 0x876: 0xba, 0x877: 0xba, + 0x878: 0xba, 0x879: 0xba, 0x87a: 0xba, 0x87b: 0xba, 0x87c: 0xba, 0x87d: 0xba, 0x87e: 0xba, 0x87f: 0xba, + // Block 0x22, offset 0x880 + 0x880: 0x0b, 0x881: 0x0b, 0x882: 0x0b, 0x883: 0x0b, 0x884: 0x0b, 0x885: 0x0b, 0x886: 0x0b, 0x887: 0x0b, + 0x888: 0x0b, 0x889: 0x0b, 0x88a: 0x0b, 0x88b: 0x0b, 0x88c: 0x0b, 0x88d: 0x0b, 0x88e: 0x0b, 0x88f: 0x0b, + 0x890: 0x0b, 0x891: 0x0b, 0x892: 0x0b, 0x893: 0x0b, 0x894: 0x0b, 0x895: 0x0b, 0x896: 0x0b, 0x897: 0x0b, + 0x898: 0x0b, 0x899: 0x0b, 0x89a: 0x0b, 0x89b: 0x0b, 0x89c: 0x0b, 0x89d: 0x0b, 0x89e: 0x0b, 0x89f: 0x0b, + 0x8a0: 0x1f, 0x8a1: 0x0b, 0x8a2: 0x0b, 0x8a3: 0x0b, 0x8a4: 0x0b, 0x8a5: 0x0b, 0x8a6: 0x0b, 0x8a7: 0x0b, + 0x8a8: 0x0b, 0x8a9: 0x0b, 0x8aa: 0x0b, 0x8ab: 0x0b, 0x8ac: 0x0b, 0x8ad: 0x0b, 0x8ae: 0x0b, 0x8af: 0x0b, + 0x8b0: 0x0b, 0x8b1: 0x0b, 0x8b2: 0x0b, 0x8b3: 0x0b, 0x8b4: 0x0b, 0x8b5: 0x0b, 0x8b6: 0x0b, 0x8b7: 0x0b, + 0x8b8: 0x0b, 0x8b9: 0x0b, 0x8ba: 0x0b, 0x8bb: 0x0b, 0x8bc: 0x0b, 0x8bd: 0x0b, 0x8be: 0x0b, 0x8bf: 0x0b, + // Block 0x23, offset 0x8c0 + 0x8c0: 0x0b, 0x8c1: 0x0b, 0x8c2: 0x0b, 0x8c3: 0x0b, 0x8c4: 0x0b, 0x8c5: 0x0b, 0x8c6: 0x0b, 0x8c7: 0x0b, + 0x8c8: 0x0b, 0x8c9: 0x0b, 0x8ca: 0x0b, 0x8cb: 0x0b, 0x8cc: 0x0b, 0x8cd: 0x0b, 0x8ce: 0x0b, 0x8cf: 0x0b, +} + +// idnaSparseOffset: 264 entries, 528 bytes +var idnaSparseOffset = []uint16{0x0, 0x8, 0x19, 0x25, 0x27, 0x2c, 0x34, 0x3f, 0x4b, 0x4f, 0x5e, 0x63, 0x6b, 0x77, 0x85, 0x8a, 0x93, 0xa3, 0xb1, 0xbd, 0xc9, 0xda, 0xe4, 0xeb, 0xf8, 0x109, 0x110, 0x11b, 0x12a, 0x138, 0x142, 0x144, 0x149, 0x14c, 0x14f, 0x151, 0x15d, 0x168, 0x170, 0x176, 0x17c, 0x181, 0x186, 0x189, 0x18d, 0x193, 0x198, 0x1a4, 0x1ae, 0x1b4, 0x1c5, 0x1cf, 0x1d2, 0x1da, 0x1dd, 0x1ea, 0x1f2, 0x1f6, 0x1fd, 0x205, 0x215, 0x221, 0x223, 0x22d, 0x239, 0x245, 0x251, 0x259, 0x25e, 0x268, 0x279, 0x27d, 0x288, 0x28c, 0x295, 0x29d, 0x2a3, 0x2a8, 0x2ab, 0x2af, 0x2b5, 0x2b9, 0x2bd, 0x2c3, 0x2ca, 0x2d0, 0x2d8, 0x2df, 0x2ea, 0x2f4, 0x2f8, 0x2fb, 0x301, 0x305, 0x307, 0x30a, 0x30c, 0x30f, 0x319, 0x31c, 0x32b, 0x32f, 0x334, 0x337, 0x33b, 0x340, 0x345, 0x34b, 0x351, 0x360, 0x366, 0x36a, 0x379, 0x37e, 0x386, 0x390, 0x39b, 0x3a3, 0x3b4, 0x3bd, 0x3cd, 0x3da, 0x3e4, 0x3e9, 0x3f6, 0x3fa, 0x3ff, 0x401, 0x405, 0x407, 0x40b, 0x414, 0x41a, 0x41e, 0x42e, 0x438, 0x43d, 0x440, 0x446, 0x44d, 0x452, 0x456, 0x45c, 0x461, 0x46a, 0x46f, 0x475, 0x47c, 0x483, 0x48a, 0x48e, 0x493, 0x496, 0x49b, 0x4a7, 0x4ad, 0x4b2, 0x4b9, 0x4c1, 0x4c6, 0x4ca, 0x4da, 0x4e1, 0x4e5, 0x4e9, 0x4f0, 0x4f2, 0x4f5, 0x4f8, 0x4fc, 0x500, 0x506, 0x50f, 0x51b, 0x522, 0x52b, 0x533, 0x53a, 0x548, 0x555, 0x562, 0x56b, 0x56f, 0x57d, 0x585, 0x590, 0x599, 0x59f, 0x5a7, 0x5b0, 0x5ba, 0x5bd, 0x5c9, 0x5cc, 0x5d1, 0x5de, 0x5e7, 0x5f3, 0x5f6, 0x600, 0x609, 0x615, 0x622, 0x62a, 0x62d, 0x632, 0x635, 0x638, 0x63b, 0x642, 0x649, 0x64d, 0x658, 0x65b, 0x661, 0x666, 0x66a, 0x66d, 0x670, 0x673, 0x676, 0x679, 0x67e, 0x688, 0x68b, 0x68f, 0x69e, 0x6aa, 0x6ae, 0x6b3, 0x6b8, 0x6bc, 0x6c1, 0x6ca, 0x6d5, 0x6db, 0x6e3, 0x6e7, 0x6eb, 0x6f1, 0x6f7, 0x6fc, 0x6ff, 0x70f, 0x716, 0x719, 0x71c, 0x720, 0x726, 0x72b, 0x730, 0x735, 0x738, 0x73d, 0x740, 0x743, 0x747, 0x74b, 0x74e, 0x75e, 0x76f, 0x774, 0x776, 0x778} + +// idnaSparseValues: 1915 entries, 7660 bytes +var idnaSparseValues = [1915]valueRange{ + // Block 0x0, offset 0x0 + {value: 0x0000, lo: 0x07}, + {value: 0xe105, lo: 0x80, hi: 0x96}, + {value: 0x0018, lo: 0x97, hi: 0x97}, + {value: 0xe105, lo: 0x98, hi: 0x9e}, + {value: 0x001f, lo: 0x9f, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xb6}, + {value: 0x0018, lo: 0xb7, hi: 0xb7}, + {value: 0x0008, lo: 0xb8, hi: 0xbf}, + // Block 0x1, offset 0x8 + {value: 0x0000, lo: 0x10}, + {value: 0x0008, lo: 0x80, hi: 0x80}, + {value: 0xe01d, lo: 0x81, hi: 0x81}, + {value: 0x0008, lo: 0x82, hi: 0x82}, + {value: 0x0335, lo: 0x83, hi: 0x83}, + {value: 0x034d, lo: 0x84, hi: 0x84}, + {value: 0x0365, lo: 0x85, hi: 0x85}, + {value: 0xe00d, lo: 0x86, hi: 0x86}, + {value: 0x0008, lo: 0x87, hi: 0x87}, + {value: 0xe00d, lo: 0x88, hi: 0x88}, + {value: 0x0008, lo: 0x89, hi: 0x89}, + {value: 0xe00d, lo: 0x8a, hi: 0x8a}, + {value: 0x0008, lo: 0x8b, hi: 0x8b}, + {value: 0xe00d, lo: 0x8c, hi: 0x8c}, + {value: 0x0008, lo: 0x8d, hi: 0x8d}, + {value: 0xe00d, lo: 0x8e, hi: 0x8e}, + {value: 0x0008, lo: 0x8f, hi: 0xbf}, + // Block 0x2, offset 0x19 + {value: 0x0000, lo: 0x0b}, + {value: 0x0008, lo: 0x80, hi: 0xaf}, + {value: 0x0249, lo: 0xb0, hi: 0xb0}, + {value: 0x037d, lo: 0xb1, hi: 0xb1}, + {value: 0x0259, lo: 0xb2, hi: 0xb2}, + {value: 0x0269, lo: 0xb3, hi: 0xb3}, + {value: 0x034d, lo: 0xb4, hi: 0xb4}, + {value: 0x0395, lo: 0xb5, hi: 0xb5}, + {value: 0xe1bd, lo: 0xb6, hi: 0xb6}, + {value: 0x0279, lo: 0xb7, hi: 0xb7}, + {value: 0x0289, lo: 0xb8, hi: 0xb8}, + {value: 0x0008, lo: 0xb9, hi: 0xbf}, + // Block 0x3, offset 0x25 + {value: 0x0000, lo: 0x01}, + {value: 0x3308, lo: 0x80, hi: 0xbf}, + // Block 0x4, offset 0x27 + {value: 0x0000, lo: 0x04}, + {value: 0x03f5, lo: 0x80, hi: 0x8f}, + {value: 0xe105, lo: 0x90, hi: 0x9f}, + {value: 0x049d, lo: 0xa0, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbf}, + // Block 0x5, offset 0x2c + {value: 0x0000, lo: 0x07}, + {value: 0xe185, lo: 0x80, hi: 0x8f}, + {value: 0x0545, lo: 0x90, hi: 0x96}, + {value: 0x0040, lo: 0x97, hi: 0x98}, + {value: 0x0008, lo: 0x99, hi: 0x99}, + {value: 0x0018, lo: 0x9a, hi: 0x9f}, + {value: 0x0040, lo: 0xa0, hi: 0xa0}, + {value: 0x0008, lo: 0xa1, hi: 0xbf}, + // Block 0x6, offset 0x34 + {value: 0x0000, lo: 0x0a}, + {value: 0x0008, lo: 0x80, hi: 0x86}, + {value: 0x0401, lo: 0x87, hi: 0x87}, + {value: 0x0040, lo: 0x88, hi: 0x88}, + {value: 0x0018, lo: 0x89, hi: 0x8a}, + {value: 0x0040, lo: 0x8b, hi: 0x8c}, + {value: 0x0018, lo: 0x8d, hi: 0x8f}, + {value: 0x0040, lo: 0x90, hi: 0x90}, + {value: 0x3308, lo: 0x91, hi: 0xbd}, + {value: 0x0818, lo: 0xbe, hi: 0xbe}, + {value: 0x3308, lo: 0xbf, hi: 0xbf}, + // Block 0x7, offset 0x3f + {value: 0x0000, lo: 0x0b}, + {value: 0x0818, lo: 0x80, hi: 0x80}, + {value: 0x3308, lo: 0x81, hi: 0x82}, + {value: 0x0818, lo: 0x83, hi: 0x83}, + {value: 0x3308, lo: 0x84, hi: 0x85}, + {value: 0x0818, lo: 0x86, hi: 0x86}, + {value: 0x3308, lo: 0x87, hi: 0x87}, + {value: 0x0040, lo: 0x88, hi: 0x8f}, + {value: 0x0808, lo: 0x90, hi: 0xaa}, + {value: 0x0040, lo: 0xab, hi: 0xaf}, + {value: 0x0808, lo: 0xb0, hi: 0xb4}, + {value: 0x0040, lo: 0xb5, hi: 0xbf}, + // Block 0x8, offset 0x4b + {value: 0x0000, lo: 0x03}, + {value: 0x0a08, lo: 0x80, hi: 0x87}, + {value: 0x0c08, lo: 0x88, hi: 0x99}, + {value: 0x0a08, lo: 0x9a, hi: 0xbf}, + // Block 0x9, offset 0x4f + {value: 0x0000, lo: 0x0e}, + {value: 0x3308, lo: 0x80, hi: 0x8a}, + {value: 0x0040, lo: 0x8b, hi: 0x8c}, + {value: 0x0c08, lo: 0x8d, hi: 0x8d}, + {value: 0x0a08, lo: 0x8e, hi: 0x98}, + {value: 0x0c08, lo: 0x99, hi: 0x9b}, + {value: 0x0a08, lo: 0x9c, hi: 0xaa}, + {value: 0x0c08, lo: 0xab, hi: 0xac}, + {value: 0x0a08, lo: 0xad, hi: 0xb0}, + {value: 0x0c08, lo: 0xb1, hi: 0xb1}, + {value: 0x0a08, lo: 0xb2, hi: 0xb2}, + {value: 0x0c08, lo: 0xb3, hi: 0xb4}, + {value: 0x0a08, lo: 0xb5, hi: 0xb7}, + {value: 0x0c08, lo: 0xb8, hi: 0xb9}, + {value: 0x0a08, lo: 0xba, hi: 0xbf}, + // Block 0xa, offset 0x5e + {value: 0x0000, lo: 0x04}, + {value: 0x0808, lo: 0x80, hi: 0xa5}, + {value: 0x3308, lo: 0xa6, hi: 0xb0}, + {value: 0x0808, lo: 0xb1, hi: 0xb1}, + {value: 0x0040, lo: 0xb2, hi: 0xbf}, + // Block 0xb, offset 0x63 + {value: 0x0000, lo: 0x07}, + {value: 0x0808, lo: 0x80, hi: 0x89}, + {value: 0x0a08, lo: 0x8a, hi: 0xaa}, + {value: 0x3308, lo: 0xab, hi: 0xb3}, + {value: 0x0808, lo: 0xb4, hi: 0xb5}, + {value: 0x0018, lo: 0xb6, hi: 0xb9}, + {value: 0x0818, lo: 0xba, hi: 0xba}, + {value: 0x0040, lo: 0xbb, hi: 0xbf}, + // Block 0xc, offset 0x6b + {value: 0x0000, lo: 0x0b}, + {value: 0x0808, lo: 0x80, hi: 0x95}, + {value: 0x3308, lo: 0x96, hi: 0x99}, + {value: 0x0808, lo: 0x9a, hi: 0x9a}, + {value: 0x3308, lo: 0x9b, hi: 0xa3}, + {value: 0x0808, lo: 0xa4, hi: 0xa4}, + {value: 0x3308, lo: 0xa5, hi: 0xa7}, + {value: 0x0808, lo: 0xa8, hi: 0xa8}, + {value: 0x3308, lo: 0xa9, hi: 0xad}, + {value: 0x0040, lo: 0xae, hi: 0xaf}, + {value: 0x0818, lo: 0xb0, hi: 0xbe}, + {value: 0x0040, lo: 0xbf, hi: 0xbf}, + // Block 0xd, offset 0x77 + {value: 0x0000, lo: 0x0d}, + {value: 0x0040, lo: 0x80, hi: 0x9f}, + {value: 0x0a08, lo: 0xa0, hi: 0xa9}, + {value: 0x0c08, lo: 0xaa, hi: 0xac}, + {value: 0x0808, lo: 0xad, hi: 0xad}, + {value: 0x0c08, lo: 0xae, hi: 0xae}, + {value: 0x0a08, lo: 0xaf, hi: 0xb0}, + {value: 0x0c08, lo: 0xb1, hi: 0xb2}, + {value: 0x0a08, lo: 0xb3, hi: 0xb4}, + {value: 0x0040, lo: 0xb5, hi: 0xb5}, + {value: 0x0a08, lo: 0xb6, hi: 0xb8}, + {value: 0x0c08, lo: 0xb9, hi: 0xb9}, + {value: 0x0a08, lo: 0xba, hi: 0xbd}, + {value: 0x0040, lo: 0xbe, hi: 0xbf}, + // Block 0xe, offset 0x85 + {value: 0x0000, lo: 0x04}, + {value: 0x0040, lo: 0x80, hi: 0x93}, + {value: 0x3308, lo: 0x94, hi: 0xa1}, + {value: 0x0840, lo: 0xa2, hi: 0xa2}, + {value: 0x3308, lo: 0xa3, hi: 0xbf}, + // Block 0xf, offset 0x8a + {value: 0x0000, lo: 0x08}, + {value: 0x3308, lo: 0x80, hi: 0x82}, + {value: 0x3008, lo: 0x83, hi: 0x83}, + {value: 0x0008, lo: 0x84, hi: 0xb9}, + {value: 0x3308, lo: 0xba, hi: 0xba}, + {value: 0x3008, lo: 0xbb, hi: 0xbb}, + {value: 0x3308, lo: 0xbc, hi: 0xbc}, + {value: 0x0008, lo: 0xbd, hi: 0xbd}, + {value: 0x3008, lo: 0xbe, hi: 0xbf}, + // Block 0x10, offset 0x93 + {value: 0x0000, lo: 0x0f}, + {value: 0x3308, lo: 0x80, hi: 0x80}, + {value: 0x3008, lo: 0x81, hi: 0x82}, + {value: 0x0040, lo: 0x83, hi: 0x85}, + {value: 0x3008, lo: 0x86, hi: 0x88}, + {value: 0x0040, lo: 0x89, hi: 0x89}, + {value: 0x3008, lo: 0x8a, hi: 0x8c}, + {value: 0x3b08, lo: 0x8d, hi: 0x8d}, + {value: 0x0040, lo: 0x8e, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x90}, + {value: 0x0040, lo: 0x91, hi: 0x96}, + {value: 0x3008, lo: 0x97, hi: 0x97}, + {value: 0x0040, lo: 0x98, hi: 0xa5}, + {value: 0x0008, lo: 0xa6, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xba}, + {value: 0x0040, lo: 0xbb, hi: 0xbf}, + // Block 0x11, offset 0xa3 + {value: 0x0000, lo: 0x0d}, + {value: 0x3308, lo: 0x80, hi: 0x80}, + {value: 0x3008, lo: 0x81, hi: 0x83}, + {value: 0x0040, lo: 0x84, hi: 0x84}, + {value: 0x0008, lo: 0x85, hi: 0x8c}, + {value: 0x0040, lo: 0x8d, hi: 0x8d}, + {value: 0x0008, lo: 0x8e, hi: 0x90}, + {value: 0x0040, lo: 0x91, hi: 0x91}, + {value: 0x0008, lo: 0x92, hi: 0xa8}, + {value: 0x0040, lo: 0xa9, hi: 0xa9}, + {value: 0x0008, lo: 0xaa, hi: 0xb9}, + {value: 0x0040, lo: 0xba, hi: 0xbc}, + {value: 0x0008, lo: 0xbd, hi: 0xbd}, + {value: 0x3308, lo: 0xbe, hi: 0xbf}, + // Block 0x12, offset 0xb1 + {value: 0x0000, lo: 0x0b}, + {value: 0x3308, lo: 0x80, hi: 0x81}, + {value: 0x3008, lo: 0x82, hi: 0x83}, + {value: 0x0040, lo: 0x84, hi: 0x84}, + {value: 0x0008, lo: 0x85, hi: 0x8c}, + {value: 0x0040, lo: 0x8d, hi: 0x8d}, + {value: 0x0008, lo: 0x8e, hi: 0x90}, + {value: 0x0040, lo: 0x91, hi: 0x91}, + {value: 0x0008, lo: 0x92, hi: 0xba}, + {value: 0x3b08, lo: 0xbb, hi: 0xbc}, + {value: 0x0008, lo: 0xbd, hi: 0xbd}, + {value: 0x3008, lo: 0xbe, hi: 0xbf}, + // Block 0x13, offset 0xbd + {value: 0x0000, lo: 0x0b}, + {value: 0x0040, lo: 0x80, hi: 0x81}, + {value: 0x3008, lo: 0x82, hi: 0x83}, + {value: 0x0040, lo: 0x84, hi: 0x84}, + {value: 0x0008, lo: 0x85, hi: 0x96}, + {value: 0x0040, lo: 0x97, hi: 0x99}, + {value: 0x0008, lo: 0x9a, hi: 0xb1}, + {value: 0x0040, lo: 0xb2, hi: 0xb2}, + {value: 0x0008, lo: 0xb3, hi: 0xbb}, + {value: 0x0040, lo: 0xbc, hi: 0xbc}, + {value: 0x0008, lo: 0xbd, hi: 0xbd}, + {value: 0x0040, lo: 0xbe, hi: 0xbf}, + // Block 0x14, offset 0xc9 + {value: 0x0000, lo: 0x10}, + {value: 0x0008, lo: 0x80, hi: 0x86}, + {value: 0x0040, lo: 0x87, hi: 0x89}, + {value: 0x3b08, lo: 0x8a, hi: 0x8a}, + {value: 0x0040, lo: 0x8b, hi: 0x8e}, + {value: 0x3008, lo: 0x8f, hi: 0x91}, + {value: 0x3308, lo: 0x92, hi: 0x94}, + {value: 0x0040, lo: 0x95, hi: 0x95}, + {value: 0x3308, lo: 0x96, hi: 0x96}, + {value: 0x0040, lo: 0x97, hi: 0x97}, + {value: 0x3008, lo: 0x98, hi: 0x9f}, + {value: 0x0040, lo: 0xa0, hi: 0xa5}, + {value: 0x0008, lo: 0xa6, hi: 0xaf}, + {value: 0x0040, lo: 0xb0, hi: 0xb1}, + {value: 0x3008, lo: 0xb2, hi: 0xb3}, + {value: 0x0018, lo: 0xb4, hi: 0xb4}, + {value: 0x0040, lo: 0xb5, hi: 0xbf}, + // Block 0x15, offset 0xda + {value: 0x0000, lo: 0x09}, + {value: 0x0040, lo: 0x80, hi: 0x80}, + {value: 0x0008, lo: 0x81, hi: 0xb0}, + {value: 0x3308, lo: 0xb1, hi: 0xb1}, + {value: 0x0008, lo: 0xb2, hi: 0xb2}, + {value: 0x08f1, lo: 0xb3, hi: 0xb3}, + {value: 0x3308, lo: 0xb4, hi: 0xb9}, + {value: 0x3b08, lo: 0xba, hi: 0xba}, + {value: 0x0040, lo: 0xbb, hi: 0xbe}, + {value: 0x0018, lo: 0xbf, hi: 0xbf}, + // Block 0x16, offset 0xe4 + {value: 0x0000, lo: 0x06}, + {value: 0x0008, lo: 0x80, hi: 0x86}, + {value: 0x3308, lo: 0x87, hi: 0x8e}, + {value: 0x0018, lo: 0x8f, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0018, lo: 0x9a, hi: 0x9b}, + {value: 0x0040, lo: 0x9c, hi: 0xbf}, + // Block 0x17, offset 0xeb + {value: 0x0000, lo: 0x0c}, + {value: 0x0008, lo: 0x80, hi: 0x84}, + {value: 0x0040, lo: 0x85, hi: 0x85}, + {value: 0x0008, lo: 0x86, hi: 0x86}, + {value: 0x0040, lo: 0x87, hi: 0x87}, + {value: 0x3308, lo: 0x88, hi: 0x8d}, + {value: 0x0040, lo: 0x8e, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9b}, + {value: 0x0961, lo: 0x9c, hi: 0x9c}, + {value: 0x0999, lo: 0x9d, hi: 0x9d}, + {value: 0x0008, lo: 0x9e, hi: 0x9f}, + {value: 0x0040, lo: 0xa0, hi: 0xbf}, + // Block 0x18, offset 0xf8 + {value: 0x0000, lo: 0x10}, + {value: 0x0008, lo: 0x80, hi: 0x80}, + {value: 0x0018, lo: 0x81, hi: 0x8a}, + {value: 0x0008, lo: 0x8b, hi: 0x8b}, + {value: 0xe03d, lo: 0x8c, hi: 0x8c}, + {value: 0x0018, lo: 0x8d, hi: 0x97}, + {value: 0x3308, lo: 0x98, hi: 0x99}, + {value: 0x0018, lo: 0x9a, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xa9}, + {value: 0x0018, lo: 0xaa, hi: 0xb4}, + {value: 0x3308, lo: 0xb5, hi: 0xb5}, + {value: 0x0018, lo: 0xb6, hi: 0xb6}, + {value: 0x3308, lo: 0xb7, hi: 0xb7}, + {value: 0x0018, lo: 0xb8, hi: 0xb8}, + {value: 0x3308, lo: 0xb9, hi: 0xb9}, + {value: 0x0018, lo: 0xba, hi: 0xbd}, + {value: 0x3008, lo: 0xbe, hi: 0xbf}, + // Block 0x19, offset 0x109 + {value: 0x0000, lo: 0x06}, + {value: 0x0018, lo: 0x80, hi: 0x85}, + {value: 0x3308, lo: 0x86, hi: 0x86}, + {value: 0x0018, lo: 0x87, hi: 0x8c}, + {value: 0x0040, lo: 0x8d, hi: 0x8d}, + {value: 0x0018, lo: 0x8e, hi: 0x9a}, + {value: 0x0040, lo: 0x9b, hi: 0xbf}, + // Block 0x1a, offset 0x110 + {value: 0x0000, lo: 0x0a}, + {value: 0x0008, lo: 0x80, hi: 0xaa}, + {value: 0x3008, lo: 0xab, hi: 0xac}, + {value: 0x3308, lo: 0xad, hi: 0xb0}, + {value: 0x3008, lo: 0xb1, hi: 0xb1}, + {value: 0x3308, lo: 0xb2, hi: 0xb7}, + {value: 0x3008, lo: 0xb8, hi: 0xb8}, + {value: 0x3b08, lo: 0xb9, hi: 0xba}, + {value: 0x3008, lo: 0xbb, hi: 0xbc}, + {value: 0x3308, lo: 0xbd, hi: 0xbe}, + {value: 0x0008, lo: 0xbf, hi: 0xbf}, + // Block 0x1b, offset 0x11b + {value: 0x0000, lo: 0x0e}, + {value: 0x0008, lo: 0x80, hi: 0x89}, + {value: 0x0018, lo: 0x8a, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x95}, + {value: 0x3008, lo: 0x96, hi: 0x97}, + {value: 0x3308, lo: 0x98, hi: 0x99}, + {value: 0x0008, lo: 0x9a, hi: 0x9d}, + {value: 0x3308, lo: 0x9e, hi: 0xa0}, + {value: 0x0008, lo: 0xa1, hi: 0xa1}, + {value: 0x3008, lo: 0xa2, hi: 0xa4}, + {value: 0x0008, lo: 0xa5, hi: 0xa6}, + {value: 0x3008, lo: 0xa7, hi: 0xad}, + {value: 0x0008, lo: 0xae, hi: 0xb0}, + {value: 0x3308, lo: 0xb1, hi: 0xb4}, + {value: 0x0008, lo: 0xb5, hi: 0xbf}, + // Block 0x1c, offset 0x12a + {value: 0x0000, lo: 0x0d}, + {value: 0x0008, lo: 0x80, hi: 0x81}, + {value: 0x3308, lo: 0x82, hi: 0x82}, + {value: 0x3008, lo: 0x83, hi: 0x84}, + {value: 0x3308, lo: 0x85, hi: 0x86}, + {value: 0x3008, lo: 0x87, hi: 0x8c}, + {value: 0x3308, lo: 0x8d, hi: 0x8d}, + {value: 0x0008, lo: 0x8e, hi: 0x8e}, + {value: 0x3008, lo: 0x8f, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x3008, lo: 0x9a, hi: 0x9c}, + {value: 0x3308, lo: 0x9d, hi: 0x9d}, + {value: 0x0018, lo: 0x9e, hi: 0x9f}, + {value: 0x0040, lo: 0xa0, hi: 0xbf}, + // Block 0x1d, offset 0x138 + {value: 0x0000, lo: 0x09}, + {value: 0x0040, lo: 0x80, hi: 0x86}, + {value: 0x055d, lo: 0x87, hi: 0x87}, + {value: 0x0040, lo: 0x88, hi: 0x8c}, + {value: 0x055d, lo: 0x8d, hi: 0x8d}, + {value: 0x0040, lo: 0x8e, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0xba}, + {value: 0x0018, lo: 0xbb, hi: 0xbb}, + {value: 0xe105, lo: 0xbc, hi: 0xbc}, + {value: 0x0008, lo: 0xbd, hi: 0xbf}, + // Block 0x1e, offset 0x142 + {value: 0x0000, lo: 0x01}, + {value: 0x0018, lo: 0x80, hi: 0xbf}, + // Block 0x1f, offset 0x144 + {value: 0x0000, lo: 0x04}, + {value: 0x0018, lo: 0x80, hi: 0x9e}, + {value: 0x0040, lo: 0x9f, hi: 0xa0}, + {value: 0x2018, lo: 0xa1, hi: 0xb5}, + {value: 0x0018, lo: 0xb6, hi: 0xbf}, + // Block 0x20, offset 0x149 + {value: 0x0000, lo: 0x02}, + {value: 0x0018, lo: 0x80, hi: 0xa7}, + {value: 0x2018, lo: 0xa8, hi: 0xbf}, + // Block 0x21, offset 0x14c + {value: 0x0000, lo: 0x02}, + {value: 0x2018, lo: 0x80, hi: 0x82}, + {value: 0x0018, lo: 0x83, hi: 0xbf}, + // Block 0x22, offset 0x14f + {value: 0x0000, lo: 0x01}, + {value: 0x0008, lo: 0x80, hi: 0xbf}, + // Block 0x23, offset 0x151 + {value: 0x0000, lo: 0x0b}, + {value: 0x0008, lo: 0x80, hi: 0x88}, + {value: 0x0040, lo: 0x89, hi: 0x89}, + {value: 0x0008, lo: 0x8a, hi: 0x8d}, + {value: 0x0040, lo: 0x8e, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x96}, + {value: 0x0040, lo: 0x97, hi: 0x97}, + {value: 0x0008, lo: 0x98, hi: 0x98}, + {value: 0x0040, lo: 0x99, hi: 0x99}, + {value: 0x0008, lo: 0x9a, hi: 0x9d}, + {value: 0x0040, lo: 0x9e, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xbf}, + // Block 0x24, offset 0x15d + {value: 0x0000, lo: 0x0a}, + {value: 0x0008, lo: 0x80, hi: 0x88}, + {value: 0x0040, lo: 0x89, hi: 0x89}, + {value: 0x0008, lo: 0x8a, hi: 0x8d}, + {value: 0x0040, lo: 0x8e, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0xb0}, + {value: 0x0040, lo: 0xb1, hi: 0xb1}, + {value: 0x0008, lo: 0xb2, hi: 0xb5}, + {value: 0x0040, lo: 0xb6, hi: 0xb7}, + {value: 0x0008, lo: 0xb8, hi: 0xbe}, + {value: 0x0040, lo: 0xbf, hi: 0xbf}, + // Block 0x25, offset 0x168 + {value: 0x0000, lo: 0x07}, + {value: 0x0008, lo: 0x80, hi: 0x80}, + {value: 0x0040, lo: 0x81, hi: 0x81}, + {value: 0x0008, lo: 0x82, hi: 0x85}, + {value: 0x0040, lo: 0x86, hi: 0x87}, + {value: 0x0008, lo: 0x88, hi: 0x96}, + {value: 0x0040, lo: 0x97, hi: 0x97}, + {value: 0x0008, lo: 0x98, hi: 0xbf}, + // Block 0x26, offset 0x170 + {value: 0x0000, lo: 0x05}, + {value: 0x0008, lo: 0x80, hi: 0x90}, + {value: 0x0040, lo: 0x91, hi: 0x91}, + {value: 0x0008, lo: 0x92, hi: 0x95}, + {value: 0x0040, lo: 0x96, hi: 0x97}, + {value: 0x0008, lo: 0x98, hi: 0xbf}, + // Block 0x27, offset 0x176 + {value: 0x0000, lo: 0x05}, + {value: 0x0008, lo: 0x80, hi: 0x9a}, + {value: 0x0040, lo: 0x9b, hi: 0x9c}, + {value: 0x3308, lo: 0x9d, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xbc}, + {value: 0x0040, lo: 0xbd, hi: 0xbf}, + // Block 0x28, offset 0x17c + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0x8f}, + {value: 0x0018, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xbf}, + // Block 0x29, offset 0x181 + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0xb5}, + {value: 0x0040, lo: 0xb6, hi: 0xb7}, + {value: 0xe045, lo: 0xb8, hi: 0xbd}, + {value: 0x0040, lo: 0xbe, hi: 0xbf}, + // Block 0x2a, offset 0x186 + {value: 0x0000, lo: 0x02}, + {value: 0x0018, lo: 0x80, hi: 0x80}, + {value: 0x0008, lo: 0x81, hi: 0xbf}, + // Block 0x2b, offset 0x189 + {value: 0x0000, lo: 0x03}, + {value: 0x0008, lo: 0x80, hi: 0xac}, + {value: 0x0018, lo: 0xad, hi: 0xae}, + {value: 0x0008, lo: 0xaf, hi: 0xbf}, + // Block 0x2c, offset 0x18d + {value: 0x0000, lo: 0x05}, + {value: 0x0040, lo: 0x80, hi: 0x80}, + {value: 0x0008, lo: 0x81, hi: 0x9a}, + {value: 0x0018, lo: 0x9b, hi: 0x9c}, + {value: 0x0040, lo: 0x9d, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xbf}, + // Block 0x2d, offset 0x193 + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0xaa}, + {value: 0x0018, lo: 0xab, hi: 0xb0}, + {value: 0x0008, lo: 0xb1, hi: 0xb8}, + {value: 0x0040, lo: 0xb9, hi: 0xbf}, + // Block 0x2e, offset 0x198 + {value: 0x0000, lo: 0x0b}, + {value: 0x0008, lo: 0x80, hi: 0x8c}, + {value: 0x0040, lo: 0x8d, hi: 0x8d}, + {value: 0x0008, lo: 0x8e, hi: 0x91}, + {value: 0x3308, lo: 0x92, hi: 0x93}, + {value: 0x3b08, lo: 0x94, hi: 0x94}, + {value: 0x0040, lo: 0x95, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xb1}, + {value: 0x3308, lo: 0xb2, hi: 0xb3}, + {value: 0x3b08, lo: 0xb4, hi: 0xb4}, + {value: 0x0018, lo: 0xb5, hi: 0xb6}, + {value: 0x0040, lo: 0xb7, hi: 0xbf}, + // Block 0x2f, offset 0x1a4 + {value: 0x0000, lo: 0x09}, + {value: 0x0008, lo: 0x80, hi: 0x91}, + {value: 0x3308, lo: 0x92, hi: 0x93}, + {value: 0x0040, lo: 0x94, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xac}, + {value: 0x0040, lo: 0xad, hi: 0xad}, + {value: 0x0008, lo: 0xae, hi: 0xb0}, + {value: 0x0040, lo: 0xb1, hi: 0xb1}, + {value: 0x3308, lo: 0xb2, hi: 0xb3}, + {value: 0x0040, lo: 0xb4, hi: 0xbf}, + // Block 0x30, offset 0x1ae + {value: 0x0000, lo: 0x05}, + {value: 0x0008, lo: 0x80, hi: 0xb3}, + {value: 0x3340, lo: 0xb4, hi: 0xb5}, + {value: 0x3008, lo: 0xb6, hi: 0xb6}, + {value: 0x3308, lo: 0xb7, hi: 0xbd}, + {value: 0x3008, lo: 0xbe, hi: 0xbf}, + // Block 0x31, offset 0x1b4 + {value: 0x0000, lo: 0x10}, + {value: 0x3008, lo: 0x80, hi: 0x85}, + {value: 0x3308, lo: 0x86, hi: 0x86}, + {value: 0x3008, lo: 0x87, hi: 0x88}, + {value: 0x3308, lo: 0x89, hi: 0x91}, + {value: 0x3b08, lo: 0x92, hi: 0x92}, + {value: 0x3308, lo: 0x93, hi: 0x93}, + {value: 0x0018, lo: 0x94, hi: 0x96}, + {value: 0x0008, lo: 0x97, hi: 0x97}, + {value: 0x0018, lo: 0x98, hi: 0x9b}, + {value: 0x0008, lo: 0x9c, hi: 0x9c}, + {value: 0x3308, lo: 0x9d, hi: 0x9d}, + {value: 0x0040, lo: 0x9e, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xa9}, + {value: 0x0040, lo: 0xaa, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xb9}, + {value: 0x0040, lo: 0xba, hi: 0xbf}, + // Block 0x32, offset 0x1c5 + {value: 0x0000, lo: 0x09}, + {value: 0x0018, lo: 0x80, hi: 0x85}, + {value: 0x0040, lo: 0x86, hi: 0x86}, + {value: 0x0218, lo: 0x87, hi: 0x87}, + {value: 0x0018, lo: 0x88, hi: 0x8a}, + {value: 0x33c0, lo: 0x8b, hi: 0x8d}, + {value: 0x0040, lo: 0x8e, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9f}, + {value: 0x0208, lo: 0xa0, hi: 0xbf}, + // Block 0x33, offset 0x1cf + {value: 0x0000, lo: 0x02}, + {value: 0x0208, lo: 0x80, hi: 0xb7}, + {value: 0x0040, lo: 0xb8, hi: 0xbf}, + // Block 0x34, offset 0x1d2 + {value: 0x0000, lo: 0x07}, + {value: 0x0008, lo: 0x80, hi: 0x84}, + {value: 0x3308, lo: 0x85, hi: 0x86}, + {value: 0x0208, lo: 0x87, hi: 0xa8}, + {value: 0x3308, lo: 0xa9, hi: 0xa9}, + {value: 0x0208, lo: 0xaa, hi: 0xaa}, + {value: 0x0040, lo: 0xab, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbf}, + // Block 0x35, offset 0x1da + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xb5}, + {value: 0x0040, lo: 0xb6, hi: 0xbf}, + // Block 0x36, offset 0x1dd + {value: 0x0000, lo: 0x0c}, + {value: 0x0008, lo: 0x80, hi: 0x9e}, + {value: 0x0040, lo: 0x9f, hi: 0x9f}, + {value: 0x3308, lo: 0xa0, hi: 0xa2}, + {value: 0x3008, lo: 0xa3, hi: 0xa6}, + {value: 0x3308, lo: 0xa7, hi: 0xa8}, + {value: 0x3008, lo: 0xa9, hi: 0xab}, + {value: 0x0040, lo: 0xac, hi: 0xaf}, + {value: 0x3008, lo: 0xb0, hi: 0xb1}, + {value: 0x3308, lo: 0xb2, hi: 0xb2}, + {value: 0x3008, lo: 0xb3, hi: 0xb8}, + {value: 0x3308, lo: 0xb9, hi: 0xbb}, + {value: 0x0040, lo: 0xbc, hi: 0xbf}, + // Block 0x37, offset 0x1ea + {value: 0x0000, lo: 0x07}, + {value: 0x0018, lo: 0x80, hi: 0x80}, + {value: 0x0040, lo: 0x81, hi: 0x83}, + {value: 0x0018, lo: 0x84, hi: 0x85}, + {value: 0x0008, lo: 0x86, hi: 0xad}, + {value: 0x0040, lo: 0xae, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xb4}, + {value: 0x0040, lo: 0xb5, hi: 0xbf}, + // Block 0x38, offset 0x1f2 + {value: 0x0000, lo: 0x03}, + {value: 0x0008, lo: 0x80, hi: 0xab}, + {value: 0x0040, lo: 0xac, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbf}, + // Block 0x39, offset 0x1f6 + {value: 0x0000, lo: 0x06}, + {value: 0x0008, lo: 0x80, hi: 0x89}, + {value: 0x0040, lo: 0x8a, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0028, lo: 0x9a, hi: 0x9a}, + {value: 0x0040, lo: 0x9b, hi: 0x9d}, + {value: 0x0018, lo: 0x9e, hi: 0xbf}, + // Block 0x3a, offset 0x1fd + {value: 0x0000, lo: 0x07}, + {value: 0x0008, lo: 0x80, hi: 0x96}, + {value: 0x3308, lo: 0x97, hi: 0x98}, + {value: 0x3008, lo: 0x99, hi: 0x9a}, + {value: 0x3308, lo: 0x9b, hi: 0x9b}, + {value: 0x0040, lo: 0x9c, hi: 0x9d}, + {value: 0x0018, lo: 0x9e, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xbf}, + // Block 0x3b, offset 0x205 + {value: 0x0000, lo: 0x0f}, + {value: 0x0008, lo: 0x80, hi: 0x94}, + {value: 0x3008, lo: 0x95, hi: 0x95}, + {value: 0x3308, lo: 0x96, hi: 0x96}, + {value: 0x3008, lo: 0x97, hi: 0x97}, + {value: 0x3308, lo: 0x98, hi: 0x9e}, + {value: 0x0040, lo: 0x9f, hi: 0x9f}, + {value: 0x3b08, lo: 0xa0, hi: 0xa0}, + {value: 0x3008, lo: 0xa1, hi: 0xa1}, + {value: 0x3308, lo: 0xa2, hi: 0xa2}, + {value: 0x3008, lo: 0xa3, hi: 0xa4}, + {value: 0x3308, lo: 0xa5, hi: 0xac}, + {value: 0x3008, lo: 0xad, hi: 0xb2}, + {value: 0x3308, lo: 0xb3, hi: 0xbc}, + {value: 0x0040, lo: 0xbd, hi: 0xbe}, + {value: 0x3308, lo: 0xbf, hi: 0xbf}, + // Block 0x3c, offset 0x215 + {value: 0x0000, lo: 0x0b}, + {value: 0x0008, lo: 0x80, hi: 0x89}, + {value: 0x0040, lo: 0x8a, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xa6}, + {value: 0x0008, lo: 0xa7, hi: 0xa7}, + {value: 0x0018, lo: 0xa8, hi: 0xad}, + {value: 0x0040, lo: 0xae, hi: 0xaf}, + {value: 0x3308, lo: 0xb0, hi: 0xbd}, + {value: 0x3318, lo: 0xbe, hi: 0xbe}, + {value: 0x0040, lo: 0xbf, hi: 0xbf}, + // Block 0x3d, offset 0x221 + {value: 0x0000, lo: 0x01}, + {value: 0x0040, lo: 0x80, hi: 0xbf}, + // Block 0x3e, offset 0x223 + {value: 0x0000, lo: 0x09}, + {value: 0x3308, lo: 0x80, hi: 0x83}, + {value: 0x3008, lo: 0x84, hi: 0x84}, + {value: 0x0008, lo: 0x85, hi: 0xb3}, + {value: 0x3308, lo: 0xb4, hi: 0xb4}, + {value: 0x3008, lo: 0xb5, hi: 0xb5}, + {value: 0x3308, lo: 0xb6, hi: 0xba}, + {value: 0x3008, lo: 0xbb, hi: 0xbb}, + {value: 0x3308, lo: 0xbc, hi: 0xbc}, + {value: 0x3008, lo: 0xbd, hi: 0xbf}, + // Block 0x3f, offset 0x22d + {value: 0x0000, lo: 0x0b}, + {value: 0x3008, lo: 0x80, hi: 0x81}, + {value: 0x3308, lo: 0x82, hi: 0x82}, + {value: 0x3008, lo: 0x83, hi: 0x83}, + {value: 0x3808, lo: 0x84, hi: 0x84}, + {value: 0x0008, lo: 0x85, hi: 0x8b}, + {value: 0x0040, lo: 0x8c, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0018, lo: 0x9a, hi: 0xaa}, + {value: 0x3308, lo: 0xab, hi: 0xb3}, + {value: 0x0018, lo: 0xb4, hi: 0xbc}, + {value: 0x0040, lo: 0xbd, hi: 0xbf}, + // Block 0x40, offset 0x239 + {value: 0x0000, lo: 0x0b}, + {value: 0x3308, lo: 0x80, hi: 0x81}, + {value: 0x3008, lo: 0x82, hi: 0x82}, + {value: 0x0008, lo: 0x83, hi: 0xa0}, + {value: 0x3008, lo: 0xa1, hi: 0xa1}, + {value: 0x3308, lo: 0xa2, hi: 0xa5}, + {value: 0x3008, lo: 0xa6, hi: 0xa7}, + {value: 0x3308, lo: 0xa8, hi: 0xa9}, + {value: 0x3808, lo: 0xaa, hi: 0xaa}, + {value: 0x3b08, lo: 0xab, hi: 0xab}, + {value: 0x3308, lo: 0xac, hi: 0xad}, + {value: 0x0008, lo: 0xae, hi: 0xbf}, + // Block 0x41, offset 0x245 + {value: 0x0000, lo: 0x0b}, + {value: 0x0008, lo: 0x80, hi: 0xa5}, + {value: 0x3308, lo: 0xa6, hi: 0xa6}, + {value: 0x3008, lo: 0xa7, hi: 0xa7}, + {value: 0x3308, lo: 0xa8, hi: 0xa9}, + {value: 0x3008, lo: 0xaa, hi: 0xac}, + {value: 0x3308, lo: 0xad, hi: 0xad}, + {value: 0x3008, lo: 0xae, hi: 0xae}, + {value: 0x3308, lo: 0xaf, hi: 0xb1}, + {value: 0x3808, lo: 0xb2, hi: 0xb3}, + {value: 0x0040, lo: 0xb4, hi: 0xbb}, + {value: 0x0018, lo: 0xbc, hi: 0xbf}, + // Block 0x42, offset 0x251 + {value: 0x0000, lo: 0x07}, + {value: 0x0008, lo: 0x80, hi: 0xa3}, + {value: 0x3008, lo: 0xa4, hi: 0xab}, + {value: 0x3308, lo: 0xac, hi: 0xb3}, + {value: 0x3008, lo: 0xb4, hi: 0xb5}, + {value: 0x3308, lo: 0xb6, hi: 0xb7}, + {value: 0x0040, lo: 0xb8, hi: 0xba}, + {value: 0x0018, lo: 0xbb, hi: 0xbf}, + // Block 0x43, offset 0x259 + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0x89}, + {value: 0x0040, lo: 0x8a, hi: 0x8c}, + {value: 0x0008, lo: 0x8d, hi: 0xbd}, + {value: 0x0018, lo: 0xbe, hi: 0xbf}, + // Block 0x44, offset 0x25e + {value: 0x0000, lo: 0x09}, + {value: 0x0e29, lo: 0x80, hi: 0x80}, + {value: 0x0e41, lo: 0x81, hi: 0x81}, + {value: 0x0e59, lo: 0x82, hi: 0x82}, + {value: 0x0e71, lo: 0x83, hi: 0x83}, + {value: 0x0e89, lo: 0x84, hi: 0x85}, + {value: 0x0ea1, lo: 0x86, hi: 0x86}, + {value: 0x0eb9, lo: 0x87, hi: 0x87}, + {value: 0x057d, lo: 0x88, hi: 0x88}, + {value: 0x0040, lo: 0x89, hi: 0xbf}, + // Block 0x45, offset 0x268 + {value: 0x0000, lo: 0x10}, + {value: 0x0018, lo: 0x80, hi: 0x87}, + {value: 0x0040, lo: 0x88, hi: 0x8f}, + {value: 0x3308, lo: 0x90, hi: 0x92}, + {value: 0x0018, lo: 0x93, hi: 0x93}, + {value: 0x3308, lo: 0x94, hi: 0xa0}, + {value: 0x3008, lo: 0xa1, hi: 0xa1}, + {value: 0x3308, lo: 0xa2, hi: 0xa8}, + {value: 0x0008, lo: 0xa9, hi: 0xac}, + {value: 0x3308, lo: 0xad, hi: 0xad}, + {value: 0x0008, lo: 0xae, hi: 0xb1}, + {value: 0x3008, lo: 0xb2, hi: 0xb3}, + {value: 0x3308, lo: 0xb4, hi: 0xb4}, + {value: 0x0008, lo: 0xb5, hi: 0xb6}, + {value: 0x3008, lo: 0xb7, hi: 0xb7}, + {value: 0x3308, lo: 0xb8, hi: 0xb9}, + {value: 0x0040, lo: 0xba, hi: 0xbf}, + // Block 0x46, offset 0x279 + {value: 0x0000, lo: 0x03}, + {value: 0x3308, lo: 0x80, hi: 0xb9}, + {value: 0x0040, lo: 0xba, hi: 0xba}, + {value: 0x3308, lo: 0xbb, hi: 0xbf}, + // Block 0x47, offset 0x27d + {value: 0x0000, lo: 0x0a}, + {value: 0x0008, lo: 0x80, hi: 0x87}, + {value: 0xe045, lo: 0x88, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x95}, + {value: 0x0040, lo: 0x96, hi: 0x97}, + {value: 0xe045, lo: 0x98, hi: 0x9d}, + {value: 0x0040, lo: 0x9e, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xa7}, + {value: 0xe045, lo: 0xa8, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xb7}, + {value: 0xe045, lo: 0xb8, hi: 0xbf}, + // Block 0x48, offset 0x288 + {value: 0x0000, lo: 0x03}, + {value: 0x0040, lo: 0x80, hi: 0x8f}, + {value: 0x3318, lo: 0x90, hi: 0xb0}, + {value: 0x0040, lo: 0xb1, hi: 0xbf}, + // Block 0x49, offset 0x28c + {value: 0x0000, lo: 0x08}, + {value: 0x0018, lo: 0x80, hi: 0x82}, + {value: 0x0040, lo: 0x83, hi: 0x83}, + {value: 0x0008, lo: 0x84, hi: 0x84}, + {value: 0x0018, lo: 0x85, hi: 0x88}, + {value: 0x24c1, lo: 0x89, hi: 0x89}, + {value: 0x0018, lo: 0x8a, hi: 0x8b}, + {value: 0x0040, lo: 0x8c, hi: 0x8f}, + {value: 0x0018, lo: 0x90, hi: 0xbf}, + // Block 0x4a, offset 0x295 + {value: 0x0000, lo: 0x07}, + {value: 0x0018, lo: 0x80, hi: 0xab}, + {value: 0x24f1, lo: 0xac, hi: 0xac}, + {value: 0x2529, lo: 0xad, hi: 0xad}, + {value: 0x0018, lo: 0xae, hi: 0xae}, + {value: 0x2579, lo: 0xaf, hi: 0xaf}, + {value: 0x25b1, lo: 0xb0, hi: 0xb0}, + {value: 0x0018, lo: 0xb1, hi: 0xbf}, + // Block 0x4b, offset 0x29d + {value: 0x0000, lo: 0x05}, + {value: 0x0018, lo: 0x80, hi: 0x9f}, + {value: 0x0080, lo: 0xa0, hi: 0xa0}, + {value: 0x0018, lo: 0xa1, hi: 0xad}, + {value: 0x0080, lo: 0xae, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xbf}, + // Block 0x4c, offset 0x2a3 + {value: 0x0000, lo: 0x04}, + {value: 0x0018, lo: 0x80, hi: 0xa8}, + {value: 0x09c5, lo: 0xa9, hi: 0xa9}, + {value: 0x09e5, lo: 0xaa, hi: 0xaa}, + {value: 0x0018, lo: 0xab, hi: 0xbf}, + // Block 0x4d, offset 0x2a8 + {value: 0x0000, lo: 0x02}, + {value: 0x0018, lo: 0x80, hi: 0xa6}, + {value: 0x0040, lo: 0xa7, hi: 0xbf}, + // Block 0x4e, offset 0x2ab + {value: 0x0000, lo: 0x03}, + {value: 0x0018, lo: 0x80, hi: 0x8b}, + {value: 0x28c1, lo: 0x8c, hi: 0x8c}, + {value: 0x0018, lo: 0x8d, hi: 0xbf}, + // Block 0x4f, offset 0x2af + {value: 0x0000, lo: 0x05}, + {value: 0x0018, lo: 0x80, hi: 0xb3}, + {value: 0x0e66, lo: 0xb4, hi: 0xb4}, + {value: 0x292a, lo: 0xb5, hi: 0xb5}, + {value: 0x0e86, lo: 0xb6, hi: 0xb6}, + {value: 0x0018, lo: 0xb7, hi: 0xbf}, + // Block 0x50, offset 0x2b5 + {value: 0x0000, lo: 0x03}, + {value: 0x0018, lo: 0x80, hi: 0x9b}, + {value: 0x2941, lo: 0x9c, hi: 0x9c}, + {value: 0x0018, lo: 0x9d, hi: 0xbf}, + // Block 0x51, offset 0x2b9 + {value: 0x0000, lo: 0x03}, + {value: 0x0018, lo: 0x80, hi: 0xb3}, + {value: 0x0040, lo: 0xb4, hi: 0xb5}, + {value: 0x0018, lo: 0xb6, hi: 0xbf}, + // Block 0x52, offset 0x2bd + {value: 0x0000, lo: 0x05}, + {value: 0x0018, lo: 0x80, hi: 0x95}, + {value: 0x0040, lo: 0x96, hi: 0x97}, + {value: 0x0018, lo: 0x98, hi: 0xb9}, + {value: 0x0040, lo: 0xba, hi: 0xbc}, + {value: 0x0018, lo: 0xbd, hi: 0xbf}, + // Block 0x53, offset 0x2c3 + {value: 0x0000, lo: 0x06}, + {value: 0x0018, lo: 0x80, hi: 0x88}, + {value: 0x0040, lo: 0x89, hi: 0x89}, + {value: 0x0018, lo: 0x8a, hi: 0x92}, + {value: 0x0040, lo: 0x93, hi: 0xab}, + {value: 0x0018, lo: 0xac, hi: 0xaf}, + {value: 0x0040, lo: 0xb0, hi: 0xbf}, + // Block 0x54, offset 0x2ca + {value: 0x0000, lo: 0x05}, + {value: 0xe185, lo: 0x80, hi: 0x8f}, + {value: 0x03f5, lo: 0x90, hi: 0x9f}, + {value: 0x0ea5, lo: 0xa0, hi: 0xae}, + {value: 0x0040, lo: 0xaf, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbf}, + // Block 0x55, offset 0x2d0 + {value: 0x0000, lo: 0x07}, + {value: 0x0008, lo: 0x80, hi: 0xa5}, + {value: 0x0040, lo: 0xa6, hi: 0xa6}, + {value: 0x0008, lo: 0xa7, hi: 0xa7}, + {value: 0x0040, lo: 0xa8, hi: 0xac}, + {value: 0x0008, lo: 0xad, hi: 0xad}, + {value: 0x0040, lo: 0xae, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbf}, + // Block 0x56, offset 0x2d8 + {value: 0x0000, lo: 0x06}, + {value: 0x0008, lo: 0x80, hi: 0xa7}, + {value: 0x0040, lo: 0xa8, hi: 0xae}, + {value: 0xe075, lo: 0xaf, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xb0}, + {value: 0x0040, lo: 0xb1, hi: 0xbe}, + {value: 0x3b08, lo: 0xbf, hi: 0xbf}, + // Block 0x57, offset 0x2df + {value: 0x0000, lo: 0x0a}, + {value: 0x0008, lo: 0x80, hi: 0x96}, + {value: 0x0040, lo: 0x97, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xa6}, + {value: 0x0040, lo: 0xa7, hi: 0xa7}, + {value: 0x0008, lo: 0xa8, hi: 0xae}, + {value: 0x0040, lo: 0xaf, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xb6}, + {value: 0x0040, lo: 0xb7, hi: 0xb7}, + {value: 0x0008, lo: 0xb8, hi: 0xbe}, + {value: 0x0040, lo: 0xbf, hi: 0xbf}, + // Block 0x58, offset 0x2ea + {value: 0x0000, lo: 0x09}, + {value: 0x0008, lo: 0x80, hi: 0x86}, + {value: 0x0040, lo: 0x87, hi: 0x87}, + {value: 0x0008, lo: 0x88, hi: 0x8e}, + {value: 0x0040, lo: 0x8f, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x96}, + {value: 0x0040, lo: 0x97, hi: 0x97}, + {value: 0x0008, lo: 0x98, hi: 0x9e}, + {value: 0x0040, lo: 0x9f, hi: 0x9f}, + {value: 0x3308, lo: 0xa0, hi: 0xbf}, + // Block 0x59, offset 0x2f4 + {value: 0x0000, lo: 0x03}, + {value: 0x0018, lo: 0x80, hi: 0xae}, + {value: 0x0008, lo: 0xaf, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xbf}, + // Block 0x5a, offset 0x2f8 + {value: 0x0000, lo: 0x02}, + {value: 0x0018, lo: 0x80, hi: 0x89}, + {value: 0x0040, lo: 0x8a, hi: 0xbf}, + // Block 0x5b, offset 0x2fb + {value: 0x0000, lo: 0x05}, + {value: 0x0018, lo: 0x80, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9a}, + {value: 0x0018, lo: 0x9b, hi: 0x9e}, + {value: 0x0edd, lo: 0x9f, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xbf}, + // Block 0x5c, offset 0x301 + {value: 0x0000, lo: 0x03}, + {value: 0x0018, lo: 0x80, hi: 0xb2}, + {value: 0x0efd, lo: 0xb3, hi: 0xb3}, + {value: 0x0040, lo: 0xb4, hi: 0xbf}, + // Block 0x5d, offset 0x305 + {value: 0x0020, lo: 0x01}, + {value: 0x0f1d, lo: 0x80, hi: 0xbf}, + // Block 0x5e, offset 0x307 + {value: 0x0020, lo: 0x02}, + {value: 0x171d, lo: 0x80, hi: 0x8f}, + {value: 0x18fd, lo: 0x90, hi: 0xbf}, + // Block 0x5f, offset 0x30a + {value: 0x0020, lo: 0x01}, + {value: 0x1efd, lo: 0x80, hi: 0xbf}, + // Block 0x60, offset 0x30c + {value: 0x0000, lo: 0x02}, + {value: 0x0040, lo: 0x80, hi: 0x80}, + {value: 0x0008, lo: 0x81, hi: 0xbf}, + // Block 0x61, offset 0x30f + {value: 0x0000, lo: 0x09}, + {value: 0x0008, lo: 0x80, hi: 0x96}, + {value: 0x0040, lo: 0x97, hi: 0x98}, + {value: 0x3308, lo: 0x99, hi: 0x9a}, + {value: 0x29e2, lo: 0x9b, hi: 0x9b}, + {value: 0x2a0a, lo: 0x9c, hi: 0x9c}, + {value: 0x0008, lo: 0x9d, hi: 0x9e}, + {value: 0x2a31, lo: 0x9f, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xa0}, + {value: 0x0008, lo: 0xa1, hi: 0xbf}, + // Block 0x62, offset 0x319 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xbe}, + {value: 0x2a69, lo: 0xbf, hi: 0xbf}, + // Block 0x63, offset 0x31c + {value: 0x0000, lo: 0x0e}, + {value: 0x0040, lo: 0x80, hi: 0x84}, + {value: 0x0008, lo: 0x85, hi: 0xae}, + {value: 0x0040, lo: 0xaf, hi: 0xb0}, + {value: 0x2a1d, lo: 0xb1, hi: 0xb1}, + {value: 0x2a3d, lo: 0xb2, hi: 0xb2}, + {value: 0x2a5d, lo: 0xb3, hi: 0xb3}, + {value: 0x2a7d, lo: 0xb4, hi: 0xb4}, + {value: 0x2a5d, lo: 0xb5, hi: 0xb5}, + {value: 0x2a9d, lo: 0xb6, hi: 0xb6}, + {value: 0x2abd, lo: 0xb7, hi: 0xb7}, + {value: 0x2add, lo: 0xb8, hi: 0xb9}, + {value: 0x2afd, lo: 0xba, hi: 0xbb}, + {value: 0x2b1d, lo: 0xbc, hi: 0xbd}, + {value: 0x2afd, lo: 0xbe, hi: 0xbf}, + // Block 0x64, offset 0x32b + {value: 0x0000, lo: 0x03}, + {value: 0x0018, lo: 0x80, hi: 0xa3}, + {value: 0x0040, lo: 0xa4, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbf}, + // Block 0x65, offset 0x32f + {value: 0x0030, lo: 0x04}, + {value: 0x2aa2, lo: 0x80, hi: 0x9d}, + {value: 0x305a, lo: 0x9e, hi: 0x9e}, + {value: 0x0040, lo: 0x9f, hi: 0x9f}, + {value: 0x30a2, lo: 0xa0, hi: 0xbf}, + // Block 0x66, offset 0x334 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xaa}, + {value: 0x0040, lo: 0xab, hi: 0xbf}, + // Block 0x67, offset 0x337 + {value: 0x0000, lo: 0x03}, + {value: 0x0008, lo: 0x80, hi: 0x8c}, + {value: 0x0040, lo: 0x8d, hi: 0x8f}, + {value: 0x0018, lo: 0x90, hi: 0xbf}, + // Block 0x68, offset 0x33b + {value: 0x0000, lo: 0x04}, + {value: 0x0018, lo: 0x80, hi: 0x86}, + {value: 0x0040, lo: 0x87, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0xbd}, + {value: 0x0018, lo: 0xbe, hi: 0xbf}, + // Block 0x69, offset 0x340 + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0x8c}, + {value: 0x0018, lo: 0x8d, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0xab}, + {value: 0x0040, lo: 0xac, hi: 0xbf}, + // Block 0x6a, offset 0x345 + {value: 0x0000, lo: 0x05}, + {value: 0x0008, lo: 0x80, hi: 0xa5}, + {value: 0x0018, lo: 0xa6, hi: 0xaf}, + {value: 0x3308, lo: 0xb0, hi: 0xb1}, + {value: 0x0018, lo: 0xb2, hi: 0xb7}, + {value: 0x0040, lo: 0xb8, hi: 0xbf}, + // Block 0x6b, offset 0x34b + {value: 0x0000, lo: 0x05}, + {value: 0x0040, lo: 0x80, hi: 0xb6}, + {value: 0x0008, lo: 0xb7, hi: 0xb7}, + {value: 0x2009, lo: 0xb8, hi: 0xb8}, + {value: 0x6e89, lo: 0xb9, hi: 0xb9}, + {value: 0x0008, lo: 0xba, hi: 0xbf}, + // Block 0x6c, offset 0x351 + {value: 0x0000, lo: 0x0e}, + {value: 0x0008, lo: 0x80, hi: 0x81}, + {value: 0x3308, lo: 0x82, hi: 0x82}, + {value: 0x0008, lo: 0x83, hi: 0x85}, + {value: 0x3b08, lo: 0x86, hi: 0x86}, + {value: 0x0008, lo: 0x87, hi: 0x8a}, + {value: 0x3308, lo: 0x8b, hi: 0x8b}, + {value: 0x0008, lo: 0x8c, hi: 0xa2}, + {value: 0x3008, lo: 0xa3, hi: 0xa4}, + {value: 0x3308, lo: 0xa5, hi: 0xa6}, + {value: 0x3008, lo: 0xa7, hi: 0xa7}, + {value: 0x0018, lo: 0xa8, hi: 0xab}, + {value: 0x0040, lo: 0xac, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xb9}, + {value: 0x0040, lo: 0xba, hi: 0xbf}, + // Block 0x6d, offset 0x360 + {value: 0x0000, lo: 0x05}, + {value: 0x0208, lo: 0x80, hi: 0xb1}, + {value: 0x0108, lo: 0xb2, hi: 0xb2}, + {value: 0x0008, lo: 0xb3, hi: 0xb3}, + {value: 0x0018, lo: 0xb4, hi: 0xb7}, + {value: 0x0040, lo: 0xb8, hi: 0xbf}, + // Block 0x6e, offset 0x366 + {value: 0x0000, lo: 0x03}, + {value: 0x3008, lo: 0x80, hi: 0x81}, + {value: 0x0008, lo: 0x82, hi: 0xb3}, + {value: 0x3008, lo: 0xb4, hi: 0xbf}, + // Block 0x6f, offset 0x36a + {value: 0x0000, lo: 0x0e}, + {value: 0x3008, lo: 0x80, hi: 0x83}, + {value: 0x3b08, lo: 0x84, hi: 0x84}, + {value: 0x3308, lo: 0x85, hi: 0x85}, + {value: 0x0040, lo: 0x86, hi: 0x8d}, + {value: 0x0018, lo: 0x8e, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9f}, + {value: 0x3308, lo: 0xa0, hi: 0xb1}, + {value: 0x0008, lo: 0xb2, hi: 0xb7}, + {value: 0x0018, lo: 0xb8, hi: 0xba}, + {value: 0x0008, lo: 0xbb, hi: 0xbb}, + {value: 0x0018, lo: 0xbc, hi: 0xbc}, + {value: 0x0008, lo: 0xbd, hi: 0xbd}, + {value: 0x0040, lo: 0xbe, hi: 0xbf}, + // Block 0x70, offset 0x379 + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0xa5}, + {value: 0x3308, lo: 0xa6, hi: 0xad}, + {value: 0x0018, lo: 0xae, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbf}, + // Block 0x71, offset 0x37e + {value: 0x0000, lo: 0x07}, + {value: 0x0008, lo: 0x80, hi: 0x86}, + {value: 0x3308, lo: 0x87, hi: 0x91}, + {value: 0x3008, lo: 0x92, hi: 0x92}, + {value: 0x3808, lo: 0x93, hi: 0x93}, + {value: 0x0040, lo: 0x94, hi: 0x9e}, + {value: 0x0018, lo: 0x9f, hi: 0xbc}, + {value: 0x0040, lo: 0xbd, hi: 0xbf}, + // Block 0x72, offset 0x386 + {value: 0x0000, lo: 0x09}, + {value: 0x3308, lo: 0x80, hi: 0x82}, + {value: 0x3008, lo: 0x83, hi: 0x83}, + {value: 0x0008, lo: 0x84, hi: 0xb2}, + {value: 0x3308, lo: 0xb3, hi: 0xb3}, + {value: 0x3008, lo: 0xb4, hi: 0xb5}, + {value: 0x3308, lo: 0xb6, hi: 0xb9}, + {value: 0x3008, lo: 0xba, hi: 0xbb}, + {value: 0x3308, lo: 0xbc, hi: 0xbc}, + {value: 0x3008, lo: 0xbd, hi: 0xbf}, + // Block 0x73, offset 0x390 + {value: 0x0000, lo: 0x0a}, + {value: 0x3808, lo: 0x80, hi: 0x80}, + {value: 0x0018, lo: 0x81, hi: 0x8d}, + {value: 0x0040, lo: 0x8e, hi: 0x8e}, + {value: 0x0008, lo: 0x8f, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9d}, + {value: 0x0018, lo: 0x9e, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xa4}, + {value: 0x3308, lo: 0xa5, hi: 0xa5}, + {value: 0x0008, lo: 0xa6, hi: 0xbe}, + {value: 0x0040, lo: 0xbf, hi: 0xbf}, + // Block 0x74, offset 0x39b + {value: 0x0000, lo: 0x07}, + {value: 0x0008, lo: 0x80, hi: 0xa8}, + {value: 0x3308, lo: 0xa9, hi: 0xae}, + {value: 0x3008, lo: 0xaf, hi: 0xb0}, + {value: 0x3308, lo: 0xb1, hi: 0xb2}, + {value: 0x3008, lo: 0xb3, hi: 0xb4}, + {value: 0x3308, lo: 0xb5, hi: 0xb6}, + {value: 0x0040, lo: 0xb7, hi: 0xbf}, + // Block 0x75, offset 0x3a3 + {value: 0x0000, lo: 0x10}, + {value: 0x0008, lo: 0x80, hi: 0x82}, + {value: 0x3308, lo: 0x83, hi: 0x83}, + {value: 0x0008, lo: 0x84, hi: 0x8b}, + {value: 0x3308, lo: 0x8c, hi: 0x8c}, + {value: 0x3008, lo: 0x8d, hi: 0x8d}, + {value: 0x0040, lo: 0x8e, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9b}, + {value: 0x0018, lo: 0x9c, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xb6}, + {value: 0x0018, lo: 0xb7, hi: 0xb9}, + {value: 0x0008, lo: 0xba, hi: 0xba}, + {value: 0x3008, lo: 0xbb, hi: 0xbb}, + {value: 0x3308, lo: 0xbc, hi: 0xbc}, + {value: 0x3008, lo: 0xbd, hi: 0xbd}, + {value: 0x0008, lo: 0xbe, hi: 0xbf}, + // Block 0x76, offset 0x3b4 + {value: 0x0000, lo: 0x08}, + {value: 0x0008, lo: 0x80, hi: 0xaf}, + {value: 0x3308, lo: 0xb0, hi: 0xb0}, + {value: 0x0008, lo: 0xb1, hi: 0xb1}, + {value: 0x3308, lo: 0xb2, hi: 0xb4}, + {value: 0x0008, lo: 0xb5, hi: 0xb6}, + {value: 0x3308, lo: 0xb7, hi: 0xb8}, + {value: 0x0008, lo: 0xb9, hi: 0xbd}, + {value: 0x3308, lo: 0xbe, hi: 0xbf}, + // Block 0x77, offset 0x3bd + {value: 0x0000, lo: 0x0f}, + {value: 0x0008, lo: 0x80, hi: 0x80}, + {value: 0x3308, lo: 0x81, hi: 0x81}, + {value: 0x0008, lo: 0x82, hi: 0x82}, + {value: 0x0040, lo: 0x83, hi: 0x9a}, + {value: 0x0008, lo: 0x9b, hi: 0x9d}, + {value: 0x0018, lo: 0x9e, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xaa}, + {value: 0x3008, lo: 0xab, hi: 0xab}, + {value: 0x3308, lo: 0xac, hi: 0xad}, + {value: 0x3008, lo: 0xae, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xb1}, + {value: 0x0008, lo: 0xb2, hi: 0xb4}, + {value: 0x3008, lo: 0xb5, hi: 0xb5}, + {value: 0x3b08, lo: 0xb6, hi: 0xb6}, + {value: 0x0040, lo: 0xb7, hi: 0xbf}, + // Block 0x78, offset 0x3cd + {value: 0x0000, lo: 0x0c}, + {value: 0x0040, lo: 0x80, hi: 0x80}, + {value: 0x0008, lo: 0x81, hi: 0x86}, + {value: 0x0040, lo: 0x87, hi: 0x88}, + {value: 0x0008, lo: 0x89, hi: 0x8e}, + {value: 0x0040, lo: 0x8f, hi: 0x90}, + {value: 0x0008, lo: 0x91, hi: 0x96}, + {value: 0x0040, lo: 0x97, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xa6}, + {value: 0x0040, lo: 0xa7, hi: 0xa7}, + {value: 0x0008, lo: 0xa8, hi: 0xae}, + {value: 0x0040, lo: 0xaf, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbf}, + // Block 0x79, offset 0x3da + {value: 0x0000, lo: 0x09}, + {value: 0x0008, lo: 0x80, hi: 0x9a}, + {value: 0x0018, lo: 0x9b, hi: 0x9b}, + {value: 0x4465, lo: 0x9c, hi: 0x9c}, + {value: 0x447d, lo: 0x9d, hi: 0x9d}, + {value: 0x2971, lo: 0x9e, hi: 0x9e}, + {value: 0xe06d, lo: 0x9f, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xa5}, + {value: 0x0040, lo: 0xa6, hi: 0xaf}, + {value: 0x4495, lo: 0xb0, hi: 0xbf}, + // Block 0x7a, offset 0x3e4 + {value: 0x0000, lo: 0x04}, + {value: 0x44b5, lo: 0x80, hi: 0x8f}, + {value: 0x44d5, lo: 0x90, hi: 0x9f}, + {value: 0x44f5, lo: 0xa0, hi: 0xaf}, + {value: 0x44d5, lo: 0xb0, hi: 0xbf}, + // Block 0x7b, offset 0x3e9 + {value: 0x0000, lo: 0x0c}, + {value: 0x0008, lo: 0x80, hi: 0xa2}, + {value: 0x3008, lo: 0xa3, hi: 0xa4}, + {value: 0x3308, lo: 0xa5, hi: 0xa5}, + {value: 0x3008, lo: 0xa6, hi: 0xa7}, + {value: 0x3308, lo: 0xa8, hi: 0xa8}, + {value: 0x3008, lo: 0xa9, hi: 0xaa}, + {value: 0x0018, lo: 0xab, hi: 0xab}, + {value: 0x3008, lo: 0xac, hi: 0xac}, + {value: 0x3b08, lo: 0xad, hi: 0xad}, + {value: 0x0040, lo: 0xae, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xb9}, + {value: 0x0040, lo: 0xba, hi: 0xbf}, + // Block 0x7c, offset 0x3f6 + {value: 0x0000, lo: 0x03}, + {value: 0x0008, lo: 0x80, hi: 0xa3}, + {value: 0x0040, lo: 0xa4, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xbf}, + // Block 0x7d, offset 0x3fa + {value: 0x0000, lo: 0x04}, + {value: 0x0018, lo: 0x80, hi: 0x86}, + {value: 0x0040, lo: 0x87, hi: 0x8a}, + {value: 0x0018, lo: 0x8b, hi: 0xbb}, + {value: 0x0040, lo: 0xbc, hi: 0xbf}, + // Block 0x7e, offset 0x3ff + {value: 0x0020, lo: 0x01}, + {value: 0x4515, lo: 0x80, hi: 0xbf}, + // Block 0x7f, offset 0x401 + {value: 0x0020, lo: 0x03}, + {value: 0x4d15, lo: 0x80, hi: 0x94}, + {value: 0x4ad5, lo: 0x95, hi: 0x95}, + {value: 0x4fb5, lo: 0x96, hi: 0xbf}, + // Block 0x80, offset 0x405 + {value: 0x0020, lo: 0x01}, + {value: 0x54f5, lo: 0x80, hi: 0xbf}, + // Block 0x81, offset 0x407 + {value: 0x0020, lo: 0x03}, + {value: 0x5cf5, lo: 0x80, hi: 0x84}, + {value: 0x5655, lo: 0x85, hi: 0x85}, + {value: 0x5d95, lo: 0x86, hi: 0xbf}, + // Block 0x82, offset 0x40b + {value: 0x0020, lo: 0x08}, + {value: 0x6b55, lo: 0x80, hi: 0x8f}, + {value: 0x6d15, lo: 0x90, hi: 0x90}, + {value: 0x6d55, lo: 0x91, hi: 0xab}, + {value: 0x6ea1, lo: 0xac, hi: 0xac}, + {value: 0x70b5, lo: 0xad, hi: 0xad}, + {value: 0x0040, lo: 0xae, hi: 0xae}, + {value: 0x0040, lo: 0xaf, hi: 0xaf}, + {value: 0x70d5, lo: 0xb0, hi: 0xbf}, + // Block 0x83, offset 0x414 + {value: 0x0020, lo: 0x05}, + {value: 0x72d5, lo: 0x80, hi: 0xad}, + {value: 0x6535, lo: 0xae, hi: 0xae}, + {value: 0x7895, lo: 0xaf, hi: 0xb5}, + {value: 0x6f55, lo: 0xb6, hi: 0xb6}, + {value: 0x7975, lo: 0xb7, hi: 0xbf}, + // Block 0x84, offset 0x41a + {value: 0x0028, lo: 0x03}, + {value: 0x7c21, lo: 0x80, hi: 0x82}, + {value: 0x7be1, lo: 0x83, hi: 0x83}, + {value: 0x7c99, lo: 0x84, hi: 0xbf}, + // Block 0x85, offset 0x41e + {value: 0x0038, lo: 0x0f}, + {value: 0x9db1, lo: 0x80, hi: 0x83}, + {value: 0x9e59, lo: 0x84, hi: 0x85}, + {value: 0x9e91, lo: 0x86, hi: 0x87}, + {value: 0x9ec9, lo: 0x88, hi: 0x8f}, + {value: 0x0040, lo: 0x90, hi: 0x90}, + {value: 0x0040, lo: 0x91, hi: 0x91}, + {value: 0xa089, lo: 0x92, hi: 0x97}, + {value: 0xa1a1, lo: 0x98, hi: 0x9c}, + {value: 0xa281, lo: 0x9d, hi: 0xb3}, + {value: 0x9d41, lo: 0xb4, hi: 0xb4}, + {value: 0x9db1, lo: 0xb5, hi: 0xb5}, + {value: 0xa789, lo: 0xb6, hi: 0xbb}, + {value: 0xa869, lo: 0xbc, hi: 0xbc}, + {value: 0xa7f9, lo: 0xbd, hi: 0xbd}, + {value: 0xa8d9, lo: 0xbe, hi: 0xbf}, + // Block 0x86, offset 0x42e + {value: 0x0000, lo: 0x09}, + {value: 0x0008, lo: 0x80, hi: 0x8b}, + {value: 0x0040, lo: 0x8c, hi: 0x8c}, + {value: 0x0008, lo: 0x8d, hi: 0xa6}, + {value: 0x0040, lo: 0xa7, hi: 0xa7}, + {value: 0x0008, lo: 0xa8, hi: 0xba}, + {value: 0x0040, lo: 0xbb, hi: 0xbb}, + {value: 0x0008, lo: 0xbc, hi: 0xbd}, + {value: 0x0040, lo: 0xbe, hi: 0xbe}, + {value: 0x0008, lo: 0xbf, hi: 0xbf}, + // Block 0x87, offset 0x438 + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0x8d}, + {value: 0x0040, lo: 0x8e, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x9d}, + {value: 0x0040, lo: 0x9e, hi: 0xbf}, + // Block 0x88, offset 0x43d + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xba}, + {value: 0x0040, lo: 0xbb, hi: 0xbf}, + // Block 0x89, offset 0x440 + {value: 0x0000, lo: 0x05}, + {value: 0x0018, lo: 0x80, hi: 0x82}, + {value: 0x0040, lo: 0x83, hi: 0x86}, + {value: 0x0018, lo: 0x87, hi: 0xb3}, + {value: 0x0040, lo: 0xb4, hi: 0xb6}, + {value: 0x0018, lo: 0xb7, hi: 0xbf}, + // Block 0x8a, offset 0x446 + {value: 0x0000, lo: 0x06}, + {value: 0x0018, lo: 0x80, hi: 0x8e}, + {value: 0x0040, lo: 0x8f, hi: 0x8f}, + {value: 0x0018, lo: 0x90, hi: 0x9b}, + {value: 0x0040, lo: 0x9c, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xa0}, + {value: 0x0040, lo: 0xa1, hi: 0xbf}, + // Block 0x8b, offset 0x44d + {value: 0x0000, lo: 0x04}, + {value: 0x0040, lo: 0x80, hi: 0x8f}, + {value: 0x0018, lo: 0x90, hi: 0xbc}, + {value: 0x3308, lo: 0xbd, hi: 0xbd}, + {value: 0x0040, lo: 0xbe, hi: 0xbf}, + // Block 0x8c, offset 0x452 + {value: 0x0000, lo: 0x03}, + {value: 0x0008, lo: 0x80, hi: 0x9c}, + {value: 0x0040, lo: 0x9d, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xbf}, + // Block 0x8d, offset 0x456 + {value: 0x0000, lo: 0x05}, + {value: 0x0008, lo: 0x80, hi: 0x90}, + {value: 0x0040, lo: 0x91, hi: 0x9f}, + {value: 0x3308, lo: 0xa0, hi: 0xa0}, + {value: 0x0018, lo: 0xa1, hi: 0xbb}, + {value: 0x0040, lo: 0xbc, hi: 0xbf}, + // Block 0x8e, offset 0x45c + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xa3}, + {value: 0x0040, lo: 0xa4, hi: 0xac}, + {value: 0x0008, lo: 0xad, hi: 0xbf}, + // Block 0x8f, offset 0x461 + {value: 0x0000, lo: 0x08}, + {value: 0x0008, lo: 0x80, hi: 0x80}, + {value: 0x0018, lo: 0x81, hi: 0x81}, + {value: 0x0008, lo: 0x82, hi: 0x89}, + {value: 0x0018, lo: 0x8a, hi: 0x8a}, + {value: 0x0040, lo: 0x8b, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0xb5}, + {value: 0x3308, lo: 0xb6, hi: 0xba}, + {value: 0x0040, lo: 0xbb, hi: 0xbf}, + // Block 0x90, offset 0x46a + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0x9d}, + {value: 0x0040, lo: 0x9e, hi: 0x9e}, + {value: 0x0018, lo: 0x9f, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xbf}, + // Block 0x91, offset 0x46f + {value: 0x0000, lo: 0x05}, + {value: 0x0008, lo: 0x80, hi: 0x83}, + {value: 0x0040, lo: 0x84, hi: 0x87}, + {value: 0x0008, lo: 0x88, hi: 0x8f}, + {value: 0x0018, lo: 0x90, hi: 0x95}, + {value: 0x0040, lo: 0x96, hi: 0xbf}, + // Block 0x92, offset 0x475 + {value: 0x0000, lo: 0x06}, + {value: 0xe145, lo: 0x80, hi: 0x87}, + {value: 0xe1c5, lo: 0x88, hi: 0x8f}, + {value: 0xe145, lo: 0x90, hi: 0x97}, + {value: 0x8ad5, lo: 0x98, hi: 0x9f}, + {value: 0x8aed, lo: 0xa0, hi: 0xa7}, + {value: 0x0008, lo: 0xa8, hi: 0xbf}, + // Block 0x93, offset 0x47c + {value: 0x0000, lo: 0x06}, + {value: 0x0008, lo: 0x80, hi: 0x9d}, + {value: 0x0040, lo: 0x9e, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xa9}, + {value: 0x0040, lo: 0xaa, hi: 0xaf}, + {value: 0x8aed, lo: 0xb0, hi: 0xb7}, + {value: 0x8ad5, lo: 0xb8, hi: 0xbf}, + // Block 0x94, offset 0x483 + {value: 0x0000, lo: 0x06}, + {value: 0xe145, lo: 0x80, hi: 0x87}, + {value: 0xe1c5, lo: 0x88, hi: 0x8f}, + {value: 0xe145, lo: 0x90, hi: 0x93}, + {value: 0x0040, lo: 0x94, hi: 0x97}, + {value: 0x0008, lo: 0x98, hi: 0xbb}, + {value: 0x0040, lo: 0xbc, hi: 0xbf}, + // Block 0x95, offset 0x48a + {value: 0x0000, lo: 0x03}, + {value: 0x0008, lo: 0x80, hi: 0xa7}, + {value: 0x0040, lo: 0xa8, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbf}, + // Block 0x96, offset 0x48e + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0xa3}, + {value: 0x0040, lo: 0xa4, hi: 0xae}, + {value: 0x0018, lo: 0xaf, hi: 0xaf}, + {value: 0x0040, lo: 0xb0, hi: 0xbf}, + // Block 0x97, offset 0x493 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xb6}, + {value: 0x0040, lo: 0xb7, hi: 0xbf}, + // Block 0x98, offset 0x496 + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0x95}, + {value: 0x0040, lo: 0x96, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xa7}, + {value: 0x0040, lo: 0xa8, hi: 0xbf}, + // Block 0x99, offset 0x49b + {value: 0x0000, lo: 0x0b}, + {value: 0x0808, lo: 0x80, hi: 0x85}, + {value: 0x0040, lo: 0x86, hi: 0x87}, + {value: 0x0808, lo: 0x88, hi: 0x88}, + {value: 0x0040, lo: 0x89, hi: 0x89}, + {value: 0x0808, lo: 0x8a, hi: 0xb5}, + {value: 0x0040, lo: 0xb6, hi: 0xb6}, + {value: 0x0808, lo: 0xb7, hi: 0xb8}, + {value: 0x0040, lo: 0xb9, hi: 0xbb}, + {value: 0x0808, lo: 0xbc, hi: 0xbc}, + {value: 0x0040, lo: 0xbd, hi: 0xbe}, + {value: 0x0808, lo: 0xbf, hi: 0xbf}, + // Block 0x9a, offset 0x4a7 + {value: 0x0000, lo: 0x05}, + {value: 0x0808, lo: 0x80, hi: 0x95}, + {value: 0x0040, lo: 0x96, hi: 0x96}, + {value: 0x0818, lo: 0x97, hi: 0x9f}, + {value: 0x0808, lo: 0xa0, hi: 0xb6}, + {value: 0x0818, lo: 0xb7, hi: 0xbf}, + // Block 0x9b, offset 0x4ad + {value: 0x0000, lo: 0x04}, + {value: 0x0808, lo: 0x80, hi: 0x9e}, + {value: 0x0040, lo: 0x9f, hi: 0xa6}, + {value: 0x0818, lo: 0xa7, hi: 0xaf}, + {value: 0x0040, lo: 0xb0, hi: 0xbf}, + // Block 0x9c, offset 0x4b2 + {value: 0x0000, lo: 0x06}, + {value: 0x0040, lo: 0x80, hi: 0x9f}, + {value: 0x0808, lo: 0xa0, hi: 0xb2}, + {value: 0x0040, lo: 0xb3, hi: 0xb3}, + {value: 0x0808, lo: 0xb4, hi: 0xb5}, + {value: 0x0040, lo: 0xb6, hi: 0xba}, + {value: 0x0818, lo: 0xbb, hi: 0xbf}, + // Block 0x9d, offset 0x4b9 + {value: 0x0000, lo: 0x07}, + {value: 0x0808, lo: 0x80, hi: 0x95}, + {value: 0x0818, lo: 0x96, hi: 0x9b}, + {value: 0x0040, lo: 0x9c, hi: 0x9e}, + {value: 0x0018, lo: 0x9f, hi: 0x9f}, + {value: 0x0808, lo: 0xa0, hi: 0xb9}, + {value: 0x0040, lo: 0xba, hi: 0xbe}, + {value: 0x0818, lo: 0xbf, hi: 0xbf}, + // Block 0x9e, offset 0x4c1 + {value: 0x0000, lo: 0x04}, + {value: 0x0808, lo: 0x80, hi: 0xb7}, + {value: 0x0040, lo: 0xb8, hi: 0xbb}, + {value: 0x0818, lo: 0xbc, hi: 0xbd}, + {value: 0x0808, lo: 0xbe, hi: 0xbf}, + // Block 0x9f, offset 0x4c6 + {value: 0x0000, lo: 0x03}, + {value: 0x0818, lo: 0x80, hi: 0x8f}, + {value: 0x0040, lo: 0x90, hi: 0x91}, + {value: 0x0818, lo: 0x92, hi: 0xbf}, + // Block 0xa0, offset 0x4ca + {value: 0x0000, lo: 0x0f}, + {value: 0x0808, lo: 0x80, hi: 0x80}, + {value: 0x3308, lo: 0x81, hi: 0x83}, + {value: 0x0040, lo: 0x84, hi: 0x84}, + {value: 0x3308, lo: 0x85, hi: 0x86}, + {value: 0x0040, lo: 0x87, hi: 0x8b}, + {value: 0x3308, lo: 0x8c, hi: 0x8f}, + {value: 0x0808, lo: 0x90, hi: 0x93}, + {value: 0x0040, lo: 0x94, hi: 0x94}, + {value: 0x0808, lo: 0x95, hi: 0x97}, + {value: 0x0040, lo: 0x98, hi: 0x98}, + {value: 0x0808, lo: 0x99, hi: 0xb3}, + {value: 0x0040, lo: 0xb4, hi: 0xb7}, + {value: 0x3308, lo: 0xb8, hi: 0xba}, + {value: 0x0040, lo: 0xbb, hi: 0xbe}, + {value: 0x3b08, lo: 0xbf, hi: 0xbf}, + // Block 0xa1, offset 0x4da + {value: 0x0000, lo: 0x06}, + {value: 0x0818, lo: 0x80, hi: 0x87}, + {value: 0x0040, lo: 0x88, hi: 0x8f}, + {value: 0x0818, lo: 0x90, hi: 0x98}, + {value: 0x0040, lo: 0x99, hi: 0x9f}, + {value: 0x0808, lo: 0xa0, hi: 0xbc}, + {value: 0x0818, lo: 0xbd, hi: 0xbf}, + // Block 0xa2, offset 0x4e1 + {value: 0x0000, lo: 0x03}, + {value: 0x0808, lo: 0x80, hi: 0x9c}, + {value: 0x0818, lo: 0x9d, hi: 0x9f}, + {value: 0x0040, lo: 0xa0, hi: 0xbf}, + // Block 0xa3, offset 0x4e5 + {value: 0x0000, lo: 0x03}, + {value: 0x0808, lo: 0x80, hi: 0xb5}, + {value: 0x0040, lo: 0xb6, hi: 0xb8}, + {value: 0x0018, lo: 0xb9, hi: 0xbf}, + // Block 0xa4, offset 0x4e9 + {value: 0x0000, lo: 0x06}, + {value: 0x0808, lo: 0x80, hi: 0x95}, + {value: 0x0040, lo: 0x96, hi: 0x97}, + {value: 0x0818, lo: 0x98, hi: 0x9f}, + {value: 0x0808, lo: 0xa0, hi: 0xb2}, + {value: 0x0040, lo: 0xb3, hi: 0xb7}, + {value: 0x0818, lo: 0xb8, hi: 0xbf}, + // Block 0xa5, offset 0x4f0 + {value: 0x0000, lo: 0x01}, + {value: 0x0808, lo: 0x80, hi: 0xbf}, + // Block 0xa6, offset 0x4f2 + {value: 0x0000, lo: 0x02}, + {value: 0x0808, lo: 0x80, hi: 0x88}, + {value: 0x0040, lo: 0x89, hi: 0xbf}, + // Block 0xa7, offset 0x4f5 + {value: 0x0000, lo: 0x02}, + {value: 0x03dd, lo: 0x80, hi: 0xb2}, + {value: 0x0040, lo: 0xb3, hi: 0xbf}, + // Block 0xa8, offset 0x4f8 + {value: 0x0000, lo: 0x03}, + {value: 0x0808, lo: 0x80, hi: 0xb2}, + {value: 0x0040, lo: 0xb3, hi: 0xb9}, + {value: 0x0818, lo: 0xba, hi: 0xbf}, + // Block 0xa9, offset 0x4fc + {value: 0x0000, lo: 0x03}, + {value: 0x0040, lo: 0x80, hi: 0x9f}, + {value: 0x0818, lo: 0xa0, hi: 0xbe}, + {value: 0x0040, lo: 0xbf, hi: 0xbf}, + // Block 0xaa, offset 0x500 + {value: 0x0000, lo: 0x05}, + {value: 0x3008, lo: 0x80, hi: 0x80}, + {value: 0x3308, lo: 0x81, hi: 0x81}, + {value: 0x3008, lo: 0x82, hi: 0x82}, + {value: 0x0008, lo: 0x83, hi: 0xb7}, + {value: 0x3308, lo: 0xb8, hi: 0xbf}, + // Block 0xab, offset 0x506 + {value: 0x0000, lo: 0x08}, + {value: 0x3308, lo: 0x80, hi: 0x85}, + {value: 0x3b08, lo: 0x86, hi: 0x86}, + {value: 0x0018, lo: 0x87, hi: 0x8d}, + {value: 0x0040, lo: 0x8e, hi: 0x91}, + {value: 0x0018, lo: 0x92, hi: 0xa5}, + {value: 0x0008, lo: 0xa6, hi: 0xaf}, + {value: 0x0040, lo: 0xb0, hi: 0xbe}, + {value: 0x3b08, lo: 0xbf, hi: 0xbf}, + // Block 0xac, offset 0x50f + {value: 0x0000, lo: 0x0b}, + {value: 0x3308, lo: 0x80, hi: 0x81}, + {value: 0x3008, lo: 0x82, hi: 0x82}, + {value: 0x0008, lo: 0x83, hi: 0xaf}, + {value: 0x3008, lo: 0xb0, hi: 0xb2}, + {value: 0x3308, lo: 0xb3, hi: 0xb6}, + {value: 0x3008, lo: 0xb7, hi: 0xb8}, + {value: 0x3b08, lo: 0xb9, hi: 0xb9}, + {value: 0x3308, lo: 0xba, hi: 0xba}, + {value: 0x0018, lo: 0xbb, hi: 0xbc}, + {value: 0x0340, lo: 0xbd, hi: 0xbd}, + {value: 0x0018, lo: 0xbe, hi: 0xbf}, + // Block 0xad, offset 0x51b + {value: 0x0000, lo: 0x06}, + {value: 0x0018, lo: 0x80, hi: 0x81}, + {value: 0x0040, lo: 0x82, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0xa8}, + {value: 0x0040, lo: 0xa9, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xb9}, + {value: 0x0040, lo: 0xba, hi: 0xbf}, + // Block 0xae, offset 0x522 + {value: 0x0000, lo: 0x08}, + {value: 0x3308, lo: 0x80, hi: 0x82}, + {value: 0x0008, lo: 0x83, hi: 0xa6}, + {value: 0x3308, lo: 0xa7, hi: 0xab}, + {value: 0x3008, lo: 0xac, hi: 0xac}, + {value: 0x3308, lo: 0xad, hi: 0xb2}, + {value: 0x3b08, lo: 0xb3, hi: 0xb4}, + {value: 0x0040, lo: 0xb5, hi: 0xb5}, + {value: 0x0008, lo: 0xb6, hi: 0xbf}, + // Block 0xaf, offset 0x52b + {value: 0x0000, lo: 0x07}, + {value: 0x0018, lo: 0x80, hi: 0x83}, + {value: 0x0040, lo: 0x84, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0xb2}, + {value: 0x3308, lo: 0xb3, hi: 0xb3}, + {value: 0x0018, lo: 0xb4, hi: 0xb5}, + {value: 0x0008, lo: 0xb6, hi: 0xb6}, + {value: 0x0040, lo: 0xb7, hi: 0xbf}, + // Block 0xb0, offset 0x533 + {value: 0x0000, lo: 0x06}, + {value: 0x3308, lo: 0x80, hi: 0x81}, + {value: 0x3008, lo: 0x82, hi: 0x82}, + {value: 0x0008, lo: 0x83, hi: 0xb2}, + {value: 0x3008, lo: 0xb3, hi: 0xb5}, + {value: 0x3308, lo: 0xb6, hi: 0xbe}, + {value: 0x3008, lo: 0xbf, hi: 0xbf}, + // Block 0xb1, offset 0x53a + {value: 0x0000, lo: 0x0d}, + {value: 0x3808, lo: 0x80, hi: 0x80}, + {value: 0x0008, lo: 0x81, hi: 0x84}, + {value: 0x0018, lo: 0x85, hi: 0x89}, + {value: 0x3308, lo: 0x8a, hi: 0x8c}, + {value: 0x0018, lo: 0x8d, hi: 0x8d}, + {value: 0x0040, lo: 0x8e, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x9a}, + {value: 0x0018, lo: 0x9b, hi: 0x9b}, + {value: 0x0008, lo: 0x9c, hi: 0x9c}, + {value: 0x0018, lo: 0x9d, hi: 0x9f}, + {value: 0x0040, lo: 0xa0, hi: 0xa0}, + {value: 0x0018, lo: 0xa1, hi: 0xb4}, + {value: 0x0040, lo: 0xb5, hi: 0xbf}, + // Block 0xb2, offset 0x548 + {value: 0x0000, lo: 0x0c}, + {value: 0x0008, lo: 0x80, hi: 0x91}, + {value: 0x0040, lo: 0x92, hi: 0x92}, + {value: 0x0008, lo: 0x93, hi: 0xab}, + {value: 0x3008, lo: 0xac, hi: 0xae}, + {value: 0x3308, lo: 0xaf, hi: 0xb1}, + {value: 0x3008, lo: 0xb2, hi: 0xb3}, + {value: 0x3308, lo: 0xb4, hi: 0xb4}, + {value: 0x3808, lo: 0xb5, hi: 0xb5}, + {value: 0x3308, lo: 0xb6, hi: 0xb7}, + {value: 0x0018, lo: 0xb8, hi: 0xbd}, + {value: 0x3308, lo: 0xbe, hi: 0xbe}, + {value: 0x0040, lo: 0xbf, hi: 0xbf}, + // Block 0xb3, offset 0x555 + {value: 0x0000, lo: 0x0c}, + {value: 0x0008, lo: 0x80, hi: 0x86}, + {value: 0x0040, lo: 0x87, hi: 0x87}, + {value: 0x0008, lo: 0x88, hi: 0x88}, + {value: 0x0040, lo: 0x89, hi: 0x89}, + {value: 0x0008, lo: 0x8a, hi: 0x8d}, + {value: 0x0040, lo: 0x8e, hi: 0x8e}, + {value: 0x0008, lo: 0x8f, hi: 0x9d}, + {value: 0x0040, lo: 0x9e, hi: 0x9e}, + {value: 0x0008, lo: 0x9f, hi: 0xa8}, + {value: 0x0018, lo: 0xa9, hi: 0xa9}, + {value: 0x0040, lo: 0xaa, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbf}, + // Block 0xb4, offset 0x562 + {value: 0x0000, lo: 0x08}, + {value: 0x0008, lo: 0x80, hi: 0x9e}, + {value: 0x3308, lo: 0x9f, hi: 0x9f}, + {value: 0x3008, lo: 0xa0, hi: 0xa2}, + {value: 0x3308, lo: 0xa3, hi: 0xa9}, + {value: 0x3b08, lo: 0xaa, hi: 0xaa}, + {value: 0x0040, lo: 0xab, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xb9}, + {value: 0x0040, lo: 0xba, hi: 0xbf}, + // Block 0xb5, offset 0x56b + {value: 0x0000, lo: 0x03}, + {value: 0x0008, lo: 0x80, hi: 0xb4}, + {value: 0x3008, lo: 0xb5, hi: 0xb7}, + {value: 0x3308, lo: 0xb8, hi: 0xbf}, + // Block 0xb6, offset 0x56f + {value: 0x0000, lo: 0x0d}, + {value: 0x3008, lo: 0x80, hi: 0x81}, + {value: 0x3b08, lo: 0x82, hi: 0x82}, + {value: 0x3308, lo: 0x83, hi: 0x84}, + {value: 0x3008, lo: 0x85, hi: 0x85}, + {value: 0x3308, lo: 0x86, hi: 0x86}, + {value: 0x0008, lo: 0x87, hi: 0x8a}, + {value: 0x0018, lo: 0x8b, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9a}, + {value: 0x0018, lo: 0x9b, hi: 0x9b}, + {value: 0x0040, lo: 0x9c, hi: 0x9c}, + {value: 0x0018, lo: 0x9d, hi: 0x9d}, + {value: 0x0040, lo: 0x9e, hi: 0xbf}, + // Block 0xb7, offset 0x57d + {value: 0x0000, lo: 0x07}, + {value: 0x0008, lo: 0x80, hi: 0xaf}, + {value: 0x3008, lo: 0xb0, hi: 0xb2}, + {value: 0x3308, lo: 0xb3, hi: 0xb8}, + {value: 0x3008, lo: 0xb9, hi: 0xb9}, + {value: 0x3308, lo: 0xba, hi: 0xba}, + {value: 0x3008, lo: 0xbb, hi: 0xbe}, + {value: 0x3308, lo: 0xbf, hi: 0xbf}, + // Block 0xb8, offset 0x585 + {value: 0x0000, lo: 0x0a}, + {value: 0x3308, lo: 0x80, hi: 0x80}, + {value: 0x3008, lo: 0x81, hi: 0x81}, + {value: 0x3b08, lo: 0x82, hi: 0x82}, + {value: 0x3308, lo: 0x83, hi: 0x83}, + {value: 0x0008, lo: 0x84, hi: 0x85}, + {value: 0x0018, lo: 0x86, hi: 0x86}, + {value: 0x0008, lo: 0x87, hi: 0x87}, + {value: 0x0040, lo: 0x88, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0xbf}, + // Block 0xb9, offset 0x590 + {value: 0x0000, lo: 0x08}, + {value: 0x0008, lo: 0x80, hi: 0xae}, + {value: 0x3008, lo: 0xaf, hi: 0xb1}, + {value: 0x3308, lo: 0xb2, hi: 0xb5}, + {value: 0x0040, lo: 0xb6, hi: 0xb7}, + {value: 0x3008, lo: 0xb8, hi: 0xbb}, + {value: 0x3308, lo: 0xbc, hi: 0xbd}, + {value: 0x3008, lo: 0xbe, hi: 0xbe}, + {value: 0x3b08, lo: 0xbf, hi: 0xbf}, + // Block 0xba, offset 0x599 + {value: 0x0000, lo: 0x05}, + {value: 0x3308, lo: 0x80, hi: 0x80}, + {value: 0x0018, lo: 0x81, hi: 0x97}, + {value: 0x0008, lo: 0x98, hi: 0x9b}, + {value: 0x3308, lo: 0x9c, hi: 0x9d}, + {value: 0x0040, lo: 0x9e, hi: 0xbf}, + // Block 0xbb, offset 0x59f + {value: 0x0000, lo: 0x07}, + {value: 0x0008, lo: 0x80, hi: 0xaf}, + {value: 0x3008, lo: 0xb0, hi: 0xb2}, + {value: 0x3308, lo: 0xb3, hi: 0xba}, + {value: 0x3008, lo: 0xbb, hi: 0xbc}, + {value: 0x3308, lo: 0xbd, hi: 0xbd}, + {value: 0x3008, lo: 0xbe, hi: 0xbe}, + {value: 0x3b08, lo: 0xbf, hi: 0xbf}, + // Block 0xbc, offset 0x5a7 + {value: 0x0000, lo: 0x08}, + {value: 0x3308, lo: 0x80, hi: 0x80}, + {value: 0x0018, lo: 0x81, hi: 0x83}, + {value: 0x0008, lo: 0x84, hi: 0x84}, + {value: 0x0040, lo: 0x85, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xac}, + {value: 0x0040, lo: 0xad, hi: 0xbf}, + // Block 0xbd, offset 0x5b0 + {value: 0x0000, lo: 0x09}, + {value: 0x0008, lo: 0x80, hi: 0xaa}, + {value: 0x3308, lo: 0xab, hi: 0xab}, + {value: 0x3008, lo: 0xac, hi: 0xac}, + {value: 0x3308, lo: 0xad, hi: 0xad}, + {value: 0x3008, lo: 0xae, hi: 0xaf}, + {value: 0x3308, lo: 0xb0, hi: 0xb5}, + {value: 0x3808, lo: 0xb6, hi: 0xb6}, + {value: 0x3308, lo: 0xb7, hi: 0xb7}, + {value: 0x0040, lo: 0xb8, hi: 0xbf}, + // Block 0xbe, offset 0x5ba + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0x89}, + {value: 0x0040, lo: 0x8a, hi: 0xbf}, + // Block 0xbf, offset 0x5bd + {value: 0x0000, lo: 0x0b}, + {value: 0x0008, lo: 0x80, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9c}, + {value: 0x3308, lo: 0x9d, hi: 0x9f}, + {value: 0x3008, lo: 0xa0, hi: 0xa1}, + {value: 0x3308, lo: 0xa2, hi: 0xa5}, + {value: 0x3008, lo: 0xa6, hi: 0xa6}, + {value: 0x3308, lo: 0xa7, hi: 0xaa}, + {value: 0x3b08, lo: 0xab, hi: 0xab}, + {value: 0x0040, lo: 0xac, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xb9}, + {value: 0x0018, lo: 0xba, hi: 0xbf}, + // Block 0xc0, offset 0x5c9 + {value: 0x0000, lo: 0x02}, + {value: 0x0040, lo: 0x80, hi: 0x9f}, + {value: 0x049d, lo: 0xa0, hi: 0xbf}, + // Block 0xc1, offset 0x5cc + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0xa9}, + {value: 0x0018, lo: 0xaa, hi: 0xb2}, + {value: 0x0040, lo: 0xb3, hi: 0xbe}, + {value: 0x0008, lo: 0xbf, hi: 0xbf}, + // Block 0xc2, offset 0x5d1 + {value: 0x0000, lo: 0x0c}, + {value: 0x0008, lo: 0x80, hi: 0x80}, + {value: 0x3308, lo: 0x81, hi: 0x86}, + {value: 0x3008, lo: 0x87, hi: 0x88}, + {value: 0x3308, lo: 0x89, hi: 0x8a}, + {value: 0x0008, lo: 0x8b, hi: 0xb2}, + {value: 0x3308, lo: 0xb3, hi: 0xb3}, + {value: 0x3b08, lo: 0xb4, hi: 0xb4}, + {value: 0x3308, lo: 0xb5, hi: 0xb8}, + {value: 0x3008, lo: 0xb9, hi: 0xb9}, + {value: 0x0008, lo: 0xba, hi: 0xba}, + {value: 0x3308, lo: 0xbb, hi: 0xbe}, + {value: 0x0018, lo: 0xbf, hi: 0xbf}, + // Block 0xc3, offset 0x5de + {value: 0x0000, lo: 0x08}, + {value: 0x0018, lo: 0x80, hi: 0x86}, + {value: 0x3b08, lo: 0x87, hi: 0x87}, + {value: 0x0040, lo: 0x88, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x90}, + {value: 0x3308, lo: 0x91, hi: 0x96}, + {value: 0x3008, lo: 0x97, hi: 0x98}, + {value: 0x3308, lo: 0x99, hi: 0x9b}, + {value: 0x0008, lo: 0x9c, hi: 0xbf}, + // Block 0xc4, offset 0x5e7 + {value: 0x0000, lo: 0x0b}, + {value: 0x0008, lo: 0x80, hi: 0x83}, + {value: 0x0040, lo: 0x84, hi: 0x85}, + {value: 0x0008, lo: 0x86, hi: 0x89}, + {value: 0x3308, lo: 0x8a, hi: 0x96}, + {value: 0x3008, lo: 0x97, hi: 0x97}, + {value: 0x3308, lo: 0x98, hi: 0x98}, + {value: 0x3b08, lo: 0x99, hi: 0x99}, + {value: 0x0018, lo: 0x9a, hi: 0x9c}, + {value: 0x0040, lo: 0x9d, hi: 0x9d}, + {value: 0x0018, lo: 0x9e, hi: 0xa2}, + {value: 0x0040, lo: 0xa3, hi: 0xbf}, + // Block 0xc5, offset 0x5f3 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xb8}, + {value: 0x0040, lo: 0xb9, hi: 0xbf}, + // Block 0xc6, offset 0x5f6 + {value: 0x0000, lo: 0x09}, + {value: 0x0008, lo: 0x80, hi: 0x88}, + {value: 0x0040, lo: 0x89, hi: 0x89}, + {value: 0x0008, lo: 0x8a, hi: 0xae}, + {value: 0x3008, lo: 0xaf, hi: 0xaf}, + {value: 0x3308, lo: 0xb0, hi: 0xb6}, + {value: 0x0040, lo: 0xb7, hi: 0xb7}, + {value: 0x3308, lo: 0xb8, hi: 0xbd}, + {value: 0x3008, lo: 0xbe, hi: 0xbe}, + {value: 0x3b08, lo: 0xbf, hi: 0xbf}, + // Block 0xc7, offset 0x600 + {value: 0x0000, lo: 0x08}, + {value: 0x0008, lo: 0x80, hi: 0x80}, + {value: 0x0018, lo: 0x81, hi: 0x85}, + {value: 0x0040, lo: 0x86, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0018, lo: 0x9a, hi: 0xac}, + {value: 0x0040, lo: 0xad, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xb1}, + {value: 0x0008, lo: 0xb2, hi: 0xbf}, + // Block 0xc8, offset 0x609 + {value: 0x0000, lo: 0x0b}, + {value: 0x0008, lo: 0x80, hi: 0x8f}, + {value: 0x0040, lo: 0x90, hi: 0x91}, + {value: 0x3308, lo: 0x92, hi: 0xa7}, + {value: 0x0040, lo: 0xa8, hi: 0xa8}, + {value: 0x3008, lo: 0xa9, hi: 0xa9}, + {value: 0x3308, lo: 0xaa, hi: 0xb0}, + {value: 0x3008, lo: 0xb1, hi: 0xb1}, + {value: 0x3308, lo: 0xb2, hi: 0xb3}, + {value: 0x3008, lo: 0xb4, hi: 0xb4}, + {value: 0x3308, lo: 0xb5, hi: 0xb6}, + {value: 0x0040, lo: 0xb7, hi: 0xbf}, + // Block 0xc9, offset 0x615 + {value: 0x0000, lo: 0x0c}, + {value: 0x0008, lo: 0x80, hi: 0x86}, + {value: 0x0040, lo: 0x87, hi: 0x87}, + {value: 0x0008, lo: 0x88, hi: 0x89}, + {value: 0x0040, lo: 0x8a, hi: 0x8a}, + {value: 0x0008, lo: 0x8b, hi: 0xb0}, + {value: 0x3308, lo: 0xb1, hi: 0xb6}, + {value: 0x0040, lo: 0xb7, hi: 0xb9}, + {value: 0x3308, lo: 0xba, hi: 0xba}, + {value: 0x0040, lo: 0xbb, hi: 0xbb}, + {value: 0x3308, lo: 0xbc, hi: 0xbd}, + {value: 0x0040, lo: 0xbe, hi: 0xbe}, + {value: 0x3308, lo: 0xbf, hi: 0xbf}, + // Block 0xca, offset 0x622 + {value: 0x0000, lo: 0x07}, + {value: 0x3308, lo: 0x80, hi: 0x83}, + {value: 0x3b08, lo: 0x84, hi: 0x85}, + {value: 0x0008, lo: 0x86, hi: 0x86}, + {value: 0x3308, lo: 0x87, hi: 0x87}, + {value: 0x0040, lo: 0x88, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0xbf}, + // Block 0xcb, offset 0x62a + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0xbf}, + // Block 0xcc, offset 0x62d + {value: 0x0000, lo: 0x04}, + {value: 0x0018, lo: 0x80, hi: 0xae}, + {value: 0x0040, lo: 0xaf, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xb4}, + {value: 0x0040, lo: 0xb5, hi: 0xbf}, + // Block 0xcd, offset 0x632 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0x83}, + {value: 0x0040, lo: 0x84, hi: 0xbf}, + // Block 0xce, offset 0x635 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xae}, + {value: 0x0040, lo: 0xaf, hi: 0xbf}, + // Block 0xcf, offset 0x638 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0x86}, + {value: 0x0040, lo: 0x87, hi: 0xbf}, + // Block 0xd0, offset 0x63b + {value: 0x0000, lo: 0x06}, + {value: 0x0008, lo: 0x80, hi: 0x9e}, + {value: 0x0040, lo: 0x9f, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xa9}, + {value: 0x0040, lo: 0xaa, hi: 0xad}, + {value: 0x0018, lo: 0xae, hi: 0xaf}, + {value: 0x0040, lo: 0xb0, hi: 0xbf}, + // Block 0xd1, offset 0x642 + {value: 0x0000, lo: 0x06}, + {value: 0x0040, lo: 0x80, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0xad}, + {value: 0x0040, lo: 0xae, hi: 0xaf}, + {value: 0x3308, lo: 0xb0, hi: 0xb4}, + {value: 0x0018, lo: 0xb5, hi: 0xb5}, + {value: 0x0040, lo: 0xb6, hi: 0xbf}, + // Block 0xd2, offset 0x649 + {value: 0x0000, lo: 0x03}, + {value: 0x0008, lo: 0x80, hi: 0xaf}, + {value: 0x3308, lo: 0xb0, hi: 0xb6}, + {value: 0x0018, lo: 0xb7, hi: 0xbf}, + // Block 0xd3, offset 0x64d + {value: 0x0000, lo: 0x0a}, + {value: 0x0008, lo: 0x80, hi: 0x83}, + {value: 0x0018, lo: 0x84, hi: 0x85}, + {value: 0x0040, lo: 0x86, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9a}, + {value: 0x0018, lo: 0x9b, hi: 0xa1}, + {value: 0x0040, lo: 0xa2, hi: 0xa2}, + {value: 0x0008, lo: 0xa3, hi: 0xb7}, + {value: 0x0040, lo: 0xb8, hi: 0xbc}, + {value: 0x0008, lo: 0xbd, hi: 0xbf}, + // Block 0xd4, offset 0x658 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0x8f}, + {value: 0x0040, lo: 0x90, hi: 0xbf}, + // Block 0xd5, offset 0x65b + {value: 0x0000, lo: 0x05}, + {value: 0x0008, lo: 0x80, hi: 0x84}, + {value: 0x0040, lo: 0x85, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x90}, + {value: 0x3008, lo: 0x91, hi: 0xbe}, + {value: 0x0040, lo: 0xbf, hi: 0xbf}, + // Block 0xd6, offset 0x661 + {value: 0x0000, lo: 0x04}, + {value: 0x0040, lo: 0x80, hi: 0x8e}, + {value: 0x3308, lo: 0x8f, hi: 0x92}, + {value: 0x0008, lo: 0x93, hi: 0x9f}, + {value: 0x0040, lo: 0xa0, hi: 0xbf}, + // Block 0xd7, offset 0x666 + {value: 0x0000, lo: 0x03}, + {value: 0x0040, lo: 0x80, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xa1}, + {value: 0x0040, lo: 0xa2, hi: 0xbf}, + // Block 0xd8, offset 0x66a + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xac}, + {value: 0x0040, lo: 0xad, hi: 0xbf}, + // Block 0xd9, offset 0x66d + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xb2}, + {value: 0x0040, lo: 0xb3, hi: 0xbf}, + // Block 0xda, offset 0x670 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0x9e}, + {value: 0x0040, lo: 0x9f, hi: 0xbf}, + // Block 0xdb, offset 0x673 + {value: 0x0000, lo: 0x02}, + {value: 0x0040, lo: 0x80, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbf}, + // Block 0xdc, offset 0x676 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xbb}, + {value: 0x0040, lo: 0xbc, hi: 0xbf}, + // Block 0xdd, offset 0x679 + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0xaa}, + {value: 0x0040, lo: 0xab, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbc}, + {value: 0x0040, lo: 0xbd, hi: 0xbf}, + // Block 0xde, offset 0x67e + {value: 0x0000, lo: 0x09}, + {value: 0x0008, lo: 0x80, hi: 0x88}, + {value: 0x0040, lo: 0x89, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9b}, + {value: 0x0018, lo: 0x9c, hi: 0x9c}, + {value: 0x3308, lo: 0x9d, hi: 0x9e}, + {value: 0x0018, lo: 0x9f, hi: 0x9f}, + {value: 0x03c0, lo: 0xa0, hi: 0xa3}, + {value: 0x0040, lo: 0xa4, hi: 0xbf}, + // Block 0xdf, offset 0x688 + {value: 0x0000, lo: 0x02}, + {value: 0x0018, lo: 0x80, hi: 0xb5}, + {value: 0x0040, lo: 0xb6, hi: 0xbf}, + // Block 0xe0, offset 0x68b + {value: 0x0000, lo: 0x03}, + {value: 0x0018, lo: 0x80, hi: 0xa6}, + {value: 0x0040, lo: 0xa7, hi: 0xa8}, + {value: 0x0018, lo: 0xa9, hi: 0xbf}, + // Block 0xe1, offset 0x68f + {value: 0x0000, lo: 0x0e}, + {value: 0x0018, lo: 0x80, hi: 0x9d}, + {value: 0xb5b9, lo: 0x9e, hi: 0x9e}, + {value: 0xb601, lo: 0x9f, hi: 0x9f}, + {value: 0xb649, lo: 0xa0, hi: 0xa0}, + {value: 0xb6b1, lo: 0xa1, hi: 0xa1}, + {value: 0xb719, lo: 0xa2, hi: 0xa2}, + {value: 0xb781, lo: 0xa3, hi: 0xa3}, + {value: 0xb7e9, lo: 0xa4, hi: 0xa4}, + {value: 0x3018, lo: 0xa5, hi: 0xa6}, + {value: 0x3318, lo: 0xa7, hi: 0xa9}, + {value: 0x0018, lo: 0xaa, hi: 0xac}, + {value: 0x3018, lo: 0xad, hi: 0xb2}, + {value: 0x0340, lo: 0xb3, hi: 0xba}, + {value: 0x3318, lo: 0xbb, hi: 0xbf}, + // Block 0xe2, offset 0x69e + {value: 0x0000, lo: 0x0b}, + {value: 0x3318, lo: 0x80, hi: 0x82}, + {value: 0x0018, lo: 0x83, hi: 0x84}, + {value: 0x3318, lo: 0x85, hi: 0x8b}, + {value: 0x0018, lo: 0x8c, hi: 0xa9}, + {value: 0x3318, lo: 0xaa, hi: 0xad}, + {value: 0x0018, lo: 0xae, hi: 0xba}, + {value: 0xb851, lo: 0xbb, hi: 0xbb}, + {value: 0xb899, lo: 0xbc, hi: 0xbc}, + {value: 0xb8e1, lo: 0xbd, hi: 0xbd}, + {value: 0xb949, lo: 0xbe, hi: 0xbe}, + {value: 0xb9b1, lo: 0xbf, hi: 0xbf}, + // Block 0xe3, offset 0x6aa + {value: 0x0000, lo: 0x03}, + {value: 0xba19, lo: 0x80, hi: 0x80}, + {value: 0x0018, lo: 0x81, hi: 0xa8}, + {value: 0x0040, lo: 0xa9, hi: 0xbf}, + // Block 0xe4, offset 0x6ae + {value: 0x0000, lo: 0x04}, + {value: 0x0018, lo: 0x80, hi: 0x81}, + {value: 0x3318, lo: 0x82, hi: 0x84}, + {value: 0x0018, lo: 0x85, hi: 0x85}, + {value: 0x0040, lo: 0x86, hi: 0xbf}, + // Block 0xe5, offset 0x6b3 + {value: 0x0000, lo: 0x04}, + {value: 0x0018, lo: 0x80, hi: 0x96}, + {value: 0x0040, lo: 0x97, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xb1}, + {value: 0x0040, lo: 0xb2, hi: 0xbf}, + // Block 0xe6, offset 0x6b8 + {value: 0x0000, lo: 0x03}, + {value: 0x3308, lo: 0x80, hi: 0xb6}, + {value: 0x0018, lo: 0xb7, hi: 0xba}, + {value: 0x3308, lo: 0xbb, hi: 0xbf}, + // Block 0xe7, offset 0x6bc + {value: 0x0000, lo: 0x04}, + {value: 0x3308, lo: 0x80, hi: 0xac}, + {value: 0x0018, lo: 0xad, hi: 0xb4}, + {value: 0x3308, lo: 0xb5, hi: 0xb5}, + {value: 0x0018, lo: 0xb6, hi: 0xbf}, + // Block 0xe8, offset 0x6c1 + {value: 0x0000, lo: 0x08}, + {value: 0x0018, lo: 0x80, hi: 0x83}, + {value: 0x3308, lo: 0x84, hi: 0x84}, + {value: 0x0018, lo: 0x85, hi: 0x8b}, + {value: 0x0040, lo: 0x8c, hi: 0x9a}, + {value: 0x3308, lo: 0x9b, hi: 0x9f}, + {value: 0x0040, lo: 0xa0, hi: 0xa0}, + {value: 0x3308, lo: 0xa1, hi: 0xaf}, + {value: 0x0040, lo: 0xb0, hi: 0xbf}, + // Block 0xe9, offset 0x6ca + {value: 0x0000, lo: 0x0a}, + {value: 0x3308, lo: 0x80, hi: 0x86}, + {value: 0x0040, lo: 0x87, hi: 0x87}, + {value: 0x3308, lo: 0x88, hi: 0x98}, + {value: 0x0040, lo: 0x99, hi: 0x9a}, + {value: 0x3308, lo: 0x9b, hi: 0xa1}, + {value: 0x0040, lo: 0xa2, hi: 0xa2}, + {value: 0x3308, lo: 0xa3, hi: 0xa4}, + {value: 0x0040, lo: 0xa5, hi: 0xa5}, + {value: 0x3308, lo: 0xa6, hi: 0xaa}, + {value: 0x0040, lo: 0xab, hi: 0xbf}, + // Block 0xea, offset 0x6d5 + {value: 0x0000, lo: 0x05}, + {value: 0x0808, lo: 0x80, hi: 0x84}, + {value: 0x0040, lo: 0x85, hi: 0x86}, + {value: 0x0818, lo: 0x87, hi: 0x8f}, + {value: 0x3308, lo: 0x90, hi: 0x96}, + {value: 0x0040, lo: 0x97, hi: 0xbf}, + // Block 0xeb, offset 0x6db + {value: 0x0000, lo: 0x07}, + {value: 0x0a08, lo: 0x80, hi: 0x83}, + {value: 0x3308, lo: 0x84, hi: 0x8a}, + {value: 0x0040, lo: 0x8b, hi: 0x8f}, + {value: 0x0808, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9d}, + {value: 0x0818, lo: 0x9e, hi: 0x9f}, + {value: 0x0040, lo: 0xa0, hi: 0xbf}, + // Block 0xec, offset 0x6e3 + {value: 0x0000, lo: 0x03}, + {value: 0x0040, lo: 0x80, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xb1}, + {value: 0x0040, lo: 0xb2, hi: 0xbf}, + // Block 0xed, offset 0x6e7 + {value: 0x0000, lo: 0x03}, + {value: 0x0018, lo: 0x80, hi: 0xab}, + {value: 0x0040, lo: 0xac, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xbf}, + // Block 0xee, offset 0x6eb + {value: 0x0000, lo: 0x05}, + {value: 0x0018, lo: 0x80, hi: 0x93}, + {value: 0x0040, lo: 0x94, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xae}, + {value: 0x0040, lo: 0xaf, hi: 0xb0}, + {value: 0x0018, lo: 0xb1, hi: 0xbf}, + // Block 0xef, offset 0x6f1 + {value: 0x0000, lo: 0x05}, + {value: 0x0040, lo: 0x80, hi: 0x80}, + {value: 0x0018, lo: 0x81, hi: 0x8f}, + {value: 0x0040, lo: 0x90, hi: 0x90}, + {value: 0x0018, lo: 0x91, hi: 0xb5}, + {value: 0x0040, lo: 0xb6, hi: 0xbf}, + // Block 0xf0, offset 0x6f7 + {value: 0x0000, lo: 0x04}, + {value: 0x0018, lo: 0x80, hi: 0x8f}, + {value: 0xc1c1, lo: 0x90, hi: 0x90}, + {value: 0x0018, lo: 0x91, hi: 0xac}, + {value: 0x0040, lo: 0xad, hi: 0xbf}, + // Block 0xf1, offset 0x6fc + {value: 0x0000, lo: 0x02}, + {value: 0x0040, lo: 0x80, hi: 0xa5}, + {value: 0x0018, lo: 0xa6, hi: 0xbf}, + // Block 0xf2, offset 0x6ff + {value: 0x0000, lo: 0x0f}, + {value: 0xc7e9, lo: 0x80, hi: 0x80}, + {value: 0xc839, lo: 0x81, hi: 0x81}, + {value: 0xc889, lo: 0x82, hi: 0x82}, + {value: 0xc8d9, lo: 0x83, hi: 0x83}, + {value: 0xc929, lo: 0x84, hi: 0x84}, + {value: 0xc979, lo: 0x85, hi: 0x85}, + {value: 0xc9c9, lo: 0x86, hi: 0x86}, + {value: 0xca19, lo: 0x87, hi: 0x87}, + {value: 0xca69, lo: 0x88, hi: 0x88}, + {value: 0x0040, lo: 0x89, hi: 0x8f}, + {value: 0xcab9, lo: 0x90, hi: 0x90}, + {value: 0xcad9, lo: 0x91, hi: 0x91}, + {value: 0x0040, lo: 0x92, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xa5}, + {value: 0x0040, lo: 0xa6, hi: 0xbf}, + // Block 0xf3, offset 0x70f + {value: 0x0000, lo: 0x06}, + {value: 0x0018, lo: 0x80, hi: 0x94}, + {value: 0x0040, lo: 0x95, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xac}, + {value: 0x0040, lo: 0xad, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xb8}, + {value: 0x0040, lo: 0xb9, hi: 0xbf}, + // Block 0xf4, offset 0x716 + {value: 0x0000, lo: 0x02}, + {value: 0x0018, lo: 0x80, hi: 0xb3}, + {value: 0x0040, lo: 0xb4, hi: 0xbf}, + // Block 0xf5, offset 0x719 + {value: 0x0000, lo: 0x02}, + {value: 0x0018, lo: 0x80, hi: 0x94}, + {value: 0x0040, lo: 0x95, hi: 0xbf}, + // Block 0xf6, offset 0x71c + {value: 0x0000, lo: 0x03}, + {value: 0x0018, lo: 0x80, hi: 0x8b}, + {value: 0x0040, lo: 0x8c, hi: 0x8f}, + {value: 0x0018, lo: 0x90, hi: 0xbf}, + // Block 0xf7, offset 0x720 + {value: 0x0000, lo: 0x05}, + {value: 0x0018, lo: 0x80, hi: 0x87}, + {value: 0x0040, lo: 0x88, hi: 0x8f}, + {value: 0x0018, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xbf}, + // Block 0xf8, offset 0x726 + {value: 0x0000, lo: 0x04}, + {value: 0x0018, lo: 0x80, hi: 0x87}, + {value: 0x0040, lo: 0x88, hi: 0x8f}, + {value: 0x0018, lo: 0x90, hi: 0xad}, + {value: 0x0040, lo: 0xae, hi: 0xbf}, + // Block 0xf9, offset 0x72b + {value: 0x0000, lo: 0x04}, + {value: 0x0018, lo: 0x80, hi: 0x8b}, + {value: 0x0040, lo: 0x8c, hi: 0x8f}, + {value: 0x0018, lo: 0x90, hi: 0xbe}, + {value: 0x0040, lo: 0xbf, hi: 0xbf}, + // Block 0xfa, offset 0x730 + {value: 0x0000, lo: 0x04}, + {value: 0x0018, lo: 0x80, hi: 0x8c}, + {value: 0x0040, lo: 0x8d, hi: 0x8f}, + {value: 0x0018, lo: 0x90, hi: 0xab}, + {value: 0x0040, lo: 0xac, hi: 0xbf}, + // Block 0xfb, offset 0x735 + {value: 0x0000, lo: 0x02}, + {value: 0x0018, lo: 0x80, hi: 0x97}, + {value: 0x0040, lo: 0x98, hi: 0xbf}, + // Block 0xfc, offset 0x738 + {value: 0x0000, lo: 0x04}, + {value: 0x0018, lo: 0x80, hi: 0x80}, + {value: 0x0040, lo: 0x81, hi: 0x8f}, + {value: 0x0018, lo: 0x90, hi: 0xa6}, + {value: 0x0040, lo: 0xa7, hi: 0xbf}, + // Block 0xfd, offset 0x73d + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0x96}, + {value: 0x0040, lo: 0x97, hi: 0xbf}, + // Block 0xfe, offset 0x740 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xb4}, + {value: 0x0040, lo: 0xb5, hi: 0xbf}, + // Block 0xff, offset 0x743 + {value: 0x0000, lo: 0x03}, + {value: 0x0008, lo: 0x80, hi: 0x9d}, + {value: 0x0040, lo: 0x9e, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xbf}, + // Block 0x100, offset 0x747 + {value: 0x0000, lo: 0x03}, + {value: 0x0008, lo: 0x80, hi: 0xa1}, + {value: 0x0040, lo: 0xa2, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbf}, + // Block 0x101, offset 0x74b + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xa0}, + {value: 0x0040, lo: 0xa1, hi: 0xbf}, + // Block 0x102, offset 0x74e + {value: 0x0020, lo: 0x0f}, + {value: 0xdeb9, lo: 0x80, hi: 0x89}, + {value: 0x8dfd, lo: 0x8a, hi: 0x8a}, + {value: 0xdff9, lo: 0x8b, hi: 0x9c}, + {value: 0x8e1d, lo: 0x9d, hi: 0x9d}, + {value: 0xe239, lo: 0x9e, hi: 0xa2}, + {value: 0x8e3d, lo: 0xa3, hi: 0xa3}, + {value: 0xe2d9, lo: 0xa4, hi: 0xab}, + {value: 0x7ed5, lo: 0xac, hi: 0xac}, + {value: 0xe3d9, lo: 0xad, hi: 0xaf}, + {value: 0x8e5d, lo: 0xb0, hi: 0xb0}, + {value: 0xe439, lo: 0xb1, hi: 0xb6}, + {value: 0x8e7d, lo: 0xb7, hi: 0xb9}, + {value: 0xe4f9, lo: 0xba, hi: 0xba}, + {value: 0x8edd, lo: 0xbb, hi: 0xbb}, + {value: 0xe519, lo: 0xbc, hi: 0xbf}, + // Block 0x103, offset 0x75e + {value: 0x0020, lo: 0x10}, + {value: 0x937d, lo: 0x80, hi: 0x80}, + {value: 0xf099, lo: 0x81, hi: 0x86}, + {value: 0x939d, lo: 0x87, hi: 0x8a}, + {value: 0xd9f9, lo: 0x8b, hi: 0x8b}, + {value: 0xf159, lo: 0x8c, hi: 0x96}, + {value: 0x941d, lo: 0x97, hi: 0x97}, + {value: 0xf2b9, lo: 0x98, hi: 0xa3}, + {value: 0x943d, lo: 0xa4, hi: 0xa6}, + {value: 0xf439, lo: 0xa7, hi: 0xaa}, + {value: 0x949d, lo: 0xab, hi: 0xab}, + {value: 0xf4b9, lo: 0xac, hi: 0xac}, + {value: 0x94bd, lo: 0xad, hi: 0xad}, + {value: 0xf4d9, lo: 0xae, hi: 0xaf}, + {value: 0x94dd, lo: 0xb0, hi: 0xb1}, + {value: 0xf519, lo: 0xb2, hi: 0xbe}, + {value: 0x2040, lo: 0xbf, hi: 0xbf}, + // Block 0x104, offset 0x76f + {value: 0x0000, lo: 0x04}, + {value: 0x0040, lo: 0x80, hi: 0x80}, + {value: 0x0340, lo: 0x81, hi: 0x81}, + {value: 0x0040, lo: 0x82, hi: 0x9f}, + {value: 0x0340, lo: 0xa0, hi: 0xbf}, + // Block 0x105, offset 0x774 + {value: 0x0000, lo: 0x01}, + {value: 0x0340, lo: 0x80, hi: 0xbf}, + // Block 0x106, offset 0x776 + {value: 0x0000, lo: 0x01}, + {value: 0x33c0, lo: 0x80, hi: 0xbf}, + // Block 0x107, offset 0x778 + {value: 0x0000, lo: 0x02}, + {value: 0x33c0, lo: 0x80, hi: 0xaf}, + {value: 0x0040, lo: 0xb0, hi: 0xbf}, +} + +// Total table size 42115 bytes (41KiB); checksum: F4A1FA4E diff --git a/vendor/golang.org/x/net/idna/trie.go b/vendor/golang.org/x/net/idna/trie.go new file mode 100644 index 0000000000..c4ef847e7a --- /dev/null +++ b/vendor/golang.org/x/net/idna/trie.go @@ -0,0 +1,72 @@ +// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. + +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package idna + +// appendMapping appends the mapping for the respective rune. isMapped must be +// true. A mapping is a categorization of a rune as defined in UTS #46. +func (c info) appendMapping(b []byte, s string) []byte { + index := int(c >> indexShift) + if c&xorBit == 0 { + s := mappings[index:] + return append(b, s[1:s[0]+1]...) + } + b = append(b, s...) + if c&inlineXOR == inlineXOR { + // TODO: support and handle two-byte inline masks + b[len(b)-1] ^= byte(index) + } else { + for p := len(b) - int(xorData[index]); p < len(b); p++ { + index++ + b[p] ^= xorData[index] + } + } + return b +} + +// Sparse block handling code. + +type valueRange struct { + value uint16 // header: value:stride + lo, hi byte // header: lo:n +} + +type sparseBlocks struct { + values []valueRange + offset []uint16 +} + +var idnaSparse = sparseBlocks{ + values: idnaSparseValues[:], + offset: idnaSparseOffset[:], +} + +// Don't use newIdnaTrie to avoid unconditional linking in of the table. +var trie = &idnaTrie{} + +// lookup determines the type of block n and looks up the value for b. +// For n < t.cutoff, the block is a simple lookup table. Otherwise, the block +// is a list of ranges with an accompanying value. Given a matching range r, +// the value for b is by r.value + (b - r.lo) * stride. +func (t *sparseBlocks) lookup(n uint32, b byte) uint16 { + offset := t.offset[n] + header := t.values[offset] + lo := offset + 1 + hi := lo + uint16(header.lo) + for lo < hi { + m := lo + (hi-lo)/2 + r := t.values[m] + if r.lo <= b && b <= r.hi { + return r.value + uint16(b-r.lo)*header.value + } + if b < r.lo { + hi = m + } else { + lo = m + 1 + } + } + return 0 +} diff --git a/vendor/golang.org/x/net/idna/trieval.go b/vendor/golang.org/x/net/idna/trieval.go new file mode 100644 index 0000000000..7a8cf889b5 --- /dev/null +++ b/vendor/golang.org/x/net/idna/trieval.go @@ -0,0 +1,119 @@ +// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. + +package idna + +// This file contains definitions for interpreting the trie value of the idna +// trie generated by "go run gen*.go". It is shared by both the generator +// program and the resultant package. Sharing is achieved by the generator +// copying gen_trieval.go to trieval.go and changing what's above this comment. + +// info holds information from the IDNA mapping table for a single rune. It is +// the value returned by a trie lookup. In most cases, all information fits in +// a 16-bit value. For mappings, this value may contain an index into a slice +// with the mapped string. Such mappings can consist of the actual mapped value +// or an XOR pattern to be applied to the bytes of the UTF8 encoding of the +// input rune. This technique is used by the cases packages and reduces the +// table size significantly. +// +// The per-rune values have the following format: +// +// if mapped { +// if inlinedXOR { +// 15..13 inline XOR marker +// 12..11 unused +// 10..3 inline XOR mask +// } else { +// 15..3 index into xor or mapping table +// } +// } else { +// 15..14 unused +// 13 mayNeedNorm +// 12..11 attributes +// 10..8 joining type +// 7..3 category type +// } +// 2 use xor pattern +// 1..0 mapped category +// +// See the definitions below for a more detailed description of the various +// bits. +type info uint16 + +const ( + catSmallMask = 0x3 + catBigMask = 0xF8 + indexShift = 3 + xorBit = 0x4 // interpret the index as an xor pattern + inlineXOR = 0xE000 // These bits are set if the XOR pattern is inlined. + + joinShift = 8 + joinMask = 0x07 + + // Attributes + attributesMask = 0x1800 + viramaModifier = 0x1800 + modifier = 0x1000 + rtl = 0x0800 + + mayNeedNorm = 0x2000 +) + +// A category corresponds to a category defined in the IDNA mapping table. +type category uint16 + +const ( + unknown category = 0 // not currently defined in unicode. + mapped category = 1 + disallowedSTD3Mapped category = 2 + deviation category = 3 +) + +const ( + valid category = 0x08 + validNV8 category = 0x18 + validXV8 category = 0x28 + disallowed category = 0x40 + disallowedSTD3Valid category = 0x80 + ignored category = 0xC0 +) + +// join types and additional rune information +const ( + joiningL = (iota + 1) + joiningD + joiningT + joiningR + + //the following types are derived during processing + joinZWJ + joinZWNJ + joinVirama + numJoinTypes +) + +func (c info) isMapped() bool { + return c&0x3 != 0 +} + +func (c info) category() category { + small := c & catSmallMask + if small != 0 { + return category(small) + } + return category(c & catBigMask) +} + +func (c info) joinType() info { + if c.isMapped() { + return 0 + } + return (c >> joinShift) & joinMask +} + +func (c info) isModifier() bool { + return c&(modifier|catSmallMask) == modifier +} + +func (c info) isViramaModifier() bool { + return c&(attributesMask|catSmallMask) == viramaModifier +} diff --git a/vendor/golang.org/x/text/secure/bidirule/bidirule.go b/vendor/golang.org/x/text/secure/bidirule/bidirule.go new file mode 100644 index 0000000000..e2b70f76c2 --- /dev/null +++ b/vendor/golang.org/x/text/secure/bidirule/bidirule.go @@ -0,0 +1,336 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package bidirule implements the Bidi Rule defined by RFC 5893. +// +// This package is under development. The API may change without notice and +// without preserving backward compatibility. +package bidirule + +import ( + "errors" + "unicode/utf8" + + "golang.org/x/text/transform" + "golang.org/x/text/unicode/bidi" +) + +// This file contains an implementation of RFC 5893: Right-to-Left Scripts for +// Internationalized Domain Names for Applications (IDNA) +// +// A label is an individual component of a domain name. Labels are usually +// shown separated by dots; for example, the domain name "www.example.com" is +// composed of three labels: "www", "example", and "com". +// +// An RTL label is a label that contains at least one character of class R, AL, +// or AN. An LTR label is any label that is not an RTL label. +// +// A "Bidi domain name" is a domain name that contains at least one RTL label. +// +// The following guarantees can be made based on the above: +// +// o In a domain name consisting of only labels that satisfy the rule, +// the requirements of Section 3 are satisfied. Note that even LTR +// labels and pure ASCII labels have to be tested. +// +// o In a domain name consisting of only LDH labels (as defined in the +// Definitions document [RFC5890]) and labels that satisfy the rule, +// the requirements of Section 3 are satisfied as long as a label +// that starts with an ASCII digit does not come after a +// right-to-left label. +// +// No guarantee is given for other combinations. + +// ErrInvalid indicates a label is invalid according to the Bidi Rule. +var ErrInvalid = errors.New("bidirule: failed Bidi Rule") + +type ruleState uint8 + +const ( + ruleInitial ruleState = iota + ruleLTR + ruleLTRFinal + ruleRTL + ruleRTLFinal + ruleInvalid +) + +type ruleTransition struct { + next ruleState + mask uint16 +} + +var transitions = [...][2]ruleTransition{ + // [2.1] The first character must be a character with Bidi property L, R, or + // AL. If it has the R or AL property, it is an RTL label; if it has the L + // property, it is an LTR label. + ruleInitial: { + {ruleLTRFinal, 1 << bidi.L}, + {ruleRTLFinal, 1< 0; count-- { + p.openers.Remove(p.openers.Front()) + } + break + } + } + sort.Sort(p.pairPositions) + // if we get here, the closing bracket matched no openers + // and gets ignored + } + } +} + +// Bracket pairs within an isolating run sequence are processed as units so +// that both the opening and the closing paired bracket in a pair resolve to +// the same direction. +// +// N0. Process bracket pairs in an isolating run sequence sequentially in +// the logical order of the text positions of the opening paired brackets +// using the logic given below. Within this scope, bidirectional types EN +// and AN are treated as R. +// +// Identify the bracket pairs in the current isolating run sequence +// according to BD16. For each bracket-pair element in the list of pairs of +// text positions: +// +// a Inspect the bidirectional types of the characters enclosed within the +// bracket pair. +// +// b If any strong type (either L or R) matching the embedding direction is +// found, set the type for both brackets in the pair to match the embedding +// direction. +// +// o [ e ] o -> o e e e o +// +// o [ o e ] -> o e o e e +// +// o [ NI e ] -> o e NI e e +// +// c Otherwise, if a strong type (opposite the embedding direction) is +// found, test for adjacent strong types as follows: 1 First, check +// backwards before the opening paired bracket until the first strong type +// (L, R, or sos) is found. If that first preceding strong type is opposite +// the embedding direction, then set the type for both brackets in the pair +// to that type. 2 Otherwise, set the type for both brackets in the pair to +// the embedding direction. +// +// o [ o ] e -> o o o o e +// +// o [ o NI ] o -> o o o NI o o +// +// e [ o ] o -> e e o e o +// +// e [ o ] e -> e e o e e +// +// e ( o [ o ] NI ) e -> e e o o o o NI e e +// +// d Otherwise, do not set the type for the current bracket pair. Note that +// if the enclosed text contains no strong types the paired brackets will +// both resolve to the same level when resolved individually using rules N1 +// and N2. +// +// e ( NI ) o -> e ( NI ) o + +// getStrongTypeN0 maps character's directional code to strong type as required +// by rule N0. +// +// TODO: have separate type for "strong" directionality. +func (p *bracketPairer) getStrongTypeN0(index int) Class { + switch p.codesIsolatedRun[index] { + // in the scope of N0, number types are treated as R + case EN, AN, AL, R: + return R + case L: + return L + default: + return ON + } +} + +// classifyPairContent reports the strong types contained inside a Bracket Pair, +// assuming the given embedding direction. +// +// It returns ON if no strong type is found. If a single strong type is found, +// it returns this this type. Otherwise it returns the embedding direction. +// +// TODO: use separate type for "strong" directionality. +func (p *bracketPairer) classifyPairContent(loc bracketPair, dirEmbed Class) Class { + dirOpposite := ON + for i := loc.opener + 1; i < loc.closer; i++ { + dir := p.getStrongTypeN0(i) + if dir == ON { + continue + } + if dir == dirEmbed { + return dir // type matching embedding direction found + } + dirOpposite = dir + } + // return ON if no strong type found, or class opposite to dirEmbed + return dirOpposite +} + +// classBeforePair determines which strong types are present before a Bracket +// Pair. Return R or L if strong type found, otherwise ON. +func (p *bracketPairer) classBeforePair(loc bracketPair) Class { + for i := loc.opener - 1; i >= 0; i-- { + if dir := p.getStrongTypeN0(i); dir != ON { + return dir + } + } + // no strong types found, return sos + return p.sos +} + +// assignBracketType implements rule N0 for a single bracket pair. +func (p *bracketPairer) assignBracketType(loc bracketPair, dirEmbed Class, initialTypes []Class) { + // rule "N0, a", inspect contents of pair + dirPair := p.classifyPairContent(loc, dirEmbed) + + // dirPair is now L, R, or N (no strong type found) + + // the following logical tests are performed out of order compared to + // the statement of the rules but yield the same results + if dirPair == ON { + return // case "d" - nothing to do + } + + if dirPair != dirEmbed { + // case "c": strong type found, opposite - check before (c.1) + dirPair = p.classBeforePair(loc) + if dirPair == dirEmbed || dirPair == ON { + // no strong opposite type found before - use embedding (c.2) + dirPair = dirEmbed + } + } + // else: case "b", strong type found matching embedding, + // no explicit action needed, as dirPair is already set to embedding + // direction + + // set the bracket types to the type found + p.setBracketsToType(loc, dirPair, initialTypes) +} + +func (p *bracketPairer) setBracketsToType(loc bracketPair, dirPair Class, initialTypes []Class) { + p.codesIsolatedRun[loc.opener] = dirPair + p.codesIsolatedRun[loc.closer] = dirPair + + for i := loc.opener + 1; i < loc.closer; i++ { + index := p.indexes[i] + if initialTypes[index] != NSM { + break + } + p.codesIsolatedRun[i] = dirPair + } + + for i := loc.closer + 1; i < len(p.indexes); i++ { + index := p.indexes[i] + if initialTypes[index] != NSM { + break + } + p.codesIsolatedRun[i] = dirPair + } +} + +// resolveBrackets implements rule N0 for a list of pairs. +func (p *bracketPairer) resolveBrackets(dirEmbed Class, initialTypes []Class) { + for _, loc := range p.pairPositions { + p.assignBracketType(loc, dirEmbed, initialTypes) + } +} diff --git a/vendor/golang.org/x/text/unicode/bidi/core.go b/vendor/golang.org/x/text/unicode/bidi/core.go new file mode 100644 index 0000000000..d4c1399f0d --- /dev/null +++ b/vendor/golang.org/x/text/unicode/bidi/core.go @@ -0,0 +1,1058 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package bidi + +import "log" + +// This implementation is a port based on the reference implementation found at: +// http://www.unicode.org/Public/PROGRAMS/BidiReferenceJava/ +// +// described in Unicode Bidirectional Algorithm (UAX #9). +// +// Input: +// There are two levels of input to the algorithm, since clients may prefer to +// supply some information from out-of-band sources rather than relying on the +// default behavior. +// +// - Bidi class array +// - Bidi class array, with externally supplied base line direction +// +// Output: +// Output is separated into several stages: +// +// - levels array over entire paragraph +// - reordering array over entire paragraph +// - levels array over line +// - reordering array over line +// +// Note that for conformance to the Unicode Bidirectional Algorithm, +// implementations are only required to generate correct reordering and +// character directionality (odd or even levels) over a line. Generating +// identical level arrays over a line is not required. Bidi explicit format +// codes (LRE, RLE, LRO, RLO, PDF) and BN can be assigned arbitrary levels and +// positions as long as the rest of the input is properly reordered. +// +// As the algorithm is defined to operate on a single paragraph at a time, this +// implementation is written to handle single paragraphs. Thus rule P1 is +// presumed by this implementation-- the data provided to the implementation is +// assumed to be a single paragraph, and either contains no 'B' codes, or a +// single 'B' code at the end of the input. 'B' is allowed as input to +// illustrate how the algorithm assigns it a level. +// +// Also note that rules L3 and L4 depend on the rendering engine that uses the +// result of the bidi algorithm. This implementation assumes that the rendering +// engine expects combining marks in visual order (e.g. to the left of their +// base character in RTL runs) and that it adjusts the glyphs used to render +// mirrored characters that are in RTL runs so that they render appropriately. + +// level is the embedding level of a character. Even embedding levels indicate +// left-to-right order and odd levels indicate right-to-left order. The special +// level of -1 is reserved for undefined order. +type level int8 + +const implicitLevel level = -1 + +// in returns if x is equal to any of the values in set. +func (c Class) in(set ...Class) bool { + for _, s := range set { + if c == s { + return true + } + } + return false +} + +// A paragraph contains the state of a paragraph. +type paragraph struct { + initialTypes []Class + + // Arrays of properties needed for paired bracket evaluation in N0 + pairTypes []bracketType // paired Bracket types for paragraph + pairValues []rune // rune for opening bracket or pbOpen and pbClose; 0 for pbNone + + embeddingLevel level // default: = implicitLevel; + + // at the paragraph levels + resultTypes []Class + resultLevels []level + + // Index of matching PDI for isolate initiator characters. For other + // characters, the value of matchingPDI will be set to -1. For isolate + // initiators with no matching PDI, matchingPDI will be set to the length of + // the input string. + matchingPDI []int + + // Index of matching isolate initiator for PDI characters. For other + // characters, and for PDIs with no matching isolate initiator, the value of + // matchingIsolateInitiator will be set to -1. + matchingIsolateInitiator []int +} + +// newParagraph initializes a paragraph. The user needs to supply a few arrays +// corresponding to the preprocessed text input. The types correspond to the +// Unicode BiDi classes for each rune. pairTypes indicates the bracket type for +// each rune. pairValues provides a unique bracket class identifier for each +// rune (suggested is the rune of the open bracket for opening and matching +// close brackets, after normalization). The embedding levels are optional, but +// may be supplied to encode embedding levels of styled text. +// +// TODO: return an error. +func newParagraph(types []Class, pairTypes []bracketType, pairValues []rune, levels level) *paragraph { + validateTypes(types) + validatePbTypes(pairTypes) + validatePbValues(pairValues, pairTypes) + validateParagraphEmbeddingLevel(levels) + + p := ¶graph{ + initialTypes: append([]Class(nil), types...), + embeddingLevel: levels, + + pairTypes: pairTypes, + pairValues: pairValues, + + resultTypes: append([]Class(nil), types...), + } + p.run() + return p +} + +func (p *paragraph) Len() int { return len(p.initialTypes) } + +// The algorithm. Does not include line-based processing (Rules L1, L2). +// These are applied later in the line-based phase of the algorithm. +func (p *paragraph) run() { + p.determineMatchingIsolates() + + // 1) determining the paragraph level + // Rule P1 is the requirement for entering this algorithm. + // Rules P2, P3. + // If no externally supplied paragraph embedding level, use default. + if p.embeddingLevel == implicitLevel { + p.embeddingLevel = p.determineParagraphEmbeddingLevel(0, p.Len()) + } + + // Initialize result levels to paragraph embedding level. + p.resultLevels = make([]level, p.Len()) + setLevels(p.resultLevels, p.embeddingLevel) + + // 2) Explicit levels and directions + // Rules X1-X8. + p.determineExplicitEmbeddingLevels() + + // Rule X9. + // We do not remove the embeddings, the overrides, the PDFs, and the BNs + // from the string explicitly. But they are not copied into isolating run + // sequences when they are created, so they are removed for all + // practical purposes. + + // Rule X10. + // Run remainder of algorithm one isolating run sequence at a time + for _, seq := range p.determineIsolatingRunSequences() { + // 3) resolving weak types + // Rules W1-W7. + seq.resolveWeakTypes() + + // 4a) resolving paired brackets + // Rule N0 + resolvePairedBrackets(seq) + + // 4b) resolving neutral types + // Rules N1-N3. + seq.resolveNeutralTypes() + + // 5) resolving implicit embedding levels + // Rules I1, I2. + seq.resolveImplicitLevels() + + // Apply the computed levels and types + seq.applyLevelsAndTypes() + } + + // Assign appropriate levels to 'hide' LREs, RLEs, LROs, RLOs, PDFs, and + // BNs. This is for convenience, so the resulting level array will have + // a value for every character. + p.assignLevelsToCharactersRemovedByX9() +} + +// determineMatchingIsolates determines the matching PDI for each isolate +// initiator and vice versa. +// +// Definition BD9. +// +// At the end of this function: +// +// - The member variable matchingPDI is set to point to the index of the +// matching PDI character for each isolate initiator character. If there is +// no matching PDI, it is set to the length of the input text. For other +// characters, it is set to -1. +// - The member variable matchingIsolateInitiator is set to point to the +// index of the matching isolate initiator character for each PDI character. +// If there is no matching isolate initiator, or the character is not a PDI, +// it is set to -1. +func (p *paragraph) determineMatchingIsolates() { + p.matchingPDI = make([]int, p.Len()) + p.matchingIsolateInitiator = make([]int, p.Len()) + + for i := range p.matchingIsolateInitiator { + p.matchingIsolateInitiator[i] = -1 + } + + for i := range p.matchingPDI { + p.matchingPDI[i] = -1 + + if t := p.resultTypes[i]; t.in(LRI, RLI, FSI) { + depthCounter := 1 + for j := i + 1; j < p.Len(); j++ { + if u := p.resultTypes[j]; u.in(LRI, RLI, FSI) { + depthCounter++ + } else if u == PDI { + if depthCounter--; depthCounter == 0 { + p.matchingPDI[i] = j + p.matchingIsolateInitiator[j] = i + break + } + } + } + if p.matchingPDI[i] == -1 { + p.matchingPDI[i] = p.Len() + } + } + } +} + +// determineParagraphEmbeddingLevel reports the resolved paragraph direction of +// the substring limited by the given range [start, end). +// +// Determines the paragraph level based on rules P2, P3. This is also used +// in rule X5c to find if an FSI should resolve to LRI or RLI. +func (p *paragraph) determineParagraphEmbeddingLevel(start, end int) level { + var strongType Class = unknownClass + + // Rule P2. + for i := start; i < end; i++ { + if t := p.resultTypes[i]; t.in(L, AL, R) { + strongType = t + break + } else if t.in(FSI, LRI, RLI) { + i = p.matchingPDI[i] // skip over to the matching PDI + if i > end { + log.Panic("assert (i <= end)") + } + } + } + // Rule P3. + switch strongType { + case unknownClass: // none found + // default embedding level when no strong types found is 0. + return 0 + case L: + return 0 + default: // AL, R + return 1 + } +} + +const maxDepth = 125 + +// This stack will store the embedding levels and override and isolated +// statuses +type directionalStatusStack struct { + stackCounter int + embeddingLevelStack [maxDepth + 1]level + overrideStatusStack [maxDepth + 1]Class + isolateStatusStack [maxDepth + 1]bool +} + +func (s *directionalStatusStack) empty() { s.stackCounter = 0 } +func (s *directionalStatusStack) pop() { s.stackCounter-- } +func (s *directionalStatusStack) depth() int { return s.stackCounter } + +func (s *directionalStatusStack) push(level level, overrideStatus Class, isolateStatus bool) { + s.embeddingLevelStack[s.stackCounter] = level + s.overrideStatusStack[s.stackCounter] = overrideStatus + s.isolateStatusStack[s.stackCounter] = isolateStatus + s.stackCounter++ +} + +func (s *directionalStatusStack) lastEmbeddingLevel() level { + return s.embeddingLevelStack[s.stackCounter-1] +} + +func (s *directionalStatusStack) lastDirectionalOverrideStatus() Class { + return s.overrideStatusStack[s.stackCounter-1] +} + +func (s *directionalStatusStack) lastDirectionalIsolateStatus() bool { + return s.isolateStatusStack[s.stackCounter-1] +} + +// Determine explicit levels using rules X1 - X8 +func (p *paragraph) determineExplicitEmbeddingLevels() { + var stack directionalStatusStack + var overflowIsolateCount, overflowEmbeddingCount, validIsolateCount int + + // Rule X1. + stack.push(p.embeddingLevel, ON, false) + + for i, t := range p.resultTypes { + // Rules X2, X3, X4, X5, X5a, X5b, X5c + switch t { + case RLE, LRE, RLO, LRO, RLI, LRI, FSI: + isIsolate := t.in(RLI, LRI, FSI) + isRTL := t.in(RLE, RLO, RLI) + + // override if this is an FSI that resolves to RLI + if t == FSI { + isRTL = (p.determineParagraphEmbeddingLevel(i+1, p.matchingPDI[i]) == 1) + } + if isIsolate { + p.resultLevels[i] = stack.lastEmbeddingLevel() + if stack.lastDirectionalOverrideStatus() != ON { + p.resultTypes[i] = stack.lastDirectionalOverrideStatus() + } + } + + var newLevel level + if isRTL { + // least greater odd + newLevel = (stack.lastEmbeddingLevel() + 1) | 1 + } else { + // least greater even + newLevel = (stack.lastEmbeddingLevel() + 2) &^ 1 + } + + if newLevel <= maxDepth && overflowIsolateCount == 0 && overflowEmbeddingCount == 0 { + if isIsolate { + validIsolateCount++ + } + // Push new embedding level, override status, and isolated + // status. + // No check for valid stack counter, since the level check + // suffices. + switch t { + case LRO: + stack.push(newLevel, L, isIsolate) + case RLO: + stack.push(newLevel, R, isIsolate) + default: + stack.push(newLevel, ON, isIsolate) + } + // Not really part of the spec + if !isIsolate { + p.resultLevels[i] = newLevel + } + } else { + // This is an invalid explicit formatting character, + // so apply the "Otherwise" part of rules X2-X5b. + if isIsolate { + overflowIsolateCount++ + } else { // !isIsolate + if overflowIsolateCount == 0 { + overflowEmbeddingCount++ + } + } + } + + // Rule X6a + case PDI: + if overflowIsolateCount > 0 { + overflowIsolateCount-- + } else if validIsolateCount == 0 { + // do nothing + } else { + overflowEmbeddingCount = 0 + for !stack.lastDirectionalIsolateStatus() { + stack.pop() + } + stack.pop() + validIsolateCount-- + } + p.resultLevels[i] = stack.lastEmbeddingLevel() + + // Rule X7 + case PDF: + // Not really part of the spec + p.resultLevels[i] = stack.lastEmbeddingLevel() + + if overflowIsolateCount > 0 { + // do nothing + } else if overflowEmbeddingCount > 0 { + overflowEmbeddingCount-- + } else if !stack.lastDirectionalIsolateStatus() && stack.depth() >= 2 { + stack.pop() + } + + case B: // paragraph separator. + // Rule X8. + + // These values are reset for clarity, in this implementation B + // can only occur as the last code in the array. + stack.empty() + overflowIsolateCount = 0 + overflowEmbeddingCount = 0 + validIsolateCount = 0 + p.resultLevels[i] = p.embeddingLevel + + default: + p.resultLevels[i] = stack.lastEmbeddingLevel() + if stack.lastDirectionalOverrideStatus() != ON { + p.resultTypes[i] = stack.lastDirectionalOverrideStatus() + } + } + } +} + +type isolatingRunSequence struct { + p *paragraph + + indexes []int // indexes to the original string + + types []Class // type of each character using the index + resolvedLevels []level // resolved levels after application of rules + level level + sos, eos Class +} + +func (i *isolatingRunSequence) Len() int { return len(i.indexes) } + +func maxLevel(a, b level) level { + if a > b { + return a + } + return b +} + +// Rule X10, second bullet: Determine the start-of-sequence (sos) and end-of-sequence (eos) types, +// either L or R, for each isolating run sequence. +func (p *paragraph) isolatingRunSequence(indexes []int) *isolatingRunSequence { + length := len(indexes) + types := make([]Class, length) + for i, x := range indexes { + types[i] = p.resultTypes[x] + } + + // assign level, sos and eos + prevChar := indexes[0] - 1 + for prevChar >= 0 && isRemovedByX9(p.initialTypes[prevChar]) { + prevChar-- + } + prevLevel := p.embeddingLevel + if prevChar >= 0 { + prevLevel = p.resultLevels[prevChar] + } + + var succLevel level + lastType := types[length-1] + if lastType.in(LRI, RLI, FSI) { + succLevel = p.embeddingLevel + } else { + // the first character after the end of run sequence + limit := indexes[length-1] + 1 + for ; limit < p.Len() && isRemovedByX9(p.initialTypes[limit]); limit++ { + + } + succLevel = p.embeddingLevel + if limit < p.Len() { + succLevel = p.resultLevels[limit] + } + } + level := p.resultLevels[indexes[0]] + return &isolatingRunSequence{ + p: p, + indexes: indexes, + types: types, + level: level, + sos: typeForLevel(maxLevel(prevLevel, level)), + eos: typeForLevel(maxLevel(succLevel, level)), + } +} + +// Resolving weak types Rules W1-W7. +// +// Note that some weak types (EN, AN) remain after this processing is +// complete. +func (s *isolatingRunSequence) resolveWeakTypes() { + + // on entry, only these types remain + s.assertOnly(L, R, AL, EN, ES, ET, AN, CS, B, S, WS, ON, NSM, LRI, RLI, FSI, PDI) + + // Rule W1. + // Changes all NSMs. + preceedingCharacterType := s.sos + for i, t := range s.types { + if t == NSM { + s.types[i] = preceedingCharacterType + } else { + if t.in(LRI, RLI, FSI, PDI) { + preceedingCharacterType = ON + } + preceedingCharacterType = t + } + } + + // Rule W2. + // EN does not change at the start of the run, because sos != AL. + for i, t := range s.types { + if t == EN { + for j := i - 1; j >= 0; j-- { + if t := s.types[j]; t.in(L, R, AL) { + if t == AL { + s.types[i] = AN + } + break + } + } + } + } + + // Rule W3. + for i, t := range s.types { + if t == AL { + s.types[i] = R + } + } + + // Rule W4. + // Since there must be values on both sides for this rule to have an + // effect, the scan skips the first and last value. + // + // Although the scan proceeds left to right, and changes the type + // values in a way that would appear to affect the computations + // later in the scan, there is actually no problem. A change in the + // current value can only affect the value to its immediate right, + // and only affect it if it is ES or CS. But the current value can + // only change if the value to its right is not ES or CS. Thus + // either the current value will not change, or its change will have + // no effect on the remainder of the analysis. + + for i := 1; i < s.Len()-1; i++ { + t := s.types[i] + if t == ES || t == CS { + prevSepType := s.types[i-1] + succSepType := s.types[i+1] + if prevSepType == EN && succSepType == EN { + s.types[i] = EN + } else if s.types[i] == CS && prevSepType == AN && succSepType == AN { + s.types[i] = AN + } + } + } + + // Rule W5. + for i, t := range s.types { + if t == ET { + // locate end of sequence + runStart := i + runEnd := s.findRunLimit(runStart, ET) + + // check values at ends of sequence + t := s.sos + if runStart > 0 { + t = s.types[runStart-1] + } + if t != EN { + t = s.eos + if runEnd < len(s.types) { + t = s.types[runEnd] + } + } + if t == EN { + setTypes(s.types[runStart:runEnd], EN) + } + // continue at end of sequence + i = runEnd + } + } + + // Rule W6. + for i, t := range s.types { + if t.in(ES, ET, CS) { + s.types[i] = ON + } + } + + // Rule W7. + for i, t := range s.types { + if t == EN { + // set default if we reach start of run + prevStrongType := s.sos + for j := i - 1; j >= 0; j-- { + t = s.types[j] + if t == L || t == R { // AL's have been changed to R + prevStrongType = t + break + } + } + if prevStrongType == L { + s.types[i] = L + } + } + } +} + +// 6) resolving neutral types Rules N1-N2. +func (s *isolatingRunSequence) resolveNeutralTypes() { + + // on entry, only these types can be in resultTypes + s.assertOnly(L, R, EN, AN, B, S, WS, ON, RLI, LRI, FSI, PDI) + + for i, t := range s.types { + switch t { + case WS, ON, B, S, RLI, LRI, FSI, PDI: + // find bounds of run of neutrals + runStart := i + runEnd := s.findRunLimit(runStart, B, S, WS, ON, RLI, LRI, FSI, PDI) + + // determine effective types at ends of run + var leadType, trailType Class + + // Note that the character found can only be L, R, AN, or + // EN. + if runStart == 0 { + leadType = s.sos + } else { + leadType = s.types[runStart-1] + if leadType.in(AN, EN) { + leadType = R + } + } + if runEnd == len(s.types) { + trailType = s.eos + } else { + trailType = s.types[runEnd] + if trailType.in(AN, EN) { + trailType = R + } + } + + var resolvedType Class + if leadType == trailType { + // Rule N1. + resolvedType = leadType + } else { + // Rule N2. + // Notice the embedding level of the run is used, not + // the paragraph embedding level. + resolvedType = typeForLevel(s.level) + } + + setTypes(s.types[runStart:runEnd], resolvedType) + + // skip over run of (former) neutrals + i = runEnd + } + } +} + +func setLevels(levels []level, newLevel level) { + for i := range levels { + levels[i] = newLevel + } +} + +func setTypes(types []Class, newType Class) { + for i := range types { + types[i] = newType + } +} + +// 7) resolving implicit embedding levels Rules I1, I2. +func (s *isolatingRunSequence) resolveImplicitLevels() { + + // on entry, only these types can be in resultTypes + s.assertOnly(L, R, EN, AN) + + s.resolvedLevels = make([]level, len(s.types)) + setLevels(s.resolvedLevels, s.level) + + if (s.level & 1) == 0 { // even level + for i, t := range s.types { + // Rule I1. + if t == L { + // no change + } else if t == R { + s.resolvedLevels[i] += 1 + } else { // t == AN || t == EN + s.resolvedLevels[i] += 2 + } + } + } else { // odd level + for i, t := range s.types { + // Rule I2. + if t == R { + // no change + } else { // t == L || t == AN || t == EN + s.resolvedLevels[i] += 1 + } + } + } +} + +// Applies the levels and types resolved in rules W1-I2 to the +// resultLevels array. +func (s *isolatingRunSequence) applyLevelsAndTypes() { + for i, x := range s.indexes { + s.p.resultTypes[x] = s.types[i] + s.p.resultLevels[x] = s.resolvedLevels[i] + } +} + +// Return the limit of the run consisting only of the types in validSet +// starting at index. This checks the value at index, and will return +// index if that value is not in validSet. +func (s *isolatingRunSequence) findRunLimit(index int, validSet ...Class) int { +loop: + for ; index < len(s.types); index++ { + t := s.types[index] + for _, valid := range validSet { + if t == valid { + continue loop + } + } + return index // didn't find a match in validSet + } + return len(s.types) +} + +// Algorithm validation. Assert that all values in types are in the +// provided set. +func (s *isolatingRunSequence) assertOnly(codes ...Class) { +loop: + for i, t := range s.types { + for _, c := range codes { + if t == c { + continue loop + } + } + log.Panicf("invalid bidi code %v present in assertOnly at position %d", t, s.indexes[i]) + } +} + +// determineLevelRuns returns an array of level runs. Each level run is +// described as an array of indexes into the input string. +// +// Determines the level runs. Rule X9 will be applied in determining the +// runs, in the way that makes sure the characters that are supposed to be +// removed are not included in the runs. +func (p *paragraph) determineLevelRuns() [][]int { + run := []int{} + allRuns := [][]int{} + currentLevel := implicitLevel + + for i := range p.initialTypes { + if !isRemovedByX9(p.initialTypes[i]) { + if p.resultLevels[i] != currentLevel { + // we just encountered a new run; wrap up last run + if currentLevel >= 0 { // only wrap it up if there was a run + allRuns = append(allRuns, run) + run = nil + } + // Start new run + currentLevel = p.resultLevels[i] + } + run = append(run, i) + } + } + // Wrap up the final run, if any + if len(run) > 0 { + allRuns = append(allRuns, run) + } + return allRuns +} + +// Definition BD13. Determine isolating run sequences. +func (p *paragraph) determineIsolatingRunSequences() []*isolatingRunSequence { + levelRuns := p.determineLevelRuns() + + // Compute the run that each character belongs to + runForCharacter := make([]int, p.Len()) + for i, run := range levelRuns { + for _, index := range run { + runForCharacter[index] = i + } + } + + sequences := []*isolatingRunSequence{} + + var currentRunSequence []int + + for _, run := range levelRuns { + first := run[0] + if p.initialTypes[first] != PDI || p.matchingIsolateInitiator[first] == -1 { + currentRunSequence = nil + // int run = i; + for { + // Copy this level run into currentRunSequence + currentRunSequence = append(currentRunSequence, run...) + + last := currentRunSequence[len(currentRunSequence)-1] + lastT := p.initialTypes[last] + if lastT.in(LRI, RLI, FSI) && p.matchingPDI[last] != p.Len() { + run = levelRuns[runForCharacter[p.matchingPDI[last]]] + } else { + break + } + } + sequences = append(sequences, p.isolatingRunSequence(currentRunSequence)) + } + } + return sequences +} + +// Assign level information to characters removed by rule X9. This is for +// ease of relating the level information to the original input data. Note +// that the levels assigned to these codes are arbitrary, they're chosen so +// as to avoid breaking level runs. +func (p *paragraph) assignLevelsToCharactersRemovedByX9() { + for i, t := range p.initialTypes { + if t.in(LRE, RLE, LRO, RLO, PDF, BN) { + p.resultTypes[i] = t + p.resultLevels[i] = -1 + } + } + // now propagate forward the levels information (could have + // propagated backward, the main thing is not to introduce a level + // break where one doesn't already exist). + + if p.resultLevels[0] == -1 { + p.resultLevels[0] = p.embeddingLevel + } + for i := 1; i < len(p.initialTypes); i++ { + if p.resultLevels[i] == -1 { + p.resultLevels[i] = p.resultLevels[i-1] + } + } + // Embedding information is for informational purposes only so need not be + // adjusted. +} + +// +// Output +// + +// getLevels computes levels array breaking lines at offsets in linebreaks. +// Rule L1. +// +// The linebreaks array must include at least one value. The values must be +// in strictly increasing order (no duplicates) between 1 and the length of +// the text, inclusive. The last value must be the length of the text. +func (p *paragraph) getLevels(linebreaks []int) []level { + // Note that since the previous processing has removed all + // P, S, and WS values from resultTypes, the values referred to + // in these rules are the initial types, before any processing + // has been applied (including processing of overrides). + // + // This example implementation has reinserted explicit format codes + // and BN, in order that the levels array correspond to the + // initial text. Their final placement is not normative. + // These codes are treated like WS in this implementation, + // so they don't interrupt sequences of WS. + + validateLineBreaks(linebreaks, p.Len()) + + result := append([]level(nil), p.resultLevels...) + + // don't worry about linebreaks since if there is a break within + // a series of WS values preceding S, the linebreak itself + // causes the reset. + for i, t := range p.initialTypes { + if t.in(B, S) { + // Rule L1, clauses one and two. + result[i] = p.embeddingLevel + + // Rule L1, clause three. + for j := i - 1; j >= 0; j-- { + if isWhitespace(p.initialTypes[j]) { // including format codes + result[j] = p.embeddingLevel + } else { + break + } + } + } + } + + // Rule L1, clause four. + start := 0 + for _, limit := range linebreaks { + for j := limit - 1; j >= start; j-- { + if isWhitespace(p.initialTypes[j]) { // including format codes + result[j] = p.embeddingLevel + } else { + break + } + } + start = limit + } + + return result +} + +// getReordering returns the reordering of lines from a visual index to a +// logical index for line breaks at the given offsets. +// +// Lines are concatenated from left to right. So for example, the fifth +// character from the left on the third line is +// +// getReordering(linebreaks)[linebreaks[1] + 4] +// +// (linebreaks[1] is the position after the last character of the second +// line, which is also the index of the first character on the third line, +// and adding four gets the fifth character from the left). +// +// The linebreaks array must include at least one value. The values must be +// in strictly increasing order (no duplicates) between 1 and the length of +// the text, inclusive. The last value must be the length of the text. +func (p *paragraph) getReordering(linebreaks []int) []int { + validateLineBreaks(linebreaks, p.Len()) + + return computeMultilineReordering(p.getLevels(linebreaks), linebreaks) +} + +// Return multiline reordering array for a given level array. Reordering +// does not occur across a line break. +func computeMultilineReordering(levels []level, linebreaks []int) []int { + result := make([]int, len(levels)) + + start := 0 + for _, limit := range linebreaks { + tempLevels := make([]level, limit-start) + copy(tempLevels, levels[start:]) + + for j, order := range computeReordering(tempLevels) { + result[start+j] = order + start + } + start = limit + } + return result +} + +// Return reordering array for a given level array. This reorders a single +// line. The reordering is a visual to logical map. For example, the +// leftmost char is string.charAt(order[0]). Rule L2. +func computeReordering(levels []level) []int { + result := make([]int, len(levels)) + // initialize order + for i := range result { + result[i] = i + } + + // locate highest level found on line. + // Note the rules say text, but no reordering across line bounds is + // performed, so this is sufficient. + highestLevel := level(0) + lowestOddLevel := level(maxDepth + 2) + for _, level := range levels { + if level > highestLevel { + highestLevel = level + } + if level&1 != 0 && level < lowestOddLevel { + lowestOddLevel = level + } + } + + for level := highestLevel; level >= lowestOddLevel; level-- { + for i := 0; i < len(levels); i++ { + if levels[i] >= level { + // find range of text at or above this level + start := i + limit := i + 1 + for limit < len(levels) && levels[limit] >= level { + limit++ + } + + for j, k := start, limit-1; j < k; j, k = j+1, k-1 { + result[j], result[k] = result[k], result[j] + } + // skip to end of level run + i = limit + } + } + } + + return result +} + +// isWhitespace reports whether the type is considered a whitespace type for the +// line break rules. +func isWhitespace(c Class) bool { + switch c { + case LRE, RLE, LRO, RLO, PDF, LRI, RLI, FSI, PDI, BN, WS: + return true + } + return false +} + +// isRemovedByX9 reports whether the type is one of the types removed in X9. +func isRemovedByX9(c Class) bool { + switch c { + case LRE, RLE, LRO, RLO, PDF, BN: + return true + } + return false +} + +// typeForLevel reports the strong type (L or R) corresponding to the level. +func typeForLevel(level level) Class { + if (level & 0x1) == 0 { + return L + } + return R +} + +// TODO: change validation to not panic + +func validateTypes(types []Class) { + if len(types) == 0 { + log.Panic("types is null") + } + for i, t := range types[:len(types)-1] { + if t == B { + log.Panicf("B type before end of paragraph at index: %d", i) + } + } +} + +func validateParagraphEmbeddingLevel(embeddingLevel level) { + if embeddingLevel != implicitLevel && + embeddingLevel != 0 && + embeddingLevel != 1 { + log.Panicf("illegal paragraph embedding level: %d", embeddingLevel) + } +} + +func validateLineBreaks(linebreaks []int, textLength int) { + prev := 0 + for i, next := range linebreaks { + if next <= prev { + log.Panicf("bad linebreak: %d at index: %d", next, i) + } + prev = next + } + if prev != textLength { + log.Panicf("last linebreak was %d, want %d", prev, textLength) + } +} + +func validatePbTypes(pairTypes []bracketType) { + if len(pairTypes) == 0 { + log.Panic("pairTypes is null") + } + for i, pt := range pairTypes { + switch pt { + case bpNone, bpOpen, bpClose: + default: + log.Panicf("illegal pairType value at %d: %v", i, pairTypes[i]) + } + } +} + +func validatePbValues(pairValues []rune, pairTypes []bracketType) { + if pairValues == nil { + log.Panic("pairValues is null") + } + if len(pairTypes) != len(pairValues) { + log.Panic("pairTypes is different length from pairValues") + } +} diff --git a/vendor/golang.org/x/text/unicode/bidi/prop.go b/vendor/golang.org/x/text/unicode/bidi/prop.go new file mode 100644 index 0000000000..7c9484e1f5 --- /dev/null +++ b/vendor/golang.org/x/text/unicode/bidi/prop.go @@ -0,0 +1,206 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package bidi + +import "unicode/utf8" + +// Properties provides access to BiDi properties of runes. +type Properties struct { + entry uint8 + last uint8 +} + +var trie = newBidiTrie(0) + +// TODO: using this for bidirule reduces the running time by about 5%. Consider +// if this is worth exposing or if we can find a way to speed up the Class +// method. +// +// // CompactClass is like Class, but maps all of the BiDi control classes +// // (LRO, RLO, LRE, RLE, PDF, LRI, RLI, FSI, PDI) to the class Control. +// func (p Properties) CompactClass() Class { +// return Class(p.entry & 0x0F) +// } + +// Class returns the Bidi class for p. +func (p Properties) Class() Class { + c := Class(p.entry & 0x0F) + if c == Control { + c = controlByteToClass[p.last&0xF] + } + return c +} + +// IsBracket reports whether the rune is a bracket. +func (p Properties) IsBracket() bool { return p.entry&0xF0 != 0 } + +// IsOpeningBracket reports whether the rune is an opening bracket. +// IsBracket must return true. +func (p Properties) IsOpeningBracket() bool { return p.entry&openMask != 0 } + +// TODO: find a better API and expose. +func (p Properties) reverseBracket(r rune) rune { + return xorMasks[p.entry>>xorMaskShift] ^ r +} + +var controlByteToClass = [16]Class{ + 0xD: LRO, // U+202D LeftToRightOverride, + 0xE: RLO, // U+202E RightToLeftOverride, + 0xA: LRE, // U+202A LeftToRightEmbedding, + 0xB: RLE, // U+202B RightToLeftEmbedding, + 0xC: PDF, // U+202C PopDirectionalFormat, + 0x6: LRI, // U+2066 LeftToRightIsolate, + 0x7: RLI, // U+2067 RightToLeftIsolate, + 0x8: FSI, // U+2068 FirstStrongIsolate, + 0x9: PDI, // U+2069 PopDirectionalIsolate, +} + +// LookupRune returns properties for r. +func LookupRune(r rune) (p Properties, size int) { + var buf [4]byte + n := utf8.EncodeRune(buf[:], r) + return Lookup(buf[:n]) +} + +// TODO: these lookup methods are based on the generated trie code. The returned +// sizes have slightly different semantics from the generated code, in that it +// always returns size==1 for an illegal UTF-8 byte (instead of the length +// of the maximum invalid subsequence). Most Transformers, like unicode/norm, +// leave invalid UTF-8 untouched, in which case it has performance benefits to +// do so (without changing the semantics). Bidi requires the semantics used here +// for the bidirule implementation to be compatible with the Go semantics. +// They ultimately should perhaps be adopted by all trie implementations, for +// convenience sake. +// This unrolled code also boosts performance of the secure/bidirule package by +// about 30%. +// So, to remove this code: +// - add option to trie generator to define return type. +// - always return 1 byte size for ill-formed UTF-8 runes. + +// Lookup returns properties for the first rune in s and the width in bytes of +// its encoding. The size will be 0 if s does not hold enough bytes to complete +// the encoding. +func Lookup(s []byte) (p Properties, sz int) { + c0 := s[0] + switch { + case c0 < 0x80: // is ASCII + return Properties{entry: bidiValues[c0]}, 1 + case c0 < 0xC2: + return Properties{}, 1 + case c0 < 0xE0: // 2-byte UTF-8 + if len(s) < 2 { + return Properties{}, 0 + } + i := bidiIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return Properties{}, 1 + } + return Properties{entry: trie.lookupValue(uint32(i), c1)}, 2 + case c0 < 0xF0: // 3-byte UTF-8 + if len(s) < 3 { + return Properties{}, 0 + } + i := bidiIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return Properties{}, 1 + } + o := uint32(i)<<6 + uint32(c1) + i = bidiIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return Properties{}, 1 + } + return Properties{entry: trie.lookupValue(uint32(i), c2), last: c2}, 3 + case c0 < 0xF8: // 4-byte UTF-8 + if len(s) < 4 { + return Properties{}, 0 + } + i := bidiIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return Properties{}, 1 + } + o := uint32(i)<<6 + uint32(c1) + i = bidiIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return Properties{}, 1 + } + o = uint32(i)<<6 + uint32(c2) + i = bidiIndex[o] + c3 := s[3] + if c3 < 0x80 || 0xC0 <= c3 { + return Properties{}, 1 + } + return Properties{entry: trie.lookupValue(uint32(i), c3)}, 4 + } + // Illegal rune + return Properties{}, 1 +} + +// LookupString returns properties for the first rune in s and the width in +// bytes of its encoding. The size will be 0 if s does not hold enough bytes to +// complete the encoding. +func LookupString(s string) (p Properties, sz int) { + c0 := s[0] + switch { + case c0 < 0x80: // is ASCII + return Properties{entry: bidiValues[c0]}, 1 + case c0 < 0xC2: + return Properties{}, 1 + case c0 < 0xE0: // 2-byte UTF-8 + if len(s) < 2 { + return Properties{}, 0 + } + i := bidiIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return Properties{}, 1 + } + return Properties{entry: trie.lookupValue(uint32(i), c1)}, 2 + case c0 < 0xF0: // 3-byte UTF-8 + if len(s) < 3 { + return Properties{}, 0 + } + i := bidiIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return Properties{}, 1 + } + o := uint32(i)<<6 + uint32(c1) + i = bidiIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return Properties{}, 1 + } + return Properties{entry: trie.lookupValue(uint32(i), c2), last: c2}, 3 + case c0 < 0xF8: // 4-byte UTF-8 + if len(s) < 4 { + return Properties{}, 0 + } + i := bidiIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return Properties{}, 1 + } + o := uint32(i)<<6 + uint32(c1) + i = bidiIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return Properties{}, 1 + } + o = uint32(i)<<6 + uint32(c2) + i = bidiIndex[o] + c3 := s[3] + if c3 < 0x80 || 0xC0 <= c3 { + return Properties{}, 1 + } + return Properties{entry: trie.lookupValue(uint32(i), c3)}, 4 + } + // Illegal rune + return Properties{}, 1 +} diff --git a/vendor/golang.org/x/text/unicode/bidi/tables10.0.0.go b/vendor/golang.org/x/text/unicode/bidi/tables10.0.0.go new file mode 100644 index 0000000000..2e1ff19599 --- /dev/null +++ b/vendor/golang.org/x/text/unicode/bidi/tables10.0.0.go @@ -0,0 +1,1815 @@ +// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. + +// +build go1.10 + +package bidi + +// UnicodeVersion is the Unicode version from which the tables in this package are derived. +const UnicodeVersion = "10.0.0" + +// xorMasks contains masks to be xor-ed with brackets to get the reverse +// version. +var xorMasks = []int32{ // 8 elements + 0, 1, 6, 7, 3, 15, 29, 63, +} // Size: 56 bytes + +// lookup returns the trie value for the first UTF-8 encoding in s and +// the width in bytes of this encoding. The size will be 0 if s does not +// hold enough bytes to complete the encoding. len(s) must be greater than 0. +func (t *bidiTrie) lookup(s []byte) (v uint8, sz int) { + c0 := s[0] + switch { + case c0 < 0x80: // is ASCII + return bidiValues[c0], 1 + case c0 < 0xC2: + return 0, 1 // Illegal UTF-8: not a starter, not ASCII. + case c0 < 0xE0: // 2-byte UTF-8 + if len(s) < 2 { + return 0, 0 + } + i := bidiIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c1), 2 + case c0 < 0xF0: // 3-byte UTF-8 + if len(s) < 3 { + return 0, 0 + } + i := bidiIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = bidiIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c2), 3 + case c0 < 0xF8: // 4-byte UTF-8 + if len(s) < 4 { + return 0, 0 + } + i := bidiIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = bidiIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + o = uint32(i)<<6 + uint32(c2) + i = bidiIndex[o] + c3 := s[3] + if c3 < 0x80 || 0xC0 <= c3 { + return 0, 3 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c3), 4 + } + // Illegal rune + return 0, 1 +} + +// lookupUnsafe returns the trie value for the first UTF-8 encoding in s. +// s must start with a full and valid UTF-8 encoded rune. +func (t *bidiTrie) lookupUnsafe(s []byte) uint8 { + c0 := s[0] + if c0 < 0x80 { // is ASCII + return bidiValues[c0] + } + i := bidiIndex[c0] + if c0 < 0xE0 { // 2-byte UTF-8 + return t.lookupValue(uint32(i), s[1]) + } + i = bidiIndex[uint32(i)<<6+uint32(s[1])] + if c0 < 0xF0 { // 3-byte UTF-8 + return t.lookupValue(uint32(i), s[2]) + } + i = bidiIndex[uint32(i)<<6+uint32(s[2])] + if c0 < 0xF8 { // 4-byte UTF-8 + return t.lookupValue(uint32(i), s[3]) + } + return 0 +} + +// lookupString returns the trie value for the first UTF-8 encoding in s and +// the width in bytes of this encoding. The size will be 0 if s does not +// hold enough bytes to complete the encoding. len(s) must be greater than 0. +func (t *bidiTrie) lookupString(s string) (v uint8, sz int) { + c0 := s[0] + switch { + case c0 < 0x80: // is ASCII + return bidiValues[c0], 1 + case c0 < 0xC2: + return 0, 1 // Illegal UTF-8: not a starter, not ASCII. + case c0 < 0xE0: // 2-byte UTF-8 + if len(s) < 2 { + return 0, 0 + } + i := bidiIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c1), 2 + case c0 < 0xF0: // 3-byte UTF-8 + if len(s) < 3 { + return 0, 0 + } + i := bidiIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = bidiIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c2), 3 + case c0 < 0xF8: // 4-byte UTF-8 + if len(s) < 4 { + return 0, 0 + } + i := bidiIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = bidiIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + o = uint32(i)<<6 + uint32(c2) + i = bidiIndex[o] + c3 := s[3] + if c3 < 0x80 || 0xC0 <= c3 { + return 0, 3 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c3), 4 + } + // Illegal rune + return 0, 1 +} + +// lookupStringUnsafe returns the trie value for the first UTF-8 encoding in s. +// s must start with a full and valid UTF-8 encoded rune. +func (t *bidiTrie) lookupStringUnsafe(s string) uint8 { + c0 := s[0] + if c0 < 0x80 { // is ASCII + return bidiValues[c0] + } + i := bidiIndex[c0] + if c0 < 0xE0 { // 2-byte UTF-8 + return t.lookupValue(uint32(i), s[1]) + } + i = bidiIndex[uint32(i)<<6+uint32(s[1])] + if c0 < 0xF0 { // 3-byte UTF-8 + return t.lookupValue(uint32(i), s[2]) + } + i = bidiIndex[uint32(i)<<6+uint32(s[2])] + if c0 < 0xF8 { // 4-byte UTF-8 + return t.lookupValue(uint32(i), s[3]) + } + return 0 +} + +// bidiTrie. Total size: 16128 bytes (15.75 KiB). Checksum: 8122d83e461996f. +type bidiTrie struct{} + +func newBidiTrie(i int) *bidiTrie { + return &bidiTrie{} +} + +// lookupValue determines the type of block n and looks up the value for b. +func (t *bidiTrie) lookupValue(n uint32, b byte) uint8 { + switch { + default: + return uint8(bidiValues[n<<6+uint32(b)]) + } +} + +// bidiValues: 228 blocks, 14592 entries, 14592 bytes +// The third block is the zero block. +var bidiValues = [14592]uint8{ + // Block 0x0, offset 0x0 + 0x00: 0x000b, 0x01: 0x000b, 0x02: 0x000b, 0x03: 0x000b, 0x04: 0x000b, 0x05: 0x000b, + 0x06: 0x000b, 0x07: 0x000b, 0x08: 0x000b, 0x09: 0x0008, 0x0a: 0x0007, 0x0b: 0x0008, + 0x0c: 0x0009, 0x0d: 0x0007, 0x0e: 0x000b, 0x0f: 0x000b, 0x10: 0x000b, 0x11: 0x000b, + 0x12: 0x000b, 0x13: 0x000b, 0x14: 0x000b, 0x15: 0x000b, 0x16: 0x000b, 0x17: 0x000b, + 0x18: 0x000b, 0x19: 0x000b, 0x1a: 0x000b, 0x1b: 0x000b, 0x1c: 0x0007, 0x1d: 0x0007, + 0x1e: 0x0007, 0x1f: 0x0008, 0x20: 0x0009, 0x21: 0x000a, 0x22: 0x000a, 0x23: 0x0004, + 0x24: 0x0004, 0x25: 0x0004, 0x26: 0x000a, 0x27: 0x000a, 0x28: 0x003a, 0x29: 0x002a, + 0x2a: 0x000a, 0x2b: 0x0003, 0x2c: 0x0006, 0x2d: 0x0003, 0x2e: 0x0006, 0x2f: 0x0006, + 0x30: 0x0002, 0x31: 0x0002, 0x32: 0x0002, 0x33: 0x0002, 0x34: 0x0002, 0x35: 0x0002, + 0x36: 0x0002, 0x37: 0x0002, 0x38: 0x0002, 0x39: 0x0002, 0x3a: 0x0006, 0x3b: 0x000a, + 0x3c: 0x000a, 0x3d: 0x000a, 0x3e: 0x000a, 0x3f: 0x000a, + // Block 0x1, offset 0x40 + 0x40: 0x000a, + 0x5b: 0x005a, 0x5c: 0x000a, 0x5d: 0x004a, + 0x5e: 0x000a, 0x5f: 0x000a, 0x60: 0x000a, + 0x7b: 0x005a, + 0x7c: 0x000a, 0x7d: 0x004a, 0x7e: 0x000a, 0x7f: 0x000b, + // Block 0x2, offset 0x80 + // Block 0x3, offset 0xc0 + 0xc0: 0x000b, 0xc1: 0x000b, 0xc2: 0x000b, 0xc3: 0x000b, 0xc4: 0x000b, 0xc5: 0x0007, + 0xc6: 0x000b, 0xc7: 0x000b, 0xc8: 0x000b, 0xc9: 0x000b, 0xca: 0x000b, 0xcb: 0x000b, + 0xcc: 0x000b, 0xcd: 0x000b, 0xce: 0x000b, 0xcf: 0x000b, 0xd0: 0x000b, 0xd1: 0x000b, + 0xd2: 0x000b, 0xd3: 0x000b, 0xd4: 0x000b, 0xd5: 0x000b, 0xd6: 0x000b, 0xd7: 0x000b, + 0xd8: 0x000b, 0xd9: 0x000b, 0xda: 0x000b, 0xdb: 0x000b, 0xdc: 0x000b, 0xdd: 0x000b, + 0xde: 0x000b, 0xdf: 0x000b, 0xe0: 0x0006, 0xe1: 0x000a, 0xe2: 0x0004, 0xe3: 0x0004, + 0xe4: 0x0004, 0xe5: 0x0004, 0xe6: 0x000a, 0xe7: 0x000a, 0xe8: 0x000a, 0xe9: 0x000a, + 0xeb: 0x000a, 0xec: 0x000a, 0xed: 0x000b, 0xee: 0x000a, 0xef: 0x000a, + 0xf0: 0x0004, 0xf1: 0x0004, 0xf2: 0x0002, 0xf3: 0x0002, 0xf4: 0x000a, + 0xf6: 0x000a, 0xf7: 0x000a, 0xf8: 0x000a, 0xf9: 0x0002, 0xfb: 0x000a, + 0xfc: 0x000a, 0xfd: 0x000a, 0xfe: 0x000a, 0xff: 0x000a, + // Block 0x4, offset 0x100 + 0x117: 0x000a, + 0x137: 0x000a, + // Block 0x5, offset 0x140 + 0x179: 0x000a, 0x17a: 0x000a, + // Block 0x6, offset 0x180 + 0x182: 0x000a, 0x183: 0x000a, 0x184: 0x000a, 0x185: 0x000a, + 0x186: 0x000a, 0x187: 0x000a, 0x188: 0x000a, 0x189: 0x000a, 0x18a: 0x000a, 0x18b: 0x000a, + 0x18c: 0x000a, 0x18d: 0x000a, 0x18e: 0x000a, 0x18f: 0x000a, + 0x192: 0x000a, 0x193: 0x000a, 0x194: 0x000a, 0x195: 0x000a, 0x196: 0x000a, 0x197: 0x000a, + 0x198: 0x000a, 0x199: 0x000a, 0x19a: 0x000a, 0x19b: 0x000a, 0x19c: 0x000a, 0x19d: 0x000a, + 0x19e: 0x000a, 0x19f: 0x000a, + 0x1a5: 0x000a, 0x1a6: 0x000a, 0x1a7: 0x000a, 0x1a8: 0x000a, 0x1a9: 0x000a, + 0x1aa: 0x000a, 0x1ab: 0x000a, 0x1ac: 0x000a, 0x1ad: 0x000a, 0x1af: 0x000a, + 0x1b0: 0x000a, 0x1b1: 0x000a, 0x1b2: 0x000a, 0x1b3: 0x000a, 0x1b4: 0x000a, 0x1b5: 0x000a, + 0x1b6: 0x000a, 0x1b7: 0x000a, 0x1b8: 0x000a, 0x1b9: 0x000a, 0x1ba: 0x000a, 0x1bb: 0x000a, + 0x1bc: 0x000a, 0x1bd: 0x000a, 0x1be: 0x000a, 0x1bf: 0x000a, + // Block 0x7, offset 0x1c0 + 0x1c0: 0x000c, 0x1c1: 0x000c, 0x1c2: 0x000c, 0x1c3: 0x000c, 0x1c4: 0x000c, 0x1c5: 0x000c, + 0x1c6: 0x000c, 0x1c7: 0x000c, 0x1c8: 0x000c, 0x1c9: 0x000c, 0x1ca: 0x000c, 0x1cb: 0x000c, + 0x1cc: 0x000c, 0x1cd: 0x000c, 0x1ce: 0x000c, 0x1cf: 0x000c, 0x1d0: 0x000c, 0x1d1: 0x000c, + 0x1d2: 0x000c, 0x1d3: 0x000c, 0x1d4: 0x000c, 0x1d5: 0x000c, 0x1d6: 0x000c, 0x1d7: 0x000c, + 0x1d8: 0x000c, 0x1d9: 0x000c, 0x1da: 0x000c, 0x1db: 0x000c, 0x1dc: 0x000c, 0x1dd: 0x000c, + 0x1de: 0x000c, 0x1df: 0x000c, 0x1e0: 0x000c, 0x1e1: 0x000c, 0x1e2: 0x000c, 0x1e3: 0x000c, + 0x1e4: 0x000c, 0x1e5: 0x000c, 0x1e6: 0x000c, 0x1e7: 0x000c, 0x1e8: 0x000c, 0x1e9: 0x000c, + 0x1ea: 0x000c, 0x1eb: 0x000c, 0x1ec: 0x000c, 0x1ed: 0x000c, 0x1ee: 0x000c, 0x1ef: 0x000c, + 0x1f0: 0x000c, 0x1f1: 0x000c, 0x1f2: 0x000c, 0x1f3: 0x000c, 0x1f4: 0x000c, 0x1f5: 0x000c, + 0x1f6: 0x000c, 0x1f7: 0x000c, 0x1f8: 0x000c, 0x1f9: 0x000c, 0x1fa: 0x000c, 0x1fb: 0x000c, + 0x1fc: 0x000c, 0x1fd: 0x000c, 0x1fe: 0x000c, 0x1ff: 0x000c, + // Block 0x8, offset 0x200 + 0x200: 0x000c, 0x201: 0x000c, 0x202: 0x000c, 0x203: 0x000c, 0x204: 0x000c, 0x205: 0x000c, + 0x206: 0x000c, 0x207: 0x000c, 0x208: 0x000c, 0x209: 0x000c, 0x20a: 0x000c, 0x20b: 0x000c, + 0x20c: 0x000c, 0x20d: 0x000c, 0x20e: 0x000c, 0x20f: 0x000c, 0x210: 0x000c, 0x211: 0x000c, + 0x212: 0x000c, 0x213: 0x000c, 0x214: 0x000c, 0x215: 0x000c, 0x216: 0x000c, 0x217: 0x000c, + 0x218: 0x000c, 0x219: 0x000c, 0x21a: 0x000c, 0x21b: 0x000c, 0x21c: 0x000c, 0x21d: 0x000c, + 0x21e: 0x000c, 0x21f: 0x000c, 0x220: 0x000c, 0x221: 0x000c, 0x222: 0x000c, 0x223: 0x000c, + 0x224: 0x000c, 0x225: 0x000c, 0x226: 0x000c, 0x227: 0x000c, 0x228: 0x000c, 0x229: 0x000c, + 0x22a: 0x000c, 0x22b: 0x000c, 0x22c: 0x000c, 0x22d: 0x000c, 0x22e: 0x000c, 0x22f: 0x000c, + 0x234: 0x000a, 0x235: 0x000a, + 0x23e: 0x000a, + // Block 0x9, offset 0x240 + 0x244: 0x000a, 0x245: 0x000a, + 0x247: 0x000a, + // Block 0xa, offset 0x280 + 0x2b6: 0x000a, + // Block 0xb, offset 0x2c0 + 0x2c3: 0x000c, 0x2c4: 0x000c, 0x2c5: 0x000c, + 0x2c6: 0x000c, 0x2c7: 0x000c, 0x2c8: 0x000c, 0x2c9: 0x000c, + // Block 0xc, offset 0x300 + 0x30a: 0x000a, + 0x30d: 0x000a, 0x30e: 0x000a, 0x30f: 0x0004, 0x310: 0x0001, 0x311: 0x000c, + 0x312: 0x000c, 0x313: 0x000c, 0x314: 0x000c, 0x315: 0x000c, 0x316: 0x000c, 0x317: 0x000c, + 0x318: 0x000c, 0x319: 0x000c, 0x31a: 0x000c, 0x31b: 0x000c, 0x31c: 0x000c, 0x31d: 0x000c, + 0x31e: 0x000c, 0x31f: 0x000c, 0x320: 0x000c, 0x321: 0x000c, 0x322: 0x000c, 0x323: 0x000c, + 0x324: 0x000c, 0x325: 0x000c, 0x326: 0x000c, 0x327: 0x000c, 0x328: 0x000c, 0x329: 0x000c, + 0x32a: 0x000c, 0x32b: 0x000c, 0x32c: 0x000c, 0x32d: 0x000c, 0x32e: 0x000c, 0x32f: 0x000c, + 0x330: 0x000c, 0x331: 0x000c, 0x332: 0x000c, 0x333: 0x000c, 0x334: 0x000c, 0x335: 0x000c, + 0x336: 0x000c, 0x337: 0x000c, 0x338: 0x000c, 0x339: 0x000c, 0x33a: 0x000c, 0x33b: 0x000c, + 0x33c: 0x000c, 0x33d: 0x000c, 0x33e: 0x0001, 0x33f: 0x000c, + // Block 0xd, offset 0x340 + 0x340: 0x0001, 0x341: 0x000c, 0x342: 0x000c, 0x343: 0x0001, 0x344: 0x000c, 0x345: 0x000c, + 0x346: 0x0001, 0x347: 0x000c, 0x348: 0x0001, 0x349: 0x0001, 0x34a: 0x0001, 0x34b: 0x0001, + 0x34c: 0x0001, 0x34d: 0x0001, 0x34e: 0x0001, 0x34f: 0x0001, 0x350: 0x0001, 0x351: 0x0001, + 0x352: 0x0001, 0x353: 0x0001, 0x354: 0x0001, 0x355: 0x0001, 0x356: 0x0001, 0x357: 0x0001, + 0x358: 0x0001, 0x359: 0x0001, 0x35a: 0x0001, 0x35b: 0x0001, 0x35c: 0x0001, 0x35d: 0x0001, + 0x35e: 0x0001, 0x35f: 0x0001, 0x360: 0x0001, 0x361: 0x0001, 0x362: 0x0001, 0x363: 0x0001, + 0x364: 0x0001, 0x365: 0x0001, 0x366: 0x0001, 0x367: 0x0001, 0x368: 0x0001, 0x369: 0x0001, + 0x36a: 0x0001, 0x36b: 0x0001, 0x36c: 0x0001, 0x36d: 0x0001, 0x36e: 0x0001, 0x36f: 0x0001, + 0x370: 0x0001, 0x371: 0x0001, 0x372: 0x0001, 0x373: 0x0001, 0x374: 0x0001, 0x375: 0x0001, + 0x376: 0x0001, 0x377: 0x0001, 0x378: 0x0001, 0x379: 0x0001, 0x37a: 0x0001, 0x37b: 0x0001, + 0x37c: 0x0001, 0x37d: 0x0001, 0x37e: 0x0001, 0x37f: 0x0001, + // Block 0xe, offset 0x380 + 0x380: 0x0005, 0x381: 0x0005, 0x382: 0x0005, 0x383: 0x0005, 0x384: 0x0005, 0x385: 0x0005, + 0x386: 0x000a, 0x387: 0x000a, 0x388: 0x000d, 0x389: 0x0004, 0x38a: 0x0004, 0x38b: 0x000d, + 0x38c: 0x0006, 0x38d: 0x000d, 0x38e: 0x000a, 0x38f: 0x000a, 0x390: 0x000c, 0x391: 0x000c, + 0x392: 0x000c, 0x393: 0x000c, 0x394: 0x000c, 0x395: 0x000c, 0x396: 0x000c, 0x397: 0x000c, + 0x398: 0x000c, 0x399: 0x000c, 0x39a: 0x000c, 0x39b: 0x000d, 0x39c: 0x000d, 0x39d: 0x000d, + 0x39e: 0x000d, 0x39f: 0x000d, 0x3a0: 0x000d, 0x3a1: 0x000d, 0x3a2: 0x000d, 0x3a3: 0x000d, + 0x3a4: 0x000d, 0x3a5: 0x000d, 0x3a6: 0x000d, 0x3a7: 0x000d, 0x3a8: 0x000d, 0x3a9: 0x000d, + 0x3aa: 0x000d, 0x3ab: 0x000d, 0x3ac: 0x000d, 0x3ad: 0x000d, 0x3ae: 0x000d, 0x3af: 0x000d, + 0x3b0: 0x000d, 0x3b1: 0x000d, 0x3b2: 0x000d, 0x3b3: 0x000d, 0x3b4: 0x000d, 0x3b5: 0x000d, + 0x3b6: 0x000d, 0x3b7: 0x000d, 0x3b8: 0x000d, 0x3b9: 0x000d, 0x3ba: 0x000d, 0x3bb: 0x000d, + 0x3bc: 0x000d, 0x3bd: 0x000d, 0x3be: 0x000d, 0x3bf: 0x000d, + // Block 0xf, offset 0x3c0 + 0x3c0: 0x000d, 0x3c1: 0x000d, 0x3c2: 0x000d, 0x3c3: 0x000d, 0x3c4: 0x000d, 0x3c5: 0x000d, + 0x3c6: 0x000d, 0x3c7: 0x000d, 0x3c8: 0x000d, 0x3c9: 0x000d, 0x3ca: 0x000d, 0x3cb: 0x000c, + 0x3cc: 0x000c, 0x3cd: 0x000c, 0x3ce: 0x000c, 0x3cf: 0x000c, 0x3d0: 0x000c, 0x3d1: 0x000c, + 0x3d2: 0x000c, 0x3d3: 0x000c, 0x3d4: 0x000c, 0x3d5: 0x000c, 0x3d6: 0x000c, 0x3d7: 0x000c, + 0x3d8: 0x000c, 0x3d9: 0x000c, 0x3da: 0x000c, 0x3db: 0x000c, 0x3dc: 0x000c, 0x3dd: 0x000c, + 0x3de: 0x000c, 0x3df: 0x000c, 0x3e0: 0x0005, 0x3e1: 0x0005, 0x3e2: 0x0005, 0x3e3: 0x0005, + 0x3e4: 0x0005, 0x3e5: 0x0005, 0x3e6: 0x0005, 0x3e7: 0x0005, 0x3e8: 0x0005, 0x3e9: 0x0005, + 0x3ea: 0x0004, 0x3eb: 0x0005, 0x3ec: 0x0005, 0x3ed: 0x000d, 0x3ee: 0x000d, 0x3ef: 0x000d, + 0x3f0: 0x000c, 0x3f1: 0x000d, 0x3f2: 0x000d, 0x3f3: 0x000d, 0x3f4: 0x000d, 0x3f5: 0x000d, + 0x3f6: 0x000d, 0x3f7: 0x000d, 0x3f8: 0x000d, 0x3f9: 0x000d, 0x3fa: 0x000d, 0x3fb: 0x000d, + 0x3fc: 0x000d, 0x3fd: 0x000d, 0x3fe: 0x000d, 0x3ff: 0x000d, + // Block 0x10, offset 0x400 + 0x400: 0x000d, 0x401: 0x000d, 0x402: 0x000d, 0x403: 0x000d, 0x404: 0x000d, 0x405: 0x000d, + 0x406: 0x000d, 0x407: 0x000d, 0x408: 0x000d, 0x409: 0x000d, 0x40a: 0x000d, 0x40b: 0x000d, + 0x40c: 0x000d, 0x40d: 0x000d, 0x40e: 0x000d, 0x40f: 0x000d, 0x410: 0x000d, 0x411: 0x000d, + 0x412: 0x000d, 0x413: 0x000d, 0x414: 0x000d, 0x415: 0x000d, 0x416: 0x000d, 0x417: 0x000d, + 0x418: 0x000d, 0x419: 0x000d, 0x41a: 0x000d, 0x41b: 0x000d, 0x41c: 0x000d, 0x41d: 0x000d, + 0x41e: 0x000d, 0x41f: 0x000d, 0x420: 0x000d, 0x421: 0x000d, 0x422: 0x000d, 0x423: 0x000d, + 0x424: 0x000d, 0x425: 0x000d, 0x426: 0x000d, 0x427: 0x000d, 0x428: 0x000d, 0x429: 0x000d, + 0x42a: 0x000d, 0x42b: 0x000d, 0x42c: 0x000d, 0x42d: 0x000d, 0x42e: 0x000d, 0x42f: 0x000d, + 0x430: 0x000d, 0x431: 0x000d, 0x432: 0x000d, 0x433: 0x000d, 0x434: 0x000d, 0x435: 0x000d, + 0x436: 0x000d, 0x437: 0x000d, 0x438: 0x000d, 0x439: 0x000d, 0x43a: 0x000d, 0x43b: 0x000d, + 0x43c: 0x000d, 0x43d: 0x000d, 0x43e: 0x000d, 0x43f: 0x000d, + // Block 0x11, offset 0x440 + 0x440: 0x000d, 0x441: 0x000d, 0x442: 0x000d, 0x443: 0x000d, 0x444: 0x000d, 0x445: 0x000d, + 0x446: 0x000d, 0x447: 0x000d, 0x448: 0x000d, 0x449: 0x000d, 0x44a: 0x000d, 0x44b: 0x000d, + 0x44c: 0x000d, 0x44d: 0x000d, 0x44e: 0x000d, 0x44f: 0x000d, 0x450: 0x000d, 0x451: 0x000d, + 0x452: 0x000d, 0x453: 0x000d, 0x454: 0x000d, 0x455: 0x000d, 0x456: 0x000c, 0x457: 0x000c, + 0x458: 0x000c, 0x459: 0x000c, 0x45a: 0x000c, 0x45b: 0x000c, 0x45c: 0x000c, 0x45d: 0x0005, + 0x45e: 0x000a, 0x45f: 0x000c, 0x460: 0x000c, 0x461: 0x000c, 0x462: 0x000c, 0x463: 0x000c, + 0x464: 0x000c, 0x465: 0x000d, 0x466: 0x000d, 0x467: 0x000c, 0x468: 0x000c, 0x469: 0x000a, + 0x46a: 0x000c, 0x46b: 0x000c, 0x46c: 0x000c, 0x46d: 0x000c, 0x46e: 0x000d, 0x46f: 0x000d, + 0x470: 0x0002, 0x471: 0x0002, 0x472: 0x0002, 0x473: 0x0002, 0x474: 0x0002, 0x475: 0x0002, + 0x476: 0x0002, 0x477: 0x0002, 0x478: 0x0002, 0x479: 0x0002, 0x47a: 0x000d, 0x47b: 0x000d, + 0x47c: 0x000d, 0x47d: 0x000d, 0x47e: 0x000d, 0x47f: 0x000d, + // Block 0x12, offset 0x480 + 0x480: 0x000d, 0x481: 0x000d, 0x482: 0x000d, 0x483: 0x000d, 0x484: 0x000d, 0x485: 0x000d, + 0x486: 0x000d, 0x487: 0x000d, 0x488: 0x000d, 0x489: 0x000d, 0x48a: 0x000d, 0x48b: 0x000d, + 0x48c: 0x000d, 0x48d: 0x000d, 0x48e: 0x000d, 0x48f: 0x000d, 0x490: 0x000d, 0x491: 0x000c, + 0x492: 0x000d, 0x493: 0x000d, 0x494: 0x000d, 0x495: 0x000d, 0x496: 0x000d, 0x497: 0x000d, + 0x498: 0x000d, 0x499: 0x000d, 0x49a: 0x000d, 0x49b: 0x000d, 0x49c: 0x000d, 0x49d: 0x000d, + 0x49e: 0x000d, 0x49f: 0x000d, 0x4a0: 0x000d, 0x4a1: 0x000d, 0x4a2: 0x000d, 0x4a3: 0x000d, + 0x4a4: 0x000d, 0x4a5: 0x000d, 0x4a6: 0x000d, 0x4a7: 0x000d, 0x4a8: 0x000d, 0x4a9: 0x000d, + 0x4aa: 0x000d, 0x4ab: 0x000d, 0x4ac: 0x000d, 0x4ad: 0x000d, 0x4ae: 0x000d, 0x4af: 0x000d, + 0x4b0: 0x000c, 0x4b1: 0x000c, 0x4b2: 0x000c, 0x4b3: 0x000c, 0x4b4: 0x000c, 0x4b5: 0x000c, + 0x4b6: 0x000c, 0x4b7: 0x000c, 0x4b8: 0x000c, 0x4b9: 0x000c, 0x4ba: 0x000c, 0x4bb: 0x000c, + 0x4bc: 0x000c, 0x4bd: 0x000c, 0x4be: 0x000c, 0x4bf: 0x000c, + // Block 0x13, offset 0x4c0 + 0x4c0: 0x000c, 0x4c1: 0x000c, 0x4c2: 0x000c, 0x4c3: 0x000c, 0x4c4: 0x000c, 0x4c5: 0x000c, + 0x4c6: 0x000c, 0x4c7: 0x000c, 0x4c8: 0x000c, 0x4c9: 0x000c, 0x4ca: 0x000c, 0x4cb: 0x000d, + 0x4cc: 0x000d, 0x4cd: 0x000d, 0x4ce: 0x000d, 0x4cf: 0x000d, 0x4d0: 0x000d, 0x4d1: 0x000d, + 0x4d2: 0x000d, 0x4d3: 0x000d, 0x4d4: 0x000d, 0x4d5: 0x000d, 0x4d6: 0x000d, 0x4d7: 0x000d, + 0x4d8: 0x000d, 0x4d9: 0x000d, 0x4da: 0x000d, 0x4db: 0x000d, 0x4dc: 0x000d, 0x4dd: 0x000d, + 0x4de: 0x000d, 0x4df: 0x000d, 0x4e0: 0x000d, 0x4e1: 0x000d, 0x4e2: 0x000d, 0x4e3: 0x000d, + 0x4e4: 0x000d, 0x4e5: 0x000d, 0x4e6: 0x000d, 0x4e7: 0x000d, 0x4e8: 0x000d, 0x4e9: 0x000d, + 0x4ea: 0x000d, 0x4eb: 0x000d, 0x4ec: 0x000d, 0x4ed: 0x000d, 0x4ee: 0x000d, 0x4ef: 0x000d, + 0x4f0: 0x000d, 0x4f1: 0x000d, 0x4f2: 0x000d, 0x4f3: 0x000d, 0x4f4: 0x000d, 0x4f5: 0x000d, + 0x4f6: 0x000d, 0x4f7: 0x000d, 0x4f8: 0x000d, 0x4f9: 0x000d, 0x4fa: 0x000d, 0x4fb: 0x000d, + 0x4fc: 0x000d, 0x4fd: 0x000d, 0x4fe: 0x000d, 0x4ff: 0x000d, + // Block 0x14, offset 0x500 + 0x500: 0x000d, 0x501: 0x000d, 0x502: 0x000d, 0x503: 0x000d, 0x504: 0x000d, 0x505: 0x000d, + 0x506: 0x000d, 0x507: 0x000d, 0x508: 0x000d, 0x509: 0x000d, 0x50a: 0x000d, 0x50b: 0x000d, + 0x50c: 0x000d, 0x50d: 0x000d, 0x50e: 0x000d, 0x50f: 0x000d, 0x510: 0x000d, 0x511: 0x000d, + 0x512: 0x000d, 0x513: 0x000d, 0x514: 0x000d, 0x515: 0x000d, 0x516: 0x000d, 0x517: 0x000d, + 0x518: 0x000d, 0x519: 0x000d, 0x51a: 0x000d, 0x51b: 0x000d, 0x51c: 0x000d, 0x51d: 0x000d, + 0x51e: 0x000d, 0x51f: 0x000d, 0x520: 0x000d, 0x521: 0x000d, 0x522: 0x000d, 0x523: 0x000d, + 0x524: 0x000d, 0x525: 0x000d, 0x526: 0x000c, 0x527: 0x000c, 0x528: 0x000c, 0x529: 0x000c, + 0x52a: 0x000c, 0x52b: 0x000c, 0x52c: 0x000c, 0x52d: 0x000c, 0x52e: 0x000c, 0x52f: 0x000c, + 0x530: 0x000c, 0x531: 0x000d, 0x532: 0x000d, 0x533: 0x000d, 0x534: 0x000d, 0x535: 0x000d, + 0x536: 0x000d, 0x537: 0x000d, 0x538: 0x000d, 0x539: 0x000d, 0x53a: 0x000d, 0x53b: 0x000d, + 0x53c: 0x000d, 0x53d: 0x000d, 0x53e: 0x000d, 0x53f: 0x000d, + // Block 0x15, offset 0x540 + 0x540: 0x0001, 0x541: 0x0001, 0x542: 0x0001, 0x543: 0x0001, 0x544: 0x0001, 0x545: 0x0001, + 0x546: 0x0001, 0x547: 0x0001, 0x548: 0x0001, 0x549: 0x0001, 0x54a: 0x0001, 0x54b: 0x0001, + 0x54c: 0x0001, 0x54d: 0x0001, 0x54e: 0x0001, 0x54f: 0x0001, 0x550: 0x0001, 0x551: 0x0001, + 0x552: 0x0001, 0x553: 0x0001, 0x554: 0x0001, 0x555: 0x0001, 0x556: 0x0001, 0x557: 0x0001, + 0x558: 0x0001, 0x559: 0x0001, 0x55a: 0x0001, 0x55b: 0x0001, 0x55c: 0x0001, 0x55d: 0x0001, + 0x55e: 0x0001, 0x55f: 0x0001, 0x560: 0x0001, 0x561: 0x0001, 0x562: 0x0001, 0x563: 0x0001, + 0x564: 0x0001, 0x565: 0x0001, 0x566: 0x0001, 0x567: 0x0001, 0x568: 0x0001, 0x569: 0x0001, + 0x56a: 0x0001, 0x56b: 0x000c, 0x56c: 0x000c, 0x56d: 0x000c, 0x56e: 0x000c, 0x56f: 0x000c, + 0x570: 0x000c, 0x571: 0x000c, 0x572: 0x000c, 0x573: 0x000c, 0x574: 0x0001, 0x575: 0x0001, + 0x576: 0x000a, 0x577: 0x000a, 0x578: 0x000a, 0x579: 0x000a, 0x57a: 0x0001, 0x57b: 0x0001, + 0x57c: 0x0001, 0x57d: 0x0001, 0x57e: 0x0001, 0x57f: 0x0001, + // Block 0x16, offset 0x580 + 0x580: 0x0001, 0x581: 0x0001, 0x582: 0x0001, 0x583: 0x0001, 0x584: 0x0001, 0x585: 0x0001, + 0x586: 0x0001, 0x587: 0x0001, 0x588: 0x0001, 0x589: 0x0001, 0x58a: 0x0001, 0x58b: 0x0001, + 0x58c: 0x0001, 0x58d: 0x0001, 0x58e: 0x0001, 0x58f: 0x0001, 0x590: 0x0001, 0x591: 0x0001, + 0x592: 0x0001, 0x593: 0x0001, 0x594: 0x0001, 0x595: 0x0001, 0x596: 0x000c, 0x597: 0x000c, + 0x598: 0x000c, 0x599: 0x000c, 0x59a: 0x0001, 0x59b: 0x000c, 0x59c: 0x000c, 0x59d: 0x000c, + 0x59e: 0x000c, 0x59f: 0x000c, 0x5a0: 0x000c, 0x5a1: 0x000c, 0x5a2: 0x000c, 0x5a3: 0x000c, + 0x5a4: 0x0001, 0x5a5: 0x000c, 0x5a6: 0x000c, 0x5a7: 0x000c, 0x5a8: 0x0001, 0x5a9: 0x000c, + 0x5aa: 0x000c, 0x5ab: 0x000c, 0x5ac: 0x000c, 0x5ad: 0x000c, 0x5ae: 0x0001, 0x5af: 0x0001, + 0x5b0: 0x0001, 0x5b1: 0x0001, 0x5b2: 0x0001, 0x5b3: 0x0001, 0x5b4: 0x0001, 0x5b5: 0x0001, + 0x5b6: 0x0001, 0x5b7: 0x0001, 0x5b8: 0x0001, 0x5b9: 0x0001, 0x5ba: 0x0001, 0x5bb: 0x0001, + 0x5bc: 0x0001, 0x5bd: 0x0001, 0x5be: 0x0001, 0x5bf: 0x0001, + // Block 0x17, offset 0x5c0 + 0x5c0: 0x0001, 0x5c1: 0x0001, 0x5c2: 0x0001, 0x5c3: 0x0001, 0x5c4: 0x0001, 0x5c5: 0x0001, + 0x5c6: 0x0001, 0x5c7: 0x0001, 0x5c8: 0x0001, 0x5c9: 0x0001, 0x5ca: 0x0001, 0x5cb: 0x0001, + 0x5cc: 0x0001, 0x5cd: 0x0001, 0x5ce: 0x0001, 0x5cf: 0x0001, 0x5d0: 0x0001, 0x5d1: 0x0001, + 0x5d2: 0x0001, 0x5d3: 0x0001, 0x5d4: 0x0001, 0x5d5: 0x0001, 0x5d6: 0x0001, 0x5d7: 0x0001, + 0x5d8: 0x0001, 0x5d9: 0x000c, 0x5da: 0x000c, 0x5db: 0x000c, 0x5dc: 0x0001, 0x5dd: 0x0001, + 0x5de: 0x0001, 0x5df: 0x0001, 0x5e0: 0x000d, 0x5e1: 0x000d, 0x5e2: 0x000d, 0x5e3: 0x000d, + 0x5e4: 0x000d, 0x5e5: 0x000d, 0x5e6: 0x000d, 0x5e7: 0x000d, 0x5e8: 0x000d, 0x5e9: 0x000d, + 0x5ea: 0x000d, 0x5eb: 0x000d, 0x5ec: 0x000d, 0x5ed: 0x000d, 0x5ee: 0x000d, 0x5ef: 0x000d, + 0x5f0: 0x0001, 0x5f1: 0x0001, 0x5f2: 0x0001, 0x5f3: 0x0001, 0x5f4: 0x0001, 0x5f5: 0x0001, + 0x5f6: 0x0001, 0x5f7: 0x0001, 0x5f8: 0x0001, 0x5f9: 0x0001, 0x5fa: 0x0001, 0x5fb: 0x0001, + 0x5fc: 0x0001, 0x5fd: 0x0001, 0x5fe: 0x0001, 0x5ff: 0x0001, + // Block 0x18, offset 0x600 + 0x600: 0x0001, 0x601: 0x0001, 0x602: 0x0001, 0x603: 0x0001, 0x604: 0x0001, 0x605: 0x0001, + 0x606: 0x0001, 0x607: 0x0001, 0x608: 0x0001, 0x609: 0x0001, 0x60a: 0x0001, 0x60b: 0x0001, + 0x60c: 0x0001, 0x60d: 0x0001, 0x60e: 0x0001, 0x60f: 0x0001, 0x610: 0x0001, 0x611: 0x0001, + 0x612: 0x0001, 0x613: 0x0001, 0x614: 0x0001, 0x615: 0x0001, 0x616: 0x0001, 0x617: 0x0001, + 0x618: 0x0001, 0x619: 0x0001, 0x61a: 0x0001, 0x61b: 0x0001, 0x61c: 0x0001, 0x61d: 0x0001, + 0x61e: 0x0001, 0x61f: 0x0001, 0x620: 0x000d, 0x621: 0x000d, 0x622: 0x000d, 0x623: 0x000d, + 0x624: 0x000d, 0x625: 0x000d, 0x626: 0x000d, 0x627: 0x000d, 0x628: 0x000d, 0x629: 0x000d, + 0x62a: 0x000d, 0x62b: 0x000d, 0x62c: 0x000d, 0x62d: 0x000d, 0x62e: 0x000d, 0x62f: 0x000d, + 0x630: 0x000d, 0x631: 0x000d, 0x632: 0x000d, 0x633: 0x000d, 0x634: 0x000d, 0x635: 0x000d, + 0x636: 0x000d, 0x637: 0x000d, 0x638: 0x000d, 0x639: 0x000d, 0x63a: 0x000d, 0x63b: 0x000d, + 0x63c: 0x000d, 0x63d: 0x000d, 0x63e: 0x000d, 0x63f: 0x000d, + // Block 0x19, offset 0x640 + 0x640: 0x000d, 0x641: 0x000d, 0x642: 0x000d, 0x643: 0x000d, 0x644: 0x000d, 0x645: 0x000d, + 0x646: 0x000d, 0x647: 0x000d, 0x648: 0x000d, 0x649: 0x000d, 0x64a: 0x000d, 0x64b: 0x000d, + 0x64c: 0x000d, 0x64d: 0x000d, 0x64e: 0x000d, 0x64f: 0x000d, 0x650: 0x000d, 0x651: 0x000d, + 0x652: 0x000d, 0x653: 0x000d, 0x654: 0x000c, 0x655: 0x000c, 0x656: 0x000c, 0x657: 0x000c, + 0x658: 0x000c, 0x659: 0x000c, 0x65a: 0x000c, 0x65b: 0x000c, 0x65c: 0x000c, 0x65d: 0x000c, + 0x65e: 0x000c, 0x65f: 0x000c, 0x660: 0x000c, 0x661: 0x000c, 0x662: 0x0005, 0x663: 0x000c, + 0x664: 0x000c, 0x665: 0x000c, 0x666: 0x000c, 0x667: 0x000c, 0x668: 0x000c, 0x669: 0x000c, + 0x66a: 0x000c, 0x66b: 0x000c, 0x66c: 0x000c, 0x66d: 0x000c, 0x66e: 0x000c, 0x66f: 0x000c, + 0x670: 0x000c, 0x671: 0x000c, 0x672: 0x000c, 0x673: 0x000c, 0x674: 0x000c, 0x675: 0x000c, + 0x676: 0x000c, 0x677: 0x000c, 0x678: 0x000c, 0x679: 0x000c, 0x67a: 0x000c, 0x67b: 0x000c, + 0x67c: 0x000c, 0x67d: 0x000c, 0x67e: 0x000c, 0x67f: 0x000c, + // Block 0x1a, offset 0x680 + 0x680: 0x000c, 0x681: 0x000c, 0x682: 0x000c, + 0x6ba: 0x000c, + 0x6bc: 0x000c, + // Block 0x1b, offset 0x6c0 + 0x6c1: 0x000c, 0x6c2: 0x000c, 0x6c3: 0x000c, 0x6c4: 0x000c, 0x6c5: 0x000c, + 0x6c6: 0x000c, 0x6c7: 0x000c, 0x6c8: 0x000c, + 0x6cd: 0x000c, 0x6d1: 0x000c, + 0x6d2: 0x000c, 0x6d3: 0x000c, 0x6d4: 0x000c, 0x6d5: 0x000c, 0x6d6: 0x000c, 0x6d7: 0x000c, + 0x6e2: 0x000c, 0x6e3: 0x000c, + // Block 0x1c, offset 0x700 + 0x701: 0x000c, + 0x73c: 0x000c, + // Block 0x1d, offset 0x740 + 0x741: 0x000c, 0x742: 0x000c, 0x743: 0x000c, 0x744: 0x000c, + 0x74d: 0x000c, + 0x762: 0x000c, 0x763: 0x000c, + 0x772: 0x0004, 0x773: 0x0004, + 0x77b: 0x0004, + // Block 0x1e, offset 0x780 + 0x781: 0x000c, 0x782: 0x000c, + 0x7bc: 0x000c, + // Block 0x1f, offset 0x7c0 + 0x7c1: 0x000c, 0x7c2: 0x000c, + 0x7c7: 0x000c, 0x7c8: 0x000c, 0x7cb: 0x000c, + 0x7cc: 0x000c, 0x7cd: 0x000c, 0x7d1: 0x000c, + 0x7f0: 0x000c, 0x7f1: 0x000c, 0x7f5: 0x000c, + // Block 0x20, offset 0x800 + 0x801: 0x000c, 0x802: 0x000c, 0x803: 0x000c, 0x804: 0x000c, 0x805: 0x000c, + 0x807: 0x000c, 0x808: 0x000c, + 0x80d: 0x000c, + 0x822: 0x000c, 0x823: 0x000c, + 0x831: 0x0004, + 0x83a: 0x000c, 0x83b: 0x000c, + 0x83c: 0x000c, 0x83d: 0x000c, 0x83e: 0x000c, 0x83f: 0x000c, + // Block 0x21, offset 0x840 + 0x841: 0x000c, + 0x87c: 0x000c, 0x87f: 0x000c, + // Block 0x22, offset 0x880 + 0x881: 0x000c, 0x882: 0x000c, 0x883: 0x000c, 0x884: 0x000c, + 0x88d: 0x000c, + 0x896: 0x000c, + 0x8a2: 0x000c, 0x8a3: 0x000c, + // Block 0x23, offset 0x8c0 + 0x8c2: 0x000c, + // Block 0x24, offset 0x900 + 0x900: 0x000c, + 0x90d: 0x000c, + 0x933: 0x000a, 0x934: 0x000a, 0x935: 0x000a, + 0x936: 0x000a, 0x937: 0x000a, 0x938: 0x000a, 0x939: 0x0004, 0x93a: 0x000a, + // Block 0x25, offset 0x940 + 0x940: 0x000c, + 0x97e: 0x000c, 0x97f: 0x000c, + // Block 0x26, offset 0x980 + 0x980: 0x000c, + 0x986: 0x000c, 0x987: 0x000c, 0x988: 0x000c, 0x98a: 0x000c, 0x98b: 0x000c, + 0x98c: 0x000c, 0x98d: 0x000c, + 0x995: 0x000c, 0x996: 0x000c, + 0x9a2: 0x000c, 0x9a3: 0x000c, + 0x9b8: 0x000a, 0x9b9: 0x000a, 0x9ba: 0x000a, 0x9bb: 0x000a, + 0x9bc: 0x000a, 0x9bd: 0x000a, 0x9be: 0x000a, + // Block 0x27, offset 0x9c0 + 0x9cc: 0x000c, 0x9cd: 0x000c, + 0x9e2: 0x000c, 0x9e3: 0x000c, + // Block 0x28, offset 0xa00 + 0xa00: 0x000c, 0xa01: 0x000c, + 0xa3b: 0x000c, + 0xa3c: 0x000c, + // Block 0x29, offset 0xa40 + 0xa41: 0x000c, 0xa42: 0x000c, 0xa43: 0x000c, 0xa44: 0x000c, + 0xa4d: 0x000c, + 0xa62: 0x000c, 0xa63: 0x000c, + // Block 0x2a, offset 0xa80 + 0xa8a: 0x000c, + 0xa92: 0x000c, 0xa93: 0x000c, 0xa94: 0x000c, 0xa96: 0x000c, + // Block 0x2b, offset 0xac0 + 0xaf1: 0x000c, 0xaf4: 0x000c, 0xaf5: 0x000c, + 0xaf6: 0x000c, 0xaf7: 0x000c, 0xaf8: 0x000c, 0xaf9: 0x000c, 0xafa: 0x000c, + 0xaff: 0x0004, + // Block 0x2c, offset 0xb00 + 0xb07: 0x000c, 0xb08: 0x000c, 0xb09: 0x000c, 0xb0a: 0x000c, 0xb0b: 0x000c, + 0xb0c: 0x000c, 0xb0d: 0x000c, 0xb0e: 0x000c, + // Block 0x2d, offset 0xb40 + 0xb71: 0x000c, 0xb74: 0x000c, 0xb75: 0x000c, + 0xb76: 0x000c, 0xb77: 0x000c, 0xb78: 0x000c, 0xb79: 0x000c, 0xb7b: 0x000c, + 0xb7c: 0x000c, + // Block 0x2e, offset 0xb80 + 0xb88: 0x000c, 0xb89: 0x000c, 0xb8a: 0x000c, 0xb8b: 0x000c, + 0xb8c: 0x000c, 0xb8d: 0x000c, + // Block 0x2f, offset 0xbc0 + 0xbd8: 0x000c, 0xbd9: 0x000c, + 0xbf5: 0x000c, + 0xbf7: 0x000c, 0xbf9: 0x000c, 0xbfa: 0x003a, 0xbfb: 0x002a, + 0xbfc: 0x003a, 0xbfd: 0x002a, + // Block 0x30, offset 0xc00 + 0xc31: 0x000c, 0xc32: 0x000c, 0xc33: 0x000c, 0xc34: 0x000c, 0xc35: 0x000c, + 0xc36: 0x000c, 0xc37: 0x000c, 0xc38: 0x000c, 0xc39: 0x000c, 0xc3a: 0x000c, 0xc3b: 0x000c, + 0xc3c: 0x000c, 0xc3d: 0x000c, 0xc3e: 0x000c, + // Block 0x31, offset 0xc40 + 0xc40: 0x000c, 0xc41: 0x000c, 0xc42: 0x000c, 0xc43: 0x000c, 0xc44: 0x000c, + 0xc46: 0x000c, 0xc47: 0x000c, + 0xc4d: 0x000c, 0xc4e: 0x000c, 0xc4f: 0x000c, 0xc50: 0x000c, 0xc51: 0x000c, + 0xc52: 0x000c, 0xc53: 0x000c, 0xc54: 0x000c, 0xc55: 0x000c, 0xc56: 0x000c, 0xc57: 0x000c, + 0xc59: 0x000c, 0xc5a: 0x000c, 0xc5b: 0x000c, 0xc5c: 0x000c, 0xc5d: 0x000c, + 0xc5e: 0x000c, 0xc5f: 0x000c, 0xc60: 0x000c, 0xc61: 0x000c, 0xc62: 0x000c, 0xc63: 0x000c, + 0xc64: 0x000c, 0xc65: 0x000c, 0xc66: 0x000c, 0xc67: 0x000c, 0xc68: 0x000c, 0xc69: 0x000c, + 0xc6a: 0x000c, 0xc6b: 0x000c, 0xc6c: 0x000c, 0xc6d: 0x000c, 0xc6e: 0x000c, 0xc6f: 0x000c, + 0xc70: 0x000c, 0xc71: 0x000c, 0xc72: 0x000c, 0xc73: 0x000c, 0xc74: 0x000c, 0xc75: 0x000c, + 0xc76: 0x000c, 0xc77: 0x000c, 0xc78: 0x000c, 0xc79: 0x000c, 0xc7a: 0x000c, 0xc7b: 0x000c, + 0xc7c: 0x000c, + // Block 0x32, offset 0xc80 + 0xc86: 0x000c, + // Block 0x33, offset 0xcc0 + 0xced: 0x000c, 0xcee: 0x000c, 0xcef: 0x000c, + 0xcf0: 0x000c, 0xcf2: 0x000c, 0xcf3: 0x000c, 0xcf4: 0x000c, 0xcf5: 0x000c, + 0xcf6: 0x000c, 0xcf7: 0x000c, 0xcf9: 0x000c, 0xcfa: 0x000c, + 0xcfd: 0x000c, 0xcfe: 0x000c, + // Block 0x34, offset 0xd00 + 0xd18: 0x000c, 0xd19: 0x000c, + 0xd1e: 0x000c, 0xd1f: 0x000c, 0xd20: 0x000c, + 0xd31: 0x000c, 0xd32: 0x000c, 0xd33: 0x000c, 0xd34: 0x000c, + // Block 0x35, offset 0xd40 + 0xd42: 0x000c, 0xd45: 0x000c, + 0xd46: 0x000c, + 0xd4d: 0x000c, + 0xd5d: 0x000c, + // Block 0x36, offset 0xd80 + 0xd9d: 0x000c, + 0xd9e: 0x000c, 0xd9f: 0x000c, + // Block 0x37, offset 0xdc0 + 0xdd0: 0x000a, 0xdd1: 0x000a, + 0xdd2: 0x000a, 0xdd3: 0x000a, 0xdd4: 0x000a, 0xdd5: 0x000a, 0xdd6: 0x000a, 0xdd7: 0x000a, + 0xdd8: 0x000a, 0xdd9: 0x000a, + // Block 0x38, offset 0xe00 + 0xe00: 0x000a, + // Block 0x39, offset 0xe40 + 0xe40: 0x0009, + 0xe5b: 0x007a, 0xe5c: 0x006a, + // Block 0x3a, offset 0xe80 + 0xe92: 0x000c, 0xe93: 0x000c, 0xe94: 0x000c, + 0xeb2: 0x000c, 0xeb3: 0x000c, 0xeb4: 0x000c, + // Block 0x3b, offset 0xec0 + 0xed2: 0x000c, 0xed3: 0x000c, + 0xef2: 0x000c, 0xef3: 0x000c, + // Block 0x3c, offset 0xf00 + 0xf34: 0x000c, 0xf35: 0x000c, + 0xf37: 0x000c, 0xf38: 0x000c, 0xf39: 0x000c, 0xf3a: 0x000c, 0xf3b: 0x000c, + 0xf3c: 0x000c, 0xf3d: 0x000c, + // Block 0x3d, offset 0xf40 + 0xf46: 0x000c, 0xf49: 0x000c, 0xf4a: 0x000c, 0xf4b: 0x000c, + 0xf4c: 0x000c, 0xf4d: 0x000c, 0xf4e: 0x000c, 0xf4f: 0x000c, 0xf50: 0x000c, 0xf51: 0x000c, + 0xf52: 0x000c, 0xf53: 0x000c, + 0xf5b: 0x0004, 0xf5d: 0x000c, + 0xf70: 0x000a, 0xf71: 0x000a, 0xf72: 0x000a, 0xf73: 0x000a, 0xf74: 0x000a, 0xf75: 0x000a, + 0xf76: 0x000a, 0xf77: 0x000a, 0xf78: 0x000a, 0xf79: 0x000a, + // Block 0x3e, offset 0xf80 + 0xf80: 0x000a, 0xf81: 0x000a, 0xf82: 0x000a, 0xf83: 0x000a, 0xf84: 0x000a, 0xf85: 0x000a, + 0xf86: 0x000a, 0xf87: 0x000a, 0xf88: 0x000a, 0xf89: 0x000a, 0xf8a: 0x000a, 0xf8b: 0x000c, + 0xf8c: 0x000c, 0xf8d: 0x000c, 0xf8e: 0x000b, + // Block 0x3f, offset 0xfc0 + 0xfc5: 0x000c, + 0xfc6: 0x000c, + 0xfe9: 0x000c, + // Block 0x40, offset 0x1000 + 0x1020: 0x000c, 0x1021: 0x000c, 0x1022: 0x000c, + 0x1027: 0x000c, 0x1028: 0x000c, + 0x1032: 0x000c, + 0x1039: 0x000c, 0x103a: 0x000c, 0x103b: 0x000c, + // Block 0x41, offset 0x1040 + 0x1040: 0x000a, 0x1044: 0x000a, 0x1045: 0x000a, + // Block 0x42, offset 0x1080 + 0x109e: 0x000a, 0x109f: 0x000a, 0x10a0: 0x000a, 0x10a1: 0x000a, 0x10a2: 0x000a, 0x10a3: 0x000a, + 0x10a4: 0x000a, 0x10a5: 0x000a, 0x10a6: 0x000a, 0x10a7: 0x000a, 0x10a8: 0x000a, 0x10a9: 0x000a, + 0x10aa: 0x000a, 0x10ab: 0x000a, 0x10ac: 0x000a, 0x10ad: 0x000a, 0x10ae: 0x000a, 0x10af: 0x000a, + 0x10b0: 0x000a, 0x10b1: 0x000a, 0x10b2: 0x000a, 0x10b3: 0x000a, 0x10b4: 0x000a, 0x10b5: 0x000a, + 0x10b6: 0x000a, 0x10b7: 0x000a, 0x10b8: 0x000a, 0x10b9: 0x000a, 0x10ba: 0x000a, 0x10bb: 0x000a, + 0x10bc: 0x000a, 0x10bd: 0x000a, 0x10be: 0x000a, 0x10bf: 0x000a, + // Block 0x43, offset 0x10c0 + 0x10d7: 0x000c, + 0x10d8: 0x000c, 0x10db: 0x000c, + // Block 0x44, offset 0x1100 + 0x1116: 0x000c, + 0x1118: 0x000c, 0x1119: 0x000c, 0x111a: 0x000c, 0x111b: 0x000c, 0x111c: 0x000c, 0x111d: 0x000c, + 0x111e: 0x000c, 0x1120: 0x000c, 0x1122: 0x000c, + 0x1125: 0x000c, 0x1126: 0x000c, 0x1127: 0x000c, 0x1128: 0x000c, 0x1129: 0x000c, + 0x112a: 0x000c, 0x112b: 0x000c, 0x112c: 0x000c, + 0x1133: 0x000c, 0x1134: 0x000c, 0x1135: 0x000c, + 0x1136: 0x000c, 0x1137: 0x000c, 0x1138: 0x000c, 0x1139: 0x000c, 0x113a: 0x000c, 0x113b: 0x000c, + 0x113c: 0x000c, 0x113f: 0x000c, + // Block 0x45, offset 0x1140 + 0x1170: 0x000c, 0x1171: 0x000c, 0x1172: 0x000c, 0x1173: 0x000c, 0x1174: 0x000c, 0x1175: 0x000c, + 0x1176: 0x000c, 0x1177: 0x000c, 0x1178: 0x000c, 0x1179: 0x000c, 0x117a: 0x000c, 0x117b: 0x000c, + 0x117c: 0x000c, 0x117d: 0x000c, 0x117e: 0x000c, + // Block 0x46, offset 0x1180 + 0x1180: 0x000c, 0x1181: 0x000c, 0x1182: 0x000c, 0x1183: 0x000c, + 0x11b4: 0x000c, + 0x11b6: 0x000c, 0x11b7: 0x000c, 0x11b8: 0x000c, 0x11b9: 0x000c, 0x11ba: 0x000c, + 0x11bc: 0x000c, + // Block 0x47, offset 0x11c0 + 0x11c2: 0x000c, + 0x11eb: 0x000c, 0x11ec: 0x000c, 0x11ed: 0x000c, 0x11ee: 0x000c, 0x11ef: 0x000c, + 0x11f0: 0x000c, 0x11f1: 0x000c, 0x11f2: 0x000c, 0x11f3: 0x000c, + // Block 0x48, offset 0x1200 + 0x1200: 0x000c, 0x1201: 0x000c, + 0x1222: 0x000c, 0x1223: 0x000c, + 0x1224: 0x000c, 0x1225: 0x000c, 0x1228: 0x000c, 0x1229: 0x000c, + 0x122b: 0x000c, 0x122c: 0x000c, 0x122d: 0x000c, + // Block 0x49, offset 0x1240 + 0x1266: 0x000c, 0x1268: 0x000c, 0x1269: 0x000c, + 0x126d: 0x000c, 0x126f: 0x000c, + 0x1270: 0x000c, 0x1271: 0x000c, + // Block 0x4a, offset 0x1280 + 0x12ac: 0x000c, 0x12ad: 0x000c, 0x12ae: 0x000c, 0x12af: 0x000c, + 0x12b0: 0x000c, 0x12b1: 0x000c, 0x12b2: 0x000c, 0x12b3: 0x000c, + 0x12b6: 0x000c, 0x12b7: 0x000c, + // Block 0x4b, offset 0x12c0 + 0x12d0: 0x000c, 0x12d1: 0x000c, + 0x12d2: 0x000c, 0x12d4: 0x000c, 0x12d5: 0x000c, 0x12d6: 0x000c, 0x12d7: 0x000c, + 0x12d8: 0x000c, 0x12d9: 0x000c, 0x12da: 0x000c, 0x12db: 0x000c, 0x12dc: 0x000c, 0x12dd: 0x000c, + 0x12de: 0x000c, 0x12df: 0x000c, 0x12e0: 0x000c, 0x12e2: 0x000c, 0x12e3: 0x000c, + 0x12e4: 0x000c, 0x12e5: 0x000c, 0x12e6: 0x000c, 0x12e7: 0x000c, 0x12e8: 0x000c, + 0x12ed: 0x000c, + 0x12f4: 0x000c, + 0x12f8: 0x000c, 0x12f9: 0x000c, + // Block 0x4c, offset 0x1300 + 0x1300: 0x000c, 0x1301: 0x000c, 0x1302: 0x000c, 0x1303: 0x000c, 0x1304: 0x000c, 0x1305: 0x000c, + 0x1306: 0x000c, 0x1307: 0x000c, 0x1308: 0x000c, 0x1309: 0x000c, 0x130a: 0x000c, 0x130b: 0x000c, + 0x130c: 0x000c, 0x130d: 0x000c, 0x130e: 0x000c, 0x130f: 0x000c, 0x1310: 0x000c, 0x1311: 0x000c, + 0x1312: 0x000c, 0x1313: 0x000c, 0x1314: 0x000c, 0x1315: 0x000c, 0x1316: 0x000c, 0x1317: 0x000c, + 0x1318: 0x000c, 0x1319: 0x000c, 0x131a: 0x000c, 0x131b: 0x000c, 0x131c: 0x000c, 0x131d: 0x000c, + 0x131e: 0x000c, 0x131f: 0x000c, 0x1320: 0x000c, 0x1321: 0x000c, 0x1322: 0x000c, 0x1323: 0x000c, + 0x1324: 0x000c, 0x1325: 0x000c, 0x1326: 0x000c, 0x1327: 0x000c, 0x1328: 0x000c, 0x1329: 0x000c, + 0x132a: 0x000c, 0x132b: 0x000c, 0x132c: 0x000c, 0x132d: 0x000c, 0x132e: 0x000c, 0x132f: 0x000c, + 0x1330: 0x000c, 0x1331: 0x000c, 0x1332: 0x000c, 0x1333: 0x000c, 0x1334: 0x000c, 0x1335: 0x000c, + 0x1336: 0x000c, 0x1337: 0x000c, 0x1338: 0x000c, 0x1339: 0x000c, 0x133b: 0x000c, + 0x133c: 0x000c, 0x133d: 0x000c, 0x133e: 0x000c, 0x133f: 0x000c, + // Block 0x4d, offset 0x1340 + 0x137d: 0x000a, 0x137f: 0x000a, + // Block 0x4e, offset 0x1380 + 0x1380: 0x000a, 0x1381: 0x000a, + 0x138d: 0x000a, 0x138e: 0x000a, 0x138f: 0x000a, + 0x139d: 0x000a, + 0x139e: 0x000a, 0x139f: 0x000a, + 0x13ad: 0x000a, 0x13ae: 0x000a, 0x13af: 0x000a, + 0x13bd: 0x000a, 0x13be: 0x000a, + // Block 0x4f, offset 0x13c0 + 0x13c0: 0x0009, 0x13c1: 0x0009, 0x13c2: 0x0009, 0x13c3: 0x0009, 0x13c4: 0x0009, 0x13c5: 0x0009, + 0x13c6: 0x0009, 0x13c7: 0x0009, 0x13c8: 0x0009, 0x13c9: 0x0009, 0x13ca: 0x0009, 0x13cb: 0x000b, + 0x13cc: 0x000b, 0x13cd: 0x000b, 0x13cf: 0x0001, 0x13d0: 0x000a, 0x13d1: 0x000a, + 0x13d2: 0x000a, 0x13d3: 0x000a, 0x13d4: 0x000a, 0x13d5: 0x000a, 0x13d6: 0x000a, 0x13d7: 0x000a, + 0x13d8: 0x000a, 0x13d9: 0x000a, 0x13da: 0x000a, 0x13db: 0x000a, 0x13dc: 0x000a, 0x13dd: 0x000a, + 0x13de: 0x000a, 0x13df: 0x000a, 0x13e0: 0x000a, 0x13e1: 0x000a, 0x13e2: 0x000a, 0x13e3: 0x000a, + 0x13e4: 0x000a, 0x13e5: 0x000a, 0x13e6: 0x000a, 0x13e7: 0x000a, 0x13e8: 0x0009, 0x13e9: 0x0007, + 0x13ea: 0x000e, 0x13eb: 0x000e, 0x13ec: 0x000e, 0x13ed: 0x000e, 0x13ee: 0x000e, 0x13ef: 0x0006, + 0x13f0: 0x0004, 0x13f1: 0x0004, 0x13f2: 0x0004, 0x13f3: 0x0004, 0x13f4: 0x0004, 0x13f5: 0x000a, + 0x13f6: 0x000a, 0x13f7: 0x000a, 0x13f8: 0x000a, 0x13f9: 0x000a, 0x13fa: 0x000a, 0x13fb: 0x000a, + 0x13fc: 0x000a, 0x13fd: 0x000a, 0x13fe: 0x000a, 0x13ff: 0x000a, + // Block 0x50, offset 0x1400 + 0x1400: 0x000a, 0x1401: 0x000a, 0x1402: 0x000a, 0x1403: 0x000a, 0x1404: 0x0006, 0x1405: 0x009a, + 0x1406: 0x008a, 0x1407: 0x000a, 0x1408: 0x000a, 0x1409: 0x000a, 0x140a: 0x000a, 0x140b: 0x000a, + 0x140c: 0x000a, 0x140d: 0x000a, 0x140e: 0x000a, 0x140f: 0x000a, 0x1410: 0x000a, 0x1411: 0x000a, + 0x1412: 0x000a, 0x1413: 0x000a, 0x1414: 0x000a, 0x1415: 0x000a, 0x1416: 0x000a, 0x1417: 0x000a, + 0x1418: 0x000a, 0x1419: 0x000a, 0x141a: 0x000a, 0x141b: 0x000a, 0x141c: 0x000a, 0x141d: 0x000a, + 0x141e: 0x000a, 0x141f: 0x0009, 0x1420: 0x000b, 0x1421: 0x000b, 0x1422: 0x000b, 0x1423: 0x000b, + 0x1424: 0x000b, 0x1425: 0x000b, 0x1426: 0x000e, 0x1427: 0x000e, 0x1428: 0x000e, 0x1429: 0x000e, + 0x142a: 0x000b, 0x142b: 0x000b, 0x142c: 0x000b, 0x142d: 0x000b, 0x142e: 0x000b, 0x142f: 0x000b, + 0x1430: 0x0002, 0x1434: 0x0002, 0x1435: 0x0002, + 0x1436: 0x0002, 0x1437: 0x0002, 0x1438: 0x0002, 0x1439: 0x0002, 0x143a: 0x0003, 0x143b: 0x0003, + 0x143c: 0x000a, 0x143d: 0x009a, 0x143e: 0x008a, + // Block 0x51, offset 0x1440 + 0x1440: 0x0002, 0x1441: 0x0002, 0x1442: 0x0002, 0x1443: 0x0002, 0x1444: 0x0002, 0x1445: 0x0002, + 0x1446: 0x0002, 0x1447: 0x0002, 0x1448: 0x0002, 0x1449: 0x0002, 0x144a: 0x0003, 0x144b: 0x0003, + 0x144c: 0x000a, 0x144d: 0x009a, 0x144e: 0x008a, + 0x1460: 0x0004, 0x1461: 0x0004, 0x1462: 0x0004, 0x1463: 0x0004, + 0x1464: 0x0004, 0x1465: 0x0004, 0x1466: 0x0004, 0x1467: 0x0004, 0x1468: 0x0004, 0x1469: 0x0004, + 0x146a: 0x0004, 0x146b: 0x0004, 0x146c: 0x0004, 0x146d: 0x0004, 0x146e: 0x0004, 0x146f: 0x0004, + 0x1470: 0x0004, 0x1471: 0x0004, 0x1472: 0x0004, 0x1473: 0x0004, 0x1474: 0x0004, 0x1475: 0x0004, + 0x1476: 0x0004, 0x1477: 0x0004, 0x1478: 0x0004, 0x1479: 0x0004, 0x147a: 0x0004, 0x147b: 0x0004, + 0x147c: 0x0004, 0x147d: 0x0004, 0x147e: 0x0004, 0x147f: 0x0004, + // Block 0x52, offset 0x1480 + 0x1480: 0x0004, 0x1481: 0x0004, 0x1482: 0x0004, 0x1483: 0x0004, 0x1484: 0x0004, 0x1485: 0x0004, + 0x1486: 0x0004, 0x1487: 0x0004, 0x1488: 0x0004, 0x1489: 0x0004, 0x148a: 0x0004, 0x148b: 0x0004, + 0x148c: 0x0004, 0x148d: 0x0004, 0x148e: 0x0004, 0x148f: 0x0004, 0x1490: 0x000c, 0x1491: 0x000c, + 0x1492: 0x000c, 0x1493: 0x000c, 0x1494: 0x000c, 0x1495: 0x000c, 0x1496: 0x000c, 0x1497: 0x000c, + 0x1498: 0x000c, 0x1499: 0x000c, 0x149a: 0x000c, 0x149b: 0x000c, 0x149c: 0x000c, 0x149d: 0x000c, + 0x149e: 0x000c, 0x149f: 0x000c, 0x14a0: 0x000c, 0x14a1: 0x000c, 0x14a2: 0x000c, 0x14a3: 0x000c, + 0x14a4: 0x000c, 0x14a5: 0x000c, 0x14a6: 0x000c, 0x14a7: 0x000c, 0x14a8: 0x000c, 0x14a9: 0x000c, + 0x14aa: 0x000c, 0x14ab: 0x000c, 0x14ac: 0x000c, 0x14ad: 0x000c, 0x14ae: 0x000c, 0x14af: 0x000c, + 0x14b0: 0x000c, + // Block 0x53, offset 0x14c0 + 0x14c0: 0x000a, 0x14c1: 0x000a, 0x14c3: 0x000a, 0x14c4: 0x000a, 0x14c5: 0x000a, + 0x14c6: 0x000a, 0x14c8: 0x000a, 0x14c9: 0x000a, + 0x14d4: 0x000a, 0x14d6: 0x000a, 0x14d7: 0x000a, + 0x14d8: 0x000a, + 0x14de: 0x000a, 0x14df: 0x000a, 0x14e0: 0x000a, 0x14e1: 0x000a, 0x14e2: 0x000a, 0x14e3: 0x000a, + 0x14e5: 0x000a, 0x14e7: 0x000a, 0x14e9: 0x000a, + 0x14ee: 0x0004, + 0x14fa: 0x000a, 0x14fb: 0x000a, + // Block 0x54, offset 0x1500 + 0x1500: 0x000a, 0x1501: 0x000a, 0x1502: 0x000a, 0x1503: 0x000a, 0x1504: 0x000a, + 0x150a: 0x000a, 0x150b: 0x000a, + 0x150c: 0x000a, 0x150d: 0x000a, 0x1510: 0x000a, 0x1511: 0x000a, + 0x1512: 0x000a, 0x1513: 0x000a, 0x1514: 0x000a, 0x1515: 0x000a, 0x1516: 0x000a, 0x1517: 0x000a, + 0x1518: 0x000a, 0x1519: 0x000a, 0x151a: 0x000a, 0x151b: 0x000a, 0x151c: 0x000a, 0x151d: 0x000a, + 0x151e: 0x000a, 0x151f: 0x000a, + // Block 0x55, offset 0x1540 + 0x1549: 0x000a, 0x154a: 0x000a, 0x154b: 0x000a, + 0x1550: 0x000a, 0x1551: 0x000a, + 0x1552: 0x000a, 0x1553: 0x000a, 0x1554: 0x000a, 0x1555: 0x000a, 0x1556: 0x000a, 0x1557: 0x000a, + 0x1558: 0x000a, 0x1559: 0x000a, 0x155a: 0x000a, 0x155b: 0x000a, 0x155c: 0x000a, 0x155d: 0x000a, + 0x155e: 0x000a, 0x155f: 0x000a, 0x1560: 0x000a, 0x1561: 0x000a, 0x1562: 0x000a, 0x1563: 0x000a, + 0x1564: 0x000a, 0x1565: 0x000a, 0x1566: 0x000a, 0x1567: 0x000a, 0x1568: 0x000a, 0x1569: 0x000a, + 0x156a: 0x000a, 0x156b: 0x000a, 0x156c: 0x000a, 0x156d: 0x000a, 0x156e: 0x000a, 0x156f: 0x000a, + 0x1570: 0x000a, 0x1571: 0x000a, 0x1572: 0x000a, 0x1573: 0x000a, 0x1574: 0x000a, 0x1575: 0x000a, + 0x1576: 0x000a, 0x1577: 0x000a, 0x1578: 0x000a, 0x1579: 0x000a, 0x157a: 0x000a, 0x157b: 0x000a, + 0x157c: 0x000a, 0x157d: 0x000a, 0x157e: 0x000a, 0x157f: 0x000a, + // Block 0x56, offset 0x1580 + 0x1580: 0x000a, 0x1581: 0x000a, 0x1582: 0x000a, 0x1583: 0x000a, 0x1584: 0x000a, 0x1585: 0x000a, + 0x1586: 0x000a, 0x1587: 0x000a, 0x1588: 0x000a, 0x1589: 0x000a, 0x158a: 0x000a, 0x158b: 0x000a, + 0x158c: 0x000a, 0x158d: 0x000a, 0x158e: 0x000a, 0x158f: 0x000a, 0x1590: 0x000a, 0x1591: 0x000a, + 0x1592: 0x000a, 0x1593: 0x000a, 0x1594: 0x000a, 0x1595: 0x000a, 0x1596: 0x000a, 0x1597: 0x000a, + 0x1598: 0x000a, 0x1599: 0x000a, 0x159a: 0x000a, 0x159b: 0x000a, 0x159c: 0x000a, 0x159d: 0x000a, + 0x159e: 0x000a, 0x159f: 0x000a, 0x15a0: 0x000a, 0x15a1: 0x000a, 0x15a2: 0x000a, 0x15a3: 0x000a, + 0x15a4: 0x000a, 0x15a5: 0x000a, 0x15a6: 0x000a, 0x15a7: 0x000a, 0x15a8: 0x000a, 0x15a9: 0x000a, + 0x15aa: 0x000a, 0x15ab: 0x000a, 0x15ac: 0x000a, 0x15ad: 0x000a, 0x15ae: 0x000a, 0x15af: 0x000a, + 0x15b0: 0x000a, 0x15b1: 0x000a, 0x15b2: 0x000a, 0x15b3: 0x000a, 0x15b4: 0x000a, 0x15b5: 0x000a, + 0x15b6: 0x000a, 0x15b7: 0x000a, 0x15b8: 0x000a, 0x15b9: 0x000a, 0x15ba: 0x000a, 0x15bb: 0x000a, + 0x15bc: 0x000a, 0x15bd: 0x000a, 0x15be: 0x000a, 0x15bf: 0x000a, + // Block 0x57, offset 0x15c0 + 0x15c0: 0x000a, 0x15c1: 0x000a, 0x15c2: 0x000a, 0x15c3: 0x000a, 0x15c4: 0x000a, 0x15c5: 0x000a, + 0x15c6: 0x000a, 0x15c7: 0x000a, 0x15c8: 0x000a, 0x15c9: 0x000a, 0x15ca: 0x000a, 0x15cb: 0x000a, + 0x15cc: 0x000a, 0x15cd: 0x000a, 0x15ce: 0x000a, 0x15cf: 0x000a, 0x15d0: 0x000a, 0x15d1: 0x000a, + 0x15d2: 0x0003, 0x15d3: 0x0004, 0x15d4: 0x000a, 0x15d5: 0x000a, 0x15d6: 0x000a, 0x15d7: 0x000a, + 0x15d8: 0x000a, 0x15d9: 0x000a, 0x15da: 0x000a, 0x15db: 0x000a, 0x15dc: 0x000a, 0x15dd: 0x000a, + 0x15de: 0x000a, 0x15df: 0x000a, 0x15e0: 0x000a, 0x15e1: 0x000a, 0x15e2: 0x000a, 0x15e3: 0x000a, + 0x15e4: 0x000a, 0x15e5: 0x000a, 0x15e6: 0x000a, 0x15e7: 0x000a, 0x15e8: 0x000a, 0x15e9: 0x000a, + 0x15ea: 0x000a, 0x15eb: 0x000a, 0x15ec: 0x000a, 0x15ed: 0x000a, 0x15ee: 0x000a, 0x15ef: 0x000a, + 0x15f0: 0x000a, 0x15f1: 0x000a, 0x15f2: 0x000a, 0x15f3: 0x000a, 0x15f4: 0x000a, 0x15f5: 0x000a, + 0x15f6: 0x000a, 0x15f7: 0x000a, 0x15f8: 0x000a, 0x15f9: 0x000a, 0x15fa: 0x000a, 0x15fb: 0x000a, + 0x15fc: 0x000a, 0x15fd: 0x000a, 0x15fe: 0x000a, 0x15ff: 0x000a, + // Block 0x58, offset 0x1600 + 0x1600: 0x000a, 0x1601: 0x000a, 0x1602: 0x000a, 0x1603: 0x000a, 0x1604: 0x000a, 0x1605: 0x000a, + 0x1606: 0x000a, 0x1607: 0x000a, 0x1608: 0x003a, 0x1609: 0x002a, 0x160a: 0x003a, 0x160b: 0x002a, + 0x160c: 0x000a, 0x160d: 0x000a, 0x160e: 0x000a, 0x160f: 0x000a, 0x1610: 0x000a, 0x1611: 0x000a, + 0x1612: 0x000a, 0x1613: 0x000a, 0x1614: 0x000a, 0x1615: 0x000a, 0x1616: 0x000a, 0x1617: 0x000a, + 0x1618: 0x000a, 0x1619: 0x000a, 0x161a: 0x000a, 0x161b: 0x000a, 0x161c: 0x000a, 0x161d: 0x000a, + 0x161e: 0x000a, 0x161f: 0x000a, 0x1620: 0x000a, 0x1621: 0x000a, 0x1622: 0x000a, 0x1623: 0x000a, + 0x1624: 0x000a, 0x1625: 0x000a, 0x1626: 0x000a, 0x1627: 0x000a, 0x1628: 0x000a, 0x1629: 0x009a, + 0x162a: 0x008a, 0x162b: 0x000a, 0x162c: 0x000a, 0x162d: 0x000a, 0x162e: 0x000a, 0x162f: 0x000a, + 0x1630: 0x000a, 0x1631: 0x000a, 0x1632: 0x000a, 0x1633: 0x000a, 0x1634: 0x000a, 0x1635: 0x000a, + // Block 0x59, offset 0x1640 + 0x167b: 0x000a, + 0x167c: 0x000a, 0x167d: 0x000a, 0x167e: 0x000a, 0x167f: 0x000a, + // Block 0x5a, offset 0x1680 + 0x1680: 0x000a, 0x1681: 0x000a, 0x1682: 0x000a, 0x1683: 0x000a, 0x1684: 0x000a, 0x1685: 0x000a, + 0x1686: 0x000a, 0x1687: 0x000a, 0x1688: 0x000a, 0x1689: 0x000a, 0x168a: 0x000a, 0x168b: 0x000a, + 0x168c: 0x000a, 0x168d: 0x000a, 0x168e: 0x000a, 0x168f: 0x000a, 0x1690: 0x000a, 0x1691: 0x000a, + 0x1692: 0x000a, 0x1693: 0x000a, 0x1694: 0x000a, 0x1696: 0x000a, 0x1697: 0x000a, + 0x1698: 0x000a, 0x1699: 0x000a, 0x169a: 0x000a, 0x169b: 0x000a, 0x169c: 0x000a, 0x169d: 0x000a, + 0x169e: 0x000a, 0x169f: 0x000a, 0x16a0: 0x000a, 0x16a1: 0x000a, 0x16a2: 0x000a, 0x16a3: 0x000a, + 0x16a4: 0x000a, 0x16a5: 0x000a, 0x16a6: 0x000a, 0x16a7: 0x000a, 0x16a8: 0x000a, 0x16a9: 0x000a, + 0x16aa: 0x000a, 0x16ab: 0x000a, 0x16ac: 0x000a, 0x16ad: 0x000a, 0x16ae: 0x000a, 0x16af: 0x000a, + 0x16b0: 0x000a, 0x16b1: 0x000a, 0x16b2: 0x000a, 0x16b3: 0x000a, 0x16b4: 0x000a, 0x16b5: 0x000a, + 0x16b6: 0x000a, 0x16b7: 0x000a, 0x16b8: 0x000a, 0x16b9: 0x000a, 0x16ba: 0x000a, 0x16bb: 0x000a, + 0x16bc: 0x000a, 0x16bd: 0x000a, 0x16be: 0x000a, 0x16bf: 0x000a, + // Block 0x5b, offset 0x16c0 + 0x16c0: 0x000a, 0x16c1: 0x000a, 0x16c2: 0x000a, 0x16c3: 0x000a, 0x16c4: 0x000a, 0x16c5: 0x000a, + 0x16c6: 0x000a, 0x16c7: 0x000a, 0x16c8: 0x000a, 0x16c9: 0x000a, 0x16ca: 0x000a, 0x16cb: 0x000a, + 0x16cc: 0x000a, 0x16cd: 0x000a, 0x16ce: 0x000a, 0x16cf: 0x000a, 0x16d0: 0x000a, 0x16d1: 0x000a, + 0x16d2: 0x000a, 0x16d3: 0x000a, 0x16d4: 0x000a, 0x16d5: 0x000a, 0x16d6: 0x000a, 0x16d7: 0x000a, + 0x16d8: 0x000a, 0x16d9: 0x000a, 0x16da: 0x000a, 0x16db: 0x000a, 0x16dc: 0x000a, 0x16dd: 0x000a, + 0x16de: 0x000a, 0x16df: 0x000a, 0x16e0: 0x000a, 0x16e1: 0x000a, 0x16e2: 0x000a, 0x16e3: 0x000a, + 0x16e4: 0x000a, 0x16e5: 0x000a, 0x16e6: 0x000a, + // Block 0x5c, offset 0x1700 + 0x1700: 0x000a, 0x1701: 0x000a, 0x1702: 0x000a, 0x1703: 0x000a, 0x1704: 0x000a, 0x1705: 0x000a, + 0x1706: 0x000a, 0x1707: 0x000a, 0x1708: 0x000a, 0x1709: 0x000a, 0x170a: 0x000a, + 0x1720: 0x000a, 0x1721: 0x000a, 0x1722: 0x000a, 0x1723: 0x000a, + 0x1724: 0x000a, 0x1725: 0x000a, 0x1726: 0x000a, 0x1727: 0x000a, 0x1728: 0x000a, 0x1729: 0x000a, + 0x172a: 0x000a, 0x172b: 0x000a, 0x172c: 0x000a, 0x172d: 0x000a, 0x172e: 0x000a, 0x172f: 0x000a, + 0x1730: 0x000a, 0x1731: 0x000a, 0x1732: 0x000a, 0x1733: 0x000a, 0x1734: 0x000a, 0x1735: 0x000a, + 0x1736: 0x000a, 0x1737: 0x000a, 0x1738: 0x000a, 0x1739: 0x000a, 0x173a: 0x000a, 0x173b: 0x000a, + 0x173c: 0x000a, 0x173d: 0x000a, 0x173e: 0x000a, 0x173f: 0x000a, + // Block 0x5d, offset 0x1740 + 0x1740: 0x000a, 0x1741: 0x000a, 0x1742: 0x000a, 0x1743: 0x000a, 0x1744: 0x000a, 0x1745: 0x000a, + 0x1746: 0x000a, 0x1747: 0x000a, 0x1748: 0x0002, 0x1749: 0x0002, 0x174a: 0x0002, 0x174b: 0x0002, + 0x174c: 0x0002, 0x174d: 0x0002, 0x174e: 0x0002, 0x174f: 0x0002, 0x1750: 0x0002, 0x1751: 0x0002, + 0x1752: 0x0002, 0x1753: 0x0002, 0x1754: 0x0002, 0x1755: 0x0002, 0x1756: 0x0002, 0x1757: 0x0002, + 0x1758: 0x0002, 0x1759: 0x0002, 0x175a: 0x0002, 0x175b: 0x0002, + // Block 0x5e, offset 0x1780 + 0x17aa: 0x000a, 0x17ab: 0x000a, 0x17ac: 0x000a, 0x17ad: 0x000a, 0x17ae: 0x000a, 0x17af: 0x000a, + 0x17b0: 0x000a, 0x17b1: 0x000a, 0x17b2: 0x000a, 0x17b3: 0x000a, 0x17b4: 0x000a, 0x17b5: 0x000a, + 0x17b6: 0x000a, 0x17b7: 0x000a, 0x17b8: 0x000a, 0x17b9: 0x000a, 0x17ba: 0x000a, 0x17bb: 0x000a, + 0x17bc: 0x000a, 0x17bd: 0x000a, 0x17be: 0x000a, 0x17bf: 0x000a, + // Block 0x5f, offset 0x17c0 + 0x17c0: 0x000a, 0x17c1: 0x000a, 0x17c2: 0x000a, 0x17c3: 0x000a, 0x17c4: 0x000a, 0x17c5: 0x000a, + 0x17c6: 0x000a, 0x17c7: 0x000a, 0x17c8: 0x000a, 0x17c9: 0x000a, 0x17ca: 0x000a, 0x17cb: 0x000a, + 0x17cc: 0x000a, 0x17cd: 0x000a, 0x17ce: 0x000a, 0x17cf: 0x000a, 0x17d0: 0x000a, 0x17d1: 0x000a, + 0x17d2: 0x000a, 0x17d3: 0x000a, 0x17d4: 0x000a, 0x17d5: 0x000a, 0x17d6: 0x000a, 0x17d7: 0x000a, + 0x17d8: 0x000a, 0x17d9: 0x000a, 0x17da: 0x000a, 0x17db: 0x000a, 0x17dc: 0x000a, 0x17dd: 0x000a, + 0x17de: 0x000a, 0x17df: 0x000a, 0x17e0: 0x000a, 0x17e1: 0x000a, 0x17e2: 0x000a, 0x17e3: 0x000a, + 0x17e4: 0x000a, 0x17e5: 0x000a, 0x17e6: 0x000a, 0x17e7: 0x000a, 0x17e8: 0x000a, 0x17e9: 0x000a, + 0x17ea: 0x000a, 0x17eb: 0x000a, 0x17ed: 0x000a, 0x17ee: 0x000a, 0x17ef: 0x000a, + 0x17f0: 0x000a, 0x17f1: 0x000a, 0x17f2: 0x000a, 0x17f3: 0x000a, 0x17f4: 0x000a, 0x17f5: 0x000a, + 0x17f6: 0x000a, 0x17f7: 0x000a, 0x17f8: 0x000a, 0x17f9: 0x000a, 0x17fa: 0x000a, 0x17fb: 0x000a, + 0x17fc: 0x000a, 0x17fd: 0x000a, 0x17fe: 0x000a, 0x17ff: 0x000a, + // Block 0x60, offset 0x1800 + 0x1800: 0x000a, 0x1801: 0x000a, 0x1802: 0x000a, 0x1803: 0x000a, 0x1804: 0x000a, 0x1805: 0x000a, + 0x1806: 0x000a, 0x1807: 0x000a, 0x1808: 0x000a, 0x1809: 0x000a, 0x180a: 0x000a, 0x180b: 0x000a, + 0x180c: 0x000a, 0x180d: 0x000a, 0x180e: 0x000a, 0x180f: 0x000a, 0x1810: 0x000a, 0x1811: 0x000a, + 0x1812: 0x000a, 0x1813: 0x000a, 0x1814: 0x000a, 0x1815: 0x000a, 0x1816: 0x000a, 0x1817: 0x000a, + 0x1818: 0x000a, 0x1819: 0x000a, 0x181a: 0x000a, 0x181b: 0x000a, 0x181c: 0x000a, 0x181d: 0x000a, + 0x181e: 0x000a, 0x181f: 0x000a, 0x1820: 0x000a, 0x1821: 0x000a, 0x1822: 0x000a, 0x1823: 0x000a, + 0x1824: 0x000a, 0x1825: 0x000a, 0x1826: 0x000a, 0x1827: 0x000a, 0x1828: 0x003a, 0x1829: 0x002a, + 0x182a: 0x003a, 0x182b: 0x002a, 0x182c: 0x003a, 0x182d: 0x002a, 0x182e: 0x003a, 0x182f: 0x002a, + 0x1830: 0x003a, 0x1831: 0x002a, 0x1832: 0x003a, 0x1833: 0x002a, 0x1834: 0x003a, 0x1835: 0x002a, + 0x1836: 0x000a, 0x1837: 0x000a, 0x1838: 0x000a, 0x1839: 0x000a, 0x183a: 0x000a, 0x183b: 0x000a, + 0x183c: 0x000a, 0x183d: 0x000a, 0x183e: 0x000a, 0x183f: 0x000a, + // Block 0x61, offset 0x1840 + 0x1840: 0x000a, 0x1841: 0x000a, 0x1842: 0x000a, 0x1843: 0x000a, 0x1844: 0x000a, 0x1845: 0x009a, + 0x1846: 0x008a, 0x1847: 0x000a, 0x1848: 0x000a, 0x1849: 0x000a, 0x184a: 0x000a, 0x184b: 0x000a, + 0x184c: 0x000a, 0x184d: 0x000a, 0x184e: 0x000a, 0x184f: 0x000a, 0x1850: 0x000a, 0x1851: 0x000a, + 0x1852: 0x000a, 0x1853: 0x000a, 0x1854: 0x000a, 0x1855: 0x000a, 0x1856: 0x000a, 0x1857: 0x000a, + 0x1858: 0x000a, 0x1859: 0x000a, 0x185a: 0x000a, 0x185b: 0x000a, 0x185c: 0x000a, 0x185d: 0x000a, + 0x185e: 0x000a, 0x185f: 0x000a, 0x1860: 0x000a, 0x1861: 0x000a, 0x1862: 0x000a, 0x1863: 0x000a, + 0x1864: 0x000a, 0x1865: 0x000a, 0x1866: 0x003a, 0x1867: 0x002a, 0x1868: 0x003a, 0x1869: 0x002a, + 0x186a: 0x003a, 0x186b: 0x002a, 0x186c: 0x003a, 0x186d: 0x002a, 0x186e: 0x003a, 0x186f: 0x002a, + 0x1870: 0x000a, 0x1871: 0x000a, 0x1872: 0x000a, 0x1873: 0x000a, 0x1874: 0x000a, 0x1875: 0x000a, + 0x1876: 0x000a, 0x1877: 0x000a, 0x1878: 0x000a, 0x1879: 0x000a, 0x187a: 0x000a, 0x187b: 0x000a, + 0x187c: 0x000a, 0x187d: 0x000a, 0x187e: 0x000a, 0x187f: 0x000a, + // Block 0x62, offset 0x1880 + 0x1880: 0x000a, 0x1881: 0x000a, 0x1882: 0x000a, 0x1883: 0x007a, 0x1884: 0x006a, 0x1885: 0x009a, + 0x1886: 0x008a, 0x1887: 0x00ba, 0x1888: 0x00aa, 0x1889: 0x009a, 0x188a: 0x008a, 0x188b: 0x007a, + 0x188c: 0x006a, 0x188d: 0x00da, 0x188e: 0x002a, 0x188f: 0x003a, 0x1890: 0x00ca, 0x1891: 0x009a, + 0x1892: 0x008a, 0x1893: 0x007a, 0x1894: 0x006a, 0x1895: 0x009a, 0x1896: 0x008a, 0x1897: 0x00ba, + 0x1898: 0x00aa, 0x1899: 0x000a, 0x189a: 0x000a, 0x189b: 0x000a, 0x189c: 0x000a, 0x189d: 0x000a, + 0x189e: 0x000a, 0x189f: 0x000a, 0x18a0: 0x000a, 0x18a1: 0x000a, 0x18a2: 0x000a, 0x18a3: 0x000a, + 0x18a4: 0x000a, 0x18a5: 0x000a, 0x18a6: 0x000a, 0x18a7: 0x000a, 0x18a8: 0x000a, 0x18a9: 0x000a, + 0x18aa: 0x000a, 0x18ab: 0x000a, 0x18ac: 0x000a, 0x18ad: 0x000a, 0x18ae: 0x000a, 0x18af: 0x000a, + 0x18b0: 0x000a, 0x18b1: 0x000a, 0x18b2: 0x000a, 0x18b3: 0x000a, 0x18b4: 0x000a, 0x18b5: 0x000a, + 0x18b6: 0x000a, 0x18b7: 0x000a, 0x18b8: 0x000a, 0x18b9: 0x000a, 0x18ba: 0x000a, 0x18bb: 0x000a, + 0x18bc: 0x000a, 0x18bd: 0x000a, 0x18be: 0x000a, 0x18bf: 0x000a, + // Block 0x63, offset 0x18c0 + 0x18c0: 0x000a, 0x18c1: 0x000a, 0x18c2: 0x000a, 0x18c3: 0x000a, 0x18c4: 0x000a, 0x18c5: 0x000a, + 0x18c6: 0x000a, 0x18c7: 0x000a, 0x18c8: 0x000a, 0x18c9: 0x000a, 0x18ca: 0x000a, 0x18cb: 0x000a, + 0x18cc: 0x000a, 0x18cd: 0x000a, 0x18ce: 0x000a, 0x18cf: 0x000a, 0x18d0: 0x000a, 0x18d1: 0x000a, + 0x18d2: 0x000a, 0x18d3: 0x000a, 0x18d4: 0x000a, 0x18d5: 0x000a, 0x18d6: 0x000a, 0x18d7: 0x000a, + 0x18d8: 0x003a, 0x18d9: 0x002a, 0x18da: 0x003a, 0x18db: 0x002a, 0x18dc: 0x000a, 0x18dd: 0x000a, + 0x18de: 0x000a, 0x18df: 0x000a, 0x18e0: 0x000a, 0x18e1: 0x000a, 0x18e2: 0x000a, 0x18e3: 0x000a, + 0x18e4: 0x000a, 0x18e5: 0x000a, 0x18e6: 0x000a, 0x18e7: 0x000a, 0x18e8: 0x000a, 0x18e9: 0x000a, + 0x18ea: 0x000a, 0x18eb: 0x000a, 0x18ec: 0x000a, 0x18ed: 0x000a, 0x18ee: 0x000a, 0x18ef: 0x000a, + 0x18f0: 0x000a, 0x18f1: 0x000a, 0x18f2: 0x000a, 0x18f3: 0x000a, 0x18f4: 0x000a, 0x18f5: 0x000a, + 0x18f6: 0x000a, 0x18f7: 0x000a, 0x18f8: 0x000a, 0x18f9: 0x000a, 0x18fa: 0x000a, 0x18fb: 0x000a, + 0x18fc: 0x003a, 0x18fd: 0x002a, 0x18fe: 0x000a, 0x18ff: 0x000a, + // Block 0x64, offset 0x1900 + 0x1900: 0x000a, 0x1901: 0x000a, 0x1902: 0x000a, 0x1903: 0x000a, 0x1904: 0x000a, 0x1905: 0x000a, + 0x1906: 0x000a, 0x1907: 0x000a, 0x1908: 0x000a, 0x1909: 0x000a, 0x190a: 0x000a, 0x190b: 0x000a, + 0x190c: 0x000a, 0x190d: 0x000a, 0x190e: 0x000a, 0x190f: 0x000a, 0x1910: 0x000a, 0x1911: 0x000a, + 0x1912: 0x000a, 0x1913: 0x000a, 0x1914: 0x000a, 0x1915: 0x000a, 0x1916: 0x000a, 0x1917: 0x000a, + 0x1918: 0x000a, 0x1919: 0x000a, 0x191a: 0x000a, 0x191b: 0x000a, 0x191c: 0x000a, 0x191d: 0x000a, + 0x191e: 0x000a, 0x191f: 0x000a, 0x1920: 0x000a, 0x1921: 0x000a, 0x1922: 0x000a, 0x1923: 0x000a, + 0x1924: 0x000a, 0x1925: 0x000a, 0x1926: 0x000a, 0x1927: 0x000a, 0x1928: 0x000a, 0x1929: 0x000a, + 0x192a: 0x000a, 0x192b: 0x000a, 0x192c: 0x000a, 0x192d: 0x000a, 0x192e: 0x000a, 0x192f: 0x000a, + 0x1930: 0x000a, 0x1931: 0x000a, 0x1932: 0x000a, 0x1933: 0x000a, + 0x1936: 0x000a, 0x1937: 0x000a, 0x1938: 0x000a, 0x1939: 0x000a, 0x193a: 0x000a, 0x193b: 0x000a, + 0x193c: 0x000a, 0x193d: 0x000a, 0x193e: 0x000a, 0x193f: 0x000a, + // Block 0x65, offset 0x1940 + 0x1940: 0x000a, 0x1941: 0x000a, 0x1942: 0x000a, 0x1943: 0x000a, 0x1944: 0x000a, 0x1945: 0x000a, + 0x1946: 0x000a, 0x1947: 0x000a, 0x1948: 0x000a, 0x1949: 0x000a, 0x194a: 0x000a, 0x194b: 0x000a, + 0x194c: 0x000a, 0x194d: 0x000a, 0x194e: 0x000a, 0x194f: 0x000a, 0x1950: 0x000a, 0x1951: 0x000a, + 0x1952: 0x000a, 0x1953: 0x000a, 0x1954: 0x000a, 0x1955: 0x000a, + 0x1958: 0x000a, 0x1959: 0x000a, 0x195a: 0x000a, 0x195b: 0x000a, 0x195c: 0x000a, 0x195d: 0x000a, + 0x195e: 0x000a, 0x195f: 0x000a, 0x1960: 0x000a, 0x1961: 0x000a, 0x1962: 0x000a, 0x1963: 0x000a, + 0x1964: 0x000a, 0x1965: 0x000a, 0x1966: 0x000a, 0x1967: 0x000a, 0x1968: 0x000a, 0x1969: 0x000a, + 0x196a: 0x000a, 0x196b: 0x000a, 0x196c: 0x000a, 0x196d: 0x000a, 0x196e: 0x000a, 0x196f: 0x000a, + 0x1970: 0x000a, 0x1971: 0x000a, 0x1972: 0x000a, 0x1973: 0x000a, 0x1974: 0x000a, 0x1975: 0x000a, + 0x1976: 0x000a, 0x1977: 0x000a, 0x1978: 0x000a, 0x1979: 0x000a, + 0x197d: 0x000a, 0x197e: 0x000a, 0x197f: 0x000a, + // Block 0x66, offset 0x1980 + 0x1980: 0x000a, 0x1981: 0x000a, 0x1982: 0x000a, 0x1983: 0x000a, 0x1984: 0x000a, 0x1985: 0x000a, + 0x1986: 0x000a, 0x1987: 0x000a, 0x1988: 0x000a, 0x198a: 0x000a, 0x198b: 0x000a, + 0x198c: 0x000a, 0x198d: 0x000a, 0x198e: 0x000a, 0x198f: 0x000a, 0x1990: 0x000a, 0x1991: 0x000a, + 0x1992: 0x000a, + 0x19ac: 0x000a, 0x19ad: 0x000a, 0x19ae: 0x000a, 0x19af: 0x000a, + // Block 0x67, offset 0x19c0 + 0x19e5: 0x000a, 0x19e6: 0x000a, 0x19e7: 0x000a, 0x19e8: 0x000a, 0x19e9: 0x000a, + 0x19ea: 0x000a, 0x19ef: 0x000c, + 0x19f0: 0x000c, 0x19f1: 0x000c, + 0x19f9: 0x000a, 0x19fa: 0x000a, 0x19fb: 0x000a, + 0x19fc: 0x000a, 0x19fd: 0x000a, 0x19fe: 0x000a, 0x19ff: 0x000a, + // Block 0x68, offset 0x1a00 + 0x1a3f: 0x000c, + // Block 0x69, offset 0x1a40 + 0x1a60: 0x000c, 0x1a61: 0x000c, 0x1a62: 0x000c, 0x1a63: 0x000c, + 0x1a64: 0x000c, 0x1a65: 0x000c, 0x1a66: 0x000c, 0x1a67: 0x000c, 0x1a68: 0x000c, 0x1a69: 0x000c, + 0x1a6a: 0x000c, 0x1a6b: 0x000c, 0x1a6c: 0x000c, 0x1a6d: 0x000c, 0x1a6e: 0x000c, 0x1a6f: 0x000c, + 0x1a70: 0x000c, 0x1a71: 0x000c, 0x1a72: 0x000c, 0x1a73: 0x000c, 0x1a74: 0x000c, 0x1a75: 0x000c, + 0x1a76: 0x000c, 0x1a77: 0x000c, 0x1a78: 0x000c, 0x1a79: 0x000c, 0x1a7a: 0x000c, 0x1a7b: 0x000c, + 0x1a7c: 0x000c, 0x1a7d: 0x000c, 0x1a7e: 0x000c, 0x1a7f: 0x000c, + // Block 0x6a, offset 0x1a80 + 0x1a80: 0x000a, 0x1a81: 0x000a, 0x1a82: 0x000a, 0x1a83: 0x000a, 0x1a84: 0x000a, 0x1a85: 0x000a, + 0x1a86: 0x000a, 0x1a87: 0x000a, 0x1a88: 0x000a, 0x1a89: 0x000a, 0x1a8a: 0x000a, 0x1a8b: 0x000a, + 0x1a8c: 0x000a, 0x1a8d: 0x000a, 0x1a8e: 0x000a, 0x1a8f: 0x000a, 0x1a90: 0x000a, 0x1a91: 0x000a, + 0x1a92: 0x000a, 0x1a93: 0x000a, 0x1a94: 0x000a, 0x1a95: 0x000a, 0x1a96: 0x000a, 0x1a97: 0x000a, + 0x1a98: 0x000a, 0x1a99: 0x000a, 0x1a9a: 0x000a, 0x1a9b: 0x000a, 0x1a9c: 0x000a, 0x1a9d: 0x000a, + 0x1a9e: 0x000a, 0x1a9f: 0x000a, 0x1aa0: 0x000a, 0x1aa1: 0x000a, 0x1aa2: 0x003a, 0x1aa3: 0x002a, + 0x1aa4: 0x003a, 0x1aa5: 0x002a, 0x1aa6: 0x003a, 0x1aa7: 0x002a, 0x1aa8: 0x003a, 0x1aa9: 0x002a, + 0x1aaa: 0x000a, 0x1aab: 0x000a, 0x1aac: 0x000a, 0x1aad: 0x000a, 0x1aae: 0x000a, 0x1aaf: 0x000a, + 0x1ab0: 0x000a, 0x1ab1: 0x000a, 0x1ab2: 0x000a, 0x1ab3: 0x000a, 0x1ab4: 0x000a, 0x1ab5: 0x000a, + 0x1ab6: 0x000a, 0x1ab7: 0x000a, 0x1ab8: 0x000a, 0x1ab9: 0x000a, 0x1aba: 0x000a, 0x1abb: 0x000a, + 0x1abc: 0x000a, 0x1abd: 0x000a, 0x1abe: 0x000a, 0x1abf: 0x000a, + // Block 0x6b, offset 0x1ac0 + 0x1ac0: 0x000a, 0x1ac1: 0x000a, 0x1ac2: 0x000a, 0x1ac3: 0x000a, 0x1ac4: 0x000a, 0x1ac5: 0x000a, + 0x1ac6: 0x000a, 0x1ac7: 0x000a, 0x1ac8: 0x000a, 0x1ac9: 0x000a, + // Block 0x6c, offset 0x1b00 + 0x1b00: 0x000a, 0x1b01: 0x000a, 0x1b02: 0x000a, 0x1b03: 0x000a, 0x1b04: 0x000a, 0x1b05: 0x000a, + 0x1b06: 0x000a, 0x1b07: 0x000a, 0x1b08: 0x000a, 0x1b09: 0x000a, 0x1b0a: 0x000a, 0x1b0b: 0x000a, + 0x1b0c: 0x000a, 0x1b0d: 0x000a, 0x1b0e: 0x000a, 0x1b0f: 0x000a, 0x1b10: 0x000a, 0x1b11: 0x000a, + 0x1b12: 0x000a, 0x1b13: 0x000a, 0x1b14: 0x000a, 0x1b15: 0x000a, 0x1b16: 0x000a, 0x1b17: 0x000a, + 0x1b18: 0x000a, 0x1b19: 0x000a, 0x1b1b: 0x000a, 0x1b1c: 0x000a, 0x1b1d: 0x000a, + 0x1b1e: 0x000a, 0x1b1f: 0x000a, 0x1b20: 0x000a, 0x1b21: 0x000a, 0x1b22: 0x000a, 0x1b23: 0x000a, + 0x1b24: 0x000a, 0x1b25: 0x000a, 0x1b26: 0x000a, 0x1b27: 0x000a, 0x1b28: 0x000a, 0x1b29: 0x000a, + 0x1b2a: 0x000a, 0x1b2b: 0x000a, 0x1b2c: 0x000a, 0x1b2d: 0x000a, 0x1b2e: 0x000a, 0x1b2f: 0x000a, + 0x1b30: 0x000a, 0x1b31: 0x000a, 0x1b32: 0x000a, 0x1b33: 0x000a, 0x1b34: 0x000a, 0x1b35: 0x000a, + 0x1b36: 0x000a, 0x1b37: 0x000a, 0x1b38: 0x000a, 0x1b39: 0x000a, 0x1b3a: 0x000a, 0x1b3b: 0x000a, + 0x1b3c: 0x000a, 0x1b3d: 0x000a, 0x1b3e: 0x000a, 0x1b3f: 0x000a, + // Block 0x6d, offset 0x1b40 + 0x1b40: 0x000a, 0x1b41: 0x000a, 0x1b42: 0x000a, 0x1b43: 0x000a, 0x1b44: 0x000a, 0x1b45: 0x000a, + 0x1b46: 0x000a, 0x1b47: 0x000a, 0x1b48: 0x000a, 0x1b49: 0x000a, 0x1b4a: 0x000a, 0x1b4b: 0x000a, + 0x1b4c: 0x000a, 0x1b4d: 0x000a, 0x1b4e: 0x000a, 0x1b4f: 0x000a, 0x1b50: 0x000a, 0x1b51: 0x000a, + 0x1b52: 0x000a, 0x1b53: 0x000a, 0x1b54: 0x000a, 0x1b55: 0x000a, 0x1b56: 0x000a, 0x1b57: 0x000a, + 0x1b58: 0x000a, 0x1b59: 0x000a, 0x1b5a: 0x000a, 0x1b5b: 0x000a, 0x1b5c: 0x000a, 0x1b5d: 0x000a, + 0x1b5e: 0x000a, 0x1b5f: 0x000a, 0x1b60: 0x000a, 0x1b61: 0x000a, 0x1b62: 0x000a, 0x1b63: 0x000a, + 0x1b64: 0x000a, 0x1b65: 0x000a, 0x1b66: 0x000a, 0x1b67: 0x000a, 0x1b68: 0x000a, 0x1b69: 0x000a, + 0x1b6a: 0x000a, 0x1b6b: 0x000a, 0x1b6c: 0x000a, 0x1b6d: 0x000a, 0x1b6e: 0x000a, 0x1b6f: 0x000a, + 0x1b70: 0x000a, 0x1b71: 0x000a, 0x1b72: 0x000a, 0x1b73: 0x000a, + // Block 0x6e, offset 0x1b80 + 0x1b80: 0x000a, 0x1b81: 0x000a, 0x1b82: 0x000a, 0x1b83: 0x000a, 0x1b84: 0x000a, 0x1b85: 0x000a, + 0x1b86: 0x000a, 0x1b87: 0x000a, 0x1b88: 0x000a, 0x1b89: 0x000a, 0x1b8a: 0x000a, 0x1b8b: 0x000a, + 0x1b8c: 0x000a, 0x1b8d: 0x000a, 0x1b8e: 0x000a, 0x1b8f: 0x000a, 0x1b90: 0x000a, 0x1b91: 0x000a, + 0x1b92: 0x000a, 0x1b93: 0x000a, 0x1b94: 0x000a, 0x1b95: 0x000a, + 0x1bb0: 0x000a, 0x1bb1: 0x000a, 0x1bb2: 0x000a, 0x1bb3: 0x000a, 0x1bb4: 0x000a, 0x1bb5: 0x000a, + 0x1bb6: 0x000a, 0x1bb7: 0x000a, 0x1bb8: 0x000a, 0x1bb9: 0x000a, 0x1bba: 0x000a, 0x1bbb: 0x000a, + // Block 0x6f, offset 0x1bc0 + 0x1bc0: 0x0009, 0x1bc1: 0x000a, 0x1bc2: 0x000a, 0x1bc3: 0x000a, 0x1bc4: 0x000a, + 0x1bc8: 0x003a, 0x1bc9: 0x002a, 0x1bca: 0x003a, 0x1bcb: 0x002a, + 0x1bcc: 0x003a, 0x1bcd: 0x002a, 0x1bce: 0x003a, 0x1bcf: 0x002a, 0x1bd0: 0x003a, 0x1bd1: 0x002a, + 0x1bd2: 0x000a, 0x1bd3: 0x000a, 0x1bd4: 0x003a, 0x1bd5: 0x002a, 0x1bd6: 0x003a, 0x1bd7: 0x002a, + 0x1bd8: 0x003a, 0x1bd9: 0x002a, 0x1bda: 0x003a, 0x1bdb: 0x002a, 0x1bdc: 0x000a, 0x1bdd: 0x000a, + 0x1bde: 0x000a, 0x1bdf: 0x000a, 0x1be0: 0x000a, + 0x1bea: 0x000c, 0x1beb: 0x000c, 0x1bec: 0x000c, 0x1bed: 0x000c, + 0x1bf0: 0x000a, + 0x1bf6: 0x000a, 0x1bf7: 0x000a, + 0x1bfd: 0x000a, 0x1bfe: 0x000a, 0x1bff: 0x000a, + // Block 0x70, offset 0x1c00 + 0x1c19: 0x000c, 0x1c1a: 0x000c, 0x1c1b: 0x000a, 0x1c1c: 0x000a, + 0x1c20: 0x000a, + // Block 0x71, offset 0x1c40 + 0x1c7b: 0x000a, + // Block 0x72, offset 0x1c80 + 0x1c80: 0x000a, 0x1c81: 0x000a, 0x1c82: 0x000a, 0x1c83: 0x000a, 0x1c84: 0x000a, 0x1c85: 0x000a, + 0x1c86: 0x000a, 0x1c87: 0x000a, 0x1c88: 0x000a, 0x1c89: 0x000a, 0x1c8a: 0x000a, 0x1c8b: 0x000a, + 0x1c8c: 0x000a, 0x1c8d: 0x000a, 0x1c8e: 0x000a, 0x1c8f: 0x000a, 0x1c90: 0x000a, 0x1c91: 0x000a, + 0x1c92: 0x000a, 0x1c93: 0x000a, 0x1c94: 0x000a, 0x1c95: 0x000a, 0x1c96: 0x000a, 0x1c97: 0x000a, + 0x1c98: 0x000a, 0x1c99: 0x000a, 0x1c9a: 0x000a, 0x1c9b: 0x000a, 0x1c9c: 0x000a, 0x1c9d: 0x000a, + 0x1c9e: 0x000a, 0x1c9f: 0x000a, 0x1ca0: 0x000a, 0x1ca1: 0x000a, 0x1ca2: 0x000a, 0x1ca3: 0x000a, + // Block 0x73, offset 0x1cc0 + 0x1cdd: 0x000a, + 0x1cde: 0x000a, + // Block 0x74, offset 0x1d00 + 0x1d10: 0x000a, 0x1d11: 0x000a, + 0x1d12: 0x000a, 0x1d13: 0x000a, 0x1d14: 0x000a, 0x1d15: 0x000a, 0x1d16: 0x000a, 0x1d17: 0x000a, + 0x1d18: 0x000a, 0x1d19: 0x000a, 0x1d1a: 0x000a, 0x1d1b: 0x000a, 0x1d1c: 0x000a, 0x1d1d: 0x000a, + 0x1d1e: 0x000a, 0x1d1f: 0x000a, + 0x1d3c: 0x000a, 0x1d3d: 0x000a, 0x1d3e: 0x000a, + // Block 0x75, offset 0x1d40 + 0x1d71: 0x000a, 0x1d72: 0x000a, 0x1d73: 0x000a, 0x1d74: 0x000a, 0x1d75: 0x000a, + 0x1d76: 0x000a, 0x1d77: 0x000a, 0x1d78: 0x000a, 0x1d79: 0x000a, 0x1d7a: 0x000a, 0x1d7b: 0x000a, + 0x1d7c: 0x000a, 0x1d7d: 0x000a, 0x1d7e: 0x000a, 0x1d7f: 0x000a, + // Block 0x76, offset 0x1d80 + 0x1d8c: 0x000a, 0x1d8d: 0x000a, 0x1d8e: 0x000a, 0x1d8f: 0x000a, + // Block 0x77, offset 0x1dc0 + 0x1df7: 0x000a, 0x1df8: 0x000a, 0x1df9: 0x000a, 0x1dfa: 0x000a, + // Block 0x78, offset 0x1e00 + 0x1e1e: 0x000a, 0x1e1f: 0x000a, + 0x1e3f: 0x000a, + // Block 0x79, offset 0x1e40 + 0x1e50: 0x000a, 0x1e51: 0x000a, + 0x1e52: 0x000a, 0x1e53: 0x000a, 0x1e54: 0x000a, 0x1e55: 0x000a, 0x1e56: 0x000a, 0x1e57: 0x000a, + 0x1e58: 0x000a, 0x1e59: 0x000a, 0x1e5a: 0x000a, 0x1e5b: 0x000a, 0x1e5c: 0x000a, 0x1e5d: 0x000a, + 0x1e5e: 0x000a, 0x1e5f: 0x000a, 0x1e60: 0x000a, 0x1e61: 0x000a, 0x1e62: 0x000a, 0x1e63: 0x000a, + 0x1e64: 0x000a, 0x1e65: 0x000a, 0x1e66: 0x000a, 0x1e67: 0x000a, 0x1e68: 0x000a, 0x1e69: 0x000a, + 0x1e6a: 0x000a, 0x1e6b: 0x000a, 0x1e6c: 0x000a, 0x1e6d: 0x000a, 0x1e6e: 0x000a, 0x1e6f: 0x000a, + 0x1e70: 0x000a, 0x1e71: 0x000a, 0x1e72: 0x000a, 0x1e73: 0x000a, 0x1e74: 0x000a, 0x1e75: 0x000a, + 0x1e76: 0x000a, 0x1e77: 0x000a, 0x1e78: 0x000a, 0x1e79: 0x000a, 0x1e7a: 0x000a, 0x1e7b: 0x000a, + 0x1e7c: 0x000a, 0x1e7d: 0x000a, 0x1e7e: 0x000a, 0x1e7f: 0x000a, + // Block 0x7a, offset 0x1e80 + 0x1e80: 0x000a, 0x1e81: 0x000a, 0x1e82: 0x000a, 0x1e83: 0x000a, 0x1e84: 0x000a, 0x1e85: 0x000a, + 0x1e86: 0x000a, + // Block 0x7b, offset 0x1ec0 + 0x1ecd: 0x000a, 0x1ece: 0x000a, 0x1ecf: 0x000a, + // Block 0x7c, offset 0x1f00 + 0x1f2f: 0x000c, + 0x1f30: 0x000c, 0x1f31: 0x000c, 0x1f32: 0x000c, 0x1f33: 0x000a, 0x1f34: 0x000c, 0x1f35: 0x000c, + 0x1f36: 0x000c, 0x1f37: 0x000c, 0x1f38: 0x000c, 0x1f39: 0x000c, 0x1f3a: 0x000c, 0x1f3b: 0x000c, + 0x1f3c: 0x000c, 0x1f3d: 0x000c, 0x1f3e: 0x000a, 0x1f3f: 0x000a, + // Block 0x7d, offset 0x1f40 + 0x1f5e: 0x000c, 0x1f5f: 0x000c, + // Block 0x7e, offset 0x1f80 + 0x1fb0: 0x000c, 0x1fb1: 0x000c, + // Block 0x7f, offset 0x1fc0 + 0x1fc0: 0x000a, 0x1fc1: 0x000a, 0x1fc2: 0x000a, 0x1fc3: 0x000a, 0x1fc4: 0x000a, 0x1fc5: 0x000a, + 0x1fc6: 0x000a, 0x1fc7: 0x000a, 0x1fc8: 0x000a, 0x1fc9: 0x000a, 0x1fca: 0x000a, 0x1fcb: 0x000a, + 0x1fcc: 0x000a, 0x1fcd: 0x000a, 0x1fce: 0x000a, 0x1fcf: 0x000a, 0x1fd0: 0x000a, 0x1fd1: 0x000a, + 0x1fd2: 0x000a, 0x1fd3: 0x000a, 0x1fd4: 0x000a, 0x1fd5: 0x000a, 0x1fd6: 0x000a, 0x1fd7: 0x000a, + 0x1fd8: 0x000a, 0x1fd9: 0x000a, 0x1fda: 0x000a, 0x1fdb: 0x000a, 0x1fdc: 0x000a, 0x1fdd: 0x000a, + 0x1fde: 0x000a, 0x1fdf: 0x000a, 0x1fe0: 0x000a, 0x1fe1: 0x000a, + // Block 0x80, offset 0x2000 + 0x2008: 0x000a, + // Block 0x81, offset 0x2040 + 0x2042: 0x000c, + 0x2046: 0x000c, 0x204b: 0x000c, + 0x2065: 0x000c, 0x2066: 0x000c, 0x2068: 0x000a, 0x2069: 0x000a, + 0x206a: 0x000a, 0x206b: 0x000a, + 0x2078: 0x0004, 0x2079: 0x0004, + // Block 0x82, offset 0x2080 + 0x20b4: 0x000a, 0x20b5: 0x000a, + 0x20b6: 0x000a, 0x20b7: 0x000a, + // Block 0x83, offset 0x20c0 + 0x20c4: 0x000c, 0x20c5: 0x000c, + 0x20e0: 0x000c, 0x20e1: 0x000c, 0x20e2: 0x000c, 0x20e3: 0x000c, + 0x20e4: 0x000c, 0x20e5: 0x000c, 0x20e6: 0x000c, 0x20e7: 0x000c, 0x20e8: 0x000c, 0x20e9: 0x000c, + 0x20ea: 0x000c, 0x20eb: 0x000c, 0x20ec: 0x000c, 0x20ed: 0x000c, 0x20ee: 0x000c, 0x20ef: 0x000c, + 0x20f0: 0x000c, 0x20f1: 0x000c, + // Block 0x84, offset 0x2100 + 0x2126: 0x000c, 0x2127: 0x000c, 0x2128: 0x000c, 0x2129: 0x000c, + 0x212a: 0x000c, 0x212b: 0x000c, 0x212c: 0x000c, 0x212d: 0x000c, + // Block 0x85, offset 0x2140 + 0x2147: 0x000c, 0x2148: 0x000c, 0x2149: 0x000c, 0x214a: 0x000c, 0x214b: 0x000c, + 0x214c: 0x000c, 0x214d: 0x000c, 0x214e: 0x000c, 0x214f: 0x000c, 0x2150: 0x000c, 0x2151: 0x000c, + // Block 0x86, offset 0x2180 + 0x2180: 0x000c, 0x2181: 0x000c, 0x2182: 0x000c, + 0x21b3: 0x000c, + 0x21b6: 0x000c, 0x21b7: 0x000c, 0x21b8: 0x000c, 0x21b9: 0x000c, + 0x21bc: 0x000c, + // Block 0x87, offset 0x21c0 + 0x21e5: 0x000c, + // Block 0x88, offset 0x2200 + 0x2229: 0x000c, + 0x222a: 0x000c, 0x222b: 0x000c, 0x222c: 0x000c, 0x222d: 0x000c, 0x222e: 0x000c, + 0x2231: 0x000c, 0x2232: 0x000c, 0x2235: 0x000c, + 0x2236: 0x000c, + // Block 0x89, offset 0x2240 + 0x2243: 0x000c, + 0x224c: 0x000c, + 0x227c: 0x000c, + // Block 0x8a, offset 0x2280 + 0x22b0: 0x000c, 0x22b2: 0x000c, 0x22b3: 0x000c, 0x22b4: 0x000c, + 0x22b7: 0x000c, 0x22b8: 0x000c, + 0x22be: 0x000c, 0x22bf: 0x000c, + // Block 0x8b, offset 0x22c0 + 0x22c1: 0x000c, + 0x22ec: 0x000c, 0x22ed: 0x000c, + 0x22f6: 0x000c, + // Block 0x8c, offset 0x2300 + 0x2325: 0x000c, 0x2328: 0x000c, + 0x232d: 0x000c, + // Block 0x8d, offset 0x2340 + 0x235d: 0x0001, + 0x235e: 0x000c, 0x235f: 0x0001, 0x2360: 0x0001, 0x2361: 0x0001, 0x2362: 0x0001, 0x2363: 0x0001, + 0x2364: 0x0001, 0x2365: 0x0001, 0x2366: 0x0001, 0x2367: 0x0001, 0x2368: 0x0001, 0x2369: 0x0003, + 0x236a: 0x0001, 0x236b: 0x0001, 0x236c: 0x0001, 0x236d: 0x0001, 0x236e: 0x0001, 0x236f: 0x0001, + 0x2370: 0x0001, 0x2371: 0x0001, 0x2372: 0x0001, 0x2373: 0x0001, 0x2374: 0x0001, 0x2375: 0x0001, + 0x2376: 0x0001, 0x2377: 0x0001, 0x2378: 0x0001, 0x2379: 0x0001, 0x237a: 0x0001, 0x237b: 0x0001, + 0x237c: 0x0001, 0x237d: 0x0001, 0x237e: 0x0001, 0x237f: 0x0001, + // Block 0x8e, offset 0x2380 + 0x2380: 0x0001, 0x2381: 0x0001, 0x2382: 0x0001, 0x2383: 0x0001, 0x2384: 0x0001, 0x2385: 0x0001, + 0x2386: 0x0001, 0x2387: 0x0001, 0x2388: 0x0001, 0x2389: 0x0001, 0x238a: 0x0001, 0x238b: 0x0001, + 0x238c: 0x0001, 0x238d: 0x0001, 0x238e: 0x0001, 0x238f: 0x0001, 0x2390: 0x000d, 0x2391: 0x000d, + 0x2392: 0x000d, 0x2393: 0x000d, 0x2394: 0x000d, 0x2395: 0x000d, 0x2396: 0x000d, 0x2397: 0x000d, + 0x2398: 0x000d, 0x2399: 0x000d, 0x239a: 0x000d, 0x239b: 0x000d, 0x239c: 0x000d, 0x239d: 0x000d, + 0x239e: 0x000d, 0x239f: 0x000d, 0x23a0: 0x000d, 0x23a1: 0x000d, 0x23a2: 0x000d, 0x23a3: 0x000d, + 0x23a4: 0x000d, 0x23a5: 0x000d, 0x23a6: 0x000d, 0x23a7: 0x000d, 0x23a8: 0x000d, 0x23a9: 0x000d, + 0x23aa: 0x000d, 0x23ab: 0x000d, 0x23ac: 0x000d, 0x23ad: 0x000d, 0x23ae: 0x000d, 0x23af: 0x000d, + 0x23b0: 0x000d, 0x23b1: 0x000d, 0x23b2: 0x000d, 0x23b3: 0x000d, 0x23b4: 0x000d, 0x23b5: 0x000d, + 0x23b6: 0x000d, 0x23b7: 0x000d, 0x23b8: 0x000d, 0x23b9: 0x000d, 0x23ba: 0x000d, 0x23bb: 0x000d, + 0x23bc: 0x000d, 0x23bd: 0x000d, 0x23be: 0x000d, 0x23bf: 0x000d, + // Block 0x8f, offset 0x23c0 + 0x23c0: 0x000d, 0x23c1: 0x000d, 0x23c2: 0x000d, 0x23c3: 0x000d, 0x23c4: 0x000d, 0x23c5: 0x000d, + 0x23c6: 0x000d, 0x23c7: 0x000d, 0x23c8: 0x000d, 0x23c9: 0x000d, 0x23ca: 0x000d, 0x23cb: 0x000d, + 0x23cc: 0x000d, 0x23cd: 0x000d, 0x23ce: 0x000d, 0x23cf: 0x000d, 0x23d0: 0x000d, 0x23d1: 0x000d, + 0x23d2: 0x000d, 0x23d3: 0x000d, 0x23d4: 0x000d, 0x23d5: 0x000d, 0x23d6: 0x000d, 0x23d7: 0x000d, + 0x23d8: 0x000d, 0x23d9: 0x000d, 0x23da: 0x000d, 0x23db: 0x000d, 0x23dc: 0x000d, 0x23dd: 0x000d, + 0x23de: 0x000d, 0x23df: 0x000d, 0x23e0: 0x000d, 0x23e1: 0x000d, 0x23e2: 0x000d, 0x23e3: 0x000d, + 0x23e4: 0x000d, 0x23e5: 0x000d, 0x23e6: 0x000d, 0x23e7: 0x000d, 0x23e8: 0x000d, 0x23e9: 0x000d, + 0x23ea: 0x000d, 0x23eb: 0x000d, 0x23ec: 0x000d, 0x23ed: 0x000d, 0x23ee: 0x000d, 0x23ef: 0x000d, + 0x23f0: 0x000d, 0x23f1: 0x000d, 0x23f2: 0x000d, 0x23f3: 0x000d, 0x23f4: 0x000d, 0x23f5: 0x000d, + 0x23f6: 0x000d, 0x23f7: 0x000d, 0x23f8: 0x000d, 0x23f9: 0x000d, 0x23fa: 0x000d, 0x23fb: 0x000d, + 0x23fc: 0x000d, 0x23fd: 0x000d, 0x23fe: 0x000a, 0x23ff: 0x000a, + // Block 0x90, offset 0x2400 + 0x2400: 0x000d, 0x2401: 0x000d, 0x2402: 0x000d, 0x2403: 0x000d, 0x2404: 0x000d, 0x2405: 0x000d, + 0x2406: 0x000d, 0x2407: 0x000d, 0x2408: 0x000d, 0x2409: 0x000d, 0x240a: 0x000d, 0x240b: 0x000d, + 0x240c: 0x000d, 0x240d: 0x000d, 0x240e: 0x000d, 0x240f: 0x000d, 0x2410: 0x000b, 0x2411: 0x000b, + 0x2412: 0x000b, 0x2413: 0x000b, 0x2414: 0x000b, 0x2415: 0x000b, 0x2416: 0x000b, 0x2417: 0x000b, + 0x2418: 0x000b, 0x2419: 0x000b, 0x241a: 0x000b, 0x241b: 0x000b, 0x241c: 0x000b, 0x241d: 0x000b, + 0x241e: 0x000b, 0x241f: 0x000b, 0x2420: 0x000b, 0x2421: 0x000b, 0x2422: 0x000b, 0x2423: 0x000b, + 0x2424: 0x000b, 0x2425: 0x000b, 0x2426: 0x000b, 0x2427: 0x000b, 0x2428: 0x000b, 0x2429: 0x000b, + 0x242a: 0x000b, 0x242b: 0x000b, 0x242c: 0x000b, 0x242d: 0x000b, 0x242e: 0x000b, 0x242f: 0x000b, + 0x2430: 0x000d, 0x2431: 0x000d, 0x2432: 0x000d, 0x2433: 0x000d, 0x2434: 0x000d, 0x2435: 0x000d, + 0x2436: 0x000d, 0x2437: 0x000d, 0x2438: 0x000d, 0x2439: 0x000d, 0x243a: 0x000d, 0x243b: 0x000d, + 0x243c: 0x000d, 0x243d: 0x000a, 0x243e: 0x000d, 0x243f: 0x000d, + // Block 0x91, offset 0x2440 + 0x2440: 0x000c, 0x2441: 0x000c, 0x2442: 0x000c, 0x2443: 0x000c, 0x2444: 0x000c, 0x2445: 0x000c, + 0x2446: 0x000c, 0x2447: 0x000c, 0x2448: 0x000c, 0x2449: 0x000c, 0x244a: 0x000c, 0x244b: 0x000c, + 0x244c: 0x000c, 0x244d: 0x000c, 0x244e: 0x000c, 0x244f: 0x000c, 0x2450: 0x000a, 0x2451: 0x000a, + 0x2452: 0x000a, 0x2453: 0x000a, 0x2454: 0x000a, 0x2455: 0x000a, 0x2456: 0x000a, 0x2457: 0x000a, + 0x2458: 0x000a, 0x2459: 0x000a, + 0x2460: 0x000c, 0x2461: 0x000c, 0x2462: 0x000c, 0x2463: 0x000c, + 0x2464: 0x000c, 0x2465: 0x000c, 0x2466: 0x000c, 0x2467: 0x000c, 0x2468: 0x000c, 0x2469: 0x000c, + 0x246a: 0x000c, 0x246b: 0x000c, 0x246c: 0x000c, 0x246d: 0x000c, 0x246e: 0x000c, 0x246f: 0x000c, + 0x2470: 0x000a, 0x2471: 0x000a, 0x2472: 0x000a, 0x2473: 0x000a, 0x2474: 0x000a, 0x2475: 0x000a, + 0x2476: 0x000a, 0x2477: 0x000a, 0x2478: 0x000a, 0x2479: 0x000a, 0x247a: 0x000a, 0x247b: 0x000a, + 0x247c: 0x000a, 0x247d: 0x000a, 0x247e: 0x000a, 0x247f: 0x000a, + // Block 0x92, offset 0x2480 + 0x2480: 0x000a, 0x2481: 0x000a, 0x2482: 0x000a, 0x2483: 0x000a, 0x2484: 0x000a, 0x2485: 0x000a, + 0x2486: 0x000a, 0x2487: 0x000a, 0x2488: 0x000a, 0x2489: 0x000a, 0x248a: 0x000a, 0x248b: 0x000a, + 0x248c: 0x000a, 0x248d: 0x000a, 0x248e: 0x000a, 0x248f: 0x000a, 0x2490: 0x0006, 0x2491: 0x000a, + 0x2492: 0x0006, 0x2494: 0x000a, 0x2495: 0x0006, 0x2496: 0x000a, 0x2497: 0x000a, + 0x2498: 0x000a, 0x2499: 0x009a, 0x249a: 0x008a, 0x249b: 0x007a, 0x249c: 0x006a, 0x249d: 0x009a, + 0x249e: 0x008a, 0x249f: 0x0004, 0x24a0: 0x000a, 0x24a1: 0x000a, 0x24a2: 0x0003, 0x24a3: 0x0003, + 0x24a4: 0x000a, 0x24a5: 0x000a, 0x24a6: 0x000a, 0x24a8: 0x000a, 0x24a9: 0x0004, + 0x24aa: 0x0004, 0x24ab: 0x000a, + 0x24b0: 0x000d, 0x24b1: 0x000d, 0x24b2: 0x000d, 0x24b3: 0x000d, 0x24b4: 0x000d, 0x24b5: 0x000d, + 0x24b6: 0x000d, 0x24b7: 0x000d, 0x24b8: 0x000d, 0x24b9: 0x000d, 0x24ba: 0x000d, 0x24bb: 0x000d, + 0x24bc: 0x000d, 0x24bd: 0x000d, 0x24be: 0x000d, 0x24bf: 0x000d, + // Block 0x93, offset 0x24c0 + 0x24c0: 0x000d, 0x24c1: 0x000d, 0x24c2: 0x000d, 0x24c3: 0x000d, 0x24c4: 0x000d, 0x24c5: 0x000d, + 0x24c6: 0x000d, 0x24c7: 0x000d, 0x24c8: 0x000d, 0x24c9: 0x000d, 0x24ca: 0x000d, 0x24cb: 0x000d, + 0x24cc: 0x000d, 0x24cd: 0x000d, 0x24ce: 0x000d, 0x24cf: 0x000d, 0x24d0: 0x000d, 0x24d1: 0x000d, + 0x24d2: 0x000d, 0x24d3: 0x000d, 0x24d4: 0x000d, 0x24d5: 0x000d, 0x24d6: 0x000d, 0x24d7: 0x000d, + 0x24d8: 0x000d, 0x24d9: 0x000d, 0x24da: 0x000d, 0x24db: 0x000d, 0x24dc: 0x000d, 0x24dd: 0x000d, + 0x24de: 0x000d, 0x24df: 0x000d, 0x24e0: 0x000d, 0x24e1: 0x000d, 0x24e2: 0x000d, 0x24e3: 0x000d, + 0x24e4: 0x000d, 0x24e5: 0x000d, 0x24e6: 0x000d, 0x24e7: 0x000d, 0x24e8: 0x000d, 0x24e9: 0x000d, + 0x24ea: 0x000d, 0x24eb: 0x000d, 0x24ec: 0x000d, 0x24ed: 0x000d, 0x24ee: 0x000d, 0x24ef: 0x000d, + 0x24f0: 0x000d, 0x24f1: 0x000d, 0x24f2: 0x000d, 0x24f3: 0x000d, 0x24f4: 0x000d, 0x24f5: 0x000d, + 0x24f6: 0x000d, 0x24f7: 0x000d, 0x24f8: 0x000d, 0x24f9: 0x000d, 0x24fa: 0x000d, 0x24fb: 0x000d, + 0x24fc: 0x000d, 0x24fd: 0x000d, 0x24fe: 0x000d, 0x24ff: 0x000b, + // Block 0x94, offset 0x2500 + 0x2501: 0x000a, 0x2502: 0x000a, 0x2503: 0x0004, 0x2504: 0x0004, 0x2505: 0x0004, + 0x2506: 0x000a, 0x2507: 0x000a, 0x2508: 0x003a, 0x2509: 0x002a, 0x250a: 0x000a, 0x250b: 0x0003, + 0x250c: 0x0006, 0x250d: 0x0003, 0x250e: 0x0006, 0x250f: 0x0006, 0x2510: 0x0002, 0x2511: 0x0002, + 0x2512: 0x0002, 0x2513: 0x0002, 0x2514: 0x0002, 0x2515: 0x0002, 0x2516: 0x0002, 0x2517: 0x0002, + 0x2518: 0x0002, 0x2519: 0x0002, 0x251a: 0x0006, 0x251b: 0x000a, 0x251c: 0x000a, 0x251d: 0x000a, + 0x251e: 0x000a, 0x251f: 0x000a, 0x2520: 0x000a, + 0x253b: 0x005a, + 0x253c: 0x000a, 0x253d: 0x004a, 0x253e: 0x000a, 0x253f: 0x000a, + // Block 0x95, offset 0x2540 + 0x2540: 0x000a, + 0x255b: 0x005a, 0x255c: 0x000a, 0x255d: 0x004a, + 0x255e: 0x000a, 0x255f: 0x00fa, 0x2560: 0x00ea, 0x2561: 0x000a, 0x2562: 0x003a, 0x2563: 0x002a, + 0x2564: 0x000a, 0x2565: 0x000a, + // Block 0x96, offset 0x2580 + 0x25a0: 0x0004, 0x25a1: 0x0004, 0x25a2: 0x000a, 0x25a3: 0x000a, + 0x25a4: 0x000a, 0x25a5: 0x0004, 0x25a6: 0x0004, 0x25a8: 0x000a, 0x25a9: 0x000a, + 0x25aa: 0x000a, 0x25ab: 0x000a, 0x25ac: 0x000a, 0x25ad: 0x000a, 0x25ae: 0x000a, + 0x25b0: 0x000b, 0x25b1: 0x000b, 0x25b2: 0x000b, 0x25b3: 0x000b, 0x25b4: 0x000b, 0x25b5: 0x000b, + 0x25b6: 0x000b, 0x25b7: 0x000b, 0x25b8: 0x000b, 0x25b9: 0x000a, 0x25ba: 0x000a, 0x25bb: 0x000a, + 0x25bc: 0x000a, 0x25bd: 0x000a, 0x25be: 0x000b, 0x25bf: 0x000b, + // Block 0x97, offset 0x25c0 + 0x25c1: 0x000a, + // Block 0x98, offset 0x2600 + 0x2600: 0x000a, 0x2601: 0x000a, 0x2602: 0x000a, 0x2603: 0x000a, 0x2604: 0x000a, 0x2605: 0x000a, + 0x2606: 0x000a, 0x2607: 0x000a, 0x2608: 0x000a, 0x2609: 0x000a, 0x260a: 0x000a, 0x260b: 0x000a, + 0x260c: 0x000a, 0x2610: 0x000a, 0x2611: 0x000a, + 0x2612: 0x000a, 0x2613: 0x000a, 0x2614: 0x000a, 0x2615: 0x000a, 0x2616: 0x000a, 0x2617: 0x000a, + 0x2618: 0x000a, 0x2619: 0x000a, 0x261a: 0x000a, 0x261b: 0x000a, + 0x2620: 0x000a, + // Block 0x99, offset 0x2640 + 0x267d: 0x000c, + // Block 0x9a, offset 0x2680 + 0x26a0: 0x000c, 0x26a1: 0x0002, 0x26a2: 0x0002, 0x26a3: 0x0002, + 0x26a4: 0x0002, 0x26a5: 0x0002, 0x26a6: 0x0002, 0x26a7: 0x0002, 0x26a8: 0x0002, 0x26a9: 0x0002, + 0x26aa: 0x0002, 0x26ab: 0x0002, 0x26ac: 0x0002, 0x26ad: 0x0002, 0x26ae: 0x0002, 0x26af: 0x0002, + 0x26b0: 0x0002, 0x26b1: 0x0002, 0x26b2: 0x0002, 0x26b3: 0x0002, 0x26b4: 0x0002, 0x26b5: 0x0002, + 0x26b6: 0x0002, 0x26b7: 0x0002, 0x26b8: 0x0002, 0x26b9: 0x0002, 0x26ba: 0x0002, 0x26bb: 0x0002, + // Block 0x9b, offset 0x26c0 + 0x26f6: 0x000c, 0x26f7: 0x000c, 0x26f8: 0x000c, 0x26f9: 0x000c, 0x26fa: 0x000c, + // Block 0x9c, offset 0x2700 + 0x2700: 0x0001, 0x2701: 0x0001, 0x2702: 0x0001, 0x2703: 0x0001, 0x2704: 0x0001, 0x2705: 0x0001, + 0x2706: 0x0001, 0x2707: 0x0001, 0x2708: 0x0001, 0x2709: 0x0001, 0x270a: 0x0001, 0x270b: 0x0001, + 0x270c: 0x0001, 0x270d: 0x0001, 0x270e: 0x0001, 0x270f: 0x0001, 0x2710: 0x0001, 0x2711: 0x0001, + 0x2712: 0x0001, 0x2713: 0x0001, 0x2714: 0x0001, 0x2715: 0x0001, 0x2716: 0x0001, 0x2717: 0x0001, + 0x2718: 0x0001, 0x2719: 0x0001, 0x271a: 0x0001, 0x271b: 0x0001, 0x271c: 0x0001, 0x271d: 0x0001, + 0x271e: 0x0001, 0x271f: 0x0001, 0x2720: 0x0001, 0x2721: 0x0001, 0x2722: 0x0001, 0x2723: 0x0001, + 0x2724: 0x0001, 0x2725: 0x0001, 0x2726: 0x0001, 0x2727: 0x0001, 0x2728: 0x0001, 0x2729: 0x0001, + 0x272a: 0x0001, 0x272b: 0x0001, 0x272c: 0x0001, 0x272d: 0x0001, 0x272e: 0x0001, 0x272f: 0x0001, + 0x2730: 0x0001, 0x2731: 0x0001, 0x2732: 0x0001, 0x2733: 0x0001, 0x2734: 0x0001, 0x2735: 0x0001, + 0x2736: 0x0001, 0x2737: 0x0001, 0x2738: 0x0001, 0x2739: 0x0001, 0x273a: 0x0001, 0x273b: 0x0001, + 0x273c: 0x0001, 0x273d: 0x0001, 0x273e: 0x0001, 0x273f: 0x0001, + // Block 0x9d, offset 0x2740 + 0x2740: 0x0001, 0x2741: 0x0001, 0x2742: 0x0001, 0x2743: 0x0001, 0x2744: 0x0001, 0x2745: 0x0001, + 0x2746: 0x0001, 0x2747: 0x0001, 0x2748: 0x0001, 0x2749: 0x0001, 0x274a: 0x0001, 0x274b: 0x0001, + 0x274c: 0x0001, 0x274d: 0x0001, 0x274e: 0x0001, 0x274f: 0x0001, 0x2750: 0x0001, 0x2751: 0x0001, + 0x2752: 0x0001, 0x2753: 0x0001, 0x2754: 0x0001, 0x2755: 0x0001, 0x2756: 0x0001, 0x2757: 0x0001, + 0x2758: 0x0001, 0x2759: 0x0001, 0x275a: 0x0001, 0x275b: 0x0001, 0x275c: 0x0001, 0x275d: 0x0001, + 0x275e: 0x0001, 0x275f: 0x000a, 0x2760: 0x0001, 0x2761: 0x0001, 0x2762: 0x0001, 0x2763: 0x0001, + 0x2764: 0x0001, 0x2765: 0x0001, 0x2766: 0x0001, 0x2767: 0x0001, 0x2768: 0x0001, 0x2769: 0x0001, + 0x276a: 0x0001, 0x276b: 0x0001, 0x276c: 0x0001, 0x276d: 0x0001, 0x276e: 0x0001, 0x276f: 0x0001, + 0x2770: 0x0001, 0x2771: 0x0001, 0x2772: 0x0001, 0x2773: 0x0001, 0x2774: 0x0001, 0x2775: 0x0001, + 0x2776: 0x0001, 0x2777: 0x0001, 0x2778: 0x0001, 0x2779: 0x0001, 0x277a: 0x0001, 0x277b: 0x0001, + 0x277c: 0x0001, 0x277d: 0x0001, 0x277e: 0x0001, 0x277f: 0x0001, + // Block 0x9e, offset 0x2780 + 0x2780: 0x0001, 0x2781: 0x000c, 0x2782: 0x000c, 0x2783: 0x000c, 0x2784: 0x0001, 0x2785: 0x000c, + 0x2786: 0x000c, 0x2787: 0x0001, 0x2788: 0x0001, 0x2789: 0x0001, 0x278a: 0x0001, 0x278b: 0x0001, + 0x278c: 0x000c, 0x278d: 0x000c, 0x278e: 0x000c, 0x278f: 0x000c, 0x2790: 0x0001, 0x2791: 0x0001, + 0x2792: 0x0001, 0x2793: 0x0001, 0x2794: 0x0001, 0x2795: 0x0001, 0x2796: 0x0001, 0x2797: 0x0001, + 0x2798: 0x0001, 0x2799: 0x0001, 0x279a: 0x0001, 0x279b: 0x0001, 0x279c: 0x0001, 0x279d: 0x0001, + 0x279e: 0x0001, 0x279f: 0x0001, 0x27a0: 0x0001, 0x27a1: 0x0001, 0x27a2: 0x0001, 0x27a3: 0x0001, + 0x27a4: 0x0001, 0x27a5: 0x0001, 0x27a6: 0x0001, 0x27a7: 0x0001, 0x27a8: 0x0001, 0x27a9: 0x0001, + 0x27aa: 0x0001, 0x27ab: 0x0001, 0x27ac: 0x0001, 0x27ad: 0x0001, 0x27ae: 0x0001, 0x27af: 0x0001, + 0x27b0: 0x0001, 0x27b1: 0x0001, 0x27b2: 0x0001, 0x27b3: 0x0001, 0x27b4: 0x0001, 0x27b5: 0x0001, + 0x27b6: 0x0001, 0x27b7: 0x0001, 0x27b8: 0x000c, 0x27b9: 0x000c, 0x27ba: 0x000c, 0x27bb: 0x0001, + 0x27bc: 0x0001, 0x27bd: 0x0001, 0x27be: 0x0001, 0x27bf: 0x000c, + // Block 0x9f, offset 0x27c0 + 0x27c0: 0x0001, 0x27c1: 0x0001, 0x27c2: 0x0001, 0x27c3: 0x0001, 0x27c4: 0x0001, 0x27c5: 0x0001, + 0x27c6: 0x0001, 0x27c7: 0x0001, 0x27c8: 0x0001, 0x27c9: 0x0001, 0x27ca: 0x0001, 0x27cb: 0x0001, + 0x27cc: 0x0001, 0x27cd: 0x0001, 0x27ce: 0x0001, 0x27cf: 0x0001, 0x27d0: 0x0001, 0x27d1: 0x0001, + 0x27d2: 0x0001, 0x27d3: 0x0001, 0x27d4: 0x0001, 0x27d5: 0x0001, 0x27d6: 0x0001, 0x27d7: 0x0001, + 0x27d8: 0x0001, 0x27d9: 0x0001, 0x27da: 0x0001, 0x27db: 0x0001, 0x27dc: 0x0001, 0x27dd: 0x0001, + 0x27de: 0x0001, 0x27df: 0x0001, 0x27e0: 0x0001, 0x27e1: 0x0001, 0x27e2: 0x0001, 0x27e3: 0x0001, + 0x27e4: 0x0001, 0x27e5: 0x000c, 0x27e6: 0x000c, 0x27e7: 0x0001, 0x27e8: 0x0001, 0x27e9: 0x0001, + 0x27ea: 0x0001, 0x27eb: 0x0001, 0x27ec: 0x0001, 0x27ed: 0x0001, 0x27ee: 0x0001, 0x27ef: 0x0001, + 0x27f0: 0x0001, 0x27f1: 0x0001, 0x27f2: 0x0001, 0x27f3: 0x0001, 0x27f4: 0x0001, 0x27f5: 0x0001, + 0x27f6: 0x0001, 0x27f7: 0x0001, 0x27f8: 0x0001, 0x27f9: 0x0001, 0x27fa: 0x0001, 0x27fb: 0x0001, + 0x27fc: 0x0001, 0x27fd: 0x0001, 0x27fe: 0x0001, 0x27ff: 0x0001, + // Block 0xa0, offset 0x2800 + 0x2800: 0x0001, 0x2801: 0x0001, 0x2802: 0x0001, 0x2803: 0x0001, 0x2804: 0x0001, 0x2805: 0x0001, + 0x2806: 0x0001, 0x2807: 0x0001, 0x2808: 0x0001, 0x2809: 0x0001, 0x280a: 0x0001, 0x280b: 0x0001, + 0x280c: 0x0001, 0x280d: 0x0001, 0x280e: 0x0001, 0x280f: 0x0001, 0x2810: 0x0001, 0x2811: 0x0001, + 0x2812: 0x0001, 0x2813: 0x0001, 0x2814: 0x0001, 0x2815: 0x0001, 0x2816: 0x0001, 0x2817: 0x0001, + 0x2818: 0x0001, 0x2819: 0x0001, 0x281a: 0x0001, 0x281b: 0x0001, 0x281c: 0x0001, 0x281d: 0x0001, + 0x281e: 0x0001, 0x281f: 0x0001, 0x2820: 0x0001, 0x2821: 0x0001, 0x2822: 0x0001, 0x2823: 0x0001, + 0x2824: 0x0001, 0x2825: 0x0001, 0x2826: 0x0001, 0x2827: 0x0001, 0x2828: 0x0001, 0x2829: 0x0001, + 0x282a: 0x0001, 0x282b: 0x0001, 0x282c: 0x0001, 0x282d: 0x0001, 0x282e: 0x0001, 0x282f: 0x0001, + 0x2830: 0x0001, 0x2831: 0x0001, 0x2832: 0x0001, 0x2833: 0x0001, 0x2834: 0x0001, 0x2835: 0x0001, + 0x2836: 0x0001, 0x2837: 0x0001, 0x2838: 0x0001, 0x2839: 0x000a, 0x283a: 0x000a, 0x283b: 0x000a, + 0x283c: 0x000a, 0x283d: 0x000a, 0x283e: 0x000a, 0x283f: 0x000a, + // Block 0xa1, offset 0x2840 + 0x2840: 0x0001, 0x2841: 0x0001, 0x2842: 0x0001, 0x2843: 0x0001, 0x2844: 0x0001, 0x2845: 0x0001, + 0x2846: 0x0001, 0x2847: 0x0001, 0x2848: 0x0001, 0x2849: 0x0001, 0x284a: 0x0001, 0x284b: 0x0001, + 0x284c: 0x0001, 0x284d: 0x0001, 0x284e: 0x0001, 0x284f: 0x0001, 0x2850: 0x0001, 0x2851: 0x0001, + 0x2852: 0x0001, 0x2853: 0x0001, 0x2854: 0x0001, 0x2855: 0x0001, 0x2856: 0x0001, 0x2857: 0x0001, + 0x2858: 0x0001, 0x2859: 0x0001, 0x285a: 0x0001, 0x285b: 0x0001, 0x285c: 0x0001, 0x285d: 0x0001, + 0x285e: 0x0001, 0x285f: 0x0001, 0x2860: 0x0005, 0x2861: 0x0005, 0x2862: 0x0005, 0x2863: 0x0005, + 0x2864: 0x0005, 0x2865: 0x0005, 0x2866: 0x0005, 0x2867: 0x0005, 0x2868: 0x0005, 0x2869: 0x0005, + 0x286a: 0x0005, 0x286b: 0x0005, 0x286c: 0x0005, 0x286d: 0x0005, 0x286e: 0x0005, 0x286f: 0x0005, + 0x2870: 0x0005, 0x2871: 0x0005, 0x2872: 0x0005, 0x2873: 0x0005, 0x2874: 0x0005, 0x2875: 0x0005, + 0x2876: 0x0005, 0x2877: 0x0005, 0x2878: 0x0005, 0x2879: 0x0005, 0x287a: 0x0005, 0x287b: 0x0005, + 0x287c: 0x0005, 0x287d: 0x0005, 0x287e: 0x0005, 0x287f: 0x0001, + // Block 0xa2, offset 0x2880 + 0x2881: 0x000c, + 0x28b8: 0x000c, 0x28b9: 0x000c, 0x28ba: 0x000c, 0x28bb: 0x000c, + 0x28bc: 0x000c, 0x28bd: 0x000c, 0x28be: 0x000c, 0x28bf: 0x000c, + // Block 0xa3, offset 0x28c0 + 0x28c0: 0x000c, 0x28c1: 0x000c, 0x28c2: 0x000c, 0x28c3: 0x000c, 0x28c4: 0x000c, 0x28c5: 0x000c, + 0x28c6: 0x000c, + 0x28d2: 0x000a, 0x28d3: 0x000a, 0x28d4: 0x000a, 0x28d5: 0x000a, 0x28d6: 0x000a, 0x28d7: 0x000a, + 0x28d8: 0x000a, 0x28d9: 0x000a, 0x28da: 0x000a, 0x28db: 0x000a, 0x28dc: 0x000a, 0x28dd: 0x000a, + 0x28de: 0x000a, 0x28df: 0x000a, 0x28e0: 0x000a, 0x28e1: 0x000a, 0x28e2: 0x000a, 0x28e3: 0x000a, + 0x28e4: 0x000a, 0x28e5: 0x000a, + 0x28ff: 0x000c, + // Block 0xa4, offset 0x2900 + 0x2900: 0x000c, 0x2901: 0x000c, + 0x2933: 0x000c, 0x2934: 0x000c, 0x2935: 0x000c, + 0x2936: 0x000c, 0x2939: 0x000c, 0x293a: 0x000c, + // Block 0xa5, offset 0x2940 + 0x2940: 0x000c, 0x2941: 0x000c, 0x2942: 0x000c, + 0x2967: 0x000c, 0x2968: 0x000c, 0x2969: 0x000c, + 0x296a: 0x000c, 0x296b: 0x000c, 0x296d: 0x000c, 0x296e: 0x000c, 0x296f: 0x000c, + 0x2970: 0x000c, 0x2971: 0x000c, 0x2972: 0x000c, 0x2973: 0x000c, 0x2974: 0x000c, + // Block 0xa6, offset 0x2980 + 0x29b3: 0x000c, + // Block 0xa7, offset 0x29c0 + 0x29c0: 0x000c, 0x29c1: 0x000c, + 0x29f6: 0x000c, 0x29f7: 0x000c, 0x29f8: 0x000c, 0x29f9: 0x000c, 0x29fa: 0x000c, 0x29fb: 0x000c, + 0x29fc: 0x000c, 0x29fd: 0x000c, 0x29fe: 0x000c, + // Block 0xa8, offset 0x2a00 + 0x2a0a: 0x000c, 0x2a0b: 0x000c, + 0x2a0c: 0x000c, + // Block 0xa9, offset 0x2a40 + 0x2a6f: 0x000c, + 0x2a70: 0x000c, 0x2a71: 0x000c, 0x2a74: 0x000c, + 0x2a76: 0x000c, 0x2a77: 0x000c, + 0x2a7e: 0x000c, + // Block 0xaa, offset 0x2a80 + 0x2a9f: 0x000c, 0x2aa3: 0x000c, + 0x2aa4: 0x000c, 0x2aa5: 0x000c, 0x2aa6: 0x000c, 0x2aa7: 0x000c, 0x2aa8: 0x000c, 0x2aa9: 0x000c, + 0x2aaa: 0x000c, + // Block 0xab, offset 0x2ac0 + 0x2ac0: 0x000c, 0x2ac1: 0x000c, + 0x2afc: 0x000c, + // Block 0xac, offset 0x2b00 + 0x2b00: 0x000c, + 0x2b26: 0x000c, 0x2b27: 0x000c, 0x2b28: 0x000c, 0x2b29: 0x000c, + 0x2b2a: 0x000c, 0x2b2b: 0x000c, 0x2b2c: 0x000c, + 0x2b30: 0x000c, 0x2b31: 0x000c, 0x2b32: 0x000c, 0x2b33: 0x000c, 0x2b34: 0x000c, + // Block 0xad, offset 0x2b40 + 0x2b78: 0x000c, 0x2b79: 0x000c, 0x2b7a: 0x000c, 0x2b7b: 0x000c, + 0x2b7c: 0x000c, 0x2b7d: 0x000c, 0x2b7e: 0x000c, 0x2b7f: 0x000c, + // Block 0xae, offset 0x2b80 + 0x2b82: 0x000c, 0x2b83: 0x000c, 0x2b84: 0x000c, + 0x2b86: 0x000c, + // Block 0xaf, offset 0x2bc0 + 0x2bf3: 0x000c, 0x2bf4: 0x000c, 0x2bf5: 0x000c, + 0x2bf6: 0x000c, 0x2bf7: 0x000c, 0x2bf8: 0x000c, 0x2bfa: 0x000c, + 0x2bff: 0x000c, + // Block 0xb0, offset 0x2c00 + 0x2c00: 0x000c, 0x2c02: 0x000c, 0x2c03: 0x000c, + // Block 0xb1, offset 0x2c40 + 0x2c72: 0x000c, 0x2c73: 0x000c, 0x2c74: 0x000c, 0x2c75: 0x000c, + 0x2c7c: 0x000c, 0x2c7d: 0x000c, 0x2c7f: 0x000c, + // Block 0xb2, offset 0x2c80 + 0x2c80: 0x000c, + 0x2c9c: 0x000c, 0x2c9d: 0x000c, + // Block 0xb3, offset 0x2cc0 + 0x2cf3: 0x000c, 0x2cf4: 0x000c, 0x2cf5: 0x000c, + 0x2cf6: 0x000c, 0x2cf7: 0x000c, 0x2cf8: 0x000c, 0x2cf9: 0x000c, 0x2cfa: 0x000c, + 0x2cfd: 0x000c, 0x2cff: 0x000c, + // Block 0xb4, offset 0x2d00 + 0x2d00: 0x000c, + 0x2d20: 0x000a, 0x2d21: 0x000a, 0x2d22: 0x000a, 0x2d23: 0x000a, + 0x2d24: 0x000a, 0x2d25: 0x000a, 0x2d26: 0x000a, 0x2d27: 0x000a, 0x2d28: 0x000a, 0x2d29: 0x000a, + 0x2d2a: 0x000a, 0x2d2b: 0x000a, 0x2d2c: 0x000a, + // Block 0xb5, offset 0x2d40 + 0x2d6b: 0x000c, 0x2d6d: 0x000c, + 0x2d70: 0x000c, 0x2d71: 0x000c, 0x2d72: 0x000c, 0x2d73: 0x000c, 0x2d74: 0x000c, 0x2d75: 0x000c, + 0x2d77: 0x000c, + // Block 0xb6, offset 0x2d80 + 0x2d9d: 0x000c, + 0x2d9e: 0x000c, 0x2d9f: 0x000c, 0x2da2: 0x000c, 0x2da3: 0x000c, + 0x2da4: 0x000c, 0x2da5: 0x000c, 0x2da7: 0x000c, 0x2da8: 0x000c, 0x2da9: 0x000c, + 0x2daa: 0x000c, 0x2dab: 0x000c, + // Block 0xb7, offset 0x2dc0 + 0x2dc1: 0x000c, 0x2dc2: 0x000c, 0x2dc3: 0x000c, 0x2dc4: 0x000c, 0x2dc5: 0x000c, + 0x2dc6: 0x000c, 0x2dc9: 0x000c, 0x2dca: 0x000c, + 0x2df3: 0x000c, 0x2df4: 0x000c, 0x2df5: 0x000c, + 0x2df6: 0x000c, 0x2df7: 0x000c, 0x2df8: 0x000c, 0x2dfb: 0x000c, + 0x2dfc: 0x000c, 0x2dfd: 0x000c, 0x2dfe: 0x000c, + // Block 0xb8, offset 0x2e00 + 0x2e07: 0x000c, + 0x2e11: 0x000c, + 0x2e12: 0x000c, 0x2e13: 0x000c, 0x2e14: 0x000c, 0x2e15: 0x000c, 0x2e16: 0x000c, + 0x2e19: 0x000c, 0x2e1a: 0x000c, 0x2e1b: 0x000c, + // Block 0xb9, offset 0x2e40 + 0x2e4a: 0x000c, 0x2e4b: 0x000c, + 0x2e4c: 0x000c, 0x2e4d: 0x000c, 0x2e4e: 0x000c, 0x2e4f: 0x000c, 0x2e50: 0x000c, 0x2e51: 0x000c, + 0x2e52: 0x000c, 0x2e53: 0x000c, 0x2e54: 0x000c, 0x2e55: 0x000c, 0x2e56: 0x000c, + 0x2e58: 0x000c, 0x2e59: 0x000c, + // Block 0xba, offset 0x2e80 + 0x2eb0: 0x000c, 0x2eb1: 0x000c, 0x2eb2: 0x000c, 0x2eb3: 0x000c, 0x2eb4: 0x000c, 0x2eb5: 0x000c, + 0x2eb6: 0x000c, 0x2eb8: 0x000c, 0x2eb9: 0x000c, 0x2eba: 0x000c, 0x2ebb: 0x000c, + 0x2ebc: 0x000c, 0x2ebd: 0x000c, + // Block 0xbb, offset 0x2ec0 + 0x2ed2: 0x000c, 0x2ed3: 0x000c, 0x2ed4: 0x000c, 0x2ed5: 0x000c, 0x2ed6: 0x000c, 0x2ed7: 0x000c, + 0x2ed8: 0x000c, 0x2ed9: 0x000c, 0x2eda: 0x000c, 0x2edb: 0x000c, 0x2edc: 0x000c, 0x2edd: 0x000c, + 0x2ede: 0x000c, 0x2edf: 0x000c, 0x2ee0: 0x000c, 0x2ee1: 0x000c, 0x2ee2: 0x000c, 0x2ee3: 0x000c, + 0x2ee4: 0x000c, 0x2ee5: 0x000c, 0x2ee6: 0x000c, 0x2ee7: 0x000c, + 0x2eea: 0x000c, 0x2eeb: 0x000c, 0x2eec: 0x000c, 0x2eed: 0x000c, 0x2eee: 0x000c, 0x2eef: 0x000c, + 0x2ef0: 0x000c, 0x2ef2: 0x000c, 0x2ef3: 0x000c, 0x2ef5: 0x000c, + 0x2ef6: 0x000c, + // Block 0xbc, offset 0x2f00 + 0x2f31: 0x000c, 0x2f32: 0x000c, 0x2f33: 0x000c, 0x2f34: 0x000c, 0x2f35: 0x000c, + 0x2f36: 0x000c, 0x2f3a: 0x000c, + 0x2f3c: 0x000c, 0x2f3d: 0x000c, 0x2f3f: 0x000c, + // Block 0xbd, offset 0x2f40 + 0x2f40: 0x000c, 0x2f41: 0x000c, 0x2f42: 0x000c, 0x2f43: 0x000c, 0x2f44: 0x000c, 0x2f45: 0x000c, + 0x2f47: 0x000c, + // Block 0xbe, offset 0x2f80 + 0x2fb0: 0x000c, 0x2fb1: 0x000c, 0x2fb2: 0x000c, 0x2fb3: 0x000c, 0x2fb4: 0x000c, + // Block 0xbf, offset 0x2fc0 + 0x2ff0: 0x000c, 0x2ff1: 0x000c, 0x2ff2: 0x000c, 0x2ff3: 0x000c, 0x2ff4: 0x000c, 0x2ff5: 0x000c, + 0x2ff6: 0x000c, + // Block 0xc0, offset 0x3000 + 0x300f: 0x000c, 0x3010: 0x000c, 0x3011: 0x000c, + 0x3012: 0x000c, + // Block 0xc1, offset 0x3040 + 0x305d: 0x000c, + 0x305e: 0x000c, 0x3060: 0x000b, 0x3061: 0x000b, 0x3062: 0x000b, 0x3063: 0x000b, + // Block 0xc2, offset 0x3080 + 0x30a7: 0x000c, 0x30a8: 0x000c, 0x30a9: 0x000c, + 0x30b3: 0x000b, 0x30b4: 0x000b, 0x30b5: 0x000b, + 0x30b6: 0x000b, 0x30b7: 0x000b, 0x30b8: 0x000b, 0x30b9: 0x000b, 0x30ba: 0x000b, 0x30bb: 0x000c, + 0x30bc: 0x000c, 0x30bd: 0x000c, 0x30be: 0x000c, 0x30bf: 0x000c, + // Block 0xc3, offset 0x30c0 + 0x30c0: 0x000c, 0x30c1: 0x000c, 0x30c2: 0x000c, 0x30c5: 0x000c, + 0x30c6: 0x000c, 0x30c7: 0x000c, 0x30c8: 0x000c, 0x30c9: 0x000c, 0x30ca: 0x000c, 0x30cb: 0x000c, + 0x30ea: 0x000c, 0x30eb: 0x000c, 0x30ec: 0x000c, 0x30ed: 0x000c, + // Block 0xc4, offset 0x3100 + 0x3100: 0x000a, 0x3101: 0x000a, 0x3102: 0x000c, 0x3103: 0x000c, 0x3104: 0x000c, 0x3105: 0x000a, + // Block 0xc5, offset 0x3140 + 0x3140: 0x000a, 0x3141: 0x000a, 0x3142: 0x000a, 0x3143: 0x000a, 0x3144: 0x000a, 0x3145: 0x000a, + 0x3146: 0x000a, 0x3147: 0x000a, 0x3148: 0x000a, 0x3149: 0x000a, 0x314a: 0x000a, 0x314b: 0x000a, + 0x314c: 0x000a, 0x314d: 0x000a, 0x314e: 0x000a, 0x314f: 0x000a, 0x3150: 0x000a, 0x3151: 0x000a, + 0x3152: 0x000a, 0x3153: 0x000a, 0x3154: 0x000a, 0x3155: 0x000a, 0x3156: 0x000a, + // Block 0xc6, offset 0x3180 + 0x319b: 0x000a, + // Block 0xc7, offset 0x31c0 + 0x31d5: 0x000a, + // Block 0xc8, offset 0x3200 + 0x320f: 0x000a, + // Block 0xc9, offset 0x3240 + 0x3249: 0x000a, + // Block 0xca, offset 0x3280 + 0x3283: 0x000a, + 0x328e: 0x0002, 0x328f: 0x0002, 0x3290: 0x0002, 0x3291: 0x0002, + 0x3292: 0x0002, 0x3293: 0x0002, 0x3294: 0x0002, 0x3295: 0x0002, 0x3296: 0x0002, 0x3297: 0x0002, + 0x3298: 0x0002, 0x3299: 0x0002, 0x329a: 0x0002, 0x329b: 0x0002, 0x329c: 0x0002, 0x329d: 0x0002, + 0x329e: 0x0002, 0x329f: 0x0002, 0x32a0: 0x0002, 0x32a1: 0x0002, 0x32a2: 0x0002, 0x32a3: 0x0002, + 0x32a4: 0x0002, 0x32a5: 0x0002, 0x32a6: 0x0002, 0x32a7: 0x0002, 0x32a8: 0x0002, 0x32a9: 0x0002, + 0x32aa: 0x0002, 0x32ab: 0x0002, 0x32ac: 0x0002, 0x32ad: 0x0002, 0x32ae: 0x0002, 0x32af: 0x0002, + 0x32b0: 0x0002, 0x32b1: 0x0002, 0x32b2: 0x0002, 0x32b3: 0x0002, 0x32b4: 0x0002, 0x32b5: 0x0002, + 0x32b6: 0x0002, 0x32b7: 0x0002, 0x32b8: 0x0002, 0x32b9: 0x0002, 0x32ba: 0x0002, 0x32bb: 0x0002, + 0x32bc: 0x0002, 0x32bd: 0x0002, 0x32be: 0x0002, 0x32bf: 0x0002, + // Block 0xcb, offset 0x32c0 + 0x32c0: 0x000c, 0x32c1: 0x000c, 0x32c2: 0x000c, 0x32c3: 0x000c, 0x32c4: 0x000c, 0x32c5: 0x000c, + 0x32c6: 0x000c, 0x32c7: 0x000c, 0x32c8: 0x000c, 0x32c9: 0x000c, 0x32ca: 0x000c, 0x32cb: 0x000c, + 0x32cc: 0x000c, 0x32cd: 0x000c, 0x32ce: 0x000c, 0x32cf: 0x000c, 0x32d0: 0x000c, 0x32d1: 0x000c, + 0x32d2: 0x000c, 0x32d3: 0x000c, 0x32d4: 0x000c, 0x32d5: 0x000c, 0x32d6: 0x000c, 0x32d7: 0x000c, + 0x32d8: 0x000c, 0x32d9: 0x000c, 0x32da: 0x000c, 0x32db: 0x000c, 0x32dc: 0x000c, 0x32dd: 0x000c, + 0x32de: 0x000c, 0x32df: 0x000c, 0x32e0: 0x000c, 0x32e1: 0x000c, 0x32e2: 0x000c, 0x32e3: 0x000c, + 0x32e4: 0x000c, 0x32e5: 0x000c, 0x32e6: 0x000c, 0x32e7: 0x000c, 0x32e8: 0x000c, 0x32e9: 0x000c, + 0x32ea: 0x000c, 0x32eb: 0x000c, 0x32ec: 0x000c, 0x32ed: 0x000c, 0x32ee: 0x000c, 0x32ef: 0x000c, + 0x32f0: 0x000c, 0x32f1: 0x000c, 0x32f2: 0x000c, 0x32f3: 0x000c, 0x32f4: 0x000c, 0x32f5: 0x000c, + 0x32f6: 0x000c, 0x32fb: 0x000c, + 0x32fc: 0x000c, 0x32fd: 0x000c, 0x32fe: 0x000c, 0x32ff: 0x000c, + // Block 0xcc, offset 0x3300 + 0x3300: 0x000c, 0x3301: 0x000c, 0x3302: 0x000c, 0x3303: 0x000c, 0x3304: 0x000c, 0x3305: 0x000c, + 0x3306: 0x000c, 0x3307: 0x000c, 0x3308: 0x000c, 0x3309: 0x000c, 0x330a: 0x000c, 0x330b: 0x000c, + 0x330c: 0x000c, 0x330d: 0x000c, 0x330e: 0x000c, 0x330f: 0x000c, 0x3310: 0x000c, 0x3311: 0x000c, + 0x3312: 0x000c, 0x3313: 0x000c, 0x3314: 0x000c, 0x3315: 0x000c, 0x3316: 0x000c, 0x3317: 0x000c, + 0x3318: 0x000c, 0x3319: 0x000c, 0x331a: 0x000c, 0x331b: 0x000c, 0x331c: 0x000c, 0x331d: 0x000c, + 0x331e: 0x000c, 0x331f: 0x000c, 0x3320: 0x000c, 0x3321: 0x000c, 0x3322: 0x000c, 0x3323: 0x000c, + 0x3324: 0x000c, 0x3325: 0x000c, 0x3326: 0x000c, 0x3327: 0x000c, 0x3328: 0x000c, 0x3329: 0x000c, + 0x332a: 0x000c, 0x332b: 0x000c, 0x332c: 0x000c, + 0x3335: 0x000c, + // Block 0xcd, offset 0x3340 + 0x3344: 0x000c, + 0x335b: 0x000c, 0x335c: 0x000c, 0x335d: 0x000c, + 0x335e: 0x000c, 0x335f: 0x000c, 0x3361: 0x000c, 0x3362: 0x000c, 0x3363: 0x000c, + 0x3364: 0x000c, 0x3365: 0x000c, 0x3366: 0x000c, 0x3367: 0x000c, 0x3368: 0x000c, 0x3369: 0x000c, + 0x336a: 0x000c, 0x336b: 0x000c, 0x336c: 0x000c, 0x336d: 0x000c, 0x336e: 0x000c, 0x336f: 0x000c, + // Block 0xce, offset 0x3380 + 0x3380: 0x000c, 0x3381: 0x000c, 0x3382: 0x000c, 0x3383: 0x000c, 0x3384: 0x000c, 0x3385: 0x000c, + 0x3386: 0x000c, 0x3388: 0x000c, 0x3389: 0x000c, 0x338a: 0x000c, 0x338b: 0x000c, + 0x338c: 0x000c, 0x338d: 0x000c, 0x338e: 0x000c, 0x338f: 0x000c, 0x3390: 0x000c, 0x3391: 0x000c, + 0x3392: 0x000c, 0x3393: 0x000c, 0x3394: 0x000c, 0x3395: 0x000c, 0x3396: 0x000c, 0x3397: 0x000c, + 0x3398: 0x000c, 0x339b: 0x000c, 0x339c: 0x000c, 0x339d: 0x000c, + 0x339e: 0x000c, 0x339f: 0x000c, 0x33a0: 0x000c, 0x33a1: 0x000c, 0x33a3: 0x000c, + 0x33a4: 0x000c, 0x33a6: 0x000c, 0x33a7: 0x000c, 0x33a8: 0x000c, 0x33a9: 0x000c, + 0x33aa: 0x000c, + // Block 0xcf, offset 0x33c0 + 0x33c0: 0x0001, 0x33c1: 0x0001, 0x33c2: 0x0001, 0x33c3: 0x0001, 0x33c4: 0x0001, 0x33c5: 0x0001, + 0x33c6: 0x0001, 0x33c7: 0x0001, 0x33c8: 0x0001, 0x33c9: 0x0001, 0x33ca: 0x0001, 0x33cb: 0x0001, + 0x33cc: 0x0001, 0x33cd: 0x0001, 0x33ce: 0x0001, 0x33cf: 0x0001, 0x33d0: 0x000c, 0x33d1: 0x000c, + 0x33d2: 0x000c, 0x33d3: 0x000c, 0x33d4: 0x000c, 0x33d5: 0x000c, 0x33d6: 0x000c, 0x33d7: 0x0001, + 0x33d8: 0x0001, 0x33d9: 0x0001, 0x33da: 0x0001, 0x33db: 0x0001, 0x33dc: 0x0001, 0x33dd: 0x0001, + 0x33de: 0x0001, 0x33df: 0x0001, 0x33e0: 0x0001, 0x33e1: 0x0001, 0x33e2: 0x0001, 0x33e3: 0x0001, + 0x33e4: 0x0001, 0x33e5: 0x0001, 0x33e6: 0x0001, 0x33e7: 0x0001, 0x33e8: 0x0001, 0x33e9: 0x0001, + 0x33ea: 0x0001, 0x33eb: 0x0001, 0x33ec: 0x0001, 0x33ed: 0x0001, 0x33ee: 0x0001, 0x33ef: 0x0001, + 0x33f0: 0x0001, 0x33f1: 0x0001, 0x33f2: 0x0001, 0x33f3: 0x0001, 0x33f4: 0x0001, 0x33f5: 0x0001, + 0x33f6: 0x0001, 0x33f7: 0x0001, 0x33f8: 0x0001, 0x33f9: 0x0001, 0x33fa: 0x0001, 0x33fb: 0x0001, + 0x33fc: 0x0001, 0x33fd: 0x0001, 0x33fe: 0x0001, 0x33ff: 0x0001, + // Block 0xd0, offset 0x3400 + 0x3400: 0x0001, 0x3401: 0x0001, 0x3402: 0x0001, 0x3403: 0x0001, 0x3404: 0x000c, 0x3405: 0x000c, + 0x3406: 0x000c, 0x3407: 0x000c, 0x3408: 0x000c, 0x3409: 0x000c, 0x340a: 0x000c, 0x340b: 0x0001, + 0x340c: 0x0001, 0x340d: 0x0001, 0x340e: 0x0001, 0x340f: 0x0001, 0x3410: 0x0001, 0x3411: 0x0001, + 0x3412: 0x0001, 0x3413: 0x0001, 0x3414: 0x0001, 0x3415: 0x0001, 0x3416: 0x0001, 0x3417: 0x0001, + 0x3418: 0x0001, 0x3419: 0x0001, 0x341a: 0x0001, 0x341b: 0x0001, 0x341c: 0x0001, 0x341d: 0x0001, + 0x341e: 0x0001, 0x341f: 0x0001, 0x3420: 0x0001, 0x3421: 0x0001, 0x3422: 0x0001, 0x3423: 0x0001, + 0x3424: 0x0001, 0x3425: 0x0001, 0x3426: 0x0001, 0x3427: 0x0001, 0x3428: 0x0001, 0x3429: 0x0001, + 0x342a: 0x0001, 0x342b: 0x0001, 0x342c: 0x0001, 0x342d: 0x0001, 0x342e: 0x0001, 0x342f: 0x0001, + 0x3430: 0x0001, 0x3431: 0x0001, 0x3432: 0x0001, 0x3433: 0x0001, 0x3434: 0x0001, 0x3435: 0x0001, + 0x3436: 0x0001, 0x3437: 0x0001, 0x3438: 0x0001, 0x3439: 0x0001, 0x343a: 0x0001, 0x343b: 0x0001, + 0x343c: 0x0001, 0x343d: 0x0001, 0x343e: 0x0001, 0x343f: 0x0001, + // Block 0xd1, offset 0x3440 + 0x3440: 0x000d, 0x3441: 0x000d, 0x3442: 0x000d, 0x3443: 0x000d, 0x3444: 0x000d, 0x3445: 0x000d, + 0x3446: 0x000d, 0x3447: 0x000d, 0x3448: 0x000d, 0x3449: 0x000d, 0x344a: 0x000d, 0x344b: 0x000d, + 0x344c: 0x000d, 0x344d: 0x000d, 0x344e: 0x000d, 0x344f: 0x000d, 0x3450: 0x000d, 0x3451: 0x000d, + 0x3452: 0x000d, 0x3453: 0x000d, 0x3454: 0x000d, 0x3455: 0x000d, 0x3456: 0x000d, 0x3457: 0x000d, + 0x3458: 0x000d, 0x3459: 0x000d, 0x345a: 0x000d, 0x345b: 0x000d, 0x345c: 0x000d, 0x345d: 0x000d, + 0x345e: 0x000d, 0x345f: 0x000d, 0x3460: 0x000d, 0x3461: 0x000d, 0x3462: 0x000d, 0x3463: 0x000d, + 0x3464: 0x000d, 0x3465: 0x000d, 0x3466: 0x000d, 0x3467: 0x000d, 0x3468: 0x000d, 0x3469: 0x000d, + 0x346a: 0x000d, 0x346b: 0x000d, 0x346c: 0x000d, 0x346d: 0x000d, 0x346e: 0x000d, 0x346f: 0x000d, + 0x3470: 0x000a, 0x3471: 0x000a, 0x3472: 0x000d, 0x3473: 0x000d, 0x3474: 0x000d, 0x3475: 0x000d, + 0x3476: 0x000d, 0x3477: 0x000d, 0x3478: 0x000d, 0x3479: 0x000d, 0x347a: 0x000d, 0x347b: 0x000d, + 0x347c: 0x000d, 0x347d: 0x000d, 0x347e: 0x000d, 0x347f: 0x000d, + // Block 0xd2, offset 0x3480 + 0x3480: 0x000a, 0x3481: 0x000a, 0x3482: 0x000a, 0x3483: 0x000a, 0x3484: 0x000a, 0x3485: 0x000a, + 0x3486: 0x000a, 0x3487: 0x000a, 0x3488: 0x000a, 0x3489: 0x000a, 0x348a: 0x000a, 0x348b: 0x000a, + 0x348c: 0x000a, 0x348d: 0x000a, 0x348e: 0x000a, 0x348f: 0x000a, 0x3490: 0x000a, 0x3491: 0x000a, + 0x3492: 0x000a, 0x3493: 0x000a, 0x3494: 0x000a, 0x3495: 0x000a, 0x3496: 0x000a, 0x3497: 0x000a, + 0x3498: 0x000a, 0x3499: 0x000a, 0x349a: 0x000a, 0x349b: 0x000a, 0x349c: 0x000a, 0x349d: 0x000a, + 0x349e: 0x000a, 0x349f: 0x000a, 0x34a0: 0x000a, 0x34a1: 0x000a, 0x34a2: 0x000a, 0x34a3: 0x000a, + 0x34a4: 0x000a, 0x34a5: 0x000a, 0x34a6: 0x000a, 0x34a7: 0x000a, 0x34a8: 0x000a, 0x34a9: 0x000a, + 0x34aa: 0x000a, 0x34ab: 0x000a, + 0x34b0: 0x000a, 0x34b1: 0x000a, 0x34b2: 0x000a, 0x34b3: 0x000a, 0x34b4: 0x000a, 0x34b5: 0x000a, + 0x34b6: 0x000a, 0x34b7: 0x000a, 0x34b8: 0x000a, 0x34b9: 0x000a, 0x34ba: 0x000a, 0x34bb: 0x000a, + 0x34bc: 0x000a, 0x34bd: 0x000a, 0x34be: 0x000a, 0x34bf: 0x000a, + // Block 0xd3, offset 0x34c0 + 0x34c0: 0x000a, 0x34c1: 0x000a, 0x34c2: 0x000a, 0x34c3: 0x000a, 0x34c4: 0x000a, 0x34c5: 0x000a, + 0x34c6: 0x000a, 0x34c7: 0x000a, 0x34c8: 0x000a, 0x34c9: 0x000a, 0x34ca: 0x000a, 0x34cb: 0x000a, + 0x34cc: 0x000a, 0x34cd: 0x000a, 0x34ce: 0x000a, 0x34cf: 0x000a, 0x34d0: 0x000a, 0x34d1: 0x000a, + 0x34d2: 0x000a, 0x34d3: 0x000a, + 0x34e0: 0x000a, 0x34e1: 0x000a, 0x34e2: 0x000a, 0x34e3: 0x000a, + 0x34e4: 0x000a, 0x34e5: 0x000a, 0x34e6: 0x000a, 0x34e7: 0x000a, 0x34e8: 0x000a, 0x34e9: 0x000a, + 0x34ea: 0x000a, 0x34eb: 0x000a, 0x34ec: 0x000a, 0x34ed: 0x000a, 0x34ee: 0x000a, + 0x34f1: 0x000a, 0x34f2: 0x000a, 0x34f3: 0x000a, 0x34f4: 0x000a, 0x34f5: 0x000a, + 0x34f6: 0x000a, 0x34f7: 0x000a, 0x34f8: 0x000a, 0x34f9: 0x000a, 0x34fa: 0x000a, 0x34fb: 0x000a, + 0x34fc: 0x000a, 0x34fd: 0x000a, 0x34fe: 0x000a, 0x34ff: 0x000a, + // Block 0xd4, offset 0x3500 + 0x3501: 0x000a, 0x3502: 0x000a, 0x3503: 0x000a, 0x3504: 0x000a, 0x3505: 0x000a, + 0x3506: 0x000a, 0x3507: 0x000a, 0x3508: 0x000a, 0x3509: 0x000a, 0x350a: 0x000a, 0x350b: 0x000a, + 0x350c: 0x000a, 0x350d: 0x000a, 0x350e: 0x000a, 0x350f: 0x000a, 0x3511: 0x000a, + 0x3512: 0x000a, 0x3513: 0x000a, 0x3514: 0x000a, 0x3515: 0x000a, 0x3516: 0x000a, 0x3517: 0x000a, + 0x3518: 0x000a, 0x3519: 0x000a, 0x351a: 0x000a, 0x351b: 0x000a, 0x351c: 0x000a, 0x351d: 0x000a, + 0x351e: 0x000a, 0x351f: 0x000a, 0x3520: 0x000a, 0x3521: 0x000a, 0x3522: 0x000a, 0x3523: 0x000a, + 0x3524: 0x000a, 0x3525: 0x000a, 0x3526: 0x000a, 0x3527: 0x000a, 0x3528: 0x000a, 0x3529: 0x000a, + 0x352a: 0x000a, 0x352b: 0x000a, 0x352c: 0x000a, 0x352d: 0x000a, 0x352e: 0x000a, 0x352f: 0x000a, + 0x3530: 0x000a, 0x3531: 0x000a, 0x3532: 0x000a, 0x3533: 0x000a, 0x3534: 0x000a, 0x3535: 0x000a, + // Block 0xd5, offset 0x3540 + 0x3540: 0x0002, 0x3541: 0x0002, 0x3542: 0x0002, 0x3543: 0x0002, 0x3544: 0x0002, 0x3545: 0x0002, + 0x3546: 0x0002, 0x3547: 0x0002, 0x3548: 0x0002, 0x3549: 0x0002, 0x354a: 0x0002, 0x354b: 0x000a, + 0x354c: 0x000a, + // Block 0xd6, offset 0x3580 + 0x35aa: 0x000a, 0x35ab: 0x000a, + // Block 0xd7, offset 0x35c0 + 0x35e0: 0x000a, 0x35e1: 0x000a, 0x35e2: 0x000a, 0x35e3: 0x000a, + 0x35e4: 0x000a, 0x35e5: 0x000a, + // Block 0xd8, offset 0x3600 + 0x3600: 0x000a, 0x3601: 0x000a, 0x3602: 0x000a, 0x3603: 0x000a, 0x3604: 0x000a, 0x3605: 0x000a, + 0x3606: 0x000a, 0x3607: 0x000a, 0x3608: 0x000a, 0x3609: 0x000a, 0x360a: 0x000a, 0x360b: 0x000a, + 0x360c: 0x000a, 0x360d: 0x000a, 0x360e: 0x000a, 0x360f: 0x000a, 0x3610: 0x000a, 0x3611: 0x000a, + 0x3612: 0x000a, 0x3613: 0x000a, 0x3614: 0x000a, + 0x3620: 0x000a, 0x3621: 0x000a, 0x3622: 0x000a, 0x3623: 0x000a, + 0x3624: 0x000a, 0x3625: 0x000a, 0x3626: 0x000a, 0x3627: 0x000a, 0x3628: 0x000a, 0x3629: 0x000a, + 0x362a: 0x000a, 0x362b: 0x000a, 0x362c: 0x000a, + 0x3630: 0x000a, 0x3631: 0x000a, 0x3632: 0x000a, 0x3633: 0x000a, 0x3634: 0x000a, 0x3635: 0x000a, + 0x3636: 0x000a, 0x3637: 0x000a, 0x3638: 0x000a, + // Block 0xd9, offset 0x3640 + 0x3640: 0x000a, 0x3641: 0x000a, 0x3642: 0x000a, 0x3643: 0x000a, 0x3644: 0x000a, 0x3645: 0x000a, + 0x3646: 0x000a, 0x3647: 0x000a, 0x3648: 0x000a, 0x3649: 0x000a, 0x364a: 0x000a, 0x364b: 0x000a, + 0x364c: 0x000a, 0x364d: 0x000a, 0x364e: 0x000a, 0x364f: 0x000a, 0x3650: 0x000a, 0x3651: 0x000a, + 0x3652: 0x000a, 0x3653: 0x000a, 0x3654: 0x000a, + // Block 0xda, offset 0x3680 + 0x3680: 0x000a, 0x3681: 0x000a, 0x3682: 0x000a, 0x3683: 0x000a, 0x3684: 0x000a, 0x3685: 0x000a, + 0x3686: 0x000a, 0x3687: 0x000a, 0x3688: 0x000a, 0x3689: 0x000a, 0x368a: 0x000a, 0x368b: 0x000a, + 0x3690: 0x000a, 0x3691: 0x000a, + 0x3692: 0x000a, 0x3693: 0x000a, 0x3694: 0x000a, 0x3695: 0x000a, 0x3696: 0x000a, 0x3697: 0x000a, + 0x3698: 0x000a, 0x3699: 0x000a, 0x369a: 0x000a, 0x369b: 0x000a, 0x369c: 0x000a, 0x369d: 0x000a, + 0x369e: 0x000a, 0x369f: 0x000a, 0x36a0: 0x000a, 0x36a1: 0x000a, 0x36a2: 0x000a, 0x36a3: 0x000a, + 0x36a4: 0x000a, 0x36a5: 0x000a, 0x36a6: 0x000a, 0x36a7: 0x000a, 0x36a8: 0x000a, 0x36a9: 0x000a, + 0x36aa: 0x000a, 0x36ab: 0x000a, 0x36ac: 0x000a, 0x36ad: 0x000a, 0x36ae: 0x000a, 0x36af: 0x000a, + 0x36b0: 0x000a, 0x36b1: 0x000a, 0x36b2: 0x000a, 0x36b3: 0x000a, 0x36b4: 0x000a, 0x36b5: 0x000a, + 0x36b6: 0x000a, 0x36b7: 0x000a, 0x36b8: 0x000a, 0x36b9: 0x000a, 0x36ba: 0x000a, 0x36bb: 0x000a, + 0x36bc: 0x000a, 0x36bd: 0x000a, 0x36be: 0x000a, 0x36bf: 0x000a, + // Block 0xdb, offset 0x36c0 + 0x36c0: 0x000a, 0x36c1: 0x000a, 0x36c2: 0x000a, 0x36c3: 0x000a, 0x36c4: 0x000a, 0x36c5: 0x000a, + 0x36c6: 0x000a, 0x36c7: 0x000a, + 0x36d0: 0x000a, 0x36d1: 0x000a, + 0x36d2: 0x000a, 0x36d3: 0x000a, 0x36d4: 0x000a, 0x36d5: 0x000a, 0x36d6: 0x000a, 0x36d7: 0x000a, + 0x36d8: 0x000a, 0x36d9: 0x000a, + 0x36e0: 0x000a, 0x36e1: 0x000a, 0x36e2: 0x000a, 0x36e3: 0x000a, + 0x36e4: 0x000a, 0x36e5: 0x000a, 0x36e6: 0x000a, 0x36e7: 0x000a, 0x36e8: 0x000a, 0x36e9: 0x000a, + 0x36ea: 0x000a, 0x36eb: 0x000a, 0x36ec: 0x000a, 0x36ed: 0x000a, 0x36ee: 0x000a, 0x36ef: 0x000a, + 0x36f0: 0x000a, 0x36f1: 0x000a, 0x36f2: 0x000a, 0x36f3: 0x000a, 0x36f4: 0x000a, 0x36f5: 0x000a, + 0x36f6: 0x000a, 0x36f7: 0x000a, 0x36f8: 0x000a, 0x36f9: 0x000a, 0x36fa: 0x000a, 0x36fb: 0x000a, + 0x36fc: 0x000a, 0x36fd: 0x000a, 0x36fe: 0x000a, 0x36ff: 0x000a, + // Block 0xdc, offset 0x3700 + 0x3700: 0x000a, 0x3701: 0x000a, 0x3702: 0x000a, 0x3703: 0x000a, 0x3704: 0x000a, 0x3705: 0x000a, + 0x3706: 0x000a, 0x3707: 0x000a, + 0x3710: 0x000a, 0x3711: 0x000a, + 0x3712: 0x000a, 0x3713: 0x000a, 0x3714: 0x000a, 0x3715: 0x000a, 0x3716: 0x000a, 0x3717: 0x000a, + 0x3718: 0x000a, 0x3719: 0x000a, 0x371a: 0x000a, 0x371b: 0x000a, 0x371c: 0x000a, 0x371d: 0x000a, + 0x371e: 0x000a, 0x371f: 0x000a, 0x3720: 0x000a, 0x3721: 0x000a, 0x3722: 0x000a, 0x3723: 0x000a, + 0x3724: 0x000a, 0x3725: 0x000a, 0x3726: 0x000a, 0x3727: 0x000a, 0x3728: 0x000a, 0x3729: 0x000a, + 0x372a: 0x000a, 0x372b: 0x000a, 0x372c: 0x000a, 0x372d: 0x000a, + // Block 0xdd, offset 0x3740 + 0x3740: 0x000a, 0x3741: 0x000a, 0x3742: 0x000a, 0x3743: 0x000a, 0x3744: 0x000a, 0x3745: 0x000a, + 0x3746: 0x000a, 0x3747: 0x000a, 0x3748: 0x000a, 0x3749: 0x000a, 0x374a: 0x000a, 0x374b: 0x000a, + 0x3750: 0x000a, 0x3751: 0x000a, + 0x3752: 0x000a, 0x3753: 0x000a, 0x3754: 0x000a, 0x3755: 0x000a, 0x3756: 0x000a, 0x3757: 0x000a, + 0x3758: 0x000a, 0x3759: 0x000a, 0x375a: 0x000a, 0x375b: 0x000a, 0x375c: 0x000a, 0x375d: 0x000a, + 0x375e: 0x000a, 0x375f: 0x000a, 0x3760: 0x000a, 0x3761: 0x000a, 0x3762: 0x000a, 0x3763: 0x000a, + 0x3764: 0x000a, 0x3765: 0x000a, 0x3766: 0x000a, 0x3767: 0x000a, 0x3768: 0x000a, 0x3769: 0x000a, + 0x376a: 0x000a, 0x376b: 0x000a, 0x376c: 0x000a, 0x376d: 0x000a, 0x376e: 0x000a, 0x376f: 0x000a, + 0x3770: 0x000a, 0x3771: 0x000a, 0x3772: 0x000a, 0x3773: 0x000a, 0x3774: 0x000a, 0x3775: 0x000a, + 0x3776: 0x000a, 0x3777: 0x000a, 0x3778: 0x000a, 0x3779: 0x000a, 0x377a: 0x000a, 0x377b: 0x000a, + 0x377c: 0x000a, 0x377d: 0x000a, 0x377e: 0x000a, + // Block 0xde, offset 0x3780 + 0x3780: 0x000a, 0x3781: 0x000a, 0x3782: 0x000a, 0x3783: 0x000a, 0x3784: 0x000a, 0x3785: 0x000a, + 0x3786: 0x000a, 0x3787: 0x000a, 0x3788: 0x000a, 0x3789: 0x000a, 0x378a: 0x000a, 0x378b: 0x000a, + 0x378c: 0x000a, 0x3790: 0x000a, 0x3791: 0x000a, + 0x3792: 0x000a, 0x3793: 0x000a, 0x3794: 0x000a, 0x3795: 0x000a, 0x3796: 0x000a, 0x3797: 0x000a, + 0x3798: 0x000a, 0x3799: 0x000a, 0x379a: 0x000a, 0x379b: 0x000a, 0x379c: 0x000a, 0x379d: 0x000a, + 0x379e: 0x000a, 0x379f: 0x000a, 0x37a0: 0x000a, 0x37a1: 0x000a, 0x37a2: 0x000a, 0x37a3: 0x000a, + 0x37a4: 0x000a, 0x37a5: 0x000a, 0x37a6: 0x000a, 0x37a7: 0x000a, 0x37a8: 0x000a, 0x37a9: 0x000a, + 0x37aa: 0x000a, 0x37ab: 0x000a, + // Block 0xdf, offset 0x37c0 + 0x37c0: 0x000a, 0x37c1: 0x000a, 0x37c2: 0x000a, 0x37c3: 0x000a, 0x37c4: 0x000a, 0x37c5: 0x000a, + 0x37c6: 0x000a, 0x37c7: 0x000a, 0x37c8: 0x000a, 0x37c9: 0x000a, 0x37ca: 0x000a, 0x37cb: 0x000a, + 0x37cc: 0x000a, 0x37cd: 0x000a, 0x37ce: 0x000a, 0x37cf: 0x000a, 0x37d0: 0x000a, 0x37d1: 0x000a, + 0x37d2: 0x000a, 0x37d3: 0x000a, 0x37d4: 0x000a, 0x37d5: 0x000a, 0x37d6: 0x000a, 0x37d7: 0x000a, + // Block 0xe0, offset 0x3800 + 0x3800: 0x000a, + 0x3810: 0x000a, 0x3811: 0x000a, + 0x3812: 0x000a, 0x3813: 0x000a, 0x3814: 0x000a, 0x3815: 0x000a, 0x3816: 0x000a, 0x3817: 0x000a, + 0x3818: 0x000a, 0x3819: 0x000a, 0x381a: 0x000a, 0x381b: 0x000a, 0x381c: 0x000a, 0x381d: 0x000a, + 0x381e: 0x000a, 0x381f: 0x000a, 0x3820: 0x000a, 0x3821: 0x000a, 0x3822: 0x000a, 0x3823: 0x000a, + 0x3824: 0x000a, 0x3825: 0x000a, 0x3826: 0x000a, + // Block 0xe1, offset 0x3840 + 0x387e: 0x000b, 0x387f: 0x000b, + // Block 0xe2, offset 0x3880 + 0x3880: 0x000b, 0x3881: 0x000b, 0x3882: 0x000b, 0x3883: 0x000b, 0x3884: 0x000b, 0x3885: 0x000b, + 0x3886: 0x000b, 0x3887: 0x000b, 0x3888: 0x000b, 0x3889: 0x000b, 0x388a: 0x000b, 0x388b: 0x000b, + 0x388c: 0x000b, 0x388d: 0x000b, 0x388e: 0x000b, 0x388f: 0x000b, 0x3890: 0x000b, 0x3891: 0x000b, + 0x3892: 0x000b, 0x3893: 0x000b, 0x3894: 0x000b, 0x3895: 0x000b, 0x3896: 0x000b, 0x3897: 0x000b, + 0x3898: 0x000b, 0x3899: 0x000b, 0x389a: 0x000b, 0x389b: 0x000b, 0x389c: 0x000b, 0x389d: 0x000b, + 0x389e: 0x000b, 0x389f: 0x000b, 0x38a0: 0x000b, 0x38a1: 0x000b, 0x38a2: 0x000b, 0x38a3: 0x000b, + 0x38a4: 0x000b, 0x38a5: 0x000b, 0x38a6: 0x000b, 0x38a7: 0x000b, 0x38a8: 0x000b, 0x38a9: 0x000b, + 0x38aa: 0x000b, 0x38ab: 0x000b, 0x38ac: 0x000b, 0x38ad: 0x000b, 0x38ae: 0x000b, 0x38af: 0x000b, + 0x38b0: 0x000b, 0x38b1: 0x000b, 0x38b2: 0x000b, 0x38b3: 0x000b, 0x38b4: 0x000b, 0x38b5: 0x000b, + 0x38b6: 0x000b, 0x38b7: 0x000b, 0x38b8: 0x000b, 0x38b9: 0x000b, 0x38ba: 0x000b, 0x38bb: 0x000b, + 0x38bc: 0x000b, 0x38bd: 0x000b, 0x38be: 0x000b, 0x38bf: 0x000b, + // Block 0xe3, offset 0x38c0 + 0x38c0: 0x000c, 0x38c1: 0x000c, 0x38c2: 0x000c, 0x38c3: 0x000c, 0x38c4: 0x000c, 0x38c5: 0x000c, + 0x38c6: 0x000c, 0x38c7: 0x000c, 0x38c8: 0x000c, 0x38c9: 0x000c, 0x38ca: 0x000c, 0x38cb: 0x000c, + 0x38cc: 0x000c, 0x38cd: 0x000c, 0x38ce: 0x000c, 0x38cf: 0x000c, 0x38d0: 0x000c, 0x38d1: 0x000c, + 0x38d2: 0x000c, 0x38d3: 0x000c, 0x38d4: 0x000c, 0x38d5: 0x000c, 0x38d6: 0x000c, 0x38d7: 0x000c, + 0x38d8: 0x000c, 0x38d9: 0x000c, 0x38da: 0x000c, 0x38db: 0x000c, 0x38dc: 0x000c, 0x38dd: 0x000c, + 0x38de: 0x000c, 0x38df: 0x000c, 0x38e0: 0x000c, 0x38e1: 0x000c, 0x38e2: 0x000c, 0x38e3: 0x000c, + 0x38e4: 0x000c, 0x38e5: 0x000c, 0x38e6: 0x000c, 0x38e7: 0x000c, 0x38e8: 0x000c, 0x38e9: 0x000c, + 0x38ea: 0x000c, 0x38eb: 0x000c, 0x38ec: 0x000c, 0x38ed: 0x000c, 0x38ee: 0x000c, 0x38ef: 0x000c, + 0x38f0: 0x000b, 0x38f1: 0x000b, 0x38f2: 0x000b, 0x38f3: 0x000b, 0x38f4: 0x000b, 0x38f5: 0x000b, + 0x38f6: 0x000b, 0x38f7: 0x000b, 0x38f8: 0x000b, 0x38f9: 0x000b, 0x38fa: 0x000b, 0x38fb: 0x000b, + 0x38fc: 0x000b, 0x38fd: 0x000b, 0x38fe: 0x000b, 0x38ff: 0x000b, +} + +// bidiIndex: 24 blocks, 1536 entries, 1536 bytes +// Block 0 is the zero block. +var bidiIndex = [1536]uint8{ + // Block 0x0, offset 0x0 + // Block 0x1, offset 0x40 + // Block 0x2, offset 0x80 + // Block 0x3, offset 0xc0 + 0xc2: 0x01, 0xc3: 0x02, + 0xca: 0x03, 0xcb: 0x04, 0xcc: 0x05, 0xcd: 0x06, 0xce: 0x07, 0xcf: 0x08, + 0xd2: 0x09, 0xd6: 0x0a, 0xd7: 0x0b, + 0xd8: 0x0c, 0xd9: 0x0d, 0xda: 0x0e, 0xdb: 0x0f, 0xdc: 0x10, 0xdd: 0x11, 0xde: 0x12, 0xdf: 0x13, + 0xe0: 0x02, 0xe1: 0x03, 0xe2: 0x04, 0xe3: 0x05, 0xe4: 0x06, + 0xea: 0x07, 0xef: 0x08, + 0xf0: 0x11, 0xf1: 0x12, 0xf2: 0x12, 0xf3: 0x14, 0xf4: 0x15, + // Block 0x4, offset 0x100 + 0x120: 0x14, 0x121: 0x15, 0x122: 0x16, 0x123: 0x17, 0x124: 0x18, 0x125: 0x19, 0x126: 0x1a, 0x127: 0x1b, + 0x128: 0x1c, 0x129: 0x1d, 0x12a: 0x1c, 0x12b: 0x1e, 0x12c: 0x1f, 0x12d: 0x20, 0x12e: 0x21, 0x12f: 0x22, + 0x130: 0x23, 0x131: 0x24, 0x132: 0x1a, 0x133: 0x25, 0x134: 0x26, 0x135: 0x27, 0x137: 0x28, + 0x138: 0x29, 0x139: 0x2a, 0x13a: 0x2b, 0x13b: 0x2c, 0x13c: 0x2d, 0x13d: 0x2e, 0x13e: 0x2f, 0x13f: 0x30, + // Block 0x5, offset 0x140 + 0x140: 0x31, 0x141: 0x32, 0x142: 0x33, + 0x14d: 0x34, 0x14e: 0x35, + 0x150: 0x36, + 0x15a: 0x37, 0x15c: 0x38, 0x15d: 0x39, 0x15e: 0x3a, 0x15f: 0x3b, + 0x160: 0x3c, 0x162: 0x3d, 0x164: 0x3e, 0x165: 0x3f, 0x167: 0x40, + 0x168: 0x41, 0x169: 0x42, 0x16a: 0x43, 0x16c: 0x44, 0x16d: 0x45, 0x16e: 0x46, 0x16f: 0x47, + 0x170: 0x48, 0x173: 0x49, 0x177: 0x4a, + 0x17e: 0x4b, 0x17f: 0x4c, + // Block 0x6, offset 0x180 + 0x180: 0x4d, 0x181: 0x4e, 0x182: 0x4f, 0x183: 0x50, 0x184: 0x51, 0x185: 0x52, 0x186: 0x53, 0x187: 0x54, + 0x188: 0x55, 0x189: 0x54, 0x18a: 0x54, 0x18b: 0x54, 0x18c: 0x56, 0x18d: 0x57, 0x18e: 0x58, 0x18f: 0x54, + 0x190: 0x59, 0x191: 0x5a, 0x192: 0x5b, 0x193: 0x5c, 0x194: 0x54, 0x195: 0x54, 0x196: 0x54, 0x197: 0x54, + 0x198: 0x54, 0x199: 0x54, 0x19a: 0x5d, 0x19b: 0x54, 0x19c: 0x54, 0x19d: 0x5e, 0x19e: 0x54, 0x19f: 0x5f, + 0x1a4: 0x54, 0x1a5: 0x54, 0x1a6: 0x60, 0x1a7: 0x61, + 0x1a8: 0x54, 0x1a9: 0x54, 0x1aa: 0x54, 0x1ab: 0x54, 0x1ac: 0x54, 0x1ad: 0x62, 0x1ae: 0x63, 0x1af: 0x64, + 0x1b3: 0x65, 0x1b5: 0x66, 0x1b7: 0x67, + 0x1b8: 0x68, 0x1b9: 0x69, 0x1ba: 0x6a, 0x1bb: 0x6b, 0x1bc: 0x54, 0x1bd: 0x54, 0x1be: 0x54, 0x1bf: 0x6c, + // Block 0x7, offset 0x1c0 + 0x1c0: 0x6d, 0x1c2: 0x6e, 0x1c3: 0x6f, 0x1c7: 0x70, + 0x1c8: 0x71, 0x1c9: 0x72, 0x1ca: 0x73, 0x1cb: 0x74, 0x1cd: 0x75, 0x1cf: 0x76, + // Block 0x8, offset 0x200 + 0x237: 0x54, + // Block 0x9, offset 0x240 + 0x252: 0x77, 0x253: 0x78, + 0x258: 0x79, 0x259: 0x7a, 0x25a: 0x7b, 0x25b: 0x7c, 0x25c: 0x7d, 0x25e: 0x7e, + 0x260: 0x7f, 0x261: 0x80, 0x263: 0x81, 0x264: 0x82, 0x265: 0x83, 0x266: 0x84, 0x267: 0x85, + 0x268: 0x86, 0x269: 0x87, 0x26a: 0x88, 0x26b: 0x89, 0x26f: 0x8a, + // Block 0xa, offset 0x280 + 0x2ac: 0x8b, 0x2ad: 0x8c, 0x2ae: 0x0e, 0x2af: 0x0e, + 0x2b0: 0x0e, 0x2b1: 0x0e, 0x2b2: 0x0e, 0x2b3: 0x0e, 0x2b4: 0x8d, 0x2b5: 0x0e, 0x2b6: 0x0e, 0x2b7: 0x8e, + 0x2b8: 0x8f, 0x2b9: 0x90, 0x2ba: 0x0e, 0x2bb: 0x91, 0x2bc: 0x92, 0x2bd: 0x93, 0x2bf: 0x94, + // Block 0xb, offset 0x2c0 + 0x2c4: 0x95, 0x2c5: 0x54, 0x2c6: 0x96, 0x2c7: 0x97, + 0x2cb: 0x98, 0x2cd: 0x99, + 0x2e0: 0x9a, 0x2e1: 0x9a, 0x2e2: 0x9a, 0x2e3: 0x9a, 0x2e4: 0x9b, 0x2e5: 0x9a, 0x2e6: 0x9a, 0x2e7: 0x9a, + 0x2e8: 0x9c, 0x2e9: 0x9a, 0x2ea: 0x9a, 0x2eb: 0x9d, 0x2ec: 0x9e, 0x2ed: 0x9a, 0x2ee: 0x9a, 0x2ef: 0x9a, + 0x2f0: 0x9a, 0x2f1: 0x9a, 0x2f2: 0x9a, 0x2f3: 0x9a, 0x2f4: 0x9a, 0x2f5: 0x9a, 0x2f6: 0x9a, 0x2f7: 0x9a, + 0x2f8: 0x9a, 0x2f9: 0x9f, 0x2fa: 0x9a, 0x2fb: 0x9a, 0x2fc: 0x9a, 0x2fd: 0x9a, 0x2fe: 0x9a, 0x2ff: 0x9a, + // Block 0xc, offset 0x300 + 0x300: 0xa0, 0x301: 0xa1, 0x302: 0xa2, 0x304: 0xa3, 0x305: 0xa4, 0x306: 0xa5, 0x307: 0xa6, + 0x308: 0xa7, 0x30b: 0xa8, 0x30c: 0xa9, 0x30d: 0xaa, + 0x310: 0xab, 0x311: 0xac, 0x312: 0xad, 0x313: 0xae, 0x316: 0xaf, 0x317: 0xb0, + 0x318: 0xb1, 0x319: 0xb2, 0x31a: 0xb3, 0x31c: 0xb4, + 0x328: 0xb5, 0x329: 0xb6, 0x32a: 0xb7, + 0x330: 0xb8, 0x332: 0xb9, 0x334: 0xba, 0x335: 0xbb, + // Block 0xd, offset 0x340 + 0x36b: 0xbc, 0x36c: 0xbd, + 0x37e: 0xbe, + // Block 0xe, offset 0x380 + 0x3b2: 0xbf, + // Block 0xf, offset 0x3c0 + 0x3c5: 0xc0, 0x3c6: 0xc1, + 0x3c8: 0x54, 0x3c9: 0xc2, 0x3cc: 0x54, 0x3cd: 0xc3, + 0x3db: 0xc4, 0x3dc: 0xc5, 0x3dd: 0xc6, 0x3de: 0xc7, 0x3df: 0xc8, + 0x3e8: 0xc9, 0x3e9: 0xca, 0x3ea: 0xcb, + // Block 0x10, offset 0x400 + 0x400: 0xcc, + 0x420: 0x9a, 0x421: 0x9a, 0x422: 0x9a, 0x423: 0xcd, 0x424: 0x9a, 0x425: 0xce, 0x426: 0x9a, 0x427: 0x9a, + 0x428: 0x9a, 0x429: 0x9a, 0x42a: 0x9a, 0x42b: 0x9a, 0x42c: 0x9a, 0x42d: 0x9a, 0x42e: 0x9a, 0x42f: 0x9a, + 0x430: 0x9a, 0x431: 0x9a, 0x432: 0x9a, 0x433: 0x9a, 0x434: 0x9a, 0x435: 0x9a, 0x436: 0x9a, 0x437: 0x9a, + 0x438: 0x0e, 0x439: 0x0e, 0x43a: 0x0e, 0x43b: 0xcf, 0x43c: 0x9a, 0x43d: 0x9a, 0x43e: 0x9a, 0x43f: 0x9a, + // Block 0x11, offset 0x440 + 0x440: 0xd0, 0x441: 0x54, 0x442: 0xd1, 0x443: 0xd2, 0x444: 0xd3, 0x445: 0xd4, + 0x449: 0xd5, 0x44c: 0x54, 0x44d: 0x54, 0x44e: 0x54, 0x44f: 0x54, + 0x450: 0x54, 0x451: 0x54, 0x452: 0x54, 0x453: 0x54, 0x454: 0x54, 0x455: 0x54, 0x456: 0x54, 0x457: 0x54, + 0x458: 0x54, 0x459: 0x54, 0x45a: 0x54, 0x45b: 0xd6, 0x45c: 0x54, 0x45d: 0x6b, 0x45e: 0x54, 0x45f: 0xd7, + 0x460: 0xd8, 0x461: 0xd9, 0x462: 0xda, 0x464: 0xdb, 0x465: 0xdc, 0x466: 0xdd, 0x467: 0xde, + 0x47f: 0xdf, + // Block 0x12, offset 0x480 + 0x4bf: 0xdf, + // Block 0x13, offset 0x4c0 + 0x4d0: 0x09, 0x4d1: 0x0a, 0x4d6: 0x0b, + 0x4db: 0x0c, 0x4dd: 0x0d, 0x4de: 0x0e, 0x4df: 0x0f, + 0x4ef: 0x10, + 0x4ff: 0x10, + // Block 0x14, offset 0x500 + 0x50f: 0x10, + 0x51f: 0x10, + 0x52f: 0x10, + 0x53f: 0x10, + // Block 0x15, offset 0x540 + 0x540: 0xe0, 0x541: 0xe0, 0x542: 0xe0, 0x543: 0xe0, 0x544: 0x05, 0x545: 0x05, 0x546: 0x05, 0x547: 0xe1, + 0x548: 0xe0, 0x549: 0xe0, 0x54a: 0xe0, 0x54b: 0xe0, 0x54c: 0xe0, 0x54d: 0xe0, 0x54e: 0xe0, 0x54f: 0xe0, + 0x550: 0xe0, 0x551: 0xe0, 0x552: 0xe0, 0x553: 0xe0, 0x554: 0xe0, 0x555: 0xe0, 0x556: 0xe0, 0x557: 0xe0, + 0x558: 0xe0, 0x559: 0xe0, 0x55a: 0xe0, 0x55b: 0xe0, 0x55c: 0xe0, 0x55d: 0xe0, 0x55e: 0xe0, 0x55f: 0xe0, + 0x560: 0xe0, 0x561: 0xe0, 0x562: 0xe0, 0x563: 0xe0, 0x564: 0xe0, 0x565: 0xe0, 0x566: 0xe0, 0x567: 0xe0, + 0x568: 0xe0, 0x569: 0xe0, 0x56a: 0xe0, 0x56b: 0xe0, 0x56c: 0xe0, 0x56d: 0xe0, 0x56e: 0xe0, 0x56f: 0xe0, + 0x570: 0xe0, 0x571: 0xe0, 0x572: 0xe0, 0x573: 0xe0, 0x574: 0xe0, 0x575: 0xe0, 0x576: 0xe0, 0x577: 0xe0, + 0x578: 0xe0, 0x579: 0xe0, 0x57a: 0xe0, 0x57b: 0xe0, 0x57c: 0xe0, 0x57d: 0xe0, 0x57e: 0xe0, 0x57f: 0xe0, + // Block 0x16, offset 0x580 + 0x58f: 0x10, + 0x59f: 0x10, + 0x5a0: 0x13, + 0x5af: 0x10, + 0x5bf: 0x10, + // Block 0x17, offset 0x5c0 + 0x5cf: 0x10, +} + +// Total table size 16184 bytes (15KiB); checksum: F50EF68C diff --git a/vendor/golang.org/x/text/unicode/bidi/tables9.0.0.go b/vendor/golang.org/x/text/unicode/bidi/tables9.0.0.go new file mode 100644 index 0000000000..0ca0193ebe --- /dev/null +++ b/vendor/golang.org/x/text/unicode/bidi/tables9.0.0.go @@ -0,0 +1,1781 @@ +// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. + +// +build !go1.10 + +package bidi + +// UnicodeVersion is the Unicode version from which the tables in this package are derived. +const UnicodeVersion = "9.0.0" + +// xorMasks contains masks to be xor-ed with brackets to get the reverse +// version. +var xorMasks = []int32{ // 8 elements + 0, 1, 6, 7, 3, 15, 29, 63, +} // Size: 56 bytes + +// lookup returns the trie value for the first UTF-8 encoding in s and +// the width in bytes of this encoding. The size will be 0 if s does not +// hold enough bytes to complete the encoding. len(s) must be greater than 0. +func (t *bidiTrie) lookup(s []byte) (v uint8, sz int) { + c0 := s[0] + switch { + case c0 < 0x80: // is ASCII + return bidiValues[c0], 1 + case c0 < 0xC2: + return 0, 1 // Illegal UTF-8: not a starter, not ASCII. + case c0 < 0xE0: // 2-byte UTF-8 + if len(s) < 2 { + return 0, 0 + } + i := bidiIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c1), 2 + case c0 < 0xF0: // 3-byte UTF-8 + if len(s) < 3 { + return 0, 0 + } + i := bidiIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = bidiIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c2), 3 + case c0 < 0xF8: // 4-byte UTF-8 + if len(s) < 4 { + return 0, 0 + } + i := bidiIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = bidiIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + o = uint32(i)<<6 + uint32(c2) + i = bidiIndex[o] + c3 := s[3] + if c3 < 0x80 || 0xC0 <= c3 { + return 0, 3 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c3), 4 + } + // Illegal rune + return 0, 1 +} + +// lookupUnsafe returns the trie value for the first UTF-8 encoding in s. +// s must start with a full and valid UTF-8 encoded rune. +func (t *bidiTrie) lookupUnsafe(s []byte) uint8 { + c0 := s[0] + if c0 < 0x80 { // is ASCII + return bidiValues[c0] + } + i := bidiIndex[c0] + if c0 < 0xE0 { // 2-byte UTF-8 + return t.lookupValue(uint32(i), s[1]) + } + i = bidiIndex[uint32(i)<<6+uint32(s[1])] + if c0 < 0xF0 { // 3-byte UTF-8 + return t.lookupValue(uint32(i), s[2]) + } + i = bidiIndex[uint32(i)<<6+uint32(s[2])] + if c0 < 0xF8 { // 4-byte UTF-8 + return t.lookupValue(uint32(i), s[3]) + } + return 0 +} + +// lookupString returns the trie value for the first UTF-8 encoding in s and +// the width in bytes of this encoding. The size will be 0 if s does not +// hold enough bytes to complete the encoding. len(s) must be greater than 0. +func (t *bidiTrie) lookupString(s string) (v uint8, sz int) { + c0 := s[0] + switch { + case c0 < 0x80: // is ASCII + return bidiValues[c0], 1 + case c0 < 0xC2: + return 0, 1 // Illegal UTF-8: not a starter, not ASCII. + case c0 < 0xE0: // 2-byte UTF-8 + if len(s) < 2 { + return 0, 0 + } + i := bidiIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c1), 2 + case c0 < 0xF0: // 3-byte UTF-8 + if len(s) < 3 { + return 0, 0 + } + i := bidiIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = bidiIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c2), 3 + case c0 < 0xF8: // 4-byte UTF-8 + if len(s) < 4 { + return 0, 0 + } + i := bidiIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = bidiIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + o = uint32(i)<<6 + uint32(c2) + i = bidiIndex[o] + c3 := s[3] + if c3 < 0x80 || 0xC0 <= c3 { + return 0, 3 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c3), 4 + } + // Illegal rune + return 0, 1 +} + +// lookupStringUnsafe returns the trie value for the first UTF-8 encoding in s. +// s must start with a full and valid UTF-8 encoded rune. +func (t *bidiTrie) lookupStringUnsafe(s string) uint8 { + c0 := s[0] + if c0 < 0x80 { // is ASCII + return bidiValues[c0] + } + i := bidiIndex[c0] + if c0 < 0xE0 { // 2-byte UTF-8 + return t.lookupValue(uint32(i), s[1]) + } + i = bidiIndex[uint32(i)<<6+uint32(s[1])] + if c0 < 0xF0 { // 3-byte UTF-8 + return t.lookupValue(uint32(i), s[2]) + } + i = bidiIndex[uint32(i)<<6+uint32(s[2])] + if c0 < 0xF8 { // 4-byte UTF-8 + return t.lookupValue(uint32(i), s[3]) + } + return 0 +} + +// bidiTrie. Total size: 15744 bytes (15.38 KiB). Checksum: b4c3b70954803b86. +type bidiTrie struct{} + +func newBidiTrie(i int) *bidiTrie { + return &bidiTrie{} +} + +// lookupValue determines the type of block n and looks up the value for b. +func (t *bidiTrie) lookupValue(n uint32, b byte) uint8 { + switch { + default: + return uint8(bidiValues[n<<6+uint32(b)]) + } +} + +// bidiValues: 222 blocks, 14208 entries, 14208 bytes +// The third block is the zero block. +var bidiValues = [14208]uint8{ + // Block 0x0, offset 0x0 + 0x00: 0x000b, 0x01: 0x000b, 0x02: 0x000b, 0x03: 0x000b, 0x04: 0x000b, 0x05: 0x000b, + 0x06: 0x000b, 0x07: 0x000b, 0x08: 0x000b, 0x09: 0x0008, 0x0a: 0x0007, 0x0b: 0x0008, + 0x0c: 0x0009, 0x0d: 0x0007, 0x0e: 0x000b, 0x0f: 0x000b, 0x10: 0x000b, 0x11: 0x000b, + 0x12: 0x000b, 0x13: 0x000b, 0x14: 0x000b, 0x15: 0x000b, 0x16: 0x000b, 0x17: 0x000b, + 0x18: 0x000b, 0x19: 0x000b, 0x1a: 0x000b, 0x1b: 0x000b, 0x1c: 0x0007, 0x1d: 0x0007, + 0x1e: 0x0007, 0x1f: 0x0008, 0x20: 0x0009, 0x21: 0x000a, 0x22: 0x000a, 0x23: 0x0004, + 0x24: 0x0004, 0x25: 0x0004, 0x26: 0x000a, 0x27: 0x000a, 0x28: 0x003a, 0x29: 0x002a, + 0x2a: 0x000a, 0x2b: 0x0003, 0x2c: 0x0006, 0x2d: 0x0003, 0x2e: 0x0006, 0x2f: 0x0006, + 0x30: 0x0002, 0x31: 0x0002, 0x32: 0x0002, 0x33: 0x0002, 0x34: 0x0002, 0x35: 0x0002, + 0x36: 0x0002, 0x37: 0x0002, 0x38: 0x0002, 0x39: 0x0002, 0x3a: 0x0006, 0x3b: 0x000a, + 0x3c: 0x000a, 0x3d: 0x000a, 0x3e: 0x000a, 0x3f: 0x000a, + // Block 0x1, offset 0x40 + 0x40: 0x000a, + 0x5b: 0x005a, 0x5c: 0x000a, 0x5d: 0x004a, + 0x5e: 0x000a, 0x5f: 0x000a, 0x60: 0x000a, + 0x7b: 0x005a, + 0x7c: 0x000a, 0x7d: 0x004a, 0x7e: 0x000a, 0x7f: 0x000b, + // Block 0x2, offset 0x80 + // Block 0x3, offset 0xc0 + 0xc0: 0x000b, 0xc1: 0x000b, 0xc2: 0x000b, 0xc3: 0x000b, 0xc4: 0x000b, 0xc5: 0x0007, + 0xc6: 0x000b, 0xc7: 0x000b, 0xc8: 0x000b, 0xc9: 0x000b, 0xca: 0x000b, 0xcb: 0x000b, + 0xcc: 0x000b, 0xcd: 0x000b, 0xce: 0x000b, 0xcf: 0x000b, 0xd0: 0x000b, 0xd1: 0x000b, + 0xd2: 0x000b, 0xd3: 0x000b, 0xd4: 0x000b, 0xd5: 0x000b, 0xd6: 0x000b, 0xd7: 0x000b, + 0xd8: 0x000b, 0xd9: 0x000b, 0xda: 0x000b, 0xdb: 0x000b, 0xdc: 0x000b, 0xdd: 0x000b, + 0xde: 0x000b, 0xdf: 0x000b, 0xe0: 0x0006, 0xe1: 0x000a, 0xe2: 0x0004, 0xe3: 0x0004, + 0xe4: 0x0004, 0xe5: 0x0004, 0xe6: 0x000a, 0xe7: 0x000a, 0xe8: 0x000a, 0xe9: 0x000a, + 0xeb: 0x000a, 0xec: 0x000a, 0xed: 0x000b, 0xee: 0x000a, 0xef: 0x000a, + 0xf0: 0x0004, 0xf1: 0x0004, 0xf2: 0x0002, 0xf3: 0x0002, 0xf4: 0x000a, + 0xf6: 0x000a, 0xf7: 0x000a, 0xf8: 0x000a, 0xf9: 0x0002, 0xfb: 0x000a, + 0xfc: 0x000a, 0xfd: 0x000a, 0xfe: 0x000a, 0xff: 0x000a, + // Block 0x4, offset 0x100 + 0x117: 0x000a, + 0x137: 0x000a, + // Block 0x5, offset 0x140 + 0x179: 0x000a, 0x17a: 0x000a, + // Block 0x6, offset 0x180 + 0x182: 0x000a, 0x183: 0x000a, 0x184: 0x000a, 0x185: 0x000a, + 0x186: 0x000a, 0x187: 0x000a, 0x188: 0x000a, 0x189: 0x000a, 0x18a: 0x000a, 0x18b: 0x000a, + 0x18c: 0x000a, 0x18d: 0x000a, 0x18e: 0x000a, 0x18f: 0x000a, + 0x192: 0x000a, 0x193: 0x000a, 0x194: 0x000a, 0x195: 0x000a, 0x196: 0x000a, 0x197: 0x000a, + 0x198: 0x000a, 0x199: 0x000a, 0x19a: 0x000a, 0x19b: 0x000a, 0x19c: 0x000a, 0x19d: 0x000a, + 0x19e: 0x000a, 0x19f: 0x000a, + 0x1a5: 0x000a, 0x1a6: 0x000a, 0x1a7: 0x000a, 0x1a8: 0x000a, 0x1a9: 0x000a, + 0x1aa: 0x000a, 0x1ab: 0x000a, 0x1ac: 0x000a, 0x1ad: 0x000a, 0x1af: 0x000a, + 0x1b0: 0x000a, 0x1b1: 0x000a, 0x1b2: 0x000a, 0x1b3: 0x000a, 0x1b4: 0x000a, 0x1b5: 0x000a, + 0x1b6: 0x000a, 0x1b7: 0x000a, 0x1b8: 0x000a, 0x1b9: 0x000a, 0x1ba: 0x000a, 0x1bb: 0x000a, + 0x1bc: 0x000a, 0x1bd: 0x000a, 0x1be: 0x000a, 0x1bf: 0x000a, + // Block 0x7, offset 0x1c0 + 0x1c0: 0x000c, 0x1c1: 0x000c, 0x1c2: 0x000c, 0x1c3: 0x000c, 0x1c4: 0x000c, 0x1c5: 0x000c, + 0x1c6: 0x000c, 0x1c7: 0x000c, 0x1c8: 0x000c, 0x1c9: 0x000c, 0x1ca: 0x000c, 0x1cb: 0x000c, + 0x1cc: 0x000c, 0x1cd: 0x000c, 0x1ce: 0x000c, 0x1cf: 0x000c, 0x1d0: 0x000c, 0x1d1: 0x000c, + 0x1d2: 0x000c, 0x1d3: 0x000c, 0x1d4: 0x000c, 0x1d5: 0x000c, 0x1d6: 0x000c, 0x1d7: 0x000c, + 0x1d8: 0x000c, 0x1d9: 0x000c, 0x1da: 0x000c, 0x1db: 0x000c, 0x1dc: 0x000c, 0x1dd: 0x000c, + 0x1de: 0x000c, 0x1df: 0x000c, 0x1e0: 0x000c, 0x1e1: 0x000c, 0x1e2: 0x000c, 0x1e3: 0x000c, + 0x1e4: 0x000c, 0x1e5: 0x000c, 0x1e6: 0x000c, 0x1e7: 0x000c, 0x1e8: 0x000c, 0x1e9: 0x000c, + 0x1ea: 0x000c, 0x1eb: 0x000c, 0x1ec: 0x000c, 0x1ed: 0x000c, 0x1ee: 0x000c, 0x1ef: 0x000c, + 0x1f0: 0x000c, 0x1f1: 0x000c, 0x1f2: 0x000c, 0x1f3: 0x000c, 0x1f4: 0x000c, 0x1f5: 0x000c, + 0x1f6: 0x000c, 0x1f7: 0x000c, 0x1f8: 0x000c, 0x1f9: 0x000c, 0x1fa: 0x000c, 0x1fb: 0x000c, + 0x1fc: 0x000c, 0x1fd: 0x000c, 0x1fe: 0x000c, 0x1ff: 0x000c, + // Block 0x8, offset 0x200 + 0x200: 0x000c, 0x201: 0x000c, 0x202: 0x000c, 0x203: 0x000c, 0x204: 0x000c, 0x205: 0x000c, + 0x206: 0x000c, 0x207: 0x000c, 0x208: 0x000c, 0x209: 0x000c, 0x20a: 0x000c, 0x20b: 0x000c, + 0x20c: 0x000c, 0x20d: 0x000c, 0x20e: 0x000c, 0x20f: 0x000c, 0x210: 0x000c, 0x211: 0x000c, + 0x212: 0x000c, 0x213: 0x000c, 0x214: 0x000c, 0x215: 0x000c, 0x216: 0x000c, 0x217: 0x000c, + 0x218: 0x000c, 0x219: 0x000c, 0x21a: 0x000c, 0x21b: 0x000c, 0x21c: 0x000c, 0x21d: 0x000c, + 0x21e: 0x000c, 0x21f: 0x000c, 0x220: 0x000c, 0x221: 0x000c, 0x222: 0x000c, 0x223: 0x000c, + 0x224: 0x000c, 0x225: 0x000c, 0x226: 0x000c, 0x227: 0x000c, 0x228: 0x000c, 0x229: 0x000c, + 0x22a: 0x000c, 0x22b: 0x000c, 0x22c: 0x000c, 0x22d: 0x000c, 0x22e: 0x000c, 0x22f: 0x000c, + 0x234: 0x000a, 0x235: 0x000a, + 0x23e: 0x000a, + // Block 0x9, offset 0x240 + 0x244: 0x000a, 0x245: 0x000a, + 0x247: 0x000a, + // Block 0xa, offset 0x280 + 0x2b6: 0x000a, + // Block 0xb, offset 0x2c0 + 0x2c3: 0x000c, 0x2c4: 0x000c, 0x2c5: 0x000c, + 0x2c6: 0x000c, 0x2c7: 0x000c, 0x2c8: 0x000c, 0x2c9: 0x000c, + // Block 0xc, offset 0x300 + 0x30a: 0x000a, + 0x30d: 0x000a, 0x30e: 0x000a, 0x30f: 0x0004, 0x310: 0x0001, 0x311: 0x000c, + 0x312: 0x000c, 0x313: 0x000c, 0x314: 0x000c, 0x315: 0x000c, 0x316: 0x000c, 0x317: 0x000c, + 0x318: 0x000c, 0x319: 0x000c, 0x31a: 0x000c, 0x31b: 0x000c, 0x31c: 0x000c, 0x31d: 0x000c, + 0x31e: 0x000c, 0x31f: 0x000c, 0x320: 0x000c, 0x321: 0x000c, 0x322: 0x000c, 0x323: 0x000c, + 0x324: 0x000c, 0x325: 0x000c, 0x326: 0x000c, 0x327: 0x000c, 0x328: 0x000c, 0x329: 0x000c, + 0x32a: 0x000c, 0x32b: 0x000c, 0x32c: 0x000c, 0x32d: 0x000c, 0x32e: 0x000c, 0x32f: 0x000c, + 0x330: 0x000c, 0x331: 0x000c, 0x332: 0x000c, 0x333: 0x000c, 0x334: 0x000c, 0x335: 0x000c, + 0x336: 0x000c, 0x337: 0x000c, 0x338: 0x000c, 0x339: 0x000c, 0x33a: 0x000c, 0x33b: 0x000c, + 0x33c: 0x000c, 0x33d: 0x000c, 0x33e: 0x0001, 0x33f: 0x000c, + // Block 0xd, offset 0x340 + 0x340: 0x0001, 0x341: 0x000c, 0x342: 0x000c, 0x343: 0x0001, 0x344: 0x000c, 0x345: 0x000c, + 0x346: 0x0001, 0x347: 0x000c, 0x348: 0x0001, 0x349: 0x0001, 0x34a: 0x0001, 0x34b: 0x0001, + 0x34c: 0x0001, 0x34d: 0x0001, 0x34e: 0x0001, 0x34f: 0x0001, 0x350: 0x0001, 0x351: 0x0001, + 0x352: 0x0001, 0x353: 0x0001, 0x354: 0x0001, 0x355: 0x0001, 0x356: 0x0001, 0x357: 0x0001, + 0x358: 0x0001, 0x359: 0x0001, 0x35a: 0x0001, 0x35b: 0x0001, 0x35c: 0x0001, 0x35d: 0x0001, + 0x35e: 0x0001, 0x35f: 0x0001, 0x360: 0x0001, 0x361: 0x0001, 0x362: 0x0001, 0x363: 0x0001, + 0x364: 0x0001, 0x365: 0x0001, 0x366: 0x0001, 0x367: 0x0001, 0x368: 0x0001, 0x369: 0x0001, + 0x36a: 0x0001, 0x36b: 0x0001, 0x36c: 0x0001, 0x36d: 0x0001, 0x36e: 0x0001, 0x36f: 0x0001, + 0x370: 0x0001, 0x371: 0x0001, 0x372: 0x0001, 0x373: 0x0001, 0x374: 0x0001, 0x375: 0x0001, + 0x376: 0x0001, 0x377: 0x0001, 0x378: 0x0001, 0x379: 0x0001, 0x37a: 0x0001, 0x37b: 0x0001, + 0x37c: 0x0001, 0x37d: 0x0001, 0x37e: 0x0001, 0x37f: 0x0001, + // Block 0xe, offset 0x380 + 0x380: 0x0005, 0x381: 0x0005, 0x382: 0x0005, 0x383: 0x0005, 0x384: 0x0005, 0x385: 0x0005, + 0x386: 0x000a, 0x387: 0x000a, 0x388: 0x000d, 0x389: 0x0004, 0x38a: 0x0004, 0x38b: 0x000d, + 0x38c: 0x0006, 0x38d: 0x000d, 0x38e: 0x000a, 0x38f: 0x000a, 0x390: 0x000c, 0x391: 0x000c, + 0x392: 0x000c, 0x393: 0x000c, 0x394: 0x000c, 0x395: 0x000c, 0x396: 0x000c, 0x397: 0x000c, + 0x398: 0x000c, 0x399: 0x000c, 0x39a: 0x000c, 0x39b: 0x000d, 0x39c: 0x000d, 0x39d: 0x000d, + 0x39e: 0x000d, 0x39f: 0x000d, 0x3a0: 0x000d, 0x3a1: 0x000d, 0x3a2: 0x000d, 0x3a3: 0x000d, + 0x3a4: 0x000d, 0x3a5: 0x000d, 0x3a6: 0x000d, 0x3a7: 0x000d, 0x3a8: 0x000d, 0x3a9: 0x000d, + 0x3aa: 0x000d, 0x3ab: 0x000d, 0x3ac: 0x000d, 0x3ad: 0x000d, 0x3ae: 0x000d, 0x3af: 0x000d, + 0x3b0: 0x000d, 0x3b1: 0x000d, 0x3b2: 0x000d, 0x3b3: 0x000d, 0x3b4: 0x000d, 0x3b5: 0x000d, + 0x3b6: 0x000d, 0x3b7: 0x000d, 0x3b8: 0x000d, 0x3b9: 0x000d, 0x3ba: 0x000d, 0x3bb: 0x000d, + 0x3bc: 0x000d, 0x3bd: 0x000d, 0x3be: 0x000d, 0x3bf: 0x000d, + // Block 0xf, offset 0x3c0 + 0x3c0: 0x000d, 0x3c1: 0x000d, 0x3c2: 0x000d, 0x3c3: 0x000d, 0x3c4: 0x000d, 0x3c5: 0x000d, + 0x3c6: 0x000d, 0x3c7: 0x000d, 0x3c8: 0x000d, 0x3c9: 0x000d, 0x3ca: 0x000d, 0x3cb: 0x000c, + 0x3cc: 0x000c, 0x3cd: 0x000c, 0x3ce: 0x000c, 0x3cf: 0x000c, 0x3d0: 0x000c, 0x3d1: 0x000c, + 0x3d2: 0x000c, 0x3d3: 0x000c, 0x3d4: 0x000c, 0x3d5: 0x000c, 0x3d6: 0x000c, 0x3d7: 0x000c, + 0x3d8: 0x000c, 0x3d9: 0x000c, 0x3da: 0x000c, 0x3db: 0x000c, 0x3dc: 0x000c, 0x3dd: 0x000c, + 0x3de: 0x000c, 0x3df: 0x000c, 0x3e0: 0x0005, 0x3e1: 0x0005, 0x3e2: 0x0005, 0x3e3: 0x0005, + 0x3e4: 0x0005, 0x3e5: 0x0005, 0x3e6: 0x0005, 0x3e7: 0x0005, 0x3e8: 0x0005, 0x3e9: 0x0005, + 0x3ea: 0x0004, 0x3eb: 0x0005, 0x3ec: 0x0005, 0x3ed: 0x000d, 0x3ee: 0x000d, 0x3ef: 0x000d, + 0x3f0: 0x000c, 0x3f1: 0x000d, 0x3f2: 0x000d, 0x3f3: 0x000d, 0x3f4: 0x000d, 0x3f5: 0x000d, + 0x3f6: 0x000d, 0x3f7: 0x000d, 0x3f8: 0x000d, 0x3f9: 0x000d, 0x3fa: 0x000d, 0x3fb: 0x000d, + 0x3fc: 0x000d, 0x3fd: 0x000d, 0x3fe: 0x000d, 0x3ff: 0x000d, + // Block 0x10, offset 0x400 + 0x400: 0x000d, 0x401: 0x000d, 0x402: 0x000d, 0x403: 0x000d, 0x404: 0x000d, 0x405: 0x000d, + 0x406: 0x000d, 0x407: 0x000d, 0x408: 0x000d, 0x409: 0x000d, 0x40a: 0x000d, 0x40b: 0x000d, + 0x40c: 0x000d, 0x40d: 0x000d, 0x40e: 0x000d, 0x40f: 0x000d, 0x410: 0x000d, 0x411: 0x000d, + 0x412: 0x000d, 0x413: 0x000d, 0x414: 0x000d, 0x415: 0x000d, 0x416: 0x000d, 0x417: 0x000d, + 0x418: 0x000d, 0x419: 0x000d, 0x41a: 0x000d, 0x41b: 0x000d, 0x41c: 0x000d, 0x41d: 0x000d, + 0x41e: 0x000d, 0x41f: 0x000d, 0x420: 0x000d, 0x421: 0x000d, 0x422: 0x000d, 0x423: 0x000d, + 0x424: 0x000d, 0x425: 0x000d, 0x426: 0x000d, 0x427: 0x000d, 0x428: 0x000d, 0x429: 0x000d, + 0x42a: 0x000d, 0x42b: 0x000d, 0x42c: 0x000d, 0x42d: 0x000d, 0x42e: 0x000d, 0x42f: 0x000d, + 0x430: 0x000d, 0x431: 0x000d, 0x432: 0x000d, 0x433: 0x000d, 0x434: 0x000d, 0x435: 0x000d, + 0x436: 0x000d, 0x437: 0x000d, 0x438: 0x000d, 0x439: 0x000d, 0x43a: 0x000d, 0x43b: 0x000d, + 0x43c: 0x000d, 0x43d: 0x000d, 0x43e: 0x000d, 0x43f: 0x000d, + // Block 0x11, offset 0x440 + 0x440: 0x000d, 0x441: 0x000d, 0x442: 0x000d, 0x443: 0x000d, 0x444: 0x000d, 0x445: 0x000d, + 0x446: 0x000d, 0x447: 0x000d, 0x448: 0x000d, 0x449: 0x000d, 0x44a: 0x000d, 0x44b: 0x000d, + 0x44c: 0x000d, 0x44d: 0x000d, 0x44e: 0x000d, 0x44f: 0x000d, 0x450: 0x000d, 0x451: 0x000d, + 0x452: 0x000d, 0x453: 0x000d, 0x454: 0x000d, 0x455: 0x000d, 0x456: 0x000c, 0x457: 0x000c, + 0x458: 0x000c, 0x459: 0x000c, 0x45a: 0x000c, 0x45b: 0x000c, 0x45c: 0x000c, 0x45d: 0x0005, + 0x45e: 0x000a, 0x45f: 0x000c, 0x460: 0x000c, 0x461: 0x000c, 0x462: 0x000c, 0x463: 0x000c, + 0x464: 0x000c, 0x465: 0x000d, 0x466: 0x000d, 0x467: 0x000c, 0x468: 0x000c, 0x469: 0x000a, + 0x46a: 0x000c, 0x46b: 0x000c, 0x46c: 0x000c, 0x46d: 0x000c, 0x46e: 0x000d, 0x46f: 0x000d, + 0x470: 0x0002, 0x471: 0x0002, 0x472: 0x0002, 0x473: 0x0002, 0x474: 0x0002, 0x475: 0x0002, + 0x476: 0x0002, 0x477: 0x0002, 0x478: 0x0002, 0x479: 0x0002, 0x47a: 0x000d, 0x47b: 0x000d, + 0x47c: 0x000d, 0x47d: 0x000d, 0x47e: 0x000d, 0x47f: 0x000d, + // Block 0x12, offset 0x480 + 0x480: 0x000d, 0x481: 0x000d, 0x482: 0x000d, 0x483: 0x000d, 0x484: 0x000d, 0x485: 0x000d, + 0x486: 0x000d, 0x487: 0x000d, 0x488: 0x000d, 0x489: 0x000d, 0x48a: 0x000d, 0x48b: 0x000d, + 0x48c: 0x000d, 0x48d: 0x000d, 0x48e: 0x000d, 0x48f: 0x000d, 0x490: 0x000d, 0x491: 0x000c, + 0x492: 0x000d, 0x493: 0x000d, 0x494: 0x000d, 0x495: 0x000d, 0x496: 0x000d, 0x497: 0x000d, + 0x498: 0x000d, 0x499: 0x000d, 0x49a: 0x000d, 0x49b: 0x000d, 0x49c: 0x000d, 0x49d: 0x000d, + 0x49e: 0x000d, 0x49f: 0x000d, 0x4a0: 0x000d, 0x4a1: 0x000d, 0x4a2: 0x000d, 0x4a3: 0x000d, + 0x4a4: 0x000d, 0x4a5: 0x000d, 0x4a6: 0x000d, 0x4a7: 0x000d, 0x4a8: 0x000d, 0x4a9: 0x000d, + 0x4aa: 0x000d, 0x4ab: 0x000d, 0x4ac: 0x000d, 0x4ad: 0x000d, 0x4ae: 0x000d, 0x4af: 0x000d, + 0x4b0: 0x000c, 0x4b1: 0x000c, 0x4b2: 0x000c, 0x4b3: 0x000c, 0x4b4: 0x000c, 0x4b5: 0x000c, + 0x4b6: 0x000c, 0x4b7: 0x000c, 0x4b8: 0x000c, 0x4b9: 0x000c, 0x4ba: 0x000c, 0x4bb: 0x000c, + 0x4bc: 0x000c, 0x4bd: 0x000c, 0x4be: 0x000c, 0x4bf: 0x000c, + // Block 0x13, offset 0x4c0 + 0x4c0: 0x000c, 0x4c1: 0x000c, 0x4c2: 0x000c, 0x4c3: 0x000c, 0x4c4: 0x000c, 0x4c5: 0x000c, + 0x4c6: 0x000c, 0x4c7: 0x000c, 0x4c8: 0x000c, 0x4c9: 0x000c, 0x4ca: 0x000c, 0x4cb: 0x000d, + 0x4cc: 0x000d, 0x4cd: 0x000d, 0x4ce: 0x000d, 0x4cf: 0x000d, 0x4d0: 0x000d, 0x4d1: 0x000d, + 0x4d2: 0x000d, 0x4d3: 0x000d, 0x4d4: 0x000d, 0x4d5: 0x000d, 0x4d6: 0x000d, 0x4d7: 0x000d, + 0x4d8: 0x000d, 0x4d9: 0x000d, 0x4da: 0x000d, 0x4db: 0x000d, 0x4dc: 0x000d, 0x4dd: 0x000d, + 0x4de: 0x000d, 0x4df: 0x000d, 0x4e0: 0x000d, 0x4e1: 0x000d, 0x4e2: 0x000d, 0x4e3: 0x000d, + 0x4e4: 0x000d, 0x4e5: 0x000d, 0x4e6: 0x000d, 0x4e7: 0x000d, 0x4e8: 0x000d, 0x4e9: 0x000d, + 0x4ea: 0x000d, 0x4eb: 0x000d, 0x4ec: 0x000d, 0x4ed: 0x000d, 0x4ee: 0x000d, 0x4ef: 0x000d, + 0x4f0: 0x000d, 0x4f1: 0x000d, 0x4f2: 0x000d, 0x4f3: 0x000d, 0x4f4: 0x000d, 0x4f5: 0x000d, + 0x4f6: 0x000d, 0x4f7: 0x000d, 0x4f8: 0x000d, 0x4f9: 0x000d, 0x4fa: 0x000d, 0x4fb: 0x000d, + 0x4fc: 0x000d, 0x4fd: 0x000d, 0x4fe: 0x000d, 0x4ff: 0x000d, + // Block 0x14, offset 0x500 + 0x500: 0x000d, 0x501: 0x000d, 0x502: 0x000d, 0x503: 0x000d, 0x504: 0x000d, 0x505: 0x000d, + 0x506: 0x000d, 0x507: 0x000d, 0x508: 0x000d, 0x509: 0x000d, 0x50a: 0x000d, 0x50b: 0x000d, + 0x50c: 0x000d, 0x50d: 0x000d, 0x50e: 0x000d, 0x50f: 0x000d, 0x510: 0x000d, 0x511: 0x000d, + 0x512: 0x000d, 0x513: 0x000d, 0x514: 0x000d, 0x515: 0x000d, 0x516: 0x000d, 0x517: 0x000d, + 0x518: 0x000d, 0x519: 0x000d, 0x51a: 0x000d, 0x51b: 0x000d, 0x51c: 0x000d, 0x51d: 0x000d, + 0x51e: 0x000d, 0x51f: 0x000d, 0x520: 0x000d, 0x521: 0x000d, 0x522: 0x000d, 0x523: 0x000d, + 0x524: 0x000d, 0x525: 0x000d, 0x526: 0x000c, 0x527: 0x000c, 0x528: 0x000c, 0x529: 0x000c, + 0x52a: 0x000c, 0x52b: 0x000c, 0x52c: 0x000c, 0x52d: 0x000c, 0x52e: 0x000c, 0x52f: 0x000c, + 0x530: 0x000c, 0x531: 0x000d, 0x532: 0x000d, 0x533: 0x000d, 0x534: 0x000d, 0x535: 0x000d, + 0x536: 0x000d, 0x537: 0x000d, 0x538: 0x000d, 0x539: 0x000d, 0x53a: 0x000d, 0x53b: 0x000d, + 0x53c: 0x000d, 0x53d: 0x000d, 0x53e: 0x000d, 0x53f: 0x000d, + // Block 0x15, offset 0x540 + 0x540: 0x0001, 0x541: 0x0001, 0x542: 0x0001, 0x543: 0x0001, 0x544: 0x0001, 0x545: 0x0001, + 0x546: 0x0001, 0x547: 0x0001, 0x548: 0x0001, 0x549: 0x0001, 0x54a: 0x0001, 0x54b: 0x0001, + 0x54c: 0x0001, 0x54d: 0x0001, 0x54e: 0x0001, 0x54f: 0x0001, 0x550: 0x0001, 0x551: 0x0001, + 0x552: 0x0001, 0x553: 0x0001, 0x554: 0x0001, 0x555: 0x0001, 0x556: 0x0001, 0x557: 0x0001, + 0x558: 0x0001, 0x559: 0x0001, 0x55a: 0x0001, 0x55b: 0x0001, 0x55c: 0x0001, 0x55d: 0x0001, + 0x55e: 0x0001, 0x55f: 0x0001, 0x560: 0x0001, 0x561: 0x0001, 0x562: 0x0001, 0x563: 0x0001, + 0x564: 0x0001, 0x565: 0x0001, 0x566: 0x0001, 0x567: 0x0001, 0x568: 0x0001, 0x569: 0x0001, + 0x56a: 0x0001, 0x56b: 0x000c, 0x56c: 0x000c, 0x56d: 0x000c, 0x56e: 0x000c, 0x56f: 0x000c, + 0x570: 0x000c, 0x571: 0x000c, 0x572: 0x000c, 0x573: 0x000c, 0x574: 0x0001, 0x575: 0x0001, + 0x576: 0x000a, 0x577: 0x000a, 0x578: 0x000a, 0x579: 0x000a, 0x57a: 0x0001, 0x57b: 0x0001, + 0x57c: 0x0001, 0x57d: 0x0001, 0x57e: 0x0001, 0x57f: 0x0001, + // Block 0x16, offset 0x580 + 0x580: 0x0001, 0x581: 0x0001, 0x582: 0x0001, 0x583: 0x0001, 0x584: 0x0001, 0x585: 0x0001, + 0x586: 0x0001, 0x587: 0x0001, 0x588: 0x0001, 0x589: 0x0001, 0x58a: 0x0001, 0x58b: 0x0001, + 0x58c: 0x0001, 0x58d: 0x0001, 0x58e: 0x0001, 0x58f: 0x0001, 0x590: 0x0001, 0x591: 0x0001, + 0x592: 0x0001, 0x593: 0x0001, 0x594: 0x0001, 0x595: 0x0001, 0x596: 0x000c, 0x597: 0x000c, + 0x598: 0x000c, 0x599: 0x000c, 0x59a: 0x0001, 0x59b: 0x000c, 0x59c: 0x000c, 0x59d: 0x000c, + 0x59e: 0x000c, 0x59f: 0x000c, 0x5a0: 0x000c, 0x5a1: 0x000c, 0x5a2: 0x000c, 0x5a3: 0x000c, + 0x5a4: 0x0001, 0x5a5: 0x000c, 0x5a6: 0x000c, 0x5a7: 0x000c, 0x5a8: 0x0001, 0x5a9: 0x000c, + 0x5aa: 0x000c, 0x5ab: 0x000c, 0x5ac: 0x000c, 0x5ad: 0x000c, 0x5ae: 0x0001, 0x5af: 0x0001, + 0x5b0: 0x0001, 0x5b1: 0x0001, 0x5b2: 0x0001, 0x5b3: 0x0001, 0x5b4: 0x0001, 0x5b5: 0x0001, + 0x5b6: 0x0001, 0x5b7: 0x0001, 0x5b8: 0x0001, 0x5b9: 0x0001, 0x5ba: 0x0001, 0x5bb: 0x0001, + 0x5bc: 0x0001, 0x5bd: 0x0001, 0x5be: 0x0001, 0x5bf: 0x0001, + // Block 0x17, offset 0x5c0 + 0x5c0: 0x0001, 0x5c1: 0x0001, 0x5c2: 0x0001, 0x5c3: 0x0001, 0x5c4: 0x0001, 0x5c5: 0x0001, + 0x5c6: 0x0001, 0x5c7: 0x0001, 0x5c8: 0x0001, 0x5c9: 0x0001, 0x5ca: 0x0001, 0x5cb: 0x0001, + 0x5cc: 0x0001, 0x5cd: 0x0001, 0x5ce: 0x0001, 0x5cf: 0x0001, 0x5d0: 0x0001, 0x5d1: 0x0001, + 0x5d2: 0x0001, 0x5d3: 0x0001, 0x5d4: 0x0001, 0x5d5: 0x0001, 0x5d6: 0x0001, 0x5d7: 0x0001, + 0x5d8: 0x0001, 0x5d9: 0x000c, 0x5da: 0x000c, 0x5db: 0x000c, 0x5dc: 0x0001, 0x5dd: 0x0001, + 0x5de: 0x0001, 0x5df: 0x0001, 0x5e0: 0x0001, 0x5e1: 0x0001, 0x5e2: 0x0001, 0x5e3: 0x0001, + 0x5e4: 0x0001, 0x5e5: 0x0001, 0x5e6: 0x0001, 0x5e7: 0x0001, 0x5e8: 0x0001, 0x5e9: 0x0001, + 0x5ea: 0x0001, 0x5eb: 0x0001, 0x5ec: 0x0001, 0x5ed: 0x0001, 0x5ee: 0x0001, 0x5ef: 0x0001, + 0x5f0: 0x0001, 0x5f1: 0x0001, 0x5f2: 0x0001, 0x5f3: 0x0001, 0x5f4: 0x0001, 0x5f5: 0x0001, + 0x5f6: 0x0001, 0x5f7: 0x0001, 0x5f8: 0x0001, 0x5f9: 0x0001, 0x5fa: 0x0001, 0x5fb: 0x0001, + 0x5fc: 0x0001, 0x5fd: 0x0001, 0x5fe: 0x0001, 0x5ff: 0x0001, + // Block 0x18, offset 0x600 + 0x600: 0x0001, 0x601: 0x0001, 0x602: 0x0001, 0x603: 0x0001, 0x604: 0x0001, 0x605: 0x0001, + 0x606: 0x0001, 0x607: 0x0001, 0x608: 0x0001, 0x609: 0x0001, 0x60a: 0x0001, 0x60b: 0x0001, + 0x60c: 0x0001, 0x60d: 0x0001, 0x60e: 0x0001, 0x60f: 0x0001, 0x610: 0x0001, 0x611: 0x0001, + 0x612: 0x0001, 0x613: 0x0001, 0x614: 0x0001, 0x615: 0x0001, 0x616: 0x0001, 0x617: 0x0001, + 0x618: 0x0001, 0x619: 0x0001, 0x61a: 0x0001, 0x61b: 0x0001, 0x61c: 0x0001, 0x61d: 0x0001, + 0x61e: 0x0001, 0x61f: 0x0001, 0x620: 0x000d, 0x621: 0x000d, 0x622: 0x000d, 0x623: 0x000d, + 0x624: 0x000d, 0x625: 0x000d, 0x626: 0x000d, 0x627: 0x000d, 0x628: 0x000d, 0x629: 0x000d, + 0x62a: 0x000d, 0x62b: 0x000d, 0x62c: 0x000d, 0x62d: 0x000d, 0x62e: 0x000d, 0x62f: 0x000d, + 0x630: 0x000d, 0x631: 0x000d, 0x632: 0x000d, 0x633: 0x000d, 0x634: 0x000d, 0x635: 0x000d, + 0x636: 0x000d, 0x637: 0x000d, 0x638: 0x000d, 0x639: 0x000d, 0x63a: 0x000d, 0x63b: 0x000d, + 0x63c: 0x000d, 0x63d: 0x000d, 0x63e: 0x000d, 0x63f: 0x000d, + // Block 0x19, offset 0x640 + 0x640: 0x000d, 0x641: 0x000d, 0x642: 0x000d, 0x643: 0x000d, 0x644: 0x000d, 0x645: 0x000d, + 0x646: 0x000d, 0x647: 0x000d, 0x648: 0x000d, 0x649: 0x000d, 0x64a: 0x000d, 0x64b: 0x000d, + 0x64c: 0x000d, 0x64d: 0x000d, 0x64e: 0x000d, 0x64f: 0x000d, 0x650: 0x000d, 0x651: 0x000d, + 0x652: 0x000d, 0x653: 0x000d, 0x654: 0x000c, 0x655: 0x000c, 0x656: 0x000c, 0x657: 0x000c, + 0x658: 0x000c, 0x659: 0x000c, 0x65a: 0x000c, 0x65b: 0x000c, 0x65c: 0x000c, 0x65d: 0x000c, + 0x65e: 0x000c, 0x65f: 0x000c, 0x660: 0x000c, 0x661: 0x000c, 0x662: 0x0005, 0x663: 0x000c, + 0x664: 0x000c, 0x665: 0x000c, 0x666: 0x000c, 0x667: 0x000c, 0x668: 0x000c, 0x669: 0x000c, + 0x66a: 0x000c, 0x66b: 0x000c, 0x66c: 0x000c, 0x66d: 0x000c, 0x66e: 0x000c, 0x66f: 0x000c, + 0x670: 0x000c, 0x671: 0x000c, 0x672: 0x000c, 0x673: 0x000c, 0x674: 0x000c, 0x675: 0x000c, + 0x676: 0x000c, 0x677: 0x000c, 0x678: 0x000c, 0x679: 0x000c, 0x67a: 0x000c, 0x67b: 0x000c, + 0x67c: 0x000c, 0x67d: 0x000c, 0x67e: 0x000c, 0x67f: 0x000c, + // Block 0x1a, offset 0x680 + 0x680: 0x000c, 0x681: 0x000c, 0x682: 0x000c, + 0x6ba: 0x000c, + 0x6bc: 0x000c, + // Block 0x1b, offset 0x6c0 + 0x6c1: 0x000c, 0x6c2: 0x000c, 0x6c3: 0x000c, 0x6c4: 0x000c, 0x6c5: 0x000c, + 0x6c6: 0x000c, 0x6c7: 0x000c, 0x6c8: 0x000c, + 0x6cd: 0x000c, 0x6d1: 0x000c, + 0x6d2: 0x000c, 0x6d3: 0x000c, 0x6d4: 0x000c, 0x6d5: 0x000c, 0x6d6: 0x000c, 0x6d7: 0x000c, + 0x6e2: 0x000c, 0x6e3: 0x000c, + // Block 0x1c, offset 0x700 + 0x701: 0x000c, + 0x73c: 0x000c, + // Block 0x1d, offset 0x740 + 0x741: 0x000c, 0x742: 0x000c, 0x743: 0x000c, 0x744: 0x000c, + 0x74d: 0x000c, + 0x762: 0x000c, 0x763: 0x000c, + 0x772: 0x0004, 0x773: 0x0004, + 0x77b: 0x0004, + // Block 0x1e, offset 0x780 + 0x781: 0x000c, 0x782: 0x000c, + 0x7bc: 0x000c, + // Block 0x1f, offset 0x7c0 + 0x7c1: 0x000c, 0x7c2: 0x000c, + 0x7c7: 0x000c, 0x7c8: 0x000c, 0x7cb: 0x000c, + 0x7cc: 0x000c, 0x7cd: 0x000c, 0x7d1: 0x000c, + 0x7f0: 0x000c, 0x7f1: 0x000c, 0x7f5: 0x000c, + // Block 0x20, offset 0x800 + 0x801: 0x000c, 0x802: 0x000c, 0x803: 0x000c, 0x804: 0x000c, 0x805: 0x000c, + 0x807: 0x000c, 0x808: 0x000c, + 0x80d: 0x000c, + 0x822: 0x000c, 0x823: 0x000c, + 0x831: 0x0004, + // Block 0x21, offset 0x840 + 0x841: 0x000c, + 0x87c: 0x000c, 0x87f: 0x000c, + // Block 0x22, offset 0x880 + 0x881: 0x000c, 0x882: 0x000c, 0x883: 0x000c, 0x884: 0x000c, + 0x88d: 0x000c, + 0x896: 0x000c, + 0x8a2: 0x000c, 0x8a3: 0x000c, + // Block 0x23, offset 0x8c0 + 0x8c2: 0x000c, + // Block 0x24, offset 0x900 + 0x900: 0x000c, + 0x90d: 0x000c, + 0x933: 0x000a, 0x934: 0x000a, 0x935: 0x000a, + 0x936: 0x000a, 0x937: 0x000a, 0x938: 0x000a, 0x939: 0x0004, 0x93a: 0x000a, + // Block 0x25, offset 0x940 + 0x940: 0x000c, + 0x97e: 0x000c, 0x97f: 0x000c, + // Block 0x26, offset 0x980 + 0x980: 0x000c, + 0x986: 0x000c, 0x987: 0x000c, 0x988: 0x000c, 0x98a: 0x000c, 0x98b: 0x000c, + 0x98c: 0x000c, 0x98d: 0x000c, + 0x995: 0x000c, 0x996: 0x000c, + 0x9a2: 0x000c, 0x9a3: 0x000c, + 0x9b8: 0x000a, 0x9b9: 0x000a, 0x9ba: 0x000a, 0x9bb: 0x000a, + 0x9bc: 0x000a, 0x9bd: 0x000a, 0x9be: 0x000a, + // Block 0x27, offset 0x9c0 + 0x9cc: 0x000c, 0x9cd: 0x000c, + 0x9e2: 0x000c, 0x9e3: 0x000c, + // Block 0x28, offset 0xa00 + 0xa01: 0x000c, + // Block 0x29, offset 0xa40 + 0xa41: 0x000c, 0xa42: 0x000c, 0xa43: 0x000c, 0xa44: 0x000c, + 0xa4d: 0x000c, + 0xa62: 0x000c, 0xa63: 0x000c, + // Block 0x2a, offset 0xa80 + 0xa8a: 0x000c, + 0xa92: 0x000c, 0xa93: 0x000c, 0xa94: 0x000c, 0xa96: 0x000c, + // Block 0x2b, offset 0xac0 + 0xaf1: 0x000c, 0xaf4: 0x000c, 0xaf5: 0x000c, + 0xaf6: 0x000c, 0xaf7: 0x000c, 0xaf8: 0x000c, 0xaf9: 0x000c, 0xafa: 0x000c, + 0xaff: 0x0004, + // Block 0x2c, offset 0xb00 + 0xb07: 0x000c, 0xb08: 0x000c, 0xb09: 0x000c, 0xb0a: 0x000c, 0xb0b: 0x000c, + 0xb0c: 0x000c, 0xb0d: 0x000c, 0xb0e: 0x000c, + // Block 0x2d, offset 0xb40 + 0xb71: 0x000c, 0xb74: 0x000c, 0xb75: 0x000c, + 0xb76: 0x000c, 0xb77: 0x000c, 0xb78: 0x000c, 0xb79: 0x000c, 0xb7b: 0x000c, + 0xb7c: 0x000c, + // Block 0x2e, offset 0xb80 + 0xb88: 0x000c, 0xb89: 0x000c, 0xb8a: 0x000c, 0xb8b: 0x000c, + 0xb8c: 0x000c, 0xb8d: 0x000c, + // Block 0x2f, offset 0xbc0 + 0xbd8: 0x000c, 0xbd9: 0x000c, + 0xbf5: 0x000c, + 0xbf7: 0x000c, 0xbf9: 0x000c, 0xbfa: 0x003a, 0xbfb: 0x002a, + 0xbfc: 0x003a, 0xbfd: 0x002a, + // Block 0x30, offset 0xc00 + 0xc31: 0x000c, 0xc32: 0x000c, 0xc33: 0x000c, 0xc34: 0x000c, 0xc35: 0x000c, + 0xc36: 0x000c, 0xc37: 0x000c, 0xc38: 0x000c, 0xc39: 0x000c, 0xc3a: 0x000c, 0xc3b: 0x000c, + 0xc3c: 0x000c, 0xc3d: 0x000c, 0xc3e: 0x000c, + // Block 0x31, offset 0xc40 + 0xc40: 0x000c, 0xc41: 0x000c, 0xc42: 0x000c, 0xc43: 0x000c, 0xc44: 0x000c, + 0xc46: 0x000c, 0xc47: 0x000c, + 0xc4d: 0x000c, 0xc4e: 0x000c, 0xc4f: 0x000c, 0xc50: 0x000c, 0xc51: 0x000c, + 0xc52: 0x000c, 0xc53: 0x000c, 0xc54: 0x000c, 0xc55: 0x000c, 0xc56: 0x000c, 0xc57: 0x000c, + 0xc59: 0x000c, 0xc5a: 0x000c, 0xc5b: 0x000c, 0xc5c: 0x000c, 0xc5d: 0x000c, + 0xc5e: 0x000c, 0xc5f: 0x000c, 0xc60: 0x000c, 0xc61: 0x000c, 0xc62: 0x000c, 0xc63: 0x000c, + 0xc64: 0x000c, 0xc65: 0x000c, 0xc66: 0x000c, 0xc67: 0x000c, 0xc68: 0x000c, 0xc69: 0x000c, + 0xc6a: 0x000c, 0xc6b: 0x000c, 0xc6c: 0x000c, 0xc6d: 0x000c, 0xc6e: 0x000c, 0xc6f: 0x000c, + 0xc70: 0x000c, 0xc71: 0x000c, 0xc72: 0x000c, 0xc73: 0x000c, 0xc74: 0x000c, 0xc75: 0x000c, + 0xc76: 0x000c, 0xc77: 0x000c, 0xc78: 0x000c, 0xc79: 0x000c, 0xc7a: 0x000c, 0xc7b: 0x000c, + 0xc7c: 0x000c, + // Block 0x32, offset 0xc80 + 0xc86: 0x000c, + // Block 0x33, offset 0xcc0 + 0xced: 0x000c, 0xcee: 0x000c, 0xcef: 0x000c, + 0xcf0: 0x000c, 0xcf2: 0x000c, 0xcf3: 0x000c, 0xcf4: 0x000c, 0xcf5: 0x000c, + 0xcf6: 0x000c, 0xcf7: 0x000c, 0xcf9: 0x000c, 0xcfa: 0x000c, + 0xcfd: 0x000c, 0xcfe: 0x000c, + // Block 0x34, offset 0xd00 + 0xd18: 0x000c, 0xd19: 0x000c, + 0xd1e: 0x000c, 0xd1f: 0x000c, 0xd20: 0x000c, + 0xd31: 0x000c, 0xd32: 0x000c, 0xd33: 0x000c, 0xd34: 0x000c, + // Block 0x35, offset 0xd40 + 0xd42: 0x000c, 0xd45: 0x000c, + 0xd46: 0x000c, + 0xd4d: 0x000c, + 0xd5d: 0x000c, + // Block 0x36, offset 0xd80 + 0xd9d: 0x000c, + 0xd9e: 0x000c, 0xd9f: 0x000c, + // Block 0x37, offset 0xdc0 + 0xdd0: 0x000a, 0xdd1: 0x000a, + 0xdd2: 0x000a, 0xdd3: 0x000a, 0xdd4: 0x000a, 0xdd5: 0x000a, 0xdd6: 0x000a, 0xdd7: 0x000a, + 0xdd8: 0x000a, 0xdd9: 0x000a, + // Block 0x38, offset 0xe00 + 0xe00: 0x000a, + // Block 0x39, offset 0xe40 + 0xe40: 0x0009, + 0xe5b: 0x007a, 0xe5c: 0x006a, + // Block 0x3a, offset 0xe80 + 0xe92: 0x000c, 0xe93: 0x000c, 0xe94: 0x000c, + 0xeb2: 0x000c, 0xeb3: 0x000c, 0xeb4: 0x000c, + // Block 0x3b, offset 0xec0 + 0xed2: 0x000c, 0xed3: 0x000c, + 0xef2: 0x000c, 0xef3: 0x000c, + // Block 0x3c, offset 0xf00 + 0xf34: 0x000c, 0xf35: 0x000c, + 0xf37: 0x000c, 0xf38: 0x000c, 0xf39: 0x000c, 0xf3a: 0x000c, 0xf3b: 0x000c, + 0xf3c: 0x000c, 0xf3d: 0x000c, + // Block 0x3d, offset 0xf40 + 0xf46: 0x000c, 0xf49: 0x000c, 0xf4a: 0x000c, 0xf4b: 0x000c, + 0xf4c: 0x000c, 0xf4d: 0x000c, 0xf4e: 0x000c, 0xf4f: 0x000c, 0xf50: 0x000c, 0xf51: 0x000c, + 0xf52: 0x000c, 0xf53: 0x000c, + 0xf5b: 0x0004, 0xf5d: 0x000c, + 0xf70: 0x000a, 0xf71: 0x000a, 0xf72: 0x000a, 0xf73: 0x000a, 0xf74: 0x000a, 0xf75: 0x000a, + 0xf76: 0x000a, 0xf77: 0x000a, 0xf78: 0x000a, 0xf79: 0x000a, + // Block 0x3e, offset 0xf80 + 0xf80: 0x000a, 0xf81: 0x000a, 0xf82: 0x000a, 0xf83: 0x000a, 0xf84: 0x000a, 0xf85: 0x000a, + 0xf86: 0x000a, 0xf87: 0x000a, 0xf88: 0x000a, 0xf89: 0x000a, 0xf8a: 0x000a, 0xf8b: 0x000c, + 0xf8c: 0x000c, 0xf8d: 0x000c, 0xf8e: 0x000b, + // Block 0x3f, offset 0xfc0 + 0xfc5: 0x000c, + 0xfc6: 0x000c, + 0xfe9: 0x000c, + // Block 0x40, offset 0x1000 + 0x1020: 0x000c, 0x1021: 0x000c, 0x1022: 0x000c, + 0x1027: 0x000c, 0x1028: 0x000c, + 0x1032: 0x000c, + 0x1039: 0x000c, 0x103a: 0x000c, 0x103b: 0x000c, + // Block 0x41, offset 0x1040 + 0x1040: 0x000a, 0x1044: 0x000a, 0x1045: 0x000a, + // Block 0x42, offset 0x1080 + 0x109e: 0x000a, 0x109f: 0x000a, 0x10a0: 0x000a, 0x10a1: 0x000a, 0x10a2: 0x000a, 0x10a3: 0x000a, + 0x10a4: 0x000a, 0x10a5: 0x000a, 0x10a6: 0x000a, 0x10a7: 0x000a, 0x10a8: 0x000a, 0x10a9: 0x000a, + 0x10aa: 0x000a, 0x10ab: 0x000a, 0x10ac: 0x000a, 0x10ad: 0x000a, 0x10ae: 0x000a, 0x10af: 0x000a, + 0x10b0: 0x000a, 0x10b1: 0x000a, 0x10b2: 0x000a, 0x10b3: 0x000a, 0x10b4: 0x000a, 0x10b5: 0x000a, + 0x10b6: 0x000a, 0x10b7: 0x000a, 0x10b8: 0x000a, 0x10b9: 0x000a, 0x10ba: 0x000a, 0x10bb: 0x000a, + 0x10bc: 0x000a, 0x10bd: 0x000a, 0x10be: 0x000a, 0x10bf: 0x000a, + // Block 0x43, offset 0x10c0 + 0x10d7: 0x000c, + 0x10d8: 0x000c, 0x10db: 0x000c, + // Block 0x44, offset 0x1100 + 0x1116: 0x000c, + 0x1118: 0x000c, 0x1119: 0x000c, 0x111a: 0x000c, 0x111b: 0x000c, 0x111c: 0x000c, 0x111d: 0x000c, + 0x111e: 0x000c, 0x1120: 0x000c, 0x1122: 0x000c, + 0x1125: 0x000c, 0x1126: 0x000c, 0x1127: 0x000c, 0x1128: 0x000c, 0x1129: 0x000c, + 0x112a: 0x000c, 0x112b: 0x000c, 0x112c: 0x000c, + 0x1133: 0x000c, 0x1134: 0x000c, 0x1135: 0x000c, + 0x1136: 0x000c, 0x1137: 0x000c, 0x1138: 0x000c, 0x1139: 0x000c, 0x113a: 0x000c, 0x113b: 0x000c, + 0x113c: 0x000c, 0x113f: 0x000c, + // Block 0x45, offset 0x1140 + 0x1170: 0x000c, 0x1171: 0x000c, 0x1172: 0x000c, 0x1173: 0x000c, 0x1174: 0x000c, 0x1175: 0x000c, + 0x1176: 0x000c, 0x1177: 0x000c, 0x1178: 0x000c, 0x1179: 0x000c, 0x117a: 0x000c, 0x117b: 0x000c, + 0x117c: 0x000c, 0x117d: 0x000c, 0x117e: 0x000c, + // Block 0x46, offset 0x1180 + 0x1180: 0x000c, 0x1181: 0x000c, 0x1182: 0x000c, 0x1183: 0x000c, + 0x11b4: 0x000c, + 0x11b6: 0x000c, 0x11b7: 0x000c, 0x11b8: 0x000c, 0x11b9: 0x000c, 0x11ba: 0x000c, + 0x11bc: 0x000c, + // Block 0x47, offset 0x11c0 + 0x11c2: 0x000c, + 0x11eb: 0x000c, 0x11ec: 0x000c, 0x11ed: 0x000c, 0x11ee: 0x000c, 0x11ef: 0x000c, + 0x11f0: 0x000c, 0x11f1: 0x000c, 0x11f2: 0x000c, 0x11f3: 0x000c, + // Block 0x48, offset 0x1200 + 0x1200: 0x000c, 0x1201: 0x000c, + 0x1222: 0x000c, 0x1223: 0x000c, + 0x1224: 0x000c, 0x1225: 0x000c, 0x1228: 0x000c, 0x1229: 0x000c, + 0x122b: 0x000c, 0x122c: 0x000c, 0x122d: 0x000c, + // Block 0x49, offset 0x1240 + 0x1266: 0x000c, 0x1268: 0x000c, 0x1269: 0x000c, + 0x126d: 0x000c, 0x126f: 0x000c, + 0x1270: 0x000c, 0x1271: 0x000c, + // Block 0x4a, offset 0x1280 + 0x12ac: 0x000c, 0x12ad: 0x000c, 0x12ae: 0x000c, 0x12af: 0x000c, + 0x12b0: 0x000c, 0x12b1: 0x000c, 0x12b2: 0x000c, 0x12b3: 0x000c, + 0x12b6: 0x000c, 0x12b7: 0x000c, + // Block 0x4b, offset 0x12c0 + 0x12d0: 0x000c, 0x12d1: 0x000c, + 0x12d2: 0x000c, 0x12d4: 0x000c, 0x12d5: 0x000c, 0x12d6: 0x000c, 0x12d7: 0x000c, + 0x12d8: 0x000c, 0x12d9: 0x000c, 0x12da: 0x000c, 0x12db: 0x000c, 0x12dc: 0x000c, 0x12dd: 0x000c, + 0x12de: 0x000c, 0x12df: 0x000c, 0x12e0: 0x000c, 0x12e2: 0x000c, 0x12e3: 0x000c, + 0x12e4: 0x000c, 0x12e5: 0x000c, 0x12e6: 0x000c, 0x12e7: 0x000c, 0x12e8: 0x000c, + 0x12ed: 0x000c, + 0x12f4: 0x000c, + 0x12f8: 0x000c, 0x12f9: 0x000c, + // Block 0x4c, offset 0x1300 + 0x1300: 0x000c, 0x1301: 0x000c, 0x1302: 0x000c, 0x1303: 0x000c, 0x1304: 0x000c, 0x1305: 0x000c, + 0x1306: 0x000c, 0x1307: 0x000c, 0x1308: 0x000c, 0x1309: 0x000c, 0x130a: 0x000c, 0x130b: 0x000c, + 0x130c: 0x000c, 0x130d: 0x000c, 0x130e: 0x000c, 0x130f: 0x000c, 0x1310: 0x000c, 0x1311: 0x000c, + 0x1312: 0x000c, 0x1313: 0x000c, 0x1314: 0x000c, 0x1315: 0x000c, 0x1316: 0x000c, 0x1317: 0x000c, + 0x1318: 0x000c, 0x1319: 0x000c, 0x131a: 0x000c, 0x131b: 0x000c, 0x131c: 0x000c, 0x131d: 0x000c, + 0x131e: 0x000c, 0x131f: 0x000c, 0x1320: 0x000c, 0x1321: 0x000c, 0x1322: 0x000c, 0x1323: 0x000c, + 0x1324: 0x000c, 0x1325: 0x000c, 0x1326: 0x000c, 0x1327: 0x000c, 0x1328: 0x000c, 0x1329: 0x000c, + 0x132a: 0x000c, 0x132b: 0x000c, 0x132c: 0x000c, 0x132d: 0x000c, 0x132e: 0x000c, 0x132f: 0x000c, + 0x1330: 0x000c, 0x1331: 0x000c, 0x1332: 0x000c, 0x1333: 0x000c, 0x1334: 0x000c, 0x1335: 0x000c, + 0x133b: 0x000c, + 0x133c: 0x000c, 0x133d: 0x000c, 0x133e: 0x000c, 0x133f: 0x000c, + // Block 0x4d, offset 0x1340 + 0x137d: 0x000a, 0x137f: 0x000a, + // Block 0x4e, offset 0x1380 + 0x1380: 0x000a, 0x1381: 0x000a, + 0x138d: 0x000a, 0x138e: 0x000a, 0x138f: 0x000a, + 0x139d: 0x000a, + 0x139e: 0x000a, 0x139f: 0x000a, + 0x13ad: 0x000a, 0x13ae: 0x000a, 0x13af: 0x000a, + 0x13bd: 0x000a, 0x13be: 0x000a, + // Block 0x4f, offset 0x13c0 + 0x13c0: 0x0009, 0x13c1: 0x0009, 0x13c2: 0x0009, 0x13c3: 0x0009, 0x13c4: 0x0009, 0x13c5: 0x0009, + 0x13c6: 0x0009, 0x13c7: 0x0009, 0x13c8: 0x0009, 0x13c9: 0x0009, 0x13ca: 0x0009, 0x13cb: 0x000b, + 0x13cc: 0x000b, 0x13cd: 0x000b, 0x13cf: 0x0001, 0x13d0: 0x000a, 0x13d1: 0x000a, + 0x13d2: 0x000a, 0x13d3: 0x000a, 0x13d4: 0x000a, 0x13d5: 0x000a, 0x13d6: 0x000a, 0x13d7: 0x000a, + 0x13d8: 0x000a, 0x13d9: 0x000a, 0x13da: 0x000a, 0x13db: 0x000a, 0x13dc: 0x000a, 0x13dd: 0x000a, + 0x13de: 0x000a, 0x13df: 0x000a, 0x13e0: 0x000a, 0x13e1: 0x000a, 0x13e2: 0x000a, 0x13e3: 0x000a, + 0x13e4: 0x000a, 0x13e5: 0x000a, 0x13e6: 0x000a, 0x13e7: 0x000a, 0x13e8: 0x0009, 0x13e9: 0x0007, + 0x13ea: 0x000e, 0x13eb: 0x000e, 0x13ec: 0x000e, 0x13ed: 0x000e, 0x13ee: 0x000e, 0x13ef: 0x0006, + 0x13f0: 0x0004, 0x13f1: 0x0004, 0x13f2: 0x0004, 0x13f3: 0x0004, 0x13f4: 0x0004, 0x13f5: 0x000a, + 0x13f6: 0x000a, 0x13f7: 0x000a, 0x13f8: 0x000a, 0x13f9: 0x000a, 0x13fa: 0x000a, 0x13fb: 0x000a, + 0x13fc: 0x000a, 0x13fd: 0x000a, 0x13fe: 0x000a, 0x13ff: 0x000a, + // Block 0x50, offset 0x1400 + 0x1400: 0x000a, 0x1401: 0x000a, 0x1402: 0x000a, 0x1403: 0x000a, 0x1404: 0x0006, 0x1405: 0x009a, + 0x1406: 0x008a, 0x1407: 0x000a, 0x1408: 0x000a, 0x1409: 0x000a, 0x140a: 0x000a, 0x140b: 0x000a, + 0x140c: 0x000a, 0x140d: 0x000a, 0x140e: 0x000a, 0x140f: 0x000a, 0x1410: 0x000a, 0x1411: 0x000a, + 0x1412: 0x000a, 0x1413: 0x000a, 0x1414: 0x000a, 0x1415: 0x000a, 0x1416: 0x000a, 0x1417: 0x000a, + 0x1418: 0x000a, 0x1419: 0x000a, 0x141a: 0x000a, 0x141b: 0x000a, 0x141c: 0x000a, 0x141d: 0x000a, + 0x141e: 0x000a, 0x141f: 0x0009, 0x1420: 0x000b, 0x1421: 0x000b, 0x1422: 0x000b, 0x1423: 0x000b, + 0x1424: 0x000b, 0x1425: 0x000b, 0x1426: 0x000e, 0x1427: 0x000e, 0x1428: 0x000e, 0x1429: 0x000e, + 0x142a: 0x000b, 0x142b: 0x000b, 0x142c: 0x000b, 0x142d: 0x000b, 0x142e: 0x000b, 0x142f: 0x000b, + 0x1430: 0x0002, 0x1434: 0x0002, 0x1435: 0x0002, + 0x1436: 0x0002, 0x1437: 0x0002, 0x1438: 0x0002, 0x1439: 0x0002, 0x143a: 0x0003, 0x143b: 0x0003, + 0x143c: 0x000a, 0x143d: 0x009a, 0x143e: 0x008a, + // Block 0x51, offset 0x1440 + 0x1440: 0x0002, 0x1441: 0x0002, 0x1442: 0x0002, 0x1443: 0x0002, 0x1444: 0x0002, 0x1445: 0x0002, + 0x1446: 0x0002, 0x1447: 0x0002, 0x1448: 0x0002, 0x1449: 0x0002, 0x144a: 0x0003, 0x144b: 0x0003, + 0x144c: 0x000a, 0x144d: 0x009a, 0x144e: 0x008a, + 0x1460: 0x0004, 0x1461: 0x0004, 0x1462: 0x0004, 0x1463: 0x0004, + 0x1464: 0x0004, 0x1465: 0x0004, 0x1466: 0x0004, 0x1467: 0x0004, 0x1468: 0x0004, 0x1469: 0x0004, + 0x146a: 0x0004, 0x146b: 0x0004, 0x146c: 0x0004, 0x146d: 0x0004, 0x146e: 0x0004, 0x146f: 0x0004, + 0x1470: 0x0004, 0x1471: 0x0004, 0x1472: 0x0004, 0x1473: 0x0004, 0x1474: 0x0004, 0x1475: 0x0004, + 0x1476: 0x0004, 0x1477: 0x0004, 0x1478: 0x0004, 0x1479: 0x0004, 0x147a: 0x0004, 0x147b: 0x0004, + 0x147c: 0x0004, 0x147d: 0x0004, 0x147e: 0x0004, 0x147f: 0x0004, + // Block 0x52, offset 0x1480 + 0x1480: 0x0004, 0x1481: 0x0004, 0x1482: 0x0004, 0x1483: 0x0004, 0x1484: 0x0004, 0x1485: 0x0004, + 0x1486: 0x0004, 0x1487: 0x0004, 0x1488: 0x0004, 0x1489: 0x0004, 0x148a: 0x0004, 0x148b: 0x0004, + 0x148c: 0x0004, 0x148d: 0x0004, 0x148e: 0x0004, 0x148f: 0x0004, 0x1490: 0x000c, 0x1491: 0x000c, + 0x1492: 0x000c, 0x1493: 0x000c, 0x1494: 0x000c, 0x1495: 0x000c, 0x1496: 0x000c, 0x1497: 0x000c, + 0x1498: 0x000c, 0x1499: 0x000c, 0x149a: 0x000c, 0x149b: 0x000c, 0x149c: 0x000c, 0x149d: 0x000c, + 0x149e: 0x000c, 0x149f: 0x000c, 0x14a0: 0x000c, 0x14a1: 0x000c, 0x14a2: 0x000c, 0x14a3: 0x000c, + 0x14a4: 0x000c, 0x14a5: 0x000c, 0x14a6: 0x000c, 0x14a7: 0x000c, 0x14a8: 0x000c, 0x14a9: 0x000c, + 0x14aa: 0x000c, 0x14ab: 0x000c, 0x14ac: 0x000c, 0x14ad: 0x000c, 0x14ae: 0x000c, 0x14af: 0x000c, + 0x14b0: 0x000c, + // Block 0x53, offset 0x14c0 + 0x14c0: 0x000a, 0x14c1: 0x000a, 0x14c3: 0x000a, 0x14c4: 0x000a, 0x14c5: 0x000a, + 0x14c6: 0x000a, 0x14c8: 0x000a, 0x14c9: 0x000a, + 0x14d4: 0x000a, 0x14d6: 0x000a, 0x14d7: 0x000a, + 0x14d8: 0x000a, + 0x14de: 0x000a, 0x14df: 0x000a, 0x14e0: 0x000a, 0x14e1: 0x000a, 0x14e2: 0x000a, 0x14e3: 0x000a, + 0x14e5: 0x000a, 0x14e7: 0x000a, 0x14e9: 0x000a, + 0x14ee: 0x0004, + 0x14fa: 0x000a, 0x14fb: 0x000a, + // Block 0x54, offset 0x1500 + 0x1500: 0x000a, 0x1501: 0x000a, 0x1502: 0x000a, 0x1503: 0x000a, 0x1504: 0x000a, + 0x150a: 0x000a, 0x150b: 0x000a, + 0x150c: 0x000a, 0x150d: 0x000a, 0x1510: 0x000a, 0x1511: 0x000a, + 0x1512: 0x000a, 0x1513: 0x000a, 0x1514: 0x000a, 0x1515: 0x000a, 0x1516: 0x000a, 0x1517: 0x000a, + 0x1518: 0x000a, 0x1519: 0x000a, 0x151a: 0x000a, 0x151b: 0x000a, 0x151c: 0x000a, 0x151d: 0x000a, + 0x151e: 0x000a, 0x151f: 0x000a, + // Block 0x55, offset 0x1540 + 0x1549: 0x000a, 0x154a: 0x000a, 0x154b: 0x000a, + 0x1550: 0x000a, 0x1551: 0x000a, + 0x1552: 0x000a, 0x1553: 0x000a, 0x1554: 0x000a, 0x1555: 0x000a, 0x1556: 0x000a, 0x1557: 0x000a, + 0x1558: 0x000a, 0x1559: 0x000a, 0x155a: 0x000a, 0x155b: 0x000a, 0x155c: 0x000a, 0x155d: 0x000a, + 0x155e: 0x000a, 0x155f: 0x000a, 0x1560: 0x000a, 0x1561: 0x000a, 0x1562: 0x000a, 0x1563: 0x000a, + 0x1564: 0x000a, 0x1565: 0x000a, 0x1566: 0x000a, 0x1567: 0x000a, 0x1568: 0x000a, 0x1569: 0x000a, + 0x156a: 0x000a, 0x156b: 0x000a, 0x156c: 0x000a, 0x156d: 0x000a, 0x156e: 0x000a, 0x156f: 0x000a, + 0x1570: 0x000a, 0x1571: 0x000a, 0x1572: 0x000a, 0x1573: 0x000a, 0x1574: 0x000a, 0x1575: 0x000a, + 0x1576: 0x000a, 0x1577: 0x000a, 0x1578: 0x000a, 0x1579: 0x000a, 0x157a: 0x000a, 0x157b: 0x000a, + 0x157c: 0x000a, 0x157d: 0x000a, 0x157e: 0x000a, 0x157f: 0x000a, + // Block 0x56, offset 0x1580 + 0x1580: 0x000a, 0x1581: 0x000a, 0x1582: 0x000a, 0x1583: 0x000a, 0x1584: 0x000a, 0x1585: 0x000a, + 0x1586: 0x000a, 0x1587: 0x000a, 0x1588: 0x000a, 0x1589: 0x000a, 0x158a: 0x000a, 0x158b: 0x000a, + 0x158c: 0x000a, 0x158d: 0x000a, 0x158e: 0x000a, 0x158f: 0x000a, 0x1590: 0x000a, 0x1591: 0x000a, + 0x1592: 0x000a, 0x1593: 0x000a, 0x1594: 0x000a, 0x1595: 0x000a, 0x1596: 0x000a, 0x1597: 0x000a, + 0x1598: 0x000a, 0x1599: 0x000a, 0x159a: 0x000a, 0x159b: 0x000a, 0x159c: 0x000a, 0x159d: 0x000a, + 0x159e: 0x000a, 0x159f: 0x000a, 0x15a0: 0x000a, 0x15a1: 0x000a, 0x15a2: 0x000a, 0x15a3: 0x000a, + 0x15a4: 0x000a, 0x15a5: 0x000a, 0x15a6: 0x000a, 0x15a7: 0x000a, 0x15a8: 0x000a, 0x15a9: 0x000a, + 0x15aa: 0x000a, 0x15ab: 0x000a, 0x15ac: 0x000a, 0x15ad: 0x000a, 0x15ae: 0x000a, 0x15af: 0x000a, + 0x15b0: 0x000a, 0x15b1: 0x000a, 0x15b2: 0x000a, 0x15b3: 0x000a, 0x15b4: 0x000a, 0x15b5: 0x000a, + 0x15b6: 0x000a, 0x15b7: 0x000a, 0x15b8: 0x000a, 0x15b9: 0x000a, 0x15ba: 0x000a, 0x15bb: 0x000a, + 0x15bc: 0x000a, 0x15bd: 0x000a, 0x15be: 0x000a, 0x15bf: 0x000a, + // Block 0x57, offset 0x15c0 + 0x15c0: 0x000a, 0x15c1: 0x000a, 0x15c2: 0x000a, 0x15c3: 0x000a, 0x15c4: 0x000a, 0x15c5: 0x000a, + 0x15c6: 0x000a, 0x15c7: 0x000a, 0x15c8: 0x000a, 0x15c9: 0x000a, 0x15ca: 0x000a, 0x15cb: 0x000a, + 0x15cc: 0x000a, 0x15cd: 0x000a, 0x15ce: 0x000a, 0x15cf: 0x000a, 0x15d0: 0x000a, 0x15d1: 0x000a, + 0x15d2: 0x0003, 0x15d3: 0x0004, 0x15d4: 0x000a, 0x15d5: 0x000a, 0x15d6: 0x000a, 0x15d7: 0x000a, + 0x15d8: 0x000a, 0x15d9: 0x000a, 0x15da: 0x000a, 0x15db: 0x000a, 0x15dc: 0x000a, 0x15dd: 0x000a, + 0x15de: 0x000a, 0x15df: 0x000a, 0x15e0: 0x000a, 0x15e1: 0x000a, 0x15e2: 0x000a, 0x15e3: 0x000a, + 0x15e4: 0x000a, 0x15e5: 0x000a, 0x15e6: 0x000a, 0x15e7: 0x000a, 0x15e8: 0x000a, 0x15e9: 0x000a, + 0x15ea: 0x000a, 0x15eb: 0x000a, 0x15ec: 0x000a, 0x15ed: 0x000a, 0x15ee: 0x000a, 0x15ef: 0x000a, + 0x15f0: 0x000a, 0x15f1: 0x000a, 0x15f2: 0x000a, 0x15f3: 0x000a, 0x15f4: 0x000a, 0x15f5: 0x000a, + 0x15f6: 0x000a, 0x15f7: 0x000a, 0x15f8: 0x000a, 0x15f9: 0x000a, 0x15fa: 0x000a, 0x15fb: 0x000a, + 0x15fc: 0x000a, 0x15fd: 0x000a, 0x15fe: 0x000a, 0x15ff: 0x000a, + // Block 0x58, offset 0x1600 + 0x1600: 0x000a, 0x1601: 0x000a, 0x1602: 0x000a, 0x1603: 0x000a, 0x1604: 0x000a, 0x1605: 0x000a, + 0x1606: 0x000a, 0x1607: 0x000a, 0x1608: 0x003a, 0x1609: 0x002a, 0x160a: 0x003a, 0x160b: 0x002a, + 0x160c: 0x000a, 0x160d: 0x000a, 0x160e: 0x000a, 0x160f: 0x000a, 0x1610: 0x000a, 0x1611: 0x000a, + 0x1612: 0x000a, 0x1613: 0x000a, 0x1614: 0x000a, 0x1615: 0x000a, 0x1616: 0x000a, 0x1617: 0x000a, + 0x1618: 0x000a, 0x1619: 0x000a, 0x161a: 0x000a, 0x161b: 0x000a, 0x161c: 0x000a, 0x161d: 0x000a, + 0x161e: 0x000a, 0x161f: 0x000a, 0x1620: 0x000a, 0x1621: 0x000a, 0x1622: 0x000a, 0x1623: 0x000a, + 0x1624: 0x000a, 0x1625: 0x000a, 0x1626: 0x000a, 0x1627: 0x000a, 0x1628: 0x000a, 0x1629: 0x009a, + 0x162a: 0x008a, 0x162b: 0x000a, 0x162c: 0x000a, 0x162d: 0x000a, 0x162e: 0x000a, 0x162f: 0x000a, + 0x1630: 0x000a, 0x1631: 0x000a, 0x1632: 0x000a, 0x1633: 0x000a, 0x1634: 0x000a, 0x1635: 0x000a, + // Block 0x59, offset 0x1640 + 0x167b: 0x000a, + 0x167c: 0x000a, 0x167d: 0x000a, 0x167e: 0x000a, 0x167f: 0x000a, + // Block 0x5a, offset 0x1680 + 0x1680: 0x000a, 0x1681: 0x000a, 0x1682: 0x000a, 0x1683: 0x000a, 0x1684: 0x000a, 0x1685: 0x000a, + 0x1686: 0x000a, 0x1687: 0x000a, 0x1688: 0x000a, 0x1689: 0x000a, 0x168a: 0x000a, 0x168b: 0x000a, + 0x168c: 0x000a, 0x168d: 0x000a, 0x168e: 0x000a, 0x168f: 0x000a, 0x1690: 0x000a, 0x1691: 0x000a, + 0x1692: 0x000a, 0x1693: 0x000a, 0x1694: 0x000a, 0x1696: 0x000a, 0x1697: 0x000a, + 0x1698: 0x000a, 0x1699: 0x000a, 0x169a: 0x000a, 0x169b: 0x000a, 0x169c: 0x000a, 0x169d: 0x000a, + 0x169e: 0x000a, 0x169f: 0x000a, 0x16a0: 0x000a, 0x16a1: 0x000a, 0x16a2: 0x000a, 0x16a3: 0x000a, + 0x16a4: 0x000a, 0x16a5: 0x000a, 0x16a6: 0x000a, 0x16a7: 0x000a, 0x16a8: 0x000a, 0x16a9: 0x000a, + 0x16aa: 0x000a, 0x16ab: 0x000a, 0x16ac: 0x000a, 0x16ad: 0x000a, 0x16ae: 0x000a, 0x16af: 0x000a, + 0x16b0: 0x000a, 0x16b1: 0x000a, 0x16b2: 0x000a, 0x16b3: 0x000a, 0x16b4: 0x000a, 0x16b5: 0x000a, + 0x16b6: 0x000a, 0x16b7: 0x000a, 0x16b8: 0x000a, 0x16b9: 0x000a, 0x16ba: 0x000a, 0x16bb: 0x000a, + 0x16bc: 0x000a, 0x16bd: 0x000a, 0x16be: 0x000a, 0x16bf: 0x000a, + // Block 0x5b, offset 0x16c0 + 0x16c0: 0x000a, 0x16c1: 0x000a, 0x16c2: 0x000a, 0x16c3: 0x000a, 0x16c4: 0x000a, 0x16c5: 0x000a, + 0x16c6: 0x000a, 0x16c7: 0x000a, 0x16c8: 0x000a, 0x16c9: 0x000a, 0x16ca: 0x000a, 0x16cb: 0x000a, + 0x16cc: 0x000a, 0x16cd: 0x000a, 0x16ce: 0x000a, 0x16cf: 0x000a, 0x16d0: 0x000a, 0x16d1: 0x000a, + 0x16d2: 0x000a, 0x16d3: 0x000a, 0x16d4: 0x000a, 0x16d5: 0x000a, 0x16d6: 0x000a, 0x16d7: 0x000a, + 0x16d8: 0x000a, 0x16d9: 0x000a, 0x16da: 0x000a, 0x16db: 0x000a, 0x16dc: 0x000a, 0x16dd: 0x000a, + 0x16de: 0x000a, 0x16df: 0x000a, 0x16e0: 0x000a, 0x16e1: 0x000a, 0x16e2: 0x000a, 0x16e3: 0x000a, + 0x16e4: 0x000a, 0x16e5: 0x000a, 0x16e6: 0x000a, 0x16e7: 0x000a, 0x16e8: 0x000a, 0x16e9: 0x000a, + 0x16ea: 0x000a, 0x16eb: 0x000a, 0x16ec: 0x000a, 0x16ed: 0x000a, 0x16ee: 0x000a, 0x16ef: 0x000a, + 0x16f0: 0x000a, 0x16f1: 0x000a, 0x16f2: 0x000a, 0x16f3: 0x000a, 0x16f4: 0x000a, 0x16f5: 0x000a, + 0x16f6: 0x000a, 0x16f7: 0x000a, 0x16f8: 0x000a, 0x16f9: 0x000a, 0x16fa: 0x000a, 0x16fb: 0x000a, + 0x16fc: 0x000a, 0x16fd: 0x000a, 0x16fe: 0x000a, + // Block 0x5c, offset 0x1700 + 0x1700: 0x000a, 0x1701: 0x000a, 0x1702: 0x000a, 0x1703: 0x000a, 0x1704: 0x000a, 0x1705: 0x000a, + 0x1706: 0x000a, 0x1707: 0x000a, 0x1708: 0x000a, 0x1709: 0x000a, 0x170a: 0x000a, 0x170b: 0x000a, + 0x170c: 0x000a, 0x170d: 0x000a, 0x170e: 0x000a, 0x170f: 0x000a, 0x1710: 0x000a, 0x1711: 0x000a, + 0x1712: 0x000a, 0x1713: 0x000a, 0x1714: 0x000a, 0x1715: 0x000a, 0x1716: 0x000a, 0x1717: 0x000a, + 0x1718: 0x000a, 0x1719: 0x000a, 0x171a: 0x000a, 0x171b: 0x000a, 0x171c: 0x000a, 0x171d: 0x000a, + 0x171e: 0x000a, 0x171f: 0x000a, 0x1720: 0x000a, 0x1721: 0x000a, 0x1722: 0x000a, 0x1723: 0x000a, + 0x1724: 0x000a, 0x1725: 0x000a, 0x1726: 0x000a, + // Block 0x5d, offset 0x1740 + 0x1740: 0x000a, 0x1741: 0x000a, 0x1742: 0x000a, 0x1743: 0x000a, 0x1744: 0x000a, 0x1745: 0x000a, + 0x1746: 0x000a, 0x1747: 0x000a, 0x1748: 0x000a, 0x1749: 0x000a, 0x174a: 0x000a, + 0x1760: 0x000a, 0x1761: 0x000a, 0x1762: 0x000a, 0x1763: 0x000a, + 0x1764: 0x000a, 0x1765: 0x000a, 0x1766: 0x000a, 0x1767: 0x000a, 0x1768: 0x000a, 0x1769: 0x000a, + 0x176a: 0x000a, 0x176b: 0x000a, 0x176c: 0x000a, 0x176d: 0x000a, 0x176e: 0x000a, 0x176f: 0x000a, + 0x1770: 0x000a, 0x1771: 0x000a, 0x1772: 0x000a, 0x1773: 0x000a, 0x1774: 0x000a, 0x1775: 0x000a, + 0x1776: 0x000a, 0x1777: 0x000a, 0x1778: 0x000a, 0x1779: 0x000a, 0x177a: 0x000a, 0x177b: 0x000a, + 0x177c: 0x000a, 0x177d: 0x000a, 0x177e: 0x000a, 0x177f: 0x000a, + // Block 0x5e, offset 0x1780 + 0x1780: 0x000a, 0x1781: 0x000a, 0x1782: 0x000a, 0x1783: 0x000a, 0x1784: 0x000a, 0x1785: 0x000a, + 0x1786: 0x000a, 0x1787: 0x000a, 0x1788: 0x0002, 0x1789: 0x0002, 0x178a: 0x0002, 0x178b: 0x0002, + 0x178c: 0x0002, 0x178d: 0x0002, 0x178e: 0x0002, 0x178f: 0x0002, 0x1790: 0x0002, 0x1791: 0x0002, + 0x1792: 0x0002, 0x1793: 0x0002, 0x1794: 0x0002, 0x1795: 0x0002, 0x1796: 0x0002, 0x1797: 0x0002, + 0x1798: 0x0002, 0x1799: 0x0002, 0x179a: 0x0002, 0x179b: 0x0002, + // Block 0x5f, offset 0x17c0 + 0x17ea: 0x000a, 0x17eb: 0x000a, 0x17ec: 0x000a, 0x17ed: 0x000a, 0x17ee: 0x000a, 0x17ef: 0x000a, + 0x17f0: 0x000a, 0x17f1: 0x000a, 0x17f2: 0x000a, 0x17f3: 0x000a, 0x17f4: 0x000a, 0x17f5: 0x000a, + 0x17f6: 0x000a, 0x17f7: 0x000a, 0x17f8: 0x000a, 0x17f9: 0x000a, 0x17fa: 0x000a, 0x17fb: 0x000a, + 0x17fc: 0x000a, 0x17fd: 0x000a, 0x17fe: 0x000a, 0x17ff: 0x000a, + // Block 0x60, offset 0x1800 + 0x1800: 0x000a, 0x1801: 0x000a, 0x1802: 0x000a, 0x1803: 0x000a, 0x1804: 0x000a, 0x1805: 0x000a, + 0x1806: 0x000a, 0x1807: 0x000a, 0x1808: 0x000a, 0x1809: 0x000a, 0x180a: 0x000a, 0x180b: 0x000a, + 0x180c: 0x000a, 0x180d: 0x000a, 0x180e: 0x000a, 0x180f: 0x000a, 0x1810: 0x000a, 0x1811: 0x000a, + 0x1812: 0x000a, 0x1813: 0x000a, 0x1814: 0x000a, 0x1815: 0x000a, 0x1816: 0x000a, 0x1817: 0x000a, + 0x1818: 0x000a, 0x1819: 0x000a, 0x181a: 0x000a, 0x181b: 0x000a, 0x181c: 0x000a, 0x181d: 0x000a, + 0x181e: 0x000a, 0x181f: 0x000a, 0x1820: 0x000a, 0x1821: 0x000a, 0x1822: 0x000a, 0x1823: 0x000a, + 0x1824: 0x000a, 0x1825: 0x000a, 0x1826: 0x000a, 0x1827: 0x000a, 0x1828: 0x000a, 0x1829: 0x000a, + 0x182a: 0x000a, 0x182b: 0x000a, 0x182d: 0x000a, 0x182e: 0x000a, 0x182f: 0x000a, + 0x1830: 0x000a, 0x1831: 0x000a, 0x1832: 0x000a, 0x1833: 0x000a, 0x1834: 0x000a, 0x1835: 0x000a, + 0x1836: 0x000a, 0x1837: 0x000a, 0x1838: 0x000a, 0x1839: 0x000a, 0x183a: 0x000a, 0x183b: 0x000a, + 0x183c: 0x000a, 0x183d: 0x000a, 0x183e: 0x000a, 0x183f: 0x000a, + // Block 0x61, offset 0x1840 + 0x1840: 0x000a, 0x1841: 0x000a, 0x1842: 0x000a, 0x1843: 0x000a, 0x1844: 0x000a, 0x1845: 0x000a, + 0x1846: 0x000a, 0x1847: 0x000a, 0x1848: 0x000a, 0x1849: 0x000a, 0x184a: 0x000a, 0x184b: 0x000a, + 0x184c: 0x000a, 0x184d: 0x000a, 0x184e: 0x000a, 0x184f: 0x000a, 0x1850: 0x000a, 0x1851: 0x000a, + 0x1852: 0x000a, 0x1853: 0x000a, 0x1854: 0x000a, 0x1855: 0x000a, 0x1856: 0x000a, 0x1857: 0x000a, + 0x1858: 0x000a, 0x1859: 0x000a, 0x185a: 0x000a, 0x185b: 0x000a, 0x185c: 0x000a, 0x185d: 0x000a, + 0x185e: 0x000a, 0x185f: 0x000a, 0x1860: 0x000a, 0x1861: 0x000a, 0x1862: 0x000a, 0x1863: 0x000a, + 0x1864: 0x000a, 0x1865: 0x000a, 0x1866: 0x000a, 0x1867: 0x000a, 0x1868: 0x003a, 0x1869: 0x002a, + 0x186a: 0x003a, 0x186b: 0x002a, 0x186c: 0x003a, 0x186d: 0x002a, 0x186e: 0x003a, 0x186f: 0x002a, + 0x1870: 0x003a, 0x1871: 0x002a, 0x1872: 0x003a, 0x1873: 0x002a, 0x1874: 0x003a, 0x1875: 0x002a, + 0x1876: 0x000a, 0x1877: 0x000a, 0x1878: 0x000a, 0x1879: 0x000a, 0x187a: 0x000a, 0x187b: 0x000a, + 0x187c: 0x000a, 0x187d: 0x000a, 0x187e: 0x000a, 0x187f: 0x000a, + // Block 0x62, offset 0x1880 + 0x1880: 0x000a, 0x1881: 0x000a, 0x1882: 0x000a, 0x1883: 0x000a, 0x1884: 0x000a, 0x1885: 0x009a, + 0x1886: 0x008a, 0x1887: 0x000a, 0x1888: 0x000a, 0x1889: 0x000a, 0x188a: 0x000a, 0x188b: 0x000a, + 0x188c: 0x000a, 0x188d: 0x000a, 0x188e: 0x000a, 0x188f: 0x000a, 0x1890: 0x000a, 0x1891: 0x000a, + 0x1892: 0x000a, 0x1893: 0x000a, 0x1894: 0x000a, 0x1895: 0x000a, 0x1896: 0x000a, 0x1897: 0x000a, + 0x1898: 0x000a, 0x1899: 0x000a, 0x189a: 0x000a, 0x189b: 0x000a, 0x189c: 0x000a, 0x189d: 0x000a, + 0x189e: 0x000a, 0x189f: 0x000a, 0x18a0: 0x000a, 0x18a1: 0x000a, 0x18a2: 0x000a, 0x18a3: 0x000a, + 0x18a4: 0x000a, 0x18a5: 0x000a, 0x18a6: 0x003a, 0x18a7: 0x002a, 0x18a8: 0x003a, 0x18a9: 0x002a, + 0x18aa: 0x003a, 0x18ab: 0x002a, 0x18ac: 0x003a, 0x18ad: 0x002a, 0x18ae: 0x003a, 0x18af: 0x002a, + 0x18b0: 0x000a, 0x18b1: 0x000a, 0x18b2: 0x000a, 0x18b3: 0x000a, 0x18b4: 0x000a, 0x18b5: 0x000a, + 0x18b6: 0x000a, 0x18b7: 0x000a, 0x18b8: 0x000a, 0x18b9: 0x000a, 0x18ba: 0x000a, 0x18bb: 0x000a, + 0x18bc: 0x000a, 0x18bd: 0x000a, 0x18be: 0x000a, 0x18bf: 0x000a, + // Block 0x63, offset 0x18c0 + 0x18c0: 0x000a, 0x18c1: 0x000a, 0x18c2: 0x000a, 0x18c3: 0x007a, 0x18c4: 0x006a, 0x18c5: 0x009a, + 0x18c6: 0x008a, 0x18c7: 0x00ba, 0x18c8: 0x00aa, 0x18c9: 0x009a, 0x18ca: 0x008a, 0x18cb: 0x007a, + 0x18cc: 0x006a, 0x18cd: 0x00da, 0x18ce: 0x002a, 0x18cf: 0x003a, 0x18d0: 0x00ca, 0x18d1: 0x009a, + 0x18d2: 0x008a, 0x18d3: 0x007a, 0x18d4: 0x006a, 0x18d5: 0x009a, 0x18d6: 0x008a, 0x18d7: 0x00ba, + 0x18d8: 0x00aa, 0x18d9: 0x000a, 0x18da: 0x000a, 0x18db: 0x000a, 0x18dc: 0x000a, 0x18dd: 0x000a, + 0x18de: 0x000a, 0x18df: 0x000a, 0x18e0: 0x000a, 0x18e1: 0x000a, 0x18e2: 0x000a, 0x18e3: 0x000a, + 0x18e4: 0x000a, 0x18e5: 0x000a, 0x18e6: 0x000a, 0x18e7: 0x000a, 0x18e8: 0x000a, 0x18e9: 0x000a, + 0x18ea: 0x000a, 0x18eb: 0x000a, 0x18ec: 0x000a, 0x18ed: 0x000a, 0x18ee: 0x000a, 0x18ef: 0x000a, + 0x18f0: 0x000a, 0x18f1: 0x000a, 0x18f2: 0x000a, 0x18f3: 0x000a, 0x18f4: 0x000a, 0x18f5: 0x000a, + 0x18f6: 0x000a, 0x18f7: 0x000a, 0x18f8: 0x000a, 0x18f9: 0x000a, 0x18fa: 0x000a, 0x18fb: 0x000a, + 0x18fc: 0x000a, 0x18fd: 0x000a, 0x18fe: 0x000a, 0x18ff: 0x000a, + // Block 0x64, offset 0x1900 + 0x1900: 0x000a, 0x1901: 0x000a, 0x1902: 0x000a, 0x1903: 0x000a, 0x1904: 0x000a, 0x1905: 0x000a, + 0x1906: 0x000a, 0x1907: 0x000a, 0x1908: 0x000a, 0x1909: 0x000a, 0x190a: 0x000a, 0x190b: 0x000a, + 0x190c: 0x000a, 0x190d: 0x000a, 0x190e: 0x000a, 0x190f: 0x000a, 0x1910: 0x000a, 0x1911: 0x000a, + 0x1912: 0x000a, 0x1913: 0x000a, 0x1914: 0x000a, 0x1915: 0x000a, 0x1916: 0x000a, 0x1917: 0x000a, + 0x1918: 0x003a, 0x1919: 0x002a, 0x191a: 0x003a, 0x191b: 0x002a, 0x191c: 0x000a, 0x191d: 0x000a, + 0x191e: 0x000a, 0x191f: 0x000a, 0x1920: 0x000a, 0x1921: 0x000a, 0x1922: 0x000a, 0x1923: 0x000a, + 0x1924: 0x000a, 0x1925: 0x000a, 0x1926: 0x000a, 0x1927: 0x000a, 0x1928: 0x000a, 0x1929: 0x000a, + 0x192a: 0x000a, 0x192b: 0x000a, 0x192c: 0x000a, 0x192d: 0x000a, 0x192e: 0x000a, 0x192f: 0x000a, + 0x1930: 0x000a, 0x1931: 0x000a, 0x1932: 0x000a, 0x1933: 0x000a, 0x1934: 0x000a, 0x1935: 0x000a, + 0x1936: 0x000a, 0x1937: 0x000a, 0x1938: 0x000a, 0x1939: 0x000a, 0x193a: 0x000a, 0x193b: 0x000a, + 0x193c: 0x003a, 0x193d: 0x002a, 0x193e: 0x000a, 0x193f: 0x000a, + // Block 0x65, offset 0x1940 + 0x1940: 0x000a, 0x1941: 0x000a, 0x1942: 0x000a, 0x1943: 0x000a, 0x1944: 0x000a, 0x1945: 0x000a, + 0x1946: 0x000a, 0x1947: 0x000a, 0x1948: 0x000a, 0x1949: 0x000a, 0x194a: 0x000a, 0x194b: 0x000a, + 0x194c: 0x000a, 0x194d: 0x000a, 0x194e: 0x000a, 0x194f: 0x000a, 0x1950: 0x000a, 0x1951: 0x000a, + 0x1952: 0x000a, 0x1953: 0x000a, 0x1954: 0x000a, 0x1955: 0x000a, 0x1956: 0x000a, 0x1957: 0x000a, + 0x1958: 0x000a, 0x1959: 0x000a, 0x195a: 0x000a, 0x195b: 0x000a, 0x195c: 0x000a, 0x195d: 0x000a, + 0x195e: 0x000a, 0x195f: 0x000a, 0x1960: 0x000a, 0x1961: 0x000a, 0x1962: 0x000a, 0x1963: 0x000a, + 0x1964: 0x000a, 0x1965: 0x000a, 0x1966: 0x000a, 0x1967: 0x000a, 0x1968: 0x000a, 0x1969: 0x000a, + 0x196a: 0x000a, 0x196b: 0x000a, 0x196c: 0x000a, 0x196d: 0x000a, 0x196e: 0x000a, 0x196f: 0x000a, + 0x1970: 0x000a, 0x1971: 0x000a, 0x1972: 0x000a, 0x1973: 0x000a, + 0x1976: 0x000a, 0x1977: 0x000a, 0x1978: 0x000a, 0x1979: 0x000a, 0x197a: 0x000a, 0x197b: 0x000a, + 0x197c: 0x000a, 0x197d: 0x000a, 0x197e: 0x000a, 0x197f: 0x000a, + // Block 0x66, offset 0x1980 + 0x1980: 0x000a, 0x1981: 0x000a, 0x1982: 0x000a, 0x1983: 0x000a, 0x1984: 0x000a, 0x1985: 0x000a, + 0x1986: 0x000a, 0x1987: 0x000a, 0x1988: 0x000a, 0x1989: 0x000a, 0x198a: 0x000a, 0x198b: 0x000a, + 0x198c: 0x000a, 0x198d: 0x000a, 0x198e: 0x000a, 0x198f: 0x000a, 0x1990: 0x000a, 0x1991: 0x000a, + 0x1992: 0x000a, 0x1993: 0x000a, 0x1994: 0x000a, 0x1995: 0x000a, + 0x1998: 0x000a, 0x1999: 0x000a, 0x199a: 0x000a, 0x199b: 0x000a, 0x199c: 0x000a, 0x199d: 0x000a, + 0x199e: 0x000a, 0x199f: 0x000a, 0x19a0: 0x000a, 0x19a1: 0x000a, 0x19a2: 0x000a, 0x19a3: 0x000a, + 0x19a4: 0x000a, 0x19a5: 0x000a, 0x19a6: 0x000a, 0x19a7: 0x000a, 0x19a8: 0x000a, 0x19a9: 0x000a, + 0x19aa: 0x000a, 0x19ab: 0x000a, 0x19ac: 0x000a, 0x19ad: 0x000a, 0x19ae: 0x000a, 0x19af: 0x000a, + 0x19b0: 0x000a, 0x19b1: 0x000a, 0x19b2: 0x000a, 0x19b3: 0x000a, 0x19b4: 0x000a, 0x19b5: 0x000a, + 0x19b6: 0x000a, 0x19b7: 0x000a, 0x19b8: 0x000a, 0x19b9: 0x000a, + 0x19bd: 0x000a, 0x19be: 0x000a, 0x19bf: 0x000a, + // Block 0x67, offset 0x19c0 + 0x19c0: 0x000a, 0x19c1: 0x000a, 0x19c2: 0x000a, 0x19c3: 0x000a, 0x19c4: 0x000a, 0x19c5: 0x000a, + 0x19c6: 0x000a, 0x19c7: 0x000a, 0x19c8: 0x000a, 0x19ca: 0x000a, 0x19cb: 0x000a, + 0x19cc: 0x000a, 0x19cd: 0x000a, 0x19ce: 0x000a, 0x19cf: 0x000a, 0x19d0: 0x000a, 0x19d1: 0x000a, + 0x19ec: 0x000a, 0x19ed: 0x000a, 0x19ee: 0x000a, 0x19ef: 0x000a, + // Block 0x68, offset 0x1a00 + 0x1a25: 0x000a, 0x1a26: 0x000a, 0x1a27: 0x000a, 0x1a28: 0x000a, 0x1a29: 0x000a, + 0x1a2a: 0x000a, 0x1a2f: 0x000c, + 0x1a30: 0x000c, 0x1a31: 0x000c, + 0x1a39: 0x000a, 0x1a3a: 0x000a, 0x1a3b: 0x000a, + 0x1a3c: 0x000a, 0x1a3d: 0x000a, 0x1a3e: 0x000a, 0x1a3f: 0x000a, + // Block 0x69, offset 0x1a40 + 0x1a7f: 0x000c, + // Block 0x6a, offset 0x1a80 + 0x1aa0: 0x000c, 0x1aa1: 0x000c, 0x1aa2: 0x000c, 0x1aa3: 0x000c, + 0x1aa4: 0x000c, 0x1aa5: 0x000c, 0x1aa6: 0x000c, 0x1aa7: 0x000c, 0x1aa8: 0x000c, 0x1aa9: 0x000c, + 0x1aaa: 0x000c, 0x1aab: 0x000c, 0x1aac: 0x000c, 0x1aad: 0x000c, 0x1aae: 0x000c, 0x1aaf: 0x000c, + 0x1ab0: 0x000c, 0x1ab1: 0x000c, 0x1ab2: 0x000c, 0x1ab3: 0x000c, 0x1ab4: 0x000c, 0x1ab5: 0x000c, + 0x1ab6: 0x000c, 0x1ab7: 0x000c, 0x1ab8: 0x000c, 0x1ab9: 0x000c, 0x1aba: 0x000c, 0x1abb: 0x000c, + 0x1abc: 0x000c, 0x1abd: 0x000c, 0x1abe: 0x000c, 0x1abf: 0x000c, + // Block 0x6b, offset 0x1ac0 + 0x1ac0: 0x000a, 0x1ac1: 0x000a, 0x1ac2: 0x000a, 0x1ac3: 0x000a, 0x1ac4: 0x000a, 0x1ac5: 0x000a, + 0x1ac6: 0x000a, 0x1ac7: 0x000a, 0x1ac8: 0x000a, 0x1ac9: 0x000a, 0x1aca: 0x000a, 0x1acb: 0x000a, + 0x1acc: 0x000a, 0x1acd: 0x000a, 0x1ace: 0x000a, 0x1acf: 0x000a, 0x1ad0: 0x000a, 0x1ad1: 0x000a, + 0x1ad2: 0x000a, 0x1ad3: 0x000a, 0x1ad4: 0x000a, 0x1ad5: 0x000a, 0x1ad6: 0x000a, 0x1ad7: 0x000a, + 0x1ad8: 0x000a, 0x1ad9: 0x000a, 0x1ada: 0x000a, 0x1adb: 0x000a, 0x1adc: 0x000a, 0x1add: 0x000a, + 0x1ade: 0x000a, 0x1adf: 0x000a, 0x1ae0: 0x000a, 0x1ae1: 0x000a, 0x1ae2: 0x003a, 0x1ae3: 0x002a, + 0x1ae4: 0x003a, 0x1ae5: 0x002a, 0x1ae6: 0x003a, 0x1ae7: 0x002a, 0x1ae8: 0x003a, 0x1ae9: 0x002a, + 0x1aea: 0x000a, 0x1aeb: 0x000a, 0x1aec: 0x000a, 0x1aed: 0x000a, 0x1aee: 0x000a, 0x1aef: 0x000a, + 0x1af0: 0x000a, 0x1af1: 0x000a, 0x1af2: 0x000a, 0x1af3: 0x000a, 0x1af4: 0x000a, 0x1af5: 0x000a, + 0x1af6: 0x000a, 0x1af7: 0x000a, 0x1af8: 0x000a, 0x1af9: 0x000a, 0x1afa: 0x000a, 0x1afb: 0x000a, + 0x1afc: 0x000a, 0x1afd: 0x000a, 0x1afe: 0x000a, 0x1aff: 0x000a, + // Block 0x6c, offset 0x1b00 + 0x1b00: 0x000a, 0x1b01: 0x000a, 0x1b02: 0x000a, 0x1b03: 0x000a, 0x1b04: 0x000a, + // Block 0x6d, offset 0x1b40 + 0x1b40: 0x000a, 0x1b41: 0x000a, 0x1b42: 0x000a, 0x1b43: 0x000a, 0x1b44: 0x000a, 0x1b45: 0x000a, + 0x1b46: 0x000a, 0x1b47: 0x000a, 0x1b48: 0x000a, 0x1b49: 0x000a, 0x1b4a: 0x000a, 0x1b4b: 0x000a, + 0x1b4c: 0x000a, 0x1b4d: 0x000a, 0x1b4e: 0x000a, 0x1b4f: 0x000a, 0x1b50: 0x000a, 0x1b51: 0x000a, + 0x1b52: 0x000a, 0x1b53: 0x000a, 0x1b54: 0x000a, 0x1b55: 0x000a, 0x1b56: 0x000a, 0x1b57: 0x000a, + 0x1b58: 0x000a, 0x1b59: 0x000a, 0x1b5b: 0x000a, 0x1b5c: 0x000a, 0x1b5d: 0x000a, + 0x1b5e: 0x000a, 0x1b5f: 0x000a, 0x1b60: 0x000a, 0x1b61: 0x000a, 0x1b62: 0x000a, 0x1b63: 0x000a, + 0x1b64: 0x000a, 0x1b65: 0x000a, 0x1b66: 0x000a, 0x1b67: 0x000a, 0x1b68: 0x000a, 0x1b69: 0x000a, + 0x1b6a: 0x000a, 0x1b6b: 0x000a, 0x1b6c: 0x000a, 0x1b6d: 0x000a, 0x1b6e: 0x000a, 0x1b6f: 0x000a, + 0x1b70: 0x000a, 0x1b71: 0x000a, 0x1b72: 0x000a, 0x1b73: 0x000a, 0x1b74: 0x000a, 0x1b75: 0x000a, + 0x1b76: 0x000a, 0x1b77: 0x000a, 0x1b78: 0x000a, 0x1b79: 0x000a, 0x1b7a: 0x000a, 0x1b7b: 0x000a, + 0x1b7c: 0x000a, 0x1b7d: 0x000a, 0x1b7e: 0x000a, 0x1b7f: 0x000a, + // Block 0x6e, offset 0x1b80 + 0x1b80: 0x000a, 0x1b81: 0x000a, 0x1b82: 0x000a, 0x1b83: 0x000a, 0x1b84: 0x000a, 0x1b85: 0x000a, + 0x1b86: 0x000a, 0x1b87: 0x000a, 0x1b88: 0x000a, 0x1b89: 0x000a, 0x1b8a: 0x000a, 0x1b8b: 0x000a, + 0x1b8c: 0x000a, 0x1b8d: 0x000a, 0x1b8e: 0x000a, 0x1b8f: 0x000a, 0x1b90: 0x000a, 0x1b91: 0x000a, + 0x1b92: 0x000a, 0x1b93: 0x000a, 0x1b94: 0x000a, 0x1b95: 0x000a, 0x1b96: 0x000a, 0x1b97: 0x000a, + 0x1b98: 0x000a, 0x1b99: 0x000a, 0x1b9a: 0x000a, 0x1b9b: 0x000a, 0x1b9c: 0x000a, 0x1b9d: 0x000a, + 0x1b9e: 0x000a, 0x1b9f: 0x000a, 0x1ba0: 0x000a, 0x1ba1: 0x000a, 0x1ba2: 0x000a, 0x1ba3: 0x000a, + 0x1ba4: 0x000a, 0x1ba5: 0x000a, 0x1ba6: 0x000a, 0x1ba7: 0x000a, 0x1ba8: 0x000a, 0x1ba9: 0x000a, + 0x1baa: 0x000a, 0x1bab: 0x000a, 0x1bac: 0x000a, 0x1bad: 0x000a, 0x1bae: 0x000a, 0x1baf: 0x000a, + 0x1bb0: 0x000a, 0x1bb1: 0x000a, 0x1bb2: 0x000a, 0x1bb3: 0x000a, + // Block 0x6f, offset 0x1bc0 + 0x1bc0: 0x000a, 0x1bc1: 0x000a, 0x1bc2: 0x000a, 0x1bc3: 0x000a, 0x1bc4: 0x000a, 0x1bc5: 0x000a, + 0x1bc6: 0x000a, 0x1bc7: 0x000a, 0x1bc8: 0x000a, 0x1bc9: 0x000a, 0x1bca: 0x000a, 0x1bcb: 0x000a, + 0x1bcc: 0x000a, 0x1bcd: 0x000a, 0x1bce: 0x000a, 0x1bcf: 0x000a, 0x1bd0: 0x000a, 0x1bd1: 0x000a, + 0x1bd2: 0x000a, 0x1bd3: 0x000a, 0x1bd4: 0x000a, 0x1bd5: 0x000a, + 0x1bf0: 0x000a, 0x1bf1: 0x000a, 0x1bf2: 0x000a, 0x1bf3: 0x000a, 0x1bf4: 0x000a, 0x1bf5: 0x000a, + 0x1bf6: 0x000a, 0x1bf7: 0x000a, 0x1bf8: 0x000a, 0x1bf9: 0x000a, 0x1bfa: 0x000a, 0x1bfb: 0x000a, + // Block 0x70, offset 0x1c00 + 0x1c00: 0x0009, 0x1c01: 0x000a, 0x1c02: 0x000a, 0x1c03: 0x000a, 0x1c04: 0x000a, + 0x1c08: 0x003a, 0x1c09: 0x002a, 0x1c0a: 0x003a, 0x1c0b: 0x002a, + 0x1c0c: 0x003a, 0x1c0d: 0x002a, 0x1c0e: 0x003a, 0x1c0f: 0x002a, 0x1c10: 0x003a, 0x1c11: 0x002a, + 0x1c12: 0x000a, 0x1c13: 0x000a, 0x1c14: 0x003a, 0x1c15: 0x002a, 0x1c16: 0x003a, 0x1c17: 0x002a, + 0x1c18: 0x003a, 0x1c19: 0x002a, 0x1c1a: 0x003a, 0x1c1b: 0x002a, 0x1c1c: 0x000a, 0x1c1d: 0x000a, + 0x1c1e: 0x000a, 0x1c1f: 0x000a, 0x1c20: 0x000a, + 0x1c2a: 0x000c, 0x1c2b: 0x000c, 0x1c2c: 0x000c, 0x1c2d: 0x000c, + 0x1c30: 0x000a, + 0x1c36: 0x000a, 0x1c37: 0x000a, + 0x1c3d: 0x000a, 0x1c3e: 0x000a, 0x1c3f: 0x000a, + // Block 0x71, offset 0x1c40 + 0x1c59: 0x000c, 0x1c5a: 0x000c, 0x1c5b: 0x000a, 0x1c5c: 0x000a, + 0x1c60: 0x000a, + // Block 0x72, offset 0x1c80 + 0x1cbb: 0x000a, + // Block 0x73, offset 0x1cc0 + 0x1cc0: 0x000a, 0x1cc1: 0x000a, 0x1cc2: 0x000a, 0x1cc3: 0x000a, 0x1cc4: 0x000a, 0x1cc5: 0x000a, + 0x1cc6: 0x000a, 0x1cc7: 0x000a, 0x1cc8: 0x000a, 0x1cc9: 0x000a, 0x1cca: 0x000a, 0x1ccb: 0x000a, + 0x1ccc: 0x000a, 0x1ccd: 0x000a, 0x1cce: 0x000a, 0x1ccf: 0x000a, 0x1cd0: 0x000a, 0x1cd1: 0x000a, + 0x1cd2: 0x000a, 0x1cd3: 0x000a, 0x1cd4: 0x000a, 0x1cd5: 0x000a, 0x1cd6: 0x000a, 0x1cd7: 0x000a, + 0x1cd8: 0x000a, 0x1cd9: 0x000a, 0x1cda: 0x000a, 0x1cdb: 0x000a, 0x1cdc: 0x000a, 0x1cdd: 0x000a, + 0x1cde: 0x000a, 0x1cdf: 0x000a, 0x1ce0: 0x000a, 0x1ce1: 0x000a, 0x1ce2: 0x000a, 0x1ce3: 0x000a, + // Block 0x74, offset 0x1d00 + 0x1d1d: 0x000a, + 0x1d1e: 0x000a, + // Block 0x75, offset 0x1d40 + 0x1d50: 0x000a, 0x1d51: 0x000a, + 0x1d52: 0x000a, 0x1d53: 0x000a, 0x1d54: 0x000a, 0x1d55: 0x000a, 0x1d56: 0x000a, 0x1d57: 0x000a, + 0x1d58: 0x000a, 0x1d59: 0x000a, 0x1d5a: 0x000a, 0x1d5b: 0x000a, 0x1d5c: 0x000a, 0x1d5d: 0x000a, + 0x1d5e: 0x000a, 0x1d5f: 0x000a, + 0x1d7c: 0x000a, 0x1d7d: 0x000a, 0x1d7e: 0x000a, + // Block 0x76, offset 0x1d80 + 0x1db1: 0x000a, 0x1db2: 0x000a, 0x1db3: 0x000a, 0x1db4: 0x000a, 0x1db5: 0x000a, + 0x1db6: 0x000a, 0x1db7: 0x000a, 0x1db8: 0x000a, 0x1db9: 0x000a, 0x1dba: 0x000a, 0x1dbb: 0x000a, + 0x1dbc: 0x000a, 0x1dbd: 0x000a, 0x1dbe: 0x000a, 0x1dbf: 0x000a, + // Block 0x77, offset 0x1dc0 + 0x1dcc: 0x000a, 0x1dcd: 0x000a, 0x1dce: 0x000a, 0x1dcf: 0x000a, + // Block 0x78, offset 0x1e00 + 0x1e37: 0x000a, 0x1e38: 0x000a, 0x1e39: 0x000a, 0x1e3a: 0x000a, + // Block 0x79, offset 0x1e40 + 0x1e5e: 0x000a, 0x1e5f: 0x000a, + 0x1e7f: 0x000a, + // Block 0x7a, offset 0x1e80 + 0x1e90: 0x000a, 0x1e91: 0x000a, + 0x1e92: 0x000a, 0x1e93: 0x000a, 0x1e94: 0x000a, 0x1e95: 0x000a, 0x1e96: 0x000a, 0x1e97: 0x000a, + 0x1e98: 0x000a, 0x1e99: 0x000a, 0x1e9a: 0x000a, 0x1e9b: 0x000a, 0x1e9c: 0x000a, 0x1e9d: 0x000a, + 0x1e9e: 0x000a, 0x1e9f: 0x000a, 0x1ea0: 0x000a, 0x1ea1: 0x000a, 0x1ea2: 0x000a, 0x1ea3: 0x000a, + 0x1ea4: 0x000a, 0x1ea5: 0x000a, 0x1ea6: 0x000a, 0x1ea7: 0x000a, 0x1ea8: 0x000a, 0x1ea9: 0x000a, + 0x1eaa: 0x000a, 0x1eab: 0x000a, 0x1eac: 0x000a, 0x1ead: 0x000a, 0x1eae: 0x000a, 0x1eaf: 0x000a, + 0x1eb0: 0x000a, 0x1eb1: 0x000a, 0x1eb2: 0x000a, 0x1eb3: 0x000a, 0x1eb4: 0x000a, 0x1eb5: 0x000a, + 0x1eb6: 0x000a, 0x1eb7: 0x000a, 0x1eb8: 0x000a, 0x1eb9: 0x000a, 0x1eba: 0x000a, 0x1ebb: 0x000a, + 0x1ebc: 0x000a, 0x1ebd: 0x000a, 0x1ebe: 0x000a, 0x1ebf: 0x000a, + // Block 0x7b, offset 0x1ec0 + 0x1ec0: 0x000a, 0x1ec1: 0x000a, 0x1ec2: 0x000a, 0x1ec3: 0x000a, 0x1ec4: 0x000a, 0x1ec5: 0x000a, + 0x1ec6: 0x000a, + // Block 0x7c, offset 0x1f00 + 0x1f0d: 0x000a, 0x1f0e: 0x000a, 0x1f0f: 0x000a, + // Block 0x7d, offset 0x1f40 + 0x1f6f: 0x000c, + 0x1f70: 0x000c, 0x1f71: 0x000c, 0x1f72: 0x000c, 0x1f73: 0x000a, 0x1f74: 0x000c, 0x1f75: 0x000c, + 0x1f76: 0x000c, 0x1f77: 0x000c, 0x1f78: 0x000c, 0x1f79: 0x000c, 0x1f7a: 0x000c, 0x1f7b: 0x000c, + 0x1f7c: 0x000c, 0x1f7d: 0x000c, 0x1f7e: 0x000a, 0x1f7f: 0x000a, + // Block 0x7e, offset 0x1f80 + 0x1f9e: 0x000c, 0x1f9f: 0x000c, + // Block 0x7f, offset 0x1fc0 + 0x1ff0: 0x000c, 0x1ff1: 0x000c, + // Block 0x80, offset 0x2000 + 0x2000: 0x000a, 0x2001: 0x000a, 0x2002: 0x000a, 0x2003: 0x000a, 0x2004: 0x000a, 0x2005: 0x000a, + 0x2006: 0x000a, 0x2007: 0x000a, 0x2008: 0x000a, 0x2009: 0x000a, 0x200a: 0x000a, 0x200b: 0x000a, + 0x200c: 0x000a, 0x200d: 0x000a, 0x200e: 0x000a, 0x200f: 0x000a, 0x2010: 0x000a, 0x2011: 0x000a, + 0x2012: 0x000a, 0x2013: 0x000a, 0x2014: 0x000a, 0x2015: 0x000a, 0x2016: 0x000a, 0x2017: 0x000a, + 0x2018: 0x000a, 0x2019: 0x000a, 0x201a: 0x000a, 0x201b: 0x000a, 0x201c: 0x000a, 0x201d: 0x000a, + 0x201e: 0x000a, 0x201f: 0x000a, 0x2020: 0x000a, 0x2021: 0x000a, + // Block 0x81, offset 0x2040 + 0x2048: 0x000a, + // Block 0x82, offset 0x2080 + 0x2082: 0x000c, + 0x2086: 0x000c, 0x208b: 0x000c, + 0x20a5: 0x000c, 0x20a6: 0x000c, 0x20a8: 0x000a, 0x20a9: 0x000a, + 0x20aa: 0x000a, 0x20ab: 0x000a, + 0x20b8: 0x0004, 0x20b9: 0x0004, + // Block 0x83, offset 0x20c0 + 0x20f4: 0x000a, 0x20f5: 0x000a, + 0x20f6: 0x000a, 0x20f7: 0x000a, + // Block 0x84, offset 0x2100 + 0x2104: 0x000c, 0x2105: 0x000c, + 0x2120: 0x000c, 0x2121: 0x000c, 0x2122: 0x000c, 0x2123: 0x000c, + 0x2124: 0x000c, 0x2125: 0x000c, 0x2126: 0x000c, 0x2127: 0x000c, 0x2128: 0x000c, 0x2129: 0x000c, + 0x212a: 0x000c, 0x212b: 0x000c, 0x212c: 0x000c, 0x212d: 0x000c, 0x212e: 0x000c, 0x212f: 0x000c, + 0x2130: 0x000c, 0x2131: 0x000c, + // Block 0x85, offset 0x2140 + 0x2166: 0x000c, 0x2167: 0x000c, 0x2168: 0x000c, 0x2169: 0x000c, + 0x216a: 0x000c, 0x216b: 0x000c, 0x216c: 0x000c, 0x216d: 0x000c, + // Block 0x86, offset 0x2180 + 0x2187: 0x000c, 0x2188: 0x000c, 0x2189: 0x000c, 0x218a: 0x000c, 0x218b: 0x000c, + 0x218c: 0x000c, 0x218d: 0x000c, 0x218e: 0x000c, 0x218f: 0x000c, 0x2190: 0x000c, 0x2191: 0x000c, + // Block 0x87, offset 0x21c0 + 0x21c0: 0x000c, 0x21c1: 0x000c, 0x21c2: 0x000c, + 0x21f3: 0x000c, + 0x21f6: 0x000c, 0x21f7: 0x000c, 0x21f8: 0x000c, 0x21f9: 0x000c, + 0x21fc: 0x000c, + // Block 0x88, offset 0x2200 + 0x2225: 0x000c, + // Block 0x89, offset 0x2240 + 0x2269: 0x000c, + 0x226a: 0x000c, 0x226b: 0x000c, 0x226c: 0x000c, 0x226d: 0x000c, 0x226e: 0x000c, + 0x2271: 0x000c, 0x2272: 0x000c, 0x2275: 0x000c, + 0x2276: 0x000c, + // Block 0x8a, offset 0x2280 + 0x2283: 0x000c, + 0x228c: 0x000c, + 0x22bc: 0x000c, + // Block 0x8b, offset 0x22c0 + 0x22f0: 0x000c, 0x22f2: 0x000c, 0x22f3: 0x000c, 0x22f4: 0x000c, + 0x22f7: 0x000c, 0x22f8: 0x000c, + 0x22fe: 0x000c, 0x22ff: 0x000c, + // Block 0x8c, offset 0x2300 + 0x2301: 0x000c, + 0x232c: 0x000c, 0x232d: 0x000c, + 0x2336: 0x000c, + // Block 0x8d, offset 0x2340 + 0x2365: 0x000c, 0x2368: 0x000c, + 0x236d: 0x000c, + // Block 0x8e, offset 0x2380 + 0x239d: 0x0001, + 0x239e: 0x000c, 0x239f: 0x0001, 0x23a0: 0x0001, 0x23a1: 0x0001, 0x23a2: 0x0001, 0x23a3: 0x0001, + 0x23a4: 0x0001, 0x23a5: 0x0001, 0x23a6: 0x0001, 0x23a7: 0x0001, 0x23a8: 0x0001, 0x23a9: 0x0003, + 0x23aa: 0x0001, 0x23ab: 0x0001, 0x23ac: 0x0001, 0x23ad: 0x0001, 0x23ae: 0x0001, 0x23af: 0x0001, + 0x23b0: 0x0001, 0x23b1: 0x0001, 0x23b2: 0x0001, 0x23b3: 0x0001, 0x23b4: 0x0001, 0x23b5: 0x0001, + 0x23b6: 0x0001, 0x23b7: 0x0001, 0x23b8: 0x0001, 0x23b9: 0x0001, 0x23ba: 0x0001, 0x23bb: 0x0001, + 0x23bc: 0x0001, 0x23bd: 0x0001, 0x23be: 0x0001, 0x23bf: 0x0001, + // Block 0x8f, offset 0x23c0 + 0x23c0: 0x0001, 0x23c1: 0x0001, 0x23c2: 0x0001, 0x23c3: 0x0001, 0x23c4: 0x0001, 0x23c5: 0x0001, + 0x23c6: 0x0001, 0x23c7: 0x0001, 0x23c8: 0x0001, 0x23c9: 0x0001, 0x23ca: 0x0001, 0x23cb: 0x0001, + 0x23cc: 0x0001, 0x23cd: 0x0001, 0x23ce: 0x0001, 0x23cf: 0x0001, 0x23d0: 0x000d, 0x23d1: 0x000d, + 0x23d2: 0x000d, 0x23d3: 0x000d, 0x23d4: 0x000d, 0x23d5: 0x000d, 0x23d6: 0x000d, 0x23d7: 0x000d, + 0x23d8: 0x000d, 0x23d9: 0x000d, 0x23da: 0x000d, 0x23db: 0x000d, 0x23dc: 0x000d, 0x23dd: 0x000d, + 0x23de: 0x000d, 0x23df: 0x000d, 0x23e0: 0x000d, 0x23e1: 0x000d, 0x23e2: 0x000d, 0x23e3: 0x000d, + 0x23e4: 0x000d, 0x23e5: 0x000d, 0x23e6: 0x000d, 0x23e7: 0x000d, 0x23e8: 0x000d, 0x23e9: 0x000d, + 0x23ea: 0x000d, 0x23eb: 0x000d, 0x23ec: 0x000d, 0x23ed: 0x000d, 0x23ee: 0x000d, 0x23ef: 0x000d, + 0x23f0: 0x000d, 0x23f1: 0x000d, 0x23f2: 0x000d, 0x23f3: 0x000d, 0x23f4: 0x000d, 0x23f5: 0x000d, + 0x23f6: 0x000d, 0x23f7: 0x000d, 0x23f8: 0x000d, 0x23f9: 0x000d, 0x23fa: 0x000d, 0x23fb: 0x000d, + 0x23fc: 0x000d, 0x23fd: 0x000d, 0x23fe: 0x000d, 0x23ff: 0x000d, + // Block 0x90, offset 0x2400 + 0x2400: 0x000d, 0x2401: 0x000d, 0x2402: 0x000d, 0x2403: 0x000d, 0x2404: 0x000d, 0x2405: 0x000d, + 0x2406: 0x000d, 0x2407: 0x000d, 0x2408: 0x000d, 0x2409: 0x000d, 0x240a: 0x000d, 0x240b: 0x000d, + 0x240c: 0x000d, 0x240d: 0x000d, 0x240e: 0x000d, 0x240f: 0x000d, 0x2410: 0x000d, 0x2411: 0x000d, + 0x2412: 0x000d, 0x2413: 0x000d, 0x2414: 0x000d, 0x2415: 0x000d, 0x2416: 0x000d, 0x2417: 0x000d, + 0x2418: 0x000d, 0x2419: 0x000d, 0x241a: 0x000d, 0x241b: 0x000d, 0x241c: 0x000d, 0x241d: 0x000d, + 0x241e: 0x000d, 0x241f: 0x000d, 0x2420: 0x000d, 0x2421: 0x000d, 0x2422: 0x000d, 0x2423: 0x000d, + 0x2424: 0x000d, 0x2425: 0x000d, 0x2426: 0x000d, 0x2427: 0x000d, 0x2428: 0x000d, 0x2429: 0x000d, + 0x242a: 0x000d, 0x242b: 0x000d, 0x242c: 0x000d, 0x242d: 0x000d, 0x242e: 0x000d, 0x242f: 0x000d, + 0x2430: 0x000d, 0x2431: 0x000d, 0x2432: 0x000d, 0x2433: 0x000d, 0x2434: 0x000d, 0x2435: 0x000d, + 0x2436: 0x000d, 0x2437: 0x000d, 0x2438: 0x000d, 0x2439: 0x000d, 0x243a: 0x000d, 0x243b: 0x000d, + 0x243c: 0x000d, 0x243d: 0x000d, 0x243e: 0x000a, 0x243f: 0x000a, + // Block 0x91, offset 0x2440 + 0x2440: 0x000d, 0x2441: 0x000d, 0x2442: 0x000d, 0x2443: 0x000d, 0x2444: 0x000d, 0x2445: 0x000d, + 0x2446: 0x000d, 0x2447: 0x000d, 0x2448: 0x000d, 0x2449: 0x000d, 0x244a: 0x000d, 0x244b: 0x000d, + 0x244c: 0x000d, 0x244d: 0x000d, 0x244e: 0x000d, 0x244f: 0x000d, 0x2450: 0x000b, 0x2451: 0x000b, + 0x2452: 0x000b, 0x2453: 0x000b, 0x2454: 0x000b, 0x2455: 0x000b, 0x2456: 0x000b, 0x2457: 0x000b, + 0x2458: 0x000b, 0x2459: 0x000b, 0x245a: 0x000b, 0x245b: 0x000b, 0x245c: 0x000b, 0x245d: 0x000b, + 0x245e: 0x000b, 0x245f: 0x000b, 0x2460: 0x000b, 0x2461: 0x000b, 0x2462: 0x000b, 0x2463: 0x000b, + 0x2464: 0x000b, 0x2465: 0x000b, 0x2466: 0x000b, 0x2467: 0x000b, 0x2468: 0x000b, 0x2469: 0x000b, + 0x246a: 0x000b, 0x246b: 0x000b, 0x246c: 0x000b, 0x246d: 0x000b, 0x246e: 0x000b, 0x246f: 0x000b, + 0x2470: 0x000d, 0x2471: 0x000d, 0x2472: 0x000d, 0x2473: 0x000d, 0x2474: 0x000d, 0x2475: 0x000d, + 0x2476: 0x000d, 0x2477: 0x000d, 0x2478: 0x000d, 0x2479: 0x000d, 0x247a: 0x000d, 0x247b: 0x000d, + 0x247c: 0x000d, 0x247d: 0x000a, 0x247e: 0x000d, 0x247f: 0x000d, + // Block 0x92, offset 0x2480 + 0x2480: 0x000c, 0x2481: 0x000c, 0x2482: 0x000c, 0x2483: 0x000c, 0x2484: 0x000c, 0x2485: 0x000c, + 0x2486: 0x000c, 0x2487: 0x000c, 0x2488: 0x000c, 0x2489: 0x000c, 0x248a: 0x000c, 0x248b: 0x000c, + 0x248c: 0x000c, 0x248d: 0x000c, 0x248e: 0x000c, 0x248f: 0x000c, 0x2490: 0x000a, 0x2491: 0x000a, + 0x2492: 0x000a, 0x2493: 0x000a, 0x2494: 0x000a, 0x2495: 0x000a, 0x2496: 0x000a, 0x2497: 0x000a, + 0x2498: 0x000a, 0x2499: 0x000a, + 0x24a0: 0x000c, 0x24a1: 0x000c, 0x24a2: 0x000c, 0x24a3: 0x000c, + 0x24a4: 0x000c, 0x24a5: 0x000c, 0x24a6: 0x000c, 0x24a7: 0x000c, 0x24a8: 0x000c, 0x24a9: 0x000c, + 0x24aa: 0x000c, 0x24ab: 0x000c, 0x24ac: 0x000c, 0x24ad: 0x000c, 0x24ae: 0x000c, 0x24af: 0x000c, + 0x24b0: 0x000a, 0x24b1: 0x000a, 0x24b2: 0x000a, 0x24b3: 0x000a, 0x24b4: 0x000a, 0x24b5: 0x000a, + 0x24b6: 0x000a, 0x24b7: 0x000a, 0x24b8: 0x000a, 0x24b9: 0x000a, 0x24ba: 0x000a, 0x24bb: 0x000a, + 0x24bc: 0x000a, 0x24bd: 0x000a, 0x24be: 0x000a, 0x24bf: 0x000a, + // Block 0x93, offset 0x24c0 + 0x24c0: 0x000a, 0x24c1: 0x000a, 0x24c2: 0x000a, 0x24c3: 0x000a, 0x24c4: 0x000a, 0x24c5: 0x000a, + 0x24c6: 0x000a, 0x24c7: 0x000a, 0x24c8: 0x000a, 0x24c9: 0x000a, 0x24ca: 0x000a, 0x24cb: 0x000a, + 0x24cc: 0x000a, 0x24cd: 0x000a, 0x24ce: 0x000a, 0x24cf: 0x000a, 0x24d0: 0x0006, 0x24d1: 0x000a, + 0x24d2: 0x0006, 0x24d4: 0x000a, 0x24d5: 0x0006, 0x24d6: 0x000a, 0x24d7: 0x000a, + 0x24d8: 0x000a, 0x24d9: 0x009a, 0x24da: 0x008a, 0x24db: 0x007a, 0x24dc: 0x006a, 0x24dd: 0x009a, + 0x24de: 0x008a, 0x24df: 0x0004, 0x24e0: 0x000a, 0x24e1: 0x000a, 0x24e2: 0x0003, 0x24e3: 0x0003, + 0x24e4: 0x000a, 0x24e5: 0x000a, 0x24e6: 0x000a, 0x24e8: 0x000a, 0x24e9: 0x0004, + 0x24ea: 0x0004, 0x24eb: 0x000a, + 0x24f0: 0x000d, 0x24f1: 0x000d, 0x24f2: 0x000d, 0x24f3: 0x000d, 0x24f4: 0x000d, 0x24f5: 0x000d, + 0x24f6: 0x000d, 0x24f7: 0x000d, 0x24f8: 0x000d, 0x24f9: 0x000d, 0x24fa: 0x000d, 0x24fb: 0x000d, + 0x24fc: 0x000d, 0x24fd: 0x000d, 0x24fe: 0x000d, 0x24ff: 0x000d, + // Block 0x94, offset 0x2500 + 0x2500: 0x000d, 0x2501: 0x000d, 0x2502: 0x000d, 0x2503: 0x000d, 0x2504: 0x000d, 0x2505: 0x000d, + 0x2506: 0x000d, 0x2507: 0x000d, 0x2508: 0x000d, 0x2509: 0x000d, 0x250a: 0x000d, 0x250b: 0x000d, + 0x250c: 0x000d, 0x250d: 0x000d, 0x250e: 0x000d, 0x250f: 0x000d, 0x2510: 0x000d, 0x2511: 0x000d, + 0x2512: 0x000d, 0x2513: 0x000d, 0x2514: 0x000d, 0x2515: 0x000d, 0x2516: 0x000d, 0x2517: 0x000d, + 0x2518: 0x000d, 0x2519: 0x000d, 0x251a: 0x000d, 0x251b: 0x000d, 0x251c: 0x000d, 0x251d: 0x000d, + 0x251e: 0x000d, 0x251f: 0x000d, 0x2520: 0x000d, 0x2521: 0x000d, 0x2522: 0x000d, 0x2523: 0x000d, + 0x2524: 0x000d, 0x2525: 0x000d, 0x2526: 0x000d, 0x2527: 0x000d, 0x2528: 0x000d, 0x2529: 0x000d, + 0x252a: 0x000d, 0x252b: 0x000d, 0x252c: 0x000d, 0x252d: 0x000d, 0x252e: 0x000d, 0x252f: 0x000d, + 0x2530: 0x000d, 0x2531: 0x000d, 0x2532: 0x000d, 0x2533: 0x000d, 0x2534: 0x000d, 0x2535: 0x000d, + 0x2536: 0x000d, 0x2537: 0x000d, 0x2538: 0x000d, 0x2539: 0x000d, 0x253a: 0x000d, 0x253b: 0x000d, + 0x253c: 0x000d, 0x253d: 0x000d, 0x253e: 0x000d, 0x253f: 0x000b, + // Block 0x95, offset 0x2540 + 0x2541: 0x000a, 0x2542: 0x000a, 0x2543: 0x0004, 0x2544: 0x0004, 0x2545: 0x0004, + 0x2546: 0x000a, 0x2547: 0x000a, 0x2548: 0x003a, 0x2549: 0x002a, 0x254a: 0x000a, 0x254b: 0x0003, + 0x254c: 0x0006, 0x254d: 0x0003, 0x254e: 0x0006, 0x254f: 0x0006, 0x2550: 0x0002, 0x2551: 0x0002, + 0x2552: 0x0002, 0x2553: 0x0002, 0x2554: 0x0002, 0x2555: 0x0002, 0x2556: 0x0002, 0x2557: 0x0002, + 0x2558: 0x0002, 0x2559: 0x0002, 0x255a: 0x0006, 0x255b: 0x000a, 0x255c: 0x000a, 0x255d: 0x000a, + 0x255e: 0x000a, 0x255f: 0x000a, 0x2560: 0x000a, + 0x257b: 0x005a, + 0x257c: 0x000a, 0x257d: 0x004a, 0x257e: 0x000a, 0x257f: 0x000a, + // Block 0x96, offset 0x2580 + 0x2580: 0x000a, + 0x259b: 0x005a, 0x259c: 0x000a, 0x259d: 0x004a, + 0x259e: 0x000a, 0x259f: 0x00fa, 0x25a0: 0x00ea, 0x25a1: 0x000a, 0x25a2: 0x003a, 0x25a3: 0x002a, + 0x25a4: 0x000a, 0x25a5: 0x000a, + // Block 0x97, offset 0x25c0 + 0x25e0: 0x0004, 0x25e1: 0x0004, 0x25e2: 0x000a, 0x25e3: 0x000a, + 0x25e4: 0x000a, 0x25e5: 0x0004, 0x25e6: 0x0004, 0x25e8: 0x000a, 0x25e9: 0x000a, + 0x25ea: 0x000a, 0x25eb: 0x000a, 0x25ec: 0x000a, 0x25ed: 0x000a, 0x25ee: 0x000a, + 0x25f0: 0x000b, 0x25f1: 0x000b, 0x25f2: 0x000b, 0x25f3: 0x000b, 0x25f4: 0x000b, 0x25f5: 0x000b, + 0x25f6: 0x000b, 0x25f7: 0x000b, 0x25f8: 0x000b, 0x25f9: 0x000a, 0x25fa: 0x000a, 0x25fb: 0x000a, + 0x25fc: 0x000a, 0x25fd: 0x000a, 0x25fe: 0x000b, 0x25ff: 0x000b, + // Block 0x98, offset 0x2600 + 0x2601: 0x000a, + // Block 0x99, offset 0x2640 + 0x2640: 0x000a, 0x2641: 0x000a, 0x2642: 0x000a, 0x2643: 0x000a, 0x2644: 0x000a, 0x2645: 0x000a, + 0x2646: 0x000a, 0x2647: 0x000a, 0x2648: 0x000a, 0x2649: 0x000a, 0x264a: 0x000a, 0x264b: 0x000a, + 0x264c: 0x000a, 0x2650: 0x000a, 0x2651: 0x000a, + 0x2652: 0x000a, 0x2653: 0x000a, 0x2654: 0x000a, 0x2655: 0x000a, 0x2656: 0x000a, 0x2657: 0x000a, + 0x2658: 0x000a, 0x2659: 0x000a, 0x265a: 0x000a, 0x265b: 0x000a, + 0x2660: 0x000a, + // Block 0x9a, offset 0x2680 + 0x26bd: 0x000c, + // Block 0x9b, offset 0x26c0 + 0x26e0: 0x000c, 0x26e1: 0x0002, 0x26e2: 0x0002, 0x26e3: 0x0002, + 0x26e4: 0x0002, 0x26e5: 0x0002, 0x26e6: 0x0002, 0x26e7: 0x0002, 0x26e8: 0x0002, 0x26e9: 0x0002, + 0x26ea: 0x0002, 0x26eb: 0x0002, 0x26ec: 0x0002, 0x26ed: 0x0002, 0x26ee: 0x0002, 0x26ef: 0x0002, + 0x26f0: 0x0002, 0x26f1: 0x0002, 0x26f2: 0x0002, 0x26f3: 0x0002, 0x26f4: 0x0002, 0x26f5: 0x0002, + 0x26f6: 0x0002, 0x26f7: 0x0002, 0x26f8: 0x0002, 0x26f9: 0x0002, 0x26fa: 0x0002, 0x26fb: 0x0002, + // Block 0x9c, offset 0x2700 + 0x2736: 0x000c, 0x2737: 0x000c, 0x2738: 0x000c, 0x2739: 0x000c, 0x273a: 0x000c, + // Block 0x9d, offset 0x2740 + 0x2740: 0x0001, 0x2741: 0x0001, 0x2742: 0x0001, 0x2743: 0x0001, 0x2744: 0x0001, 0x2745: 0x0001, + 0x2746: 0x0001, 0x2747: 0x0001, 0x2748: 0x0001, 0x2749: 0x0001, 0x274a: 0x0001, 0x274b: 0x0001, + 0x274c: 0x0001, 0x274d: 0x0001, 0x274e: 0x0001, 0x274f: 0x0001, 0x2750: 0x0001, 0x2751: 0x0001, + 0x2752: 0x0001, 0x2753: 0x0001, 0x2754: 0x0001, 0x2755: 0x0001, 0x2756: 0x0001, 0x2757: 0x0001, + 0x2758: 0x0001, 0x2759: 0x0001, 0x275a: 0x0001, 0x275b: 0x0001, 0x275c: 0x0001, 0x275d: 0x0001, + 0x275e: 0x0001, 0x275f: 0x0001, 0x2760: 0x0001, 0x2761: 0x0001, 0x2762: 0x0001, 0x2763: 0x0001, + 0x2764: 0x0001, 0x2765: 0x0001, 0x2766: 0x0001, 0x2767: 0x0001, 0x2768: 0x0001, 0x2769: 0x0001, + 0x276a: 0x0001, 0x276b: 0x0001, 0x276c: 0x0001, 0x276d: 0x0001, 0x276e: 0x0001, 0x276f: 0x0001, + 0x2770: 0x0001, 0x2771: 0x0001, 0x2772: 0x0001, 0x2773: 0x0001, 0x2774: 0x0001, 0x2775: 0x0001, + 0x2776: 0x0001, 0x2777: 0x0001, 0x2778: 0x0001, 0x2779: 0x0001, 0x277a: 0x0001, 0x277b: 0x0001, + 0x277c: 0x0001, 0x277d: 0x0001, 0x277e: 0x0001, 0x277f: 0x0001, + // Block 0x9e, offset 0x2780 + 0x2780: 0x0001, 0x2781: 0x0001, 0x2782: 0x0001, 0x2783: 0x0001, 0x2784: 0x0001, 0x2785: 0x0001, + 0x2786: 0x0001, 0x2787: 0x0001, 0x2788: 0x0001, 0x2789: 0x0001, 0x278a: 0x0001, 0x278b: 0x0001, + 0x278c: 0x0001, 0x278d: 0x0001, 0x278e: 0x0001, 0x278f: 0x0001, 0x2790: 0x0001, 0x2791: 0x0001, + 0x2792: 0x0001, 0x2793: 0x0001, 0x2794: 0x0001, 0x2795: 0x0001, 0x2796: 0x0001, 0x2797: 0x0001, + 0x2798: 0x0001, 0x2799: 0x0001, 0x279a: 0x0001, 0x279b: 0x0001, 0x279c: 0x0001, 0x279d: 0x0001, + 0x279e: 0x0001, 0x279f: 0x000a, 0x27a0: 0x0001, 0x27a1: 0x0001, 0x27a2: 0x0001, 0x27a3: 0x0001, + 0x27a4: 0x0001, 0x27a5: 0x0001, 0x27a6: 0x0001, 0x27a7: 0x0001, 0x27a8: 0x0001, 0x27a9: 0x0001, + 0x27aa: 0x0001, 0x27ab: 0x0001, 0x27ac: 0x0001, 0x27ad: 0x0001, 0x27ae: 0x0001, 0x27af: 0x0001, + 0x27b0: 0x0001, 0x27b1: 0x0001, 0x27b2: 0x0001, 0x27b3: 0x0001, 0x27b4: 0x0001, 0x27b5: 0x0001, + 0x27b6: 0x0001, 0x27b7: 0x0001, 0x27b8: 0x0001, 0x27b9: 0x0001, 0x27ba: 0x0001, 0x27bb: 0x0001, + 0x27bc: 0x0001, 0x27bd: 0x0001, 0x27be: 0x0001, 0x27bf: 0x0001, + // Block 0x9f, offset 0x27c0 + 0x27c0: 0x0001, 0x27c1: 0x000c, 0x27c2: 0x000c, 0x27c3: 0x000c, 0x27c4: 0x0001, 0x27c5: 0x000c, + 0x27c6: 0x000c, 0x27c7: 0x0001, 0x27c8: 0x0001, 0x27c9: 0x0001, 0x27ca: 0x0001, 0x27cb: 0x0001, + 0x27cc: 0x000c, 0x27cd: 0x000c, 0x27ce: 0x000c, 0x27cf: 0x000c, 0x27d0: 0x0001, 0x27d1: 0x0001, + 0x27d2: 0x0001, 0x27d3: 0x0001, 0x27d4: 0x0001, 0x27d5: 0x0001, 0x27d6: 0x0001, 0x27d7: 0x0001, + 0x27d8: 0x0001, 0x27d9: 0x0001, 0x27da: 0x0001, 0x27db: 0x0001, 0x27dc: 0x0001, 0x27dd: 0x0001, + 0x27de: 0x0001, 0x27df: 0x0001, 0x27e0: 0x0001, 0x27e1: 0x0001, 0x27e2: 0x0001, 0x27e3: 0x0001, + 0x27e4: 0x0001, 0x27e5: 0x0001, 0x27e6: 0x0001, 0x27e7: 0x0001, 0x27e8: 0x0001, 0x27e9: 0x0001, + 0x27ea: 0x0001, 0x27eb: 0x0001, 0x27ec: 0x0001, 0x27ed: 0x0001, 0x27ee: 0x0001, 0x27ef: 0x0001, + 0x27f0: 0x0001, 0x27f1: 0x0001, 0x27f2: 0x0001, 0x27f3: 0x0001, 0x27f4: 0x0001, 0x27f5: 0x0001, + 0x27f6: 0x0001, 0x27f7: 0x0001, 0x27f8: 0x000c, 0x27f9: 0x000c, 0x27fa: 0x000c, 0x27fb: 0x0001, + 0x27fc: 0x0001, 0x27fd: 0x0001, 0x27fe: 0x0001, 0x27ff: 0x000c, + // Block 0xa0, offset 0x2800 + 0x2800: 0x0001, 0x2801: 0x0001, 0x2802: 0x0001, 0x2803: 0x0001, 0x2804: 0x0001, 0x2805: 0x0001, + 0x2806: 0x0001, 0x2807: 0x0001, 0x2808: 0x0001, 0x2809: 0x0001, 0x280a: 0x0001, 0x280b: 0x0001, + 0x280c: 0x0001, 0x280d: 0x0001, 0x280e: 0x0001, 0x280f: 0x0001, 0x2810: 0x0001, 0x2811: 0x0001, + 0x2812: 0x0001, 0x2813: 0x0001, 0x2814: 0x0001, 0x2815: 0x0001, 0x2816: 0x0001, 0x2817: 0x0001, + 0x2818: 0x0001, 0x2819: 0x0001, 0x281a: 0x0001, 0x281b: 0x0001, 0x281c: 0x0001, 0x281d: 0x0001, + 0x281e: 0x0001, 0x281f: 0x0001, 0x2820: 0x0001, 0x2821: 0x0001, 0x2822: 0x0001, 0x2823: 0x0001, + 0x2824: 0x0001, 0x2825: 0x000c, 0x2826: 0x000c, 0x2827: 0x0001, 0x2828: 0x0001, 0x2829: 0x0001, + 0x282a: 0x0001, 0x282b: 0x0001, 0x282c: 0x0001, 0x282d: 0x0001, 0x282e: 0x0001, 0x282f: 0x0001, + 0x2830: 0x0001, 0x2831: 0x0001, 0x2832: 0x0001, 0x2833: 0x0001, 0x2834: 0x0001, 0x2835: 0x0001, + 0x2836: 0x0001, 0x2837: 0x0001, 0x2838: 0x0001, 0x2839: 0x0001, 0x283a: 0x0001, 0x283b: 0x0001, + 0x283c: 0x0001, 0x283d: 0x0001, 0x283e: 0x0001, 0x283f: 0x0001, + // Block 0xa1, offset 0x2840 + 0x2840: 0x0001, 0x2841: 0x0001, 0x2842: 0x0001, 0x2843: 0x0001, 0x2844: 0x0001, 0x2845: 0x0001, + 0x2846: 0x0001, 0x2847: 0x0001, 0x2848: 0x0001, 0x2849: 0x0001, 0x284a: 0x0001, 0x284b: 0x0001, + 0x284c: 0x0001, 0x284d: 0x0001, 0x284e: 0x0001, 0x284f: 0x0001, 0x2850: 0x0001, 0x2851: 0x0001, + 0x2852: 0x0001, 0x2853: 0x0001, 0x2854: 0x0001, 0x2855: 0x0001, 0x2856: 0x0001, 0x2857: 0x0001, + 0x2858: 0x0001, 0x2859: 0x0001, 0x285a: 0x0001, 0x285b: 0x0001, 0x285c: 0x0001, 0x285d: 0x0001, + 0x285e: 0x0001, 0x285f: 0x0001, 0x2860: 0x0001, 0x2861: 0x0001, 0x2862: 0x0001, 0x2863: 0x0001, + 0x2864: 0x0001, 0x2865: 0x0001, 0x2866: 0x0001, 0x2867: 0x0001, 0x2868: 0x0001, 0x2869: 0x0001, + 0x286a: 0x0001, 0x286b: 0x0001, 0x286c: 0x0001, 0x286d: 0x0001, 0x286e: 0x0001, 0x286f: 0x0001, + 0x2870: 0x0001, 0x2871: 0x0001, 0x2872: 0x0001, 0x2873: 0x0001, 0x2874: 0x0001, 0x2875: 0x0001, + 0x2876: 0x0001, 0x2877: 0x0001, 0x2878: 0x0001, 0x2879: 0x000a, 0x287a: 0x000a, 0x287b: 0x000a, + 0x287c: 0x000a, 0x287d: 0x000a, 0x287e: 0x000a, 0x287f: 0x000a, + // Block 0xa2, offset 0x2880 + 0x2880: 0x0001, 0x2881: 0x0001, 0x2882: 0x0001, 0x2883: 0x0001, 0x2884: 0x0001, 0x2885: 0x0001, + 0x2886: 0x0001, 0x2887: 0x0001, 0x2888: 0x0001, 0x2889: 0x0001, 0x288a: 0x0001, 0x288b: 0x0001, + 0x288c: 0x0001, 0x288d: 0x0001, 0x288e: 0x0001, 0x288f: 0x0001, 0x2890: 0x0001, 0x2891: 0x0001, + 0x2892: 0x0001, 0x2893: 0x0001, 0x2894: 0x0001, 0x2895: 0x0001, 0x2896: 0x0001, 0x2897: 0x0001, + 0x2898: 0x0001, 0x2899: 0x0001, 0x289a: 0x0001, 0x289b: 0x0001, 0x289c: 0x0001, 0x289d: 0x0001, + 0x289e: 0x0001, 0x289f: 0x0001, 0x28a0: 0x0005, 0x28a1: 0x0005, 0x28a2: 0x0005, 0x28a3: 0x0005, + 0x28a4: 0x0005, 0x28a5: 0x0005, 0x28a6: 0x0005, 0x28a7: 0x0005, 0x28a8: 0x0005, 0x28a9: 0x0005, + 0x28aa: 0x0005, 0x28ab: 0x0005, 0x28ac: 0x0005, 0x28ad: 0x0005, 0x28ae: 0x0005, 0x28af: 0x0005, + 0x28b0: 0x0005, 0x28b1: 0x0005, 0x28b2: 0x0005, 0x28b3: 0x0005, 0x28b4: 0x0005, 0x28b5: 0x0005, + 0x28b6: 0x0005, 0x28b7: 0x0005, 0x28b8: 0x0005, 0x28b9: 0x0005, 0x28ba: 0x0005, 0x28bb: 0x0005, + 0x28bc: 0x0005, 0x28bd: 0x0005, 0x28be: 0x0005, 0x28bf: 0x0001, + // Block 0xa3, offset 0x28c0 + 0x28c1: 0x000c, + 0x28f8: 0x000c, 0x28f9: 0x000c, 0x28fa: 0x000c, 0x28fb: 0x000c, + 0x28fc: 0x000c, 0x28fd: 0x000c, 0x28fe: 0x000c, 0x28ff: 0x000c, + // Block 0xa4, offset 0x2900 + 0x2900: 0x000c, 0x2901: 0x000c, 0x2902: 0x000c, 0x2903: 0x000c, 0x2904: 0x000c, 0x2905: 0x000c, + 0x2906: 0x000c, + 0x2912: 0x000a, 0x2913: 0x000a, 0x2914: 0x000a, 0x2915: 0x000a, 0x2916: 0x000a, 0x2917: 0x000a, + 0x2918: 0x000a, 0x2919: 0x000a, 0x291a: 0x000a, 0x291b: 0x000a, 0x291c: 0x000a, 0x291d: 0x000a, + 0x291e: 0x000a, 0x291f: 0x000a, 0x2920: 0x000a, 0x2921: 0x000a, 0x2922: 0x000a, 0x2923: 0x000a, + 0x2924: 0x000a, 0x2925: 0x000a, + 0x293f: 0x000c, + // Block 0xa5, offset 0x2940 + 0x2940: 0x000c, 0x2941: 0x000c, + 0x2973: 0x000c, 0x2974: 0x000c, 0x2975: 0x000c, + 0x2976: 0x000c, 0x2979: 0x000c, 0x297a: 0x000c, + // Block 0xa6, offset 0x2980 + 0x2980: 0x000c, 0x2981: 0x000c, 0x2982: 0x000c, + 0x29a7: 0x000c, 0x29a8: 0x000c, 0x29a9: 0x000c, + 0x29aa: 0x000c, 0x29ab: 0x000c, 0x29ad: 0x000c, 0x29ae: 0x000c, 0x29af: 0x000c, + 0x29b0: 0x000c, 0x29b1: 0x000c, 0x29b2: 0x000c, 0x29b3: 0x000c, 0x29b4: 0x000c, + // Block 0xa7, offset 0x29c0 + 0x29f3: 0x000c, + // Block 0xa8, offset 0x2a00 + 0x2a00: 0x000c, 0x2a01: 0x000c, + 0x2a36: 0x000c, 0x2a37: 0x000c, 0x2a38: 0x000c, 0x2a39: 0x000c, 0x2a3a: 0x000c, 0x2a3b: 0x000c, + 0x2a3c: 0x000c, 0x2a3d: 0x000c, 0x2a3e: 0x000c, + // Block 0xa9, offset 0x2a40 + 0x2a4a: 0x000c, 0x2a4b: 0x000c, + 0x2a4c: 0x000c, + // Block 0xaa, offset 0x2a80 + 0x2aaf: 0x000c, + 0x2ab0: 0x000c, 0x2ab1: 0x000c, 0x2ab4: 0x000c, + 0x2ab6: 0x000c, 0x2ab7: 0x000c, + 0x2abe: 0x000c, + // Block 0xab, offset 0x2ac0 + 0x2adf: 0x000c, 0x2ae3: 0x000c, + 0x2ae4: 0x000c, 0x2ae5: 0x000c, 0x2ae6: 0x000c, 0x2ae7: 0x000c, 0x2ae8: 0x000c, 0x2ae9: 0x000c, + 0x2aea: 0x000c, + // Block 0xac, offset 0x2b00 + 0x2b00: 0x000c, 0x2b01: 0x000c, + 0x2b3c: 0x000c, + // Block 0xad, offset 0x2b40 + 0x2b40: 0x000c, + 0x2b66: 0x000c, 0x2b67: 0x000c, 0x2b68: 0x000c, 0x2b69: 0x000c, + 0x2b6a: 0x000c, 0x2b6b: 0x000c, 0x2b6c: 0x000c, + 0x2b70: 0x000c, 0x2b71: 0x000c, 0x2b72: 0x000c, 0x2b73: 0x000c, 0x2b74: 0x000c, + // Block 0xae, offset 0x2b80 + 0x2bb8: 0x000c, 0x2bb9: 0x000c, 0x2bba: 0x000c, 0x2bbb: 0x000c, + 0x2bbc: 0x000c, 0x2bbd: 0x000c, 0x2bbe: 0x000c, 0x2bbf: 0x000c, + // Block 0xaf, offset 0x2bc0 + 0x2bc2: 0x000c, 0x2bc3: 0x000c, 0x2bc4: 0x000c, + 0x2bc6: 0x000c, + // Block 0xb0, offset 0x2c00 + 0x2c33: 0x000c, 0x2c34: 0x000c, 0x2c35: 0x000c, + 0x2c36: 0x000c, 0x2c37: 0x000c, 0x2c38: 0x000c, 0x2c3a: 0x000c, + 0x2c3f: 0x000c, + // Block 0xb1, offset 0x2c40 + 0x2c40: 0x000c, 0x2c42: 0x000c, 0x2c43: 0x000c, + // Block 0xb2, offset 0x2c80 + 0x2cb2: 0x000c, 0x2cb3: 0x000c, 0x2cb4: 0x000c, 0x2cb5: 0x000c, + 0x2cbc: 0x000c, 0x2cbd: 0x000c, 0x2cbf: 0x000c, + // Block 0xb3, offset 0x2cc0 + 0x2cc0: 0x000c, + 0x2cdc: 0x000c, 0x2cdd: 0x000c, + // Block 0xb4, offset 0x2d00 + 0x2d33: 0x000c, 0x2d34: 0x000c, 0x2d35: 0x000c, + 0x2d36: 0x000c, 0x2d37: 0x000c, 0x2d38: 0x000c, 0x2d39: 0x000c, 0x2d3a: 0x000c, + 0x2d3d: 0x000c, 0x2d3f: 0x000c, + // Block 0xb5, offset 0x2d40 + 0x2d40: 0x000c, + 0x2d60: 0x000a, 0x2d61: 0x000a, 0x2d62: 0x000a, 0x2d63: 0x000a, + 0x2d64: 0x000a, 0x2d65: 0x000a, 0x2d66: 0x000a, 0x2d67: 0x000a, 0x2d68: 0x000a, 0x2d69: 0x000a, + 0x2d6a: 0x000a, 0x2d6b: 0x000a, 0x2d6c: 0x000a, + // Block 0xb6, offset 0x2d80 + 0x2dab: 0x000c, 0x2dad: 0x000c, + 0x2db0: 0x000c, 0x2db1: 0x000c, 0x2db2: 0x000c, 0x2db3: 0x000c, 0x2db4: 0x000c, 0x2db5: 0x000c, + 0x2db7: 0x000c, + // Block 0xb7, offset 0x2dc0 + 0x2ddd: 0x000c, + 0x2dde: 0x000c, 0x2ddf: 0x000c, 0x2de2: 0x000c, 0x2de3: 0x000c, + 0x2de4: 0x000c, 0x2de5: 0x000c, 0x2de7: 0x000c, 0x2de8: 0x000c, 0x2de9: 0x000c, + 0x2dea: 0x000c, 0x2deb: 0x000c, + // Block 0xb8, offset 0x2e00 + 0x2e30: 0x000c, 0x2e31: 0x000c, 0x2e32: 0x000c, 0x2e33: 0x000c, 0x2e34: 0x000c, 0x2e35: 0x000c, + 0x2e36: 0x000c, 0x2e38: 0x000c, 0x2e39: 0x000c, 0x2e3a: 0x000c, 0x2e3b: 0x000c, + 0x2e3c: 0x000c, 0x2e3d: 0x000c, + // Block 0xb9, offset 0x2e40 + 0x2e52: 0x000c, 0x2e53: 0x000c, 0x2e54: 0x000c, 0x2e55: 0x000c, 0x2e56: 0x000c, 0x2e57: 0x000c, + 0x2e58: 0x000c, 0x2e59: 0x000c, 0x2e5a: 0x000c, 0x2e5b: 0x000c, 0x2e5c: 0x000c, 0x2e5d: 0x000c, + 0x2e5e: 0x000c, 0x2e5f: 0x000c, 0x2e60: 0x000c, 0x2e61: 0x000c, 0x2e62: 0x000c, 0x2e63: 0x000c, + 0x2e64: 0x000c, 0x2e65: 0x000c, 0x2e66: 0x000c, 0x2e67: 0x000c, + 0x2e6a: 0x000c, 0x2e6b: 0x000c, 0x2e6c: 0x000c, 0x2e6d: 0x000c, 0x2e6e: 0x000c, 0x2e6f: 0x000c, + 0x2e70: 0x000c, 0x2e72: 0x000c, 0x2e73: 0x000c, 0x2e75: 0x000c, + 0x2e76: 0x000c, + // Block 0xba, offset 0x2e80 + 0x2eb0: 0x000c, 0x2eb1: 0x000c, 0x2eb2: 0x000c, 0x2eb3: 0x000c, 0x2eb4: 0x000c, + // Block 0xbb, offset 0x2ec0 + 0x2ef0: 0x000c, 0x2ef1: 0x000c, 0x2ef2: 0x000c, 0x2ef3: 0x000c, 0x2ef4: 0x000c, 0x2ef5: 0x000c, + 0x2ef6: 0x000c, + // Block 0xbc, offset 0x2f00 + 0x2f0f: 0x000c, 0x2f10: 0x000c, 0x2f11: 0x000c, + 0x2f12: 0x000c, + // Block 0xbd, offset 0x2f40 + 0x2f5d: 0x000c, + 0x2f5e: 0x000c, 0x2f60: 0x000b, 0x2f61: 0x000b, 0x2f62: 0x000b, 0x2f63: 0x000b, + // Block 0xbe, offset 0x2f80 + 0x2fa7: 0x000c, 0x2fa8: 0x000c, 0x2fa9: 0x000c, + 0x2fb3: 0x000b, 0x2fb4: 0x000b, 0x2fb5: 0x000b, + 0x2fb6: 0x000b, 0x2fb7: 0x000b, 0x2fb8: 0x000b, 0x2fb9: 0x000b, 0x2fba: 0x000b, 0x2fbb: 0x000c, + 0x2fbc: 0x000c, 0x2fbd: 0x000c, 0x2fbe: 0x000c, 0x2fbf: 0x000c, + // Block 0xbf, offset 0x2fc0 + 0x2fc0: 0x000c, 0x2fc1: 0x000c, 0x2fc2: 0x000c, 0x2fc5: 0x000c, + 0x2fc6: 0x000c, 0x2fc7: 0x000c, 0x2fc8: 0x000c, 0x2fc9: 0x000c, 0x2fca: 0x000c, 0x2fcb: 0x000c, + 0x2fea: 0x000c, 0x2feb: 0x000c, 0x2fec: 0x000c, 0x2fed: 0x000c, + // Block 0xc0, offset 0x3000 + 0x3000: 0x000a, 0x3001: 0x000a, 0x3002: 0x000c, 0x3003: 0x000c, 0x3004: 0x000c, 0x3005: 0x000a, + // Block 0xc1, offset 0x3040 + 0x3040: 0x000a, 0x3041: 0x000a, 0x3042: 0x000a, 0x3043: 0x000a, 0x3044: 0x000a, 0x3045: 0x000a, + 0x3046: 0x000a, 0x3047: 0x000a, 0x3048: 0x000a, 0x3049: 0x000a, 0x304a: 0x000a, 0x304b: 0x000a, + 0x304c: 0x000a, 0x304d: 0x000a, 0x304e: 0x000a, 0x304f: 0x000a, 0x3050: 0x000a, 0x3051: 0x000a, + 0x3052: 0x000a, 0x3053: 0x000a, 0x3054: 0x000a, 0x3055: 0x000a, 0x3056: 0x000a, + // Block 0xc2, offset 0x3080 + 0x309b: 0x000a, + // Block 0xc3, offset 0x30c0 + 0x30d5: 0x000a, + // Block 0xc4, offset 0x3100 + 0x310f: 0x000a, + // Block 0xc5, offset 0x3140 + 0x3149: 0x000a, + // Block 0xc6, offset 0x3180 + 0x3183: 0x000a, + 0x318e: 0x0002, 0x318f: 0x0002, 0x3190: 0x0002, 0x3191: 0x0002, + 0x3192: 0x0002, 0x3193: 0x0002, 0x3194: 0x0002, 0x3195: 0x0002, 0x3196: 0x0002, 0x3197: 0x0002, + 0x3198: 0x0002, 0x3199: 0x0002, 0x319a: 0x0002, 0x319b: 0x0002, 0x319c: 0x0002, 0x319d: 0x0002, + 0x319e: 0x0002, 0x319f: 0x0002, 0x31a0: 0x0002, 0x31a1: 0x0002, 0x31a2: 0x0002, 0x31a3: 0x0002, + 0x31a4: 0x0002, 0x31a5: 0x0002, 0x31a6: 0x0002, 0x31a7: 0x0002, 0x31a8: 0x0002, 0x31a9: 0x0002, + 0x31aa: 0x0002, 0x31ab: 0x0002, 0x31ac: 0x0002, 0x31ad: 0x0002, 0x31ae: 0x0002, 0x31af: 0x0002, + 0x31b0: 0x0002, 0x31b1: 0x0002, 0x31b2: 0x0002, 0x31b3: 0x0002, 0x31b4: 0x0002, 0x31b5: 0x0002, + 0x31b6: 0x0002, 0x31b7: 0x0002, 0x31b8: 0x0002, 0x31b9: 0x0002, 0x31ba: 0x0002, 0x31bb: 0x0002, + 0x31bc: 0x0002, 0x31bd: 0x0002, 0x31be: 0x0002, 0x31bf: 0x0002, + // Block 0xc7, offset 0x31c0 + 0x31c0: 0x000c, 0x31c1: 0x000c, 0x31c2: 0x000c, 0x31c3: 0x000c, 0x31c4: 0x000c, 0x31c5: 0x000c, + 0x31c6: 0x000c, 0x31c7: 0x000c, 0x31c8: 0x000c, 0x31c9: 0x000c, 0x31ca: 0x000c, 0x31cb: 0x000c, + 0x31cc: 0x000c, 0x31cd: 0x000c, 0x31ce: 0x000c, 0x31cf: 0x000c, 0x31d0: 0x000c, 0x31d1: 0x000c, + 0x31d2: 0x000c, 0x31d3: 0x000c, 0x31d4: 0x000c, 0x31d5: 0x000c, 0x31d6: 0x000c, 0x31d7: 0x000c, + 0x31d8: 0x000c, 0x31d9: 0x000c, 0x31da: 0x000c, 0x31db: 0x000c, 0x31dc: 0x000c, 0x31dd: 0x000c, + 0x31de: 0x000c, 0x31df: 0x000c, 0x31e0: 0x000c, 0x31e1: 0x000c, 0x31e2: 0x000c, 0x31e3: 0x000c, + 0x31e4: 0x000c, 0x31e5: 0x000c, 0x31e6: 0x000c, 0x31e7: 0x000c, 0x31e8: 0x000c, 0x31e9: 0x000c, + 0x31ea: 0x000c, 0x31eb: 0x000c, 0x31ec: 0x000c, 0x31ed: 0x000c, 0x31ee: 0x000c, 0x31ef: 0x000c, + 0x31f0: 0x000c, 0x31f1: 0x000c, 0x31f2: 0x000c, 0x31f3: 0x000c, 0x31f4: 0x000c, 0x31f5: 0x000c, + 0x31f6: 0x000c, 0x31fb: 0x000c, + 0x31fc: 0x000c, 0x31fd: 0x000c, 0x31fe: 0x000c, 0x31ff: 0x000c, + // Block 0xc8, offset 0x3200 + 0x3200: 0x000c, 0x3201: 0x000c, 0x3202: 0x000c, 0x3203: 0x000c, 0x3204: 0x000c, 0x3205: 0x000c, + 0x3206: 0x000c, 0x3207: 0x000c, 0x3208: 0x000c, 0x3209: 0x000c, 0x320a: 0x000c, 0x320b: 0x000c, + 0x320c: 0x000c, 0x320d: 0x000c, 0x320e: 0x000c, 0x320f: 0x000c, 0x3210: 0x000c, 0x3211: 0x000c, + 0x3212: 0x000c, 0x3213: 0x000c, 0x3214: 0x000c, 0x3215: 0x000c, 0x3216: 0x000c, 0x3217: 0x000c, + 0x3218: 0x000c, 0x3219: 0x000c, 0x321a: 0x000c, 0x321b: 0x000c, 0x321c: 0x000c, 0x321d: 0x000c, + 0x321e: 0x000c, 0x321f: 0x000c, 0x3220: 0x000c, 0x3221: 0x000c, 0x3222: 0x000c, 0x3223: 0x000c, + 0x3224: 0x000c, 0x3225: 0x000c, 0x3226: 0x000c, 0x3227: 0x000c, 0x3228: 0x000c, 0x3229: 0x000c, + 0x322a: 0x000c, 0x322b: 0x000c, 0x322c: 0x000c, + 0x3235: 0x000c, + // Block 0xc9, offset 0x3240 + 0x3244: 0x000c, + 0x325b: 0x000c, 0x325c: 0x000c, 0x325d: 0x000c, + 0x325e: 0x000c, 0x325f: 0x000c, 0x3261: 0x000c, 0x3262: 0x000c, 0x3263: 0x000c, + 0x3264: 0x000c, 0x3265: 0x000c, 0x3266: 0x000c, 0x3267: 0x000c, 0x3268: 0x000c, 0x3269: 0x000c, + 0x326a: 0x000c, 0x326b: 0x000c, 0x326c: 0x000c, 0x326d: 0x000c, 0x326e: 0x000c, 0x326f: 0x000c, + // Block 0xca, offset 0x3280 + 0x3280: 0x000c, 0x3281: 0x000c, 0x3282: 0x000c, 0x3283: 0x000c, 0x3284: 0x000c, 0x3285: 0x000c, + 0x3286: 0x000c, 0x3288: 0x000c, 0x3289: 0x000c, 0x328a: 0x000c, 0x328b: 0x000c, + 0x328c: 0x000c, 0x328d: 0x000c, 0x328e: 0x000c, 0x328f: 0x000c, 0x3290: 0x000c, 0x3291: 0x000c, + 0x3292: 0x000c, 0x3293: 0x000c, 0x3294: 0x000c, 0x3295: 0x000c, 0x3296: 0x000c, 0x3297: 0x000c, + 0x3298: 0x000c, 0x329b: 0x000c, 0x329c: 0x000c, 0x329d: 0x000c, + 0x329e: 0x000c, 0x329f: 0x000c, 0x32a0: 0x000c, 0x32a1: 0x000c, 0x32a3: 0x000c, + 0x32a4: 0x000c, 0x32a6: 0x000c, 0x32a7: 0x000c, 0x32a8: 0x000c, 0x32a9: 0x000c, + 0x32aa: 0x000c, + // Block 0xcb, offset 0x32c0 + 0x32c0: 0x0001, 0x32c1: 0x0001, 0x32c2: 0x0001, 0x32c3: 0x0001, 0x32c4: 0x0001, 0x32c5: 0x0001, + 0x32c6: 0x0001, 0x32c7: 0x0001, 0x32c8: 0x0001, 0x32c9: 0x0001, 0x32ca: 0x0001, 0x32cb: 0x0001, + 0x32cc: 0x0001, 0x32cd: 0x0001, 0x32ce: 0x0001, 0x32cf: 0x0001, 0x32d0: 0x000c, 0x32d1: 0x000c, + 0x32d2: 0x000c, 0x32d3: 0x000c, 0x32d4: 0x000c, 0x32d5: 0x000c, 0x32d6: 0x000c, 0x32d7: 0x0001, + 0x32d8: 0x0001, 0x32d9: 0x0001, 0x32da: 0x0001, 0x32db: 0x0001, 0x32dc: 0x0001, 0x32dd: 0x0001, + 0x32de: 0x0001, 0x32df: 0x0001, 0x32e0: 0x0001, 0x32e1: 0x0001, 0x32e2: 0x0001, 0x32e3: 0x0001, + 0x32e4: 0x0001, 0x32e5: 0x0001, 0x32e6: 0x0001, 0x32e7: 0x0001, 0x32e8: 0x0001, 0x32e9: 0x0001, + 0x32ea: 0x0001, 0x32eb: 0x0001, 0x32ec: 0x0001, 0x32ed: 0x0001, 0x32ee: 0x0001, 0x32ef: 0x0001, + 0x32f0: 0x0001, 0x32f1: 0x0001, 0x32f2: 0x0001, 0x32f3: 0x0001, 0x32f4: 0x0001, 0x32f5: 0x0001, + 0x32f6: 0x0001, 0x32f7: 0x0001, 0x32f8: 0x0001, 0x32f9: 0x0001, 0x32fa: 0x0001, 0x32fb: 0x0001, + 0x32fc: 0x0001, 0x32fd: 0x0001, 0x32fe: 0x0001, 0x32ff: 0x0001, + // Block 0xcc, offset 0x3300 + 0x3300: 0x0001, 0x3301: 0x0001, 0x3302: 0x0001, 0x3303: 0x0001, 0x3304: 0x000c, 0x3305: 0x000c, + 0x3306: 0x000c, 0x3307: 0x000c, 0x3308: 0x000c, 0x3309: 0x000c, 0x330a: 0x000c, 0x330b: 0x0001, + 0x330c: 0x0001, 0x330d: 0x0001, 0x330e: 0x0001, 0x330f: 0x0001, 0x3310: 0x0001, 0x3311: 0x0001, + 0x3312: 0x0001, 0x3313: 0x0001, 0x3314: 0x0001, 0x3315: 0x0001, 0x3316: 0x0001, 0x3317: 0x0001, + 0x3318: 0x0001, 0x3319: 0x0001, 0x331a: 0x0001, 0x331b: 0x0001, 0x331c: 0x0001, 0x331d: 0x0001, + 0x331e: 0x0001, 0x331f: 0x0001, 0x3320: 0x0001, 0x3321: 0x0001, 0x3322: 0x0001, 0x3323: 0x0001, + 0x3324: 0x0001, 0x3325: 0x0001, 0x3326: 0x0001, 0x3327: 0x0001, 0x3328: 0x0001, 0x3329: 0x0001, + 0x332a: 0x0001, 0x332b: 0x0001, 0x332c: 0x0001, 0x332d: 0x0001, 0x332e: 0x0001, 0x332f: 0x0001, + 0x3330: 0x0001, 0x3331: 0x0001, 0x3332: 0x0001, 0x3333: 0x0001, 0x3334: 0x0001, 0x3335: 0x0001, + 0x3336: 0x0001, 0x3337: 0x0001, 0x3338: 0x0001, 0x3339: 0x0001, 0x333a: 0x0001, 0x333b: 0x0001, + 0x333c: 0x0001, 0x333d: 0x0001, 0x333e: 0x0001, 0x333f: 0x0001, + // Block 0xcd, offset 0x3340 + 0x3340: 0x000d, 0x3341: 0x000d, 0x3342: 0x000d, 0x3343: 0x000d, 0x3344: 0x000d, 0x3345: 0x000d, + 0x3346: 0x000d, 0x3347: 0x000d, 0x3348: 0x000d, 0x3349: 0x000d, 0x334a: 0x000d, 0x334b: 0x000d, + 0x334c: 0x000d, 0x334d: 0x000d, 0x334e: 0x000d, 0x334f: 0x000d, 0x3350: 0x000d, 0x3351: 0x000d, + 0x3352: 0x000d, 0x3353: 0x000d, 0x3354: 0x000d, 0x3355: 0x000d, 0x3356: 0x000d, 0x3357: 0x000d, + 0x3358: 0x000d, 0x3359: 0x000d, 0x335a: 0x000d, 0x335b: 0x000d, 0x335c: 0x000d, 0x335d: 0x000d, + 0x335e: 0x000d, 0x335f: 0x000d, 0x3360: 0x000d, 0x3361: 0x000d, 0x3362: 0x000d, 0x3363: 0x000d, + 0x3364: 0x000d, 0x3365: 0x000d, 0x3366: 0x000d, 0x3367: 0x000d, 0x3368: 0x000d, 0x3369: 0x000d, + 0x336a: 0x000d, 0x336b: 0x000d, 0x336c: 0x000d, 0x336d: 0x000d, 0x336e: 0x000d, 0x336f: 0x000d, + 0x3370: 0x000a, 0x3371: 0x000a, 0x3372: 0x000d, 0x3373: 0x000d, 0x3374: 0x000d, 0x3375: 0x000d, + 0x3376: 0x000d, 0x3377: 0x000d, 0x3378: 0x000d, 0x3379: 0x000d, 0x337a: 0x000d, 0x337b: 0x000d, + 0x337c: 0x000d, 0x337d: 0x000d, 0x337e: 0x000d, 0x337f: 0x000d, + // Block 0xce, offset 0x3380 + 0x3380: 0x000a, 0x3381: 0x000a, 0x3382: 0x000a, 0x3383: 0x000a, 0x3384: 0x000a, 0x3385: 0x000a, + 0x3386: 0x000a, 0x3387: 0x000a, 0x3388: 0x000a, 0x3389: 0x000a, 0x338a: 0x000a, 0x338b: 0x000a, + 0x338c: 0x000a, 0x338d: 0x000a, 0x338e: 0x000a, 0x338f: 0x000a, 0x3390: 0x000a, 0x3391: 0x000a, + 0x3392: 0x000a, 0x3393: 0x000a, 0x3394: 0x000a, 0x3395: 0x000a, 0x3396: 0x000a, 0x3397: 0x000a, + 0x3398: 0x000a, 0x3399: 0x000a, 0x339a: 0x000a, 0x339b: 0x000a, 0x339c: 0x000a, 0x339d: 0x000a, + 0x339e: 0x000a, 0x339f: 0x000a, 0x33a0: 0x000a, 0x33a1: 0x000a, 0x33a2: 0x000a, 0x33a3: 0x000a, + 0x33a4: 0x000a, 0x33a5: 0x000a, 0x33a6: 0x000a, 0x33a7: 0x000a, 0x33a8: 0x000a, 0x33a9: 0x000a, + 0x33aa: 0x000a, 0x33ab: 0x000a, + 0x33b0: 0x000a, 0x33b1: 0x000a, 0x33b2: 0x000a, 0x33b3: 0x000a, 0x33b4: 0x000a, 0x33b5: 0x000a, + 0x33b6: 0x000a, 0x33b7: 0x000a, 0x33b8: 0x000a, 0x33b9: 0x000a, 0x33ba: 0x000a, 0x33bb: 0x000a, + 0x33bc: 0x000a, 0x33bd: 0x000a, 0x33be: 0x000a, 0x33bf: 0x000a, + // Block 0xcf, offset 0x33c0 + 0x33c0: 0x000a, 0x33c1: 0x000a, 0x33c2: 0x000a, 0x33c3: 0x000a, 0x33c4: 0x000a, 0x33c5: 0x000a, + 0x33c6: 0x000a, 0x33c7: 0x000a, 0x33c8: 0x000a, 0x33c9: 0x000a, 0x33ca: 0x000a, 0x33cb: 0x000a, + 0x33cc: 0x000a, 0x33cd: 0x000a, 0x33ce: 0x000a, 0x33cf: 0x000a, 0x33d0: 0x000a, 0x33d1: 0x000a, + 0x33d2: 0x000a, 0x33d3: 0x000a, + 0x33e0: 0x000a, 0x33e1: 0x000a, 0x33e2: 0x000a, 0x33e3: 0x000a, + 0x33e4: 0x000a, 0x33e5: 0x000a, 0x33e6: 0x000a, 0x33e7: 0x000a, 0x33e8: 0x000a, 0x33e9: 0x000a, + 0x33ea: 0x000a, 0x33eb: 0x000a, 0x33ec: 0x000a, 0x33ed: 0x000a, 0x33ee: 0x000a, + 0x33f1: 0x000a, 0x33f2: 0x000a, 0x33f3: 0x000a, 0x33f4: 0x000a, 0x33f5: 0x000a, + 0x33f6: 0x000a, 0x33f7: 0x000a, 0x33f8: 0x000a, 0x33f9: 0x000a, 0x33fa: 0x000a, 0x33fb: 0x000a, + 0x33fc: 0x000a, 0x33fd: 0x000a, 0x33fe: 0x000a, 0x33ff: 0x000a, + // Block 0xd0, offset 0x3400 + 0x3401: 0x000a, 0x3402: 0x000a, 0x3403: 0x000a, 0x3404: 0x000a, 0x3405: 0x000a, + 0x3406: 0x000a, 0x3407: 0x000a, 0x3408: 0x000a, 0x3409: 0x000a, 0x340a: 0x000a, 0x340b: 0x000a, + 0x340c: 0x000a, 0x340d: 0x000a, 0x340e: 0x000a, 0x340f: 0x000a, 0x3411: 0x000a, + 0x3412: 0x000a, 0x3413: 0x000a, 0x3414: 0x000a, 0x3415: 0x000a, 0x3416: 0x000a, 0x3417: 0x000a, + 0x3418: 0x000a, 0x3419: 0x000a, 0x341a: 0x000a, 0x341b: 0x000a, 0x341c: 0x000a, 0x341d: 0x000a, + 0x341e: 0x000a, 0x341f: 0x000a, 0x3420: 0x000a, 0x3421: 0x000a, 0x3422: 0x000a, 0x3423: 0x000a, + 0x3424: 0x000a, 0x3425: 0x000a, 0x3426: 0x000a, 0x3427: 0x000a, 0x3428: 0x000a, 0x3429: 0x000a, + 0x342a: 0x000a, 0x342b: 0x000a, 0x342c: 0x000a, 0x342d: 0x000a, 0x342e: 0x000a, 0x342f: 0x000a, + 0x3430: 0x000a, 0x3431: 0x000a, 0x3432: 0x000a, 0x3433: 0x000a, 0x3434: 0x000a, 0x3435: 0x000a, + // Block 0xd1, offset 0x3440 + 0x3440: 0x0002, 0x3441: 0x0002, 0x3442: 0x0002, 0x3443: 0x0002, 0x3444: 0x0002, 0x3445: 0x0002, + 0x3446: 0x0002, 0x3447: 0x0002, 0x3448: 0x0002, 0x3449: 0x0002, 0x344a: 0x0002, 0x344b: 0x000a, + 0x344c: 0x000a, + // Block 0xd2, offset 0x3480 + 0x34aa: 0x000a, 0x34ab: 0x000a, + // Block 0xd3, offset 0x34c0 + 0x34c0: 0x000a, 0x34c1: 0x000a, 0x34c2: 0x000a, 0x34c3: 0x000a, 0x34c4: 0x000a, 0x34c5: 0x000a, + 0x34c6: 0x000a, 0x34c7: 0x000a, 0x34c8: 0x000a, 0x34c9: 0x000a, 0x34ca: 0x000a, 0x34cb: 0x000a, + 0x34cc: 0x000a, 0x34cd: 0x000a, 0x34ce: 0x000a, 0x34cf: 0x000a, 0x34d0: 0x000a, 0x34d1: 0x000a, + 0x34d2: 0x000a, + 0x34e0: 0x000a, 0x34e1: 0x000a, 0x34e2: 0x000a, 0x34e3: 0x000a, + 0x34e4: 0x000a, 0x34e5: 0x000a, 0x34e6: 0x000a, 0x34e7: 0x000a, 0x34e8: 0x000a, 0x34e9: 0x000a, + 0x34ea: 0x000a, 0x34eb: 0x000a, 0x34ec: 0x000a, + 0x34f0: 0x000a, 0x34f1: 0x000a, 0x34f2: 0x000a, 0x34f3: 0x000a, 0x34f4: 0x000a, 0x34f5: 0x000a, + 0x34f6: 0x000a, + // Block 0xd4, offset 0x3500 + 0x3500: 0x000a, 0x3501: 0x000a, 0x3502: 0x000a, 0x3503: 0x000a, 0x3504: 0x000a, 0x3505: 0x000a, + 0x3506: 0x000a, 0x3507: 0x000a, 0x3508: 0x000a, 0x3509: 0x000a, 0x350a: 0x000a, 0x350b: 0x000a, + 0x350c: 0x000a, 0x350d: 0x000a, 0x350e: 0x000a, 0x350f: 0x000a, 0x3510: 0x000a, 0x3511: 0x000a, + 0x3512: 0x000a, 0x3513: 0x000a, 0x3514: 0x000a, + // Block 0xd5, offset 0x3540 + 0x3540: 0x000a, 0x3541: 0x000a, 0x3542: 0x000a, 0x3543: 0x000a, 0x3544: 0x000a, 0x3545: 0x000a, + 0x3546: 0x000a, 0x3547: 0x000a, 0x3548: 0x000a, 0x3549: 0x000a, 0x354a: 0x000a, 0x354b: 0x000a, + 0x3550: 0x000a, 0x3551: 0x000a, + 0x3552: 0x000a, 0x3553: 0x000a, 0x3554: 0x000a, 0x3555: 0x000a, 0x3556: 0x000a, 0x3557: 0x000a, + 0x3558: 0x000a, 0x3559: 0x000a, 0x355a: 0x000a, 0x355b: 0x000a, 0x355c: 0x000a, 0x355d: 0x000a, + 0x355e: 0x000a, 0x355f: 0x000a, 0x3560: 0x000a, 0x3561: 0x000a, 0x3562: 0x000a, 0x3563: 0x000a, + 0x3564: 0x000a, 0x3565: 0x000a, 0x3566: 0x000a, 0x3567: 0x000a, 0x3568: 0x000a, 0x3569: 0x000a, + 0x356a: 0x000a, 0x356b: 0x000a, 0x356c: 0x000a, 0x356d: 0x000a, 0x356e: 0x000a, 0x356f: 0x000a, + 0x3570: 0x000a, 0x3571: 0x000a, 0x3572: 0x000a, 0x3573: 0x000a, 0x3574: 0x000a, 0x3575: 0x000a, + 0x3576: 0x000a, 0x3577: 0x000a, 0x3578: 0x000a, 0x3579: 0x000a, 0x357a: 0x000a, 0x357b: 0x000a, + 0x357c: 0x000a, 0x357d: 0x000a, 0x357e: 0x000a, 0x357f: 0x000a, + // Block 0xd6, offset 0x3580 + 0x3580: 0x000a, 0x3581: 0x000a, 0x3582: 0x000a, 0x3583: 0x000a, 0x3584: 0x000a, 0x3585: 0x000a, + 0x3586: 0x000a, 0x3587: 0x000a, + 0x3590: 0x000a, 0x3591: 0x000a, + 0x3592: 0x000a, 0x3593: 0x000a, 0x3594: 0x000a, 0x3595: 0x000a, 0x3596: 0x000a, 0x3597: 0x000a, + 0x3598: 0x000a, 0x3599: 0x000a, + 0x35a0: 0x000a, 0x35a1: 0x000a, 0x35a2: 0x000a, 0x35a3: 0x000a, + 0x35a4: 0x000a, 0x35a5: 0x000a, 0x35a6: 0x000a, 0x35a7: 0x000a, 0x35a8: 0x000a, 0x35a9: 0x000a, + 0x35aa: 0x000a, 0x35ab: 0x000a, 0x35ac: 0x000a, 0x35ad: 0x000a, 0x35ae: 0x000a, 0x35af: 0x000a, + 0x35b0: 0x000a, 0x35b1: 0x000a, 0x35b2: 0x000a, 0x35b3: 0x000a, 0x35b4: 0x000a, 0x35b5: 0x000a, + 0x35b6: 0x000a, 0x35b7: 0x000a, 0x35b8: 0x000a, 0x35b9: 0x000a, 0x35ba: 0x000a, 0x35bb: 0x000a, + 0x35bc: 0x000a, 0x35bd: 0x000a, 0x35be: 0x000a, 0x35bf: 0x000a, + // Block 0xd7, offset 0x35c0 + 0x35c0: 0x000a, 0x35c1: 0x000a, 0x35c2: 0x000a, 0x35c3: 0x000a, 0x35c4: 0x000a, 0x35c5: 0x000a, + 0x35c6: 0x000a, 0x35c7: 0x000a, + 0x35d0: 0x000a, 0x35d1: 0x000a, + 0x35d2: 0x000a, 0x35d3: 0x000a, 0x35d4: 0x000a, 0x35d5: 0x000a, 0x35d6: 0x000a, 0x35d7: 0x000a, + 0x35d8: 0x000a, 0x35d9: 0x000a, 0x35da: 0x000a, 0x35db: 0x000a, 0x35dc: 0x000a, 0x35dd: 0x000a, + 0x35de: 0x000a, 0x35df: 0x000a, 0x35e0: 0x000a, 0x35e1: 0x000a, 0x35e2: 0x000a, 0x35e3: 0x000a, + 0x35e4: 0x000a, 0x35e5: 0x000a, 0x35e6: 0x000a, 0x35e7: 0x000a, 0x35e8: 0x000a, 0x35e9: 0x000a, + 0x35ea: 0x000a, 0x35eb: 0x000a, 0x35ec: 0x000a, 0x35ed: 0x000a, + // Block 0xd8, offset 0x3600 + 0x3610: 0x000a, 0x3611: 0x000a, + 0x3612: 0x000a, 0x3613: 0x000a, 0x3614: 0x000a, 0x3615: 0x000a, 0x3616: 0x000a, 0x3617: 0x000a, + 0x3618: 0x000a, 0x3619: 0x000a, 0x361a: 0x000a, 0x361b: 0x000a, 0x361c: 0x000a, 0x361d: 0x000a, + 0x361e: 0x000a, 0x3620: 0x000a, 0x3621: 0x000a, 0x3622: 0x000a, 0x3623: 0x000a, + 0x3624: 0x000a, 0x3625: 0x000a, 0x3626: 0x000a, 0x3627: 0x000a, + 0x3630: 0x000a, 0x3633: 0x000a, 0x3634: 0x000a, 0x3635: 0x000a, + 0x3636: 0x000a, 0x3637: 0x000a, 0x3638: 0x000a, 0x3639: 0x000a, 0x363a: 0x000a, 0x363b: 0x000a, + 0x363c: 0x000a, 0x363d: 0x000a, 0x363e: 0x000a, + // Block 0xd9, offset 0x3640 + 0x3640: 0x000a, 0x3641: 0x000a, 0x3642: 0x000a, 0x3643: 0x000a, 0x3644: 0x000a, 0x3645: 0x000a, + 0x3646: 0x000a, 0x3647: 0x000a, 0x3648: 0x000a, 0x3649: 0x000a, 0x364a: 0x000a, 0x364b: 0x000a, + 0x3650: 0x000a, 0x3651: 0x000a, + 0x3652: 0x000a, 0x3653: 0x000a, 0x3654: 0x000a, 0x3655: 0x000a, 0x3656: 0x000a, 0x3657: 0x000a, + 0x3658: 0x000a, 0x3659: 0x000a, 0x365a: 0x000a, 0x365b: 0x000a, 0x365c: 0x000a, 0x365d: 0x000a, + 0x365e: 0x000a, + // Block 0xda, offset 0x3680 + 0x3680: 0x000a, 0x3681: 0x000a, 0x3682: 0x000a, 0x3683: 0x000a, 0x3684: 0x000a, 0x3685: 0x000a, + 0x3686: 0x000a, 0x3687: 0x000a, 0x3688: 0x000a, 0x3689: 0x000a, 0x368a: 0x000a, 0x368b: 0x000a, + 0x368c: 0x000a, 0x368d: 0x000a, 0x368e: 0x000a, 0x368f: 0x000a, 0x3690: 0x000a, 0x3691: 0x000a, + // Block 0xdb, offset 0x36c0 + 0x36fe: 0x000b, 0x36ff: 0x000b, + // Block 0xdc, offset 0x3700 + 0x3700: 0x000b, 0x3701: 0x000b, 0x3702: 0x000b, 0x3703: 0x000b, 0x3704: 0x000b, 0x3705: 0x000b, + 0x3706: 0x000b, 0x3707: 0x000b, 0x3708: 0x000b, 0x3709: 0x000b, 0x370a: 0x000b, 0x370b: 0x000b, + 0x370c: 0x000b, 0x370d: 0x000b, 0x370e: 0x000b, 0x370f: 0x000b, 0x3710: 0x000b, 0x3711: 0x000b, + 0x3712: 0x000b, 0x3713: 0x000b, 0x3714: 0x000b, 0x3715: 0x000b, 0x3716: 0x000b, 0x3717: 0x000b, + 0x3718: 0x000b, 0x3719: 0x000b, 0x371a: 0x000b, 0x371b: 0x000b, 0x371c: 0x000b, 0x371d: 0x000b, + 0x371e: 0x000b, 0x371f: 0x000b, 0x3720: 0x000b, 0x3721: 0x000b, 0x3722: 0x000b, 0x3723: 0x000b, + 0x3724: 0x000b, 0x3725: 0x000b, 0x3726: 0x000b, 0x3727: 0x000b, 0x3728: 0x000b, 0x3729: 0x000b, + 0x372a: 0x000b, 0x372b: 0x000b, 0x372c: 0x000b, 0x372d: 0x000b, 0x372e: 0x000b, 0x372f: 0x000b, + 0x3730: 0x000b, 0x3731: 0x000b, 0x3732: 0x000b, 0x3733: 0x000b, 0x3734: 0x000b, 0x3735: 0x000b, + 0x3736: 0x000b, 0x3737: 0x000b, 0x3738: 0x000b, 0x3739: 0x000b, 0x373a: 0x000b, 0x373b: 0x000b, + 0x373c: 0x000b, 0x373d: 0x000b, 0x373e: 0x000b, 0x373f: 0x000b, + // Block 0xdd, offset 0x3740 + 0x3740: 0x000c, 0x3741: 0x000c, 0x3742: 0x000c, 0x3743: 0x000c, 0x3744: 0x000c, 0x3745: 0x000c, + 0x3746: 0x000c, 0x3747: 0x000c, 0x3748: 0x000c, 0x3749: 0x000c, 0x374a: 0x000c, 0x374b: 0x000c, + 0x374c: 0x000c, 0x374d: 0x000c, 0x374e: 0x000c, 0x374f: 0x000c, 0x3750: 0x000c, 0x3751: 0x000c, + 0x3752: 0x000c, 0x3753: 0x000c, 0x3754: 0x000c, 0x3755: 0x000c, 0x3756: 0x000c, 0x3757: 0x000c, + 0x3758: 0x000c, 0x3759: 0x000c, 0x375a: 0x000c, 0x375b: 0x000c, 0x375c: 0x000c, 0x375d: 0x000c, + 0x375e: 0x000c, 0x375f: 0x000c, 0x3760: 0x000c, 0x3761: 0x000c, 0x3762: 0x000c, 0x3763: 0x000c, + 0x3764: 0x000c, 0x3765: 0x000c, 0x3766: 0x000c, 0x3767: 0x000c, 0x3768: 0x000c, 0x3769: 0x000c, + 0x376a: 0x000c, 0x376b: 0x000c, 0x376c: 0x000c, 0x376d: 0x000c, 0x376e: 0x000c, 0x376f: 0x000c, + 0x3770: 0x000b, 0x3771: 0x000b, 0x3772: 0x000b, 0x3773: 0x000b, 0x3774: 0x000b, 0x3775: 0x000b, + 0x3776: 0x000b, 0x3777: 0x000b, 0x3778: 0x000b, 0x3779: 0x000b, 0x377a: 0x000b, 0x377b: 0x000b, + 0x377c: 0x000b, 0x377d: 0x000b, 0x377e: 0x000b, 0x377f: 0x000b, +} + +// bidiIndex: 24 blocks, 1536 entries, 1536 bytes +// Block 0 is the zero block. +var bidiIndex = [1536]uint8{ + // Block 0x0, offset 0x0 + // Block 0x1, offset 0x40 + // Block 0x2, offset 0x80 + // Block 0x3, offset 0xc0 + 0xc2: 0x01, 0xc3: 0x02, + 0xca: 0x03, 0xcb: 0x04, 0xcc: 0x05, 0xcd: 0x06, 0xce: 0x07, 0xcf: 0x08, + 0xd2: 0x09, 0xd6: 0x0a, 0xd7: 0x0b, + 0xd8: 0x0c, 0xd9: 0x0d, 0xda: 0x0e, 0xdb: 0x0f, 0xdc: 0x10, 0xdd: 0x11, 0xde: 0x12, 0xdf: 0x13, + 0xe0: 0x02, 0xe1: 0x03, 0xe2: 0x04, 0xe3: 0x05, 0xe4: 0x06, + 0xea: 0x07, 0xef: 0x08, + 0xf0: 0x11, 0xf1: 0x12, 0xf2: 0x12, 0xf3: 0x14, 0xf4: 0x15, + // Block 0x4, offset 0x100 + 0x120: 0x14, 0x121: 0x15, 0x122: 0x16, 0x123: 0x17, 0x124: 0x18, 0x125: 0x19, 0x126: 0x1a, 0x127: 0x1b, + 0x128: 0x1c, 0x129: 0x1d, 0x12a: 0x1c, 0x12b: 0x1e, 0x12c: 0x1f, 0x12d: 0x20, 0x12e: 0x21, 0x12f: 0x22, + 0x130: 0x23, 0x131: 0x24, 0x132: 0x1a, 0x133: 0x25, 0x134: 0x26, 0x135: 0x27, 0x137: 0x28, + 0x138: 0x29, 0x139: 0x2a, 0x13a: 0x2b, 0x13b: 0x2c, 0x13c: 0x2d, 0x13d: 0x2e, 0x13e: 0x2f, 0x13f: 0x30, + // Block 0x5, offset 0x140 + 0x140: 0x31, 0x141: 0x32, 0x142: 0x33, + 0x14d: 0x34, 0x14e: 0x35, + 0x150: 0x36, + 0x15a: 0x37, 0x15c: 0x38, 0x15d: 0x39, 0x15e: 0x3a, 0x15f: 0x3b, + 0x160: 0x3c, 0x162: 0x3d, 0x164: 0x3e, 0x165: 0x3f, 0x167: 0x40, + 0x168: 0x41, 0x169: 0x42, 0x16a: 0x43, 0x16c: 0x44, 0x16d: 0x45, 0x16e: 0x46, 0x16f: 0x47, + 0x170: 0x48, 0x173: 0x49, 0x177: 0x4a, + 0x17e: 0x4b, 0x17f: 0x4c, + // Block 0x6, offset 0x180 + 0x180: 0x4d, 0x181: 0x4e, 0x182: 0x4f, 0x183: 0x50, 0x184: 0x51, 0x185: 0x52, 0x186: 0x53, 0x187: 0x54, + 0x188: 0x55, 0x189: 0x54, 0x18a: 0x54, 0x18b: 0x54, 0x18c: 0x56, 0x18d: 0x57, 0x18e: 0x58, 0x18f: 0x59, + 0x190: 0x5a, 0x191: 0x5b, 0x192: 0x5c, 0x193: 0x5d, 0x194: 0x54, 0x195: 0x54, 0x196: 0x54, 0x197: 0x54, + 0x198: 0x54, 0x199: 0x54, 0x19a: 0x5e, 0x19b: 0x54, 0x19c: 0x54, 0x19d: 0x5f, 0x19e: 0x54, 0x19f: 0x60, + 0x1a4: 0x54, 0x1a5: 0x54, 0x1a6: 0x61, 0x1a7: 0x62, + 0x1a8: 0x54, 0x1a9: 0x54, 0x1aa: 0x54, 0x1ab: 0x54, 0x1ac: 0x54, 0x1ad: 0x63, 0x1ae: 0x64, 0x1af: 0x65, + 0x1b3: 0x66, 0x1b5: 0x67, 0x1b7: 0x68, + 0x1b8: 0x69, 0x1b9: 0x6a, 0x1ba: 0x6b, 0x1bb: 0x6c, 0x1bc: 0x54, 0x1bd: 0x54, 0x1be: 0x54, 0x1bf: 0x6d, + // Block 0x7, offset 0x1c0 + 0x1c0: 0x6e, 0x1c2: 0x6f, 0x1c3: 0x70, 0x1c7: 0x71, + 0x1c8: 0x72, 0x1c9: 0x73, 0x1ca: 0x74, 0x1cb: 0x75, 0x1cd: 0x76, 0x1cf: 0x77, + // Block 0x8, offset 0x200 + 0x237: 0x54, + // Block 0x9, offset 0x240 + 0x252: 0x78, 0x253: 0x79, + 0x258: 0x7a, 0x259: 0x7b, 0x25a: 0x7c, 0x25b: 0x7d, 0x25c: 0x7e, 0x25e: 0x7f, + 0x260: 0x80, 0x261: 0x81, 0x263: 0x82, 0x264: 0x83, 0x265: 0x84, 0x266: 0x85, 0x267: 0x86, + 0x268: 0x87, 0x269: 0x88, 0x26a: 0x89, 0x26b: 0x8a, 0x26f: 0x8b, + // Block 0xa, offset 0x280 + 0x2ac: 0x8c, 0x2ad: 0x8d, 0x2ae: 0x0e, 0x2af: 0x0e, + 0x2b0: 0x0e, 0x2b1: 0x0e, 0x2b2: 0x0e, 0x2b3: 0x0e, 0x2b4: 0x8e, 0x2b5: 0x0e, 0x2b6: 0x0e, 0x2b7: 0x8f, + 0x2b8: 0x90, 0x2b9: 0x91, 0x2ba: 0x0e, 0x2bb: 0x92, 0x2bc: 0x93, 0x2bd: 0x94, 0x2bf: 0x95, + // Block 0xb, offset 0x2c0 + 0x2c4: 0x96, 0x2c5: 0x54, 0x2c6: 0x97, 0x2c7: 0x98, + 0x2cb: 0x99, 0x2cd: 0x9a, + 0x2e0: 0x9b, 0x2e1: 0x9b, 0x2e2: 0x9b, 0x2e3: 0x9b, 0x2e4: 0x9c, 0x2e5: 0x9b, 0x2e6: 0x9b, 0x2e7: 0x9b, + 0x2e8: 0x9d, 0x2e9: 0x9b, 0x2ea: 0x9b, 0x2eb: 0x9e, 0x2ec: 0x9f, 0x2ed: 0x9b, 0x2ee: 0x9b, 0x2ef: 0x9b, + 0x2f0: 0x9b, 0x2f1: 0x9b, 0x2f2: 0x9b, 0x2f3: 0x9b, 0x2f4: 0x9b, 0x2f5: 0x9b, 0x2f6: 0x9b, 0x2f7: 0x9b, + 0x2f8: 0x9b, 0x2f9: 0xa0, 0x2fa: 0x9b, 0x2fb: 0x9b, 0x2fc: 0x9b, 0x2fd: 0x9b, 0x2fe: 0x9b, 0x2ff: 0x9b, + // Block 0xc, offset 0x300 + 0x300: 0xa1, 0x301: 0xa2, 0x302: 0xa3, 0x304: 0xa4, 0x305: 0xa5, 0x306: 0xa6, 0x307: 0xa7, + 0x308: 0xa8, 0x30b: 0xa9, 0x30c: 0xaa, 0x30d: 0xab, + 0x310: 0xac, 0x311: 0xad, 0x312: 0xae, 0x313: 0xaf, 0x316: 0xb0, 0x317: 0xb1, + 0x318: 0xb2, 0x319: 0xb3, 0x31a: 0xb4, 0x31c: 0xb5, + 0x330: 0xb6, 0x332: 0xb7, + // Block 0xd, offset 0x340 + 0x36b: 0xb8, 0x36c: 0xb9, + 0x37e: 0xba, + // Block 0xe, offset 0x380 + 0x3b2: 0xbb, + // Block 0xf, offset 0x3c0 + 0x3c5: 0xbc, 0x3c6: 0xbd, + 0x3c8: 0x54, 0x3c9: 0xbe, 0x3cc: 0x54, 0x3cd: 0xbf, + 0x3db: 0xc0, 0x3dc: 0xc1, 0x3dd: 0xc2, 0x3de: 0xc3, 0x3df: 0xc4, + 0x3e8: 0xc5, 0x3e9: 0xc6, 0x3ea: 0xc7, + // Block 0x10, offset 0x400 + 0x400: 0xc8, + 0x420: 0x9b, 0x421: 0x9b, 0x422: 0x9b, 0x423: 0xc9, 0x424: 0x9b, 0x425: 0xca, 0x426: 0x9b, 0x427: 0x9b, + 0x428: 0x9b, 0x429: 0x9b, 0x42a: 0x9b, 0x42b: 0x9b, 0x42c: 0x9b, 0x42d: 0x9b, 0x42e: 0x9b, 0x42f: 0x9b, + 0x430: 0x9b, 0x431: 0x9b, 0x432: 0x9b, 0x433: 0x9b, 0x434: 0x9b, 0x435: 0x9b, 0x436: 0x9b, 0x437: 0x9b, + 0x438: 0x0e, 0x439: 0x0e, 0x43a: 0x0e, 0x43b: 0xcb, 0x43c: 0x9b, 0x43d: 0x9b, 0x43e: 0x9b, 0x43f: 0x9b, + // Block 0x11, offset 0x440 + 0x440: 0xcc, 0x441: 0x54, 0x442: 0xcd, 0x443: 0xce, 0x444: 0xcf, 0x445: 0xd0, + 0x44c: 0x54, 0x44d: 0x54, 0x44e: 0x54, 0x44f: 0x54, + 0x450: 0x54, 0x451: 0x54, 0x452: 0x54, 0x453: 0x54, 0x454: 0x54, 0x455: 0x54, 0x456: 0x54, 0x457: 0x54, + 0x458: 0x54, 0x459: 0x54, 0x45a: 0x54, 0x45b: 0xd1, 0x45c: 0x54, 0x45d: 0x6c, 0x45e: 0x54, 0x45f: 0xd2, + 0x460: 0xd3, 0x461: 0xd4, 0x462: 0xd5, 0x464: 0xd6, 0x465: 0xd7, 0x466: 0xd8, 0x467: 0x36, + 0x47f: 0xd9, + // Block 0x12, offset 0x480 + 0x4bf: 0xd9, + // Block 0x13, offset 0x4c0 + 0x4d0: 0x09, 0x4d1: 0x0a, 0x4d6: 0x0b, + 0x4db: 0x0c, 0x4dd: 0x0d, 0x4de: 0x0e, 0x4df: 0x0f, + 0x4ef: 0x10, + 0x4ff: 0x10, + // Block 0x14, offset 0x500 + 0x50f: 0x10, + 0x51f: 0x10, + 0x52f: 0x10, + 0x53f: 0x10, + // Block 0x15, offset 0x540 + 0x540: 0xda, 0x541: 0xda, 0x542: 0xda, 0x543: 0xda, 0x544: 0x05, 0x545: 0x05, 0x546: 0x05, 0x547: 0xdb, + 0x548: 0xda, 0x549: 0xda, 0x54a: 0xda, 0x54b: 0xda, 0x54c: 0xda, 0x54d: 0xda, 0x54e: 0xda, 0x54f: 0xda, + 0x550: 0xda, 0x551: 0xda, 0x552: 0xda, 0x553: 0xda, 0x554: 0xda, 0x555: 0xda, 0x556: 0xda, 0x557: 0xda, + 0x558: 0xda, 0x559: 0xda, 0x55a: 0xda, 0x55b: 0xda, 0x55c: 0xda, 0x55d: 0xda, 0x55e: 0xda, 0x55f: 0xda, + 0x560: 0xda, 0x561: 0xda, 0x562: 0xda, 0x563: 0xda, 0x564: 0xda, 0x565: 0xda, 0x566: 0xda, 0x567: 0xda, + 0x568: 0xda, 0x569: 0xda, 0x56a: 0xda, 0x56b: 0xda, 0x56c: 0xda, 0x56d: 0xda, 0x56e: 0xda, 0x56f: 0xda, + 0x570: 0xda, 0x571: 0xda, 0x572: 0xda, 0x573: 0xda, 0x574: 0xda, 0x575: 0xda, 0x576: 0xda, 0x577: 0xda, + 0x578: 0xda, 0x579: 0xda, 0x57a: 0xda, 0x57b: 0xda, 0x57c: 0xda, 0x57d: 0xda, 0x57e: 0xda, 0x57f: 0xda, + // Block 0x16, offset 0x580 + 0x58f: 0x10, + 0x59f: 0x10, + 0x5a0: 0x13, + 0x5af: 0x10, + 0x5bf: 0x10, + // Block 0x17, offset 0x5c0 + 0x5cf: 0x10, +} + +// Total table size 15800 bytes (15KiB); checksum: F50EF68C diff --git a/vendor/golang.org/x/text/unicode/bidi/trieval.go b/vendor/golang.org/x/text/unicode/bidi/trieval.go new file mode 100644 index 0000000000..4c459c4b72 --- /dev/null +++ b/vendor/golang.org/x/text/unicode/bidi/trieval.go @@ -0,0 +1,60 @@ +// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. + +package bidi + +// Class is the Unicode BiDi class. Each rune has a single class. +type Class uint + +const ( + L Class = iota // LeftToRight + R // RightToLeft + EN // EuropeanNumber + ES // EuropeanSeparator + ET // EuropeanTerminator + AN // ArabicNumber + CS // CommonSeparator + B // ParagraphSeparator + S // SegmentSeparator + WS // WhiteSpace + ON // OtherNeutral + BN // BoundaryNeutral + NSM // NonspacingMark + AL // ArabicLetter + Control // Control LRO - PDI + + numClass + + LRO // LeftToRightOverride + RLO // RightToLeftOverride + LRE // LeftToRightEmbedding + RLE // RightToLeftEmbedding + PDF // PopDirectionalFormat + LRI // LeftToRightIsolate + RLI // RightToLeftIsolate + FSI // FirstStrongIsolate + PDI // PopDirectionalIsolate + + unknownClass = ^Class(0) +) + +var controlToClass = map[rune]Class{ + 0x202D: LRO, // LeftToRightOverride, + 0x202E: RLO, // RightToLeftOverride, + 0x202A: LRE, // LeftToRightEmbedding, + 0x202B: RLE, // RightToLeftEmbedding, + 0x202C: PDF, // PopDirectionalFormat, + 0x2066: LRI, // LeftToRightIsolate, + 0x2067: RLI, // RightToLeftIsolate, + 0x2068: FSI, // FirstStrongIsolate, + 0x2069: PDI, // PopDirectionalIsolate, +} + +// A trie entry has the following bits: +// 7..5 XOR mask for brackets +// 4 1: Bracket open, 0: Bracket close +// 3..0 Class type + +const ( + openMask = 0x10 + xorMaskShift = 5 +) diff --git a/vendor/golang.org/x/text/unicode/norm/composition.go b/vendor/golang.org/x/text/unicode/norm/composition.go new file mode 100644 index 0000000000..bab4c5de02 --- /dev/null +++ b/vendor/golang.org/x/text/unicode/norm/composition.go @@ -0,0 +1,508 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package norm + +import "unicode/utf8" + +const ( + maxNonStarters = 30 + // The maximum number of characters needed for a buffer is + // maxNonStarters + 1 for the starter + 1 for the GCJ + maxBufferSize = maxNonStarters + 2 + maxNFCExpansion = 3 // NFC(0x1D160) + maxNFKCExpansion = 18 // NFKC(0xFDFA) + + maxByteBufferSize = utf8.UTFMax * maxBufferSize // 128 +) + +// ssState is used for reporting the segment state after inserting a rune. +// It is returned by streamSafe.next. +type ssState int + +const ( + // Indicates a rune was successfully added to the segment. + ssSuccess ssState = iota + // Indicates a rune starts a new segment and should not be added. + ssStarter + // Indicates a rune caused a segment overflow and a CGJ should be inserted. + ssOverflow +) + +// streamSafe implements the policy of when a CGJ should be inserted. +type streamSafe uint8 + +// first inserts the first rune of a segment. It is a faster version of next if +// it is known p represents the first rune in a segment. +func (ss *streamSafe) first(p Properties) { + *ss = streamSafe(p.nTrailingNonStarters()) +} + +// insert returns a ssState value to indicate whether a rune represented by p +// can be inserted. +func (ss *streamSafe) next(p Properties) ssState { + if *ss > maxNonStarters { + panic("streamSafe was not reset") + } + n := p.nLeadingNonStarters() + if *ss += streamSafe(n); *ss > maxNonStarters { + *ss = 0 + return ssOverflow + } + // The Stream-Safe Text Processing prescribes that the counting can stop + // as soon as a starter is encountered. However, there are some starters, + // like Jamo V and T, that can combine with other runes, leaving their + // successive non-starters appended to the previous, possibly causing an + // overflow. We will therefore consider any rune with a non-zero nLead to + // be a non-starter. Note that it always hold that if nLead > 0 then + // nLead == nTrail. + if n == 0 { + *ss = streamSafe(p.nTrailingNonStarters()) + return ssStarter + } + return ssSuccess +} + +// backwards is used for checking for overflow and segment starts +// when traversing a string backwards. Users do not need to call first +// for the first rune. The state of the streamSafe retains the count of +// the non-starters loaded. +func (ss *streamSafe) backwards(p Properties) ssState { + if *ss > maxNonStarters { + panic("streamSafe was not reset") + } + c := *ss + streamSafe(p.nTrailingNonStarters()) + if c > maxNonStarters { + return ssOverflow + } + *ss = c + if p.nLeadingNonStarters() == 0 { + return ssStarter + } + return ssSuccess +} + +func (ss streamSafe) isMax() bool { + return ss == maxNonStarters +} + +// GraphemeJoiner is inserted after maxNonStarters non-starter runes. +const GraphemeJoiner = "\u034F" + +// reorderBuffer is used to normalize a single segment. Characters inserted with +// insert are decomposed and reordered based on CCC. The compose method can +// be used to recombine characters. Note that the byte buffer does not hold +// the UTF-8 characters in order. Only the rune array is maintained in sorted +// order. flush writes the resulting segment to a byte array. +type reorderBuffer struct { + rune [maxBufferSize]Properties // Per character info. + byte [maxByteBufferSize]byte // UTF-8 buffer. Referenced by runeInfo.pos. + nbyte uint8 // Number or bytes. + ss streamSafe // For limiting length of non-starter sequence. + nrune int // Number of runeInfos. + f formInfo + + src input + nsrc int + tmpBytes input + + out []byte + flushF func(*reorderBuffer) bool +} + +func (rb *reorderBuffer) init(f Form, src []byte) { + rb.f = *formTable[f] + rb.src.setBytes(src) + rb.nsrc = len(src) + rb.ss = 0 +} + +func (rb *reorderBuffer) initString(f Form, src string) { + rb.f = *formTable[f] + rb.src.setString(src) + rb.nsrc = len(src) + rb.ss = 0 +} + +func (rb *reorderBuffer) setFlusher(out []byte, f func(*reorderBuffer) bool) { + rb.out = out + rb.flushF = f +} + +// reset discards all characters from the buffer. +func (rb *reorderBuffer) reset() { + rb.nrune = 0 + rb.nbyte = 0 +} + +func (rb *reorderBuffer) doFlush() bool { + if rb.f.composing { + rb.compose() + } + res := rb.flushF(rb) + rb.reset() + return res +} + +// appendFlush appends the normalized segment to rb.out. +func appendFlush(rb *reorderBuffer) bool { + for i := 0; i < rb.nrune; i++ { + start := rb.rune[i].pos + end := start + rb.rune[i].size + rb.out = append(rb.out, rb.byte[start:end]...) + } + return true +} + +// flush appends the normalized segment to out and resets rb. +func (rb *reorderBuffer) flush(out []byte) []byte { + for i := 0; i < rb.nrune; i++ { + start := rb.rune[i].pos + end := start + rb.rune[i].size + out = append(out, rb.byte[start:end]...) + } + rb.reset() + return out +} + +// flushCopy copies the normalized segment to buf and resets rb. +// It returns the number of bytes written to buf. +func (rb *reorderBuffer) flushCopy(buf []byte) int { + p := 0 + for i := 0; i < rb.nrune; i++ { + runep := rb.rune[i] + p += copy(buf[p:], rb.byte[runep.pos:runep.pos+runep.size]) + } + rb.reset() + return p +} + +// insertOrdered inserts a rune in the buffer, ordered by Canonical Combining Class. +// It returns false if the buffer is not large enough to hold the rune. +// It is used internally by insert and insertString only. +func (rb *reorderBuffer) insertOrdered(info Properties) { + n := rb.nrune + b := rb.rune[:] + cc := info.ccc + if cc > 0 { + // Find insertion position + move elements to make room. + for ; n > 0; n-- { + if b[n-1].ccc <= cc { + break + } + b[n] = b[n-1] + } + } + rb.nrune += 1 + pos := uint8(rb.nbyte) + rb.nbyte += utf8.UTFMax + info.pos = pos + b[n] = info +} + +// insertErr is an error code returned by insert. Using this type instead +// of error improves performance up to 20% for many of the benchmarks. +type insertErr int + +const ( + iSuccess insertErr = -iota + iShortDst + iShortSrc +) + +// insertFlush inserts the given rune in the buffer ordered by CCC. +// If a decomposition with multiple segments are encountered, they leading +// ones are flushed. +// It returns a non-zero error code if the rune was not inserted. +func (rb *reorderBuffer) insertFlush(src input, i int, info Properties) insertErr { + if rune := src.hangul(i); rune != 0 { + rb.decomposeHangul(rune) + return iSuccess + } + if info.hasDecomposition() { + return rb.insertDecomposed(info.Decomposition()) + } + rb.insertSingle(src, i, info) + return iSuccess +} + +// insertUnsafe inserts the given rune in the buffer ordered by CCC. +// It is assumed there is sufficient space to hold the runes. It is the +// responsibility of the caller to ensure this. This can be done by checking +// the state returned by the streamSafe type. +func (rb *reorderBuffer) insertUnsafe(src input, i int, info Properties) { + if rune := src.hangul(i); rune != 0 { + rb.decomposeHangul(rune) + } + if info.hasDecomposition() { + // TODO: inline. + rb.insertDecomposed(info.Decomposition()) + } else { + rb.insertSingle(src, i, info) + } +} + +// insertDecomposed inserts an entry in to the reorderBuffer for each rune +// in dcomp. dcomp must be a sequence of decomposed UTF-8-encoded runes. +// It flushes the buffer on each new segment start. +func (rb *reorderBuffer) insertDecomposed(dcomp []byte) insertErr { + rb.tmpBytes.setBytes(dcomp) + // As the streamSafe accounting already handles the counting for modifiers, + // we don't have to call next. However, we do need to keep the accounting + // intact when flushing the buffer. + for i := 0; i < len(dcomp); { + info := rb.f.info(rb.tmpBytes, i) + if info.BoundaryBefore() && rb.nrune > 0 && !rb.doFlush() { + return iShortDst + } + i += copy(rb.byte[rb.nbyte:], dcomp[i:i+int(info.size)]) + rb.insertOrdered(info) + } + return iSuccess +} + +// insertSingle inserts an entry in the reorderBuffer for the rune at +// position i. info is the runeInfo for the rune at position i. +func (rb *reorderBuffer) insertSingle(src input, i int, info Properties) { + src.copySlice(rb.byte[rb.nbyte:], i, i+int(info.size)) + rb.insertOrdered(info) +} + +// insertCGJ inserts a Combining Grapheme Joiner (0x034f) into rb. +func (rb *reorderBuffer) insertCGJ() { + rb.insertSingle(input{str: GraphemeJoiner}, 0, Properties{size: uint8(len(GraphemeJoiner))}) +} + +// appendRune inserts a rune at the end of the buffer. It is used for Hangul. +func (rb *reorderBuffer) appendRune(r rune) { + bn := rb.nbyte + sz := utf8.EncodeRune(rb.byte[bn:], rune(r)) + rb.nbyte += utf8.UTFMax + rb.rune[rb.nrune] = Properties{pos: bn, size: uint8(sz)} + rb.nrune++ +} + +// assignRune sets a rune at position pos. It is used for Hangul and recomposition. +func (rb *reorderBuffer) assignRune(pos int, r rune) { + bn := rb.rune[pos].pos + sz := utf8.EncodeRune(rb.byte[bn:], rune(r)) + rb.rune[pos] = Properties{pos: bn, size: uint8(sz)} +} + +// runeAt returns the rune at position n. It is used for Hangul and recomposition. +func (rb *reorderBuffer) runeAt(n int) rune { + inf := rb.rune[n] + r, _ := utf8.DecodeRune(rb.byte[inf.pos : inf.pos+inf.size]) + return r +} + +// bytesAt returns the UTF-8 encoding of the rune at position n. +// It is used for Hangul and recomposition. +func (rb *reorderBuffer) bytesAt(n int) []byte { + inf := rb.rune[n] + return rb.byte[inf.pos : int(inf.pos)+int(inf.size)] +} + +// For Hangul we combine algorithmically, instead of using tables. +const ( + hangulBase = 0xAC00 // UTF-8(hangulBase) -> EA B0 80 + hangulBase0 = 0xEA + hangulBase1 = 0xB0 + hangulBase2 = 0x80 + + hangulEnd = hangulBase + jamoLVTCount // UTF-8(0xD7A4) -> ED 9E A4 + hangulEnd0 = 0xED + hangulEnd1 = 0x9E + hangulEnd2 = 0xA4 + + jamoLBase = 0x1100 // UTF-8(jamoLBase) -> E1 84 00 + jamoLBase0 = 0xE1 + jamoLBase1 = 0x84 + jamoLEnd = 0x1113 + jamoVBase = 0x1161 + jamoVEnd = 0x1176 + jamoTBase = 0x11A7 + jamoTEnd = 0x11C3 + + jamoTCount = 28 + jamoVCount = 21 + jamoVTCount = 21 * 28 + jamoLVTCount = 19 * 21 * 28 +) + +const hangulUTF8Size = 3 + +func isHangul(b []byte) bool { + if len(b) < hangulUTF8Size { + return false + } + b0 := b[0] + if b0 < hangulBase0 { + return false + } + b1 := b[1] + switch { + case b0 == hangulBase0: + return b1 >= hangulBase1 + case b0 < hangulEnd0: + return true + case b0 > hangulEnd0: + return false + case b1 < hangulEnd1: + return true + } + return b1 == hangulEnd1 && b[2] < hangulEnd2 +} + +func isHangulString(b string) bool { + if len(b) < hangulUTF8Size { + return false + } + b0 := b[0] + if b0 < hangulBase0 { + return false + } + b1 := b[1] + switch { + case b0 == hangulBase0: + return b1 >= hangulBase1 + case b0 < hangulEnd0: + return true + case b0 > hangulEnd0: + return false + case b1 < hangulEnd1: + return true + } + return b1 == hangulEnd1 && b[2] < hangulEnd2 +} + +// Caller must ensure len(b) >= 2. +func isJamoVT(b []byte) bool { + // True if (rune & 0xff00) == jamoLBase + return b[0] == jamoLBase0 && (b[1]&0xFC) == jamoLBase1 +} + +func isHangulWithoutJamoT(b []byte) bool { + c, _ := utf8.DecodeRune(b) + c -= hangulBase + return c < jamoLVTCount && c%jamoTCount == 0 +} + +// decomposeHangul writes the decomposed Hangul to buf and returns the number +// of bytes written. len(buf) should be at least 9. +func decomposeHangul(buf []byte, r rune) int { + const JamoUTF8Len = 3 + r -= hangulBase + x := r % jamoTCount + r /= jamoTCount + utf8.EncodeRune(buf, jamoLBase+r/jamoVCount) + utf8.EncodeRune(buf[JamoUTF8Len:], jamoVBase+r%jamoVCount) + if x != 0 { + utf8.EncodeRune(buf[2*JamoUTF8Len:], jamoTBase+x) + return 3 * JamoUTF8Len + } + return 2 * JamoUTF8Len +} + +// decomposeHangul algorithmically decomposes a Hangul rune into +// its Jamo components. +// See http://unicode.org/reports/tr15/#Hangul for details on decomposing Hangul. +func (rb *reorderBuffer) decomposeHangul(r rune) { + r -= hangulBase + x := r % jamoTCount + r /= jamoTCount + rb.appendRune(jamoLBase + r/jamoVCount) + rb.appendRune(jamoVBase + r%jamoVCount) + if x != 0 { + rb.appendRune(jamoTBase + x) + } +} + +// combineHangul algorithmically combines Jamo character components into Hangul. +// See http://unicode.org/reports/tr15/#Hangul for details on combining Hangul. +func (rb *reorderBuffer) combineHangul(s, i, k int) { + b := rb.rune[:] + bn := rb.nrune + for ; i < bn; i++ { + cccB := b[k-1].ccc + cccC := b[i].ccc + if cccB == 0 { + s = k - 1 + } + if s != k-1 && cccB >= cccC { + // b[i] is blocked by greater-equal cccX below it + b[k] = b[i] + k++ + } else { + l := rb.runeAt(s) // also used to compare to hangulBase + v := rb.runeAt(i) // also used to compare to jamoT + switch { + case jamoLBase <= l && l < jamoLEnd && + jamoVBase <= v && v < jamoVEnd: + // 11xx plus 116x to LV + rb.assignRune(s, hangulBase+ + (l-jamoLBase)*jamoVTCount+(v-jamoVBase)*jamoTCount) + case hangulBase <= l && l < hangulEnd && + jamoTBase < v && v < jamoTEnd && + ((l-hangulBase)%jamoTCount) == 0: + // ACxx plus 11Ax to LVT + rb.assignRune(s, l+v-jamoTBase) + default: + b[k] = b[i] + k++ + } + } + } + rb.nrune = k +} + +// compose recombines the runes in the buffer. +// It should only be used to recompose a single segment, as it will not +// handle alternations between Hangul and non-Hangul characters correctly. +func (rb *reorderBuffer) compose() { + // UAX #15, section X5 , including Corrigendum #5 + // "In any character sequence beginning with starter S, a character C is + // blocked from S if and only if there is some character B between S + // and C, and either B is a starter or it has the same or higher + // combining class as C." + bn := rb.nrune + if bn == 0 { + return + } + k := 1 + b := rb.rune[:] + for s, i := 0, 1; i < bn; i++ { + if isJamoVT(rb.bytesAt(i)) { + // Redo from start in Hangul mode. Necessary to support + // U+320E..U+321E in NFKC mode. + rb.combineHangul(s, i, k) + return + } + ii := b[i] + // We can only use combineForward as a filter if we later + // get the info for the combined character. This is more + // expensive than using the filter. Using combinesBackward() + // is safe. + if ii.combinesBackward() { + cccB := b[k-1].ccc + cccC := ii.ccc + blocked := false // b[i] blocked by starter or greater or equal CCC? + if cccB == 0 { + s = k - 1 + } else { + blocked = s != k-1 && cccB >= cccC + } + if !blocked { + combined := combine(rb.runeAt(s), rb.runeAt(i)) + if combined != 0 { + rb.assignRune(s, combined) + continue + } + } + } + b[k] = b[i] + k++ + } + rb.nrune = k +} diff --git a/vendor/golang.org/x/text/unicode/norm/forminfo.go b/vendor/golang.org/x/text/unicode/norm/forminfo.go new file mode 100644 index 0000000000..e67e7655c5 --- /dev/null +++ b/vendor/golang.org/x/text/unicode/norm/forminfo.go @@ -0,0 +1,259 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package norm + +// This file contains Form-specific logic and wrappers for data in tables.go. + +// Rune info is stored in a separate trie per composing form. A composing form +// and its corresponding decomposing form share the same trie. Each trie maps +// a rune to a uint16. The values take two forms. For v >= 0x8000: +// bits +// 15: 1 (inverse of NFD_QC bit of qcInfo) +// 13..7: qcInfo (see below). isYesD is always true (no decompostion). +// 6..0: ccc (compressed CCC value). +// For v < 0x8000, the respective rune has a decomposition and v is an index +// into a byte array of UTF-8 decomposition sequences and additional info and +// has the form: +//
* [ []] +// The header contains the number of bytes in the decomposition (excluding this +// length byte). The two most significant bits of this length byte correspond +// to bit 5 and 4 of qcInfo (see below). The byte sequence itself starts at v+1. +// The byte sequence is followed by a trailing and leading CCC if the values +// for these are not zero. The value of v determines which ccc are appended +// to the sequences. For v < firstCCC, there are none, for v >= firstCCC, +// the sequence is followed by a trailing ccc, and for v >= firstLeadingCC +// there is an additional leading ccc. The value of tccc itself is the +// trailing CCC shifted left 2 bits. The two least-significant bits of tccc +// are the number of trailing non-starters. + +const ( + qcInfoMask = 0x3F // to clear all but the relevant bits in a qcInfo + headerLenMask = 0x3F // extract the length value from the header byte + headerFlagsMask = 0xC0 // extract the qcInfo bits from the header byte +) + +// Properties provides access to normalization properties of a rune. +type Properties struct { + pos uint8 // start position in reorderBuffer; used in composition.go + size uint8 // length of UTF-8 encoding of this rune + ccc uint8 // leading canonical combining class (ccc if not decomposition) + tccc uint8 // trailing canonical combining class (ccc if not decomposition) + nLead uint8 // number of leading non-starters. + flags qcInfo // quick check flags + index uint16 +} + +// functions dispatchable per form +type lookupFunc func(b input, i int) Properties + +// formInfo holds Form-specific functions and tables. +type formInfo struct { + form Form + composing, compatibility bool // form type + info lookupFunc + nextMain iterFunc +} + +var formTable = []*formInfo{{ + form: NFC, + composing: true, + compatibility: false, + info: lookupInfoNFC, + nextMain: nextComposed, +}, { + form: NFD, + composing: false, + compatibility: false, + info: lookupInfoNFC, + nextMain: nextDecomposed, +}, { + form: NFKC, + composing: true, + compatibility: true, + info: lookupInfoNFKC, + nextMain: nextComposed, +}, { + form: NFKD, + composing: false, + compatibility: true, + info: lookupInfoNFKC, + nextMain: nextDecomposed, +}} + +// We do not distinguish between boundaries for NFC, NFD, etc. to avoid +// unexpected behavior for the user. For example, in NFD, there is a boundary +// after 'a'. However, 'a' might combine with modifiers, so from the application's +// perspective it is not a good boundary. We will therefore always use the +// boundaries for the combining variants. + +// BoundaryBefore returns true if this rune starts a new segment and +// cannot combine with any rune on the left. +func (p Properties) BoundaryBefore() bool { + if p.ccc == 0 && !p.combinesBackward() { + return true + } + // We assume that the CCC of the first character in a decomposition + // is always non-zero if different from info.ccc and that we can return + // false at this point. This is verified by maketables. + return false +} + +// BoundaryAfter returns true if runes cannot combine with or otherwise +// interact with this or previous runes. +func (p Properties) BoundaryAfter() bool { + // TODO: loosen these conditions. + return p.isInert() +} + +// We pack quick check data in 4 bits: +// 5: Combines forward (0 == false, 1 == true) +// 4..3: NFC_QC Yes(00), No (10), or Maybe (11) +// 2: NFD_QC Yes (0) or No (1). No also means there is a decomposition. +// 1..0: Number of trailing non-starters. +// +// When all 4 bits are zero, the character is inert, meaning it is never +// influenced by normalization. +type qcInfo uint8 + +func (p Properties) isYesC() bool { return p.flags&0x10 == 0 } +func (p Properties) isYesD() bool { return p.flags&0x4 == 0 } + +func (p Properties) combinesForward() bool { return p.flags&0x20 != 0 } +func (p Properties) combinesBackward() bool { return p.flags&0x8 != 0 } // == isMaybe +func (p Properties) hasDecomposition() bool { return p.flags&0x4 != 0 } // == isNoD + +func (p Properties) isInert() bool { + return p.flags&qcInfoMask == 0 && p.ccc == 0 +} + +func (p Properties) multiSegment() bool { + return p.index >= firstMulti && p.index < endMulti +} + +func (p Properties) nLeadingNonStarters() uint8 { + return p.nLead +} + +func (p Properties) nTrailingNonStarters() uint8 { + return uint8(p.flags & 0x03) +} + +// Decomposition returns the decomposition for the underlying rune +// or nil if there is none. +func (p Properties) Decomposition() []byte { + // TODO: create the decomposition for Hangul? + if p.index == 0 { + return nil + } + i := p.index + n := decomps[i] & headerLenMask + i++ + return decomps[i : i+uint16(n)] +} + +// Size returns the length of UTF-8 encoding of the rune. +func (p Properties) Size() int { + return int(p.size) +} + +// CCC returns the canonical combining class of the underlying rune. +func (p Properties) CCC() uint8 { + if p.index >= firstCCCZeroExcept { + return 0 + } + return ccc[p.ccc] +} + +// LeadCCC returns the CCC of the first rune in the decomposition. +// If there is no decomposition, LeadCCC equals CCC. +func (p Properties) LeadCCC() uint8 { + return ccc[p.ccc] +} + +// TrailCCC returns the CCC of the last rune in the decomposition. +// If there is no decomposition, TrailCCC equals CCC. +func (p Properties) TrailCCC() uint8 { + return ccc[p.tccc] +} + +// Recomposition +// We use 32-bit keys instead of 64-bit for the two codepoint keys. +// This clips off the bits of three entries, but we know this will not +// result in a collision. In the unlikely event that changes to +// UnicodeData.txt introduce collisions, the compiler will catch it. +// Note that the recomposition map for NFC and NFKC are identical. + +// combine returns the combined rune or 0 if it doesn't exist. +func combine(a, b rune) rune { + key := uint32(uint16(a))<<16 + uint32(uint16(b)) + return recompMap[key] +} + +func lookupInfoNFC(b input, i int) Properties { + v, sz := b.charinfoNFC(i) + return compInfo(v, sz) +} + +func lookupInfoNFKC(b input, i int) Properties { + v, sz := b.charinfoNFKC(i) + return compInfo(v, sz) +} + +// Properties returns properties for the first rune in s. +func (f Form) Properties(s []byte) Properties { + if f == NFC || f == NFD { + return compInfo(nfcData.lookup(s)) + } + return compInfo(nfkcData.lookup(s)) +} + +// PropertiesString returns properties for the first rune in s. +func (f Form) PropertiesString(s string) Properties { + if f == NFC || f == NFD { + return compInfo(nfcData.lookupString(s)) + } + return compInfo(nfkcData.lookupString(s)) +} + +// compInfo converts the information contained in v and sz +// to a Properties. See the comment at the top of the file +// for more information on the format. +func compInfo(v uint16, sz int) Properties { + if v == 0 { + return Properties{size: uint8(sz)} + } else if v >= 0x8000 { + p := Properties{ + size: uint8(sz), + ccc: uint8(v), + tccc: uint8(v), + flags: qcInfo(v >> 8), + } + if p.ccc > 0 || p.combinesBackward() { + p.nLead = uint8(p.flags & 0x3) + } + return p + } + // has decomposition + h := decomps[v] + f := (qcInfo(h&headerFlagsMask) >> 2) | 0x4 + p := Properties{size: uint8(sz), flags: f, index: v} + if v >= firstCCC { + v += uint16(h&headerLenMask) + 1 + c := decomps[v] + p.tccc = c >> 2 + p.flags |= qcInfo(c & 0x3) + if v >= firstLeadingCCC { + p.nLead = c & 0x3 + if v >= firstStarterWithNLead { + // We were tricked. Remove the decomposition. + p.flags &= 0x03 + p.index = 0 + return p + } + p.ccc = decomps[v+1] + } + } + return p +} diff --git a/vendor/golang.org/x/text/unicode/norm/input.go b/vendor/golang.org/x/text/unicode/norm/input.go new file mode 100644 index 0000000000..479e35bc25 --- /dev/null +++ b/vendor/golang.org/x/text/unicode/norm/input.go @@ -0,0 +1,109 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package norm + +import "unicode/utf8" + +type input struct { + str string + bytes []byte +} + +func inputBytes(str []byte) input { + return input{bytes: str} +} + +func inputString(str string) input { + return input{str: str} +} + +func (in *input) setBytes(str []byte) { + in.str = "" + in.bytes = str +} + +func (in *input) setString(str string) { + in.str = str + in.bytes = nil +} + +func (in *input) _byte(p int) byte { + if in.bytes == nil { + return in.str[p] + } + return in.bytes[p] +} + +func (in *input) skipASCII(p, max int) int { + if in.bytes == nil { + for ; p < max && in.str[p] < utf8.RuneSelf; p++ { + } + } else { + for ; p < max && in.bytes[p] < utf8.RuneSelf; p++ { + } + } + return p +} + +func (in *input) skipContinuationBytes(p int) int { + if in.bytes == nil { + for ; p < len(in.str) && !utf8.RuneStart(in.str[p]); p++ { + } + } else { + for ; p < len(in.bytes) && !utf8.RuneStart(in.bytes[p]); p++ { + } + } + return p +} + +func (in *input) appendSlice(buf []byte, b, e int) []byte { + if in.bytes != nil { + return append(buf, in.bytes[b:e]...) + } + for i := b; i < e; i++ { + buf = append(buf, in.str[i]) + } + return buf +} + +func (in *input) copySlice(buf []byte, b, e int) int { + if in.bytes == nil { + return copy(buf, in.str[b:e]) + } + return copy(buf, in.bytes[b:e]) +} + +func (in *input) charinfoNFC(p int) (uint16, int) { + if in.bytes == nil { + return nfcData.lookupString(in.str[p:]) + } + return nfcData.lookup(in.bytes[p:]) +} + +func (in *input) charinfoNFKC(p int) (uint16, int) { + if in.bytes == nil { + return nfkcData.lookupString(in.str[p:]) + } + return nfkcData.lookup(in.bytes[p:]) +} + +func (in *input) hangul(p int) (r rune) { + var size int + if in.bytes == nil { + if !isHangulString(in.str[p:]) { + return 0 + } + r, size = utf8.DecodeRuneInString(in.str[p:]) + } else { + if !isHangul(in.bytes[p:]) { + return 0 + } + r, size = utf8.DecodeRune(in.bytes[p:]) + } + if size != hangulUTF8Size { + return 0 + } + return r +} diff --git a/vendor/golang.org/x/text/unicode/norm/iter.go b/vendor/golang.org/x/text/unicode/norm/iter.go new file mode 100644 index 0000000000..ce17f96c2e --- /dev/null +++ b/vendor/golang.org/x/text/unicode/norm/iter.go @@ -0,0 +1,457 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package norm + +import ( + "fmt" + "unicode/utf8" +) + +// MaxSegmentSize is the maximum size of a byte buffer needed to consider any +// sequence of starter and non-starter runes for the purpose of normalization. +const MaxSegmentSize = maxByteBufferSize + +// An Iter iterates over a string or byte slice, while normalizing it +// to a given Form. +type Iter struct { + rb reorderBuffer + buf [maxByteBufferSize]byte + info Properties // first character saved from previous iteration + next iterFunc // implementation of next depends on form + asciiF iterFunc + + p int // current position in input source + multiSeg []byte // remainder of multi-segment decomposition +} + +type iterFunc func(*Iter) []byte + +// Init initializes i to iterate over src after normalizing it to Form f. +func (i *Iter) Init(f Form, src []byte) { + i.p = 0 + if len(src) == 0 { + i.setDone() + i.rb.nsrc = 0 + return + } + i.multiSeg = nil + i.rb.init(f, src) + i.next = i.rb.f.nextMain + i.asciiF = nextASCIIBytes + i.info = i.rb.f.info(i.rb.src, i.p) + i.rb.ss.first(i.info) +} + +// InitString initializes i to iterate over src after normalizing it to Form f. +func (i *Iter) InitString(f Form, src string) { + i.p = 0 + if len(src) == 0 { + i.setDone() + i.rb.nsrc = 0 + return + } + i.multiSeg = nil + i.rb.initString(f, src) + i.next = i.rb.f.nextMain + i.asciiF = nextASCIIString + i.info = i.rb.f.info(i.rb.src, i.p) + i.rb.ss.first(i.info) +} + +// Seek sets the segment to be returned by the next call to Next to start +// at position p. It is the responsibility of the caller to set p to the +// start of a segment. +func (i *Iter) Seek(offset int64, whence int) (int64, error) { + var abs int64 + switch whence { + case 0: + abs = offset + case 1: + abs = int64(i.p) + offset + case 2: + abs = int64(i.rb.nsrc) + offset + default: + return 0, fmt.Errorf("norm: invalid whence") + } + if abs < 0 { + return 0, fmt.Errorf("norm: negative position") + } + if int(abs) >= i.rb.nsrc { + i.setDone() + return int64(i.p), nil + } + i.p = int(abs) + i.multiSeg = nil + i.next = i.rb.f.nextMain + i.info = i.rb.f.info(i.rb.src, i.p) + i.rb.ss.first(i.info) + return abs, nil +} + +// returnSlice returns a slice of the underlying input type as a byte slice. +// If the underlying is of type []byte, it will simply return a slice. +// If the underlying is of type string, it will copy the slice to the buffer +// and return that. +func (i *Iter) returnSlice(a, b int) []byte { + if i.rb.src.bytes == nil { + return i.buf[:copy(i.buf[:], i.rb.src.str[a:b])] + } + return i.rb.src.bytes[a:b] +} + +// Pos returns the byte position at which the next call to Next will commence processing. +func (i *Iter) Pos() int { + return i.p +} + +func (i *Iter) setDone() { + i.next = nextDone + i.p = i.rb.nsrc +} + +// Done returns true if there is no more input to process. +func (i *Iter) Done() bool { + return i.p >= i.rb.nsrc +} + +// Next returns f(i.input[i.Pos():n]), where n is a boundary of i.input. +// For any input a and b for which f(a) == f(b), subsequent calls +// to Next will return the same segments. +// Modifying runes are grouped together with the preceding starter, if such a starter exists. +// Although not guaranteed, n will typically be the smallest possible n. +func (i *Iter) Next() []byte { + return i.next(i) +} + +func nextASCIIBytes(i *Iter) []byte { + p := i.p + 1 + if p >= i.rb.nsrc { + i.setDone() + return i.rb.src.bytes[i.p:p] + } + if i.rb.src.bytes[p] < utf8.RuneSelf { + p0 := i.p + i.p = p + return i.rb.src.bytes[p0:p] + } + i.info = i.rb.f.info(i.rb.src, i.p) + i.next = i.rb.f.nextMain + return i.next(i) +} + +func nextASCIIString(i *Iter) []byte { + p := i.p + 1 + if p >= i.rb.nsrc { + i.buf[0] = i.rb.src.str[i.p] + i.setDone() + return i.buf[:1] + } + if i.rb.src.str[p] < utf8.RuneSelf { + i.buf[0] = i.rb.src.str[i.p] + i.p = p + return i.buf[:1] + } + i.info = i.rb.f.info(i.rb.src, i.p) + i.next = i.rb.f.nextMain + return i.next(i) +} + +func nextHangul(i *Iter) []byte { + p := i.p + next := p + hangulUTF8Size + if next >= i.rb.nsrc { + i.setDone() + } else if i.rb.src.hangul(next) == 0 { + i.rb.ss.next(i.info) + i.info = i.rb.f.info(i.rb.src, i.p) + i.next = i.rb.f.nextMain + return i.next(i) + } + i.p = next + return i.buf[:decomposeHangul(i.buf[:], i.rb.src.hangul(p))] +} + +func nextDone(i *Iter) []byte { + return nil +} + +// nextMulti is used for iterating over multi-segment decompositions +// for decomposing normal forms. +func nextMulti(i *Iter) []byte { + j := 0 + d := i.multiSeg + // skip first rune + for j = 1; j < len(d) && !utf8.RuneStart(d[j]); j++ { + } + for j < len(d) { + info := i.rb.f.info(input{bytes: d}, j) + if info.BoundaryBefore() { + i.multiSeg = d[j:] + return d[:j] + } + j += int(info.size) + } + // treat last segment as normal decomposition + i.next = i.rb.f.nextMain + return i.next(i) +} + +// nextMultiNorm is used for iterating over multi-segment decompositions +// for composing normal forms. +func nextMultiNorm(i *Iter) []byte { + j := 0 + d := i.multiSeg + for j < len(d) { + info := i.rb.f.info(input{bytes: d}, j) + if info.BoundaryBefore() { + i.rb.compose() + seg := i.buf[:i.rb.flushCopy(i.buf[:])] + i.rb.insertUnsafe(input{bytes: d}, j, info) + i.multiSeg = d[j+int(info.size):] + return seg + } + i.rb.insertUnsafe(input{bytes: d}, j, info) + j += int(info.size) + } + i.multiSeg = nil + i.next = nextComposed + return doNormComposed(i) +} + +// nextDecomposed is the implementation of Next for forms NFD and NFKD. +func nextDecomposed(i *Iter) (next []byte) { + outp := 0 + inCopyStart, outCopyStart := i.p, 0 + for { + if sz := int(i.info.size); sz <= 1 { + i.rb.ss = 0 + p := i.p + i.p++ // ASCII or illegal byte. Either way, advance by 1. + if i.p >= i.rb.nsrc { + i.setDone() + return i.returnSlice(p, i.p) + } else if i.rb.src._byte(i.p) < utf8.RuneSelf { + i.next = i.asciiF + return i.returnSlice(p, i.p) + } + outp++ + } else if d := i.info.Decomposition(); d != nil { + // Note: If leading CCC != 0, then len(d) == 2 and last is also non-zero. + // Case 1: there is a leftover to copy. In this case the decomposition + // must begin with a modifier and should always be appended. + // Case 2: no leftover. Simply return d if followed by a ccc == 0 value. + p := outp + len(d) + if outp > 0 { + i.rb.src.copySlice(i.buf[outCopyStart:], inCopyStart, i.p) + // TODO: this condition should not be possible, but we leave it + // in for defensive purposes. + if p > len(i.buf) { + return i.buf[:outp] + } + } else if i.info.multiSegment() { + // outp must be 0 as multi-segment decompositions always + // start a new segment. + if i.multiSeg == nil { + i.multiSeg = d + i.next = nextMulti + return nextMulti(i) + } + // We are in the last segment. Treat as normal decomposition. + d = i.multiSeg + i.multiSeg = nil + p = len(d) + } + prevCC := i.info.tccc + if i.p += sz; i.p >= i.rb.nsrc { + i.setDone() + i.info = Properties{} // Force BoundaryBefore to succeed. + } else { + i.info = i.rb.f.info(i.rb.src, i.p) + } + switch i.rb.ss.next(i.info) { + case ssOverflow: + i.next = nextCGJDecompose + fallthrough + case ssStarter: + if outp > 0 { + copy(i.buf[outp:], d) + return i.buf[:p] + } + return d + } + copy(i.buf[outp:], d) + outp = p + inCopyStart, outCopyStart = i.p, outp + if i.info.ccc < prevCC { + goto doNorm + } + continue + } else if r := i.rb.src.hangul(i.p); r != 0 { + outp = decomposeHangul(i.buf[:], r) + i.p += hangulUTF8Size + inCopyStart, outCopyStart = i.p, outp + if i.p >= i.rb.nsrc { + i.setDone() + break + } else if i.rb.src.hangul(i.p) != 0 { + i.next = nextHangul + return i.buf[:outp] + } + } else { + p := outp + sz + if p > len(i.buf) { + break + } + outp = p + i.p += sz + } + if i.p >= i.rb.nsrc { + i.setDone() + break + } + prevCC := i.info.tccc + i.info = i.rb.f.info(i.rb.src, i.p) + if v := i.rb.ss.next(i.info); v == ssStarter { + break + } else if v == ssOverflow { + i.next = nextCGJDecompose + break + } + if i.info.ccc < prevCC { + goto doNorm + } + } + if outCopyStart == 0 { + return i.returnSlice(inCopyStart, i.p) + } else if inCopyStart < i.p { + i.rb.src.copySlice(i.buf[outCopyStart:], inCopyStart, i.p) + } + return i.buf[:outp] +doNorm: + // Insert what we have decomposed so far in the reorderBuffer. + // As we will only reorder, there will always be enough room. + i.rb.src.copySlice(i.buf[outCopyStart:], inCopyStart, i.p) + i.rb.insertDecomposed(i.buf[0:outp]) + return doNormDecomposed(i) +} + +func doNormDecomposed(i *Iter) []byte { + for { + i.rb.insertUnsafe(i.rb.src, i.p, i.info) + if i.p += int(i.info.size); i.p >= i.rb.nsrc { + i.setDone() + break + } + i.info = i.rb.f.info(i.rb.src, i.p) + if i.info.ccc == 0 { + break + } + if s := i.rb.ss.next(i.info); s == ssOverflow { + i.next = nextCGJDecompose + break + } + } + // new segment or too many combining characters: exit normalization + return i.buf[:i.rb.flushCopy(i.buf[:])] +} + +func nextCGJDecompose(i *Iter) []byte { + i.rb.ss = 0 + i.rb.insertCGJ() + i.next = nextDecomposed + i.rb.ss.first(i.info) + buf := doNormDecomposed(i) + return buf +} + +// nextComposed is the implementation of Next for forms NFC and NFKC. +func nextComposed(i *Iter) []byte { + outp, startp := 0, i.p + var prevCC uint8 + for { + if !i.info.isYesC() { + goto doNorm + } + prevCC = i.info.tccc + sz := int(i.info.size) + if sz == 0 { + sz = 1 // illegal rune: copy byte-by-byte + } + p := outp + sz + if p > len(i.buf) { + break + } + outp = p + i.p += sz + if i.p >= i.rb.nsrc { + i.setDone() + break + } else if i.rb.src._byte(i.p) < utf8.RuneSelf { + i.rb.ss = 0 + i.next = i.asciiF + break + } + i.info = i.rb.f.info(i.rb.src, i.p) + if v := i.rb.ss.next(i.info); v == ssStarter { + break + } else if v == ssOverflow { + i.next = nextCGJCompose + break + } + if i.info.ccc < prevCC { + goto doNorm + } + } + return i.returnSlice(startp, i.p) +doNorm: + // reset to start position + i.p = startp + i.info = i.rb.f.info(i.rb.src, i.p) + i.rb.ss.first(i.info) + if i.info.multiSegment() { + d := i.info.Decomposition() + info := i.rb.f.info(input{bytes: d}, 0) + i.rb.insertUnsafe(input{bytes: d}, 0, info) + i.multiSeg = d[int(info.size):] + i.next = nextMultiNorm + return nextMultiNorm(i) + } + i.rb.ss.first(i.info) + i.rb.insertUnsafe(i.rb.src, i.p, i.info) + return doNormComposed(i) +} + +func doNormComposed(i *Iter) []byte { + // First rune should already be inserted. + for { + if i.p += int(i.info.size); i.p >= i.rb.nsrc { + i.setDone() + break + } + i.info = i.rb.f.info(i.rb.src, i.p) + if s := i.rb.ss.next(i.info); s == ssStarter { + break + } else if s == ssOverflow { + i.next = nextCGJCompose + break + } + i.rb.insertUnsafe(i.rb.src, i.p, i.info) + } + i.rb.compose() + seg := i.buf[:i.rb.flushCopy(i.buf[:])] + return seg +} + +func nextCGJCompose(i *Iter) []byte { + i.rb.ss = 0 // instead of first + i.rb.insertCGJ() + i.next = nextComposed + // Note that we treat any rune with nLeadingNonStarters > 0 as a non-starter, + // even if they are not. This is particularly dubious for U+FF9E and UFF9A. + // If we ever change that, insert a check here. + i.rb.ss.first(i.info) + i.rb.insertUnsafe(i.rb.src, i.p, i.info) + return doNormComposed(i) +} diff --git a/vendor/golang.org/x/text/unicode/norm/normalize.go b/vendor/golang.org/x/text/unicode/norm/normalize.go new file mode 100644 index 0000000000..e28ac641ac --- /dev/null +++ b/vendor/golang.org/x/text/unicode/norm/normalize.go @@ -0,0 +1,609 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Note: the file data_test.go that is generated should not be checked in. +//go:generate go run maketables.go triegen.go +//go:generate go test -tags test + +// Package norm contains types and functions for normalizing Unicode strings. +package norm // import "golang.org/x/text/unicode/norm" + +import ( + "unicode/utf8" + + "golang.org/x/text/transform" +) + +// A Form denotes a canonical representation of Unicode code points. +// The Unicode-defined normalization and equivalence forms are: +// +// NFC Unicode Normalization Form C +// NFD Unicode Normalization Form D +// NFKC Unicode Normalization Form KC +// NFKD Unicode Normalization Form KD +// +// For a Form f, this documentation uses the notation f(x) to mean +// the bytes or string x converted to the given form. +// A position n in x is called a boundary if conversion to the form can +// proceed independently on both sides: +// f(x) == append(f(x[0:n]), f(x[n:])...) +// +// References: http://unicode.org/reports/tr15/ and +// http://unicode.org/notes/tn5/. +type Form int + +const ( + NFC Form = iota + NFD + NFKC + NFKD +) + +// Bytes returns f(b). May return b if f(b) = b. +func (f Form) Bytes(b []byte) []byte { + src := inputBytes(b) + ft := formTable[f] + n, ok := ft.quickSpan(src, 0, len(b), true) + if ok { + return b + } + out := make([]byte, n, len(b)) + copy(out, b[0:n]) + rb := reorderBuffer{f: *ft, src: src, nsrc: len(b), out: out, flushF: appendFlush} + return doAppendInner(&rb, n) +} + +// String returns f(s). +func (f Form) String(s string) string { + src := inputString(s) + ft := formTable[f] + n, ok := ft.quickSpan(src, 0, len(s), true) + if ok { + return s + } + out := make([]byte, n, len(s)) + copy(out, s[0:n]) + rb := reorderBuffer{f: *ft, src: src, nsrc: len(s), out: out, flushF: appendFlush} + return string(doAppendInner(&rb, n)) +} + +// IsNormal returns true if b == f(b). +func (f Form) IsNormal(b []byte) bool { + src := inputBytes(b) + ft := formTable[f] + bp, ok := ft.quickSpan(src, 0, len(b), true) + if ok { + return true + } + rb := reorderBuffer{f: *ft, src: src, nsrc: len(b)} + rb.setFlusher(nil, cmpNormalBytes) + for bp < len(b) { + rb.out = b[bp:] + if bp = decomposeSegment(&rb, bp, true); bp < 0 { + return false + } + bp, _ = rb.f.quickSpan(rb.src, bp, len(b), true) + } + return true +} + +func cmpNormalBytes(rb *reorderBuffer) bool { + b := rb.out + for i := 0; i < rb.nrune; i++ { + info := rb.rune[i] + if int(info.size) > len(b) { + return false + } + p := info.pos + pe := p + info.size + for ; p < pe; p++ { + if b[0] != rb.byte[p] { + return false + } + b = b[1:] + } + } + return true +} + +// IsNormalString returns true if s == f(s). +func (f Form) IsNormalString(s string) bool { + src := inputString(s) + ft := formTable[f] + bp, ok := ft.quickSpan(src, 0, len(s), true) + if ok { + return true + } + rb := reorderBuffer{f: *ft, src: src, nsrc: len(s)} + rb.setFlusher(nil, func(rb *reorderBuffer) bool { + for i := 0; i < rb.nrune; i++ { + info := rb.rune[i] + if bp+int(info.size) > len(s) { + return false + } + p := info.pos + pe := p + info.size + for ; p < pe; p++ { + if s[bp] != rb.byte[p] { + return false + } + bp++ + } + } + return true + }) + for bp < len(s) { + if bp = decomposeSegment(&rb, bp, true); bp < 0 { + return false + } + bp, _ = rb.f.quickSpan(rb.src, bp, len(s), true) + } + return true +} + +// patchTail fixes a case where a rune may be incorrectly normalized +// if it is followed by illegal continuation bytes. It returns the +// patched buffer and whether the decomposition is still in progress. +func patchTail(rb *reorderBuffer) bool { + info, p := lastRuneStart(&rb.f, rb.out) + if p == -1 || info.size == 0 { + return true + } + end := p + int(info.size) + extra := len(rb.out) - end + if extra > 0 { + // Potentially allocating memory. However, this only + // happens with ill-formed UTF-8. + x := make([]byte, 0) + x = append(x, rb.out[len(rb.out)-extra:]...) + rb.out = rb.out[:end] + decomposeToLastBoundary(rb) + rb.doFlush() + rb.out = append(rb.out, x...) + return false + } + buf := rb.out[p:] + rb.out = rb.out[:p] + decomposeToLastBoundary(rb) + if s := rb.ss.next(info); s == ssStarter { + rb.doFlush() + rb.ss.first(info) + } else if s == ssOverflow { + rb.doFlush() + rb.insertCGJ() + rb.ss = 0 + } + rb.insertUnsafe(inputBytes(buf), 0, info) + return true +} + +func appendQuick(rb *reorderBuffer, i int) int { + if rb.nsrc == i { + return i + } + end, _ := rb.f.quickSpan(rb.src, i, rb.nsrc, true) + rb.out = rb.src.appendSlice(rb.out, i, end) + return end +} + +// Append returns f(append(out, b...)). +// The buffer out must be nil, empty, or equal to f(out). +func (f Form) Append(out []byte, src ...byte) []byte { + return f.doAppend(out, inputBytes(src), len(src)) +} + +func (f Form) doAppend(out []byte, src input, n int) []byte { + if n == 0 { + return out + } + ft := formTable[f] + // Attempt to do a quickSpan first so we can avoid initializing the reorderBuffer. + if len(out) == 0 { + p, _ := ft.quickSpan(src, 0, n, true) + out = src.appendSlice(out, 0, p) + if p == n { + return out + } + rb := reorderBuffer{f: *ft, src: src, nsrc: n, out: out, flushF: appendFlush} + return doAppendInner(&rb, p) + } + rb := reorderBuffer{f: *ft, src: src, nsrc: n} + return doAppend(&rb, out, 0) +} + +func doAppend(rb *reorderBuffer, out []byte, p int) []byte { + rb.setFlusher(out, appendFlush) + src, n := rb.src, rb.nsrc + doMerge := len(out) > 0 + if q := src.skipContinuationBytes(p); q > p { + // Move leading non-starters to destination. + rb.out = src.appendSlice(rb.out, p, q) + p = q + doMerge = patchTail(rb) + } + fd := &rb.f + if doMerge { + var info Properties + if p < n { + info = fd.info(src, p) + if !info.BoundaryBefore() || info.nLeadingNonStarters() > 0 { + if p == 0 { + decomposeToLastBoundary(rb) + } + p = decomposeSegment(rb, p, true) + } + } + if info.size == 0 { + rb.doFlush() + // Append incomplete UTF-8 encoding. + return src.appendSlice(rb.out, p, n) + } + if rb.nrune > 0 { + return doAppendInner(rb, p) + } + } + p = appendQuick(rb, p) + return doAppendInner(rb, p) +} + +func doAppendInner(rb *reorderBuffer, p int) []byte { + for n := rb.nsrc; p < n; { + p = decomposeSegment(rb, p, true) + p = appendQuick(rb, p) + } + return rb.out +} + +// AppendString returns f(append(out, []byte(s))). +// The buffer out must be nil, empty, or equal to f(out). +func (f Form) AppendString(out []byte, src string) []byte { + return f.doAppend(out, inputString(src), len(src)) +} + +// QuickSpan returns a boundary n such that b[0:n] == f(b[0:n]). +// It is not guaranteed to return the largest such n. +func (f Form) QuickSpan(b []byte) int { + n, _ := formTable[f].quickSpan(inputBytes(b), 0, len(b), true) + return n +} + +// Span implements transform.SpanningTransformer. It returns a boundary n such +// that b[0:n] == f(b[0:n]). It is not guaranteed to return the largest such n. +func (f Form) Span(b []byte, atEOF bool) (n int, err error) { + n, ok := formTable[f].quickSpan(inputBytes(b), 0, len(b), atEOF) + if n < len(b) { + if !ok { + err = transform.ErrEndOfSpan + } else { + err = transform.ErrShortSrc + } + } + return n, err +} + +// SpanString returns a boundary n such that s[0:n] == f(s[0:n]). +// It is not guaranteed to return the largest such n. +func (f Form) SpanString(s string, atEOF bool) (n int, err error) { + n, ok := formTable[f].quickSpan(inputString(s), 0, len(s), atEOF) + if n < len(s) { + if !ok { + err = transform.ErrEndOfSpan + } else { + err = transform.ErrShortSrc + } + } + return n, err +} + +// quickSpan returns a boundary n such that src[0:n] == f(src[0:n]) and +// whether any non-normalized parts were found. If atEOF is false, n will +// not point past the last segment if this segment might be become +// non-normalized by appending other runes. +func (f *formInfo) quickSpan(src input, i, end int, atEOF bool) (n int, ok bool) { + var lastCC uint8 + ss := streamSafe(0) + lastSegStart := i + for n = end; i < n; { + if j := src.skipASCII(i, n); i != j { + i = j + lastSegStart = i - 1 + lastCC = 0 + ss = 0 + continue + } + info := f.info(src, i) + if info.size == 0 { + if atEOF { + // include incomplete runes + return n, true + } + return lastSegStart, true + } + // This block needs to be before the next, because it is possible to + // have an overflow for runes that are starters (e.g. with U+FF9E). + switch ss.next(info) { + case ssStarter: + lastSegStart = i + case ssOverflow: + return lastSegStart, false + case ssSuccess: + if lastCC > info.ccc { + return lastSegStart, false + } + } + if f.composing { + if !info.isYesC() { + break + } + } else { + if !info.isYesD() { + break + } + } + lastCC = info.ccc + i += int(info.size) + } + if i == n { + if !atEOF { + n = lastSegStart + } + return n, true + } + return lastSegStart, false +} + +// QuickSpanString returns a boundary n such that s[0:n] == f(s[0:n]). +// It is not guaranteed to return the largest such n. +func (f Form) QuickSpanString(s string) int { + n, _ := formTable[f].quickSpan(inputString(s), 0, len(s), true) + return n +} + +// FirstBoundary returns the position i of the first boundary in b +// or -1 if b contains no boundary. +func (f Form) FirstBoundary(b []byte) int { + return f.firstBoundary(inputBytes(b), len(b)) +} + +func (f Form) firstBoundary(src input, nsrc int) int { + i := src.skipContinuationBytes(0) + if i >= nsrc { + return -1 + } + fd := formTable[f] + ss := streamSafe(0) + // We should call ss.first here, but we can't as the first rune is + // skipped already. This means FirstBoundary can't really determine + // CGJ insertion points correctly. Luckily it doesn't have to. + for { + info := fd.info(src, i) + if info.size == 0 { + return -1 + } + if s := ss.next(info); s != ssSuccess { + return i + } + i += int(info.size) + if i >= nsrc { + if !info.BoundaryAfter() && !ss.isMax() { + return -1 + } + return nsrc + } + } +} + +// FirstBoundaryInString returns the position i of the first boundary in s +// or -1 if s contains no boundary. +func (f Form) FirstBoundaryInString(s string) int { + return f.firstBoundary(inputString(s), len(s)) +} + +// NextBoundary reports the index of the boundary between the first and next +// segment in b or -1 if atEOF is false and there are not enough bytes to +// determine this boundary. +func (f Form) NextBoundary(b []byte, atEOF bool) int { + return f.nextBoundary(inputBytes(b), len(b), atEOF) +} + +// NextBoundaryInString reports the index of the boundary between the first and +// next segment in b or -1 if atEOF is false and there are not enough bytes to +// determine this boundary. +func (f Form) NextBoundaryInString(s string, atEOF bool) int { + return f.nextBoundary(inputString(s), len(s), atEOF) +} + +func (f Form) nextBoundary(src input, nsrc int, atEOF bool) int { + if nsrc == 0 { + if atEOF { + return 0 + } + return -1 + } + fd := formTable[f] + info := fd.info(src, 0) + if info.size == 0 { + if atEOF { + return 1 + } + return -1 + } + ss := streamSafe(0) + ss.first(info) + + for i := int(info.size); i < nsrc; i += int(info.size) { + info = fd.info(src, i) + if info.size == 0 { + if atEOF { + return i + } + return -1 + } + // TODO: Using streamSafe to determine the boundary isn't the same as + // using BoundaryBefore. Determine which should be used. + if s := ss.next(info); s != ssSuccess { + return i + } + } + if !atEOF && !info.BoundaryAfter() && !ss.isMax() { + return -1 + } + return nsrc +} + +// LastBoundary returns the position i of the last boundary in b +// or -1 if b contains no boundary. +func (f Form) LastBoundary(b []byte) int { + return lastBoundary(formTable[f], b) +} + +func lastBoundary(fd *formInfo, b []byte) int { + i := len(b) + info, p := lastRuneStart(fd, b) + if p == -1 { + return -1 + } + if info.size == 0 { // ends with incomplete rune + if p == 0 { // starts with incomplete rune + return -1 + } + i = p + info, p = lastRuneStart(fd, b[:i]) + if p == -1 { // incomplete UTF-8 encoding or non-starter bytes without a starter + return i + } + } + if p+int(info.size) != i { // trailing non-starter bytes: illegal UTF-8 + return i + } + if info.BoundaryAfter() { + return i + } + ss := streamSafe(0) + v := ss.backwards(info) + for i = p; i >= 0 && v != ssStarter; i = p { + info, p = lastRuneStart(fd, b[:i]) + if v = ss.backwards(info); v == ssOverflow { + break + } + if p+int(info.size) != i { + if p == -1 { // no boundary found + return -1 + } + return i // boundary after an illegal UTF-8 encoding + } + } + return i +} + +// decomposeSegment scans the first segment in src into rb. It inserts 0x034f +// (Grapheme Joiner) when it encounters a sequence of more than 30 non-starters +// and returns the number of bytes consumed from src or iShortDst or iShortSrc. +func decomposeSegment(rb *reorderBuffer, sp int, atEOF bool) int { + // Force one character to be consumed. + info := rb.f.info(rb.src, sp) + if info.size == 0 { + return 0 + } + if s := rb.ss.next(info); s == ssStarter { + // TODO: this could be removed if we don't support merging. + if rb.nrune > 0 { + goto end + } + } else if s == ssOverflow { + rb.insertCGJ() + goto end + } + if err := rb.insertFlush(rb.src, sp, info); err != iSuccess { + return int(err) + } + for { + sp += int(info.size) + if sp >= rb.nsrc { + if !atEOF && !info.BoundaryAfter() { + return int(iShortSrc) + } + break + } + info = rb.f.info(rb.src, sp) + if info.size == 0 { + if !atEOF { + return int(iShortSrc) + } + break + } + if s := rb.ss.next(info); s == ssStarter { + break + } else if s == ssOverflow { + rb.insertCGJ() + break + } + if err := rb.insertFlush(rb.src, sp, info); err != iSuccess { + return int(err) + } + } +end: + if !rb.doFlush() { + return int(iShortDst) + } + return sp +} + +// lastRuneStart returns the runeInfo and position of the last +// rune in buf or the zero runeInfo and -1 if no rune was found. +func lastRuneStart(fd *formInfo, buf []byte) (Properties, int) { + p := len(buf) - 1 + for ; p >= 0 && !utf8.RuneStart(buf[p]); p-- { + } + if p < 0 { + return Properties{}, -1 + } + return fd.info(inputBytes(buf), p), p +} + +// decomposeToLastBoundary finds an open segment at the end of the buffer +// and scans it into rb. Returns the buffer minus the last segment. +func decomposeToLastBoundary(rb *reorderBuffer) { + fd := &rb.f + info, i := lastRuneStart(fd, rb.out) + if int(info.size) != len(rb.out)-i { + // illegal trailing continuation bytes + return + } + if info.BoundaryAfter() { + return + } + var add [maxNonStarters + 1]Properties // stores runeInfo in reverse order + padd := 0 + ss := streamSafe(0) + p := len(rb.out) + for { + add[padd] = info + v := ss.backwards(info) + if v == ssOverflow { + // Note that if we have an overflow, it the string we are appending to + // is not correctly normalized. In this case the behavior is undefined. + break + } + padd++ + p -= int(info.size) + if v == ssStarter || p < 0 { + break + } + info, i = lastRuneStart(fd, rb.out[:p]) + if int(info.size) != p-i { + break + } + } + rb.ss = ss + // Copy bytes for insertion as we may need to overwrite rb.out. + var buf [maxBufferSize * utf8.UTFMax]byte + cp := buf[:copy(buf[:], rb.out[p:])] + rb.out = rb.out[:p] + for padd--; padd >= 0; padd-- { + info = add[padd] + rb.insertUnsafe(inputBytes(cp), 0, info) + cp = cp[info.size:] + } +} diff --git a/vendor/golang.org/x/text/unicode/norm/readwriter.go b/vendor/golang.org/x/text/unicode/norm/readwriter.go new file mode 100644 index 0000000000..d926ee903e --- /dev/null +++ b/vendor/golang.org/x/text/unicode/norm/readwriter.go @@ -0,0 +1,125 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package norm + +import "io" + +type normWriter struct { + rb reorderBuffer + w io.Writer + buf []byte +} + +// Write implements the standard write interface. If the last characters are +// not at a normalization boundary, the bytes will be buffered for the next +// write. The remaining bytes will be written on close. +func (w *normWriter) Write(data []byte) (n int, err error) { + // Process data in pieces to keep w.buf size bounded. + const chunk = 4000 + + for len(data) > 0 { + // Normalize into w.buf. + m := len(data) + if m > chunk { + m = chunk + } + w.rb.src = inputBytes(data[:m]) + w.rb.nsrc = m + w.buf = doAppend(&w.rb, w.buf, 0) + data = data[m:] + n += m + + // Write out complete prefix, save remainder. + // Note that lastBoundary looks back at most 31 runes. + i := lastBoundary(&w.rb.f, w.buf) + if i == -1 { + i = 0 + } + if i > 0 { + if _, err = w.w.Write(w.buf[:i]); err != nil { + break + } + bn := copy(w.buf, w.buf[i:]) + w.buf = w.buf[:bn] + } + } + return n, err +} + +// Close forces data that remains in the buffer to be written. +func (w *normWriter) Close() error { + if len(w.buf) > 0 { + _, err := w.w.Write(w.buf) + if err != nil { + return err + } + } + return nil +} + +// Writer returns a new writer that implements Write(b) +// by writing f(b) to w. The returned writer may use an +// an internal buffer to maintain state across Write calls. +// Calling its Close method writes any buffered data to w. +func (f Form) Writer(w io.Writer) io.WriteCloser { + wr := &normWriter{rb: reorderBuffer{}, w: w} + wr.rb.init(f, nil) + return wr +} + +type normReader struct { + rb reorderBuffer + r io.Reader + inbuf []byte + outbuf []byte + bufStart int + lastBoundary int + err error +} + +// Read implements the standard read interface. +func (r *normReader) Read(p []byte) (int, error) { + for { + if r.lastBoundary-r.bufStart > 0 { + n := copy(p, r.outbuf[r.bufStart:r.lastBoundary]) + r.bufStart += n + if r.lastBoundary-r.bufStart > 0 { + return n, nil + } + return n, r.err + } + if r.err != nil { + return 0, r.err + } + outn := copy(r.outbuf, r.outbuf[r.lastBoundary:]) + r.outbuf = r.outbuf[0:outn] + r.bufStart = 0 + + n, err := r.r.Read(r.inbuf) + r.rb.src = inputBytes(r.inbuf[0:n]) + r.rb.nsrc, r.err = n, err + if n > 0 { + r.outbuf = doAppend(&r.rb, r.outbuf, 0) + } + if err == io.EOF { + r.lastBoundary = len(r.outbuf) + } else { + r.lastBoundary = lastBoundary(&r.rb.f, r.outbuf) + if r.lastBoundary == -1 { + r.lastBoundary = 0 + } + } + } +} + +// Reader returns a new reader that implements Read +// by reading data from r and returning f(data). +func (f Form) Reader(r io.Reader) io.Reader { + const chunk = 4000 + buf := make([]byte, chunk) + rr := &normReader{rb: reorderBuffer{}, r: r, inbuf: buf} + rr.rb.init(f, buf) + return rr +} diff --git a/vendor/golang.org/x/text/unicode/norm/tables10.0.0.go b/vendor/golang.org/x/text/unicode/norm/tables10.0.0.go new file mode 100644 index 0000000000..44dd3978ca --- /dev/null +++ b/vendor/golang.org/x/text/unicode/norm/tables10.0.0.go @@ -0,0 +1,7653 @@ +// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. + +// +build go1.10 + +package norm + +const ( + // Version is the Unicode edition from which the tables are derived. + Version = "10.0.0" + + // MaxTransformChunkSize indicates the maximum number of bytes that Transform + // may need to write atomically for any Form. Making a destination buffer at + // least this size ensures that Transform can always make progress and that + // the user does not need to grow the buffer on an ErrShortDst. + MaxTransformChunkSize = 35 + maxNonStarters*4 +) + +var ccc = [55]uint8{ + 0, 1, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 24, 25, 26, 27, 28, + 29, 30, 31, 32, 33, 34, 35, 36, + 84, 91, 103, 107, 118, 122, 129, 130, + 132, 202, 214, 216, 218, 220, 222, 224, + 226, 228, 230, 232, 233, 234, 240, +} + +const ( + firstMulti = 0x186D + firstCCC = 0x2C9E + endMulti = 0x2F60 + firstLeadingCCC = 0x49AE + firstCCCZeroExcept = 0x4A78 + firstStarterWithNLead = 0x4A9F + lastDecomp = 0x4AA1 + maxDecomp = 0x8000 +) + +// decomps: 19105 bytes +var decomps = [...]byte{ + // Bytes 0 - 3f + 0x00, 0x41, 0x20, 0x41, 0x21, 0x41, 0x22, 0x41, + 0x23, 0x41, 0x24, 0x41, 0x25, 0x41, 0x26, 0x41, + 0x27, 0x41, 0x28, 0x41, 0x29, 0x41, 0x2A, 0x41, + 0x2B, 0x41, 0x2C, 0x41, 0x2D, 0x41, 0x2E, 0x41, + 0x2F, 0x41, 0x30, 0x41, 0x31, 0x41, 0x32, 0x41, + 0x33, 0x41, 0x34, 0x41, 0x35, 0x41, 0x36, 0x41, + 0x37, 0x41, 0x38, 0x41, 0x39, 0x41, 0x3A, 0x41, + 0x3B, 0x41, 0x3C, 0x41, 0x3D, 0x41, 0x3E, 0x41, + // Bytes 40 - 7f + 0x3F, 0x41, 0x40, 0x41, 0x41, 0x41, 0x42, 0x41, + 0x43, 0x41, 0x44, 0x41, 0x45, 0x41, 0x46, 0x41, + 0x47, 0x41, 0x48, 0x41, 0x49, 0x41, 0x4A, 0x41, + 0x4B, 0x41, 0x4C, 0x41, 0x4D, 0x41, 0x4E, 0x41, + 0x4F, 0x41, 0x50, 0x41, 0x51, 0x41, 0x52, 0x41, + 0x53, 0x41, 0x54, 0x41, 0x55, 0x41, 0x56, 0x41, + 0x57, 0x41, 0x58, 0x41, 0x59, 0x41, 0x5A, 0x41, + 0x5B, 0x41, 0x5C, 0x41, 0x5D, 0x41, 0x5E, 0x41, + // Bytes 80 - bf + 0x5F, 0x41, 0x60, 0x41, 0x61, 0x41, 0x62, 0x41, + 0x63, 0x41, 0x64, 0x41, 0x65, 0x41, 0x66, 0x41, + 0x67, 0x41, 0x68, 0x41, 0x69, 0x41, 0x6A, 0x41, + 0x6B, 0x41, 0x6C, 0x41, 0x6D, 0x41, 0x6E, 0x41, + 0x6F, 0x41, 0x70, 0x41, 0x71, 0x41, 0x72, 0x41, + 0x73, 0x41, 0x74, 0x41, 0x75, 0x41, 0x76, 0x41, + 0x77, 0x41, 0x78, 0x41, 0x79, 0x41, 0x7A, 0x41, + 0x7B, 0x41, 0x7C, 0x41, 0x7D, 0x41, 0x7E, 0x42, + // Bytes c0 - ff + 0xC2, 0xA2, 0x42, 0xC2, 0xA3, 0x42, 0xC2, 0xA5, + 0x42, 0xC2, 0xA6, 0x42, 0xC2, 0xAC, 0x42, 0xC2, + 0xB7, 0x42, 0xC3, 0x86, 0x42, 0xC3, 0xB0, 0x42, + 0xC4, 0xA6, 0x42, 0xC4, 0xA7, 0x42, 0xC4, 0xB1, + 0x42, 0xC5, 0x8B, 0x42, 0xC5, 0x93, 0x42, 0xC6, + 0x8E, 0x42, 0xC6, 0x90, 0x42, 0xC6, 0xAB, 0x42, + 0xC8, 0xA2, 0x42, 0xC8, 0xB7, 0x42, 0xC9, 0x90, + 0x42, 0xC9, 0x91, 0x42, 0xC9, 0x92, 0x42, 0xC9, + // Bytes 100 - 13f + 0x94, 0x42, 0xC9, 0x95, 0x42, 0xC9, 0x99, 0x42, + 0xC9, 0x9B, 0x42, 0xC9, 0x9C, 0x42, 0xC9, 0x9F, + 0x42, 0xC9, 0xA1, 0x42, 0xC9, 0xA3, 0x42, 0xC9, + 0xA5, 0x42, 0xC9, 0xA6, 0x42, 0xC9, 0xA8, 0x42, + 0xC9, 0xA9, 0x42, 0xC9, 0xAA, 0x42, 0xC9, 0xAB, + 0x42, 0xC9, 0xAD, 0x42, 0xC9, 0xAF, 0x42, 0xC9, + 0xB0, 0x42, 0xC9, 0xB1, 0x42, 0xC9, 0xB2, 0x42, + 0xC9, 0xB3, 0x42, 0xC9, 0xB4, 0x42, 0xC9, 0xB5, + // Bytes 140 - 17f + 0x42, 0xC9, 0xB8, 0x42, 0xC9, 0xB9, 0x42, 0xC9, + 0xBB, 0x42, 0xCA, 0x81, 0x42, 0xCA, 0x82, 0x42, + 0xCA, 0x83, 0x42, 0xCA, 0x89, 0x42, 0xCA, 0x8A, + 0x42, 0xCA, 0x8B, 0x42, 0xCA, 0x8C, 0x42, 0xCA, + 0x90, 0x42, 0xCA, 0x91, 0x42, 0xCA, 0x92, 0x42, + 0xCA, 0x95, 0x42, 0xCA, 0x9D, 0x42, 0xCA, 0x9F, + 0x42, 0xCA, 0xB9, 0x42, 0xCE, 0x91, 0x42, 0xCE, + 0x92, 0x42, 0xCE, 0x93, 0x42, 0xCE, 0x94, 0x42, + // Bytes 180 - 1bf + 0xCE, 0x95, 0x42, 0xCE, 0x96, 0x42, 0xCE, 0x97, + 0x42, 0xCE, 0x98, 0x42, 0xCE, 0x99, 0x42, 0xCE, + 0x9A, 0x42, 0xCE, 0x9B, 0x42, 0xCE, 0x9C, 0x42, + 0xCE, 0x9D, 0x42, 0xCE, 0x9E, 0x42, 0xCE, 0x9F, + 0x42, 0xCE, 0xA0, 0x42, 0xCE, 0xA1, 0x42, 0xCE, + 0xA3, 0x42, 0xCE, 0xA4, 0x42, 0xCE, 0xA5, 0x42, + 0xCE, 0xA6, 0x42, 0xCE, 0xA7, 0x42, 0xCE, 0xA8, + 0x42, 0xCE, 0xA9, 0x42, 0xCE, 0xB1, 0x42, 0xCE, + // Bytes 1c0 - 1ff + 0xB2, 0x42, 0xCE, 0xB3, 0x42, 0xCE, 0xB4, 0x42, + 0xCE, 0xB5, 0x42, 0xCE, 0xB6, 0x42, 0xCE, 0xB7, + 0x42, 0xCE, 0xB8, 0x42, 0xCE, 0xB9, 0x42, 0xCE, + 0xBA, 0x42, 0xCE, 0xBB, 0x42, 0xCE, 0xBC, 0x42, + 0xCE, 0xBD, 0x42, 0xCE, 0xBE, 0x42, 0xCE, 0xBF, + 0x42, 0xCF, 0x80, 0x42, 0xCF, 0x81, 0x42, 0xCF, + 0x82, 0x42, 0xCF, 0x83, 0x42, 0xCF, 0x84, 0x42, + 0xCF, 0x85, 0x42, 0xCF, 0x86, 0x42, 0xCF, 0x87, + // Bytes 200 - 23f + 0x42, 0xCF, 0x88, 0x42, 0xCF, 0x89, 0x42, 0xCF, + 0x9C, 0x42, 0xCF, 0x9D, 0x42, 0xD0, 0xBD, 0x42, + 0xD1, 0x8A, 0x42, 0xD1, 0x8C, 0x42, 0xD7, 0x90, + 0x42, 0xD7, 0x91, 0x42, 0xD7, 0x92, 0x42, 0xD7, + 0x93, 0x42, 0xD7, 0x94, 0x42, 0xD7, 0x9B, 0x42, + 0xD7, 0x9C, 0x42, 0xD7, 0x9D, 0x42, 0xD7, 0xA2, + 0x42, 0xD7, 0xA8, 0x42, 0xD7, 0xAA, 0x42, 0xD8, + 0xA1, 0x42, 0xD8, 0xA7, 0x42, 0xD8, 0xA8, 0x42, + // Bytes 240 - 27f + 0xD8, 0xA9, 0x42, 0xD8, 0xAA, 0x42, 0xD8, 0xAB, + 0x42, 0xD8, 0xAC, 0x42, 0xD8, 0xAD, 0x42, 0xD8, + 0xAE, 0x42, 0xD8, 0xAF, 0x42, 0xD8, 0xB0, 0x42, + 0xD8, 0xB1, 0x42, 0xD8, 0xB2, 0x42, 0xD8, 0xB3, + 0x42, 0xD8, 0xB4, 0x42, 0xD8, 0xB5, 0x42, 0xD8, + 0xB6, 0x42, 0xD8, 0xB7, 0x42, 0xD8, 0xB8, 0x42, + 0xD8, 0xB9, 0x42, 0xD8, 0xBA, 0x42, 0xD9, 0x81, + 0x42, 0xD9, 0x82, 0x42, 0xD9, 0x83, 0x42, 0xD9, + // Bytes 280 - 2bf + 0x84, 0x42, 0xD9, 0x85, 0x42, 0xD9, 0x86, 0x42, + 0xD9, 0x87, 0x42, 0xD9, 0x88, 0x42, 0xD9, 0x89, + 0x42, 0xD9, 0x8A, 0x42, 0xD9, 0xAE, 0x42, 0xD9, + 0xAF, 0x42, 0xD9, 0xB1, 0x42, 0xD9, 0xB9, 0x42, + 0xD9, 0xBA, 0x42, 0xD9, 0xBB, 0x42, 0xD9, 0xBE, + 0x42, 0xD9, 0xBF, 0x42, 0xDA, 0x80, 0x42, 0xDA, + 0x83, 0x42, 0xDA, 0x84, 0x42, 0xDA, 0x86, 0x42, + 0xDA, 0x87, 0x42, 0xDA, 0x88, 0x42, 0xDA, 0x8C, + // Bytes 2c0 - 2ff + 0x42, 0xDA, 0x8D, 0x42, 0xDA, 0x8E, 0x42, 0xDA, + 0x91, 0x42, 0xDA, 0x98, 0x42, 0xDA, 0xA1, 0x42, + 0xDA, 0xA4, 0x42, 0xDA, 0xA6, 0x42, 0xDA, 0xA9, + 0x42, 0xDA, 0xAD, 0x42, 0xDA, 0xAF, 0x42, 0xDA, + 0xB1, 0x42, 0xDA, 0xB3, 0x42, 0xDA, 0xBA, 0x42, + 0xDA, 0xBB, 0x42, 0xDA, 0xBE, 0x42, 0xDB, 0x81, + 0x42, 0xDB, 0x85, 0x42, 0xDB, 0x86, 0x42, 0xDB, + 0x87, 0x42, 0xDB, 0x88, 0x42, 0xDB, 0x89, 0x42, + // Bytes 300 - 33f + 0xDB, 0x8B, 0x42, 0xDB, 0x8C, 0x42, 0xDB, 0x90, + 0x42, 0xDB, 0x92, 0x43, 0xE0, 0xBC, 0x8B, 0x43, + 0xE1, 0x83, 0x9C, 0x43, 0xE1, 0x84, 0x80, 0x43, + 0xE1, 0x84, 0x81, 0x43, 0xE1, 0x84, 0x82, 0x43, + 0xE1, 0x84, 0x83, 0x43, 0xE1, 0x84, 0x84, 0x43, + 0xE1, 0x84, 0x85, 0x43, 0xE1, 0x84, 0x86, 0x43, + 0xE1, 0x84, 0x87, 0x43, 0xE1, 0x84, 0x88, 0x43, + 0xE1, 0x84, 0x89, 0x43, 0xE1, 0x84, 0x8A, 0x43, + // Bytes 340 - 37f + 0xE1, 0x84, 0x8B, 0x43, 0xE1, 0x84, 0x8C, 0x43, + 0xE1, 0x84, 0x8D, 0x43, 0xE1, 0x84, 0x8E, 0x43, + 0xE1, 0x84, 0x8F, 0x43, 0xE1, 0x84, 0x90, 0x43, + 0xE1, 0x84, 0x91, 0x43, 0xE1, 0x84, 0x92, 0x43, + 0xE1, 0x84, 0x94, 0x43, 0xE1, 0x84, 0x95, 0x43, + 0xE1, 0x84, 0x9A, 0x43, 0xE1, 0x84, 0x9C, 0x43, + 0xE1, 0x84, 0x9D, 0x43, 0xE1, 0x84, 0x9E, 0x43, + 0xE1, 0x84, 0xA0, 0x43, 0xE1, 0x84, 0xA1, 0x43, + // Bytes 380 - 3bf + 0xE1, 0x84, 0xA2, 0x43, 0xE1, 0x84, 0xA3, 0x43, + 0xE1, 0x84, 0xA7, 0x43, 0xE1, 0x84, 0xA9, 0x43, + 0xE1, 0x84, 0xAB, 0x43, 0xE1, 0x84, 0xAC, 0x43, + 0xE1, 0x84, 0xAD, 0x43, 0xE1, 0x84, 0xAE, 0x43, + 0xE1, 0x84, 0xAF, 0x43, 0xE1, 0x84, 0xB2, 0x43, + 0xE1, 0x84, 0xB6, 0x43, 0xE1, 0x85, 0x80, 0x43, + 0xE1, 0x85, 0x87, 0x43, 0xE1, 0x85, 0x8C, 0x43, + 0xE1, 0x85, 0x97, 0x43, 0xE1, 0x85, 0x98, 0x43, + // Bytes 3c0 - 3ff + 0xE1, 0x85, 0x99, 0x43, 0xE1, 0x85, 0xA0, 0x43, + 0xE1, 0x86, 0x84, 0x43, 0xE1, 0x86, 0x85, 0x43, + 0xE1, 0x86, 0x88, 0x43, 0xE1, 0x86, 0x91, 0x43, + 0xE1, 0x86, 0x92, 0x43, 0xE1, 0x86, 0x94, 0x43, + 0xE1, 0x86, 0x9E, 0x43, 0xE1, 0x86, 0xA1, 0x43, + 0xE1, 0x87, 0x87, 0x43, 0xE1, 0x87, 0x88, 0x43, + 0xE1, 0x87, 0x8C, 0x43, 0xE1, 0x87, 0x8E, 0x43, + 0xE1, 0x87, 0x93, 0x43, 0xE1, 0x87, 0x97, 0x43, + // Bytes 400 - 43f + 0xE1, 0x87, 0x99, 0x43, 0xE1, 0x87, 0x9D, 0x43, + 0xE1, 0x87, 0x9F, 0x43, 0xE1, 0x87, 0xB1, 0x43, + 0xE1, 0x87, 0xB2, 0x43, 0xE1, 0xB4, 0x82, 0x43, + 0xE1, 0xB4, 0x96, 0x43, 0xE1, 0xB4, 0x97, 0x43, + 0xE1, 0xB4, 0x9C, 0x43, 0xE1, 0xB4, 0x9D, 0x43, + 0xE1, 0xB4, 0xA5, 0x43, 0xE1, 0xB5, 0xBB, 0x43, + 0xE1, 0xB6, 0x85, 0x43, 0xE2, 0x80, 0x82, 0x43, + 0xE2, 0x80, 0x83, 0x43, 0xE2, 0x80, 0x90, 0x43, + // Bytes 440 - 47f + 0xE2, 0x80, 0x93, 0x43, 0xE2, 0x80, 0x94, 0x43, + 0xE2, 0x82, 0xA9, 0x43, 0xE2, 0x86, 0x90, 0x43, + 0xE2, 0x86, 0x91, 0x43, 0xE2, 0x86, 0x92, 0x43, + 0xE2, 0x86, 0x93, 0x43, 0xE2, 0x88, 0x82, 0x43, + 0xE2, 0x88, 0x87, 0x43, 0xE2, 0x88, 0x91, 0x43, + 0xE2, 0x88, 0x92, 0x43, 0xE2, 0x94, 0x82, 0x43, + 0xE2, 0x96, 0xA0, 0x43, 0xE2, 0x97, 0x8B, 0x43, + 0xE2, 0xA6, 0x85, 0x43, 0xE2, 0xA6, 0x86, 0x43, + // Bytes 480 - 4bf + 0xE2, 0xB5, 0xA1, 0x43, 0xE3, 0x80, 0x81, 0x43, + 0xE3, 0x80, 0x82, 0x43, 0xE3, 0x80, 0x88, 0x43, + 0xE3, 0x80, 0x89, 0x43, 0xE3, 0x80, 0x8A, 0x43, + 0xE3, 0x80, 0x8B, 0x43, 0xE3, 0x80, 0x8C, 0x43, + 0xE3, 0x80, 0x8D, 0x43, 0xE3, 0x80, 0x8E, 0x43, + 0xE3, 0x80, 0x8F, 0x43, 0xE3, 0x80, 0x90, 0x43, + 0xE3, 0x80, 0x91, 0x43, 0xE3, 0x80, 0x92, 0x43, + 0xE3, 0x80, 0x94, 0x43, 0xE3, 0x80, 0x95, 0x43, + // Bytes 4c0 - 4ff + 0xE3, 0x80, 0x96, 0x43, 0xE3, 0x80, 0x97, 0x43, + 0xE3, 0x82, 0xA1, 0x43, 0xE3, 0x82, 0xA2, 0x43, + 0xE3, 0x82, 0xA3, 0x43, 0xE3, 0x82, 0xA4, 0x43, + 0xE3, 0x82, 0xA5, 0x43, 0xE3, 0x82, 0xA6, 0x43, + 0xE3, 0x82, 0xA7, 0x43, 0xE3, 0x82, 0xA8, 0x43, + 0xE3, 0x82, 0xA9, 0x43, 0xE3, 0x82, 0xAA, 0x43, + 0xE3, 0x82, 0xAB, 0x43, 0xE3, 0x82, 0xAD, 0x43, + 0xE3, 0x82, 0xAF, 0x43, 0xE3, 0x82, 0xB1, 0x43, + // Bytes 500 - 53f + 0xE3, 0x82, 0xB3, 0x43, 0xE3, 0x82, 0xB5, 0x43, + 0xE3, 0x82, 0xB7, 0x43, 0xE3, 0x82, 0xB9, 0x43, + 0xE3, 0x82, 0xBB, 0x43, 0xE3, 0x82, 0xBD, 0x43, + 0xE3, 0x82, 0xBF, 0x43, 0xE3, 0x83, 0x81, 0x43, + 0xE3, 0x83, 0x83, 0x43, 0xE3, 0x83, 0x84, 0x43, + 0xE3, 0x83, 0x86, 0x43, 0xE3, 0x83, 0x88, 0x43, + 0xE3, 0x83, 0x8A, 0x43, 0xE3, 0x83, 0x8B, 0x43, + 0xE3, 0x83, 0x8C, 0x43, 0xE3, 0x83, 0x8D, 0x43, + // Bytes 540 - 57f + 0xE3, 0x83, 0x8E, 0x43, 0xE3, 0x83, 0x8F, 0x43, + 0xE3, 0x83, 0x92, 0x43, 0xE3, 0x83, 0x95, 0x43, + 0xE3, 0x83, 0x98, 0x43, 0xE3, 0x83, 0x9B, 0x43, + 0xE3, 0x83, 0x9E, 0x43, 0xE3, 0x83, 0x9F, 0x43, + 0xE3, 0x83, 0xA0, 0x43, 0xE3, 0x83, 0xA1, 0x43, + 0xE3, 0x83, 0xA2, 0x43, 0xE3, 0x83, 0xA3, 0x43, + 0xE3, 0x83, 0xA4, 0x43, 0xE3, 0x83, 0xA5, 0x43, + 0xE3, 0x83, 0xA6, 0x43, 0xE3, 0x83, 0xA7, 0x43, + // Bytes 580 - 5bf + 0xE3, 0x83, 0xA8, 0x43, 0xE3, 0x83, 0xA9, 0x43, + 0xE3, 0x83, 0xAA, 0x43, 0xE3, 0x83, 0xAB, 0x43, + 0xE3, 0x83, 0xAC, 0x43, 0xE3, 0x83, 0xAD, 0x43, + 0xE3, 0x83, 0xAF, 0x43, 0xE3, 0x83, 0xB0, 0x43, + 0xE3, 0x83, 0xB1, 0x43, 0xE3, 0x83, 0xB2, 0x43, + 0xE3, 0x83, 0xB3, 0x43, 0xE3, 0x83, 0xBB, 0x43, + 0xE3, 0x83, 0xBC, 0x43, 0xE3, 0x92, 0x9E, 0x43, + 0xE3, 0x92, 0xB9, 0x43, 0xE3, 0x92, 0xBB, 0x43, + // Bytes 5c0 - 5ff + 0xE3, 0x93, 0x9F, 0x43, 0xE3, 0x94, 0x95, 0x43, + 0xE3, 0x9B, 0xAE, 0x43, 0xE3, 0x9B, 0xBC, 0x43, + 0xE3, 0x9E, 0x81, 0x43, 0xE3, 0xA0, 0xAF, 0x43, + 0xE3, 0xA1, 0xA2, 0x43, 0xE3, 0xA1, 0xBC, 0x43, + 0xE3, 0xA3, 0x87, 0x43, 0xE3, 0xA3, 0xA3, 0x43, + 0xE3, 0xA4, 0x9C, 0x43, 0xE3, 0xA4, 0xBA, 0x43, + 0xE3, 0xA8, 0xAE, 0x43, 0xE3, 0xA9, 0xAC, 0x43, + 0xE3, 0xAB, 0xA4, 0x43, 0xE3, 0xAC, 0x88, 0x43, + // Bytes 600 - 63f + 0xE3, 0xAC, 0x99, 0x43, 0xE3, 0xAD, 0x89, 0x43, + 0xE3, 0xAE, 0x9D, 0x43, 0xE3, 0xB0, 0x98, 0x43, + 0xE3, 0xB1, 0x8E, 0x43, 0xE3, 0xB4, 0xB3, 0x43, + 0xE3, 0xB6, 0x96, 0x43, 0xE3, 0xBA, 0xAC, 0x43, + 0xE3, 0xBA, 0xB8, 0x43, 0xE3, 0xBC, 0x9B, 0x43, + 0xE3, 0xBF, 0xBC, 0x43, 0xE4, 0x80, 0x88, 0x43, + 0xE4, 0x80, 0x98, 0x43, 0xE4, 0x80, 0xB9, 0x43, + 0xE4, 0x81, 0x86, 0x43, 0xE4, 0x82, 0x96, 0x43, + // Bytes 640 - 67f + 0xE4, 0x83, 0xA3, 0x43, 0xE4, 0x84, 0xAF, 0x43, + 0xE4, 0x88, 0x82, 0x43, 0xE4, 0x88, 0xA7, 0x43, + 0xE4, 0x8A, 0xA0, 0x43, 0xE4, 0x8C, 0x81, 0x43, + 0xE4, 0x8C, 0xB4, 0x43, 0xE4, 0x8D, 0x99, 0x43, + 0xE4, 0x8F, 0x95, 0x43, 0xE4, 0x8F, 0x99, 0x43, + 0xE4, 0x90, 0x8B, 0x43, 0xE4, 0x91, 0xAB, 0x43, + 0xE4, 0x94, 0xAB, 0x43, 0xE4, 0x95, 0x9D, 0x43, + 0xE4, 0x95, 0xA1, 0x43, 0xE4, 0x95, 0xAB, 0x43, + // Bytes 680 - 6bf + 0xE4, 0x97, 0x97, 0x43, 0xE4, 0x97, 0xB9, 0x43, + 0xE4, 0x98, 0xB5, 0x43, 0xE4, 0x9A, 0xBE, 0x43, + 0xE4, 0x9B, 0x87, 0x43, 0xE4, 0xA6, 0x95, 0x43, + 0xE4, 0xA7, 0xA6, 0x43, 0xE4, 0xA9, 0xAE, 0x43, + 0xE4, 0xA9, 0xB6, 0x43, 0xE4, 0xAA, 0xB2, 0x43, + 0xE4, 0xAC, 0xB3, 0x43, 0xE4, 0xAF, 0x8E, 0x43, + 0xE4, 0xB3, 0x8E, 0x43, 0xE4, 0xB3, 0xAD, 0x43, + 0xE4, 0xB3, 0xB8, 0x43, 0xE4, 0xB5, 0x96, 0x43, + // Bytes 6c0 - 6ff + 0xE4, 0xB8, 0x80, 0x43, 0xE4, 0xB8, 0x81, 0x43, + 0xE4, 0xB8, 0x83, 0x43, 0xE4, 0xB8, 0x89, 0x43, + 0xE4, 0xB8, 0x8A, 0x43, 0xE4, 0xB8, 0x8B, 0x43, + 0xE4, 0xB8, 0x8D, 0x43, 0xE4, 0xB8, 0x99, 0x43, + 0xE4, 0xB8, 0xA6, 0x43, 0xE4, 0xB8, 0xA8, 0x43, + 0xE4, 0xB8, 0xAD, 0x43, 0xE4, 0xB8, 0xB2, 0x43, + 0xE4, 0xB8, 0xB6, 0x43, 0xE4, 0xB8, 0xB8, 0x43, + 0xE4, 0xB8, 0xB9, 0x43, 0xE4, 0xB8, 0xBD, 0x43, + // Bytes 700 - 73f + 0xE4, 0xB8, 0xBF, 0x43, 0xE4, 0xB9, 0x81, 0x43, + 0xE4, 0xB9, 0x99, 0x43, 0xE4, 0xB9, 0x9D, 0x43, + 0xE4, 0xBA, 0x82, 0x43, 0xE4, 0xBA, 0x85, 0x43, + 0xE4, 0xBA, 0x86, 0x43, 0xE4, 0xBA, 0x8C, 0x43, + 0xE4, 0xBA, 0x94, 0x43, 0xE4, 0xBA, 0xA0, 0x43, + 0xE4, 0xBA, 0xA4, 0x43, 0xE4, 0xBA, 0xAE, 0x43, + 0xE4, 0xBA, 0xBA, 0x43, 0xE4, 0xBB, 0x80, 0x43, + 0xE4, 0xBB, 0x8C, 0x43, 0xE4, 0xBB, 0xA4, 0x43, + // Bytes 740 - 77f + 0xE4, 0xBC, 0x81, 0x43, 0xE4, 0xBC, 0x91, 0x43, + 0xE4, 0xBD, 0xA0, 0x43, 0xE4, 0xBE, 0x80, 0x43, + 0xE4, 0xBE, 0x86, 0x43, 0xE4, 0xBE, 0x8B, 0x43, + 0xE4, 0xBE, 0xAE, 0x43, 0xE4, 0xBE, 0xBB, 0x43, + 0xE4, 0xBE, 0xBF, 0x43, 0xE5, 0x80, 0x82, 0x43, + 0xE5, 0x80, 0xAB, 0x43, 0xE5, 0x81, 0xBA, 0x43, + 0xE5, 0x82, 0x99, 0x43, 0xE5, 0x83, 0x8F, 0x43, + 0xE5, 0x83, 0x9A, 0x43, 0xE5, 0x83, 0xA7, 0x43, + // Bytes 780 - 7bf + 0xE5, 0x84, 0xAA, 0x43, 0xE5, 0x84, 0xBF, 0x43, + 0xE5, 0x85, 0x80, 0x43, 0xE5, 0x85, 0x85, 0x43, + 0xE5, 0x85, 0x8D, 0x43, 0xE5, 0x85, 0x94, 0x43, + 0xE5, 0x85, 0xA4, 0x43, 0xE5, 0x85, 0xA5, 0x43, + 0xE5, 0x85, 0xA7, 0x43, 0xE5, 0x85, 0xA8, 0x43, + 0xE5, 0x85, 0xA9, 0x43, 0xE5, 0x85, 0xAB, 0x43, + 0xE5, 0x85, 0xAD, 0x43, 0xE5, 0x85, 0xB7, 0x43, + 0xE5, 0x86, 0x80, 0x43, 0xE5, 0x86, 0x82, 0x43, + // Bytes 7c0 - 7ff + 0xE5, 0x86, 0x8D, 0x43, 0xE5, 0x86, 0x92, 0x43, + 0xE5, 0x86, 0x95, 0x43, 0xE5, 0x86, 0x96, 0x43, + 0xE5, 0x86, 0x97, 0x43, 0xE5, 0x86, 0x99, 0x43, + 0xE5, 0x86, 0xA4, 0x43, 0xE5, 0x86, 0xAB, 0x43, + 0xE5, 0x86, 0xAC, 0x43, 0xE5, 0x86, 0xB5, 0x43, + 0xE5, 0x86, 0xB7, 0x43, 0xE5, 0x87, 0x89, 0x43, + 0xE5, 0x87, 0x8C, 0x43, 0xE5, 0x87, 0x9C, 0x43, + 0xE5, 0x87, 0x9E, 0x43, 0xE5, 0x87, 0xA0, 0x43, + // Bytes 800 - 83f + 0xE5, 0x87, 0xB5, 0x43, 0xE5, 0x88, 0x80, 0x43, + 0xE5, 0x88, 0x83, 0x43, 0xE5, 0x88, 0x87, 0x43, + 0xE5, 0x88, 0x97, 0x43, 0xE5, 0x88, 0x9D, 0x43, + 0xE5, 0x88, 0xA9, 0x43, 0xE5, 0x88, 0xBA, 0x43, + 0xE5, 0x88, 0xBB, 0x43, 0xE5, 0x89, 0x86, 0x43, + 0xE5, 0x89, 0x8D, 0x43, 0xE5, 0x89, 0xB2, 0x43, + 0xE5, 0x89, 0xB7, 0x43, 0xE5, 0x8A, 0x89, 0x43, + 0xE5, 0x8A, 0x9B, 0x43, 0xE5, 0x8A, 0xA3, 0x43, + // Bytes 840 - 87f + 0xE5, 0x8A, 0xB3, 0x43, 0xE5, 0x8A, 0xB4, 0x43, + 0xE5, 0x8B, 0x87, 0x43, 0xE5, 0x8B, 0x89, 0x43, + 0xE5, 0x8B, 0x92, 0x43, 0xE5, 0x8B, 0x9E, 0x43, + 0xE5, 0x8B, 0xA4, 0x43, 0xE5, 0x8B, 0xB5, 0x43, + 0xE5, 0x8B, 0xB9, 0x43, 0xE5, 0x8B, 0xBA, 0x43, + 0xE5, 0x8C, 0x85, 0x43, 0xE5, 0x8C, 0x86, 0x43, + 0xE5, 0x8C, 0x95, 0x43, 0xE5, 0x8C, 0x97, 0x43, + 0xE5, 0x8C, 0x9A, 0x43, 0xE5, 0x8C, 0xB8, 0x43, + // Bytes 880 - 8bf + 0xE5, 0x8C, 0xBB, 0x43, 0xE5, 0x8C, 0xBF, 0x43, + 0xE5, 0x8D, 0x81, 0x43, 0xE5, 0x8D, 0x84, 0x43, + 0xE5, 0x8D, 0x85, 0x43, 0xE5, 0x8D, 0x89, 0x43, + 0xE5, 0x8D, 0x91, 0x43, 0xE5, 0x8D, 0x94, 0x43, + 0xE5, 0x8D, 0x9A, 0x43, 0xE5, 0x8D, 0x9C, 0x43, + 0xE5, 0x8D, 0xA9, 0x43, 0xE5, 0x8D, 0xB0, 0x43, + 0xE5, 0x8D, 0xB3, 0x43, 0xE5, 0x8D, 0xB5, 0x43, + 0xE5, 0x8D, 0xBD, 0x43, 0xE5, 0x8D, 0xBF, 0x43, + // Bytes 8c0 - 8ff + 0xE5, 0x8E, 0x82, 0x43, 0xE5, 0x8E, 0xB6, 0x43, + 0xE5, 0x8F, 0x83, 0x43, 0xE5, 0x8F, 0x88, 0x43, + 0xE5, 0x8F, 0x8A, 0x43, 0xE5, 0x8F, 0x8C, 0x43, + 0xE5, 0x8F, 0x9F, 0x43, 0xE5, 0x8F, 0xA3, 0x43, + 0xE5, 0x8F, 0xA5, 0x43, 0xE5, 0x8F, 0xAB, 0x43, + 0xE5, 0x8F, 0xAF, 0x43, 0xE5, 0x8F, 0xB1, 0x43, + 0xE5, 0x8F, 0xB3, 0x43, 0xE5, 0x90, 0x86, 0x43, + 0xE5, 0x90, 0x88, 0x43, 0xE5, 0x90, 0x8D, 0x43, + // Bytes 900 - 93f + 0xE5, 0x90, 0x8F, 0x43, 0xE5, 0x90, 0x9D, 0x43, + 0xE5, 0x90, 0xB8, 0x43, 0xE5, 0x90, 0xB9, 0x43, + 0xE5, 0x91, 0x82, 0x43, 0xE5, 0x91, 0x88, 0x43, + 0xE5, 0x91, 0xA8, 0x43, 0xE5, 0x92, 0x9E, 0x43, + 0xE5, 0x92, 0xA2, 0x43, 0xE5, 0x92, 0xBD, 0x43, + 0xE5, 0x93, 0xB6, 0x43, 0xE5, 0x94, 0x90, 0x43, + 0xE5, 0x95, 0x8F, 0x43, 0xE5, 0x95, 0x93, 0x43, + 0xE5, 0x95, 0x95, 0x43, 0xE5, 0x95, 0xA3, 0x43, + // Bytes 940 - 97f + 0xE5, 0x96, 0x84, 0x43, 0xE5, 0x96, 0x87, 0x43, + 0xE5, 0x96, 0x99, 0x43, 0xE5, 0x96, 0x9D, 0x43, + 0xE5, 0x96, 0xAB, 0x43, 0xE5, 0x96, 0xB3, 0x43, + 0xE5, 0x96, 0xB6, 0x43, 0xE5, 0x97, 0x80, 0x43, + 0xE5, 0x97, 0x82, 0x43, 0xE5, 0x97, 0xA2, 0x43, + 0xE5, 0x98, 0x86, 0x43, 0xE5, 0x99, 0x91, 0x43, + 0xE5, 0x99, 0xA8, 0x43, 0xE5, 0x99, 0xB4, 0x43, + 0xE5, 0x9B, 0x97, 0x43, 0xE5, 0x9B, 0x9B, 0x43, + // Bytes 980 - 9bf + 0xE5, 0x9B, 0xB9, 0x43, 0xE5, 0x9C, 0x96, 0x43, + 0xE5, 0x9C, 0x97, 0x43, 0xE5, 0x9C, 0x9F, 0x43, + 0xE5, 0x9C, 0xB0, 0x43, 0xE5, 0x9E, 0x8B, 0x43, + 0xE5, 0x9F, 0x8E, 0x43, 0xE5, 0x9F, 0xB4, 0x43, + 0xE5, 0xA0, 0x8D, 0x43, 0xE5, 0xA0, 0xB1, 0x43, + 0xE5, 0xA0, 0xB2, 0x43, 0xE5, 0xA1, 0x80, 0x43, + 0xE5, 0xA1, 0x9A, 0x43, 0xE5, 0xA1, 0x9E, 0x43, + 0xE5, 0xA2, 0xA8, 0x43, 0xE5, 0xA2, 0xAC, 0x43, + // Bytes 9c0 - 9ff + 0xE5, 0xA2, 0xB3, 0x43, 0xE5, 0xA3, 0x98, 0x43, + 0xE5, 0xA3, 0x9F, 0x43, 0xE5, 0xA3, 0xAB, 0x43, + 0xE5, 0xA3, 0xAE, 0x43, 0xE5, 0xA3, 0xB0, 0x43, + 0xE5, 0xA3, 0xB2, 0x43, 0xE5, 0xA3, 0xB7, 0x43, + 0xE5, 0xA4, 0x82, 0x43, 0xE5, 0xA4, 0x86, 0x43, + 0xE5, 0xA4, 0x8A, 0x43, 0xE5, 0xA4, 0x95, 0x43, + 0xE5, 0xA4, 0x9A, 0x43, 0xE5, 0xA4, 0x9C, 0x43, + 0xE5, 0xA4, 0xA2, 0x43, 0xE5, 0xA4, 0xA7, 0x43, + // Bytes a00 - a3f + 0xE5, 0xA4, 0xA9, 0x43, 0xE5, 0xA5, 0x84, 0x43, + 0xE5, 0xA5, 0x88, 0x43, 0xE5, 0xA5, 0x91, 0x43, + 0xE5, 0xA5, 0x94, 0x43, 0xE5, 0xA5, 0xA2, 0x43, + 0xE5, 0xA5, 0xB3, 0x43, 0xE5, 0xA7, 0x98, 0x43, + 0xE5, 0xA7, 0xAC, 0x43, 0xE5, 0xA8, 0x9B, 0x43, + 0xE5, 0xA8, 0xA7, 0x43, 0xE5, 0xA9, 0xA2, 0x43, + 0xE5, 0xA9, 0xA6, 0x43, 0xE5, 0xAA, 0xB5, 0x43, + 0xE5, 0xAC, 0x88, 0x43, 0xE5, 0xAC, 0xA8, 0x43, + // Bytes a40 - a7f + 0xE5, 0xAC, 0xBE, 0x43, 0xE5, 0xAD, 0x90, 0x43, + 0xE5, 0xAD, 0x97, 0x43, 0xE5, 0xAD, 0xA6, 0x43, + 0xE5, 0xAE, 0x80, 0x43, 0xE5, 0xAE, 0x85, 0x43, + 0xE5, 0xAE, 0x97, 0x43, 0xE5, 0xAF, 0x83, 0x43, + 0xE5, 0xAF, 0x98, 0x43, 0xE5, 0xAF, 0xA7, 0x43, + 0xE5, 0xAF, 0xAE, 0x43, 0xE5, 0xAF, 0xB3, 0x43, + 0xE5, 0xAF, 0xB8, 0x43, 0xE5, 0xAF, 0xBF, 0x43, + 0xE5, 0xB0, 0x86, 0x43, 0xE5, 0xB0, 0x8F, 0x43, + // Bytes a80 - abf + 0xE5, 0xB0, 0xA2, 0x43, 0xE5, 0xB0, 0xB8, 0x43, + 0xE5, 0xB0, 0xBF, 0x43, 0xE5, 0xB1, 0xA0, 0x43, + 0xE5, 0xB1, 0xA2, 0x43, 0xE5, 0xB1, 0xA4, 0x43, + 0xE5, 0xB1, 0xA5, 0x43, 0xE5, 0xB1, 0xAE, 0x43, + 0xE5, 0xB1, 0xB1, 0x43, 0xE5, 0xB2, 0x8D, 0x43, + 0xE5, 0xB3, 0x80, 0x43, 0xE5, 0xB4, 0x99, 0x43, + 0xE5, 0xB5, 0x83, 0x43, 0xE5, 0xB5, 0x90, 0x43, + 0xE5, 0xB5, 0xAB, 0x43, 0xE5, 0xB5, 0xAE, 0x43, + // Bytes ac0 - aff + 0xE5, 0xB5, 0xBC, 0x43, 0xE5, 0xB6, 0xB2, 0x43, + 0xE5, 0xB6, 0xBA, 0x43, 0xE5, 0xB7, 0x9B, 0x43, + 0xE5, 0xB7, 0xA1, 0x43, 0xE5, 0xB7, 0xA2, 0x43, + 0xE5, 0xB7, 0xA5, 0x43, 0xE5, 0xB7, 0xA6, 0x43, + 0xE5, 0xB7, 0xB1, 0x43, 0xE5, 0xB7, 0xBD, 0x43, + 0xE5, 0xB7, 0xBE, 0x43, 0xE5, 0xB8, 0xA8, 0x43, + 0xE5, 0xB8, 0xBD, 0x43, 0xE5, 0xB9, 0xA9, 0x43, + 0xE5, 0xB9, 0xB2, 0x43, 0xE5, 0xB9, 0xB4, 0x43, + // Bytes b00 - b3f + 0xE5, 0xB9, 0xBA, 0x43, 0xE5, 0xB9, 0xBC, 0x43, + 0xE5, 0xB9, 0xBF, 0x43, 0xE5, 0xBA, 0xA6, 0x43, + 0xE5, 0xBA, 0xB0, 0x43, 0xE5, 0xBA, 0xB3, 0x43, + 0xE5, 0xBA, 0xB6, 0x43, 0xE5, 0xBB, 0x89, 0x43, + 0xE5, 0xBB, 0x8A, 0x43, 0xE5, 0xBB, 0x92, 0x43, + 0xE5, 0xBB, 0x93, 0x43, 0xE5, 0xBB, 0x99, 0x43, + 0xE5, 0xBB, 0xAC, 0x43, 0xE5, 0xBB, 0xB4, 0x43, + 0xE5, 0xBB, 0xBE, 0x43, 0xE5, 0xBC, 0x84, 0x43, + // Bytes b40 - b7f + 0xE5, 0xBC, 0x8B, 0x43, 0xE5, 0xBC, 0x93, 0x43, + 0xE5, 0xBC, 0xA2, 0x43, 0xE5, 0xBD, 0x90, 0x43, + 0xE5, 0xBD, 0x93, 0x43, 0xE5, 0xBD, 0xA1, 0x43, + 0xE5, 0xBD, 0xA2, 0x43, 0xE5, 0xBD, 0xA9, 0x43, + 0xE5, 0xBD, 0xAB, 0x43, 0xE5, 0xBD, 0xB3, 0x43, + 0xE5, 0xBE, 0x8B, 0x43, 0xE5, 0xBE, 0x8C, 0x43, + 0xE5, 0xBE, 0x97, 0x43, 0xE5, 0xBE, 0x9A, 0x43, + 0xE5, 0xBE, 0xA9, 0x43, 0xE5, 0xBE, 0xAD, 0x43, + // Bytes b80 - bbf + 0xE5, 0xBF, 0x83, 0x43, 0xE5, 0xBF, 0x8D, 0x43, + 0xE5, 0xBF, 0x97, 0x43, 0xE5, 0xBF, 0xB5, 0x43, + 0xE5, 0xBF, 0xB9, 0x43, 0xE6, 0x80, 0x92, 0x43, + 0xE6, 0x80, 0x9C, 0x43, 0xE6, 0x81, 0xB5, 0x43, + 0xE6, 0x82, 0x81, 0x43, 0xE6, 0x82, 0x94, 0x43, + 0xE6, 0x83, 0x87, 0x43, 0xE6, 0x83, 0x98, 0x43, + 0xE6, 0x83, 0xA1, 0x43, 0xE6, 0x84, 0x88, 0x43, + 0xE6, 0x85, 0x84, 0x43, 0xE6, 0x85, 0x88, 0x43, + // Bytes bc0 - bff + 0xE6, 0x85, 0x8C, 0x43, 0xE6, 0x85, 0x8E, 0x43, + 0xE6, 0x85, 0xA0, 0x43, 0xE6, 0x85, 0xA8, 0x43, + 0xE6, 0x85, 0xBA, 0x43, 0xE6, 0x86, 0x8E, 0x43, + 0xE6, 0x86, 0x90, 0x43, 0xE6, 0x86, 0xA4, 0x43, + 0xE6, 0x86, 0xAF, 0x43, 0xE6, 0x86, 0xB2, 0x43, + 0xE6, 0x87, 0x9E, 0x43, 0xE6, 0x87, 0xB2, 0x43, + 0xE6, 0x87, 0xB6, 0x43, 0xE6, 0x88, 0x80, 0x43, + 0xE6, 0x88, 0x88, 0x43, 0xE6, 0x88, 0x90, 0x43, + // Bytes c00 - c3f + 0xE6, 0x88, 0x9B, 0x43, 0xE6, 0x88, 0xAE, 0x43, + 0xE6, 0x88, 0xB4, 0x43, 0xE6, 0x88, 0xB6, 0x43, + 0xE6, 0x89, 0x8B, 0x43, 0xE6, 0x89, 0x93, 0x43, + 0xE6, 0x89, 0x9D, 0x43, 0xE6, 0x8A, 0x95, 0x43, + 0xE6, 0x8A, 0xB1, 0x43, 0xE6, 0x8B, 0x89, 0x43, + 0xE6, 0x8B, 0x8F, 0x43, 0xE6, 0x8B, 0x93, 0x43, + 0xE6, 0x8B, 0x94, 0x43, 0xE6, 0x8B, 0xBC, 0x43, + 0xE6, 0x8B, 0xBE, 0x43, 0xE6, 0x8C, 0x87, 0x43, + // Bytes c40 - c7f + 0xE6, 0x8C, 0xBD, 0x43, 0xE6, 0x8D, 0x90, 0x43, + 0xE6, 0x8D, 0x95, 0x43, 0xE6, 0x8D, 0xA8, 0x43, + 0xE6, 0x8D, 0xBB, 0x43, 0xE6, 0x8E, 0x83, 0x43, + 0xE6, 0x8E, 0xA0, 0x43, 0xE6, 0x8E, 0xA9, 0x43, + 0xE6, 0x8F, 0x84, 0x43, 0xE6, 0x8F, 0x85, 0x43, + 0xE6, 0x8F, 0xA4, 0x43, 0xE6, 0x90, 0x9C, 0x43, + 0xE6, 0x90, 0xA2, 0x43, 0xE6, 0x91, 0x92, 0x43, + 0xE6, 0x91, 0xA9, 0x43, 0xE6, 0x91, 0xB7, 0x43, + // Bytes c80 - cbf + 0xE6, 0x91, 0xBE, 0x43, 0xE6, 0x92, 0x9A, 0x43, + 0xE6, 0x92, 0x9D, 0x43, 0xE6, 0x93, 0x84, 0x43, + 0xE6, 0x94, 0xAF, 0x43, 0xE6, 0x94, 0xB4, 0x43, + 0xE6, 0x95, 0x8F, 0x43, 0xE6, 0x95, 0x96, 0x43, + 0xE6, 0x95, 0xAC, 0x43, 0xE6, 0x95, 0xB8, 0x43, + 0xE6, 0x96, 0x87, 0x43, 0xE6, 0x96, 0x97, 0x43, + 0xE6, 0x96, 0x99, 0x43, 0xE6, 0x96, 0xA4, 0x43, + 0xE6, 0x96, 0xB0, 0x43, 0xE6, 0x96, 0xB9, 0x43, + // Bytes cc0 - cff + 0xE6, 0x97, 0x85, 0x43, 0xE6, 0x97, 0xA0, 0x43, + 0xE6, 0x97, 0xA2, 0x43, 0xE6, 0x97, 0xA3, 0x43, + 0xE6, 0x97, 0xA5, 0x43, 0xE6, 0x98, 0x93, 0x43, + 0xE6, 0x98, 0xA0, 0x43, 0xE6, 0x99, 0x89, 0x43, + 0xE6, 0x99, 0xB4, 0x43, 0xE6, 0x9A, 0x88, 0x43, + 0xE6, 0x9A, 0x91, 0x43, 0xE6, 0x9A, 0x9C, 0x43, + 0xE6, 0x9A, 0xB4, 0x43, 0xE6, 0x9B, 0x86, 0x43, + 0xE6, 0x9B, 0xB0, 0x43, 0xE6, 0x9B, 0xB4, 0x43, + // Bytes d00 - d3f + 0xE6, 0x9B, 0xB8, 0x43, 0xE6, 0x9C, 0x80, 0x43, + 0xE6, 0x9C, 0x88, 0x43, 0xE6, 0x9C, 0x89, 0x43, + 0xE6, 0x9C, 0x97, 0x43, 0xE6, 0x9C, 0x9B, 0x43, + 0xE6, 0x9C, 0xA1, 0x43, 0xE6, 0x9C, 0xA8, 0x43, + 0xE6, 0x9D, 0x8E, 0x43, 0xE6, 0x9D, 0x93, 0x43, + 0xE6, 0x9D, 0x96, 0x43, 0xE6, 0x9D, 0x9E, 0x43, + 0xE6, 0x9D, 0xBB, 0x43, 0xE6, 0x9E, 0x85, 0x43, + 0xE6, 0x9E, 0x97, 0x43, 0xE6, 0x9F, 0xB3, 0x43, + // Bytes d40 - d7f + 0xE6, 0x9F, 0xBA, 0x43, 0xE6, 0xA0, 0x97, 0x43, + 0xE6, 0xA0, 0x9F, 0x43, 0xE6, 0xA0, 0xAA, 0x43, + 0xE6, 0xA1, 0x92, 0x43, 0xE6, 0xA2, 0x81, 0x43, + 0xE6, 0xA2, 0x85, 0x43, 0xE6, 0xA2, 0x8E, 0x43, + 0xE6, 0xA2, 0xA8, 0x43, 0xE6, 0xA4, 0x94, 0x43, + 0xE6, 0xA5, 0x82, 0x43, 0xE6, 0xA6, 0xA3, 0x43, + 0xE6, 0xA7, 0xAA, 0x43, 0xE6, 0xA8, 0x82, 0x43, + 0xE6, 0xA8, 0x93, 0x43, 0xE6, 0xAA, 0xA8, 0x43, + // Bytes d80 - dbf + 0xE6, 0xAB, 0x93, 0x43, 0xE6, 0xAB, 0x9B, 0x43, + 0xE6, 0xAC, 0x84, 0x43, 0xE6, 0xAC, 0xA0, 0x43, + 0xE6, 0xAC, 0xA1, 0x43, 0xE6, 0xAD, 0x94, 0x43, + 0xE6, 0xAD, 0xA2, 0x43, 0xE6, 0xAD, 0xA3, 0x43, + 0xE6, 0xAD, 0xB2, 0x43, 0xE6, 0xAD, 0xB7, 0x43, + 0xE6, 0xAD, 0xB9, 0x43, 0xE6, 0xAE, 0x9F, 0x43, + 0xE6, 0xAE, 0xAE, 0x43, 0xE6, 0xAE, 0xB3, 0x43, + 0xE6, 0xAE, 0xBA, 0x43, 0xE6, 0xAE, 0xBB, 0x43, + // Bytes dc0 - dff + 0xE6, 0xAF, 0x8B, 0x43, 0xE6, 0xAF, 0x8D, 0x43, + 0xE6, 0xAF, 0x94, 0x43, 0xE6, 0xAF, 0x9B, 0x43, + 0xE6, 0xB0, 0x8F, 0x43, 0xE6, 0xB0, 0x94, 0x43, + 0xE6, 0xB0, 0xB4, 0x43, 0xE6, 0xB1, 0x8E, 0x43, + 0xE6, 0xB1, 0xA7, 0x43, 0xE6, 0xB2, 0x88, 0x43, + 0xE6, 0xB2, 0xBF, 0x43, 0xE6, 0xB3, 0x8C, 0x43, + 0xE6, 0xB3, 0x8D, 0x43, 0xE6, 0xB3, 0xA5, 0x43, + 0xE6, 0xB3, 0xA8, 0x43, 0xE6, 0xB4, 0x96, 0x43, + // Bytes e00 - e3f + 0xE6, 0xB4, 0x9B, 0x43, 0xE6, 0xB4, 0x9E, 0x43, + 0xE6, 0xB4, 0xB4, 0x43, 0xE6, 0xB4, 0xBE, 0x43, + 0xE6, 0xB5, 0x81, 0x43, 0xE6, 0xB5, 0xA9, 0x43, + 0xE6, 0xB5, 0xAA, 0x43, 0xE6, 0xB5, 0xB7, 0x43, + 0xE6, 0xB5, 0xB8, 0x43, 0xE6, 0xB6, 0x85, 0x43, + 0xE6, 0xB7, 0x8B, 0x43, 0xE6, 0xB7, 0x9A, 0x43, + 0xE6, 0xB7, 0xAA, 0x43, 0xE6, 0xB7, 0xB9, 0x43, + 0xE6, 0xB8, 0x9A, 0x43, 0xE6, 0xB8, 0xAF, 0x43, + // Bytes e40 - e7f + 0xE6, 0xB9, 0xAE, 0x43, 0xE6, 0xBA, 0x80, 0x43, + 0xE6, 0xBA, 0x9C, 0x43, 0xE6, 0xBA, 0xBA, 0x43, + 0xE6, 0xBB, 0x87, 0x43, 0xE6, 0xBB, 0x8B, 0x43, + 0xE6, 0xBB, 0x91, 0x43, 0xE6, 0xBB, 0x9B, 0x43, + 0xE6, 0xBC, 0x8F, 0x43, 0xE6, 0xBC, 0x94, 0x43, + 0xE6, 0xBC, 0xA2, 0x43, 0xE6, 0xBC, 0xA3, 0x43, + 0xE6, 0xBD, 0xAE, 0x43, 0xE6, 0xBF, 0x86, 0x43, + 0xE6, 0xBF, 0xAB, 0x43, 0xE6, 0xBF, 0xBE, 0x43, + // Bytes e80 - ebf + 0xE7, 0x80, 0x9B, 0x43, 0xE7, 0x80, 0x9E, 0x43, + 0xE7, 0x80, 0xB9, 0x43, 0xE7, 0x81, 0x8A, 0x43, + 0xE7, 0x81, 0xAB, 0x43, 0xE7, 0x81, 0xB0, 0x43, + 0xE7, 0x81, 0xB7, 0x43, 0xE7, 0x81, 0xBD, 0x43, + 0xE7, 0x82, 0x99, 0x43, 0xE7, 0x82, 0xAD, 0x43, + 0xE7, 0x83, 0x88, 0x43, 0xE7, 0x83, 0x99, 0x43, + 0xE7, 0x84, 0xA1, 0x43, 0xE7, 0x85, 0x85, 0x43, + 0xE7, 0x85, 0x89, 0x43, 0xE7, 0x85, 0xAE, 0x43, + // Bytes ec0 - eff + 0xE7, 0x86, 0x9C, 0x43, 0xE7, 0x87, 0x8E, 0x43, + 0xE7, 0x87, 0x90, 0x43, 0xE7, 0x88, 0x90, 0x43, + 0xE7, 0x88, 0x9B, 0x43, 0xE7, 0x88, 0xA8, 0x43, + 0xE7, 0x88, 0xAA, 0x43, 0xE7, 0x88, 0xAB, 0x43, + 0xE7, 0x88, 0xB5, 0x43, 0xE7, 0x88, 0xB6, 0x43, + 0xE7, 0x88, 0xBB, 0x43, 0xE7, 0x88, 0xBF, 0x43, + 0xE7, 0x89, 0x87, 0x43, 0xE7, 0x89, 0x90, 0x43, + 0xE7, 0x89, 0x99, 0x43, 0xE7, 0x89, 0x9B, 0x43, + // Bytes f00 - f3f + 0xE7, 0x89, 0xA2, 0x43, 0xE7, 0x89, 0xB9, 0x43, + 0xE7, 0x8A, 0x80, 0x43, 0xE7, 0x8A, 0x95, 0x43, + 0xE7, 0x8A, 0xAC, 0x43, 0xE7, 0x8A, 0xAF, 0x43, + 0xE7, 0x8B, 0x80, 0x43, 0xE7, 0x8B, 0xBC, 0x43, + 0xE7, 0x8C, 0xAA, 0x43, 0xE7, 0x8D, 0xB5, 0x43, + 0xE7, 0x8D, 0xBA, 0x43, 0xE7, 0x8E, 0x84, 0x43, + 0xE7, 0x8E, 0x87, 0x43, 0xE7, 0x8E, 0x89, 0x43, + 0xE7, 0x8E, 0x8B, 0x43, 0xE7, 0x8E, 0xA5, 0x43, + // Bytes f40 - f7f + 0xE7, 0x8E, 0xB2, 0x43, 0xE7, 0x8F, 0x9E, 0x43, + 0xE7, 0x90, 0x86, 0x43, 0xE7, 0x90, 0x89, 0x43, + 0xE7, 0x90, 0xA2, 0x43, 0xE7, 0x91, 0x87, 0x43, + 0xE7, 0x91, 0x9C, 0x43, 0xE7, 0x91, 0xA9, 0x43, + 0xE7, 0x91, 0xB1, 0x43, 0xE7, 0x92, 0x85, 0x43, + 0xE7, 0x92, 0x89, 0x43, 0xE7, 0x92, 0x98, 0x43, + 0xE7, 0x93, 0x8A, 0x43, 0xE7, 0x93, 0x9C, 0x43, + 0xE7, 0x93, 0xA6, 0x43, 0xE7, 0x94, 0x86, 0x43, + // Bytes f80 - fbf + 0xE7, 0x94, 0x98, 0x43, 0xE7, 0x94, 0x9F, 0x43, + 0xE7, 0x94, 0xA4, 0x43, 0xE7, 0x94, 0xA8, 0x43, + 0xE7, 0x94, 0xB0, 0x43, 0xE7, 0x94, 0xB2, 0x43, + 0xE7, 0x94, 0xB3, 0x43, 0xE7, 0x94, 0xB7, 0x43, + 0xE7, 0x94, 0xBB, 0x43, 0xE7, 0x94, 0xBE, 0x43, + 0xE7, 0x95, 0x99, 0x43, 0xE7, 0x95, 0xA5, 0x43, + 0xE7, 0x95, 0xB0, 0x43, 0xE7, 0x96, 0x8B, 0x43, + 0xE7, 0x96, 0x92, 0x43, 0xE7, 0x97, 0xA2, 0x43, + // Bytes fc0 - fff + 0xE7, 0x98, 0x90, 0x43, 0xE7, 0x98, 0x9D, 0x43, + 0xE7, 0x98, 0x9F, 0x43, 0xE7, 0x99, 0x82, 0x43, + 0xE7, 0x99, 0xA9, 0x43, 0xE7, 0x99, 0xB6, 0x43, + 0xE7, 0x99, 0xBD, 0x43, 0xE7, 0x9A, 0xAE, 0x43, + 0xE7, 0x9A, 0xBF, 0x43, 0xE7, 0x9B, 0x8A, 0x43, + 0xE7, 0x9B, 0x9B, 0x43, 0xE7, 0x9B, 0xA3, 0x43, + 0xE7, 0x9B, 0xA7, 0x43, 0xE7, 0x9B, 0xAE, 0x43, + 0xE7, 0x9B, 0xB4, 0x43, 0xE7, 0x9C, 0x81, 0x43, + // Bytes 1000 - 103f + 0xE7, 0x9C, 0x9E, 0x43, 0xE7, 0x9C, 0x9F, 0x43, + 0xE7, 0x9D, 0x80, 0x43, 0xE7, 0x9D, 0x8A, 0x43, + 0xE7, 0x9E, 0x8B, 0x43, 0xE7, 0x9E, 0xA7, 0x43, + 0xE7, 0x9F, 0x9B, 0x43, 0xE7, 0x9F, 0xA2, 0x43, + 0xE7, 0x9F, 0xB3, 0x43, 0xE7, 0xA1, 0x8E, 0x43, + 0xE7, 0xA1, 0xAB, 0x43, 0xE7, 0xA2, 0x8C, 0x43, + 0xE7, 0xA2, 0x91, 0x43, 0xE7, 0xA3, 0x8A, 0x43, + 0xE7, 0xA3, 0x8C, 0x43, 0xE7, 0xA3, 0xBB, 0x43, + // Bytes 1040 - 107f + 0xE7, 0xA4, 0xAA, 0x43, 0xE7, 0xA4, 0xBA, 0x43, + 0xE7, 0xA4, 0xBC, 0x43, 0xE7, 0xA4, 0xBE, 0x43, + 0xE7, 0xA5, 0x88, 0x43, 0xE7, 0xA5, 0x89, 0x43, + 0xE7, 0xA5, 0x90, 0x43, 0xE7, 0xA5, 0x96, 0x43, + 0xE7, 0xA5, 0x9D, 0x43, 0xE7, 0xA5, 0x9E, 0x43, + 0xE7, 0xA5, 0xA5, 0x43, 0xE7, 0xA5, 0xBF, 0x43, + 0xE7, 0xA6, 0x81, 0x43, 0xE7, 0xA6, 0x8D, 0x43, + 0xE7, 0xA6, 0x8E, 0x43, 0xE7, 0xA6, 0x8F, 0x43, + // Bytes 1080 - 10bf + 0xE7, 0xA6, 0xAE, 0x43, 0xE7, 0xA6, 0xB8, 0x43, + 0xE7, 0xA6, 0xBE, 0x43, 0xE7, 0xA7, 0x8A, 0x43, + 0xE7, 0xA7, 0x98, 0x43, 0xE7, 0xA7, 0xAB, 0x43, + 0xE7, 0xA8, 0x9C, 0x43, 0xE7, 0xA9, 0x80, 0x43, + 0xE7, 0xA9, 0x8A, 0x43, 0xE7, 0xA9, 0x8F, 0x43, + 0xE7, 0xA9, 0xB4, 0x43, 0xE7, 0xA9, 0xBA, 0x43, + 0xE7, 0xAA, 0x81, 0x43, 0xE7, 0xAA, 0xB1, 0x43, + 0xE7, 0xAB, 0x8B, 0x43, 0xE7, 0xAB, 0xAE, 0x43, + // Bytes 10c0 - 10ff + 0xE7, 0xAB, 0xB9, 0x43, 0xE7, 0xAC, 0xA0, 0x43, + 0xE7, 0xAE, 0x8F, 0x43, 0xE7, 0xAF, 0x80, 0x43, + 0xE7, 0xAF, 0x86, 0x43, 0xE7, 0xAF, 0x89, 0x43, + 0xE7, 0xB0, 0xBE, 0x43, 0xE7, 0xB1, 0xA0, 0x43, + 0xE7, 0xB1, 0xB3, 0x43, 0xE7, 0xB1, 0xBB, 0x43, + 0xE7, 0xB2, 0x92, 0x43, 0xE7, 0xB2, 0xBE, 0x43, + 0xE7, 0xB3, 0x92, 0x43, 0xE7, 0xB3, 0x96, 0x43, + 0xE7, 0xB3, 0xA3, 0x43, 0xE7, 0xB3, 0xA7, 0x43, + // Bytes 1100 - 113f + 0xE7, 0xB3, 0xA8, 0x43, 0xE7, 0xB3, 0xB8, 0x43, + 0xE7, 0xB4, 0x80, 0x43, 0xE7, 0xB4, 0x90, 0x43, + 0xE7, 0xB4, 0xA2, 0x43, 0xE7, 0xB4, 0xAF, 0x43, + 0xE7, 0xB5, 0x82, 0x43, 0xE7, 0xB5, 0x9B, 0x43, + 0xE7, 0xB5, 0xA3, 0x43, 0xE7, 0xB6, 0xA0, 0x43, + 0xE7, 0xB6, 0xBE, 0x43, 0xE7, 0xB7, 0x87, 0x43, + 0xE7, 0xB7, 0xB4, 0x43, 0xE7, 0xB8, 0x82, 0x43, + 0xE7, 0xB8, 0x89, 0x43, 0xE7, 0xB8, 0xB7, 0x43, + // Bytes 1140 - 117f + 0xE7, 0xB9, 0x81, 0x43, 0xE7, 0xB9, 0x85, 0x43, + 0xE7, 0xBC, 0xB6, 0x43, 0xE7, 0xBC, 0xBE, 0x43, + 0xE7, 0xBD, 0x91, 0x43, 0xE7, 0xBD, 0xB2, 0x43, + 0xE7, 0xBD, 0xB9, 0x43, 0xE7, 0xBD, 0xBA, 0x43, + 0xE7, 0xBE, 0x85, 0x43, 0xE7, 0xBE, 0x8A, 0x43, + 0xE7, 0xBE, 0x95, 0x43, 0xE7, 0xBE, 0x9A, 0x43, + 0xE7, 0xBE, 0xBD, 0x43, 0xE7, 0xBF, 0xBA, 0x43, + 0xE8, 0x80, 0x81, 0x43, 0xE8, 0x80, 0x85, 0x43, + // Bytes 1180 - 11bf + 0xE8, 0x80, 0x8C, 0x43, 0xE8, 0x80, 0x92, 0x43, + 0xE8, 0x80, 0xB3, 0x43, 0xE8, 0x81, 0x86, 0x43, + 0xE8, 0x81, 0xA0, 0x43, 0xE8, 0x81, 0xAF, 0x43, + 0xE8, 0x81, 0xB0, 0x43, 0xE8, 0x81, 0xBE, 0x43, + 0xE8, 0x81, 0xBF, 0x43, 0xE8, 0x82, 0x89, 0x43, + 0xE8, 0x82, 0x8B, 0x43, 0xE8, 0x82, 0xAD, 0x43, + 0xE8, 0x82, 0xB2, 0x43, 0xE8, 0x84, 0x83, 0x43, + 0xE8, 0x84, 0xBE, 0x43, 0xE8, 0x87, 0x98, 0x43, + // Bytes 11c0 - 11ff + 0xE8, 0x87, 0xA3, 0x43, 0xE8, 0x87, 0xA8, 0x43, + 0xE8, 0x87, 0xAA, 0x43, 0xE8, 0x87, 0xAD, 0x43, + 0xE8, 0x87, 0xB3, 0x43, 0xE8, 0x87, 0xBC, 0x43, + 0xE8, 0x88, 0x81, 0x43, 0xE8, 0x88, 0x84, 0x43, + 0xE8, 0x88, 0x8C, 0x43, 0xE8, 0x88, 0x98, 0x43, + 0xE8, 0x88, 0x9B, 0x43, 0xE8, 0x88, 0x9F, 0x43, + 0xE8, 0x89, 0xAE, 0x43, 0xE8, 0x89, 0xAF, 0x43, + 0xE8, 0x89, 0xB2, 0x43, 0xE8, 0x89, 0xB8, 0x43, + // Bytes 1200 - 123f + 0xE8, 0x89, 0xB9, 0x43, 0xE8, 0x8A, 0x8B, 0x43, + 0xE8, 0x8A, 0x91, 0x43, 0xE8, 0x8A, 0x9D, 0x43, + 0xE8, 0x8A, 0xB1, 0x43, 0xE8, 0x8A, 0xB3, 0x43, + 0xE8, 0x8A, 0xBD, 0x43, 0xE8, 0x8B, 0xA5, 0x43, + 0xE8, 0x8B, 0xA6, 0x43, 0xE8, 0x8C, 0x9D, 0x43, + 0xE8, 0x8C, 0xA3, 0x43, 0xE8, 0x8C, 0xB6, 0x43, + 0xE8, 0x8D, 0x92, 0x43, 0xE8, 0x8D, 0x93, 0x43, + 0xE8, 0x8D, 0xA3, 0x43, 0xE8, 0x8E, 0xAD, 0x43, + // Bytes 1240 - 127f + 0xE8, 0x8E, 0xBD, 0x43, 0xE8, 0x8F, 0x89, 0x43, + 0xE8, 0x8F, 0x8A, 0x43, 0xE8, 0x8F, 0x8C, 0x43, + 0xE8, 0x8F, 0x9C, 0x43, 0xE8, 0x8F, 0xA7, 0x43, + 0xE8, 0x8F, 0xAF, 0x43, 0xE8, 0x8F, 0xB1, 0x43, + 0xE8, 0x90, 0xBD, 0x43, 0xE8, 0x91, 0x89, 0x43, + 0xE8, 0x91, 0x97, 0x43, 0xE8, 0x93, 0xAE, 0x43, + 0xE8, 0x93, 0xB1, 0x43, 0xE8, 0x93, 0xB3, 0x43, + 0xE8, 0x93, 0xBC, 0x43, 0xE8, 0x94, 0x96, 0x43, + // Bytes 1280 - 12bf + 0xE8, 0x95, 0xA4, 0x43, 0xE8, 0x97, 0x8D, 0x43, + 0xE8, 0x97, 0xBA, 0x43, 0xE8, 0x98, 0x86, 0x43, + 0xE8, 0x98, 0x92, 0x43, 0xE8, 0x98, 0xAD, 0x43, + 0xE8, 0x98, 0xBF, 0x43, 0xE8, 0x99, 0x8D, 0x43, + 0xE8, 0x99, 0x90, 0x43, 0xE8, 0x99, 0x9C, 0x43, + 0xE8, 0x99, 0xA7, 0x43, 0xE8, 0x99, 0xA9, 0x43, + 0xE8, 0x99, 0xAB, 0x43, 0xE8, 0x9A, 0x88, 0x43, + 0xE8, 0x9A, 0xA9, 0x43, 0xE8, 0x9B, 0xA2, 0x43, + // Bytes 12c0 - 12ff + 0xE8, 0x9C, 0x8E, 0x43, 0xE8, 0x9C, 0xA8, 0x43, + 0xE8, 0x9D, 0xAB, 0x43, 0xE8, 0x9D, 0xB9, 0x43, + 0xE8, 0x9E, 0x86, 0x43, 0xE8, 0x9E, 0xBA, 0x43, + 0xE8, 0x9F, 0xA1, 0x43, 0xE8, 0xA0, 0x81, 0x43, + 0xE8, 0xA0, 0x9F, 0x43, 0xE8, 0xA1, 0x80, 0x43, + 0xE8, 0xA1, 0x8C, 0x43, 0xE8, 0xA1, 0xA0, 0x43, + 0xE8, 0xA1, 0xA3, 0x43, 0xE8, 0xA3, 0x82, 0x43, + 0xE8, 0xA3, 0x8F, 0x43, 0xE8, 0xA3, 0x97, 0x43, + // Bytes 1300 - 133f + 0xE8, 0xA3, 0x9E, 0x43, 0xE8, 0xA3, 0xA1, 0x43, + 0xE8, 0xA3, 0xB8, 0x43, 0xE8, 0xA3, 0xBA, 0x43, + 0xE8, 0xA4, 0x90, 0x43, 0xE8, 0xA5, 0x81, 0x43, + 0xE8, 0xA5, 0xA4, 0x43, 0xE8, 0xA5, 0xBE, 0x43, + 0xE8, 0xA6, 0x86, 0x43, 0xE8, 0xA6, 0x8B, 0x43, + 0xE8, 0xA6, 0x96, 0x43, 0xE8, 0xA7, 0x92, 0x43, + 0xE8, 0xA7, 0xA3, 0x43, 0xE8, 0xA8, 0x80, 0x43, + 0xE8, 0xAA, 0xA0, 0x43, 0xE8, 0xAA, 0xAA, 0x43, + // Bytes 1340 - 137f + 0xE8, 0xAA, 0xBF, 0x43, 0xE8, 0xAB, 0x8B, 0x43, + 0xE8, 0xAB, 0x92, 0x43, 0xE8, 0xAB, 0x96, 0x43, + 0xE8, 0xAB, 0xAD, 0x43, 0xE8, 0xAB, 0xB8, 0x43, + 0xE8, 0xAB, 0xBE, 0x43, 0xE8, 0xAC, 0x81, 0x43, + 0xE8, 0xAC, 0xB9, 0x43, 0xE8, 0xAD, 0x98, 0x43, + 0xE8, 0xAE, 0x80, 0x43, 0xE8, 0xAE, 0x8A, 0x43, + 0xE8, 0xB0, 0xB7, 0x43, 0xE8, 0xB1, 0x86, 0x43, + 0xE8, 0xB1, 0x88, 0x43, 0xE8, 0xB1, 0x95, 0x43, + // Bytes 1380 - 13bf + 0xE8, 0xB1, 0xB8, 0x43, 0xE8, 0xB2, 0x9D, 0x43, + 0xE8, 0xB2, 0xA1, 0x43, 0xE8, 0xB2, 0xA9, 0x43, + 0xE8, 0xB2, 0xAB, 0x43, 0xE8, 0xB3, 0x81, 0x43, + 0xE8, 0xB3, 0x82, 0x43, 0xE8, 0xB3, 0x87, 0x43, + 0xE8, 0xB3, 0x88, 0x43, 0xE8, 0xB3, 0x93, 0x43, + 0xE8, 0xB4, 0x88, 0x43, 0xE8, 0xB4, 0x9B, 0x43, + 0xE8, 0xB5, 0xA4, 0x43, 0xE8, 0xB5, 0xB0, 0x43, + 0xE8, 0xB5, 0xB7, 0x43, 0xE8, 0xB6, 0xB3, 0x43, + // Bytes 13c0 - 13ff + 0xE8, 0xB6, 0xBC, 0x43, 0xE8, 0xB7, 0x8B, 0x43, + 0xE8, 0xB7, 0xAF, 0x43, 0xE8, 0xB7, 0xB0, 0x43, + 0xE8, 0xBA, 0xAB, 0x43, 0xE8, 0xBB, 0x8A, 0x43, + 0xE8, 0xBB, 0x94, 0x43, 0xE8, 0xBC, 0xA6, 0x43, + 0xE8, 0xBC, 0xAA, 0x43, 0xE8, 0xBC, 0xB8, 0x43, + 0xE8, 0xBC, 0xBB, 0x43, 0xE8, 0xBD, 0xA2, 0x43, + 0xE8, 0xBE, 0x9B, 0x43, 0xE8, 0xBE, 0x9E, 0x43, + 0xE8, 0xBE, 0xB0, 0x43, 0xE8, 0xBE, 0xB5, 0x43, + // Bytes 1400 - 143f + 0xE8, 0xBE, 0xB6, 0x43, 0xE9, 0x80, 0xA3, 0x43, + 0xE9, 0x80, 0xB8, 0x43, 0xE9, 0x81, 0x8A, 0x43, + 0xE9, 0x81, 0xA9, 0x43, 0xE9, 0x81, 0xB2, 0x43, + 0xE9, 0x81, 0xBC, 0x43, 0xE9, 0x82, 0x8F, 0x43, + 0xE9, 0x82, 0x91, 0x43, 0xE9, 0x82, 0x94, 0x43, + 0xE9, 0x83, 0x8E, 0x43, 0xE9, 0x83, 0x9E, 0x43, + 0xE9, 0x83, 0xB1, 0x43, 0xE9, 0x83, 0xBD, 0x43, + 0xE9, 0x84, 0x91, 0x43, 0xE9, 0x84, 0x9B, 0x43, + // Bytes 1440 - 147f + 0xE9, 0x85, 0x89, 0x43, 0xE9, 0x85, 0x8D, 0x43, + 0xE9, 0x85, 0xAA, 0x43, 0xE9, 0x86, 0x99, 0x43, + 0xE9, 0x86, 0xB4, 0x43, 0xE9, 0x87, 0x86, 0x43, + 0xE9, 0x87, 0x8C, 0x43, 0xE9, 0x87, 0x8F, 0x43, + 0xE9, 0x87, 0x91, 0x43, 0xE9, 0x88, 0xB4, 0x43, + 0xE9, 0x88, 0xB8, 0x43, 0xE9, 0x89, 0xB6, 0x43, + 0xE9, 0x89, 0xBC, 0x43, 0xE9, 0x8B, 0x97, 0x43, + 0xE9, 0x8B, 0x98, 0x43, 0xE9, 0x8C, 0x84, 0x43, + // Bytes 1480 - 14bf + 0xE9, 0x8D, 0x8A, 0x43, 0xE9, 0x8F, 0xB9, 0x43, + 0xE9, 0x90, 0x95, 0x43, 0xE9, 0x95, 0xB7, 0x43, + 0xE9, 0x96, 0x80, 0x43, 0xE9, 0x96, 0x8B, 0x43, + 0xE9, 0x96, 0xAD, 0x43, 0xE9, 0x96, 0xB7, 0x43, + 0xE9, 0x98, 0x9C, 0x43, 0xE9, 0x98, 0xAE, 0x43, + 0xE9, 0x99, 0x8B, 0x43, 0xE9, 0x99, 0x8D, 0x43, + 0xE9, 0x99, 0xB5, 0x43, 0xE9, 0x99, 0xB8, 0x43, + 0xE9, 0x99, 0xBC, 0x43, 0xE9, 0x9A, 0x86, 0x43, + // Bytes 14c0 - 14ff + 0xE9, 0x9A, 0xA3, 0x43, 0xE9, 0x9A, 0xB6, 0x43, + 0xE9, 0x9A, 0xB7, 0x43, 0xE9, 0x9A, 0xB8, 0x43, + 0xE9, 0x9A, 0xB9, 0x43, 0xE9, 0x9B, 0x83, 0x43, + 0xE9, 0x9B, 0xA2, 0x43, 0xE9, 0x9B, 0xA3, 0x43, + 0xE9, 0x9B, 0xA8, 0x43, 0xE9, 0x9B, 0xB6, 0x43, + 0xE9, 0x9B, 0xB7, 0x43, 0xE9, 0x9C, 0xA3, 0x43, + 0xE9, 0x9C, 0xB2, 0x43, 0xE9, 0x9D, 0x88, 0x43, + 0xE9, 0x9D, 0x91, 0x43, 0xE9, 0x9D, 0x96, 0x43, + // Bytes 1500 - 153f + 0xE9, 0x9D, 0x9E, 0x43, 0xE9, 0x9D, 0xA2, 0x43, + 0xE9, 0x9D, 0xA9, 0x43, 0xE9, 0x9F, 0x8B, 0x43, + 0xE9, 0x9F, 0x9B, 0x43, 0xE9, 0x9F, 0xA0, 0x43, + 0xE9, 0x9F, 0xAD, 0x43, 0xE9, 0x9F, 0xB3, 0x43, + 0xE9, 0x9F, 0xBF, 0x43, 0xE9, 0xA0, 0x81, 0x43, + 0xE9, 0xA0, 0x85, 0x43, 0xE9, 0xA0, 0x8B, 0x43, + 0xE9, 0xA0, 0x98, 0x43, 0xE9, 0xA0, 0xA9, 0x43, + 0xE9, 0xA0, 0xBB, 0x43, 0xE9, 0xA1, 0x9E, 0x43, + // Bytes 1540 - 157f + 0xE9, 0xA2, 0xA8, 0x43, 0xE9, 0xA3, 0x9B, 0x43, + 0xE9, 0xA3, 0x9F, 0x43, 0xE9, 0xA3, 0xA2, 0x43, + 0xE9, 0xA3, 0xAF, 0x43, 0xE9, 0xA3, 0xBC, 0x43, + 0xE9, 0xA4, 0xA8, 0x43, 0xE9, 0xA4, 0xA9, 0x43, + 0xE9, 0xA6, 0x96, 0x43, 0xE9, 0xA6, 0x99, 0x43, + 0xE9, 0xA6, 0xA7, 0x43, 0xE9, 0xA6, 0xAC, 0x43, + 0xE9, 0xA7, 0x82, 0x43, 0xE9, 0xA7, 0xB1, 0x43, + 0xE9, 0xA7, 0xBE, 0x43, 0xE9, 0xA9, 0xAA, 0x43, + // Bytes 1580 - 15bf + 0xE9, 0xAA, 0xA8, 0x43, 0xE9, 0xAB, 0x98, 0x43, + 0xE9, 0xAB, 0x9F, 0x43, 0xE9, 0xAC, 0x92, 0x43, + 0xE9, 0xAC, 0xA5, 0x43, 0xE9, 0xAC, 0xAF, 0x43, + 0xE9, 0xAC, 0xB2, 0x43, 0xE9, 0xAC, 0xBC, 0x43, + 0xE9, 0xAD, 0x9A, 0x43, 0xE9, 0xAD, 0xAF, 0x43, + 0xE9, 0xB1, 0x80, 0x43, 0xE9, 0xB1, 0x97, 0x43, + 0xE9, 0xB3, 0xA5, 0x43, 0xE9, 0xB3, 0xBD, 0x43, + 0xE9, 0xB5, 0xA7, 0x43, 0xE9, 0xB6, 0xB4, 0x43, + // Bytes 15c0 - 15ff + 0xE9, 0xB7, 0xBA, 0x43, 0xE9, 0xB8, 0x9E, 0x43, + 0xE9, 0xB9, 0xB5, 0x43, 0xE9, 0xB9, 0xBF, 0x43, + 0xE9, 0xBA, 0x97, 0x43, 0xE9, 0xBA, 0x9F, 0x43, + 0xE9, 0xBA, 0xA5, 0x43, 0xE9, 0xBA, 0xBB, 0x43, + 0xE9, 0xBB, 0x83, 0x43, 0xE9, 0xBB, 0x8D, 0x43, + 0xE9, 0xBB, 0x8E, 0x43, 0xE9, 0xBB, 0x91, 0x43, + 0xE9, 0xBB, 0xB9, 0x43, 0xE9, 0xBB, 0xBD, 0x43, + 0xE9, 0xBB, 0xBE, 0x43, 0xE9, 0xBC, 0x85, 0x43, + // Bytes 1600 - 163f + 0xE9, 0xBC, 0x8E, 0x43, 0xE9, 0xBC, 0x8F, 0x43, + 0xE9, 0xBC, 0x93, 0x43, 0xE9, 0xBC, 0x96, 0x43, + 0xE9, 0xBC, 0xA0, 0x43, 0xE9, 0xBC, 0xBB, 0x43, + 0xE9, 0xBD, 0x83, 0x43, 0xE9, 0xBD, 0x8A, 0x43, + 0xE9, 0xBD, 0x92, 0x43, 0xE9, 0xBE, 0x8D, 0x43, + 0xE9, 0xBE, 0x8E, 0x43, 0xE9, 0xBE, 0x9C, 0x43, + 0xE9, 0xBE, 0x9F, 0x43, 0xE9, 0xBE, 0xA0, 0x43, + 0xEA, 0x9C, 0xA7, 0x43, 0xEA, 0x9D, 0xAF, 0x43, + // Bytes 1640 - 167f + 0xEA, 0xAC, 0xB7, 0x43, 0xEA, 0xAD, 0x92, 0x44, + 0xF0, 0xA0, 0x84, 0xA2, 0x44, 0xF0, 0xA0, 0x94, + 0x9C, 0x44, 0xF0, 0xA0, 0x94, 0xA5, 0x44, 0xF0, + 0xA0, 0x95, 0x8B, 0x44, 0xF0, 0xA0, 0x98, 0xBA, + 0x44, 0xF0, 0xA0, 0xA0, 0x84, 0x44, 0xF0, 0xA0, + 0xA3, 0x9E, 0x44, 0xF0, 0xA0, 0xA8, 0xAC, 0x44, + 0xF0, 0xA0, 0xAD, 0xA3, 0x44, 0xF0, 0xA1, 0x93, + 0xA4, 0x44, 0xF0, 0xA1, 0x9A, 0xA8, 0x44, 0xF0, + // Bytes 1680 - 16bf + 0xA1, 0x9B, 0xAA, 0x44, 0xF0, 0xA1, 0xA7, 0x88, + 0x44, 0xF0, 0xA1, 0xAC, 0x98, 0x44, 0xF0, 0xA1, + 0xB4, 0x8B, 0x44, 0xF0, 0xA1, 0xB7, 0xA4, 0x44, + 0xF0, 0xA1, 0xB7, 0xA6, 0x44, 0xF0, 0xA2, 0x86, + 0x83, 0x44, 0xF0, 0xA2, 0x86, 0x9F, 0x44, 0xF0, + 0xA2, 0x8C, 0xB1, 0x44, 0xF0, 0xA2, 0x9B, 0x94, + 0x44, 0xF0, 0xA2, 0xA1, 0x84, 0x44, 0xF0, 0xA2, + 0xA1, 0x8A, 0x44, 0xF0, 0xA2, 0xAC, 0x8C, 0x44, + // Bytes 16c0 - 16ff + 0xF0, 0xA2, 0xAF, 0xB1, 0x44, 0xF0, 0xA3, 0x80, + 0x8A, 0x44, 0xF0, 0xA3, 0x8A, 0xB8, 0x44, 0xF0, + 0xA3, 0x8D, 0x9F, 0x44, 0xF0, 0xA3, 0x8E, 0x93, + 0x44, 0xF0, 0xA3, 0x8E, 0x9C, 0x44, 0xF0, 0xA3, + 0x8F, 0x83, 0x44, 0xF0, 0xA3, 0x8F, 0x95, 0x44, + 0xF0, 0xA3, 0x91, 0xAD, 0x44, 0xF0, 0xA3, 0x9A, + 0xA3, 0x44, 0xF0, 0xA3, 0xA2, 0xA7, 0x44, 0xF0, + 0xA3, 0xAA, 0x8D, 0x44, 0xF0, 0xA3, 0xAB, 0xBA, + // Bytes 1700 - 173f + 0x44, 0xF0, 0xA3, 0xB2, 0xBC, 0x44, 0xF0, 0xA3, + 0xB4, 0x9E, 0x44, 0xF0, 0xA3, 0xBB, 0x91, 0x44, + 0xF0, 0xA3, 0xBD, 0x9E, 0x44, 0xF0, 0xA3, 0xBE, + 0x8E, 0x44, 0xF0, 0xA4, 0x89, 0xA3, 0x44, 0xF0, + 0xA4, 0x8B, 0xAE, 0x44, 0xF0, 0xA4, 0x8E, 0xAB, + 0x44, 0xF0, 0xA4, 0x98, 0x88, 0x44, 0xF0, 0xA4, + 0x9C, 0xB5, 0x44, 0xF0, 0xA4, 0xA0, 0x94, 0x44, + 0xF0, 0xA4, 0xB0, 0xB6, 0x44, 0xF0, 0xA4, 0xB2, + // Bytes 1740 - 177f + 0x92, 0x44, 0xF0, 0xA4, 0xBE, 0xA1, 0x44, 0xF0, + 0xA4, 0xBE, 0xB8, 0x44, 0xF0, 0xA5, 0x81, 0x84, + 0x44, 0xF0, 0xA5, 0x83, 0xB2, 0x44, 0xF0, 0xA5, + 0x83, 0xB3, 0x44, 0xF0, 0xA5, 0x84, 0x99, 0x44, + 0xF0, 0xA5, 0x84, 0xB3, 0x44, 0xF0, 0xA5, 0x89, + 0x89, 0x44, 0xF0, 0xA5, 0x90, 0x9D, 0x44, 0xF0, + 0xA5, 0x98, 0xA6, 0x44, 0xF0, 0xA5, 0x9A, 0x9A, + 0x44, 0xF0, 0xA5, 0x9B, 0x85, 0x44, 0xF0, 0xA5, + // Bytes 1780 - 17bf + 0xA5, 0xBC, 0x44, 0xF0, 0xA5, 0xAA, 0xA7, 0x44, + 0xF0, 0xA5, 0xAE, 0xAB, 0x44, 0xF0, 0xA5, 0xB2, + 0x80, 0x44, 0xF0, 0xA5, 0xB3, 0x90, 0x44, 0xF0, + 0xA5, 0xBE, 0x86, 0x44, 0xF0, 0xA6, 0x87, 0x9A, + 0x44, 0xF0, 0xA6, 0x88, 0xA8, 0x44, 0xF0, 0xA6, + 0x89, 0x87, 0x44, 0xF0, 0xA6, 0x8B, 0x99, 0x44, + 0xF0, 0xA6, 0x8C, 0xBE, 0x44, 0xF0, 0xA6, 0x93, + 0x9A, 0x44, 0xF0, 0xA6, 0x94, 0xA3, 0x44, 0xF0, + // Bytes 17c0 - 17ff + 0xA6, 0x96, 0xA8, 0x44, 0xF0, 0xA6, 0x9E, 0xA7, + 0x44, 0xF0, 0xA6, 0x9E, 0xB5, 0x44, 0xF0, 0xA6, + 0xAC, 0xBC, 0x44, 0xF0, 0xA6, 0xB0, 0xB6, 0x44, + 0xF0, 0xA6, 0xB3, 0x95, 0x44, 0xF0, 0xA6, 0xB5, + 0xAB, 0x44, 0xF0, 0xA6, 0xBC, 0xAC, 0x44, 0xF0, + 0xA6, 0xBE, 0xB1, 0x44, 0xF0, 0xA7, 0x83, 0x92, + 0x44, 0xF0, 0xA7, 0x8F, 0x8A, 0x44, 0xF0, 0xA7, + 0x99, 0xA7, 0x44, 0xF0, 0xA7, 0xA2, 0xAE, 0x44, + // Bytes 1800 - 183f + 0xF0, 0xA7, 0xA5, 0xA6, 0x44, 0xF0, 0xA7, 0xB2, + 0xA8, 0x44, 0xF0, 0xA7, 0xBB, 0x93, 0x44, 0xF0, + 0xA7, 0xBC, 0xAF, 0x44, 0xF0, 0xA8, 0x97, 0x92, + 0x44, 0xF0, 0xA8, 0x97, 0xAD, 0x44, 0xF0, 0xA8, + 0x9C, 0xAE, 0x44, 0xF0, 0xA8, 0xAF, 0xBA, 0x44, + 0xF0, 0xA8, 0xB5, 0xB7, 0x44, 0xF0, 0xA9, 0x85, + 0x85, 0x44, 0xF0, 0xA9, 0x87, 0x9F, 0x44, 0xF0, + 0xA9, 0x88, 0x9A, 0x44, 0xF0, 0xA9, 0x90, 0x8A, + // Bytes 1840 - 187f + 0x44, 0xF0, 0xA9, 0x92, 0x96, 0x44, 0xF0, 0xA9, + 0x96, 0xB6, 0x44, 0xF0, 0xA9, 0xAC, 0xB0, 0x44, + 0xF0, 0xAA, 0x83, 0x8E, 0x44, 0xF0, 0xAA, 0x84, + 0x85, 0x44, 0xF0, 0xAA, 0x88, 0x8E, 0x44, 0xF0, + 0xAA, 0x8A, 0x91, 0x44, 0xF0, 0xAA, 0x8E, 0x92, + 0x44, 0xF0, 0xAA, 0x98, 0x80, 0x42, 0x21, 0x21, + 0x42, 0x21, 0x3F, 0x42, 0x2E, 0x2E, 0x42, 0x30, + 0x2C, 0x42, 0x30, 0x2E, 0x42, 0x31, 0x2C, 0x42, + // Bytes 1880 - 18bf + 0x31, 0x2E, 0x42, 0x31, 0x30, 0x42, 0x31, 0x31, + 0x42, 0x31, 0x32, 0x42, 0x31, 0x33, 0x42, 0x31, + 0x34, 0x42, 0x31, 0x35, 0x42, 0x31, 0x36, 0x42, + 0x31, 0x37, 0x42, 0x31, 0x38, 0x42, 0x31, 0x39, + 0x42, 0x32, 0x2C, 0x42, 0x32, 0x2E, 0x42, 0x32, + 0x30, 0x42, 0x32, 0x31, 0x42, 0x32, 0x32, 0x42, + 0x32, 0x33, 0x42, 0x32, 0x34, 0x42, 0x32, 0x35, + 0x42, 0x32, 0x36, 0x42, 0x32, 0x37, 0x42, 0x32, + // Bytes 18c0 - 18ff + 0x38, 0x42, 0x32, 0x39, 0x42, 0x33, 0x2C, 0x42, + 0x33, 0x2E, 0x42, 0x33, 0x30, 0x42, 0x33, 0x31, + 0x42, 0x33, 0x32, 0x42, 0x33, 0x33, 0x42, 0x33, + 0x34, 0x42, 0x33, 0x35, 0x42, 0x33, 0x36, 0x42, + 0x33, 0x37, 0x42, 0x33, 0x38, 0x42, 0x33, 0x39, + 0x42, 0x34, 0x2C, 0x42, 0x34, 0x2E, 0x42, 0x34, + 0x30, 0x42, 0x34, 0x31, 0x42, 0x34, 0x32, 0x42, + 0x34, 0x33, 0x42, 0x34, 0x34, 0x42, 0x34, 0x35, + // Bytes 1900 - 193f + 0x42, 0x34, 0x36, 0x42, 0x34, 0x37, 0x42, 0x34, + 0x38, 0x42, 0x34, 0x39, 0x42, 0x35, 0x2C, 0x42, + 0x35, 0x2E, 0x42, 0x35, 0x30, 0x42, 0x36, 0x2C, + 0x42, 0x36, 0x2E, 0x42, 0x37, 0x2C, 0x42, 0x37, + 0x2E, 0x42, 0x38, 0x2C, 0x42, 0x38, 0x2E, 0x42, + 0x39, 0x2C, 0x42, 0x39, 0x2E, 0x42, 0x3D, 0x3D, + 0x42, 0x3F, 0x21, 0x42, 0x3F, 0x3F, 0x42, 0x41, + 0x55, 0x42, 0x42, 0x71, 0x42, 0x43, 0x44, 0x42, + // Bytes 1940 - 197f + 0x44, 0x4A, 0x42, 0x44, 0x5A, 0x42, 0x44, 0x7A, + 0x42, 0x47, 0x42, 0x42, 0x47, 0x79, 0x42, 0x48, + 0x50, 0x42, 0x48, 0x56, 0x42, 0x48, 0x67, 0x42, + 0x48, 0x7A, 0x42, 0x49, 0x49, 0x42, 0x49, 0x4A, + 0x42, 0x49, 0x55, 0x42, 0x49, 0x56, 0x42, 0x49, + 0x58, 0x42, 0x4B, 0x42, 0x42, 0x4B, 0x4B, 0x42, + 0x4B, 0x4D, 0x42, 0x4C, 0x4A, 0x42, 0x4C, 0x6A, + 0x42, 0x4D, 0x42, 0x42, 0x4D, 0x43, 0x42, 0x4D, + // Bytes 1980 - 19bf + 0x44, 0x42, 0x4D, 0x56, 0x42, 0x4D, 0x57, 0x42, + 0x4E, 0x4A, 0x42, 0x4E, 0x6A, 0x42, 0x4E, 0x6F, + 0x42, 0x50, 0x48, 0x42, 0x50, 0x52, 0x42, 0x50, + 0x61, 0x42, 0x52, 0x73, 0x42, 0x53, 0x44, 0x42, + 0x53, 0x4D, 0x42, 0x53, 0x53, 0x42, 0x53, 0x76, + 0x42, 0x54, 0x4D, 0x42, 0x56, 0x49, 0x42, 0x57, + 0x43, 0x42, 0x57, 0x5A, 0x42, 0x57, 0x62, 0x42, + 0x58, 0x49, 0x42, 0x63, 0x63, 0x42, 0x63, 0x64, + // Bytes 19c0 - 19ff + 0x42, 0x63, 0x6D, 0x42, 0x64, 0x42, 0x42, 0x64, + 0x61, 0x42, 0x64, 0x6C, 0x42, 0x64, 0x6D, 0x42, + 0x64, 0x7A, 0x42, 0x65, 0x56, 0x42, 0x66, 0x66, + 0x42, 0x66, 0x69, 0x42, 0x66, 0x6C, 0x42, 0x66, + 0x6D, 0x42, 0x68, 0x61, 0x42, 0x69, 0x69, 0x42, + 0x69, 0x6A, 0x42, 0x69, 0x6E, 0x42, 0x69, 0x76, + 0x42, 0x69, 0x78, 0x42, 0x6B, 0x41, 0x42, 0x6B, + 0x56, 0x42, 0x6B, 0x57, 0x42, 0x6B, 0x67, 0x42, + // Bytes 1a00 - 1a3f + 0x6B, 0x6C, 0x42, 0x6B, 0x6D, 0x42, 0x6B, 0x74, + 0x42, 0x6C, 0x6A, 0x42, 0x6C, 0x6D, 0x42, 0x6C, + 0x6E, 0x42, 0x6C, 0x78, 0x42, 0x6D, 0x32, 0x42, + 0x6D, 0x33, 0x42, 0x6D, 0x41, 0x42, 0x6D, 0x56, + 0x42, 0x6D, 0x57, 0x42, 0x6D, 0x62, 0x42, 0x6D, + 0x67, 0x42, 0x6D, 0x6C, 0x42, 0x6D, 0x6D, 0x42, + 0x6D, 0x73, 0x42, 0x6E, 0x41, 0x42, 0x6E, 0x46, + 0x42, 0x6E, 0x56, 0x42, 0x6E, 0x57, 0x42, 0x6E, + // Bytes 1a40 - 1a7f + 0x6A, 0x42, 0x6E, 0x6D, 0x42, 0x6E, 0x73, 0x42, + 0x6F, 0x56, 0x42, 0x70, 0x41, 0x42, 0x70, 0x46, + 0x42, 0x70, 0x56, 0x42, 0x70, 0x57, 0x42, 0x70, + 0x63, 0x42, 0x70, 0x73, 0x42, 0x73, 0x72, 0x42, + 0x73, 0x74, 0x42, 0x76, 0x69, 0x42, 0x78, 0x69, + 0x43, 0x28, 0x31, 0x29, 0x43, 0x28, 0x32, 0x29, + 0x43, 0x28, 0x33, 0x29, 0x43, 0x28, 0x34, 0x29, + 0x43, 0x28, 0x35, 0x29, 0x43, 0x28, 0x36, 0x29, + // Bytes 1a80 - 1abf + 0x43, 0x28, 0x37, 0x29, 0x43, 0x28, 0x38, 0x29, + 0x43, 0x28, 0x39, 0x29, 0x43, 0x28, 0x41, 0x29, + 0x43, 0x28, 0x42, 0x29, 0x43, 0x28, 0x43, 0x29, + 0x43, 0x28, 0x44, 0x29, 0x43, 0x28, 0x45, 0x29, + 0x43, 0x28, 0x46, 0x29, 0x43, 0x28, 0x47, 0x29, + 0x43, 0x28, 0x48, 0x29, 0x43, 0x28, 0x49, 0x29, + 0x43, 0x28, 0x4A, 0x29, 0x43, 0x28, 0x4B, 0x29, + 0x43, 0x28, 0x4C, 0x29, 0x43, 0x28, 0x4D, 0x29, + // Bytes 1ac0 - 1aff + 0x43, 0x28, 0x4E, 0x29, 0x43, 0x28, 0x4F, 0x29, + 0x43, 0x28, 0x50, 0x29, 0x43, 0x28, 0x51, 0x29, + 0x43, 0x28, 0x52, 0x29, 0x43, 0x28, 0x53, 0x29, + 0x43, 0x28, 0x54, 0x29, 0x43, 0x28, 0x55, 0x29, + 0x43, 0x28, 0x56, 0x29, 0x43, 0x28, 0x57, 0x29, + 0x43, 0x28, 0x58, 0x29, 0x43, 0x28, 0x59, 0x29, + 0x43, 0x28, 0x5A, 0x29, 0x43, 0x28, 0x61, 0x29, + 0x43, 0x28, 0x62, 0x29, 0x43, 0x28, 0x63, 0x29, + // Bytes 1b00 - 1b3f + 0x43, 0x28, 0x64, 0x29, 0x43, 0x28, 0x65, 0x29, + 0x43, 0x28, 0x66, 0x29, 0x43, 0x28, 0x67, 0x29, + 0x43, 0x28, 0x68, 0x29, 0x43, 0x28, 0x69, 0x29, + 0x43, 0x28, 0x6A, 0x29, 0x43, 0x28, 0x6B, 0x29, + 0x43, 0x28, 0x6C, 0x29, 0x43, 0x28, 0x6D, 0x29, + 0x43, 0x28, 0x6E, 0x29, 0x43, 0x28, 0x6F, 0x29, + 0x43, 0x28, 0x70, 0x29, 0x43, 0x28, 0x71, 0x29, + 0x43, 0x28, 0x72, 0x29, 0x43, 0x28, 0x73, 0x29, + // Bytes 1b40 - 1b7f + 0x43, 0x28, 0x74, 0x29, 0x43, 0x28, 0x75, 0x29, + 0x43, 0x28, 0x76, 0x29, 0x43, 0x28, 0x77, 0x29, + 0x43, 0x28, 0x78, 0x29, 0x43, 0x28, 0x79, 0x29, + 0x43, 0x28, 0x7A, 0x29, 0x43, 0x2E, 0x2E, 0x2E, + 0x43, 0x31, 0x30, 0x2E, 0x43, 0x31, 0x31, 0x2E, + 0x43, 0x31, 0x32, 0x2E, 0x43, 0x31, 0x33, 0x2E, + 0x43, 0x31, 0x34, 0x2E, 0x43, 0x31, 0x35, 0x2E, + 0x43, 0x31, 0x36, 0x2E, 0x43, 0x31, 0x37, 0x2E, + // Bytes 1b80 - 1bbf + 0x43, 0x31, 0x38, 0x2E, 0x43, 0x31, 0x39, 0x2E, + 0x43, 0x32, 0x30, 0x2E, 0x43, 0x3A, 0x3A, 0x3D, + 0x43, 0x3D, 0x3D, 0x3D, 0x43, 0x43, 0x6F, 0x2E, + 0x43, 0x46, 0x41, 0x58, 0x43, 0x47, 0x48, 0x7A, + 0x43, 0x47, 0x50, 0x61, 0x43, 0x49, 0x49, 0x49, + 0x43, 0x4C, 0x54, 0x44, 0x43, 0x4C, 0xC2, 0xB7, + 0x43, 0x4D, 0x48, 0x7A, 0x43, 0x4D, 0x50, 0x61, + 0x43, 0x4D, 0xCE, 0xA9, 0x43, 0x50, 0x50, 0x4D, + // Bytes 1bc0 - 1bff + 0x43, 0x50, 0x50, 0x56, 0x43, 0x50, 0x54, 0x45, + 0x43, 0x54, 0x45, 0x4C, 0x43, 0x54, 0x48, 0x7A, + 0x43, 0x56, 0x49, 0x49, 0x43, 0x58, 0x49, 0x49, + 0x43, 0x61, 0x2F, 0x63, 0x43, 0x61, 0x2F, 0x73, + 0x43, 0x61, 0xCA, 0xBE, 0x43, 0x62, 0x61, 0x72, + 0x43, 0x63, 0x2F, 0x6F, 0x43, 0x63, 0x2F, 0x75, + 0x43, 0x63, 0x61, 0x6C, 0x43, 0x63, 0x6D, 0x32, + 0x43, 0x63, 0x6D, 0x33, 0x43, 0x64, 0x6D, 0x32, + // Bytes 1c00 - 1c3f + 0x43, 0x64, 0x6D, 0x33, 0x43, 0x65, 0x72, 0x67, + 0x43, 0x66, 0x66, 0x69, 0x43, 0x66, 0x66, 0x6C, + 0x43, 0x67, 0x61, 0x6C, 0x43, 0x68, 0x50, 0x61, + 0x43, 0x69, 0x69, 0x69, 0x43, 0x6B, 0x48, 0x7A, + 0x43, 0x6B, 0x50, 0x61, 0x43, 0x6B, 0x6D, 0x32, + 0x43, 0x6B, 0x6D, 0x33, 0x43, 0x6B, 0xCE, 0xA9, + 0x43, 0x6C, 0x6F, 0x67, 0x43, 0x6C, 0xC2, 0xB7, + 0x43, 0x6D, 0x69, 0x6C, 0x43, 0x6D, 0x6D, 0x32, + // Bytes 1c40 - 1c7f + 0x43, 0x6D, 0x6D, 0x33, 0x43, 0x6D, 0x6F, 0x6C, + 0x43, 0x72, 0x61, 0x64, 0x43, 0x76, 0x69, 0x69, + 0x43, 0x78, 0x69, 0x69, 0x43, 0xC2, 0xB0, 0x43, + 0x43, 0xC2, 0xB0, 0x46, 0x43, 0xCA, 0xBC, 0x6E, + 0x43, 0xCE, 0xBC, 0x41, 0x43, 0xCE, 0xBC, 0x46, + 0x43, 0xCE, 0xBC, 0x56, 0x43, 0xCE, 0xBC, 0x57, + 0x43, 0xCE, 0xBC, 0x67, 0x43, 0xCE, 0xBC, 0x6C, + 0x43, 0xCE, 0xBC, 0x6D, 0x43, 0xCE, 0xBC, 0x73, + // Bytes 1c80 - 1cbf + 0x44, 0x28, 0x31, 0x30, 0x29, 0x44, 0x28, 0x31, + 0x31, 0x29, 0x44, 0x28, 0x31, 0x32, 0x29, 0x44, + 0x28, 0x31, 0x33, 0x29, 0x44, 0x28, 0x31, 0x34, + 0x29, 0x44, 0x28, 0x31, 0x35, 0x29, 0x44, 0x28, + 0x31, 0x36, 0x29, 0x44, 0x28, 0x31, 0x37, 0x29, + 0x44, 0x28, 0x31, 0x38, 0x29, 0x44, 0x28, 0x31, + 0x39, 0x29, 0x44, 0x28, 0x32, 0x30, 0x29, 0x44, + 0x30, 0xE7, 0x82, 0xB9, 0x44, 0x31, 0xE2, 0x81, + // Bytes 1cc0 - 1cff + 0x84, 0x44, 0x31, 0xE6, 0x97, 0xA5, 0x44, 0x31, + 0xE6, 0x9C, 0x88, 0x44, 0x31, 0xE7, 0x82, 0xB9, + 0x44, 0x32, 0xE6, 0x97, 0xA5, 0x44, 0x32, 0xE6, + 0x9C, 0x88, 0x44, 0x32, 0xE7, 0x82, 0xB9, 0x44, + 0x33, 0xE6, 0x97, 0xA5, 0x44, 0x33, 0xE6, 0x9C, + 0x88, 0x44, 0x33, 0xE7, 0x82, 0xB9, 0x44, 0x34, + 0xE6, 0x97, 0xA5, 0x44, 0x34, 0xE6, 0x9C, 0x88, + 0x44, 0x34, 0xE7, 0x82, 0xB9, 0x44, 0x35, 0xE6, + // Bytes 1d00 - 1d3f + 0x97, 0xA5, 0x44, 0x35, 0xE6, 0x9C, 0x88, 0x44, + 0x35, 0xE7, 0x82, 0xB9, 0x44, 0x36, 0xE6, 0x97, + 0xA5, 0x44, 0x36, 0xE6, 0x9C, 0x88, 0x44, 0x36, + 0xE7, 0x82, 0xB9, 0x44, 0x37, 0xE6, 0x97, 0xA5, + 0x44, 0x37, 0xE6, 0x9C, 0x88, 0x44, 0x37, 0xE7, + 0x82, 0xB9, 0x44, 0x38, 0xE6, 0x97, 0xA5, 0x44, + 0x38, 0xE6, 0x9C, 0x88, 0x44, 0x38, 0xE7, 0x82, + 0xB9, 0x44, 0x39, 0xE6, 0x97, 0xA5, 0x44, 0x39, + // Bytes 1d40 - 1d7f + 0xE6, 0x9C, 0x88, 0x44, 0x39, 0xE7, 0x82, 0xB9, + 0x44, 0x56, 0x49, 0x49, 0x49, 0x44, 0x61, 0x2E, + 0x6D, 0x2E, 0x44, 0x6B, 0x63, 0x61, 0x6C, 0x44, + 0x70, 0x2E, 0x6D, 0x2E, 0x44, 0x76, 0x69, 0x69, + 0x69, 0x44, 0xD5, 0xA5, 0xD6, 0x82, 0x44, 0xD5, + 0xB4, 0xD5, 0xA5, 0x44, 0xD5, 0xB4, 0xD5, 0xAB, + 0x44, 0xD5, 0xB4, 0xD5, 0xAD, 0x44, 0xD5, 0xB4, + 0xD5, 0xB6, 0x44, 0xD5, 0xBE, 0xD5, 0xB6, 0x44, + // Bytes 1d80 - 1dbf + 0xD7, 0x90, 0xD7, 0x9C, 0x44, 0xD8, 0xA7, 0xD9, + 0xB4, 0x44, 0xD8, 0xA8, 0xD8, 0xAC, 0x44, 0xD8, + 0xA8, 0xD8, 0xAD, 0x44, 0xD8, 0xA8, 0xD8, 0xAE, + 0x44, 0xD8, 0xA8, 0xD8, 0xB1, 0x44, 0xD8, 0xA8, + 0xD8, 0xB2, 0x44, 0xD8, 0xA8, 0xD9, 0x85, 0x44, + 0xD8, 0xA8, 0xD9, 0x86, 0x44, 0xD8, 0xA8, 0xD9, + 0x87, 0x44, 0xD8, 0xA8, 0xD9, 0x89, 0x44, 0xD8, + 0xA8, 0xD9, 0x8A, 0x44, 0xD8, 0xAA, 0xD8, 0xAC, + // Bytes 1dc0 - 1dff + 0x44, 0xD8, 0xAA, 0xD8, 0xAD, 0x44, 0xD8, 0xAA, + 0xD8, 0xAE, 0x44, 0xD8, 0xAA, 0xD8, 0xB1, 0x44, + 0xD8, 0xAA, 0xD8, 0xB2, 0x44, 0xD8, 0xAA, 0xD9, + 0x85, 0x44, 0xD8, 0xAA, 0xD9, 0x86, 0x44, 0xD8, + 0xAA, 0xD9, 0x87, 0x44, 0xD8, 0xAA, 0xD9, 0x89, + 0x44, 0xD8, 0xAA, 0xD9, 0x8A, 0x44, 0xD8, 0xAB, + 0xD8, 0xAC, 0x44, 0xD8, 0xAB, 0xD8, 0xB1, 0x44, + 0xD8, 0xAB, 0xD8, 0xB2, 0x44, 0xD8, 0xAB, 0xD9, + // Bytes 1e00 - 1e3f + 0x85, 0x44, 0xD8, 0xAB, 0xD9, 0x86, 0x44, 0xD8, + 0xAB, 0xD9, 0x87, 0x44, 0xD8, 0xAB, 0xD9, 0x89, + 0x44, 0xD8, 0xAB, 0xD9, 0x8A, 0x44, 0xD8, 0xAC, + 0xD8, 0xAD, 0x44, 0xD8, 0xAC, 0xD9, 0x85, 0x44, + 0xD8, 0xAC, 0xD9, 0x89, 0x44, 0xD8, 0xAC, 0xD9, + 0x8A, 0x44, 0xD8, 0xAD, 0xD8, 0xAC, 0x44, 0xD8, + 0xAD, 0xD9, 0x85, 0x44, 0xD8, 0xAD, 0xD9, 0x89, + 0x44, 0xD8, 0xAD, 0xD9, 0x8A, 0x44, 0xD8, 0xAE, + // Bytes 1e40 - 1e7f + 0xD8, 0xAC, 0x44, 0xD8, 0xAE, 0xD8, 0xAD, 0x44, + 0xD8, 0xAE, 0xD9, 0x85, 0x44, 0xD8, 0xAE, 0xD9, + 0x89, 0x44, 0xD8, 0xAE, 0xD9, 0x8A, 0x44, 0xD8, + 0xB3, 0xD8, 0xAC, 0x44, 0xD8, 0xB3, 0xD8, 0xAD, + 0x44, 0xD8, 0xB3, 0xD8, 0xAE, 0x44, 0xD8, 0xB3, + 0xD8, 0xB1, 0x44, 0xD8, 0xB3, 0xD9, 0x85, 0x44, + 0xD8, 0xB3, 0xD9, 0x87, 0x44, 0xD8, 0xB3, 0xD9, + 0x89, 0x44, 0xD8, 0xB3, 0xD9, 0x8A, 0x44, 0xD8, + // Bytes 1e80 - 1ebf + 0xB4, 0xD8, 0xAC, 0x44, 0xD8, 0xB4, 0xD8, 0xAD, + 0x44, 0xD8, 0xB4, 0xD8, 0xAE, 0x44, 0xD8, 0xB4, + 0xD8, 0xB1, 0x44, 0xD8, 0xB4, 0xD9, 0x85, 0x44, + 0xD8, 0xB4, 0xD9, 0x87, 0x44, 0xD8, 0xB4, 0xD9, + 0x89, 0x44, 0xD8, 0xB4, 0xD9, 0x8A, 0x44, 0xD8, + 0xB5, 0xD8, 0xAD, 0x44, 0xD8, 0xB5, 0xD8, 0xAE, + 0x44, 0xD8, 0xB5, 0xD8, 0xB1, 0x44, 0xD8, 0xB5, + 0xD9, 0x85, 0x44, 0xD8, 0xB5, 0xD9, 0x89, 0x44, + // Bytes 1ec0 - 1eff + 0xD8, 0xB5, 0xD9, 0x8A, 0x44, 0xD8, 0xB6, 0xD8, + 0xAC, 0x44, 0xD8, 0xB6, 0xD8, 0xAD, 0x44, 0xD8, + 0xB6, 0xD8, 0xAE, 0x44, 0xD8, 0xB6, 0xD8, 0xB1, + 0x44, 0xD8, 0xB6, 0xD9, 0x85, 0x44, 0xD8, 0xB6, + 0xD9, 0x89, 0x44, 0xD8, 0xB6, 0xD9, 0x8A, 0x44, + 0xD8, 0xB7, 0xD8, 0xAD, 0x44, 0xD8, 0xB7, 0xD9, + 0x85, 0x44, 0xD8, 0xB7, 0xD9, 0x89, 0x44, 0xD8, + 0xB7, 0xD9, 0x8A, 0x44, 0xD8, 0xB8, 0xD9, 0x85, + // Bytes 1f00 - 1f3f + 0x44, 0xD8, 0xB9, 0xD8, 0xAC, 0x44, 0xD8, 0xB9, + 0xD9, 0x85, 0x44, 0xD8, 0xB9, 0xD9, 0x89, 0x44, + 0xD8, 0xB9, 0xD9, 0x8A, 0x44, 0xD8, 0xBA, 0xD8, + 0xAC, 0x44, 0xD8, 0xBA, 0xD9, 0x85, 0x44, 0xD8, + 0xBA, 0xD9, 0x89, 0x44, 0xD8, 0xBA, 0xD9, 0x8A, + 0x44, 0xD9, 0x81, 0xD8, 0xAC, 0x44, 0xD9, 0x81, + 0xD8, 0xAD, 0x44, 0xD9, 0x81, 0xD8, 0xAE, 0x44, + 0xD9, 0x81, 0xD9, 0x85, 0x44, 0xD9, 0x81, 0xD9, + // Bytes 1f40 - 1f7f + 0x89, 0x44, 0xD9, 0x81, 0xD9, 0x8A, 0x44, 0xD9, + 0x82, 0xD8, 0xAD, 0x44, 0xD9, 0x82, 0xD9, 0x85, + 0x44, 0xD9, 0x82, 0xD9, 0x89, 0x44, 0xD9, 0x82, + 0xD9, 0x8A, 0x44, 0xD9, 0x83, 0xD8, 0xA7, 0x44, + 0xD9, 0x83, 0xD8, 0xAC, 0x44, 0xD9, 0x83, 0xD8, + 0xAD, 0x44, 0xD9, 0x83, 0xD8, 0xAE, 0x44, 0xD9, + 0x83, 0xD9, 0x84, 0x44, 0xD9, 0x83, 0xD9, 0x85, + 0x44, 0xD9, 0x83, 0xD9, 0x89, 0x44, 0xD9, 0x83, + // Bytes 1f80 - 1fbf + 0xD9, 0x8A, 0x44, 0xD9, 0x84, 0xD8, 0xA7, 0x44, + 0xD9, 0x84, 0xD8, 0xAC, 0x44, 0xD9, 0x84, 0xD8, + 0xAD, 0x44, 0xD9, 0x84, 0xD8, 0xAE, 0x44, 0xD9, + 0x84, 0xD9, 0x85, 0x44, 0xD9, 0x84, 0xD9, 0x87, + 0x44, 0xD9, 0x84, 0xD9, 0x89, 0x44, 0xD9, 0x84, + 0xD9, 0x8A, 0x44, 0xD9, 0x85, 0xD8, 0xA7, 0x44, + 0xD9, 0x85, 0xD8, 0xAC, 0x44, 0xD9, 0x85, 0xD8, + 0xAD, 0x44, 0xD9, 0x85, 0xD8, 0xAE, 0x44, 0xD9, + // Bytes 1fc0 - 1fff + 0x85, 0xD9, 0x85, 0x44, 0xD9, 0x85, 0xD9, 0x89, + 0x44, 0xD9, 0x85, 0xD9, 0x8A, 0x44, 0xD9, 0x86, + 0xD8, 0xAC, 0x44, 0xD9, 0x86, 0xD8, 0xAD, 0x44, + 0xD9, 0x86, 0xD8, 0xAE, 0x44, 0xD9, 0x86, 0xD8, + 0xB1, 0x44, 0xD9, 0x86, 0xD8, 0xB2, 0x44, 0xD9, + 0x86, 0xD9, 0x85, 0x44, 0xD9, 0x86, 0xD9, 0x86, + 0x44, 0xD9, 0x86, 0xD9, 0x87, 0x44, 0xD9, 0x86, + 0xD9, 0x89, 0x44, 0xD9, 0x86, 0xD9, 0x8A, 0x44, + // Bytes 2000 - 203f + 0xD9, 0x87, 0xD8, 0xAC, 0x44, 0xD9, 0x87, 0xD9, + 0x85, 0x44, 0xD9, 0x87, 0xD9, 0x89, 0x44, 0xD9, + 0x87, 0xD9, 0x8A, 0x44, 0xD9, 0x88, 0xD9, 0xB4, + 0x44, 0xD9, 0x8A, 0xD8, 0xAC, 0x44, 0xD9, 0x8A, + 0xD8, 0xAD, 0x44, 0xD9, 0x8A, 0xD8, 0xAE, 0x44, + 0xD9, 0x8A, 0xD8, 0xB1, 0x44, 0xD9, 0x8A, 0xD8, + 0xB2, 0x44, 0xD9, 0x8A, 0xD9, 0x85, 0x44, 0xD9, + 0x8A, 0xD9, 0x86, 0x44, 0xD9, 0x8A, 0xD9, 0x87, + // Bytes 2040 - 207f + 0x44, 0xD9, 0x8A, 0xD9, 0x89, 0x44, 0xD9, 0x8A, + 0xD9, 0x8A, 0x44, 0xD9, 0x8A, 0xD9, 0xB4, 0x44, + 0xDB, 0x87, 0xD9, 0xB4, 0x45, 0x28, 0xE1, 0x84, + 0x80, 0x29, 0x45, 0x28, 0xE1, 0x84, 0x82, 0x29, + 0x45, 0x28, 0xE1, 0x84, 0x83, 0x29, 0x45, 0x28, + 0xE1, 0x84, 0x85, 0x29, 0x45, 0x28, 0xE1, 0x84, + 0x86, 0x29, 0x45, 0x28, 0xE1, 0x84, 0x87, 0x29, + 0x45, 0x28, 0xE1, 0x84, 0x89, 0x29, 0x45, 0x28, + // Bytes 2080 - 20bf + 0xE1, 0x84, 0x8B, 0x29, 0x45, 0x28, 0xE1, 0x84, + 0x8C, 0x29, 0x45, 0x28, 0xE1, 0x84, 0x8E, 0x29, + 0x45, 0x28, 0xE1, 0x84, 0x8F, 0x29, 0x45, 0x28, + 0xE1, 0x84, 0x90, 0x29, 0x45, 0x28, 0xE1, 0x84, + 0x91, 0x29, 0x45, 0x28, 0xE1, 0x84, 0x92, 0x29, + 0x45, 0x28, 0xE4, 0xB8, 0x80, 0x29, 0x45, 0x28, + 0xE4, 0xB8, 0x83, 0x29, 0x45, 0x28, 0xE4, 0xB8, + 0x89, 0x29, 0x45, 0x28, 0xE4, 0xB9, 0x9D, 0x29, + // Bytes 20c0 - 20ff + 0x45, 0x28, 0xE4, 0xBA, 0x8C, 0x29, 0x45, 0x28, + 0xE4, 0xBA, 0x94, 0x29, 0x45, 0x28, 0xE4, 0xBB, + 0xA3, 0x29, 0x45, 0x28, 0xE4, 0xBC, 0x81, 0x29, + 0x45, 0x28, 0xE4, 0xBC, 0x91, 0x29, 0x45, 0x28, + 0xE5, 0x85, 0xAB, 0x29, 0x45, 0x28, 0xE5, 0x85, + 0xAD, 0x29, 0x45, 0x28, 0xE5, 0x8A, 0xB4, 0x29, + 0x45, 0x28, 0xE5, 0x8D, 0x81, 0x29, 0x45, 0x28, + 0xE5, 0x8D, 0x94, 0x29, 0x45, 0x28, 0xE5, 0x90, + // Bytes 2100 - 213f + 0x8D, 0x29, 0x45, 0x28, 0xE5, 0x91, 0xBC, 0x29, + 0x45, 0x28, 0xE5, 0x9B, 0x9B, 0x29, 0x45, 0x28, + 0xE5, 0x9C, 0x9F, 0x29, 0x45, 0x28, 0xE5, 0xAD, + 0xA6, 0x29, 0x45, 0x28, 0xE6, 0x97, 0xA5, 0x29, + 0x45, 0x28, 0xE6, 0x9C, 0x88, 0x29, 0x45, 0x28, + 0xE6, 0x9C, 0x89, 0x29, 0x45, 0x28, 0xE6, 0x9C, + 0xA8, 0x29, 0x45, 0x28, 0xE6, 0xA0, 0xAA, 0x29, + 0x45, 0x28, 0xE6, 0xB0, 0xB4, 0x29, 0x45, 0x28, + // Bytes 2140 - 217f + 0xE7, 0x81, 0xAB, 0x29, 0x45, 0x28, 0xE7, 0x89, + 0xB9, 0x29, 0x45, 0x28, 0xE7, 0x9B, 0xA3, 0x29, + 0x45, 0x28, 0xE7, 0xA4, 0xBE, 0x29, 0x45, 0x28, + 0xE7, 0xA5, 0x9D, 0x29, 0x45, 0x28, 0xE7, 0xA5, + 0xAD, 0x29, 0x45, 0x28, 0xE8, 0x87, 0xAA, 0x29, + 0x45, 0x28, 0xE8, 0x87, 0xB3, 0x29, 0x45, 0x28, + 0xE8, 0xB2, 0xA1, 0x29, 0x45, 0x28, 0xE8, 0xB3, + 0x87, 0x29, 0x45, 0x28, 0xE9, 0x87, 0x91, 0x29, + // Bytes 2180 - 21bf + 0x45, 0x30, 0xE2, 0x81, 0x84, 0x33, 0x45, 0x31, + 0x30, 0xE6, 0x97, 0xA5, 0x45, 0x31, 0x30, 0xE6, + 0x9C, 0x88, 0x45, 0x31, 0x30, 0xE7, 0x82, 0xB9, + 0x45, 0x31, 0x31, 0xE6, 0x97, 0xA5, 0x45, 0x31, + 0x31, 0xE6, 0x9C, 0x88, 0x45, 0x31, 0x31, 0xE7, + 0x82, 0xB9, 0x45, 0x31, 0x32, 0xE6, 0x97, 0xA5, + 0x45, 0x31, 0x32, 0xE6, 0x9C, 0x88, 0x45, 0x31, + 0x32, 0xE7, 0x82, 0xB9, 0x45, 0x31, 0x33, 0xE6, + // Bytes 21c0 - 21ff + 0x97, 0xA5, 0x45, 0x31, 0x33, 0xE7, 0x82, 0xB9, + 0x45, 0x31, 0x34, 0xE6, 0x97, 0xA5, 0x45, 0x31, + 0x34, 0xE7, 0x82, 0xB9, 0x45, 0x31, 0x35, 0xE6, + 0x97, 0xA5, 0x45, 0x31, 0x35, 0xE7, 0x82, 0xB9, + 0x45, 0x31, 0x36, 0xE6, 0x97, 0xA5, 0x45, 0x31, + 0x36, 0xE7, 0x82, 0xB9, 0x45, 0x31, 0x37, 0xE6, + 0x97, 0xA5, 0x45, 0x31, 0x37, 0xE7, 0x82, 0xB9, + 0x45, 0x31, 0x38, 0xE6, 0x97, 0xA5, 0x45, 0x31, + // Bytes 2200 - 223f + 0x38, 0xE7, 0x82, 0xB9, 0x45, 0x31, 0x39, 0xE6, + 0x97, 0xA5, 0x45, 0x31, 0x39, 0xE7, 0x82, 0xB9, + 0x45, 0x31, 0xE2, 0x81, 0x84, 0x32, 0x45, 0x31, + 0xE2, 0x81, 0x84, 0x33, 0x45, 0x31, 0xE2, 0x81, + 0x84, 0x34, 0x45, 0x31, 0xE2, 0x81, 0x84, 0x35, + 0x45, 0x31, 0xE2, 0x81, 0x84, 0x36, 0x45, 0x31, + 0xE2, 0x81, 0x84, 0x37, 0x45, 0x31, 0xE2, 0x81, + 0x84, 0x38, 0x45, 0x31, 0xE2, 0x81, 0x84, 0x39, + // Bytes 2240 - 227f + 0x45, 0x32, 0x30, 0xE6, 0x97, 0xA5, 0x45, 0x32, + 0x30, 0xE7, 0x82, 0xB9, 0x45, 0x32, 0x31, 0xE6, + 0x97, 0xA5, 0x45, 0x32, 0x31, 0xE7, 0x82, 0xB9, + 0x45, 0x32, 0x32, 0xE6, 0x97, 0xA5, 0x45, 0x32, + 0x32, 0xE7, 0x82, 0xB9, 0x45, 0x32, 0x33, 0xE6, + 0x97, 0xA5, 0x45, 0x32, 0x33, 0xE7, 0x82, 0xB9, + 0x45, 0x32, 0x34, 0xE6, 0x97, 0xA5, 0x45, 0x32, + 0x34, 0xE7, 0x82, 0xB9, 0x45, 0x32, 0x35, 0xE6, + // Bytes 2280 - 22bf + 0x97, 0xA5, 0x45, 0x32, 0x36, 0xE6, 0x97, 0xA5, + 0x45, 0x32, 0x37, 0xE6, 0x97, 0xA5, 0x45, 0x32, + 0x38, 0xE6, 0x97, 0xA5, 0x45, 0x32, 0x39, 0xE6, + 0x97, 0xA5, 0x45, 0x32, 0xE2, 0x81, 0x84, 0x33, + 0x45, 0x32, 0xE2, 0x81, 0x84, 0x35, 0x45, 0x33, + 0x30, 0xE6, 0x97, 0xA5, 0x45, 0x33, 0x31, 0xE6, + 0x97, 0xA5, 0x45, 0x33, 0xE2, 0x81, 0x84, 0x34, + 0x45, 0x33, 0xE2, 0x81, 0x84, 0x35, 0x45, 0x33, + // Bytes 22c0 - 22ff + 0xE2, 0x81, 0x84, 0x38, 0x45, 0x34, 0xE2, 0x81, + 0x84, 0x35, 0x45, 0x35, 0xE2, 0x81, 0x84, 0x36, + 0x45, 0x35, 0xE2, 0x81, 0x84, 0x38, 0x45, 0x37, + 0xE2, 0x81, 0x84, 0x38, 0x45, 0x41, 0xE2, 0x88, + 0x95, 0x6D, 0x45, 0x56, 0xE2, 0x88, 0x95, 0x6D, + 0x45, 0x6D, 0xE2, 0x88, 0x95, 0x73, 0x46, 0x31, + 0xE2, 0x81, 0x84, 0x31, 0x30, 0x46, 0x43, 0xE2, + 0x88, 0x95, 0x6B, 0x67, 0x46, 0x6D, 0xE2, 0x88, + // Bytes 2300 - 233f + 0x95, 0x73, 0x32, 0x46, 0xD8, 0xA8, 0xD8, 0xAD, + 0xD9, 0x8A, 0x46, 0xD8, 0xA8, 0xD8, 0xAE, 0xD9, + 0x8A, 0x46, 0xD8, 0xAA, 0xD8, 0xAC, 0xD9, 0x85, + 0x46, 0xD8, 0xAA, 0xD8, 0xAC, 0xD9, 0x89, 0x46, + 0xD8, 0xAA, 0xD8, 0xAC, 0xD9, 0x8A, 0x46, 0xD8, + 0xAA, 0xD8, 0xAD, 0xD8, 0xAC, 0x46, 0xD8, 0xAA, + 0xD8, 0xAD, 0xD9, 0x85, 0x46, 0xD8, 0xAA, 0xD8, + 0xAE, 0xD9, 0x85, 0x46, 0xD8, 0xAA, 0xD8, 0xAE, + // Bytes 2340 - 237f + 0xD9, 0x89, 0x46, 0xD8, 0xAA, 0xD8, 0xAE, 0xD9, + 0x8A, 0x46, 0xD8, 0xAA, 0xD9, 0x85, 0xD8, 0xAC, + 0x46, 0xD8, 0xAA, 0xD9, 0x85, 0xD8, 0xAD, 0x46, + 0xD8, 0xAA, 0xD9, 0x85, 0xD8, 0xAE, 0x46, 0xD8, + 0xAA, 0xD9, 0x85, 0xD9, 0x89, 0x46, 0xD8, 0xAA, + 0xD9, 0x85, 0xD9, 0x8A, 0x46, 0xD8, 0xAC, 0xD8, + 0xAD, 0xD9, 0x89, 0x46, 0xD8, 0xAC, 0xD8, 0xAD, + 0xD9, 0x8A, 0x46, 0xD8, 0xAC, 0xD9, 0x85, 0xD8, + // Bytes 2380 - 23bf + 0xAD, 0x46, 0xD8, 0xAC, 0xD9, 0x85, 0xD9, 0x89, + 0x46, 0xD8, 0xAC, 0xD9, 0x85, 0xD9, 0x8A, 0x46, + 0xD8, 0xAD, 0xD8, 0xAC, 0xD9, 0x8A, 0x46, 0xD8, + 0xAD, 0xD9, 0x85, 0xD9, 0x89, 0x46, 0xD8, 0xAD, + 0xD9, 0x85, 0xD9, 0x8A, 0x46, 0xD8, 0xB3, 0xD8, + 0xAC, 0xD8, 0xAD, 0x46, 0xD8, 0xB3, 0xD8, 0xAC, + 0xD9, 0x89, 0x46, 0xD8, 0xB3, 0xD8, 0xAD, 0xD8, + 0xAC, 0x46, 0xD8, 0xB3, 0xD8, 0xAE, 0xD9, 0x89, + // Bytes 23c0 - 23ff + 0x46, 0xD8, 0xB3, 0xD8, 0xAE, 0xD9, 0x8A, 0x46, + 0xD8, 0xB3, 0xD9, 0x85, 0xD8, 0xAC, 0x46, 0xD8, + 0xB3, 0xD9, 0x85, 0xD8, 0xAD, 0x46, 0xD8, 0xB3, + 0xD9, 0x85, 0xD9, 0x85, 0x46, 0xD8, 0xB4, 0xD8, + 0xAC, 0xD9, 0x8A, 0x46, 0xD8, 0xB4, 0xD8, 0xAD, + 0xD9, 0x85, 0x46, 0xD8, 0xB4, 0xD8, 0xAD, 0xD9, + 0x8A, 0x46, 0xD8, 0xB4, 0xD9, 0x85, 0xD8, 0xAE, + 0x46, 0xD8, 0xB4, 0xD9, 0x85, 0xD9, 0x85, 0x46, + // Bytes 2400 - 243f + 0xD8, 0xB5, 0xD8, 0xAD, 0xD8, 0xAD, 0x46, 0xD8, + 0xB5, 0xD8, 0xAD, 0xD9, 0x8A, 0x46, 0xD8, 0xB5, + 0xD9, 0x84, 0xD9, 0x89, 0x46, 0xD8, 0xB5, 0xD9, + 0x84, 0xDB, 0x92, 0x46, 0xD8, 0xB5, 0xD9, 0x85, + 0xD9, 0x85, 0x46, 0xD8, 0xB6, 0xD8, 0xAD, 0xD9, + 0x89, 0x46, 0xD8, 0xB6, 0xD8, 0xAD, 0xD9, 0x8A, + 0x46, 0xD8, 0xB6, 0xD8, 0xAE, 0xD9, 0x85, 0x46, + 0xD8, 0xB7, 0xD9, 0x85, 0xD8, 0xAD, 0x46, 0xD8, + // Bytes 2440 - 247f + 0xB7, 0xD9, 0x85, 0xD9, 0x85, 0x46, 0xD8, 0xB7, + 0xD9, 0x85, 0xD9, 0x8A, 0x46, 0xD8, 0xB9, 0xD8, + 0xAC, 0xD9, 0x85, 0x46, 0xD8, 0xB9, 0xD9, 0x85, + 0xD9, 0x85, 0x46, 0xD8, 0xB9, 0xD9, 0x85, 0xD9, + 0x89, 0x46, 0xD8, 0xB9, 0xD9, 0x85, 0xD9, 0x8A, + 0x46, 0xD8, 0xBA, 0xD9, 0x85, 0xD9, 0x85, 0x46, + 0xD8, 0xBA, 0xD9, 0x85, 0xD9, 0x89, 0x46, 0xD8, + 0xBA, 0xD9, 0x85, 0xD9, 0x8A, 0x46, 0xD9, 0x81, + // Bytes 2480 - 24bf + 0xD8, 0xAE, 0xD9, 0x85, 0x46, 0xD9, 0x81, 0xD9, + 0x85, 0xD9, 0x8A, 0x46, 0xD9, 0x82, 0xD9, 0x84, + 0xDB, 0x92, 0x46, 0xD9, 0x82, 0xD9, 0x85, 0xD8, + 0xAD, 0x46, 0xD9, 0x82, 0xD9, 0x85, 0xD9, 0x85, + 0x46, 0xD9, 0x82, 0xD9, 0x85, 0xD9, 0x8A, 0x46, + 0xD9, 0x83, 0xD9, 0x85, 0xD9, 0x85, 0x46, 0xD9, + 0x83, 0xD9, 0x85, 0xD9, 0x8A, 0x46, 0xD9, 0x84, + 0xD8, 0xAC, 0xD8, 0xAC, 0x46, 0xD9, 0x84, 0xD8, + // Bytes 24c0 - 24ff + 0xAC, 0xD9, 0x85, 0x46, 0xD9, 0x84, 0xD8, 0xAC, + 0xD9, 0x8A, 0x46, 0xD9, 0x84, 0xD8, 0xAD, 0xD9, + 0x85, 0x46, 0xD9, 0x84, 0xD8, 0xAD, 0xD9, 0x89, + 0x46, 0xD9, 0x84, 0xD8, 0xAD, 0xD9, 0x8A, 0x46, + 0xD9, 0x84, 0xD8, 0xAE, 0xD9, 0x85, 0x46, 0xD9, + 0x84, 0xD9, 0x85, 0xD8, 0xAD, 0x46, 0xD9, 0x84, + 0xD9, 0x85, 0xD9, 0x8A, 0x46, 0xD9, 0x85, 0xD8, + 0xAC, 0xD8, 0xAD, 0x46, 0xD9, 0x85, 0xD8, 0xAC, + // Bytes 2500 - 253f + 0xD8, 0xAE, 0x46, 0xD9, 0x85, 0xD8, 0xAC, 0xD9, + 0x85, 0x46, 0xD9, 0x85, 0xD8, 0xAC, 0xD9, 0x8A, + 0x46, 0xD9, 0x85, 0xD8, 0xAD, 0xD8, 0xAC, 0x46, + 0xD9, 0x85, 0xD8, 0xAD, 0xD9, 0x85, 0x46, 0xD9, + 0x85, 0xD8, 0xAD, 0xD9, 0x8A, 0x46, 0xD9, 0x85, + 0xD8, 0xAE, 0xD8, 0xAC, 0x46, 0xD9, 0x85, 0xD8, + 0xAE, 0xD9, 0x85, 0x46, 0xD9, 0x85, 0xD8, 0xAE, + 0xD9, 0x8A, 0x46, 0xD9, 0x85, 0xD9, 0x85, 0xD9, + // Bytes 2540 - 257f + 0x8A, 0x46, 0xD9, 0x86, 0xD8, 0xAC, 0xD8, 0xAD, + 0x46, 0xD9, 0x86, 0xD8, 0xAC, 0xD9, 0x85, 0x46, + 0xD9, 0x86, 0xD8, 0xAC, 0xD9, 0x89, 0x46, 0xD9, + 0x86, 0xD8, 0xAC, 0xD9, 0x8A, 0x46, 0xD9, 0x86, + 0xD8, 0xAD, 0xD9, 0x85, 0x46, 0xD9, 0x86, 0xD8, + 0xAD, 0xD9, 0x89, 0x46, 0xD9, 0x86, 0xD8, 0xAD, + 0xD9, 0x8A, 0x46, 0xD9, 0x86, 0xD9, 0x85, 0xD9, + 0x89, 0x46, 0xD9, 0x86, 0xD9, 0x85, 0xD9, 0x8A, + // Bytes 2580 - 25bf + 0x46, 0xD9, 0x87, 0xD9, 0x85, 0xD8, 0xAC, 0x46, + 0xD9, 0x87, 0xD9, 0x85, 0xD9, 0x85, 0x46, 0xD9, + 0x8A, 0xD8, 0xAC, 0xD9, 0x8A, 0x46, 0xD9, 0x8A, + 0xD8, 0xAD, 0xD9, 0x8A, 0x46, 0xD9, 0x8A, 0xD9, + 0x85, 0xD9, 0x85, 0x46, 0xD9, 0x8A, 0xD9, 0x85, + 0xD9, 0x8A, 0x46, 0xD9, 0x8A, 0xD9, 0x94, 0xD8, + 0xA7, 0x46, 0xD9, 0x8A, 0xD9, 0x94, 0xD8, 0xAC, + 0x46, 0xD9, 0x8A, 0xD9, 0x94, 0xD8, 0xAD, 0x46, + // Bytes 25c0 - 25ff + 0xD9, 0x8A, 0xD9, 0x94, 0xD8, 0xAE, 0x46, 0xD9, + 0x8A, 0xD9, 0x94, 0xD8, 0xB1, 0x46, 0xD9, 0x8A, + 0xD9, 0x94, 0xD8, 0xB2, 0x46, 0xD9, 0x8A, 0xD9, + 0x94, 0xD9, 0x85, 0x46, 0xD9, 0x8A, 0xD9, 0x94, + 0xD9, 0x86, 0x46, 0xD9, 0x8A, 0xD9, 0x94, 0xD9, + 0x87, 0x46, 0xD9, 0x8A, 0xD9, 0x94, 0xD9, 0x88, + 0x46, 0xD9, 0x8A, 0xD9, 0x94, 0xD9, 0x89, 0x46, + 0xD9, 0x8A, 0xD9, 0x94, 0xD9, 0x8A, 0x46, 0xD9, + // Bytes 2600 - 263f + 0x8A, 0xD9, 0x94, 0xDB, 0x86, 0x46, 0xD9, 0x8A, + 0xD9, 0x94, 0xDB, 0x87, 0x46, 0xD9, 0x8A, 0xD9, + 0x94, 0xDB, 0x88, 0x46, 0xD9, 0x8A, 0xD9, 0x94, + 0xDB, 0x90, 0x46, 0xD9, 0x8A, 0xD9, 0x94, 0xDB, + 0x95, 0x46, 0xE0, 0xB9, 0x8D, 0xE0, 0xB8, 0xB2, + 0x46, 0xE0, 0xBA, 0xAB, 0xE0, 0xBA, 0x99, 0x46, + 0xE0, 0xBA, 0xAB, 0xE0, 0xBA, 0xA1, 0x46, 0xE0, + 0xBB, 0x8D, 0xE0, 0xBA, 0xB2, 0x46, 0xE0, 0xBD, + // Bytes 2640 - 267f + 0x80, 0xE0, 0xBE, 0xB5, 0x46, 0xE0, 0xBD, 0x82, + 0xE0, 0xBE, 0xB7, 0x46, 0xE0, 0xBD, 0x8C, 0xE0, + 0xBE, 0xB7, 0x46, 0xE0, 0xBD, 0x91, 0xE0, 0xBE, + 0xB7, 0x46, 0xE0, 0xBD, 0x96, 0xE0, 0xBE, 0xB7, + 0x46, 0xE0, 0xBD, 0x9B, 0xE0, 0xBE, 0xB7, 0x46, + 0xE0, 0xBE, 0x90, 0xE0, 0xBE, 0xB5, 0x46, 0xE0, + 0xBE, 0x92, 0xE0, 0xBE, 0xB7, 0x46, 0xE0, 0xBE, + 0x9C, 0xE0, 0xBE, 0xB7, 0x46, 0xE0, 0xBE, 0xA1, + // Bytes 2680 - 26bf + 0xE0, 0xBE, 0xB7, 0x46, 0xE0, 0xBE, 0xA6, 0xE0, + 0xBE, 0xB7, 0x46, 0xE0, 0xBE, 0xAB, 0xE0, 0xBE, + 0xB7, 0x46, 0xE2, 0x80, 0xB2, 0xE2, 0x80, 0xB2, + 0x46, 0xE2, 0x80, 0xB5, 0xE2, 0x80, 0xB5, 0x46, + 0xE2, 0x88, 0xAB, 0xE2, 0x88, 0xAB, 0x46, 0xE2, + 0x88, 0xAE, 0xE2, 0x88, 0xAE, 0x46, 0xE3, 0x81, + 0xBB, 0xE3, 0x81, 0x8B, 0x46, 0xE3, 0x82, 0x88, + 0xE3, 0x82, 0x8A, 0x46, 0xE3, 0x82, 0xAD, 0xE3, + // Bytes 26c0 - 26ff + 0x83, 0xAD, 0x46, 0xE3, 0x82, 0xB3, 0xE3, 0x82, + 0xB3, 0x46, 0xE3, 0x82, 0xB3, 0xE3, 0x83, 0x88, + 0x46, 0xE3, 0x83, 0x88, 0xE3, 0x83, 0xB3, 0x46, + 0xE3, 0x83, 0x8A, 0xE3, 0x83, 0x8E, 0x46, 0xE3, + 0x83, 0x9B, 0xE3, 0x83, 0xB3, 0x46, 0xE3, 0x83, + 0x9F, 0xE3, 0x83, 0xAA, 0x46, 0xE3, 0x83, 0xAA, + 0xE3, 0x83, 0xA9, 0x46, 0xE3, 0x83, 0xAC, 0xE3, + 0x83, 0xA0, 0x46, 0xE5, 0xA4, 0xA7, 0xE6, 0xAD, + // Bytes 2700 - 273f + 0xA3, 0x46, 0xE5, 0xB9, 0xB3, 0xE6, 0x88, 0x90, + 0x46, 0xE6, 0x98, 0x8E, 0xE6, 0xB2, 0xBB, 0x46, + 0xE6, 0x98, 0xAD, 0xE5, 0x92, 0x8C, 0x47, 0x72, + 0x61, 0x64, 0xE2, 0x88, 0x95, 0x73, 0x47, 0xE3, + 0x80, 0x94, 0x53, 0xE3, 0x80, 0x95, 0x48, 0x28, + 0xE1, 0x84, 0x80, 0xE1, 0x85, 0xA1, 0x29, 0x48, + 0x28, 0xE1, 0x84, 0x82, 0xE1, 0x85, 0xA1, 0x29, + 0x48, 0x28, 0xE1, 0x84, 0x83, 0xE1, 0x85, 0xA1, + // Bytes 2740 - 277f + 0x29, 0x48, 0x28, 0xE1, 0x84, 0x85, 0xE1, 0x85, + 0xA1, 0x29, 0x48, 0x28, 0xE1, 0x84, 0x86, 0xE1, + 0x85, 0xA1, 0x29, 0x48, 0x28, 0xE1, 0x84, 0x87, + 0xE1, 0x85, 0xA1, 0x29, 0x48, 0x28, 0xE1, 0x84, + 0x89, 0xE1, 0x85, 0xA1, 0x29, 0x48, 0x28, 0xE1, + 0x84, 0x8B, 0xE1, 0x85, 0xA1, 0x29, 0x48, 0x28, + 0xE1, 0x84, 0x8C, 0xE1, 0x85, 0xA1, 0x29, 0x48, + 0x28, 0xE1, 0x84, 0x8C, 0xE1, 0x85, 0xAE, 0x29, + // Bytes 2780 - 27bf + 0x48, 0x28, 0xE1, 0x84, 0x8E, 0xE1, 0x85, 0xA1, + 0x29, 0x48, 0x28, 0xE1, 0x84, 0x8F, 0xE1, 0x85, + 0xA1, 0x29, 0x48, 0x28, 0xE1, 0x84, 0x90, 0xE1, + 0x85, 0xA1, 0x29, 0x48, 0x28, 0xE1, 0x84, 0x91, + 0xE1, 0x85, 0xA1, 0x29, 0x48, 0x28, 0xE1, 0x84, + 0x92, 0xE1, 0x85, 0xA1, 0x29, 0x48, 0x72, 0x61, + 0x64, 0xE2, 0x88, 0x95, 0x73, 0x32, 0x48, 0xD8, + 0xA7, 0xD9, 0x83, 0xD8, 0xA8, 0xD8, 0xB1, 0x48, + // Bytes 27c0 - 27ff + 0xD8, 0xA7, 0xD9, 0x84, 0xD9, 0x84, 0xD9, 0x87, + 0x48, 0xD8, 0xB1, 0xD8, 0xB3, 0xD9, 0x88, 0xD9, + 0x84, 0x48, 0xD8, 0xB1, 0xDB, 0x8C, 0xD8, 0xA7, + 0xD9, 0x84, 0x48, 0xD8, 0xB5, 0xD9, 0x84, 0xD8, + 0xB9, 0xD9, 0x85, 0x48, 0xD8, 0xB9, 0xD9, 0x84, + 0xD9, 0x8A, 0xD9, 0x87, 0x48, 0xD9, 0x85, 0xD8, + 0xAD, 0xD9, 0x85, 0xD8, 0xAF, 0x48, 0xD9, 0x88, + 0xD8, 0xB3, 0xD9, 0x84, 0xD9, 0x85, 0x49, 0xE2, + // Bytes 2800 - 283f + 0x80, 0xB2, 0xE2, 0x80, 0xB2, 0xE2, 0x80, 0xB2, + 0x49, 0xE2, 0x80, 0xB5, 0xE2, 0x80, 0xB5, 0xE2, + 0x80, 0xB5, 0x49, 0xE2, 0x88, 0xAB, 0xE2, 0x88, + 0xAB, 0xE2, 0x88, 0xAB, 0x49, 0xE2, 0x88, 0xAE, + 0xE2, 0x88, 0xAE, 0xE2, 0x88, 0xAE, 0x49, 0xE3, + 0x80, 0x94, 0xE4, 0xB8, 0x89, 0xE3, 0x80, 0x95, + 0x49, 0xE3, 0x80, 0x94, 0xE4, 0xBA, 0x8C, 0xE3, + 0x80, 0x95, 0x49, 0xE3, 0x80, 0x94, 0xE5, 0x8B, + // Bytes 2840 - 287f + 0x9D, 0xE3, 0x80, 0x95, 0x49, 0xE3, 0x80, 0x94, + 0xE5, 0xAE, 0x89, 0xE3, 0x80, 0x95, 0x49, 0xE3, + 0x80, 0x94, 0xE6, 0x89, 0x93, 0xE3, 0x80, 0x95, + 0x49, 0xE3, 0x80, 0x94, 0xE6, 0x95, 0x97, 0xE3, + 0x80, 0x95, 0x49, 0xE3, 0x80, 0x94, 0xE6, 0x9C, + 0xAC, 0xE3, 0x80, 0x95, 0x49, 0xE3, 0x80, 0x94, + 0xE7, 0x82, 0xB9, 0xE3, 0x80, 0x95, 0x49, 0xE3, + 0x80, 0x94, 0xE7, 0x9B, 0x97, 0xE3, 0x80, 0x95, + // Bytes 2880 - 28bf + 0x49, 0xE3, 0x82, 0xA2, 0xE3, 0x83, 0xBC, 0xE3, + 0x83, 0xAB, 0x49, 0xE3, 0x82, 0xA4, 0xE3, 0x83, + 0xB3, 0xE3, 0x83, 0x81, 0x49, 0xE3, 0x82, 0xA6, + 0xE3, 0x82, 0xA9, 0xE3, 0x83, 0xB3, 0x49, 0xE3, + 0x82, 0xAA, 0xE3, 0x83, 0xB3, 0xE3, 0x82, 0xB9, + 0x49, 0xE3, 0x82, 0xAA, 0xE3, 0x83, 0xBC, 0xE3, + 0x83, 0xA0, 0x49, 0xE3, 0x82, 0xAB, 0xE3, 0x82, + 0xA4, 0xE3, 0x83, 0xAA, 0x49, 0xE3, 0x82, 0xB1, + // Bytes 28c0 - 28ff + 0xE3, 0x83, 0xBC, 0xE3, 0x82, 0xB9, 0x49, 0xE3, + 0x82, 0xB3, 0xE3, 0x83, 0xAB, 0xE3, 0x83, 0x8A, + 0x49, 0xE3, 0x82, 0xBB, 0xE3, 0x83, 0xB3, 0xE3, + 0x83, 0x81, 0x49, 0xE3, 0x82, 0xBB, 0xE3, 0x83, + 0xB3, 0xE3, 0x83, 0x88, 0x49, 0xE3, 0x83, 0x86, + 0xE3, 0x82, 0x99, 0xE3, 0x82, 0xB7, 0x49, 0xE3, + 0x83, 0x88, 0xE3, 0x82, 0x99, 0xE3, 0x83, 0xAB, + 0x49, 0xE3, 0x83, 0x8E, 0xE3, 0x83, 0x83, 0xE3, + // Bytes 2900 - 293f + 0x83, 0x88, 0x49, 0xE3, 0x83, 0x8F, 0xE3, 0x82, + 0xA4, 0xE3, 0x83, 0x84, 0x49, 0xE3, 0x83, 0x92, + 0xE3, 0x82, 0x99, 0xE3, 0x83, 0xAB, 0x49, 0xE3, + 0x83, 0x92, 0xE3, 0x82, 0x9A, 0xE3, 0x82, 0xB3, + 0x49, 0xE3, 0x83, 0x95, 0xE3, 0x83, 0xA9, 0xE3, + 0x83, 0xB3, 0x49, 0xE3, 0x83, 0x98, 0xE3, 0x82, + 0x9A, 0xE3, 0x82, 0xBD, 0x49, 0xE3, 0x83, 0x98, + 0xE3, 0x83, 0xAB, 0xE3, 0x83, 0x84, 0x49, 0xE3, + // Bytes 2940 - 297f + 0x83, 0x9B, 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0xAB, + 0x49, 0xE3, 0x83, 0x9B, 0xE3, 0x83, 0xBC, 0xE3, + 0x83, 0xB3, 0x49, 0xE3, 0x83, 0x9E, 0xE3, 0x82, + 0xA4, 0xE3, 0x83, 0xAB, 0x49, 0xE3, 0x83, 0x9E, + 0xE3, 0x83, 0x83, 0xE3, 0x83, 0x8F, 0x49, 0xE3, + 0x83, 0x9E, 0xE3, 0x83, 0xAB, 0xE3, 0x82, 0xAF, + 0x49, 0xE3, 0x83, 0xA4, 0xE3, 0x83, 0xBC, 0xE3, + 0x83, 0xAB, 0x49, 0xE3, 0x83, 0xA6, 0xE3, 0x82, + // Bytes 2980 - 29bf + 0xA2, 0xE3, 0x83, 0xB3, 0x49, 0xE3, 0x83, 0xAF, + 0xE3, 0x83, 0x83, 0xE3, 0x83, 0x88, 0x4C, 0xE2, + 0x80, 0xB2, 0xE2, 0x80, 0xB2, 0xE2, 0x80, 0xB2, + 0xE2, 0x80, 0xB2, 0x4C, 0xE2, 0x88, 0xAB, 0xE2, + 0x88, 0xAB, 0xE2, 0x88, 0xAB, 0xE2, 0x88, 0xAB, + 0x4C, 0xE3, 0x82, 0xA2, 0xE3, 0x83, 0xAB, 0xE3, + 0x83, 0x95, 0xE3, 0x82, 0xA1, 0x4C, 0xE3, 0x82, + 0xA8, 0xE3, 0x83, 0xBC, 0xE3, 0x82, 0xAB, 0xE3, + // Bytes 29c0 - 29ff + 0x83, 0xBC, 0x4C, 0xE3, 0x82, 0xAB, 0xE3, 0x82, + 0x99, 0xE3, 0x83, 0xAD, 0xE3, 0x83, 0xB3, 0x4C, + 0xE3, 0x82, 0xAB, 0xE3, 0x82, 0x99, 0xE3, 0x83, + 0xB3, 0xE3, 0x83, 0x9E, 0x4C, 0xE3, 0x82, 0xAB, + 0xE3, 0x83, 0xA9, 0xE3, 0x83, 0x83, 0xE3, 0x83, + 0x88, 0x4C, 0xE3, 0x82, 0xAB, 0xE3, 0x83, 0xAD, + 0xE3, 0x83, 0xAA, 0xE3, 0x83, 0xBC, 0x4C, 0xE3, + 0x82, 0xAD, 0xE3, 0x82, 0x99, 0xE3, 0x83, 0x8B, + // Bytes 2a00 - 2a3f + 0xE3, 0x83, 0xBC, 0x4C, 0xE3, 0x82, 0xAD, 0xE3, + 0x83, 0xA5, 0xE3, 0x83, 0xAA, 0xE3, 0x83, 0xBC, + 0x4C, 0xE3, 0x82, 0xAF, 0xE3, 0x82, 0x99, 0xE3, + 0x83, 0xA9, 0xE3, 0x83, 0xA0, 0x4C, 0xE3, 0x82, + 0xAF, 0xE3, 0x83, 0xAD, 0xE3, 0x83, 0xBC, 0xE3, + 0x83, 0x8D, 0x4C, 0xE3, 0x82, 0xB5, 0xE3, 0x82, + 0xA4, 0xE3, 0x82, 0xAF, 0xE3, 0x83, 0xAB, 0x4C, + 0xE3, 0x82, 0xBF, 0xE3, 0x82, 0x99, 0xE3, 0x83, + // Bytes 2a40 - 2a7f + 0xBC, 0xE3, 0x82, 0xB9, 0x4C, 0xE3, 0x83, 0x8F, + 0xE3, 0x82, 0x9A, 0xE3, 0x83, 0xBC, 0xE3, 0x83, + 0x84, 0x4C, 0xE3, 0x83, 0x92, 0xE3, 0x82, 0x9A, + 0xE3, 0x82, 0xAF, 0xE3, 0x83, 0xAB, 0x4C, 0xE3, + 0x83, 0x95, 0xE3, 0x82, 0xA3, 0xE3, 0x83, 0xBC, + 0xE3, 0x83, 0x88, 0x4C, 0xE3, 0x83, 0x98, 0xE3, + 0x82, 0x99, 0xE3, 0x83, 0xBC, 0xE3, 0x82, 0xBF, + 0x4C, 0xE3, 0x83, 0x98, 0xE3, 0x82, 0x9A, 0xE3, + // Bytes 2a80 - 2abf + 0x83, 0x8B, 0xE3, 0x83, 0x92, 0x4C, 0xE3, 0x83, + 0x98, 0xE3, 0x82, 0x9A, 0xE3, 0x83, 0xB3, 0xE3, + 0x82, 0xB9, 0x4C, 0xE3, 0x83, 0x9B, 0xE3, 0x82, + 0x99, 0xE3, 0x83, 0xAB, 0xE3, 0x83, 0x88, 0x4C, + 0xE3, 0x83, 0x9E, 0xE3, 0x82, 0xA4, 0xE3, 0x82, + 0xAF, 0xE3, 0x83, 0xAD, 0x4C, 0xE3, 0x83, 0x9F, + 0xE3, 0x82, 0xAF, 0xE3, 0x83, 0xAD, 0xE3, 0x83, + 0xB3, 0x4C, 0xE3, 0x83, 0xA1, 0xE3, 0x83, 0xBC, + // Bytes 2ac0 - 2aff + 0xE3, 0x83, 0x88, 0xE3, 0x83, 0xAB, 0x4C, 0xE3, + 0x83, 0xAA, 0xE3, 0x83, 0x83, 0xE3, 0x83, 0x88, + 0xE3, 0x83, 0xAB, 0x4C, 0xE3, 0x83, 0xAB, 0xE3, + 0x83, 0x92, 0xE3, 0x82, 0x9A, 0xE3, 0x83, 0xBC, + 0x4C, 0xE6, 0xA0, 0xAA, 0xE5, 0xBC, 0x8F, 0xE4, + 0xBC, 0x9A, 0xE7, 0xA4, 0xBE, 0x4E, 0x28, 0xE1, + 0x84, 0x8B, 0xE1, 0x85, 0xA9, 0xE1, 0x84, 0x92, + 0xE1, 0x85, 0xAE, 0x29, 0x4F, 0xD8, 0xAC, 0xD9, + // Bytes 2b00 - 2b3f + 0x84, 0x20, 0xD8, 0xAC, 0xD9, 0x84, 0xD8, 0xA7, + 0xD9, 0x84, 0xD9, 0x87, 0x4F, 0xE3, 0x82, 0xA2, + 0xE3, 0x83, 0x8F, 0xE3, 0x82, 0x9A, 0xE3, 0x83, + 0xBC, 0xE3, 0x83, 0x88, 0x4F, 0xE3, 0x82, 0xA2, + 0xE3, 0x83, 0xB3, 0xE3, 0x83, 0x98, 0xE3, 0x82, + 0x9A, 0xE3, 0x82, 0xA2, 0x4F, 0xE3, 0x82, 0xAD, + 0xE3, 0x83, 0xAD, 0xE3, 0x83, 0xAF, 0xE3, 0x83, + 0x83, 0xE3, 0x83, 0x88, 0x4F, 0xE3, 0x82, 0xB5, + // Bytes 2b40 - 2b7f + 0xE3, 0x83, 0xB3, 0xE3, 0x83, 0x81, 0xE3, 0x83, + 0xBC, 0xE3, 0x83, 0xA0, 0x4F, 0xE3, 0x83, 0x8F, + 0xE3, 0x82, 0x99, 0xE3, 0x83, 0xBC, 0xE3, 0x83, + 0xAC, 0xE3, 0x83, 0xAB, 0x4F, 0xE3, 0x83, 0x98, + 0xE3, 0x82, 0xAF, 0xE3, 0x82, 0xBF, 0xE3, 0x83, + 0xBC, 0xE3, 0x83, 0xAB, 0x4F, 0xE3, 0x83, 0x9B, + 0xE3, 0x82, 0x9A, 0xE3, 0x82, 0xA4, 0xE3, 0x83, + 0xB3, 0xE3, 0x83, 0x88, 0x4F, 0xE3, 0x83, 0x9E, + // Bytes 2b80 - 2bbf + 0xE3, 0x83, 0xB3, 0xE3, 0x82, 0xB7, 0xE3, 0x83, + 0xA7, 0xE3, 0x83, 0xB3, 0x4F, 0xE3, 0x83, 0xA1, + 0xE3, 0x82, 0xAB, 0xE3, 0x82, 0x99, 0xE3, 0x83, + 0x88, 0xE3, 0x83, 0xB3, 0x4F, 0xE3, 0x83, 0xAB, + 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0x95, 0xE3, 0x82, + 0x99, 0xE3, 0x83, 0xAB, 0x51, 0x28, 0xE1, 0x84, + 0x8B, 0xE1, 0x85, 0xA9, 0xE1, 0x84, 0x8C, 0xE1, + 0x85, 0xA5, 0xE1, 0x86, 0xAB, 0x29, 0x52, 0xE3, + // Bytes 2bc0 - 2bff + 0x82, 0xAD, 0xE3, 0x82, 0x99, 0xE3, 0x83, 0xAB, + 0xE3, 0x82, 0xBF, 0xE3, 0x82, 0x99, 0xE3, 0x83, + 0xBC, 0x52, 0xE3, 0x82, 0xAD, 0xE3, 0x83, 0xAD, + 0xE3, 0x82, 0xAF, 0xE3, 0x82, 0x99, 0xE3, 0x83, + 0xA9, 0xE3, 0x83, 0xA0, 0x52, 0xE3, 0x82, 0xAD, + 0xE3, 0x83, 0xAD, 0xE3, 0x83, 0xA1, 0xE3, 0x83, + 0xBC, 0xE3, 0x83, 0x88, 0xE3, 0x83, 0xAB, 0x52, + 0xE3, 0x82, 0xAF, 0xE3, 0x82, 0x99, 0xE3, 0x83, + // Bytes 2c00 - 2c3f + 0xA9, 0xE3, 0x83, 0xA0, 0xE3, 0x83, 0x88, 0xE3, + 0x83, 0xB3, 0x52, 0xE3, 0x82, 0xAF, 0xE3, 0x83, + 0xAB, 0xE3, 0x82, 0xBB, 0xE3, 0x82, 0x99, 0xE3, + 0x82, 0xA4, 0xE3, 0x83, 0xAD, 0x52, 0xE3, 0x83, + 0x8F, 0xE3, 0x82, 0x9A, 0xE3, 0x83, 0xBC, 0xE3, + 0x82, 0xBB, 0xE3, 0x83, 0xB3, 0xE3, 0x83, 0x88, + 0x52, 0xE3, 0x83, 0x92, 0xE3, 0x82, 0x9A, 0xE3, + 0x82, 0xA2, 0xE3, 0x82, 0xB9, 0xE3, 0x83, 0x88, + // Bytes 2c40 - 2c7f + 0xE3, 0x83, 0xAB, 0x52, 0xE3, 0x83, 0x95, 0xE3, + 0x82, 0x99, 0xE3, 0x83, 0x83, 0xE3, 0x82, 0xB7, + 0xE3, 0x82, 0xA7, 0xE3, 0x83, 0xAB, 0x52, 0xE3, + 0x83, 0x9F, 0xE3, 0x83, 0xAA, 0xE3, 0x83, 0x8F, + 0xE3, 0x82, 0x99, 0xE3, 0x83, 0xBC, 0xE3, 0x83, + 0xAB, 0x52, 0xE3, 0x83, 0xAC, 0xE3, 0x83, 0xB3, + 0xE3, 0x83, 0x88, 0xE3, 0x82, 0xB1, 0xE3, 0x82, + 0x99, 0xE3, 0x83, 0xB3, 0x61, 0xD8, 0xB5, 0xD9, + // Bytes 2c80 - 2cbf + 0x84, 0xD9, 0x89, 0x20, 0xD8, 0xA7, 0xD9, 0x84, + 0xD9, 0x84, 0xD9, 0x87, 0x20, 0xD8, 0xB9, 0xD9, + 0x84, 0xD9, 0x8A, 0xD9, 0x87, 0x20, 0xD9, 0x88, + 0xD8, 0xB3, 0xD9, 0x84, 0xD9, 0x85, 0x06, 0xE0, + 0xA7, 0x87, 0xE0, 0xA6, 0xBE, 0x01, 0x06, 0xE0, + 0xA7, 0x87, 0xE0, 0xA7, 0x97, 0x01, 0x06, 0xE0, + 0xAD, 0x87, 0xE0, 0xAC, 0xBE, 0x01, 0x06, 0xE0, + 0xAD, 0x87, 0xE0, 0xAD, 0x96, 0x01, 0x06, 0xE0, + // Bytes 2cc0 - 2cff + 0xAD, 0x87, 0xE0, 0xAD, 0x97, 0x01, 0x06, 0xE0, + 0xAE, 0x92, 0xE0, 0xAF, 0x97, 0x01, 0x06, 0xE0, + 0xAF, 0x86, 0xE0, 0xAE, 0xBE, 0x01, 0x06, 0xE0, + 0xAF, 0x86, 0xE0, 0xAF, 0x97, 0x01, 0x06, 0xE0, + 0xAF, 0x87, 0xE0, 0xAE, 0xBE, 0x01, 0x06, 0xE0, + 0xB2, 0xBF, 0xE0, 0xB3, 0x95, 0x01, 0x06, 0xE0, + 0xB3, 0x86, 0xE0, 0xB3, 0x95, 0x01, 0x06, 0xE0, + 0xB3, 0x86, 0xE0, 0xB3, 0x96, 0x01, 0x06, 0xE0, + // Bytes 2d00 - 2d3f + 0xB5, 0x86, 0xE0, 0xB4, 0xBE, 0x01, 0x06, 0xE0, + 0xB5, 0x86, 0xE0, 0xB5, 0x97, 0x01, 0x06, 0xE0, + 0xB5, 0x87, 0xE0, 0xB4, 0xBE, 0x01, 0x06, 0xE0, + 0xB7, 0x99, 0xE0, 0xB7, 0x9F, 0x01, 0x06, 0xE1, + 0x80, 0xA5, 0xE1, 0x80, 0xAE, 0x01, 0x06, 0xE1, + 0xAC, 0x85, 0xE1, 0xAC, 0xB5, 0x01, 0x06, 0xE1, + 0xAC, 0x87, 0xE1, 0xAC, 0xB5, 0x01, 0x06, 0xE1, + 0xAC, 0x89, 0xE1, 0xAC, 0xB5, 0x01, 0x06, 0xE1, + // Bytes 2d40 - 2d7f + 0xAC, 0x8B, 0xE1, 0xAC, 0xB5, 0x01, 0x06, 0xE1, + 0xAC, 0x8D, 0xE1, 0xAC, 0xB5, 0x01, 0x06, 0xE1, + 0xAC, 0x91, 0xE1, 0xAC, 0xB5, 0x01, 0x06, 0xE1, + 0xAC, 0xBA, 0xE1, 0xAC, 0xB5, 0x01, 0x06, 0xE1, + 0xAC, 0xBC, 0xE1, 0xAC, 0xB5, 0x01, 0x06, 0xE1, + 0xAC, 0xBE, 0xE1, 0xAC, 0xB5, 0x01, 0x06, 0xE1, + 0xAC, 0xBF, 0xE1, 0xAC, 0xB5, 0x01, 0x06, 0xE1, + 0xAD, 0x82, 0xE1, 0xAC, 0xB5, 0x01, 0x08, 0xF0, + // Bytes 2d80 - 2dbf + 0x91, 0x84, 0xB1, 0xF0, 0x91, 0x84, 0xA7, 0x01, + 0x08, 0xF0, 0x91, 0x84, 0xB2, 0xF0, 0x91, 0x84, + 0xA7, 0x01, 0x08, 0xF0, 0x91, 0x8D, 0x87, 0xF0, + 0x91, 0x8C, 0xBE, 0x01, 0x08, 0xF0, 0x91, 0x8D, + 0x87, 0xF0, 0x91, 0x8D, 0x97, 0x01, 0x08, 0xF0, + 0x91, 0x92, 0xB9, 0xF0, 0x91, 0x92, 0xB0, 0x01, + 0x08, 0xF0, 0x91, 0x92, 0xB9, 0xF0, 0x91, 0x92, + 0xBA, 0x01, 0x08, 0xF0, 0x91, 0x92, 0xB9, 0xF0, + // Bytes 2dc0 - 2dff + 0x91, 0x92, 0xBD, 0x01, 0x08, 0xF0, 0x91, 0x96, + 0xB8, 0xF0, 0x91, 0x96, 0xAF, 0x01, 0x08, 0xF0, + 0x91, 0x96, 0xB9, 0xF0, 0x91, 0x96, 0xAF, 0x01, + 0x09, 0xE0, 0xB3, 0x86, 0xE0, 0xB3, 0x82, 0xE0, + 0xB3, 0x95, 0x02, 0x09, 0xE0, 0xB7, 0x99, 0xE0, + 0xB7, 0x8F, 0xE0, 0xB7, 0x8A, 0x12, 0x44, 0x44, + 0x5A, 0xCC, 0x8C, 0xC9, 0x44, 0x44, 0x7A, 0xCC, + 0x8C, 0xC9, 0x44, 0x64, 0x7A, 0xCC, 0x8C, 0xC9, + // Bytes 2e00 - 2e3f + 0x46, 0xD9, 0x84, 0xD8, 0xA7, 0xD9, 0x93, 0xC9, + 0x46, 0xD9, 0x84, 0xD8, 0xA7, 0xD9, 0x94, 0xC9, + 0x46, 0xD9, 0x84, 0xD8, 0xA7, 0xD9, 0x95, 0xB5, + 0x46, 0xE1, 0x84, 0x80, 0xE1, 0x85, 0xA1, 0x01, + 0x46, 0xE1, 0x84, 0x82, 0xE1, 0x85, 0xA1, 0x01, + 0x46, 0xE1, 0x84, 0x83, 0xE1, 0x85, 0xA1, 0x01, + 0x46, 0xE1, 0x84, 0x85, 0xE1, 0x85, 0xA1, 0x01, + 0x46, 0xE1, 0x84, 0x86, 0xE1, 0x85, 0xA1, 0x01, + // Bytes 2e40 - 2e7f + 0x46, 0xE1, 0x84, 0x87, 0xE1, 0x85, 0xA1, 0x01, + 0x46, 0xE1, 0x84, 0x89, 0xE1, 0x85, 0xA1, 0x01, + 0x46, 0xE1, 0x84, 0x8B, 0xE1, 0x85, 0xA1, 0x01, + 0x46, 0xE1, 0x84, 0x8B, 0xE1, 0x85, 0xAE, 0x01, + 0x46, 0xE1, 0x84, 0x8C, 0xE1, 0x85, 0xA1, 0x01, + 0x46, 0xE1, 0x84, 0x8E, 0xE1, 0x85, 0xA1, 0x01, + 0x46, 0xE1, 0x84, 0x8F, 0xE1, 0x85, 0xA1, 0x01, + 0x46, 0xE1, 0x84, 0x90, 0xE1, 0x85, 0xA1, 0x01, + // Bytes 2e80 - 2ebf + 0x46, 0xE1, 0x84, 0x91, 0xE1, 0x85, 0xA1, 0x01, + 0x46, 0xE1, 0x84, 0x92, 0xE1, 0x85, 0xA1, 0x01, + 0x49, 0xE3, 0x83, 0xA1, 0xE3, 0x82, 0xAB, 0xE3, + 0x82, 0x99, 0x0D, 0x4C, 0xE1, 0x84, 0x8C, 0xE1, + 0x85, 0xAE, 0xE1, 0x84, 0x8B, 0xE1, 0x85, 0xB4, + 0x01, 0x4C, 0xE3, 0x82, 0xAD, 0xE3, 0x82, 0x99, + 0xE3, 0x82, 0xAB, 0xE3, 0x82, 0x99, 0x0D, 0x4C, + 0xE3, 0x82, 0xB3, 0xE3, 0x83, 0xBC, 0xE3, 0x83, + // Bytes 2ec0 - 2eff + 0x9B, 0xE3, 0x82, 0x9A, 0x0D, 0x4C, 0xE3, 0x83, + 0xA4, 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0x88, 0xE3, + 0x82, 0x99, 0x0D, 0x4F, 0xE1, 0x84, 0x8E, 0xE1, + 0x85, 0xA1, 0xE1, 0x86, 0xB7, 0xE1, 0x84, 0x80, + 0xE1, 0x85, 0xA9, 0x01, 0x4F, 0xE3, 0x82, 0xA4, + 0xE3, 0x83, 0x8B, 0xE3, 0x83, 0xB3, 0xE3, 0x82, + 0xAF, 0xE3, 0x82, 0x99, 0x0D, 0x4F, 0xE3, 0x82, + 0xB7, 0xE3, 0x83, 0xAA, 0xE3, 0x83, 0xB3, 0xE3, + // Bytes 2f00 - 2f3f + 0x82, 0xAF, 0xE3, 0x82, 0x99, 0x0D, 0x4F, 0xE3, + 0x83, 0x98, 0xE3, 0x82, 0x9A, 0xE3, 0x83, 0xBC, + 0xE3, 0x82, 0xB7, 0xE3, 0x82, 0x99, 0x0D, 0x4F, + 0xE3, 0x83, 0x9B, 0xE3, 0x82, 0x9A, 0xE3, 0x83, + 0xB3, 0xE3, 0x83, 0x88, 0xE3, 0x82, 0x99, 0x0D, + 0x52, 0xE3, 0x82, 0xA8, 0xE3, 0x82, 0xB9, 0xE3, + 0x82, 0xAF, 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0x88, + 0xE3, 0x82, 0x99, 0x0D, 0x52, 0xE3, 0x83, 0x95, + // Bytes 2f40 - 2f7f + 0xE3, 0x82, 0xA1, 0xE3, 0x83, 0xA9, 0xE3, 0x83, + 0x83, 0xE3, 0x83, 0x88, 0xE3, 0x82, 0x99, 0x0D, + 0x86, 0xE0, 0xB3, 0x86, 0xE0, 0xB3, 0x82, 0x01, + 0x86, 0xE0, 0xB7, 0x99, 0xE0, 0xB7, 0x8F, 0x01, + 0x03, 0x3C, 0xCC, 0xB8, 0x05, 0x03, 0x3D, 0xCC, + 0xB8, 0x05, 0x03, 0x3E, 0xCC, 0xB8, 0x05, 0x03, + 0x41, 0xCC, 0x80, 0xC9, 0x03, 0x41, 0xCC, 0x81, + 0xC9, 0x03, 0x41, 0xCC, 0x83, 0xC9, 0x03, 0x41, + // Bytes 2f80 - 2fbf + 0xCC, 0x84, 0xC9, 0x03, 0x41, 0xCC, 0x89, 0xC9, + 0x03, 0x41, 0xCC, 0x8C, 0xC9, 0x03, 0x41, 0xCC, + 0x8F, 0xC9, 0x03, 0x41, 0xCC, 0x91, 0xC9, 0x03, + 0x41, 0xCC, 0xA5, 0xB5, 0x03, 0x41, 0xCC, 0xA8, + 0xA5, 0x03, 0x42, 0xCC, 0x87, 0xC9, 0x03, 0x42, + 0xCC, 0xA3, 0xB5, 0x03, 0x42, 0xCC, 0xB1, 0xB5, + 0x03, 0x43, 0xCC, 0x81, 0xC9, 0x03, 0x43, 0xCC, + 0x82, 0xC9, 0x03, 0x43, 0xCC, 0x87, 0xC9, 0x03, + // Bytes 2fc0 - 2fff + 0x43, 0xCC, 0x8C, 0xC9, 0x03, 0x44, 0xCC, 0x87, + 0xC9, 0x03, 0x44, 0xCC, 0x8C, 0xC9, 0x03, 0x44, + 0xCC, 0xA3, 0xB5, 0x03, 0x44, 0xCC, 0xA7, 0xA5, + 0x03, 0x44, 0xCC, 0xAD, 0xB5, 0x03, 0x44, 0xCC, + 0xB1, 0xB5, 0x03, 0x45, 0xCC, 0x80, 0xC9, 0x03, + 0x45, 0xCC, 0x81, 0xC9, 0x03, 0x45, 0xCC, 0x83, + 0xC9, 0x03, 0x45, 0xCC, 0x86, 0xC9, 0x03, 0x45, + 0xCC, 0x87, 0xC9, 0x03, 0x45, 0xCC, 0x88, 0xC9, + // Bytes 3000 - 303f + 0x03, 0x45, 0xCC, 0x89, 0xC9, 0x03, 0x45, 0xCC, + 0x8C, 0xC9, 0x03, 0x45, 0xCC, 0x8F, 0xC9, 0x03, + 0x45, 0xCC, 0x91, 0xC9, 0x03, 0x45, 0xCC, 0xA8, + 0xA5, 0x03, 0x45, 0xCC, 0xAD, 0xB5, 0x03, 0x45, + 0xCC, 0xB0, 0xB5, 0x03, 0x46, 0xCC, 0x87, 0xC9, + 0x03, 0x47, 0xCC, 0x81, 0xC9, 0x03, 0x47, 0xCC, + 0x82, 0xC9, 0x03, 0x47, 0xCC, 0x84, 0xC9, 0x03, + 0x47, 0xCC, 0x86, 0xC9, 0x03, 0x47, 0xCC, 0x87, + // Bytes 3040 - 307f + 0xC9, 0x03, 0x47, 0xCC, 0x8C, 0xC9, 0x03, 0x47, + 0xCC, 0xA7, 0xA5, 0x03, 0x48, 0xCC, 0x82, 0xC9, + 0x03, 0x48, 0xCC, 0x87, 0xC9, 0x03, 0x48, 0xCC, + 0x88, 0xC9, 0x03, 0x48, 0xCC, 0x8C, 0xC9, 0x03, + 0x48, 0xCC, 0xA3, 0xB5, 0x03, 0x48, 0xCC, 0xA7, + 0xA5, 0x03, 0x48, 0xCC, 0xAE, 0xB5, 0x03, 0x49, + 0xCC, 0x80, 0xC9, 0x03, 0x49, 0xCC, 0x81, 0xC9, + 0x03, 0x49, 0xCC, 0x82, 0xC9, 0x03, 0x49, 0xCC, + // Bytes 3080 - 30bf + 0x83, 0xC9, 0x03, 0x49, 0xCC, 0x84, 0xC9, 0x03, + 0x49, 0xCC, 0x86, 0xC9, 0x03, 0x49, 0xCC, 0x87, + 0xC9, 0x03, 0x49, 0xCC, 0x89, 0xC9, 0x03, 0x49, + 0xCC, 0x8C, 0xC9, 0x03, 0x49, 0xCC, 0x8F, 0xC9, + 0x03, 0x49, 0xCC, 0x91, 0xC9, 0x03, 0x49, 0xCC, + 0xA3, 0xB5, 0x03, 0x49, 0xCC, 0xA8, 0xA5, 0x03, + 0x49, 0xCC, 0xB0, 0xB5, 0x03, 0x4A, 0xCC, 0x82, + 0xC9, 0x03, 0x4B, 0xCC, 0x81, 0xC9, 0x03, 0x4B, + // Bytes 30c0 - 30ff + 0xCC, 0x8C, 0xC9, 0x03, 0x4B, 0xCC, 0xA3, 0xB5, + 0x03, 0x4B, 0xCC, 0xA7, 0xA5, 0x03, 0x4B, 0xCC, + 0xB1, 0xB5, 0x03, 0x4C, 0xCC, 0x81, 0xC9, 0x03, + 0x4C, 0xCC, 0x8C, 0xC9, 0x03, 0x4C, 0xCC, 0xA7, + 0xA5, 0x03, 0x4C, 0xCC, 0xAD, 0xB5, 0x03, 0x4C, + 0xCC, 0xB1, 0xB5, 0x03, 0x4D, 0xCC, 0x81, 0xC9, + 0x03, 0x4D, 0xCC, 0x87, 0xC9, 0x03, 0x4D, 0xCC, + 0xA3, 0xB5, 0x03, 0x4E, 0xCC, 0x80, 0xC9, 0x03, + // Bytes 3100 - 313f + 0x4E, 0xCC, 0x81, 0xC9, 0x03, 0x4E, 0xCC, 0x83, + 0xC9, 0x03, 0x4E, 0xCC, 0x87, 0xC9, 0x03, 0x4E, + 0xCC, 0x8C, 0xC9, 0x03, 0x4E, 0xCC, 0xA3, 0xB5, + 0x03, 0x4E, 0xCC, 0xA7, 0xA5, 0x03, 0x4E, 0xCC, + 0xAD, 0xB5, 0x03, 0x4E, 0xCC, 0xB1, 0xB5, 0x03, + 0x4F, 0xCC, 0x80, 0xC9, 0x03, 0x4F, 0xCC, 0x81, + 0xC9, 0x03, 0x4F, 0xCC, 0x86, 0xC9, 0x03, 0x4F, + 0xCC, 0x89, 0xC9, 0x03, 0x4F, 0xCC, 0x8B, 0xC9, + // Bytes 3140 - 317f + 0x03, 0x4F, 0xCC, 0x8C, 0xC9, 0x03, 0x4F, 0xCC, + 0x8F, 0xC9, 0x03, 0x4F, 0xCC, 0x91, 0xC9, 0x03, + 0x50, 0xCC, 0x81, 0xC9, 0x03, 0x50, 0xCC, 0x87, + 0xC9, 0x03, 0x52, 0xCC, 0x81, 0xC9, 0x03, 0x52, + 0xCC, 0x87, 0xC9, 0x03, 0x52, 0xCC, 0x8C, 0xC9, + 0x03, 0x52, 0xCC, 0x8F, 0xC9, 0x03, 0x52, 0xCC, + 0x91, 0xC9, 0x03, 0x52, 0xCC, 0xA7, 0xA5, 0x03, + 0x52, 0xCC, 0xB1, 0xB5, 0x03, 0x53, 0xCC, 0x82, + // Bytes 3180 - 31bf + 0xC9, 0x03, 0x53, 0xCC, 0x87, 0xC9, 0x03, 0x53, + 0xCC, 0xA6, 0xB5, 0x03, 0x53, 0xCC, 0xA7, 0xA5, + 0x03, 0x54, 0xCC, 0x87, 0xC9, 0x03, 0x54, 0xCC, + 0x8C, 0xC9, 0x03, 0x54, 0xCC, 0xA3, 0xB5, 0x03, + 0x54, 0xCC, 0xA6, 0xB5, 0x03, 0x54, 0xCC, 0xA7, + 0xA5, 0x03, 0x54, 0xCC, 0xAD, 0xB5, 0x03, 0x54, + 0xCC, 0xB1, 0xB5, 0x03, 0x55, 0xCC, 0x80, 0xC9, + 0x03, 0x55, 0xCC, 0x81, 0xC9, 0x03, 0x55, 0xCC, + // Bytes 31c0 - 31ff + 0x82, 0xC9, 0x03, 0x55, 0xCC, 0x86, 0xC9, 0x03, + 0x55, 0xCC, 0x89, 0xC9, 0x03, 0x55, 0xCC, 0x8A, + 0xC9, 0x03, 0x55, 0xCC, 0x8B, 0xC9, 0x03, 0x55, + 0xCC, 0x8C, 0xC9, 0x03, 0x55, 0xCC, 0x8F, 0xC9, + 0x03, 0x55, 0xCC, 0x91, 0xC9, 0x03, 0x55, 0xCC, + 0xA3, 0xB5, 0x03, 0x55, 0xCC, 0xA4, 0xB5, 0x03, + 0x55, 0xCC, 0xA8, 0xA5, 0x03, 0x55, 0xCC, 0xAD, + 0xB5, 0x03, 0x55, 0xCC, 0xB0, 0xB5, 0x03, 0x56, + // Bytes 3200 - 323f + 0xCC, 0x83, 0xC9, 0x03, 0x56, 0xCC, 0xA3, 0xB5, + 0x03, 0x57, 0xCC, 0x80, 0xC9, 0x03, 0x57, 0xCC, + 0x81, 0xC9, 0x03, 0x57, 0xCC, 0x82, 0xC9, 0x03, + 0x57, 0xCC, 0x87, 0xC9, 0x03, 0x57, 0xCC, 0x88, + 0xC9, 0x03, 0x57, 0xCC, 0xA3, 0xB5, 0x03, 0x58, + 0xCC, 0x87, 0xC9, 0x03, 0x58, 0xCC, 0x88, 0xC9, + 0x03, 0x59, 0xCC, 0x80, 0xC9, 0x03, 0x59, 0xCC, + 0x81, 0xC9, 0x03, 0x59, 0xCC, 0x82, 0xC9, 0x03, + // Bytes 3240 - 327f + 0x59, 0xCC, 0x83, 0xC9, 0x03, 0x59, 0xCC, 0x84, + 0xC9, 0x03, 0x59, 0xCC, 0x87, 0xC9, 0x03, 0x59, + 0xCC, 0x88, 0xC9, 0x03, 0x59, 0xCC, 0x89, 0xC9, + 0x03, 0x59, 0xCC, 0xA3, 0xB5, 0x03, 0x5A, 0xCC, + 0x81, 0xC9, 0x03, 0x5A, 0xCC, 0x82, 0xC9, 0x03, + 0x5A, 0xCC, 0x87, 0xC9, 0x03, 0x5A, 0xCC, 0x8C, + 0xC9, 0x03, 0x5A, 0xCC, 0xA3, 0xB5, 0x03, 0x5A, + 0xCC, 0xB1, 0xB5, 0x03, 0x61, 0xCC, 0x80, 0xC9, + // Bytes 3280 - 32bf + 0x03, 0x61, 0xCC, 0x81, 0xC9, 0x03, 0x61, 0xCC, + 0x83, 0xC9, 0x03, 0x61, 0xCC, 0x84, 0xC9, 0x03, + 0x61, 0xCC, 0x89, 0xC9, 0x03, 0x61, 0xCC, 0x8C, + 0xC9, 0x03, 0x61, 0xCC, 0x8F, 0xC9, 0x03, 0x61, + 0xCC, 0x91, 0xC9, 0x03, 0x61, 0xCC, 0xA5, 0xB5, + 0x03, 0x61, 0xCC, 0xA8, 0xA5, 0x03, 0x62, 0xCC, + 0x87, 0xC9, 0x03, 0x62, 0xCC, 0xA3, 0xB5, 0x03, + 0x62, 0xCC, 0xB1, 0xB5, 0x03, 0x63, 0xCC, 0x81, + // Bytes 32c0 - 32ff + 0xC9, 0x03, 0x63, 0xCC, 0x82, 0xC9, 0x03, 0x63, + 0xCC, 0x87, 0xC9, 0x03, 0x63, 0xCC, 0x8C, 0xC9, + 0x03, 0x64, 0xCC, 0x87, 0xC9, 0x03, 0x64, 0xCC, + 0x8C, 0xC9, 0x03, 0x64, 0xCC, 0xA3, 0xB5, 0x03, + 0x64, 0xCC, 0xA7, 0xA5, 0x03, 0x64, 0xCC, 0xAD, + 0xB5, 0x03, 0x64, 0xCC, 0xB1, 0xB5, 0x03, 0x65, + 0xCC, 0x80, 0xC9, 0x03, 0x65, 0xCC, 0x81, 0xC9, + 0x03, 0x65, 0xCC, 0x83, 0xC9, 0x03, 0x65, 0xCC, + // Bytes 3300 - 333f + 0x86, 0xC9, 0x03, 0x65, 0xCC, 0x87, 0xC9, 0x03, + 0x65, 0xCC, 0x88, 0xC9, 0x03, 0x65, 0xCC, 0x89, + 0xC9, 0x03, 0x65, 0xCC, 0x8C, 0xC9, 0x03, 0x65, + 0xCC, 0x8F, 0xC9, 0x03, 0x65, 0xCC, 0x91, 0xC9, + 0x03, 0x65, 0xCC, 0xA8, 0xA5, 0x03, 0x65, 0xCC, + 0xAD, 0xB5, 0x03, 0x65, 0xCC, 0xB0, 0xB5, 0x03, + 0x66, 0xCC, 0x87, 0xC9, 0x03, 0x67, 0xCC, 0x81, + 0xC9, 0x03, 0x67, 0xCC, 0x82, 0xC9, 0x03, 0x67, + // Bytes 3340 - 337f + 0xCC, 0x84, 0xC9, 0x03, 0x67, 0xCC, 0x86, 0xC9, + 0x03, 0x67, 0xCC, 0x87, 0xC9, 0x03, 0x67, 0xCC, + 0x8C, 0xC9, 0x03, 0x67, 0xCC, 0xA7, 0xA5, 0x03, + 0x68, 0xCC, 0x82, 0xC9, 0x03, 0x68, 0xCC, 0x87, + 0xC9, 0x03, 0x68, 0xCC, 0x88, 0xC9, 0x03, 0x68, + 0xCC, 0x8C, 0xC9, 0x03, 0x68, 0xCC, 0xA3, 0xB5, + 0x03, 0x68, 0xCC, 0xA7, 0xA5, 0x03, 0x68, 0xCC, + 0xAE, 0xB5, 0x03, 0x68, 0xCC, 0xB1, 0xB5, 0x03, + // Bytes 3380 - 33bf + 0x69, 0xCC, 0x80, 0xC9, 0x03, 0x69, 0xCC, 0x81, + 0xC9, 0x03, 0x69, 0xCC, 0x82, 0xC9, 0x03, 0x69, + 0xCC, 0x83, 0xC9, 0x03, 0x69, 0xCC, 0x84, 0xC9, + 0x03, 0x69, 0xCC, 0x86, 0xC9, 0x03, 0x69, 0xCC, + 0x89, 0xC9, 0x03, 0x69, 0xCC, 0x8C, 0xC9, 0x03, + 0x69, 0xCC, 0x8F, 0xC9, 0x03, 0x69, 0xCC, 0x91, + 0xC9, 0x03, 0x69, 0xCC, 0xA3, 0xB5, 0x03, 0x69, + 0xCC, 0xA8, 0xA5, 0x03, 0x69, 0xCC, 0xB0, 0xB5, + // Bytes 33c0 - 33ff + 0x03, 0x6A, 0xCC, 0x82, 0xC9, 0x03, 0x6A, 0xCC, + 0x8C, 0xC9, 0x03, 0x6B, 0xCC, 0x81, 0xC9, 0x03, + 0x6B, 0xCC, 0x8C, 0xC9, 0x03, 0x6B, 0xCC, 0xA3, + 0xB5, 0x03, 0x6B, 0xCC, 0xA7, 0xA5, 0x03, 0x6B, + 0xCC, 0xB1, 0xB5, 0x03, 0x6C, 0xCC, 0x81, 0xC9, + 0x03, 0x6C, 0xCC, 0x8C, 0xC9, 0x03, 0x6C, 0xCC, + 0xA7, 0xA5, 0x03, 0x6C, 0xCC, 0xAD, 0xB5, 0x03, + 0x6C, 0xCC, 0xB1, 0xB5, 0x03, 0x6D, 0xCC, 0x81, + // Bytes 3400 - 343f + 0xC9, 0x03, 0x6D, 0xCC, 0x87, 0xC9, 0x03, 0x6D, + 0xCC, 0xA3, 0xB5, 0x03, 0x6E, 0xCC, 0x80, 0xC9, + 0x03, 0x6E, 0xCC, 0x81, 0xC9, 0x03, 0x6E, 0xCC, + 0x83, 0xC9, 0x03, 0x6E, 0xCC, 0x87, 0xC9, 0x03, + 0x6E, 0xCC, 0x8C, 0xC9, 0x03, 0x6E, 0xCC, 0xA3, + 0xB5, 0x03, 0x6E, 0xCC, 0xA7, 0xA5, 0x03, 0x6E, + 0xCC, 0xAD, 0xB5, 0x03, 0x6E, 0xCC, 0xB1, 0xB5, + 0x03, 0x6F, 0xCC, 0x80, 0xC9, 0x03, 0x6F, 0xCC, + // Bytes 3440 - 347f + 0x81, 0xC9, 0x03, 0x6F, 0xCC, 0x86, 0xC9, 0x03, + 0x6F, 0xCC, 0x89, 0xC9, 0x03, 0x6F, 0xCC, 0x8B, + 0xC9, 0x03, 0x6F, 0xCC, 0x8C, 0xC9, 0x03, 0x6F, + 0xCC, 0x8F, 0xC9, 0x03, 0x6F, 0xCC, 0x91, 0xC9, + 0x03, 0x70, 0xCC, 0x81, 0xC9, 0x03, 0x70, 0xCC, + 0x87, 0xC9, 0x03, 0x72, 0xCC, 0x81, 0xC9, 0x03, + 0x72, 0xCC, 0x87, 0xC9, 0x03, 0x72, 0xCC, 0x8C, + 0xC9, 0x03, 0x72, 0xCC, 0x8F, 0xC9, 0x03, 0x72, + // Bytes 3480 - 34bf + 0xCC, 0x91, 0xC9, 0x03, 0x72, 0xCC, 0xA7, 0xA5, + 0x03, 0x72, 0xCC, 0xB1, 0xB5, 0x03, 0x73, 0xCC, + 0x82, 0xC9, 0x03, 0x73, 0xCC, 0x87, 0xC9, 0x03, + 0x73, 0xCC, 0xA6, 0xB5, 0x03, 0x73, 0xCC, 0xA7, + 0xA5, 0x03, 0x74, 0xCC, 0x87, 0xC9, 0x03, 0x74, + 0xCC, 0x88, 0xC9, 0x03, 0x74, 0xCC, 0x8C, 0xC9, + 0x03, 0x74, 0xCC, 0xA3, 0xB5, 0x03, 0x74, 0xCC, + 0xA6, 0xB5, 0x03, 0x74, 0xCC, 0xA7, 0xA5, 0x03, + // Bytes 34c0 - 34ff + 0x74, 0xCC, 0xAD, 0xB5, 0x03, 0x74, 0xCC, 0xB1, + 0xB5, 0x03, 0x75, 0xCC, 0x80, 0xC9, 0x03, 0x75, + 0xCC, 0x81, 0xC9, 0x03, 0x75, 0xCC, 0x82, 0xC9, + 0x03, 0x75, 0xCC, 0x86, 0xC9, 0x03, 0x75, 0xCC, + 0x89, 0xC9, 0x03, 0x75, 0xCC, 0x8A, 0xC9, 0x03, + 0x75, 0xCC, 0x8B, 0xC9, 0x03, 0x75, 0xCC, 0x8C, + 0xC9, 0x03, 0x75, 0xCC, 0x8F, 0xC9, 0x03, 0x75, + 0xCC, 0x91, 0xC9, 0x03, 0x75, 0xCC, 0xA3, 0xB5, + // Bytes 3500 - 353f + 0x03, 0x75, 0xCC, 0xA4, 0xB5, 0x03, 0x75, 0xCC, + 0xA8, 0xA5, 0x03, 0x75, 0xCC, 0xAD, 0xB5, 0x03, + 0x75, 0xCC, 0xB0, 0xB5, 0x03, 0x76, 0xCC, 0x83, + 0xC9, 0x03, 0x76, 0xCC, 0xA3, 0xB5, 0x03, 0x77, + 0xCC, 0x80, 0xC9, 0x03, 0x77, 0xCC, 0x81, 0xC9, + 0x03, 0x77, 0xCC, 0x82, 0xC9, 0x03, 0x77, 0xCC, + 0x87, 0xC9, 0x03, 0x77, 0xCC, 0x88, 0xC9, 0x03, + 0x77, 0xCC, 0x8A, 0xC9, 0x03, 0x77, 0xCC, 0xA3, + // Bytes 3540 - 357f + 0xB5, 0x03, 0x78, 0xCC, 0x87, 0xC9, 0x03, 0x78, + 0xCC, 0x88, 0xC9, 0x03, 0x79, 0xCC, 0x80, 0xC9, + 0x03, 0x79, 0xCC, 0x81, 0xC9, 0x03, 0x79, 0xCC, + 0x82, 0xC9, 0x03, 0x79, 0xCC, 0x83, 0xC9, 0x03, + 0x79, 0xCC, 0x84, 0xC9, 0x03, 0x79, 0xCC, 0x87, + 0xC9, 0x03, 0x79, 0xCC, 0x88, 0xC9, 0x03, 0x79, + 0xCC, 0x89, 0xC9, 0x03, 0x79, 0xCC, 0x8A, 0xC9, + 0x03, 0x79, 0xCC, 0xA3, 0xB5, 0x03, 0x7A, 0xCC, + // Bytes 3580 - 35bf + 0x81, 0xC9, 0x03, 0x7A, 0xCC, 0x82, 0xC9, 0x03, + 0x7A, 0xCC, 0x87, 0xC9, 0x03, 0x7A, 0xCC, 0x8C, + 0xC9, 0x03, 0x7A, 0xCC, 0xA3, 0xB5, 0x03, 0x7A, + 0xCC, 0xB1, 0xB5, 0x04, 0xC2, 0xA8, 0xCC, 0x80, + 0xCA, 0x04, 0xC2, 0xA8, 0xCC, 0x81, 0xCA, 0x04, + 0xC2, 0xA8, 0xCD, 0x82, 0xCA, 0x04, 0xC3, 0x86, + 0xCC, 0x81, 0xC9, 0x04, 0xC3, 0x86, 0xCC, 0x84, + 0xC9, 0x04, 0xC3, 0x98, 0xCC, 0x81, 0xC9, 0x04, + // Bytes 35c0 - 35ff + 0xC3, 0xA6, 0xCC, 0x81, 0xC9, 0x04, 0xC3, 0xA6, + 0xCC, 0x84, 0xC9, 0x04, 0xC3, 0xB8, 0xCC, 0x81, + 0xC9, 0x04, 0xC5, 0xBF, 0xCC, 0x87, 0xC9, 0x04, + 0xC6, 0xB7, 0xCC, 0x8C, 0xC9, 0x04, 0xCA, 0x92, + 0xCC, 0x8C, 0xC9, 0x04, 0xCE, 0x91, 0xCC, 0x80, + 0xC9, 0x04, 0xCE, 0x91, 0xCC, 0x81, 0xC9, 0x04, + 0xCE, 0x91, 0xCC, 0x84, 0xC9, 0x04, 0xCE, 0x91, + 0xCC, 0x86, 0xC9, 0x04, 0xCE, 0x91, 0xCD, 0x85, + // Bytes 3600 - 363f + 0xD9, 0x04, 0xCE, 0x95, 0xCC, 0x80, 0xC9, 0x04, + 0xCE, 0x95, 0xCC, 0x81, 0xC9, 0x04, 0xCE, 0x97, + 0xCC, 0x80, 0xC9, 0x04, 0xCE, 0x97, 0xCC, 0x81, + 0xC9, 0x04, 0xCE, 0x97, 0xCD, 0x85, 0xD9, 0x04, + 0xCE, 0x99, 0xCC, 0x80, 0xC9, 0x04, 0xCE, 0x99, + 0xCC, 0x81, 0xC9, 0x04, 0xCE, 0x99, 0xCC, 0x84, + 0xC9, 0x04, 0xCE, 0x99, 0xCC, 0x86, 0xC9, 0x04, + 0xCE, 0x99, 0xCC, 0x88, 0xC9, 0x04, 0xCE, 0x9F, + // Bytes 3640 - 367f + 0xCC, 0x80, 0xC9, 0x04, 0xCE, 0x9F, 0xCC, 0x81, + 0xC9, 0x04, 0xCE, 0xA1, 0xCC, 0x94, 0xC9, 0x04, + 0xCE, 0xA5, 0xCC, 0x80, 0xC9, 0x04, 0xCE, 0xA5, + 0xCC, 0x81, 0xC9, 0x04, 0xCE, 0xA5, 0xCC, 0x84, + 0xC9, 0x04, 0xCE, 0xA5, 0xCC, 0x86, 0xC9, 0x04, + 0xCE, 0xA5, 0xCC, 0x88, 0xC9, 0x04, 0xCE, 0xA9, + 0xCC, 0x80, 0xC9, 0x04, 0xCE, 0xA9, 0xCC, 0x81, + 0xC9, 0x04, 0xCE, 0xA9, 0xCD, 0x85, 0xD9, 0x04, + // Bytes 3680 - 36bf + 0xCE, 0xB1, 0xCC, 0x84, 0xC9, 0x04, 0xCE, 0xB1, + 0xCC, 0x86, 0xC9, 0x04, 0xCE, 0xB1, 0xCD, 0x85, + 0xD9, 0x04, 0xCE, 0xB5, 0xCC, 0x80, 0xC9, 0x04, + 0xCE, 0xB5, 0xCC, 0x81, 0xC9, 0x04, 0xCE, 0xB7, + 0xCD, 0x85, 0xD9, 0x04, 0xCE, 0xB9, 0xCC, 0x80, + 0xC9, 0x04, 0xCE, 0xB9, 0xCC, 0x81, 0xC9, 0x04, + 0xCE, 0xB9, 0xCC, 0x84, 0xC9, 0x04, 0xCE, 0xB9, + 0xCC, 0x86, 0xC9, 0x04, 0xCE, 0xB9, 0xCD, 0x82, + // Bytes 36c0 - 36ff + 0xC9, 0x04, 0xCE, 0xBF, 0xCC, 0x80, 0xC9, 0x04, + 0xCE, 0xBF, 0xCC, 0x81, 0xC9, 0x04, 0xCF, 0x81, + 0xCC, 0x93, 0xC9, 0x04, 0xCF, 0x81, 0xCC, 0x94, + 0xC9, 0x04, 0xCF, 0x85, 0xCC, 0x80, 0xC9, 0x04, + 0xCF, 0x85, 0xCC, 0x81, 0xC9, 0x04, 0xCF, 0x85, + 0xCC, 0x84, 0xC9, 0x04, 0xCF, 0x85, 0xCC, 0x86, + 0xC9, 0x04, 0xCF, 0x85, 0xCD, 0x82, 0xC9, 0x04, + 0xCF, 0x89, 0xCD, 0x85, 0xD9, 0x04, 0xCF, 0x92, + // Bytes 3700 - 373f + 0xCC, 0x81, 0xC9, 0x04, 0xCF, 0x92, 0xCC, 0x88, + 0xC9, 0x04, 0xD0, 0x86, 0xCC, 0x88, 0xC9, 0x04, + 0xD0, 0x90, 0xCC, 0x86, 0xC9, 0x04, 0xD0, 0x90, + 0xCC, 0x88, 0xC9, 0x04, 0xD0, 0x93, 0xCC, 0x81, + 0xC9, 0x04, 0xD0, 0x95, 0xCC, 0x80, 0xC9, 0x04, + 0xD0, 0x95, 0xCC, 0x86, 0xC9, 0x04, 0xD0, 0x95, + 0xCC, 0x88, 0xC9, 0x04, 0xD0, 0x96, 0xCC, 0x86, + 0xC9, 0x04, 0xD0, 0x96, 0xCC, 0x88, 0xC9, 0x04, + // Bytes 3740 - 377f + 0xD0, 0x97, 0xCC, 0x88, 0xC9, 0x04, 0xD0, 0x98, + 0xCC, 0x80, 0xC9, 0x04, 0xD0, 0x98, 0xCC, 0x84, + 0xC9, 0x04, 0xD0, 0x98, 0xCC, 0x86, 0xC9, 0x04, + 0xD0, 0x98, 0xCC, 0x88, 0xC9, 0x04, 0xD0, 0x9A, + 0xCC, 0x81, 0xC9, 0x04, 0xD0, 0x9E, 0xCC, 0x88, + 0xC9, 0x04, 0xD0, 0xA3, 0xCC, 0x84, 0xC9, 0x04, + 0xD0, 0xA3, 0xCC, 0x86, 0xC9, 0x04, 0xD0, 0xA3, + 0xCC, 0x88, 0xC9, 0x04, 0xD0, 0xA3, 0xCC, 0x8B, + // Bytes 3780 - 37bf + 0xC9, 0x04, 0xD0, 0xA7, 0xCC, 0x88, 0xC9, 0x04, + 0xD0, 0xAB, 0xCC, 0x88, 0xC9, 0x04, 0xD0, 0xAD, + 0xCC, 0x88, 0xC9, 0x04, 0xD0, 0xB0, 0xCC, 0x86, + 0xC9, 0x04, 0xD0, 0xB0, 0xCC, 0x88, 0xC9, 0x04, + 0xD0, 0xB3, 0xCC, 0x81, 0xC9, 0x04, 0xD0, 0xB5, + 0xCC, 0x80, 0xC9, 0x04, 0xD0, 0xB5, 0xCC, 0x86, + 0xC9, 0x04, 0xD0, 0xB5, 0xCC, 0x88, 0xC9, 0x04, + 0xD0, 0xB6, 0xCC, 0x86, 0xC9, 0x04, 0xD0, 0xB6, + // Bytes 37c0 - 37ff + 0xCC, 0x88, 0xC9, 0x04, 0xD0, 0xB7, 0xCC, 0x88, + 0xC9, 0x04, 0xD0, 0xB8, 0xCC, 0x80, 0xC9, 0x04, + 0xD0, 0xB8, 0xCC, 0x84, 0xC9, 0x04, 0xD0, 0xB8, + 0xCC, 0x86, 0xC9, 0x04, 0xD0, 0xB8, 0xCC, 0x88, + 0xC9, 0x04, 0xD0, 0xBA, 0xCC, 0x81, 0xC9, 0x04, + 0xD0, 0xBE, 0xCC, 0x88, 0xC9, 0x04, 0xD1, 0x83, + 0xCC, 0x84, 0xC9, 0x04, 0xD1, 0x83, 0xCC, 0x86, + 0xC9, 0x04, 0xD1, 0x83, 0xCC, 0x88, 0xC9, 0x04, + // Bytes 3800 - 383f + 0xD1, 0x83, 0xCC, 0x8B, 0xC9, 0x04, 0xD1, 0x87, + 0xCC, 0x88, 0xC9, 0x04, 0xD1, 0x8B, 0xCC, 0x88, + 0xC9, 0x04, 0xD1, 0x8D, 0xCC, 0x88, 0xC9, 0x04, + 0xD1, 0x96, 0xCC, 0x88, 0xC9, 0x04, 0xD1, 0xB4, + 0xCC, 0x8F, 0xC9, 0x04, 0xD1, 0xB5, 0xCC, 0x8F, + 0xC9, 0x04, 0xD3, 0x98, 0xCC, 0x88, 0xC9, 0x04, + 0xD3, 0x99, 0xCC, 0x88, 0xC9, 0x04, 0xD3, 0xA8, + 0xCC, 0x88, 0xC9, 0x04, 0xD3, 0xA9, 0xCC, 0x88, + // Bytes 3840 - 387f + 0xC9, 0x04, 0xD8, 0xA7, 0xD9, 0x93, 0xC9, 0x04, + 0xD8, 0xA7, 0xD9, 0x94, 0xC9, 0x04, 0xD8, 0xA7, + 0xD9, 0x95, 0xB5, 0x04, 0xD9, 0x88, 0xD9, 0x94, + 0xC9, 0x04, 0xD9, 0x8A, 0xD9, 0x94, 0xC9, 0x04, + 0xDB, 0x81, 0xD9, 0x94, 0xC9, 0x04, 0xDB, 0x92, + 0xD9, 0x94, 0xC9, 0x04, 0xDB, 0x95, 0xD9, 0x94, + 0xC9, 0x05, 0x41, 0xCC, 0x82, 0xCC, 0x80, 0xCA, + 0x05, 0x41, 0xCC, 0x82, 0xCC, 0x81, 0xCA, 0x05, + // Bytes 3880 - 38bf + 0x41, 0xCC, 0x82, 0xCC, 0x83, 0xCA, 0x05, 0x41, + 0xCC, 0x82, 0xCC, 0x89, 0xCA, 0x05, 0x41, 0xCC, + 0x86, 0xCC, 0x80, 0xCA, 0x05, 0x41, 0xCC, 0x86, + 0xCC, 0x81, 0xCA, 0x05, 0x41, 0xCC, 0x86, 0xCC, + 0x83, 0xCA, 0x05, 0x41, 0xCC, 0x86, 0xCC, 0x89, + 0xCA, 0x05, 0x41, 0xCC, 0x87, 0xCC, 0x84, 0xCA, + 0x05, 0x41, 0xCC, 0x88, 0xCC, 0x84, 0xCA, 0x05, + 0x41, 0xCC, 0x8A, 0xCC, 0x81, 0xCA, 0x05, 0x41, + // Bytes 38c0 - 38ff + 0xCC, 0xA3, 0xCC, 0x82, 0xCA, 0x05, 0x41, 0xCC, + 0xA3, 0xCC, 0x86, 0xCA, 0x05, 0x43, 0xCC, 0xA7, + 0xCC, 0x81, 0xCA, 0x05, 0x45, 0xCC, 0x82, 0xCC, + 0x80, 0xCA, 0x05, 0x45, 0xCC, 0x82, 0xCC, 0x81, + 0xCA, 0x05, 0x45, 0xCC, 0x82, 0xCC, 0x83, 0xCA, + 0x05, 0x45, 0xCC, 0x82, 0xCC, 0x89, 0xCA, 0x05, + 0x45, 0xCC, 0x84, 0xCC, 0x80, 0xCA, 0x05, 0x45, + 0xCC, 0x84, 0xCC, 0x81, 0xCA, 0x05, 0x45, 0xCC, + // Bytes 3900 - 393f + 0xA3, 0xCC, 0x82, 0xCA, 0x05, 0x45, 0xCC, 0xA7, + 0xCC, 0x86, 0xCA, 0x05, 0x49, 0xCC, 0x88, 0xCC, + 0x81, 0xCA, 0x05, 0x4C, 0xCC, 0xA3, 0xCC, 0x84, + 0xCA, 0x05, 0x4F, 0xCC, 0x82, 0xCC, 0x80, 0xCA, + 0x05, 0x4F, 0xCC, 0x82, 0xCC, 0x81, 0xCA, 0x05, + 0x4F, 0xCC, 0x82, 0xCC, 0x83, 0xCA, 0x05, 0x4F, + 0xCC, 0x82, 0xCC, 0x89, 0xCA, 0x05, 0x4F, 0xCC, + 0x83, 0xCC, 0x81, 0xCA, 0x05, 0x4F, 0xCC, 0x83, + // Bytes 3940 - 397f + 0xCC, 0x84, 0xCA, 0x05, 0x4F, 0xCC, 0x83, 0xCC, + 0x88, 0xCA, 0x05, 0x4F, 0xCC, 0x84, 0xCC, 0x80, + 0xCA, 0x05, 0x4F, 0xCC, 0x84, 0xCC, 0x81, 0xCA, + 0x05, 0x4F, 0xCC, 0x87, 0xCC, 0x84, 0xCA, 0x05, + 0x4F, 0xCC, 0x88, 0xCC, 0x84, 0xCA, 0x05, 0x4F, + 0xCC, 0x9B, 0xCC, 0x80, 0xCA, 0x05, 0x4F, 0xCC, + 0x9B, 0xCC, 0x81, 0xCA, 0x05, 0x4F, 0xCC, 0x9B, + 0xCC, 0x83, 0xCA, 0x05, 0x4F, 0xCC, 0x9B, 0xCC, + // Bytes 3980 - 39bf + 0x89, 0xCA, 0x05, 0x4F, 0xCC, 0x9B, 0xCC, 0xA3, + 0xB6, 0x05, 0x4F, 0xCC, 0xA3, 0xCC, 0x82, 0xCA, + 0x05, 0x4F, 0xCC, 0xA8, 0xCC, 0x84, 0xCA, 0x05, + 0x52, 0xCC, 0xA3, 0xCC, 0x84, 0xCA, 0x05, 0x53, + 0xCC, 0x81, 0xCC, 0x87, 0xCA, 0x05, 0x53, 0xCC, + 0x8C, 0xCC, 0x87, 0xCA, 0x05, 0x53, 0xCC, 0xA3, + 0xCC, 0x87, 0xCA, 0x05, 0x55, 0xCC, 0x83, 0xCC, + 0x81, 0xCA, 0x05, 0x55, 0xCC, 0x84, 0xCC, 0x88, + // Bytes 39c0 - 39ff + 0xCA, 0x05, 0x55, 0xCC, 0x88, 0xCC, 0x80, 0xCA, + 0x05, 0x55, 0xCC, 0x88, 0xCC, 0x81, 0xCA, 0x05, + 0x55, 0xCC, 0x88, 0xCC, 0x84, 0xCA, 0x05, 0x55, + 0xCC, 0x88, 0xCC, 0x8C, 0xCA, 0x05, 0x55, 0xCC, + 0x9B, 0xCC, 0x80, 0xCA, 0x05, 0x55, 0xCC, 0x9B, + 0xCC, 0x81, 0xCA, 0x05, 0x55, 0xCC, 0x9B, 0xCC, + 0x83, 0xCA, 0x05, 0x55, 0xCC, 0x9B, 0xCC, 0x89, + 0xCA, 0x05, 0x55, 0xCC, 0x9B, 0xCC, 0xA3, 0xB6, + // Bytes 3a00 - 3a3f + 0x05, 0x61, 0xCC, 0x82, 0xCC, 0x80, 0xCA, 0x05, + 0x61, 0xCC, 0x82, 0xCC, 0x81, 0xCA, 0x05, 0x61, + 0xCC, 0x82, 0xCC, 0x83, 0xCA, 0x05, 0x61, 0xCC, + 0x82, 0xCC, 0x89, 0xCA, 0x05, 0x61, 0xCC, 0x86, + 0xCC, 0x80, 0xCA, 0x05, 0x61, 0xCC, 0x86, 0xCC, + 0x81, 0xCA, 0x05, 0x61, 0xCC, 0x86, 0xCC, 0x83, + 0xCA, 0x05, 0x61, 0xCC, 0x86, 0xCC, 0x89, 0xCA, + 0x05, 0x61, 0xCC, 0x87, 0xCC, 0x84, 0xCA, 0x05, + // Bytes 3a40 - 3a7f + 0x61, 0xCC, 0x88, 0xCC, 0x84, 0xCA, 0x05, 0x61, + 0xCC, 0x8A, 0xCC, 0x81, 0xCA, 0x05, 0x61, 0xCC, + 0xA3, 0xCC, 0x82, 0xCA, 0x05, 0x61, 0xCC, 0xA3, + 0xCC, 0x86, 0xCA, 0x05, 0x63, 0xCC, 0xA7, 0xCC, + 0x81, 0xCA, 0x05, 0x65, 0xCC, 0x82, 0xCC, 0x80, + 0xCA, 0x05, 0x65, 0xCC, 0x82, 0xCC, 0x81, 0xCA, + 0x05, 0x65, 0xCC, 0x82, 0xCC, 0x83, 0xCA, 0x05, + 0x65, 0xCC, 0x82, 0xCC, 0x89, 0xCA, 0x05, 0x65, + // Bytes 3a80 - 3abf + 0xCC, 0x84, 0xCC, 0x80, 0xCA, 0x05, 0x65, 0xCC, + 0x84, 0xCC, 0x81, 0xCA, 0x05, 0x65, 0xCC, 0xA3, + 0xCC, 0x82, 0xCA, 0x05, 0x65, 0xCC, 0xA7, 0xCC, + 0x86, 0xCA, 0x05, 0x69, 0xCC, 0x88, 0xCC, 0x81, + 0xCA, 0x05, 0x6C, 0xCC, 0xA3, 0xCC, 0x84, 0xCA, + 0x05, 0x6F, 0xCC, 0x82, 0xCC, 0x80, 0xCA, 0x05, + 0x6F, 0xCC, 0x82, 0xCC, 0x81, 0xCA, 0x05, 0x6F, + 0xCC, 0x82, 0xCC, 0x83, 0xCA, 0x05, 0x6F, 0xCC, + // Bytes 3ac0 - 3aff + 0x82, 0xCC, 0x89, 0xCA, 0x05, 0x6F, 0xCC, 0x83, + 0xCC, 0x81, 0xCA, 0x05, 0x6F, 0xCC, 0x83, 0xCC, + 0x84, 0xCA, 0x05, 0x6F, 0xCC, 0x83, 0xCC, 0x88, + 0xCA, 0x05, 0x6F, 0xCC, 0x84, 0xCC, 0x80, 0xCA, + 0x05, 0x6F, 0xCC, 0x84, 0xCC, 0x81, 0xCA, 0x05, + 0x6F, 0xCC, 0x87, 0xCC, 0x84, 0xCA, 0x05, 0x6F, + 0xCC, 0x88, 0xCC, 0x84, 0xCA, 0x05, 0x6F, 0xCC, + 0x9B, 0xCC, 0x80, 0xCA, 0x05, 0x6F, 0xCC, 0x9B, + // Bytes 3b00 - 3b3f + 0xCC, 0x81, 0xCA, 0x05, 0x6F, 0xCC, 0x9B, 0xCC, + 0x83, 0xCA, 0x05, 0x6F, 0xCC, 0x9B, 0xCC, 0x89, + 0xCA, 0x05, 0x6F, 0xCC, 0x9B, 0xCC, 0xA3, 0xB6, + 0x05, 0x6F, 0xCC, 0xA3, 0xCC, 0x82, 0xCA, 0x05, + 0x6F, 0xCC, 0xA8, 0xCC, 0x84, 0xCA, 0x05, 0x72, + 0xCC, 0xA3, 0xCC, 0x84, 0xCA, 0x05, 0x73, 0xCC, + 0x81, 0xCC, 0x87, 0xCA, 0x05, 0x73, 0xCC, 0x8C, + 0xCC, 0x87, 0xCA, 0x05, 0x73, 0xCC, 0xA3, 0xCC, + // Bytes 3b40 - 3b7f + 0x87, 0xCA, 0x05, 0x75, 0xCC, 0x83, 0xCC, 0x81, + 0xCA, 0x05, 0x75, 0xCC, 0x84, 0xCC, 0x88, 0xCA, + 0x05, 0x75, 0xCC, 0x88, 0xCC, 0x80, 0xCA, 0x05, + 0x75, 0xCC, 0x88, 0xCC, 0x81, 0xCA, 0x05, 0x75, + 0xCC, 0x88, 0xCC, 0x84, 0xCA, 0x05, 0x75, 0xCC, + 0x88, 0xCC, 0x8C, 0xCA, 0x05, 0x75, 0xCC, 0x9B, + 0xCC, 0x80, 0xCA, 0x05, 0x75, 0xCC, 0x9B, 0xCC, + 0x81, 0xCA, 0x05, 0x75, 0xCC, 0x9B, 0xCC, 0x83, + // Bytes 3b80 - 3bbf + 0xCA, 0x05, 0x75, 0xCC, 0x9B, 0xCC, 0x89, 0xCA, + 0x05, 0x75, 0xCC, 0x9B, 0xCC, 0xA3, 0xB6, 0x05, + 0xE1, 0xBE, 0xBF, 0xCC, 0x80, 0xCA, 0x05, 0xE1, + 0xBE, 0xBF, 0xCC, 0x81, 0xCA, 0x05, 0xE1, 0xBE, + 0xBF, 0xCD, 0x82, 0xCA, 0x05, 0xE1, 0xBF, 0xBE, + 0xCC, 0x80, 0xCA, 0x05, 0xE1, 0xBF, 0xBE, 0xCC, + 0x81, 0xCA, 0x05, 0xE1, 0xBF, 0xBE, 0xCD, 0x82, + 0xCA, 0x05, 0xE2, 0x86, 0x90, 0xCC, 0xB8, 0x05, + // Bytes 3bc0 - 3bff + 0x05, 0xE2, 0x86, 0x92, 0xCC, 0xB8, 0x05, 0x05, + 0xE2, 0x86, 0x94, 0xCC, 0xB8, 0x05, 0x05, 0xE2, + 0x87, 0x90, 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x87, + 0x92, 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x87, 0x94, + 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x88, 0x83, 0xCC, + 0xB8, 0x05, 0x05, 0xE2, 0x88, 0x88, 0xCC, 0xB8, + 0x05, 0x05, 0xE2, 0x88, 0x8B, 0xCC, 0xB8, 0x05, + 0x05, 0xE2, 0x88, 0xA3, 0xCC, 0xB8, 0x05, 0x05, + // Bytes 3c00 - 3c3f + 0xE2, 0x88, 0xA5, 0xCC, 0xB8, 0x05, 0x05, 0xE2, + 0x88, 0xBC, 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x89, + 0x83, 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x89, 0x85, + 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x89, 0x88, 0xCC, + 0xB8, 0x05, 0x05, 0xE2, 0x89, 0x8D, 0xCC, 0xB8, + 0x05, 0x05, 0xE2, 0x89, 0xA1, 0xCC, 0xB8, 0x05, + 0x05, 0xE2, 0x89, 0xA4, 0xCC, 0xB8, 0x05, 0x05, + 0xE2, 0x89, 0xA5, 0xCC, 0xB8, 0x05, 0x05, 0xE2, + // Bytes 3c40 - 3c7f + 0x89, 0xB2, 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x89, + 0xB3, 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x89, 0xB6, + 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x89, 0xB7, 0xCC, + 0xB8, 0x05, 0x05, 0xE2, 0x89, 0xBA, 0xCC, 0xB8, + 0x05, 0x05, 0xE2, 0x89, 0xBB, 0xCC, 0xB8, 0x05, + 0x05, 0xE2, 0x89, 0xBC, 0xCC, 0xB8, 0x05, 0x05, + 0xE2, 0x89, 0xBD, 0xCC, 0xB8, 0x05, 0x05, 0xE2, + 0x8A, 0x82, 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x8A, + // Bytes 3c80 - 3cbf + 0x83, 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x8A, 0x86, + 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x8A, 0x87, 0xCC, + 0xB8, 0x05, 0x05, 0xE2, 0x8A, 0x91, 0xCC, 0xB8, + 0x05, 0x05, 0xE2, 0x8A, 0x92, 0xCC, 0xB8, 0x05, + 0x05, 0xE2, 0x8A, 0xA2, 0xCC, 0xB8, 0x05, 0x05, + 0xE2, 0x8A, 0xA8, 0xCC, 0xB8, 0x05, 0x05, 0xE2, + 0x8A, 0xA9, 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x8A, + 0xAB, 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x8A, 0xB2, + // Bytes 3cc0 - 3cff + 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x8A, 0xB3, 0xCC, + 0xB8, 0x05, 0x05, 0xE2, 0x8A, 0xB4, 0xCC, 0xB8, + 0x05, 0x05, 0xE2, 0x8A, 0xB5, 0xCC, 0xB8, 0x05, + 0x06, 0xCE, 0x91, 0xCC, 0x93, 0xCD, 0x85, 0xDA, + 0x06, 0xCE, 0x91, 0xCC, 0x94, 0xCD, 0x85, 0xDA, + 0x06, 0xCE, 0x95, 0xCC, 0x93, 0xCC, 0x80, 0xCA, + 0x06, 0xCE, 0x95, 0xCC, 0x93, 0xCC, 0x81, 0xCA, + 0x06, 0xCE, 0x95, 0xCC, 0x94, 0xCC, 0x80, 0xCA, + // Bytes 3d00 - 3d3f + 0x06, 0xCE, 0x95, 0xCC, 0x94, 0xCC, 0x81, 0xCA, + 0x06, 0xCE, 0x97, 0xCC, 0x93, 0xCD, 0x85, 0xDA, + 0x06, 0xCE, 0x97, 0xCC, 0x94, 0xCD, 0x85, 0xDA, + 0x06, 0xCE, 0x99, 0xCC, 0x93, 0xCC, 0x80, 0xCA, + 0x06, 0xCE, 0x99, 0xCC, 0x93, 0xCC, 0x81, 0xCA, + 0x06, 0xCE, 0x99, 0xCC, 0x93, 0xCD, 0x82, 0xCA, + 0x06, 0xCE, 0x99, 0xCC, 0x94, 0xCC, 0x80, 0xCA, + 0x06, 0xCE, 0x99, 0xCC, 0x94, 0xCC, 0x81, 0xCA, + // Bytes 3d40 - 3d7f + 0x06, 0xCE, 0x99, 0xCC, 0x94, 0xCD, 0x82, 0xCA, + 0x06, 0xCE, 0x9F, 0xCC, 0x93, 0xCC, 0x80, 0xCA, + 0x06, 0xCE, 0x9F, 0xCC, 0x93, 0xCC, 0x81, 0xCA, + 0x06, 0xCE, 0x9F, 0xCC, 0x94, 0xCC, 0x80, 0xCA, + 0x06, 0xCE, 0x9F, 0xCC, 0x94, 0xCC, 0x81, 0xCA, + 0x06, 0xCE, 0xA5, 0xCC, 0x94, 0xCC, 0x80, 0xCA, + 0x06, 0xCE, 0xA5, 0xCC, 0x94, 0xCC, 0x81, 0xCA, + 0x06, 0xCE, 0xA5, 0xCC, 0x94, 0xCD, 0x82, 0xCA, + // Bytes 3d80 - 3dbf + 0x06, 0xCE, 0xA9, 0xCC, 0x93, 0xCD, 0x85, 0xDA, + 0x06, 0xCE, 0xA9, 0xCC, 0x94, 0xCD, 0x85, 0xDA, + 0x06, 0xCE, 0xB1, 0xCC, 0x80, 0xCD, 0x85, 0xDA, + 0x06, 0xCE, 0xB1, 0xCC, 0x81, 0xCD, 0x85, 0xDA, + 0x06, 0xCE, 0xB1, 0xCC, 0x93, 0xCD, 0x85, 0xDA, + 0x06, 0xCE, 0xB1, 0xCC, 0x94, 0xCD, 0x85, 0xDA, + 0x06, 0xCE, 0xB1, 0xCD, 0x82, 0xCD, 0x85, 0xDA, + 0x06, 0xCE, 0xB5, 0xCC, 0x93, 0xCC, 0x80, 0xCA, + // Bytes 3dc0 - 3dff + 0x06, 0xCE, 0xB5, 0xCC, 0x93, 0xCC, 0x81, 0xCA, + 0x06, 0xCE, 0xB5, 0xCC, 0x94, 0xCC, 0x80, 0xCA, + 0x06, 0xCE, 0xB5, 0xCC, 0x94, 0xCC, 0x81, 0xCA, + 0x06, 0xCE, 0xB7, 0xCC, 0x80, 0xCD, 0x85, 0xDA, + 0x06, 0xCE, 0xB7, 0xCC, 0x81, 0xCD, 0x85, 0xDA, + 0x06, 0xCE, 0xB7, 0xCC, 0x93, 0xCD, 0x85, 0xDA, + 0x06, 0xCE, 0xB7, 0xCC, 0x94, 0xCD, 0x85, 0xDA, + 0x06, 0xCE, 0xB7, 0xCD, 0x82, 0xCD, 0x85, 0xDA, + // Bytes 3e00 - 3e3f + 0x06, 0xCE, 0xB9, 0xCC, 0x88, 0xCC, 0x80, 0xCA, + 0x06, 0xCE, 0xB9, 0xCC, 0x88, 0xCC, 0x81, 0xCA, + 0x06, 0xCE, 0xB9, 0xCC, 0x88, 0xCD, 0x82, 0xCA, + 0x06, 0xCE, 0xB9, 0xCC, 0x93, 0xCC, 0x80, 0xCA, + 0x06, 0xCE, 0xB9, 0xCC, 0x93, 0xCC, 0x81, 0xCA, + 0x06, 0xCE, 0xB9, 0xCC, 0x93, 0xCD, 0x82, 0xCA, + 0x06, 0xCE, 0xB9, 0xCC, 0x94, 0xCC, 0x80, 0xCA, + 0x06, 0xCE, 0xB9, 0xCC, 0x94, 0xCC, 0x81, 0xCA, + // Bytes 3e40 - 3e7f + 0x06, 0xCE, 0xB9, 0xCC, 0x94, 0xCD, 0x82, 0xCA, + 0x06, 0xCE, 0xBF, 0xCC, 0x93, 0xCC, 0x80, 0xCA, + 0x06, 0xCE, 0xBF, 0xCC, 0x93, 0xCC, 0x81, 0xCA, + 0x06, 0xCE, 0xBF, 0xCC, 0x94, 0xCC, 0x80, 0xCA, + 0x06, 0xCE, 0xBF, 0xCC, 0x94, 0xCC, 0x81, 0xCA, + 0x06, 0xCF, 0x85, 0xCC, 0x88, 0xCC, 0x80, 0xCA, + 0x06, 0xCF, 0x85, 0xCC, 0x88, 0xCC, 0x81, 0xCA, + 0x06, 0xCF, 0x85, 0xCC, 0x88, 0xCD, 0x82, 0xCA, + // Bytes 3e80 - 3ebf + 0x06, 0xCF, 0x85, 0xCC, 0x93, 0xCC, 0x80, 0xCA, + 0x06, 0xCF, 0x85, 0xCC, 0x93, 0xCC, 0x81, 0xCA, + 0x06, 0xCF, 0x85, 0xCC, 0x93, 0xCD, 0x82, 0xCA, + 0x06, 0xCF, 0x85, 0xCC, 0x94, 0xCC, 0x80, 0xCA, + 0x06, 0xCF, 0x85, 0xCC, 0x94, 0xCC, 0x81, 0xCA, + 0x06, 0xCF, 0x85, 0xCC, 0x94, 0xCD, 0x82, 0xCA, + 0x06, 0xCF, 0x89, 0xCC, 0x80, 0xCD, 0x85, 0xDA, + 0x06, 0xCF, 0x89, 0xCC, 0x81, 0xCD, 0x85, 0xDA, + // Bytes 3ec0 - 3eff + 0x06, 0xCF, 0x89, 0xCC, 0x93, 0xCD, 0x85, 0xDA, + 0x06, 0xCF, 0x89, 0xCC, 0x94, 0xCD, 0x85, 0xDA, + 0x06, 0xCF, 0x89, 0xCD, 0x82, 0xCD, 0x85, 0xDA, + 0x06, 0xE0, 0xA4, 0xA8, 0xE0, 0xA4, 0xBC, 0x09, + 0x06, 0xE0, 0xA4, 0xB0, 0xE0, 0xA4, 0xBC, 0x09, + 0x06, 0xE0, 0xA4, 0xB3, 0xE0, 0xA4, 0xBC, 0x09, + 0x06, 0xE0, 0xB1, 0x86, 0xE0, 0xB1, 0x96, 0x85, + 0x06, 0xE0, 0xB7, 0x99, 0xE0, 0xB7, 0x8A, 0x11, + // Bytes 3f00 - 3f3f + 0x06, 0xE3, 0x81, 0x86, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x81, 0x8B, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x81, 0x8D, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x81, 0x8F, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x81, 0x91, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x81, 0x93, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x81, 0x95, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x81, 0x97, 0xE3, 0x82, 0x99, 0x0D, + // Bytes 3f40 - 3f7f + 0x06, 0xE3, 0x81, 0x99, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x81, 0x9B, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x81, 0x9D, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x81, 0x9F, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x81, 0xA1, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x81, 0xA4, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x81, 0xA6, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x81, 0xA8, 0xE3, 0x82, 0x99, 0x0D, + // Bytes 3f80 - 3fbf + 0x06, 0xE3, 0x81, 0xAF, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x81, 0xAF, 0xE3, 0x82, 0x9A, 0x0D, + 0x06, 0xE3, 0x81, 0xB2, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x81, 0xB2, 0xE3, 0x82, 0x9A, 0x0D, + 0x06, 0xE3, 0x81, 0xB5, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x81, 0xB5, 0xE3, 0x82, 0x9A, 0x0D, + 0x06, 0xE3, 0x81, 0xB8, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x81, 0xB8, 0xE3, 0x82, 0x9A, 0x0D, + // Bytes 3fc0 - 3fff + 0x06, 0xE3, 0x81, 0xBB, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x81, 0xBB, 0xE3, 0x82, 0x9A, 0x0D, + 0x06, 0xE3, 0x82, 0x9D, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x82, 0xA6, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x82, 0xAB, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x82, 0xAD, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x82, 0xAF, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x82, 0xB1, 0xE3, 0x82, 0x99, 0x0D, + // Bytes 4000 - 403f + 0x06, 0xE3, 0x82, 0xB3, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x82, 0xB5, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x82, 0xB7, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x82, 0xB9, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x82, 0xBB, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x82, 0xBD, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x82, 0xBF, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x83, 0x81, 0xE3, 0x82, 0x99, 0x0D, + // Bytes 4040 - 407f + 0x06, 0xE3, 0x83, 0x84, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x83, 0x86, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x83, 0x88, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x83, 0x8F, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x83, 0x8F, 0xE3, 0x82, 0x9A, 0x0D, + 0x06, 0xE3, 0x83, 0x92, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x83, 0x92, 0xE3, 0x82, 0x9A, 0x0D, + 0x06, 0xE3, 0x83, 0x95, 0xE3, 0x82, 0x99, 0x0D, + // Bytes 4080 - 40bf + 0x06, 0xE3, 0x83, 0x95, 0xE3, 0x82, 0x9A, 0x0D, + 0x06, 0xE3, 0x83, 0x98, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x83, 0x98, 0xE3, 0x82, 0x9A, 0x0D, + 0x06, 0xE3, 0x83, 0x9B, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x83, 0x9B, 0xE3, 0x82, 0x9A, 0x0D, + 0x06, 0xE3, 0x83, 0xAF, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x83, 0xB0, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x83, 0xB1, 0xE3, 0x82, 0x99, 0x0D, + // Bytes 40c0 - 40ff + 0x06, 0xE3, 0x83, 0xB2, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x83, 0xBD, 0xE3, 0x82, 0x99, 0x0D, + 0x08, 0xCE, 0x91, 0xCC, 0x93, 0xCC, 0x80, 0xCD, + 0x85, 0xDB, 0x08, 0xCE, 0x91, 0xCC, 0x93, 0xCC, + 0x81, 0xCD, 0x85, 0xDB, 0x08, 0xCE, 0x91, 0xCC, + 0x93, 0xCD, 0x82, 0xCD, 0x85, 0xDB, 0x08, 0xCE, + 0x91, 0xCC, 0x94, 0xCC, 0x80, 0xCD, 0x85, 0xDB, + 0x08, 0xCE, 0x91, 0xCC, 0x94, 0xCC, 0x81, 0xCD, + // Bytes 4100 - 413f + 0x85, 0xDB, 0x08, 0xCE, 0x91, 0xCC, 0x94, 0xCD, + 0x82, 0xCD, 0x85, 0xDB, 0x08, 0xCE, 0x97, 0xCC, + 0x93, 0xCC, 0x80, 0xCD, 0x85, 0xDB, 0x08, 0xCE, + 0x97, 0xCC, 0x93, 0xCC, 0x81, 0xCD, 0x85, 0xDB, + 0x08, 0xCE, 0x97, 0xCC, 0x93, 0xCD, 0x82, 0xCD, + 0x85, 0xDB, 0x08, 0xCE, 0x97, 0xCC, 0x94, 0xCC, + 0x80, 0xCD, 0x85, 0xDB, 0x08, 0xCE, 0x97, 0xCC, + 0x94, 0xCC, 0x81, 0xCD, 0x85, 0xDB, 0x08, 0xCE, + // Bytes 4140 - 417f + 0x97, 0xCC, 0x94, 0xCD, 0x82, 0xCD, 0x85, 0xDB, + 0x08, 0xCE, 0xA9, 0xCC, 0x93, 0xCC, 0x80, 0xCD, + 0x85, 0xDB, 0x08, 0xCE, 0xA9, 0xCC, 0x93, 0xCC, + 0x81, 0xCD, 0x85, 0xDB, 0x08, 0xCE, 0xA9, 0xCC, + 0x93, 0xCD, 0x82, 0xCD, 0x85, 0xDB, 0x08, 0xCE, + 0xA9, 0xCC, 0x94, 0xCC, 0x80, 0xCD, 0x85, 0xDB, + 0x08, 0xCE, 0xA9, 0xCC, 0x94, 0xCC, 0x81, 0xCD, + 0x85, 0xDB, 0x08, 0xCE, 0xA9, 0xCC, 0x94, 0xCD, + // Bytes 4180 - 41bf + 0x82, 0xCD, 0x85, 0xDB, 0x08, 0xCE, 0xB1, 0xCC, + 0x93, 0xCC, 0x80, 0xCD, 0x85, 0xDB, 0x08, 0xCE, + 0xB1, 0xCC, 0x93, 0xCC, 0x81, 0xCD, 0x85, 0xDB, + 0x08, 0xCE, 0xB1, 0xCC, 0x93, 0xCD, 0x82, 0xCD, + 0x85, 0xDB, 0x08, 0xCE, 0xB1, 0xCC, 0x94, 0xCC, + 0x80, 0xCD, 0x85, 0xDB, 0x08, 0xCE, 0xB1, 0xCC, + 0x94, 0xCC, 0x81, 0xCD, 0x85, 0xDB, 0x08, 0xCE, + 0xB1, 0xCC, 0x94, 0xCD, 0x82, 0xCD, 0x85, 0xDB, + // Bytes 41c0 - 41ff + 0x08, 0xCE, 0xB7, 0xCC, 0x93, 0xCC, 0x80, 0xCD, + 0x85, 0xDB, 0x08, 0xCE, 0xB7, 0xCC, 0x93, 0xCC, + 0x81, 0xCD, 0x85, 0xDB, 0x08, 0xCE, 0xB7, 0xCC, + 0x93, 0xCD, 0x82, 0xCD, 0x85, 0xDB, 0x08, 0xCE, + 0xB7, 0xCC, 0x94, 0xCC, 0x80, 0xCD, 0x85, 0xDB, + 0x08, 0xCE, 0xB7, 0xCC, 0x94, 0xCC, 0x81, 0xCD, + 0x85, 0xDB, 0x08, 0xCE, 0xB7, 0xCC, 0x94, 0xCD, + 0x82, 0xCD, 0x85, 0xDB, 0x08, 0xCF, 0x89, 0xCC, + // Bytes 4200 - 423f + 0x93, 0xCC, 0x80, 0xCD, 0x85, 0xDB, 0x08, 0xCF, + 0x89, 0xCC, 0x93, 0xCC, 0x81, 0xCD, 0x85, 0xDB, + 0x08, 0xCF, 0x89, 0xCC, 0x93, 0xCD, 0x82, 0xCD, + 0x85, 0xDB, 0x08, 0xCF, 0x89, 0xCC, 0x94, 0xCC, + 0x80, 0xCD, 0x85, 0xDB, 0x08, 0xCF, 0x89, 0xCC, + 0x94, 0xCC, 0x81, 0xCD, 0x85, 0xDB, 0x08, 0xCF, + 0x89, 0xCC, 0x94, 0xCD, 0x82, 0xCD, 0x85, 0xDB, + 0x08, 0xF0, 0x91, 0x82, 0x99, 0xF0, 0x91, 0x82, + // Bytes 4240 - 427f + 0xBA, 0x09, 0x08, 0xF0, 0x91, 0x82, 0x9B, 0xF0, + 0x91, 0x82, 0xBA, 0x09, 0x08, 0xF0, 0x91, 0x82, + 0xA5, 0xF0, 0x91, 0x82, 0xBA, 0x09, 0x42, 0xC2, + 0xB4, 0x01, 0x43, 0x20, 0xCC, 0x81, 0xC9, 0x43, + 0x20, 0xCC, 0x83, 0xC9, 0x43, 0x20, 0xCC, 0x84, + 0xC9, 0x43, 0x20, 0xCC, 0x85, 0xC9, 0x43, 0x20, + 0xCC, 0x86, 0xC9, 0x43, 0x20, 0xCC, 0x87, 0xC9, + 0x43, 0x20, 0xCC, 0x88, 0xC9, 0x43, 0x20, 0xCC, + // Bytes 4280 - 42bf + 0x8A, 0xC9, 0x43, 0x20, 0xCC, 0x8B, 0xC9, 0x43, + 0x20, 0xCC, 0x93, 0xC9, 0x43, 0x20, 0xCC, 0x94, + 0xC9, 0x43, 0x20, 0xCC, 0xA7, 0xA5, 0x43, 0x20, + 0xCC, 0xA8, 0xA5, 0x43, 0x20, 0xCC, 0xB3, 0xB5, + 0x43, 0x20, 0xCD, 0x82, 0xC9, 0x43, 0x20, 0xCD, + 0x85, 0xD9, 0x43, 0x20, 0xD9, 0x8B, 0x59, 0x43, + 0x20, 0xD9, 0x8C, 0x5D, 0x43, 0x20, 0xD9, 0x8D, + 0x61, 0x43, 0x20, 0xD9, 0x8E, 0x65, 0x43, 0x20, + // Bytes 42c0 - 42ff + 0xD9, 0x8F, 0x69, 0x43, 0x20, 0xD9, 0x90, 0x6D, + 0x43, 0x20, 0xD9, 0x91, 0x71, 0x43, 0x20, 0xD9, + 0x92, 0x75, 0x43, 0x41, 0xCC, 0x8A, 0xC9, 0x43, + 0x73, 0xCC, 0x87, 0xC9, 0x44, 0x20, 0xE3, 0x82, + 0x99, 0x0D, 0x44, 0x20, 0xE3, 0x82, 0x9A, 0x0D, + 0x44, 0xC2, 0xA8, 0xCC, 0x81, 0xCA, 0x44, 0xCE, + 0x91, 0xCC, 0x81, 0xC9, 0x44, 0xCE, 0x95, 0xCC, + 0x81, 0xC9, 0x44, 0xCE, 0x97, 0xCC, 0x81, 0xC9, + // Bytes 4300 - 433f + 0x44, 0xCE, 0x99, 0xCC, 0x81, 0xC9, 0x44, 0xCE, + 0x9F, 0xCC, 0x81, 0xC9, 0x44, 0xCE, 0xA5, 0xCC, + 0x81, 0xC9, 0x44, 0xCE, 0xA5, 0xCC, 0x88, 0xC9, + 0x44, 0xCE, 0xA9, 0xCC, 0x81, 0xC9, 0x44, 0xCE, + 0xB1, 0xCC, 0x81, 0xC9, 0x44, 0xCE, 0xB5, 0xCC, + 0x81, 0xC9, 0x44, 0xCE, 0xB7, 0xCC, 0x81, 0xC9, + 0x44, 0xCE, 0xB9, 0xCC, 0x81, 0xC9, 0x44, 0xCE, + 0xBF, 0xCC, 0x81, 0xC9, 0x44, 0xCF, 0x85, 0xCC, + // Bytes 4340 - 437f + 0x81, 0xC9, 0x44, 0xCF, 0x89, 0xCC, 0x81, 0xC9, + 0x44, 0xD7, 0x90, 0xD6, 0xB7, 0x31, 0x44, 0xD7, + 0x90, 0xD6, 0xB8, 0x35, 0x44, 0xD7, 0x90, 0xD6, + 0xBC, 0x41, 0x44, 0xD7, 0x91, 0xD6, 0xBC, 0x41, + 0x44, 0xD7, 0x91, 0xD6, 0xBF, 0x49, 0x44, 0xD7, + 0x92, 0xD6, 0xBC, 0x41, 0x44, 0xD7, 0x93, 0xD6, + 0xBC, 0x41, 0x44, 0xD7, 0x94, 0xD6, 0xBC, 0x41, + 0x44, 0xD7, 0x95, 0xD6, 0xB9, 0x39, 0x44, 0xD7, + // Bytes 4380 - 43bf + 0x95, 0xD6, 0xBC, 0x41, 0x44, 0xD7, 0x96, 0xD6, + 0xBC, 0x41, 0x44, 0xD7, 0x98, 0xD6, 0xBC, 0x41, + 0x44, 0xD7, 0x99, 0xD6, 0xB4, 0x25, 0x44, 0xD7, + 0x99, 0xD6, 0xBC, 0x41, 0x44, 0xD7, 0x9A, 0xD6, + 0xBC, 0x41, 0x44, 0xD7, 0x9B, 0xD6, 0xBC, 0x41, + 0x44, 0xD7, 0x9B, 0xD6, 0xBF, 0x49, 0x44, 0xD7, + 0x9C, 0xD6, 0xBC, 0x41, 0x44, 0xD7, 0x9E, 0xD6, + 0xBC, 0x41, 0x44, 0xD7, 0xA0, 0xD6, 0xBC, 0x41, + // Bytes 43c0 - 43ff + 0x44, 0xD7, 0xA1, 0xD6, 0xBC, 0x41, 0x44, 0xD7, + 0xA3, 0xD6, 0xBC, 0x41, 0x44, 0xD7, 0xA4, 0xD6, + 0xBC, 0x41, 0x44, 0xD7, 0xA4, 0xD6, 0xBF, 0x49, + 0x44, 0xD7, 0xA6, 0xD6, 0xBC, 0x41, 0x44, 0xD7, + 0xA7, 0xD6, 0xBC, 0x41, 0x44, 0xD7, 0xA8, 0xD6, + 0xBC, 0x41, 0x44, 0xD7, 0xA9, 0xD6, 0xBC, 0x41, + 0x44, 0xD7, 0xA9, 0xD7, 0x81, 0x4D, 0x44, 0xD7, + 0xA9, 0xD7, 0x82, 0x51, 0x44, 0xD7, 0xAA, 0xD6, + // Bytes 4400 - 443f + 0xBC, 0x41, 0x44, 0xD7, 0xB2, 0xD6, 0xB7, 0x31, + 0x44, 0xD8, 0xA7, 0xD9, 0x8B, 0x59, 0x44, 0xD8, + 0xA7, 0xD9, 0x93, 0xC9, 0x44, 0xD8, 0xA7, 0xD9, + 0x94, 0xC9, 0x44, 0xD8, 0xA7, 0xD9, 0x95, 0xB5, + 0x44, 0xD8, 0xB0, 0xD9, 0xB0, 0x79, 0x44, 0xD8, + 0xB1, 0xD9, 0xB0, 0x79, 0x44, 0xD9, 0x80, 0xD9, + 0x8B, 0x59, 0x44, 0xD9, 0x80, 0xD9, 0x8E, 0x65, + 0x44, 0xD9, 0x80, 0xD9, 0x8F, 0x69, 0x44, 0xD9, + // Bytes 4440 - 447f + 0x80, 0xD9, 0x90, 0x6D, 0x44, 0xD9, 0x80, 0xD9, + 0x91, 0x71, 0x44, 0xD9, 0x80, 0xD9, 0x92, 0x75, + 0x44, 0xD9, 0x87, 0xD9, 0xB0, 0x79, 0x44, 0xD9, + 0x88, 0xD9, 0x94, 0xC9, 0x44, 0xD9, 0x89, 0xD9, + 0xB0, 0x79, 0x44, 0xD9, 0x8A, 0xD9, 0x94, 0xC9, + 0x44, 0xDB, 0x92, 0xD9, 0x94, 0xC9, 0x44, 0xDB, + 0x95, 0xD9, 0x94, 0xC9, 0x45, 0x20, 0xCC, 0x88, + 0xCC, 0x80, 0xCA, 0x45, 0x20, 0xCC, 0x88, 0xCC, + // Bytes 4480 - 44bf + 0x81, 0xCA, 0x45, 0x20, 0xCC, 0x88, 0xCD, 0x82, + 0xCA, 0x45, 0x20, 0xCC, 0x93, 0xCC, 0x80, 0xCA, + 0x45, 0x20, 0xCC, 0x93, 0xCC, 0x81, 0xCA, 0x45, + 0x20, 0xCC, 0x93, 0xCD, 0x82, 0xCA, 0x45, 0x20, + 0xCC, 0x94, 0xCC, 0x80, 0xCA, 0x45, 0x20, 0xCC, + 0x94, 0xCC, 0x81, 0xCA, 0x45, 0x20, 0xCC, 0x94, + 0xCD, 0x82, 0xCA, 0x45, 0x20, 0xD9, 0x8C, 0xD9, + 0x91, 0x72, 0x45, 0x20, 0xD9, 0x8D, 0xD9, 0x91, + // Bytes 44c0 - 44ff + 0x72, 0x45, 0x20, 0xD9, 0x8E, 0xD9, 0x91, 0x72, + 0x45, 0x20, 0xD9, 0x8F, 0xD9, 0x91, 0x72, 0x45, + 0x20, 0xD9, 0x90, 0xD9, 0x91, 0x72, 0x45, 0x20, + 0xD9, 0x91, 0xD9, 0xB0, 0x7A, 0x45, 0xE2, 0xAB, + 0x9D, 0xCC, 0xB8, 0x05, 0x46, 0xCE, 0xB9, 0xCC, + 0x88, 0xCC, 0x81, 0xCA, 0x46, 0xCF, 0x85, 0xCC, + 0x88, 0xCC, 0x81, 0xCA, 0x46, 0xD7, 0xA9, 0xD6, + 0xBC, 0xD7, 0x81, 0x4E, 0x46, 0xD7, 0xA9, 0xD6, + // Bytes 4500 - 453f + 0xBC, 0xD7, 0x82, 0x52, 0x46, 0xD9, 0x80, 0xD9, + 0x8E, 0xD9, 0x91, 0x72, 0x46, 0xD9, 0x80, 0xD9, + 0x8F, 0xD9, 0x91, 0x72, 0x46, 0xD9, 0x80, 0xD9, + 0x90, 0xD9, 0x91, 0x72, 0x46, 0xE0, 0xA4, 0x95, + 0xE0, 0xA4, 0xBC, 0x09, 0x46, 0xE0, 0xA4, 0x96, + 0xE0, 0xA4, 0xBC, 0x09, 0x46, 0xE0, 0xA4, 0x97, + 0xE0, 0xA4, 0xBC, 0x09, 0x46, 0xE0, 0xA4, 0x9C, + 0xE0, 0xA4, 0xBC, 0x09, 0x46, 0xE0, 0xA4, 0xA1, + // Bytes 4540 - 457f + 0xE0, 0xA4, 0xBC, 0x09, 0x46, 0xE0, 0xA4, 0xA2, + 0xE0, 0xA4, 0xBC, 0x09, 0x46, 0xE0, 0xA4, 0xAB, + 0xE0, 0xA4, 0xBC, 0x09, 0x46, 0xE0, 0xA4, 0xAF, + 0xE0, 0xA4, 0xBC, 0x09, 0x46, 0xE0, 0xA6, 0xA1, + 0xE0, 0xA6, 0xBC, 0x09, 0x46, 0xE0, 0xA6, 0xA2, + 0xE0, 0xA6, 0xBC, 0x09, 0x46, 0xE0, 0xA6, 0xAF, + 0xE0, 0xA6, 0xBC, 0x09, 0x46, 0xE0, 0xA8, 0x96, + 0xE0, 0xA8, 0xBC, 0x09, 0x46, 0xE0, 0xA8, 0x97, + // Bytes 4580 - 45bf + 0xE0, 0xA8, 0xBC, 0x09, 0x46, 0xE0, 0xA8, 0x9C, + 0xE0, 0xA8, 0xBC, 0x09, 0x46, 0xE0, 0xA8, 0xAB, + 0xE0, 0xA8, 0xBC, 0x09, 0x46, 0xE0, 0xA8, 0xB2, + 0xE0, 0xA8, 0xBC, 0x09, 0x46, 0xE0, 0xA8, 0xB8, + 0xE0, 0xA8, 0xBC, 0x09, 0x46, 0xE0, 0xAC, 0xA1, + 0xE0, 0xAC, 0xBC, 0x09, 0x46, 0xE0, 0xAC, 0xA2, + 0xE0, 0xAC, 0xBC, 0x09, 0x46, 0xE0, 0xBE, 0xB2, + 0xE0, 0xBE, 0x80, 0x9D, 0x46, 0xE0, 0xBE, 0xB3, + // Bytes 45c0 - 45ff + 0xE0, 0xBE, 0x80, 0x9D, 0x46, 0xE3, 0x83, 0x86, + 0xE3, 0x82, 0x99, 0x0D, 0x48, 0xF0, 0x9D, 0x85, + 0x97, 0xF0, 0x9D, 0x85, 0xA5, 0xAD, 0x48, 0xF0, + 0x9D, 0x85, 0x98, 0xF0, 0x9D, 0x85, 0xA5, 0xAD, + 0x48, 0xF0, 0x9D, 0x86, 0xB9, 0xF0, 0x9D, 0x85, + 0xA5, 0xAD, 0x48, 0xF0, 0x9D, 0x86, 0xBA, 0xF0, + 0x9D, 0x85, 0xA5, 0xAD, 0x49, 0xE0, 0xBE, 0xB2, + 0xE0, 0xBD, 0xB1, 0xE0, 0xBE, 0x80, 0x9E, 0x49, + // Bytes 4600 - 463f + 0xE0, 0xBE, 0xB3, 0xE0, 0xBD, 0xB1, 0xE0, 0xBE, + 0x80, 0x9E, 0x4C, 0xF0, 0x9D, 0x85, 0x98, 0xF0, + 0x9D, 0x85, 0xA5, 0xF0, 0x9D, 0x85, 0xAE, 0xAE, + 0x4C, 0xF0, 0x9D, 0x85, 0x98, 0xF0, 0x9D, 0x85, + 0xA5, 0xF0, 0x9D, 0x85, 0xAF, 0xAE, 0x4C, 0xF0, + 0x9D, 0x85, 0x98, 0xF0, 0x9D, 0x85, 0xA5, 0xF0, + 0x9D, 0x85, 0xB0, 0xAE, 0x4C, 0xF0, 0x9D, 0x85, + 0x98, 0xF0, 0x9D, 0x85, 0xA5, 0xF0, 0x9D, 0x85, + // Bytes 4640 - 467f + 0xB1, 0xAE, 0x4C, 0xF0, 0x9D, 0x85, 0x98, 0xF0, + 0x9D, 0x85, 0xA5, 0xF0, 0x9D, 0x85, 0xB2, 0xAE, + 0x4C, 0xF0, 0x9D, 0x86, 0xB9, 0xF0, 0x9D, 0x85, + 0xA5, 0xF0, 0x9D, 0x85, 0xAE, 0xAE, 0x4C, 0xF0, + 0x9D, 0x86, 0xB9, 0xF0, 0x9D, 0x85, 0xA5, 0xF0, + 0x9D, 0x85, 0xAF, 0xAE, 0x4C, 0xF0, 0x9D, 0x86, + 0xBA, 0xF0, 0x9D, 0x85, 0xA5, 0xF0, 0x9D, 0x85, + 0xAE, 0xAE, 0x4C, 0xF0, 0x9D, 0x86, 0xBA, 0xF0, + // Bytes 4680 - 46bf + 0x9D, 0x85, 0xA5, 0xF0, 0x9D, 0x85, 0xAF, 0xAE, + 0x83, 0x41, 0xCC, 0x82, 0xC9, 0x83, 0x41, 0xCC, + 0x86, 0xC9, 0x83, 0x41, 0xCC, 0x87, 0xC9, 0x83, + 0x41, 0xCC, 0x88, 0xC9, 0x83, 0x41, 0xCC, 0x8A, + 0xC9, 0x83, 0x41, 0xCC, 0xA3, 0xB5, 0x83, 0x43, + 0xCC, 0xA7, 0xA5, 0x83, 0x45, 0xCC, 0x82, 0xC9, + 0x83, 0x45, 0xCC, 0x84, 0xC9, 0x83, 0x45, 0xCC, + 0xA3, 0xB5, 0x83, 0x45, 0xCC, 0xA7, 0xA5, 0x83, + // Bytes 46c0 - 46ff + 0x49, 0xCC, 0x88, 0xC9, 0x83, 0x4C, 0xCC, 0xA3, + 0xB5, 0x83, 0x4F, 0xCC, 0x82, 0xC9, 0x83, 0x4F, + 0xCC, 0x83, 0xC9, 0x83, 0x4F, 0xCC, 0x84, 0xC9, + 0x83, 0x4F, 0xCC, 0x87, 0xC9, 0x83, 0x4F, 0xCC, + 0x88, 0xC9, 0x83, 0x4F, 0xCC, 0x9B, 0xAD, 0x83, + 0x4F, 0xCC, 0xA3, 0xB5, 0x83, 0x4F, 0xCC, 0xA8, + 0xA5, 0x83, 0x52, 0xCC, 0xA3, 0xB5, 0x83, 0x53, + 0xCC, 0x81, 0xC9, 0x83, 0x53, 0xCC, 0x8C, 0xC9, + // Bytes 4700 - 473f + 0x83, 0x53, 0xCC, 0xA3, 0xB5, 0x83, 0x55, 0xCC, + 0x83, 0xC9, 0x83, 0x55, 0xCC, 0x84, 0xC9, 0x83, + 0x55, 0xCC, 0x88, 0xC9, 0x83, 0x55, 0xCC, 0x9B, + 0xAD, 0x83, 0x61, 0xCC, 0x82, 0xC9, 0x83, 0x61, + 0xCC, 0x86, 0xC9, 0x83, 0x61, 0xCC, 0x87, 0xC9, + 0x83, 0x61, 0xCC, 0x88, 0xC9, 0x83, 0x61, 0xCC, + 0x8A, 0xC9, 0x83, 0x61, 0xCC, 0xA3, 0xB5, 0x83, + 0x63, 0xCC, 0xA7, 0xA5, 0x83, 0x65, 0xCC, 0x82, + // Bytes 4740 - 477f + 0xC9, 0x83, 0x65, 0xCC, 0x84, 0xC9, 0x83, 0x65, + 0xCC, 0xA3, 0xB5, 0x83, 0x65, 0xCC, 0xA7, 0xA5, + 0x83, 0x69, 0xCC, 0x88, 0xC9, 0x83, 0x6C, 0xCC, + 0xA3, 0xB5, 0x83, 0x6F, 0xCC, 0x82, 0xC9, 0x83, + 0x6F, 0xCC, 0x83, 0xC9, 0x83, 0x6F, 0xCC, 0x84, + 0xC9, 0x83, 0x6F, 0xCC, 0x87, 0xC9, 0x83, 0x6F, + 0xCC, 0x88, 0xC9, 0x83, 0x6F, 0xCC, 0x9B, 0xAD, + 0x83, 0x6F, 0xCC, 0xA3, 0xB5, 0x83, 0x6F, 0xCC, + // Bytes 4780 - 47bf + 0xA8, 0xA5, 0x83, 0x72, 0xCC, 0xA3, 0xB5, 0x83, + 0x73, 0xCC, 0x81, 0xC9, 0x83, 0x73, 0xCC, 0x8C, + 0xC9, 0x83, 0x73, 0xCC, 0xA3, 0xB5, 0x83, 0x75, + 0xCC, 0x83, 0xC9, 0x83, 0x75, 0xCC, 0x84, 0xC9, + 0x83, 0x75, 0xCC, 0x88, 0xC9, 0x83, 0x75, 0xCC, + 0x9B, 0xAD, 0x84, 0xCE, 0x91, 0xCC, 0x93, 0xC9, + 0x84, 0xCE, 0x91, 0xCC, 0x94, 0xC9, 0x84, 0xCE, + 0x95, 0xCC, 0x93, 0xC9, 0x84, 0xCE, 0x95, 0xCC, + // Bytes 47c0 - 47ff + 0x94, 0xC9, 0x84, 0xCE, 0x97, 0xCC, 0x93, 0xC9, + 0x84, 0xCE, 0x97, 0xCC, 0x94, 0xC9, 0x84, 0xCE, + 0x99, 0xCC, 0x93, 0xC9, 0x84, 0xCE, 0x99, 0xCC, + 0x94, 0xC9, 0x84, 0xCE, 0x9F, 0xCC, 0x93, 0xC9, + 0x84, 0xCE, 0x9F, 0xCC, 0x94, 0xC9, 0x84, 0xCE, + 0xA5, 0xCC, 0x94, 0xC9, 0x84, 0xCE, 0xA9, 0xCC, + 0x93, 0xC9, 0x84, 0xCE, 0xA9, 0xCC, 0x94, 0xC9, + 0x84, 0xCE, 0xB1, 0xCC, 0x80, 0xC9, 0x84, 0xCE, + // Bytes 4800 - 483f + 0xB1, 0xCC, 0x81, 0xC9, 0x84, 0xCE, 0xB1, 0xCC, + 0x93, 0xC9, 0x84, 0xCE, 0xB1, 0xCC, 0x94, 0xC9, + 0x84, 0xCE, 0xB1, 0xCD, 0x82, 0xC9, 0x84, 0xCE, + 0xB5, 0xCC, 0x93, 0xC9, 0x84, 0xCE, 0xB5, 0xCC, + 0x94, 0xC9, 0x84, 0xCE, 0xB7, 0xCC, 0x80, 0xC9, + 0x84, 0xCE, 0xB7, 0xCC, 0x81, 0xC9, 0x84, 0xCE, + 0xB7, 0xCC, 0x93, 0xC9, 0x84, 0xCE, 0xB7, 0xCC, + 0x94, 0xC9, 0x84, 0xCE, 0xB7, 0xCD, 0x82, 0xC9, + // Bytes 4840 - 487f + 0x84, 0xCE, 0xB9, 0xCC, 0x88, 0xC9, 0x84, 0xCE, + 0xB9, 0xCC, 0x93, 0xC9, 0x84, 0xCE, 0xB9, 0xCC, + 0x94, 0xC9, 0x84, 0xCE, 0xBF, 0xCC, 0x93, 0xC9, + 0x84, 0xCE, 0xBF, 0xCC, 0x94, 0xC9, 0x84, 0xCF, + 0x85, 0xCC, 0x88, 0xC9, 0x84, 0xCF, 0x85, 0xCC, + 0x93, 0xC9, 0x84, 0xCF, 0x85, 0xCC, 0x94, 0xC9, + 0x84, 0xCF, 0x89, 0xCC, 0x80, 0xC9, 0x84, 0xCF, + 0x89, 0xCC, 0x81, 0xC9, 0x84, 0xCF, 0x89, 0xCC, + // Bytes 4880 - 48bf + 0x93, 0xC9, 0x84, 0xCF, 0x89, 0xCC, 0x94, 0xC9, + 0x84, 0xCF, 0x89, 0xCD, 0x82, 0xC9, 0x86, 0xCE, + 0x91, 0xCC, 0x93, 0xCC, 0x80, 0xCA, 0x86, 0xCE, + 0x91, 0xCC, 0x93, 0xCC, 0x81, 0xCA, 0x86, 0xCE, + 0x91, 0xCC, 0x93, 0xCD, 0x82, 0xCA, 0x86, 0xCE, + 0x91, 0xCC, 0x94, 0xCC, 0x80, 0xCA, 0x86, 0xCE, + 0x91, 0xCC, 0x94, 0xCC, 0x81, 0xCA, 0x86, 0xCE, + 0x91, 0xCC, 0x94, 0xCD, 0x82, 0xCA, 0x86, 0xCE, + // Bytes 48c0 - 48ff + 0x97, 0xCC, 0x93, 0xCC, 0x80, 0xCA, 0x86, 0xCE, + 0x97, 0xCC, 0x93, 0xCC, 0x81, 0xCA, 0x86, 0xCE, + 0x97, 0xCC, 0x93, 0xCD, 0x82, 0xCA, 0x86, 0xCE, + 0x97, 0xCC, 0x94, 0xCC, 0x80, 0xCA, 0x86, 0xCE, + 0x97, 0xCC, 0x94, 0xCC, 0x81, 0xCA, 0x86, 0xCE, + 0x97, 0xCC, 0x94, 0xCD, 0x82, 0xCA, 0x86, 0xCE, + 0xA9, 0xCC, 0x93, 0xCC, 0x80, 0xCA, 0x86, 0xCE, + 0xA9, 0xCC, 0x93, 0xCC, 0x81, 0xCA, 0x86, 0xCE, + // Bytes 4900 - 493f + 0xA9, 0xCC, 0x93, 0xCD, 0x82, 0xCA, 0x86, 0xCE, + 0xA9, 0xCC, 0x94, 0xCC, 0x80, 0xCA, 0x86, 0xCE, + 0xA9, 0xCC, 0x94, 0xCC, 0x81, 0xCA, 0x86, 0xCE, + 0xA9, 0xCC, 0x94, 0xCD, 0x82, 0xCA, 0x86, 0xCE, + 0xB1, 0xCC, 0x93, 0xCC, 0x80, 0xCA, 0x86, 0xCE, + 0xB1, 0xCC, 0x93, 0xCC, 0x81, 0xCA, 0x86, 0xCE, + 0xB1, 0xCC, 0x93, 0xCD, 0x82, 0xCA, 0x86, 0xCE, + 0xB1, 0xCC, 0x94, 0xCC, 0x80, 0xCA, 0x86, 0xCE, + // Bytes 4940 - 497f + 0xB1, 0xCC, 0x94, 0xCC, 0x81, 0xCA, 0x86, 0xCE, + 0xB1, 0xCC, 0x94, 0xCD, 0x82, 0xCA, 0x86, 0xCE, + 0xB7, 0xCC, 0x93, 0xCC, 0x80, 0xCA, 0x86, 0xCE, + 0xB7, 0xCC, 0x93, 0xCC, 0x81, 0xCA, 0x86, 0xCE, + 0xB7, 0xCC, 0x93, 0xCD, 0x82, 0xCA, 0x86, 0xCE, + 0xB7, 0xCC, 0x94, 0xCC, 0x80, 0xCA, 0x86, 0xCE, + 0xB7, 0xCC, 0x94, 0xCC, 0x81, 0xCA, 0x86, 0xCE, + 0xB7, 0xCC, 0x94, 0xCD, 0x82, 0xCA, 0x86, 0xCF, + // Bytes 4980 - 49bf + 0x89, 0xCC, 0x93, 0xCC, 0x80, 0xCA, 0x86, 0xCF, + 0x89, 0xCC, 0x93, 0xCC, 0x81, 0xCA, 0x86, 0xCF, + 0x89, 0xCC, 0x93, 0xCD, 0x82, 0xCA, 0x86, 0xCF, + 0x89, 0xCC, 0x94, 0xCC, 0x80, 0xCA, 0x86, 0xCF, + 0x89, 0xCC, 0x94, 0xCC, 0x81, 0xCA, 0x86, 0xCF, + 0x89, 0xCC, 0x94, 0xCD, 0x82, 0xCA, 0x42, 0xCC, + 0x80, 0xC9, 0x32, 0x42, 0xCC, 0x81, 0xC9, 0x32, + 0x42, 0xCC, 0x93, 0xC9, 0x32, 0x43, 0xE1, 0x85, + // Bytes 49c0 - 49ff + 0xA1, 0x01, 0x00, 0x43, 0xE1, 0x85, 0xA2, 0x01, + 0x00, 0x43, 0xE1, 0x85, 0xA3, 0x01, 0x00, 0x43, + 0xE1, 0x85, 0xA4, 0x01, 0x00, 0x43, 0xE1, 0x85, + 0xA5, 0x01, 0x00, 0x43, 0xE1, 0x85, 0xA6, 0x01, + 0x00, 0x43, 0xE1, 0x85, 0xA7, 0x01, 0x00, 0x43, + 0xE1, 0x85, 0xA8, 0x01, 0x00, 0x43, 0xE1, 0x85, + 0xA9, 0x01, 0x00, 0x43, 0xE1, 0x85, 0xAA, 0x01, + 0x00, 0x43, 0xE1, 0x85, 0xAB, 0x01, 0x00, 0x43, + // Bytes 4a00 - 4a3f + 0xE1, 0x85, 0xAC, 0x01, 0x00, 0x43, 0xE1, 0x85, + 0xAD, 0x01, 0x00, 0x43, 0xE1, 0x85, 0xAE, 0x01, + 0x00, 0x43, 0xE1, 0x85, 0xAF, 0x01, 0x00, 0x43, + 0xE1, 0x85, 0xB0, 0x01, 0x00, 0x43, 0xE1, 0x85, + 0xB1, 0x01, 0x00, 0x43, 0xE1, 0x85, 0xB2, 0x01, + 0x00, 0x43, 0xE1, 0x85, 0xB3, 0x01, 0x00, 0x43, + 0xE1, 0x85, 0xB4, 0x01, 0x00, 0x43, 0xE1, 0x85, + 0xB5, 0x01, 0x00, 0x43, 0xE1, 0x86, 0xAA, 0x01, + // Bytes 4a40 - 4a7f + 0x00, 0x43, 0xE1, 0x86, 0xAC, 0x01, 0x00, 0x43, + 0xE1, 0x86, 0xAD, 0x01, 0x00, 0x43, 0xE1, 0x86, + 0xB0, 0x01, 0x00, 0x43, 0xE1, 0x86, 0xB1, 0x01, + 0x00, 0x43, 0xE1, 0x86, 0xB2, 0x01, 0x00, 0x43, + 0xE1, 0x86, 0xB3, 0x01, 0x00, 0x43, 0xE1, 0x86, + 0xB4, 0x01, 0x00, 0x43, 0xE1, 0x86, 0xB5, 0x01, + 0x00, 0x44, 0xCC, 0x88, 0xCC, 0x81, 0xCA, 0x32, + 0x43, 0xE3, 0x82, 0x99, 0x0D, 0x03, 0x43, 0xE3, + // Bytes 4a80 - 4abf + 0x82, 0x9A, 0x0D, 0x03, 0x46, 0xE0, 0xBD, 0xB1, + 0xE0, 0xBD, 0xB2, 0x9E, 0x26, 0x46, 0xE0, 0xBD, + 0xB1, 0xE0, 0xBD, 0xB4, 0xA2, 0x26, 0x46, 0xE0, + 0xBD, 0xB1, 0xE0, 0xBE, 0x80, 0x9E, 0x26, 0x00, + 0x01, +} + +// lookup returns the trie value for the first UTF-8 encoding in s and +// the width in bytes of this encoding. The size will be 0 if s does not +// hold enough bytes to complete the encoding. len(s) must be greater than 0. +func (t *nfcTrie) lookup(s []byte) (v uint16, sz int) { + c0 := s[0] + switch { + case c0 < 0x80: // is ASCII + return nfcValues[c0], 1 + case c0 < 0xC2: + return 0, 1 // Illegal UTF-8: not a starter, not ASCII. + case c0 < 0xE0: // 2-byte UTF-8 + if len(s) < 2 { + return 0, 0 + } + i := nfcIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c1), 2 + case c0 < 0xF0: // 3-byte UTF-8 + if len(s) < 3 { + return 0, 0 + } + i := nfcIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = nfcIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c2), 3 + case c0 < 0xF8: // 4-byte UTF-8 + if len(s) < 4 { + return 0, 0 + } + i := nfcIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = nfcIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + o = uint32(i)<<6 + uint32(c2) + i = nfcIndex[o] + c3 := s[3] + if c3 < 0x80 || 0xC0 <= c3 { + return 0, 3 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c3), 4 + } + // Illegal rune + return 0, 1 +} + +// lookupUnsafe returns the trie value for the first UTF-8 encoding in s. +// s must start with a full and valid UTF-8 encoded rune. +func (t *nfcTrie) lookupUnsafe(s []byte) uint16 { + c0 := s[0] + if c0 < 0x80 { // is ASCII + return nfcValues[c0] + } + i := nfcIndex[c0] + if c0 < 0xE0 { // 2-byte UTF-8 + return t.lookupValue(uint32(i), s[1]) + } + i = nfcIndex[uint32(i)<<6+uint32(s[1])] + if c0 < 0xF0 { // 3-byte UTF-8 + return t.lookupValue(uint32(i), s[2]) + } + i = nfcIndex[uint32(i)<<6+uint32(s[2])] + if c0 < 0xF8 { // 4-byte UTF-8 + return t.lookupValue(uint32(i), s[3]) + } + return 0 +} + +// lookupString returns the trie value for the first UTF-8 encoding in s and +// the width in bytes of this encoding. The size will be 0 if s does not +// hold enough bytes to complete the encoding. len(s) must be greater than 0. +func (t *nfcTrie) lookupString(s string) (v uint16, sz int) { + c0 := s[0] + switch { + case c0 < 0x80: // is ASCII + return nfcValues[c0], 1 + case c0 < 0xC2: + return 0, 1 // Illegal UTF-8: not a starter, not ASCII. + case c0 < 0xE0: // 2-byte UTF-8 + if len(s) < 2 { + return 0, 0 + } + i := nfcIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c1), 2 + case c0 < 0xF0: // 3-byte UTF-8 + if len(s) < 3 { + return 0, 0 + } + i := nfcIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = nfcIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c2), 3 + case c0 < 0xF8: // 4-byte UTF-8 + if len(s) < 4 { + return 0, 0 + } + i := nfcIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = nfcIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + o = uint32(i)<<6 + uint32(c2) + i = nfcIndex[o] + c3 := s[3] + if c3 < 0x80 || 0xC0 <= c3 { + return 0, 3 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c3), 4 + } + // Illegal rune + return 0, 1 +} + +// lookupStringUnsafe returns the trie value for the first UTF-8 encoding in s. +// s must start with a full and valid UTF-8 encoded rune. +func (t *nfcTrie) lookupStringUnsafe(s string) uint16 { + c0 := s[0] + if c0 < 0x80 { // is ASCII + return nfcValues[c0] + } + i := nfcIndex[c0] + if c0 < 0xE0 { // 2-byte UTF-8 + return t.lookupValue(uint32(i), s[1]) + } + i = nfcIndex[uint32(i)<<6+uint32(s[1])] + if c0 < 0xF0 { // 3-byte UTF-8 + return t.lookupValue(uint32(i), s[2]) + } + i = nfcIndex[uint32(i)<<6+uint32(s[2])] + if c0 < 0xF8 { // 4-byte UTF-8 + return t.lookupValue(uint32(i), s[3]) + } + return 0 +} + +// nfcTrie. Total size: 10442 bytes (10.20 KiB). Checksum: 4ba400a9d8208e03. +type nfcTrie struct{} + +func newNfcTrie(i int) *nfcTrie { + return &nfcTrie{} +} + +// lookupValue determines the type of block n and looks up the value for b. +func (t *nfcTrie) lookupValue(n uint32, b byte) uint16 { + switch { + case n < 45: + return uint16(nfcValues[n<<6+uint32(b)]) + default: + n -= 45 + return uint16(nfcSparse.lookup(n, b)) + } +} + +// nfcValues: 47 blocks, 3008 entries, 6016 bytes +// The third block is the zero block. +var nfcValues = [3008]uint16{ + // Block 0x0, offset 0x0 + 0x3c: 0xa000, 0x3d: 0xa000, 0x3e: 0xa000, + // Block 0x1, offset 0x40 + 0x41: 0xa000, 0x42: 0xa000, 0x43: 0xa000, 0x44: 0xa000, 0x45: 0xa000, + 0x46: 0xa000, 0x47: 0xa000, 0x48: 0xa000, 0x49: 0xa000, 0x4a: 0xa000, 0x4b: 0xa000, + 0x4c: 0xa000, 0x4d: 0xa000, 0x4e: 0xa000, 0x4f: 0xa000, 0x50: 0xa000, + 0x52: 0xa000, 0x53: 0xa000, 0x54: 0xa000, 0x55: 0xa000, 0x56: 0xa000, 0x57: 0xa000, + 0x58: 0xa000, 0x59: 0xa000, 0x5a: 0xa000, + 0x61: 0xa000, 0x62: 0xa000, 0x63: 0xa000, + 0x64: 0xa000, 0x65: 0xa000, 0x66: 0xa000, 0x67: 0xa000, 0x68: 0xa000, 0x69: 0xa000, + 0x6a: 0xa000, 0x6b: 0xa000, 0x6c: 0xa000, 0x6d: 0xa000, 0x6e: 0xa000, 0x6f: 0xa000, + 0x70: 0xa000, 0x72: 0xa000, 0x73: 0xa000, 0x74: 0xa000, 0x75: 0xa000, + 0x76: 0xa000, 0x77: 0xa000, 0x78: 0xa000, 0x79: 0xa000, 0x7a: 0xa000, + // Block 0x2, offset 0x80 + // Block 0x3, offset 0xc0 + 0xc0: 0x2f6f, 0xc1: 0x2f74, 0xc2: 0x4688, 0xc3: 0x2f79, 0xc4: 0x4697, 0xc5: 0x469c, + 0xc6: 0xa000, 0xc7: 0x46a6, 0xc8: 0x2fe2, 0xc9: 0x2fe7, 0xca: 0x46ab, 0xcb: 0x2ffb, + 0xcc: 0x306e, 0xcd: 0x3073, 0xce: 0x3078, 0xcf: 0x46bf, 0xd1: 0x3104, + 0xd2: 0x3127, 0xd3: 0x312c, 0xd4: 0x46c9, 0xd5: 0x46ce, 0xd6: 0x46dd, + 0xd8: 0xa000, 0xd9: 0x31b3, 0xda: 0x31b8, 0xdb: 0x31bd, 0xdc: 0x470f, 0xdd: 0x3235, + 0xe0: 0x327b, 0xe1: 0x3280, 0xe2: 0x4719, 0xe3: 0x3285, + 0xe4: 0x4728, 0xe5: 0x472d, 0xe6: 0xa000, 0xe7: 0x4737, 0xe8: 0x32ee, 0xe9: 0x32f3, + 0xea: 0x473c, 0xeb: 0x3307, 0xec: 0x337f, 0xed: 0x3384, 0xee: 0x3389, 0xef: 0x4750, + 0xf1: 0x3415, 0xf2: 0x3438, 0xf3: 0x343d, 0xf4: 0x475a, 0xf5: 0x475f, + 0xf6: 0x476e, 0xf8: 0xa000, 0xf9: 0x34c9, 0xfa: 0x34ce, 0xfb: 0x34d3, + 0xfc: 0x47a0, 0xfd: 0x3550, 0xff: 0x3569, + // Block 0x4, offset 0x100 + 0x100: 0x2f7e, 0x101: 0x328a, 0x102: 0x468d, 0x103: 0x471e, 0x104: 0x2f9c, 0x105: 0x32a8, + 0x106: 0x2fb0, 0x107: 0x32bc, 0x108: 0x2fb5, 0x109: 0x32c1, 0x10a: 0x2fba, 0x10b: 0x32c6, + 0x10c: 0x2fbf, 0x10d: 0x32cb, 0x10e: 0x2fc9, 0x10f: 0x32d5, + 0x112: 0x46b0, 0x113: 0x4741, 0x114: 0x2ff1, 0x115: 0x32fd, 0x116: 0x2ff6, 0x117: 0x3302, + 0x118: 0x3014, 0x119: 0x3320, 0x11a: 0x3005, 0x11b: 0x3311, 0x11c: 0x302d, 0x11d: 0x3339, + 0x11e: 0x3037, 0x11f: 0x3343, 0x120: 0x303c, 0x121: 0x3348, 0x122: 0x3046, 0x123: 0x3352, + 0x124: 0x304b, 0x125: 0x3357, 0x128: 0x307d, 0x129: 0x338e, + 0x12a: 0x3082, 0x12b: 0x3393, 0x12c: 0x3087, 0x12d: 0x3398, 0x12e: 0x30aa, 0x12f: 0x33b6, + 0x130: 0x308c, 0x134: 0x30b4, 0x135: 0x33c0, + 0x136: 0x30c8, 0x137: 0x33d9, 0x139: 0x30d2, 0x13a: 0x33e3, 0x13b: 0x30dc, + 0x13c: 0x33ed, 0x13d: 0x30d7, 0x13e: 0x33e8, + // Block 0x5, offset 0x140 + 0x143: 0x30ff, 0x144: 0x3410, 0x145: 0x3118, + 0x146: 0x3429, 0x147: 0x310e, 0x148: 0x341f, + 0x14c: 0x46d3, 0x14d: 0x4764, 0x14e: 0x3131, 0x14f: 0x3442, 0x150: 0x313b, 0x151: 0x344c, + 0x154: 0x3159, 0x155: 0x346a, 0x156: 0x3172, 0x157: 0x3483, + 0x158: 0x3163, 0x159: 0x3474, 0x15a: 0x46f6, 0x15b: 0x4787, 0x15c: 0x317c, 0x15d: 0x348d, + 0x15e: 0x318b, 0x15f: 0x349c, 0x160: 0x46fb, 0x161: 0x478c, 0x162: 0x31a4, 0x163: 0x34ba, + 0x164: 0x3195, 0x165: 0x34ab, 0x168: 0x4705, 0x169: 0x4796, + 0x16a: 0x470a, 0x16b: 0x479b, 0x16c: 0x31c2, 0x16d: 0x34d8, 0x16e: 0x31cc, 0x16f: 0x34e2, + 0x170: 0x31d1, 0x171: 0x34e7, 0x172: 0x31ef, 0x173: 0x3505, 0x174: 0x3212, 0x175: 0x3528, + 0x176: 0x323a, 0x177: 0x3555, 0x178: 0x324e, 0x179: 0x325d, 0x17a: 0x357d, 0x17b: 0x3267, + 0x17c: 0x3587, 0x17d: 0x326c, 0x17e: 0x358c, 0x17f: 0xa000, + // Block 0x6, offset 0x180 + 0x184: 0x8100, 0x185: 0x8100, + 0x186: 0x8100, + 0x18d: 0x2f88, 0x18e: 0x3294, 0x18f: 0x3096, 0x190: 0x33a2, 0x191: 0x3140, + 0x192: 0x3451, 0x193: 0x31d6, 0x194: 0x34ec, 0x195: 0x39cf, 0x196: 0x3b5e, 0x197: 0x39c8, + 0x198: 0x3b57, 0x199: 0x39d6, 0x19a: 0x3b65, 0x19b: 0x39c1, 0x19c: 0x3b50, + 0x19e: 0x38b0, 0x19f: 0x3a3f, 0x1a0: 0x38a9, 0x1a1: 0x3a38, 0x1a2: 0x35b3, 0x1a3: 0x35c5, + 0x1a6: 0x3041, 0x1a7: 0x334d, 0x1a8: 0x30be, 0x1a9: 0x33cf, + 0x1aa: 0x46ec, 0x1ab: 0x477d, 0x1ac: 0x3990, 0x1ad: 0x3b1f, 0x1ae: 0x35d7, 0x1af: 0x35dd, + 0x1b0: 0x33c5, 0x1b4: 0x3028, 0x1b5: 0x3334, + 0x1b8: 0x30fa, 0x1b9: 0x340b, 0x1ba: 0x38b7, 0x1bb: 0x3a46, + 0x1bc: 0x35ad, 0x1bd: 0x35bf, 0x1be: 0x35b9, 0x1bf: 0x35cb, + // Block 0x7, offset 0x1c0 + 0x1c0: 0x2f8d, 0x1c1: 0x3299, 0x1c2: 0x2f92, 0x1c3: 0x329e, 0x1c4: 0x300a, 0x1c5: 0x3316, + 0x1c6: 0x300f, 0x1c7: 0x331b, 0x1c8: 0x309b, 0x1c9: 0x33a7, 0x1ca: 0x30a0, 0x1cb: 0x33ac, + 0x1cc: 0x3145, 0x1cd: 0x3456, 0x1ce: 0x314a, 0x1cf: 0x345b, 0x1d0: 0x3168, 0x1d1: 0x3479, + 0x1d2: 0x316d, 0x1d3: 0x347e, 0x1d4: 0x31db, 0x1d5: 0x34f1, 0x1d6: 0x31e0, 0x1d7: 0x34f6, + 0x1d8: 0x3186, 0x1d9: 0x3497, 0x1da: 0x319f, 0x1db: 0x34b5, + 0x1de: 0x305a, 0x1df: 0x3366, + 0x1e6: 0x4692, 0x1e7: 0x4723, 0x1e8: 0x46ba, 0x1e9: 0x474b, + 0x1ea: 0x395f, 0x1eb: 0x3aee, 0x1ec: 0x393c, 0x1ed: 0x3acb, 0x1ee: 0x46d8, 0x1ef: 0x4769, + 0x1f0: 0x3958, 0x1f1: 0x3ae7, 0x1f2: 0x3244, 0x1f3: 0x355f, + // Block 0x8, offset 0x200 + 0x200: 0x9932, 0x201: 0x9932, 0x202: 0x9932, 0x203: 0x9932, 0x204: 0x9932, 0x205: 0x8132, + 0x206: 0x9932, 0x207: 0x9932, 0x208: 0x9932, 0x209: 0x9932, 0x20a: 0x9932, 0x20b: 0x9932, + 0x20c: 0x9932, 0x20d: 0x8132, 0x20e: 0x8132, 0x20f: 0x9932, 0x210: 0x8132, 0x211: 0x9932, + 0x212: 0x8132, 0x213: 0x9932, 0x214: 0x9932, 0x215: 0x8133, 0x216: 0x812d, 0x217: 0x812d, + 0x218: 0x812d, 0x219: 0x812d, 0x21a: 0x8133, 0x21b: 0x992b, 0x21c: 0x812d, 0x21d: 0x812d, + 0x21e: 0x812d, 0x21f: 0x812d, 0x220: 0x812d, 0x221: 0x8129, 0x222: 0x8129, 0x223: 0x992d, + 0x224: 0x992d, 0x225: 0x992d, 0x226: 0x992d, 0x227: 0x9929, 0x228: 0x9929, 0x229: 0x812d, + 0x22a: 0x812d, 0x22b: 0x812d, 0x22c: 0x812d, 0x22d: 0x992d, 0x22e: 0x992d, 0x22f: 0x812d, + 0x230: 0x992d, 0x231: 0x992d, 0x232: 0x812d, 0x233: 0x812d, 0x234: 0x8101, 0x235: 0x8101, + 0x236: 0x8101, 0x237: 0x8101, 0x238: 0x9901, 0x239: 0x812d, 0x23a: 0x812d, 0x23b: 0x812d, + 0x23c: 0x812d, 0x23d: 0x8132, 0x23e: 0x8132, 0x23f: 0x8132, + // Block 0x9, offset 0x240 + 0x240: 0x49ae, 0x241: 0x49b3, 0x242: 0x9932, 0x243: 0x49b8, 0x244: 0x4a71, 0x245: 0x9936, + 0x246: 0x8132, 0x247: 0x812d, 0x248: 0x812d, 0x249: 0x812d, 0x24a: 0x8132, 0x24b: 0x8132, + 0x24c: 0x8132, 0x24d: 0x812d, 0x24e: 0x812d, 0x250: 0x8132, 0x251: 0x8132, + 0x252: 0x8132, 0x253: 0x812d, 0x254: 0x812d, 0x255: 0x812d, 0x256: 0x812d, 0x257: 0x8132, + 0x258: 0x8133, 0x259: 0x812d, 0x25a: 0x812d, 0x25b: 0x8132, 0x25c: 0x8134, 0x25d: 0x8135, + 0x25e: 0x8135, 0x25f: 0x8134, 0x260: 0x8135, 0x261: 0x8135, 0x262: 0x8134, 0x263: 0x8132, + 0x264: 0x8132, 0x265: 0x8132, 0x266: 0x8132, 0x267: 0x8132, 0x268: 0x8132, 0x269: 0x8132, + 0x26a: 0x8132, 0x26b: 0x8132, 0x26c: 0x8132, 0x26d: 0x8132, 0x26e: 0x8132, 0x26f: 0x8132, + 0x274: 0x0170, + 0x27a: 0x8100, + 0x27e: 0x0037, + // Block 0xa, offset 0x280 + 0x284: 0x8100, 0x285: 0x35a1, + 0x286: 0x35e9, 0x287: 0x00ce, 0x288: 0x3607, 0x289: 0x3613, 0x28a: 0x3625, + 0x28c: 0x3643, 0x28e: 0x3655, 0x28f: 0x3673, 0x290: 0x3e08, 0x291: 0xa000, + 0x295: 0xa000, 0x297: 0xa000, + 0x299: 0xa000, + 0x29f: 0xa000, 0x2a1: 0xa000, + 0x2a5: 0xa000, 0x2a9: 0xa000, + 0x2aa: 0x3637, 0x2ab: 0x3667, 0x2ac: 0x47fe, 0x2ad: 0x3697, 0x2ae: 0x4828, 0x2af: 0x36a9, + 0x2b0: 0x3e70, 0x2b1: 0xa000, 0x2b5: 0xa000, + 0x2b7: 0xa000, 0x2b9: 0xa000, + 0x2bf: 0xa000, + // Block 0xb, offset 0x2c0 + 0x2c0: 0x3721, 0x2c1: 0x372d, 0x2c3: 0x371b, + 0x2c6: 0xa000, 0x2c7: 0x3709, + 0x2cc: 0x375d, 0x2cd: 0x3745, 0x2ce: 0x376f, 0x2d0: 0xa000, + 0x2d3: 0xa000, 0x2d5: 0xa000, 0x2d6: 0xa000, 0x2d7: 0xa000, + 0x2d8: 0xa000, 0x2d9: 0x3751, 0x2da: 0xa000, + 0x2de: 0xa000, 0x2e3: 0xa000, + 0x2e7: 0xa000, + 0x2eb: 0xa000, 0x2ed: 0xa000, + 0x2f0: 0xa000, 0x2f3: 0xa000, 0x2f5: 0xa000, + 0x2f6: 0xa000, 0x2f7: 0xa000, 0x2f8: 0xa000, 0x2f9: 0x37d5, 0x2fa: 0xa000, + 0x2fe: 0xa000, + // Block 0xc, offset 0x300 + 0x301: 0x3733, 0x302: 0x37b7, + 0x310: 0x370f, 0x311: 0x3793, + 0x312: 0x3715, 0x313: 0x3799, 0x316: 0x3727, 0x317: 0x37ab, + 0x318: 0xa000, 0x319: 0xa000, 0x31a: 0x3829, 0x31b: 0x382f, 0x31c: 0x3739, 0x31d: 0x37bd, + 0x31e: 0x373f, 0x31f: 0x37c3, 0x322: 0x374b, 0x323: 0x37cf, + 0x324: 0x3757, 0x325: 0x37db, 0x326: 0x3763, 0x327: 0x37e7, 0x328: 0xa000, 0x329: 0xa000, + 0x32a: 0x3835, 0x32b: 0x383b, 0x32c: 0x378d, 0x32d: 0x3811, 0x32e: 0x3769, 0x32f: 0x37ed, + 0x330: 0x3775, 0x331: 0x37f9, 0x332: 0x377b, 0x333: 0x37ff, 0x334: 0x3781, 0x335: 0x3805, + 0x338: 0x3787, 0x339: 0x380b, + // Block 0xd, offset 0x340 + 0x351: 0x812d, + 0x352: 0x8132, 0x353: 0x8132, 0x354: 0x8132, 0x355: 0x8132, 0x356: 0x812d, 0x357: 0x8132, + 0x358: 0x8132, 0x359: 0x8132, 0x35a: 0x812e, 0x35b: 0x812d, 0x35c: 0x8132, 0x35d: 0x8132, + 0x35e: 0x8132, 0x35f: 0x8132, 0x360: 0x8132, 0x361: 0x8132, 0x362: 0x812d, 0x363: 0x812d, + 0x364: 0x812d, 0x365: 0x812d, 0x366: 0x812d, 0x367: 0x812d, 0x368: 0x8132, 0x369: 0x8132, + 0x36a: 0x812d, 0x36b: 0x8132, 0x36c: 0x8132, 0x36d: 0x812e, 0x36e: 0x8131, 0x36f: 0x8132, + 0x370: 0x8105, 0x371: 0x8106, 0x372: 0x8107, 0x373: 0x8108, 0x374: 0x8109, 0x375: 0x810a, + 0x376: 0x810b, 0x377: 0x810c, 0x378: 0x810d, 0x379: 0x810e, 0x37a: 0x810e, 0x37b: 0x810f, + 0x37c: 0x8110, 0x37d: 0x8111, 0x37f: 0x8112, + // Block 0xe, offset 0x380 + 0x388: 0xa000, 0x38a: 0xa000, 0x38b: 0x8116, + 0x38c: 0x8117, 0x38d: 0x8118, 0x38e: 0x8119, 0x38f: 0x811a, 0x390: 0x811b, 0x391: 0x811c, + 0x392: 0x811d, 0x393: 0x9932, 0x394: 0x9932, 0x395: 0x992d, 0x396: 0x812d, 0x397: 0x8132, + 0x398: 0x8132, 0x399: 0x8132, 0x39a: 0x8132, 0x39b: 0x8132, 0x39c: 0x812d, 0x39d: 0x8132, + 0x39e: 0x8132, 0x39f: 0x812d, + 0x3b0: 0x811e, + // Block 0xf, offset 0x3c0 + 0x3c5: 0xa000, + 0x3c6: 0x2d26, 0x3c7: 0xa000, 0x3c8: 0x2d2e, 0x3c9: 0xa000, 0x3ca: 0x2d36, 0x3cb: 0xa000, + 0x3cc: 0x2d3e, 0x3cd: 0xa000, 0x3ce: 0x2d46, 0x3d1: 0xa000, + 0x3d2: 0x2d4e, + 0x3f4: 0x8102, 0x3f5: 0x9900, + 0x3fa: 0xa000, 0x3fb: 0x2d56, + 0x3fc: 0xa000, 0x3fd: 0x2d5e, 0x3fe: 0xa000, 0x3ff: 0xa000, + // Block 0x10, offset 0x400 + 0x400: 0x8132, 0x401: 0x8132, 0x402: 0x812d, 0x403: 0x8132, 0x404: 0x8132, 0x405: 0x8132, + 0x406: 0x8132, 0x407: 0x8132, 0x408: 0x8132, 0x409: 0x8132, 0x40a: 0x812d, 0x40b: 0x8132, + 0x40c: 0x8132, 0x40d: 0x8135, 0x40e: 0x812a, 0x40f: 0x812d, 0x410: 0x8129, 0x411: 0x8132, + 0x412: 0x8132, 0x413: 0x8132, 0x414: 0x8132, 0x415: 0x8132, 0x416: 0x8132, 0x417: 0x8132, + 0x418: 0x8132, 0x419: 0x8132, 0x41a: 0x8132, 0x41b: 0x8132, 0x41c: 0x8132, 0x41d: 0x8132, + 0x41e: 0x8132, 0x41f: 0x8132, 0x420: 0x8132, 0x421: 0x8132, 0x422: 0x8132, 0x423: 0x8132, + 0x424: 0x8132, 0x425: 0x8132, 0x426: 0x8132, 0x427: 0x8132, 0x428: 0x8132, 0x429: 0x8132, + 0x42a: 0x8132, 0x42b: 0x8132, 0x42c: 0x8132, 0x42d: 0x8132, 0x42e: 0x8132, 0x42f: 0x8132, + 0x430: 0x8132, 0x431: 0x8132, 0x432: 0x8132, 0x433: 0x8132, 0x434: 0x8132, 0x435: 0x8132, + 0x436: 0x8133, 0x437: 0x8131, 0x438: 0x8131, 0x439: 0x812d, 0x43b: 0x8132, + 0x43c: 0x8134, 0x43d: 0x812d, 0x43e: 0x8132, 0x43f: 0x812d, + // Block 0x11, offset 0x440 + 0x440: 0x2f97, 0x441: 0x32a3, 0x442: 0x2fa1, 0x443: 0x32ad, 0x444: 0x2fa6, 0x445: 0x32b2, + 0x446: 0x2fab, 0x447: 0x32b7, 0x448: 0x38cc, 0x449: 0x3a5b, 0x44a: 0x2fc4, 0x44b: 0x32d0, + 0x44c: 0x2fce, 0x44d: 0x32da, 0x44e: 0x2fdd, 0x44f: 0x32e9, 0x450: 0x2fd3, 0x451: 0x32df, + 0x452: 0x2fd8, 0x453: 0x32e4, 0x454: 0x38ef, 0x455: 0x3a7e, 0x456: 0x38f6, 0x457: 0x3a85, + 0x458: 0x3019, 0x459: 0x3325, 0x45a: 0x301e, 0x45b: 0x332a, 0x45c: 0x3904, 0x45d: 0x3a93, + 0x45e: 0x3023, 0x45f: 0x332f, 0x460: 0x3032, 0x461: 0x333e, 0x462: 0x3050, 0x463: 0x335c, + 0x464: 0x305f, 0x465: 0x336b, 0x466: 0x3055, 0x467: 0x3361, 0x468: 0x3064, 0x469: 0x3370, + 0x46a: 0x3069, 0x46b: 0x3375, 0x46c: 0x30af, 0x46d: 0x33bb, 0x46e: 0x390b, 0x46f: 0x3a9a, + 0x470: 0x30b9, 0x471: 0x33ca, 0x472: 0x30c3, 0x473: 0x33d4, 0x474: 0x30cd, 0x475: 0x33de, + 0x476: 0x46c4, 0x477: 0x4755, 0x478: 0x3912, 0x479: 0x3aa1, 0x47a: 0x30e6, 0x47b: 0x33f7, + 0x47c: 0x30e1, 0x47d: 0x33f2, 0x47e: 0x30eb, 0x47f: 0x33fc, + // Block 0x12, offset 0x480 + 0x480: 0x30f0, 0x481: 0x3401, 0x482: 0x30f5, 0x483: 0x3406, 0x484: 0x3109, 0x485: 0x341a, + 0x486: 0x3113, 0x487: 0x3424, 0x488: 0x3122, 0x489: 0x3433, 0x48a: 0x311d, 0x48b: 0x342e, + 0x48c: 0x3935, 0x48d: 0x3ac4, 0x48e: 0x3943, 0x48f: 0x3ad2, 0x490: 0x394a, 0x491: 0x3ad9, + 0x492: 0x3951, 0x493: 0x3ae0, 0x494: 0x314f, 0x495: 0x3460, 0x496: 0x3154, 0x497: 0x3465, + 0x498: 0x315e, 0x499: 0x346f, 0x49a: 0x46f1, 0x49b: 0x4782, 0x49c: 0x3997, 0x49d: 0x3b26, + 0x49e: 0x3177, 0x49f: 0x3488, 0x4a0: 0x3181, 0x4a1: 0x3492, 0x4a2: 0x4700, 0x4a3: 0x4791, + 0x4a4: 0x399e, 0x4a5: 0x3b2d, 0x4a6: 0x39a5, 0x4a7: 0x3b34, 0x4a8: 0x39ac, 0x4a9: 0x3b3b, + 0x4aa: 0x3190, 0x4ab: 0x34a1, 0x4ac: 0x319a, 0x4ad: 0x34b0, 0x4ae: 0x31ae, 0x4af: 0x34c4, + 0x4b0: 0x31a9, 0x4b1: 0x34bf, 0x4b2: 0x31ea, 0x4b3: 0x3500, 0x4b4: 0x31f9, 0x4b5: 0x350f, + 0x4b6: 0x31f4, 0x4b7: 0x350a, 0x4b8: 0x39b3, 0x4b9: 0x3b42, 0x4ba: 0x39ba, 0x4bb: 0x3b49, + 0x4bc: 0x31fe, 0x4bd: 0x3514, 0x4be: 0x3203, 0x4bf: 0x3519, + // Block 0x13, offset 0x4c0 + 0x4c0: 0x3208, 0x4c1: 0x351e, 0x4c2: 0x320d, 0x4c3: 0x3523, 0x4c4: 0x321c, 0x4c5: 0x3532, + 0x4c6: 0x3217, 0x4c7: 0x352d, 0x4c8: 0x3221, 0x4c9: 0x353c, 0x4ca: 0x3226, 0x4cb: 0x3541, + 0x4cc: 0x322b, 0x4cd: 0x3546, 0x4ce: 0x3249, 0x4cf: 0x3564, 0x4d0: 0x3262, 0x4d1: 0x3582, + 0x4d2: 0x3271, 0x4d3: 0x3591, 0x4d4: 0x3276, 0x4d5: 0x3596, 0x4d6: 0x337a, 0x4d7: 0x34a6, + 0x4d8: 0x3537, 0x4d9: 0x3573, 0x4db: 0x35d1, + 0x4e0: 0x46a1, 0x4e1: 0x4732, 0x4e2: 0x2f83, 0x4e3: 0x328f, + 0x4e4: 0x3878, 0x4e5: 0x3a07, 0x4e6: 0x3871, 0x4e7: 0x3a00, 0x4e8: 0x3886, 0x4e9: 0x3a15, + 0x4ea: 0x387f, 0x4eb: 0x3a0e, 0x4ec: 0x38be, 0x4ed: 0x3a4d, 0x4ee: 0x3894, 0x4ef: 0x3a23, + 0x4f0: 0x388d, 0x4f1: 0x3a1c, 0x4f2: 0x38a2, 0x4f3: 0x3a31, 0x4f4: 0x389b, 0x4f5: 0x3a2a, + 0x4f6: 0x38c5, 0x4f7: 0x3a54, 0x4f8: 0x46b5, 0x4f9: 0x4746, 0x4fa: 0x3000, 0x4fb: 0x330c, + 0x4fc: 0x2fec, 0x4fd: 0x32f8, 0x4fe: 0x38da, 0x4ff: 0x3a69, + // Block 0x14, offset 0x500 + 0x500: 0x38d3, 0x501: 0x3a62, 0x502: 0x38e8, 0x503: 0x3a77, 0x504: 0x38e1, 0x505: 0x3a70, + 0x506: 0x38fd, 0x507: 0x3a8c, 0x508: 0x3091, 0x509: 0x339d, 0x50a: 0x30a5, 0x50b: 0x33b1, + 0x50c: 0x46e7, 0x50d: 0x4778, 0x50e: 0x3136, 0x50f: 0x3447, 0x510: 0x3920, 0x511: 0x3aaf, + 0x512: 0x3919, 0x513: 0x3aa8, 0x514: 0x392e, 0x515: 0x3abd, 0x516: 0x3927, 0x517: 0x3ab6, + 0x518: 0x3989, 0x519: 0x3b18, 0x51a: 0x396d, 0x51b: 0x3afc, 0x51c: 0x3966, 0x51d: 0x3af5, + 0x51e: 0x397b, 0x51f: 0x3b0a, 0x520: 0x3974, 0x521: 0x3b03, 0x522: 0x3982, 0x523: 0x3b11, + 0x524: 0x31e5, 0x525: 0x34fb, 0x526: 0x31c7, 0x527: 0x34dd, 0x528: 0x39e4, 0x529: 0x3b73, + 0x52a: 0x39dd, 0x52b: 0x3b6c, 0x52c: 0x39f2, 0x52d: 0x3b81, 0x52e: 0x39eb, 0x52f: 0x3b7a, + 0x530: 0x39f9, 0x531: 0x3b88, 0x532: 0x3230, 0x533: 0x354b, 0x534: 0x3258, 0x535: 0x3578, + 0x536: 0x3253, 0x537: 0x356e, 0x538: 0x323f, 0x539: 0x355a, + // Block 0x15, offset 0x540 + 0x540: 0x4804, 0x541: 0x480a, 0x542: 0x491e, 0x543: 0x4936, 0x544: 0x4926, 0x545: 0x493e, + 0x546: 0x492e, 0x547: 0x4946, 0x548: 0x47aa, 0x549: 0x47b0, 0x54a: 0x488e, 0x54b: 0x48a6, + 0x54c: 0x4896, 0x54d: 0x48ae, 0x54e: 0x489e, 0x54f: 0x48b6, 0x550: 0x4816, 0x551: 0x481c, + 0x552: 0x3db8, 0x553: 0x3dc8, 0x554: 0x3dc0, 0x555: 0x3dd0, + 0x558: 0x47b6, 0x559: 0x47bc, 0x55a: 0x3ce8, 0x55b: 0x3cf8, 0x55c: 0x3cf0, 0x55d: 0x3d00, + 0x560: 0x482e, 0x561: 0x4834, 0x562: 0x494e, 0x563: 0x4966, + 0x564: 0x4956, 0x565: 0x496e, 0x566: 0x495e, 0x567: 0x4976, 0x568: 0x47c2, 0x569: 0x47c8, + 0x56a: 0x48be, 0x56b: 0x48d6, 0x56c: 0x48c6, 0x56d: 0x48de, 0x56e: 0x48ce, 0x56f: 0x48e6, + 0x570: 0x4846, 0x571: 0x484c, 0x572: 0x3e18, 0x573: 0x3e30, 0x574: 0x3e20, 0x575: 0x3e38, + 0x576: 0x3e28, 0x577: 0x3e40, 0x578: 0x47ce, 0x579: 0x47d4, 0x57a: 0x3d18, 0x57b: 0x3d30, + 0x57c: 0x3d20, 0x57d: 0x3d38, 0x57e: 0x3d28, 0x57f: 0x3d40, + // Block 0x16, offset 0x580 + 0x580: 0x4852, 0x581: 0x4858, 0x582: 0x3e48, 0x583: 0x3e58, 0x584: 0x3e50, 0x585: 0x3e60, + 0x588: 0x47da, 0x589: 0x47e0, 0x58a: 0x3d48, 0x58b: 0x3d58, + 0x58c: 0x3d50, 0x58d: 0x3d60, 0x590: 0x4864, 0x591: 0x486a, + 0x592: 0x3e80, 0x593: 0x3e98, 0x594: 0x3e88, 0x595: 0x3ea0, 0x596: 0x3e90, 0x597: 0x3ea8, + 0x599: 0x47e6, 0x59b: 0x3d68, 0x59d: 0x3d70, + 0x59f: 0x3d78, 0x5a0: 0x487c, 0x5a1: 0x4882, 0x5a2: 0x497e, 0x5a3: 0x4996, + 0x5a4: 0x4986, 0x5a5: 0x499e, 0x5a6: 0x498e, 0x5a7: 0x49a6, 0x5a8: 0x47ec, 0x5a9: 0x47f2, + 0x5aa: 0x48ee, 0x5ab: 0x4906, 0x5ac: 0x48f6, 0x5ad: 0x490e, 0x5ae: 0x48fe, 0x5af: 0x4916, + 0x5b0: 0x47f8, 0x5b1: 0x431e, 0x5b2: 0x3691, 0x5b3: 0x4324, 0x5b4: 0x4822, 0x5b5: 0x432a, + 0x5b6: 0x36a3, 0x5b7: 0x4330, 0x5b8: 0x36c1, 0x5b9: 0x4336, 0x5ba: 0x36d9, 0x5bb: 0x433c, + 0x5bc: 0x4870, 0x5bd: 0x4342, + // Block 0x17, offset 0x5c0 + 0x5c0: 0x3da0, 0x5c1: 0x3da8, 0x5c2: 0x4184, 0x5c3: 0x41a2, 0x5c4: 0x418e, 0x5c5: 0x41ac, + 0x5c6: 0x4198, 0x5c7: 0x41b6, 0x5c8: 0x3cd8, 0x5c9: 0x3ce0, 0x5ca: 0x40d0, 0x5cb: 0x40ee, + 0x5cc: 0x40da, 0x5cd: 0x40f8, 0x5ce: 0x40e4, 0x5cf: 0x4102, 0x5d0: 0x3de8, 0x5d1: 0x3df0, + 0x5d2: 0x41c0, 0x5d3: 0x41de, 0x5d4: 0x41ca, 0x5d5: 0x41e8, 0x5d6: 0x41d4, 0x5d7: 0x41f2, + 0x5d8: 0x3d08, 0x5d9: 0x3d10, 0x5da: 0x410c, 0x5db: 0x412a, 0x5dc: 0x4116, 0x5dd: 0x4134, + 0x5de: 0x4120, 0x5df: 0x413e, 0x5e0: 0x3ec0, 0x5e1: 0x3ec8, 0x5e2: 0x41fc, 0x5e3: 0x421a, + 0x5e4: 0x4206, 0x5e5: 0x4224, 0x5e6: 0x4210, 0x5e7: 0x422e, 0x5e8: 0x3d80, 0x5e9: 0x3d88, + 0x5ea: 0x4148, 0x5eb: 0x4166, 0x5ec: 0x4152, 0x5ed: 0x4170, 0x5ee: 0x415c, 0x5ef: 0x417a, + 0x5f0: 0x3685, 0x5f1: 0x367f, 0x5f2: 0x3d90, 0x5f3: 0x368b, 0x5f4: 0x3d98, + 0x5f6: 0x4810, 0x5f7: 0x3db0, 0x5f8: 0x35f5, 0x5f9: 0x35ef, 0x5fa: 0x35e3, 0x5fb: 0x42ee, + 0x5fc: 0x35fb, 0x5fd: 0x8100, 0x5fe: 0x01d3, 0x5ff: 0xa100, + // Block 0x18, offset 0x600 + 0x600: 0x8100, 0x601: 0x35a7, 0x602: 0x3dd8, 0x603: 0x369d, 0x604: 0x3de0, + 0x606: 0x483a, 0x607: 0x3df8, 0x608: 0x3601, 0x609: 0x42f4, 0x60a: 0x360d, 0x60b: 0x42fa, + 0x60c: 0x3619, 0x60d: 0x3b8f, 0x60e: 0x3b96, 0x60f: 0x3b9d, 0x610: 0x36b5, 0x611: 0x36af, + 0x612: 0x3e00, 0x613: 0x44e4, 0x616: 0x36bb, 0x617: 0x3e10, + 0x618: 0x3631, 0x619: 0x362b, 0x61a: 0x361f, 0x61b: 0x4300, 0x61d: 0x3ba4, + 0x61e: 0x3bab, 0x61f: 0x3bb2, 0x620: 0x36eb, 0x621: 0x36e5, 0x622: 0x3e68, 0x623: 0x44ec, + 0x624: 0x36cd, 0x625: 0x36d3, 0x626: 0x36f1, 0x627: 0x3e78, 0x628: 0x3661, 0x629: 0x365b, + 0x62a: 0x364f, 0x62b: 0x430c, 0x62c: 0x3649, 0x62d: 0x359b, 0x62e: 0x42e8, 0x62f: 0x0081, + 0x632: 0x3eb0, 0x633: 0x36f7, 0x634: 0x3eb8, + 0x636: 0x4888, 0x637: 0x3ed0, 0x638: 0x363d, 0x639: 0x4306, 0x63a: 0x366d, 0x63b: 0x4318, + 0x63c: 0x3679, 0x63d: 0x4256, 0x63e: 0xa100, + // Block 0x19, offset 0x640 + 0x641: 0x3c06, 0x643: 0xa000, 0x644: 0x3c0d, 0x645: 0xa000, + 0x647: 0x3c14, 0x648: 0xa000, 0x649: 0x3c1b, + 0x64d: 0xa000, + 0x660: 0x2f65, 0x661: 0xa000, 0x662: 0x3c29, + 0x664: 0xa000, 0x665: 0xa000, + 0x66d: 0x3c22, 0x66e: 0x2f60, 0x66f: 0x2f6a, + 0x670: 0x3c30, 0x671: 0x3c37, 0x672: 0xa000, 0x673: 0xa000, 0x674: 0x3c3e, 0x675: 0x3c45, + 0x676: 0xa000, 0x677: 0xa000, 0x678: 0x3c4c, 0x679: 0x3c53, 0x67a: 0xa000, 0x67b: 0xa000, + 0x67c: 0xa000, 0x67d: 0xa000, + // Block 0x1a, offset 0x680 + 0x680: 0x3c5a, 0x681: 0x3c61, 0x682: 0xa000, 0x683: 0xa000, 0x684: 0x3c76, 0x685: 0x3c7d, + 0x686: 0xa000, 0x687: 0xa000, 0x688: 0x3c84, 0x689: 0x3c8b, + 0x691: 0xa000, + 0x692: 0xa000, + 0x6a2: 0xa000, + 0x6a8: 0xa000, 0x6a9: 0xa000, + 0x6ab: 0xa000, 0x6ac: 0x3ca0, 0x6ad: 0x3ca7, 0x6ae: 0x3cae, 0x6af: 0x3cb5, + 0x6b2: 0xa000, 0x6b3: 0xa000, 0x6b4: 0xa000, 0x6b5: 0xa000, + // Block 0x1b, offset 0x6c0 + 0x6c6: 0xa000, 0x6cb: 0xa000, + 0x6cc: 0x3f08, 0x6cd: 0xa000, 0x6ce: 0x3f10, 0x6cf: 0xa000, 0x6d0: 0x3f18, 0x6d1: 0xa000, + 0x6d2: 0x3f20, 0x6d3: 0xa000, 0x6d4: 0x3f28, 0x6d5: 0xa000, 0x6d6: 0x3f30, 0x6d7: 0xa000, + 0x6d8: 0x3f38, 0x6d9: 0xa000, 0x6da: 0x3f40, 0x6db: 0xa000, 0x6dc: 0x3f48, 0x6dd: 0xa000, + 0x6de: 0x3f50, 0x6df: 0xa000, 0x6e0: 0x3f58, 0x6e1: 0xa000, 0x6e2: 0x3f60, + 0x6e4: 0xa000, 0x6e5: 0x3f68, 0x6e6: 0xa000, 0x6e7: 0x3f70, 0x6e8: 0xa000, 0x6e9: 0x3f78, + 0x6ef: 0xa000, + 0x6f0: 0x3f80, 0x6f1: 0x3f88, 0x6f2: 0xa000, 0x6f3: 0x3f90, 0x6f4: 0x3f98, 0x6f5: 0xa000, + 0x6f6: 0x3fa0, 0x6f7: 0x3fa8, 0x6f8: 0xa000, 0x6f9: 0x3fb0, 0x6fa: 0x3fb8, 0x6fb: 0xa000, + 0x6fc: 0x3fc0, 0x6fd: 0x3fc8, + // Block 0x1c, offset 0x700 + 0x714: 0x3f00, + 0x719: 0x9903, 0x71a: 0x9903, 0x71b: 0x8100, 0x71c: 0x8100, 0x71d: 0xa000, + 0x71e: 0x3fd0, + 0x726: 0xa000, + 0x72b: 0xa000, 0x72c: 0x3fe0, 0x72d: 0xa000, 0x72e: 0x3fe8, 0x72f: 0xa000, + 0x730: 0x3ff0, 0x731: 0xa000, 0x732: 0x3ff8, 0x733: 0xa000, 0x734: 0x4000, 0x735: 0xa000, + 0x736: 0x4008, 0x737: 0xa000, 0x738: 0x4010, 0x739: 0xa000, 0x73a: 0x4018, 0x73b: 0xa000, + 0x73c: 0x4020, 0x73d: 0xa000, 0x73e: 0x4028, 0x73f: 0xa000, + // Block 0x1d, offset 0x740 + 0x740: 0x4030, 0x741: 0xa000, 0x742: 0x4038, 0x744: 0xa000, 0x745: 0x4040, + 0x746: 0xa000, 0x747: 0x4048, 0x748: 0xa000, 0x749: 0x4050, + 0x74f: 0xa000, 0x750: 0x4058, 0x751: 0x4060, + 0x752: 0xa000, 0x753: 0x4068, 0x754: 0x4070, 0x755: 0xa000, 0x756: 0x4078, 0x757: 0x4080, + 0x758: 0xa000, 0x759: 0x4088, 0x75a: 0x4090, 0x75b: 0xa000, 0x75c: 0x4098, 0x75d: 0x40a0, + 0x76f: 0xa000, + 0x770: 0xa000, 0x771: 0xa000, 0x772: 0xa000, 0x774: 0x3fd8, + 0x777: 0x40a8, 0x778: 0x40b0, 0x779: 0x40b8, 0x77a: 0x40c0, + 0x77d: 0xa000, 0x77e: 0x40c8, + // Block 0x1e, offset 0x780 + 0x780: 0x1377, 0x781: 0x0cfb, 0x782: 0x13d3, 0x783: 0x139f, 0x784: 0x0e57, 0x785: 0x06eb, + 0x786: 0x08df, 0x787: 0x162b, 0x788: 0x162b, 0x789: 0x0a0b, 0x78a: 0x145f, 0x78b: 0x0943, + 0x78c: 0x0a07, 0x78d: 0x0bef, 0x78e: 0x0fcf, 0x78f: 0x115f, 0x790: 0x1297, 0x791: 0x12d3, + 0x792: 0x1307, 0x793: 0x141b, 0x794: 0x0d73, 0x795: 0x0dff, 0x796: 0x0eab, 0x797: 0x0f43, + 0x798: 0x125f, 0x799: 0x1447, 0x79a: 0x1573, 0x79b: 0x070f, 0x79c: 0x08b3, 0x79d: 0x0d87, + 0x79e: 0x0ecf, 0x79f: 0x1293, 0x7a0: 0x15c3, 0x7a1: 0x0ab3, 0x7a2: 0x0e77, 0x7a3: 0x1283, + 0x7a4: 0x1317, 0x7a5: 0x0c23, 0x7a6: 0x11bb, 0x7a7: 0x12df, 0x7a8: 0x0b1f, 0x7a9: 0x0d0f, + 0x7aa: 0x0e17, 0x7ab: 0x0f1b, 0x7ac: 0x1427, 0x7ad: 0x074f, 0x7ae: 0x07e7, 0x7af: 0x0853, + 0x7b0: 0x0c8b, 0x7b1: 0x0d7f, 0x7b2: 0x0ecb, 0x7b3: 0x0fef, 0x7b4: 0x1177, 0x7b5: 0x128b, + 0x7b6: 0x12a3, 0x7b7: 0x13c7, 0x7b8: 0x14ef, 0x7b9: 0x15a3, 0x7ba: 0x15bf, 0x7bb: 0x102b, + 0x7bc: 0x106b, 0x7bd: 0x1123, 0x7be: 0x1243, 0x7bf: 0x147b, + // Block 0x1f, offset 0x7c0 + 0x7c0: 0x15cb, 0x7c1: 0x134b, 0x7c2: 0x09c7, 0x7c3: 0x0b3b, 0x7c4: 0x10db, 0x7c5: 0x119b, + 0x7c6: 0x0eff, 0x7c7: 0x1033, 0x7c8: 0x1397, 0x7c9: 0x14e7, 0x7ca: 0x09c3, 0x7cb: 0x0a8f, + 0x7cc: 0x0d77, 0x7cd: 0x0e2b, 0x7ce: 0x0e5f, 0x7cf: 0x1113, 0x7d0: 0x113b, 0x7d1: 0x14a7, + 0x7d2: 0x084f, 0x7d3: 0x11a7, 0x7d4: 0x07f3, 0x7d5: 0x07ef, 0x7d6: 0x1097, 0x7d7: 0x1127, + 0x7d8: 0x125b, 0x7d9: 0x14af, 0x7da: 0x1367, 0x7db: 0x0c27, 0x7dc: 0x0d73, 0x7dd: 0x1357, + 0x7de: 0x06f7, 0x7df: 0x0a63, 0x7e0: 0x0b93, 0x7e1: 0x0f2f, 0x7e2: 0x0faf, 0x7e3: 0x0873, + 0x7e4: 0x103b, 0x7e5: 0x075f, 0x7e6: 0x0b77, 0x7e7: 0x06d7, 0x7e8: 0x0deb, 0x7e9: 0x0ca3, + 0x7ea: 0x110f, 0x7eb: 0x08c7, 0x7ec: 0x09b3, 0x7ed: 0x0ffb, 0x7ee: 0x1263, 0x7ef: 0x133b, + 0x7f0: 0x0db7, 0x7f1: 0x13f7, 0x7f2: 0x0de3, 0x7f3: 0x0c37, 0x7f4: 0x121b, 0x7f5: 0x0c57, + 0x7f6: 0x0fab, 0x7f7: 0x072b, 0x7f8: 0x07a7, 0x7f9: 0x07eb, 0x7fa: 0x0d53, 0x7fb: 0x10fb, + 0x7fc: 0x11f3, 0x7fd: 0x1347, 0x7fe: 0x145b, 0x7ff: 0x085b, + // Block 0x20, offset 0x800 + 0x800: 0x090f, 0x801: 0x0a17, 0x802: 0x0b2f, 0x803: 0x0cbf, 0x804: 0x0e7b, 0x805: 0x103f, + 0x806: 0x1497, 0x807: 0x157b, 0x808: 0x15cf, 0x809: 0x15e7, 0x80a: 0x0837, 0x80b: 0x0cf3, + 0x80c: 0x0da3, 0x80d: 0x13eb, 0x80e: 0x0afb, 0x80f: 0x0bd7, 0x810: 0x0bf3, 0x811: 0x0c83, + 0x812: 0x0e6b, 0x813: 0x0eb7, 0x814: 0x0f67, 0x815: 0x108b, 0x816: 0x112f, 0x817: 0x1193, + 0x818: 0x13db, 0x819: 0x126b, 0x81a: 0x1403, 0x81b: 0x147f, 0x81c: 0x080f, 0x81d: 0x083b, + 0x81e: 0x0923, 0x81f: 0x0ea7, 0x820: 0x12f3, 0x821: 0x133b, 0x822: 0x0b1b, 0x823: 0x0b8b, + 0x824: 0x0c4f, 0x825: 0x0daf, 0x826: 0x10d7, 0x827: 0x0f23, 0x828: 0x073b, 0x829: 0x097f, + 0x82a: 0x0a63, 0x82b: 0x0ac7, 0x82c: 0x0b97, 0x82d: 0x0f3f, 0x82e: 0x0f5b, 0x82f: 0x116b, + 0x830: 0x118b, 0x831: 0x1463, 0x832: 0x14e3, 0x833: 0x14f3, 0x834: 0x152f, 0x835: 0x0753, + 0x836: 0x107f, 0x837: 0x144f, 0x838: 0x14cb, 0x839: 0x0baf, 0x83a: 0x0717, 0x83b: 0x0777, + 0x83c: 0x0a67, 0x83d: 0x0a87, 0x83e: 0x0caf, 0x83f: 0x0d73, + // Block 0x21, offset 0x840 + 0x840: 0x0ec3, 0x841: 0x0fcb, 0x842: 0x1277, 0x843: 0x1417, 0x844: 0x1623, 0x845: 0x0ce3, + 0x846: 0x14a3, 0x847: 0x0833, 0x848: 0x0d2f, 0x849: 0x0d3b, 0x84a: 0x0e0f, 0x84b: 0x0e47, + 0x84c: 0x0f4b, 0x84d: 0x0fa7, 0x84e: 0x1027, 0x84f: 0x110b, 0x850: 0x153b, 0x851: 0x07af, + 0x852: 0x0c03, 0x853: 0x14b3, 0x854: 0x0767, 0x855: 0x0aab, 0x856: 0x0e2f, 0x857: 0x13df, + 0x858: 0x0b67, 0x859: 0x0bb7, 0x85a: 0x0d43, 0x85b: 0x0f2f, 0x85c: 0x14bb, 0x85d: 0x0817, + 0x85e: 0x08ff, 0x85f: 0x0a97, 0x860: 0x0cd3, 0x861: 0x0d1f, 0x862: 0x0d5f, 0x863: 0x0df3, + 0x864: 0x0f47, 0x865: 0x0fbb, 0x866: 0x1157, 0x867: 0x12f7, 0x868: 0x1303, 0x869: 0x1457, + 0x86a: 0x14d7, 0x86b: 0x0883, 0x86c: 0x0e4b, 0x86d: 0x0903, 0x86e: 0x0ec7, 0x86f: 0x0f6b, + 0x870: 0x1287, 0x871: 0x14bf, 0x872: 0x15ab, 0x873: 0x15d3, 0x874: 0x0d37, 0x875: 0x0e27, + 0x876: 0x11c3, 0x877: 0x10b7, 0x878: 0x10c3, 0x879: 0x10e7, 0x87a: 0x0f17, 0x87b: 0x0e9f, + 0x87c: 0x1363, 0x87d: 0x0733, 0x87e: 0x122b, 0x87f: 0x081b, + // Block 0x22, offset 0x880 + 0x880: 0x080b, 0x881: 0x0b0b, 0x882: 0x0c2b, 0x883: 0x10f3, 0x884: 0x0a53, 0x885: 0x0e03, + 0x886: 0x0cef, 0x887: 0x13e7, 0x888: 0x12e7, 0x889: 0x14ab, 0x88a: 0x1323, 0x88b: 0x0b27, + 0x88c: 0x0787, 0x88d: 0x095b, 0x890: 0x09af, + 0x892: 0x0cdf, 0x895: 0x07f7, 0x896: 0x0f1f, 0x897: 0x0fe3, + 0x898: 0x1047, 0x899: 0x1063, 0x89a: 0x1067, 0x89b: 0x107b, 0x89c: 0x14fb, 0x89d: 0x10eb, + 0x89e: 0x116f, 0x8a0: 0x128f, 0x8a2: 0x1353, + 0x8a5: 0x1407, 0x8a6: 0x1433, + 0x8aa: 0x154f, 0x8ab: 0x1553, 0x8ac: 0x1557, 0x8ad: 0x15bb, 0x8ae: 0x142b, 0x8af: 0x14c7, + 0x8b0: 0x0757, 0x8b1: 0x077b, 0x8b2: 0x078f, 0x8b3: 0x084b, 0x8b4: 0x0857, 0x8b5: 0x0897, + 0x8b6: 0x094b, 0x8b7: 0x0967, 0x8b8: 0x096f, 0x8b9: 0x09ab, 0x8ba: 0x09b7, 0x8bb: 0x0a93, + 0x8bc: 0x0a9b, 0x8bd: 0x0ba3, 0x8be: 0x0bcb, 0x8bf: 0x0bd3, + // Block 0x23, offset 0x8c0 + 0x8c0: 0x0beb, 0x8c1: 0x0c97, 0x8c2: 0x0cc7, 0x8c3: 0x0ce7, 0x8c4: 0x0d57, 0x8c5: 0x0e1b, + 0x8c6: 0x0e37, 0x8c7: 0x0e67, 0x8c8: 0x0ebb, 0x8c9: 0x0edb, 0x8ca: 0x0f4f, 0x8cb: 0x102f, + 0x8cc: 0x104b, 0x8cd: 0x1053, 0x8ce: 0x104f, 0x8cf: 0x1057, 0x8d0: 0x105b, 0x8d1: 0x105f, + 0x8d2: 0x1073, 0x8d3: 0x1077, 0x8d4: 0x109b, 0x8d5: 0x10af, 0x8d6: 0x10cb, 0x8d7: 0x112f, + 0x8d8: 0x1137, 0x8d9: 0x113f, 0x8da: 0x1153, 0x8db: 0x117b, 0x8dc: 0x11cb, 0x8dd: 0x11ff, + 0x8de: 0x11ff, 0x8df: 0x1267, 0x8e0: 0x130f, 0x8e1: 0x1327, 0x8e2: 0x135b, 0x8e3: 0x135f, + 0x8e4: 0x13a3, 0x8e5: 0x13a7, 0x8e6: 0x13ff, 0x8e7: 0x1407, 0x8e8: 0x14db, 0x8e9: 0x151f, + 0x8ea: 0x1537, 0x8eb: 0x0b9b, 0x8ec: 0x171e, 0x8ed: 0x11e3, + 0x8f0: 0x06df, 0x8f1: 0x07e3, 0x8f2: 0x07a3, 0x8f3: 0x074b, 0x8f4: 0x078b, 0x8f5: 0x07b7, + 0x8f6: 0x0847, 0x8f7: 0x0863, 0x8f8: 0x094b, 0x8f9: 0x0937, 0x8fa: 0x0947, 0x8fb: 0x0963, + 0x8fc: 0x09af, 0x8fd: 0x09bf, 0x8fe: 0x0a03, 0x8ff: 0x0a0f, + // Block 0x24, offset 0x900 + 0x900: 0x0a2b, 0x901: 0x0a3b, 0x902: 0x0b23, 0x903: 0x0b2b, 0x904: 0x0b5b, 0x905: 0x0b7b, + 0x906: 0x0bab, 0x907: 0x0bc3, 0x908: 0x0bb3, 0x909: 0x0bd3, 0x90a: 0x0bc7, 0x90b: 0x0beb, + 0x90c: 0x0c07, 0x90d: 0x0c5f, 0x90e: 0x0c6b, 0x90f: 0x0c73, 0x910: 0x0c9b, 0x911: 0x0cdf, + 0x912: 0x0d0f, 0x913: 0x0d13, 0x914: 0x0d27, 0x915: 0x0da7, 0x916: 0x0db7, 0x917: 0x0e0f, + 0x918: 0x0e5b, 0x919: 0x0e53, 0x91a: 0x0e67, 0x91b: 0x0e83, 0x91c: 0x0ebb, 0x91d: 0x1013, + 0x91e: 0x0edf, 0x91f: 0x0f13, 0x920: 0x0f1f, 0x921: 0x0f5f, 0x922: 0x0f7b, 0x923: 0x0f9f, + 0x924: 0x0fc3, 0x925: 0x0fc7, 0x926: 0x0fe3, 0x927: 0x0fe7, 0x928: 0x0ff7, 0x929: 0x100b, + 0x92a: 0x1007, 0x92b: 0x1037, 0x92c: 0x10b3, 0x92d: 0x10cb, 0x92e: 0x10e3, 0x92f: 0x111b, + 0x930: 0x112f, 0x931: 0x114b, 0x932: 0x117b, 0x933: 0x122f, 0x934: 0x1257, 0x935: 0x12cb, + 0x936: 0x1313, 0x937: 0x131f, 0x938: 0x1327, 0x939: 0x133f, 0x93a: 0x1353, 0x93b: 0x1343, + 0x93c: 0x135b, 0x93d: 0x1357, 0x93e: 0x134f, 0x93f: 0x135f, + // Block 0x25, offset 0x940 + 0x940: 0x136b, 0x941: 0x13a7, 0x942: 0x13e3, 0x943: 0x1413, 0x944: 0x144b, 0x945: 0x146b, + 0x946: 0x14b7, 0x947: 0x14db, 0x948: 0x14fb, 0x949: 0x150f, 0x94a: 0x151f, 0x94b: 0x152b, + 0x94c: 0x1537, 0x94d: 0x158b, 0x94e: 0x162b, 0x94f: 0x16b5, 0x950: 0x16b0, 0x951: 0x16e2, + 0x952: 0x0607, 0x953: 0x062f, 0x954: 0x0633, 0x955: 0x1764, 0x956: 0x1791, 0x957: 0x1809, + 0x958: 0x1617, 0x959: 0x1627, + // Block 0x26, offset 0x980 + 0x980: 0x06fb, 0x981: 0x06f3, 0x982: 0x0703, 0x983: 0x1647, 0x984: 0x0747, 0x985: 0x0757, + 0x986: 0x075b, 0x987: 0x0763, 0x988: 0x076b, 0x989: 0x076f, 0x98a: 0x077b, 0x98b: 0x0773, + 0x98c: 0x05b3, 0x98d: 0x165b, 0x98e: 0x078f, 0x98f: 0x0793, 0x990: 0x0797, 0x991: 0x07b3, + 0x992: 0x164c, 0x993: 0x05b7, 0x994: 0x079f, 0x995: 0x07bf, 0x996: 0x1656, 0x997: 0x07cf, + 0x998: 0x07d7, 0x999: 0x0737, 0x99a: 0x07df, 0x99b: 0x07e3, 0x99c: 0x1831, 0x99d: 0x07ff, + 0x99e: 0x0807, 0x99f: 0x05bf, 0x9a0: 0x081f, 0x9a1: 0x0823, 0x9a2: 0x082b, 0x9a3: 0x082f, + 0x9a4: 0x05c3, 0x9a5: 0x0847, 0x9a6: 0x084b, 0x9a7: 0x0857, 0x9a8: 0x0863, 0x9a9: 0x0867, + 0x9aa: 0x086b, 0x9ab: 0x0873, 0x9ac: 0x0893, 0x9ad: 0x0897, 0x9ae: 0x089f, 0x9af: 0x08af, + 0x9b0: 0x08b7, 0x9b1: 0x08bb, 0x9b2: 0x08bb, 0x9b3: 0x08bb, 0x9b4: 0x166a, 0x9b5: 0x0e93, + 0x9b6: 0x08cf, 0x9b7: 0x08d7, 0x9b8: 0x166f, 0x9b9: 0x08e3, 0x9ba: 0x08eb, 0x9bb: 0x08f3, + 0x9bc: 0x091b, 0x9bd: 0x0907, 0x9be: 0x0913, 0x9bf: 0x0917, + // Block 0x27, offset 0x9c0 + 0x9c0: 0x091f, 0x9c1: 0x0927, 0x9c2: 0x092b, 0x9c3: 0x0933, 0x9c4: 0x093b, 0x9c5: 0x093f, + 0x9c6: 0x093f, 0x9c7: 0x0947, 0x9c8: 0x094f, 0x9c9: 0x0953, 0x9ca: 0x095f, 0x9cb: 0x0983, + 0x9cc: 0x0967, 0x9cd: 0x0987, 0x9ce: 0x096b, 0x9cf: 0x0973, 0x9d0: 0x080b, 0x9d1: 0x09cf, + 0x9d2: 0x0997, 0x9d3: 0x099b, 0x9d4: 0x099f, 0x9d5: 0x0993, 0x9d6: 0x09a7, 0x9d7: 0x09a3, + 0x9d8: 0x09bb, 0x9d9: 0x1674, 0x9da: 0x09d7, 0x9db: 0x09db, 0x9dc: 0x09e3, 0x9dd: 0x09ef, + 0x9de: 0x09f7, 0x9df: 0x0a13, 0x9e0: 0x1679, 0x9e1: 0x167e, 0x9e2: 0x0a1f, 0x9e3: 0x0a23, + 0x9e4: 0x0a27, 0x9e5: 0x0a1b, 0x9e6: 0x0a2f, 0x9e7: 0x05c7, 0x9e8: 0x05cb, 0x9e9: 0x0a37, + 0x9ea: 0x0a3f, 0x9eb: 0x0a3f, 0x9ec: 0x1683, 0x9ed: 0x0a5b, 0x9ee: 0x0a5f, 0x9ef: 0x0a63, + 0x9f0: 0x0a6b, 0x9f1: 0x1688, 0x9f2: 0x0a73, 0x9f3: 0x0a77, 0x9f4: 0x0b4f, 0x9f5: 0x0a7f, + 0x9f6: 0x05cf, 0x9f7: 0x0a8b, 0x9f8: 0x0a9b, 0x9f9: 0x0aa7, 0x9fa: 0x0aa3, 0x9fb: 0x1692, + 0x9fc: 0x0aaf, 0x9fd: 0x1697, 0x9fe: 0x0abb, 0x9ff: 0x0ab7, + // Block 0x28, offset 0xa00 + 0xa00: 0x0abf, 0xa01: 0x0acf, 0xa02: 0x0ad3, 0xa03: 0x05d3, 0xa04: 0x0ae3, 0xa05: 0x0aeb, + 0xa06: 0x0aef, 0xa07: 0x0af3, 0xa08: 0x05d7, 0xa09: 0x169c, 0xa0a: 0x05db, 0xa0b: 0x0b0f, + 0xa0c: 0x0b13, 0xa0d: 0x0b17, 0xa0e: 0x0b1f, 0xa0f: 0x1863, 0xa10: 0x0b37, 0xa11: 0x16a6, + 0xa12: 0x16a6, 0xa13: 0x11d7, 0xa14: 0x0b47, 0xa15: 0x0b47, 0xa16: 0x05df, 0xa17: 0x16c9, + 0xa18: 0x179b, 0xa19: 0x0b57, 0xa1a: 0x0b5f, 0xa1b: 0x05e3, 0xa1c: 0x0b73, 0xa1d: 0x0b83, + 0xa1e: 0x0b87, 0xa1f: 0x0b8f, 0xa20: 0x0b9f, 0xa21: 0x05eb, 0xa22: 0x05e7, 0xa23: 0x0ba3, + 0xa24: 0x16ab, 0xa25: 0x0ba7, 0xa26: 0x0bbb, 0xa27: 0x0bbf, 0xa28: 0x0bc3, 0xa29: 0x0bbf, + 0xa2a: 0x0bcf, 0xa2b: 0x0bd3, 0xa2c: 0x0be3, 0xa2d: 0x0bdb, 0xa2e: 0x0bdf, 0xa2f: 0x0be7, + 0xa30: 0x0beb, 0xa31: 0x0bef, 0xa32: 0x0bfb, 0xa33: 0x0bff, 0xa34: 0x0c17, 0xa35: 0x0c1f, + 0xa36: 0x0c2f, 0xa37: 0x0c43, 0xa38: 0x16ba, 0xa39: 0x0c3f, 0xa3a: 0x0c33, 0xa3b: 0x0c4b, + 0xa3c: 0x0c53, 0xa3d: 0x0c67, 0xa3e: 0x16bf, 0xa3f: 0x0c6f, + // Block 0x29, offset 0xa40 + 0xa40: 0x0c63, 0xa41: 0x0c5b, 0xa42: 0x05ef, 0xa43: 0x0c77, 0xa44: 0x0c7f, 0xa45: 0x0c87, + 0xa46: 0x0c7b, 0xa47: 0x05f3, 0xa48: 0x0c97, 0xa49: 0x0c9f, 0xa4a: 0x16c4, 0xa4b: 0x0ccb, + 0xa4c: 0x0cff, 0xa4d: 0x0cdb, 0xa4e: 0x05ff, 0xa4f: 0x0ce7, 0xa50: 0x05fb, 0xa51: 0x05f7, + 0xa52: 0x07c3, 0xa53: 0x07c7, 0xa54: 0x0d03, 0xa55: 0x0ceb, 0xa56: 0x11ab, 0xa57: 0x0663, + 0xa58: 0x0d0f, 0xa59: 0x0d13, 0xa5a: 0x0d17, 0xa5b: 0x0d2b, 0xa5c: 0x0d23, 0xa5d: 0x16dd, + 0xa5e: 0x0603, 0xa5f: 0x0d3f, 0xa60: 0x0d33, 0xa61: 0x0d4f, 0xa62: 0x0d57, 0xa63: 0x16e7, + 0xa64: 0x0d5b, 0xa65: 0x0d47, 0xa66: 0x0d63, 0xa67: 0x0607, 0xa68: 0x0d67, 0xa69: 0x0d6b, + 0xa6a: 0x0d6f, 0xa6b: 0x0d7b, 0xa6c: 0x16ec, 0xa6d: 0x0d83, 0xa6e: 0x060b, 0xa6f: 0x0d8f, + 0xa70: 0x16f1, 0xa71: 0x0d93, 0xa72: 0x060f, 0xa73: 0x0d9f, 0xa74: 0x0dab, 0xa75: 0x0db7, + 0xa76: 0x0dbb, 0xa77: 0x16f6, 0xa78: 0x168d, 0xa79: 0x16fb, 0xa7a: 0x0ddb, 0xa7b: 0x1700, + 0xa7c: 0x0de7, 0xa7d: 0x0def, 0xa7e: 0x0ddf, 0xa7f: 0x0dfb, + // Block 0x2a, offset 0xa80 + 0xa80: 0x0e0b, 0xa81: 0x0e1b, 0xa82: 0x0e0f, 0xa83: 0x0e13, 0xa84: 0x0e1f, 0xa85: 0x0e23, + 0xa86: 0x1705, 0xa87: 0x0e07, 0xa88: 0x0e3b, 0xa89: 0x0e3f, 0xa8a: 0x0613, 0xa8b: 0x0e53, + 0xa8c: 0x0e4f, 0xa8d: 0x170a, 0xa8e: 0x0e33, 0xa8f: 0x0e6f, 0xa90: 0x170f, 0xa91: 0x1714, + 0xa92: 0x0e73, 0xa93: 0x0e87, 0xa94: 0x0e83, 0xa95: 0x0e7f, 0xa96: 0x0617, 0xa97: 0x0e8b, + 0xa98: 0x0e9b, 0xa99: 0x0e97, 0xa9a: 0x0ea3, 0xa9b: 0x1651, 0xa9c: 0x0eb3, 0xa9d: 0x1719, + 0xa9e: 0x0ebf, 0xa9f: 0x1723, 0xaa0: 0x0ed3, 0xaa1: 0x0edf, 0xaa2: 0x0ef3, 0xaa3: 0x1728, + 0xaa4: 0x0f07, 0xaa5: 0x0f0b, 0xaa6: 0x172d, 0xaa7: 0x1732, 0xaa8: 0x0f27, 0xaa9: 0x0f37, + 0xaaa: 0x061b, 0xaab: 0x0f3b, 0xaac: 0x061f, 0xaad: 0x061f, 0xaae: 0x0f53, 0xaaf: 0x0f57, + 0xab0: 0x0f5f, 0xab1: 0x0f63, 0xab2: 0x0f6f, 0xab3: 0x0623, 0xab4: 0x0f87, 0xab5: 0x1737, + 0xab6: 0x0fa3, 0xab7: 0x173c, 0xab8: 0x0faf, 0xab9: 0x16a1, 0xaba: 0x0fbf, 0xabb: 0x1741, + 0xabc: 0x1746, 0xabd: 0x174b, 0xabe: 0x0627, 0xabf: 0x062b, + // Block 0x2b, offset 0xac0 + 0xac0: 0x0ff7, 0xac1: 0x1755, 0xac2: 0x1750, 0xac3: 0x175a, 0xac4: 0x175f, 0xac5: 0x0fff, + 0xac6: 0x1003, 0xac7: 0x1003, 0xac8: 0x100b, 0xac9: 0x0633, 0xaca: 0x100f, 0xacb: 0x0637, + 0xacc: 0x063b, 0xacd: 0x1769, 0xace: 0x1023, 0xacf: 0x102b, 0xad0: 0x1037, 0xad1: 0x063f, + 0xad2: 0x176e, 0xad3: 0x105b, 0xad4: 0x1773, 0xad5: 0x1778, 0xad6: 0x107b, 0xad7: 0x1093, + 0xad8: 0x0643, 0xad9: 0x109b, 0xada: 0x109f, 0xadb: 0x10a3, 0xadc: 0x177d, 0xadd: 0x1782, + 0xade: 0x1782, 0xadf: 0x10bb, 0xae0: 0x0647, 0xae1: 0x1787, 0xae2: 0x10cf, 0xae3: 0x10d3, + 0xae4: 0x064b, 0xae5: 0x178c, 0xae6: 0x10ef, 0xae7: 0x064f, 0xae8: 0x10ff, 0xae9: 0x10f7, + 0xaea: 0x1107, 0xaeb: 0x1796, 0xaec: 0x111f, 0xaed: 0x0653, 0xaee: 0x112b, 0xaef: 0x1133, + 0xaf0: 0x1143, 0xaf1: 0x0657, 0xaf2: 0x17a0, 0xaf3: 0x17a5, 0xaf4: 0x065b, 0xaf5: 0x17aa, + 0xaf6: 0x115b, 0xaf7: 0x17af, 0xaf8: 0x1167, 0xaf9: 0x1173, 0xafa: 0x117b, 0xafb: 0x17b4, + 0xafc: 0x17b9, 0xafd: 0x118f, 0xafe: 0x17be, 0xaff: 0x1197, + // Block 0x2c, offset 0xb00 + 0xb00: 0x16ce, 0xb01: 0x065f, 0xb02: 0x11af, 0xb03: 0x11b3, 0xb04: 0x0667, 0xb05: 0x11b7, + 0xb06: 0x0a33, 0xb07: 0x17c3, 0xb08: 0x17c8, 0xb09: 0x16d3, 0xb0a: 0x16d8, 0xb0b: 0x11d7, + 0xb0c: 0x11db, 0xb0d: 0x13f3, 0xb0e: 0x066b, 0xb0f: 0x1207, 0xb10: 0x1203, 0xb11: 0x120b, + 0xb12: 0x083f, 0xb13: 0x120f, 0xb14: 0x1213, 0xb15: 0x1217, 0xb16: 0x121f, 0xb17: 0x17cd, + 0xb18: 0x121b, 0xb19: 0x1223, 0xb1a: 0x1237, 0xb1b: 0x123b, 0xb1c: 0x1227, 0xb1d: 0x123f, + 0xb1e: 0x1253, 0xb1f: 0x1267, 0xb20: 0x1233, 0xb21: 0x1247, 0xb22: 0x124b, 0xb23: 0x124f, + 0xb24: 0x17d2, 0xb25: 0x17dc, 0xb26: 0x17d7, 0xb27: 0x066f, 0xb28: 0x126f, 0xb29: 0x1273, + 0xb2a: 0x127b, 0xb2b: 0x17f0, 0xb2c: 0x127f, 0xb2d: 0x17e1, 0xb2e: 0x0673, 0xb2f: 0x0677, + 0xb30: 0x17e6, 0xb31: 0x17eb, 0xb32: 0x067b, 0xb33: 0x129f, 0xb34: 0x12a3, 0xb35: 0x12a7, + 0xb36: 0x12ab, 0xb37: 0x12b7, 0xb38: 0x12b3, 0xb39: 0x12bf, 0xb3a: 0x12bb, 0xb3b: 0x12cb, + 0xb3c: 0x12c3, 0xb3d: 0x12c7, 0xb3e: 0x12cf, 0xb3f: 0x067f, + // Block 0x2d, offset 0xb40 + 0xb40: 0x12d7, 0xb41: 0x12db, 0xb42: 0x0683, 0xb43: 0x12eb, 0xb44: 0x12ef, 0xb45: 0x17f5, + 0xb46: 0x12fb, 0xb47: 0x12ff, 0xb48: 0x0687, 0xb49: 0x130b, 0xb4a: 0x05bb, 0xb4b: 0x17fa, + 0xb4c: 0x17ff, 0xb4d: 0x068b, 0xb4e: 0x068f, 0xb4f: 0x1337, 0xb50: 0x134f, 0xb51: 0x136b, + 0xb52: 0x137b, 0xb53: 0x1804, 0xb54: 0x138f, 0xb55: 0x1393, 0xb56: 0x13ab, 0xb57: 0x13b7, + 0xb58: 0x180e, 0xb59: 0x1660, 0xb5a: 0x13c3, 0xb5b: 0x13bf, 0xb5c: 0x13cb, 0xb5d: 0x1665, + 0xb5e: 0x13d7, 0xb5f: 0x13e3, 0xb60: 0x1813, 0xb61: 0x1818, 0xb62: 0x1423, 0xb63: 0x142f, + 0xb64: 0x1437, 0xb65: 0x181d, 0xb66: 0x143b, 0xb67: 0x1467, 0xb68: 0x1473, 0xb69: 0x1477, + 0xb6a: 0x146f, 0xb6b: 0x1483, 0xb6c: 0x1487, 0xb6d: 0x1822, 0xb6e: 0x1493, 0xb6f: 0x0693, + 0xb70: 0x149b, 0xb71: 0x1827, 0xb72: 0x0697, 0xb73: 0x14d3, 0xb74: 0x0ac3, 0xb75: 0x14eb, + 0xb76: 0x182c, 0xb77: 0x1836, 0xb78: 0x069b, 0xb79: 0x069f, 0xb7a: 0x1513, 0xb7b: 0x183b, + 0xb7c: 0x06a3, 0xb7d: 0x1840, 0xb7e: 0x152b, 0xb7f: 0x152b, + // Block 0x2e, offset 0xb80 + 0xb80: 0x1533, 0xb81: 0x1845, 0xb82: 0x154b, 0xb83: 0x06a7, 0xb84: 0x155b, 0xb85: 0x1567, + 0xb86: 0x156f, 0xb87: 0x1577, 0xb88: 0x06ab, 0xb89: 0x184a, 0xb8a: 0x158b, 0xb8b: 0x15a7, + 0xb8c: 0x15b3, 0xb8d: 0x06af, 0xb8e: 0x06b3, 0xb8f: 0x15b7, 0xb90: 0x184f, 0xb91: 0x06b7, + 0xb92: 0x1854, 0xb93: 0x1859, 0xb94: 0x185e, 0xb95: 0x15db, 0xb96: 0x06bb, 0xb97: 0x15ef, + 0xb98: 0x15f7, 0xb99: 0x15fb, 0xb9a: 0x1603, 0xb9b: 0x160b, 0xb9c: 0x1613, 0xb9d: 0x1868, +} + +// nfcIndex: 22 blocks, 1408 entries, 1408 bytes +// Block 0 is the zero block. +var nfcIndex = [1408]uint8{ + // Block 0x0, offset 0x0 + // Block 0x1, offset 0x40 + // Block 0x2, offset 0x80 + // Block 0x3, offset 0xc0 + 0xc2: 0x2d, 0xc3: 0x01, 0xc4: 0x02, 0xc5: 0x03, 0xc6: 0x2e, 0xc7: 0x04, + 0xc8: 0x05, 0xca: 0x2f, 0xcb: 0x30, 0xcc: 0x06, 0xcd: 0x07, 0xce: 0x08, 0xcf: 0x31, + 0xd0: 0x09, 0xd1: 0x32, 0xd2: 0x33, 0xd3: 0x0a, 0xd6: 0x0b, 0xd7: 0x34, + 0xd8: 0x35, 0xd9: 0x0c, 0xdb: 0x36, 0xdc: 0x37, 0xdd: 0x38, 0xdf: 0x39, + 0xe0: 0x02, 0xe1: 0x03, 0xe2: 0x04, 0xe3: 0x05, + 0xea: 0x06, 0xeb: 0x07, 0xec: 0x08, 0xed: 0x09, 0xef: 0x0a, + 0xf0: 0x13, + // Block 0x4, offset 0x100 + 0x120: 0x3a, 0x121: 0x3b, 0x123: 0x3c, 0x124: 0x3d, 0x125: 0x3e, 0x126: 0x3f, 0x127: 0x40, + 0x128: 0x41, 0x129: 0x42, 0x12a: 0x43, 0x12b: 0x44, 0x12c: 0x3f, 0x12d: 0x45, 0x12e: 0x46, 0x12f: 0x47, + 0x131: 0x48, 0x132: 0x49, 0x133: 0x4a, 0x134: 0x4b, 0x135: 0x4c, 0x137: 0x4d, + 0x138: 0x4e, 0x139: 0x4f, 0x13a: 0x50, 0x13b: 0x51, 0x13c: 0x52, 0x13d: 0x53, 0x13e: 0x54, 0x13f: 0x55, + // Block 0x5, offset 0x140 + 0x140: 0x56, 0x142: 0x57, 0x144: 0x58, 0x145: 0x59, 0x146: 0x5a, 0x147: 0x5b, + 0x14d: 0x5c, + 0x15c: 0x5d, 0x15f: 0x5e, + 0x162: 0x5f, 0x164: 0x60, + 0x168: 0x61, 0x169: 0x62, 0x16a: 0x63, 0x16c: 0x0d, 0x16d: 0x64, 0x16e: 0x65, 0x16f: 0x66, + 0x170: 0x67, 0x173: 0x68, 0x177: 0x0e, + 0x178: 0x0f, 0x179: 0x10, 0x17a: 0x11, 0x17b: 0x12, 0x17c: 0x13, 0x17d: 0x14, 0x17e: 0x15, 0x17f: 0x16, + // Block 0x6, offset 0x180 + 0x180: 0x69, 0x183: 0x6a, 0x184: 0x6b, 0x186: 0x6c, 0x187: 0x6d, + 0x188: 0x6e, 0x189: 0x17, 0x18a: 0x18, 0x18b: 0x6f, 0x18c: 0x70, + 0x1ab: 0x71, + 0x1b3: 0x72, 0x1b5: 0x73, 0x1b7: 0x74, + // Block 0x7, offset 0x1c0 + 0x1c0: 0x75, 0x1c1: 0x19, 0x1c2: 0x1a, 0x1c3: 0x1b, 0x1c4: 0x76, 0x1c5: 0x77, + 0x1c9: 0x78, 0x1cc: 0x79, 0x1cd: 0x7a, + // Block 0x8, offset 0x200 + 0x219: 0x7b, 0x21a: 0x7c, 0x21b: 0x7d, + 0x220: 0x7e, 0x223: 0x7f, 0x224: 0x80, 0x225: 0x81, 0x226: 0x82, 0x227: 0x83, + 0x22a: 0x84, 0x22b: 0x85, 0x22f: 0x86, + 0x230: 0x87, 0x231: 0x88, 0x232: 0x89, 0x233: 0x8a, 0x234: 0x8b, 0x235: 0x8c, 0x236: 0x8d, 0x237: 0x87, + 0x238: 0x88, 0x239: 0x89, 0x23a: 0x8a, 0x23b: 0x8b, 0x23c: 0x8c, 0x23d: 0x8d, 0x23e: 0x87, 0x23f: 0x88, + // Block 0x9, offset 0x240 + 0x240: 0x89, 0x241: 0x8a, 0x242: 0x8b, 0x243: 0x8c, 0x244: 0x8d, 0x245: 0x87, 0x246: 0x88, 0x247: 0x89, + 0x248: 0x8a, 0x249: 0x8b, 0x24a: 0x8c, 0x24b: 0x8d, 0x24c: 0x87, 0x24d: 0x88, 0x24e: 0x89, 0x24f: 0x8a, + 0x250: 0x8b, 0x251: 0x8c, 0x252: 0x8d, 0x253: 0x87, 0x254: 0x88, 0x255: 0x89, 0x256: 0x8a, 0x257: 0x8b, + 0x258: 0x8c, 0x259: 0x8d, 0x25a: 0x87, 0x25b: 0x88, 0x25c: 0x89, 0x25d: 0x8a, 0x25e: 0x8b, 0x25f: 0x8c, + 0x260: 0x8d, 0x261: 0x87, 0x262: 0x88, 0x263: 0x89, 0x264: 0x8a, 0x265: 0x8b, 0x266: 0x8c, 0x267: 0x8d, + 0x268: 0x87, 0x269: 0x88, 0x26a: 0x89, 0x26b: 0x8a, 0x26c: 0x8b, 0x26d: 0x8c, 0x26e: 0x8d, 0x26f: 0x87, + 0x270: 0x88, 0x271: 0x89, 0x272: 0x8a, 0x273: 0x8b, 0x274: 0x8c, 0x275: 0x8d, 0x276: 0x87, 0x277: 0x88, + 0x278: 0x89, 0x279: 0x8a, 0x27a: 0x8b, 0x27b: 0x8c, 0x27c: 0x8d, 0x27d: 0x87, 0x27e: 0x88, 0x27f: 0x89, + // Block 0xa, offset 0x280 + 0x280: 0x8a, 0x281: 0x8b, 0x282: 0x8c, 0x283: 0x8d, 0x284: 0x87, 0x285: 0x88, 0x286: 0x89, 0x287: 0x8a, + 0x288: 0x8b, 0x289: 0x8c, 0x28a: 0x8d, 0x28b: 0x87, 0x28c: 0x88, 0x28d: 0x89, 0x28e: 0x8a, 0x28f: 0x8b, + 0x290: 0x8c, 0x291: 0x8d, 0x292: 0x87, 0x293: 0x88, 0x294: 0x89, 0x295: 0x8a, 0x296: 0x8b, 0x297: 0x8c, + 0x298: 0x8d, 0x299: 0x87, 0x29a: 0x88, 0x29b: 0x89, 0x29c: 0x8a, 0x29d: 0x8b, 0x29e: 0x8c, 0x29f: 0x8d, + 0x2a0: 0x87, 0x2a1: 0x88, 0x2a2: 0x89, 0x2a3: 0x8a, 0x2a4: 0x8b, 0x2a5: 0x8c, 0x2a6: 0x8d, 0x2a7: 0x87, + 0x2a8: 0x88, 0x2a9: 0x89, 0x2aa: 0x8a, 0x2ab: 0x8b, 0x2ac: 0x8c, 0x2ad: 0x8d, 0x2ae: 0x87, 0x2af: 0x88, + 0x2b0: 0x89, 0x2b1: 0x8a, 0x2b2: 0x8b, 0x2b3: 0x8c, 0x2b4: 0x8d, 0x2b5: 0x87, 0x2b6: 0x88, 0x2b7: 0x89, + 0x2b8: 0x8a, 0x2b9: 0x8b, 0x2ba: 0x8c, 0x2bb: 0x8d, 0x2bc: 0x87, 0x2bd: 0x88, 0x2be: 0x89, 0x2bf: 0x8a, + // Block 0xb, offset 0x2c0 + 0x2c0: 0x8b, 0x2c1: 0x8c, 0x2c2: 0x8d, 0x2c3: 0x87, 0x2c4: 0x88, 0x2c5: 0x89, 0x2c6: 0x8a, 0x2c7: 0x8b, + 0x2c8: 0x8c, 0x2c9: 0x8d, 0x2ca: 0x87, 0x2cb: 0x88, 0x2cc: 0x89, 0x2cd: 0x8a, 0x2ce: 0x8b, 0x2cf: 0x8c, + 0x2d0: 0x8d, 0x2d1: 0x87, 0x2d2: 0x88, 0x2d3: 0x89, 0x2d4: 0x8a, 0x2d5: 0x8b, 0x2d6: 0x8c, 0x2d7: 0x8d, + 0x2d8: 0x87, 0x2d9: 0x88, 0x2da: 0x89, 0x2db: 0x8a, 0x2dc: 0x8b, 0x2dd: 0x8c, 0x2de: 0x8e, + // Block 0xc, offset 0x300 + 0x324: 0x1c, 0x325: 0x1d, 0x326: 0x1e, 0x327: 0x1f, + 0x328: 0x20, 0x329: 0x21, 0x32a: 0x22, 0x32b: 0x23, 0x32c: 0x8f, 0x32d: 0x90, 0x32e: 0x91, + 0x331: 0x92, 0x332: 0x93, 0x333: 0x94, 0x334: 0x95, + 0x338: 0x96, 0x339: 0x97, 0x33a: 0x98, 0x33b: 0x99, 0x33e: 0x9a, 0x33f: 0x9b, + // Block 0xd, offset 0x340 + 0x347: 0x9c, + 0x34b: 0x9d, 0x34d: 0x9e, + 0x368: 0x9f, 0x36b: 0xa0, + // Block 0xe, offset 0x380 + 0x381: 0xa1, 0x382: 0xa2, 0x384: 0xa3, 0x385: 0x82, 0x387: 0xa4, + 0x388: 0xa5, 0x38b: 0xa6, 0x38c: 0x3f, 0x38d: 0xa7, + 0x391: 0xa8, 0x392: 0xa9, 0x393: 0xaa, 0x396: 0xab, 0x397: 0xac, + 0x398: 0x73, 0x39a: 0xad, 0x39c: 0xae, + 0x3a8: 0xaf, 0x3a9: 0xb0, 0x3aa: 0xb1, + 0x3b0: 0x73, 0x3b5: 0xb2, + // Block 0xf, offset 0x3c0 + 0x3eb: 0xb3, 0x3ec: 0xb4, + // Block 0x10, offset 0x400 + 0x432: 0xb5, + // Block 0x11, offset 0x440 + 0x445: 0xb6, 0x446: 0xb7, 0x447: 0xb8, + 0x449: 0xb9, + // Block 0x12, offset 0x480 + 0x480: 0xba, + 0x4a3: 0xbb, 0x4a5: 0xbc, + // Block 0x13, offset 0x4c0 + 0x4c8: 0xbd, + // Block 0x14, offset 0x500 + 0x520: 0x24, 0x521: 0x25, 0x522: 0x26, 0x523: 0x27, 0x524: 0x28, 0x525: 0x29, 0x526: 0x2a, 0x527: 0x2b, + 0x528: 0x2c, + // Block 0x15, offset 0x540 + 0x550: 0x0b, 0x551: 0x0c, 0x556: 0x0d, + 0x55b: 0x0e, 0x55d: 0x0f, 0x55e: 0x10, 0x55f: 0x11, + 0x56f: 0x12, +} + +// nfcSparseOffset: 145 entries, 290 bytes +var nfcSparseOffset = []uint16{0x0, 0x5, 0x9, 0xb, 0xd, 0x18, 0x28, 0x2a, 0x2f, 0x3a, 0x49, 0x56, 0x5e, 0x62, 0x67, 0x69, 0x7a, 0x82, 0x89, 0x8c, 0x93, 0x97, 0x9b, 0x9d, 0x9f, 0xa8, 0xac, 0xb3, 0xb8, 0xbb, 0xc5, 0xc8, 0xcf, 0xd7, 0xda, 0xdc, 0xde, 0xe0, 0xe5, 0xf6, 0x102, 0x104, 0x10a, 0x10c, 0x10e, 0x110, 0x112, 0x114, 0x116, 0x119, 0x11c, 0x11e, 0x121, 0x124, 0x128, 0x12d, 0x136, 0x138, 0x13b, 0x13d, 0x148, 0x14c, 0x15a, 0x15d, 0x163, 0x169, 0x174, 0x178, 0x17a, 0x17c, 0x17e, 0x180, 0x182, 0x188, 0x18c, 0x18e, 0x190, 0x198, 0x19c, 0x19f, 0x1a1, 0x1a3, 0x1a5, 0x1a8, 0x1aa, 0x1ac, 0x1ae, 0x1b0, 0x1b6, 0x1b9, 0x1bb, 0x1c2, 0x1c8, 0x1ce, 0x1d6, 0x1dc, 0x1e2, 0x1e8, 0x1ec, 0x1fa, 0x203, 0x206, 0x209, 0x20b, 0x20e, 0x210, 0x214, 0x219, 0x21b, 0x21d, 0x222, 0x228, 0x22a, 0x22c, 0x22e, 0x234, 0x237, 0x23a, 0x242, 0x249, 0x24c, 0x24f, 0x251, 0x259, 0x25c, 0x263, 0x266, 0x26c, 0x26e, 0x271, 0x273, 0x275, 0x277, 0x279, 0x27c, 0x27e, 0x280, 0x282, 0x28f, 0x299, 0x29b, 0x29d, 0x2a3, 0x2a5, 0x2a8} + +// nfcSparseValues: 682 entries, 2728 bytes +var nfcSparseValues = [682]valueRange{ + // Block 0x0, offset 0x0 + {value: 0x0000, lo: 0x04}, + {value: 0xa100, lo: 0xa8, hi: 0xa8}, + {value: 0x8100, lo: 0xaf, hi: 0xaf}, + {value: 0x8100, lo: 0xb4, hi: 0xb4}, + {value: 0x8100, lo: 0xb8, hi: 0xb8}, + // Block 0x1, offset 0x5 + {value: 0x0091, lo: 0x03}, + {value: 0x46e2, lo: 0xa0, hi: 0xa1}, + {value: 0x4714, lo: 0xaf, hi: 0xb0}, + {value: 0xa000, lo: 0xb7, hi: 0xb7}, + // Block 0x2, offset 0x9 + {value: 0x0000, lo: 0x01}, + {value: 0xa000, lo: 0x92, hi: 0x92}, + // Block 0x3, offset 0xb + {value: 0x0000, lo: 0x01}, + {value: 0x8100, lo: 0x98, hi: 0x9d}, + // Block 0x4, offset 0xd + {value: 0x0006, lo: 0x0a}, + {value: 0xa000, lo: 0x81, hi: 0x81}, + {value: 0xa000, lo: 0x85, hi: 0x85}, + {value: 0xa000, lo: 0x89, hi: 0x89}, + {value: 0x4840, lo: 0x8a, hi: 0x8a}, + {value: 0x485e, lo: 0x8b, hi: 0x8b}, + {value: 0x36c7, lo: 0x8c, hi: 0x8c}, + {value: 0x36df, lo: 0x8d, hi: 0x8d}, + {value: 0x4876, lo: 0x8e, hi: 0x8e}, + {value: 0xa000, lo: 0x92, hi: 0x92}, + {value: 0x36fd, lo: 0x93, hi: 0x94}, + // Block 0x5, offset 0x18 + {value: 0x0000, lo: 0x0f}, + {value: 0xa000, lo: 0x83, hi: 0x83}, + {value: 0xa000, lo: 0x87, hi: 0x87}, + {value: 0xa000, lo: 0x8b, hi: 0x8b}, + {value: 0xa000, lo: 0x8d, hi: 0x8d}, + {value: 0x37a5, lo: 0x90, hi: 0x90}, + {value: 0x37b1, lo: 0x91, hi: 0x91}, + {value: 0x379f, lo: 0x93, hi: 0x93}, + {value: 0xa000, lo: 0x96, hi: 0x96}, + {value: 0x3817, lo: 0x97, hi: 0x97}, + {value: 0x37e1, lo: 0x9c, hi: 0x9c}, + {value: 0x37c9, lo: 0x9d, hi: 0x9d}, + {value: 0x37f3, lo: 0x9e, hi: 0x9e}, + {value: 0xa000, lo: 0xb4, hi: 0xb5}, + {value: 0x381d, lo: 0xb6, hi: 0xb6}, + {value: 0x3823, lo: 0xb7, hi: 0xb7}, + // Block 0x6, offset 0x28 + {value: 0x0000, lo: 0x01}, + {value: 0x8132, lo: 0x83, hi: 0x87}, + // Block 0x7, offset 0x2a + {value: 0x0001, lo: 0x04}, + {value: 0x8113, lo: 0x81, hi: 0x82}, + {value: 0x8132, lo: 0x84, hi: 0x84}, + {value: 0x812d, lo: 0x85, hi: 0x85}, + {value: 0x810d, lo: 0x87, hi: 0x87}, + // Block 0x8, offset 0x2f + {value: 0x0000, lo: 0x0a}, + {value: 0x8132, lo: 0x90, hi: 0x97}, + {value: 0x8119, lo: 0x98, hi: 0x98}, + {value: 0x811a, lo: 0x99, hi: 0x99}, + {value: 0x811b, lo: 0x9a, hi: 0x9a}, + {value: 0x3841, lo: 0xa2, hi: 0xa2}, + {value: 0x3847, lo: 0xa3, hi: 0xa3}, + {value: 0x3853, lo: 0xa4, hi: 0xa4}, + {value: 0x384d, lo: 0xa5, hi: 0xa5}, + {value: 0x3859, lo: 0xa6, hi: 0xa6}, + {value: 0xa000, lo: 0xa7, hi: 0xa7}, + // Block 0x9, offset 0x3a + {value: 0x0000, lo: 0x0e}, + {value: 0x386b, lo: 0x80, hi: 0x80}, + {value: 0xa000, lo: 0x81, hi: 0x81}, + {value: 0x385f, lo: 0x82, hi: 0x82}, + {value: 0xa000, lo: 0x92, hi: 0x92}, + {value: 0x3865, lo: 0x93, hi: 0x93}, + {value: 0xa000, lo: 0x95, hi: 0x95}, + {value: 0x8132, lo: 0x96, hi: 0x9c}, + {value: 0x8132, lo: 0x9f, hi: 0xa2}, + {value: 0x812d, lo: 0xa3, hi: 0xa3}, + {value: 0x8132, lo: 0xa4, hi: 0xa4}, + {value: 0x8132, lo: 0xa7, hi: 0xa8}, + {value: 0x812d, lo: 0xaa, hi: 0xaa}, + {value: 0x8132, lo: 0xab, hi: 0xac}, + {value: 0x812d, lo: 0xad, hi: 0xad}, + // Block 0xa, offset 0x49 + {value: 0x0000, lo: 0x0c}, + {value: 0x811f, lo: 0x91, hi: 0x91}, + {value: 0x8132, lo: 0xb0, hi: 0xb0}, + {value: 0x812d, lo: 0xb1, hi: 0xb1}, + {value: 0x8132, lo: 0xb2, hi: 0xb3}, + {value: 0x812d, lo: 0xb4, hi: 0xb4}, + {value: 0x8132, lo: 0xb5, hi: 0xb6}, + {value: 0x812d, lo: 0xb7, hi: 0xb9}, + {value: 0x8132, lo: 0xba, hi: 0xba}, + {value: 0x812d, lo: 0xbb, hi: 0xbc}, + {value: 0x8132, lo: 0xbd, hi: 0xbd}, + {value: 0x812d, lo: 0xbe, hi: 0xbe}, + {value: 0x8132, lo: 0xbf, hi: 0xbf}, + // Block 0xb, offset 0x56 + {value: 0x0005, lo: 0x07}, + {value: 0x8132, lo: 0x80, hi: 0x80}, + {value: 0x8132, lo: 0x81, hi: 0x81}, + {value: 0x812d, lo: 0x82, hi: 0x83}, + {value: 0x812d, lo: 0x84, hi: 0x85}, + {value: 0x812d, lo: 0x86, hi: 0x87}, + {value: 0x812d, lo: 0x88, hi: 0x89}, + {value: 0x8132, lo: 0x8a, hi: 0x8a}, + // Block 0xc, offset 0x5e + {value: 0x0000, lo: 0x03}, + {value: 0x8132, lo: 0xab, hi: 0xb1}, + {value: 0x812d, lo: 0xb2, hi: 0xb2}, + {value: 0x8132, lo: 0xb3, hi: 0xb3}, + // Block 0xd, offset 0x62 + {value: 0x0000, lo: 0x04}, + {value: 0x8132, lo: 0x96, hi: 0x99}, + {value: 0x8132, lo: 0x9b, hi: 0xa3}, + {value: 0x8132, lo: 0xa5, hi: 0xa7}, + {value: 0x8132, lo: 0xa9, hi: 0xad}, + // Block 0xe, offset 0x67 + {value: 0x0000, lo: 0x01}, + {value: 0x812d, lo: 0x99, hi: 0x9b}, + // Block 0xf, offset 0x69 + {value: 0x0000, lo: 0x10}, + {value: 0x8132, lo: 0x94, hi: 0xa1}, + {value: 0x812d, lo: 0xa3, hi: 0xa3}, + {value: 0x8132, lo: 0xa4, hi: 0xa5}, + {value: 0x812d, lo: 0xa6, hi: 0xa6}, + {value: 0x8132, lo: 0xa7, hi: 0xa8}, + {value: 0x812d, lo: 0xa9, hi: 0xa9}, + {value: 0x8132, lo: 0xaa, hi: 0xac}, + {value: 0x812d, lo: 0xad, hi: 0xaf}, + {value: 0x8116, lo: 0xb0, hi: 0xb0}, + {value: 0x8117, lo: 0xb1, hi: 0xb1}, + {value: 0x8118, lo: 0xb2, hi: 0xb2}, + {value: 0x8132, lo: 0xb3, hi: 0xb5}, + {value: 0x812d, lo: 0xb6, hi: 0xb6}, + {value: 0x8132, lo: 0xb7, hi: 0xb8}, + {value: 0x812d, lo: 0xb9, hi: 0xba}, + {value: 0x8132, lo: 0xbb, hi: 0xbf}, + // Block 0x10, offset 0x7a + {value: 0x0000, lo: 0x07}, + {value: 0xa000, lo: 0xa8, hi: 0xa8}, + {value: 0x3ed8, lo: 0xa9, hi: 0xa9}, + {value: 0xa000, lo: 0xb0, hi: 0xb0}, + {value: 0x3ee0, lo: 0xb1, hi: 0xb1}, + {value: 0xa000, lo: 0xb3, hi: 0xb3}, + {value: 0x3ee8, lo: 0xb4, hi: 0xb4}, + {value: 0x9902, lo: 0xbc, hi: 0xbc}, + // Block 0x11, offset 0x82 + {value: 0x0008, lo: 0x06}, + {value: 0x8104, lo: 0x8d, hi: 0x8d}, + {value: 0x8132, lo: 0x91, hi: 0x91}, + {value: 0x812d, lo: 0x92, hi: 0x92}, + {value: 0x8132, lo: 0x93, hi: 0x93}, + {value: 0x8132, lo: 0x94, hi: 0x94}, + {value: 0x451c, lo: 0x98, hi: 0x9f}, + // Block 0x12, offset 0x89 + {value: 0x0000, lo: 0x02}, + {value: 0x8102, lo: 0xbc, hi: 0xbc}, + {value: 0x9900, lo: 0xbe, hi: 0xbe}, + // Block 0x13, offset 0x8c + {value: 0x0008, lo: 0x06}, + {value: 0xa000, lo: 0x87, hi: 0x87}, + {value: 0x2c9e, lo: 0x8b, hi: 0x8c}, + {value: 0x8104, lo: 0x8d, hi: 0x8d}, + {value: 0x9900, lo: 0x97, hi: 0x97}, + {value: 0x455c, lo: 0x9c, hi: 0x9d}, + {value: 0x456c, lo: 0x9f, hi: 0x9f}, + // Block 0x14, offset 0x93 + {value: 0x0000, lo: 0x03}, + {value: 0x4594, lo: 0xb3, hi: 0xb3}, + {value: 0x459c, lo: 0xb6, hi: 0xb6}, + {value: 0x8102, lo: 0xbc, hi: 0xbc}, + // Block 0x15, offset 0x97 + {value: 0x0008, lo: 0x03}, + {value: 0x8104, lo: 0x8d, hi: 0x8d}, + {value: 0x4574, lo: 0x99, hi: 0x9b}, + {value: 0x458c, lo: 0x9e, hi: 0x9e}, + // Block 0x16, offset 0x9b + {value: 0x0000, lo: 0x01}, + {value: 0x8102, lo: 0xbc, hi: 0xbc}, + // Block 0x17, offset 0x9d + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0x8d, hi: 0x8d}, + // Block 0x18, offset 0x9f + {value: 0x0000, lo: 0x08}, + {value: 0xa000, lo: 0x87, hi: 0x87}, + {value: 0x2cb6, lo: 0x88, hi: 0x88}, + {value: 0x2cae, lo: 0x8b, hi: 0x8b}, + {value: 0x2cbe, lo: 0x8c, hi: 0x8c}, + {value: 0x8104, lo: 0x8d, hi: 0x8d}, + {value: 0x9900, lo: 0x96, hi: 0x97}, + {value: 0x45a4, lo: 0x9c, hi: 0x9c}, + {value: 0x45ac, lo: 0x9d, hi: 0x9d}, + // Block 0x19, offset 0xa8 + {value: 0x0000, lo: 0x03}, + {value: 0xa000, lo: 0x92, hi: 0x92}, + {value: 0x2cc6, lo: 0x94, hi: 0x94}, + {value: 0x9900, lo: 0xbe, hi: 0xbe}, + // Block 0x1a, offset 0xac + {value: 0x0000, lo: 0x06}, + {value: 0xa000, lo: 0x86, hi: 0x87}, + {value: 0x2cce, lo: 0x8a, hi: 0x8a}, + {value: 0x2cde, lo: 0x8b, hi: 0x8b}, + {value: 0x2cd6, lo: 0x8c, hi: 0x8c}, + {value: 0x8104, lo: 0x8d, hi: 0x8d}, + {value: 0x9900, lo: 0x97, hi: 0x97}, + // Block 0x1b, offset 0xb3 + {value: 0x1801, lo: 0x04}, + {value: 0xa000, lo: 0x86, hi: 0x86}, + {value: 0x3ef0, lo: 0x88, hi: 0x88}, + {value: 0x8104, lo: 0x8d, hi: 0x8d}, + {value: 0x8120, lo: 0x95, hi: 0x96}, + // Block 0x1c, offset 0xb8 + {value: 0x0000, lo: 0x02}, + {value: 0x8102, lo: 0xbc, hi: 0xbc}, + {value: 0xa000, lo: 0xbf, hi: 0xbf}, + // Block 0x1d, offset 0xbb + {value: 0x0000, lo: 0x09}, + {value: 0x2ce6, lo: 0x80, hi: 0x80}, + {value: 0x9900, lo: 0x82, hi: 0x82}, + {value: 0xa000, lo: 0x86, hi: 0x86}, + {value: 0x2cee, lo: 0x87, hi: 0x87}, + {value: 0x2cf6, lo: 0x88, hi: 0x88}, + {value: 0x2f50, lo: 0x8a, hi: 0x8a}, + {value: 0x2dd8, lo: 0x8b, hi: 0x8b}, + {value: 0x8104, lo: 0x8d, hi: 0x8d}, + {value: 0x9900, lo: 0x95, hi: 0x96}, + // Block 0x1e, offset 0xc5 + {value: 0x0000, lo: 0x02}, + {value: 0x8104, lo: 0xbb, hi: 0xbc}, + {value: 0x9900, lo: 0xbe, hi: 0xbe}, + // Block 0x1f, offset 0xc8 + {value: 0x0000, lo: 0x06}, + {value: 0xa000, lo: 0x86, hi: 0x87}, + {value: 0x2cfe, lo: 0x8a, hi: 0x8a}, + {value: 0x2d0e, lo: 0x8b, hi: 0x8b}, + {value: 0x2d06, lo: 0x8c, hi: 0x8c}, + {value: 0x8104, lo: 0x8d, hi: 0x8d}, + {value: 0x9900, lo: 0x97, hi: 0x97}, + // Block 0x20, offset 0xcf + {value: 0x6bea, lo: 0x07}, + {value: 0x9904, lo: 0x8a, hi: 0x8a}, + {value: 0x9900, lo: 0x8f, hi: 0x8f}, + {value: 0xa000, lo: 0x99, hi: 0x99}, + {value: 0x3ef8, lo: 0x9a, hi: 0x9a}, + {value: 0x2f58, lo: 0x9c, hi: 0x9c}, + {value: 0x2de3, lo: 0x9d, hi: 0x9d}, + {value: 0x2d16, lo: 0x9e, hi: 0x9f}, + // Block 0x21, offset 0xd7 + {value: 0x0000, lo: 0x02}, + {value: 0x8122, lo: 0xb8, hi: 0xb9}, + {value: 0x8104, lo: 0xba, hi: 0xba}, + // Block 0x22, offset 0xda + {value: 0x0000, lo: 0x01}, + {value: 0x8123, lo: 0x88, hi: 0x8b}, + // Block 0x23, offset 0xdc + {value: 0x0000, lo: 0x01}, + {value: 0x8124, lo: 0xb8, hi: 0xb9}, + // Block 0x24, offset 0xde + {value: 0x0000, lo: 0x01}, + {value: 0x8125, lo: 0x88, hi: 0x8b}, + // Block 0x25, offset 0xe0 + {value: 0x0000, lo: 0x04}, + {value: 0x812d, lo: 0x98, hi: 0x99}, + {value: 0x812d, lo: 0xb5, hi: 0xb5}, + {value: 0x812d, lo: 0xb7, hi: 0xb7}, + {value: 0x812b, lo: 0xb9, hi: 0xb9}, + // Block 0x26, offset 0xe5 + {value: 0x0000, lo: 0x10}, + {value: 0x2644, lo: 0x83, hi: 0x83}, + {value: 0x264b, lo: 0x8d, hi: 0x8d}, + {value: 0x2652, lo: 0x92, hi: 0x92}, + {value: 0x2659, lo: 0x97, hi: 0x97}, + {value: 0x2660, lo: 0x9c, hi: 0x9c}, + {value: 0x263d, lo: 0xa9, hi: 0xa9}, + {value: 0x8126, lo: 0xb1, hi: 0xb1}, + {value: 0x8127, lo: 0xb2, hi: 0xb2}, + {value: 0x4a84, lo: 0xb3, hi: 0xb3}, + {value: 0x8128, lo: 0xb4, hi: 0xb4}, + {value: 0x4a8d, lo: 0xb5, hi: 0xb5}, + {value: 0x45b4, lo: 0xb6, hi: 0xb6}, + {value: 0x8200, lo: 0xb7, hi: 0xb7}, + {value: 0x45bc, lo: 0xb8, hi: 0xb8}, + {value: 0x8200, lo: 0xb9, hi: 0xb9}, + {value: 0x8127, lo: 0xba, hi: 0xbd}, + // Block 0x27, offset 0xf6 + {value: 0x0000, lo: 0x0b}, + {value: 0x8127, lo: 0x80, hi: 0x80}, + {value: 0x4a96, lo: 0x81, hi: 0x81}, + {value: 0x8132, lo: 0x82, hi: 0x83}, + {value: 0x8104, lo: 0x84, hi: 0x84}, + {value: 0x8132, lo: 0x86, hi: 0x87}, + {value: 0x266e, lo: 0x93, hi: 0x93}, + {value: 0x2675, lo: 0x9d, hi: 0x9d}, + {value: 0x267c, lo: 0xa2, hi: 0xa2}, + {value: 0x2683, lo: 0xa7, hi: 0xa7}, + {value: 0x268a, lo: 0xac, hi: 0xac}, + {value: 0x2667, lo: 0xb9, hi: 0xb9}, + // Block 0x28, offset 0x102 + {value: 0x0000, lo: 0x01}, + {value: 0x812d, lo: 0x86, hi: 0x86}, + // Block 0x29, offset 0x104 + {value: 0x0000, lo: 0x05}, + {value: 0xa000, lo: 0xa5, hi: 0xa5}, + {value: 0x2d1e, lo: 0xa6, hi: 0xa6}, + {value: 0x9900, lo: 0xae, hi: 0xae}, + {value: 0x8102, lo: 0xb7, hi: 0xb7}, + {value: 0x8104, lo: 0xb9, hi: 0xba}, + // Block 0x2a, offset 0x10a + {value: 0x0000, lo: 0x01}, + {value: 0x812d, lo: 0x8d, hi: 0x8d}, + // Block 0x2b, offset 0x10c + {value: 0x0000, lo: 0x01}, + {value: 0xa000, lo: 0x80, hi: 0x92}, + // Block 0x2c, offset 0x10e + {value: 0x0000, lo: 0x01}, + {value: 0xb900, lo: 0xa1, hi: 0xb5}, + // Block 0x2d, offset 0x110 + {value: 0x0000, lo: 0x01}, + {value: 0x9900, lo: 0xa8, hi: 0xbf}, + // Block 0x2e, offset 0x112 + {value: 0x0000, lo: 0x01}, + {value: 0x9900, lo: 0x80, hi: 0x82}, + // Block 0x2f, offset 0x114 + {value: 0x0000, lo: 0x01}, + {value: 0x8132, lo: 0x9d, hi: 0x9f}, + // Block 0x30, offset 0x116 + {value: 0x0000, lo: 0x02}, + {value: 0x8104, lo: 0x94, hi: 0x94}, + {value: 0x8104, lo: 0xb4, hi: 0xb4}, + // Block 0x31, offset 0x119 + {value: 0x0000, lo: 0x02}, + {value: 0x8104, lo: 0x92, hi: 0x92}, + {value: 0x8132, lo: 0x9d, hi: 0x9d}, + // Block 0x32, offset 0x11c + {value: 0x0000, lo: 0x01}, + {value: 0x8131, lo: 0xa9, hi: 0xa9}, + // Block 0x33, offset 0x11e + {value: 0x0004, lo: 0x02}, + {value: 0x812e, lo: 0xb9, hi: 0xba}, + {value: 0x812d, lo: 0xbb, hi: 0xbb}, + // Block 0x34, offset 0x121 + {value: 0x0000, lo: 0x02}, + {value: 0x8132, lo: 0x97, hi: 0x97}, + {value: 0x812d, lo: 0x98, hi: 0x98}, + // Block 0x35, offset 0x124 + {value: 0x0000, lo: 0x03}, + {value: 0x8104, lo: 0xa0, hi: 0xa0}, + {value: 0x8132, lo: 0xb5, hi: 0xbc}, + {value: 0x812d, lo: 0xbf, hi: 0xbf}, + // Block 0x36, offset 0x128 + {value: 0x0000, lo: 0x04}, + {value: 0x8132, lo: 0xb0, hi: 0xb4}, + {value: 0x812d, lo: 0xb5, hi: 0xba}, + {value: 0x8132, lo: 0xbb, hi: 0xbc}, + {value: 0x812d, lo: 0xbd, hi: 0xbd}, + // Block 0x37, offset 0x12d + {value: 0x0000, lo: 0x08}, + {value: 0x2d66, lo: 0x80, hi: 0x80}, + {value: 0x2d6e, lo: 0x81, hi: 0x81}, + {value: 0xa000, lo: 0x82, hi: 0x82}, + {value: 0x2d76, lo: 0x83, hi: 0x83}, + {value: 0x8104, lo: 0x84, hi: 0x84}, + {value: 0x8132, lo: 0xab, hi: 0xab}, + {value: 0x812d, lo: 0xac, hi: 0xac}, + {value: 0x8132, lo: 0xad, hi: 0xb3}, + // Block 0x38, offset 0x136 + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0xaa, hi: 0xab}, + // Block 0x39, offset 0x138 + {value: 0x0000, lo: 0x02}, + {value: 0x8102, lo: 0xa6, hi: 0xa6}, + {value: 0x8104, lo: 0xb2, hi: 0xb3}, + // Block 0x3a, offset 0x13b + {value: 0x0000, lo: 0x01}, + {value: 0x8102, lo: 0xb7, hi: 0xb7}, + // Block 0x3b, offset 0x13d + {value: 0x0000, lo: 0x0a}, + {value: 0x8132, lo: 0x90, hi: 0x92}, + {value: 0x8101, lo: 0x94, hi: 0x94}, + {value: 0x812d, lo: 0x95, hi: 0x99}, + {value: 0x8132, lo: 0x9a, hi: 0x9b}, + {value: 0x812d, lo: 0x9c, hi: 0x9f}, + {value: 0x8132, lo: 0xa0, hi: 0xa0}, + {value: 0x8101, lo: 0xa2, hi: 0xa8}, + {value: 0x812d, lo: 0xad, hi: 0xad}, + {value: 0x8132, lo: 0xb4, hi: 0xb4}, + {value: 0x8132, lo: 0xb8, hi: 0xb9}, + // Block 0x3c, offset 0x148 + {value: 0x0004, lo: 0x03}, + {value: 0x0433, lo: 0x80, hi: 0x81}, + {value: 0x8100, lo: 0x97, hi: 0x97}, + {value: 0x8100, lo: 0xbe, hi: 0xbe}, + // Block 0x3d, offset 0x14c + {value: 0x0000, lo: 0x0d}, + {value: 0x8132, lo: 0x90, hi: 0x91}, + {value: 0x8101, lo: 0x92, hi: 0x93}, + {value: 0x8132, lo: 0x94, hi: 0x97}, + {value: 0x8101, lo: 0x98, hi: 0x9a}, + {value: 0x8132, lo: 0x9b, hi: 0x9c}, + {value: 0x8132, lo: 0xa1, hi: 0xa1}, + {value: 0x8101, lo: 0xa5, hi: 0xa6}, + {value: 0x8132, lo: 0xa7, hi: 0xa7}, + {value: 0x812d, lo: 0xa8, hi: 0xa8}, + {value: 0x8132, lo: 0xa9, hi: 0xa9}, + {value: 0x8101, lo: 0xaa, hi: 0xab}, + {value: 0x812d, lo: 0xac, hi: 0xaf}, + {value: 0x8132, lo: 0xb0, hi: 0xb0}, + // Block 0x3e, offset 0x15a + {value: 0x427b, lo: 0x02}, + {value: 0x01b8, lo: 0xa6, hi: 0xa6}, + {value: 0x0057, lo: 0xaa, hi: 0xab}, + // Block 0x3f, offset 0x15d + {value: 0x0007, lo: 0x05}, + {value: 0xa000, lo: 0x90, hi: 0x90}, + {value: 0xa000, lo: 0x92, hi: 0x92}, + {value: 0xa000, lo: 0x94, hi: 0x94}, + {value: 0x3bb9, lo: 0x9a, hi: 0x9b}, + {value: 0x3bc7, lo: 0xae, hi: 0xae}, + // Block 0x40, offset 0x163 + {value: 0x000e, lo: 0x05}, + {value: 0x3bce, lo: 0x8d, hi: 0x8e}, + {value: 0x3bd5, lo: 0x8f, hi: 0x8f}, + {value: 0xa000, lo: 0x90, hi: 0x90}, + {value: 0xa000, lo: 0x92, hi: 0x92}, + {value: 0xa000, lo: 0x94, hi: 0x94}, + // Block 0x41, offset 0x169 + {value: 0x6408, lo: 0x0a}, + {value: 0xa000, lo: 0x83, hi: 0x83}, + {value: 0x3be3, lo: 0x84, hi: 0x84}, + {value: 0xa000, lo: 0x88, hi: 0x88}, + {value: 0x3bea, lo: 0x89, hi: 0x89}, + {value: 0xa000, lo: 0x8b, hi: 0x8b}, + {value: 0x3bf1, lo: 0x8c, hi: 0x8c}, + {value: 0xa000, lo: 0xa3, hi: 0xa3}, + {value: 0x3bf8, lo: 0xa4, hi: 0xa5}, + {value: 0x3bff, lo: 0xa6, hi: 0xa6}, + {value: 0xa000, lo: 0xbc, hi: 0xbc}, + // Block 0x42, offset 0x174 + {value: 0x0007, lo: 0x03}, + {value: 0x3c68, lo: 0xa0, hi: 0xa1}, + {value: 0x3c92, lo: 0xa2, hi: 0xa3}, + {value: 0x3cbc, lo: 0xaa, hi: 0xad}, + // Block 0x43, offset 0x178 + {value: 0x0004, lo: 0x01}, + {value: 0x048b, lo: 0xa9, hi: 0xaa}, + // Block 0x44, offset 0x17a + {value: 0x0000, lo: 0x01}, + {value: 0x44dd, lo: 0x9c, hi: 0x9c}, + // Block 0x45, offset 0x17c + {value: 0x0000, lo: 0x01}, + {value: 0x8132, lo: 0xaf, hi: 0xb1}, + // Block 0x46, offset 0x17e + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0xbf, hi: 0xbf}, + // Block 0x47, offset 0x180 + {value: 0x0000, lo: 0x01}, + {value: 0x8132, lo: 0xa0, hi: 0xbf}, + // Block 0x48, offset 0x182 + {value: 0x0000, lo: 0x05}, + {value: 0x812c, lo: 0xaa, hi: 0xaa}, + {value: 0x8131, lo: 0xab, hi: 0xab}, + {value: 0x8133, lo: 0xac, hi: 0xac}, + {value: 0x812e, lo: 0xad, hi: 0xad}, + {value: 0x812f, lo: 0xae, hi: 0xaf}, + // Block 0x49, offset 0x188 + {value: 0x0000, lo: 0x03}, + {value: 0x4a9f, lo: 0xb3, hi: 0xb3}, + {value: 0x4a9f, lo: 0xb5, hi: 0xb6}, + {value: 0x4a9f, lo: 0xba, hi: 0xbf}, + // Block 0x4a, offset 0x18c + {value: 0x0000, lo: 0x01}, + {value: 0x4a9f, lo: 0x8f, hi: 0xa3}, + // Block 0x4b, offset 0x18e + {value: 0x0000, lo: 0x01}, + {value: 0x8100, lo: 0xae, hi: 0xbe}, + // Block 0x4c, offset 0x190 + {value: 0x0000, lo: 0x07}, + {value: 0x8100, lo: 0x84, hi: 0x84}, + {value: 0x8100, lo: 0x87, hi: 0x87}, + {value: 0x8100, lo: 0x90, hi: 0x90}, + {value: 0x8100, lo: 0x9e, hi: 0x9e}, + {value: 0x8100, lo: 0xa1, hi: 0xa1}, + {value: 0x8100, lo: 0xb2, hi: 0xb2}, + {value: 0x8100, lo: 0xbb, hi: 0xbb}, + // Block 0x4d, offset 0x198 + {value: 0x0000, lo: 0x03}, + {value: 0x8100, lo: 0x80, hi: 0x80}, + {value: 0x8100, lo: 0x8b, hi: 0x8b}, + {value: 0x8100, lo: 0x8e, hi: 0x8e}, + // Block 0x4e, offset 0x19c + {value: 0x0000, lo: 0x02}, + {value: 0x8132, lo: 0xaf, hi: 0xaf}, + {value: 0x8132, lo: 0xb4, hi: 0xbd}, + // Block 0x4f, offset 0x19f + {value: 0x0000, lo: 0x01}, + {value: 0x8132, lo: 0x9e, hi: 0x9f}, + // Block 0x50, offset 0x1a1 + {value: 0x0000, lo: 0x01}, + {value: 0x8132, lo: 0xb0, hi: 0xb1}, + // Block 0x51, offset 0x1a3 + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0x86, hi: 0x86}, + // Block 0x52, offset 0x1a5 + {value: 0x0000, lo: 0x02}, + {value: 0x8104, lo: 0x84, hi: 0x84}, + {value: 0x8132, lo: 0xa0, hi: 0xb1}, + // Block 0x53, offset 0x1a8 + {value: 0x0000, lo: 0x01}, + {value: 0x812d, lo: 0xab, hi: 0xad}, + // Block 0x54, offset 0x1aa + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0x93, hi: 0x93}, + // Block 0x55, offset 0x1ac + {value: 0x0000, lo: 0x01}, + {value: 0x8102, lo: 0xb3, hi: 0xb3}, + // Block 0x56, offset 0x1ae + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0x80, hi: 0x80}, + // Block 0x57, offset 0x1b0 + {value: 0x0000, lo: 0x05}, + {value: 0x8132, lo: 0xb0, hi: 0xb0}, + {value: 0x8132, lo: 0xb2, hi: 0xb3}, + {value: 0x812d, lo: 0xb4, hi: 0xb4}, + {value: 0x8132, lo: 0xb7, hi: 0xb8}, + {value: 0x8132, lo: 0xbe, hi: 0xbf}, + // Block 0x58, offset 0x1b6 + {value: 0x0000, lo: 0x02}, + {value: 0x8132, lo: 0x81, hi: 0x81}, + {value: 0x8104, lo: 0xb6, hi: 0xb6}, + // Block 0x59, offset 0x1b9 + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0xad, hi: 0xad}, + // Block 0x5a, offset 0x1bb + {value: 0x0000, lo: 0x06}, + {value: 0xe500, lo: 0x80, hi: 0x80}, + {value: 0xc600, lo: 0x81, hi: 0x9b}, + {value: 0xe500, lo: 0x9c, hi: 0x9c}, + {value: 0xc600, lo: 0x9d, hi: 0xb7}, + {value: 0xe500, lo: 0xb8, hi: 0xb8}, + {value: 0xc600, lo: 0xb9, hi: 0xbf}, + // Block 0x5b, offset 0x1c2 + {value: 0x0000, lo: 0x05}, + {value: 0xc600, lo: 0x80, hi: 0x93}, + {value: 0xe500, lo: 0x94, hi: 0x94}, + {value: 0xc600, lo: 0x95, hi: 0xaf}, + {value: 0xe500, lo: 0xb0, hi: 0xb0}, + {value: 0xc600, lo: 0xb1, hi: 0xbf}, + // Block 0x5c, offset 0x1c8 + {value: 0x0000, lo: 0x05}, + {value: 0xc600, lo: 0x80, hi: 0x8b}, + {value: 0xe500, lo: 0x8c, hi: 0x8c}, + {value: 0xc600, lo: 0x8d, hi: 0xa7}, + {value: 0xe500, lo: 0xa8, hi: 0xa8}, + {value: 0xc600, lo: 0xa9, hi: 0xbf}, + // Block 0x5d, offset 0x1ce + {value: 0x0000, lo: 0x07}, + {value: 0xc600, lo: 0x80, hi: 0x83}, + {value: 0xe500, lo: 0x84, hi: 0x84}, + {value: 0xc600, lo: 0x85, hi: 0x9f}, + {value: 0xe500, lo: 0xa0, hi: 0xa0}, + {value: 0xc600, lo: 0xa1, hi: 0xbb}, + {value: 0xe500, lo: 0xbc, hi: 0xbc}, + {value: 0xc600, lo: 0xbd, hi: 0xbf}, + // Block 0x5e, offset 0x1d6 + {value: 0x0000, lo: 0x05}, + {value: 0xc600, lo: 0x80, hi: 0x97}, + {value: 0xe500, lo: 0x98, hi: 0x98}, + {value: 0xc600, lo: 0x99, hi: 0xb3}, + {value: 0xe500, lo: 0xb4, hi: 0xb4}, + {value: 0xc600, lo: 0xb5, hi: 0xbf}, + // Block 0x5f, offset 0x1dc + {value: 0x0000, lo: 0x05}, + {value: 0xc600, lo: 0x80, hi: 0x8f}, + {value: 0xe500, lo: 0x90, hi: 0x90}, + {value: 0xc600, lo: 0x91, hi: 0xab}, + {value: 0xe500, lo: 0xac, hi: 0xac}, + {value: 0xc600, lo: 0xad, hi: 0xbf}, + // Block 0x60, offset 0x1e2 + {value: 0x0000, lo: 0x05}, + {value: 0xc600, lo: 0x80, hi: 0x87}, + {value: 0xe500, lo: 0x88, hi: 0x88}, + {value: 0xc600, lo: 0x89, hi: 0xa3}, + {value: 0xe500, lo: 0xa4, hi: 0xa4}, + {value: 0xc600, lo: 0xa5, hi: 0xbf}, + // Block 0x61, offset 0x1e8 + {value: 0x0000, lo: 0x03}, + {value: 0xc600, lo: 0x80, hi: 0x87}, + {value: 0xe500, lo: 0x88, hi: 0x88}, + {value: 0xc600, lo: 0x89, hi: 0xa3}, + // Block 0x62, offset 0x1ec + {value: 0x0006, lo: 0x0d}, + {value: 0x4390, lo: 0x9d, hi: 0x9d}, + {value: 0x8115, lo: 0x9e, hi: 0x9e}, + {value: 0x4402, lo: 0x9f, hi: 0x9f}, + {value: 0x43f0, lo: 0xaa, hi: 0xab}, + {value: 0x44f4, lo: 0xac, hi: 0xac}, + {value: 0x44fc, lo: 0xad, hi: 0xad}, + {value: 0x4348, lo: 0xae, hi: 0xb1}, + {value: 0x4366, lo: 0xb2, hi: 0xb4}, + {value: 0x437e, lo: 0xb5, hi: 0xb6}, + {value: 0x438a, lo: 0xb8, hi: 0xb8}, + {value: 0x4396, lo: 0xb9, hi: 0xbb}, + {value: 0x43ae, lo: 0xbc, hi: 0xbc}, + {value: 0x43b4, lo: 0xbe, hi: 0xbe}, + // Block 0x63, offset 0x1fa + {value: 0x0006, lo: 0x08}, + {value: 0x43ba, lo: 0x80, hi: 0x81}, + {value: 0x43c6, lo: 0x83, hi: 0x84}, + {value: 0x43d8, lo: 0x86, hi: 0x89}, + {value: 0x43fc, lo: 0x8a, hi: 0x8a}, + {value: 0x4378, lo: 0x8b, hi: 0x8b}, + {value: 0x4360, lo: 0x8c, hi: 0x8c}, + {value: 0x43a8, lo: 0x8d, hi: 0x8d}, + {value: 0x43d2, lo: 0x8e, hi: 0x8e}, + // Block 0x64, offset 0x203 + {value: 0x0000, lo: 0x02}, + {value: 0x8100, lo: 0xa4, hi: 0xa5}, + {value: 0x8100, lo: 0xb0, hi: 0xb1}, + // Block 0x65, offset 0x206 + {value: 0x0000, lo: 0x02}, + {value: 0x8100, lo: 0x9b, hi: 0x9d}, + {value: 0x8200, lo: 0x9e, hi: 0xa3}, + // Block 0x66, offset 0x209 + {value: 0x0000, lo: 0x01}, + {value: 0x8100, lo: 0x90, hi: 0x90}, + // Block 0x67, offset 0x20b + {value: 0x0000, lo: 0x02}, + {value: 0x8100, lo: 0x99, hi: 0x99}, + {value: 0x8200, lo: 0xb2, hi: 0xb4}, + // Block 0x68, offset 0x20e + {value: 0x0000, lo: 0x01}, + {value: 0x8100, lo: 0xbc, hi: 0xbd}, + // Block 0x69, offset 0x210 + {value: 0x0000, lo: 0x03}, + {value: 0x8132, lo: 0xa0, hi: 0xa6}, + {value: 0x812d, lo: 0xa7, hi: 0xad}, + {value: 0x8132, lo: 0xae, hi: 0xaf}, + // Block 0x6a, offset 0x214 + {value: 0x0000, lo: 0x04}, + {value: 0x8100, lo: 0x89, hi: 0x8c}, + {value: 0x8100, lo: 0xb0, hi: 0xb2}, + {value: 0x8100, lo: 0xb4, hi: 0xb4}, + {value: 0x8100, lo: 0xb6, hi: 0xbf}, + // Block 0x6b, offset 0x219 + {value: 0x0000, lo: 0x01}, + {value: 0x8100, lo: 0x81, hi: 0x8c}, + // Block 0x6c, offset 0x21b + {value: 0x0000, lo: 0x01}, + {value: 0x8100, lo: 0xb5, hi: 0xba}, + // Block 0x6d, offset 0x21d + {value: 0x0000, lo: 0x04}, + {value: 0x4a9f, lo: 0x9e, hi: 0x9f}, + {value: 0x4a9f, lo: 0xa3, hi: 0xa3}, + {value: 0x4a9f, lo: 0xa5, hi: 0xa6}, + {value: 0x4a9f, lo: 0xaa, hi: 0xaf}, + // Block 0x6e, offset 0x222 + {value: 0x0000, lo: 0x05}, + {value: 0x4a9f, lo: 0x82, hi: 0x87}, + {value: 0x4a9f, lo: 0x8a, hi: 0x8f}, + {value: 0x4a9f, lo: 0x92, hi: 0x97}, + {value: 0x4a9f, lo: 0x9a, hi: 0x9c}, + {value: 0x8100, lo: 0xa3, hi: 0xa3}, + // Block 0x6f, offset 0x228 + {value: 0x0000, lo: 0x01}, + {value: 0x812d, lo: 0xbd, hi: 0xbd}, + // Block 0x70, offset 0x22a + {value: 0x0000, lo: 0x01}, + {value: 0x812d, lo: 0xa0, hi: 0xa0}, + // Block 0x71, offset 0x22c + {value: 0x0000, lo: 0x01}, + {value: 0x8132, lo: 0xb6, hi: 0xba}, + // Block 0x72, offset 0x22e + {value: 0x002c, lo: 0x05}, + {value: 0x812d, lo: 0x8d, hi: 0x8d}, + {value: 0x8132, lo: 0x8f, hi: 0x8f}, + {value: 0x8132, lo: 0xb8, hi: 0xb8}, + {value: 0x8101, lo: 0xb9, hi: 0xba}, + {value: 0x8104, lo: 0xbf, hi: 0xbf}, + // Block 0x73, offset 0x234 + {value: 0x0000, lo: 0x02}, + {value: 0x8132, lo: 0xa5, hi: 0xa5}, + {value: 0x812d, lo: 0xa6, hi: 0xa6}, + // Block 0x74, offset 0x237 + {value: 0x0000, lo: 0x02}, + {value: 0x8104, lo: 0x86, hi: 0x86}, + {value: 0x8104, lo: 0xbf, hi: 0xbf}, + // Block 0x75, offset 0x23a + {value: 0x17fe, lo: 0x07}, + {value: 0xa000, lo: 0x99, hi: 0x99}, + {value: 0x4238, lo: 0x9a, hi: 0x9a}, + {value: 0xa000, lo: 0x9b, hi: 0x9b}, + {value: 0x4242, lo: 0x9c, hi: 0x9c}, + {value: 0xa000, lo: 0xa5, hi: 0xa5}, + {value: 0x424c, lo: 0xab, hi: 0xab}, + {value: 0x8104, lo: 0xb9, hi: 0xba}, + // Block 0x76, offset 0x242 + {value: 0x0000, lo: 0x06}, + {value: 0x8132, lo: 0x80, hi: 0x82}, + {value: 0x9900, lo: 0xa7, hi: 0xa7}, + {value: 0x2d7e, lo: 0xae, hi: 0xae}, + {value: 0x2d88, lo: 0xaf, hi: 0xaf}, + {value: 0xa000, lo: 0xb1, hi: 0xb2}, + {value: 0x8104, lo: 0xb3, hi: 0xb4}, + // Block 0x77, offset 0x249 + {value: 0x0000, lo: 0x02}, + {value: 0x8104, lo: 0x80, hi: 0x80}, + {value: 0x8102, lo: 0x8a, hi: 0x8a}, + // Block 0x78, offset 0x24c + {value: 0x0000, lo: 0x02}, + {value: 0x8104, lo: 0xb5, hi: 0xb5}, + {value: 0x8102, lo: 0xb6, hi: 0xb6}, + // Block 0x79, offset 0x24f + {value: 0x0002, lo: 0x01}, + {value: 0x8102, lo: 0xa9, hi: 0xaa}, + // Block 0x7a, offset 0x251 + {value: 0x0000, lo: 0x07}, + {value: 0xa000, lo: 0x87, hi: 0x87}, + {value: 0x2d92, lo: 0x8b, hi: 0x8b}, + {value: 0x2d9c, lo: 0x8c, hi: 0x8c}, + {value: 0x8104, lo: 0x8d, hi: 0x8d}, + {value: 0x9900, lo: 0x97, hi: 0x97}, + {value: 0x8132, lo: 0xa6, hi: 0xac}, + {value: 0x8132, lo: 0xb0, hi: 0xb4}, + // Block 0x7b, offset 0x259 + {value: 0x0000, lo: 0x02}, + {value: 0x8104, lo: 0x82, hi: 0x82}, + {value: 0x8102, lo: 0x86, hi: 0x86}, + // Block 0x7c, offset 0x25c + {value: 0x6b5a, lo: 0x06}, + {value: 0x9900, lo: 0xb0, hi: 0xb0}, + {value: 0xa000, lo: 0xb9, hi: 0xb9}, + {value: 0x9900, lo: 0xba, hi: 0xba}, + {value: 0x2db0, lo: 0xbb, hi: 0xbb}, + {value: 0x2da6, lo: 0xbc, hi: 0xbd}, + {value: 0x2dba, lo: 0xbe, hi: 0xbe}, + // Block 0x7d, offset 0x263 + {value: 0x0000, lo: 0x02}, + {value: 0x8104, lo: 0x82, hi: 0x82}, + {value: 0x8102, lo: 0x83, hi: 0x83}, + // Block 0x7e, offset 0x266 + {value: 0x0000, lo: 0x05}, + {value: 0x9900, lo: 0xaf, hi: 0xaf}, + {value: 0xa000, lo: 0xb8, hi: 0xb9}, + {value: 0x2dc4, lo: 0xba, hi: 0xba}, + {value: 0x2dce, lo: 0xbb, hi: 0xbb}, + {value: 0x8104, lo: 0xbf, hi: 0xbf}, + // Block 0x7f, offset 0x26c + {value: 0x0000, lo: 0x01}, + {value: 0x8102, lo: 0x80, hi: 0x80}, + // Block 0x80, offset 0x26e + {value: 0x0000, lo: 0x02}, + {value: 0x8104, lo: 0xb6, hi: 0xb6}, + {value: 0x8102, lo: 0xb7, hi: 0xb7}, + // Block 0x81, offset 0x271 + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0xab, hi: 0xab}, + // Block 0x82, offset 0x273 + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0xb4, hi: 0xb4}, + // Block 0x83, offset 0x275 + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0x87, hi: 0x87}, + // Block 0x84, offset 0x277 + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0x99, hi: 0x99}, + // Block 0x85, offset 0x279 + {value: 0x0000, lo: 0x02}, + {value: 0x8102, lo: 0x82, hi: 0x82}, + {value: 0x8104, lo: 0x84, hi: 0x85}, + // Block 0x86, offset 0x27c + {value: 0x0000, lo: 0x01}, + {value: 0x8101, lo: 0xb0, hi: 0xb4}, + // Block 0x87, offset 0x27e + {value: 0x0000, lo: 0x01}, + {value: 0x8132, lo: 0xb0, hi: 0xb6}, + // Block 0x88, offset 0x280 + {value: 0x0000, lo: 0x01}, + {value: 0x8101, lo: 0x9e, hi: 0x9e}, + // Block 0x89, offset 0x282 + {value: 0x0000, lo: 0x0c}, + {value: 0x45cc, lo: 0x9e, hi: 0x9e}, + {value: 0x45d6, lo: 0x9f, hi: 0x9f}, + {value: 0x460a, lo: 0xa0, hi: 0xa0}, + {value: 0x4618, lo: 0xa1, hi: 0xa1}, + {value: 0x4626, lo: 0xa2, hi: 0xa2}, + {value: 0x4634, lo: 0xa3, hi: 0xa3}, + {value: 0x4642, lo: 0xa4, hi: 0xa4}, + {value: 0x812b, lo: 0xa5, hi: 0xa6}, + {value: 0x8101, lo: 0xa7, hi: 0xa9}, + {value: 0x8130, lo: 0xad, hi: 0xad}, + {value: 0x812b, lo: 0xae, hi: 0xb2}, + {value: 0x812d, lo: 0xbb, hi: 0xbf}, + // Block 0x8a, offset 0x28f + {value: 0x0000, lo: 0x09}, + {value: 0x812d, lo: 0x80, hi: 0x82}, + {value: 0x8132, lo: 0x85, hi: 0x89}, + {value: 0x812d, lo: 0x8a, hi: 0x8b}, + {value: 0x8132, lo: 0xaa, hi: 0xad}, + {value: 0x45e0, lo: 0xbb, hi: 0xbb}, + {value: 0x45ea, lo: 0xbc, hi: 0xbc}, + {value: 0x4650, lo: 0xbd, hi: 0xbd}, + {value: 0x466c, lo: 0xbe, hi: 0xbe}, + {value: 0x465e, lo: 0xbf, hi: 0xbf}, + // Block 0x8b, offset 0x299 + {value: 0x0000, lo: 0x01}, + {value: 0x467a, lo: 0x80, hi: 0x80}, + // Block 0x8c, offset 0x29b + {value: 0x0000, lo: 0x01}, + {value: 0x8132, lo: 0x82, hi: 0x84}, + // Block 0x8d, offset 0x29d + {value: 0x0000, lo: 0x05}, + {value: 0x8132, lo: 0x80, hi: 0x86}, + {value: 0x8132, lo: 0x88, hi: 0x98}, + {value: 0x8132, lo: 0x9b, hi: 0xa1}, + {value: 0x8132, lo: 0xa3, hi: 0xa4}, + {value: 0x8132, lo: 0xa6, hi: 0xaa}, + // Block 0x8e, offset 0x2a3 + {value: 0x0000, lo: 0x01}, + {value: 0x812d, lo: 0x90, hi: 0x96}, + // Block 0x8f, offset 0x2a5 + {value: 0x0000, lo: 0x02}, + {value: 0x8132, lo: 0x84, hi: 0x89}, + {value: 0x8102, lo: 0x8a, hi: 0x8a}, + // Block 0x90, offset 0x2a8 + {value: 0x0000, lo: 0x01}, + {value: 0x8100, lo: 0x93, hi: 0x93}, +} + +// lookup returns the trie value for the first UTF-8 encoding in s and +// the width in bytes of this encoding. The size will be 0 if s does not +// hold enough bytes to complete the encoding. len(s) must be greater than 0. +func (t *nfkcTrie) lookup(s []byte) (v uint16, sz int) { + c0 := s[0] + switch { + case c0 < 0x80: // is ASCII + return nfkcValues[c0], 1 + case c0 < 0xC2: + return 0, 1 // Illegal UTF-8: not a starter, not ASCII. + case c0 < 0xE0: // 2-byte UTF-8 + if len(s) < 2 { + return 0, 0 + } + i := nfkcIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c1), 2 + case c0 < 0xF0: // 3-byte UTF-8 + if len(s) < 3 { + return 0, 0 + } + i := nfkcIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = nfkcIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c2), 3 + case c0 < 0xF8: // 4-byte UTF-8 + if len(s) < 4 { + return 0, 0 + } + i := nfkcIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = nfkcIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + o = uint32(i)<<6 + uint32(c2) + i = nfkcIndex[o] + c3 := s[3] + if c3 < 0x80 || 0xC0 <= c3 { + return 0, 3 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c3), 4 + } + // Illegal rune + return 0, 1 +} + +// lookupUnsafe returns the trie value for the first UTF-8 encoding in s. +// s must start with a full and valid UTF-8 encoded rune. +func (t *nfkcTrie) lookupUnsafe(s []byte) uint16 { + c0 := s[0] + if c0 < 0x80 { // is ASCII + return nfkcValues[c0] + } + i := nfkcIndex[c0] + if c0 < 0xE0 { // 2-byte UTF-8 + return t.lookupValue(uint32(i), s[1]) + } + i = nfkcIndex[uint32(i)<<6+uint32(s[1])] + if c0 < 0xF0 { // 3-byte UTF-8 + return t.lookupValue(uint32(i), s[2]) + } + i = nfkcIndex[uint32(i)<<6+uint32(s[2])] + if c0 < 0xF8 { // 4-byte UTF-8 + return t.lookupValue(uint32(i), s[3]) + } + return 0 +} + +// lookupString returns the trie value for the first UTF-8 encoding in s and +// the width in bytes of this encoding. The size will be 0 if s does not +// hold enough bytes to complete the encoding. len(s) must be greater than 0. +func (t *nfkcTrie) lookupString(s string) (v uint16, sz int) { + c0 := s[0] + switch { + case c0 < 0x80: // is ASCII + return nfkcValues[c0], 1 + case c0 < 0xC2: + return 0, 1 // Illegal UTF-8: not a starter, not ASCII. + case c0 < 0xE0: // 2-byte UTF-8 + if len(s) < 2 { + return 0, 0 + } + i := nfkcIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c1), 2 + case c0 < 0xF0: // 3-byte UTF-8 + if len(s) < 3 { + return 0, 0 + } + i := nfkcIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = nfkcIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c2), 3 + case c0 < 0xF8: // 4-byte UTF-8 + if len(s) < 4 { + return 0, 0 + } + i := nfkcIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = nfkcIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + o = uint32(i)<<6 + uint32(c2) + i = nfkcIndex[o] + c3 := s[3] + if c3 < 0x80 || 0xC0 <= c3 { + return 0, 3 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c3), 4 + } + // Illegal rune + return 0, 1 +} + +// lookupStringUnsafe returns the trie value for the first UTF-8 encoding in s. +// s must start with a full and valid UTF-8 encoded rune. +func (t *nfkcTrie) lookupStringUnsafe(s string) uint16 { + c0 := s[0] + if c0 < 0x80 { // is ASCII + return nfkcValues[c0] + } + i := nfkcIndex[c0] + if c0 < 0xE0 { // 2-byte UTF-8 + return t.lookupValue(uint32(i), s[1]) + } + i = nfkcIndex[uint32(i)<<6+uint32(s[1])] + if c0 < 0xF0 { // 3-byte UTF-8 + return t.lookupValue(uint32(i), s[2]) + } + i = nfkcIndex[uint32(i)<<6+uint32(s[2])] + if c0 < 0xF8 { // 4-byte UTF-8 + return t.lookupValue(uint32(i), s[3]) + } + return 0 +} + +// nfkcTrie. Total size: 17104 bytes (16.70 KiB). Checksum: d985061cf5307b35. +type nfkcTrie struct{} + +func newNfkcTrie(i int) *nfkcTrie { + return &nfkcTrie{} +} + +// lookupValue determines the type of block n and looks up the value for b. +func (t *nfkcTrie) lookupValue(n uint32, b byte) uint16 { + switch { + case n < 91: + return uint16(nfkcValues[n<<6+uint32(b)]) + default: + n -= 91 + return uint16(nfkcSparse.lookup(n, b)) + } +} + +// nfkcValues: 93 blocks, 5952 entries, 11904 bytes +// The third block is the zero block. +var nfkcValues = [5952]uint16{ + // Block 0x0, offset 0x0 + 0x3c: 0xa000, 0x3d: 0xa000, 0x3e: 0xa000, + // Block 0x1, offset 0x40 + 0x41: 0xa000, 0x42: 0xa000, 0x43: 0xa000, 0x44: 0xa000, 0x45: 0xa000, + 0x46: 0xa000, 0x47: 0xa000, 0x48: 0xa000, 0x49: 0xa000, 0x4a: 0xa000, 0x4b: 0xa000, + 0x4c: 0xa000, 0x4d: 0xa000, 0x4e: 0xa000, 0x4f: 0xa000, 0x50: 0xa000, + 0x52: 0xa000, 0x53: 0xa000, 0x54: 0xa000, 0x55: 0xa000, 0x56: 0xa000, 0x57: 0xa000, + 0x58: 0xa000, 0x59: 0xa000, 0x5a: 0xa000, + 0x61: 0xa000, 0x62: 0xa000, 0x63: 0xa000, + 0x64: 0xa000, 0x65: 0xa000, 0x66: 0xa000, 0x67: 0xa000, 0x68: 0xa000, 0x69: 0xa000, + 0x6a: 0xa000, 0x6b: 0xa000, 0x6c: 0xa000, 0x6d: 0xa000, 0x6e: 0xa000, 0x6f: 0xa000, + 0x70: 0xa000, 0x72: 0xa000, 0x73: 0xa000, 0x74: 0xa000, 0x75: 0xa000, + 0x76: 0xa000, 0x77: 0xa000, 0x78: 0xa000, 0x79: 0xa000, 0x7a: 0xa000, + // Block 0x2, offset 0x80 + // Block 0x3, offset 0xc0 + 0xc0: 0x2f6f, 0xc1: 0x2f74, 0xc2: 0x4688, 0xc3: 0x2f79, 0xc4: 0x4697, 0xc5: 0x469c, + 0xc6: 0xa000, 0xc7: 0x46a6, 0xc8: 0x2fe2, 0xc9: 0x2fe7, 0xca: 0x46ab, 0xcb: 0x2ffb, + 0xcc: 0x306e, 0xcd: 0x3073, 0xce: 0x3078, 0xcf: 0x46bf, 0xd1: 0x3104, + 0xd2: 0x3127, 0xd3: 0x312c, 0xd4: 0x46c9, 0xd5: 0x46ce, 0xd6: 0x46dd, + 0xd8: 0xa000, 0xd9: 0x31b3, 0xda: 0x31b8, 0xdb: 0x31bd, 0xdc: 0x470f, 0xdd: 0x3235, + 0xe0: 0x327b, 0xe1: 0x3280, 0xe2: 0x4719, 0xe3: 0x3285, + 0xe4: 0x4728, 0xe5: 0x472d, 0xe6: 0xa000, 0xe7: 0x4737, 0xe8: 0x32ee, 0xe9: 0x32f3, + 0xea: 0x473c, 0xeb: 0x3307, 0xec: 0x337f, 0xed: 0x3384, 0xee: 0x3389, 0xef: 0x4750, + 0xf1: 0x3415, 0xf2: 0x3438, 0xf3: 0x343d, 0xf4: 0x475a, 0xf5: 0x475f, + 0xf6: 0x476e, 0xf8: 0xa000, 0xf9: 0x34c9, 0xfa: 0x34ce, 0xfb: 0x34d3, + 0xfc: 0x47a0, 0xfd: 0x3550, 0xff: 0x3569, + // Block 0x4, offset 0x100 + 0x100: 0x2f7e, 0x101: 0x328a, 0x102: 0x468d, 0x103: 0x471e, 0x104: 0x2f9c, 0x105: 0x32a8, + 0x106: 0x2fb0, 0x107: 0x32bc, 0x108: 0x2fb5, 0x109: 0x32c1, 0x10a: 0x2fba, 0x10b: 0x32c6, + 0x10c: 0x2fbf, 0x10d: 0x32cb, 0x10e: 0x2fc9, 0x10f: 0x32d5, + 0x112: 0x46b0, 0x113: 0x4741, 0x114: 0x2ff1, 0x115: 0x32fd, 0x116: 0x2ff6, 0x117: 0x3302, + 0x118: 0x3014, 0x119: 0x3320, 0x11a: 0x3005, 0x11b: 0x3311, 0x11c: 0x302d, 0x11d: 0x3339, + 0x11e: 0x3037, 0x11f: 0x3343, 0x120: 0x303c, 0x121: 0x3348, 0x122: 0x3046, 0x123: 0x3352, + 0x124: 0x304b, 0x125: 0x3357, 0x128: 0x307d, 0x129: 0x338e, + 0x12a: 0x3082, 0x12b: 0x3393, 0x12c: 0x3087, 0x12d: 0x3398, 0x12e: 0x30aa, 0x12f: 0x33b6, + 0x130: 0x308c, 0x132: 0x195d, 0x133: 0x19e7, 0x134: 0x30b4, 0x135: 0x33c0, + 0x136: 0x30c8, 0x137: 0x33d9, 0x139: 0x30d2, 0x13a: 0x33e3, 0x13b: 0x30dc, + 0x13c: 0x33ed, 0x13d: 0x30d7, 0x13e: 0x33e8, 0x13f: 0x1bac, + // Block 0x5, offset 0x140 + 0x140: 0x1c34, 0x143: 0x30ff, 0x144: 0x3410, 0x145: 0x3118, + 0x146: 0x3429, 0x147: 0x310e, 0x148: 0x341f, 0x149: 0x1c5c, + 0x14c: 0x46d3, 0x14d: 0x4764, 0x14e: 0x3131, 0x14f: 0x3442, 0x150: 0x313b, 0x151: 0x344c, + 0x154: 0x3159, 0x155: 0x346a, 0x156: 0x3172, 0x157: 0x3483, + 0x158: 0x3163, 0x159: 0x3474, 0x15a: 0x46f6, 0x15b: 0x4787, 0x15c: 0x317c, 0x15d: 0x348d, + 0x15e: 0x318b, 0x15f: 0x349c, 0x160: 0x46fb, 0x161: 0x478c, 0x162: 0x31a4, 0x163: 0x34ba, + 0x164: 0x3195, 0x165: 0x34ab, 0x168: 0x4705, 0x169: 0x4796, + 0x16a: 0x470a, 0x16b: 0x479b, 0x16c: 0x31c2, 0x16d: 0x34d8, 0x16e: 0x31cc, 0x16f: 0x34e2, + 0x170: 0x31d1, 0x171: 0x34e7, 0x172: 0x31ef, 0x173: 0x3505, 0x174: 0x3212, 0x175: 0x3528, + 0x176: 0x323a, 0x177: 0x3555, 0x178: 0x324e, 0x179: 0x325d, 0x17a: 0x357d, 0x17b: 0x3267, + 0x17c: 0x3587, 0x17d: 0x326c, 0x17e: 0x358c, 0x17f: 0x00a7, + // Block 0x6, offset 0x180 + 0x184: 0x2dee, 0x185: 0x2df4, + 0x186: 0x2dfa, 0x187: 0x1972, 0x188: 0x1975, 0x189: 0x1a08, 0x18a: 0x1987, 0x18b: 0x198a, + 0x18c: 0x1a3e, 0x18d: 0x2f88, 0x18e: 0x3294, 0x18f: 0x3096, 0x190: 0x33a2, 0x191: 0x3140, + 0x192: 0x3451, 0x193: 0x31d6, 0x194: 0x34ec, 0x195: 0x39cf, 0x196: 0x3b5e, 0x197: 0x39c8, + 0x198: 0x3b57, 0x199: 0x39d6, 0x19a: 0x3b65, 0x19b: 0x39c1, 0x19c: 0x3b50, + 0x19e: 0x38b0, 0x19f: 0x3a3f, 0x1a0: 0x38a9, 0x1a1: 0x3a38, 0x1a2: 0x35b3, 0x1a3: 0x35c5, + 0x1a6: 0x3041, 0x1a7: 0x334d, 0x1a8: 0x30be, 0x1a9: 0x33cf, + 0x1aa: 0x46ec, 0x1ab: 0x477d, 0x1ac: 0x3990, 0x1ad: 0x3b1f, 0x1ae: 0x35d7, 0x1af: 0x35dd, + 0x1b0: 0x33c5, 0x1b1: 0x1942, 0x1b2: 0x1945, 0x1b3: 0x19cf, 0x1b4: 0x3028, 0x1b5: 0x3334, + 0x1b8: 0x30fa, 0x1b9: 0x340b, 0x1ba: 0x38b7, 0x1bb: 0x3a46, + 0x1bc: 0x35ad, 0x1bd: 0x35bf, 0x1be: 0x35b9, 0x1bf: 0x35cb, + // Block 0x7, offset 0x1c0 + 0x1c0: 0x2f8d, 0x1c1: 0x3299, 0x1c2: 0x2f92, 0x1c3: 0x329e, 0x1c4: 0x300a, 0x1c5: 0x3316, + 0x1c6: 0x300f, 0x1c7: 0x331b, 0x1c8: 0x309b, 0x1c9: 0x33a7, 0x1ca: 0x30a0, 0x1cb: 0x33ac, + 0x1cc: 0x3145, 0x1cd: 0x3456, 0x1ce: 0x314a, 0x1cf: 0x345b, 0x1d0: 0x3168, 0x1d1: 0x3479, + 0x1d2: 0x316d, 0x1d3: 0x347e, 0x1d4: 0x31db, 0x1d5: 0x34f1, 0x1d6: 0x31e0, 0x1d7: 0x34f6, + 0x1d8: 0x3186, 0x1d9: 0x3497, 0x1da: 0x319f, 0x1db: 0x34b5, + 0x1de: 0x305a, 0x1df: 0x3366, + 0x1e6: 0x4692, 0x1e7: 0x4723, 0x1e8: 0x46ba, 0x1e9: 0x474b, + 0x1ea: 0x395f, 0x1eb: 0x3aee, 0x1ec: 0x393c, 0x1ed: 0x3acb, 0x1ee: 0x46d8, 0x1ef: 0x4769, + 0x1f0: 0x3958, 0x1f1: 0x3ae7, 0x1f2: 0x3244, 0x1f3: 0x355f, + // Block 0x8, offset 0x200 + 0x200: 0x9932, 0x201: 0x9932, 0x202: 0x9932, 0x203: 0x9932, 0x204: 0x9932, 0x205: 0x8132, + 0x206: 0x9932, 0x207: 0x9932, 0x208: 0x9932, 0x209: 0x9932, 0x20a: 0x9932, 0x20b: 0x9932, + 0x20c: 0x9932, 0x20d: 0x8132, 0x20e: 0x8132, 0x20f: 0x9932, 0x210: 0x8132, 0x211: 0x9932, + 0x212: 0x8132, 0x213: 0x9932, 0x214: 0x9932, 0x215: 0x8133, 0x216: 0x812d, 0x217: 0x812d, + 0x218: 0x812d, 0x219: 0x812d, 0x21a: 0x8133, 0x21b: 0x992b, 0x21c: 0x812d, 0x21d: 0x812d, + 0x21e: 0x812d, 0x21f: 0x812d, 0x220: 0x812d, 0x221: 0x8129, 0x222: 0x8129, 0x223: 0x992d, + 0x224: 0x992d, 0x225: 0x992d, 0x226: 0x992d, 0x227: 0x9929, 0x228: 0x9929, 0x229: 0x812d, + 0x22a: 0x812d, 0x22b: 0x812d, 0x22c: 0x812d, 0x22d: 0x992d, 0x22e: 0x992d, 0x22f: 0x812d, + 0x230: 0x992d, 0x231: 0x992d, 0x232: 0x812d, 0x233: 0x812d, 0x234: 0x8101, 0x235: 0x8101, + 0x236: 0x8101, 0x237: 0x8101, 0x238: 0x9901, 0x239: 0x812d, 0x23a: 0x812d, 0x23b: 0x812d, + 0x23c: 0x812d, 0x23d: 0x8132, 0x23e: 0x8132, 0x23f: 0x8132, + // Block 0x9, offset 0x240 + 0x240: 0x49ae, 0x241: 0x49b3, 0x242: 0x9932, 0x243: 0x49b8, 0x244: 0x4a71, 0x245: 0x9936, + 0x246: 0x8132, 0x247: 0x812d, 0x248: 0x812d, 0x249: 0x812d, 0x24a: 0x8132, 0x24b: 0x8132, + 0x24c: 0x8132, 0x24d: 0x812d, 0x24e: 0x812d, 0x250: 0x8132, 0x251: 0x8132, + 0x252: 0x8132, 0x253: 0x812d, 0x254: 0x812d, 0x255: 0x812d, 0x256: 0x812d, 0x257: 0x8132, + 0x258: 0x8133, 0x259: 0x812d, 0x25a: 0x812d, 0x25b: 0x8132, 0x25c: 0x8134, 0x25d: 0x8135, + 0x25e: 0x8135, 0x25f: 0x8134, 0x260: 0x8135, 0x261: 0x8135, 0x262: 0x8134, 0x263: 0x8132, + 0x264: 0x8132, 0x265: 0x8132, 0x266: 0x8132, 0x267: 0x8132, 0x268: 0x8132, 0x269: 0x8132, + 0x26a: 0x8132, 0x26b: 0x8132, 0x26c: 0x8132, 0x26d: 0x8132, 0x26e: 0x8132, 0x26f: 0x8132, + 0x274: 0x0170, + 0x27a: 0x42a5, + 0x27e: 0x0037, + // Block 0xa, offset 0x280 + 0x284: 0x425a, 0x285: 0x447b, + 0x286: 0x35e9, 0x287: 0x00ce, 0x288: 0x3607, 0x289: 0x3613, 0x28a: 0x3625, + 0x28c: 0x3643, 0x28e: 0x3655, 0x28f: 0x3673, 0x290: 0x3e08, 0x291: 0xa000, + 0x295: 0xa000, 0x297: 0xa000, + 0x299: 0xa000, + 0x29f: 0xa000, 0x2a1: 0xa000, + 0x2a5: 0xa000, 0x2a9: 0xa000, + 0x2aa: 0x3637, 0x2ab: 0x3667, 0x2ac: 0x47fe, 0x2ad: 0x3697, 0x2ae: 0x4828, 0x2af: 0x36a9, + 0x2b0: 0x3e70, 0x2b1: 0xa000, 0x2b5: 0xa000, + 0x2b7: 0xa000, 0x2b9: 0xa000, + 0x2bf: 0xa000, + // Block 0xb, offset 0x2c0 + 0x2c1: 0xa000, 0x2c5: 0xa000, + 0x2c9: 0xa000, 0x2ca: 0x4840, 0x2cb: 0x485e, + 0x2cc: 0x36c7, 0x2cd: 0x36df, 0x2ce: 0x4876, 0x2d0: 0x01be, 0x2d1: 0x01d0, + 0x2d2: 0x01ac, 0x2d3: 0x430c, 0x2d4: 0x4312, 0x2d5: 0x01fa, 0x2d6: 0x01e8, + 0x2f0: 0x01d6, 0x2f1: 0x01eb, 0x2f2: 0x01ee, 0x2f4: 0x0188, 0x2f5: 0x01c7, + 0x2f9: 0x01a6, + // Block 0xc, offset 0x300 + 0x300: 0x3721, 0x301: 0x372d, 0x303: 0x371b, + 0x306: 0xa000, 0x307: 0x3709, + 0x30c: 0x375d, 0x30d: 0x3745, 0x30e: 0x376f, 0x310: 0xa000, + 0x313: 0xa000, 0x315: 0xa000, 0x316: 0xa000, 0x317: 0xa000, + 0x318: 0xa000, 0x319: 0x3751, 0x31a: 0xa000, + 0x31e: 0xa000, 0x323: 0xa000, + 0x327: 0xa000, + 0x32b: 0xa000, 0x32d: 0xa000, + 0x330: 0xa000, 0x333: 0xa000, 0x335: 0xa000, + 0x336: 0xa000, 0x337: 0xa000, 0x338: 0xa000, 0x339: 0x37d5, 0x33a: 0xa000, + 0x33e: 0xa000, + // Block 0xd, offset 0x340 + 0x341: 0x3733, 0x342: 0x37b7, + 0x350: 0x370f, 0x351: 0x3793, + 0x352: 0x3715, 0x353: 0x3799, 0x356: 0x3727, 0x357: 0x37ab, + 0x358: 0xa000, 0x359: 0xa000, 0x35a: 0x3829, 0x35b: 0x382f, 0x35c: 0x3739, 0x35d: 0x37bd, + 0x35e: 0x373f, 0x35f: 0x37c3, 0x362: 0x374b, 0x363: 0x37cf, + 0x364: 0x3757, 0x365: 0x37db, 0x366: 0x3763, 0x367: 0x37e7, 0x368: 0xa000, 0x369: 0xa000, + 0x36a: 0x3835, 0x36b: 0x383b, 0x36c: 0x378d, 0x36d: 0x3811, 0x36e: 0x3769, 0x36f: 0x37ed, + 0x370: 0x3775, 0x371: 0x37f9, 0x372: 0x377b, 0x373: 0x37ff, 0x374: 0x3781, 0x375: 0x3805, + 0x378: 0x3787, 0x379: 0x380b, + // Block 0xe, offset 0x380 + 0x387: 0x1d61, + 0x391: 0x812d, + 0x392: 0x8132, 0x393: 0x8132, 0x394: 0x8132, 0x395: 0x8132, 0x396: 0x812d, 0x397: 0x8132, + 0x398: 0x8132, 0x399: 0x8132, 0x39a: 0x812e, 0x39b: 0x812d, 0x39c: 0x8132, 0x39d: 0x8132, + 0x39e: 0x8132, 0x39f: 0x8132, 0x3a0: 0x8132, 0x3a1: 0x8132, 0x3a2: 0x812d, 0x3a3: 0x812d, + 0x3a4: 0x812d, 0x3a5: 0x812d, 0x3a6: 0x812d, 0x3a7: 0x812d, 0x3a8: 0x8132, 0x3a9: 0x8132, + 0x3aa: 0x812d, 0x3ab: 0x8132, 0x3ac: 0x8132, 0x3ad: 0x812e, 0x3ae: 0x8131, 0x3af: 0x8132, + 0x3b0: 0x8105, 0x3b1: 0x8106, 0x3b2: 0x8107, 0x3b3: 0x8108, 0x3b4: 0x8109, 0x3b5: 0x810a, + 0x3b6: 0x810b, 0x3b7: 0x810c, 0x3b8: 0x810d, 0x3b9: 0x810e, 0x3ba: 0x810e, 0x3bb: 0x810f, + 0x3bc: 0x8110, 0x3bd: 0x8111, 0x3bf: 0x8112, + // Block 0xf, offset 0x3c0 + 0x3c8: 0xa000, 0x3ca: 0xa000, 0x3cb: 0x8116, + 0x3cc: 0x8117, 0x3cd: 0x8118, 0x3ce: 0x8119, 0x3cf: 0x811a, 0x3d0: 0x811b, 0x3d1: 0x811c, + 0x3d2: 0x811d, 0x3d3: 0x9932, 0x3d4: 0x9932, 0x3d5: 0x992d, 0x3d6: 0x812d, 0x3d7: 0x8132, + 0x3d8: 0x8132, 0x3d9: 0x8132, 0x3da: 0x8132, 0x3db: 0x8132, 0x3dc: 0x812d, 0x3dd: 0x8132, + 0x3de: 0x8132, 0x3df: 0x812d, + 0x3f0: 0x811e, 0x3f5: 0x1d84, + 0x3f6: 0x2013, 0x3f7: 0x204f, 0x3f8: 0x204a, + // Block 0x10, offset 0x400 + 0x405: 0xa000, + 0x406: 0x2d26, 0x407: 0xa000, 0x408: 0x2d2e, 0x409: 0xa000, 0x40a: 0x2d36, 0x40b: 0xa000, + 0x40c: 0x2d3e, 0x40d: 0xa000, 0x40e: 0x2d46, 0x411: 0xa000, + 0x412: 0x2d4e, + 0x434: 0x8102, 0x435: 0x9900, + 0x43a: 0xa000, 0x43b: 0x2d56, + 0x43c: 0xa000, 0x43d: 0x2d5e, 0x43e: 0xa000, 0x43f: 0xa000, + // Block 0x11, offset 0x440 + 0x440: 0x0069, 0x441: 0x006b, 0x442: 0x006f, 0x443: 0x0083, 0x444: 0x00f5, 0x445: 0x00f8, + 0x446: 0x0413, 0x447: 0x0085, 0x448: 0x0089, 0x449: 0x008b, 0x44a: 0x0104, 0x44b: 0x0107, + 0x44c: 0x010a, 0x44d: 0x008f, 0x44f: 0x0097, 0x450: 0x009b, 0x451: 0x00e0, + 0x452: 0x009f, 0x453: 0x00fe, 0x454: 0x0417, 0x455: 0x041b, 0x456: 0x00a1, 0x457: 0x00a9, + 0x458: 0x00ab, 0x459: 0x0423, 0x45a: 0x012b, 0x45b: 0x00ad, 0x45c: 0x0427, 0x45d: 0x01be, + 0x45e: 0x01c1, 0x45f: 0x01c4, 0x460: 0x01fa, 0x461: 0x01fd, 0x462: 0x0093, 0x463: 0x00a5, + 0x464: 0x00ab, 0x465: 0x00ad, 0x466: 0x01be, 0x467: 0x01c1, 0x468: 0x01eb, 0x469: 0x01fa, + 0x46a: 0x01fd, + 0x478: 0x020c, + // Block 0x12, offset 0x480 + 0x49b: 0x00fb, 0x49c: 0x0087, 0x49d: 0x0101, + 0x49e: 0x00d4, 0x49f: 0x010a, 0x4a0: 0x008d, 0x4a1: 0x010d, 0x4a2: 0x0110, 0x4a3: 0x0116, + 0x4a4: 0x011c, 0x4a5: 0x011f, 0x4a6: 0x0122, 0x4a7: 0x042b, 0x4a8: 0x016a, 0x4a9: 0x0128, + 0x4aa: 0x042f, 0x4ab: 0x016d, 0x4ac: 0x0131, 0x4ad: 0x012e, 0x4ae: 0x0134, 0x4af: 0x0137, + 0x4b0: 0x013a, 0x4b1: 0x013d, 0x4b2: 0x0140, 0x4b3: 0x014c, 0x4b4: 0x014f, 0x4b5: 0x00ec, + 0x4b6: 0x0152, 0x4b7: 0x0155, 0x4b8: 0x041f, 0x4b9: 0x0158, 0x4ba: 0x015b, 0x4bb: 0x00b5, + 0x4bc: 0x015e, 0x4bd: 0x0161, 0x4be: 0x0164, 0x4bf: 0x01d0, + // Block 0x13, offset 0x4c0 + 0x4c0: 0x8132, 0x4c1: 0x8132, 0x4c2: 0x812d, 0x4c3: 0x8132, 0x4c4: 0x8132, 0x4c5: 0x8132, + 0x4c6: 0x8132, 0x4c7: 0x8132, 0x4c8: 0x8132, 0x4c9: 0x8132, 0x4ca: 0x812d, 0x4cb: 0x8132, + 0x4cc: 0x8132, 0x4cd: 0x8135, 0x4ce: 0x812a, 0x4cf: 0x812d, 0x4d0: 0x8129, 0x4d1: 0x8132, + 0x4d2: 0x8132, 0x4d3: 0x8132, 0x4d4: 0x8132, 0x4d5: 0x8132, 0x4d6: 0x8132, 0x4d7: 0x8132, + 0x4d8: 0x8132, 0x4d9: 0x8132, 0x4da: 0x8132, 0x4db: 0x8132, 0x4dc: 0x8132, 0x4dd: 0x8132, + 0x4de: 0x8132, 0x4df: 0x8132, 0x4e0: 0x8132, 0x4e1: 0x8132, 0x4e2: 0x8132, 0x4e3: 0x8132, + 0x4e4: 0x8132, 0x4e5: 0x8132, 0x4e6: 0x8132, 0x4e7: 0x8132, 0x4e8: 0x8132, 0x4e9: 0x8132, + 0x4ea: 0x8132, 0x4eb: 0x8132, 0x4ec: 0x8132, 0x4ed: 0x8132, 0x4ee: 0x8132, 0x4ef: 0x8132, + 0x4f0: 0x8132, 0x4f1: 0x8132, 0x4f2: 0x8132, 0x4f3: 0x8132, 0x4f4: 0x8132, 0x4f5: 0x8132, + 0x4f6: 0x8133, 0x4f7: 0x8131, 0x4f8: 0x8131, 0x4f9: 0x812d, 0x4fb: 0x8132, + 0x4fc: 0x8134, 0x4fd: 0x812d, 0x4fe: 0x8132, 0x4ff: 0x812d, + // Block 0x14, offset 0x500 + 0x500: 0x2f97, 0x501: 0x32a3, 0x502: 0x2fa1, 0x503: 0x32ad, 0x504: 0x2fa6, 0x505: 0x32b2, + 0x506: 0x2fab, 0x507: 0x32b7, 0x508: 0x38cc, 0x509: 0x3a5b, 0x50a: 0x2fc4, 0x50b: 0x32d0, + 0x50c: 0x2fce, 0x50d: 0x32da, 0x50e: 0x2fdd, 0x50f: 0x32e9, 0x510: 0x2fd3, 0x511: 0x32df, + 0x512: 0x2fd8, 0x513: 0x32e4, 0x514: 0x38ef, 0x515: 0x3a7e, 0x516: 0x38f6, 0x517: 0x3a85, + 0x518: 0x3019, 0x519: 0x3325, 0x51a: 0x301e, 0x51b: 0x332a, 0x51c: 0x3904, 0x51d: 0x3a93, + 0x51e: 0x3023, 0x51f: 0x332f, 0x520: 0x3032, 0x521: 0x333e, 0x522: 0x3050, 0x523: 0x335c, + 0x524: 0x305f, 0x525: 0x336b, 0x526: 0x3055, 0x527: 0x3361, 0x528: 0x3064, 0x529: 0x3370, + 0x52a: 0x3069, 0x52b: 0x3375, 0x52c: 0x30af, 0x52d: 0x33bb, 0x52e: 0x390b, 0x52f: 0x3a9a, + 0x530: 0x30b9, 0x531: 0x33ca, 0x532: 0x30c3, 0x533: 0x33d4, 0x534: 0x30cd, 0x535: 0x33de, + 0x536: 0x46c4, 0x537: 0x4755, 0x538: 0x3912, 0x539: 0x3aa1, 0x53a: 0x30e6, 0x53b: 0x33f7, + 0x53c: 0x30e1, 0x53d: 0x33f2, 0x53e: 0x30eb, 0x53f: 0x33fc, + // Block 0x15, offset 0x540 + 0x540: 0x30f0, 0x541: 0x3401, 0x542: 0x30f5, 0x543: 0x3406, 0x544: 0x3109, 0x545: 0x341a, + 0x546: 0x3113, 0x547: 0x3424, 0x548: 0x3122, 0x549: 0x3433, 0x54a: 0x311d, 0x54b: 0x342e, + 0x54c: 0x3935, 0x54d: 0x3ac4, 0x54e: 0x3943, 0x54f: 0x3ad2, 0x550: 0x394a, 0x551: 0x3ad9, + 0x552: 0x3951, 0x553: 0x3ae0, 0x554: 0x314f, 0x555: 0x3460, 0x556: 0x3154, 0x557: 0x3465, + 0x558: 0x315e, 0x559: 0x346f, 0x55a: 0x46f1, 0x55b: 0x4782, 0x55c: 0x3997, 0x55d: 0x3b26, + 0x55e: 0x3177, 0x55f: 0x3488, 0x560: 0x3181, 0x561: 0x3492, 0x562: 0x4700, 0x563: 0x4791, + 0x564: 0x399e, 0x565: 0x3b2d, 0x566: 0x39a5, 0x567: 0x3b34, 0x568: 0x39ac, 0x569: 0x3b3b, + 0x56a: 0x3190, 0x56b: 0x34a1, 0x56c: 0x319a, 0x56d: 0x34b0, 0x56e: 0x31ae, 0x56f: 0x34c4, + 0x570: 0x31a9, 0x571: 0x34bf, 0x572: 0x31ea, 0x573: 0x3500, 0x574: 0x31f9, 0x575: 0x350f, + 0x576: 0x31f4, 0x577: 0x350a, 0x578: 0x39b3, 0x579: 0x3b42, 0x57a: 0x39ba, 0x57b: 0x3b49, + 0x57c: 0x31fe, 0x57d: 0x3514, 0x57e: 0x3203, 0x57f: 0x3519, + // Block 0x16, offset 0x580 + 0x580: 0x3208, 0x581: 0x351e, 0x582: 0x320d, 0x583: 0x3523, 0x584: 0x321c, 0x585: 0x3532, + 0x586: 0x3217, 0x587: 0x352d, 0x588: 0x3221, 0x589: 0x353c, 0x58a: 0x3226, 0x58b: 0x3541, + 0x58c: 0x322b, 0x58d: 0x3546, 0x58e: 0x3249, 0x58f: 0x3564, 0x590: 0x3262, 0x591: 0x3582, + 0x592: 0x3271, 0x593: 0x3591, 0x594: 0x3276, 0x595: 0x3596, 0x596: 0x337a, 0x597: 0x34a6, + 0x598: 0x3537, 0x599: 0x3573, 0x59a: 0x1be0, 0x59b: 0x42d7, + 0x5a0: 0x46a1, 0x5a1: 0x4732, 0x5a2: 0x2f83, 0x5a3: 0x328f, + 0x5a4: 0x3878, 0x5a5: 0x3a07, 0x5a6: 0x3871, 0x5a7: 0x3a00, 0x5a8: 0x3886, 0x5a9: 0x3a15, + 0x5aa: 0x387f, 0x5ab: 0x3a0e, 0x5ac: 0x38be, 0x5ad: 0x3a4d, 0x5ae: 0x3894, 0x5af: 0x3a23, + 0x5b0: 0x388d, 0x5b1: 0x3a1c, 0x5b2: 0x38a2, 0x5b3: 0x3a31, 0x5b4: 0x389b, 0x5b5: 0x3a2a, + 0x5b6: 0x38c5, 0x5b7: 0x3a54, 0x5b8: 0x46b5, 0x5b9: 0x4746, 0x5ba: 0x3000, 0x5bb: 0x330c, + 0x5bc: 0x2fec, 0x5bd: 0x32f8, 0x5be: 0x38da, 0x5bf: 0x3a69, + // Block 0x17, offset 0x5c0 + 0x5c0: 0x38d3, 0x5c1: 0x3a62, 0x5c2: 0x38e8, 0x5c3: 0x3a77, 0x5c4: 0x38e1, 0x5c5: 0x3a70, + 0x5c6: 0x38fd, 0x5c7: 0x3a8c, 0x5c8: 0x3091, 0x5c9: 0x339d, 0x5ca: 0x30a5, 0x5cb: 0x33b1, + 0x5cc: 0x46e7, 0x5cd: 0x4778, 0x5ce: 0x3136, 0x5cf: 0x3447, 0x5d0: 0x3920, 0x5d1: 0x3aaf, + 0x5d2: 0x3919, 0x5d3: 0x3aa8, 0x5d4: 0x392e, 0x5d5: 0x3abd, 0x5d6: 0x3927, 0x5d7: 0x3ab6, + 0x5d8: 0x3989, 0x5d9: 0x3b18, 0x5da: 0x396d, 0x5db: 0x3afc, 0x5dc: 0x3966, 0x5dd: 0x3af5, + 0x5de: 0x397b, 0x5df: 0x3b0a, 0x5e0: 0x3974, 0x5e1: 0x3b03, 0x5e2: 0x3982, 0x5e3: 0x3b11, + 0x5e4: 0x31e5, 0x5e5: 0x34fb, 0x5e6: 0x31c7, 0x5e7: 0x34dd, 0x5e8: 0x39e4, 0x5e9: 0x3b73, + 0x5ea: 0x39dd, 0x5eb: 0x3b6c, 0x5ec: 0x39f2, 0x5ed: 0x3b81, 0x5ee: 0x39eb, 0x5ef: 0x3b7a, + 0x5f0: 0x39f9, 0x5f1: 0x3b88, 0x5f2: 0x3230, 0x5f3: 0x354b, 0x5f4: 0x3258, 0x5f5: 0x3578, + 0x5f6: 0x3253, 0x5f7: 0x356e, 0x5f8: 0x323f, 0x5f9: 0x355a, + // Block 0x18, offset 0x600 + 0x600: 0x4804, 0x601: 0x480a, 0x602: 0x491e, 0x603: 0x4936, 0x604: 0x4926, 0x605: 0x493e, + 0x606: 0x492e, 0x607: 0x4946, 0x608: 0x47aa, 0x609: 0x47b0, 0x60a: 0x488e, 0x60b: 0x48a6, + 0x60c: 0x4896, 0x60d: 0x48ae, 0x60e: 0x489e, 0x60f: 0x48b6, 0x610: 0x4816, 0x611: 0x481c, + 0x612: 0x3db8, 0x613: 0x3dc8, 0x614: 0x3dc0, 0x615: 0x3dd0, + 0x618: 0x47b6, 0x619: 0x47bc, 0x61a: 0x3ce8, 0x61b: 0x3cf8, 0x61c: 0x3cf0, 0x61d: 0x3d00, + 0x620: 0x482e, 0x621: 0x4834, 0x622: 0x494e, 0x623: 0x4966, + 0x624: 0x4956, 0x625: 0x496e, 0x626: 0x495e, 0x627: 0x4976, 0x628: 0x47c2, 0x629: 0x47c8, + 0x62a: 0x48be, 0x62b: 0x48d6, 0x62c: 0x48c6, 0x62d: 0x48de, 0x62e: 0x48ce, 0x62f: 0x48e6, + 0x630: 0x4846, 0x631: 0x484c, 0x632: 0x3e18, 0x633: 0x3e30, 0x634: 0x3e20, 0x635: 0x3e38, + 0x636: 0x3e28, 0x637: 0x3e40, 0x638: 0x47ce, 0x639: 0x47d4, 0x63a: 0x3d18, 0x63b: 0x3d30, + 0x63c: 0x3d20, 0x63d: 0x3d38, 0x63e: 0x3d28, 0x63f: 0x3d40, + // Block 0x19, offset 0x640 + 0x640: 0x4852, 0x641: 0x4858, 0x642: 0x3e48, 0x643: 0x3e58, 0x644: 0x3e50, 0x645: 0x3e60, + 0x648: 0x47da, 0x649: 0x47e0, 0x64a: 0x3d48, 0x64b: 0x3d58, + 0x64c: 0x3d50, 0x64d: 0x3d60, 0x650: 0x4864, 0x651: 0x486a, + 0x652: 0x3e80, 0x653: 0x3e98, 0x654: 0x3e88, 0x655: 0x3ea0, 0x656: 0x3e90, 0x657: 0x3ea8, + 0x659: 0x47e6, 0x65b: 0x3d68, 0x65d: 0x3d70, + 0x65f: 0x3d78, 0x660: 0x487c, 0x661: 0x4882, 0x662: 0x497e, 0x663: 0x4996, + 0x664: 0x4986, 0x665: 0x499e, 0x666: 0x498e, 0x667: 0x49a6, 0x668: 0x47ec, 0x669: 0x47f2, + 0x66a: 0x48ee, 0x66b: 0x4906, 0x66c: 0x48f6, 0x66d: 0x490e, 0x66e: 0x48fe, 0x66f: 0x4916, + 0x670: 0x47f8, 0x671: 0x431e, 0x672: 0x3691, 0x673: 0x4324, 0x674: 0x4822, 0x675: 0x432a, + 0x676: 0x36a3, 0x677: 0x4330, 0x678: 0x36c1, 0x679: 0x4336, 0x67a: 0x36d9, 0x67b: 0x433c, + 0x67c: 0x4870, 0x67d: 0x4342, + // Block 0x1a, offset 0x680 + 0x680: 0x3da0, 0x681: 0x3da8, 0x682: 0x4184, 0x683: 0x41a2, 0x684: 0x418e, 0x685: 0x41ac, + 0x686: 0x4198, 0x687: 0x41b6, 0x688: 0x3cd8, 0x689: 0x3ce0, 0x68a: 0x40d0, 0x68b: 0x40ee, + 0x68c: 0x40da, 0x68d: 0x40f8, 0x68e: 0x40e4, 0x68f: 0x4102, 0x690: 0x3de8, 0x691: 0x3df0, + 0x692: 0x41c0, 0x693: 0x41de, 0x694: 0x41ca, 0x695: 0x41e8, 0x696: 0x41d4, 0x697: 0x41f2, + 0x698: 0x3d08, 0x699: 0x3d10, 0x69a: 0x410c, 0x69b: 0x412a, 0x69c: 0x4116, 0x69d: 0x4134, + 0x69e: 0x4120, 0x69f: 0x413e, 0x6a0: 0x3ec0, 0x6a1: 0x3ec8, 0x6a2: 0x41fc, 0x6a3: 0x421a, + 0x6a4: 0x4206, 0x6a5: 0x4224, 0x6a6: 0x4210, 0x6a7: 0x422e, 0x6a8: 0x3d80, 0x6a9: 0x3d88, + 0x6aa: 0x4148, 0x6ab: 0x4166, 0x6ac: 0x4152, 0x6ad: 0x4170, 0x6ae: 0x415c, 0x6af: 0x417a, + 0x6b0: 0x3685, 0x6b1: 0x367f, 0x6b2: 0x3d90, 0x6b3: 0x368b, 0x6b4: 0x3d98, + 0x6b6: 0x4810, 0x6b7: 0x3db0, 0x6b8: 0x35f5, 0x6b9: 0x35ef, 0x6ba: 0x35e3, 0x6bb: 0x42ee, + 0x6bc: 0x35fb, 0x6bd: 0x4287, 0x6be: 0x01d3, 0x6bf: 0x4287, + // Block 0x1b, offset 0x6c0 + 0x6c0: 0x42a0, 0x6c1: 0x4482, 0x6c2: 0x3dd8, 0x6c3: 0x369d, 0x6c4: 0x3de0, + 0x6c6: 0x483a, 0x6c7: 0x3df8, 0x6c8: 0x3601, 0x6c9: 0x42f4, 0x6ca: 0x360d, 0x6cb: 0x42fa, + 0x6cc: 0x3619, 0x6cd: 0x4489, 0x6ce: 0x4490, 0x6cf: 0x4497, 0x6d0: 0x36b5, 0x6d1: 0x36af, + 0x6d2: 0x3e00, 0x6d3: 0x44e4, 0x6d6: 0x36bb, 0x6d7: 0x3e10, + 0x6d8: 0x3631, 0x6d9: 0x362b, 0x6da: 0x361f, 0x6db: 0x4300, 0x6dd: 0x449e, + 0x6de: 0x44a5, 0x6df: 0x44ac, 0x6e0: 0x36eb, 0x6e1: 0x36e5, 0x6e2: 0x3e68, 0x6e3: 0x44ec, + 0x6e4: 0x36cd, 0x6e5: 0x36d3, 0x6e6: 0x36f1, 0x6e7: 0x3e78, 0x6e8: 0x3661, 0x6e9: 0x365b, + 0x6ea: 0x364f, 0x6eb: 0x430c, 0x6ec: 0x3649, 0x6ed: 0x4474, 0x6ee: 0x447b, 0x6ef: 0x0081, + 0x6f2: 0x3eb0, 0x6f3: 0x36f7, 0x6f4: 0x3eb8, + 0x6f6: 0x4888, 0x6f7: 0x3ed0, 0x6f8: 0x363d, 0x6f9: 0x4306, 0x6fa: 0x366d, 0x6fb: 0x4318, + 0x6fc: 0x3679, 0x6fd: 0x425a, 0x6fe: 0x428c, + // Block 0x1c, offset 0x700 + 0x700: 0x1bd8, 0x701: 0x1bdc, 0x702: 0x0047, 0x703: 0x1c54, 0x705: 0x1be8, + 0x706: 0x1bec, 0x707: 0x00e9, 0x709: 0x1c58, 0x70a: 0x008f, 0x70b: 0x0051, + 0x70c: 0x0051, 0x70d: 0x0051, 0x70e: 0x0091, 0x70f: 0x00da, 0x710: 0x0053, 0x711: 0x0053, + 0x712: 0x0059, 0x713: 0x0099, 0x715: 0x005d, 0x716: 0x198d, + 0x719: 0x0061, 0x71a: 0x0063, 0x71b: 0x0065, 0x71c: 0x0065, 0x71d: 0x0065, + 0x720: 0x199f, 0x721: 0x1bc8, 0x722: 0x19a8, + 0x724: 0x0075, 0x726: 0x01b8, 0x728: 0x0075, + 0x72a: 0x0057, 0x72b: 0x42d2, 0x72c: 0x0045, 0x72d: 0x0047, 0x72f: 0x008b, + 0x730: 0x004b, 0x731: 0x004d, 0x733: 0x005b, 0x734: 0x009f, 0x735: 0x0215, + 0x736: 0x0218, 0x737: 0x021b, 0x738: 0x021e, 0x739: 0x0093, 0x73b: 0x1b98, + 0x73c: 0x01e8, 0x73d: 0x01c1, 0x73e: 0x0179, 0x73f: 0x01a0, + // Block 0x1d, offset 0x740 + 0x740: 0x0463, 0x745: 0x0049, + 0x746: 0x0089, 0x747: 0x008b, 0x748: 0x0093, 0x749: 0x0095, + 0x750: 0x222e, 0x751: 0x223a, + 0x752: 0x22ee, 0x753: 0x2216, 0x754: 0x229a, 0x755: 0x2222, 0x756: 0x22a0, 0x757: 0x22b8, + 0x758: 0x22c4, 0x759: 0x2228, 0x75a: 0x22ca, 0x75b: 0x2234, 0x75c: 0x22be, 0x75d: 0x22d0, + 0x75e: 0x22d6, 0x75f: 0x1cbc, 0x760: 0x0053, 0x761: 0x195a, 0x762: 0x1ba4, 0x763: 0x1963, + 0x764: 0x006d, 0x765: 0x19ab, 0x766: 0x1bd0, 0x767: 0x1d48, 0x768: 0x1966, 0x769: 0x0071, + 0x76a: 0x19b7, 0x76b: 0x1bd4, 0x76c: 0x0059, 0x76d: 0x0047, 0x76e: 0x0049, 0x76f: 0x005b, + 0x770: 0x0093, 0x771: 0x19e4, 0x772: 0x1c18, 0x773: 0x19ed, 0x774: 0x00ad, 0x775: 0x1a62, + 0x776: 0x1c4c, 0x777: 0x1d5c, 0x778: 0x19f0, 0x779: 0x00b1, 0x77a: 0x1a65, 0x77b: 0x1c50, + 0x77c: 0x0099, 0x77d: 0x0087, 0x77e: 0x0089, 0x77f: 0x009b, + // Block 0x1e, offset 0x780 + 0x781: 0x3c06, 0x783: 0xa000, 0x784: 0x3c0d, 0x785: 0xa000, + 0x787: 0x3c14, 0x788: 0xa000, 0x789: 0x3c1b, + 0x78d: 0xa000, + 0x7a0: 0x2f65, 0x7a1: 0xa000, 0x7a2: 0x3c29, + 0x7a4: 0xa000, 0x7a5: 0xa000, + 0x7ad: 0x3c22, 0x7ae: 0x2f60, 0x7af: 0x2f6a, + 0x7b0: 0x3c30, 0x7b1: 0x3c37, 0x7b2: 0xa000, 0x7b3: 0xa000, 0x7b4: 0x3c3e, 0x7b5: 0x3c45, + 0x7b6: 0xa000, 0x7b7: 0xa000, 0x7b8: 0x3c4c, 0x7b9: 0x3c53, 0x7ba: 0xa000, 0x7bb: 0xa000, + 0x7bc: 0xa000, 0x7bd: 0xa000, + // Block 0x1f, offset 0x7c0 + 0x7c0: 0x3c5a, 0x7c1: 0x3c61, 0x7c2: 0xa000, 0x7c3: 0xa000, 0x7c4: 0x3c76, 0x7c5: 0x3c7d, + 0x7c6: 0xa000, 0x7c7: 0xa000, 0x7c8: 0x3c84, 0x7c9: 0x3c8b, + 0x7d1: 0xa000, + 0x7d2: 0xa000, + 0x7e2: 0xa000, + 0x7e8: 0xa000, 0x7e9: 0xa000, + 0x7eb: 0xa000, 0x7ec: 0x3ca0, 0x7ed: 0x3ca7, 0x7ee: 0x3cae, 0x7ef: 0x3cb5, + 0x7f2: 0xa000, 0x7f3: 0xa000, 0x7f4: 0xa000, 0x7f5: 0xa000, + // Block 0x20, offset 0x800 + 0x820: 0x0023, 0x821: 0x0025, 0x822: 0x0027, 0x823: 0x0029, + 0x824: 0x002b, 0x825: 0x002d, 0x826: 0x002f, 0x827: 0x0031, 0x828: 0x0033, 0x829: 0x1882, + 0x82a: 0x1885, 0x82b: 0x1888, 0x82c: 0x188b, 0x82d: 0x188e, 0x82e: 0x1891, 0x82f: 0x1894, + 0x830: 0x1897, 0x831: 0x189a, 0x832: 0x189d, 0x833: 0x18a6, 0x834: 0x1a68, 0x835: 0x1a6c, + 0x836: 0x1a70, 0x837: 0x1a74, 0x838: 0x1a78, 0x839: 0x1a7c, 0x83a: 0x1a80, 0x83b: 0x1a84, + 0x83c: 0x1a88, 0x83d: 0x1c80, 0x83e: 0x1c85, 0x83f: 0x1c8a, + // Block 0x21, offset 0x840 + 0x840: 0x1c8f, 0x841: 0x1c94, 0x842: 0x1c99, 0x843: 0x1c9e, 0x844: 0x1ca3, 0x845: 0x1ca8, + 0x846: 0x1cad, 0x847: 0x1cb2, 0x848: 0x187f, 0x849: 0x18a3, 0x84a: 0x18c7, 0x84b: 0x18eb, + 0x84c: 0x190f, 0x84d: 0x1918, 0x84e: 0x191e, 0x84f: 0x1924, 0x850: 0x192a, 0x851: 0x1b60, + 0x852: 0x1b64, 0x853: 0x1b68, 0x854: 0x1b6c, 0x855: 0x1b70, 0x856: 0x1b74, 0x857: 0x1b78, + 0x858: 0x1b7c, 0x859: 0x1b80, 0x85a: 0x1b84, 0x85b: 0x1b88, 0x85c: 0x1af4, 0x85d: 0x1af8, + 0x85e: 0x1afc, 0x85f: 0x1b00, 0x860: 0x1b04, 0x861: 0x1b08, 0x862: 0x1b0c, 0x863: 0x1b10, + 0x864: 0x1b14, 0x865: 0x1b18, 0x866: 0x1b1c, 0x867: 0x1b20, 0x868: 0x1b24, 0x869: 0x1b28, + 0x86a: 0x1b2c, 0x86b: 0x1b30, 0x86c: 0x1b34, 0x86d: 0x1b38, 0x86e: 0x1b3c, 0x86f: 0x1b40, + 0x870: 0x1b44, 0x871: 0x1b48, 0x872: 0x1b4c, 0x873: 0x1b50, 0x874: 0x1b54, 0x875: 0x1b58, + 0x876: 0x0043, 0x877: 0x0045, 0x878: 0x0047, 0x879: 0x0049, 0x87a: 0x004b, 0x87b: 0x004d, + 0x87c: 0x004f, 0x87d: 0x0051, 0x87e: 0x0053, 0x87f: 0x0055, + // Block 0x22, offset 0x880 + 0x880: 0x06bf, 0x881: 0x06e3, 0x882: 0x06ef, 0x883: 0x06ff, 0x884: 0x0707, 0x885: 0x0713, + 0x886: 0x071b, 0x887: 0x0723, 0x888: 0x072f, 0x889: 0x0783, 0x88a: 0x079b, 0x88b: 0x07ab, + 0x88c: 0x07bb, 0x88d: 0x07cb, 0x88e: 0x07db, 0x88f: 0x07fb, 0x890: 0x07ff, 0x891: 0x0803, + 0x892: 0x0837, 0x893: 0x085f, 0x894: 0x086f, 0x895: 0x0877, 0x896: 0x087b, 0x897: 0x0887, + 0x898: 0x08a3, 0x899: 0x08a7, 0x89a: 0x08bf, 0x89b: 0x08c3, 0x89c: 0x08cb, 0x89d: 0x08db, + 0x89e: 0x0977, 0x89f: 0x098b, 0x8a0: 0x09cb, 0x8a1: 0x09df, 0x8a2: 0x09e7, 0x8a3: 0x09eb, + 0x8a4: 0x09fb, 0x8a5: 0x0a17, 0x8a6: 0x0a43, 0x8a7: 0x0a4f, 0x8a8: 0x0a6f, 0x8a9: 0x0a7b, + 0x8aa: 0x0a7f, 0x8ab: 0x0a83, 0x8ac: 0x0a9b, 0x8ad: 0x0a9f, 0x8ae: 0x0acb, 0x8af: 0x0ad7, + 0x8b0: 0x0adf, 0x8b1: 0x0ae7, 0x8b2: 0x0af7, 0x8b3: 0x0aff, 0x8b4: 0x0b07, 0x8b5: 0x0b33, + 0x8b6: 0x0b37, 0x8b7: 0x0b3f, 0x8b8: 0x0b43, 0x8b9: 0x0b4b, 0x8ba: 0x0b53, 0x8bb: 0x0b63, + 0x8bc: 0x0b7f, 0x8bd: 0x0bf7, 0x8be: 0x0c0b, 0x8bf: 0x0c0f, + // Block 0x23, offset 0x8c0 + 0x8c0: 0x0c8f, 0x8c1: 0x0c93, 0x8c2: 0x0ca7, 0x8c3: 0x0cab, 0x8c4: 0x0cb3, 0x8c5: 0x0cbb, + 0x8c6: 0x0cc3, 0x8c7: 0x0ccf, 0x8c8: 0x0cf7, 0x8c9: 0x0d07, 0x8ca: 0x0d1b, 0x8cb: 0x0d8b, + 0x8cc: 0x0d97, 0x8cd: 0x0da7, 0x8ce: 0x0db3, 0x8cf: 0x0dbf, 0x8d0: 0x0dc7, 0x8d1: 0x0dcb, + 0x8d2: 0x0dcf, 0x8d3: 0x0dd3, 0x8d4: 0x0dd7, 0x8d5: 0x0e8f, 0x8d6: 0x0ed7, 0x8d7: 0x0ee3, + 0x8d8: 0x0ee7, 0x8d9: 0x0eeb, 0x8da: 0x0eef, 0x8db: 0x0ef7, 0x8dc: 0x0efb, 0x8dd: 0x0f0f, + 0x8de: 0x0f2b, 0x8df: 0x0f33, 0x8e0: 0x0f73, 0x8e1: 0x0f77, 0x8e2: 0x0f7f, 0x8e3: 0x0f83, + 0x8e4: 0x0f8b, 0x8e5: 0x0f8f, 0x8e6: 0x0fb3, 0x8e7: 0x0fb7, 0x8e8: 0x0fd3, 0x8e9: 0x0fd7, + 0x8ea: 0x0fdb, 0x8eb: 0x0fdf, 0x8ec: 0x0ff3, 0x8ed: 0x1017, 0x8ee: 0x101b, 0x8ef: 0x101f, + 0x8f0: 0x1043, 0x8f1: 0x1083, 0x8f2: 0x1087, 0x8f3: 0x10a7, 0x8f4: 0x10b7, 0x8f5: 0x10bf, + 0x8f6: 0x10df, 0x8f7: 0x1103, 0x8f8: 0x1147, 0x8f9: 0x114f, 0x8fa: 0x1163, 0x8fb: 0x116f, + 0x8fc: 0x1177, 0x8fd: 0x117f, 0x8fe: 0x1183, 0x8ff: 0x1187, + // Block 0x24, offset 0x900 + 0x900: 0x119f, 0x901: 0x11a3, 0x902: 0x11bf, 0x903: 0x11c7, 0x904: 0x11cf, 0x905: 0x11d3, + 0x906: 0x11df, 0x907: 0x11e7, 0x908: 0x11eb, 0x909: 0x11ef, 0x90a: 0x11f7, 0x90b: 0x11fb, + 0x90c: 0x129b, 0x90d: 0x12af, 0x90e: 0x12e3, 0x90f: 0x12e7, 0x910: 0x12ef, 0x911: 0x131b, + 0x912: 0x1323, 0x913: 0x132b, 0x914: 0x1333, 0x915: 0x136f, 0x916: 0x1373, 0x917: 0x137b, + 0x918: 0x137f, 0x919: 0x1383, 0x91a: 0x13af, 0x91b: 0x13b3, 0x91c: 0x13bb, 0x91d: 0x13cf, + 0x91e: 0x13d3, 0x91f: 0x13ef, 0x920: 0x13f7, 0x921: 0x13fb, 0x922: 0x141f, 0x923: 0x143f, + 0x924: 0x1453, 0x925: 0x1457, 0x926: 0x145f, 0x927: 0x148b, 0x928: 0x148f, 0x929: 0x149f, + 0x92a: 0x14c3, 0x92b: 0x14cf, 0x92c: 0x14df, 0x92d: 0x14f7, 0x92e: 0x14ff, 0x92f: 0x1503, + 0x930: 0x1507, 0x931: 0x150b, 0x932: 0x1517, 0x933: 0x151b, 0x934: 0x1523, 0x935: 0x153f, + 0x936: 0x1543, 0x937: 0x1547, 0x938: 0x155f, 0x939: 0x1563, 0x93a: 0x156b, 0x93b: 0x157f, + 0x93c: 0x1583, 0x93d: 0x1587, 0x93e: 0x158f, 0x93f: 0x1593, + // Block 0x25, offset 0x940 + 0x946: 0xa000, 0x94b: 0xa000, + 0x94c: 0x3f08, 0x94d: 0xa000, 0x94e: 0x3f10, 0x94f: 0xa000, 0x950: 0x3f18, 0x951: 0xa000, + 0x952: 0x3f20, 0x953: 0xa000, 0x954: 0x3f28, 0x955: 0xa000, 0x956: 0x3f30, 0x957: 0xa000, + 0x958: 0x3f38, 0x959: 0xa000, 0x95a: 0x3f40, 0x95b: 0xa000, 0x95c: 0x3f48, 0x95d: 0xa000, + 0x95e: 0x3f50, 0x95f: 0xa000, 0x960: 0x3f58, 0x961: 0xa000, 0x962: 0x3f60, + 0x964: 0xa000, 0x965: 0x3f68, 0x966: 0xa000, 0x967: 0x3f70, 0x968: 0xa000, 0x969: 0x3f78, + 0x96f: 0xa000, + 0x970: 0x3f80, 0x971: 0x3f88, 0x972: 0xa000, 0x973: 0x3f90, 0x974: 0x3f98, 0x975: 0xa000, + 0x976: 0x3fa0, 0x977: 0x3fa8, 0x978: 0xa000, 0x979: 0x3fb0, 0x97a: 0x3fb8, 0x97b: 0xa000, + 0x97c: 0x3fc0, 0x97d: 0x3fc8, + // Block 0x26, offset 0x980 + 0x994: 0x3f00, + 0x999: 0x9903, 0x99a: 0x9903, 0x99b: 0x42dc, 0x99c: 0x42e2, 0x99d: 0xa000, + 0x99e: 0x3fd0, 0x99f: 0x26b4, + 0x9a6: 0xa000, + 0x9ab: 0xa000, 0x9ac: 0x3fe0, 0x9ad: 0xa000, 0x9ae: 0x3fe8, 0x9af: 0xa000, + 0x9b0: 0x3ff0, 0x9b1: 0xa000, 0x9b2: 0x3ff8, 0x9b3: 0xa000, 0x9b4: 0x4000, 0x9b5: 0xa000, + 0x9b6: 0x4008, 0x9b7: 0xa000, 0x9b8: 0x4010, 0x9b9: 0xa000, 0x9ba: 0x4018, 0x9bb: 0xa000, + 0x9bc: 0x4020, 0x9bd: 0xa000, 0x9be: 0x4028, 0x9bf: 0xa000, + // Block 0x27, offset 0x9c0 + 0x9c0: 0x4030, 0x9c1: 0xa000, 0x9c2: 0x4038, 0x9c4: 0xa000, 0x9c5: 0x4040, + 0x9c6: 0xa000, 0x9c7: 0x4048, 0x9c8: 0xa000, 0x9c9: 0x4050, + 0x9cf: 0xa000, 0x9d0: 0x4058, 0x9d1: 0x4060, + 0x9d2: 0xa000, 0x9d3: 0x4068, 0x9d4: 0x4070, 0x9d5: 0xa000, 0x9d6: 0x4078, 0x9d7: 0x4080, + 0x9d8: 0xa000, 0x9d9: 0x4088, 0x9da: 0x4090, 0x9db: 0xa000, 0x9dc: 0x4098, 0x9dd: 0x40a0, + 0x9ef: 0xa000, + 0x9f0: 0xa000, 0x9f1: 0xa000, 0x9f2: 0xa000, 0x9f4: 0x3fd8, + 0x9f7: 0x40a8, 0x9f8: 0x40b0, 0x9f9: 0x40b8, 0x9fa: 0x40c0, + 0x9fd: 0xa000, 0x9fe: 0x40c8, 0x9ff: 0x26c9, + // Block 0x28, offset 0xa00 + 0xa00: 0x0367, 0xa01: 0x032b, 0xa02: 0x032f, 0xa03: 0x0333, 0xa04: 0x037b, 0xa05: 0x0337, + 0xa06: 0x033b, 0xa07: 0x033f, 0xa08: 0x0343, 0xa09: 0x0347, 0xa0a: 0x034b, 0xa0b: 0x034f, + 0xa0c: 0x0353, 0xa0d: 0x0357, 0xa0e: 0x035b, 0xa0f: 0x49bd, 0xa10: 0x49c3, 0xa11: 0x49c9, + 0xa12: 0x49cf, 0xa13: 0x49d5, 0xa14: 0x49db, 0xa15: 0x49e1, 0xa16: 0x49e7, 0xa17: 0x49ed, + 0xa18: 0x49f3, 0xa19: 0x49f9, 0xa1a: 0x49ff, 0xa1b: 0x4a05, 0xa1c: 0x4a0b, 0xa1d: 0x4a11, + 0xa1e: 0x4a17, 0xa1f: 0x4a1d, 0xa20: 0x4a23, 0xa21: 0x4a29, 0xa22: 0x4a2f, 0xa23: 0x4a35, + 0xa24: 0x03c3, 0xa25: 0x035f, 0xa26: 0x0363, 0xa27: 0x03e7, 0xa28: 0x03eb, 0xa29: 0x03ef, + 0xa2a: 0x03f3, 0xa2b: 0x03f7, 0xa2c: 0x03fb, 0xa2d: 0x03ff, 0xa2e: 0x036b, 0xa2f: 0x0403, + 0xa30: 0x0407, 0xa31: 0x036f, 0xa32: 0x0373, 0xa33: 0x0377, 0xa34: 0x037f, 0xa35: 0x0383, + 0xa36: 0x0387, 0xa37: 0x038b, 0xa38: 0x038f, 0xa39: 0x0393, 0xa3a: 0x0397, 0xa3b: 0x039b, + 0xa3c: 0x039f, 0xa3d: 0x03a3, 0xa3e: 0x03a7, 0xa3f: 0x03ab, + // Block 0x29, offset 0xa40 + 0xa40: 0x03af, 0xa41: 0x03b3, 0xa42: 0x040b, 0xa43: 0x040f, 0xa44: 0x03b7, 0xa45: 0x03bb, + 0xa46: 0x03bf, 0xa47: 0x03c7, 0xa48: 0x03cb, 0xa49: 0x03cf, 0xa4a: 0x03d3, 0xa4b: 0x03d7, + 0xa4c: 0x03db, 0xa4d: 0x03df, 0xa4e: 0x03e3, + 0xa52: 0x06bf, 0xa53: 0x071b, 0xa54: 0x06cb, 0xa55: 0x097b, 0xa56: 0x06cf, 0xa57: 0x06e7, + 0xa58: 0x06d3, 0xa59: 0x0f93, 0xa5a: 0x0707, 0xa5b: 0x06db, 0xa5c: 0x06c3, 0xa5d: 0x09ff, + 0xa5e: 0x098f, 0xa5f: 0x072f, + // Block 0x2a, offset 0xa80 + 0xa80: 0x2054, 0xa81: 0x205a, 0xa82: 0x2060, 0xa83: 0x2066, 0xa84: 0x206c, 0xa85: 0x2072, + 0xa86: 0x2078, 0xa87: 0x207e, 0xa88: 0x2084, 0xa89: 0x208a, 0xa8a: 0x2090, 0xa8b: 0x2096, + 0xa8c: 0x209c, 0xa8d: 0x20a2, 0xa8e: 0x2726, 0xa8f: 0x272f, 0xa90: 0x2738, 0xa91: 0x2741, + 0xa92: 0x274a, 0xa93: 0x2753, 0xa94: 0x275c, 0xa95: 0x2765, 0xa96: 0x276e, 0xa97: 0x2780, + 0xa98: 0x2789, 0xa99: 0x2792, 0xa9a: 0x279b, 0xa9b: 0x27a4, 0xa9c: 0x2777, 0xa9d: 0x2bac, + 0xa9e: 0x2aed, 0xaa0: 0x20a8, 0xaa1: 0x20c0, 0xaa2: 0x20b4, 0xaa3: 0x2108, + 0xaa4: 0x20c6, 0xaa5: 0x20e4, 0xaa6: 0x20ae, 0xaa7: 0x20de, 0xaa8: 0x20ba, 0xaa9: 0x20f0, + 0xaaa: 0x2120, 0xaab: 0x213e, 0xaac: 0x2138, 0xaad: 0x212c, 0xaae: 0x217a, 0xaaf: 0x210e, + 0xab0: 0x211a, 0xab1: 0x2132, 0xab2: 0x2126, 0xab3: 0x2150, 0xab4: 0x20fc, 0xab5: 0x2144, + 0xab6: 0x216e, 0xab7: 0x2156, 0xab8: 0x20ea, 0xab9: 0x20cc, 0xaba: 0x2102, 0xabb: 0x2114, + 0xabc: 0x214a, 0xabd: 0x20d2, 0xabe: 0x2174, 0xabf: 0x20f6, + // Block 0x2b, offset 0xac0 + 0xac0: 0x215c, 0xac1: 0x20d8, 0xac2: 0x2162, 0xac3: 0x2168, 0xac4: 0x092f, 0xac5: 0x0b03, + 0xac6: 0x0ca7, 0xac7: 0x10c7, + 0xad0: 0x1bc4, 0xad1: 0x18a9, + 0xad2: 0x18ac, 0xad3: 0x18af, 0xad4: 0x18b2, 0xad5: 0x18b5, 0xad6: 0x18b8, 0xad7: 0x18bb, + 0xad8: 0x18be, 0xad9: 0x18c1, 0xada: 0x18ca, 0xadb: 0x18cd, 0xadc: 0x18d0, 0xadd: 0x18d3, + 0xade: 0x18d6, 0xadf: 0x18d9, 0xae0: 0x0313, 0xae1: 0x031b, 0xae2: 0x031f, 0xae3: 0x0327, + 0xae4: 0x032b, 0xae5: 0x032f, 0xae6: 0x0337, 0xae7: 0x033f, 0xae8: 0x0343, 0xae9: 0x034b, + 0xaea: 0x034f, 0xaeb: 0x0353, 0xaec: 0x0357, 0xaed: 0x035b, 0xaee: 0x2e18, 0xaef: 0x2e20, + 0xaf0: 0x2e28, 0xaf1: 0x2e30, 0xaf2: 0x2e38, 0xaf3: 0x2e40, 0xaf4: 0x2e48, 0xaf5: 0x2e50, + 0xaf6: 0x2e60, 0xaf7: 0x2e68, 0xaf8: 0x2e70, 0xaf9: 0x2e78, 0xafa: 0x2e80, 0xafb: 0x2e88, + 0xafc: 0x2ed3, 0xafd: 0x2e9b, 0xafe: 0x2e58, + // Block 0x2c, offset 0xb00 + 0xb00: 0x06bf, 0xb01: 0x071b, 0xb02: 0x06cb, 0xb03: 0x097b, 0xb04: 0x071f, 0xb05: 0x07af, + 0xb06: 0x06c7, 0xb07: 0x07ab, 0xb08: 0x070b, 0xb09: 0x0887, 0xb0a: 0x0d07, 0xb0b: 0x0e8f, + 0xb0c: 0x0dd7, 0xb0d: 0x0d1b, 0xb0e: 0x145f, 0xb0f: 0x098b, 0xb10: 0x0ccf, 0xb11: 0x0d4b, + 0xb12: 0x0d0b, 0xb13: 0x104b, 0xb14: 0x08fb, 0xb15: 0x0f03, 0xb16: 0x1387, 0xb17: 0x105f, + 0xb18: 0x0843, 0xb19: 0x108f, 0xb1a: 0x0f9b, 0xb1b: 0x0a17, 0xb1c: 0x140f, 0xb1d: 0x077f, + 0xb1e: 0x08ab, 0xb1f: 0x0df7, 0xb20: 0x1527, 0xb21: 0x0743, 0xb22: 0x07d3, 0xb23: 0x0d9b, + 0xb24: 0x06cf, 0xb25: 0x06e7, 0xb26: 0x06d3, 0xb27: 0x0adb, 0xb28: 0x08ef, 0xb29: 0x087f, + 0xb2a: 0x0a57, 0xb2b: 0x0a4b, 0xb2c: 0x0feb, 0xb2d: 0x073f, 0xb2e: 0x139b, 0xb2f: 0x089b, + 0xb30: 0x09f3, 0xb31: 0x18dc, 0xb32: 0x18df, 0xb33: 0x18e2, 0xb34: 0x18e5, 0xb35: 0x18ee, + 0xb36: 0x18f1, 0xb37: 0x18f4, 0xb38: 0x18f7, 0xb39: 0x18fa, 0xb3a: 0x18fd, 0xb3b: 0x1900, + 0xb3c: 0x1903, 0xb3d: 0x1906, 0xb3e: 0x1909, 0xb3f: 0x1912, + // Block 0x2d, offset 0xb40 + 0xb40: 0x1cc6, 0xb41: 0x1cd5, 0xb42: 0x1ce4, 0xb43: 0x1cf3, 0xb44: 0x1d02, 0xb45: 0x1d11, + 0xb46: 0x1d20, 0xb47: 0x1d2f, 0xb48: 0x1d3e, 0xb49: 0x218c, 0xb4a: 0x219e, 0xb4b: 0x21b0, + 0xb4c: 0x1954, 0xb4d: 0x1c04, 0xb4e: 0x19d2, 0xb4f: 0x1ba8, 0xb50: 0x04cb, 0xb51: 0x04d3, + 0xb52: 0x04db, 0xb53: 0x04e3, 0xb54: 0x04eb, 0xb55: 0x04ef, 0xb56: 0x04f3, 0xb57: 0x04f7, + 0xb58: 0x04fb, 0xb59: 0x04ff, 0xb5a: 0x0503, 0xb5b: 0x0507, 0xb5c: 0x050b, 0xb5d: 0x050f, + 0xb5e: 0x0513, 0xb5f: 0x0517, 0xb60: 0x051b, 0xb61: 0x0523, 0xb62: 0x0527, 0xb63: 0x052b, + 0xb64: 0x052f, 0xb65: 0x0533, 0xb66: 0x0537, 0xb67: 0x053b, 0xb68: 0x053f, 0xb69: 0x0543, + 0xb6a: 0x0547, 0xb6b: 0x054b, 0xb6c: 0x054f, 0xb6d: 0x0553, 0xb6e: 0x0557, 0xb6f: 0x055b, + 0xb70: 0x055f, 0xb71: 0x0563, 0xb72: 0x0567, 0xb73: 0x056f, 0xb74: 0x0577, 0xb75: 0x057f, + 0xb76: 0x0583, 0xb77: 0x0587, 0xb78: 0x058b, 0xb79: 0x058f, 0xb7a: 0x0593, 0xb7b: 0x0597, + 0xb7c: 0x059b, 0xb7d: 0x059f, 0xb7e: 0x05a3, + // Block 0x2e, offset 0xb80 + 0xb80: 0x2b0c, 0xb81: 0x29a8, 0xb82: 0x2b1c, 0xb83: 0x2880, 0xb84: 0x2ee4, 0xb85: 0x288a, + 0xb86: 0x2894, 0xb87: 0x2f28, 0xb88: 0x29b5, 0xb89: 0x289e, 0xb8a: 0x28a8, 0xb8b: 0x28b2, + 0xb8c: 0x29dc, 0xb8d: 0x29e9, 0xb8e: 0x29c2, 0xb8f: 0x29cf, 0xb90: 0x2ea9, 0xb91: 0x29f6, + 0xb92: 0x2a03, 0xb93: 0x2bbe, 0xb94: 0x26bb, 0xb95: 0x2bd1, 0xb96: 0x2be4, 0xb97: 0x2b2c, + 0xb98: 0x2a10, 0xb99: 0x2bf7, 0xb9a: 0x2c0a, 0xb9b: 0x2a1d, 0xb9c: 0x28bc, 0xb9d: 0x28c6, + 0xb9e: 0x2eb7, 0xb9f: 0x2a2a, 0xba0: 0x2b3c, 0xba1: 0x2ef5, 0xba2: 0x28d0, 0xba3: 0x28da, + 0xba4: 0x2a37, 0xba5: 0x28e4, 0xba6: 0x28ee, 0xba7: 0x26d0, 0xba8: 0x26d7, 0xba9: 0x28f8, + 0xbaa: 0x2902, 0xbab: 0x2c1d, 0xbac: 0x2a44, 0xbad: 0x2b4c, 0xbae: 0x2c30, 0xbaf: 0x2a51, + 0xbb0: 0x2916, 0xbb1: 0x290c, 0xbb2: 0x2f3c, 0xbb3: 0x2a5e, 0xbb4: 0x2c43, 0xbb5: 0x2920, + 0xbb6: 0x2b5c, 0xbb7: 0x292a, 0xbb8: 0x2a78, 0xbb9: 0x2934, 0xbba: 0x2a85, 0xbbb: 0x2f06, + 0xbbc: 0x2a6b, 0xbbd: 0x2b6c, 0xbbe: 0x2a92, 0xbbf: 0x26de, + // Block 0x2f, offset 0xbc0 + 0xbc0: 0x2f17, 0xbc1: 0x293e, 0xbc2: 0x2948, 0xbc3: 0x2a9f, 0xbc4: 0x2952, 0xbc5: 0x295c, + 0xbc6: 0x2966, 0xbc7: 0x2b7c, 0xbc8: 0x2aac, 0xbc9: 0x26e5, 0xbca: 0x2c56, 0xbcb: 0x2e90, + 0xbcc: 0x2b8c, 0xbcd: 0x2ab9, 0xbce: 0x2ec5, 0xbcf: 0x2970, 0xbd0: 0x297a, 0xbd1: 0x2ac6, + 0xbd2: 0x26ec, 0xbd3: 0x2ad3, 0xbd4: 0x2b9c, 0xbd5: 0x26f3, 0xbd6: 0x2c69, 0xbd7: 0x2984, + 0xbd8: 0x1cb7, 0xbd9: 0x1ccb, 0xbda: 0x1cda, 0xbdb: 0x1ce9, 0xbdc: 0x1cf8, 0xbdd: 0x1d07, + 0xbde: 0x1d16, 0xbdf: 0x1d25, 0xbe0: 0x1d34, 0xbe1: 0x1d43, 0xbe2: 0x2192, 0xbe3: 0x21a4, + 0xbe4: 0x21b6, 0xbe5: 0x21c2, 0xbe6: 0x21ce, 0xbe7: 0x21da, 0xbe8: 0x21e6, 0xbe9: 0x21f2, + 0xbea: 0x21fe, 0xbeb: 0x220a, 0xbec: 0x2246, 0xbed: 0x2252, 0xbee: 0x225e, 0xbef: 0x226a, + 0xbf0: 0x2276, 0xbf1: 0x1c14, 0xbf2: 0x19c6, 0xbf3: 0x1936, 0xbf4: 0x1be4, 0xbf5: 0x1a47, + 0xbf6: 0x1a56, 0xbf7: 0x19cc, 0xbf8: 0x1bfc, 0xbf9: 0x1c00, 0xbfa: 0x1960, 0xbfb: 0x2701, + 0xbfc: 0x270f, 0xbfd: 0x26fa, 0xbfe: 0x2708, 0xbff: 0x2ae0, + // Block 0x30, offset 0xc00 + 0xc00: 0x1a4a, 0xc01: 0x1a32, 0xc02: 0x1c60, 0xc03: 0x1a1a, 0xc04: 0x19f3, 0xc05: 0x1969, + 0xc06: 0x1978, 0xc07: 0x1948, 0xc08: 0x1bf0, 0xc09: 0x1d52, 0xc0a: 0x1a4d, 0xc0b: 0x1a35, + 0xc0c: 0x1c64, 0xc0d: 0x1c70, 0xc0e: 0x1a26, 0xc0f: 0x19fc, 0xc10: 0x1957, 0xc11: 0x1c1c, + 0xc12: 0x1bb0, 0xc13: 0x1b9c, 0xc14: 0x1bcc, 0xc15: 0x1c74, 0xc16: 0x1a29, 0xc17: 0x19c9, + 0xc18: 0x19ff, 0xc19: 0x19de, 0xc1a: 0x1a41, 0xc1b: 0x1c78, 0xc1c: 0x1a2c, 0xc1d: 0x19c0, + 0xc1e: 0x1a02, 0xc1f: 0x1c3c, 0xc20: 0x1bf4, 0xc21: 0x1a14, 0xc22: 0x1c24, 0xc23: 0x1c40, + 0xc24: 0x1bf8, 0xc25: 0x1a17, 0xc26: 0x1c28, 0xc27: 0x22e8, 0xc28: 0x22fc, 0xc29: 0x1996, + 0xc2a: 0x1c20, 0xc2b: 0x1bb4, 0xc2c: 0x1ba0, 0xc2d: 0x1c48, 0xc2e: 0x2716, 0xc2f: 0x27ad, + 0xc30: 0x1a59, 0xc31: 0x1a44, 0xc32: 0x1c7c, 0xc33: 0x1a2f, 0xc34: 0x1a50, 0xc35: 0x1a38, + 0xc36: 0x1c68, 0xc37: 0x1a1d, 0xc38: 0x19f6, 0xc39: 0x1981, 0xc3a: 0x1a53, 0xc3b: 0x1a3b, + 0xc3c: 0x1c6c, 0xc3d: 0x1a20, 0xc3e: 0x19f9, 0xc3f: 0x1984, + // Block 0x31, offset 0xc40 + 0xc40: 0x1c2c, 0xc41: 0x1bb8, 0xc42: 0x1d4d, 0xc43: 0x1939, 0xc44: 0x19ba, 0xc45: 0x19bd, + 0xc46: 0x22f5, 0xc47: 0x1b94, 0xc48: 0x19c3, 0xc49: 0x194b, 0xc4a: 0x19e1, 0xc4b: 0x194e, + 0xc4c: 0x19ea, 0xc4d: 0x196c, 0xc4e: 0x196f, 0xc4f: 0x1a05, 0xc50: 0x1a0b, 0xc51: 0x1a0e, + 0xc52: 0x1c30, 0xc53: 0x1a11, 0xc54: 0x1a23, 0xc55: 0x1c38, 0xc56: 0x1c44, 0xc57: 0x1990, + 0xc58: 0x1d57, 0xc59: 0x1bbc, 0xc5a: 0x1993, 0xc5b: 0x1a5c, 0xc5c: 0x19a5, 0xc5d: 0x19b4, + 0xc5e: 0x22e2, 0xc5f: 0x22dc, 0xc60: 0x1cc1, 0xc61: 0x1cd0, 0xc62: 0x1cdf, 0xc63: 0x1cee, + 0xc64: 0x1cfd, 0xc65: 0x1d0c, 0xc66: 0x1d1b, 0xc67: 0x1d2a, 0xc68: 0x1d39, 0xc69: 0x2186, + 0xc6a: 0x2198, 0xc6b: 0x21aa, 0xc6c: 0x21bc, 0xc6d: 0x21c8, 0xc6e: 0x21d4, 0xc6f: 0x21e0, + 0xc70: 0x21ec, 0xc71: 0x21f8, 0xc72: 0x2204, 0xc73: 0x2240, 0xc74: 0x224c, 0xc75: 0x2258, + 0xc76: 0x2264, 0xc77: 0x2270, 0xc78: 0x227c, 0xc79: 0x2282, 0xc7a: 0x2288, 0xc7b: 0x228e, + 0xc7c: 0x2294, 0xc7d: 0x22a6, 0xc7e: 0x22ac, 0xc7f: 0x1c10, + // Block 0x32, offset 0xc80 + 0xc80: 0x1377, 0xc81: 0x0cfb, 0xc82: 0x13d3, 0xc83: 0x139f, 0xc84: 0x0e57, 0xc85: 0x06eb, + 0xc86: 0x08df, 0xc87: 0x162b, 0xc88: 0x162b, 0xc89: 0x0a0b, 0xc8a: 0x145f, 0xc8b: 0x0943, + 0xc8c: 0x0a07, 0xc8d: 0x0bef, 0xc8e: 0x0fcf, 0xc8f: 0x115f, 0xc90: 0x1297, 0xc91: 0x12d3, + 0xc92: 0x1307, 0xc93: 0x141b, 0xc94: 0x0d73, 0xc95: 0x0dff, 0xc96: 0x0eab, 0xc97: 0x0f43, + 0xc98: 0x125f, 0xc99: 0x1447, 0xc9a: 0x1573, 0xc9b: 0x070f, 0xc9c: 0x08b3, 0xc9d: 0x0d87, + 0xc9e: 0x0ecf, 0xc9f: 0x1293, 0xca0: 0x15c3, 0xca1: 0x0ab3, 0xca2: 0x0e77, 0xca3: 0x1283, + 0xca4: 0x1317, 0xca5: 0x0c23, 0xca6: 0x11bb, 0xca7: 0x12df, 0xca8: 0x0b1f, 0xca9: 0x0d0f, + 0xcaa: 0x0e17, 0xcab: 0x0f1b, 0xcac: 0x1427, 0xcad: 0x074f, 0xcae: 0x07e7, 0xcaf: 0x0853, + 0xcb0: 0x0c8b, 0xcb1: 0x0d7f, 0xcb2: 0x0ecb, 0xcb3: 0x0fef, 0xcb4: 0x1177, 0xcb5: 0x128b, + 0xcb6: 0x12a3, 0xcb7: 0x13c7, 0xcb8: 0x14ef, 0xcb9: 0x15a3, 0xcba: 0x15bf, 0xcbb: 0x102b, + 0xcbc: 0x106b, 0xcbd: 0x1123, 0xcbe: 0x1243, 0xcbf: 0x147b, + // Block 0x33, offset 0xcc0 + 0xcc0: 0x15cb, 0xcc1: 0x134b, 0xcc2: 0x09c7, 0xcc3: 0x0b3b, 0xcc4: 0x10db, 0xcc5: 0x119b, + 0xcc6: 0x0eff, 0xcc7: 0x1033, 0xcc8: 0x1397, 0xcc9: 0x14e7, 0xcca: 0x09c3, 0xccb: 0x0a8f, + 0xccc: 0x0d77, 0xccd: 0x0e2b, 0xcce: 0x0e5f, 0xccf: 0x1113, 0xcd0: 0x113b, 0xcd1: 0x14a7, + 0xcd2: 0x084f, 0xcd3: 0x11a7, 0xcd4: 0x07f3, 0xcd5: 0x07ef, 0xcd6: 0x1097, 0xcd7: 0x1127, + 0xcd8: 0x125b, 0xcd9: 0x14af, 0xcda: 0x1367, 0xcdb: 0x0c27, 0xcdc: 0x0d73, 0xcdd: 0x1357, + 0xcde: 0x06f7, 0xcdf: 0x0a63, 0xce0: 0x0b93, 0xce1: 0x0f2f, 0xce2: 0x0faf, 0xce3: 0x0873, + 0xce4: 0x103b, 0xce5: 0x075f, 0xce6: 0x0b77, 0xce7: 0x06d7, 0xce8: 0x0deb, 0xce9: 0x0ca3, + 0xcea: 0x110f, 0xceb: 0x08c7, 0xcec: 0x09b3, 0xced: 0x0ffb, 0xcee: 0x1263, 0xcef: 0x133b, + 0xcf0: 0x0db7, 0xcf1: 0x13f7, 0xcf2: 0x0de3, 0xcf3: 0x0c37, 0xcf4: 0x121b, 0xcf5: 0x0c57, + 0xcf6: 0x0fab, 0xcf7: 0x072b, 0xcf8: 0x07a7, 0xcf9: 0x07eb, 0xcfa: 0x0d53, 0xcfb: 0x10fb, + 0xcfc: 0x11f3, 0xcfd: 0x1347, 0xcfe: 0x145b, 0xcff: 0x085b, + // Block 0x34, offset 0xd00 + 0xd00: 0x090f, 0xd01: 0x0a17, 0xd02: 0x0b2f, 0xd03: 0x0cbf, 0xd04: 0x0e7b, 0xd05: 0x103f, + 0xd06: 0x1497, 0xd07: 0x157b, 0xd08: 0x15cf, 0xd09: 0x15e7, 0xd0a: 0x0837, 0xd0b: 0x0cf3, + 0xd0c: 0x0da3, 0xd0d: 0x13eb, 0xd0e: 0x0afb, 0xd0f: 0x0bd7, 0xd10: 0x0bf3, 0xd11: 0x0c83, + 0xd12: 0x0e6b, 0xd13: 0x0eb7, 0xd14: 0x0f67, 0xd15: 0x108b, 0xd16: 0x112f, 0xd17: 0x1193, + 0xd18: 0x13db, 0xd19: 0x126b, 0xd1a: 0x1403, 0xd1b: 0x147f, 0xd1c: 0x080f, 0xd1d: 0x083b, + 0xd1e: 0x0923, 0xd1f: 0x0ea7, 0xd20: 0x12f3, 0xd21: 0x133b, 0xd22: 0x0b1b, 0xd23: 0x0b8b, + 0xd24: 0x0c4f, 0xd25: 0x0daf, 0xd26: 0x10d7, 0xd27: 0x0f23, 0xd28: 0x073b, 0xd29: 0x097f, + 0xd2a: 0x0a63, 0xd2b: 0x0ac7, 0xd2c: 0x0b97, 0xd2d: 0x0f3f, 0xd2e: 0x0f5b, 0xd2f: 0x116b, + 0xd30: 0x118b, 0xd31: 0x1463, 0xd32: 0x14e3, 0xd33: 0x14f3, 0xd34: 0x152f, 0xd35: 0x0753, + 0xd36: 0x107f, 0xd37: 0x144f, 0xd38: 0x14cb, 0xd39: 0x0baf, 0xd3a: 0x0717, 0xd3b: 0x0777, + 0xd3c: 0x0a67, 0xd3d: 0x0a87, 0xd3e: 0x0caf, 0xd3f: 0x0d73, + // Block 0x35, offset 0xd40 + 0xd40: 0x0ec3, 0xd41: 0x0fcb, 0xd42: 0x1277, 0xd43: 0x1417, 0xd44: 0x1623, 0xd45: 0x0ce3, + 0xd46: 0x14a3, 0xd47: 0x0833, 0xd48: 0x0d2f, 0xd49: 0x0d3b, 0xd4a: 0x0e0f, 0xd4b: 0x0e47, + 0xd4c: 0x0f4b, 0xd4d: 0x0fa7, 0xd4e: 0x1027, 0xd4f: 0x110b, 0xd50: 0x153b, 0xd51: 0x07af, + 0xd52: 0x0c03, 0xd53: 0x14b3, 0xd54: 0x0767, 0xd55: 0x0aab, 0xd56: 0x0e2f, 0xd57: 0x13df, + 0xd58: 0x0b67, 0xd59: 0x0bb7, 0xd5a: 0x0d43, 0xd5b: 0x0f2f, 0xd5c: 0x14bb, 0xd5d: 0x0817, + 0xd5e: 0x08ff, 0xd5f: 0x0a97, 0xd60: 0x0cd3, 0xd61: 0x0d1f, 0xd62: 0x0d5f, 0xd63: 0x0df3, + 0xd64: 0x0f47, 0xd65: 0x0fbb, 0xd66: 0x1157, 0xd67: 0x12f7, 0xd68: 0x1303, 0xd69: 0x1457, + 0xd6a: 0x14d7, 0xd6b: 0x0883, 0xd6c: 0x0e4b, 0xd6d: 0x0903, 0xd6e: 0x0ec7, 0xd6f: 0x0f6b, + 0xd70: 0x1287, 0xd71: 0x14bf, 0xd72: 0x15ab, 0xd73: 0x15d3, 0xd74: 0x0d37, 0xd75: 0x0e27, + 0xd76: 0x11c3, 0xd77: 0x10b7, 0xd78: 0x10c3, 0xd79: 0x10e7, 0xd7a: 0x0f17, 0xd7b: 0x0e9f, + 0xd7c: 0x1363, 0xd7d: 0x0733, 0xd7e: 0x122b, 0xd7f: 0x081b, + // Block 0x36, offset 0xd80 + 0xd80: 0x080b, 0xd81: 0x0b0b, 0xd82: 0x0c2b, 0xd83: 0x10f3, 0xd84: 0x0a53, 0xd85: 0x0e03, + 0xd86: 0x0cef, 0xd87: 0x13e7, 0xd88: 0x12e7, 0xd89: 0x14ab, 0xd8a: 0x1323, 0xd8b: 0x0b27, + 0xd8c: 0x0787, 0xd8d: 0x095b, 0xd90: 0x09af, + 0xd92: 0x0cdf, 0xd95: 0x07f7, 0xd96: 0x0f1f, 0xd97: 0x0fe3, + 0xd98: 0x1047, 0xd99: 0x1063, 0xd9a: 0x1067, 0xd9b: 0x107b, 0xd9c: 0x14fb, 0xd9d: 0x10eb, + 0xd9e: 0x116f, 0xda0: 0x128f, 0xda2: 0x1353, + 0xda5: 0x1407, 0xda6: 0x1433, + 0xdaa: 0x154f, 0xdab: 0x1553, 0xdac: 0x1557, 0xdad: 0x15bb, 0xdae: 0x142b, 0xdaf: 0x14c7, + 0xdb0: 0x0757, 0xdb1: 0x077b, 0xdb2: 0x078f, 0xdb3: 0x084b, 0xdb4: 0x0857, 0xdb5: 0x0897, + 0xdb6: 0x094b, 0xdb7: 0x0967, 0xdb8: 0x096f, 0xdb9: 0x09ab, 0xdba: 0x09b7, 0xdbb: 0x0a93, + 0xdbc: 0x0a9b, 0xdbd: 0x0ba3, 0xdbe: 0x0bcb, 0xdbf: 0x0bd3, + // Block 0x37, offset 0xdc0 + 0xdc0: 0x0beb, 0xdc1: 0x0c97, 0xdc2: 0x0cc7, 0xdc3: 0x0ce7, 0xdc4: 0x0d57, 0xdc5: 0x0e1b, + 0xdc6: 0x0e37, 0xdc7: 0x0e67, 0xdc8: 0x0ebb, 0xdc9: 0x0edb, 0xdca: 0x0f4f, 0xdcb: 0x102f, + 0xdcc: 0x104b, 0xdcd: 0x1053, 0xdce: 0x104f, 0xdcf: 0x1057, 0xdd0: 0x105b, 0xdd1: 0x105f, + 0xdd2: 0x1073, 0xdd3: 0x1077, 0xdd4: 0x109b, 0xdd5: 0x10af, 0xdd6: 0x10cb, 0xdd7: 0x112f, + 0xdd8: 0x1137, 0xdd9: 0x113f, 0xdda: 0x1153, 0xddb: 0x117b, 0xddc: 0x11cb, 0xddd: 0x11ff, + 0xdde: 0x11ff, 0xddf: 0x1267, 0xde0: 0x130f, 0xde1: 0x1327, 0xde2: 0x135b, 0xde3: 0x135f, + 0xde4: 0x13a3, 0xde5: 0x13a7, 0xde6: 0x13ff, 0xde7: 0x1407, 0xde8: 0x14db, 0xde9: 0x151f, + 0xdea: 0x1537, 0xdeb: 0x0b9b, 0xdec: 0x171e, 0xded: 0x11e3, + 0xdf0: 0x06df, 0xdf1: 0x07e3, 0xdf2: 0x07a3, 0xdf3: 0x074b, 0xdf4: 0x078b, 0xdf5: 0x07b7, + 0xdf6: 0x0847, 0xdf7: 0x0863, 0xdf8: 0x094b, 0xdf9: 0x0937, 0xdfa: 0x0947, 0xdfb: 0x0963, + 0xdfc: 0x09af, 0xdfd: 0x09bf, 0xdfe: 0x0a03, 0xdff: 0x0a0f, + // Block 0x38, offset 0xe00 + 0xe00: 0x0a2b, 0xe01: 0x0a3b, 0xe02: 0x0b23, 0xe03: 0x0b2b, 0xe04: 0x0b5b, 0xe05: 0x0b7b, + 0xe06: 0x0bab, 0xe07: 0x0bc3, 0xe08: 0x0bb3, 0xe09: 0x0bd3, 0xe0a: 0x0bc7, 0xe0b: 0x0beb, + 0xe0c: 0x0c07, 0xe0d: 0x0c5f, 0xe0e: 0x0c6b, 0xe0f: 0x0c73, 0xe10: 0x0c9b, 0xe11: 0x0cdf, + 0xe12: 0x0d0f, 0xe13: 0x0d13, 0xe14: 0x0d27, 0xe15: 0x0da7, 0xe16: 0x0db7, 0xe17: 0x0e0f, + 0xe18: 0x0e5b, 0xe19: 0x0e53, 0xe1a: 0x0e67, 0xe1b: 0x0e83, 0xe1c: 0x0ebb, 0xe1d: 0x1013, + 0xe1e: 0x0edf, 0xe1f: 0x0f13, 0xe20: 0x0f1f, 0xe21: 0x0f5f, 0xe22: 0x0f7b, 0xe23: 0x0f9f, + 0xe24: 0x0fc3, 0xe25: 0x0fc7, 0xe26: 0x0fe3, 0xe27: 0x0fe7, 0xe28: 0x0ff7, 0xe29: 0x100b, + 0xe2a: 0x1007, 0xe2b: 0x1037, 0xe2c: 0x10b3, 0xe2d: 0x10cb, 0xe2e: 0x10e3, 0xe2f: 0x111b, + 0xe30: 0x112f, 0xe31: 0x114b, 0xe32: 0x117b, 0xe33: 0x122f, 0xe34: 0x1257, 0xe35: 0x12cb, + 0xe36: 0x1313, 0xe37: 0x131f, 0xe38: 0x1327, 0xe39: 0x133f, 0xe3a: 0x1353, 0xe3b: 0x1343, + 0xe3c: 0x135b, 0xe3d: 0x1357, 0xe3e: 0x134f, 0xe3f: 0x135f, + // Block 0x39, offset 0xe40 + 0xe40: 0x136b, 0xe41: 0x13a7, 0xe42: 0x13e3, 0xe43: 0x1413, 0xe44: 0x144b, 0xe45: 0x146b, + 0xe46: 0x14b7, 0xe47: 0x14db, 0xe48: 0x14fb, 0xe49: 0x150f, 0xe4a: 0x151f, 0xe4b: 0x152b, + 0xe4c: 0x1537, 0xe4d: 0x158b, 0xe4e: 0x162b, 0xe4f: 0x16b5, 0xe50: 0x16b0, 0xe51: 0x16e2, + 0xe52: 0x0607, 0xe53: 0x062f, 0xe54: 0x0633, 0xe55: 0x1764, 0xe56: 0x1791, 0xe57: 0x1809, + 0xe58: 0x1617, 0xe59: 0x1627, + // Block 0x3a, offset 0xe80 + 0xe80: 0x19d5, 0xe81: 0x19d8, 0xe82: 0x19db, 0xe83: 0x1c08, 0xe84: 0x1c0c, 0xe85: 0x1a5f, + 0xe86: 0x1a5f, + 0xe93: 0x1d75, 0xe94: 0x1d66, 0xe95: 0x1d6b, 0xe96: 0x1d7a, 0xe97: 0x1d70, + 0xe9d: 0x4390, + 0xe9e: 0x8115, 0xe9f: 0x4402, 0xea0: 0x022d, 0xea1: 0x0215, 0xea2: 0x021e, 0xea3: 0x0221, + 0xea4: 0x0224, 0xea5: 0x0227, 0xea6: 0x022a, 0xea7: 0x0230, 0xea8: 0x0233, 0xea9: 0x0017, + 0xeaa: 0x43f0, 0xeab: 0x43f6, 0xeac: 0x44f4, 0xead: 0x44fc, 0xeae: 0x4348, 0xeaf: 0x434e, + 0xeb0: 0x4354, 0xeb1: 0x435a, 0xeb2: 0x4366, 0xeb3: 0x436c, 0xeb4: 0x4372, 0xeb5: 0x437e, + 0xeb6: 0x4384, 0xeb8: 0x438a, 0xeb9: 0x4396, 0xeba: 0x439c, 0xebb: 0x43a2, + 0xebc: 0x43ae, 0xebe: 0x43b4, + // Block 0x3b, offset 0xec0 + 0xec0: 0x43ba, 0xec1: 0x43c0, 0xec3: 0x43c6, 0xec4: 0x43cc, + 0xec6: 0x43d8, 0xec7: 0x43de, 0xec8: 0x43e4, 0xec9: 0x43ea, 0xeca: 0x43fc, 0xecb: 0x4378, + 0xecc: 0x4360, 0xecd: 0x43a8, 0xece: 0x43d2, 0xecf: 0x1d7f, 0xed0: 0x0299, 0xed1: 0x0299, + 0xed2: 0x02a2, 0xed3: 0x02a2, 0xed4: 0x02a2, 0xed5: 0x02a2, 0xed6: 0x02a5, 0xed7: 0x02a5, + 0xed8: 0x02a5, 0xed9: 0x02a5, 0xeda: 0x02ab, 0xedb: 0x02ab, 0xedc: 0x02ab, 0xedd: 0x02ab, + 0xede: 0x029f, 0xedf: 0x029f, 0xee0: 0x029f, 0xee1: 0x029f, 0xee2: 0x02a8, 0xee3: 0x02a8, + 0xee4: 0x02a8, 0xee5: 0x02a8, 0xee6: 0x029c, 0xee7: 0x029c, 0xee8: 0x029c, 0xee9: 0x029c, + 0xeea: 0x02cf, 0xeeb: 0x02cf, 0xeec: 0x02cf, 0xeed: 0x02cf, 0xeee: 0x02d2, 0xeef: 0x02d2, + 0xef0: 0x02d2, 0xef1: 0x02d2, 0xef2: 0x02b1, 0xef3: 0x02b1, 0xef4: 0x02b1, 0xef5: 0x02b1, + 0xef6: 0x02ae, 0xef7: 0x02ae, 0xef8: 0x02ae, 0xef9: 0x02ae, 0xefa: 0x02b4, 0xefb: 0x02b4, + 0xefc: 0x02b4, 0xefd: 0x02b4, 0xefe: 0x02b7, 0xeff: 0x02b7, + // Block 0x3c, offset 0xf00 + 0xf00: 0x02b7, 0xf01: 0x02b7, 0xf02: 0x02c0, 0xf03: 0x02c0, 0xf04: 0x02bd, 0xf05: 0x02bd, + 0xf06: 0x02c3, 0xf07: 0x02c3, 0xf08: 0x02ba, 0xf09: 0x02ba, 0xf0a: 0x02c9, 0xf0b: 0x02c9, + 0xf0c: 0x02c6, 0xf0d: 0x02c6, 0xf0e: 0x02d5, 0xf0f: 0x02d5, 0xf10: 0x02d5, 0xf11: 0x02d5, + 0xf12: 0x02db, 0xf13: 0x02db, 0xf14: 0x02db, 0xf15: 0x02db, 0xf16: 0x02e1, 0xf17: 0x02e1, + 0xf18: 0x02e1, 0xf19: 0x02e1, 0xf1a: 0x02de, 0xf1b: 0x02de, 0xf1c: 0x02de, 0xf1d: 0x02de, + 0xf1e: 0x02e4, 0xf1f: 0x02e4, 0xf20: 0x02e7, 0xf21: 0x02e7, 0xf22: 0x02e7, 0xf23: 0x02e7, + 0xf24: 0x446e, 0xf25: 0x446e, 0xf26: 0x02ed, 0xf27: 0x02ed, 0xf28: 0x02ed, 0xf29: 0x02ed, + 0xf2a: 0x02ea, 0xf2b: 0x02ea, 0xf2c: 0x02ea, 0xf2d: 0x02ea, 0xf2e: 0x0308, 0xf2f: 0x0308, + 0xf30: 0x4468, 0xf31: 0x4468, + // Block 0x3d, offset 0xf40 + 0xf53: 0x02d8, 0xf54: 0x02d8, 0xf55: 0x02d8, 0xf56: 0x02d8, 0xf57: 0x02f6, + 0xf58: 0x02f6, 0xf59: 0x02f3, 0xf5a: 0x02f3, 0xf5b: 0x02f9, 0xf5c: 0x02f9, 0xf5d: 0x204f, + 0xf5e: 0x02ff, 0xf5f: 0x02ff, 0xf60: 0x02f0, 0xf61: 0x02f0, 0xf62: 0x02fc, 0xf63: 0x02fc, + 0xf64: 0x0305, 0xf65: 0x0305, 0xf66: 0x0305, 0xf67: 0x0305, 0xf68: 0x028d, 0xf69: 0x028d, + 0xf6a: 0x25aa, 0xf6b: 0x25aa, 0xf6c: 0x261a, 0xf6d: 0x261a, 0xf6e: 0x25e9, 0xf6f: 0x25e9, + 0xf70: 0x2605, 0xf71: 0x2605, 0xf72: 0x25fe, 0xf73: 0x25fe, 0xf74: 0x260c, 0xf75: 0x260c, + 0xf76: 0x2613, 0xf77: 0x2613, 0xf78: 0x2613, 0xf79: 0x25f0, 0xf7a: 0x25f0, 0xf7b: 0x25f0, + 0xf7c: 0x0302, 0xf7d: 0x0302, 0xf7e: 0x0302, 0xf7f: 0x0302, + // Block 0x3e, offset 0xf80 + 0xf80: 0x25b1, 0xf81: 0x25b8, 0xf82: 0x25d4, 0xf83: 0x25f0, 0xf84: 0x25f7, 0xf85: 0x1d89, + 0xf86: 0x1d8e, 0xf87: 0x1d93, 0xf88: 0x1da2, 0xf89: 0x1db1, 0xf8a: 0x1db6, 0xf8b: 0x1dbb, + 0xf8c: 0x1dc0, 0xf8d: 0x1dc5, 0xf8e: 0x1dd4, 0xf8f: 0x1de3, 0xf90: 0x1de8, 0xf91: 0x1ded, + 0xf92: 0x1dfc, 0xf93: 0x1e0b, 0xf94: 0x1e10, 0xf95: 0x1e15, 0xf96: 0x1e1a, 0xf97: 0x1e29, + 0xf98: 0x1e2e, 0xf99: 0x1e3d, 0xf9a: 0x1e42, 0xf9b: 0x1e47, 0xf9c: 0x1e56, 0xf9d: 0x1e5b, + 0xf9e: 0x1e60, 0xf9f: 0x1e6a, 0xfa0: 0x1ea6, 0xfa1: 0x1eb5, 0xfa2: 0x1ec4, 0xfa3: 0x1ec9, + 0xfa4: 0x1ece, 0xfa5: 0x1ed8, 0xfa6: 0x1ee7, 0xfa7: 0x1eec, 0xfa8: 0x1efb, 0xfa9: 0x1f00, + 0xfaa: 0x1f05, 0xfab: 0x1f14, 0xfac: 0x1f19, 0xfad: 0x1f28, 0xfae: 0x1f2d, 0xfaf: 0x1f32, + 0xfb0: 0x1f37, 0xfb1: 0x1f3c, 0xfb2: 0x1f41, 0xfb3: 0x1f46, 0xfb4: 0x1f4b, 0xfb5: 0x1f50, + 0xfb6: 0x1f55, 0xfb7: 0x1f5a, 0xfb8: 0x1f5f, 0xfb9: 0x1f64, 0xfba: 0x1f69, 0xfbb: 0x1f6e, + 0xfbc: 0x1f73, 0xfbd: 0x1f78, 0xfbe: 0x1f7d, 0xfbf: 0x1f87, + // Block 0x3f, offset 0xfc0 + 0xfc0: 0x1f8c, 0xfc1: 0x1f91, 0xfc2: 0x1f96, 0xfc3: 0x1fa0, 0xfc4: 0x1fa5, 0xfc5: 0x1faf, + 0xfc6: 0x1fb4, 0xfc7: 0x1fb9, 0xfc8: 0x1fbe, 0xfc9: 0x1fc3, 0xfca: 0x1fc8, 0xfcb: 0x1fcd, + 0xfcc: 0x1fd2, 0xfcd: 0x1fd7, 0xfce: 0x1fe6, 0xfcf: 0x1ff5, 0xfd0: 0x1ffa, 0xfd1: 0x1fff, + 0xfd2: 0x2004, 0xfd3: 0x2009, 0xfd4: 0x200e, 0xfd5: 0x2018, 0xfd6: 0x201d, 0xfd7: 0x2022, + 0xfd8: 0x2031, 0xfd9: 0x2040, 0xfda: 0x2045, 0xfdb: 0x4420, 0xfdc: 0x4426, 0xfdd: 0x445c, + 0xfde: 0x44b3, 0xfdf: 0x44ba, 0xfe0: 0x44c1, 0xfe1: 0x44c8, 0xfe2: 0x44cf, 0xfe3: 0x44d6, + 0xfe4: 0x25c6, 0xfe5: 0x25cd, 0xfe6: 0x25d4, 0xfe7: 0x25db, 0xfe8: 0x25f0, 0xfe9: 0x25f7, + 0xfea: 0x1d98, 0xfeb: 0x1d9d, 0xfec: 0x1da2, 0xfed: 0x1da7, 0xfee: 0x1db1, 0xfef: 0x1db6, + 0xff0: 0x1dca, 0xff1: 0x1dcf, 0xff2: 0x1dd4, 0xff3: 0x1dd9, 0xff4: 0x1de3, 0xff5: 0x1de8, + 0xff6: 0x1df2, 0xff7: 0x1df7, 0xff8: 0x1dfc, 0xff9: 0x1e01, 0xffa: 0x1e0b, 0xffb: 0x1e10, + 0xffc: 0x1f3c, 0xffd: 0x1f41, 0xffe: 0x1f50, 0xfff: 0x1f55, + // Block 0x40, offset 0x1000 + 0x1000: 0x1f5a, 0x1001: 0x1f6e, 0x1002: 0x1f73, 0x1003: 0x1f78, 0x1004: 0x1f7d, 0x1005: 0x1f96, + 0x1006: 0x1fa0, 0x1007: 0x1fa5, 0x1008: 0x1faa, 0x1009: 0x1fbe, 0x100a: 0x1fdc, 0x100b: 0x1fe1, + 0x100c: 0x1fe6, 0x100d: 0x1feb, 0x100e: 0x1ff5, 0x100f: 0x1ffa, 0x1010: 0x445c, 0x1011: 0x2027, + 0x1012: 0x202c, 0x1013: 0x2031, 0x1014: 0x2036, 0x1015: 0x2040, 0x1016: 0x2045, 0x1017: 0x25b1, + 0x1018: 0x25b8, 0x1019: 0x25bf, 0x101a: 0x25d4, 0x101b: 0x25e2, 0x101c: 0x1d89, 0x101d: 0x1d8e, + 0x101e: 0x1d93, 0x101f: 0x1da2, 0x1020: 0x1dac, 0x1021: 0x1dbb, 0x1022: 0x1dc0, 0x1023: 0x1dc5, + 0x1024: 0x1dd4, 0x1025: 0x1dde, 0x1026: 0x1dfc, 0x1027: 0x1e15, 0x1028: 0x1e1a, 0x1029: 0x1e29, + 0x102a: 0x1e2e, 0x102b: 0x1e3d, 0x102c: 0x1e47, 0x102d: 0x1e56, 0x102e: 0x1e5b, 0x102f: 0x1e60, + 0x1030: 0x1e6a, 0x1031: 0x1ea6, 0x1032: 0x1eab, 0x1033: 0x1eb5, 0x1034: 0x1ec4, 0x1035: 0x1ec9, + 0x1036: 0x1ece, 0x1037: 0x1ed8, 0x1038: 0x1ee7, 0x1039: 0x1efb, 0x103a: 0x1f00, 0x103b: 0x1f05, + 0x103c: 0x1f14, 0x103d: 0x1f19, 0x103e: 0x1f28, 0x103f: 0x1f2d, + // Block 0x41, offset 0x1040 + 0x1040: 0x1f32, 0x1041: 0x1f37, 0x1042: 0x1f46, 0x1043: 0x1f4b, 0x1044: 0x1f5f, 0x1045: 0x1f64, + 0x1046: 0x1f69, 0x1047: 0x1f6e, 0x1048: 0x1f73, 0x1049: 0x1f87, 0x104a: 0x1f8c, 0x104b: 0x1f91, + 0x104c: 0x1f96, 0x104d: 0x1f9b, 0x104e: 0x1faf, 0x104f: 0x1fb4, 0x1050: 0x1fb9, 0x1051: 0x1fbe, + 0x1052: 0x1fcd, 0x1053: 0x1fd2, 0x1054: 0x1fd7, 0x1055: 0x1fe6, 0x1056: 0x1ff0, 0x1057: 0x1fff, + 0x1058: 0x2004, 0x1059: 0x4450, 0x105a: 0x2018, 0x105b: 0x201d, 0x105c: 0x2022, 0x105d: 0x2031, + 0x105e: 0x203b, 0x105f: 0x25d4, 0x1060: 0x25e2, 0x1061: 0x1da2, 0x1062: 0x1dac, 0x1063: 0x1dd4, + 0x1064: 0x1dde, 0x1065: 0x1dfc, 0x1066: 0x1e06, 0x1067: 0x1e6a, 0x1068: 0x1e6f, 0x1069: 0x1e92, + 0x106a: 0x1e97, 0x106b: 0x1f6e, 0x106c: 0x1f73, 0x106d: 0x1f96, 0x106e: 0x1fe6, 0x106f: 0x1ff0, + 0x1070: 0x2031, 0x1071: 0x203b, 0x1072: 0x4504, 0x1073: 0x450c, 0x1074: 0x4514, 0x1075: 0x1ef1, + 0x1076: 0x1ef6, 0x1077: 0x1f0a, 0x1078: 0x1f0f, 0x1079: 0x1f1e, 0x107a: 0x1f23, 0x107b: 0x1e74, + 0x107c: 0x1e79, 0x107d: 0x1e9c, 0x107e: 0x1ea1, 0x107f: 0x1e33, + // Block 0x42, offset 0x1080 + 0x1080: 0x1e38, 0x1081: 0x1e1f, 0x1082: 0x1e24, 0x1083: 0x1e4c, 0x1084: 0x1e51, 0x1085: 0x1eba, + 0x1086: 0x1ebf, 0x1087: 0x1edd, 0x1088: 0x1ee2, 0x1089: 0x1e7e, 0x108a: 0x1e83, 0x108b: 0x1e88, + 0x108c: 0x1e92, 0x108d: 0x1e8d, 0x108e: 0x1e65, 0x108f: 0x1eb0, 0x1090: 0x1ed3, 0x1091: 0x1ef1, + 0x1092: 0x1ef6, 0x1093: 0x1f0a, 0x1094: 0x1f0f, 0x1095: 0x1f1e, 0x1096: 0x1f23, 0x1097: 0x1e74, + 0x1098: 0x1e79, 0x1099: 0x1e9c, 0x109a: 0x1ea1, 0x109b: 0x1e33, 0x109c: 0x1e38, 0x109d: 0x1e1f, + 0x109e: 0x1e24, 0x109f: 0x1e4c, 0x10a0: 0x1e51, 0x10a1: 0x1eba, 0x10a2: 0x1ebf, 0x10a3: 0x1edd, + 0x10a4: 0x1ee2, 0x10a5: 0x1e7e, 0x10a6: 0x1e83, 0x10a7: 0x1e88, 0x10a8: 0x1e92, 0x10a9: 0x1e8d, + 0x10aa: 0x1e65, 0x10ab: 0x1eb0, 0x10ac: 0x1ed3, 0x10ad: 0x1e7e, 0x10ae: 0x1e83, 0x10af: 0x1e88, + 0x10b0: 0x1e92, 0x10b1: 0x1e6f, 0x10b2: 0x1e97, 0x10b3: 0x1eec, 0x10b4: 0x1e56, 0x10b5: 0x1e5b, + 0x10b6: 0x1e60, 0x10b7: 0x1e7e, 0x10b8: 0x1e83, 0x10b9: 0x1e88, 0x10ba: 0x1eec, 0x10bb: 0x1efb, + 0x10bc: 0x4408, 0x10bd: 0x4408, + // Block 0x43, offset 0x10c0 + 0x10d0: 0x2311, 0x10d1: 0x2326, + 0x10d2: 0x2326, 0x10d3: 0x232d, 0x10d4: 0x2334, 0x10d5: 0x2349, 0x10d6: 0x2350, 0x10d7: 0x2357, + 0x10d8: 0x237a, 0x10d9: 0x237a, 0x10da: 0x239d, 0x10db: 0x2396, 0x10dc: 0x23b2, 0x10dd: 0x23a4, + 0x10de: 0x23ab, 0x10df: 0x23ce, 0x10e0: 0x23ce, 0x10e1: 0x23c7, 0x10e2: 0x23d5, 0x10e3: 0x23d5, + 0x10e4: 0x23ff, 0x10e5: 0x23ff, 0x10e6: 0x241b, 0x10e7: 0x23e3, 0x10e8: 0x23e3, 0x10e9: 0x23dc, + 0x10ea: 0x23f1, 0x10eb: 0x23f1, 0x10ec: 0x23f8, 0x10ed: 0x23f8, 0x10ee: 0x2422, 0x10ef: 0x2430, + 0x10f0: 0x2430, 0x10f1: 0x2437, 0x10f2: 0x2437, 0x10f3: 0x243e, 0x10f4: 0x2445, 0x10f5: 0x244c, + 0x10f6: 0x2453, 0x10f7: 0x2453, 0x10f8: 0x245a, 0x10f9: 0x2468, 0x10fa: 0x2476, 0x10fb: 0x246f, + 0x10fc: 0x247d, 0x10fd: 0x247d, 0x10fe: 0x2492, 0x10ff: 0x2499, + // Block 0x44, offset 0x1100 + 0x1100: 0x24ca, 0x1101: 0x24d8, 0x1102: 0x24d1, 0x1103: 0x24b5, 0x1104: 0x24b5, 0x1105: 0x24df, + 0x1106: 0x24df, 0x1107: 0x24e6, 0x1108: 0x24e6, 0x1109: 0x2510, 0x110a: 0x2517, 0x110b: 0x251e, + 0x110c: 0x24f4, 0x110d: 0x2502, 0x110e: 0x2525, 0x110f: 0x252c, + 0x1112: 0x24fb, 0x1113: 0x2580, 0x1114: 0x2587, 0x1115: 0x255d, 0x1116: 0x2564, 0x1117: 0x2548, + 0x1118: 0x2548, 0x1119: 0x254f, 0x111a: 0x2579, 0x111b: 0x2572, 0x111c: 0x259c, 0x111d: 0x259c, + 0x111e: 0x230a, 0x111f: 0x231f, 0x1120: 0x2318, 0x1121: 0x2342, 0x1122: 0x233b, 0x1123: 0x2365, + 0x1124: 0x235e, 0x1125: 0x2388, 0x1126: 0x236c, 0x1127: 0x2381, 0x1128: 0x23b9, 0x1129: 0x2406, + 0x112a: 0x23ea, 0x112b: 0x2429, 0x112c: 0x24c3, 0x112d: 0x24ed, 0x112e: 0x2595, 0x112f: 0x258e, + 0x1130: 0x25a3, 0x1131: 0x253a, 0x1132: 0x24a0, 0x1133: 0x256b, 0x1134: 0x2492, 0x1135: 0x24ca, + 0x1136: 0x2461, 0x1137: 0x24ae, 0x1138: 0x2541, 0x1139: 0x2533, 0x113a: 0x24bc, 0x113b: 0x24a7, + 0x113c: 0x24bc, 0x113d: 0x2541, 0x113e: 0x2373, 0x113f: 0x238f, + // Block 0x45, offset 0x1140 + 0x1140: 0x2509, 0x1141: 0x2484, 0x1142: 0x2303, 0x1143: 0x24a7, 0x1144: 0x244c, 0x1145: 0x241b, + 0x1146: 0x23c0, 0x1147: 0x2556, + 0x1170: 0x2414, 0x1171: 0x248b, 0x1172: 0x27bf, 0x1173: 0x27b6, 0x1174: 0x27ec, 0x1175: 0x27da, + 0x1176: 0x27c8, 0x1177: 0x27e3, 0x1178: 0x27f5, 0x1179: 0x240d, 0x117a: 0x2c7c, 0x117b: 0x2afc, + 0x117c: 0x27d1, + // Block 0x46, offset 0x1180 + 0x1190: 0x0019, 0x1191: 0x0483, + 0x1192: 0x0487, 0x1193: 0x0035, 0x1194: 0x0037, 0x1195: 0x0003, 0x1196: 0x003f, 0x1197: 0x04bf, + 0x1198: 0x04c3, 0x1199: 0x1b5c, + 0x11a0: 0x8132, 0x11a1: 0x8132, 0x11a2: 0x8132, 0x11a3: 0x8132, + 0x11a4: 0x8132, 0x11a5: 0x8132, 0x11a6: 0x8132, 0x11a7: 0x812d, 0x11a8: 0x812d, 0x11a9: 0x812d, + 0x11aa: 0x812d, 0x11ab: 0x812d, 0x11ac: 0x812d, 0x11ad: 0x812d, 0x11ae: 0x8132, 0x11af: 0x8132, + 0x11b0: 0x1873, 0x11b1: 0x0443, 0x11b2: 0x043f, 0x11b3: 0x007f, 0x11b4: 0x007f, 0x11b5: 0x0011, + 0x11b6: 0x0013, 0x11b7: 0x00b7, 0x11b8: 0x00bb, 0x11b9: 0x04b7, 0x11ba: 0x04bb, 0x11bb: 0x04ab, + 0x11bc: 0x04af, 0x11bd: 0x0493, 0x11be: 0x0497, 0x11bf: 0x048b, + // Block 0x47, offset 0x11c0 + 0x11c0: 0x048f, 0x11c1: 0x049b, 0x11c2: 0x049f, 0x11c3: 0x04a3, 0x11c4: 0x04a7, + 0x11c7: 0x0077, 0x11c8: 0x007b, 0x11c9: 0x4269, 0x11ca: 0x4269, 0x11cb: 0x4269, + 0x11cc: 0x4269, 0x11cd: 0x007f, 0x11ce: 0x007f, 0x11cf: 0x007f, 0x11d0: 0x0019, 0x11d1: 0x0483, + 0x11d2: 0x001d, 0x11d4: 0x0037, 0x11d5: 0x0035, 0x11d6: 0x003f, 0x11d7: 0x0003, + 0x11d8: 0x0443, 0x11d9: 0x0011, 0x11da: 0x0013, 0x11db: 0x00b7, 0x11dc: 0x00bb, 0x11dd: 0x04b7, + 0x11de: 0x04bb, 0x11df: 0x0007, 0x11e0: 0x000d, 0x11e1: 0x0015, 0x11e2: 0x0017, 0x11e3: 0x001b, + 0x11e4: 0x0039, 0x11e5: 0x003d, 0x11e6: 0x003b, 0x11e8: 0x0079, 0x11e9: 0x0009, + 0x11ea: 0x000b, 0x11eb: 0x0041, + 0x11f0: 0x42aa, 0x11f1: 0x442c, 0x11f2: 0x42af, 0x11f4: 0x42b4, + 0x11f6: 0x42b9, 0x11f7: 0x4432, 0x11f8: 0x42be, 0x11f9: 0x4438, 0x11fa: 0x42c3, 0x11fb: 0x443e, + 0x11fc: 0x42c8, 0x11fd: 0x4444, 0x11fe: 0x42cd, 0x11ff: 0x444a, + // Block 0x48, offset 0x1200 + 0x1200: 0x0236, 0x1201: 0x440e, 0x1202: 0x440e, 0x1203: 0x4414, 0x1204: 0x4414, 0x1205: 0x4456, + 0x1206: 0x4456, 0x1207: 0x441a, 0x1208: 0x441a, 0x1209: 0x4462, 0x120a: 0x4462, 0x120b: 0x4462, + 0x120c: 0x4462, 0x120d: 0x0239, 0x120e: 0x0239, 0x120f: 0x023c, 0x1210: 0x023c, 0x1211: 0x023c, + 0x1212: 0x023c, 0x1213: 0x023f, 0x1214: 0x023f, 0x1215: 0x0242, 0x1216: 0x0242, 0x1217: 0x0242, + 0x1218: 0x0242, 0x1219: 0x0245, 0x121a: 0x0245, 0x121b: 0x0245, 0x121c: 0x0245, 0x121d: 0x0248, + 0x121e: 0x0248, 0x121f: 0x0248, 0x1220: 0x0248, 0x1221: 0x024b, 0x1222: 0x024b, 0x1223: 0x024b, + 0x1224: 0x024b, 0x1225: 0x024e, 0x1226: 0x024e, 0x1227: 0x024e, 0x1228: 0x024e, 0x1229: 0x0251, + 0x122a: 0x0251, 0x122b: 0x0254, 0x122c: 0x0254, 0x122d: 0x0257, 0x122e: 0x0257, 0x122f: 0x025a, + 0x1230: 0x025a, 0x1231: 0x025d, 0x1232: 0x025d, 0x1233: 0x025d, 0x1234: 0x025d, 0x1235: 0x0260, + 0x1236: 0x0260, 0x1237: 0x0260, 0x1238: 0x0260, 0x1239: 0x0263, 0x123a: 0x0263, 0x123b: 0x0263, + 0x123c: 0x0263, 0x123d: 0x0266, 0x123e: 0x0266, 0x123f: 0x0266, + // Block 0x49, offset 0x1240 + 0x1240: 0x0266, 0x1241: 0x0269, 0x1242: 0x0269, 0x1243: 0x0269, 0x1244: 0x0269, 0x1245: 0x026c, + 0x1246: 0x026c, 0x1247: 0x026c, 0x1248: 0x026c, 0x1249: 0x026f, 0x124a: 0x026f, 0x124b: 0x026f, + 0x124c: 0x026f, 0x124d: 0x0272, 0x124e: 0x0272, 0x124f: 0x0272, 0x1250: 0x0272, 0x1251: 0x0275, + 0x1252: 0x0275, 0x1253: 0x0275, 0x1254: 0x0275, 0x1255: 0x0278, 0x1256: 0x0278, 0x1257: 0x0278, + 0x1258: 0x0278, 0x1259: 0x027b, 0x125a: 0x027b, 0x125b: 0x027b, 0x125c: 0x027b, 0x125d: 0x027e, + 0x125e: 0x027e, 0x125f: 0x027e, 0x1260: 0x027e, 0x1261: 0x0281, 0x1262: 0x0281, 0x1263: 0x0281, + 0x1264: 0x0281, 0x1265: 0x0284, 0x1266: 0x0284, 0x1267: 0x0284, 0x1268: 0x0284, 0x1269: 0x0287, + 0x126a: 0x0287, 0x126b: 0x0287, 0x126c: 0x0287, 0x126d: 0x028a, 0x126e: 0x028a, 0x126f: 0x028d, + 0x1270: 0x028d, 0x1271: 0x0290, 0x1272: 0x0290, 0x1273: 0x0290, 0x1274: 0x0290, 0x1275: 0x2e00, + 0x1276: 0x2e00, 0x1277: 0x2e08, 0x1278: 0x2e08, 0x1279: 0x2e10, 0x127a: 0x2e10, 0x127b: 0x1f82, + 0x127c: 0x1f82, + // Block 0x4a, offset 0x1280 + 0x1280: 0x0081, 0x1281: 0x0083, 0x1282: 0x0085, 0x1283: 0x0087, 0x1284: 0x0089, 0x1285: 0x008b, + 0x1286: 0x008d, 0x1287: 0x008f, 0x1288: 0x0091, 0x1289: 0x0093, 0x128a: 0x0095, 0x128b: 0x0097, + 0x128c: 0x0099, 0x128d: 0x009b, 0x128e: 0x009d, 0x128f: 0x009f, 0x1290: 0x00a1, 0x1291: 0x00a3, + 0x1292: 0x00a5, 0x1293: 0x00a7, 0x1294: 0x00a9, 0x1295: 0x00ab, 0x1296: 0x00ad, 0x1297: 0x00af, + 0x1298: 0x00b1, 0x1299: 0x00b3, 0x129a: 0x00b5, 0x129b: 0x00b7, 0x129c: 0x00b9, 0x129d: 0x00bb, + 0x129e: 0x00bd, 0x129f: 0x0477, 0x12a0: 0x047b, 0x12a1: 0x0487, 0x12a2: 0x049b, 0x12a3: 0x049f, + 0x12a4: 0x0483, 0x12a5: 0x05ab, 0x12a6: 0x05a3, 0x12a7: 0x04c7, 0x12a8: 0x04cf, 0x12a9: 0x04d7, + 0x12aa: 0x04df, 0x12ab: 0x04e7, 0x12ac: 0x056b, 0x12ad: 0x0573, 0x12ae: 0x057b, 0x12af: 0x051f, + 0x12b0: 0x05af, 0x12b1: 0x04cb, 0x12b2: 0x04d3, 0x12b3: 0x04db, 0x12b4: 0x04e3, 0x12b5: 0x04eb, + 0x12b6: 0x04ef, 0x12b7: 0x04f3, 0x12b8: 0x04f7, 0x12b9: 0x04fb, 0x12ba: 0x04ff, 0x12bb: 0x0503, + 0x12bc: 0x0507, 0x12bd: 0x050b, 0x12be: 0x050f, 0x12bf: 0x0513, + // Block 0x4b, offset 0x12c0 + 0x12c0: 0x0517, 0x12c1: 0x051b, 0x12c2: 0x0523, 0x12c3: 0x0527, 0x12c4: 0x052b, 0x12c5: 0x052f, + 0x12c6: 0x0533, 0x12c7: 0x0537, 0x12c8: 0x053b, 0x12c9: 0x053f, 0x12ca: 0x0543, 0x12cb: 0x0547, + 0x12cc: 0x054b, 0x12cd: 0x054f, 0x12ce: 0x0553, 0x12cf: 0x0557, 0x12d0: 0x055b, 0x12d1: 0x055f, + 0x12d2: 0x0563, 0x12d3: 0x0567, 0x12d4: 0x056f, 0x12d5: 0x0577, 0x12d6: 0x057f, 0x12d7: 0x0583, + 0x12d8: 0x0587, 0x12d9: 0x058b, 0x12da: 0x058f, 0x12db: 0x0593, 0x12dc: 0x0597, 0x12dd: 0x05a7, + 0x12de: 0x4a78, 0x12df: 0x4a7e, 0x12e0: 0x03c3, 0x12e1: 0x0313, 0x12e2: 0x0317, 0x12e3: 0x4a3b, + 0x12e4: 0x031b, 0x12e5: 0x4a41, 0x12e6: 0x4a47, 0x12e7: 0x031f, 0x12e8: 0x0323, 0x12e9: 0x0327, + 0x12ea: 0x4a4d, 0x12eb: 0x4a53, 0x12ec: 0x4a59, 0x12ed: 0x4a5f, 0x12ee: 0x4a65, 0x12ef: 0x4a6b, + 0x12f0: 0x0367, 0x12f1: 0x032b, 0x12f2: 0x032f, 0x12f3: 0x0333, 0x12f4: 0x037b, 0x12f5: 0x0337, + 0x12f6: 0x033b, 0x12f7: 0x033f, 0x12f8: 0x0343, 0x12f9: 0x0347, 0x12fa: 0x034b, 0x12fb: 0x034f, + 0x12fc: 0x0353, 0x12fd: 0x0357, 0x12fe: 0x035b, + // Block 0x4c, offset 0x1300 + 0x1302: 0x49bd, 0x1303: 0x49c3, 0x1304: 0x49c9, 0x1305: 0x49cf, + 0x1306: 0x49d5, 0x1307: 0x49db, 0x130a: 0x49e1, 0x130b: 0x49e7, + 0x130c: 0x49ed, 0x130d: 0x49f3, 0x130e: 0x49f9, 0x130f: 0x49ff, + 0x1312: 0x4a05, 0x1313: 0x4a0b, 0x1314: 0x4a11, 0x1315: 0x4a17, 0x1316: 0x4a1d, 0x1317: 0x4a23, + 0x131a: 0x4a29, 0x131b: 0x4a2f, 0x131c: 0x4a35, + 0x1320: 0x00bf, 0x1321: 0x00c2, 0x1322: 0x00cb, 0x1323: 0x4264, + 0x1324: 0x00c8, 0x1325: 0x00c5, 0x1326: 0x0447, 0x1328: 0x046b, 0x1329: 0x044b, + 0x132a: 0x044f, 0x132b: 0x0453, 0x132c: 0x0457, 0x132d: 0x046f, 0x132e: 0x0473, + // Block 0x4d, offset 0x1340 + 0x1340: 0x0063, 0x1341: 0x0065, 0x1342: 0x0067, 0x1343: 0x0069, 0x1344: 0x006b, 0x1345: 0x006d, + 0x1346: 0x006f, 0x1347: 0x0071, 0x1348: 0x0073, 0x1349: 0x0075, 0x134a: 0x0083, 0x134b: 0x0085, + 0x134c: 0x0087, 0x134d: 0x0089, 0x134e: 0x008b, 0x134f: 0x008d, 0x1350: 0x008f, 0x1351: 0x0091, + 0x1352: 0x0093, 0x1353: 0x0095, 0x1354: 0x0097, 0x1355: 0x0099, 0x1356: 0x009b, 0x1357: 0x009d, + 0x1358: 0x009f, 0x1359: 0x00a1, 0x135a: 0x00a3, 0x135b: 0x00a5, 0x135c: 0x00a7, 0x135d: 0x00a9, + 0x135e: 0x00ab, 0x135f: 0x00ad, 0x1360: 0x00af, 0x1361: 0x00b1, 0x1362: 0x00b3, 0x1363: 0x00b5, + 0x1364: 0x00dd, 0x1365: 0x00f2, 0x1368: 0x0173, 0x1369: 0x0176, + 0x136a: 0x0179, 0x136b: 0x017c, 0x136c: 0x017f, 0x136d: 0x0182, 0x136e: 0x0185, 0x136f: 0x0188, + 0x1370: 0x018b, 0x1371: 0x018e, 0x1372: 0x0191, 0x1373: 0x0194, 0x1374: 0x0197, 0x1375: 0x019a, + 0x1376: 0x019d, 0x1377: 0x01a0, 0x1378: 0x01a3, 0x1379: 0x0188, 0x137a: 0x01a6, 0x137b: 0x01a9, + 0x137c: 0x01ac, 0x137d: 0x01af, 0x137e: 0x01b2, 0x137f: 0x01b5, + // Block 0x4e, offset 0x1380 + 0x1380: 0x01fd, 0x1381: 0x0200, 0x1382: 0x0203, 0x1383: 0x045b, 0x1384: 0x01c7, 0x1385: 0x01d0, + 0x1386: 0x01d6, 0x1387: 0x01fa, 0x1388: 0x01eb, 0x1389: 0x01e8, 0x138a: 0x0206, 0x138b: 0x0209, + 0x138e: 0x0021, 0x138f: 0x0023, 0x1390: 0x0025, 0x1391: 0x0027, + 0x1392: 0x0029, 0x1393: 0x002b, 0x1394: 0x002d, 0x1395: 0x002f, 0x1396: 0x0031, 0x1397: 0x0033, + 0x1398: 0x0021, 0x1399: 0x0023, 0x139a: 0x0025, 0x139b: 0x0027, 0x139c: 0x0029, 0x139d: 0x002b, + 0x139e: 0x002d, 0x139f: 0x002f, 0x13a0: 0x0031, 0x13a1: 0x0033, 0x13a2: 0x0021, 0x13a3: 0x0023, + 0x13a4: 0x0025, 0x13a5: 0x0027, 0x13a6: 0x0029, 0x13a7: 0x002b, 0x13a8: 0x002d, 0x13a9: 0x002f, + 0x13aa: 0x0031, 0x13ab: 0x0033, 0x13ac: 0x0021, 0x13ad: 0x0023, 0x13ae: 0x0025, 0x13af: 0x0027, + 0x13b0: 0x0029, 0x13b1: 0x002b, 0x13b2: 0x002d, 0x13b3: 0x002f, 0x13b4: 0x0031, 0x13b5: 0x0033, + 0x13b6: 0x0021, 0x13b7: 0x0023, 0x13b8: 0x0025, 0x13b9: 0x0027, 0x13ba: 0x0029, 0x13bb: 0x002b, + 0x13bc: 0x002d, 0x13bd: 0x002f, 0x13be: 0x0031, 0x13bf: 0x0033, + // Block 0x4f, offset 0x13c0 + 0x13c0: 0x0239, 0x13c1: 0x023c, 0x13c2: 0x0248, 0x13c3: 0x0251, 0x13c5: 0x028a, + 0x13c6: 0x025a, 0x13c7: 0x024b, 0x13c8: 0x0269, 0x13c9: 0x0290, 0x13ca: 0x027b, 0x13cb: 0x027e, + 0x13cc: 0x0281, 0x13cd: 0x0284, 0x13ce: 0x025d, 0x13cf: 0x026f, 0x13d0: 0x0275, 0x13d1: 0x0263, + 0x13d2: 0x0278, 0x13d3: 0x0257, 0x13d4: 0x0260, 0x13d5: 0x0242, 0x13d6: 0x0245, 0x13d7: 0x024e, + 0x13d8: 0x0254, 0x13d9: 0x0266, 0x13da: 0x026c, 0x13db: 0x0272, 0x13dc: 0x0293, 0x13dd: 0x02e4, + 0x13de: 0x02cc, 0x13df: 0x0296, 0x13e1: 0x023c, 0x13e2: 0x0248, + 0x13e4: 0x0287, 0x13e7: 0x024b, 0x13e9: 0x0290, + 0x13ea: 0x027b, 0x13eb: 0x027e, 0x13ec: 0x0281, 0x13ed: 0x0284, 0x13ee: 0x025d, 0x13ef: 0x026f, + 0x13f0: 0x0275, 0x13f1: 0x0263, 0x13f2: 0x0278, 0x13f4: 0x0260, 0x13f5: 0x0242, + 0x13f6: 0x0245, 0x13f7: 0x024e, 0x13f9: 0x0266, 0x13fb: 0x0272, + // Block 0x50, offset 0x1400 + 0x1402: 0x0248, + 0x1407: 0x024b, 0x1409: 0x0290, 0x140b: 0x027e, + 0x140d: 0x0284, 0x140e: 0x025d, 0x140f: 0x026f, 0x1411: 0x0263, + 0x1412: 0x0278, 0x1414: 0x0260, 0x1417: 0x024e, + 0x1419: 0x0266, 0x141b: 0x0272, 0x141d: 0x02e4, + 0x141f: 0x0296, 0x1421: 0x023c, 0x1422: 0x0248, + 0x1424: 0x0287, 0x1427: 0x024b, 0x1428: 0x0269, 0x1429: 0x0290, + 0x142a: 0x027b, 0x142c: 0x0281, 0x142d: 0x0284, 0x142e: 0x025d, 0x142f: 0x026f, + 0x1430: 0x0275, 0x1431: 0x0263, 0x1432: 0x0278, 0x1434: 0x0260, 0x1435: 0x0242, + 0x1436: 0x0245, 0x1437: 0x024e, 0x1439: 0x0266, 0x143a: 0x026c, 0x143b: 0x0272, + 0x143c: 0x0293, 0x143e: 0x02cc, + // Block 0x51, offset 0x1440 + 0x1440: 0x0239, 0x1441: 0x023c, 0x1442: 0x0248, 0x1443: 0x0251, 0x1444: 0x0287, 0x1445: 0x028a, + 0x1446: 0x025a, 0x1447: 0x024b, 0x1448: 0x0269, 0x1449: 0x0290, 0x144b: 0x027e, + 0x144c: 0x0281, 0x144d: 0x0284, 0x144e: 0x025d, 0x144f: 0x026f, 0x1450: 0x0275, 0x1451: 0x0263, + 0x1452: 0x0278, 0x1453: 0x0257, 0x1454: 0x0260, 0x1455: 0x0242, 0x1456: 0x0245, 0x1457: 0x024e, + 0x1458: 0x0254, 0x1459: 0x0266, 0x145a: 0x026c, 0x145b: 0x0272, + 0x1461: 0x023c, 0x1462: 0x0248, 0x1463: 0x0251, + 0x1465: 0x028a, 0x1466: 0x025a, 0x1467: 0x024b, 0x1468: 0x0269, 0x1469: 0x0290, + 0x146b: 0x027e, 0x146c: 0x0281, 0x146d: 0x0284, 0x146e: 0x025d, 0x146f: 0x026f, + 0x1470: 0x0275, 0x1471: 0x0263, 0x1472: 0x0278, 0x1473: 0x0257, 0x1474: 0x0260, 0x1475: 0x0242, + 0x1476: 0x0245, 0x1477: 0x024e, 0x1478: 0x0254, 0x1479: 0x0266, 0x147a: 0x026c, 0x147b: 0x0272, + // Block 0x52, offset 0x1480 + 0x1480: 0x1879, 0x1481: 0x1876, 0x1482: 0x187c, 0x1483: 0x18a0, 0x1484: 0x18c4, 0x1485: 0x18e8, + 0x1486: 0x190c, 0x1487: 0x1915, 0x1488: 0x191b, 0x1489: 0x1921, 0x148a: 0x1927, + 0x1490: 0x1a8c, 0x1491: 0x1a90, + 0x1492: 0x1a94, 0x1493: 0x1a98, 0x1494: 0x1a9c, 0x1495: 0x1aa0, 0x1496: 0x1aa4, 0x1497: 0x1aa8, + 0x1498: 0x1aac, 0x1499: 0x1ab0, 0x149a: 0x1ab4, 0x149b: 0x1ab8, 0x149c: 0x1abc, 0x149d: 0x1ac0, + 0x149e: 0x1ac4, 0x149f: 0x1ac8, 0x14a0: 0x1acc, 0x14a1: 0x1ad0, 0x14a2: 0x1ad4, 0x14a3: 0x1ad8, + 0x14a4: 0x1adc, 0x14a5: 0x1ae0, 0x14a6: 0x1ae4, 0x14a7: 0x1ae8, 0x14a8: 0x1aec, 0x14a9: 0x1af0, + 0x14aa: 0x271e, 0x14ab: 0x0047, 0x14ac: 0x0065, 0x14ad: 0x193c, 0x14ae: 0x19b1, + 0x14b0: 0x0043, 0x14b1: 0x0045, 0x14b2: 0x0047, 0x14b3: 0x0049, 0x14b4: 0x004b, 0x14b5: 0x004d, + 0x14b6: 0x004f, 0x14b7: 0x0051, 0x14b8: 0x0053, 0x14b9: 0x0055, 0x14ba: 0x0057, 0x14bb: 0x0059, + 0x14bc: 0x005b, 0x14bd: 0x005d, 0x14be: 0x005f, 0x14bf: 0x0061, + // Block 0x53, offset 0x14c0 + 0x14c0: 0x26ad, 0x14c1: 0x26c2, 0x14c2: 0x0503, + 0x14d0: 0x0c0f, 0x14d1: 0x0a47, + 0x14d2: 0x08d3, 0x14d3: 0x45c4, 0x14d4: 0x071b, 0x14d5: 0x09ef, 0x14d6: 0x132f, 0x14d7: 0x09ff, + 0x14d8: 0x0727, 0x14d9: 0x0cd7, 0x14da: 0x0eaf, 0x14db: 0x0caf, 0x14dc: 0x0827, 0x14dd: 0x0b6b, + 0x14de: 0x07bf, 0x14df: 0x0cb7, 0x14e0: 0x0813, 0x14e1: 0x1117, 0x14e2: 0x0f83, 0x14e3: 0x138b, + 0x14e4: 0x09d3, 0x14e5: 0x090b, 0x14e6: 0x0e63, 0x14e7: 0x0c1b, 0x14e8: 0x0c47, 0x14e9: 0x06bf, + 0x14ea: 0x06cb, 0x14eb: 0x140b, 0x14ec: 0x0adb, 0x14ed: 0x06e7, 0x14ee: 0x08ef, 0x14ef: 0x0c3b, + 0x14f0: 0x13b3, 0x14f1: 0x0c13, 0x14f2: 0x106f, 0x14f3: 0x10ab, 0x14f4: 0x08f7, 0x14f5: 0x0e43, + 0x14f6: 0x0d0b, 0x14f7: 0x0d07, 0x14f8: 0x0f97, 0x14f9: 0x082b, 0x14fa: 0x0957, 0x14fb: 0x1443, + // Block 0x54, offset 0x1500 + 0x1500: 0x06fb, 0x1501: 0x06f3, 0x1502: 0x0703, 0x1503: 0x1647, 0x1504: 0x0747, 0x1505: 0x0757, + 0x1506: 0x075b, 0x1507: 0x0763, 0x1508: 0x076b, 0x1509: 0x076f, 0x150a: 0x077b, 0x150b: 0x0773, + 0x150c: 0x05b3, 0x150d: 0x165b, 0x150e: 0x078f, 0x150f: 0x0793, 0x1510: 0x0797, 0x1511: 0x07b3, + 0x1512: 0x164c, 0x1513: 0x05b7, 0x1514: 0x079f, 0x1515: 0x07bf, 0x1516: 0x1656, 0x1517: 0x07cf, + 0x1518: 0x07d7, 0x1519: 0x0737, 0x151a: 0x07df, 0x151b: 0x07e3, 0x151c: 0x1831, 0x151d: 0x07ff, + 0x151e: 0x0807, 0x151f: 0x05bf, 0x1520: 0x081f, 0x1521: 0x0823, 0x1522: 0x082b, 0x1523: 0x082f, + 0x1524: 0x05c3, 0x1525: 0x0847, 0x1526: 0x084b, 0x1527: 0x0857, 0x1528: 0x0863, 0x1529: 0x0867, + 0x152a: 0x086b, 0x152b: 0x0873, 0x152c: 0x0893, 0x152d: 0x0897, 0x152e: 0x089f, 0x152f: 0x08af, + 0x1530: 0x08b7, 0x1531: 0x08bb, 0x1532: 0x08bb, 0x1533: 0x08bb, 0x1534: 0x166a, 0x1535: 0x0e93, + 0x1536: 0x08cf, 0x1537: 0x08d7, 0x1538: 0x166f, 0x1539: 0x08e3, 0x153a: 0x08eb, 0x153b: 0x08f3, + 0x153c: 0x091b, 0x153d: 0x0907, 0x153e: 0x0913, 0x153f: 0x0917, + // Block 0x55, offset 0x1540 + 0x1540: 0x091f, 0x1541: 0x0927, 0x1542: 0x092b, 0x1543: 0x0933, 0x1544: 0x093b, 0x1545: 0x093f, + 0x1546: 0x093f, 0x1547: 0x0947, 0x1548: 0x094f, 0x1549: 0x0953, 0x154a: 0x095f, 0x154b: 0x0983, + 0x154c: 0x0967, 0x154d: 0x0987, 0x154e: 0x096b, 0x154f: 0x0973, 0x1550: 0x080b, 0x1551: 0x09cf, + 0x1552: 0x0997, 0x1553: 0x099b, 0x1554: 0x099f, 0x1555: 0x0993, 0x1556: 0x09a7, 0x1557: 0x09a3, + 0x1558: 0x09bb, 0x1559: 0x1674, 0x155a: 0x09d7, 0x155b: 0x09db, 0x155c: 0x09e3, 0x155d: 0x09ef, + 0x155e: 0x09f7, 0x155f: 0x0a13, 0x1560: 0x1679, 0x1561: 0x167e, 0x1562: 0x0a1f, 0x1563: 0x0a23, + 0x1564: 0x0a27, 0x1565: 0x0a1b, 0x1566: 0x0a2f, 0x1567: 0x05c7, 0x1568: 0x05cb, 0x1569: 0x0a37, + 0x156a: 0x0a3f, 0x156b: 0x0a3f, 0x156c: 0x1683, 0x156d: 0x0a5b, 0x156e: 0x0a5f, 0x156f: 0x0a63, + 0x1570: 0x0a6b, 0x1571: 0x1688, 0x1572: 0x0a73, 0x1573: 0x0a77, 0x1574: 0x0b4f, 0x1575: 0x0a7f, + 0x1576: 0x05cf, 0x1577: 0x0a8b, 0x1578: 0x0a9b, 0x1579: 0x0aa7, 0x157a: 0x0aa3, 0x157b: 0x1692, + 0x157c: 0x0aaf, 0x157d: 0x1697, 0x157e: 0x0abb, 0x157f: 0x0ab7, + // Block 0x56, offset 0x1580 + 0x1580: 0x0abf, 0x1581: 0x0acf, 0x1582: 0x0ad3, 0x1583: 0x05d3, 0x1584: 0x0ae3, 0x1585: 0x0aeb, + 0x1586: 0x0aef, 0x1587: 0x0af3, 0x1588: 0x05d7, 0x1589: 0x169c, 0x158a: 0x05db, 0x158b: 0x0b0f, + 0x158c: 0x0b13, 0x158d: 0x0b17, 0x158e: 0x0b1f, 0x158f: 0x1863, 0x1590: 0x0b37, 0x1591: 0x16a6, + 0x1592: 0x16a6, 0x1593: 0x11d7, 0x1594: 0x0b47, 0x1595: 0x0b47, 0x1596: 0x05df, 0x1597: 0x16c9, + 0x1598: 0x179b, 0x1599: 0x0b57, 0x159a: 0x0b5f, 0x159b: 0x05e3, 0x159c: 0x0b73, 0x159d: 0x0b83, + 0x159e: 0x0b87, 0x159f: 0x0b8f, 0x15a0: 0x0b9f, 0x15a1: 0x05eb, 0x15a2: 0x05e7, 0x15a3: 0x0ba3, + 0x15a4: 0x16ab, 0x15a5: 0x0ba7, 0x15a6: 0x0bbb, 0x15a7: 0x0bbf, 0x15a8: 0x0bc3, 0x15a9: 0x0bbf, + 0x15aa: 0x0bcf, 0x15ab: 0x0bd3, 0x15ac: 0x0be3, 0x15ad: 0x0bdb, 0x15ae: 0x0bdf, 0x15af: 0x0be7, + 0x15b0: 0x0beb, 0x15b1: 0x0bef, 0x15b2: 0x0bfb, 0x15b3: 0x0bff, 0x15b4: 0x0c17, 0x15b5: 0x0c1f, + 0x15b6: 0x0c2f, 0x15b7: 0x0c43, 0x15b8: 0x16ba, 0x15b9: 0x0c3f, 0x15ba: 0x0c33, 0x15bb: 0x0c4b, + 0x15bc: 0x0c53, 0x15bd: 0x0c67, 0x15be: 0x16bf, 0x15bf: 0x0c6f, + // Block 0x57, offset 0x15c0 + 0x15c0: 0x0c63, 0x15c1: 0x0c5b, 0x15c2: 0x05ef, 0x15c3: 0x0c77, 0x15c4: 0x0c7f, 0x15c5: 0x0c87, + 0x15c6: 0x0c7b, 0x15c7: 0x05f3, 0x15c8: 0x0c97, 0x15c9: 0x0c9f, 0x15ca: 0x16c4, 0x15cb: 0x0ccb, + 0x15cc: 0x0cff, 0x15cd: 0x0cdb, 0x15ce: 0x05ff, 0x15cf: 0x0ce7, 0x15d0: 0x05fb, 0x15d1: 0x05f7, + 0x15d2: 0x07c3, 0x15d3: 0x07c7, 0x15d4: 0x0d03, 0x15d5: 0x0ceb, 0x15d6: 0x11ab, 0x15d7: 0x0663, + 0x15d8: 0x0d0f, 0x15d9: 0x0d13, 0x15da: 0x0d17, 0x15db: 0x0d2b, 0x15dc: 0x0d23, 0x15dd: 0x16dd, + 0x15de: 0x0603, 0x15df: 0x0d3f, 0x15e0: 0x0d33, 0x15e1: 0x0d4f, 0x15e2: 0x0d57, 0x15e3: 0x16e7, + 0x15e4: 0x0d5b, 0x15e5: 0x0d47, 0x15e6: 0x0d63, 0x15e7: 0x0607, 0x15e8: 0x0d67, 0x15e9: 0x0d6b, + 0x15ea: 0x0d6f, 0x15eb: 0x0d7b, 0x15ec: 0x16ec, 0x15ed: 0x0d83, 0x15ee: 0x060b, 0x15ef: 0x0d8f, + 0x15f0: 0x16f1, 0x15f1: 0x0d93, 0x15f2: 0x060f, 0x15f3: 0x0d9f, 0x15f4: 0x0dab, 0x15f5: 0x0db7, + 0x15f6: 0x0dbb, 0x15f7: 0x16f6, 0x15f8: 0x168d, 0x15f9: 0x16fb, 0x15fa: 0x0ddb, 0x15fb: 0x1700, + 0x15fc: 0x0de7, 0x15fd: 0x0def, 0x15fe: 0x0ddf, 0x15ff: 0x0dfb, + // Block 0x58, offset 0x1600 + 0x1600: 0x0e0b, 0x1601: 0x0e1b, 0x1602: 0x0e0f, 0x1603: 0x0e13, 0x1604: 0x0e1f, 0x1605: 0x0e23, + 0x1606: 0x1705, 0x1607: 0x0e07, 0x1608: 0x0e3b, 0x1609: 0x0e3f, 0x160a: 0x0613, 0x160b: 0x0e53, + 0x160c: 0x0e4f, 0x160d: 0x170a, 0x160e: 0x0e33, 0x160f: 0x0e6f, 0x1610: 0x170f, 0x1611: 0x1714, + 0x1612: 0x0e73, 0x1613: 0x0e87, 0x1614: 0x0e83, 0x1615: 0x0e7f, 0x1616: 0x0617, 0x1617: 0x0e8b, + 0x1618: 0x0e9b, 0x1619: 0x0e97, 0x161a: 0x0ea3, 0x161b: 0x1651, 0x161c: 0x0eb3, 0x161d: 0x1719, + 0x161e: 0x0ebf, 0x161f: 0x1723, 0x1620: 0x0ed3, 0x1621: 0x0edf, 0x1622: 0x0ef3, 0x1623: 0x1728, + 0x1624: 0x0f07, 0x1625: 0x0f0b, 0x1626: 0x172d, 0x1627: 0x1732, 0x1628: 0x0f27, 0x1629: 0x0f37, + 0x162a: 0x061b, 0x162b: 0x0f3b, 0x162c: 0x061f, 0x162d: 0x061f, 0x162e: 0x0f53, 0x162f: 0x0f57, + 0x1630: 0x0f5f, 0x1631: 0x0f63, 0x1632: 0x0f6f, 0x1633: 0x0623, 0x1634: 0x0f87, 0x1635: 0x1737, + 0x1636: 0x0fa3, 0x1637: 0x173c, 0x1638: 0x0faf, 0x1639: 0x16a1, 0x163a: 0x0fbf, 0x163b: 0x1741, + 0x163c: 0x1746, 0x163d: 0x174b, 0x163e: 0x0627, 0x163f: 0x062b, + // Block 0x59, offset 0x1640 + 0x1640: 0x0ff7, 0x1641: 0x1755, 0x1642: 0x1750, 0x1643: 0x175a, 0x1644: 0x175f, 0x1645: 0x0fff, + 0x1646: 0x1003, 0x1647: 0x1003, 0x1648: 0x100b, 0x1649: 0x0633, 0x164a: 0x100f, 0x164b: 0x0637, + 0x164c: 0x063b, 0x164d: 0x1769, 0x164e: 0x1023, 0x164f: 0x102b, 0x1650: 0x1037, 0x1651: 0x063f, + 0x1652: 0x176e, 0x1653: 0x105b, 0x1654: 0x1773, 0x1655: 0x1778, 0x1656: 0x107b, 0x1657: 0x1093, + 0x1658: 0x0643, 0x1659: 0x109b, 0x165a: 0x109f, 0x165b: 0x10a3, 0x165c: 0x177d, 0x165d: 0x1782, + 0x165e: 0x1782, 0x165f: 0x10bb, 0x1660: 0x0647, 0x1661: 0x1787, 0x1662: 0x10cf, 0x1663: 0x10d3, + 0x1664: 0x064b, 0x1665: 0x178c, 0x1666: 0x10ef, 0x1667: 0x064f, 0x1668: 0x10ff, 0x1669: 0x10f7, + 0x166a: 0x1107, 0x166b: 0x1796, 0x166c: 0x111f, 0x166d: 0x0653, 0x166e: 0x112b, 0x166f: 0x1133, + 0x1670: 0x1143, 0x1671: 0x0657, 0x1672: 0x17a0, 0x1673: 0x17a5, 0x1674: 0x065b, 0x1675: 0x17aa, + 0x1676: 0x115b, 0x1677: 0x17af, 0x1678: 0x1167, 0x1679: 0x1173, 0x167a: 0x117b, 0x167b: 0x17b4, + 0x167c: 0x17b9, 0x167d: 0x118f, 0x167e: 0x17be, 0x167f: 0x1197, + // Block 0x5a, offset 0x1680 + 0x1680: 0x16ce, 0x1681: 0x065f, 0x1682: 0x11af, 0x1683: 0x11b3, 0x1684: 0x0667, 0x1685: 0x11b7, + 0x1686: 0x0a33, 0x1687: 0x17c3, 0x1688: 0x17c8, 0x1689: 0x16d3, 0x168a: 0x16d8, 0x168b: 0x11d7, + 0x168c: 0x11db, 0x168d: 0x13f3, 0x168e: 0x066b, 0x168f: 0x1207, 0x1690: 0x1203, 0x1691: 0x120b, + 0x1692: 0x083f, 0x1693: 0x120f, 0x1694: 0x1213, 0x1695: 0x1217, 0x1696: 0x121f, 0x1697: 0x17cd, + 0x1698: 0x121b, 0x1699: 0x1223, 0x169a: 0x1237, 0x169b: 0x123b, 0x169c: 0x1227, 0x169d: 0x123f, + 0x169e: 0x1253, 0x169f: 0x1267, 0x16a0: 0x1233, 0x16a1: 0x1247, 0x16a2: 0x124b, 0x16a3: 0x124f, + 0x16a4: 0x17d2, 0x16a5: 0x17dc, 0x16a6: 0x17d7, 0x16a7: 0x066f, 0x16a8: 0x126f, 0x16a9: 0x1273, + 0x16aa: 0x127b, 0x16ab: 0x17f0, 0x16ac: 0x127f, 0x16ad: 0x17e1, 0x16ae: 0x0673, 0x16af: 0x0677, + 0x16b0: 0x17e6, 0x16b1: 0x17eb, 0x16b2: 0x067b, 0x16b3: 0x129f, 0x16b4: 0x12a3, 0x16b5: 0x12a7, + 0x16b6: 0x12ab, 0x16b7: 0x12b7, 0x16b8: 0x12b3, 0x16b9: 0x12bf, 0x16ba: 0x12bb, 0x16bb: 0x12cb, + 0x16bc: 0x12c3, 0x16bd: 0x12c7, 0x16be: 0x12cf, 0x16bf: 0x067f, + // Block 0x5b, offset 0x16c0 + 0x16c0: 0x12d7, 0x16c1: 0x12db, 0x16c2: 0x0683, 0x16c3: 0x12eb, 0x16c4: 0x12ef, 0x16c5: 0x17f5, + 0x16c6: 0x12fb, 0x16c7: 0x12ff, 0x16c8: 0x0687, 0x16c9: 0x130b, 0x16ca: 0x05bb, 0x16cb: 0x17fa, + 0x16cc: 0x17ff, 0x16cd: 0x068b, 0x16ce: 0x068f, 0x16cf: 0x1337, 0x16d0: 0x134f, 0x16d1: 0x136b, + 0x16d2: 0x137b, 0x16d3: 0x1804, 0x16d4: 0x138f, 0x16d5: 0x1393, 0x16d6: 0x13ab, 0x16d7: 0x13b7, + 0x16d8: 0x180e, 0x16d9: 0x1660, 0x16da: 0x13c3, 0x16db: 0x13bf, 0x16dc: 0x13cb, 0x16dd: 0x1665, + 0x16de: 0x13d7, 0x16df: 0x13e3, 0x16e0: 0x1813, 0x16e1: 0x1818, 0x16e2: 0x1423, 0x16e3: 0x142f, + 0x16e4: 0x1437, 0x16e5: 0x181d, 0x16e6: 0x143b, 0x16e7: 0x1467, 0x16e8: 0x1473, 0x16e9: 0x1477, + 0x16ea: 0x146f, 0x16eb: 0x1483, 0x16ec: 0x1487, 0x16ed: 0x1822, 0x16ee: 0x1493, 0x16ef: 0x0693, + 0x16f0: 0x149b, 0x16f1: 0x1827, 0x16f2: 0x0697, 0x16f3: 0x14d3, 0x16f4: 0x0ac3, 0x16f5: 0x14eb, + 0x16f6: 0x182c, 0x16f7: 0x1836, 0x16f8: 0x069b, 0x16f9: 0x069f, 0x16fa: 0x1513, 0x16fb: 0x183b, + 0x16fc: 0x06a3, 0x16fd: 0x1840, 0x16fe: 0x152b, 0x16ff: 0x152b, + // Block 0x5c, offset 0x1700 + 0x1700: 0x1533, 0x1701: 0x1845, 0x1702: 0x154b, 0x1703: 0x06a7, 0x1704: 0x155b, 0x1705: 0x1567, + 0x1706: 0x156f, 0x1707: 0x1577, 0x1708: 0x06ab, 0x1709: 0x184a, 0x170a: 0x158b, 0x170b: 0x15a7, + 0x170c: 0x15b3, 0x170d: 0x06af, 0x170e: 0x06b3, 0x170f: 0x15b7, 0x1710: 0x184f, 0x1711: 0x06b7, + 0x1712: 0x1854, 0x1713: 0x1859, 0x1714: 0x185e, 0x1715: 0x15db, 0x1716: 0x06bb, 0x1717: 0x15ef, + 0x1718: 0x15f7, 0x1719: 0x15fb, 0x171a: 0x1603, 0x171b: 0x160b, 0x171c: 0x1613, 0x171d: 0x1868, +} + +// nfkcIndex: 22 blocks, 1408 entries, 1408 bytes +// Block 0 is the zero block. +var nfkcIndex = [1408]uint8{ + // Block 0x0, offset 0x0 + // Block 0x1, offset 0x40 + // Block 0x2, offset 0x80 + // Block 0x3, offset 0xc0 + 0xc2: 0x5b, 0xc3: 0x01, 0xc4: 0x02, 0xc5: 0x03, 0xc6: 0x5c, 0xc7: 0x04, + 0xc8: 0x05, 0xca: 0x5d, 0xcb: 0x5e, 0xcc: 0x06, 0xcd: 0x07, 0xce: 0x08, 0xcf: 0x09, + 0xd0: 0x0a, 0xd1: 0x5f, 0xd2: 0x60, 0xd3: 0x0b, 0xd6: 0x0c, 0xd7: 0x61, + 0xd8: 0x62, 0xd9: 0x0d, 0xdb: 0x63, 0xdc: 0x64, 0xdd: 0x65, 0xdf: 0x66, + 0xe0: 0x02, 0xe1: 0x03, 0xe2: 0x04, 0xe3: 0x05, + 0xea: 0x06, 0xeb: 0x07, 0xec: 0x08, 0xed: 0x09, 0xef: 0x0a, + 0xf0: 0x13, + // Block 0x4, offset 0x100 + 0x120: 0x67, 0x121: 0x68, 0x123: 0x69, 0x124: 0x6a, 0x125: 0x6b, 0x126: 0x6c, 0x127: 0x6d, + 0x128: 0x6e, 0x129: 0x6f, 0x12a: 0x70, 0x12b: 0x71, 0x12c: 0x6c, 0x12d: 0x72, 0x12e: 0x73, 0x12f: 0x74, + 0x131: 0x75, 0x132: 0x76, 0x133: 0x77, 0x134: 0x78, 0x135: 0x79, 0x137: 0x7a, + 0x138: 0x7b, 0x139: 0x7c, 0x13a: 0x7d, 0x13b: 0x7e, 0x13c: 0x7f, 0x13d: 0x80, 0x13e: 0x81, 0x13f: 0x82, + // Block 0x5, offset 0x140 + 0x140: 0x83, 0x142: 0x84, 0x143: 0x85, 0x144: 0x86, 0x145: 0x87, 0x146: 0x88, 0x147: 0x89, + 0x14d: 0x8a, + 0x15c: 0x8b, 0x15f: 0x8c, + 0x162: 0x8d, 0x164: 0x8e, + 0x168: 0x8f, 0x169: 0x90, 0x16a: 0x91, 0x16c: 0x0e, 0x16d: 0x92, 0x16e: 0x93, 0x16f: 0x94, + 0x170: 0x95, 0x173: 0x96, 0x174: 0x97, 0x175: 0x0f, 0x176: 0x10, 0x177: 0x11, + 0x178: 0x12, 0x179: 0x13, 0x17a: 0x14, 0x17b: 0x15, 0x17c: 0x16, 0x17d: 0x17, 0x17e: 0x18, 0x17f: 0x19, + // Block 0x6, offset 0x180 + 0x180: 0x98, 0x181: 0x99, 0x182: 0x9a, 0x183: 0x9b, 0x184: 0x1a, 0x185: 0x1b, 0x186: 0x9c, 0x187: 0x9d, + 0x188: 0x9e, 0x189: 0x1c, 0x18a: 0x1d, 0x18b: 0x9f, 0x18c: 0xa0, + 0x191: 0x1e, 0x192: 0x1f, 0x193: 0xa1, + 0x1a8: 0xa2, 0x1a9: 0xa3, 0x1ab: 0xa4, + 0x1b1: 0xa5, 0x1b3: 0xa6, 0x1b5: 0xa7, 0x1b7: 0xa8, + 0x1ba: 0xa9, 0x1bb: 0xaa, 0x1bc: 0x20, 0x1bd: 0x21, 0x1be: 0x22, 0x1bf: 0xab, + // Block 0x7, offset 0x1c0 + 0x1c0: 0xac, 0x1c1: 0x23, 0x1c2: 0x24, 0x1c3: 0x25, 0x1c4: 0xad, 0x1c5: 0x26, 0x1c6: 0x27, + 0x1c8: 0x28, 0x1c9: 0x29, 0x1ca: 0x2a, 0x1cb: 0x2b, 0x1cc: 0x2c, 0x1cd: 0x2d, 0x1ce: 0x2e, 0x1cf: 0x2f, + // Block 0x8, offset 0x200 + 0x219: 0xae, 0x21a: 0xaf, 0x21b: 0xb0, 0x21d: 0xb1, 0x21f: 0xb2, + 0x220: 0xb3, 0x223: 0xb4, 0x224: 0xb5, 0x225: 0xb6, 0x226: 0xb7, 0x227: 0xb8, + 0x22a: 0xb9, 0x22b: 0xba, 0x22d: 0xbb, 0x22f: 0xbc, + 0x230: 0xbd, 0x231: 0xbe, 0x232: 0xbf, 0x233: 0xc0, 0x234: 0xc1, 0x235: 0xc2, 0x236: 0xc3, 0x237: 0xbd, + 0x238: 0xbe, 0x239: 0xbf, 0x23a: 0xc0, 0x23b: 0xc1, 0x23c: 0xc2, 0x23d: 0xc3, 0x23e: 0xbd, 0x23f: 0xbe, + // Block 0x9, offset 0x240 + 0x240: 0xbf, 0x241: 0xc0, 0x242: 0xc1, 0x243: 0xc2, 0x244: 0xc3, 0x245: 0xbd, 0x246: 0xbe, 0x247: 0xbf, + 0x248: 0xc0, 0x249: 0xc1, 0x24a: 0xc2, 0x24b: 0xc3, 0x24c: 0xbd, 0x24d: 0xbe, 0x24e: 0xbf, 0x24f: 0xc0, + 0x250: 0xc1, 0x251: 0xc2, 0x252: 0xc3, 0x253: 0xbd, 0x254: 0xbe, 0x255: 0xbf, 0x256: 0xc0, 0x257: 0xc1, + 0x258: 0xc2, 0x259: 0xc3, 0x25a: 0xbd, 0x25b: 0xbe, 0x25c: 0xbf, 0x25d: 0xc0, 0x25e: 0xc1, 0x25f: 0xc2, + 0x260: 0xc3, 0x261: 0xbd, 0x262: 0xbe, 0x263: 0xbf, 0x264: 0xc0, 0x265: 0xc1, 0x266: 0xc2, 0x267: 0xc3, + 0x268: 0xbd, 0x269: 0xbe, 0x26a: 0xbf, 0x26b: 0xc0, 0x26c: 0xc1, 0x26d: 0xc2, 0x26e: 0xc3, 0x26f: 0xbd, + 0x270: 0xbe, 0x271: 0xbf, 0x272: 0xc0, 0x273: 0xc1, 0x274: 0xc2, 0x275: 0xc3, 0x276: 0xbd, 0x277: 0xbe, + 0x278: 0xbf, 0x279: 0xc0, 0x27a: 0xc1, 0x27b: 0xc2, 0x27c: 0xc3, 0x27d: 0xbd, 0x27e: 0xbe, 0x27f: 0xbf, + // Block 0xa, offset 0x280 + 0x280: 0xc0, 0x281: 0xc1, 0x282: 0xc2, 0x283: 0xc3, 0x284: 0xbd, 0x285: 0xbe, 0x286: 0xbf, 0x287: 0xc0, + 0x288: 0xc1, 0x289: 0xc2, 0x28a: 0xc3, 0x28b: 0xbd, 0x28c: 0xbe, 0x28d: 0xbf, 0x28e: 0xc0, 0x28f: 0xc1, + 0x290: 0xc2, 0x291: 0xc3, 0x292: 0xbd, 0x293: 0xbe, 0x294: 0xbf, 0x295: 0xc0, 0x296: 0xc1, 0x297: 0xc2, + 0x298: 0xc3, 0x299: 0xbd, 0x29a: 0xbe, 0x29b: 0xbf, 0x29c: 0xc0, 0x29d: 0xc1, 0x29e: 0xc2, 0x29f: 0xc3, + 0x2a0: 0xbd, 0x2a1: 0xbe, 0x2a2: 0xbf, 0x2a3: 0xc0, 0x2a4: 0xc1, 0x2a5: 0xc2, 0x2a6: 0xc3, 0x2a7: 0xbd, + 0x2a8: 0xbe, 0x2a9: 0xbf, 0x2aa: 0xc0, 0x2ab: 0xc1, 0x2ac: 0xc2, 0x2ad: 0xc3, 0x2ae: 0xbd, 0x2af: 0xbe, + 0x2b0: 0xbf, 0x2b1: 0xc0, 0x2b2: 0xc1, 0x2b3: 0xc2, 0x2b4: 0xc3, 0x2b5: 0xbd, 0x2b6: 0xbe, 0x2b7: 0xbf, + 0x2b8: 0xc0, 0x2b9: 0xc1, 0x2ba: 0xc2, 0x2bb: 0xc3, 0x2bc: 0xbd, 0x2bd: 0xbe, 0x2be: 0xbf, 0x2bf: 0xc0, + // Block 0xb, offset 0x2c0 + 0x2c0: 0xc1, 0x2c1: 0xc2, 0x2c2: 0xc3, 0x2c3: 0xbd, 0x2c4: 0xbe, 0x2c5: 0xbf, 0x2c6: 0xc0, 0x2c7: 0xc1, + 0x2c8: 0xc2, 0x2c9: 0xc3, 0x2ca: 0xbd, 0x2cb: 0xbe, 0x2cc: 0xbf, 0x2cd: 0xc0, 0x2ce: 0xc1, 0x2cf: 0xc2, + 0x2d0: 0xc3, 0x2d1: 0xbd, 0x2d2: 0xbe, 0x2d3: 0xbf, 0x2d4: 0xc0, 0x2d5: 0xc1, 0x2d6: 0xc2, 0x2d7: 0xc3, + 0x2d8: 0xbd, 0x2d9: 0xbe, 0x2da: 0xbf, 0x2db: 0xc0, 0x2dc: 0xc1, 0x2dd: 0xc2, 0x2de: 0xc4, + // Block 0xc, offset 0x300 + 0x324: 0x30, 0x325: 0x31, 0x326: 0x32, 0x327: 0x33, + 0x328: 0x34, 0x329: 0x35, 0x32a: 0x36, 0x32b: 0x37, 0x32c: 0x38, 0x32d: 0x39, 0x32e: 0x3a, 0x32f: 0x3b, + 0x330: 0x3c, 0x331: 0x3d, 0x332: 0x3e, 0x333: 0x3f, 0x334: 0x40, 0x335: 0x41, 0x336: 0x42, 0x337: 0x43, + 0x338: 0x44, 0x339: 0x45, 0x33a: 0x46, 0x33b: 0x47, 0x33c: 0xc5, 0x33d: 0x48, 0x33e: 0x49, 0x33f: 0x4a, + // Block 0xd, offset 0x340 + 0x347: 0xc6, + 0x34b: 0xc7, 0x34d: 0xc8, + 0x368: 0xc9, 0x36b: 0xca, + // Block 0xe, offset 0x380 + 0x381: 0xcb, 0x382: 0xcc, 0x384: 0xcd, 0x385: 0xb7, 0x387: 0xce, + 0x388: 0xcf, 0x38b: 0xd0, 0x38c: 0x6c, 0x38d: 0xd1, + 0x391: 0xd2, 0x392: 0xd3, 0x393: 0xd4, 0x396: 0xd5, 0x397: 0xd6, + 0x398: 0xd7, 0x39a: 0xd8, 0x39c: 0xd9, + 0x3a8: 0xda, 0x3a9: 0xdb, 0x3aa: 0xdc, + 0x3b0: 0xd7, 0x3b5: 0xdd, + // Block 0xf, offset 0x3c0 + 0x3eb: 0xde, 0x3ec: 0xdf, + // Block 0x10, offset 0x400 + 0x432: 0xe0, + // Block 0x11, offset 0x440 + 0x445: 0xe1, 0x446: 0xe2, 0x447: 0xe3, + 0x449: 0xe4, + 0x450: 0xe5, 0x451: 0xe6, 0x452: 0xe7, 0x453: 0xe8, 0x454: 0xe9, 0x455: 0xea, 0x456: 0xeb, 0x457: 0xec, + 0x458: 0xed, 0x459: 0xee, 0x45a: 0x4b, 0x45b: 0xef, 0x45c: 0xf0, 0x45d: 0xf1, 0x45e: 0xf2, 0x45f: 0x4c, + // Block 0x12, offset 0x480 + 0x480: 0xf3, + 0x4a3: 0xf4, 0x4a5: 0xf5, + 0x4b8: 0x4d, 0x4b9: 0x4e, 0x4ba: 0x4f, + // Block 0x13, offset 0x4c0 + 0x4c4: 0x50, 0x4c5: 0xf6, 0x4c6: 0xf7, + 0x4c8: 0x51, 0x4c9: 0xf8, + // Block 0x14, offset 0x500 + 0x520: 0x52, 0x521: 0x53, 0x522: 0x54, 0x523: 0x55, 0x524: 0x56, 0x525: 0x57, 0x526: 0x58, 0x527: 0x59, + 0x528: 0x5a, + // Block 0x15, offset 0x540 + 0x550: 0x0b, 0x551: 0x0c, 0x556: 0x0d, + 0x55b: 0x0e, 0x55d: 0x0f, 0x55e: 0x10, 0x55f: 0x11, + 0x56f: 0x12, +} + +// nfkcSparseOffset: 158 entries, 316 bytes +var nfkcSparseOffset = []uint16{0x0, 0xe, 0x12, 0x1b, 0x25, 0x35, 0x37, 0x3c, 0x47, 0x56, 0x63, 0x6b, 0x6f, 0x74, 0x76, 0x87, 0x8f, 0x96, 0x99, 0xa0, 0xa4, 0xa8, 0xaa, 0xac, 0xb5, 0xb9, 0xc0, 0xc5, 0xc8, 0xd2, 0xd5, 0xdc, 0xe4, 0xe8, 0xea, 0xed, 0xf1, 0xf7, 0x108, 0x114, 0x116, 0x11c, 0x11e, 0x120, 0x122, 0x124, 0x126, 0x128, 0x12a, 0x12d, 0x130, 0x132, 0x135, 0x138, 0x13c, 0x141, 0x14a, 0x14c, 0x14f, 0x151, 0x15c, 0x167, 0x175, 0x183, 0x193, 0x1a1, 0x1a8, 0x1ae, 0x1bd, 0x1c1, 0x1c3, 0x1c7, 0x1c9, 0x1cc, 0x1ce, 0x1d1, 0x1d3, 0x1d6, 0x1d8, 0x1da, 0x1dc, 0x1e8, 0x1f2, 0x1fc, 0x1ff, 0x203, 0x205, 0x207, 0x209, 0x20b, 0x20e, 0x210, 0x212, 0x214, 0x216, 0x21c, 0x21f, 0x223, 0x225, 0x22c, 0x232, 0x238, 0x240, 0x246, 0x24c, 0x252, 0x256, 0x258, 0x25a, 0x25c, 0x25e, 0x264, 0x267, 0x26a, 0x272, 0x279, 0x27c, 0x27f, 0x281, 0x289, 0x28c, 0x293, 0x296, 0x29c, 0x29e, 0x2a0, 0x2a3, 0x2a5, 0x2a7, 0x2a9, 0x2ab, 0x2ae, 0x2b0, 0x2b2, 0x2b4, 0x2c1, 0x2cb, 0x2cd, 0x2cf, 0x2d3, 0x2d8, 0x2e4, 0x2e9, 0x2f2, 0x2f8, 0x2fd, 0x301, 0x306, 0x30a, 0x31a, 0x328, 0x336, 0x344, 0x34a, 0x34c, 0x34f, 0x359, 0x35b} + +// nfkcSparseValues: 869 entries, 3476 bytes +var nfkcSparseValues = [869]valueRange{ + // Block 0x0, offset 0x0 + {value: 0x0002, lo: 0x0d}, + {value: 0x0001, lo: 0xa0, hi: 0xa0}, + {value: 0x4278, lo: 0xa8, hi: 0xa8}, + {value: 0x0083, lo: 0xaa, hi: 0xaa}, + {value: 0x4264, lo: 0xaf, hi: 0xaf}, + {value: 0x0025, lo: 0xb2, hi: 0xb3}, + {value: 0x425a, lo: 0xb4, hi: 0xb4}, + {value: 0x01dc, lo: 0xb5, hi: 0xb5}, + {value: 0x4291, lo: 0xb8, hi: 0xb8}, + {value: 0x0023, lo: 0xb9, hi: 0xb9}, + {value: 0x009f, lo: 0xba, hi: 0xba}, + {value: 0x221c, lo: 0xbc, hi: 0xbc}, + {value: 0x2210, lo: 0xbd, hi: 0xbd}, + {value: 0x22b2, lo: 0xbe, hi: 0xbe}, + // Block 0x1, offset 0xe + {value: 0x0091, lo: 0x03}, + {value: 0x46e2, lo: 0xa0, hi: 0xa1}, + {value: 0x4714, lo: 0xaf, hi: 0xb0}, + {value: 0xa000, lo: 0xb7, hi: 0xb7}, + // Block 0x2, offset 0x12 + {value: 0x0003, lo: 0x08}, + {value: 0xa000, lo: 0x92, hi: 0x92}, + {value: 0x0091, lo: 0xb0, hi: 0xb0}, + {value: 0x0119, lo: 0xb1, hi: 0xb1}, + {value: 0x0095, lo: 0xb2, hi: 0xb2}, + {value: 0x00a5, lo: 0xb3, hi: 0xb3}, + {value: 0x0143, lo: 0xb4, hi: 0xb6}, + {value: 0x00af, lo: 0xb7, hi: 0xb7}, + {value: 0x00b3, lo: 0xb8, hi: 0xb8}, + // Block 0x3, offset 0x1b + {value: 0x000a, lo: 0x09}, + {value: 0x426e, lo: 0x98, hi: 0x98}, + {value: 0x4273, lo: 0x99, hi: 0x9a}, + {value: 0x4296, lo: 0x9b, hi: 0x9b}, + {value: 0x425f, lo: 0x9c, hi: 0x9c}, + {value: 0x4282, lo: 0x9d, hi: 0x9d}, + {value: 0x0113, lo: 0xa0, hi: 0xa0}, + {value: 0x0099, lo: 0xa1, hi: 0xa1}, + {value: 0x00a7, lo: 0xa2, hi: 0xa3}, + {value: 0x0167, lo: 0xa4, hi: 0xa4}, + // Block 0x4, offset 0x25 + {value: 0x0000, lo: 0x0f}, + {value: 0xa000, lo: 0x83, hi: 0x83}, + {value: 0xa000, lo: 0x87, hi: 0x87}, + {value: 0xa000, lo: 0x8b, hi: 0x8b}, + {value: 0xa000, lo: 0x8d, hi: 0x8d}, + {value: 0x37a5, lo: 0x90, hi: 0x90}, + {value: 0x37b1, lo: 0x91, hi: 0x91}, + {value: 0x379f, lo: 0x93, hi: 0x93}, + {value: 0xa000, lo: 0x96, hi: 0x96}, + {value: 0x3817, lo: 0x97, hi: 0x97}, + {value: 0x37e1, lo: 0x9c, hi: 0x9c}, + {value: 0x37c9, lo: 0x9d, hi: 0x9d}, + {value: 0x37f3, lo: 0x9e, hi: 0x9e}, + {value: 0xa000, lo: 0xb4, hi: 0xb5}, + {value: 0x381d, lo: 0xb6, hi: 0xb6}, + {value: 0x3823, lo: 0xb7, hi: 0xb7}, + // Block 0x5, offset 0x35 + {value: 0x0000, lo: 0x01}, + {value: 0x8132, lo: 0x83, hi: 0x87}, + // Block 0x6, offset 0x37 + {value: 0x0001, lo: 0x04}, + {value: 0x8113, lo: 0x81, hi: 0x82}, + {value: 0x8132, lo: 0x84, hi: 0x84}, + {value: 0x812d, lo: 0x85, hi: 0x85}, + {value: 0x810d, lo: 0x87, hi: 0x87}, + // Block 0x7, offset 0x3c + {value: 0x0000, lo: 0x0a}, + {value: 0x8132, lo: 0x90, hi: 0x97}, + {value: 0x8119, lo: 0x98, hi: 0x98}, + {value: 0x811a, lo: 0x99, hi: 0x99}, + {value: 0x811b, lo: 0x9a, hi: 0x9a}, + {value: 0x3841, lo: 0xa2, hi: 0xa2}, + {value: 0x3847, lo: 0xa3, hi: 0xa3}, + {value: 0x3853, lo: 0xa4, hi: 0xa4}, + {value: 0x384d, lo: 0xa5, hi: 0xa5}, + {value: 0x3859, lo: 0xa6, hi: 0xa6}, + {value: 0xa000, lo: 0xa7, hi: 0xa7}, + // Block 0x8, offset 0x47 + {value: 0x0000, lo: 0x0e}, + {value: 0x386b, lo: 0x80, hi: 0x80}, + {value: 0xa000, lo: 0x81, hi: 0x81}, + {value: 0x385f, lo: 0x82, hi: 0x82}, + {value: 0xa000, lo: 0x92, hi: 0x92}, + {value: 0x3865, lo: 0x93, hi: 0x93}, + {value: 0xa000, lo: 0x95, hi: 0x95}, + {value: 0x8132, lo: 0x96, hi: 0x9c}, + {value: 0x8132, lo: 0x9f, hi: 0xa2}, + {value: 0x812d, lo: 0xa3, hi: 0xa3}, + {value: 0x8132, lo: 0xa4, hi: 0xa4}, + {value: 0x8132, lo: 0xa7, hi: 0xa8}, + {value: 0x812d, lo: 0xaa, hi: 0xaa}, + {value: 0x8132, lo: 0xab, hi: 0xac}, + {value: 0x812d, lo: 0xad, hi: 0xad}, + // Block 0x9, offset 0x56 + {value: 0x0000, lo: 0x0c}, + {value: 0x811f, lo: 0x91, hi: 0x91}, + {value: 0x8132, lo: 0xb0, hi: 0xb0}, + {value: 0x812d, lo: 0xb1, hi: 0xb1}, + {value: 0x8132, lo: 0xb2, hi: 0xb3}, + {value: 0x812d, lo: 0xb4, hi: 0xb4}, + {value: 0x8132, lo: 0xb5, hi: 0xb6}, + {value: 0x812d, lo: 0xb7, hi: 0xb9}, + {value: 0x8132, lo: 0xba, hi: 0xba}, + {value: 0x812d, lo: 0xbb, hi: 0xbc}, + {value: 0x8132, lo: 0xbd, hi: 0xbd}, + {value: 0x812d, lo: 0xbe, hi: 0xbe}, + {value: 0x8132, lo: 0xbf, hi: 0xbf}, + // Block 0xa, offset 0x63 + {value: 0x0005, lo: 0x07}, + {value: 0x8132, lo: 0x80, hi: 0x80}, + {value: 0x8132, lo: 0x81, hi: 0x81}, + {value: 0x812d, lo: 0x82, hi: 0x83}, + {value: 0x812d, lo: 0x84, hi: 0x85}, + {value: 0x812d, lo: 0x86, hi: 0x87}, + {value: 0x812d, lo: 0x88, hi: 0x89}, + {value: 0x8132, lo: 0x8a, hi: 0x8a}, + // Block 0xb, offset 0x6b + {value: 0x0000, lo: 0x03}, + {value: 0x8132, lo: 0xab, hi: 0xb1}, + {value: 0x812d, lo: 0xb2, hi: 0xb2}, + {value: 0x8132, lo: 0xb3, hi: 0xb3}, + // Block 0xc, offset 0x6f + {value: 0x0000, lo: 0x04}, + {value: 0x8132, lo: 0x96, hi: 0x99}, + {value: 0x8132, lo: 0x9b, hi: 0xa3}, + {value: 0x8132, lo: 0xa5, hi: 0xa7}, + {value: 0x8132, lo: 0xa9, hi: 0xad}, + // Block 0xd, offset 0x74 + {value: 0x0000, lo: 0x01}, + {value: 0x812d, lo: 0x99, hi: 0x9b}, + // Block 0xe, offset 0x76 + {value: 0x0000, lo: 0x10}, + {value: 0x8132, lo: 0x94, hi: 0xa1}, + {value: 0x812d, lo: 0xa3, hi: 0xa3}, + {value: 0x8132, lo: 0xa4, hi: 0xa5}, + {value: 0x812d, lo: 0xa6, hi: 0xa6}, + {value: 0x8132, lo: 0xa7, hi: 0xa8}, + {value: 0x812d, lo: 0xa9, hi: 0xa9}, + {value: 0x8132, lo: 0xaa, hi: 0xac}, + {value: 0x812d, lo: 0xad, hi: 0xaf}, + {value: 0x8116, lo: 0xb0, hi: 0xb0}, + {value: 0x8117, lo: 0xb1, hi: 0xb1}, + {value: 0x8118, lo: 0xb2, hi: 0xb2}, + {value: 0x8132, lo: 0xb3, hi: 0xb5}, + {value: 0x812d, lo: 0xb6, hi: 0xb6}, + {value: 0x8132, lo: 0xb7, hi: 0xb8}, + {value: 0x812d, lo: 0xb9, hi: 0xba}, + {value: 0x8132, lo: 0xbb, hi: 0xbf}, + // Block 0xf, offset 0x87 + {value: 0x0000, lo: 0x07}, + {value: 0xa000, lo: 0xa8, hi: 0xa8}, + {value: 0x3ed8, lo: 0xa9, hi: 0xa9}, + {value: 0xa000, lo: 0xb0, hi: 0xb0}, + {value: 0x3ee0, lo: 0xb1, hi: 0xb1}, + {value: 0xa000, lo: 0xb3, hi: 0xb3}, + {value: 0x3ee8, lo: 0xb4, hi: 0xb4}, + {value: 0x9902, lo: 0xbc, hi: 0xbc}, + // Block 0x10, offset 0x8f + {value: 0x0008, lo: 0x06}, + {value: 0x8104, lo: 0x8d, hi: 0x8d}, + {value: 0x8132, lo: 0x91, hi: 0x91}, + {value: 0x812d, lo: 0x92, hi: 0x92}, + {value: 0x8132, lo: 0x93, hi: 0x93}, + {value: 0x8132, lo: 0x94, hi: 0x94}, + {value: 0x451c, lo: 0x98, hi: 0x9f}, + // Block 0x11, offset 0x96 + {value: 0x0000, lo: 0x02}, + {value: 0x8102, lo: 0xbc, hi: 0xbc}, + {value: 0x9900, lo: 0xbe, hi: 0xbe}, + // Block 0x12, offset 0x99 + {value: 0x0008, lo: 0x06}, + {value: 0xa000, lo: 0x87, hi: 0x87}, + {value: 0x2c9e, lo: 0x8b, hi: 0x8c}, + {value: 0x8104, lo: 0x8d, hi: 0x8d}, + {value: 0x9900, lo: 0x97, hi: 0x97}, + {value: 0x455c, lo: 0x9c, hi: 0x9d}, + {value: 0x456c, lo: 0x9f, hi: 0x9f}, + // Block 0x13, offset 0xa0 + {value: 0x0000, lo: 0x03}, + {value: 0x4594, lo: 0xb3, hi: 0xb3}, + {value: 0x459c, lo: 0xb6, hi: 0xb6}, + {value: 0x8102, lo: 0xbc, hi: 0xbc}, + // Block 0x14, offset 0xa4 + {value: 0x0008, lo: 0x03}, + {value: 0x8104, lo: 0x8d, hi: 0x8d}, + {value: 0x4574, lo: 0x99, hi: 0x9b}, + {value: 0x458c, lo: 0x9e, hi: 0x9e}, + // Block 0x15, offset 0xa8 + {value: 0x0000, lo: 0x01}, + {value: 0x8102, lo: 0xbc, hi: 0xbc}, + // Block 0x16, offset 0xaa + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0x8d, hi: 0x8d}, + // Block 0x17, offset 0xac + {value: 0x0000, lo: 0x08}, + {value: 0xa000, lo: 0x87, hi: 0x87}, + {value: 0x2cb6, lo: 0x88, hi: 0x88}, + {value: 0x2cae, lo: 0x8b, hi: 0x8b}, + {value: 0x2cbe, lo: 0x8c, hi: 0x8c}, + {value: 0x8104, lo: 0x8d, hi: 0x8d}, + {value: 0x9900, lo: 0x96, hi: 0x97}, + {value: 0x45a4, lo: 0x9c, hi: 0x9c}, + {value: 0x45ac, lo: 0x9d, hi: 0x9d}, + // Block 0x18, offset 0xb5 + {value: 0x0000, lo: 0x03}, + {value: 0xa000, lo: 0x92, hi: 0x92}, + {value: 0x2cc6, lo: 0x94, hi: 0x94}, + {value: 0x9900, lo: 0xbe, hi: 0xbe}, + // Block 0x19, offset 0xb9 + {value: 0x0000, lo: 0x06}, + {value: 0xa000, lo: 0x86, hi: 0x87}, + {value: 0x2cce, lo: 0x8a, hi: 0x8a}, + {value: 0x2cde, lo: 0x8b, hi: 0x8b}, + {value: 0x2cd6, lo: 0x8c, hi: 0x8c}, + {value: 0x8104, lo: 0x8d, hi: 0x8d}, + {value: 0x9900, lo: 0x97, hi: 0x97}, + // Block 0x1a, offset 0xc0 + {value: 0x1801, lo: 0x04}, + {value: 0xa000, lo: 0x86, hi: 0x86}, + {value: 0x3ef0, lo: 0x88, hi: 0x88}, + {value: 0x8104, lo: 0x8d, hi: 0x8d}, + {value: 0x8120, lo: 0x95, hi: 0x96}, + // Block 0x1b, offset 0xc5 + {value: 0x0000, lo: 0x02}, + {value: 0x8102, lo: 0xbc, hi: 0xbc}, + {value: 0xa000, lo: 0xbf, hi: 0xbf}, + // Block 0x1c, offset 0xc8 + {value: 0x0000, lo: 0x09}, + {value: 0x2ce6, lo: 0x80, hi: 0x80}, + {value: 0x9900, lo: 0x82, hi: 0x82}, + {value: 0xa000, lo: 0x86, hi: 0x86}, + {value: 0x2cee, lo: 0x87, hi: 0x87}, + {value: 0x2cf6, lo: 0x88, hi: 0x88}, + {value: 0x2f50, lo: 0x8a, hi: 0x8a}, + {value: 0x2dd8, lo: 0x8b, hi: 0x8b}, + {value: 0x8104, lo: 0x8d, hi: 0x8d}, + {value: 0x9900, lo: 0x95, hi: 0x96}, + // Block 0x1d, offset 0xd2 + {value: 0x0000, lo: 0x02}, + {value: 0x8104, lo: 0xbb, hi: 0xbc}, + {value: 0x9900, lo: 0xbe, hi: 0xbe}, + // Block 0x1e, offset 0xd5 + {value: 0x0000, lo: 0x06}, + {value: 0xa000, lo: 0x86, hi: 0x87}, + {value: 0x2cfe, lo: 0x8a, hi: 0x8a}, + {value: 0x2d0e, lo: 0x8b, hi: 0x8b}, + {value: 0x2d06, lo: 0x8c, hi: 0x8c}, + {value: 0x8104, lo: 0x8d, hi: 0x8d}, + {value: 0x9900, lo: 0x97, hi: 0x97}, + // Block 0x1f, offset 0xdc + {value: 0x6bea, lo: 0x07}, + {value: 0x9904, lo: 0x8a, hi: 0x8a}, + {value: 0x9900, lo: 0x8f, hi: 0x8f}, + {value: 0xa000, lo: 0x99, hi: 0x99}, + {value: 0x3ef8, lo: 0x9a, hi: 0x9a}, + {value: 0x2f58, lo: 0x9c, hi: 0x9c}, + {value: 0x2de3, lo: 0x9d, hi: 0x9d}, + {value: 0x2d16, lo: 0x9e, hi: 0x9f}, + // Block 0x20, offset 0xe4 + {value: 0x0000, lo: 0x03}, + {value: 0x2621, lo: 0xb3, hi: 0xb3}, + {value: 0x8122, lo: 0xb8, hi: 0xb9}, + {value: 0x8104, lo: 0xba, hi: 0xba}, + // Block 0x21, offset 0xe8 + {value: 0x0000, lo: 0x01}, + {value: 0x8123, lo: 0x88, hi: 0x8b}, + // Block 0x22, offset 0xea + {value: 0x0000, lo: 0x02}, + {value: 0x2636, lo: 0xb3, hi: 0xb3}, + {value: 0x8124, lo: 0xb8, hi: 0xb9}, + // Block 0x23, offset 0xed + {value: 0x0000, lo: 0x03}, + {value: 0x8125, lo: 0x88, hi: 0x8b}, + {value: 0x2628, lo: 0x9c, hi: 0x9c}, + {value: 0x262f, lo: 0x9d, hi: 0x9d}, + // Block 0x24, offset 0xf1 + {value: 0x0000, lo: 0x05}, + {value: 0x030b, lo: 0x8c, hi: 0x8c}, + {value: 0x812d, lo: 0x98, hi: 0x99}, + {value: 0x812d, lo: 0xb5, hi: 0xb5}, + {value: 0x812d, lo: 0xb7, hi: 0xb7}, + {value: 0x812b, lo: 0xb9, hi: 0xb9}, + // Block 0x25, offset 0xf7 + {value: 0x0000, lo: 0x10}, + {value: 0x2644, lo: 0x83, hi: 0x83}, + {value: 0x264b, lo: 0x8d, hi: 0x8d}, + {value: 0x2652, lo: 0x92, hi: 0x92}, + {value: 0x2659, lo: 0x97, hi: 0x97}, + {value: 0x2660, lo: 0x9c, hi: 0x9c}, + {value: 0x263d, lo: 0xa9, hi: 0xa9}, + {value: 0x8126, lo: 0xb1, hi: 0xb1}, + {value: 0x8127, lo: 0xb2, hi: 0xb2}, + {value: 0x4a84, lo: 0xb3, hi: 0xb3}, + {value: 0x8128, lo: 0xb4, hi: 0xb4}, + {value: 0x4a8d, lo: 0xb5, hi: 0xb5}, + {value: 0x45b4, lo: 0xb6, hi: 0xb6}, + {value: 0x45f4, lo: 0xb7, hi: 0xb7}, + {value: 0x45bc, lo: 0xb8, hi: 0xb8}, + {value: 0x45ff, lo: 0xb9, hi: 0xb9}, + {value: 0x8127, lo: 0xba, hi: 0xbd}, + // Block 0x26, offset 0x108 + {value: 0x0000, lo: 0x0b}, + {value: 0x8127, lo: 0x80, hi: 0x80}, + {value: 0x4a96, lo: 0x81, hi: 0x81}, + {value: 0x8132, lo: 0x82, hi: 0x83}, + {value: 0x8104, lo: 0x84, hi: 0x84}, + {value: 0x8132, lo: 0x86, hi: 0x87}, + {value: 0x266e, lo: 0x93, hi: 0x93}, + {value: 0x2675, lo: 0x9d, hi: 0x9d}, + {value: 0x267c, lo: 0xa2, hi: 0xa2}, + {value: 0x2683, lo: 0xa7, hi: 0xa7}, + {value: 0x268a, lo: 0xac, hi: 0xac}, + {value: 0x2667, lo: 0xb9, hi: 0xb9}, + // Block 0x27, offset 0x114 + {value: 0x0000, lo: 0x01}, + {value: 0x812d, lo: 0x86, hi: 0x86}, + // Block 0x28, offset 0x116 + {value: 0x0000, lo: 0x05}, + {value: 0xa000, lo: 0xa5, hi: 0xa5}, + {value: 0x2d1e, lo: 0xa6, hi: 0xa6}, + {value: 0x9900, lo: 0xae, hi: 0xae}, + {value: 0x8102, lo: 0xb7, hi: 0xb7}, + {value: 0x8104, lo: 0xb9, hi: 0xba}, + // Block 0x29, offset 0x11c + {value: 0x0000, lo: 0x01}, + {value: 0x812d, lo: 0x8d, hi: 0x8d}, + // Block 0x2a, offset 0x11e + {value: 0x0000, lo: 0x01}, + {value: 0x030f, lo: 0xbc, hi: 0xbc}, + // Block 0x2b, offset 0x120 + {value: 0x0000, lo: 0x01}, + {value: 0xa000, lo: 0x80, hi: 0x92}, + // Block 0x2c, offset 0x122 + {value: 0x0000, lo: 0x01}, + {value: 0xb900, lo: 0xa1, hi: 0xb5}, + // Block 0x2d, offset 0x124 + {value: 0x0000, lo: 0x01}, + {value: 0x9900, lo: 0xa8, hi: 0xbf}, + // Block 0x2e, offset 0x126 + {value: 0x0000, lo: 0x01}, + {value: 0x9900, lo: 0x80, hi: 0x82}, + // Block 0x2f, offset 0x128 + {value: 0x0000, lo: 0x01}, + {value: 0x8132, lo: 0x9d, hi: 0x9f}, + // Block 0x30, offset 0x12a + {value: 0x0000, lo: 0x02}, + {value: 0x8104, lo: 0x94, hi: 0x94}, + {value: 0x8104, lo: 0xb4, hi: 0xb4}, + // Block 0x31, offset 0x12d + {value: 0x0000, lo: 0x02}, + {value: 0x8104, lo: 0x92, hi: 0x92}, + {value: 0x8132, lo: 0x9d, hi: 0x9d}, + // Block 0x32, offset 0x130 + {value: 0x0000, lo: 0x01}, + {value: 0x8131, lo: 0xa9, hi: 0xa9}, + // Block 0x33, offset 0x132 + {value: 0x0004, lo: 0x02}, + {value: 0x812e, lo: 0xb9, hi: 0xba}, + {value: 0x812d, lo: 0xbb, hi: 0xbb}, + // Block 0x34, offset 0x135 + {value: 0x0000, lo: 0x02}, + {value: 0x8132, lo: 0x97, hi: 0x97}, + {value: 0x812d, lo: 0x98, hi: 0x98}, + // Block 0x35, offset 0x138 + {value: 0x0000, lo: 0x03}, + {value: 0x8104, lo: 0xa0, hi: 0xa0}, + {value: 0x8132, lo: 0xb5, hi: 0xbc}, + {value: 0x812d, lo: 0xbf, hi: 0xbf}, + // Block 0x36, offset 0x13c + {value: 0x0000, lo: 0x04}, + {value: 0x8132, lo: 0xb0, hi: 0xb4}, + {value: 0x812d, lo: 0xb5, hi: 0xba}, + {value: 0x8132, lo: 0xbb, hi: 0xbc}, + {value: 0x812d, lo: 0xbd, hi: 0xbd}, + // Block 0x37, offset 0x141 + {value: 0x0000, lo: 0x08}, + {value: 0x2d66, lo: 0x80, hi: 0x80}, + {value: 0x2d6e, lo: 0x81, hi: 0x81}, + {value: 0xa000, lo: 0x82, hi: 0x82}, + {value: 0x2d76, lo: 0x83, hi: 0x83}, + {value: 0x8104, lo: 0x84, hi: 0x84}, + {value: 0x8132, lo: 0xab, hi: 0xab}, + {value: 0x812d, lo: 0xac, hi: 0xac}, + {value: 0x8132, lo: 0xad, hi: 0xb3}, + // Block 0x38, offset 0x14a + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0xaa, hi: 0xab}, + // Block 0x39, offset 0x14c + {value: 0x0000, lo: 0x02}, + {value: 0x8102, lo: 0xa6, hi: 0xa6}, + {value: 0x8104, lo: 0xb2, hi: 0xb3}, + // Block 0x3a, offset 0x14f + {value: 0x0000, lo: 0x01}, + {value: 0x8102, lo: 0xb7, hi: 0xb7}, + // Block 0x3b, offset 0x151 + {value: 0x0000, lo: 0x0a}, + {value: 0x8132, lo: 0x90, hi: 0x92}, + {value: 0x8101, lo: 0x94, hi: 0x94}, + {value: 0x812d, lo: 0x95, hi: 0x99}, + {value: 0x8132, lo: 0x9a, hi: 0x9b}, + {value: 0x812d, lo: 0x9c, hi: 0x9f}, + {value: 0x8132, lo: 0xa0, hi: 0xa0}, + {value: 0x8101, lo: 0xa2, hi: 0xa8}, + {value: 0x812d, lo: 0xad, hi: 0xad}, + {value: 0x8132, lo: 0xb4, hi: 0xb4}, + {value: 0x8132, lo: 0xb8, hi: 0xb9}, + // Block 0x3c, offset 0x15c + {value: 0x0002, lo: 0x0a}, + {value: 0x0043, lo: 0xac, hi: 0xac}, + {value: 0x00d1, lo: 0xad, hi: 0xad}, + {value: 0x0045, lo: 0xae, hi: 0xae}, + {value: 0x0049, lo: 0xb0, hi: 0xb1}, + {value: 0x00e6, lo: 0xb2, hi: 0xb2}, + {value: 0x004f, lo: 0xb3, hi: 0xba}, + {value: 0x005f, lo: 0xbc, hi: 0xbc}, + {value: 0x00ef, lo: 0xbd, hi: 0xbd}, + {value: 0x0061, lo: 0xbe, hi: 0xbe}, + {value: 0x0065, lo: 0xbf, hi: 0xbf}, + // Block 0x3d, offset 0x167 + {value: 0x0000, lo: 0x0d}, + {value: 0x0001, lo: 0x80, hi: 0x8a}, + {value: 0x043b, lo: 0x91, hi: 0x91}, + {value: 0x429b, lo: 0x97, hi: 0x97}, + {value: 0x001d, lo: 0xa4, hi: 0xa4}, + {value: 0x1873, lo: 0xa5, hi: 0xa5}, + {value: 0x1b5c, lo: 0xa6, hi: 0xa6}, + {value: 0x0001, lo: 0xaf, hi: 0xaf}, + {value: 0x2691, lo: 0xb3, hi: 0xb3}, + {value: 0x27fe, lo: 0xb4, hi: 0xb4}, + {value: 0x2698, lo: 0xb6, hi: 0xb6}, + {value: 0x2808, lo: 0xb7, hi: 0xb7}, + {value: 0x186d, lo: 0xbc, hi: 0xbc}, + {value: 0x4269, lo: 0xbe, hi: 0xbe}, + // Block 0x3e, offset 0x175 + {value: 0x0002, lo: 0x0d}, + {value: 0x1933, lo: 0x87, hi: 0x87}, + {value: 0x1930, lo: 0x88, hi: 0x88}, + {value: 0x1870, lo: 0x89, hi: 0x89}, + {value: 0x298e, lo: 0x97, hi: 0x97}, + {value: 0x0001, lo: 0x9f, hi: 0x9f}, + {value: 0x0021, lo: 0xb0, hi: 0xb0}, + {value: 0x0093, lo: 0xb1, hi: 0xb1}, + {value: 0x0029, lo: 0xb4, hi: 0xb9}, + {value: 0x0017, lo: 0xba, hi: 0xba}, + {value: 0x0467, lo: 0xbb, hi: 0xbb}, + {value: 0x003b, lo: 0xbc, hi: 0xbc}, + {value: 0x0011, lo: 0xbd, hi: 0xbe}, + {value: 0x009d, lo: 0xbf, hi: 0xbf}, + // Block 0x3f, offset 0x183 + {value: 0x0002, lo: 0x0f}, + {value: 0x0021, lo: 0x80, hi: 0x89}, + {value: 0x0017, lo: 0x8a, hi: 0x8a}, + {value: 0x0467, lo: 0x8b, hi: 0x8b}, + {value: 0x003b, lo: 0x8c, hi: 0x8c}, + {value: 0x0011, lo: 0x8d, hi: 0x8e}, + {value: 0x0083, lo: 0x90, hi: 0x90}, + {value: 0x008b, lo: 0x91, hi: 0x91}, + {value: 0x009f, lo: 0x92, hi: 0x92}, + {value: 0x00b1, lo: 0x93, hi: 0x93}, + {value: 0x0104, lo: 0x94, hi: 0x94}, + {value: 0x0091, lo: 0x95, hi: 0x95}, + {value: 0x0097, lo: 0x96, hi: 0x99}, + {value: 0x00a1, lo: 0x9a, hi: 0x9a}, + {value: 0x00a7, lo: 0x9b, hi: 0x9c}, + {value: 0x1999, lo: 0xa8, hi: 0xa8}, + // Block 0x40, offset 0x193 + {value: 0x0000, lo: 0x0d}, + {value: 0x8132, lo: 0x90, hi: 0x91}, + {value: 0x8101, lo: 0x92, hi: 0x93}, + {value: 0x8132, lo: 0x94, hi: 0x97}, + {value: 0x8101, lo: 0x98, hi: 0x9a}, + {value: 0x8132, lo: 0x9b, hi: 0x9c}, + {value: 0x8132, lo: 0xa1, hi: 0xa1}, + {value: 0x8101, lo: 0xa5, hi: 0xa6}, + {value: 0x8132, lo: 0xa7, hi: 0xa7}, + {value: 0x812d, lo: 0xa8, hi: 0xa8}, + {value: 0x8132, lo: 0xa9, hi: 0xa9}, + {value: 0x8101, lo: 0xaa, hi: 0xab}, + {value: 0x812d, lo: 0xac, hi: 0xaf}, + {value: 0x8132, lo: 0xb0, hi: 0xb0}, + // Block 0x41, offset 0x1a1 + {value: 0x0007, lo: 0x06}, + {value: 0x2180, lo: 0x89, hi: 0x89}, + {value: 0xa000, lo: 0x90, hi: 0x90}, + {value: 0xa000, lo: 0x92, hi: 0x92}, + {value: 0xa000, lo: 0x94, hi: 0x94}, + {value: 0x3bb9, lo: 0x9a, hi: 0x9b}, + {value: 0x3bc7, lo: 0xae, hi: 0xae}, + // Block 0x42, offset 0x1a8 + {value: 0x000e, lo: 0x05}, + {value: 0x3bce, lo: 0x8d, hi: 0x8e}, + {value: 0x3bd5, lo: 0x8f, hi: 0x8f}, + {value: 0xa000, lo: 0x90, hi: 0x90}, + {value: 0xa000, lo: 0x92, hi: 0x92}, + {value: 0xa000, lo: 0x94, hi: 0x94}, + // Block 0x43, offset 0x1ae + {value: 0x0173, lo: 0x0e}, + {value: 0xa000, lo: 0x83, hi: 0x83}, + {value: 0x3be3, lo: 0x84, hi: 0x84}, + {value: 0xa000, lo: 0x88, hi: 0x88}, + {value: 0x3bea, lo: 0x89, hi: 0x89}, + {value: 0xa000, lo: 0x8b, hi: 0x8b}, + {value: 0x3bf1, lo: 0x8c, hi: 0x8c}, + {value: 0xa000, lo: 0xa3, hi: 0xa3}, + {value: 0x3bf8, lo: 0xa4, hi: 0xa4}, + {value: 0xa000, lo: 0xa5, hi: 0xa5}, + {value: 0x3bff, lo: 0xa6, hi: 0xa6}, + {value: 0x269f, lo: 0xac, hi: 0xad}, + {value: 0x26a6, lo: 0xaf, hi: 0xaf}, + {value: 0x281c, lo: 0xb0, hi: 0xb0}, + {value: 0xa000, lo: 0xbc, hi: 0xbc}, + // Block 0x44, offset 0x1bd + {value: 0x0007, lo: 0x03}, + {value: 0x3c68, lo: 0xa0, hi: 0xa1}, + {value: 0x3c92, lo: 0xa2, hi: 0xa3}, + {value: 0x3cbc, lo: 0xaa, hi: 0xad}, + // Block 0x45, offset 0x1c1 + {value: 0x0004, lo: 0x01}, + {value: 0x048b, lo: 0xa9, hi: 0xaa}, + // Block 0x46, offset 0x1c3 + {value: 0x0002, lo: 0x03}, + {value: 0x0057, lo: 0x80, hi: 0x8f}, + {value: 0x0083, lo: 0x90, hi: 0xa9}, + {value: 0x0021, lo: 0xaa, hi: 0xaa}, + // Block 0x47, offset 0x1c7 + {value: 0x0000, lo: 0x01}, + {value: 0x299b, lo: 0x8c, hi: 0x8c}, + // Block 0x48, offset 0x1c9 + {value: 0x0263, lo: 0x02}, + {value: 0x1b8c, lo: 0xb4, hi: 0xb4}, + {value: 0x192d, lo: 0xb5, hi: 0xb6}, + // Block 0x49, offset 0x1cc + {value: 0x0000, lo: 0x01}, + {value: 0x44dd, lo: 0x9c, hi: 0x9c}, + // Block 0x4a, offset 0x1ce + {value: 0x0000, lo: 0x02}, + {value: 0x0095, lo: 0xbc, hi: 0xbc}, + {value: 0x006d, lo: 0xbd, hi: 0xbd}, + // Block 0x4b, offset 0x1d1 + {value: 0x0000, lo: 0x01}, + {value: 0x8132, lo: 0xaf, hi: 0xb1}, + // Block 0x4c, offset 0x1d3 + {value: 0x0000, lo: 0x02}, + {value: 0x047f, lo: 0xaf, hi: 0xaf}, + {value: 0x8104, lo: 0xbf, hi: 0xbf}, + // Block 0x4d, offset 0x1d6 + {value: 0x0000, lo: 0x01}, + {value: 0x8132, lo: 0xa0, hi: 0xbf}, + // Block 0x4e, offset 0x1d8 + {value: 0x0000, lo: 0x01}, + {value: 0x0dc3, lo: 0x9f, hi: 0x9f}, + // Block 0x4f, offset 0x1da + {value: 0x0000, lo: 0x01}, + {value: 0x162f, lo: 0xb3, hi: 0xb3}, + // Block 0x50, offset 0x1dc + {value: 0x0004, lo: 0x0b}, + {value: 0x1597, lo: 0x80, hi: 0x82}, + {value: 0x15af, lo: 0x83, hi: 0x83}, + {value: 0x15c7, lo: 0x84, hi: 0x85}, + {value: 0x15d7, lo: 0x86, hi: 0x89}, + {value: 0x15eb, lo: 0x8a, hi: 0x8c}, + {value: 0x15ff, lo: 0x8d, hi: 0x8d}, + {value: 0x1607, lo: 0x8e, hi: 0x8e}, + {value: 0x160f, lo: 0x8f, hi: 0x90}, + {value: 0x161b, lo: 0x91, hi: 0x93}, + {value: 0x162b, lo: 0x94, hi: 0x94}, + {value: 0x1633, lo: 0x95, hi: 0x95}, + // Block 0x51, offset 0x1e8 + {value: 0x0004, lo: 0x09}, + {value: 0x0001, lo: 0x80, hi: 0x80}, + {value: 0x812c, lo: 0xaa, hi: 0xaa}, + {value: 0x8131, lo: 0xab, hi: 0xab}, + {value: 0x8133, lo: 0xac, hi: 0xac}, + {value: 0x812e, lo: 0xad, hi: 0xad}, + {value: 0x812f, lo: 0xae, hi: 0xae}, + {value: 0x812f, lo: 0xaf, hi: 0xaf}, + {value: 0x04b3, lo: 0xb6, hi: 0xb6}, + {value: 0x0887, lo: 0xb8, hi: 0xba}, + // Block 0x52, offset 0x1f2 + {value: 0x0006, lo: 0x09}, + {value: 0x0313, lo: 0xb1, hi: 0xb1}, + {value: 0x0317, lo: 0xb2, hi: 0xb2}, + {value: 0x4a3b, lo: 0xb3, hi: 0xb3}, + {value: 0x031b, lo: 0xb4, hi: 0xb4}, + {value: 0x4a41, lo: 0xb5, hi: 0xb6}, + {value: 0x031f, lo: 0xb7, hi: 0xb7}, + {value: 0x0323, lo: 0xb8, hi: 0xb8}, + {value: 0x0327, lo: 0xb9, hi: 0xb9}, + {value: 0x4a4d, lo: 0xba, hi: 0xbf}, + // Block 0x53, offset 0x1fc + {value: 0x0000, lo: 0x02}, + {value: 0x8132, lo: 0xaf, hi: 0xaf}, + {value: 0x8132, lo: 0xb4, hi: 0xbd}, + // Block 0x54, offset 0x1ff + {value: 0x0000, lo: 0x03}, + {value: 0x020f, lo: 0x9c, hi: 0x9c}, + {value: 0x0212, lo: 0x9d, hi: 0x9d}, + {value: 0x8132, lo: 0x9e, hi: 0x9f}, + // Block 0x55, offset 0x203 + {value: 0x0000, lo: 0x01}, + {value: 0x8132, lo: 0xb0, hi: 0xb1}, + // Block 0x56, offset 0x205 + {value: 0x0000, lo: 0x01}, + {value: 0x163b, lo: 0xb0, hi: 0xb0}, + // Block 0x57, offset 0x207 + {value: 0x000c, lo: 0x01}, + {value: 0x00d7, lo: 0xb8, hi: 0xb9}, + // Block 0x58, offset 0x209 + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0x86, hi: 0x86}, + // Block 0x59, offset 0x20b + {value: 0x0000, lo: 0x02}, + {value: 0x8104, lo: 0x84, hi: 0x84}, + {value: 0x8132, lo: 0xa0, hi: 0xb1}, + // Block 0x5a, offset 0x20e + {value: 0x0000, lo: 0x01}, + {value: 0x812d, lo: 0xab, hi: 0xad}, + // Block 0x5b, offset 0x210 + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0x93, hi: 0x93}, + // Block 0x5c, offset 0x212 + {value: 0x0000, lo: 0x01}, + {value: 0x8102, lo: 0xb3, hi: 0xb3}, + // Block 0x5d, offset 0x214 + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0x80, hi: 0x80}, + // Block 0x5e, offset 0x216 + {value: 0x0000, lo: 0x05}, + {value: 0x8132, lo: 0xb0, hi: 0xb0}, + {value: 0x8132, lo: 0xb2, hi: 0xb3}, + {value: 0x812d, lo: 0xb4, hi: 0xb4}, + {value: 0x8132, lo: 0xb7, hi: 0xb8}, + {value: 0x8132, lo: 0xbe, hi: 0xbf}, + // Block 0x5f, offset 0x21c + {value: 0x0000, lo: 0x02}, + {value: 0x8132, lo: 0x81, hi: 0x81}, + {value: 0x8104, lo: 0xb6, hi: 0xb6}, + // Block 0x60, offset 0x21f + {value: 0x0008, lo: 0x03}, + {value: 0x1637, lo: 0x9c, hi: 0x9d}, + {value: 0x0125, lo: 0x9e, hi: 0x9e}, + {value: 0x1643, lo: 0x9f, hi: 0x9f}, + // Block 0x61, offset 0x223 + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0xad, hi: 0xad}, + // Block 0x62, offset 0x225 + {value: 0x0000, lo: 0x06}, + {value: 0xe500, lo: 0x80, hi: 0x80}, + {value: 0xc600, lo: 0x81, hi: 0x9b}, + {value: 0xe500, lo: 0x9c, hi: 0x9c}, + {value: 0xc600, lo: 0x9d, hi: 0xb7}, + {value: 0xe500, lo: 0xb8, hi: 0xb8}, + {value: 0xc600, lo: 0xb9, hi: 0xbf}, + // Block 0x63, offset 0x22c + {value: 0x0000, lo: 0x05}, + {value: 0xc600, lo: 0x80, hi: 0x93}, + {value: 0xe500, lo: 0x94, hi: 0x94}, + {value: 0xc600, lo: 0x95, hi: 0xaf}, + {value: 0xe500, lo: 0xb0, hi: 0xb0}, + {value: 0xc600, lo: 0xb1, hi: 0xbf}, + // Block 0x64, offset 0x232 + {value: 0x0000, lo: 0x05}, + {value: 0xc600, lo: 0x80, hi: 0x8b}, + {value: 0xe500, lo: 0x8c, hi: 0x8c}, + {value: 0xc600, lo: 0x8d, hi: 0xa7}, + {value: 0xe500, lo: 0xa8, hi: 0xa8}, + {value: 0xc600, lo: 0xa9, hi: 0xbf}, + // Block 0x65, offset 0x238 + {value: 0x0000, lo: 0x07}, + {value: 0xc600, lo: 0x80, hi: 0x83}, + {value: 0xe500, lo: 0x84, hi: 0x84}, + {value: 0xc600, lo: 0x85, hi: 0x9f}, + {value: 0xe500, lo: 0xa0, hi: 0xa0}, + {value: 0xc600, lo: 0xa1, hi: 0xbb}, + {value: 0xe500, lo: 0xbc, hi: 0xbc}, + {value: 0xc600, lo: 0xbd, hi: 0xbf}, + // Block 0x66, offset 0x240 + {value: 0x0000, lo: 0x05}, + {value: 0xc600, lo: 0x80, hi: 0x97}, + {value: 0xe500, lo: 0x98, hi: 0x98}, + {value: 0xc600, lo: 0x99, hi: 0xb3}, + {value: 0xe500, lo: 0xb4, hi: 0xb4}, + {value: 0xc600, lo: 0xb5, hi: 0xbf}, + // Block 0x67, offset 0x246 + {value: 0x0000, lo: 0x05}, + {value: 0xc600, lo: 0x80, hi: 0x8f}, + {value: 0xe500, lo: 0x90, hi: 0x90}, + {value: 0xc600, lo: 0x91, hi: 0xab}, + {value: 0xe500, lo: 0xac, hi: 0xac}, + {value: 0xc600, lo: 0xad, hi: 0xbf}, + // Block 0x68, offset 0x24c + {value: 0x0000, lo: 0x05}, + {value: 0xc600, lo: 0x80, hi: 0x87}, + {value: 0xe500, lo: 0x88, hi: 0x88}, + {value: 0xc600, lo: 0x89, hi: 0xa3}, + {value: 0xe500, lo: 0xa4, hi: 0xa4}, + {value: 0xc600, lo: 0xa5, hi: 0xbf}, + // Block 0x69, offset 0x252 + {value: 0x0000, lo: 0x03}, + {value: 0xc600, lo: 0x80, hi: 0x87}, + {value: 0xe500, lo: 0x88, hi: 0x88}, + {value: 0xc600, lo: 0x89, hi: 0xa3}, + // Block 0x6a, offset 0x256 + {value: 0x0002, lo: 0x01}, + {value: 0x0003, lo: 0x81, hi: 0xbf}, + // Block 0x6b, offset 0x258 + {value: 0x0000, lo: 0x01}, + {value: 0x812d, lo: 0xbd, hi: 0xbd}, + // Block 0x6c, offset 0x25a + {value: 0x0000, lo: 0x01}, + {value: 0x812d, lo: 0xa0, hi: 0xa0}, + // Block 0x6d, offset 0x25c + {value: 0x0000, lo: 0x01}, + {value: 0x8132, lo: 0xb6, hi: 0xba}, + // Block 0x6e, offset 0x25e + {value: 0x002c, lo: 0x05}, + {value: 0x812d, lo: 0x8d, hi: 0x8d}, + {value: 0x8132, lo: 0x8f, hi: 0x8f}, + {value: 0x8132, lo: 0xb8, hi: 0xb8}, + {value: 0x8101, lo: 0xb9, hi: 0xba}, + {value: 0x8104, lo: 0xbf, hi: 0xbf}, + // Block 0x6f, offset 0x264 + {value: 0x0000, lo: 0x02}, + {value: 0x8132, lo: 0xa5, hi: 0xa5}, + {value: 0x812d, lo: 0xa6, hi: 0xa6}, + // Block 0x70, offset 0x267 + {value: 0x0000, lo: 0x02}, + {value: 0x8104, lo: 0x86, hi: 0x86}, + {value: 0x8104, lo: 0xbf, hi: 0xbf}, + // Block 0x71, offset 0x26a + {value: 0x17fe, lo: 0x07}, + {value: 0xa000, lo: 0x99, hi: 0x99}, + {value: 0x4238, lo: 0x9a, hi: 0x9a}, + {value: 0xa000, lo: 0x9b, hi: 0x9b}, + {value: 0x4242, lo: 0x9c, hi: 0x9c}, + {value: 0xa000, lo: 0xa5, hi: 0xa5}, + {value: 0x424c, lo: 0xab, hi: 0xab}, + {value: 0x8104, lo: 0xb9, hi: 0xba}, + // Block 0x72, offset 0x272 + {value: 0x0000, lo: 0x06}, + {value: 0x8132, lo: 0x80, hi: 0x82}, + {value: 0x9900, lo: 0xa7, hi: 0xa7}, + {value: 0x2d7e, lo: 0xae, hi: 0xae}, + {value: 0x2d88, lo: 0xaf, hi: 0xaf}, + {value: 0xa000, lo: 0xb1, hi: 0xb2}, + {value: 0x8104, lo: 0xb3, hi: 0xb4}, + // Block 0x73, offset 0x279 + {value: 0x0000, lo: 0x02}, + {value: 0x8104, lo: 0x80, hi: 0x80}, + {value: 0x8102, lo: 0x8a, hi: 0x8a}, + // Block 0x74, offset 0x27c + {value: 0x0000, lo: 0x02}, + {value: 0x8104, lo: 0xb5, hi: 0xb5}, + {value: 0x8102, lo: 0xb6, hi: 0xb6}, + // Block 0x75, offset 0x27f + {value: 0x0002, lo: 0x01}, + {value: 0x8102, lo: 0xa9, hi: 0xaa}, + // Block 0x76, offset 0x281 + {value: 0x0000, lo: 0x07}, + {value: 0xa000, lo: 0x87, hi: 0x87}, + {value: 0x2d92, lo: 0x8b, hi: 0x8b}, + {value: 0x2d9c, lo: 0x8c, hi: 0x8c}, + {value: 0x8104, lo: 0x8d, hi: 0x8d}, + {value: 0x9900, lo: 0x97, hi: 0x97}, + {value: 0x8132, lo: 0xa6, hi: 0xac}, + {value: 0x8132, lo: 0xb0, hi: 0xb4}, + // Block 0x77, offset 0x289 + {value: 0x0000, lo: 0x02}, + {value: 0x8104, lo: 0x82, hi: 0x82}, + {value: 0x8102, lo: 0x86, hi: 0x86}, + // Block 0x78, offset 0x28c + {value: 0x6b5a, lo: 0x06}, + {value: 0x9900, lo: 0xb0, hi: 0xb0}, + {value: 0xa000, lo: 0xb9, hi: 0xb9}, + {value: 0x9900, lo: 0xba, hi: 0xba}, + {value: 0x2db0, lo: 0xbb, hi: 0xbb}, + {value: 0x2da6, lo: 0xbc, hi: 0xbd}, + {value: 0x2dba, lo: 0xbe, hi: 0xbe}, + // Block 0x79, offset 0x293 + {value: 0x0000, lo: 0x02}, + {value: 0x8104, lo: 0x82, hi: 0x82}, + {value: 0x8102, lo: 0x83, hi: 0x83}, + // Block 0x7a, offset 0x296 + {value: 0x0000, lo: 0x05}, + {value: 0x9900, lo: 0xaf, hi: 0xaf}, + {value: 0xa000, lo: 0xb8, hi: 0xb9}, + {value: 0x2dc4, lo: 0xba, hi: 0xba}, + {value: 0x2dce, lo: 0xbb, hi: 0xbb}, + {value: 0x8104, lo: 0xbf, hi: 0xbf}, + // Block 0x7b, offset 0x29c + {value: 0x0000, lo: 0x01}, + {value: 0x8102, lo: 0x80, hi: 0x80}, + // Block 0x7c, offset 0x29e + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0xbf, hi: 0xbf}, + // Block 0x7d, offset 0x2a0 + {value: 0x0000, lo: 0x02}, + {value: 0x8104, lo: 0xb6, hi: 0xb6}, + {value: 0x8102, lo: 0xb7, hi: 0xb7}, + // Block 0x7e, offset 0x2a3 + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0xab, hi: 0xab}, + // Block 0x7f, offset 0x2a5 + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0xb4, hi: 0xb4}, + // Block 0x80, offset 0x2a7 + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0x87, hi: 0x87}, + // Block 0x81, offset 0x2a9 + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0x99, hi: 0x99}, + // Block 0x82, offset 0x2ab + {value: 0x0000, lo: 0x02}, + {value: 0x8102, lo: 0x82, hi: 0x82}, + {value: 0x8104, lo: 0x84, hi: 0x85}, + // Block 0x83, offset 0x2ae + {value: 0x0000, lo: 0x01}, + {value: 0x8101, lo: 0xb0, hi: 0xb4}, + // Block 0x84, offset 0x2b0 + {value: 0x0000, lo: 0x01}, + {value: 0x8132, lo: 0xb0, hi: 0xb6}, + // Block 0x85, offset 0x2b2 + {value: 0x0000, lo: 0x01}, + {value: 0x8101, lo: 0x9e, hi: 0x9e}, + // Block 0x86, offset 0x2b4 + {value: 0x0000, lo: 0x0c}, + {value: 0x45cc, lo: 0x9e, hi: 0x9e}, + {value: 0x45d6, lo: 0x9f, hi: 0x9f}, + {value: 0x460a, lo: 0xa0, hi: 0xa0}, + {value: 0x4618, lo: 0xa1, hi: 0xa1}, + {value: 0x4626, lo: 0xa2, hi: 0xa2}, + {value: 0x4634, lo: 0xa3, hi: 0xa3}, + {value: 0x4642, lo: 0xa4, hi: 0xa4}, + {value: 0x812b, lo: 0xa5, hi: 0xa6}, + {value: 0x8101, lo: 0xa7, hi: 0xa9}, + {value: 0x8130, lo: 0xad, hi: 0xad}, + {value: 0x812b, lo: 0xae, hi: 0xb2}, + {value: 0x812d, lo: 0xbb, hi: 0xbf}, + // Block 0x87, offset 0x2c1 + {value: 0x0000, lo: 0x09}, + {value: 0x812d, lo: 0x80, hi: 0x82}, + {value: 0x8132, lo: 0x85, hi: 0x89}, + {value: 0x812d, lo: 0x8a, hi: 0x8b}, + {value: 0x8132, lo: 0xaa, hi: 0xad}, + {value: 0x45e0, lo: 0xbb, hi: 0xbb}, + {value: 0x45ea, lo: 0xbc, hi: 0xbc}, + {value: 0x4650, lo: 0xbd, hi: 0xbd}, + {value: 0x466c, lo: 0xbe, hi: 0xbe}, + {value: 0x465e, lo: 0xbf, hi: 0xbf}, + // Block 0x88, offset 0x2cb + {value: 0x0000, lo: 0x01}, + {value: 0x467a, lo: 0x80, hi: 0x80}, + // Block 0x89, offset 0x2cd + {value: 0x0000, lo: 0x01}, + {value: 0x8132, lo: 0x82, hi: 0x84}, + // Block 0x8a, offset 0x2cf + {value: 0x0002, lo: 0x03}, + {value: 0x0043, lo: 0x80, hi: 0x99}, + {value: 0x0083, lo: 0x9a, hi: 0xb3}, + {value: 0x0043, lo: 0xb4, hi: 0xbf}, + // Block 0x8b, offset 0x2d3 + {value: 0x0002, lo: 0x04}, + {value: 0x005b, lo: 0x80, hi: 0x8d}, + {value: 0x0083, lo: 0x8e, hi: 0x94}, + {value: 0x0093, lo: 0x96, hi: 0xa7}, + {value: 0x0043, lo: 0xa8, hi: 0xbf}, + // Block 0x8c, offset 0x2d8 + {value: 0x0002, lo: 0x0b}, + {value: 0x0073, lo: 0x80, hi: 0x81}, + {value: 0x0083, lo: 0x82, hi: 0x9b}, + {value: 0x0043, lo: 0x9c, hi: 0x9c}, + {value: 0x0047, lo: 0x9e, hi: 0x9f}, + {value: 0x004f, lo: 0xa2, hi: 0xa2}, + {value: 0x0055, lo: 0xa5, hi: 0xa6}, + {value: 0x005d, lo: 0xa9, hi: 0xac}, + {value: 0x0067, lo: 0xae, hi: 0xb5}, + {value: 0x0083, lo: 0xb6, hi: 0xb9}, + {value: 0x008d, lo: 0xbb, hi: 0xbb}, + {value: 0x0091, lo: 0xbd, hi: 0xbf}, + // Block 0x8d, offset 0x2e4 + {value: 0x0002, lo: 0x04}, + {value: 0x0097, lo: 0x80, hi: 0x83}, + {value: 0x00a1, lo: 0x85, hi: 0x8f}, + {value: 0x0043, lo: 0x90, hi: 0xa9}, + {value: 0x0083, lo: 0xaa, hi: 0xbf}, + // Block 0x8e, offset 0x2e9 + {value: 0x0002, lo: 0x08}, + {value: 0x00af, lo: 0x80, hi: 0x83}, + {value: 0x0043, lo: 0x84, hi: 0x85}, + {value: 0x0049, lo: 0x87, hi: 0x8a}, + {value: 0x0055, lo: 0x8d, hi: 0x94}, + {value: 0x0067, lo: 0x96, hi: 0x9c}, + {value: 0x0083, lo: 0x9e, hi: 0xb7}, + {value: 0x0043, lo: 0xb8, hi: 0xb9}, + {value: 0x0049, lo: 0xbb, hi: 0xbe}, + // Block 0x8f, offset 0x2f2 + {value: 0x0002, lo: 0x05}, + {value: 0x0053, lo: 0x80, hi: 0x84}, + {value: 0x005f, lo: 0x86, hi: 0x86}, + {value: 0x0067, lo: 0x8a, hi: 0x90}, + {value: 0x0083, lo: 0x92, hi: 0xab}, + {value: 0x0043, lo: 0xac, hi: 0xbf}, + // Block 0x90, offset 0x2f8 + {value: 0x0002, lo: 0x04}, + {value: 0x006b, lo: 0x80, hi: 0x85}, + {value: 0x0083, lo: 0x86, hi: 0x9f}, + {value: 0x0043, lo: 0xa0, hi: 0xb9}, + {value: 0x0083, lo: 0xba, hi: 0xbf}, + // Block 0x91, offset 0x2fd + {value: 0x0002, lo: 0x03}, + {value: 0x008f, lo: 0x80, hi: 0x93}, + {value: 0x0043, lo: 0x94, hi: 0xad}, + {value: 0x0083, lo: 0xae, hi: 0xbf}, + // Block 0x92, offset 0x301 + {value: 0x0002, lo: 0x04}, + {value: 0x00a7, lo: 0x80, hi: 0x87}, + {value: 0x0043, lo: 0x88, hi: 0xa1}, + {value: 0x0083, lo: 0xa2, hi: 0xbb}, + {value: 0x0043, lo: 0xbc, hi: 0xbf}, + // Block 0x93, offset 0x306 + {value: 0x0002, lo: 0x03}, + {value: 0x004b, lo: 0x80, hi: 0x95}, + {value: 0x0083, lo: 0x96, hi: 0xaf}, + {value: 0x0043, lo: 0xb0, hi: 0xbf}, + // Block 0x94, offset 0x30a + {value: 0x0003, lo: 0x0f}, + {value: 0x01b8, lo: 0x80, hi: 0x80}, + {value: 0x045f, lo: 0x81, hi: 0x81}, + {value: 0x01bb, lo: 0x82, hi: 0x9a}, + {value: 0x045b, lo: 0x9b, hi: 0x9b}, + {value: 0x01c7, lo: 0x9c, hi: 0x9c}, + {value: 0x01d0, lo: 0x9d, hi: 0x9d}, + {value: 0x01d6, lo: 0x9e, hi: 0x9e}, + {value: 0x01fa, lo: 0x9f, hi: 0x9f}, + {value: 0x01eb, lo: 0xa0, hi: 0xa0}, + {value: 0x01e8, lo: 0xa1, hi: 0xa1}, + {value: 0x0173, lo: 0xa2, hi: 0xb2}, + {value: 0x0188, lo: 0xb3, hi: 0xb3}, + {value: 0x01a6, lo: 0xb4, hi: 0xba}, + {value: 0x045f, lo: 0xbb, hi: 0xbb}, + {value: 0x01bb, lo: 0xbc, hi: 0xbf}, + // Block 0x95, offset 0x31a + {value: 0x0003, lo: 0x0d}, + {value: 0x01c7, lo: 0x80, hi: 0x94}, + {value: 0x045b, lo: 0x95, hi: 0x95}, + {value: 0x01c7, lo: 0x96, hi: 0x96}, + {value: 0x01d0, lo: 0x97, hi: 0x97}, + {value: 0x01d6, lo: 0x98, hi: 0x98}, + {value: 0x01fa, lo: 0x99, hi: 0x99}, + {value: 0x01eb, lo: 0x9a, hi: 0x9a}, + {value: 0x01e8, lo: 0x9b, hi: 0x9b}, + {value: 0x0173, lo: 0x9c, hi: 0xac}, + {value: 0x0188, lo: 0xad, hi: 0xad}, + {value: 0x01a6, lo: 0xae, hi: 0xb4}, + {value: 0x045f, lo: 0xb5, hi: 0xb5}, + {value: 0x01bb, lo: 0xb6, hi: 0xbf}, + // Block 0x96, offset 0x328 + {value: 0x0003, lo: 0x0d}, + {value: 0x01d9, lo: 0x80, hi: 0x8e}, + {value: 0x045b, lo: 0x8f, hi: 0x8f}, + {value: 0x01c7, lo: 0x90, hi: 0x90}, + {value: 0x01d0, lo: 0x91, hi: 0x91}, + {value: 0x01d6, lo: 0x92, hi: 0x92}, + {value: 0x01fa, lo: 0x93, hi: 0x93}, + {value: 0x01eb, lo: 0x94, hi: 0x94}, + {value: 0x01e8, lo: 0x95, hi: 0x95}, + {value: 0x0173, lo: 0x96, hi: 0xa6}, + {value: 0x0188, lo: 0xa7, hi: 0xa7}, + {value: 0x01a6, lo: 0xa8, hi: 0xae}, + {value: 0x045f, lo: 0xaf, hi: 0xaf}, + {value: 0x01bb, lo: 0xb0, hi: 0xbf}, + // Block 0x97, offset 0x336 + {value: 0x0003, lo: 0x0d}, + {value: 0x01eb, lo: 0x80, hi: 0x88}, + {value: 0x045b, lo: 0x89, hi: 0x89}, + {value: 0x01c7, lo: 0x8a, hi: 0x8a}, + {value: 0x01d0, lo: 0x8b, hi: 0x8b}, + {value: 0x01d6, lo: 0x8c, hi: 0x8c}, + {value: 0x01fa, lo: 0x8d, hi: 0x8d}, + {value: 0x01eb, lo: 0x8e, hi: 0x8e}, + {value: 0x01e8, lo: 0x8f, hi: 0x8f}, + {value: 0x0173, lo: 0x90, hi: 0xa0}, + {value: 0x0188, lo: 0xa1, hi: 0xa1}, + {value: 0x01a6, lo: 0xa2, hi: 0xa8}, + {value: 0x045f, lo: 0xa9, hi: 0xa9}, + {value: 0x01bb, lo: 0xaa, hi: 0xbf}, + // Block 0x98, offset 0x344 + {value: 0x0000, lo: 0x05}, + {value: 0x8132, lo: 0x80, hi: 0x86}, + {value: 0x8132, lo: 0x88, hi: 0x98}, + {value: 0x8132, lo: 0x9b, hi: 0xa1}, + {value: 0x8132, lo: 0xa3, hi: 0xa4}, + {value: 0x8132, lo: 0xa6, hi: 0xaa}, + // Block 0x99, offset 0x34a + {value: 0x0000, lo: 0x01}, + {value: 0x812d, lo: 0x90, hi: 0x96}, + // Block 0x9a, offset 0x34c + {value: 0x0000, lo: 0x02}, + {value: 0x8132, lo: 0x84, hi: 0x89}, + {value: 0x8102, lo: 0x8a, hi: 0x8a}, + // Block 0x9b, offset 0x34f + {value: 0x0002, lo: 0x09}, + {value: 0x0063, lo: 0x80, hi: 0x89}, + {value: 0x1951, lo: 0x8a, hi: 0x8a}, + {value: 0x1981, lo: 0x8b, hi: 0x8b}, + {value: 0x199c, lo: 0x8c, hi: 0x8c}, + {value: 0x19a2, lo: 0x8d, hi: 0x8d}, + {value: 0x1bc0, lo: 0x8e, hi: 0x8e}, + {value: 0x19ae, lo: 0x8f, hi: 0x8f}, + {value: 0x197b, lo: 0xaa, hi: 0xaa}, + {value: 0x197e, lo: 0xab, hi: 0xab}, + // Block 0x9c, offset 0x359 + {value: 0x0000, lo: 0x01}, + {value: 0x193f, lo: 0x90, hi: 0x90}, + // Block 0x9d, offset 0x35b + {value: 0x0028, lo: 0x09}, + {value: 0x2862, lo: 0x80, hi: 0x80}, + {value: 0x2826, lo: 0x81, hi: 0x81}, + {value: 0x2830, lo: 0x82, hi: 0x82}, + {value: 0x2844, lo: 0x83, hi: 0x84}, + {value: 0x284e, lo: 0x85, hi: 0x86}, + {value: 0x283a, lo: 0x87, hi: 0x87}, + {value: 0x2858, lo: 0x88, hi: 0x88}, + {value: 0x0b6f, lo: 0x90, hi: 0x90}, + {value: 0x08e7, lo: 0x91, hi: 0x91}, +} + +// recompMap: 7520 bytes (entries only) +var recompMap = map[uint32]rune{ + 0x00410300: 0x00C0, + 0x00410301: 0x00C1, + 0x00410302: 0x00C2, + 0x00410303: 0x00C3, + 0x00410308: 0x00C4, + 0x0041030A: 0x00C5, + 0x00430327: 0x00C7, + 0x00450300: 0x00C8, + 0x00450301: 0x00C9, + 0x00450302: 0x00CA, + 0x00450308: 0x00CB, + 0x00490300: 0x00CC, + 0x00490301: 0x00CD, + 0x00490302: 0x00CE, + 0x00490308: 0x00CF, + 0x004E0303: 0x00D1, + 0x004F0300: 0x00D2, + 0x004F0301: 0x00D3, + 0x004F0302: 0x00D4, + 0x004F0303: 0x00D5, + 0x004F0308: 0x00D6, + 0x00550300: 0x00D9, + 0x00550301: 0x00DA, + 0x00550302: 0x00DB, + 0x00550308: 0x00DC, + 0x00590301: 0x00DD, + 0x00610300: 0x00E0, + 0x00610301: 0x00E1, + 0x00610302: 0x00E2, + 0x00610303: 0x00E3, + 0x00610308: 0x00E4, + 0x0061030A: 0x00E5, + 0x00630327: 0x00E7, + 0x00650300: 0x00E8, + 0x00650301: 0x00E9, + 0x00650302: 0x00EA, + 0x00650308: 0x00EB, + 0x00690300: 0x00EC, + 0x00690301: 0x00ED, + 0x00690302: 0x00EE, + 0x00690308: 0x00EF, + 0x006E0303: 0x00F1, + 0x006F0300: 0x00F2, + 0x006F0301: 0x00F3, + 0x006F0302: 0x00F4, + 0x006F0303: 0x00F5, + 0x006F0308: 0x00F6, + 0x00750300: 0x00F9, + 0x00750301: 0x00FA, + 0x00750302: 0x00FB, + 0x00750308: 0x00FC, + 0x00790301: 0x00FD, + 0x00790308: 0x00FF, + 0x00410304: 0x0100, + 0x00610304: 0x0101, + 0x00410306: 0x0102, + 0x00610306: 0x0103, + 0x00410328: 0x0104, + 0x00610328: 0x0105, + 0x00430301: 0x0106, + 0x00630301: 0x0107, + 0x00430302: 0x0108, + 0x00630302: 0x0109, + 0x00430307: 0x010A, + 0x00630307: 0x010B, + 0x0043030C: 0x010C, + 0x0063030C: 0x010D, + 0x0044030C: 0x010E, + 0x0064030C: 0x010F, + 0x00450304: 0x0112, + 0x00650304: 0x0113, + 0x00450306: 0x0114, + 0x00650306: 0x0115, + 0x00450307: 0x0116, + 0x00650307: 0x0117, + 0x00450328: 0x0118, + 0x00650328: 0x0119, + 0x0045030C: 0x011A, + 0x0065030C: 0x011B, + 0x00470302: 0x011C, + 0x00670302: 0x011D, + 0x00470306: 0x011E, + 0x00670306: 0x011F, + 0x00470307: 0x0120, + 0x00670307: 0x0121, + 0x00470327: 0x0122, + 0x00670327: 0x0123, + 0x00480302: 0x0124, + 0x00680302: 0x0125, + 0x00490303: 0x0128, + 0x00690303: 0x0129, + 0x00490304: 0x012A, + 0x00690304: 0x012B, + 0x00490306: 0x012C, + 0x00690306: 0x012D, + 0x00490328: 0x012E, + 0x00690328: 0x012F, + 0x00490307: 0x0130, + 0x004A0302: 0x0134, + 0x006A0302: 0x0135, + 0x004B0327: 0x0136, + 0x006B0327: 0x0137, + 0x004C0301: 0x0139, + 0x006C0301: 0x013A, + 0x004C0327: 0x013B, + 0x006C0327: 0x013C, + 0x004C030C: 0x013D, + 0x006C030C: 0x013E, + 0x004E0301: 0x0143, + 0x006E0301: 0x0144, + 0x004E0327: 0x0145, + 0x006E0327: 0x0146, + 0x004E030C: 0x0147, + 0x006E030C: 0x0148, + 0x004F0304: 0x014C, + 0x006F0304: 0x014D, + 0x004F0306: 0x014E, + 0x006F0306: 0x014F, + 0x004F030B: 0x0150, + 0x006F030B: 0x0151, + 0x00520301: 0x0154, + 0x00720301: 0x0155, + 0x00520327: 0x0156, + 0x00720327: 0x0157, + 0x0052030C: 0x0158, + 0x0072030C: 0x0159, + 0x00530301: 0x015A, + 0x00730301: 0x015B, + 0x00530302: 0x015C, + 0x00730302: 0x015D, + 0x00530327: 0x015E, + 0x00730327: 0x015F, + 0x0053030C: 0x0160, + 0x0073030C: 0x0161, + 0x00540327: 0x0162, + 0x00740327: 0x0163, + 0x0054030C: 0x0164, + 0x0074030C: 0x0165, + 0x00550303: 0x0168, + 0x00750303: 0x0169, + 0x00550304: 0x016A, + 0x00750304: 0x016B, + 0x00550306: 0x016C, + 0x00750306: 0x016D, + 0x0055030A: 0x016E, + 0x0075030A: 0x016F, + 0x0055030B: 0x0170, + 0x0075030B: 0x0171, + 0x00550328: 0x0172, + 0x00750328: 0x0173, + 0x00570302: 0x0174, + 0x00770302: 0x0175, + 0x00590302: 0x0176, + 0x00790302: 0x0177, + 0x00590308: 0x0178, + 0x005A0301: 0x0179, + 0x007A0301: 0x017A, + 0x005A0307: 0x017B, + 0x007A0307: 0x017C, + 0x005A030C: 0x017D, + 0x007A030C: 0x017E, + 0x004F031B: 0x01A0, + 0x006F031B: 0x01A1, + 0x0055031B: 0x01AF, + 0x0075031B: 0x01B0, + 0x0041030C: 0x01CD, + 0x0061030C: 0x01CE, + 0x0049030C: 0x01CF, + 0x0069030C: 0x01D0, + 0x004F030C: 0x01D1, + 0x006F030C: 0x01D2, + 0x0055030C: 0x01D3, + 0x0075030C: 0x01D4, + 0x00DC0304: 0x01D5, + 0x00FC0304: 0x01D6, + 0x00DC0301: 0x01D7, + 0x00FC0301: 0x01D8, + 0x00DC030C: 0x01D9, + 0x00FC030C: 0x01DA, + 0x00DC0300: 0x01DB, + 0x00FC0300: 0x01DC, + 0x00C40304: 0x01DE, + 0x00E40304: 0x01DF, + 0x02260304: 0x01E0, + 0x02270304: 0x01E1, + 0x00C60304: 0x01E2, + 0x00E60304: 0x01E3, + 0x0047030C: 0x01E6, + 0x0067030C: 0x01E7, + 0x004B030C: 0x01E8, + 0x006B030C: 0x01E9, + 0x004F0328: 0x01EA, + 0x006F0328: 0x01EB, + 0x01EA0304: 0x01EC, + 0x01EB0304: 0x01ED, + 0x01B7030C: 0x01EE, + 0x0292030C: 0x01EF, + 0x006A030C: 0x01F0, + 0x00470301: 0x01F4, + 0x00670301: 0x01F5, + 0x004E0300: 0x01F8, + 0x006E0300: 0x01F9, + 0x00C50301: 0x01FA, + 0x00E50301: 0x01FB, + 0x00C60301: 0x01FC, + 0x00E60301: 0x01FD, + 0x00D80301: 0x01FE, + 0x00F80301: 0x01FF, + 0x0041030F: 0x0200, + 0x0061030F: 0x0201, + 0x00410311: 0x0202, + 0x00610311: 0x0203, + 0x0045030F: 0x0204, + 0x0065030F: 0x0205, + 0x00450311: 0x0206, + 0x00650311: 0x0207, + 0x0049030F: 0x0208, + 0x0069030F: 0x0209, + 0x00490311: 0x020A, + 0x00690311: 0x020B, + 0x004F030F: 0x020C, + 0x006F030F: 0x020D, + 0x004F0311: 0x020E, + 0x006F0311: 0x020F, + 0x0052030F: 0x0210, + 0x0072030F: 0x0211, + 0x00520311: 0x0212, + 0x00720311: 0x0213, + 0x0055030F: 0x0214, + 0x0075030F: 0x0215, + 0x00550311: 0x0216, + 0x00750311: 0x0217, + 0x00530326: 0x0218, + 0x00730326: 0x0219, + 0x00540326: 0x021A, + 0x00740326: 0x021B, + 0x0048030C: 0x021E, + 0x0068030C: 0x021F, + 0x00410307: 0x0226, + 0x00610307: 0x0227, + 0x00450327: 0x0228, + 0x00650327: 0x0229, + 0x00D60304: 0x022A, + 0x00F60304: 0x022B, + 0x00D50304: 0x022C, + 0x00F50304: 0x022D, + 0x004F0307: 0x022E, + 0x006F0307: 0x022F, + 0x022E0304: 0x0230, + 0x022F0304: 0x0231, + 0x00590304: 0x0232, + 0x00790304: 0x0233, + 0x00A80301: 0x0385, + 0x03910301: 0x0386, + 0x03950301: 0x0388, + 0x03970301: 0x0389, + 0x03990301: 0x038A, + 0x039F0301: 0x038C, + 0x03A50301: 0x038E, + 0x03A90301: 0x038F, + 0x03CA0301: 0x0390, + 0x03990308: 0x03AA, + 0x03A50308: 0x03AB, + 0x03B10301: 0x03AC, + 0x03B50301: 0x03AD, + 0x03B70301: 0x03AE, + 0x03B90301: 0x03AF, + 0x03CB0301: 0x03B0, + 0x03B90308: 0x03CA, + 0x03C50308: 0x03CB, + 0x03BF0301: 0x03CC, + 0x03C50301: 0x03CD, + 0x03C90301: 0x03CE, + 0x03D20301: 0x03D3, + 0x03D20308: 0x03D4, + 0x04150300: 0x0400, + 0x04150308: 0x0401, + 0x04130301: 0x0403, + 0x04060308: 0x0407, + 0x041A0301: 0x040C, + 0x04180300: 0x040D, + 0x04230306: 0x040E, + 0x04180306: 0x0419, + 0x04380306: 0x0439, + 0x04350300: 0x0450, + 0x04350308: 0x0451, + 0x04330301: 0x0453, + 0x04560308: 0x0457, + 0x043A0301: 0x045C, + 0x04380300: 0x045D, + 0x04430306: 0x045E, + 0x0474030F: 0x0476, + 0x0475030F: 0x0477, + 0x04160306: 0x04C1, + 0x04360306: 0x04C2, + 0x04100306: 0x04D0, + 0x04300306: 0x04D1, + 0x04100308: 0x04D2, + 0x04300308: 0x04D3, + 0x04150306: 0x04D6, + 0x04350306: 0x04D7, + 0x04D80308: 0x04DA, + 0x04D90308: 0x04DB, + 0x04160308: 0x04DC, + 0x04360308: 0x04DD, + 0x04170308: 0x04DE, + 0x04370308: 0x04DF, + 0x04180304: 0x04E2, + 0x04380304: 0x04E3, + 0x04180308: 0x04E4, + 0x04380308: 0x04E5, + 0x041E0308: 0x04E6, + 0x043E0308: 0x04E7, + 0x04E80308: 0x04EA, + 0x04E90308: 0x04EB, + 0x042D0308: 0x04EC, + 0x044D0308: 0x04ED, + 0x04230304: 0x04EE, + 0x04430304: 0x04EF, + 0x04230308: 0x04F0, + 0x04430308: 0x04F1, + 0x0423030B: 0x04F2, + 0x0443030B: 0x04F3, + 0x04270308: 0x04F4, + 0x04470308: 0x04F5, + 0x042B0308: 0x04F8, + 0x044B0308: 0x04F9, + 0x06270653: 0x0622, + 0x06270654: 0x0623, + 0x06480654: 0x0624, + 0x06270655: 0x0625, + 0x064A0654: 0x0626, + 0x06D50654: 0x06C0, + 0x06C10654: 0x06C2, + 0x06D20654: 0x06D3, + 0x0928093C: 0x0929, + 0x0930093C: 0x0931, + 0x0933093C: 0x0934, + 0x09C709BE: 0x09CB, + 0x09C709D7: 0x09CC, + 0x0B470B56: 0x0B48, + 0x0B470B3E: 0x0B4B, + 0x0B470B57: 0x0B4C, + 0x0B920BD7: 0x0B94, + 0x0BC60BBE: 0x0BCA, + 0x0BC70BBE: 0x0BCB, + 0x0BC60BD7: 0x0BCC, + 0x0C460C56: 0x0C48, + 0x0CBF0CD5: 0x0CC0, + 0x0CC60CD5: 0x0CC7, + 0x0CC60CD6: 0x0CC8, + 0x0CC60CC2: 0x0CCA, + 0x0CCA0CD5: 0x0CCB, + 0x0D460D3E: 0x0D4A, + 0x0D470D3E: 0x0D4B, + 0x0D460D57: 0x0D4C, + 0x0DD90DCA: 0x0DDA, + 0x0DD90DCF: 0x0DDC, + 0x0DDC0DCA: 0x0DDD, + 0x0DD90DDF: 0x0DDE, + 0x1025102E: 0x1026, + 0x1B051B35: 0x1B06, + 0x1B071B35: 0x1B08, + 0x1B091B35: 0x1B0A, + 0x1B0B1B35: 0x1B0C, + 0x1B0D1B35: 0x1B0E, + 0x1B111B35: 0x1B12, + 0x1B3A1B35: 0x1B3B, + 0x1B3C1B35: 0x1B3D, + 0x1B3E1B35: 0x1B40, + 0x1B3F1B35: 0x1B41, + 0x1B421B35: 0x1B43, + 0x00410325: 0x1E00, + 0x00610325: 0x1E01, + 0x00420307: 0x1E02, + 0x00620307: 0x1E03, + 0x00420323: 0x1E04, + 0x00620323: 0x1E05, + 0x00420331: 0x1E06, + 0x00620331: 0x1E07, + 0x00C70301: 0x1E08, + 0x00E70301: 0x1E09, + 0x00440307: 0x1E0A, + 0x00640307: 0x1E0B, + 0x00440323: 0x1E0C, + 0x00640323: 0x1E0D, + 0x00440331: 0x1E0E, + 0x00640331: 0x1E0F, + 0x00440327: 0x1E10, + 0x00640327: 0x1E11, + 0x0044032D: 0x1E12, + 0x0064032D: 0x1E13, + 0x01120300: 0x1E14, + 0x01130300: 0x1E15, + 0x01120301: 0x1E16, + 0x01130301: 0x1E17, + 0x0045032D: 0x1E18, + 0x0065032D: 0x1E19, + 0x00450330: 0x1E1A, + 0x00650330: 0x1E1B, + 0x02280306: 0x1E1C, + 0x02290306: 0x1E1D, + 0x00460307: 0x1E1E, + 0x00660307: 0x1E1F, + 0x00470304: 0x1E20, + 0x00670304: 0x1E21, + 0x00480307: 0x1E22, + 0x00680307: 0x1E23, + 0x00480323: 0x1E24, + 0x00680323: 0x1E25, + 0x00480308: 0x1E26, + 0x00680308: 0x1E27, + 0x00480327: 0x1E28, + 0x00680327: 0x1E29, + 0x0048032E: 0x1E2A, + 0x0068032E: 0x1E2B, + 0x00490330: 0x1E2C, + 0x00690330: 0x1E2D, + 0x00CF0301: 0x1E2E, + 0x00EF0301: 0x1E2F, + 0x004B0301: 0x1E30, + 0x006B0301: 0x1E31, + 0x004B0323: 0x1E32, + 0x006B0323: 0x1E33, + 0x004B0331: 0x1E34, + 0x006B0331: 0x1E35, + 0x004C0323: 0x1E36, + 0x006C0323: 0x1E37, + 0x1E360304: 0x1E38, + 0x1E370304: 0x1E39, + 0x004C0331: 0x1E3A, + 0x006C0331: 0x1E3B, + 0x004C032D: 0x1E3C, + 0x006C032D: 0x1E3D, + 0x004D0301: 0x1E3E, + 0x006D0301: 0x1E3F, + 0x004D0307: 0x1E40, + 0x006D0307: 0x1E41, + 0x004D0323: 0x1E42, + 0x006D0323: 0x1E43, + 0x004E0307: 0x1E44, + 0x006E0307: 0x1E45, + 0x004E0323: 0x1E46, + 0x006E0323: 0x1E47, + 0x004E0331: 0x1E48, + 0x006E0331: 0x1E49, + 0x004E032D: 0x1E4A, + 0x006E032D: 0x1E4B, + 0x00D50301: 0x1E4C, + 0x00F50301: 0x1E4D, + 0x00D50308: 0x1E4E, + 0x00F50308: 0x1E4F, + 0x014C0300: 0x1E50, + 0x014D0300: 0x1E51, + 0x014C0301: 0x1E52, + 0x014D0301: 0x1E53, + 0x00500301: 0x1E54, + 0x00700301: 0x1E55, + 0x00500307: 0x1E56, + 0x00700307: 0x1E57, + 0x00520307: 0x1E58, + 0x00720307: 0x1E59, + 0x00520323: 0x1E5A, + 0x00720323: 0x1E5B, + 0x1E5A0304: 0x1E5C, + 0x1E5B0304: 0x1E5D, + 0x00520331: 0x1E5E, + 0x00720331: 0x1E5F, + 0x00530307: 0x1E60, + 0x00730307: 0x1E61, + 0x00530323: 0x1E62, + 0x00730323: 0x1E63, + 0x015A0307: 0x1E64, + 0x015B0307: 0x1E65, + 0x01600307: 0x1E66, + 0x01610307: 0x1E67, + 0x1E620307: 0x1E68, + 0x1E630307: 0x1E69, + 0x00540307: 0x1E6A, + 0x00740307: 0x1E6B, + 0x00540323: 0x1E6C, + 0x00740323: 0x1E6D, + 0x00540331: 0x1E6E, + 0x00740331: 0x1E6F, + 0x0054032D: 0x1E70, + 0x0074032D: 0x1E71, + 0x00550324: 0x1E72, + 0x00750324: 0x1E73, + 0x00550330: 0x1E74, + 0x00750330: 0x1E75, + 0x0055032D: 0x1E76, + 0x0075032D: 0x1E77, + 0x01680301: 0x1E78, + 0x01690301: 0x1E79, + 0x016A0308: 0x1E7A, + 0x016B0308: 0x1E7B, + 0x00560303: 0x1E7C, + 0x00760303: 0x1E7D, + 0x00560323: 0x1E7E, + 0x00760323: 0x1E7F, + 0x00570300: 0x1E80, + 0x00770300: 0x1E81, + 0x00570301: 0x1E82, + 0x00770301: 0x1E83, + 0x00570308: 0x1E84, + 0x00770308: 0x1E85, + 0x00570307: 0x1E86, + 0x00770307: 0x1E87, + 0x00570323: 0x1E88, + 0x00770323: 0x1E89, + 0x00580307: 0x1E8A, + 0x00780307: 0x1E8B, + 0x00580308: 0x1E8C, + 0x00780308: 0x1E8D, + 0x00590307: 0x1E8E, + 0x00790307: 0x1E8F, + 0x005A0302: 0x1E90, + 0x007A0302: 0x1E91, + 0x005A0323: 0x1E92, + 0x007A0323: 0x1E93, + 0x005A0331: 0x1E94, + 0x007A0331: 0x1E95, + 0x00680331: 0x1E96, + 0x00740308: 0x1E97, + 0x0077030A: 0x1E98, + 0x0079030A: 0x1E99, + 0x017F0307: 0x1E9B, + 0x00410323: 0x1EA0, + 0x00610323: 0x1EA1, + 0x00410309: 0x1EA2, + 0x00610309: 0x1EA3, + 0x00C20301: 0x1EA4, + 0x00E20301: 0x1EA5, + 0x00C20300: 0x1EA6, + 0x00E20300: 0x1EA7, + 0x00C20309: 0x1EA8, + 0x00E20309: 0x1EA9, + 0x00C20303: 0x1EAA, + 0x00E20303: 0x1EAB, + 0x1EA00302: 0x1EAC, + 0x1EA10302: 0x1EAD, + 0x01020301: 0x1EAE, + 0x01030301: 0x1EAF, + 0x01020300: 0x1EB0, + 0x01030300: 0x1EB1, + 0x01020309: 0x1EB2, + 0x01030309: 0x1EB3, + 0x01020303: 0x1EB4, + 0x01030303: 0x1EB5, + 0x1EA00306: 0x1EB6, + 0x1EA10306: 0x1EB7, + 0x00450323: 0x1EB8, + 0x00650323: 0x1EB9, + 0x00450309: 0x1EBA, + 0x00650309: 0x1EBB, + 0x00450303: 0x1EBC, + 0x00650303: 0x1EBD, + 0x00CA0301: 0x1EBE, + 0x00EA0301: 0x1EBF, + 0x00CA0300: 0x1EC0, + 0x00EA0300: 0x1EC1, + 0x00CA0309: 0x1EC2, + 0x00EA0309: 0x1EC3, + 0x00CA0303: 0x1EC4, + 0x00EA0303: 0x1EC5, + 0x1EB80302: 0x1EC6, + 0x1EB90302: 0x1EC7, + 0x00490309: 0x1EC8, + 0x00690309: 0x1EC9, + 0x00490323: 0x1ECA, + 0x00690323: 0x1ECB, + 0x004F0323: 0x1ECC, + 0x006F0323: 0x1ECD, + 0x004F0309: 0x1ECE, + 0x006F0309: 0x1ECF, + 0x00D40301: 0x1ED0, + 0x00F40301: 0x1ED1, + 0x00D40300: 0x1ED2, + 0x00F40300: 0x1ED3, + 0x00D40309: 0x1ED4, + 0x00F40309: 0x1ED5, + 0x00D40303: 0x1ED6, + 0x00F40303: 0x1ED7, + 0x1ECC0302: 0x1ED8, + 0x1ECD0302: 0x1ED9, + 0x01A00301: 0x1EDA, + 0x01A10301: 0x1EDB, + 0x01A00300: 0x1EDC, + 0x01A10300: 0x1EDD, + 0x01A00309: 0x1EDE, + 0x01A10309: 0x1EDF, + 0x01A00303: 0x1EE0, + 0x01A10303: 0x1EE1, + 0x01A00323: 0x1EE2, + 0x01A10323: 0x1EE3, + 0x00550323: 0x1EE4, + 0x00750323: 0x1EE5, + 0x00550309: 0x1EE6, + 0x00750309: 0x1EE7, + 0x01AF0301: 0x1EE8, + 0x01B00301: 0x1EE9, + 0x01AF0300: 0x1EEA, + 0x01B00300: 0x1EEB, + 0x01AF0309: 0x1EEC, + 0x01B00309: 0x1EED, + 0x01AF0303: 0x1EEE, + 0x01B00303: 0x1EEF, + 0x01AF0323: 0x1EF0, + 0x01B00323: 0x1EF1, + 0x00590300: 0x1EF2, + 0x00790300: 0x1EF3, + 0x00590323: 0x1EF4, + 0x00790323: 0x1EF5, + 0x00590309: 0x1EF6, + 0x00790309: 0x1EF7, + 0x00590303: 0x1EF8, + 0x00790303: 0x1EF9, + 0x03B10313: 0x1F00, + 0x03B10314: 0x1F01, + 0x1F000300: 0x1F02, + 0x1F010300: 0x1F03, + 0x1F000301: 0x1F04, + 0x1F010301: 0x1F05, + 0x1F000342: 0x1F06, + 0x1F010342: 0x1F07, + 0x03910313: 0x1F08, + 0x03910314: 0x1F09, + 0x1F080300: 0x1F0A, + 0x1F090300: 0x1F0B, + 0x1F080301: 0x1F0C, + 0x1F090301: 0x1F0D, + 0x1F080342: 0x1F0E, + 0x1F090342: 0x1F0F, + 0x03B50313: 0x1F10, + 0x03B50314: 0x1F11, + 0x1F100300: 0x1F12, + 0x1F110300: 0x1F13, + 0x1F100301: 0x1F14, + 0x1F110301: 0x1F15, + 0x03950313: 0x1F18, + 0x03950314: 0x1F19, + 0x1F180300: 0x1F1A, + 0x1F190300: 0x1F1B, + 0x1F180301: 0x1F1C, + 0x1F190301: 0x1F1D, + 0x03B70313: 0x1F20, + 0x03B70314: 0x1F21, + 0x1F200300: 0x1F22, + 0x1F210300: 0x1F23, + 0x1F200301: 0x1F24, + 0x1F210301: 0x1F25, + 0x1F200342: 0x1F26, + 0x1F210342: 0x1F27, + 0x03970313: 0x1F28, + 0x03970314: 0x1F29, + 0x1F280300: 0x1F2A, + 0x1F290300: 0x1F2B, + 0x1F280301: 0x1F2C, + 0x1F290301: 0x1F2D, + 0x1F280342: 0x1F2E, + 0x1F290342: 0x1F2F, + 0x03B90313: 0x1F30, + 0x03B90314: 0x1F31, + 0x1F300300: 0x1F32, + 0x1F310300: 0x1F33, + 0x1F300301: 0x1F34, + 0x1F310301: 0x1F35, + 0x1F300342: 0x1F36, + 0x1F310342: 0x1F37, + 0x03990313: 0x1F38, + 0x03990314: 0x1F39, + 0x1F380300: 0x1F3A, + 0x1F390300: 0x1F3B, + 0x1F380301: 0x1F3C, + 0x1F390301: 0x1F3D, + 0x1F380342: 0x1F3E, + 0x1F390342: 0x1F3F, + 0x03BF0313: 0x1F40, + 0x03BF0314: 0x1F41, + 0x1F400300: 0x1F42, + 0x1F410300: 0x1F43, + 0x1F400301: 0x1F44, + 0x1F410301: 0x1F45, + 0x039F0313: 0x1F48, + 0x039F0314: 0x1F49, + 0x1F480300: 0x1F4A, + 0x1F490300: 0x1F4B, + 0x1F480301: 0x1F4C, + 0x1F490301: 0x1F4D, + 0x03C50313: 0x1F50, + 0x03C50314: 0x1F51, + 0x1F500300: 0x1F52, + 0x1F510300: 0x1F53, + 0x1F500301: 0x1F54, + 0x1F510301: 0x1F55, + 0x1F500342: 0x1F56, + 0x1F510342: 0x1F57, + 0x03A50314: 0x1F59, + 0x1F590300: 0x1F5B, + 0x1F590301: 0x1F5D, + 0x1F590342: 0x1F5F, + 0x03C90313: 0x1F60, + 0x03C90314: 0x1F61, + 0x1F600300: 0x1F62, + 0x1F610300: 0x1F63, + 0x1F600301: 0x1F64, + 0x1F610301: 0x1F65, + 0x1F600342: 0x1F66, + 0x1F610342: 0x1F67, + 0x03A90313: 0x1F68, + 0x03A90314: 0x1F69, + 0x1F680300: 0x1F6A, + 0x1F690300: 0x1F6B, + 0x1F680301: 0x1F6C, + 0x1F690301: 0x1F6D, + 0x1F680342: 0x1F6E, + 0x1F690342: 0x1F6F, + 0x03B10300: 0x1F70, + 0x03B50300: 0x1F72, + 0x03B70300: 0x1F74, + 0x03B90300: 0x1F76, + 0x03BF0300: 0x1F78, + 0x03C50300: 0x1F7A, + 0x03C90300: 0x1F7C, + 0x1F000345: 0x1F80, + 0x1F010345: 0x1F81, + 0x1F020345: 0x1F82, + 0x1F030345: 0x1F83, + 0x1F040345: 0x1F84, + 0x1F050345: 0x1F85, + 0x1F060345: 0x1F86, + 0x1F070345: 0x1F87, + 0x1F080345: 0x1F88, + 0x1F090345: 0x1F89, + 0x1F0A0345: 0x1F8A, + 0x1F0B0345: 0x1F8B, + 0x1F0C0345: 0x1F8C, + 0x1F0D0345: 0x1F8D, + 0x1F0E0345: 0x1F8E, + 0x1F0F0345: 0x1F8F, + 0x1F200345: 0x1F90, + 0x1F210345: 0x1F91, + 0x1F220345: 0x1F92, + 0x1F230345: 0x1F93, + 0x1F240345: 0x1F94, + 0x1F250345: 0x1F95, + 0x1F260345: 0x1F96, + 0x1F270345: 0x1F97, + 0x1F280345: 0x1F98, + 0x1F290345: 0x1F99, + 0x1F2A0345: 0x1F9A, + 0x1F2B0345: 0x1F9B, + 0x1F2C0345: 0x1F9C, + 0x1F2D0345: 0x1F9D, + 0x1F2E0345: 0x1F9E, + 0x1F2F0345: 0x1F9F, + 0x1F600345: 0x1FA0, + 0x1F610345: 0x1FA1, + 0x1F620345: 0x1FA2, + 0x1F630345: 0x1FA3, + 0x1F640345: 0x1FA4, + 0x1F650345: 0x1FA5, + 0x1F660345: 0x1FA6, + 0x1F670345: 0x1FA7, + 0x1F680345: 0x1FA8, + 0x1F690345: 0x1FA9, + 0x1F6A0345: 0x1FAA, + 0x1F6B0345: 0x1FAB, + 0x1F6C0345: 0x1FAC, + 0x1F6D0345: 0x1FAD, + 0x1F6E0345: 0x1FAE, + 0x1F6F0345: 0x1FAF, + 0x03B10306: 0x1FB0, + 0x03B10304: 0x1FB1, + 0x1F700345: 0x1FB2, + 0x03B10345: 0x1FB3, + 0x03AC0345: 0x1FB4, + 0x03B10342: 0x1FB6, + 0x1FB60345: 0x1FB7, + 0x03910306: 0x1FB8, + 0x03910304: 0x1FB9, + 0x03910300: 0x1FBA, + 0x03910345: 0x1FBC, + 0x00A80342: 0x1FC1, + 0x1F740345: 0x1FC2, + 0x03B70345: 0x1FC3, + 0x03AE0345: 0x1FC4, + 0x03B70342: 0x1FC6, + 0x1FC60345: 0x1FC7, + 0x03950300: 0x1FC8, + 0x03970300: 0x1FCA, + 0x03970345: 0x1FCC, + 0x1FBF0300: 0x1FCD, + 0x1FBF0301: 0x1FCE, + 0x1FBF0342: 0x1FCF, + 0x03B90306: 0x1FD0, + 0x03B90304: 0x1FD1, + 0x03CA0300: 0x1FD2, + 0x03B90342: 0x1FD6, + 0x03CA0342: 0x1FD7, + 0x03990306: 0x1FD8, + 0x03990304: 0x1FD9, + 0x03990300: 0x1FDA, + 0x1FFE0300: 0x1FDD, + 0x1FFE0301: 0x1FDE, + 0x1FFE0342: 0x1FDF, + 0x03C50306: 0x1FE0, + 0x03C50304: 0x1FE1, + 0x03CB0300: 0x1FE2, + 0x03C10313: 0x1FE4, + 0x03C10314: 0x1FE5, + 0x03C50342: 0x1FE6, + 0x03CB0342: 0x1FE7, + 0x03A50306: 0x1FE8, + 0x03A50304: 0x1FE9, + 0x03A50300: 0x1FEA, + 0x03A10314: 0x1FEC, + 0x00A80300: 0x1FED, + 0x1F7C0345: 0x1FF2, + 0x03C90345: 0x1FF3, + 0x03CE0345: 0x1FF4, + 0x03C90342: 0x1FF6, + 0x1FF60345: 0x1FF7, + 0x039F0300: 0x1FF8, + 0x03A90300: 0x1FFA, + 0x03A90345: 0x1FFC, + 0x21900338: 0x219A, + 0x21920338: 0x219B, + 0x21940338: 0x21AE, + 0x21D00338: 0x21CD, + 0x21D40338: 0x21CE, + 0x21D20338: 0x21CF, + 0x22030338: 0x2204, + 0x22080338: 0x2209, + 0x220B0338: 0x220C, + 0x22230338: 0x2224, + 0x22250338: 0x2226, + 0x223C0338: 0x2241, + 0x22430338: 0x2244, + 0x22450338: 0x2247, + 0x22480338: 0x2249, + 0x003D0338: 0x2260, + 0x22610338: 0x2262, + 0x224D0338: 0x226D, + 0x003C0338: 0x226E, + 0x003E0338: 0x226F, + 0x22640338: 0x2270, + 0x22650338: 0x2271, + 0x22720338: 0x2274, + 0x22730338: 0x2275, + 0x22760338: 0x2278, + 0x22770338: 0x2279, + 0x227A0338: 0x2280, + 0x227B0338: 0x2281, + 0x22820338: 0x2284, + 0x22830338: 0x2285, + 0x22860338: 0x2288, + 0x22870338: 0x2289, + 0x22A20338: 0x22AC, + 0x22A80338: 0x22AD, + 0x22A90338: 0x22AE, + 0x22AB0338: 0x22AF, + 0x227C0338: 0x22E0, + 0x227D0338: 0x22E1, + 0x22910338: 0x22E2, + 0x22920338: 0x22E3, + 0x22B20338: 0x22EA, + 0x22B30338: 0x22EB, + 0x22B40338: 0x22EC, + 0x22B50338: 0x22ED, + 0x304B3099: 0x304C, + 0x304D3099: 0x304E, + 0x304F3099: 0x3050, + 0x30513099: 0x3052, + 0x30533099: 0x3054, + 0x30553099: 0x3056, + 0x30573099: 0x3058, + 0x30593099: 0x305A, + 0x305B3099: 0x305C, + 0x305D3099: 0x305E, + 0x305F3099: 0x3060, + 0x30613099: 0x3062, + 0x30643099: 0x3065, + 0x30663099: 0x3067, + 0x30683099: 0x3069, + 0x306F3099: 0x3070, + 0x306F309A: 0x3071, + 0x30723099: 0x3073, + 0x3072309A: 0x3074, + 0x30753099: 0x3076, + 0x3075309A: 0x3077, + 0x30783099: 0x3079, + 0x3078309A: 0x307A, + 0x307B3099: 0x307C, + 0x307B309A: 0x307D, + 0x30463099: 0x3094, + 0x309D3099: 0x309E, + 0x30AB3099: 0x30AC, + 0x30AD3099: 0x30AE, + 0x30AF3099: 0x30B0, + 0x30B13099: 0x30B2, + 0x30B33099: 0x30B4, + 0x30B53099: 0x30B6, + 0x30B73099: 0x30B8, + 0x30B93099: 0x30BA, + 0x30BB3099: 0x30BC, + 0x30BD3099: 0x30BE, + 0x30BF3099: 0x30C0, + 0x30C13099: 0x30C2, + 0x30C43099: 0x30C5, + 0x30C63099: 0x30C7, + 0x30C83099: 0x30C9, + 0x30CF3099: 0x30D0, + 0x30CF309A: 0x30D1, + 0x30D23099: 0x30D3, + 0x30D2309A: 0x30D4, + 0x30D53099: 0x30D6, + 0x30D5309A: 0x30D7, + 0x30D83099: 0x30D9, + 0x30D8309A: 0x30DA, + 0x30DB3099: 0x30DC, + 0x30DB309A: 0x30DD, + 0x30A63099: 0x30F4, + 0x30EF3099: 0x30F7, + 0x30F03099: 0x30F8, + 0x30F13099: 0x30F9, + 0x30F23099: 0x30FA, + 0x30FD3099: 0x30FE, + 0x109910BA: 0x1109A, + 0x109B10BA: 0x1109C, + 0x10A510BA: 0x110AB, + 0x11311127: 0x1112E, + 0x11321127: 0x1112F, + 0x1347133E: 0x1134B, + 0x13471357: 0x1134C, + 0x14B914BA: 0x114BB, + 0x14B914B0: 0x114BC, + 0x14B914BD: 0x114BE, + 0x15B815AF: 0x115BA, + 0x15B915AF: 0x115BB, +} + +// Total size of tables: 53KB (54226 bytes) diff --git a/vendor/golang.org/x/text/unicode/norm/tables9.0.0.go b/vendor/golang.org/x/text/unicode/norm/tables9.0.0.go new file mode 100644 index 0000000000..a01274a8e8 --- /dev/null +++ b/vendor/golang.org/x/text/unicode/norm/tables9.0.0.go @@ -0,0 +1,7633 @@ +// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. + +// +build !go1.10 + +package norm + +const ( + // Version is the Unicode edition from which the tables are derived. + Version = "9.0.0" + + // MaxTransformChunkSize indicates the maximum number of bytes that Transform + // may need to write atomically for any Form. Making a destination buffer at + // least this size ensures that Transform can always make progress and that + // the user does not need to grow the buffer on an ErrShortDst. + MaxTransformChunkSize = 35 + maxNonStarters*4 +) + +var ccc = [55]uint8{ + 0, 1, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 24, 25, 26, 27, 28, + 29, 30, 31, 32, 33, 34, 35, 36, + 84, 91, 103, 107, 118, 122, 129, 130, + 132, 202, 214, 216, 218, 220, 222, 224, + 226, 228, 230, 232, 233, 234, 240, +} + +const ( + firstMulti = 0x186D + firstCCC = 0x2C9E + endMulti = 0x2F60 + firstLeadingCCC = 0x49AE + firstCCCZeroExcept = 0x4A78 + firstStarterWithNLead = 0x4A9F + lastDecomp = 0x4AA1 + maxDecomp = 0x8000 +) + +// decomps: 19105 bytes +var decomps = [...]byte{ + // Bytes 0 - 3f + 0x00, 0x41, 0x20, 0x41, 0x21, 0x41, 0x22, 0x41, + 0x23, 0x41, 0x24, 0x41, 0x25, 0x41, 0x26, 0x41, + 0x27, 0x41, 0x28, 0x41, 0x29, 0x41, 0x2A, 0x41, + 0x2B, 0x41, 0x2C, 0x41, 0x2D, 0x41, 0x2E, 0x41, + 0x2F, 0x41, 0x30, 0x41, 0x31, 0x41, 0x32, 0x41, + 0x33, 0x41, 0x34, 0x41, 0x35, 0x41, 0x36, 0x41, + 0x37, 0x41, 0x38, 0x41, 0x39, 0x41, 0x3A, 0x41, + 0x3B, 0x41, 0x3C, 0x41, 0x3D, 0x41, 0x3E, 0x41, + // Bytes 40 - 7f + 0x3F, 0x41, 0x40, 0x41, 0x41, 0x41, 0x42, 0x41, + 0x43, 0x41, 0x44, 0x41, 0x45, 0x41, 0x46, 0x41, + 0x47, 0x41, 0x48, 0x41, 0x49, 0x41, 0x4A, 0x41, + 0x4B, 0x41, 0x4C, 0x41, 0x4D, 0x41, 0x4E, 0x41, + 0x4F, 0x41, 0x50, 0x41, 0x51, 0x41, 0x52, 0x41, + 0x53, 0x41, 0x54, 0x41, 0x55, 0x41, 0x56, 0x41, + 0x57, 0x41, 0x58, 0x41, 0x59, 0x41, 0x5A, 0x41, + 0x5B, 0x41, 0x5C, 0x41, 0x5D, 0x41, 0x5E, 0x41, + // Bytes 80 - bf + 0x5F, 0x41, 0x60, 0x41, 0x61, 0x41, 0x62, 0x41, + 0x63, 0x41, 0x64, 0x41, 0x65, 0x41, 0x66, 0x41, + 0x67, 0x41, 0x68, 0x41, 0x69, 0x41, 0x6A, 0x41, + 0x6B, 0x41, 0x6C, 0x41, 0x6D, 0x41, 0x6E, 0x41, + 0x6F, 0x41, 0x70, 0x41, 0x71, 0x41, 0x72, 0x41, + 0x73, 0x41, 0x74, 0x41, 0x75, 0x41, 0x76, 0x41, + 0x77, 0x41, 0x78, 0x41, 0x79, 0x41, 0x7A, 0x41, + 0x7B, 0x41, 0x7C, 0x41, 0x7D, 0x41, 0x7E, 0x42, + // Bytes c0 - ff + 0xC2, 0xA2, 0x42, 0xC2, 0xA3, 0x42, 0xC2, 0xA5, + 0x42, 0xC2, 0xA6, 0x42, 0xC2, 0xAC, 0x42, 0xC2, + 0xB7, 0x42, 0xC3, 0x86, 0x42, 0xC3, 0xB0, 0x42, + 0xC4, 0xA6, 0x42, 0xC4, 0xA7, 0x42, 0xC4, 0xB1, + 0x42, 0xC5, 0x8B, 0x42, 0xC5, 0x93, 0x42, 0xC6, + 0x8E, 0x42, 0xC6, 0x90, 0x42, 0xC6, 0xAB, 0x42, + 0xC8, 0xA2, 0x42, 0xC8, 0xB7, 0x42, 0xC9, 0x90, + 0x42, 0xC9, 0x91, 0x42, 0xC9, 0x92, 0x42, 0xC9, + // Bytes 100 - 13f + 0x94, 0x42, 0xC9, 0x95, 0x42, 0xC9, 0x99, 0x42, + 0xC9, 0x9B, 0x42, 0xC9, 0x9C, 0x42, 0xC9, 0x9F, + 0x42, 0xC9, 0xA1, 0x42, 0xC9, 0xA3, 0x42, 0xC9, + 0xA5, 0x42, 0xC9, 0xA6, 0x42, 0xC9, 0xA8, 0x42, + 0xC9, 0xA9, 0x42, 0xC9, 0xAA, 0x42, 0xC9, 0xAB, + 0x42, 0xC9, 0xAD, 0x42, 0xC9, 0xAF, 0x42, 0xC9, + 0xB0, 0x42, 0xC9, 0xB1, 0x42, 0xC9, 0xB2, 0x42, + 0xC9, 0xB3, 0x42, 0xC9, 0xB4, 0x42, 0xC9, 0xB5, + // Bytes 140 - 17f + 0x42, 0xC9, 0xB8, 0x42, 0xC9, 0xB9, 0x42, 0xC9, + 0xBB, 0x42, 0xCA, 0x81, 0x42, 0xCA, 0x82, 0x42, + 0xCA, 0x83, 0x42, 0xCA, 0x89, 0x42, 0xCA, 0x8A, + 0x42, 0xCA, 0x8B, 0x42, 0xCA, 0x8C, 0x42, 0xCA, + 0x90, 0x42, 0xCA, 0x91, 0x42, 0xCA, 0x92, 0x42, + 0xCA, 0x95, 0x42, 0xCA, 0x9D, 0x42, 0xCA, 0x9F, + 0x42, 0xCA, 0xB9, 0x42, 0xCE, 0x91, 0x42, 0xCE, + 0x92, 0x42, 0xCE, 0x93, 0x42, 0xCE, 0x94, 0x42, + // Bytes 180 - 1bf + 0xCE, 0x95, 0x42, 0xCE, 0x96, 0x42, 0xCE, 0x97, + 0x42, 0xCE, 0x98, 0x42, 0xCE, 0x99, 0x42, 0xCE, + 0x9A, 0x42, 0xCE, 0x9B, 0x42, 0xCE, 0x9C, 0x42, + 0xCE, 0x9D, 0x42, 0xCE, 0x9E, 0x42, 0xCE, 0x9F, + 0x42, 0xCE, 0xA0, 0x42, 0xCE, 0xA1, 0x42, 0xCE, + 0xA3, 0x42, 0xCE, 0xA4, 0x42, 0xCE, 0xA5, 0x42, + 0xCE, 0xA6, 0x42, 0xCE, 0xA7, 0x42, 0xCE, 0xA8, + 0x42, 0xCE, 0xA9, 0x42, 0xCE, 0xB1, 0x42, 0xCE, + // Bytes 1c0 - 1ff + 0xB2, 0x42, 0xCE, 0xB3, 0x42, 0xCE, 0xB4, 0x42, + 0xCE, 0xB5, 0x42, 0xCE, 0xB6, 0x42, 0xCE, 0xB7, + 0x42, 0xCE, 0xB8, 0x42, 0xCE, 0xB9, 0x42, 0xCE, + 0xBA, 0x42, 0xCE, 0xBB, 0x42, 0xCE, 0xBC, 0x42, + 0xCE, 0xBD, 0x42, 0xCE, 0xBE, 0x42, 0xCE, 0xBF, + 0x42, 0xCF, 0x80, 0x42, 0xCF, 0x81, 0x42, 0xCF, + 0x82, 0x42, 0xCF, 0x83, 0x42, 0xCF, 0x84, 0x42, + 0xCF, 0x85, 0x42, 0xCF, 0x86, 0x42, 0xCF, 0x87, + // Bytes 200 - 23f + 0x42, 0xCF, 0x88, 0x42, 0xCF, 0x89, 0x42, 0xCF, + 0x9C, 0x42, 0xCF, 0x9D, 0x42, 0xD0, 0xBD, 0x42, + 0xD1, 0x8A, 0x42, 0xD1, 0x8C, 0x42, 0xD7, 0x90, + 0x42, 0xD7, 0x91, 0x42, 0xD7, 0x92, 0x42, 0xD7, + 0x93, 0x42, 0xD7, 0x94, 0x42, 0xD7, 0x9B, 0x42, + 0xD7, 0x9C, 0x42, 0xD7, 0x9D, 0x42, 0xD7, 0xA2, + 0x42, 0xD7, 0xA8, 0x42, 0xD7, 0xAA, 0x42, 0xD8, + 0xA1, 0x42, 0xD8, 0xA7, 0x42, 0xD8, 0xA8, 0x42, + // Bytes 240 - 27f + 0xD8, 0xA9, 0x42, 0xD8, 0xAA, 0x42, 0xD8, 0xAB, + 0x42, 0xD8, 0xAC, 0x42, 0xD8, 0xAD, 0x42, 0xD8, + 0xAE, 0x42, 0xD8, 0xAF, 0x42, 0xD8, 0xB0, 0x42, + 0xD8, 0xB1, 0x42, 0xD8, 0xB2, 0x42, 0xD8, 0xB3, + 0x42, 0xD8, 0xB4, 0x42, 0xD8, 0xB5, 0x42, 0xD8, + 0xB6, 0x42, 0xD8, 0xB7, 0x42, 0xD8, 0xB8, 0x42, + 0xD8, 0xB9, 0x42, 0xD8, 0xBA, 0x42, 0xD9, 0x81, + 0x42, 0xD9, 0x82, 0x42, 0xD9, 0x83, 0x42, 0xD9, + // Bytes 280 - 2bf + 0x84, 0x42, 0xD9, 0x85, 0x42, 0xD9, 0x86, 0x42, + 0xD9, 0x87, 0x42, 0xD9, 0x88, 0x42, 0xD9, 0x89, + 0x42, 0xD9, 0x8A, 0x42, 0xD9, 0xAE, 0x42, 0xD9, + 0xAF, 0x42, 0xD9, 0xB1, 0x42, 0xD9, 0xB9, 0x42, + 0xD9, 0xBA, 0x42, 0xD9, 0xBB, 0x42, 0xD9, 0xBE, + 0x42, 0xD9, 0xBF, 0x42, 0xDA, 0x80, 0x42, 0xDA, + 0x83, 0x42, 0xDA, 0x84, 0x42, 0xDA, 0x86, 0x42, + 0xDA, 0x87, 0x42, 0xDA, 0x88, 0x42, 0xDA, 0x8C, + // Bytes 2c0 - 2ff + 0x42, 0xDA, 0x8D, 0x42, 0xDA, 0x8E, 0x42, 0xDA, + 0x91, 0x42, 0xDA, 0x98, 0x42, 0xDA, 0xA1, 0x42, + 0xDA, 0xA4, 0x42, 0xDA, 0xA6, 0x42, 0xDA, 0xA9, + 0x42, 0xDA, 0xAD, 0x42, 0xDA, 0xAF, 0x42, 0xDA, + 0xB1, 0x42, 0xDA, 0xB3, 0x42, 0xDA, 0xBA, 0x42, + 0xDA, 0xBB, 0x42, 0xDA, 0xBE, 0x42, 0xDB, 0x81, + 0x42, 0xDB, 0x85, 0x42, 0xDB, 0x86, 0x42, 0xDB, + 0x87, 0x42, 0xDB, 0x88, 0x42, 0xDB, 0x89, 0x42, + // Bytes 300 - 33f + 0xDB, 0x8B, 0x42, 0xDB, 0x8C, 0x42, 0xDB, 0x90, + 0x42, 0xDB, 0x92, 0x43, 0xE0, 0xBC, 0x8B, 0x43, + 0xE1, 0x83, 0x9C, 0x43, 0xE1, 0x84, 0x80, 0x43, + 0xE1, 0x84, 0x81, 0x43, 0xE1, 0x84, 0x82, 0x43, + 0xE1, 0x84, 0x83, 0x43, 0xE1, 0x84, 0x84, 0x43, + 0xE1, 0x84, 0x85, 0x43, 0xE1, 0x84, 0x86, 0x43, + 0xE1, 0x84, 0x87, 0x43, 0xE1, 0x84, 0x88, 0x43, + 0xE1, 0x84, 0x89, 0x43, 0xE1, 0x84, 0x8A, 0x43, + // Bytes 340 - 37f + 0xE1, 0x84, 0x8B, 0x43, 0xE1, 0x84, 0x8C, 0x43, + 0xE1, 0x84, 0x8D, 0x43, 0xE1, 0x84, 0x8E, 0x43, + 0xE1, 0x84, 0x8F, 0x43, 0xE1, 0x84, 0x90, 0x43, + 0xE1, 0x84, 0x91, 0x43, 0xE1, 0x84, 0x92, 0x43, + 0xE1, 0x84, 0x94, 0x43, 0xE1, 0x84, 0x95, 0x43, + 0xE1, 0x84, 0x9A, 0x43, 0xE1, 0x84, 0x9C, 0x43, + 0xE1, 0x84, 0x9D, 0x43, 0xE1, 0x84, 0x9E, 0x43, + 0xE1, 0x84, 0xA0, 0x43, 0xE1, 0x84, 0xA1, 0x43, + // Bytes 380 - 3bf + 0xE1, 0x84, 0xA2, 0x43, 0xE1, 0x84, 0xA3, 0x43, + 0xE1, 0x84, 0xA7, 0x43, 0xE1, 0x84, 0xA9, 0x43, + 0xE1, 0x84, 0xAB, 0x43, 0xE1, 0x84, 0xAC, 0x43, + 0xE1, 0x84, 0xAD, 0x43, 0xE1, 0x84, 0xAE, 0x43, + 0xE1, 0x84, 0xAF, 0x43, 0xE1, 0x84, 0xB2, 0x43, + 0xE1, 0x84, 0xB6, 0x43, 0xE1, 0x85, 0x80, 0x43, + 0xE1, 0x85, 0x87, 0x43, 0xE1, 0x85, 0x8C, 0x43, + 0xE1, 0x85, 0x97, 0x43, 0xE1, 0x85, 0x98, 0x43, + // Bytes 3c0 - 3ff + 0xE1, 0x85, 0x99, 0x43, 0xE1, 0x85, 0xA0, 0x43, + 0xE1, 0x86, 0x84, 0x43, 0xE1, 0x86, 0x85, 0x43, + 0xE1, 0x86, 0x88, 0x43, 0xE1, 0x86, 0x91, 0x43, + 0xE1, 0x86, 0x92, 0x43, 0xE1, 0x86, 0x94, 0x43, + 0xE1, 0x86, 0x9E, 0x43, 0xE1, 0x86, 0xA1, 0x43, + 0xE1, 0x87, 0x87, 0x43, 0xE1, 0x87, 0x88, 0x43, + 0xE1, 0x87, 0x8C, 0x43, 0xE1, 0x87, 0x8E, 0x43, + 0xE1, 0x87, 0x93, 0x43, 0xE1, 0x87, 0x97, 0x43, + // Bytes 400 - 43f + 0xE1, 0x87, 0x99, 0x43, 0xE1, 0x87, 0x9D, 0x43, + 0xE1, 0x87, 0x9F, 0x43, 0xE1, 0x87, 0xB1, 0x43, + 0xE1, 0x87, 0xB2, 0x43, 0xE1, 0xB4, 0x82, 0x43, + 0xE1, 0xB4, 0x96, 0x43, 0xE1, 0xB4, 0x97, 0x43, + 0xE1, 0xB4, 0x9C, 0x43, 0xE1, 0xB4, 0x9D, 0x43, + 0xE1, 0xB4, 0xA5, 0x43, 0xE1, 0xB5, 0xBB, 0x43, + 0xE1, 0xB6, 0x85, 0x43, 0xE2, 0x80, 0x82, 0x43, + 0xE2, 0x80, 0x83, 0x43, 0xE2, 0x80, 0x90, 0x43, + // Bytes 440 - 47f + 0xE2, 0x80, 0x93, 0x43, 0xE2, 0x80, 0x94, 0x43, + 0xE2, 0x82, 0xA9, 0x43, 0xE2, 0x86, 0x90, 0x43, + 0xE2, 0x86, 0x91, 0x43, 0xE2, 0x86, 0x92, 0x43, + 0xE2, 0x86, 0x93, 0x43, 0xE2, 0x88, 0x82, 0x43, + 0xE2, 0x88, 0x87, 0x43, 0xE2, 0x88, 0x91, 0x43, + 0xE2, 0x88, 0x92, 0x43, 0xE2, 0x94, 0x82, 0x43, + 0xE2, 0x96, 0xA0, 0x43, 0xE2, 0x97, 0x8B, 0x43, + 0xE2, 0xA6, 0x85, 0x43, 0xE2, 0xA6, 0x86, 0x43, + // Bytes 480 - 4bf + 0xE2, 0xB5, 0xA1, 0x43, 0xE3, 0x80, 0x81, 0x43, + 0xE3, 0x80, 0x82, 0x43, 0xE3, 0x80, 0x88, 0x43, + 0xE3, 0x80, 0x89, 0x43, 0xE3, 0x80, 0x8A, 0x43, + 0xE3, 0x80, 0x8B, 0x43, 0xE3, 0x80, 0x8C, 0x43, + 0xE3, 0x80, 0x8D, 0x43, 0xE3, 0x80, 0x8E, 0x43, + 0xE3, 0x80, 0x8F, 0x43, 0xE3, 0x80, 0x90, 0x43, + 0xE3, 0x80, 0x91, 0x43, 0xE3, 0x80, 0x92, 0x43, + 0xE3, 0x80, 0x94, 0x43, 0xE3, 0x80, 0x95, 0x43, + // Bytes 4c0 - 4ff + 0xE3, 0x80, 0x96, 0x43, 0xE3, 0x80, 0x97, 0x43, + 0xE3, 0x82, 0xA1, 0x43, 0xE3, 0x82, 0xA2, 0x43, + 0xE3, 0x82, 0xA3, 0x43, 0xE3, 0x82, 0xA4, 0x43, + 0xE3, 0x82, 0xA5, 0x43, 0xE3, 0x82, 0xA6, 0x43, + 0xE3, 0x82, 0xA7, 0x43, 0xE3, 0x82, 0xA8, 0x43, + 0xE3, 0x82, 0xA9, 0x43, 0xE3, 0x82, 0xAA, 0x43, + 0xE3, 0x82, 0xAB, 0x43, 0xE3, 0x82, 0xAD, 0x43, + 0xE3, 0x82, 0xAF, 0x43, 0xE3, 0x82, 0xB1, 0x43, + // Bytes 500 - 53f + 0xE3, 0x82, 0xB3, 0x43, 0xE3, 0x82, 0xB5, 0x43, + 0xE3, 0x82, 0xB7, 0x43, 0xE3, 0x82, 0xB9, 0x43, + 0xE3, 0x82, 0xBB, 0x43, 0xE3, 0x82, 0xBD, 0x43, + 0xE3, 0x82, 0xBF, 0x43, 0xE3, 0x83, 0x81, 0x43, + 0xE3, 0x83, 0x83, 0x43, 0xE3, 0x83, 0x84, 0x43, + 0xE3, 0x83, 0x86, 0x43, 0xE3, 0x83, 0x88, 0x43, + 0xE3, 0x83, 0x8A, 0x43, 0xE3, 0x83, 0x8B, 0x43, + 0xE3, 0x83, 0x8C, 0x43, 0xE3, 0x83, 0x8D, 0x43, + // Bytes 540 - 57f + 0xE3, 0x83, 0x8E, 0x43, 0xE3, 0x83, 0x8F, 0x43, + 0xE3, 0x83, 0x92, 0x43, 0xE3, 0x83, 0x95, 0x43, + 0xE3, 0x83, 0x98, 0x43, 0xE3, 0x83, 0x9B, 0x43, + 0xE3, 0x83, 0x9E, 0x43, 0xE3, 0x83, 0x9F, 0x43, + 0xE3, 0x83, 0xA0, 0x43, 0xE3, 0x83, 0xA1, 0x43, + 0xE3, 0x83, 0xA2, 0x43, 0xE3, 0x83, 0xA3, 0x43, + 0xE3, 0x83, 0xA4, 0x43, 0xE3, 0x83, 0xA5, 0x43, + 0xE3, 0x83, 0xA6, 0x43, 0xE3, 0x83, 0xA7, 0x43, + // Bytes 580 - 5bf + 0xE3, 0x83, 0xA8, 0x43, 0xE3, 0x83, 0xA9, 0x43, + 0xE3, 0x83, 0xAA, 0x43, 0xE3, 0x83, 0xAB, 0x43, + 0xE3, 0x83, 0xAC, 0x43, 0xE3, 0x83, 0xAD, 0x43, + 0xE3, 0x83, 0xAF, 0x43, 0xE3, 0x83, 0xB0, 0x43, + 0xE3, 0x83, 0xB1, 0x43, 0xE3, 0x83, 0xB2, 0x43, + 0xE3, 0x83, 0xB3, 0x43, 0xE3, 0x83, 0xBB, 0x43, + 0xE3, 0x83, 0xBC, 0x43, 0xE3, 0x92, 0x9E, 0x43, + 0xE3, 0x92, 0xB9, 0x43, 0xE3, 0x92, 0xBB, 0x43, + // Bytes 5c0 - 5ff + 0xE3, 0x93, 0x9F, 0x43, 0xE3, 0x94, 0x95, 0x43, + 0xE3, 0x9B, 0xAE, 0x43, 0xE3, 0x9B, 0xBC, 0x43, + 0xE3, 0x9E, 0x81, 0x43, 0xE3, 0xA0, 0xAF, 0x43, + 0xE3, 0xA1, 0xA2, 0x43, 0xE3, 0xA1, 0xBC, 0x43, + 0xE3, 0xA3, 0x87, 0x43, 0xE3, 0xA3, 0xA3, 0x43, + 0xE3, 0xA4, 0x9C, 0x43, 0xE3, 0xA4, 0xBA, 0x43, + 0xE3, 0xA8, 0xAE, 0x43, 0xE3, 0xA9, 0xAC, 0x43, + 0xE3, 0xAB, 0xA4, 0x43, 0xE3, 0xAC, 0x88, 0x43, + // Bytes 600 - 63f + 0xE3, 0xAC, 0x99, 0x43, 0xE3, 0xAD, 0x89, 0x43, + 0xE3, 0xAE, 0x9D, 0x43, 0xE3, 0xB0, 0x98, 0x43, + 0xE3, 0xB1, 0x8E, 0x43, 0xE3, 0xB4, 0xB3, 0x43, + 0xE3, 0xB6, 0x96, 0x43, 0xE3, 0xBA, 0xAC, 0x43, + 0xE3, 0xBA, 0xB8, 0x43, 0xE3, 0xBC, 0x9B, 0x43, + 0xE3, 0xBF, 0xBC, 0x43, 0xE4, 0x80, 0x88, 0x43, + 0xE4, 0x80, 0x98, 0x43, 0xE4, 0x80, 0xB9, 0x43, + 0xE4, 0x81, 0x86, 0x43, 0xE4, 0x82, 0x96, 0x43, + // Bytes 640 - 67f + 0xE4, 0x83, 0xA3, 0x43, 0xE4, 0x84, 0xAF, 0x43, + 0xE4, 0x88, 0x82, 0x43, 0xE4, 0x88, 0xA7, 0x43, + 0xE4, 0x8A, 0xA0, 0x43, 0xE4, 0x8C, 0x81, 0x43, + 0xE4, 0x8C, 0xB4, 0x43, 0xE4, 0x8D, 0x99, 0x43, + 0xE4, 0x8F, 0x95, 0x43, 0xE4, 0x8F, 0x99, 0x43, + 0xE4, 0x90, 0x8B, 0x43, 0xE4, 0x91, 0xAB, 0x43, + 0xE4, 0x94, 0xAB, 0x43, 0xE4, 0x95, 0x9D, 0x43, + 0xE4, 0x95, 0xA1, 0x43, 0xE4, 0x95, 0xAB, 0x43, + // Bytes 680 - 6bf + 0xE4, 0x97, 0x97, 0x43, 0xE4, 0x97, 0xB9, 0x43, + 0xE4, 0x98, 0xB5, 0x43, 0xE4, 0x9A, 0xBE, 0x43, + 0xE4, 0x9B, 0x87, 0x43, 0xE4, 0xA6, 0x95, 0x43, + 0xE4, 0xA7, 0xA6, 0x43, 0xE4, 0xA9, 0xAE, 0x43, + 0xE4, 0xA9, 0xB6, 0x43, 0xE4, 0xAA, 0xB2, 0x43, + 0xE4, 0xAC, 0xB3, 0x43, 0xE4, 0xAF, 0x8E, 0x43, + 0xE4, 0xB3, 0x8E, 0x43, 0xE4, 0xB3, 0xAD, 0x43, + 0xE4, 0xB3, 0xB8, 0x43, 0xE4, 0xB5, 0x96, 0x43, + // Bytes 6c0 - 6ff + 0xE4, 0xB8, 0x80, 0x43, 0xE4, 0xB8, 0x81, 0x43, + 0xE4, 0xB8, 0x83, 0x43, 0xE4, 0xB8, 0x89, 0x43, + 0xE4, 0xB8, 0x8A, 0x43, 0xE4, 0xB8, 0x8B, 0x43, + 0xE4, 0xB8, 0x8D, 0x43, 0xE4, 0xB8, 0x99, 0x43, + 0xE4, 0xB8, 0xA6, 0x43, 0xE4, 0xB8, 0xA8, 0x43, + 0xE4, 0xB8, 0xAD, 0x43, 0xE4, 0xB8, 0xB2, 0x43, + 0xE4, 0xB8, 0xB6, 0x43, 0xE4, 0xB8, 0xB8, 0x43, + 0xE4, 0xB8, 0xB9, 0x43, 0xE4, 0xB8, 0xBD, 0x43, + // Bytes 700 - 73f + 0xE4, 0xB8, 0xBF, 0x43, 0xE4, 0xB9, 0x81, 0x43, + 0xE4, 0xB9, 0x99, 0x43, 0xE4, 0xB9, 0x9D, 0x43, + 0xE4, 0xBA, 0x82, 0x43, 0xE4, 0xBA, 0x85, 0x43, + 0xE4, 0xBA, 0x86, 0x43, 0xE4, 0xBA, 0x8C, 0x43, + 0xE4, 0xBA, 0x94, 0x43, 0xE4, 0xBA, 0xA0, 0x43, + 0xE4, 0xBA, 0xA4, 0x43, 0xE4, 0xBA, 0xAE, 0x43, + 0xE4, 0xBA, 0xBA, 0x43, 0xE4, 0xBB, 0x80, 0x43, + 0xE4, 0xBB, 0x8C, 0x43, 0xE4, 0xBB, 0xA4, 0x43, + // Bytes 740 - 77f + 0xE4, 0xBC, 0x81, 0x43, 0xE4, 0xBC, 0x91, 0x43, + 0xE4, 0xBD, 0xA0, 0x43, 0xE4, 0xBE, 0x80, 0x43, + 0xE4, 0xBE, 0x86, 0x43, 0xE4, 0xBE, 0x8B, 0x43, + 0xE4, 0xBE, 0xAE, 0x43, 0xE4, 0xBE, 0xBB, 0x43, + 0xE4, 0xBE, 0xBF, 0x43, 0xE5, 0x80, 0x82, 0x43, + 0xE5, 0x80, 0xAB, 0x43, 0xE5, 0x81, 0xBA, 0x43, + 0xE5, 0x82, 0x99, 0x43, 0xE5, 0x83, 0x8F, 0x43, + 0xE5, 0x83, 0x9A, 0x43, 0xE5, 0x83, 0xA7, 0x43, + // Bytes 780 - 7bf + 0xE5, 0x84, 0xAA, 0x43, 0xE5, 0x84, 0xBF, 0x43, + 0xE5, 0x85, 0x80, 0x43, 0xE5, 0x85, 0x85, 0x43, + 0xE5, 0x85, 0x8D, 0x43, 0xE5, 0x85, 0x94, 0x43, + 0xE5, 0x85, 0xA4, 0x43, 0xE5, 0x85, 0xA5, 0x43, + 0xE5, 0x85, 0xA7, 0x43, 0xE5, 0x85, 0xA8, 0x43, + 0xE5, 0x85, 0xA9, 0x43, 0xE5, 0x85, 0xAB, 0x43, + 0xE5, 0x85, 0xAD, 0x43, 0xE5, 0x85, 0xB7, 0x43, + 0xE5, 0x86, 0x80, 0x43, 0xE5, 0x86, 0x82, 0x43, + // Bytes 7c0 - 7ff + 0xE5, 0x86, 0x8D, 0x43, 0xE5, 0x86, 0x92, 0x43, + 0xE5, 0x86, 0x95, 0x43, 0xE5, 0x86, 0x96, 0x43, + 0xE5, 0x86, 0x97, 0x43, 0xE5, 0x86, 0x99, 0x43, + 0xE5, 0x86, 0xA4, 0x43, 0xE5, 0x86, 0xAB, 0x43, + 0xE5, 0x86, 0xAC, 0x43, 0xE5, 0x86, 0xB5, 0x43, + 0xE5, 0x86, 0xB7, 0x43, 0xE5, 0x87, 0x89, 0x43, + 0xE5, 0x87, 0x8C, 0x43, 0xE5, 0x87, 0x9C, 0x43, + 0xE5, 0x87, 0x9E, 0x43, 0xE5, 0x87, 0xA0, 0x43, + // Bytes 800 - 83f + 0xE5, 0x87, 0xB5, 0x43, 0xE5, 0x88, 0x80, 0x43, + 0xE5, 0x88, 0x83, 0x43, 0xE5, 0x88, 0x87, 0x43, + 0xE5, 0x88, 0x97, 0x43, 0xE5, 0x88, 0x9D, 0x43, + 0xE5, 0x88, 0xA9, 0x43, 0xE5, 0x88, 0xBA, 0x43, + 0xE5, 0x88, 0xBB, 0x43, 0xE5, 0x89, 0x86, 0x43, + 0xE5, 0x89, 0x8D, 0x43, 0xE5, 0x89, 0xB2, 0x43, + 0xE5, 0x89, 0xB7, 0x43, 0xE5, 0x8A, 0x89, 0x43, + 0xE5, 0x8A, 0x9B, 0x43, 0xE5, 0x8A, 0xA3, 0x43, + // Bytes 840 - 87f + 0xE5, 0x8A, 0xB3, 0x43, 0xE5, 0x8A, 0xB4, 0x43, + 0xE5, 0x8B, 0x87, 0x43, 0xE5, 0x8B, 0x89, 0x43, + 0xE5, 0x8B, 0x92, 0x43, 0xE5, 0x8B, 0x9E, 0x43, + 0xE5, 0x8B, 0xA4, 0x43, 0xE5, 0x8B, 0xB5, 0x43, + 0xE5, 0x8B, 0xB9, 0x43, 0xE5, 0x8B, 0xBA, 0x43, + 0xE5, 0x8C, 0x85, 0x43, 0xE5, 0x8C, 0x86, 0x43, + 0xE5, 0x8C, 0x95, 0x43, 0xE5, 0x8C, 0x97, 0x43, + 0xE5, 0x8C, 0x9A, 0x43, 0xE5, 0x8C, 0xB8, 0x43, + // Bytes 880 - 8bf + 0xE5, 0x8C, 0xBB, 0x43, 0xE5, 0x8C, 0xBF, 0x43, + 0xE5, 0x8D, 0x81, 0x43, 0xE5, 0x8D, 0x84, 0x43, + 0xE5, 0x8D, 0x85, 0x43, 0xE5, 0x8D, 0x89, 0x43, + 0xE5, 0x8D, 0x91, 0x43, 0xE5, 0x8D, 0x94, 0x43, + 0xE5, 0x8D, 0x9A, 0x43, 0xE5, 0x8D, 0x9C, 0x43, + 0xE5, 0x8D, 0xA9, 0x43, 0xE5, 0x8D, 0xB0, 0x43, + 0xE5, 0x8D, 0xB3, 0x43, 0xE5, 0x8D, 0xB5, 0x43, + 0xE5, 0x8D, 0xBD, 0x43, 0xE5, 0x8D, 0xBF, 0x43, + // Bytes 8c0 - 8ff + 0xE5, 0x8E, 0x82, 0x43, 0xE5, 0x8E, 0xB6, 0x43, + 0xE5, 0x8F, 0x83, 0x43, 0xE5, 0x8F, 0x88, 0x43, + 0xE5, 0x8F, 0x8A, 0x43, 0xE5, 0x8F, 0x8C, 0x43, + 0xE5, 0x8F, 0x9F, 0x43, 0xE5, 0x8F, 0xA3, 0x43, + 0xE5, 0x8F, 0xA5, 0x43, 0xE5, 0x8F, 0xAB, 0x43, + 0xE5, 0x8F, 0xAF, 0x43, 0xE5, 0x8F, 0xB1, 0x43, + 0xE5, 0x8F, 0xB3, 0x43, 0xE5, 0x90, 0x86, 0x43, + 0xE5, 0x90, 0x88, 0x43, 0xE5, 0x90, 0x8D, 0x43, + // Bytes 900 - 93f + 0xE5, 0x90, 0x8F, 0x43, 0xE5, 0x90, 0x9D, 0x43, + 0xE5, 0x90, 0xB8, 0x43, 0xE5, 0x90, 0xB9, 0x43, + 0xE5, 0x91, 0x82, 0x43, 0xE5, 0x91, 0x88, 0x43, + 0xE5, 0x91, 0xA8, 0x43, 0xE5, 0x92, 0x9E, 0x43, + 0xE5, 0x92, 0xA2, 0x43, 0xE5, 0x92, 0xBD, 0x43, + 0xE5, 0x93, 0xB6, 0x43, 0xE5, 0x94, 0x90, 0x43, + 0xE5, 0x95, 0x8F, 0x43, 0xE5, 0x95, 0x93, 0x43, + 0xE5, 0x95, 0x95, 0x43, 0xE5, 0x95, 0xA3, 0x43, + // Bytes 940 - 97f + 0xE5, 0x96, 0x84, 0x43, 0xE5, 0x96, 0x87, 0x43, + 0xE5, 0x96, 0x99, 0x43, 0xE5, 0x96, 0x9D, 0x43, + 0xE5, 0x96, 0xAB, 0x43, 0xE5, 0x96, 0xB3, 0x43, + 0xE5, 0x96, 0xB6, 0x43, 0xE5, 0x97, 0x80, 0x43, + 0xE5, 0x97, 0x82, 0x43, 0xE5, 0x97, 0xA2, 0x43, + 0xE5, 0x98, 0x86, 0x43, 0xE5, 0x99, 0x91, 0x43, + 0xE5, 0x99, 0xA8, 0x43, 0xE5, 0x99, 0xB4, 0x43, + 0xE5, 0x9B, 0x97, 0x43, 0xE5, 0x9B, 0x9B, 0x43, + // Bytes 980 - 9bf + 0xE5, 0x9B, 0xB9, 0x43, 0xE5, 0x9C, 0x96, 0x43, + 0xE5, 0x9C, 0x97, 0x43, 0xE5, 0x9C, 0x9F, 0x43, + 0xE5, 0x9C, 0xB0, 0x43, 0xE5, 0x9E, 0x8B, 0x43, + 0xE5, 0x9F, 0x8E, 0x43, 0xE5, 0x9F, 0xB4, 0x43, + 0xE5, 0xA0, 0x8D, 0x43, 0xE5, 0xA0, 0xB1, 0x43, + 0xE5, 0xA0, 0xB2, 0x43, 0xE5, 0xA1, 0x80, 0x43, + 0xE5, 0xA1, 0x9A, 0x43, 0xE5, 0xA1, 0x9E, 0x43, + 0xE5, 0xA2, 0xA8, 0x43, 0xE5, 0xA2, 0xAC, 0x43, + // Bytes 9c0 - 9ff + 0xE5, 0xA2, 0xB3, 0x43, 0xE5, 0xA3, 0x98, 0x43, + 0xE5, 0xA3, 0x9F, 0x43, 0xE5, 0xA3, 0xAB, 0x43, + 0xE5, 0xA3, 0xAE, 0x43, 0xE5, 0xA3, 0xB0, 0x43, + 0xE5, 0xA3, 0xB2, 0x43, 0xE5, 0xA3, 0xB7, 0x43, + 0xE5, 0xA4, 0x82, 0x43, 0xE5, 0xA4, 0x86, 0x43, + 0xE5, 0xA4, 0x8A, 0x43, 0xE5, 0xA4, 0x95, 0x43, + 0xE5, 0xA4, 0x9A, 0x43, 0xE5, 0xA4, 0x9C, 0x43, + 0xE5, 0xA4, 0xA2, 0x43, 0xE5, 0xA4, 0xA7, 0x43, + // Bytes a00 - a3f + 0xE5, 0xA4, 0xA9, 0x43, 0xE5, 0xA5, 0x84, 0x43, + 0xE5, 0xA5, 0x88, 0x43, 0xE5, 0xA5, 0x91, 0x43, + 0xE5, 0xA5, 0x94, 0x43, 0xE5, 0xA5, 0xA2, 0x43, + 0xE5, 0xA5, 0xB3, 0x43, 0xE5, 0xA7, 0x98, 0x43, + 0xE5, 0xA7, 0xAC, 0x43, 0xE5, 0xA8, 0x9B, 0x43, + 0xE5, 0xA8, 0xA7, 0x43, 0xE5, 0xA9, 0xA2, 0x43, + 0xE5, 0xA9, 0xA6, 0x43, 0xE5, 0xAA, 0xB5, 0x43, + 0xE5, 0xAC, 0x88, 0x43, 0xE5, 0xAC, 0xA8, 0x43, + // Bytes a40 - a7f + 0xE5, 0xAC, 0xBE, 0x43, 0xE5, 0xAD, 0x90, 0x43, + 0xE5, 0xAD, 0x97, 0x43, 0xE5, 0xAD, 0xA6, 0x43, + 0xE5, 0xAE, 0x80, 0x43, 0xE5, 0xAE, 0x85, 0x43, + 0xE5, 0xAE, 0x97, 0x43, 0xE5, 0xAF, 0x83, 0x43, + 0xE5, 0xAF, 0x98, 0x43, 0xE5, 0xAF, 0xA7, 0x43, + 0xE5, 0xAF, 0xAE, 0x43, 0xE5, 0xAF, 0xB3, 0x43, + 0xE5, 0xAF, 0xB8, 0x43, 0xE5, 0xAF, 0xBF, 0x43, + 0xE5, 0xB0, 0x86, 0x43, 0xE5, 0xB0, 0x8F, 0x43, + // Bytes a80 - abf + 0xE5, 0xB0, 0xA2, 0x43, 0xE5, 0xB0, 0xB8, 0x43, + 0xE5, 0xB0, 0xBF, 0x43, 0xE5, 0xB1, 0xA0, 0x43, + 0xE5, 0xB1, 0xA2, 0x43, 0xE5, 0xB1, 0xA4, 0x43, + 0xE5, 0xB1, 0xA5, 0x43, 0xE5, 0xB1, 0xAE, 0x43, + 0xE5, 0xB1, 0xB1, 0x43, 0xE5, 0xB2, 0x8D, 0x43, + 0xE5, 0xB3, 0x80, 0x43, 0xE5, 0xB4, 0x99, 0x43, + 0xE5, 0xB5, 0x83, 0x43, 0xE5, 0xB5, 0x90, 0x43, + 0xE5, 0xB5, 0xAB, 0x43, 0xE5, 0xB5, 0xAE, 0x43, + // Bytes ac0 - aff + 0xE5, 0xB5, 0xBC, 0x43, 0xE5, 0xB6, 0xB2, 0x43, + 0xE5, 0xB6, 0xBA, 0x43, 0xE5, 0xB7, 0x9B, 0x43, + 0xE5, 0xB7, 0xA1, 0x43, 0xE5, 0xB7, 0xA2, 0x43, + 0xE5, 0xB7, 0xA5, 0x43, 0xE5, 0xB7, 0xA6, 0x43, + 0xE5, 0xB7, 0xB1, 0x43, 0xE5, 0xB7, 0xBD, 0x43, + 0xE5, 0xB7, 0xBE, 0x43, 0xE5, 0xB8, 0xA8, 0x43, + 0xE5, 0xB8, 0xBD, 0x43, 0xE5, 0xB9, 0xA9, 0x43, + 0xE5, 0xB9, 0xB2, 0x43, 0xE5, 0xB9, 0xB4, 0x43, + // Bytes b00 - b3f + 0xE5, 0xB9, 0xBA, 0x43, 0xE5, 0xB9, 0xBC, 0x43, + 0xE5, 0xB9, 0xBF, 0x43, 0xE5, 0xBA, 0xA6, 0x43, + 0xE5, 0xBA, 0xB0, 0x43, 0xE5, 0xBA, 0xB3, 0x43, + 0xE5, 0xBA, 0xB6, 0x43, 0xE5, 0xBB, 0x89, 0x43, + 0xE5, 0xBB, 0x8A, 0x43, 0xE5, 0xBB, 0x92, 0x43, + 0xE5, 0xBB, 0x93, 0x43, 0xE5, 0xBB, 0x99, 0x43, + 0xE5, 0xBB, 0xAC, 0x43, 0xE5, 0xBB, 0xB4, 0x43, + 0xE5, 0xBB, 0xBE, 0x43, 0xE5, 0xBC, 0x84, 0x43, + // Bytes b40 - b7f + 0xE5, 0xBC, 0x8B, 0x43, 0xE5, 0xBC, 0x93, 0x43, + 0xE5, 0xBC, 0xA2, 0x43, 0xE5, 0xBD, 0x90, 0x43, + 0xE5, 0xBD, 0x93, 0x43, 0xE5, 0xBD, 0xA1, 0x43, + 0xE5, 0xBD, 0xA2, 0x43, 0xE5, 0xBD, 0xA9, 0x43, + 0xE5, 0xBD, 0xAB, 0x43, 0xE5, 0xBD, 0xB3, 0x43, + 0xE5, 0xBE, 0x8B, 0x43, 0xE5, 0xBE, 0x8C, 0x43, + 0xE5, 0xBE, 0x97, 0x43, 0xE5, 0xBE, 0x9A, 0x43, + 0xE5, 0xBE, 0xA9, 0x43, 0xE5, 0xBE, 0xAD, 0x43, + // Bytes b80 - bbf + 0xE5, 0xBF, 0x83, 0x43, 0xE5, 0xBF, 0x8D, 0x43, + 0xE5, 0xBF, 0x97, 0x43, 0xE5, 0xBF, 0xB5, 0x43, + 0xE5, 0xBF, 0xB9, 0x43, 0xE6, 0x80, 0x92, 0x43, + 0xE6, 0x80, 0x9C, 0x43, 0xE6, 0x81, 0xB5, 0x43, + 0xE6, 0x82, 0x81, 0x43, 0xE6, 0x82, 0x94, 0x43, + 0xE6, 0x83, 0x87, 0x43, 0xE6, 0x83, 0x98, 0x43, + 0xE6, 0x83, 0xA1, 0x43, 0xE6, 0x84, 0x88, 0x43, + 0xE6, 0x85, 0x84, 0x43, 0xE6, 0x85, 0x88, 0x43, + // Bytes bc0 - bff + 0xE6, 0x85, 0x8C, 0x43, 0xE6, 0x85, 0x8E, 0x43, + 0xE6, 0x85, 0xA0, 0x43, 0xE6, 0x85, 0xA8, 0x43, + 0xE6, 0x85, 0xBA, 0x43, 0xE6, 0x86, 0x8E, 0x43, + 0xE6, 0x86, 0x90, 0x43, 0xE6, 0x86, 0xA4, 0x43, + 0xE6, 0x86, 0xAF, 0x43, 0xE6, 0x86, 0xB2, 0x43, + 0xE6, 0x87, 0x9E, 0x43, 0xE6, 0x87, 0xB2, 0x43, + 0xE6, 0x87, 0xB6, 0x43, 0xE6, 0x88, 0x80, 0x43, + 0xE6, 0x88, 0x88, 0x43, 0xE6, 0x88, 0x90, 0x43, + // Bytes c00 - c3f + 0xE6, 0x88, 0x9B, 0x43, 0xE6, 0x88, 0xAE, 0x43, + 0xE6, 0x88, 0xB4, 0x43, 0xE6, 0x88, 0xB6, 0x43, + 0xE6, 0x89, 0x8B, 0x43, 0xE6, 0x89, 0x93, 0x43, + 0xE6, 0x89, 0x9D, 0x43, 0xE6, 0x8A, 0x95, 0x43, + 0xE6, 0x8A, 0xB1, 0x43, 0xE6, 0x8B, 0x89, 0x43, + 0xE6, 0x8B, 0x8F, 0x43, 0xE6, 0x8B, 0x93, 0x43, + 0xE6, 0x8B, 0x94, 0x43, 0xE6, 0x8B, 0xBC, 0x43, + 0xE6, 0x8B, 0xBE, 0x43, 0xE6, 0x8C, 0x87, 0x43, + // Bytes c40 - c7f + 0xE6, 0x8C, 0xBD, 0x43, 0xE6, 0x8D, 0x90, 0x43, + 0xE6, 0x8D, 0x95, 0x43, 0xE6, 0x8D, 0xA8, 0x43, + 0xE6, 0x8D, 0xBB, 0x43, 0xE6, 0x8E, 0x83, 0x43, + 0xE6, 0x8E, 0xA0, 0x43, 0xE6, 0x8E, 0xA9, 0x43, + 0xE6, 0x8F, 0x84, 0x43, 0xE6, 0x8F, 0x85, 0x43, + 0xE6, 0x8F, 0xA4, 0x43, 0xE6, 0x90, 0x9C, 0x43, + 0xE6, 0x90, 0xA2, 0x43, 0xE6, 0x91, 0x92, 0x43, + 0xE6, 0x91, 0xA9, 0x43, 0xE6, 0x91, 0xB7, 0x43, + // Bytes c80 - cbf + 0xE6, 0x91, 0xBE, 0x43, 0xE6, 0x92, 0x9A, 0x43, + 0xE6, 0x92, 0x9D, 0x43, 0xE6, 0x93, 0x84, 0x43, + 0xE6, 0x94, 0xAF, 0x43, 0xE6, 0x94, 0xB4, 0x43, + 0xE6, 0x95, 0x8F, 0x43, 0xE6, 0x95, 0x96, 0x43, + 0xE6, 0x95, 0xAC, 0x43, 0xE6, 0x95, 0xB8, 0x43, + 0xE6, 0x96, 0x87, 0x43, 0xE6, 0x96, 0x97, 0x43, + 0xE6, 0x96, 0x99, 0x43, 0xE6, 0x96, 0xA4, 0x43, + 0xE6, 0x96, 0xB0, 0x43, 0xE6, 0x96, 0xB9, 0x43, + // Bytes cc0 - cff + 0xE6, 0x97, 0x85, 0x43, 0xE6, 0x97, 0xA0, 0x43, + 0xE6, 0x97, 0xA2, 0x43, 0xE6, 0x97, 0xA3, 0x43, + 0xE6, 0x97, 0xA5, 0x43, 0xE6, 0x98, 0x93, 0x43, + 0xE6, 0x98, 0xA0, 0x43, 0xE6, 0x99, 0x89, 0x43, + 0xE6, 0x99, 0xB4, 0x43, 0xE6, 0x9A, 0x88, 0x43, + 0xE6, 0x9A, 0x91, 0x43, 0xE6, 0x9A, 0x9C, 0x43, + 0xE6, 0x9A, 0xB4, 0x43, 0xE6, 0x9B, 0x86, 0x43, + 0xE6, 0x9B, 0xB0, 0x43, 0xE6, 0x9B, 0xB4, 0x43, + // Bytes d00 - d3f + 0xE6, 0x9B, 0xB8, 0x43, 0xE6, 0x9C, 0x80, 0x43, + 0xE6, 0x9C, 0x88, 0x43, 0xE6, 0x9C, 0x89, 0x43, + 0xE6, 0x9C, 0x97, 0x43, 0xE6, 0x9C, 0x9B, 0x43, + 0xE6, 0x9C, 0xA1, 0x43, 0xE6, 0x9C, 0xA8, 0x43, + 0xE6, 0x9D, 0x8E, 0x43, 0xE6, 0x9D, 0x93, 0x43, + 0xE6, 0x9D, 0x96, 0x43, 0xE6, 0x9D, 0x9E, 0x43, + 0xE6, 0x9D, 0xBB, 0x43, 0xE6, 0x9E, 0x85, 0x43, + 0xE6, 0x9E, 0x97, 0x43, 0xE6, 0x9F, 0xB3, 0x43, + // Bytes d40 - d7f + 0xE6, 0x9F, 0xBA, 0x43, 0xE6, 0xA0, 0x97, 0x43, + 0xE6, 0xA0, 0x9F, 0x43, 0xE6, 0xA0, 0xAA, 0x43, + 0xE6, 0xA1, 0x92, 0x43, 0xE6, 0xA2, 0x81, 0x43, + 0xE6, 0xA2, 0x85, 0x43, 0xE6, 0xA2, 0x8E, 0x43, + 0xE6, 0xA2, 0xA8, 0x43, 0xE6, 0xA4, 0x94, 0x43, + 0xE6, 0xA5, 0x82, 0x43, 0xE6, 0xA6, 0xA3, 0x43, + 0xE6, 0xA7, 0xAA, 0x43, 0xE6, 0xA8, 0x82, 0x43, + 0xE6, 0xA8, 0x93, 0x43, 0xE6, 0xAA, 0xA8, 0x43, + // Bytes d80 - dbf + 0xE6, 0xAB, 0x93, 0x43, 0xE6, 0xAB, 0x9B, 0x43, + 0xE6, 0xAC, 0x84, 0x43, 0xE6, 0xAC, 0xA0, 0x43, + 0xE6, 0xAC, 0xA1, 0x43, 0xE6, 0xAD, 0x94, 0x43, + 0xE6, 0xAD, 0xA2, 0x43, 0xE6, 0xAD, 0xA3, 0x43, + 0xE6, 0xAD, 0xB2, 0x43, 0xE6, 0xAD, 0xB7, 0x43, + 0xE6, 0xAD, 0xB9, 0x43, 0xE6, 0xAE, 0x9F, 0x43, + 0xE6, 0xAE, 0xAE, 0x43, 0xE6, 0xAE, 0xB3, 0x43, + 0xE6, 0xAE, 0xBA, 0x43, 0xE6, 0xAE, 0xBB, 0x43, + // Bytes dc0 - dff + 0xE6, 0xAF, 0x8B, 0x43, 0xE6, 0xAF, 0x8D, 0x43, + 0xE6, 0xAF, 0x94, 0x43, 0xE6, 0xAF, 0x9B, 0x43, + 0xE6, 0xB0, 0x8F, 0x43, 0xE6, 0xB0, 0x94, 0x43, + 0xE6, 0xB0, 0xB4, 0x43, 0xE6, 0xB1, 0x8E, 0x43, + 0xE6, 0xB1, 0xA7, 0x43, 0xE6, 0xB2, 0x88, 0x43, + 0xE6, 0xB2, 0xBF, 0x43, 0xE6, 0xB3, 0x8C, 0x43, + 0xE6, 0xB3, 0x8D, 0x43, 0xE6, 0xB3, 0xA5, 0x43, + 0xE6, 0xB3, 0xA8, 0x43, 0xE6, 0xB4, 0x96, 0x43, + // Bytes e00 - e3f + 0xE6, 0xB4, 0x9B, 0x43, 0xE6, 0xB4, 0x9E, 0x43, + 0xE6, 0xB4, 0xB4, 0x43, 0xE6, 0xB4, 0xBE, 0x43, + 0xE6, 0xB5, 0x81, 0x43, 0xE6, 0xB5, 0xA9, 0x43, + 0xE6, 0xB5, 0xAA, 0x43, 0xE6, 0xB5, 0xB7, 0x43, + 0xE6, 0xB5, 0xB8, 0x43, 0xE6, 0xB6, 0x85, 0x43, + 0xE6, 0xB7, 0x8B, 0x43, 0xE6, 0xB7, 0x9A, 0x43, + 0xE6, 0xB7, 0xAA, 0x43, 0xE6, 0xB7, 0xB9, 0x43, + 0xE6, 0xB8, 0x9A, 0x43, 0xE6, 0xB8, 0xAF, 0x43, + // Bytes e40 - e7f + 0xE6, 0xB9, 0xAE, 0x43, 0xE6, 0xBA, 0x80, 0x43, + 0xE6, 0xBA, 0x9C, 0x43, 0xE6, 0xBA, 0xBA, 0x43, + 0xE6, 0xBB, 0x87, 0x43, 0xE6, 0xBB, 0x8B, 0x43, + 0xE6, 0xBB, 0x91, 0x43, 0xE6, 0xBB, 0x9B, 0x43, + 0xE6, 0xBC, 0x8F, 0x43, 0xE6, 0xBC, 0x94, 0x43, + 0xE6, 0xBC, 0xA2, 0x43, 0xE6, 0xBC, 0xA3, 0x43, + 0xE6, 0xBD, 0xAE, 0x43, 0xE6, 0xBF, 0x86, 0x43, + 0xE6, 0xBF, 0xAB, 0x43, 0xE6, 0xBF, 0xBE, 0x43, + // Bytes e80 - ebf + 0xE7, 0x80, 0x9B, 0x43, 0xE7, 0x80, 0x9E, 0x43, + 0xE7, 0x80, 0xB9, 0x43, 0xE7, 0x81, 0x8A, 0x43, + 0xE7, 0x81, 0xAB, 0x43, 0xE7, 0x81, 0xB0, 0x43, + 0xE7, 0x81, 0xB7, 0x43, 0xE7, 0x81, 0xBD, 0x43, + 0xE7, 0x82, 0x99, 0x43, 0xE7, 0x82, 0xAD, 0x43, + 0xE7, 0x83, 0x88, 0x43, 0xE7, 0x83, 0x99, 0x43, + 0xE7, 0x84, 0xA1, 0x43, 0xE7, 0x85, 0x85, 0x43, + 0xE7, 0x85, 0x89, 0x43, 0xE7, 0x85, 0xAE, 0x43, + // Bytes ec0 - eff + 0xE7, 0x86, 0x9C, 0x43, 0xE7, 0x87, 0x8E, 0x43, + 0xE7, 0x87, 0x90, 0x43, 0xE7, 0x88, 0x90, 0x43, + 0xE7, 0x88, 0x9B, 0x43, 0xE7, 0x88, 0xA8, 0x43, + 0xE7, 0x88, 0xAA, 0x43, 0xE7, 0x88, 0xAB, 0x43, + 0xE7, 0x88, 0xB5, 0x43, 0xE7, 0x88, 0xB6, 0x43, + 0xE7, 0x88, 0xBB, 0x43, 0xE7, 0x88, 0xBF, 0x43, + 0xE7, 0x89, 0x87, 0x43, 0xE7, 0x89, 0x90, 0x43, + 0xE7, 0x89, 0x99, 0x43, 0xE7, 0x89, 0x9B, 0x43, + // Bytes f00 - f3f + 0xE7, 0x89, 0xA2, 0x43, 0xE7, 0x89, 0xB9, 0x43, + 0xE7, 0x8A, 0x80, 0x43, 0xE7, 0x8A, 0x95, 0x43, + 0xE7, 0x8A, 0xAC, 0x43, 0xE7, 0x8A, 0xAF, 0x43, + 0xE7, 0x8B, 0x80, 0x43, 0xE7, 0x8B, 0xBC, 0x43, + 0xE7, 0x8C, 0xAA, 0x43, 0xE7, 0x8D, 0xB5, 0x43, + 0xE7, 0x8D, 0xBA, 0x43, 0xE7, 0x8E, 0x84, 0x43, + 0xE7, 0x8E, 0x87, 0x43, 0xE7, 0x8E, 0x89, 0x43, + 0xE7, 0x8E, 0x8B, 0x43, 0xE7, 0x8E, 0xA5, 0x43, + // Bytes f40 - f7f + 0xE7, 0x8E, 0xB2, 0x43, 0xE7, 0x8F, 0x9E, 0x43, + 0xE7, 0x90, 0x86, 0x43, 0xE7, 0x90, 0x89, 0x43, + 0xE7, 0x90, 0xA2, 0x43, 0xE7, 0x91, 0x87, 0x43, + 0xE7, 0x91, 0x9C, 0x43, 0xE7, 0x91, 0xA9, 0x43, + 0xE7, 0x91, 0xB1, 0x43, 0xE7, 0x92, 0x85, 0x43, + 0xE7, 0x92, 0x89, 0x43, 0xE7, 0x92, 0x98, 0x43, + 0xE7, 0x93, 0x8A, 0x43, 0xE7, 0x93, 0x9C, 0x43, + 0xE7, 0x93, 0xA6, 0x43, 0xE7, 0x94, 0x86, 0x43, + // Bytes f80 - fbf + 0xE7, 0x94, 0x98, 0x43, 0xE7, 0x94, 0x9F, 0x43, + 0xE7, 0x94, 0xA4, 0x43, 0xE7, 0x94, 0xA8, 0x43, + 0xE7, 0x94, 0xB0, 0x43, 0xE7, 0x94, 0xB2, 0x43, + 0xE7, 0x94, 0xB3, 0x43, 0xE7, 0x94, 0xB7, 0x43, + 0xE7, 0x94, 0xBB, 0x43, 0xE7, 0x94, 0xBE, 0x43, + 0xE7, 0x95, 0x99, 0x43, 0xE7, 0x95, 0xA5, 0x43, + 0xE7, 0x95, 0xB0, 0x43, 0xE7, 0x96, 0x8B, 0x43, + 0xE7, 0x96, 0x92, 0x43, 0xE7, 0x97, 0xA2, 0x43, + // Bytes fc0 - fff + 0xE7, 0x98, 0x90, 0x43, 0xE7, 0x98, 0x9D, 0x43, + 0xE7, 0x98, 0x9F, 0x43, 0xE7, 0x99, 0x82, 0x43, + 0xE7, 0x99, 0xA9, 0x43, 0xE7, 0x99, 0xB6, 0x43, + 0xE7, 0x99, 0xBD, 0x43, 0xE7, 0x9A, 0xAE, 0x43, + 0xE7, 0x9A, 0xBF, 0x43, 0xE7, 0x9B, 0x8A, 0x43, + 0xE7, 0x9B, 0x9B, 0x43, 0xE7, 0x9B, 0xA3, 0x43, + 0xE7, 0x9B, 0xA7, 0x43, 0xE7, 0x9B, 0xAE, 0x43, + 0xE7, 0x9B, 0xB4, 0x43, 0xE7, 0x9C, 0x81, 0x43, + // Bytes 1000 - 103f + 0xE7, 0x9C, 0x9E, 0x43, 0xE7, 0x9C, 0x9F, 0x43, + 0xE7, 0x9D, 0x80, 0x43, 0xE7, 0x9D, 0x8A, 0x43, + 0xE7, 0x9E, 0x8B, 0x43, 0xE7, 0x9E, 0xA7, 0x43, + 0xE7, 0x9F, 0x9B, 0x43, 0xE7, 0x9F, 0xA2, 0x43, + 0xE7, 0x9F, 0xB3, 0x43, 0xE7, 0xA1, 0x8E, 0x43, + 0xE7, 0xA1, 0xAB, 0x43, 0xE7, 0xA2, 0x8C, 0x43, + 0xE7, 0xA2, 0x91, 0x43, 0xE7, 0xA3, 0x8A, 0x43, + 0xE7, 0xA3, 0x8C, 0x43, 0xE7, 0xA3, 0xBB, 0x43, + // Bytes 1040 - 107f + 0xE7, 0xA4, 0xAA, 0x43, 0xE7, 0xA4, 0xBA, 0x43, + 0xE7, 0xA4, 0xBC, 0x43, 0xE7, 0xA4, 0xBE, 0x43, + 0xE7, 0xA5, 0x88, 0x43, 0xE7, 0xA5, 0x89, 0x43, + 0xE7, 0xA5, 0x90, 0x43, 0xE7, 0xA5, 0x96, 0x43, + 0xE7, 0xA5, 0x9D, 0x43, 0xE7, 0xA5, 0x9E, 0x43, + 0xE7, 0xA5, 0xA5, 0x43, 0xE7, 0xA5, 0xBF, 0x43, + 0xE7, 0xA6, 0x81, 0x43, 0xE7, 0xA6, 0x8D, 0x43, + 0xE7, 0xA6, 0x8E, 0x43, 0xE7, 0xA6, 0x8F, 0x43, + // Bytes 1080 - 10bf + 0xE7, 0xA6, 0xAE, 0x43, 0xE7, 0xA6, 0xB8, 0x43, + 0xE7, 0xA6, 0xBE, 0x43, 0xE7, 0xA7, 0x8A, 0x43, + 0xE7, 0xA7, 0x98, 0x43, 0xE7, 0xA7, 0xAB, 0x43, + 0xE7, 0xA8, 0x9C, 0x43, 0xE7, 0xA9, 0x80, 0x43, + 0xE7, 0xA9, 0x8A, 0x43, 0xE7, 0xA9, 0x8F, 0x43, + 0xE7, 0xA9, 0xB4, 0x43, 0xE7, 0xA9, 0xBA, 0x43, + 0xE7, 0xAA, 0x81, 0x43, 0xE7, 0xAA, 0xB1, 0x43, + 0xE7, 0xAB, 0x8B, 0x43, 0xE7, 0xAB, 0xAE, 0x43, + // Bytes 10c0 - 10ff + 0xE7, 0xAB, 0xB9, 0x43, 0xE7, 0xAC, 0xA0, 0x43, + 0xE7, 0xAE, 0x8F, 0x43, 0xE7, 0xAF, 0x80, 0x43, + 0xE7, 0xAF, 0x86, 0x43, 0xE7, 0xAF, 0x89, 0x43, + 0xE7, 0xB0, 0xBE, 0x43, 0xE7, 0xB1, 0xA0, 0x43, + 0xE7, 0xB1, 0xB3, 0x43, 0xE7, 0xB1, 0xBB, 0x43, + 0xE7, 0xB2, 0x92, 0x43, 0xE7, 0xB2, 0xBE, 0x43, + 0xE7, 0xB3, 0x92, 0x43, 0xE7, 0xB3, 0x96, 0x43, + 0xE7, 0xB3, 0xA3, 0x43, 0xE7, 0xB3, 0xA7, 0x43, + // Bytes 1100 - 113f + 0xE7, 0xB3, 0xA8, 0x43, 0xE7, 0xB3, 0xB8, 0x43, + 0xE7, 0xB4, 0x80, 0x43, 0xE7, 0xB4, 0x90, 0x43, + 0xE7, 0xB4, 0xA2, 0x43, 0xE7, 0xB4, 0xAF, 0x43, + 0xE7, 0xB5, 0x82, 0x43, 0xE7, 0xB5, 0x9B, 0x43, + 0xE7, 0xB5, 0xA3, 0x43, 0xE7, 0xB6, 0xA0, 0x43, + 0xE7, 0xB6, 0xBE, 0x43, 0xE7, 0xB7, 0x87, 0x43, + 0xE7, 0xB7, 0xB4, 0x43, 0xE7, 0xB8, 0x82, 0x43, + 0xE7, 0xB8, 0x89, 0x43, 0xE7, 0xB8, 0xB7, 0x43, + // Bytes 1140 - 117f + 0xE7, 0xB9, 0x81, 0x43, 0xE7, 0xB9, 0x85, 0x43, + 0xE7, 0xBC, 0xB6, 0x43, 0xE7, 0xBC, 0xBE, 0x43, + 0xE7, 0xBD, 0x91, 0x43, 0xE7, 0xBD, 0xB2, 0x43, + 0xE7, 0xBD, 0xB9, 0x43, 0xE7, 0xBD, 0xBA, 0x43, + 0xE7, 0xBE, 0x85, 0x43, 0xE7, 0xBE, 0x8A, 0x43, + 0xE7, 0xBE, 0x95, 0x43, 0xE7, 0xBE, 0x9A, 0x43, + 0xE7, 0xBE, 0xBD, 0x43, 0xE7, 0xBF, 0xBA, 0x43, + 0xE8, 0x80, 0x81, 0x43, 0xE8, 0x80, 0x85, 0x43, + // Bytes 1180 - 11bf + 0xE8, 0x80, 0x8C, 0x43, 0xE8, 0x80, 0x92, 0x43, + 0xE8, 0x80, 0xB3, 0x43, 0xE8, 0x81, 0x86, 0x43, + 0xE8, 0x81, 0xA0, 0x43, 0xE8, 0x81, 0xAF, 0x43, + 0xE8, 0x81, 0xB0, 0x43, 0xE8, 0x81, 0xBE, 0x43, + 0xE8, 0x81, 0xBF, 0x43, 0xE8, 0x82, 0x89, 0x43, + 0xE8, 0x82, 0x8B, 0x43, 0xE8, 0x82, 0xAD, 0x43, + 0xE8, 0x82, 0xB2, 0x43, 0xE8, 0x84, 0x83, 0x43, + 0xE8, 0x84, 0xBE, 0x43, 0xE8, 0x87, 0x98, 0x43, + // Bytes 11c0 - 11ff + 0xE8, 0x87, 0xA3, 0x43, 0xE8, 0x87, 0xA8, 0x43, + 0xE8, 0x87, 0xAA, 0x43, 0xE8, 0x87, 0xAD, 0x43, + 0xE8, 0x87, 0xB3, 0x43, 0xE8, 0x87, 0xBC, 0x43, + 0xE8, 0x88, 0x81, 0x43, 0xE8, 0x88, 0x84, 0x43, + 0xE8, 0x88, 0x8C, 0x43, 0xE8, 0x88, 0x98, 0x43, + 0xE8, 0x88, 0x9B, 0x43, 0xE8, 0x88, 0x9F, 0x43, + 0xE8, 0x89, 0xAE, 0x43, 0xE8, 0x89, 0xAF, 0x43, + 0xE8, 0x89, 0xB2, 0x43, 0xE8, 0x89, 0xB8, 0x43, + // Bytes 1200 - 123f + 0xE8, 0x89, 0xB9, 0x43, 0xE8, 0x8A, 0x8B, 0x43, + 0xE8, 0x8A, 0x91, 0x43, 0xE8, 0x8A, 0x9D, 0x43, + 0xE8, 0x8A, 0xB1, 0x43, 0xE8, 0x8A, 0xB3, 0x43, + 0xE8, 0x8A, 0xBD, 0x43, 0xE8, 0x8B, 0xA5, 0x43, + 0xE8, 0x8B, 0xA6, 0x43, 0xE8, 0x8C, 0x9D, 0x43, + 0xE8, 0x8C, 0xA3, 0x43, 0xE8, 0x8C, 0xB6, 0x43, + 0xE8, 0x8D, 0x92, 0x43, 0xE8, 0x8D, 0x93, 0x43, + 0xE8, 0x8D, 0xA3, 0x43, 0xE8, 0x8E, 0xAD, 0x43, + // Bytes 1240 - 127f + 0xE8, 0x8E, 0xBD, 0x43, 0xE8, 0x8F, 0x89, 0x43, + 0xE8, 0x8F, 0x8A, 0x43, 0xE8, 0x8F, 0x8C, 0x43, + 0xE8, 0x8F, 0x9C, 0x43, 0xE8, 0x8F, 0xA7, 0x43, + 0xE8, 0x8F, 0xAF, 0x43, 0xE8, 0x8F, 0xB1, 0x43, + 0xE8, 0x90, 0xBD, 0x43, 0xE8, 0x91, 0x89, 0x43, + 0xE8, 0x91, 0x97, 0x43, 0xE8, 0x93, 0xAE, 0x43, + 0xE8, 0x93, 0xB1, 0x43, 0xE8, 0x93, 0xB3, 0x43, + 0xE8, 0x93, 0xBC, 0x43, 0xE8, 0x94, 0x96, 0x43, + // Bytes 1280 - 12bf + 0xE8, 0x95, 0xA4, 0x43, 0xE8, 0x97, 0x8D, 0x43, + 0xE8, 0x97, 0xBA, 0x43, 0xE8, 0x98, 0x86, 0x43, + 0xE8, 0x98, 0x92, 0x43, 0xE8, 0x98, 0xAD, 0x43, + 0xE8, 0x98, 0xBF, 0x43, 0xE8, 0x99, 0x8D, 0x43, + 0xE8, 0x99, 0x90, 0x43, 0xE8, 0x99, 0x9C, 0x43, + 0xE8, 0x99, 0xA7, 0x43, 0xE8, 0x99, 0xA9, 0x43, + 0xE8, 0x99, 0xAB, 0x43, 0xE8, 0x9A, 0x88, 0x43, + 0xE8, 0x9A, 0xA9, 0x43, 0xE8, 0x9B, 0xA2, 0x43, + // Bytes 12c0 - 12ff + 0xE8, 0x9C, 0x8E, 0x43, 0xE8, 0x9C, 0xA8, 0x43, + 0xE8, 0x9D, 0xAB, 0x43, 0xE8, 0x9D, 0xB9, 0x43, + 0xE8, 0x9E, 0x86, 0x43, 0xE8, 0x9E, 0xBA, 0x43, + 0xE8, 0x9F, 0xA1, 0x43, 0xE8, 0xA0, 0x81, 0x43, + 0xE8, 0xA0, 0x9F, 0x43, 0xE8, 0xA1, 0x80, 0x43, + 0xE8, 0xA1, 0x8C, 0x43, 0xE8, 0xA1, 0xA0, 0x43, + 0xE8, 0xA1, 0xA3, 0x43, 0xE8, 0xA3, 0x82, 0x43, + 0xE8, 0xA3, 0x8F, 0x43, 0xE8, 0xA3, 0x97, 0x43, + // Bytes 1300 - 133f + 0xE8, 0xA3, 0x9E, 0x43, 0xE8, 0xA3, 0xA1, 0x43, + 0xE8, 0xA3, 0xB8, 0x43, 0xE8, 0xA3, 0xBA, 0x43, + 0xE8, 0xA4, 0x90, 0x43, 0xE8, 0xA5, 0x81, 0x43, + 0xE8, 0xA5, 0xA4, 0x43, 0xE8, 0xA5, 0xBE, 0x43, + 0xE8, 0xA6, 0x86, 0x43, 0xE8, 0xA6, 0x8B, 0x43, + 0xE8, 0xA6, 0x96, 0x43, 0xE8, 0xA7, 0x92, 0x43, + 0xE8, 0xA7, 0xA3, 0x43, 0xE8, 0xA8, 0x80, 0x43, + 0xE8, 0xAA, 0xA0, 0x43, 0xE8, 0xAA, 0xAA, 0x43, + // Bytes 1340 - 137f + 0xE8, 0xAA, 0xBF, 0x43, 0xE8, 0xAB, 0x8B, 0x43, + 0xE8, 0xAB, 0x92, 0x43, 0xE8, 0xAB, 0x96, 0x43, + 0xE8, 0xAB, 0xAD, 0x43, 0xE8, 0xAB, 0xB8, 0x43, + 0xE8, 0xAB, 0xBE, 0x43, 0xE8, 0xAC, 0x81, 0x43, + 0xE8, 0xAC, 0xB9, 0x43, 0xE8, 0xAD, 0x98, 0x43, + 0xE8, 0xAE, 0x80, 0x43, 0xE8, 0xAE, 0x8A, 0x43, + 0xE8, 0xB0, 0xB7, 0x43, 0xE8, 0xB1, 0x86, 0x43, + 0xE8, 0xB1, 0x88, 0x43, 0xE8, 0xB1, 0x95, 0x43, + // Bytes 1380 - 13bf + 0xE8, 0xB1, 0xB8, 0x43, 0xE8, 0xB2, 0x9D, 0x43, + 0xE8, 0xB2, 0xA1, 0x43, 0xE8, 0xB2, 0xA9, 0x43, + 0xE8, 0xB2, 0xAB, 0x43, 0xE8, 0xB3, 0x81, 0x43, + 0xE8, 0xB3, 0x82, 0x43, 0xE8, 0xB3, 0x87, 0x43, + 0xE8, 0xB3, 0x88, 0x43, 0xE8, 0xB3, 0x93, 0x43, + 0xE8, 0xB4, 0x88, 0x43, 0xE8, 0xB4, 0x9B, 0x43, + 0xE8, 0xB5, 0xA4, 0x43, 0xE8, 0xB5, 0xB0, 0x43, + 0xE8, 0xB5, 0xB7, 0x43, 0xE8, 0xB6, 0xB3, 0x43, + // Bytes 13c0 - 13ff + 0xE8, 0xB6, 0xBC, 0x43, 0xE8, 0xB7, 0x8B, 0x43, + 0xE8, 0xB7, 0xAF, 0x43, 0xE8, 0xB7, 0xB0, 0x43, + 0xE8, 0xBA, 0xAB, 0x43, 0xE8, 0xBB, 0x8A, 0x43, + 0xE8, 0xBB, 0x94, 0x43, 0xE8, 0xBC, 0xA6, 0x43, + 0xE8, 0xBC, 0xAA, 0x43, 0xE8, 0xBC, 0xB8, 0x43, + 0xE8, 0xBC, 0xBB, 0x43, 0xE8, 0xBD, 0xA2, 0x43, + 0xE8, 0xBE, 0x9B, 0x43, 0xE8, 0xBE, 0x9E, 0x43, + 0xE8, 0xBE, 0xB0, 0x43, 0xE8, 0xBE, 0xB5, 0x43, + // Bytes 1400 - 143f + 0xE8, 0xBE, 0xB6, 0x43, 0xE9, 0x80, 0xA3, 0x43, + 0xE9, 0x80, 0xB8, 0x43, 0xE9, 0x81, 0x8A, 0x43, + 0xE9, 0x81, 0xA9, 0x43, 0xE9, 0x81, 0xB2, 0x43, + 0xE9, 0x81, 0xBC, 0x43, 0xE9, 0x82, 0x8F, 0x43, + 0xE9, 0x82, 0x91, 0x43, 0xE9, 0x82, 0x94, 0x43, + 0xE9, 0x83, 0x8E, 0x43, 0xE9, 0x83, 0x9E, 0x43, + 0xE9, 0x83, 0xB1, 0x43, 0xE9, 0x83, 0xBD, 0x43, + 0xE9, 0x84, 0x91, 0x43, 0xE9, 0x84, 0x9B, 0x43, + // Bytes 1440 - 147f + 0xE9, 0x85, 0x89, 0x43, 0xE9, 0x85, 0x8D, 0x43, + 0xE9, 0x85, 0xAA, 0x43, 0xE9, 0x86, 0x99, 0x43, + 0xE9, 0x86, 0xB4, 0x43, 0xE9, 0x87, 0x86, 0x43, + 0xE9, 0x87, 0x8C, 0x43, 0xE9, 0x87, 0x8F, 0x43, + 0xE9, 0x87, 0x91, 0x43, 0xE9, 0x88, 0xB4, 0x43, + 0xE9, 0x88, 0xB8, 0x43, 0xE9, 0x89, 0xB6, 0x43, + 0xE9, 0x89, 0xBC, 0x43, 0xE9, 0x8B, 0x97, 0x43, + 0xE9, 0x8B, 0x98, 0x43, 0xE9, 0x8C, 0x84, 0x43, + // Bytes 1480 - 14bf + 0xE9, 0x8D, 0x8A, 0x43, 0xE9, 0x8F, 0xB9, 0x43, + 0xE9, 0x90, 0x95, 0x43, 0xE9, 0x95, 0xB7, 0x43, + 0xE9, 0x96, 0x80, 0x43, 0xE9, 0x96, 0x8B, 0x43, + 0xE9, 0x96, 0xAD, 0x43, 0xE9, 0x96, 0xB7, 0x43, + 0xE9, 0x98, 0x9C, 0x43, 0xE9, 0x98, 0xAE, 0x43, + 0xE9, 0x99, 0x8B, 0x43, 0xE9, 0x99, 0x8D, 0x43, + 0xE9, 0x99, 0xB5, 0x43, 0xE9, 0x99, 0xB8, 0x43, + 0xE9, 0x99, 0xBC, 0x43, 0xE9, 0x9A, 0x86, 0x43, + // Bytes 14c0 - 14ff + 0xE9, 0x9A, 0xA3, 0x43, 0xE9, 0x9A, 0xB6, 0x43, + 0xE9, 0x9A, 0xB7, 0x43, 0xE9, 0x9A, 0xB8, 0x43, + 0xE9, 0x9A, 0xB9, 0x43, 0xE9, 0x9B, 0x83, 0x43, + 0xE9, 0x9B, 0xA2, 0x43, 0xE9, 0x9B, 0xA3, 0x43, + 0xE9, 0x9B, 0xA8, 0x43, 0xE9, 0x9B, 0xB6, 0x43, + 0xE9, 0x9B, 0xB7, 0x43, 0xE9, 0x9C, 0xA3, 0x43, + 0xE9, 0x9C, 0xB2, 0x43, 0xE9, 0x9D, 0x88, 0x43, + 0xE9, 0x9D, 0x91, 0x43, 0xE9, 0x9D, 0x96, 0x43, + // Bytes 1500 - 153f + 0xE9, 0x9D, 0x9E, 0x43, 0xE9, 0x9D, 0xA2, 0x43, + 0xE9, 0x9D, 0xA9, 0x43, 0xE9, 0x9F, 0x8B, 0x43, + 0xE9, 0x9F, 0x9B, 0x43, 0xE9, 0x9F, 0xA0, 0x43, + 0xE9, 0x9F, 0xAD, 0x43, 0xE9, 0x9F, 0xB3, 0x43, + 0xE9, 0x9F, 0xBF, 0x43, 0xE9, 0xA0, 0x81, 0x43, + 0xE9, 0xA0, 0x85, 0x43, 0xE9, 0xA0, 0x8B, 0x43, + 0xE9, 0xA0, 0x98, 0x43, 0xE9, 0xA0, 0xA9, 0x43, + 0xE9, 0xA0, 0xBB, 0x43, 0xE9, 0xA1, 0x9E, 0x43, + // Bytes 1540 - 157f + 0xE9, 0xA2, 0xA8, 0x43, 0xE9, 0xA3, 0x9B, 0x43, + 0xE9, 0xA3, 0x9F, 0x43, 0xE9, 0xA3, 0xA2, 0x43, + 0xE9, 0xA3, 0xAF, 0x43, 0xE9, 0xA3, 0xBC, 0x43, + 0xE9, 0xA4, 0xA8, 0x43, 0xE9, 0xA4, 0xA9, 0x43, + 0xE9, 0xA6, 0x96, 0x43, 0xE9, 0xA6, 0x99, 0x43, + 0xE9, 0xA6, 0xA7, 0x43, 0xE9, 0xA6, 0xAC, 0x43, + 0xE9, 0xA7, 0x82, 0x43, 0xE9, 0xA7, 0xB1, 0x43, + 0xE9, 0xA7, 0xBE, 0x43, 0xE9, 0xA9, 0xAA, 0x43, + // Bytes 1580 - 15bf + 0xE9, 0xAA, 0xA8, 0x43, 0xE9, 0xAB, 0x98, 0x43, + 0xE9, 0xAB, 0x9F, 0x43, 0xE9, 0xAC, 0x92, 0x43, + 0xE9, 0xAC, 0xA5, 0x43, 0xE9, 0xAC, 0xAF, 0x43, + 0xE9, 0xAC, 0xB2, 0x43, 0xE9, 0xAC, 0xBC, 0x43, + 0xE9, 0xAD, 0x9A, 0x43, 0xE9, 0xAD, 0xAF, 0x43, + 0xE9, 0xB1, 0x80, 0x43, 0xE9, 0xB1, 0x97, 0x43, + 0xE9, 0xB3, 0xA5, 0x43, 0xE9, 0xB3, 0xBD, 0x43, + 0xE9, 0xB5, 0xA7, 0x43, 0xE9, 0xB6, 0xB4, 0x43, + // Bytes 15c0 - 15ff + 0xE9, 0xB7, 0xBA, 0x43, 0xE9, 0xB8, 0x9E, 0x43, + 0xE9, 0xB9, 0xB5, 0x43, 0xE9, 0xB9, 0xBF, 0x43, + 0xE9, 0xBA, 0x97, 0x43, 0xE9, 0xBA, 0x9F, 0x43, + 0xE9, 0xBA, 0xA5, 0x43, 0xE9, 0xBA, 0xBB, 0x43, + 0xE9, 0xBB, 0x83, 0x43, 0xE9, 0xBB, 0x8D, 0x43, + 0xE9, 0xBB, 0x8E, 0x43, 0xE9, 0xBB, 0x91, 0x43, + 0xE9, 0xBB, 0xB9, 0x43, 0xE9, 0xBB, 0xBD, 0x43, + 0xE9, 0xBB, 0xBE, 0x43, 0xE9, 0xBC, 0x85, 0x43, + // Bytes 1600 - 163f + 0xE9, 0xBC, 0x8E, 0x43, 0xE9, 0xBC, 0x8F, 0x43, + 0xE9, 0xBC, 0x93, 0x43, 0xE9, 0xBC, 0x96, 0x43, + 0xE9, 0xBC, 0xA0, 0x43, 0xE9, 0xBC, 0xBB, 0x43, + 0xE9, 0xBD, 0x83, 0x43, 0xE9, 0xBD, 0x8A, 0x43, + 0xE9, 0xBD, 0x92, 0x43, 0xE9, 0xBE, 0x8D, 0x43, + 0xE9, 0xBE, 0x8E, 0x43, 0xE9, 0xBE, 0x9C, 0x43, + 0xE9, 0xBE, 0x9F, 0x43, 0xE9, 0xBE, 0xA0, 0x43, + 0xEA, 0x9C, 0xA7, 0x43, 0xEA, 0x9D, 0xAF, 0x43, + // Bytes 1640 - 167f + 0xEA, 0xAC, 0xB7, 0x43, 0xEA, 0xAD, 0x92, 0x44, + 0xF0, 0xA0, 0x84, 0xA2, 0x44, 0xF0, 0xA0, 0x94, + 0x9C, 0x44, 0xF0, 0xA0, 0x94, 0xA5, 0x44, 0xF0, + 0xA0, 0x95, 0x8B, 0x44, 0xF0, 0xA0, 0x98, 0xBA, + 0x44, 0xF0, 0xA0, 0xA0, 0x84, 0x44, 0xF0, 0xA0, + 0xA3, 0x9E, 0x44, 0xF0, 0xA0, 0xA8, 0xAC, 0x44, + 0xF0, 0xA0, 0xAD, 0xA3, 0x44, 0xF0, 0xA1, 0x93, + 0xA4, 0x44, 0xF0, 0xA1, 0x9A, 0xA8, 0x44, 0xF0, + // Bytes 1680 - 16bf + 0xA1, 0x9B, 0xAA, 0x44, 0xF0, 0xA1, 0xA7, 0x88, + 0x44, 0xF0, 0xA1, 0xAC, 0x98, 0x44, 0xF0, 0xA1, + 0xB4, 0x8B, 0x44, 0xF0, 0xA1, 0xB7, 0xA4, 0x44, + 0xF0, 0xA1, 0xB7, 0xA6, 0x44, 0xF0, 0xA2, 0x86, + 0x83, 0x44, 0xF0, 0xA2, 0x86, 0x9F, 0x44, 0xF0, + 0xA2, 0x8C, 0xB1, 0x44, 0xF0, 0xA2, 0x9B, 0x94, + 0x44, 0xF0, 0xA2, 0xA1, 0x84, 0x44, 0xF0, 0xA2, + 0xA1, 0x8A, 0x44, 0xF0, 0xA2, 0xAC, 0x8C, 0x44, + // Bytes 16c0 - 16ff + 0xF0, 0xA2, 0xAF, 0xB1, 0x44, 0xF0, 0xA3, 0x80, + 0x8A, 0x44, 0xF0, 0xA3, 0x8A, 0xB8, 0x44, 0xF0, + 0xA3, 0x8D, 0x9F, 0x44, 0xF0, 0xA3, 0x8E, 0x93, + 0x44, 0xF0, 0xA3, 0x8E, 0x9C, 0x44, 0xF0, 0xA3, + 0x8F, 0x83, 0x44, 0xF0, 0xA3, 0x8F, 0x95, 0x44, + 0xF0, 0xA3, 0x91, 0xAD, 0x44, 0xF0, 0xA3, 0x9A, + 0xA3, 0x44, 0xF0, 0xA3, 0xA2, 0xA7, 0x44, 0xF0, + 0xA3, 0xAA, 0x8D, 0x44, 0xF0, 0xA3, 0xAB, 0xBA, + // Bytes 1700 - 173f + 0x44, 0xF0, 0xA3, 0xB2, 0xBC, 0x44, 0xF0, 0xA3, + 0xB4, 0x9E, 0x44, 0xF0, 0xA3, 0xBB, 0x91, 0x44, + 0xF0, 0xA3, 0xBD, 0x9E, 0x44, 0xF0, 0xA3, 0xBE, + 0x8E, 0x44, 0xF0, 0xA4, 0x89, 0xA3, 0x44, 0xF0, + 0xA4, 0x8B, 0xAE, 0x44, 0xF0, 0xA4, 0x8E, 0xAB, + 0x44, 0xF0, 0xA4, 0x98, 0x88, 0x44, 0xF0, 0xA4, + 0x9C, 0xB5, 0x44, 0xF0, 0xA4, 0xA0, 0x94, 0x44, + 0xF0, 0xA4, 0xB0, 0xB6, 0x44, 0xF0, 0xA4, 0xB2, + // Bytes 1740 - 177f + 0x92, 0x44, 0xF0, 0xA4, 0xBE, 0xA1, 0x44, 0xF0, + 0xA4, 0xBE, 0xB8, 0x44, 0xF0, 0xA5, 0x81, 0x84, + 0x44, 0xF0, 0xA5, 0x83, 0xB2, 0x44, 0xF0, 0xA5, + 0x83, 0xB3, 0x44, 0xF0, 0xA5, 0x84, 0x99, 0x44, + 0xF0, 0xA5, 0x84, 0xB3, 0x44, 0xF0, 0xA5, 0x89, + 0x89, 0x44, 0xF0, 0xA5, 0x90, 0x9D, 0x44, 0xF0, + 0xA5, 0x98, 0xA6, 0x44, 0xF0, 0xA5, 0x9A, 0x9A, + 0x44, 0xF0, 0xA5, 0x9B, 0x85, 0x44, 0xF0, 0xA5, + // Bytes 1780 - 17bf + 0xA5, 0xBC, 0x44, 0xF0, 0xA5, 0xAA, 0xA7, 0x44, + 0xF0, 0xA5, 0xAE, 0xAB, 0x44, 0xF0, 0xA5, 0xB2, + 0x80, 0x44, 0xF0, 0xA5, 0xB3, 0x90, 0x44, 0xF0, + 0xA5, 0xBE, 0x86, 0x44, 0xF0, 0xA6, 0x87, 0x9A, + 0x44, 0xF0, 0xA6, 0x88, 0xA8, 0x44, 0xF0, 0xA6, + 0x89, 0x87, 0x44, 0xF0, 0xA6, 0x8B, 0x99, 0x44, + 0xF0, 0xA6, 0x8C, 0xBE, 0x44, 0xF0, 0xA6, 0x93, + 0x9A, 0x44, 0xF0, 0xA6, 0x94, 0xA3, 0x44, 0xF0, + // Bytes 17c0 - 17ff + 0xA6, 0x96, 0xA8, 0x44, 0xF0, 0xA6, 0x9E, 0xA7, + 0x44, 0xF0, 0xA6, 0x9E, 0xB5, 0x44, 0xF0, 0xA6, + 0xAC, 0xBC, 0x44, 0xF0, 0xA6, 0xB0, 0xB6, 0x44, + 0xF0, 0xA6, 0xB3, 0x95, 0x44, 0xF0, 0xA6, 0xB5, + 0xAB, 0x44, 0xF0, 0xA6, 0xBC, 0xAC, 0x44, 0xF0, + 0xA6, 0xBE, 0xB1, 0x44, 0xF0, 0xA7, 0x83, 0x92, + 0x44, 0xF0, 0xA7, 0x8F, 0x8A, 0x44, 0xF0, 0xA7, + 0x99, 0xA7, 0x44, 0xF0, 0xA7, 0xA2, 0xAE, 0x44, + // Bytes 1800 - 183f + 0xF0, 0xA7, 0xA5, 0xA6, 0x44, 0xF0, 0xA7, 0xB2, + 0xA8, 0x44, 0xF0, 0xA7, 0xBB, 0x93, 0x44, 0xF0, + 0xA7, 0xBC, 0xAF, 0x44, 0xF0, 0xA8, 0x97, 0x92, + 0x44, 0xF0, 0xA8, 0x97, 0xAD, 0x44, 0xF0, 0xA8, + 0x9C, 0xAE, 0x44, 0xF0, 0xA8, 0xAF, 0xBA, 0x44, + 0xF0, 0xA8, 0xB5, 0xB7, 0x44, 0xF0, 0xA9, 0x85, + 0x85, 0x44, 0xF0, 0xA9, 0x87, 0x9F, 0x44, 0xF0, + 0xA9, 0x88, 0x9A, 0x44, 0xF0, 0xA9, 0x90, 0x8A, + // Bytes 1840 - 187f + 0x44, 0xF0, 0xA9, 0x92, 0x96, 0x44, 0xF0, 0xA9, + 0x96, 0xB6, 0x44, 0xF0, 0xA9, 0xAC, 0xB0, 0x44, + 0xF0, 0xAA, 0x83, 0x8E, 0x44, 0xF0, 0xAA, 0x84, + 0x85, 0x44, 0xF0, 0xAA, 0x88, 0x8E, 0x44, 0xF0, + 0xAA, 0x8A, 0x91, 0x44, 0xF0, 0xAA, 0x8E, 0x92, + 0x44, 0xF0, 0xAA, 0x98, 0x80, 0x42, 0x21, 0x21, + 0x42, 0x21, 0x3F, 0x42, 0x2E, 0x2E, 0x42, 0x30, + 0x2C, 0x42, 0x30, 0x2E, 0x42, 0x31, 0x2C, 0x42, + // Bytes 1880 - 18bf + 0x31, 0x2E, 0x42, 0x31, 0x30, 0x42, 0x31, 0x31, + 0x42, 0x31, 0x32, 0x42, 0x31, 0x33, 0x42, 0x31, + 0x34, 0x42, 0x31, 0x35, 0x42, 0x31, 0x36, 0x42, + 0x31, 0x37, 0x42, 0x31, 0x38, 0x42, 0x31, 0x39, + 0x42, 0x32, 0x2C, 0x42, 0x32, 0x2E, 0x42, 0x32, + 0x30, 0x42, 0x32, 0x31, 0x42, 0x32, 0x32, 0x42, + 0x32, 0x33, 0x42, 0x32, 0x34, 0x42, 0x32, 0x35, + 0x42, 0x32, 0x36, 0x42, 0x32, 0x37, 0x42, 0x32, + // Bytes 18c0 - 18ff + 0x38, 0x42, 0x32, 0x39, 0x42, 0x33, 0x2C, 0x42, + 0x33, 0x2E, 0x42, 0x33, 0x30, 0x42, 0x33, 0x31, + 0x42, 0x33, 0x32, 0x42, 0x33, 0x33, 0x42, 0x33, + 0x34, 0x42, 0x33, 0x35, 0x42, 0x33, 0x36, 0x42, + 0x33, 0x37, 0x42, 0x33, 0x38, 0x42, 0x33, 0x39, + 0x42, 0x34, 0x2C, 0x42, 0x34, 0x2E, 0x42, 0x34, + 0x30, 0x42, 0x34, 0x31, 0x42, 0x34, 0x32, 0x42, + 0x34, 0x33, 0x42, 0x34, 0x34, 0x42, 0x34, 0x35, + // Bytes 1900 - 193f + 0x42, 0x34, 0x36, 0x42, 0x34, 0x37, 0x42, 0x34, + 0x38, 0x42, 0x34, 0x39, 0x42, 0x35, 0x2C, 0x42, + 0x35, 0x2E, 0x42, 0x35, 0x30, 0x42, 0x36, 0x2C, + 0x42, 0x36, 0x2E, 0x42, 0x37, 0x2C, 0x42, 0x37, + 0x2E, 0x42, 0x38, 0x2C, 0x42, 0x38, 0x2E, 0x42, + 0x39, 0x2C, 0x42, 0x39, 0x2E, 0x42, 0x3D, 0x3D, + 0x42, 0x3F, 0x21, 0x42, 0x3F, 0x3F, 0x42, 0x41, + 0x55, 0x42, 0x42, 0x71, 0x42, 0x43, 0x44, 0x42, + // Bytes 1940 - 197f + 0x44, 0x4A, 0x42, 0x44, 0x5A, 0x42, 0x44, 0x7A, + 0x42, 0x47, 0x42, 0x42, 0x47, 0x79, 0x42, 0x48, + 0x50, 0x42, 0x48, 0x56, 0x42, 0x48, 0x67, 0x42, + 0x48, 0x7A, 0x42, 0x49, 0x49, 0x42, 0x49, 0x4A, + 0x42, 0x49, 0x55, 0x42, 0x49, 0x56, 0x42, 0x49, + 0x58, 0x42, 0x4B, 0x42, 0x42, 0x4B, 0x4B, 0x42, + 0x4B, 0x4D, 0x42, 0x4C, 0x4A, 0x42, 0x4C, 0x6A, + 0x42, 0x4D, 0x42, 0x42, 0x4D, 0x43, 0x42, 0x4D, + // Bytes 1980 - 19bf + 0x44, 0x42, 0x4D, 0x56, 0x42, 0x4D, 0x57, 0x42, + 0x4E, 0x4A, 0x42, 0x4E, 0x6A, 0x42, 0x4E, 0x6F, + 0x42, 0x50, 0x48, 0x42, 0x50, 0x52, 0x42, 0x50, + 0x61, 0x42, 0x52, 0x73, 0x42, 0x53, 0x44, 0x42, + 0x53, 0x4D, 0x42, 0x53, 0x53, 0x42, 0x53, 0x76, + 0x42, 0x54, 0x4D, 0x42, 0x56, 0x49, 0x42, 0x57, + 0x43, 0x42, 0x57, 0x5A, 0x42, 0x57, 0x62, 0x42, + 0x58, 0x49, 0x42, 0x63, 0x63, 0x42, 0x63, 0x64, + // Bytes 19c0 - 19ff + 0x42, 0x63, 0x6D, 0x42, 0x64, 0x42, 0x42, 0x64, + 0x61, 0x42, 0x64, 0x6C, 0x42, 0x64, 0x6D, 0x42, + 0x64, 0x7A, 0x42, 0x65, 0x56, 0x42, 0x66, 0x66, + 0x42, 0x66, 0x69, 0x42, 0x66, 0x6C, 0x42, 0x66, + 0x6D, 0x42, 0x68, 0x61, 0x42, 0x69, 0x69, 0x42, + 0x69, 0x6A, 0x42, 0x69, 0x6E, 0x42, 0x69, 0x76, + 0x42, 0x69, 0x78, 0x42, 0x6B, 0x41, 0x42, 0x6B, + 0x56, 0x42, 0x6B, 0x57, 0x42, 0x6B, 0x67, 0x42, + // Bytes 1a00 - 1a3f + 0x6B, 0x6C, 0x42, 0x6B, 0x6D, 0x42, 0x6B, 0x74, + 0x42, 0x6C, 0x6A, 0x42, 0x6C, 0x6D, 0x42, 0x6C, + 0x6E, 0x42, 0x6C, 0x78, 0x42, 0x6D, 0x32, 0x42, + 0x6D, 0x33, 0x42, 0x6D, 0x41, 0x42, 0x6D, 0x56, + 0x42, 0x6D, 0x57, 0x42, 0x6D, 0x62, 0x42, 0x6D, + 0x67, 0x42, 0x6D, 0x6C, 0x42, 0x6D, 0x6D, 0x42, + 0x6D, 0x73, 0x42, 0x6E, 0x41, 0x42, 0x6E, 0x46, + 0x42, 0x6E, 0x56, 0x42, 0x6E, 0x57, 0x42, 0x6E, + // Bytes 1a40 - 1a7f + 0x6A, 0x42, 0x6E, 0x6D, 0x42, 0x6E, 0x73, 0x42, + 0x6F, 0x56, 0x42, 0x70, 0x41, 0x42, 0x70, 0x46, + 0x42, 0x70, 0x56, 0x42, 0x70, 0x57, 0x42, 0x70, + 0x63, 0x42, 0x70, 0x73, 0x42, 0x73, 0x72, 0x42, + 0x73, 0x74, 0x42, 0x76, 0x69, 0x42, 0x78, 0x69, + 0x43, 0x28, 0x31, 0x29, 0x43, 0x28, 0x32, 0x29, + 0x43, 0x28, 0x33, 0x29, 0x43, 0x28, 0x34, 0x29, + 0x43, 0x28, 0x35, 0x29, 0x43, 0x28, 0x36, 0x29, + // Bytes 1a80 - 1abf + 0x43, 0x28, 0x37, 0x29, 0x43, 0x28, 0x38, 0x29, + 0x43, 0x28, 0x39, 0x29, 0x43, 0x28, 0x41, 0x29, + 0x43, 0x28, 0x42, 0x29, 0x43, 0x28, 0x43, 0x29, + 0x43, 0x28, 0x44, 0x29, 0x43, 0x28, 0x45, 0x29, + 0x43, 0x28, 0x46, 0x29, 0x43, 0x28, 0x47, 0x29, + 0x43, 0x28, 0x48, 0x29, 0x43, 0x28, 0x49, 0x29, + 0x43, 0x28, 0x4A, 0x29, 0x43, 0x28, 0x4B, 0x29, + 0x43, 0x28, 0x4C, 0x29, 0x43, 0x28, 0x4D, 0x29, + // Bytes 1ac0 - 1aff + 0x43, 0x28, 0x4E, 0x29, 0x43, 0x28, 0x4F, 0x29, + 0x43, 0x28, 0x50, 0x29, 0x43, 0x28, 0x51, 0x29, + 0x43, 0x28, 0x52, 0x29, 0x43, 0x28, 0x53, 0x29, + 0x43, 0x28, 0x54, 0x29, 0x43, 0x28, 0x55, 0x29, + 0x43, 0x28, 0x56, 0x29, 0x43, 0x28, 0x57, 0x29, + 0x43, 0x28, 0x58, 0x29, 0x43, 0x28, 0x59, 0x29, + 0x43, 0x28, 0x5A, 0x29, 0x43, 0x28, 0x61, 0x29, + 0x43, 0x28, 0x62, 0x29, 0x43, 0x28, 0x63, 0x29, + // Bytes 1b00 - 1b3f + 0x43, 0x28, 0x64, 0x29, 0x43, 0x28, 0x65, 0x29, + 0x43, 0x28, 0x66, 0x29, 0x43, 0x28, 0x67, 0x29, + 0x43, 0x28, 0x68, 0x29, 0x43, 0x28, 0x69, 0x29, + 0x43, 0x28, 0x6A, 0x29, 0x43, 0x28, 0x6B, 0x29, + 0x43, 0x28, 0x6C, 0x29, 0x43, 0x28, 0x6D, 0x29, + 0x43, 0x28, 0x6E, 0x29, 0x43, 0x28, 0x6F, 0x29, + 0x43, 0x28, 0x70, 0x29, 0x43, 0x28, 0x71, 0x29, + 0x43, 0x28, 0x72, 0x29, 0x43, 0x28, 0x73, 0x29, + // Bytes 1b40 - 1b7f + 0x43, 0x28, 0x74, 0x29, 0x43, 0x28, 0x75, 0x29, + 0x43, 0x28, 0x76, 0x29, 0x43, 0x28, 0x77, 0x29, + 0x43, 0x28, 0x78, 0x29, 0x43, 0x28, 0x79, 0x29, + 0x43, 0x28, 0x7A, 0x29, 0x43, 0x2E, 0x2E, 0x2E, + 0x43, 0x31, 0x30, 0x2E, 0x43, 0x31, 0x31, 0x2E, + 0x43, 0x31, 0x32, 0x2E, 0x43, 0x31, 0x33, 0x2E, + 0x43, 0x31, 0x34, 0x2E, 0x43, 0x31, 0x35, 0x2E, + 0x43, 0x31, 0x36, 0x2E, 0x43, 0x31, 0x37, 0x2E, + // Bytes 1b80 - 1bbf + 0x43, 0x31, 0x38, 0x2E, 0x43, 0x31, 0x39, 0x2E, + 0x43, 0x32, 0x30, 0x2E, 0x43, 0x3A, 0x3A, 0x3D, + 0x43, 0x3D, 0x3D, 0x3D, 0x43, 0x43, 0x6F, 0x2E, + 0x43, 0x46, 0x41, 0x58, 0x43, 0x47, 0x48, 0x7A, + 0x43, 0x47, 0x50, 0x61, 0x43, 0x49, 0x49, 0x49, + 0x43, 0x4C, 0x54, 0x44, 0x43, 0x4C, 0xC2, 0xB7, + 0x43, 0x4D, 0x48, 0x7A, 0x43, 0x4D, 0x50, 0x61, + 0x43, 0x4D, 0xCE, 0xA9, 0x43, 0x50, 0x50, 0x4D, + // Bytes 1bc0 - 1bff + 0x43, 0x50, 0x50, 0x56, 0x43, 0x50, 0x54, 0x45, + 0x43, 0x54, 0x45, 0x4C, 0x43, 0x54, 0x48, 0x7A, + 0x43, 0x56, 0x49, 0x49, 0x43, 0x58, 0x49, 0x49, + 0x43, 0x61, 0x2F, 0x63, 0x43, 0x61, 0x2F, 0x73, + 0x43, 0x61, 0xCA, 0xBE, 0x43, 0x62, 0x61, 0x72, + 0x43, 0x63, 0x2F, 0x6F, 0x43, 0x63, 0x2F, 0x75, + 0x43, 0x63, 0x61, 0x6C, 0x43, 0x63, 0x6D, 0x32, + 0x43, 0x63, 0x6D, 0x33, 0x43, 0x64, 0x6D, 0x32, + // Bytes 1c00 - 1c3f + 0x43, 0x64, 0x6D, 0x33, 0x43, 0x65, 0x72, 0x67, + 0x43, 0x66, 0x66, 0x69, 0x43, 0x66, 0x66, 0x6C, + 0x43, 0x67, 0x61, 0x6C, 0x43, 0x68, 0x50, 0x61, + 0x43, 0x69, 0x69, 0x69, 0x43, 0x6B, 0x48, 0x7A, + 0x43, 0x6B, 0x50, 0x61, 0x43, 0x6B, 0x6D, 0x32, + 0x43, 0x6B, 0x6D, 0x33, 0x43, 0x6B, 0xCE, 0xA9, + 0x43, 0x6C, 0x6F, 0x67, 0x43, 0x6C, 0xC2, 0xB7, + 0x43, 0x6D, 0x69, 0x6C, 0x43, 0x6D, 0x6D, 0x32, + // Bytes 1c40 - 1c7f + 0x43, 0x6D, 0x6D, 0x33, 0x43, 0x6D, 0x6F, 0x6C, + 0x43, 0x72, 0x61, 0x64, 0x43, 0x76, 0x69, 0x69, + 0x43, 0x78, 0x69, 0x69, 0x43, 0xC2, 0xB0, 0x43, + 0x43, 0xC2, 0xB0, 0x46, 0x43, 0xCA, 0xBC, 0x6E, + 0x43, 0xCE, 0xBC, 0x41, 0x43, 0xCE, 0xBC, 0x46, + 0x43, 0xCE, 0xBC, 0x56, 0x43, 0xCE, 0xBC, 0x57, + 0x43, 0xCE, 0xBC, 0x67, 0x43, 0xCE, 0xBC, 0x6C, + 0x43, 0xCE, 0xBC, 0x6D, 0x43, 0xCE, 0xBC, 0x73, + // Bytes 1c80 - 1cbf + 0x44, 0x28, 0x31, 0x30, 0x29, 0x44, 0x28, 0x31, + 0x31, 0x29, 0x44, 0x28, 0x31, 0x32, 0x29, 0x44, + 0x28, 0x31, 0x33, 0x29, 0x44, 0x28, 0x31, 0x34, + 0x29, 0x44, 0x28, 0x31, 0x35, 0x29, 0x44, 0x28, + 0x31, 0x36, 0x29, 0x44, 0x28, 0x31, 0x37, 0x29, + 0x44, 0x28, 0x31, 0x38, 0x29, 0x44, 0x28, 0x31, + 0x39, 0x29, 0x44, 0x28, 0x32, 0x30, 0x29, 0x44, + 0x30, 0xE7, 0x82, 0xB9, 0x44, 0x31, 0xE2, 0x81, + // Bytes 1cc0 - 1cff + 0x84, 0x44, 0x31, 0xE6, 0x97, 0xA5, 0x44, 0x31, + 0xE6, 0x9C, 0x88, 0x44, 0x31, 0xE7, 0x82, 0xB9, + 0x44, 0x32, 0xE6, 0x97, 0xA5, 0x44, 0x32, 0xE6, + 0x9C, 0x88, 0x44, 0x32, 0xE7, 0x82, 0xB9, 0x44, + 0x33, 0xE6, 0x97, 0xA5, 0x44, 0x33, 0xE6, 0x9C, + 0x88, 0x44, 0x33, 0xE7, 0x82, 0xB9, 0x44, 0x34, + 0xE6, 0x97, 0xA5, 0x44, 0x34, 0xE6, 0x9C, 0x88, + 0x44, 0x34, 0xE7, 0x82, 0xB9, 0x44, 0x35, 0xE6, + // Bytes 1d00 - 1d3f + 0x97, 0xA5, 0x44, 0x35, 0xE6, 0x9C, 0x88, 0x44, + 0x35, 0xE7, 0x82, 0xB9, 0x44, 0x36, 0xE6, 0x97, + 0xA5, 0x44, 0x36, 0xE6, 0x9C, 0x88, 0x44, 0x36, + 0xE7, 0x82, 0xB9, 0x44, 0x37, 0xE6, 0x97, 0xA5, + 0x44, 0x37, 0xE6, 0x9C, 0x88, 0x44, 0x37, 0xE7, + 0x82, 0xB9, 0x44, 0x38, 0xE6, 0x97, 0xA5, 0x44, + 0x38, 0xE6, 0x9C, 0x88, 0x44, 0x38, 0xE7, 0x82, + 0xB9, 0x44, 0x39, 0xE6, 0x97, 0xA5, 0x44, 0x39, + // Bytes 1d40 - 1d7f + 0xE6, 0x9C, 0x88, 0x44, 0x39, 0xE7, 0x82, 0xB9, + 0x44, 0x56, 0x49, 0x49, 0x49, 0x44, 0x61, 0x2E, + 0x6D, 0x2E, 0x44, 0x6B, 0x63, 0x61, 0x6C, 0x44, + 0x70, 0x2E, 0x6D, 0x2E, 0x44, 0x76, 0x69, 0x69, + 0x69, 0x44, 0xD5, 0xA5, 0xD6, 0x82, 0x44, 0xD5, + 0xB4, 0xD5, 0xA5, 0x44, 0xD5, 0xB4, 0xD5, 0xAB, + 0x44, 0xD5, 0xB4, 0xD5, 0xAD, 0x44, 0xD5, 0xB4, + 0xD5, 0xB6, 0x44, 0xD5, 0xBE, 0xD5, 0xB6, 0x44, + // Bytes 1d80 - 1dbf + 0xD7, 0x90, 0xD7, 0x9C, 0x44, 0xD8, 0xA7, 0xD9, + 0xB4, 0x44, 0xD8, 0xA8, 0xD8, 0xAC, 0x44, 0xD8, + 0xA8, 0xD8, 0xAD, 0x44, 0xD8, 0xA8, 0xD8, 0xAE, + 0x44, 0xD8, 0xA8, 0xD8, 0xB1, 0x44, 0xD8, 0xA8, + 0xD8, 0xB2, 0x44, 0xD8, 0xA8, 0xD9, 0x85, 0x44, + 0xD8, 0xA8, 0xD9, 0x86, 0x44, 0xD8, 0xA8, 0xD9, + 0x87, 0x44, 0xD8, 0xA8, 0xD9, 0x89, 0x44, 0xD8, + 0xA8, 0xD9, 0x8A, 0x44, 0xD8, 0xAA, 0xD8, 0xAC, + // Bytes 1dc0 - 1dff + 0x44, 0xD8, 0xAA, 0xD8, 0xAD, 0x44, 0xD8, 0xAA, + 0xD8, 0xAE, 0x44, 0xD8, 0xAA, 0xD8, 0xB1, 0x44, + 0xD8, 0xAA, 0xD8, 0xB2, 0x44, 0xD8, 0xAA, 0xD9, + 0x85, 0x44, 0xD8, 0xAA, 0xD9, 0x86, 0x44, 0xD8, + 0xAA, 0xD9, 0x87, 0x44, 0xD8, 0xAA, 0xD9, 0x89, + 0x44, 0xD8, 0xAA, 0xD9, 0x8A, 0x44, 0xD8, 0xAB, + 0xD8, 0xAC, 0x44, 0xD8, 0xAB, 0xD8, 0xB1, 0x44, + 0xD8, 0xAB, 0xD8, 0xB2, 0x44, 0xD8, 0xAB, 0xD9, + // Bytes 1e00 - 1e3f + 0x85, 0x44, 0xD8, 0xAB, 0xD9, 0x86, 0x44, 0xD8, + 0xAB, 0xD9, 0x87, 0x44, 0xD8, 0xAB, 0xD9, 0x89, + 0x44, 0xD8, 0xAB, 0xD9, 0x8A, 0x44, 0xD8, 0xAC, + 0xD8, 0xAD, 0x44, 0xD8, 0xAC, 0xD9, 0x85, 0x44, + 0xD8, 0xAC, 0xD9, 0x89, 0x44, 0xD8, 0xAC, 0xD9, + 0x8A, 0x44, 0xD8, 0xAD, 0xD8, 0xAC, 0x44, 0xD8, + 0xAD, 0xD9, 0x85, 0x44, 0xD8, 0xAD, 0xD9, 0x89, + 0x44, 0xD8, 0xAD, 0xD9, 0x8A, 0x44, 0xD8, 0xAE, + // Bytes 1e40 - 1e7f + 0xD8, 0xAC, 0x44, 0xD8, 0xAE, 0xD8, 0xAD, 0x44, + 0xD8, 0xAE, 0xD9, 0x85, 0x44, 0xD8, 0xAE, 0xD9, + 0x89, 0x44, 0xD8, 0xAE, 0xD9, 0x8A, 0x44, 0xD8, + 0xB3, 0xD8, 0xAC, 0x44, 0xD8, 0xB3, 0xD8, 0xAD, + 0x44, 0xD8, 0xB3, 0xD8, 0xAE, 0x44, 0xD8, 0xB3, + 0xD8, 0xB1, 0x44, 0xD8, 0xB3, 0xD9, 0x85, 0x44, + 0xD8, 0xB3, 0xD9, 0x87, 0x44, 0xD8, 0xB3, 0xD9, + 0x89, 0x44, 0xD8, 0xB3, 0xD9, 0x8A, 0x44, 0xD8, + // Bytes 1e80 - 1ebf + 0xB4, 0xD8, 0xAC, 0x44, 0xD8, 0xB4, 0xD8, 0xAD, + 0x44, 0xD8, 0xB4, 0xD8, 0xAE, 0x44, 0xD8, 0xB4, + 0xD8, 0xB1, 0x44, 0xD8, 0xB4, 0xD9, 0x85, 0x44, + 0xD8, 0xB4, 0xD9, 0x87, 0x44, 0xD8, 0xB4, 0xD9, + 0x89, 0x44, 0xD8, 0xB4, 0xD9, 0x8A, 0x44, 0xD8, + 0xB5, 0xD8, 0xAD, 0x44, 0xD8, 0xB5, 0xD8, 0xAE, + 0x44, 0xD8, 0xB5, 0xD8, 0xB1, 0x44, 0xD8, 0xB5, + 0xD9, 0x85, 0x44, 0xD8, 0xB5, 0xD9, 0x89, 0x44, + // Bytes 1ec0 - 1eff + 0xD8, 0xB5, 0xD9, 0x8A, 0x44, 0xD8, 0xB6, 0xD8, + 0xAC, 0x44, 0xD8, 0xB6, 0xD8, 0xAD, 0x44, 0xD8, + 0xB6, 0xD8, 0xAE, 0x44, 0xD8, 0xB6, 0xD8, 0xB1, + 0x44, 0xD8, 0xB6, 0xD9, 0x85, 0x44, 0xD8, 0xB6, + 0xD9, 0x89, 0x44, 0xD8, 0xB6, 0xD9, 0x8A, 0x44, + 0xD8, 0xB7, 0xD8, 0xAD, 0x44, 0xD8, 0xB7, 0xD9, + 0x85, 0x44, 0xD8, 0xB7, 0xD9, 0x89, 0x44, 0xD8, + 0xB7, 0xD9, 0x8A, 0x44, 0xD8, 0xB8, 0xD9, 0x85, + // Bytes 1f00 - 1f3f + 0x44, 0xD8, 0xB9, 0xD8, 0xAC, 0x44, 0xD8, 0xB9, + 0xD9, 0x85, 0x44, 0xD8, 0xB9, 0xD9, 0x89, 0x44, + 0xD8, 0xB9, 0xD9, 0x8A, 0x44, 0xD8, 0xBA, 0xD8, + 0xAC, 0x44, 0xD8, 0xBA, 0xD9, 0x85, 0x44, 0xD8, + 0xBA, 0xD9, 0x89, 0x44, 0xD8, 0xBA, 0xD9, 0x8A, + 0x44, 0xD9, 0x81, 0xD8, 0xAC, 0x44, 0xD9, 0x81, + 0xD8, 0xAD, 0x44, 0xD9, 0x81, 0xD8, 0xAE, 0x44, + 0xD9, 0x81, 0xD9, 0x85, 0x44, 0xD9, 0x81, 0xD9, + // Bytes 1f40 - 1f7f + 0x89, 0x44, 0xD9, 0x81, 0xD9, 0x8A, 0x44, 0xD9, + 0x82, 0xD8, 0xAD, 0x44, 0xD9, 0x82, 0xD9, 0x85, + 0x44, 0xD9, 0x82, 0xD9, 0x89, 0x44, 0xD9, 0x82, + 0xD9, 0x8A, 0x44, 0xD9, 0x83, 0xD8, 0xA7, 0x44, + 0xD9, 0x83, 0xD8, 0xAC, 0x44, 0xD9, 0x83, 0xD8, + 0xAD, 0x44, 0xD9, 0x83, 0xD8, 0xAE, 0x44, 0xD9, + 0x83, 0xD9, 0x84, 0x44, 0xD9, 0x83, 0xD9, 0x85, + 0x44, 0xD9, 0x83, 0xD9, 0x89, 0x44, 0xD9, 0x83, + // Bytes 1f80 - 1fbf + 0xD9, 0x8A, 0x44, 0xD9, 0x84, 0xD8, 0xA7, 0x44, + 0xD9, 0x84, 0xD8, 0xAC, 0x44, 0xD9, 0x84, 0xD8, + 0xAD, 0x44, 0xD9, 0x84, 0xD8, 0xAE, 0x44, 0xD9, + 0x84, 0xD9, 0x85, 0x44, 0xD9, 0x84, 0xD9, 0x87, + 0x44, 0xD9, 0x84, 0xD9, 0x89, 0x44, 0xD9, 0x84, + 0xD9, 0x8A, 0x44, 0xD9, 0x85, 0xD8, 0xA7, 0x44, + 0xD9, 0x85, 0xD8, 0xAC, 0x44, 0xD9, 0x85, 0xD8, + 0xAD, 0x44, 0xD9, 0x85, 0xD8, 0xAE, 0x44, 0xD9, + // Bytes 1fc0 - 1fff + 0x85, 0xD9, 0x85, 0x44, 0xD9, 0x85, 0xD9, 0x89, + 0x44, 0xD9, 0x85, 0xD9, 0x8A, 0x44, 0xD9, 0x86, + 0xD8, 0xAC, 0x44, 0xD9, 0x86, 0xD8, 0xAD, 0x44, + 0xD9, 0x86, 0xD8, 0xAE, 0x44, 0xD9, 0x86, 0xD8, + 0xB1, 0x44, 0xD9, 0x86, 0xD8, 0xB2, 0x44, 0xD9, + 0x86, 0xD9, 0x85, 0x44, 0xD9, 0x86, 0xD9, 0x86, + 0x44, 0xD9, 0x86, 0xD9, 0x87, 0x44, 0xD9, 0x86, + 0xD9, 0x89, 0x44, 0xD9, 0x86, 0xD9, 0x8A, 0x44, + // Bytes 2000 - 203f + 0xD9, 0x87, 0xD8, 0xAC, 0x44, 0xD9, 0x87, 0xD9, + 0x85, 0x44, 0xD9, 0x87, 0xD9, 0x89, 0x44, 0xD9, + 0x87, 0xD9, 0x8A, 0x44, 0xD9, 0x88, 0xD9, 0xB4, + 0x44, 0xD9, 0x8A, 0xD8, 0xAC, 0x44, 0xD9, 0x8A, + 0xD8, 0xAD, 0x44, 0xD9, 0x8A, 0xD8, 0xAE, 0x44, + 0xD9, 0x8A, 0xD8, 0xB1, 0x44, 0xD9, 0x8A, 0xD8, + 0xB2, 0x44, 0xD9, 0x8A, 0xD9, 0x85, 0x44, 0xD9, + 0x8A, 0xD9, 0x86, 0x44, 0xD9, 0x8A, 0xD9, 0x87, + // Bytes 2040 - 207f + 0x44, 0xD9, 0x8A, 0xD9, 0x89, 0x44, 0xD9, 0x8A, + 0xD9, 0x8A, 0x44, 0xD9, 0x8A, 0xD9, 0xB4, 0x44, + 0xDB, 0x87, 0xD9, 0xB4, 0x45, 0x28, 0xE1, 0x84, + 0x80, 0x29, 0x45, 0x28, 0xE1, 0x84, 0x82, 0x29, + 0x45, 0x28, 0xE1, 0x84, 0x83, 0x29, 0x45, 0x28, + 0xE1, 0x84, 0x85, 0x29, 0x45, 0x28, 0xE1, 0x84, + 0x86, 0x29, 0x45, 0x28, 0xE1, 0x84, 0x87, 0x29, + 0x45, 0x28, 0xE1, 0x84, 0x89, 0x29, 0x45, 0x28, + // Bytes 2080 - 20bf + 0xE1, 0x84, 0x8B, 0x29, 0x45, 0x28, 0xE1, 0x84, + 0x8C, 0x29, 0x45, 0x28, 0xE1, 0x84, 0x8E, 0x29, + 0x45, 0x28, 0xE1, 0x84, 0x8F, 0x29, 0x45, 0x28, + 0xE1, 0x84, 0x90, 0x29, 0x45, 0x28, 0xE1, 0x84, + 0x91, 0x29, 0x45, 0x28, 0xE1, 0x84, 0x92, 0x29, + 0x45, 0x28, 0xE4, 0xB8, 0x80, 0x29, 0x45, 0x28, + 0xE4, 0xB8, 0x83, 0x29, 0x45, 0x28, 0xE4, 0xB8, + 0x89, 0x29, 0x45, 0x28, 0xE4, 0xB9, 0x9D, 0x29, + // Bytes 20c0 - 20ff + 0x45, 0x28, 0xE4, 0xBA, 0x8C, 0x29, 0x45, 0x28, + 0xE4, 0xBA, 0x94, 0x29, 0x45, 0x28, 0xE4, 0xBB, + 0xA3, 0x29, 0x45, 0x28, 0xE4, 0xBC, 0x81, 0x29, + 0x45, 0x28, 0xE4, 0xBC, 0x91, 0x29, 0x45, 0x28, + 0xE5, 0x85, 0xAB, 0x29, 0x45, 0x28, 0xE5, 0x85, + 0xAD, 0x29, 0x45, 0x28, 0xE5, 0x8A, 0xB4, 0x29, + 0x45, 0x28, 0xE5, 0x8D, 0x81, 0x29, 0x45, 0x28, + 0xE5, 0x8D, 0x94, 0x29, 0x45, 0x28, 0xE5, 0x90, + // Bytes 2100 - 213f + 0x8D, 0x29, 0x45, 0x28, 0xE5, 0x91, 0xBC, 0x29, + 0x45, 0x28, 0xE5, 0x9B, 0x9B, 0x29, 0x45, 0x28, + 0xE5, 0x9C, 0x9F, 0x29, 0x45, 0x28, 0xE5, 0xAD, + 0xA6, 0x29, 0x45, 0x28, 0xE6, 0x97, 0xA5, 0x29, + 0x45, 0x28, 0xE6, 0x9C, 0x88, 0x29, 0x45, 0x28, + 0xE6, 0x9C, 0x89, 0x29, 0x45, 0x28, 0xE6, 0x9C, + 0xA8, 0x29, 0x45, 0x28, 0xE6, 0xA0, 0xAA, 0x29, + 0x45, 0x28, 0xE6, 0xB0, 0xB4, 0x29, 0x45, 0x28, + // Bytes 2140 - 217f + 0xE7, 0x81, 0xAB, 0x29, 0x45, 0x28, 0xE7, 0x89, + 0xB9, 0x29, 0x45, 0x28, 0xE7, 0x9B, 0xA3, 0x29, + 0x45, 0x28, 0xE7, 0xA4, 0xBE, 0x29, 0x45, 0x28, + 0xE7, 0xA5, 0x9D, 0x29, 0x45, 0x28, 0xE7, 0xA5, + 0xAD, 0x29, 0x45, 0x28, 0xE8, 0x87, 0xAA, 0x29, + 0x45, 0x28, 0xE8, 0x87, 0xB3, 0x29, 0x45, 0x28, + 0xE8, 0xB2, 0xA1, 0x29, 0x45, 0x28, 0xE8, 0xB3, + 0x87, 0x29, 0x45, 0x28, 0xE9, 0x87, 0x91, 0x29, + // Bytes 2180 - 21bf + 0x45, 0x30, 0xE2, 0x81, 0x84, 0x33, 0x45, 0x31, + 0x30, 0xE6, 0x97, 0xA5, 0x45, 0x31, 0x30, 0xE6, + 0x9C, 0x88, 0x45, 0x31, 0x30, 0xE7, 0x82, 0xB9, + 0x45, 0x31, 0x31, 0xE6, 0x97, 0xA5, 0x45, 0x31, + 0x31, 0xE6, 0x9C, 0x88, 0x45, 0x31, 0x31, 0xE7, + 0x82, 0xB9, 0x45, 0x31, 0x32, 0xE6, 0x97, 0xA5, + 0x45, 0x31, 0x32, 0xE6, 0x9C, 0x88, 0x45, 0x31, + 0x32, 0xE7, 0x82, 0xB9, 0x45, 0x31, 0x33, 0xE6, + // Bytes 21c0 - 21ff + 0x97, 0xA5, 0x45, 0x31, 0x33, 0xE7, 0x82, 0xB9, + 0x45, 0x31, 0x34, 0xE6, 0x97, 0xA5, 0x45, 0x31, + 0x34, 0xE7, 0x82, 0xB9, 0x45, 0x31, 0x35, 0xE6, + 0x97, 0xA5, 0x45, 0x31, 0x35, 0xE7, 0x82, 0xB9, + 0x45, 0x31, 0x36, 0xE6, 0x97, 0xA5, 0x45, 0x31, + 0x36, 0xE7, 0x82, 0xB9, 0x45, 0x31, 0x37, 0xE6, + 0x97, 0xA5, 0x45, 0x31, 0x37, 0xE7, 0x82, 0xB9, + 0x45, 0x31, 0x38, 0xE6, 0x97, 0xA5, 0x45, 0x31, + // Bytes 2200 - 223f + 0x38, 0xE7, 0x82, 0xB9, 0x45, 0x31, 0x39, 0xE6, + 0x97, 0xA5, 0x45, 0x31, 0x39, 0xE7, 0x82, 0xB9, + 0x45, 0x31, 0xE2, 0x81, 0x84, 0x32, 0x45, 0x31, + 0xE2, 0x81, 0x84, 0x33, 0x45, 0x31, 0xE2, 0x81, + 0x84, 0x34, 0x45, 0x31, 0xE2, 0x81, 0x84, 0x35, + 0x45, 0x31, 0xE2, 0x81, 0x84, 0x36, 0x45, 0x31, + 0xE2, 0x81, 0x84, 0x37, 0x45, 0x31, 0xE2, 0x81, + 0x84, 0x38, 0x45, 0x31, 0xE2, 0x81, 0x84, 0x39, + // Bytes 2240 - 227f + 0x45, 0x32, 0x30, 0xE6, 0x97, 0xA5, 0x45, 0x32, + 0x30, 0xE7, 0x82, 0xB9, 0x45, 0x32, 0x31, 0xE6, + 0x97, 0xA5, 0x45, 0x32, 0x31, 0xE7, 0x82, 0xB9, + 0x45, 0x32, 0x32, 0xE6, 0x97, 0xA5, 0x45, 0x32, + 0x32, 0xE7, 0x82, 0xB9, 0x45, 0x32, 0x33, 0xE6, + 0x97, 0xA5, 0x45, 0x32, 0x33, 0xE7, 0x82, 0xB9, + 0x45, 0x32, 0x34, 0xE6, 0x97, 0xA5, 0x45, 0x32, + 0x34, 0xE7, 0x82, 0xB9, 0x45, 0x32, 0x35, 0xE6, + // Bytes 2280 - 22bf + 0x97, 0xA5, 0x45, 0x32, 0x36, 0xE6, 0x97, 0xA5, + 0x45, 0x32, 0x37, 0xE6, 0x97, 0xA5, 0x45, 0x32, + 0x38, 0xE6, 0x97, 0xA5, 0x45, 0x32, 0x39, 0xE6, + 0x97, 0xA5, 0x45, 0x32, 0xE2, 0x81, 0x84, 0x33, + 0x45, 0x32, 0xE2, 0x81, 0x84, 0x35, 0x45, 0x33, + 0x30, 0xE6, 0x97, 0xA5, 0x45, 0x33, 0x31, 0xE6, + 0x97, 0xA5, 0x45, 0x33, 0xE2, 0x81, 0x84, 0x34, + 0x45, 0x33, 0xE2, 0x81, 0x84, 0x35, 0x45, 0x33, + // Bytes 22c0 - 22ff + 0xE2, 0x81, 0x84, 0x38, 0x45, 0x34, 0xE2, 0x81, + 0x84, 0x35, 0x45, 0x35, 0xE2, 0x81, 0x84, 0x36, + 0x45, 0x35, 0xE2, 0x81, 0x84, 0x38, 0x45, 0x37, + 0xE2, 0x81, 0x84, 0x38, 0x45, 0x41, 0xE2, 0x88, + 0x95, 0x6D, 0x45, 0x56, 0xE2, 0x88, 0x95, 0x6D, + 0x45, 0x6D, 0xE2, 0x88, 0x95, 0x73, 0x46, 0x31, + 0xE2, 0x81, 0x84, 0x31, 0x30, 0x46, 0x43, 0xE2, + 0x88, 0x95, 0x6B, 0x67, 0x46, 0x6D, 0xE2, 0x88, + // Bytes 2300 - 233f + 0x95, 0x73, 0x32, 0x46, 0xD8, 0xA8, 0xD8, 0xAD, + 0xD9, 0x8A, 0x46, 0xD8, 0xA8, 0xD8, 0xAE, 0xD9, + 0x8A, 0x46, 0xD8, 0xAA, 0xD8, 0xAC, 0xD9, 0x85, + 0x46, 0xD8, 0xAA, 0xD8, 0xAC, 0xD9, 0x89, 0x46, + 0xD8, 0xAA, 0xD8, 0xAC, 0xD9, 0x8A, 0x46, 0xD8, + 0xAA, 0xD8, 0xAD, 0xD8, 0xAC, 0x46, 0xD8, 0xAA, + 0xD8, 0xAD, 0xD9, 0x85, 0x46, 0xD8, 0xAA, 0xD8, + 0xAE, 0xD9, 0x85, 0x46, 0xD8, 0xAA, 0xD8, 0xAE, + // Bytes 2340 - 237f + 0xD9, 0x89, 0x46, 0xD8, 0xAA, 0xD8, 0xAE, 0xD9, + 0x8A, 0x46, 0xD8, 0xAA, 0xD9, 0x85, 0xD8, 0xAC, + 0x46, 0xD8, 0xAA, 0xD9, 0x85, 0xD8, 0xAD, 0x46, + 0xD8, 0xAA, 0xD9, 0x85, 0xD8, 0xAE, 0x46, 0xD8, + 0xAA, 0xD9, 0x85, 0xD9, 0x89, 0x46, 0xD8, 0xAA, + 0xD9, 0x85, 0xD9, 0x8A, 0x46, 0xD8, 0xAC, 0xD8, + 0xAD, 0xD9, 0x89, 0x46, 0xD8, 0xAC, 0xD8, 0xAD, + 0xD9, 0x8A, 0x46, 0xD8, 0xAC, 0xD9, 0x85, 0xD8, + // Bytes 2380 - 23bf + 0xAD, 0x46, 0xD8, 0xAC, 0xD9, 0x85, 0xD9, 0x89, + 0x46, 0xD8, 0xAC, 0xD9, 0x85, 0xD9, 0x8A, 0x46, + 0xD8, 0xAD, 0xD8, 0xAC, 0xD9, 0x8A, 0x46, 0xD8, + 0xAD, 0xD9, 0x85, 0xD9, 0x89, 0x46, 0xD8, 0xAD, + 0xD9, 0x85, 0xD9, 0x8A, 0x46, 0xD8, 0xB3, 0xD8, + 0xAC, 0xD8, 0xAD, 0x46, 0xD8, 0xB3, 0xD8, 0xAC, + 0xD9, 0x89, 0x46, 0xD8, 0xB3, 0xD8, 0xAD, 0xD8, + 0xAC, 0x46, 0xD8, 0xB3, 0xD8, 0xAE, 0xD9, 0x89, + // Bytes 23c0 - 23ff + 0x46, 0xD8, 0xB3, 0xD8, 0xAE, 0xD9, 0x8A, 0x46, + 0xD8, 0xB3, 0xD9, 0x85, 0xD8, 0xAC, 0x46, 0xD8, + 0xB3, 0xD9, 0x85, 0xD8, 0xAD, 0x46, 0xD8, 0xB3, + 0xD9, 0x85, 0xD9, 0x85, 0x46, 0xD8, 0xB4, 0xD8, + 0xAC, 0xD9, 0x8A, 0x46, 0xD8, 0xB4, 0xD8, 0xAD, + 0xD9, 0x85, 0x46, 0xD8, 0xB4, 0xD8, 0xAD, 0xD9, + 0x8A, 0x46, 0xD8, 0xB4, 0xD9, 0x85, 0xD8, 0xAE, + 0x46, 0xD8, 0xB4, 0xD9, 0x85, 0xD9, 0x85, 0x46, + // Bytes 2400 - 243f + 0xD8, 0xB5, 0xD8, 0xAD, 0xD8, 0xAD, 0x46, 0xD8, + 0xB5, 0xD8, 0xAD, 0xD9, 0x8A, 0x46, 0xD8, 0xB5, + 0xD9, 0x84, 0xD9, 0x89, 0x46, 0xD8, 0xB5, 0xD9, + 0x84, 0xDB, 0x92, 0x46, 0xD8, 0xB5, 0xD9, 0x85, + 0xD9, 0x85, 0x46, 0xD8, 0xB6, 0xD8, 0xAD, 0xD9, + 0x89, 0x46, 0xD8, 0xB6, 0xD8, 0xAD, 0xD9, 0x8A, + 0x46, 0xD8, 0xB6, 0xD8, 0xAE, 0xD9, 0x85, 0x46, + 0xD8, 0xB7, 0xD9, 0x85, 0xD8, 0xAD, 0x46, 0xD8, + // Bytes 2440 - 247f + 0xB7, 0xD9, 0x85, 0xD9, 0x85, 0x46, 0xD8, 0xB7, + 0xD9, 0x85, 0xD9, 0x8A, 0x46, 0xD8, 0xB9, 0xD8, + 0xAC, 0xD9, 0x85, 0x46, 0xD8, 0xB9, 0xD9, 0x85, + 0xD9, 0x85, 0x46, 0xD8, 0xB9, 0xD9, 0x85, 0xD9, + 0x89, 0x46, 0xD8, 0xB9, 0xD9, 0x85, 0xD9, 0x8A, + 0x46, 0xD8, 0xBA, 0xD9, 0x85, 0xD9, 0x85, 0x46, + 0xD8, 0xBA, 0xD9, 0x85, 0xD9, 0x89, 0x46, 0xD8, + 0xBA, 0xD9, 0x85, 0xD9, 0x8A, 0x46, 0xD9, 0x81, + // Bytes 2480 - 24bf + 0xD8, 0xAE, 0xD9, 0x85, 0x46, 0xD9, 0x81, 0xD9, + 0x85, 0xD9, 0x8A, 0x46, 0xD9, 0x82, 0xD9, 0x84, + 0xDB, 0x92, 0x46, 0xD9, 0x82, 0xD9, 0x85, 0xD8, + 0xAD, 0x46, 0xD9, 0x82, 0xD9, 0x85, 0xD9, 0x85, + 0x46, 0xD9, 0x82, 0xD9, 0x85, 0xD9, 0x8A, 0x46, + 0xD9, 0x83, 0xD9, 0x85, 0xD9, 0x85, 0x46, 0xD9, + 0x83, 0xD9, 0x85, 0xD9, 0x8A, 0x46, 0xD9, 0x84, + 0xD8, 0xAC, 0xD8, 0xAC, 0x46, 0xD9, 0x84, 0xD8, + // Bytes 24c0 - 24ff + 0xAC, 0xD9, 0x85, 0x46, 0xD9, 0x84, 0xD8, 0xAC, + 0xD9, 0x8A, 0x46, 0xD9, 0x84, 0xD8, 0xAD, 0xD9, + 0x85, 0x46, 0xD9, 0x84, 0xD8, 0xAD, 0xD9, 0x89, + 0x46, 0xD9, 0x84, 0xD8, 0xAD, 0xD9, 0x8A, 0x46, + 0xD9, 0x84, 0xD8, 0xAE, 0xD9, 0x85, 0x46, 0xD9, + 0x84, 0xD9, 0x85, 0xD8, 0xAD, 0x46, 0xD9, 0x84, + 0xD9, 0x85, 0xD9, 0x8A, 0x46, 0xD9, 0x85, 0xD8, + 0xAC, 0xD8, 0xAD, 0x46, 0xD9, 0x85, 0xD8, 0xAC, + // Bytes 2500 - 253f + 0xD8, 0xAE, 0x46, 0xD9, 0x85, 0xD8, 0xAC, 0xD9, + 0x85, 0x46, 0xD9, 0x85, 0xD8, 0xAC, 0xD9, 0x8A, + 0x46, 0xD9, 0x85, 0xD8, 0xAD, 0xD8, 0xAC, 0x46, + 0xD9, 0x85, 0xD8, 0xAD, 0xD9, 0x85, 0x46, 0xD9, + 0x85, 0xD8, 0xAD, 0xD9, 0x8A, 0x46, 0xD9, 0x85, + 0xD8, 0xAE, 0xD8, 0xAC, 0x46, 0xD9, 0x85, 0xD8, + 0xAE, 0xD9, 0x85, 0x46, 0xD9, 0x85, 0xD8, 0xAE, + 0xD9, 0x8A, 0x46, 0xD9, 0x85, 0xD9, 0x85, 0xD9, + // Bytes 2540 - 257f + 0x8A, 0x46, 0xD9, 0x86, 0xD8, 0xAC, 0xD8, 0xAD, + 0x46, 0xD9, 0x86, 0xD8, 0xAC, 0xD9, 0x85, 0x46, + 0xD9, 0x86, 0xD8, 0xAC, 0xD9, 0x89, 0x46, 0xD9, + 0x86, 0xD8, 0xAC, 0xD9, 0x8A, 0x46, 0xD9, 0x86, + 0xD8, 0xAD, 0xD9, 0x85, 0x46, 0xD9, 0x86, 0xD8, + 0xAD, 0xD9, 0x89, 0x46, 0xD9, 0x86, 0xD8, 0xAD, + 0xD9, 0x8A, 0x46, 0xD9, 0x86, 0xD9, 0x85, 0xD9, + 0x89, 0x46, 0xD9, 0x86, 0xD9, 0x85, 0xD9, 0x8A, + // Bytes 2580 - 25bf + 0x46, 0xD9, 0x87, 0xD9, 0x85, 0xD8, 0xAC, 0x46, + 0xD9, 0x87, 0xD9, 0x85, 0xD9, 0x85, 0x46, 0xD9, + 0x8A, 0xD8, 0xAC, 0xD9, 0x8A, 0x46, 0xD9, 0x8A, + 0xD8, 0xAD, 0xD9, 0x8A, 0x46, 0xD9, 0x8A, 0xD9, + 0x85, 0xD9, 0x85, 0x46, 0xD9, 0x8A, 0xD9, 0x85, + 0xD9, 0x8A, 0x46, 0xD9, 0x8A, 0xD9, 0x94, 0xD8, + 0xA7, 0x46, 0xD9, 0x8A, 0xD9, 0x94, 0xD8, 0xAC, + 0x46, 0xD9, 0x8A, 0xD9, 0x94, 0xD8, 0xAD, 0x46, + // Bytes 25c0 - 25ff + 0xD9, 0x8A, 0xD9, 0x94, 0xD8, 0xAE, 0x46, 0xD9, + 0x8A, 0xD9, 0x94, 0xD8, 0xB1, 0x46, 0xD9, 0x8A, + 0xD9, 0x94, 0xD8, 0xB2, 0x46, 0xD9, 0x8A, 0xD9, + 0x94, 0xD9, 0x85, 0x46, 0xD9, 0x8A, 0xD9, 0x94, + 0xD9, 0x86, 0x46, 0xD9, 0x8A, 0xD9, 0x94, 0xD9, + 0x87, 0x46, 0xD9, 0x8A, 0xD9, 0x94, 0xD9, 0x88, + 0x46, 0xD9, 0x8A, 0xD9, 0x94, 0xD9, 0x89, 0x46, + 0xD9, 0x8A, 0xD9, 0x94, 0xD9, 0x8A, 0x46, 0xD9, + // Bytes 2600 - 263f + 0x8A, 0xD9, 0x94, 0xDB, 0x86, 0x46, 0xD9, 0x8A, + 0xD9, 0x94, 0xDB, 0x87, 0x46, 0xD9, 0x8A, 0xD9, + 0x94, 0xDB, 0x88, 0x46, 0xD9, 0x8A, 0xD9, 0x94, + 0xDB, 0x90, 0x46, 0xD9, 0x8A, 0xD9, 0x94, 0xDB, + 0x95, 0x46, 0xE0, 0xB9, 0x8D, 0xE0, 0xB8, 0xB2, + 0x46, 0xE0, 0xBA, 0xAB, 0xE0, 0xBA, 0x99, 0x46, + 0xE0, 0xBA, 0xAB, 0xE0, 0xBA, 0xA1, 0x46, 0xE0, + 0xBB, 0x8D, 0xE0, 0xBA, 0xB2, 0x46, 0xE0, 0xBD, + // Bytes 2640 - 267f + 0x80, 0xE0, 0xBE, 0xB5, 0x46, 0xE0, 0xBD, 0x82, + 0xE0, 0xBE, 0xB7, 0x46, 0xE0, 0xBD, 0x8C, 0xE0, + 0xBE, 0xB7, 0x46, 0xE0, 0xBD, 0x91, 0xE0, 0xBE, + 0xB7, 0x46, 0xE0, 0xBD, 0x96, 0xE0, 0xBE, 0xB7, + 0x46, 0xE0, 0xBD, 0x9B, 0xE0, 0xBE, 0xB7, 0x46, + 0xE0, 0xBE, 0x90, 0xE0, 0xBE, 0xB5, 0x46, 0xE0, + 0xBE, 0x92, 0xE0, 0xBE, 0xB7, 0x46, 0xE0, 0xBE, + 0x9C, 0xE0, 0xBE, 0xB7, 0x46, 0xE0, 0xBE, 0xA1, + // Bytes 2680 - 26bf + 0xE0, 0xBE, 0xB7, 0x46, 0xE0, 0xBE, 0xA6, 0xE0, + 0xBE, 0xB7, 0x46, 0xE0, 0xBE, 0xAB, 0xE0, 0xBE, + 0xB7, 0x46, 0xE2, 0x80, 0xB2, 0xE2, 0x80, 0xB2, + 0x46, 0xE2, 0x80, 0xB5, 0xE2, 0x80, 0xB5, 0x46, + 0xE2, 0x88, 0xAB, 0xE2, 0x88, 0xAB, 0x46, 0xE2, + 0x88, 0xAE, 0xE2, 0x88, 0xAE, 0x46, 0xE3, 0x81, + 0xBB, 0xE3, 0x81, 0x8B, 0x46, 0xE3, 0x82, 0x88, + 0xE3, 0x82, 0x8A, 0x46, 0xE3, 0x82, 0xAD, 0xE3, + // Bytes 26c0 - 26ff + 0x83, 0xAD, 0x46, 0xE3, 0x82, 0xB3, 0xE3, 0x82, + 0xB3, 0x46, 0xE3, 0x82, 0xB3, 0xE3, 0x83, 0x88, + 0x46, 0xE3, 0x83, 0x88, 0xE3, 0x83, 0xB3, 0x46, + 0xE3, 0x83, 0x8A, 0xE3, 0x83, 0x8E, 0x46, 0xE3, + 0x83, 0x9B, 0xE3, 0x83, 0xB3, 0x46, 0xE3, 0x83, + 0x9F, 0xE3, 0x83, 0xAA, 0x46, 0xE3, 0x83, 0xAA, + 0xE3, 0x83, 0xA9, 0x46, 0xE3, 0x83, 0xAC, 0xE3, + 0x83, 0xA0, 0x46, 0xE5, 0xA4, 0xA7, 0xE6, 0xAD, + // Bytes 2700 - 273f + 0xA3, 0x46, 0xE5, 0xB9, 0xB3, 0xE6, 0x88, 0x90, + 0x46, 0xE6, 0x98, 0x8E, 0xE6, 0xB2, 0xBB, 0x46, + 0xE6, 0x98, 0xAD, 0xE5, 0x92, 0x8C, 0x47, 0x72, + 0x61, 0x64, 0xE2, 0x88, 0x95, 0x73, 0x47, 0xE3, + 0x80, 0x94, 0x53, 0xE3, 0x80, 0x95, 0x48, 0x28, + 0xE1, 0x84, 0x80, 0xE1, 0x85, 0xA1, 0x29, 0x48, + 0x28, 0xE1, 0x84, 0x82, 0xE1, 0x85, 0xA1, 0x29, + 0x48, 0x28, 0xE1, 0x84, 0x83, 0xE1, 0x85, 0xA1, + // Bytes 2740 - 277f + 0x29, 0x48, 0x28, 0xE1, 0x84, 0x85, 0xE1, 0x85, + 0xA1, 0x29, 0x48, 0x28, 0xE1, 0x84, 0x86, 0xE1, + 0x85, 0xA1, 0x29, 0x48, 0x28, 0xE1, 0x84, 0x87, + 0xE1, 0x85, 0xA1, 0x29, 0x48, 0x28, 0xE1, 0x84, + 0x89, 0xE1, 0x85, 0xA1, 0x29, 0x48, 0x28, 0xE1, + 0x84, 0x8B, 0xE1, 0x85, 0xA1, 0x29, 0x48, 0x28, + 0xE1, 0x84, 0x8C, 0xE1, 0x85, 0xA1, 0x29, 0x48, + 0x28, 0xE1, 0x84, 0x8C, 0xE1, 0x85, 0xAE, 0x29, + // Bytes 2780 - 27bf + 0x48, 0x28, 0xE1, 0x84, 0x8E, 0xE1, 0x85, 0xA1, + 0x29, 0x48, 0x28, 0xE1, 0x84, 0x8F, 0xE1, 0x85, + 0xA1, 0x29, 0x48, 0x28, 0xE1, 0x84, 0x90, 0xE1, + 0x85, 0xA1, 0x29, 0x48, 0x28, 0xE1, 0x84, 0x91, + 0xE1, 0x85, 0xA1, 0x29, 0x48, 0x28, 0xE1, 0x84, + 0x92, 0xE1, 0x85, 0xA1, 0x29, 0x48, 0x72, 0x61, + 0x64, 0xE2, 0x88, 0x95, 0x73, 0x32, 0x48, 0xD8, + 0xA7, 0xD9, 0x83, 0xD8, 0xA8, 0xD8, 0xB1, 0x48, + // Bytes 27c0 - 27ff + 0xD8, 0xA7, 0xD9, 0x84, 0xD9, 0x84, 0xD9, 0x87, + 0x48, 0xD8, 0xB1, 0xD8, 0xB3, 0xD9, 0x88, 0xD9, + 0x84, 0x48, 0xD8, 0xB1, 0xDB, 0x8C, 0xD8, 0xA7, + 0xD9, 0x84, 0x48, 0xD8, 0xB5, 0xD9, 0x84, 0xD8, + 0xB9, 0xD9, 0x85, 0x48, 0xD8, 0xB9, 0xD9, 0x84, + 0xD9, 0x8A, 0xD9, 0x87, 0x48, 0xD9, 0x85, 0xD8, + 0xAD, 0xD9, 0x85, 0xD8, 0xAF, 0x48, 0xD9, 0x88, + 0xD8, 0xB3, 0xD9, 0x84, 0xD9, 0x85, 0x49, 0xE2, + // Bytes 2800 - 283f + 0x80, 0xB2, 0xE2, 0x80, 0xB2, 0xE2, 0x80, 0xB2, + 0x49, 0xE2, 0x80, 0xB5, 0xE2, 0x80, 0xB5, 0xE2, + 0x80, 0xB5, 0x49, 0xE2, 0x88, 0xAB, 0xE2, 0x88, + 0xAB, 0xE2, 0x88, 0xAB, 0x49, 0xE2, 0x88, 0xAE, + 0xE2, 0x88, 0xAE, 0xE2, 0x88, 0xAE, 0x49, 0xE3, + 0x80, 0x94, 0xE4, 0xB8, 0x89, 0xE3, 0x80, 0x95, + 0x49, 0xE3, 0x80, 0x94, 0xE4, 0xBA, 0x8C, 0xE3, + 0x80, 0x95, 0x49, 0xE3, 0x80, 0x94, 0xE5, 0x8B, + // Bytes 2840 - 287f + 0x9D, 0xE3, 0x80, 0x95, 0x49, 0xE3, 0x80, 0x94, + 0xE5, 0xAE, 0x89, 0xE3, 0x80, 0x95, 0x49, 0xE3, + 0x80, 0x94, 0xE6, 0x89, 0x93, 0xE3, 0x80, 0x95, + 0x49, 0xE3, 0x80, 0x94, 0xE6, 0x95, 0x97, 0xE3, + 0x80, 0x95, 0x49, 0xE3, 0x80, 0x94, 0xE6, 0x9C, + 0xAC, 0xE3, 0x80, 0x95, 0x49, 0xE3, 0x80, 0x94, + 0xE7, 0x82, 0xB9, 0xE3, 0x80, 0x95, 0x49, 0xE3, + 0x80, 0x94, 0xE7, 0x9B, 0x97, 0xE3, 0x80, 0x95, + // Bytes 2880 - 28bf + 0x49, 0xE3, 0x82, 0xA2, 0xE3, 0x83, 0xBC, 0xE3, + 0x83, 0xAB, 0x49, 0xE3, 0x82, 0xA4, 0xE3, 0x83, + 0xB3, 0xE3, 0x83, 0x81, 0x49, 0xE3, 0x82, 0xA6, + 0xE3, 0x82, 0xA9, 0xE3, 0x83, 0xB3, 0x49, 0xE3, + 0x82, 0xAA, 0xE3, 0x83, 0xB3, 0xE3, 0x82, 0xB9, + 0x49, 0xE3, 0x82, 0xAA, 0xE3, 0x83, 0xBC, 0xE3, + 0x83, 0xA0, 0x49, 0xE3, 0x82, 0xAB, 0xE3, 0x82, + 0xA4, 0xE3, 0x83, 0xAA, 0x49, 0xE3, 0x82, 0xB1, + // Bytes 28c0 - 28ff + 0xE3, 0x83, 0xBC, 0xE3, 0x82, 0xB9, 0x49, 0xE3, + 0x82, 0xB3, 0xE3, 0x83, 0xAB, 0xE3, 0x83, 0x8A, + 0x49, 0xE3, 0x82, 0xBB, 0xE3, 0x83, 0xB3, 0xE3, + 0x83, 0x81, 0x49, 0xE3, 0x82, 0xBB, 0xE3, 0x83, + 0xB3, 0xE3, 0x83, 0x88, 0x49, 0xE3, 0x83, 0x86, + 0xE3, 0x82, 0x99, 0xE3, 0x82, 0xB7, 0x49, 0xE3, + 0x83, 0x88, 0xE3, 0x82, 0x99, 0xE3, 0x83, 0xAB, + 0x49, 0xE3, 0x83, 0x8E, 0xE3, 0x83, 0x83, 0xE3, + // Bytes 2900 - 293f + 0x83, 0x88, 0x49, 0xE3, 0x83, 0x8F, 0xE3, 0x82, + 0xA4, 0xE3, 0x83, 0x84, 0x49, 0xE3, 0x83, 0x92, + 0xE3, 0x82, 0x99, 0xE3, 0x83, 0xAB, 0x49, 0xE3, + 0x83, 0x92, 0xE3, 0x82, 0x9A, 0xE3, 0x82, 0xB3, + 0x49, 0xE3, 0x83, 0x95, 0xE3, 0x83, 0xA9, 0xE3, + 0x83, 0xB3, 0x49, 0xE3, 0x83, 0x98, 0xE3, 0x82, + 0x9A, 0xE3, 0x82, 0xBD, 0x49, 0xE3, 0x83, 0x98, + 0xE3, 0x83, 0xAB, 0xE3, 0x83, 0x84, 0x49, 0xE3, + // Bytes 2940 - 297f + 0x83, 0x9B, 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0xAB, + 0x49, 0xE3, 0x83, 0x9B, 0xE3, 0x83, 0xBC, 0xE3, + 0x83, 0xB3, 0x49, 0xE3, 0x83, 0x9E, 0xE3, 0x82, + 0xA4, 0xE3, 0x83, 0xAB, 0x49, 0xE3, 0x83, 0x9E, + 0xE3, 0x83, 0x83, 0xE3, 0x83, 0x8F, 0x49, 0xE3, + 0x83, 0x9E, 0xE3, 0x83, 0xAB, 0xE3, 0x82, 0xAF, + 0x49, 0xE3, 0x83, 0xA4, 0xE3, 0x83, 0xBC, 0xE3, + 0x83, 0xAB, 0x49, 0xE3, 0x83, 0xA6, 0xE3, 0x82, + // Bytes 2980 - 29bf + 0xA2, 0xE3, 0x83, 0xB3, 0x49, 0xE3, 0x83, 0xAF, + 0xE3, 0x83, 0x83, 0xE3, 0x83, 0x88, 0x4C, 0xE2, + 0x80, 0xB2, 0xE2, 0x80, 0xB2, 0xE2, 0x80, 0xB2, + 0xE2, 0x80, 0xB2, 0x4C, 0xE2, 0x88, 0xAB, 0xE2, + 0x88, 0xAB, 0xE2, 0x88, 0xAB, 0xE2, 0x88, 0xAB, + 0x4C, 0xE3, 0x82, 0xA2, 0xE3, 0x83, 0xAB, 0xE3, + 0x83, 0x95, 0xE3, 0x82, 0xA1, 0x4C, 0xE3, 0x82, + 0xA8, 0xE3, 0x83, 0xBC, 0xE3, 0x82, 0xAB, 0xE3, + // Bytes 29c0 - 29ff + 0x83, 0xBC, 0x4C, 0xE3, 0x82, 0xAB, 0xE3, 0x82, + 0x99, 0xE3, 0x83, 0xAD, 0xE3, 0x83, 0xB3, 0x4C, + 0xE3, 0x82, 0xAB, 0xE3, 0x82, 0x99, 0xE3, 0x83, + 0xB3, 0xE3, 0x83, 0x9E, 0x4C, 0xE3, 0x82, 0xAB, + 0xE3, 0x83, 0xA9, 0xE3, 0x83, 0x83, 0xE3, 0x83, + 0x88, 0x4C, 0xE3, 0x82, 0xAB, 0xE3, 0x83, 0xAD, + 0xE3, 0x83, 0xAA, 0xE3, 0x83, 0xBC, 0x4C, 0xE3, + 0x82, 0xAD, 0xE3, 0x82, 0x99, 0xE3, 0x83, 0x8B, + // Bytes 2a00 - 2a3f + 0xE3, 0x83, 0xBC, 0x4C, 0xE3, 0x82, 0xAD, 0xE3, + 0x83, 0xA5, 0xE3, 0x83, 0xAA, 0xE3, 0x83, 0xBC, + 0x4C, 0xE3, 0x82, 0xAF, 0xE3, 0x82, 0x99, 0xE3, + 0x83, 0xA9, 0xE3, 0x83, 0xA0, 0x4C, 0xE3, 0x82, + 0xAF, 0xE3, 0x83, 0xAD, 0xE3, 0x83, 0xBC, 0xE3, + 0x83, 0x8D, 0x4C, 0xE3, 0x82, 0xB5, 0xE3, 0x82, + 0xA4, 0xE3, 0x82, 0xAF, 0xE3, 0x83, 0xAB, 0x4C, + 0xE3, 0x82, 0xBF, 0xE3, 0x82, 0x99, 0xE3, 0x83, + // Bytes 2a40 - 2a7f + 0xBC, 0xE3, 0x82, 0xB9, 0x4C, 0xE3, 0x83, 0x8F, + 0xE3, 0x82, 0x9A, 0xE3, 0x83, 0xBC, 0xE3, 0x83, + 0x84, 0x4C, 0xE3, 0x83, 0x92, 0xE3, 0x82, 0x9A, + 0xE3, 0x82, 0xAF, 0xE3, 0x83, 0xAB, 0x4C, 0xE3, + 0x83, 0x95, 0xE3, 0x82, 0xA3, 0xE3, 0x83, 0xBC, + 0xE3, 0x83, 0x88, 0x4C, 0xE3, 0x83, 0x98, 0xE3, + 0x82, 0x99, 0xE3, 0x83, 0xBC, 0xE3, 0x82, 0xBF, + 0x4C, 0xE3, 0x83, 0x98, 0xE3, 0x82, 0x9A, 0xE3, + // Bytes 2a80 - 2abf + 0x83, 0x8B, 0xE3, 0x83, 0x92, 0x4C, 0xE3, 0x83, + 0x98, 0xE3, 0x82, 0x9A, 0xE3, 0x83, 0xB3, 0xE3, + 0x82, 0xB9, 0x4C, 0xE3, 0x83, 0x9B, 0xE3, 0x82, + 0x99, 0xE3, 0x83, 0xAB, 0xE3, 0x83, 0x88, 0x4C, + 0xE3, 0x83, 0x9E, 0xE3, 0x82, 0xA4, 0xE3, 0x82, + 0xAF, 0xE3, 0x83, 0xAD, 0x4C, 0xE3, 0x83, 0x9F, + 0xE3, 0x82, 0xAF, 0xE3, 0x83, 0xAD, 0xE3, 0x83, + 0xB3, 0x4C, 0xE3, 0x83, 0xA1, 0xE3, 0x83, 0xBC, + // Bytes 2ac0 - 2aff + 0xE3, 0x83, 0x88, 0xE3, 0x83, 0xAB, 0x4C, 0xE3, + 0x83, 0xAA, 0xE3, 0x83, 0x83, 0xE3, 0x83, 0x88, + 0xE3, 0x83, 0xAB, 0x4C, 0xE3, 0x83, 0xAB, 0xE3, + 0x83, 0x92, 0xE3, 0x82, 0x9A, 0xE3, 0x83, 0xBC, + 0x4C, 0xE6, 0xA0, 0xAA, 0xE5, 0xBC, 0x8F, 0xE4, + 0xBC, 0x9A, 0xE7, 0xA4, 0xBE, 0x4E, 0x28, 0xE1, + 0x84, 0x8B, 0xE1, 0x85, 0xA9, 0xE1, 0x84, 0x92, + 0xE1, 0x85, 0xAE, 0x29, 0x4F, 0xD8, 0xAC, 0xD9, + // Bytes 2b00 - 2b3f + 0x84, 0x20, 0xD8, 0xAC, 0xD9, 0x84, 0xD8, 0xA7, + 0xD9, 0x84, 0xD9, 0x87, 0x4F, 0xE3, 0x82, 0xA2, + 0xE3, 0x83, 0x8F, 0xE3, 0x82, 0x9A, 0xE3, 0x83, + 0xBC, 0xE3, 0x83, 0x88, 0x4F, 0xE3, 0x82, 0xA2, + 0xE3, 0x83, 0xB3, 0xE3, 0x83, 0x98, 0xE3, 0x82, + 0x9A, 0xE3, 0x82, 0xA2, 0x4F, 0xE3, 0x82, 0xAD, + 0xE3, 0x83, 0xAD, 0xE3, 0x83, 0xAF, 0xE3, 0x83, + 0x83, 0xE3, 0x83, 0x88, 0x4F, 0xE3, 0x82, 0xB5, + // Bytes 2b40 - 2b7f + 0xE3, 0x83, 0xB3, 0xE3, 0x83, 0x81, 0xE3, 0x83, + 0xBC, 0xE3, 0x83, 0xA0, 0x4F, 0xE3, 0x83, 0x8F, + 0xE3, 0x82, 0x99, 0xE3, 0x83, 0xBC, 0xE3, 0x83, + 0xAC, 0xE3, 0x83, 0xAB, 0x4F, 0xE3, 0x83, 0x98, + 0xE3, 0x82, 0xAF, 0xE3, 0x82, 0xBF, 0xE3, 0x83, + 0xBC, 0xE3, 0x83, 0xAB, 0x4F, 0xE3, 0x83, 0x9B, + 0xE3, 0x82, 0x9A, 0xE3, 0x82, 0xA4, 0xE3, 0x83, + 0xB3, 0xE3, 0x83, 0x88, 0x4F, 0xE3, 0x83, 0x9E, + // Bytes 2b80 - 2bbf + 0xE3, 0x83, 0xB3, 0xE3, 0x82, 0xB7, 0xE3, 0x83, + 0xA7, 0xE3, 0x83, 0xB3, 0x4F, 0xE3, 0x83, 0xA1, + 0xE3, 0x82, 0xAB, 0xE3, 0x82, 0x99, 0xE3, 0x83, + 0x88, 0xE3, 0x83, 0xB3, 0x4F, 0xE3, 0x83, 0xAB, + 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0x95, 0xE3, 0x82, + 0x99, 0xE3, 0x83, 0xAB, 0x51, 0x28, 0xE1, 0x84, + 0x8B, 0xE1, 0x85, 0xA9, 0xE1, 0x84, 0x8C, 0xE1, + 0x85, 0xA5, 0xE1, 0x86, 0xAB, 0x29, 0x52, 0xE3, + // Bytes 2bc0 - 2bff + 0x82, 0xAD, 0xE3, 0x82, 0x99, 0xE3, 0x83, 0xAB, + 0xE3, 0x82, 0xBF, 0xE3, 0x82, 0x99, 0xE3, 0x83, + 0xBC, 0x52, 0xE3, 0x82, 0xAD, 0xE3, 0x83, 0xAD, + 0xE3, 0x82, 0xAF, 0xE3, 0x82, 0x99, 0xE3, 0x83, + 0xA9, 0xE3, 0x83, 0xA0, 0x52, 0xE3, 0x82, 0xAD, + 0xE3, 0x83, 0xAD, 0xE3, 0x83, 0xA1, 0xE3, 0x83, + 0xBC, 0xE3, 0x83, 0x88, 0xE3, 0x83, 0xAB, 0x52, + 0xE3, 0x82, 0xAF, 0xE3, 0x82, 0x99, 0xE3, 0x83, + // Bytes 2c00 - 2c3f + 0xA9, 0xE3, 0x83, 0xA0, 0xE3, 0x83, 0x88, 0xE3, + 0x83, 0xB3, 0x52, 0xE3, 0x82, 0xAF, 0xE3, 0x83, + 0xAB, 0xE3, 0x82, 0xBB, 0xE3, 0x82, 0x99, 0xE3, + 0x82, 0xA4, 0xE3, 0x83, 0xAD, 0x52, 0xE3, 0x83, + 0x8F, 0xE3, 0x82, 0x9A, 0xE3, 0x83, 0xBC, 0xE3, + 0x82, 0xBB, 0xE3, 0x83, 0xB3, 0xE3, 0x83, 0x88, + 0x52, 0xE3, 0x83, 0x92, 0xE3, 0x82, 0x9A, 0xE3, + 0x82, 0xA2, 0xE3, 0x82, 0xB9, 0xE3, 0x83, 0x88, + // Bytes 2c40 - 2c7f + 0xE3, 0x83, 0xAB, 0x52, 0xE3, 0x83, 0x95, 0xE3, + 0x82, 0x99, 0xE3, 0x83, 0x83, 0xE3, 0x82, 0xB7, + 0xE3, 0x82, 0xA7, 0xE3, 0x83, 0xAB, 0x52, 0xE3, + 0x83, 0x9F, 0xE3, 0x83, 0xAA, 0xE3, 0x83, 0x8F, + 0xE3, 0x82, 0x99, 0xE3, 0x83, 0xBC, 0xE3, 0x83, + 0xAB, 0x52, 0xE3, 0x83, 0xAC, 0xE3, 0x83, 0xB3, + 0xE3, 0x83, 0x88, 0xE3, 0x82, 0xB1, 0xE3, 0x82, + 0x99, 0xE3, 0x83, 0xB3, 0x61, 0xD8, 0xB5, 0xD9, + // Bytes 2c80 - 2cbf + 0x84, 0xD9, 0x89, 0x20, 0xD8, 0xA7, 0xD9, 0x84, + 0xD9, 0x84, 0xD9, 0x87, 0x20, 0xD8, 0xB9, 0xD9, + 0x84, 0xD9, 0x8A, 0xD9, 0x87, 0x20, 0xD9, 0x88, + 0xD8, 0xB3, 0xD9, 0x84, 0xD9, 0x85, 0x06, 0xE0, + 0xA7, 0x87, 0xE0, 0xA6, 0xBE, 0x01, 0x06, 0xE0, + 0xA7, 0x87, 0xE0, 0xA7, 0x97, 0x01, 0x06, 0xE0, + 0xAD, 0x87, 0xE0, 0xAC, 0xBE, 0x01, 0x06, 0xE0, + 0xAD, 0x87, 0xE0, 0xAD, 0x96, 0x01, 0x06, 0xE0, + // Bytes 2cc0 - 2cff + 0xAD, 0x87, 0xE0, 0xAD, 0x97, 0x01, 0x06, 0xE0, + 0xAE, 0x92, 0xE0, 0xAF, 0x97, 0x01, 0x06, 0xE0, + 0xAF, 0x86, 0xE0, 0xAE, 0xBE, 0x01, 0x06, 0xE0, + 0xAF, 0x86, 0xE0, 0xAF, 0x97, 0x01, 0x06, 0xE0, + 0xAF, 0x87, 0xE0, 0xAE, 0xBE, 0x01, 0x06, 0xE0, + 0xB2, 0xBF, 0xE0, 0xB3, 0x95, 0x01, 0x06, 0xE0, + 0xB3, 0x86, 0xE0, 0xB3, 0x95, 0x01, 0x06, 0xE0, + 0xB3, 0x86, 0xE0, 0xB3, 0x96, 0x01, 0x06, 0xE0, + // Bytes 2d00 - 2d3f + 0xB5, 0x86, 0xE0, 0xB4, 0xBE, 0x01, 0x06, 0xE0, + 0xB5, 0x86, 0xE0, 0xB5, 0x97, 0x01, 0x06, 0xE0, + 0xB5, 0x87, 0xE0, 0xB4, 0xBE, 0x01, 0x06, 0xE0, + 0xB7, 0x99, 0xE0, 0xB7, 0x9F, 0x01, 0x06, 0xE1, + 0x80, 0xA5, 0xE1, 0x80, 0xAE, 0x01, 0x06, 0xE1, + 0xAC, 0x85, 0xE1, 0xAC, 0xB5, 0x01, 0x06, 0xE1, + 0xAC, 0x87, 0xE1, 0xAC, 0xB5, 0x01, 0x06, 0xE1, + 0xAC, 0x89, 0xE1, 0xAC, 0xB5, 0x01, 0x06, 0xE1, + // Bytes 2d40 - 2d7f + 0xAC, 0x8B, 0xE1, 0xAC, 0xB5, 0x01, 0x06, 0xE1, + 0xAC, 0x8D, 0xE1, 0xAC, 0xB5, 0x01, 0x06, 0xE1, + 0xAC, 0x91, 0xE1, 0xAC, 0xB5, 0x01, 0x06, 0xE1, + 0xAC, 0xBA, 0xE1, 0xAC, 0xB5, 0x01, 0x06, 0xE1, + 0xAC, 0xBC, 0xE1, 0xAC, 0xB5, 0x01, 0x06, 0xE1, + 0xAC, 0xBE, 0xE1, 0xAC, 0xB5, 0x01, 0x06, 0xE1, + 0xAC, 0xBF, 0xE1, 0xAC, 0xB5, 0x01, 0x06, 0xE1, + 0xAD, 0x82, 0xE1, 0xAC, 0xB5, 0x01, 0x08, 0xF0, + // Bytes 2d80 - 2dbf + 0x91, 0x84, 0xB1, 0xF0, 0x91, 0x84, 0xA7, 0x01, + 0x08, 0xF0, 0x91, 0x84, 0xB2, 0xF0, 0x91, 0x84, + 0xA7, 0x01, 0x08, 0xF0, 0x91, 0x8D, 0x87, 0xF0, + 0x91, 0x8C, 0xBE, 0x01, 0x08, 0xF0, 0x91, 0x8D, + 0x87, 0xF0, 0x91, 0x8D, 0x97, 0x01, 0x08, 0xF0, + 0x91, 0x92, 0xB9, 0xF0, 0x91, 0x92, 0xB0, 0x01, + 0x08, 0xF0, 0x91, 0x92, 0xB9, 0xF0, 0x91, 0x92, + 0xBA, 0x01, 0x08, 0xF0, 0x91, 0x92, 0xB9, 0xF0, + // Bytes 2dc0 - 2dff + 0x91, 0x92, 0xBD, 0x01, 0x08, 0xF0, 0x91, 0x96, + 0xB8, 0xF0, 0x91, 0x96, 0xAF, 0x01, 0x08, 0xF0, + 0x91, 0x96, 0xB9, 0xF0, 0x91, 0x96, 0xAF, 0x01, + 0x09, 0xE0, 0xB3, 0x86, 0xE0, 0xB3, 0x82, 0xE0, + 0xB3, 0x95, 0x02, 0x09, 0xE0, 0xB7, 0x99, 0xE0, + 0xB7, 0x8F, 0xE0, 0xB7, 0x8A, 0x12, 0x44, 0x44, + 0x5A, 0xCC, 0x8C, 0xC9, 0x44, 0x44, 0x7A, 0xCC, + 0x8C, 0xC9, 0x44, 0x64, 0x7A, 0xCC, 0x8C, 0xC9, + // Bytes 2e00 - 2e3f + 0x46, 0xD9, 0x84, 0xD8, 0xA7, 0xD9, 0x93, 0xC9, + 0x46, 0xD9, 0x84, 0xD8, 0xA7, 0xD9, 0x94, 0xC9, + 0x46, 0xD9, 0x84, 0xD8, 0xA7, 0xD9, 0x95, 0xB5, + 0x46, 0xE1, 0x84, 0x80, 0xE1, 0x85, 0xA1, 0x01, + 0x46, 0xE1, 0x84, 0x82, 0xE1, 0x85, 0xA1, 0x01, + 0x46, 0xE1, 0x84, 0x83, 0xE1, 0x85, 0xA1, 0x01, + 0x46, 0xE1, 0x84, 0x85, 0xE1, 0x85, 0xA1, 0x01, + 0x46, 0xE1, 0x84, 0x86, 0xE1, 0x85, 0xA1, 0x01, + // Bytes 2e40 - 2e7f + 0x46, 0xE1, 0x84, 0x87, 0xE1, 0x85, 0xA1, 0x01, + 0x46, 0xE1, 0x84, 0x89, 0xE1, 0x85, 0xA1, 0x01, + 0x46, 0xE1, 0x84, 0x8B, 0xE1, 0x85, 0xA1, 0x01, + 0x46, 0xE1, 0x84, 0x8B, 0xE1, 0x85, 0xAE, 0x01, + 0x46, 0xE1, 0x84, 0x8C, 0xE1, 0x85, 0xA1, 0x01, + 0x46, 0xE1, 0x84, 0x8E, 0xE1, 0x85, 0xA1, 0x01, + 0x46, 0xE1, 0x84, 0x8F, 0xE1, 0x85, 0xA1, 0x01, + 0x46, 0xE1, 0x84, 0x90, 0xE1, 0x85, 0xA1, 0x01, + // Bytes 2e80 - 2ebf + 0x46, 0xE1, 0x84, 0x91, 0xE1, 0x85, 0xA1, 0x01, + 0x46, 0xE1, 0x84, 0x92, 0xE1, 0x85, 0xA1, 0x01, + 0x49, 0xE3, 0x83, 0xA1, 0xE3, 0x82, 0xAB, 0xE3, + 0x82, 0x99, 0x0D, 0x4C, 0xE1, 0x84, 0x8C, 0xE1, + 0x85, 0xAE, 0xE1, 0x84, 0x8B, 0xE1, 0x85, 0xB4, + 0x01, 0x4C, 0xE3, 0x82, 0xAD, 0xE3, 0x82, 0x99, + 0xE3, 0x82, 0xAB, 0xE3, 0x82, 0x99, 0x0D, 0x4C, + 0xE3, 0x82, 0xB3, 0xE3, 0x83, 0xBC, 0xE3, 0x83, + // Bytes 2ec0 - 2eff + 0x9B, 0xE3, 0x82, 0x9A, 0x0D, 0x4C, 0xE3, 0x83, + 0xA4, 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0x88, 0xE3, + 0x82, 0x99, 0x0D, 0x4F, 0xE1, 0x84, 0x8E, 0xE1, + 0x85, 0xA1, 0xE1, 0x86, 0xB7, 0xE1, 0x84, 0x80, + 0xE1, 0x85, 0xA9, 0x01, 0x4F, 0xE3, 0x82, 0xA4, + 0xE3, 0x83, 0x8B, 0xE3, 0x83, 0xB3, 0xE3, 0x82, + 0xAF, 0xE3, 0x82, 0x99, 0x0D, 0x4F, 0xE3, 0x82, + 0xB7, 0xE3, 0x83, 0xAA, 0xE3, 0x83, 0xB3, 0xE3, + // Bytes 2f00 - 2f3f + 0x82, 0xAF, 0xE3, 0x82, 0x99, 0x0D, 0x4F, 0xE3, + 0x83, 0x98, 0xE3, 0x82, 0x9A, 0xE3, 0x83, 0xBC, + 0xE3, 0x82, 0xB7, 0xE3, 0x82, 0x99, 0x0D, 0x4F, + 0xE3, 0x83, 0x9B, 0xE3, 0x82, 0x9A, 0xE3, 0x83, + 0xB3, 0xE3, 0x83, 0x88, 0xE3, 0x82, 0x99, 0x0D, + 0x52, 0xE3, 0x82, 0xA8, 0xE3, 0x82, 0xB9, 0xE3, + 0x82, 0xAF, 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0x88, + 0xE3, 0x82, 0x99, 0x0D, 0x52, 0xE3, 0x83, 0x95, + // Bytes 2f40 - 2f7f + 0xE3, 0x82, 0xA1, 0xE3, 0x83, 0xA9, 0xE3, 0x83, + 0x83, 0xE3, 0x83, 0x88, 0xE3, 0x82, 0x99, 0x0D, + 0x86, 0xE0, 0xB3, 0x86, 0xE0, 0xB3, 0x82, 0x01, + 0x86, 0xE0, 0xB7, 0x99, 0xE0, 0xB7, 0x8F, 0x01, + 0x03, 0x3C, 0xCC, 0xB8, 0x05, 0x03, 0x3D, 0xCC, + 0xB8, 0x05, 0x03, 0x3E, 0xCC, 0xB8, 0x05, 0x03, + 0x41, 0xCC, 0x80, 0xC9, 0x03, 0x41, 0xCC, 0x81, + 0xC9, 0x03, 0x41, 0xCC, 0x83, 0xC9, 0x03, 0x41, + // Bytes 2f80 - 2fbf + 0xCC, 0x84, 0xC9, 0x03, 0x41, 0xCC, 0x89, 0xC9, + 0x03, 0x41, 0xCC, 0x8C, 0xC9, 0x03, 0x41, 0xCC, + 0x8F, 0xC9, 0x03, 0x41, 0xCC, 0x91, 0xC9, 0x03, + 0x41, 0xCC, 0xA5, 0xB5, 0x03, 0x41, 0xCC, 0xA8, + 0xA5, 0x03, 0x42, 0xCC, 0x87, 0xC9, 0x03, 0x42, + 0xCC, 0xA3, 0xB5, 0x03, 0x42, 0xCC, 0xB1, 0xB5, + 0x03, 0x43, 0xCC, 0x81, 0xC9, 0x03, 0x43, 0xCC, + 0x82, 0xC9, 0x03, 0x43, 0xCC, 0x87, 0xC9, 0x03, + // Bytes 2fc0 - 2fff + 0x43, 0xCC, 0x8C, 0xC9, 0x03, 0x44, 0xCC, 0x87, + 0xC9, 0x03, 0x44, 0xCC, 0x8C, 0xC9, 0x03, 0x44, + 0xCC, 0xA3, 0xB5, 0x03, 0x44, 0xCC, 0xA7, 0xA5, + 0x03, 0x44, 0xCC, 0xAD, 0xB5, 0x03, 0x44, 0xCC, + 0xB1, 0xB5, 0x03, 0x45, 0xCC, 0x80, 0xC9, 0x03, + 0x45, 0xCC, 0x81, 0xC9, 0x03, 0x45, 0xCC, 0x83, + 0xC9, 0x03, 0x45, 0xCC, 0x86, 0xC9, 0x03, 0x45, + 0xCC, 0x87, 0xC9, 0x03, 0x45, 0xCC, 0x88, 0xC9, + // Bytes 3000 - 303f + 0x03, 0x45, 0xCC, 0x89, 0xC9, 0x03, 0x45, 0xCC, + 0x8C, 0xC9, 0x03, 0x45, 0xCC, 0x8F, 0xC9, 0x03, + 0x45, 0xCC, 0x91, 0xC9, 0x03, 0x45, 0xCC, 0xA8, + 0xA5, 0x03, 0x45, 0xCC, 0xAD, 0xB5, 0x03, 0x45, + 0xCC, 0xB0, 0xB5, 0x03, 0x46, 0xCC, 0x87, 0xC9, + 0x03, 0x47, 0xCC, 0x81, 0xC9, 0x03, 0x47, 0xCC, + 0x82, 0xC9, 0x03, 0x47, 0xCC, 0x84, 0xC9, 0x03, + 0x47, 0xCC, 0x86, 0xC9, 0x03, 0x47, 0xCC, 0x87, + // Bytes 3040 - 307f + 0xC9, 0x03, 0x47, 0xCC, 0x8C, 0xC9, 0x03, 0x47, + 0xCC, 0xA7, 0xA5, 0x03, 0x48, 0xCC, 0x82, 0xC9, + 0x03, 0x48, 0xCC, 0x87, 0xC9, 0x03, 0x48, 0xCC, + 0x88, 0xC9, 0x03, 0x48, 0xCC, 0x8C, 0xC9, 0x03, + 0x48, 0xCC, 0xA3, 0xB5, 0x03, 0x48, 0xCC, 0xA7, + 0xA5, 0x03, 0x48, 0xCC, 0xAE, 0xB5, 0x03, 0x49, + 0xCC, 0x80, 0xC9, 0x03, 0x49, 0xCC, 0x81, 0xC9, + 0x03, 0x49, 0xCC, 0x82, 0xC9, 0x03, 0x49, 0xCC, + // Bytes 3080 - 30bf + 0x83, 0xC9, 0x03, 0x49, 0xCC, 0x84, 0xC9, 0x03, + 0x49, 0xCC, 0x86, 0xC9, 0x03, 0x49, 0xCC, 0x87, + 0xC9, 0x03, 0x49, 0xCC, 0x89, 0xC9, 0x03, 0x49, + 0xCC, 0x8C, 0xC9, 0x03, 0x49, 0xCC, 0x8F, 0xC9, + 0x03, 0x49, 0xCC, 0x91, 0xC9, 0x03, 0x49, 0xCC, + 0xA3, 0xB5, 0x03, 0x49, 0xCC, 0xA8, 0xA5, 0x03, + 0x49, 0xCC, 0xB0, 0xB5, 0x03, 0x4A, 0xCC, 0x82, + 0xC9, 0x03, 0x4B, 0xCC, 0x81, 0xC9, 0x03, 0x4B, + // Bytes 30c0 - 30ff + 0xCC, 0x8C, 0xC9, 0x03, 0x4B, 0xCC, 0xA3, 0xB5, + 0x03, 0x4B, 0xCC, 0xA7, 0xA5, 0x03, 0x4B, 0xCC, + 0xB1, 0xB5, 0x03, 0x4C, 0xCC, 0x81, 0xC9, 0x03, + 0x4C, 0xCC, 0x8C, 0xC9, 0x03, 0x4C, 0xCC, 0xA7, + 0xA5, 0x03, 0x4C, 0xCC, 0xAD, 0xB5, 0x03, 0x4C, + 0xCC, 0xB1, 0xB5, 0x03, 0x4D, 0xCC, 0x81, 0xC9, + 0x03, 0x4D, 0xCC, 0x87, 0xC9, 0x03, 0x4D, 0xCC, + 0xA3, 0xB5, 0x03, 0x4E, 0xCC, 0x80, 0xC9, 0x03, + // Bytes 3100 - 313f + 0x4E, 0xCC, 0x81, 0xC9, 0x03, 0x4E, 0xCC, 0x83, + 0xC9, 0x03, 0x4E, 0xCC, 0x87, 0xC9, 0x03, 0x4E, + 0xCC, 0x8C, 0xC9, 0x03, 0x4E, 0xCC, 0xA3, 0xB5, + 0x03, 0x4E, 0xCC, 0xA7, 0xA5, 0x03, 0x4E, 0xCC, + 0xAD, 0xB5, 0x03, 0x4E, 0xCC, 0xB1, 0xB5, 0x03, + 0x4F, 0xCC, 0x80, 0xC9, 0x03, 0x4F, 0xCC, 0x81, + 0xC9, 0x03, 0x4F, 0xCC, 0x86, 0xC9, 0x03, 0x4F, + 0xCC, 0x89, 0xC9, 0x03, 0x4F, 0xCC, 0x8B, 0xC9, + // Bytes 3140 - 317f + 0x03, 0x4F, 0xCC, 0x8C, 0xC9, 0x03, 0x4F, 0xCC, + 0x8F, 0xC9, 0x03, 0x4F, 0xCC, 0x91, 0xC9, 0x03, + 0x50, 0xCC, 0x81, 0xC9, 0x03, 0x50, 0xCC, 0x87, + 0xC9, 0x03, 0x52, 0xCC, 0x81, 0xC9, 0x03, 0x52, + 0xCC, 0x87, 0xC9, 0x03, 0x52, 0xCC, 0x8C, 0xC9, + 0x03, 0x52, 0xCC, 0x8F, 0xC9, 0x03, 0x52, 0xCC, + 0x91, 0xC9, 0x03, 0x52, 0xCC, 0xA7, 0xA5, 0x03, + 0x52, 0xCC, 0xB1, 0xB5, 0x03, 0x53, 0xCC, 0x82, + // Bytes 3180 - 31bf + 0xC9, 0x03, 0x53, 0xCC, 0x87, 0xC9, 0x03, 0x53, + 0xCC, 0xA6, 0xB5, 0x03, 0x53, 0xCC, 0xA7, 0xA5, + 0x03, 0x54, 0xCC, 0x87, 0xC9, 0x03, 0x54, 0xCC, + 0x8C, 0xC9, 0x03, 0x54, 0xCC, 0xA3, 0xB5, 0x03, + 0x54, 0xCC, 0xA6, 0xB5, 0x03, 0x54, 0xCC, 0xA7, + 0xA5, 0x03, 0x54, 0xCC, 0xAD, 0xB5, 0x03, 0x54, + 0xCC, 0xB1, 0xB5, 0x03, 0x55, 0xCC, 0x80, 0xC9, + 0x03, 0x55, 0xCC, 0x81, 0xC9, 0x03, 0x55, 0xCC, + // Bytes 31c0 - 31ff + 0x82, 0xC9, 0x03, 0x55, 0xCC, 0x86, 0xC9, 0x03, + 0x55, 0xCC, 0x89, 0xC9, 0x03, 0x55, 0xCC, 0x8A, + 0xC9, 0x03, 0x55, 0xCC, 0x8B, 0xC9, 0x03, 0x55, + 0xCC, 0x8C, 0xC9, 0x03, 0x55, 0xCC, 0x8F, 0xC9, + 0x03, 0x55, 0xCC, 0x91, 0xC9, 0x03, 0x55, 0xCC, + 0xA3, 0xB5, 0x03, 0x55, 0xCC, 0xA4, 0xB5, 0x03, + 0x55, 0xCC, 0xA8, 0xA5, 0x03, 0x55, 0xCC, 0xAD, + 0xB5, 0x03, 0x55, 0xCC, 0xB0, 0xB5, 0x03, 0x56, + // Bytes 3200 - 323f + 0xCC, 0x83, 0xC9, 0x03, 0x56, 0xCC, 0xA3, 0xB5, + 0x03, 0x57, 0xCC, 0x80, 0xC9, 0x03, 0x57, 0xCC, + 0x81, 0xC9, 0x03, 0x57, 0xCC, 0x82, 0xC9, 0x03, + 0x57, 0xCC, 0x87, 0xC9, 0x03, 0x57, 0xCC, 0x88, + 0xC9, 0x03, 0x57, 0xCC, 0xA3, 0xB5, 0x03, 0x58, + 0xCC, 0x87, 0xC9, 0x03, 0x58, 0xCC, 0x88, 0xC9, + 0x03, 0x59, 0xCC, 0x80, 0xC9, 0x03, 0x59, 0xCC, + 0x81, 0xC9, 0x03, 0x59, 0xCC, 0x82, 0xC9, 0x03, + // Bytes 3240 - 327f + 0x59, 0xCC, 0x83, 0xC9, 0x03, 0x59, 0xCC, 0x84, + 0xC9, 0x03, 0x59, 0xCC, 0x87, 0xC9, 0x03, 0x59, + 0xCC, 0x88, 0xC9, 0x03, 0x59, 0xCC, 0x89, 0xC9, + 0x03, 0x59, 0xCC, 0xA3, 0xB5, 0x03, 0x5A, 0xCC, + 0x81, 0xC9, 0x03, 0x5A, 0xCC, 0x82, 0xC9, 0x03, + 0x5A, 0xCC, 0x87, 0xC9, 0x03, 0x5A, 0xCC, 0x8C, + 0xC9, 0x03, 0x5A, 0xCC, 0xA3, 0xB5, 0x03, 0x5A, + 0xCC, 0xB1, 0xB5, 0x03, 0x61, 0xCC, 0x80, 0xC9, + // Bytes 3280 - 32bf + 0x03, 0x61, 0xCC, 0x81, 0xC9, 0x03, 0x61, 0xCC, + 0x83, 0xC9, 0x03, 0x61, 0xCC, 0x84, 0xC9, 0x03, + 0x61, 0xCC, 0x89, 0xC9, 0x03, 0x61, 0xCC, 0x8C, + 0xC9, 0x03, 0x61, 0xCC, 0x8F, 0xC9, 0x03, 0x61, + 0xCC, 0x91, 0xC9, 0x03, 0x61, 0xCC, 0xA5, 0xB5, + 0x03, 0x61, 0xCC, 0xA8, 0xA5, 0x03, 0x62, 0xCC, + 0x87, 0xC9, 0x03, 0x62, 0xCC, 0xA3, 0xB5, 0x03, + 0x62, 0xCC, 0xB1, 0xB5, 0x03, 0x63, 0xCC, 0x81, + // Bytes 32c0 - 32ff + 0xC9, 0x03, 0x63, 0xCC, 0x82, 0xC9, 0x03, 0x63, + 0xCC, 0x87, 0xC9, 0x03, 0x63, 0xCC, 0x8C, 0xC9, + 0x03, 0x64, 0xCC, 0x87, 0xC9, 0x03, 0x64, 0xCC, + 0x8C, 0xC9, 0x03, 0x64, 0xCC, 0xA3, 0xB5, 0x03, + 0x64, 0xCC, 0xA7, 0xA5, 0x03, 0x64, 0xCC, 0xAD, + 0xB5, 0x03, 0x64, 0xCC, 0xB1, 0xB5, 0x03, 0x65, + 0xCC, 0x80, 0xC9, 0x03, 0x65, 0xCC, 0x81, 0xC9, + 0x03, 0x65, 0xCC, 0x83, 0xC9, 0x03, 0x65, 0xCC, + // Bytes 3300 - 333f + 0x86, 0xC9, 0x03, 0x65, 0xCC, 0x87, 0xC9, 0x03, + 0x65, 0xCC, 0x88, 0xC9, 0x03, 0x65, 0xCC, 0x89, + 0xC9, 0x03, 0x65, 0xCC, 0x8C, 0xC9, 0x03, 0x65, + 0xCC, 0x8F, 0xC9, 0x03, 0x65, 0xCC, 0x91, 0xC9, + 0x03, 0x65, 0xCC, 0xA8, 0xA5, 0x03, 0x65, 0xCC, + 0xAD, 0xB5, 0x03, 0x65, 0xCC, 0xB0, 0xB5, 0x03, + 0x66, 0xCC, 0x87, 0xC9, 0x03, 0x67, 0xCC, 0x81, + 0xC9, 0x03, 0x67, 0xCC, 0x82, 0xC9, 0x03, 0x67, + // Bytes 3340 - 337f + 0xCC, 0x84, 0xC9, 0x03, 0x67, 0xCC, 0x86, 0xC9, + 0x03, 0x67, 0xCC, 0x87, 0xC9, 0x03, 0x67, 0xCC, + 0x8C, 0xC9, 0x03, 0x67, 0xCC, 0xA7, 0xA5, 0x03, + 0x68, 0xCC, 0x82, 0xC9, 0x03, 0x68, 0xCC, 0x87, + 0xC9, 0x03, 0x68, 0xCC, 0x88, 0xC9, 0x03, 0x68, + 0xCC, 0x8C, 0xC9, 0x03, 0x68, 0xCC, 0xA3, 0xB5, + 0x03, 0x68, 0xCC, 0xA7, 0xA5, 0x03, 0x68, 0xCC, + 0xAE, 0xB5, 0x03, 0x68, 0xCC, 0xB1, 0xB5, 0x03, + // Bytes 3380 - 33bf + 0x69, 0xCC, 0x80, 0xC9, 0x03, 0x69, 0xCC, 0x81, + 0xC9, 0x03, 0x69, 0xCC, 0x82, 0xC9, 0x03, 0x69, + 0xCC, 0x83, 0xC9, 0x03, 0x69, 0xCC, 0x84, 0xC9, + 0x03, 0x69, 0xCC, 0x86, 0xC9, 0x03, 0x69, 0xCC, + 0x89, 0xC9, 0x03, 0x69, 0xCC, 0x8C, 0xC9, 0x03, + 0x69, 0xCC, 0x8F, 0xC9, 0x03, 0x69, 0xCC, 0x91, + 0xC9, 0x03, 0x69, 0xCC, 0xA3, 0xB5, 0x03, 0x69, + 0xCC, 0xA8, 0xA5, 0x03, 0x69, 0xCC, 0xB0, 0xB5, + // Bytes 33c0 - 33ff + 0x03, 0x6A, 0xCC, 0x82, 0xC9, 0x03, 0x6A, 0xCC, + 0x8C, 0xC9, 0x03, 0x6B, 0xCC, 0x81, 0xC9, 0x03, + 0x6B, 0xCC, 0x8C, 0xC9, 0x03, 0x6B, 0xCC, 0xA3, + 0xB5, 0x03, 0x6B, 0xCC, 0xA7, 0xA5, 0x03, 0x6B, + 0xCC, 0xB1, 0xB5, 0x03, 0x6C, 0xCC, 0x81, 0xC9, + 0x03, 0x6C, 0xCC, 0x8C, 0xC9, 0x03, 0x6C, 0xCC, + 0xA7, 0xA5, 0x03, 0x6C, 0xCC, 0xAD, 0xB5, 0x03, + 0x6C, 0xCC, 0xB1, 0xB5, 0x03, 0x6D, 0xCC, 0x81, + // Bytes 3400 - 343f + 0xC9, 0x03, 0x6D, 0xCC, 0x87, 0xC9, 0x03, 0x6D, + 0xCC, 0xA3, 0xB5, 0x03, 0x6E, 0xCC, 0x80, 0xC9, + 0x03, 0x6E, 0xCC, 0x81, 0xC9, 0x03, 0x6E, 0xCC, + 0x83, 0xC9, 0x03, 0x6E, 0xCC, 0x87, 0xC9, 0x03, + 0x6E, 0xCC, 0x8C, 0xC9, 0x03, 0x6E, 0xCC, 0xA3, + 0xB5, 0x03, 0x6E, 0xCC, 0xA7, 0xA5, 0x03, 0x6E, + 0xCC, 0xAD, 0xB5, 0x03, 0x6E, 0xCC, 0xB1, 0xB5, + 0x03, 0x6F, 0xCC, 0x80, 0xC9, 0x03, 0x6F, 0xCC, + // Bytes 3440 - 347f + 0x81, 0xC9, 0x03, 0x6F, 0xCC, 0x86, 0xC9, 0x03, + 0x6F, 0xCC, 0x89, 0xC9, 0x03, 0x6F, 0xCC, 0x8B, + 0xC9, 0x03, 0x6F, 0xCC, 0x8C, 0xC9, 0x03, 0x6F, + 0xCC, 0x8F, 0xC9, 0x03, 0x6F, 0xCC, 0x91, 0xC9, + 0x03, 0x70, 0xCC, 0x81, 0xC9, 0x03, 0x70, 0xCC, + 0x87, 0xC9, 0x03, 0x72, 0xCC, 0x81, 0xC9, 0x03, + 0x72, 0xCC, 0x87, 0xC9, 0x03, 0x72, 0xCC, 0x8C, + 0xC9, 0x03, 0x72, 0xCC, 0x8F, 0xC9, 0x03, 0x72, + // Bytes 3480 - 34bf + 0xCC, 0x91, 0xC9, 0x03, 0x72, 0xCC, 0xA7, 0xA5, + 0x03, 0x72, 0xCC, 0xB1, 0xB5, 0x03, 0x73, 0xCC, + 0x82, 0xC9, 0x03, 0x73, 0xCC, 0x87, 0xC9, 0x03, + 0x73, 0xCC, 0xA6, 0xB5, 0x03, 0x73, 0xCC, 0xA7, + 0xA5, 0x03, 0x74, 0xCC, 0x87, 0xC9, 0x03, 0x74, + 0xCC, 0x88, 0xC9, 0x03, 0x74, 0xCC, 0x8C, 0xC9, + 0x03, 0x74, 0xCC, 0xA3, 0xB5, 0x03, 0x74, 0xCC, + 0xA6, 0xB5, 0x03, 0x74, 0xCC, 0xA7, 0xA5, 0x03, + // Bytes 34c0 - 34ff + 0x74, 0xCC, 0xAD, 0xB5, 0x03, 0x74, 0xCC, 0xB1, + 0xB5, 0x03, 0x75, 0xCC, 0x80, 0xC9, 0x03, 0x75, + 0xCC, 0x81, 0xC9, 0x03, 0x75, 0xCC, 0x82, 0xC9, + 0x03, 0x75, 0xCC, 0x86, 0xC9, 0x03, 0x75, 0xCC, + 0x89, 0xC9, 0x03, 0x75, 0xCC, 0x8A, 0xC9, 0x03, + 0x75, 0xCC, 0x8B, 0xC9, 0x03, 0x75, 0xCC, 0x8C, + 0xC9, 0x03, 0x75, 0xCC, 0x8F, 0xC9, 0x03, 0x75, + 0xCC, 0x91, 0xC9, 0x03, 0x75, 0xCC, 0xA3, 0xB5, + // Bytes 3500 - 353f + 0x03, 0x75, 0xCC, 0xA4, 0xB5, 0x03, 0x75, 0xCC, + 0xA8, 0xA5, 0x03, 0x75, 0xCC, 0xAD, 0xB5, 0x03, + 0x75, 0xCC, 0xB0, 0xB5, 0x03, 0x76, 0xCC, 0x83, + 0xC9, 0x03, 0x76, 0xCC, 0xA3, 0xB5, 0x03, 0x77, + 0xCC, 0x80, 0xC9, 0x03, 0x77, 0xCC, 0x81, 0xC9, + 0x03, 0x77, 0xCC, 0x82, 0xC9, 0x03, 0x77, 0xCC, + 0x87, 0xC9, 0x03, 0x77, 0xCC, 0x88, 0xC9, 0x03, + 0x77, 0xCC, 0x8A, 0xC9, 0x03, 0x77, 0xCC, 0xA3, + // Bytes 3540 - 357f + 0xB5, 0x03, 0x78, 0xCC, 0x87, 0xC9, 0x03, 0x78, + 0xCC, 0x88, 0xC9, 0x03, 0x79, 0xCC, 0x80, 0xC9, + 0x03, 0x79, 0xCC, 0x81, 0xC9, 0x03, 0x79, 0xCC, + 0x82, 0xC9, 0x03, 0x79, 0xCC, 0x83, 0xC9, 0x03, + 0x79, 0xCC, 0x84, 0xC9, 0x03, 0x79, 0xCC, 0x87, + 0xC9, 0x03, 0x79, 0xCC, 0x88, 0xC9, 0x03, 0x79, + 0xCC, 0x89, 0xC9, 0x03, 0x79, 0xCC, 0x8A, 0xC9, + 0x03, 0x79, 0xCC, 0xA3, 0xB5, 0x03, 0x7A, 0xCC, + // Bytes 3580 - 35bf + 0x81, 0xC9, 0x03, 0x7A, 0xCC, 0x82, 0xC9, 0x03, + 0x7A, 0xCC, 0x87, 0xC9, 0x03, 0x7A, 0xCC, 0x8C, + 0xC9, 0x03, 0x7A, 0xCC, 0xA3, 0xB5, 0x03, 0x7A, + 0xCC, 0xB1, 0xB5, 0x04, 0xC2, 0xA8, 0xCC, 0x80, + 0xCA, 0x04, 0xC2, 0xA8, 0xCC, 0x81, 0xCA, 0x04, + 0xC2, 0xA8, 0xCD, 0x82, 0xCA, 0x04, 0xC3, 0x86, + 0xCC, 0x81, 0xC9, 0x04, 0xC3, 0x86, 0xCC, 0x84, + 0xC9, 0x04, 0xC3, 0x98, 0xCC, 0x81, 0xC9, 0x04, + // Bytes 35c0 - 35ff + 0xC3, 0xA6, 0xCC, 0x81, 0xC9, 0x04, 0xC3, 0xA6, + 0xCC, 0x84, 0xC9, 0x04, 0xC3, 0xB8, 0xCC, 0x81, + 0xC9, 0x04, 0xC5, 0xBF, 0xCC, 0x87, 0xC9, 0x04, + 0xC6, 0xB7, 0xCC, 0x8C, 0xC9, 0x04, 0xCA, 0x92, + 0xCC, 0x8C, 0xC9, 0x04, 0xCE, 0x91, 0xCC, 0x80, + 0xC9, 0x04, 0xCE, 0x91, 0xCC, 0x81, 0xC9, 0x04, + 0xCE, 0x91, 0xCC, 0x84, 0xC9, 0x04, 0xCE, 0x91, + 0xCC, 0x86, 0xC9, 0x04, 0xCE, 0x91, 0xCD, 0x85, + // Bytes 3600 - 363f + 0xD9, 0x04, 0xCE, 0x95, 0xCC, 0x80, 0xC9, 0x04, + 0xCE, 0x95, 0xCC, 0x81, 0xC9, 0x04, 0xCE, 0x97, + 0xCC, 0x80, 0xC9, 0x04, 0xCE, 0x97, 0xCC, 0x81, + 0xC9, 0x04, 0xCE, 0x97, 0xCD, 0x85, 0xD9, 0x04, + 0xCE, 0x99, 0xCC, 0x80, 0xC9, 0x04, 0xCE, 0x99, + 0xCC, 0x81, 0xC9, 0x04, 0xCE, 0x99, 0xCC, 0x84, + 0xC9, 0x04, 0xCE, 0x99, 0xCC, 0x86, 0xC9, 0x04, + 0xCE, 0x99, 0xCC, 0x88, 0xC9, 0x04, 0xCE, 0x9F, + // Bytes 3640 - 367f + 0xCC, 0x80, 0xC9, 0x04, 0xCE, 0x9F, 0xCC, 0x81, + 0xC9, 0x04, 0xCE, 0xA1, 0xCC, 0x94, 0xC9, 0x04, + 0xCE, 0xA5, 0xCC, 0x80, 0xC9, 0x04, 0xCE, 0xA5, + 0xCC, 0x81, 0xC9, 0x04, 0xCE, 0xA5, 0xCC, 0x84, + 0xC9, 0x04, 0xCE, 0xA5, 0xCC, 0x86, 0xC9, 0x04, + 0xCE, 0xA5, 0xCC, 0x88, 0xC9, 0x04, 0xCE, 0xA9, + 0xCC, 0x80, 0xC9, 0x04, 0xCE, 0xA9, 0xCC, 0x81, + 0xC9, 0x04, 0xCE, 0xA9, 0xCD, 0x85, 0xD9, 0x04, + // Bytes 3680 - 36bf + 0xCE, 0xB1, 0xCC, 0x84, 0xC9, 0x04, 0xCE, 0xB1, + 0xCC, 0x86, 0xC9, 0x04, 0xCE, 0xB1, 0xCD, 0x85, + 0xD9, 0x04, 0xCE, 0xB5, 0xCC, 0x80, 0xC9, 0x04, + 0xCE, 0xB5, 0xCC, 0x81, 0xC9, 0x04, 0xCE, 0xB7, + 0xCD, 0x85, 0xD9, 0x04, 0xCE, 0xB9, 0xCC, 0x80, + 0xC9, 0x04, 0xCE, 0xB9, 0xCC, 0x81, 0xC9, 0x04, + 0xCE, 0xB9, 0xCC, 0x84, 0xC9, 0x04, 0xCE, 0xB9, + 0xCC, 0x86, 0xC9, 0x04, 0xCE, 0xB9, 0xCD, 0x82, + // Bytes 36c0 - 36ff + 0xC9, 0x04, 0xCE, 0xBF, 0xCC, 0x80, 0xC9, 0x04, + 0xCE, 0xBF, 0xCC, 0x81, 0xC9, 0x04, 0xCF, 0x81, + 0xCC, 0x93, 0xC9, 0x04, 0xCF, 0x81, 0xCC, 0x94, + 0xC9, 0x04, 0xCF, 0x85, 0xCC, 0x80, 0xC9, 0x04, + 0xCF, 0x85, 0xCC, 0x81, 0xC9, 0x04, 0xCF, 0x85, + 0xCC, 0x84, 0xC9, 0x04, 0xCF, 0x85, 0xCC, 0x86, + 0xC9, 0x04, 0xCF, 0x85, 0xCD, 0x82, 0xC9, 0x04, + 0xCF, 0x89, 0xCD, 0x85, 0xD9, 0x04, 0xCF, 0x92, + // Bytes 3700 - 373f + 0xCC, 0x81, 0xC9, 0x04, 0xCF, 0x92, 0xCC, 0x88, + 0xC9, 0x04, 0xD0, 0x86, 0xCC, 0x88, 0xC9, 0x04, + 0xD0, 0x90, 0xCC, 0x86, 0xC9, 0x04, 0xD0, 0x90, + 0xCC, 0x88, 0xC9, 0x04, 0xD0, 0x93, 0xCC, 0x81, + 0xC9, 0x04, 0xD0, 0x95, 0xCC, 0x80, 0xC9, 0x04, + 0xD0, 0x95, 0xCC, 0x86, 0xC9, 0x04, 0xD0, 0x95, + 0xCC, 0x88, 0xC9, 0x04, 0xD0, 0x96, 0xCC, 0x86, + 0xC9, 0x04, 0xD0, 0x96, 0xCC, 0x88, 0xC9, 0x04, + // Bytes 3740 - 377f + 0xD0, 0x97, 0xCC, 0x88, 0xC9, 0x04, 0xD0, 0x98, + 0xCC, 0x80, 0xC9, 0x04, 0xD0, 0x98, 0xCC, 0x84, + 0xC9, 0x04, 0xD0, 0x98, 0xCC, 0x86, 0xC9, 0x04, + 0xD0, 0x98, 0xCC, 0x88, 0xC9, 0x04, 0xD0, 0x9A, + 0xCC, 0x81, 0xC9, 0x04, 0xD0, 0x9E, 0xCC, 0x88, + 0xC9, 0x04, 0xD0, 0xA3, 0xCC, 0x84, 0xC9, 0x04, + 0xD0, 0xA3, 0xCC, 0x86, 0xC9, 0x04, 0xD0, 0xA3, + 0xCC, 0x88, 0xC9, 0x04, 0xD0, 0xA3, 0xCC, 0x8B, + // Bytes 3780 - 37bf + 0xC9, 0x04, 0xD0, 0xA7, 0xCC, 0x88, 0xC9, 0x04, + 0xD0, 0xAB, 0xCC, 0x88, 0xC9, 0x04, 0xD0, 0xAD, + 0xCC, 0x88, 0xC9, 0x04, 0xD0, 0xB0, 0xCC, 0x86, + 0xC9, 0x04, 0xD0, 0xB0, 0xCC, 0x88, 0xC9, 0x04, + 0xD0, 0xB3, 0xCC, 0x81, 0xC9, 0x04, 0xD0, 0xB5, + 0xCC, 0x80, 0xC9, 0x04, 0xD0, 0xB5, 0xCC, 0x86, + 0xC9, 0x04, 0xD0, 0xB5, 0xCC, 0x88, 0xC9, 0x04, + 0xD0, 0xB6, 0xCC, 0x86, 0xC9, 0x04, 0xD0, 0xB6, + // Bytes 37c0 - 37ff + 0xCC, 0x88, 0xC9, 0x04, 0xD0, 0xB7, 0xCC, 0x88, + 0xC9, 0x04, 0xD0, 0xB8, 0xCC, 0x80, 0xC9, 0x04, + 0xD0, 0xB8, 0xCC, 0x84, 0xC9, 0x04, 0xD0, 0xB8, + 0xCC, 0x86, 0xC9, 0x04, 0xD0, 0xB8, 0xCC, 0x88, + 0xC9, 0x04, 0xD0, 0xBA, 0xCC, 0x81, 0xC9, 0x04, + 0xD0, 0xBE, 0xCC, 0x88, 0xC9, 0x04, 0xD1, 0x83, + 0xCC, 0x84, 0xC9, 0x04, 0xD1, 0x83, 0xCC, 0x86, + 0xC9, 0x04, 0xD1, 0x83, 0xCC, 0x88, 0xC9, 0x04, + // Bytes 3800 - 383f + 0xD1, 0x83, 0xCC, 0x8B, 0xC9, 0x04, 0xD1, 0x87, + 0xCC, 0x88, 0xC9, 0x04, 0xD1, 0x8B, 0xCC, 0x88, + 0xC9, 0x04, 0xD1, 0x8D, 0xCC, 0x88, 0xC9, 0x04, + 0xD1, 0x96, 0xCC, 0x88, 0xC9, 0x04, 0xD1, 0xB4, + 0xCC, 0x8F, 0xC9, 0x04, 0xD1, 0xB5, 0xCC, 0x8F, + 0xC9, 0x04, 0xD3, 0x98, 0xCC, 0x88, 0xC9, 0x04, + 0xD3, 0x99, 0xCC, 0x88, 0xC9, 0x04, 0xD3, 0xA8, + 0xCC, 0x88, 0xC9, 0x04, 0xD3, 0xA9, 0xCC, 0x88, + // Bytes 3840 - 387f + 0xC9, 0x04, 0xD8, 0xA7, 0xD9, 0x93, 0xC9, 0x04, + 0xD8, 0xA7, 0xD9, 0x94, 0xC9, 0x04, 0xD8, 0xA7, + 0xD9, 0x95, 0xB5, 0x04, 0xD9, 0x88, 0xD9, 0x94, + 0xC9, 0x04, 0xD9, 0x8A, 0xD9, 0x94, 0xC9, 0x04, + 0xDB, 0x81, 0xD9, 0x94, 0xC9, 0x04, 0xDB, 0x92, + 0xD9, 0x94, 0xC9, 0x04, 0xDB, 0x95, 0xD9, 0x94, + 0xC9, 0x05, 0x41, 0xCC, 0x82, 0xCC, 0x80, 0xCA, + 0x05, 0x41, 0xCC, 0x82, 0xCC, 0x81, 0xCA, 0x05, + // Bytes 3880 - 38bf + 0x41, 0xCC, 0x82, 0xCC, 0x83, 0xCA, 0x05, 0x41, + 0xCC, 0x82, 0xCC, 0x89, 0xCA, 0x05, 0x41, 0xCC, + 0x86, 0xCC, 0x80, 0xCA, 0x05, 0x41, 0xCC, 0x86, + 0xCC, 0x81, 0xCA, 0x05, 0x41, 0xCC, 0x86, 0xCC, + 0x83, 0xCA, 0x05, 0x41, 0xCC, 0x86, 0xCC, 0x89, + 0xCA, 0x05, 0x41, 0xCC, 0x87, 0xCC, 0x84, 0xCA, + 0x05, 0x41, 0xCC, 0x88, 0xCC, 0x84, 0xCA, 0x05, + 0x41, 0xCC, 0x8A, 0xCC, 0x81, 0xCA, 0x05, 0x41, + // Bytes 38c0 - 38ff + 0xCC, 0xA3, 0xCC, 0x82, 0xCA, 0x05, 0x41, 0xCC, + 0xA3, 0xCC, 0x86, 0xCA, 0x05, 0x43, 0xCC, 0xA7, + 0xCC, 0x81, 0xCA, 0x05, 0x45, 0xCC, 0x82, 0xCC, + 0x80, 0xCA, 0x05, 0x45, 0xCC, 0x82, 0xCC, 0x81, + 0xCA, 0x05, 0x45, 0xCC, 0x82, 0xCC, 0x83, 0xCA, + 0x05, 0x45, 0xCC, 0x82, 0xCC, 0x89, 0xCA, 0x05, + 0x45, 0xCC, 0x84, 0xCC, 0x80, 0xCA, 0x05, 0x45, + 0xCC, 0x84, 0xCC, 0x81, 0xCA, 0x05, 0x45, 0xCC, + // Bytes 3900 - 393f + 0xA3, 0xCC, 0x82, 0xCA, 0x05, 0x45, 0xCC, 0xA7, + 0xCC, 0x86, 0xCA, 0x05, 0x49, 0xCC, 0x88, 0xCC, + 0x81, 0xCA, 0x05, 0x4C, 0xCC, 0xA3, 0xCC, 0x84, + 0xCA, 0x05, 0x4F, 0xCC, 0x82, 0xCC, 0x80, 0xCA, + 0x05, 0x4F, 0xCC, 0x82, 0xCC, 0x81, 0xCA, 0x05, + 0x4F, 0xCC, 0x82, 0xCC, 0x83, 0xCA, 0x05, 0x4F, + 0xCC, 0x82, 0xCC, 0x89, 0xCA, 0x05, 0x4F, 0xCC, + 0x83, 0xCC, 0x81, 0xCA, 0x05, 0x4F, 0xCC, 0x83, + // Bytes 3940 - 397f + 0xCC, 0x84, 0xCA, 0x05, 0x4F, 0xCC, 0x83, 0xCC, + 0x88, 0xCA, 0x05, 0x4F, 0xCC, 0x84, 0xCC, 0x80, + 0xCA, 0x05, 0x4F, 0xCC, 0x84, 0xCC, 0x81, 0xCA, + 0x05, 0x4F, 0xCC, 0x87, 0xCC, 0x84, 0xCA, 0x05, + 0x4F, 0xCC, 0x88, 0xCC, 0x84, 0xCA, 0x05, 0x4F, + 0xCC, 0x9B, 0xCC, 0x80, 0xCA, 0x05, 0x4F, 0xCC, + 0x9B, 0xCC, 0x81, 0xCA, 0x05, 0x4F, 0xCC, 0x9B, + 0xCC, 0x83, 0xCA, 0x05, 0x4F, 0xCC, 0x9B, 0xCC, + // Bytes 3980 - 39bf + 0x89, 0xCA, 0x05, 0x4F, 0xCC, 0x9B, 0xCC, 0xA3, + 0xB6, 0x05, 0x4F, 0xCC, 0xA3, 0xCC, 0x82, 0xCA, + 0x05, 0x4F, 0xCC, 0xA8, 0xCC, 0x84, 0xCA, 0x05, + 0x52, 0xCC, 0xA3, 0xCC, 0x84, 0xCA, 0x05, 0x53, + 0xCC, 0x81, 0xCC, 0x87, 0xCA, 0x05, 0x53, 0xCC, + 0x8C, 0xCC, 0x87, 0xCA, 0x05, 0x53, 0xCC, 0xA3, + 0xCC, 0x87, 0xCA, 0x05, 0x55, 0xCC, 0x83, 0xCC, + 0x81, 0xCA, 0x05, 0x55, 0xCC, 0x84, 0xCC, 0x88, + // Bytes 39c0 - 39ff + 0xCA, 0x05, 0x55, 0xCC, 0x88, 0xCC, 0x80, 0xCA, + 0x05, 0x55, 0xCC, 0x88, 0xCC, 0x81, 0xCA, 0x05, + 0x55, 0xCC, 0x88, 0xCC, 0x84, 0xCA, 0x05, 0x55, + 0xCC, 0x88, 0xCC, 0x8C, 0xCA, 0x05, 0x55, 0xCC, + 0x9B, 0xCC, 0x80, 0xCA, 0x05, 0x55, 0xCC, 0x9B, + 0xCC, 0x81, 0xCA, 0x05, 0x55, 0xCC, 0x9B, 0xCC, + 0x83, 0xCA, 0x05, 0x55, 0xCC, 0x9B, 0xCC, 0x89, + 0xCA, 0x05, 0x55, 0xCC, 0x9B, 0xCC, 0xA3, 0xB6, + // Bytes 3a00 - 3a3f + 0x05, 0x61, 0xCC, 0x82, 0xCC, 0x80, 0xCA, 0x05, + 0x61, 0xCC, 0x82, 0xCC, 0x81, 0xCA, 0x05, 0x61, + 0xCC, 0x82, 0xCC, 0x83, 0xCA, 0x05, 0x61, 0xCC, + 0x82, 0xCC, 0x89, 0xCA, 0x05, 0x61, 0xCC, 0x86, + 0xCC, 0x80, 0xCA, 0x05, 0x61, 0xCC, 0x86, 0xCC, + 0x81, 0xCA, 0x05, 0x61, 0xCC, 0x86, 0xCC, 0x83, + 0xCA, 0x05, 0x61, 0xCC, 0x86, 0xCC, 0x89, 0xCA, + 0x05, 0x61, 0xCC, 0x87, 0xCC, 0x84, 0xCA, 0x05, + // Bytes 3a40 - 3a7f + 0x61, 0xCC, 0x88, 0xCC, 0x84, 0xCA, 0x05, 0x61, + 0xCC, 0x8A, 0xCC, 0x81, 0xCA, 0x05, 0x61, 0xCC, + 0xA3, 0xCC, 0x82, 0xCA, 0x05, 0x61, 0xCC, 0xA3, + 0xCC, 0x86, 0xCA, 0x05, 0x63, 0xCC, 0xA7, 0xCC, + 0x81, 0xCA, 0x05, 0x65, 0xCC, 0x82, 0xCC, 0x80, + 0xCA, 0x05, 0x65, 0xCC, 0x82, 0xCC, 0x81, 0xCA, + 0x05, 0x65, 0xCC, 0x82, 0xCC, 0x83, 0xCA, 0x05, + 0x65, 0xCC, 0x82, 0xCC, 0x89, 0xCA, 0x05, 0x65, + // Bytes 3a80 - 3abf + 0xCC, 0x84, 0xCC, 0x80, 0xCA, 0x05, 0x65, 0xCC, + 0x84, 0xCC, 0x81, 0xCA, 0x05, 0x65, 0xCC, 0xA3, + 0xCC, 0x82, 0xCA, 0x05, 0x65, 0xCC, 0xA7, 0xCC, + 0x86, 0xCA, 0x05, 0x69, 0xCC, 0x88, 0xCC, 0x81, + 0xCA, 0x05, 0x6C, 0xCC, 0xA3, 0xCC, 0x84, 0xCA, + 0x05, 0x6F, 0xCC, 0x82, 0xCC, 0x80, 0xCA, 0x05, + 0x6F, 0xCC, 0x82, 0xCC, 0x81, 0xCA, 0x05, 0x6F, + 0xCC, 0x82, 0xCC, 0x83, 0xCA, 0x05, 0x6F, 0xCC, + // Bytes 3ac0 - 3aff + 0x82, 0xCC, 0x89, 0xCA, 0x05, 0x6F, 0xCC, 0x83, + 0xCC, 0x81, 0xCA, 0x05, 0x6F, 0xCC, 0x83, 0xCC, + 0x84, 0xCA, 0x05, 0x6F, 0xCC, 0x83, 0xCC, 0x88, + 0xCA, 0x05, 0x6F, 0xCC, 0x84, 0xCC, 0x80, 0xCA, + 0x05, 0x6F, 0xCC, 0x84, 0xCC, 0x81, 0xCA, 0x05, + 0x6F, 0xCC, 0x87, 0xCC, 0x84, 0xCA, 0x05, 0x6F, + 0xCC, 0x88, 0xCC, 0x84, 0xCA, 0x05, 0x6F, 0xCC, + 0x9B, 0xCC, 0x80, 0xCA, 0x05, 0x6F, 0xCC, 0x9B, + // Bytes 3b00 - 3b3f + 0xCC, 0x81, 0xCA, 0x05, 0x6F, 0xCC, 0x9B, 0xCC, + 0x83, 0xCA, 0x05, 0x6F, 0xCC, 0x9B, 0xCC, 0x89, + 0xCA, 0x05, 0x6F, 0xCC, 0x9B, 0xCC, 0xA3, 0xB6, + 0x05, 0x6F, 0xCC, 0xA3, 0xCC, 0x82, 0xCA, 0x05, + 0x6F, 0xCC, 0xA8, 0xCC, 0x84, 0xCA, 0x05, 0x72, + 0xCC, 0xA3, 0xCC, 0x84, 0xCA, 0x05, 0x73, 0xCC, + 0x81, 0xCC, 0x87, 0xCA, 0x05, 0x73, 0xCC, 0x8C, + 0xCC, 0x87, 0xCA, 0x05, 0x73, 0xCC, 0xA3, 0xCC, + // Bytes 3b40 - 3b7f + 0x87, 0xCA, 0x05, 0x75, 0xCC, 0x83, 0xCC, 0x81, + 0xCA, 0x05, 0x75, 0xCC, 0x84, 0xCC, 0x88, 0xCA, + 0x05, 0x75, 0xCC, 0x88, 0xCC, 0x80, 0xCA, 0x05, + 0x75, 0xCC, 0x88, 0xCC, 0x81, 0xCA, 0x05, 0x75, + 0xCC, 0x88, 0xCC, 0x84, 0xCA, 0x05, 0x75, 0xCC, + 0x88, 0xCC, 0x8C, 0xCA, 0x05, 0x75, 0xCC, 0x9B, + 0xCC, 0x80, 0xCA, 0x05, 0x75, 0xCC, 0x9B, 0xCC, + 0x81, 0xCA, 0x05, 0x75, 0xCC, 0x9B, 0xCC, 0x83, + // Bytes 3b80 - 3bbf + 0xCA, 0x05, 0x75, 0xCC, 0x9B, 0xCC, 0x89, 0xCA, + 0x05, 0x75, 0xCC, 0x9B, 0xCC, 0xA3, 0xB6, 0x05, + 0xE1, 0xBE, 0xBF, 0xCC, 0x80, 0xCA, 0x05, 0xE1, + 0xBE, 0xBF, 0xCC, 0x81, 0xCA, 0x05, 0xE1, 0xBE, + 0xBF, 0xCD, 0x82, 0xCA, 0x05, 0xE1, 0xBF, 0xBE, + 0xCC, 0x80, 0xCA, 0x05, 0xE1, 0xBF, 0xBE, 0xCC, + 0x81, 0xCA, 0x05, 0xE1, 0xBF, 0xBE, 0xCD, 0x82, + 0xCA, 0x05, 0xE2, 0x86, 0x90, 0xCC, 0xB8, 0x05, + // Bytes 3bc0 - 3bff + 0x05, 0xE2, 0x86, 0x92, 0xCC, 0xB8, 0x05, 0x05, + 0xE2, 0x86, 0x94, 0xCC, 0xB8, 0x05, 0x05, 0xE2, + 0x87, 0x90, 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x87, + 0x92, 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x87, 0x94, + 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x88, 0x83, 0xCC, + 0xB8, 0x05, 0x05, 0xE2, 0x88, 0x88, 0xCC, 0xB8, + 0x05, 0x05, 0xE2, 0x88, 0x8B, 0xCC, 0xB8, 0x05, + 0x05, 0xE2, 0x88, 0xA3, 0xCC, 0xB8, 0x05, 0x05, + // Bytes 3c00 - 3c3f + 0xE2, 0x88, 0xA5, 0xCC, 0xB8, 0x05, 0x05, 0xE2, + 0x88, 0xBC, 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x89, + 0x83, 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x89, 0x85, + 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x89, 0x88, 0xCC, + 0xB8, 0x05, 0x05, 0xE2, 0x89, 0x8D, 0xCC, 0xB8, + 0x05, 0x05, 0xE2, 0x89, 0xA1, 0xCC, 0xB8, 0x05, + 0x05, 0xE2, 0x89, 0xA4, 0xCC, 0xB8, 0x05, 0x05, + 0xE2, 0x89, 0xA5, 0xCC, 0xB8, 0x05, 0x05, 0xE2, + // Bytes 3c40 - 3c7f + 0x89, 0xB2, 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x89, + 0xB3, 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x89, 0xB6, + 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x89, 0xB7, 0xCC, + 0xB8, 0x05, 0x05, 0xE2, 0x89, 0xBA, 0xCC, 0xB8, + 0x05, 0x05, 0xE2, 0x89, 0xBB, 0xCC, 0xB8, 0x05, + 0x05, 0xE2, 0x89, 0xBC, 0xCC, 0xB8, 0x05, 0x05, + 0xE2, 0x89, 0xBD, 0xCC, 0xB8, 0x05, 0x05, 0xE2, + 0x8A, 0x82, 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x8A, + // Bytes 3c80 - 3cbf + 0x83, 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x8A, 0x86, + 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x8A, 0x87, 0xCC, + 0xB8, 0x05, 0x05, 0xE2, 0x8A, 0x91, 0xCC, 0xB8, + 0x05, 0x05, 0xE2, 0x8A, 0x92, 0xCC, 0xB8, 0x05, + 0x05, 0xE2, 0x8A, 0xA2, 0xCC, 0xB8, 0x05, 0x05, + 0xE2, 0x8A, 0xA8, 0xCC, 0xB8, 0x05, 0x05, 0xE2, + 0x8A, 0xA9, 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x8A, + 0xAB, 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x8A, 0xB2, + // Bytes 3cc0 - 3cff + 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x8A, 0xB3, 0xCC, + 0xB8, 0x05, 0x05, 0xE2, 0x8A, 0xB4, 0xCC, 0xB8, + 0x05, 0x05, 0xE2, 0x8A, 0xB5, 0xCC, 0xB8, 0x05, + 0x06, 0xCE, 0x91, 0xCC, 0x93, 0xCD, 0x85, 0xDA, + 0x06, 0xCE, 0x91, 0xCC, 0x94, 0xCD, 0x85, 0xDA, + 0x06, 0xCE, 0x95, 0xCC, 0x93, 0xCC, 0x80, 0xCA, + 0x06, 0xCE, 0x95, 0xCC, 0x93, 0xCC, 0x81, 0xCA, + 0x06, 0xCE, 0x95, 0xCC, 0x94, 0xCC, 0x80, 0xCA, + // Bytes 3d00 - 3d3f + 0x06, 0xCE, 0x95, 0xCC, 0x94, 0xCC, 0x81, 0xCA, + 0x06, 0xCE, 0x97, 0xCC, 0x93, 0xCD, 0x85, 0xDA, + 0x06, 0xCE, 0x97, 0xCC, 0x94, 0xCD, 0x85, 0xDA, + 0x06, 0xCE, 0x99, 0xCC, 0x93, 0xCC, 0x80, 0xCA, + 0x06, 0xCE, 0x99, 0xCC, 0x93, 0xCC, 0x81, 0xCA, + 0x06, 0xCE, 0x99, 0xCC, 0x93, 0xCD, 0x82, 0xCA, + 0x06, 0xCE, 0x99, 0xCC, 0x94, 0xCC, 0x80, 0xCA, + 0x06, 0xCE, 0x99, 0xCC, 0x94, 0xCC, 0x81, 0xCA, + // Bytes 3d40 - 3d7f + 0x06, 0xCE, 0x99, 0xCC, 0x94, 0xCD, 0x82, 0xCA, + 0x06, 0xCE, 0x9F, 0xCC, 0x93, 0xCC, 0x80, 0xCA, + 0x06, 0xCE, 0x9F, 0xCC, 0x93, 0xCC, 0x81, 0xCA, + 0x06, 0xCE, 0x9F, 0xCC, 0x94, 0xCC, 0x80, 0xCA, + 0x06, 0xCE, 0x9F, 0xCC, 0x94, 0xCC, 0x81, 0xCA, + 0x06, 0xCE, 0xA5, 0xCC, 0x94, 0xCC, 0x80, 0xCA, + 0x06, 0xCE, 0xA5, 0xCC, 0x94, 0xCC, 0x81, 0xCA, + 0x06, 0xCE, 0xA5, 0xCC, 0x94, 0xCD, 0x82, 0xCA, + // Bytes 3d80 - 3dbf + 0x06, 0xCE, 0xA9, 0xCC, 0x93, 0xCD, 0x85, 0xDA, + 0x06, 0xCE, 0xA9, 0xCC, 0x94, 0xCD, 0x85, 0xDA, + 0x06, 0xCE, 0xB1, 0xCC, 0x80, 0xCD, 0x85, 0xDA, + 0x06, 0xCE, 0xB1, 0xCC, 0x81, 0xCD, 0x85, 0xDA, + 0x06, 0xCE, 0xB1, 0xCC, 0x93, 0xCD, 0x85, 0xDA, + 0x06, 0xCE, 0xB1, 0xCC, 0x94, 0xCD, 0x85, 0xDA, + 0x06, 0xCE, 0xB1, 0xCD, 0x82, 0xCD, 0x85, 0xDA, + 0x06, 0xCE, 0xB5, 0xCC, 0x93, 0xCC, 0x80, 0xCA, + // Bytes 3dc0 - 3dff + 0x06, 0xCE, 0xB5, 0xCC, 0x93, 0xCC, 0x81, 0xCA, + 0x06, 0xCE, 0xB5, 0xCC, 0x94, 0xCC, 0x80, 0xCA, + 0x06, 0xCE, 0xB5, 0xCC, 0x94, 0xCC, 0x81, 0xCA, + 0x06, 0xCE, 0xB7, 0xCC, 0x80, 0xCD, 0x85, 0xDA, + 0x06, 0xCE, 0xB7, 0xCC, 0x81, 0xCD, 0x85, 0xDA, + 0x06, 0xCE, 0xB7, 0xCC, 0x93, 0xCD, 0x85, 0xDA, + 0x06, 0xCE, 0xB7, 0xCC, 0x94, 0xCD, 0x85, 0xDA, + 0x06, 0xCE, 0xB7, 0xCD, 0x82, 0xCD, 0x85, 0xDA, + // Bytes 3e00 - 3e3f + 0x06, 0xCE, 0xB9, 0xCC, 0x88, 0xCC, 0x80, 0xCA, + 0x06, 0xCE, 0xB9, 0xCC, 0x88, 0xCC, 0x81, 0xCA, + 0x06, 0xCE, 0xB9, 0xCC, 0x88, 0xCD, 0x82, 0xCA, + 0x06, 0xCE, 0xB9, 0xCC, 0x93, 0xCC, 0x80, 0xCA, + 0x06, 0xCE, 0xB9, 0xCC, 0x93, 0xCC, 0x81, 0xCA, + 0x06, 0xCE, 0xB9, 0xCC, 0x93, 0xCD, 0x82, 0xCA, + 0x06, 0xCE, 0xB9, 0xCC, 0x94, 0xCC, 0x80, 0xCA, + 0x06, 0xCE, 0xB9, 0xCC, 0x94, 0xCC, 0x81, 0xCA, + // Bytes 3e40 - 3e7f + 0x06, 0xCE, 0xB9, 0xCC, 0x94, 0xCD, 0x82, 0xCA, + 0x06, 0xCE, 0xBF, 0xCC, 0x93, 0xCC, 0x80, 0xCA, + 0x06, 0xCE, 0xBF, 0xCC, 0x93, 0xCC, 0x81, 0xCA, + 0x06, 0xCE, 0xBF, 0xCC, 0x94, 0xCC, 0x80, 0xCA, + 0x06, 0xCE, 0xBF, 0xCC, 0x94, 0xCC, 0x81, 0xCA, + 0x06, 0xCF, 0x85, 0xCC, 0x88, 0xCC, 0x80, 0xCA, + 0x06, 0xCF, 0x85, 0xCC, 0x88, 0xCC, 0x81, 0xCA, + 0x06, 0xCF, 0x85, 0xCC, 0x88, 0xCD, 0x82, 0xCA, + // Bytes 3e80 - 3ebf + 0x06, 0xCF, 0x85, 0xCC, 0x93, 0xCC, 0x80, 0xCA, + 0x06, 0xCF, 0x85, 0xCC, 0x93, 0xCC, 0x81, 0xCA, + 0x06, 0xCF, 0x85, 0xCC, 0x93, 0xCD, 0x82, 0xCA, + 0x06, 0xCF, 0x85, 0xCC, 0x94, 0xCC, 0x80, 0xCA, + 0x06, 0xCF, 0x85, 0xCC, 0x94, 0xCC, 0x81, 0xCA, + 0x06, 0xCF, 0x85, 0xCC, 0x94, 0xCD, 0x82, 0xCA, + 0x06, 0xCF, 0x89, 0xCC, 0x80, 0xCD, 0x85, 0xDA, + 0x06, 0xCF, 0x89, 0xCC, 0x81, 0xCD, 0x85, 0xDA, + // Bytes 3ec0 - 3eff + 0x06, 0xCF, 0x89, 0xCC, 0x93, 0xCD, 0x85, 0xDA, + 0x06, 0xCF, 0x89, 0xCC, 0x94, 0xCD, 0x85, 0xDA, + 0x06, 0xCF, 0x89, 0xCD, 0x82, 0xCD, 0x85, 0xDA, + 0x06, 0xE0, 0xA4, 0xA8, 0xE0, 0xA4, 0xBC, 0x09, + 0x06, 0xE0, 0xA4, 0xB0, 0xE0, 0xA4, 0xBC, 0x09, + 0x06, 0xE0, 0xA4, 0xB3, 0xE0, 0xA4, 0xBC, 0x09, + 0x06, 0xE0, 0xB1, 0x86, 0xE0, 0xB1, 0x96, 0x85, + 0x06, 0xE0, 0xB7, 0x99, 0xE0, 0xB7, 0x8A, 0x11, + // Bytes 3f00 - 3f3f + 0x06, 0xE3, 0x81, 0x86, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x81, 0x8B, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x81, 0x8D, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x81, 0x8F, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x81, 0x91, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x81, 0x93, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x81, 0x95, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x81, 0x97, 0xE3, 0x82, 0x99, 0x0D, + // Bytes 3f40 - 3f7f + 0x06, 0xE3, 0x81, 0x99, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x81, 0x9B, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x81, 0x9D, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x81, 0x9F, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x81, 0xA1, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x81, 0xA4, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x81, 0xA6, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x81, 0xA8, 0xE3, 0x82, 0x99, 0x0D, + // Bytes 3f80 - 3fbf + 0x06, 0xE3, 0x81, 0xAF, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x81, 0xAF, 0xE3, 0x82, 0x9A, 0x0D, + 0x06, 0xE3, 0x81, 0xB2, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x81, 0xB2, 0xE3, 0x82, 0x9A, 0x0D, + 0x06, 0xE3, 0x81, 0xB5, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x81, 0xB5, 0xE3, 0x82, 0x9A, 0x0D, + 0x06, 0xE3, 0x81, 0xB8, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x81, 0xB8, 0xE3, 0x82, 0x9A, 0x0D, + // Bytes 3fc0 - 3fff + 0x06, 0xE3, 0x81, 0xBB, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x81, 0xBB, 0xE3, 0x82, 0x9A, 0x0D, + 0x06, 0xE3, 0x82, 0x9D, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x82, 0xA6, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x82, 0xAB, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x82, 0xAD, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x82, 0xAF, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x82, 0xB1, 0xE3, 0x82, 0x99, 0x0D, + // Bytes 4000 - 403f + 0x06, 0xE3, 0x82, 0xB3, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x82, 0xB5, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x82, 0xB7, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x82, 0xB9, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x82, 0xBB, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x82, 0xBD, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x82, 0xBF, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x83, 0x81, 0xE3, 0x82, 0x99, 0x0D, + // Bytes 4040 - 407f + 0x06, 0xE3, 0x83, 0x84, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x83, 0x86, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x83, 0x88, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x83, 0x8F, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x83, 0x8F, 0xE3, 0x82, 0x9A, 0x0D, + 0x06, 0xE3, 0x83, 0x92, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x83, 0x92, 0xE3, 0x82, 0x9A, 0x0D, + 0x06, 0xE3, 0x83, 0x95, 0xE3, 0x82, 0x99, 0x0D, + // Bytes 4080 - 40bf + 0x06, 0xE3, 0x83, 0x95, 0xE3, 0x82, 0x9A, 0x0D, + 0x06, 0xE3, 0x83, 0x98, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x83, 0x98, 0xE3, 0x82, 0x9A, 0x0D, + 0x06, 0xE3, 0x83, 0x9B, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x83, 0x9B, 0xE3, 0x82, 0x9A, 0x0D, + 0x06, 0xE3, 0x83, 0xAF, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x83, 0xB0, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x83, 0xB1, 0xE3, 0x82, 0x99, 0x0D, + // Bytes 40c0 - 40ff + 0x06, 0xE3, 0x83, 0xB2, 0xE3, 0x82, 0x99, 0x0D, + 0x06, 0xE3, 0x83, 0xBD, 0xE3, 0x82, 0x99, 0x0D, + 0x08, 0xCE, 0x91, 0xCC, 0x93, 0xCC, 0x80, 0xCD, + 0x85, 0xDB, 0x08, 0xCE, 0x91, 0xCC, 0x93, 0xCC, + 0x81, 0xCD, 0x85, 0xDB, 0x08, 0xCE, 0x91, 0xCC, + 0x93, 0xCD, 0x82, 0xCD, 0x85, 0xDB, 0x08, 0xCE, + 0x91, 0xCC, 0x94, 0xCC, 0x80, 0xCD, 0x85, 0xDB, + 0x08, 0xCE, 0x91, 0xCC, 0x94, 0xCC, 0x81, 0xCD, + // Bytes 4100 - 413f + 0x85, 0xDB, 0x08, 0xCE, 0x91, 0xCC, 0x94, 0xCD, + 0x82, 0xCD, 0x85, 0xDB, 0x08, 0xCE, 0x97, 0xCC, + 0x93, 0xCC, 0x80, 0xCD, 0x85, 0xDB, 0x08, 0xCE, + 0x97, 0xCC, 0x93, 0xCC, 0x81, 0xCD, 0x85, 0xDB, + 0x08, 0xCE, 0x97, 0xCC, 0x93, 0xCD, 0x82, 0xCD, + 0x85, 0xDB, 0x08, 0xCE, 0x97, 0xCC, 0x94, 0xCC, + 0x80, 0xCD, 0x85, 0xDB, 0x08, 0xCE, 0x97, 0xCC, + 0x94, 0xCC, 0x81, 0xCD, 0x85, 0xDB, 0x08, 0xCE, + // Bytes 4140 - 417f + 0x97, 0xCC, 0x94, 0xCD, 0x82, 0xCD, 0x85, 0xDB, + 0x08, 0xCE, 0xA9, 0xCC, 0x93, 0xCC, 0x80, 0xCD, + 0x85, 0xDB, 0x08, 0xCE, 0xA9, 0xCC, 0x93, 0xCC, + 0x81, 0xCD, 0x85, 0xDB, 0x08, 0xCE, 0xA9, 0xCC, + 0x93, 0xCD, 0x82, 0xCD, 0x85, 0xDB, 0x08, 0xCE, + 0xA9, 0xCC, 0x94, 0xCC, 0x80, 0xCD, 0x85, 0xDB, + 0x08, 0xCE, 0xA9, 0xCC, 0x94, 0xCC, 0x81, 0xCD, + 0x85, 0xDB, 0x08, 0xCE, 0xA9, 0xCC, 0x94, 0xCD, + // Bytes 4180 - 41bf + 0x82, 0xCD, 0x85, 0xDB, 0x08, 0xCE, 0xB1, 0xCC, + 0x93, 0xCC, 0x80, 0xCD, 0x85, 0xDB, 0x08, 0xCE, + 0xB1, 0xCC, 0x93, 0xCC, 0x81, 0xCD, 0x85, 0xDB, + 0x08, 0xCE, 0xB1, 0xCC, 0x93, 0xCD, 0x82, 0xCD, + 0x85, 0xDB, 0x08, 0xCE, 0xB1, 0xCC, 0x94, 0xCC, + 0x80, 0xCD, 0x85, 0xDB, 0x08, 0xCE, 0xB1, 0xCC, + 0x94, 0xCC, 0x81, 0xCD, 0x85, 0xDB, 0x08, 0xCE, + 0xB1, 0xCC, 0x94, 0xCD, 0x82, 0xCD, 0x85, 0xDB, + // Bytes 41c0 - 41ff + 0x08, 0xCE, 0xB7, 0xCC, 0x93, 0xCC, 0x80, 0xCD, + 0x85, 0xDB, 0x08, 0xCE, 0xB7, 0xCC, 0x93, 0xCC, + 0x81, 0xCD, 0x85, 0xDB, 0x08, 0xCE, 0xB7, 0xCC, + 0x93, 0xCD, 0x82, 0xCD, 0x85, 0xDB, 0x08, 0xCE, + 0xB7, 0xCC, 0x94, 0xCC, 0x80, 0xCD, 0x85, 0xDB, + 0x08, 0xCE, 0xB7, 0xCC, 0x94, 0xCC, 0x81, 0xCD, + 0x85, 0xDB, 0x08, 0xCE, 0xB7, 0xCC, 0x94, 0xCD, + 0x82, 0xCD, 0x85, 0xDB, 0x08, 0xCF, 0x89, 0xCC, + // Bytes 4200 - 423f + 0x93, 0xCC, 0x80, 0xCD, 0x85, 0xDB, 0x08, 0xCF, + 0x89, 0xCC, 0x93, 0xCC, 0x81, 0xCD, 0x85, 0xDB, + 0x08, 0xCF, 0x89, 0xCC, 0x93, 0xCD, 0x82, 0xCD, + 0x85, 0xDB, 0x08, 0xCF, 0x89, 0xCC, 0x94, 0xCC, + 0x80, 0xCD, 0x85, 0xDB, 0x08, 0xCF, 0x89, 0xCC, + 0x94, 0xCC, 0x81, 0xCD, 0x85, 0xDB, 0x08, 0xCF, + 0x89, 0xCC, 0x94, 0xCD, 0x82, 0xCD, 0x85, 0xDB, + 0x08, 0xF0, 0x91, 0x82, 0x99, 0xF0, 0x91, 0x82, + // Bytes 4240 - 427f + 0xBA, 0x09, 0x08, 0xF0, 0x91, 0x82, 0x9B, 0xF0, + 0x91, 0x82, 0xBA, 0x09, 0x08, 0xF0, 0x91, 0x82, + 0xA5, 0xF0, 0x91, 0x82, 0xBA, 0x09, 0x42, 0xC2, + 0xB4, 0x01, 0x43, 0x20, 0xCC, 0x81, 0xC9, 0x43, + 0x20, 0xCC, 0x83, 0xC9, 0x43, 0x20, 0xCC, 0x84, + 0xC9, 0x43, 0x20, 0xCC, 0x85, 0xC9, 0x43, 0x20, + 0xCC, 0x86, 0xC9, 0x43, 0x20, 0xCC, 0x87, 0xC9, + 0x43, 0x20, 0xCC, 0x88, 0xC9, 0x43, 0x20, 0xCC, + // Bytes 4280 - 42bf + 0x8A, 0xC9, 0x43, 0x20, 0xCC, 0x8B, 0xC9, 0x43, + 0x20, 0xCC, 0x93, 0xC9, 0x43, 0x20, 0xCC, 0x94, + 0xC9, 0x43, 0x20, 0xCC, 0xA7, 0xA5, 0x43, 0x20, + 0xCC, 0xA8, 0xA5, 0x43, 0x20, 0xCC, 0xB3, 0xB5, + 0x43, 0x20, 0xCD, 0x82, 0xC9, 0x43, 0x20, 0xCD, + 0x85, 0xD9, 0x43, 0x20, 0xD9, 0x8B, 0x59, 0x43, + 0x20, 0xD9, 0x8C, 0x5D, 0x43, 0x20, 0xD9, 0x8D, + 0x61, 0x43, 0x20, 0xD9, 0x8E, 0x65, 0x43, 0x20, + // Bytes 42c0 - 42ff + 0xD9, 0x8F, 0x69, 0x43, 0x20, 0xD9, 0x90, 0x6D, + 0x43, 0x20, 0xD9, 0x91, 0x71, 0x43, 0x20, 0xD9, + 0x92, 0x75, 0x43, 0x41, 0xCC, 0x8A, 0xC9, 0x43, + 0x73, 0xCC, 0x87, 0xC9, 0x44, 0x20, 0xE3, 0x82, + 0x99, 0x0D, 0x44, 0x20, 0xE3, 0x82, 0x9A, 0x0D, + 0x44, 0xC2, 0xA8, 0xCC, 0x81, 0xCA, 0x44, 0xCE, + 0x91, 0xCC, 0x81, 0xC9, 0x44, 0xCE, 0x95, 0xCC, + 0x81, 0xC9, 0x44, 0xCE, 0x97, 0xCC, 0x81, 0xC9, + // Bytes 4300 - 433f + 0x44, 0xCE, 0x99, 0xCC, 0x81, 0xC9, 0x44, 0xCE, + 0x9F, 0xCC, 0x81, 0xC9, 0x44, 0xCE, 0xA5, 0xCC, + 0x81, 0xC9, 0x44, 0xCE, 0xA5, 0xCC, 0x88, 0xC9, + 0x44, 0xCE, 0xA9, 0xCC, 0x81, 0xC9, 0x44, 0xCE, + 0xB1, 0xCC, 0x81, 0xC9, 0x44, 0xCE, 0xB5, 0xCC, + 0x81, 0xC9, 0x44, 0xCE, 0xB7, 0xCC, 0x81, 0xC9, + 0x44, 0xCE, 0xB9, 0xCC, 0x81, 0xC9, 0x44, 0xCE, + 0xBF, 0xCC, 0x81, 0xC9, 0x44, 0xCF, 0x85, 0xCC, + // Bytes 4340 - 437f + 0x81, 0xC9, 0x44, 0xCF, 0x89, 0xCC, 0x81, 0xC9, + 0x44, 0xD7, 0x90, 0xD6, 0xB7, 0x31, 0x44, 0xD7, + 0x90, 0xD6, 0xB8, 0x35, 0x44, 0xD7, 0x90, 0xD6, + 0xBC, 0x41, 0x44, 0xD7, 0x91, 0xD6, 0xBC, 0x41, + 0x44, 0xD7, 0x91, 0xD6, 0xBF, 0x49, 0x44, 0xD7, + 0x92, 0xD6, 0xBC, 0x41, 0x44, 0xD7, 0x93, 0xD6, + 0xBC, 0x41, 0x44, 0xD7, 0x94, 0xD6, 0xBC, 0x41, + 0x44, 0xD7, 0x95, 0xD6, 0xB9, 0x39, 0x44, 0xD7, + // Bytes 4380 - 43bf + 0x95, 0xD6, 0xBC, 0x41, 0x44, 0xD7, 0x96, 0xD6, + 0xBC, 0x41, 0x44, 0xD7, 0x98, 0xD6, 0xBC, 0x41, + 0x44, 0xD7, 0x99, 0xD6, 0xB4, 0x25, 0x44, 0xD7, + 0x99, 0xD6, 0xBC, 0x41, 0x44, 0xD7, 0x9A, 0xD6, + 0xBC, 0x41, 0x44, 0xD7, 0x9B, 0xD6, 0xBC, 0x41, + 0x44, 0xD7, 0x9B, 0xD6, 0xBF, 0x49, 0x44, 0xD7, + 0x9C, 0xD6, 0xBC, 0x41, 0x44, 0xD7, 0x9E, 0xD6, + 0xBC, 0x41, 0x44, 0xD7, 0xA0, 0xD6, 0xBC, 0x41, + // Bytes 43c0 - 43ff + 0x44, 0xD7, 0xA1, 0xD6, 0xBC, 0x41, 0x44, 0xD7, + 0xA3, 0xD6, 0xBC, 0x41, 0x44, 0xD7, 0xA4, 0xD6, + 0xBC, 0x41, 0x44, 0xD7, 0xA4, 0xD6, 0xBF, 0x49, + 0x44, 0xD7, 0xA6, 0xD6, 0xBC, 0x41, 0x44, 0xD7, + 0xA7, 0xD6, 0xBC, 0x41, 0x44, 0xD7, 0xA8, 0xD6, + 0xBC, 0x41, 0x44, 0xD7, 0xA9, 0xD6, 0xBC, 0x41, + 0x44, 0xD7, 0xA9, 0xD7, 0x81, 0x4D, 0x44, 0xD7, + 0xA9, 0xD7, 0x82, 0x51, 0x44, 0xD7, 0xAA, 0xD6, + // Bytes 4400 - 443f + 0xBC, 0x41, 0x44, 0xD7, 0xB2, 0xD6, 0xB7, 0x31, + 0x44, 0xD8, 0xA7, 0xD9, 0x8B, 0x59, 0x44, 0xD8, + 0xA7, 0xD9, 0x93, 0xC9, 0x44, 0xD8, 0xA7, 0xD9, + 0x94, 0xC9, 0x44, 0xD8, 0xA7, 0xD9, 0x95, 0xB5, + 0x44, 0xD8, 0xB0, 0xD9, 0xB0, 0x79, 0x44, 0xD8, + 0xB1, 0xD9, 0xB0, 0x79, 0x44, 0xD9, 0x80, 0xD9, + 0x8B, 0x59, 0x44, 0xD9, 0x80, 0xD9, 0x8E, 0x65, + 0x44, 0xD9, 0x80, 0xD9, 0x8F, 0x69, 0x44, 0xD9, + // Bytes 4440 - 447f + 0x80, 0xD9, 0x90, 0x6D, 0x44, 0xD9, 0x80, 0xD9, + 0x91, 0x71, 0x44, 0xD9, 0x80, 0xD9, 0x92, 0x75, + 0x44, 0xD9, 0x87, 0xD9, 0xB0, 0x79, 0x44, 0xD9, + 0x88, 0xD9, 0x94, 0xC9, 0x44, 0xD9, 0x89, 0xD9, + 0xB0, 0x79, 0x44, 0xD9, 0x8A, 0xD9, 0x94, 0xC9, + 0x44, 0xDB, 0x92, 0xD9, 0x94, 0xC9, 0x44, 0xDB, + 0x95, 0xD9, 0x94, 0xC9, 0x45, 0x20, 0xCC, 0x88, + 0xCC, 0x80, 0xCA, 0x45, 0x20, 0xCC, 0x88, 0xCC, + // Bytes 4480 - 44bf + 0x81, 0xCA, 0x45, 0x20, 0xCC, 0x88, 0xCD, 0x82, + 0xCA, 0x45, 0x20, 0xCC, 0x93, 0xCC, 0x80, 0xCA, + 0x45, 0x20, 0xCC, 0x93, 0xCC, 0x81, 0xCA, 0x45, + 0x20, 0xCC, 0x93, 0xCD, 0x82, 0xCA, 0x45, 0x20, + 0xCC, 0x94, 0xCC, 0x80, 0xCA, 0x45, 0x20, 0xCC, + 0x94, 0xCC, 0x81, 0xCA, 0x45, 0x20, 0xCC, 0x94, + 0xCD, 0x82, 0xCA, 0x45, 0x20, 0xD9, 0x8C, 0xD9, + 0x91, 0x72, 0x45, 0x20, 0xD9, 0x8D, 0xD9, 0x91, + // Bytes 44c0 - 44ff + 0x72, 0x45, 0x20, 0xD9, 0x8E, 0xD9, 0x91, 0x72, + 0x45, 0x20, 0xD9, 0x8F, 0xD9, 0x91, 0x72, 0x45, + 0x20, 0xD9, 0x90, 0xD9, 0x91, 0x72, 0x45, 0x20, + 0xD9, 0x91, 0xD9, 0xB0, 0x7A, 0x45, 0xE2, 0xAB, + 0x9D, 0xCC, 0xB8, 0x05, 0x46, 0xCE, 0xB9, 0xCC, + 0x88, 0xCC, 0x81, 0xCA, 0x46, 0xCF, 0x85, 0xCC, + 0x88, 0xCC, 0x81, 0xCA, 0x46, 0xD7, 0xA9, 0xD6, + 0xBC, 0xD7, 0x81, 0x4E, 0x46, 0xD7, 0xA9, 0xD6, + // Bytes 4500 - 453f + 0xBC, 0xD7, 0x82, 0x52, 0x46, 0xD9, 0x80, 0xD9, + 0x8E, 0xD9, 0x91, 0x72, 0x46, 0xD9, 0x80, 0xD9, + 0x8F, 0xD9, 0x91, 0x72, 0x46, 0xD9, 0x80, 0xD9, + 0x90, 0xD9, 0x91, 0x72, 0x46, 0xE0, 0xA4, 0x95, + 0xE0, 0xA4, 0xBC, 0x09, 0x46, 0xE0, 0xA4, 0x96, + 0xE0, 0xA4, 0xBC, 0x09, 0x46, 0xE0, 0xA4, 0x97, + 0xE0, 0xA4, 0xBC, 0x09, 0x46, 0xE0, 0xA4, 0x9C, + 0xE0, 0xA4, 0xBC, 0x09, 0x46, 0xE0, 0xA4, 0xA1, + // Bytes 4540 - 457f + 0xE0, 0xA4, 0xBC, 0x09, 0x46, 0xE0, 0xA4, 0xA2, + 0xE0, 0xA4, 0xBC, 0x09, 0x46, 0xE0, 0xA4, 0xAB, + 0xE0, 0xA4, 0xBC, 0x09, 0x46, 0xE0, 0xA4, 0xAF, + 0xE0, 0xA4, 0xBC, 0x09, 0x46, 0xE0, 0xA6, 0xA1, + 0xE0, 0xA6, 0xBC, 0x09, 0x46, 0xE0, 0xA6, 0xA2, + 0xE0, 0xA6, 0xBC, 0x09, 0x46, 0xE0, 0xA6, 0xAF, + 0xE0, 0xA6, 0xBC, 0x09, 0x46, 0xE0, 0xA8, 0x96, + 0xE0, 0xA8, 0xBC, 0x09, 0x46, 0xE0, 0xA8, 0x97, + // Bytes 4580 - 45bf + 0xE0, 0xA8, 0xBC, 0x09, 0x46, 0xE0, 0xA8, 0x9C, + 0xE0, 0xA8, 0xBC, 0x09, 0x46, 0xE0, 0xA8, 0xAB, + 0xE0, 0xA8, 0xBC, 0x09, 0x46, 0xE0, 0xA8, 0xB2, + 0xE0, 0xA8, 0xBC, 0x09, 0x46, 0xE0, 0xA8, 0xB8, + 0xE0, 0xA8, 0xBC, 0x09, 0x46, 0xE0, 0xAC, 0xA1, + 0xE0, 0xAC, 0xBC, 0x09, 0x46, 0xE0, 0xAC, 0xA2, + 0xE0, 0xAC, 0xBC, 0x09, 0x46, 0xE0, 0xBE, 0xB2, + 0xE0, 0xBE, 0x80, 0x9D, 0x46, 0xE0, 0xBE, 0xB3, + // Bytes 45c0 - 45ff + 0xE0, 0xBE, 0x80, 0x9D, 0x46, 0xE3, 0x83, 0x86, + 0xE3, 0x82, 0x99, 0x0D, 0x48, 0xF0, 0x9D, 0x85, + 0x97, 0xF0, 0x9D, 0x85, 0xA5, 0xAD, 0x48, 0xF0, + 0x9D, 0x85, 0x98, 0xF0, 0x9D, 0x85, 0xA5, 0xAD, + 0x48, 0xF0, 0x9D, 0x86, 0xB9, 0xF0, 0x9D, 0x85, + 0xA5, 0xAD, 0x48, 0xF0, 0x9D, 0x86, 0xBA, 0xF0, + 0x9D, 0x85, 0xA5, 0xAD, 0x49, 0xE0, 0xBE, 0xB2, + 0xE0, 0xBD, 0xB1, 0xE0, 0xBE, 0x80, 0x9E, 0x49, + // Bytes 4600 - 463f + 0xE0, 0xBE, 0xB3, 0xE0, 0xBD, 0xB1, 0xE0, 0xBE, + 0x80, 0x9E, 0x4C, 0xF0, 0x9D, 0x85, 0x98, 0xF0, + 0x9D, 0x85, 0xA5, 0xF0, 0x9D, 0x85, 0xAE, 0xAE, + 0x4C, 0xF0, 0x9D, 0x85, 0x98, 0xF0, 0x9D, 0x85, + 0xA5, 0xF0, 0x9D, 0x85, 0xAF, 0xAE, 0x4C, 0xF0, + 0x9D, 0x85, 0x98, 0xF0, 0x9D, 0x85, 0xA5, 0xF0, + 0x9D, 0x85, 0xB0, 0xAE, 0x4C, 0xF0, 0x9D, 0x85, + 0x98, 0xF0, 0x9D, 0x85, 0xA5, 0xF0, 0x9D, 0x85, + // Bytes 4640 - 467f + 0xB1, 0xAE, 0x4C, 0xF0, 0x9D, 0x85, 0x98, 0xF0, + 0x9D, 0x85, 0xA5, 0xF0, 0x9D, 0x85, 0xB2, 0xAE, + 0x4C, 0xF0, 0x9D, 0x86, 0xB9, 0xF0, 0x9D, 0x85, + 0xA5, 0xF0, 0x9D, 0x85, 0xAE, 0xAE, 0x4C, 0xF0, + 0x9D, 0x86, 0xB9, 0xF0, 0x9D, 0x85, 0xA5, 0xF0, + 0x9D, 0x85, 0xAF, 0xAE, 0x4C, 0xF0, 0x9D, 0x86, + 0xBA, 0xF0, 0x9D, 0x85, 0xA5, 0xF0, 0x9D, 0x85, + 0xAE, 0xAE, 0x4C, 0xF0, 0x9D, 0x86, 0xBA, 0xF0, + // Bytes 4680 - 46bf + 0x9D, 0x85, 0xA5, 0xF0, 0x9D, 0x85, 0xAF, 0xAE, + 0x83, 0x41, 0xCC, 0x82, 0xC9, 0x83, 0x41, 0xCC, + 0x86, 0xC9, 0x83, 0x41, 0xCC, 0x87, 0xC9, 0x83, + 0x41, 0xCC, 0x88, 0xC9, 0x83, 0x41, 0xCC, 0x8A, + 0xC9, 0x83, 0x41, 0xCC, 0xA3, 0xB5, 0x83, 0x43, + 0xCC, 0xA7, 0xA5, 0x83, 0x45, 0xCC, 0x82, 0xC9, + 0x83, 0x45, 0xCC, 0x84, 0xC9, 0x83, 0x45, 0xCC, + 0xA3, 0xB5, 0x83, 0x45, 0xCC, 0xA7, 0xA5, 0x83, + // Bytes 46c0 - 46ff + 0x49, 0xCC, 0x88, 0xC9, 0x83, 0x4C, 0xCC, 0xA3, + 0xB5, 0x83, 0x4F, 0xCC, 0x82, 0xC9, 0x83, 0x4F, + 0xCC, 0x83, 0xC9, 0x83, 0x4F, 0xCC, 0x84, 0xC9, + 0x83, 0x4F, 0xCC, 0x87, 0xC9, 0x83, 0x4F, 0xCC, + 0x88, 0xC9, 0x83, 0x4F, 0xCC, 0x9B, 0xAD, 0x83, + 0x4F, 0xCC, 0xA3, 0xB5, 0x83, 0x4F, 0xCC, 0xA8, + 0xA5, 0x83, 0x52, 0xCC, 0xA3, 0xB5, 0x83, 0x53, + 0xCC, 0x81, 0xC9, 0x83, 0x53, 0xCC, 0x8C, 0xC9, + // Bytes 4700 - 473f + 0x83, 0x53, 0xCC, 0xA3, 0xB5, 0x83, 0x55, 0xCC, + 0x83, 0xC9, 0x83, 0x55, 0xCC, 0x84, 0xC9, 0x83, + 0x55, 0xCC, 0x88, 0xC9, 0x83, 0x55, 0xCC, 0x9B, + 0xAD, 0x83, 0x61, 0xCC, 0x82, 0xC9, 0x83, 0x61, + 0xCC, 0x86, 0xC9, 0x83, 0x61, 0xCC, 0x87, 0xC9, + 0x83, 0x61, 0xCC, 0x88, 0xC9, 0x83, 0x61, 0xCC, + 0x8A, 0xC9, 0x83, 0x61, 0xCC, 0xA3, 0xB5, 0x83, + 0x63, 0xCC, 0xA7, 0xA5, 0x83, 0x65, 0xCC, 0x82, + // Bytes 4740 - 477f + 0xC9, 0x83, 0x65, 0xCC, 0x84, 0xC9, 0x83, 0x65, + 0xCC, 0xA3, 0xB5, 0x83, 0x65, 0xCC, 0xA7, 0xA5, + 0x83, 0x69, 0xCC, 0x88, 0xC9, 0x83, 0x6C, 0xCC, + 0xA3, 0xB5, 0x83, 0x6F, 0xCC, 0x82, 0xC9, 0x83, + 0x6F, 0xCC, 0x83, 0xC9, 0x83, 0x6F, 0xCC, 0x84, + 0xC9, 0x83, 0x6F, 0xCC, 0x87, 0xC9, 0x83, 0x6F, + 0xCC, 0x88, 0xC9, 0x83, 0x6F, 0xCC, 0x9B, 0xAD, + 0x83, 0x6F, 0xCC, 0xA3, 0xB5, 0x83, 0x6F, 0xCC, + // Bytes 4780 - 47bf + 0xA8, 0xA5, 0x83, 0x72, 0xCC, 0xA3, 0xB5, 0x83, + 0x73, 0xCC, 0x81, 0xC9, 0x83, 0x73, 0xCC, 0x8C, + 0xC9, 0x83, 0x73, 0xCC, 0xA3, 0xB5, 0x83, 0x75, + 0xCC, 0x83, 0xC9, 0x83, 0x75, 0xCC, 0x84, 0xC9, + 0x83, 0x75, 0xCC, 0x88, 0xC9, 0x83, 0x75, 0xCC, + 0x9B, 0xAD, 0x84, 0xCE, 0x91, 0xCC, 0x93, 0xC9, + 0x84, 0xCE, 0x91, 0xCC, 0x94, 0xC9, 0x84, 0xCE, + 0x95, 0xCC, 0x93, 0xC9, 0x84, 0xCE, 0x95, 0xCC, + // Bytes 47c0 - 47ff + 0x94, 0xC9, 0x84, 0xCE, 0x97, 0xCC, 0x93, 0xC9, + 0x84, 0xCE, 0x97, 0xCC, 0x94, 0xC9, 0x84, 0xCE, + 0x99, 0xCC, 0x93, 0xC9, 0x84, 0xCE, 0x99, 0xCC, + 0x94, 0xC9, 0x84, 0xCE, 0x9F, 0xCC, 0x93, 0xC9, + 0x84, 0xCE, 0x9F, 0xCC, 0x94, 0xC9, 0x84, 0xCE, + 0xA5, 0xCC, 0x94, 0xC9, 0x84, 0xCE, 0xA9, 0xCC, + 0x93, 0xC9, 0x84, 0xCE, 0xA9, 0xCC, 0x94, 0xC9, + 0x84, 0xCE, 0xB1, 0xCC, 0x80, 0xC9, 0x84, 0xCE, + // Bytes 4800 - 483f + 0xB1, 0xCC, 0x81, 0xC9, 0x84, 0xCE, 0xB1, 0xCC, + 0x93, 0xC9, 0x84, 0xCE, 0xB1, 0xCC, 0x94, 0xC9, + 0x84, 0xCE, 0xB1, 0xCD, 0x82, 0xC9, 0x84, 0xCE, + 0xB5, 0xCC, 0x93, 0xC9, 0x84, 0xCE, 0xB5, 0xCC, + 0x94, 0xC9, 0x84, 0xCE, 0xB7, 0xCC, 0x80, 0xC9, + 0x84, 0xCE, 0xB7, 0xCC, 0x81, 0xC9, 0x84, 0xCE, + 0xB7, 0xCC, 0x93, 0xC9, 0x84, 0xCE, 0xB7, 0xCC, + 0x94, 0xC9, 0x84, 0xCE, 0xB7, 0xCD, 0x82, 0xC9, + // Bytes 4840 - 487f + 0x84, 0xCE, 0xB9, 0xCC, 0x88, 0xC9, 0x84, 0xCE, + 0xB9, 0xCC, 0x93, 0xC9, 0x84, 0xCE, 0xB9, 0xCC, + 0x94, 0xC9, 0x84, 0xCE, 0xBF, 0xCC, 0x93, 0xC9, + 0x84, 0xCE, 0xBF, 0xCC, 0x94, 0xC9, 0x84, 0xCF, + 0x85, 0xCC, 0x88, 0xC9, 0x84, 0xCF, 0x85, 0xCC, + 0x93, 0xC9, 0x84, 0xCF, 0x85, 0xCC, 0x94, 0xC9, + 0x84, 0xCF, 0x89, 0xCC, 0x80, 0xC9, 0x84, 0xCF, + 0x89, 0xCC, 0x81, 0xC9, 0x84, 0xCF, 0x89, 0xCC, + // Bytes 4880 - 48bf + 0x93, 0xC9, 0x84, 0xCF, 0x89, 0xCC, 0x94, 0xC9, + 0x84, 0xCF, 0x89, 0xCD, 0x82, 0xC9, 0x86, 0xCE, + 0x91, 0xCC, 0x93, 0xCC, 0x80, 0xCA, 0x86, 0xCE, + 0x91, 0xCC, 0x93, 0xCC, 0x81, 0xCA, 0x86, 0xCE, + 0x91, 0xCC, 0x93, 0xCD, 0x82, 0xCA, 0x86, 0xCE, + 0x91, 0xCC, 0x94, 0xCC, 0x80, 0xCA, 0x86, 0xCE, + 0x91, 0xCC, 0x94, 0xCC, 0x81, 0xCA, 0x86, 0xCE, + 0x91, 0xCC, 0x94, 0xCD, 0x82, 0xCA, 0x86, 0xCE, + // Bytes 48c0 - 48ff + 0x97, 0xCC, 0x93, 0xCC, 0x80, 0xCA, 0x86, 0xCE, + 0x97, 0xCC, 0x93, 0xCC, 0x81, 0xCA, 0x86, 0xCE, + 0x97, 0xCC, 0x93, 0xCD, 0x82, 0xCA, 0x86, 0xCE, + 0x97, 0xCC, 0x94, 0xCC, 0x80, 0xCA, 0x86, 0xCE, + 0x97, 0xCC, 0x94, 0xCC, 0x81, 0xCA, 0x86, 0xCE, + 0x97, 0xCC, 0x94, 0xCD, 0x82, 0xCA, 0x86, 0xCE, + 0xA9, 0xCC, 0x93, 0xCC, 0x80, 0xCA, 0x86, 0xCE, + 0xA9, 0xCC, 0x93, 0xCC, 0x81, 0xCA, 0x86, 0xCE, + // Bytes 4900 - 493f + 0xA9, 0xCC, 0x93, 0xCD, 0x82, 0xCA, 0x86, 0xCE, + 0xA9, 0xCC, 0x94, 0xCC, 0x80, 0xCA, 0x86, 0xCE, + 0xA9, 0xCC, 0x94, 0xCC, 0x81, 0xCA, 0x86, 0xCE, + 0xA9, 0xCC, 0x94, 0xCD, 0x82, 0xCA, 0x86, 0xCE, + 0xB1, 0xCC, 0x93, 0xCC, 0x80, 0xCA, 0x86, 0xCE, + 0xB1, 0xCC, 0x93, 0xCC, 0x81, 0xCA, 0x86, 0xCE, + 0xB1, 0xCC, 0x93, 0xCD, 0x82, 0xCA, 0x86, 0xCE, + 0xB1, 0xCC, 0x94, 0xCC, 0x80, 0xCA, 0x86, 0xCE, + // Bytes 4940 - 497f + 0xB1, 0xCC, 0x94, 0xCC, 0x81, 0xCA, 0x86, 0xCE, + 0xB1, 0xCC, 0x94, 0xCD, 0x82, 0xCA, 0x86, 0xCE, + 0xB7, 0xCC, 0x93, 0xCC, 0x80, 0xCA, 0x86, 0xCE, + 0xB7, 0xCC, 0x93, 0xCC, 0x81, 0xCA, 0x86, 0xCE, + 0xB7, 0xCC, 0x93, 0xCD, 0x82, 0xCA, 0x86, 0xCE, + 0xB7, 0xCC, 0x94, 0xCC, 0x80, 0xCA, 0x86, 0xCE, + 0xB7, 0xCC, 0x94, 0xCC, 0x81, 0xCA, 0x86, 0xCE, + 0xB7, 0xCC, 0x94, 0xCD, 0x82, 0xCA, 0x86, 0xCF, + // Bytes 4980 - 49bf + 0x89, 0xCC, 0x93, 0xCC, 0x80, 0xCA, 0x86, 0xCF, + 0x89, 0xCC, 0x93, 0xCC, 0x81, 0xCA, 0x86, 0xCF, + 0x89, 0xCC, 0x93, 0xCD, 0x82, 0xCA, 0x86, 0xCF, + 0x89, 0xCC, 0x94, 0xCC, 0x80, 0xCA, 0x86, 0xCF, + 0x89, 0xCC, 0x94, 0xCC, 0x81, 0xCA, 0x86, 0xCF, + 0x89, 0xCC, 0x94, 0xCD, 0x82, 0xCA, 0x42, 0xCC, + 0x80, 0xC9, 0x32, 0x42, 0xCC, 0x81, 0xC9, 0x32, + 0x42, 0xCC, 0x93, 0xC9, 0x32, 0x43, 0xE1, 0x85, + // Bytes 49c0 - 49ff + 0xA1, 0x01, 0x00, 0x43, 0xE1, 0x85, 0xA2, 0x01, + 0x00, 0x43, 0xE1, 0x85, 0xA3, 0x01, 0x00, 0x43, + 0xE1, 0x85, 0xA4, 0x01, 0x00, 0x43, 0xE1, 0x85, + 0xA5, 0x01, 0x00, 0x43, 0xE1, 0x85, 0xA6, 0x01, + 0x00, 0x43, 0xE1, 0x85, 0xA7, 0x01, 0x00, 0x43, + 0xE1, 0x85, 0xA8, 0x01, 0x00, 0x43, 0xE1, 0x85, + 0xA9, 0x01, 0x00, 0x43, 0xE1, 0x85, 0xAA, 0x01, + 0x00, 0x43, 0xE1, 0x85, 0xAB, 0x01, 0x00, 0x43, + // Bytes 4a00 - 4a3f + 0xE1, 0x85, 0xAC, 0x01, 0x00, 0x43, 0xE1, 0x85, + 0xAD, 0x01, 0x00, 0x43, 0xE1, 0x85, 0xAE, 0x01, + 0x00, 0x43, 0xE1, 0x85, 0xAF, 0x01, 0x00, 0x43, + 0xE1, 0x85, 0xB0, 0x01, 0x00, 0x43, 0xE1, 0x85, + 0xB1, 0x01, 0x00, 0x43, 0xE1, 0x85, 0xB2, 0x01, + 0x00, 0x43, 0xE1, 0x85, 0xB3, 0x01, 0x00, 0x43, + 0xE1, 0x85, 0xB4, 0x01, 0x00, 0x43, 0xE1, 0x85, + 0xB5, 0x01, 0x00, 0x43, 0xE1, 0x86, 0xAA, 0x01, + // Bytes 4a40 - 4a7f + 0x00, 0x43, 0xE1, 0x86, 0xAC, 0x01, 0x00, 0x43, + 0xE1, 0x86, 0xAD, 0x01, 0x00, 0x43, 0xE1, 0x86, + 0xB0, 0x01, 0x00, 0x43, 0xE1, 0x86, 0xB1, 0x01, + 0x00, 0x43, 0xE1, 0x86, 0xB2, 0x01, 0x00, 0x43, + 0xE1, 0x86, 0xB3, 0x01, 0x00, 0x43, 0xE1, 0x86, + 0xB4, 0x01, 0x00, 0x43, 0xE1, 0x86, 0xB5, 0x01, + 0x00, 0x44, 0xCC, 0x88, 0xCC, 0x81, 0xCA, 0x32, + 0x43, 0xE3, 0x82, 0x99, 0x0D, 0x03, 0x43, 0xE3, + // Bytes 4a80 - 4abf + 0x82, 0x9A, 0x0D, 0x03, 0x46, 0xE0, 0xBD, 0xB1, + 0xE0, 0xBD, 0xB2, 0x9E, 0x26, 0x46, 0xE0, 0xBD, + 0xB1, 0xE0, 0xBD, 0xB4, 0xA2, 0x26, 0x46, 0xE0, + 0xBD, 0xB1, 0xE0, 0xBE, 0x80, 0x9E, 0x26, 0x00, + 0x01, +} + +// lookup returns the trie value for the first UTF-8 encoding in s and +// the width in bytes of this encoding. The size will be 0 if s does not +// hold enough bytes to complete the encoding. len(s) must be greater than 0. +func (t *nfcTrie) lookup(s []byte) (v uint16, sz int) { + c0 := s[0] + switch { + case c0 < 0x80: // is ASCII + return nfcValues[c0], 1 + case c0 < 0xC2: + return 0, 1 // Illegal UTF-8: not a starter, not ASCII. + case c0 < 0xE0: // 2-byte UTF-8 + if len(s) < 2 { + return 0, 0 + } + i := nfcIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c1), 2 + case c0 < 0xF0: // 3-byte UTF-8 + if len(s) < 3 { + return 0, 0 + } + i := nfcIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = nfcIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c2), 3 + case c0 < 0xF8: // 4-byte UTF-8 + if len(s) < 4 { + return 0, 0 + } + i := nfcIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = nfcIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + o = uint32(i)<<6 + uint32(c2) + i = nfcIndex[o] + c3 := s[3] + if c3 < 0x80 || 0xC0 <= c3 { + return 0, 3 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c3), 4 + } + // Illegal rune + return 0, 1 +} + +// lookupUnsafe returns the trie value for the first UTF-8 encoding in s. +// s must start with a full and valid UTF-8 encoded rune. +func (t *nfcTrie) lookupUnsafe(s []byte) uint16 { + c0 := s[0] + if c0 < 0x80 { // is ASCII + return nfcValues[c0] + } + i := nfcIndex[c0] + if c0 < 0xE0 { // 2-byte UTF-8 + return t.lookupValue(uint32(i), s[1]) + } + i = nfcIndex[uint32(i)<<6+uint32(s[1])] + if c0 < 0xF0 { // 3-byte UTF-8 + return t.lookupValue(uint32(i), s[2]) + } + i = nfcIndex[uint32(i)<<6+uint32(s[2])] + if c0 < 0xF8 { // 4-byte UTF-8 + return t.lookupValue(uint32(i), s[3]) + } + return 0 +} + +// lookupString returns the trie value for the first UTF-8 encoding in s and +// the width in bytes of this encoding. The size will be 0 if s does not +// hold enough bytes to complete the encoding. len(s) must be greater than 0. +func (t *nfcTrie) lookupString(s string) (v uint16, sz int) { + c0 := s[0] + switch { + case c0 < 0x80: // is ASCII + return nfcValues[c0], 1 + case c0 < 0xC2: + return 0, 1 // Illegal UTF-8: not a starter, not ASCII. + case c0 < 0xE0: // 2-byte UTF-8 + if len(s) < 2 { + return 0, 0 + } + i := nfcIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c1), 2 + case c0 < 0xF0: // 3-byte UTF-8 + if len(s) < 3 { + return 0, 0 + } + i := nfcIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = nfcIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c2), 3 + case c0 < 0xF8: // 4-byte UTF-8 + if len(s) < 4 { + return 0, 0 + } + i := nfcIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = nfcIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + o = uint32(i)<<6 + uint32(c2) + i = nfcIndex[o] + c3 := s[3] + if c3 < 0x80 || 0xC0 <= c3 { + return 0, 3 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c3), 4 + } + // Illegal rune + return 0, 1 +} + +// lookupStringUnsafe returns the trie value for the first UTF-8 encoding in s. +// s must start with a full and valid UTF-8 encoded rune. +func (t *nfcTrie) lookupStringUnsafe(s string) uint16 { + c0 := s[0] + if c0 < 0x80 { // is ASCII + return nfcValues[c0] + } + i := nfcIndex[c0] + if c0 < 0xE0 { // 2-byte UTF-8 + return t.lookupValue(uint32(i), s[1]) + } + i = nfcIndex[uint32(i)<<6+uint32(s[1])] + if c0 < 0xF0 { // 3-byte UTF-8 + return t.lookupValue(uint32(i), s[2]) + } + i = nfcIndex[uint32(i)<<6+uint32(s[2])] + if c0 < 0xF8 { // 4-byte UTF-8 + return t.lookupValue(uint32(i), s[3]) + } + return 0 +} + +// nfcTrie. Total size: 10332 bytes (10.09 KiB). Checksum: 51cc525b297fc970. +type nfcTrie struct{} + +func newNfcTrie(i int) *nfcTrie { + return &nfcTrie{} +} + +// lookupValue determines the type of block n and looks up the value for b. +func (t *nfcTrie) lookupValue(n uint32, b byte) uint16 { + switch { + case n < 44: + return uint16(nfcValues[n<<6+uint32(b)]) + default: + n -= 44 + return uint16(nfcSparse.lookup(n, b)) + } +} + +// nfcValues: 46 blocks, 2944 entries, 5888 bytes +// The third block is the zero block. +var nfcValues = [2944]uint16{ + // Block 0x0, offset 0x0 + 0x3c: 0xa000, 0x3d: 0xa000, 0x3e: 0xa000, + // Block 0x1, offset 0x40 + 0x41: 0xa000, 0x42: 0xa000, 0x43: 0xa000, 0x44: 0xa000, 0x45: 0xa000, + 0x46: 0xa000, 0x47: 0xa000, 0x48: 0xa000, 0x49: 0xa000, 0x4a: 0xa000, 0x4b: 0xa000, + 0x4c: 0xa000, 0x4d: 0xa000, 0x4e: 0xa000, 0x4f: 0xa000, 0x50: 0xa000, + 0x52: 0xa000, 0x53: 0xa000, 0x54: 0xa000, 0x55: 0xa000, 0x56: 0xa000, 0x57: 0xa000, + 0x58: 0xa000, 0x59: 0xa000, 0x5a: 0xa000, + 0x61: 0xa000, 0x62: 0xa000, 0x63: 0xa000, + 0x64: 0xa000, 0x65: 0xa000, 0x66: 0xa000, 0x67: 0xa000, 0x68: 0xa000, 0x69: 0xa000, + 0x6a: 0xa000, 0x6b: 0xa000, 0x6c: 0xa000, 0x6d: 0xa000, 0x6e: 0xa000, 0x6f: 0xa000, + 0x70: 0xa000, 0x72: 0xa000, 0x73: 0xa000, 0x74: 0xa000, 0x75: 0xa000, + 0x76: 0xa000, 0x77: 0xa000, 0x78: 0xa000, 0x79: 0xa000, 0x7a: 0xa000, + // Block 0x2, offset 0x80 + // Block 0x3, offset 0xc0 + 0xc0: 0x2f6f, 0xc1: 0x2f74, 0xc2: 0x4688, 0xc3: 0x2f79, 0xc4: 0x4697, 0xc5: 0x469c, + 0xc6: 0xa000, 0xc7: 0x46a6, 0xc8: 0x2fe2, 0xc9: 0x2fe7, 0xca: 0x46ab, 0xcb: 0x2ffb, + 0xcc: 0x306e, 0xcd: 0x3073, 0xce: 0x3078, 0xcf: 0x46bf, 0xd1: 0x3104, + 0xd2: 0x3127, 0xd3: 0x312c, 0xd4: 0x46c9, 0xd5: 0x46ce, 0xd6: 0x46dd, + 0xd8: 0xa000, 0xd9: 0x31b3, 0xda: 0x31b8, 0xdb: 0x31bd, 0xdc: 0x470f, 0xdd: 0x3235, + 0xe0: 0x327b, 0xe1: 0x3280, 0xe2: 0x4719, 0xe3: 0x3285, + 0xe4: 0x4728, 0xe5: 0x472d, 0xe6: 0xa000, 0xe7: 0x4737, 0xe8: 0x32ee, 0xe9: 0x32f3, + 0xea: 0x473c, 0xeb: 0x3307, 0xec: 0x337f, 0xed: 0x3384, 0xee: 0x3389, 0xef: 0x4750, + 0xf1: 0x3415, 0xf2: 0x3438, 0xf3: 0x343d, 0xf4: 0x475a, 0xf5: 0x475f, + 0xf6: 0x476e, 0xf8: 0xa000, 0xf9: 0x34c9, 0xfa: 0x34ce, 0xfb: 0x34d3, + 0xfc: 0x47a0, 0xfd: 0x3550, 0xff: 0x3569, + // Block 0x4, offset 0x100 + 0x100: 0x2f7e, 0x101: 0x328a, 0x102: 0x468d, 0x103: 0x471e, 0x104: 0x2f9c, 0x105: 0x32a8, + 0x106: 0x2fb0, 0x107: 0x32bc, 0x108: 0x2fb5, 0x109: 0x32c1, 0x10a: 0x2fba, 0x10b: 0x32c6, + 0x10c: 0x2fbf, 0x10d: 0x32cb, 0x10e: 0x2fc9, 0x10f: 0x32d5, + 0x112: 0x46b0, 0x113: 0x4741, 0x114: 0x2ff1, 0x115: 0x32fd, 0x116: 0x2ff6, 0x117: 0x3302, + 0x118: 0x3014, 0x119: 0x3320, 0x11a: 0x3005, 0x11b: 0x3311, 0x11c: 0x302d, 0x11d: 0x3339, + 0x11e: 0x3037, 0x11f: 0x3343, 0x120: 0x303c, 0x121: 0x3348, 0x122: 0x3046, 0x123: 0x3352, + 0x124: 0x304b, 0x125: 0x3357, 0x128: 0x307d, 0x129: 0x338e, + 0x12a: 0x3082, 0x12b: 0x3393, 0x12c: 0x3087, 0x12d: 0x3398, 0x12e: 0x30aa, 0x12f: 0x33b6, + 0x130: 0x308c, 0x134: 0x30b4, 0x135: 0x33c0, + 0x136: 0x30c8, 0x137: 0x33d9, 0x139: 0x30d2, 0x13a: 0x33e3, 0x13b: 0x30dc, + 0x13c: 0x33ed, 0x13d: 0x30d7, 0x13e: 0x33e8, + // Block 0x5, offset 0x140 + 0x143: 0x30ff, 0x144: 0x3410, 0x145: 0x3118, + 0x146: 0x3429, 0x147: 0x310e, 0x148: 0x341f, + 0x14c: 0x46d3, 0x14d: 0x4764, 0x14e: 0x3131, 0x14f: 0x3442, 0x150: 0x313b, 0x151: 0x344c, + 0x154: 0x3159, 0x155: 0x346a, 0x156: 0x3172, 0x157: 0x3483, + 0x158: 0x3163, 0x159: 0x3474, 0x15a: 0x46f6, 0x15b: 0x4787, 0x15c: 0x317c, 0x15d: 0x348d, + 0x15e: 0x318b, 0x15f: 0x349c, 0x160: 0x46fb, 0x161: 0x478c, 0x162: 0x31a4, 0x163: 0x34ba, + 0x164: 0x3195, 0x165: 0x34ab, 0x168: 0x4705, 0x169: 0x4796, + 0x16a: 0x470a, 0x16b: 0x479b, 0x16c: 0x31c2, 0x16d: 0x34d8, 0x16e: 0x31cc, 0x16f: 0x34e2, + 0x170: 0x31d1, 0x171: 0x34e7, 0x172: 0x31ef, 0x173: 0x3505, 0x174: 0x3212, 0x175: 0x3528, + 0x176: 0x323a, 0x177: 0x3555, 0x178: 0x324e, 0x179: 0x325d, 0x17a: 0x357d, 0x17b: 0x3267, + 0x17c: 0x3587, 0x17d: 0x326c, 0x17e: 0x358c, 0x17f: 0xa000, + // Block 0x6, offset 0x180 + 0x184: 0x8100, 0x185: 0x8100, + 0x186: 0x8100, + 0x18d: 0x2f88, 0x18e: 0x3294, 0x18f: 0x3096, 0x190: 0x33a2, 0x191: 0x3140, + 0x192: 0x3451, 0x193: 0x31d6, 0x194: 0x34ec, 0x195: 0x39cf, 0x196: 0x3b5e, 0x197: 0x39c8, + 0x198: 0x3b57, 0x199: 0x39d6, 0x19a: 0x3b65, 0x19b: 0x39c1, 0x19c: 0x3b50, + 0x19e: 0x38b0, 0x19f: 0x3a3f, 0x1a0: 0x38a9, 0x1a1: 0x3a38, 0x1a2: 0x35b3, 0x1a3: 0x35c5, + 0x1a6: 0x3041, 0x1a7: 0x334d, 0x1a8: 0x30be, 0x1a9: 0x33cf, + 0x1aa: 0x46ec, 0x1ab: 0x477d, 0x1ac: 0x3990, 0x1ad: 0x3b1f, 0x1ae: 0x35d7, 0x1af: 0x35dd, + 0x1b0: 0x33c5, 0x1b4: 0x3028, 0x1b5: 0x3334, + 0x1b8: 0x30fa, 0x1b9: 0x340b, 0x1ba: 0x38b7, 0x1bb: 0x3a46, + 0x1bc: 0x35ad, 0x1bd: 0x35bf, 0x1be: 0x35b9, 0x1bf: 0x35cb, + // Block 0x7, offset 0x1c0 + 0x1c0: 0x2f8d, 0x1c1: 0x3299, 0x1c2: 0x2f92, 0x1c3: 0x329e, 0x1c4: 0x300a, 0x1c5: 0x3316, + 0x1c6: 0x300f, 0x1c7: 0x331b, 0x1c8: 0x309b, 0x1c9: 0x33a7, 0x1ca: 0x30a0, 0x1cb: 0x33ac, + 0x1cc: 0x3145, 0x1cd: 0x3456, 0x1ce: 0x314a, 0x1cf: 0x345b, 0x1d0: 0x3168, 0x1d1: 0x3479, + 0x1d2: 0x316d, 0x1d3: 0x347e, 0x1d4: 0x31db, 0x1d5: 0x34f1, 0x1d6: 0x31e0, 0x1d7: 0x34f6, + 0x1d8: 0x3186, 0x1d9: 0x3497, 0x1da: 0x319f, 0x1db: 0x34b5, + 0x1de: 0x305a, 0x1df: 0x3366, + 0x1e6: 0x4692, 0x1e7: 0x4723, 0x1e8: 0x46ba, 0x1e9: 0x474b, + 0x1ea: 0x395f, 0x1eb: 0x3aee, 0x1ec: 0x393c, 0x1ed: 0x3acb, 0x1ee: 0x46d8, 0x1ef: 0x4769, + 0x1f0: 0x3958, 0x1f1: 0x3ae7, 0x1f2: 0x3244, 0x1f3: 0x355f, + // Block 0x8, offset 0x200 + 0x200: 0x9932, 0x201: 0x9932, 0x202: 0x9932, 0x203: 0x9932, 0x204: 0x9932, 0x205: 0x8132, + 0x206: 0x9932, 0x207: 0x9932, 0x208: 0x9932, 0x209: 0x9932, 0x20a: 0x9932, 0x20b: 0x9932, + 0x20c: 0x9932, 0x20d: 0x8132, 0x20e: 0x8132, 0x20f: 0x9932, 0x210: 0x8132, 0x211: 0x9932, + 0x212: 0x8132, 0x213: 0x9932, 0x214: 0x9932, 0x215: 0x8133, 0x216: 0x812d, 0x217: 0x812d, + 0x218: 0x812d, 0x219: 0x812d, 0x21a: 0x8133, 0x21b: 0x992b, 0x21c: 0x812d, 0x21d: 0x812d, + 0x21e: 0x812d, 0x21f: 0x812d, 0x220: 0x812d, 0x221: 0x8129, 0x222: 0x8129, 0x223: 0x992d, + 0x224: 0x992d, 0x225: 0x992d, 0x226: 0x992d, 0x227: 0x9929, 0x228: 0x9929, 0x229: 0x812d, + 0x22a: 0x812d, 0x22b: 0x812d, 0x22c: 0x812d, 0x22d: 0x992d, 0x22e: 0x992d, 0x22f: 0x812d, + 0x230: 0x992d, 0x231: 0x992d, 0x232: 0x812d, 0x233: 0x812d, 0x234: 0x8101, 0x235: 0x8101, + 0x236: 0x8101, 0x237: 0x8101, 0x238: 0x9901, 0x239: 0x812d, 0x23a: 0x812d, 0x23b: 0x812d, + 0x23c: 0x812d, 0x23d: 0x8132, 0x23e: 0x8132, 0x23f: 0x8132, + // Block 0x9, offset 0x240 + 0x240: 0x49ae, 0x241: 0x49b3, 0x242: 0x9932, 0x243: 0x49b8, 0x244: 0x4a71, 0x245: 0x9936, + 0x246: 0x8132, 0x247: 0x812d, 0x248: 0x812d, 0x249: 0x812d, 0x24a: 0x8132, 0x24b: 0x8132, + 0x24c: 0x8132, 0x24d: 0x812d, 0x24e: 0x812d, 0x250: 0x8132, 0x251: 0x8132, + 0x252: 0x8132, 0x253: 0x812d, 0x254: 0x812d, 0x255: 0x812d, 0x256: 0x812d, 0x257: 0x8132, + 0x258: 0x8133, 0x259: 0x812d, 0x25a: 0x812d, 0x25b: 0x8132, 0x25c: 0x8134, 0x25d: 0x8135, + 0x25e: 0x8135, 0x25f: 0x8134, 0x260: 0x8135, 0x261: 0x8135, 0x262: 0x8134, 0x263: 0x8132, + 0x264: 0x8132, 0x265: 0x8132, 0x266: 0x8132, 0x267: 0x8132, 0x268: 0x8132, 0x269: 0x8132, + 0x26a: 0x8132, 0x26b: 0x8132, 0x26c: 0x8132, 0x26d: 0x8132, 0x26e: 0x8132, 0x26f: 0x8132, + 0x274: 0x0170, + 0x27a: 0x8100, + 0x27e: 0x0037, + // Block 0xa, offset 0x280 + 0x284: 0x8100, 0x285: 0x35a1, + 0x286: 0x35e9, 0x287: 0x00ce, 0x288: 0x3607, 0x289: 0x3613, 0x28a: 0x3625, + 0x28c: 0x3643, 0x28e: 0x3655, 0x28f: 0x3673, 0x290: 0x3e08, 0x291: 0xa000, + 0x295: 0xa000, 0x297: 0xa000, + 0x299: 0xa000, + 0x29f: 0xa000, 0x2a1: 0xa000, + 0x2a5: 0xa000, 0x2a9: 0xa000, + 0x2aa: 0x3637, 0x2ab: 0x3667, 0x2ac: 0x47fe, 0x2ad: 0x3697, 0x2ae: 0x4828, 0x2af: 0x36a9, + 0x2b0: 0x3e70, 0x2b1: 0xa000, 0x2b5: 0xa000, + 0x2b7: 0xa000, 0x2b9: 0xa000, + 0x2bf: 0xa000, + // Block 0xb, offset 0x2c0 + 0x2c0: 0x3721, 0x2c1: 0x372d, 0x2c3: 0x371b, + 0x2c6: 0xa000, 0x2c7: 0x3709, + 0x2cc: 0x375d, 0x2cd: 0x3745, 0x2ce: 0x376f, 0x2d0: 0xa000, + 0x2d3: 0xa000, 0x2d5: 0xa000, 0x2d6: 0xa000, 0x2d7: 0xa000, + 0x2d8: 0xa000, 0x2d9: 0x3751, 0x2da: 0xa000, + 0x2de: 0xa000, 0x2e3: 0xa000, + 0x2e7: 0xa000, + 0x2eb: 0xa000, 0x2ed: 0xa000, + 0x2f0: 0xa000, 0x2f3: 0xa000, 0x2f5: 0xa000, + 0x2f6: 0xa000, 0x2f7: 0xa000, 0x2f8: 0xa000, 0x2f9: 0x37d5, 0x2fa: 0xa000, + 0x2fe: 0xa000, + // Block 0xc, offset 0x300 + 0x301: 0x3733, 0x302: 0x37b7, + 0x310: 0x370f, 0x311: 0x3793, + 0x312: 0x3715, 0x313: 0x3799, 0x316: 0x3727, 0x317: 0x37ab, + 0x318: 0xa000, 0x319: 0xa000, 0x31a: 0x3829, 0x31b: 0x382f, 0x31c: 0x3739, 0x31d: 0x37bd, + 0x31e: 0x373f, 0x31f: 0x37c3, 0x322: 0x374b, 0x323: 0x37cf, + 0x324: 0x3757, 0x325: 0x37db, 0x326: 0x3763, 0x327: 0x37e7, 0x328: 0xa000, 0x329: 0xa000, + 0x32a: 0x3835, 0x32b: 0x383b, 0x32c: 0x378d, 0x32d: 0x3811, 0x32e: 0x3769, 0x32f: 0x37ed, + 0x330: 0x3775, 0x331: 0x37f9, 0x332: 0x377b, 0x333: 0x37ff, 0x334: 0x3781, 0x335: 0x3805, + 0x338: 0x3787, 0x339: 0x380b, + // Block 0xd, offset 0x340 + 0x351: 0x812d, + 0x352: 0x8132, 0x353: 0x8132, 0x354: 0x8132, 0x355: 0x8132, 0x356: 0x812d, 0x357: 0x8132, + 0x358: 0x8132, 0x359: 0x8132, 0x35a: 0x812e, 0x35b: 0x812d, 0x35c: 0x8132, 0x35d: 0x8132, + 0x35e: 0x8132, 0x35f: 0x8132, 0x360: 0x8132, 0x361: 0x8132, 0x362: 0x812d, 0x363: 0x812d, + 0x364: 0x812d, 0x365: 0x812d, 0x366: 0x812d, 0x367: 0x812d, 0x368: 0x8132, 0x369: 0x8132, + 0x36a: 0x812d, 0x36b: 0x8132, 0x36c: 0x8132, 0x36d: 0x812e, 0x36e: 0x8131, 0x36f: 0x8132, + 0x370: 0x8105, 0x371: 0x8106, 0x372: 0x8107, 0x373: 0x8108, 0x374: 0x8109, 0x375: 0x810a, + 0x376: 0x810b, 0x377: 0x810c, 0x378: 0x810d, 0x379: 0x810e, 0x37a: 0x810e, 0x37b: 0x810f, + 0x37c: 0x8110, 0x37d: 0x8111, 0x37f: 0x8112, + // Block 0xe, offset 0x380 + 0x388: 0xa000, 0x38a: 0xa000, 0x38b: 0x8116, + 0x38c: 0x8117, 0x38d: 0x8118, 0x38e: 0x8119, 0x38f: 0x811a, 0x390: 0x811b, 0x391: 0x811c, + 0x392: 0x811d, 0x393: 0x9932, 0x394: 0x9932, 0x395: 0x992d, 0x396: 0x812d, 0x397: 0x8132, + 0x398: 0x8132, 0x399: 0x8132, 0x39a: 0x8132, 0x39b: 0x8132, 0x39c: 0x812d, 0x39d: 0x8132, + 0x39e: 0x8132, 0x39f: 0x812d, + 0x3b0: 0x811e, + // Block 0xf, offset 0x3c0 + 0x3c5: 0xa000, + 0x3c6: 0x2d26, 0x3c7: 0xa000, 0x3c8: 0x2d2e, 0x3c9: 0xa000, 0x3ca: 0x2d36, 0x3cb: 0xa000, + 0x3cc: 0x2d3e, 0x3cd: 0xa000, 0x3ce: 0x2d46, 0x3d1: 0xa000, + 0x3d2: 0x2d4e, + 0x3f4: 0x8102, 0x3f5: 0x9900, + 0x3fa: 0xa000, 0x3fb: 0x2d56, + 0x3fc: 0xa000, 0x3fd: 0x2d5e, 0x3fe: 0xa000, 0x3ff: 0xa000, + // Block 0x10, offset 0x400 + 0x400: 0x2f97, 0x401: 0x32a3, 0x402: 0x2fa1, 0x403: 0x32ad, 0x404: 0x2fa6, 0x405: 0x32b2, + 0x406: 0x2fab, 0x407: 0x32b7, 0x408: 0x38cc, 0x409: 0x3a5b, 0x40a: 0x2fc4, 0x40b: 0x32d0, + 0x40c: 0x2fce, 0x40d: 0x32da, 0x40e: 0x2fdd, 0x40f: 0x32e9, 0x410: 0x2fd3, 0x411: 0x32df, + 0x412: 0x2fd8, 0x413: 0x32e4, 0x414: 0x38ef, 0x415: 0x3a7e, 0x416: 0x38f6, 0x417: 0x3a85, + 0x418: 0x3019, 0x419: 0x3325, 0x41a: 0x301e, 0x41b: 0x332a, 0x41c: 0x3904, 0x41d: 0x3a93, + 0x41e: 0x3023, 0x41f: 0x332f, 0x420: 0x3032, 0x421: 0x333e, 0x422: 0x3050, 0x423: 0x335c, + 0x424: 0x305f, 0x425: 0x336b, 0x426: 0x3055, 0x427: 0x3361, 0x428: 0x3064, 0x429: 0x3370, + 0x42a: 0x3069, 0x42b: 0x3375, 0x42c: 0x30af, 0x42d: 0x33bb, 0x42e: 0x390b, 0x42f: 0x3a9a, + 0x430: 0x30b9, 0x431: 0x33ca, 0x432: 0x30c3, 0x433: 0x33d4, 0x434: 0x30cd, 0x435: 0x33de, + 0x436: 0x46c4, 0x437: 0x4755, 0x438: 0x3912, 0x439: 0x3aa1, 0x43a: 0x30e6, 0x43b: 0x33f7, + 0x43c: 0x30e1, 0x43d: 0x33f2, 0x43e: 0x30eb, 0x43f: 0x33fc, + // Block 0x11, offset 0x440 + 0x440: 0x30f0, 0x441: 0x3401, 0x442: 0x30f5, 0x443: 0x3406, 0x444: 0x3109, 0x445: 0x341a, + 0x446: 0x3113, 0x447: 0x3424, 0x448: 0x3122, 0x449: 0x3433, 0x44a: 0x311d, 0x44b: 0x342e, + 0x44c: 0x3935, 0x44d: 0x3ac4, 0x44e: 0x3943, 0x44f: 0x3ad2, 0x450: 0x394a, 0x451: 0x3ad9, + 0x452: 0x3951, 0x453: 0x3ae0, 0x454: 0x314f, 0x455: 0x3460, 0x456: 0x3154, 0x457: 0x3465, + 0x458: 0x315e, 0x459: 0x346f, 0x45a: 0x46f1, 0x45b: 0x4782, 0x45c: 0x3997, 0x45d: 0x3b26, + 0x45e: 0x3177, 0x45f: 0x3488, 0x460: 0x3181, 0x461: 0x3492, 0x462: 0x4700, 0x463: 0x4791, + 0x464: 0x399e, 0x465: 0x3b2d, 0x466: 0x39a5, 0x467: 0x3b34, 0x468: 0x39ac, 0x469: 0x3b3b, + 0x46a: 0x3190, 0x46b: 0x34a1, 0x46c: 0x319a, 0x46d: 0x34b0, 0x46e: 0x31ae, 0x46f: 0x34c4, + 0x470: 0x31a9, 0x471: 0x34bf, 0x472: 0x31ea, 0x473: 0x3500, 0x474: 0x31f9, 0x475: 0x350f, + 0x476: 0x31f4, 0x477: 0x350a, 0x478: 0x39b3, 0x479: 0x3b42, 0x47a: 0x39ba, 0x47b: 0x3b49, + 0x47c: 0x31fe, 0x47d: 0x3514, 0x47e: 0x3203, 0x47f: 0x3519, + // Block 0x12, offset 0x480 + 0x480: 0x3208, 0x481: 0x351e, 0x482: 0x320d, 0x483: 0x3523, 0x484: 0x321c, 0x485: 0x3532, + 0x486: 0x3217, 0x487: 0x352d, 0x488: 0x3221, 0x489: 0x353c, 0x48a: 0x3226, 0x48b: 0x3541, + 0x48c: 0x322b, 0x48d: 0x3546, 0x48e: 0x3249, 0x48f: 0x3564, 0x490: 0x3262, 0x491: 0x3582, + 0x492: 0x3271, 0x493: 0x3591, 0x494: 0x3276, 0x495: 0x3596, 0x496: 0x337a, 0x497: 0x34a6, + 0x498: 0x3537, 0x499: 0x3573, 0x49b: 0x35d1, + 0x4a0: 0x46a1, 0x4a1: 0x4732, 0x4a2: 0x2f83, 0x4a3: 0x328f, + 0x4a4: 0x3878, 0x4a5: 0x3a07, 0x4a6: 0x3871, 0x4a7: 0x3a00, 0x4a8: 0x3886, 0x4a9: 0x3a15, + 0x4aa: 0x387f, 0x4ab: 0x3a0e, 0x4ac: 0x38be, 0x4ad: 0x3a4d, 0x4ae: 0x3894, 0x4af: 0x3a23, + 0x4b0: 0x388d, 0x4b1: 0x3a1c, 0x4b2: 0x38a2, 0x4b3: 0x3a31, 0x4b4: 0x389b, 0x4b5: 0x3a2a, + 0x4b6: 0x38c5, 0x4b7: 0x3a54, 0x4b8: 0x46b5, 0x4b9: 0x4746, 0x4ba: 0x3000, 0x4bb: 0x330c, + 0x4bc: 0x2fec, 0x4bd: 0x32f8, 0x4be: 0x38da, 0x4bf: 0x3a69, + // Block 0x13, offset 0x4c0 + 0x4c0: 0x38d3, 0x4c1: 0x3a62, 0x4c2: 0x38e8, 0x4c3: 0x3a77, 0x4c4: 0x38e1, 0x4c5: 0x3a70, + 0x4c6: 0x38fd, 0x4c7: 0x3a8c, 0x4c8: 0x3091, 0x4c9: 0x339d, 0x4ca: 0x30a5, 0x4cb: 0x33b1, + 0x4cc: 0x46e7, 0x4cd: 0x4778, 0x4ce: 0x3136, 0x4cf: 0x3447, 0x4d0: 0x3920, 0x4d1: 0x3aaf, + 0x4d2: 0x3919, 0x4d3: 0x3aa8, 0x4d4: 0x392e, 0x4d5: 0x3abd, 0x4d6: 0x3927, 0x4d7: 0x3ab6, + 0x4d8: 0x3989, 0x4d9: 0x3b18, 0x4da: 0x396d, 0x4db: 0x3afc, 0x4dc: 0x3966, 0x4dd: 0x3af5, + 0x4de: 0x397b, 0x4df: 0x3b0a, 0x4e0: 0x3974, 0x4e1: 0x3b03, 0x4e2: 0x3982, 0x4e3: 0x3b11, + 0x4e4: 0x31e5, 0x4e5: 0x34fb, 0x4e6: 0x31c7, 0x4e7: 0x34dd, 0x4e8: 0x39e4, 0x4e9: 0x3b73, + 0x4ea: 0x39dd, 0x4eb: 0x3b6c, 0x4ec: 0x39f2, 0x4ed: 0x3b81, 0x4ee: 0x39eb, 0x4ef: 0x3b7a, + 0x4f0: 0x39f9, 0x4f1: 0x3b88, 0x4f2: 0x3230, 0x4f3: 0x354b, 0x4f4: 0x3258, 0x4f5: 0x3578, + 0x4f6: 0x3253, 0x4f7: 0x356e, 0x4f8: 0x323f, 0x4f9: 0x355a, + // Block 0x14, offset 0x500 + 0x500: 0x4804, 0x501: 0x480a, 0x502: 0x491e, 0x503: 0x4936, 0x504: 0x4926, 0x505: 0x493e, + 0x506: 0x492e, 0x507: 0x4946, 0x508: 0x47aa, 0x509: 0x47b0, 0x50a: 0x488e, 0x50b: 0x48a6, + 0x50c: 0x4896, 0x50d: 0x48ae, 0x50e: 0x489e, 0x50f: 0x48b6, 0x510: 0x4816, 0x511: 0x481c, + 0x512: 0x3db8, 0x513: 0x3dc8, 0x514: 0x3dc0, 0x515: 0x3dd0, + 0x518: 0x47b6, 0x519: 0x47bc, 0x51a: 0x3ce8, 0x51b: 0x3cf8, 0x51c: 0x3cf0, 0x51d: 0x3d00, + 0x520: 0x482e, 0x521: 0x4834, 0x522: 0x494e, 0x523: 0x4966, + 0x524: 0x4956, 0x525: 0x496e, 0x526: 0x495e, 0x527: 0x4976, 0x528: 0x47c2, 0x529: 0x47c8, + 0x52a: 0x48be, 0x52b: 0x48d6, 0x52c: 0x48c6, 0x52d: 0x48de, 0x52e: 0x48ce, 0x52f: 0x48e6, + 0x530: 0x4846, 0x531: 0x484c, 0x532: 0x3e18, 0x533: 0x3e30, 0x534: 0x3e20, 0x535: 0x3e38, + 0x536: 0x3e28, 0x537: 0x3e40, 0x538: 0x47ce, 0x539: 0x47d4, 0x53a: 0x3d18, 0x53b: 0x3d30, + 0x53c: 0x3d20, 0x53d: 0x3d38, 0x53e: 0x3d28, 0x53f: 0x3d40, + // Block 0x15, offset 0x540 + 0x540: 0x4852, 0x541: 0x4858, 0x542: 0x3e48, 0x543: 0x3e58, 0x544: 0x3e50, 0x545: 0x3e60, + 0x548: 0x47da, 0x549: 0x47e0, 0x54a: 0x3d48, 0x54b: 0x3d58, + 0x54c: 0x3d50, 0x54d: 0x3d60, 0x550: 0x4864, 0x551: 0x486a, + 0x552: 0x3e80, 0x553: 0x3e98, 0x554: 0x3e88, 0x555: 0x3ea0, 0x556: 0x3e90, 0x557: 0x3ea8, + 0x559: 0x47e6, 0x55b: 0x3d68, 0x55d: 0x3d70, + 0x55f: 0x3d78, 0x560: 0x487c, 0x561: 0x4882, 0x562: 0x497e, 0x563: 0x4996, + 0x564: 0x4986, 0x565: 0x499e, 0x566: 0x498e, 0x567: 0x49a6, 0x568: 0x47ec, 0x569: 0x47f2, + 0x56a: 0x48ee, 0x56b: 0x4906, 0x56c: 0x48f6, 0x56d: 0x490e, 0x56e: 0x48fe, 0x56f: 0x4916, + 0x570: 0x47f8, 0x571: 0x431e, 0x572: 0x3691, 0x573: 0x4324, 0x574: 0x4822, 0x575: 0x432a, + 0x576: 0x36a3, 0x577: 0x4330, 0x578: 0x36c1, 0x579: 0x4336, 0x57a: 0x36d9, 0x57b: 0x433c, + 0x57c: 0x4870, 0x57d: 0x4342, + // Block 0x16, offset 0x580 + 0x580: 0x3da0, 0x581: 0x3da8, 0x582: 0x4184, 0x583: 0x41a2, 0x584: 0x418e, 0x585: 0x41ac, + 0x586: 0x4198, 0x587: 0x41b6, 0x588: 0x3cd8, 0x589: 0x3ce0, 0x58a: 0x40d0, 0x58b: 0x40ee, + 0x58c: 0x40da, 0x58d: 0x40f8, 0x58e: 0x40e4, 0x58f: 0x4102, 0x590: 0x3de8, 0x591: 0x3df0, + 0x592: 0x41c0, 0x593: 0x41de, 0x594: 0x41ca, 0x595: 0x41e8, 0x596: 0x41d4, 0x597: 0x41f2, + 0x598: 0x3d08, 0x599: 0x3d10, 0x59a: 0x410c, 0x59b: 0x412a, 0x59c: 0x4116, 0x59d: 0x4134, + 0x59e: 0x4120, 0x59f: 0x413e, 0x5a0: 0x3ec0, 0x5a1: 0x3ec8, 0x5a2: 0x41fc, 0x5a3: 0x421a, + 0x5a4: 0x4206, 0x5a5: 0x4224, 0x5a6: 0x4210, 0x5a7: 0x422e, 0x5a8: 0x3d80, 0x5a9: 0x3d88, + 0x5aa: 0x4148, 0x5ab: 0x4166, 0x5ac: 0x4152, 0x5ad: 0x4170, 0x5ae: 0x415c, 0x5af: 0x417a, + 0x5b0: 0x3685, 0x5b1: 0x367f, 0x5b2: 0x3d90, 0x5b3: 0x368b, 0x5b4: 0x3d98, + 0x5b6: 0x4810, 0x5b7: 0x3db0, 0x5b8: 0x35f5, 0x5b9: 0x35ef, 0x5ba: 0x35e3, 0x5bb: 0x42ee, + 0x5bc: 0x35fb, 0x5bd: 0x8100, 0x5be: 0x01d3, 0x5bf: 0xa100, + // Block 0x17, offset 0x5c0 + 0x5c0: 0x8100, 0x5c1: 0x35a7, 0x5c2: 0x3dd8, 0x5c3: 0x369d, 0x5c4: 0x3de0, + 0x5c6: 0x483a, 0x5c7: 0x3df8, 0x5c8: 0x3601, 0x5c9: 0x42f4, 0x5ca: 0x360d, 0x5cb: 0x42fa, + 0x5cc: 0x3619, 0x5cd: 0x3b8f, 0x5ce: 0x3b96, 0x5cf: 0x3b9d, 0x5d0: 0x36b5, 0x5d1: 0x36af, + 0x5d2: 0x3e00, 0x5d3: 0x44e4, 0x5d6: 0x36bb, 0x5d7: 0x3e10, + 0x5d8: 0x3631, 0x5d9: 0x362b, 0x5da: 0x361f, 0x5db: 0x4300, 0x5dd: 0x3ba4, + 0x5de: 0x3bab, 0x5df: 0x3bb2, 0x5e0: 0x36eb, 0x5e1: 0x36e5, 0x5e2: 0x3e68, 0x5e3: 0x44ec, + 0x5e4: 0x36cd, 0x5e5: 0x36d3, 0x5e6: 0x36f1, 0x5e7: 0x3e78, 0x5e8: 0x3661, 0x5e9: 0x365b, + 0x5ea: 0x364f, 0x5eb: 0x430c, 0x5ec: 0x3649, 0x5ed: 0x359b, 0x5ee: 0x42e8, 0x5ef: 0x0081, + 0x5f2: 0x3eb0, 0x5f3: 0x36f7, 0x5f4: 0x3eb8, + 0x5f6: 0x4888, 0x5f7: 0x3ed0, 0x5f8: 0x363d, 0x5f9: 0x4306, 0x5fa: 0x366d, 0x5fb: 0x4318, + 0x5fc: 0x3679, 0x5fd: 0x4256, 0x5fe: 0xa100, + // Block 0x18, offset 0x600 + 0x601: 0x3c06, 0x603: 0xa000, 0x604: 0x3c0d, 0x605: 0xa000, + 0x607: 0x3c14, 0x608: 0xa000, 0x609: 0x3c1b, + 0x60d: 0xa000, + 0x620: 0x2f65, 0x621: 0xa000, 0x622: 0x3c29, + 0x624: 0xa000, 0x625: 0xa000, + 0x62d: 0x3c22, 0x62e: 0x2f60, 0x62f: 0x2f6a, + 0x630: 0x3c30, 0x631: 0x3c37, 0x632: 0xa000, 0x633: 0xa000, 0x634: 0x3c3e, 0x635: 0x3c45, + 0x636: 0xa000, 0x637: 0xa000, 0x638: 0x3c4c, 0x639: 0x3c53, 0x63a: 0xa000, 0x63b: 0xa000, + 0x63c: 0xa000, 0x63d: 0xa000, + // Block 0x19, offset 0x640 + 0x640: 0x3c5a, 0x641: 0x3c61, 0x642: 0xa000, 0x643: 0xa000, 0x644: 0x3c76, 0x645: 0x3c7d, + 0x646: 0xa000, 0x647: 0xa000, 0x648: 0x3c84, 0x649: 0x3c8b, + 0x651: 0xa000, + 0x652: 0xa000, + 0x662: 0xa000, + 0x668: 0xa000, 0x669: 0xa000, + 0x66b: 0xa000, 0x66c: 0x3ca0, 0x66d: 0x3ca7, 0x66e: 0x3cae, 0x66f: 0x3cb5, + 0x672: 0xa000, 0x673: 0xa000, 0x674: 0xa000, 0x675: 0xa000, + // Block 0x1a, offset 0x680 + 0x686: 0xa000, 0x68b: 0xa000, + 0x68c: 0x3f08, 0x68d: 0xa000, 0x68e: 0x3f10, 0x68f: 0xa000, 0x690: 0x3f18, 0x691: 0xa000, + 0x692: 0x3f20, 0x693: 0xa000, 0x694: 0x3f28, 0x695: 0xa000, 0x696: 0x3f30, 0x697: 0xa000, + 0x698: 0x3f38, 0x699: 0xa000, 0x69a: 0x3f40, 0x69b: 0xa000, 0x69c: 0x3f48, 0x69d: 0xa000, + 0x69e: 0x3f50, 0x69f: 0xa000, 0x6a0: 0x3f58, 0x6a1: 0xa000, 0x6a2: 0x3f60, + 0x6a4: 0xa000, 0x6a5: 0x3f68, 0x6a6: 0xa000, 0x6a7: 0x3f70, 0x6a8: 0xa000, 0x6a9: 0x3f78, + 0x6af: 0xa000, + 0x6b0: 0x3f80, 0x6b1: 0x3f88, 0x6b2: 0xa000, 0x6b3: 0x3f90, 0x6b4: 0x3f98, 0x6b5: 0xa000, + 0x6b6: 0x3fa0, 0x6b7: 0x3fa8, 0x6b8: 0xa000, 0x6b9: 0x3fb0, 0x6ba: 0x3fb8, 0x6bb: 0xa000, + 0x6bc: 0x3fc0, 0x6bd: 0x3fc8, + // Block 0x1b, offset 0x6c0 + 0x6d4: 0x3f00, + 0x6d9: 0x9903, 0x6da: 0x9903, 0x6db: 0x8100, 0x6dc: 0x8100, 0x6dd: 0xa000, + 0x6de: 0x3fd0, + 0x6e6: 0xa000, + 0x6eb: 0xa000, 0x6ec: 0x3fe0, 0x6ed: 0xa000, 0x6ee: 0x3fe8, 0x6ef: 0xa000, + 0x6f0: 0x3ff0, 0x6f1: 0xa000, 0x6f2: 0x3ff8, 0x6f3: 0xa000, 0x6f4: 0x4000, 0x6f5: 0xa000, + 0x6f6: 0x4008, 0x6f7: 0xa000, 0x6f8: 0x4010, 0x6f9: 0xa000, 0x6fa: 0x4018, 0x6fb: 0xa000, + 0x6fc: 0x4020, 0x6fd: 0xa000, 0x6fe: 0x4028, 0x6ff: 0xa000, + // Block 0x1c, offset 0x700 + 0x700: 0x4030, 0x701: 0xa000, 0x702: 0x4038, 0x704: 0xa000, 0x705: 0x4040, + 0x706: 0xa000, 0x707: 0x4048, 0x708: 0xa000, 0x709: 0x4050, + 0x70f: 0xa000, 0x710: 0x4058, 0x711: 0x4060, + 0x712: 0xa000, 0x713: 0x4068, 0x714: 0x4070, 0x715: 0xa000, 0x716: 0x4078, 0x717: 0x4080, + 0x718: 0xa000, 0x719: 0x4088, 0x71a: 0x4090, 0x71b: 0xa000, 0x71c: 0x4098, 0x71d: 0x40a0, + 0x72f: 0xa000, + 0x730: 0xa000, 0x731: 0xa000, 0x732: 0xa000, 0x734: 0x3fd8, + 0x737: 0x40a8, 0x738: 0x40b0, 0x739: 0x40b8, 0x73a: 0x40c0, + 0x73d: 0xa000, 0x73e: 0x40c8, + // Block 0x1d, offset 0x740 + 0x740: 0x1377, 0x741: 0x0cfb, 0x742: 0x13d3, 0x743: 0x139f, 0x744: 0x0e57, 0x745: 0x06eb, + 0x746: 0x08df, 0x747: 0x162b, 0x748: 0x162b, 0x749: 0x0a0b, 0x74a: 0x145f, 0x74b: 0x0943, + 0x74c: 0x0a07, 0x74d: 0x0bef, 0x74e: 0x0fcf, 0x74f: 0x115f, 0x750: 0x1297, 0x751: 0x12d3, + 0x752: 0x1307, 0x753: 0x141b, 0x754: 0x0d73, 0x755: 0x0dff, 0x756: 0x0eab, 0x757: 0x0f43, + 0x758: 0x125f, 0x759: 0x1447, 0x75a: 0x1573, 0x75b: 0x070f, 0x75c: 0x08b3, 0x75d: 0x0d87, + 0x75e: 0x0ecf, 0x75f: 0x1293, 0x760: 0x15c3, 0x761: 0x0ab3, 0x762: 0x0e77, 0x763: 0x1283, + 0x764: 0x1317, 0x765: 0x0c23, 0x766: 0x11bb, 0x767: 0x12df, 0x768: 0x0b1f, 0x769: 0x0d0f, + 0x76a: 0x0e17, 0x76b: 0x0f1b, 0x76c: 0x1427, 0x76d: 0x074f, 0x76e: 0x07e7, 0x76f: 0x0853, + 0x770: 0x0c8b, 0x771: 0x0d7f, 0x772: 0x0ecb, 0x773: 0x0fef, 0x774: 0x1177, 0x775: 0x128b, + 0x776: 0x12a3, 0x777: 0x13c7, 0x778: 0x14ef, 0x779: 0x15a3, 0x77a: 0x15bf, 0x77b: 0x102b, + 0x77c: 0x106b, 0x77d: 0x1123, 0x77e: 0x1243, 0x77f: 0x147b, + // Block 0x1e, offset 0x780 + 0x780: 0x15cb, 0x781: 0x134b, 0x782: 0x09c7, 0x783: 0x0b3b, 0x784: 0x10db, 0x785: 0x119b, + 0x786: 0x0eff, 0x787: 0x1033, 0x788: 0x1397, 0x789: 0x14e7, 0x78a: 0x09c3, 0x78b: 0x0a8f, + 0x78c: 0x0d77, 0x78d: 0x0e2b, 0x78e: 0x0e5f, 0x78f: 0x1113, 0x790: 0x113b, 0x791: 0x14a7, + 0x792: 0x084f, 0x793: 0x11a7, 0x794: 0x07f3, 0x795: 0x07ef, 0x796: 0x1097, 0x797: 0x1127, + 0x798: 0x125b, 0x799: 0x14af, 0x79a: 0x1367, 0x79b: 0x0c27, 0x79c: 0x0d73, 0x79d: 0x1357, + 0x79e: 0x06f7, 0x79f: 0x0a63, 0x7a0: 0x0b93, 0x7a1: 0x0f2f, 0x7a2: 0x0faf, 0x7a3: 0x0873, + 0x7a4: 0x103b, 0x7a5: 0x075f, 0x7a6: 0x0b77, 0x7a7: 0x06d7, 0x7a8: 0x0deb, 0x7a9: 0x0ca3, + 0x7aa: 0x110f, 0x7ab: 0x08c7, 0x7ac: 0x09b3, 0x7ad: 0x0ffb, 0x7ae: 0x1263, 0x7af: 0x133b, + 0x7b0: 0x0db7, 0x7b1: 0x13f7, 0x7b2: 0x0de3, 0x7b3: 0x0c37, 0x7b4: 0x121b, 0x7b5: 0x0c57, + 0x7b6: 0x0fab, 0x7b7: 0x072b, 0x7b8: 0x07a7, 0x7b9: 0x07eb, 0x7ba: 0x0d53, 0x7bb: 0x10fb, + 0x7bc: 0x11f3, 0x7bd: 0x1347, 0x7be: 0x145b, 0x7bf: 0x085b, + // Block 0x1f, offset 0x7c0 + 0x7c0: 0x090f, 0x7c1: 0x0a17, 0x7c2: 0x0b2f, 0x7c3: 0x0cbf, 0x7c4: 0x0e7b, 0x7c5: 0x103f, + 0x7c6: 0x1497, 0x7c7: 0x157b, 0x7c8: 0x15cf, 0x7c9: 0x15e7, 0x7ca: 0x0837, 0x7cb: 0x0cf3, + 0x7cc: 0x0da3, 0x7cd: 0x13eb, 0x7ce: 0x0afb, 0x7cf: 0x0bd7, 0x7d0: 0x0bf3, 0x7d1: 0x0c83, + 0x7d2: 0x0e6b, 0x7d3: 0x0eb7, 0x7d4: 0x0f67, 0x7d5: 0x108b, 0x7d6: 0x112f, 0x7d7: 0x1193, + 0x7d8: 0x13db, 0x7d9: 0x126b, 0x7da: 0x1403, 0x7db: 0x147f, 0x7dc: 0x080f, 0x7dd: 0x083b, + 0x7de: 0x0923, 0x7df: 0x0ea7, 0x7e0: 0x12f3, 0x7e1: 0x133b, 0x7e2: 0x0b1b, 0x7e3: 0x0b8b, + 0x7e4: 0x0c4f, 0x7e5: 0x0daf, 0x7e6: 0x10d7, 0x7e7: 0x0f23, 0x7e8: 0x073b, 0x7e9: 0x097f, + 0x7ea: 0x0a63, 0x7eb: 0x0ac7, 0x7ec: 0x0b97, 0x7ed: 0x0f3f, 0x7ee: 0x0f5b, 0x7ef: 0x116b, + 0x7f0: 0x118b, 0x7f1: 0x1463, 0x7f2: 0x14e3, 0x7f3: 0x14f3, 0x7f4: 0x152f, 0x7f5: 0x0753, + 0x7f6: 0x107f, 0x7f7: 0x144f, 0x7f8: 0x14cb, 0x7f9: 0x0baf, 0x7fa: 0x0717, 0x7fb: 0x0777, + 0x7fc: 0x0a67, 0x7fd: 0x0a87, 0x7fe: 0x0caf, 0x7ff: 0x0d73, + // Block 0x20, offset 0x800 + 0x800: 0x0ec3, 0x801: 0x0fcb, 0x802: 0x1277, 0x803: 0x1417, 0x804: 0x1623, 0x805: 0x0ce3, + 0x806: 0x14a3, 0x807: 0x0833, 0x808: 0x0d2f, 0x809: 0x0d3b, 0x80a: 0x0e0f, 0x80b: 0x0e47, + 0x80c: 0x0f4b, 0x80d: 0x0fa7, 0x80e: 0x1027, 0x80f: 0x110b, 0x810: 0x153b, 0x811: 0x07af, + 0x812: 0x0c03, 0x813: 0x14b3, 0x814: 0x0767, 0x815: 0x0aab, 0x816: 0x0e2f, 0x817: 0x13df, + 0x818: 0x0b67, 0x819: 0x0bb7, 0x81a: 0x0d43, 0x81b: 0x0f2f, 0x81c: 0x14bb, 0x81d: 0x0817, + 0x81e: 0x08ff, 0x81f: 0x0a97, 0x820: 0x0cd3, 0x821: 0x0d1f, 0x822: 0x0d5f, 0x823: 0x0df3, + 0x824: 0x0f47, 0x825: 0x0fbb, 0x826: 0x1157, 0x827: 0x12f7, 0x828: 0x1303, 0x829: 0x1457, + 0x82a: 0x14d7, 0x82b: 0x0883, 0x82c: 0x0e4b, 0x82d: 0x0903, 0x82e: 0x0ec7, 0x82f: 0x0f6b, + 0x830: 0x1287, 0x831: 0x14bf, 0x832: 0x15ab, 0x833: 0x15d3, 0x834: 0x0d37, 0x835: 0x0e27, + 0x836: 0x11c3, 0x837: 0x10b7, 0x838: 0x10c3, 0x839: 0x10e7, 0x83a: 0x0f17, 0x83b: 0x0e9f, + 0x83c: 0x1363, 0x83d: 0x0733, 0x83e: 0x122b, 0x83f: 0x081b, + // Block 0x21, offset 0x840 + 0x840: 0x080b, 0x841: 0x0b0b, 0x842: 0x0c2b, 0x843: 0x10f3, 0x844: 0x0a53, 0x845: 0x0e03, + 0x846: 0x0cef, 0x847: 0x13e7, 0x848: 0x12e7, 0x849: 0x14ab, 0x84a: 0x1323, 0x84b: 0x0b27, + 0x84c: 0x0787, 0x84d: 0x095b, 0x850: 0x09af, + 0x852: 0x0cdf, 0x855: 0x07f7, 0x856: 0x0f1f, 0x857: 0x0fe3, + 0x858: 0x1047, 0x859: 0x1063, 0x85a: 0x1067, 0x85b: 0x107b, 0x85c: 0x14fb, 0x85d: 0x10eb, + 0x85e: 0x116f, 0x860: 0x128f, 0x862: 0x1353, + 0x865: 0x1407, 0x866: 0x1433, + 0x86a: 0x154f, 0x86b: 0x1553, 0x86c: 0x1557, 0x86d: 0x15bb, 0x86e: 0x142b, 0x86f: 0x14c7, + 0x870: 0x0757, 0x871: 0x077b, 0x872: 0x078f, 0x873: 0x084b, 0x874: 0x0857, 0x875: 0x0897, + 0x876: 0x094b, 0x877: 0x0967, 0x878: 0x096f, 0x879: 0x09ab, 0x87a: 0x09b7, 0x87b: 0x0a93, + 0x87c: 0x0a9b, 0x87d: 0x0ba3, 0x87e: 0x0bcb, 0x87f: 0x0bd3, + // Block 0x22, offset 0x880 + 0x880: 0x0beb, 0x881: 0x0c97, 0x882: 0x0cc7, 0x883: 0x0ce7, 0x884: 0x0d57, 0x885: 0x0e1b, + 0x886: 0x0e37, 0x887: 0x0e67, 0x888: 0x0ebb, 0x889: 0x0edb, 0x88a: 0x0f4f, 0x88b: 0x102f, + 0x88c: 0x104b, 0x88d: 0x1053, 0x88e: 0x104f, 0x88f: 0x1057, 0x890: 0x105b, 0x891: 0x105f, + 0x892: 0x1073, 0x893: 0x1077, 0x894: 0x109b, 0x895: 0x10af, 0x896: 0x10cb, 0x897: 0x112f, + 0x898: 0x1137, 0x899: 0x113f, 0x89a: 0x1153, 0x89b: 0x117b, 0x89c: 0x11cb, 0x89d: 0x11ff, + 0x89e: 0x11ff, 0x89f: 0x1267, 0x8a0: 0x130f, 0x8a1: 0x1327, 0x8a2: 0x135b, 0x8a3: 0x135f, + 0x8a4: 0x13a3, 0x8a5: 0x13a7, 0x8a6: 0x13ff, 0x8a7: 0x1407, 0x8a8: 0x14db, 0x8a9: 0x151f, + 0x8aa: 0x1537, 0x8ab: 0x0b9b, 0x8ac: 0x171e, 0x8ad: 0x11e3, + 0x8b0: 0x06df, 0x8b1: 0x07e3, 0x8b2: 0x07a3, 0x8b3: 0x074b, 0x8b4: 0x078b, 0x8b5: 0x07b7, + 0x8b6: 0x0847, 0x8b7: 0x0863, 0x8b8: 0x094b, 0x8b9: 0x0937, 0x8ba: 0x0947, 0x8bb: 0x0963, + 0x8bc: 0x09af, 0x8bd: 0x09bf, 0x8be: 0x0a03, 0x8bf: 0x0a0f, + // Block 0x23, offset 0x8c0 + 0x8c0: 0x0a2b, 0x8c1: 0x0a3b, 0x8c2: 0x0b23, 0x8c3: 0x0b2b, 0x8c4: 0x0b5b, 0x8c5: 0x0b7b, + 0x8c6: 0x0bab, 0x8c7: 0x0bc3, 0x8c8: 0x0bb3, 0x8c9: 0x0bd3, 0x8ca: 0x0bc7, 0x8cb: 0x0beb, + 0x8cc: 0x0c07, 0x8cd: 0x0c5f, 0x8ce: 0x0c6b, 0x8cf: 0x0c73, 0x8d0: 0x0c9b, 0x8d1: 0x0cdf, + 0x8d2: 0x0d0f, 0x8d3: 0x0d13, 0x8d4: 0x0d27, 0x8d5: 0x0da7, 0x8d6: 0x0db7, 0x8d7: 0x0e0f, + 0x8d8: 0x0e5b, 0x8d9: 0x0e53, 0x8da: 0x0e67, 0x8db: 0x0e83, 0x8dc: 0x0ebb, 0x8dd: 0x1013, + 0x8de: 0x0edf, 0x8df: 0x0f13, 0x8e0: 0x0f1f, 0x8e1: 0x0f5f, 0x8e2: 0x0f7b, 0x8e3: 0x0f9f, + 0x8e4: 0x0fc3, 0x8e5: 0x0fc7, 0x8e6: 0x0fe3, 0x8e7: 0x0fe7, 0x8e8: 0x0ff7, 0x8e9: 0x100b, + 0x8ea: 0x1007, 0x8eb: 0x1037, 0x8ec: 0x10b3, 0x8ed: 0x10cb, 0x8ee: 0x10e3, 0x8ef: 0x111b, + 0x8f0: 0x112f, 0x8f1: 0x114b, 0x8f2: 0x117b, 0x8f3: 0x122f, 0x8f4: 0x1257, 0x8f5: 0x12cb, + 0x8f6: 0x1313, 0x8f7: 0x131f, 0x8f8: 0x1327, 0x8f9: 0x133f, 0x8fa: 0x1353, 0x8fb: 0x1343, + 0x8fc: 0x135b, 0x8fd: 0x1357, 0x8fe: 0x134f, 0x8ff: 0x135f, + // Block 0x24, offset 0x900 + 0x900: 0x136b, 0x901: 0x13a7, 0x902: 0x13e3, 0x903: 0x1413, 0x904: 0x144b, 0x905: 0x146b, + 0x906: 0x14b7, 0x907: 0x14db, 0x908: 0x14fb, 0x909: 0x150f, 0x90a: 0x151f, 0x90b: 0x152b, + 0x90c: 0x1537, 0x90d: 0x158b, 0x90e: 0x162b, 0x90f: 0x16b5, 0x910: 0x16b0, 0x911: 0x16e2, + 0x912: 0x0607, 0x913: 0x062f, 0x914: 0x0633, 0x915: 0x1764, 0x916: 0x1791, 0x917: 0x1809, + 0x918: 0x1617, 0x919: 0x1627, + // Block 0x25, offset 0x940 + 0x940: 0x06fb, 0x941: 0x06f3, 0x942: 0x0703, 0x943: 0x1647, 0x944: 0x0747, 0x945: 0x0757, + 0x946: 0x075b, 0x947: 0x0763, 0x948: 0x076b, 0x949: 0x076f, 0x94a: 0x077b, 0x94b: 0x0773, + 0x94c: 0x05b3, 0x94d: 0x165b, 0x94e: 0x078f, 0x94f: 0x0793, 0x950: 0x0797, 0x951: 0x07b3, + 0x952: 0x164c, 0x953: 0x05b7, 0x954: 0x079f, 0x955: 0x07bf, 0x956: 0x1656, 0x957: 0x07cf, + 0x958: 0x07d7, 0x959: 0x0737, 0x95a: 0x07df, 0x95b: 0x07e3, 0x95c: 0x1831, 0x95d: 0x07ff, + 0x95e: 0x0807, 0x95f: 0x05bf, 0x960: 0x081f, 0x961: 0x0823, 0x962: 0x082b, 0x963: 0x082f, + 0x964: 0x05c3, 0x965: 0x0847, 0x966: 0x084b, 0x967: 0x0857, 0x968: 0x0863, 0x969: 0x0867, + 0x96a: 0x086b, 0x96b: 0x0873, 0x96c: 0x0893, 0x96d: 0x0897, 0x96e: 0x089f, 0x96f: 0x08af, + 0x970: 0x08b7, 0x971: 0x08bb, 0x972: 0x08bb, 0x973: 0x08bb, 0x974: 0x166a, 0x975: 0x0e93, + 0x976: 0x08cf, 0x977: 0x08d7, 0x978: 0x166f, 0x979: 0x08e3, 0x97a: 0x08eb, 0x97b: 0x08f3, + 0x97c: 0x091b, 0x97d: 0x0907, 0x97e: 0x0913, 0x97f: 0x0917, + // Block 0x26, offset 0x980 + 0x980: 0x091f, 0x981: 0x0927, 0x982: 0x092b, 0x983: 0x0933, 0x984: 0x093b, 0x985: 0x093f, + 0x986: 0x093f, 0x987: 0x0947, 0x988: 0x094f, 0x989: 0x0953, 0x98a: 0x095f, 0x98b: 0x0983, + 0x98c: 0x0967, 0x98d: 0x0987, 0x98e: 0x096b, 0x98f: 0x0973, 0x990: 0x080b, 0x991: 0x09cf, + 0x992: 0x0997, 0x993: 0x099b, 0x994: 0x099f, 0x995: 0x0993, 0x996: 0x09a7, 0x997: 0x09a3, + 0x998: 0x09bb, 0x999: 0x1674, 0x99a: 0x09d7, 0x99b: 0x09db, 0x99c: 0x09e3, 0x99d: 0x09ef, + 0x99e: 0x09f7, 0x99f: 0x0a13, 0x9a0: 0x1679, 0x9a1: 0x167e, 0x9a2: 0x0a1f, 0x9a3: 0x0a23, + 0x9a4: 0x0a27, 0x9a5: 0x0a1b, 0x9a6: 0x0a2f, 0x9a7: 0x05c7, 0x9a8: 0x05cb, 0x9a9: 0x0a37, + 0x9aa: 0x0a3f, 0x9ab: 0x0a3f, 0x9ac: 0x1683, 0x9ad: 0x0a5b, 0x9ae: 0x0a5f, 0x9af: 0x0a63, + 0x9b0: 0x0a6b, 0x9b1: 0x1688, 0x9b2: 0x0a73, 0x9b3: 0x0a77, 0x9b4: 0x0b4f, 0x9b5: 0x0a7f, + 0x9b6: 0x05cf, 0x9b7: 0x0a8b, 0x9b8: 0x0a9b, 0x9b9: 0x0aa7, 0x9ba: 0x0aa3, 0x9bb: 0x1692, + 0x9bc: 0x0aaf, 0x9bd: 0x1697, 0x9be: 0x0abb, 0x9bf: 0x0ab7, + // Block 0x27, offset 0x9c0 + 0x9c0: 0x0abf, 0x9c1: 0x0acf, 0x9c2: 0x0ad3, 0x9c3: 0x05d3, 0x9c4: 0x0ae3, 0x9c5: 0x0aeb, + 0x9c6: 0x0aef, 0x9c7: 0x0af3, 0x9c8: 0x05d7, 0x9c9: 0x169c, 0x9ca: 0x05db, 0x9cb: 0x0b0f, + 0x9cc: 0x0b13, 0x9cd: 0x0b17, 0x9ce: 0x0b1f, 0x9cf: 0x1863, 0x9d0: 0x0b37, 0x9d1: 0x16a6, + 0x9d2: 0x16a6, 0x9d3: 0x11d7, 0x9d4: 0x0b47, 0x9d5: 0x0b47, 0x9d6: 0x05df, 0x9d7: 0x16c9, + 0x9d8: 0x179b, 0x9d9: 0x0b57, 0x9da: 0x0b5f, 0x9db: 0x05e3, 0x9dc: 0x0b73, 0x9dd: 0x0b83, + 0x9de: 0x0b87, 0x9df: 0x0b8f, 0x9e0: 0x0b9f, 0x9e1: 0x05eb, 0x9e2: 0x05e7, 0x9e3: 0x0ba3, + 0x9e4: 0x16ab, 0x9e5: 0x0ba7, 0x9e6: 0x0bbb, 0x9e7: 0x0bbf, 0x9e8: 0x0bc3, 0x9e9: 0x0bbf, + 0x9ea: 0x0bcf, 0x9eb: 0x0bd3, 0x9ec: 0x0be3, 0x9ed: 0x0bdb, 0x9ee: 0x0bdf, 0x9ef: 0x0be7, + 0x9f0: 0x0beb, 0x9f1: 0x0bef, 0x9f2: 0x0bfb, 0x9f3: 0x0bff, 0x9f4: 0x0c17, 0x9f5: 0x0c1f, + 0x9f6: 0x0c2f, 0x9f7: 0x0c43, 0x9f8: 0x16ba, 0x9f9: 0x0c3f, 0x9fa: 0x0c33, 0x9fb: 0x0c4b, + 0x9fc: 0x0c53, 0x9fd: 0x0c67, 0x9fe: 0x16bf, 0x9ff: 0x0c6f, + // Block 0x28, offset 0xa00 + 0xa00: 0x0c63, 0xa01: 0x0c5b, 0xa02: 0x05ef, 0xa03: 0x0c77, 0xa04: 0x0c7f, 0xa05: 0x0c87, + 0xa06: 0x0c7b, 0xa07: 0x05f3, 0xa08: 0x0c97, 0xa09: 0x0c9f, 0xa0a: 0x16c4, 0xa0b: 0x0ccb, + 0xa0c: 0x0cff, 0xa0d: 0x0cdb, 0xa0e: 0x05ff, 0xa0f: 0x0ce7, 0xa10: 0x05fb, 0xa11: 0x05f7, + 0xa12: 0x07c3, 0xa13: 0x07c7, 0xa14: 0x0d03, 0xa15: 0x0ceb, 0xa16: 0x11ab, 0xa17: 0x0663, + 0xa18: 0x0d0f, 0xa19: 0x0d13, 0xa1a: 0x0d17, 0xa1b: 0x0d2b, 0xa1c: 0x0d23, 0xa1d: 0x16dd, + 0xa1e: 0x0603, 0xa1f: 0x0d3f, 0xa20: 0x0d33, 0xa21: 0x0d4f, 0xa22: 0x0d57, 0xa23: 0x16e7, + 0xa24: 0x0d5b, 0xa25: 0x0d47, 0xa26: 0x0d63, 0xa27: 0x0607, 0xa28: 0x0d67, 0xa29: 0x0d6b, + 0xa2a: 0x0d6f, 0xa2b: 0x0d7b, 0xa2c: 0x16ec, 0xa2d: 0x0d83, 0xa2e: 0x060b, 0xa2f: 0x0d8f, + 0xa30: 0x16f1, 0xa31: 0x0d93, 0xa32: 0x060f, 0xa33: 0x0d9f, 0xa34: 0x0dab, 0xa35: 0x0db7, + 0xa36: 0x0dbb, 0xa37: 0x16f6, 0xa38: 0x168d, 0xa39: 0x16fb, 0xa3a: 0x0ddb, 0xa3b: 0x1700, + 0xa3c: 0x0de7, 0xa3d: 0x0def, 0xa3e: 0x0ddf, 0xa3f: 0x0dfb, + // Block 0x29, offset 0xa40 + 0xa40: 0x0e0b, 0xa41: 0x0e1b, 0xa42: 0x0e0f, 0xa43: 0x0e13, 0xa44: 0x0e1f, 0xa45: 0x0e23, + 0xa46: 0x1705, 0xa47: 0x0e07, 0xa48: 0x0e3b, 0xa49: 0x0e3f, 0xa4a: 0x0613, 0xa4b: 0x0e53, + 0xa4c: 0x0e4f, 0xa4d: 0x170a, 0xa4e: 0x0e33, 0xa4f: 0x0e6f, 0xa50: 0x170f, 0xa51: 0x1714, + 0xa52: 0x0e73, 0xa53: 0x0e87, 0xa54: 0x0e83, 0xa55: 0x0e7f, 0xa56: 0x0617, 0xa57: 0x0e8b, + 0xa58: 0x0e9b, 0xa59: 0x0e97, 0xa5a: 0x0ea3, 0xa5b: 0x1651, 0xa5c: 0x0eb3, 0xa5d: 0x1719, + 0xa5e: 0x0ebf, 0xa5f: 0x1723, 0xa60: 0x0ed3, 0xa61: 0x0edf, 0xa62: 0x0ef3, 0xa63: 0x1728, + 0xa64: 0x0f07, 0xa65: 0x0f0b, 0xa66: 0x172d, 0xa67: 0x1732, 0xa68: 0x0f27, 0xa69: 0x0f37, + 0xa6a: 0x061b, 0xa6b: 0x0f3b, 0xa6c: 0x061f, 0xa6d: 0x061f, 0xa6e: 0x0f53, 0xa6f: 0x0f57, + 0xa70: 0x0f5f, 0xa71: 0x0f63, 0xa72: 0x0f6f, 0xa73: 0x0623, 0xa74: 0x0f87, 0xa75: 0x1737, + 0xa76: 0x0fa3, 0xa77: 0x173c, 0xa78: 0x0faf, 0xa79: 0x16a1, 0xa7a: 0x0fbf, 0xa7b: 0x1741, + 0xa7c: 0x1746, 0xa7d: 0x174b, 0xa7e: 0x0627, 0xa7f: 0x062b, + // Block 0x2a, offset 0xa80 + 0xa80: 0x0ff7, 0xa81: 0x1755, 0xa82: 0x1750, 0xa83: 0x175a, 0xa84: 0x175f, 0xa85: 0x0fff, + 0xa86: 0x1003, 0xa87: 0x1003, 0xa88: 0x100b, 0xa89: 0x0633, 0xa8a: 0x100f, 0xa8b: 0x0637, + 0xa8c: 0x063b, 0xa8d: 0x1769, 0xa8e: 0x1023, 0xa8f: 0x102b, 0xa90: 0x1037, 0xa91: 0x063f, + 0xa92: 0x176e, 0xa93: 0x105b, 0xa94: 0x1773, 0xa95: 0x1778, 0xa96: 0x107b, 0xa97: 0x1093, + 0xa98: 0x0643, 0xa99: 0x109b, 0xa9a: 0x109f, 0xa9b: 0x10a3, 0xa9c: 0x177d, 0xa9d: 0x1782, + 0xa9e: 0x1782, 0xa9f: 0x10bb, 0xaa0: 0x0647, 0xaa1: 0x1787, 0xaa2: 0x10cf, 0xaa3: 0x10d3, + 0xaa4: 0x064b, 0xaa5: 0x178c, 0xaa6: 0x10ef, 0xaa7: 0x064f, 0xaa8: 0x10ff, 0xaa9: 0x10f7, + 0xaaa: 0x1107, 0xaab: 0x1796, 0xaac: 0x111f, 0xaad: 0x0653, 0xaae: 0x112b, 0xaaf: 0x1133, + 0xab0: 0x1143, 0xab1: 0x0657, 0xab2: 0x17a0, 0xab3: 0x17a5, 0xab4: 0x065b, 0xab5: 0x17aa, + 0xab6: 0x115b, 0xab7: 0x17af, 0xab8: 0x1167, 0xab9: 0x1173, 0xaba: 0x117b, 0xabb: 0x17b4, + 0xabc: 0x17b9, 0xabd: 0x118f, 0xabe: 0x17be, 0xabf: 0x1197, + // Block 0x2b, offset 0xac0 + 0xac0: 0x16ce, 0xac1: 0x065f, 0xac2: 0x11af, 0xac3: 0x11b3, 0xac4: 0x0667, 0xac5: 0x11b7, + 0xac6: 0x0a33, 0xac7: 0x17c3, 0xac8: 0x17c8, 0xac9: 0x16d3, 0xaca: 0x16d8, 0xacb: 0x11d7, + 0xacc: 0x11db, 0xacd: 0x13f3, 0xace: 0x066b, 0xacf: 0x1207, 0xad0: 0x1203, 0xad1: 0x120b, + 0xad2: 0x083f, 0xad3: 0x120f, 0xad4: 0x1213, 0xad5: 0x1217, 0xad6: 0x121f, 0xad7: 0x17cd, + 0xad8: 0x121b, 0xad9: 0x1223, 0xada: 0x1237, 0xadb: 0x123b, 0xadc: 0x1227, 0xadd: 0x123f, + 0xade: 0x1253, 0xadf: 0x1267, 0xae0: 0x1233, 0xae1: 0x1247, 0xae2: 0x124b, 0xae3: 0x124f, + 0xae4: 0x17d2, 0xae5: 0x17dc, 0xae6: 0x17d7, 0xae7: 0x066f, 0xae8: 0x126f, 0xae9: 0x1273, + 0xaea: 0x127b, 0xaeb: 0x17f0, 0xaec: 0x127f, 0xaed: 0x17e1, 0xaee: 0x0673, 0xaef: 0x0677, + 0xaf0: 0x17e6, 0xaf1: 0x17eb, 0xaf2: 0x067b, 0xaf3: 0x129f, 0xaf4: 0x12a3, 0xaf5: 0x12a7, + 0xaf6: 0x12ab, 0xaf7: 0x12b7, 0xaf8: 0x12b3, 0xaf9: 0x12bf, 0xafa: 0x12bb, 0xafb: 0x12cb, + 0xafc: 0x12c3, 0xafd: 0x12c7, 0xafe: 0x12cf, 0xaff: 0x067f, + // Block 0x2c, offset 0xb00 + 0xb00: 0x12d7, 0xb01: 0x12db, 0xb02: 0x0683, 0xb03: 0x12eb, 0xb04: 0x12ef, 0xb05: 0x17f5, + 0xb06: 0x12fb, 0xb07: 0x12ff, 0xb08: 0x0687, 0xb09: 0x130b, 0xb0a: 0x05bb, 0xb0b: 0x17fa, + 0xb0c: 0x17ff, 0xb0d: 0x068b, 0xb0e: 0x068f, 0xb0f: 0x1337, 0xb10: 0x134f, 0xb11: 0x136b, + 0xb12: 0x137b, 0xb13: 0x1804, 0xb14: 0x138f, 0xb15: 0x1393, 0xb16: 0x13ab, 0xb17: 0x13b7, + 0xb18: 0x180e, 0xb19: 0x1660, 0xb1a: 0x13c3, 0xb1b: 0x13bf, 0xb1c: 0x13cb, 0xb1d: 0x1665, + 0xb1e: 0x13d7, 0xb1f: 0x13e3, 0xb20: 0x1813, 0xb21: 0x1818, 0xb22: 0x1423, 0xb23: 0x142f, + 0xb24: 0x1437, 0xb25: 0x181d, 0xb26: 0x143b, 0xb27: 0x1467, 0xb28: 0x1473, 0xb29: 0x1477, + 0xb2a: 0x146f, 0xb2b: 0x1483, 0xb2c: 0x1487, 0xb2d: 0x1822, 0xb2e: 0x1493, 0xb2f: 0x0693, + 0xb30: 0x149b, 0xb31: 0x1827, 0xb32: 0x0697, 0xb33: 0x14d3, 0xb34: 0x0ac3, 0xb35: 0x14eb, + 0xb36: 0x182c, 0xb37: 0x1836, 0xb38: 0x069b, 0xb39: 0x069f, 0xb3a: 0x1513, 0xb3b: 0x183b, + 0xb3c: 0x06a3, 0xb3d: 0x1840, 0xb3e: 0x152b, 0xb3f: 0x152b, + // Block 0x2d, offset 0xb40 + 0xb40: 0x1533, 0xb41: 0x1845, 0xb42: 0x154b, 0xb43: 0x06a7, 0xb44: 0x155b, 0xb45: 0x1567, + 0xb46: 0x156f, 0xb47: 0x1577, 0xb48: 0x06ab, 0xb49: 0x184a, 0xb4a: 0x158b, 0xb4b: 0x15a7, + 0xb4c: 0x15b3, 0xb4d: 0x06af, 0xb4e: 0x06b3, 0xb4f: 0x15b7, 0xb50: 0x184f, 0xb51: 0x06b7, + 0xb52: 0x1854, 0xb53: 0x1859, 0xb54: 0x185e, 0xb55: 0x15db, 0xb56: 0x06bb, 0xb57: 0x15ef, + 0xb58: 0x15f7, 0xb59: 0x15fb, 0xb5a: 0x1603, 0xb5b: 0x160b, 0xb5c: 0x1613, 0xb5d: 0x1868, +} + +// nfcIndex: 22 blocks, 1408 entries, 1408 bytes +// Block 0 is the zero block. +var nfcIndex = [1408]uint8{ + // Block 0x0, offset 0x0 + // Block 0x1, offset 0x40 + // Block 0x2, offset 0x80 + // Block 0x3, offset 0xc0 + 0xc2: 0x2c, 0xc3: 0x01, 0xc4: 0x02, 0xc5: 0x03, 0xc6: 0x2d, 0xc7: 0x04, + 0xc8: 0x05, 0xca: 0x2e, 0xcb: 0x2f, 0xcc: 0x06, 0xcd: 0x07, 0xce: 0x08, 0xcf: 0x30, + 0xd0: 0x09, 0xd1: 0x31, 0xd2: 0x32, 0xd3: 0x0a, 0xd6: 0x0b, 0xd7: 0x33, + 0xd8: 0x34, 0xd9: 0x0c, 0xdb: 0x35, 0xdc: 0x36, 0xdd: 0x37, 0xdf: 0x38, + 0xe0: 0x02, 0xe1: 0x03, 0xe2: 0x04, 0xe3: 0x05, + 0xea: 0x06, 0xeb: 0x07, 0xec: 0x08, 0xed: 0x09, 0xef: 0x0a, + 0xf0: 0x13, + // Block 0x4, offset 0x100 + 0x120: 0x39, 0x121: 0x3a, 0x123: 0x3b, 0x124: 0x3c, 0x125: 0x3d, 0x126: 0x3e, 0x127: 0x3f, + 0x128: 0x40, 0x129: 0x41, 0x12a: 0x42, 0x12b: 0x43, 0x12c: 0x3e, 0x12d: 0x44, 0x12e: 0x45, 0x12f: 0x46, + 0x131: 0x47, 0x132: 0x48, 0x133: 0x49, 0x134: 0x4a, 0x135: 0x4b, 0x137: 0x4c, + 0x138: 0x4d, 0x139: 0x4e, 0x13a: 0x4f, 0x13b: 0x50, 0x13c: 0x51, 0x13d: 0x52, 0x13e: 0x53, 0x13f: 0x54, + // Block 0x5, offset 0x140 + 0x140: 0x55, 0x142: 0x56, 0x144: 0x57, 0x145: 0x58, 0x146: 0x59, 0x147: 0x5a, + 0x14d: 0x5b, + 0x15c: 0x5c, 0x15f: 0x5d, + 0x162: 0x5e, 0x164: 0x5f, + 0x168: 0x60, 0x169: 0x61, 0x16a: 0x62, 0x16c: 0x0d, 0x16d: 0x63, 0x16e: 0x64, 0x16f: 0x65, + 0x170: 0x66, 0x173: 0x67, 0x177: 0x68, + 0x178: 0x0e, 0x179: 0x0f, 0x17a: 0x10, 0x17b: 0x11, 0x17c: 0x12, 0x17d: 0x13, 0x17e: 0x14, 0x17f: 0x15, + // Block 0x6, offset 0x180 + 0x180: 0x69, 0x183: 0x6a, 0x184: 0x6b, 0x186: 0x6c, 0x187: 0x6d, + 0x188: 0x6e, 0x189: 0x16, 0x18a: 0x17, 0x18b: 0x6f, 0x18c: 0x70, + 0x1ab: 0x71, + 0x1b3: 0x72, 0x1b5: 0x73, 0x1b7: 0x74, + // Block 0x7, offset 0x1c0 + 0x1c0: 0x75, 0x1c1: 0x18, 0x1c2: 0x19, 0x1c3: 0x1a, 0x1c4: 0x76, 0x1c5: 0x77, + 0x1c9: 0x78, 0x1cc: 0x79, 0x1cd: 0x7a, + // Block 0x8, offset 0x200 + 0x219: 0x7b, 0x21a: 0x7c, 0x21b: 0x7d, + 0x220: 0x7e, 0x223: 0x7f, 0x224: 0x80, 0x225: 0x81, 0x226: 0x82, 0x227: 0x83, + 0x22a: 0x84, 0x22b: 0x85, 0x22f: 0x86, + 0x230: 0x87, 0x231: 0x88, 0x232: 0x89, 0x233: 0x8a, 0x234: 0x8b, 0x235: 0x8c, 0x236: 0x8d, 0x237: 0x87, + 0x238: 0x88, 0x239: 0x89, 0x23a: 0x8a, 0x23b: 0x8b, 0x23c: 0x8c, 0x23d: 0x8d, 0x23e: 0x87, 0x23f: 0x88, + // Block 0x9, offset 0x240 + 0x240: 0x89, 0x241: 0x8a, 0x242: 0x8b, 0x243: 0x8c, 0x244: 0x8d, 0x245: 0x87, 0x246: 0x88, 0x247: 0x89, + 0x248: 0x8a, 0x249: 0x8b, 0x24a: 0x8c, 0x24b: 0x8d, 0x24c: 0x87, 0x24d: 0x88, 0x24e: 0x89, 0x24f: 0x8a, + 0x250: 0x8b, 0x251: 0x8c, 0x252: 0x8d, 0x253: 0x87, 0x254: 0x88, 0x255: 0x89, 0x256: 0x8a, 0x257: 0x8b, + 0x258: 0x8c, 0x259: 0x8d, 0x25a: 0x87, 0x25b: 0x88, 0x25c: 0x89, 0x25d: 0x8a, 0x25e: 0x8b, 0x25f: 0x8c, + 0x260: 0x8d, 0x261: 0x87, 0x262: 0x88, 0x263: 0x89, 0x264: 0x8a, 0x265: 0x8b, 0x266: 0x8c, 0x267: 0x8d, + 0x268: 0x87, 0x269: 0x88, 0x26a: 0x89, 0x26b: 0x8a, 0x26c: 0x8b, 0x26d: 0x8c, 0x26e: 0x8d, 0x26f: 0x87, + 0x270: 0x88, 0x271: 0x89, 0x272: 0x8a, 0x273: 0x8b, 0x274: 0x8c, 0x275: 0x8d, 0x276: 0x87, 0x277: 0x88, + 0x278: 0x89, 0x279: 0x8a, 0x27a: 0x8b, 0x27b: 0x8c, 0x27c: 0x8d, 0x27d: 0x87, 0x27e: 0x88, 0x27f: 0x89, + // Block 0xa, offset 0x280 + 0x280: 0x8a, 0x281: 0x8b, 0x282: 0x8c, 0x283: 0x8d, 0x284: 0x87, 0x285: 0x88, 0x286: 0x89, 0x287: 0x8a, + 0x288: 0x8b, 0x289: 0x8c, 0x28a: 0x8d, 0x28b: 0x87, 0x28c: 0x88, 0x28d: 0x89, 0x28e: 0x8a, 0x28f: 0x8b, + 0x290: 0x8c, 0x291: 0x8d, 0x292: 0x87, 0x293: 0x88, 0x294: 0x89, 0x295: 0x8a, 0x296: 0x8b, 0x297: 0x8c, + 0x298: 0x8d, 0x299: 0x87, 0x29a: 0x88, 0x29b: 0x89, 0x29c: 0x8a, 0x29d: 0x8b, 0x29e: 0x8c, 0x29f: 0x8d, + 0x2a0: 0x87, 0x2a1: 0x88, 0x2a2: 0x89, 0x2a3: 0x8a, 0x2a4: 0x8b, 0x2a5: 0x8c, 0x2a6: 0x8d, 0x2a7: 0x87, + 0x2a8: 0x88, 0x2a9: 0x89, 0x2aa: 0x8a, 0x2ab: 0x8b, 0x2ac: 0x8c, 0x2ad: 0x8d, 0x2ae: 0x87, 0x2af: 0x88, + 0x2b0: 0x89, 0x2b1: 0x8a, 0x2b2: 0x8b, 0x2b3: 0x8c, 0x2b4: 0x8d, 0x2b5: 0x87, 0x2b6: 0x88, 0x2b7: 0x89, + 0x2b8: 0x8a, 0x2b9: 0x8b, 0x2ba: 0x8c, 0x2bb: 0x8d, 0x2bc: 0x87, 0x2bd: 0x88, 0x2be: 0x89, 0x2bf: 0x8a, + // Block 0xb, offset 0x2c0 + 0x2c0: 0x8b, 0x2c1: 0x8c, 0x2c2: 0x8d, 0x2c3: 0x87, 0x2c4: 0x88, 0x2c5: 0x89, 0x2c6: 0x8a, 0x2c7: 0x8b, + 0x2c8: 0x8c, 0x2c9: 0x8d, 0x2ca: 0x87, 0x2cb: 0x88, 0x2cc: 0x89, 0x2cd: 0x8a, 0x2ce: 0x8b, 0x2cf: 0x8c, + 0x2d0: 0x8d, 0x2d1: 0x87, 0x2d2: 0x88, 0x2d3: 0x89, 0x2d4: 0x8a, 0x2d5: 0x8b, 0x2d6: 0x8c, 0x2d7: 0x8d, + 0x2d8: 0x87, 0x2d9: 0x88, 0x2da: 0x89, 0x2db: 0x8a, 0x2dc: 0x8b, 0x2dd: 0x8c, 0x2de: 0x8e, + // Block 0xc, offset 0x300 + 0x324: 0x1b, 0x325: 0x1c, 0x326: 0x1d, 0x327: 0x1e, + 0x328: 0x1f, 0x329: 0x20, 0x32a: 0x21, 0x32b: 0x22, 0x32c: 0x8f, 0x32d: 0x90, 0x32e: 0x91, + 0x331: 0x92, 0x332: 0x93, 0x333: 0x94, 0x334: 0x95, + 0x338: 0x96, 0x339: 0x97, 0x33a: 0x98, 0x33b: 0x99, 0x33e: 0x9a, 0x33f: 0x9b, + // Block 0xd, offset 0x340 + 0x347: 0x9c, + 0x34b: 0x9d, 0x34d: 0x9e, + 0x368: 0x9f, 0x36b: 0xa0, + // Block 0xe, offset 0x380 + 0x381: 0xa1, 0x382: 0xa2, 0x384: 0xa3, 0x385: 0x82, 0x387: 0xa4, + 0x388: 0xa5, 0x38b: 0xa6, 0x38c: 0x3e, 0x38d: 0xa7, + 0x391: 0xa8, 0x392: 0xa9, 0x393: 0xaa, 0x396: 0xab, 0x397: 0xac, + 0x398: 0x73, 0x39a: 0xad, 0x39c: 0xae, + 0x3b0: 0x73, + // Block 0xf, offset 0x3c0 + 0x3eb: 0xaf, 0x3ec: 0xb0, + // Block 0x10, offset 0x400 + 0x432: 0xb1, + // Block 0x11, offset 0x440 + 0x445: 0xb2, 0x446: 0xb3, 0x447: 0xb4, + 0x449: 0xb5, + // Block 0x12, offset 0x480 + 0x480: 0xb6, + 0x4a3: 0xb7, 0x4a5: 0xb8, + // Block 0x13, offset 0x4c0 + 0x4c8: 0xb9, + // Block 0x14, offset 0x500 + 0x520: 0x23, 0x521: 0x24, 0x522: 0x25, 0x523: 0x26, 0x524: 0x27, 0x525: 0x28, 0x526: 0x29, 0x527: 0x2a, + 0x528: 0x2b, + // Block 0x15, offset 0x540 + 0x550: 0x0b, 0x551: 0x0c, 0x556: 0x0d, + 0x55b: 0x0e, 0x55d: 0x0f, 0x55e: 0x10, 0x55f: 0x11, + 0x56f: 0x12, +} + +// nfcSparseOffset: 142 entries, 284 bytes +var nfcSparseOffset = []uint16{0x0, 0x5, 0x9, 0xb, 0xd, 0x18, 0x28, 0x2a, 0x2f, 0x3a, 0x49, 0x56, 0x5e, 0x62, 0x67, 0x69, 0x7a, 0x82, 0x89, 0x8c, 0x93, 0x97, 0x9b, 0x9d, 0x9f, 0xa8, 0xac, 0xb3, 0xb8, 0xbb, 0xc5, 0xc7, 0xce, 0xd6, 0xd9, 0xdb, 0xdd, 0xdf, 0xe4, 0xf5, 0x101, 0x103, 0x109, 0x10b, 0x10d, 0x10f, 0x111, 0x113, 0x115, 0x118, 0x11b, 0x11d, 0x120, 0x123, 0x127, 0x12c, 0x135, 0x137, 0x13a, 0x13c, 0x147, 0x157, 0x15b, 0x169, 0x16c, 0x172, 0x178, 0x183, 0x187, 0x189, 0x18b, 0x18d, 0x18f, 0x191, 0x197, 0x19b, 0x19d, 0x19f, 0x1a7, 0x1ab, 0x1ae, 0x1b0, 0x1b2, 0x1b4, 0x1b7, 0x1b9, 0x1bb, 0x1bd, 0x1bf, 0x1c5, 0x1c8, 0x1ca, 0x1d1, 0x1d7, 0x1dd, 0x1e5, 0x1eb, 0x1f1, 0x1f7, 0x1fb, 0x209, 0x212, 0x215, 0x218, 0x21a, 0x21d, 0x21f, 0x223, 0x228, 0x22a, 0x22c, 0x231, 0x237, 0x239, 0x23b, 0x23d, 0x243, 0x246, 0x249, 0x251, 0x258, 0x25b, 0x25e, 0x260, 0x268, 0x26b, 0x272, 0x275, 0x27b, 0x27d, 0x280, 0x282, 0x284, 0x286, 0x288, 0x295, 0x29f, 0x2a1, 0x2a3, 0x2a9, 0x2ab, 0x2ae} + +// nfcSparseValues: 688 entries, 2752 bytes +var nfcSparseValues = [688]valueRange{ + // Block 0x0, offset 0x0 + {value: 0x0000, lo: 0x04}, + {value: 0xa100, lo: 0xa8, hi: 0xa8}, + {value: 0x8100, lo: 0xaf, hi: 0xaf}, + {value: 0x8100, lo: 0xb4, hi: 0xb4}, + {value: 0x8100, lo: 0xb8, hi: 0xb8}, + // Block 0x1, offset 0x5 + {value: 0x0091, lo: 0x03}, + {value: 0x46e2, lo: 0xa0, hi: 0xa1}, + {value: 0x4714, lo: 0xaf, hi: 0xb0}, + {value: 0xa000, lo: 0xb7, hi: 0xb7}, + // Block 0x2, offset 0x9 + {value: 0x0000, lo: 0x01}, + {value: 0xa000, lo: 0x92, hi: 0x92}, + // Block 0x3, offset 0xb + {value: 0x0000, lo: 0x01}, + {value: 0x8100, lo: 0x98, hi: 0x9d}, + // Block 0x4, offset 0xd + {value: 0x0006, lo: 0x0a}, + {value: 0xa000, lo: 0x81, hi: 0x81}, + {value: 0xa000, lo: 0x85, hi: 0x85}, + {value: 0xa000, lo: 0x89, hi: 0x89}, + {value: 0x4840, lo: 0x8a, hi: 0x8a}, + {value: 0x485e, lo: 0x8b, hi: 0x8b}, + {value: 0x36c7, lo: 0x8c, hi: 0x8c}, + {value: 0x36df, lo: 0x8d, hi: 0x8d}, + {value: 0x4876, lo: 0x8e, hi: 0x8e}, + {value: 0xa000, lo: 0x92, hi: 0x92}, + {value: 0x36fd, lo: 0x93, hi: 0x94}, + // Block 0x5, offset 0x18 + {value: 0x0000, lo: 0x0f}, + {value: 0xa000, lo: 0x83, hi: 0x83}, + {value: 0xa000, lo: 0x87, hi: 0x87}, + {value: 0xa000, lo: 0x8b, hi: 0x8b}, + {value: 0xa000, lo: 0x8d, hi: 0x8d}, + {value: 0x37a5, lo: 0x90, hi: 0x90}, + {value: 0x37b1, lo: 0x91, hi: 0x91}, + {value: 0x379f, lo: 0x93, hi: 0x93}, + {value: 0xa000, lo: 0x96, hi: 0x96}, + {value: 0x3817, lo: 0x97, hi: 0x97}, + {value: 0x37e1, lo: 0x9c, hi: 0x9c}, + {value: 0x37c9, lo: 0x9d, hi: 0x9d}, + {value: 0x37f3, lo: 0x9e, hi: 0x9e}, + {value: 0xa000, lo: 0xb4, hi: 0xb5}, + {value: 0x381d, lo: 0xb6, hi: 0xb6}, + {value: 0x3823, lo: 0xb7, hi: 0xb7}, + // Block 0x6, offset 0x28 + {value: 0x0000, lo: 0x01}, + {value: 0x8132, lo: 0x83, hi: 0x87}, + // Block 0x7, offset 0x2a + {value: 0x0001, lo: 0x04}, + {value: 0x8113, lo: 0x81, hi: 0x82}, + {value: 0x8132, lo: 0x84, hi: 0x84}, + {value: 0x812d, lo: 0x85, hi: 0x85}, + {value: 0x810d, lo: 0x87, hi: 0x87}, + // Block 0x8, offset 0x2f + {value: 0x0000, lo: 0x0a}, + {value: 0x8132, lo: 0x90, hi: 0x97}, + {value: 0x8119, lo: 0x98, hi: 0x98}, + {value: 0x811a, lo: 0x99, hi: 0x99}, + {value: 0x811b, lo: 0x9a, hi: 0x9a}, + {value: 0x3841, lo: 0xa2, hi: 0xa2}, + {value: 0x3847, lo: 0xa3, hi: 0xa3}, + {value: 0x3853, lo: 0xa4, hi: 0xa4}, + {value: 0x384d, lo: 0xa5, hi: 0xa5}, + {value: 0x3859, lo: 0xa6, hi: 0xa6}, + {value: 0xa000, lo: 0xa7, hi: 0xa7}, + // Block 0x9, offset 0x3a + {value: 0x0000, lo: 0x0e}, + {value: 0x386b, lo: 0x80, hi: 0x80}, + {value: 0xa000, lo: 0x81, hi: 0x81}, + {value: 0x385f, lo: 0x82, hi: 0x82}, + {value: 0xa000, lo: 0x92, hi: 0x92}, + {value: 0x3865, lo: 0x93, hi: 0x93}, + {value: 0xa000, lo: 0x95, hi: 0x95}, + {value: 0x8132, lo: 0x96, hi: 0x9c}, + {value: 0x8132, lo: 0x9f, hi: 0xa2}, + {value: 0x812d, lo: 0xa3, hi: 0xa3}, + {value: 0x8132, lo: 0xa4, hi: 0xa4}, + {value: 0x8132, lo: 0xa7, hi: 0xa8}, + {value: 0x812d, lo: 0xaa, hi: 0xaa}, + {value: 0x8132, lo: 0xab, hi: 0xac}, + {value: 0x812d, lo: 0xad, hi: 0xad}, + // Block 0xa, offset 0x49 + {value: 0x0000, lo: 0x0c}, + {value: 0x811f, lo: 0x91, hi: 0x91}, + {value: 0x8132, lo: 0xb0, hi: 0xb0}, + {value: 0x812d, lo: 0xb1, hi: 0xb1}, + {value: 0x8132, lo: 0xb2, hi: 0xb3}, + {value: 0x812d, lo: 0xb4, hi: 0xb4}, + {value: 0x8132, lo: 0xb5, hi: 0xb6}, + {value: 0x812d, lo: 0xb7, hi: 0xb9}, + {value: 0x8132, lo: 0xba, hi: 0xba}, + {value: 0x812d, lo: 0xbb, hi: 0xbc}, + {value: 0x8132, lo: 0xbd, hi: 0xbd}, + {value: 0x812d, lo: 0xbe, hi: 0xbe}, + {value: 0x8132, lo: 0xbf, hi: 0xbf}, + // Block 0xb, offset 0x56 + {value: 0x0005, lo: 0x07}, + {value: 0x8132, lo: 0x80, hi: 0x80}, + {value: 0x8132, lo: 0x81, hi: 0x81}, + {value: 0x812d, lo: 0x82, hi: 0x83}, + {value: 0x812d, lo: 0x84, hi: 0x85}, + {value: 0x812d, lo: 0x86, hi: 0x87}, + {value: 0x812d, lo: 0x88, hi: 0x89}, + {value: 0x8132, lo: 0x8a, hi: 0x8a}, + // Block 0xc, offset 0x5e + {value: 0x0000, lo: 0x03}, + {value: 0x8132, lo: 0xab, hi: 0xb1}, + {value: 0x812d, lo: 0xb2, hi: 0xb2}, + {value: 0x8132, lo: 0xb3, hi: 0xb3}, + // Block 0xd, offset 0x62 + {value: 0x0000, lo: 0x04}, + {value: 0x8132, lo: 0x96, hi: 0x99}, + {value: 0x8132, lo: 0x9b, hi: 0xa3}, + {value: 0x8132, lo: 0xa5, hi: 0xa7}, + {value: 0x8132, lo: 0xa9, hi: 0xad}, + // Block 0xe, offset 0x67 + {value: 0x0000, lo: 0x01}, + {value: 0x812d, lo: 0x99, hi: 0x9b}, + // Block 0xf, offset 0x69 + {value: 0x0000, lo: 0x10}, + {value: 0x8132, lo: 0x94, hi: 0xa1}, + {value: 0x812d, lo: 0xa3, hi: 0xa3}, + {value: 0x8132, lo: 0xa4, hi: 0xa5}, + {value: 0x812d, lo: 0xa6, hi: 0xa6}, + {value: 0x8132, lo: 0xa7, hi: 0xa8}, + {value: 0x812d, lo: 0xa9, hi: 0xa9}, + {value: 0x8132, lo: 0xaa, hi: 0xac}, + {value: 0x812d, lo: 0xad, hi: 0xaf}, + {value: 0x8116, lo: 0xb0, hi: 0xb0}, + {value: 0x8117, lo: 0xb1, hi: 0xb1}, + {value: 0x8118, lo: 0xb2, hi: 0xb2}, + {value: 0x8132, lo: 0xb3, hi: 0xb5}, + {value: 0x812d, lo: 0xb6, hi: 0xb6}, + {value: 0x8132, lo: 0xb7, hi: 0xb8}, + {value: 0x812d, lo: 0xb9, hi: 0xba}, + {value: 0x8132, lo: 0xbb, hi: 0xbf}, + // Block 0x10, offset 0x7a + {value: 0x0000, lo: 0x07}, + {value: 0xa000, lo: 0xa8, hi: 0xa8}, + {value: 0x3ed8, lo: 0xa9, hi: 0xa9}, + {value: 0xa000, lo: 0xb0, hi: 0xb0}, + {value: 0x3ee0, lo: 0xb1, hi: 0xb1}, + {value: 0xa000, lo: 0xb3, hi: 0xb3}, + {value: 0x3ee8, lo: 0xb4, hi: 0xb4}, + {value: 0x9902, lo: 0xbc, hi: 0xbc}, + // Block 0x11, offset 0x82 + {value: 0x0008, lo: 0x06}, + {value: 0x8104, lo: 0x8d, hi: 0x8d}, + {value: 0x8132, lo: 0x91, hi: 0x91}, + {value: 0x812d, lo: 0x92, hi: 0x92}, + {value: 0x8132, lo: 0x93, hi: 0x93}, + {value: 0x8132, lo: 0x94, hi: 0x94}, + {value: 0x451c, lo: 0x98, hi: 0x9f}, + // Block 0x12, offset 0x89 + {value: 0x0000, lo: 0x02}, + {value: 0x8102, lo: 0xbc, hi: 0xbc}, + {value: 0x9900, lo: 0xbe, hi: 0xbe}, + // Block 0x13, offset 0x8c + {value: 0x0008, lo: 0x06}, + {value: 0xa000, lo: 0x87, hi: 0x87}, + {value: 0x2c9e, lo: 0x8b, hi: 0x8c}, + {value: 0x8104, lo: 0x8d, hi: 0x8d}, + {value: 0x9900, lo: 0x97, hi: 0x97}, + {value: 0x455c, lo: 0x9c, hi: 0x9d}, + {value: 0x456c, lo: 0x9f, hi: 0x9f}, + // Block 0x14, offset 0x93 + {value: 0x0000, lo: 0x03}, + {value: 0x4594, lo: 0xb3, hi: 0xb3}, + {value: 0x459c, lo: 0xb6, hi: 0xb6}, + {value: 0x8102, lo: 0xbc, hi: 0xbc}, + // Block 0x15, offset 0x97 + {value: 0x0008, lo: 0x03}, + {value: 0x8104, lo: 0x8d, hi: 0x8d}, + {value: 0x4574, lo: 0x99, hi: 0x9b}, + {value: 0x458c, lo: 0x9e, hi: 0x9e}, + // Block 0x16, offset 0x9b + {value: 0x0000, lo: 0x01}, + {value: 0x8102, lo: 0xbc, hi: 0xbc}, + // Block 0x17, offset 0x9d + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0x8d, hi: 0x8d}, + // Block 0x18, offset 0x9f + {value: 0x0000, lo: 0x08}, + {value: 0xa000, lo: 0x87, hi: 0x87}, + {value: 0x2cb6, lo: 0x88, hi: 0x88}, + {value: 0x2cae, lo: 0x8b, hi: 0x8b}, + {value: 0x2cbe, lo: 0x8c, hi: 0x8c}, + {value: 0x8104, lo: 0x8d, hi: 0x8d}, + {value: 0x9900, lo: 0x96, hi: 0x97}, + {value: 0x45a4, lo: 0x9c, hi: 0x9c}, + {value: 0x45ac, lo: 0x9d, hi: 0x9d}, + // Block 0x19, offset 0xa8 + {value: 0x0000, lo: 0x03}, + {value: 0xa000, lo: 0x92, hi: 0x92}, + {value: 0x2cc6, lo: 0x94, hi: 0x94}, + {value: 0x9900, lo: 0xbe, hi: 0xbe}, + // Block 0x1a, offset 0xac + {value: 0x0000, lo: 0x06}, + {value: 0xa000, lo: 0x86, hi: 0x87}, + {value: 0x2cce, lo: 0x8a, hi: 0x8a}, + {value: 0x2cde, lo: 0x8b, hi: 0x8b}, + {value: 0x2cd6, lo: 0x8c, hi: 0x8c}, + {value: 0x8104, lo: 0x8d, hi: 0x8d}, + {value: 0x9900, lo: 0x97, hi: 0x97}, + // Block 0x1b, offset 0xb3 + {value: 0x1801, lo: 0x04}, + {value: 0xa000, lo: 0x86, hi: 0x86}, + {value: 0x3ef0, lo: 0x88, hi: 0x88}, + {value: 0x8104, lo: 0x8d, hi: 0x8d}, + {value: 0x8120, lo: 0x95, hi: 0x96}, + // Block 0x1c, offset 0xb8 + {value: 0x0000, lo: 0x02}, + {value: 0x8102, lo: 0xbc, hi: 0xbc}, + {value: 0xa000, lo: 0xbf, hi: 0xbf}, + // Block 0x1d, offset 0xbb + {value: 0x0000, lo: 0x09}, + {value: 0x2ce6, lo: 0x80, hi: 0x80}, + {value: 0x9900, lo: 0x82, hi: 0x82}, + {value: 0xa000, lo: 0x86, hi: 0x86}, + {value: 0x2cee, lo: 0x87, hi: 0x87}, + {value: 0x2cf6, lo: 0x88, hi: 0x88}, + {value: 0x2f50, lo: 0x8a, hi: 0x8a}, + {value: 0x2dd8, lo: 0x8b, hi: 0x8b}, + {value: 0x8104, lo: 0x8d, hi: 0x8d}, + {value: 0x9900, lo: 0x95, hi: 0x96}, + // Block 0x1e, offset 0xc5 + {value: 0x0000, lo: 0x01}, + {value: 0x9900, lo: 0xbe, hi: 0xbe}, + // Block 0x1f, offset 0xc7 + {value: 0x0000, lo: 0x06}, + {value: 0xa000, lo: 0x86, hi: 0x87}, + {value: 0x2cfe, lo: 0x8a, hi: 0x8a}, + {value: 0x2d0e, lo: 0x8b, hi: 0x8b}, + {value: 0x2d06, lo: 0x8c, hi: 0x8c}, + {value: 0x8104, lo: 0x8d, hi: 0x8d}, + {value: 0x9900, lo: 0x97, hi: 0x97}, + // Block 0x20, offset 0xce + {value: 0x6bea, lo: 0x07}, + {value: 0x9904, lo: 0x8a, hi: 0x8a}, + {value: 0x9900, lo: 0x8f, hi: 0x8f}, + {value: 0xa000, lo: 0x99, hi: 0x99}, + {value: 0x3ef8, lo: 0x9a, hi: 0x9a}, + {value: 0x2f58, lo: 0x9c, hi: 0x9c}, + {value: 0x2de3, lo: 0x9d, hi: 0x9d}, + {value: 0x2d16, lo: 0x9e, hi: 0x9f}, + // Block 0x21, offset 0xd6 + {value: 0x0000, lo: 0x02}, + {value: 0x8122, lo: 0xb8, hi: 0xb9}, + {value: 0x8104, lo: 0xba, hi: 0xba}, + // Block 0x22, offset 0xd9 + {value: 0x0000, lo: 0x01}, + {value: 0x8123, lo: 0x88, hi: 0x8b}, + // Block 0x23, offset 0xdb + {value: 0x0000, lo: 0x01}, + {value: 0x8124, lo: 0xb8, hi: 0xb9}, + // Block 0x24, offset 0xdd + {value: 0x0000, lo: 0x01}, + {value: 0x8125, lo: 0x88, hi: 0x8b}, + // Block 0x25, offset 0xdf + {value: 0x0000, lo: 0x04}, + {value: 0x812d, lo: 0x98, hi: 0x99}, + {value: 0x812d, lo: 0xb5, hi: 0xb5}, + {value: 0x812d, lo: 0xb7, hi: 0xb7}, + {value: 0x812b, lo: 0xb9, hi: 0xb9}, + // Block 0x26, offset 0xe4 + {value: 0x0000, lo: 0x10}, + {value: 0x2644, lo: 0x83, hi: 0x83}, + {value: 0x264b, lo: 0x8d, hi: 0x8d}, + {value: 0x2652, lo: 0x92, hi: 0x92}, + {value: 0x2659, lo: 0x97, hi: 0x97}, + {value: 0x2660, lo: 0x9c, hi: 0x9c}, + {value: 0x263d, lo: 0xa9, hi: 0xa9}, + {value: 0x8126, lo: 0xb1, hi: 0xb1}, + {value: 0x8127, lo: 0xb2, hi: 0xb2}, + {value: 0x4a84, lo: 0xb3, hi: 0xb3}, + {value: 0x8128, lo: 0xb4, hi: 0xb4}, + {value: 0x4a8d, lo: 0xb5, hi: 0xb5}, + {value: 0x45b4, lo: 0xb6, hi: 0xb6}, + {value: 0x8200, lo: 0xb7, hi: 0xb7}, + {value: 0x45bc, lo: 0xb8, hi: 0xb8}, + {value: 0x8200, lo: 0xb9, hi: 0xb9}, + {value: 0x8127, lo: 0xba, hi: 0xbd}, + // Block 0x27, offset 0xf5 + {value: 0x0000, lo: 0x0b}, + {value: 0x8127, lo: 0x80, hi: 0x80}, + {value: 0x4a96, lo: 0x81, hi: 0x81}, + {value: 0x8132, lo: 0x82, hi: 0x83}, + {value: 0x8104, lo: 0x84, hi: 0x84}, + {value: 0x8132, lo: 0x86, hi: 0x87}, + {value: 0x266e, lo: 0x93, hi: 0x93}, + {value: 0x2675, lo: 0x9d, hi: 0x9d}, + {value: 0x267c, lo: 0xa2, hi: 0xa2}, + {value: 0x2683, lo: 0xa7, hi: 0xa7}, + {value: 0x268a, lo: 0xac, hi: 0xac}, + {value: 0x2667, lo: 0xb9, hi: 0xb9}, + // Block 0x28, offset 0x101 + {value: 0x0000, lo: 0x01}, + {value: 0x812d, lo: 0x86, hi: 0x86}, + // Block 0x29, offset 0x103 + {value: 0x0000, lo: 0x05}, + {value: 0xa000, lo: 0xa5, hi: 0xa5}, + {value: 0x2d1e, lo: 0xa6, hi: 0xa6}, + {value: 0x9900, lo: 0xae, hi: 0xae}, + {value: 0x8102, lo: 0xb7, hi: 0xb7}, + {value: 0x8104, lo: 0xb9, hi: 0xba}, + // Block 0x2a, offset 0x109 + {value: 0x0000, lo: 0x01}, + {value: 0x812d, lo: 0x8d, hi: 0x8d}, + // Block 0x2b, offset 0x10b + {value: 0x0000, lo: 0x01}, + {value: 0xa000, lo: 0x80, hi: 0x92}, + // Block 0x2c, offset 0x10d + {value: 0x0000, lo: 0x01}, + {value: 0xb900, lo: 0xa1, hi: 0xb5}, + // Block 0x2d, offset 0x10f + {value: 0x0000, lo: 0x01}, + {value: 0x9900, lo: 0xa8, hi: 0xbf}, + // Block 0x2e, offset 0x111 + {value: 0x0000, lo: 0x01}, + {value: 0x9900, lo: 0x80, hi: 0x82}, + // Block 0x2f, offset 0x113 + {value: 0x0000, lo: 0x01}, + {value: 0x8132, lo: 0x9d, hi: 0x9f}, + // Block 0x30, offset 0x115 + {value: 0x0000, lo: 0x02}, + {value: 0x8104, lo: 0x94, hi: 0x94}, + {value: 0x8104, lo: 0xb4, hi: 0xb4}, + // Block 0x31, offset 0x118 + {value: 0x0000, lo: 0x02}, + {value: 0x8104, lo: 0x92, hi: 0x92}, + {value: 0x8132, lo: 0x9d, hi: 0x9d}, + // Block 0x32, offset 0x11b + {value: 0x0000, lo: 0x01}, + {value: 0x8131, lo: 0xa9, hi: 0xa9}, + // Block 0x33, offset 0x11d + {value: 0x0004, lo: 0x02}, + {value: 0x812e, lo: 0xb9, hi: 0xba}, + {value: 0x812d, lo: 0xbb, hi: 0xbb}, + // Block 0x34, offset 0x120 + {value: 0x0000, lo: 0x02}, + {value: 0x8132, lo: 0x97, hi: 0x97}, + {value: 0x812d, lo: 0x98, hi: 0x98}, + // Block 0x35, offset 0x123 + {value: 0x0000, lo: 0x03}, + {value: 0x8104, lo: 0xa0, hi: 0xa0}, + {value: 0x8132, lo: 0xb5, hi: 0xbc}, + {value: 0x812d, lo: 0xbf, hi: 0xbf}, + // Block 0x36, offset 0x127 + {value: 0x0000, lo: 0x04}, + {value: 0x8132, lo: 0xb0, hi: 0xb4}, + {value: 0x812d, lo: 0xb5, hi: 0xba}, + {value: 0x8132, lo: 0xbb, hi: 0xbc}, + {value: 0x812d, lo: 0xbd, hi: 0xbd}, + // Block 0x37, offset 0x12c + {value: 0x0000, lo: 0x08}, + {value: 0x2d66, lo: 0x80, hi: 0x80}, + {value: 0x2d6e, lo: 0x81, hi: 0x81}, + {value: 0xa000, lo: 0x82, hi: 0x82}, + {value: 0x2d76, lo: 0x83, hi: 0x83}, + {value: 0x8104, lo: 0x84, hi: 0x84}, + {value: 0x8132, lo: 0xab, hi: 0xab}, + {value: 0x812d, lo: 0xac, hi: 0xac}, + {value: 0x8132, lo: 0xad, hi: 0xb3}, + // Block 0x38, offset 0x135 + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0xaa, hi: 0xab}, + // Block 0x39, offset 0x137 + {value: 0x0000, lo: 0x02}, + {value: 0x8102, lo: 0xa6, hi: 0xa6}, + {value: 0x8104, lo: 0xb2, hi: 0xb3}, + // Block 0x3a, offset 0x13a + {value: 0x0000, lo: 0x01}, + {value: 0x8102, lo: 0xb7, hi: 0xb7}, + // Block 0x3b, offset 0x13c + {value: 0x0000, lo: 0x0a}, + {value: 0x8132, lo: 0x90, hi: 0x92}, + {value: 0x8101, lo: 0x94, hi: 0x94}, + {value: 0x812d, lo: 0x95, hi: 0x99}, + {value: 0x8132, lo: 0x9a, hi: 0x9b}, + {value: 0x812d, lo: 0x9c, hi: 0x9f}, + {value: 0x8132, lo: 0xa0, hi: 0xa0}, + {value: 0x8101, lo: 0xa2, hi: 0xa8}, + {value: 0x812d, lo: 0xad, hi: 0xad}, + {value: 0x8132, lo: 0xb4, hi: 0xb4}, + {value: 0x8132, lo: 0xb8, hi: 0xb9}, + // Block 0x3c, offset 0x147 + {value: 0x0000, lo: 0x0f}, + {value: 0x8132, lo: 0x80, hi: 0x81}, + {value: 0x812d, lo: 0x82, hi: 0x82}, + {value: 0x8132, lo: 0x83, hi: 0x89}, + {value: 0x812d, lo: 0x8a, hi: 0x8a}, + {value: 0x8132, lo: 0x8b, hi: 0x8c}, + {value: 0x8135, lo: 0x8d, hi: 0x8d}, + {value: 0x812a, lo: 0x8e, hi: 0x8e}, + {value: 0x812d, lo: 0x8f, hi: 0x8f}, + {value: 0x8129, lo: 0x90, hi: 0x90}, + {value: 0x8132, lo: 0x91, hi: 0xb5}, + {value: 0x8132, lo: 0xbb, hi: 0xbb}, + {value: 0x8134, lo: 0xbc, hi: 0xbc}, + {value: 0x812d, lo: 0xbd, hi: 0xbd}, + {value: 0x8132, lo: 0xbe, hi: 0xbe}, + {value: 0x812d, lo: 0xbf, hi: 0xbf}, + // Block 0x3d, offset 0x157 + {value: 0x0004, lo: 0x03}, + {value: 0x0433, lo: 0x80, hi: 0x81}, + {value: 0x8100, lo: 0x97, hi: 0x97}, + {value: 0x8100, lo: 0xbe, hi: 0xbe}, + // Block 0x3e, offset 0x15b + {value: 0x0000, lo: 0x0d}, + {value: 0x8132, lo: 0x90, hi: 0x91}, + {value: 0x8101, lo: 0x92, hi: 0x93}, + {value: 0x8132, lo: 0x94, hi: 0x97}, + {value: 0x8101, lo: 0x98, hi: 0x9a}, + {value: 0x8132, lo: 0x9b, hi: 0x9c}, + {value: 0x8132, lo: 0xa1, hi: 0xa1}, + {value: 0x8101, lo: 0xa5, hi: 0xa6}, + {value: 0x8132, lo: 0xa7, hi: 0xa7}, + {value: 0x812d, lo: 0xa8, hi: 0xa8}, + {value: 0x8132, lo: 0xa9, hi: 0xa9}, + {value: 0x8101, lo: 0xaa, hi: 0xab}, + {value: 0x812d, lo: 0xac, hi: 0xaf}, + {value: 0x8132, lo: 0xb0, hi: 0xb0}, + // Block 0x3f, offset 0x169 + {value: 0x427b, lo: 0x02}, + {value: 0x01b8, lo: 0xa6, hi: 0xa6}, + {value: 0x0057, lo: 0xaa, hi: 0xab}, + // Block 0x40, offset 0x16c + {value: 0x0007, lo: 0x05}, + {value: 0xa000, lo: 0x90, hi: 0x90}, + {value: 0xa000, lo: 0x92, hi: 0x92}, + {value: 0xa000, lo: 0x94, hi: 0x94}, + {value: 0x3bb9, lo: 0x9a, hi: 0x9b}, + {value: 0x3bc7, lo: 0xae, hi: 0xae}, + // Block 0x41, offset 0x172 + {value: 0x000e, lo: 0x05}, + {value: 0x3bce, lo: 0x8d, hi: 0x8e}, + {value: 0x3bd5, lo: 0x8f, hi: 0x8f}, + {value: 0xa000, lo: 0x90, hi: 0x90}, + {value: 0xa000, lo: 0x92, hi: 0x92}, + {value: 0xa000, lo: 0x94, hi: 0x94}, + // Block 0x42, offset 0x178 + {value: 0x6408, lo: 0x0a}, + {value: 0xa000, lo: 0x83, hi: 0x83}, + {value: 0x3be3, lo: 0x84, hi: 0x84}, + {value: 0xa000, lo: 0x88, hi: 0x88}, + {value: 0x3bea, lo: 0x89, hi: 0x89}, + {value: 0xa000, lo: 0x8b, hi: 0x8b}, + {value: 0x3bf1, lo: 0x8c, hi: 0x8c}, + {value: 0xa000, lo: 0xa3, hi: 0xa3}, + {value: 0x3bf8, lo: 0xa4, hi: 0xa5}, + {value: 0x3bff, lo: 0xa6, hi: 0xa6}, + {value: 0xa000, lo: 0xbc, hi: 0xbc}, + // Block 0x43, offset 0x183 + {value: 0x0007, lo: 0x03}, + {value: 0x3c68, lo: 0xa0, hi: 0xa1}, + {value: 0x3c92, lo: 0xa2, hi: 0xa3}, + {value: 0x3cbc, lo: 0xaa, hi: 0xad}, + // Block 0x44, offset 0x187 + {value: 0x0004, lo: 0x01}, + {value: 0x048b, lo: 0xa9, hi: 0xaa}, + // Block 0x45, offset 0x189 + {value: 0x0000, lo: 0x01}, + {value: 0x44dd, lo: 0x9c, hi: 0x9c}, + // Block 0x46, offset 0x18b + {value: 0x0000, lo: 0x01}, + {value: 0x8132, lo: 0xaf, hi: 0xb1}, + // Block 0x47, offset 0x18d + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0xbf, hi: 0xbf}, + // Block 0x48, offset 0x18f + {value: 0x0000, lo: 0x01}, + {value: 0x8132, lo: 0xa0, hi: 0xbf}, + // Block 0x49, offset 0x191 + {value: 0x0000, lo: 0x05}, + {value: 0x812c, lo: 0xaa, hi: 0xaa}, + {value: 0x8131, lo: 0xab, hi: 0xab}, + {value: 0x8133, lo: 0xac, hi: 0xac}, + {value: 0x812e, lo: 0xad, hi: 0xad}, + {value: 0x812f, lo: 0xae, hi: 0xaf}, + // Block 0x4a, offset 0x197 + {value: 0x0000, lo: 0x03}, + {value: 0x4a9f, lo: 0xb3, hi: 0xb3}, + {value: 0x4a9f, lo: 0xb5, hi: 0xb6}, + {value: 0x4a9f, lo: 0xba, hi: 0xbf}, + // Block 0x4b, offset 0x19b + {value: 0x0000, lo: 0x01}, + {value: 0x4a9f, lo: 0x8f, hi: 0xa3}, + // Block 0x4c, offset 0x19d + {value: 0x0000, lo: 0x01}, + {value: 0x8100, lo: 0xae, hi: 0xbe}, + // Block 0x4d, offset 0x19f + {value: 0x0000, lo: 0x07}, + {value: 0x8100, lo: 0x84, hi: 0x84}, + {value: 0x8100, lo: 0x87, hi: 0x87}, + {value: 0x8100, lo: 0x90, hi: 0x90}, + {value: 0x8100, lo: 0x9e, hi: 0x9e}, + {value: 0x8100, lo: 0xa1, hi: 0xa1}, + {value: 0x8100, lo: 0xb2, hi: 0xb2}, + {value: 0x8100, lo: 0xbb, hi: 0xbb}, + // Block 0x4e, offset 0x1a7 + {value: 0x0000, lo: 0x03}, + {value: 0x8100, lo: 0x80, hi: 0x80}, + {value: 0x8100, lo: 0x8b, hi: 0x8b}, + {value: 0x8100, lo: 0x8e, hi: 0x8e}, + // Block 0x4f, offset 0x1ab + {value: 0x0000, lo: 0x02}, + {value: 0x8132, lo: 0xaf, hi: 0xaf}, + {value: 0x8132, lo: 0xb4, hi: 0xbd}, + // Block 0x50, offset 0x1ae + {value: 0x0000, lo: 0x01}, + {value: 0x8132, lo: 0x9e, hi: 0x9f}, + // Block 0x51, offset 0x1b0 + {value: 0x0000, lo: 0x01}, + {value: 0x8132, lo: 0xb0, hi: 0xb1}, + // Block 0x52, offset 0x1b2 + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0x86, hi: 0x86}, + // Block 0x53, offset 0x1b4 + {value: 0x0000, lo: 0x02}, + {value: 0x8104, lo: 0x84, hi: 0x84}, + {value: 0x8132, lo: 0xa0, hi: 0xb1}, + // Block 0x54, offset 0x1b7 + {value: 0x0000, lo: 0x01}, + {value: 0x812d, lo: 0xab, hi: 0xad}, + // Block 0x55, offset 0x1b9 + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0x93, hi: 0x93}, + // Block 0x56, offset 0x1bb + {value: 0x0000, lo: 0x01}, + {value: 0x8102, lo: 0xb3, hi: 0xb3}, + // Block 0x57, offset 0x1bd + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0x80, hi: 0x80}, + // Block 0x58, offset 0x1bf + {value: 0x0000, lo: 0x05}, + {value: 0x8132, lo: 0xb0, hi: 0xb0}, + {value: 0x8132, lo: 0xb2, hi: 0xb3}, + {value: 0x812d, lo: 0xb4, hi: 0xb4}, + {value: 0x8132, lo: 0xb7, hi: 0xb8}, + {value: 0x8132, lo: 0xbe, hi: 0xbf}, + // Block 0x59, offset 0x1c5 + {value: 0x0000, lo: 0x02}, + {value: 0x8132, lo: 0x81, hi: 0x81}, + {value: 0x8104, lo: 0xb6, hi: 0xb6}, + // Block 0x5a, offset 0x1c8 + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0xad, hi: 0xad}, + // Block 0x5b, offset 0x1ca + {value: 0x0000, lo: 0x06}, + {value: 0xe500, lo: 0x80, hi: 0x80}, + {value: 0xc600, lo: 0x81, hi: 0x9b}, + {value: 0xe500, lo: 0x9c, hi: 0x9c}, + {value: 0xc600, lo: 0x9d, hi: 0xb7}, + {value: 0xe500, lo: 0xb8, hi: 0xb8}, + {value: 0xc600, lo: 0xb9, hi: 0xbf}, + // Block 0x5c, offset 0x1d1 + {value: 0x0000, lo: 0x05}, + {value: 0xc600, lo: 0x80, hi: 0x93}, + {value: 0xe500, lo: 0x94, hi: 0x94}, + {value: 0xc600, lo: 0x95, hi: 0xaf}, + {value: 0xe500, lo: 0xb0, hi: 0xb0}, + {value: 0xc600, lo: 0xb1, hi: 0xbf}, + // Block 0x5d, offset 0x1d7 + {value: 0x0000, lo: 0x05}, + {value: 0xc600, lo: 0x80, hi: 0x8b}, + {value: 0xe500, lo: 0x8c, hi: 0x8c}, + {value: 0xc600, lo: 0x8d, hi: 0xa7}, + {value: 0xe500, lo: 0xa8, hi: 0xa8}, + {value: 0xc600, lo: 0xa9, hi: 0xbf}, + // Block 0x5e, offset 0x1dd + {value: 0x0000, lo: 0x07}, + {value: 0xc600, lo: 0x80, hi: 0x83}, + {value: 0xe500, lo: 0x84, hi: 0x84}, + {value: 0xc600, lo: 0x85, hi: 0x9f}, + {value: 0xe500, lo: 0xa0, hi: 0xa0}, + {value: 0xc600, lo: 0xa1, hi: 0xbb}, + {value: 0xe500, lo: 0xbc, hi: 0xbc}, + {value: 0xc600, lo: 0xbd, hi: 0xbf}, + // Block 0x5f, offset 0x1e5 + {value: 0x0000, lo: 0x05}, + {value: 0xc600, lo: 0x80, hi: 0x97}, + {value: 0xe500, lo: 0x98, hi: 0x98}, + {value: 0xc600, lo: 0x99, hi: 0xb3}, + {value: 0xe500, lo: 0xb4, hi: 0xb4}, + {value: 0xc600, lo: 0xb5, hi: 0xbf}, + // Block 0x60, offset 0x1eb + {value: 0x0000, lo: 0x05}, + {value: 0xc600, lo: 0x80, hi: 0x8f}, + {value: 0xe500, lo: 0x90, hi: 0x90}, + {value: 0xc600, lo: 0x91, hi: 0xab}, + {value: 0xe500, lo: 0xac, hi: 0xac}, + {value: 0xc600, lo: 0xad, hi: 0xbf}, + // Block 0x61, offset 0x1f1 + {value: 0x0000, lo: 0x05}, + {value: 0xc600, lo: 0x80, hi: 0x87}, + {value: 0xe500, lo: 0x88, hi: 0x88}, + {value: 0xc600, lo: 0x89, hi: 0xa3}, + {value: 0xe500, lo: 0xa4, hi: 0xa4}, + {value: 0xc600, lo: 0xa5, hi: 0xbf}, + // Block 0x62, offset 0x1f7 + {value: 0x0000, lo: 0x03}, + {value: 0xc600, lo: 0x80, hi: 0x87}, + {value: 0xe500, lo: 0x88, hi: 0x88}, + {value: 0xc600, lo: 0x89, hi: 0xa3}, + // Block 0x63, offset 0x1fb + {value: 0x0006, lo: 0x0d}, + {value: 0x4390, lo: 0x9d, hi: 0x9d}, + {value: 0x8115, lo: 0x9e, hi: 0x9e}, + {value: 0x4402, lo: 0x9f, hi: 0x9f}, + {value: 0x43f0, lo: 0xaa, hi: 0xab}, + {value: 0x44f4, lo: 0xac, hi: 0xac}, + {value: 0x44fc, lo: 0xad, hi: 0xad}, + {value: 0x4348, lo: 0xae, hi: 0xb1}, + {value: 0x4366, lo: 0xb2, hi: 0xb4}, + {value: 0x437e, lo: 0xb5, hi: 0xb6}, + {value: 0x438a, lo: 0xb8, hi: 0xb8}, + {value: 0x4396, lo: 0xb9, hi: 0xbb}, + {value: 0x43ae, lo: 0xbc, hi: 0xbc}, + {value: 0x43b4, lo: 0xbe, hi: 0xbe}, + // Block 0x64, offset 0x209 + {value: 0x0006, lo: 0x08}, + {value: 0x43ba, lo: 0x80, hi: 0x81}, + {value: 0x43c6, lo: 0x83, hi: 0x84}, + {value: 0x43d8, lo: 0x86, hi: 0x89}, + {value: 0x43fc, lo: 0x8a, hi: 0x8a}, + {value: 0x4378, lo: 0x8b, hi: 0x8b}, + {value: 0x4360, lo: 0x8c, hi: 0x8c}, + {value: 0x43a8, lo: 0x8d, hi: 0x8d}, + {value: 0x43d2, lo: 0x8e, hi: 0x8e}, + // Block 0x65, offset 0x212 + {value: 0x0000, lo: 0x02}, + {value: 0x8100, lo: 0xa4, hi: 0xa5}, + {value: 0x8100, lo: 0xb0, hi: 0xb1}, + // Block 0x66, offset 0x215 + {value: 0x0000, lo: 0x02}, + {value: 0x8100, lo: 0x9b, hi: 0x9d}, + {value: 0x8200, lo: 0x9e, hi: 0xa3}, + // Block 0x67, offset 0x218 + {value: 0x0000, lo: 0x01}, + {value: 0x8100, lo: 0x90, hi: 0x90}, + // Block 0x68, offset 0x21a + {value: 0x0000, lo: 0x02}, + {value: 0x8100, lo: 0x99, hi: 0x99}, + {value: 0x8200, lo: 0xb2, hi: 0xb4}, + // Block 0x69, offset 0x21d + {value: 0x0000, lo: 0x01}, + {value: 0x8100, lo: 0xbc, hi: 0xbd}, + // Block 0x6a, offset 0x21f + {value: 0x0000, lo: 0x03}, + {value: 0x8132, lo: 0xa0, hi: 0xa6}, + {value: 0x812d, lo: 0xa7, hi: 0xad}, + {value: 0x8132, lo: 0xae, hi: 0xaf}, + // Block 0x6b, offset 0x223 + {value: 0x0000, lo: 0x04}, + {value: 0x8100, lo: 0x89, hi: 0x8c}, + {value: 0x8100, lo: 0xb0, hi: 0xb2}, + {value: 0x8100, lo: 0xb4, hi: 0xb4}, + {value: 0x8100, lo: 0xb6, hi: 0xbf}, + // Block 0x6c, offset 0x228 + {value: 0x0000, lo: 0x01}, + {value: 0x8100, lo: 0x81, hi: 0x8c}, + // Block 0x6d, offset 0x22a + {value: 0x0000, lo: 0x01}, + {value: 0x8100, lo: 0xb5, hi: 0xba}, + // Block 0x6e, offset 0x22c + {value: 0x0000, lo: 0x04}, + {value: 0x4a9f, lo: 0x9e, hi: 0x9f}, + {value: 0x4a9f, lo: 0xa3, hi: 0xa3}, + {value: 0x4a9f, lo: 0xa5, hi: 0xa6}, + {value: 0x4a9f, lo: 0xaa, hi: 0xaf}, + // Block 0x6f, offset 0x231 + {value: 0x0000, lo: 0x05}, + {value: 0x4a9f, lo: 0x82, hi: 0x87}, + {value: 0x4a9f, lo: 0x8a, hi: 0x8f}, + {value: 0x4a9f, lo: 0x92, hi: 0x97}, + {value: 0x4a9f, lo: 0x9a, hi: 0x9c}, + {value: 0x8100, lo: 0xa3, hi: 0xa3}, + // Block 0x70, offset 0x237 + {value: 0x0000, lo: 0x01}, + {value: 0x812d, lo: 0xbd, hi: 0xbd}, + // Block 0x71, offset 0x239 + {value: 0x0000, lo: 0x01}, + {value: 0x812d, lo: 0xa0, hi: 0xa0}, + // Block 0x72, offset 0x23b + {value: 0x0000, lo: 0x01}, + {value: 0x8132, lo: 0xb6, hi: 0xba}, + // Block 0x73, offset 0x23d + {value: 0x002c, lo: 0x05}, + {value: 0x812d, lo: 0x8d, hi: 0x8d}, + {value: 0x8132, lo: 0x8f, hi: 0x8f}, + {value: 0x8132, lo: 0xb8, hi: 0xb8}, + {value: 0x8101, lo: 0xb9, hi: 0xba}, + {value: 0x8104, lo: 0xbf, hi: 0xbf}, + // Block 0x74, offset 0x243 + {value: 0x0000, lo: 0x02}, + {value: 0x8132, lo: 0xa5, hi: 0xa5}, + {value: 0x812d, lo: 0xa6, hi: 0xa6}, + // Block 0x75, offset 0x246 + {value: 0x0000, lo: 0x02}, + {value: 0x8104, lo: 0x86, hi: 0x86}, + {value: 0x8104, lo: 0xbf, hi: 0xbf}, + // Block 0x76, offset 0x249 + {value: 0x17fe, lo: 0x07}, + {value: 0xa000, lo: 0x99, hi: 0x99}, + {value: 0x4238, lo: 0x9a, hi: 0x9a}, + {value: 0xa000, lo: 0x9b, hi: 0x9b}, + {value: 0x4242, lo: 0x9c, hi: 0x9c}, + {value: 0xa000, lo: 0xa5, hi: 0xa5}, + {value: 0x424c, lo: 0xab, hi: 0xab}, + {value: 0x8104, lo: 0xb9, hi: 0xba}, + // Block 0x77, offset 0x251 + {value: 0x0000, lo: 0x06}, + {value: 0x8132, lo: 0x80, hi: 0x82}, + {value: 0x9900, lo: 0xa7, hi: 0xa7}, + {value: 0x2d7e, lo: 0xae, hi: 0xae}, + {value: 0x2d88, lo: 0xaf, hi: 0xaf}, + {value: 0xa000, lo: 0xb1, hi: 0xb2}, + {value: 0x8104, lo: 0xb3, hi: 0xb4}, + // Block 0x78, offset 0x258 + {value: 0x0000, lo: 0x02}, + {value: 0x8104, lo: 0x80, hi: 0x80}, + {value: 0x8102, lo: 0x8a, hi: 0x8a}, + // Block 0x79, offset 0x25b + {value: 0x0000, lo: 0x02}, + {value: 0x8104, lo: 0xb5, hi: 0xb5}, + {value: 0x8102, lo: 0xb6, hi: 0xb6}, + // Block 0x7a, offset 0x25e + {value: 0x0002, lo: 0x01}, + {value: 0x8102, lo: 0xa9, hi: 0xaa}, + // Block 0x7b, offset 0x260 + {value: 0x0000, lo: 0x07}, + {value: 0xa000, lo: 0x87, hi: 0x87}, + {value: 0x2d92, lo: 0x8b, hi: 0x8b}, + {value: 0x2d9c, lo: 0x8c, hi: 0x8c}, + {value: 0x8104, lo: 0x8d, hi: 0x8d}, + {value: 0x9900, lo: 0x97, hi: 0x97}, + {value: 0x8132, lo: 0xa6, hi: 0xac}, + {value: 0x8132, lo: 0xb0, hi: 0xb4}, + // Block 0x7c, offset 0x268 + {value: 0x0000, lo: 0x02}, + {value: 0x8104, lo: 0x82, hi: 0x82}, + {value: 0x8102, lo: 0x86, hi: 0x86}, + // Block 0x7d, offset 0x26b + {value: 0x6b5a, lo: 0x06}, + {value: 0x9900, lo: 0xb0, hi: 0xb0}, + {value: 0xa000, lo: 0xb9, hi: 0xb9}, + {value: 0x9900, lo: 0xba, hi: 0xba}, + {value: 0x2db0, lo: 0xbb, hi: 0xbb}, + {value: 0x2da6, lo: 0xbc, hi: 0xbd}, + {value: 0x2dba, lo: 0xbe, hi: 0xbe}, + // Block 0x7e, offset 0x272 + {value: 0x0000, lo: 0x02}, + {value: 0x8104, lo: 0x82, hi: 0x82}, + {value: 0x8102, lo: 0x83, hi: 0x83}, + // Block 0x7f, offset 0x275 + {value: 0x0000, lo: 0x05}, + {value: 0x9900, lo: 0xaf, hi: 0xaf}, + {value: 0xa000, lo: 0xb8, hi: 0xb9}, + {value: 0x2dc4, lo: 0xba, hi: 0xba}, + {value: 0x2dce, lo: 0xbb, hi: 0xbb}, + {value: 0x8104, lo: 0xbf, hi: 0xbf}, + // Block 0x80, offset 0x27b + {value: 0x0000, lo: 0x01}, + {value: 0x8102, lo: 0x80, hi: 0x80}, + // Block 0x81, offset 0x27d + {value: 0x0000, lo: 0x02}, + {value: 0x8104, lo: 0xb6, hi: 0xb6}, + {value: 0x8102, lo: 0xb7, hi: 0xb7}, + // Block 0x82, offset 0x280 + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0xab, hi: 0xab}, + // Block 0x83, offset 0x282 + {value: 0x0000, lo: 0x01}, + {value: 0x8101, lo: 0xb0, hi: 0xb4}, + // Block 0x84, offset 0x284 + {value: 0x0000, lo: 0x01}, + {value: 0x8132, lo: 0xb0, hi: 0xb6}, + // Block 0x85, offset 0x286 + {value: 0x0000, lo: 0x01}, + {value: 0x8101, lo: 0x9e, hi: 0x9e}, + // Block 0x86, offset 0x288 + {value: 0x0000, lo: 0x0c}, + {value: 0x45cc, lo: 0x9e, hi: 0x9e}, + {value: 0x45d6, lo: 0x9f, hi: 0x9f}, + {value: 0x460a, lo: 0xa0, hi: 0xa0}, + {value: 0x4618, lo: 0xa1, hi: 0xa1}, + {value: 0x4626, lo: 0xa2, hi: 0xa2}, + {value: 0x4634, lo: 0xa3, hi: 0xa3}, + {value: 0x4642, lo: 0xa4, hi: 0xa4}, + {value: 0x812b, lo: 0xa5, hi: 0xa6}, + {value: 0x8101, lo: 0xa7, hi: 0xa9}, + {value: 0x8130, lo: 0xad, hi: 0xad}, + {value: 0x812b, lo: 0xae, hi: 0xb2}, + {value: 0x812d, lo: 0xbb, hi: 0xbf}, + // Block 0x87, offset 0x295 + {value: 0x0000, lo: 0x09}, + {value: 0x812d, lo: 0x80, hi: 0x82}, + {value: 0x8132, lo: 0x85, hi: 0x89}, + {value: 0x812d, lo: 0x8a, hi: 0x8b}, + {value: 0x8132, lo: 0xaa, hi: 0xad}, + {value: 0x45e0, lo: 0xbb, hi: 0xbb}, + {value: 0x45ea, lo: 0xbc, hi: 0xbc}, + {value: 0x4650, lo: 0xbd, hi: 0xbd}, + {value: 0x466c, lo: 0xbe, hi: 0xbe}, + {value: 0x465e, lo: 0xbf, hi: 0xbf}, + // Block 0x88, offset 0x29f + {value: 0x0000, lo: 0x01}, + {value: 0x467a, lo: 0x80, hi: 0x80}, + // Block 0x89, offset 0x2a1 + {value: 0x0000, lo: 0x01}, + {value: 0x8132, lo: 0x82, hi: 0x84}, + // Block 0x8a, offset 0x2a3 + {value: 0x0000, lo: 0x05}, + {value: 0x8132, lo: 0x80, hi: 0x86}, + {value: 0x8132, lo: 0x88, hi: 0x98}, + {value: 0x8132, lo: 0x9b, hi: 0xa1}, + {value: 0x8132, lo: 0xa3, hi: 0xa4}, + {value: 0x8132, lo: 0xa6, hi: 0xaa}, + // Block 0x8b, offset 0x2a9 + {value: 0x0000, lo: 0x01}, + {value: 0x812d, lo: 0x90, hi: 0x96}, + // Block 0x8c, offset 0x2ab + {value: 0x0000, lo: 0x02}, + {value: 0x8132, lo: 0x84, hi: 0x89}, + {value: 0x8102, lo: 0x8a, hi: 0x8a}, + // Block 0x8d, offset 0x2ae + {value: 0x0000, lo: 0x01}, + {value: 0x8100, lo: 0x93, hi: 0x93}, +} + +// lookup returns the trie value for the first UTF-8 encoding in s and +// the width in bytes of this encoding. The size will be 0 if s does not +// hold enough bytes to complete the encoding. len(s) must be greater than 0. +func (t *nfkcTrie) lookup(s []byte) (v uint16, sz int) { + c0 := s[0] + switch { + case c0 < 0x80: // is ASCII + return nfkcValues[c0], 1 + case c0 < 0xC2: + return 0, 1 // Illegal UTF-8: not a starter, not ASCII. + case c0 < 0xE0: // 2-byte UTF-8 + if len(s) < 2 { + return 0, 0 + } + i := nfkcIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c1), 2 + case c0 < 0xF0: // 3-byte UTF-8 + if len(s) < 3 { + return 0, 0 + } + i := nfkcIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = nfkcIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c2), 3 + case c0 < 0xF8: // 4-byte UTF-8 + if len(s) < 4 { + return 0, 0 + } + i := nfkcIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = nfkcIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + o = uint32(i)<<6 + uint32(c2) + i = nfkcIndex[o] + c3 := s[3] + if c3 < 0x80 || 0xC0 <= c3 { + return 0, 3 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c3), 4 + } + // Illegal rune + return 0, 1 +} + +// lookupUnsafe returns the trie value for the first UTF-8 encoding in s. +// s must start with a full and valid UTF-8 encoded rune. +func (t *nfkcTrie) lookupUnsafe(s []byte) uint16 { + c0 := s[0] + if c0 < 0x80 { // is ASCII + return nfkcValues[c0] + } + i := nfkcIndex[c0] + if c0 < 0xE0 { // 2-byte UTF-8 + return t.lookupValue(uint32(i), s[1]) + } + i = nfkcIndex[uint32(i)<<6+uint32(s[1])] + if c0 < 0xF0 { // 3-byte UTF-8 + return t.lookupValue(uint32(i), s[2]) + } + i = nfkcIndex[uint32(i)<<6+uint32(s[2])] + if c0 < 0xF8 { // 4-byte UTF-8 + return t.lookupValue(uint32(i), s[3]) + } + return 0 +} + +// lookupString returns the trie value for the first UTF-8 encoding in s and +// the width in bytes of this encoding. The size will be 0 if s does not +// hold enough bytes to complete the encoding. len(s) must be greater than 0. +func (t *nfkcTrie) lookupString(s string) (v uint16, sz int) { + c0 := s[0] + switch { + case c0 < 0x80: // is ASCII + return nfkcValues[c0], 1 + case c0 < 0xC2: + return 0, 1 // Illegal UTF-8: not a starter, not ASCII. + case c0 < 0xE0: // 2-byte UTF-8 + if len(s) < 2 { + return 0, 0 + } + i := nfkcIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c1), 2 + case c0 < 0xF0: // 3-byte UTF-8 + if len(s) < 3 { + return 0, 0 + } + i := nfkcIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = nfkcIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c2), 3 + case c0 < 0xF8: // 4-byte UTF-8 + if len(s) < 4 { + return 0, 0 + } + i := nfkcIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = nfkcIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + o = uint32(i)<<6 + uint32(c2) + i = nfkcIndex[o] + c3 := s[3] + if c3 < 0x80 || 0xC0 <= c3 { + return 0, 3 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c3), 4 + } + // Illegal rune + return 0, 1 +} + +// lookupStringUnsafe returns the trie value for the first UTF-8 encoding in s. +// s must start with a full and valid UTF-8 encoded rune. +func (t *nfkcTrie) lookupStringUnsafe(s string) uint16 { + c0 := s[0] + if c0 < 0x80 { // is ASCII + return nfkcValues[c0] + } + i := nfkcIndex[c0] + if c0 < 0xE0 { // 2-byte UTF-8 + return t.lookupValue(uint32(i), s[1]) + } + i = nfkcIndex[uint32(i)<<6+uint32(s[1])] + if c0 < 0xF0 { // 3-byte UTF-8 + return t.lookupValue(uint32(i), s[2]) + } + i = nfkcIndex[uint32(i)<<6+uint32(s[2])] + if c0 < 0xF8 { // 4-byte UTF-8 + return t.lookupValue(uint32(i), s[3]) + } + return 0 +} + +// nfkcTrie. Total size: 16994 bytes (16.60 KiB). Checksum: c3ed54ee046f3c46. +type nfkcTrie struct{} + +func newNfkcTrie(i int) *nfkcTrie { + return &nfkcTrie{} +} + +// lookupValue determines the type of block n and looks up the value for b. +func (t *nfkcTrie) lookupValue(n uint32, b byte) uint16 { + switch { + case n < 90: + return uint16(nfkcValues[n<<6+uint32(b)]) + default: + n -= 90 + return uint16(nfkcSparse.lookup(n, b)) + } +} + +// nfkcValues: 92 blocks, 5888 entries, 11776 bytes +// The third block is the zero block. +var nfkcValues = [5888]uint16{ + // Block 0x0, offset 0x0 + 0x3c: 0xa000, 0x3d: 0xa000, 0x3e: 0xa000, + // Block 0x1, offset 0x40 + 0x41: 0xa000, 0x42: 0xa000, 0x43: 0xa000, 0x44: 0xa000, 0x45: 0xa000, + 0x46: 0xa000, 0x47: 0xa000, 0x48: 0xa000, 0x49: 0xa000, 0x4a: 0xa000, 0x4b: 0xa000, + 0x4c: 0xa000, 0x4d: 0xa000, 0x4e: 0xa000, 0x4f: 0xa000, 0x50: 0xa000, + 0x52: 0xa000, 0x53: 0xa000, 0x54: 0xa000, 0x55: 0xa000, 0x56: 0xa000, 0x57: 0xa000, + 0x58: 0xa000, 0x59: 0xa000, 0x5a: 0xa000, + 0x61: 0xa000, 0x62: 0xa000, 0x63: 0xa000, + 0x64: 0xa000, 0x65: 0xa000, 0x66: 0xa000, 0x67: 0xa000, 0x68: 0xa000, 0x69: 0xa000, + 0x6a: 0xa000, 0x6b: 0xa000, 0x6c: 0xa000, 0x6d: 0xa000, 0x6e: 0xa000, 0x6f: 0xa000, + 0x70: 0xa000, 0x72: 0xa000, 0x73: 0xa000, 0x74: 0xa000, 0x75: 0xa000, + 0x76: 0xa000, 0x77: 0xa000, 0x78: 0xa000, 0x79: 0xa000, 0x7a: 0xa000, + // Block 0x2, offset 0x80 + // Block 0x3, offset 0xc0 + 0xc0: 0x2f6f, 0xc1: 0x2f74, 0xc2: 0x4688, 0xc3: 0x2f79, 0xc4: 0x4697, 0xc5: 0x469c, + 0xc6: 0xa000, 0xc7: 0x46a6, 0xc8: 0x2fe2, 0xc9: 0x2fe7, 0xca: 0x46ab, 0xcb: 0x2ffb, + 0xcc: 0x306e, 0xcd: 0x3073, 0xce: 0x3078, 0xcf: 0x46bf, 0xd1: 0x3104, + 0xd2: 0x3127, 0xd3: 0x312c, 0xd4: 0x46c9, 0xd5: 0x46ce, 0xd6: 0x46dd, + 0xd8: 0xa000, 0xd9: 0x31b3, 0xda: 0x31b8, 0xdb: 0x31bd, 0xdc: 0x470f, 0xdd: 0x3235, + 0xe0: 0x327b, 0xe1: 0x3280, 0xe2: 0x4719, 0xe3: 0x3285, + 0xe4: 0x4728, 0xe5: 0x472d, 0xe6: 0xa000, 0xe7: 0x4737, 0xe8: 0x32ee, 0xe9: 0x32f3, + 0xea: 0x473c, 0xeb: 0x3307, 0xec: 0x337f, 0xed: 0x3384, 0xee: 0x3389, 0xef: 0x4750, + 0xf1: 0x3415, 0xf2: 0x3438, 0xf3: 0x343d, 0xf4: 0x475a, 0xf5: 0x475f, + 0xf6: 0x476e, 0xf8: 0xa000, 0xf9: 0x34c9, 0xfa: 0x34ce, 0xfb: 0x34d3, + 0xfc: 0x47a0, 0xfd: 0x3550, 0xff: 0x3569, + // Block 0x4, offset 0x100 + 0x100: 0x2f7e, 0x101: 0x328a, 0x102: 0x468d, 0x103: 0x471e, 0x104: 0x2f9c, 0x105: 0x32a8, + 0x106: 0x2fb0, 0x107: 0x32bc, 0x108: 0x2fb5, 0x109: 0x32c1, 0x10a: 0x2fba, 0x10b: 0x32c6, + 0x10c: 0x2fbf, 0x10d: 0x32cb, 0x10e: 0x2fc9, 0x10f: 0x32d5, + 0x112: 0x46b0, 0x113: 0x4741, 0x114: 0x2ff1, 0x115: 0x32fd, 0x116: 0x2ff6, 0x117: 0x3302, + 0x118: 0x3014, 0x119: 0x3320, 0x11a: 0x3005, 0x11b: 0x3311, 0x11c: 0x302d, 0x11d: 0x3339, + 0x11e: 0x3037, 0x11f: 0x3343, 0x120: 0x303c, 0x121: 0x3348, 0x122: 0x3046, 0x123: 0x3352, + 0x124: 0x304b, 0x125: 0x3357, 0x128: 0x307d, 0x129: 0x338e, + 0x12a: 0x3082, 0x12b: 0x3393, 0x12c: 0x3087, 0x12d: 0x3398, 0x12e: 0x30aa, 0x12f: 0x33b6, + 0x130: 0x308c, 0x132: 0x195d, 0x133: 0x19e7, 0x134: 0x30b4, 0x135: 0x33c0, + 0x136: 0x30c8, 0x137: 0x33d9, 0x139: 0x30d2, 0x13a: 0x33e3, 0x13b: 0x30dc, + 0x13c: 0x33ed, 0x13d: 0x30d7, 0x13e: 0x33e8, 0x13f: 0x1bac, + // Block 0x5, offset 0x140 + 0x140: 0x1c34, 0x143: 0x30ff, 0x144: 0x3410, 0x145: 0x3118, + 0x146: 0x3429, 0x147: 0x310e, 0x148: 0x341f, 0x149: 0x1c5c, + 0x14c: 0x46d3, 0x14d: 0x4764, 0x14e: 0x3131, 0x14f: 0x3442, 0x150: 0x313b, 0x151: 0x344c, + 0x154: 0x3159, 0x155: 0x346a, 0x156: 0x3172, 0x157: 0x3483, + 0x158: 0x3163, 0x159: 0x3474, 0x15a: 0x46f6, 0x15b: 0x4787, 0x15c: 0x317c, 0x15d: 0x348d, + 0x15e: 0x318b, 0x15f: 0x349c, 0x160: 0x46fb, 0x161: 0x478c, 0x162: 0x31a4, 0x163: 0x34ba, + 0x164: 0x3195, 0x165: 0x34ab, 0x168: 0x4705, 0x169: 0x4796, + 0x16a: 0x470a, 0x16b: 0x479b, 0x16c: 0x31c2, 0x16d: 0x34d8, 0x16e: 0x31cc, 0x16f: 0x34e2, + 0x170: 0x31d1, 0x171: 0x34e7, 0x172: 0x31ef, 0x173: 0x3505, 0x174: 0x3212, 0x175: 0x3528, + 0x176: 0x323a, 0x177: 0x3555, 0x178: 0x324e, 0x179: 0x325d, 0x17a: 0x357d, 0x17b: 0x3267, + 0x17c: 0x3587, 0x17d: 0x326c, 0x17e: 0x358c, 0x17f: 0x00a7, + // Block 0x6, offset 0x180 + 0x184: 0x2dee, 0x185: 0x2df4, + 0x186: 0x2dfa, 0x187: 0x1972, 0x188: 0x1975, 0x189: 0x1a08, 0x18a: 0x1987, 0x18b: 0x198a, + 0x18c: 0x1a3e, 0x18d: 0x2f88, 0x18e: 0x3294, 0x18f: 0x3096, 0x190: 0x33a2, 0x191: 0x3140, + 0x192: 0x3451, 0x193: 0x31d6, 0x194: 0x34ec, 0x195: 0x39cf, 0x196: 0x3b5e, 0x197: 0x39c8, + 0x198: 0x3b57, 0x199: 0x39d6, 0x19a: 0x3b65, 0x19b: 0x39c1, 0x19c: 0x3b50, + 0x19e: 0x38b0, 0x19f: 0x3a3f, 0x1a0: 0x38a9, 0x1a1: 0x3a38, 0x1a2: 0x35b3, 0x1a3: 0x35c5, + 0x1a6: 0x3041, 0x1a7: 0x334d, 0x1a8: 0x30be, 0x1a9: 0x33cf, + 0x1aa: 0x46ec, 0x1ab: 0x477d, 0x1ac: 0x3990, 0x1ad: 0x3b1f, 0x1ae: 0x35d7, 0x1af: 0x35dd, + 0x1b0: 0x33c5, 0x1b1: 0x1942, 0x1b2: 0x1945, 0x1b3: 0x19cf, 0x1b4: 0x3028, 0x1b5: 0x3334, + 0x1b8: 0x30fa, 0x1b9: 0x340b, 0x1ba: 0x38b7, 0x1bb: 0x3a46, + 0x1bc: 0x35ad, 0x1bd: 0x35bf, 0x1be: 0x35b9, 0x1bf: 0x35cb, + // Block 0x7, offset 0x1c0 + 0x1c0: 0x2f8d, 0x1c1: 0x3299, 0x1c2: 0x2f92, 0x1c3: 0x329e, 0x1c4: 0x300a, 0x1c5: 0x3316, + 0x1c6: 0x300f, 0x1c7: 0x331b, 0x1c8: 0x309b, 0x1c9: 0x33a7, 0x1ca: 0x30a0, 0x1cb: 0x33ac, + 0x1cc: 0x3145, 0x1cd: 0x3456, 0x1ce: 0x314a, 0x1cf: 0x345b, 0x1d0: 0x3168, 0x1d1: 0x3479, + 0x1d2: 0x316d, 0x1d3: 0x347e, 0x1d4: 0x31db, 0x1d5: 0x34f1, 0x1d6: 0x31e0, 0x1d7: 0x34f6, + 0x1d8: 0x3186, 0x1d9: 0x3497, 0x1da: 0x319f, 0x1db: 0x34b5, + 0x1de: 0x305a, 0x1df: 0x3366, + 0x1e6: 0x4692, 0x1e7: 0x4723, 0x1e8: 0x46ba, 0x1e9: 0x474b, + 0x1ea: 0x395f, 0x1eb: 0x3aee, 0x1ec: 0x393c, 0x1ed: 0x3acb, 0x1ee: 0x46d8, 0x1ef: 0x4769, + 0x1f0: 0x3958, 0x1f1: 0x3ae7, 0x1f2: 0x3244, 0x1f3: 0x355f, + // Block 0x8, offset 0x200 + 0x200: 0x9932, 0x201: 0x9932, 0x202: 0x9932, 0x203: 0x9932, 0x204: 0x9932, 0x205: 0x8132, + 0x206: 0x9932, 0x207: 0x9932, 0x208: 0x9932, 0x209: 0x9932, 0x20a: 0x9932, 0x20b: 0x9932, + 0x20c: 0x9932, 0x20d: 0x8132, 0x20e: 0x8132, 0x20f: 0x9932, 0x210: 0x8132, 0x211: 0x9932, + 0x212: 0x8132, 0x213: 0x9932, 0x214: 0x9932, 0x215: 0x8133, 0x216: 0x812d, 0x217: 0x812d, + 0x218: 0x812d, 0x219: 0x812d, 0x21a: 0x8133, 0x21b: 0x992b, 0x21c: 0x812d, 0x21d: 0x812d, + 0x21e: 0x812d, 0x21f: 0x812d, 0x220: 0x812d, 0x221: 0x8129, 0x222: 0x8129, 0x223: 0x992d, + 0x224: 0x992d, 0x225: 0x992d, 0x226: 0x992d, 0x227: 0x9929, 0x228: 0x9929, 0x229: 0x812d, + 0x22a: 0x812d, 0x22b: 0x812d, 0x22c: 0x812d, 0x22d: 0x992d, 0x22e: 0x992d, 0x22f: 0x812d, + 0x230: 0x992d, 0x231: 0x992d, 0x232: 0x812d, 0x233: 0x812d, 0x234: 0x8101, 0x235: 0x8101, + 0x236: 0x8101, 0x237: 0x8101, 0x238: 0x9901, 0x239: 0x812d, 0x23a: 0x812d, 0x23b: 0x812d, + 0x23c: 0x812d, 0x23d: 0x8132, 0x23e: 0x8132, 0x23f: 0x8132, + // Block 0x9, offset 0x240 + 0x240: 0x49ae, 0x241: 0x49b3, 0x242: 0x9932, 0x243: 0x49b8, 0x244: 0x4a71, 0x245: 0x9936, + 0x246: 0x8132, 0x247: 0x812d, 0x248: 0x812d, 0x249: 0x812d, 0x24a: 0x8132, 0x24b: 0x8132, + 0x24c: 0x8132, 0x24d: 0x812d, 0x24e: 0x812d, 0x250: 0x8132, 0x251: 0x8132, + 0x252: 0x8132, 0x253: 0x812d, 0x254: 0x812d, 0x255: 0x812d, 0x256: 0x812d, 0x257: 0x8132, + 0x258: 0x8133, 0x259: 0x812d, 0x25a: 0x812d, 0x25b: 0x8132, 0x25c: 0x8134, 0x25d: 0x8135, + 0x25e: 0x8135, 0x25f: 0x8134, 0x260: 0x8135, 0x261: 0x8135, 0x262: 0x8134, 0x263: 0x8132, + 0x264: 0x8132, 0x265: 0x8132, 0x266: 0x8132, 0x267: 0x8132, 0x268: 0x8132, 0x269: 0x8132, + 0x26a: 0x8132, 0x26b: 0x8132, 0x26c: 0x8132, 0x26d: 0x8132, 0x26e: 0x8132, 0x26f: 0x8132, + 0x274: 0x0170, + 0x27a: 0x42a5, + 0x27e: 0x0037, + // Block 0xa, offset 0x280 + 0x284: 0x425a, 0x285: 0x447b, + 0x286: 0x35e9, 0x287: 0x00ce, 0x288: 0x3607, 0x289: 0x3613, 0x28a: 0x3625, + 0x28c: 0x3643, 0x28e: 0x3655, 0x28f: 0x3673, 0x290: 0x3e08, 0x291: 0xa000, + 0x295: 0xa000, 0x297: 0xa000, + 0x299: 0xa000, + 0x29f: 0xa000, 0x2a1: 0xa000, + 0x2a5: 0xa000, 0x2a9: 0xa000, + 0x2aa: 0x3637, 0x2ab: 0x3667, 0x2ac: 0x47fe, 0x2ad: 0x3697, 0x2ae: 0x4828, 0x2af: 0x36a9, + 0x2b0: 0x3e70, 0x2b1: 0xa000, 0x2b5: 0xa000, + 0x2b7: 0xa000, 0x2b9: 0xa000, + 0x2bf: 0xa000, + // Block 0xb, offset 0x2c0 + 0x2c1: 0xa000, 0x2c5: 0xa000, + 0x2c9: 0xa000, 0x2ca: 0x4840, 0x2cb: 0x485e, + 0x2cc: 0x36c7, 0x2cd: 0x36df, 0x2ce: 0x4876, 0x2d0: 0x01be, 0x2d1: 0x01d0, + 0x2d2: 0x01ac, 0x2d3: 0x430c, 0x2d4: 0x4312, 0x2d5: 0x01fa, 0x2d6: 0x01e8, + 0x2f0: 0x01d6, 0x2f1: 0x01eb, 0x2f2: 0x01ee, 0x2f4: 0x0188, 0x2f5: 0x01c7, + 0x2f9: 0x01a6, + // Block 0xc, offset 0x300 + 0x300: 0x3721, 0x301: 0x372d, 0x303: 0x371b, + 0x306: 0xa000, 0x307: 0x3709, + 0x30c: 0x375d, 0x30d: 0x3745, 0x30e: 0x376f, 0x310: 0xa000, + 0x313: 0xa000, 0x315: 0xa000, 0x316: 0xa000, 0x317: 0xa000, + 0x318: 0xa000, 0x319: 0x3751, 0x31a: 0xa000, + 0x31e: 0xa000, 0x323: 0xa000, + 0x327: 0xa000, + 0x32b: 0xa000, 0x32d: 0xa000, + 0x330: 0xa000, 0x333: 0xa000, 0x335: 0xa000, + 0x336: 0xa000, 0x337: 0xa000, 0x338: 0xa000, 0x339: 0x37d5, 0x33a: 0xa000, + 0x33e: 0xa000, + // Block 0xd, offset 0x340 + 0x341: 0x3733, 0x342: 0x37b7, + 0x350: 0x370f, 0x351: 0x3793, + 0x352: 0x3715, 0x353: 0x3799, 0x356: 0x3727, 0x357: 0x37ab, + 0x358: 0xa000, 0x359: 0xa000, 0x35a: 0x3829, 0x35b: 0x382f, 0x35c: 0x3739, 0x35d: 0x37bd, + 0x35e: 0x373f, 0x35f: 0x37c3, 0x362: 0x374b, 0x363: 0x37cf, + 0x364: 0x3757, 0x365: 0x37db, 0x366: 0x3763, 0x367: 0x37e7, 0x368: 0xa000, 0x369: 0xa000, + 0x36a: 0x3835, 0x36b: 0x383b, 0x36c: 0x378d, 0x36d: 0x3811, 0x36e: 0x3769, 0x36f: 0x37ed, + 0x370: 0x3775, 0x371: 0x37f9, 0x372: 0x377b, 0x373: 0x37ff, 0x374: 0x3781, 0x375: 0x3805, + 0x378: 0x3787, 0x379: 0x380b, + // Block 0xe, offset 0x380 + 0x387: 0x1d61, + 0x391: 0x812d, + 0x392: 0x8132, 0x393: 0x8132, 0x394: 0x8132, 0x395: 0x8132, 0x396: 0x812d, 0x397: 0x8132, + 0x398: 0x8132, 0x399: 0x8132, 0x39a: 0x812e, 0x39b: 0x812d, 0x39c: 0x8132, 0x39d: 0x8132, + 0x39e: 0x8132, 0x39f: 0x8132, 0x3a0: 0x8132, 0x3a1: 0x8132, 0x3a2: 0x812d, 0x3a3: 0x812d, + 0x3a4: 0x812d, 0x3a5: 0x812d, 0x3a6: 0x812d, 0x3a7: 0x812d, 0x3a8: 0x8132, 0x3a9: 0x8132, + 0x3aa: 0x812d, 0x3ab: 0x8132, 0x3ac: 0x8132, 0x3ad: 0x812e, 0x3ae: 0x8131, 0x3af: 0x8132, + 0x3b0: 0x8105, 0x3b1: 0x8106, 0x3b2: 0x8107, 0x3b3: 0x8108, 0x3b4: 0x8109, 0x3b5: 0x810a, + 0x3b6: 0x810b, 0x3b7: 0x810c, 0x3b8: 0x810d, 0x3b9: 0x810e, 0x3ba: 0x810e, 0x3bb: 0x810f, + 0x3bc: 0x8110, 0x3bd: 0x8111, 0x3bf: 0x8112, + // Block 0xf, offset 0x3c0 + 0x3c8: 0xa000, 0x3ca: 0xa000, 0x3cb: 0x8116, + 0x3cc: 0x8117, 0x3cd: 0x8118, 0x3ce: 0x8119, 0x3cf: 0x811a, 0x3d0: 0x811b, 0x3d1: 0x811c, + 0x3d2: 0x811d, 0x3d3: 0x9932, 0x3d4: 0x9932, 0x3d5: 0x992d, 0x3d6: 0x812d, 0x3d7: 0x8132, + 0x3d8: 0x8132, 0x3d9: 0x8132, 0x3da: 0x8132, 0x3db: 0x8132, 0x3dc: 0x812d, 0x3dd: 0x8132, + 0x3de: 0x8132, 0x3df: 0x812d, + 0x3f0: 0x811e, 0x3f5: 0x1d84, + 0x3f6: 0x2013, 0x3f7: 0x204f, 0x3f8: 0x204a, + // Block 0x10, offset 0x400 + 0x405: 0xa000, + 0x406: 0x2d26, 0x407: 0xa000, 0x408: 0x2d2e, 0x409: 0xa000, 0x40a: 0x2d36, 0x40b: 0xa000, + 0x40c: 0x2d3e, 0x40d: 0xa000, 0x40e: 0x2d46, 0x411: 0xa000, + 0x412: 0x2d4e, + 0x434: 0x8102, 0x435: 0x9900, + 0x43a: 0xa000, 0x43b: 0x2d56, + 0x43c: 0xa000, 0x43d: 0x2d5e, 0x43e: 0xa000, 0x43f: 0xa000, + // Block 0x11, offset 0x440 + 0x440: 0x0069, 0x441: 0x006b, 0x442: 0x006f, 0x443: 0x0083, 0x444: 0x00f5, 0x445: 0x00f8, + 0x446: 0x0413, 0x447: 0x0085, 0x448: 0x0089, 0x449: 0x008b, 0x44a: 0x0104, 0x44b: 0x0107, + 0x44c: 0x010a, 0x44d: 0x008f, 0x44f: 0x0097, 0x450: 0x009b, 0x451: 0x00e0, + 0x452: 0x009f, 0x453: 0x00fe, 0x454: 0x0417, 0x455: 0x041b, 0x456: 0x00a1, 0x457: 0x00a9, + 0x458: 0x00ab, 0x459: 0x0423, 0x45a: 0x012b, 0x45b: 0x00ad, 0x45c: 0x0427, 0x45d: 0x01be, + 0x45e: 0x01c1, 0x45f: 0x01c4, 0x460: 0x01fa, 0x461: 0x01fd, 0x462: 0x0093, 0x463: 0x00a5, + 0x464: 0x00ab, 0x465: 0x00ad, 0x466: 0x01be, 0x467: 0x01c1, 0x468: 0x01eb, 0x469: 0x01fa, + 0x46a: 0x01fd, + 0x478: 0x020c, + // Block 0x12, offset 0x480 + 0x49b: 0x00fb, 0x49c: 0x0087, 0x49d: 0x0101, + 0x49e: 0x00d4, 0x49f: 0x010a, 0x4a0: 0x008d, 0x4a1: 0x010d, 0x4a2: 0x0110, 0x4a3: 0x0116, + 0x4a4: 0x011c, 0x4a5: 0x011f, 0x4a6: 0x0122, 0x4a7: 0x042b, 0x4a8: 0x016a, 0x4a9: 0x0128, + 0x4aa: 0x042f, 0x4ab: 0x016d, 0x4ac: 0x0131, 0x4ad: 0x012e, 0x4ae: 0x0134, 0x4af: 0x0137, + 0x4b0: 0x013a, 0x4b1: 0x013d, 0x4b2: 0x0140, 0x4b3: 0x014c, 0x4b4: 0x014f, 0x4b5: 0x00ec, + 0x4b6: 0x0152, 0x4b7: 0x0155, 0x4b8: 0x041f, 0x4b9: 0x0158, 0x4ba: 0x015b, 0x4bb: 0x00b5, + 0x4bc: 0x015e, 0x4bd: 0x0161, 0x4be: 0x0164, 0x4bf: 0x01d0, + // Block 0x13, offset 0x4c0 + 0x4c0: 0x2f97, 0x4c1: 0x32a3, 0x4c2: 0x2fa1, 0x4c3: 0x32ad, 0x4c4: 0x2fa6, 0x4c5: 0x32b2, + 0x4c6: 0x2fab, 0x4c7: 0x32b7, 0x4c8: 0x38cc, 0x4c9: 0x3a5b, 0x4ca: 0x2fc4, 0x4cb: 0x32d0, + 0x4cc: 0x2fce, 0x4cd: 0x32da, 0x4ce: 0x2fdd, 0x4cf: 0x32e9, 0x4d0: 0x2fd3, 0x4d1: 0x32df, + 0x4d2: 0x2fd8, 0x4d3: 0x32e4, 0x4d4: 0x38ef, 0x4d5: 0x3a7e, 0x4d6: 0x38f6, 0x4d7: 0x3a85, + 0x4d8: 0x3019, 0x4d9: 0x3325, 0x4da: 0x301e, 0x4db: 0x332a, 0x4dc: 0x3904, 0x4dd: 0x3a93, + 0x4de: 0x3023, 0x4df: 0x332f, 0x4e0: 0x3032, 0x4e1: 0x333e, 0x4e2: 0x3050, 0x4e3: 0x335c, + 0x4e4: 0x305f, 0x4e5: 0x336b, 0x4e6: 0x3055, 0x4e7: 0x3361, 0x4e8: 0x3064, 0x4e9: 0x3370, + 0x4ea: 0x3069, 0x4eb: 0x3375, 0x4ec: 0x30af, 0x4ed: 0x33bb, 0x4ee: 0x390b, 0x4ef: 0x3a9a, + 0x4f0: 0x30b9, 0x4f1: 0x33ca, 0x4f2: 0x30c3, 0x4f3: 0x33d4, 0x4f4: 0x30cd, 0x4f5: 0x33de, + 0x4f6: 0x46c4, 0x4f7: 0x4755, 0x4f8: 0x3912, 0x4f9: 0x3aa1, 0x4fa: 0x30e6, 0x4fb: 0x33f7, + 0x4fc: 0x30e1, 0x4fd: 0x33f2, 0x4fe: 0x30eb, 0x4ff: 0x33fc, + // Block 0x14, offset 0x500 + 0x500: 0x30f0, 0x501: 0x3401, 0x502: 0x30f5, 0x503: 0x3406, 0x504: 0x3109, 0x505: 0x341a, + 0x506: 0x3113, 0x507: 0x3424, 0x508: 0x3122, 0x509: 0x3433, 0x50a: 0x311d, 0x50b: 0x342e, + 0x50c: 0x3935, 0x50d: 0x3ac4, 0x50e: 0x3943, 0x50f: 0x3ad2, 0x510: 0x394a, 0x511: 0x3ad9, + 0x512: 0x3951, 0x513: 0x3ae0, 0x514: 0x314f, 0x515: 0x3460, 0x516: 0x3154, 0x517: 0x3465, + 0x518: 0x315e, 0x519: 0x346f, 0x51a: 0x46f1, 0x51b: 0x4782, 0x51c: 0x3997, 0x51d: 0x3b26, + 0x51e: 0x3177, 0x51f: 0x3488, 0x520: 0x3181, 0x521: 0x3492, 0x522: 0x4700, 0x523: 0x4791, + 0x524: 0x399e, 0x525: 0x3b2d, 0x526: 0x39a5, 0x527: 0x3b34, 0x528: 0x39ac, 0x529: 0x3b3b, + 0x52a: 0x3190, 0x52b: 0x34a1, 0x52c: 0x319a, 0x52d: 0x34b0, 0x52e: 0x31ae, 0x52f: 0x34c4, + 0x530: 0x31a9, 0x531: 0x34bf, 0x532: 0x31ea, 0x533: 0x3500, 0x534: 0x31f9, 0x535: 0x350f, + 0x536: 0x31f4, 0x537: 0x350a, 0x538: 0x39b3, 0x539: 0x3b42, 0x53a: 0x39ba, 0x53b: 0x3b49, + 0x53c: 0x31fe, 0x53d: 0x3514, 0x53e: 0x3203, 0x53f: 0x3519, + // Block 0x15, offset 0x540 + 0x540: 0x3208, 0x541: 0x351e, 0x542: 0x320d, 0x543: 0x3523, 0x544: 0x321c, 0x545: 0x3532, + 0x546: 0x3217, 0x547: 0x352d, 0x548: 0x3221, 0x549: 0x353c, 0x54a: 0x3226, 0x54b: 0x3541, + 0x54c: 0x322b, 0x54d: 0x3546, 0x54e: 0x3249, 0x54f: 0x3564, 0x550: 0x3262, 0x551: 0x3582, + 0x552: 0x3271, 0x553: 0x3591, 0x554: 0x3276, 0x555: 0x3596, 0x556: 0x337a, 0x557: 0x34a6, + 0x558: 0x3537, 0x559: 0x3573, 0x55a: 0x1be0, 0x55b: 0x42d7, + 0x560: 0x46a1, 0x561: 0x4732, 0x562: 0x2f83, 0x563: 0x328f, + 0x564: 0x3878, 0x565: 0x3a07, 0x566: 0x3871, 0x567: 0x3a00, 0x568: 0x3886, 0x569: 0x3a15, + 0x56a: 0x387f, 0x56b: 0x3a0e, 0x56c: 0x38be, 0x56d: 0x3a4d, 0x56e: 0x3894, 0x56f: 0x3a23, + 0x570: 0x388d, 0x571: 0x3a1c, 0x572: 0x38a2, 0x573: 0x3a31, 0x574: 0x389b, 0x575: 0x3a2a, + 0x576: 0x38c5, 0x577: 0x3a54, 0x578: 0x46b5, 0x579: 0x4746, 0x57a: 0x3000, 0x57b: 0x330c, + 0x57c: 0x2fec, 0x57d: 0x32f8, 0x57e: 0x38da, 0x57f: 0x3a69, + // Block 0x16, offset 0x580 + 0x580: 0x38d3, 0x581: 0x3a62, 0x582: 0x38e8, 0x583: 0x3a77, 0x584: 0x38e1, 0x585: 0x3a70, + 0x586: 0x38fd, 0x587: 0x3a8c, 0x588: 0x3091, 0x589: 0x339d, 0x58a: 0x30a5, 0x58b: 0x33b1, + 0x58c: 0x46e7, 0x58d: 0x4778, 0x58e: 0x3136, 0x58f: 0x3447, 0x590: 0x3920, 0x591: 0x3aaf, + 0x592: 0x3919, 0x593: 0x3aa8, 0x594: 0x392e, 0x595: 0x3abd, 0x596: 0x3927, 0x597: 0x3ab6, + 0x598: 0x3989, 0x599: 0x3b18, 0x59a: 0x396d, 0x59b: 0x3afc, 0x59c: 0x3966, 0x59d: 0x3af5, + 0x59e: 0x397b, 0x59f: 0x3b0a, 0x5a0: 0x3974, 0x5a1: 0x3b03, 0x5a2: 0x3982, 0x5a3: 0x3b11, + 0x5a4: 0x31e5, 0x5a5: 0x34fb, 0x5a6: 0x31c7, 0x5a7: 0x34dd, 0x5a8: 0x39e4, 0x5a9: 0x3b73, + 0x5aa: 0x39dd, 0x5ab: 0x3b6c, 0x5ac: 0x39f2, 0x5ad: 0x3b81, 0x5ae: 0x39eb, 0x5af: 0x3b7a, + 0x5b0: 0x39f9, 0x5b1: 0x3b88, 0x5b2: 0x3230, 0x5b3: 0x354b, 0x5b4: 0x3258, 0x5b5: 0x3578, + 0x5b6: 0x3253, 0x5b7: 0x356e, 0x5b8: 0x323f, 0x5b9: 0x355a, + // Block 0x17, offset 0x5c0 + 0x5c0: 0x4804, 0x5c1: 0x480a, 0x5c2: 0x491e, 0x5c3: 0x4936, 0x5c4: 0x4926, 0x5c5: 0x493e, + 0x5c6: 0x492e, 0x5c7: 0x4946, 0x5c8: 0x47aa, 0x5c9: 0x47b0, 0x5ca: 0x488e, 0x5cb: 0x48a6, + 0x5cc: 0x4896, 0x5cd: 0x48ae, 0x5ce: 0x489e, 0x5cf: 0x48b6, 0x5d0: 0x4816, 0x5d1: 0x481c, + 0x5d2: 0x3db8, 0x5d3: 0x3dc8, 0x5d4: 0x3dc0, 0x5d5: 0x3dd0, + 0x5d8: 0x47b6, 0x5d9: 0x47bc, 0x5da: 0x3ce8, 0x5db: 0x3cf8, 0x5dc: 0x3cf0, 0x5dd: 0x3d00, + 0x5e0: 0x482e, 0x5e1: 0x4834, 0x5e2: 0x494e, 0x5e3: 0x4966, + 0x5e4: 0x4956, 0x5e5: 0x496e, 0x5e6: 0x495e, 0x5e7: 0x4976, 0x5e8: 0x47c2, 0x5e9: 0x47c8, + 0x5ea: 0x48be, 0x5eb: 0x48d6, 0x5ec: 0x48c6, 0x5ed: 0x48de, 0x5ee: 0x48ce, 0x5ef: 0x48e6, + 0x5f0: 0x4846, 0x5f1: 0x484c, 0x5f2: 0x3e18, 0x5f3: 0x3e30, 0x5f4: 0x3e20, 0x5f5: 0x3e38, + 0x5f6: 0x3e28, 0x5f7: 0x3e40, 0x5f8: 0x47ce, 0x5f9: 0x47d4, 0x5fa: 0x3d18, 0x5fb: 0x3d30, + 0x5fc: 0x3d20, 0x5fd: 0x3d38, 0x5fe: 0x3d28, 0x5ff: 0x3d40, + // Block 0x18, offset 0x600 + 0x600: 0x4852, 0x601: 0x4858, 0x602: 0x3e48, 0x603: 0x3e58, 0x604: 0x3e50, 0x605: 0x3e60, + 0x608: 0x47da, 0x609: 0x47e0, 0x60a: 0x3d48, 0x60b: 0x3d58, + 0x60c: 0x3d50, 0x60d: 0x3d60, 0x610: 0x4864, 0x611: 0x486a, + 0x612: 0x3e80, 0x613: 0x3e98, 0x614: 0x3e88, 0x615: 0x3ea0, 0x616: 0x3e90, 0x617: 0x3ea8, + 0x619: 0x47e6, 0x61b: 0x3d68, 0x61d: 0x3d70, + 0x61f: 0x3d78, 0x620: 0x487c, 0x621: 0x4882, 0x622: 0x497e, 0x623: 0x4996, + 0x624: 0x4986, 0x625: 0x499e, 0x626: 0x498e, 0x627: 0x49a6, 0x628: 0x47ec, 0x629: 0x47f2, + 0x62a: 0x48ee, 0x62b: 0x4906, 0x62c: 0x48f6, 0x62d: 0x490e, 0x62e: 0x48fe, 0x62f: 0x4916, + 0x630: 0x47f8, 0x631: 0x431e, 0x632: 0x3691, 0x633: 0x4324, 0x634: 0x4822, 0x635: 0x432a, + 0x636: 0x36a3, 0x637: 0x4330, 0x638: 0x36c1, 0x639: 0x4336, 0x63a: 0x36d9, 0x63b: 0x433c, + 0x63c: 0x4870, 0x63d: 0x4342, + // Block 0x19, offset 0x640 + 0x640: 0x3da0, 0x641: 0x3da8, 0x642: 0x4184, 0x643: 0x41a2, 0x644: 0x418e, 0x645: 0x41ac, + 0x646: 0x4198, 0x647: 0x41b6, 0x648: 0x3cd8, 0x649: 0x3ce0, 0x64a: 0x40d0, 0x64b: 0x40ee, + 0x64c: 0x40da, 0x64d: 0x40f8, 0x64e: 0x40e4, 0x64f: 0x4102, 0x650: 0x3de8, 0x651: 0x3df0, + 0x652: 0x41c0, 0x653: 0x41de, 0x654: 0x41ca, 0x655: 0x41e8, 0x656: 0x41d4, 0x657: 0x41f2, + 0x658: 0x3d08, 0x659: 0x3d10, 0x65a: 0x410c, 0x65b: 0x412a, 0x65c: 0x4116, 0x65d: 0x4134, + 0x65e: 0x4120, 0x65f: 0x413e, 0x660: 0x3ec0, 0x661: 0x3ec8, 0x662: 0x41fc, 0x663: 0x421a, + 0x664: 0x4206, 0x665: 0x4224, 0x666: 0x4210, 0x667: 0x422e, 0x668: 0x3d80, 0x669: 0x3d88, + 0x66a: 0x4148, 0x66b: 0x4166, 0x66c: 0x4152, 0x66d: 0x4170, 0x66e: 0x415c, 0x66f: 0x417a, + 0x670: 0x3685, 0x671: 0x367f, 0x672: 0x3d90, 0x673: 0x368b, 0x674: 0x3d98, + 0x676: 0x4810, 0x677: 0x3db0, 0x678: 0x35f5, 0x679: 0x35ef, 0x67a: 0x35e3, 0x67b: 0x42ee, + 0x67c: 0x35fb, 0x67d: 0x4287, 0x67e: 0x01d3, 0x67f: 0x4287, + // Block 0x1a, offset 0x680 + 0x680: 0x42a0, 0x681: 0x4482, 0x682: 0x3dd8, 0x683: 0x369d, 0x684: 0x3de0, + 0x686: 0x483a, 0x687: 0x3df8, 0x688: 0x3601, 0x689: 0x42f4, 0x68a: 0x360d, 0x68b: 0x42fa, + 0x68c: 0x3619, 0x68d: 0x4489, 0x68e: 0x4490, 0x68f: 0x4497, 0x690: 0x36b5, 0x691: 0x36af, + 0x692: 0x3e00, 0x693: 0x44e4, 0x696: 0x36bb, 0x697: 0x3e10, + 0x698: 0x3631, 0x699: 0x362b, 0x69a: 0x361f, 0x69b: 0x4300, 0x69d: 0x449e, + 0x69e: 0x44a5, 0x69f: 0x44ac, 0x6a0: 0x36eb, 0x6a1: 0x36e5, 0x6a2: 0x3e68, 0x6a3: 0x44ec, + 0x6a4: 0x36cd, 0x6a5: 0x36d3, 0x6a6: 0x36f1, 0x6a7: 0x3e78, 0x6a8: 0x3661, 0x6a9: 0x365b, + 0x6aa: 0x364f, 0x6ab: 0x430c, 0x6ac: 0x3649, 0x6ad: 0x4474, 0x6ae: 0x447b, 0x6af: 0x0081, + 0x6b2: 0x3eb0, 0x6b3: 0x36f7, 0x6b4: 0x3eb8, + 0x6b6: 0x4888, 0x6b7: 0x3ed0, 0x6b8: 0x363d, 0x6b9: 0x4306, 0x6ba: 0x366d, 0x6bb: 0x4318, + 0x6bc: 0x3679, 0x6bd: 0x425a, 0x6be: 0x428c, + // Block 0x1b, offset 0x6c0 + 0x6c0: 0x1bd8, 0x6c1: 0x1bdc, 0x6c2: 0x0047, 0x6c3: 0x1c54, 0x6c5: 0x1be8, + 0x6c6: 0x1bec, 0x6c7: 0x00e9, 0x6c9: 0x1c58, 0x6ca: 0x008f, 0x6cb: 0x0051, + 0x6cc: 0x0051, 0x6cd: 0x0051, 0x6ce: 0x0091, 0x6cf: 0x00da, 0x6d0: 0x0053, 0x6d1: 0x0053, + 0x6d2: 0x0059, 0x6d3: 0x0099, 0x6d5: 0x005d, 0x6d6: 0x198d, + 0x6d9: 0x0061, 0x6da: 0x0063, 0x6db: 0x0065, 0x6dc: 0x0065, 0x6dd: 0x0065, + 0x6e0: 0x199f, 0x6e1: 0x1bc8, 0x6e2: 0x19a8, + 0x6e4: 0x0075, 0x6e6: 0x01b8, 0x6e8: 0x0075, + 0x6ea: 0x0057, 0x6eb: 0x42d2, 0x6ec: 0x0045, 0x6ed: 0x0047, 0x6ef: 0x008b, + 0x6f0: 0x004b, 0x6f1: 0x004d, 0x6f3: 0x005b, 0x6f4: 0x009f, 0x6f5: 0x0215, + 0x6f6: 0x0218, 0x6f7: 0x021b, 0x6f8: 0x021e, 0x6f9: 0x0093, 0x6fb: 0x1b98, + 0x6fc: 0x01e8, 0x6fd: 0x01c1, 0x6fe: 0x0179, 0x6ff: 0x01a0, + // Block 0x1c, offset 0x700 + 0x700: 0x0463, 0x705: 0x0049, + 0x706: 0x0089, 0x707: 0x008b, 0x708: 0x0093, 0x709: 0x0095, + 0x710: 0x222e, 0x711: 0x223a, + 0x712: 0x22ee, 0x713: 0x2216, 0x714: 0x229a, 0x715: 0x2222, 0x716: 0x22a0, 0x717: 0x22b8, + 0x718: 0x22c4, 0x719: 0x2228, 0x71a: 0x22ca, 0x71b: 0x2234, 0x71c: 0x22be, 0x71d: 0x22d0, + 0x71e: 0x22d6, 0x71f: 0x1cbc, 0x720: 0x0053, 0x721: 0x195a, 0x722: 0x1ba4, 0x723: 0x1963, + 0x724: 0x006d, 0x725: 0x19ab, 0x726: 0x1bd0, 0x727: 0x1d48, 0x728: 0x1966, 0x729: 0x0071, + 0x72a: 0x19b7, 0x72b: 0x1bd4, 0x72c: 0x0059, 0x72d: 0x0047, 0x72e: 0x0049, 0x72f: 0x005b, + 0x730: 0x0093, 0x731: 0x19e4, 0x732: 0x1c18, 0x733: 0x19ed, 0x734: 0x00ad, 0x735: 0x1a62, + 0x736: 0x1c4c, 0x737: 0x1d5c, 0x738: 0x19f0, 0x739: 0x00b1, 0x73a: 0x1a65, 0x73b: 0x1c50, + 0x73c: 0x0099, 0x73d: 0x0087, 0x73e: 0x0089, 0x73f: 0x009b, + // Block 0x1d, offset 0x740 + 0x741: 0x3c06, 0x743: 0xa000, 0x744: 0x3c0d, 0x745: 0xa000, + 0x747: 0x3c14, 0x748: 0xa000, 0x749: 0x3c1b, + 0x74d: 0xa000, + 0x760: 0x2f65, 0x761: 0xa000, 0x762: 0x3c29, + 0x764: 0xa000, 0x765: 0xa000, + 0x76d: 0x3c22, 0x76e: 0x2f60, 0x76f: 0x2f6a, + 0x770: 0x3c30, 0x771: 0x3c37, 0x772: 0xa000, 0x773: 0xa000, 0x774: 0x3c3e, 0x775: 0x3c45, + 0x776: 0xa000, 0x777: 0xa000, 0x778: 0x3c4c, 0x779: 0x3c53, 0x77a: 0xa000, 0x77b: 0xa000, + 0x77c: 0xa000, 0x77d: 0xa000, + // Block 0x1e, offset 0x780 + 0x780: 0x3c5a, 0x781: 0x3c61, 0x782: 0xa000, 0x783: 0xa000, 0x784: 0x3c76, 0x785: 0x3c7d, + 0x786: 0xa000, 0x787: 0xa000, 0x788: 0x3c84, 0x789: 0x3c8b, + 0x791: 0xa000, + 0x792: 0xa000, + 0x7a2: 0xa000, + 0x7a8: 0xa000, 0x7a9: 0xa000, + 0x7ab: 0xa000, 0x7ac: 0x3ca0, 0x7ad: 0x3ca7, 0x7ae: 0x3cae, 0x7af: 0x3cb5, + 0x7b2: 0xa000, 0x7b3: 0xa000, 0x7b4: 0xa000, 0x7b5: 0xa000, + // Block 0x1f, offset 0x7c0 + 0x7e0: 0x0023, 0x7e1: 0x0025, 0x7e2: 0x0027, 0x7e3: 0x0029, + 0x7e4: 0x002b, 0x7e5: 0x002d, 0x7e6: 0x002f, 0x7e7: 0x0031, 0x7e8: 0x0033, 0x7e9: 0x1882, + 0x7ea: 0x1885, 0x7eb: 0x1888, 0x7ec: 0x188b, 0x7ed: 0x188e, 0x7ee: 0x1891, 0x7ef: 0x1894, + 0x7f0: 0x1897, 0x7f1: 0x189a, 0x7f2: 0x189d, 0x7f3: 0x18a6, 0x7f4: 0x1a68, 0x7f5: 0x1a6c, + 0x7f6: 0x1a70, 0x7f7: 0x1a74, 0x7f8: 0x1a78, 0x7f9: 0x1a7c, 0x7fa: 0x1a80, 0x7fb: 0x1a84, + 0x7fc: 0x1a88, 0x7fd: 0x1c80, 0x7fe: 0x1c85, 0x7ff: 0x1c8a, + // Block 0x20, offset 0x800 + 0x800: 0x1c8f, 0x801: 0x1c94, 0x802: 0x1c99, 0x803: 0x1c9e, 0x804: 0x1ca3, 0x805: 0x1ca8, + 0x806: 0x1cad, 0x807: 0x1cb2, 0x808: 0x187f, 0x809: 0x18a3, 0x80a: 0x18c7, 0x80b: 0x18eb, + 0x80c: 0x190f, 0x80d: 0x1918, 0x80e: 0x191e, 0x80f: 0x1924, 0x810: 0x192a, 0x811: 0x1b60, + 0x812: 0x1b64, 0x813: 0x1b68, 0x814: 0x1b6c, 0x815: 0x1b70, 0x816: 0x1b74, 0x817: 0x1b78, + 0x818: 0x1b7c, 0x819: 0x1b80, 0x81a: 0x1b84, 0x81b: 0x1b88, 0x81c: 0x1af4, 0x81d: 0x1af8, + 0x81e: 0x1afc, 0x81f: 0x1b00, 0x820: 0x1b04, 0x821: 0x1b08, 0x822: 0x1b0c, 0x823: 0x1b10, + 0x824: 0x1b14, 0x825: 0x1b18, 0x826: 0x1b1c, 0x827: 0x1b20, 0x828: 0x1b24, 0x829: 0x1b28, + 0x82a: 0x1b2c, 0x82b: 0x1b30, 0x82c: 0x1b34, 0x82d: 0x1b38, 0x82e: 0x1b3c, 0x82f: 0x1b40, + 0x830: 0x1b44, 0x831: 0x1b48, 0x832: 0x1b4c, 0x833: 0x1b50, 0x834: 0x1b54, 0x835: 0x1b58, + 0x836: 0x0043, 0x837: 0x0045, 0x838: 0x0047, 0x839: 0x0049, 0x83a: 0x004b, 0x83b: 0x004d, + 0x83c: 0x004f, 0x83d: 0x0051, 0x83e: 0x0053, 0x83f: 0x0055, + // Block 0x21, offset 0x840 + 0x840: 0x06bf, 0x841: 0x06e3, 0x842: 0x06ef, 0x843: 0x06ff, 0x844: 0x0707, 0x845: 0x0713, + 0x846: 0x071b, 0x847: 0x0723, 0x848: 0x072f, 0x849: 0x0783, 0x84a: 0x079b, 0x84b: 0x07ab, + 0x84c: 0x07bb, 0x84d: 0x07cb, 0x84e: 0x07db, 0x84f: 0x07fb, 0x850: 0x07ff, 0x851: 0x0803, + 0x852: 0x0837, 0x853: 0x085f, 0x854: 0x086f, 0x855: 0x0877, 0x856: 0x087b, 0x857: 0x0887, + 0x858: 0x08a3, 0x859: 0x08a7, 0x85a: 0x08bf, 0x85b: 0x08c3, 0x85c: 0x08cb, 0x85d: 0x08db, + 0x85e: 0x0977, 0x85f: 0x098b, 0x860: 0x09cb, 0x861: 0x09df, 0x862: 0x09e7, 0x863: 0x09eb, + 0x864: 0x09fb, 0x865: 0x0a17, 0x866: 0x0a43, 0x867: 0x0a4f, 0x868: 0x0a6f, 0x869: 0x0a7b, + 0x86a: 0x0a7f, 0x86b: 0x0a83, 0x86c: 0x0a9b, 0x86d: 0x0a9f, 0x86e: 0x0acb, 0x86f: 0x0ad7, + 0x870: 0x0adf, 0x871: 0x0ae7, 0x872: 0x0af7, 0x873: 0x0aff, 0x874: 0x0b07, 0x875: 0x0b33, + 0x876: 0x0b37, 0x877: 0x0b3f, 0x878: 0x0b43, 0x879: 0x0b4b, 0x87a: 0x0b53, 0x87b: 0x0b63, + 0x87c: 0x0b7f, 0x87d: 0x0bf7, 0x87e: 0x0c0b, 0x87f: 0x0c0f, + // Block 0x22, offset 0x880 + 0x880: 0x0c8f, 0x881: 0x0c93, 0x882: 0x0ca7, 0x883: 0x0cab, 0x884: 0x0cb3, 0x885: 0x0cbb, + 0x886: 0x0cc3, 0x887: 0x0ccf, 0x888: 0x0cf7, 0x889: 0x0d07, 0x88a: 0x0d1b, 0x88b: 0x0d8b, + 0x88c: 0x0d97, 0x88d: 0x0da7, 0x88e: 0x0db3, 0x88f: 0x0dbf, 0x890: 0x0dc7, 0x891: 0x0dcb, + 0x892: 0x0dcf, 0x893: 0x0dd3, 0x894: 0x0dd7, 0x895: 0x0e8f, 0x896: 0x0ed7, 0x897: 0x0ee3, + 0x898: 0x0ee7, 0x899: 0x0eeb, 0x89a: 0x0eef, 0x89b: 0x0ef7, 0x89c: 0x0efb, 0x89d: 0x0f0f, + 0x89e: 0x0f2b, 0x89f: 0x0f33, 0x8a0: 0x0f73, 0x8a1: 0x0f77, 0x8a2: 0x0f7f, 0x8a3: 0x0f83, + 0x8a4: 0x0f8b, 0x8a5: 0x0f8f, 0x8a6: 0x0fb3, 0x8a7: 0x0fb7, 0x8a8: 0x0fd3, 0x8a9: 0x0fd7, + 0x8aa: 0x0fdb, 0x8ab: 0x0fdf, 0x8ac: 0x0ff3, 0x8ad: 0x1017, 0x8ae: 0x101b, 0x8af: 0x101f, + 0x8b0: 0x1043, 0x8b1: 0x1083, 0x8b2: 0x1087, 0x8b3: 0x10a7, 0x8b4: 0x10b7, 0x8b5: 0x10bf, + 0x8b6: 0x10df, 0x8b7: 0x1103, 0x8b8: 0x1147, 0x8b9: 0x114f, 0x8ba: 0x1163, 0x8bb: 0x116f, + 0x8bc: 0x1177, 0x8bd: 0x117f, 0x8be: 0x1183, 0x8bf: 0x1187, + // Block 0x23, offset 0x8c0 + 0x8c0: 0x119f, 0x8c1: 0x11a3, 0x8c2: 0x11bf, 0x8c3: 0x11c7, 0x8c4: 0x11cf, 0x8c5: 0x11d3, + 0x8c6: 0x11df, 0x8c7: 0x11e7, 0x8c8: 0x11eb, 0x8c9: 0x11ef, 0x8ca: 0x11f7, 0x8cb: 0x11fb, + 0x8cc: 0x129b, 0x8cd: 0x12af, 0x8ce: 0x12e3, 0x8cf: 0x12e7, 0x8d0: 0x12ef, 0x8d1: 0x131b, + 0x8d2: 0x1323, 0x8d3: 0x132b, 0x8d4: 0x1333, 0x8d5: 0x136f, 0x8d6: 0x1373, 0x8d7: 0x137b, + 0x8d8: 0x137f, 0x8d9: 0x1383, 0x8da: 0x13af, 0x8db: 0x13b3, 0x8dc: 0x13bb, 0x8dd: 0x13cf, + 0x8de: 0x13d3, 0x8df: 0x13ef, 0x8e0: 0x13f7, 0x8e1: 0x13fb, 0x8e2: 0x141f, 0x8e3: 0x143f, + 0x8e4: 0x1453, 0x8e5: 0x1457, 0x8e6: 0x145f, 0x8e7: 0x148b, 0x8e8: 0x148f, 0x8e9: 0x149f, + 0x8ea: 0x14c3, 0x8eb: 0x14cf, 0x8ec: 0x14df, 0x8ed: 0x14f7, 0x8ee: 0x14ff, 0x8ef: 0x1503, + 0x8f0: 0x1507, 0x8f1: 0x150b, 0x8f2: 0x1517, 0x8f3: 0x151b, 0x8f4: 0x1523, 0x8f5: 0x153f, + 0x8f6: 0x1543, 0x8f7: 0x1547, 0x8f8: 0x155f, 0x8f9: 0x1563, 0x8fa: 0x156b, 0x8fb: 0x157f, + 0x8fc: 0x1583, 0x8fd: 0x1587, 0x8fe: 0x158f, 0x8ff: 0x1593, + // Block 0x24, offset 0x900 + 0x906: 0xa000, 0x90b: 0xa000, + 0x90c: 0x3f08, 0x90d: 0xa000, 0x90e: 0x3f10, 0x90f: 0xa000, 0x910: 0x3f18, 0x911: 0xa000, + 0x912: 0x3f20, 0x913: 0xa000, 0x914: 0x3f28, 0x915: 0xa000, 0x916: 0x3f30, 0x917: 0xa000, + 0x918: 0x3f38, 0x919: 0xa000, 0x91a: 0x3f40, 0x91b: 0xa000, 0x91c: 0x3f48, 0x91d: 0xa000, + 0x91e: 0x3f50, 0x91f: 0xa000, 0x920: 0x3f58, 0x921: 0xa000, 0x922: 0x3f60, + 0x924: 0xa000, 0x925: 0x3f68, 0x926: 0xa000, 0x927: 0x3f70, 0x928: 0xa000, 0x929: 0x3f78, + 0x92f: 0xa000, + 0x930: 0x3f80, 0x931: 0x3f88, 0x932: 0xa000, 0x933: 0x3f90, 0x934: 0x3f98, 0x935: 0xa000, + 0x936: 0x3fa0, 0x937: 0x3fa8, 0x938: 0xa000, 0x939: 0x3fb0, 0x93a: 0x3fb8, 0x93b: 0xa000, + 0x93c: 0x3fc0, 0x93d: 0x3fc8, + // Block 0x25, offset 0x940 + 0x954: 0x3f00, + 0x959: 0x9903, 0x95a: 0x9903, 0x95b: 0x42dc, 0x95c: 0x42e2, 0x95d: 0xa000, + 0x95e: 0x3fd0, 0x95f: 0x26b4, + 0x966: 0xa000, + 0x96b: 0xa000, 0x96c: 0x3fe0, 0x96d: 0xa000, 0x96e: 0x3fe8, 0x96f: 0xa000, + 0x970: 0x3ff0, 0x971: 0xa000, 0x972: 0x3ff8, 0x973: 0xa000, 0x974: 0x4000, 0x975: 0xa000, + 0x976: 0x4008, 0x977: 0xa000, 0x978: 0x4010, 0x979: 0xa000, 0x97a: 0x4018, 0x97b: 0xa000, + 0x97c: 0x4020, 0x97d: 0xa000, 0x97e: 0x4028, 0x97f: 0xa000, + // Block 0x26, offset 0x980 + 0x980: 0x4030, 0x981: 0xa000, 0x982: 0x4038, 0x984: 0xa000, 0x985: 0x4040, + 0x986: 0xa000, 0x987: 0x4048, 0x988: 0xa000, 0x989: 0x4050, + 0x98f: 0xa000, 0x990: 0x4058, 0x991: 0x4060, + 0x992: 0xa000, 0x993: 0x4068, 0x994: 0x4070, 0x995: 0xa000, 0x996: 0x4078, 0x997: 0x4080, + 0x998: 0xa000, 0x999: 0x4088, 0x99a: 0x4090, 0x99b: 0xa000, 0x99c: 0x4098, 0x99d: 0x40a0, + 0x9af: 0xa000, + 0x9b0: 0xa000, 0x9b1: 0xa000, 0x9b2: 0xa000, 0x9b4: 0x3fd8, + 0x9b7: 0x40a8, 0x9b8: 0x40b0, 0x9b9: 0x40b8, 0x9ba: 0x40c0, + 0x9bd: 0xa000, 0x9be: 0x40c8, 0x9bf: 0x26c9, + // Block 0x27, offset 0x9c0 + 0x9c0: 0x0367, 0x9c1: 0x032b, 0x9c2: 0x032f, 0x9c3: 0x0333, 0x9c4: 0x037b, 0x9c5: 0x0337, + 0x9c6: 0x033b, 0x9c7: 0x033f, 0x9c8: 0x0343, 0x9c9: 0x0347, 0x9ca: 0x034b, 0x9cb: 0x034f, + 0x9cc: 0x0353, 0x9cd: 0x0357, 0x9ce: 0x035b, 0x9cf: 0x49bd, 0x9d0: 0x49c3, 0x9d1: 0x49c9, + 0x9d2: 0x49cf, 0x9d3: 0x49d5, 0x9d4: 0x49db, 0x9d5: 0x49e1, 0x9d6: 0x49e7, 0x9d7: 0x49ed, + 0x9d8: 0x49f3, 0x9d9: 0x49f9, 0x9da: 0x49ff, 0x9db: 0x4a05, 0x9dc: 0x4a0b, 0x9dd: 0x4a11, + 0x9de: 0x4a17, 0x9df: 0x4a1d, 0x9e0: 0x4a23, 0x9e1: 0x4a29, 0x9e2: 0x4a2f, 0x9e3: 0x4a35, + 0x9e4: 0x03c3, 0x9e5: 0x035f, 0x9e6: 0x0363, 0x9e7: 0x03e7, 0x9e8: 0x03eb, 0x9e9: 0x03ef, + 0x9ea: 0x03f3, 0x9eb: 0x03f7, 0x9ec: 0x03fb, 0x9ed: 0x03ff, 0x9ee: 0x036b, 0x9ef: 0x0403, + 0x9f0: 0x0407, 0x9f1: 0x036f, 0x9f2: 0x0373, 0x9f3: 0x0377, 0x9f4: 0x037f, 0x9f5: 0x0383, + 0x9f6: 0x0387, 0x9f7: 0x038b, 0x9f8: 0x038f, 0x9f9: 0x0393, 0x9fa: 0x0397, 0x9fb: 0x039b, + 0x9fc: 0x039f, 0x9fd: 0x03a3, 0x9fe: 0x03a7, 0x9ff: 0x03ab, + // Block 0x28, offset 0xa00 + 0xa00: 0x03af, 0xa01: 0x03b3, 0xa02: 0x040b, 0xa03: 0x040f, 0xa04: 0x03b7, 0xa05: 0x03bb, + 0xa06: 0x03bf, 0xa07: 0x03c7, 0xa08: 0x03cb, 0xa09: 0x03cf, 0xa0a: 0x03d3, 0xa0b: 0x03d7, + 0xa0c: 0x03db, 0xa0d: 0x03df, 0xa0e: 0x03e3, + 0xa12: 0x06bf, 0xa13: 0x071b, 0xa14: 0x06cb, 0xa15: 0x097b, 0xa16: 0x06cf, 0xa17: 0x06e7, + 0xa18: 0x06d3, 0xa19: 0x0f93, 0xa1a: 0x0707, 0xa1b: 0x06db, 0xa1c: 0x06c3, 0xa1d: 0x09ff, + 0xa1e: 0x098f, 0xa1f: 0x072f, + // Block 0x29, offset 0xa40 + 0xa40: 0x2054, 0xa41: 0x205a, 0xa42: 0x2060, 0xa43: 0x2066, 0xa44: 0x206c, 0xa45: 0x2072, + 0xa46: 0x2078, 0xa47: 0x207e, 0xa48: 0x2084, 0xa49: 0x208a, 0xa4a: 0x2090, 0xa4b: 0x2096, + 0xa4c: 0x209c, 0xa4d: 0x20a2, 0xa4e: 0x2726, 0xa4f: 0x272f, 0xa50: 0x2738, 0xa51: 0x2741, + 0xa52: 0x274a, 0xa53: 0x2753, 0xa54: 0x275c, 0xa55: 0x2765, 0xa56: 0x276e, 0xa57: 0x2780, + 0xa58: 0x2789, 0xa59: 0x2792, 0xa5a: 0x279b, 0xa5b: 0x27a4, 0xa5c: 0x2777, 0xa5d: 0x2bac, + 0xa5e: 0x2aed, 0xa60: 0x20a8, 0xa61: 0x20c0, 0xa62: 0x20b4, 0xa63: 0x2108, + 0xa64: 0x20c6, 0xa65: 0x20e4, 0xa66: 0x20ae, 0xa67: 0x20de, 0xa68: 0x20ba, 0xa69: 0x20f0, + 0xa6a: 0x2120, 0xa6b: 0x213e, 0xa6c: 0x2138, 0xa6d: 0x212c, 0xa6e: 0x217a, 0xa6f: 0x210e, + 0xa70: 0x211a, 0xa71: 0x2132, 0xa72: 0x2126, 0xa73: 0x2150, 0xa74: 0x20fc, 0xa75: 0x2144, + 0xa76: 0x216e, 0xa77: 0x2156, 0xa78: 0x20ea, 0xa79: 0x20cc, 0xa7a: 0x2102, 0xa7b: 0x2114, + 0xa7c: 0x214a, 0xa7d: 0x20d2, 0xa7e: 0x2174, 0xa7f: 0x20f6, + // Block 0x2a, offset 0xa80 + 0xa80: 0x215c, 0xa81: 0x20d8, 0xa82: 0x2162, 0xa83: 0x2168, 0xa84: 0x092f, 0xa85: 0x0b03, + 0xa86: 0x0ca7, 0xa87: 0x10c7, + 0xa90: 0x1bc4, 0xa91: 0x18a9, + 0xa92: 0x18ac, 0xa93: 0x18af, 0xa94: 0x18b2, 0xa95: 0x18b5, 0xa96: 0x18b8, 0xa97: 0x18bb, + 0xa98: 0x18be, 0xa99: 0x18c1, 0xa9a: 0x18ca, 0xa9b: 0x18cd, 0xa9c: 0x18d0, 0xa9d: 0x18d3, + 0xa9e: 0x18d6, 0xa9f: 0x18d9, 0xaa0: 0x0313, 0xaa1: 0x031b, 0xaa2: 0x031f, 0xaa3: 0x0327, + 0xaa4: 0x032b, 0xaa5: 0x032f, 0xaa6: 0x0337, 0xaa7: 0x033f, 0xaa8: 0x0343, 0xaa9: 0x034b, + 0xaaa: 0x034f, 0xaab: 0x0353, 0xaac: 0x0357, 0xaad: 0x035b, 0xaae: 0x2e18, 0xaaf: 0x2e20, + 0xab0: 0x2e28, 0xab1: 0x2e30, 0xab2: 0x2e38, 0xab3: 0x2e40, 0xab4: 0x2e48, 0xab5: 0x2e50, + 0xab6: 0x2e60, 0xab7: 0x2e68, 0xab8: 0x2e70, 0xab9: 0x2e78, 0xaba: 0x2e80, 0xabb: 0x2e88, + 0xabc: 0x2ed3, 0xabd: 0x2e9b, 0xabe: 0x2e58, + // Block 0x2b, offset 0xac0 + 0xac0: 0x06bf, 0xac1: 0x071b, 0xac2: 0x06cb, 0xac3: 0x097b, 0xac4: 0x071f, 0xac5: 0x07af, + 0xac6: 0x06c7, 0xac7: 0x07ab, 0xac8: 0x070b, 0xac9: 0x0887, 0xaca: 0x0d07, 0xacb: 0x0e8f, + 0xacc: 0x0dd7, 0xacd: 0x0d1b, 0xace: 0x145f, 0xacf: 0x098b, 0xad0: 0x0ccf, 0xad1: 0x0d4b, + 0xad2: 0x0d0b, 0xad3: 0x104b, 0xad4: 0x08fb, 0xad5: 0x0f03, 0xad6: 0x1387, 0xad7: 0x105f, + 0xad8: 0x0843, 0xad9: 0x108f, 0xada: 0x0f9b, 0xadb: 0x0a17, 0xadc: 0x140f, 0xadd: 0x077f, + 0xade: 0x08ab, 0xadf: 0x0df7, 0xae0: 0x1527, 0xae1: 0x0743, 0xae2: 0x07d3, 0xae3: 0x0d9b, + 0xae4: 0x06cf, 0xae5: 0x06e7, 0xae6: 0x06d3, 0xae7: 0x0adb, 0xae8: 0x08ef, 0xae9: 0x087f, + 0xaea: 0x0a57, 0xaeb: 0x0a4b, 0xaec: 0x0feb, 0xaed: 0x073f, 0xaee: 0x139b, 0xaef: 0x089b, + 0xaf0: 0x09f3, 0xaf1: 0x18dc, 0xaf2: 0x18df, 0xaf3: 0x18e2, 0xaf4: 0x18e5, 0xaf5: 0x18ee, + 0xaf6: 0x18f1, 0xaf7: 0x18f4, 0xaf8: 0x18f7, 0xaf9: 0x18fa, 0xafa: 0x18fd, 0xafb: 0x1900, + 0xafc: 0x1903, 0xafd: 0x1906, 0xafe: 0x1909, 0xaff: 0x1912, + // Block 0x2c, offset 0xb00 + 0xb00: 0x1cc6, 0xb01: 0x1cd5, 0xb02: 0x1ce4, 0xb03: 0x1cf3, 0xb04: 0x1d02, 0xb05: 0x1d11, + 0xb06: 0x1d20, 0xb07: 0x1d2f, 0xb08: 0x1d3e, 0xb09: 0x218c, 0xb0a: 0x219e, 0xb0b: 0x21b0, + 0xb0c: 0x1954, 0xb0d: 0x1c04, 0xb0e: 0x19d2, 0xb0f: 0x1ba8, 0xb10: 0x04cb, 0xb11: 0x04d3, + 0xb12: 0x04db, 0xb13: 0x04e3, 0xb14: 0x04eb, 0xb15: 0x04ef, 0xb16: 0x04f3, 0xb17: 0x04f7, + 0xb18: 0x04fb, 0xb19: 0x04ff, 0xb1a: 0x0503, 0xb1b: 0x0507, 0xb1c: 0x050b, 0xb1d: 0x050f, + 0xb1e: 0x0513, 0xb1f: 0x0517, 0xb20: 0x051b, 0xb21: 0x0523, 0xb22: 0x0527, 0xb23: 0x052b, + 0xb24: 0x052f, 0xb25: 0x0533, 0xb26: 0x0537, 0xb27: 0x053b, 0xb28: 0x053f, 0xb29: 0x0543, + 0xb2a: 0x0547, 0xb2b: 0x054b, 0xb2c: 0x054f, 0xb2d: 0x0553, 0xb2e: 0x0557, 0xb2f: 0x055b, + 0xb30: 0x055f, 0xb31: 0x0563, 0xb32: 0x0567, 0xb33: 0x056f, 0xb34: 0x0577, 0xb35: 0x057f, + 0xb36: 0x0583, 0xb37: 0x0587, 0xb38: 0x058b, 0xb39: 0x058f, 0xb3a: 0x0593, 0xb3b: 0x0597, + 0xb3c: 0x059b, 0xb3d: 0x059f, 0xb3e: 0x05a3, + // Block 0x2d, offset 0xb40 + 0xb40: 0x2b0c, 0xb41: 0x29a8, 0xb42: 0x2b1c, 0xb43: 0x2880, 0xb44: 0x2ee4, 0xb45: 0x288a, + 0xb46: 0x2894, 0xb47: 0x2f28, 0xb48: 0x29b5, 0xb49: 0x289e, 0xb4a: 0x28a8, 0xb4b: 0x28b2, + 0xb4c: 0x29dc, 0xb4d: 0x29e9, 0xb4e: 0x29c2, 0xb4f: 0x29cf, 0xb50: 0x2ea9, 0xb51: 0x29f6, + 0xb52: 0x2a03, 0xb53: 0x2bbe, 0xb54: 0x26bb, 0xb55: 0x2bd1, 0xb56: 0x2be4, 0xb57: 0x2b2c, + 0xb58: 0x2a10, 0xb59: 0x2bf7, 0xb5a: 0x2c0a, 0xb5b: 0x2a1d, 0xb5c: 0x28bc, 0xb5d: 0x28c6, + 0xb5e: 0x2eb7, 0xb5f: 0x2a2a, 0xb60: 0x2b3c, 0xb61: 0x2ef5, 0xb62: 0x28d0, 0xb63: 0x28da, + 0xb64: 0x2a37, 0xb65: 0x28e4, 0xb66: 0x28ee, 0xb67: 0x26d0, 0xb68: 0x26d7, 0xb69: 0x28f8, + 0xb6a: 0x2902, 0xb6b: 0x2c1d, 0xb6c: 0x2a44, 0xb6d: 0x2b4c, 0xb6e: 0x2c30, 0xb6f: 0x2a51, + 0xb70: 0x2916, 0xb71: 0x290c, 0xb72: 0x2f3c, 0xb73: 0x2a5e, 0xb74: 0x2c43, 0xb75: 0x2920, + 0xb76: 0x2b5c, 0xb77: 0x292a, 0xb78: 0x2a78, 0xb79: 0x2934, 0xb7a: 0x2a85, 0xb7b: 0x2f06, + 0xb7c: 0x2a6b, 0xb7d: 0x2b6c, 0xb7e: 0x2a92, 0xb7f: 0x26de, + // Block 0x2e, offset 0xb80 + 0xb80: 0x2f17, 0xb81: 0x293e, 0xb82: 0x2948, 0xb83: 0x2a9f, 0xb84: 0x2952, 0xb85: 0x295c, + 0xb86: 0x2966, 0xb87: 0x2b7c, 0xb88: 0x2aac, 0xb89: 0x26e5, 0xb8a: 0x2c56, 0xb8b: 0x2e90, + 0xb8c: 0x2b8c, 0xb8d: 0x2ab9, 0xb8e: 0x2ec5, 0xb8f: 0x2970, 0xb90: 0x297a, 0xb91: 0x2ac6, + 0xb92: 0x26ec, 0xb93: 0x2ad3, 0xb94: 0x2b9c, 0xb95: 0x26f3, 0xb96: 0x2c69, 0xb97: 0x2984, + 0xb98: 0x1cb7, 0xb99: 0x1ccb, 0xb9a: 0x1cda, 0xb9b: 0x1ce9, 0xb9c: 0x1cf8, 0xb9d: 0x1d07, + 0xb9e: 0x1d16, 0xb9f: 0x1d25, 0xba0: 0x1d34, 0xba1: 0x1d43, 0xba2: 0x2192, 0xba3: 0x21a4, + 0xba4: 0x21b6, 0xba5: 0x21c2, 0xba6: 0x21ce, 0xba7: 0x21da, 0xba8: 0x21e6, 0xba9: 0x21f2, + 0xbaa: 0x21fe, 0xbab: 0x220a, 0xbac: 0x2246, 0xbad: 0x2252, 0xbae: 0x225e, 0xbaf: 0x226a, + 0xbb0: 0x2276, 0xbb1: 0x1c14, 0xbb2: 0x19c6, 0xbb3: 0x1936, 0xbb4: 0x1be4, 0xbb5: 0x1a47, + 0xbb6: 0x1a56, 0xbb7: 0x19cc, 0xbb8: 0x1bfc, 0xbb9: 0x1c00, 0xbba: 0x1960, 0xbbb: 0x2701, + 0xbbc: 0x270f, 0xbbd: 0x26fa, 0xbbe: 0x2708, 0xbbf: 0x2ae0, + // Block 0x2f, offset 0xbc0 + 0xbc0: 0x1a4a, 0xbc1: 0x1a32, 0xbc2: 0x1c60, 0xbc3: 0x1a1a, 0xbc4: 0x19f3, 0xbc5: 0x1969, + 0xbc6: 0x1978, 0xbc7: 0x1948, 0xbc8: 0x1bf0, 0xbc9: 0x1d52, 0xbca: 0x1a4d, 0xbcb: 0x1a35, + 0xbcc: 0x1c64, 0xbcd: 0x1c70, 0xbce: 0x1a26, 0xbcf: 0x19fc, 0xbd0: 0x1957, 0xbd1: 0x1c1c, + 0xbd2: 0x1bb0, 0xbd3: 0x1b9c, 0xbd4: 0x1bcc, 0xbd5: 0x1c74, 0xbd6: 0x1a29, 0xbd7: 0x19c9, + 0xbd8: 0x19ff, 0xbd9: 0x19de, 0xbda: 0x1a41, 0xbdb: 0x1c78, 0xbdc: 0x1a2c, 0xbdd: 0x19c0, + 0xbde: 0x1a02, 0xbdf: 0x1c3c, 0xbe0: 0x1bf4, 0xbe1: 0x1a14, 0xbe2: 0x1c24, 0xbe3: 0x1c40, + 0xbe4: 0x1bf8, 0xbe5: 0x1a17, 0xbe6: 0x1c28, 0xbe7: 0x22e8, 0xbe8: 0x22fc, 0xbe9: 0x1996, + 0xbea: 0x1c20, 0xbeb: 0x1bb4, 0xbec: 0x1ba0, 0xbed: 0x1c48, 0xbee: 0x2716, 0xbef: 0x27ad, + 0xbf0: 0x1a59, 0xbf1: 0x1a44, 0xbf2: 0x1c7c, 0xbf3: 0x1a2f, 0xbf4: 0x1a50, 0xbf5: 0x1a38, + 0xbf6: 0x1c68, 0xbf7: 0x1a1d, 0xbf8: 0x19f6, 0xbf9: 0x1981, 0xbfa: 0x1a53, 0xbfb: 0x1a3b, + 0xbfc: 0x1c6c, 0xbfd: 0x1a20, 0xbfe: 0x19f9, 0xbff: 0x1984, + // Block 0x30, offset 0xc00 + 0xc00: 0x1c2c, 0xc01: 0x1bb8, 0xc02: 0x1d4d, 0xc03: 0x1939, 0xc04: 0x19ba, 0xc05: 0x19bd, + 0xc06: 0x22f5, 0xc07: 0x1b94, 0xc08: 0x19c3, 0xc09: 0x194b, 0xc0a: 0x19e1, 0xc0b: 0x194e, + 0xc0c: 0x19ea, 0xc0d: 0x196c, 0xc0e: 0x196f, 0xc0f: 0x1a05, 0xc10: 0x1a0b, 0xc11: 0x1a0e, + 0xc12: 0x1c30, 0xc13: 0x1a11, 0xc14: 0x1a23, 0xc15: 0x1c38, 0xc16: 0x1c44, 0xc17: 0x1990, + 0xc18: 0x1d57, 0xc19: 0x1bbc, 0xc1a: 0x1993, 0xc1b: 0x1a5c, 0xc1c: 0x19a5, 0xc1d: 0x19b4, + 0xc1e: 0x22e2, 0xc1f: 0x22dc, 0xc20: 0x1cc1, 0xc21: 0x1cd0, 0xc22: 0x1cdf, 0xc23: 0x1cee, + 0xc24: 0x1cfd, 0xc25: 0x1d0c, 0xc26: 0x1d1b, 0xc27: 0x1d2a, 0xc28: 0x1d39, 0xc29: 0x2186, + 0xc2a: 0x2198, 0xc2b: 0x21aa, 0xc2c: 0x21bc, 0xc2d: 0x21c8, 0xc2e: 0x21d4, 0xc2f: 0x21e0, + 0xc30: 0x21ec, 0xc31: 0x21f8, 0xc32: 0x2204, 0xc33: 0x2240, 0xc34: 0x224c, 0xc35: 0x2258, + 0xc36: 0x2264, 0xc37: 0x2270, 0xc38: 0x227c, 0xc39: 0x2282, 0xc3a: 0x2288, 0xc3b: 0x228e, + 0xc3c: 0x2294, 0xc3d: 0x22a6, 0xc3e: 0x22ac, 0xc3f: 0x1c10, + // Block 0x31, offset 0xc40 + 0xc40: 0x1377, 0xc41: 0x0cfb, 0xc42: 0x13d3, 0xc43: 0x139f, 0xc44: 0x0e57, 0xc45: 0x06eb, + 0xc46: 0x08df, 0xc47: 0x162b, 0xc48: 0x162b, 0xc49: 0x0a0b, 0xc4a: 0x145f, 0xc4b: 0x0943, + 0xc4c: 0x0a07, 0xc4d: 0x0bef, 0xc4e: 0x0fcf, 0xc4f: 0x115f, 0xc50: 0x1297, 0xc51: 0x12d3, + 0xc52: 0x1307, 0xc53: 0x141b, 0xc54: 0x0d73, 0xc55: 0x0dff, 0xc56: 0x0eab, 0xc57: 0x0f43, + 0xc58: 0x125f, 0xc59: 0x1447, 0xc5a: 0x1573, 0xc5b: 0x070f, 0xc5c: 0x08b3, 0xc5d: 0x0d87, + 0xc5e: 0x0ecf, 0xc5f: 0x1293, 0xc60: 0x15c3, 0xc61: 0x0ab3, 0xc62: 0x0e77, 0xc63: 0x1283, + 0xc64: 0x1317, 0xc65: 0x0c23, 0xc66: 0x11bb, 0xc67: 0x12df, 0xc68: 0x0b1f, 0xc69: 0x0d0f, + 0xc6a: 0x0e17, 0xc6b: 0x0f1b, 0xc6c: 0x1427, 0xc6d: 0x074f, 0xc6e: 0x07e7, 0xc6f: 0x0853, + 0xc70: 0x0c8b, 0xc71: 0x0d7f, 0xc72: 0x0ecb, 0xc73: 0x0fef, 0xc74: 0x1177, 0xc75: 0x128b, + 0xc76: 0x12a3, 0xc77: 0x13c7, 0xc78: 0x14ef, 0xc79: 0x15a3, 0xc7a: 0x15bf, 0xc7b: 0x102b, + 0xc7c: 0x106b, 0xc7d: 0x1123, 0xc7e: 0x1243, 0xc7f: 0x147b, + // Block 0x32, offset 0xc80 + 0xc80: 0x15cb, 0xc81: 0x134b, 0xc82: 0x09c7, 0xc83: 0x0b3b, 0xc84: 0x10db, 0xc85: 0x119b, + 0xc86: 0x0eff, 0xc87: 0x1033, 0xc88: 0x1397, 0xc89: 0x14e7, 0xc8a: 0x09c3, 0xc8b: 0x0a8f, + 0xc8c: 0x0d77, 0xc8d: 0x0e2b, 0xc8e: 0x0e5f, 0xc8f: 0x1113, 0xc90: 0x113b, 0xc91: 0x14a7, + 0xc92: 0x084f, 0xc93: 0x11a7, 0xc94: 0x07f3, 0xc95: 0x07ef, 0xc96: 0x1097, 0xc97: 0x1127, + 0xc98: 0x125b, 0xc99: 0x14af, 0xc9a: 0x1367, 0xc9b: 0x0c27, 0xc9c: 0x0d73, 0xc9d: 0x1357, + 0xc9e: 0x06f7, 0xc9f: 0x0a63, 0xca0: 0x0b93, 0xca1: 0x0f2f, 0xca2: 0x0faf, 0xca3: 0x0873, + 0xca4: 0x103b, 0xca5: 0x075f, 0xca6: 0x0b77, 0xca7: 0x06d7, 0xca8: 0x0deb, 0xca9: 0x0ca3, + 0xcaa: 0x110f, 0xcab: 0x08c7, 0xcac: 0x09b3, 0xcad: 0x0ffb, 0xcae: 0x1263, 0xcaf: 0x133b, + 0xcb0: 0x0db7, 0xcb1: 0x13f7, 0xcb2: 0x0de3, 0xcb3: 0x0c37, 0xcb4: 0x121b, 0xcb5: 0x0c57, + 0xcb6: 0x0fab, 0xcb7: 0x072b, 0xcb8: 0x07a7, 0xcb9: 0x07eb, 0xcba: 0x0d53, 0xcbb: 0x10fb, + 0xcbc: 0x11f3, 0xcbd: 0x1347, 0xcbe: 0x145b, 0xcbf: 0x085b, + // Block 0x33, offset 0xcc0 + 0xcc0: 0x090f, 0xcc1: 0x0a17, 0xcc2: 0x0b2f, 0xcc3: 0x0cbf, 0xcc4: 0x0e7b, 0xcc5: 0x103f, + 0xcc6: 0x1497, 0xcc7: 0x157b, 0xcc8: 0x15cf, 0xcc9: 0x15e7, 0xcca: 0x0837, 0xccb: 0x0cf3, + 0xccc: 0x0da3, 0xccd: 0x13eb, 0xcce: 0x0afb, 0xccf: 0x0bd7, 0xcd0: 0x0bf3, 0xcd1: 0x0c83, + 0xcd2: 0x0e6b, 0xcd3: 0x0eb7, 0xcd4: 0x0f67, 0xcd5: 0x108b, 0xcd6: 0x112f, 0xcd7: 0x1193, + 0xcd8: 0x13db, 0xcd9: 0x126b, 0xcda: 0x1403, 0xcdb: 0x147f, 0xcdc: 0x080f, 0xcdd: 0x083b, + 0xcde: 0x0923, 0xcdf: 0x0ea7, 0xce0: 0x12f3, 0xce1: 0x133b, 0xce2: 0x0b1b, 0xce3: 0x0b8b, + 0xce4: 0x0c4f, 0xce5: 0x0daf, 0xce6: 0x10d7, 0xce7: 0x0f23, 0xce8: 0x073b, 0xce9: 0x097f, + 0xcea: 0x0a63, 0xceb: 0x0ac7, 0xcec: 0x0b97, 0xced: 0x0f3f, 0xcee: 0x0f5b, 0xcef: 0x116b, + 0xcf0: 0x118b, 0xcf1: 0x1463, 0xcf2: 0x14e3, 0xcf3: 0x14f3, 0xcf4: 0x152f, 0xcf5: 0x0753, + 0xcf6: 0x107f, 0xcf7: 0x144f, 0xcf8: 0x14cb, 0xcf9: 0x0baf, 0xcfa: 0x0717, 0xcfb: 0x0777, + 0xcfc: 0x0a67, 0xcfd: 0x0a87, 0xcfe: 0x0caf, 0xcff: 0x0d73, + // Block 0x34, offset 0xd00 + 0xd00: 0x0ec3, 0xd01: 0x0fcb, 0xd02: 0x1277, 0xd03: 0x1417, 0xd04: 0x1623, 0xd05: 0x0ce3, + 0xd06: 0x14a3, 0xd07: 0x0833, 0xd08: 0x0d2f, 0xd09: 0x0d3b, 0xd0a: 0x0e0f, 0xd0b: 0x0e47, + 0xd0c: 0x0f4b, 0xd0d: 0x0fa7, 0xd0e: 0x1027, 0xd0f: 0x110b, 0xd10: 0x153b, 0xd11: 0x07af, + 0xd12: 0x0c03, 0xd13: 0x14b3, 0xd14: 0x0767, 0xd15: 0x0aab, 0xd16: 0x0e2f, 0xd17: 0x13df, + 0xd18: 0x0b67, 0xd19: 0x0bb7, 0xd1a: 0x0d43, 0xd1b: 0x0f2f, 0xd1c: 0x14bb, 0xd1d: 0x0817, + 0xd1e: 0x08ff, 0xd1f: 0x0a97, 0xd20: 0x0cd3, 0xd21: 0x0d1f, 0xd22: 0x0d5f, 0xd23: 0x0df3, + 0xd24: 0x0f47, 0xd25: 0x0fbb, 0xd26: 0x1157, 0xd27: 0x12f7, 0xd28: 0x1303, 0xd29: 0x1457, + 0xd2a: 0x14d7, 0xd2b: 0x0883, 0xd2c: 0x0e4b, 0xd2d: 0x0903, 0xd2e: 0x0ec7, 0xd2f: 0x0f6b, + 0xd30: 0x1287, 0xd31: 0x14bf, 0xd32: 0x15ab, 0xd33: 0x15d3, 0xd34: 0x0d37, 0xd35: 0x0e27, + 0xd36: 0x11c3, 0xd37: 0x10b7, 0xd38: 0x10c3, 0xd39: 0x10e7, 0xd3a: 0x0f17, 0xd3b: 0x0e9f, + 0xd3c: 0x1363, 0xd3d: 0x0733, 0xd3e: 0x122b, 0xd3f: 0x081b, + // Block 0x35, offset 0xd40 + 0xd40: 0x080b, 0xd41: 0x0b0b, 0xd42: 0x0c2b, 0xd43: 0x10f3, 0xd44: 0x0a53, 0xd45: 0x0e03, + 0xd46: 0x0cef, 0xd47: 0x13e7, 0xd48: 0x12e7, 0xd49: 0x14ab, 0xd4a: 0x1323, 0xd4b: 0x0b27, + 0xd4c: 0x0787, 0xd4d: 0x095b, 0xd50: 0x09af, + 0xd52: 0x0cdf, 0xd55: 0x07f7, 0xd56: 0x0f1f, 0xd57: 0x0fe3, + 0xd58: 0x1047, 0xd59: 0x1063, 0xd5a: 0x1067, 0xd5b: 0x107b, 0xd5c: 0x14fb, 0xd5d: 0x10eb, + 0xd5e: 0x116f, 0xd60: 0x128f, 0xd62: 0x1353, + 0xd65: 0x1407, 0xd66: 0x1433, + 0xd6a: 0x154f, 0xd6b: 0x1553, 0xd6c: 0x1557, 0xd6d: 0x15bb, 0xd6e: 0x142b, 0xd6f: 0x14c7, + 0xd70: 0x0757, 0xd71: 0x077b, 0xd72: 0x078f, 0xd73: 0x084b, 0xd74: 0x0857, 0xd75: 0x0897, + 0xd76: 0x094b, 0xd77: 0x0967, 0xd78: 0x096f, 0xd79: 0x09ab, 0xd7a: 0x09b7, 0xd7b: 0x0a93, + 0xd7c: 0x0a9b, 0xd7d: 0x0ba3, 0xd7e: 0x0bcb, 0xd7f: 0x0bd3, + // Block 0x36, offset 0xd80 + 0xd80: 0x0beb, 0xd81: 0x0c97, 0xd82: 0x0cc7, 0xd83: 0x0ce7, 0xd84: 0x0d57, 0xd85: 0x0e1b, + 0xd86: 0x0e37, 0xd87: 0x0e67, 0xd88: 0x0ebb, 0xd89: 0x0edb, 0xd8a: 0x0f4f, 0xd8b: 0x102f, + 0xd8c: 0x104b, 0xd8d: 0x1053, 0xd8e: 0x104f, 0xd8f: 0x1057, 0xd90: 0x105b, 0xd91: 0x105f, + 0xd92: 0x1073, 0xd93: 0x1077, 0xd94: 0x109b, 0xd95: 0x10af, 0xd96: 0x10cb, 0xd97: 0x112f, + 0xd98: 0x1137, 0xd99: 0x113f, 0xd9a: 0x1153, 0xd9b: 0x117b, 0xd9c: 0x11cb, 0xd9d: 0x11ff, + 0xd9e: 0x11ff, 0xd9f: 0x1267, 0xda0: 0x130f, 0xda1: 0x1327, 0xda2: 0x135b, 0xda3: 0x135f, + 0xda4: 0x13a3, 0xda5: 0x13a7, 0xda6: 0x13ff, 0xda7: 0x1407, 0xda8: 0x14db, 0xda9: 0x151f, + 0xdaa: 0x1537, 0xdab: 0x0b9b, 0xdac: 0x171e, 0xdad: 0x11e3, + 0xdb0: 0x06df, 0xdb1: 0x07e3, 0xdb2: 0x07a3, 0xdb3: 0x074b, 0xdb4: 0x078b, 0xdb5: 0x07b7, + 0xdb6: 0x0847, 0xdb7: 0x0863, 0xdb8: 0x094b, 0xdb9: 0x0937, 0xdba: 0x0947, 0xdbb: 0x0963, + 0xdbc: 0x09af, 0xdbd: 0x09bf, 0xdbe: 0x0a03, 0xdbf: 0x0a0f, + // Block 0x37, offset 0xdc0 + 0xdc0: 0x0a2b, 0xdc1: 0x0a3b, 0xdc2: 0x0b23, 0xdc3: 0x0b2b, 0xdc4: 0x0b5b, 0xdc5: 0x0b7b, + 0xdc6: 0x0bab, 0xdc7: 0x0bc3, 0xdc8: 0x0bb3, 0xdc9: 0x0bd3, 0xdca: 0x0bc7, 0xdcb: 0x0beb, + 0xdcc: 0x0c07, 0xdcd: 0x0c5f, 0xdce: 0x0c6b, 0xdcf: 0x0c73, 0xdd0: 0x0c9b, 0xdd1: 0x0cdf, + 0xdd2: 0x0d0f, 0xdd3: 0x0d13, 0xdd4: 0x0d27, 0xdd5: 0x0da7, 0xdd6: 0x0db7, 0xdd7: 0x0e0f, + 0xdd8: 0x0e5b, 0xdd9: 0x0e53, 0xdda: 0x0e67, 0xddb: 0x0e83, 0xddc: 0x0ebb, 0xddd: 0x1013, + 0xdde: 0x0edf, 0xddf: 0x0f13, 0xde0: 0x0f1f, 0xde1: 0x0f5f, 0xde2: 0x0f7b, 0xde3: 0x0f9f, + 0xde4: 0x0fc3, 0xde5: 0x0fc7, 0xde6: 0x0fe3, 0xde7: 0x0fe7, 0xde8: 0x0ff7, 0xde9: 0x100b, + 0xdea: 0x1007, 0xdeb: 0x1037, 0xdec: 0x10b3, 0xded: 0x10cb, 0xdee: 0x10e3, 0xdef: 0x111b, + 0xdf0: 0x112f, 0xdf1: 0x114b, 0xdf2: 0x117b, 0xdf3: 0x122f, 0xdf4: 0x1257, 0xdf5: 0x12cb, + 0xdf6: 0x1313, 0xdf7: 0x131f, 0xdf8: 0x1327, 0xdf9: 0x133f, 0xdfa: 0x1353, 0xdfb: 0x1343, + 0xdfc: 0x135b, 0xdfd: 0x1357, 0xdfe: 0x134f, 0xdff: 0x135f, + // Block 0x38, offset 0xe00 + 0xe00: 0x136b, 0xe01: 0x13a7, 0xe02: 0x13e3, 0xe03: 0x1413, 0xe04: 0x144b, 0xe05: 0x146b, + 0xe06: 0x14b7, 0xe07: 0x14db, 0xe08: 0x14fb, 0xe09: 0x150f, 0xe0a: 0x151f, 0xe0b: 0x152b, + 0xe0c: 0x1537, 0xe0d: 0x158b, 0xe0e: 0x162b, 0xe0f: 0x16b5, 0xe10: 0x16b0, 0xe11: 0x16e2, + 0xe12: 0x0607, 0xe13: 0x062f, 0xe14: 0x0633, 0xe15: 0x1764, 0xe16: 0x1791, 0xe17: 0x1809, + 0xe18: 0x1617, 0xe19: 0x1627, + // Block 0x39, offset 0xe40 + 0xe40: 0x19d5, 0xe41: 0x19d8, 0xe42: 0x19db, 0xe43: 0x1c08, 0xe44: 0x1c0c, 0xe45: 0x1a5f, + 0xe46: 0x1a5f, + 0xe53: 0x1d75, 0xe54: 0x1d66, 0xe55: 0x1d6b, 0xe56: 0x1d7a, 0xe57: 0x1d70, + 0xe5d: 0x4390, + 0xe5e: 0x8115, 0xe5f: 0x4402, 0xe60: 0x022d, 0xe61: 0x0215, 0xe62: 0x021e, 0xe63: 0x0221, + 0xe64: 0x0224, 0xe65: 0x0227, 0xe66: 0x022a, 0xe67: 0x0230, 0xe68: 0x0233, 0xe69: 0x0017, + 0xe6a: 0x43f0, 0xe6b: 0x43f6, 0xe6c: 0x44f4, 0xe6d: 0x44fc, 0xe6e: 0x4348, 0xe6f: 0x434e, + 0xe70: 0x4354, 0xe71: 0x435a, 0xe72: 0x4366, 0xe73: 0x436c, 0xe74: 0x4372, 0xe75: 0x437e, + 0xe76: 0x4384, 0xe78: 0x438a, 0xe79: 0x4396, 0xe7a: 0x439c, 0xe7b: 0x43a2, + 0xe7c: 0x43ae, 0xe7e: 0x43b4, + // Block 0x3a, offset 0xe80 + 0xe80: 0x43ba, 0xe81: 0x43c0, 0xe83: 0x43c6, 0xe84: 0x43cc, + 0xe86: 0x43d8, 0xe87: 0x43de, 0xe88: 0x43e4, 0xe89: 0x43ea, 0xe8a: 0x43fc, 0xe8b: 0x4378, + 0xe8c: 0x4360, 0xe8d: 0x43a8, 0xe8e: 0x43d2, 0xe8f: 0x1d7f, 0xe90: 0x0299, 0xe91: 0x0299, + 0xe92: 0x02a2, 0xe93: 0x02a2, 0xe94: 0x02a2, 0xe95: 0x02a2, 0xe96: 0x02a5, 0xe97: 0x02a5, + 0xe98: 0x02a5, 0xe99: 0x02a5, 0xe9a: 0x02ab, 0xe9b: 0x02ab, 0xe9c: 0x02ab, 0xe9d: 0x02ab, + 0xe9e: 0x029f, 0xe9f: 0x029f, 0xea0: 0x029f, 0xea1: 0x029f, 0xea2: 0x02a8, 0xea3: 0x02a8, + 0xea4: 0x02a8, 0xea5: 0x02a8, 0xea6: 0x029c, 0xea7: 0x029c, 0xea8: 0x029c, 0xea9: 0x029c, + 0xeaa: 0x02cf, 0xeab: 0x02cf, 0xeac: 0x02cf, 0xead: 0x02cf, 0xeae: 0x02d2, 0xeaf: 0x02d2, + 0xeb0: 0x02d2, 0xeb1: 0x02d2, 0xeb2: 0x02b1, 0xeb3: 0x02b1, 0xeb4: 0x02b1, 0xeb5: 0x02b1, + 0xeb6: 0x02ae, 0xeb7: 0x02ae, 0xeb8: 0x02ae, 0xeb9: 0x02ae, 0xeba: 0x02b4, 0xebb: 0x02b4, + 0xebc: 0x02b4, 0xebd: 0x02b4, 0xebe: 0x02b7, 0xebf: 0x02b7, + // Block 0x3b, offset 0xec0 + 0xec0: 0x02b7, 0xec1: 0x02b7, 0xec2: 0x02c0, 0xec3: 0x02c0, 0xec4: 0x02bd, 0xec5: 0x02bd, + 0xec6: 0x02c3, 0xec7: 0x02c3, 0xec8: 0x02ba, 0xec9: 0x02ba, 0xeca: 0x02c9, 0xecb: 0x02c9, + 0xecc: 0x02c6, 0xecd: 0x02c6, 0xece: 0x02d5, 0xecf: 0x02d5, 0xed0: 0x02d5, 0xed1: 0x02d5, + 0xed2: 0x02db, 0xed3: 0x02db, 0xed4: 0x02db, 0xed5: 0x02db, 0xed6: 0x02e1, 0xed7: 0x02e1, + 0xed8: 0x02e1, 0xed9: 0x02e1, 0xeda: 0x02de, 0xedb: 0x02de, 0xedc: 0x02de, 0xedd: 0x02de, + 0xede: 0x02e4, 0xedf: 0x02e4, 0xee0: 0x02e7, 0xee1: 0x02e7, 0xee2: 0x02e7, 0xee3: 0x02e7, + 0xee4: 0x446e, 0xee5: 0x446e, 0xee6: 0x02ed, 0xee7: 0x02ed, 0xee8: 0x02ed, 0xee9: 0x02ed, + 0xeea: 0x02ea, 0xeeb: 0x02ea, 0xeec: 0x02ea, 0xeed: 0x02ea, 0xeee: 0x0308, 0xeef: 0x0308, + 0xef0: 0x4468, 0xef1: 0x4468, + // Block 0x3c, offset 0xf00 + 0xf13: 0x02d8, 0xf14: 0x02d8, 0xf15: 0x02d8, 0xf16: 0x02d8, 0xf17: 0x02f6, + 0xf18: 0x02f6, 0xf19: 0x02f3, 0xf1a: 0x02f3, 0xf1b: 0x02f9, 0xf1c: 0x02f9, 0xf1d: 0x204f, + 0xf1e: 0x02ff, 0xf1f: 0x02ff, 0xf20: 0x02f0, 0xf21: 0x02f0, 0xf22: 0x02fc, 0xf23: 0x02fc, + 0xf24: 0x0305, 0xf25: 0x0305, 0xf26: 0x0305, 0xf27: 0x0305, 0xf28: 0x028d, 0xf29: 0x028d, + 0xf2a: 0x25aa, 0xf2b: 0x25aa, 0xf2c: 0x261a, 0xf2d: 0x261a, 0xf2e: 0x25e9, 0xf2f: 0x25e9, + 0xf30: 0x2605, 0xf31: 0x2605, 0xf32: 0x25fe, 0xf33: 0x25fe, 0xf34: 0x260c, 0xf35: 0x260c, + 0xf36: 0x2613, 0xf37: 0x2613, 0xf38: 0x2613, 0xf39: 0x25f0, 0xf3a: 0x25f0, 0xf3b: 0x25f0, + 0xf3c: 0x0302, 0xf3d: 0x0302, 0xf3e: 0x0302, 0xf3f: 0x0302, + // Block 0x3d, offset 0xf40 + 0xf40: 0x25b1, 0xf41: 0x25b8, 0xf42: 0x25d4, 0xf43: 0x25f0, 0xf44: 0x25f7, 0xf45: 0x1d89, + 0xf46: 0x1d8e, 0xf47: 0x1d93, 0xf48: 0x1da2, 0xf49: 0x1db1, 0xf4a: 0x1db6, 0xf4b: 0x1dbb, + 0xf4c: 0x1dc0, 0xf4d: 0x1dc5, 0xf4e: 0x1dd4, 0xf4f: 0x1de3, 0xf50: 0x1de8, 0xf51: 0x1ded, + 0xf52: 0x1dfc, 0xf53: 0x1e0b, 0xf54: 0x1e10, 0xf55: 0x1e15, 0xf56: 0x1e1a, 0xf57: 0x1e29, + 0xf58: 0x1e2e, 0xf59: 0x1e3d, 0xf5a: 0x1e42, 0xf5b: 0x1e47, 0xf5c: 0x1e56, 0xf5d: 0x1e5b, + 0xf5e: 0x1e60, 0xf5f: 0x1e6a, 0xf60: 0x1ea6, 0xf61: 0x1eb5, 0xf62: 0x1ec4, 0xf63: 0x1ec9, + 0xf64: 0x1ece, 0xf65: 0x1ed8, 0xf66: 0x1ee7, 0xf67: 0x1eec, 0xf68: 0x1efb, 0xf69: 0x1f00, + 0xf6a: 0x1f05, 0xf6b: 0x1f14, 0xf6c: 0x1f19, 0xf6d: 0x1f28, 0xf6e: 0x1f2d, 0xf6f: 0x1f32, + 0xf70: 0x1f37, 0xf71: 0x1f3c, 0xf72: 0x1f41, 0xf73: 0x1f46, 0xf74: 0x1f4b, 0xf75: 0x1f50, + 0xf76: 0x1f55, 0xf77: 0x1f5a, 0xf78: 0x1f5f, 0xf79: 0x1f64, 0xf7a: 0x1f69, 0xf7b: 0x1f6e, + 0xf7c: 0x1f73, 0xf7d: 0x1f78, 0xf7e: 0x1f7d, 0xf7f: 0x1f87, + // Block 0x3e, offset 0xf80 + 0xf80: 0x1f8c, 0xf81: 0x1f91, 0xf82: 0x1f96, 0xf83: 0x1fa0, 0xf84: 0x1fa5, 0xf85: 0x1faf, + 0xf86: 0x1fb4, 0xf87: 0x1fb9, 0xf88: 0x1fbe, 0xf89: 0x1fc3, 0xf8a: 0x1fc8, 0xf8b: 0x1fcd, + 0xf8c: 0x1fd2, 0xf8d: 0x1fd7, 0xf8e: 0x1fe6, 0xf8f: 0x1ff5, 0xf90: 0x1ffa, 0xf91: 0x1fff, + 0xf92: 0x2004, 0xf93: 0x2009, 0xf94: 0x200e, 0xf95: 0x2018, 0xf96: 0x201d, 0xf97: 0x2022, + 0xf98: 0x2031, 0xf99: 0x2040, 0xf9a: 0x2045, 0xf9b: 0x4420, 0xf9c: 0x4426, 0xf9d: 0x445c, + 0xf9e: 0x44b3, 0xf9f: 0x44ba, 0xfa0: 0x44c1, 0xfa1: 0x44c8, 0xfa2: 0x44cf, 0xfa3: 0x44d6, + 0xfa4: 0x25c6, 0xfa5: 0x25cd, 0xfa6: 0x25d4, 0xfa7: 0x25db, 0xfa8: 0x25f0, 0xfa9: 0x25f7, + 0xfaa: 0x1d98, 0xfab: 0x1d9d, 0xfac: 0x1da2, 0xfad: 0x1da7, 0xfae: 0x1db1, 0xfaf: 0x1db6, + 0xfb0: 0x1dca, 0xfb1: 0x1dcf, 0xfb2: 0x1dd4, 0xfb3: 0x1dd9, 0xfb4: 0x1de3, 0xfb5: 0x1de8, + 0xfb6: 0x1df2, 0xfb7: 0x1df7, 0xfb8: 0x1dfc, 0xfb9: 0x1e01, 0xfba: 0x1e0b, 0xfbb: 0x1e10, + 0xfbc: 0x1f3c, 0xfbd: 0x1f41, 0xfbe: 0x1f50, 0xfbf: 0x1f55, + // Block 0x3f, offset 0xfc0 + 0xfc0: 0x1f5a, 0xfc1: 0x1f6e, 0xfc2: 0x1f73, 0xfc3: 0x1f78, 0xfc4: 0x1f7d, 0xfc5: 0x1f96, + 0xfc6: 0x1fa0, 0xfc7: 0x1fa5, 0xfc8: 0x1faa, 0xfc9: 0x1fbe, 0xfca: 0x1fdc, 0xfcb: 0x1fe1, + 0xfcc: 0x1fe6, 0xfcd: 0x1feb, 0xfce: 0x1ff5, 0xfcf: 0x1ffa, 0xfd0: 0x445c, 0xfd1: 0x2027, + 0xfd2: 0x202c, 0xfd3: 0x2031, 0xfd4: 0x2036, 0xfd5: 0x2040, 0xfd6: 0x2045, 0xfd7: 0x25b1, + 0xfd8: 0x25b8, 0xfd9: 0x25bf, 0xfda: 0x25d4, 0xfdb: 0x25e2, 0xfdc: 0x1d89, 0xfdd: 0x1d8e, + 0xfde: 0x1d93, 0xfdf: 0x1da2, 0xfe0: 0x1dac, 0xfe1: 0x1dbb, 0xfe2: 0x1dc0, 0xfe3: 0x1dc5, + 0xfe4: 0x1dd4, 0xfe5: 0x1dde, 0xfe6: 0x1dfc, 0xfe7: 0x1e15, 0xfe8: 0x1e1a, 0xfe9: 0x1e29, + 0xfea: 0x1e2e, 0xfeb: 0x1e3d, 0xfec: 0x1e47, 0xfed: 0x1e56, 0xfee: 0x1e5b, 0xfef: 0x1e60, + 0xff0: 0x1e6a, 0xff1: 0x1ea6, 0xff2: 0x1eab, 0xff3: 0x1eb5, 0xff4: 0x1ec4, 0xff5: 0x1ec9, + 0xff6: 0x1ece, 0xff7: 0x1ed8, 0xff8: 0x1ee7, 0xff9: 0x1efb, 0xffa: 0x1f00, 0xffb: 0x1f05, + 0xffc: 0x1f14, 0xffd: 0x1f19, 0xffe: 0x1f28, 0xfff: 0x1f2d, + // Block 0x40, offset 0x1000 + 0x1000: 0x1f32, 0x1001: 0x1f37, 0x1002: 0x1f46, 0x1003: 0x1f4b, 0x1004: 0x1f5f, 0x1005: 0x1f64, + 0x1006: 0x1f69, 0x1007: 0x1f6e, 0x1008: 0x1f73, 0x1009: 0x1f87, 0x100a: 0x1f8c, 0x100b: 0x1f91, + 0x100c: 0x1f96, 0x100d: 0x1f9b, 0x100e: 0x1faf, 0x100f: 0x1fb4, 0x1010: 0x1fb9, 0x1011: 0x1fbe, + 0x1012: 0x1fcd, 0x1013: 0x1fd2, 0x1014: 0x1fd7, 0x1015: 0x1fe6, 0x1016: 0x1ff0, 0x1017: 0x1fff, + 0x1018: 0x2004, 0x1019: 0x4450, 0x101a: 0x2018, 0x101b: 0x201d, 0x101c: 0x2022, 0x101d: 0x2031, + 0x101e: 0x203b, 0x101f: 0x25d4, 0x1020: 0x25e2, 0x1021: 0x1da2, 0x1022: 0x1dac, 0x1023: 0x1dd4, + 0x1024: 0x1dde, 0x1025: 0x1dfc, 0x1026: 0x1e06, 0x1027: 0x1e6a, 0x1028: 0x1e6f, 0x1029: 0x1e92, + 0x102a: 0x1e97, 0x102b: 0x1f6e, 0x102c: 0x1f73, 0x102d: 0x1f96, 0x102e: 0x1fe6, 0x102f: 0x1ff0, + 0x1030: 0x2031, 0x1031: 0x203b, 0x1032: 0x4504, 0x1033: 0x450c, 0x1034: 0x4514, 0x1035: 0x1ef1, + 0x1036: 0x1ef6, 0x1037: 0x1f0a, 0x1038: 0x1f0f, 0x1039: 0x1f1e, 0x103a: 0x1f23, 0x103b: 0x1e74, + 0x103c: 0x1e79, 0x103d: 0x1e9c, 0x103e: 0x1ea1, 0x103f: 0x1e33, + // Block 0x41, offset 0x1040 + 0x1040: 0x1e38, 0x1041: 0x1e1f, 0x1042: 0x1e24, 0x1043: 0x1e4c, 0x1044: 0x1e51, 0x1045: 0x1eba, + 0x1046: 0x1ebf, 0x1047: 0x1edd, 0x1048: 0x1ee2, 0x1049: 0x1e7e, 0x104a: 0x1e83, 0x104b: 0x1e88, + 0x104c: 0x1e92, 0x104d: 0x1e8d, 0x104e: 0x1e65, 0x104f: 0x1eb0, 0x1050: 0x1ed3, 0x1051: 0x1ef1, + 0x1052: 0x1ef6, 0x1053: 0x1f0a, 0x1054: 0x1f0f, 0x1055: 0x1f1e, 0x1056: 0x1f23, 0x1057: 0x1e74, + 0x1058: 0x1e79, 0x1059: 0x1e9c, 0x105a: 0x1ea1, 0x105b: 0x1e33, 0x105c: 0x1e38, 0x105d: 0x1e1f, + 0x105e: 0x1e24, 0x105f: 0x1e4c, 0x1060: 0x1e51, 0x1061: 0x1eba, 0x1062: 0x1ebf, 0x1063: 0x1edd, + 0x1064: 0x1ee2, 0x1065: 0x1e7e, 0x1066: 0x1e83, 0x1067: 0x1e88, 0x1068: 0x1e92, 0x1069: 0x1e8d, + 0x106a: 0x1e65, 0x106b: 0x1eb0, 0x106c: 0x1ed3, 0x106d: 0x1e7e, 0x106e: 0x1e83, 0x106f: 0x1e88, + 0x1070: 0x1e92, 0x1071: 0x1e6f, 0x1072: 0x1e97, 0x1073: 0x1eec, 0x1074: 0x1e56, 0x1075: 0x1e5b, + 0x1076: 0x1e60, 0x1077: 0x1e7e, 0x1078: 0x1e83, 0x1079: 0x1e88, 0x107a: 0x1eec, 0x107b: 0x1efb, + 0x107c: 0x4408, 0x107d: 0x4408, + // Block 0x42, offset 0x1080 + 0x1090: 0x2311, 0x1091: 0x2326, + 0x1092: 0x2326, 0x1093: 0x232d, 0x1094: 0x2334, 0x1095: 0x2349, 0x1096: 0x2350, 0x1097: 0x2357, + 0x1098: 0x237a, 0x1099: 0x237a, 0x109a: 0x239d, 0x109b: 0x2396, 0x109c: 0x23b2, 0x109d: 0x23a4, + 0x109e: 0x23ab, 0x109f: 0x23ce, 0x10a0: 0x23ce, 0x10a1: 0x23c7, 0x10a2: 0x23d5, 0x10a3: 0x23d5, + 0x10a4: 0x23ff, 0x10a5: 0x23ff, 0x10a6: 0x241b, 0x10a7: 0x23e3, 0x10a8: 0x23e3, 0x10a9: 0x23dc, + 0x10aa: 0x23f1, 0x10ab: 0x23f1, 0x10ac: 0x23f8, 0x10ad: 0x23f8, 0x10ae: 0x2422, 0x10af: 0x2430, + 0x10b0: 0x2430, 0x10b1: 0x2437, 0x10b2: 0x2437, 0x10b3: 0x243e, 0x10b4: 0x2445, 0x10b5: 0x244c, + 0x10b6: 0x2453, 0x10b7: 0x2453, 0x10b8: 0x245a, 0x10b9: 0x2468, 0x10ba: 0x2476, 0x10bb: 0x246f, + 0x10bc: 0x247d, 0x10bd: 0x247d, 0x10be: 0x2492, 0x10bf: 0x2499, + // Block 0x43, offset 0x10c0 + 0x10c0: 0x24ca, 0x10c1: 0x24d8, 0x10c2: 0x24d1, 0x10c3: 0x24b5, 0x10c4: 0x24b5, 0x10c5: 0x24df, + 0x10c6: 0x24df, 0x10c7: 0x24e6, 0x10c8: 0x24e6, 0x10c9: 0x2510, 0x10ca: 0x2517, 0x10cb: 0x251e, + 0x10cc: 0x24f4, 0x10cd: 0x2502, 0x10ce: 0x2525, 0x10cf: 0x252c, + 0x10d2: 0x24fb, 0x10d3: 0x2580, 0x10d4: 0x2587, 0x10d5: 0x255d, 0x10d6: 0x2564, 0x10d7: 0x2548, + 0x10d8: 0x2548, 0x10d9: 0x254f, 0x10da: 0x2579, 0x10db: 0x2572, 0x10dc: 0x259c, 0x10dd: 0x259c, + 0x10de: 0x230a, 0x10df: 0x231f, 0x10e0: 0x2318, 0x10e1: 0x2342, 0x10e2: 0x233b, 0x10e3: 0x2365, + 0x10e4: 0x235e, 0x10e5: 0x2388, 0x10e6: 0x236c, 0x10e7: 0x2381, 0x10e8: 0x23b9, 0x10e9: 0x2406, + 0x10ea: 0x23ea, 0x10eb: 0x2429, 0x10ec: 0x24c3, 0x10ed: 0x24ed, 0x10ee: 0x2595, 0x10ef: 0x258e, + 0x10f0: 0x25a3, 0x10f1: 0x253a, 0x10f2: 0x24a0, 0x10f3: 0x256b, 0x10f4: 0x2492, 0x10f5: 0x24ca, + 0x10f6: 0x2461, 0x10f7: 0x24ae, 0x10f8: 0x2541, 0x10f9: 0x2533, 0x10fa: 0x24bc, 0x10fb: 0x24a7, + 0x10fc: 0x24bc, 0x10fd: 0x2541, 0x10fe: 0x2373, 0x10ff: 0x238f, + // Block 0x44, offset 0x1100 + 0x1100: 0x2509, 0x1101: 0x2484, 0x1102: 0x2303, 0x1103: 0x24a7, 0x1104: 0x244c, 0x1105: 0x241b, + 0x1106: 0x23c0, 0x1107: 0x2556, + 0x1130: 0x2414, 0x1131: 0x248b, 0x1132: 0x27bf, 0x1133: 0x27b6, 0x1134: 0x27ec, 0x1135: 0x27da, + 0x1136: 0x27c8, 0x1137: 0x27e3, 0x1138: 0x27f5, 0x1139: 0x240d, 0x113a: 0x2c7c, 0x113b: 0x2afc, + 0x113c: 0x27d1, + // Block 0x45, offset 0x1140 + 0x1150: 0x0019, 0x1151: 0x0483, + 0x1152: 0x0487, 0x1153: 0x0035, 0x1154: 0x0037, 0x1155: 0x0003, 0x1156: 0x003f, 0x1157: 0x04bf, + 0x1158: 0x04c3, 0x1159: 0x1b5c, + 0x1160: 0x8132, 0x1161: 0x8132, 0x1162: 0x8132, 0x1163: 0x8132, + 0x1164: 0x8132, 0x1165: 0x8132, 0x1166: 0x8132, 0x1167: 0x812d, 0x1168: 0x812d, 0x1169: 0x812d, + 0x116a: 0x812d, 0x116b: 0x812d, 0x116c: 0x812d, 0x116d: 0x812d, 0x116e: 0x8132, 0x116f: 0x8132, + 0x1170: 0x1873, 0x1171: 0x0443, 0x1172: 0x043f, 0x1173: 0x007f, 0x1174: 0x007f, 0x1175: 0x0011, + 0x1176: 0x0013, 0x1177: 0x00b7, 0x1178: 0x00bb, 0x1179: 0x04b7, 0x117a: 0x04bb, 0x117b: 0x04ab, + 0x117c: 0x04af, 0x117d: 0x0493, 0x117e: 0x0497, 0x117f: 0x048b, + // Block 0x46, offset 0x1180 + 0x1180: 0x048f, 0x1181: 0x049b, 0x1182: 0x049f, 0x1183: 0x04a3, 0x1184: 0x04a7, + 0x1187: 0x0077, 0x1188: 0x007b, 0x1189: 0x4269, 0x118a: 0x4269, 0x118b: 0x4269, + 0x118c: 0x4269, 0x118d: 0x007f, 0x118e: 0x007f, 0x118f: 0x007f, 0x1190: 0x0019, 0x1191: 0x0483, + 0x1192: 0x001d, 0x1194: 0x0037, 0x1195: 0x0035, 0x1196: 0x003f, 0x1197: 0x0003, + 0x1198: 0x0443, 0x1199: 0x0011, 0x119a: 0x0013, 0x119b: 0x00b7, 0x119c: 0x00bb, 0x119d: 0x04b7, + 0x119e: 0x04bb, 0x119f: 0x0007, 0x11a0: 0x000d, 0x11a1: 0x0015, 0x11a2: 0x0017, 0x11a3: 0x001b, + 0x11a4: 0x0039, 0x11a5: 0x003d, 0x11a6: 0x003b, 0x11a8: 0x0079, 0x11a9: 0x0009, + 0x11aa: 0x000b, 0x11ab: 0x0041, + 0x11b0: 0x42aa, 0x11b1: 0x442c, 0x11b2: 0x42af, 0x11b4: 0x42b4, + 0x11b6: 0x42b9, 0x11b7: 0x4432, 0x11b8: 0x42be, 0x11b9: 0x4438, 0x11ba: 0x42c3, 0x11bb: 0x443e, + 0x11bc: 0x42c8, 0x11bd: 0x4444, 0x11be: 0x42cd, 0x11bf: 0x444a, + // Block 0x47, offset 0x11c0 + 0x11c0: 0x0236, 0x11c1: 0x440e, 0x11c2: 0x440e, 0x11c3: 0x4414, 0x11c4: 0x4414, 0x11c5: 0x4456, + 0x11c6: 0x4456, 0x11c7: 0x441a, 0x11c8: 0x441a, 0x11c9: 0x4462, 0x11ca: 0x4462, 0x11cb: 0x4462, + 0x11cc: 0x4462, 0x11cd: 0x0239, 0x11ce: 0x0239, 0x11cf: 0x023c, 0x11d0: 0x023c, 0x11d1: 0x023c, + 0x11d2: 0x023c, 0x11d3: 0x023f, 0x11d4: 0x023f, 0x11d5: 0x0242, 0x11d6: 0x0242, 0x11d7: 0x0242, + 0x11d8: 0x0242, 0x11d9: 0x0245, 0x11da: 0x0245, 0x11db: 0x0245, 0x11dc: 0x0245, 0x11dd: 0x0248, + 0x11de: 0x0248, 0x11df: 0x0248, 0x11e0: 0x0248, 0x11e1: 0x024b, 0x11e2: 0x024b, 0x11e3: 0x024b, + 0x11e4: 0x024b, 0x11e5: 0x024e, 0x11e6: 0x024e, 0x11e7: 0x024e, 0x11e8: 0x024e, 0x11e9: 0x0251, + 0x11ea: 0x0251, 0x11eb: 0x0254, 0x11ec: 0x0254, 0x11ed: 0x0257, 0x11ee: 0x0257, 0x11ef: 0x025a, + 0x11f0: 0x025a, 0x11f1: 0x025d, 0x11f2: 0x025d, 0x11f3: 0x025d, 0x11f4: 0x025d, 0x11f5: 0x0260, + 0x11f6: 0x0260, 0x11f7: 0x0260, 0x11f8: 0x0260, 0x11f9: 0x0263, 0x11fa: 0x0263, 0x11fb: 0x0263, + 0x11fc: 0x0263, 0x11fd: 0x0266, 0x11fe: 0x0266, 0x11ff: 0x0266, + // Block 0x48, offset 0x1200 + 0x1200: 0x0266, 0x1201: 0x0269, 0x1202: 0x0269, 0x1203: 0x0269, 0x1204: 0x0269, 0x1205: 0x026c, + 0x1206: 0x026c, 0x1207: 0x026c, 0x1208: 0x026c, 0x1209: 0x026f, 0x120a: 0x026f, 0x120b: 0x026f, + 0x120c: 0x026f, 0x120d: 0x0272, 0x120e: 0x0272, 0x120f: 0x0272, 0x1210: 0x0272, 0x1211: 0x0275, + 0x1212: 0x0275, 0x1213: 0x0275, 0x1214: 0x0275, 0x1215: 0x0278, 0x1216: 0x0278, 0x1217: 0x0278, + 0x1218: 0x0278, 0x1219: 0x027b, 0x121a: 0x027b, 0x121b: 0x027b, 0x121c: 0x027b, 0x121d: 0x027e, + 0x121e: 0x027e, 0x121f: 0x027e, 0x1220: 0x027e, 0x1221: 0x0281, 0x1222: 0x0281, 0x1223: 0x0281, + 0x1224: 0x0281, 0x1225: 0x0284, 0x1226: 0x0284, 0x1227: 0x0284, 0x1228: 0x0284, 0x1229: 0x0287, + 0x122a: 0x0287, 0x122b: 0x0287, 0x122c: 0x0287, 0x122d: 0x028a, 0x122e: 0x028a, 0x122f: 0x028d, + 0x1230: 0x028d, 0x1231: 0x0290, 0x1232: 0x0290, 0x1233: 0x0290, 0x1234: 0x0290, 0x1235: 0x2e00, + 0x1236: 0x2e00, 0x1237: 0x2e08, 0x1238: 0x2e08, 0x1239: 0x2e10, 0x123a: 0x2e10, 0x123b: 0x1f82, + 0x123c: 0x1f82, + // Block 0x49, offset 0x1240 + 0x1240: 0x0081, 0x1241: 0x0083, 0x1242: 0x0085, 0x1243: 0x0087, 0x1244: 0x0089, 0x1245: 0x008b, + 0x1246: 0x008d, 0x1247: 0x008f, 0x1248: 0x0091, 0x1249: 0x0093, 0x124a: 0x0095, 0x124b: 0x0097, + 0x124c: 0x0099, 0x124d: 0x009b, 0x124e: 0x009d, 0x124f: 0x009f, 0x1250: 0x00a1, 0x1251: 0x00a3, + 0x1252: 0x00a5, 0x1253: 0x00a7, 0x1254: 0x00a9, 0x1255: 0x00ab, 0x1256: 0x00ad, 0x1257: 0x00af, + 0x1258: 0x00b1, 0x1259: 0x00b3, 0x125a: 0x00b5, 0x125b: 0x00b7, 0x125c: 0x00b9, 0x125d: 0x00bb, + 0x125e: 0x00bd, 0x125f: 0x0477, 0x1260: 0x047b, 0x1261: 0x0487, 0x1262: 0x049b, 0x1263: 0x049f, + 0x1264: 0x0483, 0x1265: 0x05ab, 0x1266: 0x05a3, 0x1267: 0x04c7, 0x1268: 0x04cf, 0x1269: 0x04d7, + 0x126a: 0x04df, 0x126b: 0x04e7, 0x126c: 0x056b, 0x126d: 0x0573, 0x126e: 0x057b, 0x126f: 0x051f, + 0x1270: 0x05af, 0x1271: 0x04cb, 0x1272: 0x04d3, 0x1273: 0x04db, 0x1274: 0x04e3, 0x1275: 0x04eb, + 0x1276: 0x04ef, 0x1277: 0x04f3, 0x1278: 0x04f7, 0x1279: 0x04fb, 0x127a: 0x04ff, 0x127b: 0x0503, + 0x127c: 0x0507, 0x127d: 0x050b, 0x127e: 0x050f, 0x127f: 0x0513, + // Block 0x4a, offset 0x1280 + 0x1280: 0x0517, 0x1281: 0x051b, 0x1282: 0x0523, 0x1283: 0x0527, 0x1284: 0x052b, 0x1285: 0x052f, + 0x1286: 0x0533, 0x1287: 0x0537, 0x1288: 0x053b, 0x1289: 0x053f, 0x128a: 0x0543, 0x128b: 0x0547, + 0x128c: 0x054b, 0x128d: 0x054f, 0x128e: 0x0553, 0x128f: 0x0557, 0x1290: 0x055b, 0x1291: 0x055f, + 0x1292: 0x0563, 0x1293: 0x0567, 0x1294: 0x056f, 0x1295: 0x0577, 0x1296: 0x057f, 0x1297: 0x0583, + 0x1298: 0x0587, 0x1299: 0x058b, 0x129a: 0x058f, 0x129b: 0x0593, 0x129c: 0x0597, 0x129d: 0x05a7, + 0x129e: 0x4a78, 0x129f: 0x4a7e, 0x12a0: 0x03c3, 0x12a1: 0x0313, 0x12a2: 0x0317, 0x12a3: 0x4a3b, + 0x12a4: 0x031b, 0x12a5: 0x4a41, 0x12a6: 0x4a47, 0x12a7: 0x031f, 0x12a8: 0x0323, 0x12a9: 0x0327, + 0x12aa: 0x4a4d, 0x12ab: 0x4a53, 0x12ac: 0x4a59, 0x12ad: 0x4a5f, 0x12ae: 0x4a65, 0x12af: 0x4a6b, + 0x12b0: 0x0367, 0x12b1: 0x032b, 0x12b2: 0x032f, 0x12b3: 0x0333, 0x12b4: 0x037b, 0x12b5: 0x0337, + 0x12b6: 0x033b, 0x12b7: 0x033f, 0x12b8: 0x0343, 0x12b9: 0x0347, 0x12ba: 0x034b, 0x12bb: 0x034f, + 0x12bc: 0x0353, 0x12bd: 0x0357, 0x12be: 0x035b, + // Block 0x4b, offset 0x12c0 + 0x12c2: 0x49bd, 0x12c3: 0x49c3, 0x12c4: 0x49c9, 0x12c5: 0x49cf, + 0x12c6: 0x49d5, 0x12c7: 0x49db, 0x12ca: 0x49e1, 0x12cb: 0x49e7, + 0x12cc: 0x49ed, 0x12cd: 0x49f3, 0x12ce: 0x49f9, 0x12cf: 0x49ff, + 0x12d2: 0x4a05, 0x12d3: 0x4a0b, 0x12d4: 0x4a11, 0x12d5: 0x4a17, 0x12d6: 0x4a1d, 0x12d7: 0x4a23, + 0x12da: 0x4a29, 0x12db: 0x4a2f, 0x12dc: 0x4a35, + 0x12e0: 0x00bf, 0x12e1: 0x00c2, 0x12e2: 0x00cb, 0x12e3: 0x4264, + 0x12e4: 0x00c8, 0x12e5: 0x00c5, 0x12e6: 0x0447, 0x12e8: 0x046b, 0x12e9: 0x044b, + 0x12ea: 0x044f, 0x12eb: 0x0453, 0x12ec: 0x0457, 0x12ed: 0x046f, 0x12ee: 0x0473, + // Block 0x4c, offset 0x1300 + 0x1300: 0x0063, 0x1301: 0x0065, 0x1302: 0x0067, 0x1303: 0x0069, 0x1304: 0x006b, 0x1305: 0x006d, + 0x1306: 0x006f, 0x1307: 0x0071, 0x1308: 0x0073, 0x1309: 0x0075, 0x130a: 0x0083, 0x130b: 0x0085, + 0x130c: 0x0087, 0x130d: 0x0089, 0x130e: 0x008b, 0x130f: 0x008d, 0x1310: 0x008f, 0x1311: 0x0091, + 0x1312: 0x0093, 0x1313: 0x0095, 0x1314: 0x0097, 0x1315: 0x0099, 0x1316: 0x009b, 0x1317: 0x009d, + 0x1318: 0x009f, 0x1319: 0x00a1, 0x131a: 0x00a3, 0x131b: 0x00a5, 0x131c: 0x00a7, 0x131d: 0x00a9, + 0x131e: 0x00ab, 0x131f: 0x00ad, 0x1320: 0x00af, 0x1321: 0x00b1, 0x1322: 0x00b3, 0x1323: 0x00b5, + 0x1324: 0x00dd, 0x1325: 0x00f2, 0x1328: 0x0173, 0x1329: 0x0176, + 0x132a: 0x0179, 0x132b: 0x017c, 0x132c: 0x017f, 0x132d: 0x0182, 0x132e: 0x0185, 0x132f: 0x0188, + 0x1330: 0x018b, 0x1331: 0x018e, 0x1332: 0x0191, 0x1333: 0x0194, 0x1334: 0x0197, 0x1335: 0x019a, + 0x1336: 0x019d, 0x1337: 0x01a0, 0x1338: 0x01a3, 0x1339: 0x0188, 0x133a: 0x01a6, 0x133b: 0x01a9, + 0x133c: 0x01ac, 0x133d: 0x01af, 0x133e: 0x01b2, 0x133f: 0x01b5, + // Block 0x4d, offset 0x1340 + 0x1340: 0x01fd, 0x1341: 0x0200, 0x1342: 0x0203, 0x1343: 0x045b, 0x1344: 0x01c7, 0x1345: 0x01d0, + 0x1346: 0x01d6, 0x1347: 0x01fa, 0x1348: 0x01eb, 0x1349: 0x01e8, 0x134a: 0x0206, 0x134b: 0x0209, + 0x134e: 0x0021, 0x134f: 0x0023, 0x1350: 0x0025, 0x1351: 0x0027, + 0x1352: 0x0029, 0x1353: 0x002b, 0x1354: 0x002d, 0x1355: 0x002f, 0x1356: 0x0031, 0x1357: 0x0033, + 0x1358: 0x0021, 0x1359: 0x0023, 0x135a: 0x0025, 0x135b: 0x0027, 0x135c: 0x0029, 0x135d: 0x002b, + 0x135e: 0x002d, 0x135f: 0x002f, 0x1360: 0x0031, 0x1361: 0x0033, 0x1362: 0x0021, 0x1363: 0x0023, + 0x1364: 0x0025, 0x1365: 0x0027, 0x1366: 0x0029, 0x1367: 0x002b, 0x1368: 0x002d, 0x1369: 0x002f, + 0x136a: 0x0031, 0x136b: 0x0033, 0x136c: 0x0021, 0x136d: 0x0023, 0x136e: 0x0025, 0x136f: 0x0027, + 0x1370: 0x0029, 0x1371: 0x002b, 0x1372: 0x002d, 0x1373: 0x002f, 0x1374: 0x0031, 0x1375: 0x0033, + 0x1376: 0x0021, 0x1377: 0x0023, 0x1378: 0x0025, 0x1379: 0x0027, 0x137a: 0x0029, 0x137b: 0x002b, + 0x137c: 0x002d, 0x137d: 0x002f, 0x137e: 0x0031, 0x137f: 0x0033, + // Block 0x4e, offset 0x1380 + 0x1380: 0x0239, 0x1381: 0x023c, 0x1382: 0x0248, 0x1383: 0x0251, 0x1385: 0x028a, + 0x1386: 0x025a, 0x1387: 0x024b, 0x1388: 0x0269, 0x1389: 0x0290, 0x138a: 0x027b, 0x138b: 0x027e, + 0x138c: 0x0281, 0x138d: 0x0284, 0x138e: 0x025d, 0x138f: 0x026f, 0x1390: 0x0275, 0x1391: 0x0263, + 0x1392: 0x0278, 0x1393: 0x0257, 0x1394: 0x0260, 0x1395: 0x0242, 0x1396: 0x0245, 0x1397: 0x024e, + 0x1398: 0x0254, 0x1399: 0x0266, 0x139a: 0x026c, 0x139b: 0x0272, 0x139c: 0x0293, 0x139d: 0x02e4, + 0x139e: 0x02cc, 0x139f: 0x0296, 0x13a1: 0x023c, 0x13a2: 0x0248, + 0x13a4: 0x0287, 0x13a7: 0x024b, 0x13a9: 0x0290, + 0x13aa: 0x027b, 0x13ab: 0x027e, 0x13ac: 0x0281, 0x13ad: 0x0284, 0x13ae: 0x025d, 0x13af: 0x026f, + 0x13b0: 0x0275, 0x13b1: 0x0263, 0x13b2: 0x0278, 0x13b4: 0x0260, 0x13b5: 0x0242, + 0x13b6: 0x0245, 0x13b7: 0x024e, 0x13b9: 0x0266, 0x13bb: 0x0272, + // Block 0x4f, offset 0x13c0 + 0x13c2: 0x0248, + 0x13c7: 0x024b, 0x13c9: 0x0290, 0x13cb: 0x027e, + 0x13cd: 0x0284, 0x13ce: 0x025d, 0x13cf: 0x026f, 0x13d1: 0x0263, + 0x13d2: 0x0278, 0x13d4: 0x0260, 0x13d7: 0x024e, + 0x13d9: 0x0266, 0x13db: 0x0272, 0x13dd: 0x02e4, + 0x13df: 0x0296, 0x13e1: 0x023c, 0x13e2: 0x0248, + 0x13e4: 0x0287, 0x13e7: 0x024b, 0x13e8: 0x0269, 0x13e9: 0x0290, + 0x13ea: 0x027b, 0x13ec: 0x0281, 0x13ed: 0x0284, 0x13ee: 0x025d, 0x13ef: 0x026f, + 0x13f0: 0x0275, 0x13f1: 0x0263, 0x13f2: 0x0278, 0x13f4: 0x0260, 0x13f5: 0x0242, + 0x13f6: 0x0245, 0x13f7: 0x024e, 0x13f9: 0x0266, 0x13fa: 0x026c, 0x13fb: 0x0272, + 0x13fc: 0x0293, 0x13fe: 0x02cc, + // Block 0x50, offset 0x1400 + 0x1400: 0x0239, 0x1401: 0x023c, 0x1402: 0x0248, 0x1403: 0x0251, 0x1404: 0x0287, 0x1405: 0x028a, + 0x1406: 0x025a, 0x1407: 0x024b, 0x1408: 0x0269, 0x1409: 0x0290, 0x140b: 0x027e, + 0x140c: 0x0281, 0x140d: 0x0284, 0x140e: 0x025d, 0x140f: 0x026f, 0x1410: 0x0275, 0x1411: 0x0263, + 0x1412: 0x0278, 0x1413: 0x0257, 0x1414: 0x0260, 0x1415: 0x0242, 0x1416: 0x0245, 0x1417: 0x024e, + 0x1418: 0x0254, 0x1419: 0x0266, 0x141a: 0x026c, 0x141b: 0x0272, + 0x1421: 0x023c, 0x1422: 0x0248, 0x1423: 0x0251, + 0x1425: 0x028a, 0x1426: 0x025a, 0x1427: 0x024b, 0x1428: 0x0269, 0x1429: 0x0290, + 0x142b: 0x027e, 0x142c: 0x0281, 0x142d: 0x0284, 0x142e: 0x025d, 0x142f: 0x026f, + 0x1430: 0x0275, 0x1431: 0x0263, 0x1432: 0x0278, 0x1433: 0x0257, 0x1434: 0x0260, 0x1435: 0x0242, + 0x1436: 0x0245, 0x1437: 0x024e, 0x1438: 0x0254, 0x1439: 0x0266, 0x143a: 0x026c, 0x143b: 0x0272, + // Block 0x51, offset 0x1440 + 0x1440: 0x1879, 0x1441: 0x1876, 0x1442: 0x187c, 0x1443: 0x18a0, 0x1444: 0x18c4, 0x1445: 0x18e8, + 0x1446: 0x190c, 0x1447: 0x1915, 0x1448: 0x191b, 0x1449: 0x1921, 0x144a: 0x1927, + 0x1450: 0x1a8c, 0x1451: 0x1a90, + 0x1452: 0x1a94, 0x1453: 0x1a98, 0x1454: 0x1a9c, 0x1455: 0x1aa0, 0x1456: 0x1aa4, 0x1457: 0x1aa8, + 0x1458: 0x1aac, 0x1459: 0x1ab0, 0x145a: 0x1ab4, 0x145b: 0x1ab8, 0x145c: 0x1abc, 0x145d: 0x1ac0, + 0x145e: 0x1ac4, 0x145f: 0x1ac8, 0x1460: 0x1acc, 0x1461: 0x1ad0, 0x1462: 0x1ad4, 0x1463: 0x1ad8, + 0x1464: 0x1adc, 0x1465: 0x1ae0, 0x1466: 0x1ae4, 0x1467: 0x1ae8, 0x1468: 0x1aec, 0x1469: 0x1af0, + 0x146a: 0x271e, 0x146b: 0x0047, 0x146c: 0x0065, 0x146d: 0x193c, 0x146e: 0x19b1, + 0x1470: 0x0043, 0x1471: 0x0045, 0x1472: 0x0047, 0x1473: 0x0049, 0x1474: 0x004b, 0x1475: 0x004d, + 0x1476: 0x004f, 0x1477: 0x0051, 0x1478: 0x0053, 0x1479: 0x0055, 0x147a: 0x0057, 0x147b: 0x0059, + 0x147c: 0x005b, 0x147d: 0x005d, 0x147e: 0x005f, 0x147f: 0x0061, + // Block 0x52, offset 0x1480 + 0x1480: 0x26ad, 0x1481: 0x26c2, 0x1482: 0x0503, + 0x1490: 0x0c0f, 0x1491: 0x0a47, + 0x1492: 0x08d3, 0x1493: 0x45c4, 0x1494: 0x071b, 0x1495: 0x09ef, 0x1496: 0x132f, 0x1497: 0x09ff, + 0x1498: 0x0727, 0x1499: 0x0cd7, 0x149a: 0x0eaf, 0x149b: 0x0caf, 0x149c: 0x0827, 0x149d: 0x0b6b, + 0x149e: 0x07bf, 0x149f: 0x0cb7, 0x14a0: 0x0813, 0x14a1: 0x1117, 0x14a2: 0x0f83, 0x14a3: 0x138b, + 0x14a4: 0x09d3, 0x14a5: 0x090b, 0x14a6: 0x0e63, 0x14a7: 0x0c1b, 0x14a8: 0x0c47, 0x14a9: 0x06bf, + 0x14aa: 0x06cb, 0x14ab: 0x140b, 0x14ac: 0x0adb, 0x14ad: 0x06e7, 0x14ae: 0x08ef, 0x14af: 0x0c3b, + 0x14b0: 0x13b3, 0x14b1: 0x0c13, 0x14b2: 0x106f, 0x14b3: 0x10ab, 0x14b4: 0x08f7, 0x14b5: 0x0e43, + 0x14b6: 0x0d0b, 0x14b7: 0x0d07, 0x14b8: 0x0f97, 0x14b9: 0x082b, 0x14ba: 0x0957, 0x14bb: 0x1443, + // Block 0x53, offset 0x14c0 + 0x14c0: 0x06fb, 0x14c1: 0x06f3, 0x14c2: 0x0703, 0x14c3: 0x1647, 0x14c4: 0x0747, 0x14c5: 0x0757, + 0x14c6: 0x075b, 0x14c7: 0x0763, 0x14c8: 0x076b, 0x14c9: 0x076f, 0x14ca: 0x077b, 0x14cb: 0x0773, + 0x14cc: 0x05b3, 0x14cd: 0x165b, 0x14ce: 0x078f, 0x14cf: 0x0793, 0x14d0: 0x0797, 0x14d1: 0x07b3, + 0x14d2: 0x164c, 0x14d3: 0x05b7, 0x14d4: 0x079f, 0x14d5: 0x07bf, 0x14d6: 0x1656, 0x14d7: 0x07cf, + 0x14d8: 0x07d7, 0x14d9: 0x0737, 0x14da: 0x07df, 0x14db: 0x07e3, 0x14dc: 0x1831, 0x14dd: 0x07ff, + 0x14de: 0x0807, 0x14df: 0x05bf, 0x14e0: 0x081f, 0x14e1: 0x0823, 0x14e2: 0x082b, 0x14e3: 0x082f, + 0x14e4: 0x05c3, 0x14e5: 0x0847, 0x14e6: 0x084b, 0x14e7: 0x0857, 0x14e8: 0x0863, 0x14e9: 0x0867, + 0x14ea: 0x086b, 0x14eb: 0x0873, 0x14ec: 0x0893, 0x14ed: 0x0897, 0x14ee: 0x089f, 0x14ef: 0x08af, + 0x14f0: 0x08b7, 0x14f1: 0x08bb, 0x14f2: 0x08bb, 0x14f3: 0x08bb, 0x14f4: 0x166a, 0x14f5: 0x0e93, + 0x14f6: 0x08cf, 0x14f7: 0x08d7, 0x14f8: 0x166f, 0x14f9: 0x08e3, 0x14fa: 0x08eb, 0x14fb: 0x08f3, + 0x14fc: 0x091b, 0x14fd: 0x0907, 0x14fe: 0x0913, 0x14ff: 0x0917, + // Block 0x54, offset 0x1500 + 0x1500: 0x091f, 0x1501: 0x0927, 0x1502: 0x092b, 0x1503: 0x0933, 0x1504: 0x093b, 0x1505: 0x093f, + 0x1506: 0x093f, 0x1507: 0x0947, 0x1508: 0x094f, 0x1509: 0x0953, 0x150a: 0x095f, 0x150b: 0x0983, + 0x150c: 0x0967, 0x150d: 0x0987, 0x150e: 0x096b, 0x150f: 0x0973, 0x1510: 0x080b, 0x1511: 0x09cf, + 0x1512: 0x0997, 0x1513: 0x099b, 0x1514: 0x099f, 0x1515: 0x0993, 0x1516: 0x09a7, 0x1517: 0x09a3, + 0x1518: 0x09bb, 0x1519: 0x1674, 0x151a: 0x09d7, 0x151b: 0x09db, 0x151c: 0x09e3, 0x151d: 0x09ef, + 0x151e: 0x09f7, 0x151f: 0x0a13, 0x1520: 0x1679, 0x1521: 0x167e, 0x1522: 0x0a1f, 0x1523: 0x0a23, + 0x1524: 0x0a27, 0x1525: 0x0a1b, 0x1526: 0x0a2f, 0x1527: 0x05c7, 0x1528: 0x05cb, 0x1529: 0x0a37, + 0x152a: 0x0a3f, 0x152b: 0x0a3f, 0x152c: 0x1683, 0x152d: 0x0a5b, 0x152e: 0x0a5f, 0x152f: 0x0a63, + 0x1530: 0x0a6b, 0x1531: 0x1688, 0x1532: 0x0a73, 0x1533: 0x0a77, 0x1534: 0x0b4f, 0x1535: 0x0a7f, + 0x1536: 0x05cf, 0x1537: 0x0a8b, 0x1538: 0x0a9b, 0x1539: 0x0aa7, 0x153a: 0x0aa3, 0x153b: 0x1692, + 0x153c: 0x0aaf, 0x153d: 0x1697, 0x153e: 0x0abb, 0x153f: 0x0ab7, + // Block 0x55, offset 0x1540 + 0x1540: 0x0abf, 0x1541: 0x0acf, 0x1542: 0x0ad3, 0x1543: 0x05d3, 0x1544: 0x0ae3, 0x1545: 0x0aeb, + 0x1546: 0x0aef, 0x1547: 0x0af3, 0x1548: 0x05d7, 0x1549: 0x169c, 0x154a: 0x05db, 0x154b: 0x0b0f, + 0x154c: 0x0b13, 0x154d: 0x0b17, 0x154e: 0x0b1f, 0x154f: 0x1863, 0x1550: 0x0b37, 0x1551: 0x16a6, + 0x1552: 0x16a6, 0x1553: 0x11d7, 0x1554: 0x0b47, 0x1555: 0x0b47, 0x1556: 0x05df, 0x1557: 0x16c9, + 0x1558: 0x179b, 0x1559: 0x0b57, 0x155a: 0x0b5f, 0x155b: 0x05e3, 0x155c: 0x0b73, 0x155d: 0x0b83, + 0x155e: 0x0b87, 0x155f: 0x0b8f, 0x1560: 0x0b9f, 0x1561: 0x05eb, 0x1562: 0x05e7, 0x1563: 0x0ba3, + 0x1564: 0x16ab, 0x1565: 0x0ba7, 0x1566: 0x0bbb, 0x1567: 0x0bbf, 0x1568: 0x0bc3, 0x1569: 0x0bbf, + 0x156a: 0x0bcf, 0x156b: 0x0bd3, 0x156c: 0x0be3, 0x156d: 0x0bdb, 0x156e: 0x0bdf, 0x156f: 0x0be7, + 0x1570: 0x0beb, 0x1571: 0x0bef, 0x1572: 0x0bfb, 0x1573: 0x0bff, 0x1574: 0x0c17, 0x1575: 0x0c1f, + 0x1576: 0x0c2f, 0x1577: 0x0c43, 0x1578: 0x16ba, 0x1579: 0x0c3f, 0x157a: 0x0c33, 0x157b: 0x0c4b, + 0x157c: 0x0c53, 0x157d: 0x0c67, 0x157e: 0x16bf, 0x157f: 0x0c6f, + // Block 0x56, offset 0x1580 + 0x1580: 0x0c63, 0x1581: 0x0c5b, 0x1582: 0x05ef, 0x1583: 0x0c77, 0x1584: 0x0c7f, 0x1585: 0x0c87, + 0x1586: 0x0c7b, 0x1587: 0x05f3, 0x1588: 0x0c97, 0x1589: 0x0c9f, 0x158a: 0x16c4, 0x158b: 0x0ccb, + 0x158c: 0x0cff, 0x158d: 0x0cdb, 0x158e: 0x05ff, 0x158f: 0x0ce7, 0x1590: 0x05fb, 0x1591: 0x05f7, + 0x1592: 0x07c3, 0x1593: 0x07c7, 0x1594: 0x0d03, 0x1595: 0x0ceb, 0x1596: 0x11ab, 0x1597: 0x0663, + 0x1598: 0x0d0f, 0x1599: 0x0d13, 0x159a: 0x0d17, 0x159b: 0x0d2b, 0x159c: 0x0d23, 0x159d: 0x16dd, + 0x159e: 0x0603, 0x159f: 0x0d3f, 0x15a0: 0x0d33, 0x15a1: 0x0d4f, 0x15a2: 0x0d57, 0x15a3: 0x16e7, + 0x15a4: 0x0d5b, 0x15a5: 0x0d47, 0x15a6: 0x0d63, 0x15a7: 0x0607, 0x15a8: 0x0d67, 0x15a9: 0x0d6b, + 0x15aa: 0x0d6f, 0x15ab: 0x0d7b, 0x15ac: 0x16ec, 0x15ad: 0x0d83, 0x15ae: 0x060b, 0x15af: 0x0d8f, + 0x15b0: 0x16f1, 0x15b1: 0x0d93, 0x15b2: 0x060f, 0x15b3: 0x0d9f, 0x15b4: 0x0dab, 0x15b5: 0x0db7, + 0x15b6: 0x0dbb, 0x15b7: 0x16f6, 0x15b8: 0x168d, 0x15b9: 0x16fb, 0x15ba: 0x0ddb, 0x15bb: 0x1700, + 0x15bc: 0x0de7, 0x15bd: 0x0def, 0x15be: 0x0ddf, 0x15bf: 0x0dfb, + // Block 0x57, offset 0x15c0 + 0x15c0: 0x0e0b, 0x15c1: 0x0e1b, 0x15c2: 0x0e0f, 0x15c3: 0x0e13, 0x15c4: 0x0e1f, 0x15c5: 0x0e23, + 0x15c6: 0x1705, 0x15c7: 0x0e07, 0x15c8: 0x0e3b, 0x15c9: 0x0e3f, 0x15ca: 0x0613, 0x15cb: 0x0e53, + 0x15cc: 0x0e4f, 0x15cd: 0x170a, 0x15ce: 0x0e33, 0x15cf: 0x0e6f, 0x15d0: 0x170f, 0x15d1: 0x1714, + 0x15d2: 0x0e73, 0x15d3: 0x0e87, 0x15d4: 0x0e83, 0x15d5: 0x0e7f, 0x15d6: 0x0617, 0x15d7: 0x0e8b, + 0x15d8: 0x0e9b, 0x15d9: 0x0e97, 0x15da: 0x0ea3, 0x15db: 0x1651, 0x15dc: 0x0eb3, 0x15dd: 0x1719, + 0x15de: 0x0ebf, 0x15df: 0x1723, 0x15e0: 0x0ed3, 0x15e1: 0x0edf, 0x15e2: 0x0ef3, 0x15e3: 0x1728, + 0x15e4: 0x0f07, 0x15e5: 0x0f0b, 0x15e6: 0x172d, 0x15e7: 0x1732, 0x15e8: 0x0f27, 0x15e9: 0x0f37, + 0x15ea: 0x061b, 0x15eb: 0x0f3b, 0x15ec: 0x061f, 0x15ed: 0x061f, 0x15ee: 0x0f53, 0x15ef: 0x0f57, + 0x15f0: 0x0f5f, 0x15f1: 0x0f63, 0x15f2: 0x0f6f, 0x15f3: 0x0623, 0x15f4: 0x0f87, 0x15f5: 0x1737, + 0x15f6: 0x0fa3, 0x15f7: 0x173c, 0x15f8: 0x0faf, 0x15f9: 0x16a1, 0x15fa: 0x0fbf, 0x15fb: 0x1741, + 0x15fc: 0x1746, 0x15fd: 0x174b, 0x15fe: 0x0627, 0x15ff: 0x062b, + // Block 0x58, offset 0x1600 + 0x1600: 0x0ff7, 0x1601: 0x1755, 0x1602: 0x1750, 0x1603: 0x175a, 0x1604: 0x175f, 0x1605: 0x0fff, + 0x1606: 0x1003, 0x1607: 0x1003, 0x1608: 0x100b, 0x1609: 0x0633, 0x160a: 0x100f, 0x160b: 0x0637, + 0x160c: 0x063b, 0x160d: 0x1769, 0x160e: 0x1023, 0x160f: 0x102b, 0x1610: 0x1037, 0x1611: 0x063f, + 0x1612: 0x176e, 0x1613: 0x105b, 0x1614: 0x1773, 0x1615: 0x1778, 0x1616: 0x107b, 0x1617: 0x1093, + 0x1618: 0x0643, 0x1619: 0x109b, 0x161a: 0x109f, 0x161b: 0x10a3, 0x161c: 0x177d, 0x161d: 0x1782, + 0x161e: 0x1782, 0x161f: 0x10bb, 0x1620: 0x0647, 0x1621: 0x1787, 0x1622: 0x10cf, 0x1623: 0x10d3, + 0x1624: 0x064b, 0x1625: 0x178c, 0x1626: 0x10ef, 0x1627: 0x064f, 0x1628: 0x10ff, 0x1629: 0x10f7, + 0x162a: 0x1107, 0x162b: 0x1796, 0x162c: 0x111f, 0x162d: 0x0653, 0x162e: 0x112b, 0x162f: 0x1133, + 0x1630: 0x1143, 0x1631: 0x0657, 0x1632: 0x17a0, 0x1633: 0x17a5, 0x1634: 0x065b, 0x1635: 0x17aa, + 0x1636: 0x115b, 0x1637: 0x17af, 0x1638: 0x1167, 0x1639: 0x1173, 0x163a: 0x117b, 0x163b: 0x17b4, + 0x163c: 0x17b9, 0x163d: 0x118f, 0x163e: 0x17be, 0x163f: 0x1197, + // Block 0x59, offset 0x1640 + 0x1640: 0x16ce, 0x1641: 0x065f, 0x1642: 0x11af, 0x1643: 0x11b3, 0x1644: 0x0667, 0x1645: 0x11b7, + 0x1646: 0x0a33, 0x1647: 0x17c3, 0x1648: 0x17c8, 0x1649: 0x16d3, 0x164a: 0x16d8, 0x164b: 0x11d7, + 0x164c: 0x11db, 0x164d: 0x13f3, 0x164e: 0x066b, 0x164f: 0x1207, 0x1650: 0x1203, 0x1651: 0x120b, + 0x1652: 0x083f, 0x1653: 0x120f, 0x1654: 0x1213, 0x1655: 0x1217, 0x1656: 0x121f, 0x1657: 0x17cd, + 0x1658: 0x121b, 0x1659: 0x1223, 0x165a: 0x1237, 0x165b: 0x123b, 0x165c: 0x1227, 0x165d: 0x123f, + 0x165e: 0x1253, 0x165f: 0x1267, 0x1660: 0x1233, 0x1661: 0x1247, 0x1662: 0x124b, 0x1663: 0x124f, + 0x1664: 0x17d2, 0x1665: 0x17dc, 0x1666: 0x17d7, 0x1667: 0x066f, 0x1668: 0x126f, 0x1669: 0x1273, + 0x166a: 0x127b, 0x166b: 0x17f0, 0x166c: 0x127f, 0x166d: 0x17e1, 0x166e: 0x0673, 0x166f: 0x0677, + 0x1670: 0x17e6, 0x1671: 0x17eb, 0x1672: 0x067b, 0x1673: 0x129f, 0x1674: 0x12a3, 0x1675: 0x12a7, + 0x1676: 0x12ab, 0x1677: 0x12b7, 0x1678: 0x12b3, 0x1679: 0x12bf, 0x167a: 0x12bb, 0x167b: 0x12cb, + 0x167c: 0x12c3, 0x167d: 0x12c7, 0x167e: 0x12cf, 0x167f: 0x067f, + // Block 0x5a, offset 0x1680 + 0x1680: 0x12d7, 0x1681: 0x12db, 0x1682: 0x0683, 0x1683: 0x12eb, 0x1684: 0x12ef, 0x1685: 0x17f5, + 0x1686: 0x12fb, 0x1687: 0x12ff, 0x1688: 0x0687, 0x1689: 0x130b, 0x168a: 0x05bb, 0x168b: 0x17fa, + 0x168c: 0x17ff, 0x168d: 0x068b, 0x168e: 0x068f, 0x168f: 0x1337, 0x1690: 0x134f, 0x1691: 0x136b, + 0x1692: 0x137b, 0x1693: 0x1804, 0x1694: 0x138f, 0x1695: 0x1393, 0x1696: 0x13ab, 0x1697: 0x13b7, + 0x1698: 0x180e, 0x1699: 0x1660, 0x169a: 0x13c3, 0x169b: 0x13bf, 0x169c: 0x13cb, 0x169d: 0x1665, + 0x169e: 0x13d7, 0x169f: 0x13e3, 0x16a0: 0x1813, 0x16a1: 0x1818, 0x16a2: 0x1423, 0x16a3: 0x142f, + 0x16a4: 0x1437, 0x16a5: 0x181d, 0x16a6: 0x143b, 0x16a7: 0x1467, 0x16a8: 0x1473, 0x16a9: 0x1477, + 0x16aa: 0x146f, 0x16ab: 0x1483, 0x16ac: 0x1487, 0x16ad: 0x1822, 0x16ae: 0x1493, 0x16af: 0x0693, + 0x16b0: 0x149b, 0x16b1: 0x1827, 0x16b2: 0x0697, 0x16b3: 0x14d3, 0x16b4: 0x0ac3, 0x16b5: 0x14eb, + 0x16b6: 0x182c, 0x16b7: 0x1836, 0x16b8: 0x069b, 0x16b9: 0x069f, 0x16ba: 0x1513, 0x16bb: 0x183b, + 0x16bc: 0x06a3, 0x16bd: 0x1840, 0x16be: 0x152b, 0x16bf: 0x152b, + // Block 0x5b, offset 0x16c0 + 0x16c0: 0x1533, 0x16c1: 0x1845, 0x16c2: 0x154b, 0x16c3: 0x06a7, 0x16c4: 0x155b, 0x16c5: 0x1567, + 0x16c6: 0x156f, 0x16c7: 0x1577, 0x16c8: 0x06ab, 0x16c9: 0x184a, 0x16ca: 0x158b, 0x16cb: 0x15a7, + 0x16cc: 0x15b3, 0x16cd: 0x06af, 0x16ce: 0x06b3, 0x16cf: 0x15b7, 0x16d0: 0x184f, 0x16d1: 0x06b7, + 0x16d2: 0x1854, 0x16d3: 0x1859, 0x16d4: 0x185e, 0x16d5: 0x15db, 0x16d6: 0x06bb, 0x16d7: 0x15ef, + 0x16d8: 0x15f7, 0x16d9: 0x15fb, 0x16da: 0x1603, 0x16db: 0x160b, 0x16dc: 0x1613, 0x16dd: 0x1868, +} + +// nfkcIndex: 22 blocks, 1408 entries, 1408 bytes +// Block 0 is the zero block. +var nfkcIndex = [1408]uint8{ + // Block 0x0, offset 0x0 + // Block 0x1, offset 0x40 + // Block 0x2, offset 0x80 + // Block 0x3, offset 0xc0 + 0xc2: 0x5a, 0xc3: 0x01, 0xc4: 0x02, 0xc5: 0x03, 0xc6: 0x5b, 0xc7: 0x04, + 0xc8: 0x05, 0xca: 0x5c, 0xcb: 0x5d, 0xcc: 0x06, 0xcd: 0x07, 0xce: 0x08, 0xcf: 0x09, + 0xd0: 0x0a, 0xd1: 0x5e, 0xd2: 0x5f, 0xd3: 0x0b, 0xd6: 0x0c, 0xd7: 0x60, + 0xd8: 0x61, 0xd9: 0x0d, 0xdb: 0x62, 0xdc: 0x63, 0xdd: 0x64, 0xdf: 0x65, + 0xe0: 0x02, 0xe1: 0x03, 0xe2: 0x04, 0xe3: 0x05, + 0xea: 0x06, 0xeb: 0x07, 0xec: 0x08, 0xed: 0x09, 0xef: 0x0a, + 0xf0: 0x13, + // Block 0x4, offset 0x100 + 0x120: 0x66, 0x121: 0x67, 0x123: 0x68, 0x124: 0x69, 0x125: 0x6a, 0x126: 0x6b, 0x127: 0x6c, + 0x128: 0x6d, 0x129: 0x6e, 0x12a: 0x6f, 0x12b: 0x70, 0x12c: 0x6b, 0x12d: 0x71, 0x12e: 0x72, 0x12f: 0x73, + 0x131: 0x74, 0x132: 0x75, 0x133: 0x76, 0x134: 0x77, 0x135: 0x78, 0x137: 0x79, + 0x138: 0x7a, 0x139: 0x7b, 0x13a: 0x7c, 0x13b: 0x7d, 0x13c: 0x7e, 0x13d: 0x7f, 0x13e: 0x80, 0x13f: 0x81, + // Block 0x5, offset 0x140 + 0x140: 0x82, 0x142: 0x83, 0x143: 0x84, 0x144: 0x85, 0x145: 0x86, 0x146: 0x87, 0x147: 0x88, + 0x14d: 0x89, + 0x15c: 0x8a, 0x15f: 0x8b, + 0x162: 0x8c, 0x164: 0x8d, + 0x168: 0x8e, 0x169: 0x8f, 0x16a: 0x90, 0x16c: 0x0e, 0x16d: 0x91, 0x16e: 0x92, 0x16f: 0x93, + 0x170: 0x94, 0x173: 0x95, 0x174: 0x96, 0x175: 0x0f, 0x176: 0x10, 0x177: 0x97, + 0x178: 0x11, 0x179: 0x12, 0x17a: 0x13, 0x17b: 0x14, 0x17c: 0x15, 0x17d: 0x16, 0x17e: 0x17, 0x17f: 0x18, + // Block 0x6, offset 0x180 + 0x180: 0x98, 0x181: 0x99, 0x182: 0x9a, 0x183: 0x9b, 0x184: 0x19, 0x185: 0x1a, 0x186: 0x9c, 0x187: 0x9d, + 0x188: 0x9e, 0x189: 0x1b, 0x18a: 0x1c, 0x18b: 0x9f, 0x18c: 0xa0, + 0x191: 0x1d, 0x192: 0x1e, 0x193: 0xa1, + 0x1a8: 0xa2, 0x1a9: 0xa3, 0x1ab: 0xa4, + 0x1b1: 0xa5, 0x1b3: 0xa6, 0x1b5: 0xa7, 0x1b7: 0xa8, + 0x1ba: 0xa9, 0x1bb: 0xaa, 0x1bc: 0x1f, 0x1bd: 0x20, 0x1be: 0x21, 0x1bf: 0xab, + // Block 0x7, offset 0x1c0 + 0x1c0: 0xac, 0x1c1: 0x22, 0x1c2: 0x23, 0x1c3: 0x24, 0x1c4: 0xad, 0x1c5: 0x25, 0x1c6: 0x26, + 0x1c8: 0x27, 0x1c9: 0x28, 0x1ca: 0x29, 0x1cb: 0x2a, 0x1cc: 0x2b, 0x1cd: 0x2c, 0x1ce: 0x2d, 0x1cf: 0x2e, + // Block 0x8, offset 0x200 + 0x219: 0xae, 0x21a: 0xaf, 0x21b: 0xb0, 0x21d: 0xb1, 0x21f: 0xb2, + 0x220: 0xb3, 0x223: 0xb4, 0x224: 0xb5, 0x225: 0xb6, 0x226: 0xb7, 0x227: 0xb8, + 0x22a: 0xb9, 0x22b: 0xba, 0x22d: 0xbb, 0x22f: 0xbc, + 0x230: 0xbd, 0x231: 0xbe, 0x232: 0xbf, 0x233: 0xc0, 0x234: 0xc1, 0x235: 0xc2, 0x236: 0xc3, 0x237: 0xbd, + 0x238: 0xbe, 0x239: 0xbf, 0x23a: 0xc0, 0x23b: 0xc1, 0x23c: 0xc2, 0x23d: 0xc3, 0x23e: 0xbd, 0x23f: 0xbe, + // Block 0x9, offset 0x240 + 0x240: 0xbf, 0x241: 0xc0, 0x242: 0xc1, 0x243: 0xc2, 0x244: 0xc3, 0x245: 0xbd, 0x246: 0xbe, 0x247: 0xbf, + 0x248: 0xc0, 0x249: 0xc1, 0x24a: 0xc2, 0x24b: 0xc3, 0x24c: 0xbd, 0x24d: 0xbe, 0x24e: 0xbf, 0x24f: 0xc0, + 0x250: 0xc1, 0x251: 0xc2, 0x252: 0xc3, 0x253: 0xbd, 0x254: 0xbe, 0x255: 0xbf, 0x256: 0xc0, 0x257: 0xc1, + 0x258: 0xc2, 0x259: 0xc3, 0x25a: 0xbd, 0x25b: 0xbe, 0x25c: 0xbf, 0x25d: 0xc0, 0x25e: 0xc1, 0x25f: 0xc2, + 0x260: 0xc3, 0x261: 0xbd, 0x262: 0xbe, 0x263: 0xbf, 0x264: 0xc0, 0x265: 0xc1, 0x266: 0xc2, 0x267: 0xc3, + 0x268: 0xbd, 0x269: 0xbe, 0x26a: 0xbf, 0x26b: 0xc0, 0x26c: 0xc1, 0x26d: 0xc2, 0x26e: 0xc3, 0x26f: 0xbd, + 0x270: 0xbe, 0x271: 0xbf, 0x272: 0xc0, 0x273: 0xc1, 0x274: 0xc2, 0x275: 0xc3, 0x276: 0xbd, 0x277: 0xbe, + 0x278: 0xbf, 0x279: 0xc0, 0x27a: 0xc1, 0x27b: 0xc2, 0x27c: 0xc3, 0x27d: 0xbd, 0x27e: 0xbe, 0x27f: 0xbf, + // Block 0xa, offset 0x280 + 0x280: 0xc0, 0x281: 0xc1, 0x282: 0xc2, 0x283: 0xc3, 0x284: 0xbd, 0x285: 0xbe, 0x286: 0xbf, 0x287: 0xc0, + 0x288: 0xc1, 0x289: 0xc2, 0x28a: 0xc3, 0x28b: 0xbd, 0x28c: 0xbe, 0x28d: 0xbf, 0x28e: 0xc0, 0x28f: 0xc1, + 0x290: 0xc2, 0x291: 0xc3, 0x292: 0xbd, 0x293: 0xbe, 0x294: 0xbf, 0x295: 0xc0, 0x296: 0xc1, 0x297: 0xc2, + 0x298: 0xc3, 0x299: 0xbd, 0x29a: 0xbe, 0x29b: 0xbf, 0x29c: 0xc0, 0x29d: 0xc1, 0x29e: 0xc2, 0x29f: 0xc3, + 0x2a0: 0xbd, 0x2a1: 0xbe, 0x2a2: 0xbf, 0x2a3: 0xc0, 0x2a4: 0xc1, 0x2a5: 0xc2, 0x2a6: 0xc3, 0x2a7: 0xbd, + 0x2a8: 0xbe, 0x2a9: 0xbf, 0x2aa: 0xc0, 0x2ab: 0xc1, 0x2ac: 0xc2, 0x2ad: 0xc3, 0x2ae: 0xbd, 0x2af: 0xbe, + 0x2b0: 0xbf, 0x2b1: 0xc0, 0x2b2: 0xc1, 0x2b3: 0xc2, 0x2b4: 0xc3, 0x2b5: 0xbd, 0x2b6: 0xbe, 0x2b7: 0xbf, + 0x2b8: 0xc0, 0x2b9: 0xc1, 0x2ba: 0xc2, 0x2bb: 0xc3, 0x2bc: 0xbd, 0x2bd: 0xbe, 0x2be: 0xbf, 0x2bf: 0xc0, + // Block 0xb, offset 0x2c0 + 0x2c0: 0xc1, 0x2c1: 0xc2, 0x2c2: 0xc3, 0x2c3: 0xbd, 0x2c4: 0xbe, 0x2c5: 0xbf, 0x2c6: 0xc0, 0x2c7: 0xc1, + 0x2c8: 0xc2, 0x2c9: 0xc3, 0x2ca: 0xbd, 0x2cb: 0xbe, 0x2cc: 0xbf, 0x2cd: 0xc0, 0x2ce: 0xc1, 0x2cf: 0xc2, + 0x2d0: 0xc3, 0x2d1: 0xbd, 0x2d2: 0xbe, 0x2d3: 0xbf, 0x2d4: 0xc0, 0x2d5: 0xc1, 0x2d6: 0xc2, 0x2d7: 0xc3, + 0x2d8: 0xbd, 0x2d9: 0xbe, 0x2da: 0xbf, 0x2db: 0xc0, 0x2dc: 0xc1, 0x2dd: 0xc2, 0x2de: 0xc4, + // Block 0xc, offset 0x300 + 0x324: 0x2f, 0x325: 0x30, 0x326: 0x31, 0x327: 0x32, + 0x328: 0x33, 0x329: 0x34, 0x32a: 0x35, 0x32b: 0x36, 0x32c: 0x37, 0x32d: 0x38, 0x32e: 0x39, 0x32f: 0x3a, + 0x330: 0x3b, 0x331: 0x3c, 0x332: 0x3d, 0x333: 0x3e, 0x334: 0x3f, 0x335: 0x40, 0x336: 0x41, 0x337: 0x42, + 0x338: 0x43, 0x339: 0x44, 0x33a: 0x45, 0x33b: 0x46, 0x33c: 0xc5, 0x33d: 0x47, 0x33e: 0x48, 0x33f: 0x49, + // Block 0xd, offset 0x340 + 0x347: 0xc6, + 0x34b: 0xc7, 0x34d: 0xc8, + 0x368: 0xc9, 0x36b: 0xca, + // Block 0xe, offset 0x380 + 0x381: 0xcb, 0x382: 0xcc, 0x384: 0xcd, 0x385: 0xb7, 0x387: 0xce, + 0x388: 0xcf, 0x38b: 0xd0, 0x38c: 0x6b, 0x38d: 0xd1, + 0x391: 0xd2, 0x392: 0xd3, 0x393: 0xd4, 0x396: 0xd5, 0x397: 0xd6, + 0x398: 0xd7, 0x39a: 0xd8, 0x39c: 0xd9, + 0x3b0: 0xd7, + // Block 0xf, offset 0x3c0 + 0x3eb: 0xda, 0x3ec: 0xdb, + // Block 0x10, offset 0x400 + 0x432: 0xdc, + // Block 0x11, offset 0x440 + 0x445: 0xdd, 0x446: 0xde, 0x447: 0xdf, + 0x449: 0xe0, + 0x450: 0xe1, 0x451: 0xe2, 0x452: 0xe3, 0x453: 0xe4, 0x454: 0xe5, 0x455: 0xe6, 0x456: 0xe7, 0x457: 0xe8, + 0x458: 0xe9, 0x459: 0xea, 0x45a: 0x4a, 0x45b: 0xeb, 0x45c: 0xec, 0x45d: 0xed, 0x45e: 0xee, 0x45f: 0x4b, + // Block 0x12, offset 0x480 + 0x480: 0xef, + 0x4a3: 0xf0, 0x4a5: 0xf1, + 0x4b8: 0x4c, 0x4b9: 0x4d, 0x4ba: 0x4e, + // Block 0x13, offset 0x4c0 + 0x4c4: 0x4f, 0x4c5: 0xf2, 0x4c6: 0xf3, + 0x4c8: 0x50, 0x4c9: 0xf4, + // Block 0x14, offset 0x500 + 0x520: 0x51, 0x521: 0x52, 0x522: 0x53, 0x523: 0x54, 0x524: 0x55, 0x525: 0x56, 0x526: 0x57, 0x527: 0x58, + 0x528: 0x59, + // Block 0x15, offset 0x540 + 0x550: 0x0b, 0x551: 0x0c, 0x556: 0x0d, + 0x55b: 0x0e, 0x55d: 0x0f, 0x55e: 0x10, 0x55f: 0x11, + 0x56f: 0x12, +} + +// nfkcSparseOffset: 155 entries, 310 bytes +var nfkcSparseOffset = []uint16{0x0, 0xe, 0x12, 0x1b, 0x25, 0x35, 0x37, 0x3c, 0x47, 0x56, 0x63, 0x6b, 0x6f, 0x74, 0x76, 0x87, 0x8f, 0x96, 0x99, 0xa0, 0xa4, 0xa8, 0xaa, 0xac, 0xb5, 0xb9, 0xc0, 0xc5, 0xc8, 0xd2, 0xd4, 0xdb, 0xe3, 0xe7, 0xe9, 0xec, 0xf0, 0xf6, 0x107, 0x113, 0x115, 0x11b, 0x11d, 0x11f, 0x121, 0x123, 0x125, 0x127, 0x129, 0x12c, 0x12f, 0x131, 0x134, 0x137, 0x13b, 0x140, 0x149, 0x14b, 0x14e, 0x150, 0x15b, 0x166, 0x176, 0x184, 0x192, 0x1a2, 0x1b0, 0x1b7, 0x1bd, 0x1cc, 0x1d0, 0x1d2, 0x1d6, 0x1d8, 0x1db, 0x1dd, 0x1e0, 0x1e2, 0x1e5, 0x1e7, 0x1e9, 0x1eb, 0x1f7, 0x201, 0x20b, 0x20e, 0x212, 0x214, 0x216, 0x218, 0x21a, 0x21d, 0x21f, 0x221, 0x223, 0x225, 0x22b, 0x22e, 0x232, 0x234, 0x23b, 0x241, 0x247, 0x24f, 0x255, 0x25b, 0x261, 0x265, 0x267, 0x269, 0x26b, 0x26d, 0x273, 0x276, 0x279, 0x281, 0x288, 0x28b, 0x28e, 0x290, 0x298, 0x29b, 0x2a2, 0x2a5, 0x2ab, 0x2ad, 0x2af, 0x2b2, 0x2b4, 0x2b6, 0x2b8, 0x2ba, 0x2c7, 0x2d1, 0x2d3, 0x2d5, 0x2d9, 0x2de, 0x2ea, 0x2ef, 0x2f8, 0x2fe, 0x303, 0x307, 0x30c, 0x310, 0x320, 0x32e, 0x33c, 0x34a, 0x350, 0x352, 0x355, 0x35f, 0x361} + +// nfkcSparseValues: 875 entries, 3500 bytes +var nfkcSparseValues = [875]valueRange{ + // Block 0x0, offset 0x0 + {value: 0x0002, lo: 0x0d}, + {value: 0x0001, lo: 0xa0, hi: 0xa0}, + {value: 0x4278, lo: 0xa8, hi: 0xa8}, + {value: 0x0083, lo: 0xaa, hi: 0xaa}, + {value: 0x4264, lo: 0xaf, hi: 0xaf}, + {value: 0x0025, lo: 0xb2, hi: 0xb3}, + {value: 0x425a, lo: 0xb4, hi: 0xb4}, + {value: 0x01dc, lo: 0xb5, hi: 0xb5}, + {value: 0x4291, lo: 0xb8, hi: 0xb8}, + {value: 0x0023, lo: 0xb9, hi: 0xb9}, + {value: 0x009f, lo: 0xba, hi: 0xba}, + {value: 0x221c, lo: 0xbc, hi: 0xbc}, + {value: 0x2210, lo: 0xbd, hi: 0xbd}, + {value: 0x22b2, lo: 0xbe, hi: 0xbe}, + // Block 0x1, offset 0xe + {value: 0x0091, lo: 0x03}, + {value: 0x46e2, lo: 0xa0, hi: 0xa1}, + {value: 0x4714, lo: 0xaf, hi: 0xb0}, + {value: 0xa000, lo: 0xb7, hi: 0xb7}, + // Block 0x2, offset 0x12 + {value: 0x0003, lo: 0x08}, + {value: 0xa000, lo: 0x92, hi: 0x92}, + {value: 0x0091, lo: 0xb0, hi: 0xb0}, + {value: 0x0119, lo: 0xb1, hi: 0xb1}, + {value: 0x0095, lo: 0xb2, hi: 0xb2}, + {value: 0x00a5, lo: 0xb3, hi: 0xb3}, + {value: 0x0143, lo: 0xb4, hi: 0xb6}, + {value: 0x00af, lo: 0xb7, hi: 0xb7}, + {value: 0x00b3, lo: 0xb8, hi: 0xb8}, + // Block 0x3, offset 0x1b + {value: 0x000a, lo: 0x09}, + {value: 0x426e, lo: 0x98, hi: 0x98}, + {value: 0x4273, lo: 0x99, hi: 0x9a}, + {value: 0x4296, lo: 0x9b, hi: 0x9b}, + {value: 0x425f, lo: 0x9c, hi: 0x9c}, + {value: 0x4282, lo: 0x9d, hi: 0x9d}, + {value: 0x0113, lo: 0xa0, hi: 0xa0}, + {value: 0x0099, lo: 0xa1, hi: 0xa1}, + {value: 0x00a7, lo: 0xa2, hi: 0xa3}, + {value: 0x0167, lo: 0xa4, hi: 0xa4}, + // Block 0x4, offset 0x25 + {value: 0x0000, lo: 0x0f}, + {value: 0xa000, lo: 0x83, hi: 0x83}, + {value: 0xa000, lo: 0x87, hi: 0x87}, + {value: 0xa000, lo: 0x8b, hi: 0x8b}, + {value: 0xa000, lo: 0x8d, hi: 0x8d}, + {value: 0x37a5, lo: 0x90, hi: 0x90}, + {value: 0x37b1, lo: 0x91, hi: 0x91}, + {value: 0x379f, lo: 0x93, hi: 0x93}, + {value: 0xa000, lo: 0x96, hi: 0x96}, + {value: 0x3817, lo: 0x97, hi: 0x97}, + {value: 0x37e1, lo: 0x9c, hi: 0x9c}, + {value: 0x37c9, lo: 0x9d, hi: 0x9d}, + {value: 0x37f3, lo: 0x9e, hi: 0x9e}, + {value: 0xa000, lo: 0xb4, hi: 0xb5}, + {value: 0x381d, lo: 0xb6, hi: 0xb6}, + {value: 0x3823, lo: 0xb7, hi: 0xb7}, + // Block 0x5, offset 0x35 + {value: 0x0000, lo: 0x01}, + {value: 0x8132, lo: 0x83, hi: 0x87}, + // Block 0x6, offset 0x37 + {value: 0x0001, lo: 0x04}, + {value: 0x8113, lo: 0x81, hi: 0x82}, + {value: 0x8132, lo: 0x84, hi: 0x84}, + {value: 0x812d, lo: 0x85, hi: 0x85}, + {value: 0x810d, lo: 0x87, hi: 0x87}, + // Block 0x7, offset 0x3c + {value: 0x0000, lo: 0x0a}, + {value: 0x8132, lo: 0x90, hi: 0x97}, + {value: 0x8119, lo: 0x98, hi: 0x98}, + {value: 0x811a, lo: 0x99, hi: 0x99}, + {value: 0x811b, lo: 0x9a, hi: 0x9a}, + {value: 0x3841, lo: 0xa2, hi: 0xa2}, + {value: 0x3847, lo: 0xa3, hi: 0xa3}, + {value: 0x3853, lo: 0xa4, hi: 0xa4}, + {value: 0x384d, lo: 0xa5, hi: 0xa5}, + {value: 0x3859, lo: 0xa6, hi: 0xa6}, + {value: 0xa000, lo: 0xa7, hi: 0xa7}, + // Block 0x8, offset 0x47 + {value: 0x0000, lo: 0x0e}, + {value: 0x386b, lo: 0x80, hi: 0x80}, + {value: 0xa000, lo: 0x81, hi: 0x81}, + {value: 0x385f, lo: 0x82, hi: 0x82}, + {value: 0xa000, lo: 0x92, hi: 0x92}, + {value: 0x3865, lo: 0x93, hi: 0x93}, + {value: 0xa000, lo: 0x95, hi: 0x95}, + {value: 0x8132, lo: 0x96, hi: 0x9c}, + {value: 0x8132, lo: 0x9f, hi: 0xa2}, + {value: 0x812d, lo: 0xa3, hi: 0xa3}, + {value: 0x8132, lo: 0xa4, hi: 0xa4}, + {value: 0x8132, lo: 0xa7, hi: 0xa8}, + {value: 0x812d, lo: 0xaa, hi: 0xaa}, + {value: 0x8132, lo: 0xab, hi: 0xac}, + {value: 0x812d, lo: 0xad, hi: 0xad}, + // Block 0x9, offset 0x56 + {value: 0x0000, lo: 0x0c}, + {value: 0x811f, lo: 0x91, hi: 0x91}, + {value: 0x8132, lo: 0xb0, hi: 0xb0}, + {value: 0x812d, lo: 0xb1, hi: 0xb1}, + {value: 0x8132, lo: 0xb2, hi: 0xb3}, + {value: 0x812d, lo: 0xb4, hi: 0xb4}, + {value: 0x8132, lo: 0xb5, hi: 0xb6}, + {value: 0x812d, lo: 0xb7, hi: 0xb9}, + {value: 0x8132, lo: 0xba, hi: 0xba}, + {value: 0x812d, lo: 0xbb, hi: 0xbc}, + {value: 0x8132, lo: 0xbd, hi: 0xbd}, + {value: 0x812d, lo: 0xbe, hi: 0xbe}, + {value: 0x8132, lo: 0xbf, hi: 0xbf}, + // Block 0xa, offset 0x63 + {value: 0x0005, lo: 0x07}, + {value: 0x8132, lo: 0x80, hi: 0x80}, + {value: 0x8132, lo: 0x81, hi: 0x81}, + {value: 0x812d, lo: 0x82, hi: 0x83}, + {value: 0x812d, lo: 0x84, hi: 0x85}, + {value: 0x812d, lo: 0x86, hi: 0x87}, + {value: 0x812d, lo: 0x88, hi: 0x89}, + {value: 0x8132, lo: 0x8a, hi: 0x8a}, + // Block 0xb, offset 0x6b + {value: 0x0000, lo: 0x03}, + {value: 0x8132, lo: 0xab, hi: 0xb1}, + {value: 0x812d, lo: 0xb2, hi: 0xb2}, + {value: 0x8132, lo: 0xb3, hi: 0xb3}, + // Block 0xc, offset 0x6f + {value: 0x0000, lo: 0x04}, + {value: 0x8132, lo: 0x96, hi: 0x99}, + {value: 0x8132, lo: 0x9b, hi: 0xa3}, + {value: 0x8132, lo: 0xa5, hi: 0xa7}, + {value: 0x8132, lo: 0xa9, hi: 0xad}, + // Block 0xd, offset 0x74 + {value: 0x0000, lo: 0x01}, + {value: 0x812d, lo: 0x99, hi: 0x9b}, + // Block 0xe, offset 0x76 + {value: 0x0000, lo: 0x10}, + {value: 0x8132, lo: 0x94, hi: 0xa1}, + {value: 0x812d, lo: 0xa3, hi: 0xa3}, + {value: 0x8132, lo: 0xa4, hi: 0xa5}, + {value: 0x812d, lo: 0xa6, hi: 0xa6}, + {value: 0x8132, lo: 0xa7, hi: 0xa8}, + {value: 0x812d, lo: 0xa9, hi: 0xa9}, + {value: 0x8132, lo: 0xaa, hi: 0xac}, + {value: 0x812d, lo: 0xad, hi: 0xaf}, + {value: 0x8116, lo: 0xb0, hi: 0xb0}, + {value: 0x8117, lo: 0xb1, hi: 0xb1}, + {value: 0x8118, lo: 0xb2, hi: 0xb2}, + {value: 0x8132, lo: 0xb3, hi: 0xb5}, + {value: 0x812d, lo: 0xb6, hi: 0xb6}, + {value: 0x8132, lo: 0xb7, hi: 0xb8}, + {value: 0x812d, lo: 0xb9, hi: 0xba}, + {value: 0x8132, lo: 0xbb, hi: 0xbf}, + // Block 0xf, offset 0x87 + {value: 0x0000, lo: 0x07}, + {value: 0xa000, lo: 0xa8, hi: 0xa8}, + {value: 0x3ed8, lo: 0xa9, hi: 0xa9}, + {value: 0xa000, lo: 0xb0, hi: 0xb0}, + {value: 0x3ee0, lo: 0xb1, hi: 0xb1}, + {value: 0xa000, lo: 0xb3, hi: 0xb3}, + {value: 0x3ee8, lo: 0xb4, hi: 0xb4}, + {value: 0x9902, lo: 0xbc, hi: 0xbc}, + // Block 0x10, offset 0x8f + {value: 0x0008, lo: 0x06}, + {value: 0x8104, lo: 0x8d, hi: 0x8d}, + {value: 0x8132, lo: 0x91, hi: 0x91}, + {value: 0x812d, lo: 0x92, hi: 0x92}, + {value: 0x8132, lo: 0x93, hi: 0x93}, + {value: 0x8132, lo: 0x94, hi: 0x94}, + {value: 0x451c, lo: 0x98, hi: 0x9f}, + // Block 0x11, offset 0x96 + {value: 0x0000, lo: 0x02}, + {value: 0x8102, lo: 0xbc, hi: 0xbc}, + {value: 0x9900, lo: 0xbe, hi: 0xbe}, + // Block 0x12, offset 0x99 + {value: 0x0008, lo: 0x06}, + {value: 0xa000, lo: 0x87, hi: 0x87}, + {value: 0x2c9e, lo: 0x8b, hi: 0x8c}, + {value: 0x8104, lo: 0x8d, hi: 0x8d}, + {value: 0x9900, lo: 0x97, hi: 0x97}, + {value: 0x455c, lo: 0x9c, hi: 0x9d}, + {value: 0x456c, lo: 0x9f, hi: 0x9f}, + // Block 0x13, offset 0xa0 + {value: 0x0000, lo: 0x03}, + {value: 0x4594, lo: 0xb3, hi: 0xb3}, + {value: 0x459c, lo: 0xb6, hi: 0xb6}, + {value: 0x8102, lo: 0xbc, hi: 0xbc}, + // Block 0x14, offset 0xa4 + {value: 0x0008, lo: 0x03}, + {value: 0x8104, lo: 0x8d, hi: 0x8d}, + {value: 0x4574, lo: 0x99, hi: 0x9b}, + {value: 0x458c, lo: 0x9e, hi: 0x9e}, + // Block 0x15, offset 0xa8 + {value: 0x0000, lo: 0x01}, + {value: 0x8102, lo: 0xbc, hi: 0xbc}, + // Block 0x16, offset 0xaa + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0x8d, hi: 0x8d}, + // Block 0x17, offset 0xac + {value: 0x0000, lo: 0x08}, + {value: 0xa000, lo: 0x87, hi: 0x87}, + {value: 0x2cb6, lo: 0x88, hi: 0x88}, + {value: 0x2cae, lo: 0x8b, hi: 0x8b}, + {value: 0x2cbe, lo: 0x8c, hi: 0x8c}, + {value: 0x8104, lo: 0x8d, hi: 0x8d}, + {value: 0x9900, lo: 0x96, hi: 0x97}, + {value: 0x45a4, lo: 0x9c, hi: 0x9c}, + {value: 0x45ac, lo: 0x9d, hi: 0x9d}, + // Block 0x18, offset 0xb5 + {value: 0x0000, lo: 0x03}, + {value: 0xa000, lo: 0x92, hi: 0x92}, + {value: 0x2cc6, lo: 0x94, hi: 0x94}, + {value: 0x9900, lo: 0xbe, hi: 0xbe}, + // Block 0x19, offset 0xb9 + {value: 0x0000, lo: 0x06}, + {value: 0xa000, lo: 0x86, hi: 0x87}, + {value: 0x2cce, lo: 0x8a, hi: 0x8a}, + {value: 0x2cde, lo: 0x8b, hi: 0x8b}, + {value: 0x2cd6, lo: 0x8c, hi: 0x8c}, + {value: 0x8104, lo: 0x8d, hi: 0x8d}, + {value: 0x9900, lo: 0x97, hi: 0x97}, + // Block 0x1a, offset 0xc0 + {value: 0x1801, lo: 0x04}, + {value: 0xa000, lo: 0x86, hi: 0x86}, + {value: 0x3ef0, lo: 0x88, hi: 0x88}, + {value: 0x8104, lo: 0x8d, hi: 0x8d}, + {value: 0x8120, lo: 0x95, hi: 0x96}, + // Block 0x1b, offset 0xc5 + {value: 0x0000, lo: 0x02}, + {value: 0x8102, lo: 0xbc, hi: 0xbc}, + {value: 0xa000, lo: 0xbf, hi: 0xbf}, + // Block 0x1c, offset 0xc8 + {value: 0x0000, lo: 0x09}, + {value: 0x2ce6, lo: 0x80, hi: 0x80}, + {value: 0x9900, lo: 0x82, hi: 0x82}, + {value: 0xa000, lo: 0x86, hi: 0x86}, + {value: 0x2cee, lo: 0x87, hi: 0x87}, + {value: 0x2cf6, lo: 0x88, hi: 0x88}, + {value: 0x2f50, lo: 0x8a, hi: 0x8a}, + {value: 0x2dd8, lo: 0x8b, hi: 0x8b}, + {value: 0x8104, lo: 0x8d, hi: 0x8d}, + {value: 0x9900, lo: 0x95, hi: 0x96}, + // Block 0x1d, offset 0xd2 + {value: 0x0000, lo: 0x01}, + {value: 0x9900, lo: 0xbe, hi: 0xbe}, + // Block 0x1e, offset 0xd4 + {value: 0x0000, lo: 0x06}, + {value: 0xa000, lo: 0x86, hi: 0x87}, + {value: 0x2cfe, lo: 0x8a, hi: 0x8a}, + {value: 0x2d0e, lo: 0x8b, hi: 0x8b}, + {value: 0x2d06, lo: 0x8c, hi: 0x8c}, + {value: 0x8104, lo: 0x8d, hi: 0x8d}, + {value: 0x9900, lo: 0x97, hi: 0x97}, + // Block 0x1f, offset 0xdb + {value: 0x6bea, lo: 0x07}, + {value: 0x9904, lo: 0x8a, hi: 0x8a}, + {value: 0x9900, lo: 0x8f, hi: 0x8f}, + {value: 0xa000, lo: 0x99, hi: 0x99}, + {value: 0x3ef8, lo: 0x9a, hi: 0x9a}, + {value: 0x2f58, lo: 0x9c, hi: 0x9c}, + {value: 0x2de3, lo: 0x9d, hi: 0x9d}, + {value: 0x2d16, lo: 0x9e, hi: 0x9f}, + // Block 0x20, offset 0xe3 + {value: 0x0000, lo: 0x03}, + {value: 0x2621, lo: 0xb3, hi: 0xb3}, + {value: 0x8122, lo: 0xb8, hi: 0xb9}, + {value: 0x8104, lo: 0xba, hi: 0xba}, + // Block 0x21, offset 0xe7 + {value: 0x0000, lo: 0x01}, + {value: 0x8123, lo: 0x88, hi: 0x8b}, + // Block 0x22, offset 0xe9 + {value: 0x0000, lo: 0x02}, + {value: 0x2636, lo: 0xb3, hi: 0xb3}, + {value: 0x8124, lo: 0xb8, hi: 0xb9}, + // Block 0x23, offset 0xec + {value: 0x0000, lo: 0x03}, + {value: 0x8125, lo: 0x88, hi: 0x8b}, + {value: 0x2628, lo: 0x9c, hi: 0x9c}, + {value: 0x262f, lo: 0x9d, hi: 0x9d}, + // Block 0x24, offset 0xf0 + {value: 0x0000, lo: 0x05}, + {value: 0x030b, lo: 0x8c, hi: 0x8c}, + {value: 0x812d, lo: 0x98, hi: 0x99}, + {value: 0x812d, lo: 0xb5, hi: 0xb5}, + {value: 0x812d, lo: 0xb7, hi: 0xb7}, + {value: 0x812b, lo: 0xb9, hi: 0xb9}, + // Block 0x25, offset 0xf6 + {value: 0x0000, lo: 0x10}, + {value: 0x2644, lo: 0x83, hi: 0x83}, + {value: 0x264b, lo: 0x8d, hi: 0x8d}, + {value: 0x2652, lo: 0x92, hi: 0x92}, + {value: 0x2659, lo: 0x97, hi: 0x97}, + {value: 0x2660, lo: 0x9c, hi: 0x9c}, + {value: 0x263d, lo: 0xa9, hi: 0xa9}, + {value: 0x8126, lo: 0xb1, hi: 0xb1}, + {value: 0x8127, lo: 0xb2, hi: 0xb2}, + {value: 0x4a84, lo: 0xb3, hi: 0xb3}, + {value: 0x8128, lo: 0xb4, hi: 0xb4}, + {value: 0x4a8d, lo: 0xb5, hi: 0xb5}, + {value: 0x45b4, lo: 0xb6, hi: 0xb6}, + {value: 0x45f4, lo: 0xb7, hi: 0xb7}, + {value: 0x45bc, lo: 0xb8, hi: 0xb8}, + {value: 0x45ff, lo: 0xb9, hi: 0xb9}, + {value: 0x8127, lo: 0xba, hi: 0xbd}, + // Block 0x26, offset 0x107 + {value: 0x0000, lo: 0x0b}, + {value: 0x8127, lo: 0x80, hi: 0x80}, + {value: 0x4a96, lo: 0x81, hi: 0x81}, + {value: 0x8132, lo: 0x82, hi: 0x83}, + {value: 0x8104, lo: 0x84, hi: 0x84}, + {value: 0x8132, lo: 0x86, hi: 0x87}, + {value: 0x266e, lo: 0x93, hi: 0x93}, + {value: 0x2675, lo: 0x9d, hi: 0x9d}, + {value: 0x267c, lo: 0xa2, hi: 0xa2}, + {value: 0x2683, lo: 0xa7, hi: 0xa7}, + {value: 0x268a, lo: 0xac, hi: 0xac}, + {value: 0x2667, lo: 0xb9, hi: 0xb9}, + // Block 0x27, offset 0x113 + {value: 0x0000, lo: 0x01}, + {value: 0x812d, lo: 0x86, hi: 0x86}, + // Block 0x28, offset 0x115 + {value: 0x0000, lo: 0x05}, + {value: 0xa000, lo: 0xa5, hi: 0xa5}, + {value: 0x2d1e, lo: 0xa6, hi: 0xa6}, + {value: 0x9900, lo: 0xae, hi: 0xae}, + {value: 0x8102, lo: 0xb7, hi: 0xb7}, + {value: 0x8104, lo: 0xb9, hi: 0xba}, + // Block 0x29, offset 0x11b + {value: 0x0000, lo: 0x01}, + {value: 0x812d, lo: 0x8d, hi: 0x8d}, + // Block 0x2a, offset 0x11d + {value: 0x0000, lo: 0x01}, + {value: 0x030f, lo: 0xbc, hi: 0xbc}, + // Block 0x2b, offset 0x11f + {value: 0x0000, lo: 0x01}, + {value: 0xa000, lo: 0x80, hi: 0x92}, + // Block 0x2c, offset 0x121 + {value: 0x0000, lo: 0x01}, + {value: 0xb900, lo: 0xa1, hi: 0xb5}, + // Block 0x2d, offset 0x123 + {value: 0x0000, lo: 0x01}, + {value: 0x9900, lo: 0xa8, hi: 0xbf}, + // Block 0x2e, offset 0x125 + {value: 0x0000, lo: 0x01}, + {value: 0x9900, lo: 0x80, hi: 0x82}, + // Block 0x2f, offset 0x127 + {value: 0x0000, lo: 0x01}, + {value: 0x8132, lo: 0x9d, hi: 0x9f}, + // Block 0x30, offset 0x129 + {value: 0x0000, lo: 0x02}, + {value: 0x8104, lo: 0x94, hi: 0x94}, + {value: 0x8104, lo: 0xb4, hi: 0xb4}, + // Block 0x31, offset 0x12c + {value: 0x0000, lo: 0x02}, + {value: 0x8104, lo: 0x92, hi: 0x92}, + {value: 0x8132, lo: 0x9d, hi: 0x9d}, + // Block 0x32, offset 0x12f + {value: 0x0000, lo: 0x01}, + {value: 0x8131, lo: 0xa9, hi: 0xa9}, + // Block 0x33, offset 0x131 + {value: 0x0004, lo: 0x02}, + {value: 0x812e, lo: 0xb9, hi: 0xba}, + {value: 0x812d, lo: 0xbb, hi: 0xbb}, + // Block 0x34, offset 0x134 + {value: 0x0000, lo: 0x02}, + {value: 0x8132, lo: 0x97, hi: 0x97}, + {value: 0x812d, lo: 0x98, hi: 0x98}, + // Block 0x35, offset 0x137 + {value: 0x0000, lo: 0x03}, + {value: 0x8104, lo: 0xa0, hi: 0xa0}, + {value: 0x8132, lo: 0xb5, hi: 0xbc}, + {value: 0x812d, lo: 0xbf, hi: 0xbf}, + // Block 0x36, offset 0x13b + {value: 0x0000, lo: 0x04}, + {value: 0x8132, lo: 0xb0, hi: 0xb4}, + {value: 0x812d, lo: 0xb5, hi: 0xba}, + {value: 0x8132, lo: 0xbb, hi: 0xbc}, + {value: 0x812d, lo: 0xbd, hi: 0xbd}, + // Block 0x37, offset 0x140 + {value: 0x0000, lo: 0x08}, + {value: 0x2d66, lo: 0x80, hi: 0x80}, + {value: 0x2d6e, lo: 0x81, hi: 0x81}, + {value: 0xa000, lo: 0x82, hi: 0x82}, + {value: 0x2d76, lo: 0x83, hi: 0x83}, + {value: 0x8104, lo: 0x84, hi: 0x84}, + {value: 0x8132, lo: 0xab, hi: 0xab}, + {value: 0x812d, lo: 0xac, hi: 0xac}, + {value: 0x8132, lo: 0xad, hi: 0xb3}, + // Block 0x38, offset 0x149 + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0xaa, hi: 0xab}, + // Block 0x39, offset 0x14b + {value: 0x0000, lo: 0x02}, + {value: 0x8102, lo: 0xa6, hi: 0xa6}, + {value: 0x8104, lo: 0xb2, hi: 0xb3}, + // Block 0x3a, offset 0x14e + {value: 0x0000, lo: 0x01}, + {value: 0x8102, lo: 0xb7, hi: 0xb7}, + // Block 0x3b, offset 0x150 + {value: 0x0000, lo: 0x0a}, + {value: 0x8132, lo: 0x90, hi: 0x92}, + {value: 0x8101, lo: 0x94, hi: 0x94}, + {value: 0x812d, lo: 0x95, hi: 0x99}, + {value: 0x8132, lo: 0x9a, hi: 0x9b}, + {value: 0x812d, lo: 0x9c, hi: 0x9f}, + {value: 0x8132, lo: 0xa0, hi: 0xa0}, + {value: 0x8101, lo: 0xa2, hi: 0xa8}, + {value: 0x812d, lo: 0xad, hi: 0xad}, + {value: 0x8132, lo: 0xb4, hi: 0xb4}, + {value: 0x8132, lo: 0xb8, hi: 0xb9}, + // Block 0x3c, offset 0x15b + {value: 0x0002, lo: 0x0a}, + {value: 0x0043, lo: 0xac, hi: 0xac}, + {value: 0x00d1, lo: 0xad, hi: 0xad}, + {value: 0x0045, lo: 0xae, hi: 0xae}, + {value: 0x0049, lo: 0xb0, hi: 0xb1}, + {value: 0x00e6, lo: 0xb2, hi: 0xb2}, + {value: 0x004f, lo: 0xb3, hi: 0xba}, + {value: 0x005f, lo: 0xbc, hi: 0xbc}, + {value: 0x00ef, lo: 0xbd, hi: 0xbd}, + {value: 0x0061, lo: 0xbe, hi: 0xbe}, + {value: 0x0065, lo: 0xbf, hi: 0xbf}, + // Block 0x3d, offset 0x166 + {value: 0x0000, lo: 0x0f}, + {value: 0x8132, lo: 0x80, hi: 0x81}, + {value: 0x812d, lo: 0x82, hi: 0x82}, + {value: 0x8132, lo: 0x83, hi: 0x89}, + {value: 0x812d, lo: 0x8a, hi: 0x8a}, + {value: 0x8132, lo: 0x8b, hi: 0x8c}, + {value: 0x8135, lo: 0x8d, hi: 0x8d}, + {value: 0x812a, lo: 0x8e, hi: 0x8e}, + {value: 0x812d, lo: 0x8f, hi: 0x8f}, + {value: 0x8129, lo: 0x90, hi: 0x90}, + {value: 0x8132, lo: 0x91, hi: 0xb5}, + {value: 0x8132, lo: 0xbb, hi: 0xbb}, + {value: 0x8134, lo: 0xbc, hi: 0xbc}, + {value: 0x812d, lo: 0xbd, hi: 0xbd}, + {value: 0x8132, lo: 0xbe, hi: 0xbe}, + {value: 0x812d, lo: 0xbf, hi: 0xbf}, + // Block 0x3e, offset 0x176 + {value: 0x0000, lo: 0x0d}, + {value: 0x0001, lo: 0x80, hi: 0x8a}, + {value: 0x043b, lo: 0x91, hi: 0x91}, + {value: 0x429b, lo: 0x97, hi: 0x97}, + {value: 0x001d, lo: 0xa4, hi: 0xa4}, + {value: 0x1873, lo: 0xa5, hi: 0xa5}, + {value: 0x1b5c, lo: 0xa6, hi: 0xa6}, + {value: 0x0001, lo: 0xaf, hi: 0xaf}, + {value: 0x2691, lo: 0xb3, hi: 0xb3}, + {value: 0x27fe, lo: 0xb4, hi: 0xb4}, + {value: 0x2698, lo: 0xb6, hi: 0xb6}, + {value: 0x2808, lo: 0xb7, hi: 0xb7}, + {value: 0x186d, lo: 0xbc, hi: 0xbc}, + {value: 0x4269, lo: 0xbe, hi: 0xbe}, + // Block 0x3f, offset 0x184 + {value: 0x0002, lo: 0x0d}, + {value: 0x1933, lo: 0x87, hi: 0x87}, + {value: 0x1930, lo: 0x88, hi: 0x88}, + {value: 0x1870, lo: 0x89, hi: 0x89}, + {value: 0x298e, lo: 0x97, hi: 0x97}, + {value: 0x0001, lo: 0x9f, hi: 0x9f}, + {value: 0x0021, lo: 0xb0, hi: 0xb0}, + {value: 0x0093, lo: 0xb1, hi: 0xb1}, + {value: 0x0029, lo: 0xb4, hi: 0xb9}, + {value: 0x0017, lo: 0xba, hi: 0xba}, + {value: 0x0467, lo: 0xbb, hi: 0xbb}, + {value: 0x003b, lo: 0xbc, hi: 0xbc}, + {value: 0x0011, lo: 0xbd, hi: 0xbe}, + {value: 0x009d, lo: 0xbf, hi: 0xbf}, + // Block 0x40, offset 0x192 + {value: 0x0002, lo: 0x0f}, + {value: 0x0021, lo: 0x80, hi: 0x89}, + {value: 0x0017, lo: 0x8a, hi: 0x8a}, + {value: 0x0467, lo: 0x8b, hi: 0x8b}, + {value: 0x003b, lo: 0x8c, hi: 0x8c}, + {value: 0x0011, lo: 0x8d, hi: 0x8e}, + {value: 0x0083, lo: 0x90, hi: 0x90}, + {value: 0x008b, lo: 0x91, hi: 0x91}, + {value: 0x009f, lo: 0x92, hi: 0x92}, + {value: 0x00b1, lo: 0x93, hi: 0x93}, + {value: 0x0104, lo: 0x94, hi: 0x94}, + {value: 0x0091, lo: 0x95, hi: 0x95}, + {value: 0x0097, lo: 0x96, hi: 0x99}, + {value: 0x00a1, lo: 0x9a, hi: 0x9a}, + {value: 0x00a7, lo: 0x9b, hi: 0x9c}, + {value: 0x1999, lo: 0xa8, hi: 0xa8}, + // Block 0x41, offset 0x1a2 + {value: 0x0000, lo: 0x0d}, + {value: 0x8132, lo: 0x90, hi: 0x91}, + {value: 0x8101, lo: 0x92, hi: 0x93}, + {value: 0x8132, lo: 0x94, hi: 0x97}, + {value: 0x8101, lo: 0x98, hi: 0x9a}, + {value: 0x8132, lo: 0x9b, hi: 0x9c}, + {value: 0x8132, lo: 0xa1, hi: 0xa1}, + {value: 0x8101, lo: 0xa5, hi: 0xa6}, + {value: 0x8132, lo: 0xa7, hi: 0xa7}, + {value: 0x812d, lo: 0xa8, hi: 0xa8}, + {value: 0x8132, lo: 0xa9, hi: 0xa9}, + {value: 0x8101, lo: 0xaa, hi: 0xab}, + {value: 0x812d, lo: 0xac, hi: 0xaf}, + {value: 0x8132, lo: 0xb0, hi: 0xb0}, + // Block 0x42, offset 0x1b0 + {value: 0x0007, lo: 0x06}, + {value: 0x2180, lo: 0x89, hi: 0x89}, + {value: 0xa000, lo: 0x90, hi: 0x90}, + {value: 0xa000, lo: 0x92, hi: 0x92}, + {value: 0xa000, lo: 0x94, hi: 0x94}, + {value: 0x3bb9, lo: 0x9a, hi: 0x9b}, + {value: 0x3bc7, lo: 0xae, hi: 0xae}, + // Block 0x43, offset 0x1b7 + {value: 0x000e, lo: 0x05}, + {value: 0x3bce, lo: 0x8d, hi: 0x8e}, + {value: 0x3bd5, lo: 0x8f, hi: 0x8f}, + {value: 0xa000, lo: 0x90, hi: 0x90}, + {value: 0xa000, lo: 0x92, hi: 0x92}, + {value: 0xa000, lo: 0x94, hi: 0x94}, + // Block 0x44, offset 0x1bd + {value: 0x0173, lo: 0x0e}, + {value: 0xa000, lo: 0x83, hi: 0x83}, + {value: 0x3be3, lo: 0x84, hi: 0x84}, + {value: 0xa000, lo: 0x88, hi: 0x88}, + {value: 0x3bea, lo: 0x89, hi: 0x89}, + {value: 0xa000, lo: 0x8b, hi: 0x8b}, + {value: 0x3bf1, lo: 0x8c, hi: 0x8c}, + {value: 0xa000, lo: 0xa3, hi: 0xa3}, + {value: 0x3bf8, lo: 0xa4, hi: 0xa4}, + {value: 0xa000, lo: 0xa5, hi: 0xa5}, + {value: 0x3bff, lo: 0xa6, hi: 0xa6}, + {value: 0x269f, lo: 0xac, hi: 0xad}, + {value: 0x26a6, lo: 0xaf, hi: 0xaf}, + {value: 0x281c, lo: 0xb0, hi: 0xb0}, + {value: 0xa000, lo: 0xbc, hi: 0xbc}, + // Block 0x45, offset 0x1cc + {value: 0x0007, lo: 0x03}, + {value: 0x3c68, lo: 0xa0, hi: 0xa1}, + {value: 0x3c92, lo: 0xa2, hi: 0xa3}, + {value: 0x3cbc, lo: 0xaa, hi: 0xad}, + // Block 0x46, offset 0x1d0 + {value: 0x0004, lo: 0x01}, + {value: 0x048b, lo: 0xa9, hi: 0xaa}, + // Block 0x47, offset 0x1d2 + {value: 0x0002, lo: 0x03}, + {value: 0x0057, lo: 0x80, hi: 0x8f}, + {value: 0x0083, lo: 0x90, hi: 0xa9}, + {value: 0x0021, lo: 0xaa, hi: 0xaa}, + // Block 0x48, offset 0x1d6 + {value: 0x0000, lo: 0x01}, + {value: 0x299b, lo: 0x8c, hi: 0x8c}, + // Block 0x49, offset 0x1d8 + {value: 0x0263, lo: 0x02}, + {value: 0x1b8c, lo: 0xb4, hi: 0xb4}, + {value: 0x192d, lo: 0xb5, hi: 0xb6}, + // Block 0x4a, offset 0x1db + {value: 0x0000, lo: 0x01}, + {value: 0x44dd, lo: 0x9c, hi: 0x9c}, + // Block 0x4b, offset 0x1dd + {value: 0x0000, lo: 0x02}, + {value: 0x0095, lo: 0xbc, hi: 0xbc}, + {value: 0x006d, lo: 0xbd, hi: 0xbd}, + // Block 0x4c, offset 0x1e0 + {value: 0x0000, lo: 0x01}, + {value: 0x8132, lo: 0xaf, hi: 0xb1}, + // Block 0x4d, offset 0x1e2 + {value: 0x0000, lo: 0x02}, + {value: 0x047f, lo: 0xaf, hi: 0xaf}, + {value: 0x8104, lo: 0xbf, hi: 0xbf}, + // Block 0x4e, offset 0x1e5 + {value: 0x0000, lo: 0x01}, + {value: 0x8132, lo: 0xa0, hi: 0xbf}, + // Block 0x4f, offset 0x1e7 + {value: 0x0000, lo: 0x01}, + {value: 0x0dc3, lo: 0x9f, hi: 0x9f}, + // Block 0x50, offset 0x1e9 + {value: 0x0000, lo: 0x01}, + {value: 0x162f, lo: 0xb3, hi: 0xb3}, + // Block 0x51, offset 0x1eb + {value: 0x0004, lo: 0x0b}, + {value: 0x1597, lo: 0x80, hi: 0x82}, + {value: 0x15af, lo: 0x83, hi: 0x83}, + {value: 0x15c7, lo: 0x84, hi: 0x85}, + {value: 0x15d7, lo: 0x86, hi: 0x89}, + {value: 0x15eb, lo: 0x8a, hi: 0x8c}, + {value: 0x15ff, lo: 0x8d, hi: 0x8d}, + {value: 0x1607, lo: 0x8e, hi: 0x8e}, + {value: 0x160f, lo: 0x8f, hi: 0x90}, + {value: 0x161b, lo: 0x91, hi: 0x93}, + {value: 0x162b, lo: 0x94, hi: 0x94}, + {value: 0x1633, lo: 0x95, hi: 0x95}, + // Block 0x52, offset 0x1f7 + {value: 0x0004, lo: 0x09}, + {value: 0x0001, lo: 0x80, hi: 0x80}, + {value: 0x812c, lo: 0xaa, hi: 0xaa}, + {value: 0x8131, lo: 0xab, hi: 0xab}, + {value: 0x8133, lo: 0xac, hi: 0xac}, + {value: 0x812e, lo: 0xad, hi: 0xad}, + {value: 0x812f, lo: 0xae, hi: 0xae}, + {value: 0x812f, lo: 0xaf, hi: 0xaf}, + {value: 0x04b3, lo: 0xb6, hi: 0xb6}, + {value: 0x0887, lo: 0xb8, hi: 0xba}, + // Block 0x53, offset 0x201 + {value: 0x0006, lo: 0x09}, + {value: 0x0313, lo: 0xb1, hi: 0xb1}, + {value: 0x0317, lo: 0xb2, hi: 0xb2}, + {value: 0x4a3b, lo: 0xb3, hi: 0xb3}, + {value: 0x031b, lo: 0xb4, hi: 0xb4}, + {value: 0x4a41, lo: 0xb5, hi: 0xb6}, + {value: 0x031f, lo: 0xb7, hi: 0xb7}, + {value: 0x0323, lo: 0xb8, hi: 0xb8}, + {value: 0x0327, lo: 0xb9, hi: 0xb9}, + {value: 0x4a4d, lo: 0xba, hi: 0xbf}, + // Block 0x54, offset 0x20b + {value: 0x0000, lo: 0x02}, + {value: 0x8132, lo: 0xaf, hi: 0xaf}, + {value: 0x8132, lo: 0xb4, hi: 0xbd}, + // Block 0x55, offset 0x20e + {value: 0x0000, lo: 0x03}, + {value: 0x020f, lo: 0x9c, hi: 0x9c}, + {value: 0x0212, lo: 0x9d, hi: 0x9d}, + {value: 0x8132, lo: 0x9e, hi: 0x9f}, + // Block 0x56, offset 0x212 + {value: 0x0000, lo: 0x01}, + {value: 0x8132, lo: 0xb0, hi: 0xb1}, + // Block 0x57, offset 0x214 + {value: 0x0000, lo: 0x01}, + {value: 0x163b, lo: 0xb0, hi: 0xb0}, + // Block 0x58, offset 0x216 + {value: 0x000c, lo: 0x01}, + {value: 0x00d7, lo: 0xb8, hi: 0xb9}, + // Block 0x59, offset 0x218 + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0x86, hi: 0x86}, + // Block 0x5a, offset 0x21a + {value: 0x0000, lo: 0x02}, + {value: 0x8104, lo: 0x84, hi: 0x84}, + {value: 0x8132, lo: 0xa0, hi: 0xb1}, + // Block 0x5b, offset 0x21d + {value: 0x0000, lo: 0x01}, + {value: 0x812d, lo: 0xab, hi: 0xad}, + // Block 0x5c, offset 0x21f + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0x93, hi: 0x93}, + // Block 0x5d, offset 0x221 + {value: 0x0000, lo: 0x01}, + {value: 0x8102, lo: 0xb3, hi: 0xb3}, + // Block 0x5e, offset 0x223 + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0x80, hi: 0x80}, + // Block 0x5f, offset 0x225 + {value: 0x0000, lo: 0x05}, + {value: 0x8132, lo: 0xb0, hi: 0xb0}, + {value: 0x8132, lo: 0xb2, hi: 0xb3}, + {value: 0x812d, lo: 0xb4, hi: 0xb4}, + {value: 0x8132, lo: 0xb7, hi: 0xb8}, + {value: 0x8132, lo: 0xbe, hi: 0xbf}, + // Block 0x60, offset 0x22b + {value: 0x0000, lo: 0x02}, + {value: 0x8132, lo: 0x81, hi: 0x81}, + {value: 0x8104, lo: 0xb6, hi: 0xb6}, + // Block 0x61, offset 0x22e + {value: 0x0008, lo: 0x03}, + {value: 0x1637, lo: 0x9c, hi: 0x9d}, + {value: 0x0125, lo: 0x9e, hi: 0x9e}, + {value: 0x1643, lo: 0x9f, hi: 0x9f}, + // Block 0x62, offset 0x232 + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0xad, hi: 0xad}, + // Block 0x63, offset 0x234 + {value: 0x0000, lo: 0x06}, + {value: 0xe500, lo: 0x80, hi: 0x80}, + {value: 0xc600, lo: 0x81, hi: 0x9b}, + {value: 0xe500, lo: 0x9c, hi: 0x9c}, + {value: 0xc600, lo: 0x9d, hi: 0xb7}, + {value: 0xe500, lo: 0xb8, hi: 0xb8}, + {value: 0xc600, lo: 0xb9, hi: 0xbf}, + // Block 0x64, offset 0x23b + {value: 0x0000, lo: 0x05}, + {value: 0xc600, lo: 0x80, hi: 0x93}, + {value: 0xe500, lo: 0x94, hi: 0x94}, + {value: 0xc600, lo: 0x95, hi: 0xaf}, + {value: 0xe500, lo: 0xb0, hi: 0xb0}, + {value: 0xc600, lo: 0xb1, hi: 0xbf}, + // Block 0x65, offset 0x241 + {value: 0x0000, lo: 0x05}, + {value: 0xc600, lo: 0x80, hi: 0x8b}, + {value: 0xe500, lo: 0x8c, hi: 0x8c}, + {value: 0xc600, lo: 0x8d, hi: 0xa7}, + {value: 0xe500, lo: 0xa8, hi: 0xa8}, + {value: 0xc600, lo: 0xa9, hi: 0xbf}, + // Block 0x66, offset 0x247 + {value: 0x0000, lo: 0x07}, + {value: 0xc600, lo: 0x80, hi: 0x83}, + {value: 0xe500, lo: 0x84, hi: 0x84}, + {value: 0xc600, lo: 0x85, hi: 0x9f}, + {value: 0xe500, lo: 0xa0, hi: 0xa0}, + {value: 0xc600, lo: 0xa1, hi: 0xbb}, + {value: 0xe500, lo: 0xbc, hi: 0xbc}, + {value: 0xc600, lo: 0xbd, hi: 0xbf}, + // Block 0x67, offset 0x24f + {value: 0x0000, lo: 0x05}, + {value: 0xc600, lo: 0x80, hi: 0x97}, + {value: 0xe500, lo: 0x98, hi: 0x98}, + {value: 0xc600, lo: 0x99, hi: 0xb3}, + {value: 0xe500, lo: 0xb4, hi: 0xb4}, + {value: 0xc600, lo: 0xb5, hi: 0xbf}, + // Block 0x68, offset 0x255 + {value: 0x0000, lo: 0x05}, + {value: 0xc600, lo: 0x80, hi: 0x8f}, + {value: 0xe500, lo: 0x90, hi: 0x90}, + {value: 0xc600, lo: 0x91, hi: 0xab}, + {value: 0xe500, lo: 0xac, hi: 0xac}, + {value: 0xc600, lo: 0xad, hi: 0xbf}, + // Block 0x69, offset 0x25b + {value: 0x0000, lo: 0x05}, + {value: 0xc600, lo: 0x80, hi: 0x87}, + {value: 0xe500, lo: 0x88, hi: 0x88}, + {value: 0xc600, lo: 0x89, hi: 0xa3}, + {value: 0xe500, lo: 0xa4, hi: 0xa4}, + {value: 0xc600, lo: 0xa5, hi: 0xbf}, + // Block 0x6a, offset 0x261 + {value: 0x0000, lo: 0x03}, + {value: 0xc600, lo: 0x80, hi: 0x87}, + {value: 0xe500, lo: 0x88, hi: 0x88}, + {value: 0xc600, lo: 0x89, hi: 0xa3}, + // Block 0x6b, offset 0x265 + {value: 0x0002, lo: 0x01}, + {value: 0x0003, lo: 0x81, hi: 0xbf}, + // Block 0x6c, offset 0x267 + {value: 0x0000, lo: 0x01}, + {value: 0x812d, lo: 0xbd, hi: 0xbd}, + // Block 0x6d, offset 0x269 + {value: 0x0000, lo: 0x01}, + {value: 0x812d, lo: 0xa0, hi: 0xa0}, + // Block 0x6e, offset 0x26b + {value: 0x0000, lo: 0x01}, + {value: 0x8132, lo: 0xb6, hi: 0xba}, + // Block 0x6f, offset 0x26d + {value: 0x002c, lo: 0x05}, + {value: 0x812d, lo: 0x8d, hi: 0x8d}, + {value: 0x8132, lo: 0x8f, hi: 0x8f}, + {value: 0x8132, lo: 0xb8, hi: 0xb8}, + {value: 0x8101, lo: 0xb9, hi: 0xba}, + {value: 0x8104, lo: 0xbf, hi: 0xbf}, + // Block 0x70, offset 0x273 + {value: 0x0000, lo: 0x02}, + {value: 0x8132, lo: 0xa5, hi: 0xa5}, + {value: 0x812d, lo: 0xa6, hi: 0xa6}, + // Block 0x71, offset 0x276 + {value: 0x0000, lo: 0x02}, + {value: 0x8104, lo: 0x86, hi: 0x86}, + {value: 0x8104, lo: 0xbf, hi: 0xbf}, + // Block 0x72, offset 0x279 + {value: 0x17fe, lo: 0x07}, + {value: 0xa000, lo: 0x99, hi: 0x99}, + {value: 0x4238, lo: 0x9a, hi: 0x9a}, + {value: 0xa000, lo: 0x9b, hi: 0x9b}, + {value: 0x4242, lo: 0x9c, hi: 0x9c}, + {value: 0xa000, lo: 0xa5, hi: 0xa5}, + {value: 0x424c, lo: 0xab, hi: 0xab}, + {value: 0x8104, lo: 0xb9, hi: 0xba}, + // Block 0x73, offset 0x281 + {value: 0x0000, lo: 0x06}, + {value: 0x8132, lo: 0x80, hi: 0x82}, + {value: 0x9900, lo: 0xa7, hi: 0xa7}, + {value: 0x2d7e, lo: 0xae, hi: 0xae}, + {value: 0x2d88, lo: 0xaf, hi: 0xaf}, + {value: 0xa000, lo: 0xb1, hi: 0xb2}, + {value: 0x8104, lo: 0xb3, hi: 0xb4}, + // Block 0x74, offset 0x288 + {value: 0x0000, lo: 0x02}, + {value: 0x8104, lo: 0x80, hi: 0x80}, + {value: 0x8102, lo: 0x8a, hi: 0x8a}, + // Block 0x75, offset 0x28b + {value: 0x0000, lo: 0x02}, + {value: 0x8104, lo: 0xb5, hi: 0xb5}, + {value: 0x8102, lo: 0xb6, hi: 0xb6}, + // Block 0x76, offset 0x28e + {value: 0x0002, lo: 0x01}, + {value: 0x8102, lo: 0xa9, hi: 0xaa}, + // Block 0x77, offset 0x290 + {value: 0x0000, lo: 0x07}, + {value: 0xa000, lo: 0x87, hi: 0x87}, + {value: 0x2d92, lo: 0x8b, hi: 0x8b}, + {value: 0x2d9c, lo: 0x8c, hi: 0x8c}, + {value: 0x8104, lo: 0x8d, hi: 0x8d}, + {value: 0x9900, lo: 0x97, hi: 0x97}, + {value: 0x8132, lo: 0xa6, hi: 0xac}, + {value: 0x8132, lo: 0xb0, hi: 0xb4}, + // Block 0x78, offset 0x298 + {value: 0x0000, lo: 0x02}, + {value: 0x8104, lo: 0x82, hi: 0x82}, + {value: 0x8102, lo: 0x86, hi: 0x86}, + // Block 0x79, offset 0x29b + {value: 0x6b5a, lo: 0x06}, + {value: 0x9900, lo: 0xb0, hi: 0xb0}, + {value: 0xa000, lo: 0xb9, hi: 0xb9}, + {value: 0x9900, lo: 0xba, hi: 0xba}, + {value: 0x2db0, lo: 0xbb, hi: 0xbb}, + {value: 0x2da6, lo: 0xbc, hi: 0xbd}, + {value: 0x2dba, lo: 0xbe, hi: 0xbe}, + // Block 0x7a, offset 0x2a2 + {value: 0x0000, lo: 0x02}, + {value: 0x8104, lo: 0x82, hi: 0x82}, + {value: 0x8102, lo: 0x83, hi: 0x83}, + // Block 0x7b, offset 0x2a5 + {value: 0x0000, lo: 0x05}, + {value: 0x9900, lo: 0xaf, hi: 0xaf}, + {value: 0xa000, lo: 0xb8, hi: 0xb9}, + {value: 0x2dc4, lo: 0xba, hi: 0xba}, + {value: 0x2dce, lo: 0xbb, hi: 0xbb}, + {value: 0x8104, lo: 0xbf, hi: 0xbf}, + // Block 0x7c, offset 0x2ab + {value: 0x0000, lo: 0x01}, + {value: 0x8102, lo: 0x80, hi: 0x80}, + // Block 0x7d, offset 0x2ad + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0xbf, hi: 0xbf}, + // Block 0x7e, offset 0x2af + {value: 0x0000, lo: 0x02}, + {value: 0x8104, lo: 0xb6, hi: 0xb6}, + {value: 0x8102, lo: 0xb7, hi: 0xb7}, + // Block 0x7f, offset 0x2b2 + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0xab, hi: 0xab}, + // Block 0x80, offset 0x2b4 + {value: 0x0000, lo: 0x01}, + {value: 0x8101, lo: 0xb0, hi: 0xb4}, + // Block 0x81, offset 0x2b6 + {value: 0x0000, lo: 0x01}, + {value: 0x8132, lo: 0xb0, hi: 0xb6}, + // Block 0x82, offset 0x2b8 + {value: 0x0000, lo: 0x01}, + {value: 0x8101, lo: 0x9e, hi: 0x9e}, + // Block 0x83, offset 0x2ba + {value: 0x0000, lo: 0x0c}, + {value: 0x45cc, lo: 0x9e, hi: 0x9e}, + {value: 0x45d6, lo: 0x9f, hi: 0x9f}, + {value: 0x460a, lo: 0xa0, hi: 0xa0}, + {value: 0x4618, lo: 0xa1, hi: 0xa1}, + {value: 0x4626, lo: 0xa2, hi: 0xa2}, + {value: 0x4634, lo: 0xa3, hi: 0xa3}, + {value: 0x4642, lo: 0xa4, hi: 0xa4}, + {value: 0x812b, lo: 0xa5, hi: 0xa6}, + {value: 0x8101, lo: 0xa7, hi: 0xa9}, + {value: 0x8130, lo: 0xad, hi: 0xad}, + {value: 0x812b, lo: 0xae, hi: 0xb2}, + {value: 0x812d, lo: 0xbb, hi: 0xbf}, + // Block 0x84, offset 0x2c7 + {value: 0x0000, lo: 0x09}, + {value: 0x812d, lo: 0x80, hi: 0x82}, + {value: 0x8132, lo: 0x85, hi: 0x89}, + {value: 0x812d, lo: 0x8a, hi: 0x8b}, + {value: 0x8132, lo: 0xaa, hi: 0xad}, + {value: 0x45e0, lo: 0xbb, hi: 0xbb}, + {value: 0x45ea, lo: 0xbc, hi: 0xbc}, + {value: 0x4650, lo: 0xbd, hi: 0xbd}, + {value: 0x466c, lo: 0xbe, hi: 0xbe}, + {value: 0x465e, lo: 0xbf, hi: 0xbf}, + // Block 0x85, offset 0x2d1 + {value: 0x0000, lo: 0x01}, + {value: 0x467a, lo: 0x80, hi: 0x80}, + // Block 0x86, offset 0x2d3 + {value: 0x0000, lo: 0x01}, + {value: 0x8132, lo: 0x82, hi: 0x84}, + // Block 0x87, offset 0x2d5 + {value: 0x0002, lo: 0x03}, + {value: 0x0043, lo: 0x80, hi: 0x99}, + {value: 0x0083, lo: 0x9a, hi: 0xb3}, + {value: 0x0043, lo: 0xb4, hi: 0xbf}, + // Block 0x88, offset 0x2d9 + {value: 0x0002, lo: 0x04}, + {value: 0x005b, lo: 0x80, hi: 0x8d}, + {value: 0x0083, lo: 0x8e, hi: 0x94}, + {value: 0x0093, lo: 0x96, hi: 0xa7}, + {value: 0x0043, lo: 0xa8, hi: 0xbf}, + // Block 0x89, offset 0x2de + {value: 0x0002, lo: 0x0b}, + {value: 0x0073, lo: 0x80, hi: 0x81}, + {value: 0x0083, lo: 0x82, hi: 0x9b}, + {value: 0x0043, lo: 0x9c, hi: 0x9c}, + {value: 0x0047, lo: 0x9e, hi: 0x9f}, + {value: 0x004f, lo: 0xa2, hi: 0xa2}, + {value: 0x0055, lo: 0xa5, hi: 0xa6}, + {value: 0x005d, lo: 0xa9, hi: 0xac}, + {value: 0x0067, lo: 0xae, hi: 0xb5}, + {value: 0x0083, lo: 0xb6, hi: 0xb9}, + {value: 0x008d, lo: 0xbb, hi: 0xbb}, + {value: 0x0091, lo: 0xbd, hi: 0xbf}, + // Block 0x8a, offset 0x2ea + {value: 0x0002, lo: 0x04}, + {value: 0x0097, lo: 0x80, hi: 0x83}, + {value: 0x00a1, lo: 0x85, hi: 0x8f}, + {value: 0x0043, lo: 0x90, hi: 0xa9}, + {value: 0x0083, lo: 0xaa, hi: 0xbf}, + // Block 0x8b, offset 0x2ef + {value: 0x0002, lo: 0x08}, + {value: 0x00af, lo: 0x80, hi: 0x83}, + {value: 0x0043, lo: 0x84, hi: 0x85}, + {value: 0x0049, lo: 0x87, hi: 0x8a}, + {value: 0x0055, lo: 0x8d, hi: 0x94}, + {value: 0x0067, lo: 0x96, hi: 0x9c}, + {value: 0x0083, lo: 0x9e, hi: 0xb7}, + {value: 0x0043, lo: 0xb8, hi: 0xb9}, + {value: 0x0049, lo: 0xbb, hi: 0xbe}, + // Block 0x8c, offset 0x2f8 + {value: 0x0002, lo: 0x05}, + {value: 0x0053, lo: 0x80, hi: 0x84}, + {value: 0x005f, lo: 0x86, hi: 0x86}, + {value: 0x0067, lo: 0x8a, hi: 0x90}, + {value: 0x0083, lo: 0x92, hi: 0xab}, + {value: 0x0043, lo: 0xac, hi: 0xbf}, + // Block 0x8d, offset 0x2fe + {value: 0x0002, lo: 0x04}, + {value: 0x006b, lo: 0x80, hi: 0x85}, + {value: 0x0083, lo: 0x86, hi: 0x9f}, + {value: 0x0043, lo: 0xa0, hi: 0xb9}, + {value: 0x0083, lo: 0xba, hi: 0xbf}, + // Block 0x8e, offset 0x303 + {value: 0x0002, lo: 0x03}, + {value: 0x008f, lo: 0x80, hi: 0x93}, + {value: 0x0043, lo: 0x94, hi: 0xad}, + {value: 0x0083, lo: 0xae, hi: 0xbf}, + // Block 0x8f, offset 0x307 + {value: 0x0002, lo: 0x04}, + {value: 0x00a7, lo: 0x80, hi: 0x87}, + {value: 0x0043, lo: 0x88, hi: 0xa1}, + {value: 0x0083, lo: 0xa2, hi: 0xbb}, + {value: 0x0043, lo: 0xbc, hi: 0xbf}, + // Block 0x90, offset 0x30c + {value: 0x0002, lo: 0x03}, + {value: 0x004b, lo: 0x80, hi: 0x95}, + {value: 0x0083, lo: 0x96, hi: 0xaf}, + {value: 0x0043, lo: 0xb0, hi: 0xbf}, + // Block 0x91, offset 0x310 + {value: 0x0003, lo: 0x0f}, + {value: 0x01b8, lo: 0x80, hi: 0x80}, + {value: 0x045f, lo: 0x81, hi: 0x81}, + {value: 0x01bb, lo: 0x82, hi: 0x9a}, + {value: 0x045b, lo: 0x9b, hi: 0x9b}, + {value: 0x01c7, lo: 0x9c, hi: 0x9c}, + {value: 0x01d0, lo: 0x9d, hi: 0x9d}, + {value: 0x01d6, lo: 0x9e, hi: 0x9e}, + {value: 0x01fa, lo: 0x9f, hi: 0x9f}, + {value: 0x01eb, lo: 0xa0, hi: 0xa0}, + {value: 0x01e8, lo: 0xa1, hi: 0xa1}, + {value: 0x0173, lo: 0xa2, hi: 0xb2}, + {value: 0x0188, lo: 0xb3, hi: 0xb3}, + {value: 0x01a6, lo: 0xb4, hi: 0xba}, + {value: 0x045f, lo: 0xbb, hi: 0xbb}, + {value: 0x01bb, lo: 0xbc, hi: 0xbf}, + // Block 0x92, offset 0x320 + {value: 0x0003, lo: 0x0d}, + {value: 0x01c7, lo: 0x80, hi: 0x94}, + {value: 0x045b, lo: 0x95, hi: 0x95}, + {value: 0x01c7, lo: 0x96, hi: 0x96}, + {value: 0x01d0, lo: 0x97, hi: 0x97}, + {value: 0x01d6, lo: 0x98, hi: 0x98}, + {value: 0x01fa, lo: 0x99, hi: 0x99}, + {value: 0x01eb, lo: 0x9a, hi: 0x9a}, + {value: 0x01e8, lo: 0x9b, hi: 0x9b}, + {value: 0x0173, lo: 0x9c, hi: 0xac}, + {value: 0x0188, lo: 0xad, hi: 0xad}, + {value: 0x01a6, lo: 0xae, hi: 0xb4}, + {value: 0x045f, lo: 0xb5, hi: 0xb5}, + {value: 0x01bb, lo: 0xb6, hi: 0xbf}, + // Block 0x93, offset 0x32e + {value: 0x0003, lo: 0x0d}, + {value: 0x01d9, lo: 0x80, hi: 0x8e}, + {value: 0x045b, lo: 0x8f, hi: 0x8f}, + {value: 0x01c7, lo: 0x90, hi: 0x90}, + {value: 0x01d0, lo: 0x91, hi: 0x91}, + {value: 0x01d6, lo: 0x92, hi: 0x92}, + {value: 0x01fa, lo: 0x93, hi: 0x93}, + {value: 0x01eb, lo: 0x94, hi: 0x94}, + {value: 0x01e8, lo: 0x95, hi: 0x95}, + {value: 0x0173, lo: 0x96, hi: 0xa6}, + {value: 0x0188, lo: 0xa7, hi: 0xa7}, + {value: 0x01a6, lo: 0xa8, hi: 0xae}, + {value: 0x045f, lo: 0xaf, hi: 0xaf}, + {value: 0x01bb, lo: 0xb0, hi: 0xbf}, + // Block 0x94, offset 0x33c + {value: 0x0003, lo: 0x0d}, + {value: 0x01eb, lo: 0x80, hi: 0x88}, + {value: 0x045b, lo: 0x89, hi: 0x89}, + {value: 0x01c7, lo: 0x8a, hi: 0x8a}, + {value: 0x01d0, lo: 0x8b, hi: 0x8b}, + {value: 0x01d6, lo: 0x8c, hi: 0x8c}, + {value: 0x01fa, lo: 0x8d, hi: 0x8d}, + {value: 0x01eb, lo: 0x8e, hi: 0x8e}, + {value: 0x01e8, lo: 0x8f, hi: 0x8f}, + {value: 0x0173, lo: 0x90, hi: 0xa0}, + {value: 0x0188, lo: 0xa1, hi: 0xa1}, + {value: 0x01a6, lo: 0xa2, hi: 0xa8}, + {value: 0x045f, lo: 0xa9, hi: 0xa9}, + {value: 0x01bb, lo: 0xaa, hi: 0xbf}, + // Block 0x95, offset 0x34a + {value: 0x0000, lo: 0x05}, + {value: 0x8132, lo: 0x80, hi: 0x86}, + {value: 0x8132, lo: 0x88, hi: 0x98}, + {value: 0x8132, lo: 0x9b, hi: 0xa1}, + {value: 0x8132, lo: 0xa3, hi: 0xa4}, + {value: 0x8132, lo: 0xa6, hi: 0xaa}, + // Block 0x96, offset 0x350 + {value: 0x0000, lo: 0x01}, + {value: 0x812d, lo: 0x90, hi: 0x96}, + // Block 0x97, offset 0x352 + {value: 0x0000, lo: 0x02}, + {value: 0x8132, lo: 0x84, hi: 0x89}, + {value: 0x8102, lo: 0x8a, hi: 0x8a}, + // Block 0x98, offset 0x355 + {value: 0x0002, lo: 0x09}, + {value: 0x0063, lo: 0x80, hi: 0x89}, + {value: 0x1951, lo: 0x8a, hi: 0x8a}, + {value: 0x1981, lo: 0x8b, hi: 0x8b}, + {value: 0x199c, lo: 0x8c, hi: 0x8c}, + {value: 0x19a2, lo: 0x8d, hi: 0x8d}, + {value: 0x1bc0, lo: 0x8e, hi: 0x8e}, + {value: 0x19ae, lo: 0x8f, hi: 0x8f}, + {value: 0x197b, lo: 0xaa, hi: 0xaa}, + {value: 0x197e, lo: 0xab, hi: 0xab}, + // Block 0x99, offset 0x35f + {value: 0x0000, lo: 0x01}, + {value: 0x193f, lo: 0x90, hi: 0x90}, + // Block 0x9a, offset 0x361 + {value: 0x0028, lo: 0x09}, + {value: 0x2862, lo: 0x80, hi: 0x80}, + {value: 0x2826, lo: 0x81, hi: 0x81}, + {value: 0x2830, lo: 0x82, hi: 0x82}, + {value: 0x2844, lo: 0x83, hi: 0x84}, + {value: 0x284e, lo: 0x85, hi: 0x86}, + {value: 0x283a, lo: 0x87, hi: 0x87}, + {value: 0x2858, lo: 0x88, hi: 0x88}, + {value: 0x0b6f, lo: 0x90, hi: 0x90}, + {value: 0x08e7, lo: 0x91, hi: 0x91}, +} + +// recompMap: 7520 bytes (entries only) +var recompMap = map[uint32]rune{ + 0x00410300: 0x00C0, + 0x00410301: 0x00C1, + 0x00410302: 0x00C2, + 0x00410303: 0x00C3, + 0x00410308: 0x00C4, + 0x0041030A: 0x00C5, + 0x00430327: 0x00C7, + 0x00450300: 0x00C8, + 0x00450301: 0x00C9, + 0x00450302: 0x00CA, + 0x00450308: 0x00CB, + 0x00490300: 0x00CC, + 0x00490301: 0x00CD, + 0x00490302: 0x00CE, + 0x00490308: 0x00CF, + 0x004E0303: 0x00D1, + 0x004F0300: 0x00D2, + 0x004F0301: 0x00D3, + 0x004F0302: 0x00D4, + 0x004F0303: 0x00D5, + 0x004F0308: 0x00D6, + 0x00550300: 0x00D9, + 0x00550301: 0x00DA, + 0x00550302: 0x00DB, + 0x00550308: 0x00DC, + 0x00590301: 0x00DD, + 0x00610300: 0x00E0, + 0x00610301: 0x00E1, + 0x00610302: 0x00E2, + 0x00610303: 0x00E3, + 0x00610308: 0x00E4, + 0x0061030A: 0x00E5, + 0x00630327: 0x00E7, + 0x00650300: 0x00E8, + 0x00650301: 0x00E9, + 0x00650302: 0x00EA, + 0x00650308: 0x00EB, + 0x00690300: 0x00EC, + 0x00690301: 0x00ED, + 0x00690302: 0x00EE, + 0x00690308: 0x00EF, + 0x006E0303: 0x00F1, + 0x006F0300: 0x00F2, + 0x006F0301: 0x00F3, + 0x006F0302: 0x00F4, + 0x006F0303: 0x00F5, + 0x006F0308: 0x00F6, + 0x00750300: 0x00F9, + 0x00750301: 0x00FA, + 0x00750302: 0x00FB, + 0x00750308: 0x00FC, + 0x00790301: 0x00FD, + 0x00790308: 0x00FF, + 0x00410304: 0x0100, + 0x00610304: 0x0101, + 0x00410306: 0x0102, + 0x00610306: 0x0103, + 0x00410328: 0x0104, + 0x00610328: 0x0105, + 0x00430301: 0x0106, + 0x00630301: 0x0107, + 0x00430302: 0x0108, + 0x00630302: 0x0109, + 0x00430307: 0x010A, + 0x00630307: 0x010B, + 0x0043030C: 0x010C, + 0x0063030C: 0x010D, + 0x0044030C: 0x010E, + 0x0064030C: 0x010F, + 0x00450304: 0x0112, + 0x00650304: 0x0113, + 0x00450306: 0x0114, + 0x00650306: 0x0115, + 0x00450307: 0x0116, + 0x00650307: 0x0117, + 0x00450328: 0x0118, + 0x00650328: 0x0119, + 0x0045030C: 0x011A, + 0x0065030C: 0x011B, + 0x00470302: 0x011C, + 0x00670302: 0x011D, + 0x00470306: 0x011E, + 0x00670306: 0x011F, + 0x00470307: 0x0120, + 0x00670307: 0x0121, + 0x00470327: 0x0122, + 0x00670327: 0x0123, + 0x00480302: 0x0124, + 0x00680302: 0x0125, + 0x00490303: 0x0128, + 0x00690303: 0x0129, + 0x00490304: 0x012A, + 0x00690304: 0x012B, + 0x00490306: 0x012C, + 0x00690306: 0x012D, + 0x00490328: 0x012E, + 0x00690328: 0x012F, + 0x00490307: 0x0130, + 0x004A0302: 0x0134, + 0x006A0302: 0x0135, + 0x004B0327: 0x0136, + 0x006B0327: 0x0137, + 0x004C0301: 0x0139, + 0x006C0301: 0x013A, + 0x004C0327: 0x013B, + 0x006C0327: 0x013C, + 0x004C030C: 0x013D, + 0x006C030C: 0x013E, + 0x004E0301: 0x0143, + 0x006E0301: 0x0144, + 0x004E0327: 0x0145, + 0x006E0327: 0x0146, + 0x004E030C: 0x0147, + 0x006E030C: 0x0148, + 0x004F0304: 0x014C, + 0x006F0304: 0x014D, + 0x004F0306: 0x014E, + 0x006F0306: 0x014F, + 0x004F030B: 0x0150, + 0x006F030B: 0x0151, + 0x00520301: 0x0154, + 0x00720301: 0x0155, + 0x00520327: 0x0156, + 0x00720327: 0x0157, + 0x0052030C: 0x0158, + 0x0072030C: 0x0159, + 0x00530301: 0x015A, + 0x00730301: 0x015B, + 0x00530302: 0x015C, + 0x00730302: 0x015D, + 0x00530327: 0x015E, + 0x00730327: 0x015F, + 0x0053030C: 0x0160, + 0x0073030C: 0x0161, + 0x00540327: 0x0162, + 0x00740327: 0x0163, + 0x0054030C: 0x0164, + 0x0074030C: 0x0165, + 0x00550303: 0x0168, + 0x00750303: 0x0169, + 0x00550304: 0x016A, + 0x00750304: 0x016B, + 0x00550306: 0x016C, + 0x00750306: 0x016D, + 0x0055030A: 0x016E, + 0x0075030A: 0x016F, + 0x0055030B: 0x0170, + 0x0075030B: 0x0171, + 0x00550328: 0x0172, + 0x00750328: 0x0173, + 0x00570302: 0x0174, + 0x00770302: 0x0175, + 0x00590302: 0x0176, + 0x00790302: 0x0177, + 0x00590308: 0x0178, + 0x005A0301: 0x0179, + 0x007A0301: 0x017A, + 0x005A0307: 0x017B, + 0x007A0307: 0x017C, + 0x005A030C: 0x017D, + 0x007A030C: 0x017E, + 0x004F031B: 0x01A0, + 0x006F031B: 0x01A1, + 0x0055031B: 0x01AF, + 0x0075031B: 0x01B0, + 0x0041030C: 0x01CD, + 0x0061030C: 0x01CE, + 0x0049030C: 0x01CF, + 0x0069030C: 0x01D0, + 0x004F030C: 0x01D1, + 0x006F030C: 0x01D2, + 0x0055030C: 0x01D3, + 0x0075030C: 0x01D4, + 0x00DC0304: 0x01D5, + 0x00FC0304: 0x01D6, + 0x00DC0301: 0x01D7, + 0x00FC0301: 0x01D8, + 0x00DC030C: 0x01D9, + 0x00FC030C: 0x01DA, + 0x00DC0300: 0x01DB, + 0x00FC0300: 0x01DC, + 0x00C40304: 0x01DE, + 0x00E40304: 0x01DF, + 0x02260304: 0x01E0, + 0x02270304: 0x01E1, + 0x00C60304: 0x01E2, + 0x00E60304: 0x01E3, + 0x0047030C: 0x01E6, + 0x0067030C: 0x01E7, + 0x004B030C: 0x01E8, + 0x006B030C: 0x01E9, + 0x004F0328: 0x01EA, + 0x006F0328: 0x01EB, + 0x01EA0304: 0x01EC, + 0x01EB0304: 0x01ED, + 0x01B7030C: 0x01EE, + 0x0292030C: 0x01EF, + 0x006A030C: 0x01F0, + 0x00470301: 0x01F4, + 0x00670301: 0x01F5, + 0x004E0300: 0x01F8, + 0x006E0300: 0x01F9, + 0x00C50301: 0x01FA, + 0x00E50301: 0x01FB, + 0x00C60301: 0x01FC, + 0x00E60301: 0x01FD, + 0x00D80301: 0x01FE, + 0x00F80301: 0x01FF, + 0x0041030F: 0x0200, + 0x0061030F: 0x0201, + 0x00410311: 0x0202, + 0x00610311: 0x0203, + 0x0045030F: 0x0204, + 0x0065030F: 0x0205, + 0x00450311: 0x0206, + 0x00650311: 0x0207, + 0x0049030F: 0x0208, + 0x0069030F: 0x0209, + 0x00490311: 0x020A, + 0x00690311: 0x020B, + 0x004F030F: 0x020C, + 0x006F030F: 0x020D, + 0x004F0311: 0x020E, + 0x006F0311: 0x020F, + 0x0052030F: 0x0210, + 0x0072030F: 0x0211, + 0x00520311: 0x0212, + 0x00720311: 0x0213, + 0x0055030F: 0x0214, + 0x0075030F: 0x0215, + 0x00550311: 0x0216, + 0x00750311: 0x0217, + 0x00530326: 0x0218, + 0x00730326: 0x0219, + 0x00540326: 0x021A, + 0x00740326: 0x021B, + 0x0048030C: 0x021E, + 0x0068030C: 0x021F, + 0x00410307: 0x0226, + 0x00610307: 0x0227, + 0x00450327: 0x0228, + 0x00650327: 0x0229, + 0x00D60304: 0x022A, + 0x00F60304: 0x022B, + 0x00D50304: 0x022C, + 0x00F50304: 0x022D, + 0x004F0307: 0x022E, + 0x006F0307: 0x022F, + 0x022E0304: 0x0230, + 0x022F0304: 0x0231, + 0x00590304: 0x0232, + 0x00790304: 0x0233, + 0x00A80301: 0x0385, + 0x03910301: 0x0386, + 0x03950301: 0x0388, + 0x03970301: 0x0389, + 0x03990301: 0x038A, + 0x039F0301: 0x038C, + 0x03A50301: 0x038E, + 0x03A90301: 0x038F, + 0x03CA0301: 0x0390, + 0x03990308: 0x03AA, + 0x03A50308: 0x03AB, + 0x03B10301: 0x03AC, + 0x03B50301: 0x03AD, + 0x03B70301: 0x03AE, + 0x03B90301: 0x03AF, + 0x03CB0301: 0x03B0, + 0x03B90308: 0x03CA, + 0x03C50308: 0x03CB, + 0x03BF0301: 0x03CC, + 0x03C50301: 0x03CD, + 0x03C90301: 0x03CE, + 0x03D20301: 0x03D3, + 0x03D20308: 0x03D4, + 0x04150300: 0x0400, + 0x04150308: 0x0401, + 0x04130301: 0x0403, + 0x04060308: 0x0407, + 0x041A0301: 0x040C, + 0x04180300: 0x040D, + 0x04230306: 0x040E, + 0x04180306: 0x0419, + 0x04380306: 0x0439, + 0x04350300: 0x0450, + 0x04350308: 0x0451, + 0x04330301: 0x0453, + 0x04560308: 0x0457, + 0x043A0301: 0x045C, + 0x04380300: 0x045D, + 0x04430306: 0x045E, + 0x0474030F: 0x0476, + 0x0475030F: 0x0477, + 0x04160306: 0x04C1, + 0x04360306: 0x04C2, + 0x04100306: 0x04D0, + 0x04300306: 0x04D1, + 0x04100308: 0x04D2, + 0x04300308: 0x04D3, + 0x04150306: 0x04D6, + 0x04350306: 0x04D7, + 0x04D80308: 0x04DA, + 0x04D90308: 0x04DB, + 0x04160308: 0x04DC, + 0x04360308: 0x04DD, + 0x04170308: 0x04DE, + 0x04370308: 0x04DF, + 0x04180304: 0x04E2, + 0x04380304: 0x04E3, + 0x04180308: 0x04E4, + 0x04380308: 0x04E5, + 0x041E0308: 0x04E6, + 0x043E0308: 0x04E7, + 0x04E80308: 0x04EA, + 0x04E90308: 0x04EB, + 0x042D0308: 0x04EC, + 0x044D0308: 0x04ED, + 0x04230304: 0x04EE, + 0x04430304: 0x04EF, + 0x04230308: 0x04F0, + 0x04430308: 0x04F1, + 0x0423030B: 0x04F2, + 0x0443030B: 0x04F3, + 0x04270308: 0x04F4, + 0x04470308: 0x04F5, + 0x042B0308: 0x04F8, + 0x044B0308: 0x04F9, + 0x06270653: 0x0622, + 0x06270654: 0x0623, + 0x06480654: 0x0624, + 0x06270655: 0x0625, + 0x064A0654: 0x0626, + 0x06D50654: 0x06C0, + 0x06C10654: 0x06C2, + 0x06D20654: 0x06D3, + 0x0928093C: 0x0929, + 0x0930093C: 0x0931, + 0x0933093C: 0x0934, + 0x09C709BE: 0x09CB, + 0x09C709D7: 0x09CC, + 0x0B470B56: 0x0B48, + 0x0B470B3E: 0x0B4B, + 0x0B470B57: 0x0B4C, + 0x0B920BD7: 0x0B94, + 0x0BC60BBE: 0x0BCA, + 0x0BC70BBE: 0x0BCB, + 0x0BC60BD7: 0x0BCC, + 0x0C460C56: 0x0C48, + 0x0CBF0CD5: 0x0CC0, + 0x0CC60CD5: 0x0CC7, + 0x0CC60CD6: 0x0CC8, + 0x0CC60CC2: 0x0CCA, + 0x0CCA0CD5: 0x0CCB, + 0x0D460D3E: 0x0D4A, + 0x0D470D3E: 0x0D4B, + 0x0D460D57: 0x0D4C, + 0x0DD90DCA: 0x0DDA, + 0x0DD90DCF: 0x0DDC, + 0x0DDC0DCA: 0x0DDD, + 0x0DD90DDF: 0x0DDE, + 0x1025102E: 0x1026, + 0x1B051B35: 0x1B06, + 0x1B071B35: 0x1B08, + 0x1B091B35: 0x1B0A, + 0x1B0B1B35: 0x1B0C, + 0x1B0D1B35: 0x1B0E, + 0x1B111B35: 0x1B12, + 0x1B3A1B35: 0x1B3B, + 0x1B3C1B35: 0x1B3D, + 0x1B3E1B35: 0x1B40, + 0x1B3F1B35: 0x1B41, + 0x1B421B35: 0x1B43, + 0x00410325: 0x1E00, + 0x00610325: 0x1E01, + 0x00420307: 0x1E02, + 0x00620307: 0x1E03, + 0x00420323: 0x1E04, + 0x00620323: 0x1E05, + 0x00420331: 0x1E06, + 0x00620331: 0x1E07, + 0x00C70301: 0x1E08, + 0x00E70301: 0x1E09, + 0x00440307: 0x1E0A, + 0x00640307: 0x1E0B, + 0x00440323: 0x1E0C, + 0x00640323: 0x1E0D, + 0x00440331: 0x1E0E, + 0x00640331: 0x1E0F, + 0x00440327: 0x1E10, + 0x00640327: 0x1E11, + 0x0044032D: 0x1E12, + 0x0064032D: 0x1E13, + 0x01120300: 0x1E14, + 0x01130300: 0x1E15, + 0x01120301: 0x1E16, + 0x01130301: 0x1E17, + 0x0045032D: 0x1E18, + 0x0065032D: 0x1E19, + 0x00450330: 0x1E1A, + 0x00650330: 0x1E1B, + 0x02280306: 0x1E1C, + 0x02290306: 0x1E1D, + 0x00460307: 0x1E1E, + 0x00660307: 0x1E1F, + 0x00470304: 0x1E20, + 0x00670304: 0x1E21, + 0x00480307: 0x1E22, + 0x00680307: 0x1E23, + 0x00480323: 0x1E24, + 0x00680323: 0x1E25, + 0x00480308: 0x1E26, + 0x00680308: 0x1E27, + 0x00480327: 0x1E28, + 0x00680327: 0x1E29, + 0x0048032E: 0x1E2A, + 0x0068032E: 0x1E2B, + 0x00490330: 0x1E2C, + 0x00690330: 0x1E2D, + 0x00CF0301: 0x1E2E, + 0x00EF0301: 0x1E2F, + 0x004B0301: 0x1E30, + 0x006B0301: 0x1E31, + 0x004B0323: 0x1E32, + 0x006B0323: 0x1E33, + 0x004B0331: 0x1E34, + 0x006B0331: 0x1E35, + 0x004C0323: 0x1E36, + 0x006C0323: 0x1E37, + 0x1E360304: 0x1E38, + 0x1E370304: 0x1E39, + 0x004C0331: 0x1E3A, + 0x006C0331: 0x1E3B, + 0x004C032D: 0x1E3C, + 0x006C032D: 0x1E3D, + 0x004D0301: 0x1E3E, + 0x006D0301: 0x1E3F, + 0x004D0307: 0x1E40, + 0x006D0307: 0x1E41, + 0x004D0323: 0x1E42, + 0x006D0323: 0x1E43, + 0x004E0307: 0x1E44, + 0x006E0307: 0x1E45, + 0x004E0323: 0x1E46, + 0x006E0323: 0x1E47, + 0x004E0331: 0x1E48, + 0x006E0331: 0x1E49, + 0x004E032D: 0x1E4A, + 0x006E032D: 0x1E4B, + 0x00D50301: 0x1E4C, + 0x00F50301: 0x1E4D, + 0x00D50308: 0x1E4E, + 0x00F50308: 0x1E4F, + 0x014C0300: 0x1E50, + 0x014D0300: 0x1E51, + 0x014C0301: 0x1E52, + 0x014D0301: 0x1E53, + 0x00500301: 0x1E54, + 0x00700301: 0x1E55, + 0x00500307: 0x1E56, + 0x00700307: 0x1E57, + 0x00520307: 0x1E58, + 0x00720307: 0x1E59, + 0x00520323: 0x1E5A, + 0x00720323: 0x1E5B, + 0x1E5A0304: 0x1E5C, + 0x1E5B0304: 0x1E5D, + 0x00520331: 0x1E5E, + 0x00720331: 0x1E5F, + 0x00530307: 0x1E60, + 0x00730307: 0x1E61, + 0x00530323: 0x1E62, + 0x00730323: 0x1E63, + 0x015A0307: 0x1E64, + 0x015B0307: 0x1E65, + 0x01600307: 0x1E66, + 0x01610307: 0x1E67, + 0x1E620307: 0x1E68, + 0x1E630307: 0x1E69, + 0x00540307: 0x1E6A, + 0x00740307: 0x1E6B, + 0x00540323: 0x1E6C, + 0x00740323: 0x1E6D, + 0x00540331: 0x1E6E, + 0x00740331: 0x1E6F, + 0x0054032D: 0x1E70, + 0x0074032D: 0x1E71, + 0x00550324: 0x1E72, + 0x00750324: 0x1E73, + 0x00550330: 0x1E74, + 0x00750330: 0x1E75, + 0x0055032D: 0x1E76, + 0x0075032D: 0x1E77, + 0x01680301: 0x1E78, + 0x01690301: 0x1E79, + 0x016A0308: 0x1E7A, + 0x016B0308: 0x1E7B, + 0x00560303: 0x1E7C, + 0x00760303: 0x1E7D, + 0x00560323: 0x1E7E, + 0x00760323: 0x1E7F, + 0x00570300: 0x1E80, + 0x00770300: 0x1E81, + 0x00570301: 0x1E82, + 0x00770301: 0x1E83, + 0x00570308: 0x1E84, + 0x00770308: 0x1E85, + 0x00570307: 0x1E86, + 0x00770307: 0x1E87, + 0x00570323: 0x1E88, + 0x00770323: 0x1E89, + 0x00580307: 0x1E8A, + 0x00780307: 0x1E8B, + 0x00580308: 0x1E8C, + 0x00780308: 0x1E8D, + 0x00590307: 0x1E8E, + 0x00790307: 0x1E8F, + 0x005A0302: 0x1E90, + 0x007A0302: 0x1E91, + 0x005A0323: 0x1E92, + 0x007A0323: 0x1E93, + 0x005A0331: 0x1E94, + 0x007A0331: 0x1E95, + 0x00680331: 0x1E96, + 0x00740308: 0x1E97, + 0x0077030A: 0x1E98, + 0x0079030A: 0x1E99, + 0x017F0307: 0x1E9B, + 0x00410323: 0x1EA0, + 0x00610323: 0x1EA1, + 0x00410309: 0x1EA2, + 0x00610309: 0x1EA3, + 0x00C20301: 0x1EA4, + 0x00E20301: 0x1EA5, + 0x00C20300: 0x1EA6, + 0x00E20300: 0x1EA7, + 0x00C20309: 0x1EA8, + 0x00E20309: 0x1EA9, + 0x00C20303: 0x1EAA, + 0x00E20303: 0x1EAB, + 0x1EA00302: 0x1EAC, + 0x1EA10302: 0x1EAD, + 0x01020301: 0x1EAE, + 0x01030301: 0x1EAF, + 0x01020300: 0x1EB0, + 0x01030300: 0x1EB1, + 0x01020309: 0x1EB2, + 0x01030309: 0x1EB3, + 0x01020303: 0x1EB4, + 0x01030303: 0x1EB5, + 0x1EA00306: 0x1EB6, + 0x1EA10306: 0x1EB7, + 0x00450323: 0x1EB8, + 0x00650323: 0x1EB9, + 0x00450309: 0x1EBA, + 0x00650309: 0x1EBB, + 0x00450303: 0x1EBC, + 0x00650303: 0x1EBD, + 0x00CA0301: 0x1EBE, + 0x00EA0301: 0x1EBF, + 0x00CA0300: 0x1EC0, + 0x00EA0300: 0x1EC1, + 0x00CA0309: 0x1EC2, + 0x00EA0309: 0x1EC3, + 0x00CA0303: 0x1EC4, + 0x00EA0303: 0x1EC5, + 0x1EB80302: 0x1EC6, + 0x1EB90302: 0x1EC7, + 0x00490309: 0x1EC8, + 0x00690309: 0x1EC9, + 0x00490323: 0x1ECA, + 0x00690323: 0x1ECB, + 0x004F0323: 0x1ECC, + 0x006F0323: 0x1ECD, + 0x004F0309: 0x1ECE, + 0x006F0309: 0x1ECF, + 0x00D40301: 0x1ED0, + 0x00F40301: 0x1ED1, + 0x00D40300: 0x1ED2, + 0x00F40300: 0x1ED3, + 0x00D40309: 0x1ED4, + 0x00F40309: 0x1ED5, + 0x00D40303: 0x1ED6, + 0x00F40303: 0x1ED7, + 0x1ECC0302: 0x1ED8, + 0x1ECD0302: 0x1ED9, + 0x01A00301: 0x1EDA, + 0x01A10301: 0x1EDB, + 0x01A00300: 0x1EDC, + 0x01A10300: 0x1EDD, + 0x01A00309: 0x1EDE, + 0x01A10309: 0x1EDF, + 0x01A00303: 0x1EE0, + 0x01A10303: 0x1EE1, + 0x01A00323: 0x1EE2, + 0x01A10323: 0x1EE3, + 0x00550323: 0x1EE4, + 0x00750323: 0x1EE5, + 0x00550309: 0x1EE6, + 0x00750309: 0x1EE7, + 0x01AF0301: 0x1EE8, + 0x01B00301: 0x1EE9, + 0x01AF0300: 0x1EEA, + 0x01B00300: 0x1EEB, + 0x01AF0309: 0x1EEC, + 0x01B00309: 0x1EED, + 0x01AF0303: 0x1EEE, + 0x01B00303: 0x1EEF, + 0x01AF0323: 0x1EF0, + 0x01B00323: 0x1EF1, + 0x00590300: 0x1EF2, + 0x00790300: 0x1EF3, + 0x00590323: 0x1EF4, + 0x00790323: 0x1EF5, + 0x00590309: 0x1EF6, + 0x00790309: 0x1EF7, + 0x00590303: 0x1EF8, + 0x00790303: 0x1EF9, + 0x03B10313: 0x1F00, + 0x03B10314: 0x1F01, + 0x1F000300: 0x1F02, + 0x1F010300: 0x1F03, + 0x1F000301: 0x1F04, + 0x1F010301: 0x1F05, + 0x1F000342: 0x1F06, + 0x1F010342: 0x1F07, + 0x03910313: 0x1F08, + 0x03910314: 0x1F09, + 0x1F080300: 0x1F0A, + 0x1F090300: 0x1F0B, + 0x1F080301: 0x1F0C, + 0x1F090301: 0x1F0D, + 0x1F080342: 0x1F0E, + 0x1F090342: 0x1F0F, + 0x03B50313: 0x1F10, + 0x03B50314: 0x1F11, + 0x1F100300: 0x1F12, + 0x1F110300: 0x1F13, + 0x1F100301: 0x1F14, + 0x1F110301: 0x1F15, + 0x03950313: 0x1F18, + 0x03950314: 0x1F19, + 0x1F180300: 0x1F1A, + 0x1F190300: 0x1F1B, + 0x1F180301: 0x1F1C, + 0x1F190301: 0x1F1D, + 0x03B70313: 0x1F20, + 0x03B70314: 0x1F21, + 0x1F200300: 0x1F22, + 0x1F210300: 0x1F23, + 0x1F200301: 0x1F24, + 0x1F210301: 0x1F25, + 0x1F200342: 0x1F26, + 0x1F210342: 0x1F27, + 0x03970313: 0x1F28, + 0x03970314: 0x1F29, + 0x1F280300: 0x1F2A, + 0x1F290300: 0x1F2B, + 0x1F280301: 0x1F2C, + 0x1F290301: 0x1F2D, + 0x1F280342: 0x1F2E, + 0x1F290342: 0x1F2F, + 0x03B90313: 0x1F30, + 0x03B90314: 0x1F31, + 0x1F300300: 0x1F32, + 0x1F310300: 0x1F33, + 0x1F300301: 0x1F34, + 0x1F310301: 0x1F35, + 0x1F300342: 0x1F36, + 0x1F310342: 0x1F37, + 0x03990313: 0x1F38, + 0x03990314: 0x1F39, + 0x1F380300: 0x1F3A, + 0x1F390300: 0x1F3B, + 0x1F380301: 0x1F3C, + 0x1F390301: 0x1F3D, + 0x1F380342: 0x1F3E, + 0x1F390342: 0x1F3F, + 0x03BF0313: 0x1F40, + 0x03BF0314: 0x1F41, + 0x1F400300: 0x1F42, + 0x1F410300: 0x1F43, + 0x1F400301: 0x1F44, + 0x1F410301: 0x1F45, + 0x039F0313: 0x1F48, + 0x039F0314: 0x1F49, + 0x1F480300: 0x1F4A, + 0x1F490300: 0x1F4B, + 0x1F480301: 0x1F4C, + 0x1F490301: 0x1F4D, + 0x03C50313: 0x1F50, + 0x03C50314: 0x1F51, + 0x1F500300: 0x1F52, + 0x1F510300: 0x1F53, + 0x1F500301: 0x1F54, + 0x1F510301: 0x1F55, + 0x1F500342: 0x1F56, + 0x1F510342: 0x1F57, + 0x03A50314: 0x1F59, + 0x1F590300: 0x1F5B, + 0x1F590301: 0x1F5D, + 0x1F590342: 0x1F5F, + 0x03C90313: 0x1F60, + 0x03C90314: 0x1F61, + 0x1F600300: 0x1F62, + 0x1F610300: 0x1F63, + 0x1F600301: 0x1F64, + 0x1F610301: 0x1F65, + 0x1F600342: 0x1F66, + 0x1F610342: 0x1F67, + 0x03A90313: 0x1F68, + 0x03A90314: 0x1F69, + 0x1F680300: 0x1F6A, + 0x1F690300: 0x1F6B, + 0x1F680301: 0x1F6C, + 0x1F690301: 0x1F6D, + 0x1F680342: 0x1F6E, + 0x1F690342: 0x1F6F, + 0x03B10300: 0x1F70, + 0x03B50300: 0x1F72, + 0x03B70300: 0x1F74, + 0x03B90300: 0x1F76, + 0x03BF0300: 0x1F78, + 0x03C50300: 0x1F7A, + 0x03C90300: 0x1F7C, + 0x1F000345: 0x1F80, + 0x1F010345: 0x1F81, + 0x1F020345: 0x1F82, + 0x1F030345: 0x1F83, + 0x1F040345: 0x1F84, + 0x1F050345: 0x1F85, + 0x1F060345: 0x1F86, + 0x1F070345: 0x1F87, + 0x1F080345: 0x1F88, + 0x1F090345: 0x1F89, + 0x1F0A0345: 0x1F8A, + 0x1F0B0345: 0x1F8B, + 0x1F0C0345: 0x1F8C, + 0x1F0D0345: 0x1F8D, + 0x1F0E0345: 0x1F8E, + 0x1F0F0345: 0x1F8F, + 0x1F200345: 0x1F90, + 0x1F210345: 0x1F91, + 0x1F220345: 0x1F92, + 0x1F230345: 0x1F93, + 0x1F240345: 0x1F94, + 0x1F250345: 0x1F95, + 0x1F260345: 0x1F96, + 0x1F270345: 0x1F97, + 0x1F280345: 0x1F98, + 0x1F290345: 0x1F99, + 0x1F2A0345: 0x1F9A, + 0x1F2B0345: 0x1F9B, + 0x1F2C0345: 0x1F9C, + 0x1F2D0345: 0x1F9D, + 0x1F2E0345: 0x1F9E, + 0x1F2F0345: 0x1F9F, + 0x1F600345: 0x1FA0, + 0x1F610345: 0x1FA1, + 0x1F620345: 0x1FA2, + 0x1F630345: 0x1FA3, + 0x1F640345: 0x1FA4, + 0x1F650345: 0x1FA5, + 0x1F660345: 0x1FA6, + 0x1F670345: 0x1FA7, + 0x1F680345: 0x1FA8, + 0x1F690345: 0x1FA9, + 0x1F6A0345: 0x1FAA, + 0x1F6B0345: 0x1FAB, + 0x1F6C0345: 0x1FAC, + 0x1F6D0345: 0x1FAD, + 0x1F6E0345: 0x1FAE, + 0x1F6F0345: 0x1FAF, + 0x03B10306: 0x1FB0, + 0x03B10304: 0x1FB1, + 0x1F700345: 0x1FB2, + 0x03B10345: 0x1FB3, + 0x03AC0345: 0x1FB4, + 0x03B10342: 0x1FB6, + 0x1FB60345: 0x1FB7, + 0x03910306: 0x1FB8, + 0x03910304: 0x1FB9, + 0x03910300: 0x1FBA, + 0x03910345: 0x1FBC, + 0x00A80342: 0x1FC1, + 0x1F740345: 0x1FC2, + 0x03B70345: 0x1FC3, + 0x03AE0345: 0x1FC4, + 0x03B70342: 0x1FC6, + 0x1FC60345: 0x1FC7, + 0x03950300: 0x1FC8, + 0x03970300: 0x1FCA, + 0x03970345: 0x1FCC, + 0x1FBF0300: 0x1FCD, + 0x1FBF0301: 0x1FCE, + 0x1FBF0342: 0x1FCF, + 0x03B90306: 0x1FD0, + 0x03B90304: 0x1FD1, + 0x03CA0300: 0x1FD2, + 0x03B90342: 0x1FD6, + 0x03CA0342: 0x1FD7, + 0x03990306: 0x1FD8, + 0x03990304: 0x1FD9, + 0x03990300: 0x1FDA, + 0x1FFE0300: 0x1FDD, + 0x1FFE0301: 0x1FDE, + 0x1FFE0342: 0x1FDF, + 0x03C50306: 0x1FE0, + 0x03C50304: 0x1FE1, + 0x03CB0300: 0x1FE2, + 0x03C10313: 0x1FE4, + 0x03C10314: 0x1FE5, + 0x03C50342: 0x1FE6, + 0x03CB0342: 0x1FE7, + 0x03A50306: 0x1FE8, + 0x03A50304: 0x1FE9, + 0x03A50300: 0x1FEA, + 0x03A10314: 0x1FEC, + 0x00A80300: 0x1FED, + 0x1F7C0345: 0x1FF2, + 0x03C90345: 0x1FF3, + 0x03CE0345: 0x1FF4, + 0x03C90342: 0x1FF6, + 0x1FF60345: 0x1FF7, + 0x039F0300: 0x1FF8, + 0x03A90300: 0x1FFA, + 0x03A90345: 0x1FFC, + 0x21900338: 0x219A, + 0x21920338: 0x219B, + 0x21940338: 0x21AE, + 0x21D00338: 0x21CD, + 0x21D40338: 0x21CE, + 0x21D20338: 0x21CF, + 0x22030338: 0x2204, + 0x22080338: 0x2209, + 0x220B0338: 0x220C, + 0x22230338: 0x2224, + 0x22250338: 0x2226, + 0x223C0338: 0x2241, + 0x22430338: 0x2244, + 0x22450338: 0x2247, + 0x22480338: 0x2249, + 0x003D0338: 0x2260, + 0x22610338: 0x2262, + 0x224D0338: 0x226D, + 0x003C0338: 0x226E, + 0x003E0338: 0x226F, + 0x22640338: 0x2270, + 0x22650338: 0x2271, + 0x22720338: 0x2274, + 0x22730338: 0x2275, + 0x22760338: 0x2278, + 0x22770338: 0x2279, + 0x227A0338: 0x2280, + 0x227B0338: 0x2281, + 0x22820338: 0x2284, + 0x22830338: 0x2285, + 0x22860338: 0x2288, + 0x22870338: 0x2289, + 0x22A20338: 0x22AC, + 0x22A80338: 0x22AD, + 0x22A90338: 0x22AE, + 0x22AB0338: 0x22AF, + 0x227C0338: 0x22E0, + 0x227D0338: 0x22E1, + 0x22910338: 0x22E2, + 0x22920338: 0x22E3, + 0x22B20338: 0x22EA, + 0x22B30338: 0x22EB, + 0x22B40338: 0x22EC, + 0x22B50338: 0x22ED, + 0x304B3099: 0x304C, + 0x304D3099: 0x304E, + 0x304F3099: 0x3050, + 0x30513099: 0x3052, + 0x30533099: 0x3054, + 0x30553099: 0x3056, + 0x30573099: 0x3058, + 0x30593099: 0x305A, + 0x305B3099: 0x305C, + 0x305D3099: 0x305E, + 0x305F3099: 0x3060, + 0x30613099: 0x3062, + 0x30643099: 0x3065, + 0x30663099: 0x3067, + 0x30683099: 0x3069, + 0x306F3099: 0x3070, + 0x306F309A: 0x3071, + 0x30723099: 0x3073, + 0x3072309A: 0x3074, + 0x30753099: 0x3076, + 0x3075309A: 0x3077, + 0x30783099: 0x3079, + 0x3078309A: 0x307A, + 0x307B3099: 0x307C, + 0x307B309A: 0x307D, + 0x30463099: 0x3094, + 0x309D3099: 0x309E, + 0x30AB3099: 0x30AC, + 0x30AD3099: 0x30AE, + 0x30AF3099: 0x30B0, + 0x30B13099: 0x30B2, + 0x30B33099: 0x30B4, + 0x30B53099: 0x30B6, + 0x30B73099: 0x30B8, + 0x30B93099: 0x30BA, + 0x30BB3099: 0x30BC, + 0x30BD3099: 0x30BE, + 0x30BF3099: 0x30C0, + 0x30C13099: 0x30C2, + 0x30C43099: 0x30C5, + 0x30C63099: 0x30C7, + 0x30C83099: 0x30C9, + 0x30CF3099: 0x30D0, + 0x30CF309A: 0x30D1, + 0x30D23099: 0x30D3, + 0x30D2309A: 0x30D4, + 0x30D53099: 0x30D6, + 0x30D5309A: 0x30D7, + 0x30D83099: 0x30D9, + 0x30D8309A: 0x30DA, + 0x30DB3099: 0x30DC, + 0x30DB309A: 0x30DD, + 0x30A63099: 0x30F4, + 0x30EF3099: 0x30F7, + 0x30F03099: 0x30F8, + 0x30F13099: 0x30F9, + 0x30F23099: 0x30FA, + 0x30FD3099: 0x30FE, + 0x109910BA: 0x1109A, + 0x109B10BA: 0x1109C, + 0x10A510BA: 0x110AB, + 0x11311127: 0x1112E, + 0x11321127: 0x1112F, + 0x1347133E: 0x1134B, + 0x13471357: 0x1134C, + 0x14B914BA: 0x114BB, + 0x14B914B0: 0x114BC, + 0x14B914BD: 0x114BE, + 0x15B815AF: 0x115BA, + 0x15B915AF: 0x115BB, +} + +// Total size of tables: 53KB (54006 bytes) diff --git a/vendor/golang.org/x/text/unicode/norm/transform.go b/vendor/golang.org/x/text/unicode/norm/transform.go new file mode 100644 index 0000000000..9f47efbaf6 --- /dev/null +++ b/vendor/golang.org/x/text/unicode/norm/transform.go @@ -0,0 +1,88 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package norm + +import ( + "unicode/utf8" + + "golang.org/x/text/transform" +) + +// Reset implements the Reset method of the transform.Transformer interface. +func (Form) Reset() {} + +// Transform implements the Transform method of the transform.Transformer +// interface. It may need to write segments of up to MaxSegmentSize at once. +// Users should either catch ErrShortDst and allow dst to grow or have dst be at +// least of size MaxTransformChunkSize to be guaranteed of progress. +func (f Form) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) { + n := 0 + // Cap the maximum number of src bytes to check. + b := src + eof := atEOF + if ns := len(dst); ns < len(b) { + err = transform.ErrShortDst + eof = false + b = b[:ns] + } + i, ok := formTable[f].quickSpan(inputBytes(b), n, len(b), eof) + n += copy(dst[n:], b[n:i]) + if !ok { + nDst, nSrc, err = f.transform(dst[n:], src[n:], atEOF) + return nDst + n, nSrc + n, err + } + if n < len(src) && !atEOF { + err = transform.ErrShortSrc + } + return n, n, err +} + +func flushTransform(rb *reorderBuffer) bool { + // Write out (must fully fit in dst, or else it is an ErrShortDst). + if len(rb.out) < rb.nrune*utf8.UTFMax { + return false + } + rb.out = rb.out[rb.flushCopy(rb.out):] + return true +} + +var errs = []error{nil, transform.ErrShortDst, transform.ErrShortSrc} + +// transform implements the transform.Transformer interface. It is only called +// when quickSpan does not pass for a given string. +func (f Form) transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) { + // TODO: get rid of reorderBuffer. See CL 23460044. + rb := reorderBuffer{} + rb.init(f, src) + for { + // Load segment into reorder buffer. + rb.setFlusher(dst[nDst:], flushTransform) + end := decomposeSegment(&rb, nSrc, atEOF) + if end < 0 { + return nDst, nSrc, errs[-end] + } + nDst = len(dst) - len(rb.out) + nSrc = end + + // Next quickSpan. + end = rb.nsrc + eof := atEOF + if n := nSrc + len(dst) - nDst; n < end { + err = transform.ErrShortDst + end = n + eof = false + } + end, ok := rb.f.quickSpan(rb.src, nSrc, end, eof) + n := copy(dst[nDst:], rb.src.bytes[nSrc:end]) + nSrc += n + nDst += n + if ok { + if n < rb.nsrc && !atEOF { + err = transform.ErrShortSrc + } + return nDst, nSrc, err + } + } +} diff --git a/vendor/golang.org/x/text/unicode/norm/trie.go b/vendor/golang.org/x/text/unicode/norm/trie.go new file mode 100644 index 0000000000..423386bf43 --- /dev/null +++ b/vendor/golang.org/x/text/unicode/norm/trie.go @@ -0,0 +1,54 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package norm + +type valueRange struct { + value uint16 // header: value:stride + lo, hi byte // header: lo:n +} + +type sparseBlocks struct { + values []valueRange + offset []uint16 +} + +var nfcSparse = sparseBlocks{ + values: nfcSparseValues[:], + offset: nfcSparseOffset[:], +} + +var nfkcSparse = sparseBlocks{ + values: nfkcSparseValues[:], + offset: nfkcSparseOffset[:], +} + +var ( + nfcData = newNfcTrie(0) + nfkcData = newNfkcTrie(0) +) + +// lookupValue determines the type of block n and looks up the value for b. +// For n < t.cutoff, the block is a simple lookup table. Otherwise, the block +// is a list of ranges with an accompanying value. Given a matching range r, +// the value for b is by r.value + (b - r.lo) * stride. +func (t *sparseBlocks) lookup(n uint32, b byte) uint16 { + offset := t.offset[n] + header := t.values[offset] + lo := offset + 1 + hi := lo + uint16(header.lo) + for lo < hi { + m := lo + (hi-lo)/2 + r := t.values[m] + if r.lo <= b && b <= r.hi { + return r.value + uint16(b-r.lo)*header.value + } + if b < r.lo { + hi = m + } else { + lo = m + 1 + } + } + return 0 +} diff --git a/vendor/gopkg.in/fatih/set.v0/README.md b/vendor/gopkg.in/fatih/set.v0/README.md deleted file mode 100644 index 23afdd98d3..0000000000 --- a/vendor/gopkg.in/fatih/set.v0/README.md +++ /dev/null @@ -1,245 +0,0 @@ -# Set [![GoDoc](http://img.shields.io/badge/go-documentation-blue.svg?style=flat-square)](https://godoc.org/gopkg.in/fatih/set.v0) [![Build Status](http://img.shields.io/travis/fatih/set.svg?style=flat-square)](https://travis-ci.org/fatih/set) - -Set is a basic and simple, hash-based, **Set** data structure implementation -in Go (Golang). - -Set provides both threadsafe and non-threadsafe implementations of a generic -set data structure. The thread safety encompasses all operations on one set. -Operations on multiple sets are consistent in that the elements of each set -used was valid at exactly one point in time between the start and the end of -the operation. Because it's thread safe, you can use it concurrently with your -goroutines. - -For usage see examples below or click on the godoc badge. - -## Install and Usage - -Install the package with: - -```bash -go get gopkg.in/fatih/set.v0 -``` - -Import it with: - -```go -import "gopkg.in/fatih/set.v0" -``` - -and use `set` as the package name inside the code. - -## Examples - -#### Initialization of a new Set - -```go - -// create a set with zero items -s := set.New() -s := set.NewNonTS() // non thread-safe version - -// ... or with some initial values -s := set.New("istanbul", "frankfurt", 30.123, "san francisco", 1234) -s := set.NewNonTS("kenya", "ethiopia", "sumatra") - -``` - -#### Basic Operations - -```go -// add items -s.Add("istanbul") -s.Add("istanbul") // nothing happens if you add duplicate item - -// add multiple items -s.Add("ankara", "san francisco", 3.14) - -// remove item -s.Remove("frankfurt") -s.Remove("frankfurt") // nothing happes if you remove a nonexisting item - -// remove multiple items -s.Remove("barcelona", 3.14, "ankara") - -// removes an arbitary item and return it -item := s.Pop() - -// create a new copy -other := s.Copy() - -// remove all items -s.Clear() - -// number of items in the set -len := s.Size() - -// return a list of items -items := s.List() - -// string representation of set -fmt.Printf("set is %s", s.String()) - -``` - -#### Check Operations - -```go -// check for set emptiness, returns true if set is empty -s.IsEmpty() - -// check for a single item exist -s.Has("istanbul") - -// ... or for multiple items. This will return true if all of the items exist. -s.Has("istanbul", "san francisco", 3.14) - -// create two sets for the following checks... -s := s.New("1", "2", "3", "4", "5") -t := s.New("1", "2", "3") - - -// check if they are the same -if !s.IsEqual(t) { - fmt.Println("s is not equal to t") -} - -// if s contains all elements of t -if s.IsSubset(t) { - fmt.Println("t is a subset of s") -} - -// ... or if s is a superset of t -if t.IsSuperset(s) { - fmt.Println("s is a superset of t") -} - - -``` - -#### Set Operations - - -```go -// let us initialize two sets with some values -a := set.New("ankara", "berlin", "san francisco") -b := set.New("frankfurt", "berlin") - -// creates a new set with the items in a and b combined. -// [frankfurt, berlin, ankara, san francisco] -c := set.Union(a, b) - -// contains items which is in both a and b -// [berlin] -c := set.Intersection(a, b) - -// contains items which are in a but not in b -// [ankara, san francisco] -c := set.Difference(a, b) - -// contains items which are in one of either, but not in both. -// [frankfurt, ankara, san francisco] -c := set.SymmetricDifference(a, b) - -``` - -```go -// like Union but saves the result back into a. -a.Merge(b) - -// removes the set items which are in b from a and saves the result back into a. -a.Separate(b) - -``` - -#### Multiple Set Operations - -```go -a := set.New("1", "3", "4", "5") -b := set.New("2", "3", "4", "5") -c := set.New("4", "5", "6", "7") - -// creates a new set with items in a, b and c -// [1 2 3 4 5 6 7] -u := set.Union(a, b, c) - -// creates a new set with items in a but not in b and c -// [1] -u := set.Difference(a, b, c) - -// creates a new set with items that are common to a, b and c -// [5] -u := set.Intersection(a, b, c) -``` - -#### Helper methods - -The Slice functions below are a convenient way to extract or convert your Set data -into basic data types. - - -```go -// create a set of mixed types -s := set.New("ankara", "5", "8", "san francisco", 13, 21) - - -// convert s into a slice of strings (type is []string) -// [ankara 5 8 san francisco] -t := set.StringSlice(s) - - -// u contains a slice of ints (type is []int) -// [13, 21] -u := set.IntSlice(s) - -``` - -#### Concurrent safe usage - -Below is an example of a concurrent way that uses set. We call ten functions -concurrently and wait until they are finished. It basically creates a new -string for each goroutine and adds it to our set. - -```go -package main - -import ( - "fmt" - "github.com/fatih/set" - "strconv" - "sync" -) - -func main() { - var wg sync.WaitGroup // this is just for waiting until all goroutines finish - - // Initialize our thread safe Set - s := set.New() - - // Add items concurrently (item1, item2, and so on) - for i := 0; i < 10; i++ { - wg.Add(1) - go func(i int) { - item := "item" + strconv.Itoa(i) - fmt.Println("adding", item) - s.Add(item) - wg.Done() - }(i) - } - - // Wait until all concurrent calls finished and print our set - wg.Wait() - fmt.Println(s) -} -``` - -## Credits - - * [Fatih Arslan](https://github.com/fatih) - * [Arne Hormann](https://github.com/arnehormann) - * [Sam Boyer](https://github.com/sdboyer) - * [Ralph Loizzo](https://github.com/friartech) - -## License - -The MIT License (MIT) - see LICENSE.md for more details - diff --git a/vendor/gopkg.in/fatih/set.v0/set.go b/vendor/gopkg.in/fatih/set.v0/set.go deleted file mode 100644 index ac0240ce70..0000000000 --- a/vendor/gopkg.in/fatih/set.v0/set.go +++ /dev/null @@ -1,121 +0,0 @@ -// Package set provides both threadsafe and non-threadsafe implementations of -// a generic set data structure. In the threadsafe set, safety encompasses all -// operations on one set. Operations on multiple sets are consistent in that -// the elements of each set used was valid at exactly one point in time -// between the start and the end of the operation. -package set - -// Interface is describing a Set. Sets are an unordered, unique list of values. -type Interface interface { - New(items ...interface{}) Interface - Add(items ...interface{}) - Remove(items ...interface{}) - Pop() interface{} - Has(items ...interface{}) bool - Size() int - Clear() - IsEmpty() bool - IsEqual(s Interface) bool - IsSubset(s Interface) bool - IsSuperset(s Interface) bool - Each(func(interface{}) bool) - String() string - List() []interface{} - Copy() Interface - Merge(s Interface) - Separate(s Interface) -} - -// helpful to not write everywhere struct{}{} -var keyExists = struct{}{} - -// Union is the merger of multiple sets. It returns a new set with all the -// elements present in all the sets that are passed. -// -// The dynamic type of the returned set is determined by the first passed set's -// implementation of the New() method. -func Union(set1, set2 Interface, sets ...Interface) Interface { - u := set1.Copy() - set2.Each(func(item interface{}) bool { - u.Add(item) - return true - }) - for _, set := range sets { - set.Each(func(item interface{}) bool { - u.Add(item) - return true - }) - } - - return u -} - -// Difference returns a new set which contains items which are in in the first -// set but not in the others. Unlike the Difference() method you can use this -// function separately with multiple sets. -func Difference(set1, set2 Interface, sets ...Interface) Interface { - s := set1.Copy() - s.Separate(set2) - for _, set := range sets { - s.Separate(set) // seperate is thread safe - } - return s -} - -// Intersection returns a new set which contains items that only exist in all given sets. -func Intersection(set1, set2 Interface, sets ...Interface) Interface { - all := Union(set1, set2, sets...) - result := Union(set1, set2, sets...) - - all.Each(func(item interface{}) bool { - if !set1.Has(item) || !set2.Has(item) { - result.Remove(item) - } - - for _, set := range sets { - if !set.Has(item) { - result.Remove(item) - } - } - return true - }) - return result -} - -// SymmetricDifference returns a new set which s is the difference of items which are in -// one of either, but not in both. -func SymmetricDifference(s Interface, t Interface) Interface { - u := Difference(s, t) - v := Difference(t, s) - return Union(u, v) -} - -// StringSlice is a helper function that returns a slice of strings of s. If -// the set contains mixed types of items only items of type string are returned. -func StringSlice(s Interface) []string { - slice := make([]string, 0) - for _, item := range s.List() { - v, ok := item.(string) - if !ok { - continue - } - - slice = append(slice, v) - } - return slice -} - -// IntSlice is a helper function that returns a slice of ints of s. If -// the set contains mixed types of items only items of type int are returned. -func IntSlice(s Interface) []int { - slice := make([]int, 0) - for _, item := range s.List() { - v, ok := item.(int) - if !ok { - continue - } - - slice = append(slice, v) - } - return slice -} diff --git a/vendor/gopkg.in/fatih/set.v0/set_nots.go b/vendor/gopkg.in/fatih/set.v0/set_nots.go deleted file mode 100644 index ec1ab2285f..0000000000 --- a/vendor/gopkg.in/fatih/set.v0/set_nots.go +++ /dev/null @@ -1,195 +0,0 @@ -package set - -import ( - "fmt" - "strings" -) - -// Provides a common set baseline for both threadsafe and non-ts Sets. -type set struct { - m map[interface{}]struct{} // struct{} doesn't take up space -} - -// SetNonTS defines a non-thread safe set data structure. -type SetNonTS struct { - set -} - -// NewNonTS creates and initialize a new non-threadsafe Set. -// It accepts a variable number of arguments to populate the initial set. -// If nothing is passed a SetNonTS with zero size is created. -func NewNonTS(items ...interface{}) *SetNonTS { - s := &SetNonTS{} - s.m = make(map[interface{}]struct{}) - - // Ensure interface compliance - var _ Interface = s - - s.Add(items...) - return s -} - -// New creates and initalizes a new Set interface. It accepts a variable -// number of arguments to populate the initial set. If nothing is passed a -// zero size Set based on the struct is created. -func (s *set) New(items ...interface{}) Interface { - return NewNonTS(items...) -} - -// Add includes the specified items (one or more) to the set. The underlying -// Set s is modified. If passed nothing it silently returns. -func (s *set) Add(items ...interface{}) { - if len(items) == 0 { - return - } - - for _, item := range items { - s.m[item] = keyExists - } -} - -// Remove deletes the specified items from the set. The underlying Set s is -// modified. If passed nothing it silently returns. -func (s *set) Remove(items ...interface{}) { - if len(items) == 0 { - return - } - - for _, item := range items { - delete(s.m, item) - } -} - -// Pop deletes and return an item from the set. The underlying Set s is -// modified. If set is empty, nil is returned. -func (s *set) Pop() interface{} { - for item := range s.m { - delete(s.m, item) - return item - } - return nil -} - -// Has looks for the existence of items passed. It returns false if nothing is -// passed. For multiple items it returns true only if all of the items exist. -func (s *set) Has(items ...interface{}) bool { - // assume checked for empty item, which not exist - if len(items) == 0 { - return false - } - - has := true - for _, item := range items { - if _, has = s.m[item]; !has { - break - } - } - return has -} - -// Size returns the number of items in a set. -func (s *set) Size() int { - return len(s.m) -} - -// Clear removes all items from the set. -func (s *set) Clear() { - s.m = make(map[interface{}]struct{}) -} - -// IsEmpty reports whether the Set is empty. -func (s *set) IsEmpty() bool { - return s.Size() == 0 -} - -// IsEqual test whether s and t are the same in size and have the same items. -func (s *set) IsEqual(t Interface) bool { - // Force locking only if given set is threadsafe. - if conv, ok := t.(*Set); ok { - conv.l.RLock() - defer conv.l.RUnlock() - } - - // return false if they are no the same size - if sameSize := len(s.m) == t.Size(); !sameSize { - return false - } - - equal := true - t.Each(func(item interface{}) bool { - _, equal = s.m[item] - return equal // if false, Each() will end - }) - - return equal -} - -// IsSubset tests whether t is a subset of s. -func (s *set) IsSubset(t Interface) (subset bool) { - subset = true - - t.Each(func(item interface{}) bool { - _, subset = s.m[item] - return subset - }) - - return -} - -// IsSuperset tests whether t is a superset of s. -func (s *set) IsSuperset(t Interface) bool { - return t.IsSubset(s) -} - -// Each traverses the items in the Set, calling the provided function for each -// set member. Traversal will continue until all items in the Set have been -// visited, or if the closure returns false. -func (s *set) Each(f func(item interface{}) bool) { - for item := range s.m { - if !f(item) { - break - } - } -} - -// String returns a string representation of s -func (s *set) String() string { - t := make([]string, 0, len(s.List())) - for _, item := range s.List() { - t = append(t, fmt.Sprintf("%v", item)) - } - - return fmt.Sprintf("[%s]", strings.Join(t, ", ")) -} - -// List returns a slice of all items. There is also StringSlice() and -// IntSlice() methods for returning slices of type string or int. -func (s *set) List() []interface{} { - list := make([]interface{}, 0, len(s.m)) - - for item := range s.m { - list = append(list, item) - } - - return list -} - -// Copy returns a new Set with a copy of s. -func (s *set) Copy() Interface { - return NewNonTS(s.List()...) -} - -// Merge is like Union, however it modifies the current set it's applied on -// with the given t set. -func (s *set) Merge(t Interface) { - t.Each(func(item interface{}) bool { - s.m[item] = keyExists - return true - }) -} - -// it's not the opposite of Merge. -// Separate removes the set items containing in t from set s. Please aware that -func (s *set) Separate(t Interface) { - s.Remove(t.List()...) -} diff --git a/vendor/gopkg.in/fatih/set.v0/set_ts.go b/vendor/gopkg.in/fatih/set.v0/set_ts.go deleted file mode 100644 index 50f532565b..0000000000 --- a/vendor/gopkg.in/fatih/set.v0/set_ts.go +++ /dev/null @@ -1,200 +0,0 @@ -package set - -import ( - "sync" -) - -// Set defines a thread safe set data structure. -type Set struct { - set - l sync.RWMutex // we name it because we don't want to expose it -} - -// New creates and initialize a new Set. It's accept a variable number of -// arguments to populate the initial set. If nothing passed a Set with zero -// size is created. -func New(items ...interface{}) *Set { - s := &Set{} - s.m = make(map[interface{}]struct{}) - - // Ensure interface compliance - var _ Interface = s - - s.Add(items...) - return s -} - -// New creates and initalizes a new Set interface. It accepts a variable -// number of arguments to populate the initial set. If nothing is passed a -// zero size Set based on the struct is created. -func (s *Set) New(items ...interface{}) Interface { - return New(items...) -} - -// Add includes the specified items (one or more) to the set. The underlying -// Set s is modified. If passed nothing it silently returns. -func (s *Set) Add(items ...interface{}) { - if len(items) == 0 { - return - } - - s.l.Lock() - defer s.l.Unlock() - - for _, item := range items { - s.m[item] = keyExists - } -} - -// Remove deletes the specified items from the set. The underlying Set s is -// modified. If passed nothing it silently returns. -func (s *Set) Remove(items ...interface{}) { - if len(items) == 0 { - return - } - - s.l.Lock() - defer s.l.Unlock() - - for _, item := range items { - delete(s.m, item) - } -} - -// Pop deletes and return an item from the set. The underlying Set s is -// modified. If set is empty, nil is returned. -func (s *Set) Pop() interface{} { - s.l.RLock() - for item := range s.m { - s.l.RUnlock() - s.l.Lock() - delete(s.m, item) - s.l.Unlock() - return item - } - s.l.RUnlock() - return nil -} - -// Has looks for the existence of items passed. It returns false if nothing is -// passed. For multiple items it returns true only if all of the items exist. -func (s *Set) Has(items ...interface{}) bool { - // assume checked for empty item, which not exist - if len(items) == 0 { - return false - } - - s.l.RLock() - defer s.l.RUnlock() - - has := true - for _, item := range items { - if _, has = s.m[item]; !has { - break - } - } - return has -} - -// Size returns the number of items in a set. -func (s *Set) Size() int { - s.l.RLock() - defer s.l.RUnlock() - - l := len(s.m) - return l -} - -// Clear removes all items from the set. -func (s *Set) Clear() { - s.l.Lock() - defer s.l.Unlock() - - s.m = make(map[interface{}]struct{}) -} - -// IsEqual test whether s and t are the same in size and have the same items. -func (s *Set) IsEqual(t Interface) bool { - s.l.RLock() - defer s.l.RUnlock() - - // Force locking only if given set is threadsafe. - if conv, ok := t.(*Set); ok { - conv.l.RLock() - defer conv.l.RUnlock() - } - - // return false if they are no the same size - if sameSize := len(s.m) == t.Size(); !sameSize { - return false - } - - equal := true - t.Each(func(item interface{}) bool { - _, equal = s.m[item] - return equal // if false, Each() will end - }) - - return equal -} - -// IsSubset tests whether t is a subset of s. -func (s *Set) IsSubset(t Interface) (subset bool) { - s.l.RLock() - defer s.l.RUnlock() - - subset = true - - t.Each(func(item interface{}) bool { - _, subset = s.m[item] - return subset - }) - - return -} - -// Each traverses the items in the Set, calling the provided function for each -// set member. Traversal will continue until all items in the Set have been -// visited, or if the closure returns false. -func (s *Set) Each(f func(item interface{}) bool) { - s.l.RLock() - defer s.l.RUnlock() - - for item := range s.m { - if !f(item) { - break - } - } -} - -// List returns a slice of all items. There is also StringSlice() and -// IntSlice() methods for returning slices of type string or int. -func (s *Set) List() []interface{} { - s.l.RLock() - defer s.l.RUnlock() - - list := make([]interface{}, 0, len(s.m)) - - for item := range s.m { - list = append(list, item) - } - - return list -} - -// Copy returns a new Set with a copy of s. -func (s *Set) Copy() Interface { - return New(s.List()...) -} - -// Merge is like Union, however it modifies the current set it's applied on -// with the given t set. -func (s *Set) Merge(t Interface) { - s.l.Lock() - defer s.l.Unlock() - - t.Each(func(item interface{}) bool { - s.m[item] = keyExists - return true - }) -} diff --git a/vendor/vendor.json b/vendor/vendor.json index 4b3efd7e5e..6ec698da14 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -21,28 +21,16 @@ "revisionTime": "2016-08-11T21:22:31Z" }, { - "checksumSHA1": "24EW3PGLGVSy/5joAOZdHzN/S2E=", - "path": "github.com/Azure/azure-storage-go", - "revision": "12ccaadb081cdd217702067d28da9a7ff4305239", - "revisionTime": "2017-03-02T22:15:08Z" + "checksumSHA1": "z+M6FYl9EKsoZZMLcT0Ktwfk8pI=", + "path": "github.com/Azure/azure-pipeline-go/pipeline", + "revision": "7571e8eb0876932ab505918ff7ed5107773e5ee2", + "revisionTime": "2018-06-07T21:19:23Z" }, { - "checksumSHA1": "+sxS3YEvxf1VxlRskIdXFRWq9rY=", - "path": "github.com/Azure/go-autorest/autorest", - "revision": "ec5f4903f77ed9927ac95b19ab8e44ada64c1356", - "revisionTime": "2017-02-15T19:58:14Z" - }, - { - "checksumSHA1": "ghrnc4vZv6q8zzeakZnrS8CGFhE=", - "path": "github.com/Azure/go-autorest/autorest/azure", - "revision": "ec5f4903f77ed9927ac95b19ab8e44ada64c1356", - "revisionTime": "2017-02-15T19:58:14Z" - }, - { - "checksumSHA1": "q9Qz8PAxK5FTOZwgYKe5Lj38u4c=", - "path": "github.com/Azure/go-autorest/autorest/date", - "revision": "ec5f4903f77ed9927ac95b19ab8e44ada64c1356", - "revisionTime": "2017-02-15T19:58:14Z" + "checksumSHA1": "5nsGu77r69lloEWbFhMof2UA9rY=", + "path": "github.com/Azure/azure-storage-blob-go/2018-03-28/azblob", + "revision": "eaae161d9d5e07363f04ddb19d84d57efc66d1a1", + "revisionTime": "2018-07-12T00:56:34Z" }, { "checksumSHA1": "QC55lHNOv1+UAL2xtIHw17MJ8J8=", @@ -68,12 +56,24 @@ "revision": "165db2f241fd235aec29ba6d9b1ccd5f1c14637c", "revisionTime": "2015-01-22T07:26:53Z" }, + { + "checksumSHA1": "7gK+lSShSu1NRw83/A95BcgMqsI=", + "path": "github.com/codahale/hdrhistogram", + "revision": "3a0bb77429bd3a61596f5e8a3172445844342120", + "revisionTime": "2016-10-10T02:54:55Z" + }, { "checksumSHA1": "dvabztWVQX8f6oMLRyv4dLH+TGY=", "path": "github.com/davecgh/go-spew/spew", "revision": "346938d642f2ec3594ed81d874461961cd0faa76", "revisionTime": "2016-10-29T20:57:26Z" }, + { + "checksumSHA1": "1xK7ycc1ICRInk/S9iiyB9Rpv50=", + "path": "github.com/deckarep/golang-set", + "revision": "504e848d77ea4752b3057b8fb46da0e7f746ccf3", + "revisionTime": "2018-06-03T19:32:48Z" + }, { "checksumSHA1": "2Fy1Y6Z3lRRX1891WF/+HT4XS2I=", "path": "github.com/dgrijalva/jwt-go", @@ -81,10 +81,10 @@ "revisionTime": "2017-02-01T22:58:49Z" }, { - "checksumSHA1": "lutCa+IVM60R1OYBm9RtDAW50Ys=", + "checksumSHA1": "Ad8LPSCP9HctFrmskh+S5HpHXcs=", "path": "github.com/docker/docker/pkg/reexec", - "revision": "83ee902ecc3790c33c1e2d87334074436056bb49", - "revisionTime": "2017-04-22T21:51:12Z" + "revision": "8e610b2b55bfd1bfa9436ab110d311f5e8a74dcb", + "revisionTime": "2018-06-25T18:44:42Z" }, { "checksumSHA1": "zYnPsNAVm1/ViwCkN++dX2JQhBo=", @@ -93,10 +93,10 @@ "revisionTime": "2016-05-12T03:30:02Z" }, { - "checksumSHA1": "Fc8BCxCoQ7ZmghDT6X1cASR10Ec=", + "checksumSHA1": "jElNoLEe7m/iaoF1vYIHyNaS2SE=", "path": "github.com/elastic/gosigar", - "revision": "a3814ce5008e612a0c6d027608b54e1d0d9a5613", - "revisionTime": "2018-01-22T22:25:45Z" + "revision": "37f05ff46ffa7a825d1b24cf2b62d4a4c1a9d2e8", + "revisionTime": "2018-03-30T10:04:40Z" }, { "checksumSHA1": "qDsgp2kAeI9nhj565HUScaUyjU4=", @@ -110,6 +110,18 @@ "revision": "5ec5d9d3c2cf82e9688b34e9bc27a94d616a7193", "revisionTime": "2017-02-09T08:00:14Z" }, + { + "checksumSHA1": "Jq1rrHSGPfh689nA2hL1QVb62zE=", + "path": "github.com/fjl/memsize", + "revision": "ca190fb6ffbc076ff49197b7168a760f30182d2e", + "revisionTime": "2018-04-18T12:24:29Z" + }, + { + "checksumSHA1": "Z13QAYTqeW4cTiglkc2F05gWLu4=", + "path": "github.com/fjl/memsize/memsizeui", + "revision": "ca190fb6ffbc076ff49197b7168a760f30182d2e", + "revisionTime": "2018-04-18T12:24:29Z" + }, { "checksumSHA1": "0orwvPL96wFckVJyPl39fz2QsgA=", "path": "github.com/gizak/termui", @@ -280,10 +292,16 @@ "revisionTime": "2015-03-14T17:03:34Z" }, { - "checksumSHA1": "2gmvVTDCks8cPhpmyDlvm0sbrXE=", + "checksumSHA1": "2jsbDTvwxafPp7FJjJ8IIFlTLjs=", + "path": "github.com/mohae/deepcopy", + "revision": "c48cc78d482608239f6c4c92a4abd87eb8761c90", + "revisionTime": "2017-09-29T03:49:55Z" + }, + { + "checksumSHA1": "FYM/8R2CqS6PSNAoKl6X5gNJ20A=", "path": "github.com/naoina/toml", - "revision": "ac014c6b6502388d89a85552b7208b8da7cfe104", - "revisionTime": "2017-04-10T21:57:17Z" + "revision": "9fafd69674167c06933b1787ae235618431ce87f", + "revisionTime": "2017-09-18T21:04:37Z" }, { "checksumSHA1": "xZBlSMT5o/A+EDOro6KbfHZwSNc=", @@ -303,6 +321,24 @@ "revision": "febf2d34b54a69ce7530036c7503b1c9fbfdf0bb", "revisionTime": "2017-01-28T05:05:32Z" }, + { + "checksumSHA1": "wIcN7tZiF441h08RHAm4NV8cYO4=", + "path": "github.com/opentracing/opentracing-go", + "revision": "bd9c3193394760d98b2fa6ebb2291f0cd1d06a7d", + "revisionTime": "2018-06-06T20:41:48Z" + }, + { + "checksumSHA1": "uhDxBvLEqRAMZKgpTZ8MFuLIIM8=", + "path": "github.com/opentracing/opentracing-go/ext", + "revision": "bd9c3193394760d98b2fa6ebb2291f0cd1d06a7d", + "revisionTime": "2018-06-06T20:41:48Z" + }, + { + "checksumSHA1": "tnkdNJbJxNKuPZMWapP1xhKIIGw=", + "path": "github.com/opentracing/opentracing-go/log", + "revision": "bd9c3193394760d98b2fa6ebb2291f0cd1d06a7d", + "revisionTime": "2018-06-06T20:41:48Z" + }, { "checksumSHA1": "Se195FlZ160eaEk/uVx4KdTPSxU=", "path": "github.com/pborman/uuid", @@ -406,76 +442,178 @@ "revisionTime": "2017-07-05T02:17:15Z" }, { - "checksumSHA1": "k13cCuMJO7+KhR8ZXx5oUqDKGQA=", + "checksumSHA1": "k6zbR5hiI10hkWtiK91rIY5s5/E=", "path": "github.com/syndtr/goleveldb/leveldb", - "revision": "ae970a0732be3a1f5311da86118d37b9f4bd2a5a", - "revisionTime": "2018-05-02T07:23:49Z" + "revision": "c4c61651e9e37fa117f53c5a906d3b63090d8445", + "revisionTime": "2018-07-08T03:05:51Z" }, { "checksumSHA1": "EKIow7XkgNdWvR/982ffIZxKG8Y=", "path": "github.com/syndtr/goleveldb/leveldb/cache", - "revision": "ae970a0732be3a1f5311da86118d37b9f4bd2a5a", - "revisionTime": "2018-05-02T07:23:49Z" + "revision": "c4c61651e9e37fa117f53c5a906d3b63090d8445", + "revisionTime": "2018-07-08T03:05:51Z" }, { "checksumSHA1": "5KPgnvCPlR0ysDAqo6jApzRQ3tw=", "path": "github.com/syndtr/goleveldb/leveldb/comparer", - "revision": "ae970a0732be3a1f5311da86118d37b9f4bd2a5a", - "revisionTime": "2018-05-02T07:23:49Z" + "revision": "c4c61651e9e37fa117f53c5a906d3b63090d8445", + "revisionTime": "2018-07-08T03:05:51Z" }, { "checksumSHA1": "1DRAxdlWzS4U0xKN/yQ/fdNN7f0=", "path": "github.com/syndtr/goleveldb/leveldb/errors", - "revision": "ae970a0732be3a1f5311da86118d37b9f4bd2a5a", - "revisionTime": "2018-05-02T07:23:49Z" + "revision": "c4c61651e9e37fa117f53c5a906d3b63090d8445", + "revisionTime": "2018-07-08T03:05:51Z" }, { "checksumSHA1": "eqKeD6DS7eNCtxVYZEHHRKkyZrw=", "path": "github.com/syndtr/goleveldb/leveldb/filter", - "revision": "ae970a0732be3a1f5311da86118d37b9f4bd2a5a", - "revisionTime": "2018-05-02T07:23:49Z" + "revision": "c4c61651e9e37fa117f53c5a906d3b63090d8445", + "revisionTime": "2018-07-08T03:05:51Z" }, { "checksumSHA1": "weSsccMav4BCerDpSLzh3mMxAYo=", "path": "github.com/syndtr/goleveldb/leveldb/iterator", - "revision": "ae970a0732be3a1f5311da86118d37b9f4bd2a5a", - "revisionTime": "2018-05-02T07:23:49Z" + "revision": "c4c61651e9e37fa117f53c5a906d3b63090d8445", + "revisionTime": "2018-07-08T03:05:51Z" }, { "checksumSHA1": "gJY7bRpELtO0PJpZXgPQ2BYFJ88=", "path": "github.com/syndtr/goleveldb/leveldb/journal", - "revision": "ae970a0732be3a1f5311da86118d37b9f4bd2a5a", - "revisionTime": "2018-05-02T07:23:49Z" + "revision": "c4c61651e9e37fa117f53c5a906d3b63090d8445", + "revisionTime": "2018-07-08T03:05:51Z" }, { "checksumSHA1": "MtYY1b2234y/MlS+djL8tXVAcQs=", "path": "github.com/syndtr/goleveldb/leveldb/memdb", - "revision": "ae970a0732be3a1f5311da86118d37b9f4bd2a5a", - "revisionTime": "2018-05-02T07:23:49Z" + "revision": "c4c61651e9e37fa117f53c5a906d3b63090d8445", + "revisionTime": "2018-07-08T03:05:51Z" }, { "checksumSHA1": "UmQeotV+m8/FduKEfLOhjdp18rs=", "path": "github.com/syndtr/goleveldb/leveldb/opt", - "revision": "ae970a0732be3a1f5311da86118d37b9f4bd2a5a", - "revisionTime": "2018-05-02T07:23:49Z" + "revision": "c4c61651e9e37fa117f53c5a906d3b63090d8445", + "revisionTime": "2018-07-08T03:05:51Z" }, { - "checksumSHA1": "7H3fa12T7WoMAeXq1+qG5O7LD0w=", + "checksumSHA1": "ZnyuciM+R19NG8L5YS3TIJdo1e8=", "path": "github.com/syndtr/goleveldb/leveldb/storage", - "revision": "ae970a0732be3a1f5311da86118d37b9f4bd2a5a", - "revisionTime": "2018-05-02T07:23:49Z" + "revision": "c4c61651e9e37fa117f53c5a906d3b63090d8445", + "revisionTime": "2018-07-08T03:05:51Z" }, { "checksumSHA1": "gWFPMz8OQeul0t54RM66yMTX49g=", "path": "github.com/syndtr/goleveldb/leveldb/table", - "revision": "ae970a0732be3a1f5311da86118d37b9f4bd2a5a", - "revisionTime": "2018-05-02T07:23:49Z" + "revision": "c4c61651e9e37fa117f53c5a906d3b63090d8445", + "revisionTime": "2018-07-08T03:05:51Z" }, { "checksumSHA1": "V/Dh7NV0/fy/5jX1KaAjmGcNbzI=", "path": "github.com/syndtr/goleveldb/leveldb/util", - "revision": "ae970a0732be3a1f5311da86118d37b9f4bd2a5a", - "revisionTime": "2018-05-02T07:23:49Z" + "revision": "c4c61651e9e37fa117f53c5a906d3b63090d8445", + "revisionTime": "2018-07-08T03:05:51Z" + }, + { + "checksumSHA1": "nD6S4KB0S+YHxVMDDE+w3PyXaMk=", + "path": "github.com/uber/jaeger-client-go", + "revision": "f7e0d4744fa6d5287c53b8ac8d4f83089ce07ce8", + "revisionTime": "2018-06-07T15:18:42Z" + }, + { + "checksumSHA1": "cjhPfiQbTqfkHmZM3Bi+Bm8qgN4=", + "path": "github.com/uber/jaeger-client-go/config", + "revision": "f7e0d4744fa6d5287c53b8ac8d4f83089ce07ce8", + "revisionTime": "2018-06-07T15:18:42Z" + }, + { + "checksumSHA1": "KM5UXTWkHULmw0dDRNuk8ogWyGs=", + "path": "github.com/uber/jaeger-client-go/internal/baggage", + "revision": "f7e0d4744fa6d5287c53b8ac8d4f83089ce07ce8", + "revisionTime": "2018-06-07T15:18:42Z" + }, + { + "checksumSHA1": "tZqlcHV1XoLdZp9jfnydzsZAvYo=", + "path": "github.com/uber/jaeger-client-go/internal/baggage/remote", + "revision": "f7e0d4744fa6d5287c53b8ac8d4f83089ce07ce8", + "revisionTime": "2018-06-07T15:18:42Z" + }, + { + "checksumSHA1": "QB0L0GrzyMGQp6ivkkxp7a1DPsE=", + "path": "github.com/uber/jaeger-client-go/internal/spanlog", + "revision": "f7e0d4744fa6d5287c53b8ac8d4f83089ce07ce8", + "revisionTime": "2018-06-07T15:18:42Z" + }, + { + "checksumSHA1": "79HRO/+ekkpwqDB/OMiW+AHJtlE=", + "path": "github.com/uber/jaeger-client-go/internal/throttler", + "revision": "f7e0d4744fa6d5287c53b8ac8d4f83089ce07ce8", + "revisionTime": "2018-06-07T15:18:42Z" + }, + { + "checksumSHA1": "OVQDWFtFMs+NODe0F/S5kYViQco=", + "path": "github.com/uber/jaeger-client-go/internal/throttler/remote", + "revision": "f7e0d4744fa6d5287c53b8ac8d4f83089ce07ce8", + "revisionTime": "2018-06-07T15:18:42Z" + }, + { + "checksumSHA1": "tMP/vxbHwNAbOEaUhic5/meKfac=", + "path": "github.com/uber/jaeger-client-go/log", + "revision": "f7e0d4744fa6d5287c53b8ac8d4f83089ce07ce8", + "revisionTime": "2018-06-07T15:18:42Z" + }, + { + "checksumSHA1": "j4WrA/B2SJCqHxttCQ+TYbmtQqE=", + "path": "github.com/uber/jaeger-client-go/rpcmetrics", + "revision": "f7e0d4744fa6d5287c53b8ac8d4f83089ce07ce8", + "revisionTime": "2018-06-07T15:18:42Z" + }, + { + "checksumSHA1": "+ffspyTBQLql2UiU6muvfWR/m1o=", + "path": "github.com/uber/jaeger-client-go/thrift", + "revision": "f7e0d4744fa6d5287c53b8ac8d4f83089ce07ce8", + "revisionTime": "2018-06-07T15:18:42Z" + }, + { + "checksumSHA1": "fMIQ4sJFCkqFYhXvvLKIlofqxvY=", + "path": "github.com/uber/jaeger-client-go/thrift-gen/agent", + "revision": "f7e0d4744fa6d5287c53b8ac8d4f83089ce07ce8", + "revisionTime": "2018-06-07T15:18:42Z" + }, + { + "checksumSHA1": "fRR2p+JAp7paApf32YuQuWU7yzY=", + "path": "github.com/uber/jaeger-client-go/thrift-gen/baggage", + "revision": "f7e0d4744fa6d5287c53b8ac8d4f83089ce07ce8", + "revisionTime": "2018-06-07T15:18:42Z" + }, + { + "checksumSHA1": "JZkMEOmiOFFEuGCsDOVLK5RzvMM=", + "path": "github.com/uber/jaeger-client-go/thrift-gen/jaeger", + "revision": "f7e0d4744fa6d5287c53b8ac8d4f83089ce07ce8", + "revisionTime": "2018-06-07T15:18:42Z" + }, + { + "checksumSHA1": "0teQUhTqTE1fLs+vbnTTzWOqdEQ=", + "path": "github.com/uber/jaeger-client-go/thrift-gen/sampling", + "revision": "f7e0d4744fa6d5287c53b8ac8d4f83089ce07ce8", + "revisionTime": "2018-06-07T15:18:42Z" + }, + { + "checksumSHA1": "Nx5witfz05BSO2YlFzh2Gno6bA0=", + "path": "github.com/uber/jaeger-client-go/thrift-gen/zipkincore", + "revision": "f7e0d4744fa6d5287c53b8ac8d4f83089ce07ce8", + "revisionTime": "2018-06-07T15:18:42Z" + }, + { + "checksumSHA1": "DKwwIk9vq53IKO7RKccat9cnqeo=", + "path": "github.com/uber/jaeger-client-go/utils", + "revision": "f7e0d4744fa6d5287c53b8ac8d4f83089ce07ce8", + "revisionTime": "2018-06-07T15:18:42Z" + }, + { + "checksumSHA1": "k1iaOSBmLp3TpGvHNnRQXyJfwyI=", + "path": "github.com/uber/jaeger-lib/metrics", + "revision": "a51202d6f4a7e5a219e3841a43614ff7187ae7f1", + "revisionTime": "2018-06-15T20:27:29Z" }, { "checksumSHA1": "TT1rac6kpQp2vz24m5yDGUNQ/QQ=", @@ -591,6 +729,12 @@ "revision": "b4690f45fa1cafc47b1c280c2e75116efe40cc13", "revisionTime": "2017-02-15T08:41:58Z" }, + { + "checksumSHA1": "RcrB7tgYS/GMW4QrwVdMOTNqIU8=", + "path": "golang.org/x/net/idna", + "revision": "5ccada7d0a7ba9aeb5d3aca8d3501b4c2a509fec", + "revisionTime": "2018-01-12T01:53:59Z" + }, { "checksumSHA1": "7EZyXN0EmZLgGxZxK01IJua4c8o=", "path": "golang.org/x/net/websocket", @@ -711,12 +855,30 @@ "revision": "85c29909967d7f171f821e7a42e7b7af76fb9598", "revisionTime": "2017-02-11T12:01:23Z" }, + { + "checksumSHA1": "CbpjEkkOeh0fdM/V8xKDdI0AA88=", + "path": "golang.org/x/text/secure/bidirule", + "revision": "e19ae1496984b1c655b8044a65c0300a3c878dd3", + "revisionTime": "2017-12-24T20:31:28Z" + }, { "checksumSHA1": "ziMb9+ANGRJSSIuxYdRbA+cDRBQ=", "path": "golang.org/x/text/transform", "revision": "85c29909967d7f171f821e7a42e7b7af76fb9598", "revisionTime": "2017-02-11T12:01:23Z" }, + { + "checksumSHA1": "w8kDfZ1Ug+qAcVU0v8obbu3aDOY=", + "path": "golang.org/x/text/unicode/bidi", + "revision": "e19ae1496984b1c655b8044a65c0300a3c878dd3", + "revisionTime": "2017-12-24T20:31:28Z" + }, + { + "checksumSHA1": "BCNYmf4Ek93G4lk5x3ucNi/lTwA=", + "path": "golang.org/x/text/unicode/norm", + "revision": "e19ae1496984b1c655b8044a65c0300a3c878dd3", + "revisionTime": "2017-12-24T20:31:28Z" + }, { "checksumSHA1": "ikor+YKJu2eKwyFteBWhsb8IGy8=", "path": "golang.org/x/tools/go/ast/astutil", @@ -735,12 +897,6 @@ "revision": "20d25e2804050c1cd24a7eea1e7a6447dd0e74ec", "revisionTime": "2016-12-08T18:13:25Z" }, - { - "checksumSHA1": "NGg7/qIJVUfXi7xnEyyDLocdi6Y=", - "path": "gopkg.in/fatih/set.v0", - "revision": "27c40922c40b43fe04554d8223a402af3ea333f3", - "revisionTime": "2014-12-10T08:48:24Z" - }, { "checksumSHA1": "DQXNV0EivoHm4q+bkdahYXrjjfE=", "path": "gopkg.in/karalabe/cookiejar.v2/collections/prque", diff --git a/whisper/mailserver/mailserver.go b/whisper/mailserver/mailserver.go index 57e6505ad1..d32eaddec3 100644 --- a/whisper/mailserver/mailserver.go +++ b/whisper/mailserver/mailserver.go @@ -20,7 +20,6 @@ import ( "encoding/binary" "fmt" - "github.com/ethereum/go-ethereum/cmd/utils" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/log" @@ -54,19 +53,19 @@ func NewDbKey(t uint32, h common.Hash) *DBKey { return &k } -func (s *WMailServer) Init(shh *whisper.Whisper, path string, password string, pow float64) { +func (s *WMailServer) Init(shh *whisper.Whisper, path string, password string, pow float64) error { var err error if len(path) == 0 { - utils.Fatalf("DB file is not specified") + return fmt.Errorf("DB file is not specified") } if len(password) == 0 { - utils.Fatalf("Password is not specified for MailServer") + return fmt.Errorf("password is not specified") } s.db, err = leveldb.OpenFile(path, nil) if err != nil { - utils.Fatalf("Failed to open DB file: %s", err) + return fmt.Errorf("open DB file: %s", err) } s.w = shh @@ -74,12 +73,13 @@ func (s *WMailServer) Init(shh *whisper.Whisper, path string, password string, p MailServerKeyID, err := s.w.AddSymKeyFromPassword(password) if err != nil { - utils.Fatalf("Failed to create symmetric key for MailServer: %s", err) + return fmt.Errorf("create symmetric key: %s", err) } s.key, err = s.w.GetSymKey(MailServerKeyID) if err != nil { - utils.Fatalf("Failed to save symmetric key for MailServer") + return fmt.Errorf("save symmetric key: %s", err) } + return nil } func (s *WMailServer) Close() { diff --git a/whisper/mailserver/server_test.go b/whisper/mailserver/server_test.go index d5b993afb9..edb817cc75 100644 --- a/whisper/mailserver/server_test.go +++ b/whisper/mailserver/server_test.go @@ -92,7 +92,10 @@ func TestMailServer(t *testing.T) { shh = whisper.New(&whisper.DefaultConfig) shh.RegisterServer(&server) - server.Init(shh, dir, password, powRequirement) + err = server.Init(shh, dir, password, powRequirement) + if err != nil { + t.Fatal(err) + } defer server.Close() keyID, err = shh.AddSymKeyFromPassword(password) diff --git a/whisper/shhclient/client.go b/whisper/shhclient/client.go index bbe694baaa..a814154e47 100644 --- a/whisper/shhclient/client.go +++ b/whisper/shhclient/client.go @@ -67,7 +67,6 @@ func (sc *Client) SetMaxMessageSize(ctx context.Context, size uint32) error { } // SetMinimumPoW (experimental) sets the minimal PoW required by this node. - // This experimental function was introduced for the future dynamic adjustment of // PoW requirement. If the node is overwhelmed with messages, it should raise the // PoW requirement and notify the peers. The new value should be set relative to @@ -77,7 +76,7 @@ func (sc *Client) SetMinimumPoW(ctx context.Context, pow float64) error { return sc.c.CallContext(ctx, &ignored, "shh_setMinPoW", pow) } -// Marks specific peer trusted, which will allow it to send historic (expired) messages. +// MarkTrustedPeer marks specific peer trusted, which will allow it to send historic (expired) messages. // Note This function is not adding new nodes, the node needs to exists as a peer. func (sc *Client) MarkTrustedPeer(ctx context.Context, enode string) error { var ignored bool @@ -136,9 +135,9 @@ func (sc *Client) AddSymmetricKey(ctx context.Context, key []byte) (string, erro } // GenerateSymmetricKeyFromPassword generates the key from password, stores it, and returns its identifier. -func (sc *Client) GenerateSymmetricKeyFromPassword(ctx context.Context, passwd []byte) (string, error) { +func (sc *Client) GenerateSymmetricKeyFromPassword(ctx context.Context, passwd string) (string, error) { var id string - return id, sc.c.CallContext(ctx, &id, "shh_generateSymKeyFromPassword", hexutil.Bytes(passwd)) + return id, sc.c.CallContext(ctx, &id, "shh_generateSymKeyFromPassword", passwd) } // HasSymmetricKey returns an indication if the key associated with the given id is stored in the node. @@ -160,9 +159,9 @@ func (sc *Client) DeleteSymmetricKey(ctx context.Context, id string) error { } // Post a message onto the network. -func (sc *Client) Post(ctx context.Context, message whisper.NewMessage) error { - var ignored bool - return sc.c.CallContext(ctx, &ignored, "shh_post", message) +func (sc *Client) Post(ctx context.Context, message whisper.NewMessage) (string, error) { + var hash string + return hash, sc.c.CallContext(ctx, &hash, "shh_post", message) } // SubscribeMessages subscribes to messages that match the given criteria. This method diff --git a/whisper/whisperv5/api.go b/whisper/whisperv5/api.go index ee566625c9..2ce4642202 100644 --- a/whisper/whisperv5/api.go +++ b/whisper/whisperv5/api.go @@ -32,10 +32,6 @@ import ( "github.com/ethereum/go-ethereum/rpc" ) -const ( - filterTimeout = 300 // filters are considered timeout out after filterTimeout seconds -) - var ( ErrSymAsym = errors.New("specify either a symmetric or an asymmetric key") ErrInvalidSymmetricKey = errors.New("invalid symmetric key") @@ -93,7 +89,7 @@ func (api *PublicWhisperAPI) SetMaxMessageSize(ctx context.Context, size uint32) return true, api.w.SetMaxMessageSize(size) } -// SetMinPow sets the minimum PoW for a message before it is accepted. +// SetMinPoW sets the minimum PoW for a message before it is accepted. func (api *PublicWhisperAPI) SetMinPoW(ctx context.Context, pow float64) (bool, error) { return true, api.w.SetMinimumPoW(pow) } @@ -146,7 +142,7 @@ func (api *PublicWhisperAPI) GetPublicKey(ctx context.Context, id string) (hexut return crypto.FromECDSAPub(&key.PublicKey), nil } -// GetPublicKey returns the private key associated with the given key. The key is the hex +// GetPrivateKey returns the private key associated with the given key. The key is the hex // encoded representation of a key in the form specified in section 4.3.6 of ANSI X9.62. func (api *PublicWhisperAPI) GetPrivateKey(ctx context.Context, id string) (hexutil.Bytes, error) { key, err := api.w.GetPrivateKey(id) @@ -256,8 +252,7 @@ func (api *PublicWhisperAPI) Post(ctx context.Context, req NewMessage) (bool, er // Set asymmetric key that is used to encrypt the message if pubKeyGiven { - params.Dst = crypto.ToECDSAPub(req.PublicKey) - if !ValidatePublicKey(params.Dst) { + if params.Dst, err = crypto.UnmarshalPubkey(req.PublicKey); err != nil { return false, ErrInvalidPublicKey } } @@ -333,8 +328,7 @@ func (api *PublicWhisperAPI) Messages(ctx context.Context, crit Criteria) (*rpc. } if len(crit.Sig) > 0 { - filter.Src = crypto.ToECDSAPub(crit.Sig) - if !ValidatePublicKey(filter.Src) { + if filter.Src, err = crypto.UnmarshalPubkey(crit.Sig); err != nil { return nil, ErrInvalidSigningPubKey } } @@ -517,8 +511,7 @@ func (api *PublicWhisperAPI) NewMessageFilter(req Criteria) (string, error) { } if len(req.Sig) > 0 { - src = crypto.ToECDSAPub(req.Sig) - if !ValidatePublicKey(src) { + if src, err = crypto.UnmarshalPubkey(req.Sig); err != nil { return "", ErrInvalidSigningPubKey } } diff --git a/whisper/whisperv5/doc.go b/whisper/whisperv5/doc.go index 7a57488bd7..8161db8ed6 100644 --- a/whisper/whisperv5/doc.go +++ b/whisper/whisperv5/doc.go @@ -15,7 +15,7 @@ // along with the go-ethereum library. If not, see . /* -Package whisper implements the Whisper protocol (version 5). +Package whisperv5 implements the Whisper protocol (version 5). Whisper combines aspects of both DHTs and datagram messaging systems (e.g. UDP). As such it may be likened and compared to both, not dissimilar to the diff --git a/whisper/whisperv5/message.go b/whisper/whisperv5/message.go index 34ce52e64f..35711d724b 100644 --- a/whisper/whisperv5/message.go +++ b/whisper/whisperv5/message.go @@ -33,7 +33,7 @@ import ( "github.com/ethereum/go-ethereum/log" ) -// Options specifies the exact way a message should be wrapped into an Envelope. +// MessageParams specifies the exact way a message should be wrapped into an Envelope. type MessageParams struct { TTL uint32 Src *ecdsa.PrivateKey @@ -86,7 +86,7 @@ func (msg *ReceivedMessage) isAsymmetricEncryption() bool { return msg.Dst != nil } -// NewMessage creates and initializes a non-signed, non-encrypted Whisper message. +// NewSentMessage creates and initializes a non-signed, non-encrypted Whisper message. func NewSentMessage(params *MessageParams) (*sentMessage, error) { msg := sentMessage{} msg.Raw = make([]byte, 1, len(params.Payload)+len(params.Padding)+signatureLength+padSizeLimit) @@ -330,7 +330,7 @@ func (msg *ReceivedMessage) extractPadding(end int) (int, bool) { return paddingSize, true } -// Recover retrieves the public key of the message signer. +// SigToPubKey retrieves the public key of the message signer. func (msg *ReceivedMessage) SigToPubKey() *ecdsa.PublicKey { defer func() { recover() }() // in case of invalid signature diff --git a/whisper/whisperv5/peer.go b/whisper/whisperv5/peer.go index 179c931795..2bb5677c7c 100644 --- a/whisper/whisperv5/peer.go +++ b/whisper/whisperv5/peer.go @@ -20,21 +20,21 @@ import ( "fmt" "time" + mapset "github.com/deckarep/golang-set" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/p2p" "github.com/ethereum/go-ethereum/rlp" - set "gopkg.in/fatih/set.v0" ) -// peer represents a whisper protocol peer connection. +// Peer represents a whisper protocol peer connection. type Peer struct { host *Whisper peer *p2p.Peer ws p2p.MsgReadWriter trusted bool - known *set.Set // Messages already known by the peer to avoid wasting bandwidth + known mapset.Set // Messages already known by the peer to avoid wasting bandwidth quit chan struct{} } @@ -46,58 +46,58 @@ func newPeer(host *Whisper, remote *p2p.Peer, rw p2p.MsgReadWriter) *Peer { peer: remote, ws: rw, trusted: false, - known: set.New(), + known: mapset.NewSet(), quit: make(chan struct{}), } } // start initiates the peer updater, periodically broadcasting the whisper packets // into the network. -func (p *Peer) start() { - go p.update() - log.Trace("start", "peer", p.ID()) +func (peer *Peer) start() { + go peer.update() + log.Trace("start", "peer", peer.ID()) } // stop terminates the peer updater, stopping message forwarding to it. -func (p *Peer) stop() { - close(p.quit) - log.Trace("stop", "peer", p.ID()) +func (peer *Peer) stop() { + close(peer.quit) + log.Trace("stop", "peer", peer.ID()) } // handshake sends the protocol initiation status message to the remote peer and // verifies the remote status too. -func (p *Peer) handshake() error { +func (peer *Peer) handshake() error { // Send the handshake status message asynchronously errc := make(chan error, 1) go func() { - errc <- p2p.Send(p.ws, statusCode, ProtocolVersion) + errc <- p2p.Send(peer.ws, statusCode, ProtocolVersion) }() // Fetch the remote status packet and verify protocol match - packet, err := p.ws.ReadMsg() + packet, err := peer.ws.ReadMsg() if err != nil { return err } if packet.Code != statusCode { - return fmt.Errorf("peer [%x] sent packet %x before status packet", p.ID(), packet.Code) + return fmt.Errorf("peer [%x] sent packet %x before status packet", peer.ID(), packet.Code) } s := rlp.NewStream(packet.Payload, uint64(packet.Size)) peerVersion, err := s.Uint() if err != nil { - return fmt.Errorf("peer [%x] sent bad status message: %v", p.ID(), err) + return fmt.Errorf("peer [%x] sent bad status message: %v", peer.ID(), err) } if peerVersion != ProtocolVersion { - return fmt.Errorf("peer [%x]: protocol version mismatch %d != %d", p.ID(), peerVersion, ProtocolVersion) + return fmt.Errorf("peer [%x]: protocol version mismatch %d != %d", peer.ID(), peerVersion, ProtocolVersion) } // Wait until out own status is consumed too if err := <-errc; err != nil { - return fmt.Errorf("peer [%x] failed to send status packet: %v", p.ID(), err) + return fmt.Errorf("peer [%x] failed to send status packet: %v", peer.ID(), err) } return nil } // update executes periodic operations on the peer, including message transmission // and expiration. -func (p *Peer) update() { +func (peer *Peer) update() { // Start the tickers for the updates expire := time.NewTicker(expirationCycle) transmit := time.NewTicker(transmissionCycle) @@ -106,15 +106,15 @@ func (p *Peer) update() { for { select { case <-expire.C: - p.expire() + peer.expire() case <-transmit.C: - if err := p.broadcast(); err != nil { - log.Trace("broadcast failed", "reason", err, "peer", p.ID()) + if err := peer.broadcast(); err != nil { + log.Trace("broadcast failed", "reason", err, "peer", peer.ID()) return } - case <-p.quit: + case <-peer.quit: return } } @@ -127,7 +127,7 @@ func (peer *Peer) mark(envelope *Envelope) { // marked checks if an envelope is already known to the remote peer. func (peer *Peer) marked(envelope *Envelope) bool { - return peer.known.Has(envelope.Hash()) + return peer.known.Contains(envelope.Hash()) } // expire iterates over all the known envelopes in the host and removes all @@ -148,16 +148,16 @@ func (peer *Peer) expire() { // broadcast iterates over the collection of envelopes and transmits yet unknown // ones over the network. -func (p *Peer) broadcast() error { +func (peer *Peer) broadcast() error { var cnt int - envelopes := p.host.Envelopes() + envelopes := peer.host.Envelopes() for _, envelope := range envelopes { - if !p.marked(envelope) { - err := p2p.Send(p.ws, messagesCode, envelope) + if !peer.marked(envelope) { + err := p2p.Send(peer.ws, messagesCode, envelope) if err != nil { return err } else { - p.mark(envelope) + peer.mark(envelope) cnt++ } } @@ -168,7 +168,7 @@ func (p *Peer) broadcast() error { return nil } -func (p *Peer) ID() []byte { - id := p.peer.ID() +func (peer *Peer) ID() []byte { + id := peer.peer.ID() return id[:] } diff --git a/whisper/whisperv5/peer_test.go b/whisper/whisperv5/peer_test.go index bae2adb6f5..256a670aa4 100644 --- a/whisper/whisperv5/peer_test.go +++ b/whisper/whisperv5/peer_test.go @@ -19,7 +19,6 @@ package whisperv5 import ( "bytes" "crypto/ecdsa" - "fmt" "net" "sync" "testing" @@ -32,7 +31,7 @@ import ( "github.com/ethereum/go-ethereum/p2p/nat" ) -var keys []string = []string{ +var keys = []string{ "d49dcf37238dc8a7aac57dc61b9fee68f0a97f062968978b9fafa7d1033d03a9", "73fd6143c48e80ed3c56ea159fe7494a0b6b393a392227b422f4c3e8f1b54f98", "119dd32adb1daa7a4c7bf77f847fb28730785aa92947edf42fdd997b54de40dc", @@ -84,9 +83,9 @@ type TestNode struct { var result TestData var nodes [NumNodes]*TestNode -var sharedKey []byte = []byte("some arbitrary data here") +var sharedKey = []byte("some arbitrary data here") var sharedTopic TopicType = TopicType{0xF, 0x1, 0x2, 0} -var expectedMessage []byte = []byte("per rectum ad astra") +var expectedMessage = []byte("per rectum ad astra") // This test does the following: // 1. creates a chain of whisper nodes, @@ -108,8 +107,6 @@ func TestSimulation(t *testing.T) { func initialize(t *testing.T) { var err error - ip := net.IPv4(127, 0, 0, 1) - port0 := 30303 for i := 0; i < NumNodes; i++ { var node TestNode @@ -128,29 +125,15 @@ func initialize(t *testing.T) { if err != nil { t.Fatalf("failed convert the key: %s.", keys[i]) } - port := port0 + i - addr := fmt.Sprintf(":%d", port) // e.g. ":30303" name := common.MakeName("whisper-go", "2.0") - var peers []*discover.Node - if i > 0 { - peerNodeId := nodes[i-1].id - peerPort := uint16(port - 1) - peerNode := discover.PubkeyID(&peerNodeId.PublicKey) - peer := discover.NewNode(peerNode, ip, peerPort, peerPort) - peers = append(peers, peer) - } - node.server = &p2p.Server{ Config: p2p.Config{ - PrivateKey: node.id, - MaxPeers: NumNodes/2 + 1, - Name: name, - Protocols: node.shh.Protocols(), - ListenAddr: addr, - NAT: nat.Any(), - BootstrapNodes: peers, - StaticNodes: peers, - TrustedNodes: peers, + PrivateKey: node.id, + MaxPeers: NumNodes/2 + 1, + Name: name, + Protocols: node.shh.Protocols(), + ListenAddr: "127.0.0.1:0", + NAT: nat.Any(), }, } @@ -159,6 +142,15 @@ func initialize(t *testing.T) { t.Fatalf("failed to start server %d.", i) } + for j := 0; j < i; j++ { + peerNodeId := nodes[j].id + address, _ := net.ResolveTCPAddr("tcp", nodes[j].server.ListenAddr) + peerPort := uint16(address.Port) + peerNode := discover.PubkeyID(&peerNodeId.PublicKey) + peer := discover.NewNode(peerNode, address.IP, peerPort, peerPort) + node.server.AddPeer(peer) + } + nodes[i] = &node } } diff --git a/whisper/whisperv5/topic.go b/whisper/whisperv5/topic.go index c4ea67eefa..c4eda1db42 100644 --- a/whisper/whisperv5/topic.go +++ b/whisper/whisperv5/topic.go @@ -23,7 +23,7 @@ import ( "github.com/ethereum/go-ethereum/common/hexutil" ) -// Topic represents a cryptographically secure, probabilistic partial +// TopicType represents a cryptographically secure, probabilistic partial // classifications of a message, determined as the first (left) 4 bytes of the // SHA3 hash of some arbitrary data given by the original author of the message. type TopicType [TopicLength]byte diff --git a/whisper/whisperv5/whisper.go b/whisper/whisperv5/whisper.go index 85849ccce4..5a2b25c9ec 100644 --- a/whisper/whisperv5/whisper.go +++ b/whisper/whisperv5/whisper.go @@ -26,6 +26,7 @@ import ( "sync" "time" + mapset "github.com/deckarep/golang-set" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/log" @@ -34,7 +35,6 @@ import ( "github.com/syndtr/goleveldb/leveldb/errors" "golang.org/x/crypto/pbkdf2" "golang.org/x/sync/syncmap" - set "gopkg.in/fatih/set.v0" ) type Statistics struct { @@ -63,7 +63,7 @@ type Whisper struct { poolMu sync.RWMutex // Mutex to sync the message and expiration pools envelopes map[common.Hash]*Envelope // Pool of envelopes currently tracked by this node - expirations map[uint32]*set.SetNonTS // Message expiration pool + expirations map[uint32]mapset.Set // Message expiration pool peerMu sync.RWMutex // Mutex to sync the active peer set peers map[*Peer]struct{} // Set of currently active peers @@ -90,7 +90,7 @@ func New(cfg *Config) *Whisper { privateKeys: make(map[string]*ecdsa.PrivateKey), symKeys: make(map[string][]byte), envelopes: make(map[common.Hash]*Envelope), - expirations: make(map[uint32]*set.SetNonTS), + expirations: make(map[uint32]mapset.Set), peers: make(map[*Peer]struct{}), messageQueue: make(chan *Envelope, messageQueueLimit), p2pMsgQueue: make(chan *Envelope, messageQueueLimit), @@ -469,18 +469,18 @@ func (w *Whisper) Stop() error { // HandlePeer is called by the underlying P2P layer when the whisper sub-protocol // connection is negotiated. -func (wh *Whisper) HandlePeer(peer *p2p.Peer, rw p2p.MsgReadWriter) error { +func (w *Whisper) HandlePeer(peer *p2p.Peer, rw p2p.MsgReadWriter) error { // Create the new peer and start tracking it - whisperPeer := newPeer(wh, peer, rw) + whisperPeer := newPeer(w, peer, rw) - wh.peerMu.Lock() - wh.peers[whisperPeer] = struct{}{} - wh.peerMu.Unlock() + w.peerMu.Lock() + w.peers[whisperPeer] = struct{}{} + w.peerMu.Unlock() defer func() { - wh.peerMu.Lock() - delete(wh.peers, whisperPeer) - wh.peerMu.Unlock() + w.peerMu.Lock() + delete(w.peers, whisperPeer) + w.peerMu.Unlock() }() // Run the peer handshake and state updates @@ -490,19 +490,19 @@ func (wh *Whisper) HandlePeer(peer *p2p.Peer, rw p2p.MsgReadWriter) error { whisperPeer.start() defer whisperPeer.stop() - return wh.runMessageLoop(whisperPeer, rw) + return w.runMessageLoop(whisperPeer, rw) } // runMessageLoop reads and processes inbound messages directly to merge into client-global state. -func (wh *Whisper) runMessageLoop(p *Peer, rw p2p.MsgReadWriter) error { +func (w *Whisper) runMessageLoop(p *Peer, rw p2p.MsgReadWriter) error { for { // fetch the next packet packet, err := rw.ReadMsg() if err != nil { - log.Warn("message loop", "peer", p.peer.ID(), "err", err) + log.Info("message loop", "peer", p.peer.ID(), "err", err) return err } - if packet.Size > wh.MaxMessageSize() { + if packet.Size > w.MaxMessageSize() { log.Warn("oversized message received", "peer", p.peer.ID()) return errors.New("oversized message received") } @@ -518,7 +518,7 @@ func (wh *Whisper) runMessageLoop(p *Peer, rw p2p.MsgReadWriter) error { log.Warn("failed to decode envelope, peer will be disconnected", "peer", p.peer.ID(), "err", err) return errors.New("invalid envelope") } - cached, err := wh.add(&envelope) + cached, err := w.add(&envelope) if err != nil { log.Warn("bad envelope received, peer will be disconnected", "peer", p.peer.ID(), "err", err) return errors.New("invalid envelope") @@ -537,17 +537,17 @@ func (wh *Whisper) runMessageLoop(p *Peer, rw p2p.MsgReadWriter) error { log.Warn("failed to decode direct message, peer will be disconnected", "peer", p.peer.ID(), "err", err) return errors.New("invalid direct message") } - wh.postEvent(&envelope, true) + w.postEvent(&envelope, true) } case p2pRequestCode: // Must be processed if mail server is implemented. Otherwise ignore. - if wh.mailServer != nil { + if w.mailServer != nil { var request Envelope if err := packet.Decode(&request); err != nil { log.Warn("failed to decode p2p request message, peer will be disconnected", "peer", p.peer.ID(), "err", err) return errors.New("invalid p2p request") } - wh.mailServer.DeliverMail(p, &request) + w.mailServer.DeliverMail(p, &request) } default: // New message types might be implemented in the future versions of Whisper. @@ -561,29 +561,27 @@ func (wh *Whisper) runMessageLoop(p *Peer, rw p2p.MsgReadWriter) error { // add inserts a new envelope into the message pool to be distributed within the // whisper network. It also inserts the envelope into the expiration pool at the // appropriate time-stamp. In case of error, connection should be dropped. -func (wh *Whisper) add(envelope *Envelope) (bool, error) { +func (w *Whisper) add(envelope *Envelope) (bool, error) { now := uint32(time.Now().Unix()) sent := envelope.Expiry - envelope.TTL if sent > now { if sent-SynchAllowance > now { return false, fmt.Errorf("envelope created in the future [%x]", envelope.Hash()) - } else { - // recalculate PoW, adjusted for the time difference, plus one second for latency - envelope.calculatePoW(sent - now + 1) } + // recalculate PoW, adjusted for the time difference, plus one second for latency + envelope.calculatePoW(sent - now + 1) } if envelope.Expiry < now { if envelope.Expiry+SynchAllowance*2 < now { return false, fmt.Errorf("very old message") - } else { - log.Debug("expired envelope dropped", "hash", envelope.Hash().Hex()) - return false, nil // drop envelope without error } + log.Debug("expired envelope dropped", "hash", envelope.Hash().Hex()) + return false, nil // drop envelope without error } - if uint32(envelope.size()) > wh.MaxMessageSize() { + if uint32(envelope.size()) > w.MaxMessageSize() { return false, fmt.Errorf("huge messages are not allowed [%x]", envelope.Hash()) } @@ -598,36 +596,36 @@ func (wh *Whisper) add(envelope *Envelope) (bool, error) { return false, fmt.Errorf("wrong size of AESNonce: %d bytes [env: %x]", aesNonceSize, envelope.Hash()) } - if envelope.PoW() < wh.MinPow() { + if envelope.PoW() < w.MinPow() { log.Debug("envelope with low PoW dropped", "PoW", envelope.PoW(), "hash", envelope.Hash().Hex()) return false, nil // drop envelope without error } hash := envelope.Hash() - wh.poolMu.Lock() - _, alreadyCached := wh.envelopes[hash] + w.poolMu.Lock() + _, alreadyCached := w.envelopes[hash] if !alreadyCached { - wh.envelopes[hash] = envelope - if wh.expirations[envelope.Expiry] == nil { - wh.expirations[envelope.Expiry] = set.NewNonTS() + w.envelopes[hash] = envelope + if w.expirations[envelope.Expiry] == nil { + w.expirations[envelope.Expiry] = mapset.NewThreadUnsafeSet() } - if !wh.expirations[envelope.Expiry].Has(hash) { - wh.expirations[envelope.Expiry].Add(hash) + if !w.expirations[envelope.Expiry].Contains(hash) { + w.expirations[envelope.Expiry].Add(hash) } } - wh.poolMu.Unlock() + w.poolMu.Unlock() if alreadyCached { log.Trace("whisper envelope already cached", "hash", envelope.Hash().Hex()) } else { log.Trace("cached whisper envelope", "hash", envelope.Hash().Hex()) - wh.statsMu.Lock() - wh.stats.memoryUsed += envelope.size() - wh.statsMu.Unlock() - wh.postEvent(envelope, false) // notify the local node about the new message - if wh.mailServer != nil { - wh.mailServer.Archive(envelope) + w.statsMu.Lock() + w.stats.memoryUsed += envelope.size() + w.statsMu.Unlock() + w.postEvent(envelope, false) // notify the local node about the new message + if w.mailServer != nil { + w.mailServer.Archive(envelope) } } return true, nil @@ -838,9 +836,8 @@ func deriveKeyMaterial(key []byte, version uint64) (derivedKey []byte, err error // because it's a once in a session experience derivedKey := pbkdf2.Key(key, nil, 65356, aesKeyLength, sha256.New) return derivedKey, nil - } else { - return nil, unknownVersionError(version) } + return nil, unknownVersionError(version) } // GenerateRandomID generates a random string, which is then returned to be used as a key id diff --git a/whisper/whisperv6/api.go b/whisper/whisperv6/api.go index 3f3a082afe..d729e79c35 100644 --- a/whisper/whisperv6/api.go +++ b/whisper/whisperv6/api.go @@ -32,10 +32,6 @@ import ( "github.com/ethereum/go-ethereum/rpc" ) -const ( - filterTimeout = 300 // filters are considered timeout out after filterTimeout seconds -) - // List of errors var ( ErrSymAsym = errors.New("specify either a symmetric or an asymmetric key") @@ -231,8 +227,9 @@ type newMessageOverride struct { Padding hexutil.Bytes } -// Post a message on the Whisper network. -func (api *PublicWhisperAPI) Post(ctx context.Context, req NewMessage) (bool, error) { +// Post posts a message on the Whisper network. +// returns the hash of the message in case of success. +func (api *PublicWhisperAPI) Post(ctx context.Context, req NewMessage) (hexutil.Bytes, error) { var ( symKeyGiven = len(req.SymKeyID) > 0 pubKeyGiven = len(req.PublicKey) > 0 @@ -241,7 +238,7 @@ func (api *PublicWhisperAPI) Post(ctx context.Context, req NewMessage) (bool, er // user must specify either a symmetric or an asymmetric key if (symKeyGiven && pubKeyGiven) || (!symKeyGiven && !pubKeyGiven) { - return false, ErrSymAsym + return nil, ErrSymAsym } params := &MessageParams{ @@ -256,57 +253,67 @@ func (api *PublicWhisperAPI) Post(ctx context.Context, req NewMessage) (bool, er // Set key that is used to sign the message if len(req.Sig) > 0 { if params.Src, err = api.w.GetPrivateKey(req.Sig); err != nil { - return false, err + return nil, err } } // Set symmetric key that is used to encrypt the message if symKeyGiven { if params.Topic == (TopicType{}) { // topics are mandatory with symmetric encryption - return false, ErrNoTopics + return nil, ErrNoTopics } if params.KeySym, err = api.w.GetSymKey(req.SymKeyID); err != nil { - return false, err + return nil, err } if !validateDataIntegrity(params.KeySym, aesKeyLength) { - return false, ErrInvalidSymmetricKey + return nil, ErrInvalidSymmetricKey } } // Set asymmetric key that is used to encrypt the message if pubKeyGiven { - params.Dst = crypto.ToECDSAPub(req.PublicKey) - if !ValidatePublicKey(params.Dst) { - return false, ErrInvalidPublicKey + if params.Dst, err = crypto.UnmarshalPubkey(req.PublicKey); err != nil { + return nil, ErrInvalidPublicKey } } // encrypt and sent message whisperMsg, err := NewSentMessage(params) if err != nil { - return false, err + return nil, err } + var result []byte env, err := whisperMsg.Wrap(params) if err != nil { - return false, err + return nil, err } // send to specific node (skip PoW check) if len(req.TargetPeer) > 0 { n, err := discover.ParseNode(req.TargetPeer) if err != nil { - return false, fmt.Errorf("failed to parse target peer: %s", err) + return nil, fmt.Errorf("failed to parse target peer: %s", err) } - return true, api.w.SendP2PMessage(n.ID[:], env) + err = api.w.SendP2PMessage(n.ID[:], env) + if err == nil { + hash := env.Hash() + result = hash[:] + } + return result, err } // ensure that the message PoW meets the node's minimum accepted PoW if req.PowTarget < api.w.MinPow() { - return false, ErrTooLowPoW + return nil, ErrTooLowPoW } - return true, api.w.Send(env) + err = api.w.Send(env) + if err == nil { + hash := env.Hash() + result = hash[:] + } + return result, err } //go:generate gencodec -type Criteria -field-override criteriaOverride -out gen_criteria_json.go @@ -352,8 +359,7 @@ func (api *PublicWhisperAPI) Messages(ctx context.Context, crit Criteria) (*rpc. } if len(crit.Sig) > 0 { - filter.Src = crypto.ToECDSAPub(crit.Sig) - if !ValidatePublicKey(filter.Src) { + if filter.Src, err = crypto.UnmarshalPubkey(crit.Sig); err != nil { return nil, ErrInvalidSigningPubKey } } @@ -536,8 +542,7 @@ func (api *PublicWhisperAPI) NewMessageFilter(req Criteria) (string, error) { } if len(req.Sig) > 0 { - src = crypto.ToECDSAPub(req.Sig) - if !ValidatePublicKey(src) { + if src, err = crypto.UnmarshalPubkey(req.Sig); err != nil { return "", ErrInvalidSigningPubKey } } diff --git a/whisper/whisperv6/api_test.go b/whisper/whisperv6/api_test.go index 004a41c949..cdbc7fab5e 100644 --- a/whisper/whisperv6/api_test.go +++ b/whisper/whisperv6/api_test.go @@ -22,8 +22,8 @@ import ( "testing" "time" + mapset "github.com/deckarep/golang-set" "github.com/ethereum/go-ethereum/common" - set "gopkg.in/fatih/set.v0" ) func TestMultipleTopicCopyInNewMessageFilter(t *testing.T) { @@ -31,7 +31,7 @@ func TestMultipleTopicCopyInNewMessageFilter(t *testing.T) { privateKeys: make(map[string]*ecdsa.PrivateKey), symKeys: make(map[string][]byte), envelopes: make(map[common.Hash]*Envelope), - expirations: make(map[uint32]*set.SetNonTS), + expirations: make(map[uint32]mapset.Set), peers: make(map[*Peer]struct{}), messageQueue: make(chan *Envelope, messageQueueLimit), p2pMsgQueue: make(chan *Envelope, messageQueueLimit), diff --git a/whisper/whisperv6/peer.go b/whisper/whisperv6/peer.go index 2bf1c905b2..79cc212708 100644 --- a/whisper/whisperv6/peer.go +++ b/whisper/whisperv6/peer.go @@ -22,11 +22,11 @@ import ( "sync" "time" + mapset "github.com/deckarep/golang-set" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/p2p" "github.com/ethereum/go-ethereum/rlp" - set "gopkg.in/fatih/set.v0" ) // Peer represents a whisper protocol peer connection. @@ -41,7 +41,7 @@ type Peer struct { bloomFilter []byte fullNode bool - known *set.Set // Messages already known by the peer to avoid wasting bandwidth + known mapset.Set // Messages already known by the peer to avoid wasting bandwidth quit chan struct{} } @@ -54,7 +54,7 @@ func newPeer(host *Whisper, remote *p2p.Peer, rw p2p.MsgReadWriter) *Peer { ws: rw, trusted: false, powRequirement: 0.0, - known: set.New(), + known: mapset.NewSet(), quit: make(chan struct{}), bloomFilter: MakeFullNodeBloom(), fullNode: true, @@ -165,7 +165,7 @@ func (peer *Peer) mark(envelope *Envelope) { // marked checks if an envelope is already known to the remote peer. func (peer *Peer) marked(envelope *Envelope) bool { - return peer.known.Has(envelope.Hash()) + return peer.known.Contains(envelope.Hash()) } // expire iterates over all the known envelopes in the host and removes all diff --git a/whisper/whisperv6/peer_test.go b/whisper/whisperv6/peer_test.go index ec985ae65b..0c9b380901 100644 --- a/whisper/whisperv6/peer_test.go +++ b/whisper/whisperv6/peer_test.go @@ -21,12 +21,13 @@ import ( "crypto/ecdsa" "fmt" mrand "math/rand" - "net" "sync" "sync/atomic" "testing" "time" + "net" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/crypto" @@ -173,8 +174,6 @@ func initialize(t *testing.T) { initBloom(t) var err error - ip := net.IPv4(127, 0, 0, 1) - port0 := 30303 for i := 0; i < NumNodes; i++ { var node TestNode @@ -199,40 +198,36 @@ func initialize(t *testing.T) { if err != nil { t.Fatalf("failed convert the key: %s.", keys[i]) } - port := port0 + i - addr := fmt.Sprintf(":%d", port) // e.g. ":30303" name := common.MakeName("whisper-go", "2.0") - var peers []*discover.Node - if i > 0 { - peerNodeID := nodes[i-1].id - peerPort := uint16(port - 1) - peerNode := discover.PubkeyID(&peerNodeID.PublicKey) - peer := discover.NewNode(peerNode, ip, peerPort, peerPort) - peers = append(peers, peer) - } node.server = &p2p.Server{ Config: p2p.Config{ - PrivateKey: node.id, - MaxPeers: NumNodes/2 + 1, - Name: name, - Protocols: node.shh.Protocols(), - ListenAddr: addr, - NAT: nat.Any(), - BootstrapNodes: peers, - StaticNodes: peers, - TrustedNodes: peers, + PrivateKey: node.id, + MaxPeers: NumNodes/2 + 1, + Name: name, + Protocols: node.shh.Protocols(), + ListenAddr: "127.0.0.1:0", + NAT: nat.Any(), }, } + go startServer(t, node.server) + nodes[i] = &node } - for i := 0; i < NumNodes; i++ { - go startServer(t, nodes[i].server) - } - waitForServersToStart(t) + + for i := 0; i < NumNodes; i++ { + for j := 0; j < i; j++ { + peerNodeId := nodes[j].id + address, _ := net.ResolveTCPAddr("tcp", nodes[j].server.ListenAddr) + peerPort := uint16(address.Port) + peerNode := discover.PubkeyID(&peerNodeId.PublicKey) + peer := discover.NewNode(peerNode, address.IP, peerPort, peerPort) + nodes[i].server.AddPeer(peer) + } + } } func startServer(t *testing.T, s *p2p.Server) { diff --git a/whisper/whisperv6/whisper.go b/whisper/whisperv6/whisper.go index 880cced098..76d485808d 100644 --- a/whisper/whisperv6/whisper.go +++ b/whisper/whisperv6/whisper.go @@ -26,6 +26,7 @@ import ( "sync" "time" + mapset "github.com/deckarep/golang-set" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/log" @@ -35,7 +36,6 @@ import ( "github.com/syndtr/goleveldb/leveldb/errors" "golang.org/x/crypto/pbkdf2" "golang.org/x/sync/syncmap" - set "gopkg.in/fatih/set.v0" ) // Statistics holds several message-related counter for analytics @@ -69,7 +69,7 @@ type Whisper struct { poolMu sync.RWMutex // Mutex to sync the message and expiration pools envelopes map[common.Hash]*Envelope // Pool of envelopes currently tracked by this node - expirations map[uint32]*set.SetNonTS // Message expiration pool + expirations map[uint32]mapset.Set // Message expiration pool peerMu sync.RWMutex // Mutex to sync the active peer set peers map[*Peer]struct{} // Set of currently active peers @@ -100,7 +100,7 @@ func New(cfg *Config) *Whisper { privateKeys: make(map[string]*ecdsa.PrivateKey), symKeys: make(map[string][]byte), envelopes: make(map[common.Hash]*Envelope), - expirations: make(map[uint32]*set.SetNonTS), + expirations: make(map[uint32]mapset.Set), peers: make(map[*Peer]struct{}), messageQueue: make(chan *Envelope, messageQueueLimit), p2pMsgQueue: make(chan *Envelope, messageQueueLimit), @@ -650,7 +650,7 @@ func (whisper *Whisper) runMessageLoop(p *Peer, rw p2p.MsgReadWriter) error { // fetch the next packet packet, err := rw.ReadMsg() if err != nil { - log.Warn("message loop", "peer", p.peer.ID(), "err", err) + log.Info("message loop", "peer", p.peer.ID(), "err", err) return err } if packet.Size > whisper.MaxMessageSize() { @@ -796,9 +796,9 @@ func (whisper *Whisper) add(envelope *Envelope, isP2P bool) (bool, error) { if !alreadyCached { whisper.envelopes[hash] = envelope if whisper.expirations[envelope.Expiry] == nil { - whisper.expirations[envelope.Expiry] = set.NewNonTS() + whisper.expirations[envelope.Expiry] = mapset.NewThreadUnsafeSet() } - if !whisper.expirations[envelope.Expiry].Has(hash) { + if !whisper.expirations[envelope.Expiry].Contains(hash) { whisper.expirations[envelope.Expiry].Add(hash) } }